ZGlmZiAtLWdpdCBhL0tFWVMgYi9LRVlTCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NWVlZjQ2Li4wMDAwMDAwCi0tLSBhL0tFWVMKKysrIC9kZXYvbnVsbApAQCAtMSwxMzIgKzAsMCBAQAotVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBQR1Aga2V5cyBvZiB2YXJpb3VzIFhhbGFuIGRldmVsb3BlcnMuCi1QbGVhc2UgZG9uJ3QgdXNlIHRoZW0gZm9yIGVtYWlsIHVubGVzcyB5b3UgaGF2ZSB0by4gVGhlaXIgbWFpbgotcHVycG9zZSBpcyBjb2RlIHNpZ25pbmcuCi0KLVhhbGFuIHVzZXJzOiBwZ3AgPCBLRVlTCi1YYWxhbiBkZXZlbG9wZXJzOiBwZ3AgLWt4YSA8eW91ciBuYW1lPiBhbmQgYXBwZW5kIGl0IHRvIHRoaXMgZmlsZS4KLQotCi1UeXBlIEJpdHMvS2V5SUQgICAgRGF0ZSAgICAgICBVc2VyIElECi1wdWIgIDEwMjQvMzBBMjFENTUgMTk5OS8xMS8wNCBTaGFuZSBDdXJjdXJ1IDxzaGFuZV9jdXJjdXJ1QGxvdHVzLmNvbT4KLQotLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCi1WZXJzaW9uOiBQR1AgUGVyc29uYWwgUHJpdmFjeSA2LjUuMwotCi1tUUdpQkRnaGpOSVJCQURYQjRVWTRZZloyRG1iU3VzaGx6UFpDa1kwMGlEUFVCK0drVzZGUWhnbkdDTFpvdmd5Ci1GaENuQ3NLZE4xeHlIRnEvTnMzUFYzSFByTUd4RktnVk9mUnV4UkViRjhDb1hBYS91MHFSMVdvQW0rcmx5QzlsCi1PVnNIZFh4eU9wWjhlNFNQR25lOExRWVp3cjJxK0xzSGlYT1prdGthQm84dWE4RjRFSllrQk1GaFpRQ2cvNEl3Ci1qWG1mcHQ2NjFFc3NtZjhkMDVjTWRBY0VBTDByK1ByRnhDbXJVOE9rK3I3NCtlcXljbHhWYmlEYk9mN1VlZjZOCi1mRUptQzVpaFg3cDhrOGVFZjJYZXBlQW82TjBnZE94WVZYVndjb1JDbXFQeTdTU2cxam5YcUtPbkE4N3lsdjE2Ci1sT2lKNVdVa2lWWDk2V09XRXNiYllLdWdnbVdlREwrNmlGYzlocDZvRVAyc2YvZ2VDOEFFQUVIVFBmbmVKenBvCi0zejI4QS85aVg0MXI0SzBpUng1ZUlKdTJLVXJqZHBQeGhuMEpQZTlkejJYeldaSWNpTmVraStUaHJjYXJFajloCi1sbWZ2Y0dMaWZYYlFmWHVGaWQzYnRNc0JSSThkcUFiYlhteWZ2Q1lZU0hET2tYRW1vTVc2NkFXZmVGNGhnZkhGCi1TQTVsbWNwSDRtdEhVNjl1QzArY3ZZbFJST1ArSGFlT2VwWWJyaUErOUE5UXE0TUFXN1FuVTJoaGJtVWdRM1Z5Ci1ZM1Z5ZFNBOGMyaGhibVZmWTNWeVkzVnlkVUJzYjNSMWN5NWpiMjAraVFCT0JCQVJBZ0FPQlFJNElZelNCQXNECi1BZ0VDR1FFQUNna1FNdXdYV1RDaUhWWFFJUUNnMVExTUtrV3lnSXNER0FPaGlQYU0wOXBUZGxVQW5pVGVDa29PCi1JMCsySWdEL050cW5HRGFTdk5EbmlRQkdCQkFSQWdBR0JRSTRxWmsvQUFvSkVGSHJQdkZYZGxyeVZiSUFvTy9lCi1ndGkxZXNnUkk2R0VySWhJQ2czSW9jdGZBS0RscHc2TldxL1dUeGsxQWEwcE4vMWI2Zm1ENUxrQ0RRUTRJWXpTCi1FQWdBOWtKWHR3aC9DQmR5b3JyV3FVTHpCZWo1VXhFNVQ3YnhicmxMT0NEYUFhZFdveFRwajBCVjg5QUh4c3RECi1xWlN0OTB4a2hrbjRESU85WmVrWDFLSFRVUGoxV1YvY2RsSlBQVDJOMjg2WjRWZVNXYzM5dUs1MFQ4WDhkcnlECi14VWN3WWM1OHlXYi9GZm03L1pGZXh3R3EwMXVlamFDbGNqclVHdkMvUmdCWUsrWDBpUDFZVGtuYnpTQzBuZVNSCi1CelpyTTJ3NERVVWREM3lJc3h4OFd5Mk85dlBKSThCRDhLVmJHSTJPdTFXTXVGMDQwelQ5ZkJkWFE2TWRHR3plCi1NeUVzdFNyL1BPR3hLVUFZRVkxOGhLY0tjdGFHeEFNWnlBY3Blc3FWRE5tV242dlFDbENiQWtiVENEMW1wRjFCCi1uNXg4dllsTEloa211cXVpWHNOVjZUSUxPd0FDQWdnQXp1L1FPYnV5a0xHd1BMQ29TUUVLZmVOU0dQT3I3d0syCi1YU3A4YzhEUzFCMmpyVkw0b0grUFliNndWaGNOZDMrWHQ0K1AvQmZsbGVtUlU4MEdENnQvUkhvVEVaaElocC8zCi04ZXJCTEpmTFBxRkRZZGpLZjMwRU1NakZXSWhlY2c5UW5aU1hVMmY3RUoyNEwrL3Zub3RqQXo2aFpmSnZqYjFiCi0xdFgzUFExVzJlK2xURmhTejFSWVNLeDRtc0VjZXozWjB3VmFsTnFXbGV0M3Q3OGNDWlJUNGZQT2t5TTRDN0ZiCi10SzZjc3ZGVVhrSWZ1M3FneDRhVms4SFVJd1hrSFpEMlc3WGlGU1BoTXRnY1BlVUFiM0FJZVlKcy9pcVA0SDROCi00b0o4QjZ0WHhtcERtM1A4NVBoQzRnSk9GVVRoblpLR2tMdFd3ZFVhZ284WFNLQjVWVUEvVUlrQVJnUVlFUUlBCi1CZ1VDT0NHTTBnQUtDUkF5N0JkWk1LSWRWWFMrQUtEaHlKd3gwNDgrYzdBVElOU0dmNkl4aVhReVlRQ2c0NnBKCi0vZmMwSFZXVXZIZmppb0RSYUxRVUl2OD0KLT11dC9NCi0tLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCi0KLS0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQotVmVyc2lvbjogUEdQIDYuNS44Ci0KLW1RR2lCRG5qVFVNUkJBREd6aTd5MVhpVHR5L0haMVFoUlF4TWt5ZjdKRC9FNWRHWENWTFJvU1FWOS9oZEtQdEYKLU9HempaUXQ2RHNzUG5pc2dyVzZoU0xFczhHclpLSENaRTZ6OGg1WWVrZytXSlRzM0swTE5KM1gvdFN0VmUvZlUKLURhckxNN3UwcXd0Y3NhSVNXRk1Sb3kxeGJyeEJrcEZCZU5rRCtGUlVrOHNYVFZYb09Hdm0zRncvOHdDZy8rcGcKLVk3WEQ2WklBMG0vQ3hyeFIreFRCcmk4RC9SazQvNXJ6c1Q0MkFJbUp3QXdlSmlkemxtbXZXY0RHalpvbER4ckgKLVRsVnBJWEZqR0ZKQmo5dGcxWHorMy93OXpLeWs5MDBnY3dsSFU3dXoyOHhQeWxpc2hnZDhEeUFiL2VuU1hzRXkKLU5DMUVhZ3lwQWJNcEVoVEFkQmFVTlBiNnQ4eU9YM2RIVWtpNXl1WitQcnlPeUtXVGFpSHloSEx3SjV2Wmk5eG0KLW8rL1pCQUNxalVxQUwyN0pPQzFxdzF6cldDUVF6RUpJZUlJZEdGRUdvTUJpRkM0MjV2aC8xZEpBMUxVSUNIU1oKLWJadmc3Vmx2QU1Fcm5aYi9JY1Z4NExYNFI4VWVyZ2gwRS80WGk2a3JUWVp2RHVJNFJtUDVKbi83SWFLMmMyN0kKLWxDeDdJMGhqNENRSVdWSUVWQ0RBR2pKazlFMzhWYWhKWUh5U0h6ak1kaFhTalRicVc3UW5URzkwZFhONGMyd2cKLVZHVmhiU0E4VEc5MGRYTjRjMnhmVkdWaGJVQnNiM1IxY3k1amIyMCtpUUJPQkJBUkFnQU9CUUk1NDAxREJBc0QKLUFnRUNHUUVBQ2drUUdibkJpMlJDdzl5Vlp3Q2dqeEMvaWU1L0doUExaeVFoTVNRdkp1REpQOGtBbjE3VU5mTi8KLXRSdEZmY0pEck5jQzdQMjF1dCtWdVFJTkJEbmpUVU1RQ0FEMlFsZTNDSDhJRjNLaXV0YXBRdk1GNlBsVEVUbFAKLXR2RnV1VXM0SU5vQnAxYWpGT21QUUZYejBBZkd5ME9wbEszM1RHU0dTZmdNZzcxbDZSZlVvZE5RK1BWWlg5eDIKLVVrODlQWTNienBuaFY1Slp6ZjI0cm5SUHhmeDJ2SVBGUnpCaHpuekpadjhWK2J2OWtWN0hBYXJUVzU2Tm9LVnkKLU90UWE4TDlHQUZncjVmU0kvVmhPU2R2TklMU2Q1SkVITm1zemJEZ05SUjBQZklpekhIeGJMWTcyODhrandFUHcKLXBWc1lqWTY3Vll5NFhUalROUDE4RjFkRG94MFliTjR6SVN5MUt2ODg0YkVwUUJnUmpYeUVwd3B5MW9iRUF4bkkKLUJ5bDZ5cFVNMlphZnE5QUtVSnNDUnRNSVBXYWtYVUdmbkh5OWlVc2lHU2E2cTZKZXcxWHBNZ3M3QUFJQ0IvOWcKLTVhUjZtV2J2YVpBd04vSUZ3SUM5Y2Q1NGNEQVc2cHZvd282L2drZ0xmd1VMSTdpR1I4anJISHM5clN1OTY4ZlYKLTNMN3lzM3BGTFI5My8yMm1KUjFJblRwK3FRZFVudGNuaDVmd2JBZDlaOE5vTTJRRXVZNGM3Y1Zqb2Jhek9nUGYKLUM2WFprUzFDM3RIY3ZVZWR6UjhrbWYxaGlSdElMV1cycEY3QTlKYkpCM1JIY3VCdXQzY1MzZU1FMitzK2RDU2wKLVN1Z1pLeVZGdWlEb0tPNTlURDdPSW45ZHdpcFZoWDdVZ0cwdUxEbFp6Q2Q5ZEhMc3Jscjc1TER4SVp5aWlmREIKLTFvYSt4TTVzbUZZRXF1eCszbGYvVU5HaHB4Y2FHREpNMDlVVXBPVnY4eVZ6K0ZaUWlsWjdCdTBYS3ZuajFwOTEKLVlGVkFpUXZRSGlqeWEra015Nk1DaVFCR0JCZ1JBZ0FHQlFJNTQwMURBQW9KRUJtNXdZdGtRc1BjUGxVQW9Oa20KLWZNQjBITDcxaDVRWWZCL05SSnVwV3NXVUFLQ2kyVUVUcTljd0E3UXR1TXlRMWNqdmtBMW1uUT09Ci09bE5aMgotLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQotCi0tLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0KLVZlcnNpb246IFBHUGZyZWV3YXJlIDYuNS44IGZvciBub24tY29tbWVyY2lhbCB1c2UgPGh0dHA6Ly93d3cucGdwLmNvbT4KLQotbVFHaUJEdGlPdUVSQkFEV3F0WXZSL3dxUDlIOTlibVExR05wUzhOTDdZWG1PVUVkSDlYLzdLVDNuckZCamFjTwotWFRKMi9yam5ZMUl0VzZFd25lbnVGZjBva2duZjNaZ1VhaTZBanI0YnV4Q01ocEF6bTJodE9BYVNuYzNsL0ZaRgotbWNkdnB2S2twYzRiZjJxWUMwajRSaktQdlhFeFBkSzNEYlFubDdQaTVxMHF2ZGFTMEpVa1lSNVgvUUNnLzdmSQotdUpLSFZCcUl2ZWVBbVpLcFU4eFlkNjBEL1J2VGxsM2R3VkNXaHMyMWEvQUZGWUtwQTg2QTVqeXEveVh3SWVWcgotSUt0S2Z4bnZjanBtWkFZSU1kZHNCdFZGalcvQ3lSbTZLUVpYUmRXcFh1THltUDcrcHBUMlZsUkxNM1RxVXh1bQotNHBBU0pkcHRrN2ZqM3F6aXZ5ZmFRNi9mQUczUHlKY09lNWhTN3puTFYyYTBMWDdQUUJpUHBVd3FjaktRMmEyaAotTG9nUUJBQ2FscGdBSWROMWRmVWJnT1NtOWdkc1JiOHdZSU9LVEZHcENXRjE3ck1UTXVTWVRMQXNtNm1QZHhybAotRkhuMndsUk93aURGbnpoRURGYlBPSGRDNVhNRCt0WWRyV0phZmZKWktXN1pJdE9FejZPSWg3Z25tS3BCY0RzeQotV29KOUo3UVJVaUVUSFgzQWJLT3luU2RrNWtjZ0RXeW1DalNQNnJFME0xUEFpTVZnMUxRaFUyTnZkSFFnUW05aAotWnlBOGMyTnZkSFJmWW05aFowQnNiM1IxY3k1amIyMCtpUUJPQkJBUkFnQU9CUUk3WWpyaEJBc0RBZ0VDR1FFQQotQ2drUVFrUGJPY0dpWHVZdXFRQ2d4bnV4a0Eyd2ZYZi9xcmhLOUZEZGh0RzY3TVFBbmlubTJyWlZjVEhxb3JCVgotS3FVSE1lQzRWSGFFdVFJTkJEdGlPdUVRQ0FEMlFsZTNDSDhJRjNLaXV0YXBRdk1GNlBsVEVUbFB0dkZ1dVVzNAotSU5vQnAxYWpGT21QUUZYejBBZkd5ME9wbEszM1RHU0dTZmdNZzcxbDZSZlVvZE5RK1BWWlg5eDJVazg5UFkzYgotenBuaFY1Slp6ZjI0cm5SUHhmeDJ2SVBGUnpCaHpuekpadjhWK2J2OWtWN0hBYXJUVzU2Tm9LVnlPdFFhOEw5RwotQUZncjVmU0kvVmhPU2R2TklMU2Q1SkVITm1zemJEZ05SUjBQZklpekhIeGJMWTcyODhrandFUHdwVnNZalk2NwotVll5NFhUalROUDE4RjFkRG94MFliTjR6SVN5MUt2ODg0YkVwUUJnUmpYeUVwd3B5MW9iRUF4bklCeWw2eXBVTQotMlphZnE5QUtVSnNDUnRNSVBXYWtYVUdmbkh5OWlVc2lHU2E2cTZKZXcxWHBNZ3M3QUFJQ0NBRGoxWUhKenBnNwotSjB6MHpSbXB6aG1SZkRadHpCWkIrYmpxWGgxbGtjSk85UDZ0cXdFZTlKbmhtK3lNV0t0ZkVUZWlOeHlLN0M1ZgotcVRBVG85VVNxQjIrVlRmRXIwWStVaXZVY0lUQjFVdkNoajAyaVBqN3poclc2QTdraTVVSFl6Y0s2eTI5TXc2SwotSjM5bktuN0ZQYXhjcUZFemtzQUdlblQreXEwL3NTQ0F5ZFgwR3lXNnNjRWtrbWRWc1Vza0Q1dGI4M0txTnpLSwotd1htL2lJa1FIUzVGeXpRN1UvV0dBS1JNY1FmMTRVa0dyZlBvZVJiTWZObWxwL0IrSndwZmJuM2JINDdoZ293QQotZ2RHY0tRU0FRaFVneTZHRHBzeFdGVFZ5amlaTkVCSTJVeGtvQjdkOEh6TVJ2bWU2dHc1MWQ1OU1TTks3WC9HbwotR3RBOVArSXFBM1VUaVFCR0JCZ1JBZ0FHQlFJN1lqcmhBQW9KRUVKRDJ6bkJvbDdtdytNQW4zcGJnY2FZVitLWgotVExKc3pzc09DcFFMdkp3cEFLQ09CaEtTSE5VSlI4T1hJNFZoWTJBcnZtbTMzZz09Ci09Z2VubgotLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQotCi0tLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0KLVZlcnNpb246IFBHUGZyZWV3YXJlIDYuNS4xIGZvciBub24tY29tbWVyY2lhbCB1c2UgPGh0dHA6Ly93d3cucGdwLmNvbT4KLQotbVFHaUJEdU9sRnNSQkFEVDJIdEMyUWlFdVBIekFrNk9hOTVudXBtNXpQRmR0VWFzR1duYk5oajM3Sk5qaE5GQQotL2lDQXZsb1JITUc4cFI5bHRsTFpBNGFlNFgyQmhQUHFrK1VzN3pqWVkvRGtGLytHK2NUTXdQZG9ha2M1SnhMNQotWlJvVm50QVlSSDViY212OU1kU2JZNFlEZjJpcWs4Z0NhRlBqUDlFUWN3M2wzOGtUYmZWdkdLSWpOd0NnLzdmVQotYUFISWlPWVNIK2VMTXBGNEx0dXFRUDBELzNEaHRwdnJBTFNwaUYvcnczVm5MMXJueGNiMklaczlJTDFVNmJGSwotcDBJYnFRT1JTVk8yK2RZU1dvNC9WdDdhV0JGVlBmL3lmbi9lbG5jVm1vMTJ3QXpXeTdzQm5xdjhRemZZQXZ5WQotVXVPaDJXVUQ0SzFBTE95N1ZITk0xbU15dkg0ZERJQW9PdXFYTVFCd0p4MEErL3pVVWFVWlpMb2pzV2wzNjZwRgotR0htbEJBQ2E1elhTWjBtVWY1U2NacVp5ZGE3L2tVc1YrQjV0S2pFS3VPWTFkL2huSTVlLzlaMTFFUUlmcXF4cwotVWNrekNpaSttZzh6U3BTZ1dIdHNTdTVOOTB0ZUx1bTk4YkV1aFlOVDF0QjZQYzd5TldFZnEzYzNTUHc4WnN0WAotdTFrVFFyc1FlVGlQaG1mVFErUnlGaXYrWmpvbkVzRVROUUs4bjdDVStOMmRpaVg1ZDdRalRYbHlhV0Z0SUUxcAotWkhrZ1BHMTVjbWxoYlY5dGFXUjVRR3h2ZEhWekxtTnZiVDZKQUU0RUVCRUNBQTRGQWp1T2xGc0VDd01DQVFJWgotQVFBS0NSRGV6aUsyd2NWOUx6Wi9BS0NZVDRTTkFGeVFCK3RBOTNuWWpSbytOTWMxMndDYUF3NnpmSjdqN3BJNAotZTdMMk9BMG5pU2Q4dkhlNUFnMEVPNDZVV3hBSUFQWkNWN2NJZndnWGNxSzYxcWxDOHdYbytWTVJPVSsyOFc2NQotU3pnZzJnR25WcU1VNlk5QVZmUFFCOGJMUTZtVXJmZE1aSVpKK0F5RHZXWHBGOVNoMDFENDlWbGYzSFpTVHowOQotamR2T21lRlhrbG5OL2JpdWRFL0YvSGE4ZzhWSE1HSE9mTWxtL3hYNXUvMlJYc2NCcXROYm5vMmdwWEk2MUJydwotdjBZQVdDdmw5SWo5V0U1SjI4MGd0SjNra1FjMmF6TnNPQTFGSFE5OGlMTWNmRnN0anZienlTUEFRL0NsV3hpTgotanJ0VmpMaGRPTk0wL1h3WFYwT2pIUmhzM2pNaExMVXEvenpoc1NsQUdCR05mSVNuQ25MV2hzUURHY2dIS1hySwotbFF6WmxwK3IwQXBRbXdKRzB3ZzlacVJkUVorY2ZMMkpTeUlaSnJxcm9sN0RWZWt5Q3pzQUFnSUlBTnh4RmpZbwotdFVGVFFwdkVWSHUxWkpoeVpOeVNsUjVFRURGZW1HLzNBQzY3TWh2N3lnSGFlS1Avb0Z6SWl4S21XbGxUN2lLUwotU0xqeVM3NXJxN0xwVHpoYXNnMitzdVFQUm5WOHkyQVRUTG5sS1dRVm1aZlZLWTFSRGlPNE1XTGlrOWxhRlRWWQota0V5RmJLZ0Y5dzBMeWVvYnNEN1NVMUo0RDlJVU9ZbXNscTBtOXJhYzBsKzFvdk5ldGR6SW0zV1NUQi9nbS9CMgotTnJ6MXo4dXJoNG1mK1JKd3VPMHRvOWZrU2pFMUtVY3JFN25UaVNENkEzZVVhUUM2UytRNXdFZWlCM1FONWYxOAotZ2lRdXhuYTlBZXQ5Sjh0bk1rKzVpdWgwUVlLak55WGx5WUQ1QjlaRi80U1huUVZEaTZqQUlDL1p6dC9ZcXp3bwotUVgzTkF0Ujh5WTBXZ0FTSkFFWUVHQkVDQUFZRkFqdU9sRnNBQ2drUTNzNGl0c0hGZlMrUTFRQ2c5eXdieHYxbgotMzJnbE1xZkliOVg3aWNXeFlJRUFvT0djdHJrd2ZBNzFoRUIwUzZ6aFQ0VVUzeng3Ci09ZURDKwotLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQpkaWZmIC0tZ2l0IGEvTGljZW5zZSBiL0xpY2Vuc2UKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIxMTU2YTYuLjAwMDAwMDAKLS0tIGEvTGljZW5zZQorKysgL2Rldi9udWxsCkBAIC0xLDU1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KZGlmZiAtLWdpdCBhL2Jpbi9CQ0VMLmphciBiL2Jpbi9CQ0VMLmphcgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzM0NjA1OC4uMDAwMDAwMAotLS0gYS9iaW4vQkNFTC5qYXIKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9iaW4vSkxleC5qYXIgYi9iaW4vSkxleC5qYXIKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFjOTc3ZjMuLjAwMDAwMDAKLS0tIGEvYmluL0pMZXguamFyCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvYmluL2FudC5qYXIgYi9iaW4vYW50LmphcgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTRlZmFiMy4uMDAwMDAwMAotLS0gYS9iaW4vYW50LmphcgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2Jpbi9hbnRSdW4gYi9iaW4vYW50UnVuCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMGExOGYxLi4wMDAwMDAwCi0tLSBhL2Jpbi9hbnRSdW4KKysrIC9kZXYvbnVsbApAQCAtMSw5ICswLDAgQEAKLSMhIC9iaW4vc2gKLQotIyBBcmdzOiBESVIgY29tbWFuZAotY2QgIiQxIgotQ01EPSIkMiIKLXNoaWZ0Ci1zaGlmdAotCi1leGVjICRDTUQgIiRAIgpkaWZmIC0tZ2l0IGEvYmluL2FudFJ1bi5iYXQgYi9iaW4vYW50UnVuLmJhdApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggODE2Y2I2MC4uMDAwMDAwMAotLS0gYS9iaW4vYW50UnVuLmJhdAorKysgL2Rldi9udWxsCkBAIC0xLDIwICswLDAgQEAKLUBlY2hvIG9mZgotCi0jIENoYW5nZSBkcml2ZSBhbmQgZGlyZWN0b3J5IHRvICUxIChXaW45WCBvbmx5IGZvciBOVC8ySyB1c2UgImNkIC9kIikKLWNkICUxCi0lMVwKLXNldCBBTlRfUlVOX0NNRD0lMgotc2hpZnQKLXNoaWZ0Ci0KLXNldCBQQVJBTVM9Ci06bG9vcAotaWYgIiIlMSA9PSAiIiBnb3RvIHJ1bkNvbW1hbmQKLXNldCBQQVJBTVM9JVBBUkFNUyUgJTEKLXNoaWZ0Ci1nb3RvIGxvb3AKLQotOnJ1bkNvbW1hbmQKLXJlbSBlY2hvICVBTlRfUlVOX0NNRCUgJVBBUkFNUyUKLSVBTlRfUlVOX0NNRCUgJVBBUkFNUyUKLQpkaWZmIC0tZ2l0IGEvYmluL2JzZi5qYXIgYi9iaW4vYnNmLmphcgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTkwMzZjMS4uMDAwMDAwMAotLS0gYS9iaW4vYnNmLmphcgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2Jpbi9qYXZhX2N1cC5qYXIgYi9iaW4vamF2YV9jdXAuamFyCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZjdiMWY3Li4wMDAwMDAwCi0tLSBhL2Jpbi9qYXZhX2N1cC5qYXIKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9iaW4vcnVudGltZS5qYXIgYi9iaW4vcnVudGltZS5qYXIKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUwNDFjZGIuLjAwMDAwMDAKLS0tIGEvYmluL3J1bnRpbWUuamFyCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvYmluL3N0eWxlYm9vay0xLjAtYjNfeGFsYW4tMi5qYXIgYi9iaW4vc3R5bGVib29rLTEuMC1iM194YWxhbi0yLmphcgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmI2NDBlOS4uMDAwMDAwMAotLS0gYS9iaW4vc3R5bGVib29rLTEuMC1iM194YWxhbi0yLmphcgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2Jpbi94YWxhbjJqZG9jLmphciBiL2Jpbi94YWxhbjJqZG9jLmphcgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDg0YjQ3Yi4uMDAwMDAwMAotLS0gYS9iaW4veGFsYW4yamRvYy5qYXIKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9iaW4veGVyY2VzLmphciBiL2Jpbi94ZXJjZXMuamFyCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNWE1ZmRlLi4wMDAwMDAwCi0tLSBhL2Jpbi94ZXJjZXMuamFyCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvYmluL3htbC5qYXIgYi9iaW4veG1sLmphcgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzNmNjEyOS4uMDAwMDAwMAotLS0gYS9iaW4veG1sLmphcgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2J1aWxkLmJhdCBiL2J1aWxkLmJhdApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMTYyODY1OC4uMDAwMDAwMAotLS0gYS9idWlsZC5iYXQKKysrIC9kZXYvbnVsbApAQCAtMSw2MCArMCwwIEBACi1AZWNobyBvZmYKLXJlbSAgICAgYnVpbGQuYmF0OiBCdWlsZCBYYWxhbi1KIDIueCB1c2luZyBBbnQgCi1yZW0gICAgIFVzYWdlOiBidWlsZCBbYW50LW9wdGlvbnNdIFt0YXJnZXRzXQotcmVtICAgICBTZXR1cDoKLXJlbSAgICAgICAgIC0geW91IHNob3VsZCBzZXQgSkFWQV9IT01FCi1yZW0gICAgICAgICAtIHlvdSBjYW4gc2V0IEFOVF9IT01FIGlmIHlvdSB1c2UgeW91ciBvd24gQW50IGluc3RhbGwKLXJlbSAgICAgICAgIC0gSkFWQV9PUFRTIGlzIGFkZGVkIHRvIHRoZSBqYXZhIGNvbW1hbmQgbGluZQotcmVtICAgICAgICAgLSBQQVJTRVJfSkFSIG1heSBiZSBzZXQgdG8gdXNlIGFsdGVybmF0ZSBwYXJzZXIgKGRlZmF1bHQ6YmluXHhlcmNlcy5qYXIpCi1lY2hvLgotZWNobyBYYWxhbi1KIDIueCBCdWlsZAotZWNobyAtLS0tLS0tLS0tLS0tCi0KLWlmIG5vdCAiJUpBVkFfSE9NRSUiID09ICIiIGdvdG8gc2V0YW50Ci06bm9KYXZhSG9tZQotcmVtIERlZmF1bHQgY29tbWFuZCB1c2VkIHRvIGNhbGwgamF2YS5leGU7IGhvcGVmdWxseSBpdCdzIG9uIHRoZSBwYXRoIGhlcmUKLWlmICIlX0pBVkFDTUQlIiA9PSAiIiBzZXQgX0pBVkFDTUQ9amF2YQotZWNoby4KLWVjaG8gV2FybmluZzogSkFWQV9IT01FIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQuCi1lY2hvICAgSWYgYnVpbGQgZmFpbHMgYmVjYXVzZSBzdW4uKiBjbGFzc2VzIGNvdWxkIG5vdCBiZSBmb3VuZAotZWNobyAgIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHRoZSBKQVZBX0hPTUUgZW52aXJvbm1lbnQgdmFyaWFibGUKLWVjaG8gICB0byB0aGUgaW5zdGFsbGF0aW9uIGRpcmVjdG9yeSBvZiBqYXZhLgotZWNoby4KLQotOnNldGFudAotcmVtIERlZmF1bHQgY29tbWFuZCB1c2VkIHRvIGNhbGwgamF2YS5leGUgb3IgZXF1aXZhbGVudAotaWYgIiVfSkFWQUNNRCUiID09ICIiIHNldCBfSkFWQUNNRD0lSkFWQV9IT01FJVxiaW5camF2YQotCi1yZW0gRGVmYXVsdCBfQU5UX0hPTUUgdG8gWGFsYW4ncyBjaGVja2VkLWluIGNvcHkgaWYgbm90IHNldAotc2V0IF9BTlRfSE9NRT0lQU5UX0hPTUUlCi1pZiAiJV9BTlRfSE9NRSUiID09ICIiIHNldCBfQU5UX0hPTUU9LgotCi1yZW0gRGVmYXVsdCBsb2NhdGlvbnMgb2YgamFycyB3ZSBkZXBlbmQgb24gdG8gcnVuIEFudCBvbiBvdXIgYnVpbGQueG1sIGZpbGUKLXJlbSBTZXQgb3VyIGxvY2FsIHZhcnMgdG8gYWxsIHN0YXJ0IHdpdGggX3VuZGVyc2NvcmUKLXNldCBfQU5UX0pBUj0lQU5UX0pBUiUKLWlmICIlX0FOVF9KQVIlIiA9PSAiIiBzZXQgX0FOVF9KQVI9YmluXGFudC5qYXIKLXNldCBfUEFSU0VSX0pBUj0lUEFSU0VSX0pBUiUKLWlmICIlX1BBUlNFUl9KQVIlIiA9PSAiIiBzZXQgX1BBUlNFUl9KQVI9YmluXHhlcmNlcy5qYXIKLQotcmVtIEF0dGVtcHQgdG8gYXV0b21hdGljYWxseSBhZGQgc3lzdGVtIGNsYXNzZXMgdG8gX0NMQVNTUEFUSAotcmVtIFVzZSBfdW5kZXJzY29yZSBwcmVmaXggdG8gbm90IGNvbmZsaWN0IHdpdGggdXNlcidzIHNldHRpbmdzCi1zZXQgX0NMQVNTUEFUSD0lQ0xBU1NQQVRIJQotaWYgZXhpc3QgIiVKQVZBX0hPTUUlXGxpYlx0b29scy5qYXIiIHNldCBfQ0xBU1NQQVRIPSVDTEFTU1BBVEglOyVKQVZBX0hPTUUlXGxpYlx0b29scy5qYXIKLWlmIGV4aXN0ICIlSkFWQV9IT01FJVxsaWJcY2xhc3Nlcy56aXAiIHNldCBfQ0xBU1NQQVRIPSVDTEFTU1BBVEglOyVKQVZBX0hPTUUlXGxpYlxjbGFzc2VzLnppcAotc2V0IF9DTEFTU1BBVEg9JV9BTlRfSkFSJTslX1BBUlNFUl9KQVIlOyVfQ0xBU1NQQVRIJQotCi1SRU0gZWNobyAiJV9KQVZBQ01EJSIgJUpBVkFfT1BUUyUgLURhbnQuaG9tZT0iJUFOVF9IT01FJSIgLWNsYXNzcGF0aCAiJV9DTEFTU1BBVEglIiBvcmcuYXBhY2hlLnRvb2xzLmFudC5NYWluICUxICUyICUzICU0ICU1ICU2ICU3ICU4ICU5Ci1AZWNobyBvbgotIiVfSkFWQUNNRCUiIC1teDY0bSAlSkFWQV9PUFRTJSAtRGFudC5ob21lPSIlQU5UX0hPTUUlIiAtY2xhc3NwYXRoICIlX0NMQVNTUEFUSCUiIG9yZy5hcGFjaGUudG9vbHMuYW50Lk1haW4gJTEgJTIgJTMgJTQgJTUgJTYgJTcgJTggJTkKLUBlY2hvIG9mZgotCi1nb3RvIGVuZAotCi06ZW5kCi1yZW0gQ2xlYW51cCBlbnZpcm9ubWVudCB2YXJpYWJsZXMKLXNldCBfSkFWQUNNRD0KLXNldCBfQ0xBU1NQQVRIPQotc2V0IF9BTlRfSE9NRT0KLXNldCBfQU5UX0pBUj0KLXNldCBfUEFSU0VSX0pBUj0KLQpkaWZmIC0tZ2l0IGEvYnVpbGQuc2ggYi9idWlsZC5zaApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggNGQ4OTkyOS4uMDAwMDAwMAotLS0gYS9idWlsZC5zaAorKysgL2Rldi9udWxsCkBAIC0xLDUxICswLDAgQEAKLSMhL2Jpbi9zaAotIwlOYW1lOiAgIGJ1aWxkLnNoIEJ1aWxkIFhhbGFuLUogMi54IHVzaW5nIEFudAotIwlBdXRob3I6IFNoYW5lIEN1cmN1cnUKLQotIyBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIGp1c3QgY2FsbCAiYW50IiAKLQotZWNobyAiWGFsYW4tSiAyLnggQnVpbGQiCi1lY2hvICItLS0tLS0tLS0tLS0tIgotCi1fSkFWQUNNRD0kSkFWQV9IT01FL2Jpbi9qYXZhCi1pZiBbICIkSkFWQV9IT01FIiA9ICIiIF0gOyB0aGVuCi0gICAgZWNobyAiV2FybmluZzogSkFWQV9IT01FIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQuIgotICAgIF9KQVZBQ01EPWphdmEKLWZpCi0KLSMgRGVmYXVsdCBsb2NhdGlvbnMgb2YgamFycyB3ZSBkZXBlbmQgb24gdG8gcnVuIEFudCBvbiBvdXIgYnVpbGQueG1sIGZpbGUKLWlmIFsgIiRBTlRfSE9NRSIgPSAiIiBdIDsgdGhlbgotICAgIEFOVF9IT01FPS4KLWZpCi1pZiBbICIkQU5UX0pBUiIgPSAiIiBdIDsgdGhlbgotICAgIEFOVF9KQVI9Li9iaW4vYW50LmphcgotZmkKLWlmIFsgIiRQQVJTRVJfSkFSIiA9ICIiIF0gOyB0aGVuCi0gICAgUEFSU0VSX0pBUj0uL2Jpbi94ZXJjZXMuamFyCi1maQotCi0jIFVzZSBfdW5kZXJzY29yZSBwcmVmaXggdG8gbm90IGNvbmZsaWN0IHdpdGggdXNlcidzIHNldHRpbmdzCi0jIERlZmF1bHQgdG8gVU5JWC1zdHlsZSBwYXRoaW5nCi1DTFBBVEhTRVA9OgotIyBpZiB3ZSdyZSBvbiBhIFdpbmRvd3MgYm94IG1ha2UgaXQgOwotdW5hbWUgfCBncmVwIFdJTiAmJiBDTFBBVEhTRVA9XDsKLV9DTEFTU1BBVEg9IiRBTlRfSkFSJHtDTFBBVEhTRVB9JFBBUlNFUl9KQVIke0NMUEFUSFNFUH0kQ0xBU1NQQVRIIgotCi0jIEF0dGVtcHQgdG8gYXV0b21hdGljYWxseSBhZGQgc3lzdGVtIGNsYXNzZXMgdG8gX0NMQVNTUEFUSAotaWYgWyAtZiAkSkFWQV9IT01FL2xpYi90b29scy5qYXIgXSA7IHRoZW4KLSAgX0NMQVNTUEFUSD0ke19DTEFTU1BBVEh9JHtDTFBBVEhTRVB9JHtKQVZBX0hPTUV9L2xpYi90b29scy5qYXIKLWZpCi0KLWlmIFsgLWYgJEpBVkFfSE9NRS9saWIvY2xhc3Nlcy56aXAgXSA7IHRoZW4KLSAgX0NMQVNTUEFUSD0ke19DTEFTU1BBVEh9JHtDTFBBVEhTRVB9JHtKQVZBX0hPTUV9L2xpYi9jbGFzc2VzLnppcAotZmkKLQotCi1lY2hvICJTdGFydGluZyBBbnQgd2l0aCB0YXJnZXRzOiAkQCIKLWVjaG8gIiAgICAgICAgLi4ud2l0aCBjbGFzc3BhdGg6ICRfQ0xBU1NQQVRIIgotCi0iJF9KQVZBQ01EIiAkSkFWQV9PUFRTIC1EYW50LmhvbWU9JEFOVF9IT01FIC1jbGFzc3BhdGggIiRfQ0xBU1NQQVRIIiBvcmcuYXBhY2hlLnRvb2xzLmFudC5NYWluICRACi0KLQotCi0KZGlmZiAtLWdpdCBhL2J1aWxkLnhtbCBiL2J1aWxkLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjhkYTg5OC4uMDAwMDAwMAotLS0gYS9idWlsZC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw4MjMgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gICBCdWlsZCBmaWxlIGZvciBYYWxhbi1KIDIueCAtIGZvciB1c2Ugd2l0aCB0aGUgSmFrYXJ0YSBBbnQgamF2YSBidWlsZCB0b29sCi0gICAKLVNldHVwIGluc3RydWN0aW9uczogCi0gICBCZWZvcmUgcnVubmluZyBhbiBBbnQgYnVpbGQsIHlvdSBtdXN0Ci0gICAKLSAgICAgLSBzZXQgdGhlIEpBVkFfSE9NRSBlbnZpcm9ubWVudCB2YXJpYWJsZSB0byB0aGUgSkRLIHJvb3QgZGlyZWN0b3J5Ci0gICAgIC0gVG8gYnVpbGQgJ3NlcnZsZXQnIHNhbXBsZTogSW5jbHVkZSBTZXJ2bGV0IFNESyBpbiB5b3VyIGNsYXNzcGF0aAotICAgICAtIFRvIGJ1aWxkIGRvY3MvamF2YWRvY3MveHNsdGM6IHVzZSBKREsgMS4yLnggb3IgaGlnaGVyCi0gICAKLUJ1aWxkIEluc3RydWN0aW9uczogICAKLSAgVG8gYnVpbGQsIHJ1bgotICAgIGJ1aWxkLmJhdCAod2luMzIpIG9yIGJ1aWxkLnNoICh1bml4KSBbYW50b3B0aW9uc10gW3RhcmdldHNdCi0gIGluIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhpcyBmaWxlIGlzIGxvY2F0ZWQuCi0gICAKLSAgYnVpbGQgLXByb2plY3RoZWxwICB3aWxsIHNob3cgYSBsaXN0IG9mIHN1cHBvcnRlZCB0YXJnZXRzLgotICAgCi0gIERldmVsb3BlcnM6IGluY2x1ZGUgYSBkZXNjcmlwdGlvbj0iIiBhdHRyaWJ1dGUgaW4gYWxsIHVzZXItY2FsbGFibGUgdGFyZ2V0cy4KLSAgICAgICAgCi0gIElmIHlvdSBidWlsZCBhIHRhcmdldCB0aGF0IGRlcGVuZHMgb24gb3RoZXIgdGFyZ2V0cywgdGhvc2Ugb3RoZXIgCi0gIHRhcmdldHMgYXJlICp1c3VhbGx5KiBjcmVhdGVkIGluIHRoZSBjb3JyZWN0IG9yZGVyOyBob3dldmVyIGEgCi0gIGZldyBvZiB0aGUgbGFyZ2VyIHRhcmdldHMgbGlrZSBkaXN0IGRvIG5vdCBsaXN0IGFsbCBkZXBlbmRlbmNpZXMuCi0KLU90aGVyIEltcG9ydGFudCBOb3RlczoKLS0gJ2Rpc3QnIHByb2R1Y2VzIGEgLnRhciBmaWxlIHRoYXQgd29ya3Mgd2l0aCBHTlUgY29tcGF0aWJsZSB0YXIgCi0gIHByb2dyYW1zLCBiZWNhdXNlIHRoYXQncyB3aGF0IEFudCBkb2VzIHdoZW4gaXQgZmluZHMgYSBwYXRoIHRoYXQncyAKLSAgbG9uZ2VyIHRoYW4gMTAwIGNoYXJhY3RlcnMgKGxpa2UgaW4gb3VyIGRvY3MpLiAgU29ycnkhCi0gIAotLSBFeHRlcm5hbCBidWlsZCBtYWludGFpbmVyczogbG9vayBmb3IgR1VNUDogY29tbWVudHM7IGRldmVsb3BlcnMgCi0gIHBsZWFzZSB1c2UgZ3JlYXQgY2F1dGlvbiB3aGVuIGNoYW5naW5nIHRoZXNlIGxpbmVzIQotCi0tIFVudXN1YWwgYnVpbGQgaXRlbXM6IHRoZSBkb2NzIGFuZCB4c2x0Yy5jb21waWxlIHRhcmdldHMgbGVhdmUgCi0gIGNydWZ0IGluIHRoZSBzb3VyY2UgYXJlYXM7IHZhcmlvdXMgY2xlYW4gdGFyZ2V0cyBnZXQgbW9zdCBvZiB0aGlzLgotICAKLUF1dGhvcnM6Ci0gIFNoYW5lIEN1cmN1cnUgPHNoYW5lX2N1cmN1cnVAbG90dXMuY29tPgotICBEb24gTGVzbGllIDxkb25hbGRfbGVzbGllQGxvdHVzLmNvbT4KLQotQ29weXJpZ2h0OgotICBDb3B5cmlnaHQgKGMpIDE5OTktMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gICAkSWQkCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLQotPHByb2plY3QgbmFtZT0iWGFsYW4iIGRlZmF1bHQ9ImphciIgYmFzZWRpcj0iLiI+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPCEtLSBEZWZpbmVzIHBhdGhzL25hbWVzIG9mIHByZXJlcXVpc2l0ZSBqYXIgZmlsZXMgd2UgY29tcGlsZSBhZ2FpbnN0ICAgIC0tPgotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gV2Uga2VlcCBjaGVja2VkLWluIGtub3duLWdvb2QgLmphcnMgaGVyZSAtLT4KLSAgPHByb3BlcnR5IG5hbWU9ImJpbi5kaXIiIHZhbHVlPSIuL2JpbiIvPgotCi0gIDwhLS0gR1VNUDogQWxsb3dzIGV4dGVybmFsIGJ1aWxkIHN5c3RlbXMgdG8gcmVwbGFjZSAuamFycyBYYWxhbiAKLSAgICAgICBpcyBkZXBlbmRlbnQgb24gYXMgbmVlZGVkLiAgTW9zdCBoYXZlIHNlcGFyYXRlIG5hbWUgYW5kIAotICAgICAgIGxvY2F0aW9uIHByb3BlcnRpZXMgdG8gbWFrZSBpdCBzaW1wbGVyIHRvIHJlc2V0IHRoZXNlIHZhbHVlczsgCi0gICAgICAgcGxlYXNlIHByb3ZpZGUgZmVlZGJhY2sgaWYgdGhpcyBpcyB1c2VmdWwuIAotICAtLT4KLSAgPHByb3BlcnR5IG5hbWU9InBhcnNlci5qYXIubmFtZSIgdmFsdWU9InhlcmNlcy5qYXIiLz4KLSAgPHByb3BlcnR5IG5hbWU9InBhcnNlci5qYXIiIHZhbHVlPSIke2Jpbi5kaXJ9LyR7cGFyc2VyLmphci5uYW1lfSIvPgotICA8cHJvcGVydHkgbmFtZT0iYnNmLmphci5uYW1lIiB2YWx1ZT0iYnNmLmphciIvPgotICA8cHJvcGVydHkgbmFtZT0iYnNmLmphciIgdmFsdWU9IiR7YmluLmRpcn0vJHtic2YuamFyLm5hbWV9Ii8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJzdHlsZWJvb2suamFyLm5hbWUiIHZhbHVlPSJzdHlsZWJvb2stMS4wLWIzX3hhbGFuLTIuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJzdHlsZWJvb2suamFyIiB2YWx1ZT0iJHtiaW4uZGlyfS8ke3N0eWxlYm9vay5qYXIubmFtZX0iLz4KLSAgPHByb3BlcnR5IG5hbWU9ImRvY2xldC5qYXIubmFtZSIgdmFsdWU9InhhbGFuMmpkb2MuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJkb2NsZXQuamFyIiB2YWx1ZT0iJHtiaW4uZGlyfS8ke2RvY2xldC5qYXIubmFtZX0iLz4KLQotICA8IS0tIEdVTVA6IEN1cnJlbnRseSAxOC1BcHItMDEgdXNlZCBvbmx5IGZvciB4c2x0Yy5jb21waWxlIC0tPgotICA8cHJvcGVydHkgbmFtZT0iQkNFTC5qYXIubmFtZSIgdmFsdWU9IkJDRUwuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJCQ0VMLmphciIgdmFsdWU9IiR7YmluLmRpcn0vJHtCQ0VMLmphci5uYW1lfSIvPgotICA8cHJvcGVydHkgbmFtZT0iY3JpbXNvbi5qYXIubmFtZSIgdmFsdWU9ImNyaW1zb24uamFyIi8+PCEtLSBXaHkgaXMgdGhpcyBoZXJlPyAxMC1TZXAtMDEgLXNjIC0tPgotICA8cHJvcGVydHkgbmFtZT0iY3JpbXNvbi5qYXIiIHZhbHVlPSIke2Jpbi5kaXJ9LyR7Y3JpbXNvbi5qYXIubmFtZX0iLz4KLSAgPHByb3BlcnR5IG5hbWU9ImphdmFfY3VwLmphci5uYW1lIiB2YWx1ZT0iamF2YV9jdXAuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJqYXZhX2N1cC5qYXIiIHZhbHVlPSIke2Jpbi5kaXJ9LyR7amF2YV9jdXAuamFyLm5hbWV9Ii8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJKTGV4Lmphci5uYW1lIiB2YWx1ZT0iSkxleC5qYXIiLz4KLSAgPHByb3BlcnR5IG5hbWU9IkpMZXguamFyIiB2YWx1ZT0iJHtiaW4uZGlyfS8ke0pMZXguamFyLm5hbWV9Ii8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJydW50aW1lLmphci5uYW1lIiB2YWx1ZT0icnVudGltZS5qYXIiLz4KLSAgPHByb3BlcnR5IG5hbWU9InJ1bnRpbWUuamFyIiB2YWx1ZT0iJHtiaW4uZGlyfS8ke3J1bnRpbWUuamFyLm5hbWV9Ii8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ4bWwuamFyLm5hbWUiIHZhbHVlPSJ4bWwuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ4bWwuamFyIiB2YWx1ZT0iJHtiaW4uZGlyfS8ke3htbC5qYXIubmFtZX0iLz4KLQotICA8IS0tIERlZmluZXMgZ2VuZXJhbCB2YXJpYWJsZXMgdXNlZCBieSB0aGUgb3RoZXIgdGFyZ2V0czsgbmFtZSBjb250cm9scyBvdXRwdXQgeGFsYW4uamFyICAtLT4KLSAgPHByb3BlcnR5IG5hbWU9InZlcnNpb24iIHZhbHVlPSIyXzJfRDEwIi8+PCEtLSBHVU1QOiB2ZXJzaW9uICMgb2YgZGlzdCBmaWxlIC0tPgotICA8cHJvcGVydHkgbmFtZT0ibmFtZSIgdmFsdWU9InhhbGFuIi8+PCEtLSBHVU1QOiBiYXNlIG5hbWUgb2YgamFyIHRhcmdldCdzIGZpbGUgLS0+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ5ZWFyIiB2YWx1ZT0iMjAwMSIvPgotICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuY29tcGlsZXIiIHZhbHVlPSJjbGFzc2ljIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJkZWJ1ZyIgdmFsdWU9Im9mZiIvPgotCi0gIDwhLS0gUmVsYXRpdmUgbG9jYXRpb25zIG9mIHNvdXJjZSBkaXJlY3RvcmllcyAtLT4KLSAgPHByb3BlcnR5IG5hbWU9Im1ldGFpbmYuZGlyIiB2YWx1ZT0iLi9zcmMvTUVUQS1JTkYiLz4KLSAgPHByb3BlcnR5IG5hbWU9InNyYy5kaXIiIHZhbHVlPSIuL3NyYyIvPgotICA8cHJvcGVydHkgbmFtZT0ieHBhdGgucmVsZGlyIiB2YWx1ZT0ib3JnL2FwYWNoZS94cGF0aCIvPgotICA8cHJvcGVydHkgbmFtZT0ieGFsYW4ucmVsZGlyIiB2YWx1ZT0ib3JnL2FwYWNoZS94YWxhbiIvPgotICA8cHJvcGVydHkgbmFtZT0ieHNsdGMucmVsZGlyIiB2YWx1ZT0iJHt4YWxhbi5yZWxkaXJ9L3hzbHRjIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ0cmF4LnJlbGRpciIgdmFsdWU9ImphdmF4L3htbC90cmFuc2Zvcm0iLz4KLSAgPHByb3BlcnR5IG5hbWU9InNlcmlhbGl6ZS5yZWxkaXIiIHZhbHVlPSJvcmcvYXBhY2hlL3NlcmlhbGl6ZSIvPgotICA8cHJvcGVydHkgbmFtZT0ic2VyaWFsaXplci5yZWxkaXIiIHZhbHVlPSJvcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZSIvPgotICA8cHJvcGVydHkgbmFtZT0iamF4cC5yZWxkaXIiIHZhbHVlPSJqYXZheC94bWwvcGFyc2VycyIvPgotICA8cHJvcGVydHkgbmFtZT0ic2F4LnJlbGRpciIgdmFsdWU9Im9yZy94bWwvc2F4Ii8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ3M2MucmVsZGlyIiB2YWx1ZT0ib3JnL3czYyIvPiAgICAKLQotICA8IS0tIEJ1aWxkIGFuZCBkaXN0cmlidXRpb24gb3V0cHV0IGFyZWFzIC0tPgotICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuZGlyIiB2YWx1ZT0iLi9idWlsZCIvPjwhLS0gR1VNUDogcm9vdCBvZiBhbGwgbm9ybWFsIGJ1aWxkcyBvdXRwdXQgLS0+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC54YWxhbi5qYXIiIHZhbHVlPSIke2J1aWxkLmRpcn0vJHtuYW1lfS5qYXIiLz48IS0tIEdVTVA6IGFjdHVhbCBwYXRoL25hbWUgb2YgamFyIHRhcmdldCBvdXRwdXQgLS0+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC54c2x0Yy5qYXIiIHZhbHVlPSIke2J1aWxkLmRpcn0veHNsdGMuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5jbGFzc2VzIiB2YWx1ZT0iJHtidWlsZC5kaXJ9L2NsYXNzZXMiLz4KLSAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLmRvY3MiIHZhbHVlPSIke2J1aWxkLmRpcn0vZG9jcyIvPgotICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuc2FtcGxlcyIgdmFsdWU9IiR7YnVpbGQuZGlyfS9zYW1wbGVzIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5hcGlkb2NzIiB2YWx1ZT0iJHtidWlsZC5kb2NzfS9hcGlkb2NzIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJkaXN0LmZpbGUiIHZhbHVlPSIke25hbWV9LWpfJHt2ZXJzaW9ufSIvPjwhLS0gR1VNUDogYWN0dWFsIHBhdGgvbmFtZSBvZiBkaXN0IHRhcmdldCAudGFyLmd6Ly56aXAtLT4KLSAgPHByb3BlcnR5IG5hbWU9ImRpc3QuZGlyIiB2YWx1ZT0iJHtidWlsZC5kaXJ9LyR7ZGlzdC5maWxlfSIvPgotICAKLSAgPCEtLSBYYWxhbi1KMSBjb21wYXRhYmlsaXR5IHN0dWZmLiAgLS0+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJjb21wYXQuamFyIiB2YWx1ZT0ieGFsYW5qMWNvbXBhdC5qYXIiLz4KLSAgPHByb3BlcnR5IG5hbWU9ImNvbXBhdC5zcmMuZGlyIiB2YWx1ZT0iLi9jb21wYXRfc3JjIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5jb21wYXQuY2xhc3NlcyIgdmFsdWU9IiR7YnVpbGQuZGlyfS9jb21wYXRfY2xhc3NlcyIvPgotICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuY29tcGF0LmphciIgdmFsdWU9IiR7YnVpbGQuZGlyfS8ke2NvbXBhdC5qYXJ9Ii8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5jb21wYXQuYXBpZG9jcyIgdmFsdWU9IiR7YnVpbGQuZG9jc30vY29tcGF0X2FwaWRvY3MiLz4gICAgICAgIAotCi0gIDwhLS0gRG9jdW1lbnRhdGlvbiBhbmQgc2FtcGxlcyBpbmZvcm1hdGlvbiAgLS0+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJOYW1lIiB2YWx1ZT0iWGFsYW4tSmF2YSIvPgotICA8cHJvcGVydHkgbmFtZT0idmVyc2lvbi5maWxlIiB2YWx1ZT0iJHt4YWxhbi5yZWxkaXJ9L3Byb2Nlc3Nvci9YU0xQcm9jZXNzb3JWZXJzaW9uLmphdmEiLz4KLSAgPHByb3BlcnR5IG5hbWU9InNhbXBsZXMuZGlyIiB2YWx1ZT0iLi9zYW1wbGVzIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5zYW1wbGVzLmphciIgdmFsdWU9IiR7YnVpbGQuZGlyfS94YWxhbnNhbXBsZXMuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5zZXJ2bGV0LmphciIgdmFsdWU9IiR7YnVpbGQuZGlyfS94YWxhbnNlcnZsZXQuamFyIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ4ZG9jcy5kaXIiIHZhbHVlPSIuL3hkb2NzIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ4ZG9jcy5ib29rIiB2YWx1ZT0iJHt4ZG9jcy5kaXJ9L3NvdXJjZXMveGFsYW4tamxvY2FsLnhtbCIvPgotICA8cHJvcGVydHkgbmFtZT0ieGRvY3Muc3R5bGUiIHZhbHVlPSIke3hkb2NzLmRpcn0vc3R5bGUiLz4KLSAgPHByb3BlcnR5IG5hbWU9InhhbGFub25seS1zdHlsZWRvY3MiCi0gICAgICAgICAgICB2YWx1ZT0iZHRkL3hzbC1odG1sNDBzLmR0ZCxkdGQvc3BlYy5kdGQsc3R5bGVzaGVldHMvcGF0dGVybnMueHNsLHN0eWxlc2hlZXRzL25vdGljZS54c2wsc3R5bGVzaGVldHMvc3BlYy54c2wsc3R5bGVzaGVldHMvZG9uZS54c2wsbG9hZGVyZGVzaWduLnhtbCxzdHlsZXNoZWV0cy9kZXNpZ24ycHJvamVjdC54c2wsc3R5bGVzaGVldHMvZGVzaWduZG9jMmh0bWwueHNsLHN0eWxlc2hlZXRzL3htbDJmby54c2wiLz4KLSAgPHByb3BlcnR5IG5hbWU9InhhbGFuLmNtZGxpbmUuY2xhc3MiIHZhbHVlPSJvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyIvPgotICA8cHJvcGVydHkgbmFtZT0iZG9jLmdlbmVyYXRvciIgdmFsdWU9Im9yZy5hcGFjaGUuc3R5bGVib29rLlN0eWxlQm9vayIvPgotICA8cHJvcGVydHkgbmFtZT0iZG9jLmdlbmVyYXRvci5zdHlsZXRhcmd6IiB2YWx1ZT0iJHt4ZG9jcy5kaXJ9L3htbC1zaXRlLXN0eWxlLnRhci5neiIvPgotICA8cHJvcGVydHkgbmFtZT0iZG9jLmdlbmVyYXRvci5zdHlsZXRhciIgdmFsdWU9IiR7eGRvY3MuZGlyfS94bWwtc2l0ZS1zdHlsZS50YXIiLz4KLSAgPHByb3BlcnR5IG5hbWU9InNpdGUucm9vdCIgdmFsdWU9Ii4veG1sLXNpdGUiLz4KLSAgPHByb3BlcnR5IG5hbWU9InNpdGUuZGlyIiB2YWx1ZT0iJHtzaXRlLnJvb3R9L3RhcmdldC94YWxhbi1qIi8+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJzaXRlLmJvb2siIHZhbHVlPSIke3hkb2NzLmRpcn0vc291cmNlcy94YWxhbi1qc2l0ZS54bWwiLz4KLSAgPHByb3BlcnR5IG5hbWU9Inhkb2NzLkRPTkUuZmlsZSIgdmFsdWU9IiR7eGRvY3MuZGlyfS9zb3VyY2VzL3hhbGFuL0RPTkUiLz4KLSAgPHBhdGggaWQ9ImRvY3MuY2xhc3MucGF0aCI+Ci0gICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2JzZi5qYXJ9IiAvPgotICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtzdHlsZWJvb2suamFyfSIgLz4KLSAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7ZG9jbGV0Lmphcn0iIC8+Ci0gICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2J1aWxkLnhhbGFuLmphcn0iIC8+Ci0gICAgPHBhdGhlbGVtZW50IHBhdGg9IiR7amF2YS5jbGFzcy5wYXRofSIgLz4KLSAgPC9wYXRoPgotCi0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPCEtLSBDcmVhdGVzIG91dHB1dCBidWlsZCBkaXJlY3RvcmllcyBhbmQgZG9jIHByZXJlcXVpc3RlcyAgICAgICAgICAgICAgIC0tPgotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDx0YXJnZXQgbmFtZT0icHJlcGFyZSI+Ci0gICAgPGVjaG8gbWVzc2FnZT0iUHJvamVjdDoke05hbWV9IHZlcnNpb246JHt2ZXJzaW9ufSBidWlsZC54bWwgJFJldmlzaW9uJCIvPgotICAgIDxta2RpciBkaXI9IiR7YnVpbGQuZGlyfSIvPgotICAgIDxta2RpciBkaXI9IiR7YnVpbGQuY2xhc3Nlc30iLz4KLSAgICA8IS0tIE5vdGUgdGhhdCBhbGwgdGVzdGluZy1yZWxhdGVkIHRhcmdldHMgKm11c3QqIGRlcGVuZCBvbiAKLSAgICAgICAgIHRoaXMgdGFyZ2V0LCBlaXRoZXIgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSwgdG8gZ2V0IAotICAgICAgICAgdGhlIHRlc3RzLWF2YWlsYWJsZSBwcm9wZXJ0eSBzZXQgZm9yIHRoZW0uCi0gICAgLS0+Ci0gICAgPGF2YWlsYWJsZSBmaWxlPSIke3Rlc3QucmVscGF0aH0iIHByb3BlcnR5PSJ0ZXN0cy1hdmFpbGFibGUiIC8+Ci0gICAgPGF2YWlsYWJsZSBwcm9wZXJ0eT0ieGVyY2VzLnByZXNlbnQiIAotICAgICAgY2xhc3NuYW1lPSJvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlciIvPgotICA8L3RhcmdldD4KLQotICA8IS0tIE11c3QgZGVwZW5kIG9uIGphciBzaW5jZSB3ZSB1c2UgWGFsYW4gdG8gcHJvY2VzcyB4bWwgZmlsZXMgLS0+Ci0gIDx0YXJnZXQgbmFtZT0icHJlcGFyZS5kb2NzIiBkZXBlbmRzPSJqYXIiPgotICAgIDxta2RpciBkaXI9IiR7YnVpbGQuZG9jc30iLz4gCi0gICAgPG1rZGlyIGRpcj0iJHtidWlsZC5hcGlkb2NzfSIvPgotCi0gICAgPGd1bnppcCBzcmM9IiR7ZG9jLmdlbmVyYXRvci5zdHlsZXRhcmd6fSIvPgotICAgIDx1bnRhciBzcmM9IiR7ZG9jLmdlbmVyYXRvci5zdHlsZXRhcn0iIGRlc3Q9IiR7eGRvY3MuZGlyfSIvPgotICAgIDxkZWxldGUgZmlsZT0iJHtkb2MuZ2VuZXJhdG9yLnN0eWxldGFyfSIvPgotICAgIAotICAgIDxlY2hvIG1lc3NhZ2U9IlRyYW5zZm9ybSB0b2RvLnhtbCBhbmQgcHV0IHRoZSByZXN1bHQgaW4gJHtidWlsZC5kb2NzfSIvPgotICAgIDxqYXZhIGZvcms9InllcyIgY2xhc3NuYW1lPSIke3hhbGFuLmNtZGxpbmUuY2xhc3N9Ij4KLSAgICAgIDxjbGFzc3BhdGggcmVmaWQ9ImRvY3MuY2xhc3MucGF0aCIgLz4KLSAgICAgIDxhcmcgbGluZT0iLWluIHRvZG8ueG1sIC14c2wgdG9kby54c2wgLW91dCBidWlsZC9kb2NzL3RvZG8uaHRtbCIvPgotICAgIDwvamF2YT4gCi0gICAgPCEtLSBXZSB1c2UgYSBOb3RlcyBhZ2VudCB0byBwZXJpb2RpY2FsbHkgZXh0cmFjdCBYYWxhbi1KYXZhIDIgY29tbWl0cyBmcm9tIG91ciB0ZWFtIGRhdGFiYXNlIGludG8gY29tbWl0cy54bWwuICBUaGUgZm9sbG93aW5nIG9wZXJhdGlvbiAKLSAgICB0cmFuc2Zvcm1zIGNvbW1pdHMueG1sIChqdXN0IGluY2x1ZGluZyBzb3VyY2UgY29kZSBjb21taXRzKSBhbmQgcHV0cyB0aGUgcmVzdWx0IGluIHhkb2NzL3NvdXJjZXMveGFsYW4gZm9yIGluY2x1c2lvbiBpbiB0aGUgCi0gICAgcmVhZG1lLnhtbCAtLT4gICAgICAKLSAgICA8ZWNobyBtZXNzYWdlPSJUcmFuc2Zvcm0gY29tbWl0cy54bWwgYW5kIHB1dCB0aGUgcmVzdWx0IGluICR7eGRvY3MuZGlyfSIvPgotICAgIDxqYXZhIGZvcms9InllcyIgY2xhc3NuYW1lPSIke3hhbGFuLmNtZGxpbmUuY2xhc3N9IiA+Ci0gICAgICA8Y2xhc3NwYXRoIHJlZmlkPSJkb2NzLmNsYXNzLnBhdGgiIC8+Ci0gICAgICA8YXJnIGxpbmU9Ii1pbiBjb21taXRzLnhtbCAteHNsICR7eGRvY3Muc3R5bGV9L3N0eWxlc2hlZXRzL2RvbmUueHNsIC1vdXQgJHt4ZG9jcy5ET05FLmZpbGV9Ii8+Ci0gICAgPC9qYXZhPgotICAgIDxlY2hvIG1lc3NhZ2U9IkdlbmVyYXRlIFhhbGFuLUogMi54IGRlc2lnbiBkb2N1bWVudCIvPgotICAgIDxqYXZhIGZvcms9InllcyIgY2xhc3NuYW1lPSIke2RvYy5nZW5lcmF0b3J9IiA+Ci0gICAgICA8Y2xhc3NwYXRoIHJlZmlkPSJkb2NzLmNsYXNzLnBhdGgiIC8+Ci0gICAgICA8YXJnIGxpbmU9ImxvYWRlckNvbmZpZz1zYms6L3N0eWxlL2xvYWRlcmRlc2lnbi54bWwgdGFyZ2V0RGlyZWN0b3J5PS4vYnVpbGQvZG9jcy9kZXNpZ24vCi0gICAgICAgICAgICAgICAgIC4veGRvY3Mvc291cmNlcy94YWxhbmRlc2lnbi54bWwgLi94ZG9jcy9zdHlsZSIvPgotICAgIDwvamF2YT4KLSAgPC90YXJnZXQ+Ci0KLQotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gQ29tcGlsZSBlbnRpcmUgc291cmNlIHRyZWUgLSBleGNlcHQgWGFsYW4tSiAxIGNvbXBhdGFiaWxpdHkgY2xhc3NlcyAtLT4KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8dGFyZ2V0IG5hbWU9ImNvbXBpbGUiIGRlcGVuZHM9InByZXBhcmUiCi0gICAgZGVzY3JpcHRpb249IkNvbXBpbGUgWGFsYW4tSiAyLnggKHNraXBzIDEueCBjb21wYXQgYW5kIFhTTFRDKSIgPgotICAgIDxlY2hvIG1lc3NhZ2U9ImNvbXBpbGUgZW50aXJlIHNvdXJjZSB0cmVlIGFuZCBjb3B5IC5wcm9wZXJ0aWVzIGFuZCAucmVzIGZpbGVzIHRvIGJ1aWxkIHRyZWUuIi8+Ci0gICAgPCEtLSBOb3RlOiBzcGxpdCBjb21waWxlIGludG8gc2VwYXJhdGUgamF2YWMgc3RlcHMgdG8gYXZvaWQgSkRLIDEuMS44IGJ1ZyByZXBvcnRlZCBhdDoKLSAgICAgICAgIGh0dHA6Ly9kZXZlbG9wZXIuamF2YS5zdW4uY29tL2RldmVsb3Blci9idWdQYXJhZGUvYnVncy80MDQzNTA4Lmh0bWwKLSAgICAgICAgIHdoaWNoIGNhdXNlcyBhbiBlcnJvciBsaWtlOgotICAgICAgICAgW2phdmFjXSBFOlxidWlsZHNceG1sLXhhbGFuXGphdmFcc3JjXG9yZ1xhcGFjaGVceGFsYW5cdGVtcGxhdGVzXEVsZW1UZW1wbGF0ZS5qYXZhOjEwODogQ3ljbGljIGNsYXNzIGluaGVyaXRhbmNlIG9yIHNjb3BpbmcuCi0gICAgLS0+IAotICAgIDwhLS0gQ29tcGlsZSBvdXIgY29weSBvZiBKQVhQIDEuMSBjbGFzc2VzIC0tPgotICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmRpcn0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLmNsYXNzZXN9IgotICAgICAgICAgICBpbmNsdWRlcz0iamF2YXgvKiovKi5qYXZhIgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8IS0tIENvbXBpbGUgb3VyIGNvcHkgb2YgRE9NIExldmVsIDIgZmluYWwgZHJhZnQsIFNBWCAyLjAgY2xhc3NlcyAtLT4KLSAgICA8amF2YWMgc3JjZGlyPSIke3NyYy5kaXJ9IiAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5jbGFzc2VzfSIKLSAgICAgICAgICAgaW5jbHVkZXM9Im9yZy93M2MvKiovKi5qYXZhLG9yZy94bWwvKiovKi5qYXZhIgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8IS0tIENvbXBpbGUgWFBhdGggZW5naW5lIGFuZCBzb21lIGNvbW1vbiB1dGlsaXRpZXMgLS0+Ci0gICAgPGphdmFjIHNyY2Rpcj0iJHtzcmMuZGlyfSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuY2xhc3Nlc30iCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIgPgotICAgICAgPGluY2x1ZGUgbmFtZT0ib3JnL2FwYWNoZS94bWwvKiovKi5qYXZhIiAvPgotICAgICAgPGluY2x1ZGUgbmFtZT0iJHt4cGF0aC5yZWxkaXJ9LyoqLyouamF2YSIgLz4KLSAgICAgIDxleGNsdWRlIG5hbWU9IioqL0Nvcm91dGluZVNBWEZpbHRlclRlc3QuamF2YSIgCi0gICAgICAgIHVubGVzcz0ieGVyY2VzLnByZXNlbnQiCSAvPgotICAgICAgPGV4Y2x1ZGUgbmFtZT0iKiovQ29yb3V0aW5lU0FYUGFyc2VyX1hlcmNlcy5qYXZhIiAKLSAgICAgICAgdW5sZXNzPSJ4ZXJjZXMucHJlc2VudCIJIC8+Ci0gICAgICA8ZXhjbHVkZSBuYW1lPSIqKi9JbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMuamF2YSIgCi0gICAgICAgIHVubGVzcz0ieGVyY2VzLnByZXNlbnQiCSAvPgotICAgIDwvamF2YWM+Ci0gICAgPCEtLSBDb21waWxlIFhhbGFuIG1haW4gZW5naW5lIChidXQgbm90IHhzbHRjIHBhY2thZ2UgeWV0KSAtLT4KLSAgICA8amF2YWMgc3JjZGlyPSIke3NyYy5kaXJ9IiAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5jbGFzc2VzfSIKLSAgICAgICAgICAgaW5jbHVkZXM9IiR7eGFsYW4ucmVsZGlyfS8qKi8qLmphdmEiCi0gICAgICAgICAgIGV4Y2x1ZGVzPSIke3hzbHRjLnJlbGRpcn0vKiovKi5qYXZhLCR7eGFsYW4ucmVsZGlyfS9saWIvKiovKi5qYXZhLCR7eGFsYW4ucmVsZGlyfS94c2x0LyoqLyouamF2YSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+Ci0gICAgPCEtLSBDb21waWxlIHZhcmlvdXMgWGFsYW4tc3BlY2lmaWMgZXh0ZW5zaW9ucyBhbmQgY29tbWFuZCBsaW5lIGNsYXNzIC0tPgotICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmRpcn0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLmNsYXNzZXN9IgotICAgICAgICAgICBpbmNsdWRlcz0iJHt4YWxhbi5yZWxkaXJ9L2xpYi8qKi8qLmphdmEsJHt4YWxhbi5yZWxkaXJ9L3hzbHQvKiovKi5qYXZhIgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8IS0tIENvcHkgbmVlZGVkIHByb3BlcnRpZXMsIHJlc291cmNlLCBldGMuIGZpbGVzIHRvIGJlIHB1dCBpbnRvIC5qYXIgZmlsZSAtLT4KLSAgICA8Y29weSB0b2Rpcj0iJHtidWlsZC5jbGFzc2VzfSI+Ci0gICAgICAgICAgPGZpbGVzZXQgZGlyPSIke3NyYy5kaXJ9IiBpbmNsdWRlcz0iKiovKi5wcm9wZXJ0aWVzLCoqLyoucmVzLCoqL2phdmF4LnhtbC5wYXJzZXJzLiosKiovamF2YXgueG1sLnRyYW5zZm9ybS4qIi8+Ci0gICAgICAgIDwvY29weT4gIAotICA8L3RhcmdldD4KLQotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gQ29tcGlsZSBqdXN0IHRoZSBYU0xUQyBjb21waWxlciBwb3J0aW9uICh0byBiZSBpbnRlZ3JhdGVkIHNvb24hKSAtLT4KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8cGF0aCBpZD0ieHNsdGMuY2xhc3MucGF0aCI+Ci0gICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke0JDRUwuamFyfSIgLz4KLSAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7SkxleC5qYXJ9IiAvPgotICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtqYXZhX2N1cC5qYXJ9IiAvPgotICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtydW50aW1lLmphcn0iIC8+Ci0gICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke3htbC5qYXJ9IiAvPgotICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtjcmltc29uLmphcn0iIC8+Ci0gICAgPCEtLSBidWlsZC5jbGFzc2VzIG5lZWRlZCBmb3IgCi0gICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWwuSmF2YUN1cFJlZGlyZWN0IC0tPgotICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtidWlsZC5jbGFzc2VzfSIgLz4KLSAgICA8cGF0aGVsZW1lbnQgcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9IiAvPgotICA8L3BhdGg+Ci0gIDwhLS0gVGhlIHhzbHRjLmNvbXBpbGUgdGFyZ2V0IHNob3VsZCBiZSByZXdyaXR0ZW4gdG8gcHJvcGVybHkgCi0gICAgICAgZG8gZGVwZW5kZW5jaWVzIG9uIHRoZSBnZW5lcmF0ZWQgc291cmNlczogcmlnaHQgbm93LCBpdCAKLSAgICAgICB3aWxsIGFsd2F5cyByZWdlbmVyYXRlIHRoZSBzb3VyY2VzLCBldmVuIGlmIGl0J3Mgbm90IG5lZWRlZAotICAgICAgICh3aGljaCBmb3JjZXMgYWxsIGxhdGVyIHN0ZXBzIHRvIHJlLXJ1biBhcyB3ZWxsKSAtLT4KLSAgPHRhcmdldCBuYW1lPSJ4c2x0Yy5jb21waWxlIiBkZXBlbmRzPSJwcmVwYXJlIgotICAgIGRlc2NyaXB0aW9uPSJDb21waWxlIGp1c3QgdGhlIFhTTFRDIGNsYXNzZXMiID4KLQotICAgIDwhLS0gVGhlIGZpcnN0IHN0ZXAgY29tcGlsZXMgdGhlIHV0aWxzIGRpcmVjdHByeSwgd2hpY2ggaW5jbHVkZXMgCi0gICAgICAgICBhIHNwZWNpYWwgd3JhcHBlciBmb3IgdGhlIGphdmFfY3VwIHN0ZXAgbmV4dC4gLS0+Ci0gICAgPGVjaG8gbWVzc2FnZT0iQ29tcGlsaW5nIFhTTFRDIHV0aWxpdGllcyIvPgotICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmRpcn0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLmNsYXNzZXN9IgotICAgICAgICAgICBpbmNsdWRlcz0iJHt4c2x0Yy5yZWxkaXJ9L3V0aWwvKiovKi5qYXZhIgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iPgotICAgICAgPGNsYXNzcGF0aCByZWZpZD0ieHNsdGMuY2xhc3MucGF0aCIgLz4KLSAgICA8L2phdmFjPgotICAgIDwhLS0gVGhlIHNlY29uZCBzdGVwIGdlbmVyYXRlcyBzeW0uamF2YSBhbmQgWFBhdGhQYXJzZXIuamF2YSwgYW5kIHRoZQotICAgIGxhc3Qgb25lIGdlbmVyYXRlcyBYUGF0aExleGVyLmphdmEuIFRoZSBsZXhpb2dyYXBoaWNhbCBhbmFseXNlcgotICAgIGhhcyB0byBiZSBnZW5lcmF0ZWQgYWZ0ZXIgc3ltLmphdmEsIHNvIG9yZGVyIGlzIGltcG9ydGFudC4gLS0+Ci0gICAgPGVjaG8gbWVzc2FnZT0iamF2YV9jdXAgcHJlcGFyc2luZyIvPgotICAgIDxqYXZhIGZvcms9Im5vIiBmYWlsb25lcnJvcj0idHJ1ZSIgY2xhc3NuYW1lPSJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWwuSmF2YUN1cFJlZGlyZWN0IiA+Ci0gICAgICA8Y2xhc3NwYXRoIHJlZmlkPSJ4c2x0Yy5jbGFzcy5wYXRoIiAvPgotICAgICAgPCEtLSBXZSdyZSB1c2luZyBKYXZhQ3VwUmVkaXJlY3QgdG8gY2FsbCB0aGUgamF2YV9jdXAgYXBwbGljYXRpb24gLS0+Ci0gICAgICA8YXJnIGxpbmU9Ii1wYXJzZXIgWFBhdGhQYXJzZXIgLWV4cGVjdCAwIC1zdGRpbiAke3NyYy5kaXJ9LyR7eHNsdGMucmVsZGlyfS9jb21waWxlci94cGF0aC5jdXAiLz4KLSAgICA8L2phdmE+Ci0gICAgPGVjaG8gbWVzc2FnZT0iamF2YV9jdXAgbW92ZSBvdXRwdXQgZmlsZXMiLz4KLSAgICA8bW92ZSBmaWxlPSJYUGF0aFBhcnNlci5qYXZhIiB0b2ZpbGU9IiR7c3JjLmRpcn0vJHt4c2x0Yy5yZWxkaXJ9L2NvbXBpbGVyL1hQYXRoUGFyc2VyLmphdmEiLz4KLSAgICA8bW92ZSBmaWxlPSJzeW0uamF2YSIgdG9maWxlPSIke3NyYy5kaXJ9LyR7eHNsdGMucmVsZGlyfS9jb21waWxlci9zeW0uamF2YSIvPgotCi0gICAgPGVjaG8gbWVzc2FnZT0iSkxleCBwcmVwYXJzaW5nIi8+Ci0gICAgPGphdmEgZm9yaz0ibm8iIGZhaWxvbmVycm9yPSJ0cnVlIiBjbGFzc25hbWU9IkpMZXguTWFpbiIgPgotICAgICAgPGNsYXNzcGF0aCByZWZpZD0ieHNsdGMuY2xhc3MucGF0aCIgLz4KLSAgICAgIDxhcmcgbGluZT0iLXN0YXRpYyAke3NyYy5kaXJ9LyR7eHNsdGMucmVsZGlyfS9jb21waWxlci94cGF0aC5sZXgiLz4KLSAgICA8L2phdmE+Ci0gICAgPGVjaG8gbWVzc2FnZT0iSkxleCBtb3ZlIG91dHB1dCBmaWxlIi8+Ci0gICAgPG1vdmUgZmlsZT0iJHtzcmMuZGlyfS8ke3hzbHRjLnJlbGRpcn0vY29tcGlsZXIveHBhdGgubGV4LmphdmEiIHRvZmlsZT0iJHtzcmMuZGlyfS8ke3hzbHRjLnJlbGRpcn0vY29tcGlsZXIvWFBhdGhMZXhlci5qYXZhIi8+Ci0KLSAgICA8ZWNobyBtZXNzYWdlPSJDb21waWxpbmcgcmVtYWluaW5nIFhTTFRDIGNsYXNzZXMiLz4KLSAgICA8amF2YWMgc3JjZGlyPSIke3NyYy5kaXJ9IiAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5jbGFzc2VzfSIKLSAgICAgICAgICAgaW5jbHVkZXM9IiR7eHNsdGMucmVsZGlyfS8qKi8qLmphdmEiCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSI+Ci0gICAgICA8Y2xhc3NwYXRoIHJlZmlkPSJ4c2x0Yy5jbGFzcy5wYXRoIiAvPgotICAgIDwvamF2YWM+Ci0gIDwvdGFyZ2V0PgotICA8dGFyZ2V0IG5hbWU9InhzbHRjLmphciIgZGVwZW5kcz0ieHNsdGMuY29tcGlsZSIKLSAgICBkZXNjcmlwdGlvbj0iSmFyIGp1c3QgdGhlIHhzbHRjLmphciBmaWxlIiA+Ci0gICAgPGphciBqYXJmaWxlPSIke2J1aWxkLnhzbHRjLmphcn0iIGJhc2VkaXI9IiR7YnVpbGQuY2xhc3Nlc30iID4KLSAgICAgIDxwYXR0ZXJuc2V0PjwhLS0gcmVsYXRpdmUgdG8gamFyL0BiYXNlZGlyIC0tPgotICAgICAgICA8aW5jbHVkZSBuYW1lPSIke3hzbHRjLnJlbGRpcn0vKiovKiIgLz4KLSAgICAgIDwvcGF0dGVybnNldD4KLSAgICA8L2phcj4KLSAgPC90YXJnZXQ+Ci0gIAotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gQ3JlYXRlcyB0aGUgeGFsYW4gSkFSICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8dGFyZ2V0IG5hbWU9ImphciIgZGVwZW5kcz0iY29tcGlsZSIKLSAgICBkZXNjcmlwdGlvbj0iSmFyIHVwIHhhbGFuLmphciIgPgotICAgIDxqYXIgamFyZmlsZT0iJHtidWlsZC54YWxhbi5qYXJ9IiBtYW5pZmVzdD0ic3JjXE1BTklGRVNULk1GIiBiYXNlZGlyPSIke2J1aWxkLmNsYXNzZXN9IiA+Ci0gICAgICA8cGF0dGVybnNldD48IS0tIHJlbGF0aXZlIHRvIGphci9AYmFzZWRpciAtLT4KLSAgICAgICAgPGV4Y2x1ZGUgbmFtZT0iJHt4c2x0Yy5yZWxkaXJ9LyoqLyoiIC8+Ci0gICAgICAgIDxleGNsdWRlIG5hbWU9ImphdmF4L3htbC9wYXJzZXJzLyoqIiAvPgotICAgICAgICA8ZXhjbHVkZSBuYW1lPSJNRVRBLUlORi9zZXJ2aWNlcy9qYXZheC54bWwucGFyc2VycyoiIC8+Ci0gICAgICA8L3BhdHRlcm5zZXQ+Ci0gICAgPC9qYXI+Ci0gIDwvdGFyZ2V0PgotICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIERlZmF1bHQgYWxsIHRhcmdldCBzaW1wbHkgQ3JlYXRlcyB0aGUgeGFsYW4gSkFSICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJhbGwiIGRlcGVuZHM9ImphciI+PCEtLSAnU3RhbmRhcmRpemluZyBidWlsZC54bWwgZmlsZXMnIDxibG9yaXRzY2hAYXBhY2hlLm9yZz4gLS0+Ci0gICAgPGVjaG8gbWVzc2FnZT0iUmVkaXJlY3QgdG8gamFyIHRhcmdldDsgcGxlYXNlIHByb3ZpZGUgaW5wdXQgb24gZGVzaXJlZCBmdW5jdGlvbmFsaXR5IG9mIHRoaXMgdGFyZ2V0Ii8+Ci0gIDwvdGFyZ2V0PgotICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENyZWF0ZXMgdGhlIFhhbGFuLUoxIGNvbXBhdGFiaWxpdHkgSkFSICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJjb21wYXQuamFyIiBkZXBlbmRzPSJqYXIiCi0gICAgZGVzY3JpcHRpb249IkNvbXBpbGUgYW5kIGphciBYYWxhbi1KIDEueCBiYWNrd2FyZHMgY29tcGF0IGNsYXNzZXMiID4KLSAgICA8ZWNobyBtZXNzYWdlPSJDb21waWxlIGFuZCBqYXIganVzdCB0aGUgWGFsYW4tSiAxIGNvbXBhYmlsaXR5IEFQSSIvPgotICAgIDxta2RpciBkaXI9IiR7YnVpbGQuY29tcGF0LmNsYXNzZXN9Ii8+Ci0gICAgPGphdmFjIHNyY2Rpcj0iJHtjb21wYXQuc3JjLmRpcn0iIGNsYXNzcGF0aD0iJHtidWlsZC54YWxhbi5qYXJ9OiR7amF2YS5jbGFzcy5wYXRofSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuY29tcGF0LmNsYXNzZXN9IgotICAgICAgICAgICBpbmNsdWRlcz0iKiovKi5qYXZhIgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8Y29weSB0b2Rpcj0iJHtidWlsZC5jb21wYXQuY2xhc3Nlc30iPgotICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wYXQuc3JjLmRpcn0iIGluY2x1ZGVzPSIqKi8qLnByb3BlcnRpZXMsKiovKi5yZXMiLz4KLSAgICA8L2NvcHk+ICAKLSAgICA8amFyIGphcmZpbGU9IiR7YnVpbGQuY29tcGF0Lmphcn0iIG1hbmlmZXN0PSJzcmNcTUFOSUZFU1QuTUYiIGJhc2VkaXI9IiR7YnVpbGQuY29tcGF0LmNsYXNzZXN9Ii8+Ci0gIDwvdGFyZ2V0PgotICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENyZWF0ZXMgdGhlIFhhbGFuLUoxIGNvbXBhdGFiaWxpdHkgamF2YWRvYyAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJjb21wYXQuamF2YWRvY3MiIGRlcGVuZHM9ImphciIKLSAgICBkZXNjcmlwdGlvbj0iQnVpbGQgamF2YWRvY3MgZm9yIFhhbGFuLUogMS54IGJhY2t3YXJkcyBjb21wYXQgY2xhc3NlcyIgPgotICAgIDxta2RpciBkaXI9IiR7YnVpbGQuY29tcGF0LmFwaWRvY3N9Ii8+Ci0gICAgPGphdmFkb2MKLSAgICAgICAgIHB1YmxpYz0idHJ1ZSIKLSAgICAgICAgIHNvdXJjZXBhdGg9IiR7Y29tcGF0LnNyYy5kaXJ9IgotICAgICAgICAgb3ZlcnZpZXc9IiR7Y29tcGF0LnNyYy5kaXJ9L2NvbXBhdE92ZXJ2aWV3Lmh0bWwiICAgICAgICAgCi0gICAgICAgICBwYWNrYWdlbmFtZXM9Im9yZy5hcGFjaGUueGFsYW4ueHNsdCxvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sIgotICAgICAgICAgYXV0aG9yPSJ0cnVlIgotICAgICAgICAgdmVyc2lvbj0idHJ1ZSIKLSAgICAgICAgIHVzZT0idHJ1ZSIKLSAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuY29tcGF0LmFwaWRvY3N9IgotICAgICAgICAgd2luZG93dGl0bGU9IiR7TmFtZX0gMSBDb21wYXRhYmlsaXR5IiAKLSAgICAgICAgIGRvY3RpdGxlPSIke05hbWV9IDEgQ29tcGF0YWJpbGl0eSIKLSAgICAgICAgIGJvdHRvbT0iQ29weXJpZ2h0ICYjMTY5OyAke3llYXJ9IEFwYWNoZSBYTUwgUHJvamVjdC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4iPgotICAgICAgPGNsYXNzcGF0aCByZWZpZD0iZG9jcy5jbGFzcy5wYXRoIiAvPgotICAgIDwvamF2YWRvYz4KLSAgPC90YXJnZXQ+Ci0gICAgCi0KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENvbXBpbGVzIHRoZSBzYW1wbGVzIChzZXJ2bGV0IGV4Y2x1ZGVkKSBhbmQgamFycyB0aGUgY2xhc3MgZmlsZXMgICAgLS0+ICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8dGFyZ2V0IG5hbWU9InNhbXBsZXMiIGRlcGVuZHM9ImphciIKLSAgICBkZXNjcmlwdGlvbj0iQ29tcGlsZSBhbmQgamFyIHRoZSBzYW1wbGVzIChleGNlcHQgc2VydmxldCkiID4KLSAgICA8cHJvcGVydHkgbmFtZT0iZXhjbHVkZSIgdmFsdWU9IioueG1sLCoueHNsLCoudHh0LCouaHRtbCwqLnByb3BlcnRpZXMsKi5vdXQiLz4KLSAgICA8bWtkaXIgZGlyPSIke2J1aWxkLnNhbXBsZXN9Ii8+Ci0gICAgPCEtLSBTaW5jZSB0aGUgc2FtcGxlcyBhcmUgcGFja2FnZWxlc3MsIHRoZXkgbXVzdCBiZSBjb21waWxlZCBzZXBhcmF0ZWx5LiAtLT4gICAKLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXMuZGlyfS9TaW1wbGVUcmFuc2Zvcm0iIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuc2FtcGxlc30iICBleGNsdWRlcz0iJHtleGNsdWRlfSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+Ci0gICAgPGphdmFjIHNyY2Rpcj0iJHtzYW1wbGVzLmRpcn0vVXNlU3R5bGVzaGVldFBJIiBjbGFzc3BhdGg9IiR7amF2YS5jbGFzcy5wYXRofToke2J1aWxkLnhhbGFuLmphcn0iICAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5zYW1wbGVzfSIgIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXMuZGlyfS9Vc2VTdHlsZXNoZWV0UGFyYW0iIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfSIKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5zYW1wbGVzfSIgIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4gICAgICAgICAgIAotICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlcy5kaXJ9L1NBWDJTQVgiIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuc2FtcGxlc30iICBleGNsdWRlcz0iJHtleGNsdWRlfSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+ICAgICAgICAgICAKLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXMuZGlyfS9ET00yRE9NIiBjbGFzc3BhdGg9IiR7amF2YS5jbGFzcy5wYXRofToke2J1aWxkLnhhbGFuLmphcn0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLnNhbXBsZXN9IiAgZXhjbHVkZXM9IiR7ZXhjbHVkZX0iCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIvPgotICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlcy5kaXJ9L1BpcGUiIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuc2FtcGxlc30iICBleGNsdWRlcz0iJHtleGNsdWRlfSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+ICAgICAgICAgICAKLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXMuZGlyfS9Vc2VYTUxGaWx0ZXJzIiBjbGFzc3BhdGg9IiR7amF2YS5jbGFzcy5wYXRofToke2J1aWxkLnhhbGFuLmphcn0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLnNhbXBsZXN9IiAgZXhjbHVkZXM9IiR7ZXhjbHVkZX0iCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIvPgotICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlcy5kaXJ9L1RyYWNlIiBjbGFzc3BhdGg9IiR7amF2YS5jbGFzcy5wYXRofToke2J1aWxkLnhhbGFuLmphcn0iICAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5zYW1wbGVzfSIgIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlcy5kaXJ9L0FwcGx5WFBhdGgiIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfSIgCi0gICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5zYW1wbGVzfSIgZXhjbHVkZXM9IiR7ZXhjbHVkZX0iIAotICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIvPgotICAgPGphdmFjIHNyY2Rpcj0iJHtzYW1wbGVzLmRpcn0vdHJheCIgY2xhc3NwYXRoPSIke2phdmEuY2xhc3MucGF0aH06JHtidWlsZC54YWxhbi5qYXJ9IiAKLSAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLnNhbXBsZXN9IiBleGNsdWRlcz0iJHtleGNsdWRlfSIgCi0gICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+Ci0gICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXMuZGlyfS9leHRlbnNpb25zIiBjbGFzc3BhdGg9IiR7amF2YS5jbGFzcy5wYXRofToke2J1aWxkLnhhbGFuLmphcn0iIAotICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuc2FtcGxlc30iIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IiAKLSAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4gCi0gICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXMuZGlyfS9WYWxpZGF0ZSIgY2xhc3NwYXRoPSIke2phdmEuY2xhc3MucGF0aH06JHtidWlsZC54YWxhbi5qYXJ9IiAKLSAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLnNhbXBsZXN9IiBleGNsdWRlcz0iJHtleGNsdWRlfSIgCi0gICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+ICAgICAgICAgICAgICAgCi0gICAgPGphciBqYXJmaWxlPSIke2J1aWxkLnNhbXBsZXMuamFyfSIgYmFzZWRpcj0iJHtidWlsZC5zYW1wbGVzfSIKLSAgICAgICAgIGluY2x1ZGVzPSIqLmNsYXNzIi8+ICAgICAgICAgICAgICAgICAgIAotICA8L3RhcmdldD4KLSAgIAotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gQ29tcGlsZXMgdGhlIHNhbXBsZSBzZXJ2bGV0IGFuZCBqYXJzIHRoZSBjbGFzcyBmaWxlcy4gICAgICAgICAgICAgICAgLS0+ICAKLSAgPCEtLSBUaGUgamF2YXguc2VydmxldCBhbmQgamF2YXguc2VydmxldC5odHRwIHBhY2thZ2VzICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSBtdXN0IGJlIG9uIHRoZSBjbGFzc3BhdGggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotIDx0YXJnZXQgbmFtZT0ic2VydmxldCIgZGVwZW5kcz0iamFyIgotICAgIGRlc2NyaXB0aW9uPSJDb21waWxlIGFuZCBqYXIgdGhlIHNlcnZsZXQgc2FtcGxlcyIgPgotICAgICA8ZWNobyBtZXNzYWdlPSJUbyBjb21waWxlIHRoZSBzYW1wbGUgc2VydmxldHMsIGphdmF4LnNlcnZsZXQgYW5kIGphdmF4LnNlcnZsZXQuaHR0cCBtdXN0IGJlIG9uIHRoZSBjbGFzc3BhdGgiLz4gICAKLSAgICAgPG1rZGlyIGRpcj0iJHtidWlsZC5zYW1wbGVzfS9zZXJ2bGV0Ii8+Ci0gICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlcy5kaXJ9L3NlcnZsZXQiIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuc2FtcGxlc30iCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIvPgotICAgICAgPGNvcHkgdG9kaXI9IiR7YnVpbGQuc2FtcGxlc30vc2VydmxldCI+Ci0gICAgICAgICAgPGZpbGVzZXQgZGlyPSIke3NhbXBsZXMuZGlyfS9zZXJ2bGV0IiAKLSAgICAgICAgICAgICAgICBpbmNsdWRlcz0ibWVkaWEucHJvcGVydGllcyxkZWZhdWx0LnhzbCxkZWZhdWx0Mi54c2wiLz4KLSAgICAgICAgPC9jb3B5PiAgCQkgICAgICAgICAKLSAgICA8amFyIGphcmZpbGU9IiR7YnVpbGQuc2VydmxldC5qYXJ9IiAKLSAgICAgICAgIGJhc2VkaXI9IiR7YnVpbGQuc2FtcGxlc30iIAotICAgICAgICAgaW5jbHVkZXM9InNlcnZsZXQvKioiLz4KLSA8L3RhcmdldD4KLSAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENvbXBpbGVzIChkb2VzIG5vdCBqYXIpIHRoZSB0cmFuc2xldCBzYW1wbGVzIGluIHRyYW5zbGV0cy4gICAgICAgICAgLS0+Ci0gIDwhLS0gRm9yIHRpbWUgYmVpbmcsIGNsYXNzZXMgYXJlIGdlbmVyYXRlZCBpbiBwbGFjZS4gICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSBUbyBydW4gdGhlc2Ugc2FtcGxlcywgYWRkIHhzbHRjLmphciwgcnVudGltZS5qYXIsIEJDRUwuamFyLCAgICAgICAgIC0tPgotICA8IS0tIGFuZCBqYXZhX2N1cC5qYXIgKGFsbCBpbiB0aGUgYmluIGRpcmVjdG9yeSkgdG8gdGhlIGNsYXNzcGF0aCAgICAgICAgLS0+IAotICA8IS0tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gV2hlbiB3ZSBoYXZlIHN0cmFpZ2h0ZW5lZCBvdXQgY2xhc3NwYXRoIGlzc3VlcywgICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSBhZGQgc2FtcGxlcyBpbiBDb21waWxlZEFwcGxldCwgQ29tcGlsZWRCcmF6aWwsIGFuZCBDb21waWxlZFNlcnZsZXQgIC0tPgotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDx0YXJnZXQgbmFtZT0ieHNsdGMuc2FtcGxlcyIgZGVwZW5kcz0iamFyLHhzbHRjLmphciI+Ci0gICAgPGphdmFjIHNyY2Rpcj0iJHtzYW1wbGVzLmRpcn0vdHJhbnNsZXRzIiBjbGFzc3BhdGg9IiR7amF2YS5jbGFzcy5wYXRofToke2J1aWxkLnhzbHRjLmphcn0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke3NhbXBsZXMuZGlyfS90cmFuc2xldHMiIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IiAKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+ICAKLSAgPC90YXJnZXQ+Ci0gCi0gCi0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPCEtLSBHZW5lcmF0ZSBIVE1MIGRvY3MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDx0YXJnZXQgbmFtZT0iZG9jcyIgZGVwZW5kcz0iamFyLHByZXBhcmUuZG9jcyxhdXRvZG9jcyIKLSAgICBkZXNjcmlwdGlvbj0iQnVpbGQgdGhlIGRvY3VtZW50YXRpb24gKG92ZXJ2aWV3LCByZWFkbWUsIGV0Yy4pIiA+Ci0gICAgPGVjaG8gbWVzc2FnZT0iZG9jcyBpcyBodW1hbi11c2FibGUgdGFyZ2V0IHdpdGggZGVwZW5kZW5jaWVzIi8+ICAKLSAgPC90YXJnZXQ+Ci0gIAotICA8dGFyZ2V0IG5hbWU9ImF1dG9kb2NzIj4KLSAgICA8ZWNobyBtZXNzYWdlPSJhdXRvZG9jcyBpcyBmb3IgYXV0b21hdGVkIGJ1aWxkIHByb2Nlc3MsIHdpdGhvdXQgZGVwZW5kZW5jaWVzIi8+ICAgCi0gICAgPGphdmEgZm9yaz0ieWVzIiAKLSAgICAgICAgICBjbGFzc25hbWU9IiR7ZG9jLmdlbmVyYXRvcn0iIAotICAgICAgICAgIGNsYXNzcGF0aHJlZj0iZG9jcy5jbGFzcy5wYXRoIiA+Ci0gICAgICAgPGFyZyBsaW5lPSJ0YXJnZXREaXJlY3Rvcnk9JHtidWlsZC5kb2NzfSAke3hkb2NzLmJvb2t9ICR7eGRvY3Muc3R5bGV9Ii8+Ci0gICAgPC9qYXZhPgkgCi0gIDwvdGFyZ2V0PgotICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENyZWF0ZXMgdGhlIEFQSSBkb2N1bWVudGF0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJqYXZhZG9jcyIgZGVwZW5kcz0iamFyLHByZXBhcmUuZG9jcyxhdXRvamF2YWRvY3MiCi0gICAgZGVzY3JpcHRpb249IkJ1aWxkIHRoZSBKYXZhZG9jcyBmb3IgWGFsYW4gMi54IHNvdXJjZXMiID4KLSAgICA8ZWNobyBtZXNzYWdlPSJqYXZhZG9jcyBpcyBodW1hbi11c2FibGUgdGFyZ2V0IHdpdGggZGVwZW5kZW5jaWVzIi8+ICAKLSAgPC90YXJnZXQ+Ci0KLSAgPHRhcmdldCBuYW1lPSJhdXRvamF2YWRvY3MiPgotICAgIDxlY2hvIG1lc3NhZ2U9ImF1dG9qYXZhZG9jcyBpcyBmb3IgYXV0b21hdGVkIGJ1aWxkIHByb2Nlc3MsIHdpdGhvdXQgZGVwZW5kZW5jaWVzIi8+ICAgIAotICAgIAotICAgIDwhLS0gQW50IGlnbm9yZXMgZGVzdGRpciBhcmcgaWYgZG9jbGV0IGlzIHNldCwgc28gbXVzdCBzZW5kIHRvIGRvY2xldCBpbiBkb2NsZXQgc3ViZWxlbWVudC0tPgotICAgIDxqYXZhZG9jCi0gICAgICAgICBwdWJsaWM9InRydWUiCi0gICAgICAgICBzb3VyY2VwYXRoPSIke3NyYy5kaXJ9IgotICAgICAgICAgb3ZlcnZpZXc9IiR7c3JjLmRpcn0vamF2YWRvY092ZXJ2aWV3Lmh0bWwiCi0gICAgICAgICBwYWNrYWdlbmFtZXM9Im9yZy5hcGFjaGUuKixvcmcueG1sLiosb3JnLnczYy4qLGphdmF4LnhtbC4qIgotICAgICAgICAgYXV0aG9yPSJ0cnVlIgotICAgICAgICAgdmVyc2lvbj0idHJ1ZSIKLSAgICAgICAgIHVzZT0idHJ1ZSIKLSAgICAgICAgIHdpbmRvd3RpdGxlPSIke05hbWV9IDIiIAotICAgICAgICAgZG9jdGl0bGU9IiR7TmFtZX0gMiIKLSAgICAgICAgIGJvdHRvbT0iQ29weXJpZ2h0ICYjMTY5OyAke3llYXJ9IEFwYWNoZSBYTUwgUHJvamVjdC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4iPgotICAgICAgICAgIDxjbGFzc3BhdGggcmVmaWQ9ImRvY3MuY2xhc3MucGF0aCIgLz4KLSAgICAgICAgICA8ZG9jbGV0IG5hbWU9InhhbGFuamRvYy5TdGFuZGFyZCIgcGF0aD0iJHtkb2NsZXQuamFyLm5hbWV9Ij4KLSAgICAgICAgICAgIDxwYXJhbSBuYW1lPSItZCIgdmFsdWU9IiR7YnVpbGQuYXBpZG9jc30iLz4KLSAgICAgICAgICA8L2RvY2xldD4KLSAgICAgICAgICA8Z3JvdXAgdGl0bGU9IlRyYW5zZm9ybWF0aW9ucyBBUEkgZm9yIFhNTCAoVHJBWCkiIHBhY2thZ2VzPSJqYXZheC54bWwudHJhbnNmb3JtKiIvPgotICAgICAgICAgIDxncm91cCB0aXRsZT0iSmF2YSBBUEkgZm9yIFhNTCBQYXJzaW5nIiBwYWNrYWdlcz0iamF2YXgueG1sLnBhcnNlcnMiLz4KLSAgICAgICAgICA8Z3JvdXAgdGl0bGU9IlhhbGFuIENvcmUiCi0gICAgICAgICAgICAgICAgIHBhY2thZ2VzPSJvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjpvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczpvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyIi8+Ci0gICAgICAgICAgPGdyb3VwIHRpdGxlPSJYUGF0aCIgcGFja2FnZXM9Im9yZy5hcGFjaGUueHBhdGgqIi8+Ci0gICAgICAgICAgPGdyb3VwIHRpdGxlPSJEb2N1bWVudCBUYWJsZSBNb2RlbCAoRFRNKSIgcGFja2FnZXM9Im9yZy5hcGFjaGUueG1sLmR0bSoiLz4gICAgICAgICAgCi0gICAgICAgICAgPGdyb3VwIHRpdGxlPSJVdGlsaXRpZXMiIHBhY2thZ2VzPSJvcmcuYXBhY2hlLnhtbC51dGlscyoiLz4KLSAgICAgICAgICA8Z3JvdXAgdGl0bGU9IlhhbGFuIE90aGVyIiBwYWNrYWdlcz0ib3JnLmFwYWNoZS54YWxhbi5jbGllbnQ6b3JnOm9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczpvcmcuYXBhY2hlLnhhbGFuLnJlczpvcmcuYXBhY2hlLnhhbGFuLnN0cmVlOm9yZy5hcGFjaGUueGFsYW4udHJhY2U6b3JnLmFwYWNoZS54YWxhbi54c2x0Ii8+Ci0gICAgICAgICAgPGdyb3VwIHRpdGxlPSJYYWxhbiBFeHRlbnNpb25zIiBwYWNrYWdlcz0ib3JnLmFwYWNoZS54YWxhbi5saWIqIi8+Ci0gICAgICAgICAgPGdyb3VwIHRpdGxlPSJTZXJpYWxpemVycyIgcGFja2FnZXM9Im9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplIi8+Ci0gICAgICAgICAgPGdyb3VwIHRpdGxlPSJTQVggMiIgcGFja2FnZXM9Im9yZy54bWwuc2F4KiIvPgotICAgICAgICAgIDxncm91cCB0aXRsZT0iRE9NIDIiIHBhY2thZ2VzPSJvcmcudzNjLmRvbSoiLz4KLSAgICAgICAgICA8Z3JvdXAgdGl0bGU9IlhTTFRDIENvcmUiCi0gICAgICAgICAgICAgICAgIHBhY2thZ2VzPSJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjKiIvPgotICAgIDwvamF2YWRvYz4KLSAgICAKLSAgPC90YXJnZXQ+Ci0KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIFZhcmlvdXMgdGFyZ2V0cyB0byBjbGVhbiB0aGUgYnVpbGQgdHJlZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJkaXN0Y2xlYW4iIGRlcGVuZHM9ImNsZWFuIgotICAgIGRlc2NyaXB0aW9uPSJDbGVhbiBldmVyeXRoaW5nLCBpbmNsdWRpbmcgZGlzdC9qYXIvZG9jcy94c2x0Yy4qIiA+Ci0gICAgPGRlbGV0ZSBkaXI9IiR7ZGlzdC5kaXJ9Ii8+Ci0gIDwvdGFyZ2V0PgotCi0gIDx0YXJnZXQgbmFtZT0iY2xlYW4iIGRlcGVuZHM9InhzbHRjLmNsZWFuIgotICAgIGRlc2NyaXB0aW9uPSJDbGVhbiB0aGUgJHtidWlsZC5kaXJ9IHRyZWUgYW5kIGRvYyBvdXRwdXRzIiA+Ci0gICAgPGRlbGV0ZSBkaXI9IiR7YnVpbGQuZGlyfSIvPgotICAgIDxkZWxldGUgZGlyPSIke3NpdGUucm9vdH0iLz4KLSAgICA8ZGVsZXRlPgotICAgICAgPGZpbGVzZXQgZGlyPSIke3hkb2NzLnN0eWxlfSIgZXhjbHVkZXM9IiR7eGFsYW5vbmx5LXN0eWxlZG9jc30iLz4KLSAgICA8L2RlbGV0ZT4KLSAgICA8ZGVsZXRlIGZpbGU9IiR7eGRvY3MuRE9ORS5maWxlfSIvPgotICA8L3RhcmdldD4KLSAKLSAgPHRhcmdldCBuYW1lPSJ4c2x0Yy5jbGVhbiIKLSAgICBkZXNjcmlwdGlvbj0iQ2xlYW4gbWlzY2VsbGFuZW91cyBnZW5lcmF0ZWQgc291cmNlcyBmcm9tIHhzbHRjLmNvbXBpbGUiID4KLSAgICA8ZGVsZXRlIGZpbGU9IiR7c3JjLmRpcn0vJHt4c2x0Yy5yZWxkaXJ9L2NvbXBpbGVyL1hQYXRoUGFyc2VyLmphdmEiIC8+Ci0gICAgPGRlbGV0ZSBmaWxlPSIke3NyYy5kaXJ9LyR7eHNsdGMucmVsZGlyfS9jb21waWxlci9zeW0uamF2YSIgLz4KLSAgICA8ZGVsZXRlIGZpbGU9IiR7c3JjLmRpcn0vJHt4c2x0Yy5yZWxkaXJ9L2NvbXBpbGVyL1hQYXRoTGV4ZXIuamF2YSIgLz4KLSAgPC90YXJnZXQ+Ci0KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIEluc3RhbGwvVW5pbnN0YWxsIHRhcmdldHMgLSBub3QgY3VycmVudGx5IGFwcGxpY2FibGUgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJpbnN0YWxsIj48IS0tICdTdGFuZGFyZGl6aW5nIGJ1aWxkLnhtbCBmaWxlcycgPGJsb3JpdHNjaEBhcGFjaGUub3JnPiAtLT4KLSAgICA8ZWNobyBtZXNzYWdlPSJpbnN0YWxsIHRhcmdldCBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCBpbiAke05hbWV9OyB0cnkgamFyIG9yIGRpc3QgaW5zdGVhZCIvPgotICA8L3RhcmdldD4KLSAgPHRhcmdldCBuYW1lPSJ1bmluc3RhbGwiPjwhLS0gJ1N0YW5kYXJkaXppbmcgYnVpbGQueG1sIGZpbGVzJyA8Ymxvcml0c2NoQGFwYWNoZS5vcmc+IC0tPgotICAgIDxlY2hvIG1lc3NhZ2U9InVuaW5zdGFsbCB0YXJnZXQgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQgaW4gJHtOYW1lfTsgdHJ5IGRpc3RjbGVhbiBpbnN0ZWFkIi8+Ci0gIDwvdGFyZ2V0PgotCi0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPCEtLSBDcmVhdGVzIHRoZSBkaXN0cmlidXRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDx0YXJnZXQgbmFtZT0iZGlzdCIgZGVwZW5kcz0iamFyLGRvY3MsamF2YWRvY3Msc2FtcGxlcyxzZXJ2bGV0LGNvbXBhdC5qYXIsY29tcGF0LmphdmFkb2NzLHhzbHRjLmphcix4c2x0Yy5kb2NzLGF1dG9kaXN0LHRvZG8iCi0gICAgZGVzY3JpcHRpb249IkNyZWF0ZSBhIC56aXAvLnRhci5neiBkaXN0cmlidXRpb24gbW9kdWxlIiA+Ci0gICAgPGVjaG8gbWVzc2FnZT0iZGlzdCBpcyBodW1hbi11c2VhYmxlIHRhcmdldCBmb3IgZGlzdHJpYnV0aW9uLCB3aXRoIGFsbCBkZXBlbmRlbmNpZXMiLz4KLSAgPC90YXJnZXQ+Ci0gIDx0YXJnZXQgbmFtZT0iYXV0b2Rpc3QiPgotICAgIDxlY2hvIG1lc3NhZ2U9ImF1dG9kaXN0IGlzIGZvciBhdXRvbWF0ZWQgYnVpbGQgcHJvY2Vzc2VzLCB3aXRob3V0IGRlcGVuZGVuY2llcyIvPgotICAgIDxta2RpciBkaXI9IiR7ZGlzdC5kaXJ9Ii8+Ci0gICAgPG1rZGlyIGRpcj0iJHtkaXN0LmRpcn0vYmluIi8+ICAgIAotICAgIDxta2RpciBkaXI9IiR7ZGlzdC5kaXJ9L3NyYyIvPgotICAgIDxta2RpciBkaXI9IiR7ZGlzdC5kaXJ9L2NvbXBhdF9zcmMiLz4gICAgCi0gICAgPG1rZGlyIGRpcj0iJHtkaXN0LmRpcn0veGRvY3MiLz4KLSAgICA8bWtkaXIgZGlyPSIke2Rpc3QuZGlyfS9kb2NzIi8+Ci0gICAgPG1rZGlyIGRpcj0iJHtkaXN0LmRpcn0vZG9jcy9hcGlkb2NzIi8+Ci0gICAgPG1rZGlyIGRpcj0iJHtkaXN0LmRpcn0vZG9jcy9jb21wYXRfYXBpZG9jcyIvPiAgICAKLSAgICA8bWtkaXIgZGlyPSIke2Rpc3QuZGlyfS9zYW1wbGVzIi8+Ci0gICAgICAgIAotICAgICAgICA8IS0tIENvcHkgYmluIGRpcmVjdG9yeSAtLT4KLSAgICA8Y29weSB0b2Rpcj0iJHtkaXN0LmRpcn0vYmluIj4KLSAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7YmluLmRpcn0iLz4KLSAgICAgICAgPC9jb3B5PiAgCi0KLSAgICA8IS0tIENvcHkgc291cmNlcyBhbmQgc291cmNlIGRvY3VtZW50YXRpb24gLS0+Ci0gICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L3NyYyI+Ci0gICAgICA8ZmlsZXNldCBkaXI9IiR7c3JjLmRpcn0iLz4KLSAgICA8L2NvcHk+Ci0gICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L2NvbXBhdF9zcmMiPgotICAgICAgPGZpbGVzZXQgZGlyPSIke2NvbXBhdC5zcmMuZGlyfSIvPgotICAgIDwvY29weT4gICAgCi0gICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L3hkb2NzIj4KLSAgICAgIDxmaWxlc2V0IGRpcj0iJHt4ZG9jcy5kaXJ9Ii8+Ci0gICAgPC9jb3B5PgotICAgIAotICAgIDwhLS0gQ29weSBidWlsdCBkb2N1bWVudGF0aW9uIGFuZCBqYXZhZG9jLCBhbmQgc2FtcGxlcyBzcmMgYW5kIGphcnMgLS0+Ci0gICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L2RvY3MiPgotICAgICAgPGZpbGVzZXQgZGlyPSIke2J1aWxkLmRvY3N9Ii8+Ci0gICAgPC9jb3B5PiAgCi0gICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L3NhbXBsZXMiPgotICAgICAgPGZpbGVzZXQgZGlyPSIke3NhbXBsZXMuZGlyfSIvPgotICAgIDwvY29weT4gICAKLSAgICA8Y29weSBmaWxlPSIke2J1aWxkLmRpcn0veGFsYW5zYW1wbGVzLmphciIgdG9kaXI9IiR7ZGlzdC5kaXJ9L2JpbiIvPgotICAgIDxjb3B5IGZpbGU9IiR7YnVpbGQuZGlyfS94YWxhbnNlcnZsZXQuamFyIiB0b2Rpcj0iJHtkaXN0LmRpcn0vYmluIi8+Ci0KLSAgICA8IS0tIENvcHkgdmFyaW91cyBidWlsdCAuamFyIGZpbGVzIGludG8gdGhlIGJpbiBkaXJlY3RvcnkgKHN1YmplY3QgdG8gY2hhbmdlKSAtLT4KLSAgICA8Y29weSBmaWxlPSIke2J1aWxkLnhhbGFuLmphcn0iIHRvZGlyPSIke2Rpc3QuZGlyfS9iaW4iLz4KLSAgICA8Y29weSBmaWxlPSIke2J1aWxkLmNvbXBhdC5qYXJ9IiB0b2Rpcj0iJHtkaXN0LmRpcn0vYmluIi8+ICAgIAotICAgIDxjb3B5IGZpbGU9IiR7YnVpbGQueHNsdGMuamFyfSIgdG9kaXI9IiR7ZGlzdC5kaXJ9L2JpbiIvPgotCi0gICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9Ij4KLSAgICAgIDxmaWxlc2V0IGRpcj0iLiIgaW5jbHVkZXM9InJlYWRtZS5odG1sLEtFWVMsTGljZW5zZSxidWlsZC54bWwsYnVpbGQuc2gsYnVpbGQuYmF0LHRvZG8ueG1sLHhzbHRjX3RvZG8ueG1sLHRvZG8ueHNsLGNvbW1pdHMueG1sIi8+Ci0gICAgPC9jb3B5PgotICAgICAgICAgIAotICAgIDx6aXAgemlwZmlsZT0iJHtidWlsZC5kaXJ9LyR7ZGlzdC5maWxlfS56aXAiIGJhc2VkaXI9IiR7YnVpbGQuZGlyfSIgaW5jbHVkZXM9IiR7ZGlzdC5maWxlfS8qKiIvPgotICAgIDx0YXIgdGFyZmlsZT0iJHtidWlsZC5kaXJ9LyR7ZGlzdC5maWxlfS50YXIiIGJhc2VkaXI9IiR7YnVpbGQuZGlyfSIgaW5jbHVkZXM9IiR7ZGlzdC5maWxlfS8qKiIvPgotICAgIDxnemlwIHNyYz0iJHtidWlsZC5kaXJ9LyR7ZGlzdC5maWxlfS50YXIiIHppcGZpbGU9IiR7YnVpbGQuZGlyfS8ke2Rpc3QuZmlsZX0udGFyLmd6Ii8+Ci0gIDwvdGFyZ2V0PgotICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENyZWF0ZXMgdGhlIGRvY3VtZW50YXRpb24gdHJlZSBmb3IgdGhlIG9yZy5hcGFjaGUueG1sIHdlYnNpdGUgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJzaXRlIiBkZXBlbmRzPSJwcmVwYXJlLmRvY3MiCi0gICAgZGVzY3JpcHRpb249IkJ1aWxkIGRvY3VtZW50YXRpb24gZm9yIHBvc3RpbmcgdG8gdGhlIHdlYnNpdGUiID4KLSAKLSAgICA8bWtkaXIgZGlyPSIke3NpdGUuZGlyfS9hcGlkb2NzIi8+Ci0gICAgPG1rZGlyIGRpcj0iJHtzaXRlLmRpcn0vY29tcGF0X2FwaWRvY3MiLz4KLSAgICA8bWtkaXIgZGlyPSIke3NpdGUuZGlyfS9kZXNpZ24iLz4KLSAgICA8amF2YSBmb3JrPSJ5ZXMiIAotICAgICAgICAgIGNsYXNzbmFtZT0iJHtkb2MuZ2VuZXJhdG9yfSIgCi0gICAgICAgICAgY2xhc3NwYXRocmVmPSJkb2NzLmNsYXNzLnBhdGgiID4KLSAgICAgICA8YXJnIGxpbmU9InRhcmdldERpcmVjdG9yeT0ke3NpdGUuZGlyfSAke3NpdGUuYm9va30gJHt4ZG9jcy5zdHlsZX0iLz4KLSAgICA8L2phdmE+Ci0KLSAgICA8IS0tIHB1dCB0b2RvLmh0bWwgaW4gdGhlIHNpdGUgZGlyZWN0b3J5IC0tPiAgICAgCi0gICAgPGNvcHkgZmlsZT0iJHtidWlsZC5kb2NzfS90b2RvLmh0bWwiIHRvZGlyPSIke3NpdGUuZGlyfSIvPgotICAgIDwhLS0gcHV0IHhhbGFuIGRlc2lnbiBkb2MgaW4gdGhlIHNpdGUgZGVzaWduIHN1YmRpciAtLT4KLSAgICA8Y29weSB0b2Rpcj0iJHtzaXRlLmRpcn0vZGVzaWduIj4KLSAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5kb2NzfS9kZXNpZ24iLz4KLSAgICA8L2NvcHk+Ci0gICAgPCEtLSBwdXQgeHNsdGMgZGVzaWduIGRvYyBpbiB0aGUgc2l0ZSB4c2x0YyBzdWJkaXIgLS0+Ci0gICAgPGNvcHkgdG9kaXI9IiR7c2l0ZS5kaXJ9L3hzbHRjIj4KLSAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5kb2NzfS94c2x0YyIvPgotICAgIDwvY29weT4gIAotICAgIAotICAgIDwhLS0gcHV0IGluIHRoZSBqYXZhZG9jIC0tPgotICAgIDxjb3B5IHRvZGlyPSIke3NpdGUuZGlyfS9hcGlkb2NzIj4KLSAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5hcGlkb2NzfSIvPgotICAgIDwvY29weT4KLSAgICA8Y29weSB0b2Rpcj0iJHtzaXRlLmRpcn0vY29tcGF0X2FwaWRvY3MiPgotICAgICAgPGZpbGVzZXQgZGlyPSIke2J1aWxkLmNvbXBhdC5hcGlkb2NzfSIvPgotICAgIDwvY29weT4gIAotICAgICAgCi0gIDwvdGFyZ2V0PgotICAgCi0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPCEtLSBDb21waWxlcyBhbmQgcnVucyBtaW5pL3Ntb2tldGVzdCBmcm9tIHhtbC14YWxhblx0ZXN0LCBpZiBwcmVzZW50ICAgIC0tPgotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDxwcm9wZXJ0eSBuYW1lPSJ0ZXN0LnJlbHBhdGgiIHZhbHVlPSIuLi90ZXN0Ii8+Ci0KLSAgPHRhcmdldCBuYW1lPSJtaW5pdGVzdCIgZGVwZW5kcz0icHJlcGFyZSxtaW5pdGVzdC1ydW4sdGVzdHMtbm90LWF2YWlsYWJsZSIgCi0gICAgZGVzY3JpcHRpb249IlJ1biB0aGUgTWluaXRlc3QgZnJvbSB4bWwteGFsYW4vdGVzdCIgPgotICAgIDwhLS0gVGhpcyB0YXJnZXQgc2ltcGx5IGFza3MgdGhlIG1pbml0ZXN0LXJ1biB3b3JrZXIgdGFyZ2V0IHRvIAotICAgICAgICAgYWN0dWFsbHkgaGF2ZSB0aGUgTWluaXRlc3QgcnVuIChieSB0aGUgdGVzdC9idWlsZC54bWwgZmlsZSk7Ci0gICAgICAgICB3ZSB0aGVuIGFsc28gY2FsbCB0aGUgdGVzdHMtbm90LWF2YWlsYWJsZSB0YXJnZXQgaW4gY2FzZSAKLSAgICAgICAgIHRoZSB1c2VyIG5ldmVyIGNoZWNrZWQgb3V0IHRoZSB0ZXN0cy4KLSAgICAtLT4KLSAgPC90YXJnZXQ+Ci0gIDx0YXJnZXQgbmFtZT0ibWluaXRlc3QtcnVuIiBpZj0idGVzdHMtYXZhaWxhYmxlIiBkZXBlbmRzPSJqYXIiID4KLSAgICA8ZWNobyBtZXNzYWdlPSIgW21pbml0ZXN0XSBDYWxsaW5nICR7dGVzdC5yZWxwYXRofS9idWlsZC54bWwgdG8gcnVuIHRoZSBNaW5pdGVzdCIgLz4KLSAgICA8YW50IGRpcj0iJHt0ZXN0LnJlbHBhdGh9IiBhbnRmaWxlPSJidWlsZC54bWwiIHRhcmdldD0ibWluaXRlc3QuZ3VtcCIgPgotICAgIDwvYW50PgotICA8L3RhcmdldD4KLQotICA8dGFyZ2V0IG5hbWU9InNtb2tldGVzdCIgZGVwZW5kcz0icHJlcGFyZSxzbW9rZXRlc3QtcnVuLHRlc3RzLW5vdC1hdmFpbGFibGUiIAotICAgIGRlc2NyaXB0aW9uPSJSdW4gU21va2V0ZXN0cyAoTWluaXRlc3QsIGNvbmYsIGhhcm5lc3MpIGZyb20geG1sLXhhbGFuL3Rlc3QiID4KLSAgPC90YXJnZXQ+Ci0gIDx0YXJnZXQgbmFtZT0ic21va2V0ZXN0LXJ1biIgaWY9InRlc3RzLWF2YWlsYWJsZSIgZGVwZW5kcz0iamFyIiA+Ci0gICAgPGVjaG8gbWVzc2FnZT0iIFttaW5pdGVzdF0gQ2FsbGluZyAke3Rlc3QucmVscGF0aH0vYnVpbGQueG1sIHRvIHJ1biB0aGUgU21va2V0ZXN0IiAvPgotICAgIDxhbnQgZGlyPSIke3Rlc3QucmVscGF0aH0iIGFudGZpbGU9ImJ1aWxkLnhtbCIgdGFyZ2V0PSJzbW9rZXRlc3QuZGV2IiA+Ci0gICAgPC9hbnQ+Ci0gIDwvdGFyZ2V0PgotCi0gIDx0YXJnZXQgbmFtZT0iY2hlY2siIGRlcGVuZHM9InNtb2tldGVzdCI+PCEtLSAnU3RhbmRhcmRpemluZyBidWlsZC54bWwgZmlsZXMnIDxibG9yaXRzY2hAYXBhY2hlLm9yZz4gLS0+Ci0gICAgPGVjaG8gbWVzc2FnZT0iUmVkaXJlY3QgdG8gc21va2V0ZXN0IHRhcmdldCIvPgotICA8L3RhcmdldD4KLQotICA8IS0tIENhbGxlZCBmcm9tIHZhcmlvdXMgdGVzdGluZyB0YXJnZXRzIGlmIHRoZSB0ZXN0IGRpciBkb2Vzbid0IGV4aXN0LiAtLT4KLSAgPHRhcmdldCBuYW1lPSJ0ZXN0cy1ub3QtYXZhaWxhYmxlIiB1bmxlc3M9InRlc3RzLWF2YWlsYWJsZSIgPgotICAgIDxlY2hvIG1lc3NhZ2U9IiBbdGVzdHNdIFRoZSB0ZXN0cyBkbyBub3Qgc2VlbSB0byBiZSBwcmVzZW50IGluICR7dGVzdC5yZWxwYXRofSIgLz4KLSAgICA8ZWNobyBtZXNzYWdlPSIgW3Rlc3RzXSBZb3UgbXVzdCBoYXZlIGNoZWNrZWQgb3V0IGZyb20gQ1ZTIHRvIHJ1biB0aGUgdGVzdHMsIiAvPgotICAgIDxlY2hvIG1lc3NhZ2U9IiBbdGVzdHNdICAgaXQgaXMgbm90IGluY2x1ZGVkIGluIGJpbmFyeSBkaXN0cmlidXRpb25zLiIgLz4KLSAgICA8ZWNobyBtZXNzYWdlPSIgW3Rlc3RzXSBTZWUgaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuLWovdGVzdC8gZm9yIG1vcmUgaW5mby4iIC8+Ci0gIDwvdGFyZ2V0PgotICAKLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENyZWF0ZXMgdGhlIHRvZG8gbGlzdCBmb3IgdGhlIG9yZy5hcGFjaGUueG1sIHdlYnNpdGUgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPHRhcmdldCBuYW1lPSJ0b2RvIj4KLSAgICA8amF2YSBmb3JrPSJ5ZXMiIAotICAgICAgICAgIGNsYXNzbmFtZT0iJHt4YWxhbi5jbWRsaW5lLmNsYXNzfSIgCi0gICAgICAgICAgY2xhc3NwYXRocmVmPSJkb2NzLmNsYXNzLnBhdGgiID4KLSAgICAgIDxhcmcgbGluZT0iLWluIHRvZG8ueG1sIC14c2wgdG9kby54c2wgLW91dCB0b2RvLmh0bWwiLz4KLSAgICA8L2phdmE+ICAgCi0gIDwvdGFyZ2V0PiAgCi0KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotICA8IS0tIENyZWF0ZXMgdGhlIHhhbGFuIGRlc2lnbiBkb2N1bWVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgICA8dGFyZ2V0IG5hbWU9InhhbGFuLWoyLWRlc2lnbiI+Ci0gICAgPGphdmEgZm9yaz0ieWVzIiAKLSAgICAgICAgICBjbGFzc25hbWU9IiR7ZG9jLmdlbmVyYXRvcn0iIAotICAgICAgICAgIGNsYXNzcGF0aHJlZj0iZG9jcy5jbGFzcy5wYXRoIiA+Ci0gICAgICA8YXJnIGxpbmU9ImxvYWRlckNvbmZpZz1zYms6L3N0eWxlL2xvYWRlcmRlc2lnbi54bWwgdGFyZ2V0RGlyZWN0b3J5PSR7YnVpbGQuZGlyfS9kb2NzL2Rlc2lnbi8KLSAgICAgICR7eGRvY3MuZGlyfS9zb3VyY2VzL3hhbGFuZGVzaWduLnhtbCAke3hkb2NzLnN0eWxlfSIvPgotICAgIDwvamF2YT4KLSAgPC90YXJnZXQ+Ci0gIAotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gVXNlIEZPUCB0byBjcmVhdGUgcHJlbGltaW5hcnkgcHJpbnQgKHBkZikgZG9jICAgICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSBOb3RlOiBmb3AuamFyIGFuZCB4bWwuamFyIChmcm9tIHhtbC1mb3ApIG11c3QgYmUgb24gY2xhc3NwYXRoICAgICAgIC0tPgotICA8IS0tIFRoaXMgaXMgVkVSWSBwcmVsaW1pbmFyeSwgbm90IHlldCBmb3IgaW5jbHVzaW9uIGluIGRpc3RyaWJ1dGlvbiAgICAgLS0+Ci0gIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLSAgPCEtLUNvbGxhdGUgdGhlIHhtbCBzb3VyY2VzIGludG8gYSBzaW5nbGUgeG1sIHNvdXJjZSB3aXRoIGEgbGl0bGUgZXh0cmEgc3RydWN0dXJlIC0tPgotICA8dGFyZ2V0IG5hbWU9InByaW50ZXJkb2NzIiBkZXBlbmRzPSJwcmVwYXJlLmRvY3MiPgotICAgIDxlY2hvIG1lc3NhZ2U9Ik5PVElDRTogcmVxdWlyZXMgZm9wLmphciBhbmQgeG1sLmphciBvbiB0aGUgY2xhc3NwYXRoIi8+Ci0gICAgPGphdmEgZm9yaz0ieWVzIiAKLSAgICAgICAgICBjbGFzc25hbWU9IiR7eGFsYW4uY21kbGluZS5jbGFzc30iCi0gICAgICAgICAgY2xhc3NwYXRocmVmPSJkb2NzLmNsYXNzLnBhdGgiID4KLSAgICAgIDxhcmcgbGluZT0iLXhzbCAke3hkb2NzLmRpcn0vc291cmNlcy94YWxhbi1jb2xsYXRlLnhzbCAKLSAgICAgICAgICAgICAgICAgLW91dCB4ZG9jcy9zb3VyY2VzL3hhbGFuL3hhbGFuLWNvbGxhdGUueG1sIi8+Ci0gICAgPC9qYXZhPgotICAgIAotICAgIDwhLS0gVHJhbnNmb3JtIGNvbGxhdGlvbiBpbnRvIEZvcm1hdHRpbmcgT2JqZWN0cyAKLSAgICAgICAgICh3aXRoIGEgbGl0dGxlIHdvcmsgb24gbGlua3MgYWxvbmcgdGhlIHdheSkgLS0+ICAgIAotICAgIDxqYXZhIGZvcms9InllcyIgCi0gICAgICAgICAgY2xhc3NuYW1lPSIke3hhbGFuLmNtZGxpbmUuY2xhc3N9IgotICAgICAgICAgIGNsYXNzcGF0aHJlZj0iZG9jcy5jbGFzcy5wYXRoIiA+Ci0gICAgICA8YXJnIGxpbmU9Ii1pbiAgJHt4ZG9jcy5kaXJ9L3NvdXJjZXMveGFsYW4veGFsYW4tY29sbGF0ZS54bWwKLSAgICAgICAgICAgICAgICAgLXBhcmFtIHJlc291cmNlRmlsZSAnLi4vLi4vc291cmNlcy94YWxhbi9yZXNvdXJjZXMueG1sJwotICAgICAgICAgICAgICAgICAtcGFyYW0gcHJvamVjdCAke05hbWV9ICAgICAgCi0gICAgICAgICAgICAgICAgIC14c2wgJHt4ZG9jcy5zdHlsZX0vc3R5bGVzaGVldHMveG1sMmZvLnhzbCAKLSAgICAgICAgICAgICAgICAgLW91dCBidWlsZC9kb2NzL3hhbGFuLWNvbGxhdGUuZm8iLz4KLSAgICA8L2phdmE+Ci0gICAgCi0gICAgPCEtLSBVc2UgRk9QIHRvIGdlbmVyYXRlIGEgcGRmIGZpbGUgKGNsYXNzcGF0aCBtYXkgbmVlZCB1cGRhdGluZyEgLXNjIDE4LUFwci0wMSktLT4KLSAgICA8amF2YSBmb3JrPSJ5ZXMiIAotICAgICAgICAgIGNsYXNzbmFtZT0ib3JnLmFwYWNoZS5mb3AuYXBwcy5Db21tYW5kTGluZSIKLSAgICAgIGNsYXNzcGF0aD0iJHtqYXZhLmNsYXNzLnBhdGh9OiR7YnVpbGQueGFsYW4uamFyfToke2Jpbi5kaXJ9L2ZvcC5qYXI6JHtiaW4uZGlyfS93M2MuamFyIj4KLSAgICAgIDxhcmcgbGluZT0iJHtidWlsZC5kb2NzfS94YWxhbi1jb2xsYXRlLmZvIGJ1aWxkL2RvY3MveGFsYW4ucGRmIi8+Ci0gICAgPC9qYXZhPgotICA8L3RhcmdldD4KLQotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+ICAKLSAgIDwhLS0gZm9yIGRldmVsb3BlcnMgb25seTsgY29tcGlsZXMgeGFsYW4tajEgc2FtcGxlcyB3aXRoIGNvbXBhdCBqYXIgYW5kIHhhbGFuLWoyIHhhbGFuLmphci0tPgotICAgPHRhcmdldCBuYW1lPSJjb21wYXQuc2FtcGxlcyIgZGVwZW5kcz0iamFyLGNvbXBhdC5qYXIiIAotICAgIGRlc2NyaXB0aW9uPSJDb21waWxlIGFuZCBqYXIgWGFsYW4tSiAxLnggYmFja3dhcmRzIGNvbXBhdCBzYW1wbGVzIiA+Ci0gICAgIDxwcm9wZXJ0eSBuYW1lPSJleGNsdWRlIiB2YWx1ZT0iKi54bWwsKi54c2wsKi50eHQsKi5odG1sLioucHJvcGVydGllcyIvPgotICAgICA8cHJvcGVydHkgbmFtZT0ic2FtcGxlc2oxLmRpciIgdmFsdWU9Ii94bWwteGFsYW4vc2FtcGxlcyIvPgotICAgICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuY29tcGF0LnNhbXBsZXMiIHZhbHVlPSIuL2J1aWxkL2NvbXBhdF9zYW1wbGVzIi8+Ci0gICAgIDxta2RpciBkaXI9IiR7YnVpbGQuY29tcGF0LnNhbXBsZXN9Ii8+ICAgICAKLQotICAgIDwhLS1uZWVkIHRvIHVzZSB0aGUgWGFsYW5KMiBYUGF0aEFQSSwgc28gY2Fubm90IGNvbXBpbGUgQXBwbHlYUGF0aCBhcyBpcyAtLT4gICAKLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXNqMS5kaXJ9L1BpcGUiIGNsYXNzcGF0aD0iJHtidWlsZC5jb21wYXQuamFyfToke2J1aWxkLnhhbGFuLmphcn06JHtqYXZhLmNsYXNzLnBhdGh9IiAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30iICBleGNsdWRlcz0iJHtleGNsdWRlfSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+IAotICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlc2oxLmRpcn0vU2ltcGxlVHJhbnNmb3JtIiBjbGFzc3BhdGg9IiR7YnVpbGQuY29tcGF0Lmphcn06JHtidWlsZC54YWxhbi5qYXJ9OiR7amF2YS5jbGFzcy5wYXRofSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuY29tcGF0LnNhbXBsZXN9IiAgZXhjbHVkZXM9IiR7ZXhjbHVkZX0iCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIvPgotICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlc2oxLmRpcn0vVHJhbnNmb3JtVG9Eb20iIGNsYXNzcGF0aD0iJHtidWlsZC5jb21wYXQuamFyfToke2J1aWxkLnhhbGFuLmphcn06JHtqYXZhLmNsYXNzLnBhdGh9IiAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30iICBleGNsdWRlcz0iJHtleGNsdWRlfSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+Ci0gICAgPGphdmFjIHNyY2Rpcj0iJHtzYW1wbGVzajEuZGlyfS9QdXJlU0FYIiBjbGFzc3BhdGg9IiR7YnVpbGQuY29tcGF0Lmphcn06JHtidWlsZC54YWxhbi5qYXJ9OiR7amF2YS5jbGFzcy5wYXRofSIgCi0gICAgICAgICAgIGRlc3RkaXI9IiR7YnVpbGQuY29tcGF0LnNhbXBsZXN9IiAgZXhjbHVkZXM9IiR7ZXhjbHVkZX0iCi0gICAgICAgICAgIGRlYnVnPSIke2RlYnVnfSIvPiAgICAgICAgICAKLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXNqMS5kaXJ9L1VzZVN0eWxlc2hlZXRQYXJhbSIgY2xhc3NwYXRoPSIke2J1aWxkLmNvbXBhdC5qYXJ9OiR7YnVpbGQueGFsYW4uamFyfToke2phdmEuY2xhc3MucGF0aH0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLmNvbXBhdC5zYW1wbGVzfSIgIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8amF2YWMgc3JjZGlyPSIke3NhbXBsZXNqMS5kaXJ9L1NlcnZsZXQiIGNsYXNzcGF0aD0iJHtidWlsZC5jb21wYXQuamFyfToke2J1aWxkLnhhbGFuLmphcn06JHtqYXZhLmNsYXNzLnBhdGh9IiAKLSAgICAgICAgICAgZGVzdGRpcj0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30iIGV4Y2x1ZGVzPSIke2V4Y2x1ZGV9IgotICAgICAgICAgICBkZWJ1Zz0iJHtkZWJ1Z30iLz4KLSAgICA8amFyICAgamFyZmlsZT0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30veGFsYW5qY29tcGF0c2FtcGxlcy5qYXIiIGJhc2VkaXI9IiR7YnVpbGQuY29tcGF0LnNhbXBsZXN9IgotICAgICAgICAgICAgaW5jbHVkZXM9IiouY2xhc3MiLz4gCi0gICAgIDwhLS1wdXQgdGhlIHNlcnZsZXQgaW4gYSBzZXBhcmF0ZSBqYXIgLS0+Ci0gICAgIDxqYXZhYyBzcmNkaXI9IiR7c2FtcGxlc2oxLmRpcn0vU2VydmxldCIgY2xhc3NwYXRoPSIke2J1aWxkLmNvbXBhdC5qYXJ9OiR7YnVpbGQueGFsYW4uamFyfToke2phdmEuY2xhc3MucGF0aH0iIAotICAgICAgICAgICBkZXN0ZGlyPSIke2J1aWxkLmNvbXBhdC5zYW1wbGVzfSIKLSAgICAgICAgICAgZGVidWc9IiR7ZGVidWd9Ii8+Ci0gICAgICA8Y29weSB0b2Rpcj0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30vc2VydmxldCI+Ci0gICAgICAgICAgPGZpbGVzZXQgZGlyPSIke3NhbXBsZXNqMS5kaXJ9L1NlcnZsZXQiIAotICAgICAgICAgICAgICAgIGluY2x1ZGVzPSJtZWRpYS5wcm9wZXJ0aWVzLGRlZmF1bHQueHNsLGRlZmF1bHQyLnhzbCIvPgotICAgICAgICA8L2NvcHk+ICAJCSAgICAgICAgIAotICAgIDxqYXIgamFyZmlsZT0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30veGFsYW5jb21wYXRzZXJ2bGV0LmphciIgYmFzZWRpcj0iJHtidWlsZC5jb21wYXQuc2FtcGxlc30iCi0gICAgICAgICBpbmNsdWRlcz0ic2VydmxldC8qKiIvPgotIDwvdGFyZ2V0PgotIAotICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0gIDwhLS0gQnVpbGQgWFNMVEMgZGVzaWduIGRvY3VtZW50YXRpb24uIEV2ZW50dWFsbHkgaW50ZW5kIHRvIGluY29ycG9yYXRlIC0tPgotICA8IS0tIFhTTFRDIGludG8gdGhlIFhhbGFuIGJvb2suICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLSAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotCi0KLSAgPHRhcmdldCBuYW1lPSJ4c2x0Yy5wcmVwYXJlLmRvY3MiIGRlcGVuZHM9InByZXBhcmUuZG9jcyI+Ci0gICAgICA8ZWNobyBtZXNzYWdlPSJUcmFuc2Zvcm0geHNsdGNfdG9kby54bWwgYW5kIHB1dCB0aGUgcmVzdWx0IGluICR7YnVpbGQuZG9jc30veHNsdGMiLz4KLSAgIDxta2RpciBkaXI9IiR7YnVpbGQuZG9jc30veHNsdGMiLz4KLSAgICA8amF2YSBmb3JrPSJ5ZXMiIGNsYXNzbmFtZT0iJHt4YWxhbi5jbWRsaW5lLmNsYXNzfSI+Ci0gICAgICA8Y2xhc3NwYXRoIHJlZmlkPSJkb2NzLmNsYXNzLnBhdGgiIC8+Ci0gICAgICA8YXJnIGxpbmU9Ii1pbiB4c2x0Y190b2RvLnhtbCAteHNsIHRvZG8ueHNsIC1vdXQgYnVpbGQvZG9jcy94c2x0Yy90b2RvLmh0bWwiLz4KLSAgICA8L2phdmE+Ci0gIDwvdGFyZ2V0PiAgCi0gCi0gPHRhcmdldCBuYW1lPSJ4c2x0Yy5kb2NzIiBkZXBlbmRzPSJ4c2x0Yy5wcmVwYXJlLmRvY3MiPgotICAgPGVjaG8gbWVzc2FnZT0iQnVpbGQgdGhlIFhTTFRDIEFyY2hpdGVjdHVyYWwgZG9jdW1lbnRhdGlvbiIvPgotICAgPGphdmEgZm9yaz0ieWVzIiAKLSAgICAgICAgIGNsYXNzbmFtZT0iJHtkb2MuZ2VuZXJhdG9yfSIgCi0gICAgICAgICBjbGFzc3BhdGhyZWY9ImRvY3MuY2xhc3MucGF0aCIgPgotICAgICAgPGFyZyBsaW5lPSJ0YXJnZXREaXJlY3Rvcnk9JHtidWlsZC5kb2NzfS94c2x0YyAke3hkb2NzLmRpcn0vc291cmNlcy94c2x0Yy54bWwgJHt4ZG9jcy5zdHlsZX0iLz4KLSAgICA8L2phdmE+CSAKLSA8L3RhcmdldD4KLSAKLSAgIDwhLS0gcGFjayBhbGwgZG9jIGZvciB0cmFuc2ZlciB0byB3ZWJzaXRlIC0tPgotIDx0YXJnZXQgbmFtZT0icGFjay5kb2NzIj4KLSAgICA8dGFyIHRhcmZpbGU9Ii4vYnVpbGQveGFsYW4tai1kb2NzLnRhciIgYmFzZWRpcj0iLi94bWwtc2l0ZS90YXJnZXQveGFsYW4taiIgaW5jbHVkZXM9IioqIi8+Ci0gICAgPGd6aXAgc3JjPSIuL2J1aWxkL3hhbGFuLWotZG9jcy50YXIiIHppcGZpbGU9Ii4vYnVpbGQveGFsYW4tai1kb2NzLnRhci5neiIvPgotICAgIDwhLS16aXAgemlwZmlsZT0iLi9idWlsZC94YWxhbi1qLWRvY3MuemlwIiBiYXNlZGlyPSIuL3htbC1zaXRlL3RhcmdldC94YWxhbi1qIiBpbmNsdWRlcz0iKioiLy0tPgotICA8L3RhcmdldD4KLQotIAotPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvY29tbWl0cy54bWwgYi9jb21taXRzLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTM0NGM3ZC4uMDAwMDAwMAotLS0gYS9jb21taXRzLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDYxOSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxDb21taXRzPgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPmdhcnlwQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzEzLzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9zYXgyZHRtIFNBWDJEVE0uamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkZpeCBidWd6aWxsYSBidWcgMzA1NiAKLShodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTMwNTYpLiBTQVgyRFRNIG5vdyBrZWVwcyAKLXRyYWNrIGlmIGl0IGlzIHJlY2VpdmluZyBldmVudHMgaW5zaWRlIGEgRFREIGFuZCBpZ25vcmVzIGNvbW1lbnQgZXZlbnRzIHdoZW4gCi1pbnNpZGUgdGhlIERURC48L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTMvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFBhcnNlci5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+SSBhZGRlZCBhIGZsYWcgdG8gdGhlIGNvbXBpbGVyL1BhcnNlciBjbGFzcyB0aGF0IGlzIHNldCBpZiB0aGUgb3V0ZXJtb3N0IAotZWxlbWVudAotIGluIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5zIGEgZGVmaW5pdGlvbiBvZiB0aGUgWFNMIG5hbWVzcGFjZS4gVGhlIHBhcnNlciAKLWFscmVhZHkKLSBoYXMgYSBnbG9iYWwgdmFyaWFibGUgJ190YXJnZXQnIHRoYXQgaXMgc2V0IGlmIHRoZSBzdHlsZXNoZWV0IGNvbnRhaW5zIGEKLSAmbHQ7P3htbC1zdHlsZXNoZWV0PyZndDsgUEkgb3Igbm90LiBUaGUgY29tcGlsZXIgd2lsbCBub3cgZmxhZyBhbiBlcnJvciBpZiBuZWl0aGVyCi0gZmxhZ3MgYXJlIHNldCBhZnRlciB0aGUgd2hvbGUgWFNML1hNTCBpbnB1dCBkb2N1bWVudCBoYXMgYmVlbiBwYXJzZWQuCi0gUFI6IGJ1Z3ppbGxhIDE3ODAKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzEzLzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBVbmlvblBhdGhFeHByLmphdmE8L01vZGlmaWVkPgotPExvZz5BZGRlZCBhIHNtYWxsIGZpeCB0aGF0IG9yZGVycyB0aGUgZXhwcmVzc2lvbnMgaW5zaWRlIGEgdW5pb24gaW4gc3VjaCBhIHdheSAKLXRoYXQKLSBleHByZXNzaW9ucyB3aXRoIGFuIGF0dHJpYnV0ZSBheGlzIG9yIGF0dHJpYnV0ZSBub2RlIHR5cGUgd2lsbCBiZSBwdXQgZmlyc3QuCi0gUFI6IGJ1Z3ppbGxhIDI5MjEKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzEzLzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBQYXJzZXIuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkEgc21hbGwgZml4IHRoYXQgd2lsbCBhbGxvdyB0b3AtbGV2ZWwgZWxlbWVudHMgb2YgYW4gdW5rbm93biBVUkkuCi0gWFNMVEMgbm93IGlnbm9yZWQgdGhlIGVsZW1lbnQocyksIHdoaWxlIGl0IHByZXZpb3VzbHkgcmVwb3J0ZWQgYW4gZXJyb3IKLSBvZiBhbiB1bnN1cHBvcnRlZCBYU0xUIGV4dGVuc2lvbi4KLSBQUjogYnVnemlsbGEgMjg0MAotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQGFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQGFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTMvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBBYnN0cmFjdFRyYW5zbGV0LmphdmEgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIuamF2YQotIFRleHRPdXRwdXQuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkEgc3RhcnQgb24gYSBmaXggZm9yIG91dHB1dCBET0NUWVBFIGRlY2xhcmF0aW9ucyBiYXNlZCBvbiB0aGUgYXR0cmlidXRlcwotIG9mIHRoZSAmbHQ7eHNsOm91dHB1dCZndDsgZWxlbWVudC4gSSBhbHNvIGFkZGVkIGEgZml4IGZvciBidWcgMjg2MywgdG8gcHJldmVudAotIHVzIGZyb20gb3V0cHV0dGluZyBuYW1lc3BhY2UgZGVsY2FyYXRpb24gdGhhdCBwb2ludCBhIHByZWZpeCB0byB0aGUgbnVsbAotIFVSSSAoc3VjaCBhcyAneG1sbnM6YmxvYj0iIicpLgotIFBSOiBidWd6aWxsYSAyODYzCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPnRtaWxsZXJAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTMvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIHhwYXRoLmN1cDwvTW9kaWZpZWQ+Ci08TG9nPmJ1ZyAyNTUzLCBmaXhlcyBBYmJyZXZpYXRlZEFic29sdXRlTG9jYXRpb25QYXRoLAotIHNvbWUgcmVsYXRpdmUgbG9jYXRpb24gcGF0aHMgc3RpbGwgZ2l2ZSBkdXBsaWNhdGVzLCB3aWxsIG5lZWQgdG8gZmlsdGVyLjwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+bW1pZHlAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTMvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3JlcyBYU0xUSW5mby5wcm9wZXJ0aWVzPC9Nb2RpZmllZD4KLTxMb2c+VXBkYXRlIHZlcnNpb24gZm9yIDIuMi5EOSBidWlsZDwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNC8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY21kbGluZSBUcmFuc2Zvcm0uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgT3V0cHV0LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgRGVmYXVsdFJ1bi5qYXZhCi0gRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIuamF2YSBUZXh0T3V0cHV0LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXggVHJhbnNmb3JtZXJJbXBsLmphdmE8L01vZGlmaWVkPgotPExvZz5JbXBsZW1lbnRlZCBzdXBwb3J0IGZvciB0aGUgZG9jdHlwZS1zeXN0ZW0gYW5kIGRvY3R5cGUtcHVibGljIGF0dHJpYnV0ZXMKLSBvZiB0aGUgJmx0O3hzbDpvdXRwdXQvJmd0OyBlbGVtZW50LiBUaGUgdHJhbnNsZXQgcG9zdC1wcm9jZXNzb3IgKFRleHRPdXRwdXQpIGNhbgotIG5vdyBiZSBpbnN0YW5jaWF0ZWQgd2l0aCBhIENvbnRlbnRIYW5kbGVyIGFuZCBhbiBvcHRpb25hbCBMZXhpY2FsSGFuZGxlci4KLSBUaGUgTGV4aWNhbEhhbmRsZXIgd2lsbCByZWNlaXZlIG5vdG9maWNhdGlvbnMgb2YgdGhlIERPQ1RZUEUgZGVjbGFyYXRpb24uCi0gVGhlIGRlZmF1bHQgU0FYIG91dHB1dCBoYW5kbGVyIG5vdyBpbXBsZW1lbnRzIGJvdGggQ29udGVudEhhbmRsZXIgYW5kCi0gTGV4aWNhbEhhbmRsZXIuIFRoZSBMZXhpY2FsSGFuZGxlciBvbmx5IGhhbmRsZXMgdGhlIHN0YXJ0RFREKCkgbWV0aG9kLAotIGJ5IG91dHB1dHRpbmcgdGhlIERPQ1RZUEUgZGVjbGFyYXRpb24sIGFuZCBhbGwgb3RoZXIgbWV0aG9kcyBhcmUgZW1wdHkuCi0gVGhlIHRyYXguVHJhbnNmb3JtZXIgaW1wbGVtZW50YXRpb24gaGFzIGFsc28gYmVlbiB1cGRhdGVkIHRvIHVzZSB0aGUKLSBMZXhpY2FsSGFuZGxlciwgYnV0IEkgc3RpbGwgaGF2ZSBub3QgZm91bmQgYW55IHdheSBpbiB3aGljaCBhIFNBWCBjbGllbnQKLSBjYW4gc2V0IHRoZSBMZXhpY2FsSGFuZGxlci4KLSBQUjogYnVnemlsbGEgMTUwNAotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQGFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQGFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTQvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFhzbEVsZW1lbnQuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkEgbWlub3IgY2hhbmdlIHRvIHRoZSBjbGFzcyBoYW5kbGluZyB0aGUgJmx0O3hzbDplbGVtZW50Jmd0OyBlbGVtZW50IHRvIGJlIG1vcmUKLSBpbi1zeW5jIHdpdGggdGhlIFhTTFQgMS4wIHNwZWMgKGFuZCBNLktheSdzIGJvb2spLiBUaGlzIGluIG9yZGVyIHRvIG1ha2UKLSBpdCBtb3JlIHJlYWRhYmxlIGFuZCBtYWludGFpbmFibGUuIEkgd2FzIHRyeWluZyB0byBkZWJ1ZyB0aGUgY29kZSBmb3IKLSBzb21ldGhpbmcgSSB0aG91Z2h0IHdhcyBhIGJ1ZywgYW5kIGl0IHdhcyBqdXN0IGltcG9zc2libGUgdG8gbmF2aWdhdGUuCi0gVGhpcyBjaGFuZ2Ugd2FzIG5lY2Vzc2FyeSwgZXZlbiB0aG91Z2ggdGhlIGNvZGUgZnVuY3Rpb25lZCBhcyBpdCBzaG91bGQuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQGFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQGFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTQvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIExpdGVyYWxFbGVtZW50LmphdmEKLSBQYXJzZXIuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkZpeCBmb3Igb3V0cHV0dGluZyBhbGwgbmVjZXNzYXJ5IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgd2l0aCBMUkVzLgotIFBSOiBidWd6aWxsYSAyODYzCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNC8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIFJldmVyc2VJdGVyYXRvci5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+QSBmaXggdG8gYWxsb3cgcmV2ZXJzZSBpdGVyYXRvcnMgdG8gYmUgcmVzZXQgKGluc2lkZSBuZXN0ZWQgZm9yLWVhY2ggbG9vcHMpLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9ImNvcmUiPgotPFdobz5qb2huZ0BhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNC8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBDb25uZWN0aW9uUG9vbC5qYXZhCi0gRGVmYXVsdENvbm5lY3Rpb25Qb29sLmphdmEgU1FMRG9jdW1lbnQuamF2YQotIFhDb25uZWN0aW9uLmphdmE8L01vZGlmaWVkPgotPExvZz5GaXhlZCBidWcgaW4gY29ubmVjdCBtZXRob2Qgd2hlcmUgVXNlciBhbmQgUGFzc3dvcmQgd2VyZSBub3QKLSBjb3JyZWN0bHkgYmVpbmcgcGFzc2VkIHRvIHRoZSBKREJDIERyaXZlci4gUmVxdWlyZXMgY2huYWdlIGluCi0gQ29ubmVjdGlvblBvb2wgSW50ZXJmYWNlCi0gU3VibWl0dGVkIGJ5OiBKb2huIEdlbnRpbGluPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9ImNvcmUiPgotPFdobz5tbWlkeUBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNS8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBYQ29ubmVjdGlvbi5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+VXNlIGRlZmluZWQgY29uc3RhbnQgRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTIGZvciBzaGlmdGluZyBEVE0gbm9kZXMsIAotbm90IGhhcmQgY29kZWQgdmFsdWUuPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+dG1pbGxlckBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNS8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPEFkZGVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIER1cEZpbHRlckl0ZXJhdG9yLmphdmE8L0FkZGVkPgotPExvZz5idWcgZml4IDI1NTMsIG5ldyBpdGVyYXRvciB0byBnZXQgcmlkIG9mIGR1cHM8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz50bWlsbGVyQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE1LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08QWRkZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlcgotIEZpbHRlcmVkQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YTwvQWRkZWQ+Ci08TG9nPmJ1ZyBmaXggMjU1MywgbmV3IGFicyBsb2NhdGlvbiBwYXRoPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+dG1pbGxlckBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNS8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgeHBhdGguY3VwCi0gQ29uc3RhbnRzLmphdmE8L01vZGlmaWVkPgotPExvZz5idWcgZml4IDI1NTMsIHVwZGF0ZWQgQ29uc3RhbnRzIGZvciBkdXAgcHJvY2Vzc2luZwotIGFuZCB1cGRhdGVkIENVUCBydWxlIGZvciBBYmJyZXZpYXRlZEFic29sdXRlTG9jYXRpb25QYXRoczwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+bW1pZHlAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTUvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBTeXN0ZW1JRFJlc29sdmVyLmphdmE8L01vZGlmaWVkPgotPExvZz5GaXggcHJvYmxlbSB3aXRoIHJlc29sdmluZyBhIHJlbGF0aXZlIFVSSSBmcm9tIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNi8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIEFic29sdXRlSXRlcmF0b3IuamF2YQotIERPTUltcGwuamF2YSBEdXBGaWx0ZXJJdGVyYXRvci5qYXZhCi0gU3RlcEl0ZXJhdG9yLmphdmEgVW5pb25JdGVyYXRvci5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+SW1wbGVtZW50YXRpb24gb2YgaWQoKSBhbmQga2V5KCkgcGF0dGVybiAtIGZpbmFsbHkhCi0gQWRkZWQgYSBzbWFsbCBmaXggdG8gdGhlIERPTUltcGwkRGVzY2VuZGFudEl0ZXJhdG9yIHRvIHByZXZlbnQgTlBFcy4KLSBQUjogYnVnemlsbGEgMTM3NgotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNi8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgSWRLZXlQYXR0ZXJuLmphdmEKLSBLZXlDYWxsLmphdmEgTW9kZS5qYXZhIE91dHB1dC5qYXZhIFBhcnNlci5qYXZhCi0gVGVzdFNlcS5qYXZhIHhwYXRoLmN1cDwvTW9kaWZpZWQ+Ci08TG9nPkZvcmdvdCBhbiAnaW1wb3J0JyBpbiBEdXBGaWx0ZXJJdGVyYXRvcgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTYvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjIFRyYW5zbGV0T3V0cHV0SGFuZGxlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRHVwRmlsdGVySXRlcmF0b3IuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YSBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhCi0gU0FYQWRhcHRlci5qYXZhIFRleHRPdXRwdXQuamF2YQotIFRyYW5zbGV0T3V0cHV0QmFzZS5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+bWlzc2luZyBmaWxlPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE2LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkFkZGVkIGFub3RoZXIgZml4IGZvciB0aGUgbWlzc2luZyBET0NUWVBFIGRlY2xhcmF0aW9uLiBYU0xUQyB3aWxsIG5vdyBvdXRwdXQKLSBET0NUWVBFIGRlY2xhcmF0aW9ucyBmb3IgSFRNTCBvdXRwdXQgaWYgZWl0aGVyIGRvY3R5cGUtc3lzdGVtIG9yIGRvY3R5cGUtCi0gcHVibGljIGlzIGRlY2xhcmVkIGluIHRoZSAmbHQ7eHNsOm91dHB1dCZndDsgZWxlbWVudC4gWFNMIG91dHB1dCB3aWxsIGdldCBhCi0gRE9DVFlQRSBkZWNsYXJhdGlvbiBvbmx5IGlmIGRvY3R5cGUtc3lzdGVtIGlzIGRlY2xhcmVkLgotIFBSOiAxNTA0Ci0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE2LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gQWJzb2x1dGVJdGVyYXRvci5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+Ci0KLQotPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+dG1pbGxlckBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNi8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgeHBhdGguY3VwPC9Nb2RpZmllZD4KLTxMb2c+dHVybmluZyBvbiBmaWx0ZXJpbmcsIGJ1ZyAyNTUzPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE2LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRHVwRmlsdGVySXRlcmF0b3IuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPlJlbW92ZWQgYSBiYWQgb3B0aW1pc2F0aW9uIGluIHRoZSBkdXBsaWNhdGUgZmlsdGVyIGl0ZXJhdG9yLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz50bWlsbGVyQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE3LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciB4cGF0aC5jdXA8L01vZGlmaWVkPgotPExvZz5yZS1hY3RpdmF0ZWQgdGhlIG5vIGR1cHMgZmlsdGVyaW5nLCBkb250IGtub3cgaG93Ci0gdGhpcyBnb3QgcmV2ZXJ0ZWQgYmFjayB0byBubyBmaWx0ZXJpbmcsIGJ1dCBpdCBpcyBmaXhlZCBhZ2Fpbi48L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPm1taWR5QGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE3LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgU3lzdGVtSURSZXNvbHZlci5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+TWFrZSBzdXJlIGJhc2UgaXMgbm90IG51bGwgYmVmb3JlIGNoZWNraW5nIGZvciBpdHMgY29udGVudHMuPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzE3LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBJZEtleVBhdHRlcm4uamF2YQotIEtleS5qYXZhIEtleUNhbGwuamF2YSBQYXJzZXIuamF2YSBTb3J0LmphdmEKLSB4cGF0aC5jdXAKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBDb21wYXJlR2VuZXJhdG9yLmphdmEgTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3IuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERURE1vbml0b3IuamF2YQotIER1cEZpbHRlckl0ZXJhdG9yLmphdmEgS2V5SW5kZXguamF2YQotIE5vZGVTb3J0UmVjb3JkLmphdmEgTm9kZVNvcnRSZWNvcmRGYWN0b3J5LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBBYnN0cmFjdFRyYW5zbGV0LmphdmEgQmFzaXNMaWJyYXJ5LmphdmE8L01vZGlmaWVkPgotPExvZz5NYWpvciB1cGRhdGUgZm9yIGlkKCkgYW5kIGtleSgpLiBQYXR0ZXJucyBjb250YWluaW5nIGlkKCkgYW5kIGtleSgpIGFyZQotIG5vdyAxMDAlIHN1cHBvcnRlZCAoYWJvdXQgdGltZSksIGFuZCBpZCgpIGFuZCBrZXkoKSBleHByZXNzaW9ucyBzaG91bGQKLSBub3cgd29yayBpbiBhbGwgKGF0IGxlYXN0IG1vc3QpIGNvbWJpbmF0aW9ucy4KLSBQUjogYnVnemlsbGEgMTM3NiAoISEhKSBhbmQgMjYyNAotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+bW1pZHlAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMTcvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBGdW5jRG9jdW1lbnQuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkZpeCBkb2N1bWVudCBmdW5jdGlvbiBzbyB0aGF0IGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZCBhbmQgaXQgaXMgYSAKLW5vZGV0ZXN0LCB0aGUgYmFzZSB0byBiZSB1c2VkIHRvIHJlc29sdmUgcmVsYXRpdmUgVVJJcyBpcyB0aGUgYmFzZSBvZiB0aGUgZWFjaCAKLW5vZGUgaW4gdGhlIG5vZGVzZXQuPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9ImNvcmUiPgotPFdobz5tbWlkeUBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8xNy8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFhTTFRTY2hlbWEuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkFsbG93IG11bHRpcGxlIGl0ZXJhdGlvbnMgb2YgeHNsOndpdGgtcGFyYW0gd2l0aGluIGFuIHhzbDpjYWxsLXRlbXBsYXRlIG9yIAoteHNsOmFwcGx5LXRlbXBsYXRlPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzIwLzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIEJhc2lzTGlicmFyeS5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+QSBzbWFsbCBmaXggZm9yIGEgY2xlYW51cCBJIGRpZCBpbiB0aGUgYmFzaXMgbGlicmFyeSAoaXQgYnJva2UgdGhlCi0gc3Vic3RyaW5nKCkgZnVuY3Rpb24pJmd0OwotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjAvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgVGV4dE91dHB1dC5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+QWRkZWQgc21hbGwgZml4IHRvIHByZXZlbnQgTlBFIGluIG91dHB1dCBoYW5kbGVyLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0ieHNsdGMiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjAvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjIFRyYW5zbGV0T3V0cHV0SGFuZGxlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBWYXJpYWJsZS5qYXZhCi0gVmFyaWFibGVSZWYuamF2YSBWYXJpYWJsZVJlZkJhc2UuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbAotIE11bHRpSGFzaHRhYmxlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBET01JbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgQmFzaXNMaWJyYXJ5LmphdmEKLSBUZXh0T3V0cHV0LmphdmEgVHJhbnNsZXRPdXRwdXRCYXNlLmphdmE8L01vZGlmaWVkPgotPExvZz5BZGRlZCBlbGVtZW50L2F0dHJpYnV0ZSBwcmVmaXggaW5mb3JtYXRpb24gaW4gdGhlIGludGVybmFsIERPTS4KLSBUaGlzIHNob3VsZCBmaXggc29tZSBwcm9ibGVtcyB3ZSBoYXZlIGhhZCB3aXRoIHRoZSBjb3B5IGFuZCBjb3B5LW9mCi0gZWxlbWVudHMuIEFkZGVkIGEgZmV3IGxpbmVzIG9mIGNvZGUgaW4gYW4gYXR0ZW1wdCB0byBzcGVlZCB1cCB0aGUgRE9NIGJ1aWxkZXIuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+c2JvYWdAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjAvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIFhQYXRoQ29udGV4dC5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+QWRkZWQgZ2V0Q3VycmVudE5vZGVMaXN0KCkgZm9yIGdldHRpbmcgdGhlIGN1cnJlbnQgbm9kZSBsaXN0IGFzIGRlZmluZWQKLSBieSBodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZS1saXN0LgotIFRoaXMgbG9va3MgdXAgdGhlIHN0YWNrIG9mIHRoZSBTdWJDb250ZXh0TGlzdHMgdG8gZmluZCB0aGUgdG9wLWxldmVsCi0gTG9jUGF0aEl0ZXJhdG9yLiBJJ20gZmFpcmx5IHVuaGFwcHkgd2l0aCB0aGlzIGZpeCwgYW5kIGhvcGUgdG8gcmVzdHJ1Y3R1cmUKLSB0aGUgY29udGV4dCBsaXN0IHN0dWZmIGEgYml0IHRvIGF2b2lkIHRoZSBjYXN0cyBpbiB0aGUgZ2V0Q3VycmVudE5vZGVMaXN0KCksCi0gYW5kIHRvIGZpeCBnZXRDdXJyZW50Tm9kZSgpIHNvIHRoYXQgaXQgcHJvcGVybHkgZGVmaW5lcyB0aGUgY3VycmVudAotIG5vZGUgYXMgZGVmaW5lZCBieSB0aGUgWFNMVCBzcGVjLiBBcyBhIG1hdHRlciBvZiBmYWN0LCBJIHdvdWxkCi0gbGlrZSB0byBicmVhayB1cCBYUGF0aENvbnRleHQgaW50byBhbiBYU0xUQ29udGV4dC4KLSBQYXJ0IG9mIHRoZSBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTMwMzEKLSBmaXguPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9ImNvcmUiPgotPFdobz5zYm9hZ0BhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yMC8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zIEZ1bmNDdXJyZW50LmphdmE8L01vZGlmaWVkPgotPExvZz5DYWxsIG5ldyBYUGF0aENvbnRleHQjZ2V0Q3VycmVudE5vZGVMaXN0LiBGaXhlcwotIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MzAzMS48L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPnNib2FnQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzIwLzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBLZXlSZWZJdGVyYXRvci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIENoaWxkSXRlcmF0b3IuamF2YQotIENoaWxkVGVzdEl0ZXJhdG9yLmphdmEgRGVzY2VuZGFudEl0ZXJhdG9yLmphdmEKLSBNYXRjaFBhdHRlcm5JdGVyYXRvci5qYXZhCi0gU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUuamF2YSBVbmlvblBhdGhJdGVyYXRvci5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+Rml4IGZvciBwcm9ibGVtIHJlcG9ydGVkIGJ5IE1pa2UgU3RhcnIgJmx0O21pa2Uuc3RhcnJAYWlyMndlYi5jb20mZ3Q7LAotIHdoZXJlIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYW5ncyBmb3IgImZvb1syXSB8IGJhbmciCi0gcGF0dGVycywgaS5lLiB1bmlvbnMgd2l0aCBwb3NpdGlvbmFsIHByZWRpY2F0ZXMuIFRoZSBmaXgKLSBpcyB0byBoYXZlIHRoZSBpdGVyYXRvcnMjbmV4dE5vZGUoKSBzZXQgbV9sYXN0RmV0Y2hlZCB0byBEVE0uTlVMTAotIHdoZW4gbV9mb3VuZExhc3QgaXMgZm91bmQgdG8gYmUgdHJ1ZSBvbiBmdW5jdGlvbiBlbnRyeQotIChhZnRlciB0aGUgY2FjaGUgY2hlY2spLiBUaGlzIGFsbG93cyBnZXRDdXJyZW50Tm9kZSgpIHRvCi0gZnVsbGZpbGwgaXQncyBjb250cmFjdCBvZiByZXR1cm5pbmcgbnVsbCBpZiB0aGUgbGFzdCBmZXRjaCB3YXMKLSBudWxsLiBUaGUgYnVnIG9jY3VyZWQgYWZ0ZXIgYW4gb3B0aW1pemF0aW9uIGZvciBwb3NpdGlvbmFsCi0gcHJlZGljYXRlcyB0byBoYXZlIHRoZW0gbm90IGNvbnRpbnVlIHNlYXJjaGluZyBvbmNlCi0gdGhlIHBvc2l0aW9uYWwgbm9kZSB3YXMgZm91bmQsIGJ5IHNldHRpbmcgbV9mb3VuZExhc3QKLSB0byB0cnVlLjwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yMS8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERURE1vbml0b3IuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkFuIGF0dGVtcHQgdG8gb3B0aW1pc2UgdGhlIGJ1aWxkaW5nIG9mIHRoZSBJRCBpbmRleC4gVGhlIHByZXZpb3VzIHZlcnNpb24gb2YKLSB0aGlzIGNvZGUgd291bGQgdHJhdmVyc2UgdGhlIERPTSBvbmNlIGZvciBlYWNoIHR5cGUgb2YgZWxlbWVudCB0aGF0IGhhZCBhCi0gZGVmaW5lZCBJRCBhdHRyaWJ1dGUuIFRoZSBuZXcgdmVyc2lvbiB0cmF2ZXJzZXMgdGhlIERPTSBvbmNlLCBhbmQgbG9va3MgdXAKLSBlYWNoIGVsZW1lbnQncyB0eXBlIGluIGEgaGFzaHRhYmxlIHRvIGRldGVybWluZSBpdHMgSUQgYXR0cmlidXRlIHR5cGUgKGlmIAotYW55KS4KLSBUaGUgbmV3IHZlcnNpb24gb2YgdGhlIGNvZGUgZG9lcyBub3QgdXNlIHN0cmluZyBjb21wYXJpc29ucywgbGlrZSB0aGUgb2xkIG9uZS4KLSBUaGlzIHVwZGF0ZSB3YXMgZG9uZSB0byBjb21wZW5zYXRlIGZvciB0aGUgcG9zc2libGUgcGVyZm9ybWFuY2UgZGVncmFkYXRpb24gb2YKLSBoYXZpbmcgaW1wbGVtZW50ZWQgYW4gZWxlbWVudC9hdHRyaWJ1dGUgcHJlZml4IGFycmF5IGluIHRoZSBpbnRlcm5hbCBET00uCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yMS8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRlbXBsYXRlc0hhbmRsZXJJbXBsLmphdmEgVGVtcGxhdGVzSW1wbC5qYXZhCi0gVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhIFRyYW5zZm9ybWVySW1wbC5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+UHJvdGVjdGVkIHNvbWUgbWV0aG9kcyBpbiBvdXIgVHJBWCBjb2RlIHRoYXQgYXJlIG5vdCBkZWZpbmVkIGluIHRoZSBUckFYIEFQSS4KLSBUaGVzZSBtZXRob2RzIHdlcmUgbmV2ZXIgaW50ZW5kZWQgZm9yIHB1YmxpYyB1c2UgYW5kIHNob3VsZCBoYXZlIGJlZW4gZGVmaW5lZAotIGFzICJwcm90ZWN0ZWQiIHRvIGJlZ2luIHdpdGguCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yMi8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgWHNsRWxlbWVudC5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+Rml4IGZvciBhIHByb2JsZW0gd2l0aCBzb21lIGNvbWJpbmF0aW9ucyBvZiAmbHQ7eHNsOmVsZW1lbnQmZ3Q7IGFuZCBuYW1lc3BhY2UKLSBhbGlhc2luZy4gVGhlIG91dHB1dCBsYWNrZWQgdGhlIG5lY2Vzc2FyeSBuYW1lc3BhY2UgZGVmaW5pdGlvbnMgd2hlbiBhbgotIGVsZW1lbnQgY3JlYXRlZCB3aXRoICZsdDt4c2w6ZWxlbWVudCZndDsgd2FzIGdpdmVuIGEgcW5hbWUgd2l0aCBhIHByZWZpeCB0aGF0Ci0gd2FzIG1hcHBlZCB0byBzb21lIG90aGVyIHByZWZpeC4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+dG1pbGxlckBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yMy8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgUGFyYW1ldGVyUmVmLmphdmE8L01vZGlmaWVkPgotPExvZz5yZW1vdmVkIHR5cGVDaGVjaygpLCB1c2VzIHRoZSBiYXNlIGNsYXNzZXMgbWV0aG9kIG5vdzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPnRtaWxsZXJAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjMvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyCi0gVmFyaWFibGVSZWZCYXNlLmphdmE8L01vZGlmaWVkPgotPExvZz5hZGRlZCBkZWZhdWx0IHR5cGVDaGVjaygpIHRvIHRoaXMgYmFzZSBjbGFzczwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPnRtaWxsZXJAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjMvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFJlbGF0aW9uYWxFeHByLmphdmE8L01vZGlmaWVkPgotPExvZz5idWcgZml4IDI4MzgsIGNhc3QgdG8gdHlwZSByZWFsIGlmIGJvdGggb3BlcmFuZHMgYXJlCi0gUmVzdWx0VHJlZVR5cGU8L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPmpvaG5nQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzI0LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIFNRTERvY3VtZW50LmphdmE8L01vZGlmaWVkPgotPExvZz5SZW1vdmVkIGRlYnVnIGZsYWcKLSBTdWJtaXR0ZWQgYnk6Sm9obiBHZW50aWxpbjwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+am9obmdAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjQvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgU1FMRG9jdW1lbnQuamF2YQotIFhDb25uZWN0aW9uLmphdmE8L01vZGlmaWVkPgotPExvZz5GaXhlZCBTdHJlYW1pbmcgTW9kZQotIFN1Ym1pdHRlZCBieTogSm9obiBHZW50aWxpbjwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+am9obmdAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjQvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0gRFRNLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTURlZmF1bHRCYXNlLmphdmEKLSBEVE1Eb2N1bWVudEltcGwuamF2YSBEVE1NYW5hZ2VyRGVmYXVsdC5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+YWRkZWQgZG9jdW1lbnQgcmVnaXN0cmF0aW9uIGFuZCByZWxlYXNlIGV2ZW50cyB0byB0aGUgRFRNIGludGVyZmFjZQotIFN1Ym1pdHRlZCBieTogSm9obiBHZW50aWxpbjwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+Z2FyeXBAYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjUvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYiBFeHRlbnNpb25zLmphdmE8L01vZGlmaWVkPgotPExvZz5GaXggYnVnIDMxMTIgKGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MzExMikuIEZpeCAKLXRva2VuaXplIHRvIHdvcmsgd2l0aCBEVE0gYnkgb2J0YWluaW5nIGEgbmV3IERvY3VtZW50QnVpbGRlciBhbmQgbm90IHVzaW5nIHRoZSAKLWRvY3VtZW50IGZyb20gdGhlIGNvbnRleHQgbm9kZS48L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPmdhcnlwQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzI2LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aCBWYXJpYWJsZVN0YWNrLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMgVmFyaWFibGUuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkZpeCBidWcgMzI2NSAoaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0zMjY1KS4gVXNpbmcgCi1hbiBleHByZXNzaW9uIGluIHRoZSBldmFsdWF0ZSBleHRlbnNpb24gZnVuY3Rpb24gdGhhdCBjb250YWlucyBhIHRvcC1sZXZlbCAKLXZhcmlhYmxlIHdhcyBjYXVzZSBhbiBOUEUuPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9ImNvcmUiPgotPFdobz5zYm9hZ0BhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yNi8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cyBYU3RyaW5nRm9yQ2hhcnMuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkZpeGVkIHR3byBidWdzLCBvbmUgaW4gZ2V0Q2hhcnMgYW5kIG9uZSBpbiBjaGFyQXQgd2hlcmUgdGhlIG1fc3RhcnQKLSBvZmZzZXQgd2Fzbid0IGJlaW5nIHVzZWQgY29ycmVjdGx5LiBUaGlzIG1hbmlmZXN0ZWQgaXRzZWxmIGluIHNvbWUKLSBzdHVmZiBJIHdhcyBkb2luZyB3aXRoIHRoZSBzdGFydHNXaXRoIGZ1bmN0aW9uLCBidXQgbGlrZWx5IGNhdXNlZAotIG1hbnkgb3RoZXIgYnVncyB3aXRoIG90aGVyIGZ1bmN0aW9uYWxpdHkuPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzI3LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBET00uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIKLSBBYnNvbHV0ZUxvY2F0aW9uUGF0aC5qYXZhIEFic29sdXRlUGF0aFBhdHRlcm4uamF2YQotIEFuY2VzdG9yUGF0dGVybi5qYXZhIEFwcGx5VGVtcGxhdGVzLmphdmEKLSBCb29sZWFuRXhwci5qYXZhIENhbGxUZW1wbGF0ZS5qYXZhIENhc3RFeHByLmphdmEKLSBDb25zdGFudHMuamF2YSBDb3B5LmphdmEgQ29weU9mLmphdmEKLSBEb2N1bWVudENhbGwuamF2YSBGaWx0ZXJFeHByLmphdmEKLSBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoLmphdmEgRm9yRWFjaC5qYXZhCi0gRnVuY3Rpb25DYWxsLmphdmEgS2V5LmphdmEgS2V5Q2FsbC5qYXZhCi0gTGFzdENhbGwuamF2YSBMb2NhbE5hbWVDYWxsLmphdmEgTW9kZS5qYXZhCi0gTmFtZUNhbGwuamF2YSBOYW1lc3BhY2VVcmlDYWxsLmphdmEgTnVtYmVyLmphdmEKLSBQYXJhbS5qYXZhIFBhcmFtZXRlclJlZi5qYXZhCi0gUGFyZW50TG9jYXRpb25QYXRoLmphdmEgUGFyZW50UGF0dGVybi5qYXZhCi0gUG9zaXRpb25DYWxsLmphdmEgUHJlZGljYXRlLmphdmEKLSBSZWxhdGlvbmFsRXhwci5qYXZhIFNvcnQuamF2YSBTdGVwLmphdmEKLSBTdGVwUGF0dGVybi5qYXZhIFN0eWxlc2hlZXQuamF2YQotIFN5bnRheFRyZWVOb2RlLmphdmEgVGVtcGxhdGUuamF2YSBUZXN0U2VxLmphdmEKLSBUZXh0LmphdmEgVHJhbnNsZXRPdXRwdXQuamF2YSBWYWx1ZU9mLmphdmEKLSBWYXJpYWJsZS5qYXZhIFZhcmlhYmxlUmVmLmphdmEgV2hpdGVzcGFjZS5qYXZhCi0gWFNMVEMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbAotIENsYXNzR2VuZXJhdG9yLmphdmEgRXJyb3JNc2cuamF2YQotIE1ldGhvZEdlbmVyYXRvci5qYXZhIE5vZGVTZXRUeXBlLmphdmEgTm9kZVR5cGUuamF2YQotIFJlc3VsdFRyZWVUeXBlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBBeGlzLmphdmEKLSBET01BZGFwdGVyLmphdmEgRE9NSW1wbC5qYXZhIExvYWREb2N1bWVudC5qYXZhCi0gTXVsdGlET00uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YSBCYXNpc0xpYnJhcnkuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkNoYW5nZXMgYWxsIGNhbGxzIGZyb20gdGhlIGNvbXBpbGVkIHRyYW5zbGV0IGNvZGUgdG8gdGhlIERPTSB0byBiZSBjYWxscwotIHRvIHRoZSBET00gaW50ZXJmYWNlIChhbmQgbm90IHRvIGEgc3BlY2lmaWMgRE9NIGNsYXNzKS4gSSBkaWQgdGhpcyB0byBtYWtlCi0gaXQgcG9zc2libGUgdG8gcGx1Z2kgaW4gYW55IERPTSBpbXBsZW1lbnRhdGlvbi4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9ImNvcmUiPgotPFdobz5tb3J0ZW5AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjcvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxBZGRlZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjIFN0cmlwRmlsdGVyLmphdmE8L0FkZGVkPgotPExvZz5Gb3Jnb3QgdG8gYWRkIHRoaXMgZmlsZSBpbiBteSBsYXN0IHB1dGJhY2suCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yNy8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMgVHJhbnNsZXRPdXRwdXRIYW5kbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIENvbnN0YW50cy5qYXZhCi0gVHJhbnNsZXRPdXRwdXQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YSBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhCi0gVGV4dE91dHB1dC5qYXZhIFRyYW5zbGV0T3V0cHV0QmFzZS5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+QWRkZWQgYW4gJmx0O3hzbHRjOm91dHB1dCZndDsgZXh0ZW5zaW9uIHRvIGFsbG93IGZvciBtdWx0aXBsZSBvdXRwdXQgZmlsZXMuIEkga25vdwotIHRoYXQgdGhpcyBpcyBub3QgYSBwcmlvcml0aXNlZCB0YXNrLCBidXQgSSBuZWVkIHRoaXMgZm9yIGEgbGl0dGxlIHByb2plY3QgSQotIGFtIHdvcmtpbmcgb24uCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJ4c2x0YyI+Ci08V2hvPm1vcnRlbkBhcGFjaGUub3JnPC9XaG8+Ci08RGF0ZUNvbW1pdHRlZD4wOC8yOC8yMDAxPC9EYXRlQ29tbWl0dGVkPgotPE1vZGlmaWVkPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgUGFyYW0uamF2YQotIFBhcmFtZXRlclJlZi5qYXZhIFZhcmlhYmxlLmphdmEgVmFyaWFibGVCYXNlLmphdmEKLSBWYXJpYWJsZVJlZi5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsCi0gTm9kZVNldFR5cGUuamF2YSBOb2RlVHlwZS5qYXZhIFJlZmVyZW5jZVR5cGUuamF2YQotIFJlc3VsdFRyZWVUeXBlLmphdmEgU3RyaW5nVHlwZS5qYXZhIFR5cGUuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkEgZmV3IGZpeGVzIGZvciB0aGUgcmVncmVzc2lvbiBjYXVzZWQgYnkgbXkgbGFzdCAoaHVnZSkgcHV0YmFjay4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPC9Mb2c+Ci08L0NvbW1pdD4KLTxDb21taXQgY2F0ZWdvcnk9InhzbHRjIj4KLTxXaG8+bW9ydGVuQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzI4LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRHVwRmlsdGVySXRlcmF0b3IuamF2YTwvTW9kaWZpZWQ+Ci08TG9nPkEgZml4IGZvciB0aGUgcG9zaXRpb24oKSBmdW5jdGlvbiB3aGVuIHVzaW5nIGR1cGxpY2F0ZSBmaWx0ZXIgaXRlcmF0b3JzLgotIFBSOiBuLwotIE9idGFpbmVkIGZyb206IE4vQQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzwvTG9nPgotPC9Db21taXQ+Ci08Q29tbWl0IGNhdGVnb3J5PSJjb3JlIj4KLTxXaG8+amtlc3NlbG1AYXBhY2hlLm9yZzwvV2hvPgotPERhdGVDb21taXR0ZWQ+MDgvMjgvMjAwMTwvRGF0ZUNvbW1pdHRlZD4KLTxNb2RpZmllZD5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTURlZmF1bHRCYXNlLmphdmE8L01vZGlmaWVkPgotPExvZz5hZGRlZCBkdW1wTm9kZSBtZXRob2QsIGNvbnZlbmllbmNlIGZvciBkZWJ1Z2dpbmcuCi0KLSBXZSBtaWdodCB3YW50IHRvIG1vdmUgdGhpcyBmdW5jdGlvbiB1cCB0byBEVE1EZWZhdWx0QmFzZSwgb3IKLSBwZXJoYXBzIHRvIHRoZSBEVE0gQVBJIGl0c2VsZi48L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPnNib2FnQGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzI4LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUgU2VyaWFsaXplclRvVGV4dC5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+Rml4IGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MzEzMSBieQotIG92ZXJyaWRpbmcgd3JpdGVOb3JtYWxpemVkQ2hhcnMgYW5kIHdyaXRlVVRGMTZTdXJyb2dhdGUgdG8KLSBub3QgZG8gYW55IFhNTCBlc2NhcGluZy48L0xvZz4KLTwvQ29tbWl0PgotPENvbW1pdCBjYXRlZ29yeT0iY29yZSI+Ci08V2hvPm1taWR5QGFwYWNoZS5vcmc8L1dobz4KLTxEYXRlQ29tbWl0dGVkPjA4LzI4LzIwMDE8L0RhdGVDb21taXR0ZWQ+Ci08TW9kaWZpZWQ+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBEVE1EZWZhdWx0QmFzZS5qYXZhPC9Nb2RpZmllZD4KLTxMb2c+VGhlIGluZGV4IHdhcyBiZWluZyBzdG9yZWQgYXMgb3Bwb3NlZCB0byB0aGUgbm9kZSBoYW5kbGUgd2hlbiB3ZSB3ZXJlIAotcmVwbGFjaW5nIG5hbWVzcGFjZSBub2Rlcy4gU3RvcmUgdGhlIGFjdHVhbCBub2RlIGhhbmRsZS48L0xvZz4KLTwvQ29tbWl0PgotPC9Db21taXRzPgpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9jb21wYXRPdmVydmlldy5odG1sIGIvY29tcGF0X3NyYy9jb21wYXRPdmVydmlldy5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZjY0ODE3Li4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvY29tcGF0T3ZlcnZpZXcuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDI5ICswLDAgQEAKLTxIVE1MPjxIRUFEPjwvSEVBRD48Qk9EWT4KLSAgICA8UD5UaGlzIGNvbXBhdGliaWxpdHkgQVBJIHN1cHBvcnRzIGxpbWl0ZWQgdXNlIG9mIHRoZSBYYWxhbi1KYXZhIDEgQVBJIGluIHRoZSBYYWxhbi1KYXZhIDIgZW52aXJvbm1lbnQuIEZvciB0aGUgWGFsYW4tSmF2YSAyIEFQSSwgc2VlIDxBIGhyZWY9Ii4uL2FwaWRvY3MvaW5kZXguaHRtbCIgdGFyZ2V0PSJfdG9wIj5YYWxhbi1KYXZhIDIgQVBJPC9BPi48L1A+Ci0gIAotICAgICA8UD48Qj5CYXNpYyBwcm9jZWR1cmUgZm9yIHBlcmZvcm1pbmcgdHJhbnNmb3JtYXRpb25zOjwvQj48L1A+Ci0gICAgPE9MPgotICAgICAgPExJPlVzZSBvbmUgb2YgdGhlIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFByb2Nlc3NvckZhY3Rvcnl9IHN0YXRpYyBnZXRQcm9jZXNzb3IgbWV0aG9kcyB0bwotICAgICAgaW5zdGFudGlhdGUgYW4ge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUHJvY2Vzc29yfS48QlI+PEJSPgotICAgICAgIFRoZSBYU0xUIGFuZCBYUGF0aCBlbmdpbmVzIGFyZSBpbmRlcGVuZGVudCBmcm9tIGFueSBnaXZlbiBET00gb3IgWE1MIGltcGxlbWVudGF0aW9uLiBBbGwgcGFyc2VyLWRlcGVuZGVudAotICAgICAgIGNhbGxzIGFyZSBmdW5uZWxlZCB0aHJvdWdoIHRoZSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuWE1MUGFyc2VyTGlhaXNvbn0uPEJSPjxCUj48L0xJPiAgICAgCi0gICAgICAgPExJPlNldCB1cCB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRJbnB1dFNvdXJjZX0gb2JqZWN0cyBmb3IgdGhlIFhNTCBpbnB1dCBhbmQgWFNMIHN0eWxlc2hlZXQuIAotICAgICAgIFlvdSBjYW4gdXNlIGEgZmlsZSBuYW1lIG9yIFVSTCwgY2hhcmFjdGVyIHN0cmVhbSwgYnl0ZSBzdHJlYW0sIG9yIFNBWCBpbnB1dCBzdHJlYW0gdG8gaW5zdGFudGlhdGUgYW4KLSAgICAgICBYU0xUSW5wdXRTb3VyY2Ugb2JqZWN0LjxCUj48QlI+Ci0gICAgICAgSWYgdGhlIFhNTCBkb2N1bWVudCBjb250YWlucyBhIHN0eWxlc2hlZXQgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbiAoUEkpLCB5b3UgZG8gbm90IG5lZWQgdG8gY3JlYXRlIGEgc2VwYXJhdGUKLSAgICAgICBYU0xUSW5wdXRTb3VyY2Ugb2JqZWN0IGZvciBhbiBYU0wgc3R5bGVzaGVldC48QlI+PEJSPgotICAgICAgIDxCPk5vdGU6PC9CPiBGb3IgaW1wcm92ZWQgcGVyZm9ybWFuY2Ugd2l0aCBhIHNlcmllcyBvZiB0cmFuc2Zvcm1hdGlvbnMsIHVzZSB0aGUgWFNMVFByb2Nlc3NvcgotICAgICAgIHByb2Nlc3NTdHlsZXNoZWV0IG1ldGhvZCB0byBjb21waWxlIHRoZSBYU0wgc3R5bGVzaGVldC4gVGhlIHJlc3VsdCBpcyBhIAotICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuU3R5bGVzaGVldFJvb3R9IG9iamVjdCB3aXRoIGl0cyBvd24gcHJvY2VzcygpIG1ldGhvZCBmb3IgcGVyZm9ybWluZyB0cmFuc2Zvcm1hdGlvbnMuCi0gICAgICAgIENvbXBpbGluZyB0aGUgc3R5bGVzaGVldCBpcyBhbHNvIHVzZWZ1bCB3aGVuIHlvdSBuZWVkIHRvIGdldCBpbmZvcm1hdGlvbiBmcm9tIHRoZQotICAgICAgIHN0eWxlc2hlZXQgYmVmb3JlIHRoZSB0cmFuc2Zvcm1hdGlvbiBvY2N1cnMuIFlvdSBhbHNvIG11c3QgY29tcGlsZSB0aGUgc3R5bGVzaGVldCBpZiB5b3UgYXJlIHVzaW5nIHRoZQotICAgICAgICBYU0xUUHJvY2Vzc29yIGFzIGEgU0FYIGRvY3VtZW50IGhhbmRsZXIuPEJSPjxCUj48L0xJPgotICAgICAgIDxMST5TZXQgdXAgYW4ge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUmVzdWx0VGFyZ2V0fSBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uIG91dHB1dC4gWW91IGNhbiB1c2UgYQotICAgICAgIGZpbGUgbmFtZSBvciBVUkwsIGNoYXJhY3RlciBzdHJlYW0sIGJ5dGUgc3RyZWFtLCBvciBTQVggZG9jdW1lbnQgaGFuZGxlciB0byBpbnN0YW50aWF0ZSBhbiBYU0xUUmVzdWx0VGFyZ2V0Ci0gICAgICAgb2JqZWN0LjxCUj48QlI+PC9MST4KLSAgICAgICA8TEk+VXNlIHRoZSBYU0xUUHJvY2Vzc29yIG9yIChpZiB5b3UgaGF2ZSBjb21waWxlZCB0aGUgc3R5bGVzaGVldCkgdGhlKEBsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5TdHlsZXNoZWV0Um9vdH0KLSAgICAgICBwcm9jZXNzIG1ldGhvZCB0byBwZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbi48QlI+PEJSPgotICAgICAgICBYYWxhbi1KYXZhIGlzIHRocmVhZC1zYWZlIGZvciBvbmUgaW5zdGFuY2UgcGVyIHRocmVhZC4gSWYgeW91IGFyZSB1c2luZyB0aGUgc2FtZSBpbnN0YW5jZSBvZiBYU0xUUHJvY2Vzc29yIHRvCi0gICAgICAgICBwZXJmb3JtIG1vcmUgdGhhbiBvbmUgdHJhbnNmb3JtYXRpb24sIGNhbGwgdGhlIHJlc2V0IG1ldGhvZCBiZXR3ZWVuIHRyYW5zZm9ybWF0aW9ucy48L0xJPgotICAgIDwvT0w+Ci0gIDwvQk9EWT48L0hUTUw+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hCb29sZWFuLmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWEJvb2xlYW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDBlNzJlZC4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWEJvb2xlYW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBYUGF0aCBib29sZWFuIG9iamVjdCwgYW5kIGlzIGNhcGFibGUgb2YgCi0gKiBjb252ZXJ0aW5nIHRoZSBib29sZWFuIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYQm9vbGVhbiBleHRlbmRzIFhPYmplY3QKLXsKLSAgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuIG1feGJvb2xlYW47Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0IGEgWEJvb2xlYW4gb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhCb29sZWFuKGJvb2xlYW4gYikKLSAgewotICAgIHN1cGVyKCk7IAotICAgICBtX3hib29sZWFuID0gbmV3IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbihiKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgdGhhdCB0aGlzIGlzIGEgQ0xBU1NfQk9PTEVBTi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gbV94Ym9vbGVhbi5nZXRUeXBlKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4gCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkgLy8gUFI6RE1BTjRNQko0RCBTdWJtaXR0ZWQgYnk6PGdhcnlwQGZpcnN0ZWNoLmNvbT4gY2hhbmdlIHRvIHByb3RlY3RlZAotICB7Ci0gICAgcmV0dXJuIG1feGJvb2xlYW4uZ2V0VHlwZVN0cmluZygpOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKQotICB7Ci0gICAgcmV0dXJuIG1feGJvb2xlYW4ubnVtKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKQotICB7Ci0gICAgcmV0dXJuIG1feGJvb2xlYW4uYm9vbCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIHJldHVybiBtX3hib29sZWFuLnN0cigpOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIGEgamF2YSBvYmplY3QgdGhhdCdzIGNsb3NlcyB0byB0aGUgcmVwcmVzZW5hdGlvbiAKLSAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLSAgICovCi0gIHB1YmxpYyBPYmplY3Qgb2JqZWN0KCkKLSAgewotICAgIHJldHVybiBtX3hib29sZWFuLm9iamVjdCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7ICAgIAotICAgIHJldHVybiBtX3hib29sZWFuLmVxdWFscyhvYmoyKTsKLSAgfQotICAKLSAgCi19Ci0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YQm9vbGVhblN0YXRpYy5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hCb29sZWFuU3RhdGljLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ2NjliY2EuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hCb29sZWFuU3RhdGljLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgZG9lc24ndCBoYXZlIGFueSBYUGF0aFN1cHBvcnQsIHNvIG92ZXJyaWRlIAotICogd2hhdGV2ZXIgdG8gZW5zdXJlIGl0IHdvcmtzIE9LLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYQm9vbGVhblN0YXRpYyBleHRlbmRzIFhCb29sZWFuCi17Ci0gIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhblN0YXRpYyBtX3hib29sZWFuOwotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhOb2RlU2V0IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYQm9vbGVhblN0YXRpYyhib29sZWFuIGIpCi0gIHsKLSAgICBzdXBlcihiKTsgCi0gICAgbV94Ym9vbGVhbiA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW5TdGF0aWMoYik7Ci0gIH0gCi0gIAotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV94Ym9vbGVhbi5lcXVhbHMob2JqMik7Ci0gIH0KLQotfQotCmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWE5vZGVTZXQuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YTm9kZVNldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MTk2OTBjLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YTm9kZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzU5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGg7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcjsKLWltcG9ydCBqYXZhLnRleHQuKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkRPTUhlbHBlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIG5vZGVzZXQgb2JqZWN0LCBhbmQgaXMgY2FwYWJsZSBvZiAKLSAqIGNvbnZlcnRpbmcgdGhlIG5vZGVzZXQgdG8gb3RoZXIgdHlwZXMsIHN1Y2ggYXMgYSBzdHJpbmcuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhOb2RlU2V0IGV4dGVuZHMgWE9iamVjdCAgCi17Ci0gIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldCBtX3hub2Rlc2V0OwotICBEVE1NYW5hZ2VyRGVmYXVsdCBkdG1NZ3IgPSBuZXcgRFRNTWFuYWdlckRlZmF1bHQoKTsgCi0gIAotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhOb2RlU2V0KE5vZGVMaXN0IHZhbCkKLSAgewotICAgIHN1cGVyKCk7Ci0gICAgaW50IG5vZGUgPSBkdG1NZ3IuZ2V0RFRNSGFuZGxlRnJvbU5vZGUodmFsLml0ZW0oMCkpOwotICAgIG1feG5vZGVzZXQgPSBuZXcgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0KGR0bU1nci5jcmVhdGVEVE1JdGVyYXRvcihub2RlKSkgOwotICB9Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGVtcHR5IFhOb2RlU2V0IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTm9kZVNldCgpCi0gIHsKLSAgICBzdXBlcigpOwotICAgIG1feG5vZGVzZXQgPSBuZXcgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0KGR0bU1ncik7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0IGZvciBvbmUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBYTm9kZVNldChOb2RlIG4pCi0gIHsKLSAgICBzdXBlcihuKTsgICAgCi0gICAgbV94bm9kZXNldCA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE5vZGVTZXQoZHRtTWdyLmdldERUTUhhbmRsZUZyb21Ob2RlKG4pLCBkdG1NZ3IpOwotICB9Ci0gIAotICAKLSAgLyoqCi0gICAqIFRlbGwgdGhhdCB0aGlzIGlzIGEgQ0xBU1NfTk9ERVNFVC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gbV94bm9kZXNldC5nZXRUeXBlKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4gCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkgLy8gUFI6RE1BTjRNQko0RCBTdWJtaXR0ZWQgYnk6PGdhcnlwQGZpcnN0ZWNoLmNvbT4gY2hhbmdlIHRvIHByb3RlY3RlZAotICB7Ci0gICAgcmV0dXJuIG1feG5vZGVzZXQuZ2V0VHlwZVN0cmluZygpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIGEgc2luZ2xlIG5vZGUuCi0gICAqLwotICBkb3VibGUgZ2V0TnVtYmVyRnJvbU5vZGUoTm9kZSBuKQotICB7Ci0gICAgcmV0dXJuIG1feG5vZGVzZXQuZ2V0TnVtYmVyRnJvbU5vZGUoZHRtTWdyLmdldERUTUhhbmRsZUZyb21Ob2RlKG4pKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gIHsKLSAgICByZXR1cm4gbV94bm9kZXNldC5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gbV94bm9kZXNldC5ib29sKCk7Ci0gIH0KLSAgCi0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSBhIHNpbmdsZSBub2RlLgotICAgKi8KLSAgc3RhdGljIFN0cmluZyBnZXRTdHJpbmdGcm9tTm9kZShOb2RlIG4pCi0gIHsKLSAgICBzd2l0Y2ggKG4uZ2V0Tm9kZVR5cGUoKSkKLSAgICB7Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOgotICAgICAgcmV0dXJuIERPTUhlbHBlci5nZXROb2RlRGF0YShuKTsKLSAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICBjYXNlIE5vZGUuVEVYVF9OT0RFIDoKLSAgICAgIHJldHVybiAoKFRleHQpIG4pLmdldERhdGEoKTsKLSAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLSAgICBjYXNlIE5vZGUuQVRUUklCVVRFX05PREUgOgotICAgICAgcmV0dXJuIG4uZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICByZXR1cm4gRE9NSGVscGVyLmdldE5vZGVEYXRhKG4pOwotICAgIH0KLSAgfQotICAKLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIG1feG5vZGVzZXQuc3RyKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoU3VwcG9ydCBzdXBwb3J0KQotICB7ICAgIAotICAgIHJldHVybiBydHJlZSgoWFBhdGhDb250ZXh0KSBzdXBwb3J0KTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uIAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBub2Rlc2V0IGFzIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBydHJlZShYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotICAgIG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0IGNvbnRleHQgPSAob3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQpc3VwcG9ydDsKLSAgICByZXR1cm4gbV94bm9kZXNldC5ydHJlZShjb250ZXh0KTsKLSAgICAvL3JldHVybiAoRG9jdW1lbnRGcmFnbWVudCljb250ZXh0LmdldERUTU1hbmFnZXIoKS5nZXREVE0ocmVzdWx0KS5nZXROb2RlKHJlc3VsdCk7ICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG5vZGVsaXN0LgotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IG5vZGVzZXQoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBEVE1Ob2RlTGlzdChtX3hub2Rlc2V0Lml0ZXIoKSk7Ci0gIH0gIAotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4KLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBtdXRhYmxlTm9kZXNldCgpCi0gIHsKLSAgIHJldHVybiBuZXcgRFRNTm9kZUxpc3QobV94bm9kZXNldC5tdXRhYmxlTm9kZXNldCgpKTsKLSAgfSAgCi0gIAotICAvKioKLSAgICogVGVsbCBpZiBvbmUgb2JqZWN0IGlzIGxlc3MgdGhhbiB0aGUgb3RoZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbihYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feG5vZGVzZXQubGVzc1RoYW4ob2JqMi5tX3hPYmplY3QpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiBvbmUgb2JqZWN0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgb3RoZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBtX3hub2Rlc2V0Lmxlc3NUaGFuT3JFcXVhbChvYmoyLm1feE9iamVjdCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIHRoZSBvdGhlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdyZWF0ZXJUaGFuKFhPYmplY3Qgb2JqMikKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV94bm9kZXNldC5ncmVhdGVyVGhhbihvYmoyLm1feE9iamVjdCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIHRoZSBvdGhlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdyZWF0ZXJUaGFuT3JFcXVhbChYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feG5vZGVzZXQuZ3JlYXRlclRoYW5PckVxdWFsKG9iajIubV94T2JqZWN0KTsKLSAgfSAgIAotICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feG5vZGVzZXQuZXF1YWxzKG9iajIpOwotICB9ICAKLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgbm90IGVxdWFsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbm90RXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV94bm9kZXNldC5ub3RFcXVhbHMob2JqMi5tX3hPYmplY3QpOwotICB9ICAKLSAKLSBzdGF0aWMgY2xhc3MgTm9kZUl0ZXJhdG9yV3JhcHBlciBleHRlbmRzIG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTQotICB7Ci0KLSAgICAvKiogUG9zaXRpb24gb2YgbmV4dCBub2RlICAgICAgICAgICovCi0gICAgcHJpdmF0ZSBpbnQgbV9wb3MgPSAwOwotCi0gICAgLyoqIERvY3VtZW50IGZyYWdtZW50IGluc3RhbmNlIHRoaXMgd2lsbCB3cmFwICAgICAgICAgKi8KLSAgICBwcml2YXRlIE5vZGVMaXN0IG1fbGlzdDsKLSAgICBwcml2YXRlIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyIGR0bU1hbmFnZXI7IAotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgTm9kZUl0ZXJhdG9yV3JhcHBlcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZGYgRG9jdW1lbnQgZnJhZ21lbnQgaW5zdGFuY2UgdGhpcyB3aWxsIHdyYXAKLSAgICAgKi8KLSAgICBOb2RlSXRlcmF0b3JXcmFwcGVyKE5vZGVMaXN0IGxpc3QpCi0gICAgewotICAgICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQoKSk7Ci0gICAgICBtX2xpc3QgPSBsaXN0OwotICAgICAgZHRtTWFuYWdlciA9IGdldERUTU1hbmFnZXIoKTsgCi0gICAgfQotCi0gIAotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgICAqIGl0ZXJhdG9yIGluIHRoZSBzZXQuIEFmdGVyIGEgTm9kZUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KLSAgICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgICAqICAgPGNvZGU+ZGV0YWNoPC9jb2RlPiBtZXRob2Qgd2FzIGludm9rZWQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0Tm9kZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgIE5vZGUgbjsKLSAgICAgIGlmIChtX3BvcyA8IG1fbGlzdC5nZXRMZW5ndGgoKSkKLSAgICAgIHsKLSAgICAgICBuID0gbV9saXN0Lml0ZW0obV9wb3MrKyk7Ci0gICAgICAgcmV0dXJuIGR0bU1hbmFnZXIuZ2V0RFRNSGFuZGxlRnJvbU5vZGUobik7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBSZXR1cm5zIHRoZSBwcmV2aW91cyBub2RlIGluIHRoZSBzZXQgYW5kIG1vdmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICAgKiBpdGVyYXRvciBiYWNrd2FyZHMgaW4gdGhlIHNldC4KLSAgICAgKiBAcmV0dXJuICBUaGUgcHJldmlvdXMgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLAotICAgICAqICAgb3I8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAgICogICAgSU5WQUxJRF9TVEFURV9FUlI6IFJhaXNlZCBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgdGhlCi0gICAgICogICA8Y29kZT5kZXRhY2g8L2NvZGU+IG1ldGhvZCB3YXMgaW52b2tlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHByZXZpb3VzTm9kZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgIE5vZGUgbjsKLSAgICAgIGlmIChtX3BvcyA+MCkKLSAgICAgIHsKLSAgICAgICAgbiA9IG1fbGlzdC5pdGVtKG1fcG9zLTEpOwotICAgICAgICByZXR1cm4gZHRtTWFuYWdlci5nZXREVE1IYW5kbGVGcm9tTm9kZShuKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqICBEZXRhY2hlcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsIHJlbGVhc2luZwotICAgICAqIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IgaW4gdGhlIElOVkFMSUQKLSAgICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAgICogPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsIHJhaXNlIHRoZQotICAgICAqIGV4Y2VwdGlvbiBJTlZBTElEX1NUQVRFX0VSUi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkZXRhY2goKXt9Ci0gIH0KLSAgCi0KLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YTnVsbC5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hOdWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3ZTQ2YjYuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hOdWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54cGF0aDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggbnVsbCBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mIAotICogY29udmVydGluZyB0aGUgbnVsbCB0byBvdGhlciB0eXBlcywgc3VjaCBhcyBhIHN0cmluZy4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgWE51bGwgZXh0ZW5kcyBYT2JqZWN0Ci17Ci0gIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVsbCBtX3hudWxsOwotICAvKioKLSAgICogQ3JlYXRlIGFuIFhPYmplY3QuCi0gICAqLwotICBwdWJsaWMgWE51bGwoKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgICBtX3hudWxsID0gbmV3IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVsbCgpIDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgd2hhdCBraW5kIG9mIGNsYXNzIHRoaXMgaXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIG1feG51bGwuZ2V0VHlwZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgcmVxdWVzdCB0eXBlLCByZXR1cm4gdGhlIGVxdWl2YWxlbnQgc3RyaW5nLiAKLSAgICogRm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGVTdHJpbmcoKSAvLyBQUjpETUFONE1CSjREIFN1Ym1pdHRlZCBieTo8Z2FyeXBAZmlyc3RlY2guY29tPiBjaGFuZ2UgdG8gcHJvdGVjdGVkCi0gIHsKLSAgICByZXR1cm4gbV94bnVsbC5nZXRUeXBlU3RyaW5nKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gIHsKLSAgICByZXR1cm4gbV94bnVsbC5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gbV94bnVsbC5ib29sKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIG1feG51bGwuc3RyKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoU3VwcG9ydCBzdXBwb3J0KQotICB7Ci0gICAgcmV0dXJuIHJ0cmVlKChYUGF0aENvbnRleHQpc3VwcG9ydCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCBhcyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKi8KLSAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgcnRyZWUoWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLSAgICBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dCBjb250ZXh0ID0gKG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0KXN1cHBvcnQ7Ci0gICAgcmV0dXJuIG1feG51bGwucnRyZWUoY29udGV4dCk7Ci0gICAgLy9yZXR1cm4gKERvY3VtZW50RnJhZ21lbnQpY29udGV4dC5nZXREVE1NYW5hZ2VyKCkuZ2V0RFRNKHJlc3VsdCkuZ2V0Tm9kZShyZXN1bHQpOyAgICAKLSAgfSAKLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuCi0gICAqLwotICBwdWJsaWMgTm9kZUxpc3Qgbm9kZXNldCgpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfSAgCi0gICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLSAgICByZXR1cm4gbV94bnVsbC5lcXVhbHMob2JqMik7Ci0gIH0KLQotICAKLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YTnVtYmVyLmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWE51bWJlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3OWUxYjBkLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YTnVtYmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54cGF0aDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBYUGF0aCBudW1iZXIsIGFuZCBpcyBjYXBhYmxlIG9mIAotICogY29udmVydGluZyB0aGUgbnVtYmVyIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYTnVtYmVyIGV4dGVuZHMgWE9iamVjdAotewotICAKLSAgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXIgbV94bnVtYmVyOwotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhOdW1iZXIoZG91YmxlIGQpCi0gIHsKLSAgICBzdXBlcigpOwotICAgIG1feG51bWJlciA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcihkKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgdGhhdCB0aGlzIGlzIGEgQ0xBU1NfTlVNQkVSLgotICAgKi8KLSAgcHVibGljIGludCBnZXRUeXBlKCkKLSAgewotICAgIHJldHVybiBtX3hudW1iZXIuZ2V0VHlwZSgpOwotICB9Ci0gIAotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuIAotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpIC8vIFBSOkRNQU40TUJKNEQgU3VibWl0dGVkIGJ5OjxnYXJ5cEBmaXJzdGVjaC5jb20+IGNoYW5nZSB0byBwcm90ZWN0ZWQKLSAgewotICAgIHJldHVybiBtX3hudW1iZXIuZ2V0VHlwZVN0cmluZygpOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKQotICB7Ci0gICAgcmV0dXJuIG1feG51bWJlci5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gbV94bnVtYmVyLmJvb2woKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIHJldHVybiBtX3hudW1iZXIuc3RyKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm4gYSBqYXZhIG9iamVjdCB0aGF0J3MgY2xvc2VzIHRvIHRoZSByZXByZXNlbmF0aW9uIAotICAgKiB0aGF0IHNob3VsZCBiZSBoYW5kZWQgdG8gYW4gZXh0ZW5zaW9uLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1feG51bWJlci5vYmplY3QoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE9iamVjdCBvYmoyKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBtX3hudW1iZXIuZXF1YWxzKG9iajIpOwotICB9Ci0gIAotICAKLX0KLQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hPYmplY3QuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YT2JqZWN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEyNjM5YmIuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hPYmplY3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uIAotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGg7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIG9iamVjdCwgYW5kIGlzIGNhcGFibGUgb2YgCi0gKiBjb252ZXJ0aW5nIHRoZSBvYmplY3QgdG8gdmFyaW91cyB0eXBlcywgc3VjaCBhcyBhIHN0cmluZy4KLSAqIFRoaXMgY2xhc3MgYWN0cyBhcyB0aGUgYmFzZSBjbGFzcyB0byBvdGhlciBYUGF0aCB0eXBlIG9iamVjdHMsIAotICogc3VjaCBhcyBYU3RyaW5nLCBhbmQgcHJvdmlkZXMgcG9seW1vcnBoaWMgY2FzdGluZyBjYXBhYmlsaXRpZXMuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhPYmplY3QgZXh0ZW5kcyBPYmplY3QgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgICAgCi17Ci0gIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0IG1feE9iamVjdDsKLSAgCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0KCkKLSAgewotICAgIG1feE9iamVjdCA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdCgpIDsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0KE9iamVjdCBvYmopCi0gIHsKLSAgICBtX3hPYmplY3QgPSBuZXcgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Qob2JqKSA7Ci0gIH0KLSAgCi0gICAgLyoqCi0gICAqIFRlbGwgd2hhdCBraW5kIG9mIGNsYXNzIHRoaXMgaXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIG1feE9iamVjdC5nZXRUeXBlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuIAotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgZ2V0VHlwZVN0cmluZygpIC8vIFBSOkRNQU40TUJKNEQgU3VibWl0dGVkIGJ5OjxnYXJ5cEBmaXJzdGVjaC5jb20+IGNoYW5nZSB0byBwcm90ZWN0ZWQKLSAgewotICAgIHJldHVybiAiI1VOS05PV04iOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCSAgcmV0dXJuIG1feE9iamVjdC5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feE9iamVjdC5ib29sKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIG1feE9iamVjdC5zdHIoKTsKLSAgfQotICAKLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV94T2JqZWN0LnRvU3RyaW5nKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoU3VwcG9ydCBzdXBwb3J0KQotICB7Ci0gICAgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQgY29udGV4dCA9IChvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dClzdXBwb3J0OwotICAgIHJldHVybiBtX3hPYmplY3QucnRyZWUoY29udGV4dCk7Ci0gICAgLy9yZXR1cm4gIChEb2N1bWVudEZyYWdtZW50KWNvbnRleHQuZ2V0RFRNTWFuYWdlcigpLmdldERUTShyZXN1bHQpLmdldE5vZGUocmVzdWx0KTsgICAgICAgICAKLSAgfQotICAKLSAgLyoqCi0gICAqIEZvciBmdW5jdGlvbnMgdG8gb3ZlcnJpZGUuCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBydHJlZSgpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiBhIGphdmEgb2JqZWN0IHRoYXQncyBjbG9zZXMgdG8gdGhlIHJlcHJlc2VuYXRpb24gCi0gICAqIHRoYXQgc2hvdWxkIGJlIGhhbmRlZCB0byBhbiBleHRlbnNpb24uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0gIHsKLSAgICByZXR1cm4gbV94T2JqZWN0Lm9iamVjdCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG5vZGVsaXN0LgotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IG5vZGVzZXQoKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULCBuZXcgT2JqZWN0W10ge2dldFR5cGVTdHJpbmcoKX0pOyAvLyJDYW4gbm90IGNvbnZlcnQgIitnZXRUeXBlU3RyaW5nKCkrIiB0byBhIE5vZGVMaXN0ISIpOwotICAgIHJldHVybiBudWxsOwotICB9ICAKLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4KLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBtdXRhYmxlTm9kZXNldCgpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVMaXN0KG1feE9iamVjdC5tdXRhYmxlTm9kZXNldCgpKTsKLSAgfSAgCi0gCi0gIC8qKgotICAgKiBDYXN0IG9iamVjdCB0byB0eXBlIHQuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNhc3RUb1R5cGUoaW50IHQsIFhQYXRoU3VwcG9ydCBzdXBwb3J0KQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgeyAgIAotICAgIHJldHVybiBtX3hPYmplY3QuY2FzdFRvVHlwZSh0LCAob3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQpIHN1cHBvcnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gdGhlIG90aGVyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbGVzc1RoYW4oWE9iamVjdCBvYmoyKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgCi0gICAgcmV0dXJuIG1feE9iamVjdC5sZXNzVGhhbihvYmoyLm1feE9iamVjdCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiBvbmUgb2JqZWN0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgb3RoZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBtX3hPYmplY3QubGVzc1RoYW5PckVxdWFsKG9iajIubV94T2JqZWN0KTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBvdGhlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdyZWF0ZXJUaGFuKFhPYmplY3Qgb2JqMikKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV94T2JqZWN0LmdyZWF0ZXJUaGFuKG9iajIubV94T2JqZWN0KTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBvdGhlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdyZWF0ZXJUaGFuT3JFcXVhbChYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feE9iamVjdC5ncmVhdGVyVGhhbk9yRXF1YWwob2JqMi5tX3hPYmplY3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feE9iamVjdC5lcXVhbHMob2JqMi5tX3hPYmplY3QpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IG5vdCBlcXVhbC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIG5vdEVxdWFscyhYT2JqZWN0IG9iajIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1feE9iamVjdC5ub3RFcXVhbHMob2JqMi5tX3hPYmplY3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbiAKLSAgICogZXhjZXB0aW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoaW50IG1zZykKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQkgIGVycm9yIChtc2csIG51bGwpOwotICB9CSAgIAotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4gCi0gICAqIGV4Y2VwdGlvbi4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGVycm9yKGludCBtc2csIE9iamVjdFtdIGFyZ3MpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UobXNnLCBhcmdzKTsKLQotICAgIAotICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZm1zZyk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hQYXRoU3VwcG9ydC5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hQYXRoU3VwcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZmIxOWYzLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YUGF0aFN1cHBvcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotCi0KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFByb3ZpZGVzIGJhc2ljIHN1cHBvcnQgZm9yIGluZGVwZW5kZW50IHVzZSBvZiBYUGF0aC4gIFRoaXMgaW50ZXJmYWNlIAotICogaXMgdXNlZCBpbiBvcmRlciB0aGF0IHRoZXJlIG1heSBiZSBsb29zZSBjb3VwbGluZyBiZXR3ZWVuIHRoZSAKLSAqIFhQYXRoIHBhY2thZ2UgYW5kIHRoZSBzdXBwb3J0IHNlcnZpY2VzLCBzdWNoIGFzIHRoZSB2YXJpYWJsZSBzdG9yZSwgCi0gKiBwYXJzZXIgc2VydmljZXMsIERPTSBpbXBsZW1lbnRhdGlvbiwgZXRjLiAgTW9zdCBpZiBhbGwgaW1wbGVtZW50YXRpb25zCi0gKiBvZiB0aGlzIHNob3VsZCBkZXJpdmUgZnJvbSBYUGF0aFN1cHBvcnREZWZhdWx0IChoZW5jZSwgaXQgc2hvdWxkIAotICogcHJvYmFibHkgYmUgYW4gYWJzdHJhY3QgY2xhc3MgaW5zdGVhZCBvZiBhbiBpbnRlcmZhY2UpLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFBhdGhTdXBwb3J0IAotewotICAKLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YUGF0aFN1cHBvcnREZWZhdWx0LmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWFBhdGhTdXBwb3J0RGVmYXVsdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiODk4YjMyLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YUGF0aFN1cHBvcnREZWZhdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBEZWZhdWx0IGNsYXNzIGZvciBleGVjdXRpb24gY29udGV4dCB3aGVuIFhQYXRoIGlzIHVzZWQgYnkgaXRzZWxmLiBNYW55IAotICogb2YgdGhlIGZ1bmN0aW9ucyBpbiB0aGlzIGNsYXNzIG5lZWQgdG8gYmUgb3ZlcnJpZGRlbiBpbiBvcmRlciB0byAKLSAqIHBlcmZvcm0gY29ycmVjdCBleGVjdXRpb24gb2YgdGhlIFhQYXRoIChmb3IgaW5zdGFuY2UsIHZhcmlhYmxlIAotICogZXhlY3V0aW9uKS4gIFRoaXMgY2xhc3Mgd2lsbCBsaWtlbHkgZXZlbnR1YWxseSByZXBsYWNlIFhNTFBhcnNlckxpYWlzb25zLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aFN1cHBvcnREZWZhdWx0IGV4dGVuZHMgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQgaW1wbGVtZW50cyBYUGF0aFN1cHBvcnQgCi17Ci0gIAotfQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hSVHJlZUZyYWcuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC9YUlRyZWVGcmFnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5YTI5ODQuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hSVHJlZUZyYWcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIHJlc3VsdCB0cmVlIGZyYWdtZW50IG9iamVjdCwgYW5kIGlzIGNhcGFibGUgb2YgCi0gKiBjb252ZXJ0aW5nIHRoZSBSVEYgdG8gb3RoZXIgdHlwZXMsIHN1Y2ggYXMgYSBzdHJpbmcuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhSVHJlZUZyYWcgZXh0ZW5kcyBYT2JqZWN0IAoteyAKLSAgCi0gIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnIG1feHJ0cmVlZnJhZzsKLSAgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQgY29udGV4dCA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dCgpOwotICAgIAotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYT2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhSVHJlZUZyYWcoRG9jdW1lbnRGcmFnbWVudCBmcmFnKQotICB7Ci0gICAgc3VwZXIoZnJhZyk7ICAgCi0gICAgbV94cnRyZWVmcmFnID0gbmV3IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnKGNvbnRleHQuZ2V0RFRNSGFuZGxlRnJvbU5vZGUoZnJhZyksIGNvbnRleHQpOyAKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgd2hhdCBraW5kIG9mIGNsYXNzIHRoaXMgaXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIG1feHJ0cmVlZnJhZy5nZXRUeXBlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuIAotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpIC8vIFBSOkRNQU40TUJKNEQgU3VibWl0dGVkIGJ5OjxnYXJ5cEBmaXJzdGVjaC5jb20+IGNoYW5nZSB0byBwcm90ZWN0ZWQKLSAgewotICAgIHJldHVybiBtX3hydHJlZWZyYWcuZ2V0VHlwZVN0cmluZygpOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7ICAgIAotICAgIHJldHVybiBtX3hydHJlZWZyYWcubnVtKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKQotICB7Ci0gICAgcmV0dXJuIG1feHJ0cmVlZnJhZy5ib29sKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIG1feHJ0cmVlZnJhZy5zdHIoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKi8KLSAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgcnRyZWUoKQotICB7Ci0gICAgcmV0dXJuIG1feHJ0cmVlZnJhZy5ydHJlZShjb250ZXh0KTsKLSAgICAvL3JldHVybiAgKERvY3VtZW50RnJhZ21lbnQpY29udGV4dC5nZXREVE1NYW5hZ2VyKCkuZ2V0RFRNKHJlc3VsdCkuZ2V0Tm9kZShyZXN1bHQpOyAgICAKLSAgfSAgCi0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIChzcGVjaWFsIGZ1bmN0aW9uKS4KLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBjb252ZXJ0VG9Ob2Rlc2V0KCkKLSAgewotICAgIHJldHVybiAoKERvY3VtZW50RnJhZ21lbnQpdGhpcy5vYmplY3QoKSkuZ2V0Q2hpbGROb2RlcygpOyAgICAKLSAgfSAgCi0gIAotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsgICAKLSAgICAgIHJldHVybiBtX3hydHJlZWZyYWcuZXF1YWxzKG9iajIpOyAgICAKLSAgfQotICAKLSAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWFN0cmluZy5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hTdHJpbmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjBlNzlhZS4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvWFN0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjEzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xICAKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54cGF0aDsKLQotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIHN0cmluZyBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mIAotICogY29udmVydGluZyB0aGUgc3RyaW5nIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgbnVtYmVyLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYU3RyaW5nIGV4dGVuZHMgWE9iamVjdAotewotICAKLSAgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmcgbV94c3RyaW5nOwotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhTdHJpbmcgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhTdHJpbmcoU3RyaW5nIHZhbCkKLSAgewotICAgIHN1cGVyKHZhbCk7Ci0gICAgbV94c3RyaW5nID0gbmV3IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nKHZhbCk7Ci0gIH0KLSAgCi0gICAvKioKLSAgICogVGVsbCB0aGF0IHRoaXMgaXMgYSBDTEFTU19TVFJJTkcuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIG1feHN0cmluZy5nZXRUeXBlKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4gCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkgLy8gUFI6RE1BTjRNQko0RCBTdWJtaXR0ZWQgYnk6PGdhcnlwQGZpcnN0ZWNoLmNvbT4gY2hhbmdlIHRvIHByb3RlY3RlZAotICB7Ci0gICAgcmV0dXJuIG1feHN0cmluZy5nZXRUeXBlU3RyaW5nKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IGEgc3RyaW5nIHRvIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBkb3VibGUgY2FzdFRvTnVtKFN0cmluZyBzKQotICB7ICAKLSAgICBkb3VibGUgcmVzdWx0OwotCi0gICAgaWYgKG51bGwgPT0gcykKLSAgICAgIHJlc3VsdCA9IDAuMDsKLSAgICBlbHNlCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRPRE86IEFkanVzdCB0aGlzIGZvciBsb2NhbGUuIE5lZWQgdG8gdGFrZSBpbnRvCi0gICAgICAgICAqIGFjY291bnQgdGhlIGxhbmcgcGFyYW1ldGVyIG9uIHRoZSB4c2w6c29ydAotICAgICAgICAgKi8KLQotICAgICAgICAvLyBJdCBzZWVtcyB3ZSBjYW4gbm90IHVzZSB0aGlzIGFzIGl0IGp1c3QgcGFyc2VzIHRoZSAKLSAgICAgICAgLy8gc3RhcnQgb2YgdGhlIHN0cmluZyB1bnRpbCBpdCBmaW5kcyBhIG5vbi1udW1iZXIgY2hhciwgCi0gICAgICAgIC8vIHdoaWNoIGlzIG5vdCB3aGF0IHdlIHdhbnQgYWNjb3JkaW5nIHRvIHRoZSBYU0xUIHNwZWMuICAKLSAgICAgICAgLy8gQWxzbywgSSAqdGhpbmsqIHRoaXMgaXMgYSBsb2NhbC1zcGVjaWZpYwotICAgICAgICAvLyBwYXJzZSwgd2hpY2ggaXMgYWxzbyBub3Qgd2hhdCB3ZSB3YW50IGFjY29yZGluZyB0byB0aGUgCi0gICAgICAgIC8vIFhTTFQgc3BlYyAoc2VlIGJlbG93KS4KLSAgICAgICAgLy8gTnVtYmVyRm9ybWF0IGZvcm1hdHRlciA9IE51bWJlckZvcm1hdC5nZXROdW1iZXJJbnN0YW5jZSgpOwotICAgICAgICAvLyByZXN1bHQgPSBmb3JtYXR0ZXIucGFyc2Uocy50cmltKCkpLmRvdWJsZVZhbHVlKCk7Ci0gICAgICAgIC8vIFRoZSBkdW1iIFhTTFQgc3BlYyBzYXlzOiAiVGhlIG51bWJlciBmdW5jdGlvbiBzaG91bGQgCi0gICAgICAgIC8vIG5vdCBiZSB1c2VkIGZvciBjb252ZXJzaW9uIG9mIG51bWVyaWMgZGF0YSBvY2N1cnJpbmcgCi0gICAgICAgIC8vIGluIGFuIGVsZW1lbnQgaW4gYW4gWE1MIGRvY3VtZW50IHVubGVzcyB0aGUgZWxlbWVudCAKLSAgICAgICAgLy8gaXMgb2YgYSB0eXBlIHRoYXQgcmVwcmVzZW50cyBudW1lcmljIGRhdGEgaW4gYSAKLSAgICAgICAgLy8gbGFuZ3VhZ2UtbmV1dHJhbCBmb3JtYXQgKHdoaWNoIHdvdWxkIHR5cGljYWxseSBiZSAKLSAgICAgICAgLy8gdHJhbnNmb3JtZWQgaW50byBhIGxhbmd1YWdlLXNwZWNpZmljIGZvcm1hdCBmb3IgCi0gICAgICAgIC8vIHByZXNlbnRhdGlvbiB0byBhIHVzZXIpLiBJbiBhZGRpdGlvbiwgdGhlIG51bWJlciAKLSAgICAgICAgLy8gZnVuY3Rpb24gY2Fubm90IGJlIHVzZWQgdW5sZXNzIHRoZSBsYW5ndWFnZS1uZXV0cmFsIAotICAgICAgICAvLyBmb3JtYXQgdXNlZCBieSB0aGUgZWxlbWVudCBpcyBjb25zaXN0ZW50IHdpdGggdGhlIAotICAgICAgICAvLyBYUGF0aCBzeW50YXggZm9yIGEgTnVtYmVyLiIKLSAgICAgICAgLy8gU28gSSBndWVzcyB3ZSBuZWVkIHRvIGNoZWNrLCBpZiB0aGUgZGVmYXVsdCBsb2NhbCAKLSAgICAgICAgLy8gaXMgZnJlbmNoLCBkb2VzIERvdWJsZS52YWx1ZU9mIHVzZSB0aGUgbG9jYWwgc3BlY2lmaWMgCi0gICAgICAgIC8vIHBhcnNlPyAgT3IgZG9lcyBpdCB1c2UgdGhlIGllZWUgcGFyc2U/Ci0gICAgICAgIHJlc3VsdCA9IERvdWJsZS52YWx1ZU9mKHMudHJpbSgpKS5kb3VibGVWYWx1ZSgpOwotICAgICAgfQotCi0gICAgICAvLyBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgCi0gICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkKLSAgICAgIHsKLSAgICAgICAgcmVzdWx0ID0gRG91YmxlLk5hTjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OyAgCi0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gIHsKLSAgICByZXR1cm4gbV94c3RyaW5nLm51bSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIGJvb2xlYW4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKCkKLSAgewotICAgIHJldHVybiBtX3hzdHJpbmcuYm9vbCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIHJldHVybiBtX3hzdHJpbmcuc3RyKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoU3VwcG9ydCBzdXBwb3J0KQotICB7ICAKLSAgICBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dCBjb250ZXh0ID0gKG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0KXN1cHBvcnQ7Ci0gICAgcmV0dXJuIG1feHN0cmluZy5ydHJlZShjb250ZXh0KTsKLSAgICAvL3JldHVybiAoRG9jdW1lbnRGcmFnbWVudCljb250ZXh0LmdldERUTU1hbmFnZXIoKS5nZXREVE0ocmVzdWx0KS5nZXROb2RlKHJlc3VsdCk7ICAgIAotICB9Ci0gIAotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBYcGF0aCBjb250ZXh0IHRvIHVzZSBmb3IgdGhlIGNvbnZlcnNpb24gCi0gICAqCi0gICAqIEByZXR1cm4gQSBkb2N1bWVudCBmcmFnbWVudCB3aXRoIHRoaXMgc3RyaW5nIGFzIGEgY2hpbGQgbm9kZQotICAgKi8KLSAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgcnRyZWUoWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLSAgICBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dCBjb250ZXh0ID0gKG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0KXN1cHBvcnQ7Ci0gICAgcmV0dXJuIG1feHN0cmluZy5ydHJlZShjb250ZXh0KTsKLSAgICAvL3JldHVybiAoRG9jdW1lbnRGcmFnbWVudCljb250ZXh0LmdldERUTU1hbmFnZXIoKS5nZXREVE0ocmVzdWx0KS5nZXROb2RlKHJlc3VsdCk7ICAgIAotICB9IAotICAKLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE9iamVjdCBvYmoyKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBtX3hzdHJpbmcuZXF1YWxzKG9iajIpOwotICB9Ci0KLSAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvcGFja2FnZS5odG1sIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjlhNTVkYS4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsNSArMCwwIEBACi08SFRNTD48SEVBRD48L0hFQUQ+PEJPRFk+Ci0gICAgIDxQPkluZnJhc3RydWN0dXJlIGZvciBwcm9jZXNzaW5nIFhQQVRIIGV4cHJlc3Npb25zPC9QPgotICAgCi0gICAgIDxQPjwvUD4KLSAgIDwvQk9EWT48L0hUTUw+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3hkb20vWGVyY2VzTGlhaXNvbi5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3hkb20vWGVyY2VzTGlhaXNvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YzQ0NzhiLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94ZG9tL1hlcmNlc0xpYWlzb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4OSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54cGF0aC54ZG9tOwotCi1pbXBvcnQgamF2YS5uZXQuKjsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54ZXJjZXMuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGVyY2VzLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFByb3ZpZGVzIFhTTFRQcm9jZXNzb3IgYW4gaW50ZXJmYWNlIHRvIHRoZSBYZXJjZXMgWE1MIHBhcnNlci4gIFRoaXMgCi0gKiBsaWFpc29uIHNob3VsZCBiZSB1c2VkIGlmIFhlcmNlcyBET00gbm9kZXMgYXJlIGJlaW5nIHByb2Nlc3MgYXMgCi0gKiB0aGUgc291cmNlIHRyZWUgb3IgYXMgdGhlIHJlc3VsdCB0cmVlLgotICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFByb2Nlc3NvcgotICogQHNlZSBvcmcuYXBhY2hlLnhtbC5wYXJzZXJzCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhlcmNlc0xpYWlzb24gZXh0ZW5kcyBYTUxQYXJzZXJMaWFpc29uRGVmYXVsdCAvL2ltcGxlbWVudHMgWFBhdGhTdXBwb3J0Ci17Ci0gIC8qKgotICAgKiBSZXR1cm4gYSBzdHJpbmcgc3VpdGlibGUgZm9yIHRlbGxpbmcgdGhlIHVzZXIgd2hhdCBwYXJzZXIgaXMgYmVpbmcgdXNlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UGFyc2VyRGVzY3JpcHRpb24oKQotICB7Ci0gICAgcmV0dXJuICJYTUw0SiBWZXJzaW9uICIrIGdldFhNTDRKVmVyc2lvblN0cmluZygpOwotICB9Ci0KLQlwcml2YXRlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBtX2Vycm9ySGFuZGxlcjsKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgU0FYIEVycm9ySGFuZGxlciBhcyBhbiBhcmd1bWVudC4gVGhlIGVycm9yIGhhbmRsZXIKLSAgICogaXMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBYTUwgUGFyc2VyLiBBbnkgWE1MLXJlbGF0ZWQgZXJyb3JzIHdpbGwgYmUgcmVwb3J0ZWQKLSAgICogdG8gdGhlIGNhbGxpbmcgYXBwbGljYXRpb24gdXNpbmcgdGhpcyBlcnJvciBoYW5kbGVyLgotICAgKgotICAgKiBAcGFyYW0JZXJyb3JIYW5kbGVyIFNBWCBFcnJvckhhbmRsZXIgaW5zdGFuY2UuCi0gICAqLwotICBwdWJsaWMgWGVyY2VzTGlhaXNvbihvcmcueG1sLnNheC5FcnJvckhhbmRsZXIgZXJyb3JIYW5kbGVyKQotICB7Ci0gICAgbV9lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlLgotICAgKgotICBwdWJsaWMgWGVyY2VzTGlhaXNvbihYUGF0aEVudlN1cHBvcnQgZW52U3VwcG9ydCkKLSAgewotICAgIG1fZW52U3VwcG9ydCA9IGVudlN1cHBvcnQ7Ci0gIH0qLwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gaW5zdGFuY2UuCi0gICAqLwotICBwdWJsaWMgWGVyY2VzTGlhaXNvbigpCi0gIHsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogQ2hlY2sgbm9kZSB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGlzIGxpYWlzb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja05vZGUoTm9kZSBub2RlKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYoIShub2RlIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54ZXJjZXMuZG9tLk5vZGVJbXBsKSkKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUywgbmV3IE9iamVjdFtdeygoT2JqZWN0KW5vZGUpLmdldENsYXNzKCl9KSk7IC8vIlhlcmNlc0xpYWlzb24gY2FuIG5vdCBoYW5kbGUgbm9kZXMgb2YgdHlwZSIKLSAgICAgICAgLy8rKChPYmplY3Qpbm9kZSkuZ2V0Q2xhc3MoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0cnVlIHRoYXQgdGhpcyBpbXBsZW1lbnRhdGlvbiBkb2VzIHN1cHBvcnQKLSAgICogdGhlIFNBWCBEb2N1bWVudEhhbmRsZXIgaW50ZXJmYWNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNTQVgoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIEdldCBYZXJjZXMgdmVyc2lvbiBmaWVsZC4uLiB3ZSBoYXZlIHRvIGRvIHRoaXMgJ2NhdXNlCi0gICAqIHRoZSAicHVibGljIHN0YXRpYyBmaW5hbCIgZmllbGRzIHNlZW0gdG8gZ2V0IGJvdW5kCi0gICAqIGF0IGNvbXBpbGUgdGltZSBvdGhlcndpc2UuCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBnZXRYTUw0SlZlcnNpb25TdHJpbmcoKQotICB7Ci0gICAgLy8gcmV0dXJuIFZlcnNpb24uZlZlcnNpb247Ci0gICAgU3RyaW5nIHZlcnNpb24gPSAiIjsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCB2ZXJzaW9uRmllbGQgPSBWZXJzaW9uLmNsYXNzLmdldEZpZWxkKCJmVmVyc2lvbiIpOwotICAgICAgdmVyc2lvbiA9IChTdHJpbmcpdmVyc2lvbkZpZWxkLmdldChudWxsKTsKLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgIH0KLSAgICByZXR1cm4gdmVyc2lvbjsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IG9uZSBvZiB0aGUgWGVyY2VzIHZlcnNpb24gbnVtYmVycy4uLgotICAgKiB3ZSBoYXZlIHRvIGRvIHRoaXMgJ2NhdXNlIHRoZSAicHVibGljIHN0YXRpYyBmaW5hbCIKLSAgICogZmllbGRzIHNlZW0gdG8gZ2V0IGJvdW5kIGF0IGNvbXBpbGUgdGltZSBvdGhlcndpc2UuCi0gICAqLwotICBwcml2YXRlIGludCBnZXRYTUw0SlZlcnNpb25OdW0oaW50IGZpZWxkKQotICB7Ci0gICAgaW50IHZlcnNpb25OdW0gPSAwOwotICAgIFN0cmluZyB2ZXIgPSBnZXRYTUw0SlZlcnNpb25TdHJpbmcoKTsKLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih2ZXIsICIgLiIpOwotICAgIGZvcihpbnQgaSA9IDA7IHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCk7IGkrKykKLSAgICB7Ci0gICAgICBTdHJpbmcgdG9rID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgaWYoZmllbGQgPT0gaSkKLSAgICAgIHsKLSAgICAgICAgdmVyc2lvbk51bSA9IEludGVnZXIucGFyc2VJbnQodG9rKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIHZlcnNpb25OdW07Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBQb29sIHRoZSBET00gcGFyc2VycyBmb3IgcmV1c2UuCi0gICAqCi0gIHByaXZhdGUgT2JqZWN0UG9vbCBtX2RvbVBhcnNlclBvb2wgPSBuZXcgT2JqZWN0UG9vbChET01QYXJzZXIuY2xhc3MpOwotICAKLSAgLyoqCi0gICAqIFBvb2wgdGhlIFNBWCBwYXJzZXJzIGZvciByZXVzZS4KLSAgICoKLSAgcHJpdmF0ZSBPYmplY3RQb29sIG1fc2F4UGFyc2VyUG9vbCA9IG5ldyBPYmplY3RQb29sKFNBWFBhcnNlci5jbGFzcyk7Ci0gCi0gIC8qKgotICAgKiBDb3VudCB0aGUgcGFyc2VzIHNpbmNlIHRoZSBsYXN0IGdhcmJhZ2UgY29sbGVjdGlvbi4gIEdDIGV2ZXJ5IAotICAgKiAxMCBwYXJzZXMgb3Igc28uICAoVGhpcyBtaWdodCBiZSBhIGJhZCBpZGVhLCBidXQgaXQgc2VlbXMgdG8gCi0gICAqIGhlbHAuLi4pCi0gICAqCi0gIHByb3RlY3RlZCBpbnQgbV9wYXJzZUNvdW50U2luY2VHQyA9IDA7Ci0qLwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogUGFyc2UgYW4gWE1MIGRvY3VtZW50LgotICAgKgotICAgKiA8cD5UaGUgYXBwbGljYXRpb24gY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBpbnN0cnVjdCB0aGUgU0FYIHBhcnNlcgotICAgKiB0byBiZWdpbiBwYXJzaW5nIGFuIFhNTCBkb2N1bWVudCBmcm9tIGFueSB2YWxpZCBpbnB1dAotICAgKiBzb3VyY2UgKGEgY2hhcmFjdGVyIHN0cmVhbSwgYSBieXRlIHN0cmVhbSwgb3IgYSBVUkkpLjwvcD4KLSAgICoKLSAgICogPHA+QXBwbGljYXRpb25zIG1heSBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHdoaWxlIGEgcGFyc2UgaXMgaW4KLSAgICogcHJvZ3Jlc3MgKHRoZXkgc2hvdWxkIGNyZWF0ZSBhIG5ldyBQYXJzZXIgaW5zdGVhZCBmb3IgZWFjaAotICAgKiBhZGRpdGlvbmFsIFhNTCBkb2N1bWVudCkuICBPbmNlIGEgcGFyc2UgaXMgY29tcGxldGUsIGFuCi0gICAqIGFwcGxpY2F0aW9uIG1heSByZXVzZSB0aGUgc2FtZSBQYXJzZXIgb2JqZWN0LCBwb3NzaWJseSB3aXRoIGEKLSAgICogZGlmZmVyZW50IGlucHV0IHNvdXJjZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBmb3IgdGhlIHRvcC1sZXZlbCBvZiB0aGUKLSAgICogICAgICAgIFhNTCBkb2N1bWVudC4KLSAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBleGNlcHRpb24gamF2YS5pby5JT0V4Y2VwdGlvbiBBbiBJTyBleGNlcHRpb24gZnJvbSB0aGUgcGFyc2VyLAotICAgKiAgICAgICAgICAgIHBvc3NpYmx5IGZyb20gYSBieXRlIHN0cmVhbSBvciBjaGFyYWN0ZXIgc3RyZWFtCi0gICAqICAgICAgICAgICAgc3VwcGxpZWQgYnkgdGhlIGFwcGxpY2F0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LklucHV0U291cmNlCi0gICAqIEBzZWUgI3BhcnNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgI3NldEVudGl0eVJlc29sdmVyCi0gICAqIEBzZWUgI3NldERUREhhbmRsZXIKLSAgICogQHNlZSAjc2V0RG9jdW1lbnRIYW5kbGVyCi0gICAqIEBzZWUgI3NldEVycm9ySGFuZGxlcgotICAgKi8KLSAgcHVibGljIHZvaWQgcGFyc2UgKElucHV0U291cmNlIHNvdXJjZSkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIEkgZ3Vlc3MgSSBzaG91bGQgdXNlIEpBWFAgZmFjdG9yeSBoZXJlLi4uIHdoZW4gaXQncyBsZWdhbC4KLSAgICAgIC8vIG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuRE9NUGFyc2VyIHBhcnNlciAKLSAgICAgIC8vICA9IG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLkRPTVBhcnNlcigpOwotICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBidWlsZGVyRmFjdG9yeSA9Ci0gICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgYnVpbGRlckZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7ICAgICAgCi0KLSAgICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBidWlsZGVyRmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLQkJCWlmIChtX2Vycm9ySGFuZGxlciA9PSBudWxsKQotCQkJCXBhcnNlci5zZXRFcnJvckhhbmRsZXIobmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLkRlZmF1bHRFcnJvckhhbmRsZXIoKSk7Ci0JCQllbHNlCi0JCQkJcGFyc2VyLnNldEVycm9ySGFuZGxlcihtX2Vycm9ySGFuZGxlcik7Ci0KLSAgICAgIC8vIGlmKG51bGwgIT0gbV9lbnRpdHlSZXNvbHZlcikKLSAgICAgIC8vIHsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiU2V0dGluZyB0aGUgZW50aXR5IHJlc29sdmVyLiIpOwotICAgICAgLy8gIHBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcihtX2VudGl0eVJlc29sdmVyKTsKLSAgICAgIC8vIH0KLSAgICAgIHNldERvY3VtZW50KHBhcnNlci5wYXJzZShzb3VyY2UpKTsKLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHBjZSk7Ci0gICAgfQotICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0gIAotICBwdWJsaWMgdm9pZCBjb3B5RnJvbU90aGVyTGlhaXNvbihYTUxQYXJzZXJMaWFpc29uRGVmYXVsdCBmcm9tKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8vc3VwZXIuY29weUZyb21PdGhlckxpYWlzb24oZnJvbSk7Ci0gICAgaWYobnVsbCAhPSBmcm9tKSAvLyBkZWZlbnNpdmUKLSAgICB7Ci0gICAgICBpZihmcm9tIGluc3RhbmNlb2YgWGVyY2VzTGlhaXNvbikKLSAgICAgICAgdGhpcy5tX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgPSAoKFhlcmNlc0xpYWlzb24pZnJvbSkubV91c2VET00yZ2V0TmFtZXNwYWNlVVJJOwotICAgIH0KLSB9Ci0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGVtcHR5IERPTSBEb2N1bWVudC4gIE1haW5seSB1c2VkIGZvciBjcmVhdGluZyBhbgotICAgKiBvdXRwdXQgZG9jdW1lbnQuICBJbXBsZW1lbnRhdGlvbiBvZiBYTUxQYXJzZXJMaWFpc29uCi0gICAqIGludGVyZmFjZSBtZXRob2QuCi0gICAqLwotICBzdGF0aWMgcHVibGljIERvY3VtZW50IGNyZWF0ZURvY3VtZW50KCkKLSAgewotICAgIG9yZy5hcGFjaGUueGVyY2VzLmRvbS5Eb2N1bWVudEltcGwgZG9jID0gbmV3IG9yZy5hcGFjaGUueGVyY2VzLmRvbS5Eb2N1bWVudEltcGwoKTsKLSAgICByZXR1cm4gZG9jOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIElELCByZXR1cm4gdGhlIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50QnlJRChTdHJpbmcgaWQsIERvY3VtZW50IGRvYykKLSAgewotICAgIHJldHVybiAoKERvY3VtZW50SW1wbClkb2MpLmdldElkZW50aWZpZXIoaWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIG5vZGUgaXMgaWdub3JhYmxlIHdoaXRlc3BhY2UuCi0gICAqIEBkZXByZWNhdGVkCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0lnbm9yYWJsZVdoaXRlc3BhY2UoVGV4dCBub2RlKQotICB7Ci0gICAgYm9vbGVhbiBpc0lnbm9yYWJsZTsKLSAgICBpZiggbm9kZSBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueGVyY2VzLmRvbS5UZXh0SW1wbCkKLSAgICB7Ci0gICAgICBpc0lnbm9yYWJsZSA9ICgob3JnLmFwYWNoZS54ZXJjZXMuZG9tLlRleHRJbXBsKW5vZGUpLmlzSWdub3JhYmxlV2hpdGVzcGFjZSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaXNJZ25vcmFibGUgPSBmYWxzZTsKLSAgICB9Ci0gICAgcmV0dXJuIGlzSWdub3JhYmxlOwotICB9Ci0gIAotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgPSB0cnVlOwotICAKLSAgLyoqCi0gICAqIFNldCB3aGV0aGVyIG9yIG5vdCBnZXROYW1lc3BhY2VPZk5vZGUgc2hvdWxkIHVzZSB0aGUgWGVyY2VzL0RPTTIKLSAgICogZ2V0TmFtZXNwYWNlVVJJLiAgVGhpcyBoYXMgdG8gYmUgc2V0IHRvIHRydWUgaWYgdGhlIAotICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyBpcyBzZXQgdG8gZmFsc2UsIG9yIGlmIAotICAgKiB0aGUgdHJlZSBpcyBtdXRhdGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VXNlRE9NMmdldE5hbWVzcGFjZVVSSShib29sZWFuIGIpCi0gIHsKLSAgICBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgPSBiOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBvZiB0aGUgbm9kZS4gIENhbGxzIG9yZy5hcGFjaGUueGVyY2VzLmRvbS5Ob2RlSW1wbCdzCi0gICAqIGdldE5hbWVzcGFjZVVSSSgpIGlmIHNldFVzZURPTTJnZXROYW1lc3BhY2VVUkkodHJ1ZSkgaGFzIGJlZW4gY2FsbGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VPZk5vZGUoTm9kZSBuKQotICB7Ci0gICAgcmV0dXJuKG1fdXNlRE9NMmdldE5hbWVzcGFjZVVSSSkgPwotICAgICAgICAgICgob3JnLmFwYWNoZS54ZXJjZXMuZG9tLk5vZGVJbXBsKW4pLmdldE5hbWVzcGFjZVVSSSgpCi0gICAgICAgICAgOiBzdXBlci5nZXROYW1lc3BhY2VPZk5vZGUobik7Ci0gIH0KLSAgCi0KLSAgLyoqCi0gICogUmV0dXJucyB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgKi8KLSAgLy8gcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWVPZk5vZGUoTm9kZSBuKQotICAvLyB7Ci0gIC8vICAgcmV0dXJuICgob3JnLmFwYWNoZS54ZXJjZXMuZG9tLk5vZGVJbXBsKW4pLmdldExvY2FsTmFtZSgpOwotICAvLyB9Ci0KLSAgLyoqCi0gICogUmV0dXJucyB0aGUgZWxlbWVudCBuYW1lIHdpdGggdGhlIG5hbWVzcGFjZSBleHBhbmRlZC4KLSAgKi8KLSAgLy8gcHVibGljIFN0cmluZyBnZXRFeHBhbmRlZEVsZW1lbnROYW1lKEVsZW1lbnQgZWxlbSkKLSAgLy8gewotICAvLyAgU3RyaW5nIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZU9mTm9kZShlbGVtKTsKLSAgLy8gICByZXR1cm4gKG51bGwgIT0gbmFtZXNwYWNlKSA/IG5hbWVzcGFjZSsiOiIrIGdldExvY2FsTmFtZU9mTm9kZShlbGVtKQotICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRMb2NhbE5hbWVPZk5vZGUoZWxlbSk7Ci0gIC8vIH0KLQotICAvKioKLSAgKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgbmFtZSB3aXRoIHRoZSBuYW1lc3BhY2UgZXhwYW5kZWQuCi0gICovCi0gIC8vIHB1YmxpYyBTdHJpbmcgZ2V0RXhwYW5kZWRBdHRyaWJ1dGVOYW1lKEF0dHIgYXR0cikKLSAgLy8gewotICAvLyAgU3RyaW5nIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZU9mTm9kZShhdHRyKTsKLSAgLy8gICByZXR1cm4gKG51bGwgIT0gbmFtZXNwYWNlKSA/IG5hbWVzcGFjZSsiOiIrIGdldExvY2FsTmFtZU9mTm9kZShhdHRyKQotICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGdldExvY2FsTmFtZU9mTm9kZShhdHRyKTsKLSAgLy8gfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhcmVudCBvZiBhIG5vZGUuCi0gICAqLwotICBzdGF0aWMgcHVibGljIE5vZGUgZ2V0UGFyZW50T2ZOb2RlKE5vZGUgbm9kZSkKLSAgICB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChOb2RlLkFUVFJJQlVURV9OT0RFID09IG5vZGUuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgICAgICAgPyAoKEF0dHIpbm9kZSkuZ2V0T3duZXJFbGVtZW50KCkgOiBub2RlLmdldFBhcmVudE5vZGUoKTsKLSAgfQotCi19Ci0KLQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbC9Gb3JtYXR0ZXJUb0RPTS5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbC9Gb3JtYXR0ZXJUb0RPTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OTBjOTY4Li4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9ET00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJGYWN0b3J5OwotLy9pbXBvcnQgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLkJhc2VNYXJrdXBTZXJpYWxpemVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLkRPTVNlcmlhbGl6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplclRvWE1MOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyB0YWtlcyBTQVggZXZlbnRzIChpbiBhZGRpdGlvbiB0byBzb21lIGV4dHJhIGV2ZW50cyAKLSAqIHRoYXQgU0FYIGRvZXNuJ3QgaGFuZGxlIHlldCkgYW5kIGFkZHMgdGhlIHJlc3VsdCB0byBhIGRvY3VtZW50IAotICogb3IgZG9jdW1lbnQgZnJhZ21lbnQuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIEZvcm1hdHRlclRvRE9NIGV4dGVuZHMgUGFyc2VyQWRhcHRlcgoteyAKLSAgRE9NU2VyaWFsaXplciBtX3NlcmlhbGl6ZXI7Ci0gICAgCi0gIC8qKgotICAgKiBGb3JtYXR0ZXJUb0RPTSBpbnN0YW5jZSBjb25zdHJ1Y3Rvci4uLiBpdCB3aWxsIGFkZCB0aGUgRE9NIG5vZGVzIAotICAgKiB0byB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAqLwotICBwdWJsaWMgRm9ybWF0dGVyVG9ET00oRG9jdW1lbnQgZG9jLCBFbGVtZW50IGVsZW0pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcigpKTsKLSAgICB0cnl7Ci0gICAgICBtX3NlcmlhbGl6ZXIgPSAobmV3IFNlcmlhbGl6ZXJUb1hNTCgpKS5hc0RPTVNlcmlhbGl6ZXIoKTsKLSAgICAgIHRoaXMuc2V0Q29udGVudEhhbmRsZXIoKFNlcmlhbGl6ZXJUb1hNTCltX3NlcmlhbGl6ZXIpOwotICAgIH0KLSAgICBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBpb2UpCi0gICAge30KLSAgfQotCi0gIC8qKgotICAgKiBGb3JtYXR0ZXJUb0RPTSBpbnN0YW5jZSBjb25zdHJ1Y3Rvci4uLiBpdCB3aWxsIGFkZCB0aGUgRE9NIG5vZGVzIAotICAgKiB0byB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAqLwotICBwdWJsaWMgRm9ybWF0dGVyVG9ET00oRG9jdW1lbnQgZG9jLCBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWcpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcigpKTsgCi0gICAgdHJ5ewotICAgICAgbV9zZXJpYWxpemVyID0gKG5ldyBTZXJpYWxpemVyVG9YTUwoKSkuYXNET01TZXJpYWxpemVyKCk7Ci0gICAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKChTZXJpYWxpemVyVG9YTUwpbV9zZXJpYWxpemVyKTsKLSAgICB9Ci0gICAgY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gaW9lKQotICAgIHt9Ci0gIH0KLQotICAvKioKLSAgICogRm9ybWF0dGVyVG9ET00gaW5zdGFuY2UgY29uc3RydWN0b3IuLi4gaXQgd2lsbCBhZGQgdGhlIERPTSBub2RlcyAKLSAgICogdG8gdGhlIGRvY3VtZW50LgotICAgKi8KLSAgcHVibGljIEZvcm1hdHRlclRvRE9NKERvY3VtZW50IGRvYykgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgIHRyeXsKLSAgICAgIG1fc2VyaWFsaXplciA9IChuZXcgU2VyaWFsaXplclRvWE1MKCkpLmFzRE9NU2VyaWFsaXplcigpOwotICAgICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcigoU2VyaWFsaXplclRvWE1MKW1fc2VyaWFsaXplcik7Ci0gICAgfQotICAgIGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGlvZSkKLSAgICB7fQotICB9Ci0gIAotICBwdWJsaWMgU2VyaWFsaXplclRvWE1MIGdldFNlcmlhbGl6ZXJPYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIChTZXJpYWxpemVyVG9YTUwpbV9zZXJpYWxpemVyOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9IVE1MLmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL0Zvcm1hdHRlclRvSFRNTC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Zjg0MTFiLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9IVE1MLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEgIAotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbDsKLQotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplclRvSFRNTDsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlBhcnNlckFkYXB0ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotLy9pbXBvcnQgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLk91dHB1dEZvcm1hdDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogRm9ybWF0dGVyVG9IVE1MIGZvcm1hdHMgU0FYLXN0eWxlIGV2ZW50cyBpbnRvIFhNTC4KLSAqIFdhcm5pbmc6IHRoaXMgY2xhc3Mgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgWGVyY2VzIFNlcmlhbGl6ZXIgY2xhc3Nlcy4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgRm9ybWF0dGVyVG9IVE1MIGV4dGVuZHMgUGFyc2VyQWRhcHRlcgoteyAKLSAgCi0gIFNlcmlhbGl6ZXJUb0hUTUwgbV9zZXJpYWxpemVyOwotICAKLSAgcHVibGljIEZvcm1hdHRlclRvSFRNTCgpIHRocm93cyBTQVhFeGNlcHRpb24gCi0gIHsKLSAgICBzdXBlcihuZXcgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIoKSk7Ci0gICAgbV9zZXJpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXJUb0hUTUwoKTsKLSAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKG1fc2VyaWFsaXplcik7ICAKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIHVzaW5nIGEgd3JpdGVyLgotICAgKiBAcGFyYW0gd3JpdGVyICAgICAgICBUaGUgY2hhcmFjdGVyIG91dHB1dCBzdHJlYW0gdG8gdXNlLgotICAgKi8KLSAgcHVibGljIEZvcm1hdHRlclRvSFRNTChXcml0ZXIgd3JpdGVyKSB0aHJvd3MgU0FYRXhjZXB0aW9uICAKLSAgewotICAgIHN1cGVyKG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcigpKTsKLSAgICBtX3NlcmlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplclRvSFRNTCgpOwotICAgIG1fc2VyaWFsaXplci5zZXRXcml0ZXIod3JpdGVyKTsKLSAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKG1fc2VyaWFsaXplcik7ICAgIAotICB9Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0b3IgdXNpbmcgYW4gb3V0cHV0IHN0cmVhbSwgYW5kIGEgc2ltcGxlIE91dHB1dEZvcm1hdC4KLSAgICogQHBhcmFtIHdyaXRlciAgICAgICAgVGhlIGNoYXJhY3RlciBvdXRwdXQgc3RyZWFtIHRvIHVzZS4KLSAgICovCi0gIHB1YmxpYyBGb3JtYXR0ZXJUb0hUTUwoamF2YS5pby5PdXRwdXRTdHJlYW0gb3MpICAKLSAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgIG1fc2VyaWFsaXplciA9IG5ldyBTZXJpYWxpemVyVG9IVE1MKCk7Ci0gICAgbV9zZXJpYWxpemVyLnNldE91dHB1dFN0cmVhbShvcyk7Ci0gICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcihtX3NlcmlhbGl6ZXIpOwotICAgIAotICB9Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0b3IgdXNpbmcgYSB3cml0ZXIuCi0gICAqIEBwYXJhbSB3cml0ZXIgICAgICAgIFRoZSBjaGFyYWN0ZXIgb3V0cHV0IHN0cmVhbSB0byB1c2UuCi0gICAqLwotICBwdWJsaWMgRm9ybWF0dGVyVG9IVE1MKEZvcm1hdHRlclRvWE1MIHhtbExpc3RlbmVyKSB0aHJvd3MgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgIG1fc2VyaWFsaXplciA9IG5ldyBTZXJpYWxpemVyVG9IVE1MKCk7Ci0gICAgbV9zZXJpYWxpemVyLkNvcHlGcm9tKHhtbExpc3RlbmVyLm1fc2VyaWFsaXplcik7Ci0gICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcihtX3NlcmlhbGl6ZXIpOwotICB9Ci0gIAotICBwdWJsaWMgU2VyaWFsaXplclRvSFRNTCBnZXRTZXJpYWxpemVyT2JqZWN0KCkKLSAgewotICAgIHJldHVybiBtX3NlcmlhbGl6ZXI7Ci0gIH0KLSAgCi19Ci0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9UZXh0LmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL0Zvcm1hdHRlclRvVGV4dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ODllZGEwLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9UZXh0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sOwotCi1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJGYWN0b3J5OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1RleHQ7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5QYXJzZXJBZGFwdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyB0YWtlcyBTQVggZXZlbnRzIChpbiBhZGRpdGlvbiB0byBzb21lIGV4dHJhIGV2ZW50cyAKLSAqIHRoYXQgU0FYIGRvZXNuJ3QgaGFuZGxlIHlldCkgYW5kIHByb2R1Y2VzIHNpbXBsZSB0ZXh0IG9ubHkuCi0gKiBXYXJuaW5nOiB0aGlzIGNsYXNzIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIFhlcmNlcyBTZXJpYWxpemVyIGNsYXNzZXMuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIEZvcm1hdHRlclRvVGV4dCBleHRlbmRzIFBhcnNlckFkYXB0ZXIKLXsKLSAgCi0gIHByaXZhdGUgU2VyaWFsaXplclRvVGV4dCBtX3NlcmlhbGl6ZXI7Ci0gIC8qKgotICAgKiBGb3JtYXR0ZXJUb1RleHQgaW5zdGFuY2UgY29uc3RydWN0b3IuLi4gaXQgd2lsbCBhZGQgdGhlIERPTSBub2RlcyAKLSAgICogdG8gdGhlIGRvY3VtZW50IGZyYWdtZW50LgotICAgKi8KLSAgcHVibGljIEZvcm1hdHRlclRvVGV4dChXcml0ZXIgcHcpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcigpKTsKLSAgICBtX3NlcmlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplclRvVGV4dCgpOyAKLSAgICBtX3NlcmlhbGl6ZXIuc2V0V3JpdGVyKHB3KTsKLSAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKG1fc2VyaWFsaXplcik7Ci0gIH0KLSAgCi0gIHB1YmxpYyBTZXJpYWxpemVyVG9UZXh0IGdldFNlcmlhbGl6ZXJPYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fc2VyaWFsaXplcjsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9YTUwuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvRm9ybWF0dGVyVG9YTUwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzBlYWFkZS4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL0Zvcm1hdHRlclRvWE1MLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEgIAotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbDsKLQotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplclRvWE1MOwotLy9pbXBvcnQgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLkJhc2VNYXJrdXBTZXJpYWxpemVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLk1ldGhvZDsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlBhcnNlckFkYXB0ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIEZvcm1hdHRlclRvWE1MIGZvcm1hdHMgU0FYLXN0eWxlIGV2ZW50cyBpbnRvIFhNTC4KLSAqIFdhcm5pbmc6IHRoaXMgY2xhc3Mgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgWGVyY2VzIFNlcmlhbGl6ZXIgY2xhc3Nlcy4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgRm9ybWF0dGVyVG9YTUwgZXh0ZW5kcyBQYXJzZXJBZGFwdGVyCi17Ci0gIFNlcmlhbGl6ZXJUb1hNTCBtX3NlcmlhbGl6ZXI7Ci0gIAotICBwdWJsaWMgRm9ybWF0dGVyVG9YTUwoKQotICB7Ci0gICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgIG1fc2VyaWFsaXplciA9IG5ldyBTZXJpYWxpemVyVG9YTUwoKTsKLSAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKG1fc2VyaWFsaXplcik7Ci0gICAgLy9zdXBlciggbmV3IE91dHB1dEZvcm1hdCggTWV0aG9kLlhNTCwgbnVsbCwgZmFsc2UgKSApOyAgICAgCi0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciB1c2luZyBhIHdyaXRlci4KLSAgICogQHBhcmFtIHdyaXRlciAgICAgICAgVGhlIGNoYXJhY3RlciBvdXRwdXQgc3RyZWFtIHRvIHVzZS4KLSAgICovCi0gIHB1YmxpYyBGb3JtYXR0ZXJUb1hNTChXcml0ZXIgd3JpdGVyKSB0aHJvd3MgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgIG1fc2VyaWFsaXplciA9IG5ldyBTZXJpYWxpemVyVG9YTUwoKTsKLSAgIC8vIHN1cGVyKCBmb3JtYXQgIT0gbnVsbCA/IGZvcm1hdCA6IG5ldyBPdXRwdXRGb3JtYXQoIE1ldGhvZC5YTUwsIG51bGwsIGZhbHNlICkgKTsKLSAgICAvL19mb3JtYXQuc2V0TWV0aG9kKCBNZXRob2QuWE1MICk7Ci0gICAgbV9zZXJpYWxpemVyLnNldFdyaXRlciggd3JpdGVyICk7Ci0gICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcihtX3NlcmlhbGl6ZXIpOwotICB9Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0b3IgdXNpbmcgYW4gb3V0cHV0IHN0cmVhbSwgYW5kIGEgc2ltcGxlIE91dHB1dEZvcm1hdC4KLSAgICogQHBhcmFtIHdyaXRlciAgICAgICAgVGhlIGNoYXJhY3RlciBvdXRwdXQgc3RyZWFtIHRvIHVzZS4KLSAgICovCi0gIHB1YmxpYyBGb3JtYXR0ZXJUb1hNTChqYXZhLmlvLk91dHB1dFN0cmVhbSBvcykgCi0gICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gLCBTQVhFeGNlcHRpb24gCi0gIHsKLSAgICBzdXBlcihuZXcgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIoKSk7Ci0gICAgbV9zZXJpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXJUb1hNTCgpOwotICAgIC8vc3VwZXIoIGZvcm1hdCAhPSBudWxsID8gZm9ybWF0IDogbmV3IE91dHB1dEZvcm1hdCggTWV0aG9kLlhNTCwgbnVsbCwgZmFsc2UgKSApOwotICAgIC8vX2Zvcm1hdC5zZXRNZXRob2QoIE1ldGhvZC5YTUwgKTsKLSAgICBtX3NlcmlhbGl6ZXIuc2V0T3V0cHV0U3RyZWFtKCBvcyApOwotICAgIHRoaXMuc2V0Q29udGVudEhhbmRsZXIobV9zZXJpYWxpemVyKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIHVzaW5nIGEgd3JpdGVyLgotICAgKiBAcGFyYW0gd3JpdGVyICAgICAgICBUaGUgY2hhcmFjdGVyIG91dHB1dCBzdHJlYW0gdG8gdXNlLgotICAgKi8KLSAgcHVibGljIEZvcm1hdHRlclRvWE1MKEZvcm1hdHRlclRvWE1MIHhtbExpc3RlbmVyKSB0aHJvd3MgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgc3VwZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgIG1fc2VyaWFsaXplciA9IG5ldyBTZXJpYWxpemVyVG9YTUwoKTsKLSAgICBtX3NlcmlhbGl6ZXIuQ29weUZyb20oeG1sTGlzdGVuZXIubV9zZXJpYWxpemVyKTsKLSAgICAvL3N1cGVyKCBuZXcgT3V0cHV0Rm9ybWF0KCBNZXRob2QuWE1MLCBudWxsLCBmYWxzZSApICk7Ci0gICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcihtX3NlcmlhbGl6ZXIpOwotICB9Ci0gIAotICBwdWJsaWMgU2VyaWFsaXplclRvWE1MIGdldFNlcmlhbGl6ZXJPYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fc2VyaWFsaXplcjsKLSAgfQotICAKLQotfSAgLy9Ub1hNTFN0cmluZ1Zpc2l0b3IKZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvUHJvYmxlbUxpc3RlbmVyLmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL1Byb2JsZW1MaXN0ZW5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZWFmOTk2Li4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvUHJvYmxlbUxpc3RlbmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEgIAotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgaXMgdGhlIGludGVyZmFjZSB0aGF0IHRoZSBYU0wgcHJvY2Vzc29yIGNhbGxzIHdoZW4gaXQgCi0gKiBoYXMgYSBwcm9ibGVtIG9mIHNvbWUga2luZCwgZWl0aGVyIGFuIGVycm9yIG9yIGEgd2FybmluZy4KLSAqIFVzZXJzIHNob3VsZCBhc3MgdGhlIFhTTFRFbmdpbmVJbXBsIGNsYXNzIHRvIHNldFByb2JsZW1MaXN0ZW5lcgotICogaWYgdGhleSB3aXNoIGFuIG9iamVjdCBpbnN0YW5jZSB0byBiZSBjYWxsZWQgd2hlbiBhIHByb2JsZW0KLSAqIGV2ZW50IG9jY3Vycy4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFByb2JsZW1MaXN0ZW5lcgotewotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0ICAgIFdBUk5JTkcgICAgICAgICA9IDE7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgICAgRVJST1IgICAgICAgICAgID0gMjsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCAgICBNRVNTQUdFICAgICAgICAgPSAzOwotCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgICAgWE1MUEFSU0VSICAgICAgID0gMTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCAgICBYU0xQUk9DRVNTT1IgICAgPSAyOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0ICAgIFFVRVJZRU5HSU5FICAgICA9IDM7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgICAgWFBBVEhQUk9DRVNTT1IgID0gNDsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCAgICBYUEFUSFBBUlNFUiAgPSA1OwotCi0gIC8qKgotICAgKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIGEgcHJvYmxlbSBldmVudCBvY2N1cnMuCi0gICAqIAotICAgKiBAcGFyYW0gICB3aGVyZSAgICAgICAgICAgICBFaXRoZXIgYW5kIFhNTFBBUlNFUiwgWFNMUFJPQ0VTU09SLCBvciBRVUVSWUVOR0lORS4KLSAgICogQHBhcmFtICAgY2xhc3NpZmljYXRpb24gICAgRWl0aGVyIEVSUk9SIG9yIFdBUk5JTkcuCi0gICAqIEBwYXJhbSAgIHN0eWxlTm9kZSAgICAgICAgIFRoZSBzdHlsZSB0cmVlIG5vZGUgd2hlcmUgdGhlIHByb2JsZW0KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXJyZWQuICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtICAgc291cmNlTm9kZSAgICAgICAgVGhlIHNvdXJjZSB0cmVlIG5vZGUgd2hlcmUgdGhlIHByb2JsZW0KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXJyZWQuICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtICAgbXNnICAgICAgICAgICAgICAgQSBzdHJpbmcgbWVzc2FnZSBleHBsYWluaW5nIHRoZSBwcm9ibGVtLgotICAgKiBAcGFyYW0gICBsaW5lTm8gICAgICAgICAgICBUaGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIHByb2JsZW0gb2NjdXJyZWQsICAKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgaXQgaXMga25vd24uIE1heSBiZSB6ZXJvLgotICAgKiBAcGFyYW0gICBjaGFyT2Zmc2V0ICAgICAgICBUaGUgY2hhcmFjdGVyIG9mZnNldCB3aGVyZSB0aGUgcHJvYmxlbSwgIAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cnJlZCBpZiBpdCBpcyBrbm93bi4gTWF5IGJlIHplcm8uCi0gICAqIAotICAgKiBAcmV0dXJuICB0cnVlIGlmIHRoZSByZXR1cm4gaXMgYW4gRVJST1IsIGluIHdoaWNoIGNhc2UKLSAgICogICAgICAgICAgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLiAgT3RoZXJ3aXNlIHRoZSBwcm9jZXNzb3Igd2lsbCAKLSAgICogICAgICAgICAgY29udGludWUgdG8gcHJvY2Vzcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHByb2JsZW0oc2hvcnQgd2hlcmUsIHNob3J0IGNsYXNzaWZpY2F0aW9uLCAKLSAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHN0eWxlTm9kZSwgTm9kZSBzb3VyY2VOb2RlLAotICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbXNnLCBTdHJpbmcgaWQsIGludCBsaW5lTm8sIGludCBjaGFyT2Zmc2V0KQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gIDsKLSAgCi0gIC8qKgotICAgKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB0byBpc3N1ZSBhIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSAgIG1zZyAgICAgICAgICAgICAgIEEgc3RyaW5nIG1lc3NhZ2UgdG8gb3V0cHV0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbWVzc2FnZShTdHJpbmcgbXNnKTsKLQotfQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbC9Qcm9ibGVtTGlzdGVuZXJEZWZhdWx0LmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL1Byb2JsZW1MaXN0ZW5lckRlZmF1bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjFhN2JhMi4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL1Byb2JsZW1MaXN0ZW5lckRlZmF1bHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcueG1sLnNheC5FcnJvckhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgaXMgdGhlIGludGVyZmFjZSB0aGF0IHRoZSBYU0wgcHJvY2Vzc29yIGNhbGxzIHdoZW4gaXQgCi0gKiBoYXMgYSBwcm9ibGVtIG9mIHNvbWUga2luZCwgZWl0aGVyIGFuIGVycm9yIG9yIGEgd2FybmluZy4KLSAqIFVzZXJzIHNob3VsZCBhc3MgdGhlIFhTTFRFbmdpbmVJbXBsIGNsYXNzIHRvIHNldFByb2JsZW1MaXN0ZW5lcgotICogaWYgdGhleSB3aXNoIGFuIG9iamVjdCBpbnN0YW5jZSB0byBiZSBjYWxsZWQgd2hlbiBhIHByb2JsZW0KLSAqIGV2ZW50IG9jY3Vycy4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgUHJvYmxlbUxpc3RlbmVyRGVmYXVsdCBleHRlbmRzIG9yZy5hcGFjaGUueG1sLnV0aWxzLkRlZmF1bHRFcnJvckhhbmRsZXIgaW1wbGVtZW50cyBQcm9ibGVtTGlzdGVuZXIgCi17Ci0gIC8vRXJyb3JIYW5kbGVyIG1fZXJyb3JIYW5kbGVyID0gbnVsbDsKLSAgUHJvYmxlbUxpc3RlbmVyIG1fcHJvYmxlbUxpc3RlbmVyID0gbnVsbDsKLSAgCi0gIHB1YmxpYyBQcm9ibGVtTGlzdGVuZXJEZWZhdWx0KCkKLSAgewotICAgIHN1cGVyKCk7ICAgIAotICB9Ci0gIAotICBwdWJsaWMgUHJvYmxlbUxpc3RlbmVyRGVmYXVsdChQcm9ibGVtTGlzdGVuZXIgbCkKLSAgeyAKLSAgICAvL21fZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKLSAgICBtX3Byb2JsZW1MaXN0ZW5lciA9IGw7Ci0gIH0KLSAgLyoKLSAgcHVibGljIHZvaWQgc2V0RXJyb3JIYW5kbGVyIChFcnJvckhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIG1fZXJyb3JIYW5kbGVyID0gaGFuZGxlcjsKLSAgfQotICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9ibGVtTGlzdGVuZXIgKFByb2JsZW1MaXN0ZW5lciBsKQotICB7Ci0gICAgbV9wcm9ibGVtTGlzdGVuZXIgPSBsOwotICB9Ci0gIAotICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlciAoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7IC8vIG1fZXJyb3JIYW5kbGVyOwotICB9Ci0gIAotICBwdWJsaWMgUHJvYmxlbUxpc3RlbmVyIGdldFByb2JsZW1MaXN0ZW5lciAoKQotICB7Ci0gICAgaWYgKG1fcHJvYmxlbUxpc3RlbmVyICE9IG51bGwpCi0gICAgICByZXR1cm4gbV9wcm9ibGVtTGlzdGVuZXI7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHRoaXM7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB0byBpc3N1ZSBhIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSAgIG1zZyAgICAgICAgICAgICAgIEEgc3RyaW5nIG1lc3NhZ2UgdG8gb3V0cHV0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbWVzc2FnZShTdHJpbmcgbXNnKQotICB7Ci0gICAgICBpZiAobV9wcm9ibGVtTGlzdGVuZXIgIT0gbnVsbCkKLSAgICAgICAgbV9wcm9ibGVtTGlzdGVuZXIubWVzc2FnZShtc2cpOwotICAgICAgc3luY2hyb25pemVkICh0aGlzKQotICAgICAgeyAgCi0gICAgICAgIG5ldyBqYXZhLmlvLlByaW50V3JpdGVyKCAgU3lzdGVtLmVyciwgdHJ1ZSApLnByaW50bG4oIG1zZyApOwotICAgICAgfSAKLSAgIAotICAgIHJldHVybiBmYWxzZTsgICAgICAgICAgICAgICAgICAgIC8vIHdlIGRvbid0IGtub3cgdGhpcyBpcyBhbiBlcnJvciAKLSAgfQotICAKLSAgcHVibGljIGJvb2xlYW4gcHJvYmxlbShzaG9ydCB3aGVyZSwgc2hvcnQgY2xhc3NpZmljYXRpb24sIAotICAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qgc3R5bGVOb2RlLCBOb2RlIHNvdXJjZU5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2csIFN0cmluZyBpZCwgaW50IGxpbmVObywgaW50IGNoYXJPZmZzZXQpCi0gIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gICAKLSAgewotICAgIGlmIChtX3Byb2JsZW1MaXN0ZW5lciAhPSBudWxsKQotICAgICAgcmV0dXJuIG1fcHJvYmxlbUxpc3RlbmVyLnByb2JsZW0od2hlcmUsIGNsYXNzaWZpY2F0aW9uLCBzdHlsZU5vZGUsIHNvdXJjZU5vZGUsIG1zZywgaWQsIGxpbmVObywgY2hhck9mZnNldCk7Ci0gICAgZWxzZQotICAgIHsgIAotICAgICAgdGhpcy5lcnJvcihuZXcgU0FYUGFyc2VFeGNlcHRpb24obXNnLCBudWxsLCBpZCwgbGluZU5vLCBjaGFyT2Zmc2V0KSk7Ci0gICAgICByZXR1cm4gZmFsc2U7ICAgCi0gICAgfQotICB9IAotICAKLSAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmIChtX3Byb2JsZW1MaXN0ZW5lciA9PSBudWxsKQotICAgIHsKLSAgICAgIHN1cGVyLndhcm5pbmcoZXhjZXB0aW9uKTsgICAgCi0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBib29sZWFuIHNob3VsZHRocm93ID0gbV9wcm9ibGVtTGlzdGVuZXIucHJvYmxlbShYU0xQUk9DRVNTT1IsIFdBUk5JTkcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24uZ2V0TGluZU51bWJlcigpLCAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRDb2x1bW5OdW1iZXIoKSk7IAotICAgICAgaWYgKHNob3VsZHRocm93KQotICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGV4Y2VwdGlvbik7Ci0gICAgfQotICB9Ci0gIAotICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmIChtX3Byb2JsZW1MaXN0ZW5lciA9PSBudWxsKQotICAgIHsKLSAgICAgIHN1cGVyLmVycm9yKGV4Y2VwdGlvbik7ICAgIAotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgYm9vbGVhbiBzaG91bGR0aHJvdyA9IG1fcHJvYmxlbUxpc3RlbmVyLnByb2JsZW0oWFNMUFJPQ0VTU09SLCBFUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldFN5c3RlbUlkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRMaW5lTnVtYmVyKCksICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldENvbHVtbk51bWJlcigpKTsgCi0gICAgICBpZiAoc2hvdWxkdGhyb3cpCi0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZXhjZXB0aW9uKTsKLSAgICB9Ci0gIH0KLSAgCi0gIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobV9wcm9ibGVtTGlzdGVuZXIgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBzdXBlci5mYXRhbEVycm9yKGV4Y2VwdGlvbik7ICAgIAotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgYm9vbGVhbiBzaG91bGR0aHJvdyA9IG1fcHJvYmxlbUxpc3RlbmVyLnByb2JsZW0oWFNMUFJPQ0VTU09SLCBFUlJPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldFN5c3RlbUlkKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRMaW5lTnVtYmVyKCksICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldENvbHVtbk51bWJlcigpKTsgCi0gICAgICBpZiAoc2hvdWxkdGhyb3cpCi0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZXhjZXB0aW9uKTsKLSAgICB9Ci0gIH0KLSAgCi0gIHB1YmxpYyB2b2lkIHdhcm5pbmcoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmIChtX3Byb2JsZW1MaXN0ZW5lciA9PSBudWxsKQotICAgIHsKLSAgICAgIHN1cGVyLndhcm5pbmcoZXhjZXB0aW9uKTsgICAgCi0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBib29sZWFuIHNob3VsZHRocm93ID0gdHJ1ZTsKLSAgICAgIHRyeXsKLSAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBleGNlcHRpb24uZ2V0TG9jYXRvcigpOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgc2hvdWxkdGhyb3cgPSBtX3Byb2JsZW1MaXN0ZW5lci5wcm9ibGVtKFhTTFBST0NFU1NPUiwgV0FSTklORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRTeXN0ZW1JZCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdG9yLmdldExpbmVOdW1iZXIoKSwgIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIAotICAgICAgICB7Ci0gICAgICAgICAgc2hvdWxkdGhyb3cgPSBtX3Byb2JsZW1MaXN0ZW5lci5wcm9ibGVtKFhTTFBST0NFU1NPUiwgTUVTU0FHRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICAgIH0KLSAgICAgIGlmIChzaG91bGR0aHJvdykKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGV4Y2VwdGlvbik7Ci0gICAgfQotICB9Ci0gIAotICBwdWJsaWMgdm9pZCBlcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKG1fcHJvYmxlbUxpc3RlbmVyID09IG51bGwpCi0gICAgewotICAgICAgc3VwZXIuZXJyb3IoZXhjZXB0aW9uKTsgICAgCi0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBib29sZWFuIHNob3VsZHRocm93ID0gdHJ1ZTsKLSAgICAgIHRyeXsKLSAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBleGNlcHRpb24uZ2V0TG9jYXRvcigpOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgc2hvdWxkdGhyb3cgPSBtX3Byb2JsZW1MaXN0ZW5lci5wcm9ibGVtKFhTTFBST0NFU1NPUiwgRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRMaW5lTnVtYmVyKCksICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSAKLSAgICAgICAgewotICAgICAgICAgIHNob3VsZHRocm93ID0gbV9wcm9ibGVtTGlzdGVuZXIucHJvYmxlbShYU0xQUk9DRVNTT1IsIEVSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24uZ2V0TWVzc2FnZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgICAgfQotICAgICAgaWYgKHNob3VsZHRocm93KQotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZXhjZXB0aW9uKTsKLSAgICB9Ci0gIH0KLSAgCi0gIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmIChtX3Byb2JsZW1MaXN0ZW5lciA9PSBudWxsKQotICAgIHsKLSAgICAgIHN1cGVyLmZhdGFsRXJyb3IoZXhjZXB0aW9uKTsgICAgCi0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBib29sZWFuIHNob3VsZHRocm93ID0gdHJ1ZTsKLSAgICAgIHRyeXsKLSAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBleGNlcHRpb24uZ2V0TG9jYXRvcigpOwotICAgICAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgc2hvdWxkdGhyb3cgPSBtX3Byb2JsZW1MaXN0ZW5lci5wcm9ibGVtKFhTTFBST0NFU1NPUiwgRVJST1IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRMaW5lTnVtYmVyKCksICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSAKLSAgICAgICAgewotICAgICAgICAgIHNob3VsZHRocm93ID0gbV9wcm9ibGVtTGlzdGVuZXIucHJvYmxlbShYU0xQUk9DRVNTT1IsIEVSUk9SLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24uZ2V0TWVzc2FnZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgICAgfQotICAgICAgaWYgKHNob3VsZHRocm93KQotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZXhjZXB0aW9uKTsKLSAgICB9Ci0gIH0KLSAgLyoKLSAgcHJpdmF0ZSBjbGFzcyBNZXNzYWdlTWdyIGV4dGVuZHMgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5Nc2dNZ3IgCi0gIHsKLSAgICB2b2lkIE1lc3NhZ2VNZ3IoKQotICAgIHt9Ci0gIH0qLwotCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL1RyZWVXYWxrZXIuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvVHJlZVdhbGtlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYmM0NzAxLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvVHJlZVdhbGtlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xIAotICogCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWw7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuQXR0TGlzdDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgZG9lcyBhIHByZS1vcmRlciB3YWxrIG9mIHRoZSBET00gdHJlZSwgY2FsbGluZyB0aGUgRm9ybWF0dGVyTGlzdGVuZXIKLSAqIGludGVyZmFjZSBhcyBpdCBnb2VzLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBUcmVlV2Fsa2VyIC8vZXh0ZW5kcyBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyCi17Ci0gIAotICBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyIG1fd2Fsa2VyOyAKLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICogQHBhcmFtICAgZm9ybWF0dGVyTGlzdGVuZXIgVGhlIGltcGxlbWVudGlvbiBvZiB0aGUgCi0gICAqIEZvcm1hdHRlckxpc3RlbmVyIG9wZXJhdGlvbiAodG9YTUxTdHJpbmcsIGRpZ2VzdCwgLi4uKQotICAgKi8KLSAgcHVibGljIFRyZWVXYWxrZXIoRG9jdW1lbnRIYW5kbGVyIGZvcm1hdHRlckxpc3RlbmVyKSAKLSAgewotICAgIGlmKGZvcm1hdHRlckxpc3RlbmVyIGluc3RhbmNlb2YgRm9ybWF0dGVyVG9YTUwpCi0gICAgICBtX3dhbGtlciA9IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyKCgoRm9ybWF0dGVyVG9YTUwpZm9ybWF0dGVyTGlzdGVuZXIpLmdldFNlcmlhbGl6ZXJPYmplY3QoKSwgbmV3IG9yZy5hcGFjaGUueHBhdGguRE9NMkhlbHBlcigpKTsKLSAgICAvL3N1cGVyKGZvcm1hdHRlckxpc3RlbmVyKTsKLSAgfSAKLSAKLSAgLyoqCi0gICAqIFBlcmZvcm0gYSBwcmUtb3JkZXIgdHJhdmVyc2FsIG5vbi1yZWN1cnNpdmUgc3R5bGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmF2ZXJzZShOb2RlIHBvcykgdGhyb3dzIFNBWEV4Y2VwdGlvbiAKLSAgewotICAgIG1fd2Fsa2VyLnRyYXZlcnNlKHBvcyk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBQZXJmb3JtIGEgcHJlLW9yZGVyIHRyYXZlcnNhbCBub24tcmVjdXJzaXZlIHN0eWxlLgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhdmVyc2UoTm9kZSBwb3MsIE5vZGUgdG9wKSB0aHJvd3MgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgbV93YWxrZXIudHJhdmVyc2UocG9zLCB0b3ApOwotICB9Ci0gIAotICAKLSAgCi19ICAvL1RyZWVXYWxrZXIKZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvWE1MUGFyc2VyTGlhaXNvbi5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbC9YTUxQYXJzZXJMaWFpc29uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgyMmI0NmIuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbC9YTUxQYXJzZXJMaWFpc29uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkRPTTJIZWxwZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgaXMgdGhlIGludGVyZmFjZSB0aGF0IHRoZSBYU0wgcHJvY2Vzc29yIGNhbGxzIHdoZW4gaXQgCi0gKiBoYXMgYSBwcm9ibGVtIG9mIHNvbWUga2luZCwgZWl0aGVyIGFuIGVycm9yIG9yIGEgd2FybmluZy4KLSAqIFVzZXJzIHNob3VsZCBhc3MgdGhlIFhTTFRFbmdpbmVJbXBsIGNsYXNzIHRvIHNldFByb2JsZW1MaXN0ZW5lcgotICogaWYgdGhleSB3aXNoIGFuIG9iamVjdCBpbnN0YW5jZSB0byBiZSBjYWxsZWQgd2hlbiBhIHByb2JsZW0KLSAqIGV2ZW50IG9jY3Vycy4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgWE1MUGFyc2VyTGlhaXNvbiBleHRlbmRzIERPTTJIZWxwZXIKLXsKLSAgCi0KLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvWE1MUGFyc2VyTGlhaXNvbkRlZmF1bHQuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94cGF0aC94bWwvWE1MUGFyc2VyTGlhaXNvbkRlZmF1bHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjNhZGU2Yy4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL1hNTFBhcnNlckxpYWlzb25EZWZhdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLWltcG9ydCBqYXZhLm5ldC4qOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLlhNTFBhcnNlckxpYWlzb247Ci0KLS8qKgotICogQSBjbGFzcyB0aGF0IGhhbmRsZXMgaW50ZXJmYWNpbmcgSUJNJ3MgWE1MNEoyIHRvIHRoZSAKLSAqIExvdHVzIFhTTCBQcm9jZXNzb3IuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhNTFBhcnNlckxpYWlzb25EZWZhdWx0IGV4dGVuZHMgWE1MUGFyc2VyTGlhaXNvbiAKLXsKLSAgCi19Ci0KLQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbC9wYWNrYWdlLmh0bWwgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTdlZTdkMS4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHBhdGgveG1sL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDE1ICswLDAgQEAKLTxIVE1MPjxIRUFEPjwvSEVBRD48Qk9EWT4KLSAgICAgPFA+SW5mcmFzdHJ1Y3R1cmUgZm9yIHdvcmtpbmcgd2l0aCBhbiBYTUwgcGFyc2VyLjwvUD4KLSAgIAotICAgICAgPFA+QW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5YTUxQYXJzZXJMaWFpc29ufSBpbnRlcmZhY2UgcHJvdmlkZXMgYSBsaWFpc29uCi0gICAgIGJldHdlZW4gdGhlIFhTTFQgcHJvY2Vzc29yIGFuZCBhbiBYTUwgcGFyc2VyLiBVbmxlc3MgeW91IHNwZWNpZnkgYW4gWE1MIHBhcnNlciBhbmQgeW91ciBvd24gaW1wbGVtZW50YXRpb24gb2YgCi0gICAgIHRoZSBYTUxQYXJzZXJMaWFpc29uIGludGVyZmFjZSwgWGFsYW4tSmF2YSB1c2VzIHRoZSAKLSAgICAge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLlhNTFBhcnNlckxpYWlzb25EZWZhdWx0fTo8L1A+Ci0gICAgIDxQPlRoaXMgcGFja2FnZSBhbHNvIGluY2x1ZGVzIGZvdXIgaW1wbGVtZW50YXRpb25zIG9mIHRoZSA8QSBocmVmPSJodHRwOi8vd3d3Lm1lZ2dpbnNvbi5jb20vU0FYL3NheC5odG1sIiB0YXJnZXQ9Il90b3AiPlNBWDwvQT4gPEEgaHJlZj0iaHR0cDovL3d3dy5tZWdnaW5zb24uY29tL1NBWC9qYXZhZG9jL29yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlci5odG1sI190b3AiIHRhcmdldD0iX3RvcCI+b3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyPC9BPiBpbnRlcmZhY2U6PC9QPgotICAgICA8VUw+Ci0gICAgIDxMST57QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuRm9ybWF0dGVyVG9ET019PC9MST4KLSAgICAgPExJPntAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5Gb3JtYXR0ZXJUb1hNTH08L0xJPgotICAgICA8TEk+e0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLkZvcm1hdHRlclRvSFRNTH0gKGFuIGV4dGVuc2lvbiBvZiBGb3JtYXR0ZXJUb1hNTCk8L0xJPgotICAgICA8TEk+e0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLkZvcm1hdHRlclRvVGV4dH08L0xJPgotICAgICA8L1VMPgotICAgPC9CT0RZPjwvSFRNTD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0LmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhNDI0M2IuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvU3R5bGVzaGVldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdDsKLQotaW1wb3J0IGphdmEubmV0Lio7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLQotLyoqCi0gKiBSZXByZXNlbnRzIHRoZSBiYXNlIHN0eWxlc2hlZXQgb3IgYW4KLSAqICJpbXBvcnQiIHN0eWxlc2hlZXQ7ICJpbmNsdWRlIiBzdHlsZXNoZWV0cyBhcmUKLSAqIGNvbWJpbmVkIHdpdGggdGhlIGluY2x1ZGluZyBzdHlsZXNoZWV0LgotICogQXQgdGhlIG1vbWVudCB0aGVzZSBzdHlsZXNoZWV0cyBjYW4gbm90IGJlIHJldXNlZCB3aXRoaW4gdGhlCi0gKiBzdHlsZXNoZWV0IHRyZWUgb3IgYmV0d2VlbiB0cmVlcy4gIFRoaXMgbmVlZHMgdG8gYmUgZml4ZWQKLSAqIGluIHRoZSBmdXR1cmUuCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFN0eWxlc2hlZXQgIGV4dGVuZHMgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldAoteyAKLQkKLQkgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBhIFN0eWxlc2hlZXQgbmVlZHMgYSBEb2N1bWVudC4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXQoU3R5bGVzaGVldFJvb3Qgcm9vdCwKLSAgICAgICAgICAgICAgICAgICAgWFNMVEVuZ2luZUltcGwgcHJvY2Vzc29yLAotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZUlkZW50aWZpZXIpCi0gICAgdGhyb3dzIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiwKLSAgICAgICAgICAgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24sCi0gICAgICAgICAgIElPRXhjZXB0aW9uLAotICAgICAgICAgICBTQVhFeGNlcHRpb24KLSAgewotCQlzdXBlcihyb290LmdldE9iamVjdCgpKTsgICAgCi0gIH0KLQkKLQkvKioKLSAgICogQ29uc3RydWN0b3IgdXNpbmcgYW4gb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3QuCi0gICAqIAotICAgKiBAcGFyYW0gcyBhbiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0IG9iamVjdAotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXQob3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldCBzKSAgICAKLSAgeyAKLQkJc3VwZXIocyk7Ci0gICAgICAgCi0gIH0KLQkKLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1N0eWxlc2hlZXRIYW5kbGVyLmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0SGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYmMyOWFmLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1N0eWxlc2hlZXRIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEgIAotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0OwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEubmV0Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OyAKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEluaXRpYWxpemVzIGFuZCBwcm9jZXNzZXMgYSBzdHlsZXNoZWV0IHZpYSBTQVggZXZlbnRzLgotICogSWYgeW91IG5lZWQgdG8gYWx0ZXIgdGhlIGNvZGUgaW4gaGVyZSwKLSAqIGl0IGlzIG5vdCBmb3IgdGhlIGZhaW50LW9mLWhlYXJ0LCBkdWUgdG8gdGhlIHN0YXRlIHRyYWNraW5nCi0gKiB0aGF0IGhhcyB0byBiZSBkb25lIGR1ZSB0byB0aGUgU0FYIGV2ZW50IG1vZGVsLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBTdHlsZXNoZWV0SGFuZGxlciBleHRlbmRzIFBhcnNlckFkYXB0ZXIKLSAgCi17Ci0gIAotICAvKioKLSAgICogSW5zdGFuY2UgY29uc3RydWN0b3IuLi4gCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgIFRoZSBYU0xUUHJvY2Vzc29yIGltcGxlbWVudGF0aW9uLgotICAgKiBAcGFyYW0gc3R5bGVzaGVldCBUaGUgcm9vdCBzdHlsZXNoZWV0LgotICAgKiAgICAKLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0SGFuZGxlcihYU0xURW5naW5lSW1wbCBwcm9jZXNzb3IsIFN0eWxlc2hlZXQgc3R5bGVzaGVldFRyZWUpICAgIAotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgCi0gICAgICBzdXBlcihuZXcgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIoKSk7Ci0gICAgICAvL3RyeXsKLSAgICAgIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIgPSAKLSAgICAgICAgICAgIG5ldyBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5TdHlsZXNoZWV0SGFuZGxlcihwcm9jZXNzb3IuZ2V0VHJhbnNmb3JtZXJGYWN0b3J5KCkpOwotICAgICAgaGFuZGxlci5wdXNoU3R5bGVzaGVldChzdHlsZXNoZWV0VHJlZSk7Ci0gICAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICAgIC8vfQotICAgIC8vY2F0Y2ggKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICAvL3t9Ci0gIH0gCi0gIAotICAvKioKLSAgICogSW5zdGFuY2UgY29uc3RydWN0b3IuLi4gCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgIFRoZSBYU0xUUHJvY2Vzc29yIGltcGxlbWVudGF0aW9uLgotICAgKiBAcGFyYW0gc3R5bGVzaGVldCBUaGUgcm9vdCBzdHlsZXNoZWV0LiAKLSAgICogQGV4Y2VwdGlvbiBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gIAotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRIYW5kbGVyKFhTTFRFbmdpbmVJbXBsIHByb2Nlc3NvciwgU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldFRyZWUpICAgIAotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgLy90cnl7Ci0gICAgICBzdXBlcihuZXcgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIoKSk7Ci0gICAgICBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5TdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyID0gCi0gICAgICAgICAgICBuZXcgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuU3R5bGVzaGVldEhhbmRsZXIocHJvY2Vzc29yLmdldFRyYW5zZm9ybWVyRmFjdG9yeSgpKTsKLSAgICAgIGhhbmRsZXIucHVzaFN0eWxlc2hlZXQoc3R5bGVzaGVldFRyZWUuZ2V0T2JqZWN0KCkpOwotICAgICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgICAvL30KLSAgICAvL2NhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB0Y2UpCi0gICAgLy97fQotICB9IAotICAKLSAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0Um9vdC5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvU3R5bGVzaGVldFJvb3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODhjMmY5NC4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0Um9vdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDY2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xICAKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgamF2YS5uZXQuKjsKLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5czsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5Gb3JtYXR0ZXJUb1hNTDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5Gb3JtYXR0ZXJUb0hUTUw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuRm9ybWF0dGVyVG9UZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLkZvcm1hdHRlclRvRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPiAKLSAqIEJpbmFyeSByZXByZXNlbnRhdGlvbiBvZiBhIHN0eWxlc2hlZXQgLS0gdXNlIHRoZSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRQcm9jZXNzb3J9IFByb2Nlc3NTdHlsZXNoZWV0Ci0gKiBtZXRob2QgdG8gY3JlYXRlIGEgU3R5bGVzaGVldFJvb3QgYW5kIGltcHJvdmUgcGVyZm9ybWFuY2UgZm9yIGEgc3R5bGVzaGVldCBwZXJmb3JtaW5nIG11bHRpcGxlIHRyYW5zZm9ybWF0aW9ucy4KLSAqIEFsc28gcmVxdWlyZWQgZm9yIFhTTFRQcm9jZXNzb3IgdG8gZnVuY3Rpb24gYXMgU0FYIERvY3VtZW50SGFuZGxlci4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgU3R5bGVzaGVldFJvb3QgZXh0ZW5kcyBTdHlsZXNoZWV0Ci17Ci0gIAotICBwcml2YXRlIFN0cmluZyBtX2xpYWlzb25DbGFzc1VzZWRUb0NyZWF0ZSA9IG51bGw7Ci0gIHByaXZhdGUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3QgbV9zUm9vdE9iamVjdDsKLSAgCi0gIC8qKgotICAgKiBVc2VzIGFuIFhTTCBzdHlsZXNoZWV0IGRvY3VtZW50LgotICAgKiBAcGFyYW0gcHJvY2Vzc29yICBUaGUgWFNMVFByb2Nlc3NvciBpbXBsZW1lbnRhdGlvbi4KLSAgICogQHBhcmFtIGJhc2VJZGVudGlmaWVyIFRoZSBmaWxlIG5hbWUgb3IgVVJMIGZvciB0aGUgWFNMIHN0eWxlc2hlZXQuCi0gICAqIEBleGNlcHRpb24gVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRocm93biAKLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdChYU0xURW5naW5lSW1wbCBwcm9jZXNzb3IsCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZUlkZW50aWZpZXIpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7IAotCQlzdXBlcihudWxsKTsKLSAgICBtX3NSb290T2JqZWN0ID0gbmV3IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290KHByb2Nlc3Nvci5nZXRUcmFuc2Zvcm1lckZhY3RvcnkoKS5nZXRFcnJvckxpc3RlbmVyKCkpOyAKLSAgICBpZiAocHJvY2Vzc29yLmdldFhNTFByb2Nlc3NvckxpYWlzb24oKSE9IG51bGwpCi0gICAgICBtX2xpYWlzb25DbGFzc1VzZWRUb0NyZWF0ZSA9ICgoT2JqZWN0KXByb2Nlc3Nvci5nZXRYTUxQcm9jZXNzb3JMaWFpc29uKCkpLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgIAotICB9ICAKLQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciB1c2luZyBhbiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdC4KLSAgICogCi0gICAqIEBwYXJhbSBzIGFuIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290IG9iamVjdAotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRSb290KG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290IHMpICAgIAotICB7IAotCQlzdXBlcihudWxsKTsKLSAgICBtX3NSb290T2JqZWN0ID0gczsgICAgIAotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIHRoZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdCBvYmplY3QKLSAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3R5bGVzaGVldCByb290LgotICAgKiAgCi0gICAqIEByZXR1cm4gYW4gb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Qgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3QgZ2V0T2JqZWN0KCkKLSAgewotICAgIHJldHVybiBtX3NSb290T2JqZWN0OwotICB9ICAKLSAgCi0gIC8qKgotICAgKiBUcmFuc2Zvcm0gdGhlIFhNTCBzb3VyY2UgdHJlZSBhbmQgcGxhY2UgdGhlIG91dHB1dCBpbiB0aGUgcmVzdWx0IHRyZWUgdGFyZ2V0LgotICAgKiBUaGlzIG1ldGhvZCB1c2VzIGEgbmV3IFhTTFRQcm9jZXNzb3IgaW5zdGFuY2UgdG8gdHJhY2sgdGhlIHJ1bm5pbmcgc3RhdGUuCi0gICAqIEBwYXJhbSB4bWxTb3VyY2UgIFRoZSBYTUwgaW5wdXQgc291cmNlIHRyZWUuCi0gICAqIEBwYXJhbSBvdXRwdXRUYXJnZXQgVGhlIG91dHB1dCByZXN1bHQgdHJlZS4KLSAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFByb2Nlc3NvciNwcm9jZXNzKG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUSW5wdXRTb3VyY2UsIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUSW5wdXRTb3VyY2UsIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUmVzdWx0VGFyZ2V0KQotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2VzcyggWFNMVElucHV0U291cmNlIHhtbFNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgWFNMVFJlc3VsdFRhcmdldCBvdXRwdXRUYXJnZXQpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwKLSAgICAgICAgICAgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24sCi0gICAgICAgICAgIElPRXhjZXB0aW9uCi0gIHsKLSAgICBYU0xUUHJvY2Vzc29yIGlwcm9jZXNzb3IgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG51bGwgIT0gbV9saWFpc29uQ2xhc3NVc2VkVG9DcmVhdGUpID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUUHJvY2Vzc29yRmFjdG9yeSgpLmdldFByb2Nlc3NvclVzaW5nTGlhaXNvbk5hbWUobV9saWFpc29uQ2xhc3NVc2VkVG9DcmVhdGUpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBYU0xUUHJvY2Vzc29yRmFjdG9yeSgpLmdldFByb2Nlc3NvcigpOwotICAgIHByb2Nlc3MoaXByb2Nlc3NvciwgeG1sU291cmNlLCBvdXRwdXRUYXJnZXQpOwotICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIFRyYW5zZm9ybSB0aGUgWE1MIHNvdXJjZSB0cmVlIGFuZCBwbGFjZSB0aGUgb3V0cHV0IGluIHRoZSByZXN1bHQgdHJlZSB0YXJnZXQuCi0gICAqIFVzZSB0aGlzIHZlcnNpb24gb2YgdGhlIFN0eWxlc2hlZXRSb290IHByb2Nlc3MoKSBtZXRob2QgaWYgeW91IGhhdmUgdXNlZCBhbgotICAgKiBYU0xUUHJvY2Vzc29yIG9iamVjdCB0byBzZXQgYSBzdHlsZXNoZWV0IHBhcmFtZXRlci4gVGhhdCBvYmplY3QgaXMgbm93IHRoZSBpcHJvY2Vzc29yIHBhcmFtZXRlci4KLSAgICogQHBhcmFtIGlwcm9jZXNzb3IgIFRoZSBYU0xUUHJvY2Vzc29yIHRoYXQgd2lsbCB0cmFjayB0aGUgcnVubmluZyBzdGF0ZS4KLSAgICogQHBhcmFtIHhtbFNvdXJjZSAgVGhlIFhNTCBpbnB1dCBzb3VyY2UgdHJlZS4KLSAgICogQHBhcmFtIG91dHB1dFRhcmdldCBUaGUgb3V0cHV0IHJlc3VsdCB0cmVlLgotICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUHJvY2Vzc29yI3Byb2Nlc3Mob3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRJbnB1dFNvdXJjZSwgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRJbnB1dFNvdXJjZSwgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRSZXN1bHRUYXJnZXQpCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzKCBYU0xUUHJvY2Vzc29yIGlwcm9jZXNzb3IsIFhTTFRJbnB1dFNvdXJjZSB4bWxTb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgIFhTTFRSZXN1bHRUYXJnZXQgb3V0cHV0VGFyZ2V0KQotICAgIHRocm93cyBTQVhFeGNlcHRpb24sCi0gICAgICAgICAgIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwKLSAgICAgICAgICAgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAotICAgICAgICAgICBJT0V4Y2VwdGlvbgotICB7Ci0gICAgLy9wcm9jZXNzKGlwcm9jZXNzb3IsIGlwcm9jZXNzb3IuZ2V0U291cmNlVHJlZUZyb21JbnB1dCh4bWxTb3VyY2UpLCBvdXRwdXRUYXJnZXQpOwotCQlYU0xURW5naW5lSW1wbCBwcm9jZXNzb3IgPSAoWFNMVEVuZ2luZUltcGwpaXByb2Nlc3NvcjsgLy8gVE9ETzogQ2hlY2sgZm9yIGNsYXNzIGNhc3QgZXhjZXB0aW9uCi0JCQotICAgIHN5bmNocm9uaXplZChwcm9jZXNzb3IpCi0gICAgeyAgICAgIAotICAgICAgcHJvY2Vzc29yLnNldFN0eWxlc2hlZXQodGhpcyk7Ci0KLSAgICAgIHRyeQotICAgICAgewotCQkJCXByb2Nlc3Nvci5nZXRUcmFuc2Zvcm1lcigpLnRyYW5zZm9ybSh4bWxTb3VyY2UuZ2V0U291cmNlT2JqZWN0KCksCi0JCQkJCQkJCQkJCQkJCQkJCQkJCQkJIG91dHB1dFRhcmdldC5nZXRSZXN1bHRPYmplY3QoKSk7Ci0JCQl9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUpOyAKLSAgICAgIH0gICAgICAgICAgICAgCi0gICAgfQotICAgICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIFRyYW5zZm9ybSB0aGUgWE1MIHNvdXJjZSB0cmVlIChhIERPTSBOb2RlKSBhbmQgcGxhY2UgdGhlIG91dHB1dCBpbiB0aGUgcmVzdWx0IHRyZWUgdGFyZ2V0LgotICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kLiBZb3UgY2FuIGFsc28gdXNlIGEgRE9NIE5vZGUgdG8gaW5zdGFudGlhdGUgYW4gWFNMVElucHV0U291cmNlIG9iamVjdCwKLSAgICogYW5kIGNhbGwge0BsaW5rICNwcm9jZXNzKG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUHJvY2Vzc29yLCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVElucHV0U291cmNlLCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFJlc3VsdFRhcmdldCl9IG9yCi0gICAqIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFByb2Nlc3NvciNwcm9jZXNzKG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUSW5wdXRTb3VyY2UsIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUSW5wdXRTb3VyY2UsIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUmVzdWx0VGFyZ2V0KX0uCi0gICAqIEBwYXJhbSBpcHJvY2Vzc29yICBUaGUgcHJvY2Vzc29yIHRoYXQgd2lsbCB0cmFjayB0aGUgcnVubmluZyBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZVRyZWUgIFRoZSBpbnB1dCBzb3VyY2UgdHJlZSBpbiB0aGUgZm9ybSBvZiBhIERPTSBOb2RlLgotICAgKiBAcGFyYW0gb3V0cHV0VGFyZ2V0IFRoZSBvdXRwdXQgcmVzdWx0IHRyZWUuCi0gICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzKCBYU0xUUHJvY2Vzc29yIGlwcm9jZXNzb3IsIE5vZGUgc291cmNlVHJlZSwKLSAgICAgICAgICAgICAgICAgICAgICAgWFNMVFJlc3VsdFRhcmdldCBvdXRwdXRUYXJnZXQpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiwKLSAgICAgICAgICAgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24sCi0gICAgICAgICAgIElPRXhjZXB0aW9uCi0gIHsKLQkJCi0gICAgWFNMVEVuZ2luZUltcGwgcHJvY2Vzc29yID0gKFhTTFRFbmdpbmVJbXBsKWlwcm9jZXNzb3I7IC8vIFRPRE86IENoZWNrIGZvciBjbGFzcyBjYXN0IGV4Y2VwdGlvbgotCQkvL2NoZWNrSW5pdChwcm9jZXNzb3IpOwotICAgIHN5bmNocm9uaXplZChwcm9jZXNzb3IpCi0gICAgewotICAgICAgLy9wcm9jZXNzb3Iuc3dpdGNoTGlhaXNvbnNJZk5lZWRlZChzb3VyY2VUcmVlLCBvdXRwdXRUYXJnZXQuZ2V0Tm9kZSgpKTsKLQotICAgICAgcHJvY2Vzc29yLnNldFN0eWxlc2hlZXQodGhpcyk7Ci0KLSAgICAgIE91dHB1dFN0cmVhbSBvc3RyZWFtID0gbnVsbDsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0JCQkJcHJvY2Vzc29yLmdldFRyYW5zZm9ybWVyKCkudHJhbnNmb3JtKG5ldyBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2Uoc291cmNlVHJlZSksCi0JCQkJCQkJCQkJCQkJCQkJCQkJCQkJIG91dHB1dFRhcmdldC5nZXRSZXN1bHRPYmplY3QoKSk7Ci0gICAgICAgCi0gICAgICB9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUpOyAKLSAgICAgIH0KLSAgICAgICAKLSAgICAgIGZpbmFsbHkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgIT0gb3N0cmVhbSkKLSAgICAgICAgewotICAgICAgICAgIG9zdHJlYW0uY2xvc2UoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICB9Ci0gIAotICAvKioKLSAgICogQ3JlYXRlcyBhIGNvbXBhdGlibGUgU0FYIHNlcmlhbGl6ZXIgZm9yIHRoZSBzcGVjaWZpZWQgd3JpdGVyCi0gICAqIGFuZCBvdXRwdXQgZm9ybWF0LiBJZiB0aGUgb3V0cHV0IGZvcm1hdCBpcyBtaXNzaW5nLCB0aGUgZGVmYXVsdAotICAgKiBpcyBhbiBYTUwgZm9ybWF0IHdpdGggVVRGOCBlbmNvZGluZy4KLSAgICoKLSAgICogQHBhcmFtIHdyaXRlciBUaGUgd3JpdGVyCi0gICAqIEBwYXJhbSBmb3JtYXQgVGhlIG91dHB1dCBmb3JtYXQKLSAgICogQHJldHVybiBBIGNvbXBhdGlibGUgU0FYIHNlcmlhbGl6ZXIKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEhhbmRsZXIgbWFrZVNBWFNlcmlhbGl6ZXIoIFdyaXRlciB3cml0ZXIsIE91dHB1dEZvcm1hdCBmb3JtYXQgKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIAotICB7Ci0gICAgRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXI7Ci0gICAgaWYgKCBmb3JtYXQgPT0gbnVsbCApCi0gICAgewotICAgICAgZm9ybWF0ID0gbmV3IE91dHB1dEZvcm1hdCggInhtbCIsICJVVEYtOCIsIGZhbHNlICk7Ci0gICAgICBoYW5kbGVyID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSAKLSAgICB7Ci0gICAgICBoYW5kbGVyID0gbmV3IFBhcnNlckFkYXB0ZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgICAgT3V0cHV0UHJvcGVydGllcyBwcm9wcyA9IG1fc1Jvb3RPYmplY3QuZ2V0T3V0cHV0Q29tcG9zZWQoKTsKLSAgICAgIAotICAgICAgaWYgKCBmb3JtYXQuZ2V0TWV0aG9kKCkuZXF1YWxzSWdub3JlQ2FzZSggImh0bWwiICkgKQotICAgICAgewotICAgICAgICBGb3JtYXR0ZXJUb0hUTUwgc2VyaWFsaXplciA9IG5ldyBGb3JtYXR0ZXJUb0hUTUwod3JpdGVyKTsKLSAgICAgICAgc2VyaWFsaXplci5nZXRTZXJpYWxpemVyT2JqZWN0KCkuc2V0T3V0cHV0Rm9ybWF0KHByb3BzLmdldFByb3BlcnRpZXMoKSk7Ci0gICAgICAgICgoUGFyc2VyQWRhcHRlciloYW5kbGVyKS5zZXRDb250ZW50SGFuZGxlcihzZXJpYWxpemVyLmdldFNlcmlhbGl6ZXJPYmplY3QoKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICggZm9ybWF0LmdldE1ldGhvZCgpLmVxdWFsc0lnbm9yZUNhc2UoICJ4bWwiICkgKQotICAgICAgewotICAgICAgICBGb3JtYXR0ZXJUb1hNTCBzZXJpYWxpemVyID0gbmV3IEZvcm1hdHRlclRvWE1MKHdyaXRlcik7Ci0gICAgICAgIHNlcmlhbGl6ZXIuZ2V0U2VyaWFsaXplck9iamVjdCgpLnNldE91dHB1dEZvcm1hdChwcm9wcy5nZXRQcm9wZXJ0aWVzKCkpOwotICAgICAgICAoKFBhcnNlckFkYXB0ZXIpaGFuZGxlcikuc2V0Q29udGVudEhhbmRsZXIoc2VyaWFsaXplci5nZXRTZXJpYWxpemVyT2JqZWN0KCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoIGZvcm1hdC5nZXRNZXRob2QoKS5lcXVhbHNJZ25vcmVDYXNlKCAidGV4dCIgKSApCi0gICAgICB7Ci0gICAgICAgIEZvcm1hdHRlclRvVGV4dCBzZXJpYWxpemVyID0gbmV3IEZvcm1hdHRlclRvVGV4dCh3cml0ZXIpOyAKLSAgICAgICAgKChQYXJzZXJBZGFwdGVyKWhhbmRsZXIpLnNldENvbnRlbnRIYW5kbGVyKHNlcmlhbGl6ZXIuZ2V0U2VyaWFsaXplck9iamVjdCgpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaGFuZGxlciA9IG51bGw7Ci0gICAgICB9Ci0gICAgfQotICAgIAotICAgIGlmKG51bGwgPT0gaGFuZGxlcikKLSAgICB7Ci0gICAgICBTdHJpbmcgbWV0aG9kID0gZm9ybWF0LmdldE1ldGhvZCgpOwotICAgICAgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLlNlcmlhbGl6ZXJGYWN0b3J5IGZhY3RvcnkgPSBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuU2VyaWFsaXplckZhY3RvcnkuZ2V0U2VyaWFsaXplckZhY3RvcnkobWV0aG9kKTsKLSAgICAgIG9yZy5hcGFjaGUueG1sLnNlcmlhbGl6ZS5TZXJpYWxpemVyIHNlcmlhbGl6ZXIgPSBmYWN0b3J5Lm1ha2VTZXJpYWxpemVyKHdyaXRlciwgZm9ybWF0KTsKLSAgICAgIGhhbmRsZXIgPSBzZXJpYWxpemVyLmFzRG9jdW1lbnRIYW5kbGVyKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGhhbmRsZXI7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDcmVhdGVzIGEgY29tcGF0aWJsZSBTQVggc2VyaWFsaXplciBmb3IgdGhlIHNwZWNpZmllZCBvdXRwdXQgc3RyZWFtCi0gICAqIGFuZCBvdXRwdXQgZm9ybWF0LiBJZiB0aGUgb3V0cHV0IGZvcm1hdCBpcyBtaXNzaW5nLCB0aGUgZGVmYXVsdAotICAgKiBpcyBhbiBYTUwgZm9ybWF0IHdpdGggVVRGOCBlbmNvZGluZy4KLSAgICoKLSAgICogQHBhcmFtIG9zdHJlYW0gVGhlIG91dHB1dCBzdHJlYW0uCi0gICAqIEBwYXJhbSBmb3JtYXQgVGhlIG91dHB1dCBmb3JtYXQKLSAgICogQHJldHVybiBBIGNvbXBhdGlibGUgU0FYIHNlcmlhbGl6ZXIKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEhhbmRsZXIgbWFrZVNBWFNlcmlhbGl6ZXIoIE91dHB1dFN0cmVhbSBvc3RyZWFtLCBPdXRwdXRGb3JtYXQgZm9ybWF0ICkKLSAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXI7Ci0gICAgT3V0cHV0UHJvcGVydGllcyBwcm9wczsKLSAgICAgICAgCi0gICAgaWYgKCBmb3JtYXQgPT0gbnVsbCApCi0gICAgewotICAgICAgcHJvcHMgPSBuZXcgT3V0cHV0UHJvcGVydGllcygpOwotICAgICAgaGFuZGxlciA9IG51bGw7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7IAotICAgICAgaGFuZGxlciA9IG5ldyBQYXJzZXJBZGFwdGVyKG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcigpKTsKLSAgICAgIHByb3BzID0gbV9zUm9vdE9iamVjdC5nZXRPdXRwdXRDb21wb3NlZCgpOwotICAgICAgaWYgKCBmb3JtYXQuZ2V0TWV0aG9kKCkuZXF1YWxzSWdub3JlQ2FzZSggImh0bWwiICkgKQotICAgICAgewotICAgICAgICBGb3JtYXR0ZXJUb0hUTUwgc2VyaWFsaXplciA9IG5ldyBGb3JtYXR0ZXJUb0hUTUwob3N0cmVhbSk7Ci0gICAgICAgIHNlcmlhbGl6ZXIuZ2V0U2VyaWFsaXplck9iamVjdCgpLnNldE91dHB1dEZvcm1hdChwcm9wcy5nZXRQcm9wZXJ0aWVzKCkpOwotICAgICAgICAoKFBhcnNlckFkYXB0ZXIpaGFuZGxlcikuc2V0Q29udGVudEhhbmRsZXIoc2VyaWFsaXplci5nZXRTZXJpYWxpemVyT2JqZWN0KCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoIGZvcm1hdC5nZXRNZXRob2QoKS5lcXVhbHNJZ25vcmVDYXNlKCAieG1sIiApICkKLSAgICAgIHsKLSAgICAgICAgRm9ybWF0dGVyVG9YTUwgc2VyaWFsaXplciA9IG5ldyBGb3JtYXR0ZXJUb1hNTChvc3RyZWFtKTsKLSAgICAgICAgc2VyaWFsaXplci5nZXRTZXJpYWxpemVyT2JqZWN0KCkuc2V0T3V0cHV0Rm9ybWF0KHByb3BzLmdldFByb3BlcnRpZXMoKSk7Ci0gICAgICAgICgoUGFyc2VyQWRhcHRlciloYW5kbGVyKS5zZXRDb250ZW50SGFuZGxlcihzZXJpYWxpemVyLmdldFNlcmlhbGl6ZXJPYmplY3QoKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICggZm9ybWF0LmdldE1ldGhvZCgpLmVxdWFsc0lnbm9yZUNhc2UoICJ0ZXh0IiApICkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGVuY29kaW5nID0gZm9ybWF0LmdldEVuY29kaW5nKCk7Ci0gICAgICAgIGlmKG51bGwgPT0gZW5jb2RpbmcpCi0gICAgICAgIHsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBlbmNvZGluZyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5lbmNvZGluZyIpOwotICAgICAgICAgICAgZW5jb2RpbmcgPSAobnVsbCAhPSBlbmNvZGluZykgPwotICAgICAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5FbmNvZGluZ3MuY29udmVydEphdmEyTWltZUVuY29kaW5nKCBlbmNvZGluZyApIDogIkFTQ0lJIjsKLSAgICAgICAgICAgIGlmKG51bGwgPT0gZW5jb2RpbmcpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGVuY29kaW5nID0gIkFTQ0lJIjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2goU2VjdXJpdHlFeGNlcHRpb24gc2UpCi0gICAgICAgICAgewotICAgICAgICAgICAgZW5jb2RpbmcgPSAiQVNDSUkiOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vdGhpcy5tX2VuY29kaW5nID0gICBlbmNvZGluZzsKLQotICAgICAgICBTdHJpbmcgamF2YUVuY29kaW5nID0gb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuRW5jb2RpbmdzLmNvbnZlcnRNaW1lMkphdmFFbmNvZGluZyhlbmNvZGluZyk7Ci0KLSAgICAgICAgV3JpdGVyIHcgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKCBvc3RyZWFtLCBqYXZhRW5jb2RpbmcgKTsKLSAgICAgICAgKChQYXJzZXJBZGFwdGVyKWhhbmRsZXIpLnNldENvbnRlbnRIYW5kbGVyKG5ldyBGb3JtYXR0ZXJUb1RleHQodykuZ2V0U2VyaWFsaXplck9iamVjdCgpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCBmb3JtYXQuZ2V0TWV0aG9kKCkuZXF1YWxzSWdub3JlQ2FzZSggInhodG1sIiApICkKLSAgICAgIHsKLSAgICAgICAgaGFuZGxlciA9IG5ldyBYTUxTZXJpYWxpemVyKG9zdHJlYW0sIGZvcm1hdCk7Ci0gICAgICAgIC8vaGFuZGxlciA9IFNlcmlhbGl6ZXIubWFrZVNBWFNlcmlhbGl6ZXIob3N0cmVhbSwgZm9ybWF0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaGFuZGxlciA9IG5ldyBYTUxTZXJpYWxpemVyKG9zdHJlYW0sIGZvcm1hdCk7Ci0gICAgICAgIC8vaGFuZGxlciA9IFNlcmlhbGl6ZXIubWFrZVNBWFNlcmlhbGl6ZXIob3N0cmVhbSwgZm9ybWF0KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgaWYobnVsbCA9PSBoYW5kbGVyKQotICAgIHsKLSAgICAgIFN0cmluZyBtZXRob2QgPSBwcm9wcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLk1FVEhPRCk7Ci0gICAgICBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuU2VyaWFsaXplckZhY3RvcnkgZmFjdG9yeSA9IG9yZy5hcGFjaGUueG1sLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyRmFjdG9yeShtZXRob2QpOwotICAgICAgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLlNlcmlhbGl6ZXIgc2VyaWFsaXplciA9IGZhY3RvcnkubWFrZVNlcmlhbGl6ZXIob3N0cmVhbSwgZm9ybWF0KTsKLSAgICAgIGhhbmRsZXIgPSBzZXJpYWxpemVyLmFzRG9jdW1lbnRIYW5kbGVyKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGhhbmRsZXI7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIGNvbXBhdGlibGUgU0FYIHNlcmlhbGl6ZXIgZm9yIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbQotICAgKiBhbmQgb3V0cHV0IGZvcm1hdC4gSWYgdGhlIG91dHB1dCBmb3JtYXQgaXMgbWlzc2luZywgdGhlIGRlZmF1bHQKLSAgICogaXMgYW4gWE1MIGZvcm1hdCB3aXRoIFVURjggZW5jb2RpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBvc3RyZWFtIFRoZSBvdXRwdXQgc3RyZWFtLgotICAgKiBAcmV0dXJuIEEgY29tcGF0aWJsZSBTQVggc2VyaWFsaXplcgotICAgKi8KLSAgcHVibGljIERvY3VtZW50SGFuZGxlciBnZXRTQVhTZXJpYWxpemVyKCBPdXRwdXRTdHJlYW0gb3N0cmVhbSApCi0gICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KLSAgewotICAgcmV0dXJuIG1ha2VTQVhTZXJpYWxpemVyKG9zdHJlYW0sIGdldE91dHB1dEZvcm1hdCgpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCBhIG5ldyBPdXRwdXRGb3JtYXQgb2JqZWN0IGFjY29yZGluZyB0byB0aGUgeHNsOm91dHB1dCBhdHRyaWJ1dGVzLgotICAgKi8KLSAgcHVibGljIE91dHB1dEZvcm1hdCBnZXRPdXRwdXRGb3JtYXQoKQotICB7Ci0gICAgT3V0cHV0UHJvcGVydGllcyBvdXRwdXRGb3JtYXQgPSBtX3NSb290T2JqZWN0LmdldE91dHB1dENvbXBvc2VkKCk7Ci0gICAgaWYgKG91dHB1dEZvcm1hdCA9PSBudWxsKQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgT3V0cHV0Rm9ybWF0IGZvcm1hdHRlciA9IG5ldyBPdXRwdXRGb3JtYXQob3V0cHV0Rm9ybWF0LmdldFByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9EKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRGb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5FTkNPRElORyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0UHJvcGVydGllcy5nZXRCb29sZWFuUHJvcGVydHkoT3V0cHV0S2V5cy5JTkRFTlQsIG91dHB1dEZvcm1hdC5nZXRQcm9wZXJ0aWVzKCkpKTsKLSAgICBmb3JtYXR0ZXIuc2V0RG9jdHlwZShvdXRwdXRGb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5ET0NUWVBFX1BVQkxJQyksIAotICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dEZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkRPQ1RZUEVfU1lTVEVNKSk7Ci0gICAgZm9ybWF0dGVyLnNldE9taXRYTUxEZWNsYXJhdGlvbihPdXRwdXRQcm9wZXJ0aWVzLmdldEJvb2xlYW5Qcm9wZXJ0eShPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OLCBvdXRwdXRGb3JtYXQuZ2V0UHJvcGVydGllcygpKSk7Ci0gICAgZm9ybWF0dGVyLnNldFN0YW5kYWxvbmUoT3V0cHV0UHJvcGVydGllcy5nZXRCb29sZWFuUHJvcGVydHkoT3V0cHV0S2V5cy5TVEFOREFMT05FLCBvdXRwdXRGb3JtYXQuZ2V0UHJvcGVydGllcygpKSk7Ci0gICAgZm9ybWF0dGVyLnNldE1lZGlhVHlwZShvdXRwdXRGb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRURJQV9UWVBFKSk7Ci0gICAgZm9ybWF0dGVyLnNldFZlcnNpb24ob3V0cHV0Rm9ybWF0LmdldFByb3BlcnR5KE91dHB1dEtleXMuVkVSU0lPTikpOwotICAgIC8vIFRoaXMgaXMgdG8gZ2V0IGFyb3VuZCBkaWZmZXJlbmNlcyBiZXR3ZWVuIFhhbGFuIGFuZCBYZXJjZXMuCi0gICAgLy8gWGFsYW4gdXNlcyAtMSBhcyBkZWZhdWx0IGZvciBubyBpbmRlbnRpbmcsIFhlcmNlcyB1c2VzIDAuCi0gICAgLy8gU28gd2UganVzdCBidW1wIHVwIHRoZSBpbmRlbnQgdmFsdWUgaGVyZSBiZWNhdXNlIHdlIHdpbGwKLSAgICAvLyBzdWJ0cmFjdCBmcm9tIGl0IGF0IG91dHB1dCB0aW1lIChGb3JtYXR0ZXJUb1hNTC5pbml0KCkpOwotICAgLy8gaWYgKGdldE91dHB1dEluZGVudCgpKQotICAgLy8gICBmb3JtYXR0ZXIuc2V0SW5kZW50KGZvcm1hdHRlci5nZXRJbmRlbnQoKSsxKTsKLQotICAgIAotICAgIHJldHVybiBmb3JtYXR0ZXI7Ci0gIH0KLSAgCi0gIC8qKiAKLSAgICogR2V0IHRoZSBlbmNvZGluZyBzdHJpbmcgdGhhdCB3YXMgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LiAKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0T3V0cHV0RW5jb2RpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fc1Jvb3RPYmplY3QuZ2V0T3V0cHV0Q29tcG9zZWQoKS5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HKTsKLSAgfQotCi0gIC8qKiAKLSAgICogR2V0IHRoZSBtZWRpYS10eXBlIHN0cmluZyB0aGF0IHdhcyBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuIAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRPdXRwdXRNZWRpYVR5cGUoKSAKLSAgeyAKLSAgICByZXR1cm4gbV9zUm9vdE9iamVjdC5nZXRPdXRwdXRDb21wb3NlZCgpLmdldFByb3BlcnR5KE91dHB1dEtleXMuTUVESUFfVFlQRSk7IAotICB9Ci0gIAotICAvKiogCi0gICAqIEdldCB0aGUgb3V0cHV0IG1ldGhvZCB0aGF0IHdhcyBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuIAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRPdXRwdXRNZXRob2QoKSAKLSAgeyAKLSAgICByZXR1cm4gbV9zUm9vdE9iamVjdC5nZXRPdXRwdXRDb21wb3NlZCgpLmdldFByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9EKTsgCi0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIGJhc2UgaWRlbnRpZmllciB3aXRoIHdoaWNoIHRoaXMgc3R5bGVzaGVldCBpcyBhc3NvY2lhdGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRCYXNlSWRlbnRpZmllcigpCi0gIHsKLSAgICByZXR1cm4gbV9zUm9vdE9iamVjdC5nZXRCYXNlSWRlbnRpZmllcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYmFzZSBpZGVudGlmaWVyIHdpdGggd2hpY2ggdGhpcyBzdHlsZXNoZWV0IGlzIGFzc29jaWF0ZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRCYXNlSWRlbnRpZmllcihTdHJpbmcgYmFzZUlkZW50KQotICB7Ci0gICAgbV9zUm9vdE9iamVjdC5zZXRIcmVmKGJhc2VJZGVudCk7Ci0gIH0KLSAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0U3BlYy5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvU3R5bGVzaGVldFNwZWMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGFkMTUyNy4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9TdHlsZXNoZWV0U3BlYy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgcmVwcmVzZW50YXRpb24gb2YgYSBzdHlsZXNoZWV0IAotICogc3BlY2lmaWNhdGlvbiB2aWEgeG1sLXN0eWxlc2hlZXQgaW4gYW4gWE1MIGRvY3VtZW50LgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBTdHlsZXNoZWV0U3BlYyBleHRlbmRzIFN0cmVhbVNvdXJjZQotewotICBTdHJpbmcgdHlwZTsgLy8gQ0RBVEEgI1JFUVVJUkVECi0gIFN0cmluZyB0aXRsZTsgLy8gQ0RBVEEgI0lNUExJRUQKLSAgU3RyaW5nIG1lZGlhOyAvLyBDREFUQSAjSU1QTElFRAotICBTdHJpbmcgZW5jb2Rpbmc7IC8vIENEQVRBICNJTVBMSUVECi0gIGJvb2xlYW4gYWx0ZXJuYXRlOyAvLyAoeWVzfG5vKSAibm8iCi0gIAotICAvKioKLSAgICogQ3JlYXRlIGEgU3R5bGVzaGVldFNwZWMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRTcGVjKFN0cmluZyBocmVmLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHRpdGxlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtZWRpYSwgYm9vbGVhbiBhbHRlcm5hdGUsCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZW5jb2RpbmcpCi0gIHsKLSAgICB0aGlzLnNldFN5c3RlbUlkKGhyZWYpOwotICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKLSAgICB0aGlzLnR5cGUgPSB0eXBlOwotICAgIHRoaXMudGl0bGUgPSB0aXRsZTsKLSAgICB0aGlzLm1lZGlhID0gbWVkaWE7Ci0gICAgdGhpcy5hbHRlcm5hdGUgPSBhbHRlcm5hdGU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIGVuY29kaW5nIG9mIHRoZSBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyAgICAgICBnZXRFbmNvZGluZygpCi0gIHsKLSAgICByZXR1cm4gZW5jb2Rpbmc7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBzdHlsZXNoZWV0LCBpLmUuICJ0ZXh0L3hzbCIuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nICAgICAgIGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIHR5cGU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIHRpdGxlIG9mIHRoZSBlbGVtZW50IChpbiBvdGhlciB3b3JkcywgdGhlIAotICAgKiBpdGVtIHRvIGJlIHByZXNlbnRlZCB0byB0aGUgdXNlciBhZ2VudCkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nICAgICAgIGdldFRpdGxlKCkKLSAgewotICAgIHJldHVybiB0aXRsZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgbWVkaWEgYXR0cmlidXRlIG9mIHRoZSBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyAgICAgICBnZXRNZWRpYSgpCi0gIHsKLSAgICByZXR1cm4gbWVkaWE7Ci0gIH0KLSAgLyoqCi0gICAqIEdldCB3aGV0aGVyIG9yIG5vdCB0aGUgc3R5bGVzaGVldCBpcyBzcGVjaWZpZWQgYXMgCi0gICAqIGFuIGFsdGVybmF0ZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuICAgIGdldElzQWx0ZXJuYXRlKCkKLSAgewotICAgIHJldHVybiBhbHRlcm5hdGU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFByb2Nlc3NvckNvbnRleHQuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFByb2Nlc3NvckNvbnRleHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmZlN2Q5Mi4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9YU0xQcm9jZXNzb3JDb250ZXh0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8vIGltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuKjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogQ2FwdHVyZXMgcHJvY2Vzc29yIGNvbnRleHQgdG8gYmUKLSAqIHBhc3NlZCB0byBhbiBleHRlbnNpb24gZWxlbWVudC4KLSAqCi0gKiBAYXV0aG9yIFNhbmppdmEgV2VlcmF3YXJhbmEgKHNhbmppdmFAd2F0c29uLmlibS5jb20pCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhTTFByb2Nlc3NvckNvbnRleHQgZXh0ZW5kcyBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuWFNMUHJvY2Vzc29yQ29udGV4dAoteyAKLSAgcHVibGljIFhTTFByb2Nlc3NvckNvbnRleHQgKFhTTFRFbmdpbmVJbXBsIHByb2Nlc3NvciwKLQkJCSAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldFRyZWUsCi0JCQkgICAgICBOb2RlIHNvdXJjZVRyZWUsIE5vZGUgc291cmNlTm9kZSwgUU5hbWUgbW9kZSkgCi0gICAgCi0gIHsKLSAgICBzdXBlcigoVHJhbnNmb3JtZXJJbXBsKShwcm9jZXNzb3IuZ2V0VHJhbnNmb3JtZXIoKSksCi0gICAgICAgICAgc3R5bGVzaGVldFRyZWUpOwotICB9Ci0KLSAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9YU0xQcm9jZXNzb3JFeGNlcHRpb24uamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFByb2Nlc3NvckV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYWFiNWEwLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFByb2Nlc3NvckV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhlIGV4Y2VwdGlvbiB1c2VkIGZvciBtb3N0IFhTTFQgZXJyb3JzLgotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gZXh0ZW5kcyBTQVhFeGNlcHRpb24KLXsKLSAgcHJpdmF0ZSBFeGNlcHRpb24gbV9leGNlcHRpb247Ci0gIAotICAvKioKLSAgICogQ3JlYXRlIGFuIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcyAKLSAgICogYW4gZXJyb3IgbWVzc2FnZS4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuCi0gICAqLwotICBwdWJsaWMgWFNMUHJvY2Vzc29yRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSAKLSAgewotICAgICBzdXBlcigobnVsbCA9PSBtZXNzYWdlKSA/IFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1hTTFRfRVJST1IsIG51bGwpIDogbWVzc2FnZSk7Ci0gICAgIG1fZXhjZXB0aW9uID0gbnVsbDsKLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gb2JqZWN0IHRoYXQgaG9sZHMgCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UsIGFuZCBhbm90aGVyIGV4Y2VwdGlvbiAKLSAgICogdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRoYXQgY2F1c2VkIHRoaXMgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiAoU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKQotICB7Ci0gICAgc3VwZXIoKG51bGwgPT0gbWVzc2FnZSkgPyBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9YU0xUX0VSUk9SLCBudWxsKSA6IG1lc3NhZ2UpOwotICAgIHRoaXMubV9leGNlcHRpb24gPSBlOwotICB9Ci0gIAotICAvKioKLSAgICogQ3JlYXRlIGFuIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcyAKLSAgICogYW5vdGhlciBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIChFeGNlcHRpb24gZSkKLSAgewotICAgIHN1cGVyKChudWxsID09IGUuZ2V0TWVzc2FnZSgpKSA/IFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1hTTFRfRVJST1IsIG51bGwpIDogZS5nZXRNZXNzYWdlKCkpOwotICAgIHRoaXMubV9leGNlcHRpb24gPSBlOwotICB9Ci0gICAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9YU0xURW5naW5lSW1wbC5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVEVuZ2luZUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDZmYmMyYy4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9YU0xURW5naW5lSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQyNiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5YUGF0aFBhcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGguWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLlhCb29sZWFuOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGguWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLlhOdWxsOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy4qOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC4qOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuWE1MU2VyaWFsaXplcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IGphdmEubmV0Lio7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotLy9pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuWE1MUGFyc2VyTGlhaXNvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5Qcm9ibGVtTGlzdGVuZXJEZWZhdWx0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLlByb2JsZW1MaXN0ZW5lcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Q29tcG9zZWQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuU3R5bGVzaGVldEhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbDsKLS8vaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlByb2Nlc3NvclN0eWxlc2hlZXQ7Ci0vL2ltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuU3R5bGVzaGVldFNwZWM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlckRlZmF1bHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuVHJlZVdhbGtlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJIYW5kbGVySW1wbDsKLQotLy8gSW1wb3J0ZWQgSkFWQSBBUEkgZm9yIFhNTCBQYXJzaW5nIDEuMCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhlIFhhbGFuIHdvcmtob3JzZSAtLSBDb2xsYWJvcmF0ZXMgd2l0aCB0aGUgWE1MIHBhcnNlciBsaWFpc29uLCB0aGUgRE9NLAotICogYW5kIHRoZSBYUGF0aCBlbmdpbmUsIHRvIHRyYW5zZm9ybSBhIHNvdXJjZSB0cmVlIG9mIG5vZGVzIGludG8gYSByZXN1bHQgdHJlZQotICogYWNjb3JkaW5nIHRvIGluc3RydWN0aW9ucyBhbmQgdGVtcGxhdGVzIHNwZWNpZmllZCBieSBhIHN0eWxlc2hlZXQgdHJlZS4KLSAqIFdlIHN1Z2dlc3QgeW91IHVzZSBvbmUgb2YgdGhlCi0gKiBzdGF0aWMgWFNMVFByb2Nlc3NvckZhY3RvcnkgZ2V0UHJvY2Vzc29yKCkgbWV0aG9kcyB0byBpbnN0YW50aWF0ZSB0aGUgcHJvY2Vzc29yCi0gKiBhbmQgcmV0dXJuIGFuIGludGVyZmFjZSB0aGF0IGdyZWF0bHkgc2ltcGxpZmllcyB0aGUgcHJvY2VzcyBvZiBtYW5pcHVsYXRpbmcKLSAqIFhTTFRFbmdpbmVJbXBsLgotICoKLSAqIDxwPlRoZSBtZXRob2RzIDxjb2RlPnByb2Nlc3MoLi4uKTwvY29kZT4gYXJlIHRoZSBwcmltYXJ5IHB1YmxpYyBlbnRyeSBwb2ludHMuCi0gKiBUaGUgYmVzdCB3YXkgdG8gcGVyZm9ybSB0cmFuc2Zvcm1hdGlvbnMgaXMgdG8gdXNlIHRoZQotICoge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUHJvY2Vzc29yI3Byb2Nlc3Mob3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRJbnB1dFNvdXJjZSwgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRJbnB1dFNvdXJjZSwgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRSZXN1bHRUYXJnZXQpfSBtZXRob2QsCi0gKiBidXQgeW91IG1heSB1c2UgYW55IG9mIHByb2Nlc3MgbWV0aG9kcyBkZWZpbmVkIGluIFhTTFRFbmdpbmVJbXBsLjwvcD4KLSAqIAotICogPHA+UGxlYXNlIG5vdGUgdGhhdCB0aGlzIGNsYXNzIGlzIG5vdCBzYWZlIHBlciBpbnN0YW5jZSBvdmVyIG11bHRpcGxlIAotICogdGhyZWFkcy4gIElmIHlvdSBhcmUgaW4gYSBtdWx0aXRocmVhZGVkIGVudmlyb25tZW50LCB5b3Ugc2hvdWxkIAotICoga2VlcCBhIHBvb2wgb2YgdGhlc2Ugb2JqZWN0cywgb3IgY3JlYXRlIGEgbmV3IG9uZSBlYWNoIHRpbWUuICBJbiBhIAotICogbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudCwgdGhlIHJpZ2h0IHdheSB0byBkbyB0aGluZ3MgaXMgdG8gY3JlYXRlIGEgCi0gKiBTdHlsZXNoZWV0Um9vdCB2aWEgcHJvY2Vzc1N0eWxlc2hlZXQsIGFuZCB0aGVuIHJldXNlIHRoaXMgb2JqZWN0IAotICogb3ZlciBtdWx0aXBsZSB0aHJlYWRzLjwvcD4KLSAqCi0gKiA8cD5JZiB5b3UgcmV1c2UgdGhlIHByb2Nlc3NvciBpbnN0YW5jZSwgeW91IHNob3VsZCBjYWxsIHJlc2V0KCkgYmV0d2VlbiB0cmFuc2Zvcm1hdGlvbnMuPC9wPgotICogQHNlZSBYU0xUUHJvY2Vzc29yRmFjdG9yeQotICogQHNlZSBYU0xUUHJvY2Vzc29yCi0gKiBAZGVwcmVjYXRlZCBUaGlzIGNvbXBhdGliaWxpdHkgbGF5ZXIgd2lsbCBiZSByZW1vdmVkIGluIGxhdGVyIHJlbGVhc2VzLiAKLSAqLwotcHVibGljIGNsYXNzIFhTTFRFbmdpbmVJbXBsIGltcGxlbWVudHMgIFhTTFRQcm9jZXNzb3IKLXsKLSAgLy9wcml2YXRlIFByb2Nlc3NvciBtX3Byb2Nlc3NvcjsKLSAgcHJpdmF0ZSBUcmFuc2Zvcm1lckZhY3RvcnkgbV90ZmFjdG9yeTsKLSAgcHJpdmF0ZSBUcmFuc2Zvcm1lckltcGwgbV90cmFuc2Zvcm1lckltcGw7Ci0gIHByaXZhdGUgRE9NMkhlbHBlciBtX2xpYWlzb247Ci0gIHByaXZhdGUgU3RyaW5nIG1fb3V0cHV0RmlsZU5hbWU7Ci0gIHByaXZhdGUgRG9jdW1lbnRIYW5kbGVyIG1fZG9jdW1lbnRIYW5kbGVyID0gbnVsbDsKLSAgcHJpdmF0ZSBQcm9ibGVtTGlzdGVuZXJEZWZhdWx0IG1fcHJvYmxlbUxpc3RlbmVyOwotICBwcml2YXRlIEhhc2h0YWJsZSBtX3N0eWxlc2hlZXRQYXJhbXM7Ci0gIFN0eWxlc2hlZXRSb290IG1fc3R5bGVzaGVldFJvb3QgPSBudWxsOwotICAKLSAgVmVjdG9yIG1fZXZhbExpc3QgPSBudWxsOwotICBib29sZWFuIG1fbmVlZFRvRXZhbCA9IGZhbHNlOwotICAKLSAgLyoKLSAgKiBJZiB0aGlzIGlzIHRydWUsIHRoZW4gdGhlIGRpYWcgZnVuY3Rpb24gd2lsbAotICAqIGJlIGNhbGxlZC4KLSAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fdHJhY2VUZW1wbGF0ZUNoaWxkcmVuID0gZmFsc2U7Ci0KLSAgLyoKLSAgKiBJZiB0aGlzIGlzIHRydWUsIHRoZW4gdGhlIHNpbXBsZSB0cmFjaW5nIG9mIHRlbXBsYXRlcwotICAqIHdpbGwgYmUgcGVyZm9ybWVkLgotICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV90cmFjZVRlbXBsYXRlcyA9IGZhbHNlOwotICAKLSAgLyoKLSAgKiBJZiB0aGlzIGlzIHRydWUsIHRoZW4gZGlhZ25vc3RpY3Mgb2YgZWFjaCBzZWxlY3QKLSAgKiB3aWxsIGJlIHBlcmZvcm1lZC4KLSAgKi8KLSAgYm9vbGVhbiBtX3RyYWNlU2VsZWN0cyA9IGZhbHNlOwotCi0gIC8qCi0gICogQSBzdHJlYW0gdG8gcHJpbnQgZGlhZ25vc3RpY3MgdG8uCi0gICovCi0gIGphdmEuaW8uUHJpbnRXcml0ZXIgbV9kaWFnbm9zdGljc1ByaW50V3JpdGVyID0gbnVsbDsKLQotICAvKiBGb3IgZGlhZ25vc3RpY3MgKi8KLSAgSGFzaHRhYmxlIG1fZHVyYXRpb25zVGFibGUgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gIAotICAvKioKLSAgICogQSBYU0xNZXNzYWdlcyBpbnN0YW5jZSBjYXBhYmxlIG9mIHByb2R1Y2luZyB1c2VyIG1lc3NhZ2VzLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgWFNMTWVzc2FnZXMgbV9YU0xNZXNzYWdlcyA9IG5ldyBYU0xNZXNzYWdlcygpOwotICAKLSAgICAKLSAvKioKLSAgICogQ29uc3RydWN0IGFuIFhTTFQgcHJvY2Vzc29yIHRoYXQgdXNlcyB0aGUgZGVmYXVsdCBEVE0gKERvY3VtZW50IFRhYmxlIE1vZGVsKSBsaWFpc29uCi0gICAqIGFuZCBYTUwgcGFyc2VyLiBBcyBhIGdlbmVyYWwgcnVsZSwgeW91IHNob3VsZCB1c2UgWFNMVFByb2Nlc3NvckZhY3RvcnkgdG8gY3JlYXRlIGFuCi0gICAqIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYW5kIHByb3ZpZGUgYWNjZXNzIHRvIHRoZSBpbnN0YW5jZSB2aWEgdGhlIFhTTFRQcm9jZXNzb3IgaW50ZXJmYWNlLgotICAgKgotICAgKiBAc2VlIFhTTFRQcm9jZXNzb3JGYWN0b3J5Ci0gICAqIEBzZWUgWFNMVFByb2Nlc3NvcgotICAgKi8KLSAgcHJvdGVjdGVkIFhTTFRFbmdpbmVJbXBsKCkKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsgICAgCi0gICAgbV90ZmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIG1fcHJvYmxlbUxpc3RlbmVyID0gbmV3IFByb2JsZW1MaXN0ZW5lckRlZmF1bHQoKTsKLSAgICAvL21fbGlhaXNvbiA9ICAoRE9NMkhlbHBlciljcmVhdGVMaWFpc29uKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIFhTTFQgcHJvY2Vzc29yIHRoYXQgdXNlcyB0aGUgdGhlIGdpdmVuIHBhcnNlciBsaWFpc29uLgotICAgKiBBcyBhIGdlbmVyYWwgcnVsZSwgeW91IHNob3VsZCB1c2UgWFNMVFByb2Nlc3NvckZhY3RvcnkgdG8gY3JlYXRlIGFuCi0gICAqIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYW5kIHByb3ZpZGUgYWNjZXNzIHRvIHRoZSBpbnN0YW5jZSB2aWEgdGhlIFhTTFRQcm9jZXNzb3IgaW50ZXJmYWNlLgotICAgKgotICAgKiBAc2VlIFhTTFRQcm9jZXNzb3JGYWN0b3J5Ci0gICAqIEBzZWUgWFNMVFByb2Nlc3NvcgotICAgKi8KLSAgcHVibGljIFhTTFRFbmdpbmVJbXBsKFN0cmluZyBsaWFpc29uQ2xhc3NOYW1lKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24gCi0gIHsgICAKLSAgICBtX3RmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgbV9wcm9ibGVtTGlzdGVuZXIgPSBuZXcgUHJvYmxlbUxpc3RlbmVyRGVmYXVsdCgpOwotICAgIAotICAgIHRyeSAKLSAgICAgIHsKLSAgICAgICAgbV9saWFpc29uID0gIChET00ySGVscGVyKShDbGFzcy5mb3JOYW1lKGxpYWlzb25DbGFzc05hbWUpLm5ld0luc3RhbmNlKCkpOwotICAgICAgICAvL29yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0IHhjdHh0ID0gdGhpcy5nZXRUcmFuc2Zvcm1lcigpLmdldFhQYXRoQ29udGV4dCgpOwotCi0gICAgICAgIC8veGN0eHQuc2V0RE9NSGVscGVyKG1fbGlhaXNvbik7ICAgICAgICAKLSAgICAgIH0gCi0gICAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlMSkgCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIlhNTCBMaWFpc29uIGNsYXNzICIgKyBsaWFpc29uQ2xhc3NOYW1lICsKLSAgICAgICAgICAiIHNwZWNpZmllZCBidXQgbm90IGZvdW5kIiwgZTEpOwotICAgICAgfSAKLSAgICAgIGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUyKSAKLSAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJYTUwgTGlhaXNvbiBjbGFzcyAiICsgbGlhaXNvbkNsYXNzTmFtZSArCi0gICAgICAgICAgICAiIGZvdW5kIGJ1dCBjYW5ub3QgYmUgbG9hZGVkIiwgZTIpOwotICAgICAgfSAKLSAgICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUzKSAKLSAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJYTUwgTGlhaXNvbiBjbGFzcyAiICsgbGlhaXNvbkNsYXNzTmFtZSArCi0gICAgICAgICAgICAiIGxvYWRlZCBidXQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCAobm8gZW1wdHkgcHVibGljIGNvbnN0cnVjdG9yPykiLAotICAgICAgICAgICAgZTMpOwotICAgICAgfSAKLSAgICAgIGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZTQpIAotICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oIlhNTCBMaWFpc29uIGNsYXNzICIgKyBsaWFpc29uQ2xhc3NOYW1lICsKLSAgICAgICAgICAgICIgZG9lcyBub3QgaW1wbGVtZW50IERPTTJIZWxwZXIiLCBlNCk7Ci0gICAgICB9Ci0gICAKLSAgfQotICAgIAotICAgIAotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gWFNMIHByb2Nlc3NvciB0aGF0IHVzZXMgdGhlIHRoZSBnaXZlbiBwYXJzZXIgbGlhaXNvbi4KLSAgICogQXMgYSBnZW5lcmFsIHJ1bGUsIHlvdSBzaG91bGQgdXNlIFhTTFRQcm9jZXNzb3JGYWN0b3J5IHRvIGNyZWF0ZSBhbgotICAgKiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFuZCBwcm92aWRlIGFjY2VzcyB0byB0aGUgaW5zdGFuY2UgdmlhIHRoZSBYU0xUUHJvY2Vzc29yIGludGVyZmFjZS4KLSAgICoKLSAgICogQHBhcmFtIFhNTFBhcnNlckxpYWlzb24gQSBsaWFpc29uIHRvIGFuIFhNTCBwYXJzZXIuCi0gICAqCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuWE1MUGFyc2VyTGlhaXNvbgotICAgKiBAc2VlIFhTTFRQcm9jZXNzb3JGYWN0b3J5Ci0gICAqIEBzZWUgWFNMVFByb2Nlc3NvcgotICAgKi8KLSAgcHVibGljIFhTTFRFbmdpbmVJbXBsKFhNTFBhcnNlckxpYWlzb24gcGFyc2VyTGlhaXNvbikKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX3RmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgbV9wcm9ibGVtTGlzdGVuZXIgPSBuZXcgUHJvYmxlbUxpc3RlbmVyRGVmYXVsdCgpOwotICAgIAotICAgIG1fbGlhaXNvbiA9ICAoRE9NMkhlbHBlcilwYXJzZXJMaWFpc29uOwotICAgLy8gb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQgeGN0eHQgPSB0aGlzLmdldFRyYW5zZm9ybWVyKCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0KLSAgICAvL3hjdHh0LnNldERPTUhlbHBlcihtX2xpYWlzb24pOyAgICAKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gWFNMVCBwcm9jZXNzb3IgdGhhdCBjYW4gY2FsbCBiYWNrIHRvIHRoZSBYTUwgcGFyc2VyLCBpbiBvcmRlciB0byBoYW5kbGUKLSAgICogaW5jbHVkZWQgZmlsZXMgYW5kIHRoZSBsaWtlLgotICAgKgotICAgKiBAcGFyYW0gWE1MUGFyc2VyTGlhaXNvbiBBIGxpYWlzb24gdG8gYW4gWE1MIHBhcnNlci4KLSAgICoKLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5YTUxQYXJzZXJMaWFpc29uCi0gICAqIEBzZWUgWFNMVFByb2Nlc3NvckZhY3RvcnkKLSAgICogQHNlZSBYU0xUUHJvY2Vzc29yCi0gICAqLwotICBYU0xURW5naW5lSW1wbChYTUxQYXJzZXJMaWFpc29uIHBhcnNlckxpYWlzb24sIFhQYXRoRmFjdG9yeSB4cGF0aEZhY3RvcnkpICAgIAotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgeyAgIAotICAgIG1fdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBtX3Byb2JsZW1MaXN0ZW5lciA9IG5ldyBQcm9ibGVtTGlzdGVuZXJEZWZhdWx0KCk7Ci0gICAgCi0gICAgbV9saWFpc29uID0gIChET00ySGVscGVyKXBhcnNlckxpYWlzb247Ci0gICAvLyBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dCB4Y3R4dCA9IHRoaXMuZ2V0VHJhbnNmb3JtZXIoKS5nZXRYUGF0aENvbnRleHQoKTsKLQotICAgIC8veGN0eHQuc2V0RE9NSGVscGVyKG1fbGlhaXNvbik7ICAgIAotICB9Ci0gIAotICAvKiogCi0gICAqIEdldCBhIExpYWlzb24gY2xhc3MKLSAgICovCi0gIHB1YmxpYyBYTUxQYXJzZXJMaWFpc29uIGNyZWF0ZUxpYWlzb24oKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuWE1MUGFyc2VyTGlhaXNvbkRlZmF1bHQoKTsgICAgCi0gIH0KLSAKLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBzdGF0ZS4gIFRoaXMgbmVlZHMgdG8gYmUgY2FsbGVkIGFmdGVyIGEgcHJvY2VzcygpIGNhbGwKLSAgICogaXMgaW52b2tlZCwgaWYgdGhlIHByb2Nlc3NvciBpcyB0byBiZSB1c2VkIGFnYWluLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICBtX3RyYW5zZm9ybWVySW1wbC5yZXNldCgpOyAKLSAgICBtX3N0eWxlc2hlZXRQYXJhbXMgPSBudWxsOwotICB9Ci0gIAotIAotCi0gIC8qKgotICAgKiBUcmFuc2Zvcm0gdGhlIHNvdXJjZSB0cmVlIHRvIHRoZSBvdXRwdXQgaW4gdGhlIGdpdmVuCi0gICAqIHJlc3VsdCB0cmVlIHRhcmdldC4gQXMgYSBnZW5lcmFsIHJ1bGUsIHdlIHJlY29tbWVuZCB5b3UgdXNlIHRoZQotICAgKiB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRQcm9jZXNzb3IjcHJvY2VzcyhvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVElucHV0U291cmNlLCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVElucHV0U291cmNlLCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFJlc3VsdFRhcmdldCl9IG1ldGhvZC4KLSAgICogQHBhcmFtIGlucHV0U291cmNlICBUaGUgaW5wdXQgc291cmNlLgotICAgKiBAcGFyYW0gc3R5bGVzaGVldFNvdXJjZSAgVGhlIHN0eWxlc2hlZXQgc291cmNlLiAgTWF5IGJlIG51bGwgaWYgc291cmNlIGhhcyBhIHhtbC1zdHlsZXNoZWV0IFBJLgotICAgKiBAcGFyYW0gb3V0cHV0VGFyZ2V0IFRoZSBvdXRwdXQgc291cmNlIHRyZWUuCi0gICAqIEBleGNlcHRpb24gWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWE1MUGFyc2VyTGlhaXNvbiBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3MoIFhTTFRJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgWFNMVElucHV0U291cmNlIHN0eWxlc2hlZXRTb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgIFhTTFRSZXN1bHRUYXJnZXQgb3V0cHV0VGFyZ2V0KQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIEJvb2xlYW4gdG90YWxUaW1lSUQgPSBuZXcgQm9vbGVhbih0cnVlKTsKLSAgICAgIHB1c2hUaW1lKHRvdGFsVGltZUlEKTsKLSAgICAgIE5vZGUgc291cmNlVHJlZSA9IG51bGw7Ci0gICAgICAKLSAgICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBudWxsOwotICAgICAgaWYgKG1fbmVlZFRvRXZhbCkKLSAgICAgIHsKLSAgICAgICAgTm9kZSBub2RlID0gbnVsbDsKLSAgICAgICAgaWYgKG51bGwgIT0gc3R5bGVzaGVldFNvdXJjZSkKLSAgICAgICAgewotICAgICAgICAgIFNvdXJjZSBzc1NvdXJjZSA9IHN0eWxlc2hlZXRTb3VyY2UuZ2V0U291cmNlT2JqZWN0KCk7Ci0gICAgICAgICAgaWYoc3NTb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpCi0gICAgICAgICAgewotICAgICAgICAgICAgbm9kZSA9ICgoRE9NU291cmNlKXNzU291cmNlKS5nZXROb2RlKCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGlmIChudWxsID09IG5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBub2RlID0gbmV3IERPTTJIZWxwZXIoKS5jcmVhdGVEb2N1bWVudCgpIDsgCi0gICAgICAgIH0KLSAgICAgICAgZm9yIChpbnQgaT0wOyBpPCBtX2V2YWxMaXN0LnNpemUoKTsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW1fZXZhbExpc3QuZWxlbWVudEF0KGkpOwotICAgICAgICAgIFN0cmluZyBleHByZXNzaW9uID0gKFN0cmluZyltX3N0eWxlc2hlZXRQYXJhbXMuZ2V0KG5hbWUpOwotICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0IHZhbCA9IG9yZy5hcGFjaGUueHBhdGguWFBhdGhBUEkuZXZhbChub2RlLCBleHByZXNzaW9uKTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgbV9zdHlsZXNoZWV0UGFyYW1zLnB1dChuYW1lLCB2YWwpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKHRlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgbV9uZWVkVG9FdmFsID0gZmFsc2U7Ci0gICAgICAgIG1fZXZhbExpc3QgPSBudWxsOwotICAgICAgfQotICAgICAgCi0gICAgICBzb3VyY2VUcmVlID0gZ2V0U291cmNlVHJlZUZyb21JbnB1dChpbnB1dFNvdXJjZSk7Ci0gICAgICAKLSAgICAgIGlmKG51bGwgIT0gc3R5bGVzaGVldFNvdXJjZSkKLSAgICAgIHsKLSAgICAgICAgdHJ5ewotICAgICAgICB0ZW1wbGF0ZXMgPSBtX3RmYWN0b3J5Lm5ld1RlbXBsYXRlcyhzdHlsZXNoZWV0U291cmNlLmdldFNvdXJjZU9iamVjdCgpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGNlKTsKLSAgICAgICAgfSAgCi0gICAgICAgIAotICAgICAgfSAgICAgIAotICAgICAgZWxzZSBpZiggbnVsbCAhPSBpbnB1dFNvdXJjZSkKLSAgICAgIHsgCi0gICAgICAgIGlmKG51bGwgIT0gc291cmNlVHJlZSkKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBzdHlsZXNoZWV0VVJJID0gbnVsbDsKLSAgICAgICAgICBTdGFjayBocmVmcyA9IG5ldyBTdGFjaygpOwotICAgICAgICAgIGZvcihOb2RlIGNoaWxkPXNvdXJjZVRyZWUuZ2V0Rmlyc3RDaGlsZCgpOyBudWxsICE9IGNoaWxkOyBjaGlsZD1jaGlsZC5nZXROZXh0U2libGluZygpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmKE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFID09IGNoaWxkLmdldE5vZGVUeXBlKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pY2hpbGQ7Ci0gICAgICAgICAgICAgIGlmKHBpLmdldE5vZGVOYW1lKCkuZXF1YWxzKCJ4bWwtc3R5bGVzaGVldCIpCi0gICAgICAgICAgICAgICAgIHx8IHBpLmdldE5vZGVOYW1lKCkuZXF1YWxzKCJ4bWw6c3R5bGVzaGVldCIpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYm9vbGVhbiBpc09LID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihwaS5nZXROb2RlVmFsdWUoKSwgIiBcdD0iKTsKLSAgICAgICAgICAgICAgICB3aGlsZSh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIGlmKHRva2VuaXplci5uZXh0VG9rZW4oKS5lcXVhbHMoInR5cGUiKSkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGVWYWwgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgICAgIHR5cGVWYWwgPSB0eXBlVmFsLnN1YnN0cmluZygxLCB0eXBlVmFsLmxlbmd0aCgpLTEpOwotICAgICAgICAgICAgICAgICAgICBpZighdHlwZVZhbC5lcXVhbHMoInRleHQveHNsIikgJiYgIXR5cGVWYWwuZXF1YWxzKCJ0ZXh0L3htbCIpICYmICF0eXBlVmFsLmVxdWFscygiYXBwbGljYXRpb24veG1sK3hzbHQiKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgIGlzT0sgPSBmYWxzZTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGlmKGlzT0spCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihwaS5nZXROb2RlVmFsdWUoKSwgIiBcdD0iKTsKLSAgICAgICAgICAgICAgICAgIHdoaWxlKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmKHRva2VuaXplci5uZXh0VG9rZW4oKS5lcXVhbHMoImhyZWYiKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgIHN0eWxlc2hlZXRVUkkgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldFVSSSA9IHN0eWxlc2hlZXRVUkkuc3Vic3RyaW5nKDEsIHN0eWxlc2hlZXRVUkkubGVuZ3RoKCktMSk7Ci0gICAgICAgICAgICAgICAgICAgICAgaHJlZnMucHVzaChzdHlsZXNoZWV0VVJJKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9IC8vIGVuZCBmb3IoaW50IGkgPSAwOyBpIDwgbk5vZGVzOyBpKyspCi0gICAgICAgICAgYm9vbGVhbiBpc1Jvb3QgPSB0cnVlOwotICAgICAgICAgIFN0eWxlc2hlZXQgcHJldlN0eWxlc2hlZXQgPSBudWxsOwotICAgICAgICAgIHdoaWxlKCFocmVmcy5pc0VtcHR5KCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gZ2V0U3R5bGVzaGVldEZyb21QSVVSTCgoU3RyaW5nKWhyZWZzLnBvcCgpLCBzb3VyY2VUcmVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnVsbCAhPSBpbnB1dFNvdXJjZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBpbnB1dFNvdXJjZS5nZXRTeXN0ZW1JZCgpIDogbnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSb290KTsKLSAgICAgICAgICAgIGlmKGZhbHNlID09IGlzUm9vdCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcHJldlN0eWxlc2hlZXQuc2V0SW1wb3J0KChTdHlsZXNoZWV0Q29tcG9zZWQpc3R5bGVzaGVldCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBwcmV2U3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0gICAgICAgICAgICBpc1Jvb3QgPSBmYWxzZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0gICAgICAgIAotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fSU5QVVRfU1RZTEVTSEVFVCk7IC8vIlN0eWxlc2hlZXQgaW5wdXQgd2FzIG5vdCBzcGVjaWZpZWQhIik7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgCi0gICAgICBpZihudWxsID09IHRlbXBsYXRlcykKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fc3R5bGVzaGVldFJvb3QgIT0gbnVsbCkKLSAgICAgICAgICB0ZW1wbGF0ZXMgPSBtX3N0eWxlc2hlZXRSb290LmdldE9iamVjdCgpOwotICAgICAgICBlbHNlCi0gICAgICAgIHsgIAotICAgICAgICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUKTsgLy8iRmFpbGVkIHRvIHByb2Nlc3Mgc3R5bGVzaGVldCEiKTsKLSAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0gIAotICAgICAgfQotCi0gICAgICBpZihudWxsICE9IHRlbXBsYXRlcykKLSAgICAgIHsKLSAgICAgICAgdHJ5ewotICAgICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsID0gKFRyYW5zZm9ybWVySW1wbCl0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsgCi0gICAgICAgICAgaWYgKG1fcHJvYmxlbUxpc3RlbmVyICE9IG51bGwpCi0gICAgICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5zZXRFcnJvckxpc3RlbmVyKG1fcHJvYmxlbUxpc3RlbmVyKTsKLSAgICAgICAgLy8gIGlmIChtX2xpYWlzb24gIT0gbnVsbCkKLSAgICAgICAgLy8gICAgbV90cmFuc2Zvcm1lckltcGwuZ2V0WFBhdGhDb250ZXh0KCkuc2V0RE9NSGVscGVyKG1fbGlhaXNvbik7Ci0gICAKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGNlKTsKLSAgICAgICAgfSAgCi0gICAgICAgIAotICAgICAgICBpZiAobV9zdHlsZXNoZWV0UGFyYW1zICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICBFbnVtZXJhdGlvbiBrZXlzID0gbV9zdHlsZXNoZWV0UGFyYW1zLmtleXMoKTsKLSAgICAgICAgICB3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IChTdHJpbmcpa2V5cy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gbV9zdHlsZXNoZWV0UGFyYW1zLmdldChuYW1lKTsgCi0gICAgICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5zZXRQYXJhbWV0ZXIobmFtZSwgbnVsbCwgdmFsdWUpOwotICAgICAgICAgIH0gCi0gICAgICAgIH0gIAotICAgICAgICAKLSAgICAgICAgdHJ5ewotICAgICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLnRyYW5zZm9ybShuZXcgRE9NU291cmNlKHNvdXJjZVRyZWUpLAotICAgICAgICAgICAgICAgICAgICBvdXRwdXRUYXJnZXQuZ2V0UmVzdWx0T2JqZWN0KCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUpOwotICAgICAgICB9ICAKLSAgICAgICAgaWYobnVsbCAhPSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIpCi0gICAgICAgIHsKLSAgICAgICAgICBkaXNwbGF5RHVyYXRpb24oIlRvdGFsIHRpbWUiLCB0b3RhbFRpbWVJRCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11ZSkKLSAgICB7Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJST1IwMDAwLCBuZXcgT2JqZWN0W10ge211ZS5nZXRNZXNzYWdlKCl9LCBtdWUpOwotICAgICAgLy8gdGhyb3cgc2U7Ci0gICAgfQotICAgIGNhdGNoKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBmbmZlKQotICAgIHsKLSAgICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUlJPUjAwMDAsIG5ldyBPYmplY3RbXSB7Zm5mZS5nZXRNZXNzYWdlKCl9LCBmbmZlKTsKLSAgICAgIC8vIHRocm93IHNlOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSUk9SMDAwMCwgbmV3IE9iamVjdFtdIHtpb2UuZ2V0TWVzc2FnZSgpfSwgaW9lKTsKLSAgICAgIC8vIHRocm93IHNlOwotICAgIH0KLSAgICBjYXRjaChTQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1NBWF9FWENFUFRJT04sIHNlKTsgLy8iU0FYIEV4Y2VwdGlvbiIsIHNlKTsKLSAgICAgIC8vIHRocm93IHNlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSBjcmVhdGlvbiBvZiB0aGUgc3R5bGVzaGVldCBmb3IgZGVyaXZhdGlvbiBwdXJwb3Nlcy4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdCBjcmVhdGVTdHlsZXNoZWV0Um9vdChTdHJpbmcgYmFzZUlkZW50aWZpZXIpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAotICAgICAgICAgICBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB0cnl7Ci0gICAgICBpZiAoYmFzZUlkZW50aWZpZXIgPT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIG5ldyBTdHlsZXNoZWV0Um9vdCh0aGlzLCBiYXNlSWRlbnRpZmllcik7IAotICAgICAgCi0gICAgICBTb3VyY2UgaW5Tb3VyY2UgPSBuZXcgWFNMVElucHV0U291cmNlKGJhc2VJZGVudGlmaWVyKS5nZXRTb3VyY2VPYmplY3QoKTsKLSAgICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBtX3RmYWN0b3J5Lm5ld1RlbXBsYXRlcyhpblNvdXJjZSk7Ci0gICAgICBTdHlsZXNoZWV0Um9vdCBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXRSb290KChvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdCl0ZW1wbGF0ZXMpOyAgICAgIAotICAgICAgcmV0dXJuIHN0eWxlc2hlZXQ7ICAgICAgCi0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGNlKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSBjcmVhdGlvbiBvZiB0aGUgc3R5bGVzaGVldCBmb3IgZGVyaXZhdGlvbiBwdXJwb3Nlcy4KLSAgICovCi0gIFN0eWxlc2hlZXRSb290IGNyZWF0ZVN0eWxlc2hlZXRSb290KFN0cmluZyBiYXNlSWRlbnRpZmllciwgWFNMVElucHV0U291cmNlIHNvdXJjZSkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLCBGaWxlTm90Rm91bmRFeGNlcHRpb24sCi0gICAgICAgICAgIElPRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KLSAgewotICAgIHRyeXsKLSAgICAgIFNvdXJjZSBpblNvdXJjZSA9IHNvdXJjZS5nZXRTb3VyY2VPYmplY3QoKTsKLSAgICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBtX3RmYWN0b3J5Lm5ld1RlbXBsYXRlcyhpblNvdXJjZSk7Ci0gICAgICBTdHlsZXNoZWV0Um9vdCBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXRSb290KChvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdCl0ZW1wbGF0ZXMpOyAgICAgIAotICAgICAgcmV0dXJuIHN0eWxlc2hlZXQ7ICAgICAgCi0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGNlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBVUkkgdG8gYW4gWFNMIHN0eWxlc2hlZXQsCi0gICAqIENvbXBpbGUgdGhlIHN0eWxlc2hlZXQgaW50byBhbiBpbnRlcm5hbCByZXByZXNlbnRhdGlvbi4KLSAgICogVGhpcyBjYWxscyByZXNldCgpIGJlZm9yZSBwcm9jZXNzaW5nIGlmIHRoZSBzdHlsZXNoZWV0IHJvb3QgaGFzIGJlZW4gc2V0Ci0gICAqIHRvIG5vbi1udWxsLgotICAgKiBAcGFyYW0geG1sZG9jVVJMU3RyaW5nICBUaGUgVVJMIHRvIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIGNvbXBpbGVkIHN0eWxlc2hlZXQgb2JqZWN0LgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldFJvb3QgcHJvY2Vzc1N0eWxlc2hlZXQoWFNMVElucHV0U291cmNlIHN0eWxlc2hlZXRTb3VyY2UpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5ewotICAgICAgaWYobnVsbCAhPSAoKFRyYW5zZm9ybWVyRmFjdG9yeUltcGwpbV90ZmFjdG9yeSkubmV3VGVtcGxhdGVzSGFuZGxlcigpLmdldFRlbXBsYXRlcygpKQotICAgICAgICByZXNldCgpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKHRjZSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIHhzbElkZW50aWZpZXIgPSAoKG51bGwgPT0gc3R5bGVzaGVldFNvdXJjZSkgfHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnVsbCA9PSBzdHlsZXNoZWV0U291cmNlLmdldFN5c3RlbUlkKCkpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiSW5wdXQgWFNMIiA6IHN0eWxlc2hlZXRTb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLQotICAgIC8vIEluIGNhc2Ugd2UgaGF2ZSBhIGZyYWdtZW50IGlkZW50aWZpZXIsIGdvIGFoZWFkIGFuZAotICAgIC8vIHRyeSBhbmQgcGFyc2UgdGhlIFhNTCBoZXJlLgotICAgIG1fc3R5bGVzaGVldFJvb3QgPSBudWxsOwotICAgIHRyeQotICAgIHsKLSAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIHN0eWxlc2hlZXRQcm9jZXNzb3IKLSAgICAgICAgICA9IG5ldyBTdHlsZXNoZWV0SGFuZGxlcigoVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCltX3RmYWN0b3J5KTsgLy90aGlzLCBtX3N0eWxlc2hlZXRSb290KTsgCi0gICAgICAgIAotICAgICAgU291cmNlIHNzU291cmNlID0gc3R5bGVzaGVldFNvdXJjZS5nZXRTb3VyY2VPYmplY3QoKTsKLSAgICAgIGlmKHNzU291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKQotICAgICAgewotICAgICAgICBpZigoKERPTVNvdXJjZSlzc1NvdXJjZSkuZ2V0Tm9kZSgpIGluc3RhbmNlb2YgU3R5bGVzaGVldFJvb3QpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3N0eWxlc2hlZXRSb290ID0gKFN0eWxlc2hlZXRSb290KSgoRE9NU291cmNlKXNzU291cmNlKS5nZXROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgc3R5bGVzaGVldFByb2Nlc3Nvci5zZXRTeXN0ZW1JZChzdHlsZXNoZWV0U291cmNlLmdldFN5c3RlbUlkKCkpOwotICAgICAgICAgIFRyZWVXYWxrZXIgdHcgPSBuZXcgVHJlZVdhbGtlcihzdHlsZXNoZWV0UHJvY2Vzc29yLCBuZXcgb3JnLmFwYWNoZS54cGF0aC5ET00ySGVscGVyKCkpOwotICAgICAgICAgIHR3LnRyYXZlcnNlKCgoRE9NU291cmNlKXNzU291cmNlKS5nZXROb2RlKCkpOwotICAgICAgICAgIG1fc3R5bGVzaGVldFJvb3QgPSBuZXcgU3R5bGVzaGVldFJvb3Qoc3R5bGVzaGVldFByb2Nlc3Nvci5nZXRTdHlsZXNoZWV0Um9vdCgpKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCQkJCWlmKG51bGwgIT0gbV9saWFpc29uKQotICAgICAgICB7Ci0gICAgICAgICAvLyBET00ySGVscGVyIGxpYWlzb24gPSAgKERPTTJIZWxwZXIpKENsYXNzLmZvck5hbWUobGlhaXNvbkNsYXNzTmFtZSkubmV3SW5zdGFuY2UoKSk7Ci0gICAgICAgICAgbV9saWFpc29uLnBhcnNlKFNBWFNvdXJjZS5zb3VyY2VUb0lucHV0U291cmNlKHNzU291cmNlKSk7Ci0JCQkJCURPTVNvdXJjZSBzb3VyY2UgPSBuZXcgRE9NU291cmNlKG1fbGlhaXNvbi5nZXREb2N1bWVudCgpKTsKLQkJCQkJVGVtcGxhdGVzIHRlbXBsYXRlcyA9IG1fdGZhY3RvcnkubmV3VGVtcGxhdGVzKHNvdXJjZSk7Ci0JCQkJCW1fc3R5bGVzaGVldFJvb3QgPSBuZXcgU3R5bGVzaGVldFJvb3QoCi0JCQkJCQkJCQkJCQkJCQkJKG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290KXRlbXBsYXRlcyk7CQkJCQkJCQkJCQkJCQkJCSAKLSAgICAgICAgfSAgCi0JCQkJZWxzZQotCQkJCXsKLQkJCQkJbV9zdHlsZXNoZWV0Um9vdCA9IGNyZWF0ZVN0eWxlc2hlZXRSb290KHN0eWxlc2hlZXRTb3VyY2UuZ2V0U3lzdGVtSWQoKSwgc3R5bGVzaGVldFNvdXJjZSk7Ci0JCQkJfQotICAgICAgICBhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCgpOwotICAgICAgICAKLSAgICAgICAgCi0gICAgICAgIHN0eWxlc2hlZXRQcm9jZXNzb3IucHVzaFN0eWxlc2hlZXQobV9zdHlsZXNoZWV0Um9vdC5nZXRPYmplY3QoKSk7ICAgICAgCi0gICAgICAgIGRpYWcoIj09PT09PT09PSBQYXJzaW5nICIreHNsSWRlbnRpZmllcisiID09PT09PT09PT0iKTsKLSAgICAgICAgcHVzaFRpbWUoeHNsSWRlbnRpZmllcik7Ci0gICAgICAgIC8vU3RyaW5nIGxpYWlzb25DbGFzc05hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9yZy5hcGFjaGUueGFsYW4uc291cmNlLmxpYWlzb24iKTsKLQotICAgICAgICAKLSAgICAgICAgaWYobnVsbCAhPSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIpCi0gICAgICAgICAgZGlzcGxheUR1cmF0aW9uKCJQYXJzZSBvZiAiK3hzbElkZW50aWZpZXIsIHhzbElkZW50aWZpZXIpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ09VTEROVF9QQVJTRV9ET0MsIG5ldyBPYmplY3RbXSB7eHNsSWRlbnRpZmllcn0sIGUpOyAvLyJDb3VsZCBub3QgcGFyc2UgIit4c2xJZGVudGlmaWVyKyIgZG9jdW1lbnQhIiwgZSk7Ci0gICAgfQotICAgIHJldHVybiBtX3N0eWxlc2hlZXRSb290OwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgVVJJIHRvIGFuIFhTTCBzdHlsZXNoZWV0LAotICAgKiBDb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24uCi0gICAqIFRoaXMgY2FsbHMgcmVzZXQoKSBiZWZvcmUgcHJvY2Vzc2luZyBpZiB0aGUgc3R5bGVzaGVldCByb290IGhhcyBiZWVuIHNldAotICAgKiB0byBub24tbnVsbC4KLSAgICogQHBhcmFtIHhtbGRvY1VSTFN0cmluZyAgVGhlIFVSTCB0byB0aGUgaW5wdXQgWE1MIGRvY3VtZW50LgotICAgKiBAcmV0dXJuIFRoZSBjb21waWxlZCBzdHlsZXNoZWV0IG9iamVjdC4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRSb290IHByb2Nlc3NTdHlsZXNoZWV0KFN0cmluZyB4c2xkb2NVUkxTdHJpbmcpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgWFNMVElucHV0U291cmNlIGlucHV0ID0gbmV3IFhTTFRJbnB1dFNvdXJjZShnZXRVUkxGcm9tU3RyaW5nKHhzbGRvY1VSTFN0cmluZywgbnVsbCkudG9TdHJpbmcoKSk7Ci0gICAgICByZXR1cm4gcHJvY2Vzc1N0eWxlc2hlZXQoaW5wdXQpOwotICAgIH0KLSAgICBjYXRjaChTQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMLCBzZSk7IC8vInByb2Nlc3NTdHlsZXNoZWV0IG5vdCBzdWNjZXNmdWxsISIsIHNlKTsKLSAgICAgIHJldHVybiBudWxsOyAvLyBzaHV0IHVwIGNvbXBpbGVyCi0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgc3R5bGVzaGVldCBmb3IgdGhpcyBwcm9jZXNzb3IuICBJZiB0aGlzIGlzIHNldCwgdGhlbiB0aGUKLSAgICogcHJvY2VzcyBjYWxscyB0aGF0IHRha2Ugb25seSB0aGUgaW5wdXQgLnhtbCB3aWxsIHVzZQotICAgKiB0aGlzIGluc3RlYWQgb2YgbG9va2luZyBmb3IgYSBzdHlsZXNoZWV0IFBJLiAgQWxzbywKLSAgICogc2V0dGluZyB0aGUgc3R5bGVzaGVldCBpcyBuZWVkZWQgaWYgeW91IGFyZSBnb2luZwotICAgKiB0byB1c2UgdGhlIHByb2Nlc3NvciBhcyBhIFNBWCBEb2N1bWVudEhhbmRsZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0KFN0eWxlc2hlZXRSb290IHN0eWxlc2hlZXRSb290KQotICB7Ci0gICAgbV9zdHlsZXNoZWV0Um9vdCA9IHN0eWxlc2hlZXRSb290OwotICAgIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290IHNyID0gc3R5bGVzaGVldFJvb3QuZ2V0T2JqZWN0KCk7Ci0gICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsID09IG51bGwpCi0gICAgICBtX3RyYW5zZm9ybWVySW1wbCA9IChUcmFuc2Zvcm1lckltcGwpc3IubmV3VHJhbnNmb3JtZXIoKTsKLSAgICBtX3RyYW5zZm9ybWVySW1wbC5zZXRTdHlsZXNoZWV0KHNyKTsKLSAgICBpZiAobV9wcm9ibGVtTGlzdGVuZXIgIT0gbnVsbCkKLSAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLnNldEVycm9yTGlzdGVuZXIobV9wcm9ibGVtTGlzdGVuZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdHlsZXNoZWV0IGZvciB0aGlzIHByb2Nlc3Nvci4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdCBnZXRTdHlsZXNoZWV0KCkgICAgCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZXNoZWV0Um9vdDsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSBmaWxlbmFtZSBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LCBpZiBpdCB3YXMgc2V0LgotICAgKiBUaGlzIGlzIGZvciB1c2UgYnkgbXVsdGlwbGUgb3V0cHV0IGRvY3VtZW50cywgdG8gZGV0ZXJtaW5lCi0gICAqIHRoZSBiYXNlIGRpcmVjdG9yeSBmb3IgdGhlIG91dHB1dCBkb2N1bWVudC4gIEl0IG5lZWRzIHRvCi0gICAqIGJlIHNldCBieSB0aGUgY2FsbGVyLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRPdXRwdXRGaWxlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9vdXRwdXRGaWxlTmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogU2V0IHRoZSBmaWxlbmFtZSBvZiB0aGUgb3V0cHV0IGRvY3VtZW50LgotICAgKiBUaGlzIGlzIGZvciB1c2UgYnkgbXVsdGlwbGUgb3V0cHV0IGRvY3VtZW50cywgdG8gZGV0ZXJtaW5lCi0gICAqIHRoZSBiYXNlIGRpcmVjdG9yeSBmb3IgdGhlIG91dHB1dCBkb2N1bWVudC4gIEl0IG5lZWRzIHRvCi0gICAqIGJlIHNldCBieSB0aGUgY2FsbGVyLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0RmlsZU5hbWUoU3RyaW5nIGZpbGVuYW1lKQotICB7Ci0gICAgbV9vdXRwdXRGaWxlTmFtZSA9IGZpbGVuYW1lOwotICB9Ci0KLSAgCi0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGlucHV0IHNvdXJjZSwgZ2V0IHRoZSBzb3VyY2UgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldFNvdXJjZVRyZWVGcm9tSW5wdXQoWFNMVElucHV0U291cmNlIGlucHV0U291cmNlKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIE5vZGUgc291cmNlVHJlZSA9IG51bGw7Ci0gICAgU3RyaW5nIHhtbElkZW50aWZpZXIgPSAoKG51bGwgPT0gaW5wdXRTb3VyY2UpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG51bGwgPT0gaW5wdXRTb3VyY2UuZ2V0U3lzdGVtSWQoKSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICA/ICJJbnB1dCBYTUwiIDogaW5wdXRTb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLSAgICAKLSAgICBTb3VyY2UgaVNvdXJjZSA9IGlucHV0U291cmNlLmdldFNvdXJjZU9iamVjdCgpOyAKLQotICAgIGlmKGlTb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpCi0gICAgewotICAgICAgLy9pZihnZXRYTUxQcm9jZXNzb3JMaWFpc29uKCkgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLmR0bS5EVE1MaWFpc29uKQotICAgICAgIC8vIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5UX1VTRV9EVE1fRk9SX0lOUFVUKTsKLQotICAgICAgc291cmNlVHJlZSA9ICgoRE9NU291cmNlKWlTb3VyY2UpLmdldE5vZGUoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIEluIGNhc2Ugd2UgaGF2ZSBhIGZyYWdtZW50IGlkZW50aWZpZXIsIGdvIGFoZWFkIGFuZAotICAgICAgLy8gdHJ5IGFuZCBwYXJzZSB0aGUgWE1MIGhlcmUuCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZGlhZygiPT09PT09PT09IFBhcnNpbmcgIit4bWxJZGVudGlmaWVyKyIgPT09PT09PT09PSIpOwotICAgICAgICBwdXNoVGltZSh4bWxJZGVudGlmaWVyKTsKLSAgICAgICAgCi0gICAgICAgIC8vU3RyaW5nIGxpYWlzb25DbGFzc05hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9yZy5hcGFjaGUueGFsYW4uc291cmNlLmxpYWlzb24iKTsKLQotICAgICAgICBpZihudWxsICE9IG1fbGlhaXNvbikKLSAgICAgICAgewotICAgICAgICAgIC8vRE9NMkhlbHBlciBsaWFpc29uID0gIChET00ySGVscGVyKShDbGFzcy5mb3JOYW1lKGxpYWlzb25DbGFzc05hbWUpLm5ld0luc3RhbmNlKCkpOwotICAgICAgICAgIG1fbGlhaXNvbi5wYXJzZShTQVhTb3VyY2Uuc291cmNlVG9JbnB1dFNvdXJjZShpU291cmNlKSk7Ci0gICAgICAgICAgaWYobnVsbCAhPSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIpCi0gICAgICAgICAgICBkaXNwbGF5RHVyYXRpb24oIlBhcnNlIG9mICIreG1sSWRlbnRpZmllciwgeG1sSWRlbnRpZmllcik7Ci0gICAgICAgICAgc291cmNlVHJlZSA9IG1fbGlhaXNvbi5nZXREb2N1bWVudCgpOwotICAgICAgICB9Ci0JCQkJZWxzZQotCQkJCXsKLQkJCQkJdHJ5Ci0JCQkJCXsKLQotCQkJCQkJLy8gVXNlIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBKQVZBIEFQSSBmb3IgWE1MIFBhcnNpbmcgMS4wIHRvCi0JCQkJCQkvLyBjcmVhdGUgYSBET00gRG9jdW1lbnQgbm9kZSB0byBjb250YWluIHRoZSByZXN1bHQuCi0JCQkJCQlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0JCQkJCQlkZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQkJCQkJCWRmYWN0b3J5LnNldFZhbGlkYXRpbmcoZmFsc2UpOwotCi0JCQkJCQlEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotCQkJCQkJc291cmNlVHJlZSA9IGRvY0J1aWxkZXIucGFyc2UoeG1sSWRlbnRpZmllcik7Ci0KLQkJCQkJfQotCQkJCQljYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpCi0JCQkJCXsKLQkJCQkJCWVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1VMRE5UX1BBUlNFX0RPQywgbmV3IE9iamVjdFtdIHt4bWxJZGVudGlmaWVyfSwgcGNlKTsgCi0JCQkJCX0KLQkJCQl9CQkJCQkJCQotICAgICAgfQotICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIFVud3JhcCBleGNlcHRpb24KLSAgICAgICAgaWYoKGUgaW5zdGFuY2VvZiBTQVhFeGNlcHRpb24pICYmIChudWxsICE9ICgoU0FYRXhjZXB0aW9uKWUpLmdldEV4Y2VwdGlvbigpKSkKLSAgICAgICAgewotICAgICAgICAgIC8vICgoU0FYRXhjZXB0aW9uKWUpLmdldEV4Y2VwdGlvbigpLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgIGUgPSAoKFNBWEV4Y2VwdGlvbillKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgfQotICAgICAgICBzb3VyY2VUcmVlID0gbnVsbDsgLy8gc2h1dHVwIGNvbXBpbGVyCi0gICAgICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1VMRE5UX1BBUlNFX0RPQywgbmV3IE9iamVjdFtdIHt4bWxJZGVudGlmaWVyfSwgZSk7IC8vIkNvdWxkIG5vdCBwYXJzZSAiK3htbElkZW50aWZpZXIrIiBkb2N1bWVudCEiLCBlKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gc291cmNlVHJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgU3R5bGVzaGVldCBmcm9tIFBJIFVSTAotICAgKiAKLSAgICogQHBhcmFtIHhzbFVSTFN0cmluZyBhIHZhbGlkIFVSSSB0byBhbiBYU0wgc3R5bGVzaGVldC4KLSAgICogQHBhcmFtIGZyYWdiYXNlIERvY3VtZW50IGZyYWdtZW50IE5vZGUuCi0gICAqIEBwYXJhbSB4bWxCYXNlSWRlbnQgQmFzZSBVUkkgdG8gcmVzb2x2ZSBzdHlsZXNoZWV0IFVSTCAKLSAgICogQHBhcmFtIGlzUm9vdCBGbGFnIGluZGljYXRpbmcgaWYgcm9vdCBub2RlCi0gICAqLwotICBTdHlsZXNoZWV0IGdldFN0eWxlc2hlZXRGcm9tUElVUkwoU3RyaW5nIHhzbFVSTFN0cmluZywgTm9kZSBmcmFnQmFzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB4bWxCYXNlSWRlbnQsIGJvb2xlYW4gaXNSb290KQotICAgIHRocm93cyBTQVhFeGNlcHRpb24sCi0gICAgTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwKLSAgICBJT0V4Y2VwdGlvbgotICB7Ci0gICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gbnVsbDsKLSAgICBTdHJpbmdbXSBzdHJpbmdIb2xkZXIgPQotICAgIHsKLSAgICAgIG51bGx9OwotICAgIHhzbFVSTFN0cmluZyA9IHhzbFVSTFN0cmluZy50cmltKCk7Ci0gICAgaW50IGZyYWdJbmRleCA9IHhzbFVSTFN0cmluZy5pbmRleE9mKCcjJyk7Ci0gICAgU3RyaW5nIGZyYWdJRCA9IG51bGw7Ci0gICAgRG9jdW1lbnQgc3R5bGVzaGVldERvYzsKLSAgICBpZihmcmFnSW5kZXggPT0gMCkKLSAgICB7Ci0gICAgICBkaWFnKCJMb2NhdGluZyBzdHlsZXNoZWV0IGZyb20gZnJhZ21lbnQgaWRlbnRpZmllci4uLiIpOwotICAgICAgZnJhZ0lEID0geHNsVVJMU3RyaW5nLnN1YnN0cmluZygxKTsKLSAgICAgIAotICAgICAgLy8gVHJ5IGEgYnVuY2ggb2YgcmVhbGx5IHVnbHkgc3R1ZmYgdG8gZmluZCB0aGUgZnJhZ21lbnQuCi0gICAgICAvLyBXaGF0J3MgdGhlIHJpZ2h0IHdheSB0byBkbyB0aGlzPwotCi0gICAgICAvLyBDcmVhdGUgYSBYUGF0aCBwYXJzZXIuCi0gICAgICBYUGF0aFBhcnNlciBwYXJzZXIgPSBuZXcgWFBhdGhQYXJzZXIoKEVycm9yTGlzdGVuZXIpbV9wcm9ibGVtTGlzdGVuZXIuZ2V0RXJyb3JIYW5kbGVyKCksIG51bGwpOwotICAgICAgWFBhdGhDb250ZXh0IHhwYXRoQ29udGV4dCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICAgIFByZWZpeFJlc29sdmVyRGVmYXVsdCBuc05vZGUgPSBuZXcgUHJlZml4UmVzb2x2ZXJEZWZhdWx0KGZyYWdCYXNlKTsgLy94cGF0aENvbnRleHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpOwotCi0gICAgICBOb2RlSXRlcmF0b3IgbmwgPSBudWxsOwotICAgICAgLy8gQ3JlYXRlIHRoZSBYUGF0aCBvYmplY3QuCi0gICAgICB0cnl7Ci0gICAgICBYUGF0aCB4cGF0aCA9IG5ldyBYUGF0aChmcmFnSUQsIG51bGwsIG5zTm9kZSwgWFBhdGguTUFUQ0gpOwotICAgICAgQ29tcGlsZXIgY29tcGlsZXIgPSBuZXcgQ29tcGlsZXIoKTsKLSAgICAgIC8vIFBhcnNlIHRoZSB4cGF0aAotICAgICAgcGFyc2VyLmluaXRYUGF0aChjb21waWxlciwgImlkKCIrZnJhZ0lEKyIpIiwgbnNOb2RlKTsKLSAgICAgIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0IHhvYmogPSB4cGF0aC5leGVjdXRlKHhwYXRoQ29udGV4dCwgZnJhZ0Jhc2UsIG5zTm9kZSk7Ci0KLSAgICAgIG5sID0gbmV3IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKHhvYmouaXRlcigpKTsKLSAgICAgIGlmKG5sLm5leHROb2RlKCkgPT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgLy8geG9iaiA9IFN0eWxlc2hlZXQuZXZhbFhQYXRoU3RyKGdldEV4ZWNDb250ZXh0KCksICIvLypbQGlkPSciK2ZyYWdJRCsiJ10iLCBmcmFnQmFzZSwgbnNOb2RlKTsKLSAgICAgICAgLy8gQ3JlYXRlIHRoZSBYUGF0aCBvYmplY3QuCi0gICAgICAgIHhwYXRoID0gbmV3IFhQYXRoKGZyYWdJRCwgbnVsbCwgbnNOb2RlLCBYUGF0aC5NQVRDSCk7Ci0KLSAgICAgICAgLy8gUGFyc2UgdGhlIHhwYXRoCi0gICAgICAgIHBhcnNlci5pbml0WFBhdGgoY29tcGlsZXIsICIvLypbQGlkPSciK2ZyYWdJRCsiJ10iLCBuc05vZGUpOwotICAgICAgICB4b2JqID0geHBhdGguZXhlY3V0ZSh4cGF0aENvbnRleHQsIGZyYWdCYXNlLCBuc05vZGUpOwotCi0gICAgICAgIG5sID0gbmV3IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKHhvYmouaXRlcigpKTsKLSAgICAgICAgaWYobmwubmV4dE5vZGUoKSA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgLy8geG9iaiA9IFN0eWxlc2hlZXQuZXZhbFhQYXRoU3RyKGdldEV4ZWNDb250ZXh0KCksICIvLypbQG5hbWU9JyIrZnJhZ0lEKyInXSIsIGZyYWdCYXNlLCBuc05vZGUpOwotICAgICAgICAgIC8vIENyZWF0ZSB0aGUgWFBhdGggb2JqZWN0LgotICAgICAgICAgIHhwYXRoID0gbmV3IFhQYXRoKGZyYWdJRCwgbnVsbCwgbnNOb2RlLCBYUGF0aC5NQVRDSCk7Ci0KLSAgICAgICAgICAvLyBQYXJzZSB0aGUgeHBhdGgKLSAgICAgICAgICBwYXJzZXIuaW5pdFhQYXRoKGNvbXBpbGVyLCAiLy8qW0BuYW1lPSciK2ZyYWdJRCsiJ10iLCBuc05vZGUpOwotICAgICAgICAgIHhvYmogPSB4cGF0aC5leGVjdXRlKHhwYXRoQ29udGV4dCwgZnJhZ0Jhc2UsIG5zTm9kZSk7Ci0gICAgICAgICAgbmwgPSBuZXcgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Ob2RlSXRlcmF0b3IoeG9iai5pdGVyKCkpOwotICAgICAgICAgIGlmKG5sLm5leHROb2RlKCkgPT0gbnVsbCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBXZWxsLCBoZWxsLCBtYXliZSBpdCdzIGFuIFhQYXRoLi4uCi0gICAgICAgICAgICAvLyB4b2JqID0gU3R5bGVzaGVldC5ldmFsWFBhdGhTdHIoZ2V0RXhlY0NvbnRleHQoKSwgZnJhZ0lELCBmcmFnQmFzZSwgbnNOb2RlKTsKLSAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgWFBhdGggb2JqZWN0LgotICAgICAgICAgICAgLy8oKFN0eWxlc2hlZXRIYW5kbGVyKSggbV9wcm9jZXNzb3IuZ2V0VGVtcGxhdGVzQnVpbGRlcigpKSkuZ2V0TG9jYXRvcigpCi0gICAgICAgICAgICB4cGF0aCA9IG5ldyBYUGF0aChmcmFnSUQsIG51bGwsIG5zTm9kZSwgWFBhdGguTUFUQ0gpOwotCi0gICAgICAgICAgICAvLyBQYXJzZSB0aGUgeHBhdGgKLSAgICAgICAgICAgIHBhcnNlci5pbml0WFBhdGgoY29tcGlsZXIsIGZyYWdJRCwgbnNOb2RlKTsKLSAgICAgICAgICAgIHhvYmogPSB4cGF0aC5leGVjdXRlKHhwYXRoQ29udGV4dCwgZnJhZ0Jhc2UsIG5zTm9kZSk7Ci0gICAgICAgICAgICBubCA9IG5ldyBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVJdGVyYXRvcih4b2JqLml0ZXIoKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUpOwotICAgICAgfQotICAgICAgaWYobmwubmV4dE5vZGUoKSA9PSBudWxsKQotICAgICAgewotICAgICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ09VTEROVF9GSU5EX0ZSQUdNRU5ULCBuZXcgT2JqZWN0W10ge2ZyYWdJRH0pOyAvLyJDb3VsZCBub3QgZmluZCBmcmFnbWVudDogIitmcmFnSUQpOwotICAgICAgfQotICAgICAgLy8gVXNlIHByZXZpb3VzIGJlY2F1c2UgdGhlIHByZXZpb3VzIGNhbGwgbW92ZWQgdGhlIHBvaW50ZXIuCi0gICAgICAvLyBvciBzaG91bGQgd2UgdXNlIGdldFJvb3Q/PwotICAgICAgTm9kZSBmcmFnID0gbmwucHJldmlvdXNOb2RlKCk7IC8vLml0ZW0oMCk7Ci0KLSAgICAgIGlmKE5vZGUuRUxFTUVOVF9OT0RFID09IGZyYWcuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgIHsKLSAgICAgICAgcHVzaFRpbWUoZnJhZyk7Ci0gICAgICAgIGlmKGlzUm9vdCkKLSAgICAgICAgewotICAgICAgICAgIG1fc3R5bGVzaGVldFJvb3QgPSBjcmVhdGVTdHlsZXNoZWV0Um9vdChzdHJpbmdIb2xkZXJbMF0pOwotICAgICAgICAgIHN0eWxlc2hlZXQgPSBtX3N0eWxlc2hlZXRSb290LmdldE9iamVjdCgpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIC8vc3R5bGVzaGVldCA9IG5ldyBTdHlsZXNoZWV0KG1fc3R5bGVzaGVldFJvb3QpOwotICAgICAgICAgIC8vIHN0eWxlc2hlZXQgPSAoKFN0eWxlc2hlZXRIYW5kbGVyKShtX3Byb2Nlc3Nvci5nZXRUZW1wbGF0ZXNCdWlsZGVyKCkpKS5nZXRTdHlsZXNoZWV0Um9vdCgpOwotICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgIFNvdXJjZSBzb3VyY2UgPSBuZXcgWFNMVElucHV0U291cmNlKGZyYWdJRCkuZ2V0U291cmNlT2JqZWN0KCk7IAotICAgICAgICAgICAgVGVtcGxhdGVzIHRlbXBsYXRlcyA9IG1fdGZhY3RvcnkubmV3VGVtcGxhdGVzKHNvdXJjZSk7Ci0gICAgICAgICAgICBzdHlsZXNoZWV0ID0gKG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290KXRlbXBsYXRlczsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB0Y2UpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0Y2UpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBhZGRUcmFjZUxpc3RlbmVyc1RvU3R5bGVzaGVldCgpOwotCi0gICAgICAgIHRyeXsKLSAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgc3R5bGVzaGVldFByb2Nlc3NvcgotICAgICAgICAgID0gbmV3IFN0eWxlc2hlZXRIYW5kbGVyKChUcmFuc2Zvcm1lckZhY3RvcnlJbXBsKW1fdGZhY3RvcnkpOwotICAgICAgICAgICAKLSAgICAgICAgc3R5bGVzaGVldFByb2Nlc3Nvci5wdXNoU3R5bGVzaGVldChzdHlsZXNoZWV0KTsKLSAgICAgICAgVHJlZVdhbGtlciB0dyA9IG5ldyBUcmVlV2Fsa2VyKHN0eWxlc2hlZXRQcm9jZXNzb3IsIG5ldyBvcmcuYXBhY2hlLnhwYXRoLkRPTTJIZWxwZXIoKSk7Ci0gICAgICAgIHR3LnRyYXZlcnNlKGZyYWcpOwotCi0gICAgICAgIGRpc3BsYXlEdXJhdGlvbigiU2V0dXAgb2YgIit4c2xVUkxTdHJpbmcsIGZyYWcpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGNlKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0Y2UpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHN0eWxlc2hlZXREb2MgPSBudWxsOwotICAgICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9ERV9OT1RfRUxFTUVOVCwgbmV3IE9iamVjdFtdIHtmcmFnSUR9KTsgLy8iTm9kZSBwb2ludGVkIHRvIGJ5IGZyYWdtZW50IGlkZW50aWZpZXIgd2FzIG5vdCBhbiBlbGVtZW50OiAiK2ZyYWdJRCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAvLyBUT0RPOiBVc2UgUmVhZGVyIGhlcmU/PwotICAgICAgLy8gaG1tbS4uIGZvciBub3cgSSdsbCByZWx5IG9uIHRoZSBYTUwgcGFyc2VyIHRvIGhhbmRsZQotICAgICAgLy8gZnJhZ21lbnQgVVJMcy4KLSAgICAgIGRpYWcoWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HLCBuZXcgT2JqZWN0W10ge3hzbFVSTFN0cmluZ30pKTsgLy8iPT09PT09PT09IFBhcnNpbmcgYW5kIHByZXBhcmluZyAiK3hzbFVSTFN0cmluZysiID09PT09PT09PT0iKTsKLSAgICAgIHB1c2hUaW1lKHhzbFVSTFN0cmluZyk7Ci0KLQkJCVVSTCB4c2xVUkwgPSBnZXRVUkxGcm9tU3RyaW5nKHhzbFVSTFN0cmluZywgeG1sQmFzZUlkZW50KTsKLQotICAgICAgWFNMVElucHV0U291cmNlIGlucHV0U291cmNlID0gbmV3IFhTTFRJbnB1dFNvdXJjZSh4c2xVUkwudG9TdHJpbmcoKSk7Ci0gICAgICAKLQkJCWlmKGlzUm9vdCkKLQkJCXsJCQkJCi0JCQkJaWYobnVsbCAhPSBtX2xpYWlzb24pCi0JCQkJewotCQkJCQl0cnl7Ci0JCQkJCQltX2xpYWlzb24ucGFyc2UoU0FYU291cmNlLnNvdXJjZVRvSW5wdXRTb3VyY2UoaW5wdXRTb3VyY2UuZ2V0U291cmNlT2JqZWN0KCkpKTsKLQkJCQkJCURPTVNvdXJjZSBzb3VyY2UgPSBuZXcgRE9NU291cmNlKG1fbGlhaXNvbi5nZXREb2N1bWVudCgpKTsKLQkJCQkJCVRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBtX3RmYWN0b3J5Lm5ld1RlbXBsYXRlcyhzb3VyY2UpOwotCQkJCQkJbV9zdHlsZXNoZWV0Um9vdCA9IG5ldyBTdHlsZXNoZWV0Um9vdCgKLQkJCQkJCQkJCQkJCQkJCQkJCShvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdCl0ZW1wbGF0ZXMpOwotCQkJCQl9CQkJCQkKLQkJCQkJY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRjZSkKLQkJCQkJewotCQkJCQkJdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0Y2UpOwotCQkJCQl9Ci0JCQkJfQotCQkJCWVsc2UKLQkJCQl7Ci0JCQkJCW1fc3R5bGVzaGVldFJvb3QgPSBjcmVhdGVTdHlsZXNoZWV0Um9vdCh4c2xVUkxTdHJpbmcpOwotCQkJCX0KLQkJCQlzdHlsZXNoZWV0ID0gbV9zdHlsZXNoZWV0Um9vdC5nZXRPYmplY3QoKTsKLQkJCX0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgc3R5bGVzaGVldCA9IG5ldyBTdHlsZXNoZWV0KG1fc3R5bGVzaGVldFJvb3QuZ2V0T2JqZWN0KCkpOwotICAgICAgfQotICAgICAgYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQoKTsKLQotICAgICAgdHJ5ewotICAgICAgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuU3R5bGVzaGVldEhhbmRsZXIgc3R5bGVzaGVldFByb2Nlc3NvcgotICAgICAgICA9IG5ldyBTdHlsZXNoZWV0SGFuZGxlcigoVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCltX3RmYWN0b3J5KTsgLy90aGlzLCBzdHlsZXNoZWV0KTsgCi0gICAgICBzdHlsZXNoZWV0UHJvY2Vzc29yLnB1c2hTdHlsZXNoZWV0KHN0eWxlc2hlZXQpOwotICAgICAgICAgLy8gbmV3IFN0eWxlc2hlZXRIYW5kbGVyKHRoaXMsIHN0eWxlc2hlZXQpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB0Y2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGNlKTsKLSAgICAgIH0KLSAgICAgIAotICAgICAgIAotICAgICAgLy9tX3BhcnNlckxpYWlzb24uc2V0RG9jdW1lbnRIYW5kbGVyKHN0eWxlc2hlZXRQcm9jZXNzb3IpOwotICAgICAgLy9tX3BhcnNlckxpYWlzb24ucGFyc2UoaW5wdXRTb3VyY2UpOwotCi0gICAgICBkaXNwbGF5RHVyYXRpb24oIlBhcnNpbmcgYW5kIGluaXQgb2YgIit4c2xVUkxTdHJpbmcsIHhzbFVSTFN0cmluZyk7Ci0gICAgfQotICAgIHJldHVybiBzdHlsZXNoZWV0OwotICB9Ci0KLSAgICAgICAgCi0gIC8qKgotICAgKiBUYWtlIGEgdXNlciBzdHJpbmcgYW5kIHRyeSBhbmQgcGFyc2UgWE1MLCBhbmQgYWxzbyByZXR1cm4gCi0gICAqIHRoZSB1cmwuCi0gICAqIEBleGNlcHRpb24gWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZSAKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgVVJMIGdldFVSTEZyb21TdHJpbmcoU3RyaW5nIHVybFN0cmluZywgU3RyaW5nIGJhc2UpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiAKLSAgewotICAgIFN0cmluZyBvcmlnVVJMU3RyaW5nID0gdXJsU3RyaW5nOwotICAgIFN0cmluZyBvcmlnQmFzZSA9IGJhc2U7Ci0gICAgCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXRVUkxGcm9tU3RyaW5nIC0gdXJsU3RyaW5nOiAiK3VybFN0cmluZysiLCBiYXNlOiAiK2Jhc2UpOwotICAgIE9iamVjdCBkb2M7Ci0gICAgVVJMIHVybCA9IG51bGw7Ci0gICAgaW50IGZpbGVTdGFydFR5cGUgPSAwOwotICAgIHRyeQotICAgIHsKLSAgICAgIAotICAgICAgaWYobnVsbCAhPSBiYXNlKQotICAgICAgewotICAgICAgICBpZihiYXNlLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgiZmlsZTovIikpCi0gICAgICAgIHsKLSAgICAgICAgICBmaWxlU3RhcnRUeXBlID0gMTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKGJhc2UudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCJmaWxlOiIpKQotICAgICAgICB7Ci0gICAgICAgICAgZmlsZVN0YXJ0VHlwZSA9IDI7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIAotICAgICAgYm9vbGVhbiBpc0Fic29sdXRlVVJMOwotICAgICAgCi0gICAgICAvLyBGcm9tIGh0dHA6Ly93d3cuaWNzLnVjaS5lZHUvcHViL2lldGYvdXJpL3JmYzE2MzAudHh0Ci0gICAgICAvLyBBIHBhcnRpYWwgZm9ybSBjYW4gYmUgZGlzdGluZ3Vpc2hlZCBmcm9tIGFuIGFic29sdXRlIGZvcm0gaW4gdGhhdCB0aGUKLSAgICAgIC8vIGxhdHRlciBtdXN0IGhhdmUgYSBjb2xvbiBhbmQgdGhhdCBjb2xvbiBtdXN0IG9jY3VyIGJlZm9yZSBhbnkgc2xhc2gKLSAgICAgIC8vIGNoYXJhY3RlcnMuIFN5c3RlbXMgbm90IHJlcXVpcmluZyBwYXJ0aWFsIGZvcm1zIHNob3VsZCBub3QgdXNlIGFueQotICAgICAgLy8gdW5lbmNvZGVkIHNsYXNoZXMgaW4gdGhlaXIgbmFtaW5nIHNjaGVtZXMuICBJZiB0aGV5IGRvLCBhYnNvbHV0ZSBVUklzCi0gICAgICAvLyB3aWxsIHN0aWxsIHdvcmssIGJ1dCBjb25mdXNpb24gbWF5IHJlc3VsdC4KLSAgICAgIGludCBpbmRleE9mQ29sb24gPSB1cmxTdHJpbmcuaW5kZXhPZignOicpOwotICAgICAgaW50IGluZGV4T2ZTbGFzaCA9IHVybFN0cmluZy5pbmRleE9mKCcvJyk7Ci0gICAgICBpZigoaW5kZXhPZkNvbG9uICE9IC0xKSAmJiAoaW5kZXhPZlNsYXNoICE9IC0xKSAmJiAoaW5kZXhPZkNvbG9uIDwgaW5kZXhPZlNsYXNoKSkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhlIHVybCAob3IgZmlsZW5hbWUsIGZvciB0aGF0IG1hdHRlcikgaXMgYWJzb2x1dGUuCi0gICAgICAgIGlzQWJzb2x1dGVVUkwgPSB0cnVlOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpc0Fic29sdXRlVVJMID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGlmKGlzQWJzb2x1dGVVUkwgfHwgKG51bGwgPT0gYmFzZSkgfHwgKGJhc2UubGVuZ3RoKCkgPT0gMCkpCi0gICAgICB7Ci0gICAgICAgIHRyeSAKLSAgICAgICAgewotICAgICAgICAgIHVybCA9IG5ldyBVUkwodXJsU3RyaW5nKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHt9Ci0gICAgICB9Ci0gICAgICAvLyBUaGUgSmF2YSBVUkwgaGFuZGxpbmcgZG9lc24ndCBzZWVtIHRvIGhhbmRsZSByZWxhdGl2ZSBmaWxlIG5hbWVzLgotICAgICAgZWxzZSBpZighKCh1cmxTdHJpbmcuY2hhckF0KDApID09ICcuJykgfHwgKGZpbGVTdGFydFR5cGUgPiAwKSkpCi0gICAgICB7Ci0gICAgICAgIHRyeSAKLSAgICAgICAgewotICAgICAgICAgIFVSTCBiYXNlVXJsID0gbmV3IFVSTChiYXNlKTsKLSAgICAgICAgICB1cmwgPSBuZXcgVVJMKGJhc2VVcmwsIHVybFN0cmluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSAKLSAgICAgICAgewotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGlmKG51bGwgPT0gdXJsKQotICAgICAgewotICAgICAgICAvLyBUaGVuIHdlJ3JlIGdvaW5nIHRvIHRyeSBhbmQgbWFrZSBhIGZpbGUgVVJMIGJlbG93LCBzbyBzdHJpcCAKLSAgICAgICAgLy8gb2ZmIHRoZSBwcm90b2NvbCBoZWFkZXIuCi0gICAgICAgIGlmKHVybFN0cmluZy50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoImZpbGU6LyIpKQotICAgICAgICB7Ci0gICAgICAgICAgdXJsU3RyaW5nID0gdXJsU3RyaW5nLnN1YnN0cmluZyg2KTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmKHVybFN0cmluZy50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoImZpbGU6IikpCi0gICAgICAgIHsKLSAgICAgICAgICB1cmxTdHJpbmcgPSB1cmxTdHJpbmcuc3Vic3RyaW5nKDUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGlmKChudWxsID09IHVybCkgJiYgKChudWxsID09IGJhc2UpIHx8IChmaWxlU3RhcnRUeXBlID4gMCkpKQotICAgICAgewotICAgICAgICBpZigxID09IGZpbGVTdGFydFR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBpZihudWxsICE9IGJhc2UpCi0gICAgICAgICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoNik7Ci0gICAgICAgICAgZmlsZVN0YXJ0VHlwZSA9IDE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZigyID09IGZpbGVTdGFydFR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBpZihudWxsICE9IGJhc2UpCi0gICAgICAgICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoNSk7Ci0gICAgICAgICAgZmlsZVN0YXJ0VHlwZSA9IDI7Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKHVybFN0cmluZyk7Ci0gICAgICAgIAotICAgICAgICBpZighZi5pc0Fic29sdXRlKCkgJiYgKG51bGwgIT0gYmFzZSkpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBTdHJpbmcgZGlyID0gZi5pc0RpcmVjdG9yeSgpID8gZi5nZXRBYnNvbHV0ZVBhdGgoKSA6IGYuZ2V0UGFyZW50KCk7Ci0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJwcmVidWlsdFVybFN0cmluZyAoMSk6ICIrYmFzZSk7Ci0gICAgICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoYmFzZSwgIlxcLyIpOwotICAgICAgICAgIFN0cmluZyBmaXhlZEJhc2UgPSBudWxsOwotICAgICAgICAgIHdoaWxlKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgaWYgKG51bGwgPT0gZml4ZWRCYXNlKSAKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLy8gVGhhbmtzIHRvIFJpY2sgTWFkZHkgZm9yIHRoZSBidWcgZml4IGZvciBVTklYIGhlcmUuCi0gICAgICAgICAgICAgIGlmIChiYXNlLmNoYXJBdCgwKSA9PSAnXFwnIHx8IGJhc2UuY2hhckF0KDApID09ICcvJykgCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmaXhlZEJhc2UgPSBGaWxlLnNlcGFyYXRvciArIHRva2VuOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGVsc2UgCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmaXhlZEJhc2UgPSB0b2tlbjsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSAKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZml4ZWRCYXNlKz0gRmlsZS5zZXBhcmF0b3IgKyB0b2tlbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJyZWJ1aWx0VXJsU3RyaW5nICgxKTogIitmaXhlZEJhc2UpOwotICAgICAgICAgIGYgPSBuZXcgRmlsZShmaXhlZEJhc2UpOwotICAgICAgICAgIFN0cmluZyBkaXIgPSBmLmlzRGlyZWN0b3J5KCkgPyBmLmdldEFic29sdXRlUGF0aCgpIDogZi5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImRpcjogIitkaXIpOwotICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigidXJsU3RyaW5nOiAiK3VybFN0cmluZyk7Ci0gICAgICAgICAgLy8gZiA9IG5ldyBGaWxlKGRpciwgdXJsU3RyaW5nKTsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImYgKDEpOiAiK2YudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgLy8gdXJsU3RyaW5nID0gZi5nZXRBYnNvbHV0ZVBhdGgoKTsKLSAgICAgICAgICBmID0gbmV3IEZpbGUodXJsU3RyaW5nKTsgCi0gICAgICAgICAgYm9vbGVhbiBpc0Fic29sdXRlID0gIGYuaXNBYnNvbHV0ZSgpIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAodXJsU3RyaW5nLmNoYXJBdCggMCApID09ICdcXCcpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh1cmxTdHJpbmcuY2hhckF0KCAwICkgPT0gJy8nKTsKLSAgICAgICAgICBpZighaXNBYnNvbHV0ZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBHZXR0aW5nIG1vcmUgYW5kIG1vcmUgdWdseS4uLgotICAgICAgICAgICAgaWYoZGlyLmNoYXJBdCggZGlyLmxlbmd0aCgpLTEgKSAhPSBGaWxlLnNlcGFyYXRvci5jaGFyQXQoMCkgJiYgCi0gICAgICAgICAgICAgICB1cmxTdHJpbmcuY2hhckF0KCAwICkgIT0gRmlsZS5zZXBhcmF0b3IuY2hhckF0KDApKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB1cmxTdHJpbmcgPSBkaXIgKyBGaWxlLnNlcGFyYXRvciArIHVybFN0cmluZzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdXJsU3RyaW5nID0gZGlyICsgdXJsU3RyaW5nOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInByZWJ1aWx0VXJsU3RyaW5nICgyKTogIit1cmxTdHJpbmcpOwotICAgICAgICAgICAgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih1cmxTdHJpbmcsICJcXC8iKTsKLSAgICAgICAgICAgIFN0cmluZyByZWJ1aWx0VXJsU3RyaW5nID0gbnVsbDsKLSAgICAgICAgICAgIHdoaWxlKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN0cmluZyB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgaWYgKG51bGwgPT0gcmVidWlsdFVybFN0cmluZykgCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBUaGFua3MgdG8gUmljayBNYWRkeSBmb3IgdGhlIGJ1ZyBmaXggZm9yIFVOSVggaGVyZS4KLSAgICAgICAgICAgICAgICBpZiAodXJsU3RyaW5nLmNoYXJBdCgwKSA9PSAnXFwnIHx8IHVybFN0cmluZy5jaGFyQXQoMCkgPT0gJy8nKSAKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICByZWJ1aWx0VXJsU3RyaW5nID0gRmlsZS5zZXBhcmF0b3IgKyB0b2tlbjsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSAKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICByZWJ1aWx0VXJsU3RyaW5nID0gdG9rZW47Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGVsc2UgCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZWJ1aWx0VXJsU3RyaW5nKz0gRmlsZS5zZXBhcmF0b3IgKyB0b2tlbjsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJyZWJ1aWx0VXJsU3RyaW5nICgyKTogIityZWJ1aWx0VXJsU3RyaW5nKTsKLSAgICAgICAgICAgIGlmKG51bGwgIT0gcmVidWlsdFVybFN0cmluZykKLSAgICAgICAgICAgICAgdXJsU3RyaW5nID0gcmVidWlsdFVybFN0cmluZzsKLSAgICAgICAgICB9Ci0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJmaWxlU3RhcnRUeXBlOiAiK2ZpbGVTdGFydFR5cGUpOwotICAgICAgICAgIGlmKDEgPT0gZmlsZVN0YXJ0VHlwZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAodXJsU3RyaW5nLmNoYXJBdCgwKSA9PSAnLycpIAotICAgICAgICAgICAgewotICAgICAgICAgICAgICB1cmxTdHJpbmcgPSAiZmlsZTovLyIrdXJsU3RyaW5nOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB1cmxTdHJpbmcgPSAiZmlsZTovIit1cmxTdHJpbmc7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYoMiA9PSBmaWxlU3RhcnRUeXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHVybFN0cmluZyA9ICJmaWxlOiIrdXJsU3RyaW5nOwotICAgICAgICAgIH0KLSAgICAgICAgICB0cnkgCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGaW5hbCBiZWZvcmUgdHJ5OiAiK3VybFN0cmluZyk7Ci0gICAgICAgICAgICB1cmwgPSBuZXcgVVJMKHVybFN0cmluZyk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciB0cnlpbmcgdG8gbWFrZSBVUkwgZnJvbSAiK3VybFN0cmluZyk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBpZihudWxsID09IHVybCkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhlIHN1biBqYXZhIFZNIGRvZXNuJ3QgZG8gdGhpcyBjb3JyZWN0bHksIGJ1dCBJJ2xsIAotICAgICAgICAvLyB0cnkgaXQgaGVyZSBhcyBhIHNlY29uZC10by1sYXN0IHJlc29ydC4KLSAgICAgICAgaWYoKG51bGwgIT0gb3JpZ0Jhc2UpICYmIChvcmlnQmFzZS5sZW5ndGgoKSA+IDApKQotICAgICAgICB7Ci0gICAgICAgICAgdHJ5IAotICAgICAgICAgIHsKLSAgICAgICAgICAgIFVSTCBiYXNlVVJMID0gbmV3IFVSTChvcmlnQmFzZSk7Ci0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlRyeWluZyB0byBtYWtlIFVSTCBmcm9tICIrb3JpZ0Jhc2UrIiBhbmQgIitvcmlnVVJMU3RyaW5nKTsKLSAgICAgICAgICAgIHVybCA9IG5ldyBVUkwoYmFzZVVSTCwgb3JpZ1VSTFN0cmluZyk7Ci0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlN1Y2Nlc3MhIE5ldyBVUkwgaXM6ICIrdXJsLnRvU3RyaW5nKCkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIAotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRXJyb3IgdHJ5aW5nIHRvIG1ha2UgVVJMIGZyb20gIitvcmlnQmFzZSsiIGFuZCAiK29yaWdVUkxTdHJpbmcpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAKLSAgICAgICAgaWYobnVsbCA9PSB1cmwpCi0gICAgICAgIHsKLSAgICAgICAgICB0cnkgCi0gICAgICAgICAgewotICAgICAgICAgICAgU3RyaW5nIGxhc3RQYXJ0OwotICAgICAgICAgICAgaWYobnVsbCAhPSBvcmlnQmFzZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgRmlsZSBiYXNlRmlsZSA9IG5ldyBGaWxlKG9yaWdCYXNlKTsKLSAgICAgICAgICAgICAgaWYoYmFzZUZpbGUuaXNEaXJlY3RvcnkoKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGxhc3RQYXJ0ID0gbmV3IEZpbGUoYmFzZUZpbGUsIHVybFN0cmluZykuZ2V0QWJzb2x1dGVQYXRoICgpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFN0cmluZyBwYXJlbnREaXIgPSBiYXNlRmlsZS5nZXRQYXJlbnQoKTsKLSAgICAgICAgICAgICAgICBsYXN0UGFydCA9IG5ldyBGaWxlKHBhcmVudERpciwgdXJsU3RyaW5nKS5nZXRBYnNvbHV0ZVBhdGggKCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgbGFzdFBhcnQgPSBuZXcgRmlsZSAodXJsU3RyaW5nKS5nZXRBYnNvbHV0ZVBhdGggKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAvLyBIYWNrCi0gICAgICAgICAgICAvLyBpZigobGFzdFBhcnQuY2hhckF0KDApID09ICcvJykgJiYgKGxhc3RQYXJ0LmNoYXJBdCgyKSA9PSAnOicpKQotICAgICAgICAgICAgLy8gICBsYXN0UGFydCA9IGxhc3RQYXJ0LnN1YnN0cmluZygxLCBsYXN0UGFydC5sZW5ndGgoKSAtIDEpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICBTdHJpbmcgZnVsbHBhdGg7Ci0gICAgICAgICAgICBpZiAobGFzdFBhcnQuY2hhckF0KDApID09ICdcXCcgfHwgbGFzdFBhcnQuY2hhckF0KDApID09ICcvJykgCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGZ1bGxwYXRoID0gImZpbGU6Ly8iICsgbGFzdFBhcnQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGZ1bGxwYXRoID0gImZpbGU6IiArIGxhc3RQYXJ0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdXJsID0gbmV3IFVSTChmdWxscGF0aCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZTIpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbigiQ2Fubm90IGNyZWF0ZSB1cmwgZm9yOiAiICsgdXJsU3RyaW5nLCBlMiApOyAKLSAgICAgICAgICAgICAgLy9YU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfQ1JFQVRFX1VSTCwgbmV3IE9iamVjdFtde3VybFN0cmluZ30pLGUyKTsgLy8iQ2Fubm90IGNyZWF0ZSB1cmwgZm9yOiAiICsgdXJsU3RyaW5nLCBlMiApOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChTZWN1cml0eUV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgdXJsID0gbmV3IFVSTCgiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQvIitqYXZhLmxhbmcuTWF0aC5yYW5kb20oKSk7IC8vIGR1bW15Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUyKQotICAgICAgewotICAgICAgICAvLyBJIGdpdmUgdXAKLSAgICAgIH0KLSAgICB9Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJ1cmw6ICIrdXJsLnRvU3RyaW5nKCkpOwotICAgIHJldHVybiB1cmw7Ci0gIH0KLQotICAgLyoqCi0gICAqIEFkZCBhIHRyYWNlIGxpc3RlbmVyIGZvciB0aGUgcHVycG9zZXMgb2YgZGVidWdnaW5nIGFuZCBkaWFnbm9zaXMuCi0gICAqIEBwYXJhbSB0bCBUcmFjZSBsaXN0ZW5lciB0byBiZSBhZGRlZC4KLSAgICovCi0gIHZvaWQgYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8qdHJ5Ci0gICAgewotICAgICAgVHJhY2VNYW5hZ2VyIHRtID0gbV90cmFuc2Zvcm1lckltcGwuZ2V0VHJhY2VNYW5hZ2VyKCk7Ci0gICAgICBpZih0bS5oYXNUcmFjZUxpc3RlbmVycykKLSAgICAgIHsKLSAgICAgICAgaW50IG5MaXN0ZW5lcnMgPSB0bS5zaXplKCk7Ci0gICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuTGlzdGVuZXJzOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBUcmFjZUxpc3RlbmVyIHRsID0gKFRyYWNlTGlzdGVuZXIpbV90cmFjZUxpc3RlbmVycy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgaWYobnVsbCAhPSBtX3N0eWxlc2hlZXRSb290KQotICAgICAgICAgICAgbV9zdHlsZXNoZWV0Um9vdC5hZGRUcmFjZUxpc3RlbmVyKHRsKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIHRtbGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9UT09fTUFOWV9MSVNURU5FUlMsIG51bGwpLHRtbGUgKTsgLy8iYWRkVHJhY2VMaXN0ZW5lcnNUb1N0eWxlc2hlZXQgLSBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uIiwgdG1sZSk7Ci0gICAgfSovCi0gIH0KLSAgCi0gIC8qKgotICAgKiBXYXJuIHRoZSB1c2VyIG9mIGFuIHByb2JsZW0uCi0gICAqIFRoaXMgaXMgcHVibGljIGZvciBhY2Nlc3MgYnkgZXh0ZW5zaW9ucy4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgbWVzc2FnZShTdHJpbmcgbXNnKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIG1lc3NhZ2UobnVsbCwgbnVsbCwgbXNnKTsKLSAgfQotCi0KLQotICAvKioKLSAgICogV2FybiB0aGUgdXNlciBvZiBhbiBwcm9ibGVtLgotICAgKiBUaGlzIGlzIHB1YmxpYyBmb3IgYWNjZXNzIGJ5IGV4dGVuc2lvbnMuCi0gICAqIEBleGNlcHRpb24gWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWE1MUGFyc2VyTGlhaXNvbiBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIG1lc3NhZ2UoTm9kZSBzdHlsZU5vZGUsIE5vZGUgc291cmNlTm9kZSwgU3RyaW5nIG1zZykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX3Byb2JsZW1MaXN0ZW5lci5tZXNzYWdlKG1zZyk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYW4gcHJvYmxlbS4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybihpbnQgbXNnKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHdhcm4obnVsbCwgbnVsbCwgbXNnLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogV2FybiB0aGUgdXNlciBvZiBhbiBwcm9ibGVtLgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuKGludCBtc2csIE9iamVjdFtdIGFyZ3MpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgd2FybihudWxsLCBudWxsLCBtc2csIGFyZ3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBXYXJuIHRoZSB1c2VyIG9mIGFuIHByb2JsZW0uCi0gICAqIEBleGNlcHRpb24gWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWE1MUGFyc2VyTGlhaXNvbiBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm4oTm9kZSBzdHlsZU5vZGUsIE5vZGUgc291cmNlTm9kZSwgaW50IG1zZykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB3YXJuKHN0eWxlTm9kZSwgc291cmNlTm9kZSwgbXNnLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogV2FybiB0aGUgdXNlciBvZiBhbiBwcm9ibGVtLgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuKE5vZGUgc3R5bGVOb2RlLCBOb2RlIHNvdXJjZU5vZGUsIGludCBtc2csIE9iamVjdCBhcmdzW10pCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgRXhjZXB0aW9uIGUgPSBudWxsOwotICAgIFN0cmluZyBmbXNnID0gbV9YU0xNZXNzYWdlcy5jcmVhdGVXYXJuaW5nKG1zZywgYXJncyk7Ci0gICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gbnVsbDsKLSAgICB0cnl7Ci0gICAgIGxvY2F0b3IgPSAoKFN0eWxlc2hlZXRIYW5kbGVyKSgoKFRyYW5zZm9ybWVyRmFjdG9yeUltcGwpdGhpcy5tX3RmYWN0b3J5KS5uZXdUZW1wbGF0ZXNIYW5kbGVyKCkpKS5nZXRMb2NhdG9yKCk7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGNlKQotICAgIHsKLSAgICB9Ci0gICAgCi0gICAgRGVmYXVsdEVycm9ySGFuZGxlciBoYW5kbGVyOwotICAgIGlmIChtX3Byb2JsZW1MaXN0ZW5lciA9PSBudWxsKQotICAgICAgaGFuZGxlciA9IChEZWZhdWx0RXJyb3JIYW5kbGVyKW1fdGZhY3RvcnkuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgIGVsc2UKLSAgICAgIGhhbmRsZXIgPSAoRGVmYXVsdEVycm9ySGFuZGxlciltX3Byb2JsZW1MaXN0ZW5lci5nZXRFcnJvckhhbmRsZXIoKTsKLSAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSA9IChudWxsID09IGUpID8gbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIGxvY2F0b3IpIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLCBsb2NhdG9yLCBlKTsKLSAgICBpZihudWxsICE9IGhhbmRsZXIpCi0gICAgewotICAgICAgdHJ5ewotICAgICAgaGFuZGxlci53YXJuaW5nKHRlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZTIpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUyKTsKLSAgICAgIH0gCi0gICAgfQotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgbXNnKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIEV4Y2VwdGlvbiBlID0gbnVsbDsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBudWxsOwotICAgIHRyeXsKLSAgICBsb2NhdG9yID0gKChTdHlsZXNoZWV0SGFuZGxlcikoKChUcmFuc2Zvcm1lckZhY3RvcnlJbXBsKXRoaXMubV90ZmFjdG9yeSkubmV3VGVtcGxhdGVzSGFuZGxlcigpKSkuZ2V0TG9jYXRvcigpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICB7Ci0gICAgfQotICAgIERlZmF1bHRFcnJvckhhbmRsZXIgaGFuZGxlcjsKLSAgICBpZiAobV9wcm9ibGVtTGlzdGVuZXIgPT0gbnVsbCkKLSAgICAgIGhhbmRsZXIgPSAoRGVmYXVsdEVycm9ySGFuZGxlciltX3RmYWN0b3J5LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICBlbHNlCi0gICAgICBoYW5kbGVyID0gKERlZmF1bHRFcnJvckhhbmRsZXIpbV9wcm9ibGVtTGlzdGVuZXIuZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUgPSAobnVsbCA9PSBlKSA/IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIGxvY2F0b3IpIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIGxvY2F0b3IsIGUpOwotICAgIGlmKG51bGwgIT0gaGFuZGxlcikKLSAgICB7ICAKLSAgICAgIHRyeXsKLSAgICAgIGhhbmRsZXIuZmF0YWxFcnJvcih0ZSk7Ci0gICAgfQotICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlMikKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0ZTIpOwotICAgICAgfSAKLSAgICB9Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0ZSk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqIEBleGNlcHRpb24gWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWE1MUGFyc2VyTGlhaXNvbiBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKGludCBtc2cpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3IobnVsbCwgbnVsbCwgbXNnLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoaW50IG1zZywgT2JqZWN0W10gYXJncykKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihudWxsLCBudWxsLCBtc2csIGFyZ3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihpbnQgbXNnLCBFeGNlcHRpb24gZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihtc2csIG51bGwsIGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihpbnQgbXNnLCBPYmplY3QgYXJnc1tdLCBFeGNlcHRpb24gZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBTdHJpbmcgZm1zZyA9IG1fWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShtc2csIGFyZ3MpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9IG51bGw7Ci0gICAgdHJ5ewotICAgICAgbG9jYXRvciA9ICgoU3R5bGVzaGVldEhhbmRsZXIpKCgoVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCl0aGlzLm1fdGZhY3RvcnkpLm5ld1RlbXBsYXRlc0hhbmRsZXIoKSkpLmdldExvY2F0b3IoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB0Y2UpCi0gICAgewotICAgIH0KLSAgICBEZWZhdWx0RXJyb3JIYW5kbGVyIGhhbmRsZXI7Ci0gICAgaWYgKG1fcHJvYmxlbUxpc3RlbmVyID09IG51bGwpCi0gICAgICBoYW5kbGVyID0gKERlZmF1bHRFcnJvckhhbmRsZXIpbV90ZmFjdG9yeS5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgZWxzZQotICAgICAgaGFuZGxlciA9IChEZWZhdWx0RXJyb3JIYW5kbGVyKW1fcHJvYmxlbUxpc3RlbmVyLmdldEVycm9ySGFuZGxlcigpOwotICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlID0gKG51bGwgPT0gZSkgPyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm1zZywgbG9jYXRvcikgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIGxvY2F0b3IsIGUpOwotICAgIGlmKG51bGwgIT0gaGFuZGxlcikKLSAgICB7Ci0gICAgICB0cnl7Ci0gICAgICBoYW5kbGVyLmZhdGFsRXJyb3IodGUpOwotICAgIH0KLSAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZTIpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUyKTsKLSAgICAgIH0gCi0gICAgfQotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUpOwotICB9Ci0KLSAgLyoqCi0gICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKiBAZXhjZXB0aW9uIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhNTFBhcnNlckxpYWlzb24gZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihOb2RlIHN0eWxlTm9kZSwgTm9kZSBzb3VyY2VOb2RlLCBpbnQgbXNnKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGVycm9yKHN0eWxlTm9kZSwgc291cmNlTm9kZSwgbXNnLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoTm9kZSBzdHlsZU5vZGUsIE5vZGUgc291cmNlTm9kZSwgaW50IG1zZywgT2JqZWN0IGFyZ3NbXSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBFeGNlcHRpb24gZSA9IG51bGw7Ci0gICAgU3RyaW5nIGZtc2cgPSBtX1hTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UobXNnLCBhcmdzKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBudWxsOwotICAgIHRyeXsKLSAgICAgbG9jYXRvciA9ICgoU3R5bGVzaGVldEhhbmRsZXIpKCgoVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCl0aGlzLm1fdGZhY3RvcnkpLm5ld1RlbXBsYXRlc0hhbmRsZXIoKSkpLmdldExvY2F0b3IoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB0Y2UpCi0gICAgewotICAgIH0KLSAgICBEZWZhdWx0RXJyb3JIYW5kbGVyIGhhbmRsZXI7Ci0gICAgaWYgKG1fcHJvYmxlbUxpc3RlbmVyID09IG51bGwpCi0gICAgICBoYW5kbGVyID0gKERlZmF1bHRFcnJvckhhbmRsZXIpbV90ZmFjdG9yeS5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgZWxzZQotICAgICAgaGFuZGxlciA9IChEZWZhdWx0RXJyb3JIYW5kbGVyKW1fcHJvYmxlbUxpc3RlbmVyLmdldEVycm9ySGFuZGxlcigpOwotICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlID0gKG51bGwgPT0gZSkgPyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm1zZywgbG9jYXRvcikgOgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIGxvY2F0b3IsIGUpOwotICAgIGlmKG51bGwgIT0gaGFuZGxlcikKLSAgICB7ICAKLSAgICAgIHRyeXsKLSAgICAgICBoYW5kbGVyLmZhdGFsRXJyb3IodGUpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlMikKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0ZTIpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKHRlKTsKLSAgICAKLSAgIAotICB9Ci0gIAotICAvKioKLSAgICogTWFyayB0aGUgdGltZSwgc28gdGhhdCBkaXNwbGF5RHVyYXRpb24gY2FuIGxhdGVyCi0gICAqIGRpc3BsYXkgdGhlIGVsYXBzZS4KLSAgICovCi0gIHZvaWQgcHVzaFRpbWUoT2JqZWN0IGtleSkKLSAgewotICAgIGlmKG51bGwgIT0ga2V5KQotICAgIHsKLSAgICAgIG1fZHVyYXRpb25zVGFibGUucHV0KGtleSwgbmV3IExvbmcoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgZHVyYXRpb24gc2luY2UgcHVzaFRpbWUgd2FzIGNhbGxlZCwKLSAgICogaW4gbWlsbGlzZWNvbmRzLgotICAgKi8KLSAgbG9uZyBwb3BEdXJhdGlvbihPYmplY3Qga2V5KQotICB7Ci0gICAgbG9uZyBtaWxsaXNlY29uZHNEdXJhdGlvbiA9IDA7Ci0gICAgaWYobnVsbCAhPSBrZXkpCi0gICAgewotICAgICAgbG9uZyBzdGFydCA9ICgoTG9uZyltX2R1cmF0aW9uc1RhYmxlLmdldChrZXkpKS5sb25nVmFsdWUoKTsKLSAgICAgIGxvbmcgc3RvcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotICAgICAgbWlsbGlzZWNvbmRzRHVyYXRpb24gPSBzdG9wIC0gc3RhcnQ7Ci0gICAgICBtX2R1cmF0aW9uc1RhYmxlLnJlbW92ZShrZXkpOwotICAgIH0KLSAgICByZXR1cm4gbWlsbGlzZWNvbmRzRHVyYXRpb247Ci0gIH0KLSAgCi0gICAvKioKLSAgICogRGlzcGxheSB0aGUgZHVyYXRpb24gc2luY2UgcHVzaFRpbWUgd2FzIGNhbGxlZC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGRpc3BsYXlEdXJhdGlvbihTdHJpbmcgaW5mbywgT2JqZWN0IGtleSkKLSAgewotICAgIGxvbmcgbWlsbGlzZWNvbmRzRHVyYXRpb24gPSAwOwotICAgIGlmKG51bGwgIT0ga2V5KQotICAgIHsKLSAgICAgIGxvbmcgc3RhcnQgPSAoKExvbmcpbV9kdXJhdGlvbnNUYWJsZS5nZXQoa2V5KSkubG9uZ1ZhbHVlKCk7Ci0gICAgICBsb25nIHN0b3AgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgIG1pbGxpc2Vjb25kc0R1cmF0aW9uID0gc3RvcCAtIHN0YXJ0OwotICAgICAgaWYobnVsbCAhPSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIpCi0gICAgICB7Ci0gICAgICAgIG1fZGlhZ25vc3RpY3NQcmludFdyaXRlci5wcmludGxuKGluZm8gKyAiIHRvb2sgIiArIG1pbGxpc2Vjb25kc0R1cmF0aW9uICsgIiBtaWxsaXNlY29uZHMiKTsKLSAgICAgIH0KLSAgICAgIG1fZHVyYXRpb25zVGFibGUucmVtb3ZlKGtleSk7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogSWYgdGhpcyBpcyBzZXQsIGRpYWdub3N0aWNzIHdpbGwgYmUKLSAgICogd3JpdHRlbiB0byB0aGUgbV9kaWFnbm9zdGljc1ByaW50V3JpdGVyIHN0cmVhbS4gSWYKLSAgICogdGhlIHZhbHVlIGlzIG51bGwsIHRoZW4gZGlhZ25vc3RpY3Mgd2lsbCBiZSB0dXJuZWQKLSAgICogb2ZmLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RGlhZ25vc3RpY3NPdXRwdXQoamF2YS5pby5PdXRwdXRTdHJlYW0gb3V0KQotICB7Ci0gICAgc2V0RGlhZ25vc3RpY3NPdXRwdXQobmV3IFByaW50V3JpdGVyKG91dCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIHRoaXMgaXMgc2V0LCBkaWFnbm9zdGljcyB3aWxsIGJlCi0gICAqIHdyaXR0ZW4gdG8gdGhlIG1fZGlhZ25vc3RpY3NQcmludFdyaXRlciBzdHJlYW0uIElmCi0gICAqIHRoZSB2YWx1ZSBpcyBudWxsLCB0aGVuIGRpYWdub3N0aWNzIHdpbGwgYmUgdHVybmVkCi0gICAqIG9mZi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERpYWdub3N0aWNzT3V0cHV0KGphdmEuaW8uUHJpbnRXcml0ZXIgcHcpCi0gIHsKLSAgICBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIgPSBwdzsKLSAgIC8qIGlmKGdldFByb2JsZW1MaXN0ZW5lcigpIGluc3RhbmNlb2YgUHJvYmxlbUxpc3RlbmVyRGVmYXVsdCkKLSAgICB7Ci0gICAgICAoKFByb2JsZW1MaXN0ZW5lckRlZmF1bHQpZ2V0UHJvYmxlbUxpc3RlbmVyKCkpLnNldERpYWdub3N0aWNzT3V0cHV0KHB3KTsKLSAgICB9Ki8KLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIG91dHB1dCBvZiBkaWFnbm9zdGljcy4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGRpYWcoU3RyaW5nIHMpCi0gIHsKLSAgICBpZihudWxsICE9IG1fZGlhZ25vc3RpY3NQcmludFdyaXRlcikKLSAgICB7Ci0gICAgICBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIucHJpbnRsbihzKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhpcyBpcyBzZXQgdG8gdHJ1ZSwgc2ltcGxlIHRyYWNlcyBvZgotICAgKiB0ZW1wbGF0ZSBjYWxscyBhcmUgbWFkZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRyYWNlVGVtcGxhdGVzKGJvb2xlYW4gYikKLSAgewotICAgIG1fdHJhY2VUZW1wbGF0ZXMgPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIHRoaXMgaXMgc2V0IHRvIHRydWUsIHNpbXBsZSB0cmFjZXMgb2YKLSAgICogdGVtcGxhdGUgY2FsbHMgYXJlIG1hZGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUcmFjZVNlbGVjdChib29sZWFuIGIpCi0gIHsKLSAgICBtX3RyYWNlU2VsZWN0cyA9IGI7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhpcyBpcyBzZXQgdG8gdHJ1ZSwgZGVidWcgZGlhZ25vc3RpY3MgYWJvdXQKLSAgICogdGVtcGxhdGUgY2hpbGRyZW4gYXMgdGhleSBhcmUgYmVpbmcgY29uc3RydWN0ZWQKLSAgICogd2lsbCBiZSB3cml0dGVuIHRvIHRoZSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIKLSAgICogc3RyZWFtLiAgZGlhZ25vc2VUZW1wbGF0ZUNoaWxkcmVuIGlzIGZhbHNlIGJ5Ci0gICAqIGRlZmF1bHQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUcmFjZVRlbXBsYXRlQ2hpbGRyZW4oYm9vbGVhbiBiKQotICB7Ci0gICAgbV90cmFjZVRlbXBsYXRlQ2hpbGRyZW4gPSBiOwotICB9Ci0gIAotICAvLwotICAvLyBMZXhpY2FsIGhhbmRsZXIgaW50ZXJmYWNlCi0gIC8vCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIHN0YXJ0IG9mIERURCBkZWNsYXJhdGlvbnMsIGlmIGFueS4KLSAgICAgKgotICAgICAqIDxwPkFueSBkZWNsYXJhdGlvbnMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gdGhlIGludGVybmFsIHN1YnNldAotICAgICAqIHVubGVzcyBvdGhlcndpc2UgaW5kaWNhdGVkIGJ5IGEge0BsaW5rICNzdGFydEVudGl0eSBzdGFydEVudGl0eX0KLSAgICAgKiBldmVudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgdGhlIHN0YXJ0L2VuZERURCBldmVudHMgd2lsbCBhcHBlYXIgd2l0aGluCi0gICAgICogdGhlIHN0YXJ0L2VuZERvY3VtZW50IGV2ZW50cyBmcm9tIENvbnRlbnRIYW5kbGVyIGFuZAotICAgICAqIGJlZm9yZSB0aGUgZmlyc3Qgc3RhcnRFbGVtZW50IGV2ZW50LjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBkb2N1bWVudCB0eXBlIG5hbWUuCi0gICAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBkZWNsYXJlZCBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlCi0gICAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBkZWNsYXJlZCBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlCi0gICAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbgotICAgICAqICAgICAgICAgICAgZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI2VuZERURAotICAgICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwgJiYgbV90cmFuc2Zvcm1lckltcGwuZ2V0SW5wdXRMZXhpY2FsSGFuZGxlcigpICE9IG51bGwpCi0gICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0TGV4aWNhbEhhbmRsZXIoKS5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBlbmQgb2YgRFREIGRlY2xhcmF0aW9ucy4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI3N0YXJ0RFRECi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRFREICgpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsICYmIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0TGV4aWNhbEhhbmRsZXIoKSAhPSBudWxsKQotICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dExleGljYWxIYW5kbGVyKCkuZW5kRFREKCk7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5IChTdHJpbmcgbmFtZSkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwgJiYgbV90cmFuc2Zvcm1lckltcGwuZ2V0SW5wdXRMZXhpY2FsSGFuZGxlcigpICE9IG51bGwpCi0gICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0TGV4aWNhbEhhbmRsZXIoKS5zdGFydEVudGl0eSAobmFtZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5IHRoYXQgaXMgZW5kaW5nLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRW50aXR5IChTdHJpbmcgbmFtZSkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgICB7Ci0gICAgICBpZiAobV90cmFuc2Zvcm1lckltcGwgIT0gbnVsbCAmJiBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dExleGljYWxIYW5kbGVyKCkgIT0gbnVsbCkKLSAgICAgICAgbV90cmFuc2Zvcm1lckltcGwuZ2V0SW5wdXRMZXhpY2FsSGFuZGxlcigpLmVuZEVudGl0eSAobmFtZSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgdGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoZSBjb250ZW50cyBvZiB0aGUgQ0RBVEEgc2VjdGlvbiB3aWxsIGJlIHJlcG9ydGVkIHRocm91Z2gKLSAgICAgKiB0aGUgcmVndWxhciB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycwotICAgICAqIGNoYXJhY3RlcnN9IGV2ZW50LjwvcD4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqIEBzZWUgI2VuZENEQVRBCi0gICAgICovCi0gICAgcHVibGljICB2b2lkIHN0YXJ0Q0RBVEEgKCkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgeyAKLSAgICAgIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsICYmIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0TGV4aWNhbEhhbmRsZXIoKSAhPSBudWxsKQotICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dExleGljYWxIYW5kbGVyKCkuc3RhcnRDREFUQSgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmVwb3J0IHRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgICAqCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjc3RhcnRDREFUQQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZENEQVRBICgpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsICYmIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0TGV4aWNhbEhhbmRsZXIoKSAhPSBudWxsKQotICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dExleGljYWxIYW5kbGVyKCkuZW5kQ0RBVEEoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNhbGxiYWNrIHdpbGwgYmUgdXNlZCBmb3IgY29tbWVudHMgaW5zaWRlIG9yIG91dHNpZGUgdGhlCi0gICAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKLSAgICAgKiBzdWJzZXQgKGlmIHJlYWQpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaCBBbiBhcnJheSBob2xkaW5nIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBjb21tZW50LgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLSAgICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgIHZvaWQgY29tbWVudCAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgICAgewotICAgICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwgJiYgbV90cmFuc2Zvcm1lckltcGwuZ2V0SW5wdXRMZXhpY2FsSGFuZGxlcigpICE9IG51bGwpCi0gICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0TGV4aWNhbEhhbmRsZXIoKS5jb21tZW50IChjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICAgIAotICAgIC8vIERvY3VtZW50SGFuZGxlciBpbnRlcmZhY2UKLSAgICAKLSAgICAgICAgLyoqCi0gICAgICogUmVjZWl2ZSBhbiBvYmplY3QgZm9yIGxvY2F0aW5nIHRoZSBvcmlnaW4gb2YgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICAgKgotICAgICAqIDxwPlNBWCBwYXJzZXJzIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkICh0aG91Z2ggbm90IGFic29sdXRlbHkKLSAgICAgKiByZXF1aXJlZCkgdG8gc3VwcGx5IGEgbG9jYXRvcjogaWYgaXQgZG9lcyBzbywgaXQgbXVzdCBzdXBwbHkKLSAgICAgKiB0aGUgbG9jYXRvciB0byB0aGUgYXBwbGljYXRpb24gYnkgaW52b2tpbmcgdGhpcyBtZXRob2QgYmVmb3JlCi0gICAgICogaW52b2tpbmcgYW55IG9mIHRoZSBvdGhlciBtZXRob2RzIGluIHRoZSBEb2N1bWVudEhhbmRsZXIKLSAgICAgKiBpbnRlcmZhY2UuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGxvY2F0b3IgYWxsb3dzIHRoZSBhcHBsaWNhdGlvbiB0byBkZXRlcm1pbmUgdGhlIGVuZAotICAgICAqIHBvc2l0aW9uIG9mIGFueSBkb2N1bWVudC1yZWxhdGVkIGV2ZW50LCBldmVuIGlmIHRoZSBwYXJzZXIgaXMKLSAgICAgKiBub3QgcmVwb3J0aW5nIGFuIGVycm9yLiAgVHlwaWNhbGx5LCB0aGUgYXBwbGljYXRpb24gd2lsbAotICAgICAqIHVzZSB0aGlzIGluZm9ybWF0aW9uIGZvciByZXBvcnRpbmcgaXRzIG93biBlcnJvcnMgKHN1Y2ggYXMKLSAgICAgKiBjaGFyYWN0ZXIgY29udGVudCB0aGF0IGRvZXMgbm90IG1hdGNoIGFuIGFwcGxpY2F0aW9uJ3MKLSAgICAgKiBidXNpbmVzcyBydWxlcykuICBUaGUgaW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgdGhlIGxvY2F0b3IKLSAgICAgKiBpcyBwcm9iYWJseSBub3Qgc3VmZmljaWVudCBmb3IgdXNlIHdpdGggYSBzZWFyY2ggZW5naW5lLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgbG9jYXRvciB3aWxsIHJldHVybiBjb3JyZWN0IGluZm9ybWF0aW9uIG9ubHkKLSAgICAgKiBkdXJpbmcgdGhlIGludm9jYXRpb24gb2YgdGhlIGV2ZW50cyBpbiB0aGlzIGludGVyZmFjZS4gIFRoZQotICAgICAqIGFwcGxpY2F0aW9uIHNob3VsZCBub3QgYXR0ZW1wdCB0byB1c2UgaXQgYXQgYW55IG90aGVyIHRpbWUuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGxvY2F0b3IgQW4gb2JqZWN0IHRoYXQgY2FuIHJldHVybiB0aGUgbG9jYXRpb24gb2YKLSAgICAgKiAgICAgICAgICAgICAgICBhbnkgU0FYIGRvY3VtZW50IGV2ZW50LgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvciAoTG9jYXRvciBsb2NhdG9yKQotICAgIHt9Ci0gICAgCi0gICAgCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBiZWZvcmUgYW55Ci0gICAgICogb3RoZXIgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSBvciBpbiBEVERIYW5kbGVyIChleGNlcHQgZm9yCi0gICAgICogc2V0RG9jdW1lbnRMb2NhdG9yKS48L3A+Ci0gICAgICoKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQgKCkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgaWYgKG1fZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgIG1fZG9jdW1lbnRIYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgIGVsc2UgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0Q29udGVudEhhbmRsZXIoKS5zdGFydERvY3VtZW50KCk7Ci0gICAgICAvL21fdHJhbnNmb3JtZXJJbXBsLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkuc3RhcnREb2N1bWVudCgpOwotICAgICAgCi0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICAgKgotICAgICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9ubHkgb25jZSwgYW5kIGl0IHdpbGwKLSAgICAgKiBiZSB0aGUgbGFzdCBtZXRob2QgaW52b2tlZCBkdXJpbmcgdGhlIHBhcnNlLiAgVGhlIHBhcnNlciBzaGFsbAotICAgICAqIG5vdCBpbnZva2UgdGhpcyBtZXRob2QgdW50aWwgaXQgaGFzIGVpdGhlciBhYmFuZG9uZWQgcGFyc2luZwotICAgICAqIChiZWNhdXNlIG9mIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IpIG9yIHJlYWNoZWQgdGhlIGVuZCBvZgotICAgICAqIGlucHV0LjwvcD4KLSAgICAgKgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQgKCkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgaWYgKG1fZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgIG1fZG9jdW1lbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICBlbHNlIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsKQotICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkuZW5kRG9jdW1lbnQoKTsKLSAgICAgIC8vbV90cmFuc2Zvcm1lckltcGwuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKS5lbmREb2N1bWVudCgpOwotICAgIH0KLSAgICAKLSAgICAKLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBiZWdpbm5pbmcgb2YgZXZlcnkKLSAgICAgKiBlbGVtZW50IGluIHRoZSBYTUwgZG9jdW1lbnQ7IHRoZXJlIHdpbGwgYmUgYSBjb3JyZXNwb25kaW5nCi0gICAgICogZW5kRWxlbWVudCgpIGV2ZW50IGZvciBldmVyeSBzdGFydEVsZW1lbnQoKSBldmVudCAoZXZlbiB3aGVuIHRoZQotICAgICAqIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKLSAgICAgKiByZXBvcnRlZCwgaW4gb3JkZXIsIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50KCkKLSAgICAgKiBldmVudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5JZiB0aGUgZWxlbWVudCBuYW1lIGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXggd2lsbAotICAgICAqIHN0aWxsIGJlIGF0dGFjaGVkLiAgTm90ZSB0aGF0IHRoZSBhdHRyaWJ1dGUgbGlzdCBwcm92aWRlZCB3aWxsCi0gICAgICogY29udGFpbiBvbmx5IGF0dHJpYnV0ZXMgd2l0aCBleHBsaWNpdCB2YWx1ZXMgKHNwZWNpZmllZCBvcgotICAgICAqIGRlZmF1bHRlZCk6ICNJTVBMSUVEIGF0dHJpYnV0ZXMgd2lsbCBiZSBvbWl0dGVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjZW5kRWxlbWVudAotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdCAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQgKFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVMaXN0IGF0dHMpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChtX2RvY3VtZW50SGFuZGxlciA9PSBudWxsKSAgICAgICAKLSAgICAgIHsgCi0gICAgICAgIG1fZG9jdW1lbnRIYW5kbGVyID0gbmV3IFBhcnNlckFkYXB0ZXIobmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCkpOwotICAgICAgICBpZiAobV90cmFuc2Zvcm1lckltcGwgIT0gbnVsbCkKLSAgICAgICAgeyAgCi0gICAgICAgICAgKChQYXJzZXJBZGFwdGVyKW1fZG9jdW1lbnRIYW5kbGVyKS5zZXRDb250ZW50SGFuZGxlcihtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkpOwotICAgICAgICB9Ci0gICAgICAgIC8qIGVsc2UgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgaW50IGluZGV4ID0gbmFtZS5pbmRleE9mKCI6Iik7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgKQotICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkuc3RhcnRFbGVtZW50KG51bGwsIG5hbWUsIG5hbWUsIChBdHRyaWJ1dGVzKWF0dHMpOwotICAgICAgICAvL2dldFJlc3VsdFRyZWVIYW5kbGVyKCkuc3RhcnRFbGVtZW50KG51bGwsIG5hbWUsIG5hbWUsIChBdHRyaWJ1dGVzKWF0dHMpOwotICAgICAgICBlbHNlCi0gICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0Q29udGVudEhhbmRsZXIoKS5zdGFydEVsZW1lbnQobmFtZS5zdWJzdHJpbmcoMCxpbmRleCksIG5hbWUuc3Vic3RyaW5nKGluZGV4KzEpLCBuYW1lLCAoQXR0cmlidXRlcylhdHRzKTsgICAgICAgIAotICAgICAgICAvL21fdHJhbnNmb3JtZXJJbXBsLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkuc3RhcnRFbGVtZW50KG5hbWUuc3Vic3RyaW5nKDAsaW5kZXgpLCBuYW1lLnN1YnN0cmluZyhpbmRleCsxKSwgbmFtZSwgKEF0dHJpYnV0ZXMpYXR0cyk7Ci0gICAgICAgICovIAotICAgICAgfSAKLSAgICAgIG1fZG9jdW1lbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lLCBhdHRzKTsKLSAgICB9ICAgCi0gICAgCi0gICAgLyoqCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqCi0gICAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGVuZCBvZiBldmVyeQotICAgICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKLSAgICAgKiBzdGFydEVsZW1lbnQoKSBldmVudCBmb3IgZXZlcnkgZW5kRWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCi0gICAgICogZWxlbWVudCBpcyBlbXB0eSkuPC9wPgotICAgICAqCi0gICAgICogPHA+SWYgdGhlIGVsZW1lbnQgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4IHdpbGwKLSAgICAgKiBzdGlsbCBiZSBhdHRhY2hlZCB0byB0aGUgbmFtZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUKLSAgICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQgKFN0cmluZyBuYW1lKQotCXRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICBpZiAobV9kb2N1bWVudEhhbmRsZXIgPT0gbnVsbCkgICAgICAgIAotICAgICAgeyAgICAgICAgIAotICAgICAgICBtX2RvY3VtZW50SGFuZGxlciA9IG5ldyBQYXJzZXJBZGFwdGVyKG5ldyBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcigpKTsKLSAgICAgICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAoKFBhcnNlckFkYXB0ZXIpbV9kb2N1bWVudEhhbmRsZXIpLnNldENvbnRlbnRIYW5kbGVyKG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0Q29udGVudEhhbmRsZXIoKSk7Ci0gICAgICAgIH0KLSAgICAgLyogZWxzZSBpZiAobV90cmFuc2Zvcm1lckltcGwgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgaW50IGluZGV4ID0gbmFtZS5pbmRleE9mKCI6Iik7Ci0gICAgICAgIGlmIChpbmRleCA8IDAgKQotICAgICAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0Q29udGVudEhhbmRsZXIoKS5lbmRFbGVtZW50KG51bGwsIG5hbWUsIG5hbWUpOwotICAgICAgICAgIC8vbV90cmFuc2Zvcm1lckltcGwuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKS5lbmRFbGVtZW50KG51bGwsIG5hbWUsIG5hbWUpOyAgICAgICAgCi0gICAgICAgIGVsc2UKLSAgICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkuZW5kRWxlbWVudChuYW1lLnN1YnN0cmluZygwLGluZGV4KSwgbmFtZS5zdWJzdHJpbmcoaW5kZXgrMSksIG5hbWUpOwotICAgICAgICAgIC8vbV90cmFuc2Zvcm1lckltcGwuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKS5lbmRFbGVtZW50KG5hbWUuc3Vic3RyaW5nKDAsaW5kZXgpLCBuYW1lLnN1YnN0cmluZyhpbmRleCsxKSwgbmFtZSk7Ci0gICAgICAgICovCi0gICAgICB9IAotICAgICAgbV9kb2N1bWVudEhhbmRsZXIuZW5kRWxlbWVudChuYW1lKTsgICAgICAKLSAgICB9ICAgICAKLSAgICAKLSAgICAKLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZwotICAgICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZSAKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgaWYgKG1fZG9jdW1lbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgIG1fZG9jdW1lbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgZWxzZSBpZiAobV90cmFuc2Zvcm1lckltcGwgIT0gbnVsbCkKLSAgICAgIG1fdHJhbnNmb3JtZXJJbXBsLmdldElucHV0Q29udGVudEhhbmRsZXIoKS5jaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgIC8vbV90cmFuc2Zvcm1lckltcGwuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKS5jaGFyYWN0ZXJzKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9ICAKLSAgICAKLSAgICAKLSAgICAvKioKLSAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAgICoKLSAgICAgKiA8cD5WYWxpZGF0aW5nIFBhcnNlcnMgbXVzdCB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsKLSAgICAgKiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSAoc2VlIHRoZSBXM0MgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiwKLSAgICAgKiBzZWN0aW9uIDIuMTApOiBub24tdmFsaWRhdGluZyBwYXJzZXJzIG1heSBhbHNvIHVzZSB0aGlzIG1ldGhvZAotICAgICAqIGlmIHRoZXkgYXJlIGNhcGFibGUgb2YgcGFyc2luZyBhbmQgdXNpbmcgY29udGVudCBtb2RlbHMuPC9wPgotICAgICAqCi0gICAgICogPHA+U0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyB3aGl0ZXNwYWNlIGluIGEgc2luZ2xlCi0gICAgICogY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbCBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZgotICAgICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICAgKiBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IgcHJvdmlkZXMgdXNlZnVsCi0gICAgICogaW5mb3JtYXRpb24uPC9wPgotICAgICAqCi0gICAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAgICogQGV4Y2VwdGlvbiBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAgKiBAc2VlICNjaGFyYWN0ZXJzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZSAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChtX2RvY3VtZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICBtX2RvY3VtZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgIGVsc2UgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAvL21fdHJhbnNmb3JtZXJJbXBsLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBwcm9jZXNzaW5nCi0gICAgICogaW5zdHJ1Y3Rpb24gZm91bmQ6IG5vdGUgdGhhdCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBtYXkgb2NjdXIKLSAgICAgKiBiZWZvcmUgb3IgYWZ0ZXIgdGhlIG1haW4gZG9jdW1lbnQgZWxlbWVudC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5BIFNBWCBwYXJzZXIgc2hvdWxkIG5ldmVyIHJlcG9ydCBhbiBYTUwgZGVjbGFyYXRpb24gKFhNTCAxLjAsCi0gICAgICogc2VjdGlvbiAyLjgpIG9yIGEgdGV4dCBkZWNsYXJhdGlvbiAoWE1MIDEuMCwgc2VjdGlvbiA0LjMuMSkKLSAgICAgKiB1c2luZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAgICogICAgICAgIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljICB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbiAoU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChtX2RvY3VtZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICBtX2RvY3VtZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICAgIGVsc2UgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICBtX3RyYW5zZm9ybWVySW1wbC5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0gICAgICAvL21fdHJhbnNmb3JtZXJJbXBsLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSk7Ci0gICAgfQotICAgIAotICAgIC8vIEltcGxlbWVudCBYU0xUUHJvY2Vzc29yCi0gICAgCi0gICAgLyoqCi0gICAqIFNldCB0aGUgb3V0cHV0IHN0cmVhbS4gUmVxdWlyZWQgd2hlbiB0aGUgWFNMVFByb2Nlc3NvciBpcyBiZWluZyB1c2VkCi0gICAqIGFzIGEgU0FYIERvY3VtZW50SGFuZGxlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE91dHB1dFN0cmVhbShqYXZhLmlvLk91dHB1dFN0cmVhbSBvcykKLSAgewotICAgIFRyYW5zZm9ybWVySGFuZGxlckltcGwgaGFuZGxlciA9IG5ldyBUcmFuc2Zvcm1lckhhbmRsZXJJbXBsKG1fdHJhbnNmb3JtZXJJbXBsLCBmYWxzZSwgbnVsbCk7Ci0gICAgaGFuZGxlci5zZXRSZXN1bHQobmV3IFN0cmVhbVJlc3VsdChvcykpOyAgIAotICB9Ci0gIAotICAvKioKLSAgICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gY3JlYXRlIGFuIFhTdHJpbmcuCi0gICAqIEBwYXJhbSBzIEEgdmFsaWQgc3RyaW5nLgotICAgKiBAcmV0dXJuIEFuIFhTdHJpbmcgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhTdHJpbmcgY3JlYXRlWFN0cmluZyhTdHJpbmcgcykKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gWE9iamVjdC4KLSAgICogQHBhcmFtIG8gQW55IGphdmEgb2JqZWN0LgotICAgKiBAcmV0dXJuIEFuIFhPYmplY3Qgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgY3JlYXRlWE9iamVjdChPYmplY3QgbykKLSAgewotICAgIHJldHVybiBuZXcgWE9iamVjdChvKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gWE51bWJlci4KLSAgICogQHBhcmFtIGQgQW55IGRvdWJsZSBudW1iZXIuCi0gICAqIEByZXR1cm4gQW4gWE51bWJlciBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgWE51bWJlciBjcmVhdGVYTnVtYmVyKGRvdWJsZSBkKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGQpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBYQm9vbGVhbi4KLSAgICogQHBhcmFtIGIgYm9vbGVhbiB2YWx1ZS4KLSAgICogQHJldHVybiBBbiBYQm9vbGVhbiBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgWEJvb2xlYW4gY3JlYXRlWEJvb2xlYW4oYm9vbGVhbiBiKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYQm9vbGVhbihiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gWE5vZGVTZXQuCi0gICAqIEBwYXJhbSBubCBBIE5vZGVMaXN0IG9iamVjdC4KLSAgICogQHJldHVybiBBbiBYTm9kZVNldCBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgWE5vZGVTZXQgY3JlYXRlWE5vZGVTZXQoTm9kZUxpc3QgbmwpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOb2RlU2V0KG5sKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gWE5vZGVTZXQgZnJvbSBhIG5vZGUuCi0gICAqIEBwYXJhbSBuIEEgRE9NIG5vZGUuCi0gICAqIEByZXR1cm4gQW4gWE5vZGVTZXQgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhOb2RlU2V0IGNyZWF0ZVhOb2RlU2V0KE5vZGUgbikKLSAgewotICAgIHJldHVybiBuZXcgWE5vZGVTZXQobik7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gY3JlYXRlIGFuIFhOdWxsLgotICAgKiBAcmV0dXJuIEFuIFhOdWxsIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTnVsbCBjcmVhdGVYTnVsbCgpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdWxsKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIFhNTFBhcnNlckxpYWlzb24gdGhhdCB0aGlzIHByb2Nlc3NvciB1c2VzLgotICAgKi8KLSAgcHVibGljIFhNTFBhcnNlckxpYWlzb24gZ2V0WE1MUHJvY2Vzc29yTGlhaXNvbigpCi0gIHsKLSAgICByZXR1cm4gKFhNTFBhcnNlckxpYWlzb24pbV9saWFpc29uOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcHJlZmVycmVkIHN0eWxlc2hlZXQgZm9yIHRoZSBYU0xUSW5wdXRTb3VyY2UgWE1MIGRvY3VtZW50LAotICAgKiBhcyBpZGVudGlmaWVkIGJ5IHRoZSB4bWwtc3R5bGVzaGVldCBQSSwgYW5kIG1hdGNoaW5nIHRoZSBtZWRpYSBhbmQKLSAgICogY2hhcnNldCBjcml0ZXJpYS4gU2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+Ci0gICAqIEFzc29jaWF0aW5nIFN0eWxlIFNoZWV0cyB3aXRoIFhNTCBkb2N1bWVudHM8L2E+LgotICAgKiBEb2VzIG5vdCB5ZXQgaGFuZGxlIHRoZSBMSU5LIFJFTD0ic3R5bGVzaGVldCIgc3ludGF4LgotICAgKgotICAgKiBAcGFyYW0gbWVkaWEgVGhlIG1lZGlhIGF0dHJpYnV0ZSB0byBiZSBtYXRjaGVkLiAgTWF5IGJlIG51bGwsIGluIHdoaWNoCi0gICAqICAgICAgICAgICAgICBjYXNlIHRoZSBwcmVmZXJlZCBzdHlsZXNoZWV0IHdpbGwgYmUgdXNlZCAoaS5lLiwgYWx0ZXJuYXRlID0gbm8pLgotICAgKiBAcGFyYW0gdGl0bGUgVGhlIHZhbHVlIG9mIHRoZSB0aXRsZSBhdHRyaWJ1dGUgdG8gbWF0Y2guICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gIE1heSBiZSBudWxsLgotICAgKiBAcmV0dXJucyBTdHlsZXNoZWV0U3BlYyBleHRlbmRzIFhTTFRJbnB1dFNvdXJjZSBleHRlZG5zIFNBWCBJbnB1dFNvdXJjZTsgdGhlIHJldHVybiB2YWx1ZQotICAgKiBjYW4gYmUgcGFzc2VkIHRvIHRoZSBwcm9jZXNzU3R5bGVzaGVldCBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldFNwZWMgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoWFNMVElucHV0U291cmNlIHNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtZWRpYSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjaGFyc2V0KQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8qSW5wdXRTb3VyY2VbXWluID0gbV9wcm9jZXNzb3IuZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXRzKHNvdXJjZSwgbWVkaWEsIG51bGwsIGNoYXJzZXQpOwotICAgIGlmIChpbi5sZW5ndGggPjApCi0gICAgICByZXR1cm4gKFN0eWxlc2hlZXRTcGVjKWluWzBdOwotICAgIGVsc2UgCi0gICAgICByZXR1cm4gbnVsbDsgKi8KLSAgICB0cnl7Ci0gICAgU291cmNlIHMgPSBtX3RmYWN0b3J5LmdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KHNvdXJjZS5nZXRTb3VyY2VPYmplY3QoKSwgbWVkaWEsIG51bGwsIGNoYXJzZXQpOwotICAgIHJldHVybiAoU3R5bGVzaGVldFNwZWMpczsgCi0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGNlKSAKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKHRjZSk7IAotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBsaXN0IG9mIHN0eWxlc2hlZXQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBYU0xUSW5wdXRTb3VyY2UgWE1MIGRvY3VtZW50LAotICAgKiBhcyBpZGVudGlmaWVkIGJ5IHRoZSB4bWwtc3R5bGVzaGVldCBQSSwgYW5kIG1hdGNoaW5nIHRoZSBtZWRpYSBhbmQKLSAgICogY2hhcnNldCBjcml0ZXJpYS4gU2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+Ci0gICAqIEFzc29jaWF0aW5nIFN0eWxlIFNoZWV0cyB3aXRoIFhNTCBkb2N1bWVudHM8L2E+LgotICAgKiBEb2VzIG5vdCB5ZXQgaGFuZGxlIHRoZSBMSU5LIFJFTD0ic3R5bGVzaGVldCIgc3ludGF4LgotICAgKgotICAgKiBAcGFyYW0gbWVkaWEgVGhlIG1lZGlhIGF0dHJpYnV0ZSB0byBiZSBtYXRjaGVkLiAgTWF5IGJlIG51bGwsIGluIHdoaWNoCi0gICAqICAgICAgICAgICAgICBjYXNlIHRoZSBwcmVmZXJlZCBzdHlsZXNoZWV0IHdpbGwgYmUgdXNlZCAoaS5lLiwgYWx0ZXJuYXRlID0gbm8pLgotICAgKiBAcGFyYW0gdGl0bGUgVGhlIHZhbHVlIG9mIHRoZSB0aXRsZSBhdHRyaWJ1dGUgdG8gbWF0Y2guICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gIE1heSBiZSBudWxsLgotICAgKiBAcmV0dXJucyBsaXN0IG9mIFN0eWxlc2hlZXRTcGVjcyAoZXh0ZW5kIFhTTFRJbnB1dFNvdXJjZXMgZXh0ZW5kIFNBWCBJbnB1dFNvdXJjZXM7IGEKLSAgICogbGlzdCBtZW1iZXIgbWF5IGJlIHBhc3NzZWQgdG8gdGhlIHByb2Nlc3NTdHlsZXNoZWV0IG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyBWZWN0b3IgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXRzKFhTTFRJbnB1dFNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbWVkaWEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2hhcnNldCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB0cnl7Ci0gICAgICBTb3VyY2UgcyA9IG1fdGZhY3RvcnkuZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoc291cmNlLmdldFNvdXJjZU9iamVjdCgpLCBtZWRpYSwgbnVsbCwgY2hhcnNldCk7Ci0gICAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKLSAgICAgIC8vZm9yIChpbnQgaSA9IDA7IGk8IGluLmxlbmd0aDsgaSsrKQotICAgICAgdi5hZGRFbGVtZW50KChTdHlsZXNoZWV0U3BlYylzKTsKLSAgICAgIHJldHVybiB2OwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKHRjZSk7Ci0gICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgfQotICAKLSAgLyoqCi0gICAqIFN1Ym1pdCBhIHRvcC1sZXZlbCBzdHlsZXNoZWV0IHBhcmFtZXRlci4gIFRoaXMgdmFsdWUgY2FuCi0gICAqIGJlIGV2YWx1YXRlZCBpbiB0aGUgc3R5bGVzaGVldCB2aWEgeHNsOnBhcmFtLXZhcmlhYmxlLgotICAgKiBAcGFyYW0ga2V5IFRoZSBuYW1lIG9mIHRoZSBwYXJhbS4KLSAgICogQHBhcmFtIHZhbHVlIEFuIFhPYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0UGFyYW0oU3RyaW5nIGtleSwgWE9iamVjdCB2YWx1ZSkKLSAgewotICAgIHNldFBhcmFtZXRlcihrZXksIHZhbHVlLm9iamVjdCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYSB0b3AtbGV2ZWwgc3R5bGVzaGVldCBwYXJhbWV0ZXIuICBUaGlzIHZhbHVlIGNhbgotICAgKiBiZSBldmFsdWF0ZWQgdmlhIHhzbDpwYXJhbS12YXJpYWJsZS4gIE5vdGUgdGhhdCB0aGUgdmFsdWUKLSAgICogcGFzc2VkIGlzIGFuIGV4cHJlc3Npb24sIGFuZCBub3QgYSBzdHJpbmcuICBUaGlzIG1lYW5zIHRoYXQKLSAgICogc2V0U3R5bGVzaGVldFBhcmFtKCJmb28iLCAiaGVsbG8iKTsgd2lsbCBsb29rIGZvciB0aGUKLSAgICogZWxlbWVudCAiaGVsbG8iLiAgSWYgeW91IHdhbnQgdG8gcGFzcyBhIHN0cmluZywgeW91J2xsCi0gICAqIG5lZWQgdG8gcHV0IHF1b3RlcyBhcm91bmQgaXQ6Ci0gICAqIHNldFN0eWxlc2hlZXRQYXJhbSgiZm9vIiwgIidoZWxsbyciKTsgd2lsbCBsb29rIGZvciB0aGUKLSAgICogQHBhcmFtIGtleSBUaGUgbmFtZSBvZiB0aGUgcGFyYW0uCi0gICAqIEBwYXJhbSBleHByZXNzaW9uIEFuIGV4cHJlc3Npb24gdGhhdCB3aWxsIGJlIGV2YWx1YXRlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0eWxlc2hlZXRQYXJhbShTdHJpbmcga2V5LCBTdHJpbmcgZXhwcmVzc2lvbikKLSAgeyAgICAKLSAgICBpZiAobV9ldmFsTGlzdCA9PSBudWxsKQotICAgICAgbV9ldmFsTGlzdCA9IG5ldyBWZWN0b3IoKTsKLSAgICBpZiAoIW1fZXZhbExpc3QuY29udGFpbnMoa2V5KSkKLSAgICAgIG1fZXZhbExpc3QuYWRkRWxlbWVudChrZXkpOwotICAgIHNldFBhcmFtZXRlcihrZXksIGV4cHJlc3Npb24pOwotICAgIG1fbmVlZFRvRXZhbCA9IHRydWU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgYSB0b3AtbGV2ZWwgc3R5bGVzaGVldCBwYXJhbWV0ZXIuICBUaGlzIHZhbHVlIGNhbgotICAgKiBiZSBldmFsdWF0ZWQgdmlhIHhzbDpwYXJhbS12YXJpYWJsZS4gIE5vdGUgdGhhdCB0aGUgdmFsdWUKLSAgICogcGFzc2VkIGlzIGFuIGV4cHJlc3Npb24sIGFuZCBub3QgYSBzdHJpbmcuICBUaGlzIG1lYW5zIHRoYXQKLSAgICogc2V0U3R5bGVzaGVldFBhcmFtKCJmb28iLCAiaGVsbG8iKTsgd2lsbCBsb29rIGZvciB0aGUKLSAgICogZWxlbWVudCAiaGVsbG8iLiAgSWYgeW91IHdhbnQgdG8gcGFzcyBhIHN0cmluZywgeW91J2xsCi0gICAqIG5lZWQgdG8gcHV0IHF1b3RlcyBhcm91bmQgaXQ6Ci0gICAqIHNldFN0eWxlc2hlZXRQYXJhbSgiZm9vIiwgIidoZWxsbyciKTsgd2lsbCBsb29rIGZvciB0aGUKLSAgICogQHBhcmFtIGtleSBUaGUgbmFtZSBvZiB0aGUgcGFyYW0uCi0gICAqIEBwYXJhbSBleHByZXNzaW9uIEFuIGV4cHJlc3Npb24gdGhhdCB3aWxsIGJlIGV2YWx1YXRlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcga2V5LCAgT2JqZWN0IHZhbHVlKQotICB7Ci0gICAgaWYgKG1fc3R5bGVzaGVldFBhcmFtcyA9PSBudWxsKQotICAgICAgbV9zdHlsZXNoZWV0UGFyYW1zID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIG1fc3R5bGVzaGVldFBhcmFtcy5wdXQoa2V5LCB2YWx1ZSk7IAotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBGb3JtYXR0ZXJMaXN0ZW5lciAoU0FYIERvY3VtZW50SGFuZGxlciksIG9yIG51bGwgaWYgbm9uZSBoYXMgYmVlbiBzZXQuCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRIYW5kbGVyIGdldEZvcm1hdHRlckxpc3RlbmVyKCkKLSAgewotICAgIHJldHVybiBtX2RvY3VtZW50SGFuZGxlcjsKLSAgICAKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIEZvcm1hdHRlckxpc3RlbmVyICh0aGUgU0FYIERvY3VtZW50SGFuZGxlcikuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGb3JtYXR0ZXJMaXN0ZW5lcihEb2N1bWVudEhhbmRsZXIgZmxpc3RlbmVyKQotICB7Ci0gICAgbV9kb2N1bWVudEhhbmRsZXIgPSBmbGlzdGVuZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IFNBWCBEb2N1bWVudEhhbmRsZXIgKHRoZSBzYW1lIG9iamVjdCBhcyB0aGUgRm9ybWF0dGVyTGlzdGVuZXIpLCBvciBudWxsIGlmIG5vbmUgaGFzIGJlZW4gc2V0LgotICAgKi8KLSAgcHVibGljIERvY3VtZW50SGFuZGxlciBnZXREb2N1bWVudEhhbmRsZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fZG9jdW1lbnRIYW5kbGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBTQVggRG9jdW1lbnRIYW5kbGVyICh0aGUgc2FtZQotICAgKiBvYmplY3QgYXMgdGhlIEZvcm1hdHRlckxpc3RlbmVyKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIgbGlzdGVuZXIpCi0gIHsKLSAgICBpZiAobGlzdGVuZXIgaW5zdGFuY2VvZiBQYXJzZXJBZGFwdGVyKSAgICAgIAotICAgICAgbV90cmFuc2Zvcm1lckltcGwuc2V0Q29udGVudEhhbmRsZXIoKChQYXJzZXJBZGFwdGVyKWxpc3RlbmVyKS5nZXRDb250ZW50SGFuZGxlcigpKTsKLSAgICBlbHNlIGlmIChsaXN0ZW5lciBpbnN0YW5jZW9mIFhTTFRFbmdpbmVJbXBsKQotICAgICAgbV90cmFuc2Zvcm1lckltcGwuc2V0Q29udGVudEhhbmRsZXIoKChYU0xURW5naW5lSW1wbClsaXN0ZW5lcikuZ2V0VHJhbnNmb3JtZXIoKS5nZXRDb250ZW50SGFuZGxlcigpKTsKLSAgICBlbHNlIGlmIChsaXN0ZW5lciBpbnN0YW5jZW9mIFhNTFNlcmlhbGl6ZXIpCi0gICAgewotICAgICAgdHJ5ewotICAgICAgICBtX3RyYW5zZm9ybWVySW1wbC5zZXRDb250ZW50SGFuZGxlcigoKFhNTFNlcmlhbGl6ZXIpbGlzdGVuZXIpLmFzQ29udGVudEhhbmRsZXIoKSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAge30KLSAgICB9Ci0gICAgbV9kb2N1bWVudEhhbmRsZXIgPSBsaXN0ZW5lcjsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSB0cmFjZSBsaXN0ZW5lciBmb3IgdGhlIHB1cnBvc2VzIG9mIGRlYnVnZ2luZyBhbmQgZGlhZ25vc2lzLgotICAgKiBAcGFyYW0gdGwgVHJhY2UgbGlzdGVuZXIgdG8gYmUgYWRkZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRUcmFjZUxpc3RlbmVyKFRyYWNlTGlzdGVuZXIgdGwpCi0gICAgdGhyb3dzIFRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb24KLSAgewotICAgIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsKQotICAgICAgbV90cmFuc2Zvcm1lckltcGwuZ2V0VHJhY2VNYW5hZ2VyKCkuYWRkVHJhY2VMaXN0ZW5lcih0bCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBJZiBzZXQgdG8gdHJ1ZSAodGhlIGRlZmF1bHQpLCBwYXR0ZXJuIGNvbmZsaWN0IHdhcm5pbmdzIGFyZSBub3QgcHJpbnRlZCB0byB0aGUgZGlhZ25vc3RpY3Mgc3RyZWFtLgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIGNvbmZsaWN0IHdhcm5pbmdzIHNob3VsZCBiZSBzdXBwcmVzc2VkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UXVpZXRDb25mbGljdFdhcm5pbmdzKGJvb2xlYW4gYikKLSAgewotICAgIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsKQotICAgICAgbV90cmFuc2Zvcm1lckltcGwuc2V0UXVpZXRDb25mbGljdFdhcm5pbmdzKGIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSBhIHRyYWNlIGxpc3RlbmVyLgotICAgKiBAcGFyYW0gdGwgVHJhY2UgbGlzdGVuZXIgdG8gYmUgcmVtb3ZlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZVRyYWNlTGlzdGVuZXIoVHJhY2VMaXN0ZW5lciB0bCkKLSAgewotICAgIGlmIChtX3RyYW5zZm9ybWVySW1wbCAhPSBudWxsKQotICAgICAgbV90cmFuc2Zvcm1lckltcGwuZ2V0VHJhY2VNYW5hZ2VyKCkucmVtb3ZlVHJhY2VMaXN0ZW5lcih0bCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIHByb2JsZW0gbGlzdGVuZXIgcHJvcGVydHkuCi0gICAqIFRoZSBYU0wgY2xhc3MgY2FuIGhhdmUgYSBzaW5nbGUgbGlzdGVuZXIgdG8gYmUgaW5mb3JtZWQKLSAgICogb2YgZXJyb3JzIGFuZCB3YXJuaW5ncy4gVGhlIHByb2JsZW0gbGlzdGVuZXIgbm9ybWFsbHkgY29udHJvbHMgd2hldGhlciBhbiBleGNlcHRpb24KLSAgICogaXMgdGhyb3duIG9yIG5vdCAob3IgdGhlIHByb2JsZW0gbGlzdGVuZXJzIGNhbiB0aHJvdyBpdHMgb3duIFJ1bnRpbWVFeGNlcHRpb24pLgotICAgKiBAcGFyYW0gbCBBIFByb2JsZW1MaXN0ZW5lciBpbnRlcmZhY2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9ibGVtTGlzdGVuZXIoUHJvYmxlbUxpc3RlbmVyIGwpCi0gIHsKLSAgICBpZiAobCBpbnN0YW5jZW9mIFByb2JsZW1MaXN0ZW5lckRlZmF1bHQpCi0gICAgICBtX3Byb2JsZW1MaXN0ZW5lciA9IChQcm9ibGVtTGlzdGVuZXJEZWZhdWx0KWw7Ci0gICAgZWxzZQotICAgICAgbV9wcm9ibGVtTGlzdGVuZXIgPSBuZXcgUHJvYmxlbUxpc3RlbmVyRGVmYXVsdChsKTsgCi0gICAgaWYgKG1fdHJhbnNmb3JtZXJJbXBsICE9IG51bGwpCi0gICAgICBtX3RyYW5zZm9ybWVySW1wbC5zZXRFcnJvckxpc3RlbmVyKG1fcHJvYmxlbUxpc3RlbmVyKTsKLSAgICBtX3RmYWN0b3J5LnNldEVycm9yTGlzdGVuZXIobV9wcm9ibGVtTGlzdGVuZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcHJvYmxlbSBsaXN0ZW5lciBwcm9wZXJ0eS4KLSAgICogVGhlIFhTTCBjbGFzcyBjYW4gaGF2ZSBhIHNpbmdsZSBsaXN0ZW5lciB0byBiZSBpbmZvcm1lZAotICAgKiBvZiBlcnJvcnMgYW5kIHdhcm5pbmdzLiBUaGUgcHJvYmxlbSBsaXN0ZW5lciBub3JtYWxseSBjb250cm9scyB3aGV0aGVyIGFuIGV4Y2VwdGlvbgotICAgKiBpcyB0aHJvd24gb3Igbm90IChvciB0aGUgcHJvYmxlbSBsaXN0ZW5lciBjYW4gdGhyb3cgaXRzIG93biBSdW50aW1lRXhjZXB0aW9uKS4KLSAgICogQHJldHVybiBBIFByb2JsZW1MaXN0ZW5lciBpbnRlcmZhY2UuCi0gICAqLwotICBwdWJsaWMgUHJvYmxlbUxpc3RlbmVyIGdldFByb2JsZW1MaXN0ZW5lcigpCi0gIHsKLSAgICBpZiAobV9wcm9ibGVtTGlzdGVuZXIuZ2V0UHJvYmxlbUxpc3RlbmVyKCkgIT0gbnVsbCkKLSAgICAgIHJldHVybiBtX3Byb2JsZW1MaXN0ZW5lci5nZXRQcm9ibGVtTGlzdGVuZXIoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9wcm9ibGVtTGlzdGVuZXI7Ci0gIH0KLSAgCi0gIHB1YmxpYyBUcmFuc2Zvcm1lckltcGwgZ2V0VHJhbnNmb3JtZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fdHJhbnNmb3JtZXJJbXBsOyAgCi0gICAgLy9yZXR1cm4gKFN0eWxlc2hlZXRQcm9jZXNzb3IpbV9wcm9jZXNzb3I7Ci0gIH0gIAotCi0gIHB1YmxpYyBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIGdldFRyYW5zZm9ybWVyRmFjdG9yeSgpCi0gIHsKLSAgICByZXR1cm4gKFRyYW5zZm9ybWVyRmFjdG9yeUltcGwpbV90ZmFjdG9yeTsgICAgCi0gIH0gCi0KLSAgCi19IC8vIGVuZCBYU0xURW5naW5lSW1wbCBjbGFzcwpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVElucHV0U291cmNlLmphdmEgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9YU0xUSW5wdXRTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGIwYzc4MC4uMDAwMDAwMAotLS0gYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9YU0xUSW5wdXRTb3VyY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBSZXByZXNlbnRzIGFuIFhNTCBzb3VyY2UgZG9jdW1lbnQgb3IgWFNMIHN0eWxlc2hlZXQuCi0gKiBVc2UgWFNMVElucHV0U291cmNlIG9iamVjdHMgdG8gcHJvdmlkZSBpbnB1dCB0byB0aGUgWFNMVFByb2Nlc3NvciBwcm9jZXNzKCkgbWV0aG9kCi0gKiBmb3IgYSB0cmFuc2Zvcm1hdGlvbi4gVGhpcyBjbGFzcyBleHRlbmRzIHRoZSBTQVggaW5wdXQgc291cmNlIHRvIGhhbmRsZQotICogRE9NIG5vZGVzIGFzIGlucHV0IGFzIHdlbGwgYXMgZmlsZXMsIGNoYXJhY3RlciBzdHJlYW1zLCBieXRlIHN0cmVhbXMgYW5kIFNBWCBEb2N1bWVudEhhbmRsZXJzLgotICoKLSAqIEBzZWUgWFNMVFByb2Nlc3NvciNwcm9jZXNzKFhTTFRJbnB1dFNvdXJjZSwgWFNMVElucHV0U291cmNlLCBYU0xUUmVzdWx0VGFyZ2V0KQotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0xUSW5wdXRTb3VyY2UgLy9leHRlbmRzIFNBWFNvdXJjZSAKLXsKLSAgCi0gIHByaXZhdGUgU3RyZWFtU291cmNlIHN0cmVhbVNvdXJjZSA9IG51bGw7Ci0gIHByaXZhdGUgU0FYU291cmNlIHNheFNvdXJjZSA9IG51bGw7Ci0gIHByaXZhdGUgRE9NU291cmNlIGRvbVNvdXJjZSA9IG51bGw7Ci0gIAotICAvKioKLSAgICAqIFplcm8tYXJndW1lbnQgZGVmYXVsdCBjb25zdHJ1Y3RvciAtLSBCZWZvcmUgeW91IGNhbiB1c2UgdGhlIG5ldyBYU0xUSW5wdXRTb3VyY2Ugb2JqZWN0IGluIGEgdHJhbnNmb3JtYXRpb24sCi0gICAgKiB5b3UgbXVzdCBkZWZpbmUgdGhlIGRvY3VtZW50IHNvdXJjZSB3aXRoIHNldFN5c3RlbUlkKCksIHNldE5vZGUoKSwgc2V0SW5wdXRTdHJlYW0oKSwgb3Igc2V0Q2hhcmFjdGVyU3RyZWFtKCkuCi0gICAgKgotICAgICogQHNlZSAjc2V0U3lzdGVtSWQoU3RyaW5nKQotICAgICogQHNlZSAjc2V0Tm9kZShOb2RlKQotICAgICogQHNlZSAjc2V0SW5wdXRTdHJlYW0KLSAgICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbQotICAgICogQHNlZSAjc2V0RW5jb2RpbmcoU3RyaW5nKQotICAgICovCi0gIHB1YmxpYyBYU0xUSW5wdXRTb3VyY2UgKCkKLSAgewotICAgIHNheFNvdXJjZSA9IG5ldyBTQVhTb3VyY2UoKTsKLSAgfQotCi0gIC8qKgotICAgICogQ3JlYXRlIGEgbmV3IGlucHV0IHNvdXJjZSB3aXRoIGEgc3lzdGVtIGlkZW50aWZpZXIgKGZvciBhIFVSTCBvciBmaWxlIG5hbWUpIC0tCi0gICAgKiB0aGUgZXF1aXZhbGVudCBvZiBjcmVhdGluZyBhbiBpbnB1dCBzb3VyY2Ugd2l0aCB0aGUgemVyby1hcmd1bWVudAotICAgICogY29uc3RydWN0b3IgYW5kIHNldHRpbmcgdGhlIG5ldyBvYmplY3QncyBTeXN0ZW1JZCBwcm9wZXJ0eS4KLQotICAgICogSWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgVVJMLCBpdCBtdXN0IGJlIGZ1bGx5IHJlc29sdmVkLgotICAgICoKLSAgICAqIElmIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBpcyBhIFVSTCwgaXQgbXVzdCBiZSBmdWxseSByZXNvbHZlZC4KLSAgICAqCi0gICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIChVUkkpLgotICAgICogQHNlZSAjc2V0U3lzdGVtSWQoU3RyaW5nKQotICAgICogQHNlZSAjc2V0Tm9kZShOb2RlKQotICAgICogQHNlZSAjc2V0SW5wdXRTdHJlYW0KLSAgICAqIEBzZWUgI3NldEVuY29kaW5nKFN0cmluZykKLSAgICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbQotICAgICovCi0gIHB1YmxpYyBYU0xUSW5wdXRTb3VyY2UgKFN0cmluZyBzeXN0ZW1JZCkKLSAgewotICAgIHNheFNvdXJjZSA9IG5ldyBTQVhTb3VyY2UoKTsKLSAgICB0aGlzLnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgfQotCi0KLSAgLyoqCi0gICAgKiBDcmVhdGUgYSBuZXcgaW5wdXQgc291cmNlIHdpdGggYSBieXRlIHN0cmVhbSAtLSB0aGUgZXF1aXZhbGVudCBvZiBjcmVhdGluZyBhbiBpbnB1dCBzb3VyY2UKLSAgICAqIHdpdGggdGhlIHplcm8tYXJndW1lbnQgY29uc3RydWN0b3IgYW5kIHNldHRpbmcgdGhlIG5ldyBvYmplY3QncyBCeXRlU3RyZWFtIHByb3BlcnR5LgotICAgICoKLSAgICAqIEBwYXJhbSBieXRlU3RyZWFtIFRoZSByYXcgYnl0ZSBzdHJlYW0gY29udGFpbmluZyB0aGUgZG9jdW1lbnQuCi0gICAgKiBAc2VlICNzZXRJbnB1dFN0cmVhbQotICAgICogQHNlZSAjc2V0U3lzdGVtSWQoU3RyaW5nKQotICAgICogQHNlZSAjc2V0Tm9kZShOb2RlKQotICAgICogQHNlZSAjc2V0RW5jb2RpbmcoU3RyaW5nKQotICAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtCi0gICAgKi8KLSAgcHVibGljIFhTTFRJbnB1dFNvdXJjZSAoSW5wdXRTdHJlYW0gYnl0ZVN0cmVhbSkKLSAgewotICAgIHN0cmVhbVNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UoKTsKLSAgICBzdHJlYW1Tb3VyY2Uuc2V0SW5wdXRTdHJlYW0oYnl0ZVN0cmVhbSk7Ci0gIH0KLQotICAvKioKLSAgICAqIENyZWF0ZSBhIG5ldyBpbnB1dCBzb3VyY2Ugd2l0aCBhIGNoYXJhY3RlciBzdHJlYW0gLS0gdGhlIGVxdWl2YWxlbnQgb2YgY3JlYXRpbmcgYW4gaW5wdXQgc291cmNlCi0gICAgKiB3aXRoIHRoZSB6ZXJvLWFyZ3VtZW50IGNvbnN0cnVjdG9yIGFuZCBzZXR0aW5nIHRoZSBuZXcgb2JqZWN0J3MgQ2hhcmFjdGVyU3RyZWFtIHByb3BlcnR5LgotICAgICogPHA+VGhlIGNoYXJhY3RlciBzdHJlYW0gc2hhbGwgbm90IGluY2x1ZGUgYSBieXRlIG9yZGVyIG1hcmsuPC9wPgotICAgICoKLSAgICAqIEBwYXJhbSBjaGFyYWN0ZXJTdHJlYW0gVGhlIGNoYXJhY3RlciBzdHJlYW0gY29udGFpbmluZyB0aGUgZG9jdW1lbnQuCi0gICAgKiBAc2VlICNzZXRDaGFyYWN0ZXJTdHJlYW0KLSAgICAqIEBzZWUgI3NldElucHV0U3RyZWFtCi0gICAgKiBAc2VlICNzZXRTeXN0ZW1JZChTdHJpbmcpCi0gICAgKiBAc2VlICNzZXROb2RlKE5vZGUpCi0gICAgKiBAc2VlICNzZXRFbmNvZGluZyhTdHJpbmcpCi0gICAgKi8KLSAgcHVibGljIFhTTFRJbnB1dFNvdXJjZSAoUmVhZGVyIGNoYXJhY3RlclN0cmVhbSkKLSAgewotICAgIHN0cmVhbVNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UoKTsKLSAgICBzdHJlYW1Tb3VyY2Uuc2V0UmVhZGVyKGNoYXJhY3RlclN0cmVhbSk7Ci0gIH0KLQotICAvKioKLSAgICAqIENyZWF0ZSBhIG5ldyBpbnB1dCBzb3VyY2Ugd2l0aCBhIERPTSBOb2RlIC0tIHRoZSBlcXVpdmFsZW50IG9mIGNyZWF0aW5nIGFuIGlucHV0IHNvdXJjZQotICAgICogd2l0aCB0aGUgemVyby1hcmd1bWVudCBjb25zdHJ1Y3RvciBhbmQgc2V0dGluZyB0aGUgbmV3IG9iamVjdCdzIE5vZGUgcHJvcGVydHkuCi0gICAgKgotICAgICogQHBhcmFtIG5vZGUgVGhlIERPTSBOb2RlIGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50LgotICAgICogQHNlZSAjc2V0Tm9kZShOb2RlKQotICAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtCi0gICAgKiBAc2VlICNzZXRJbnB1dFN0cmVhbQotICAgICogQHNlZSAjc2V0U3lzdGVtSWQoU3RyaW5nKQotICAgICogQHNlZSAjc2V0RW5jb2RpbmcoU3RyaW5nKQotICAgICovCi0gIHB1YmxpYyBYU0xUSW5wdXRTb3VyY2UgKE5vZGUgbm9kZSkKLSAgewotICAgIGRvbVNvdXJjZSA9IG5ldyBET01Tb3VyY2UoKTsKLSAgICBkb21Tb3VyY2Uuc2V0Tm9kZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgICogQ3JlYXRlIGEgbmV3IFhTTFRJbnB1dFNvdXJjZSBzb3VyY2UgZnJvbSBhIFNBWCBpbnB1dCBzb3VyY2UuCi0gICAgKiBUaGlzIG9wZXJhdGlvbiBzZXRzIHRoZSBCeXRlU3RyZWFtLCBDaGFyYWN0ZXJTdHJlYW0sIFN5c3RlbUlkLCBQdWJsaWNJRCwgYW5kIEVuY29kaW5nIHByb3BlcnRpZXMuCi0gICAgKgotICAgKiBAcGFyYW0gaXNvdXJjZSBUaGUgU0FYIGlucHV0IHNvdXJjZS4KLSAgICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbQotICAgICogQHNlZSAjc2V0SW5wdXRTdHJlYW0KLSAgICAqIEBzZWUgI3NldFN5c3RlbUlkKFN0cmluZykKLSAgICAqIEBzZWUgI3NldEVuY29kaW5nKFN0cmluZykKLSAgICAqIEBzZWUgI3NldE5vZGUoTm9kZSkKLSAgICAqLwotICBwdWJsaWMgWFNMVElucHV0U291cmNlIChJbnB1dFNvdXJjZSBpc291cmNlKQotICB7Ci0gICAgc2F4U291cmNlID0gbmV3IFNBWFNvdXJjZSgpOwotICAgIHNheFNvdXJjZS5zZXRJbnB1dFNvdXJjZShpc291cmNlKTsKLSAgICAvL3NheFNvdXJjZS5zZXRYTUxSZWFkZXIoaXNvdXJjZS5nZXRDaGFyYWN0ZXJTdHJlYW0oKSk7Ci0gICAgdGhpcy5zZXRFbmNvZGluZyhpc291cmNlLmdldEVuY29kaW5nKCkpOwotICAgIHRoaXMuc2V0U3lzdGVtSWQoaXNvdXJjZS5nZXRTeXN0ZW1JZCgpKTsKLSAgfQotCi0gIC8qKgotICAgICogU2V0IHRoZSBET00gTm9kZSBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuCi0gICAgKgotICAgICogQHBhcmFtIG5vZGUgVGhlIERPTSBub2RlIGNvbnRhaW5pbmcgdGhlCi0gICAgKiAgICAgICAgWE1MIGRvY3VtZW50IG9yIFhTTCBzdHlsZXNoZWV0LgotICAgICogQHNlZSAjWFNMVElucHV0U291cmNlKE5vZGUpCi0gICAgKiBAc2VlICNnZXRDaGFyYWN0ZXJTdHJlYW0oKSAgICAqIAotICAgICogQHNlZSBqYXZhLmlvLlJlYWRlcgotICAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5vZGUgKE5vZGUgbm9kZSkKLSAgewotICAgIGlmIChkb21Tb3VyY2UgPT0gbnVsbCkKLSAgICAgIGRvbVNvdXJjZSA9IG5ldyBET01Tb3VyY2UoKTsKLSAgICBkb21Tb3VyY2Uuc2V0Tm9kZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgICogR2V0IHRoZSBET00gTm9kZSBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuCi0gICAgKgotICAgICogQHJldHVybiBUaGUgRE9NIG5vZGUgY29udGFpbmluZyB0aGUgZG9jdW1lbnQsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAgKiBAc2VlICNYU0xUSW5wdXRTb3VyY2UoTm9kZSkKLSAgICAqIEBzZWUgI3NldE5vZGUoTm9kZSkKLSAgICAqLwotICBwdWJsaWMgTm9kZSBnZXROb2RlICgpCi0gIHsKLSAgICBpZiAoZG9tU291cmNlICE9IG51bGwpCi0gICAgICByZXR1cm4gZG9tU291cmNlLmdldE5vZGUoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIAotICAKLSAgIC8qKiAKLSAgICAgKiBTZXQgdGhlIGNoYXJhY3RlciBlbmNvZGluZywgaWYga25vd24uCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZyBhY2NlcHRhYmxlIGZvciBhbgotICAgICAqIFhNTCBlbmNvZGluZyBkZWNsYXJhdGlvbiAoc2VlIHNlY3Rpb24gNC4zLjMgb2YgdGhlIFhNTCAxLjAKLSAgICAgKiByZWNvbW1lbmRhdGlvbikuPC9wPgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgaGFzIG5vIGVmZmVjdCB3aGVuIHRoZSBhcHBsaWNhdGlvbiBwcm92aWRlcyBhCi0gICAgICogY2hhcmFjdGVyIHN0cmVhbS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgQSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgY2hhcmFjdGVyIGVuY29kaW5nLgotICAgICAqIEBzZWUgI3NldFN5c3RlbUlkCi0gICAgICogQHNlZSAjZ2V0RW5jb2RpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyAoU3RyaW5nIGVuY29kaW5nKQotICAgIHsKLQl0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIEdldCB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGZvciBhIGJ5dGUgc3RyZWFtIG9yIFVSSS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVuY29kaW5nLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZyAoKQotICAgIHsKLQlyZXR1cm4gZW5jb2Rpbmc7Ci0gICAgfQotICAgIAotICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nID0gbnVsbDsKLSAgICAKLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGNoYXJhY3RlciBzdHJlYW0gZm9yIHRoaXMgaW5wdXQgc291cmNlLgotICAgICAqCi0gICAgICogPHA+SWYgdGhlcmUgaXMgYSBjaGFyYWN0ZXIgc3RyZWFtIHNwZWNpZmllZCwgdGhlIFNBWCBwYXJzZXIKLSAgICAgKiB3aWxsIGlnbm9yZSBhbnkgYnl0ZSBzdHJlYW0gYW5kIHdpbGwgbm90IGF0dGVtcHQgdG8gb3BlbgotICAgICAqIGEgVVJJIGNvbm5lY3Rpb24gdG8gdGhlIHN5c3RlbSBpZGVudGlmaWVyLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjaGFyYWN0ZXJTdHJlYW0gVGhlIGNoYXJhY3RlciBzdHJlYW0gY29udGFpbmluZyB0aGUKLSAgICAgKiAgICAgICAgWE1MIGRvY3VtZW50IG9yIG90aGVyIGVudGl0eS4KLSAgICAgKiBAc2VlIGphdmEuaW8uUmVhZGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Q2hhcmFjdGVyU3RyZWFtIChSZWFkZXIgY2hhcmFjdGVyU3RyZWFtKQotICAgIHsKLSAgICAgIGlmIChzdHJlYW1Tb3VyY2UgPT0gbnVsbCkKLQkgICAgICBzdHJlYW1Tb3VyY2UgPSBuZXcgU3RyZWFtU291cmNlKCk7Ci0gICAgICBzdHJlYW1Tb3VyY2Uuc2V0UmVhZGVyKGNoYXJhY3RlclN0cmVhbSk7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIEdldCB0aGUgY2hhcmFjdGVyIHN0cmVhbSBmb3IgdGhpcyBpbnB1dCBzb3VyY2UuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBjaGFyYWN0ZXIgc3RyZWFtLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgICAqLwotICAgIHB1YmxpYyBSZWFkZXIgZ2V0Q2hhcmFjdGVyU3RyZWFtICgpCi0gICAgewotICAgICAgaWYgKHN0cmVhbVNvdXJjZSAhPSBudWxsKQotICAgICAgICByZXR1cm4gc3RyZWFtU291cmNlLmdldFJlYWRlcigpOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgCi0gICAgCi0gICAgCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBiYXNlIElEIChVUkwgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIFVSTHMKLSAgICAgKiB3aWxsIGJlIHJlc29sdmVkLgotICAgICAqCi0gICAgICogQHBhcmFtIGJhc2VJRCBCYXNlIFVSTCBmb3IgdGhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgYmFzZUlEKSAKLSAgICB7Ci0gICAgICB0aGlzLmJhc2VJRCA9IGJhc2VJRDsKLSAgICAgIAotICAgICAgaWYgKHNheFNvdXJjZSAhPSBudWxsKQotICAgICAgICBzYXhTb3VyY2Uuc2V0U3lzdGVtSWQoYmFzZUlEKTsKLSAgICAgIGVsc2UgaWYgKGRvbVNvdXJjZSAhPSBudWxsKQotICAgICAgICBkb21Tb3VyY2Uuc2V0U3lzdGVtSWQoYmFzZUlEKTsKLSAgICAgIGVsc2UgaWYgKHN0cmVhbVNvdXJjZSAhPSBudWxsKQotICAgICAgICBzdHJlYW1Tb3VyY2Uuc2V0U3lzdGVtSWQoYmFzZUlEKTsgICAgICAKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGJhc2UgSUQgKFVSTCBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgVVJMcwotICAgICAqIHdpbGwgYmUgcmVzb2x2ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEJhc2UgVVJMIGZvciB0aGlzLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0gICAgICAgIHJldHVybiB0aGlzLmJhc2VJRDsKLSAgICB9Ci0gICAgCi0gICAgcHJpdmF0ZSBTdHJpbmcgYmFzZUlEID0gbnVsbDsKLQotICAgIAotICAgIC8qKgotICAgICAqIFNldCB0aGUgYnl0ZSBzdHJlYW0gdG8gYmUgdXNlZCBhcyBpbnB1dC4gIE5vcm1hbGx5LAotICAgICAqIGEgc3RyZWFtIHNob3VsZCBiZSB1c2VkIHJhdGhlciB0aGFuIGEgcmVhZGVyLCBzbyB0aGF0Ci0gICAgICogdGhlIFhNTCBwYXJzZXIgY2FuIHJlc29sdmUgY2hhcmFjdGVyIGVuY29kaW5nIHNwZWNpZmllZAotICAgICAqIGJ5IHRoZSBYTUwgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5JZiB0aGlzIFNvdXJjZSBvYmplY3QgaXMgdXNlZCB0byBwcm9jZXNzIGEgc3R5bGVzaGVldCwgbm9ybWFsbHkKLSAgICAgKiBzZXRTeXN0ZW1JZCBzaG91bGQgYWxzbyBiZSBjYWxsZWQsIHNvIHRoYXQgcmVsYXRpdmUgVVJMIHJlZmVyZW5jZXMKLSAgICAgKiBjYW4gYmUgcmVzb2x2ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGlucHV0U3RyZWFtIEEgdmFsaWQgSW5wdXRTdHJlYW0gcmVmZXJlbmNlIHRvIGFuIFhNTCBzdHJlYW0uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0pIAotICAgIHsKLSAgICAgIGlmIChzdHJlYW1Tb3VyY2UgPT0gbnVsbCkKLSAgICAgICAgc3RyZWFtU291cmNlID0gbmV3IFN0cmVhbVNvdXJjZSgpOwotICAgICAgc3RyZWFtU291cmNlLnNldElucHV0U3RyZWFtKGlucHV0U3RyZWFtKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGJ5dGUgc3RyZWFtIHRoYXQgd2FzIHNldCB3aXRoIHNldElucHV0U3RyZWFtLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgYnl0ZSBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0SW5wdXRTdHJlYW0sIG9yIG51bGwKLSAgICAgKiBpZiBzZXRCeXRlU3RyZWFtIG9yIHRoZSBCeXRlU3RyZWFtIGNvbnN0cnVjdG9yIHdhcyBub3QgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHsKLSAgICAgIGlmIChzdHJlYW1Tb3VyY2UgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIHN0cmVhbVNvdXJjZS5nZXRJbnB1dFN0cmVhbSgpOwotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgCi0gICAgCi0gICAgIC8qKgotICAgICAqIEdldCB0aGUgUmVzdWx0IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBYU0xUUmVzdWx0VGFyZ2V0IG9iamVjdCAuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBSZXN1bHQgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIFhTTFRSZXN1bHRUYXJnZXQgb2JqZWN0Ci0gICAgICogCi0gICAgICovCi0gICAgcHVibGljIFNvdXJjZSBnZXRTb3VyY2VPYmplY3QoKSAKLSAgICB7Ci0gICAgICBpZiAoc3RyZWFtU291cmNlICE9IG51bGwpICAgICAgICAKLSAgICAgICAgcmV0dXJuIHN0cmVhbVNvdXJjZTsKLSAgICAgIGVsc2UgaWYgKGRvbVNvdXJjZSAhPSBudWxsKQotICAgICAgICByZXR1cm4gZG9tU291cmNlOwotICAgICAgZWxzZSAKLSAgICAgICAgcmV0dXJuIHNheFNvdXJjZTsKLSAgICB9IAotfQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVFByb2Nlc3Nvci5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVFByb2Nlc3Nvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNjBmMzcxLi4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFRQcm9jZXNzb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHBhdGguWE5vZGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC5YQm9vbGVhbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC5YTnVsbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54cGF0aC54bWwuWE1MUGFyc2VyTGlhaXNvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5Qcm9ibGVtTGlzdGVuZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotLy9pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci0vL2ltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuU3R5bGVzaGVldFNwZWM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS4qOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5Eb2N1bWVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuT3V0cHV0Rm9ybWF0OwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhlIHRyYW5zZm9ybWF0aW9uIHByb2Nlc3NvciAtLSB1c2Uge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUHJvY2Vzc29yRmFjdG9yeX0gdG8gaW5zdGFudGlhdGUgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpbnRlcmZhY2UuCi0gKiBJdCdzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgaW1wbGVtZW50YXRpb24gKFhTTFRFbmdpbmVJbXBsKSwKLSAqIGNvbGxhYm9yYXRpbmcgd2l0aCBhIFhNTFBhcnNlckxpYWlzb24sIHRoZSBET00sCi0gKiBhbmQgdGhlIFhQYXRoIGVuZ2luZSwgdG8gdHJhbnNmb3JtIGEgc291cmNlIHRyZWUKLSAqIG9mIG5vZGVzIGludG8gYSByZXN1bHQgdHJlZSBhY2NvcmRpbmcgdG8gaW5zdHJ1Y3Rpb25zCi0gKiBhbmQgdGVtcGxhdGVzIHNwZWNpZmllZCBieSBhIHN0eWxlc2hlZXQgdHJlZS4KLSAqIFVzZSB0aGUgPGNvZGU+cHJvY2VzcyguLi4pPC9jb2RlPiBhcmUgdGhlIHByaW1hcnkKLSAqIHB1YmxpYyBlbnRyeSBwb2ludHMuCi0gKgotICogTG9vayBhdCB0aGUgUHJvY2VzcyBjbGFzcyBtYWluKCkgbWV0aG9kIGZvcgotICogZm9yIGFuIGFkdmFuY2VkIHVzYWdlIGV4YW1wbGUuCi0gKgotICogPHA+SWYgeW91IHJldXNlIHRoZSBwcm9jZXNzb3IgaW5zdGFuY2UsIHlvdSBzaG91bGQgY2FsbCByZXNldCgpIGJldHdlZW4gdHJhbnNmb3JtYXRpb25zLjwvcD4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgaW50ZXJmYWNlIFhTTFRQcm9jZXNzb3IgZXh0ZW5kcyBEb2N1bWVudEhhbmRsZXIsIExleGljYWxIYW5kbGVyCi17Ci0gIC8qKgotICAgKiBVc2UgdGhlIFhTTCBzdHlsZXNoZWV0IHRvIHRyYW5zZm9ybSB0aGUgWE1MIGlucHV0LCBwbGFjaW5nIHRoZSByZXN1bHQgaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgKiBAcGFyYW0geG1sU291cmNlICBUaGUgWE1MIGlucHV0IHRvIGJlIHRyYW5zZm9ybWVkLgotICAgKiBAcGFyYW0geHNsU3R5bGVzaGVldCAgVGhlIFhTTCBzdHlsZXNoZWV0IHRvIGJlIHVzZWQgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4gIE1heSBiZSBudWxsIGlmIFhNTCBpbnB1dAotICAgKiBoYXMgYW4gWFNMIHN0eWxlc2hlZXQgUEkuCi0gICAqIEBwYXJhbSByZXN1bHRUcmVlIFRoZSB0cmVlIHdoZXJlIHRoZSByZXN1bHQgb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGlzIHBsYWNlZC4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2VzcyggWFNMVElucHV0U291cmNlIHhtbFNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgWFNMVElucHV0U291cmNlIHhzbFN0eWxlc2hlZXQsCi0gICAgICAgICAgICAgICAgICAgICAgIFhTTFRSZXN1bHRUYXJnZXQgcmVzdWx0VHJlZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBDb21waWxlIHRoZSBYU0wgc3R5bGVzaGVldCByZXByZXNlbnRlZCBieSBhbiBYU0xUSW5wdXRTb3VyY2Ugb2JqZWN0IGludG8gYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24sCi0gICAqIGFuZCB1c2UgaXQgdG8gc2V0IHRoZSBYU0xUUHJvY2Vzc29yIFN0eWxlc2hlZXQgcHJvcGVydHkuCi0gICAqIFRoaXMgb3BlcmF0aW9uIGlzIHJlcXVpcmVkIGlmIHRoZSBYU0xUUHJvY2Vzc29yIGlzIHRvIGZ1bmN0aW9uIGFzIGEKLSAgICogU0FYIERvY3VtZW50SGFuZGxlci4KLSAgICogSWYgdGhlIFN0eWxlc2hlZXQgcHJvcGVydHkgaGFzIGFscmVhZHkgYmVlbiBzZXQgdG8gbm9uLW51bGwsIHRoaXMgb3BlcmF0aW9uCi0gICAqIGNhbGxzIHJlc2V0KCkgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24gaXMgcGVyZm9ybWVkLgotICAgKgotICAgKiBAcGFyYW0gc3R5bGVzaGVldFNvdXJjZSAgVGhlIFhTTCBzdHlsZXNoZWV0LgotICAgKiBAcmV0dXJuIFRoZSBjb21waWxlZCBzdHlsZXNoZWV0IG9iamVjdC4KLSAgICogQGV4Y2VwdGlvbiBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYTUxQYXJzZXJMaWFpc29uIGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRSb290IHByb2Nlc3NTdHlsZXNoZWV0KFhTTFRJbnB1dFNvdXJjZSBzdHlsZXNoZWV0U291cmNlKQotICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgVVJMIHRvIChvciBmaWxlIG5hbWUgb2YpIGFuIFhTTCBzdHlsZXNoZWV0LAotICAgKiBDb21waWxlIHRoZSBzdHlsZXNoZWV0IGludG8gYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24sIGFuZCB1c2UgaXQgdG8KLSAgICogc2V0IHRoZSBYU0xUUHJvY2Vzc29yIFN0eWxlc2hlZXQgcHJvcGVydHkuCi0gICAqIFRoaXMgb3BlcmF0aW9uIGlzIHJlcXVpcmVkIGlmIHRoZSBYU0xUUHJvY2Vzc29yIGlzIHRvIGZ1bmN0aW9uIGFzIGEKLSAgICogU0FYIERvY3VtZW50SGFuZGxlci4KLSAgICogSWYgdGhlIFN0eWxlc2hlZXQgcHJvcGVydHkgaGFzIGFscmVhZHkgYmVlbiBzZXQgdG8gbm9uLW51bGwsIHRoaXMgb3BlcmF0aW9uCi0gICAqIGNhbGxzIHJlc2V0KCkgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24gaXMgcGVyZm9ybWVkLgotICAgKgotICAgKiBAcGFyYW0geHNsZG9jVVJMU3RyaW5nICBUaGUgVVJMIHRvIHRoZSBYU0wgc3R5bGVzaGVldC4KLSAgICogQHJldHVybiBUaGUgY29tcGlsZWQgc3R5bGVzaGVldCBvYmplY3QuCi0gICAqIEBleGNlcHRpb24gWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWE1MUGFyc2VyTGlhaXNvbiBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdCBwcm9jZXNzU3R5bGVzaGVldChTdHJpbmcgeHNsZG9jVVJMU3RyaW5nKQotICAgIHRocm93cyBTQVhFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgb3V0cHV0IHN0cmVhbS4gUmVxdWlyZWQgd2hlbiB0aGUgWFNMVFByb2Nlc3NvciBpcyBiZWluZyB1c2VkCi0gICAqIGFzIGEgU0FYIERvY3VtZW50SGFuZGxlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE91dHB1dFN0cmVhbShqYXZhLmlvLk91dHB1dFN0cmVhbSBvcyk7Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBYU0xUUHJvY2Vzc29yIHN0YXRlLiAgTXVzdCBiZSB1c2VkIGFmdGVyIGEgcHJvY2VzcygpIGNhbGwKLSAgICogaWYgdGhlIFhTTFRQcm9jZXNzb3IgaW5zdGFuY2UgaXMgdG8gYmUgdXNlZCBhZ2Fpbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgRE9NIE5vZGUgZnJvbSB0aGUgWFNMVElucHV0U291cmNlIG9iamVjdC4gUmV0dXJucyBudWxsIGlmIHRoZSBYU0xUSW5wdXRTb3VyY2UKLSAgICogb2JqZWN0IGRvZXMgbm90IGNvbnRhaW4gYSBOb2RlIChpdCBtYXksIGZvciBleGFtcGxlLCBjb250YWluIGFuIGlucHV0IHN0cmVhbSkuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRTb3VyY2VUcmVlRnJvbUlucHV0KFhTTFRJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSkKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBVc2UgYSBjb21waWxlZCBzdHlsZXNoZWV0IHRvIHNldCB0aGUgU3R5bGVzaGVldCBwcm9wZXJ0eSBmb3IgdGhpcyBwcm9jZXNzb3IuCi0gICAqIFdoZW4gdGhpcyBwcm9wZXJ0eSBpcyBzZXQsIHRoZSBwcm9jZXNzIG1ldGhvZCB1c2VzIHRoaXMgc3R5bGVzaGVldCByYXRoZXIgdGhhbgotICAgKiBsb29raW5nIGZvciBhIHN0eWxlc2hlZXQgUEkgaWYgdGhlIHN0eWxlc2hlZXQgcGFyYW1ldGVyIGlzIG51bGwuICBBbHNvIHJlcXVpcmVkCi0gICAqIGlmIHlvdSBhcmUgZ29pbmcgdG8gdXNlIHRoZSBYU0xUUHJvY2Vzc29yIGFzIGEgU0FYIERvY3VtZW50SGFuZGxlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0eWxlc2hlZXQoU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldFJvb3QpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgU3R5bGVzaGVldCBzZXR0aW5nIGZvciB0aGlzIFhTTFRQcm9jZXNzb3IuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldFJvb3QgZ2V0U3R5bGVzaGVldCgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhNTFBhcnNlckxpYWlzb24gdGhhdCB0aGlzIHByb2Nlc3NvciB1c2VzLgotICAgKi8KLSAgcHVibGljIFhNTFBhcnNlckxpYWlzb24gZ2V0WE1MUHJvY2Vzc29yTGlhaXNvbigpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByZWZlcnJlZCBzdHlsZXNoZWV0IGZvciB0aGUgWFNMVElucHV0U291cmNlIFhNTCBkb2N1bWVudCwKLSAgICogYXMgaWRlbnRpZmllZCBieSB0aGUgeG1sLXN0eWxlc2hlZXQgUEksIGFuZCBtYXRjaGluZyB0aGUgbWVkaWEgYW5kCi0gICAqIGNoYXJzZXQgY3JpdGVyaWEuIFNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwtc3R5bGVzaGVldC8iPgotICAgKiBBc3NvY2lhdGluZyBTdHlsZSBTaGVldHMgd2l0aCBYTUwgZG9jdW1lbnRzPC9hPi4KLSAgICogRG9lcyBub3QgeWV0IGhhbmRsZSB0aGUgTElOSyBSRUw9InN0eWxlc2hlZXQiIHN5bnRheC4KLSAgICoKLSAgICogQHBhcmFtIG1lZGlhIFRoZSBtZWRpYSBhdHRyaWJ1dGUgdG8gYmUgbWF0Y2hlZC4gIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgKiAgICAgICAgICAgICAgY2FzZSB0aGUgcHJlZmVyZWQgc3R5bGVzaGVldCB3aWxsIGJlIHVzZWQgKGkuZS4sIGFsdGVybmF0ZSA9IG5vKS4KLSAgICogQHBhcmFtIHRpdGxlIFRoZSB2YWx1ZSBvZiB0aGUgdGl0bGUgYXR0cmlidXRlIHRvIG1hdGNoLiAgTWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSBjaGFyc2V0IFRoZSB2YWx1ZSBvZiB0aGUgY2hhcnNldCBhdHRyaWJ1dGUgdG8gbWF0Y2guICBNYXkgYmUgbnVsbC4KLSAgICogQHJldHVybnMgU3R5bGVzaGVldFNwZWMgZXh0ZW5kcyBYU0xUSW5wdXRTb3VyY2UgZXh0ZW5kcyBTQVggSW5wdXRTb3VyY2U7IHRoZSByZXR1cm4gdmFsdWUKLSAgICogY2FuIGJlIHBhc3NlZCB0byB0aGUgcHJvY2Vzc1N0eWxlc2hlZXQgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRTcGVjIGdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KFhTTFRJbnB1dFNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbWVkaWEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2hhcnNldCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBHZXQgYSBsaXN0IG9mIHN0eWxlc2hlZXQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBYU0xUSW5wdXRTb3VyY2UgWE1MIGRvY3VtZW50LAotICAgKiBhcyBpZGVudGlmaWVkIGJ5IHRoZSB4bWwtc3R5bGVzaGVldCBQSSwgYW5kIG1hdGNoaW5nIHRoZSBtZWRpYSBhbmQKLSAgICogY2hhcnNldCBjcml0ZXJpYS4gU2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+Ci0gICAqIEFzc29jaWF0aW5nIFN0eWxlIFNoZWV0cyB3aXRoIFhNTCBkb2N1bWVudHM8L2E+LgotICAgKiBEb2VzIG5vdCB5ZXQgaGFuZGxlIHRoZSBMSU5LIFJFTD0ic3R5bGVzaGVldCIgc3ludGF4LgotICAgKgotICAgKiBAcGFyYW0gbWVkaWEgVGhlIG1lZGlhIGF0dHJpYnV0ZSB0byBiZSBtYXRjaGVkLiAgTWF5IGJlIG51bGwsIGluIHdoaWNoCi0gICAqICAgICAgICAgICAgICBjYXNlIHRoZSBwcmVmZXJlZCBzdHlsZXNoZWV0IHdpbGwgYmUgdXNlZCAoaS5lLiwgYWx0ZXJuYXRlID0gbm8pLgotICAgKiBAcGFyYW0gdGl0bGUgVGhlIHZhbHVlIG9mIHRoZSB0aXRsZSBhdHRyaWJ1dGUgdG8gbWF0Y2guICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gIE1heSBiZSBudWxsLgotICAgKiBAcmV0dXJucyBsaXN0IG9mIFN0eWxlc2hlZXRTcGVjcyAoZXh0ZW5kIFhTTFRJbnB1dFNvdXJjZXMgZXh0ZW5kIFNBWCBJbnB1dFNvdXJjZXM7IGEKLSAgICogbGlzdCBtZW1iZXIgbWF5IGJlIHBhc3NzZWQgdG8gdGhlIHByb2Nlc3NTdHlsZXNoZWV0IG1ldGhvZC4KLSAgICovCi0gIHB1YmxpYyBWZWN0b3IgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXRzKFhTTFRJbnB1dFNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbWVkaWEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2hhcnNldCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uOwotCi0KLSAgLyoqCi0gICAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBYU3RyaW5nLgotICAgKiBAcGFyYW0gcyBBIHZhbGlkIHN0cmluZy4KLSAgICogQHJldHVybiBBbiBYU3RyaW5nIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYU3RyaW5nIGNyZWF0ZVhTdHJpbmcoU3RyaW5nIHMpOwotCi0gIC8qKgotICAgKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gWE9iamVjdC4KLSAgICogQHBhcmFtIG8gQW55IGphdmEgb2JqZWN0LgotICAgKiBAcmV0dXJuIEFuIFhPYmplY3Qgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgY3JlYXRlWE9iamVjdChPYmplY3Qgbyk7Ci0KLSAgLyoqCi0gICAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBYTnVtYmVyLgotICAgKiBAcGFyYW0gZCBBbnkgZG91YmxlIG51bWJlci4KLSAgICogQHJldHVybiBBbiBYTnVtYmVyIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTnVtYmVyIGNyZWF0ZVhOdW1iZXIoZG91YmxlIGQpOwotCi0gIC8qKgotICAgKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBjcmVhdGUgYW4gWEJvb2xlYW4uCi0gICAqIEBwYXJhbSBiIGJvb2xlYW4gdmFsdWUuCi0gICAqIEByZXR1cm4gQW4gWEJvb2xlYW4gb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhCb29sZWFuIGNyZWF0ZVhCb29sZWFuKGJvb2xlYW4gYik7Ci0KLSAgLyoqCi0gICAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBYTm9kZVNldC4KLSAgICogQHBhcmFtIG5sIEEgTm9kZUxpc3Qgb2JqZWN0LgotICAgKiBAcmV0dXJuIEFuIFhOb2RlU2V0IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTm9kZVNldCBjcmVhdGVYTm9kZVNldChOb2RlTGlzdCBubCk7Ci0KLSAgLyoqCi0gICAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBYTm9kZVNldCBmcm9tIGEgbm9kZS4KLSAgICogQHBhcmFtIG4gQSBET00gbm9kZS4KLSAgICogQHJldHVybiBBbiBYTm9kZVNldCBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgWE5vZGVTZXQgY3JlYXRlWE5vZGVTZXQoTm9kZSBuKTsKLQotICAvKioKLSAgICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gY3JlYXRlIGFuIFhOdWxsLgotICAgKiBAcmV0dXJuIEFuIFhOdWxsIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTnVsbCBjcmVhdGVYTnVsbCgpOwotCi0gIC8qKgotICAgKiBTdWJtaXQgYSB0b3AtbGV2ZWwgc3R5bGVzaGVldCBwYXJhbWV0ZXIuICBUaGlzIHZhbHVlIGNhbgotICAgKiBiZSBldmFsdWF0ZWQgaW4gdGhlIHN0eWxlc2hlZXQgdmlhIHhzbDpwYXJhbS12YXJpYWJsZS4KLSAgICogQHBhcmFtIGtleSBUaGUgbmFtZSBvZiB0aGUgcGFyYW0uCi0gICAqIEBwYXJhbSB2YWx1ZSBBbiBYT2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3R5bGVzaGVldFBhcmFtKFN0cmluZyBrZXksIFhPYmplY3QgdmFsdWUpOwotCi0gIC8qKgotICAgKiBTZXQgYSB0b3AtbGV2ZWwgc3R5bGVzaGVldCBwYXJhbWV0ZXIuICBUaGlzIHZhbHVlIGNhbgotICAgKiBiZSBldmFsdWF0ZWQgdmlhIHhzbDpwYXJhbS12YXJpYWJsZS4gIE5vdGUgdGhhdCB0aGUgdmFsdWUKLSAgICogcGFzc2VkIGlzIGFuIGV4cHJlc3Npb24sIGFuZCBub3QgYSBzdHJpbmcuICBUaGlzIG1lYW5zIHRoYXQKLSAgICogc2V0U3R5bGVzaGVldFBhcmFtKCJmb28iLCAiaGVsbG8iKTsgd2lsbCBsb29rIGZvciB0aGUKLSAgICogZWxlbWVudCAiaGVsbG8iLiAgSWYgeW91IHdhbnQgdG8gcGFzcyBhIHN0cmluZywgeW91J2xsCi0gICAqIG5lZWQgdG8gcHV0IHF1b3RlcyBhcm91bmQgaXQ6Ci0gICAqIHNldFN0eWxlc2hlZXRQYXJhbSgiZm9vIiwgIidoZWxsbyciKTsgd2lsbCBsb29rIGZvciB0aGUKLSAgICogQHBhcmFtIGtleSBUaGUgbmFtZSBvZiB0aGUgcGFyYW0uCi0gICAqIEBwYXJhbSBleHByZXNzaW9uIEFuIGV4cHJlc3Npb24gdGhhdCB3aWxsIGJlIGV2YWx1YXRlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0eWxlc2hlZXRQYXJhbShTdHJpbmcga2V5LCBTdHJpbmcgZXhwcmVzc2lvbik7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBGb3JtYXR0ZXJMaXN0ZW5lciAoU0FYIERvY3VtZW50SGFuZGxlciksIG9yIG51bGwgaWYgbm9uZSBoYXMgYmVlbiBzZXQuCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRIYW5kbGVyIGdldEZvcm1hdHRlckxpc3RlbmVyKCk7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgRm9ybWF0dGVyTGlzdGVuZXIgKHRoZSBTQVggRG9jdW1lbnRIYW5kbGVyKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEZvcm1hdHRlckxpc3RlbmVyKERvY3VtZW50SGFuZGxlciBmbGlzdGVuZXIpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgU0FYIERvY3VtZW50SGFuZGxlciAodGhlIHNhbWUgb2JqZWN0IGFzIHRoZSBGb3JtYXR0ZXJMaXN0ZW5lciksIG9yIG51bGwgaWYgbm9uZSBoYXMgYmVlbiBzZXQuCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRIYW5kbGVyIGdldERvY3VtZW50SGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgU0FYIERvY3VtZW50SGFuZGxlciAodGhlIHNhbWUKLSAgICogb2JqZWN0IGFzIHRoZSBGb3JtYXR0ZXJMaXN0ZW5lcikuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEhhbmRsZXIoRG9jdW1lbnRIYW5kbGVyIGxpc3RlbmVyKTsKLQotICAvKioKLSAgICogQWRkIGEgdHJhY2UgbGlzdGVuZXIgZm9yIHRoZSBwdXJwb3NlcyBvZiBkZWJ1Z2dpbmcgYW5kIGRpYWdub3Npcy4KLSAgICogQHBhcmFtIHRsIFRyYWNlIGxpc3RlbmVyIHRvIGJlIGFkZGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkVHJhY2VMaXN0ZW5lcihUcmFjZUxpc3RlbmVyIHRsKQotICAgIHRocm93cyBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBJZiBzZXQgdG8gdHJ1ZSwgdGVtcGxhdGUgY2FsbHMgYXJlIHRyYWNlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRyYWNlVGVtcGxhdGVzKGJvb2xlYW4gYik7Ci0KLSAgLyoqCi0gICAqIElmIHNldCB0byB0cnVlLCBzZWxlY3Rpb24gZXZlbnRzIGFyZSB0cmFjZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUcmFjZVNlbGVjdChib29sZWFuIGIpOwotCi0gIC8qKgotICAgKiBJZiBzZXQgdG8gdHJ1ZSAodGhlIGRlZmF1bHQgaXMgZmFsc2UpLCBhcyB0ZW1wbGF0ZSBjaGlsZHJlbiBhcmUgYmVpbmcgY29uc3RydWN0ZWQsIGRlYnVnIGRpYWdub3N0aWNzCi0gICAqIGFyZSB3cml0dGVuIHRvIHRoZSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIKLSAgICogc3RyZWFtLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VHJhY2VUZW1wbGF0ZUNoaWxkcmVuKGJvb2xlYW4gYik7Ci0KLSAgLyoqCi0gICAqIElmIHNldCB0byB0cnVlICh0aGUgZGVmYXVsdCksIHBhdHRlcm4gY29uZmxpY3Qgd2FybmluZ3MgYXJlIG5vdCBwcmludGVkIHRvIHRoZSBkaWFnbm9zdGljcyBzdHJlYW0uCi0gICAqIEBwYXJhbSBiIHRydWUgaWYgY29uZmxpY3Qgd2FybmluZ3Mgc2hvdWxkIGJlIHN1cHByZXNzZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRRdWlldENvbmZsaWN0V2FybmluZ3MoYm9vbGVhbiBiKTsKLQotICAvKioKLSAgICogUmVtb3ZlIGEgdHJhY2UgbGlzdGVuZXIuCi0gICAqIEBwYXJhbSB0bCBUcmFjZSBsaXN0ZW5lciB0byBiZSByZW1vdmVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlVHJhY2VMaXN0ZW5lcihUcmFjZUxpc3RlbmVyIHRsKTsKLQotICAvKioKLSAgICogSWYgc2V0LCBkaWFnbm9zdGljcyB3aWxsIGJlCi0gICAqIHdyaXR0ZW4gdG8gdGhlIG1fZGlhZ25vc3RpY3NQcmludFdyaXRlciBzdHJlYW0uIElmCi0gICAqIG51bGwsIGRpYWdub3N0aWNzIGFyZSB0dXJuZWQgb2ZmLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBjYWxscwotICAgKiB7QGxpbmsgI3NldERpYWdub3N0aWNzT3V0cHV0KGphdmEuaW8uUHJpbnRXcml0ZXIpfS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERpYWdub3N0aWNzT3V0cHV0KGphdmEuaW8uT3V0cHV0U3RyZWFtIG91dCk7Ci0KLSAgLyoqCi0gICAqIElmIHNldCwgZGlhZ25vc3RpY3Mgd2lsbCBiZQotICAgKiB3cml0dGVuIHRvIHRoZSBtX2RpYWdub3N0aWNzUHJpbnRXcml0ZXIgc3RyZWFtLiBJZgotICAgKiBudWxsLCBkaWFnbm9zdGljcyBhcmUgdHVybmVkIG9mZi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERpYWdub3N0aWNzT3V0cHV0KGphdmEuaW8uUHJpbnRXcml0ZXIgcHcpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIHByb2JsZW0gbGlzdGVuZXIgcHJvcGVydHkuCi0gICAqIFRoZSBYU0wgY2xhc3MgY2FuIGhhdmUgYSBzaW5nbGUgbGlzdGVuZXIgdG8gYmUgaW5mb3JtZWQKLSAgICogb2YgZXJyb3JzIGFuZCB3YXJuaW5ncy4gVGhlIHByb2JsZW0gbGlzdGVuZXIgbm9ybWFsbHkgY29udHJvbHMgd2hldGhlciBhbiBleGNlcHRpb24KLSAgICogaXMgdGhyb3duIG9yIG5vdCAob3IgdGhlIHByb2JsZW0gbGlzdGVuZXJzIGNhbiB0aHJvdyBpdHMgb3duIFJ1bnRpbWVFeGNlcHRpb24pLgotICAgKiBAcGFyYW0gbCBBIFByb2JsZW1MaXN0ZW5lciBpbnRlcmZhY2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9ibGVtTGlzdGVuZXIoUHJvYmxlbUxpc3RlbmVyIGwpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByb2JsZW0gbGlzdGVuZXIgcHJvcGVydHkuCi0gICAqIFRoZSBYU0wgY2xhc3MgY2FuIGhhdmUgYSBzaW5nbGUgbGlzdGVuZXIgdG8gYmUgaW5mb3JtZWQKLSAgICogb2YgZXJyb3JzIGFuZCB3YXJuaW5ncy4gVGhlIHByb2JsZW0gbGlzdGVuZXIgbm9ybWFsbHkgY29udHJvbHMgd2hldGhlciBhbiBleGNlcHRpb24KLSAgICogaXMgdGhyb3duIG9yIG5vdCAob3IgdGhlIHByb2JsZW0gbGlzdGVuZXIgY2FuIHRocm93IGl0cyBvd24gUnVudGltZUV4Y2VwdGlvbikuCi0gICAqIEByZXR1cm4gQSBQcm9ibGVtTGlzdGVuZXIgaW50ZXJmYWNlLgotICAgKi8KLSAgcHVibGljIFByb2JsZW1MaXN0ZW5lciBnZXRQcm9ibGVtTGlzdGVuZXIoKTsKLQotfQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVFByb2Nlc3NvckZhY3RvcnkuamF2YSBiL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFRQcm9jZXNzb3JGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc4NWNiNGIuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVFByb2Nlc3NvckZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5YTUxQYXJzZXJMaWFpc29uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhGYWN0b3J5OwotLy9pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Qcm9jZXNzb3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuVHJlZVdhbGtlcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogTWFudWZhY3R1cmVzIHRoZSBwcm9jZXNzb3IgZm9yIHBlcmZvcm1pbmcgdHJhbnNmb3JtYXRpb25zLiBVc2Ugb25lIG9mIHRoZSBzdGF0aWMgZ2V0UHJvY2Vzc29yIG1ldGhvZHMKLSAqIHRvIGNyZWF0ZSBhbiBYU0xUUHJvY2Vzc29yIG9iamVjdC4KLSAqIEBkZXByZWNhdGVkIFRoaXMgY29tcGF0aWJpbGl0eSBsYXllciB3aWxsIGJlIHJlbW92ZWQgaW4gbGF0ZXIgcmVsZWFzZXMuIAotICovCi1wdWJsaWMgY2xhc3MgWFNMVFByb2Nlc3NvckZhY3RvcnkKLXsKLSAgLyoqCi0gICAqIEdldCBhIG5ldyBYU0xUUHJvY2Vzc29yLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYU0xUUHJvY2Vzc29yIGdldFByb2Nlc3NvcigpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy9Qcm9jZXNzb3IgcHJvY2Vzc29yID0gUHJvY2Vzc29yLm5ld0luc3RhbmNlKCJ4c2x0Iik7IAotICAgIHJldHVybiBuZXcgWFNMVEVuZ2luZUltcGwoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBuZXcgWFNMVFByb2Nlc3NvciAocGFyc2VyTGlhaXNvbkNsYXNzTmFtZSBubyBsb25ncmUgdXNlZCkuCi0gICAqICoKLSAgICogQHNlZSAjZ2V0UHJvY2Vzc29yKCkKLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhwYXRoLnhtbC5YTUxQYXJzZXJMaWFpc29uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhTTFRQcm9jZXNzb3IgZ2V0UHJvY2Vzc29yVXNpbmdMaWFpc29uTmFtZShTdHJpbmcgcGFyc2VyTGlhaXNvbkNsYXNzTmFtZSkKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvL3JldHVybiBuZXcgWFNMVEVuZ2luZUltcGwocGFyc2VyTGlhaXNvbkNsYXNzTmFtZSk7Ci0gICAgLy9Qcm9jZXNzb3IgcHJvY2Vzc29yID0gUHJvY2Vzc29yLm5ld0luc3RhbmNlKCJ4c2x0Iik7IAotICAgIHJldHVybiBuZXcgWFNMVEVuZ2luZUltcGwoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBuZXcgWFNMVFByb2Nlc3NvciAoWE1MUGFyc2VyTGlhaXNvbiBubyBsb25nZXIgdXNlZCkuCi0gICAqCi0gICAqIEBwYXJhbSBwYXJzZXJMaWFpc29uIHRoZSBYTUxQYXJzZXJMaWFpc29uIHNldCB1cCB0byBpbnRlcmFjdCB3aXRoIGEgZ2l2ZW4gWE1MIHBhcnNlci4KLSAgICogQHJldHVybiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNMVFByb2Nlc3NvciBpbnRlcmZhY2Ugd2l0aCB3aGljaCB5b3UgY2FuIHBlcmZvcm0gdHJhbnNmb3JtYXRpb25zLgotICAgKgotICAgKiBAc2VlICNnZXRQcm9jZXNzb3IoKQotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLlhNTFBhcnNlckxpYWlzb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWFNMVFByb2Nlc3NvciBnZXRQcm9jZXNzb3IoWE1MUGFyc2VyTGlhaXNvbiBwYXJzZXJMaWFpc29uKQotICB7Ci0gICAgLy9yZXR1cm4gbmV3IFhTTFRFbmdpbmVJbXBsKHBhcnNlckxpYWlzb24pOwotICAgIHRyeXsKLSAgICAgIC8vUHJvY2Vzc29yIHByb2Nlc3NvciA9IFByb2Nlc3Nvci5uZXdJbnN0YW5jZSgieHNsdCIpOyAKLSAgICAgIHJldHVybiBuZXcgWFNMVEVuZ2luZUltcGwoKTsKLSAgICB9Ci0gICAvKiBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRjZSkKLSAgICB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ki8KLSAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIG5ldyBYU0xUUHJvY2Vzc29yIChYTUxQYXJzZXJMaWFpc29uIGFuZCBYUGF0aEZhY3Rvcnkgbm8gbG9uZ2VyIHVzZWQpLgotICAgKgotICAgKiBAcGFyYW0gcGFyc2VyTGlhaXNvbiB0aGUgWE1MUGFyc2VyTGlhaXNvbiBzZXQgdXAgdG8gaW50ZXJhY3Qgd2l0aCBhIGdpdmVuIFhNTCBwYXJzZXIuCi0gICAqIEBwYXJhbSB4cGF0aEZhY3RvcnkgQSBjdXN0b20gWFBhdGhGYWN0b3J5LgotICAgKiBAcmV0dXJuIEFuIGltcGxlbnRhdGlvbiBvZiB0aGUgWFNMVFByb2Nlc3NvciBpbnRlcmZhY2Ugd2l0aCB3aGljaCB5b3UKLSAgICogY2FuIHBlcmZvcm0gdHJhbnNmb3JtYXRpb25zLgotICAgKgotICAgKiBAc2VlICNnZXRQcm9jZXNzb3IoKQotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ueHBhdGgueG1sLlhNTFBhcnNlckxpYWlzb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWFNMVFByb2Nlc3NvciBnZXRQcm9jZXNzb3IoWE1MUGFyc2VyTGlhaXNvbiBwYXJzZXJMaWFpc29uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aEZhY3RvcnkgeHBhdGhGYWN0b3J5KQotICB7Ci0gICAgLy9yZXR1cm4gbmV3IFhTTFRFbmdpbmVJbXBsKHBhcnNlckxpYWlzb24sIHhwYXRoRmFjdG9yeSk7Ci0gICAgdHJ5ewotICAgICAgLy9Qcm9jZXNzb3IgcHJvY2Vzc29yID0gUHJvY2Vzc29yLm5ld0luc3RhbmNlKCJ4c2x0Iik7IAotICAgICAgcmV0dXJuIG5ldyBYU0xURW5naW5lSW1wbCgpOwotICAgIH0KLSAgLyogIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGUpCi0gICAgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSovCi0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVFJlc3VsdFRhcmdldC5qYXZhIGIvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvWFNMVFJlc3VsdFRhcmdldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwODEwNTk1Li4wMDAwMDAwCi0tLSBhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1hTTFRSZXN1bHRUYXJnZXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ1MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAgCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uV3JpdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRvY3VtZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLQotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBDb250YWlucyB0aGUgcmVzdWx0IG9mIGEgdHJhbnNmb3JtYXRpb24gdGhhdCB5b3UgcGVyZm9ybSB3aXRoIHRoZQotICogWFNMVFByb2Nlc3NvciBwcm9jZXNzKCkgbWV0aG9kIG9yIG9uZSBvZiB0aGUgU3R5bGVzaGVldFJvb3QgcHJvY2VzcygpIG1ldGhvZHMuCi0gKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyB0byBwcm92aWRlIHRoZSBwcm9jZXNzKCkgbWV0aG9kIGEgY29udGFpbmVyCi0gKiBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdCB0cmVlLgotICogWW91IGNhbiB1c2UgYSBmaWxlIG5hbWUgb3IgVVJMLCBjaGFyYWN0ZXIgc3RyZWFtLCBieXRlIHN0cmVhbSwgRE9NIE5vZGUsIG9yIFNBWCBEb2N1bWVudEhhbmRsZXIKLSAqIHRvIGluc3RhbnRpYXRlIGFuIFhTTFRSZXN1bHRUYXJnZXQgb2JqZWN0LgotICoKLSAqIEBzZWUgWFNMVFByb2Nlc3NvciNwcm9jZXNzKFhTTFRJbnB1dFNvdXJjZSwgWFNMVElucHV0U291cmNlLCBYU0xUUmVzdWx0VGFyZ2V0KQotICogQHNlZSBTdHlsZXNoZWV0Um9vdAotICogQGRlcHJlY2F0ZWQgVGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBsYXRlciByZWxlYXNlcy4gCi0gKi8KLXB1YmxpYyBjbGFzcyBYU0xUUmVzdWx0VGFyZ2V0IC8vaW1wbGVtZW50cyBSZXN1bHQgLy9leHRlbmRzIFN0cmVhbVJlc3VsdAotewotICAKLSAgcHJpdmF0ZSBTdHJlYW1SZXN1bHQgc3IgPSBudWxsOwotICBwcml2YXRlIFNBWFJlc3VsdCBzYXhSZXN1bHQgPSBudWxsOwotICBwcml2YXRlIERPTVJlc3VsdCBkciA9IG51bGw7Ci0gIAotICAKLSAgLyoqCi0gICAgKiBaZXJvLWFyZ3VtZW50IGRlZmF1bHQgY29uc3RydWN0b3IgIC0tIEJlZm9yZSB5b3UgY2FuIHVzZSB0aGUgbmV3IFhTTFRSZXN1bHRUYXJnZXQgb2JqZWN0IGluIGEgdHJhbnNmb3JtYXRpb24sCi0gICAgKiB5b3UgbXVzdCBkZWZpbmUgdGhlIG91dHB1dCBjb250YWluZXIgYnkgc2V0dGluZyBpdHMgRmlsZU5hbWUsIENoYXJhY3RlclN0cmVhLCBCeXRlU3RyZWFtLCBvciBOb2RlIHByb3BlcnR5LgotICAgICoKLSAgICAqIEBzZWUgI3NldEZpbGVOYW1lKFN0cmluZykKLSAgICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbShXcml0ZXIpCi0gICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtKE91dHB1dFN0cmVhbSkKLSAgICAqIEBzZWUgI3NldE5vZGUoTm9kZSkKLSAgICAqIEBzZWUgI3NldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIpCi0gICAgKiBAc2VlICNzZXRFbmNvZGluZyhTdHJpbmcpCi0gICAgKi8KLSAgcHVibGljIFhTTFRSZXN1bHRUYXJnZXQgKCkKLSAgewotICAgICBzciA9IG5ldyBTdHJlYW1SZXN1bHQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgb3V0cHV0IHRhcmdldCB3aXRoIGEgZmlsZSBuYW1lIC0tIHRoZSBlcXVpdmFsZW50IG9mIGNyZWF0aW5nIGFuIG91dHB1dCB0YXJnZXQKLSAgICogd2l0aCB0aGUgemVyby1hcmd1bWVudCBjb25zdHJ1Y3RvciBhbmQgc2V0dGluZyB0aGUgbmV3IG9iamVjdCdzIEZpbGVOYW1lIHByb3BlcnR5LgotICAgKgotICAgKiBAcGFyYW0gZmlsZU5hbWUgSWRlbnRpZmllcyB0aGUgZmlsZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0IChtdXN0IGJlIGEgdmFsaWQgc3lzdGVtIGZpbGUgbmFtZSkuCi0gICAqCi0gICAqIEBzZWUgI3NldEZpbGVOYW1lKFN0cmluZykKLSAgICogQHNlZSAjc2V0Q2hhcmFjdGVyU3RyZWFtKFdyaXRlcikKLSAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbShPdXRwdXRTdHJlYW0pCi0gICAqIEBzZWUgI3NldE5vZGUoTm9kZSkKLSAgICogQHNlZSAjc2V0RG9jdW1lbnRIYW5kbGVyKERvY3VtZW50SGFuZGxlcikKLSAgICogQHNlZSAjc2V0RW5jb2RpbmcoU3RyaW5nKQotICAgKi8KLSAgcHVibGljIFhTTFRSZXN1bHRUYXJnZXQgKFN0cmluZyBmaWxlTmFtZSkgLy8gRmlsZT8KLSAgewotICAgIHNyID0gbmV3IFN0cmVhbVJlc3VsdCgpOwotICAgIHNyLnNldFN5c3RlbUlkKGZpbGVOYW1lKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBvdXRwdXQgdGFyZ2V0IHdpdGggYSBieXRlIHN0cmVhbSAtLSB0aGUgZXF1aXZhbGVudCBvZiBjcmVhdGluZyBhbiBvdXRwdXQgdGFyZ2V0Ci0gICAqIHdpdGggdGhlIHplcm8tYXJndW1lbnQgY29uc3RydWN0b3IgYW5kIHNldHRpbmcgdGhlIG5ldyBvYmplY3QncyBCeXRlU3RyZWFtIHByb3BlcnR5LgotICAgKgotICAgKiBAcGFyYW0gYnl0ZVN0cmVhbSBUaGUgcmF3IGJ5dGUgc3RyZWFtIHRoYXQgd2lsbCBjb250YWluIHRoZSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQuCi0gICAqCi0gICAqIEBzZWUgI3NldEJ5dGVTdHJlYW0oT3V0cHV0U3RyZWFtKQotICAgKiBAc2VlICNzZXRGaWxlTmFtZShTdHJpbmcpCi0gICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbShXcml0ZXIpCi0gICAqIEBzZWUgI3NldE5vZGUoTm9kZSkKLSAgICogQHNlZSAjc2V0RG9jdW1lbnRIYW5kbGVyKERvY3VtZW50SGFuZGxlcikKLSAgICogQHNlZSAjc2V0RW5jb2RpbmcoU3RyaW5nKQotICAgKi8KLQotICBwdWJsaWMgWFNMVFJlc3VsdFRhcmdldCAoT3V0cHV0U3RyZWFtIGJ5dGVTdHJlYW0pCi0gIHsKLSAgICBzciA9IG5ldyBTdHJlYW1SZXN1bHQoKTsKLSAgICBzci5zZXRPdXRwdXRTdHJlYW0oYnl0ZVN0cmVhbSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgb3V0cHV0IHRhcmdldCB3aXRoIGEgY2hhcmFjdGVyIHN0cmVhbSAtLSB0aGUgZXF1aXZhbGVudCBvZiBjcmVhdGluZyBhbiBvdXRwdXQgdGFyZ2V0Ci0gICAqIHdpdGggdGhlIHplcm8tYXJndW1lbnQgY29uc3RydWN0b3IgYW5kIHNldHRpbmcgdGhlIG5ldyBvYmplY3QncyBDaGFyYWN0ZXJTdHJlYW0gcHJvcGVydHkuCi0gICAqCi0gICAqIEBwYXJhbSBjaGFyYWN0ZXJTdHJlYW0gVGhlIGNoYXJhY3RlciBzdHJlYW0gd2hlcmUgdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdCBpcyB3cml0dGVuLgotICAgKgotICAgKiBAc2VlICNzZXRDaGFyYWN0ZXJTdHJlYW0oV3JpdGVyKQotICAgKiBAc2VlICNzZXRCeXRlU3RyZWFtKE91dHB1dFN0cmVhbSkKLSAgICogQHNlZSAjc2V0RmlsZU5hbWUoU3RyaW5nKQotICAgKiBAc2VlICNzZXROb2RlKE5vZGUpCi0gICAqIEBzZWUgI3NldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIpCi0gICAqIEBzZWUgI3NldEVuY29kaW5nKFN0cmluZykKLSAgICovCi0gIHB1YmxpYyBYU0xUUmVzdWx0VGFyZ2V0IChXcml0ZXIgY2hhcmFjdGVyU3RyZWFtKQotICB7Ci0gICAgc3IgPSBuZXcgU3RyZWFtUmVzdWx0KCk7Ci0gICAgc3Iuc2V0V3JpdGVyKGNoYXJhY3RlclN0cmVhbSk7Ci0gIH0gICAgCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBvdXRwdXQgdGFyZ2V0IHdpdGggYSBET00gTm9kZSAtLSB0aGUgZXF1aXZhbGVudCBvZiBjcmVhdGluZyBhbiBvdXRwdXQgdGFyZ2V0Ci0gICAqIHdpdGggdGhlIHplcm8tYXJndW1lbnQgY29uc3RydWN0b3IgYW5kIHNldHRpbmcgdGhlIG5ldyBvYmplY3QncyBOb2RlIHByb3BlcnR5LgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBUaGUgRE9NIE5vZGUgdGhhdCB3aWxsIGNvbnRhaW4gdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdC4KLSAgICoKLSAgKiBAc2VlICNzZXROb2RlKE5vZGUpCi0gICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbShXcml0ZXIpCi0gICAqIEBzZWUgI3NldEJ5dGVTdHJlYW0oT3V0cHV0U3RyZWFtKQotICAgKiBAc2VlICNzZXRGaWxlTmFtZShTdHJpbmcpCi0gICAqIEBzZWUgI3NldERvY3VtZW50SGFuZGxlcihEb2N1bWVudEhhbmRsZXIpCi0gICAqIEBzZWUgI3NldEVuY29kaW5nKFN0cmluZykKLSAgICovCi0gIHB1YmxpYyBYU0xUUmVzdWx0VGFyZ2V0IChOb2RlIG4pCi0gIHsKLSAgICBkciA9IG5ldyBET01SZXN1bHQoKTsKLSAgICBkci5zZXROb2RlKG4pOwotICB9ICAgIAotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgb3V0cHV0IHRhcmdldCB3aXRoIGEgU0FYIERvY3VtZW50IGhhbmRsZXIsIHdoaWNoCi0gICAqIHdpbGwgaGFuZGxlIHJlc3VsdCBldmVudHMgLS0gdGhlIGVxdWl2YWxlbnQgb2YgY3JlYXRpbmcgYW4gb3V0cHV0IHRhcmdldCB3aXRoIHRoZQotICAgKiB6ZXJvLWFyZ3VtZW50IGNvbnN0cnVjdG9yIGFuZCBzZXR0aW5nIHRoZSBuZXcgb2JqZWN0J3MgRG9jeXVtZW50SGFuZGxlciBwcm9wZXJ0eS4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIFNBWCBEb2N1bWVudCBoYW5kbGVyIHRvIHdoaWNoIHRoZSByZXN1bHQgaXMgd3JpdHRlbi4KLSAgICoKLSAgKiBAc2VlICNzZXREb2N1bWVudEhhbmRsZXIoRG9jdW1lbnRIYW5kbGVyKQotICAgKiBAc2VlICNzZXROb2RlKE5vZGUpCi0gICAqIEBzZWUgI3NldENoYXJhY3RlclN0cmVhbShXcml0ZXIpCi0gICAqIEBzZWUgI3NldEJ5dGVTdHJlYW0oT3V0cHV0U3RyZWFtKQotICAgKiBAc2VlICNzZXRGaWxlTmFtZShTdHJpbmcpCi0gICAqIEBzZWUgI3NldEVuY29kaW5nKFN0cmluZykKLSAgICovCi0gIHB1YmxpYyBYU0xUUmVzdWx0VGFyZ2V0KERvY3VtZW50SGFuZGxlciBoYW5kbGVyKQotICB7IAotICAgIHNheFJlc3VsdCA9IG5ldyBTQVhSZXN1bHQoKTsgICAgCi0gICAgc2V0RG9jdW1lbnRIYW5kbGVyKGhhbmRsZXIpOwotICB9Ci0gICAgCi0KLSAgLyoqCi0gICAqIFNldCB0aGUgZmlsZSBuYW1lIG9yIFVSTCB3aGVyZSB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0IHdpbGwgYmUgd3JpdHRlbi4KLSAgICoKLSAgICogQHBhcmFtIGZpbGVOYW1lIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIHN0cmluZy4KLSAgICoKLSAgICogQHNlZSAjWFNMVFJlc3VsdFRhcmdldChTdHJpbmcpCi0gICAqIEBzZWUgI2dldEZpbGVOYW1lCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGaWxlTmFtZSAoU3RyaW5nIGZpbGVOYW1lKSAvLyBGaWxlPwotICB7Ci0gICAgaWYgKHNyID09IG51bGwpCi0gICAgICBzciA9IG5ldyBTdHJlYW1SZXN1bHQoKTsKLSAgICBzci5zZXRTeXN0ZW1JZChmaWxlTmFtZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZpbGUgbmFtZSB3aGVyZSB0aGUgcmVzdWx0cyBhcmUgb3Igd2lsbCBiZSB3cml0dGVuLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBmaWxlIG5hbWUgb3IgVVJMLgotICAgKgotICAgKiBAc2VlICNYU0xUUmVzdWx0VGFyZ2V0KFN0cmluZykKLSAgICogQHNlZSAjc2V0RmlsZU5hbWUoU3RyaW5nKQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSAoKQotICB7Ci0gICAgaWYgKHNyICE9IG51bGwpCi0gICAgICByZXR1cm4gc3IuZ2V0U3lzdGVtSWQoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfSAKLQotCi0KLSAgLyoqCi0gICAqIFNldCB0aGUgY2hhcmFjdGVyIGVuY29kaW5nLCBpZiBrbm93bi4KLSAgICoKLSAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyAoU3RyaW5nIGVuY29kaW5nKQotICB7Ci0gICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgdGhhdCB3YXMgdXNlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZW5jb2RpbmcsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3VwcGxpZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nICgpCi0gIHsKLSAgICByZXR1cm4gZW5jb2Rpbmc7Ci0gIH0KLSAgCi0gIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOwotCi0KLSAgLyoqCi0gICAqIFNldCBhIFNBWCBEb2N1bWVudEhhbmRsZXIgdG8gcHJvY2VzcyB0aGUgcmVzdWx0IHRyZWUgZXZlbnRzLgotICAgKiBZb3UgY2FuIHByb2Nlc3MgZXZlbnRzIGFzIHRoZXkgb2NjdXIKLSAgICogcmF0aGVyIHRoYW4gd2FpdGluZyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uIHRvIGJlIGNvbXBsZXRlZC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIFNBWCBEb2N1bWVudEhhbmRsZXIgdG8gcHJvY2VzcyByZXN1bHQgdHJlZSBldmVudHMuCi0gICAqCi0gICAqIEBzZWUgI1hTTFRSZXN1bHRUYXJnZXQoRG9jdW1lbnRIYW5kbGVyKQotICAgKiBAc2VlICNnZXREb2N1bWVudEhhbmRsZXIoKQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRIYW5kbGVyIChEb2N1bWVudEhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIHRoaXMuZm9ybWF0dGVyTGlzdGVuZXIgPSBoYW5kbGVyOwotCQlpZiAoaGFuZGxlciBpbnN0YW5jZW9mIFhTTFRFbmdpbmVJbXBsKQotCQkJc2F4UmVzdWx0LnNldEhhbmRsZXIoKChYU0xURW5naW5lSW1wbCloYW5kbGVyKS5nZXRUcmFuc2Zvcm1lcigpLmdldENvbnRlbnRIYW5kbGVyKCkpOwotICAgIGlmIChoYW5kbGVyIGluc3RhbmNlb2YgUGFyc2VyQWRhcHRlcikKLSAgICB7Ci0gICAgICBpZiAoc2F4UmVzdWx0ID09IG51bGwpCi0gICAgICAgIHNheFJlc3VsdCA9IG5ldyBTQVhSZXN1bHQoKTsKLSAgICAgIHNheFJlc3VsdC5zZXRIYW5kbGVyKCgoUGFyc2VyQWRhcHRlciloYW5kbGVyKS5nZXRDb250ZW50SGFuZGxlcigpKTsKLSAgICB9ICAKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFNBWCBEb2N1bWVudEhhbmRsZXIgdGhhdCBwcm9jZXNzZXMgdGhlIHJlc3VsdCB0cmVlIGV2ZW50cy4KLSAgICogWW91IGNhbiB1c2UgdGhlIERvY3VtZW50SGFuZGxlciB0byBwcm9jZXNzIGV2ZW50cyBhcyB0aGV5IG9jY3VyCi0gICAqIHJhdGhlciB0aGFuIHdhaXRpbmcgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbiB0byBiZSBjb21wbGV0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFNBWCBEb2N1bWVudEhhbmRsZXIgdGhhdCBwcm9jZXNzZXMgcmVzdWx0IHRyZWUgZXZlbnRzLgotICAgKgotICAgKiBAc2VlICNYU0xUUmVzdWx0VGFyZ2V0KERvY3VtZW50SGFuZGxlcikKLSAgICogQHNlZSAjc2V0RG9jdW1lbnRIYW5kbGVyKERvY3VtZW50SGFuZGxlcikKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEhhbmRsZXIgZ2V0RG9jdW1lbnRIYW5kbGVyICgpCi0gIHsKLSAgICByZXR1cm4gZm9ybWF0dGVyTGlzdGVuZXI7Ci0gIH0KLSAgCi0gIHByaXZhdGUgRG9jdW1lbnRIYW5kbGVyIGZvcm1hdHRlckxpc3RlbmVyID0gbnVsbDsKLSAgCi0gIC8qKgotICAgICAqIFNldCB0aGUgbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgcmVzdWx0IERPTSB0cmVlLiAgSW4gcHJhY3RpY2UsCi0gICAgICogdGhlIG5vZGUgc2hvdWxkIGJlIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50fSBub2RlLAotICAgICAqIGEge0BsaW5rIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnR9IG5vZGUsIG9yIGEKLSAgICAgKiB7QGxpbmsgb3JnLnczYy5kb20uRWxlbWVudH0gbm9kZS4gIEluIG90aGVyIHdvcmRzLCBhIG5vZGUKLSAgICAgKiB0aGF0IGFjY2VwdHMgY2hpbGRyZW4uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byB3aGljaCB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgKiB3aWxsIGJlIGFwcGVuZGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5vZGUoTm9kZSBub2RlKSB7Ci0gICAgICBpZiAoZHIgPT0gbnVsbCkKLSAgICAgICAgZHIgPSBuZXcgRE9NUmVzdWx0KCk7Ci0gICAgICBkci5zZXROb2RlKG5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbm9kZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgcmVzdWx0IERPTSB0cmVlLgotICAgICAqIElmIG5vIG5vZGUgd2FzIHNldCB2aWEgc2V0Tm9kZSwgdGhlIG5vZGUgd2lsbCBiZQotICAgICAqIHNldCBieSB0aGUgdHJhbnNmb3JtYXRpb24sIGFuZCBtYXkgYmUgb2J0YWluZWQgZnJvbQotICAgICAqIHRoaXMgbWV0aG9kIG9uY2UgdGhlIHRyYW5zZm9ybWF0aW9uIGlzIGNvbXBsZXRlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbm9kZSB0byB3aGljaCB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICAgKiB3aWxsIGJlIGFwcGVuZGVkLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlIGdldE5vZGUoKSB7Ci0gICAgICBpZiAoZHIgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIGRyLmdldE5vZGUoKTsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIAotIC8qKgotICAgKiBTZXQgdGhlIGJ5dGUgc3RyZWFtIHRvIGNvbnRhaW4gdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdC4KLSAgICoKLSAgICogQHBhcmFtIGJ5dGVTdHJlYW0gQSBieXRlIHN0cmVhbSB0aGF0IHdpbGwgY29udGFpbiB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0LgotICAgKgotICAgKiBAc2VlICNYU0xUUmVzdWx0VGFyZ2V0KE91dHB1dFN0cmVhbSkKLSAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbShPdXRwdXRTdHJlYW0pCi0gICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEJ5dGVTdHJlYW0oT3V0cHV0U3RyZWFtIGJ5dGVTdHJtKSB7Ci0gICAgICAgIGlmIChzciA9PSBudWxsKQotICAgICAgICAgIHNyID0gbmV3IFN0cmVhbVJlc3VsdCgpOwotICAgICAgICBzci5zZXRPdXRwdXRTdHJlYW0oYnl0ZVN0cm0pOwotICAgIH0KLQotIC8qKgotICAgKiBHZXQgdGhlIGJ5dGUgc3RyZWFtIHRoYXQgY29udGFpbnMgb3Igd2lsbCBjb250YWluIHRoZSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGJ5dGUgc3RyZWFtLCBvciBudWxsIGlmIG5vbmUgd2FzIHN1cHBsaWVkLgotICAgKgotICAgKiBAc2VlICNYU0xUUmVzdWx0VGFyZ2V0KE91dHB1dFN0cmVhbSkKLSAgICogQHNlZSAjc2V0Qnl0ZVN0cmVhbShPdXRwdXRTdHJlYW0pCi0gICAqLwotICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0Qnl0ZVN0cmVhbSgpIHsKLSAgICAgIGlmIChzciAhPSBudWxsKQotICAgICAgICByZXR1cm4gc3IuZ2V0T3V0cHV0U3RyZWFtKCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGlzIFJlc3VsdC4KLSAgICAgKgotICAgICAqIDxwPklmIHRoZSBSZXN1bHQgaXMgbm90IHRvIGJlIHdyaXR0ZW4gdG8gYSBmaWxlLCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgb3B0aW9uYWwuCi0gICAgICogVGhlIGFwcGxpY2F0aW9uIG1heSBzdGlsbCB3YW50IHRvIHByb3ZpZGUgb25lLCBob3dldmVyLCBmb3IgdXNlIGluIGVycm9yIG1lc3NhZ2VzCi0gICAgICogYW5kIHdhcm5pbmdzLCBvciB0byByZXNvbHZlIHJlbGF0aXZlIG91dHB1dCBpZGVudGlmaWVycy48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIGFzIGEgVVJJIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSUQpCi0gICAgewotICAgICAgaWYgKHNyICE9IG51bGwpCi0gICAgICAgIHNyLnNldFN5c3RlbUlkKHN5c3RlbUlEKTsKLSAgICAgIGVsc2UgaWYgKGRyICE9IG51bGwpCi0gICAgICAgIGRyLnNldFN5c3RlbUlkKHN5c3RlbUlEKTsKLSAgICAgIGVsc2UgaWYgKHNheFJlc3VsdCAhPSBudWxsKQotICAgICAgICBzYXhSZXN1bHQuc2V0U3lzdGVtSWQoc3lzdGVtSUQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZCwKLSAgICAgKiBvciBudWxsIGlmIHNldFN5c3RlbUlkIHdhcyBub3QgY2FsbGVkLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKQotICAgIHsKLSAgICAgIGlmIChzciAhPSBudWxsKQotICAgICAgICByZXR1cm4gc3IuZ2V0U3lzdGVtSWQoKTsKLSAgICAgIGVsc2UgaWYgKGRyICE9IG51bGwpCi0gICAgICAgIGRyLmdldFN5c3RlbUlkKCk7Ci0gICAgICBlbHNlIGlmIChzYXhSZXN1bHQgIT0gbnVsbCkKLSAgICAgICAgc2F4UmVzdWx0LmdldFN5c3RlbUlkKCk7Ci0gICAgICAKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICAKLSAgICAgLyoqCi0gICAgICogU2V0IHRoZSB3cml0ZXIgdGhhdCBpcyB0byByZWNlaXZlIHRoZSByZXN1bHQuICBOb3JtYWxseSwKLSAgICAgKiBhIHN0cmVhbSBzaG91bGQgYmUgdXNlZCByYXRoZXIgdGhhbiBhIHdyaXRlciwgc28gdGhhdAotICAgICAqIHRoZSB0cmFuc2Zvcm1lciBtYXkgdXNlIGluc3RydWN0aW9ucyBjb250YWluZWQgaW4gdGhlCi0gICAgICogdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zIHRvIGNvbnRyb2wgdGhlIGVuY29kaW5nLiAgSG93ZXZlciwKLSAgICAgKiB0aGVyZSBhcmUgdGltZXMgd2hlbiBpdCBpcyB1c2VmdWwgdG8gd3JpdGUgdG8gYSB3cml0ZXIsCi0gICAgICogc3VjaCBhcyB3aGVuIHVzaW5nIGEgU3RyaW5nV3JpdGVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHdyaXRlciAgQSB2YWxpZCBXcml0ZXIgcmVmZXJlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENoYXJhY3RlclN0cmVhbShXcml0ZXIgd3JpdGVyKSB7ICAgICAgCi0gICAgICBpZiAoc3IgPT0gbnVsbCkKLSAgICAgICAgc3IgPSBuZXcgU3RyZWFtUmVzdWx0KCk7Ci0gICAgICBzci5zZXRXcml0ZXIod3JpdGVyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGNoYXJhY3RlciBzdHJlYW0gdGhhdCB3YXMgc2V0IHdpdGggc2V0V3JpdGVyLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIHN0cmVhbSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRXcml0ZXIsIG9yIG51bGwKLSAgICAgKiBpZiBzZXRXcml0ZXIgb3IgdGhlIFdyaXRlciBjb25zdHJ1Y3RvciB3YXMgbm90IGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgV3JpdGVyIGdldENoYXJhY3RlclN0cmVhbSgpIHsKLSAgICAgIGlmIChzciAhPSBudWxsKQotICAgICAgICByZXR1cm4gc3IuZ2V0V3JpdGVyKCk7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgCi0gIAotICAgIC8qKgotICAgICAqIEdldCB0aGUgUmVzdWx0IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBYU0xUUmVzdWx0VGFyZ2V0IG9iamVjdCAuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBSZXN1bHQgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIFhTTFRSZXN1bHRUYXJnZXQgb2JqZWN0Ci0gICAgICogCi0gICAgICovCi0gICAgcHVibGljIFJlc3VsdCBnZXRSZXN1bHRPYmplY3QoKSAKLSAgICB7Ci0gICAgICBpZiAoc3IgIT0gbnVsbCkgICAgICAgIAotICAgICAgICByZXR1cm4gc3I7Ci0gICAgICBlbHNlIGlmIChkciAhPSBudWxsKQotICAgICAgICByZXR1cm4gZHI7Ci0gICAgICBlbHNlIAotICAgICAgICByZXR1cm4gc2F4UmVzdWx0OwotICAgIH0gCi0gICAgCi19CmRpZmYgLS1naXQgYS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9wYWNrYWdlLmh0bWwgYi9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc2ZTM5ZjIuLjAwMDAwMDAKLS0tIGEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTggKzAsMCBAQAotPEhUTUw+PEhFQUQ+PC9IRUFEPjxCT0RZPgotICAgICA8UD48Qj5UaGUgbWFpbiBYYWxhbi1KYXZhIDEgY29tcGF0YWJpbGl0eSBwYWNrYWdlPC9CPiAtLSBmYWNpbGl0aWVzIGZvciBzZXR0aW5nIHVwIGFuZCBwZXJmb3JtaW5nIFhTTCB0cmFuc2Zvcm1hdGlvbnMuPC9QPgotICAgCi0gICAgIDxQPlVzZSBvbmUgb2YgdGhlIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFByb2Nlc3NvckZhY3Rvcnl9IHN0YXRpYyBnZXRQcm9jZXNzb3IgbWV0aG9kcyB0bwotICAgICAgaW5zdGFudGlhdGUgYW4ge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xUUHJvY2Vzc29yfS4gVGhlIFhTTFRQcm9jZXNzb3IgaW50ZXJmYWNlIGRlZmluZXMgdGhlIAotICAgICAgWFNMVCBwcm9jZXNzb3IgQVBJLiBZb3Ugc2hvdWxkIG5ldmVyIG5lZWQgdG8gY2FsbCB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiAKLSAgICAgICh7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRFbmdpbmVJbXBsfSkgZGlyZWN0bHkuPC9QPgotICAgICAgCi0gICAgICA8UD5JbnN0YW50aWF0ZSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54c2x0LlhTTFRJbnB1dFNvdXJjZX0gb2JqZWN0cyBmb3IgdGhlIFhNTCBpbnB1dCBhbmQgdGhlIFhTTAotICAgICAgc3R5bGVzaGVldCwgYW5kIGFuIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuWFNMVFJlc3VsdFRhcmdldH0gb2JqZWN0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24gb3V0cHV0LiAKLSAgICAgIFlvdSBtYXkgY29uc3RydWN0IHRoZXNlIG9iamVjdHMgd2l0aCBhIHZhcmlldHkgb2YgY29udGFpbmVycy9mb3JtYXRzLCBpbmNsdWRpbmcgZmlsZXMgb3IgVVJMcywgY2hhcmFjdGVyCi0gICAgICBzdHJlYW1zLGJ5dGUgc3RyZWFtcywgU0FYIGlucHV0IHN0cmVhbXMgb3IgZG9jdW1lbnQgaGFuZGxlcnMsIGFuZCBhIERPTSB0cmVlLjwvUD4KLSAgICAgIDxQPkFzIGEgZ2VuZXJhbCBydWxlLCB1c2UgdGhlIFhTTFRQcm9jZXNzb3IgcHJvY2VzcyBtZXRob2QgdG8gcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uLCB0aGVyZWJ5IGZpbGxpbmcgdGhlCi0gICAgICBYU0xUUmVzdWx0VGFyZ2V0IG9iamVjdC4gRm9yIHJlcGVhdGVkIHRyYW5zZm9ybWF0aW9ucywgdG8gZ2F0aGVyIGluZm9ybWF0aW9uIGZyb20gdGhlIHN0eWxlc2hlZXQgYmVmb3JlIHlvdQotICAgICAgcGVyZm9ybSB0aGUgdHJhbnNmb3JtYXRpb24sIG9yIHRvIHNldCB1cCB0aGUgcHJvY2Vzc29yIHRvIGZ1bmN0aW9uIGFzIGEgU0FYIGRvY3VtZW50IGhhbmRsZXIsIHVzZSB0aGUKLSAgICAgICBYU0xUUHJvY2Vzc29yIHByb2Nlc3NTdHlsZXNoZWV0IG1ldGhvZCB0byBjb21waWxlIHRoZSBYU0wgc3R5bGVzaGVldCwgd2hpY2ggcmV0dXJucyBhIAotICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuU3R5bGVzaGVldFJvb3R9IG9iamVjdCB3aXRoIGl0cyBvd24gcHJvY2VzcyBtZXRob2QuPC9QPgotICAgPC9CT0RZPjwvSFRNTD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9yZWFkbWUuaHRtbCBiL3JlYWRtZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYWU0OGFkLi4wMDAwMDAwCi0tLSBhL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjQgKzAsMCBAQAotCi0KLTxodG1sPgotPGhlYWQ+Ci08dGl0bGU+Ci08L3RpdGxlPgotPC9oZWFkPgotPGJvZHk+Ci08bWV0YSBjb250ZW50PSIwOyBVUkw9ZG9jcy93aGF0c25ldy5odG1sIiBodHRwLWVxdWl2PSJSZWZyZXNoIj4KLSAgICAgIFJlZGlyZWN0aW5nIHRvIDxhIGhyZWY9ImRvY3Mvd2hhdHNuZXcuaHRtbCI+V2hhdCdzIE5ldyBpbiBYYWxhbl9KYXZhIDI8L2E+Ci08L2JvZHk+Ci08L2h0bWw+Ci0KLQotCi0KLSAgICAgICAgICAgIAotICAgICAgICAgICAgCi0KLQotCi0KLSAgICAgICAgICAgIAotICAgCmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9SRUFETUUuaHRtbCBiL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML1JFQURNRS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMGI1ODRkLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML1JFQURNRS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjQgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+PC90aXRsZT5YYWxhbiBTYW1wbGUgQXBwbGV0czwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keSBiZ2NvbG9yPSIjODA4MDgwIiB0ZXh0PSIjZmZmZmZmIj4KLSAgPHRhYmxlPgotICAgIDx0cj4KLSAgICAgIDx0ZD48aW1nIGJvcmRlcj0iMCIgaHNwYWNlPSIwIiB2c3BhY2U9IjAiIGFsaWduPSJsZWZ0IiBzcmM9InJhYmJpdHdob3JuLmpwZyI+PC90ZD4KLSAgICAgIDx0ZD48aDI+Jm5ic3A7UnVubmluZyB0aGUgWGFsYW4gc2FtcGxlIGFwcGxldHM8L2gyPjwvdGQ+Ci0gICAgPC90cj4KLSAgPC90YWJsZT4KLSAgPGhyPgotICA8dWw+Ci0gIDxsaT5hcHBsZXRYTUx0b0hUTUwuaHRtbCB0cmFuc2Zvcm1zIFhNTCBpbnRvIEhUTUwsIGFuZCBkaXNwbGF5cyB0aGUgWE1MIGRvY3VtZW50IGFuZCBYU0wgc3R5bGVzaGVldCBhcyB3ZWxsIGFzIHRoZSBIVE1MIHRyYW5zZm9ybWF0aW9uIHJlc3VsdC48YnIvPjxici8+PC9saT4KLSAgPGxpPmdldC10b2RvLWxpc3QuaHRtbCB1c2VzIHRvZG8ueHNsIHRvIHRyYW5zZm9ybSB0b2RvLnhtbCBhbmQgZGlzcGxheSB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0LiBUaGUgWE1MIHNvdXJjZSBpcyBhIHNuYXBzaG90IG9mIHRvZG8ueG1sIGluIHRoZSB4bWwteGFsYW4gQ1ZTIHJlcG9zaXRvcnksIGFuIG9uZ29pbmcgbGlzdCBvZiB0YXNrcyBhbmQgdGFzayBjb21wbGV0aW9ucyBmb3IgdGhlIFhhbGFuLUphdmEgMiBkZXZlbG9wbWVudCBwcm9qZWN0LjwvbGk+Ci0gIDxwPkJvdGggYXBwbGV0cyBsb29rIGZvciB4YWxhbi5qYXIgYW5kIHhlcmNlcy5qYXIgaW4gdGhlIGJpbiBkaXJlY3RvcnkuIElmIHRoZSBKQVIgZmlsZXMgYXJlIGVsc2V3aGVyZSwgeW91IG11c3QgbW92ZSB0aGVtIG9yIGFkanVzdCB0aGUgYXBwbGV0IGFyY2hpdmUgc2V0dGluZyBpbiBjbGllbnQuaHRtbCBhbmQgZ2V0LXRvZG8tbGlzdC5odG1sLjwvcD4KLTwvdWw+Ci08cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNhbXBsZXMgKHdoYXQgdGhleSBpbGx1c3RyYXRlIGFuZCBob3cgdG8gcnVuIHRoZW0pLCBzZWUgPGEgaHJlZj0iLi4vLi4vZG9jcy9zYW1wbGVzLmh0bWwiPlNhbXBsZXM8L2E+LjwvcD4KLQotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9hcHBsZXRYTUx0b0hUTUwuaHRtbCBiL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML2FwcGxldFhNTHRvSFRNTC5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYWFhOTAwLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML2FwcGxldFhNTHRvSFRNTC5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTYgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+VXNpbmcgYW4gYXBwbGV0IHRvIHBlcmZvcm0gWFNMIHRyYW5zZm9ybWF0aW9uczwvdGl0bGU+Ci08L2hlYWQ+Ci0gIDxGUkFNRVNFVCBST1dTPSIxMjUsKiIgPgotICAgIDxGUkFNRSBOQU1FPSJwcm9jZXNzb3IiIFNSQz0iY2xpZW50Lmh0bWwiIFNDUk9MTElORz0iYXV0byIgPgotICAgICAgPGZyYW1lc2V0IGNvbHM9IjMzJSwgMzMlLCAqIj4KLSAgICAgICAgPEZSQU1FIE5BTUU9InRhcmdldEFyZWEwIiBTUkM9InRhcmdldC5odG1sIiA+Ci0gICAgICAgIDxGUkFNRSBOQU1FPSJ0YXJnZXRBcmVhMSIgU1JDPSJ0YXJnZXQuaHRtbCIgPgotICAgICAgICA8RlJBTUUgTkFNRT0idGFyZ2V0QXJlYTIiIFNSQz0idGFyZ2V0Lmh0bWwiID4gICAgICAgIAotICAgICAgPC9mcmFtZXNldD4KLSAgPC9GUkFNRVNFVD4KLQotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvY2xpZW50Lmh0bWwgYi9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9jbGllbnQuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDBhNDM4Mi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9jbGllbnQuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEyMSArMCwwIEBACi08IWRvY3R5cGUgSFRNTCBwdWJsaWMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotPGh0bWw+Ci0gIDxoZWFkPgotCSAgPHRpdGxlPlVudGl0bGVkPC90aXRsZT4KLSAgPC9oZWFkPgotICA8c2NyaXB0IGxhbmd1YWdlPSJKYXZhU2NyaXB0Ij4KLQotICAgIAotICAgIGZ1bmN0aW9uIHdyaXRlU291cmNlKHNvdXJjZVN0cmluZykKLSAgICB7Ci0KLSAgICAgIHZhciBlc2NTdHJpbmc9ZG9jdW1lbnQueHNsQ29udHJvbC5lc2NhcGVTdHJpbmcoc291cmNlU3RyaW5nKTsKLSAgICAgIHZhciB0aXRsZT0iWE1MIFNvdXJjZSBEb2MiOwotICAgICAgdmFyIGRvYz10b3AuZnJhbWVzWzFdLmRvY3VtZW50OyAgICAgIAotICAgICAgZG9jLm9wZW4oKTsKLSAgICAgIGRvYy53cml0ZSgiPGgzPiIgKyB0aXRsZSArICI8L2gzPiIpOwotICAgICAgZG9jLndyaXRlKCI8UFJFPiIpOwotICAgICAgZG9jLndyaXRlKGVzY1N0cmluZyk7Ci0gICAgICBkb2Mud3JpdGUoIjwvUFJFPiIpOwotICAgICAgZG9jLmNsb3NlKCk7ICAgIAotICAgIH0KLSAgCi0gICAgZnVuY3Rpb24gd3JpdGVTdHlsZXNoZWV0KHN0eWxlU3RyaW5nKQotICAgIHsKLSAgICAgIHZhciBlc2NTdHJpbmc9ZG9jdW1lbnQueHNsQ29udHJvbC5lc2NhcGVTdHJpbmcoc3R5bGVTdHJpbmcpOwotICAgICAgdmFyIHRpdGxlPSJYU0wgU3R5bGVzaGVldCI7Ci0gICAgICB2YXIgZG9jPXRvcC5mcmFtZXNbMl0uZG9jdW1lbnQ7ICAgICAgICAgIAotICAgICAgZG9jLm9wZW4oKTsKLSAgICAgIGRvYy53cml0ZSgiPGgzPiIgKyB0aXRsZSArICI8L2gzPiIpOwotICAgICAgZG9jLndyaXRlKCI8UFJFPiIpOwotICAgICAgZG9jLndyaXRlKGVzY1N0cmluZyk7Ci0gICAgICBkb2Mud3JpdGUoIjwvUFJFPiIpOwotICAgICAgZG9jLmNsb3NlKCk7ICAgICAKLSAgICB9IAotCi0gICAgZnVuY3Rpb24gd3JpdGVUYXJnZXQodGFyZ2V0U3RyaW5nKQotICAgIHsKLSAgICAgIHZhciBkb2M9dG9wLmZyYW1lc1szXS5kb2N1bWVudDsKLSAgICAgIGRvYy5vcGVuKCk7Ci0gICAgICB2YXIgdGl0bGU9IkhUTUwgT3V0cHV0IjsgICAgICAKLSAgICAgIGRvYy53cml0ZSgiPGgzPiIgKyB0aXRsZSArICI8L2gzPiIpOwotICAgICAgaWYgKGRvY3VtZW50LnhtbFRyYW5zZm9ybS5kaXNwbGF5TW9kZVswXS5jaGVja2VkKSAvL2Rpc3BsYXkgSFRNTAotICAgICAgewotICAgICAgICBkb2Mud3JpdGUodGFyZ2V0U3RyaW5nKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgLy8gZGlzcGxheSBzb3VyY2UKLSAgICAgIHsKLSAgICAgICAgdmFyIGVzY1N0cmluZz1kb2N1bWVudC54c2xDb250cm9sLmVzY2FwZVN0cmluZyh0YXJnZXRTdHJpbmcpOwotICAgICAgICBkb2Mud3JpdGUoIjxQUkU+Iik7Ci0gICAgICAgIGRvYy53cml0ZShlc2NTdHJpbmcpOwotICAgICAgICBkb2Mud3JpdGUoIjwvUFJFPiIpOwotICAgICAgfQotICAgICAgZG9jLmNsb3NlKCk7ICAgIAotICAgIH0KLSAgCi0gICAgZnVuY3Rpb24gY2xlYXJGcmFtZXMoKQotICAgIHsKLSAgICAgIGRvY3VtZW50LnhzbENvbnRyb2wuZnJlZUNhY2hlKCk7Ci0gICAgICBmb3IgKGk9MTsgaTw0OyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgdmFyIGRvYz10b3AuZnJhbWVzW2ldLmRvY3VtZW50OwotICAgICAgICBkb2Mub3BlbigpOwotICAgICAgICBkb2MuY2xlYXIoKTsKLSAgICAgICAgZG9jLmNsb3NlKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0gIAotICAgIGZ1bmN0aW9uIHRyYW5zZm9ybSgpCi0gICAgeyAgCi0gICAgICBjbGVhckZyYW1lcygpOwotICAgICAgdmFyIHhtbFNvdXJjZT1kb2N1bWVudC54bWxUcmFuc2Zvcm0ueG1sU291cmNlTGlzdC5vcHRpb25zW2RvY3VtZW50LnhtbFRyYW5zZm9ybS54bWxTb3VyY2VMaXN0LnNlbGVjdGVkSW5kZXhdLnZhbHVlOwotICAgICAgZG9jdW1lbnQueHNsQ29udHJvbC5zZXREb2N1bWVudFVSTCh4bWxTb3VyY2UpOwotICAgICAgdmFyIHNvdXJjZVN0cmluZz1kb2N1bWVudC54c2xDb250cm9sLmdldFNvdXJjZVRyZWVBc1RleHQoKTsKLSAgICAgIHZhciBzdHlsZVN0cmluZz1kb2N1bWVudC54c2xDb250cm9sLmdldFN0eWxlVHJlZUFzVGV4dCgpOwotICAgICAgdmFyIHRhcmdldFN0cmluZz1kb2N1bWVudC54c2xDb250cm9sLmdldEh0bWxUZXh0KCk7ICAgICAgCi0gICAgICB3cml0ZVNvdXJjZShzb3VyY2VTdHJpbmcpOwotICAgICAgd3JpdGVTdHlsZXNoZWV0KHN0eWxlU3RyaW5nKTsKLSAgICAgIHdyaXRlVGFyZ2V0KHRhcmdldFN0cmluZyk7Ci0gICAgfQotICA8L3NjcmlwdD4KLSAgPGJvZHkgb25Mb2FkPSJjbGVhckZyYW1lcygpOyIgYmdjb2xvcj0iIzgwODA4MCIgdGV4dD0iI2ZmZmZmZiI+Ci0gICAgPGZvcm0gbmFtZT0ieG1sVHJhbnNmb3JtIiBhY3Rpb249IiIgbWV0aG9kPSJQT1NUIj4KLSAgICAgIDxoMj48aW1nIGJvcmRlcj0iMCIgaHNwYWNlPSIwIiB2c3BhY2U9IjAiIGFsaWduPSJsZWZ0IiBzcmM9InJhYmJpdHdob3JuLmpwZyI+Jm5ic3A7VHJhbnNmb3JtIFhNTCBEb2N1bWVudDwvaDI+Ci0gICAgICAgIDx0YWJsZT4KLSAgICAgICAgICA8dHI+Ci0gICAgICAgICAgICA8dGQgd2lkdGg9IjUwIj48L3RkPgotICAgICAgICAgICAgPHRkIGFsaWduPSJjZW50ZXIiPjxpPkRvY3VtZW50IHRvIHRyYW5zZm9ybTwvaT48L3RkPgotICAgICAgICAgICAgPHRkIGFsaWduPSJjZW50ZXIiPjxpPkRpc3BsYXkgb3V0cHV0IGFzPC9pPjwvdGQ+Ci0gICAgICAgICAgPC90cj4KLSAgICAgICAgICA8dHI+Ci0gICAgICAgICAgPHRkPjwvdGQ+Ci0gICAgICAgICAgPHRkIGFsaWduPSJjZW50ZXIiPgotICAgICAgICAgICAgPHNlbGVjdCBuYW1lPSJ4bWxTb3VyY2VMaXN0Ij4KLSAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ieGFsYW5BcHBsZXRzLnhtbCIgc2VsZWN0ZWQ+Jm5ic3A7eGFsYW5BcHBsZXRzLnhtbCZuYnNwOwotICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJmb28tczEueG1sIj4mbmJzcDtmb28tczEueG1sJm5ic3A7Ci0gICAgICAgICAgICA8L3NlbGVjdD4KLSAgICAgICAgICA8L3RkPgotICAgICAgICAgIDx0ZCBhbGlnbj0iY2VudGVyIj4KLSAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZGlzcGxheU1vZGUiIGNoZWNrZWQ+SFRNTCZuYnNwOyZuYnNwOwotICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkaXNwbGF5TW9kZSI+SFRNTCBTb3VyY2UKLSAgICAgICAgICA8L3RkPgotICAgICAgICAgIDx0ZD4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsKLSAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIG5hbWU9InRyYW5zZm9ybUJ1dHRvbiIgdmFsdWU9IlRyYW5zZm9ybSIgCi0gICAgICAgICAgICBvbkNsaWNrPSJ0cmFuc2Zvcm0oKTsiPgotICAgICAgICAgIDwvdGQ+Ci0gICAgICAgIDwvdHI+Ci0gICAgICA8L3RhYmxlPgotICAgIDwvZm9ybT4KLSAgICA8IS0tIEJlIHN1cmUgeW91IGhhdmUgYXBwbGV0IGFyY2hpdmUgYXR0cmlidXRlIHNldAotICAgICAgICAgc28gdGhlIGFwcGxldCBjYW4gZmluZCB4YWxhbi5qYXIgYW5kIHhlcmNlcy5qYXIgLS0+ICAKLSAgICA8YXBwbGV0ICAKLSAgICAgIG5hbWU9InhzbENvbnRyb2wiCi0gICAgICBjb2RlPSJvcmcuYXBhY2hlLnhhbGFuLmNsaWVudC5YU0xUUHJvY2Vzc29yQXBwbGV0LmNsYXNzIgotICAgICAgYXJjaGl2ZT0iLi4vLi4vYmluL3hhbGFuLmphciwuLi8uLi9iaW4veGVyY2VzLmphciIKLSAgICAgIGhlaWdodD0iMCIKLSAgICAgIHdpZHRoIjAiPgotICAgICAgPHBhcmFtIG5hbWU9ImRvY3VtZW50VVJMIiB2YWx1ZT0ieGFsYW5BcHBsZXRzLnhtbCIvPiAgPCEtLWRlZmF1bHQgc2V0dGluZy0tPgotICAgICAgPHBhcmFtIG5hbWU9InN0eWxlVVJMIiB2YWx1ZT0iczFUb0hUTUwueHNsIi8+IDwhLS1kb2Vzbid0IGNoYW5nZS0tPgotICAgIDwvYXBwbGV0PgotICA8L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9mb28tczEueG1sIGIvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvZm9vLXMxLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZThjZTAzMy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9mb28tczEueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxzMSB0aXRsZT0iczEgZm9vIj4KLSAgPHMyIHRpdGxlPSJGb28iPgotICAgIDxwPkhlbGxvPC9wPgotICA8L3MyPgotPC9zMT4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9nZXQtdG9kby1saXN0Lmh0bWwgYi9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9nZXQtdG9kby1saXN0Lmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMwZDkwNzMuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvZ2V0LXRvZG8tbGlzdC5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjYgKzAsMCBAQAotIDwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+Ci0KLTxodG1sPgotICA8aGVhZD4KLQk8dGl0bGU+WGFsYW4tSmF2YSAyICJ0byBkbyIgbGlzdDwvdGl0bGU+Ci0gIDwvaGVhZD4KLSAgPHNjcmlwdCBsYW5ndWFnZT0iSmF2YVNjcmlwdCI+Ci0gCi0gICAgZnVuY3Rpb24gdHJhbnNmb3JtKCkKLSAgICB7IAotICAgICAgdmFyIHRvZG9saXN0ID0geHNsQ29udHJvbC5nZXRIdG1sVGV4dCgpOwotICAgICAgZG9jdW1lbnQud3JpdGUodG9kb2xpc3QpOwotICAgIH0KLSAgPC9zY3JpcHQ+Ci0gIDxib2R5IG9uTG9hZD0idHJhbnNmb3JtKCk7Ij4KLSAgICA8YXBwbGV0ICAKLSAgICAgIG5hbWU9InhzbENvbnRyb2wiCi0gICAgICBjb2RlPSJvcmcuYXBhY2hlLnhhbGFuLmNsaWVudC5YU0xUUHJvY2Vzc29yQXBwbGV0LmNsYXNzIgotICAgICAgYXJjaGl2ZT0iLi4vLi4vYmluL3hhbGFuLmphciwuLi8uLi9iaW4veGVyY2VzLmphciIKLSAgICAgIGhlaWdodD0iMCIKLSAgICAgIHdpZHRoPSIwIj4KLSAgICAgIDxwYXJhbSBuYW1lPSJkb2N1bWVudFVSTCIgdmFsdWU9Ii4uLy4uL3RvZG8ueG1sIi8+IAotICAgICAgPHBhcmFtIG5hbWU9InN0eWxlVVJMIiB2YWx1ZT0iLi4vLi4vdG9kby54c2wiLz4KLSAgICA8L2FwcGxldD4KLSAgPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvbHRzMzYxMWJlYWMuanBnIGIvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvbHRzMzYxMWJlYWMuanBnCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMjQ5MTQ5Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML2x0czM2MTFiZWFjLmpwZworKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLU9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTwpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML3JhYmJpdHdob3JuLmpwZyBiL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML3JhYmJpdHdob3JuLmpwZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDU0NGEzOC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9yYWJiaXR3aG9ybi5qcGcKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9zMVRvSFRNTC54c2wgYi9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC9zMVRvSFRNTC54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI2MDVlNmYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvczFUb0hUTUwueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMTQxICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLz4KLSAgICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzMSI+Ci0gICAgPGh0bWw+Ci0gICAgICA8aGVhZD48dGl0bGU+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0aXRsZSIvPjwvdGl0bGU+PC9oZWFkPgotICAgICAgPGJvZHkgIGJnY29sb3I9IiNmZmZmZmYiIHRleHQ9IiMwMDAwMDAiPgotICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9InMyIi8+Ci0gICAgICA8L2JvZHk+Ci0gICAgPC9odG1sPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzMiI+Ci0gICAgPHRhYmxlIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iNCI+Ci0gICAgICA8dHI+Ci0gICAgICAgIDx0ZCBiZ2NvbG9yPSIjMDA2Njk5Ij4KLSAgICAgICAgICA8Zm9udCBjb2xvcj0iI2ZmZmZmZiIgc2l6ZT0iKzEiPgotICAgICAgICAgICAgPGI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0aXRsZSIvPjwvYj4KLSAgICAgICAgICA8L2ZvbnQ+Ci0gICAgICAgIDwvdGQ+Ci0gICAgICA8L3RyPgotICAgIDwvdGFibGU+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgIDxici8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InAiPgotICAgIDxwPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L3A+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Im5vdGUiPgotICAgIDx0YWJsZSBib3JkZXI9IjAiIHdpZHRoPSIxMDAlIj4KLSAgICAgIDx0cj4KLSAgICAgICAgPHRkIHdpZHRoPSIyMCI+JiMxNjA7PC90ZD4KLSAgICAgICAgPHRkIGJnY29sb3I9IiM4OGFhY2MiPgotICAgICAgICAgIDxmb250IHNpemU9Ii0xIj48aT5OT1RFOiA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9pPjwvZm9udD4KLSAgICAgICAgPC90ZD4KLSAgICAgICAgPHRkIHdpZHRoPSIyMCI+JiMxNjA7PC90ZD4KLSAgICAgIDwvdHI+Ci0gICAgPC90YWJsZT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ1bCI+Ci0gICAgPHVsPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L3VsPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJvbCI+Ci0gICAgPG9sPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L29sPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Imdsb3NzIj4KLSAgICA8ZGw+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvZGw+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAgPCEtLSA8dGVybT4gY29udGFpbnMgYSBzaW5nbGUtd29yZCwgbXVsdGktd29yZCBvciBzeW1ib2xpYyAKLSAgICAgICBkZXNpZ25hdGlvbiB3aGljaCBpcyByZWdhcmRlZCBhcyBhIHRlY2huaWNhbCB0ZXJtLiAtLT4gCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InRlcm0iPgotICAgIDxkZm4+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvZGZuPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJsYWJlbCIgcHJpb3JpdHk9IjEiPgotICAgIDxkdD48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9kdD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iaXRlbSIgcHJpb3JpdHk9IjIiPgotICAgIDxkZD4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICA8L2RkPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0YWJsZSI+Ci0gICAgPHAgYWxpZ249ImNlbnRlciI+PHRhYmxlIGJvcmRlcj0iMCI+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvdGFibGU+PC9wPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzb3VyY2UiPgotICAgIDx0YWJsZSBib3JkZXI9IjAiIHdpZHRoPSIxMDAlIj4KLSAgICAgIDx0cj4KLSAgICAgICAgPHRkIHdpZHRoPSIyMCI+JiMxNjA7PC90ZD4KLSAgICAgICAgPHRkIGJnY29sb3I9IiM4OGFhY2MiPjxwcmU+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvcHJlPjwvdGQ+Ci0gICAgICAgIDx0ZCB3aWR0aD0iMjAiPiYjMTYwOzwvdGQ+Ci0gICAgICA8L3RyPgotICAgIDwvdGFibGU+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImxpIj4KLSAgICA8bGk+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvbGk+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InRyIj4KLSAgICA8dHI+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvdHI+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InRoIj4KLSAgICA8dGQgYmdjb2xvcj0iIzAwNjY5OSIgYWxpZ249ImNlbnRlciI+Ci0gICAgICA8Zm9udCBjb2xvcj0iI2ZmZmZmZiI+PGI+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvYj48L2ZvbnQ+Ci0gICAgPC90ZD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGQiPgotICAgIDx0ZCBiZ2NvbG9yPSIjODhhYWNjIj48eHNsOmFwcGx5LXRlbXBsYXRlcy8+JiMxNjA7PC90ZD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idG4iPgotICAgIDx0ZD4mIzE2MDs8L3RkPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJlbSI+Ci0gICAgPGI+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvYj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icmVmIj4KLSAgICA8aT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9pPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJjb2RlIj4KLSAgICA8Y29kZT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9jb2RlPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJiciI+Ci0gICAgPGJyLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJqdW1wIj4KLSAgICA8YSBocmVmPSJ7QGhyZWZ9IiB0YXJnZXQ9Il90b3AiPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2E+Ci0gIDwveHNsOnRlbXBsYXRlPiAgCi0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iYW5jaG9yIj4KLSAgICA8YSBuYW1lPSJ7QGlkfSI+IDwvYT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iaW1nIj4KLSAgICA8aW1nIHNyYz0ie0BzcmN9IiBhbGlnbj0icmlnaHQiIGJvcmRlcj0iMCIgdnNwYWNlPSI0IiBoc3BhY2U9IjQiLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGxldFhNTHRvSFRNTC90YXJnZXQuaHRtbCBiL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML3RhcmdldC5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYTg1NDVjLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML3RhcmdldC5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsNyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotPGh0bWw+Ci0gIDxoZWFkPgotICAgIDx0aXRsZT5VbnRpdGxlZDwvdGl0bGU+Ci0gIDwvaGVhZD4KLSAgPGJvZHk+Jm5ic3A7PC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwveGFsYW5BcHBsZXRzLnhtbCBiL3NhbXBsZXMvQXBwbGV0WE1MdG9IVE1ML3hhbGFuQXBwbGV0cy54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVmODZmYzEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwveGFsYW5BcHBsZXRzLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDI2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTxzMSB0aXRsZT0iQWJvdXQgWGFsYW4gQXBwbGV0cyI+Ci0gIDxzMiB0aXRsZT0iVHJhbnNmb3JtaW5nIFhNTCB0byBIVE1MIGluIGFuIEFwcGxldCI+Ci0gICAgPG9sPiAKLSAgICAgIDxsaT4KLSAgICAgICAgPHA+SW5jbHVkZQotICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuY2xpZW50LlhTTFRQcm9jZXNzb3JBcHBsZXQKLSAgICAgICAgaW4gYW4gSFRNTCBjbGllbnQuPC9wPgotICAgICAgPC9saT4KLSAgICAgIDxsaT4KLSAgICAgICAgPHA+U3BlY2lmeSB0aGUgWE1MIHNvdXJjZSBkb2N1bWVudCBhbmQgWFNMCi0gICAgICAgIHN0eWxlc2hlZXQuPC9wPgotICAgICAgICA8cD5Zb3UgY2FuIHVzZSB0aGUgRG9jdW1lbnRVUkwgYW5kIFN0eWxlVVJMIFBBUkFNIHRhZ3MgCi0gICAgICAgIG9yIHRoZSBzZXREb2N1bWVudFVSTCgpIGFuZCBzZXRTdHlsZVVSTCgpIG1ldGhvZHMuIAotICAgICAgICBJZiB0aGUgWE1MIGRvY3VtZW50IGNvbnRhaW5zIGEgc3R5bGVzaGVldCBQcm9jZXNzaW5nCi0gICAgICAgIEluc3RydWN0aW9uIChQSSksIHlvdSBkbyBub3QgbmVlZCB0byBzcGVjaWZ5IGFuIFhTTAotICAgICAgICBzdHlsZXNoZWV0LjwvcD4KLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0gICAgICAgIDxwPkNhbGwgdGhlIGdldEh0bWxUZXh0KCkgbWV0aG9kLCB3aGljaCBwZXJmb3JtcwotICAgICAgICB0aGUgdHJhbnNmb3JtYXRpb24gYW5kIHJldHVybnMgdGhlIG5ldyBkb2N1bWVudCBhcyBhCi0gICAgICAgIFN0cmluZy48L3A+Ci0gICAgICA8L2xpPgotICAgIDwvb2w+Ci0gIDwvczI+Ci08L3MxPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvQXBwbHlYUGF0aC9BcHBseVhQYXRoLmphdmEgYi9zYW1wbGVzL0FwcGx5WFBhdGgvQXBwbHlYUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNWE5Mjk4Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQXBwbHlYUGF0aC9BcHBseVhQYXRoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0vLyBUaGlzIGZpbGUgdXNlcyA0IHNwYWNlIGluZGVudHMsIG5vIHRhYnMuCi0KLWltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLkRPTVBhcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQVBJOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlRyZWVXYWxrZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRE9NQnVpbGRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLQotLy8gSW1wb3J0ZWQgSkFWQSBBUEkgZm9yIFhNTCBQYXJzaW5nIDEuMCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsgCi0KLS8vIEltcG9ydGVkIFNlcmlhbGl6ZXIgY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLio7Ci0KLS8qKgotICogIFZlcnkgYmFzaWMgdXRpbGl0eSBmb3IgYXBwbHlpbmcgYW4gWFBhdGggZXB4cmVzc2lvbiB0byBhbiB4bWwgZmlsZSBhbmQgcHJpbnRpbmcgaW5mb3JtYXRpb24KLSAvICBhYm91dCB0aGUgZXhlY3V0aW9uIG9mIHRoZSBYUGF0aCBvYmplY3QgYW5kIHRoZSBub2RlcyBpdCBmaW5kcy4KLSAqICBUYWtlcyAyIGFyZ3VtZW50czoKLSAqICAgICAoMSkgYW4geG1sIGZpbGVuYW1lCi0gKiAgICAgKDIpIGFuIFhQYXRoIGV4cHJlc3Npb24gdG8gYXBwbHkgdG8gdGhlIGZpbGUKLSAqICBFeGFtcGxlczoKLSAqICAgICBqYXZhIEFwcGx5WFBhdGggZm9vLnhtbCAvCi0gKiAgICAgamF2YSBBcHBseVhQYXRoIGZvby54bWwgL2RvYy9uYW1lWzFdL0BsYXN0Ci0gKiBAc2VlIFhQYXRoQVBJCi0gKi8KLXB1YmxpYyBjbGFzcyBBcHBseVhQYXRoCi17Ci0gIHByb3RlY3RlZCBTdHJpbmcgZmlsZW5hbWUgPSBudWxsOwotICBwcm90ZWN0ZWQgU3RyaW5nIHhwYXRoID0gbnVsbDsKLQotICAvKiogUHJvY2VzcyBpbnB1dCBhcmdzIGFuZCBleGVjdXRlIHRoZSBYUGF0aC4gICovCi0gIHB1YmxpYyB2b2lkIGRvTWFpbihTdHJpbmdbXSBhcmdzKQotICAgIHRocm93cyBFeGNlcHRpb24KLSAgewotICAgIGZpbGVuYW1lID0gYXJnc1swXTsKLSAgICB4cGF0aCA9IGFyZ3NbMV07Ci0KLSAgICBpZiAoKGZpbGVuYW1lICE9IG51bGwpICYmIChmaWxlbmFtZS5sZW5ndGgoKSA+IDApCi0gICAgICAgICYmICh4cGF0aCAhPSBudWxsKSAmJiAoeHBhdGgubGVuZ3RoKCkgPiAwKSkKLSAgICB7Ci0gICAgICAvLyBUZWxsIHRoYXQgd2UncmUgbG9hZGluZyBjbGFzc2VzIGFuZCBwYXJzaW5nLCBzbyB0aGUgdGltZSBpdCAKLSAgICAgIC8vIHRha2VzIHRvIGRvIHRoaXMgZG9lc24ndCBnZXQgY29uZnVzZWQgd2l0aCB0aGUgdGltZSB0byBkbyAKLSAgICAgIC8vIHRoZSBhY3R1YWwgcXVlcnkgYW5kIHNlcmlhbGl6YXRpb24uCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkxvYWRpbmcgY2xhc3NlcywgcGFyc2luZyAiK2ZpbGVuYW1lKyIsIGFuZCBzZXR0aW5nIHVwIHNlcmlhbGl6ZXIiKTsKLSAgICAgIAotICAgICAgLy8gU2V0IHVwIGEgRE9NIHRyZWUgdG8gcXVlcnkuCi0gICAgICBJbnB1dFNvdXJjZSBpbiA9IG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGVuYW1lKSk7Ci0gICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgZGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgICBEb2N1bWVudCBkb2MgPSBkZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShpbik7Ci0gICAgICAKLSAgICAgIC8vIFNldCB1cCBhbiBpZGVudGl0eSB0cmFuc2Zvcm1lciB0byB1c2UgYXMgc2VyaWFsaXplci4KLSAgICAgIFRyYW5zZm9ybWVyIHNlcmlhbGl6ZXIgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgc2VyaWFsaXplci5zZXRPdXRwdXRQcm9wZXJ0eShPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OLCAieWVzIik7Ci0KLSAgICAgIC8vIFVzZSB0aGUgc2ltcGxlIFhQYXRoIEFQSSB0byBzZWxlY3QgYSBub2RlSXRlcmF0b3IuCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlF1ZXJ5aW5nIERPTSB1c2luZyAiK3hwYXRoKTsKLSAgICAgIE5vZGVJdGVyYXRvciBubCA9IFhQYXRoQVBJLnNlbGVjdE5vZGVJdGVyYXRvcihkb2MsIHhwYXRoKTsKLQotICAgICAgLy8gU2VyaWFsaXplIHRoZSBmb3VuZCBub2RlcyB0byBTeXN0ZW0ub3V0LgotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI8b3V0cHV0PiIpOwotICAgICAgICAgICAgICAgICAgCi0gICAgICBOb2RlIG47Ci0gICAgICB3aGlsZSAoKG4gPSBubC5uZXh0Tm9kZSgpKSE9IG51bGwpCi0gICAgICB7ICAgICAgICAgCi0gICAgICAgIHNlcmlhbGl6ZXIudHJhbnNmb3JtKG5ldyBET01Tb3VyY2UobiksIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgIH0KLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPC9vdXRwdXQ+Iik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkJhZCBpbnB1dCBhcmdzOiAiICsgZmlsZW5hbWUgKyAiLCAiICsgeHBhdGgpOwotICAgIH0KLSAgfQotICAKLSAgLyoqIE1haW4gbWV0aG9kIHRvIHJ1biBmcm9tIHRoZSBjb21tYW5kIGxpbmUuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmdbXSBhcmdzKQotICAgIHRocm93cyBFeGNlcHRpb24KLSAgewotICAgIGlmIChhcmdzLmxlbmd0aCAhPSAyKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiamF2YSBBcHBseVhQYXRoIGZpbGVuYW1lLnhtbCB4cGF0aFxuIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgIlJlYWRzIGZpbGVuYW1lLnhtbCBhbmQgYXBwbGllcyB0aGUgeHBhdGg7IHByaW50cyB0aGUgbm9kZWxpc3QgZm91bmQuIik7Ci0gICAgICByZXR1cm47Ci0gICAgfQotICAgICAgICAKLSAgICBBcHBseVhQYXRoIGFwcCA9IG5ldyBBcHBseVhQYXRoKCk7Ci0gICAgYXBwLmRvTWFpbihhcmdzKTsKLSAgfQkKLSAgCi19IC8vIGVuZCBvZiBjbGFzcyBBcHBseVhQYXRoCi0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQXBwbHlYUGF0aC9mb28ueG1sIGIvc2FtcGxlcy9BcHBseVhQYXRoL2Zvby54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA0MjM3MDguLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9BcHBseVhQYXRoL2Zvby54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+Ci0gIDxuYW1lIGZpcnN0PSJEYXZpZCIgbGFzdD0iTWFyc3RvbiIvPgotICA8bmFtZSBmaXJzdD0iRGF2aWQiIGxhc3Q9IkJlcnRvbmkiLz4KLSAgPG5hbWUgZmlyc3Q9IkRvbmFsZCIgbGFzdD0iTGVzbGllIi8+Ci0gIDxuYW1lIGZpcnN0PSJFbWlseSIgbGFzdD0iRmFybWVyIi8+Ci0gIDxuYW1lIGZpcnN0PSJKb3NlcGgiIGxhc3Q9Iktlc3NlbG1hbiIvPgotICA8bmFtZSBmaXJzdD0iTXlyaWFtIiBsYXN0PSJNaWR5Ii8+Ci0gIDxuYW1lIGZpcnN0PSJQYXVsIiBsYXN0PSJEaWNrIi8+Ci0gIDxuYW1lIGZpcnN0PSJTdGVwaGVuIiBsYXN0PSJBdXJpZW1tYSIvPgotICA8bmFtZSBmaXJzdD0iU2NvdHQiIGxhc3Q9IkJvYWciLz4KLSAgPG5hbWUgZmlyc3Q9IlNoYW5lIiBsYXN0PSJDdXJjdXJ1Ii8+Ci08L2RvYz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL0FwcGx5WFBhdGgvcmVhZG1lLmh0bWwgYi9zYW1wbGVzL0FwcGx5WFBhdGgvcmVhZG1lLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVjODkzNmYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9BcHBseVhQYXRoL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+WGFsYW4gU2FtcGxlczwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLTxoMj5YYWxhbiBTYW1wbGVzPC9oMj4KLTxwPkZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxlcyAod2hhdCB0aGV5IGlsbHVzdHJhdGUgYW5kIGhvdyB0byBydW4gdGhlbSksIHNlZSA8YSBocmVmPSIuLi8uLi9kb2NzL3NhbXBsZXMuaHRtbCI+U2FtcGxlczwvYT4uPC9wPgotCi0KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQ29tcGlsZWRBcHBsZXQvUkVBRE1FLmFwcGxldCBiL3NhbXBsZXMvQ29tcGlsZWRBcHBsZXQvUkVBRE1FLmFwcGxldApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGY0M2JhMy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkQXBwbGV0L1JFQURNRS5hcHBsZXQKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci1UaGUgU3VuIFhTTFQgQ29tcGlsZXIgKFhTTFRDKSBpcyBhIEphdmEtYmFzZWQgdG9vbCBmb3IgY29tcGlsaW5nIFhTTAotc3R5bGVzaGVldHMgaW50byBleHRyZW1lbHkgbGlnaHR3ZWlnaHQgYW5kIHBvcnRhYmxlIEphdmEgYnl0ZSBjb2RlLgotVGhlIFhTTFRDIEphdmEgUnVudGltZSBlbnZpcm9ubWVudCBjYW4gdGhlbiBwcm9jZXNzIFhNTCBmaWxlcyBhZ2FpbnN0Ci10aGVzZSBjb21waWxlZCBzdHlsZXNoZWV0cyAoVHJhbnNsZXRzKSB0byBnZW5lcmF0ZSBhbnkgbWFubmVyIG9mCi1vdXRwdXQgcGVyIHRoZSBzdHlsZXNoZWV0IGluc3RydWN0aW9ucy4KLQotVGhpcyBBcHBsZXQgRGVtbyBzaG93cyB5b3UgaG93IHRyYW5zbGV0cyBjYW4gYmUgcnVuIGluIGEgY2xpZW50IAotYnJvd3NlciBhcyBKYXZhIGFwcGxldHMgdG8gcGVyZm9ybSBYU0xUIHRyYW5zZm9ybWF0aW9ucyBvbiBYTUwgCi1zb3VyY2UgZG9jdW1lbnRzIHJlc2lkaW5nIG9uIGEgV2ViIHNlcnZlci4gQmVjYXVzZSBvZiBYU0xUQydzIHNtYWxsIAotZm9vdHByaW50LCBpdCBpcyBwb3NzaWJsZSB0byBkb3dubG9hZCB0aGUgY29tcGlsZWQgc3R5bGVzaGVldHMgCi0odHJhbnNsZXRzKSBhbmQgdGhlIHJ1bnRpbWUgY2xhc3NlcyBpbiB0aGUgYXBwbGV0LiBXaGVyZWFzLCB0aGlzCi13b3VsZCBub3QgYmUgZWFzeSB3aXRoIGEgZnVsbHNpemUgSmF2YS1iYXNlZCBYU0xUIHByb2Nlc3Nvci4gCi0KLVRoZXJlIGFyZSB0d28gaW1wb3J0YW50IGFkdmF0YWdlcyBvZiB0aGlzIGFwcHJvYWNoOiAKLQotICAxKSBJdCBvZmZsb2FkcyBYU0xUIHByb2Nlc3NpbmcgZnJvbSB0aGUgc2VydmVyCi0gIDIpIEl0IGVuYWJsZXMgYnJvd3NlcnMsIHN1Y2ggYXMgTmV0c2NhcGUgNC54LCB0aGF0IGRvIG5vdCBoYXZlIG5hdGl2ZSAKLSAgICAgWFNMVCBzdXBwb3J0IHRvIHBlcmZvcm0gWFNMVCB0cmFuc2Zvcm1hdGlvbnMgdG9kYXkhCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1ERU1PIENPTlRFTlRTCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotVGhlIGFwcGxldCBkZW1vIGlzIHZlcnkgZ2VuZXJpYy4gSXQgd2lsbCBsZXQgeW91IHJ1biBhbnkgcHJlLWNvbXBpbGVkCi10cmFuc2xldCB0aHJvdWdoIGFuIGFwcGxldCwgYW5kIGl0IGxldHMgeW91IHVzZSB0aGF0IG9uIGFueSBYTUwgZmlsZQoteW91IGNhbiByZWZlciB0byB1c2luZyBhbiBVUkwuIFRoZSBjb250ZW50cyBvZiB0aGlzIGRlbW8gYXJlOgotCi0gIFRyYW5zZm9ybUFwcGxldC5qYXZhIC0gIFRoZSBhcHBsZXQgdGhhdCB3cmFwcyB0aGUgWFNMVEMgcnVudGltZSAKLSAgICAgIGNsYXNzZXMgYW5kIHlvdXIgdHJhbnNsZXQocykuCi0KLSAgaW5kZXguaHRtbCAtIFlvdXIgbWFpbiBIVE1MIGRvY3VtZW50IChkaXNwbGF5cyB0d28gZnJhbWVzKQotCi0gIG1lbnUuaHRtbCAgLSBUaGUgSFRNTCBkb2N1bWVudCBmb3IgeW91ciBkaWFsb2cgZnJhbWUuIFRoaXMgaXMgdGhlCi0gICAgICBkb2N1bWVudCB0aGF0IGludm9rZXMgdGhlIFRyYW5zZm9ybUFwcGxldAotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotSE9XIFRPIFNFVCBVUCBUSEUgREVNTyBPTiBZT1VSIFNJVEUKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0xLiBJbnN0YWxsIGFuZCBjb25maWd1cmUgWGFsYW4gd2l0aCBYU0xUQwotCi0yLiBDb21waWxlIHRoZSBzdHlsZXNoZWV0cyB5b3Ugd2FudCB0byBleHBvcnQuIFRoaXMgd2lsbCByZXN1bHQgaW4gb25lCi0gICBvciBtb3JlIHNtYWxsIEphdmEgY2xhc3NlcyAodHJhbnNsZXRzKS4KLQotMy4gQ3JlYXRlIGEgSkFSIGZpbGUgd2l0aCB5b3VyIHRoZSBhcHBsZXQgY2xhc3MgKGNvbXBpbGUgaXQgZmlyc3QsIG9mCi0gICBjb3VyY2UpLCB5b3VyIHRyYW5zbGV0IGNsYXNzZXMgYW5kIHRoZXNlIGNsYXNzZXMgZnJvbSB0aGUgeGFsYW4veHNsdGMKLSAgIHBhY2thZ2U6Ci0KLSAgICAgb3JnL2FwYWNoZS94YWxhbi94c2x0Yy8qLmNsYXNzCi0gICAgIG9yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tLyouY2xhc3MKLSAgICAgb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lLyouY2xhc3MKLSAgICAgb3JnL2FwYWNoZS94YWxhbi94c2x0Yy91dGlsLyouY2xhc3MKLQotICAgQmUgc3VyZSB0byBtYWtlIHRoZSBKQVIgZmlsZSB3b3JsZCByZWFkYWJsZSEKLQotNC4gTWFrZSB5b3VyIFhNTCBzb3VyY2UgZG9jdW1lbnRzIHJlYWRhYmxlIHRocm91Z2ggYSBVUkwgKGVpdGhlciBwbGFjZQotICAgdGhlbSBiZWhpbmQgYSB3ZWIgc2VydmVyIG9yIG1ha2UgdGhlbSByZWFkYWJsZSBmb3IgeW91ciBicm93c2VyIGFzCi0gICBhIGZpbGUpLgotCi01LiBPcGVuIHRoZSBzdXBwbGllZCBpbmRleC5odG1sIGFuZCB0cnkgb3V0IHRoZSBkZW1vIQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1LTk9XIFBST0JMRU1TCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1UaGUgZm9sbG93aW5nIHByb2JsZW1zIGFyZSBzcGVjaWZpYyB0byB0aGUgTmV0c2NhcGUgNC54IGJyb3dzZXIuCi0KLUNsYXNzIEFscmVhZHkgTG9hZGVkIC0gSWYgeW91IHN0YXJ0IHVwIHRoZSBOZXRzY2FwZSBjbGllbnQgYnJvd3NlciBvbiAKLWEgVW5peCBzeXN0ZW0gd2hlcmUgeW91IGhhdmUgYmVlbiBydW5uaW5nIFhTTFRDLCBhbmQgY29uc2VxdWVudGx5IAotaGF2ZSBhIENMQVNTUEFUSCB0aGF0IGluY2x1ZGVzIHhtbC5qYXIsIGFuZCB4bHN0Y3J0LmphciwgdGhlIGFwcGxldCAKLWRlbW8gZmFpbHMuIFlvdSdsbCBzZWUgYSBtZXNzYWdlIHNheWluZyBhIGNsYXNzIGhhcyBhbHJlYWR5IGJlZW4gCi1sb2FkZWQgaW4gdGhlIEphdmFzY3JpcHQgY29uc29sZS4gVG8gYnJpbmcgdXAgdGhlIEphdmFzY3JpcHQgY29uc29sZSwKLXlvdSB0eXBlCi0KLSAgICBqYXZhc2NyaXB0OgotCi1pbiB0aGUgbG9jYXRpb24vVVJMIGZpZWxkIG9mIHRoZSBicm93c2VyLiBUbyB3b3JrIGFyb3VuZCB0aGlzIHByb2JsZW0sIAotdW5zZXQgeW91ciBDTEFTU1BBVEggYmVmb3JlIHN0YXJ0aW5nIE5ldHNjYXBlIGZyb20gYSB0ZXJtaW5hbCB3aW5kb3cuCi1UaGlzIHN0aWxsIG1heSBub3QgcmVzb2x2ZSB0aGUgcHJvYmxlbSBpZiBOZXRzY2FwZSBpcyBzdGFydGVkIGZyb20gCi1hIHdyYXBwZXIgdGhhdCBzZXRzIHlvdXIgZW52aXJvbm1lbnQgZnJvbSB5b3VyIHN0YXJ0dXAgZmlsZSAoZS5nLiwgCi15b3VyIC5jc2hyYyBmaWxlIGZvciB0aGUgQy1zaGVsbCkuCi0KLVBhcnNlciBFeGNlcHRpb24gLSBUaGlzIHByb2JsZW0gb25seSBhcHBsaWVzIHRvIE5ldHNjYXBlIG9uIHRoZSAKLVdpbmRvd3MgcGxhdGZvcm0gd2l0aCBYTUwgZG9jdW1lbnRzIHRoYXQgaGF2ZSBhbiBleHRlcm5hbCBEVEQuCi1JZiB5b3Ugc2VlIHRoZSBmb2xsb3dpbmcgbWVzc2FnZToKLQotICAgIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uOiAKLSAgICBFeHRlcm5hbCBwYXJhbWV0ZXIgZW50aXR5ICIlKERPQ1RZUEUpOyIKLSAgICBoYXMgY2hhcmFjdGVycyBhZnRlciBtYXJrdXAuCi0KLXRyeSByZW1vdmluZyB0aGUgcmVmZXJlbmNlIHRvIGFuIGV4dGVybmFsIERURCBpbiB5b3VyIFhNTCBzb3VyY2UuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1FTkQgT0YgUkVBRE1FCmRpZmYgLS1naXQgYS9zYW1wbGVzL0NvbXBpbGVkQXBwbGV0L1RyYW5zZm9ybUFwcGxldC5qYXZhIGIvc2FtcGxlcy9Db21waWxlZEFwcGxldC9UcmFuc2Zvcm1BcHBsZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGIyNGZlNy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkQXBwbGV0L1RyYW5zZm9ybUFwcGxldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjU4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKiAKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqCi0gKi8KLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLmFwcGxldC4qOwotaW1wb3J0IGphdmEuYXd0Lio7Ci1pbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLio7Ci0KLS8qKgotICogVGhpcyBhcHBsZXQgZGVtb25zdHJhdGVzIGhvdyBYU0wgdHJhbnNmb3JtYXRpb25zIGNhbiBiZSBtYWRlIHJ1biBpbgotICogYnJvd3NlcnMgd2l0aG91dCBuYXRpdmUgWFNMVCBzdXBwb3J0LgotICoKLSAqIE5vdGUgdGhhdCB0aGUgWFNMVEMgdHJhbnNmb3JtYXRpb24gZW5naW5lIGlzIGludm9rZWQgdGhyb3VnaCBpdHMgbmF0aXZlCi0gKiBpbnRlcmZhY2UgYW5kIG5vdCB0aGUgamF2YXgueG1sLnRyYW5zZm9ybSAoSkFYUCkgaW50ZXJmYWNlLiBUaGlzIGJlY2F1c2UKLSAqIFhTTFRDIHN0aWxsIGRvZXMgbm90IG9mZmVyIHByZWNvbXBpbGVkIHRyYW5zZm9ybWF0aW9ucyB0aHJvdWdoIEpBWFAuCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBUcmFuc2Zvcm1BcHBsZXQgZXh0ZW5kcyBBcHBsZXQgewotCi0gICAgLy8gU2luZ2xlIGRvY3VtZW50IGNhY2hlCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2RvY3VtZW50VXJsID0gIiI7Ci0gICAgcHJpdmF0ZSBET01JbXBsIF9kb20gPSBudWxsOwotICAgIHByaXZhdGUgRFRETW9uaXRvciBfZHRkTW9uaXRvciA9IG51bGw7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0ZFQVRVUkUgPQotCSJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyI7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBkaWFsb2cgYm94IHVzZWQgZm9yIFhTTCBtZXNzYWdlcy9jb21tZW50cwotICAgICAqLwotICAgIHB1YmxpYyBjbGFzcyBNZXNzYWdlRnJhbWUgZXh0ZW5kcyBGcmFtZSB7Ci0KLQlwdWJsaWMgRnJhbWUgZnJhbWU7Ci0KLSAgICAgICAgcHVibGljIGNsYXNzIEJ1dHRvbkhhbmRsZXIgaW1wbGVtZW50cyBBY3Rpb25MaXN0ZW5lciB7Ci0JICAgIHB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBlKSB7Ci0JICAgICAgICBmcmFtZS5zZXRWaXNpYmxlKGZhbHNlKTsKLQkgICAgfQotCX0KLQotCS8qKgotCSAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgeG1sOm1lc3NhZ2UgYW5kIHhzbDpjb21tZW50IGJ5IGRpc3BsYXlpbmcKLQkgKiB0aGUgbWVzc2FnZS9jb21tZW50IGluIGEgZGlhbG9nIGJveC4KLQkgKi8KLQlwdWJsaWMgTWVzc2FnZUZyYW1lKFN0cmluZyB0aXRsZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLQkgICAgc3VwZXIodGl0bGUpOwotCSAgICBmcmFtZSA9IHRoaXM7IC8vIE1ha2UgdmlzaWJsZSB0byBCdXR0b25IYW5kbGVyCi0JICAgIHNldFNpemUoMzIwLDIwMCk7Ci0KLQkgICAgLy8gQ3JlYXRlIGEgcGFuZWwgZm9yIHRoZSBtZXNzYWdlIGl0c2VsZgotCSAgICBQYW5lbCBjZW50ZXIgPSBuZXcgUGFuZWwoKTsKLQkgICAgY2VudGVyLmFkZChuZXcgTGFiZWwobWVzc2FnZSkpOwotCi0JICAgIC8vIENyZWF0ZSBhIHBhbmVsIGZvciB0aGUgJ09LJyBidXR0b24KLQkgICAgUGFuZWwgYm90dG9tID0gbmV3IFBhbmVsKCk7Ci0JICAgIEJ1dHRvbiBva0J1dHRvbiA9IG5ldyBCdXR0b24oIiAgIE9LICAgIik7Ci0JICAgIG9rQnV0dG9uLmFkZEFjdGlvbkxpc3RlbmVyKG5ldyBCdXR0b25IYW5kbGVyKCkpOwotCSAgICBib3R0b20uYWRkKG9rQnV0dG9uKTsKLQkgICAgCi0JICAgIC8vIEFkZCB0aGUgdHdvIHBhbmVscyB0byB0aGUgd2luZG93L2ZyYW1lCi0JICAgIGFkZChjZW50ZXIsIEJvcmRlckxheW91dC5DRU5URVIpOwotCSAgICBhZGQoYm90dG9tLEJvcmRlckxheW91dC5TT1VUSCk7Ci0KLQkgICAgLy8gU2hvdyB0aGUgZmVja2luZyB0aGluZwotCSAgICBzZXRWaXNpYmxlKHRydWUpOwotCX0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBhcHBsZWQgdXNlcyB0aGlzIG1ldGhvZCB0byBkaXNwbGF5IG1lc3NhZ2VzIGFuZCBjb21tZW50cwotICAgICAqIGdlbmVyYXRlZCBieSB4c2w6bWVzc2FnZSBhbmQgeHNsOmNvbW1lbnQgZWxlbWVudHMuCi0gICAgICovCi0gICAgcHVibGljIGNsYXNzIEFwcGxldE1lc3NhZ2VIYW5kbGVyIGV4dGVuZHMgTWVzc2FnZUhhbmRsZXIgewotCXB1YmxpYyB2b2lkIGRpc3BsYXlNZXNzYWdlKFN0cmluZyBtc2cpIHsKLQkgICAgTWVzc2FnZUZyYW1lIHogPSBuZXcgTWVzc2FnZUZyYW1lKCJYU0wgdHJhbnNmb3JtYXRpb24gYWxlcnQiLG1zZyk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlYWRzIHRoZSBpbnB1dCBkb2N1bWVudCBmcm9tIHRoZSBzdXBwbGllZCBVUkwgYW5kIGJ1aWxkcyB0aGUKLSAgICAgKiBpbnRlcm5hbCAiRE9NIiB0cmVlLgotICAgICAqLwotICAgIHByaXZhdGUgRE9NIGdldERPTShTdHJpbmcgdXJsKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkvLyBDaGVjayBpZiB0aGUgZG9jdW1lbnQgaXMgYWxyZWFkeSBpbiB0aGUgMS1kb2N1bWVudCBjYWNoZQotCWlmICh1cmwuZXF1YWxzKF9kb2N1bWVudFVybCkgPT0gZmFsc2UpIHsKLQotCSAgICAvLyBDcmVhdGUgYSBTQVggcGFyc2VyIGFuZCBnZXQgdGhlIFhNTFJlYWRlciBvYmplY3QgaXQgdXNlcwotCSAgICBmaW5hbCBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0JICAgIHRyeSB7Ci0JCWZhY3Rvcnkuc2V0RmVhdHVyZShOQU1FU1BBQ0VfRkVBVFVSRSx0cnVlKTsKLQkgICAgfQotCSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQkgICAgfQotCSAgICBmaW5hbCBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLQkgICAgZmluYWwgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQotCSAgICAvLyBTZXQgdGhlIERPTSdzIGJ1aWxkZXIgYXMgdGhlIFhNTFJlYWRlcidzIFNBWDIgY29udGVudCBoYW5kbGVyCi0JICAgIF9kb20gPSBuZXcgRE9NSW1wbCgpOwotCSAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoX2RvbS5nZXRCdWlsZGVyKCkpOwotCi0JICAgIC8vIENyZWF0ZSBhIERURCBtb25pdG9yIGFuZCBwYXNzIGl0IHRvIHRoZSBYTUxSZWFkZXIgb2JqZWN0Ci0JICAgIF9kdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLQkgICAgX2R0ZE1vbml0b3IuaGFuZGxlRFREKHJlYWRlcik7Ci0KLQkgICAgLy8gUGFyc2UgdGhlIGlucHV0IGRvY3VtZW50Ci0JICAgIHJlYWRlci5wYXJzZSh1cmwpOwotCi0JICAgIC8vIFVwZGF0ZSB0aGUgMS1kb2N1bWVudCBjYWhjZSB3aXRoIHRoaXMgRE9NCi0JICAgIF9kb2N1bWVudFVybCA9IHVybDsKLQl9Ci0JcmV0dXJuIF9kb207Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIG1haW4gYm9keSBvZiB0aGUgYXBwbGV0LiBUaGUgbWV0aG9kIGlzIGNhbGxlZAotICAgICAqIGJ5IHNvbWUgSmF2YVNjcmlwdCBjb2RlIGluIGFuIEhUTUwgZG9jdW1lbnQuCi0gICAgICovIAotICAgIHB1YmxpYyBTdHJpbmcgdHJhbnNmb3JtKE9iamVjdCBhcmcxLCBPYmplY3QgYXJnMikgewotCi0JLy8gQ29udmVydCB0aGUgdHdvIGFyZ3VtZW50cyB0byBzdHJpbmdzLgotCWZpbmFsIFN0cmluZyB0cmFuc2xldE5hbWUgPSAoU3RyaW5nKWFyZzE7Ci0JZmluYWwgU3RyaW5nIGRvY3VtZW50VXJsID0gKFN0cmluZylhcmcyOwotCi0JLy8gSW5pdGlhbGlzZSB0aGUgb3V0cHV0IHN0cmVhbQotCWZpbmFsIFN0cmluZ1dyaXRlciBzb3V0ID0gbmV3IFN0cmluZ1dyaXRlcigpOwotCWZpbmFsIFByaW50V3JpdGVyIG91dCA9IG5ldyBQcmludFdyaXRlcihzb3V0KTsKLQotCXRyeSB7Ci0JICAgIC8vIENoZWNrIHRoYXQgdGhlIHBhcmFtZXRlcnMgYXJlIHZhbGlkCi0JICAgIGlmICh0cmFuc2xldE5hbWUgPT0gbnVsbCB8fCBkb2N1bWVudFVybCA9PSBudWxsKSB7Ci0JCW91dC5wcmludGxuKCI8aDE+VHJhbnNmb3JtYXRpb24gZXJyb3I8L2gxPiIpOwotCQlvdXQucHJpbnRsbigiVGhlIHBhcmFtZXRlcnMgPGI+PHR0PmNsYXNzPC90dD48L2I+ICIrCi0JCQkgICAgImFuZCA8Yj48dHQ+c291cmNlPC90dD48L2I+IG11c3QgYmUgc3BlY2lmaWVkIik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCS8vIEluc3RhbmNpYXRlIGEgbWVzc2FnZSBoYW5kbGVyIGZvciB4c2w6bWVzc2FnZS94c2w6Y29tbWVudAotCQlBcHBsZXRNZXNzYWdlSGFuZGxlciBtc2dIYW5kbGVyID0gbmV3IEFwcGxldE1lc3NhZ2VIYW5kbGVyKCk7Ci0KLQkJLy8gR2V0IGEgcmVmZW5yZW5jZSB0byB0aGUgdHJhbnNsZXQgY2xhc3MKLQkJZmluYWwgQ2xhc3MgdGMgPSBDbGFzcy5mb3JOYW1lKHRyYW5zbGV0TmFtZSk7Ci0KLQkJLy8gSW5zdGFuY2lhdGUgYW5kIGluaXRpYWxpc2UgdGhlIHRyYW5sZXQgb2JqZWN0Ci0JCUFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0Yy5uZXdJbnN0YW5jZSgpOwotCQkoKEFic3RyYWN0VHJhbnNsZXQpdHJhbnNsZXQpLnNldE1lc3NhZ2VIYW5kbGVyKG1zZ0hhbmRsZXIpOwotCi0JCS8vIEluaXRpYWxpc2UgdGhlIHRyYW5zbGV0J3Mgb3V0cHV0IGhhbmRsZXIKLQkJRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgc2F4SGFuZGxlciA9IAotCQkgICAgbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKG91dCk7Ci0JCVRleHRPdXRwdXQgdGV4dE91dHB1dCA9IG5ldyBUZXh0T3V0cHV0KHNheEhhbmRsZXIpOwotCi0JCWdldERPTShkb2N1bWVudFVybCk7Ci0KLQkJZmluYWwgbG9uZyBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCi0JCS8vIFNldCBzaXplIG9mIGtleS9pZCBpbmRpY2VzCi0JCXRyYW5zbGV0LnNldEluZGV4U2l6ZShfZG9tLmdldFNpemUoKSk7Ci0JCS8vIElmIHRoZXJlIGFyZSBhbnkgZWxlbWVudHMgd2l0aCBJRCBhdHRyaWJ1dGVzLCBidWlsZCBhbiBpbmRleAotCi0JCV9kdGRNb25pdG9yLmJ1aWxkSWRJbmRleChfZG9tLCAwLCB0cmFuc2xldCk7Ci0JCS8vIFBhc3MgdW5wYXJzZWQgZW50aXRpZXMgdG8gdHJhbnNsZXQKLQkJdHJhbnNsZXQuc2V0VW5wYXJzZWRFbnRpdHlVUklzKF9kdGRNb25pdG9yLgotCQkJCQkgICAgICAgZ2V0VW5wYXJzZWRFbnRpdHlVUklzKCkpOwotCQkvLyBEbyB0aGUgYWN0dWFsIHRyYW5zZm9ybWF0aW9uCi0JCXRyYW5zbGV0LnRyYW5zZm9ybShfZG9tLCB0ZXh0T3V0cHV0KTsKLQotCQlmaW5hbCBsb25nIGRvbmUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0OwotCQlvdXQucHJpbnRsbigiPCEtLSB0cmFuc2Zvcm1lZCBieSBYU0xUQyBpbiAiK2RvbmUrIm1zZWNzIC0tPiIpOwotCSAgICB9Ci0JICAgIC8vIE5vdyBjbG9zZSB1cCB0aGUgc2luaywgYW5kIHJldHVybiB0aGUgSFRNTCBvdXRwdXQgaW4gdGhlCi0JICAgIC8vIFN0cmluZ1dyaXRlIG9iamVjdCBhcyBhIHN0cmluZy4KLQkgICAgb3V0LmNsb3NlKCk7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVHJhbnNmb3JtYXRpb24gY29tcGxldGUhIik7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbihzb3V0LnRvU3RyaW5nKCkpOwotCSAgICByZXR1cm4gc291dC50b1N0cmluZygpOwotCX0KLQljYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0JICAgIG91dC5jbG9zZSgpOwotCSAgICByZXR1cm4gc291dC50b1N0cmluZygpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgb3V0LnByaW50bG4oIjxoMT5leGNlcHRpb248L2gxPiIpOwotCSAgICBvdXQucHJpbnRsbihlLnRvU3RyaW5nKCkpOwotCSAgICBvdXQuY2xvc2UoKTsKLQkgICAgcmV0dXJuIHNvdXQudG9TdHJpbmcoKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEFwcGxldC9pbmRleC5odG1sIGIvc2FtcGxlcy9Db21waWxlZEFwcGxldC9pbmRleC5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDc1NQppbmRleCBiZGU1NjU2Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQ29tcGlsZWRBcHBsZXQvaW5kZXguaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDExICswLDAgQEAKLTxodG1sPgotPGhlYWQ+PHRpdGxlPlhTTFQgQXBwbGV0IERlbW9uc3RyYXRpb248L3RpdGxlPjwvaGVhZD4KLQotPGJhY2tncm91bmRjb2xvcj0jZmZmZmZmPgotCi08ZnJhbWVzZXQgYm9yZGVyPSIxIiBjb2xzPSIyNSUsKiI+Ci08ZnJhbWUgc3JjPSJtZW51Lmh0bWwiIG5hbWU9ImRlbW9fY3RybCI+Ci08ZnJhbWUgc3JjPSJhYm91dDpibGFuayIgbmFtZT0iZGVtb19vdXRwdXQiPgotPC9mcmFtZXNldD4KLQotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEFwcGxldC9tZW51Lmh0bWwgYi9zYW1wbGVzL0NvbXBpbGVkQXBwbGV0L21lbnUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMjY1NTAxYS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkQXBwbGV0L21lbnUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDUwICswLDAgQEAKLTxodG1sPgotPGhlYWQ+PC9oZWFkPgotPGJvZHkgYmdjb2xvcj0jZmZmZmZmPgotPGhyPgotCi08Y2VudGVyPjxoMz5YYWxhbi9YU0xUQyBBcHBsZXQgRGVtbzwvaDM+PC9jZW50ZXI+Ci1FYWNoIG9mIHRoZXNlIGV4YW1wbGVzIGlsbHVzdHJhdGUgdGhlIHVzZSBvZiB0cmFuc2xldHMKLXdpdGhpbiBhIEphdmEgYXBwbGV0OgotPHA+Ci0KLSAgPHNjcmlwdCBsYW5ndWFnZT0iSmF2YVNjcmlwdCI+Ci0KLSAgICBmdW5jdGlvbiBydW5fdHJhbnNmb3JtKGZvcm0pIHsKLSAgICAgIC8qIEdldCB0aGUgaW5wdXQgZG9jdW1lbnQgYW5kIHRyYW5zbGV0IGNsYXNzIG5hbWUgZnJvbSBpbnB1dCBmb3JtICovCi0gICAgICB2YXIgdHJhbnNsZXQgPSBmb3JtLnRyYW5zbGV0OwotICAgICAgdmFyIGRvY3VtZW50ID0gZm9ybS5kb2N1bWVudDsKLQotICAgICAgLyogR2V0IHRoZSBmcmFtZSB0byBvdXRwdXQgdG8gKi8KLSAgICAgIHZhciBvdXRwdXRfZnJhbWUgPSBwYXJlbnQuZnJhbWVzLmRlbW9fb3V0cHV0LmRvY3VtZW50OwotCi0gICAgICAvKiBEaXNwbGF5IHRoZSBvdXRwdXQgaW4gdGhpcyBmcmFtZSAqLwotICAgICAgb3V0cHV0X2ZyYW1lLmNsZWFyKCk7Ci0gICAgICBvdXRwdXRfZnJhbWUud3JpdGVsbihkb2N1bWVudC5UcmFuc2Zvcm1BcHBsZXQudHJhbnNmb3JtKHRyYW5zbGV0LCBkb2N1bWVudCkpOwotICAgICAgb3V0cHV0X2ZyYW1lLmNsb3NlKCk7Ci0gICAgICByZXR1cm4odHJ1ZSk7Ci0gICAgfQotCi0gIDwvc2NyaXB0PgotCi0gIDxmb3JtIG5hbWU9InhzbHRfZm9ybSIgb25TdWJtaXQ9InJ1bl90cmFuc2Zvcm0odGhpcy5mb3JtKSI+Ci0gICAgPHA+U2VsZWN0IHRyYW5zbGV0OjwvcD4KLSAgICA8cD48aW5wdXQgbmFtZT0idHJhbnNsZXQiIHdpZHRoPSI2NCI+PC9wPgotICAgIDxwPlNlbGVjdCBYTUwgc291cmNlIGRvY3VtZW50OjwvcD4KLSAgICA8cD48aW5wdXQgbmFtZT0iZG9jdW1lbnQiIHdpZHRoPSI2NCI+PC9wPgotICAgIDxwPjxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJSdW4iIG9uQ2xpY2s9InJ1bl90cmFuc2Zvcm0odGhpcy5mb3JtKSI+PC9wPgotCi0gIDwvZm9ybT4KLQotICA8IS0tCi0gICAgVGhlIHhzbHRjLmphciBmaWxlIG11c3QgY29udGFpbiB0aGUgWFNMVEMgcnVudGltZSBjbGFzc2VzIGFuZCB5b3VyCi0gICAgcHJlLWNvbXBpbGVkIHRyYW5zbGV0cywgYXMgZGVzY3JpYmVkIGluIHRoZSBSRUFETUUuYXBwbGV0IGZpbGUuCi0gIC0tPgotICA8YXBwbGV0IGFyY2hpdmU9InhzbHRjLmphciIKLSAgICAgICAgICBjb2RlPSJUcmFuc2Zvcm1BcHBsZXQiCi0gICAgICAgICAgbmFtZT0iVHJhbnNmb3JtQXBwbGV0IgotICAgICAgICAgIHdpZHRoPSIxMCIKLSAgICAgICAgICBoZWlnaHQ9IjEwIj4KLSAgPC9hcHBsZXQ+Ci0KLTwvYm9keT4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQ29tcGlsZWRCcmF6aWwvUkVBRE1FLmJyYXppbCBiL3NhbXBsZXMvQ29tcGlsZWRCcmF6aWwvUkVBRE1FLmJyYXppbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzk4OTBlMC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkQnJhemlsL1JFQURNRS5icmF6aWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNjEgKzAsMCBAQAotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci1DT05URU5UUyBPRiBUSElTIERPQ1VNRU5UOgotCi0gIG8pIEhPVyBUTyBQUk9WSURFIFhTTCBUUkFOU0ZPUk1BVElPTlMgQVMgQSBXRUIgU0VSVklDRQotICBvKSBIT1cgVE8gSU5WT0tFIFRSQU5TTEVUUyBGUk9NIEEgQlJBWklMIEhBTkRMRVIKLSAgbykgQlVJTERJTkcgWU9VUiBPV04gRE9NIENBQ0hFCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotSE9XIFRPIFBST1ZJREUgWFNMIFRSQU5TRk9STUFUSU9OUyBBUyBBIFdFQiBTRVJWSUNFCi0KLVRoaXMgc2FtcGxlIGNvZGUgaWxsdXN0cmF0ZXMgaG93IFhhbGFuL1hTTFRDIGNhbiBiZSB1c2VkIHRvCi1vZmZlciBYU0wgdHJhbnNmb3JtYXRpb25zIGFzIGEgd2ViIHNlcnZpY2Ugd2l0aG91dCB1c2luZyBhCi1mdWxsIHdlYiBzZXJ2ZXIuIFdlIGhhdmUgY2hvc2VuIHRvIHVzZSB0aGUgQnJhemlsIHByb3RvdHlwZQotZm9yIHRoZSB3ZWIgaW50ZXJmYWNlLCBhdmFpbGFibGUgZnJvbSBTdW5sYWJzOgotICAgIGh0dHA6Ly93d3cuc3VuLmNvbS9yZXNlYXJjaC9icmF6aWwvCi1idXQgd2UgY291bGQgZWFzaWx5IGhhdmUgdXNlZCBzb21lIG90aGVyIHdlYiBpbnRlcmZhY2Ugc3VjaAotYXMgVG9tY2F0LiBUaGUgc3VwcGxpZWQgSmF2YSBjb2RlIGltcGxlbWVudHMgYSBCcmF6aWwKLSJoYW5kbGVyIiwgd2hpY2ggdmVyeSBtdWNoIHJlc2VtYmxlcyBhIHNlcnZsZXQuCi0KLVRoZSBDb21waWxlZEVKQiBhbmQgQ29tcGlsZWRTZXJ2bGV0IHNhbXBsZSBjb2RlCi1kZW1vbnN0cmF0ZSBvdGhlciBhcHJvYWNoZXMgdG8gcHJvdmlkaW5nIFhTTCB0cmFuc2Zvcm1hdGlvbnMKLWFzIGEgd2ViIHNlcnZpY2UuCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotSE9XIFRPIElOVk9LRSBUUkFOU0xFVFMgRlJPTSBBIEJSQVpJTCBIQU5ETEVSCi0KLVRoZSAuQ29tcGlsZWRCcmF6aWwgZGlyZWN0b3J5IGNvbnRhaW5zIHRoZSBleGFtcGxlIHNvdXJjZSBjb2RlOgotCi0gICAgVHJhbnNmb3JtSGFuZGxlci5qYXZhCi0KLVRoaXMgZmlsZSBjb250YWlucyBhIG1pbmltYWwgaW1wbGVtZW50YXRpb24gb2YgYW4gWFNMCi10cmFuc2Zvcm1hdGlvbiBoYW5kbGVyLiBUaGUgaGFuZGxlciBwZXJmb3JtcyB0aGUgc2FtZSBiYXNpYwotc3RlcHMgYXMgdGhlIGNsYXNzIGltcGxlbWVudGluZyB0aGUgWFNMVEMgY29tbWFuZC1saW5lIHRvb2w6Ci0KLSAgICAvLyBPYnRhaW4gYSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zbGV0IGNsYXNzCi0gICAgQ2xhc3MgY2xzID0gQ2xhc3MuZm9yTmFtZSh0cmFuc2xldE5hbWUpOwotICAgIC8vIEluc3RhbmNpYXRlIGEgdHJhbnNsZXQgb2JqZWN0IChpbmhlcml0cyBBYnN0cmFjdFRyYW5zbGV0KQotICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCljbHMubmV3SW5zdGFuY2UoKTsKLQotICAgIC8vIFByZXBhcmUgdGhlIGludGVybmFsIERPTSB0cmVlCi0gICAgZmluYWwgRE9NSW1wbCBkb20gPSBuZXcgRE9NSW1wbCgpOwotICAgIGRvbS5zZXREb2N1bWVudFVSSShpbnB1dFVSSSk7Ci0KLSAgICAvLyBDcmVhdGUgYSBwYXJzZXIgZm9yIHRoZSBpbnB1dCBkb2N1bWVudAotICAgIC8vIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5Db25zdGFudHMgc2V0cyBOQU1FU1BBQ0VfRkVBVFVSRQotICAgIGZpbmFsIFNBWFBhcnNlckZhY3RvcnkgZmFjb3J5ID0gU0FYRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIHRyeSB7Ci0gICAgICBmYWN0b3J5LnNldEZlYXR1cmUoTkFNRVNQQUNFX0ZFQVRVUkUsdHJ1ZSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICB9Ci0gICAgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgICByZWFkZXIgPSBwYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0gICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGRvbS5nZXRCdWlsZGVyKCkpOwotCi0gICAgLy8gQ3JlYXRlIGEgRFRETW9uaXRvciBmb3IgaGFuZGxpbmcgSUQgcmVmZXJlbmNlcyBpbiB0aGUgRFRECi0gICAgRFRETW9uaXRvciBkdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLSAgICBkdGRNb25pdG9yLmhhbmRsZURURChyZWFkZXIpOwotCi0gICAgLy8gQ3JlYXRlIG91dHB1dCBoYW5kbGVyICh5b3UgY2FuIHBsdWcgaW4geW91ciBvd24pCi0gICAgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgc2F4SGFuZGxlcjsKLSAgICBzYXhIYW5kbGVyID0gbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKG91dCk7Ci0KLSAgICAvLyBQYXJzZSB0aGUgZG9jdW1lbnQgYW5kIGJ1aWxkIHRoZSBpbnRlcm5hbCBET00KLSAgICByZWFkZXIucGFyc2UoaW5wdXRVUkkpOwotCi0gICAgLy8gUGFzcyBpbmZvcm1hdGlvbiBvbiBpZC9rZXkgaW5kaWNpZXMgdG8gdGhlIHRyYW5zbGV0Ci0gICAgdHJhbnNsZXQuc2V0SW5kZXhTaXplKGRvbS5nZXRTaXplKCkpOwotICAgIGR0ZE1vbml0b3IuYnVpbGRJZEluZGV4KGRvbSwgMCwgdHJhbnNsZXQpOwotICAgIHRyYW5zbGV0LnNldFVucGFyc2VkRW50aXR5VVJJcyhkdGRNb25pdG9yLmdldFVucGFyc2VkRW50aXR5VVJJcygpKTsKLQotICAgIC8vIFN0YXJ0IHRoZSB0cmFuc2Zvcm1hdGlvbgotICAgIHRyYW5zbGV0LnRyYW5zZm9ybShkb20sIG5ldyBUZXh0T3V0cHV0KHNheEhhbmRsZXIpKTsKLQotQWx0ZXJuYXRpdmVseSB0aGUgaGFuZGxlciBjYW4gdXNlIGEgY2FjaGUgZm9yIHN0b3JpbmcKLWZyZXF1ZW50bHkgYWNjZXNzZWQgWE1MIGRvY3VtZW50cy4gVGhpcyBpcyBub3Qgb25seSBhIG1hdHRlcgotb2YgcmVhZGluZyB0aGUgaW5pdGlhbCBpbnB1dCBkb2N1bWVudCBmcm9tIHRoZSBjYWNoZSwgYXMKLXRoZSB0cmFuc2xldCBtYXkgbG9hZCBvdGhlciBYTUwgaW5wdXQgZG9jdW1lbnRzIGFzIHJ1bnRpbWUuCi0oSWYgdGhlIHhzbDpkb2N1bWVudCgpIGZ1bmN0aW9uIHdhcyB1c2VkIGluIHRoZSBzdHlsZXNoZWV0LikKLQotICAgIC8vIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNsZXQgY2xhc3MKLSAgICBDbGFzcyBjbHMgPSBDbGFzcy5mb3JOYW1lKHRyYW5zbGV0TmFtZSk7Ci0KLSAgICAvLyBJbnN0YW5jaWF0ZSBhIHRyYW5zbGV0IG9iamVjdCAoaW5oZXJpdHMgQWJzdHJhY3RUcmFuc2xldCkKLSAgICBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0ID0gKEFic3RyYWN0VHJhbnNsZXQpY2xzLm5ld0luc3RhbmNlKCk7Ci0KLSAgICAvLyBUaGUgdHJhbnNsZXQgbmVlZHMgYSByZWZlcmVuY2UgdG8gdGhlIGNhY2hlIGluIGNhc2UKLSAgICAvLyBpbiBuZWVkcyB0byBsb2FkIGFkZGl0aW9uYWwgWE1MIGRvY3VtZW50cy4KLSAgICB0cmFuc2xldC5zZXRET01DYWNoZShjYWNoZSk7Ci0KLSAgICAvLyBHZXQgdGhlIERPTSBmcm9tIHRoZSBET00gY2FjaGUKLSAgICBET01JbXBsIGRvbSA9IGNhY2hlLnJldHJpZXZlRG9jdW1lbnQoZG9jdW1lbnRVUkksIDAsIHRyYW5zbGV0KTsKLQotICAgIC8vIENyZWF0ZSBvdXRwdXQgaGFuZGxlciAoeW91IGNhbiBwbHVnIGluIHlvdXIgb3duKQotICAgIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIHNheEhhbmRsZXI7Ci0gICAgc2F4SGFuZGxlciA9IG5ldyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihvdXQpOwotCi0gICAgLy8gU3RhcnQgdGhlIHRyYW5zZm9ybWF0aW9uCi0gICAgdHJhbnNsZXQudHJhbnNmb3JtKGRvbSwgbmV3IFRleHRPdXRwdXQoc2F4SGFuZGxlcikpOwotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLUJVSUxESU5HIFlPVVIgT1dOIERPTSBDQUNIRQotCi1UaGUgaW50ZXJmYWNlIGZvciB0aGUgRE9NIGNhY2hlIGNvbnNpc3RzIG9mIGEgc2luZ2xlIG1ldGhvZCwKLWFuZCBpdHMgZGVmaW5pdGlvbiBjYW4gYmUgZm91bmQgaW46Ci0KLSAgICBvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL0RPTUNhY2hlLmphdmEKLQotVGhlIG1ldGhvZCBjb250YWluZWQgaW4gdGhlIGludGVyZmFjZSBpczoKLQotICAgIHB1YmxpYyBET01JbXBsIHJldHJpZXZlRG9jdW1lbnQoU3RyaW5nIHVyaSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXNrLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNsZXQgdHJhbnNsZXQpOwotCi1UaGUgcmVzcG9uc2liaWxpdGllcyBvZiB0aGlzIG1ldGhvZCBhcmU6Ci0KLSBBKSBCdWlsZCBuZXcgYSBET01JbXBsIGFuZCBEVERNb25pdG9yIGZvciBYTUwgZG9jdW1lbnRzCi0gICAgdGhhdCBhcmUgbm90IGFscmVhZHkgaW4gdGhlIGNhY2hlOgotCi0gICAgICAgIC8vIEluc3RhbmNpYXRlIGEgRE9NSW1wbCBvYmplY3QKLSAgICAgICAgUGFyc2VyICBwYXJzZXIgPSBuZXcgUGFyc2VyKCk7Ci0gICAgICAgIERPTUltcGwgZG9tID0gbmV3IERPTUltcGwoKTsKLSAgICAgICAgZG9tLnNldERvY3VtZW50VVJJKHVyaSk7Ci0gICAgICAgIHBhcnNlci5zZXREb2N1bWVudEhhbmRsZXIoZG9tLmdldEJ1aWxkZXIoKSk7Ci0KLSAgICAgICAgLy8gVXNlIGEgRFRETW9uaXRvciB0byB0cmFjayBJRCByZWZlcmVuY2VzIGluIERURAotICAgICAgICBEVERNb25pdG9yIGR0ZE1vbml0b3IgPSBuZXcgRFRETW9uaXRvcigpOwotICAgICAgICBwYXJzZXIuc2V0RFRESGFuZGxlcihkdGRNb25pdG9yKTsKLQotICAgICAgICAvLyBQYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgYW5kIGJ1aWxkIERPTQotICAgICAgICBwYXJzZXIucGFyc2UodXJpKTsKLQotICAgIEF0IHRoaXMgcG9pbnQgdGhlIERPTUltcGwgYW5kIERURE1vbml0b3Igb2JqZWN0cyBhcmUKLSAgICBwb3B1bGF0ZWQgd2l0aCB0aGUgbmVjZXNzYXJ5IGRhdGEuIFRoZSB0d28gb2JqZWN0cwotICAgIGFyZSByZWFkeSB0byBiZSBwdXQgaW4gdGhlIGNhY2hlICh1c2luZyB0aGUgVVJJIGFzCi0gICAgdGhlIGxvb2t1cCBrZXkpLgotCi0gQikgRm9yIGVhY2ggdGltZSBhIG5ldyBkb2N1bWVudCBpcyByZXF1ZXN0ZWQgYnkgYSB0cmFuc2xldDoKLQotICAgICAgICAvLyBFeHBhbmQgdHJhbnNsZXQncyBpbmRleCBhcnJheSB0byBmaXQgdGhpcyBET00KLSAgICAgICAgdHJhbnNsZXQuc2V0SW5kZXhTaXplKGRvbS5nZXRTaXplKCkpOwotCi0gICAgICAgIC8vIEJ1aWxkIGluZGljZXMgZm9yIHRoaXMgRE9NJ3MgRFREJ3MgSUQgcmVmZXJlbmNlcwotICAgICAgICBkdGQuYnVpbGRJZEluZGV4KGRvbSwgbWFzaywgdHJhbnNsZXQpOwotCi0gICAgICAgIC8vIFBhc3MgdW5wYXJzZWQgZW50aXR5IFVSSXMgdG8gdGhlIHRyYW5zbGV0Ci0gICAgICAgIHRyYW5zbGV0LnNldFVucGFyc2VkRW50aXR5VVJJcyhkdGQuZ2V0VW5wYXJzZWRFbnRpdHlVUklzKCkpOwotCi1TdGVwIEEpIG11c3QgYmUgZG9uZSBldmVyeSB0aW1lIGEgZG9jdW1lbnQgaXMgcmVhZCBpbnRvIHRoZQotY2FjaGUsIGFuZCBzdGVwIEIpIGV2ZXJ5IHRpbWUgYSBkb2N1bWVudCBpcyBnaXZlbiB0byBhCi10cmFuc2xldC4KLQotVGhlIFhTTFRDIHBhY2thZ2UgY29udGFpbnMgYW4gZXhhbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBhCi1ET00gY2FjaGUsIGJhc2VkIG9uIGEgdmVyeSBzaW1wbGUgcm91bmQtcm9iaW4gY2FjaGluZwotYWxnb3JpdGhtOgotCi0gICAgb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRG9jdW1lbnRDYWNoZS5qYXZhCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotRU5EIE9GIFJFQURNRQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEJyYXppbC9UcmFuc2Zvcm1IYW5kbGVyLmphdmEgYi9zYW1wbGVzL0NvbXBpbGVkQnJhemlsL1RyYW5zZm9ybUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzdjN2Q5MC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkQnJhemlsL1RyYW5zZm9ybUhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwNyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICogCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLio7Ci0KLWltcG9ydCBzdW5sYWJzLmJyYXppbC5zZXJ2ZXIuSGFuZGxlcjsKLWltcG9ydCBzdW5sYWJzLmJyYXppbC5zZXJ2ZXIuUmVxdWVzdDsKLWltcG9ydCBzdW5sYWJzLmJyYXppbC5zZXJ2ZXIuU2VydmVyOwotCi0vKioKLSAqIFRoaXMgQnJhemlsIGhhbmRsZXIgZGVtb25zdHJhdGVzIGhvdyBYU0wgdHJhbnNmb3JtYXRpb25zIGNhbiBiZSBtYWRlCi0gKiBhdmFpbGFibGUgYXMgYSB3ZWIgc2VydmljZSB3aXRob3V0IHVzaW5nIGEgZnVsbCB3ZWIgc2VydmVyLiBUaGlzIGNsYXNzCi0gKiBpbXBsZW1lbnRzIHRoZSBIYW5kbGVyIGludGVyZmFjZSBmcm9tIHRoZSBCcmF6aWwgcHJvamVjdCwgc2VlOgotICogaHR0cDovL3d3dy5zdW4uY29tL3Jlc2VhcmNoL2JyYXppbC8KLSAqCi0gKiBOb3RlIHRoYXQgdGhlIFhTTFRDIHRyYW5zZm9ybWF0aW9uIGVuZ2luZSBpcyBpbnZva2VkIHRocm91Z2ggaXRzIG5hdGl2ZQotICogaW50ZXJmYWNlIGFuZCBub3QgdGhlIGphdmF4LnhtbC50cmFuc2Zvcm0gKEpBWFApIGludGVyZmFjZS4gVGhpcyBiZWNhdXNlCi0gKiBYU0xUQyBzdGlsbCBkb2VzIG5vdCBvZmZlciBwcmVjb21waWxlZCB0cmFuc2Zvcm1hdGlvbnMgdGhyb3VnaCBKQVhQLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtSGFuZGxlciBpbXBsZW1lbnRzIEhhbmRsZXIgewotCi0gICAgLy8gQSBjYWNoZSBmb3IgaW50ZXJuYWwgRE9NIHN0cnVjdHVyZXMKLSAgICBwcml2YXRlIHN0YXRpYyBEb2N1bWVudENhY2hlIGNhY2hlID0gbnVsbDsKLQotICAgIC8vIFRoZXNlIHR3byBhcmUgdXNlZCB3aGlsZSBwYXJzaW5nIHRoZSBwYXJhbWV0ZXJzIGluIHRoZSBVUkwKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBQQVJBTV9UUkFOU0xFVCA9ICJ0cmFuc2xldD0iOwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIFBBUkFNX0RPQ1VNRU5UID0gImRvY3VtZW50PSI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgUEFSQU1fU1RBVFMgPSAic3RhdHM9IjsKLQotICAgIC8vIEFsbCBvdXRwdXQgZ29lcyBoZXJlOgotICAgIHByaXZhdGUgUHJpbnRXcml0ZXIgX291dCA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBEdW1wIGFuIGVycm9yIG1lc3NhZ2UgdG8gb3V0cHV0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXJyb3JNZXNzYWdlKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkgewotCWlmIChfb3V0ID09IG51bGwpIHJldHVybjsKLQlfb3V0LnByaW50bG4oIjxoMT5YU0wgdHJhbnNmb3JtYXRpb24gZXJyb3I8L2gxPiIrbWVzc2FnZSk7Ci0JX291dC5wcmludGxuKCI8YnI+RXhjZXB0aW9uOjwvYnI+IitlLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVycm9yTWVzc2FnZShTdHJpbmcgbWVzc2FnZSkgewotCWlmIChfb3V0ID09IG51bGwpIHJldHVybjsKLQlfb3V0LnByaW50bG4oIjxoMT5YU0wgdHJhbnNmb3JtYXRpb24gZXJyb3I8L2gxPiIrbWVzc2FnZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgcnVuIHdoZW4gdGhlIEJyYXppbCBwcm94eSBpcyBsb2FkZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpbml0KFNlcnZlciBzZXJ2ZXIsIFN0cmluZyBwcmVmaXgpIHsKLQlyZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBydW4gZm9yIGV2ZXJ5IEhUVFAgcmVxdWVzdCBzZW50IHRvIHRoZSBwcm94eQotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHJlc3BvbmQoUmVxdWVzdCByZXF1ZXN0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCi0JLy8gSW5pdGlhbGlzZSB0aGUgb3V0cHV0IGJ1ZmZlcgotCWZpbmFsIFN0cmluZ1dyaXRlciBzb3V0ID0gbmV3IFN0cmluZ1dyaXRlcigpOwotCV9vdXQgPSBuZXcgUHJpbnRXcml0ZXIoc291dCk7Ci0KLQkvLyBUaGVzZSB0d28gaG9sZCB0aGUgcGFyYW1ldGVycyBmcm9tIHRoZSBVUkwgJ3RyYW5zbGV0JyBhbmQgJ2RvY3VtZW50JwotCVN0cmluZyB0cmFuc2xldE5hbWUgPSBudWxsOwotCVN0cmluZyBkb2N1bWVudCA9IG51bGw7Ci0JU3RyaW5nIHN0YXRzID0gbnVsbDsKLQotCS8vIEdldCB0aGUgcGFyYW1ldGVycyBmcm9tIHRoZSBVUkwKLQlmaW5hbCBTdHJpbmdUb2tlbml6ZXIgcGFyYW1zID0gbmV3IFN0cmluZ1Rva2VuaXplcihyZXF1ZXN0LnF1ZXJ5LCImIik7Ci0Jd2hpbGUgKHBhcmFtcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBTdHJpbmcgcGFyYW0gPSBwYXJhbXMubmV4dFRva2VuKCk7Ci0JICAgIGlmIChwYXJhbS5zdGFydHNXaXRoKFBBUkFNX1RSQU5TTEVUKSkgewotCQl0cmFuc2xldE5hbWUgPSBwYXJhbS5zdWJzdHJpbmcoUEFSQU1fVFJBTlNMRVQubGVuZ3RoKCkpOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKHBhcmFtLnN0YXJ0c1dpdGgoUEFSQU1fRE9DVU1FTlQpKSB7Ci0JCWRvY3VtZW50ID0gcGFyYW0uc3Vic3RyaW5nKFBBUkFNX0RPQ1VNRU5ULmxlbmd0aCgpKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChwYXJhbS5zdGFydHNXaXRoKFBBUkFNX1NUQVRTKSkgewotCQlzdGF0cyA9IHBhcmFtLnN1YnN0cmluZyhQQVJBTV9TVEFUUy5sZW5ndGgoKSk7Ci0JICAgIH0KLQl9Ci0KLQl0cnkgewotCSAgICAvLyBJbml0aWFsaXplIHRoZSBkb2N1bWVudCBjYWNoZSB3aXRoIDMyIERPTSBzbG90cwotCSAgICBpZiAoY2FjaGUgPT0gbnVsbCkgY2FjaGUgPSBuZXcgRG9jdW1lbnRDYWNoZSgzMik7Ci0KLQkgICAgLy8gT3V0cHV0IHN0YXRpc3RpY3MgaWYgdXNlciBsb29rZWQgdXAgInNlcnZlcjpwb3J0Lz9zdGF0cz14eHgiCi0JICAgIGlmIChzdGF0cyAhPSBudWxsKSB7Ci0JCWNhY2hlLmdldFN0YXRpc3RpY3MoX291dCk7IC8vIGdldCBjYWNoZSBzdGF0aXN0aWNzIChpbiBIVE1MKQotCSAgICB9Ci0JICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGJvdGggcGFyYW1ldGVycyB3ZXJlIHNwZWNpZmllZAotCSAgICBlbHNlIGlmICgodHJhbnNsZXROYW1lID09IG51bGwpIHx8IChkb2N1bWVudCA9PSBudWxsKSkgewotCQllcnJvck1lc3NhZ2UoIlBhcmFtZXRlcnMgPGI+PHR0PnRyYW5zbGV0PC90dD48L2I+IGFuZC9vciAiKwotCQkJICAgICAiPGI+PHR0PmRvY3VtZW50PC90dD48L2I+IG5vdCBzcGVjaWZpZWQuIik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCS8vIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNsZXQgY2xhc3MKLQkgICAgICAgIENsYXNzIHRyYW5zbGV0Q2xhc3MgPSBDbGFzcy5mb3JOYW1lKHRyYW5zbGV0TmFtZSk7Ci0JCS8vIEluc3RhbmNpYXRlIHRoZSB0cmFuc2xldCBvYmplY3QgKGluaGVyaXRzIEFic3RyYWN0VHJhbnNsZXQpCi0JCUFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPQotCQkgICAgKEFic3RyYWN0VHJhbnNsZXQpdHJhbnNsZXRDbGFzcy5uZXdJbnN0YW5jZSgpOwotCQl0cmFuc2xldC5zZXRET01DYWNoZShjYWNoZSk7Ci0KLQkJLy8gR2V0IHRoZSBET00gZnJvbSB0aGUgRE9NIGNhY2hlCi0JCURPTUltcGwgZG9tID0gY2FjaGUucmV0cmlldmVEb2N1bWVudChkb2N1bWVudCwgMCwgdHJhbnNsZXQpOwotCi0JCWlmIChkb20gPT0gbnVsbCkgewotCQkgICAgZXJyb3JNZXNzYWdlKCJDb3VsZCBub3QgbG9jYXRlOiBcIjxiPiIrZG9jdW1lbnQrIlwiPC9iPiIpOwotCQl9Ci0JCWVsc2UgewotCQkgICAgLy8gSW5pdGlhbGlzZSB0aGUgdHJhbnNsZXQncyBvdXRwdXQgaGFuZGxlcgotCQkgICAgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgc2F4SGFuZGxlciA9IAotCQkJbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKF9vdXQpOwotCi0JCSAgICAvLyBEbyB0aGUgYWN0dWFsIHRyYW5zZm9ybWF0aW9uCi0JCSAgICBmaW5hbCBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCSAgICB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCBuZXcgVGV4dE91dHB1dChzYXhIYW5kbGVyKSk7Ci0JCSAgICBmaW5hbCBsb25nIGRvbmUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0OwotCQkgICAgX291dC5wcmludGxuKCI8IS0tIHRyYW5zZm9ybWVkIGJ5IFhTTFRDIGluICIrZG9uZSsibXMgLS0+Iik7Ci0JCX0KLQkgICAgfQotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkgICAgZXJyb3JNZXNzYWdlKCJFcnJvciBwYXJzaW5nIGRvY3VtZW50IFwiIitkb2N1bWVudCsiXCIiKTsKLQl9Ci0JY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotCSAgICBlcnJvck1lc3NhZ2UoIkNvdWxkIG5vdCBsb2NhdGUgdGhlIHRyYW5zbGV0IGNsYXNzOiBcIiIrCi0JCQkgdHJhbnNsZXROYW1lKyJcIjxicj5FeGNlcHRpb246PC9icj4iLGUpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgZXJyb3JNZXNzYWdlKCJJbnRlcm5hbCBlcnJvci4iLGUpOwotCX0KLQotCS8vIFBhc3MgdGhlIHRyYW5zZm9ybWF0aW9uIG91dHB1dCBhcyB0aGUgSFRUUCByZXNwb25zZQotCXJlcXVlc3Quc2VuZFJlc3BvbnNlKHNvdXQudG9TdHJpbmcoKSk7Ci0JcmV0dXJuIHRydWU7Ci0gICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQ29tcGlsZWRFSkIvUkVBRE1FLmVqYiBiL3NhbXBsZXMvQ29tcGlsZWRFSkIvUkVBRE1FLmVqYgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2E2ZjlmOS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkRUpCL1JFQURNRS5lamIKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLUNPTlRFTlRTIE9GIFRISVMgRE9DVU1FTlQ6Ci0KLSAgbykgSE9XIFRPIFBST1ZJREUgWFNMIFRSQU5TRk9STUFUSU9OUyBBUyBBIFdFQiBTRVJWSUNFCi0gIG8pIEhPVyBUTyBJTlZPS0UgVFJBTlNMRVRTIEZST00gQU4gRU5URVJQUklTRSBKQVZBIEJFQU4KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1IT1cgVE8gUFJPVklERSBYU0wgVFJBTlNGT1JNQVRJT05TIEFTIEEgV0VCIFNFUlZJQ0UKLQotV2l0aCBYU0xUQywgWFNMIHRyYW5zZm9ybWF0aW9ucyBjYW4gYmUgcnVuIGZyb20gd2l0aGluIGEKLWFuIEVudGVycHJpc2UgSmF2YSBCZWFuIChFSkIpIGFuZCBleHBvcnRlZCB0aHJvdWdoIGEgc2VydmxldC4KLVRoaXMgc2FtcGxlIGNvZGUgZGVtb25zdHJhdGVzIGhvdyB0aGF0IGNhbiBiZSBpbXBsZW1lbnRlZC4KLQotVGhlIENvbXBpbGVkU2VydmxldCBhbmQgQ29tcGlsZWRCcmF6aWwgc2FtcGxlIGNvZGUKLWRlbW9uc3RyYXRlcyBvdGhlciBhcHJvYWNoZXMgdG8gcHJvdmlkaW5nIFhTTCB0cmFuc2Zvcm1hdGlvbnMKLWFzIGEgd2ViIHNlcnZpY2UuCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotSE9XIFRPIElOVk9LRSBUUkFOU0xFVFMgRlJPTSBBTiBFTlRFUlBSSVNFIEpBVkEgQkVBTgotCi0gbykgQ3JlYXRlIGFuIEVKQiB0aGF0IGltcGxlbWVudHMgU2Vzc2lvbkJlYW4gYW5kIGhhcyBhCi0gICAgc2luZ2xlIHRyYW5zZm9ybSgpIGVudHJ5IHBvaW50OgotCi0gICAgcHVibGljIGNsYXNzIFRyYW5zZm9ybUJlYW4gaW1wbGVtZW50cyBTZXNzaW9uQmVhbiB7Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgdHJhbnNmb3JtKFN0cmluZyBkb2N1bWVudCwgU3RyaW5nIHRyYW5zbGV0TmFtZSkgewotICAgICAgICAgICAgLy8gaW5zdGFuY2lhdGUgdHJhbnNsZXQKLSAgICAgICAgICAgIC8vIGJ1aWxkIGludGVybmFsIERPTQotICAgICAgICAgICAgLy8gcnVuIHRyYW5zZm9ybWF0aW9uCi0gICAgICAgICAgICA6Ci0gICAgICAgICAgICA6Ci0gICAgICAgIH0KLSAgICAgICAgOgotICAgICAgICA6Ci0gICAgfQotCi0gbykgQ3JlYXRlIHRoaXMgRUpCJ3MgcmVtb3RlIGludGVyZmFjZSAodGhpcyBpcyB0aGUgaW50ZXJmYWNlCi0gICAgeW91ciBzZXJ2bGV0IHdpbGwgdXNlIHRvIGNhbGwgdGhlIGJlYW4ncyBlbnRyeSBwb2ludCk6Ci0KLSAgICBwdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybVJlbW90ZSBleHRlbmRzIEVKQk9iamVjdCB7Ci0gICAgICAgIHB1YmxpYyBTdHJpbmcgdHJhbnNmb3JtKFN0cmluZyBkb2N1bWVudCwgU3RyaW5nIHRyYW5zbGV0TmFtZSkgCi0gICAgICAgIHRocm93cyBSZW1vdGVFeGNlcHRpb247Ci0gICAgfQotCi0gbykgQ3JlYXRlIHRoZSBFSkIncyBob21lIGludGVyZmFjZSwgd2hpY2ggeW91ciBzZXJ2bGV0Ci0gICAgd2lsbCB1c2UgdG8gaW5zdGFuY2lhdGUgdGhlIHJlbW90ZSBpbnRlcmZhY2U6Ci0KLSAgICBwdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybUhvbWUgZXh0ZW5kcyBFSkJIb21lIHsKLSAgICAgICAgVHJhbnNmb3JtUmVtb3RlIGNyZWF0ZSgpCi0gICAgICAgICAgICB0aHJvd3MgQ3JlYXRlRXhjZXB0aW9uLCBSZW1vdGVFeGNlcHRpb247Ci0gICAgfQotCi0gbykgQ3JlYXRlIGEgc2VydmxldCB0aGF0IHVzZXMgdGhlIEVKQidzIGhvbWUgaW50ZXJmYWNlIHRvCi0gICAgY3JlYXRlIGEgcmVtb3RlIGludGVyZmFjZSB0byB0aGUgRUpCLCBhbmQgdGhlbiBjYWxscwotICAgIHRoZSBFSkIncyB0cmFuc2Zvcm0oKSBtZXRob2QgdGhyb3VnaCB0aGF0IHJlbW90ZQotICAgIGludGVyZmFjZToKLQotICAgIHB1YmxpYyBjbGFzcyBUcmFuc2Zvcm1TZXJ2bGV0IGV4dGVuZHMgSHR0cFNlcnZsZXQgewotCi0gICAgICAgIHB1YmxpYyB2b2lkIGluaXQoU2VydmxldENvbmZpZyBjb25maWcpIHsKLSAgICAgICAgICAgIC8vIGxvb2sgdXAgdGhlIEVKQidzIGhvbWUgaW50ZXJmYWNlIHVzaW5nIEpOREkKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIGRvR2V0IChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKSAKLSAgICAgICAgICAgIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHJlbW90ZSBpbnRlcmZhY2UKLSAgICAgICAgICAgIC8vIHBhc3MgdGhlIHBhcmFtZXRlcnMgZnJvbSB0ZWggcmVxdWVzdCB0byB0aGUgRUpCCi0gICAgICAgICAgICAvLyBkaXNwbGF5IHJlc3VsdHMgcGFzc2VkIGJhY2sgZnJvbSBFSkIKLSAgICAgICAgfQotICAgIH0KLQotIG8pIFNldCB1cCB5b3VyIEoyRUVfQ0xBU1NQQVRIIHRvIGluY2x1ZGUgSkFYUCBhbmQgdGhlIFhTTFRDCi0gICAgcnVudGltZSBqYXJzLgotCi0gbykgQ29tcGlsZSB5b3VyIFhTTCBzdHlsZXNoZWV0cyBhbmQgcGxhY2UgdGhlbSBlaXRoZXIgaW4KLSAgICB5b3VyIEoyRUVfQ0xBU1NQQVRIIG9yIHdyYXAgdGhlbSBpbiB5b3VyIEVKQiBqYXIuCi0KLSBvKSBEZXBsb3kgeW91ciBFSkIKLQotIG8pIENhbGwgdGhlIHNlcnZsZXQgd2l0aCB0aGUgbmVjZXNzYXJ5IHBhcmFtZXRlcnMgKGF0IGxlYXN0Ci0gICAgYW4gVVJJIHRvIHRoZSBzb3VyY2UgWE1MIGRvY3VtZW50IGFuZCB0aGUgbmFtZSBvZiB0aGUKLSAgICB0cmFuc2xldCBjbGFzcykuCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotRU5EIE9GIFJFQURNRQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEVKQi9UcmFuc2Zvcm1CZWFuLmphdmEgYi9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybUJlYW4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTkxNGE4OS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybUJlYW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqIAotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS50ZXh0Lio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBqYXZhLnJtaS5SZW1vdGVFeGNlcHRpb247Ci1pbXBvcnQgamF2YXguZWpiLlNlc3Npb25CZWFuOwotaW1wb3J0IGphdmF4LmVqYi5TZXNzaW9uQ29udGV4dDsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLio7Ci0KLXB1YmxpYyBjbGFzcyBUcmFuc2Zvcm1CZWFuIGltcGxlbWVudHMgU2Vzc2lvbkJlYW4gewotCi0gICAgcHJpdmF0ZSBTZXNzaW9uQ29udGV4dCBfY29udGV4dCA9IG51bGw7Ci0gICAgCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIG51bGxFcnJvck1zZyA9Ci0JIjxoMT5YU0wgdHJhbnNmb3JtYXRpb24gZXJyb3I8L2gxPiIrCi0JIjxwPidudWxsJyBwYXJhbWV0ZXJzIHNlbnQgdG8gdGhlIFhTTCB0cmFuc2Zvcm1hdGlvbiBiZWFuJ3MgIisKLQkiPHR0PnRyYW5zZm9ybShTdHJpbmcgZG9jdW1lbnQsIFN0cmluZyB0cmFuc2xldCk8L3R0PiBtZXRob2QuPC9wPiI7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0ZFQVRVUkUgPQotCSJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyI7Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIHRoZSBpbnB1dCBkb2N1bWVudCBhbmQgYnVpbGQgdGhlIGludGVybmFsICJET00iIHRyZWUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBET01JbXBsIGdldERPTShTdHJpbmcgdXJsLCBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0KQotCXRocm93cyBFeGNlcHRpb24gewotCi0JLy8gQ3JlYXRlIGEgU0FYIHBhcnNlciBhbmQgZ2V0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGl0IHVzZXMKLQlmaW5hbCBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0JdHJ5IHsKLQkgICAgZmFjdG9yeS5zZXRGZWF0dXJlKE5BTUVTUEFDRV9GRUFUVVJFLHRydWUpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQl9Ci0JZmluYWwgU0FYUGFyc2VyIHBhcnNlciA9IGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0JZmluYWwgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQotCS8vIFNldCB0aGUgRE9NJ3MgYnVpbGRlciBhcyB0aGUgWE1MUmVhZGVyJ3MgU0FYMiBjb250ZW50IGhhbmRsZXIKLQlET01JbXBsIGRvbSA9IG5ldyBET01JbXBsKCk7Ci0JcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGRvbS5nZXRCdWlsZGVyKCkpOwotCi0JLy8gQ3JlYXRlIGEgRFREIG1vbml0b3IgYW5kIHBhc3MgaXQgdG8gdGhlIFhNTFJlYWRlciBvYmplY3QKLQlmaW5hbCBEVERNb25pdG9yIGR0ZE1vbml0b3IgPSBuZXcgRFRETW9uaXRvcigpOwotCWR0ZE1vbml0b3IuaGFuZGxlRFREKHJlYWRlcik7Ci0JdHJhbnNsZXQuc2V0RFRETW9uaXRvcihkdGRNb25pdG9yKTsKLQotCS8vIFBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudAotCXJlYWRlci5wYXJzZSh1cmwpOwotCi0JcmV0dXJuIGRvbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZW5lcmF0ZXMgSFRNTCBmcm9tIGEgYmFzaWMgZXJyb3IgbWVzc2FnZSBhbmQgYW4gZXhjZXB0aW9uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGVycm9yTXNnKFByaW50V3JpdGVyIG91dCwgRXhjZXB0aW9uIGUsIFN0cmluZyBtc2cpIHsKLQlvdXQucHJpbnRsbigiPGgxPkVycm9yPC9oMT4iKTsKLQlvdXQucHJpbnRsbigiPHA+Iittc2crIjwvcD48YnI+Iik7Ci0Jb3V0LnByaW50bG4oZS50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNYWluIGJlYW4gZW50cnkgcG9pbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRyYW5zZm9ybShTdHJpbmcgZG9jdW1lbnQsIFN0cmluZyB0cmFuc2xldE5hbWUpIHsKLQotCS8vIEluaXRpYWxpc2UgdGhlIG91dHB1dCBzdHJlYW0KLQlmaW5hbCBTdHJpbmdXcml0ZXIgc291dCA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKLQlmaW5hbCBQcmludFdyaXRlciBvdXQgPSBuZXcgUHJpbnRXcml0ZXIoc291dCk7Ci0KLQl0cnkgewotCSAgICBpZiAoKGRvY3VtZW50ID09IG51bGwpIHx8ICh0cmFuc2xldE5hbWUgPT0gbnVsbCkpIHsKLQkJb3V0LnByaW50bG4obnVsbEVycm9yTXNnKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJLy8gSW5zdGFuY2lhdGUgYSB0cmFuc2xldCBvYmplY3QgKGluaGVyaXRzIEFic3RyYWN0VHJhbnNsZXQpCi0JICAgICAgICBDbGFzcyB0YyA9IENsYXNzLmZvck5hbWUodHJhbnNsZXROYW1lKTsKLQkJQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCA9IChBYnN0cmFjdFRyYW5zbGV0KXRjLm5ld0luc3RhbmNlKCk7Ci0KLQkJLy8gUmVhZCBpbnB1dCBkb2N1bWVudCBmcm9tIHRoZSBET00gY2FjaGUKLQkJRE9NSW1wbCBkb20gPSBnZXRET00oZG9jdW1lbnQsIHRyYW5zbGV0KTsKLQotCQkvLyBJbml0aWFsaXplIHRoZSAoZGVmYXVsdCkgU0FYIG91dHB1dCBoYW5kbGVyCi0JCURlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIHNheEhhbmRsZXIgPSAKLQkJICAgIG5ldyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihvdXQpOwotCi0JCS8vIFN0YXJ0IHRoZSB0cmFuc2Zvcm1hdGlvbgotCQlmaW5hbCBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCXRyYW5zbGV0LnRyYW5zZm9ybShkb20sIG5ldyBUZXh0T3V0cHV0KHNheEhhbmRsZXIpKTsKLQkJZmluYWwgbG9uZyBkb25lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKLQkJb3V0LnByaW50bG4oIjwhLS0gdHJhbnNmb3JtZWQgYnkgWFNMVEMgaW4gIitkb25lKyJtc2VjcyAtLT4iKTsKLQkgICAgfQotCX0KLQotCWNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0JICAgIGVycm9yTXNnKG91dCwgZSwgIkNvdWxkIG5vdCBsb2NhdGUgc291cmNlIGRvY3VtZW50OiAiK2RvY3VtZW50KTsKLQl9Ci0JY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotCSAgICBlcnJvck1zZyhvdXQsIGUsICJDb3VsZCBub3QgbG9jYXRlIHRoZSB0cmFuc2xldCBjbGFzczogIisKLQkJICAgICB0cmFuc2xldE5hbWUpOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkgICAgZXJyb3JNc2cob3V0LCBlLCAiRXJyb3IgcGFyc2luZyBkb2N1bWVudCAiK2RvY3VtZW50KTsKLQl9Ci0JY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JICAgIGVycm9yTXNnKG91dCwgZSwgIkltcG9zc2libGUgc3RhdGUgcmVhY2hlZC4iKTsKLQl9Ci0KLQkvLyBOb3cgY2xvc2UgdXAgdGhlIHNpbmssIGFuZCByZXR1cm4gdGhlIEhUTUwgb3V0cHV0IGluIHRoZQotCS8vIFN0cmluZ1dyaXRlIG9iamVjdCBhcyBhIHN0cmluZy4KLQlvdXQuY2xvc2UoKTsKLQlyZXR1cm4gc291dC50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvbkNvbnRleHQoU2Vzc2lvbkNvbnRleHQgY29udGV4dCkgewotCV9jb250ZXh0ID0gY29udGV4dDsKLSAgICB9Ci0KLSAgICAvLyBHZW5lcmFsIEVKQiBlbnRyeSBwb2ludHMKLSAgICBwdWJsaWMgdm9pZCBlamJDcmVhdGUoKSB7IH0KLSAgICBwdWJsaWMgdm9pZCBlamJSZW1vdmUoKSB7IH0KLSAgICBwdWJsaWMgdm9pZCBlamJBY3RpdmF0ZSgpIHsgfQotICAgIHB1YmxpYyB2b2lkIGVqYlBhc3NpdmF0ZSgpIHsgfQotICAgIHB1YmxpYyB2b2lkIGVqYkxvYWQoKSB7IH0KLSAgICBwdWJsaWMgdm9pZCBlamJTdG9yZSgpIHsgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEVKQi9UcmFuc2Zvcm1Ib21lLmphdmEgYi9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybUhvbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWM1ZjlhNy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybUhvbWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICogCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotaW1wb3J0IGphdmEucm1pLlJlbW90ZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC5lamIuQ3JlYXRlRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LmVqYi5FSkJIb21lOwotCi0vKioKLSAqIFhTTCB0cmFuc2Zvcm1hdGlvbiBiZWFuIGhvbWUgaW50ZXJmYWNlCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVHJhbnNmb3JtSG9tZSBleHRlbmRzIEVKQkhvbWUgewotICAgIFRyYW5zZm9ybVJlbW90ZSBjcmVhdGUoKSB0aHJvd3MgQ3JlYXRlRXhjZXB0aW9uLCBSZW1vdGVFeGNlcHRpb247Ci19CmRpZmYgLS1naXQgYS9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybVJlbW90ZS5qYXZhIGIvc2FtcGxlcy9Db21waWxlZEVKQi9UcmFuc2Zvcm1SZW1vdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGNiYWVlZC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybVJlbW90ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKiAKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1pbXBvcnQgamF2YXguZWpiLkVKQk9iamVjdDsKLWltcG9ydCBqYXZhLnJtaS5SZW1vdGVFeGNlcHRpb247Ci0KLS8qKgotICogWFNMIHRyYW5zZm9ybWF0aW9uIGJlYW4gcmVtb3RlIGludGVyZmFjZQotICovCi1wdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybVJlbW90ZSBleHRlbmRzIEVKQk9iamVjdCB7Ci0gICAgcHVibGljIFN0cmluZyB0cmFuc2Zvcm0oU3RyaW5nIGRvY3VtZW50LCBTdHJpbmcgdHJhbnNsZXROYW1lKSAKLQl0aHJvd3MgUmVtb3RlRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEVKQi9UcmFuc2Zvcm1TZXJ2bGV0LmphdmEgYi9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybVNlcnZsZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGJkYWI0YS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkRUpCL1RyYW5zZm9ybVNlcnZsZXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqIAotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLWltcG9ydCBqYXZheC5zZXJ2bGV0Lio7Ci1pbXBvcnQgamF2YXguc2VydmxldC5odHRwLio7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmF4Lm5hbWluZy4qOwotaW1wb3J0IGphdmF4LnJtaS5Qb3J0YWJsZVJlbW90ZU9iamVjdDsKLQotcHVibGljIGNsYXNzIFRyYW5zZm9ybVNlcnZsZXQgZXh0ZW5kcyBIdHRwU2VydmxldCB7Ci0KLSAgICAvLyBFcnJvciBtZXNzYWdlIHVzZWQgd2hlbiB0aGUgWFNMIHRyYW5zZm9ybWF0aW9uIGJlYW4gY2Fubm90IGJlIGNyZWF0ZWQKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgY3JlYXRlRXJyb3JNc2cgPQotCSI8aDE+WFNMIHRyYW5zZm9ybWF0aW9uIGJlYW4gZXJyb3I8L2gxPiIrCi0JIjxwPkFuIFhTTCB0cmFuc2Zvcm1hdGlvbiBiZWFuIGNvdWxkIG5vdCBiZSBjcmVhdGVkLjwvcD4iOwotCi0gICAgLy8gVHJhbnNmb3JtZXIgLSAibW9yZSB0aGFuIG1lZXRzIHRoZSBleWUiLgotICAgIHByaXZhdGUgVHJhbnNmb3JtSG9tZSB0cmFuc2Zvcm1lcjsKLQotICAgIC8qKgotICAgICAqIFNlcnZsZXQgaW5pdGlhbGl6ZXIgLSBsb29rIHVwIHRoZSBiZWFuJ3MgaG9tZSBpbnRlcmZhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbml0KFNlcnZsZXRDb25maWcgY29uZmlnKSAKLQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbnsKLQl0cnl7Ci0JICAgIEluaXRpYWxDb250ZXh0IGNvbnRleHQgPSBuZXcgSW5pdGlhbENvbnRleHQoKTsKLQkgICAgT2JqZWN0IHRyYW5zZm9ybVJlZiA9IGNvbnRleHQubG9va3VwKCJ0cmFuc2Zvcm0iKTsKLQkgICAgdHJhbnNmb3JtZXIgPQotCQkoVHJhbnNmb3JtSG9tZSlQb3J0YWJsZVJlbW90ZU9iamVjdC5uYXJyb3codHJhbnNmb3JtUmVmLAotCQkJCQkJCSAgIFRyYW5zZm9ybUhvbWUuY2xhc3MpOwotCX0gY2F0Y2ggKEV4Y2VwdGlvbiBOYW1pbmdFeGNlcHRpb24pIHsKLQkgICAgTmFtaW5nRXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZSgpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGVzICJHRVQiIEhUVFAgcmVxdWVzdHMgLSBpZS4gcnVucyB0aGUgYWN0dWFsIHRyYW5zZm9ybWF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZG9HZXQgKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCAKLQkJICAgICAgIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpIAotCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0KLQlTdHJpbmcgZG9jdW1lbnQgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigiZG9jdW1lbnQiKTsKLQlTdHJpbmcgdHJhbnNsZXQgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigidHJhbnNsZXQiKTsKLQotCXJlc3BvbnNlLnNldENvbnRlbnRUeXBlKCJ0ZXh0L2h0bWwiKTsKLQotCVByaW50V3JpdGVyIG91dCA9IHJlc3BvbnNlLmdldFdyaXRlcigpOwotCXRyeXsKLQkgICAgLy8gR2V0IHRoZSBpbnN1bHQgZnJvbSB0aGUgYmVhbgotCSAgICBUcmFuc2Zvcm1SZW1vdGUgeHNsdCA9IHRyYW5zZm9ybWVyLmNyZWF0ZSgpOwotCSAgICBTdHJpbmcgcmVzdWx0ID0geHNsdC50cmFuc2Zvcm0oZG9jdW1lbnQsIHRyYW5zbGV0KTsKLQkgICAgb3V0LnByaW50bG4ocmVzdWx0KTsKLQl9IGNhdGNoKEV4Y2VwdGlvbiBDcmVhdGVFeGNlcHRpb24pewotCSAgICBvdXQucHJpbnRsbihjcmVhdGVFcnJvck1zZyk7Ci0JfQotCW91dC5jbG9zZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRlc3Ryb3koKSB7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJEZXN0cm95Iik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEVKQi9ib3R0b21fZnJhbWUuaHRtbCBiL3NhbXBsZXMvQ29tcGlsZWRFSkIvYm90dG9tX2ZyYW1lLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVkYzE5MTguLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9Db21waWxlZEVKQi9ib3R0b21fZnJhbWUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDcgKzAsMCBAQAotPGh0bWw+Ci0gIDxoZWFkPjwvaGVhZD4KLSAgPGJvZHk+Ci0gICAgPGJhY2tncm91bmRjb2xvcj0jZmZmZmZmPgotICA8L2JvZHk+Ci08L2h0bWw+Ci0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQ29tcGlsZWRFSkIvaW5kZXguaHRtbCBiL3NhbXBsZXMvQ29tcGlsZWRFSkIvaW5kZXguaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjQxYzJiNC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkRUpCL2luZGV4Lmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNCArMCwwIEBACi08aHRtbD4KLSAgPGhlYWQ+PHRpdGxlPlhNTCBUZWNobm9sb2d5IENlbnRlcjwvdGl0bGU+PC9oZWFkPgotICAgIDxiYWNrZ3JvdW5kY29sb3I9I2ZmZmZmZj4KLQotICAgIDxmcmFtZXNldCBib3JkZXI9IjAiIHJvd3M9IjMwJSw3MCUiPgotICAgICAgPGZyYW1lIHNyYz0idG9wX2ZyYW1lLmh0bWwiIE5BTUU9InRvcCIgc2Nyb2xsaW5nPSJvZmYiPgotICAgICAgPGZyYW1lIHNyYz0iYm90dG9tX2ZyYW1lLmh0bWwiIE5BTUU9ImJvdHRvbSIgc2Nyb2xsaW5nPSJvbiI+Ci0gICAgPC9mcmFtZXNldD4KLQotICAgIDxub2ZyYW1lcz4KLSAgICA8L25vZnJhbWVzPgotCi08L2h0bWw+Ci0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvQ29tcGlsZWRFSkIvdG9wX2ZyYW1lLmh0bWwgYi9zYW1wbGVzL0NvbXBpbGVkRUpCL3RvcF9mcmFtZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNTI5MDg4Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQ29tcGlsZWRFSkIvdG9wX2ZyYW1lLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMDUgKzAsMCBAQAotPGh0bWw+Ci0KLSAgPGhlYWQ+Ci0gICAgPGJhc2UgdGFyZ2V0PXh0Y19tZW51PgotICA8L2hlYWQ+Ci0KLSAgPGJvZHkgYmdjb2xvcj0jZmZmZmZmPgotCi0gICAgPGNlbnRlcj48aDE+U2VydmVyLXNpZGUgWFNMIHRyYW5zZm9ybWF0aW9uczwvaDE+PHA+PC9jZW50ZXI+Ci0KLSAgICA8c2NyaXB0IGxhbmd1YWdlPSJKYXZhU2NyaXB0Ij4KLQotICAgICAgZnVuY3Rpb24gZ2V0VVJJKCkgewotICAgICAgICB2YXIgcm9vdCA9ICJodHRwOi8vZ29ic2hlZW4uaXJlbGFuZC9tb3J0ZW4vU3VuL1hUQy9kZW1vL3BsYXlzLyI7Ci0JdmFyIG1lbnUgPSBkb2N1bWVudC5YTUxpbnB1dC5lbGVtZW50c1swXTsKLSAgICAgICAgdmFyIHBsYXkgPSBtZW51Lm9wdGlvbnNbbWVudS5zZWxlY3RlZEluZGV4XS52YWx1ZTsKLSAgICAgICAgcmV0dXJuKHJvb3QrcGxheSk7Ci0gICAgICB9Ci0KLSAgICAgIGZ1bmN0aW9uIGdldFRyYW5zbGV0KCkgewotCXZhciBtZW51ID0gZG9jdW1lbnQuWE1MaW5wdXQuZWxlbWVudHNbMV07Ci0gICAgICAgIHZhciB0cmFuc2xldCA9IG1lbnUub3B0aW9uc1ttZW51LnNlbGVjdGVkSW5kZXhdLnZhbHVlOwotCXJldHVybih0cmFuc2xldCk7Ci0gICAgICB9Ci0KLSAgICAgIGZ1bmN0aW9uIHNldEhUTUxsb2NhdGlvbih0cmFuc2xldCkgewotICAgICAgICB2YXIgdXJpID0gZ2V0VVJJKCk7Ci0gICAgICAgIHZhciB0cmFuc2xldCA9IGdldFRyYW5zbGV0KCk7Ci0gICAgICAgIHZhciBzb3VyY2UgPSAiaHR0cDovL2dvYnNoZWVuOjgwMDAvVHJhbnNmb3JtL1RyYW5zZm9ybT8iKwotICAgICAgICAgICAgICAgICAgICAgImRvY3VtZW50PSIrdXJpKyImdHJhbnNsZXQ9Iit0cmFuc2xldDsKLSAgICAgICAgb3Blbihzb3VyY2UsImJvdHRvbSIpOwotICAgICAgfQotCi0gICAgICBmdW5jdGlvbiBzZXRYTUxsb2NhdGlvbigpIHsKLSAgICAgICAgdmFyIHRhcmdldCA9IHBhcmVudC5mcmFtZXMuZGVtb19ib3R0b207Ci0gICAgICAgIHZhciB1cmkgPSBnZXRVUkkoKTsKLSAgICAgICAgb3Blbih1cmksImJvdHRvbSIpOwotICAgICAgfQotCi0gICAgPC9zY3JpcHQ+Ci0KLSAgICA8Zm9ybSBuYW1lPSJYTUxpbnB1dCI+Ci0KLSAgICA8dGFibGU+Ci0gICAgPHRyPgotICAgICAgPHRkPgotICAgICAgICA8Yj5Tb3VyY2UgZG9jdW1lbnQ6PC9iPgotICAgICAgPC90ZD4KLSAgICAgIDx0ZD4KLSAgICAgICAgPHNlbGVjdCBuYW1lPSJkcm9wZG93biI+Ci0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iQXNZb3VMaWtlSXQueG1sIj5BcyBZb3UgTGlrZSBJdAotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IkN5bWJlbGluZS54bWwiPkN5bWJlbGluZQotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IkhhbWxldC54bWwiPlRoZSBUcmFnZWR5IG9mIEhhbWxldAotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IkhlbnJ5Vi54bWwiPlRoZSBMaWZlIG9mIEhlbnJ5IFYKLSAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJIZW5yeVZJSUkueG1sIj5UaGUgRmFtb3VzIEhpc3Rvcnkgb2YgdGhlIExpZmUgb2YgSGVucnkgVklJSQotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IktpbmdKb2huLnhtbCI+VGhlIExpZmUgYW5kIERlYXRoIG9mIEtpbmcgSm9obgotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IktpbmdMZWFyLnhtbCI+VGhlIFRyYWdlZHkgb2YgS2luZyBMZWFyCi0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iS2luZ1JpY2hhcmRJSS54bWwiPlRoZSBUcmFnZWR5IG9mIEtpbmcgUmljaGFyZCBJSQotICAgICAgICAgIDxvcHRpb24gdmFsdWU9Ik1lYXN1cmVGb3JNZWFzdXJlLnhtbCI+TWVhc3VyZSBmb3IgTWVhc3VyZQotICAgICAgICAgIDxvcHRpb24gdmFsdWU9Ik1lcmNoYW50T2ZWZW5pY2UueG1sIj5UaGUgTWVyY2hhbnQgb2YgVmVuaWNlCi0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iTWVycnlXaXZlc09mV2luZHNvci54bWwiPlRoZSBNZXJyeSBXaXZlcyBvZiBXaW5kc29yCi0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iTWlkc3VtbWVyTmlnaHRzRHJlYW0ueG1sIj5BIE1pZHN1bW1lciBOaWdodCdzIERyZWFtCi0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iTXVjaEFkb0Fib3V0Tm90aGluZy54bWwiPk11Y2ggQWRvIGFib3V0IE5vdGhpbmcKLSAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJQZXJpY2xlc1ByaW5jZU9mVHlyZS54bWwiPlBlcmljbGVzLCBQcmluY2Ugb2YgVHlyZQotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlJvbWVvQW5kSnVsaWV0LnhtbCI+VGhlIFRyYWdlZHkgb2YgUm9tZW8gYW5kIEp1bGlldAotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlRhbWluZ09mVGhlU2hyZXcueG1sIj5UaGUgVGFtaW5nIG9mIHRoZSBTaHJldwotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlRoZVRlbXBlc3QueG1sIj5UaGUgVGVtcGVzdAotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlRpbW9uT2ZBdGhlbnMueG1sIj5UaGUgTGlmZSBvZiBUaW1vbiBvZiBBdGhlbnMKLSAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJUcmFnZWR5T2ZDb3Jpb2xhbnVzLnhtbCI+VGhlIFRyYWdlZHkgb2YgQ29yaW9sYW51cwotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlRyYWdlZHlPZkp1bGl1c0NhZXNhci54bWwiPlRoZSBUcmFnZWR5IG9mIEp1bGl1cyBDYWVzYXIKLSAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJUcmFnZWR5T2ZPdGhlbGxvLnhtbCI+VGhlIFRyYWdlZHkgb2YgT3RoZWxsbywgdGhlIE1vb3Igb2YgVmVuaWNlCi0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iVHJvaWx1c0FuZENyZXNpZGEueG1sIj5UaGUgSGlzdG9yeSBvZiBUcm9pbHVzIGFuZCBDcmVzc2lkYQotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlR3ZWxmdGhOaWdodC54bWwiPlR3ZWxmdGggTmlnaHQsIG9yIFdoYXQgWW91IFdpbGwKLSAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJUd29HZW50bGVtZW50T2ZWZXJvbmEueG1sIj5UaGUgVHdvIEdlbnRsZW1lbiBvZiBWZXJvbmEKLSAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJXaW50ZXJzVGFsZS54bWwiPlRoZSBXaW50ZXIncyBUYWxlCi0gICAgICAgIDwvc2VsZWN0PgotICAgICAgPC90ZD4KLSAgICA8L3RyPgotICAgIDx0cj4KLSAgICAgIDx0ZD4KLSAgICAgICAgPGI+VHJhbnNmb3JtYXRpb246PC9iPgotICAgICAgPC90ZD4KLSAgICAgIDx0ZD4KLSAgICAgICAgPHNlbGVjdCBuYW1lPSJkcm9wZG93biI+Ci0gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iUGxheVRvSFRNTCI+RnVsbAotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlBsYXlUb1NwZWFrZXJzIj5TcGVha2VycwotICAgICAgICAgIDxvcHRpb24gdmFsdWU9IlBsYXlUb0luZGV4Ij5JbmRleAotICAgICAgICA8L3NlbGVjdD4KLSAgICAgIDwvdGQ+Ci0gICAgPC90cj4KLSAgICA8dHI+Ci0gICAgICA8dGQ+Ci0gICAgICAgIDxiPk1ldGhvZDo8L2I+Ci0gICAgICA8L3RkPgotICAgICAgPHRkPgotICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iVHJhbnNmb3JtIiBvbkNsaWNrPSJzZXRIVE1MbG9jYXRpb24oKSI+Ci0gICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJYTUwgc291cmNlIiBvbkNsaWNrPSJzZXRYTUxsb2NhdGlvbigpIj4KLSAgICAgIDwvdGQ+Ci0gICAgPC90cj4KLSAgPC90YWJsZT4KLSAgPC9mb3JtPgotCi0gIDwvYm9keT4KLQotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEpBWFAvQ29tcGlsZS5qYXZhIGIvc2FtcGxlcy9Db21waWxlZEpBWFAvQ29tcGlsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNDJkYmFhLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvQ29tcGlsZWRKQVhQL0NvbXBpbGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc3ICswLDAgQEAKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0T3V0cHV0U3RyZWFtOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy50cmF4LlRyYW5zZm9ybWVyRmFjdG9yeUltcGw7Ci0KLXB1YmxpYyBjbGFzcyBDb21waWxlIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpewotICAgICAgICBDb21waWxlIGFwcCA9IG5ldyBDb21waWxlKCk7Ci0gICAgICAgIGFwcC5ydW4oYXJnc1swXSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYW4gWFNMIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0LCB3cmFwcyB0aGUgdHJhbnNsZXQKLSAgICAgKiBpbnNpZGUgYSBUZW1wbGF0ZXMgb2JqZWN0IGFuZCBkdW1wcyBpdCB0byBhIGZpbGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcnVuKFN0cmluZyB4c2wpIHsKLSAgICAgICAgdHJ5IHsKLQkgICAgLy8gR2V0IGFuIGlucHV0IHN0cmVhbSBmb3IgdGhlIFhTTCBzdHlsZXNoZWV0Ci0JICAgIFN0cmVhbVNvdXJjZSBzdHlsZXNoZWV0ID0gbmV3IFN0cmVhbVNvdXJjZSh4c2wpOwotCi0JICAgIC8vIFRoZSBUcmFuc2Zvcm1lckZhY3Rvcnkgd2lsbCBjb21waWxlIHRoZSBzdHlsZXNoZWV0IGFuZAotCSAgICAvLyBwdXQgdGhlIHRyYW5zbGV0IGNsYXNzZXMgaW5zaWRlIHRoZSBUZW1wbGF0ZXMgb2JqZWN0Ci0JICAgIFRyYW5zZm9ybWVyRmFjdG9yeSBmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0JICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBmYWN0b3J5Lm5ld1RlbXBsYXRlcyhzdHlsZXNoZWV0KTsKLQotCSAgICAvLyBTZW5kIHRoZSBUZW1wbGF0ZXMgb2JqZWN0IHRvIGEgJy50cmFuc2xldCcgZmlsZQotCSAgICBkdW1wVGVtcGxhdGUoZ2V0QmFzZU5hbWUoeHNsKSsiLnRyYW5zbGV0IiwgdGVtcGxhdGVzKTsKLSAgICAgICAgfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJFeGNlcHRpb246ICIgKyBlKTsgCi0JICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLmV4aXQoMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgYmFzZS1uYW1lIG9mIGEgZmlsZS91cmwKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRCYXNlTmFtZShTdHJpbmcgZmlsZW5hbWUpIHsKLQlpbnQgc3RhcnQgPSBmaWxlbmFtZS5sYXN0SW5kZXhPZihGaWxlLnNlcGFyYXRvckNoYXIpOwotCWludCBzdG9wICA9IGZpbGVuYW1lLmxhc3RJbmRleE9mKCcuJyk7Ci0JaWYgKHN0b3AgPD0gc3RhcnQpIHN0b3AgPSBmaWxlbmFtZS5sZW5ndGgoKSAtIDE7Ci0JcmV0dXJuIGZpbGVuYW1lLnN1YnN0cmluZyhzdGFydCsxLCBzdG9wKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcml0ZXMgYSBUZW1wbGF0ZXMgb2JqZWN0IHRvIGEgZmlsZQotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBkdW1wVGVtcGxhdGUoU3RyaW5nIGZpbGUsIFRlbXBsYXRlcyB0ZW1wbGF0ZXMpIHsKLQl0cnkgewotCSAgICBGaWxlT3V0cHV0U3RyZWFtIG9zdHJlYW0gPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKTsKLQkgICAgT2JqZWN0T3V0cHV0U3RyZWFtIHAgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG9zdHJlYW0pOwotCSAgICBwLndyaXRlT2JqZWN0KHRlbXBsYXRlcyk7Ci0JICAgIHAuZmx1c2goKTsKLQkgICAgb3N0cmVhbS5jbG9zZSgpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgU3lzdGVtLmVyci5wcmludGxuKGUpOwotCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvdWxkIG5vdCB3cml0ZSBmaWxlICIrZmlsZSk7Ci0JfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB1c2FnZSgpIHsKLSAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJVc2FnZTogY29tcGlsZSA8eHNsX2ZpbGU+Iik7Ci0gICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZEpBWFAvVHJhbnNmb3JtLmphdmEgYi9zYW1wbGVzL0NvbXBpbGVkSkFYUC9UcmFuc2Zvcm0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTAyZDc0NS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkSkFYUC9UcmFuc2Zvcm0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc3ICswLDAgQEAKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheC5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsOwotCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpewotICAgICAgICBUcmFuc2Zvcm0gYXBwID0gbmV3IFRyYW5zZm9ybSgpOwotICAgICAgICBhcHAucnVuKGFyZ3MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlYWRzIGEgVGVtcGxhdGVzIG9iamVjdCBmcm9tIGEgZmlsZSwgdGhlIFRlbXBsYXRlcyBvYmplY3QgY3JlYXRlcwotICAgICAqIGEgdHJhbnNsZXQgYW5kIHdyYXBzIGl0IGluIGEgVHJhbnNmb3JtZXIuIFRoZSB0cmFuc2xldCBwZXJmb3JtcyB0aGUKLSAgICAgKiB0cmFuc2Zvcm1hdGlvbiBvbiBiZWhhbGYgb2YgdGhlIFRyYW5zZm9ybWVyLnRyYW5zZm9ybSgpIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBydW4oU3RyaW5nW10gYXJncyl7Ci0gICAgICAgIFN0cmluZyB4bWwgPSBhcmdzWzBdOwotICAgICAgICBTdHJpbmcgdHJhbnNsZXQgPSBhcmdzWzFdOwotCi0gICAgICAgIHRyeSB7Ci0JICAgIFN0cmVhbVNvdXJjZSBkb2N1bWVudCA9IG5ldyBTdHJlYW1Tb3VyY2UoeG1sKTsKLQkgICAgU3RyZWFtUmVzdWx0IHJlc3VsdCA9IG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCk7Ci0JICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSByZWFkVGVtcGxhdGVzKHRyYW5zbGV0KTsKLQkgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybShkb2N1bWVudCwgcmVzdWx0KTsKLSAgICAgICAgfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJFeGNlcHRpb246ICIgKyBlKTsgCi0JICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgU3lzdGVtLmV4aXQoMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVhZHMgYSBUZW1wbGF0ZXMgb2JqZWN0IGZyb20gYSBmaWxlCi0gICAgICovCi0gICAgcHJpdmF0ZSBUZW1wbGF0ZXMgcmVhZFRlbXBsYXRlcyhTdHJpbmcgZmlsZSkgewotCXRyeSB7Ci0JICAgIEZpbGVJbnB1dFN0cmVhbSBvc3RyZWFtID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKTsKLQkgICAgT2JqZWN0SW5wdXRTdHJlYW0gcCA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShvc3RyZWFtKTsKLQkgICAgVGVtcGxhdGVzIHRlbXBsYXRlcyA9IChUZW1wbGF0ZXMpcC5yZWFkT2JqZWN0KCk7Ci0JICAgIG9zdHJlYW0uY2xvc2UoKTsKLQkgICAgcmV0dXJuKHRlbXBsYXRlcyk7Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oZSk7Ci0JICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ291bGQgbm90IHdyaXRlIGZpbGUgIitmaWxlKTsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGJhc2UtbmFtZSBvZiBhIGZpbGUvdXJsCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0QmFzZU5hbWUoU3RyaW5nIGZpbGVuYW1lKSB7Ci0JaW50IHN0YXJ0ID0gZmlsZW5hbWUubGFzdEluZGV4T2YoRmlsZS5zZXBhcmF0b3JDaGFyKTsKLQlpbnQgc3RvcCAgPSBmaWxlbmFtZS5sYXN0SW5kZXhPZignLicpOwotCWlmIChzdG9wIDw9IHN0YXJ0KSBzdG9wID0gZmlsZW5hbWUubGVuZ3RoKCkgLSAxOwotCXJldHVybiBmaWxlbmFtZS5zdWJzdHJpbmcoc3RhcnQrMSwgc3RvcCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdXNhZ2UoKSB7Ci0gICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6IHJ1biA8eG1sX2ZpbGU+IDx4c2xfZmlsZT4iKTsKLSAgICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zYW1wbGVzL0NvbXBpbGVkU2VydmxldC9Db21waWxlU2VydmxldC5qYXZhIGIvc2FtcGxlcy9Db21waWxlZFNlcnZsZXQvQ29tcGlsZVNlcnZsZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjQ0YjRkNy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkU2VydmxldC9Db21waWxlU2VydmxldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKiAKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRlbW8uc2VydmxldDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnRleHQuKjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci0KLWltcG9ydCBqYXZheC5zZXJ2bGV0Lio7Ci1pbXBvcnQgamF2YXguc2VydmxldC5odHRwLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy51dGlsLmdldG9wdC4qOwotCi1wdWJsaWMgY2xhc3MgQ29tcGlsZVNlcnZsZXQgZXh0ZW5kcyBIdHRwU2VydmxldCB7Ci0KLSAgICAvKioKLSAgICAgKiBNYWluIHNlcnZsZXQgZW50cnkgcG9pbnQuIFRoZSBzZXJ2bGV0IHJlYWRzIGEgc3R5bGVzaGVldCBmcm9tIHRoZQotICAgICAqIFVSSSBzcGVjaWZpZWQgYnkgdGhlICJzaGVldCIgcGFyYW1ldGVyLiBUaGUgY29tcGlsZWQgSmF2YSBjbGFzcwotICAgICAqIGVuZHMgdXAgaW4gdGhlIENXRCBvZiB0aGUgd2ViIHNlcnZlciAoYSBiZXR0ZXIgc29sdXRpb24gd291bGQgYmUKLSAgICAgKiB0byBoYXZlIGFuIGVudmlyb25tZW50IHZhcmlhYmxlIHBvaW50IHRvIGEgdHJhbnNsZXQgZGlyZWN0b3J5KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb0dldChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKLQkJICAgICAgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKLQl0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24gewotCi0JcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbCIpOwotCVByaW50V3JpdGVyIG91dCA9IHJlc3BvbnNlLmdldFdyaXRlcigpOwotCQkKLQlTdHJpbmcgc3R5bGVzaGVldE5hbWUgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigic2hlZXQiKTsKLQkKLQlvdXQucHJpbnRsbigiPGh0bWw+PGhlYWQ+Iik7Ci0Jb3V0LnByaW50bG4oIjx0aXRsZT5TZXJ2bGV0IFN0eWxlc2hlZXQgQ29tcGlsYXRpb248L3RpdGxlPiIpOwotCW91dC5wcmludGxuKCI8L2hlYWQ+PGJvZHk+Iik7Ci0KLQlpZiAoc3R5bGVzaGVldE5hbWUgPT0gbnVsbCkgewotCSAgICBvdXQucHJpbnRsbigiPGgxPkNvbXBpbGF0aW9uIGVycm9yPC9oMT4iKTsKLQkgICAgb3V0LnByaW50bG4oIlRoZSBwYXJhbWV0ZXIgPGI+PHR0PnNoZWV0PC90dD48L2I+ICIrCi0JCQkibXVzdCBiZSBzcGVjaWZpZWQiKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIFhTTFRDIHhzbHRjID0gbmV3IFhTTFRDKCk7Ci0KLQkgICAgeHNsdGMuaW5pdCgpOwotCSAgICB4c2x0Yy5jb21waWxlKG5ldyBVUkwoc3R5bGVzaGVldE5hbWUpKTsKLQkgICAgb3V0LnByaW50bG4oIjxoMT5Db21waWxhdGlvbiBzdWNjZXNzZnVsPC9oMT4iKTsKLQkgICAgb3V0LnByaW50bG4oIlRoZSBzdHlsZXNoZWV0IHdhcyBjb21waWxlZCBpbnRvIHRoZSB0cmFuc2xldCAiKwotCQkJImNsYXNzICIreHNsdGMuZ2V0Q2xhc3NOYW1lKCkgKyAiIGFuZCBpcyBub3cgIisKLQkJCSJhdmFpbGFibGUgZm9yIHRyYW5zZm9ybWF0aW9ucyBvbiB0aGlzIHNlcnZlci4iKTsKLQl9Ci0Jb3V0LnByaW50bG4oIjwvYm9keT48L2h0bWw+Iik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Db21waWxlZFNlcnZsZXQvUkVBRE1FLnNlcnZsZXQgYi9zYW1wbGVzL0NvbXBpbGVkU2VydmxldC9SRUFETUUuc2VydmxldApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmQ3MDRjZi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0NvbXBpbGVkU2VydmxldC9SRUFETUUuc2VydmxldAorKysgL2Rldi9udWxsCkBAIC0xLDE3MCArMCwwIEBACi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotQ09OVEVOVFMgT0YgVEhJUyBET0NVTUVOVDoKLQotICBvKSBIT1cgVE8gUFJPVklERSBYU0wgVFJBTlNGT1JNQVRJT05TIEFTIEEgV0VCIFNFUlZJQ0UKLSAgbykgSE9XIFRPIElOVk9LRSBUUkFOU0xFVFMgRlJPTSBBIFNFUlZMRVQKLSAgbykgQlVJTERJTkcgWU9VUiBPV04gRE9NIENBQ0hFCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1IT1cgVE8gUFJPVklERSBYU0wgVFJBTlNGT1JNQVRJT05TIEFTIEEgV0VCIFNFUlZJQ0UKLQotV2l0aCBYU0xUQywgWFNMIHRyYW5zZm9ybWF0aW9ucyBjYW4gYmUgcnVuIGZyb20gd2l0aGluIGEgc2VydmxldC4gCi1UaGlzIHNhbXBsZSBjb2RlIGRlbW9uc3RyYXRlcyBob3cgdGhhdCBjYW4gYmUgaW1wbGVtZW50ZWQuCi0KLVRoZSBDb21waWxlZEVKQiBhbmQgQ29tcGlsZWRCcmF6aWwgc2FtcGxlIGNvZGUgZGVtb25zdHJhdGUgb3RoZXIgCi1hcHJvYWNoZXMgdG8gcHJvdmlkaW5nIFhTTCB0cmFuc2Zvcm1hdGlvbnMgYXMgYSB3ZWIgc2VydmljZS4KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLUhPVyBUTyBJTlZPS0UgVFJBTlNMRVRTIEZST00gQSBTRVJWTEVUCi0KLVRoZSBDb21waWxlZFNlcnZsZXQgZGlyZWN0b3J5IGNvbnRhaW5zIHRoZSBleGFtcGxlIHNvdXJjZSBjb2RlOgotCi0gICAgVHJhbnNmb3JtU2VydmxldC5qYXZhCi0KLVRoaXMgZmlsZSBjb250YWlucyBhIG1pbmltYWwgaW1wbGVtZW50YXRpb24gb2YgYW4gWFNMIHRyYW5zZm9ybWF0aW9uIAotc2VydmxldC4gSXQgdXRpbGl6ZXMgYSBjYWNoZSB0byBzdG9yZSB0aGUgRE9NIHRyZWVzIGZvciBmcmVxdWVudGx5IAotYWNjZXNzZWQgWE1MIGRvY3VtZW50cy4gVGhlc2UgYXJlIG5vdCBXM0MgRE9NIG9iamVjdHM7IFRoZXkgYXJlIAotc3BlY2lhbGl6ZWQgRE9NcywgbmF0aXZlIHRvIFhTTFRDIGFuZCBvcHRpbXplZCBmb3IgdXNlIHdpdGggY29tcGlsZWQgCi10cmFuc2xldHMuIEluIGFkZGl0aW9uIHRvIHRoZSBpbml0aWFsIGlucHV0IFhNTCBkb2N1bWVudHMsIHRoZSBjYWNoZSAKLW1heSBjb250YWluIERPTXMgZm9yIG90aGVyIFhNTCBpbnB1dCBkb2N1bWVudHMgdGhlIHRyYW5zbGV0IHJlcXVpcmVzIAotYXQgcnVudGltZSwgd2hlbiB0aGUgeHNsOmRvY3VtZW50KCkgZnVuY3Rpb24gaXMgdXNlZCBpbiB0aGUgc3R5bGVzaGVldC4KLQotSGVyZSdzIHRoZSBlc3NlbnRpYWwgY29kZSBpbiB0aGUgc2VydmxldCBmb3IgZG9pbmcgdGhlIHRyYW5zZm9ybWF0aW9uOgotCi0gICAgLy8gR2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCBjbGFzcwotICAgIENsYXNzIGNscyA9IENsYXNzLmZvck5hbWUodHJhbnNsZXROYW1lKTsKLQotICAgIC8vIEluc3RhbmNpYXRlIGEgdHJhbnNsZXQgb2JqZWN0IChpbmhlcml0cyBBYnN0cmFjdFRyYW5zbGV0KQotICAgIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCljbHMubmV3SW5zdGFuY2UoKTsKLQotICAgIC8vIFRoZSB0cmFuc2xldCBuZWVkcyBhIHJlZmVyZW5jZSB0byB0aGUgY2FjaGUgaW4gY2FzZQotICAgIC8vIGluIG5lZWRzIHRvIGxvYWQgYWRkaXRpb25hbCBYTUwgZG9jdW1lbnRzLgotICAgIHRyYW5zbGV0LnNldERPTUNhY2hlKGNhY2hlKTsKLQotICAgIC8vIEdldCB0aGUgRE9NIGZyb20gdGhlIERPTSBjYWNoZSBpZiBjdXJyZW50LCBvdGhlcndpc2UKLSAgICAvLyBidWlsZCBhbmQgY2FjaGUgdGhlIERPTSBmaXJzdAotICAgIERPTUltcGwgZG9tID0gY2FjaGUucmV0cmlldmVEb2N1bWVudChkb2N1bWVudFVSSSwgMCwgdHJhbnNsZXQpOwotCi0gICAgLy8gQ3JlYXRlIG91dHB1dCBoYW5kbGVyICh5b3UgY2FuIHBsdWcgaW4geW91ciBvd24pCi0gICAgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgc2F4SGFuZGxlcjsKLSAgICBzYXhIYW5kbGVyID0gbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKG91dCk7Ci0KLSAgICAvLyBTdGFydCB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCBuZXcgVGV4dE91dHB1dChzYXhIYW5kbGVyKSk7Ci0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1CVUlMRElORyBZT1VSIE9XTiBET00gQ0FDSEUKLQotVGhlIGludGVyZmFjZSBmb3IgdGhlIERPTSBjYWNoZSBjb25zaXN0cyBvZiBhIHNpbmdsZSBtZXRob2QsCi1hbmQgaXRzIGRlZmluaXRpb24gY2FuIGJlIGZvdW5kIGluOgotCi0gICAgb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ET01DYWNoZS5qYXZhCi0KLVRoZSBtZXRob2QgY29udGFpbmVkIGluIHRoZSBpbnRlcmZhY2UgaXM6Ci0KLSAgICBwdWJsaWMgRE9NSW1wbCByZXRyaWV2ZURvY3VtZW50KFN0cmluZyB1cmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWFzaywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGV0IHRyYW5zbGV0KTsKLQotVGhlIHJlc3BvbnNpYmlsaXRpZXMgb2YgdGhpcyBtZXRob2QgYXJlOgotCi0gQSkgQnVpbGQgbmV3IGEgRE9NSW1wbCBhbmQgRFRETW9uaXRvciBmb3IgWE1MIGRvY3VtZW50cwotICAgIHRoYXQgYXJlIG5vdCBhbHJlYWR5IGluIHRoZSBjYWNoZToKLQotICAgICAgICAvLyBJbnN0YW5jaWF0ZSBhIERPTUltcGwgb2JqZWN0Ci0gICAgICAgIFBhcnNlciAgcGFyc2VyID0gbmV3IFBhcnNlcigpOwotICAgICAgICBET01JbXBsIGRvbSA9IG5ldyBET01JbXBsKCk7Ci0gICAgICAgIC8vIFNldCBVUkkgZm9yIGltcG9ydHMsIGluY2x1ZGVzLCBhbmQgZG9jdW1lbnQoKSBmdW5jdGlvbnMKLSAgICAgICAgZG9tLnNldERvY3VtZW50VVJJKHVyaSk7Ci0gICAgICAgIHBhcnNlciA9IGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0gICAgICAgIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGRvbS5nZXRCdWlsZGVyKCkpOwotCi0gICAgICAgIC8vIFVzZSBhIERURE1vbml0b3IgdG8gdHJhY2sgSUQgcmVmZXJlbmNlcyBpbiBEVEQKLSAgICAgICAgRFRETW9uaXRvciBkdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLSAgICAgICAgZHRkTW9uaXRvci5oYW5kbGVEVEQocmVhZGVyKTsKLQotICAgICAgICAvLyBQYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgYW5kIGJ1aWxkIERPTQotICAgICAgICByZWFkZXIucGFyc2UodXJpKTsKLQotICAgIEF0IHRoaXMgcG9pbnQgdGhlIERPTUltcGwgYW5kIERURE1vbml0b3Igb2JqZWN0cyBhcmUKLSAgICBwb3B1bGF0ZWQgd2l0aCB0aGUgbmVjZXNzYXJ5IGRhdGEuIFRoZSB0d28gb2JqZWN0cwotICAgIGFyZSByZWFkeSB0byBiZSBwdXQgaW4gdGhlIGNhY2hlICh1c2luZyB0aGUgVVJJIGFzCi0gICAgdGhlIGxvb2t1cCBrZXkpLgotCi0gQikgRm9yIGVhY2ggdGltZSBhIG5ldyBkb2N1bWVudCBpcyByZXF1ZXN0ZWQgYnkgYSB0cmFuc2xldDoKLQotICAgICAgICAvLyBFeHBhbmQgdHJhbnNsZXQncyBpbmRleCBhcnJheSB0byBmaXQgdGhpcyBET00KLSAgICAgICAgdHJhbnNsZXQuc2V0SW5kZXhTaXplKGRvbS5nZXRTaXplKCkpOwotCi0gICAgICAgIC8vIEJ1aWxkIGluZGljZXMgZm9yIHRoaXMgRE9NJ3MgRFREJ3MgSUQgcmVmZXJlbmNlcwotICAgICAgICBkdGRNb25pdG9yLmJ1aWxkSWRJbmRleChkb20sIG1hc2ssIHRyYW5zbGV0KTsKLQotICAgICAgICAvLyBQYXNzIHVucGFyc2VkIGVudGl0eSBVUklzIHRvIHRoZSB0cmFuc2xldAotICAgICAgICB0cmFuc2xldC5zZXRVbnBhcnNlZEVudGl0eVVSSXMoZHRkLmdldFVucGFyc2VkRW50aXR5VVJJcygpKTsKLQotU3RlcCBBKSBtdXN0IGJlIGRvbmUgZXZlcnkgdGltZSBhIGRvY3VtZW50IGlzIHJlYWQgaW50byB0aGUKLWNhY2hlLCBhbmQgc3RlcCBCKSBldmVyeSB0aW1lIGEgZG9jdW1lbnQgaXMgZ2l2ZW4gdG8gYQotdHJhbnNsZXQuCi0KLVRoZSBYU0xUQyBwYWNrYWdlIGNvbnRhaW5zIGFuIGV4YW1wbGUgaW1wbGVtZW50YXRpb24gb2YgYQotRE9NIGNhY2hlLCBiYXNlZCBvbiBhIHZlcnkgc2ltcGxlIHJvdW5kLXJvYmluIGNhY2hpbmcKLWFsZ29yaXRobToKLQotICAgIG9yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RvY3VtZW50Q2FjaGUuamF2YQotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotRE9JTkcgVFJBTlNGT1JNQVRJT05TIFdJVEhPVVQgQSBET00gQ0FDSEUKLQotQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBwcm9ncmFtIGEgc2VydmxldCB0byBwZXJmb3JtIHRoZSBzYW1lIGJhc2ljCi1zdGVwcyBhcyB0aGUgWFNMVEMgY29tbWFuZC1saW5lIHRvb2wKLQotICAgIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY21kbGluZS5UcmFuc2Zvcm0KLQotYXMgZm9sbG93czoKLQotCi0gICAgLy8gT2J0YWluIGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCBjbGFzcwotICAgIENsYXNzIGNscyA9IENsYXNzLmZvck5hbWUodHJhbnNsZXROYW1lKTsKLSAgICAvLyBJbnN0YW5jaWF0ZSBhIHRyYW5zbGV0IG9iamVjdCAoaW5oZXJpdHMgQWJzdHJhY3RUcmFuc2xldCkKLSAgICBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0ID0gKEFic3RyYWN0VHJhbnNsZXQpY2xzLm5ld0luc3RhbmNlKCk7Ci0KLSAgICAvLyBQcmVwYXJlIHRoZSBpbnRlcm5hbCBET00gdHJlZQotICAgIGZpbmFsIERPTUltcGwgZG9tID0gbmV3IERPTUltcGwoKTsKLSAgICBkb20uc2V0RG9jdW1lbnRVUkkoaW5wdXRVUkkpOwotCi0gICAgLy8gQ3JlYXRlIGEgcGFyc2VyIGZvciB0aGUgaW5wdXQgZG9jdW1lbnQKLSAgICAvLyBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQ29uc3RhbnRzIHNldHMgTkFNRVNQQUNFX0ZFQVRVUkUKLSAgICBmaW5hbCBTQVhQYXJzZXJGYWN0b3J5IGZhY29yeSA9IFNBWEZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICB0cnkgewotICAgICAgZmFjdG9yeS5zZXRGZWF0dXJlKE5BTUVTUEFDRV9GRUFUVVJFLHRydWUpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgfQotICAgIHBhcnNlciA9IGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0gICAgcmVhZGVyID0gcGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihkb20uZ2V0QnVpbGRlcigpKTsKLQotICAgIC8vIENyZWF0ZSBhIERURE1vbml0b3IgZm9yIGhhbmRsaW5nIElEIHJlZmVyZW5jZXMgaW4gdGhlIERURAotICAgIERURE1vbml0b3IgZHRkTW9uaXRvciA9IG5ldyBEVERNb25pdG9yKCk7Ci0gICAgZHRkTW9uaXRvci5oYW5kbGVEVEQocmVhZGVyKTsKLQotICAgIC8vIENyZWF0ZSBvdXRwdXQgaGFuZGxlciAoeW91IGNhbiBwbHVnIGluIHlvdXIgb3duKQotICAgIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIHNheEhhbmRsZXI7Ci0gICAgc2F4SGFuZGxlciA9IG5ldyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihvdXQpOwotCi0gICAgLy8gUGFyc2UgdGhlIGRvY3VtZW50IGFuZCBidWlsZCB0aGUgaW50ZXJuYWwgRE9NCi0gICAgcmVhZGVyLnBhcnNlKGlucHV0VVJJKTsKLQotICAgIC8vIFBhc3MgaW5mb3JtYXRpb24gb24gaWQva2V5IGluZGljaWVzIHRvIHRoZSB0cmFuc2xldAotICAgIHRyYW5zbGV0LnNldEluZGV4U2l6ZShkb20uZ2V0U2l6ZSgpKTsKLSAgICBkdGRNb25pdG9yLmJ1aWxkSWRJbmRleChkb20sIDAsIHRyYW5zbGV0KTsKLSAgICB0cmFuc2xldC5zZXRVbnBhcnNlZEVudGl0eVVSSXMoZHRkTW9uaXRvci5nZXRVbnBhcnNlZEVudGl0eVVSSXMoKSk7Ci0KLSAgICAvLyBTdGFydCB0aGUgdHJhbnNmb3JtYXRpb24KLSAgICB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCBuZXcgVGV4dE91dHB1dChzYXhIYW5kbGVyKSk7Ci0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1FTkQgT0YgUkVBRE1FCmRpZmYgLS1naXQgYS9zYW1wbGVzL0NvbXBpbGVkU2VydmxldC9UcmFuc2Zvcm1TZXJ2bGV0LmphdmEgYi9zYW1wbGVzL0NvbXBpbGVkU2VydmxldC9UcmFuc2Zvcm1TZXJ2bGV0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhiYjRmZGYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9Db21waWxlZFNlcnZsZXQvVHJhbnNmb3JtU2VydmxldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICogCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKgotICovCi0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS50ZXh0Lio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBqYXZheC5zZXJ2bGV0Lio7Ci1pbXBvcnQgamF2YXguc2VydmxldC5odHRwLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLio7Ci0KLS8qKgotICogVGhpcyBzZXJ2bGV0IGRlbW9uc3RyYXRlcyBob3cgWFNMIHRyYW5zZm9ybWF0aW9ucyBjYW4gYmUgbWFkZSBhdmFpbGFibGUgYXMKLSAqIGEgd2ViIHNlcnZpY2UuIFNlZSB0aGUgQ29tcGlsZVNlcnZsZXQgZm9yIGFuIGV4YW1wbGUgb24gaG93IHN0eWxlc2hlZXRzCi0gKiBjYW4gYmUgcHJlLWNvbXBpbGVkIGJlZm9yZSB0aGlzIHNlcnZsZXQgaXMgaW52b2tlZC4KLSAqCi0gKiBOb3RlIHRoYXQgdGhlIFhTTFRDIHRyYW5zZm9ybWF0aW9uIGVuZ2luZSBpcyBpbnZva2VkIHRocm91Z2ggaXRzIG5hdGl2ZQotICogaW50ZXJmYWNlIGFuZCBub3QgdGhlIGphdmF4LnhtbC50cmFuc2Zvcm0gKEpBWFApIGludGVyZmFjZS4gVGhpcyBiZWNhdXNlCi0gKiBYU0xUQyBzdGlsbCBkb2VzIG5vdCBvZmZlciBwcmVjb21waWxlZCB0cmFuc2Zvcm1hdGlvbnMgdGhyb3VnaCBKQVhQLgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVHJhbnNmb3JtU2VydmxldCBleHRlbmRzIEh0dHBTZXJ2bGV0IHsKLQotICAgIC8qCi0gICAgICogVGhpcyBpcyBhIGRvY3VtZW50IGNhY2hlIHdpdGggMzIgZG9jdW1lbnQgc2xvdHMuIFRoaXMgc2VydmxldCByZXR1cm5zCi0gICAgICogY2FjaGUgc3RhdGlzdGljcyBpZiB0aGUgJ3N0YXRzJyBwYXJhbWV0ZXIgaXMgcGFzc2VkIHdpdGggdGhlIEhUVFAKLSAgICAgKiByZXF1ZXN0IGluIGRvR2V0KCkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgRG9jdW1lbnRDYWNoZSBjYWNoZSA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBNYWluIHNlcnZsZXQgZW50cnkgcG9pbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkb0dldChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKLQkJICAgICAgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKLQl0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24gewotCi0JLy8gSW5pdGlhbGlzZSB0aGUgb3V0cHV0IHdyaXRlcgotCXJlc3BvbnNlLnNldENvbnRlbnRUeXBlKCJ0ZXh0L2h0bWwiKTsKLQlQcmludFdyaXRlciBvdXQgPSByZXNwb25zZS5nZXRXcml0ZXIoKTsKLQotCS8vIEdldCB0aGUgdHdvIHBhcmFtdGVycyAiY2xhc3MiIGFuZCAic291cmNlIi4KLQlTdHJpbmcgY2xhc3NOYW1lICAgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigiY2xhc3MiKTsKLQlTdHJpbmcgZG9jdW1lbnRVUkkgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigic291cmNlIik7Ci0KLQl0cnkgewotCSAgICAvLyBJbml0aWFsaXplIGRvY3VtZW50IGNhY2hlIHdpdGggMzIgRE9NIHNsb3RzCi0JICAgIGlmIChjYWNoZSA9PSBudWxsKSBjYWNoZSA9IG5ldyBEb2N1bWVudENhY2hlKDMyKTsKLQotCSAgICBpZiAocmVxdWVzdC5nZXRQYXJhbWV0ZXIoInN0YXRzIikgIT0gbnVsbCkgewotCQljYWNoZS5nZXRTdGF0aXN0aWNzKG91dCk7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAoKGNsYXNzTmFtZSA9PSBudWxsKSB8fCAoZG9jdW1lbnRVUkkgPT0gbnVsbCkpIHsKLQkgICAgICAgIG91dC5wcmludGxuKCI8aDE+WFNMIHRyYW5zZm9ybWF0aW9uIGVycm9yPC9oMT4iKTsKLQkJb3V0LnByaW50bG4oIlRoZSBwYXJhbWV0ZXJzIDxiPjx0dD5jbGFzczwvdHQ+PC9iPiBhbmQgIiArCi0JCQkgICAgIjxiPjx0dD5zb3VyY2U8L3R0PjwvYj4gbXVzdCBiZSBzcGVjaWZpZWQiKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJLy8gR2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCBjbGFzcyAobm90IG9iamVjdCB5ZXQpCi0JICAgICAgICBDbGFzcyB0YyA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKLQkJLy8gSW5zdGFuY2lhdGUgYSB0cmFuc2xldCBvYmplY3QgKGluaGVyaXRzIEFic3RyYWN0VHJhbnNsZXQpCi0JCUFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0Yy5uZXdJbnN0YW5jZSgpOwotCi0JCS8vIFNldCB0aGUgZG9jdW1lbnQgY2FjaGUgZm9yIHRoZSB0cmFuc2xldC4gVGhpcyBpcyBuZWVkZWQgaW4KLQkJLy8gY2FzZSB0aGUgdHJhbnNsZXQgdXNlcyB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbi4KLQkJdHJhbnNsZXQuc2V0RE9NQ2FjaGUoY2FjaGUpOwotCi0JCS8vIFJlYWQgaW5wdXQgZG9jdW1lbnQgZnJvbSB0aGUgRE9NIGNhY2hlCi0JCURPTUltcGwgZG9tID0gY2FjaGUucmV0cmlldmVEb2N1bWVudChkb2N1bWVudFVSSSwgMCwgdHJhbnNsZXQpOwotCi0JCS8vIEluaXRpYWxpemUgdGhlIG91dHB1dCBoYW5kbGVyCi0JCURlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIHNheEhhbmRsZXIgPSAKLQkJICAgIG5ldyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihvdXQpOwotCi0JCS8vIFN0YXJ0IHRoZSB0cmFuc2Zvcm1hdGlvbgotCQlmaW5hbCBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCXRyYW5zbGV0LnRyYW5zZm9ybShkb20sIG5ldyBUZXh0T3V0cHV0KHNheEhhbmRsZXIpKTsKLQkJZmluYWwgbG9uZyBkb25lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKLQkJb3V0LnByaW50bG4oIjwhLS0gdHJhbnNmb3JtZWQgYnkgWFNMVEMgaW4gIitkb25lKyJtc2VjcyAtLT4iKTsKLQkgICAgfQotCX0KLQljYXRjaCAoSU9FeGNlcHRpb24gZSkgewotCSAgICBvdXQucHJpbnRsbigiPGgxPkVycm9yPC9oMT4iKTsKLQkgICAgb3V0LnByaW50bG4oIkNvdWxkIG5vdCBsb2NhdGUgc291cmNlIGRvY3VtZW50OiAiICsgZG9jdW1lbnRVUkkpOwotCSAgICBvdXQucHJpbnRsbihlLnRvU3RyaW5nKCkpOwotCX0KLQljYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0JICBvdXQucHJpbnRsbigiPGgxPkVycm9yPC9oMT4iKTsKLQkgIG91dC5wcmludGxuKCJDb3VsZCBub3QgbG9jYXRlIHRoZSB0cmFuc2xldCBjbGFzczogIiArIGNsYXNzTmFtZSk7Ci0JICBvdXQucHJpbnRsbihlLnRvU3RyaW5nKCkpOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkgICAgb3V0LnByaW50bG4oIjxoMT5FcnJvcjwvaDE+Iik7Ci0JICAgIG91dC5wcmludGxuKCJFcnJvciBwYXJzaW5nIGRvY3VtZW50ICIgKyBkb2N1bWVudFVSSSk7Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBvdXQucHJpbnRsbigiPGgxPkVycm9yPC9oMT4iKTsKLQkgICAgb3V0LnByaW50bG4oZS50b1N0cmluZygpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9ET00yRE9NL0RPTTJET00uamF2YSBiL3NhbXBsZXMvRE9NMkRPTS9ET00yRE9NLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4YzMyNjkuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9ET00yRE9NL0RPTTJET00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLy8gSW1wb3J0ZWQgVHJhWCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdDsKLQotLy8gSW1wb3J0ZWQgamF2YS5pbyBjbGFzc2VzCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLQotLy8gSW1wb3J0ZWQgU0FYIGNsYXNzZXMKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8vIEltcG9ydGVkIERPTSBjbGFzc2VzCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLy8gSW1wb3J0ZWQgU2VyaWFsaXplciBjbGFzc2VzCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLk91dHB1dFByb3BlcnRpZXM7Ci0KLS8vIEltcG9ydGVkIEpBVkEgQVBJIGZvciBYTUwgUGFyc2luZyBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsgCi0KLSAgLyoqCi0gICAqIFNob3cgaG93IHRvIHRyYW5zZm9ybSBhIERPTSB0cmVlIGludG8gYW5vdGhlciBET00gdHJlZS4gIAotICAgKiBUaGlzIHVzZXMgdGhlIGphdmF4LnhtbC5wYXJzZXJzIHRvIHBhcnNlIGJvdGggYW4gWFNMIGZpbGUgCi0gICAqIGFuZCB0aGUgWE1MIGZpbGUgaW50byBhIERPTSwgYW5kIGNyZWF0ZSBhbiBvdXRwdXQgRE9NLgotICAgKi8KLXB1YmxpYyBjbGFzcyBET00yRE9NCi17Ci0JcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAotICAgICAgICAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsgICAgCi0JICBUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgIGlmKHRGYWN0b3J5LmdldEZlYXR1cmUoRE9NU291cmNlLkZFQVRVUkUpICYmIHRGYWN0b3J5LmdldEZlYXR1cmUoRE9NUmVzdWx0LkZFQVRVUkUpKQotICAgIHsKLSAgICAgIC8vSW5zdGFudGlhdGUgYSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5LgotICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkRmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgLy8gQW5kIHNldE5hbWVzcGFjZUF3YXJlLCB3aGljaCBpcyByZXF1aXJlZCB3aGVuIHBhcnNpbmcgeHNsIGZpbGVzCi0gICAgICBkRmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgIAotICAgICAgLy9Vc2UgdGhlIERvY3VtZW50QnVpbGRlckZhY3RvcnkgdG8gY3JlYXRlIGEgRG9jdW1lbnRCdWlsZGVyLgotICAgICAgRG9jdW1lbnRCdWlsZGVyIGRCdWlsZGVyID0gZEZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgICAKLSAgICAgIC8vVXNlIHRoZSBEb2N1bWVudEJ1aWxkZXIgdG8gcGFyc2UgdGhlIFhTTCBzdHlsZXNoZWV0LgotICAgICAgRG9jdW1lbnQgeHNsRG9jID0gZEJ1aWxkZXIucGFyc2UoImJpcmRzLnhzbCIpOwotCi0gICAgICAvLyBVc2UgdGhlIERPTSBEb2N1bWVudCB0byBkZWZpbmUgYSBET01Tb3VyY2Ugb2JqZWN0LgotICAgICAgRE9NU291cmNlIHhzbERvbVNvdXJjZSA9IG5ldyBET01Tb3VyY2UoeHNsRG9jKTsKLQotICAgICAgLy8gU2V0IHRoZSBzeXN0ZW1JZDogbm90ZSB0aGlzIGlzIGFjdHVhbGx5IGEgVVJMLCBub3QgYSBsb2NhbCBmaWxlbmFtZQotICAgICAgeHNsRG9tU291cmNlLnNldFN5c3RlbUlkKCJiaXJkcy54c2wiKTsKLQotICAgICAgLy8gUHJvY2VzcyB0aGUgc3R5bGVzaGVldCBET01Tb3VyY2UgYW5kIGdlbmVyYXRlIGEgVHJhbnNmb3JtZXIuCi0gICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKHhzbERvbVNvdXJjZSk7Ci0KLSAgICAgIC8vVXNlIHRoZSBEb2N1bWVudEJ1aWxkZXIgdG8gcGFyc2UgdGhlIFhNTCBpbnB1dC4KLSAgICAgIERvY3VtZW50IHhtbERvYyA9IGRCdWlsZGVyLnBhcnNlKCJiaXJkcy54bWwiKTsKLSAgICAgIAotICAgICAgLy8gVXNlIHRoZSBET00gRG9jdW1lbnQgdG8gZGVmaW5lIGEgRE9NU291cmNlIG9iamVjdC4KLSAgICAgIERPTVNvdXJjZSB4bWxEb21Tb3VyY2UgPSBuZXcgRE9NU291cmNlKHhtbERvYyk7Ci0gICAgICAKLSAgICAgIC8vIFNldCB0aGUgYmFzZSBVUkkgZm9yIHRoZSBET01Tb3VyY2Ugc28gYW55IHJlbGF0aXZlIFVSSXMgaXQgY29udGFpbnMgY2FuCi0gICAgICAvLyBiZSByZXNvbHZlZC4KLSAgICAgIHhtbERvbVNvdXJjZS5zZXRTeXN0ZW1JZCgiYmlyZHMueG1sIik7Ci0gICAgICAKLSAgICAgIC8vIENyZWF0ZSBhbiBlbXB0eSBET01SZXN1bHQgZm9yIHRoZSBSZXN1bHQuCi0gICAgICBET01SZXN1bHQgZG9tUmVzdWx0ID0gbmV3IERPTVJlc3VsdCgpOwotICAKLSAgCSAgLy8gUGVyZm9ybSB0aGUgdHJhbnNmb3JtYXRpb24sIHBsYWNpbmcgdGhlIG91dHB1dCBpbiB0aGUgRE9NUmVzdWx0LgotICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHhtbERvbVNvdXJjZSwgZG9tUmVzdWx0KTsKLQkgIAotCSAgICAvL0luc3RhbnRpYXRlIGFuIFhhbGFuIFhNTCBzZXJpYWxpemVyIGFuZCB1c2UgaXQgdG8gc2VyaWFsaXplIHRoZSBvdXRwdXQgRE9NIHRvIFN5c3RlbS5vdXQKLQkgICAgLy8gdXNpbmcgYSBkZWZhdWx0IG91dHB1dCBmb3JtYXQuCi0gICAgICBTZXJpYWxpemVyIHNlcmlhbGl6ZXIgPSBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChPdXRwdXRQcm9wZXJ0aWVzLmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKCJ4bWwiKSk7Ci0gICAgICBzZXJpYWxpemVyLnNldE91dHB1dFN0cmVhbShTeXN0ZW0ub3V0KTsKLSAgICAgIHNlcmlhbGl6ZXIuYXNET01TZXJpYWxpemVyKCkuc2VyaWFsaXplKGRvbVJlc3VsdC5nZXROb2RlKCkpOwotCX0KLSAgICBlbHNlCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRE9NIG5vZGUgcHJvY2Vzc2luZyBub3Qgc3VwcG9ydGVkISIpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9ET00yRE9NL2JpcmRzLnhtbCBiL3NhbXBsZXMvRE9NMkRPTS9iaXJkcy54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcwMjc2NDIuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9ET00yRE9NL2JpcmRzLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPENsYXNzPgotPE9yZGVyIE5hbWU9IlRJTkFNSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iVElOQU1JREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGluYW11cyBtYWpvciI+ICBHcmVhdCBUaW5hbW91LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iTm90aG9jZXJjdXMiPkhpZ2hsYW5kIFRpbmFtb3UuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDcnlwdHVyZWxsdXMgc291aSI+TGl0dGxlIFRpbmFtb3UuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDcnlwdHVyZWxsdXMgY2lubmFtb21ldXMiPlRoaWNrZXQgVGluYW1vdS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkNyeXB0dXJlbGx1cyBib3VjYXJkaSI+U2xhdHktYnJlYXN0ZWQgVGluYW1vdS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkNyeXB0dXJlbGx1cyBrZXJyaWFlIj5DaG9jbyBUaW5hbW91LjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgPC9PcmRlcj4KLTxPcmRlciBOYW1lPSJHQVZJSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iR0FWSUlEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBzdGVsbGF0YSI+UmVkLXRocm9hdGVkIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBhcmN0aWNhIj5BcmN0aWMgTG9vbi48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkdhdmlhIHBhY2lmaWNhIj5QYWNpZmljIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBpbW1lciI+Q29tbW9uIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBhZGFtc2lpIj5ZZWxsb3ctYmlsbGVkIExvb24uPC9TcGVjaWVzPgotICAgICAgICA8L0ZhbWlseT4KLSAgICA8L09yZGVyPgotCi0KLTxPcmRlciBOYW1lPSJQT0RJQ0lQRURJRk9STUVTIj4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJQT0RJQ0lQRURJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGFjaHliYXB0dXMgZG9taW5pY3VzIj5MZWFzdCBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBvZGlseW1idXMgcG9kaWNlcHMiPlBpZWQtYmlsbGVkIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5BdGl0bGFuIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5Ib3JuZWQgR3JlYmUuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSIiPlJlZC1uZWNrZWQgR3JlYmUuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSIiPkVhcmVkIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5XZXN0ZXJuIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5DbGFyaydzIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIi8+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgIDwvT3JkZXI+Ci0KLQotPE9yZGVyIE5hbWU9IlBST0NFTExBUklJRk9STUVTIj4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJESU9NRURFSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlRoYWxhc3NhcmNoZSBjaGxvcm9yaHluY2hvcyI+WWVsbG93LW5vc2VkIEFsYmF0cm9zcy4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJUaGFsYXNzYXJjaGUgY2F1dGEiPlNoeSBBbGJhdHJvc3MuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGhhbGFzc2FyY2hlIG1lbGFub3BocmlzIj5CbGFjay1icm93ZWQgQWxiYXRyb3NzLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBob2ViZXRyaWEgcGFscGVicmF0YSI+TGlnaHQtbWFudGxlZCBBbGJhdHJvc3MuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iRGlvbWVkZWEgZXh1bGFucyI+V2FuZGVyaW5nIEFsYmF0cm9zcy4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaG9lYmFzdHJpYSBpbW11dGFiaWxpcyI+TGF5c2FuIEFsYmF0cm9zcy48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBob2ViYXN0cmlhIG5pZ3JpcGVzIj5CbGFjay1mb290ZWQgQWxiYXRyb3NzLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhvZWJhc3RyaWEgYWxiYXRydXMiPlNob3J0LXRhaWxlZCBBbGJhdHJvc3MuIChOKTwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUFJPQ0VMTEFSSUlEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJGdWxtYXJ1cyBnbGFjaWFsaXMiPk5vcnRoZXJuIEZ1bG1hci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgbmVnbGVjdGEiPktlcm1hZGVjIFBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGFybWluam9uaWFuYSI+SGVyYWxkIFBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIHVsdGltYSI+TXVycGh5J3MgUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgaW5leHBlY3RhdGEiPk1vdHRsZWQgUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgY2Fob3ciPkJlcm11ZGEgUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBoYXNpdGF0YSI+QmxhY2stY2FwcGVkIFBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgZXh0ZXJuYSI+SnVhbiBGZXJuYW5kZXogUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgcGhhZW9weWdpYSI+RGFyay1ydW1wZWQgUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBjZXJ2aWNhbGlzIj5XaGl0ZS1uZWNrZWQgUGV0cmVsLiAoSCk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgaHlwb2xldWNhIj5Cb25pbiBQZXRyZWwuIChIKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBuaWdyaXBlbm5pcyI+QmxhY2std2luZ2VkIFBldHJlbC4gKEgsIEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGNvb2tpaSI+Q29vaydzIFBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGxvbmdpcm9zdHJpcyI+U3Rlam5lZ2VyJ3MgUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkJ1bHdlcmlhIGJ1bHdlcmlpIj5CdWx3ZXIncyBQZXRyZWwuIChIKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQnVsd2VyaWEgZmFsbGF4Ij5Kb3VhbmluJ3MgUGV0cmVsLiAoSCwgQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlByb2NlbGxhcmlhIHBhcmtpbnNvbmkiPlBhcmtpbnNvbidzIFBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDYWxvbmVjdHJpcyBsZXVjb21lbGFzIj5TdHJlYWtlZCBTaGVhcndhdGVyLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkNhbG9uZWN0cmlzIGRpb21lZGVhIj5Db3J5J3MgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBjcmVhdG9wdXMiPlBpbmstZm9vdGVkIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgY2FybmVpcGVzIj5GbGVzaC1mb290ZWQgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBncmF2aXMiPkdyZWF0ZXIgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBwYWNpZmljdXMiPldlZGdlLXRhaWxlZCBTaGVhcndhdGVyLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgYnVsbGVyaSI+QnVsbGVyJ3MgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBncmlzZXVzIj5Tb290eSBTaGVhcndhdGVyLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIHRlbnVpcm9zdHJpcyI+U2hvcnQtdGFpbGVkIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgbmF0aXZpdGF0aXMiPkNocmlzdG1hcyBTaGVhcndhdGVyLiAoSCk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIHB1ZmZpbnVzIj5NYW54IFNoZWFyd2F0ZXIuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBhdXJpY3VsYXJpcyI+VG93bnNlbmQncyBTaGVhcndhdGVyLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgb3Bpc3Rob21lbGFzIj5CbGFjay12ZW50ZWQgU2hlYXJ3YXRlci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIGxoZXJtaW5pZXJpIj5BdWR1Ym9uJ3MgU2hlYXJ3YXRlci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIGFzc2ltaWxpcyI+TGl0dGxlIFNoZWFyd2F0ZXIuIChBKTwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iSFlEUk9CQVRJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5pdGVzIG9jZWFuaWN1cyI+V2lsc29uJ3MgU3Rvcm0tUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBlbGFnb2Ryb21hIG1hcmluYSI+V2hpdGUtZmFjZWQgU3Rvcm0tUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ikh5ZHJvYmF0ZXMgcGVsYWdpY3VzIj5FdXJvcGVhbiBTdG9ybS1QZXRyZWwuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgZnVyY2F0YSI+Rm9yay10YWlsZWQgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbGV1Y29yaG9hIj5MZWFjaCdzIFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIGhvbW9jaHJvYSI+QXNoeSBTdG9ybS1QZXRyZWwuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSBjYXN0cm8iPkJhbmQtcnVtcGVkIFN0b3JtLVBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSB0ZXRoeXMiPldlZGdlLXJ1bXBlZCBTdG9ybS1QZXRyZWwuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWVsYW5pYSI+QmxhY2sgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWFjcm9kYWN0eWxhIj5HdWFkYWx1cGUgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWFya2hhbWkiPk1hcmtoYW0ncyBTdG9ybS1QZXRyZWwuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgdHJpc3RyYW1pIj5UcmlzdHJhbSdzIFN0b3JtLVBldHJlbC4gKEgpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSBtaWNyb3NvbWEiPkxlYXN0IFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgIDwvT3JkZXI+Ci0KLTxPcmRlciBOYW1lPSJQRUxFQ0FOSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUEhBRVRIT05USURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWV0aG9uIGxlcHR1cnVzIj5XaGl0ZS10YWlsZWQgVHJvcGljYmlyZC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWV0aG9uIGFldGhlcmV1cyI+UmVkLWJpbGxlZCBUcm9waWNiaXJkLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhhZXRob24gcnVicmljYXVkYSI+UmVkLXRhaWxlZCBUcm9waWNiaXJkLjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iU1VMSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlN1bGEgZGFjdHlsYXRyYSI+TWFza2VkIEJvb2J5LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iU3VsYSBuZWJvdXhpaSI+Qmx1ZS1mb290ZWQgQm9vYnkuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJTdWxhIHZhcmllZ2F0YSI+UGVydXZpYW4gQm9vYnkuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iU3VsYSBsZXVjb2dhc3RlciI+QnJvd24gQm9vYnkuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJTdWxhIHN1bGEiPlJlZC1mb290ZWQgQm9vYnkuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJNb3J1cyBiYXNzYW51cyI+Tm9ydGhlcm4gR2FubmV0LjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUEVMRUNBTklEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQZWxlY2FudXMgZXJ5dGhyb3JoeW5jaG9zIj5BbWVyaWNhbiBXaGl0ZSBQZWxpY2FuLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGVsZWNhbnVzIG9jY2lkZW50YWxpcyI+QnJvd24gUGVsaWNhbi48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IlBIQUxBQ1JPQ09SQUNJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhhbGFjcm9jb3JheCBwZW5pY2lsbGF0dXMiPkJyYW5kdCdzIENvcm1vcmFudC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggYnJhc2lsaWFudXMiPk5lb3Ryb3BpYyBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IGF1cml0dXMiPkRvdWJsZS1jcmVzdGVkIENvcm1vcmFudC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggY2FyYm8iPkdyZWF0IENvcm1vcmFudC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggdXJpbGUiPlJlZC1mYWNlZCBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IHBlbGFnaWN1cyI+UGVsYWdpYyBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICA8L0ZhbWlseT4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJBTkhJTkdJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQW5oaW5nYSBhbmhpbmdhIj5BbmhpbmdhLjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iRlJFR0FUSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkZyZWdhdGEgbWFnbmlmaWNlbnMiPk1hZ25pZmljZW50IEZyaWdhdGViaXJkLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iRnJlZ2F0YSBtaW5vciI+R3JlYXQgRnJpZ2F0ZWJpcmQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJGcmVnYXRhIGFyaWVsIj5MZXNzZXIgRnJpZ2F0ZWJpcmQuIChBKTwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgPC9PcmRlcj4KLTwvQ2xhc3M+CmRpZmYgLS1naXQgYS9zYW1wbGVzL0RPTTJET00vYmlyZHMueHNsIGIvc2FtcGxlcy9ET00yRE9NL2JpcmRzLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGQ2ZjhlMS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0RPTTJET00vYmlyZHMueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMzggKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+IAotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotICA8eHNsOm91dHB1dCBtZXRob2Q9InhtbCIgaW5kZW50PSJ5ZXMiLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iQ2xhc3MiPgotPEJpcmRJbmZvPgotCTx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iT3JkZXIiLz4KLTwvQmlyZEluZm8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iT3JkZXIiPgotT3JkZXIgaXM6ICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQE5hbWUiLz4KLQk8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IkZhbWlseSIvPjx4c2w6dGV4dD4KLTwveHNsOnRleHQ+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iRmFtaWx5Ij4KLQlGYW1pbHkgaXM6ICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQE5hbWUiLz4KLQk8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IlNwZWNpZXMgfCBTdWJGYW1pbHkgfCB0ZXh0KCkiLz4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJTdWJGYW1pbHkiPgotCQlTdWJGYW1pbHkgaXMgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBOYW1lIi8+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJTcGVjaWVzIHwgdGV4dCgpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iU3BlY2llcyI+Ci0JPHhzbDpjaG9vc2U+Ci0JICA8eHNsOndoZW4gdGVzdD0ibmFtZSguLik9J1N1YkZhbWlseSciPgotCQk8eHNsOnRleHQ+CTwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48eHNsOnRleHQ+IDwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBTY2llbnRpZmljX05hbWUiLz4KLQkgIDwveHNsOndoZW4+Ci0JICA8eHNsOm90aGVyd2lzZT4KLQkJPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48eHNsOnRleHQ+IDwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBTY2llbnRpZmljX05hbWUiLz4KLQkgIDwveHNsOm90aGVyd2lzZT4KLQk8L3hzbDpjaG9vc2U+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvRE9NMkRPTS9yZWFkbWUuaHRtbCBiL3NhbXBsZXMvRE9NMkRPTS9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM4OTM2Zi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL0RPTTJET00vcmVhZG1lLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotCi08aHRtbD4KLTxoZWFkPgotCTx0aXRsZT5YYWxhbiBTYW1wbGVzPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPGgyPlhhbGFuIFNhbXBsZXM8L2gyPgotPHA+Rm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzYW1wbGVzICh3aGF0IHRoZXkgaWxsdXN0cmF0ZSBhbmQgaG93IHRvIHJ1biB0aGVtKSwgc2VlIDxhIGhyZWY9Ii4uLy4uL2RvY3Mvc2FtcGxlcy5odG1sIj5TYW1wbGVzPC9hPi48L3A+Ci0KLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9QaXBlL1BpcGUuamF2YSBiL3NhbXBsZXMvUGlwZS9QaXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQwZTI1ZGEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9QaXBlL1BpcGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLy8gSW1wb3J0ZWQgVHJhWCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdDsKLQotLy8gSW1wb3J0ZWQgU0FYIGNsYXNzZXMKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotLy8gSW1wb3J0ZWQgRE9NIGNsYXNzZXMKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vLyBJbXBvcnRlZCBTZXJpYWxpemVyIGNsYXNzZXMKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJGYWN0b3J5OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLk91dHB1dFByb3BlcnRpZXM7Ci0KLS8vIEltcG9ydGVkIEpBVkEgQVBJIGZvciBYTUwgUGFyc2luZyAxLjAgY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247IAotCi0vLyBJbXBvcnRlZCBqYXZhLmlvIGNsYXNzZXMKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotICAvKioKLSAgICogVGhpcyBleGFtcGxlIHNob3dzIGhvdyB0byBjaGFpbiBhIHNlcmllcyBvZiB0cmFuc2Zvcm1hdGlvbnMgYnkKLSAgICogcGlwaW5nIFNBWCBldmVudHMgZnJvbSBvbmUgVHJhbnNmb3JtZXIgdG8gYW5vdGhlci4gRWFjaCBUcmFuc2Zvcm1lcgotICAgKiBvcGVyYXRlcyBhcyBhIFNBWDIgWE1MRmlsdGVyL1hNTFJlYWRlci4KLSAgICovCi1wdWJsaWMgY2xhc3MgUGlwZQotewotCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCi0JdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIAotICAgICAgICAgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgkgICAKLQl7Ci0gICAgLy8gSW5zdGFudGlhdGUgIGEgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAJVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBzdXBwb3J0cyBUaGUgdXNlIHVmIFNBWFNvdXJjZSAKLSAgICAvLyBhbmQgU0FYUmVzdWx0Ci0gICAgaWYgKHRGYWN0b3J5LmdldEZlYXR1cmUoU0FYU291cmNlLkZFQVRVUkUpICYmIHRGYWN0b3J5LmdldEZlYXR1cmUoU0FYUmVzdWx0LkZFQVRVUkUpKQotICAgIHsgCi0gICAgICAvLyBDYXN0IHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgdG8gU0FYVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHNheFRGYWN0b3J5ID0gKChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRGYWN0b3J5KTsJICAKLSAgICAgIC8vIENyZWF0ZSBhIFRyYW5zZm9ybWVySGFuZGxlciBmb3IgZWFjaCBzdHlsZXNoZWV0LgotICAgICAgVHJhbnNmb3JtZXJIYW5kbGVyIHRIYW5kbGVyMSA9IHNheFRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVySGFuZGxlcihuZXcgU3RyZWFtU291cmNlKCJmb28xLnhzbCIpKTsKLSAgICAgIFRyYW5zZm9ybWVySGFuZGxlciB0SGFuZGxlcjIgPSBzYXhURmFjdG9yeS5uZXdUcmFuc2Zvcm1lckhhbmRsZXIobmV3IFN0cmVhbVNvdXJjZSgiZm9vMi54c2wiKSk7Ci0gICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgdEhhbmRsZXIzID0gc2F4VEZhY3RvcnkubmV3VHJhbnNmb3JtZXJIYW5kbGVyKG5ldyBTdHJlYW1Tb3VyY2UoImZvbzMueHNsIikpOwotICAgIAotICAgICAgLy8gQ3JlYXRlIGFuIFhNTFJlYWRlci4KLQkgICAgWE1MUmVhZGVyIHJlYWRlciA9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodEhhbmRsZXIxKTsKLSAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwgdEhhbmRsZXIxKTsKLQotICAgICAgdEhhbmRsZXIxLnNldFJlc3VsdChuZXcgU0FYUmVzdWx0KHRIYW5kbGVyMikpOwotICAgICAgdEhhbmRsZXIyLnNldFJlc3VsdChuZXcgU0FYUmVzdWx0KHRIYW5kbGVyMykpOwotCi0gICAgICAvLyB0cmFuc2Zvcm1lcjMgb3V0cHV0cyBTQVggZXZlbnRzIHRvIHRoZSBzZXJpYWxpemVyLgotICAgICAgU2VyaWFsaXplciBzZXJpYWxpemVyID0gU2VyaWFsaXplckZhY3RvcnkuZ2V0U2VyaWFsaXplcgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoT3V0cHV0UHJvcGVydGllcy5nZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcygieG1sIikpOyAgICAgICAgCi0gICAgICBzZXJpYWxpemVyLnNldE91dHB1dFN0cmVhbShTeXN0ZW0ub3V0KTsKLSAgICAgIHRIYW5kbGVyMy5zZXRSZXN1bHQobmV3IFNBWFJlc3VsdChzZXJpYWxpemVyLmFzQ29udGVudEhhbmRsZXIoKSkpOwotCi0JICAgIC8vIFBhcnNlIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQuIFRoZSBpbnB1dCBDb250ZW50SGFuZGxlciBhbmQgb3V0cHV0IENvbnRlbnRIYW5kbGVyCi0gICAgICAvLyB3b3JrIGluIHNlcGFyYXRlIHRocmVhZHMgdG8gb3B0aW1pemUgcGVyZm9ybWFuY2UuICAgCi0gICAgICByZWFkZXIucGFyc2UoImZvby54bWwiKTsKLSAgICB9Ci0gIH0KLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1BpcGUvZm9vLnhtbCBiL3NhbXBsZXMvUGlwZS9mb28ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYTlmNzliLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvUGlwZS9mb28ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+SGVsbG88L2RvYz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1BpcGUvZm9vMS54c2wgYi9zYW1wbGVzL1BpcGUvZm9vMS54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVkYThkNWUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9QaXBlL2ZvbzEueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImRvYyI+Ci0gICAgPG91dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvb3V0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL1BpcGUvZm9vMi54c2wgYi9zYW1wbGVzL1BpcGUvZm9vMi54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY3Y2QxOTcuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9QaXBlL2ZvbzIueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Im91dCI+Ci0gICAgPG91dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPiAuLi5nb29kIHRvIHNlZSB5b3UgYWdhaW4hPC9vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvUGlwZS9mb28zLnhzbCBiL3NhbXBsZXMvUGlwZS9mb28zLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODNjZmFhNi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1BpcGUvZm9vMy54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0ib3V0Ij4KLSAgICA8b3V0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+IC4uLmFuZCBnb29kYnkhPC9vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvUGlwZS9yZWFkbWUuaHRtbCBiL3NhbXBsZXMvUGlwZS9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM4OTM2Zi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1BpcGUvcmVhZG1lLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotCi08aHRtbD4KLTxoZWFkPgotCTx0aXRsZT5YYWxhbiBTYW1wbGVzPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPGgyPlhhbGFuIFNhbXBsZXM8L2gyPgotPHA+Rm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzYW1wbGVzICh3aGF0IHRoZXkgaWxsdXN0cmF0ZSBhbmQgaG93IHRvIHJ1biB0aGVtKSwgc2VlIDxhIGhyZWY9Ii4uLy4uL2RvY3Mvc2FtcGxlcy5odG1sIj5TYW1wbGVzPC9hPi48L3A+Ci0KLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9TQVgyU0FYL1NBWDJTQVguamF2YSBiL3NhbXBsZXMvU0FYMlNBWC9TQVgyU0FYLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdkMjA4YWIuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9TQVgyU0FYL1NBWDJTQVguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0OCArMCwwIEBACi0KLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqICBSZXBsaWNhdGUgdGhlIFNpbXBsZVRyYW5zZm9ybSBzYW1wbGUsIGV4cGxpY2l0bHkgdXNpbmcgdGhlIFNBWCBtb2RlbCB0byBoYW5kbGUgdGhlCi0gKiAgc3R5bGVzaGVldCwgdGhlIFhNTCBpbnB1dCwgYW5kIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAqLwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVGVtcGxhdGVzSGFuZGxlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXI7ICAgICAgICAgICAgICAKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJGYWN0b3J5OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuT3V0cHV0UHJvcGVydGllczsKLQotaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0KLXB1YmxpYyBjbGFzcyBTQVgyU0FYCi17Ci0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCi0JdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIAotICAgICAgICAgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgkgICAKLQl7Ci0KLSAgICAvLyBJbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgCVRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIC8vIERldGVybWluZSB3aGV0aGVyIHRoZSBUcmFuc2Zvcm1lckZhY3Rvcnkgc3VwcG9ydHMgVGhlIHVzZSBvZiBTQVhTb3VyY2UgCi0gICAgLy8gYW5kIFNBWFJlc3VsdAotICAgIGlmICh0RmFjdG9yeS5nZXRGZWF0dXJlKFNBWFNvdXJjZS5GRUFUVVJFKSAmJiB0RmFjdG9yeS5nZXRGZWF0dXJlKFNBWFJlc3VsdC5GRUFUVVJFKSkKLSAgICB7IAotICAgICAgLy8gQ2FzdCB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHNheFRGYWN0b3J5ID0gKChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRGYWN0b3J5KTsKLSAgICAgIC8vIENyZWF0ZSBhIENvbnRlbnRIYW5kbGVyIHRvIGhhbmRsZSBwYXJzaW5nIG9mIHRoZSBzdHlsZXNoZWV0LgotICAgICAgVGVtcGxhdGVzSGFuZGxlciB0ZW1wbGF0ZXNIYW5kbGVyID0gc2F4VEZhY3RvcnkubmV3VGVtcGxhdGVzSGFuZGxlcigpOwotCi0gICAgICAvLyBDcmVhdGUgYW4gWE1MUmVhZGVyIGFuZCBzZXQgaXRzIENvbnRlbnRIYW5kbGVyLgotICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodGVtcGxhdGVzSGFuZGxlcik7Ci0gICAgCi0gICAgICAvLyBQYXJzZSB0aGUgc3R5bGVzaGVldC4gICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgcmVhZGVyLnBhcnNlKCJiaXJkcy54c2wiKTsKLQotICAgICAgLy9HZXQgdGhlIFRlbXBsYXRlcyBvYmplY3QgZnJvbSB0aGUgQ29udGVudEhhbmRsZXIuCi0gICAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzID0gdGVtcGxhdGVzSGFuZGxlci5nZXRUZW1wbGF0ZXMoKTsKLSAgICAgIC8vIENyZWF0ZSBhIENvbnRlbnRIYW5kbGVyIHRvIGhhbmRsZSBwYXJzaW5nIG9mIHRoZSBYTUwgc291cmNlLiAgCi0gICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgaGFuZGxlciAKLSAgICAgICAgPSBzYXhURmFjdG9yeS5uZXdUcmFuc2Zvcm1lckhhbmRsZXIodGVtcGxhdGVzKTsKLSAgICAgIC8vIFJlc2V0IHRoZSBYTUxSZWFkZXIncyBDb250ZW50SGFuZGxlci4KLSAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsgIAotCi0gICAgICAvLyBTZXQgdGhlIENvbnRlbnRIYW5kbGVyIHRvIGFsc28gZnVuY3Rpb24gYXMgYSBMZXhpY2FsSGFuZGxlciwgd2hpY2gKLSAgICAgIC8vIGluY2x1ZGVzICJsZXhpY2FsIiBldmVudHMgKGUuZy4sIGNvbW1lbnRzIGFuZCBDREFUQSkuIAotICAgICAgcmVhZGVyLnNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIiLCBoYW5kbGVyKTsKLSAgICAgIAotICAgCSAgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbSgiYmlyZHMub3V0Iik7Ci0gICAgICAKLSAgICAgIFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9IFNlcmlhbGl6ZXJGYWN0b3J5LmdldFNlcmlhbGl6ZXIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChPdXRwdXRQcm9wZXJ0aWVzLmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKCJ4bWwiKSk7Ci0gICAgICBzZXJpYWxpemVyLnNldE91dHB1dFN0cmVhbShmb3MpOwotICAgCi0gICAgICAKLSAgICAgIC8vIFNldCB0aGUgcmVzdWx0IGhhbmRsaW5nIHRvIGJlIGEgc2VyaWFsaXphdGlvbiB0byB0aGUgZmlsZSBvdXRwdXQgc3RyZWFtLgotICAgICAgUmVzdWx0IHJlc3VsdCA9IG5ldyBTQVhSZXN1bHQoc2VyaWFsaXplci5hc0NvbnRlbnRIYW5kbGVyKCkpOwotICAgICAgaGFuZGxlci5zZXRSZXN1bHQocmVzdWx0KTsKLSAgICAgIAotICAgICAgLy8gUGFyc2UgdGhlIFhNTCBpbnB1dCBkb2N1bWVudC4KLSAgICAgIHJlYWRlci5wYXJzZSgiYmlyZHMueG1sIik7Ci0gICAgICAKLSAgICAJU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqIFRoZSByZXN1bHQgaXMgaW4gYmlyZHMub3V0ICoqKioqKioqKioqKioiKTsJCi0gICAgfQkKLSAgICBlbHNlCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgZG9lcyBub3Qgc3VwcG9ydCBTQVggaW5wdXQgYW5kIFNBWCBvdXRwdXQiKTsKLSAgfQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvU0FYMlNBWC9iaXJkcy54bWwgYi9zYW1wbGVzL1NBWDJTQVgvYmlyZHMueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MDI3NjQyLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU0FYMlNBWC9iaXJkcy54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMzYgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTxDbGFzcz4KLTxPcmRlciBOYW1lPSJUSU5BTUlGT1JNRVMiPgotICAgICAgICA8RmFtaWx5IE5hbWU9IlRJTkFNSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlRpbmFtdXMgbWFqb3IiPiAgR3JlYXQgVGluYW1vdS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik5vdGhvY2VyY3VzIj5IaWdobGFuZCBUaW5hbW91LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQ3J5cHR1cmVsbHVzIHNvdWkiPkxpdHRsZSBUaW5hbW91LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQ3J5cHR1cmVsbHVzIGNpbm5hbW9tZXVzIj5UaGlja2V0IFRpbmFtb3UuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDcnlwdHVyZWxsdXMgYm91Y2FyZGkiPlNsYXR5LWJyZWFzdGVkIFRpbmFtb3UuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDcnlwdHVyZWxsdXMga2VycmlhZSI+Q2hvY28gVGluYW1vdS48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgIDwvT3JkZXI+Ci08T3JkZXIgTmFtZT0iR0FWSUlGT1JNRVMiPgotICAgICAgICA8RmFtaWx5IE5hbWU9IkdBVklJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iR2F2aWEgc3RlbGxhdGEiPlJlZC10aHJvYXRlZCBMb29uLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iR2F2aWEgYXJjdGljYSI+QXJjdGljIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBwYWNpZmljYSI+UGFjaWZpYyBMb29uLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iR2F2aWEgaW1tZXIiPkNvbW1vbiBMb29uLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iR2F2aWEgYWRhbXNpaSI+WWVsbG93LWJpbGxlZCBMb29uLjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgPC9PcmRlcj4KLQotCi08T3JkZXIgTmFtZT0iUE9ESUNJUEVESUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUE9ESUNJUEVESURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlRhY2h5YmFwdHVzIGRvbWluaWN1cyI+TGVhc3QgR3JlYmUuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQb2RpbHltYnVzIHBvZGljZXBzIj5QaWVkLWJpbGxlZCBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IiI+QXRpdGxhbiBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IiI+SG9ybmVkIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5SZWQtbmVja2VkIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5FYXJlZCBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IiI+V2VzdGVybiBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IiI+Q2xhcmsncyBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IiIvPgotICAgICAgICA8L0ZhbWlseT4KLSAgICA8L09yZGVyPgotCi0KLTxPcmRlciBOYW1lPSJQUk9DRUxMQVJJSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iRElPTUVERUlEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJUaGFsYXNzYXJjaGUgY2hsb3Jvcmh5bmNob3MiPlllbGxvdy1ub3NlZCBBbGJhdHJvc3MuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGhhbGFzc2FyY2hlIGNhdXRhIj5TaHkgQWxiYXRyb3NzLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlRoYWxhc3NhcmNoZSBtZWxhbm9waHJpcyI+QmxhY2stYnJvd2VkIEFsYmF0cm9zcy4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaG9lYmV0cmlhIHBhbHBlYnJhdGEiPkxpZ2h0LW1hbnRsZWQgQWxiYXRyb3NzLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkRpb21lZGVhIGV4dWxhbnMiPldhbmRlcmluZyBBbGJhdHJvc3MuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhvZWJhc3RyaWEgaW1tdXRhYmlsaXMiPkxheXNhbiBBbGJhdHJvc3MuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaG9lYmFzdHJpYSBuaWdyaXBlcyI+QmxhY2stZm9vdGVkIEFsYmF0cm9zcy48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBob2ViYXN0cmlhIGFsYmF0cnVzIj5TaG9ydC10YWlsZWQgQWxiYXRyb3NzLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IlBST0NFTExBUklJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iRnVsbWFydXMgZ2xhY2lhbGlzIj5Ob3J0aGVybiBGdWxtYXIuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIG5lZ2xlY3RhIj5LZXJtYWRlYyBQZXRyZWwuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBhcm1pbmpvbmlhbmEiPkhlcmFsZCBQZXRyZWwuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSB1bHRpbWEiPk11cnBoeSdzIFBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGluZXhwZWN0YXRhIj5Nb3R0bGVkIFBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGNhaG93Ij5CZXJtdWRhIFBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgaGFzaXRhdGEiPkJsYWNrLWNhcHBlZCBQZXRyZWwuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGV4dGVybmEiPkp1YW4gRmVybmFuZGV6IFBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIHBoYWVvcHlnaWEiPkRhcmstcnVtcGVkIFBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgY2VydmljYWxpcyI+V2hpdGUtbmVja2VkIFBldHJlbC4gKEgpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGh5cG9sZXVjYSI+Qm9uaW4gUGV0cmVsLiAoSCk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgbmlncmlwZW5uaXMiPkJsYWNrLXdpbmdlZCBQZXRyZWwuIChILCBBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBjb29raWkiPkNvb2sncyBQZXRyZWwuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBsb25naXJvc3RyaXMiPlN0ZWpuZWdlcidzIFBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJCdWx3ZXJpYSBidWx3ZXJpaSI+QnVsd2VyJ3MgUGV0cmVsLiAoSCk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkJ1bHdlcmlhIGZhbGxheCI+Sm91YW5pbidzIFBldHJlbC4gKEgsIEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQcm9jZWxsYXJpYSBwYXJraW5zb25pIj5QYXJraW5zb24ncyBQZXRyZWwuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQ2Fsb25lY3RyaXMgbGV1Y29tZWxhcyI+U3RyZWFrZWQgU2hlYXJ3YXRlci4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDYWxvbmVjdHJpcyBkaW9tZWRlYSI+Q29yeSdzIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgY3JlYXRvcHVzIj5QaW5rLWZvb3RlZCBTaGVhcndhdGVyLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIGNhcm5laXBlcyI+Rmxlc2gtZm9vdGVkIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgZ3JhdmlzIj5HcmVhdGVyIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgcGFjaWZpY3VzIj5XZWRnZS10YWlsZWQgU2hlYXJ3YXRlci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIGJ1bGxlcmkiPkJ1bGxlcidzIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgZ3Jpc2V1cyI+U29vdHkgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyB0ZW51aXJvc3RyaXMiPlNob3J0LXRhaWxlZCBTaGVhcndhdGVyLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIG5hdGl2aXRhdGlzIj5DaHJpc3RtYXMgU2hlYXJ3YXRlci4gKEgpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBwdWZmaW51cyI+TWFueCBTaGVhcndhdGVyLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgYXVyaWN1bGFyaXMiPlRvd25zZW5kJ3MgU2hlYXJ3YXRlci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIG9waXN0aG9tZWxhcyI+QmxhY2stdmVudGVkIFNoZWFyd2F0ZXIuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBsaGVybWluaWVyaSI+QXVkdWJvbidzIFNoZWFyd2F0ZXIuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBhc3NpbWlsaXMiPkxpdHRsZSBTaGVhcndhdGVyLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IkhZRFJPQkFUSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFuaXRlcyBvY2VhbmljdXMiPldpbHNvbidzIFN0b3JtLVBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQZWxhZ29kcm9tYSBtYXJpbmEiPldoaXRlLWZhY2VkIFN0b3JtLVBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJIeWRyb2JhdGVzIHBlbGFnaWN1cyI+RXVyb3BlYW4gU3Rvcm0tUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIGZ1cmNhdGEiPkZvcmstdGFpbGVkIFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIGxldWNvcmhvYSI+TGVhY2gncyBTdG9ybS1QZXRyZWwuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSBob21vY2hyb2EiPkFzaHkgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgY2FzdHJvIj5CYW5kLXJ1bXBlZCBTdG9ybS1QZXRyZWwuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgdGV0aHlzIj5XZWRnZS1ydW1wZWQgU3Rvcm0tUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIG1lbGFuaWEiPkJsYWNrIFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIG1hY3JvZGFjdHlsYSI+R3VhZGFsdXBlIFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIG1hcmtoYW1pIj5NYXJraGFtJ3MgU3Rvcm0tUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIHRyaXN0cmFtaSI+VHJpc3RyYW0ncyBTdG9ybS1QZXRyZWwuIChIKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWljcm9zb21hIj5MZWFzdCBTdG9ybS1QZXRyZWwuPC9TcGVjaWVzPgotICAgICAgICA8L0ZhbWlseT4KLSAgICA8L09yZGVyPgotCi08T3JkZXIgTmFtZT0iUEVMRUNBTklGT1JNRVMiPgotICAgICAgICA8RmFtaWx5IE5hbWU9IlBIQUVUSE9OVElEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFldGhvbiBsZXB0dXJ1cyI+V2hpdGUtdGFpbGVkIFRyb3BpY2JpcmQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFldGhvbiBhZXRoZXJldXMiPlJlZC1iaWxsZWQgVHJvcGljYmlyZC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWV0aG9uIHJ1YnJpY2F1ZGEiPlJlZC10YWlsZWQgVHJvcGljYmlyZC48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IlNVTElEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJTdWxhIGRhY3R5bGF0cmEiPk1hc2tlZCBCb29ieS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlN1bGEgbmVib3V4aWkiPkJsdWUtZm9vdGVkIEJvb2J5LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iU3VsYSB2YXJpZWdhdGEiPlBlcnV2aWFuIEJvb2J5LiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlN1bGEgbGV1Y29nYXN0ZXIiPkJyb3duIEJvb2J5LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iU3VsYSBzdWxhIj5SZWQtZm9vdGVkIEJvb2J5LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iTW9ydXMgYmFzc2FudXMiPk5vcnRoZXJuIEdhbm5ldC48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IlBFTEVDQU5JREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGVsZWNhbnVzIGVyeXRocm9yaHluY2hvcyI+QW1lcmljYW4gV2hpdGUgUGVsaWNhbi48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBlbGVjYW51cyBvY2NpZGVudGFsaXMiPkJyb3duIFBlbGljYW4uPC9TcGVjaWVzPgotICAgICAgICA8L0ZhbWlseT4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJQSEFMQUNST0NPUkFDSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggcGVuaWNpbGxhdHVzIj5CcmFuZHQncyBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IGJyYXNpbGlhbnVzIj5OZW90cm9waWMgQ29ybW9yYW50LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhhbGFjcm9jb3JheCBhdXJpdHVzIj5Eb3VibGUtY3Jlc3RlZCBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IGNhcmJvIj5HcmVhdCBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IHVyaWxlIj5SZWQtZmFjZWQgQ29ybW9yYW50LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhhbGFjcm9jb3JheCBwZWxhZ2ljdXMiPlBlbGFnaWMgQ29ybW9yYW50LjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iQU5ISU5HSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkFuaGluZ2EgYW5oaW5nYSI+QW5oaW5nYS48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IkZSRUdBVElEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJGcmVnYXRhIG1hZ25pZmljZW5zIj5NYWduaWZpY2VudCBGcmlnYXRlYmlyZC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkZyZWdhdGEgbWlub3IiPkdyZWF0IEZyaWdhdGViaXJkLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iRnJlZ2F0YSBhcmllbCI+TGVzc2VyIEZyaWdhdGViaXJkLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgIDwvT3JkZXI+Ci08L0NsYXNzPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9TQVgyU0FYL2JpcmRzLnhzbCBiL3NhbXBsZXMvU0FYMlNBWC9iaXJkcy54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRkNmY4ZTEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9TQVgyU0FYL2JpcmRzLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDM4ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLSAgPHhzbDpvdXRwdXQgbWV0aG9kPSJ4bWwiIGluZGVudD0ieWVzIi8+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IkNsYXNzIj4KLTxCaXJkSW5mbz4KLQk8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9Ik9yZGVyIi8+Ci08L0JpcmRJbmZvPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9Ik9yZGVyIj4KLU9yZGVyIGlzOiAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBOYW1lIi8+Ci0JPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJGYW1pbHkiLz48eHNsOnRleHQ+Ci08L3hzbDp0ZXh0PgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IkZhbWlseSI+Ci0JRmFtaWx5IGlzOiAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBOYW1lIi8+Ci0JPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJTcGVjaWVzIHwgU3ViRmFtaWx5IHwgdGV4dCgpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iU3ViRmFtaWx5Ij4KLQkJU3ViRmFtaWx5IGlzIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJATmFtZSIvPgotICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iU3BlY2llcyB8IHRleHQoKSIvPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IlNwZWNpZXMiPgotCTx4c2w6Y2hvb3NlPgotCSAgPHhzbDp3aGVuIHRlc3Q9Im5hbWUoLi4pPSdTdWJGYW1pbHknIj4KLQkJPHhzbDp0ZXh0Pgk8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAU2NpZW50aWZpY19OYW1lIi8+Ci0JICA8L3hzbDp3aGVuPgotCSAgPHhzbDpvdGhlcndpc2U+Ci0JCTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAU2NpZW50aWZpY19OYW1lIi8+Ci0JICA8L3hzbDpvdGhlcndpc2U+Ci0JPC94c2w6Y2hvb3NlPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL1NBWDJTQVgvZm9vLnhtbCBiL3NhbXBsZXMvU0FYMlNBWC9mb28ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYTlmNzliLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU0FYMlNBWC9mb28ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+SGVsbG88L2RvYz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1NBWDJTQVgvZm9vLnhzbCBiL3NhbXBsZXMvU0FYMlNBWC9mb28ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZGE4ZDVlLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU0FYMlNBWC9mb28ueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImRvYyI+Ci0gICAgPG91dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvb3V0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL1NpbXBsZVRyYW5zZm9ybS9TaW1wbGVUcmFuc2Zvcm0uamF2YSBiL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL1NpbXBsZVRyYW5zZm9ybS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYjQ2YTI1Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL1NpbXBsZVRyYW5zZm9ybS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWFNMVDRKIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotLy8gSW1wb3J0ZWQgVHJhWCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLQotLy8gSW1wb3J0ZWQgamF2YSBjbGFzc2VzCi1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLS8qKgotICogIFVzZSB0aGUgVHJhWCBpbnRlcmZhY2UgdG8gcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uIGluIHRoZSBzaW1wbGVzdCBtYW5uZXIgcG9zc2libGUKLSAqICAoMyBzdGF0ZW1lbnRzKS4KLSAqLwotcHVibGljIGNsYXNzIFNpbXBsZVRyYW5zZm9ybQotewotCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIAotICAgICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsgIAotICAvLyBVc2UgdGhlIHN0YXRpYyBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKSBtZXRob2QgdG8gaW5zdGFudGlhdGUgCi0gIC8vIGEgVHJhbnNmb3JtZXJGYWN0b3J5LiBUaGUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkgCi0gIC8vIHN5c3RlbSBwcm9wZXJ0eSBzZXR0aW5nIGRldGVybWluZXMgdGhlIGFjdHVhbCBjbGFzcyB0byBpbnN0YW50aWF0ZSAtLQotICAvLyBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbC4KLQlUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQkKLQkvLyBVc2UgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBpbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyIHRoYXQgd2lsbCB3b3JrIHdpdGggIAotCS8vIHRoZSBzdHlsZXNoZWV0IHlvdSBzcGVjaWZ5LiBUaGlzIG1ldGhvZCBjYWxsIGFsc28gcHJvY2Vzc2VzIHRoZSBzdHlsZXNoZWV0Ci0gIC8vIGludG8gYSBjb21waWxlZCBUZW1wbGF0ZXMgb2JqZWN0LgotCVRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdEZhY3RvcnkubmV3VHJhbnNmb3JtZXIobmV3IFN0cmVhbVNvdXJjZSgiYmlyZHMueHNsIikpOwotCi0JLy8gVXNlIHRoZSBUcmFuc2Zvcm1lciB0byBhcHBseSB0aGUgYXNzb2NpYXRlZCBUZW1wbGF0ZXMgb2JqZWN0IHRvIGFuIFhNTCBkb2N1bWVudAotCS8vIChmb28ueG1sKSBhbmQgd3JpdGUgdGhlIG91dHB1dCB0byBhIGZpbGUgKGZvby5vdXQpLgotCXRyYW5zZm9ybWVyLnRyYW5zZm9ybShuZXcgU3RyZWFtU291cmNlKCJiaXJkcy54bWwiKSwgbmV3IFN0cmVhbVJlc3VsdChuZXcgRmlsZU91dHB1dFN0cmVhbSgiYmlyZHMub3V0IikpKTsKLQkKLQlTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKioqKioqKiogVGhlIHJlc3VsdCBpcyBpbiBiaXJkcy5vdXQgKioqKioqKioqKioqKiIpOwotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9TaW1wbGVUcmFuc2Zvcm0vYmlyZHMueG1sIGIvc2FtcGxlcy9TaW1wbGVUcmFuc2Zvcm0vYmlyZHMueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MDI3NjQyLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL2JpcmRzLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgotPENsYXNzPgotPE9yZGVyIE5hbWU9IlRJTkFNSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iVElOQU1JREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGluYW11cyBtYWpvciI+ICBHcmVhdCBUaW5hbW91LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iTm90aG9jZXJjdXMiPkhpZ2hsYW5kIFRpbmFtb3UuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDcnlwdHVyZWxsdXMgc291aSI+TGl0dGxlIFRpbmFtb3UuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDcnlwdHVyZWxsdXMgY2lubmFtb21ldXMiPlRoaWNrZXQgVGluYW1vdS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkNyeXB0dXJlbGx1cyBib3VjYXJkaSI+U2xhdHktYnJlYXN0ZWQgVGluYW1vdS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkNyeXB0dXJlbGx1cyBrZXJyaWFlIj5DaG9jbyBUaW5hbW91LjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgPC9PcmRlcj4KLTxPcmRlciBOYW1lPSJHQVZJSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iR0FWSUlEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBzdGVsbGF0YSI+UmVkLXRocm9hdGVkIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBhcmN0aWNhIj5BcmN0aWMgTG9vbi48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkdhdmlhIHBhY2lmaWNhIj5QYWNpZmljIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBpbW1lciI+Q29tbW9uIExvb24uPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJHYXZpYSBhZGFtc2lpIj5ZZWxsb3ctYmlsbGVkIExvb24uPC9TcGVjaWVzPgotICAgICAgICA8L0ZhbWlseT4KLSAgICA8L09yZGVyPgotCi0KLTxPcmRlciBOYW1lPSJQT0RJQ0lQRURJRk9STUVTIj4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJQT0RJQ0lQRURJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGFjaHliYXB0dXMgZG9taW5pY3VzIj5MZWFzdCBHcmViZS48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBvZGlseW1idXMgcG9kaWNlcHMiPlBpZWQtYmlsbGVkIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5BdGl0bGFuIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5Ib3JuZWQgR3JlYmUuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSIiPlJlZC1uZWNrZWQgR3JlYmUuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSIiPkVhcmVkIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5XZXN0ZXJuIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIj5DbGFyaydzIEdyZWJlLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iIi8+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgIDwvT3JkZXI+Ci0KLQotPE9yZGVyIE5hbWU9IlBST0NFTExBUklJRk9STUVTIj4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJESU9NRURFSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlRoYWxhc3NhcmNoZSBjaGxvcm9yaHluY2hvcyI+WWVsbG93LW5vc2VkIEFsYmF0cm9zcy4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJUaGFsYXNzYXJjaGUgY2F1dGEiPlNoeSBBbGJhdHJvc3MuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iVGhhbGFzc2FyY2hlIG1lbGFub3BocmlzIj5CbGFjay1icm93ZWQgQWxiYXRyb3NzLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBob2ViZXRyaWEgcGFscGVicmF0YSI+TGlnaHQtbWFudGxlZCBBbGJhdHJvc3MuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iRGlvbWVkZWEgZXh1bGFucyI+V2FuZGVyaW5nIEFsYmF0cm9zcy4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaG9lYmFzdHJpYSBpbW11dGFiaWxpcyI+TGF5c2FuIEFsYmF0cm9zcy48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBob2ViYXN0cmlhIG5pZ3JpcGVzIj5CbGFjay1mb290ZWQgQWxiYXRyb3NzLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhvZWJhc3RyaWEgYWxiYXRydXMiPlNob3J0LXRhaWxlZCBBbGJhdHJvc3MuIChOKTwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUFJPQ0VMTEFSSUlEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJGdWxtYXJ1cyBnbGFjaWFsaXMiPk5vcnRoZXJuIEZ1bG1hci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgbmVnbGVjdGEiPktlcm1hZGVjIFBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGFybWluam9uaWFuYSI+SGVyYWxkIFBldHJlbC4gKEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIHVsdGltYSI+TXVycGh5J3MgUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgaW5leHBlY3RhdGEiPk1vdHRsZWQgUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgY2Fob3ciPkJlcm11ZGEgUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBoYXNpdGF0YSI+QmxhY2stY2FwcGVkIFBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgZXh0ZXJuYSI+SnVhbiBGZXJuYW5kZXogUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgcGhhZW9weWdpYSI+RGFyay1ydW1wZWQgUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBjZXJ2aWNhbGlzIj5XaGl0ZS1uZWNrZWQgUGV0cmVsLiAoSCk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB0ZXJvZHJvbWEgaHlwb2xldWNhIj5Cb25pbiBQZXRyZWwuIChIKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHRlcm9kcm9tYSBuaWdyaXBlbm5pcyI+QmxhY2std2luZ2VkIFBldHJlbC4gKEgsIEEpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGNvb2tpaSI+Q29vaydzIFBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdGVyb2Ryb21hIGxvbmdpcm9zdHJpcyI+U3Rlam5lZ2VyJ3MgUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkJ1bHdlcmlhIGJ1bHdlcmlpIj5CdWx3ZXIncyBQZXRyZWwuIChIKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQnVsd2VyaWEgZmFsbGF4Ij5Kb3VhbmluJ3MgUGV0cmVsLiAoSCwgQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlByb2NlbGxhcmlhIHBhcmtpbnNvbmkiPlBhcmtpbnNvbidzIFBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJDYWxvbmVjdHJpcyBsZXVjb21lbGFzIj5TdHJlYWtlZCBTaGVhcndhdGVyLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkNhbG9uZWN0cmlzIGRpb21lZGVhIj5Db3J5J3MgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBjcmVhdG9wdXMiPlBpbmstZm9vdGVkIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgY2FybmVpcGVzIj5GbGVzaC1mb290ZWQgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBncmF2aXMiPkdyZWF0ZXIgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBwYWNpZmljdXMiPldlZGdlLXRhaWxlZCBTaGVhcndhdGVyLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgYnVsbGVyaSI+QnVsbGVyJ3MgU2hlYXJ3YXRlci4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBncmlzZXVzIj5Tb290eSBTaGVhcndhdGVyLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIHRlbnVpcm9zdHJpcyI+U2hvcnQtdGFpbGVkIFNoZWFyd2F0ZXIuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgbmF0aXZpdGF0aXMiPkNocmlzdG1hcyBTaGVhcndhdGVyLiAoSCk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIHB1ZmZpbnVzIj5NYW54IFNoZWFyd2F0ZXIuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQdWZmaW51cyBhdXJpY3VsYXJpcyI+VG93bnNlbmQncyBTaGVhcndhdGVyLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUHVmZmludXMgb3Bpc3Rob21lbGFzIj5CbGFjay12ZW50ZWQgU2hlYXJ3YXRlci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIGxoZXJtaW5pZXJpIj5BdWR1Ym9uJ3MgU2hlYXJ3YXRlci48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlB1ZmZpbnVzIGFzc2ltaWxpcyI+TGl0dGxlIFNoZWFyd2F0ZXIuIChBKTwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iSFlEUk9CQVRJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5pdGVzIG9jZWFuaWN1cyI+V2lsc29uJ3MgU3Rvcm0tUGV0cmVsLiAoTik8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBlbGFnb2Ryb21hIG1hcmluYSI+V2hpdGUtZmFjZWQgU3Rvcm0tUGV0cmVsLiAoQSk8L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ikh5ZHJvYmF0ZXMgcGVsYWdpY3VzIj5FdXJvcGVhbiBTdG9ybS1QZXRyZWwuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgZnVyY2F0YSI+Rm9yay10YWlsZWQgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbGV1Y29yaG9hIj5MZWFjaCdzIFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9Ik9jZWFub2Ryb21hIGhvbW9jaHJvYSI+QXNoeSBTdG9ybS1QZXRyZWwuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSBjYXN0cm8iPkJhbmQtcnVtcGVkIFN0b3JtLVBldHJlbC4gKE4pPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSB0ZXRoeXMiPldlZGdlLXJ1bXBlZCBTdG9ybS1QZXRyZWwuIChOKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWVsYW5pYSI+QmxhY2sgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWFjcm9kYWN0eWxhIj5HdWFkYWx1cGUgU3Rvcm0tUGV0cmVsLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgbWFya2hhbWkiPk1hcmtoYW0ncyBTdG9ybS1QZXRyZWwuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iT2NlYW5vZHJvbWEgdHJpc3RyYW1pIj5UcmlzdHJhbSdzIFN0b3JtLVBldHJlbC4gKEgpPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJPY2Vhbm9kcm9tYSBtaWNyb3NvbWEiPkxlYXN0IFN0b3JtLVBldHJlbC48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgIDwvT3JkZXI+Ci0KLTxPcmRlciBOYW1lPSJQRUxFQ0FOSUZPUk1FUyI+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUEhBRVRIT05USURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWV0aG9uIGxlcHR1cnVzIj5XaGl0ZS10YWlsZWQgVHJvcGljYmlyZC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWV0aG9uIGFldGhlcmV1cyI+UmVkLWJpbGxlZCBUcm9waWNiaXJkLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhhZXRob24gcnVicmljYXVkYSI+UmVkLXRhaWxlZCBUcm9waWNiaXJkLjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iU1VMSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlN1bGEgZGFjdHlsYXRyYSI+TWFza2VkIEJvb2J5LjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iU3VsYSBuZWJvdXhpaSI+Qmx1ZS1mb290ZWQgQm9vYnkuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJTdWxhIHZhcmllZ2F0YSI+UGVydXZpYW4gQm9vYnkuIChBKTwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iU3VsYSBsZXVjb2dhc3RlciI+QnJvd24gQm9vYnkuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJTdWxhIHN1bGEiPlJlZC1mb290ZWQgQm9vYnkuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJNb3J1cyBiYXNzYW51cyI+Tm9ydGhlcm4gR2FubmV0LjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iUEVMRUNBTklEQUUiPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQZWxlY2FudXMgZXJ5dGhyb3JoeW5jaG9zIj5BbWVyaWNhbiBXaGl0ZSBQZWxpY2FuLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGVsZWNhbnVzIG9jY2lkZW50YWxpcyI+QnJvd24gUGVsaWNhbi48L1NwZWNpZXM+Ci0gICAgICAgIDwvRmFtaWx5PgotICAgICAgICA8RmFtaWx5IE5hbWU9IlBIQUxBQ1JPQ09SQUNJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iUGhhbGFjcm9jb3JheCBwZW5pY2lsbGF0dXMiPkJyYW5kdCdzIENvcm1vcmFudC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggYnJhc2lsaWFudXMiPk5lb3Ryb3BpYyBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IGF1cml0dXMiPkRvdWJsZS1jcmVzdGVkIENvcm1vcmFudC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggY2FyYm8iPkdyZWF0IENvcm1vcmFudC48L1NwZWNpZXM+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IlBoYWxhY3JvY29yYXggdXJpbGUiPlJlZC1mYWNlZCBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJQaGFsYWNyb2NvcmF4IHBlbGFnaWN1cyI+UGVsYWdpYyBDb3Jtb3JhbnQuPC9TcGVjaWVzPgotICAgICAgICA8L0ZhbWlseT4KLSAgICAgICAgPEZhbWlseSBOYW1lPSJBTkhJTkdJREFFIj4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iQW5oaW5nYSBhbmhpbmdhIj5BbmhpbmdhLjwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgICAgIDxGYW1pbHkgTmFtZT0iRlJFR0FUSURBRSI+Ci0gICAgICAgICAgICA8U3BlY2llcyBTY2llbnRpZmljX05hbWU9IkZyZWdhdGEgbWFnbmlmaWNlbnMiPk1hZ25pZmljZW50IEZyaWdhdGViaXJkLjwvU3BlY2llcz4KLSAgICAgICAgICAgIDxTcGVjaWVzIFNjaWVudGlmaWNfTmFtZT0iRnJlZ2F0YSBtaW5vciI+R3JlYXQgRnJpZ2F0ZWJpcmQuPC9TcGVjaWVzPgotICAgICAgICAgICAgPFNwZWNpZXMgU2NpZW50aWZpY19OYW1lPSJGcmVnYXRhIGFyaWVsIj5MZXNzZXIgRnJpZ2F0ZWJpcmQuIChBKTwvU3BlY2llcz4KLSAgICAgICAgPC9GYW1pbHk+Ci0gICAgPC9PcmRlcj4KLTwvQ2xhc3M+CmRpZmYgLS1naXQgYS9zYW1wbGVzL1NpbXBsZVRyYW5zZm9ybS9iaXJkcy54c2wgYi9zYW1wbGVzL1NpbXBsZVRyYW5zZm9ybS9iaXJkcy54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRkNmY4ZTEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9TaW1wbGVUcmFuc2Zvcm0vYmlyZHMueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMzggKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+IAotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotICA8eHNsOm91dHB1dCBtZXRob2Q9InhtbCIgaW5kZW50PSJ5ZXMiLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iQ2xhc3MiPgotPEJpcmRJbmZvPgotCTx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iT3JkZXIiLz4KLTwvQmlyZEluZm8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iT3JkZXIiPgotT3JkZXIgaXM6ICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQE5hbWUiLz4KLQk8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IkZhbWlseSIvPjx4c2w6dGV4dD4KLTwveHNsOnRleHQ+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iRmFtaWx5Ij4KLQlGYW1pbHkgaXM6ICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQE5hbWUiLz4KLQk8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IlNwZWNpZXMgfCBTdWJGYW1pbHkgfCB0ZXh0KCkiLz4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJTdWJGYW1pbHkiPgotCQlTdWJGYW1pbHkgaXMgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBOYW1lIi8+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJTcGVjaWVzIHwgdGV4dCgpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iU3BlY2llcyI+Ci0JPHhzbDpjaG9vc2U+Ci0JICA8eHNsOndoZW4gdGVzdD0ibmFtZSguLik9J1N1YkZhbWlseSciPgotCQk8eHNsOnRleHQ+CTwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48eHNsOnRleHQ+IDwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBTY2llbnRpZmljX05hbWUiLz4KLQkgIDwveHNsOndoZW4+Ci0JICA8eHNsOm90aGVyd2lzZT4KLQkJPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48eHNsOnRleHQ+IDwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBTY2llbnRpZmljX05hbWUiLz4KLQkgIDwveHNsOm90aGVyd2lzZT4KLQk8L3hzbDpjaG9vc2U+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL2Zvby54bWwgYi9zYW1wbGVzL1NpbXBsZVRyYW5zZm9ybS9mb28ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYTlmNzliLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL2Zvby54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPGRvYz5IZWxsbzwvZG9jPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL2Zvby54c2wgYi9zYW1wbGVzL1NpbXBsZVRyYW5zZm9ybS9mb28ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZGE4ZDVlLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL2Zvby54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iZG9jIj4KLSAgICA8b3V0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC9vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtL3JlYWRtZS5odG1sIGIvc2FtcGxlcy9TaW1wbGVUcmFuc2Zvcm0vcmVhZG1lLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVjODkzNmYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9TaW1wbGVUcmFuc2Zvcm0vcmVhZG1lLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotCi08aHRtbD4KLTxoZWFkPgotCTx0aXRsZT5YYWxhbiBTYW1wbGVzPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPGgyPlhhbGFuIFNhbXBsZXM8L2gyPgotPHA+Rm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzYW1wbGVzICh3aGF0IHRoZXkgaWxsdXN0cmF0ZSBhbmQgaG93IHRvIHJ1biB0aGVtKSwgc2VlIDxhIGhyZWY9Ii4uLy4uL2RvY3Mvc2FtcGxlcy5odG1sIj5TYW1wbGVzPC9hPi48L3A+Ci0KLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9UcmFjZS9UcmFjZS5qYXZhIGIvc2FtcGxlcy9UcmFjZS9UcmFjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMDU5ZTRiLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVHJhY2UvVHJhY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5UcmFjZU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5QcmludFRyYWNlTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotcHVibGljIGNsYXNzIFRyYWNlCi17CQotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykKLQkgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCAKLQkJCSBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLAotCQkJIGphdmEudXRpbC5Ub29NYW55TGlzdGVuZXJzRXhjZXB0aW9uLCAKLQkJCSBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24JCQkgCi0gIHsKLSAgICAvLyBTZXQgdXAgYSBQcmludFRyYWNlTGlzdGVuZXIgb2JqZWN0IHRvIHByaW50IHRvIGEgZmlsZS4KLSAgICBqYXZhLmlvLkZpbGVXcml0ZXIgZncgPSBuZXcgamF2YS5pby5GaWxlV3JpdGVyKCJldmVudHMubG9nIik7ICAKLSAgICBqYXZhLmlvLlByaW50V3JpdGVyIHB3ID0gbmV3IGphdmEuaW8uUHJpbnRXcml0ZXIoZncsIHRydWUpOwotICAgIFByaW50VHJhY2VMaXN0ZW5lciBwdGwgPSBuZXcgUHJpbnRUcmFjZUxpc3RlbmVyKHB3KTsKLQotICAgIC8vIFByaW50IGluZm9ybWF0aW9uIGFzIGVhY2ggbm9kZSBpcyAnZXhlY3V0ZWQnIGluIHRoZSBzdHlsZXNoZWV0LgotICAgIHB0bC5tX3RyYWNlRWxlbWVudHMgPSB0cnVlOwotICAgIC8vIFByaW50IGluZm9ybWF0aW9uIGFmdGVyIGVhY2ggcmVzdWx0LXRyZWUgZ2VuZXJhdGlvbiBldmVudC4KLSAgICBwdGwubV90cmFjZUdlbmVyYXRpb24gPSB0cnVlOwotICAgIC8vIFByaW50IGluZm9ybWF0aW9uIGFmdGVyIGVhY2ggc2VsZWN0aW9uIGV2ZW50LgotICAgIHB0bC5tX3RyYWNlU2VsZWN0aW9uID0gdHJ1ZTsKLSAgICAvLyBQcmludCBpbmZvcm1hdGlvbiB3aGVuZXZlciBhIHRlbXBsYXRlIGlzIGludm9rZWQuCi0gICAgcHRsLm1fdHJhY2VUZW1wbGF0ZXMgPSB0cnVlOwotCi0gICAgLy8gU2V0IHVwIHRoZSB0cmFuc2Zvcm1hdGlvbiAgICAKLSAgIAlUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKG5ldyBTdHJlYW1Tb3VyY2UoImZvby54c2wiKSk7Ci0KLSAgICAvLyBDYXN0IHRoZSBUcmFuc2Zvcm1lciBvYmplY3QgdG8gVHJhbnNmb3JtZXJJbXBsLgotICAgIGlmICh0cmFuc2Zvcm1lciBpbnN0YW5jZW9mIFRyYW5zZm9ybWVySW1wbCkgCi0JICB7Ci0gICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXJJbXBsID0gKFRyYW5zZm9ybWVySW1wbCl0cmFuc2Zvcm1lcjsKLSAgICAgIC8vIFJlZ2lzdGVyIHRoZSBUcmFjZUxpc3RlbmVyIHdpdGggYSBUcmFjZU1hbmFnZXIgYXNzb2NpYXRlZCAKLSAgICAgIC8vIHdpdGggdGhlIFRyYW5zZm9ybWVySW1wbC4KLSAgICAgIFRyYWNlTWFuYWdlciB0ck1nciA9IHRyYW5zZm9ybWVySW1wbC5nZXRUcmFjZU1hbmFnZXIoKTsKLSAgICAgIHRyTWdyLmFkZFRyYWNlTGlzdGVuZXIocHRsKTsKLSAgICAgICAgICAgICAgICAgICAgIAotICAgICAgLy8gUGVyZm9ybSB0aGUgdHJhbnNmb3JtYXRpb24gLS1wcmludGluZyBpbmZvcm1hdGlvbiB0bwotICAgICAgLy8gdGhlIGV2ZW50cyBsb2cgZHVyaW5nIHRoZSBwcm9jZXNzLgotICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtCi0gICAgICAgICAgICAgICAgICAgICAgICAgKCBuZXcgU3RyZWFtU291cmNlKCJmb28ueG1sIiksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdChuZXcgamF2YS5pby5GaWxlV3JpdGVyKCJmb28ub3V0IikpICk7Ci0gICAgfQotICAgIC8vIENsb3NlIHRoZSBQcmludFdyaXRlciBhbmQgRmlsZVdyaXRlci4KLSAgICBwdy5jbG9zZSgpOwotICAgIGZ3LmNsb3NlKCk7Ci0gICAJU3lzdGVtLm91dC5wcmludGxuKCIqKlRoZSBvdXRwdXQgaXMgaW4gZm9vLm91dDsgdGhlIGxvZyBpcyBpbiBldmVudHMubG9nICoqKioiKTsJCi0gICAgCi0gIH0KLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1RyYWNlL2Zvby54bWwgYi9zYW1wbGVzL1RyYWNlL2Zvby54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVlNzJlMTUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9UcmFjZS9mb28ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotPHVwbG9hZD4KLSAgPGRheT4KLSAgICA8ZG93PnR1ZTwvZG93PgotICAgIDxvcmRlcj4KLSAgICAgIDxsaW5lPgotICAgICAgICAgPHByb2R1Y3Q+QmVsdDwvcHJvZHVjdD4KLSAgICAgICAgIDxwcmljZT41LjU0PC9wcmljZT4KLSAgICAgIDwvbGluZT4KLSAgICA8L29yZGVyPgotICA8L2RheT4KLSAgPGRheT4KLSAgICA8ZG93PndlZDwvZG93PgotICA8L2RheT4KLSAgPGRheT4KLSAgICA8ZG93PnRodTwvZG93PgotICAgIDxvcmRlcj4KLSAgICAgIDxsaW5lPgotICAgICAgICAgPHByb2R1Y3Q+Qm9vdHM8L3Byb2R1Y3Q+Ci0gICAgICAgICA8cHJpY2U+OS4yMzwvcHJpY2U+Ci0gICAgICA8L2xpbmU+Ci0gICAgPC9vcmRlcj4KLSAgPC9kYXk+Ci0gIDxkYXk+Ci0gICAgPGRvdz5mcmk8L2Rvdz4KLSAgICA8b3JkZXI+Ci0gICAgPC9vcmRlcj4KLSAgICA8b3JkZXI+Ci0gICAgPC9vcmRlcj4KLSAgPC9kYXk+Ci0gIDxkYXk+Ci0gICAgPGRvdz5zYXQ8L2Rvdz4KLSAgICA8b3JkZXI+Ci0gICAgICA8bGluZT4KLSAgICAgICAgIDxwcm9kdWN0PkphY2tldDwvcHJvZHVjdD4KLSAgICAgICAgIDxwcmljZT45Ljg0PC9wcmljZT4KLSAgICAgIDwvbGluZT4KLSAgICA8L29yZGVyPgotICA8L2RheT4KLSAgPGRheT4KLSAgICA8ZG93Pm1vbjwvZG93PgotICAgIDxvcmRlcj4KLSAgICA8L29yZGVyPgotICAgIDxvcmRlcj4KLSAgICAgIDxsaW5lPgotICAgICAgICAgPHByb2R1Y3Q+VGllPC9wcm9kdWN0PgotICAgICAgICAgPHByaWNlPjUuMzc8L3ByaWNlPgotICAgICAgPC9saW5lPgotICAgIDwvb3JkZXI+Ci0gIDwvZGF5PgotICA8ZGF5PgotICAgIDxkb3c+dHVlPC9kb3c+Ci0gIDwvZGF5PgotICA8ZGF5PgotICAgIDxkb3c+d2VkPC9kb3c+Ci0gICAgPG9yZGVyPgotICAgIDwvb3JkZXI+Ci0gIDwvZGF5PgotICA8ZGF5PgotICAgIDxkb3c+dGh1PC9kb3c+Ci0gICAgPG9yZGVyPgotICAgICAgPGxpbmU+Ci0gICAgICAgICA8cHJvZHVjdD5PdmVyYWxsczwvcHJvZHVjdD4KLSAgICAgICAgIDxwcmljZT4zLjE2PC9wcmljZT4KLSAgICAgIDwvbGluZT4KLSAgICA8L29yZGVyPgotICA8L2RheT4KLTwvdXBsb2FkPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9UcmFjZS9mb28ueHNsIGIvc2FtcGxlcy9UcmFjZS9mb28ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNzc1ZWU3Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVHJhY2UvZm9vLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDY5ICswLDAgQEAKLTx4c2w6c3R5bGVzaGVldAotICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIgotICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MCI+Ci0KLSAgPCEtLSBGaWxlTmFtZTogbWlzYy1ldmFucyAtLT4KLSAgPCEtLSBEb2N1bWVudDogaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCAtLT4KLSAgPCEtLSBEb2NWZXJzaW9uOiAxOTk5MTExNiAtLT4KLSAgPCEtLSBQdXJwb3NlOiBDT1BZIG9mIHBlcmYgdGVzdDsiQSBQcmFjdGljYWwgU3VnZ2VzdGlvbiBmb3IgWFNMVCBQZXJmb3JtYW5jZSBJbXByb3ZlbWVudCIgYnkgQ2xhcmsgRXZhbnMuIC0tPgotCi0gICA8eHNsOnZhcmlhYmxlIG5hbWU9ImRheS1saXN0IiAKLSAgICAgc2VsZWN0PSIvL2Rvd1tub3QoLj1mb2xsb3dpbmc6OmRvdyldIiAvPgotCi0gICA8eHNsOnZhcmlhYmxlIG5hbWU9InByb2R1Y3QtbGlzdCIgCi0gICAgICAgICAgICBzZWxlY3Q9Ii8vcHJvZHVjdFtub3QoLj1mb2xsb3dpbmc6OnByb2R1Y3QpXSIgLz4KLSAgICAgCi08eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgPHhzbDp2YXJpYWJsZSBuYW1lPSJteS10ZXN0Ij48YT48Yi8+PC9hPjwveHNsOnZhcmlhYmxlPgotICA8aHRtbD4KLSAgICA8eHNsOmNvcHktb2Ygc2VsZWN0PSIkbXktdGVzdCIvPgotICAgIDxib2R5PgotICAgIDx0YWJsZT4KLSAgICAgIDx0cj4KLSAgICAgICAgPHRkPjx4c2w6dGV4dD4gPC94c2w6dGV4dD48L3RkPgotICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJGRheS1saXN0Ij4KLSAgICAgICAgICA8eHNsOnNvcnQgb3JkZXI9ImFzY2VuZGluZyIgc2VsZWN0PSIuIiAvPgotICAgICAgICAgIDx0aD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvdGg+Ci0gICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgPC90cj4KLSAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSIkcHJvZHVjdC1saXN0Ij4KLSAgICAgICAgPHhzbDpzb3J0ICAgIG9yZGVyPSJhc2NlbmRpbmciIHNlbGVjdD0iLiIgLz4KLSAgICAgICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJwcm9kdWN0IiBzZWxlY3Q9Ii4iIC8+Ci0gICAgICAgIDx0cj4KLSAgICAgICAgICA8dGQ+Ci0gICAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iJHByb2R1Y3QiIC8+Ci0gICAgICAgICAgPC90ZD4KLSAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJGRheS1saXN0Ij4KLSAgICAgICAgICAgIDx4c2w6c29ydCBvcmRlcj0iYXNjZW5kaW5nIiBzZWxlY3Q9Ii4iIC8+Ci0gICAgICAgICAgICA8eHNsOnZhcmlhYmxlIG5hbWU9ImRheSIgc2VsZWN0PSIuIiAvPgotICAgICAgICAgICAgPHRkPgotICAgICAgICAgICAgICA8eHNsOnZhbHVlLW9mIAotICAgICAgICAgICAgIHNlbGVjdD0ic3VtKC8vcHJpY2VbLi4vcHJvZHVjdD0kcHJvZHVjdF1bLi4vLi4vLi4vZG93PSRkYXldKSIKLS8+IC4KLSAgICAgICAgICAgIDwvdGQ+Ci0gICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgICAgPHRkPgotICAgICAgICAgICAgPHhzbDp2YWx1ZS1vZiAKLSAgICAgICAgICAgICAgc2VsZWN0PSJzdW0oLy9wcmljZVsuLi9wcm9kdWN0PSRwcm9kdWN0XSkiIC8+IC4KLSAgICAgICAgICAgPC90ZD4KLSAgICAgICAgPC90cj4KLSAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgPHRyPgotICAgICAgICA8dGQ+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0PjwvdGQ+Ci0gICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSIkZGF5LWxpc3QiPgotICAgICAgICAgIDx4c2w6c29ydCAgICBvcmRlcj0iYXNjZW5kaW5nIiBzZWxlY3Q9Ii4iIC8+Ci0gICAgICAgICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYXkiIHNlbGVjdD0iLiIgLz4KLSAgICAgICAgICA8dGQ+Ci0gICAgICAgICAgICA8eHNsOnZhbHVlLW9mIAotICAgICAgICAgICAgICBzZWxlY3Q9InN1bSgvL3ByaWNlWy4uLy4uLy4uL2Rvdz0kZGF5XSkiIC8+Ci0gICAgICAgICAgPC90ZD4KLSAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgIDx0ZD4KLSAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0ic3VtKC8vcHJpY2UpIiAvPgotICAgICAgICA8L3RkPgotICAgICAgPC90cj4KLSAgICA8L3RhYmxlPgotICAgIDwvYm9keT4KLSAgPC9odG1sPgotPC94c2w6dGVtcGxhdGU+Ci08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Vc2VTdHlsZXNoZWV0UEkvVXNlU3R5bGVzaGVldFBJLmphdmEgYi9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQSS9Vc2VTdHlsZXNoZWV0UEkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWEwYzcxNC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQSS9Vc2VTdHlsZXNoZWV0UEkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vLyBJbXBvcnRlZCBUcmFYIGNsYXNzZXMKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotLy8gSW1wb3J0ZWQgamF2YS5pbyBjbGFzc2VzCi1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CQotCi1wdWJsaWMgY2xhc3MgVXNlU3R5bGVzaGVldFBJCi17Ci0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCi0JICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotCXsKLQkgIFN0cmluZyBtZWRpYT0gbnVsbCAsIHRpdGxlID0gbnVsbCwgY2hhcnNldCA9IG51bGw7Ci0JICB0cnkKLQkgIHsJCi0gICAgCVRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgU291cmNlIHN0eWxlc2hlZXQgPSB0RmFjdG9yeS5nZXRBc3NvY2lhdGVkU3R5bGVzaGVldAotICAgICAgICAobmV3IFN0cmVhbVNvdXJjZSgiZm9vWC54bWwiKSxtZWRpYSwgdGl0bGUsIGNoYXJzZXQpOwotICAgICAgCi0gICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKHN0eWxlc2hlZXQpOwotICAgICAgICAKLQkJICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoImZvb1gueG1sIiksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KG5ldyBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW0oImZvby5vdXQiKSkpOwotICAgICAgIAotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqIFRoZSByZXN1bHQgaXMgaW4gZm9vLm91dCAqKioqKioqKioqKioqIik7Ci0gICAgICAgCi0JICB9Ci0gIAkgIGNhdGNoIChFeGNlcHRpb24gZSkKLQkgIHsKLQkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLQkgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Vc2VTdHlsZXNoZWV0UEkvZm9vLnhzbCBiL3NhbXBsZXMvVXNlU3R5bGVzaGVldFBJL2Zvby54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVkYThkNWUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9Vc2VTdHlsZXNoZWV0UEkvZm9vLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDYgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+IAotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJkb2MiPgotICAgIDxvdXQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L291dD4KLSAgPC94c2w6dGVtcGxhdGU+Ci08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Vc2VTdHlsZXNoZWV0UEkvZm9vWC54bWwgYi9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQSS9mb29YLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2Q0Yjc0My4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQSS9mb29YLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDMgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08P3htbC1zdHlsZXNoZWV0IHR5cGU9InRleHQveHNsIiBocmVmPSJmb28ueHNsIj8+Ci08ZG9jPkhlbGxvPC9kb2M+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9Vc2VTdHlsZXNoZWV0UGFyYW0vVXNlU3R5bGVzaGVldFBhcmFtLmphdmEgYi9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQYXJhbS9Vc2VTdHlsZXNoZWV0UGFyYW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYThiM2M5MS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQYXJhbS9Vc2VTdHlsZXNoZWV0UGFyYW0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYU0xUNEoiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8vIEltcG9ydGVkIFRyYVggY2xhc3NlcwotLy8gSW1wb3J0ZWQgVHJhWCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLS8vIEltcG9ydGVkIFNBWCBjbGFzc2VzCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0vLyBJbXBvcnRlZCBqYXZhIGNsYXNzZXMKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBVc2UgY29tbWFuZC1saW5lIGlucHV0IGFzIGEgc3R5bGVzaGVldCBwYXJhbWV0ZXIuCi0gICAqLwotCi1wdWJsaWMgY2xhc3MgVXNlU3R5bGVzaGVldFBhcmFtCi17Ci0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCi0JdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIAotICAgICAgICAgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgkgICAKLQl7Ci0gICAgaWYoYXJncy5sZW5ndGggIT0gMSkKLSAgICB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlBsZWFzZSBwYXNzIG9uZSBzdHJpbmcgdG8gdGhpcyBwcm9ncmFtIik7Ci0gICAgICByZXR1cm47Ci0gICAgfQotICAJLy8gR2V0IHRoZSBwYXJhbWV0ZXIgdmFsdWUgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgotICAgIFN0cmluZyBwYXJhbVZhbHVlID0gYXJnc1swXTsKLQkKLSAgIAlUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKG5ldyBTdHJlYW1Tb3VyY2UoImZvby54c2wiKSk7Ci0KLQkvLyBTZXQgdGhlIHBhcmFtZXRlci4gSSBjYW4ndCBnZXQgbm9uLW51bGwgbmFtZXNwYWNlcyB0byB3b3JrISEKLSAgICB0cmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIoInBhcmFtMSIsCS8qIHBhcmFtZXRlciBuYW1lICovCi0gICAgICAgICAgICAgICAJCQkJCQkJIHBhcmFtVmFsdWUgLyogcGFyYW1ldGVyIHZhbHVlICovICk7Ci0gICAgCi0gICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoImZvby54bWwiKSwgbmV3IFN0cmVhbVJlc3VsdChTeXN0ZW0ub3V0KSk7Ci0gIH0gICAKLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQYXJhbS9mb28ueG1sIGIvc2FtcGxlcy9Vc2VTdHlsZXNoZWV0UGFyYW0vZm9vLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDNjMzJiNS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQYXJhbS9mb28ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+SGVsbG88L2RvYz4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvVXNlU3R5bGVzaGVldFBhcmFtL2Zvby54c2wgYi9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQYXJhbS9mb28ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZWUxOWRjLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVXNlU3R5bGVzaGVldFBhcmFtL2Zvby54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw3ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLSAgPHhzbDpwYXJhbSBuYW1lPSJwYXJhbTEiIHNlbGVjdD0iJ2RlZmF1bHQgdmFsdWUnIi8+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImRvYyI+Ci0gICAgPG91dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iJHBhcmFtMSIvPjwvb3V0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL1VzZVN0eWxlc2hlZXRQYXJhbS9yZWFkbWUuaHRtbCBiL3NhbXBsZXMvVXNlU3R5bGVzaGVldFBhcmFtL3JlYWRtZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYzg5MzZmLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVXNlU3R5bGVzaGVldFBhcmFtL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+WGFsYW4gU2FtcGxlczwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLTxoMj5YYWxhbiBTYW1wbGVzPC9oMj4KLTxwPkZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxlcyAod2hhdCB0aGV5IGlsbHVzdHJhdGUgYW5kIGhvdyB0byBydW4gdGhlbSksIHNlZSA8YSBocmVmPSIuLi8uLi9kb2NzL3NhbXBsZXMuaHRtbCI+U2FtcGxlczwvYT4uPC9wPgotCi0KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9Vc2VYTUxGaWx0ZXJzLmphdmEgYi9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvVXNlWE1MRmlsdGVycy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZmU3OGZkLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9Vc2VYTUxGaWx0ZXJzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLS8vIEltcG9ydGVkIFRyYVggY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyOyAgICAgICAgICAgICAgCi0KLS8vIEltcG9ydGVkIFNBWCBjbGFzc2VzCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlBhcnNlckFkYXB0ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxGaWx0ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLS8vIEltcG9ydGVkIERPTSBjbGFzc2VzCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLy8gSW1wb3J0ZWQgU2VyaWFsaXplciBjbGFzc2VzCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotCi0vLyBJbXBvcnRlZCBKQVZBIEFQSSBmb3IgWE1MIFBhcnNpbmcgY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247IAotCi0vLyBJbXBvcnRlZCBqYXZhLmlvIGNsYXNzZXMKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFRoaXMgZXhhbXBsZSBzaG93cyBob3cgdG8gY2hhaW4gYSBzZXJpZXMgb2YgdHJhbnNmb3JtYXRpb25zIGJ5Ci0gICAqIHBpcGluZyBTQVggZXZlbnRzIGZyb20gb25lIFRyYW5zZm9ybWVyIHRvIGFub3RoZXIuIEVhY2ggVHJhbnNmb3JtZXIKLSAgICogb3BlcmF0ZXMgYXMgYSBTQVgyIFhNTEZpbHRlci9YTUxSZWFkZXIuCi0gICAqLwotcHVibGljIGNsYXNzIFVzZVhNTEZpbHRlcnMKLXsKLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykKLQl0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgCi0gICAgICAgICBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCSAgIAotCXsKLSAgICAvLyBJbnN0YW50aWF0ZSAgYSBUcmFuc2Zvcm1lckZhY3RvcnkuCi0gIAlUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAvLyBEZXRlcm1pbmUgd2hldGhlciB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IHN1cHBvcnRzIFRoZSB1c2UgdWYgU0FYU291cmNlIAotICAgIC8vIGFuZCBTQVhSZXN1bHQKLSAgICBpZiAodEZhY3RvcnkuZ2V0RmVhdHVyZShTQVhTb3VyY2UuRkVBVFVSRSkgJiYgdEZhY3RvcnkuZ2V0RmVhdHVyZShTQVhSZXN1bHQuRkVBVFVSRSkpCi0gICAgeyAKLSAgICAgIC8vIENhc3QgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBTQVhUcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAgICBTQVhUcmFuc2Zvcm1lckZhY3Rvcnkgc2F4VEZhY3RvcnkgPSAoKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSkgdEZhY3RvcnkpOwotICAJICAvLyBDcmVhdGUgYW4gWE1MRmlsdGVyIGZvciBlYWNoIHN0eWxlc2hlZXQuCi0gICAgICBYTUxGaWx0ZXIgeG1sRmlsdGVyMSA9IHNheFRGYWN0b3J5Lm5ld1hNTEZpbHRlcihuZXcgU3RyZWFtU291cmNlKCJmb28xLnhzbCIpKTsKLSAgICAgIFhNTEZpbHRlciB4bWxGaWx0ZXIyID0gc2F4VEZhY3RvcnkubmV3WE1MRmlsdGVyKG5ldyBTdHJlYW1Tb3VyY2UoImZvbzIueHNsIikpOwotICAgICAgWE1MRmlsdGVyIHhtbEZpbHRlcjMgPSBzYXhURmFjdG9yeS5uZXdYTUxGaWx0ZXIobmV3IFN0cmVhbVNvdXJjZSgiZm9vMy54c2wiKSk7Ci0gICAgCi0gICAgICAvLyBDcmVhdGUgYW4gWE1MUmVhZGVyLgotCSAgICBYTUxSZWFkZXIgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAKLSAgICAgIC8vIHhtbEZpbHRlcjEgdXNlcyB0aGUgWE1MUmVhZGVyIGFzIGl0cyByZWFkZXIuCi0gICAgICB4bWxGaWx0ZXIxLnNldFBhcmVudChyZWFkZXIpOwotICAgIAotICAgICAgLy8geG1sRmlsdGVyMiB1c2VzIHhtbEZpbHRlcjEgYXMgaXRzIHJlYWRlci4KLSAgICAgIHhtbEZpbHRlcjIuc2V0UGFyZW50KHhtbEZpbHRlcjEpOwotICAgIAotICAgICAgLy8geG1sRmlsdGVyMyB1c2VzIHhtbEZpbHRlcjIgYXMgaXRzIHJlYWRlci4KLSAgICAgIHhtbEZpbHRlcjMuc2V0UGFyZW50KHhtbEZpbHRlcjIpOwotICAgIAotICAgICAgLy8geG1sRmlsdGVyMyBvdXRwdXRzIFNBWCBldmVudHMgdG8gdGhlIHNlcmlhbGl6ZXIuCi0gICAgICBTZXJpYWxpemVyIHNlcmlhbGl6ZXIgPSBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChPdXRwdXRQcm9wZXJ0aWVzLmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKCJ4bWwiKSk7ICAgICAgICAKLSAgICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0U3RyZWFtKFN5c3RlbS5vdXQpOwotICAgICAgeG1sRmlsdGVyMy5zZXRDb250ZW50SGFuZGxlcihzZXJpYWxpemVyLmFzQ29udGVudEhhbmRsZXIoKSk7Ci0KLSAgCSAgLy8gUGVyZm9ybSB0aGUgc2VyaWVzIG9mIHRyYW5zZm9ybWF0aW9ucyBhcyBmb2xsb3dzOgotCSAgICAvLyAgIC0gdHJhbnNmb3JtZXIzIGdldHMgaXRzIHBhcmVudCAodHJhbnNmb3JtZXIyKSBhcyB0aGUgWE1MUmVhZGVyL1hNTEZpbHRlcgotCSAgICAvLyAgICAgYW5kIGNhbGxzIHRyYW5zZm9ybWVyMi5wYXJzZShuZXcgSW5wdXRTb3VyY2UoImZvby54bWwiKSkuCi0gICAgICAvLyAgIC0gdHJhbnNmb3JtZXIyIGdldHMgaXRzIHBhcmVudCAodHJhbnNmb3JtZXIxKSBhcyB0aGUgWE1MUmVhZGVyL1hNTEZpbHRlcgotCSAgICAvLyAgICAgYW5kIGNhbGxzIHRyYW5zZm9ybWVyMS5wYXJzZShuZXcgSW5wdXRTb3VyY2UoImZvby54bWwiKSkuIAotICAgICAgLy8gICAtIHRyYW5zZm9ybWVyMSBnZXRzIGl0cyBwYXJlbnQgKHJlYWRlciwgYSBTQVhQYXJzZXIpIGFzIHRoZSBYTUxSZWFkZXIgCi0gICAgICAvLyAgICAgYW5kIGNhbGxzIHJlYWRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoImZvby54bWwiKSkuCi0JICAgIC8vICAgLSByZWFkZXIgcGFyc2VzIHRoZSBYTUwgZG9jdW1lbnQgYW5kIHNlbmRzIHRoZSBTQVggcGFyc2UgZXZlbnRzIHRvIHRyYW5zZm9ybWVyMSwgCi0JICAgIC8vICAgICB3aGljaCBwZXJmb3JtcyB0cmFuc2Zvcm1hdGlvbiAxIGFuZCBzZW5kcyB0aGUgb3V0cHV0IHRvIHRyYW5zZm9ybWVyMi4KLSAgCSAgLy8gICAtIHRyYW5zZm9ybWVyMiBwYXJzZXMgdGhlIHRyYW5zZm9ybWF0aW9uIDEgb3V0cHV0LCBwZXJmb3JtcyB0cmFuc2Zvcm1hdGlvbiAyLCBhbmQgCi0JICAgIC8vICAgICBzZW5kcyB0aGUgb3V0cHV0IHRvIHRyYW5zZm9ybWVyMy4KLQkgICAgLy8gICAtIHRyYW5zZm9ybWVyMyBwYXJzZXMgdGhlIHRyYW5zZm9ybWF0aW9uIDIgb3V0cHV0LCBwZXJmb3JtcyB0cmFuc2Zvcm1hdGlvbiAzLAotICAJICAvLyAgICAgYW5kIHNlbmRzIHRoZSBvdXRwdXQgdG8gdGhlIHNlcmlhbGl6ZXIuCi0gICAgICB4bWxGaWx0ZXIzLnBhcnNlKG5ldyBJbnB1dFNvdXJjZSgiZm9vLnhtbCIpKTsKLSAgICB9Ci0gIH0KLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvZm9vLnhtbCBiL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9mb28ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYTlmNzliLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9mb28ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+SGVsbG88L2RvYz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvZm9vMS54c2wgYi9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvZm9vMS54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVkYThkNWUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9Vc2VYTUxGaWx0ZXJzL2ZvbzEueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImRvYyI+Ci0gICAgPG91dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvb3V0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvZm9vMi54c2wgYi9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvZm9vMi54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY3Y2QxOTcuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9Vc2VYTUxGaWx0ZXJzL2ZvbzIueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Im91dCI+Ci0gICAgPG91dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPiAuLi5nb29kIHRvIHNlZSB5b3UgYWdhaW4hPC9vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9mb28zLnhzbCBiL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9mb28zLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODNjZmFhNi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvZm9vMy54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0ib3V0Ij4KLSAgICA8b3V0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+IC4uLmFuZCBnb29kYnkhPC9vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9yZWFkbWUuaHRtbCBiL3NhbXBsZXMvVXNlWE1MRmlsdGVycy9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM4OTM2Zi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL1VzZVhNTEZpbHRlcnMvcmVhZG1lLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotCi08aHRtbD4KLTxoZWFkPgotCTx0aXRsZT5YYWxhbiBTYW1wbGVzPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPGgyPlhhbGFuIFNhbXBsZXM8L2gyPgotPHA+Rm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzYW1wbGVzICh3aGF0IHRoZXkgaWxsdXN0cmF0ZSBhbmQgaG93IHRvIHJ1biB0aGVtKSwgc2VlIDxhIGhyZWY9Ii4uLy4uL2RvY3Mvc2FtcGxlcy5odG1sIj5TYW1wbGVzPC9hPi48L3A+Ci0KLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9WYWxpZGF0ZS9WYWxpZGF0ZS5qYXZhIGIvc2FtcGxlcy9WYWxpZGF0ZS9WYWxpZGF0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NTMyZjc2Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvVmFsaWRhdGUvVmFsaWRhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotLy8gSW1wb3J0ZWQgSkFYUCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotLy8gU0FYIGltcG9ydAotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLS8vIEltcG9ydGVkIGphdmEuaW8gY2xhc3NlcwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZW5hbWVGaWx0ZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOwotCi0vKiBVc2UgSkFYUCBTQVhQYXJzZXIgdG8gcGFyc2UgMSAueG1sIGZpbGUgb3IgYWxsIHRoZSAueG1sIGZpbGVzIGluIGEgZGlyZWN0b3J5LgotICogVGFrZXMgMSBvciAyIGNvbW1hbmQtbGluZSBhcmd1bWVudHM6Ci0gKiAgIEFyZ3VtZW50IDEgKHJlcXVpcmVkKSBpcyBhIGZpbGUgbmFtZSBvciBkaXJlY3RvcnkgbmFtZS4KLSAqICAgQXJndW1lbnQgMiAob3B0aW9uYWwpIGlzIGEgbG9nIGZpbGUgbmFtZS4gSWYgb21taXR0ZWQsIG1lc3NhZ2VzIGFyZSB3cml0dGVuIHRvIHNjcmVlbi4KLSAqLwotcHVibGljIGNsYXNzIFZhbGlkYXRlCi17Ci0gIHN0YXRpYyBpbnQgbnVtWE1MRmlsZXMgPSAwOwotICBzdGF0aWMgaW50IG51bVZhbGlkRmlsZXMgPSAwOwotICBzdGF0aWMgaW50IG51bUludmFsaWRGaWxlcyA9IDA7Ci0gIHN0YXRpYyBpbnQgbnVtRmlsZXNNaXNzaW5nRG9jdHlwZSA9IDA7Ci0gIHN0YXRpYyBpbnQgbnVtTWFsZm9ybWVkRmlsZXMgPSAwOwotICBzdGF0aWMgYm9vbGVhbiB1c2VMb2dGaWxlID0gZmFsc2U7Ci0gIHN0YXRpYyBTdHJpbmdCdWZmZXIgYnVmZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQotICAgIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmIChhcmdzLmxlbmd0aCA9PSAwIHx8IGFyZ3MubGVuZ3RoID4gMikKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuRW50ZXIgJ2phdmEgdmFsaWRhdGUgLWhlbHAnIGZvciBpbmZvcm1hdGlvbiBhYm91dCBydW5uaW5nIFZhbGlkYXRlIik7Ci0gICAgICByZXR1cm47Ci0gICAgfQotICAgIGlmIChhcmdzWzBdLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCItaGVscCIpKQotICAgIHsgCi0gICAgICBTdHJpbmcgc2VwID0gIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIjsKLSAgICAgIFN0cmluZyBhID0gIlZhbGlkYXRlIHVzZXMgWGVyY2VzIHRvIHBhcnNlIHRoZSB4bWwgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeSB5b3Ugc3BlY2lmeSBvciB0aGUgaW5kaXZpZHVhbCB4bWwgZmlsZSB5b3Ugc3BlY2lmeS4gVGhlIHBhcnNlciB2YWxpZGF0ZXMgZWFjaCBkb2N1bWVudCAoY2hlY2tzIHRoYXQgaXQgY29uZm9ybXMgdG8gaXRzIERPQ1RZUEUpLlxuIjsKLSAgICAgIFN0cmluZyBiID0gIkVhY2ggeG1sIGZpbGUgc2hvdWxkIGNvbnRhaW4gYSBET0NUWVBFIGRlY2xhcmF0aW9uLlxuXG4iOwotICAgICAgU3RyaW5nIGMgPSAiVmFsaWRhdGUgdGFrZXMgMSBvciAyIGFyZ3VtZW50czpcbiI7Ci0gICAgICBTdHJpbmcgZCA9ICIgQXJndW1lbnQgMSBzcGVjaWZpZXMgYSBkaXJlY3Rvcnkgb3IgYW4gaW5kaXZpZHVhbCB4bWwgZmlsZS5cbiI7Ci0gICAgICBTdHJpbmcgZSA9ICIgQXJndW1lbnQgMiBzcGVjaWZpZXMgYSBsb2cgZmlsZS4gSWYgeW91IGluY2x1ZGUgdGhpcyBhcmd1bWVudCwgVmFsaWRhdGUgYXBwZW5kcyBtZXNzYWdlcyB0byB0aGlzIGZpbGUuIElmIHlvdSBkbyBub3QsIFZhbGlkYXRlIHdyaXRlcyBtZXNzYWdlcyB0byB0aGUgc2NyZWVuLlxuIjsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihzZXArYStiK2MrZCtlK3NlcCk7Ci0gICAgICByZXR1cm47Ci0gICAgfSAgICAKLSAgICB0cnkKLSAgICB7Ci0gICAgICBWYWxpZGF0ZSB2ID0gbmV3IFZhbGlkYXRlKCk7Ci0gICAgICB2LnZhbGlkYXRlKGFyZ3MpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICB9ICAgIAotICB9Ci0gIAotICB2b2lkIHZhbGlkYXRlKFN0cmluZ1tdIGFyZ3MpCi0gICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgRmlsZSBkaXIgPSBuZXcgRmlsZShhcmdzWzBdKTsKLSAgIAotICAgIC8vIFVzZXIgbWF5IGluY2x1ZGUgYSAybmQgYXJndW1lbnQgZm9yIHRoZSBsb2cgZmlsZS4gCi0gICAgdXNlTG9nRmlsZSA9IChhcmdzLmxlbmd0aCA9PSAyKTsKLSAgIAotICAgIGlmIChkaXIuaXNGaWxlKCkpIC8vIEp1c3QgY2hlY2tpbmcgb25lIGZpbGUuCi0gICAgewotICAgICAgcGFyc2UobnVsbCxhcmdzWzBdKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoZGlyLmlzRGlyZWN0b3J5KCkpICAvLyBDaGVja2luZyB0aGUgY29udGVudHMgb2YgYSBkaXJlY3RvcnkuCi0gICAgewotICAgICAgLy8gT25seSBpbnRlcmVzdGVkIGluIC54bWwgZmlsZXMuCi0gICAgICBYTUxGaWxlRmlsdGVyIGZpbHRlciA9IG5ldyBYTUxGaWxlRmlsdGVyKCk7Ci0gICAgICBTdHJpbmcgW10gZmlsZXMgPSBkaXIubGlzdChmaWx0ZXIpOwotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPGZpbGVzLmxlbmd0aDsgaSsrKQotICAgICAgeyAKLSAgICAgICAgcGFyc2UoZGlyLnRvU3RyaW5nKCksZmlsZXNbaV0pOyAvLyBBbGwgdGhlIHdvcmsgaXMgZG9uZSBoZXJlLgotICAgICAgICAKLSAgICAgICAgaWYgKCF1c2VMb2dGaWxlKSAKLSAgICAgICAgLy8gV3JpdGUgbWVzc2FnZXMgdG8gc2NyZWVuIGFmdGVyIHBhcnNpbmcgZWFjaCBmaWxlLgotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludChidWZmLnRvU3RyaW5nKCkpOwotICAgICAgICAgIGJ1ZmYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSAvLyBDb21tYW5kLWxpbmUgYXJndW1lbnQgaXMgbm8gZ29vZCEKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oYXJnc1swXSArICIgbm90IGZvdW5kISIpOwotICAgICAgcmV0dXJuOwotICAgIH0KLSAgICAvLyBQcm92aWRlIHVzZXIgd2l0aCBhIHN1bW1hcnkuCi0gICAgYnVmZi5hcHBlbmQoIj09PT09PT09PT09PT09PT1TVU1NQVJZPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwotICAgIGlmIChudW1YTUxGaWxlcyA+IDEpCi0gICAgICBidWZmLmFwcGVuZCgiUGFyc2VkICIgKyBudW1YTUxGaWxlcyArICIgLnhtbCBmaWxlcyBpbiAiICsgIGFyZ3NbMF0gKyAiLlxuIik7Ci0gICAgaWYgKG51bVZhbGlkRmlsZXMgPiAxKQotICAgICAgYnVmZi5hcHBlbmQoIG51bVZhbGlkRmlsZXMgKyAiIGZpbGVzIGFyZSB2YWxpZC5cbiIpOwotICAgIGVsc2UgaWYgKG51bVZhbGlkRmlsZXMgPT0gMSkKLSAgICAgIGJ1ZmYuYXBwZW5kKCBudW1WYWxpZEZpbGVzICsgIiBmaWxlIGlzIHZhbGlkLlxuIik7Ci0gICAgaWYgKG51bUludmFsaWRGaWxlcyA+IDEpCi0gICAgICBidWZmLmFwcGVuZChudW1JbnZhbGlkRmlsZXMgKyAiIGZpbGVzIGFyZSBub3QgdmFsaWQuXG4iKTsKLSAgICBlbHNlIGlmIChudW1JbnZhbGlkRmlsZXMgPT0gMSkKLSAgICAgIGJ1ZmYuYXBwZW5kKCBudW1JbnZhbGlkRmlsZXMgKyAiIGZpbGUgaXMgbm90IHZhbGlkLlxuIik7Ci0gICAgaWYgKG51bU1hbGZvcm1lZEZpbGVzID4gMSkKLSAgICAgIGJ1ZmYuYXBwZW5kKG51bU1hbGZvcm1lZEZpbGVzICsgIiBmaWxlcyBhcmUgbm90IHdlbGwtZm9ybWVkLlxuIik7Ci0gICAgZWxzZSBpZiAobnVtTWFsZm9ybWVkRmlsZXMgPT0gMSkKLSAgICAgIGJ1ZmYuYXBwZW5kKCBudW1NYWxmb3JtZWRGaWxlcyArICIgZmlsZSBpcyBub3Qgd2VsbC1mb3JtZWQuXG4iKTsKLSAgICBpZiAobnVtRmlsZXNNaXNzaW5nRG9jdHlwZSA+IDEpCi0gICAgICBidWZmLmFwcGVuZChudW1GaWxlc01pc3NpbmdEb2N0eXBlICsgIiBmaWxlcyBkbyBub3QgY29udGFpbiBhIERPQ1RZUEUgZGVjbGFyYXRpb24uXG4iKTsKLSAgICBlbHNlIGlmIChudW1GaWxlc01pc3NpbmdEb2N0eXBlID09IDEpCi0gICAgICBidWZmLmFwcGVuZChudW1GaWxlc01pc3NpbmdEb2N0eXBlICsgIiBmaWxlIGRvZXMgbm90IGNvbnRhaW4gYSBET0NUWVBFIGRlY2xhcmF0aW9uLlxuIik7Ci0gICAgIAotICAgIGlmICghdXNlTG9nRmlsZSkKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoYnVmZi50b1N0cmluZygpKTsKLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gSWYgbG9nIGZpbGUgZXhpc3RzLCBhcHBlbmQuCi0gICAgICBGaWxlV3JpdGVyIHdyaXRlciA9IG5ldyBGaWxlV3JpdGVyKGFyZ3NbMV0sIHRydWUpOwotICAgICAgd3JpdGVyLndyaXRlKG5ldyBqYXZhLnV0aWwuRGF0ZSgpLnRvU3RyaW5nKCkrICJcbiIpOwotICAgICAgd3JpdGVyLndyaXRlKGJ1ZmYudG9TdHJpbmcoKSk7Ci0gICAgICB3cml0ZXIuY2xvc2UoKTsgICAgIAotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJEb25lIHdpdGggdmFsaWRhdGlvbi4gU2VlICIgKyBhcmdzWzFdICsgIi4iKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8vIFBhcnNlIGVhY2ggWE1MIGZpbGUuCi0gIHZvaWQgcGFyc2UoU3RyaW5nIGRpciwgU3RyaW5nIGZpbGVuYW1lKQotICAgICB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkgCi0gICAgewotICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZGlyLCBmaWxlbmFtZSk7Ci0gICAgICBTdHJpbmdCdWZmZXIgZXJyb3JCdWZmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShmKSk7Ci0gICAgICAvLyBTZXQgc3lzdGVtSUQgc28gcGFyc2VyIGNhbiBmaW5kIHRoZSBkdGQgd2l0aCBhIHJlbGF0aXZlIFVSTCBpbiB0aGUgc291cmNlIGRvY3VtZW50LgotICAgICAgaW5wdXQuc2V0U3lzdGVtSWQoZi50b1N0cmluZygpKTsKLSAgICAgIFNBWFBhcnNlckZhY3Rvcnkgc3BmYWN0ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgIAotICAgICAgc3BmYWN0LnNldFZhbGlkYXRpbmcodHJ1ZSk7Ci0gICAgICBzcGZhY3Quc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgICAgICAgICAKLSAgICAgIFNBWFBhcnNlciBwYXJzZXIgPSBzcGZhY3QubmV3U0FYUGFyc2VyKCk7Ci0gICAgICBYTUxSZWFkZXIgcmVhZGVyID0gcGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgCi0gICAgICAvL0luc3RhbnRpYXRlIGlubmVyLWNsYXNzIGVycm9yIGFuZCBsZXhpY2FsIGhhbmRsZXIuCi0gICAgICBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgSGFuZGxlcihmaWxlbmFtZSwgZXJyb3JCdWZmKTsKLSAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwgaGFuZGxlcik7Ci0gICAgICBwYXJzZXIucGFyc2UoaW5wdXQsIGhhbmRsZXIpOwotCi0gICAgICBpZiAoaGFuZGxlci5jb250YWluc0RURCAmJiAhaGFuZGxlci5lcnJvck9yV2FybmluZykgLy8gdmFsaWQKLSAgICAgIHsKLSAgICAgICAgYnVmZi5hcHBlbmQoIlZBTElEICIgKyBmaWxlbmFtZSArIlxuIik7Ci0gICAgICAgIG51bVZhbGlkRmlsZXMrKzsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGhhbmRsZXIuY29udGFpbnNEVEQpIC8vIG5vdCB2YWxpZAotICAgICAgewotICAgICAgICBidWZmLmFwcGVuZCAoIk5PVCBWQUxJRCAiICsgZmlsZW5hbWUgKyAiXG4iKTsKLSAgICAgICAgYnVmZi5hcHBlbmQoZXJyb3JCdWZmLnRvU3RyaW5nKCkpOwotICAgICAgICBudW1JbnZhbGlkRmlsZXMrKzsKLSAgICAgIH0KLSAgICAgIGVsc2UgLy8gbm8gRE9DVFlQRSB0byB1c2UgZm9yIHZhbGlkYXRpb24KLSAgICAgIHsKLSAgICAgICAgYnVmZi5hcHBlbmQoIk5PIERPQ1RZUEUgREVDTEFSQVRJT04gIiArIGZpbGVuYW1lICsgIlxuIik7Ci0gICAgICAgIG51bUZpbGVzTWlzc2luZ0RvY3R5cGUrKzsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSAvLyBTZXJpb3VzIHByb2JsZW0hCi0gICAgewotICAgICAgYnVmZi5hcHBlbmQoIk5PVCBXRUxMLUZPUk1FRCAiICsgZmlsZW5hbWUgKyAiLiAiICsgZS5nZXRNZXNzYWdlKCkgKyAiXG4iKTsKLSAgICAgIG51bU1hbGZvcm1lZEZpbGVzKys7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBudW1YTUxGaWxlcysrOwotICAgIH0KLSAgfQotICAvLyBJbm5lciBjbGFzc2VzCi0gIAotICAvLyBPbmx5IGludGVyZXN0ZWQgaW4gcGFyc2luZyAueG1sIGZpbGVzLgotICBjbGFzcyBYTUxGaWxlRmlsdGVyIGltcGxlbWVudHMgRmlsZW5hbWVGaWx0ZXIKLSAgewotICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChGaWxlIGRpciwgU3RyaW5nIGZpbGVOYW1lKQotICAgIHsKLSAgICAgIHJldHVybiBmaWxlTmFtZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCIueG1sIikgJiYgbmV3IEZpbGUoZGlyLnRvU3RyaW5nKCksZmlsZU5hbWUpLmlzRmlsZSgpOwotICAgIH0KLSAgfQotICAKLSAgLy8gQ2F0Y2ggYW55IGVycm9ycyBvciB3YXJuaW5ncywgYW5kIHZlcmlmeSBwcmVzZW5jZSBvZiBkb2N0eXBlIHN0YXRlbWVudC4KLSAgY2xhc3MgSGFuZGxlciBleHRlbmRzIERlZmF1bHRIYW5kbGVyIGltcGxlbWVudHMgTGV4aWNhbEhhbmRsZXIKLSAgewotICAgIGJvb2xlYW4gZXJyb3JPcldhcm5pbmc7Ci0gICAgYm9vbGVhbiBjb250YWluc0RURDsKLSAgICBTdHJpbmcgc291cmNlRmlsZTsKLSAgICBTdHJpbmdCdWZmZXIgZXJyb3JCdWZmOyAgCi0gIAotICAgIEhhbmRsZXIoU3RyaW5nIHNvdXJjZUZpbGUsIFN0cmluZ0J1ZmZlciBlcnJvckJ1ZmYpCi0gICAgewotICAgICAgc3VwZXIoKTsKLSAgICAgIHRoaXMuc291cmNlRmlsZSA9IHNvdXJjZUZpbGU7Ci0gICAgICB0aGlzLmVycm9yQnVmZiA9IGVycm9yQnVmZjsKLSAgICAgIGVycm9yT3JXYXJuaW5nID0gZmFsc2U7Ci0gICAgICBjb250YWluc0RURCA9IGZhbHNlOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGMpCi0gICAgewotICAgICAgZXJyb3JCdWZmLmFwcGVuZChzb3VyY2VGaWxlICsgIiBFcnJvcjogIiArIGV4Yy5nZXRNZXNzYWdlKCkrICJcbiIpOyAgICAKLSAgICAgIGVycm9yT3JXYXJuaW5nID0gdHJ1ZTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBleGMpCi0gICAgewotICAgICAgZXJyb3JCdWZmLmFwcGVuZChzb3VyY2VGaWxlICsgIiBXYXJuaW5nOiIgKyBleGMuZ2V0TWVzc2FnZSgpKyAiXG4iKTsgICAKLSAgICAgIGVycm9yT3JXYXJuaW5nID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvLyBMZXhpY2FsSGFuZGxlciBtZXRob2RzOyBhbGwgbm8tb3AgZXhjZXB0IHN0YXJ0RFREKCkuCi0gICAgCi0gICAgLy8gU2V0IGNvbnRhaW5zRFREIHRvIHRydWUgd2hlbiBzdGFydERURCBldmVudCBvY2N1cnMuCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQgKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLQkgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGNvbnRhaW5zRFREID0gdHJ1ZTsKLSAgICB9Ci0gCi0gICAgcHVibGljIHZvaWQgZW5kRFREICgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7fSAgCi0gIAotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5IChTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHt9Ci0gIAotICAgIHB1YmxpYyB2b2lkIGVuZEVudGl0eSAoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7fQotICAKLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBICgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7fQotICAKLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQSAoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAge30KLSAgCi0gICAgcHVibGljIHZvaWQgY29tbWVudCAoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7fQotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9WYWxpZGF0ZS9yZWFkbWUuaHRtbCBiL3NhbXBsZXMvVmFsaWRhdGUvcmVhZG1lLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVjODkzNmYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9WYWxpZGF0ZS9yZWFkbWUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzICswLDAgQEAKLTwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+Ci0KLTxodG1sPgotPGhlYWQ+Ci0JPHRpdGxlPlhhbGFuIFNhbXBsZXM8L3RpdGxlPgotPC9oZWFkPgotPGJvZHk+Ci08aDI+WGFsYW4gU2FtcGxlczwvaDI+Ci08cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNhbXBsZXMgKHdoYXQgdGhleSBpbGx1c3RyYXRlIGFuZCBob3cgdG8gcnVuIHRoZW0pLCBzZWUgPGEgaHJlZj0iLi4vLi4vZG9jcy9zYW1wbGVzLmh0bWwiPlNhbXBsZXM8L2E+LjwvcD4KLQotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvMS1yZWRpci54bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvMS1yZWRpci54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU5OWYwNWEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zLzEtcmVkaXIueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTAgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+IAotPGRvYz4KLSAgPGZvbyBmaWxlPSIxLXJlZGlyLm91dCI+Ci0gICAgVGVzdGluZyBSZWRpcmVjdCBleHRlbnNpb246Ci0gICAgPGJhcj5BIGZvbyBzdWJlbGVtZW50IHRleHQgbm9kZTwvYmFyPgotICA8L2Zvbz4KLSAgPG1haW4+Ci0gICAgRXZlcnl0aGluZyBlbHNlCi0gIDwvbWFpbj4gIAotPC9kb2M+CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvMS1yZWRpci54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvMS1yZWRpci54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIzZTY5YzIuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zLzEtcmVkaXIueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNDMgKzAsMCBAQAotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgIHZlcnNpb249IjEuMCIKLSAgICB4bWxuczpseHNsdD0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiCi0gICAgeG1sbnM6cmVkaXJlY3Q9Im9yZy5hcGFjaGUueGFsYW4ubGliLlJlZGlyZWN0IgotICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJyZWRpcmVjdCI+Ci0KLSAgPGx4c2x0OmNvbXBvbmVudCBwcmVmaXg9InJlZGlyZWN0IiBlbGVtZW50cz0id3JpdGUgb3BlbiBjbG9zZSIgZnVuY3Rpb25zPSIiPgotICAgIDxseHNsdDpzY3JpcHQgbGFuZz0iamF2YWNsYXNzIiBzcmM9Im9yZy5hcGFjaGUueGFsYW4ubGliLlJlZGlyZWN0Ii8+Ci0gIDwvbHhzbHQ6Y29tcG9uZW50PiAgCi0gICAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDxzdGFuZGFyZC1vdXQ+Ci0gICAgICBTdGFuZGFyZCBvdXRwdXQ6Ci0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgPC9zdGFuZGFyZC1vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDwhLS0gbm90IHJlZGlyZWN0ZWQgLS0+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImRvYy9tYWluIj4KLSAgICA8bWFpbj4KLSAgICAtLSBsb29rIGluIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIvZG9jL2Zvby9AZmlsZSIvPiBmb3IgdGhlIHJlZGlyZWN0ZWQgb3V0cHV0IC0tCi0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgPC9tYWluPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDwhLS0gcmVkaXJlY3RlZCAtLT4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iZG9jL2ZvbyI+Ci0gICAgPCEtLSBnZXQgcmVkaXJlY3QgZmlsZSBuYW1lIGZyb20gWE1MIGlucHV0IC0tPgotICAgIDxyZWRpcmVjdDp3cml0ZSBzZWxlY3Q9IkBmaWxlIj4KLSAgICAgIDxmb28tb3V0PgotICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgICA8L2Zvby1vdXQ+Ci0gICAgPC9yZWRpcmVjdDp3cml0ZT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotPCEtLSByZWRpcmVjdGVkIChmcm9tIHRoZSB4c2w6YXBwbHktdGVtcGxhdGVzIGFib3ZlLiBJLmUuLCBiYXIgaXMgaW4gL2RvYy9mb28gLS0+ICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iYmFyIj4KLSAgICA8Zm9vYmFyLW91dD4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICA8L2Zvb2Jhci1vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvMi1iYXNpY0pzY3JpcHQueG1sIGIvc2FtcGxlcy9leHRlbnNpb25zLzItYmFzaWNKc2NyaXB0LnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWM2NmNhMS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvMi1iYXNpY0pzY3JpcHQueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+Ci0gIDxkZWFkbGluZSBudW1kYXlzPSIyIi8+Ci08L2RvYz4gIAotIApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy8yLWJhc2ljSnNjcmlwdC54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvMi1iYXNpY0pzY3JpcHQueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMjE5Y2Y3Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy8yLWJhc2ljSnNjcmlwdC54c2wKKysrIC9kZXYvbnVsbApAQCAtMSwzNyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTwhLS1OYW1lc3BhY2VzIGFyZSBnbG9iYWwgaWYgeW91IHNldCB0aGVtIGluIHRoZSBzdHlsZXNoZWV0IGVsZW1lbnQtLT4KLTx4c2w6c3R5bGVzaGVldCAKLSAgICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgCi0gICAgdmVyc2lvbj0iMS4wIiAgIAotICAgIHhtbG5zOmx4c2x0PSJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdCIKLSAgICB4bWxuczpteS1leHQ9ImV4dDIiCi0gICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9Im15LWV4dCI+Ci0gICAgCi0gIDwhLS1UaGUgY29tcG9uZW50IGFuZCBpdHMgc2NyaXB0IGFyZSBpbiB0aGUgbHhzbHQgbmFtZXNwYWNlIGFuZCBkZWZpbmUgdGhlIGltcGxlbWVudGF0aW9uLS0+Ci0gIDxseHNsdDpjb21wb25lbnQgcHJlZml4PSJteS1leHQiIGVsZW1lbnRzPSJ0aW1lbGFwc2UiIGZ1bmN0aW9ucz0iZ2V0ZGF0ZSI+Ci0gICAgPGx4c2x0OnNjcmlwdCBsYW5nPSJqYXZhc2NyaXB0Ij4KLSAgICAgIHZhciBtdWx0aXBsaWVyPTE7Ci0gICAgICAvLyBFeHRlbnNpb24gZWxlbWVudCBpbXBsZW1lbnRhdGlvbnMgYWx3YXlzIHRha2UgdHdvIGFyZ3VtZW50cy4gVGhlIGZpcnN0Ci0gICAgICAvLyBhcmd1bWVudCBpcyB0aGUgWFNMIFByb2Nlc3NvciBjb250ZXh0OyB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIHRoZSBlbGVtZW50LgotICAgICAgZnVuY3Rpb24gdGltZWxhcHNlKHhzbFByb2Nlc3NvckNvbnRleHQsIGVsZW0pCi0gICAgICB7Ci0gICAgICAgIG11bHRpcGxpZXI9cGFyc2VJbnQoZWxlbS5nZXRBdHRyaWJ1dGUoIm11bHRpcGxpZXIiKSk7Ci0gICAgICAgIC8vIFRoZSBlbGVtZW50IHJldHVybiB2YWx1ZSBpcyBwbGFjZWQgaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgICAgICAvLyBJZiB5b3UgZG8gbm90IHdhbnQgYSByZXR1cm4gdmFsdWUsIHJldHVybiBudWxsLgotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgIH0KLSAgICAgIGZ1bmN0aW9uIGdldGRhdGUobnVtZGF5cykKLSAgICAgIHsKLSAgICAgICAgdmFyIGQgPSBuZXcgRGF0ZSgpOwotICAgICAgICBkLnNldERhdGUoZC5nZXREYXRlKCkgKyBwYXJzZUludChudW1kYXlzKm11bHRpcGxpZXIpKTsKLSAgICAgICAgcmV0dXJuIGQudG9Mb2NhbGVTdHJpbmcoKTsKLSAgICAgIH0KLSAgICA8L2x4c2x0OnNjcmlwdD4KLSAgPC9seHNsdDpjb21wb25lbnQ+Ci0gICAgICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iZGVhZGxpbmUiPgotICAgIDxwPjxteS1leHQ6dGltZWxhcHNlIG11bHRpcGxpZXI9IjIiLz5XZSBoYXZlIHJlY2VpdmVkIHlvdXIgZW5xdWlyeSBhbmQgd2lsbCAKLSAgICAgIHJlc3BvbmQgYnkgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im15LWV4dDpnZXRkYXRlKHN0cmluZyhAbnVtZGF5cykpIi8+PC9wPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvMy1qYXZhLW5hbWVzcGFjZS54bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvMy1qYXZhLW5hbWVzcGFjZS54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZmMmViNDQuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zLzMtamF2YS1uYW1lc3BhY2UueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08ZG9jPgotICAgPGRhdGUKLSAgICB5ZWFyPSIyMDAxIiBtb250aD0iNSIgZGF5PSIyNyIKLSAgICBmb3JtYXQ9IkVFRUUsIE1NTSBkZCwgeXl5eSIvPgotPC9kb2M+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zLzMtamF2YS1uYW1lc3BhY2UueHNsIGIvc2FtcGxlcy9leHRlbnNpb25zLzMtamF2YS1uYW1lc3BhY2UueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NWI2ZTU5Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy8zLWphdmEtbmFtZXNwYWNlLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDIyICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB4bWxuczpqYXZhPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdC9qYXZhIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCI+Ci0gICAgICAgICAgICAgICAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iL2RvYy9kYXRlIi8+IAotICA8L3hzbDp0ZW1wbGF0ZT4KLSAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iZGF0ZSI+Ci0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJ5ZWFyIiBzZWxlY3Q9InN0cmluZyhAeWVhcikiLz4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9Im1vbnRoIiBzZWxlY3Q9InN0cmluZyhAbW9udGgpIi8+IAotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0iZGF5IiBzZWxlY3Q9InN0cmluZyhAZGF5KSIvPiAgICAgICAgICAKLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9ImZvcm1hdCIgc2VsZWN0PSJzdHJpbmcoQGZvcm1hdCkiLz4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9ImZvcm1hdHRlciIgICAgICAgCi0gICAgICAgICBzZWxlY3Q9ImphdmE6amF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQubmV3KCRmb3JtYXQpIi8+Ci0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYXRlIiAKLSAgICAgICAgIHNlbGVjdD0iamF2YTpJbnREYXRlLmdldERhdGUoJHllYXIsJG1vbnRoLCRkYXkpIi8+Ci0gICAgPHA+RGF0ZTogPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9ImphdmE6Zm9ybWF0KCRmb3JtYXR0ZXIsICRkYXRlKSIvPjwvcD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gCi08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zLzQtbnVtbGlzdEphdmEueHNsIGIvc2FtcGxlcy9leHRlbnNpb25zLzQtbnVtbGlzdEphdmEueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZmY5OTI0Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy80LW51bWxpc3RKYXZhLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDM1ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB4bWxuczpseHNsdD0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiCi0gICAgICAgICAgICAgICAgeG1sbnM6Y291bnRlcj0iTXlDb3VudGVyIgotICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJjb3VudGVyIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCI+Ci0KLQotICA8bHhzbHQ6Y29tcG9uZW50IHByZWZpeD0iY291bnRlciIKLSAgICAgICAgICAgICAgICAgICBlbGVtZW50cz0iaW5pdCBpbmNyIiBmdW5jdGlvbnM9InJlYWQiPgotICAgIDxseHNsdDpzY3JpcHQgbGFuZz0iamF2YWNsYXNzIiBzcmM9Ik15Q291bnRlciIvPgotICA8L2x4c2x0OmNvbXBvbmVudD4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgICA8SFRNTD4KLSAgICAgIDxIMT5KYXZhIEV4YW1wbGU8L0gxPgotICAgICAgPGNvdW50ZXI6aW5pdCBuYW1lPSJpbmRleCIgdmFsdWU9IjEiLz4KLSAgICAgIDxwPkhlcmUgYXJlIHRoZSBuYW1lcyBpbiBhbHBoYWJldGljYWwgb3JkZXIgYnkgbGFzdCBuYW1lOjwvcD4KLSAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJkb2MvbmFtZSI+Ci0gICAgICAgIDx4c2w6c29ydCBzZWxlY3Q9IkBsYXN0Ii8+Ci0gICAgICAgIDx4c2w6c29ydCBzZWxlY3Q9IkBmaXJzdCIvPgotICAgICAgICA8cD4KLSAgICAgICAgPHhzbDp0ZXh0Pls8L3hzbDp0ZXh0PgotICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iY291bnRlcjpyZWFkKCdpbmRleCcpIi8+Ci0gICAgICAgIDx4c2w6dGV4dD5dLiA8L3hzbDp0ZXh0PgotICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGxhc3QiLz4KLSAgICAgICAgPHhzbDp0ZXh0PiwgPC94c2w6dGV4dD4KLSAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBmaXJzdCIvPgotICAgICAgICA8L3A+Ci0gICAgICAgIDxjb3VudGVyOmluY3IgbmFtZT0iaW5kZXgiLz4KLSAgICAgIDwveHNsOmZvci1lYWNoPgotICAgIDwvSFRNTD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gCi08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zLzUtbnVtbGlzdEpzY3JpcHQueHNsIGIvc2FtcGxlcy9leHRlbnNpb25zLzUtbnVtbGlzdEpzY3JpcHQueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZjM1MWNiLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy81LW51bWxpc3RKc2NyaXB0LnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDU0ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB4bWxuczpseHNsdD0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiCi0gICAgICAgICAgICAgICAgeG1sbnM6Y291bnRlcj0iTXlDb3VudGVyIgotICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJjb3VudGVyIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCI+Ci0KLSAgPGx4c2x0OmNvbXBvbmVudCBwcmVmaXg9ImNvdW50ZXIiCi0gICAgICAgICAgICAgICAgICAgZWxlbWVudHM9ImluaXQgaW5jciIgZnVuY3Rpb25zPSJyZWFkIj4KLSAgICA8bHhzbHQ6c2NyaXB0IGxhbmc9ImphdmFzY3JpcHQiPgotICAgICAgdmFyIGNvdW50ZXJzID0gbmV3IEFycmF5KCk7Ci0KLSAgICAgIGZ1bmN0aW9uIGluaXQgKHhzbHByb2MsIGVsZW0pIHsKLSAgICAgICAgbmFtZSA9IGVsZW0uZ2V0QXR0cmlidXRlICgibmFtZSIpOwotICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KGVsZW0uZ2V0QXR0cmlidXRlICgidmFsdWUiKSk7Ci0gICAgICAgIGNvdW50ZXJzW25hbWVdID0gdmFsdWU7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotCi0gICAgICBmdW5jdGlvbiByZWFkIChuYW1lKSB7Ci0gICAgICAgIHJldHVybiAiIiArIChjb3VudGVyc1tuYW1lXSk7Ci0gICAgICB9Ci0KLSAgICAgIGZ1bmN0aW9uIGluY3IgKHhzbHByb2MsIGVsZW0pCi0gICAgICB7Ci0gICAgICAgIG5hbWUgPSBlbGVtLmdldEF0dHJpYnV0ZSAoIm5hbWUiKTsKLSAgICAgICAgY291bnRlcnNbbmFtZV0rKzsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0gICAgPC9seHNsdDpzY3JpcHQ+Ci0gIDwvbHhzbHQ6Y29tcG9uZW50PgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDxIVE1MPgotICAgICAgPEgxPkphdmFTY3JpcHQgRXhhbXBsZS48L0gxPgotICAgICAgPGNvdW50ZXI6aW5pdCBuYW1lPSJpbmRleCIgdmFsdWU9IjEiLz4KLSAgICAgIDxwPkhlcmUgYXJlIHRoZSBuYW1lcyBpbiBhbHBoYWJldGljYWwgb3JkZXIgYnkgbGFzdCBuYW1lOjwvcD4KLSAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJkb2MvbmFtZSI+Ci0gICAgICAgIDx4c2w6c29ydCBzZWxlY3Q9IkBsYXN0Ii8+Ci0gICAgICAgIDx4c2w6c29ydCBzZWxlY3Q9IkBmaXJzdCIvPgotICAgICAgICA8cD4KLSAgICAgICAgPHhzbDp0ZXh0Pls8L3hzbDp0ZXh0PgotICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iY291bnRlcjpyZWFkKCdpbmRleCcpIi8+Ci0gICAgICAgIDx4c2w6dGV4dD5dLiA8L3hzbDp0ZXh0PgotICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGxhc3QiLz4KLSAgICAgICAgPHhzbDp0ZXh0PiwgPC94c2w6dGV4dD4KLSAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBmaXJzdCIvPgotICAgICAgICA8L3A+Ci0gICAgICAgIDxjb3VudGVyOmluY3IgbmFtZT0iaW5kZXgiLz4KLSAgICAgIDwveHNsOmZvci1lYWNoPgotICAgIDwvSFRNTD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gCi08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zLzYtc3FsbGliLWluc3RhbnRkYi54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvNi1zcWxsaWItaW5zdGFudGRiLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2U1MzU5ZC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvNi1zcWxsaWItaW5zdGFudGRiLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDQ5ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCIKLSAgICAgICAgICAgICAgICB4bWxuczpzcWw9Im9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvbiIKLSAgICAgICAgICAgICAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ic3FsIj4KLSAgPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBpbmRlbnQ9InllcyIvPgotICA8eHNsOnBhcmFtIG5hbWU9InF1ZXJ5IiBzZWxlY3Q9IidTRUxFQ1QgKiBGUk9NIGltcG9ydDEnIi8+Ci0gCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDwhLS0gMS4gTWFrZSB0aGUgY29ubmVjdGlvbiAtLT4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InByb2R1Y3RzIgotICAgICAgICAgICAgICAgICAgc2VsZWN0PSJzcWw6bmV3KCdvcmcuZW5oeWRyYS5pbnN0YW50ZGIuamRiYy5pZGJEcml2ZXInLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnamRiYzppZGI6Li9pbnN0YW50ZGIvc2FtcGxlLnBycCcpIi8+Ci0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotICAgICAgICA8VEFCTEUgYm9yZGVyPSIxIj4KLSAgICAgICAgPCEtLTIuIEV4ZWN1dGUgdGhlIHF1ZXJ5IC0tPgotICAgICAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InRhYmxlIiBzZWxlY3Q9J3NxbDpxdWVyeSgkcHJvZHVjdHMsICRxdWVyeSknLz4KLSAgICAgICAgICA8VFI+Ci0gICAgICAgICAgPCEtLSBHZXQgY29sdW1uLWxhYmVsIGF0dHJpYnV0ZSBmcm9tIGVhY2ggY29sdW1uLWhlYWRlci0tPgotICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSIkdGFibGUvcm93LXNldC9jb2x1bW4taGVhZGVyIj4KLSAgICAgICAgICAgIDxUSD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGNvbHVtbi1sYWJlbCIvPjwvVEg+Ci0gICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgICAgPC9UUj4KLSAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IiR0YWJsZS9yb3ctc2V0L3JvdyIvPgotICAgICAgICAgIDx4c2w6dGV4dD4mIzEwOzwveHNsOnRleHQ+Ci0gICAgICAgIDwvVEFCTEU+Ci0gICAgICA8L0JPRFk+Ci0gICAgPC9IVE1MPiAKLSAgICA8IS0tIDMuIENsb3NlIHRoZSBjb25uZWN0aW9uIC0tPgotICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJHByb2R1Y3RzKSIvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJyb3ciPgotICAgICAgICA8VFI+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJjb2wiLz4KLSAgICAgICAgPC9UUj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29sIj4KLSAgICA8VEQ+Ci0gICAgICA8IS0tIEhlcmUgaXMgdGhlIGNvbHVtbiBkYXRhIC0tPgotICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPgotICAgIDwvVEQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi08L3hzbDpzdHlsZXNoZWV0PgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9JbnREYXRlLmphdmEgYi9zYW1wbGVzL2V4dGVuc2lvbnMvSW50RGF0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYzljNmMzLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9JbnREYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNyArMCwwIEBACi0KLWltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKLWltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7Ci0KLXB1YmxpYyBjbGFzcyBJbnREYXRlCi17Ci0gIHB1YmxpYyBzdGF0aWMgRGF0ZSBnZXREYXRlKFN0cmluZyB5ZWFyLCBTdHJpbmcgbW9udGgsIFN0cmluZyBkYXkpCi0gICAgewotICAgICAgLy8gRGF0ZShpbnQsIGludCwgaW50KSBoYXMgYmVlbiBkZXByZWNhdGVkLCBzbyB1c2UgQ2FsZW5kYXIgdG8KLSAgICAgIC8vIHNldCB0aGUgeWVhciwgbW9udGgsIGFuZCBkYXkuCi0gICAgICBDYWxlbmRhciBjID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKLSAgICAgIC8vIENvbnZlcnQgZWFjaCBhcmd1bWVudCB0byBpbnQuCi0gICAgICBjLnNldChJbnRlZ2VyLnBhcnNlSW50KHllYXIpLEludGVnZXIucGFyc2VJbnQobW9udGgpLEludGVnZXIucGFyc2VJbnQoZGF5KSk7Ci0gICAgICByZXR1cm4gYy5nZXRUaW1lKCk7Ci0gICAgfQotfQotCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvTXlDb3VudGVyLmphdmEgYi9zYW1wbGVzL2V4dGVuc2lvbnMvTXlDb3VudGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiNWY1NGEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL015Q291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotcHVibGljIGNsYXNzIE15Q291bnRlciB7Ci0gIHN0YXRpYyBIYXNodGFibGUgY291bnRlcnMgPSBuZXcgSGFzaHRhYmxlICgpOwotCi0KLSAgcHVibGljIHZvaWQgaW5pdChvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuWFNMUHJvY2Vzc29yQ29udGV4dCBjb250ZXh0LCAKLSAgICAgICAgICAgICAgICAgICBvcmcudzNjLmRvbS5FbGVtZW50IGVsZW0pIAotICB7Ci0gICAgU3RyaW5nIG5hbWUgPSBlbGVtLmdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgIFN0cmluZyB2YWx1ZSA9IGVsZW0uZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOwotICAgIGludCB2YWw7Ci0gICAgdHJ5IAotICAgIHsKLSAgICAgIHZhbCA9IEludGVnZXIucGFyc2VJbnQgKHZhbHVlKTsKLSAgICB9IAotICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgCi0gICAgewotICAgICAgZS5wcmludFN0YWNrVHJhY2UgKCk7Ci0gICAgICB2YWwgPSAwOwotICAgIH0KLSAgICBjb3VudGVycy5wdXQgKG5hbWUsIG5ldyBJbnRlZ2VyICh2YWwpKTsKLSAgfQotCi0gIHB1YmxpYyBpbnQgcmVhZChTdHJpbmcgbmFtZSkgCi0gIHsgCi0gICAgSW50ZWdlciBjdmFsID0gKEludGVnZXIpY291bnRlcnMuZ2V0KG5hbWUpOwotICAgIHJldHVybiAoY3ZhbCA9PSBudWxsKSA/IDAgOiBjdmFsLmludFZhbHVlKCk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBpbmNyKG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5YU0xQcm9jZXNzb3JDb250ZXh0IGNvbnRleHQsICAKLSAgICAgICAgICAgICAgICAgICBvcmcudzNjLmRvbS5FbGVtZW50IGVsZW0pIHsKLSAgICBTdHJpbmcgbmFtZSA9IGVsZW0uZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0gICAgSW50ZWdlciBjdmFsID0gKEludGVnZXIpIGNvdW50ZXJzLmdldChuYW1lKTsKLSAgICBpbnQgbnZhbCA9IChjdmFsID09IG51bGwpID8gMCA6IChjdmFsLmludFZhbHVlICgpICsgMSk7Ci0gICAgY291bnRlcnMucHV0IChuYW1lLCBuZXcgSW50ZWdlciAobnZhbCkpOwotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi9pZGIuamFyIGIvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi9pZGIuamFyCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNTAxODMzLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvaWRiLmphcgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvc2FtcGxlLnBycCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvc2FtcGxlLnBycApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWQ1YjI0Ni4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3NhbXBsZS5wcnAKKysrIC9kZXYvbnVsbApAQCAtMSwzMTYgKzAsMCBAQAotIS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotIQotISBCQVNJQyBQUk9QRVJUSUVTCi0hCi0hLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSEKLSEgUGF0aCB3aGVyZSBpbmRleCB0YWJsZXMgYXJlIGhlbGQuIENhbiBiZSBhYnNvbHV0ZSBvciByZWxhdGl2ZSAKLSEgdG8gdGhlIHByb3BlcnRpZXMgZmlsZS4gRGVmYXVsdHMgdG8gdGFibGVQYXRoLgotIQotIWluZGV4UGF0aD0uL2luZGV4ZXMKLSEKLSEgUGF0aCB3aGVyZSBzeXN0ZW0gdGFibGVzIGFyZSBoZWxkLiBDYW4gYmUgYWJzb2x1dGUgb3IgcmVsYXRpdmUgdG8gCi0hIHRoZSBwcm9wZXJ0aWVzIGZpbGUuIERlZmF1bHRzIHRvIHRhYmxlUGF0aC4KLSEKLSFzeXN0ZW1QYXRoPS4vc3lzdGVtCi0hCi0hIFBhdGggd2hlcmUgZGF0YWJhc2UgdGFibGVzIGFyZSBoZWxkLiBDYW4gYmUgYWJzb2x1dGUgb3IgcmVsYXRpdmUgCi0hIHRvIHRoZSBwcm9wZXJ0aWVzIGZpbGUuIERlZmF1bHRzIHRvICJjdXJyZW50IiBkaXJlY3RvcnkuCi0hCi10YWJsZVBhdGg9Li90YWJsZXMKLSEKLSEgUGF0aCB3aGVyZSByZXN1bHRzIHNldCB0YWJsZXMgYXJlIGhlbGQuIENhbiBiZSBhYnNvbHV0ZSBvciByZWxhdGl2ZSAKLSEgdG8gdGhlIHByb3BlcnRpZXMgZmlsZS4gRGVmYXVsdHMgdG8gdGFibGVQYXRoLgotIQotIXRtcFBhdGg9Li90bXAKLSEKLSEgTm9uLXplcm8gbWVhbnMgcGF0aHMgYXJlIHJlbGF0aXZlIHRvIHRoZSBwcm9wZXJ0aWVzIGZpbGUuIAotISBEZWZhdWx0IGlzIGFic29sdXRlIHBhdGhzIGZvciBmaWxlcy4KLSEKLXJlbGF0aXZlVG9Qcm9wZXJ0aWVzPTEKLSEKLSEgQWx0ZXJuYXRpdmUgcGFydGl0aW9ucyBjYW4gYmUgZGVmaW5lZCBzbyB0aGF0IHRhYmxlcyBjYW4gYmUgcGxhY2VkCi0hIGluIG11bHRpcGxlIGxvY2F0aW9ucy4gRWFjaCBwYXJ0aXRpb24gaXMgbnVtYmVyZWQ6IDEsIDIsIDMsLi4uIFRhYmxlcwotISBjYW4gYmUgY3JlYXRlZCBvbiBwYXJ0aXRpb25zIHVzaW5nIHRoZSBzeW50YXggCi0hCi0hICAgQ1JFQVRFIFRBQkxFIDxuYW1lPiBPTiBQQVJUSVRJT04gPG51bWJlcj4uLi4KLSEKLSEgVGhlIHBhcnRpdGlvbiBjb3VudCBoYXMgdG8gYmUgc3VwcGxpZWQuCi0hCi0hcGFydGl0aW9uQ291bnQ9MgotIQotISBUaGUgbG9jYXRpb25zIG9mIGVhY2ggcGFydGl0aW9uIG11c3QgYmUgc3VwcGxpZWQuIFRoZXNlIGFyZSBhbHdheXMKLSEgYWJzb2x1dGUgcGF0aCBuYW1lcy4KLSEKLSFwYXJ0aXRpb24xPWQ6L3BldGVzCi0hcGFydGl0aW9uMj1jOi90ZW1wCi0KLQotIS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotIQotISBUVU5JTkcgUFJPUEVSVElFUwotIQotIS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi0hCi0hIFRoZSBhbW91bnQgb2YgZWFjaCBjb2x1bW4gdG8gY2FjaGUsIGV4cHJlc3NlZCBlaXRoZXIgYXMgYW4gYWJzb2x1dGUgCi0hIG51bWJlciBvZiByb3dzIG9yIGFzIGEgcGVyY2VudGFnZSBmaWd1cmUuIERlZmF1bHRzIHRvIDI1NiBvciAxMCByZXNwZWN0aXZlbHkuCi0hCi0hIFRoaXMgdmFsdWUgYXBwbGllcyBvbmx5IHdoZW4gdGFibGVzIGFyZSBmaXJzdCBjcmVhdGVkLiBJdCBoYXMgbm8gZWZmZWN0Ci0hIHdoZW4gYSB0YWJsZSBpcyBiZWluZyByZS1vcGVuZWQuCi0hCi1jYWNoZUFtb3VudD01MTIKLSEKLSEgQ0FDSEVfUk9XUyBNdXN0IGJlIG9uZSBvZiBDQUNIRV9ST1dTIG9yIENBQ0hFX1BFUkNFTlQuIERldGVybWluZXMgd2hldGhlciAKLSEgdG8gY2FjaGUgY29sdW1ucyBpbiB0YWJsZXMgYmFzZWQgb24gYW4gYWJzb2x1dGUgbnVtYmVyIG9mIHJvd3MsIG9yIHRoZSAKLSEgcGVyY2VudGFnZSBudW1iZXIgb2Ygcm93cyBpbiB0aGUgdGFibGUuIAotIQotISBUaGlzIHZhbHVlIGFwcGxpZXMgb25seSB3aGVuIHRhYmxlcyBhcmUgZmlyc3QgY3JlYXRlZC4gSXQgaGFzIG5vIGVmZmVjdAotISB3aGVuIGEgdGFibGUgaXMgYmVpbmcgcmUtb3BlbmVkLgotIQotY2FjaGVDb25kaXRpb249Q0FDSEVfUk9XUwotIQotISBUaGUgYW1vdW50IG9mIHRoZSBzeXN0ZW0gdGFibGVzIHRvIGJlIGNhY2hlZC4gRGVmYXVsdHMgdG8gMTAwLgotIQotISBUaGlzIHZhbHVlIGFwcGxpZXMgb25seSB3aGVuIHRhYmxlcyBhcmUgZmlyc3QgY3JlYXRlZC4gSXQgaGFzIG5vIGVmZmVjdAotISB3aGVuIGEgdGFibGUgaXMgYmVpbmcgcmUtb3BlbmVkLgotIQotIXN5c3RlbUNhY2hlU2l6ZT0xMAotIQotISBTaW1pbGFyIHRvIGNhY2hlQ29uZGl0aW9uLCBidXQgYXBwbGllcyBvbmx5IHRvIHRoZSBzeXN0ZW0gdGFibGVzLgotIQotISBUaGlzIHZhbHVlIGFwcGxpZXMgb25seSB3aGVuIHRhYmxlcyBhcmUgZmlyc3QgY3JlYXRlZC4gSXQgaGFzIG5vIGVmZmVjdAotISB3aGVuIGEgdGFibGUgaXMgYmVpbmcgcmUtb3BlbmVkLgotIQotIXN5c3RlbUNhY2hlQ29uZGl0aW9uPUNBQ0hFX1JPV1MKLSEKLSEgVGhlIHBlcmNlbnRhZ2UgY2FjaGUgaGl0IGltcHJvdmVtZW50IHJlcXVpcmVkIGluIG9yZGVyIHRvIG1vdmUgdGhlIAotISBjYWNoZSB0byBhIG5ldyBsb2NhdGlvbiBpbiBhIGNvbHVtbi4gCi0hCi0hIChDdXJyZW50bHkgbm90IGltcGxlbWVudGVkKS4KLSEKLWNhY2hlUmVzZXRQZXJjZW50PTEwCi0hCi0hIE5vbi16ZXJvIG1lYW5zIHRoYXQgZGF0YWJhc2UgY2hhbmdlcyBkbyBub3QgZ2V0IHdyaXR0ZW4gdG8gdGhlIAotISBkYXRhYmFzZSBpbW1lZGlhdGVseS4gU2VlIHR1bmluZy5odG1sLiAKLSEKLWZhc3RVcGRhdGU9MAotIQotISBQZXJjZW50YWdlIG9mIGZyZWUgc3BhY2UgaW4gYW4gaW5kZXggdGhhdCBtdXN0IGJlIHByZXNlbnQgYmVmb3JlIAotISB0aGUgaW5kZXggcmVvcmdhbmlzZXMgaXRzZWxmLiBIaWdoIHZhbHVlcyBtZWFucyBmcmVxdWVudCBpbmRleAotISByZW9yZ2FuaXNhdGlvbi4gTG93IHZhbHVlcyBtZWFucyBzbG93IGluZGV4IGluc2VydHMuCi0hCi1pbmRleExvYWQ9NQotIQotISBUaGUgbnVtYmVyIG9mIGNhY2hlIG1pc3NlcyB0byBpbmNsdWRlIGluIGNhbGN1bGF0aW9ucyBvZiB0aGUgbmV4dCAKLSEgYmFzZSBmb3IgdGhlIGNhY2hlLiAKLSEKLSEgKEN1cnJlbnRseSBub3QgaW1wbGVtZW50ZWQpLgotIQotbWlzc2VzSW5DYWNoZVN0YXRzPTEwMAotIQotISBOb24temVybyBtZWFucyB0aGF0IHJlc3VsdHMgc2V0cyBnZXQgaW5zdGFudGlhdGVkIG9uIGRpc2suIEJ5IGRlZmF1bHQKLSEgSW5zdGFudERCIGhvbGRzIHJlc3VsdHMgc2V0cyBlbXRpcmVseSBpbiBtZW1vcnkgKGFwYXJ0IGZyb20gQmluYXJ5Ci0hIGNvbHVtbnMpLiBGb3IgbGFyZ2UgcmVzdWx0cyBzZXRzIHRoaXMgY2FuIGJlIGEgcHJvYmxlbS4gVGhpcyBwcm9wZXJ0eQotISBmb3JjZXMgYWxsIHJlc3VsdHMgc2V0cyB0byBiZSBoZWxkIG9uIGRpc2suCi0hCi1yZXN1bHRzT25EaXNrPTAKLSEKLSEgU2ltaWxhciB0byBjYWNoZUNvbmRpdGlvbiBidXQgYXBwbGllcyBvbmx5IHRvIGRpc2sgYmFzZWQKLSEgcmVzdWx0cyBzZXRzLiBEZWZhdWx0IGlzIENBQ0hFX1JPV1MuCi0hCi1yZXN1bHRzU2V0Q2FjaGU9Q0FDSEVfUk9XUwotIQotISBTaW1pbGFyIHRvIGNhY2hlQW1vdW50IGJ1dCBhcHBsaWVzIG9ubHkgdG8gZGlzayBiYXNlZAotISByZXN1bHRzIHNldHMuIERlZmF1bHQgaXMgMTAwLgotIQotcmVzdWx0c1NldENhY2hlQW1vdW50PTEwMAotIQotISBOdW1iZXIgb2Ygcm93cyB0byByZWFkIGludG8gdGhlIGRpc2sgcmVhZCBhaGVhZCBidWZmZXIuIAotISBSZWNvbW1lbmRlZCB0byBiZSBzZXQgc29tZXdoZXJlIGFyb3VuZCAxMjggdG8gMjU2LiAKLSEgRGVmYXVsdCBpcyAyMC4KLSEKLXJvd0NhY2hlU2l6ZT0xMjgKLSEKLSEgVGhlIHJlYWQgYWhlYWQgYnVmZmVyIGlzIGVmZmVjdGl2ZSBhdCBzcGVlZGluZyB1cCBmdWxsCi0hIHRhYmxlIHNjYW5zLiBIb3dldmVyIGZvciBpbmRleGVkIGxvb2t1cHMgb3IgbXVsdGlwbGUKLSEgc2ltdWx0YW5lb3VzIHNjYW5zIGl0IGlzIGJldHRlciB0byByZWFkIGEgc2luZ2xlIHJvdyBhdAotISBhIHRpbWUuIEVhY2ggdGFibGUgaG9sZHMgYSBzbWFsbCBudW1iZXIgb2Ygc2luZ2xlIHJvdwotISBidWZmZXJzIHRvIGltcHJvdmUgc3VjaCBvcGVyYXRpb25zLiBEZWZhdWx0IGlzIDguCi0hCi0hc2luZ2xlUm93Q291bnQ9NAotIQotISBTb21ldGltZXMgdGhlIGxvb2sgYWhlYWQgYnVmZmVyIGNhbiBiZSBoZWxkIGJ5IGEgc2luZ2xlCi0hIHRocmVhZCBldmVuIHRob3VnaCBpdCBpcyBub3QgcmV0cmlldmVpbmcgbWFueSB2YWx1ZXMgZnJvbSBpdC4KLSEgSWYgdG9vIG1hbnkgbG9va3VwcyByZXRyaWV2ZSBkYXRhIGZyb20gdGhlIHNpbmdsZSByb3cKLSEgYnVmZmVycyB0aGVuIGl0IGlzIGJldHRlciB0byBmbHVzaCB0aGUgbG9vayBhaGVhZCBidWZmZXIgYW5kCi0hIG1ha2UgaXQgYXZhaWxhYmxlIGZvciByZS11c2UuIERlZmF1bHQgaXMgMTI4LgotIQotIWZsdXNoQWZ0ZXJDYWNoZU1pc3Nlcz02NAotIQotISBOdW1iZXIgb2Ygcm93cyB0byByZWFkIGFoZWFkIGZvciBzeXN0ZW0gdGFibGVzLiBCeSBkZWZhdWx0Ci0hIHN5c3RlbSB0YWJsZXMgY2FjaGUgZXZlcnl0aGluZywgc28gaXQgaXMgd2FzdGVmdWwgdG8gaGF2ZSBsYXJnZQotISByZWFkIGFoZWFkIGJ1ZmZlcnMgc2luY2UgdGhleSB3aWxsIHZlcnkgcmFyZWx5IGJlIHVzZWQuIFRoaXMKLSEgYWxsb3dzIHRoZSBzaXplIG9mIHRoZSBzeXN0ZW0gcmVhZCBhaGVhZCBidWZmZXJzIHRvIGJlIHJlZHVjZWQKLSEgaWYgbmVjZXNzYXJ5LiBEZWZhdWx0cyB0byByb3dDYWNoZVNpemUuCi0hCi0hc3lzdGVtUm93cz0yMAotIQotISBUaGUgY29udHJvbCBjb2x1bW4gaW4gYWxsIHRhYmxlcyBub3JtYWxseSBoYXMgYSBsYXJnZSBjYWNoZQotISBzaW5jZSB0aGlzIHNwZWVkcyB1cCBhbGwgb3BlcmF0aW9uIG9uIHRoYXQgdGFibGUuIFRoaXMgY2FuIGJlCi0hIHZhcmllZCB0byBlaXRoZXIgaW1wcm92ZSBwZXJmb3JtYW5jZSBvciB0byByZWR1Y2Ugc3BhY2UuCi0hIGRlZmF1bHQgaXMgODE5Mi4KLSEKLSEgVGhpcyB2YWx1ZSBhcHBsaWVzIG9ubHkgd2hlbiB0YWJsZXMgYXJlIGZpcnN0IGNyZWF0ZWQuIEl0IGhhcyBubyBlZmZlY3QKLSEgd2hlbiBhIHRhYmxlIGlzIGJlaW5nIHJlLW9wZW5lZC4KLSEKLSFjb250cm9sQ29sQ2FjaGVTaXplPTUxMgotIQotISBCeSBkZWZhdWx0LCBJbnN0YW50REIgb25seSBkb2VzIGEgY3Vyc29yeSBzZWFyY2ggZm9yIGRlbGV0ZWQgcm93cyBkdXJpbmcgCi0hIFVQREFURSBzdGF0ZW1lbnRzLiBTZXR0aW5nIHNlYXJjaERlbGV0ZXM9MSBjYXVzZXMgbW9yZSBkZXRhaWxlZCBzZWFyY2hlcyAKLSEgZm9yIGRlbGV0ZWQgcm93cy4gVGhpcyBzbG93cyBkb3duIFVQREFURSBleGVjdXRpb25zLCBidXQgcmV1bHRzIGluIG1vcmUgCi0hIGNvbXBhY3QgdGFibGVzLiAgRGVmYXVsdCBpcyAwLgotIQotc2VhcmNoRGVsZXRlcz0wCi0hCi0hIFRoZSBpbnRlcnZhbCwgaW4gbWlsbGlzZWNvbmRzLCBiZXR3ZWVuIGNoZWNrcyBmb3Igc3RhdGVtZW50IGV4ZWN1dGlvbgotISB0aW1lb3V0cy4gRGVmYXVsdCBpcyA1MDAwLgotIQotIXRpbWVyQ2hlY2s9NTAwMAotCi0hLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0hCi0hIExPR0dJTkcgQU5EIERFQlVHR0lORyBQUk9QRVJUSUVTCi0hCi0hLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSEKLSEgTm9uLXplcm8gbWVhbnMgaW5jbHVkZSBTUUwgc3RhdGVtZW50cyBpbiB0aGUgZXhwb3J0IGZpbGUuIAotIQotZXhwb3J0U1FMPTAKLSEKLSEgTm9uLXplcm8gbWVhbnMgdHJhY2Ugb3V0cHV0IGFsc28gZGlyZWN0ZWQgdG8gY29uc29sZS4gCi0hIERlZmF1bHRzIHRvIDAuCi0hCi10cmFjZUNvbnNvbGU9MQotIQotISBSZWxhdGl2ZSBvciBhYnNvbHV0ZSBwYXRoIHdoZXJlIGV4cG9ydGluZyBhbmQgdHJhY2luZyBnb2VzLgotIQotdHJhY2VGaWxlPS4vdHJhY2UubG9nCi0hCi0hIEJpdG1hcCBvZiB2YXJpb3VzIGl0ZW1zIHRoYXQgY2FuIGJlIHRyYWNlZC4gU2VlIGRlYnVnLmh0bWwuIAotISBEZWZhdWx0cyB0byAwLgotIQotdHJhY2VMZXZlbD0yCi0KLSEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSEKLSEgVFJBTlNBQ1RJT04gQU5EIFJFQ09WRVJZIFBST1BFUlRJRVMKLSEKLSEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotIQotISAwIG1lYW5zIGRvIG5vdCBwZXJmb3JtIHJlY292ZXJ5IG9uIHN0YXJ0dXAuCi0hIDEgbWVhbnMgcGVyZm9ybSBhdXRvbWF0aWMgcmVjb3ZlcnkKLSEgMiAoZGVmYXVsdCkgbWVhbnMgcHJvbXB0IHRoZSB1c2VyIHVzaW5nIHN0YW5kYXJkIGluIAotIQotcmVjb3ZlcnlQb2xpY3k9MgotIQotISBTZXRzIHRoZSBsZXZlbCBvZiB0cmFuc2FjdGlvbiBqb3VybmFsbGluZy4gU2VlIHRyYW5zLmh0bWwuCi0hIERlZmF1bHRzIHRvIDEuCi0hCi0hIDAgLSBObyBqb3VybmFsbGluZyB0YWtlcyBwbGFjZS4KLSEgMSAtIE5vcm1hbCBqb3VybmFsbGluZyAoZGVmYXVsdCkuCi0hIDIgLSBGdWxsIGpvdXJuYWxsaW5nLgotIQotdHJhbnNMZXZlbD0xCi0hCi0hIFdoZW4gZG9pbmcgYW4gaW1wb3J0LCBkZWZpbmVzIHRoZSBudW1iZXIgb2Ygcm93cyBpbXBvcnRlZCAKLSEgYmVmb3JlIHRoZSB0cmFuc2FjdGlvbiBpcyBjb21taXR0ZWQuIFJlY29tbWVuZGVkIHZhbHVlIDgxOTIuCi0hIGRlZmF1bHRzIHRvIDEwMC4KLSEKLXRyYW5zSW1wb3J0cz0xMDAKLQotIS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotIQotISBEQVRFLCBUSU1FIEFORCBDVVJSRU5DWSBQUk9QRVJUSUVTCi0hCi0hLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSEKLSEgTnVtYmVyIG9mIGRpZ2l0cyBhZnRlciBkZWNpbWFsIHBvaW50IGluIGN1cnJlbmN5IG91dHB1dHMuIERlZmF1bHRzIHRvIDIuCi0hCi1jdXJyZW5jeURlY2ltYWw9MgotIQotISBDdXJyZW5jeSBzeW1ib2wgdXNlZCBpbiBjdXJyZW5jeSBvdXRwdXRzLiBEZWZhdWx0cyB0byAkLgotIQotY3VycmVuY3lTeW1ib2w9JAotIQotISBEZWZhdWx0IGZvcm1hdCBmb3IgZGF0ZSBjb2x1bW5zLiBEZWZhdWx0cyB0byAieXl5eS1tbS1kZCIuCi0hCi1kYXRlRm9ybWF0PXl5eXktbW0tZGQKLSEKLSEgRGVmYXVsdCBmb3JtYXQgZm9yIHRpbWVzdGFtcCBjb2x1bW5zLiBEZWZhdWx0cyB0byAieXl5eS1tbS1kZCBoaDptbTpzcy5sbGwiLgotIQotZGF0ZVRpbWVGb3JtYXQ9eXl5eS1tbS1kZCBoaDptbTpzcy5sbGwKLSEKLSEgSWYgc2V0LCB0aGVuIGFsbCB0d28gZGlnaXQgZGF0ZXMgbGVzcyB0aGFuIGl0cyB2YWx1ZSBhcmUgaW50ZXJwcmV0ZWQgCi0hIGFzIDIxc3QgY2VudHVyeSBkYXRlcy4gCi0hCi0hbWlsbGVuaXVtQm91bmRhcnk9NTAKLSEKLSEgU2V0IHRvIDEgY2F1c2VzIHRoZSBkYXRlIHN0cmluZyAibm93IiB0byBzdG9yZSBhIGZ1bGwgdGltZXN0YW1wLiAKLSEgRGVmYXVsdCBpcyB0byBzdG9yZSBvbmx5IHRoZSBkYXRlIGZvciBmaWVsZHMgd2l0aCBub3cgaG91ciBpbiB0aGUgCi0hIGZvcm1hdCBzdHJpbmcuCi0hCi1ub3dNZWFuc1RpbWU9MAotCi0hLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0hCi0hIFNUUklORyBIQU5ETElORyBQUk9QRVJUSUVTCi0hCi0hLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSEKLSEgSWYgc2V0IHRvIDEgdGhlbiBTdHJpbmcgaGFzaGVzIHVzZSB0aGUgSkRLIE9iamVjdC5oYXNoQ29kZSgpIGZ1bmN0aW9uLgotISBCeSBkZWZhdWx0LCB1c2VzIEluc3RhbnREQidzIFN0cmluZyBoYXNoaW5nLgotIQotYWx0U3RyaW5nSGFzaGluZz0wCi0hCi0hIFNldCB0byAxIHRvIGNhdXNlIExJS0UgY2xhdXNlcyB0byBhbHdheXMgcGVyZm9ybSBjYXNlIGluc2Vuc2l0aXZlIAotISBjb21wYXJpc29ucy4gCi0hCi1saWtlSWdub3JlQ2FzZT0wCi0hCi0hIFNhbWUgYXMgU0VUIExJVEVSQUwgU1RSSUNUX09OLiBQcmV2ZW50cyBzdHJpbmcgbGl0ZXJhbHMgYmVpbmcgaW50ZXJwcmV0ZWQKLSEgYXMgY29sdW1uIG5hbWVzIG9yIG51bWJlcnMuIERlZmF1bHQgaXMgMC4KLSEKLXN0cmljdExpdGVyYWxzPTAKLSEKLSEgU2V0IHRoaXMgdmFsdWUgdG8gMSAob25lKSBpZiB5b3Ugd291bGQgbGlrZSBQcmVwYXJlZFN0YXRlbWVudC5zZXRTdHJpbmcoKQotISB0byBpZ25vcmUgIlwiIChiYWNrc2xhc2gpIGNoYXJhY3RlcnMgd2hlbiBwcm9jZWVzaW5nIHN0cmluZyBjb25zdGFudHMuCi0hIFdoZW4gc2V0LCBJbnN0YW50REIgd2lsbCBub3QgYXR0ZW1wdCB0byBpbnRlcnByZXQgXCBhcyB0aGUgc3RhcnQgb2YgYW4KLSEgZXNjYXBlIHNlcXVlbmNlLiBEZWZhdWx0IGlzIDAuCi0hCi0hcHJlcGFyZUlnbm9yZXNFc2NhcGVzPTEKLQotIS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotIQotISBNSVNDRUxMQU5FT1VTIFBST1BFUlRJRVMKLSEKLSEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotIQotISBBbGxvd3Mgc2VsZWN0ZWQgSW5zdGFudERCIGtleXdvcmRzIHRvIGJlIHVuLXJlc2VydmVkLiAKLSEgZS5nLiBpZ25vcmVLZXl3b3Jkcz11cmwscXVvdGUgd291bGQgYWxsb3cgdGhlIGtleXdvcmRzIAotISB1cmwgYW5kIHF1b3RlIHRvIGJlIHVzZWQgYXMgdGFibGUgb3IgY29sdW1uIG5hbWVzLiAKLSEKLSEgVGhpcyBmYWNpbGl5IGlzIHByb3ZpZGVkIGZvciBjb21wYXRhdGJpbGl0eSByZWFzb25zIG9ubHkuCi0hIEl0J3MgdXNlIGlzIG5vdCByZWNvbW1lbmRlZCBBTkQgSVMgTk9UIFNVUFBPUlRFRC4KLSEKLSFpZ25vcmVLZXl3b3JkcwotIQotISBOb24temVybyBtZWFucyBkYXRhYmFzZSBpcyBvcGVuZWQgaW4gcmVhZCBvbmx5IG1vZGUuCi0hCi1yZWFkT25seT0wCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy8kZGIkdHlwZXMudGJsIGIvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvJGRiJHR5cGVzLnRibApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGU3ODE5Mi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy8kZGIkdHlwZXMudGJsCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvaW1wb3J0MS50YmwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy9pbXBvcnQxLnRibApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2IyMDg3MS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy9pbXBvcnQxLnRibAorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZSRkYiRDb2xzJHBLZXkudGJsIGIvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlJGRiJENvbHMkcEtleS50YmwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMyMzk4MmEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlJGRiJENvbHMkcEtleS50YmwKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy9zYW1wbGUkZGIkQ29scy50YmwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy9zYW1wbGUkZGIkQ29scy50YmwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMwOTJkMDEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlJGRiJENvbHMudGJsCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlJGRiJEluZGV4ZXMudGJsIGIvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlJGRiJEluZGV4ZXMudGJsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYWExNTE3Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZSRkYiRJbmRleGVzLnRibAorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZSRkYiRUYWJsZXMkcEtleS50YmwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy9zYW1wbGUkZGIkVGFibGVzJHBLZXkudGJsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyOGYwYzA5Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZSRkYiRUYWJsZXMkcEtleS50YmwKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvaW5zdGFudGRiL3RhYmxlcy9zYW1wbGUkZGIkVGFibGVzLnRibCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZSRkYiRUYWJsZXMudGJsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NDQxOTRkLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZSRkYiRUYWJsZXMudGJsCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlLmpybCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9pbnN0YW50ZGIvdGFibGVzL3NhbXBsZS5qcmwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc4YmVmNGYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi90YWJsZXMvc2FtcGxlLmpybAorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9udW1saXN0LnhtbCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9udW1saXN0LnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzZkNDFjMi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvbnVtbGlzdC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxOCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+Ci0gIDxuYW1lIGZpcnN0PSJTYW5qaXZhIiBsYXN0PSJXZWVyYXdhcmFuYSIvPgotICA8bmFtZSBmaXJzdD0iSm9zZXBoIiBsYXN0PSJLZXNzZWxtYW4iLz4KLSAgPG5hbWUgZmlyc3Q9IlN0ZXBoZW4iIGxhc3Q9IkF1cmllbW1hIi8+Ci0gIDxuYW1lIGZpcnN0PSJJZ29yIiBsYXN0PSJCZWxha292c2tpeSIvPiAgICAKLSAgPG5hbWUgZmlyc3Q9IkRhdmlkIiBsYXN0PSJNYXJzdG9uIi8+Ci0gIDxuYW1lIGZpcnN0PSJEYXZpZCIgbGFzdD0iQmVydG9uaSIvPgotICA8bmFtZSBmaXJzdD0iRG9uYWxkIiBsYXN0PSJMZXNsaWUiLz4KLSAgPG5hbWUgZmlyc3Q9IkVtaWx5IiBsYXN0PSJGYXJtZXIiLz4KLSAgPG5hbWUgZmlyc3Q9Ik15cmlhbSIgbGFzdD0iTWlkeSIvPgotICA8bmFtZSBmaXJzdD0iUGF1bCIgbGFzdD0iRGljayIvPgotICA8bmFtZSBmaXJzdD0iU2NvdHQiIGxhc3Q9IkJvYWciLz4KLSAgPG5hbWUgZmlyc3Q9IlNoYW5lIiBsYXN0PSJDdXJjdXJ1Ii8+Ci0gIDxuYW1lIGZpcnN0PSJNYXJjaWEiIGxhc3Q9IkhvZmZtYW4iLz4KLSAgPG5hbWUgZmlyc3Q9Ik5vYWgiIGxhc3Q9Ik1lbmRlbHNvaG4iLz4KLSAgPG5hbWUgZmlyc3Q9IkFsZXgiIGxhc3Q9Ik1vcnJvdyIvPiAgICAKLTwvZG9jPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9yZWFkbWUuaHRtbCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM4OTM2Zi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvcmVhZG1lLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMyArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotCi08aHRtbD4KLTxoZWFkPgotCTx0aXRsZT5YYWxhbiBTYW1wbGVzPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPGgyPlhhbGFuIFNhbXBsZXM8L2gyPgotPHA+Rm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzYW1wbGVzICh3aGF0IHRoZXkgaWxsdXN0cmF0ZSBhbmQgaG93IHRvIHJ1biB0aGVtKSwgc2VlIDxhIGhyZWY9Ii4uLy4uL2RvY3Mvc2FtcGxlcy5odG1sIj5TYW1wbGVzPC9hPi48L3A+Ci0KLQotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9YYWxhbiBTUUwgRXh0ZW5zaW9uLmRvYyBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvWGFsYW4gU1FMIEV4dGVuc2lvbi5kb2MKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZhYTU2NmQuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9YYWxhbiBTUUwgRXh0ZW5zaW9uLmRvYworKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvWGFsYW4gU1FMIEV4dGVuc2lvbi5odG0gYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL1hhbGFuIFNRTCBFeHRlbnNpb24uaHRtCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMWFiZjNkLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvWGFsYW4gU1FMIEV4dGVuc2lvbi5odG0KKysrIC9kZXYvbnVsbApAQCAtMSwxNjEgKzAsMCBAQAotPEhUTUw+Ci08SEVBRD4KLTxNRVRBIEhUVFAtRVFVSVY9IkNvbnRlbnQtVHlwZSIgQ09OVEVOVD0idGV4dC9odG1sOyBjaGFyc2V0PXdpbmRvd3MtMTI1MiI+Ci08TUVUQSBOQU1FPSJHZW5lcmF0b3IiIENPTlRFTlQ9Ik1pY3Jvc29mdCBXb3JkIDk3Ij4KLTxUSVRMRT5YYWxhbiBTUUwgRXh0ZW5zaW9uPC9USVRMRT4KLTwvSEVBRD4KLTxCT0RZIExJTks9IiMwMDAwZmYiIFZMSU5LPSIjODAwMDgwIj4KLQotPEI+PEZPTlQgRkFDRT0iQXJpYWwiIFNJWkU9NT48UCBBTElHTj0iQ0VOVEVSIj48QSBOQU1FPSJfVG9jNTA5MDYyNTUzIj5YYWxhbiBTUUwgRXh0ZW5zaW9uPC9BPjwvUD4KLTxQIEFMSUdOPSJDRU5URVIiPjxBIE5BTUU9Il9Ub2M1MDkwNjI1NTQiPkNvbm5lY3Rpb25zIGFuZCBRdWVyaWVzPC9BPjwvUD4KLTwvRk9OVD48Rk9OVCBTSVpFPTI+PFA+RGF0YWJhc2UgQ29ubmVjdGlvbnMmIzk7PC9CPjwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQzNSI+KjwvQT48RElSPgotCi08Rk9OVCBTSVpFPTI+PFA+UHJvdmlkaW5nIENvbm5lY3Rpb24gaW5mb3JtYXRpb24gaW4gdGhlIFhTTCBGaWxlJiM5OzwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQzNiI+KjwvQT48L1A+Ci08ST48Rk9OVCBTSVpFPTI+PFA+WENvbm5lY3Rpb24oU3JpbmcgREJEcml2ZXIsIFN0cmluZyBEQnVybCkmIzk7PC9JPjwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQzNyI+KjwvQT48L1A+Ci08ST48Rk9OVCBTSVpFPTI+PFA+WENvbm5lY3Rpb24oU3RyaW5nIERCRHJpdmVyLCBTdHJpbmcgREJ1cmwsIFN0cmluZyBVc2VyLCBTdHJpbmcgUGFzc3dvcmQpJiM5OzwvST48L0ZPTlQ+PEEgSFJFRj0iI19Ub2M1MDkxMTk0MzgiPio8L0E+PC9QPgotPEk+PEZPTlQgU0laRT0yPjxQPlhDb25uZWN0aW9uKFN0cmluZyBEQkRyaXZlciwgU3RyaW5nIERCdXJsLCBOb2RlTGlzdCBQcm9wZXJ0aWVzKSYjOTs8L0k+PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDM5Ij4qPC9BPjwvUD4KLTxGT05UIFNJWkU9Mj48UD5Qcm92aWRpbmcgQ29ubmVjdGlvbiBpbmZvcm1hdGlvbiBpbiB0aGUgWE1MIEZpbGUmIzk7PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDQwIj4qPC9BPjwvUD4KLTxJPjxGT05UIFNJWkU9Mj48UD5YQ29ubmVjdGlvbihOb2RlTGlzdCBDb25uZWN0aW9uRGF0YSkmIzk7PC9JPjwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQ0MSI+KjwvQT48L1A+Ci08Rk9OVCBTSVpFPTI+PFA+VXNpbmcgRXhpc3RpbmcgQ29ubmVjdGlvbnMgaW4gYSBjb25uZWN0aW9uIHBvb2wmIzk7PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDQyIj4qPC9BPjwvUD4KLTxJPjxGT05UIFNJWkU9Mj48UD5YQ29ubmVjdGlvbihTdHJpbmcgQ29ubmVjdGlvbk5hbWUpJiM5OzwvST48L0ZPTlQ+PEEgSFJFRj0iI19Ub2M1MDkxMTk0NDMiPio8L0E+PC9QPjwvRElSPgotCi08Qj48Rk9OVCBTSVpFPTI+PFA+Q29ubmVjdGlvbiBQb29scyYjOTs8L0I+PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDQ0Ij4qPC9BPjwvUD48RElSPgotCi08Rk9OVCBTSVpFPTI+PFA+T3ZlcnZpZXcmIzk7PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDQ1Ij4qPC9BPjwvUD4KLTxGT05UIFNJWkU9Mj48UD5DcmVhdGluZyBhIG5ldyB3cmFwcGVyJiM5OzwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQ0NiI+KjwvQT48L1A+Ci08Rk9OVCBTSVpFPTI+PFA+VGhlIERlZmF1bHQgQ29ubmVjdGlvbiBQb29sJiM5OzwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQ0NyI+KjwvQT48L1A+PC9ESVI+Ci0KLTxCPjxGT05UIFNJWkU9Mj48UD5RdWVyaWVzJiM5OzwvQj48L0ZPTlQ+PEEgSFJFRj0iI19Ub2M1MDkxMTk0NDgiPio8L0E+PC9QPjxESVI+Ci0KLTxGT05UIFNJWkU9Mj48UD5TdGFuZGFyZCBxdWVyaWVzJiM5OzwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQ0OSI+KjwvQT48L1A+Ci08Rk9OVCBTSVpFPTI+PFA+UGFyYW1ldGVyIGJhc2VkIHF1ZXJpZXMmIzk7PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDUwIj4qPC9BPjwvUD4KLTxJPjxGT05UIFNJWkU9Mj48UD5PdmVydmlldyYjOTs8L0k+PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDUxIj4qPC9BPjwvUD4KLTxJPjxGT05UIFNJWkU9Mj48UD5IYW5kbGluZyBWYWx1ZSBhbmQgVHlwZSBJbmZvcm1hdGlvbiYjOTs8L0k+PC9GT05UPjxBIEhSRUY9IiNfVG9jNTA5MTE5NDUyIj4qPC9BPjwvUD48L0RJUj4KLQotPEI+PEZPTlQgU0laRT0yPjxQPkV4YW1wbGVzJiM5OzwvQj48L0ZPTlQ+PEEgSFJFRj0iI19Ub2M1MDkxMTk0NTMiPio8L0E+PC9QPjxESVI+Ci0KLTxGT05UIFNJWkU9Mj48UD5CYXNpYyYjOTs8L0ZPTlQ+PEEgSFJFRj0iI19Ub2M1MDkxMTk0NTQiPio8L0E+PC9QPgotPEZPTlQgU0laRT0yPjxQPkV4dGVybmFsIENvbm5lY3Rpb25zJiM5OzwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQ1NSI+KjwvQT48L1A+Ci08Rk9OVCBTSVpFPTI+PFA+UFF1ZXJ5JiM5OzwvRk9OVD48QSBIUkVGPSIjX1RvYzUwOTExOTQ1NiI+KjwvQT48L1A+Ci08Rk9OVCBTSVpFPTI+PC9ESVI+Ci08L1A+Ci08L0ZPTlQ+PEI+PEZPTlQgRkFDRT0iQXJpYWwiIFNJWkU9ND48UD48QSBOQU1FPSJfVG9jNTA5MDYyNTU1Ij48QSBOQU1FPSJfVG9jNTA5MTE5NDM1Ij5EYXRhYmFzZSBDb25uZWN0aW9uPC9BPnM8L0E+PC9QPjxESVI+Ci0KLTwvQj48L0ZPTlQ+PEZPTlQgU0laRT0yPjxQIEFMSUdOPSJKVVNUSUZZIj5UaGUgU1FMIEV4dGVuc2lvbiBwcm92aWRlcyAyIGJhc2ljIG1lY2hhbmlzbXMgdG8gY29ubmVjdCB0byB0aGUgZGF0YWJhc2UuIFRoZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGNhbiBlaXRoZXIgYmUgcHJvdmlkZWQgaW4gdGhlIFhTTC9YTUwgb3IgcHVsbGVkIGZyb20gYSBDb25uZWN0aW9uIFBvb2wgdGhhdCB3YXMgY3JlYXRlZCBvdXRzaWRlIHRoZSBYYWxhbiBsaWJyYXJ5LjwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj5UaGUgWENvbm5lY3Rpb24gb2JqZWN0IGlzIHVzZWQgdG8gcmVwcmVzZW50IGEgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UuIFRoZSBhY3R1YWwgY29ubmVjdGlvbiBpcyBlc3RhYmxpc2hlZCB0aHJvdWdoIHRoZSBvYmplY3QgY29uc3RydWN0b3IuIEVhY2ggb2YgdGhlIGRpZmZlcmVudCBtZWNoYW5pc21zIGRpZmZlcnMgd2l0aCB0aGUgc2lnbmF0dXJlIG9mIHRoZSBleHRlbnNpb24uPC9QPgotPFAgQUxJR049IkpVU1RJRlkiPldoZW4gdGhlIGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gaXMgcHJvdmlkZWQgaW4gdGhlIFhTTCBvciBYTUwgc291cmNlcywgYSBkZWZhdWx0IGNvbm5lY3Rpb24gcG9vbCB3aWxsIGJlIGNyZWF0ZWQgb24gaXRzIGJlaGFsZiBidXQgZHVlIHRvIHJlc3RyaWN0aW9ucyBpbiBzb21lIGRyaXZlcnMsIHRoZSBhY3R1YWwgcG9vbGluZyBvZiBjb25uZWN0aW9ucyB3aWxsIGRpc2FibGVkIGJ5IGRlZmF1bHQuIFNlZSBDb25uZWN0aW9uIFBvb2xzLCBUaGUgRGVmYXVsdCBDb25uZWN0aW9uIFBvb2wuPC9QPgotPC9GT05UPjxCPjxJPjxGT05UIEZBQ0U9IkFyaWFsIj48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDM2Ij5Qcm92aWRpbmcgQ29ubmVjdGlvbiBpbmZvcm1hdGlvbiBpbiB0aGUgWFNMIEZpbGU8L0E+PC9QPjxESVI+Ci0KLTwvQj48L0k+PC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+V2hlbiBwcm92aWRpbmcgQ29ubmVjdGlvbiBJbmZvcm1hdGlvbiBmcm9tIHRoZSBYU0wgb3IgWE1MIGlucHV0IHNvdXJjZXMsIHRoZSBYQ29ubmVjdGlvbiBvYmplY3Qgd2lsbCBjcmVhdGUgYSBkZWZhdWx0IGNvbm5lY3Rpb24gcG9vbCB0aGF0IHdpbGwgZXhpc3QgZm9yIHRoZSBsaWZldGltZSBvZiB0aGUgVHJhbnNmb3JtYXRpb24gb2JqZWN0LjwvUD4KLTwvRk9OVD48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQzNyI+WENvbm5lY3Rpb24oU3JpbmcgREJEcml2ZXIsIFN0cmluZyBEQnVybCk8L0E+PC9QPgotPC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+Q3JlYXRlIGEgc3RhbmRhcmQgSkRCQyBjb25uZWN0aW9uIHVzaW5nIHRoZSBzcGVjaWZpZWQgZHJpdmVyIGFuZCBVUkwuIFRoaXMgaXMgdXNlZCBwcmltYXJpbHkgZm9yIGxvY2FsIGRhdGFiYXNlcyB0aGF0IGRvIG5vdCByZXR1cm4gdXNlciBpZGVudGlmaWNhdGlvbi48L1A+Ci08L0ZPTlQ+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPjxBIE5BTUU9Il9Ub2M1MDkxMTk0MzgiPlhDb25uZWN0aW9uKFN0cmluZyBEQkRyaXZlciwgU3RyaW5nIERCdXJsLCBTdHJpbmcgVXNlciwgU3RyaW5nIFBhc3N3b3JkKTwvQT48L1A+PERJUj4KLQotPC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+Q3JlYXRlIGEgc3RhbmRhcmQgSkRCQyBDb25uZWN0aW9uLCB3aGljaCBhbHNvIHByb3ZpZGVzIHVzZXIgaWRlbnRpZmljYXRpb24uPC9QPjwvRElSPgotCi08L0ZPTlQ+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPjxBIE5BTUU9Il9Ub2M1MDkxMTk0MzkiPlhDb25uZWN0aW9uKFN0cmluZyBEQkRyaXZlciwgU3RyaW5nIERCdXJsLCBOb2RlTGlzdCBQcm9wZXJ0aWVzKTwvQT48L1A+PERJUj4KLQotPC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+Q3JlYXRlIGEgc3RhbmRhcmQgSkRCQyBjb25uZWN0aW9uIHRoYXQgbG9hZHMgdGhlIGRhdGFiYXNlIGRyaXZlciB1c2luZyB0aGUgc3BlY2lmaWVkIFVSTC4gVGhlIE5vZGVMaXN0IHByb3ZpZGVzIHdpbGwgdGhlbiBiZSBjb252ZXJ0ZWQgaW50byBhIHByb3BlcnRpZXMgb2JqZWN0IHdoaWNoIHdpbGwgYmUgcGFzc2VzIGluIHdoZW4gZ2V0dGluZyB0aGUgSkRCQyBjb25uZWN0aW9uLjwvUD48L0RJUj4KLTwvRElSPgotCi08L0ZPTlQ+PEI+PEk+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPjxBIE5BTUU9Il9Ub2M1MDkxMTk0NDAiPlByb3ZpZGluZyBDb25uZWN0aW9uIGluZm9ybWF0aW9uIGluIHRoZSBYTUwgRmlsZTwvQT48L1A+PERJUj4KLQotPC9CPjwvST48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDQxIj5YQ29ubmVjdGlvbihOb2RlTGlzdCBDb25uZWN0aW9uRGF0YSk8L0E+PC9QPjxESVI+Ci0KLTwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPkNyZWF0ZSBjb25uZWN0aW9uIGFuZCBwYXNzIGluIHRoZSBjb21wbGV0ZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGFzIGEgTm9kZWxpc3QuIFRoaXMgYWxsb3dzIHRoZSBYTUwgZGF0YSB0byBwcm92aWRlIHRoZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uLiBUaGUgbm9kZSBsaXN0IHdpbGwgYmUgdXNlZCB0byBjcmVhdGUgYSBuYW1lZCB2YWx1ZSBwYWlyIGxpc3Qgd2hlcmUgdGhlIE5vZGUgTmFtZSB3aWxsIHJlcHJlc2VudCB0aGUgbmFtZSBhbmQgdGhlIE5vZGUgVmFsdWUgd2lsbCBiZSB0aGUgdmFsdWUuIFJlcXVpcmVkIFRhZ3MgY29uc2lzdCBvZiAmcXVvdDtkYmRyaXZlciZxdW90OyBhbmQgJnF1b3Q7ZGJ1cmwmcXVvdDsuIE9wdGlvbmFsIHRhZ3MgY2FuIGluY2x1ZGUgJnF1b3Q7dXNlciZxdW90OyBhbmQgJnF1b3Q7cGFzc3dvcmQmcXVvdDsgdG8gc3BlY2lmeSB0aGUgdXNlciBpZGVudGlmaWNhdGlvbiBidXQgY2FuIGFsc28gaW5jbHVkZSBhbnkgb3RoZXIgZGF0YWJhc2UgY29ubmVjdGlvbiBwcm9wZXJ0eS48L1A+PC9ESVI+Ci08L0RJUj4KLQotPC9GT05UPjxCPjxJPjxGT05UIEZBQ0U9IkFyaWFsIj48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDQyIj5Vc2luZyBFeGlzdGluZyBDb25uZWN0aW9ucyBpbiBhIGNvbm5lY3Rpb24gcG9vbDwvQT48L1A+PERJUj4KLQotPC9CPjwvST48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDQzIj5YQ29ubmVjdGlvbihTdHJpbmcgQ29ubmVjdGlvbk5hbWUpPC9BPjwvUD48RElSPgotCi08L0ZPTlQ+PEZPTlQgU0laRT0yPjxQIEFMSUdOPSJKVVNUSUZZIj5UaGUgWGFsYW4gU1FMIEV4dGVuc2lvbnMgYWxsb3dzIHRoZSBjb250cm9sbGluZyBwcm9ncmFtIHRvIGNyZWF0ZSBhbiBleHRlcm5hbCBKREJDIENvbm5lY3Rpb24gUG9vbCBhbmQgcmVmZXJlbmNlIHRoZSBjb25uZWN0aW9uIHBvb2xzIGJ5IG5hbWUgaW5zaWRlIHRoZSBTdHlsc2hlZXQuIEJlc2lkZXMgcHJvdmlkaW5nIGEgbWVjaGFuaXNtIHRvIHNoYXJlIGNvbm5lY3Rpb24gcmVzb3VyY2VzIHdpdGggWGFsYW4sIGlzIGFsc28gYWxsb3dzIHRoZSBTdHlsZXNoZWV0IHRvIG5vdCBiZSBjb25jZXJuZWQgd2l0aCB0aGUgQ29ubmVjdGlvbiBwcm9wZXJ0aWVzIGFsbCB0b2dldGhlci48L1A+PC9ESVI+Ci08L0RJUj4KLTwvRElSPgotCi08L0ZPTlQ+PEI+PEZPTlQgRkFDRT0iQXJpYWwiIFNJWkU9ND48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDQ0Ij5Db25uZWN0aW9uIFBvb2xzPC9BPjwvUD48RElSPgotCi08L0ZPTlQ+PEk+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPjxBIE5BTUU9Il9Ub2M1MDkxMTk0NDUiPk92ZXJ2aWV3PC9BPjwvUD48RElSPgotCi08L0I+PC9JPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPkNvbm5lY3Rpb24gcG9vbHMgYWxsb3cgdGhlIFhhbGFuIFRyYW5zZm9ybWVyIHRvIHNoYXJlIGNvbm5lY3Rpb25zIHdpdGggdGhlIHJlc3Qgb2YgdGhlIGFwcGxpY2F0aW9uLiBBbnkgZXhpc3RpbmcgSkRCQyBDb25uZWN0aW9uIHBvb2wgc2hvdWxkIGJlIGNvbXBhdGlibGUgd2l0aCB0aGUgWGFsYW4gVHJhbnNmb3JtZXIgYnkgY3JlYXRpbmcgYSB3cmFwcGVyIGNsYXNzIGFyb3VuZCB0aGUgc3BlY2lmaWMgY29ubmVjdGlvbiBwb29sIGFuZCByZWdpc3RlcmluZyBpdCB3aXRoIHRoZSBYQ29ubmVjdGlvblBvb2xNYW5hZ2VyLjwvUD48L0RJUj4KLQotPC9GT05UPjxCPjxJPjxGT05UIEZBQ0U9IkFyaWFsIj48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDQ2Ij5DcmVhdGluZyBhIG5ldyB3cmFwcGVyPC9BPjwvUD48RElSPgotCi08L0I+PC9JPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPlRoZSBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuY29ubmVjdGlvbiBpcyB0aGUgaW50ZXJmYWNlIHRoYXQgbmVlZHMgdG8gYmUgaW1wbGVtZW50ZWQgYmUgY29tcGF0aWJsZSB3aXRoIHRoZSBYYWxhbiBUcmFuc2Zvcm1lci48L1A+PC9ESVI+Ci0KLTwvRk9OVD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQ0NyI+VGhlIERlZmF1bHQgQ29ubmVjdGlvbiBQb29sPC9BPjwvUD48RElSPgotCi08L0I+PC9JPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPlRvIHByb3ZpZGUgYSB1bmlmb3JtIGludGVybmFsIHByb2dyYW1taW5nIG1vZGVsLCB0aGUgWENvbm5lY3Rpb24gb2JqZWN0IHdpbGwgY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBEZWZhdWx0Q29ubmVjdGlvblBvb2wuIEJ5IGRlZmF1bHQgdGhlIERlZmF1bHQgQ29ubmVjdGlvbiBQb29sIHdpbGw8L1A+PC9ESVI+Ci08L0RJUj4KLQotPC9GT05UPjxCPjxGT05UIEZBQ0U9IkFyaWFsIiBTSVpFPTQ+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQ0OCI+UXVlcmllczwvQT48L1A+PERJUj4KLQotPC9GT05UPjxJPjxGT05UIEZBQ0U9IkFyaWFsIj48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDQ5Ij5TdGFuZGFyZCBxdWVyaWVzPC9BPjwvUD48RElSPgotPERJUj4KLQotPC9CPjwvST48L0ZPTlQ+PEZPTlQgU0laRT0yPjxQIEFMSUdOPSJKVVNUSUZZIj5xdWVyeShYQ29ubmVjdGlvbiBjb25uLCBTdHJpbmcgU1FMKTwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj5TdGFuZGFyZCBxdWVyaWVzIHRha2UgYSBjb25uZWN0aW9uIGFzIGFyZ3VtZW50cywgYW4gWENvbm5lY3Rpb24gYW5kIHRoZSBTUUwgU3RyaW5nLiBJdCBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIFN0eWxlc2hlZXQgZGVzaWduZXIgdG8gZm9ybWF0IHRoZSBTUUwgU3RyaW5nIGNvbXBsZXRlbHkgaW5jbHVkaW5nIGFueSBxdW90ZXMgdGhhdCBhcmUgbmVjZXNzYXJ5LiBGb3Igc3RhdGljIHF1ZXJpZXMgdGhpcyBpcyBmaW5lIGJlY2F1c2UgdGhlIHN0aW5nIGNhbiBiZSBhc3NlbWJsZWQgYXQgZGVzaWduIHRpbWUuPC9QPjwvRElSPgotPC9ESVI+Ci0KLTwvRk9OVD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQ1MCI+UGFyYW1ldGVyIGJhc2VkIHF1ZXJpZXM8L0E+PC9QPjxESVI+Ci0KLTwvQj48L0k+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQ1MSI+T3ZlcnZpZXc8L0E+PC9QPjxESVI+Ci0KLTwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPlBhcmFtZXRlciBiYXNlZCBxdWVyaWVzIGFyZSB1c2VkIHdoZW4gZGF0YSB0aGF0IGR5bmFtaWNhbGx5IGNoYW5nZXMgdGhlIHF1ZXJ5IG5lZWRzIHRvIGJlIHN1cHBsaWVkIGZyb20gdGhlIFhNTCBEYXRhLjwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj5UaGUgU3R5bGVzaGVldCB3aWxsIHByb3ZpZGUgdGhlIHNrZWxldG9uIHRlbXBsYXRlIG9mIHRoZSBxdWVyeSB3aXRoIHBsYWNlIGhvbGRlcnMgd2hlcmUgdGhlIGRhdGEgZ29lcywgdGhlbiBwcm92aWRlcyBzZXZlcmFsIG1lY2hhbmlzbXMgdG8gYXBwbHkgdGhhdCBkYXRhIGZyb20gdGhlIFhNTCBEYXRhLjwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj5QYXJhbWV0ZXIgYmFzZWQgcXVlcmllcyB0YWtlIGFkdmFudGFnZSBvZiB0aGUgSkRCQyBQcmVwYXJlZCBzdGF0ZW1lbnQgc2VtYW50aWNzLjwvUD48L0RJUj4KLQotPC9GT05UPjxGT05UIEZBQ0U9IkFyaWFsIj48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDUyIj5IYW5kbGluZyBWYWx1ZSBhbmQgVHlwZSBJbmZvcm1hdGlvbjwvQT48L1A+PERJUj4KLQotPC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+V2hlbiB1c2luZyBwYXJhbWV0ZXJpemVkIHF1ZXJ5IHRoZSBwbGFjZSBtYXJrZXJzIGluIHRoZSBxdWVyeSAoYSAmcXVvdDs/JnF1b3Q7KSB3aWxsIGJlIHJlcGxhY2VkIHdpdGggZGF0YSB0aGF0IGlzIHByb3ZpZGVkIHVzaW5nIG9uZSBvZiB0aGUgYWRkUGFyYW1ldGVyLi4gbWV0aG9kcy4gV2hlbiBhZGRpbmcgZGF0YSB0byBhIHBhcmFtZXRlciBiYXNlZCBxdWVyeSwgdGhlIHR5cGUgb2YgZWFjaCB2YWx1ZSBtdXN0IGFsc28gYmUgaW5jbHVkZWQgc28gdGhhdCByZWFsIHF1ZXJ5IGNhbiBiZSBwcm9kdWNlZC4gVGhlIHR5cGUgaW5mb3JtYXRpb24gY2FuIGJlIHBhc3NlZCBpbiBhcyBhIGNvbXBvbmVudCBvZiB0aGUgUXVlcnkgb3IgdGhlIERhdGEgd2hpY2ggZXZlciBpcyBtb3JlIGNvbnZlbmllbnQgdG8gdGhlIFN0eWxlc2hlZXQgZGVzaWduZXIuIDwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj5JZiB0aGUgdHlwZSBpbmZvcm1hdGlvbiBpcyBtaXNzaW5nIGZvciBhIGRhdGEgcG9pbnQsIHRoZSBkZWZhdWx0IHR5cGUgaXMgc2V0IHRvIFN0cmluZy48L1A+Ci08UCBBTElHTj0iSlVTVElGWSI+VGhlIGxpc3Qgb2YgcG9zc2libGUgdmFsdWUgdHlwZXMgaW5jbHVkZSwgc3RyaW5nLCAgYmlnZGVjaW1hbCwgYm9vbGVhbiwgYnl0ZXMsIGRhdGUsIGRvdWJsZSwgZmxvYXQsIGxvbmcsIHNob3J0LCB0aW1lLCB0aW1lc3RhbXAuPC9QPjwvRElSPgotCi08L0ZPTlQ+PEI+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPnBxdWVyeShYQ29ubmVjdGlvbiwgcXVlcnkpPC9QPjxESVI+Ci0KLTwvQj48L0ZPTlQ+PEZPTlQgU0laRT0yPjxQPldoZW4ganVzdCB0aGUgcXVlcnkgc3RhdGVtZW50IGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciwgdGhlIFR5cGUgaW5mb3JtYXRpb24gbXVzdCBiZSBwYXNzZWQgaW4gYXMgYSBjb21wb25lbnQgb2YgdGhlIGRhdGEuIDwvUD48L0RJUj4KLQotPC9GT05UPjxCPjxGT05UIEZBQ0U9IkFyaWFsIj48UD5wcXVlcnkoWENvbm5lY3Rpb24sIHF1ZXJ5LCB0eXBlaW5mbyk8L1A+PERJUj4KLQotPC9CPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPlRoaXMgYWxsb3dzIHRoZSBxdWVyeSB0byBiZSBzcGVjaWZpZWQgdXNpbmcgdGhlICZxdW90Oz8mcXVvdDsgcGxhY2UgaG9sZGVycyBhbmQgZGVmaW5pbmcgdGhlIHR5cGUgZm9yIGVhY2ggb2YgdGhlIHBsYWNlaG9sZGVycyBhcyBhIGNvbW1hIHNlcGFyYXRlZCB2YWx1ZSBzdHJpbmcuIGkuZS4gJnF1b3Q7c3RyaW5nLGludCxzdHJpbmcsZGF0ZXRpbWUmcXVvdDs8L1A+PC9ESVI+Ci0KLTwvRk9OVD48Qj48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+YWRkUGFyYW1ldGVyKFhDb25uZWN0aW9uLCB2YWx1ZSk8L1A+PERJUj4KLQotPC9CPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFA+QWRkIGEgbmV3IHZhbHVlIHRvIGJlIHVzZWQgd2l0aCBhIHBxdWVyeSwgZWFjaCBuZXcgdmFsdWUgaXMgYXBwZW5kZWQgdG8gYSBsaXN0IHRoYXQgd2lsbCBiZSBtZXJnZWQgaW50byB0aGUgcXVlcnkgc3RhdGVtZW50IHdoZW4gdGhlIHBxdWVyeSBzdGF0ZW1lbnQgaXMgZXhlY3V0ZWQuIEFsbCBkYXRhIHBvaW50cyBtdXN0IGJlIGFkZGVkIHByaW9yIHRvIGV4ZWN1dGluZyB0aGUgcHF1ZXJ5IHN0YXRlbWVudC48L1A+PC9ESVI+Ci0KLTwvRk9OVD48Qj48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+YWRkUGFyYW1ldGVyV2l0aFR5cGUoWENvbm5lY3Rpb24sIHZhbHVlLHR5cGUpPC9QPjxESVI+Ci0KLTwvQj48L0ZPTlQ+PEZPTlQgU0laRT0yPjxQPkFkZCBhIG5ldyB2YWx1ZSBzcGVjaWZ5aW5nIHRoZSB0eXBlIGluZm9ybWF0aW9uIGFsc28uPC9QPjwvRElSPgotCi08L0ZPTlQ+PEI+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPmFkZFBhcmFtZXRlckZyb21FbGVtZW50KFhDb25uZWN0aW9uLCBOb2RlTGlzdCk8L1A+PERJUj4KLQotPC9CPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPkFkZCBhIGJsb2NrIG9mIGRhdGEgcG9pbnRzIGZyb20gYSBub2RlIGxpc3QgcXVlcmllZCBmcm9tIHRoZSBYTUwgRGF0YSBTb3VyY2UuICBFYWNoIHRhZyBuYW1lIGF0IHRoZSBTVEFSVF9UQUcgYW5kIFRBRzEgbGV2ZWwgYXJlIGlycmVsZXZhbnQsIHRoZSBvbmx5IHNpZ25pZmljYW50IGluZm9ybWF0aW9uIGlzIHRoZSB2YWx1ZSBhbmQgcG9zc2libHkgdGhlIHR5cGUgYXR0cmlidXRlLjwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj5JZiB0aGUgdHlwZSBhdHRyaWJ1dGUgaXMgcHJlc2VudCwgaXQgd2lsbCBzZXQgdGhlIGN1cnJlbnQgdHlwZS4gSWYgdGhlIHR5cGUgaW5mb3JtYXRpb24gaXMgbWlzc2luZywgaXQgd2lsbCBlaXRoZXIgYmUgcHJvdmlkZSB0aHJvdWdoIG9uZSBvZiB0aGUgb3RoZXIgbWVjaGFuaXNtcyBvciBkZWZhdWx0IHRvIGEgc3RyaW5nLjwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj4mbHQ7U1RBUlRfVEFHJmd0OzwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj4gICZsdDtUQUcxJmd0OyB0eXBlPSZxdW90O2ludCZxdW90OyZndDt2YWx1ZSZsdDsvVEFHMSZndDs8L1A+Ci08UCBBTElHTj0iSlVTVElGWSI+Jmx0Oy9TVEFSVF9UQUc8L1A+Ci08UCBBTElHTj0iSlVTVElGWSI+PC9QPgotPFAgQUxJR049IkpVU1RJRlkiPlR5cGljYWwgaW1wbGVtZW50YXRpb24gPC9QPgotPFAgQUxJR049IkpVU1RJRlkiPiZsdDt4c2w6cGFyYW0gbmFtZT0mcXVvdDtwbGlzdCZxdW90OyBzZWxlY3Q9JnF1b3Q7L1NUQVJUX1RBRyZxdW90OyAvJmd0OzwvUD4KLTxQIEFMSUdOPSJKVVNUSUZZIj4mbHQ7eHNsOmFkZFBhcmFtZXRlckZyb21FbGVtZW50KCAkY29ubiwgJHBsaXN0KTs8L1A+PC9ESVI+Ci08L0RJUj4KLTwvRElSPgotCi08L0ZPTlQ+PEI+PEZPTlQgRkFDRT0iQXJpYWwiIFNJWkU9ND48UD48QSBOQU1FPSJfVG9jNTA5MTE5NDUzIj5FeGFtcGxlczwvQT48L1A+PERJUj4KLQotPC9CPjwvRk9OVD48Rk9OVCBTSVpFPTI+PFAgQUxJR049IkpVU1RJRlkiPkFsbCBvZiB0aGUgZm9sbG93aW5nIGV4YW1wbGVzIHVzZSB0aGUgRW5oeWRyYSBJbnN0YW50REIgd2hpY2ggaXMgaW5jbHVkZWQgYXMgcGFydCBvZiB0aGUgWGFsYW4gZGlzdHJpYnV0aW9uIHRvIG9wZXJhdGUuIFBsZWFzZSByZWFkIHRoZSBFbmh5ZHJhIGRvY3VtZW50YXRpb24gb24gbWFuYWdpbmcgYW4gSW5zdGFudERCIGh0dHA6Ly93d3cuaW5zdGFudGRiLmNvLnVrLzwvUD4KLTwvRk9OVD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQ1NCI+QmFzaWM8L0E+PC9QPjxESVI+Ci0KLTwvQj48L0k+PC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+VGhlIFhNTC9YU0wgRmlsZXMgKGRiaW5mby54bWwgYW5kIGRidGVzdC54c2wpIHByb3ZpZGUgYW4gZXhhbXBsZSBvZiBpbXBsZW1lbnRpbmcgYSBiYXNpYyBjb25uZWN0aW9uIHdoZXJlIHRoZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGlzIHByb3ZpZGVkIGluIHRoZSBYU0wgZmlsZSB1c2luZyBhIHN0YXRpYyBxdWVyeS48L1A+Ci08UCBBTElHTj0iSlVTVElGWSI+VGhlIFhNTC9YU0wgRmlsZXMgKGRiaW5mby54bWwgYW5kIGRidGVzdC1jaW5mby54c2wpIHByb3ZpZGUgYW4gZXhhbXBsZSBvZiBpbXBsZW1lbnRpbmcgYSBiYXNpYyBjb25uZWN0aW9uIHdoZXJlIHRoZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGlzIHByb3ZpZGVkIGFzIGEgbm9kZSBsaXN0IGluIHRoZSBYTUwgZmlsZSB1c2luZyBhIHN0YXRpYyBxdWVyeS48L1A+PC9ESVI+Ci0KLTwvRk9OVD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCI+PFA+PEEgTkFNRT0iX1RvYzUwOTExOTQ1NSI+RXh0ZXJuYWwgQ29ubmVjdGlvbnM8L0E+PC9QPjxESVI+Ci0KLTwvQj48L0k+PC9GT05UPjxGT05UIFNJWkU9Mj48UCBBTElHTj0iSlVTVElGWSI+VGhlIGphdmEgZmlsZSBFeHRlcm5hbENvbm5lY3Rpb24gZGVtb25zdHJhdGVzIGhvdyB0byBidWlsZCBhIEpEQkMgY29ubmVjdGlvbiBwb29sIHRoYXQgaXMgaW5kZXBlbmRlbnQgb2YgWGFsYW4uIFRoZSBhY3R1YWwgY29ubmVjdGlvbiBwb29sIHVzZWQgaXMgdGhlIERlZmF1bHQgQ29ubmVjdGlvbiBwb29sIGluc2lkZSB0aGUgWGFsYW4gU1FMIEV4dGVuc2lvbiwgd2hpY2ggYWxyZWFkeSBpbXBsZW1lbnRzIHRoZSBDb25uZWN0aW9uUG9vbCBpbnRlcmZhY2Ugc28gbm8gd3JhcHBlciB3YXMgcmVxdWlyZWQuIFRvIGltcGxlbWVudCBhIHRoaXJkIHBhcnR5IGNvbm5lY3Rpb24gcG9vbCwgYSB3cmFwcGVyIGZ1bmN0aW9uIG11c3QgYmUgaW1wbGVtZW50ZWQuPC9QPjwvRElSPgotCi08L0ZPTlQ+PEI+PEk+PEZPTlQgRkFDRT0iQXJpYWwiPjxQPjxBIE5BTUU9Il9Ub2M1MDkxMTk0NTYiPlBRdWVyeTwvQT48L1A+PERJUj4KLQotPC9CPjwvST48L0ZPTlQ+PEZPTlQgU0laRT0yPjxQIEFMSUdOPSJKVVNUSUZZIj5UaGUgWE1ML1hTTCBmaWxlIChkYkluZm8ueG1sIGFuZCBkYnRlc3QueHNsKSBwcm92aWRlIGFuIGV4YW1wbGUgb2YgaW1wbGVtZW50aW5nIGEgcGFyYW1ldGVyIGJhc2VkIHF1ZXJ5LjwvUD48L0RJUj4KLTwvRElSPgotPC9GT05UPjwvQk9EWT4KLTwvSFRNTD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9EdW1wU1FMLnhzbCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9EdW1wU1FMLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMTRkNmNhYS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2Jhc2ljLWNvbm5lY3Rpb24vRHVtcFNRTC54c2wKKysrIC9kZXYvbnVsbApAQCAtMSwyMCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB2ZXJzaW9uPSIxLjAiCi0gICAgICAgICAgICAgICAgeG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InNxbCI+Ci0KLTx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLz4KLQotPHhzbDpwYXJhbSBuYW1lPSJkcml2ZXIiIHNlbGVjdD0iJ29yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlciciLz4KLTx4c2w6cGFyYW0gbmFtZT0iZGF0YXNvdXJjZSIgc2VsZWN0PSInamRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnAnIi8+Ci08eHNsOnBhcmFtIG5hbWU9InF1ZXJ5IiBzZWxlY3Q9IidTRUxFQ1QgKiBGUk9NIGltcG9ydDEnIi8+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0iZGIiIHNlbGVjdD0ic3FsOm5ldygkZHJpdmVyLCAkZGF0YXNvdXJjZSkiLz4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InRhYmxlIiBzZWxlY3Q9J3NxbDpxdWVyeSgkZGIsICRxdWVyeSknLz4KLSAgICA8eHNsOmNvcHktb2Ygc2VsZWN0PSIkdGFibGUiIC8+Ci0gICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpjbG9zZSgkZGIpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2Jhc2ljLWNvbm5lY3Rpb24vZGJpbmZvLnhtbCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9kYmluZm8ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAxOWU2NDBmLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9kYmluZm8ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTIgKzAsMCBAQAotPGRidGVzdD4KLSA8ZGVzY3JpcHRpb24+VGhpcyBmaWxlIGNvbnRhaW5zIGluZm9ybWF0aW9uIHJlcXVpcmVkIHRvIG1ha2UgYSBjb25uZWN0aW9uIHRvIHRoZSBEQk1TPC9kZXNjcmlwdGlvbj4KLQotIDxEQklORk8+Ci0gICA8ZGJkcml2ZXI+b3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyPC9kYmRyaXZlcj4KLSAgIDxkYnVybD5qZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycDwvZGJ1cmw+Ci0gICA8dXNlciAvPgotICAgPHBhc3N3b3JkLz4KLSA8L0RCSU5GTz4KLSAKLQotPC9kYnRlc3Q+CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2Jhc2ljLWNvbm5lY3Rpb24vZGJ0ZXN0LWNpbmZvLnhzbCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9kYnRlc3QtY2luZm8ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDc1NQppbmRleCBmY2RjYzdmLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9kYnRlc3QtY2luZm8ueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNjEgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICAgICAgICAgICAgICAgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgIHhtbG5zOnNxbD0ib3JnLmFwYWNoZS54YWxhbi5saWIuc3FsLlhDb25uZWN0aW9uIgotICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJzcWwiPgotCi08eHNsOm91dHB1dCBtZXRob2Q9Imh0bWwiIGluZGVudD0ieWVzIi8+Ci0KLTx4c2w6cGFyYW0gbmFtZT0iY2luZm8iIHNlbGVjdD0iLy9EQklORk8iLz4KLTx4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gaW1wb3J0MSciLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYiIgc2VsZWN0PSJzcWw6bmV3KCkiLz4KLQotICAgIDwhLS0gQ29ubmVjdCB0byB0aGUgZGF0YWJhc2Ugd2l0aCBtaW5pbWFsIGVycm9yIGRldGVjdGlvbiAtLT4KLQkJPHhzbDppZiB0ZXN0PSJub3Qoc3FsOmNvbm5lY3QoJGRiLCAkY2luZm8pKSIgPgotICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgQ29ubmVjdGluZyB0byB0aGUgRGF0YWJhc2U8L3hzbDptZXNzYWdlPgotICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgIDwveHNsOmlmPgotICAgIAotCi0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgPFRJVExFPkxpc3Qgb2YgcHJvZHVjdHM8L1RJVExFPgotICAgICAgPC9IRUFEPgotICAgICAgPEJPRFk+Ci0gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPgotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnF1ZXJ5KCRkYiwgJHF1ZXJ5KScvPgotICAgICAgICAgIAotICAgICAgICAgIDwhLS0gCi0gICAgICAgICAgCUxldCdzIGluY2x1ZGUgRXJyb3IgQ2hlY2tpbmcsIHRoZSBlcnJvciBpcyBhY3R1YWxseSBzdG9yZWQgCi0gICAgICAgICAgICBpbiB0aGUgY29ubmVjdGlvbiBzaW5jZSAkdGFibGUgd2lsbCBiZSBlaXRoZXIgZGF0YSBvciBudWxsCi0gICAgICAgICAgLS0+Ci0gICAgICAgICAgICAgCi0gICAgICAgICAgPHhzbDppZiB0ZXN0PSJub3QoJHRhYmxlKSIgPgotICAgICAgICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgaW4gUXVlcnk8L3hzbDptZXNzYWdlPgotICAgICAgICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgICAgICAgIDwveHNsOmlmPgotICAgICAgICAgIAotICAgICAgICAgIAotICAgICAgICAgIDxUUj4KLSAgICAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJHRhYmxlL3NxbC9tZXRhZGFhdGEvY29sdW1uLWhlYWRlciI+Ci0gICAgICAgICAgICAgICA8VEg+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLz48L1RIPgotICAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgIDwvVFI+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvc3FsL3Jvdy1zZXQvcm93Ii8+Ci0gICAgICAgIDwvVEFCTEU+Ci0gICAgICA8L0JPRFk+Ci0gICAgPC9IVE1MPgotICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJGRiKSIvPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InJvdyI+Ci0gIDxUUj48eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9ImNvbCIvPjwvVFI+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29sIj4KLSAgPFREPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0ZXh0KCkiLz48L1REPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9iYXNpYy1jb25uZWN0aW9uL2RidGVzdC54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2Jhc2ljLWNvbm5lY3Rpb24vZGJ0ZXN0LnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggZmUxN2ViYi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2Jhc2ljLWNvbm5lY3Rpb24vZGJ0ZXN0LnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDYxICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCIKLSAgICAgICAgICAgICAgICB4bWxuczpzcWw9Im9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvbiIKLSAgICAgICAgICAgICAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ic3FsIj4KLQotPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBpbmRlbnQ9InllcyIvPgotCi08eHNsOnBhcmFtIG5hbWU9ImRyaXZlciIgc2VsZWN0PSInb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJyIvPgotPHhzbDpwYXJhbSBuYW1lPSJkYXRhc291cmNlIiBzZWxlY3Q9IidqZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycCciLz4KLTx4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gaW1wb3J0MSciLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgCi0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYiIgc2VsZWN0PSJzcWw6bmV3KCkiLz4KLSAgICAKLSAgICA8IS0tIENvbm5lY3QgdG8gdGhlIGRhdGFiYXNlIHdpdGggbWluaW1hbCBlcnJvciBkZXRlY3Rpb24gLS0+Ci0JCTx4c2w6aWYgdGVzdD0ibm90KHNxbDpjb25uZWN0KCRkYiwgJGRyaXZlciwgJGRhdGFzb3VyY2UpKSIgPgotICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgQ29ubmVjdGluZyB0byB0aGUgRGF0YWJhc2U8L3hzbDptZXNzYWdlPgotICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgIDwveHNsOmlmPgotICAgIAotICAgIDxIVE1MPgotICAgICAgPEhFQUQ+Ci0gICAgICAgIDxUSVRMRT5MaXN0IG9mIHByb2R1Y3RzPC9USVRMRT4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotICAgICAgICA8VEFCTEUgYm9yZGVyPSIxIj4KLSAgICAgICAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InRhYmxlIiBzZWxlY3Q9J3NxbDpxdWVyeSgkZGIsICRxdWVyeSknLz4KLSAgICAgICAgICAKLSAgICAgICAgICA8IS0tIAotICAgICAgICAgIAlMZXQncyBpbmNsdWRlIEVycm9yIENoZWNraW5nLCB0aGUgZXJyb3IgaXMgYWN0dWFsbHkgc3RvcmVkIAotICAgICAgICAgICAgaW4gdGhlIGNvbm5lY3Rpb24gc2luY2UgJHRhYmxlIHdpbGwgYmUgZWl0aGVyIGRhdGEgb3IgbnVsbAotICAgICAgICAgIC0tPgotICAgICAgICAgICAgIAotICAgICAgICAgIDx4c2w6aWYgdGVzdD0ibm90KCR0YWJsZSkiID4KLSAgICAgICAgICAJPHhzbDptZXNzYWdlPkVycm9yIGluIFF1ZXJ5PC94c2w6bWVzc2FnZT4KLSAgICAgICAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4KLSAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAKLSAgICAgICAgICA8VFI+Ci0gICAgICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9IiR0YWJsZS9zcWwvbWV0YWRhdGEvY29sdW1uLWhlYWRlciI+Ci0gICAgICAgICAgICAgICA8VEg+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLz48L1RIPgotICAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgIDwvVFI+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvc3FsL3Jvdy1zZXQvcm93Ii8+Ci0gICAgICAgIDwvVEFCTEU+Ci0gICAgICA8L0JPRFk+Ci0gICAgPC9IVE1MPgotICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJGRiKSIvPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InJvdyI+Ci0gIDxUUj48eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9ImNvbCIvPjwvVFI+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29sIj4KLSAgPFREPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0ZXh0KCkiLz48L1REPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9iYXNpYy1jb25uZWN0aW9uL3JlYWRtZS5odG1sIGIvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9iYXNpYy1jb25uZWN0aW9uL3JlYWRtZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZjlkNjllLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvYmFzaWMtY29ubmVjdGlvbi9yZWFkbWUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzICswLDAgQEAKLTwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+Ci0KLTxodG1sPgotPGhlYWQ+Ci0JPHRpdGxlPlhhbGFuIFNhbXBsZXM8L3RpdGxlPgotPC9oZWFkPgotPGJvZHk+Ci08aDI+WGFsYW4gU2FtcGxlczwvaDI+Ci08cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNhbXBsZXMgKHdoYXQgdGhleSBpbGx1c3RyYXRlIGFuZCBob3cgdG8gcnVuIHRoZW0pLCBzZWUgPGEgaHJlZj0iLi4vLi4vLi4vLi4vZG9jcy9zYW1wbGVzLmh0bWwiPlNhbXBsZXM8L2E+LjwvcD4KLQotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uL0V4dGVybmFsQ29ubmVjdGlvbi5qYXZhIGIvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9leHQtY29ubmVjdGlvbi9FeHRlcm5hbENvbm5lY3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggNDdlYWM4MC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uL0V4dGVybmFsQ29ubmVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhTTFQ0SiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLS8vIEltcG9ydGVkIFRyYVggY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsLkRlZmF1bHRDb25uZWN0aW9uUG9vbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuQ29ubmVjdGlvblBvb2xNYW5hZ2VyOwotCi0KLS8vIEltcG9ydGVkIGphdmEgY2xhc3NlcwotaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0vKioKLSAqICBVc2UgdGhlIFRyYVggaW50ZXJmYWNlIHRvIHBlcmZvcm0gYSB0cmFuc2Zvcm1hdGlvbiBpbiB0aGUgc2ltcGxlc3QgbWFubmVyIHBvc3NpYmxlCi0gKiAgKDMgc3RhdGVtZW50cykuCi0gKi8KLXB1YmxpYyBjbGFzcyBFeHRlcm5hbENvbm5lY3Rpb24KLXsKLQlwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLAotICAgICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsKLQotICAvLyBDcmVhdGUgYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZSBzZXJ2ZXIKLSAgLy8gVXAgdGhlIGNvbm5lY3Rpb24gcG9vbCBjb3VudCBmb3IgdGVzdGluZwotICBEZWZhdWx0Q29ubmVjdGlvblBvb2wgY3AgPSBuZXcgRGVmYXVsdENvbm5lY3Rpb25Qb29sKCk7Ci0gIGNwLnNldERyaXZlcigib3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyIik7Ci0gIGNwLnNldFVSTCgiamRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnAiKTsKLSAgLy9jcC5zZXRVc2VyKCJzYSIpOwotICAvL2NwLnNldFBhc3N3b3JkKCIiKTsKLSAgY3Auc2V0TWluQ29ubmVjdGlvbnMoMTApOwotICBjcC5zZXRQb29sRW5hYmxlZCh0cnVlKTsKLQotICAvLyBOb3cgbGV0J3MgcmVnaXN0ZXIgb3VyIGNvbm5lY3Rpb24gcG9vbCBzbyB3ZSBjYW4gdXNlCi0gIC8vIGluIGEgc3R5bGVzaGVldAotICBDb25uZWN0aW9uUG9vbE1hbmFnZXIgcG0gPSBuZXcgQ29ubmVjdGlvblBvb2xNYW5hZ2VyKCk7Ci0gIHBtLnJlZ2lzdGVyUG9vbCgiZXh0cG9vbCIsIGNwKTsKLQotCi0gIC8vIFVzZSB0aGUgc3RhdGljIFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpIG1ldGhvZCB0byBpbnN0YW50aWF0ZQotICAvLyBhIFRyYW5zZm9ybWVyRmFjdG9yeS4gVGhlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5Ci0gIC8vIHN5c3RlbSBwcm9wZXJ0eSBzZXR0aW5nIGRldGVybWluZXMgdGhlIGFjdHVhbCBjbGFzcyB0byBpbnN0YW50aWF0ZSAtLQotICAvLyBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbC4KLQlUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotCS8vIFVzZSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IHRvIGluc3RhbnRpYXRlIGEgVHJhbnNmb3JtZXIgdGhhdCB3aWxsIHdvcmsgd2l0aAotCS8vIHRoZSBzdHlsZXNoZWV0IHlvdSBzcGVjaWZ5LiBUaGlzIG1ldGhvZCBjYWxsIGFsc28gcHJvY2Vzc2VzIHRoZSBzdHlsZXNoZWV0Ci0gIC8vIGludG8gYSBjb21waWxlZCBUZW1wbGF0ZXMgb2JqZWN0LgotCVRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdEZhY3RvcnkubmV3VHJhbnNmb3JtZXIoCi0gICAgICAgIG5ldyBTdHJlYW1Tb3VyY2UoImRidGVzdC54c2wiKSk7Ci0KLQkvLyBGb3IgdGhpcyB0cmFuc2Zvcm1hdGlvbiwgYWxsIHRoZSByZXF1aXJlZCBpbmZvcm1hdGlvbiBpcyBpbiB0aGUgc3R5bGVzaGVldCwgc28gZ2VuZXJhdGUgCi0gIC8vIGEgbWluaW1hbCBYTUwgc291cmNlIGRvY3VtZW50IGZvciB0aGUgaW5wdXQuCi0gIC8vIE5vdGU6IHRoZSBjb21tYW5kLWxpbmUgcHJvY2Vzc29yIChvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcykgdXNlcyB0aGlzIHN0cmF0ZWd5IHdoZW4gCi0gIC8vIHRoZSB1c2VyIGRvZXMgbm90IHByb3ZpZGUgYW4gLUlOIHBhcmFtZXRlci4KLSAgU3RyaW5nUmVhZGVyIHJlYWRlciA9Ci0gICAgICAgICAgICAgIG5ldyBTdHJpbmdSZWFkZXIoIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+IDxkb2MvPiIpOwotCi0gIC8vIFVzZSB0aGUgVHJhbnNmb3JtZXIgdG8gYXBwbHkgdGhlIGFzc29jaWF0ZWQgVGVtcGxhdGVzIG9iamVjdCB0byBhbiBYTUwgZG9jdW1lbnQKLQkvLyBhbmQgd3JpdGUgdGhlIG91dHB1dCB0byBhIGZpbGUuCi0JdHJhbnNmb3JtZXIudHJhbnNmb3JtKAotICAgICAgICBuZXcgU3RyZWFtU291cmNlKHJlYWRlciksCi0gICAgICAgIG5ldyBTdHJlYW1SZXN1bHQobmV3IEZpbGVPdXRwdXRTdHJlYW0oImRidGVzdC1vdXQuaHRtbCIpKSk7Ci0KLQlTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKioqKioqKiogVGhlIHJlc3VsdCBpcyBpbiBkYnRlc3Qtb3V0Lmh0bWwgKioqKioqKioqKioqKiIpOwotICAKLSAgY3Auc2V0UG9vbEVuYWJsZWQoZmFsc2UpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uL2RidGVzdC54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uL2RidGVzdC54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IGEzM2RkNTcuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9leHQtY29ubmVjdGlvbi9kYnRlc3QueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNTkgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICAgICAgICAgICAgICAgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgIHhtbG5zOnNxbD0ib3JnLmFwYWNoZS54YWxhbi5saWIuc3FsLlhDb25uZWN0aW9uIgotICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJzcWwiPgotCi08eHNsOm91dHB1dCBtZXRob2Q9Imh0bWwiIGluZGVudD0ieWVzIi8+Ci0KLTx4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gaW1wb3J0MSciLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYiIgc2VsZWN0PSJzcWw6bmV3KCkiLz4KLQotICAgIDwhLS0gQ29ubmVjdCB0byB0aGUgZGF0YWJhc2Ugd2l0aCBtaW5pbWFsIGVycm9yIGRldGVjdGlvbiAtLT4KLQkJPHhzbDppZiB0ZXN0PSJub3Qoc3FsOmNvbm5lY3QoJGRiLCAnZXh0cG9vbCcpKSIgPgotICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgQ29ubmVjdGluZyB0byB0aGUgRGF0YWJhc2U8L3hzbDptZXNzYWdlPgotICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgIDwveHNsOmlmPgotICAgIAotCi0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgPFRJVExFPkxpc3Qgb2YgcHJvZHVjdHM8L1RJVExFPgotICAgICAgPC9IRUFEPgotICAgICAgPEJPRFk+Ci0gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPgotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnF1ZXJ5KCRkYiwgJHF1ZXJ5KScvPgotICAgICAgICAgIAotICAgICAgICAgIDwhLS0gCi0gICAgICAgICAgCUxldCdzIGluY2x1ZGUgRXJyb3IgQ2hlY2tpbmcsIHRoZSBlcnJvciBpcyBhY3R1YWxseSBzdG9yZWQgCi0gICAgICAgICAgICBpbiB0aGUgY29ubmVjdGlvbiBzaW5jZSAkdGFibGUgd2lsbCBiZSBlaXRoZXIgZGF0YSBvciBudWxsCi0gICAgICAgICAgLS0+Ci0gICAgICAgICAgICAgCi0gICAgICAgICAgPHhzbDppZiB0ZXN0PSJub3QoJHRhYmxlKSIgPgotICAgICAgICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgaW4gUXVlcnk8L3hzbDptZXNzYWdlPgotICAgICAgICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgICAgICAgIDwveHNsOmlmPgotICAgICAgICAgIAotICAgICAgICAgIDxUUj4KLSAgICAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJHRhYmxlL3NxbC9tZXRhZGF0YS9jb2x1bW4taGVhZGVyIj4KLSAgICAgICAgICAgICAgIDxUSD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGNvbHVtbi1sYWJlbCIvPjwvVEg+Ci0gICAgICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgICAgPC9UUj4KLSAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IiR0YWJsZS9zcWwvcm93LXNldC9yb3ciLz4KLSAgICAgICAgPC9UQUJMRT4KLSAgICAgIDwvQk9EWT4KLSAgICA8L0hUTUw+Ci0gICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpjbG9zZSgkZGIpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icm93Ij4KLSAgPFRSPjx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iY29sIi8+PC9UUj4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJjb2wiPgotICA8VEQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPjwvVEQ+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uL3JlYWRtZS5odG1sIGIvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9leHQtY29ubmVjdGlvbi9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWY5ZDY5ZS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+WGFsYW4gU2FtcGxlczwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLTxoMj5YYWxhbiBTYW1wbGVzPC9oMj4KLTxwPkZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxlcyAod2hhdCB0aGV5IGlsbHVzdHJhdGUgYW5kIGhvdyB0byBydW4gdGhlbSksIHNlZSA8YSBocmVmPSIuLi8uLi8uLi8uLi9kb2NzL3NhbXBsZXMuaHRtbCI+U2FtcGxlczwvYT4uPC9wPgotCi0KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvcHF1ZXJ5L2RiaW5mby54bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3BxdWVyeS9kYmluZm8ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDc1NQppbmRleCBjNGJmMjQ1Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvcHF1ZXJ5L2RiaW5mby54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNCArMCwwIEBACi08WE1MU1RPUkU+Ci0KLSA8UVVFUlk+Ci0gICA8UHJvZHVjdElEPjE8L1Byb2R1Y3RJRD4KLSA8L1FVRVJZPgotICAKLSA8REJJTkZPPgotICAgPGRiZHJpdmVyPm9yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlcjwvZGJkcml2ZXI+Ci0gICA8ZGJ1cmw+amRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnA8L2RidXJsPgotICAgPHVzZXIvPgotICAgPHBhc3N3b3JkLz4KLSA8L0RCSU5GTz4KLQotPC9YTUxTVE9SRT4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvcHF1ZXJ5L2RidGVzdC54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3BxdWVyeS9kYnRlc3QueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDc1NQppbmRleCA4ODUzNGIyLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvcHF1ZXJ5L2RidGVzdC54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLQotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCIKLSAgICAgICAgICAgICAgICB4bWxuczpzcWw9Im9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvbiIKLSAgICAgICAgICAgICAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ic3FsIj4KLQotPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBpbmRlbnQ9InllcyIvPgotCi08IS0tIEJ1aWxkIGEgUGFyYW1ldGVyIFR5cGUgUXVlcnkgLS0+Ci08eHNsOnBhcmFtIG5hbWU9InExIiBzZWxlY3Q9IidTRUxFQ1QgKiBGUk9NIGltcG9ydDEgd2hlcmUgUHJvZHVjdElEID0gPyciLz4KLQotPCEtLSBCdWlsZCBhIENTViBsaXN0IG9mIHBhcmFtZXRlciB0eXBlcyAtLT4KLTx4c2w6cGFyYW0gbmFtZT0icTF0eXBlIiBzZWxlY3Q9ImludCIgLz4KLQotPCEtLSBQdWxsIG91dCBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGZyb20gdGhlIERvY3VtZW50IFNvdXJjZSAtLT4KLTx4c2w6cGFyYW0gbmFtZT0iY2luZm8iIHNlbGVjdD0iLy9EQklORk8iIC8+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0iZGIiIHNlbGVjdD0ic3FsOm5ldygpIi8+Ci0gICAgCi0gICAgPCEtLSBDb25uZWN0IHRvIHRoZSBkYXRhYmFzZSB3aXRoIG1pbmltYWwgZXJyb3IgZGV0ZWN0aW9uIC0tPgotCQk8eHNsOmlmIHRlc3Q9Im5vdChzcWw6Y29ubmVjdCgkZGIsICRjaW5mbykpIiA+Ci0gICAgCTx4c2w6bWVzc2FnZT5FcnJvciBDb25uZWN0aW5nIHRvIHRoZSBEYXRhYmFzZTwveHNsOm1lc3NhZ2U+Ci0gICAgICA8eHNsOmNvcHktb2Ygc2VsZWN0PSJzcWw6Z2V0RXJyb3IoJGRiKS9leHQtZXJyb3IiIC8+Ci0gICAgPC94c2w6aWY+Ci0gICAgCi0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgPFRJVExFPkxpc3Qgb2YgcHJvZHVjdHM8L1RJVExFPgotICAgICAgPC9IRUFEPgotICAgICAgPEJPRFk+Ci0gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPgotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0icXBhcmFtIiBzZWxlY3Q9Ii8vUVVFUlkiLz4KLSAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0ic3FsOmFkZFBhcmFtZXRlckZyb21FbGVtZW50KCRkYiwgJHFwYXJhbSkiLz4KLQotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnBxdWVyeSgkZGIsICRxMSwgJHExdHlwZSApJy8+Ci0gICAgICAgICAgCi0gICAgICAgICAgPCEtLSAKLSAgICAgICAgICAJTGV0J3MgaW5jbHVkZSBFcnJvciBDaGVja2luZywgdGhlIGVycm9yIGlzIGFjdHVhbGx5IHN0b3JlZCAKLSAgICAgICAgICAgIGluIHRoZSBjb25uZWN0aW9uIHNpbmNlICR0YWJsZSB3aWxsIGJlIGVpdGhlciBkYXRhIG9yIG51bGwKLSAgICAgICAgICAtLT4KLSAgICAgICAgICAgICAKLSAgICAgICAgICA8eHNsOmlmIHRlc3Q9Im5vdCgkdGFibGUpIiA+Ci0gICAgICAgICAgCTx4c2w6bWVzc2FnZT5FcnJvciBpbiBRdWVyeTwveHNsOm1lc3NhZ2U+Ci0gICAgICAgICAgICA8eHNsOmNvcHktb2Ygc2VsZWN0PSJzcWw6Z2V0RXJyb3IoJGRiKS9leHQtZXJyb3IiIC8+Ci0gICAgICAgICAgPC94c2w6aWY+Ci0gICAgICAgICAgCi0gICAgICAgICAgCi0gICAgICAgICAgPFRSPgotICAgICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSIkdGFibGUvc3FsL21ldGFkYXRhL2NvbHVtbi1oZWFkZXIiPgotICAgICAgICAgICAgICAgPFRIPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAY29sdW1uLWxhYmVsIi8+PC9USD4KLSAgICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICA8L1RSPgotICAgICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iJHRhYmxlL3NxbC9yb3ctc2V0L3JvdyIvPgotICAgICAgICA8L1RBQkxFPgotICAgICAgPC9CT0RZPgotICAgIDwvSFRNTD4KLSAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0ic3FsOmNsb3NlKCRkYikiLz4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJyb3ciPgotICA8VFI+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJjb2wiLz48L1RSPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9ImNvbCI+Ci0gIDxURD48eHNsOnZhbHVlLW9mIHNlbGVjdD0idGV4dCgpIi8+PC9URD4KLTwveHNsOnRlbXBsYXRlPgotCi08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9wcXVlcnkvcmVhZG1lLmh0bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3BxdWVyeS9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWY5ZDY5ZS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3BxdWVyeS9yZWFkbWUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzICswLDAgQEAKLTwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+Ci0KLTxodG1sPgotPGhlYWQ+Ci0JPHRpdGxlPlhhbGFuIFNhbXBsZXM8L3RpdGxlPgotPC9oZWFkPgotPGJvZHk+Ci08aDI+WGFsYW4gU2FtcGxlczwvaDI+Ci08cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNhbXBsZXMgKHdoYXQgdGhleSBpbGx1c3RyYXRlIGFuZCBob3cgdG8gcnVuIHRoZW0pLCBzZWUgPGEgaHJlZj0iLi4vLi4vLi4vLi4vZG9jcy9zYW1wbGVzLmh0bWwiPlNhbXBsZXM8L2E+LjwvcD4KLQotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3JlYWRtZS5odG1sIGIvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGY1OThkMC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+WGFsYW4gU2FtcGxlczwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLTxoMj5YYWxhbiBTYW1wbGVzPC9oMj4KLTxwPkZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxlcyAod2hhdCB0aGV5IGlsbHVzdHJhdGUgYW5kIGhvdyB0byBydW4gdGhlbSksIHNlZSA8YSBocmVmPSIuLi8uLi8uLi9kb2NzL3NhbXBsZXMuaHRtbCI+U2FtcGxlczwvYT4uPC9wPgotCi0KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc2hvdy1lcnJvci9kYmluZm8ueG1sIGIvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zaG93LWVycm9yL2RiaW5mby54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IGM0YmYyNDUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zaG93LWVycm9yL2RiaW5mby54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNCArMCwwIEBACi08WE1MU1RPUkU+Ci0KLSA8UVVFUlk+Ci0gICA8UHJvZHVjdElEPjE8L1Byb2R1Y3RJRD4KLSA8L1FVRVJZPgotICAKLSA8REJJTkZPPgotICAgPGRiZHJpdmVyPm9yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlcjwvZGJkcml2ZXI+Ci0gICA8ZGJ1cmw+amRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnA8L2RidXJsPgotICAgPHVzZXIvPgotICAgPHBhc3N3b3JkLz4KLSA8L0RCSU5GTz4KLQotPC9YTUxTVE9SRT4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc2hvdy1lcnJvci9pbnZhbGlkQ29ubi54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvaW52YWxpZENvbm4ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDc1NQppbmRleCBkYzhkYTI5Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc2hvdy1lcnJvci9pbnZhbGlkQ29ubi54c2wKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz48eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCIgICAgICAgICAgICAgICAgeG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJzcWwiPjx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLz48eHNsOnBhcmFtIG5hbWU9ImRyaXZlciIgc2VsZWN0PSInb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJyIvPjwhLS0gRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgICAgICAgICBXZSBhcmUgc3BlY2lmeWluZyBhIGRhdGFiYXNlIHRoYXQgZG9lcyBub3QgZXhpc3QsICAgICAgICAgICAgICAgIHdoaWNoIHdpbGwgY2F1c2UgYSBjb25uZWN0aW9uIGVycm9yRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1ItLT48eHNsOnBhcmFtIG5hbWU9ImRhdGFzb3VyY2UiIHNlbGVjdD0iJ2pkYmM6aWRiOi4uLy4uL2luc3RhbnRkYi9Eb2VzTm90RXhpc3QucHJwJyIvPjx4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gaW1wb3J0MiciLz48eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4gICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0iZGIiIHNlbGVjdD0ic3FsOm5ldygpIi8+ICAgICAgICA8IS0tIENvbm5lY3QgdG8gdGhlIGRhdGFiYXNlIHdpdGggbWluaW1hbCBlcnJvciBkZXRlY3Rpb24gLS0+CQk8eHNsOmlmIHRlc3Q9Im5vdChzcWw6Y29ubmVjdCgkZGIsICRkcml2ZXIsICRkYXRhc291cmNlKSkiID4gICAgCTx4c2w6bWVzc2FnZT5FcnJvciBDb25uZWN0aW5nIHRvIHRoZSBEYXRhYmFzZTwveHNsOm1lc3NhZ2U+ICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPiAgICA8L3hzbDppZj4gICAgICAgIDxIVE1MPiAgICAgIDxIRUFEPiAgICAgICAgPFRJVExFPkxpc3Qgb2YgcHJvZHVjdHM8L1RJVExFPiAgICAgIDwvSEVBRD4gICAgICA8Qk9EWT4gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPiAgICAgICAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InRhYmxlIiBzZWxlY3Q9J3NxbDpxdWVyeSgkZGIsICRxdWVyeSknLz4gICAgICAgICAgICAgICAgICAgIDwhLS0gICAgICAgICAgIAlMZXQncyBpbmNsdWRlIEVycm9yIENoZWNraW5nLCB0aGUgZXJyb3IgaXMgYWN0dWFsbHkgc3RvcmVkICAgICAgICAgICAgIGluIHRoZSBjb25uZWN0aW9uIHNpbmNlICR0YWJsZSB3aWxsIGJlIGVpdGhlciBkYXRhIG9yIG51bGwgICAgICAgICAgLS0+ICAgICAgICAgICAgICAgICAgICAgICA8eHNsOmlmIHRlc3Q9Im5vdCgkdGFibGUpIiA+ICAgICAgICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgaW4gUXVlcnk8L3hzbDptZXNzYWdlPiAgICAgICAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4gICAgICAgICAgPC94c2w6aWY+ICAgICAgICAgICAgICAgICAgICA8VFI+ICAgICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSIkdGFibGUvcm93LXNldC9jb2x1bW4taGVhZGVyIj4gICAgICAgICAgICAgICA8VEg+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLz48L1RIPiAgICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4gICAgICAgICAgPC9UUj4gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvcm93LXNldC9yb3ciLz4gICAgICAgIDwvVEFCTEU+ICAgICAgPC9CT0RZPiAgICA8L0hUTUw+ICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJGRiKSIvPjwveHNsOnRlbXBsYXRlPjx4c2w6dGVtcGxhdGUgbWF0Y2g9InJvdyI+ICA8VFI+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJjb2wiLz48L1RSPjwveHNsOnRlbXBsYXRlPjx4c2w6dGVtcGxhdGUgbWF0Y2g9ImNvbCI+ICA8VEQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPjwvVEQ+PC94c2w6dGVtcGxhdGU+PC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvaW52YWxpZFBRdWVyeS54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvaW52YWxpZFBRdWVyeS54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IGMxOTA1YjIuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zaG93LWVycm9yL2ludmFsaWRQUXVlcnkueHNsCisrKyAvZGV2L251bGwKQEAgLTEsNzUgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICAgICAgICAgICAgICAgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgIHhtbG5zOnNxbD0ib3JnLmFwYWNoZS54YWxhbi5saWIuc3FsLlhDb25uZWN0aW9uIgotICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJzcWwiPgotCi08eHNsOm91dHB1dCBtZXRob2Q9Imh0bWwiIGluZGVudD0ieWVzIi8+Ci0KLTx4c2w6cGFyYW0gbmFtZT0iZHJpdmVyIiBzZWxlY3Q9IidvcmcuZW5oeWRyYS5pbnN0YW50ZGIuamRiYy5pZGJEcml2ZXInIi8+Ci0KLQotPHhzbDpwYXJhbSBuYW1lPSJkYXRhc291cmNlIiBzZWxlY3Q9IidqZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycCciLz4KLQotCi08eHNsOnBhcmFtIG5hbWU9InF1ZXJ5IiBzZWxlY3Q9IidTRUxFQ1QgKiBGUk9NIGltcG9ydDEgd2hlcmUgUHJvZHVjdElEID0gPyciLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgCi0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYiIgc2VsZWN0PSJzcWw6bmV3KCkiLz4KLSAgICAKLSAgICA8IS0tIENvbm5lY3QgdG8gdGhlIGRhdGFiYXNlIHdpdGggbWluaW1hbCBlcnJvciBkZXRlY3Rpb24gLS0+Ci0JCTx4c2w6aWYgdGVzdD0ibm90KHNxbDpjb25uZWN0KCRkYiwgJGRyaXZlciwgJGRhdGFzb3VyY2UpKSIgPgotICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgQ29ubmVjdGluZyB0byB0aGUgRGF0YWJhc2U8L3hzbDptZXNzYWdlPgotICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgIDwveHNsOmlmPgotICAgIAotICAgIDxIVE1MPgotICAgICAgPEhFQUQ+Ci0gICAgICAgIDxUSVRMRT5MaXN0IG9mIHByb2R1Y3RzPC9USVRMRT4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotICAgICAgICA8VEFCTEUgYm9yZGVyPSIxIj4KLSAgICAgICAgCi08IS0tIAotRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IKLSAgIFdlIGFyZSBzcGVjaWZ5aW5nIGFuIGV4dHJhIHZhbHVlIHdoZXJlIGFyZSBxdWVyeSBvbmx5IGV4cGVjdHMgb25lCi1FUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUgotLS0+Ci0KLSAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0ic3FsOmNsZWFyUGFyYW1ldGVycygpIi8+Ci0gICAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDphZGRQYXJhbWV0ZXJXaXRoVHlwZSgkZGIsICcxJywgJ3Nob3J0JykiLz4KLSAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0ic3FsOmFkZFBhcmFtZXRlcldpdGhUeXBlKCRkYiwgJzEnLCAnc2hvcnQnKSIvPgotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnBxdWVyeSgkZGIsICRxdWVyeSknLz4KLSAgICAgICAgICAKLSAgICAgICAgICA8IS0tIAotICAgICAgICAgIAlMZXQncyBpbmNsdWRlIEVycm9yIENoZWNraW5nLCB0aGUgZXJyb3IgaXMgYWN0dWFsbHkgc3RvcmVkIAotICAgICAgICAgICAgaW4gdGhlIGNvbm5lY3Rpb24gc2luY2UgJHRhYmxlIHdpbGwgYmUgZWl0aGVyIGRhdGEgb3IgbnVsbAotICAgICAgICAgIC0tPgotICAgICAgICAgICAgIAotICAgICAgICAgIDx4c2w6aWYgdGVzdD0ibm90KCR0YWJsZSkiID4KLSAgICAgICAgICAJPHhzbDptZXNzYWdlPkVycm9yIGluIFF1ZXJ5PC94c2w6bWVzc2FnZT4KLSAgICAgICAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4KLSAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAKLSAgICAgICAgICA8VFI+Ci0gICAgICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9IiR0YWJsZS9zcWwvbWV0YWRhdGEvY29sdW1uLWhlYWRlciI+Ci0gICAgICAgICAgICAgICA8VEg+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLz48L1RIPgotICAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgIDwvVFI+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvc3FsL3Jvdy1zZXQvcm93Ii8+Ci0gICAgICAgIDwvVEFCTEU+Ci0gICAgICA8L0JPRFk+Ci0gICAgPC9IVE1MPgotICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJGRiKSIvPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InJvdyI+Ci0gIDxUUj48eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9ImNvbCIvPjwvVFI+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29sIj4KLSAgPFREPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0ZXh0KCkiLz48L1REPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zaG93LWVycm9yL2ludmFsaWRRdWVyeS54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvaW52YWxpZFF1ZXJ5LnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggOTE4MWU0MC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvaW52YWxpZFF1ZXJ5LnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDcyICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCIKLSAgICAgICAgICAgICAgICB4bWxuczpzcWw9Im9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvbiIKLSAgICAgICAgICAgICAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ic3FsIj4KLQotPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBpbmRlbnQ9InllcyIvPgotCi08eHNsOnBhcmFtIG5hbWU9ImRyaXZlciIgc2VsZWN0PSInb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJyIvPgotCi0KLTx4c2w6cGFyYW0gbmFtZT0iZGF0YXNvdXJjZSIgc2VsZWN0PSInamRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnAnIi8+Ci0KLTwhLS0gCi1FUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUiBFUlJPUgotICAgICAgICAgICAgICBXZSB3aWxsIHNwZWNpZnkgYSB0YWJsZSB0aGF0IGRvZXMgbm90IGV4aXN0Ci0gICAgICAgICAgICAgIGluIG91ciBEYXRhYmFzZSwgY2F1c2luZyB0aGUgUXVlcnkgdG8gRmFpbAotRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IgRVJST1IKLS0tPgotCi0KLTx4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gVGFibGVOb3REZWZpbmVkJyIvPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgICAKLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9ImRiIiBzZWxlY3Q9InNxbDpuZXcoKSIvPgotICAgIAotICAgIDwhLS0gQ29ubmVjdCB0byB0aGUgZGF0YWJhc2Ugd2l0aCBtaW5pbWFsIGVycm9yIGRldGVjdGlvbiAtLT4KLQkJPHhzbDppZiB0ZXN0PSJub3Qoc3FsOmNvbm5lY3QoJGRiLCAkZHJpdmVyLCAkZGF0YXNvdXJjZSkpIiA+Ci0gICAgCTx4c2w6bWVzc2FnZT5FcnJvciBDb25uZWN0aW5nIHRvIHRoZSBEYXRhYmFzZTwveHNsOm1lc3NhZ2U+Ci0gICAgICA8eHNsOmNvcHktb2Ygc2VsZWN0PSJzcWw6Z2V0RXJyb3IoJGRiKS9leHQtZXJyb3IiIC8+Ci0gICAgPC94c2w6aWY+Ci0gICAgCi0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgPFRJVExFPkxpc3Qgb2YgcHJvZHVjdHM8L1RJVExFPgotICAgICAgPC9IRUFEPgotICAgICAgPEJPRFk+Ci0gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPgotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnF1ZXJ5KCRkYiwgJHF1ZXJ5KScvPgotICAgICAgICAgIAotICAgICAgICAgIDwhLS0gCi0gICAgICAgICAgCUxldCdzIGluY2x1ZGUgRXJyb3IgQ2hlY2tpbmcsIHRoZSBlcnJvciBpcyBhY3R1YWxseSBzdG9yZWQgCi0gICAgICAgICAgICBpbiB0aGUgY29ubmVjdGlvbiBzaW5jZSAkdGFibGUgd2lsbCBiZSBlaXRoZXIgZGF0YSBvciBudWxsCi0gICAgICAgICAgLS0+Ci0gICAgICAgICAgICAgCi0gICAgICAgICAgPHhzbDppZiB0ZXN0PSJub3QoJHRhYmxlKSIgPgotICAgICAgICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgaW4gUXVlcnk8L3hzbDptZXNzYWdlPgotICAgICAgICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgICAgICAgIDwveHNsOmlmPgotICAgICAgICAgIAotICAgICAgICAgIDxUUj4KLSAgICAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJHRhYmxlL3NxbC9tZXRhZGF0YS9jb2x1bW4taGVhZGVyIj4KLSAgICAgICAgICAgICAgIDxUSD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGNvbHVtbi1sYWJlbCIvPjwvVEg+Ci0gICAgICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgICAgPC9UUj4KLSAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IiR0YWJsZS9zcWwvcm93LXNldC9yb3ciLz4KLSAgICAgICAgPC9UQUJMRT4KLSAgICAgIDwvQk9EWT4KLSAgICA8L0hUTUw+Ci0gICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpjbG9zZSgkZGIpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icm93Ij4KLSAgPFRSPjx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iY29sIi8+PC9UUj4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJjb2wiPgotICA8VEQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPjwvVEQ+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvcmVhZG1lLmh0bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3Nob3ctZXJyb3IvcmVhZG1lLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVmOWQ2OWUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zaG93LWVycm9yL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+WGFsYW4gU2FtcGxlczwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLTxoMj5YYWxhbiBTYW1wbGVzPC9oMj4KLTxwPkZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxlcyAod2hhdCB0aGV5IGlsbHVzdHJhdGUgYW5kIGhvdyB0byBydW4gdGhlbSksIHNlZSA8YSBocmVmPSIuLi8uLi8uLi8uLi9kb2NzL3NhbXBsZXMuaHRtbCI+U2FtcGxlczwvYT4uPC9wPgotCi0KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc3RyZWFtYWJsZS9jYWNoZWROb2Rlcy54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3N0cmVhbWFibGUvY2FjaGVkTm9kZXMueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmODNkZTMwLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc3RyZWFtYWJsZS9jYWNoZWROb2Rlcy54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw2MiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB2ZXJzaW9uPSIxLjAiCi0gICAgICAgICAgICAgICAgeG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InNxbCI+Ci0KLTx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLz4KLQotPHhzbDpwYXJhbSBuYW1lPSJkcml2ZXIiIHNlbGVjdD0iJ29yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlciciLz4KLTx4c2w6cGFyYW0gbmFtZT0iZGF0YXNvdXJjZSIgc2VsZWN0PSInamRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnAnIi8+Ci08eHNsOnBhcmFtIG5hbWU9InF1ZXJ5IiBzZWxlY3Q9IidTRUxFQ1QgKiBGUk9NIGltcG9ydDEnIi8+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0iZGIiIHNlbGVjdD0ic3FsOm5ldygpIi8+Ci0gICAgCi0gICAgPCEtLSBDb25uZWN0IHRvIHRoZSBkYXRhYmFzZSB3aXRoIG1pbmltYWwgZXJyb3IgZGV0ZWN0aW9uIC0tPgotCQk8eHNsOmlmIHRlc3Q9Im5vdChzcWw6Y29ubmVjdCgkZGIsICRkcml2ZXIsICRkYXRhc291cmNlKSkiID4KLSAgICAJPHhzbDptZXNzYWdlPkVycm9yIENvbm5lY3RpbmcgdG8gdGhlIERhdGFiYXNlPC94c2w6bWVzc2FnZT4KLSAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4KLSAgICA8L3hzbDppZj4KLSAgICAKLQotICAgIDxIVE1MPgotICAgICAgPEhFQUQ+Ci0gICAgICAgIDxUSVRMRT5MaXN0IG9mIHByb2R1Y3RzPC9USVRMRT4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotICAgICAgICA8VEFCTEUgYm9yZGVyPSIxIj4KLSAgICAgICAgCTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6ZGlzYWJsZVN0cmVhbWluZ01vZGUoJGRiKSIgLz4KLSAgICAgICAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InRhYmxlIiBzZWxlY3Q9J3NxbDpxdWVyeSgkZGIsICRxdWVyeSknLz4KLSAgICAgIAotICAgICAgPCEtLSAKLSAgICAgICAgCUxldCdzIGluY2x1ZGUgRXJyb3IgQ2hlY2tpbmcsIHRoZSBlcnJvciBpcyBhY3R1YWxseSBzdG9yZWQgCi0gICAgICAgICAgaW4gdGhlIGNvbm5lY3Rpb24gc2luY2UgJHRhYmxlIHdpbGwgYmUgZWl0aGVyIGRhdGEgb3IgbnVsbAotICAgICAgIC0tPgotICAgICAgICAgICAgIAotICAgICAgICAgIDx4c2w6aWYgdGVzdD0ibm90KCR0YWJsZSkiID4KLSAgICAgICAgICAJPHhzbDptZXNzYWdlPkVycm9yIGluIFF1ZXJ5PC94c2w6bWVzc2FnZT4KLSAgICAgICAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4KLSAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAKLSAgICAgICAgICA8VFI+Ci0gICAgICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9IiR0YWJsZS9yb3ctc2V0L2NvbHVtbi1oZWFkZXIiPgotICAgICAgICAgICAgICAgPFRIPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAY29sdW1uLWxhYmVsIi8+PC9USD4KLSAgICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICA8L1RSPgotICAgICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iJHRhYmxlL3Jvdy1zZXQvcm93Ii8+Ci0gICAgICAgIDwvVEFCTEU+Ci0gICAgICA8L0JPRFk+Ci0gICAgPC9IVE1MPgotICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJGRiKSIvPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InJvdyI+Ci0gIDxUUj48eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9ImNvbCIvPjwvVFI+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29sIj4KLSAgPFREPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0ZXh0KCkiLz48L1REPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zdHJlYW1hYmxlL2RiaW5mby54bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3N0cmVhbWFibGUvZGJpbmZvLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMTllNjQwZi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3N0cmVhbWFibGUvZGJpbmZvLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDEyICswLDAgQEAKLTxkYnRlc3Q+Ci0gPGRlc2NyaXB0aW9uPlRoaXMgZmlsZSBjb250YWlucyBpbmZvcm1hdGlvbiByZXF1aXJlZCB0byBtYWtlIGEgY29ubmVjdGlvbiB0byB0aGUgREJNUzwvZGVzY3JpcHRpb24+Ci0KLSA8REJJTkZPPgotICAgPGRiZHJpdmVyPm9yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlcjwvZGJkcml2ZXI+Ci0gICA8ZGJ1cmw+amRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnA8L2RidXJsPgotICAgPHVzZXIgLz4KLSAgIDxwYXNzd29yZC8+Ci0gPC9EQklORk8+Ci0gCi0KLTwvZGJ0ZXN0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zdHJlYW1hYmxlL3Bpdm90LnhzbCBiL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc3RyZWFtYWJsZS9waXZvdC54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc5NzIwOTguLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zdHJlYW1hYmxlL3Bpdm90LnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCIKLSAgICAgICAgICAgICAgICB4bWxuczpzcWw9Im9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvbiIKLSAgICAgICAgICAgICAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ic3FsIj4KLQotPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBpbmRlbnQ9InllcyIvPgotCi08eHNsOnBhcmFtIG5hbWU9ImRyaXZlciIgc2VsZWN0PSInb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJyIvPgotPHhzbDpwYXJhbSBuYW1lPSJkYXRhc291cmNlIiBzZWxlY3Q9IidqZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycCciLz4KLTx4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gaW1wb3J0MSciLz4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJkYiIgc2VsZWN0PSJzcWw6bmV3KCkiLz4KLSAgICAKLSAgICA8IS0tIENvbm5lY3QgdG8gdGhlIGRhdGFiYXNlIHdpdGggbWluaW1hbCBlcnJvciBkZXRlY3Rpb24gLS0+Ci0JCTx4c2w6aWYgdGVzdD0ibm90KHNxbDpjb25uZWN0KCRkYiwgJGRyaXZlciwgJGRhdGFzb3VyY2UpKSIgPgotICAgIAk8eHNsOm1lc3NhZ2U+RXJyb3IgQ29ubmVjdGluZyB0byB0aGUgRGF0YWJhc2U8L3hzbDptZXNzYWdlPgotICAgICAgPHhzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOmdldEVycm9yKCRkYikvZXh0LWVycm9yIiAvPgotICAgIDwveHNsOmlmPgotICAgIAotCi0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgPFRJVExFPkxpc3Qgb2YgcHJvZHVjdHM8L1RJVExFPgotICAgICAgPC9IRUFEPgotICAgICAgPEJPRFk+Ci0gICAgICAKLSAgICAgIDwhLS0gVHVybiBvZmYgU3RyZWFtaW5nIC0tPgotICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpkaXNhYmxlU3RyZWFtaW5nTW9kZSgpIiAvPgotICAgICAgCi0gICAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InRhYmxlIiBzZWxlY3Q9J3NxbDpxdWVyeSgkZGIsICRxdWVyeSknLz4KLSAgICAgIAotICAgICAgPCEtLSAKLSAgICAgICAgCUxldCdzIGluY2x1ZGUgRXJyb3IgQ2hlY2tpbmcsIHRoZSBlcnJvciBpcyBhY3R1YWxseSBzdG9yZWQgCi0gICAgICAgICAgaW4gdGhlIGNvbm5lY3Rpb24gc2luY2UgJHRhYmxlIHdpbGwgYmUgZWl0aGVyIGRhdGEgb3IgbnVsbAotICAgICAgIC0tPgotICAgICAgICAgICAgIAotICAgICAgICAgIDx4c2w6aWYgdGVzdD0ibm90KCR0YWJsZSkiID4KLSAgICAgICAgICAJPHhzbDptZXNzYWdlPkVycm9yIGluIFF1ZXJ5PC94c2w6bWVzc2FnZT4KLSAgICAgICAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4KLSAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAKLSAgICAgIAotICAgICAgCi0gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPgotICAgICAgICAgIDxUUj4KLSAgICAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJHRhYmxlL3Jvdy1zZXQvY29sdW1uLWhlYWRlciI+Ci0gICAgICAgICAgICAgICA8VEg+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLz48L1RIPgotICAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgIDwvVFI+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvcm93LXNldC9yb3ciLz4KLSAgICAgICAgPC9UQUJMRT4KLSAgICAgICAgCi0gICAgICAgIDxUQUJMRSBib3JkZXI9IjEiPgotCi0gICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSIkdGFibGUvcm93LXNldC9jb2x1bW4taGVhZGVyIj4KLSAgICAgICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJjb2x1bW4iIHNlbGVjdD0iQGNvbHVtbi1sYWJlbCIgLz4KLQotICAgICAgICAJPFRSPgotICAgICAgICAgIAk8VEQ+PFRIPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIkY29sdW1uIi8+PC9USD48L1REPgotICAgICAgICAgICAgCTx4c2w6YXBwbHktdGVtcGxhdGVzCi0gICAgICAgICAgICAgICAJc2VsZWN0PSIkdGFibGUvcm93LXNldC9yb3cvY29sW0Bjb2x1bW4tbGFiZWw9JGNvbHVtbl0iIC8+Ci0gICAgICAgICAgPC9UUj4KLSAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLQotICAgICAgICA8L1RBQkxFPgotICAgICAgIAotICAgICAgICAKLSAgICAgIDwvQk9EWT4KLSAgICA8L0hUTUw+Ci0gICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpjbG9zZSgkZGIpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icm93Ij4KLSAgPFRSPjx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iY29sIi8+PC9UUj4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJjb2wiPgotICA8VEQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPjwvVEQ+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3N0cmVhbWFibGUvcmVhZG1lLmh0bWwgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3N0cmVhbWFibGUvcmVhZG1lLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVmOWQ2OWUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9leHRlbnNpb25zL3NxbC9zdHJlYW1hYmxlL3JlYWRtZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTMgKzAsMCBAQAotPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KLQotPGh0bWw+Ci08aGVhZD4KLQk8dGl0bGU+WGFsYW4gU2FtcGxlczwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLTxoMj5YYWxhbiBTYW1wbGVzPC9oMj4KLTxwPkZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxlcyAod2hhdCB0aGV5IGlsbHVzdHJhdGUgYW5kIGhvdyB0byBydW4gdGhlbSksIHNlZSA8YSBocmVmPSIuLi8uLi8uLi8uLi9kb2NzL3NhbXBsZXMuaHRtbCI+U2FtcGxlczwvYT4uPC9wPgotCi0KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc3RyZWFtYWJsZS9zdHJlYW1Ob2Rlcy54c2wgYi9zYW1wbGVzL2V4dGVuc2lvbnMvc3FsL3N0cmVhbWFibGUvc3RyZWFtTm9kZXMueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMzdhMWFmLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvZXh0ZW5zaW9ucy9zcWwvc3RyZWFtYWJsZS9zdHJlYW1Ob2Rlcy54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw1MSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB2ZXJzaW9uPSIxLjAiCi0gICAgICAgICAgICAgICAgeG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InNxbCI+Ci0KLTx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLz4KLQotPHhzbDpwYXJhbSBuYW1lPSJkcml2ZXIiIHNlbGVjdD0iJ29yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlciciLz4KLTx4c2w6cGFyYW0gbmFtZT0iZGF0YXNvdXJjZSIgc2VsZWN0PSInamRiYzppZGI6Li4vLi4vaW5zdGFudGRiL3NhbXBsZS5wcnAnIi8+Ci08eHNsOnBhcmFtIG5hbWU9InF1ZXJ5IiBzZWxlY3Q9IidTRUxFQ1QgKiBGUk9NIGltcG9ydDEnIi8+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0iZGIiIHNlbGVjdD0ic3FsOm5ldygpIi8+Ci0gICAgCi0gICAgPCEtLSBDb25uZWN0IHRvIHRoZSBkYXRhYmFzZSB3aXRoIG1pbmltYWwgZXJyb3IgZGV0ZWN0aW9uIC0tPgotCQk8eHNsOmlmIHRlc3Q9Im5vdChzcWw6Y29ubmVjdCgkZGIsICRkcml2ZXIsICRkYXRhc291cmNlKSkiID4KLSAgICAJPHhzbDptZXNzYWdlPkVycm9yIENvbm5lY3RpbmcgdG8gdGhlIERhdGFiYXNlPC94c2w6bWVzc2FnZT4KLSAgICAgIDx4c2w6Y29weS1vZiBzZWxlY3Q9InNxbDpnZXRFcnJvcigkZGIpL2V4dC1lcnJvciIgLz4KLSAgICA8L3hzbDppZj4KLSAgICAKLQotICAgIDxIVE1MPgotICAgICAgPEhFQUQ+Ci0gICAgICAgIDxUSVRMRT5MaXN0IG9mIHByb2R1Y3RzPC9USVRMRT4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotICAgICAgICA8VEFCTEUgYm9yZGVyPSIxIj4KLSAgICAgICAgCTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6ZW5hYmxlU3RyZWFtaW5nTW9kZSgkZGIpIiAvPgotICAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnF1ZXJ5KCRkYiwgJHF1ZXJ5KScvPgotICAgICAgICAgIDxUUj4KLSAgICAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iJHRhYmxlL3Jvdy1zZXQvY29sdW1uLWhlYWRlciI+Ci0gICAgICAgICAgICAgICA8VEg+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLz48L1RIPgotICAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgIDwvVFI+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvcm93LXNldC9yb3ciLz4KLSAgICAgICAgPC9UQUJMRT4KLSAgICAgIDwvQk9EWT4KLSAgICA8L0hUTUw+Ci0gICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpjbG9zZSgkZGIpIi8+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icm93Ij4KLSAgPFRSPjx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iY29sIi8+PC9UUj4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJjb2wiPgotICA8VEQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPjwvVEQ+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xULmphdmEgYi9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xULmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMyMzVhODQuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9zZXJ2bGV0L0FwcGx5WFNMVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTYzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBzZXJ2bGV0OwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IGphdmF4LnNlcnZsZXQuKjsKLWltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuKjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLk91dHB1dFByb3BlcnRpZXM7Ci0vLyBTQVgyIEltcG9ydHMKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci4qOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MRmlsdGVySW1wbDsKLQotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKgotICogQXBwbHlYU0xUIHN1cHBsaWVzIHRoZSBiYXNpYwotICogZnVuY3Rpb25zIGZvciB0cmFuc2Zvcm1pbmcgWE1MIGRhdGEgdXNpbmcgWFNMIHN0eWxlc2hlZXRzLgotICoKLSAqIEBhdXRob3IgU3BlbmNlciBTaGVwYXJkIChzc2hlcGFyZEB1cy5pYm0uY29tKQotICogQGF1dGhvciBSLiBBZGFtIEtpbmcgKHJha0B1cy5pYm0uY29tKQotICogQGF1dGhvciBUb20gUm93ZSAodHJvd2VAdXMuaWJtLmNvbSkKLSAqIEBhdXRob3IgRG9uIExlc2xpZSAoZG9uYWxkX2xlc2xpZUBsb3R1cy5jb20pCi0gKgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi1wdWJsaWMgY2xhc3MgQXBwbHlYU0xUIGV4dGVuZHMgSHR0cFNlcnZsZXQKLXsKLQotICAvKioKLSAgICogT3BlcmF0aW9uYWwgcGFyYW1ldGVycyBmb3IgdGhpcyBjbGFzcy4KLSAgICogPHA+UmVxdWVzdC10aW1lIHZhbHVlcyBvdmVycmlkZSBpbml0LXRpbWUgdmFsdWVzIHdoaWNoIG92ZXJyaWRlIGNsYXNzIGRlZmF1bHRzLjwvcD4KLSAgICogQHNlZSAjaW5pdAotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgQXBwbHlYU0xUUHJvcGVydGllcyBvdXJEZWZhdWx0UGFyYW1ldGVycyA9IG51bGw7Ci0gIHByaXZhdGUgYm9vbGVhbiB1c2VEZWZhdWx0VGVtcGxhdGVzID0gZmFsc2U7Ci0gIHByaXZhdGUgVGVtcGxhdGVzIGRlZmF1bHRUZW1wbGF0ZXMgPSBudWxsOwotCi0gIC8qKgotICAgKiBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBlbmQgb2YgbGluZSBjaGFyYWN0ZXJzIGZvciB0aGUgU3lzdGVtLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgRU9MID0gU3lzdGVtLmdldFByb3BlcnR5KCJsaW5lLnNlcGFyYXRvciIpOwotCi0gIC8qKgotICAgKiBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBmaWxlIHNlcGFyYXRvciBjaGFyYWN0ZXJzIGZvciB0aGUgU3lzdGVtLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgRlMgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuc2VwYXJhdG9yIik7Ci0KLSAgIC8qKgotICAgKiBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBmb3IgcHJvcGVydGllcyBmaWxlcy4gU2VlIGluaXQoKS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFJPT1QgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInNlcnZlci5yb290Iik7Ci0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIENVUlJFTlRESVI7Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgb3BlcmF0aW9uYWwgcGFyYW1ldGVycyBmcm9tIHRoZSBjb25maWd1cmF0aW9uLgotICAgKiBAcGFyYW0gY29uZmlnIENvbmZpZ3VyYXRpb24KLSAgICogQGV4Y2VwdGlvbiBTZXJ2bGV0RXhjZXB0aW9uIE5ldmVyIHRocm93bgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5pdChTZXJ2bGV0Q29uZmlnIGNvbmZpZykKLSAgICB0aHJvd3MgU2VydmxldEV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuaW5pdChjb25maWcpOwotICAgIC8vIElmIHRoZSBzZXJ2ZXIucm9vdCBwcm9wZXJ0eSAtLXNlZSBhYm92ZS0tIGlzIG51bGwsIHVzZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5Ci0gICAgLy8gYXMgZGVmYXVsdCBsb2NhdGlvbiBmb3IgbWVkaWEucHJvcGVydGllcy4KLSAgICBpZiAoUk9PVCAhPSBudWxsKQotICAgICAgQ1VSUkVOVERJUj0gUk9PVCArIEZTICsgInNlcnZsZXRzIiArIEZTOwotICAgIGVsc2UKLSAgICAgIENVUlJFTlRESVIgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuZGlyIikrIEZTOwotICAgIAotCSAgc2V0RGVmYXVsdFBhcmFtZXRlcnMoY29uZmlnKTsKLQkKLSAgICBzZXRNZWRpYVByb3BzKGNvbmZpZy5nZXRJbml0UGFyYW1ldGVyKCJtZWRpYVVSTCIpKTsKLSAgICBTdHJpbmcgZGVmYXVsdFhTTCA9IGNvbmZpZy5nZXRJbml0UGFyYW1ldGVyKCJ4c2xVUkwiKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgaWYgKGRlZmF1bHRYU0wgIT1udWxsICYmIGRlZmF1bHRYU0wubGVuZ3RoKCkgPiAwKQotICAgICAgY29tcGlsZVhTTChkZWZhdWx0WFNMKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKXt9Ci0gIH0KLSAgCi0gLyoqCi0gICogSWYgYSBkZWZhdWx0IHNldHRpbmcgZXhpc3RzIGZvciB4c2xVUkwsIGNyZWF0ZSBhIFRlbXBsYXRlcyBvYmplY3QKLSAgKiBmb3IgcmFwaWQgdHJhbnNmb3JtYXRpb25zLgotICAqLyAKLSAgcHJvdGVjdGVkIHZvaWQgY29tcGlsZVhTTChTdHJpbmcgZGVmYXVsdFhTTCkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBkZWZhdWx0VGVtcGxhdGVzID0gdEZhY3RvcnkubmV3VGVtcGxhdGVzKG5ldyBTdHJlYW1Tb3VyY2UoZGVmYXVsdFhTTCkpOwotICAgIHVzZURlZmF1bHRUZW1wbGF0ZXMgPSB0cnVlOwotICB9Ci0gIAotIC8qKgotICAgKiBTZXRzIHRoZSBkZWZhdWx0IHBhcmFtZXRlcnMgZm9yIHRoZSBzZXJ2bGV0IGZyb20gdGhlIGNvbmZpZ3VyYXRpb24uCi0gICAqIEFsc28gc2V0cyByZXF1aXJlZCBzeXN0ZW0gcHJvcGVydGllcyB1bnRpbCB3ZSBmaWd1cmUgb3V0IHdoeSBzZXJ2bGV0IAotICAgKiBzb21ldGltZXNzIGZhaWxzIHRvIHJlYWQgcHJvcGVydGllcyBmcm9tIHByb3BlcnRpZXMgZmlsZXMuCi0gICAqIEBwYXJhbSBjb25maWcgQ29uZmlndXJhdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgc2V0RGVmYXVsdFBhcmFtZXRlcnMoU2VydmxldENvbmZpZyBjb25maWcpCi0gIHsKLSAgICBvdXJEZWZhdWx0UGFyYW1ldGVycyA9IG5ldyBEZWZhdWx0QXBwbHlYU0xUUHJvcGVydGllcyhjb25maWcpOwotICB9Ci0gIAotICAvKioKLSAgICoJTG9hZHMgdGhlIG1lZGlhIHByb3BlcnRpZXMgZmlsZSBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuIHN0cmluZy4KLSAgICogQHBhcmFtIG1lZGlhVVJMc3RyaW5nIExvY2F0aW9uIG9mIHRoZSBtZWRpYSBwcm9wZXJ0aWVzIGZpbGUuICBDYW4gYmUgZWl0aGVyIGEgZnVsbCBVUkwgb3IgYSBwYXRoIHJlbGF0aXZlCi0gICAqIHRvIHRoZSBTeXN0ZW0ncyBzZXJ2ZXIucm9vdCAvc2VydmxldHMgZGlyZWN0b3J5LiAgSWYgdGhpcyBwYXJhbWV0ZXIgaXMgbnVsbCwKLSAgICogc2VydmVyLnJvb3Qvc2VydmxldHMvbWVkaWEucHJvcGVydGllcyB3aWxsIGJlIHVzZWQuCi0gICAqIEBzZWUgQXBwbHlYU0wjQ1VSUkVOVERJUgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgc2V0TWVkaWFQcm9wcyhTdHJpbmcgbWVkaWFVUkxzdHJpbmcpCi0gIHsKLSAgICBpZiAobWVkaWFVUkxzdHJpbmcgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBVUkwgdXJsID0gbnVsbDsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICB1cmwgPSBuZXcgVVJMKG1lZGlhVVJMc3RyaW5nKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlMSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICB1cmwgPSBuZXcgVVJMKCJmaWxlIiwgIiIsIENVUlJFTlRESVIgKyBtZWRpYVVSTHN0cmluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUyKQotICAgICAgICB7Ci0gICAgICAgICAgd3JpdGVMb2coIlVuYWJsZSB0byBmaW5kIHRoZSBtZWRpYSBwcm9wZXJ0aWVzIGZpbGUgYmFzZWQgb24gcGFyYW1ldGVyICdtZWRpYVVSTCcgPSAiCi0gICAgICAgICAgICAgICAgICAgKyBtZWRpYVVSTHN0cmluZywgSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19BQ0NFUFRFRCwgbXVlMik7Ci0gICAgICAgICAgdXJsID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgaWYgKHVybCAhPSBudWxsKQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIG91ck1lZGlhUHJvcHMgPSBuZXcgT3JkZXJlZFByb3BzKHVybC5vcGVuU3RyZWFtKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UxKQotICAgICAgICB7Ci0gICAgICAgICAgd3JpdGVMb2coIkV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSBvcGVuaW5nIG1lZGlhIHByb3BlcnRpZXMgZmlsZTogIiArIG1lZGlhVVJMc3RyaW5nICsKLSAgICAgICAgICAgICAgICAgICAiLiAgTWVkaWEgdGFibGUgbWF5IGJlIGludmFsaWQuIiwgSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19BQ0NFUFRFRCwgaW9lMSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIFN0cmluZyBkZWZhdWx0UHJvcCA9IENVUlJFTlRESVIgKyAibWVkaWEucHJvcGVydGllcyI7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgb3VyTWVkaWFQcm9wcyA9IG5ldyBPcmRlcmVkUHJvcHMobmV3IEZpbGVJbnB1dFN0cmVhbShkZWZhdWx0UHJvcCkpOwotICAgICAgfQotICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZTIpCi0gICAgICB7Ci0gICAgICAgIHdyaXRlTG9nKCJEZWZhdWx0IG1lZGlhIHByb3BlcnRpZXMgZmlsZSAiICsgZGVmYXVsdFByb3AgKyAiIG5vdCBmb3VuZC4iLAotICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlLlNDX0FDQ0VQVEVELCBpb2UyKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICBwdWJsaWMgU3RyaW5nIGdldE1lZGlhKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0KQotICB7Ci0gICAgcmV0dXJuIG91ck1lZGlhUHJvcHMuZ2V0VmFsdWUocmVxdWVzdC5nZXRIZWFkZXIoSEVBREVSX05BTUUpKTsKLSAgfQotICAKLSAgLy8gZG9Qb3N0IHJlbW92ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMgZHVlIHRvIHRoZSBwb3NzaWJpbGl0eSBvZiBzZW5kaW5nCi0gIC8vIHVuc2VjdXJlIFhNTCBhbmQgWFNMIFhTTFRJbnB1dFNvdXJjZXMgdGhyb3VnaCB0aGUgcmVxdWVzdCBpbnB1dCBzdHJlYW0KLQotICAvKioKLSAgICogSFRUUCBHZXQgbWV0aG9kIHBhc3NlZCBvbiB0byBwcm9jZXNzKCkuCi0gICAqIEBwYXJhbSByZXF1ZXN0IFRoZSByZXF1ZXN0Ci0gICAqIEBwYXJhbSByZXNwb25zZSBUaGUgcmVzcG9uc2UKLSAgICogQHNlZSAjcHJvY2VzcwotICAgKiBAZXhjZXB0aW9uIFNlcnZsZXRFeGNlcHRpb24gTmV2ZXIgdGhyb3duCi0gICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gTmV2ZXIgdGhyb3duCi0gICAqLwotICBwdWJsaWMgdm9pZCBkb0dldCAoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsCi0gICAgICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQotICAgIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewkKLSAgICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgcHJvY2Vzcyh0RmFjdG9yeSwgcmVxdWVzdCwgcmVzcG9uc2UpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIENvb3JkaW5hdGVzIGFwcGx5aW5nIGFuIFhTTCBzdHlsZXNoZWV0IHRvIFhNTCBkYXRhIHVzaW5nIG9wZXJhdGlvbmFsIHBhcmFtZXRlcnMuCi0gICAqIDxwPklmIHN1Y2Nlc3NmdWxseSBhcHBsaWVkLCB0aGUgcmVzdWx0IHRyZWUgd2lsbCBiZSBzdHJlYW1lZCB0byB0aGUgcmVzcG9uc2Ugb2JqZWN0Ci0gICAqIGFuZCB0aGUgY29udGVudCB0eXBlIHNldCBhY2NvcmRpbmcgdG8gdGhlIFhTTCBzdHlsZXNoZWV0J3MgJmx0O3hzbDpvdXRwdXQ+IGVsZW1lbnQocykuPC9wPgotICAgKiA8cD5JZiB0aGVyZSBpcyBhIHByb2JsZW0gaW4gcGFyc2luZyB0aGUgWE1ML1hTTCBvciBpZiB0aGVyZSBpcyBhIHByb2JsZW0gaW4gYXBwbHlpbmcKLSAgICogdGhlIFhTTCB0byB0aGUgWE1MLCBhbiBleGNlcHRpb24gd2lsbCBiZSBzdHJlYW1lZCB0byB0aGUgcmVzcG9uc2Ugb2JqZWN0LiAgVGhlIGRldGFpbAotICAgKiBvZiB0aGUgaW5mb3JtYXRpb24gcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlIG9iamVjdCB3aWxsIGRlcGVuZCBvbiB3aGV0aGVyIHdlJ3JlCi0gICAqIHJ1bm5pbmcgaW4gZGVidWcgbW9kZSBvciBub3QuPC9wPgotICAgKiBAcGFyYW0gcHJvY2Vzc29yIGltcGxlbWVudGF0aW9uIG9mIFRSYVggcHJvY2Vzc29yCi0gICAqIEBwYXJhbSByZXF1ZXN0ICBNYXkgY29udGFpbiBpbmZvcm1hdGlvbiByZWxldmFudCB0byBjcmVhdGluZyBYTUwgYW5kIFhTTCBYU0xUSW5wdXRTb3VyY2UncwotICAgKiBAcGFyYW0gcmVzcG9uc2UgV2hlcmUgdG8gd3JpdGUgdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdAotICAgKiBAc2VlICNnZXREb2N1bWVudAotICAgKiBAc2VlICNnZXRTdHlsZXNoZWV0Ci0gICAqIEBzZWUgI2dldENvbnRlbnRUeXBlCi0gICAqIEBzZWUgI2Rpc3BsYXlFeGNlcHRpb24KLSAgICogQHNlZSAjc2V0U3R5bGVzaGVldFBhcmFtcwotICAgKiBAZXhjZXB0aW9uIFNlcnZsZXRFeGNlcHRpb24gTmV2ZXIgdGhyb3duCi0gICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gTmV2ZXIgdGhyb3duCi0gICAqLwotICAKLSAgcHVibGljIHZvaWQgcHJvY2VzcyhUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnksIAotCQkgICAgICAgICAgCQkJICBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKLSAgICAgICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQotICAgIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBib29sZWFuIGRlYnVnID0gb3VyRGVmYXVsdFBhcmFtZXRlcnMuaXNEZWJ1ZyhyZXF1ZXN0KTsKLQotICAgIGxvbmcgdGltZSA9IDA7Ci0gICAgaWYgKGRlYnVnKQotICAgICAgdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCi0gICAgLy8gTGlzdGVuZXIgdG8gYmUgdXNlZCBmb3IgYWxsIHJlcG9ydGluZwotICAgIEFwcGx5WFNMVExpc3RlbmVyIGxpc3RlbmVyID0gbmV3IEFwcGx5WFNMVExpc3RlbmVyKCk7Ci0JICBsaXN0ZW5lci5vdXQucHJpbnRsbigiZGVidWcgaXMgIiArIGRlYnVnKTsKLQotICAgIFNvdXJjZSB4bWxTb3VyY2UgPSBudWxsOwotCSAgU291cmNlIHhzbFNvdXJjZSA9IG51bGw7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKCh4bWxTb3VyY2UgPSBnZXREb2N1bWVudChyZXF1ZXN0LCBsaXN0ZW5lcikpID09IG51bGwpCi0gICAgICAgIHRocm93IG5ldyBBcHBseVhTTFRFeGNlcHRpb24oImdldERvY3VtZW50KCkgcmV0dXJuZWQgbnVsbCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuU0NfTk9UX0ZPVU5EKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEFwcGx5WFNMVEV4Y2VwdGlvbiBheGUpCi0gICAgewotICAgICAgYXhlLmFwcGVuZE1lc3NhZ2UoRU9MICsgImdldERvY3VtZW50KCkgcmVzdWx0ZWQgaW4gQXBwbHlYU0xURXhjZXB0aW9uIiArIEVPTAotICAgICAgICAgICAgICAgICAgICAgICAgKyBsaXN0ZW5lci5nZXRNZXNzYWdlKCkpOwotICAgICAgaWYgKGRlYnVnKSB3cml0ZUxvZyhheGUpOwotICAgICAgZGlzcGxheUV4Y2VwdGlvbihyZXNwb25zZSwgYXhlLCBkZWJ1Zyk7Ci0gICAgICB4bWxTb3VyY2UgPSBudWxsOwotICAgIH0KLSAgICAvLyBjcmVhdGluZyBYU0wgU3R5bGVzaGVldAotICAgIGlmICh4bWxTb3VyY2UgIT0gbnVsbCkKLQkgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBpZiAoKHhzbFNvdXJjZSA9IGdldFN0eWxlc2hlZXQodEZhY3RvcnksIHJlcXVlc3QsIHhtbFNvdXJjZSwgbGlzdGVuZXIpKSA9PSBudWxsKQotICAgICAgICAgIHRocm93IG5ldyBBcHBseVhTTFRFeGNlcHRpb24oImdldFN0eWxlc2hlZXQoKSByZXR1cm5lZCBudWxsIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLlNDX05PVF9GT1VORCk7Ci0gCi0gICAgICAgIC8vIE11c3QgInJlc2V0IiB4bWxTb3VyY2UgKGEgU3RyZWFtU291cmNlKSBhZnRlciBsb29raW5nIGZvciBzdHlsZXNoZWV0IFBJCi0JCSAgICB4bWxTb3VyY2UgPSBnZXREb2N1bWVudChyZXF1ZXN0LCBsaXN0ZW5lcik7IAotICAgICAgfQotICAgICAgY2F0Y2ggKEFwcGx5WFNMVEV4Y2VwdGlvbiBheGUpCi0gICAgICB7Ci0gICAgICAgIGF4ZS5hcHBlbmRNZXNzYWdlKEVPTCArICJnZXRTdHlsZXNoZWV0KCkgcmVzdWx0ZWQgaW4gQXBwbHlYU0xURXhjZXB0aW9uIiArIEVPTAotICAgICAgICAgICAgICAgICAgICAgICAgICArIGxpc3RlbmVyLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIGlmIChkZWJ1Zykgd3JpdGVMb2coYXhlKTsKLSAgICAgICAgZGlzcGxheUV4Y2VwdGlvbihyZXNwb25zZSwgYXhlLCBkZWJ1Zyk7Ci0gICAgICAgIHhzbFNvdXJjZSA9IG51bGw7Ci0gICAgICB9Ci0gICAgLy8gcGVyZm9ybSBUcmFuc2Zvcm1hdGlvbgotCSAgCi0gICAgaWYgKHVzZURlZmF1bHRUZW1wbGF0ZXMpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGxpc3RlbmVyLm91dC5wcmludGxuKCJVc2luZyBkZWZhdWx0IHRlbXBsYXRlcyIpOwotICAgICAgICBpZiAoZGVmYXVsdFRlbXBsYXRlcyA9PSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgbGlzdGVuZXIub3V0LnByaW50bG4oIk11c3QgcmVjb21waWxlIGRlZmF1bHQgdGVtcGxhdGVzIik7Ci0gICAgICAgICAgZGVmYXVsdFRlbXBsYXRlcyA9IHRGYWN0b3J5Lm5ld1RlbXBsYXRlcyh4c2xTb3VyY2UpOwotICAgICAgICB9Ci0gICAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gZGVmYXVsdFRlbXBsYXRlcy5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgICAgICAgU3RyaW5nIGNvbnRlbnRUeXBlID0gbnVsbDsKLQkJCSAgICAgIGNvbnRlbnRUeXBlID0gZ2V0Q29udGVudFR5cGUoZGVmYXVsdFRlbXBsYXRlcyk7Ci0gICAgICAgICAgICBpZiAoY29udGVudFR5cGUgIT0gbnVsbCk7Ci0gICAgICAgICAgICAgIHJlc3BvbnNlLnNldENvbnRlbnRUeXBlKGNvbnRlbnRUeXBlKTsKLQotCQkJICAgICAgaWYgKHRyYW5zZm9ybWVyIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJJbXBsKQotCQkJICAgICAgewotCQkJICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXJJbXBsID0gKFRyYW5zZm9ybWVySW1wbCl0cmFuc2Zvcm1lcjsKLSAgICAgICAgICAgICAgdHJhbnNmb3JtZXJJbXBsLnNldFF1aWV0Q29uZmxpY3RXYXJuaW5ncyhvdXJEZWZhdWx0UGFyYW1ldGVycy5pc05vQ1cocmVxdWVzdCkpOwotCQkJICAgICAgfQotCQkJCi0JCQkgICAgICBzZXRTdHlsZXNoZWV0UGFyYW1zKHRyYW5zZm9ybWVyLCByZXF1ZXN0KTsJCQkKLQkgICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHhtbFNvdXJjZSwgbmV3IFN0cmVhbVJlc3VsdChyZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKSkpOwotCQkJCi0JCQkgICAgICBpZiAoZGVidWcpICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgd3JpdGVMb2cobGlzdGVuZXIuZ2V0TWVzc2FnZSgpLCByZXNwb25zZS5TQ19PSyk7Ci0gICAgICAgIAotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleGMpCi0gICAgICB7Ci0gICAgICAgIEFwcGx5WFNMVEV4Y2VwdGlvbiBheGUgPSBuZXcgQXBwbHlYU0xURXhjZXB0aW9uCi0JCQkJICAgICAgICAgICgiRXhjZXB0aW9uIG9jY3VycmVkIGR1cmluZyBUcmFuc2Zvcm1hdGlvbjoiCi0gICAgICAgICAgICAgICAgICAgICsgRU9MICsgbGlzdGVuZXIuZ2V0TWVzc2FnZSgpICsgRU9MCi0gICAgICAgICAgICAgICAgICAgICsgZXhjLmdldE1lc3NhZ2UoKSwgCi0JCQkJCSAgICAgICAgICBleGMsCi0gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLlNDX0lOVEVSTkFMX1NFUlZFUl9FUlJPUik7Ci0gICAgICAgIGlmIChkZWJ1Zykgd3JpdGVMb2coYXhlKTsKLSAgICAgICAgICBkaXNwbGF5RXhjZXB0aW9uKHJlc3BvbnNlLCBheGUsIGRlYnVnKTsgICAgICAKLSAgICAgICB9Ci0gICAgIH0gICAKLSAgICAgIAotICAgICBlbHNlIGlmICgoeG1sU291cmNlICE9IG51bGwpICYmICh4c2xTb3VyY2UgIT0gbnVsbCkpCi0gICAgIHsKLQkgICAgIHRyeQotCSAgICAgewotICAgICAgICAgbGlzdGVuZXIub3V0LnByaW50bG4oIlBlcmZvcm1pbmcgdHJhbnNmb3JtYXRpb24uLi4iKTsJCQotICAgICAgICAgVGVtcGxhdGVzIHRlbXBsYXRlcyA9IHRGYWN0b3J5Lm5ld1RlbXBsYXRlcyh4c2xTb3VyY2UpOwotICAgICAgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAKLSAgICAgICAgIHRyeQotICAgICAgICAgewotICAgICAgICAgICBTdHJpbmcgY29udGVudFR5cGUgPSBudWxsOwotCQkJICAgICBjb250ZW50VHlwZSA9IGdldENvbnRlbnRUeXBlKHRlbXBsYXRlcyk7Ci0gICAgICAgICAgIGlmIChjb250ZW50VHlwZSAhPSBudWxsKTsKLSAgICAgICAgICAgICByZXNwb25zZS5zZXRDb250ZW50VHlwZShjb250ZW50VHlwZSk7Ci0KLQkJCSAgICAgaWYgKHRyYW5zZm9ybWVyIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJJbXBsKQotCQkJICAgICB7Ci0JCQkgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVySW1wbCA9IChUcmFuc2Zvcm1lckltcGwpdHJhbnNmb3JtZXI7Ci0gICAgICAgICAgICAgdHJhbnNmb3JtZXJJbXBsLnNldFF1aWV0Q29uZmxpY3RXYXJuaW5ncyhvdXJEZWZhdWx0UGFyYW1ldGVycy5pc05vQ1cocmVxdWVzdCkpOwotCQkJICAgICB9Ci0JCQkKLQkJCSAgICAgc2V0U3R5bGVzaGVldFBhcmFtcyh0cmFuc2Zvcm1lciwgcmVxdWVzdCk7CQkJCi0JICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHhtbFNvdXJjZSwgbmV3IFN0cmVhbVJlc3VsdChyZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKSkpOwotCQkJCi0JCQkgICAgIGlmIChkZWJ1ZykgICAgICAgICAgICAgIAotICAgICAgICAgICAgIHdyaXRlTG9nKGxpc3RlbmVyLmdldE1lc3NhZ2UoKSwgcmVzcG9uc2UuU0NfT0spOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4YykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBBcHBseVhTTFRFeGNlcHRpb24gYXhlID0gbmV3IEFwcGx5WFNMVEV4Y2VwdGlvbgotCQkJCSAgICAgICAgICAgICAgICAgICAgICgiRXhjZXB0aW9uIG9jY3VycmVkIGR1cmluZyBUcmFuc2Zvcm1hdGlvbjoiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEVPTCArIGxpc3RlbmVyLmdldE1lc3NhZ2UoKSArIEVPTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBleGMuZ2V0TWVzc2FnZSgpLCAKLQkJCQkJCQkJCSAgICAgICAgICAgICAgZXhjLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5TQ19JTlRFUk5BTF9TRVJWRVJfRVJST1IpOwotICAgICAgICAgICAgaWYgKGRlYnVnKSB3cml0ZUxvZyhheGUpOwotICAgICAgICAgICAgZGlzcGxheUV4Y2VwdGlvbihyZXNwb25zZSwgYXhlLCBkZWJ1Zyk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyB0cmFuc2Zvcm1lci5yZXNldCgpOwotICAgICAgICAgIH0gLy8gZW5kIG9mIHRyeSAuLi4gY2F0Y2ggLi4uIGZpbmFsbHkKLQkJICAgIH0KLSAgICAgICAgY2F0Y2ggKC8qb3JnLnhtbC5zYXguU0FYKi9FeGNlcHRpb24gc2F4RXhjKQotICAgICAgICB7Ci0gICAgICAgICAgQXBwbHlYU0xURXhjZXB0aW9uIGF4ZSA9IG5ldyBBcHBseVhTTFRFeGNlcHRpb24KLQkJCSAgICAgICAgICAgICAgICAgICAgICgiRXhjZXB0aW9uIG9jY3VycmVkIGR1cmluZyBjdG9yL1RyYW5zZm9ybWF0aW9uOiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBFT0wgKyBsaXN0ZW5lci5nZXRNZXNzYWdlKCkgKyBFT0wKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzYXhFeGMuZ2V0TWVzc2FnZSgpLCAKLQkJCSAgICAgICAgICAgICAJCQkJCSBzYXhFeGMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLlNDX0lOVEVSTkFMX1NFUlZFUl9FUlJPUik7Ci0gICAgICAgICAgaWYgKGRlYnVnKSB3cml0ZUxvZyhheGUpOwotICAgICAgICAgIGRpc3BsYXlFeGNlcHRpb24ocmVzcG9uc2UsIGF4ZSwgZGVidWcpOwotICAgICAgICB9IC8vIGVuZCBvZiBuZXcgdHJ5IC4uLiBjYXRjaAotICAgICAgfSAvLyBlbmQgb2YgaWYoKHN0eWxlc2hlZXRSb290ICE9IG51bGwpIC4uLgotICAgICAgaWYgKGRlYnVnKQotICAgICAgewotICAgICAgICB0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSB0aW1lOwotICAgICAgICB3cml0ZUxvZygiICBObyBDb25mbGljdCBXYXJuaW5ncyA9ICIgKyBvdXJEZWZhdWx0UGFyYW1ldGVycy5pc05vQ1cocmVxdWVzdCkgKwotICAgICAgICAgICAgICAgICAiICBUcmFuc2Zvcm1hdGlvbiB0aW1lOiAiICsgdGltZSArICIgbXMiLCByZXNwb25zZS5TQ19PSyk7Ci0gICAgICB9Ci0gICAgfQotICB9ICAKLQotICAvKioKLSAgICogUmV0dXJucyBhIFNvdXJjZSBvYmplY3Qgd2l0aCB0aGUgWE1MIGRvY3VtZW50IHRvIGJlIHRyYW5zZm9ybWVkLiBBdHRlbXB0cyB3aWxsIGJlIG1ha2UgdG8gY3JlYXRlIHRoZSAKLSAgICogU291cmNlIG9iamVjdCBmcm9tIHRoZSBmb2xsb3dpbmc6Ci0gICAqIDxvbD4KLSAgICogPGxpPkEgcmVsYXRpdmUgVVJMIHNwZWNpZmllZCBpbiB0aGUgSFRUUCByZXF1ZXN0J3MgcGF0aCBpbmZvcm1hdGlvbi4gVGhpcyBjYXBhYmlsaXR5IGlzIGludGVuZGVkCi0gICAqIGZvciB1c2UgYnkgPGI+c2VydmxldCBlbmdpbmVzIHRoYXQgbWFwPC9iPiBzb21lIG9yIGFsbCBYTUwgZGF0YSB0byBiZSBwcm9jZXNzZWQgYXQgdGhlIHNlcnZlci48L2xpPgotICAgKiA8bGk+QSBVUkwgc3BlY2lmaWVkIGluIHRoZSBIVFRQIHJlcXVlc3QncyA8Y29kZT5VUkw9PC9jb2RlPiBwYXJhbWV0ZXIuICBUaGlzIGNhcGFiaWxpdHkKLSAgICogaXMgaW50ZW5kZWQgZm9yIDxiPmNsaWVudHMgd2lzaGluZyB0byBzZWxlY3RpdmVseSBwcm9jZXNzPC9iPiBYTUwgZGF0YSBhdCB0aGUgc2VydmVyLiAgRm9yCi0gICAqIHNlY3VyaXR5IHJlYXNvbnMsIHRoaXMgVVJMIHdpbGwgYmUgZm9yY2VkIHRvIHRoZSBsb2NhbCBJUCBob3N0LjwvbGk+Ci0gICAqIDxsaT5UaGUgSFRUUCByZXF1ZXN0J3MgWE1MIGlucHV0IHN0cmVhbS4gVGhpcyBjYXBhYmlsaXR5IGlzIGludGVuZGVkIGZvciB1c2UgYnkgY2hhaW5lZCBzZXJ2bGV0cy48L2xpPgotICAgKiA8L29sPgotICAgKiBAcGFyYW0gcmVxdWVzdCBjbGllbnQgSFRUUFJlcXVlc3Qgb2JqZWN0Ci0gICAqIEBwYXJhbSBsaXN0ZW5lciBUbyByZWNvcmQgZGV0YWlsZWQgcGFyc2luZyBtZXNzYWdlcyBmb3IgcG9zc2libGUgcmV0dXJuIHRvIHJlcXVlc3RvcgotICAgKiBAcmV0dXJuIFNvdXJjZSB3aXRoIFhNTCBkb2N1bWVudCB0byBiZSB0cmFuc2Zvcm1lZCwgb3IgbnVsbCBpZiB0aGUgU291cmNlIGNvdWxkIG5vdCBiZSBsb2NhdGVkCi0gICAqIEBleGNlcHRpb24gQXBwbHlYU0xURXhjZXB0aW9uIFRocm93biBpZiBleGNlcHRpb24gb2NjdXJzIHdoaWxlIGhhbmRsaW5nIHJlcXVlc3QKLSAgICovCi0gIHByb3RlY3RlZCBTb3VyY2UgZ2V0RG9jdW1lbnQoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBwbHlYU0xUTGlzdGVuZXIgbGlzdGVuZXIpCi0gICAgdGhyb3dzIEFwcGx5WFNMVEV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIHhtbFVSTCA9IG51bGw7Ci0gICAgICAvLyBkb2N1bWVudCBmcm9tIFBhdGhJbmZvCi0gICAgICBpZiAoKHhtbFVSTCA9IHJlcXVlc3QuZ2V0UGF0aEluZm8oKSkgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgbGlzdGVuZXIub3V0LnByaW50bG4oIlBhcnNpbmcgWE1MIERvY3VtZW50IGZyb20gUGF0aEluZm86ICIgKyB4bWxVUkwpOwotICAgICAgICByZXR1cm4gbmV3IFN0cmVhbVNvdXJjZShuZXcgVVJMKCJodHRwIiwgKChEZWZhdWx0QXBwbHlYU0xUUHJvcGVydGllcykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3VyRGVmYXVsdFBhcmFtZXRlcnMpLmdldExvY2FsSG9zdCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxVUkwucmVwbGFjZSgnXFwnLCAnLycpKS5vcGVuU3RyZWFtKCkpOwkJCi0gICAgICB9Ci0gICAgICAvLyBkb2N1bWVudCBmcm9tIFJlcXVlc3QgcGFyYW1ldGVyCi0gICAgICBpZiAoKHhtbFVSTCA9IG91ckRlZmF1bHRQYXJhbWV0ZXJzLmdldFhNTHVybChyZXF1ZXN0KSkgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgbGlzdGVuZXIub3V0LnByaW50bG4oIlBhcnNpbmcgWE1MIERvY3VtZW50IGZyb20gcmVxdWVzdCBwYXJhbWV0ZXI6ICIgKyB4bWxVUkwpOwotICAgICAgICByZXR1cm4gbmV3IFN0cmVhbVNvdXJjZShuZXcgVVJMKHhtbFVSTCkub3BlblN0cmVhbSgpKTsKLSAgICAgIH0KLSAgICAgIC8vIGRvY3VtZW50IGZyb20gY2hhaW4KLSAgICAgIFN0cmluZyBjb250ZW50VHlwZSA9IHJlcXVlc3QuZ2V0Q29udGVudFR5cGUoKTsKLSAgICAgIGlmICgoY29udGVudFR5cGUgIT0gbnVsbCkgJiYgY29udGVudFR5cGUuc3RhcnRzV2l0aCgidGV4dC94bWwiKSkKLSAgICAgIHsKLSAgICAgICAgbGlzdGVuZXIub3V0LnByaW50bG4oIlBhcnNpbmcgWE1MIERvY3VtZW50IGZyb20gcmVxdWVzdCBjaGFpbiIpOwotICAgICAgICByZXR1cm4gbmV3IFN0cmVhbVNvdXJjZShyZXF1ZXN0LmdldElucHV0U3RyZWFtKCkpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBBcHBseVhTTFRFeGNlcHRpb24oaW9lLCBIdHRwU2VydmxldFJlc3BvbnNlLlNDX05PVF9GT1VORCk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgQXBwbHlYU0xURXhjZXB0aW9uKGUsIEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfSU5URVJOQUxfU0VSVkVSX0VSUk9SKTsKLSAgICB9Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIFNvdXJjZSBvYmplY3QgY29udGFpbmluZyB0aGUgc3R5bGVzaGVldC4gIEF0dGVtcHRzIHdpbGwgYmUgbWFrZSB0byBvYnRhaW4gdGhlIHN0eWxlc2hlZXQgCi0gICAqIGZyb20gdGhlIGZvbGxvd2luZyBzb3VyY2VzOgotICAgKiA8b2w+Ci0gICAqIDxsaT5BIFVSTCBzcGVjaWZpZWQgaW4gdGhlIEhUVFAgcmVxdWVzdCdzIDxjb2RlPnhzbFVSTD08L2NvZGU+IHBhcmFtZXRlci4gRm9yIHNlY3VyaXR5IHJlYXNvbnMsIAotICAgKiB0aGlzIFVSTCB3aWxsIGJlIGZvcmNlZCB0byB0aGUgbG9jYWwgSVAgaG9zdC48L2xpPgotICAgKiA8bGk+QSBVUkwgc3BlY2lmaWVkIGluIHRoZSBYTUwgZG9jdW1lbnQgeHNsOnN0eWxlc2hlZXQgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbi4gIFhNTCBkb2N1bWVudHMgbWF5IGNvbnRhaW4gCi0gICAqIFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb24gcmVmZXJlbmNlcyB0byBvbmUgb3IgbW9yZSBzdHlsZXNoZWV0cyB1c2luZyB0aGUKLSAgICogPGEgSFJFRj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXN0eWxlc2hlZXQvPkFzc29jaWF0aW5nIFN0eWxlIFNoZWV0cyB3aXRoIFhNTCBkb2N1bWVudHM8L2E+IAotICAgKiBXM0MgZWNvbW1lbmRhdGlvbi4KLSAgICogSWYgdGhlIFhNTCBkb2N1bWVudCBkb2VzIGNvbnRhaW4gc3VjaCByZWZlcmVuY2VzLCBhIGJlc3QgbWF0Y2ggd2lsbCBiZSBjaG9zZW4gYmFzZWQgb24gdGhlIGJyb3dzZXIKLSAgICogdHlwZSBtYWtpbmcgdGhlIHJlcXVlc3QgYW5kIHRoZSBkZWZhdWx0IGFzc29jaWF0aW9uLiAgVGhpcyBjYXBhYmlsaXR5IGVuYWJsZXMgcmVsYXRpb25zaGlwcyB0byBiZQotICAgKiBkZWZpbmVkIGJldHdlZW4gY2xpZW50IGNhcGFiaWxpdGllcyBhbmQgc3R5bGVzaGVldHMgY2FwYWJsZSBvZiBhY3Rpbmcgb24gdGhlc2UgY2FwYWJpbGl0aWVzLjwvbGk+Ci0gICAqIDxsaT5BIGRlZmF1bHQgc3R5bGVzaGVldCBVUkwgc3BlY2lmaWVkIHdoZW4gdGhlIHNlcnZsZXQgaXMgbG9hZGVkLiBEdXJpbmcgaW5pdCgpLCB0aGUgc2VydmxldAotICAgKiB1c2VzIHRoaXMgeHNsVVJMIHN0YXJ0dXAgcGFyYW1ldGVyIHRvIGNyZWF0ZSBhIFRlbXBsYXRlcyBvYmplY3QsIHdoaWNoIGlzIHRoZSB1c2VkIGZvciB0cmFuc2Zvcm1hdGlvbnMKLSAgICogd2hlcmUgbm8gb3RoZXIgc3R5bGVzaGVldCBpcyBkZXNpZ25hdGVkLjwvbGk+Ci0gICAqIDwvb2w+Ci0gICAqIEBwYXJhbSByZXF1ZXN0IHRoZSBjbGllbnQgSFRUUCByZXF1ZXN0LCB3aGljaCBtYXkgaW5jbHVkZSBhbiB4c2xVUkwgcGFyYW1ldGVyCi0gICAqIEBwYXJhbSB4bWxTb3VyY2UgIHRoZSBYTUwgZG9jdW1lbnQgdG8gYmUgdHJhbnNmb3JtZWQKLSAgICogQHBhcmFtIGxpc3RlbmVyIFRvIHJlY29yZCBkZXRhaWxlZCBwYXJzaW5nIG1lc3NhZ2VzIGZvciBwb3NzaWJsZSByZXR1cm4gdG8gcmVxdWVzdG9yCi0gICAqIEByZXR1cm4gU291cmNlLCBvciBudWxsIGlmIHRoZSBzdHlsZXNoZWV0IGNvdWxkIG5vdCBiZSBsb2NhdGVkLgotICAgKiBAc2VlICNnZXRNZWRpYQotICAgKiBAc2VlICNTVFlMRVNIRUVUX0FUVFJJQlVURQotICAgKiBAc2VlICN0b0FjY2VwdExhbmd1YWdlQ29ubmVjdGlvbgotICAgKiBAZXhjZXB0aW9uIEFwcGx5WFNMVEV4Y2VwdGlvbiBUaHJvd24gaWYgZXhjZXB0aW9uIG9jY3VycyB3aGlsZSBsb2NhdGluZyB0aGUgc3R5bGVzaGVldAotICAgKi8KLSAgcHJvdGVjdGVkIFNvdXJjZSBnZXRTdHlsZXNoZWV0KFRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSwKLQkJCQkgICAJICAgICAgICAJICAJCQkgICBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvdXJjZSB4bWxTb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcHBseVhTTFRMaXN0ZW5lciBsaXN0ZW5lcikKLSAgICB0aHJvd3MgQXBwbHlYU0xURXhjZXB0aW9uCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAvL3N0eWxlc2hlZXQgVVJMIGZyb20gcmVxdWVzdAotICAgICAgU3RyaW5nIHhzbFVSTCA9ICgoRGVmYXVsdEFwcGx5WFNMVFByb3BlcnRpZXMpIG91ckRlZmF1bHRQYXJhbWV0ZXJzKS5nZXRYU0xSZXF1ZXN0VVJMKHJlcXVlc3QpOwotCi0gICAgICBpZiAoeHNsVVJMICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGxpc3RlbmVyLm91dC5wcmludGxuKCJQYXJzaW5nIFhTTCBTdHlsZXNoZWV0IERvY3VtZW50IGZyb20gcmVxdWVzdCBwYXJhbWV0ZXI6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB4c2xVUkwpOwotICAgICAgICB1c2VEZWZhdWx0VGVtcGxhdGVzID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgICBlbHNlIAotICAgICAgewotICAgICAgICAvLyBmaW5kIHN0eWxlc2hlZXQgZnJvbSBYTUwgRG9jdW1lbnQsIE1lZGlhIHRhZyBwcmVmZXJlbmNlCi0gICAgICAgIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBzdGYgPSAoU0FYVHJhbnNmb3JtZXJGYWN0b3J5KXRGYWN0b3J5OwotICAgICAgICBTb3VyY2Ugc3R5bGVTb3VyY2UgPQotICAgICAgICAgICAgICAgc3RmLmdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KHhtbFNvdXJjZSxnZXRNZWRpYShyZXF1ZXN0KSwgbnVsbCwgbnVsbCk7Ci0gICAgICAgIGlmIChzdHlsZVNvdXJjZSAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgbGlzdGVuZXIub3V0LnByaW50bG4oIlBhcnNpbmcgWFNMIFN0eWxlc2hlZXQgZnJvbSBYTUwgZG9jdW1lbnQgc3R5bGVzaGVldCBQSS4iKTsKLSAgICAgICAgICB1c2VEZWZhdWx0VGVtcGxhdGVzID0gZmFsc2U7Ci0gICAgICAgICAgcmV0dXJuIHN0eWxlU291cmNlOwotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgICAvLyBDb25maWd1cmF0aW9uIERlZmF1bHQKLSAgICAgICAgaWYgKCh4c2xVUkwgPSBvdXJEZWZhdWx0UGFyYW1ldGVycy5nZXRYU0x1cmwobnVsbCkpICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICBsaXN0ZW5lci5vdXQucHJpbnRsbigiUGFyc2luZyBYU0wgU3R5bGVzaGVldCBEb2N1bWVudCBmcm9tIGNvbmZpZ3VyYXRpb246ICIgKyB4c2xVUkwpOwotICAgICAgICAgIHVzZURlZmF1bHRUZW1wbGF0ZXMgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICByZXR1cm4gbmV3IFN0cmVhbVNvdXJjZSh4c2xVUkwpOwotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBBcHBseVhTTFRFeGNlcHRpb24oaW9lLCBIdHRwU2VydmxldFJlc3BvbnNlLlNDX05PVF9GT1VORCk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgQXBwbHlYU0xURXhjZXB0aW9uKGUsIEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfSU5URVJOQUxfU0VSVkVSX0VSUk9SKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgcmVzcG9uc2UgY29udGVudCB0eXBlIHNwZWNpZmllZCBieSB0aGUgbWVkaWEtdHlwZSBhbmQgZW5jb2RpbmcgYXR0cmlidXRlcyBvZgotICAgKiB0aGUgJmx0O3hzbDpvdXRwdXQ+IGVsZW1lbnQocykgb2YgdGhlIHN0eWxlc2hlZXQuCi0gICAqIERlZmF1bHQgb3V0cHV0IHByb3BlcnR5IHNldHRpbmdzIGFyZSB1c2VkIGZvciBhbnkgcHJvcGVydGllcyBub3Qgc2V0IGJ5IHRoZSBzdHlsZXNoZWV0LiAKLSAgICogQHBhcmFtIHhzbFNvdXJjZVJvb3QgWFNMIFN0eWxlc2hlZXQgdG8gYmUgZXhhbWluZWQgZm9yICZsdDt4c2w6b3V0cHV0PiBlbGVtZW50cy4KLSAgICogQHJldHVybiBUaGUgcmVzcG9uc2UgY29udGVudCB0eXBlIChNSU1FIHR5cGUgYW5kIGNoYXJzZXQpIG9mIHRoZSBzdHlsZXNoZWV0IG91dHB1dAotICAgKiBAc2VlICNwcm9jZXNzCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKFRlbXBsYXRlcyB0ZW1wbGF0ZXMpCi0gIHsKLSAgICBQcm9wZXJ0aWVzIG9wcm9wcyA9IHRlbXBsYXRlcy5nZXRPdXRwdXRQcm9wZXJ0aWVzKCk7Ci0gICAgU3RyaW5nIG1ldGhvZCA9IG9wcm9wcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLk1FVEhPRCk7Ci0gICAgaWYgKG1ldGhvZCA9PSBudWxsKSBtZXRob2QgPSAieG1sIjsgLy8gdGhlIGRlZmF1bHQuCi0gICAgCi0gICAgUHJvcGVydGllcyBkZWZvcHJvcHMgPSBudWxsOwotICAgIGlmIChtZXRob2QuZXF1YWxzKCJodG1sIikpCi0gICAgICBkZWZvcHJvcHMgPSBPdXRwdXRQcm9wZXJ0aWVzLmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKCJodG1sIik7Ci0gICAgZWxzZSBpZiAobWV0aG9kLmVxdWFscygidGV4dCIpKQotICAgICAgZGVmb3Byb3BzID0gT3V0cHV0UHJvcGVydGllcy5nZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcygidGV4dCIpOwotICAgIGVsc2UKLSAgICAgIGRlZm9wcm9wcyA9IE91dHB1dFByb3BlcnRpZXMuZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMoInhtbCIpOwotICAgIAotICAgIFN0cmluZyBlbmNvZGluZyA9IG9wcm9wcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HKTsKLSAgICBpZiAoZW5jb2RpbmcgPT0gbnVsbCkgCi0gICAgICBlbmNvZGluZyA9IGRlZm9wcm9wcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HKTsKLSAgICAKLSAgICBTdHJpbmcgbWVkaWEgPSBvcHJvcHMuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRURJQV9UWVBFKTsKLSAgICBpZiAobWVkaWEgPT0gbnVsbCkgCi0gICAgICBtZWRpYSA9IGRlZm9wcm9wcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLk1FRElBX1RZUEUpOwotICAgIAotICAgIHJldHVybiBtZWRpYSArICI7IGNoYXJzZXQ9IiArIGVuY29kaW5nOwotICB9ICAKLSAgCi0KLSAgLyoqCi0gICAqIERlZmluZXMgYW5kIHNldHMgc2VsZWN0IHRvcC1sZXZlbCBYU0wgc3R5bGVzaGVldCB2YXJpYWJsZXMgZnJvbSB0aGUgSFRUUCByZXF1ZXN0LCB3aGljaAotICAgKiBjYW4gYmUgZXZhbHVhdGVkIHVzaW5nICZsdDt4c2w6cGFyYW0tdmFyaWFibGUmZ3Q7LiAgVGhlIGZvbGxvd2luZyB2YXJpYWJsZXMgd2lsbCBiZQotICAgKiBhdXRvbWF0aWNhbGx5IHNldDoKLSAgICogPGRsPgotICAgKiA8ZHQ+PGk+UGFyYW1ldGVyTmFtZTwvaT48L2R0PgotICAgKiA8ZGQ+RWFjaCBub24tcmVzZXJ2ZWQgcmVxdWVzdCBwYXJhbWV0ZXIgcmV0dXJuZWQgZnJvbSByZXF1ZXN0LmdldFBhcmFtZXRlck5hbWVzKCkuICBJZiBhCi0gICAqICAgICBwYXJhbWV0ZXIgY29udGFpbnMgbW9yZSB0aGFuIGEgc2luZ2xlIHZhbHVlLCBvbmx5IHRoZSBmaXJzdCB2YWx1ZSBpcyBhdmFpbGFibGUuPC9kZD4KLSAgICogPGR0PnNlcnZsZXQtUmVtb3RlQWRkcjwvZHQ+Ci0gICAqIDxkZD5Db250YWlucyBTdHJpbmcgb3V0cHV0IGZyb20gcmVxdWVzdC5nZXRSZW1vdGVBZGRyKCksIHdoaWNoIGlzIHRoZSBJUCBhZGRyZXNzCi0gICAqICAgICBvZiB0aGUgY2xpZW50IG1hY2hpbmUuPC9kZD4KLSAgICogPGR0PnNlcnZsZXQtUmVtb3RlSG9zdDwvZHQ+Ci0gICAqIDxkZD5Db250YWlucyBTdHJpbmcgb3V0cHV0IGZyb20gcmVxdWVzdC5nZXRSZW1vdGVIb3N0KCksIHdoaWNoIGlzIHRoZSBob3N0IG5hbWUKLSAgICogICAgIG9mIHRoZSBjbGllbnQgbWFjaGluZS48L2RkPgotICAgKiA8ZHQ+c2VydmxldC1SZW1vdGVVc2VyPC9kdD4KLSAgICogPGRkPkNvbnRhaW5zIFN0cmluZyBvdXRwdXQgZnJvbSByZXF1ZXN0LmdldFJlbW90ZVVzZXIoKSwgd2hpY2ggd2FzIHRoZSB1c2VyIG5hbWUKLSAgICogICAgIGFjY2VwdGVkIGJ5IHRoZSBzZXJ2ZXIgdG8gZ3JhbnQgYWNjZXNzIHRvIHRoaXMgc2VydmxldC48L2RkPgotICAgKiA8ZHQ+c2VydmxldC1SZXF1ZXN0PC9kdD4KLSAgICogPGRkPkNvbnRhaW5zIHRoZSByZXF1ZXN0IG9iamVjdC48L2RkPgotICAgKiA8L2RsPgotICAgKiBAcGFyYW0geHNscHJvY2Vzc29yIFdoZXJlIHRvIHJlZ2lzdGVyIHBhcmFtZXRlcnMgdG8gYmUgc2V0Ci0gICAqIEBwYXJhbSByZXF1ZXN0IFByb3ZpZGVzIGFjY2VzcyB0byBhbGwgbWVhbmluZ2Z1bCBwYXJhbWV0ZXJzIHRvIHNldAotICAgKiBAc2VlICNwcm9jZXNzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0UGFyYW1zKFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyLCBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgewotICAgIEVudW1lcmF0aW9uIHBhcmFtTmFtZXMgPSByZXF1ZXN0LmdldFBhcmFtZXRlck5hbWVzKCk7Ci0gICAgd2hpbGUgKHBhcmFtTmFtZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIHBhcmFtTmFtZSA9IChTdHJpbmcpIHBhcmFtTmFtZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBTdHJpbmdbXSBwYXJhbVZhbHMgPSByZXF1ZXN0LmdldFBhcmFtZXRlclZhbHVlcyhwYXJhbU5hbWUpOwotICAgICAgICBpZiAocGFyYW1WYWxzICE9IG51bGwpCi0gICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIocGFyYW1OYW1lLCBuZXcgWFN0cmluZyhwYXJhbVZhbHNbMF0pKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICB9Ci0gICAgfQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLnNldFBhcmFtZXRlcigic2VydmxldC1SZW1vdGVBZGRyIiwgbmV3IFhTdHJpbmcocmVxdWVzdC5nZXRSZW1vdGVBZGRyKCkpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgfQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLnNldFBhcmFtZXRlcigic2VydmxldC1SZW1vdGVIb3N0IiwgbmV3IFhTdHJpbmcocmVxdWVzdC5nZXRSZW1vdGVIb3N0KCkpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgfQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLnNldFBhcmFtZXRlcigic2VydmxldC1SZW1vdGVVc2VyIiwgbmV3IFhTdHJpbmcocmVxdWVzdC5nZXRSZW1vdGVVc2VyKCkpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogV3JpdGVzIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb24gdG8gdGhlIHNlcnZsZXQgbG9nOgotICAgKiA8b2w+Ci0gICAqIDxsaT5IVFRQIHN0YXR1cyBjb2RlPC9saT4KLSAgICogPGxpPk1lc3NhZ2U8L2xpPgotICAgKiA8bGk+U3RhY2sgdHJhY2U8L2xpPgotICAgKiA8L29sPgotICAgKiBAcGFyYW0gYXhlIENvbnRhaW5zIHZhbGlkIEhUVFAgc3RhdHVzIGNvZGUsIG1lc3NhZ2UsIGFuZCBzdGFjayB0cmFjZSAob3B0aW9uYWwpCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUxvZyhBcHBseVhTTFRFeGNlcHRpb24gYXhlKQotICB7Ci0gICAgd3JpdGVMb2coYXhlLmdldE1lc3NhZ2UoKSwgYXhlLmdldFN0YXR1c0NvZGUoKSwgYXhlLmdldEV4Y2VwdGlvbigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZXMgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbiB0byB0aGUgc2VydmxldCBsb2c6Ci0gICAqIDxvbD4KLSAgICogPGxpPkhUVFAgc3RhdHVzIGNvZGU8L2xpPgotICAgKiA8bGk+TWVzc2FnZTwvbGk+Ci0gICAqIDxsaT5TdGFjayB0cmFjZTwvbGk+Ci0gICAqIDwvb2w+Ci0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSB0byBiZSBsb2dnZWQKLSAgICogQHBhcmFtIHN0YXR1c0NvZGUgVmFsaWQgc3RhdHVzIGNvZGUgZnJvbSBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZQotICAgKiBAcGFyYW0gdCBVc2VkIHRvIGdlbmVyYXRlIHN0YWNrIHRyYWNlIChtYXkgYmUgPW51bGwgdG8gc3VwcHJlc3Mgc3RhY2sgdHJhY2UpCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCB3cml0ZUxvZyhTdHJpbmcgbXNnLCBpbnQgc3RhdHVzQ29kZSwgVGhyb3dhYmxlIHQpCi0gIHsKLSAgICBpZiAodCA9PSBudWxsKQotICAgICAgd3JpdGVMb2cobXNnLCBzdGF0dXNDb2RlKTsKLSAgICBlbHNlCi0gICAgewotICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwotICAgICAgUHJpbnRXcml0ZXIgd3JpdGVyID0gbmV3IFByaW50V3JpdGVyKGJ5dGVzLCB0cnVlKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhjZXB0aW9uIGlzICIgKyB0LmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKLSAgICAgIHQucHJpbnRTdGFja1RyYWNlKHdyaXRlcik7Ci0gICAgICBsb2coIkhUVFAgU3RhdHVzIENvZGU6ICIgKyBzdGF0dXNDb2RlICsgIiAtICIgKyBtc2cgKyBFT0wgKyBieXRlcy50b1N0cmluZygpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGVzIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb24gdG8gdGhlIHNlcnZsZXQgbG9nOgotICAgKiA8b2w+Ci0gICAqIDxsaT5IVFRQIHN0YXR1cyBjb2RlPC9saT4KLSAgICogPGxpPk1lc3NhZ2U8L2xpPgotICAgKiA8L29sPgotICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgdG8gYmUgbG9nZ2VkCi0gICAqIEBwYXJhbSBzdGF0dXNDb2RlIFZhbGlkIHN0YXR1cyBjb2RlIGZyb20gamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVzcG9uc2UKLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHdyaXRlTG9nKFN0cmluZyBtc2csIGludCBzdGF0dXNDb2RlKQotICB7Ci0gICAgbG9nKCJIVFRQIFN0YXR1cyBDb2RlOiAiICsgc3RhdHVzQ29kZSArICIgLSAiICsgbXNnKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnZva2VzIHJlc3BvbnNlLnNlbmRFcnJvciBzZXR0aW5nIGFuIEhUVFAgc3RhdHVzIGNvZGUgYW5kIG9wdGlvbmFsbHkgYW4gZXJyb3IgbWVzc2FnZQotICAgKiBhcyBhbiBIVE1MIHBhZ2UuCi0gICAqIDxwPklmIHJ1bm5pbmcgaW4gZGVidWcgbW9kZSwgYWxzbyB0cnkgdG8gcmV0dXJuIGEgc3RhY2sgdHJhY2Ugb2YgdGhlIGV4Y2VwdGlvbiBhbmQKLSAgICogYW5kIHhtbC94c2wgcHJvY2Vzc29yIG1lc3NhZ2VzLjwvcD4KLSAgICogQHBhcmFtIHJlc3BvbnNlIFdoZXJlIHRvIHN0cmVhbSB0aGUgZXhjZXB0aW9uIHRvCi0gICAqIEBwYXJhbSB4c2UgVGhlIHdyYXBwZXIgd2hpY2ggY29udGFpbnMgdGhlIGV4Y2VwdGlvbiBhbmQgaXRzIEhUVFAgc3RhdHVzIGNvZGUKLSAgICogQHBhcmFtIGRlYnVnIEluZGljYXRlcyB3aGV0aGVyIHRvIGluY2x1ZGUgc3RhY2sgdHJhY2UsIGV0Yy4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGRpc3BsYXlFeGNlcHRpb24oSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSwgQXBwbHlYU0xURXhjZXB0aW9uIHhzZSwgYm9vbGVhbiBkZWJ1ZykKLSAgewotICAgIFN0cmluZyBtZXNnID0geHNlLmdldE1lc3NhZ2UoKTsKLSAgICBpZiAobWVzZyA9PSBudWxsKQotICAgICAgbWVzZyA9ICIiOwotICAgIGVsc2UgbWVzZyA9ICI8Qj4iICsgbWVzZyArICI8L0I+IjsKLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihtZXNnLCBFT0wpOwotICAgIFN0cmluZ0J1ZmZlciBzdHJCdWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICBzdHJCdWYuYXBwZW5kKHRva2Vucy5uZXh0VG9rZW4oKSArIEVPTCArICI8QlI+Iik7Ci0gICAgbWVzZyA9IHN0ckJ1Zi50b1N0cmluZygpOwotICAgIGlmIChkZWJ1ZykKLSAgICB7Ci0gICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7Ci0gICAgICBQcmludFdyaXRlciB3cml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIoYnl0ZXMsIHRydWUpOwotICAgICAgeHNlLmdldEV4Y2VwdGlvbigpLnByaW50U3RhY2tUcmFjZSh3cml0ZXIpOwotICAgICAgbWVzZyArPSAiIDxQUkU+ICIgKyBieXRlcy50b1N0cmluZygpICsgIiA8L1BSRT4gIjsKLSAgICB9Ci0gICAgcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbCIpOwotICAgIHRyeQotICAgIHsKLSAgICAgIHJlc3BvbnNlLnNlbmRFcnJvcih4c2UuZ2V0U3RhdHVzQ29kZSgpLCBtZXNnKTsKLSAgICB9Ci0gICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIklPRXhjZXB0aW9uIGlzIG9jY3VycmluZyB3aGVuIHNlbmRFcnJvciBpcyBjYWxsZWQiKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTWFwcGluZyBvZiBIVFRQIHJlcXVlc3QncyB1c2VyLUFnZW50IHZhbHVlcyB0byBzdHlsZXNoZWV0IG1lZGlhPSB2YWx1ZXMuCi0gICAqIDxwPlRoaXMgbWFwcGluZyBpcyBkZWZpbmVkIGJ5IGEgZmlsZSBwb2ludGVkIHRvIGJ5IHRoZSBvcGVyYXRpb25hbCBwYXJhbWV0ZXIgIm1lZGlhVVJMIiB3aGljaCBjYW4KLSAgICogIGVpdGhlciBjb250YWluIGEgZnVsbCBVUkwgb3IgYSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBTeXN0ZW0ncyBzZXJ2ZXIucm9vdCAvc2VydmxldHMgZGlyZWN0b3J5LjwvcD4KLSAgICogQHNlZSAjc2V0TWVkaWFQcm9wcwotICAgKiBAc2VlICNnZXRNZWRpYQotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgT3JkZXJlZFByb3BzIG91ck1lZGlhUHJvcHMgPSBudWxsOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgY29ubmVjdGlvbiB3aGljaCByZXNwZWN0cyB0aGUgQWNjZXB0LUxhbmd1YWdlIGhlYWRlciBvZiB0aGUgSFRUUCByZXF1ZXN0LiAgVGhpcwotICAgKiBpcyB1c2VmdWwgd2hlbiBYU0wgZmlsZXMgYXJlIGludGVybmF0aW9uYWxpemVkIGZvciB1c2Ugd2l0aCBXZWIgc2VydmVycyB3aGljaCByZXNwZWN0IHRoaXMKLSAgICogaGVhZGVyLgotICAgKiA8cD5Gb3IgZXhhbXBsZSwgQXBhY2hlIDEuMy42IG1heSBiZSBjb25maWd1cmVkIGZvciBtdWx0aXZpZXdzLiAgVW5kZXIgdGhpcyBjb25maWd1cmF0aW9uLAotICAgKiByZXF1ZXN0cyBmb3IgaHR0cDovL215aG9zdC9pbmRleC5odG1sIHdvdWxkIHJldHVybiBodHRwOi8vbXlob3N0L2luZGV4Lmh0bWwuZnIgdG8gRnJlbmNoIGJyb3dzZXJzCi0gICAqIGFuZCBodHRwOi8vbXlob3N0L2luZGV4Lmh0bWwuZW4gdG8gRW5nbGlzaCBicm93c2Vycy48L3A+Ci0gICAqIEBwYXJhbSB1cmwgTG9jYXRpb24gdG8gY29ubmVjdCB0bwotICAgKiBAcGFyYW0gcmVxdWVzdCBDb3VsZCBjb250YWluIGFuIEFjY2VwdC1MYW5ndWFnZSBoZWFkZXIKLSAgICogQHJldHVybiBBbiBBY2NlcHQtTGFuZ3VhZ2UtZW5hYmxlZCBVUkwgY29ubmVjdGlvbgotICAgKiBAc2VlICNnZXRTdHlsZXNoZWV0Ci0gICAqLwotICBwcm90ZWN0ZWQgVVJMQ29ubmVjdGlvbiB0b0FjY2VwdExhbmd1YWdlQ29ubmVjdGlvbihVUkwgdXJsLCBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgICB0aHJvd3MgRXhjZXB0aW9uCi0gIHsKLSAgICBVUkxDb25uZWN0aW9uIHRlbXBDb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7Ci0gICAgdGVtcENvbm5lY3Rpb24uc2V0UmVxdWVzdFByb3BlcnR5KCJBY2NlcHQtTGFuZ3VhZ2UiLCByZXF1ZXN0LmdldEhlYWRlcigiQWNjZXB0LUxhbmd1YWdlIikpOwotICAgIHJldHVybiB0ZW1wQ29ubmVjdGlvbjsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIFhTTCBzdHlsZXNoZWV0IFVSTCBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBYTUwgZG9jdW1lbnQuICBJZiBtdWx0aXBsZSBYU0wKLSAgICogc3R5bGVzaGVldHMgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgWE1MIGRvY3VtZW50LCBwcmVmZXJlbmNlIHdpbGwgYmUgZ2l2ZW4gdG8gdGhlIHN0eWxlc2hlZXQKLSAgICogd2hpY2ggY29udGFpbnMgYW4gYXR0cmlidXRlIG5hbWUvdmFsdWUgcGFpciB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlTmFtZQotICAgKiBhbmQgYXR0cmlidXRlVmFsdWUuCi0gICAqIEBwYXJhbSB4bWxTb3VyY2UgWE1MIFhTTFRJbnB1dFNvdXJjZSB0byBiZSBzZWFyY2hlZCBmb3IgYXNzb2NpYXRlZCBYU0wgc3R5bGVzaGVldHMKLSAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgIEF0dHJpYnV0ZSBuYW1lIHRvIHByb3ZpZGUgcHJlZmVyZW50aWFsIG1hdGNoaW5nCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVWYWx1ZSBBdHRyaWJ1dGUgdmFsdWUgdG8gcHJvdmlkZSBwcmVmZXJlbnRpYWwgbWF0Y2hpbmcKLSAgICogQHJldHVybiBUaGUgcHJlZmVycmVkIFhTTCBzdHlsZXNoZWV0IFVSTCwgb3IgbnVsbCBpZiBubyBYU0wgc3R5bGVzaGVldCBhc3NvY2lhdGlvbiBpcyBmb3VuZAotICAgKiBAc2VlICNnZXRTdHlsZXNoZWV0Ci0gICAqLwotLyogIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFhTTFVSTGZyb21Eb2MoU3RyZWFtU291cmNlIHhtbFNvdXJjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXR0cmlidXRlVmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5KQotICB7Ci0gICAgU3RyaW5nIHRlbXBVUkwgPSBudWxsLCByZXR1cm5VUkwgPSBudWxsOwotICAgIHRyeQotICAgIHsKLQkgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICBEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgTm9kZSBzb3VyY2VUcmVlID0gZG9jQnVpbGRlci5wYXJzZSh4bWxTb3VyY2UuZ2V0SW5wdXRTdHJlYW0oKSk7Ci0gICAgICBmb3IoTm9kZSBjaGlsZD1zb3VyY2VUcmVlLmdldEZpcnN0Q2hpbGQoKTsgbnVsbCAhPSBjaGlsZDsgY2hpbGQ9Y2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkKLSAgICAgIHsKLSAgICAgICAgaWYoTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgPT0gY2hpbGQuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgICAgewotICAgICAgICAgIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaSA9IChQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pY2hpbGQ7Ci0gICAgICAgICAgaWYocGkuZ2V0Tm9kZU5hbWUoKS5lcXVhbHMoInhtbC1zdHlsZXNoZWV0IikpCi0gICAgICAgICAgewotICAgICAgICAgICAgUElBIHBpYSA9IG5ldyBQSUEocGkpOwotICAgICAgICAgICAgaWYoInRleHQveHNsIi5lcXVhbHMocGlhLmdldEF0dHJpYnV0ZSgidHlwZSIpKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdGVtcFVSTCA9IHBpYS5nZXRBdHRyaWJ1dGUoImhyZWYiKTsKLSAgICAgICAgICAgICAgU3RyaW5nIGF0dHJpYnV0ZSA9IHBpYS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSk7Ci0gICAgICAgICAgICAgIGlmICgoYXR0cmlidXRlICE9IG51bGwpICYmIChhdHRyaWJ1dGUuaW5kZXhPZihhdHRyaWJ1dGVWYWx1ZSkgPiAtMSkpCi0gICAgICAgICAgICAgICAgcmV0dXJuIHRlbXBVUkw7Ci0gICAgICAgICAgICAgIGlmICghInllcyIuZXF1YWxzKHBpYS5nZXRBdHRyaWJ1dGUoImFsdGVybmF0ZSIpKSkKLSAgICAgICAgICAgICAgICByZXR1cm5VUkwgPSB0ZW1wVVJMOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gc2F4RXhjKQotICAgIHsKLSAgICB9Ci0gICAgcmV0dXJuIHJldHVyblVSTDsKLSAgfSAgCi0qLwotIC8qKgotICAgKiBUaGUgYXR0cmlidXRlIG5hbWUgaW4gdGhlIDw/eG1sLXN0eWxlc2hlZXQ+IHRhZyB1c2VkIGluIHN0eWxlc2hlZXQgc2VsZWN0aW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RZTEVTSEVFVF9BVFRSSUJVVEUgPSAibWVkaWEiOwotCi0gIC8qKgotICAgKglUaGUgSFRUUCBIZWFkZXIgdXNlZCBmb3IgbWF0Y2hpbmcgdGhlIFN0eWxlc2hlZXQgYXR0cmlidXRlIHZpYSB0aGUKLSAgICogbWVkaWEgcHJvcGVydGllcyBmaWxlIHNlbGVjdGVkLgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEVBREVSX05BTUUgPSAidXNlci1BZ2VudCI7Ci19Ci0KLS8qKgotICogIFN0b3JlcyB0aGUga2V5cyBhbmQgdmFsdWVzIGZyb20gYSBmaWxlIChzaW1pbGFyIHRvIGEgcHJvcGVydGllcyBmaWxlKSBhbmQKLSAqICBjYW4gcmV0dXJuIHRoZSBmaXJzdCB2YWx1ZSB3aGljaCBoYXMgYSBrZXkgY29udGFpbmVkIGluIGl0cyBzdHJpbmcuCi0gKiAgRmlsZSBjYW4gaGF2ZSBjb21tZW50IGxpbmVzIHN0YXJ0aW5nIHdpdGggJyMiIGFuZCBmb3IgZWFjaCBsaW5lIHRoZSBlbnRyaWVzIGFyZQotICogIHNlcGFyYXRlZCBieSB0YWJzIGFuZCAnPScgY2hhci4KLSAqLwotY2xhc3MgT3JkZXJlZFByb3BzCi17Ci0KLSAgLyoqCi0gICAqIFN0b3JlcyB0aGUgS2V5IGFuZCBWYWx1ZXMgYXMgYW4gYXJyYXkgb2YgU3RyaW5ncwotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgYXR0VmVjID0gbmV3IFZlY3RvcigxNSk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yLgotICAgKiBAcGFyYW0gaW5wdXRTdHJlYW0gU3RyZWFtIGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgZmlsZS4KLSAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbiBUaHJvd24gaWYgdW5hYmxlIHRvIHJlYWQgZnJvbSBzdHJlYW0KLSAgICovCi0gIE9yZGVyZWRQcm9wcyhJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkKLSAgICB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIEJ1ZmZlcmVkUmVhZGVyIGlucHV0ICA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW5wdXRTdHJlYW0pKTsKLSAgICBTdHJpbmcgY3VycmVudExpbmUsIEtleSA9IG51bGw7Ci0gICAgU3RyaW5nVG9rZW5pemVyIGN1cnJlbnRUb2tlbnM7Ci0gICAgd2hpbGUgKChjdXJyZW50TGluZSA9IGlucHV0LnJlYWRMaW5lKCkpICE9IG51bGwpCi0gICAgewotICAgICAgY3VycmVudFRva2VucyA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoY3VycmVudExpbmUsICI9XHRcclxuIik7Ci0gICAgICBpZiAoY3VycmVudFRva2Vucy5oYXNNb3JlVG9rZW5zKCkpIEtleSA9IGN1cnJlbnRUb2tlbnMubmV4dFRva2VuKCkudHJpbSgpOwotICAgICAgaWYgKChLZXkgIT0gbnVsbCkgJiYgIUtleS5zdGFydHNXaXRoKCIjIikgJiYgY3VycmVudFRva2Vucy5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyB0ZW1wW10gPSBuZXcgU3RyaW5nWzJdOwotICAgICAgICB0ZW1wWzBdID0gS2V5OyB0ZW1wWzFdID0gY3VycmVudFRva2Vucy5uZXh0VG9rZW4oKS50cmltKCk7Ci0gICAgICAgIGF0dFZlYy5hZGRFbGVtZW50KHRlbXApOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJdGVyYXRlcyB0aHJvdWdoIHRoZSBLZXkgbGlzdCBhbmQgcmV0dXJucyB0aGUgZmlyc3QgdmFsdWUgZm9yIHdob3NlCi0gICAqIGtleSB0aGUgZ2l2ZW4gc3RyaW5nIGNvbnRhaW5zLiAgUmV0dXJucyAidW5rbm93biIgaWYgbm8ga2V5IGlzIGNvbnRhaW5lZAotICAgKiBpbiB0aGUgc3RyaW5nLgotICAgKiBAcGFyYW0gcyBTdHJpbmcgYmVpbmcgc2VhcmNoZWQgZm9yIGEga2V5LgotICAgKiBAcmV0dXJuIFZhbHVlIGZvciBrZXkgZm91bmQgaW4gc3RyaW5nLCBvdGhlcndpc2UgInVua25vd24iCi0gICAqLwotICBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHMpCi0gIHsKLSAgICBpbnQgaSwgaiA9IGF0dFZlYy5zaXplKCk7Ci0gICAgZm9yIChpID0gMDsgaSA8IGo7IGkrKykKLSAgICB7Ci0gICAgICBTdHJpbmcgdGVtcFtdID0gKFN0cmluZ1tdKSBhdHRWZWMuZWxlbWVudEF0KGkpOwotICAgICAgaWYgKHMuaW5kZXhPZih0ZW1wWzBdKSA+IC0xKQotICAgICAgICByZXR1cm4gdGVtcFsxXTsKLSAgICB9Ci0gICAgcmV0dXJuICJ1bmtub3duIjsKLSAgfQotfQotCi0vKioKLSAqIFBhcnNlcyBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24ncyAoUEkpIGF0dHJpYnV0ZXMgZm9yIGVhc3kgcmV0cmlldmFsLgotICovCi1jbGFzcyBQSUEKLXsKLQotICBwcml2YXRlIEhhc2h0YWJsZSBwaUF0dHJpYnV0ZXMgPSBudWxsOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICogQHBhcmFtIHBpIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHdob3NlIGF0dHJpYnV0ZXMgYXJlIHRvIGJlIHBhcnNlZAotICAgKi8KLSAgUElBKFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBwaSkKLSAgewotICAgIHBpQXR0cmlidXRlcyA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihwaS5nZXROb2RlVmFsdWUoKSwgIj1cIiIpOwotICAgIHdoaWxlKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgewotICAgICAgcGlBdHRyaWJ1dGVzLnB1dCh0b2tlbml6ZXIubmV4dFRva2VuKCkudHJpbSgpLCB0b2tlbml6ZXIubmV4dFRva2VuKCkudHJpbSgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB2YWx1ZSBvZiBzcGVjaWZpZWQgYXR0cmlidXRlLgotICAgKiAgQHBhcmFtIG5hbWUgQXR0cmlidXRlIG5hbWUKLSAgICogIEByZXR1cm4gQXR0cmlidXRlIHZhbHVlLCBvciBudWxsIGlmIHRoZSBhdHRyaWJ1dGUgbmFtZSBkb2VzIG5vdCBleGlzdAotICAgKi8KLSAgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgewotICAgIHJldHVybiAoU3RyaW5nKSBwaUF0dHJpYnV0ZXMuZ2V0KG5hbWUpOwotICB9ICAKLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xURXhjZXB0aW9uLmphdmEgYi9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xURXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY2M2M2YTEuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9zZXJ2bGV0L0FwcGx5WFNMVEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqIAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKgotICogV3JhcHBlciBmb3IgZXhjZXB0aW9ucyBvY2N1cnJpbmcgZHVyaW5nIGFwcGx5IFhTTCBwcm9jZXNzaW5nLiAgCi0gKiBBbGxvd3MgZm9yIGV4Y2VwdGlvbnMgdG8gYmUgcmV0dXJuZWQgd2l0aCBhbiBhc3NvY2lhdGVkIEhUVFAgU3RhdHVzIENvZGUuCi0gKgotICogQGF1dGhvciBTcGVuY2VyIFNoZXBhcmQgKHNzaGVwYXJkQHVzLmlibS5jb20pCi0gKiBAYXV0aG9yIFIuIEFkYW0gS2luZyAocmFrQHVzLmlibS5jb20pCi0gKiBAYXV0aG9yIFRvbSBSb3dlICh0cm93ZUB1cy5pYm0uY29tKQotICoKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugc2VydmxldDsKLQotcHVibGljIGNsYXNzIEFwcGx5WFNMVEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7Ci0KLSAgICAvKioKLSAgICAgICogRXhjZXB0aW9uIE1lc3NhZ2UuCi0gICAgICAqIEBzZXJpYWwKLSAgICAgICovIAotICAgIHByaXZhdGUgU3RyaW5nIG15TWVzc2FnZSA9ICIiOwotCi0gICAgLyoqCi0gICAgICAqIEhUVFAgU3RhdHVzIENvZGUuIERlZmF1bHQ9IGludGVybmFsIHNlcnZlciBlcnJvci4KLSAgICAgICogQHNlcmlhbAotICAgICAgKi8KLSAgICBwcml2YXRlIGludCAgbXlIdHRwU3RhdHVzQ29kZSA9IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlLlNDX0lOVEVSTkFMX1NFUlZFUl9FUlJPUjsgCi0KLSAgICAvKioKLSAgICAgICogV3JhcHBlZCBleGNlcHRpb24KLSAgICAgICogQHNlcmlhbAotICAgICAgKi8KLSAgICBwcml2YXRlIEV4Y2VwdGlvbiBteUV4Y2VwdGlvbiA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgICogQ29uc3RydWN0b3IgZm9yIGV4Y2VwdGlvbiB3aXRoIG5vIGFkZGl0aW9uYWwgZGV0YWlsLgotICAgICAgKi8KLSAgICBwdWJsaWMgQXBwbHlYU0xURXhjZXB0aW9uKCkgCi0gICAgeyAKLSAgICAgICAgc3VwZXIoKTsgCi0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIENvbnN0cnVjdG9yIGZvciBleGNlcHRpb24gd2l0aCBtZXNzYWdlLgotICAgICAgKiBAcGFyYW0gcyBFeGNlcHRpb24gbWVzc2FnZQotICAgICAgKi8KLSAgICBwdWJsaWMgQXBwbHlYU0xURXhjZXB0aW9uKFN0cmluZyBzKSAKLSAgICB7IAotICAgICAgICBzdXBlcigpOyAKLQlteU1lc3NhZ2UgPSBzOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBDb25zdHJ1Y3RvciBmb3IgZXhjZXB0aW9uIHdpdGggSFRUUCBzdGF0dXMgY29kZS4KLSAgICAgICogQHBhcmFtIGhzYyBWYWxpZCBzdGF0dXMgY29kZSBmcm9tIGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlCi0gICAgICAqLwotICAgIHB1YmxpYyBBcHBseVhTTFRFeGNlcHRpb24oaW50IGhzYykgCi0gICAgewotCXN1cGVyKCk7Ci0JbXlIdHRwU3RhdHVzQ29kZSA9IGhzYzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogQ29uc3RydWN0b3IgZm9yIGV4Y2VwdGlvbiB3aXRoIG1lc3NhZ2UgYW5kIEhUVFAgc3RhdHVzIGNvZGUuCi0gICAgICAqIEBwYXJhbSBzIEV4Y2VwdGlvbiBtZXNzYWdlCi0gICAgICAqIEBwYXJhbSBoc2MgVmFsaWQgc3RhdHVzIGNvZGUgZnJvbSBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZQotICAgICAgKi8KLSAgICBwdWJsaWMgQXBwbHlYU0xURXhjZXB0aW9uKFN0cmluZyBzLCBpbnQgaHNjKQotICAgIHsKLQlzdXBlcigpOwotCW15SHR0cFN0YXR1c0NvZGUgPSBoc2M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIENvbnN0cnVjdG9yIGZvciBleGNlcHRpb24uCi0gICAgICAqIEBwYXJhbSBlIEV4Y2VwdGlvbiB0byBiZSB3cmFwcGVkLgotICAgICAgKi8KLSAgICBwdWJsaWMgQXBwbHlYU0xURXhjZXB0aW9uKEV4Y2VwdGlvbiBlKQotICAgIHsKLQlzdXBlcigpOwotCW15TWVzc2FnZSA9IGUuZ2V0TWVzc2FnZSgpOwotCW15RXhjZXB0aW9uID0gZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogQ29uc3RydWN0b3IgZm9yIHBhc3NlZCBleGNlcHRpb24gd2l0aCBtZXNzYWdlLgotICAgICAgKiBAcGFyYW0gcyBFeGNlcHRpb24gbWVzc2FnZQotICAgICAgKiBAcGFyYW0gZSBFeGNlcHRpb24gdG8gYmUgd3JhcHBlZC4KLSAgICAgICovCi0gICAgcHVibGljIEFwcGx5WFNMVEV4Y2VwdGlvbiAoU3RyaW5nIHMsIEV4Y2VwdGlvbiBlKQotICAgIHsKLQlzdXBlcigpOwotCW15TWVzc2FnZSA9IHM7Ci0JbXlFeGNlcHRpb24gPSBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBDb25zdHJ1Y3RvciBmb3IgcGFzc2VkIGV4Y2VwdGlvbiB3aXRoIEhUVFAgc3RhdHVzIGNvZGUuCi0gICAgICAqIEBwYXJhbSBlIEV4Y2VwdGlvbiB0byBiZSB3cmFwcGVkLgotICAgICAgKiBAcGFyYW0gaHNjIFZhbGlkIHN0YXR1cyBjb2RlIGZyb20gamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVzcG9uc2UKLSAgICAgICovCi0gICAgcHVibGljIEFwcGx5WFNMVEV4Y2VwdGlvbihFeGNlcHRpb24gZSwgaW50IGhzYykKLSAgICB7Ci0Jc3VwZXIoKTsKLQlteU1lc3NhZ2UgPSBlLmdldE1lc3NhZ2UoKTsKLQlteUV4Y2VwdGlvbiA9IGU7Ci0JbXlIdHRwU3RhdHVzQ29kZSA9IGhzYzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogQ29uc3RydWN0b3IgZm9yIHBhc3NlZCBleGNlcHRpb24gd2l0aCBIVFRQIHN0YXR1cyBjb2RlIGFuZCBtZXNzYWdlLgotICAgICAgKiBAcGFyYW0gcyBFeGNlcHRpb24gbWVzc2FnZQotICAgICAgKiBAcGFyYW0gZSBFeGNlcHRpb24gdG8gYmUgd3JhcHBlZC4KLSAgICAgICogQHBhcmFtIGhzYyBWYWxpZCBzdGF0dXMgY29kZSBmcm9tIGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlCi0gICAgICAqLwotICAgIHB1YmxpYyBBcHBseVhTTFRFeGNlcHRpb24oU3RyaW5nIHMsIEV4Y2VwdGlvbiBlLCBpbnQgaHNjKQotICAgIHsKLQlzdXBlcigpOwotCW15TWVzc2FnZSA9IHM7Ci0JbXlFeGNlcHRpb24gPSBlOwotCW15SHR0cFN0YXR1c0NvZGUgPSBoc2M7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJldHVybnMgZXhjZXB0aW9uIG1lc3NhZ2UuCi0gICAgICAqIEByZXR1cm4gZXhjZXB0aW9uIG1lc3NhZ2UKLSAgICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkKLSAgICB7Ci0JcmV0dXJuIG15TWVzc2FnZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogQXBwZW5kcyBzdHJpbmcgdG8gZXhjZXB0aW9uIG1lc3NhZ2UuCi0gICAgICAqIEBwYXJhbSBzIFN0cmluZyB0byBiZSBhZGRlZCB0byBtZXNzYWdlCi0gICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFwcGVuZE1lc3NhZ2UoU3RyaW5nIHMpCi0gICAgewotCW15TWVzc2FnZSArPSBzOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIGV4Y2VwdGlvbi4KLSAgICAgICogQHJldHVybiBXcmFwcGVkIGV4Y2VwdGlvbgotICAgICAgKi8KLSAgICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpCi0gICAgewotCXJldHVybiBteUV4Y2VwdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogUmV0dXJucyB0aGUgSFRUUCBzdGF0dXMgY29kZSBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbi4KLSAgICAgICogQHJldHVybiBWYWxpZCBzdGF0dXMgY29kZSBmcm9tIGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlCi0gICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U3RhdHVzQ29kZSgpCi0gICAgewotCXJldHVybiBteUh0dHBTdGF0dXNDb2RlOwotICAgIH0KLX0KLQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9zZXJ2bGV0L0FwcGx5WFNMVExpc3RlbmVyLmphdmEgYi9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xUTGlzdGVuZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmU0NmUyNi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xUTGlzdGVuZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugc2VydmxldDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkRlZmF1bHRFcnJvckhhbmRsZXI7Ci0KLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQXBwbHlYU0xUTGlzdGVuZXIgcHJvdmlkZXMgYSBidWZmZXJlZCBsaXN0ZW5lciBlc3NlbnRpYWwgZm9yIGNhcHR1cmluZywgYW5kIHRoZW4gc3Vic2VxdWVudGx5Ci0gKiByZXBvcnRpbmcsIFhNTCBhbmQgWFNMIHByb2Nlc3NvciBtZXNzYWdlcyB3aGljaCBtYXkgYmUgb2YgdXNlIGluIGRlYnVnZ2luZyBYTUwrWFNMIHByb2Nlc3NlZCBhdAotICogdGhlIHNlcnZlci4KLSAqCi0gKiBAYXV0aG9yIFNwZW5jZXIgU2hlcGFyZCAoc3NoZXBhcmRAdXMuaWJtLmNvbSkKLSAqIEBhdXRob3IgUi4gQWRhbSBLaW5nIChyYWtAdXMuaWJtLmNvbSkKLSAqIEBhdXRob3IgVG9tIFJvd2UgKHRyb3dlQHVzLmlibS5jb20pCi0gKgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi1wdWJsaWMgY2xhc3MgQXBwbHlYU0xUTGlzdGVuZXIgZXh0ZW5kcyBEZWZhdWx0RXJyb3JIYW5kbGVyIGltcGxlbWVudHMgRXJyb3JIYW5kbGVyCi17Ci0KLSAgICAvKioKLSAgICAgICogT3V0cHV0IHN0cmVhbQotICAgICAgKi8KLSAgICBwcml2YXRlIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7Ci0KLSAgICAvKioKLSAgICAgICogQnVmZmVyZWQgb3V0cHV0IHN0cmVhbQotICAgICAgKi8KLSAgICBwdWJsaWMgUHJpbnRXcml0ZXIgb3V0ID0gbnVsbDsKLQotICAgIC8qKgotICAgICAgKiBDb25zdHJ1Y3Rvci4KLSAgICAgICovCi0gICAgcHVibGljIEFwcGx5WFNMVExpc3RlbmVyKCkKLSAgICB7Ci0gICAgICBvdXQgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG91dFN0cmVhbSksIHRydWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHdhcm5pbmcuCi0gICAgICAqCi0gICAgICAqIEBwYXJhbSBzcGUgVGhlIHdhcm5pbmcgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KLSAgICAgICovCi0gICAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBzcGUpCi0gICAgewotCW91dC5wcmludGxuKCJQYXJzZXIgV2FybmluZzogIiArIHNwZS5nZXRNZXNzYWdlKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIGVycm9yLgotICAgICAgKgotICAgICAgKiBAcGFyYW0gc3BlIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYSBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBzcGUpCi0gICAgewotCW91dC5wcmludGxuKCJQYXJzZXIgRXJyb3I6ICIgKyBzcGUuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub24tcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgICAqCi0gICAgICAqIEBwYXJhbSBzcGUgVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIEFsd2F5cyB0aHJvd24KLSAgICAgICovCi0gICAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBzcGUpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLQlvdXQucHJpbnRsbigiUGFyc2VyIEZhdGFsIEVycm9yOiAiICsgc3BlLmdldE1lc3NhZ2UoKSk7Ci0JdGhyb3cgc3BlOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBSZXR1cm5zIHRoZSBidWZmZXJlZCBwcm9jZXNzaW5nIG1lc3NhZ2UocykuCi0gICAgICAqIEByZXR1cm4gQnVmZmVyZWQgcHJvY2Vzc2luZyBtZXNzYWdlKHMpCi0gICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpCi0gICAgewotCXJldHVybiBvdXRTdHJlYW0udG9TdHJpbmcoKTsKLSAgICB9Ci19Ci0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvc2VydmxldC9BcHBseVhTTFRQcm9wZXJ0aWVzLmphdmEgYi9zYW1wbGVzL3NlcnZsZXQvQXBwbHlYU0xUUHJvcGVydGllcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OWUwZWQ0Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvc2VydmxldC9BcHBseVhTTFRQcm9wZXJ0aWVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIHNlcnZsZXQ7Ci0KLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YXguc2VydmxldC4qOwotaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC4qOwotCi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIAotICogQXBwbHlYU0xUUHJvcGVydGllcyBjb250YWlucyBvcGVyYXRpb25hbCBwYXJhbWV0ZXJzIGZvciBBcHBseVhTTFQgYmFzZWQgCi0gKiBvbiBwcm9ncmFtIGRlZmF1bHRzIGFuZCBjb25maWd1cmF0aW9uLiAgCi0gKiA8cD5UaGlzIGNsYXNzIGlzIGFsc28gdXNlZCB0byByZXR1cm4gdmFsdWVzIGZvciByZXF1ZXN0LXRpbWUgcGFyYW1ldGVycy48L3A+Ci0gKgotICogQGF1dGhvciBTcGVuY2VyIFNoZXBhcmQgKHNzaGVwYXJkQHVzLmlibS5jb20pCi0gKiBAYXV0aG9yIFIuIEFkYW0gS2luZyAocmFrQHVzLmlibS5jb20pCi0gKiBAYXV0aG9yIFRvbSBSb3dlICh0cm93ZUB1cy5pYm0uY29tKQotICoKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotcHVibGljIGNsYXNzIEFwcGx5WFNMVFByb3BlcnRpZXMgewotCi0gICAgLyoqCi0gICAgICAqIFByb2dyYW0gZGVmYXVsdCBmb3IgcGFyYW1ldGVyICJVUkwiCi0gICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIERFRkFVTFRfVVJMOwotCi0gICAgLyoqCi0gICAgICAqIFByb2dyYW0gZGVmYXVsdCBmb3IgcGFyYW1ldGVyICJ4c2xVUkwiCi0gICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIERFRkFVTFRfeHNsVVJMOwotICAgIAotICAgIC8qKgotICAgICAgKiBQcm9ncmFtIGRlZmF1bHQgZm9yIHBhcmFtZXRlciAiZGVidWciCi0gICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBERUZBVUxUX2RlYnVnOwotCi0gICAgLyoqCi0gICAgICAqIFByb2dyYW0gZGVmYXVsdCBmb3IgcGFyYW1ldGVyICJub0NvbmZsaWN0V2FybmluZ3MiCi0gICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBERUZBVUxUX25vQ1c7Ci0gICAgCi0gICAgLyoqCi0gICAgICAqIENvbnN0cnVjdG9yIHRvIHVzZSBwcm9ncmFtIGRlZmF1bHRzLgotICAgICAgKi8KLSAgICBwdWJsaWMgQXBwbHlYU0xUUHJvcGVydGllcygpIAotICAgIHsKLQlERUZBVUxUX1VSTCA9IG51bGw7Ci0JREVGQVVMVF94c2xVUkwgPSBudWxsOwotCURFRkFVTFRfZGVidWcgPSBmYWxzZTsKLQlERUZBVUxUX25vQ1cgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogQ29uc3RydWN0b3IgdG8gdXNlIHRvIG92ZXJyaWRlIHByb2dyYW0gZGVmYXVsdHMuCi0gICAgICAqIEBwYXJhbSBjb25maWcgU2VydmxldCBjb25maWd1cmF0aW9uCi0gICAgICAqLwotICAgIHB1YmxpYyBBcHBseVhTTFRQcm9wZXJ0aWVzKFNlcnZsZXRDb25maWcgY29uZmlnKQotICAgIHsKLQlTdHJpbmcgeG0gPSBjb25maWcuZ2V0SW5pdFBhcmFtZXRlcigiVVJMIiksCi0JICAgICAgIHh1ID0gY29uZmlnLmdldEluaXRQYXJhbWV0ZXIoInhzbFVSTCIpLAotCSAgICAgICBkYiA9IGNvbmZpZy5nZXRJbml0UGFyYW1ldGVyKCJkZWJ1ZyIpLAotCSAgICAgICBjdyA9IGNvbmZpZy5nZXRJbml0UGFyYW1ldGVyKCJub0NvbmZsaWN0V2FybmluZ3MiKTsKLQkgICAgICAgCi0JaWYgKHhtICE9IG51bGwpIERFRkFVTFRfVVJMID0geG07Ci0JZWxzZSBERUZBVUxUX1VSTCA9IG51bGw7Ci0JaWYgKHh1ICE9IG51bGwpIERFRkFVTFRfeHNsVVJMID0geHU7Ci0JZWxzZSBERUZBVUxUX3hzbFVSTCA9IG51bGw7Ci0JaWYgKGRiICE9IG51bGwpIERFRkFVTFRfZGVidWcgPSBuZXcgQm9vbGVhbihkYikuYm9vbGVhblZhbHVlKCk7Ci0JZWxzZSBERUZBVUxUX2RlYnVnID0gZmFsc2U7Ci0JaWYgKGN3ICE9IG51bGwpIERFRkFVTFRfbm9DVyA9IG5ldyBCb29sZWFuKGN3KS5ib29sZWFuVmFsdWUoKTsKLQllbHNlIERFRkFVTFRfbm9DVyA9IGZhbHNlOwotICAgIH0KLSAgIAotICAgIC8qKgotICAgICAgKiBHaXZlbiBhIHBhcmFtZXRlciBuYW1lLCByZXR1cm5zIHRoZSBIVFRQIHJlcXVlc3QncyBTdHJpbmcgdmFsdWU7IAotICAgICAgKiBpZiBub3QgcHJlc2VudCBpbiByZXF1ZXN0LCByZXR1cm5zIGRlZmF1bHQgU3RyaW5nIHZhbHVlLgotICAgICAgKiBAcGFyYW0gcmVxdWVzdCBSZXF1ZXN0IHRvIGNoZWNrIGZvciBkZWZhdWx0IG92ZXJyaWRlCi0gICAgICAqIEBwYXJhbSBwYXJhbSBOYW1lIG9mIHRoZSBwYXJhbWV0ZXIKLSAgICAgICogQHJldHVybiBTdHJpbmcgdmFsdWUgb2YgbmFtZWQgcGFyYW1ldGVyCi0gICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVxdWVzdFBhcm1TdHJpbmcoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIFN0cmluZyBwYXJhbSkKLSAgICB7Ci0JaWYgKHJlcXVlc3QgIT0gbnVsbCkgeyAKLQkgICAgU3RyaW5nW10gcGFyYW1WYWxzID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXJWYWx1ZXMocGFyYW0pOyAKLQkgICAgaWYgKHBhcmFtVmFscyAhPSBudWxsKSAKLQkJcmV0dXJuIHBhcmFtVmFsc1swXTsKLQl9Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgc2V0dGluZyBmb3IgIlVSTCIuCi0gICAgICAqIEBwYXJhbSByZXF1ZXN0IFJlcXVlc3QgdG8gY2hlY2sgZm9yIHBhcmFtZXRlciB2YWx1ZQotICAgICAgKiBAcmV0dXJuIFN0cmluZyB2YWx1ZSBmb3IgIlVSTCIKLSAgICAgICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUkxFeGNlcHRpb24gV2lsbCBub3QgYmUgdGhyb3duCi0gICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WE1MdXJsKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0KQotICAgIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24KLSAgICB7Ci0JU3RyaW5nIHRlbXAgPSBnZXRSZXF1ZXN0UGFybVN0cmluZyhyZXF1ZXN0LCAiVVJMIik7Ci0JaWYgKHRlbXAgIT0gbnVsbCkKLQkgICAgcmV0dXJuIHRlbXA7Ci0JcmV0dXJuIERFRkFVTFRfVVJMOwotICAgIH0gICAgIAotICAgIAotICAgIC8qKgotICAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNldHRpbmcgZm9yICJ4c2xVUkwiLgotICAgICAgKiBAcGFyYW0gcmVxdWVzdCBSZXF1ZXN0IHRvIGNoZWNrIGZvciBwYXJhbWV0ZXIgdmFsdWUKLSAgICAgICogQHJldHVybiBTdHJpbmcgdmFsdWUgZm9yICJ4c2xVUkwiCi0gICAgICAqIEBleGNlcHRpb24gTWFsZm9ybWVkVVJMRXhjZXB0aW9uIFdpbGwgbm90IGJlIHRocm93bgotICAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFhTTHVybChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uCi0gICAgeyAgCi0JU3RyaW5nIHRlbXAgPSBnZXRSZXF1ZXN0UGFybVN0cmluZyhyZXF1ZXN0LCAieHNsVVJMIik7Ci0JaWYgKHRlbXAgIT0gbnVsbCkKLQkgICAgcmV0dXJuIHRlbXA7Ci0JcmV0dXJuIERFRkFVTFRfeHNsVVJMOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBzZXR0aW5nIGZvciAiZGVidWciLgotICAgICAgKiBAcGFyYW0gcmVxdWVzdCBSZXF1ZXN0IHRvIGNoZWNrIGZvciBwYXJhbWV0ZXIgdmFsdWUKLSAgICAgICogQHJldHVybiBCb29sZWFuIHZhbHVlIGZvciAiZGVidWciCi0gICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVidWcoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QpCi0gICAgewotCVN0cmluZyB0ZW1wID0gZ2V0UmVxdWVzdFBhcm1TdHJpbmcocmVxdWVzdCwgImRlYnVnIik7Ci0JaWYgKHRlbXAgIT0gbnVsbCkKLQkgICAgcmV0dXJuIG5ldyBCb29sZWFuKHRlbXApLmJvb2xlYW5WYWx1ZSgpOwotCXJldHVybiBERUZBVUxUX2RlYnVnOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNldHRpbmcgZm9yICJub0NvbmZsaWN0V2FybmluZ3MiLgotICAgICAgKiBAcGFyYW0gcmVxdWVzdCBSZXF1ZXN0IHRvIGNoZWNrIGZvciBwYXJhbWV0ZXIgdmFsdWUKLSAgICAgICogQHJldHVybiBCb29sZWFuIHZhbHVlIGZvciAibm9Db25mbGljdFdhcm5pbmdzIgotICAgICAgKi8KLSAgICBib29sZWFuIGlzTm9DVyhIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgICB7Ci0JU3RyaW5nIHRlbXAgPSBnZXRSZXF1ZXN0UGFybVN0cmluZyhyZXF1ZXN0LCAibm9Db25mbGljdFdhcm5pbmdzIik7Ci0JaWYgKHRlbXAgIT0gbnVsbCkKLQkgICAgcmV0dXJuIG5ldyBCb29sZWFuKHRlbXApLmJvb2xlYW5WYWx1ZSgpOwotCXJldHVybiBERUZBVUxUX25vQ1c7Ci0gICAgfSAgICAKLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3NlcnZsZXQvRGVmYXVsdEFwcGx5WFNMVFByb3BlcnRpZXMuamF2YSBiL3NhbXBsZXMvc2VydmxldC9EZWZhdWx0QXBwbHlYU0xUUHJvcGVydGllcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZmRiOTY3Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvc2VydmxldC9EZWZhdWx0QXBwbHlYU0xUUHJvcGVydGllcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBzZXJ2bGV0OwotCi1pbXBvcnQgamF2YS5uZXQuKjsKLWltcG9ydCBqYXZheC5zZXJ2bGV0Lio7Ci1pbXBvcnQgamF2YXguc2VydmxldC5odHRwLio7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIAotICogRGVmYXVsdEFwcGx5WFNMVFByb3BlcnRpZXMgY29udGFpbnMgb3BlcmF0aW9uYWwgcGFyYW1ldGVycyBmb3IgRGVmYXVsdEFwcGx5WFNMVCBiYXNlZCAKLSAqIG9uIHByb2dyYW0gZGVmYXVsdHMgYW5kIGNvbmZpZ3VyYXRpb24uICAKLSAqIDxwPlRoaXMgY2xhc3MgaXMgYWxzbyB1c2VkIHRvIHJldHVybiB2YWx1ZXMgZm9yIHJlcXVlc3QtdGltZSBwYXJhbWV0ZXJzLjwvcD4KLSAqCi0gKiBAYXV0aG9yIFNwZW5jZXIgU2hlcGFyZCAoc3NoZXBhcmRAdXMuaWJtLmNvbSkKLSAqIEBhdXRob3IgUi4gQWRhbSBLaW5nIChyYWtAdXMuaWJtLmNvbSkKLSAqIEBhdXRob3IgVG9tIFJvd2UgKHRyb3dlQHVzLmlibS5jb20pCi0gKgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi1wdWJsaWMgY2xhc3MgRGVmYXVsdEFwcGx5WFNMVFByb3BlcnRpZXMgZXh0ZW5kcyBBcHBseVhTTFRQcm9wZXJ0aWVzIHsKLSAgICAKLSAgICAvKioKLSAgICAgICogUHJvZ3JhbSBkZWZhdWx0IGZvciBwYXJhbWV0ZXIgImNhdGFsb2ciLgotICAgICAgKiBAc2VlICNnZXRDYXRhbG9nCi0gICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIERFRkFVTFRfY2F0YWxvZzsKLQotICAgIC8qKgotICAgICAgKiBIb3N0IHVzZWQgZm9yIGxvY2FsIGNvbnRleHQgY29tcGFyaXNvbnMuCi0gICAgICAqIEBzZWUgI2dldExvY2FsSG9zdAotICAgICAgKiBAc2VlICNzZXRMb2NhbEhvc3QKLSAgICAgICovCi0gICAgcHJvdGVjdGVkIHRyYW5zaWVudCBTdHJpbmcgbG9jYWxIb3N0ID0gbnVsbDsKLSAgICAKLSAgICAvKioKLSAgICAgKiBTZXJ2ZXIgcG9ydC4gVXNlZCBpbiB0b1NhZmVVUkwoKSAtLSBmaXggc3VibWl0dGVkIGJ5IFJpdGVzaCBLdW1hci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBwb3J0ID0wOwotCi0gICAgLyoqCi0gICAgICAqIENvbnN0cnVjdG9yIHRvIHVzZSBwcm9ncmFtIGRlZmF1bHRzLgotICAgICAgKi8KLSAgICBwdWJsaWMgRGVmYXVsdEFwcGx5WFNMVFByb3BlcnRpZXMoKQotICAgIHsKLQlzdXBlcigpOwotCURFRkFVTFRfY2F0YWxvZyA9IG51bGw7Ci0Jc2V0TG9jYWxIb3N0KCk7Ci0JLy8gc2V0U3lzdGVtUHJvcGVydGllcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBDb25zdHJ1Y3RvciB0byB1c2UgdG8gb3ZlcnJpZGUgcHJvZ3JhbSBkZWZhdWx0cy4KLSAgICAgICogQHBhcmFtIGNvbmZpZyBTZXJ2bGV0IGNvbmZpZ3VyYXRpb24KLSAgICAgICogQHNlZSAjc2V0TG9jYWxIb3N0Ci0gICAgICAqLwotICAgIHB1YmxpYyBEZWZhdWx0QXBwbHlYU0xUUHJvcGVydGllcyhTZXJ2bGV0Q29uZmlnIGNvbmZpZykKLSAgICB7Ci0JICAgIHN1cGVyKGNvbmZpZyk7Ci0JICAgIFN0cmluZyBjYXQgPSBjb25maWcuZ2V0SW5pdFBhcmFtZXRlcigiY2F0YWxvZyIpOwotCSAgICBpZiAoY2F0ICE9IG51bGwpIERFRkFVTFRfY2F0YWxvZyA9IGNhdDsKLQkgICAgZWxzZSBERUZBVUxUX2NhdGFsb2cgPSBudWxsOwotCSAgICBzZXRMb2NhbEhvc3QoKTsKLQkgICAgc2V0U3lzdGVtUHJvcGVydGllcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBsb2NhbCBJUCBob3N0IG5hbWU7IHRoaXMgdmFsdWUgd2lsbCBiZSB1c2VkIHRvIGNvbnN0cmFpbiB1bnRydXN0ZWQgCi0gICAgICAqIFhNTCBkb2N1bWVudCBhbmQgWFNMIHN0eWxlc2hlZXQgVVJMcyB0byB0aGlzIHRydXN0ZWQgaG9zdC4KLSAgICAgICogQHNlZSAjZ2V0TG9jYWxIb3N0Ci0gICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldExvY2FsSG9zdCgpCi0gICAgewotCSAgICB0cnkgCi0JICAgIHsgCi0JICAgICAgICBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpOwotCSAgICB9IAotCSAgICBjYXRjaCAoRXhjZXB0aW9uIHVoZSkgCi0JICAgIHsKLQkgICAgICBsb2NhbEhvc3QgPSBudWxsOwotCSAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdHJ1c3RlZCBJUCBob3N0LgotICAgICAgKiBAcmV0dXJuIE5hbWUgb2YgdHJ1c3RlZCBob3N0Ci0gICAgICAqIEBzZWUgI3NldExvY2FsSG9zdAotICAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsSG9zdCgpCi0gICAgewotCSAgICByZXR1cm4gbG9jYWxIb3N0OwotICAgIH0KLQotICAgIC8qKgotICAgICAgKiBSZXR1cm5zIGEgVVJMIHdoaWNoIGlzIGNvbnN0cmFpbmVkIHRvIGEgdHJ1c3RlZCBJUCBob3N0LgotICAgICAgKiBAcGFyYW0geFVSTCBVUkwgb3IgZmlsZSBwYXRoIHRvIGJlIG1hZGUgc2FmZSAKLSAgICAgICogQHJldHVybiBTYWZlIFVSTAotICAgICAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaHJvd24gd2hlbiB4VVJMIGlzIG5vdCBhIHZhbGlkIFVSTAotICAgICAgKiBAc2VlICNzZXRMb2NhbEhvc3QKLSAgICAgICogQHNlZSAjZ2V0TG9jYWxIb3N0Ci0gICAgICAqLwotICAgIHB1YmxpYyBVUkwgdG9TYWZlVVJMKFN0cmluZyB4VVJMLCBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uCi0gICAgewotICAgICAgLy8gRml4IHN1Ym1pdHRlZCBieSBSaXRlc2ggS3VtYXIuIFBvcnQgaXMgaW5jbHVkZWQgaW4gY29uc3RydWN0aW9uIG9mIFVSTCB0aGF0IGlzIHJldHVybmVkLgotICAgICAgaWYgKHBvcnQgPT0gMCkKLSAgICAgICAgcG9ydCA9IHJlcXVlc3QuZ2V0U2VydmVyUG9ydCgpOwotICAgICAgCi0JICAgIGlmICh4VVJMID09IG51bGwpCi0JICAgICAgcmV0dXJuIG51bGw7Ci0KLQkgICAgaWYgKHhVUkwuc3RhcnRzV2l0aCgiLyIpKSAKLSAgICAgIHsKLQkgICAgICB0cnkgCi0gICAgICAgIHsKLQkJICAgICAgcmV0dXJuIG5ldyBVUkwoImh0dHAiLCBsb2NhbEhvc3QsIHBvcnQsIHhVUkwpOwotCSAgICAgIH0KLSAgICAgICAgY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUpIAotICAgICAgICB7Ci0JICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJMRXhjZXB0aW9uKCJ0b1NhZmVVUkwoKTogIiArIHhVUkwgKyAKLQkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGRpZCBub3QgbWFwIHRvIGxvY2FsIik7Ci0JICAgICAgfQotCSAgICB9Ci0JICAgIFVSTCB0ZW1wVVJMID0gbnVsbDsKLQkgICAgdHJ5IAotICAgICAgeyAKLQkgICAgICB0ZW1wVVJMID0gbmV3IFVSTCh4VVJMKTsKLQkgICAgfSAKLSAgICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlKSAKLSAgICAgIHsKLQkgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJMRXhjZXB0aW9uKCJ0b1NhZmVVUkwoKTogIiArIHhVUkwgKyAKLQkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBub3QgYSB2YWxpZCBVUkwiKTsgCi0JICAgIH0KLQkgICAgdHJ5IAotICAgICAgeyAKLQkgICAgICByZXR1cm4gbmV3IFVSTCh0ZW1wVVJMLmdldFByb3RvY29sKCksIGxvY2FsSG9zdCwgCi0JCQkgICAgICAgICAgICAgICAgIHBvcnQsIHRlbXBVUkwuZ2V0RmlsZSgpKTsKLQkgICAgfSAKLSAgICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlKSAKLSAgICAgIHsKLQkgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJMRXhjZXB0aW9uKCJ0b1NhZmVVUkwoKTogIiArIHhVUkwgKyAKLQkJCQkgICAgICAgICAgICAgICAgICAgICAgICAgIAkgICAgIiBjb3VsZCBub3QgYmUgY29udmVydGVkIHRvIGxvY2FsIGhvc3QiKTsKLQkgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAgKglSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgY29uc3RyYWluZWQgVVJMIGZvciB0aGUgWE1MIGRvY3VtZW50LgotICAgICAgKiBJZiB0aGVyZSBpcyBubyByZXF1ZXN0IHBhcmFtZXRlciBmb3IgdGhlIFhNTCBkb2N1bWVudCwgcmV0dXJuIHRoZSBjb25maWd1cmVkIGRlZmF1bHQuCi0gICAgICAqIEBwYXJhbSByZXF1ZXN0IE1heSBjb250YWluIGFuIFhNTCBkb2N1bWVudCBVUkwgcGFyYW1ldGVyCi0gICAgICAqIEByZXR1cm4gU3RyaW5nIGZvcm0gb2YgWE1MIFVSTAotICAgICAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaHJvd24gd2hlbiByZXF1ZXN0IFVSTCBpcyBub3QgYSB2YWxpZCBVUkwgb3IgcGF0aAotICAgICAgKiBAc2VlICN0b1NhZmVVUkwKLSAgICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYTUx1cmwoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbgotICAgIHsKLQkgICAgVVJMIHVybCA9IHRvU2FmZVVSTChnZXRSZXF1ZXN0UGFybVN0cmluZyhyZXF1ZXN0LCAiVVJMIikscmVxdWVzdCk7Ci0JICAgIGlmICh1cmwgPT0gbnVsbCkKLQkgICAgICByZXR1cm4gc3VwZXIuZ2V0WE1MdXJsKG51bGwpOwotCSAgICByZXR1cm4gdXJsLnRvRXh0ZXJuYWxGb3JtKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBjb25zdHJhaW5lZCBVUkwgZm9yIHRoZSBYU0wgc3R5bGVzaGVldCAKLSAgICAgICogZnJvbSB0aGUgcmVxdWVzdC4KLSAgICAgICogQHBhcmFtIHJlcXVlc3QgTWF5IGNvbnRhaW4gYW4gWFNMIHN0eWxlc2hlZXQgVVJMIHBhcmFtZXRlcgotICAgICAgKiBAcmV0dXJuIFN0cmluZyBmb3JtIG9mIHJlcXVlc3QgWFNMIFVSTCwgb3IgbnVsbCBpZiByZXF1ZXN0IGNvbnRhaW5zIG5vIHhzbFVSTCBwYXJhbWV0ZXIKLSAgICAgICogQGV4Y2VwdGlvbiBNYWxmb3JtZWRVUkxFeGNlcHRpb24gVGhyb3duIHdoZW4gcmVxdWVzdCBVUkwgaXMgbm90IGEgdmFsaWQgVVJMIG9yIHBhdGgKLSAgICAgICogQHNlZSAjdG9TYWZlVVJMCi0gICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0WFNMUmVxdWVzdFVSTChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgICB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uCi0gICAgewotCSAgICBVUkwgdXJsID0gdG9TYWZlVVJMKGdldFJlcXVlc3RQYXJtU3RyaW5nKHJlcXVlc3QsICJ4c2xVUkwiKSxyZXF1ZXN0KTsKLQkgICAgaWYgKHVybCA9PSBudWxsKQotCSAgICAgICAgcmV0dXJuIG51bGw7Ci0JICAgIHJldHVybiB1cmwudG9FeHRlcm5hbEZvcm0oKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGNvbnN0cmFpbmVkIHJlcXVlc3QgVVJMIGZvciB0aGUgWFNMIHN0eWxlc2hlZXQuCi0gICAgICAqIElmIHRoZXJlIGlzIG5vIHJlcXVlc3QgcGFyYW1ldGVyIGZvciB0aGUgWFNMIHN0eWxlc2hlZXQsIHJldHVybiB0aGUgY29uZmlndXJlZCBkZWZhdWx0LgotICAgICAgKiBAcGFyYW0gcmVxdWVzdCBNYXkgY29udGFpbiBhbiBYU0wgc3R5bGVzaGVldCBVUkwgcGFyYW1ldGVyCi0gICAgICAqIEByZXR1cm4gU3RyaW5nIGZvcm0gb2YgWFNMIFVSTAotICAgICAgKiBAZXhjZXB0aW9uIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBUaHJvd24gd2hlbiByZXF1ZXN0IFVSTCBpcyBub3QgYSB2YWxpZCBVUkwgb3IgcGF0aAotICAgICAgKiBAc2VlICN0b1NhZmVVUkwKLSAgICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRYU0x1cmwoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QpCi0gICAgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbgotICAgIHsKLQkgICAgU3RyaW5nIHJlcVVSTCA9IGdldFhTTFJlcXVlc3RVUkwocmVxdWVzdCk7Ci0JICAgIGlmIChyZXFVUkwgIT0gbnVsbCkKLQkgICAgICAgIHJldHVybiByZXFVUkw7Ci0JICAgIHJldHVybiBzdXBlci5nZXRYU0x1cmwobnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICAqIFJldHVybnMgVVJMcyBmb3IgYWxsIDxhIGhyZWY9Imh0dHA6Ly93d3cuY2NpbC5vcmcvfmNvd2FuL1hNTC9YQ2F0YWxvZy5odG1sIj5YQ2F0YWxvZ3M8L2E+IAotICAgICAgKiB0aGF0IGFyZSB0byBiZSB1c2VkIHRvIHByb2Nlc3MgdGhlIHJlcXVlc3QuICBDYXRhbG9ncyBhcmUgdXNlZCB0byByZXNvbHZlIFhNTCBwdWJsaWMgaWRlbnRpZmllcnMKLSAgICAgICogaW50byBzeXN0ZW0gaWRlbnRpZmllcnMuCi0gICAgICAqIDxwPkEgc2luZ2xlIFhDYXRhbG9nIGNhbiBiZSBjb25maWd1cmVkIGFzIGEgZGVmYXVsdCwKLSAgICAgICogYnV0IG11bHRpcGxlIFhDYXRhbG9ncyBjYW4gYmUgc3BlY2lmaWVkIGF0IHJlcXVlc3QgdGltZSB0byBhdWdtZW50IHRoZSBjb25maWd1cmVkIGRlZmF1bHQuCi0gICAgICAqIEBwYXJhbSByZXF1ZXN0IE1heSBjb250YWluIG9uZSBvciBtb3JlIFhDYXRhbG9nIHBhcmFtZXRlcnMKLSAgICAgICogQHJldHVybiBBcnJheSBvZiBzdHJpbmdzIGZvciBhbGwgY2F0YWxvZyBVUkxzCi0gICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDYXRhbG9nKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0KQotICAgIHsKLQkgICAgU3RyaW5nIHRlbXBbXSA9IHJlcXVlc3QuZ2V0UGFyYW1ldGVyVmFsdWVzKCJjYXRhbG9nIik7Ci0JICAgIGlmIChERUZBVUxUX2NhdGFsb2cgPT0gbnVsbCkKLQkgICAgICAgIHJldHVybiB0ZW1wOwotCSAgICBpZiAodGVtcCA9PSBudWxsKSAKLSAgICAgIHsKLQkgICAgICBTdHJpbmcgZGVmYXVsdEFycmF5W10gPSBuZXcgU3RyaW5nIFsxXTsKLQkgICAgICBkZWZhdWx0QXJyYXlbMF0gPSBERUZBVUxUX2NhdGFsb2c7Ci0JICAgICAgcmV0dXJuIGRlZmF1bHRBcnJheTsKLQkgICAgfQotCSAgICBpbnQgaSwgbGVuID0gdGVtcC5sZW5ndGggKyAxOwotCSAgICBTdHJpbmcgbmV3Q2F0YWxvZ3NbXSA9IG5ldyBTdHJpbmdbbGVuXTsKLQkgICAgbmV3Q2F0YWxvZ3NbMF0gPSBERUZBVUxUX2NhdGFsb2c7Ci0JICAgIGZvciAoaT0xOyBpIDwgbGVuOyBpKyspIAotICAgICAgewotCSAgICAgIG5ld0NhdGFsb2dzW2ldID0gdGVtcFtpLTFdOwotCSAgICB9Ci0JICAgIHJldHVybiBuZXdDYXRhbG9nczsKLSAgICB9Ci0JCi0JIC8qKgotICAgKiBJIHRoaW5rIHdlIG5vIGxvbmdlciBuZWVkIHRoaXMuIFNldHMgdGhlIDMgamF4cCBjb3JlIHN5c3RlbSBwcm9wZXJ0aWVzLgotICAgKi8JCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0U3lzdGVtUHJvcGVydGllcygpCi0JewotCSAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0gICAgcHJvcHMucHV0KCJqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSIsIAotICAgICAgICAgICAgICAib3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCIpOwotICAgIHByb3BzLnB1dCgiamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSIsIAotICAgICAgICAgICAgICAib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbCIpOwotICAgIHByb3BzLnB1dCgiamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSIsIAotICAgICAgICAgICAgICAib3JnLmFwYWNoZS54ZXJjZXMuamF4cC5TQVhQYXJzZXJGYWN0b3J5SW1wbCIpOwotICAgIAotICAgICAgUHJvcGVydGllcyBzeXN0ZW1Qcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7Ci0gICAgICBFbnVtZXJhdGlvbiBwcm9wRW51bSA9IHByb3BzLnByb3BlcnR5TmFtZXMoKTsKLSAgICAgIHdoaWxlKHByb3BFbnVtLmhhc01vcmVFbGVtZW50cygpKQotICAgICAgewotICAgICAgICBTdHJpbmcgcHJvcCA9IChTdHJpbmcpcHJvcEVudW0ubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgaWYoIXN5c3RlbVByb3BzLmNvbnRhaW5zS2V5KHByb3ApKQotICAgICAgICAgIHN5c3RlbVByb3BzLnB1dChwcm9wLCBwcm9wcy5nZXRQcm9wZXJ0eShwcm9wKSk7Ci0gICAgICB9Ci0gICAgICBTeXN0ZW0uc2V0UHJvcGVydGllcyhzeXN0ZW1Qcm9wcyk7Ci0JfQotCi19CmRpZmYgLS1naXQgYS9zYW1wbGVzL3NlcnZsZXQvU2ltcGxlWFNMVFNlcnZsZXQuamF2YSBiL3NhbXBsZXMvc2VydmxldC9TaW1wbGVYU0xUU2VydmxldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZWNlZmQ3Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvc2VydmxldC9TaW1wbGVYU0xUU2VydmxldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBzZXJ2bGV0OwotCi1pbXBvcnQgamF2YXguc2VydmxldC4qOwotaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC4qOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci0KLS8qCi0gKiBUaGlzIHNhbXBsZSBhcHBsaWVzIHRoZSB0b2RvLnhzbCBzdHlsZXNoZWV0IHRvIHRoZQotICogdG9kby54bWwgWE1MIGRvY3VtZW50LCBhbmQgcmV0dXJucyB0aGUgdHJhbnNmb3JtYXRpb24KLSAqIG91dHB1dCAoSFRNTCkgdG8gdGhlIGNsaWVudCBicm93c2VyLgotICoKLSAqIElNUE9SVEFOVDogRm9yIHRoaXMgdG8gd29yaywgeW91IG11c3QgcGxhY2UgdG9kby54c2wgYW5kIHRvZG8ueG1sIAotICogaW4gdGhlIHNlcnZsZXQgcm9vdCBkaXJlY3RvcnkgZm9yIGRvY3VtZW50cy4KLSAqCi0gKi8KLQotcHVibGljIGNsYXNzIFNpbXBsZVhTTFRTZXJ2bGV0IGV4dGVuZHMgSHR0cFNlcnZsZXQgewotCi0gIHB1YmxpYyB2b2lkIGluaXQoU2VydmxldENvbmZpZyBjb25maWcpIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5pbml0KGNvbmZpZyk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBkb0dldCAoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsCi0gICAgICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQotICAgIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBUaGUgc2VydmxldCByZXR1cm5zIEhUTUwuCi0gICAgcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIpOyAgICAKLSAgICAvLyBPdXRwdXQgZ29lcyBpbiB0aGUgcmVzcG9uc2Ugc3RyZWFtLgotICAgIFByaW50V3JpdGVyIG91dCA9IHJlc3BvbnNlLmdldFdyaXRlcigpOwotICAgIHRyeQotICAgIHsJCi0gICAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgIC8vIEdldCB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGFuZCB0aGUgc3R5bGVzaGVldC4KLSAgICAgIFNvdXJjZSB4bWxTb3VyY2UgPSBuZXcgU3RyZWFtU291cmNlKG5ldyBVUkwoImZpbGU6dG9kby54bWwiKS5vcGVuU3RyZWFtKCkpOwotICAgICAgU291cmNlIHhzbFNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UobmV3IFVSTCgiZmlsZTp0b2RvLnhzbCIpLm9wZW5TdHJlYW0oKSk7Ci0gICAgICAvLyBHZW5lcmF0ZSB0aGUgdHJhbnNmb3JtZXIuCi0gICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKHhzbFNvdXJjZSk7Ci0gICAgICAvLyBQZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbiwgc2VuZGluZyB0aGUgb3V0cHV0IHRvIHRoZSByZXNwb25zZS4KLSAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybSh4bWxTb3VyY2UsIG5ldyBTdHJlYW1SZXN1bHQob3V0KSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBvdXQud3JpdGUoZS5nZXRNZXNzYWdlKCkpOwotICAgICAgZS5wcmludFN0YWNrVHJhY2Uob3V0KTsgICAgCi0gICAgfQotICAgIG91dC5jbG9zZSgpOwotICB9Ci0gIAotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9zZXJ2bGV0L1VzZVN0eWxlc2hlZXRQYXJhbVNlcnZsZXQuamF2YSBiL3NhbXBsZXMvc2VydmxldC9Vc2VTdHlsZXNoZWV0UGFyYW1TZXJ2bGV0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFkZjk0NmYuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9zZXJ2bGV0L1VzZVN0eWxlc2hlZXRQYXJhbVNlcnZsZXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLQotLyoKLVNpbXBsZSBTZXJ2bGV0IEV4YW1wbGUgdXNpbmcgYSBzdHlsZXNoZWV0IHBhcmFtZXRlcgotICovCi1wYWNrYWdlIHNlcnZsZXQ7Ci0vLyBJbXBvcnRlZCBUcmFYIGNsYXNzZXMKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotLy8gSW1wb3J0ZWQgU0FYIGNsYXNzZXMKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLS8vIEltcG9ydGVkIGphdmEuaW8gYW5kIGphdmF4LnNlcnZsZXQgY2xhc3NlcwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZheC5zZXJ2bGV0Lio7Ci1pbXBvcnQgamF2YXguc2VydmxldC5odHRwLio7Ci0KLXB1YmxpYyBjbGFzcyBVc2VTdHlsZXNoZWV0UGFyYW1TZXJ2bGV0IGV4dGVuZHMgSHR0cFNlcnZsZXQgewotCQotCVByaW50V3JpdGVyIG91dDsKLQlTdHJpbmcgeHNsRmlsZSwgeG1sRmlsZSwgcGFyYW1WYWx1ZTsKLQlwdWJsaWMgdm9pZCBkb0dldChIdHRwU2VydmxldFJlcXVlc3QgcmVxLAotCQlIdHRwU2VydmxldFJlc3BvbnNlIHJlcykKLQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlyZXMuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIpOwotCQkJb3V0ID0gcmVzLmdldFdyaXRlcigpOwotCi0gICAgICBwYXJhbVZhbHVlID0gcmVxLmdldFBhcmFtZXRlcigiUFZBTCIpOwotCQkJeG1sRmlsZSAgICA9IHJlcS5nZXRQYXJhbWV0ZXIoIlhNTCIpOwotCQkJeHNsRmlsZSAgICA9IHJlcS5nZXRQYXJhbWV0ZXIoIlhTTCIpOwotIAkJaWYgKHBhcmFtVmFsdWUgPT0gbnVsbCkgewotCQkJb3V0LnByaW50bG4oCi0JCQkiPGgxPk5vIGlucHV0IGZvciBwYXJhbVZhbHVlPC9oMT4iKTsKLQkJCXJldHVybjsKLQkJfQotIAkJaWYgKCB4bWxGaWxlID09IG51bGwpIHsKLQkJCW91dC5wcmludGxuKAotCQkJIjxoMT5ObyBpbnB1dCBmb3IgeG1sRmlsZTwvaDE+Iik7Ci0JCQlyZXR1cm47Ci0JCX0JCi0JCWlmICggeHNsRmlsZSA9PSBudWxsKSB7Ci0JCQlvdXQucHJpbnRsbigKLQkJCSI8aDE+Tm8gaW5wdXQgZm9yIHhzbEZpbGU8L2gxPiIpOwotCQkJcmV0dXJuOwotCQl9Ci0JCVRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9Ci0JCQlUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQkJVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPQotCQkJdEZhY3RvcnkubmV3VHJhbnNmb3JtZXIobmV3IFN0cmVhbVNvdXJjZSh4c2xGaWxlKSk7Ci0KLSAgICAvLyBTZXQgdGhlIHN0eWxlc2hlZXQgcGFyYW1ldGVyIChuYW1lZCBwYXJhbTEpLgotCQkJdHJhbnNmb3JtZXIuc2V0UGFyYW1ldGVyKCJwYXJhbTEiLCBwYXJhbVZhbHVlKTsKLSAgICAvLyBQZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLQkJCXRyYW5zZm9ybWVyLnRyYW5zZm9ybShuZXcgU3RyZWFtU291cmNlKHhtbEZpbGUpLAotCQkJCQkgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KG91dCkpOwotCQl9CQkKLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewkJCQotCQkJZS5wcmludFN0YWNrVHJhY2UoKTsKLQkJCVN5c3RlbS5leGl0KC0xKTsKLQkJfQotCQljYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkgewotICAgICAgZS5wcmludFN0YWNrVHJhY2Uob3V0KTsKLQkJCXJldHVybjsKLQkJfQotCX0KLX0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvc2VydmxldC9YU0xUU2VydmxldFdpdGhQYXJhbXMuamF2YSBiL3NhbXBsZXMvc2VydmxldC9YU0xUU2VydmxldFdpdGhQYXJhbXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjQ2NjU2MC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3NlcnZsZXQvWFNMVFNlcnZsZXRXaXRoUGFyYW1zLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIHNlcnZsZXQ7Ci1pbXBvcnQgamF2YXguc2VydmxldC4qOwotaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC4qOwotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci0KLS8qCi0gKiBUaGlzIHNhbXBsZSB0YWtlcyBpbnB1dCBwYXJhbWV0ZXJzIGluIHRoZSByZXF1ZXN0IFVSTDogYSBVUkwKLSAqIHBhcmFtZXRlciBmb3IgdGhlIFhNTCBpbnB1dCwgYW4geHNsVVJMIHBhcmFtZXRlciBmb3IgdGhlIHN0eWxlc2hlZXQsCi0gKiBhbmQgb3B0aW9uYWwgc3R5bGVzaGVldCBwYXJhbWV0ZXJzLgotICogVG8gcnVuIHRoZSBlcXVpdmFsZW50IG9mIFNpbXBsZXN0WFNMU2VydmxldCAod2l0aCB0aGUgZG9jdW1lbnRzIGluIHRoZQotICogc2VydmxldCBkb2N1bWVudCByb290IGRpcmVjdG9yeSksIHRoZSByZXF1ZXN0IFVSTCBpcwotICogaHR0cDovLzxzZXJ2ZXIvc2VydmxldHBhdGg+c2VydmxldC5TaW1wbGVYU0xTZXJ2bGV0P1VSTD1maWxlOnRvZG8ueG1sJnhzbFVSTD1maWxlOnRvZG8ueHNsCi0gKgotICogVXNpbmcgYSBzdHlsZXNoZWV0IFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb246Ci0gKiBJZiB0aGUgWE1MIGRvY3VtZW50IGluY2x1ZGVzIGEgc3R5bGVzaGVldCBQSSB0aGF0IHlvdSB3YW50IHRvIHVzZSwgCi0gKiBvbWl0IHRoZSB4c2xVUkwgcGFyYW1ldGVyLgotICoKLSAqIFNlbmRpbmcgc3R5bGVzaGVldCBwYXJhbWV0ZXJzOiAKLSAqIElmLCBmb3IgZXhhbXBsZSwgYSBzZXJ2bGV0IHRha2VzIGEgc3R5bGVzaGVldCBwYXJhbWV0ZXIgbmFtZWQgcGFyYW0xCi0gKiBwYXJhbTEgdGhhdCB5b3Ugd2FudCB0byBzZXQgdG8gZm9vLCBpbmNsdWRlIHBhcmFtMT1mb28gaW4gdGhlIFVSTC4KLSAqLwotCi1wdWJsaWMgY2xhc3MgWFNMVFNlcnZsZXRXaXRoUGFyYW1zIGV4dGVuZHMgSHR0cFNlcnZsZXQgewotCi0gIHB1YmxpYyB2b2lkIGluaXQoU2VydmxldENvbmZpZyBjb25maWcpIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5pbml0KGNvbmZpZyk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBkb0dldCAoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsCi0gICAgICAgICAgICAgICAgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQotICAgIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgotICB7Ci0gICAgLy8gVGhlIHNlcnZsZXQgcmV0dXJucyBIVE1MOyBjaGFyc2V0IGlzIFVURjguCi0gICAgLy8gU2VlIEFwcGx5WFNMVC5nZXRDb250ZW50VHlwZSgpIHRvIGdldCBvdXRwdXQgcHJvcGVydGllcyBmcm9tIDx4c2w6b3V0cHV0Pi4KLSAgICByZXNwb25zZS5zZXRDb250ZW50VHlwZSgidGV4dC9odG1sOyBjaGFyc2V0PVVURi04Iik7IAotICAgIFByaW50V3JpdGVyIG91dCA9IHJlc3BvbnNlLmdldFdyaXRlcigpOwotICAgIHRyeQotICAgIHsJCi0gICAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgIC8vIEdldCBwYXJhbXMgZnJvbSBVUkwuCi0gICAgICBTdHJpbmcgeG1sID0gZ2V0UmVxdWVzdFBhcmFtKHJlcXVlc3QsICJVUkwiKTsKLSAgICAgIFN0cmluZyB4c2wgPSBnZXRSZXF1ZXN0UGFyYW0ocmVxdWVzdCwgInhzbFVSTCIpOwotICAgICAgU291cmNlIHhtbFNvdXJjZSA9IG51bGw7Ci0gICAgICBTb3VyY2UgeHNsU291cmNlID0gbnVsbDsKLSAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gbnVsbDsKLSAgICAgIC8vIEdldCB0aGUgWE1MIGlucHV0IGRvY3VtZW50LgotICAgICAgaWYgKHhtbCAhPSBudWxsICYmIHhtbC5sZW5ndGgoKT4gMCkKLSAgICAgICAgeG1sU291cmNlID0gbmV3IFN0cmVhbVNvdXJjZShuZXcgVVJMKHhtbCkub3BlblN0cmVhbSgpKTsKLSAgICAgIC8vIEdldCB0aGUgc3R5bGVzaGVldC4KLSAgICAgIGlmICh4c2wgIT0gbnVsbCAmJiB4c2wubGVuZ3RoKCk+IDApCi0gICAgICAgIHhzbFNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UobmV3IFVSTCh4c2wpLm9wZW5TdHJlYW0oKSk7Ci0gICAgICBpZiAoeG1sU291cmNlICE9IG51bGwpIC8vIFdlIGhhdmUgYW4gWE1MIGlucHV0IGRvY3VtZW50LgotICAgICAgewotICAgICAgICBpZiAoeHNsU291cmNlID09IG51bGwpIC8vIElmIG5vIHN0eWxlc2hlZXQsIGxvb2sgZm9yIFBJIGluIFhNTCBpbnB1dCBkb2N1bWVudC4KLSAgICAgICAgewotICAgICAJICAgIFN0cmluZyBtZWRpYT0gbnVsbCAsIHRpdGxlID0gbnVsbCwgY2hhcnNldCA9IG51bGw7Ci0gICAgICAgICAgeHNsU291cmNlID0gdEZhY3RvcnkuZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoeG1sU291cmNlLG1lZGlhLCB0aXRsZSwgY2hhcnNldCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKHhzbFNvdXJjZSAhPSBudWxsKSAvLyBOb3cgZG8gd2UgaGF2ZSBhIHN0eWxlc2hlZXQ/Ci0gICAgICAgIHsKLSAgICAgICAgICB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKHhzbFNvdXJjZSk7Ci0gICAgICAgICAgc2V0UGFyYW1ldGVycyh0cmFuc2Zvcm1lciwgcmVxdWVzdCk7IC8vIFNldCBzdHlsZXNoZWV0IHBhcmFtcy4KLSAgICAgICAgICAvLyBQZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oeG1sU291cmNlLCBuZXcgU3RyZWFtUmVzdWx0KG91dCkpOyAKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgb3V0LndyaXRlKCJObyBTdHlsZXNoZWV0ISIpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICBvdXQud3JpdGUoIk5vIFhNTCBJbnB1dCBEb2N1bWVudCEiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKG91dCk7ICAgIAotICAgIH0KLSAgICBvdXQuY2xvc2UoKTsKLSAgfQotICAKLSAgLy8gR2V0IHBhcmFtZXRlcnMgZnJvbSB0aGUgcmVxdWVzdCBVUkwuCi0gIFN0cmluZyBnZXRSZXF1ZXN0UGFyYW0oSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIFN0cmluZyBwYXJhbSkKLSAgewotCSAgaWYgKHJlcXVlc3QgIT0gbnVsbCkgCi0gICAgeyAKLQkgICAgU3RyaW5nIHBhcmFtVmFsID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIocGFyYW0pOyAKLQkJICByZXR1cm4gcGFyYW1WYWw7Ci0JICB9Ci0JICByZXR1cm4gbnVsbDsKLSAgfQotICAKLSAgLy8gU2V0IHN0eWxlc2hlZXQgcGFyYW1ldGVycyBmcm9tIHRoZSByZXF1ZXN0IFVSTC4KLSAgdm9pZCBzZXRQYXJhbWV0ZXJzKFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyLCBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKLSAgewotICAgIEVudW1lcmF0aW9uIHBhcmFtTmFtZXMgPSByZXF1ZXN0LmdldFBhcmFtZXRlck5hbWVzKCk7Ci0gICAgd2hpbGUgKHBhcmFtTmFtZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIHBhcmFtTmFtZSA9IChTdHJpbmcpIHBhcmFtTmFtZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBTdHJpbmcgcGFyYW1WYWwgPSByZXF1ZXN0LmdldFBhcmFtZXRlcihwYXJhbU5hbWUpOwotICAgICAgICBpZiAocGFyYW1WYWwgIT0gbnVsbCkKLSAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIocGFyYW1OYW1lLCBwYXJhbVZhbCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgIH0KLSAgICB9Ci0gIH0gIAotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9zZXJ2bGV0L2RlZmF1bHQueHNsIGIvc2FtcGxlcy9zZXJ2bGV0L2RlZmF1bHQueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMWE4NWUwLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvc2VydmxldC9kZWZhdWx0LnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDI3NiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tICBEZWZhdWx0IFhTTCBzdHlsZXNoZWV0IGZvciB1c2UgYnkgY29tLmxvdHVzLnhzbC5zZXJ2ZXIjRGVmYXVsdEFwcGx5WFNMLiAgICAgICAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSAgVGhpcyBzdHlsZXNoZWV0IG1pbWljcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBJRSB3aGVuIFhNTCBkYXRhIGlzIGRpc3BsYXllZCAgLS0+Ci08IS0tICB3aXRob3V0IGEgY29ycmVzcG9uZGluZyBYU0wgc3R5bGVzaGVldC4gIFRoaXMgc3R5bGVzaGVldCB1c2VzIEphdmFTY3JpcHQgICAgICAtLT4KLTwhLS0gIHRvIGFjY29tbW9kYXRlIG5vZGUgZXhwYW5zaW9uIGFuZCBjb250cmFjdGlvbi4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwIj4KLSAgICAgICAgICAgICAgICAKLTx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJubyIvPgotPHhzbDpzdHJpcC1zcGFjZSBlbGVtZW50cz0iKiIvPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgPEhUTUw+Ci0gICAgPEhFQUQ+Ci0gICAgICA8U1RZTEUgdHlwZT0idGV4dC9jc3MiPgotICAgICAgICBCT0RZIHtmb250Ongtc21hbGwgJ1ZlcmRhbmEnOyBtYXJnaW4tcmlnaHQ6MS41ZW19Ci0gICAgICA8IS0tIGNvbnRhaW5lciBmb3IgZXhwYW5kaW5nL2NvbGxhcHNpbmcgY29udGVudCAtLT4KLSAgICAgICAgLmMgIHtjdXJzb3I6aGFuZH0KLSAgICAgIDwhLS0gYnV0dG9uIC0gY29udGFpbnMgKy8tL25ic3AgLS0+Ci0gICAgICAgIC5iICB7Y29sb3I6cmVkOyBmb250LWZhbWlseTonQ291cmllciBOZXcnOyBmb250LXdlaWdodDpib2xkOyB0ZXh0LWRlY29yYXRpb246bm9uZX0KLSAgICAgIDwhLS0gZWxlbWVudCBjb250YWluZXIgLS0+Ci0gICAgICAgIC5lICB7bWFyZ2luLWxlZnQ6MWVtOyB0ZXh0LWluZGVudDotMWVtOyBtYXJnaW4tcmlnaHQ6MWVtfQotICAgICAgPCEtLSBjb21tZW50IG9yIGNkYXRhIC0tPgotICAgICAgICAuayAge21hcmdpbi1sZWZ0OjFlbTsgdGV4dC1pbmRlbnQ6LTFlbTsgbWFyZ2luLXJpZ2h0OjFlbX0KLSAgICAgIDwhLS0gdGFnIC0tPgotICAgICAgICAudCAge2NvbG9yOiM5OTAwMDB9Ci0gICAgICA8IS0tIHRhZyBpbiB4c2wgbmFtZXNwYWNlIC0tPgotICAgICAgICAueHQge2NvbG9yOiM5OTAwOTl9Ci0gICAgICA8IS0tIGF0dHJpYnV0ZSBpbiB4bWwgb3IgeG1sbnMgbmFtZXNwYWNlIC0tPgotICAgICAgICAubnMge2NvbG9yOnJlZH0KLSAgICAgIDwhLS0gbWFya3VwIGNoYXJhY3RlcnMgLS0+Ci0gICAgICAgIC5tICB7Y29sb3I6Ymx1ZX0KLSAgICAgIDwhLS0gdGV4dCBub2RlIC0tPgotICAgICAgICAudHgge2ZvbnQtd2VpZ2h0OmJvbGR9Ci0gICAgICA8IS0tIG11bHRpLWxpbmUgKGJsb2NrKSBjZGF0YSAtLT4KLSAgICAgICAgLmRiIHt0ZXh0LWluZGVudDowcHg7IG1hcmdpbi1sZWZ0OjFlbTsgbWFyZ2luLXRvcDowcHg7IG1hcmdpbi1ib3R0b206MHB4OwotICAgICAgICAgICAgIHBhZGRpbmctbGVmdDouM2VtOyBib3JkZXItbGVmdDoxcHggc29saWQgI0NDQ0NDQzsgZm9udDpzbWFsbCBDb3VyaWVyfQotICAgICAgPCEtLSBzaW5nbGUtbGluZSAoaW5saW5lKSBjZGF0YSAtLT4KLSAgICAgICAgLmRpIHtmb250OnNtYWxsIENvdXJpZXJ9Ci0gICAgICA8IS0tIERPQ1RZUEUgZGVjbGFyYXRpb24gLS0+Ci0gICAgICAgIC5kICB7Y29sb3I6Ymx1ZX0KLSAgICAgIDwhLS0gcGkgLS0+Ci0gICAgICAgIC5waSB7Y29sb3I6Ymx1ZX0KLSAgICAgIDwhLS0gbXVsdGktbGluZSAoYmxvY2spIGNvbW1lbnQgLS0+Ci0gICAgICAgIC5jYiB7dGV4dC1pbmRlbnQ6MHB4OyBtYXJnaW4tbGVmdDoxZW07IG1hcmdpbi10b3A6MHB4OyBtYXJnaW4tYm90dG9tOjBweDsKLSAgICAgICAgICAgICBwYWRkaW5nLWxlZnQ6LjNlbTsgZm9udDpzbWFsbCBDb3VyaWVyOyBjb2xvcjojODg4ODg4fQotICAgICAgPCEtLSBzaW5nbGUtbGluZSAoaW5saW5lKSBjb21tZW50IC0tPgotICAgICAgICAuY2kge2ZvbnQ6c21hbGwgQ291cmllcjsgY29sb3I6Izg4ODg4OH0KLSAgICAgICAgUFJFIHttYXJnaW46MHB4OyBkaXNwbGF5OmlubGluZX0KLSAgICAgIDwvU1RZTEU+Ci0KLSAgICAgIDxTQ1JJUFQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48eHNsOmNvbW1lbnQ+PCFbQ0RBVEFbCi0gICAgICAgIC8vIERldGVjdCBhbmQgc3dpdGNoIHRoZSBkaXNwbGF5IG9mIENEQVRBIGFuZCBjb21tZW50cyBmcm9tIGFuIGlubGluZSB2aWV3Ci0gICAgICAgIC8vICB0byBhIGJsb2NrIHZpZXcgaWYgdGhlIGNvbW1lbnQgb3IgQ0RBVEEgaXMgbXVsdGktbGluZS4KLSAgICAgICAgZnVuY3Rpb24gZihlKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gaWYgdGhpcyBlbGVtZW50IGlzIGFuIGlubGluZSBjb21tZW50LCBhbmQgY29udGFpbnMgbW9yZSB0aGFuIGEgc2luZ2xlCi0gICAgICAgICAgLy8gIGxpbmUsIHR1cm4gaXQgaW50byBhIGJsb2NrIGNvbW1lbnQuCi0gICAgICAgICAgaWYgKGUuY2xhc3NOYW1lID09ICJjaSIpIHsKLSAgICAgICAgICAgIGlmIChlLmNoaWxkcmVuKDApLmlubmVyVGV4dC5pbmRleE9mKCJcbiIpID4gMCkKLSAgICAgICAgICAgICAgZml4KGUsICJjYiIpOwotICAgICAgICAgIH0KLSAgICAgICAgICAKLSAgICAgICAgICAvLyBpZiB0aGlzIGVsZW1lbnQgaXMgYW4gaW5saW5lIGNkYXRhLCBhbmQgY29udGFpbnMgbW9yZSB0aGFuIGEgc2luZ2xlCi0gICAgICAgICAgLy8gIGxpbmUsIHR1cm4gaXQgaW50byBhIGJsb2NrIGNkYXRhLgotICAgICAgICAgIGlmIChlLmNsYXNzTmFtZSA9PSAiZGkiKSB7Ci0gICAgICAgICAgICBpZiAoZS5jaGlsZHJlbigwKS5pbm5lclRleHQuaW5kZXhPZigiXG4iKSA+IDApCi0gICAgICAgICAgICAgIGZpeChlLCAiZGIiKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgCi0gICAgICAgICAgLy8gcmVtb3ZlIHRoZSBpZCBzaW5jZSB3ZSBvbmx5IHVzZWQgaXQgZm9yIGNsZWFudXAKLSAgICAgICAgICBlLmlkID0gIiI7Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIC8vIEZpeCB1cCB0aGUgZWxlbWVudCBhcyBhICJibG9jayIgZGlzcGxheSBhbmQgZW5hYmxlIGV4cGFuZC9jb2xsYXBzZSBvbiBpdAotICAgICAgICBmdW5jdGlvbiBmaXgoZSwgY2wpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBjaGFuZ2UgdGhlIGNsYXNzIG5hbWUgYW5kIGRpc3BsYXkgdmFsdWUKLSAgICAgICAgICBlLmNsYXNzTmFtZSA9IGNsOwotICAgICAgICAgIGUuc3R5bGUuZGlzcGxheSA9ICJibG9jayI7Ci0gICAgICAgICAgCi0gICAgICAgICAgLy8gbWFyayB0aGUgY29tbWVudCBvciBjZGF0YSBkaXNwbGF5IGFzIGEgZXhwYW5kYWJsZSBjb250YWluZXIKLSAgICAgICAgICBqID0gZS5wYXJlbnRFbGVtZW50LmNoaWxkcmVuKDApOwotICAgICAgICAgIGouY2xhc3NOYW1lID0gImMiOwotCi0gICAgICAgICAgLy8gZmluZCB0aGUgKy8tIHN5bWJvbCBhbmQgbWFrZSBpdCB2aXNpYmxlIC0gdGhlIGR1bW15IGxpbmsgZW5hYmxlcyB0YWJiaW5nCi0gICAgICAgICAgayA9IGouY2hpbGRyZW4oMCk7Ci0gICAgICAgICAgay5zdHlsZS52aXNpYmlsaXR5ID0gInZpc2libGUiOwotICAgICAgICAgIGsuaHJlZiA9ICIjIjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIENoYW5nZSB0aGUgKy8tIHN5bWJvbCBhbmQgaGlkZSB0aGUgY2hpbGRyZW4uICBUaGlzIGZ1bmN0aW9uIHdvcmtzIG9uICJlbGVtZW50IgotICAgICAgICAvLyAgZGlzcGxheXMKLSAgICAgICAgZnVuY3Rpb24gY2goZSkKLSAgICAgICAgewotICAgICAgICAgIC8vIGZpbmQgdGhlICsvLSBzeW1ib2wKLSAgICAgICAgICBtYXJrID0gZS5jaGlsZHJlbigwKS5jaGlsZHJlbigwKTsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBpZiBpdCBpcyBhbHJlYWR5IGNvbGxhcHNlZCwgZXhwYW5kIGl0IGJ5IHNob3dpbmcgdGhlIGNoaWxkcmVuCi0gICAgICAgICAgaWYgKG1hcmsuaW5uZXJUZXh0ID09ICIrIikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtYXJrLmlubmVyVGV4dCA9ICItIjsKLSAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykKLSAgICAgICAgICAgICAgZS5jaGlsZHJlbihpKS5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKLSAgICAgICAgICB9Ci0gICAgICAgICAgCi0gICAgICAgICAgLy8gaWYgaXQgaXMgZXhwYW5kZWQsIGNvbGxhcHNlIGl0IGJ5IGhpZGluZyB0aGUgY2hpbGRyZW4KLSAgICAgICAgICBlbHNlIGlmIChtYXJrLmlubmVyVGV4dCA9PSAiLSIpCi0gICAgICAgICAgewotICAgICAgICAgICAgbWFyay5pbm5lclRleHQgPSAiKyI7Ci0gICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspCi0gICAgICAgICAgICAgIGUuY2hpbGRyZW4oaSkuc3R5bGUuZGlzcGxheT0ibm9uZSI7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgICAvLyBDaGFuZ2UgdGhlICsvLSBzeW1ib2wgYW5kIGhpZGUgdGhlIGNoaWxkcmVuLiAgVGhpcyBmdW5jdGlvbiB3b3JrIG9uICJjb21tZW50IgotICAgICAgICAvLyAgYW5kICJjZGF0YSIgZGlzcGxheXMKLSAgICAgICAgZnVuY3Rpb24gY2gyKGUpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBmaW5kIHRoZSArLy0gc3ltYm9sLCBhbmQgdGhlICJQUkUiIGVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgY29udGVudAotICAgICAgICAgIG1hcmsgPSBlLmNoaWxkcmVuKDApLmNoaWxkcmVuKDApOwotICAgICAgICAgIGNvbnRlbnRzID0gZS5jaGlsZHJlbigxKTsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBpZiBpdCBpcyBhbHJlYWR5IGNvbGxhcHNlZCwgZXhwYW5kIGl0IGJ5IHNob3dpbmcgdGhlIGNoaWxkcmVuCi0gICAgICAgICAgaWYgKG1hcmsuaW5uZXJUZXh0ID09ICIrIikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtYXJrLmlubmVyVGV4dCA9ICItIjsKLSAgICAgICAgICAgIC8vIHJlc3RvcmUgdGhlIGNvcnJlY3QgImJsb2NrIi8iaW5saW5lIiBkaXNwbGF5IHR5cGUgdG8gdGhlIFBSRQotICAgICAgICAgICAgaWYgKGNvbnRlbnRzLmNsYXNzTmFtZSA9PSAiZGIiIHx8IGNvbnRlbnRzLmNsYXNzTmFtZSA9PSAiY2IiKQotICAgICAgICAgICAgICBjb250ZW50cy5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKLSAgICAgICAgICAgIGVsc2UgY29udGVudHMuc3R5bGUuZGlzcGxheSA9ICJpbmxpbmUiOwotICAgICAgICAgIH0KLSAgICAgICAgICAKLSAgICAgICAgICAvLyBpZiBpdCBpcyBleHBhbmRlZCwgY29sbGFwc2UgaXQgYnkgaGlkaW5nIHRoZSBjaGlsZHJlbgotICAgICAgICAgIGVsc2UgaWYgKG1hcmsuaW5uZXJUZXh0ID09ICItIikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtYXJrLmlubmVyVGV4dCA9ICIrIjsKLSAgICAgICAgICAgIGNvbnRlbnRzLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgICAvLyBIYW5kbGUgYSBtb3VzZSBjbGljawotICAgICAgICBmdW5jdGlvbiBjbCgpCi0gICAgICAgIHsKLSAgICAgICAgICBlID0gd2luZG93LmV2ZW50LnNyY0VsZW1lbnQ7Ci0gICAgICAgICAgCi0gICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIGFyZSBoYW5kbGluZyBjbGlja3MgdXBvbiBleHBhbmRhYmxlIGNvbnRhaW5lciBlbGVtZW50cwotICAgICAgICAgIGlmIChlLmNsYXNzTmFtZSAhPSAiYyIpCi0gICAgICAgICAgewotICAgICAgICAgICAgZSA9IGUucGFyZW50RWxlbWVudDsKLSAgICAgICAgICAgIGlmIChlLmNsYXNzTmFtZSAhPSAiYyIpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZSA9IGUucGFyZW50RWxlbWVudDsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBjYWxsIHRoZSBjb3JyZWN0IGZ1bnRpb24gdG8gY2hhbmdlIHRoZSBjb2xsYXBzZS9leHBhbmQgc3RhdGUgYW5kIGRpc3BsYXkKLSAgICAgICAgICBpZiAoZS5jbGFzc05hbWUgPT0gImUiKQotICAgICAgICAgICAgY2goZSk7Ci0gICAgICAgICAgaWYgKGUuY2xhc3NOYW1lID09ICJrIikKLSAgICAgICAgICAgIGNoMihlKTsKLSAgICAgICAgfQotICAgICAgICAKLSAgICAgICAgLy8gRXJhc2UgYm9ndXMgbGluayBpbmZvIGZyb20gdGhlIHN0YXR1cyB3aW5kb3cKLSAgICAgICAgZnVuY3Rpb24gaCgpCi0gICAgICAgIHsKLSAgICAgICAgICB3aW5kb3cuc3RhdHVzPSIgIjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFNldCB0aGUgb25jbGljayBoYW5kbGVyCi0gICAgICAgIGRvY3VtZW50Lm9uY2xpY2sgPSBjbDsKLSAgICAgICAgCi0gICAgICBdXT4vLzwveHNsOmNvbW1lbnQ+PC9TQ1JJUFQ+Ci0gICAgPC9IRUFEPgotCi0gICAgPEJPRFkgY2xhc3M9InN0Ij48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9CT0RZPgotCi0gIDwvSFRNTD4KLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIFRlbXBsYXRlcyBmb3IgZWFjaCBub2RlIHR5cGUgZm9sbG93cy4gIFRoZSBvdXRwdXQgb2YgZWFjaCB0ZW1wbGF0ZSBoYXMgYSBzaW1pbGFyIHN0cnVjdHVyZQotICB0byBlbmFibGUgc2NyaXB0IHRvIHdhbGsgdGhlIHJlc3VsdCB0cmVlIGVhc2lseSBmb3IgaGFuZGxpbmcgdXNlciBpbnRlcmFjdGlvbi4gLS0+Ci0gIAotPCEtLSBUZW1wbGF0ZSBmb3IgcGlzIG5vdCBoYW5kbGVkIGVsc2V3aGVyZSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSI+Ci0gIDxESVYgY2xhc3M9ImUiPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPgotICA8U1BBTiBjbGFzcz0ibSI+Jmx0Oz88L1NQQU4+PFNQQU4gY2xhc3M9InBpIj48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPiA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvU1BBTj48U1BBTiBjbGFzcz0ibSI+PyZndDs8L1NQQU4+Ci0gIDwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gVGVtcGxhdGUgZm9yIHRoZSBYTUwgZGVjbGFyYXRpb24uICBOZWVkIGEgc2VwYXJhdGUgdGVtcGxhdGUgYmVjYXVzZSB0aGUgcHNldWRvLWF0dHJpYnV0ZXMKLSAgICBhcmUgYWN0dWFsbHkgZXhwb3NlZCBhcyBhdHRyaWJ1dGVzIGluc3RlYWQgb2YganVzdCBlbGVtZW50IGNvbnRlbnQsIGFzIGluIG90aGVyIHBpcyAKLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oJ3htbCcpIj4KLSAgPERJViBjbGFzcz0iZSI+Ci0gIDxTUEFOIGNsYXNzPSJiIj4mIzE2MDs8L1NQQU4+Ci0gIDxTUEFOIGNsYXNzPSJtIj4mbHQ7PzwvU1BBTj48U1BBTiBjbGFzcz0icGkiPnhtbCA8eHNsOmZvci1lYWNoIHNlbGVjdD0iQCoiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PSI8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPiIgPC94c2w6Zm9yLWVhY2g+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj4/Jmd0OzwvU1BBTj4KLSAgPC9ESVY+Ci08L3hzbDp0ZW1wbGF0ZT4KLS0tPgotCi08IS0tIFRlbXBsYXRlIGZvciBhdHRyaWJ1dGVzIG5vdCBoYW5kbGVkIGVsc2V3aGVyZSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IkAqIj48U1BBTiBjbGFzcz0idCI+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj49IjwvU1BBTj48Qj48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvQj48U1BBTiBjbGFzcz0ibSI+IjwvU1BBTj48L3hzbDp0ZW1wbGF0ZT4KLQotPCEtLSBUZW1wbGF0ZSBmb3IgYXR0cmlidXRlcyBpbiB0aGUgeG1sbnMgb3IgeG1sIG5hbWVzcGFjZQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iQHhtbG5zOip8QHhtbG5zfEB4bWw6KiI+PFNQQU4gY2xhc3M9Im5zIj4gPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PFNQQU4gY2xhc3M9Im0iPj0iPC9TUEFOPjxCIGNsYXNzPSJucyI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L0I+PFNQQU4gY2xhc3M9Im0iPiI8L1NQQU4+PC94c2w6dGVtcGxhdGU+Ci0tLT4KLQotPCEtLSBUZW1wbGF0ZSBmb3IgdGV4dCBub2RlcyAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InRleHQoKSI+Ci0gIDx4c2w6Y2hvb3NlPjx4c2w6d2hlbiB0ZXN0PSJuYW1lKC4pID0gJyNjZGF0YS1zZWN0aW9uJyI+PHhzbDpjYWxsLXRlbXBsYXRlIG5hbWU9ImNkYXRhIi8+PC94c2w6d2hlbj4KLSAgPHhzbDpvdGhlcndpc2U+PERJViBjbGFzcz0iZSI+Ci0gIDxTUEFOIGNsYXNzPSJiIj4mIzE2MDs8L1NQQU4+Ci0gIDxTUEFOIGNsYXNzPSJ0eCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L1NQQU4+Ci0gIDwvRElWPjwveHNsOm90aGVyd2lzZT48L3hzbDpjaG9vc2U+Ci08L3hzbDp0ZW1wbGF0ZT4KLSAgCi08IS0tIFRlbXBsYXRlIGZvciBjb21tZW50IG5vZGVzIC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29tbWVudCgpIj4KLSAgPERJViBjbGFzcz0iayI+Ci0gIDxTUEFOPjxBIGNsYXNzPSJiIiBvbmNsaWNrPSJyZXR1cm4gZmFsc2UiIG9uZm9jdXM9ImgoKSIgU1RZTEU9InZpc2liaWxpdHk6aGlkZGVuIj4tPC9BPiA8U1BBTiBjbGFzcz0ibSI+Jmx0OyEtLTwvU1BBTj48L1NQQU4+Ci0gIDxTUEFOIGlkPSJjbGVhbiIgY2xhc3M9ImNpIj48UFJFPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC9QUkU+PC9TUEFOPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPiA8U1BBTiBjbGFzcz0ibSI+LS0mZ3Q7PC9TUEFOPgotICA8U0NSSVBUPmYoY2xlYW4pOzwvU0NSSVBUPjwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gVGVtcGxhdGUgZm9yIGNkYXRhIG5vZGVzIC0tPgotPHhzbDp0ZW1wbGF0ZSBuYW1lPSJjZGF0YSI+Ci0gIDxESVYgY2xhc3M9ImsiPgotICA8U1BBTj48QSBjbGFzcz0iYiIgb25jbGljaz0icmV0dXJuIGZhbHNlIiBvbmZvY3VzPSJoKCkiIFNUWUxFPSJ2aXNpYmlsaXR5OmhpZGRlbiI+LTwvQT4gPFNQQU4gY2xhc3M9Im0iPiZsdDshW0NEQVRBWzwvU1BBTj48L1NQQU4+Ci0gIDxTUEFOIGlkPSJjbGVhbiIgY2xhc3M9ImRpIj48UFJFPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC9QUkU+PC9TUEFOPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPiA8U1BBTiBjbGFzcz0ibSI+XV0mZ3Q7PC9TUEFOPgotICA8U0NSSVBUPmYoY2xlYW4pOzwvU0NSSVBUPjwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gVGVtcGxhdGUgZm9yIGVsZW1lbnRzIG5vdCBoYW5kbGVkIGVsc2V3aGVyZSAobGVhZiBub2RlcykgLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoPSIqIj4KLSAgPERJViBjbGFzcz0iZSI+PERJViBTVFlMRT0ibWFyZ2luLWxlZnQ6MWVtO3RleHQtaW5kZW50Oi0yZW0iPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPgotICA8U1BBTiBjbGFzcz0ibSI+Jmx0OzwvU1BBTj48U1BBTiBjbGFzcz0idCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+IDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iQCoiLz48U1BBTiBjbGFzcz0ibSI+IC8mZ3Q7PC9TUEFOPgotICA8L0RJVj48L0RJVj4KLTwveHNsOnRlbXBsYXRlPgotICAKLTwhLS0gVGVtcGxhdGUgZm9yIGVsZW1lbnRzIHdpdGggY29tbWVudCwgcGkgYW5kL29yIGNkYXRhIGNoaWxkcmVuCi08eHNsOnRlbXBsYXRlIG1hdGNoPSIqW2NvbW1lbnQoKSBvciBwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkgb3IgY2RhdGEoKV0iPgotICA8RElWIGNsYXNzPSJlIj4KLSAgPERJViBjbGFzcz0iYyI+PEEgaHJlZj0iIyIgb25jbGljaz0icmV0dXJuIGZhbHNlIiBvbmZvY3VzPSJoKCkiIGNsYXNzPSJiIj4tPC9BPiA8U1BBTiBjbGFzcz0ibSI+Jmx0OzwvU1BBTj48U1BBTj48eHNsOmF0dHJpYnV0ZSBuYW1lPSJjbGFzcyI+PHhzbDppZiB0ZXN0PSJ4c2w6KiI+eDwveHNsOmlmPnQ8L3hzbDphdHRyaWJ1dGU+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJAKiIvPiA8U1BBTiBjbGFzcz0ibSI+Jmd0OzwvU1BBTj48L0RJVj4KLSAgPERJVj48eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDxESVY+PFNQQU4gY2xhc3M9ImIiPiYjMTYwOzwvU1BBTj4gPFNQQU4gY2xhc3M9Im0iPiZsdDsvPC9TUEFOPjxTUEFOPjx4c2w6YXR0cmlidXRlIG5hbWU9ImNsYXNzIj48eHNsOmlmIHRlc3Q9InhzbDoqIj54PC94c2w6aWY+dDwveHNsOmF0dHJpYnV0ZT48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPjwvU1BBTj48U1BBTiBjbGFzcz0ibSI+Jmd0OzwvU1BBTj48L0RJVj4KLSAgPC9ESVY+PC9ESVY+Ci08L3hzbDp0ZW1wbGF0ZT4gLS0+Ci0KLTwhLS0gVGVtcGxhdGUgZm9yIGVsZW1lbnRzIHdpdGggb25seSB0ZXh0IGNoaWxkcmVuIC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iKlt0ZXh0KCkgYW5kIG5vdChjb21tZW50KCkgb3IgcHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpIG9yICopXSI+Ci0gIDxESVYgY2xhc3M9ImUiPjxESVYgU1RZTEU9Im1hcmdpbi1sZWZ0OjFlbTt0ZXh0LWluZGVudDotMmVtIj4KLSAgPFNQQU4gY2xhc3M9ImIiPiYjMTYwOzwvU1BBTj4gPFNQQU4gY2xhc3M9Im0iPiZsdDs8L1NQQU4+PFNQQU4gY2xhc3M9InQiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PC9TUEFOPjx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iQCoiLz4KLSAgPFNQQU4gY2xhc3M9Im0iPiZndDs8L1NQQU4+PFNQQU4gY2xhc3M9InR4Ij48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvU1BBTj48U1BBTiBjbGFzcz0ibSI+Jmx0Oy88L1NQQU4+PFNQQU4gY2xhc3M9InQiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj4mZ3Q7PC9TUEFOPgotICA8L0RJVj48L0RJVj4KLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIFRlbXBsYXRlIGZvciBlbGVtZW50cyB3aXRoIGVsZW1lbnQgY2hpbGRyZW4gLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoPSIqWypdIj4KLSAgPERJViBjbGFzcz0iZSI+Ci0gIDxESVYgY2xhc3M9ImMiIFNUWUxFPSJtYXJnaW4tbGVmdDoxZW07dGV4dC1pbmRlbnQ6LTJlbSI+PEEgaHJlZj0iIyIgb25jbGljaz0icmV0dXJuIGZhbHNlIiBvbmZvY3VzPSJoKCkiIGNsYXNzPSJiIj4tPC9BPiA8U1BBTiBjbGFzcz0ibSI+Jmx0OzwvU1BBTj48U1BBTiBjbGFzcz0idCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJAKiIvPjxTUEFOIGNsYXNzPSJtIj4mZ3Q7PC9TUEFOPjwvRElWPgotICA8RElWPjx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgPERJVj48U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj4mbHQ7LzwvU1BBTj48U1BBTiBjbGFzcz0idCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PFNQQU4gY2xhc3M9Im0iPiZndDs8L1NQQU4+PC9ESVY+Ci0gIDwvRElWPjwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9zZXJ2bGV0L2RlZmF1bHQyLnhzbCBiL3NhbXBsZXMvc2VydmxldC9kZWZhdWx0Mi54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE2MTlmM2YuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9zZXJ2bGV0L2RlZmF1bHQyLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDE1MiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tICBEZWZhdWx0IFhTTCBzdHlsZXNoZWV0IGZvciB1c2UgYnkgY29tLmxvdHVzLnhzbC5zZXJ2ZXIjRGVmYXVsdEFwcGx5WFNMLiAgICAgICAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSAgVGhpcyBzdHlsZXNoZWV0IG1pbWljcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBJRSB3aGVuIFhNTCBkYXRhIGlzIGRpc3BsYXllZCAgLS0+Ci08IS0tICB3aXRob3V0IGEgY29ycmVzcG9uZGluZyBYU0wgc3R5bGVzaGVldC4gIFRoaXMgc3R5bGVzaGVldCB1c2VzIG5vIEphdmFTY3JpcHQgICAtLT4KLTwhLS0gIGFuZCBkaXNwbGF5cyBhbGwgbm9kZXMgYXMgZnVsbHkgZXhwYW5kZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci0KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwIj4KLSAgICAgICAgICAgICAgICAKLTx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJubyIvPgotPHhzbDpzdHJpcC1zcGFjZSBlbGVtZW50cz0iKiIvPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgPEhUTUw+Ci0gICAgPEhFQUQ+Ci0gICAgICA8U1RZTEUgdHlwZT0idGV4dC9jc3MiPgotICAgICAgICBCT0RZIHtmb250Ongtc21hbGwgJ1ZlcmRhbmEnOyBtYXJnaW4tcmlnaHQ6MS41ZW19Ci0gICAgICA8IS0tIGNvbnRhaW5lciBmb3IgZXhwYW5kaW5nL2NvbGxhcHNpbmcgY29udGVudCAtLT4KLSAgICAgICAgLmMgIHtjdXJzb3I6aGFuZH0KLSAgICAgIDwhLS0gYnV0dG9uIC0gY29udGFpbnMgKy8tL25ic3AgLS0+Ci0gICAgICAgIC5iICB7Y29sb3I6cmVkOyBmb250LWZhbWlseTonQ291cmllciBOZXcnOyBmb250LXdlaWdodDpib2xkOyB0ZXh0LWRlY29yYXRpb246bm9uZX0KLSAgICAgIDwhLS0gZWxlbWVudCBjb250YWluZXIgLS0+Ci0gICAgICAgIC5lICB7bWFyZ2luLWxlZnQ6MWVtOyB0ZXh0LWluZGVudDotMWVtOyBtYXJnaW4tcmlnaHQ6MWVtfQotICAgICAgPCEtLSBjb21tZW50IG9yIGNkYXRhIC0tPgotICAgICAgICAuayAge21hcmdpbi1sZWZ0OjFlbTsgdGV4dC1pbmRlbnQ6LTFlbTsgbWFyZ2luLXJpZ2h0OjFlbX0KLSAgICAgIDwhLS0gdGFnIC0tPgotICAgICAgICAudCAge2NvbG9yOiM5OTAwMDB9Ci0gICAgICA8IS0tIHRhZyBpbiB4c2wgbmFtZXNwYWNlIC0tPgotICAgICAgICAueHQge2NvbG9yOiM5OTAwOTl9Ci0gICAgICA8IS0tIGF0dHJpYnV0ZSBpbiB4bWwgb3IgeG1sbnMgbmFtZXNwYWNlIC0tPgotICAgICAgICAubnMge2NvbG9yOnJlZH0KLSAgICAgIDwhLS0gbWFya3VwIGNoYXJhY3RlcnMgLS0+Ci0gICAgICAgIC5tICB7Y29sb3I6Ymx1ZX0KLSAgICAgIDwhLS0gdGV4dCBub2RlIC0tPgotICAgICAgICAudHgge2ZvbnQtd2VpZ2h0OmJvbGR9Ci0gICAgICA8IS0tIG11bHRpLWxpbmUgKGJsb2NrKSBjZGF0YSAtLT4KLSAgICAgICAgLmRiIHt0ZXh0LWluZGVudDowcHg7IG1hcmdpbi1sZWZ0OjFlbTsgbWFyZ2luLXRvcDowcHg7IG1hcmdpbi1ib3R0b206MHB4OwotICAgICAgICAgICAgIHBhZGRpbmctbGVmdDouM2VtOyBib3JkZXItbGVmdDoxcHggc29saWQgI0NDQ0NDQzsgZm9udDpzbWFsbCBDb3VyaWVyfQotICAgICAgPCEtLSBzaW5nbGUtbGluZSAoaW5saW5lKSBjZGF0YSAtLT4KLSAgICAgICAgLmRpIHtmb250OnNtYWxsIENvdXJpZXJ9Ci0gICAgICA8IS0tIERPQ1RZUEUgZGVjbGFyYXRpb24gLS0+Ci0gICAgICAgIC5kICB7Y29sb3I6Ymx1ZX0KLSAgICAgIDwhLS0gcGkgLS0+Ci0gICAgICAgIC5waSB7Y29sb3I6Ymx1ZX0KLSAgICAgIDwhLS0gbXVsdGktbGluZSAoYmxvY2spIGNvbW1lbnQgLS0+Ci0gICAgICAgIC5jYiB7dGV4dC1pbmRlbnQ6MHB4OyBtYXJnaW4tbGVmdDoxZW07IG1hcmdpbi10b3A6MHB4OyBtYXJnaW4tYm90dG9tOjBweDsKLSAgICAgICAgICAgICBwYWRkaW5nLWxlZnQ6LjNlbTsgZm9udDpzbWFsbCBDb3VyaWVyOyBjb2xvcjojODg4ODg4fQotICAgICAgPCEtLSBzaW5nbGUtbGluZSAoaW5saW5lKSBjb21tZW50IC0tPgotICAgICAgICAuY2kge2ZvbnQ6c21hbGwgQ291cmllcjsgY29sb3I6Izg4ODg4OH0KLSAgICAgICAgUFJFIHttYXJnaW46MHB4OyBkaXNwbGF5OmlubGluZX0KLSAgICAgIDwvU1RZTEU+Ci0gICAgPC9IRUFEPgotCi0gICAgPEJPRFkgY2xhc3M9InN0Ij48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9CT0RZPgotCi0gIDwvSFRNTD4KLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIFRlbXBsYXRlcyBmb3IgZWFjaCBub2RlIHR5cGUgZm9sbG93cy4gIFRoZSBvdXRwdXQgb2YgZWFjaCB0ZW1wbGF0ZSBoYXMgYSBzaW1pbGFyIHN0cnVjdHVyZQotICB0byBlbmFibGUgc2NyaXB0IHRvIHdhbGsgdGhlIHJlc3VsdCB0cmVlIGVhc2lseSBmb3IgaGFuZGxpbmcgdXNlciBpbnRlcmFjdGlvbi4gLS0+Ci0gIAotPCEtLSBUZW1wbGF0ZSBmb3IgcGlzIG5vdCBoYW5kbGVkIGVsc2V3aGVyZSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSI+Ci0gIDxESVYgY2xhc3M9ImUiPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPgotICA8U1BBTiBjbGFzcz0ibSI+Jmx0Oz88L1NQQU4+PFNQQU4gY2xhc3M9InBpIj48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPiA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvU1BBTj48U1BBTiBjbGFzcz0ibSI+PyZndDs8L1NQQU4+Ci0gIDwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gVGVtcGxhdGUgZm9yIHRoZSBYTUwgZGVjbGFyYXRpb24uICBOZWVkIGEgc2VwYXJhdGUgdGVtcGxhdGUgYmVjYXVzZSB0aGUgcHNldWRvLWF0dHJpYnV0ZXMKLSAgICBhcmUgYWN0dWFsbHkgZXhwb3NlZCBhcyBhdHRyaWJ1dGVzIGluc3RlYWQgb2YganVzdCBlbGVtZW50IGNvbnRlbnQsIGFzIGluIG90aGVyIHBpcyAKLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oJ3htbCcpIj4KLSAgPERJViBjbGFzcz0iZSI+Ci0gIDxTUEFOIGNsYXNzPSJiIj4mIzE2MDs8L1NQQU4+Ci0gIDxTUEFOIGNsYXNzPSJtIj4mbHQ7PzwvU1BBTj48U1BBTiBjbGFzcz0icGkiPnhtbCA8eHNsOmZvci1lYWNoIHNlbGVjdD0iQCoiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PSI8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPiIgPC94c2w6Zm9yLWVhY2g+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj4/Jmd0OzwvU1BBTj4KLSAgPC9ESVY+Ci08L3hzbDp0ZW1wbGF0ZT4KLS0tPgotCi08IS0tIFRlbXBsYXRlIGZvciBhdHRyaWJ1dGVzIG5vdCBoYW5kbGVkIGVsc2V3aGVyZSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IkAqIj48U1BBTiBjbGFzcz0idCI+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj49IjwvU1BBTj48Qj48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvQj48U1BBTiBjbGFzcz0ibSI+IjwvU1BBTj48L3hzbDp0ZW1wbGF0ZT4KLQotPCEtLSBUZW1wbGF0ZSBmb3IgYXR0cmlidXRlcyBpbiB0aGUgeG1sbnMgb3IgeG1sIG5hbWVzcGFjZQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iQHhtbG5zOip8QHhtbG5zfEB4bWw6KiI+PFNQQU4gY2xhc3M9Im5zIj4gPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PFNQQU4gY2xhc3M9Im0iPj0iPC9TUEFOPjxCIGNsYXNzPSJucyI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L0I+PFNQQU4gY2xhc3M9Im0iPiI8L1NQQU4+PC94c2w6dGVtcGxhdGU+Ci0tLT4KLQotPCEtLSBUZW1wbGF0ZSBmb3IgdGV4dCBub2RlcyAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InRleHQoKSI+Ci0gIDx4c2w6Y2hvb3NlPjx4c2w6d2hlbiB0ZXN0PSJuYW1lKC4pID0gJyNjZGF0YS1zZWN0aW9uJyI+PHhzbDpjYWxsLXRlbXBsYXRlIG5hbWU9ImNkYXRhIi8+PC94c2w6d2hlbj4KLSAgPHhzbDpvdGhlcndpc2U+PERJViBjbGFzcz0iZSI+Ci0gIDxTUEFOIGNsYXNzPSJiIj4mIzE2MDs8L1NQQU4+Ci0gIDxTUEFOIGNsYXNzPSJ0eCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L1NQQU4+Ci0gIDwvRElWPjwveHNsOm90aGVyd2lzZT48L3hzbDpjaG9vc2U+Ci08L3hzbDp0ZW1wbGF0ZT4KLSAgCi08IS0tIFRlbXBsYXRlIGZvciBjb21tZW50IG5vZGVzIC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iY29tbWVudCgpIj4KLSAgPERJViBjbGFzcz0iayI+Ci0gIDxTUEFOPjxTUEFOIGNsYXNzPSJiIiBTVFlMRT0idmlzaWJpbGl0eTpoaWRkZW4iPi08L1NQQU4+IDxTUEFOIGNsYXNzPSJtIj4mbHQ7IS0tPC9TUEFOPjwvU1BBTj4KLSAgPFNQQU4gY2xhc3M9ImNiIj48UFJFPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC9QUkU+PC9TUEFOPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPiA8U1BBTiBjbGFzcz0ibSI+LS0mZ3Q7PC9TUEFOPgotICA8L0RJVj4KLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIFRlbXBsYXRlIGZvciBjZGF0YSBub2RlcyAtLT4KLTx4c2w6dGVtcGxhdGUgbmFtZT0iY2RhdGEiPgotICA8RElWIGNsYXNzPSJrIj4KLSAgPFNQQU4+PFNQQU4gY2xhc3M9ImIiIFNUWUxFPSJ2aXNpYmlsaXR5OmhpZGRlbiI+LTwvU1BBTj4gPFNQQU4gY2xhc3M9Im0iPiZsdDshW0NEQVRBWzwvU1BBTj48L1NQQU4+Ci0gIDxTUEFOIGNsYXNzPSJkYiI+PFBSRT48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvUFJFPjwvU1BBTj4KLSAgPFNQQU4gY2xhc3M9ImIiPiYjMTYwOzwvU1BBTj4gPFNQQU4gY2xhc3M9Im0iPl1dJmd0OzwvU1BBTj4KLSAgPC9ESVY+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPCEtLSBUZW1wbGF0ZSBmb3IgZWxlbWVudHMgbm90IGhhbmRsZWQgZWxzZXdoZXJlIChsZWFmIG5vZGVzKSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IioiPgotICA8RElWIGNsYXNzPSJlIj48RElWIFNUWUxFPSJtYXJnaW4tbGVmdDoxZW07dGV4dC1pbmRlbnQ6LTJlbSI+Ci0gIDxTUEFOIGNsYXNzPSJiIj4mIzE2MDs8L1NQQU4+Ci0gIDxTUEFOIGNsYXNzPSJtIj4mbHQ7PC9TUEFOPjxTUEFOIGNsYXNzPSJ0Ij48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPjwvU1BBTj4gPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJAKiIvPjxTUEFOIGNsYXNzPSJtIj4gLyZndDs8L1NQQU4+Ci0gIDwvRElWPjwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0gIAotPCEtLSBUZW1wbGF0ZSBmb3IgZWxlbWVudHMgd2l0aCBjb21tZW50LCBwaSBhbmQvb3IgY2RhdGEgY2hpbGRyZW4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IipbY29tbWVudCgpIG9yIHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSBvciBjZGF0YSgpXSI+Ci0gIDxESVYgY2xhc3M9ImUiPgotICA8RElWIGNsYXNzPSJjIj48QSBocmVmPSIjIiBvbmNsaWNrPSJyZXR1cm4gZmFsc2UiIG9uZm9jdXM9ImgoKSIgY2xhc3M9ImIiPi08L0E+IDxTUEFOIGNsYXNzPSJtIj4mbHQ7PC9TUEFOPjxTUEFOPjx4c2w6YXR0cmlidXRlIG5hbWU9ImNsYXNzIj48eHNsOmlmIHRlc3Q9InhzbDoqIj54PC94c2w6aWY+dDwveHNsOmF0dHJpYnV0ZT48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPjwvU1BBTj48eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IkAqIi8+IDxTUEFOIGNsYXNzPSJtIj4mZ3Q7PC9TUEFOPjwvRElWPgotICA8RElWPjx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgPERJVj48U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPiA8U1BBTiBjbGFzcz0ibSI+Jmx0Oy88L1NQQU4+PFNQQU4+PHhzbDphdHRyaWJ1dGUgbmFtZT0iY2xhc3MiPjx4c2w6aWYgdGVzdD0ieHNsOioiPng8L3hzbDppZj50PC94c2w6YXR0cmlidXRlPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj4mZ3Q7PC9TUEFOPjwvRElWPgotICA8L0RJVj48L0RJVj4KLTwveHNsOnRlbXBsYXRlPiAtLT4KLQotPCEtLSBUZW1wbGF0ZSBmb3IgZWxlbWVudHMgd2l0aCBvbmx5IHRleHQgY2hpbGRyZW4gLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoPSIqW3RleHQoKSBhbmQgbm90KGNvbW1lbnQoKSBvciBwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkgb3IgKildIj4KLSAgPERJViBjbGFzcz0iZSI+PERJViBTVFlMRT0ibWFyZ2luLWxlZnQ6MWVtO3RleHQtaW5kZW50Oi0yZW0iPgotICA8U1BBTiBjbGFzcz0iYiI+JiMxNjA7PC9TUEFOPiA8U1BBTiBjbGFzcz0ibSI+Jmx0OzwvU1BBTj48U1BBTiBjbGFzcz0idCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJAKiIvPgotICA8U1BBTiBjbGFzcz0ibSI+Jmd0OzwvU1BBTj48U1BBTiBjbGFzcz0idHgiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC9TUEFOPjxTUEFOIGNsYXNzPSJtIj4mbHQ7LzwvU1BBTj48U1BBTiBjbGFzcz0idCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PFNQQU4gY2xhc3M9Im0iPiZndDs8L1NQQU4+Ci0gIDwvRElWPjwvRElWPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gVGVtcGxhdGUgZm9yIGVsZW1lbnRzIHdpdGggZWxlbWVudCBjaGlsZHJlbiAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9IipbKl0iPgotICA8RElWIGNsYXNzPSJlIj4KLSAgPERJViBjbGFzcz0iYyIgU1RZTEU9Im1hcmdpbi1sZWZ0OjFlbTt0ZXh0LWluZGVudDotMmVtIj48U1BBTiBjbGFzcz0iYiI+LTwvU1BBTj48U1BBTiBjbGFzcz0ibSI+Jmx0OzwvU1BBTj48U1BBTiBjbGFzcz0idCI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Im5hbWUoLikiLz48L1NQQU4+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJAKiIvPiA8U1BBTiBjbGFzcz0ibSI+Jmd0OzwvU1BBTj48L0RJVj4KLSAgPERJVj48eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDxESVY+PFNQQU4gY2xhc3M9ImIiPiYjMTYwOzwvU1BBTj4gPFNQQU4gY2xhc3M9Im0iPiZsdDsvPC9TUEFOPjxTUEFOIGNsYXNzPSJ0Ij48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPjwvU1BBTj48U1BBTiBjbGFzcz0ibSI+Jmd0OzwvU1BBTj48L0RJVj4KLSAgPC9ESVY+PC9ESVY+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3NlcnZsZXQvZm9vcGFyYW0ueG1sIGIvc2FtcGxlcy9zZXJ2bGV0L2Zvb3BhcmFtLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDNjMzJiNS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3NlcnZsZXQvZm9vcGFyYW0ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTxkb2M+SGVsbG88L2RvYz4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvc2VydmxldC9mb29wYXJhbS54c2wgYi9zYW1wbGVzL3NlcnZsZXQvZm9vcGFyYW0ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNGQwZmNlLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvc2VydmxldC9mb29wYXJhbS54c2wKKysrIC9kZXYvbnVsbApAQCAtMSwxNSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4gCi08eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIHZlcnNpb249IjEuMCI+Ci0gIDx4c2w6cGFyYW0gbmFtZT0icGFyYW0xIiBzZWxlY3Q9IidkZWZhdWx0IHZhbHVlJyIvPgotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJkb2MiPgotICAgIDxodG1sPgotICAgICAgPGhlYWQ+PHRpdGxlPlN0eWxlc2hlZXQgcGFyYW1ldGVyPC90aXRsZT48L2hlYWQ+Ci0gICAgICA8Ym9keT4KLSAgICAgICAgPGgyPlhNTCBzb3VyY2U8L2gyPgotICAgICAgICAgIDxwPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC9wPgotICAgICAgICA8aDI+U3R5bGVzaGVldCBwYXJhbWV0ZXI8L2gyPgotICAgICAgICAgIDxwPlRoZSBwYXJhbTEgc3R5bGVzaGVldCBwYXJhbWV0ZXIgaGFzIGJlZW4gc2V0IHRvIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIkcGFyYW0xIi8+LjwvcD4KLSAgICAgIDwvYm9keT4KLSAgICAgPC9odG1sPiAgICAgICAgICAKLSAgPC94c2w6dGVtcGxhdGU+Ci08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9zZXJ2bGV0L2pzcFNhbXBsZS5qc3AgYi9zYW1wbGVzL3NlcnZsZXQvanNwU2FtcGxlLmpzcApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzczOTMwYy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3NlcnZsZXQvanNwU2FtcGxlLmpzcAorKysgL2Rldi9udWxsCkBAIC0xLDQyICswLDAgQEAKLTwlQCBwYWdlIGxhbmd1YWdlPSJqYXZhIiBjb250ZW50VHlwZT0idGV4dC9odG1sIiAlPgotPCVAIHBhZ2UgaW1wb3J0PSJqYXZheC54bWwudHJhbnNmb3JtLioiJT4KLTwlQCBwYWdlIGltcG9ydD0iamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uKiIlPgotPGh0bWw+Ci08aGVhZD4KLTx0aXRsZT5KU1Agc2FtcGxlIHBhc3NpbmcgYSBwYXJhbWV0ZXIgdG8gWFNMPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPCUKLS8qKgotICogVGhpcyBKU1AgdXNlcyBQTUEgdG8gc2V0IHBhcmFtMSBpbiB0aGUKLSogIGZvby54c2wgc3R5bGVzaGVldCBiZWZvcmUgdXNpbmcgdGhlCi0gKiBzdHlsZXNoZWV0IHRvIHRyYW5zZm9ybSBmb28ueG1sCi0gKiBhbmQgb3V0cHV0aW5nIHRoZSByZXN1bHQuCi0gKgotICogSW52b2tlIHRoZSBqc3AgZnJvbSB0aGUgYXBwcm9wcmlhdGUKLSAqIGNvbnRleHQgZm9yIHlvdXIgc2VydmxldC9qc3Agc2VydmVyLgotICogRm9yIGV4YW1wbGU6IGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9zYW1wbGVzL2pzcFNhbXBsZS5qc3A/SGVsbG93V29ybGQhJlhNTD1mb28ueG1sJlhTTD1mb28ueHNsCi0gKiBUaGlzIGV4YW1wbGUgYXNzdW1lcyB0aGF0IGZvby54c2wgYW5kIGZvby54bWwKLSAqIGFyZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuIAotICogT3V0cHV0IHNob3VsZCBiZSBIZWxsbyAoZnJvbSBmb28ueHNtbCkgYW5kIEhlbGxvV29ybGQhCi0gKiAodmFsdWUgb2YgcGFyYW0xIGluIGZvby54c2wpLgotCi0gKkBhdXRob3IgUGF1bCBDYW1wYmVsbCBzZWFwd2NAaGFsY3lvbi5jb20KLSAqQHZlcnNpb24gJElkJAotICovCi0gCi0KLVN0cmluZyBwYXJhbVZhbHVlID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIoIlBNQSIpOwotU3RyaW5nIHhtbEZpbGUgICAgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigiWE1MIik7Ci1TdHJpbmcgeHNsRmlsZSAgICA9IHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJYU0wiKTsKLQotVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5ID0gCi0JVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci1UcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9Ci0JdEZhY3RvcnkubmV3VHJhbnNmb3JtZXIobmV3IFN0cmVhbVNvdXJjZSh4c2xGaWxlKSk7Ci0JdHJhbnNmb3JtZXIuc2V0UGFyYW1ldGVyKCJwYXJhbTEiLCBwYXJhbVZhbHVlKTsKLQl0cmFuc2Zvcm1lci50cmFuc2Zvcm0oCi0JCSBuZXcgU3RyZWFtU291cmNlKHhtbEZpbGUpLCBuZXcgU3RyZWFtUmVzdWx0KG91dCkpOwotJT4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvc2VydmxldC9tZWRpYS5wcm9wZXJ0aWVzIGIvc2FtcGxlcy9zZXJ2bGV0L21lZGlhLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFiM2NmNDUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy9zZXJ2bGV0L21lZGlhLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSw0MCArMCwwIEBACi0jIFRoaXMgcHJvcGVydHkgZmlsZSBpcyB1c2VkIGJ5IGNvbS5sb3R1cy54c2wuc2VydmVyLkRlZmF1bHRBcHBseVhTTC4KLSMKLSMgRWFjaCBsaW5lIGJlbG93IHNwZWNpZmllcyBhIG1hcHBpbmcgcnVsZSBiZXR3ZWVuIGEgdmFsdWUgY29udGFpbmVkIGluIHRoZSBIVFRQIHJlcXVlc3QncyB1c2VyLUFnZW50IAotIyBmaWVsZCBhbmQgYSB2YWx1ZSB0byBiZSBzY2FubmVkIGZvciBpbiBYU0wgc3R5bGVzaGVldChzKSBhc3NvY2lhdGVkIHdpdGggdGhlIFhNTCBkYXRhLiBUaGlzIG1hcHBpbmcgCi0jIGVuYWJsZXMgcmVsYXRpb25zaGlwcyB0byBiZSBkZWZpbmVkIGJldHdlZW4gY2xpZW50IGNhcGFiaWxpdGllcyBhbmQgc3R5bGVzaGVldHMgY2FwYWJsZSBvZiBhY3RpbmcgCi0jIG9uIHRoZXNlIGNhcGFiaWxpdGllcy4KLSMKLSMgVGhlIHJ1bGVzIGRlZmluZWQgYmVsb3cgYXJlIG9yZGVyLXNpZ25pZmljYW50LiAgSW4gb3RoZXIgd29yZHMsIGlmIHRoZSBmaXJzdCBydWxlIGlzIHVuc3VjY2Vzc2Z1bCwKLSMgdGhlIHNlY29uZCBydWxlIHdpbGwgYmUgdHJpZWQsIGV0Yy4gIFRoZSBtZWRpYSB2YWx1ZSAidW5rbm93biIgd2lsbCBiZSB1c2VkIHdoZW4gbm8gcnVsZXMgYXJlCi0jIHNhdGlzZmllZC4KLSMKLSMgRXhhbXBsZTogCi0jCi0jIE1hcHBpbmcgcnVsZXMgb2YuLi4KLSMKLSMgICBNU0lFPWV4cGxvcmVyCi0jICAgTVNQSUU9cG9ja2V0ZXhwbG9yZXIKLSMKLSMgLi4uYW5kIFhNTCBkYXRhIHRoYXQgY29udGFpbnMgWFNMIHN0eWxlc2hlZXQgYXNzb2NpYXRpb25zIG9mLi4uCi0jCi0jIDw/eG1sLXN0eWxlc2hlZXQgICAgICAgICAgICAgICAgIG1lZGlhPSJleHBsb3JlciIgICAgICAgaHJlZj0iYWxsZGF0YS54c2wiICB0eXBlPSJ0ZXh0L3hzbCI/PgotIyA8P3htbC1zdHlsZXNoZWV0IGFsdGVybmF0ZT0ieWVzIiBtZWRpYT0icG9ja2V0ZXhwbG9yZXIiIGhyZWY9InNvbWVkYXRhLnhzbCIgdHlwZT0idGV4dC94c2wiPz4KLSMKLSMgLi4uYW5kIGFuIEhUVFAgcmVxdWVzdCB0aGF0IGNvbnRhaW5zIGEgdXNlci1BZ2VudCB2YWx1ZSBvZi4uLgotIyAgICAKLSMgICBmb28gTVNQSUUgYmFyCi0jCi0jIC4uLndpbGwgYXBwbHkgdGhlIFhTTCBzdHlsZXNoZWV0IHNvbWVkYXRhLnhzbC4KLSMKLU1TSUU9ZXhwbG9yZXIKLU1TUElFPXBvY2tldGV4cGxvcmVyCi1IYW5kSFRUUD1oYW5kd2ViCi1Nb3ppbGxhPW5ldHNjYXBlCi1MeW54PWx5bngKLU9wZXJhPW9wZXJhCi1KYXZhPWphdmEKLUF2YW50R289YXZhbnRnbwotTm9raWE9bm9raWEKLVVQLkJyb3dzZXI9dXAKLURvQ29Nbz1pbW9kZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy9zZXJ2bGV0L3JlYWRtZS5odG1sIGIvc2FtcGxlcy9zZXJ2bGV0L3JlYWRtZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYzg5MzZmLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvc2VydmxldC9yZWFkbWUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzICswLDAgQEAKLTwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+Ci0KLTxodG1sPgotPGhlYWQ+Ci0JPHRpdGxlPlhhbGFuIFNhbXBsZXM8L3RpdGxlPgotPC9oZWFkPgotPGJvZHk+Ci08aDI+WGFsYW4gU2FtcGxlczwvaDI+Ci08cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNhbXBsZXMgKHdoYXQgdGhleSBpbGx1c3RyYXRlIGFuZCBob3cgdG8gcnVuIHRoZW0pLCBzZWUgPGEgaHJlZj0iLi4vLi4vZG9jcy9zYW1wbGVzLmh0bWwiPlNhbXBsZXM8L2E+LjwvcD4KLQotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL3RyYW5zbGV0cy9KQVhQVHJhbnNsZXRNdWx0aXBsZVRyYW5zZm9ybWF0aW9ucy5qYXZhIGIvc2FtcGxlcy90cmFuc2xldHMvSkFYUFRyYW5zbGV0TXVsdGlwbGVUcmFuc2Zvcm1hdGlvbnMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTdlNDg4NC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYW5zbGV0cy9KQVhQVHJhbnNsZXRNdWx0aXBsZVRyYW5zZm9ybWF0aW9ucy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIERvbmFsZCBMZXNsaWUKLSAqCi0gKi8KLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0KLS8qKgotICogVXNpbmcgdGhlIFRyQVgvSkFYUCAxLjEgaW50ZXJmYWNlIHRvIGNvbXBpbGUgYSB0cmFuc2xldCBhbmQgdXNlIGl0IAotICogdG8gcGVyZm9ybSBtdWx0aXBsZSB0cmFuc2Zvcm1hdGlvbnMuIFRoZSB0cmFuc2xldCBpbXBsZW1lbnRzIAotICogdGhlIFRlbXBsYXRlcyBpbnRlcmZhY2UuIElmIHlvdSB3YW50IHRvIHVzZSB0aGUgdHJhbnNsZXQgdG8gcGVyZm9ybSBhIAotICogc2luZ2xlIHRyYW5zZm9ybWF0aW9uLCBzZWUgSkFYUFRyYW5zbGV0T25lVHJhbnNmb3JtYXRpb24uamF2YS4KLSAqIAotICogCi0gKi8KLXB1YmxpYyBjbGFzcyBKQVhQVHJhbnNsZXRNdWx0aXBsZVRyYW5zZm9ybWF0aW9ucyAKLXsKLSBzdGF0aWMgdm9pZCBkb1RyYW5zZm9ybShUZW1wbGF0ZXMgdHJhbnNsZXQsIFN0cmluZyB4bWxJblVSSSwgU3RyaW5nIGh0bWxPdXRVUkkpCi0gICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgRmlsZU5vdEZvdW5kRXhjZXB0aW9uICAgICAKLSAgewotICAgIC8vIEZvciBlYWNoIHRyYW5zZm9ybWF0aW9uLCBpbnN0YW50aWF0ZSBhIG5ldyBUcmFuc2Zvcm1lciwgYW5kIHBlcmZvcm0KLSAgICAvLyB0aGUgdHJhbnNmb3JtYXRpb24gZnJvbSBhIFN0cmVhbVNvdXJjZSB0byBhIFN0cmVhbVJlc3VsdDsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRyYW5zbGV0Lm5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKCBuZXcgU3RyZWFtU291cmNlKHhtbEluVVJJKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQobmV3IEZpbGVPdXRwdXRTdHJlYW0oaHRtbE91dFVSSSkpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pICAgICAgICAKLSAgeyAKLSAgICAvLyBTZXQgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBzeXN0ZW0gcHJvcGVydHkgdG8gZ2VuZXJhdGUgYW5kIHVzZSB0cmFuc2xldHMuCi0gICAgLy8gTm90ZTogVG8gbWFrZSB0aGlzIHNhbXBsZSBtb3JlIGZsZXhpYmxlLCBsb2FkIHByb3BlcnRpZXMgZnJvbSBhIHByb3BlcnRpZXMgZmlsZS4KLSAgICAvLyBUaGUgc2V0dGluZyBmb3IgdGhlIFhhbGFuIFRyYW5zZm9ybWVyIGlzICJvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsIgotICAgIFN0cmluZyBrZXkgPSAiamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkiOwotICAgIFN0cmluZyB2YWx1ZSA9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnRyYXguVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCI7Ci0gICAgUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7Ci0gICAgcHJvcHMucHV0KGtleSwgdmFsdWUpOwotICAgIAotICAgIFN5c3RlbS5zZXRQcm9wZXJ0aWVzKHByb3BzKTsKLQotICAgIFN0cmluZyB4c2xJblVSSSA9ICJ0b2RvLnhzbCI7Ci0gICAgCi0gICAgdHJ5Ci0gICAgewotICAgICAgLy8gSW5zdGFudGlhdGUgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSwgYW5kIHVzZSBpdCBhbG9uZyB3aXRoIGEgU3RlYW1Tb3VyY2UKLSAgICAgIC8vIFhTTCBzdHlsZXNoZWV0IHRvIGNyZWF0ZSBhIHRyYW5zbGV0IGFzIGEgVGVtcGxhdGVzIG9iamVjdC4KLSAgICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgVGVtcGxhdGVzIHRyYW5zbGV0ID0gdEZhY3RvcnkubmV3VGVtcGxhdGVzKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSW5VUkkpKTsKLSAgICAKLSAgICAgIC8vIFBlcmZvcm0gZWFjaCB0cmFuc2Zvcm1hdGlvbgotICAgICAgZG9UcmFuc2Zvcm0odHJhbnNsZXQsICIuLi8uLi94c2x0Y190b2RvLnhtbCIsICJ0b2RvLXhzbHRjLmh0bWwiKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUHJvZHVjZWQgdG9kby14c2x0Yy5odG1sIik7Ci0gICAgCi0gICAgICBkb1RyYW5zZm9ybSh0cmFuc2xldCwgIi4uLy4uL3RvZG8ueG1sIiwgInRvZG8teGFsYW4uaHRtbCIpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQcm9kdWNlZCB0b2RvLXhhbGFuLmh0bWwiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfSAgICAKLSAgfSAKLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3RyYW5zbGV0cy9KQVhQVHJhbnNsZXRPbmVUcmFuc2Zvcm1hdGlvbi5qYXZhIGIvc2FtcGxlcy90cmFuc2xldHMvSkFYUFRyYW5zbGV0T25lVHJhbnNmb3JtYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzBlMmQ0ZS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYW5zbGV0cy9KQVhQVHJhbnNsZXRPbmVUcmFuc2Zvcm1hdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIERvbmFsZCBMZXNsaWUKLSAqCi0gKi8KLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0KLS8qKgotICogVXNpbmcgdGhlIFRyQVgvSkFYUCAxLjEgaW50ZXJmYWNlIHRvIGNvbXBpbGUgYW5kIHJ1biBhIHRyYW5zbGV0LiBUaGUgdHJhbnNsZXQKLSAqIGV4dGVuZHMgdGhlIGFic3RyYWN0IFRyYW5zZm9ybWVyIGNsYXNzIGFuZCBpcyB1c2VkIHRvIHBlcmZvcm0gYSBzaW5nbGUKLSAqIHRyYW5zZm9ybWF0aW9uLiBJZiB5b3Ugd2FudCB0byB1c2UgdGhlIHRyYW5zbGV0IHRvIHBlcmZvcm0gbXVsdGlwbGUgCi0gKiB0cmFuc2Zvcm1hdGlvbnMsIHNlZSBKQVhQVHJhbnNsZXRNdWx0aXBsZVRyYW5zZm9ybWF0aW9ucy5qYXZhLgotICogCi0gKi8KLXB1YmxpYyBjbGFzcyBKQVhQVHJhbnNsZXRPbmVUcmFuc2Zvcm1hdGlvbgotewotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBGaWxlTm90Rm91bmRFeGNlcHRpb24KLSAgeyAKLSAgICAvLyBTZXQgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBzeXN0ZW0gcHJvcGVydHkgdG8gZ2VuZXJhdGUgYW5kIHVzZSBhIHRyYW5zbGV0LgotICAgIC8vIE5vdGU6IFRvIG1ha2UgdGhpcyBzYW1wbGUgbW9yZSBmbGV4aWJsZSwgbG9hZCBwcm9wZXJ0aWVzIGZyb20gYSBwcm9wZXJ0aWVzIGZpbGUuICAgIAotICAgIC8vIFRoZSBzZXR0aW5nIGZvciB0aGUgWGFsYW4gVHJhbnNmb3JtZXIgaXMgIm9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlRyYW5zZm9ybWVyRmFjdG9yeUltcGwiCi0gICAgU3RyaW5nIGtleSA9ICJqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSI7Ci0gICAgU3RyaW5nIHZhbHVlID0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheC5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsIjsKLSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKLSAgICBwcm9wcy5wdXQoa2V5LCB2YWx1ZSk7Ci0gICAgU3lzdGVtLnNldFByb3BlcnRpZXMocHJvcHMpOyAgICAKLQotICAgIFN0cmluZyB4c2xJblVSSSA9ICJ0b2RvLnhzbCI7Ci0gICAgU3RyaW5nIHhtbEluVVJJID0gIi4uLy4uL3hzbHRjX3RvZG8ueG1sIjsKLSAgICBTdHJpbmcgaHRtbE91dFVSSSA9ICJ0b2RvLXhzbHRjLmh0bWwiOwotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIEluc3RhbnRpYXRlIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnksIGFuZCB1c2UgaXQgYWxvbmcgd2l0aCBhIFN0ZWFtU291cmNlCi0gICAgICAvLyBYU0wgc3R5bGVzaGVldCB0byBjcmVhdGUgYSBUcmFuc2Zvcm1lci4KLSAgICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0RmFjdG9yeS5uZXdUcmFuc2Zvcm1lcihuZXcgU3RyZWFtU291cmNlKHhzbEluVVJJKSk7Ci0gICAgICAvLyBQZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbiBmcm9tIGEgU3RyZWFtU291cmNlIHRvIGEgU3RyZWFtUmVzdWx0OwotICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoeG1sSW5VUkkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQobmV3IEZpbGVPdXRwdXRTdHJlYW0oaHRtbE91dFVSSSkpKTsgIAotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQcm9kdWNlZCB0b2RvLXhzbHRjLmh0bWwiKTsgIAotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIAotICAgIHsKLSAgICAgU3lzdGVtLm91dC5wcmludGxuKGUudG9TdHJpbmcoKSk7Ci0gICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfSAgICAgIAotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy90cmFuc2xldHMvcmVhZG1lLmh0bWwgYi9zYW1wbGVzL3RyYW5zbGV0cy9yZWFkbWUuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM4OTM2Zi4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYW5zbGV0cy9yZWFkbWUuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEzICswLDAgQEAKLTwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+Ci0KLTxodG1sPgotPGhlYWQ+Ci0JPHRpdGxlPlhhbGFuIFNhbXBsZXM8L3RpdGxlPgotPC9oZWFkPgotPGJvZHk+Ci08aDI+WGFsYW4gU2FtcGxlczwvaDI+Ci08cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNhbXBsZXMgKHdoYXQgdGhleSBpbGx1c3RyYXRlIGFuZCBob3cgdG8gcnVuIHRoZW0pLCBzZWUgPGEgaHJlZj0iLi4vLi4vZG9jcy9zYW1wbGVzLmh0bWwiPlNhbXBsZXM8L2E+LjwvcD4KLQotCi08L2JvZHk+Ci08L2h0bWw+CmRpZmYgLS1naXQgYS9zYW1wbGVzL3RyYW5zbGV0cy90b2RvLnhzbCBiL3NhbXBsZXMvdHJhbnNsZXRzL3RvZG8ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZmY4Y2FjLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvdHJhbnNsZXRzL3RvZG8ueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMTQ2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotPHhzbDp2YXJpYWJsZSBuYW1lPSJ0aXRsZSIgc2VsZWN0PSJjb25jYXQodG9kby9AcHJvamVjdCwgJyAnLCB0b2RvL0BtYWpvci12ZXJzaW9uKSIvPgotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgICA8SFRNTD4KLSAgICAgIDxIRUFEPgotICAgICAgICAgPFRJVExFPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIkdGl0bGUiLz48L1RJVExFPgotICAgICAgPC9IRUFEPgotICAgICAgPEJPRFk+Ci0KLSAgICAgICAgPEgyPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJjb25jYXQoJHRpdGxlLCAnOiAnLCB0b2RvL0B0aXRsZSkiLz48L0gyPgotICAgICAgICA8cD48Zm9udCBzaXplPSItMSI+U2VlIGEgCi0gICAgICAgICAgPHhzbDplbGVtZW50IG5hbWU9ImEiPgotICAgICAgICAgICAgPHhzbDphdHRyaWJ1dGUgbmFtZT0iaHJlZiI+I2RldmVsb3Blci1saXN0PC94c2w6YXR0cmlidXRlPgotICAgICAgICAgICAgPHhzbDp0ZXh0Pmxpc3Qgb2YgZGV2ZWxvcGVycy9pbml0aWFscy48L3hzbDp0ZXh0PgotICAgICAgICAgIDwveHNsOmVsZW1lbnQ+Ci0gICAgICAgIDwvZm9udD48L3A+Ci0gICAgICAgIDxmb250IHNpemU9Ii0xIj48cD5QbGFubmVkIHJlbGVhc2VzOiAKLSAgICAgICAgICAgIDxCUi8+PHhzbDpmb3ItZWFjaCBzZWxlY3Q9InRvZG8vYWN0aW9ucy90YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbiI+Ci0gICAgICAgICAgICAgIDx4c2w6ZWxlbWVudCBuYW1lPSJhIj4KLSAgICAgICAgICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJocmVmIj4jcmVsZWFzZS1kYXRlLTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJkYXRlIi8+PC94c2w6YXR0cmlidXRlPgotICAgICAgICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJkYXRlIi8+Ci0gICAgICAgICAgICAgIDwveHNsOmVsZW1lbnQ+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0Pjx4c2w6dGV4dD4gPC94c2w6dGV4dD4KLSAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgICAgPHhzbDplbGVtZW50IG5hbWU9ImEiPgotICAgICAgICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9ImhyZWYiPiNyZWxlYXNlLWRhdGUtY29tcGxldGVkPC94c2w6YXR0cmlidXRlPgotICAgICAgICAgICAgICAgIDx4c2w6dGV4dD5Db21wbGV0ZWQ8L3hzbDp0ZXh0PgotICAgICAgICAgICAgICA8L3hzbDplbGVtZW50PgotCi0gICAgICAgIDwvcD48L2ZvbnQ+Ci0gICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJ0b2RvIj4KLSAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iYWN0aW9ucyI+Ci0gICAgICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJ0YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbiI+Ci0gICAgICAgICAgICAgICAgPHA+Ci0gICAgICAgICAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgICAgICAgICAgICAgPC9wPgotICAgICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9ImFjdGlvbiI+Ci0gICAgICAgICAgICAgICAgPHhzbDppZiB0ZXN0PSJub3JtYWxpemUtc3BhY2UoLikiPgotICAgICAgICAgICAgICAgICAgPHA+Ci0gICAgICAgICAgICAgICAgICAgPHhzbDpudW1iZXIvPikgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgICAgICAgICAgICAgICAgIDx4c2w6aWYgdGVzdD0iQCoiPgotICAgICAgICAgICAgICAgICAgICA8QlIvPgotICAgICAgICAgICAgICAgICAgIDwveHNsOmlmPgotICAgICAgICAgICAgICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iQCoiLz4KLSAgICAgICAgICAgICAgICAgIDwvcD4KLSAgICAgICAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgICAgPEhSLz4KLSAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLQotICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJjb21wbGV0ZWQiPgotICAgICAgICAgICAgICA8eHNsOmVsZW1lbnQgbmFtZT0iYSI+Ci0gICAgICAgICAgICAgICAgPHhzbDphdHRyaWJ1dGUgbmFtZT0ibmFtZSI+cmVsZWFzZS1kYXRlLWNvbXBsZXRlZDwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgICAgICAgICA8SDM+Q29tcGxldGVkOiA8L0gzPgotICAgICAgICAgICAgICA8L3hzbDplbGVtZW50PgotICAgICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9ImFjdGlvbiI+Ci0gICAgICAgICAgICAgIDx4c2w6aWYgdGVzdD0ibm9ybWFsaXplLXNwYWNlKC4pIj4KLSAgICAgICAgICAgICAgICA8cD4KLSAgICAgICAgICAgICAgICAgPHhzbDpudW1iZXIvPikgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgICAgICAgICAgICAgICA8eHNsOmlmIHRlc3Q9IkAqIj4KLSAgICAgICAgICAgICAgICAgIDxCUi8+Ci0gICAgICAgICAgICAgICAgIDwveHNsOmlmPgotICAgICAgICAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IkAqIi8+Ci0gICAgICAgICAgICAgICAgPC9wPgotICAgICAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICA8SFIvPgotICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLQotICAgICAgICA8eHNsOmNhbGwtdGVtcGxhdGUgbmFtZT0iZGV2ZWxvcGVyLWxpc3QiLz4KLSAgICAgICA8L3hzbDpmb3ItZWFjaD4KLQotICAgICAgPC9CT0RZPgotICAgIDwvSFRNTD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iYWN0aW9uL0AqIj4KLSAgPCEtLSBBZGQgbGluayB0byB0aGUgd2hvIGF0dHJpYnV0ZXMgdG8gY29ycmVzcG9uZGluZyBpdGVtIGluIGRldmVsb3Blci1saXN0IC0tPgotICAgIDxiPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8+OjwvYj48eHNsOnRleHQ+IDwveHNsOnRleHQ+Ci0gICAgICA8eHNsOmNob29zZT4KLSAgICAgICAgPHhzbDp3aGVuIHRlc3Q9Im5hbWUoLik9J3dobyciPgotICAgICAgICAgIDx4c2w6ZWxlbWVudCBuYW1lPSJhIj4KLSAgICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9ImhyZWYiPiNwZXJzb25yZWYtPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L3hzbDphdHRyaWJ1dGU+Ci0gICAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPgotICAgICAgICAgIDwveHNsOmVsZW1lbnQ+Ci0gICAgICAgIDwveHNsOndoZW4+Ci0gICAgICAgIDx4c2w6b3RoZXJ3aXNlPgotICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+Ci0gICAgICAgIDwveHNsOm90aGVyd2lzZT4KLSAgICAgIDwveHNsOmNob29zZT4KLSAgICA8eHNsOmlmIHRlc3Q9Im5vdCAocG9zaXRpb24oKT1sYXN0KCkpIj4KLSAgICAgIDx4c2w6dGV4dD4sIDwveHNsOnRleHQ+Ci0gICAgPC94c2w6aWY+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InRhcmdldC1yZWxlYXNlLWRlc2NyaXB0aW9uL2RhdGUiPgotICAgICAgPHhzbDplbGVtZW50IG5hbWU9ImEiPgotICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJuYW1lIj5yZWxlYXNlLWRhdGUtPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L3hzbDphdHRyaWJ1dGU+Ci0gICAgICAgIDxiPjx4c2w6dGV4dD5Gb3IgcmVsZWFzZTogPC94c2w6dGV4dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvYj4KLSAgICAgIDwveHNsOmVsZW1lbnQ+Ci0gICAgCi0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Imlzc3VlIj4KLSAgICA8QlIvPjxiPklzc3VlIDwvYj48eHNsOnRleHQ+WzwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBpZCIvPgotICAgIDx4c2w6dGV4dD5dOiA8L3hzbDp0ZXh0PgotICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGFyZ2V0LXJlbGVhc2UtZGVzY3JpcHRpb24vbGV2ZWwiPgotICAgIDx4c2w6dGV4dD4sIDwveHNsOnRleHQ+PHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbi9nb2FsIj4KLSAgICA8QlIvPjxiPkdvYWwgPC9iPjx4c2w6dGV4dD5bPC94c2w6dGV4dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQHR5cGUiLz4KLSAgICA8eHNsOnRleHQ+XTogPC94c2w6dGV4dD4KLSAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0KLSAgPHhzbDp0ZW1wbGF0ZSBuYW1lPSJkZXZlbG9wZXItbGlzdCI+Ci0gICAgPEgzPgotICAgICAgPHhzbDplbGVtZW50IG5hbWU9ImEiPgotICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJuYW1lIj5kZXZlbG9wZXItbGlzdDwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgPHhzbDp0ZXh0PkRldmVsb3BlcnM6PC94c2w6dGV4dD4KLSAgICAgIDwveHNsOmVsZW1lbnQ+Ci0gICAgPC9IMz4KLSAgICA8cD5BIGxpc3Qgb2Ygc29tZSBvZiBwZW9wbGUgY3VycmVudGx5IHdvcmtpbmcgb24gd29ya2luZyBvbiA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iL3RvZG8vQHByb2plY3QiLz46PC9wPgotICAgIDx1bD4KLSAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iZGV2cy9wZXJzb24iPgotICAgICAgPGxpPgotICAgICAgICA8YSBocmVmPSJtYWlsdG86e0BlbWFpbH0iPgotICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAbmFtZSIvPgotICAgICAgICA8L2E+Ci0gICAgICAgICA8eHNsOmVsZW1lbnQgbmFtZT0iYSI+Ci0gICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9Im5hbWUiPjx4c2w6dGV4dD5wZXJzb25yZWYtPC94c2w6dGV4dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGlkIi8+PC94c2w6YXR0cmlidXRlPgotICAgICAgICAgICA8eHNsOnRleHQ+ICg8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAaWQiLz48eHNsOnRleHQ+KTwveHNsOnRleHQ+Ci0gICAgICAgICA8L3hzbDplbGVtZW50PgotICAgICAgICAgPEJSLz48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPgotICAgICAgPC9saT4KLSAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICA8L3VsPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3NhbXBsZXMvdHJheC9FeGFtcGxlQ29udGVudEhhbmRsZXIuamF2YSBiL3NhbXBsZXMvdHJheC9FeGFtcGxlQ29udGVudEhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2UzMDhmNC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYXgvRXhhbXBsZUNvbnRlbnRIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLQotcHVibGljIGNsYXNzIEV4YW1wbGVDb250ZW50SGFuZGxlciBpbXBsZW1lbnRzIENvbnRlbnRIYW5kbGVyCi17Ci0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvciAoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJzZXREb2N1bWVudExvY2F0b3IiKTsKLSAgfQotCi0KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCAoKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnREb2N1bWVudCIpOwotICB9Ci0KLQotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJlbmREb2N1bWVudCIpOwotICB9Ci0KLQotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcgKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJzdGFydFByZWZpeE1hcHBpbmc6ICIrcHJlZml4KyIsICIrdXJpKTsKLSAgfQotCi0KLSAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyAoU3RyaW5nIHByZWZpeCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImVuZFByZWZpeE1hcHBpbmc6ICIrcHJlZml4KTsKLSAgfQotCi0KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50IChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnQoInN0YXJ0RWxlbWVudDogIituYW1lc3BhY2VVUkkrIiwgIituYW1lc3BhY2VVUkkrCi0gICAgICAgICAgICAgICAgICAgICAgICIsICIrcU5hbWUpOwotICAgIGludCBuID0gYXR0cy5nZXRMZW5ndGgoKTsKLSAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgIithdHRzLmdldFFOYW1lKGkpKTsKLSAgICB9Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKLSAgfQotCi0KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudCAoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHFOYW1lKQotICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kRWxlbWVudDogIituYW1lc3BhY2VVUkkrIiwgIituYW1lc3BhY2VVUkkrCi0gICAgICAgICAgICAgICAgICAgICAgICIsICIrcU5hbWUpOwotICB9Ci0KLQotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCAobGVuZ3RoID4gMzApID8gMzAgOiBsZW5ndGgpOwotICAgIGlmKGxlbmd0aCA+IDMwKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJjaGFyYWN0ZXJzOiBcIiIrcysiXCIuLi4iKTsKLSAgICBlbHNlCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImNoYXJhY3RlcnM6IFwiIitzKyJcIiIpOwotICB9Ci0KLQotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlIChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImlnbm9yYWJsZVdoaXRlc3BhY2UiKTsKLSAgfQotCi0KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInByb2Nlc3NpbmdJbnN0cnVjdGlvbjogIit0YXJnZXQrIiwgIit0YXJnZXQpOwotICB9Ci0KLQotICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5IChTdHJpbmcgbmFtZSkKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNraXBwZWRFbnRpdHk6ICIrbmFtZSk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy90cmF4L0V4YW1wbGVzLmphdmEgYi9zYW1wbGVzL3RyYXgvRXhhbXBsZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzc1MzI2OC4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYXgvRXhhbXBsZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLio7Ci0KLS8vIE5lZWRlZCBqYXZhIGNsYXNzZXMKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZVJlYWRlcjsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKLWltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi0vLyBOZWVkZWQgU0FYIGNsYXNzZXMKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguUGFyc2VyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuUGFyc2VyQWRhcHRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTEZpbHRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyOwotCi0vLyBOZWVkZWQgRE9NIGNsYXNzZXMKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vLyBOZWVkZWQgSkFYUCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsgICAgLy8gZG1sCi0KLS8qKgotICogU29tZSBleGFtcGxlcyB0byBzaG93IGhvdyB0aGUgU2ltcGxlIEFQSSBmb3IgVHJhbnNmb3JtYXRpb25zCi0gKiBjb3VsZCBiZSB1c2VkLgotICogCi0gKiBYYWxhbiBEZXZlbG9wZXJzOiBwbGVhc2Ugc2VlIAotICogeG1sLXhhbGFuL3Rlc3QvamF2YS9zcmMvb3JnL2FwYWNoZS9xZXRlc3QvdHJheC9FeGFtcGxlc1Rlc3QuamF2YQotICogd2hlbiB1cGRhdGluZyB0aGlzIGZpbGUsIGFuZCB1cGRhdGUgdGhhdCB0ZXN0IGZpbGUgYXMgd2VsbC4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpzY290dF9ib2FnQGxvdHVzLmNvbSI+U2NvdHQgQm9hZzwvYT4KLSAqLwotcHVibGljIGNsYXNzIEV4YW1wbGVzCi17Ci0gIC8qKgotICAgKiBNZXRob2QgbWFpbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiwKLSAgICAgICAgICAgICAgICAgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgRmlsZU5vdEZvdW5kRXhjZXB0aW9uCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVTaW1wbGUgPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVTaW1wbGUxKCJ4bWwvZm9vLnhtbCIsICJ4c2wvZm9vLnhzbCIpOwotICAgIH0gY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsgCi0gICAgICAgIGhhbmRsZUV4Y2VwdGlvbihleCk7Ci0gICAgfSAKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVTaW1wbGUyIChzZWUgZm9vLm91dCkgPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVTaW1wbGUyKCJ4bWwvZm9vLnhtbCIsICJ4c2wvZm9vLnhzbCIpOwotICAgIH0gY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsgCi0gICAgICAgIGhhbmRsZUV4Y2VwdGlvbihleCk7Ci0gICAgfSAKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVGcm9tU3RyZWFtID09PT0iKTsKLSAgICB0cnkgewotICAgICAgICBleGFtcGxlRnJvbVN0cmVhbSgieG1sL2Zvby54bWwiLCAieHNsL2Zvby54c2wiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuPT09PSBleGFtcGxlRnJvbVJlYWRlciA9PT09Iik7Ci0gICAgdHJ5IHsKLSAgICAgICAgZXhhbXBsZUZyb21SZWFkZXIoInhtbC9mb28ueG1sIiwgInhzbC9mb28ueHNsIik7Ci0gICAgfSBjYXRjaCggRXhjZXB0aW9uIGV4ICkgeyAKLSAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGV4KTsKLSAgICB9IAotICAgIAotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbj09PT0gZXhhbXBsZVVzZVRlbXBsYXRlc09iaiA9PT09Iik7Ci0gICAgdHJ5IHsKLSAgICAgICAgZXhhbXBsZVVzZVRlbXBsYXRlc09iaigieG1sL2Zvby54bWwiLCAieG1sL2Jhei54bWwiLCAieHNsL2Zvby54c2wiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuPT09PSBleGFtcGxlQ29udGVudEhhbmRsZXJUb0NvbnRlbnRIYW5kbGVyID09PT0iKTsKLSAgICB0cnkgewotICAgICAgICBleGFtcGxlQ29udGVudEhhbmRsZXJUb0NvbnRlbnRIYW5kbGVyKCJ4bWwvZm9vLnhtbCIsICJ4c2wvZm9vLnhzbCIpOwotICAgIH0gY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsgCi0gICAgICAgIGhhbmRsZUV4Y2VwdGlvbihleCk7Ci0gICAgfSAKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVYTUxSZWFkZXIgPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVYTUxSZWFkZXIoInhtbC9mb28ueG1sIiwgInhzbC9mb28ueHNsIik7Ci0gICAgfSBjYXRjaCggRXhjZXB0aW9uIGV4ICkgeyAKLSAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGV4KTsKLSAgICB9IAotICAgIAotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbj09PT0gZXhhbXBsZVhNTEZpbHRlciA9PT09Iik7Ci0gICAgdHJ5IHsKLSAgICAgICAgZXhhbXBsZVhNTEZpbHRlcigieG1sL2Zvby54bWwiLCAieHNsL2Zvby54c2wiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuPT09PSBleGFtcGxlWE1MRmlsdGVyQ2hhaW4gPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVYTUxGaWx0ZXJDaGFpbigieG1sL2Zvby54bWwiLCAieHNsL2Zvby54c2wiLCAieHNsL2ZvbzIueHNsIiwgInhzbC9mb28zLnhzbCIpOwotICAgIH0gY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsgCi0gICAgICAgIGhhbmRsZUV4Y2VwdGlvbihleCk7Ci0gICAgfSAKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVET00yRE9NID09PT0iKTsKLSAgICB0cnkgewotICAgICAgICBleGFtcGxlRE9NMkRPTSgieG1sL2Zvby54bWwiLCAieHNsL2Zvby54c2wiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuPT09PSBleGFtcGxlUGFyYW0gPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVQYXJhbSgieG1sL2Zvby54bWwiLCAieHNsL2Zvby54c2wiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuPT09PSBleGFtcGxlVHJhbnNmb3JtZXJSZXVzZSA9PT09Iik7Ci0gICAgdHJ5IHsKLSAgICAgICAgZXhhbXBsZVRyYW5zZm9ybWVyUmV1c2UoInhtbC9mb28ueG1sIiwgInhzbC9mb28ueHNsIik7Ci0gICAgfSBjYXRjaCggRXhjZXB0aW9uIGV4ICkgeyAKLSAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGV4KTsKLSAgICB9IAotICAgIAotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbj09PT0gZXhhbXBsZU91dHB1dFByb3BlcnRpZXMgPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVPdXRwdXRQcm9wZXJ0aWVzKCJ4bWwvZm9vLnhtbCIsICJ4c2wvZm9vLnhzbCIpOwotICAgIH0gY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsgCi0gICAgICAgIGhhbmRsZUV4Y2VwdGlvbihleCk7Ci0gICAgfSAKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVVc2VBc3NvY2lhdGVkID09PT0iKTsKLSAgICB0cnkgewotICAgICAgICBleGFtcGxlVXNlQXNzb2NpYXRlZCgieG1sL2Zvby54bWwiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuPT09PSBleGFtcGxlQ29udGVudEhhbmRsZXIyRE9NID09PT0iKTsKLSAgICB0cnkgewotICAgICAgICBleGFtcGxlQ29udGVudEhhbmRsZXIyRE9NKCJ4bWwvZm9vLnhtbCIsICJ4c2wvZm9vLnhzbCIpOwotICAgIH0gY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsgCi0gICAgICAgIGhhbmRsZUV4Y2VwdGlvbihleCk7Ci0gICAgfSAKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG49PT09IGV4YW1wbGVBc1NlcmlhbGl6ZXIgPT09PSIpOwotICAgIHRyeSB7Ci0gICAgICAgIGV4YW1wbGVBc1NlcmlhbGl6ZXIoInhtbC9mb28ueG1sIiwgInhzbC9mb28ueHNsIik7Ci0gICAgfSBjYXRjaCggRXhjZXB0aW9uIGV4ICkgeyAKLSAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGV4KTsKLSAgICB9IAotICAgIAotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbj09PT0gZXhhbXBsZUNvbnRlbnRIYW5kbGVyMkRPTSA9PT09Iik7Ci0gICAgdHJ5IHsKLSAgICAgICAgZXhhbXBsZUNvbnRlbnRIYW5kbGVyMkRPTSgieG1sL2Zvby54bWwiLCAieHNsL2Zvby54c2wiKTsKLSAgICB9IGNhdGNoKCBFeGNlcHRpb24gZXggKSB7IAotICAgICAgICBoYW5kbGVFeGNlcHRpb24oZXgpOwotICAgIH0gCi0KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuPT09PSBkb25lISA9PT09Iik7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTaG93IHRoZSBzaW1wbGVzdCBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbiBmcm9tIHN5c3RlbSBpZCAKLSAgICogdG8gb3V0cHV0IHN0cmVhbS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBleGFtcGxlU2ltcGxlMShTdHJpbmcgc291cmNlSUQsIFN0cmluZyB4c2xJRCkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgLy8gQ3JlYXRlIGEgdHJhbnNmb3JtIGZhY3RvcnkgaW5zdGFuY2UuCi0gICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgCi0gICAgLy8gQ3JlYXRlIGEgdHJhbnNmb3JtZXIgZm9yIHRoZSBzdHlsZXNoZWV0LgotICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyIAotICAgICAgPSB0ZmFjdG9yeS5uZXdUcmFuc2Zvcm1lcihuZXcgU3RyZWFtU291cmNlKHhzbElEKSk7Ci0gICAgCi0gICAgLy8gVHJhbnNmb3JtIHRoZSBzb3VyY2UgWE1MIHRvIFN5c3RlbS5vdXQuCi0gICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKCBuZXcgU3RyZWFtU291cmNlKHNvdXJjZUlEKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotICB9Ci0gIAotICAvKioKLSAgICogU2hvdyB0aGUgc2ltcGxlc3QgcG9zc2libGUgdHJhbnNmb3JtYXRpb24gZnJvbSBGaWxlIAotICAgKiB0byBhIEZpbGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZVNpbXBsZTIoU3RyaW5nIHNvdXJjZUlELCBTdHJpbmcgeHNsSUQpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIC8vIENyZWF0ZSBhIHRyYW5zZm9ybSBmYWN0b3J5IGluc3RhbmNlLgotICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0ZmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIAotICAgIC8vIENyZWF0ZSBhIHRyYW5zZm9ybWVyIGZvciB0aGUgc3R5bGVzaGVldC4KLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciAKLSAgICAgID0gdGZhY3RvcnkubmV3VHJhbnNmb3JtZXIobmV3IFN0cmVhbVNvdXJjZSh4c2xJRCkpOwotICAgIAotICAgIC8vIFRyYW5zZm9ybSB0aGUgc291cmNlIFhNTCB0byBmb28ub3V0LgotICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybSggbmV3IFN0cmVhbVNvdXJjZShuZXcgRmlsZShzb3VyY2VJRCkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdChuZXcgRmlsZSgiZm9vLm91dCIpKSk7Ci0gIH0KLQotICAKLSAgLyoqCi0gICAqIFNob3cgc2ltcGxlIHRyYW5zZm9ybWF0aW9uIGZyb20gaW5wdXQgc3RyZWFtIHRvIG91dHB1dCBzdHJlYW0uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZUZyb21TdHJlYW0oU3RyaW5nIHNvdXJjZUlELCBTdHJpbmcgeHNsSUQpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sCi0gICAgICAgICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gQ3JlYXRlIGEgdHJhbnNmb3JtIGZhY3RvcnkgaW5zdGFuY2UuCi0gICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICBJbnB1dFN0cmVhbSB4c2xJUyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oeHNsSUQpKTsKLSAgICBTdHJlYW1Tb3VyY2UgeHNsU291cmNlID0gbmV3IFN0cmVhbVNvdXJjZSh4c2xJUyk7Ci0gICAgLy8gTm90ZSB0aGF0IGlmIHdlIGRvbid0IGRvIHRoaXMsIHJlbGF0aXZlIFVSTHMgY2FuIG5vdCBiZSByZXNvbHZlZCBjb3JyZWN0bHkhCi0gICAgeHNsU291cmNlLnNldFN5c3RlbUlkKHhzbElEKTsKLQotICAgIC8vIENyZWF0ZSBhIHRyYW5zZm9ybWVyIGZvciB0aGUgc3R5bGVzaGVldC4KLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRmYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKHhzbFNvdXJjZSk7Ci0gICAgCi0gICAgSW5wdXRTdHJlYW0geG1sSVMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgRmlsZUlucHV0U3RyZWFtKHNvdXJjZUlEKSk7Ci0gICAgU3RyZWFtU291cmNlIHhtbFNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UoeG1sSVMpOwotICAgIC8vIE5vdGUgdGhhdCBpZiB3ZSBkb24ndCBkbyB0aGlzLCByZWxhdGl2ZSBVUkxzIGNhbiBub3QgYmUgcmVzb2x2ZWQgY29ycmVjdGx5IQotICAgIHhtbFNvdXJjZS5zZXRTeXN0ZW1JZChzb3VyY2VJRCk7Ci0gICAgCi0gICAgLy8gVHJhbnNmb3JtIHRoZSBzb3VyY2UgWE1MIHRvIFN5c3RlbS5vdXQuCi0gICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKCB4bWxTb3VyY2UsIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotICB9Ci0gIAotICAvKioKLSAgICogU2hvdyBzaW1wbGUgdHJhbnNmb3JtYXRpb24gZnJvbSByZWFkZXIgdG8gb3V0cHV0IHN0cmVhbS4gIEluIGdlbmVyYWwgCi0gICAqIHRoaXMgdXNlIGNhc2UgaXMgZGlzY291cmFnZWQsIHNpbmNlIHRoZSBYTUwgZW5jb2RpbmcgY2FuIG5vdCBiZSAKLSAgICogcHJvY2Vzc2VkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIGV4YW1wbGVGcm9tUmVhZGVyKFN0cmluZyBzb3VyY2VJRCwgU3RyaW5nIHhzbElEKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLAotICAgICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24KLSAgewotICAgIC8vIENyZWF0ZSBhIHRyYW5zZm9ybSBmYWN0b3J5IGluc3RhbmNlLgotICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0ZmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgLy8gTm90ZSB0aGF0IGluIHRoaXMgY2FzZSB0aGUgWE1MIGVuY29kaW5nIGNhbiBub3QgYmUgcHJvY2Vzc2VkIQotICAgIFJlYWRlciB4c2xSZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoeHNsSUQpKTsKLSAgICBTdHJlYW1Tb3VyY2UgeHNsU291cmNlID0gbmV3IFN0cmVhbVNvdXJjZSh4c2xSZWFkZXIpOwotICAgIC8vIE5vdGUgdGhhdCBpZiB3ZSBkb24ndCBkbyB0aGlzLCByZWxhdGl2ZSBVUkxzIGNhbiBub3QgYmUgcmVzb2x2ZWQgY29ycmVjdGx5IQotICAgIHhzbFNvdXJjZS5zZXRTeXN0ZW1JZCh4c2xJRCk7Ci0KLSAgICAvLyBDcmVhdGUgYSB0cmFuc2Zvcm1lciBmb3IgdGhlIHN0eWxlc2hlZXQuCi0gICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0ZmFjdG9yeS5uZXdUcmFuc2Zvcm1lcih4c2xTb3VyY2UpOwotICAgIAotICAgIC8vIE5vdGUgdGhhdCBpbiB0aGlzIGNhc2UgdGhlIFhNTCBlbmNvZGluZyBjYW4gbm90IGJlIHByb2Nlc3NlZCEKLSAgICBSZWFkZXIgeG1sUmVhZGVyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKHNvdXJjZUlEKSk7Ci0gICAgU3RyZWFtU291cmNlIHhtbFNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UoeG1sUmVhZGVyKTsKLSAgICAvLyBOb3RlIHRoYXQgaWYgd2UgZG9uJ3QgZG8gdGhpcywgcmVsYXRpdmUgVVJMcyBjYW4gbm90IGJlIHJlc29sdmVkIGNvcnJlY3RseSEKLSAgICB4bWxTb3VyY2Uuc2V0U3lzdGVtSWQoc291cmNlSUQpOwotICAgIAotICAgIC8vIFRyYW5zZm9ybSB0aGUgc291cmNlIFhNTCB0byBTeXN0ZW0ub3V0LgotICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybSggeG1sU291cmNlLCBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLSAgfQotCi0KLSAKLSAgLyoqCi0gICAqIFNob3cgdGhlIHNpbXBsZXN0IHBvc3NpYmxlIHRyYW5zZm9ybWF0aW9uIGZyb20gc3lzdGVtIGlkIHRvIG91dHB1dCBzdHJlYW0uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZVVzZVRlbXBsYXRlc09iaihTdHJpbmcgc291cmNlSUQxLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzb3VyY2VJRDIsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHhzbElEKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLQotICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0ZmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIAotICAgIC8vIENyZWF0ZSBhIHRlbXBsYXRlcyBvYmplY3QsIHdoaWNoIGlzIHRoZSBwcm9jZXNzZWQsIAotICAgIC8vIHRocmVhZC1zYWZlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHlsZXNoZWV0LgotICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSB0ZmFjdG9yeS5uZXdUZW1wbGF0ZXMobmV3IFN0cmVhbVNvdXJjZSh4c2xJRCkpOwotCi0gICAgLy8gSWxsdXN0cmF0ZSB0aGUgZmFjdCB0aGF0IHlvdSBjYW4gbWFrZSBtdWx0aXBsZSB0cmFuc2Zvcm1lcnMgCi0gICAgLy8gZnJvbSB0aGUgc2FtZSB0ZW1wbGF0ZS4KLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcjEgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcjIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG4tLS0tLSB0cmFuc2Zvcm0gb2YgIitzb3VyY2VJRDErIiAtLS0tLSIpOwotICAgIAotICAgIHRyYW5zZm9ybWVyMS50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShzb3VyY2VJRDEpLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLSAgICAKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG4tLS0tLSB0cmFuc2Zvcm0gb2YgIitzb3VyY2VJRDIrIiAtLS0tLSIpOwotICAgIAotICAgIHRyYW5zZm9ybWVyMi50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShzb3VyY2VJRDIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLSAgfQotICAKLQotCi0gIC8qKgotICAgKiBTaG93IHRoZSBUcmFuc2Zvcm1lciB1c2luZyBTQVggZXZlbnRzIGluIGFuZCBTQVggZXZlbnRzIG91dC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBleGFtcGxlQ29udGVudEhhbmRsZXJUb0NvbnRlbnRIYW5kbGVyKFN0cmluZyBzb3VyY2VJRCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB4c2xJRCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIAotICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIAotICAgICAgICAgICAgICAgICBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgIC8vIERvZXMgdGhpcyBmYWN0b3J5IHN1cHBvcnQgU0FYIGZlYXR1cmVzPwotICAgIGlmICh0ZmFjdG9yeS5nZXRGZWF0dXJlKFNBWFNvdXJjZS5GRUFUVVJFKSkKLSAgICB7Ci0gICAgICAvLyBJZiBzbywgd2UgY2FuIHNhZmVseSBjYXN0LgotICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHN0ZmFjdG9yeSA9ICgoU0FYVHJhbnNmb3JtZXJGYWN0b3J5KSB0ZmFjdG9yeSk7Ci0gICAgICAKLSAgICAgIC8vIEEgVHJhbnNmb3JtZXJIYW5kbGVyIGlzIGEgQ29udGVudEhhbmRsZXIgdGhhdCB3aWxsIGxpc3RlbiBmb3IgCi0gICAgICAvLyBTQVggZXZlbnRzLCBhbmQgdHJhbnNmb3JtIHRoZW0gdG8gdGhlIHJlc3VsdC4KLSAgICAgIFRyYW5zZm9ybWVySGFuZGxlciBoYW5kbGVyIAotICAgICAgICA9IHN0ZmFjdG9yeS5uZXdUcmFuc2Zvcm1lckhhbmRsZXIobmV3IFN0cmVhbVNvdXJjZSh4c2xJRCkpOwotCi0gICAgICAvLyBTZXQgdGhlIHJlc3VsdCBoYW5kbGluZyB0byBiZSBhIHNlcmlhbGl6YXRpb24gdG8gU3lzdGVtLm91dC4KLSAgICAgIFJlc3VsdCByZXN1bHQgPSBuZXcgU0FYUmVzdWx0KG5ldyBFeGFtcGxlQ29udGVudEhhbmRsZXIoKSk7Ci0gICAgICBoYW5kbGVyLnNldFJlc3VsdChyZXN1bHQpOwotICAgICAgCi0gICAgICAvLyBDcmVhdGUgYSByZWFkZXIsIGFuZCBzZXQgaXQncyBjb250ZW50IGhhbmRsZXIgdG8gYmUgdGhlIFRyYW5zZm9ybWVySGFuZGxlci4KLSAgICAgIFhNTFJlYWRlciByZWFkZXI9bnVsbDsKLQotICAgICAgLy8gVXNlIEpBWFAxLjEgKCBpZiBwb3NzaWJsZSApCi0gICAgICB0cnkgewotCSAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5PQotCSAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQkgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUoIHRydWUgKTsKLQkgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyPQotCSAgICAgIGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0JICByZWFkZXI9amF4cFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQkgIAotICAgICAgfSBjYXRjaCggamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCApIHsKLQkgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oIGV4ICk7Ci0gICAgICB9IGNhdGNoKCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSApIHsKLQkgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oIGV4MS50b1N0cmluZygpICk7Ci0gICAgICB9IGNhdGNoKCBOb1N1Y2hNZXRob2RFcnJvciBleDIgKSB7Ci0gICAgICB9Ci0gICAgICBpZiggcmVhZGVyPT1udWxsICkgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgICAgIAotICAgICAgLy8gSXQncyBhIGdvb2QgaWRlYSBmb3IgdGhlIHBhcnNlciB0byBzZW5kIGxleGljYWwgZXZlbnRzLgotICAgICAgLy8gVGhlIFRyYW5zZm9ybWVySGFuZGxlciBpcyBhbHNvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAgICByZWFkZXIuc2V0UHJvcGVydHkoImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsIGhhbmRsZXIpOwotICAgICAgCi0gICAgICAvLyBQYXJzZSB0aGUgc291cmNlIFhNTCwgYW5kIHNlbmQgdGhlIHBhcnNlIGV2ZW50cyB0byB0aGUgVHJhbnNmb3JtZXJIYW5kbGVyLgotICAgICAgcmVhZGVyLnBhcnNlKHNvdXJjZUlEKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICAgIkNhbid0IGRvIGV4YW1wbGVDb250ZW50SGFuZGxlclRvQ29udGVudEhhbmRsZXIgYmVjYXVzZSB0ZmFjdG9yeSBpcyBub3QgYSBTQVhUcmFuc2Zvcm1lckZhY3RvcnkiKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTaG93IHRoZSBUcmFuc2Zvcm1lciBhcyBhIFNBWDIgWE1MUmVhZGVyLiAgQW4gWE1MRmlsdGVyIG9idGFpbmVkIAotICAgKiBmcm9tIG5ld1hNTEZpbHRlciBzaG91bGQgYWN0IGFzIGEgdHJhbnNmb3JtaW5nIFhNTFJlYWRlciBpZiBzZXRQYXJlbnQgaXMgbm90Ci0gICAqIGNhbGxlZC4gIEludGVybmFsbHksIGFuIFhNTFJlYWRlciBpcyBjcmVhdGVkIGFzIHRoZSBwYXJlbnQgZm9yIHRoZSBYTUxGaWx0ZXIuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZVhNTFJlYWRlcihTdHJpbmcgc291cmNlSUQsIFN0cmluZyB4c2xJRCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiAgICAvLyAsIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0ZmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIGlmKHRmYWN0b3J5LmdldEZlYXR1cmUoU0FYU291cmNlLkZFQVRVUkUpKQotICAgIHsKLSAgICAgIFhNTFJlYWRlciByZWFkZXIgCi0gICAgICAgID0gKChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRmYWN0b3J5KS5uZXdYTUxGaWx0ZXIobmV3IFN0cmVhbVNvdXJjZSh4c2xJRCkpOwotICAgICAgCi0gICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIobmV3IEV4YW1wbGVDb250ZW50SGFuZGxlcigpKTsKLQotICAgICAgcmVhZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShzb3VyY2VJRCkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRmYWN0b3J5IGRvZXMgbm90IHN1cHBvcnQgU0FYIGZlYXR1cmVzISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNob3cgdGhlIFRyYW5zZm9ybWVyIGFzIGEgc2ltcGxlIFhNTEZpbHRlci4gIFRoaXMgaXMgcHJldHR5IHNpbWlsYXIKLSAgICogdG8gZXhhbXBsZVhNTFJlYWRlciwgZXhjZXB0IHRoYXQgaGVyZSB0aGUgcGFyZW50IFhNTFJlYWRlciBpcyBjcmVhdGVkIAotICAgKiBieSB0aGUgY2FsbGVyLCBpbnN0ZWFkIG9mIGF1dG9tYXRpY2FsbHkgd2l0aGluIHRoZSBYTUxGaWx0ZXIuICBUaGlzIAotICAgKiBnaXZlcyB0aGUgY2FsbGVyIG1vcmUgZGlyZWN0IGNvbnRyb2wgb3ZlciB0aGUgcGFyZW50IHJlYWRlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBleGFtcGxlWE1MRmlsdGVyKFN0cmluZyBzb3VyY2VJRCwgU3RyaW5nIHhzbElEKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uICAgIC8vICwgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICBYTUxSZWFkZXIgcmVhZGVyPW51bGw7Ci0gICAgCi0gICAgLy8gVXNlIEpBWFAxLjEgKCBpZiBwb3NzaWJsZSApCi0gICAgdHJ5IHsKLQlqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGZhY3Rvcnk9Ci0JICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQkgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUoIHRydWUgKTsKLQkgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyPQotCSAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCXJlYWRlcj1qYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotCQotICAgIH0gY2F0Y2goIGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXggKSB7Ci0JdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiggZXggKTsKLSAgICB9IGNhdGNoKCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSApIHsKLQl0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKCBleDEudG9TdHJpbmcoKSApOwotICAgIH0gY2F0Y2goIE5vU3VjaE1ldGhvZEVycm9yIGV4MiApIHsKLSAgICB9Ci0gICAgaWYoIHJlYWRlcj09bnVsbCApIHJlYWRlciA9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgLy8gVGhlIHRyYW5zZm9ybWVyIHdpbGwgdXNlIGEgU0FYIHBhcnNlciBhcyBpdCdzIHJlYWRlci4gICAgCi0gICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKG5ldyBFeGFtcGxlQ29udGVudEhhbmRsZXIoKSk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgcmVhZGVyLnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYyIsCi0gICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0KLSAgICAgIC8vIFdoYXQgY2FuIHdlIGRvPwotICAgICAgLy8gVE9ETzogVXNlciBkaWFnbm9zdGljcy4KLSAgICB9Ci0KLSAgICBYTUxGaWx0ZXIgZmlsdGVyIAotICAgICAgPSAoKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSkgdGZhY3RvcnkpLm5ld1hNTEZpbHRlcihuZXcgU3RyZWFtU291cmNlKHhzbElEKSk7Ci0KLSAgICBmaWx0ZXIuc2V0UGFyZW50KHJlYWRlcik7Ci0KLSAgICAvLyBOb3csIHdoZW4geW91IGNhbGwgdHJhbnNmb3JtZXIucGFyc2UsIGl0IHdpbGwgc2V0IGl0c2VsZiBhcyAKLSAgICAvLyB0aGUgY29udGVudCBoYW5kbGVyIGZvciB0aGUgcGFyc2VyIG9iamVjdCAoaXQncyAicGFyZW50IiksIGFuZCAKLSAgICAvLyB3aWxsIHRoZW4gY2FsbCB0aGUgcGFyc2UgbWV0aG9kIG9uIHRoZSBwYXJzZXIuCi0gICAgZmlsdGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShzb3VyY2VJRCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZXhhbXBsZSBzaG93cyBob3cgdG8gY2hhaW4gZXZlbnRzIGZyb20gb25lIFRyYW5zZm9ybWVyCi0gICAqIHRvIGFub3RoZXIgdHJhbnNmb3JtZXIsIHVzaW5nIHRoZSBUcmFuc2Zvcm1lciBhcyBhCi0gICAqIFNBWDIgWE1MRmlsdGVyL1hNTFJlYWRlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBleGFtcGxlWE1MRmlsdGVyQ2hhaW4oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUlELCBTdHJpbmcgeHNsSURfMSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHhzbElEXzIsIFN0cmluZyB4c2xJRF8zKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAKLSAgICBUZW1wbGF0ZXMgc3R5bGVzaGVldDEgPSB0ZmFjdG9yeS5uZXdUZW1wbGF0ZXMobmV3IFN0cmVhbVNvdXJjZSh4c2xJRF8xKSk7Ci0gICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIxID0gc3R5bGVzaGVldDEubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAKLSAgICAgLy8gSWYgb25lIHN1Y2Nlc3MsIGFzc3VtZSBhbGwgd2lsbCBzdWNjZWVkLgotICAgIGlmICh0ZmFjdG9yeS5nZXRGZWF0dXJlKFNBWFNvdXJjZS5GRUFUVVJFKSkKLSAgICB7Ci0gICAgICBTQVhUcmFuc2Zvcm1lckZhY3Rvcnkgc3RmID0gKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSl0ZmFjdG9yeTsKLSAgICAgIFhNTFJlYWRlciByZWFkZXI9bnVsbDsKLQotICAgICAgLy8gVXNlIEpBWFAxLjEgKCBpZiBwb3NzaWJsZSApCi0gICAgICB0cnkgewotCSAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5PQotCSAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQkgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUoIHRydWUgKTsKLQkgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyPQotCSAgICAgIGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0JICByZWFkZXI9amF4cFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQkgIAotICAgICAgfSBjYXRjaCggamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCApIHsKLQkgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oIGV4ICk7Ci0gICAgICB9IGNhdGNoKCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSApIHsKLQkgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oIGV4MS50b1N0cmluZygpICk7Ci0gICAgICB9IGNhdGNoKCBOb1N1Y2hNZXRob2RFcnJvciBleDIgKSB7Ci0gICAgICB9Ci0gICAgICBpZiggcmVhZGVyPT1udWxsICkgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLQotICAgICAgWE1MRmlsdGVyIGZpbHRlcjEgPSBzdGYubmV3WE1MRmlsdGVyKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSURfMSkpOwotICAgICAgWE1MRmlsdGVyIGZpbHRlcjIgPSBzdGYubmV3WE1MRmlsdGVyKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSURfMikpOwotICAgICAgWE1MRmlsdGVyIGZpbHRlcjMgPSBzdGYubmV3WE1MRmlsdGVyKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSURfMykpOwotCi0gICAgICBpZiAobnVsbCAhPSBmaWx0ZXIxKSAvLyBJZiBvbmUgc3VjY2VzcywgYXNzdW1lIGFsbCB3ZXJlIHN1Y2Nlc3MuCi0gICAgICB7Ci0gICAgICAgIC8vIHRyYW5zZm9ybWVyMSB3aWxsIHVzZSBhIFNBWCBwYXJzZXIgYXMgaXQncyByZWFkZXIuICAgIAotICAgICAgICBmaWx0ZXIxLnNldFBhcmVudChyZWFkZXIpOwotCi0gICAgICAgIC8vIHRyYW5zZm9ybWVyMiB3aWxsIHVzZSB0cmFuc2Zvcm1lcjEgYXMgaXQncyByZWFkZXIuCi0gICAgICAgIGZpbHRlcjIuc2V0UGFyZW50KGZpbHRlcjEpOwotCi0gICAgICAgIC8vIHRyYW5zZm9ybTMgd2lsbCB1c2UgdHJhbnNmb3JtMiBhcyBpdCdzIHJlYWRlci4KLSAgICAgICAgZmlsdGVyMy5zZXRQYXJlbnQoZmlsdGVyMik7Ci0KLSAgICAgICAgZmlsdGVyMy5zZXRDb250ZW50SGFuZGxlcihuZXcgRXhhbXBsZUNvbnRlbnRIYW5kbGVyKCkpOwotICAgICAgICAvLyBmaWx0ZXIzLnNldENvbnRlbnRIYW5kbGVyKG5ldyBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyKCkpOwotCi0gICAgICAgIC8vIE5vdywgd2hlbiB5b3UgY2FsbCB0cmFuc2Zvcm1lcjMgdG8gcGFyc2UsIGl0IHdpbGwgc2V0ICAKLSAgICAgICAgLy8gaXRzZWxmIGFzIHRoZSBDb250ZW50SGFuZGxlciBmb3IgdHJhbnNmb3JtMiwgYW5kIAotICAgICAgICAvLyBjYWxsIHRyYW5zZm9ybTIucGFyc2UsIHdoaWNoIHdpbGwgc2V0IGl0c2VsZiBhcyB0aGUgCi0gICAgICAgIC8vIGNvbnRlbnQgaGFuZGxlciBmb3IgdHJhbnNmb3JtMSwgYW5kIGNhbGwgdHJhbnNmb3JtMS5wYXJzZSwgCi0gICAgICAgIC8vIHdoaWNoIHdpbGwgc2V0IGl0c2VsZiBhcyB0aGUgY29udGVudCBsaXN0ZW5lciBmb3IgdGhlIAotICAgICAgICAvLyBTQVggcGFyc2VyLCBhbmQgY2FsbCBwYXJzZXIucGFyc2UobmV3IElucHV0U291cmNlKCJ4bWwvZm9vLnhtbCIpKS4KLSAgICAgICAgZmlsdGVyMy5wYXJzZShuZXcgSW5wdXRTb3VyY2Uoc291cmNlSUQpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbid0IGRvIGV4YW1wbGVYTUxGaWx0ZXIgYmVjYXVzZSAiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgInRmYWN0b3J5IGRvZXNuJ3Qgc3VwcG9ydCBhc1hNTEZpbHRlcigpIik7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAgICAgICAgICAgICAgICAgICAgIkNhbid0IGRvIGV4YW1wbGVYTUxGaWx0ZXIgYmVjYXVzZSAiKwotICAgICAgICAgICAgICAgICAgICAgICAgICJ0ZmFjdG9yeSBpcyBub3QgYSBTQVhUcmFuc2Zvcm1lckZhY3RvcnkiKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2hvdyBob3cgdG8gdHJhbnNmb3JtIGEgRE9NIHRyZWUgaW50byBhbm90aGVyIERPTSB0cmVlLgotICAgKiBUaGlzIHVzZXMgdGhlIGphdmF4LnhtbC5wYXJzZXJzIHRvIHBhcnNlIGFuIFhNTCBmaWxlIGludG8gYQotICAgKiBET00sIGFuZCBjcmVhdGUgYW4gb3V0cHV0IERPTS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBleGFtcGxlRE9NMkRPTShTdHJpbmcgc291cmNlSUQsIFN0cmluZyB4c2xJRCkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwKLSAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgIGlmICh0ZmFjdG9yeS5nZXRGZWF0dXJlKERPTVNvdXJjZS5GRUFUVVJFKSkKLSAgICB7Ci0gICAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzOwotCi0gICAgICB7Ci0gICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGZhY3RvcnkgPQotICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgZGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgICAgIERvY3VtZW50QnVpbGRlciBkb2NCdWlsZGVyID0gZGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgICAgIG9yZy53M2MuZG9tLkRvY3VtZW50IG91dE5vZGUgPSBkb2NCdWlsZGVyLm5ld0RvY3VtZW50KCk7Ci0gICAgICAgIE5vZGUgZG9jID0gZG9jQnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoeHNsSUQpKTsKLSAKLSAgICAgICAgRE9NU291cmNlIGRzb3VyY2UgPSBuZXcgRE9NU291cmNlKGRvYyk7Ci0gICAgICAgIC8vIElmIHdlIGRvbid0IGRvIHRoaXMsIHRoZSB0cmFuc2Zvcm1lciB3b24ndCBrbm93IGhvdyB0byAKLSAgICAgICAgLy8gcmVzb2x2ZSByZWxhdGl2ZSBVUkxzIGluIHRoZSBzdHlsZXNoZWV0LgotICAgICAgICBkc291cmNlLnNldFN5c3RlbUlkKHhzbElEKTsKLQotICAgICAgICB0ZW1wbGF0ZXMgPSB0ZmFjdG9yeS5uZXdUZW1wbGF0ZXMoZHNvdXJjZSk7Ci0gICAgICB9Ci0KLSAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdGVtcGxhdGVzLm5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgRG9jdW1lbnRCdWlsZGVyIGRvY0J1aWxkZXIgPSBkZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICAgIG9yZy53M2MuZG9tLkRvY3VtZW50IG91dE5vZGUgPSBkb2NCdWlsZGVyLm5ld0RvY3VtZW50KCk7Ci0gICAgICBOb2RlIGRvYyA9IGRvY0J1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKHNvdXJjZUlEKSk7Ci0KLSAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybShuZXcgRE9NU291cmNlKGRvYyksIG5ldyBET01SZXN1bHQob3V0Tm9kZSkpOwotICAgICAgCi0gICAgICBUcmFuc2Zvcm1lciBzZXJpYWxpemVyID0gdGZhY3RvcnkubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgIHNlcmlhbGl6ZXIudHJhbnNmb3JtKG5ldyBET01Tb3VyY2Uob3V0Tm9kZSksIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotCi0gICAgICByZXR1cm4gb3V0Tm9kZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheAotICAgICAgICAuU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJET00gbm9kZSBwcm9jZXNzaW5nIG5vdCBzdXBwb3J0ZWQhIik7Ci0gICAgfQotICB9IAotCi0gIC8qKgotICAgKiBUaGlzIHNob3dzIGhvdyB0byBzZXQgYSBwYXJhbWV0ZXIgZm9yIHVzZSBieSB0aGUgdGVtcGxhdGVzLiBVc2UgCi0gICAqIHR3byB0cmFuc2Zvcm1lcnMgdG8gc2hvdyB0aGF0IGRpZmZlcmVudCBwYXJhbWV0ZXJzIG1heSBiZSBzZXQgCi0gICAqIG9uIGRpZmZlcmVudCB0cmFuc2Zvcm1lcnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZVBhcmFtKFN0cmluZyBzb3VyY2VJRCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHhzbElEKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzID0gdGZhY3RvcnkubmV3VGVtcGxhdGVzKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSUQpKTsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcjEgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcjIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLQotICAgIHRyYW5zZm9ybWVyMS5zZXRQYXJhbWV0ZXIoImEtcGFyYW0iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImhlbGxvIHRvIHlvdSEiKTsKLSAgICB0cmFuc2Zvcm1lcjEudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2Uoc291cmNlSUQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdChTeXN0ZW0ub3V0KSk7Ci0gICAgCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcbj09PT09PT09PSIpOwotICAgIAotICAgIHRyYW5zZm9ybWVyMi5zZXRPdXRwdXRQcm9wZXJ0eShPdXRwdXRLZXlzLklOREVOVCwgInllcyIpOwotICAgIHRyYW5zZm9ybWVyMi50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShzb3VyY2VJRCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNob3cgdGhlIHRoYXQgYSB0cmFuc2Zvcm1lciBjYW4gYmUgcmV1c2VkLCBhbmQgc2hvdyByZXNldHRpbmcgCi0gICAqIGEgcGFyYW1ldGVyIG9uIHRoZSB0cmFuc2Zvcm1lci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBleGFtcGxlVHJhbnNmb3JtZXJSZXVzZShTdHJpbmcgc291cmNlSUQsIFN0cmluZyB4c2xJRCkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgLy8gQ3JlYXRlIGEgdHJhbnNmb3JtIGZhY3RvcnkgaW5zdGFuY2UuCi0gICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgCi0gICAgLy8gQ3JlYXRlIGEgdHJhbnNmb3JtZXIgZm9yIHRoZSBzdHlsZXNoZWV0LgotICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyIAotICAgICAgPSB0ZmFjdG9yeS5uZXdUcmFuc2Zvcm1lcihuZXcgU3RyZWFtU291cmNlKHhzbElEKSk7Ci0gICAgCi0gICAgdHJhbnNmb3JtZXIuc2V0UGFyYW1ldGVyKCJhLXBhcmFtIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoZWxsbyB0byB5b3UhIik7Ci0gICAgCi0gICAgLy8gVHJhbnNmb3JtIHRoZSBzb3VyY2UgWE1MIHRvIFN5c3RlbS5vdXQuCi0gICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKCBuZXcgU3RyZWFtU291cmNlKHNvdXJjZUlEKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcbj09PT09PT09PVxuIik7Ci0KLSAgICB0cmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIoImEtcGFyYW0iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImhlbGxvIHRvIG1lISIpOwotICAgIHRyYW5zZm9ybWVyLnNldE91dHB1dFByb3BlcnR5KE91dHB1dEtleXMuSU5ERU5ULCAieWVzIik7Ci0KLSAgICAvLyBUcmFuc2Zvcm0gdGhlIHNvdXJjZSBYTUwgdG8gU3lzdGVtLm91dC4KLSAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oIG5ldyBTdHJlYW1Tb3VyY2Uoc291cmNlSUQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdChTeXN0ZW0ub3V0KSk7Ci0gIH0KLQotICAvKioKLSAgICogU2hvdyBob3cgdG8gb3ZlcnJpZGUgb3V0cHV0IHByb3BlcnRpZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZU91dHB1dFByb3BlcnRpZXMoU3RyaW5nIHNvdXJjZUlELCBTdHJpbmcgeHNsSUQpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0gICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgVGVtcGxhdGVzIHRlbXBsYXRlcyA9IHRmYWN0b3J5Lm5ld1RlbXBsYXRlcyhuZXcgU3RyZWFtU291cmNlKHhzbElEKSk7Ci0gICAgUHJvcGVydGllcyBvcHJvcHMgPSB0ZW1wbGF0ZXMuZ2V0T3V0cHV0UHJvcGVydGllcygpOwotCi0gICAgb3Byb3BzLnB1dChPdXRwdXRLZXlzLklOREVOVCwgInllcyIpOwotCi0gICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLQotICAgIHRyYW5zZm9ybWVyLnNldE91dHB1dFByb3BlcnRpZXMob3Byb3BzKTsKLSAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShzb3VyY2VJRCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNob3cgaG93IHRvIGdldCBzdHlsZXNoZWV0cyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbgotICAgKiB4bWwgZG9jdW1lbnQgdmlhIHRoZSB4bWwtc3R5bGVzaGVldCBQSSAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LykuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZVVzZUFzc29jaWF0ZWQoU3RyaW5nIHNvdXJjZUlEKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgIC8vIFRoZSBET00gdGZhY3Rvcnkgd2lsbCBoYXZlIGl0J3Mgb3duIHdheSwgYmFzZWQgb24gRE9NMiwgCi0gICAgLy8gb2YgZ2V0dGluZyBhc3NvY2lhdGVkIHN0eWxlc2hlZXRzLgotICAgIGlmICh0ZmFjdG9yeSBpbnN0YW5jZW9mIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSkKLSAgICB7Ci0gICAgICBTQVhUcmFuc2Zvcm1lckZhY3Rvcnkgc3RmID0gKChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRmYWN0b3J5KTsKLSAgICAgIFNvdXJjZSBzb3VyY2VzID0KLSAgICAgICAgc3RmLmdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KG5ldyBTdHJlYW1Tb3VyY2Uoc291cmNlSUQpLAotICAgICAgICAgIG51bGwsIG51bGwsIG51bGwpOwotCi0gICAgICBpZihudWxsICE9IHNvdXJjZXMpCi0gICAgICB7Ci0gICAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdGZhY3RvcnkubmV3VHJhbnNmb3JtZXIoc291cmNlcyk7Ci0KLSAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2Uoc291cmNlSUQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdChTeXN0ZW0ub3V0KSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQ2FuJ3QgZmluZCB0aGUgYXNzb2NpYXRlZCBzdHlsZXNoZWV0ISIpOwotICAgICAgfQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFNob3cgdGhlIFRyYW5zZm9ybWVyIHVzaW5nIFNBWCBldmVudHMgaW4gYW5kIERPTSBub2RlcyBvdXQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZUNvbnRlbnRIYW5kbGVyMkRPTShTdHJpbmcgc291cmNlSUQsIFN0cmluZyB4c2xJRCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAvLyBNYWtlIHN1cmUgdGhlIHRyYW5zZm9ybWVyIGZhY3Rvcnkgd2Ugb2J0YWluZWQgc3VwcG9ydHMgYm90aAotICAgIC8vIERPTSBhbmQgU0FYLgotICAgIGlmICh0ZmFjdG9yeS5nZXRGZWF0dXJlKFNBWFNvdXJjZS5GRUFUVVJFKQotICAgICAgICAmJiB0ZmFjdG9yeS5nZXRGZWF0dXJlKERPTVNvdXJjZS5GRUFUVVJFKSkKLSAgICB7Ci0gICAgICAvLyBXZSBjYW4gbm93IHNhZmVseSBjYXN0IHRvIGEgU0FYVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHNmYWN0b3J5ID0gKFNBWFRyYW5zZm9ybWVyRmFjdG9yeSkgdGZhY3Rvcnk7Ci0gICAgICAKLSAgICAgIC8vIENyZWF0ZSBhbiBEb2N1bWVudCBub2RlIGFzIHRoZSByb290IGZvciB0aGUgb3V0cHV0LgotICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkZmFjdG9yeSAKLSAgICAgICAgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICBEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgb3JnLnczYy5kb20uRG9jdW1lbnQgb3V0Tm9kZSA9IGRvY0J1aWxkZXIubmV3RG9jdW1lbnQoKTsKLSAgICAgIAotICAgICAgLy8gQ3JlYXRlIGEgQ29udGVudEhhbmRsZXIgdGhhdCBjYW4gbGlzdG9uIHRvIFNBWCBldmVudHMgCi0gICAgICAvLyBhbmQgdHJhbnNmb3JtIHRoZSBvdXRwdXQgdG8gRE9NIG5vZGVzLgotICAgICAgVHJhbnNmb3JtZXJIYW5kbGVyIGhhbmRsZXIgCi0gICAgICAgID0gc2ZhY3RvcnkubmV3VHJhbnNmb3JtZXJIYW5kbGVyKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSUQpKTsKLSAgICAgIGhhbmRsZXIuc2V0UmVzdWx0KG5ldyBET01SZXN1bHQob3V0Tm9kZSkpOwotICAgICAgCi0gICAgICAvLyBDcmVhdGUgYSByZWFkZXIgYW5kIHNldCBpdCdzIENvbnRlbnRIYW5kbGVyIHRvIGJlIHRoZSAKLSAgICAgIC8vIHRyYW5zZm9ybWVyLgotICAgICAgWE1MUmVhZGVyIHJlYWRlcj1udWxsOwotCi0gICAgICAvLyBVc2UgSkFYUDEuMSAoIGlmIHBvc3NpYmxlICkKLSAgICAgIHRyeSB7Ci0JICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGZhY3Rvcnk9Ci0JICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCSAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSggdHJ1ZSApOwotCSAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyIGpheHBQYXJzZXI9Ci0JICAgICAgZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLQkgIHJlYWRlcj1qYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotCSAgCi0gICAgICB9IGNhdGNoKCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4ICkgewotCSAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiggZXggKTsKLSAgICAgIH0gY2F0Y2goIGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxICkgewotCSAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiggZXgxLnRvU3RyaW5nKCkgKTsKLSAgICAgIH0gY2F0Y2goIE5vU3VjaE1ldGhvZEVycm9yIGV4MiApIHsKLSAgICAgIH0KLSAgICAgIGlmKCByZWFkZXI9PW51bGwgKSByZWFkZXI9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7Ci0gICAgICByZWFkZXIuc2V0UHJvcGVydHkoImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcik7Ci0gICAgICAKLSAgICAgIC8vIFNlbmQgdGhlIFNBWCBldmVudHMgZnJvbSB0aGUgcGFyc2VyIHRvIHRoZSB0cmFuc2Zvcm1lciwKLSAgICAgIC8vIGFuZCB0aHVzIHRvIHRoZSBET00gdHJlZS4KLSAgICAgIHJlYWRlci5wYXJzZShzb3VyY2VJRCk7Ci0gICAgICAKLSAgICAgIC8vIFNlcmlhbGl6ZSB0aGUgbm9kZSBmb3IgZGlhZ25vc2lzLgotICAgICAgZXhhbXBsZVNlcmlhbGl6ZU5vZGUob3V0Tm9kZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAgICJDYW4ndCBkbyBleGFtcGxlQ29udGVudEhhbmRsZXJUb0NvbnRlbnRIYW5kbGVyIGJlY2F1c2UgdGZhY3RvcnkgaXMgbm90IGEgU0FYVHJhbnNmb3JtZXJGYWN0b3J5Iik7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogU2VyaWFsaXplIGEgbm9kZSB0byBTeXN0ZW0ub3V0LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIGV4YW1wbGVTZXJpYWxpemVOb2RlKE5vZGUgbm9kZSkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwKLSAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsgCi0gICAgCi0gICAgLy8gVGhpcyBjcmVhdGVzIGEgdHJhbnNmb3JtZXIgdGhhdCBkb2VzIGEgc2ltcGxlIGlkZW50aXR5IHRyYW5zZm9ybSwgCi0gICAgLy8gYW5kIHRodXMgY2FuIGJlIHVzZWQgZm9yIGFsbCBpbnRlbnRzIGFuZCBwdXJwb3NlcyBhcyBhIHNlcmlhbGl6ZXIuCi0gICAgVHJhbnNmb3JtZXIgc2VyaWFsaXplciA9IHRmYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgCi0gICAgc2VyaWFsaXplci5zZXRPdXRwdXRQcm9wZXJ0eShPdXRwdXRLZXlzLklOREVOVCwgInllcyIpOwotICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0UHJvcGVydHkoT3V0cHV0S2V5cy5PTUlUX1hNTF9ERUNMQVJBVElPTiwgInllcyIpOwotICAgIHNlcmlhbGl6ZXIudHJhbnNmb3JtKG5ldyBET01Tb3VyY2Uobm9kZSksIAotICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCkpOwotICB9ICAKLSAgCi0gIC8qKgotICAgKiBBIGZ1bGxlciBleGFtcGxlIHNob3dpbmcgaG93IHRoZSBUckFYIGludGVyZmFjZSBjYW4gYmUgdXNlZCAKLSAgICogdG8gc2VyaWFsaXplIGEgRE9NIHRyZWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZXhhbXBsZUFzU2VyaWFsaXplcihTdHJpbmcgc291cmNlSUQsIFN0cmluZyB4c2xJRCkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwKLSAgICBQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIERvY3VtZW50QnVpbGRlciBkb2NCdWlsZGVyID0gZGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgb3JnLnczYy5kb20uRG9jdW1lbnQgb3V0Tm9kZSA9IGRvY0J1aWxkZXIubmV3RG9jdW1lbnQoKTsKLSAgICBOb2RlIGRvYyA9IGRvY0J1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKHNvdXJjZUlEKSk7Ci0KLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsgCi0gICAgCi0gICAgLy8gVGhpcyBjcmVhdGVzIGEgdHJhbnNmb3JtZXIgdGhhdCBkb2VzIGEgc2ltcGxlIGlkZW50aXR5IHRyYW5zZm9ybSwgCi0gICAgLy8gYW5kIHRodXMgY2FuIGJlIHVzZWQgZm9yIGFsbCBpbnRlbnRzIGFuZCBwdXJwb3NlcyBhcyBhIHNlcmlhbGl6ZXIuCi0gICAgVHJhbnNmb3JtZXIgc2VyaWFsaXplciA9IHRmYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgCi0gICAgUHJvcGVydGllcyBvcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOwotICAgIG9wcm9wcy5wdXQoIm1ldGhvZCIsICJodG1sIik7Ci0gICAgb3Byb3BzLnB1dCgiaW5kZW50LWFtb3VudCIsICIyIik7Ci0gICAgc2VyaWFsaXplci5zZXRPdXRwdXRQcm9wZXJ0aWVzKG9wcm9wcyk7Ci0gICAgc2VyaWFsaXplci50cmFuc2Zvcm0obmV3IERPTVNvdXJjZShkb2MpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLSAgfQotICAKLQotICBwcml2YXRlIHN0YXRpYyB2b2lkICBoYW5kbGVFeGNlcHRpb24oIEV4Y2VwdGlvbiBleCApIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVYQ0VQVElPTjogIiApOwotICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOwotICAgIAotICAgIGlmKCBleCBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiApIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbnRlcm5hbCBleGNlcHRpb246ICIgKTsKLSAgICAgIFRocm93YWJsZSBleDE9KChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24pZXgpLmdldEV4Y2VwdGlvbigpOwotICAgICAgZXgxLnByaW50U3RhY2tUcmFjZSgpOwotCi0gICAgICBpZiggZXgxIGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uICkgewotCSAgRXhjZXB0aW9uIGV4Mj0oKFNBWEV4Y2VwdGlvbilleDEpLmdldEV4Y2VwdGlvbigpOwotCSAgU3lzdGVtLm91dC5wcmludGxuKCJJbnRlcm5hbCBzdWItZXhjZXB0aW9uOiAiICk7Ci0JICBleDIucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NhbXBsZXMvdHJheC94bWwvYmF6LnhtbCBiL3NhbXBsZXMvdHJheC94bWwvYmF6LnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWVjZjQ3My4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYXgveG1sL2Jhei54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249JzEuMCc/PgotPGZvbzpkb2N1bWVudCAKLQkJICB4bWxuczpmb289Imh0dHA6Ly9hcGFjaGUub3JnL2ZvbyIKLQkJICB4bWxuczpiYXI9Imh0dHA6Ly9hcGFjaGUub3JnL2JhciI+Ci08YmFyOmVsZW1lbnQ+TXlCYXo8L2JhcjplbGVtZW50PgotPC9mb286ZG9jdW1lbnQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy90cmF4L3htbC9mb28ueG1sIGIvc2FtcGxlcy90cmF4L3htbC9mb28ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3OTU5N2FiLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvdHJheC94bWwvZm9vLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDEwICswLDAgQEAKLTw/eG1sIHZlcnNpb249JzEuMCc/PgotPD94bWwtc3R5bGVzaGVldCB0eXBlPSJ0ZXh0L3hzbCIgaHJlZj0iLi4veHNsL2Zvby54c2wiPz4KLTxmb286ZG9jdW1lbnQgCi0JCSAgeG1sbnM6Zm9vPSJodHRwOi8vYXBhY2hlLm9yZy9mb28iCi0JCSAgeG1sbnM6YmFyPSJodHRwOi8vYXBhY2hlLm9yZy9iYXIiCi0JCSAgZmlsZS1uYW1lPSJ0ZXN0IgotICAgICAgICAgZmlsZS1wYXRoPSJ3b3JrIgotCQkgIGNyZWF0aW9uLWRhdGU9Ijk3MTI1NTY5MjA3OCI+Ci08YmFyOmVsZW1lbnQ+TXlCYXI8L2JhcjplbGVtZW50PgotPC9mb286ZG9jdW1lbnQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy90cmF4L3htbC9zdWJkaXIxL2ZvbzIueG1sIGIvc2FtcGxlcy90cmF4L3htbC9zdWJkaXIxL2ZvbzIueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NzA4YWU0Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvdHJheC94bWwvc3ViZGlyMS9mb28yLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDIgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0nMS4wJz8+Ci08ZG9jPnRleHQgaW4gZm9vMi54bWw8L2RvYz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3RyYXgveG1sL3N1YmRpcjEvc3ViZGlyMi9mb28zLnhtbCBiL3NhbXBsZXMvdHJheC94bWwvc3ViZGlyMS9zdWJkaXIyL2ZvbzMueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3N2RhMWYwLi4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvdHJheC94bWwvc3ViZGlyMS9zdWJkaXIyL2ZvbzMueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPScxLjAnPz4KLTxkb2M+dGV4dCBpbiBmb28zLnhtbDwvZG9jPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvdHJheC94c2wvYmF6LnhzbCBiL3NhbXBsZXMvdHJheC94c2wvYmF6LnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzE4NDNiMy4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYXgveHNsL2Jhei54c2wKKysrIC9kZXYvbnVsbApAQCAtMSwxOCArMCwwIEBACi08eHNsOnN0eWxlc2hlZXQgCi0gICAgICB4bWxuczp4c2w9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybScgdmVyc2lvbj0nMS4wJz4KLSAgICAKLSAgPCEtLSBzYW1lIGFzIGZvby54c2wgYnV0IGRvZXNuJ3QgaW5jbHVkZSB0aGUgcGFyYW0gYmVjYXVzZSBvZiBhIGJ1ZyAtLT4gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgICA8b3V0PgotICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgIDwvb3V0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgICAgIAotICA8eHNsOnRlbXBsYXRlIAotICAgICAgbWF0Y2g9IkAqfCp8dGV4dCgpfHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSI+Ci0gICAgPHhzbDpjb3B5PgotICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgCi0gICAgICAgICBzZWxlY3Q9IkAqfCp8dGV4dCgpfHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSIvPgotICAgIDwveHNsOmNvcHk+Ci0gIDwveHNsOnRlbXBsYXRlPgotPC94c2w6c3R5bGVzaGVldD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zYW1wbGVzL3RyYXgveHNsL2Zvby54c2wgYi9zYW1wbGVzL3RyYXgveHNsL2Zvby54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIxM2I5NDUuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy90cmF4L3hzbC9mb28ueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMjcgKzAsMCBAQAotPHhzbDpzdHlsZXNoZWV0IAotICAgICAgeG1sbnM6eHNsPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0nIHZlcnNpb249JzEuMCcKLSAgICAgIHhtbG5zOmJhcj0iaHR0cDovL2FwYWNoZS5vcmcvYmFyIgotICAgICAgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXM9ImJhciI+Ci0gICAgICAKLSAgPHhzbDppbmNsdWRlIGhyZWY9ImluYzEvaW5jMS54c2wiLz4KLSAgICAgIAotICA8eHNsOnBhcmFtIG5hbWU9ImEtcGFyYW0iPmRlZmF1bHQgcGFyYW0gdmFsdWU8L3hzbDpwYXJhbT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImJhcjplbGVtZW50Ij4KLSAgICA8YmFyPgotICAgICAgPHBhcmFtLXZhbD4KLSAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IiRhLXBhcmFtIi8+PHhzbDp0ZXh0PiwgPC94c2w6dGV4dD4KLSAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IiRteS12YXIiLz4KLSAgICAgIDwvcGFyYW0tdmFsPgotICAgICAgPGRhdGE+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvZGF0YT4KLSAgICA8L2Jhcj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gICAgICAKLSAgPHhzbDp0ZW1wbGF0ZSAKLSAgICAgIG1hdGNoPSJAKnwqfHRleHQoKXxwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkiPgotICAgIDx4c2w6Y29weT4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIAotICAgICAgICAgc2VsZWN0PSJAKnwqfHRleHQoKXxwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkiLz4KLSAgICA8L3hzbDpjb3B5PgotICA8L3hzbDp0ZW1wbGF0ZT4KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc2FtcGxlcy90cmF4L3hzbC9mb28yLnhzbCBiL3NhbXBsZXMvdHJheC94c2wvZm9vMi54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIwNGY1ZjAuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy90cmF4L3hzbC9mb28yLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDE0ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PiAKLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgIHhtbG5zOmJhcj0iaHR0cDovL2FwYWNoZS5vcmcvYmFyIj4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImJhciI+Ci0gICAgPG91dD4KLSAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+Ci0gICAgPC9vdXQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGV4dCgpIj4KLSAgPC94c2w6dGVtcGxhdGU+ICAKLSAKLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS9zYW1wbGVzL3RyYXgveHNsL2ZvbzMueHNsIGIvc2FtcGxlcy90cmF4L3hzbC9mb28zLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTFiZjQyYS4uMDAwMDAwMAotLS0gYS9zYW1wbGVzL3RyYXgveHNsL2ZvbzMueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMTQgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+IAotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0ib3V0Ij4KLSAgICA8b3V0PgotICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgIDwvb3V0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InRleHQoKSI+Ci0gICAgPHNvbWUtdGV4dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjwvc29tZS10ZXh0PgotICA8L3hzbDp0ZW1wbGF0ZT4gIAotICAgCi08L3hzbDpzdHlsZXNoZWV0PgpkaWZmIC0tZ2l0IGEvc2FtcGxlcy90cmF4L3hzbC9pbmMxL2luYzEueHNsIGIvc2FtcGxlcy90cmF4L3hzbC9pbmMxL2luYzEueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNGViYjI1Li4wMDAwMDAwCi0tLSBhL3NhbXBsZXMvdHJheC94c2wvaW5jMS9pbmMxLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDYgKzAsMCBAQAotPHhzbDpzdHlsZXNoZWV0IAotICAgICAgeG1sbnM6eHNsPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0nIHZlcnNpb249JzEuMCc+Ci0gICAgICAKLSAgPHhzbDppbmNsdWRlIGhyZWY9ImluYzIvaW5jMi54c2wiLz4KLSAgCi08L3hzbDpzdHlsZXNoZWV0PgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NhbXBsZXMvdHJheC94c2wvaW5jMS9pbmMyL2luYzIueHNsIGIvc2FtcGxlcy90cmF4L3hzbC9pbmMxL2luYzIvaW5jMi54c2wKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM2NzI4ZWIuLjAwMDAwMDAKLS0tIGEvc2FtcGxlcy90cmF4L3hzbC9pbmMxL2luYzIvaW5jMi54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw0ICswLDAgQEAKLTx4c2w6c3R5bGVzaGVldCAKLSAgICAgIHhtbG5zOnhzbD0naHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtJyB2ZXJzaW9uPScxLjAnPgotICA8eHNsOnZhcmlhYmxlIG5hbWU9Im15LXZhciIgc2VsZWN0PSIndGV4dCBmcm9tIG15LXZhciBpbiBpbmMyLnhzbCciLz4KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL01BTklGRVNULk1GIGIvc3JjL01BTklGRVNULk1GCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlODFmZGI4Li4wMDAwMDAwCi0tLSBhL3NyYy9NQU5JRkVTVC5NRgorKysgL2Rldi9udWxsCkBAIC0xLDYgKzAsMCBAQAotTWFuaWZlc3QtVmVyc2lvbjogMS4wCi1DcmVhdGVkLUJ5OiAxLjIuMiAoU3VuIE1pY3Jvc3lzdGVtcyBJbmMuKQotTWFpbi1DbGFzczogb3JnLmFwYWNoZS54YWxhbi54c2x0LlByb2Nlc3MKLUNsYXNzLVBhdGg6IGpheHAuamFyIHhlcmNlcy5qYXIgY3JpbXNvbi5qYXIKLQotCmRpZmYgLS1naXQgYS9zcmMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBiL3NyYy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzODQ1Y2MxLi4wMDAwMDAwCi0tLSBhL3NyYy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5CisrKyAvZGV2L251bGwKQEAgLTEgKzAsMCBAQAotb3JnLmFwYWNoZS54ZXJjZXMuamF4cC5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5SW1wbApkaWZmIC0tZ2l0IGEvc3JjL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkgYi9zcmMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODhiMjQ3Yy4uMDAwMDAwMAotLS0gYS9zcmMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeQorKysgL2Rldi9udWxsCkBAIC0xICswLDAgQEAKLW9yZy5hcGFjaGUueGVyY2VzLmpheHAuU0FYUGFyc2VyRmFjdG9yeUltcGwKZGlmZiAtLWdpdCBhL3NyYy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSBiL3NyYy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGU4NzdkYy4uMDAwMDAwMAotLS0gYS9zcmMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1vcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsCmRpZmYgLS1naXQgYS9zcmMvamF2YWRvY092ZXJ2aWV3Lmh0bWwgYi9zcmMvamF2YWRvY092ZXJ2aWV3Lmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgzNWQyNzguLjAwMDAwMDAKLS0tIGEvc3JjL2phdmFkb2NPdmVydmlldy5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTUgKzAsMCBAQAotPGh0bWw+Ci0gIDxoZWFkPjwvaGVhZD4KLSAgPGJvZHk+Ci0gICAgPHA+WGFsYW4tSmF2YSBpbXBsZW1lbnRzIHRoZSA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0IiB0YXJnZXQ9Il90b3AiPlczQyBSZWNvbW1lbmRhdGlvbiAxNiBOb3ZlbWJlciAxOTk5IFhTTAotICAgIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVmVyc2lvbiAxLjA8L0E+LjwvcD4KLSAgCi0gICAgPHA+WExTVCBpcyBhIHN0eWxlc2hlZXQgbGFuZ3VhZ2UgZm9yIHRyYW5zZm9ybWluZyBYTUwgZG9jdW1lbnRzIGludG8gb3RoZXIgWE1MIGRvY3VtZW50cywgSFRNTCBkb2N1bWVudHMsIAotICAgIG9yIG90aGVyIGRvY3VtZW50IHR5cGVzLiBUaGUgbGFuZ3VhZ2UgaW5jbHVkZXMgdGhlIFhTTCBUcmFuc2Zvcm1hdGlvbiB2b2NhYnVsYXJ5IGFuZCBYUGF0aCwgYSBsYW5ndWFnZSBmb3IKLSAgICBhZGRyZXNzaW5nIHBhcnRzIG9mIGFuIFhNTCBkb2N1bWVudC4gQW4gWFNMIHN0eWxlc2hlZXQgZGVzY3JpYmVzIGhvdyB0byB0cmFuc2Zvcm0gdGhlIHRyZWUgb2Ygbm9kZXMgaW4gdGhlIFhNTAotICAgIGlucHV0IGludG8gYW5vdGhlciB0cmVlIG9mIG5vZGVzLjwvcD4KLSAgICA8ZGw+Ci0gICAgICA8ZHQ+PGI+VmVyc2lvbjogPC9iPjwvZHQ+PGRkPkFscGhhLCAyLjAuMCwgSnVseSAwNSwgMjAwMDwvZGQ+Ci0gICAgICA8ZHQ+PGI+QXV0aG9yOiA8L2I+PC9kdD48ZGQ+PGEgaHJlZj0ibWFpbHRvOnNjb3R0X2JvYWdAbG90dXMuY29tIj5TY290dCBCb2FnPC9hPjwvZGQ+Ci0gICAgPC9kbD4KLSAgPC9ib2R5PjwvaHRtbD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9jbGllbnQvWFNMVFByb2Nlc3NvckFwcGxldC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vY2xpZW50L1hTTFRQcm9jZXNzb3JBcHBsZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjRkMmZkYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9jbGllbnQvWFNMVFByb2Nlc3NvckFwcGxldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzk4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uY2xpZW50OwotCi1pbXBvcnQgamF2YS5hcHBsZXQuQXBwbGV0OwotCi1pbXBvcnQgamF2YS5hd3QuR3JhcGhpY3M7Ci0KLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci0KLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLQotLy8gTmVlZGVkIFhhbGFuIGNsYXNzZXMKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci0KLS8vIE5lZWRlZCBUUmFYIGNsYXNzZXMKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogUHJvdmlkZXMgYXBwbGV0IGhvc3QgZm9yIHRoZSBYU0xUIHByb2Nlc3Nvci4gVG8gcGVyZm9ybSB0cmFuc2Zvcm1hdGlvbnMgb24gYW4gSFRNTCBjbGllbnQ6Ci0gKiA8b2w+Ci0gKiA8bGk+VXNlIGFuICZsdDthcHBsZXQmZ3Q7IHRhZyB0byBlbWJlZCB0aGlzIGFwcGxldCBpbiB0aGUgSFRNTCBjbGllbnQuPC9saT4KLSAqIDxsaT5Vc2UgdGhlIERvY3VtZW50VVJMIGFuZCBTdHlsZVVSTCBQQVJBTSB0YWdzIG9yIHRoZSB7QGxpbmsgI3NldERvY3VtZW50VVJMfSBhbmQKLSAqIHtAbGluayAjc2V0U3R5bGVVUkx9IG1ldGhvZHMgdG8gc3BlY2lmeSB0aGUgWE1MIHNvdXJjZSBkb2N1bWVudCBhbmQgWFNMIHN0eWxlc2hlZXQuPC9saT4KLSAqIDxsaT5DYWxsIHRoZSB7QGxpbmsgI2dldEh0bWxUZXh0fSBtZXRob2QgKG9yIG9uZSBvZiB0aGUgdHJhbnNmb3JtVG9IdG1sKCkgbWV0aG9kcykKLSAqIHRvIHBlcmZvcm0gdGhlIHRyYW5zZm9ybWF0aW9uIGFuZCByZXR1cm4gdGhlIHJlc3VsdCBhcyBhIFN0cmluZy48L2xpPgotICogPC9vbD4KLSAqLwotcHVibGljIGNsYXNzIFhTTFRQcm9jZXNzb3JBcHBsZXQgZXh0ZW5kcyBBcHBsZXQKLXsKLQotICAvKioKLSAgICogVGhlIHN0eWxlc2hlZXQgcHJvY2Vzc29yLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBUcmFuc2Zvcm1lckZhY3RvcnkgbV90ZmFjdG9yeSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc3R5bGVVUkw7Ci0KLSAgLyoqCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fZG9jdW1lbnRVUkw7Ci0KLSAgLy8gUGFyYW1ldGVyIG5hbWVzLiAgVG8gY2hhbmdlIGEgbmFtZSBvZiBhIHBhcmFtZXRlciwgeW91IG5lZWQgb25seSBtYWtlCi0gIC8vIGEgc2luZ2xlIGNoYW5nZS4gIFNpbXBseSBtb2RpZnkgdGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgc3RyaW5nIGJlbG93LgotICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgLyoqCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgZmluYWwgU3RyaW5nIFBBUkFNX3N0eWxlVVJMID0gInN0eWxlVVJMIjsKLQotICAvKioKLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgUEFSQU1fZG9jdW1lbnRVUkwgPSAiZG9jdW1lbnRVUkwiOwotCi0KLSAgLy8gV2UnbGwga2VlcCB0aGUgRE9NIHRyZWVzIGFyb3VuZCwgc28gdGVsbCB3aGljaCB0cmVlcwotICAvLyBhcmUgY2FjaGVkLgotCi0gIC8qKgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX3N0eWxlVVJMT2ZDYWNoZWQgPSBudWxsOwotCi0gIC8qKgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX2RvY3VtZW50VVJMT2ZDYWNoZWQgPSBudWxsOwotCi0gIC8qKgotICAgKiBTYXZlIHRoaXMgZm9yIHVzZSBvbiB0aGUgd29ya2VyIHRocmVhZDsgbWF5IG5vdCBiZSBuZWNlc3NhcnkuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVVJMIG1fY29kZUJhc2UgPSBudWxsOwotICAKLSAgLyoqCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fdHJlZVVSTCA9IG51bGw7Ci0KLSAgLyoqIAotICAgKiBEb2N1bWVudEJhc2UgVVJMCi0gICAqIEBzZXJpYWwgICAgICAgCi0gICAqLwotICBwcml2YXRlIFVSTCBtX2RvY3VtZW50QmFzZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRocmVhZCBzdHVmZiBmb3IgdGhlIHRydXN0ZWQgd29ya2VyIHRocmVhZC4KLSAgICovCi0gIHRyYW5zaWVudCBwcml2YXRlIFRocmVhZCBtX2NhbGxUaHJlYWQgPSBudWxsOwotCi0gIC8qKgotICAgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgVHJ1c3RlZEFnZW50IG1fdHJ1c3RlZEFnZW50ID0gbnVsbDsKLQotICAvKioKLSAgICogVGhyZWFkIGZvciBydW5uaW5nIFRydXN0ZWRBZ2VudC4KLSAgICovCi0gIHRyYW5zaWVudCBwcml2YXRlIFRocmVhZCBtX3RydXN0ZWRXb3JrZXIgPSBudWxsOwotCi0gIC8qKgotICAgKiBXaGVyZSB0aGUgd29ya2VyIHRocmVhZCBwdXRzIHRoZSBIVE1MIHRleHQuCi0gICAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBTdHJpbmcgbV9odG1sVGV4dCA9IG51bGw7Ci0gIAotICAvKioKLSAgICogV2hlcmUgdGhlIHdvcmtlciB0aHJlYWQgcHV0cyB0aGUgZG9jdW1lbnQvc3R5bGVzaGVldCB0ZXh0LgotICAgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgU3RyaW5nIG1fc291cmNlVGV4dCA9IG51bGw7Ci0gIAotICAvKioKLSAgICogU3R5bGVzaGVldCBhdHRyaWJ1dGUgbmFtZSBhbmQgdmFsdWUgdGhhdCB0aGUgY2FsbGVyIGNhbiBzZXQuCi0gICAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBTdHJpbmcgbV9uYW1lT2ZJREF0dHJPZkVsZW1Ub01vZGlmeSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBTdHJpbmcgbV9lbGVtSWRUb01vZGlmeSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBTdHJpbmcgbV9hdHRyTmFtZVRvU2V0ID0gbnVsbDsKLQotICAvKioKLSAgICovCi0gIHRyYW5zaWVudCBwcml2YXRlIFN0cmluZyBtX2F0dHJWYWx1ZVRvU2V0ID0gbnVsbDsKLQotICAvKioKLSAgICogVGhlIFhTTFRQcm9jZXNzb3JBcHBsZXQgY29uc3RydWN0b3IgdGFrZXMgbm8gYXJndW1lbnRzLgotICAgKi8KLSAgcHVibGljIFhTTFRQcm9jZXNzb3JBcHBsZXQoKXt9Ci0KLSAgLyoqCi0gICAqIEdldCBiYXNpYyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYXBwbGV0Ci0gICAqIEByZXR1cm4gQSBTdHJpbmcgd2l0aCB0aGUgYXBwbGV0IG5hbWUgYW5kIGF1dGhvci4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXBwbGV0SW5mbygpCi0gIHsKLSAgICByZXR1cm4gIk5hbWU6IFhTTFRQcm9jZXNzb3JBcHBsZXRcclxuIiArICJBdXRob3I6IFNjb3R0IEJvYWciOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBkZXNjcmlwdGlvbnMgb2YgdGhlIGFwcGxldCBwYXJhbWV0ZXJzLgotICAgKiBAcmV0dXJuIEEgdHdvLWRpbWVuc2lvbmFsIGFycmF5IG9mIFN0cmluZ3Mgd2l0aCBOYW1lLCBUeXBlLCBhbmQgRGVzY3JpcHRpb24KLSAgICogZm9yIGVhY2ggcGFyYW1ldGVyLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1tdW10gZ2V0UGFyYW1ldGVySW5mbygpCi0gIHsKLQotICAgIFN0cmluZ1tdW10gaW5mbyA9Ci0gICAgewotICAgICAgeyBQQVJBTV9zdHlsZVVSTCwgIlN0cmluZyIsICJVUkwgdG8gYW4gWFNMIHN0eWxlc2hlZXQiIH0sCi0gICAgICB7IFBBUkFNX2RvY3VtZW50VVJMLCAiU3RyaW5nIiwgIlVSTCB0byBhbiBYTUwgZG9jdW1lbnQiIH0sCi0gICAgfTsKLQotICAgIHJldHVybiBpbmZvOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YW5kYXJkIGFwcGxldCBpbml0aWFsaXphdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXQoKQotICB7Ci0KLSAgICAvLyBQQVJBTUVURVIgU1VQUE9SVAotICAgIC8vICAgICAgICAgIFRoZSBmb2xsb3dpbmcgY29kZSByZXRyaWV2ZXMgdGhlIHZhbHVlIG9mIGVhY2ggcGFyYW1ldGVyCi0gICAgLy8gc3BlY2lmaWVkIHdpdGggdGhlIDxQQVJBTT4gdGFnIGFuZCBzdG9yZXMgaXQgaW4gYSBtZW1iZXIKLSAgICAvLyB2YXJpYWJsZS4KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBTdHJpbmcgcGFyYW07Ci0KLSAgICAvLyBzdHlsZVVSTDogUGFyYW1ldGVyIGRlc2NyaXB0aW9uCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcGFyYW0gPSBnZXRQYXJhbWV0ZXIoUEFSQU1fc3R5bGVVUkwpOwotCi0gICAgaWYgKHBhcmFtICE9IG51bGwpCi0gICAgICBzZXRTdHlsZVVSTChwYXJhbSk7Ci0KLSAgICAvLyBkb2N1bWVudFVSTDogUGFyYW1ldGVyIGRlc2NyaXB0aW9uCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgcGFyYW0gPSBnZXRQYXJhbWV0ZXIoUEFSQU1fZG9jdW1lbnRVUkwpOwotCi0gICAgaWYgKHBhcmFtICE9IG51bGwpCi0gICAgICBzZXREb2N1bWVudFVSTChwYXJhbSk7Ci0KLSAgICBtX2NvZGVCYXNlID0gdGhpcy5nZXRDb2RlQmFzZSgpOwotICAgIG1fZG9jdW1lbnRCYXNlID0gdGhpcy5nZXREb2N1bWVudEJhc2UoKTsKLQotICAgIC8vIElmIHlvdSB1c2UgYSBSZXNvdXJjZVdpemFyZC1nZW5lcmF0ZWQgImNvbnRyb2wgY3JlYXRvciIgY2xhc3MgdG8KLSAgICAvLyBhcnJhbmdlIGNvbnRyb2xzIGluIHlvdXIgYXBwbGV0LCB5b3UgbWF5IHdhbnQgdG8gY2FsbCBpdHMKLSAgICAvLyBDcmVhdGVDb250cm9scygpIG1ldGhvZCBmcm9tIHdpdGhpbiB0aGlzIG1ldGhvZC4gUmVtb3ZlIHRoZSBmb2xsb3dpbmcKLSAgICAvLyBjYWxsIHRvIHJlc2l6ZSgpIGJlZm9yZSBhZGRpbmcgdGhlIGNhbGwgdG8gQ3JlYXRlQ29udHJvbHMoKTsKLSAgICAvLyBDcmVhdGVDb250cm9scygpIGRvZXMgaXRzIG93biByZXNpemluZy4KLSAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICByZXNpemUoMzIwLCAyNDApOwotICB9Ci0gIAotICAgIC8qKgotICAgKiAgQXV0b21hdGljYWxseSBjYWxsZWQgd2hlbiB0aGUgSFRNTCBjbGllbnQgY29udGFpbmluZyB0aGUgYXBwbGV0IGxvYWRzLgotICAgKiAgVGhpcyBtZXRob2Qgc3RhcnRzIGV4ZWN1dGlvbiBvZiB0aGUgYXBwbGV0IHRocmVhZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0KCkKLSAgewotCi0gICAgbV90cnVzdGVkQWdlbnQgPSBuZXcgVHJ1c3RlZEFnZW50KCk7Ci0gICAgVGhyZWFkIGN1cnJlbnRUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOwotICAgIG1fdHJ1c3RlZFdvcmtlciA9IG5ldyBUaHJlYWQoY3VycmVudFRocmVhZC5nZXRUaHJlYWRHcm91cCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV90cnVzdGVkQWdlbnQpOwotICAgIG1fdHJ1c3RlZFdvcmtlci5zdGFydCgpOwotICAgIHRyeQotICAgIHsKLSAgICAgIG1fdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgIHRoaXMuc2hvd1N0YXR1cygiQ2F1c2luZyBUcmFuc2Zvcm1lciBhbmQgUGFyc2VyIHRvIExvYWQgYW5kIEpJVC4uLiIpOwotCi0gICAgICAvLyBQcmltZSB0aGUgcHVtcCBzbyB0aGF0IHN1YnNlcXVlbnQgdHJhbnNmb3JtcyBhcmUgZmFzdGVyLgotICAgICAgU3RyaW5nUmVhZGVyIHhtbGJ1ZiA9IG5ldyBTdHJpbmdSZWFkZXIoIjw/eG1sIHZlcnNpb249JzEuMCc/Pjxmb28vPiIpOwotICAgICAgU3RyaW5nUmVhZGVyIHhzbGJ1ZiA9IG5ldyBTdHJpbmdSZWFkZXIoCi0gICAgICAgICI8P3htbCB2ZXJzaW9uPScxLjAnPz48eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0nIHZlcnNpb249JzEuMCc+PHhzbDp0ZW1wbGF0ZSBtYXRjaD0nZm9vJz48b3V0Lz48L3hzbDp0ZW1wbGF0ZT48L3hzbDpzdHlsZXNoZWV0PiIpOwotICAgICAgUHJpbnRXcml0ZXIgcHcgPSBuZXcgUHJpbnRXcml0ZXIobmV3IFN0cmluZ1dyaXRlcigpKTsKLQotICAgICAgc3luY2hyb25pemVkIChtX3RmYWN0b3J5KQotICAgICAgewotICAgICAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzID0gbV90ZmFjdG9yeS5uZXdUZW1wbGF0ZXMobmV3IFN0cmVhbVNvdXJjZSh4c2xidWYpKTsKLSAgICAgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoeG1sYnVmKSwgbmV3IFN0cmVhbVJlc3VsdChwdykpOwotICAgICAgfQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQcmltZWQgdGhlIHB1bXAhIik7Ci0gICAgICB0aGlzLnNob3dTdGF0dXMoIlJlYWR5IHRvIGdvISIpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhpcy5zaG93U3RhdHVzKCJDb3VsZCBub3QgcHJpbWUgdGhlIHB1bXAhIik7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNvdWxkIG5vdCBwcmltZSB0aGUgcHVtcCEiKTsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIERvIG5vdCBjYWxsOyB0aGlzIGFwcGxldCBjb250YWlucyBubyBVSSBvciB2aXN1YWwgY29tcG9uZW50cy4KLSAgICoKLSAgICovCi0gIHB1YmxpYyB2b2lkIHBhaW50KEdyYXBoaWNzIGcpe30gIAotICAKLSAgLyoqCi0gICAqIEF1dG9tYXRpY2FsbHkgY2FsbGVkIHdoZW4gdGhlIEhUTUwgcGFnZSBjb250YWluaW5nIHRoZSBhcHBsZXQgaXMgbm8gbG9uZ2VyCi0gICAqIG9uIHRoZSBzY3JlZW4uIFN0b3BzIGV4ZWN1dGlvbiBvZiB0aGUgYXBwbGV0IHRocmVhZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0b3AoKQotICB7Ci0gICAgaWYgKG51bGwgIT0gbV90cnVzdGVkV29ya2VyKQotICAgIHsKLSAgICAgIG1fdHJ1c3RlZFdvcmtlci5zdG9wKCk7Ci0KLSAgICAgIC8vIG1fdHJ1c3RlZFdvcmtlci5kZXN0cm95KCk7Ci0gICAgICBtX3RydXN0ZWRXb3JrZXIgPSBudWxsOwotICAgIH0KLQotICAgIG1fc3R5bGVVUkxPZkNhY2hlZCA9IG51bGw7Ci0gICAgbV9kb2N1bWVudFVSTE9mQ2FjaGVkID0gbnVsbDsKLSAgfSAgIAotICAKLSAgLyoqCi0gICAqIENsZWFudXA7IGNhbGxlZCB3aGVuIGFwcGxldCBpcyB0ZXJtaW5hdGVkIGFuZCB1bmxvYWRlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRlc3Ryb3koKQotICB7Ci0gICAgaWYgKG51bGwgIT0gbV90cnVzdGVkV29ya2VyKQotICAgIHsKLSAgICAgIG1fdHJ1c3RlZFdvcmtlci5zdG9wKCk7Ci0KLSAgICAgIC8vIG1fdHJ1c3RlZFdvcmtlci5kZXN0cm95KCk7Ci0gICAgICBtX3RydXN0ZWRXb3JrZXIgPSBudWxsOwotICAgIH0KLSAgICBtX3N0eWxlVVJMT2ZDYWNoZWQgPSBudWxsOwotICAgIG1fZG9jdW1lbnRVUkxPZkNhY2hlZCA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBVUkwgdG8gdGhlIFhTTCBzdHlsZXNoZWV0IHRoYXQgd2lsbCBiZSB1c2VkCi0gICAqIHRvIHRyYW5zZm9ybSB0aGUgaW5wdXQgWE1MLiAgTm8gcHJvY2Vzc2luZyBpcyBkb25lIHlldC4KLSAgICogQHBhcmFtIHVybFN0cmluZyB2YWxpZCBVUkwgc3RyaW5nIGZvciBYU0wgc3R5bGVzaGVldC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0eWxlVVJMKFN0cmluZyB1cmxTdHJpbmcpCi0gIHsKLSAgICBtX3N0eWxlVVJMID0gdXJsU3RyaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgVVJMIHRvIHRoZSBYTUwgZG9jdW1lbnQgdGhhdCB3aWxsIGJlIHRyYW5zZm9ybWVkCi0gICAqIHdpdGggdGhlIFhTTCBzdHlsZXNoZWV0LiAgTm8gcHJvY2Vzc2luZyBpcyBkb25lIHlldC4KLSAgICogQHBhcmFtIHVybFN0cmluZyB2YWxpZCBVUkwgc3RyaW5nIGZvciBYTUwgZG9jdW1lbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSTChTdHJpbmcgdXJsU3RyaW5nKQotICB7Ci0gICAgbV9kb2N1bWVudFVSTCA9IHVybFN0cmluZzsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgcHJvY2Vzc29yIGtlZXBzIGEgY2FjaGUgb2YgdGhlIHNvdXJjZSBhbmQKLSAgICogc3R5bGUgdHJlZXMsIHNvIGNhbGwgdGhpcyBtZXRob2QgaWYgdGhleSBoYXZlIGNoYW5nZWQKLSAgICogb3IgeW91IHdhbnQgdG8gZG8gZ2FyYmFnZSBjb2xsZWN0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZnJlZUNhY2hlKCkKLSAgewotICAgIG1fc3R5bGVVUkxPZkNhY2hlZCA9IG51bGw7Ci0gICAgbV9kb2N1bWVudFVSTE9mQ2FjaGVkID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gYXR0cmlidXRlIGluIHRoZSBzdHlsZXNoZWV0LCB3aGljaCBnaXZlcyB0aGUgYWJpbGl0eQotICAgKiB0byBoYXZlIHNvbWUgZHluYW1pYyBzZWxlY3Rpb24gY29udHJvbC4KLSAgICogQHBhcmFtIG5hbWVPZklEQXR0ck9mRWxlbVRvTW9kaWZ5IFRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZSB0byBzZWFyY2ggZm9yIGEgdW5pcXVlIGlkLgotICAgKiBAcGFyYW0gZWxlbUlkIFRoZSB1bmlxdWUgSUQgdG8gbG9vayBmb3IuCi0gICAqIEBwYXJhbSBhdHRyTmFtZSBPbmNlIHRoZSBlbGVtZW50IGlzIGZvdW5kLCB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIHNldC4KLSAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQgdGhlIGF0dHJpYnV0ZSB0by4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0eWxlU2hlZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWVPZklEQXR0ck9mRWxlbVRvTW9kaWZ5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbGVtSWQsIFN0cmluZyBhdHRyTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUpCi0gIHsKLSAgICBtX25hbWVPZklEQXR0ck9mRWxlbVRvTW9kaWZ5ID0gbmFtZU9mSURBdHRyT2ZFbGVtVG9Nb2RpZnk7Ci0gICAgbV9lbGVtSWRUb01vZGlmeSA9IGVsZW1JZDsKLSAgICBtX2F0dHJOYW1lVG9TZXQgPSBhdHRyTmFtZTsKLSAgICBtX2F0dHJWYWx1ZVRvU2V0ID0gdmFsdWU7Ci0gIH0KLQotICAvKiogCi0gICAqIFN0eWxlc2hlZXQgcGFyYW1ldGVyIGtleQotICAgKi8KLSAgdHJhbnNpZW50IFN0cmluZyBtX2tleTsKLQotICAvKiogCi0gICAqIFN0eWxlc2hlZXQgcGFyYW1ldGVyIHZhbHVlCi0gICAqLwotICB0cmFuc2llbnQgU3RyaW5nIG1fZXhwcmVzc2lvbjsKLQotICAvKioKLSAgICogU3VibWl0IGEgc3R5bGVzaGVldCBwYXJhbWV0ZXIuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgc3R5bGVzaGVldCBwYXJhbWV0ZXIga2V5Ci0gICAqIEBwYXJhbSBleHByIHRoZSBwYXJhbWV0ZXIgZXhwcmVzc2lvbiB0byBiZSBzdWJtaXR0ZWQuCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciNzZXRQYXJhbWV0ZXIoU3RyaW5nLE9iamVjdCkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0eWxlc2hlZXRQYXJhbShTdHJpbmcga2V5LCBTdHJpbmcgZXhwcikKLSAgewotICAgIG1fa2V5ID0ga2V5OwotICAgIG1fZXhwcmVzc2lvbiA9IGV4cHI7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBTdHJpbmcgY29udGFpbmluZyBtYXJrdXAsIGVzY2FwZSB0aGUgbWFya3VwIHNvIGl0Ci0gICAqIGNhbiBiZSBkaXNwbGF5ZWQgaW4gdGhlIGJyb3dzZXIuCi0gICAqCi0gICAqIEBwYXJhbSBzIFN0cmluZyB0byBlc2NhcGUKLSAgICoKLSAgICogVGhlIGVzY2FwZWQgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBlc2NhcGVTdHJpbmcoU3RyaW5nIHMpCi0gIHsKLSAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgaW50IGxlbmd0aCA9IHMubGVuZ3RoKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKQotICAgIHsKLSAgICAgIGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKLQotICAgICAgaWYgKCc8JyA9PSBjaCkKLSAgICAgIHsKLSAgICAgICAgc2IuYXBwZW5kKCImbHQ7Iik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICgnPicgPT0gY2gpCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZCgiJmd0OyIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoJyYnID09IGNoKQotICAgICAgewotICAgICAgICBzYi5hcHBlbmQoIiZhbXA7Iik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICgweGQ4MDAgPD0gY2ggJiYgY2ggPCAweGRjMDApCi0gICAgICB7Ci0gICAgICAgIC8vIFVURi0xNiBzdXJyb2dhdGUKLSAgICAgICAgaW50IG5leHQ7Ci0KLSAgICAgICAgaWYgKGkgKyAxID49IGxlbmd0aCkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IEludGVnZXIudG9IZXhTdHJpbmcoY2gpIH0pKTsgIC8vIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogIgotCi0gICAgICAgICAgLy8rSW50ZWdlci50b0hleFN0cmluZyhjaCkrICIgPyIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG5leHQgPSBzLmNoYXJBdCgrK2kpOwotCi0gICAgICAgICAgaWYgKCEoMHhkYzAwIDw9IG5leHQgJiYgbmV4dCA8IDB4ZTAwMCkpCi0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdewotICAgICAgICAgICAgICAgICAgSW50ZWdlci50b0hleFN0cmluZyhjaCkgKyAiICIKLSAgICAgICAgICAgICAgICAgICsgSW50ZWdlci50b0hleFN0cmluZyhuZXh0KSB9KSk7ICAvLyJJbnZhbGlkIFVURi0xNiBzdXJyb2dhdGUgZGV0ZWN0ZWQ6ICIKLQotICAgICAgICAgIC8vK0ludGVnZXIudG9IZXhTdHJpbmcoY2gpKyIgIitJbnRlZ2VyLnRvSGV4U3RyaW5nKG5leHQpKTsKLSAgICAgICAgICBuZXh0ID0gKChjaCAtIDB4ZDgwMCkgPDwgMTApICsgbmV4dCAtIDB4ZGMwMCArIDB4MDAwMTAwMDA7Ci0gICAgICAgIH0KLSAgICAgICAgc2IuYXBwZW5kKCImI3giKTsKLSAgICAgICAgc2IuYXBwZW5kKEludGVnZXIudG9IZXhTdHJpbmcobmV4dCkpOwotICAgICAgICBzYi5hcHBlbmQoIjsiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgc2IuYXBwZW5kKGNoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogQXNzdW1pbmcgdGhlIHN0eWxlc2hlZXQgVVJMIGFuZCB0aGUgaW5wdXQgWE1MIFVSTCBoYXZlIGJlZW4gc2V0LAotICAgKiBwZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbiBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgYSBTdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgdGhhdCBjb250YWlucyB0aGUgY29udGVudHMgcG9pbnRlZCB0byBieSB0aGUgVVJMLgotICAgKgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRIdG1sVGV4dCgpCi0gIHsKLSAgICBtX3RydXN0ZWRBZ2VudC5tX2dldERhdGEgPSB0cnVlOwotICAgIG1fY2FsbFRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgc3luY2hyb25pemVkIChtX2NhbGxUaHJlYWQpCi0gICAgICB7Ci0gICAgICAgIG1fY2FsbFRocmVhZC53YWl0KCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oaWUuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gICAgcmV0dXJuIG1faHRtbFRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIFhNTCBkb2N1bWVudCAob3Igc3R5bGVzaGVldCkKLSAgICoKLSAgICogQHBhcmFtIHRyZWVVUkwgdmFsaWQgVVJMIHN0cmluZyBmb3IgdGhlIGRvY3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIGRvY3VtZW50Ci0gICAqCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHJlZUFzVGV4dChTdHJpbmcgdHJlZVVSTCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBtX3RyZWVVUkwgPSB0cmVlVVJMOwotICAgIG1fdHJ1c3RlZEFnZW50Lm1fZ2V0RGF0YSA9IHRydWU7Ci0gICAgbV90cnVzdGVkQWdlbnQubV9nZXRTb3VyY2UgPSB0cnVlOwotICAgIG1fY2FsbFRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgc3luY2hyb25pemVkIChtX2NhbGxUaHJlYWQpCi0gICAgICB7Ci0gICAgICAgIG1fY2FsbFRocmVhZC53YWl0KCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oaWUuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gICAgcmV0dXJuIG1fc291cmNlVGV4dDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFVzZSBhIFRyYW5zZm9ybWVyIHRvIGNvcHkgdGhlIHNvdXJjZSBkb2N1bWVudAotICAgKiB0byBhIFN0cmVhbVJlc3VsdC4KLSAgICogCi0gICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IGFzIGEgc3RyaW5nCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBnZXRTb3VyY2UoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIFN0cmluZ1dyaXRlciBvc3cgPSBuZXcgU3RyaW5nV3JpdGVyKCk7Ci0gICAgUHJpbnRXcml0ZXIgcHcgPSBuZXcgUHJpbnRXcml0ZXIob3N3LCBmYWxzZSk7Ci0gICAgU3RyaW5nIHRleHQgPSAiIjsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBVUkwgZG9jVVJMID0gbmV3IFVSTChtX2RvY3VtZW50QmFzZSwgbV90cmVlVVJMKTsKLSAgICAgIHN5bmNocm9uaXplZCAobV90ZmFjdG9yeSkKLSAgICAgIHsKLSAgICAgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSBtX3RmYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKCk7Ci0gICAgICAgIFN0cmVhbVNvdXJjZSBzb3VyY2UgPSBuZXcgU3RyZWFtU291cmNlKGRvY1VSTC50b1N0cmluZygpKTsgICAgCi0gICAgICAgIFN0cmVhbVJlc3VsdCByZXN1bHQgPSBuZXcgU3RyZWFtUmVzdWx0KHB3KTsKLSAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHNvdXJjZSwgcmVzdWx0KTsKLSAgICAgICAgdGV4dCA9IG9zdy50b1N0cmluZygpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIFN5c3RlbS5leGl0KC0xKTsKLSAgICB9ICAgICAgCi0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBhbnlfZXJyb3IpCi0gICAgewotICAgICAgYW55X2Vycm9yLnByaW50U3RhY2tUcmFjZSgpOwotICAgIH0KLSAgICByZXR1cm4gdGV4dDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhNTCBzb3VyY2UgVHJlZSBhcyBhIHRleHQgc3RyaW5nIHN1aXRhYmxlCi0gICAqIGZvciBkaXNwbGF5IGluIGEgYnJvd3Nlci4gIE5vdGUgdGhhdCB0aGlzIGlzIGZvciBkaXNwbGF5IG9mIHRoZQotICAgKiBYTUwgaXRzZWxmLCBub3QgZm9yIHJlbmRlcmluZyBvZiBIVE1MIGJ5IHRoZSBicm93c2VyLgotICAgKgotICAgKiBAcmV0dXJuIFhNTCBzb3VyY2UgZG9jdW1lbnQgYXMgYSBzdHJpbmcuCi0gICAqIEB0aHJvd3MgRXhjZXB0aW9uIHRocm93biBpZiB0cmVlIGNhbiBub3QgYmUgY29udmVydGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTb3VyY2VUcmVlQXNUZXh0KCkgdGhyb3dzIEV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGdldFRyZWVBc1RleHQobV9kb2N1bWVudFVSTCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBYU0wgc3R5bGUgVHJlZSBhcyBhIHRleHQgc3RyaW5nIHN1aXRhYmxlCi0gICAqIGZvciBkaXNwbGF5IGluIGEgYnJvd3Nlci4gIE5vdGUgdGhhdCB0aGlzIGlzIGZvciBkaXNwbGF5IG9mIHRoZQotICAgKiBYTUwgaXRzZWxmLCBub3QgZm9yIHJlbmRlcmluZyBvZiBIVE1MIGJ5IHRoZSBicm93c2VyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBYU0wgc3R5bGVzaGVldCBhcyBhIHN0cmluZy4KLSAgICogQHRocm93cyBFeGNlcHRpb24gdGhyb3duIGlmIHRyZWUgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN0eWxlVHJlZUFzVGV4dCgpIHRocm93cyBFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBnZXRUcmVlQXNUZXh0KG1fc3R5bGVVUkwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgSFRNTCByZXN1bHQgVHJlZSBhcyBhIHRleHQgc3RyaW5nIHN1aXRhYmxlCi0gICAqIGZvciBkaXNwbGF5IGluIGEgYnJvd3Nlci4gIE5vdGUgdGhhdCB0aGlzIGlzIGZvciBkaXNwbGF5IG9mIHRoZQotICAgKiBYTUwgaXRzZWxmLCBub3QgZm9yIHJlbmRlcmluZyBvZiBIVE1MIGJ5IHRoZSBicm93c2VyLgotICAgKgotICAgKiBAcmV0dXJuIFRyYW5zZm9ybWF0aW9uIHJlc3VsdCBhcyB1bm1hcmtlZCB0ZXh0LgotICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiB0aHJvd24gaWYgdHJlZSBjYW4gbm90IGJlIGNvbnZlcnRlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UmVzdWx0VHJlZUFzVGV4dCgpIHRocm93cyBFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBlc2NhcGVTdHJpbmcoZ2V0SHRtbFRleHQoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyBhIGRvY3VtZW50IGFuZCBhIHN0eWxlc2hlZXQgYW5kIHJldHVybgotICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0LiAgSWYgb25lIG9mIHRoZXNlIGlzIG51bGwsIHRoZQotICAgKiBleGlzdGluZyB2YWx1ZSAob2YgYSBwcmV2aW91cyB0cmFuc2Zvcm1hdGlvbikgaXMgbm90IGFmZmVjdGVkLgotICAgKgotICAgKiBAcGFyYW0gZG9jIFVSTCBzdHJpbmcgdG8gWE1MIGRvY3VtZW50Ci0gICAqIEBwYXJhbSBzdHlsZSBVUkwgc3RyaW5nIHRvIFhTTCBzdHlsZXNoZWV0Ci0gICAqCi0gICAqIEByZXR1cm4gSFRNTCB0cmFuc2Zvcm1hdGlvbiByZXN1bHQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdHJhbnNmb3JtVG9IdG1sKFN0cmluZyBkb2MsIFN0cmluZyBzdHlsZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gZG9jKQotICAgIHsKLSAgICAgIG1fZG9jdW1lbnRVUkwgPSBkb2M7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gc3R5bGUpCi0gICAgewotICAgICAgbV9zdHlsZVVSTCA9IHN0eWxlOwotICAgIH0KLQotICAgIHJldHVybiBnZXRIdG1sVGV4dCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYSBkb2N1bWVudCBhbmQgYSBzdHlsZXNoZWV0IGFuZCByZXR1cm4KLSAgICogdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdC4gVXNlIHRoZSB4c2w6c3R5bGVzaGVldCBQSSB0byBmaW5kIHRoZQotICAgKiBkb2N1bWVudCwgaWYgb25lIGV4aXN0cy4KLSAgICoKLSAgICogQHBhcmFtIGRvYyAgVVJMIHN0cmluZyB0byBYTUwgZG9jdW1lbnQgY29udGFpbmluZyBhbiB4c2w6c3R5bGVzaGVldCBQSS4KLSAgICoKLSAgICogQHJldHVybiBIVE1MIHRyYW5zZm9ybWF0aW9uIHJlc3VsdAotICAgKi8KLSAgcHVibGljIFN0cmluZyB0cmFuc2Zvcm1Ub0h0bWwoU3RyaW5nIGRvYykKLSAgewotCi0gICAgaWYgKG51bGwgIT0gZG9jKQotICAgIHsKLSAgICAgIG1fZG9jdW1lbnRVUkwgPSBkb2M7Ci0gICAgfQotCi0gICAgbV9zdHlsZVVSTCA9IG51bGw7Ci0KLSAgICByZXR1cm4gZ2V0SHRtbFRleHQoKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFByb2Nlc3MgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQgYXMgYSBzdHJpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIHByb2Nlc3NUcmFuc2Zvcm1hdGlvbigpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgU3RyaW5nIGh0bWxEYXRhID0gbnVsbDsKLSAgICB0aGlzLnNob3dTdGF0dXMoIldhaXRpbmcgZm9yIFRyYW5zZm9ybWVyIGFuZCBQYXJzZXIgdG8gZmluaXNoIGxvYWRpbmcgYW5kIEpJVGluZy4uLiIpOwotICAgIAotICAgIHN5bmNocm9uaXplZCAobV90ZmFjdG9yeSkKLSAgICB7Ci0gICAgIFVSTCBkb2N1bWVudFVSTCA9IG51bGw7Ci0gICAgICBVUkwgc3R5bGVVUkwgPSBudWxsOwotICAgICAgU3RyaW5nV3JpdGVyIG9zdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKLSAgICAgIFByaW50V3JpdGVyIHB3ID0gbmV3IFByaW50V3JpdGVyKG9zdywgZmFsc2UpOwotICAgICAgU3RyZWFtUmVzdWx0IHJlc3VsdCA9IG5ldyBTdHJlYW1SZXN1bHQocHcpOwotICAgIAotICAgICAgdGhpcy5zaG93U3RhdHVzKCJCZWdpbiBUcmFuc2Zvcm1hdGlvbi4uLiIpOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGRvY3VtZW50VVJMID0gbmV3IFVSTChtX2NvZGVCYXNlLCBtX2RvY3VtZW50VVJMKTsKLSAgICAgICAgU3RyZWFtU291cmNlIHhtbFNvdXJjZSA9IG5ldyBTdHJlYW1Tb3VyY2UoZG9jdW1lbnRVUkwudG9TdHJpbmcoKSk7Ci0KLSAgICAgICAgc3R5bGVVUkwgPSBuZXcgVVJMKG1fY29kZUJhc2UsIG1fc3R5bGVVUkwpOwotICAgICAgICBTdHJlYW1Tb3VyY2UgeHNsU291cmNlID0gbmV3IFN0cmVhbVNvdXJjZShzdHlsZVVSTC50b1N0cmluZygpKTsKLQotICAgICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IG1fdGZhY3RvcnkubmV3VHJhbnNmb3JtZXIoeHNsU291cmNlKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtX2tleSkKLSAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRQYXJhbWV0ZXIobV9rZXksIG1fZXhwcmVzc2lvbik7Ci0gICAgICAKLSAgICAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybSh4bWxTb3VyY2UsIHJlc3VsdCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHRmZSkKLSAgICAgIHsKLSAgICAgICAgdGZlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIFN5c3RlbS5leGl0KC0xKTsKLSAgICAgIH0KLQkgIAotICAgICAgdGhpcy5zaG93U3RhdHVzKCJUcmFuc2Zvcm1hdGlvbiBEb25lISIpOwotICAgICAgaHRtbERhdGEgPSBvc3cudG9TdHJpbmcoKTsKLSAgICB9Ci0gICAgcmV0dXJuIGh0bWxEYXRhOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgY2xhc3MgbWFpbnRhaW5zIGEgd29ya2VyIHRocmVhZCB0aGF0IHRoYXQgaXMKLSAgICogdHJ1c3RlZCBhbmQgY2FuIGRvIHRoaW5ncyBsaWtlIGFjY2VzcyBkYXRhLiAgWW91IG5lZWQKLSAgICogdGhpcyBiZWNhdXNlIHRoZSB0aHJlYWQgdGhhdCBpcyBjYWxsZWQgYnkgdGhlIGJyb3dzZXIKLSAgICogaXMgbm90IHRydXN0ZWQgYW5kIGNhbid0IGFjY2VzcyBkYXRhIGZyb20gdGhlIFVSTHMuCi0gICAqLwotICBjbGFzcyBUcnVzdGVkQWdlbnQgaW1wbGVtZW50cyBSdW5uYWJsZQotICB7Ci0KLSAgICAvKiogCi0gICAgICogU3BlY2lmaWVzIHdoZXRoZXIgdGhlIHdvcmtlciB0aHJlYWQgc2hvdWxkIHBlcmZvcm0gYSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtX2dldERhdGEgPSBmYWxzZTsKLQotICAgIC8qKiAKLSAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgd29ya2VyIHRocmVhZCBzaG91bGQgZ2V0IGFuIFhNTCBkb2N1bWVudCBvciBYU0wgc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtX2dldFNvdXJjZSA9IGZhbHNlOwotCi0gICAgLyoqCi0gICAgICogVGhlIHJlYWwgd29yayBpcyBkb25lIGZyb20gaGVyZS4KLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJ1bigpCi0gICAgewotICAgICAgd2hpbGUgKHRydWUpCi0gICAgICB7Ci0gICAgICAgIG1fdHJ1c3RlZFdvcmtlci55aWVsZCgpOwotCi0gICAgICAgIGlmIChtX2dldERhdGEpICAvLyBQZXJmb3JtIGEgdHJhbnNmb3JtYXRpb24gb3IgZ2V0IGEgZG9jdW1lbnQuCi0gICAgICAgIHsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2dldERhdGEgPSBmYWxzZTsKLSAgICAgICAgICAgIG1faHRtbFRleHQgPSBudWxsOwotICAgICAgICAgICAgbV9zb3VyY2VUZXh0ID0gbnVsbDsKLSAgICAgICAgICAgIGlmIChtX2dldFNvdXJjZSkgIC8vIEdldCBhIGRvY3VtZW50LgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBtX2dldFNvdXJjZSA9IGZhbHNlOwotICAgICAgICAgICAgICBtX3NvdXJjZVRleHQgPSBnZXRTb3VyY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgICAgICAgICAgICAgIC8vIFBlcmZvcm0gYSB0cmFuc2Zvcm1hdGlvbi4KLSAgICAgICAgICAgICAgbV9odG1sVGV4dCA9IHByb2Nlc3NUcmFuc2Zvcm1hdGlvbigpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZmluYWxseQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHN5bmNocm9uaXplZCAobV9jYWxsVGhyZWFkKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBtX2NhbGxUaHJlYWQubm90aWZ5KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG1fdHJ1c3RlZFdvcmtlci5zbGVlcCg1MCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2NsaWVudC9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9jbGllbnQvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZmQ2ZjRlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2NsaWVudC9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw4ICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WGFsYW4gQ2xpZW50IFBhY2thZ2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gYXBwbGV0LjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4cHJlc3Npb25Db250ZXh0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4cHJlc3Npb25Db250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY1MjJmNjcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9FeHByZXNzaW9uQ29udGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGNhbiBzdXBwbHkKLSAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IFhQYXRoIGV4cHJlc3Npb24gY29udGV4dC4KLSAqLwotcHVibGljIGludGVyZmFjZSBFeHByZXNzaW9uQ29udGV4dAotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldENvbnRleHROb2RlKCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICogQHJldHVybiBBbiBpdGVyYXRvciBmb3IgdGhlIGN1cnJlbnQgY29udGV4dCBsaXN0LCBhcwotICAgKiBkZWZpbmVkIGluIFhTTFQuCi0gICAqLwotICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldENvbnRleHROb2RlcygpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgbm9kZSBhcyBhIG51bWJlci4KLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSBudW1iZXIuICBNYXkgYmUgbnVsbC4KLSAgICogQHJldHVybiB2YWx1ZSBvZiBuIGFzIGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGRvdWJsZSB0b051bWJlcihOb2RlIG4pOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgbm9kZSBhcyBhIHN0cmluZy4KLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcuICBNYXkgYmUgbnVsbC4KLSAgICogQHJldHVybiB2YWx1ZSBvZiBuIGFzIGEgc3RyaW5nLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbiBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZyhOb2RlIG4pOwotCi0gIC8qKgotICAgKiBHZXQgYSB2YXJpYWJsZSBiYXNlZCBvbiBpdCdzIHF1YWxpZmllZCBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXZhbHVhdGVkIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotCi0gIHB1YmxpYyBYT2JqZWN0IGdldFZhcmlhYmxlT3JQYXJhbShvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZSBxbmFtZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbkhhbmRsZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZWJiZTczLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci0KLS8vIFRlbXA/PwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgaGFuZGxpbmcgYW4gZXh0ZW5zaW9uIG5hbWVzcGFjZSBmb3IgWFBhdGguCi0gKiBQcm92aWRlcyBmdW5jdGlvbnMgdG8gdGVzdCBhIGZ1bmN0aW9uJ3MgZXhpc3RlbmNlIGFuZCBjYWxsIGEgZnVuY3Rpb24uCi0gKiBBbHNvIHByb3ZpZGVzIGZ1bmN0aW9ucyBmb3IgY2FsbGluZyBhbiBlbGVtZW50IGFuZCB0ZXN0aW5nIGZvcgotICogYW4gZWxlbWVudCdzIGV4aXN0ZW5jZS4KLSAqCi0gKiBAYXV0aG9yIFNhbmppdmEgV2VlcmF3YXJhbmEgKHNhbmppdmFAd2F0c29uLmlibS5jb20pCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFeHRlbnNpb25IYW5kbGVyCi17Ci0KLSAgLyoqIHVyaSBvZiB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIG1fbmFtZXNwYWNlVXJpOyAKLQotICAvKiogc2NyaXB0aW5nIGxhbmd1YWdlIG9mIGltcGxlbWVudGF0aW9uICAgICAgICAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9zY3JpcHRMYW5nOwotCi0gIC8qKiBhIHplcm8gbGVuZ3RoIE9iamVjdCBhcnJheSB1c2VkIGluIGdldENsYXNzRm9yTmFtZSgpICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIE9iamVjdCBOT19PQkpTW10gPSBuZXcgT2JqZWN0WzBdOwotCi0gIC8qKiB0aGUgTWV0aG9kIG9iamVjdCBmb3IgZ2V0Q29udGV4dENsYXNzTG9hZGVyICovCi0gIHByaXZhdGUgc3RhdGljIE1ldGhvZCBnZXRDQ0w7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBnZXRDQ0wgPSBUaHJlYWQuY2xhc3MuZ2V0TWV0aG9kKCJnZXRDb250ZXh0Q2xhc3NMb2FkZXIiLCBuZXcgQ2xhc3NbMF0pOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZ2V0Q0NMID0gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwbGFjZW1lbnQgZm9yIENsYXNzLmZvck5hbWUuICBUaGlzIG1ldGhvZCBsb2FkcyBhIGNsYXNzIHVzaW5nIHRoZSBjb250ZXh0IGNsYXNzIGxvYWRlcgotICAgKiBpZiB3ZSdyZSBydW5uaW5nIHVuZGVyIEphdmEyIG9yIGhpZ2hlci4gIElmIHdlJ3JlIHJ1bm5pbmcgdW5kZXIgSmF2YTEsIHRoaXMKLSAgICogbWV0aG9kIGp1c3QgdXNlcyBDbGFzcy5mb3JOYW1lIHRvIGxvYWQgdGhlIGNsYXNzLgotICAgKiAKLSAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIHRoZSBjbGFzcyB0byBsb2FkCi0gICAqLwotICBwdWJsaWMgc3RhdGljIENsYXNzIGdldENsYXNzRm9yTmFtZShTdHJpbmcgY2xhc3NOYW1lKQotICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgewotICAgIENsYXNzIHJlc3VsdCA9IG51bGw7Ci0gICAgCi0gICAgLy8gSGFjayBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2l0aCBYYWxhbkoxIHN0eWxlc2hlZXRzCi0gICAgaWYoY2xhc3NOYW1lLmVxdWFscygib3JnLmFwYWNoZS54YWxhbi54c2x0LmV4dGVuc2lvbnMuUmVkaXJlY3QiKSkKLSAgICAgIGNsYXNzTmFtZSA9ICJvcmcuYXBhY2hlLnhhbGFuLmxpYi5SZWRpcmVjdCI7Ci0gICAgICAKLSAgICBpZiAoZ2V0Q0NMICE9IG51bGwpCi0gICAgewotICAgICAgdHJ5IHsKLSAgICAgICAgQ2xhc3NMb2FkZXIgY29udGV4dENsYXNzTG9hZGVyID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChDbGFzc0xvYWRlcikgZ2V0Q0NMLmludm9rZShUaHJlYWQuY3VycmVudFRocmVhZCgpLCBOT19PQkpTKTsKLSAgICAgICAgcmVzdWx0ID0gY29udGV4dENsYXNzTG9hZGVyLmxvYWRDbGFzcyhjbGFzc05hbWUpOwotICAgICAgfQotICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkKLSAgICAgIHsKLSAgICAgICAgcmVzdWx0ID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBnZXRDQ0wgPSBudWxsOwotICAgICAgICByZXN1bHQgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgZWxzZQotICAgICAgIHJlc3VsdCA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKLQotICAgIHJldHVybiByZXN1bHQ7Ci0gfQotCi0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBleHRlbnNpb24gbmFtZXNwYWNlIGhhbmRsZXIgZ2l2ZW4gYWxsIHRoZSBpbmZvcm1hdGlvbgotICAgKiBuZWVkZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVcmkgdGhlIGV4dGVuc2lvbiBuYW1lc3BhY2UgVVJJIHRoYXQgSSdtIGltcGxlbWVudGluZwotICAgKiBAcGFyYW0gc2NyaXB0TGFuZyAgIGxhbmd1YWdlIG9mIGNvZGUgaW1wbGVtZW50aW5nIHRoZSBleHRlbnNpb24KLSAgICovCi0gIHByb3RlY3RlZCBFeHRlbnNpb25IYW5kbGVyKFN0cmluZyBuYW1lc3BhY2VVcmksIFN0cmluZyBzY3JpcHRMYW5nKQotICB7Ci0gICAgbV9uYW1lc3BhY2VVcmkgPSBuYW1lc3BhY2VVcmk7Ci0gICAgbV9zY3JpcHRMYW5nID0gc2NyaXB0TGFuZzsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyB3aGV0aGVyIGEgY2VydGFpbiBmdW5jdGlvbiBuYW1lIGlzIGtub3duIHdpdGhpbiB0aGlzIG5hbWVzcGFjZS4KLSAgICogQHBhcmFtIGZ1bmN0aW9uIG5hbWUgb2YgdGhlIGZ1bmN0aW9uIGJlaW5nIHRlc3RlZAotICAgKiBAcmV0dXJuIHRydWUgaWYgaXRzIGtub3duLCBmYWxzZSBpZiBub3QuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc0Z1bmN0aW9uQXZhaWxhYmxlKFN0cmluZyBmdW5jdGlvbik7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIHdoZXRoZXIgYSBjZXJ0YWluIGVsZW1lbnQgbmFtZSBpcyBrbm93biB3aXRoaW4gdGhpcyBuYW1lc3BhY2UuCi0gICAqIEBwYXJhbSBmdW5jdGlvbiBuYW1lIG9mIHRoZSBmdW5jdGlvbiBiZWluZyB0ZXN0ZWQKLSAgICoKLSAgICogQHBhcmFtIGVsZW1lbnQgTmFtZSBvZiBlbGVtZW50IHRvIGNoZWNrCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBpdHMga25vd24sIGZhbHNlIGlmIG5vdC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzRWxlbWVudEF2YWlsYWJsZShTdHJpbmcgZWxlbWVudCk7Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYSBjYWxsIHRvIGEgZnVuY3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSBmdW5jTmFtZSBGdW5jdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gYXJncyAgICAgVGhlIGFyZ3VtZW50cyBvZiB0aGUgZnVuY3Rpb24gY2FsbC4KLSAgICogQHBhcmFtIG1ldGhvZEtleSBBIGtleSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcyBhbmQgbWV0aG9kIGNhbGwuCi0gICAqIEBwYXJhbSBleHByQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCB0aGlzIGV4cHJlc3Npb24gaXMgYmVpbmcgZXhlY3V0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZnVuY3Rpb24gZXZhbHVhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiAgICAgICAgICBpZiBwYXJzaW5nIHRyb3VibGUKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgY2FsbEZ1bmN0aW9uKAotICAgIFN0cmluZyBmdW5jTmFtZSwgVmVjdG9yIGFyZ3MsIE9iamVjdCBtZXRob2RLZXksCi0gICAgICBFeHByZXNzaW9uQ29udGV4dCBleHByQ29udGV4dCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBQcm9jZXNzIGEgY2FsbCB0byB0aGlzIGV4dGVuc2lvbiBuYW1lc3BhY2UgdmlhIGFuIGVsZW1lbnQuIEFzIGEgc2lkZQotICAgKiBlZmZlY3QsIHRoZSByZXN1bHRzIGFyZSBzZW50IHRvIHRoZSBUcmFuc2Zvcm1lckltcGwncyByZXN1bHQgdHJlZS4KLSAgICoKLSAgICogQHBhcmFtIGxvY2FsUGFydCAgICAgIEVsZW1lbnQgbmFtZSdzIGxvY2FsIHBhcnQuCi0gICAqIEBwYXJhbSBlbGVtZW50ICAgICAgICBUaGUgZXh0ZW5zaW9uIGVsZW1lbnQgYmVpbmcgcHJvY2Vzc2VkLgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgICAgICBIYW5kbGUgdG8gVHJhbnNmb3JtZXJJbXBsLgotICAgKiBAcGFyYW0gc3R5bGVzaGVldFRyZWUgVGhlIGNvbXBpbGVkIHN0eWxlc2hlZXQgdHJlZS4KLSAgICogQHBhcmFtIG1vZGUgICAgICAgICAgIFRoZSBjdXJyZW50IG1vZGUuCi0gICAqIEBwYXJhbSBzb3VyY2VUcmVlICAgICBUaGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUgKGJ1dCBkb24ndCBhc3N1bWUKLSAgICogICAgICAgICAgICAgICAgICAgICAgIGl0J3MgYSBEb2N1bWVudCkuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlICAgICBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBtZXRob2RLZXkgICAgICBBIGtleSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcyBhbmQgbWV0aG9kIGNhbGwuCi0gICAqCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiBzb21ldGhpbmcgZ29lcyB3cm9uZwotICAgKiAgICAgICAgICAgIHdoaWxlIHJ1bm5pbmcgdGhlIGV4dGVuc2lvbiBoYW5kbGVyLgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBpZiBsb2FkaW5nIHRyb3VibGUKLSAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gaWYgbG9hZGluZyB0cm91YmxlCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gICAgICAgICAgIGlmIGxvYWRpbmcgdHJvdWJsZQotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uICAgICAgICAgIGlmIHBhcnNpbmcgdHJvdWJsZQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgcHJvY2Vzc0VsZW1lbnQoCi0gICAgU3RyaW5nIGxvY2FsUGFydCwgRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtZW50LCBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsCi0gICAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXRUcmVlLCBPYmplY3QgbWV0aG9kS2V5KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIElPRXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9FeHRlbnNpb25IYW5kbGVyR2VuZXJhbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9FeHRlbnNpb25IYW5kbGVyR2VuZXJhbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NmQwOWU4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlckdlbmVyYWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN5c3RlbUlEUmVzb2x2ZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vLyBUZW1wPz8KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ1ZlY3RvcjsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgaGFuZGxpbmcgYW4gZXh0ZW5zaW9uIG5hbWVzcGFjZSBmb3IgWFBhdGguIFByb3ZpZGVzIGZ1bmN0aW9ucwotICogdG8gdGVzdCBhIGZ1bmN0aW9uJ3MgZXhpc3RlbmNlIGFuZCBjYWxsIGEgZnVuY3Rpb24KLSAqCi0gKiBAYXV0aG9yIFNhbmppdmEgV2VlcmF3YXJhbmEgKHNhbmppdmFAd2F0c29uLmlibS5jb20pCi0gKi8KLXB1YmxpYyBjbGFzcyBFeHRlbnNpb25IYW5kbGVyR2VuZXJhbCBleHRlbmRzIEV4dGVuc2lvbkhhbmRsZXIKLXsKLQotICAvKiogc2NyaXB0IHNvdXJjZSB0byBydW4gKGlmIGFueSkgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX3NjcmlwdFNyYzsgICAKLQotICAvKiogVVJMIG9mIHNvdXJjZSBvZiBzY3JpcHQgKGlmIGFueSkgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX3NjcmlwdFNyY1VSTDsgIAotCi0gIC8qKiBmdW5jdGlvbnMgb2YgbmFtZXNwYWNlICAgICAgICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2Z1bmN0aW9ucyA9IG5ldyBIYXNodGFibGUoKTsgIAotCi0gIC8qKiBlbGVtZW50cyBvZiBuYW1lc3BhY2UgICAgICAgICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2VsZW1lbnRzID0gbmV3IEhhc2h0YWJsZSgpOyAgIAotCi0gIC8vIEJTRiBvYmplY3RzIHVzZWQgdG8gaW52b2tlIEJTRiBieSByZWZsZWN0aW9uLiAgRG8gbm90IGltcG9ydCB0aGUgQlNGIGNsYXNzZXMKLSAgLy8gc2luY2Ugd2UgZG9uJ3Qgd2FudCBhIGNvbXBpbGUgZGVwZW5kZW5jeSBvbiBCU0YuCi0KLSAgLyoqIEluc3RhbmNlIG9mIE1hbmFnZXIgY2xhc3MgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBPYmplY3QgbV9tZ3I7ICAvLyAKLQotICAvKiogQlNGIG1hbmFnZXIgdXNlZCB0byBydW4gc2NyaXB0cyAgICAgICAgICovCi0gIHByaXZhdGUgT2JqZWN0IG1fZW5naW5lOyAgCi0KLSAgLy8gc3RhdGljIGZpZWxkcwotCi0gIC8qKiBCU0ZNYW5hZ2VyIHBhY2thZ2UgbmFtZSAgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlNGX01BTkFHRVIgPSAiY29tLmlibS5ic2YuQlNGTWFuYWdlciI7Ci0KLSAgLyoqIE1hbmFnZXIgY2xhc3MgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3MgbWFuYWdlckNsYXNzOwotCi0gIC8qKiBNYW5hZ2VyIGxvYWQgc2NyaXB0aW5nIGVuZ2luZSAgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBNZXRob2QgbWdyTG9hZFNjcmlwdGluZ0VuZ2luZTsKLQotICAvKiogQlNGRW5naW5lIHBhY2thZ2UgbmFtZSAgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQlNGX0VOR0lORSA9ICJjb20uaWJtLmJzZi5CU0ZFbmdpbmUiOwotCi0gIC8qKiBFbmdpbmUgY2FsbCB0byAiY29tcGlsZSIgc2NyaXB0cyAgICAgICAgICovCi0gIHByaXZhdGUgc3RhdGljIE1ldGhvZCBlbmdpbmVFeGVjOyAgIAotCi0gIC8qKiBFbmdpbmUgY2FsbCB0byBpbnZva2Ugc2NyaXB0cyAgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBNZXRob2QgZW5naW5lQ2FsbDsgICAKLQotICAvKiogTmVnYXRpdmUgb25lIGludGVnZXIgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnRlZ2VyIE5FRzFJTlQgPSBuZXcgSW50ZWdlcigtMSk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAvL21hbmFnZXJDbGFzcyA9IENsYXNzLmZvck5hbWUoQlNGX01BTkFHRVIpOwotICAgICAgICAgICAgICAgICAgICAgICAgbWFuYWdlckNsYXNzID0gRXh0ZW5zaW9uSGFuZGxlci5nZXRDbGFzc0Zvck5hbWUoQlNGX01BTkFHRVIpOwotICAgICAgbWdyTG9hZFNjcmlwdGluZ0VuZ2luZSA9IG1hbmFnZXJDbGFzcy5nZXRNZXRob2QoImxvYWRTY3JpcHRpbmdFbmdpbmUiLAotICAgICAgICAgICAgICBuZXcgQ2xhc3NbXXsgU3RyaW5nLmNsYXNzIH0pOwotCi0gICAgICAvL0NsYXNzIGVuZ2luZUNsYXNzID0gQ2xhc3MuZm9yTmFtZShCU0ZfRU5HSU5FKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGVuZ2luZUNsYXNzID0gRXh0ZW5zaW9uSGFuZGxlci5nZXRDbGFzc0Zvck5hbWUoQlNGX0VOR0lORSk7Ci0KLSAgICAgIGVuZ2luZUV4ZWMgPSBlbmdpbmVDbGFzcy5nZXRNZXRob2QoImV4ZWMiLCBuZXcgQ2xhc3NbXXsgU3RyaW5nLmNsYXNzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLlRZUEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuVFlQRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmNsYXNzIH0pOwotICAgICAgZW5naW5lQ2FsbCA9IGVuZ2luZUNsYXNzLmdldE1ldGhvZCgiY2FsbCIsIG5ldyBDbGFzc1tdeyBPYmplY3QuY2xhc3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZy5jbGFzcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiW0xqYXZhLmxhbmcuT2JqZWN0OyIpIH0pOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgbWFuYWdlckNsYXNzID0gbnVsbDsKLSAgICAgIG1nckxvYWRTY3JpcHRpbmdFbmdpbmUgPSBudWxsOwotICAgICAgZW5naW5lRXhlYyA9IG51bGw7Ci0gICAgICBlbmdpbmVDYWxsID0gbnVsbDsKLQotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IGV4dGVuc2lvbiBuYW1lc3BhY2UgaGFuZGxlciBnaXZlbiBhbGwgdGhlIGluZm9ybWF0aW9uCi0gICAqIG5lZWRlZC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVyaSB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBVUkkgdGhhdCBJJ20gaW1wbGVtZW50aW5nCi0gICAqIEBwYXJhbSBlbGVtTmFtZXMgVmVjdG9yIG9mIGVsZW1lbnQgbmFtZXMKLSAgICogQHBhcmFtIGZ1bmNOYW1lcyAgICBzdHJpbmcgY29udGFpbmluZyBsaXN0IG9mIGZ1bmN0aW9ucyBvZiBleHRlbnNpb24gTlMKLSAgICogQHBhcmFtIGxhbmcgICAgICAgICBsYW5ndWFnZSBvZiBjb2RlIGltcGxlbWVudGluZyB0aGUgZXh0ZW5zaW9uCi0gICAqIEBwYXJhbSBzcmNVUkwgICAgICAgdmFsdWUgb2Ygc3JjIGF0dHJpYnV0ZSAoaWYgYW55KSAtIHRyZWF0ZWQgYXMgYSBVUkwKLSAgICogICAgICAgICAgICAgICAgICAgICBvciBhIGNsYXNzbmFtZSBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIGxhbmcuIElmCi0gICAqICAgICAgICAgICAgICAgICAgICAgc3JjVVJMIGlzIG5vdCBudWxsLCB0aGVuIHNjcmlwdFNyYyBpcyBpZ25vcmVkLgotICAgKiBAcGFyYW0gc2NyaXB0TGFuZyBTY3JpcHRpbmcgbGFuZ3VhZ2Ugb2YgaW1wbGVtZW50YXRpb24KLSAgICogQHBhcmFtIHNjcmlwdFNyY1VSTCBVUkwgb2Ygc291cmNlIHNjcmlwdAotICAgKiBAcGFyYW0gc2NyaXB0U3JjICAgIHRoZSBhY3R1YWwgc2NyaXB0IGNvZGUgKGlmIGFueSkKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEV4dGVuc2lvbkhhbmRsZXJHZW5lcmFsKAotICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVcmksIFN0cmluZ1ZlY3RvciBlbGVtTmFtZXMsIFN0cmluZ1ZlY3RvciBmdW5jTmFtZXMsIFN0cmluZyBzY3JpcHRMYW5nLCBTdHJpbmcgc2NyaXB0U3JjVVJMLCBTdHJpbmcgc2NyaXB0U3JjLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIobmFtZXNwYWNlVXJpLCBzY3JpcHRMYW5nKTsKLQotICAgIGlmIChlbGVtTmFtZXMgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBPYmplY3QganVuayA9IG5ldyBPYmplY3QoKTsKLSAgICAgIGludCBuID0gZWxlbU5hbWVzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyB0b2sgPSBlbGVtTmFtZXMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgIG1fZWxlbWVudHMucHV0KHRvaywganVuayk7ICAvLyBqdXN0IHN0aWNrIGl0IGluIHRoZXJlIGJhc2ljYWxseQotICAgICAgfQotICAgIH0KLQotICAgIGlmIChmdW5jTmFtZXMgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBPYmplY3QganVuayA9IG5ldyBPYmplY3QoKTsKLSAgICAgIGludCBuID0gZnVuY05hbWVzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyB0b2sgPSBmdW5jTmFtZXMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgIG1fZnVuY3Rpb25zLnB1dCh0b2ssIGp1bmspOyAgLy8ganVzdCBzdGljayBpdCBpbiB0aGVyZSBiYXNpY2FsbHkKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX3NjcmlwdFNyY1VSTCA9IHNjcmlwdFNyY1VSTDsKLSAgICBtX3NjcmlwdFNyYyA9IHNjcmlwdFNyYzsKLQotICAgIGlmIChtX3NjcmlwdFNyY1VSTCAhPSBudWxsKQotICAgIHsKLSAgICAgIFVSTCB1cmwgPSBudWxsOwotICAgICAgdHJ5ewotICAgICAgICB1cmwgPSBuZXcgVVJMKG1fc2NyaXB0U3JjVVJMKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVlKQotICAgICAgewotICAgICAgICBpbnQgaW5kZXhPZkNvbG9uID0gbV9zY3JpcHRTcmNVUkwuaW5kZXhPZignOicpOwotICAgICAgICBpbnQgaW5kZXhPZlNsYXNoID0gbV9zY3JpcHRTcmNVUkwuaW5kZXhPZignLycpOwotCi0gICAgICAgIGlmICgoaW5kZXhPZkNvbG9uICE9IC0xKSAmJiAoaW5kZXhPZlNsYXNoICE9IC0xKQotICAgICAgICAgICAgJiYgKGluZGV4T2ZDb2xvbiA8IGluZGV4T2ZTbGFzaCkpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBUaGUgdXJsIGlzIGFic29sdXRlLgotICAgICAgICAgIHVybCA9IG51bGw7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NPVUxEX05PVF9GSU5EX0VYVEVSTl9TQ1JJUFQsIG5ldyBPYmplY3RbXXttX3NjcmlwdFNyY1VSTH0pLCBtdWUpOyAvLyJzcmMgYXR0cmlidXRlIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciAiCi0gICAgICAgICAgLy8rIHNjcmlwdExhbmcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHRyeXsKLSAgICAgICAgICAgIHVybCA9IG5ldyBVUkwobmV3IFVSTChTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHN5c3RlbUlkKSksIG1fc2NyaXB0U3JjVVJMKTsgICAgICAgICAgCi0gICAgICAgICAgfSAgICAgICAgCi0gICAgICAgICAgY2F0Y2ggKGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBtdWUyKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBULCBuZXcgT2JqZWN0W117bV9zY3JpcHRTcmNVUkx9KSwgbXVlMik7IC8vInNyYyBhdHRyaWJ1dGUgbm90IHlldCBzdXBwb3J0ZWQgZm9yICIKLSAgICAgICAgICAvLysgc2NyaXB0TGFuZyk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBpZiAodXJsICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgVVJMQ29ubmVjdGlvbiB1YyA9IHVybC5vcGVuQ29ubmVjdGlvbigpOwotICAgICAgICAgIElucHV0U3RyZWFtIGlzID0gdWMuZ2V0SW5wdXRTdHJlYW0oKTsKLSAgICAgICAgICBieXRlIFtdYkFycmF5ID0gbmV3IGJ5dGVbdWMuZ2V0Q29udGVudExlbmd0aCgpXTsKLSAgICAgICAgICBpcy5yZWFkKGJBcnJheSk7Ci0gICAgICAgICAgbV9zY3JpcHRTcmMgPSBuZXcgU3RyaW5nKGJBcnJheSk7Ci0gICAgICAgICAgCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBULCBuZXcgT2JqZWN0W117bV9zY3JpcHRTcmNVUkx9KSwgaW9lKTsgLy8ic3JjIGF0dHJpYnV0ZSBub3QgeWV0IHN1cHBvcnRlZCBmb3IgIgotICAgICAgICAgIC8vKyBzY3JpcHRMYW5nKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgCi0gICAgfQotICAgCi0gICAgaWYgKG51bGwgPT0gbWFuYWdlckNsYXNzKQotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9JTklUX0JTRk1HUiwgbnVsbCkpOyAvLyJDb3VsZCBub3QgaW5pdGlhbGl6ZSBCU0YgbWFuYWdlciIpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgbV9tZ3IgPSBtYW5hZ2VyQ2xhc3MubmV3SW5zdGFuY2UoKTsKLSAgICAgIG1fZW5naW5lID0gbWdyTG9hZFNjcmlwdGluZ0VuZ2luZS5pbnZva2UobV9tZ3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgc2NyaXB0TGFuZyB9KTsKLQotICAgICAgLy8gIkNvbXBpbGUiIHRoZSBwcm9ncmFtCi0gICAgICBlbmdpbmVFeGVjLmludm9rZShtX2VuZ2luZSwgbmV3IE9iamVjdFtdeyAiWGFsYW5TY3JpcHQiLCBORUcxSU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVHMUlOVCwgbV9zY3JpcHRTcmMgfSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCi0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0NNUExfRVhURU5TTiwgbnVsbCksIGUpOyAvLyJDb3VsZCBub3QgY29tcGlsZSBleHRlbnNpb24iLCBlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciBhIGNlcnRhaW4gZnVuY3Rpb24gbmFtZSBpcyBrbm93biB3aXRoaW4gdGhpcyBuYW1lc3BhY2UuCi0gICAqIEBwYXJhbSBmdW5jdGlvbiBuYW1lIG9mIHRoZSBmdW5jdGlvbiBiZWluZyB0ZXN0ZWQKLSAgICogQHJldHVybiB0cnVlIGlmIGl0cyBrbm93biwgZmFsc2UgaWYgbm90LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNGdW5jdGlvbkF2YWlsYWJsZShTdHJpbmcgZnVuY3Rpb24pCi0gIHsKLSAgICByZXR1cm4gKG1fZnVuY3Rpb25zLmdldChmdW5jdGlvbikgIT0gbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciBhIGNlcnRhaW4gZWxlbWVudCBuYW1lIGlzIGtub3duIHdpdGhpbiB0aGlzIG5hbWVzcGFjZS4KLSAgICogQHBhcmFtIGZ1bmN0aW9uIG5hbWUgb2YgdGhlIGZ1bmN0aW9uIGJlaW5nIHRlc3RlZAotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudCBuYW1lIG9mIHRoZSBlbGVtZW50IGJlaW5nIHRlc3RlZAotICAgKiBAcmV0dXJuIHRydWUgaWYgaXRzIGtub3duLCBmYWxzZSBpZiBub3QuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0VsZW1lbnRBdmFpbGFibGUoU3RyaW5nIGVsZW1lbnQpCi0gIHsKLSAgICByZXR1cm4gKG1fZWxlbWVudHMuZ2V0KGVsZW1lbnQpICE9IG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYSBjYWxsIHRvIGEgZnVuY3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSBmdW5jTmFtZSBGdW5jdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gYXJncyAgICAgVGhlIGFyZ3VtZW50cyBvZiB0aGUgZnVuY3Rpb24gY2FsbC4KLSAgICogQHBhcmFtIG1ldGhvZEtleSBBIGtleSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcyBhbmQgbWV0aG9kIGNhbGwuCi0gICAqIEBwYXJhbSBleHByQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCB0aGlzIGV4cHJlc3Npb24gaXMgYmVpbmcgZXhlY3V0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZnVuY3Rpb24gZXZhbHVhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiAgICAgICAgICBpZiBwYXJzaW5nIHRyb3VibGUKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2FsbEZ1bmN0aW9uKAotICAgICAgICAgIFN0cmluZyBmdW5jTmFtZSwgVmVjdG9yIGFyZ3MsIE9iamVjdCBtZXRob2RLZXksIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIE9iamVjdFtdIGFyZ0FycmF5OwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgYXJnQXJyYXkgPSBuZXcgT2JqZWN0W2FyZ3Muc2l6ZSgpXTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdBcnJheS5sZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgT2JqZWN0IG8gPSBhcmdzLmVsZW1lbnRBdChpKTsKLQotICAgICAgICBhcmdBcnJheVtpXSA9IChvIGluc3RhbmNlb2YgWE9iamVjdCkgPyAoKFhPYmplY3QpIG8pLm9iamVjdCgpIDogbzsKLSAgICAgICAgbyA9IGFyZ0FycmF5W2ldOwotICAgICAgICBpZihudWxsICE9IG8gJiYgbyBpbnN0YW5jZW9mIERUTUl0ZXJhdG9yKQotICAgICAgICB7Ci0gICAgICAgICAgYXJnQXJyYXlbaV0gPSBuZXcgRFRNTm9kZUxpc3QoKERUTUl0ZXJhdG9yKW8pOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBlbmdpbmVDYWxsLmludm9rZShtX2VuZ2luZSwgbmV3IE9iamVjdFtdeyBudWxsLCBmdW5jTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdBcnJheSB9KTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0KLSAgICAgIFN0cmluZyBtc2cgPSBlLmdldE1lc3NhZ2UoKTsKLQotICAgICAgaWYgKG51bGwgIT0gbXNnKQotICAgICAgewotICAgICAgICBpZiAobXNnLnN0YXJ0c1dpdGgoIlN0b3BwaW5nIGFmdGVyIGZhdGFsIGVycm9yOiIpKQotICAgICAgICB7Ci0gICAgICAgICAgbXNnID0gbXNnLnN1YnN0cmluZygiU3RvcHBpbmcgYWZ0ZXIgZmF0YWwgZXJyb3I6Ii5sZW5ndGgoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkNhbGwgdG8gZXh0ZW5zaW9uIGZ1bmN0aW9uIGZhaWxlZDogIittc2cpOwotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gU2hvdWxkIHByb2JhYmx5IG1ha2UgYSBUUmFYIEV4dGVuc2lvbiBFeGNlcHRpb24uCi0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04sIG5ldyBPYmplY3RbXXtmdW5jTmFtZSwgZSB9KSk7IC8vIkNvdWxkIG5vdCBjcmVhdGUgZXh0ZW5zaW9uOiAiICsgZnVuY05hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIiBiZWNhdXNlIG9mOiAiICsgZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYSBjYWxsIHRvIHRoaXMgZXh0ZW5zaW9uIG5hbWVzcGFjZSB2aWEgYW4gZWxlbWVudC4gQXMgYSBzaWRlCi0gICAqIGVmZmVjdCwgdGhlIHJlc3VsdHMgYXJlIHNlbnQgdG8gdGhlIFRyYW5zZm9ybWVySW1wbCdzIHJlc3VsdCB0cmVlLgotICAgKgotICAgKiBAcGFyYW0gbG9jYWxQYXJ0ICAgICAgRWxlbWVudCBuYW1lJ3MgbG9jYWwgcGFydC4KLSAgICogQHBhcmFtIGVsZW1lbnQgICAgICAgIFRoZSBleHRlbnNpb24gZWxlbWVudCBiZWluZyBwcm9jZXNzZWQuCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciAgICAgIEhhbmRsZSB0byBUcmFuc2Zvcm1lckltcGwuCi0gICAqIEBwYXJhbSBzdHlsZXNoZWV0VHJlZSBUaGUgY29tcGlsZWQgc3R5bGVzaGVldCB0cmVlLgotICAgKiBAcGFyYW0gbW9kZSAgICAgICAgICAgVGhlIGN1cnJlbnQgbW9kZS4KLSAgICogQHBhcmFtIHNvdXJjZVRyZWUgICAgIFRoZSByb290IG9mIHRoZSBzb3VyY2UgdHJlZSAoYnV0IGRvbid0IGFzc3VtZQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgaXQncyBhIERvY3VtZW50KS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgICAgIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICogQHBhcmFtIG1ldGhvZEtleSBBIGtleSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcyBhbmQgbWV0aG9kIGNhbGwuCi0gICAqCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiBzb21ldGhpbmcgZ29lcyB3cm9uZwotICAgKiAgICAgICAgICAgIHdoaWxlIHJ1bm5pbmcgdGhlIGV4dGVuc2lvbiBoYW5kbGVyLgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBpZiBsb2FkaW5nIHRyb3VibGUKLSAgICogQHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24gaWYgbG9hZGluZyB0cm91YmxlCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gICAgICAgICAgIGlmIGxvYWRpbmcgdHJvdWJsZQotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uICAgICAgICAgIGlmIHBhcnNpbmcgdHJvdWJsZQotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2Vzc0VsZW1lbnQoCi0gICAgICAgICAgU3RyaW5nIGxvY2FsUGFydCwgRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtZW50LCBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsIAotICAgICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldFRyZWUsIE9iamVjdCBtZXRob2RLZXkpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIE9iamVjdCByZXN1bHQgPSBudWxsOwotICAgIFhTTFByb2Nlc3NvckNvbnRleHQgeHBjID0gbmV3IFhTTFByb2Nlc3NvckNvbnRleHQodHJhbnNmb3JtZXIsIHN0eWxlc2hlZXRUcmVlKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFZlY3RvciBhcmd2ID0gbmV3IFZlY3RvcigyKTsKLQotICAgICAgYXJndi5hZGRFbGVtZW50KHhwYyk7Ci0gICAgICBhcmd2LmFkZEVsZW1lbnQoZWxlbWVudCk7Ci0KLSAgICAgIHJlc3VsdCA9IGNhbGxGdW5jdGlvbihsb2NhbFBhcnQsIGFyZ3YsIG1ldGhvZEtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXRFeHByZXNzaW9uQ29udGV4dCgpKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uIGUpCi0gICAgewotCi0gICAgICAvLyBlLnByaW50U3RhY2tUcmFjZSAoKTsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgZSk7Ci0gICAgfQotCi0gICAgaWYgKHJlc3VsdCAhPSBudWxsKQotICAgIHsKLSAgICAgIHhwYy5vdXRwdXRUb1Jlc3VsdFRyZWUoc3R5bGVzaGVldFRyZWUsIHJlc3VsdCk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbkhhbmRsZXJKYXZhLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbkhhbmRsZXJKYXZhLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY4ZTNhMmMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9FeHRlbnNpb25IYW5kbGVySmF2YS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGhhbmRsaW5nIHRoZSBqYXZhIGxhbmd1YWdlIGV4dGVuc2lvbnMgZm9yIFhQYXRoLgotICogVGhpcyBiYXNlIGNsYXNzIHByb3ZpZGVzIGNhY2hlIG1hbmFnZW1lbnQgc2hhcmVkIGJ5IGFsbCBvZiB0aGUKLSAqIHZhcmlvdXMgamF2YSBleHRlbnNpb24gaGFuZGxlcnMuCi0gKgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXh0ZW5zaW9uSGFuZGxlckphdmEgZXh0ZW5kcyBFeHRlbnNpb25IYW5kbGVyCi17Ci0KLSAgLyoqIEV4dGVuc2lvbiBjbGFzcyBuYW1lICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBtX2NsYXNzTmFtZSA9ICIiOwotCi0gIC8qKiBUYWJsZSBvZiBjYWNoZWQgbWV0aG9kcyAgICAgICAgICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2NhY2hlZE1ldGhvZHMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBleHRlbnNpb24gaGFuZGxlciBnaXZlbiBhbGwgdGhlIGluZm9ybWF0aW9uCi0gICAqIG5lZWRlZC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVyaSB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBVUkkgdGhhdCBJJ20gaW1wbGVtZW50aW5nCi0gICAqIEBwYXJhbSBmdW5jTmFtZXMgICAgc3RyaW5nIGNvbnRhaW5pbmcgbGlzdCBvZiBmdW5jdGlvbnMgb2YgZXh0ZW5zaW9uIE5TCi0gICAqIEBwYXJhbSBsYW5nICAgICAgICAgbGFuZ3VhZ2Ugb2YgY29kZSBpbXBsZW1lbnRpbmcgdGhlIGV4dGVuc2lvbgotICAgKiBAcGFyYW0gc3JjVVJMICAgICAgIHZhbHVlIG9mIHNyYyBhdHRyaWJ1dGUgKGlmIGFueSkgLSB0cmVhdGVkIGFzIGEgVVJMCi0gICAqICAgICAgICAgICAgICAgICAgICAgb3IgYSBjbGFzc25hbWUgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZSBvZiBsYW5nLiBJZgotICAgKiAgICAgICAgICAgICAgICAgICAgIHNyY1VSTCBpcyBub3QgbnVsbCwgdGhlbiBzY3JpcHRTcmMgaXMgaWdub3JlZC4KLSAgICogQHBhcmFtIHNjcmlwdFNyYyAgICB0aGUgYWN0dWFsIHNjcmlwdCBjb2RlIChpZiBhbnkpCi0gICAqIEBwYXJhbSBzY3JpcHRMYW5nICAgdGhlIHNjcmlwdGluZyBsYW5ndWFnZQotICAgKiBAcGFyYW0gY2xhc3NOYW1lICAgIHRoZSBleHRlbnNpb24gY2xhc3MgbmFtZSAKLSAgICovCi0gIHByb3RlY3RlZCBFeHRlbnNpb25IYW5kbGVySmF2YShTdHJpbmcgbmFtZXNwYWNlVXJpLCBTdHJpbmcgc2NyaXB0TGFuZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjbGFzc05hbWUpCi0gIHsKLQotICAgIHN1cGVyKG5hbWVzcGFjZVVyaSwgc2NyaXB0TGFuZyk7Ci0KLSAgICBtX2NsYXNzTmFtZSA9IGNsYXNzTmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIHRoZSBlbnRyeSBpbiB0aGUgbWV0aG9kIGNhY2hlLgotICAgKiBAcGFyYW0gbWV0aG9kS2V5ICAgQSBrZXkgdGhhdCB1bmlxdWVseSBpZGVudGlmaWVzIHRoaXMgaW52b2NhdGlvbiBpbgotICAgKiAgICAgICAgICAgICAgICAgICAgdGhlIHN0eWxlc2hlZXQuCi0gICAqIEBwYXJhbSBvYmpUeXBlICAgICBBIENsYXNzIG9iamVjdCBvciBpbnN0YW5jZSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSB0eXBlCi0gICAqIEBwYXJhbSBtZXRob2RBcmdzICBBbiBhcnJheSBvZiB0aGUgWE9iamVjdCBhcmd1bWVudHMgdG8gYmUgdXNlZCBmb3IKLSAgICogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG1hbmdsaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBnaXZlbiBtZXRob2QgZnJvbSB0aGUgbWV0aG9kIGNhY2hlCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldEZyb21DYWNoZShPYmplY3QgbWV0aG9kS2V5LCBPYmplY3Qgb2JqVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10gbWV0aG9kQXJncykKLSAgewotCi0gICAgLy8gRXZlbnR1YWxseSwgd2Ugd2FudCB0byBpbnNlcnQgY29kZSB0byBtYW5nbGUgdGhlIG1ldGhvZEtleSB3aXRoIG1ldGhvZEFyZ3MKLSAgICByZXR1cm4gbV9jYWNoZWRNZXRob2RzLmdldChtZXRob2RLZXkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIG5ldyBlbnRyeSBpbnRvIHRoZSBtZXRob2QgY2FjaGUuCi0gICAqIEBwYXJhbSBtZXRob2RLZXkgICBBIGtleSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBpbnZvY2F0aW9uIGluCi0gICAqICAgICAgICAgICAgICAgICAgICB0aGUgc3R5bGVzaGVldC4KLSAgICogQHBhcmFtIG9ialR5cGUgICAgIEEgQ2xhc3Mgb2JqZWN0IG9yIGluc3RhbmNlIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHR5cGUKLSAgICogQHBhcmFtIG1ldGhvZEFyZ3MgIEFuIGFycmF5IG9mIHRoZSBYT2JqZWN0IGFyZ3VtZW50cyB0byBiZSB1c2VkIGZvcgotICAgKiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gbWFuZ2xpbmcuCi0gICAqIEBwYXJhbSBtZXRob2RPYmogICBBIENsYXNzIG9iamVjdCBvciBpbnN0YW5jZSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBtZXRob2QKLSAgICoKLSAgICogQHJldHVybiBUaGUgY2FjaGVkIG1ldGhvZCBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgcHV0VG9DYWNoZShPYmplY3QgbWV0aG9kS2V5LCBPYmplY3Qgb2JqVHlwZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdIG1ldGhvZEFyZ3MsIE9iamVjdCBtZXRob2RPYmopCi0gIHsKLQotICAgIC8vIEV2ZW50dWFsbHksIHdlIHdhbnQgdG8gaW5zZXJ0IGNvZGUgdG8gbWFuZ2xlIHRoZSBtZXRob2RLZXkgd2l0aCBtZXRob2RBcmdzCi0gICAgcmV0dXJuIG1fY2FjaGVkTWV0aG9kcy5wdXQobWV0aG9kS2V5LCBtZXRob2RPYmopOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbkhhbmRsZXJKYXZhQ2xhc3MuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlckphdmFDbGFzcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2N2VmZmQzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlckphdmFDbGFzcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDI4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogUmVwcmVzZW50cyBhbiBleHRlbnNpb24gbmFtZXNwYWNlIGZvciBYUGF0aCB0aGF0IGhhbmRsZXMgamF2YSBjbGFzc2VzLgotICogSXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0aGUgY2xhc3MgVVJJIGJlIG9mIHRoZSBmb3JtOgotICogPHByZT4KLSAqICAgeGFsYW46Ly9mdWxseS5xdWFsaWZpZWQuY2xhc3MubmFtZQotICogPC9wcmU+Ci0gKiBIb3dldmVyLCB3ZSBkbyBub3QgZW5mb3JjZSB0aGlzLiAgSWYgdGhlIGNsYXNzIG5hbWUgY29udGFpbnMgYQotICogYSAvLCB3ZSBvbmx5IHVzZSB0aGUgcGFydCB0byB0aGUgcmlnaHQgb2YgdGhlIHJpZ2h0bW9zdCBzbGFzaC4KLSAqIEluIGFkZGl0aW9uLCB3ZSBpZ25vcmUgYW55ICJjbGFzczoiIHByZWZpeC4KLSAqIFByb3ZpZGVzIGZ1bmN0aW9ucyB0byB0ZXN0IGEgZnVuY3Rpb24ncyBleGlzdGVuY2UgYW5kIGNhbGwgYSBmdW5jdGlvbi4KLSAqIEFsc28gcHJvdmlkZXMgZnVuY3Rpb25zIHRvIHRlc3QgYW4gZWxlbWVudCdzIGV4aXN0ZW5jZSBhbmQgY2FsbCBhbgotICogZWxlbWVudC4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpnYXJ5cEBmaXJzdGVjaC5jb20iPkdhcnkgTCBQZXNraW48L2E+Ci0gKi8KLQotcHVibGljIGNsYXNzIEV4dGVuc2lvbkhhbmRsZXJKYXZhQ2xhc3MgZXh0ZW5kcyBFeHRlbnNpb25IYW5kbGVySmF2YQotewotCi0gIHByaXZhdGUgQ2xhc3MgbV9jbGFzc09iaiA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFByb3ZpZGVzIGEgZGVmYXVsdCBJbnN0YW5jZSBmb3IgdXNlIGJ5IGVsZW1lbnRzIHRoYXQgbmVlZCB0byBjYWxsIAotICAgKiBhbiBpbnN0YW5jZSBtZXRob2QuCi0gICAqLwotCi0gIHByaXZhdGUgT2JqZWN0IG1fZGVmYXVsdEluc3RhbmNlID0gbnVsbDsKLQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgZXh0ZW5zaW9uIG5hbWVzcGFjZSBoYW5kbGVyIGdpdmVuIGFsbCB0aGUgaW5mb3JtYXRpb24KLSAgICogbmVlZGVkLiAKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVyaSB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBVUkkgdGhhdCBJJ20gaW1wbGVtZW50aW5nCi0gICAqIEBwYXJhbSBzY3JpcHRMYW5nICAgbGFuZ3VhZ2Ugb2YgY29kZSBpbXBsZW1lbnRpbmcgdGhlIGV4dGVuc2lvbgotICAgKiBAcGFyYW0gY2xhc3NOYW1lICAgIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiB0aGUgY2xhc3MKLSAgICovCi0gIHB1YmxpYyBFeHRlbnNpb25IYW5kbGVySmF2YUNsYXNzKFN0cmluZyBuYW1lc3BhY2VVcmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzY3JpcHRMYW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lKQotICB7Ci0gICAgc3VwZXIobmFtZXNwYWNlVXJpLCBzY3JpcHRMYW5nLCBjbGFzc05hbWUpOwotICAgIHRyeQotICAgIHsKLSAgICAgIG1fY2xhc3NPYmogPSBnZXRDbGFzc0Zvck5hbWUoY2xhc3NOYW1lKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAvLyBGb3Igbm93LCBqdXN0IGxldCB0aGlzIGdvLiAgV2UnbGwgY2F0Y2ggaXQgd2hlbiB3ZSB0cnkgdG8gaW52b2tlIGEgbWV0aG9kLgotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlc3RzIHdoZXRoZXIgYSBjZXJ0YWluIGZ1bmN0aW9uIG5hbWUgaXMga25vd24gd2l0aGluIHRoaXMgbmFtZXNwYWNlLgotICAgKiBTaW1wbHkgbG9va3MgZm9yIGEgbWV0aG9kIHdpdGggdGhlIGFwcHJvcHJpYXRlIG5hbWUuICBUaGVyZSBpcwotICAgKiBubyBpbmZvcm1hdGlvbiByZWdhcmRpbmcgdGhlIGFyZ3VtZW50cyB0byB0aGUgZnVuY3Rpb24gY2FsbCBvcgotICAgKiB3aGV0aGVyIHRoZSBtZXRob2QgaW1wbGVtZW50aW5nIHRoZSBmdW5jdGlvbiBpcyBhIHN0YXRpYyBtZXRob2Qgb3IKLSAgICogYW4gaW5zdGFuY2UgbWV0aG9kLgotICAgKiBAcGFyYW0gZnVuY3Rpb24gbmFtZSBvZiB0aGUgZnVuY3Rpb24gYmVpbmcgdGVzdGVkCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBpdHMga25vd24sIGZhbHNlIGlmIG5vdC4KLSAgICovCi0KLSAgcHVibGljIGJvb2xlYW4gaXNGdW5jdGlvbkF2YWlsYWJsZShTdHJpbmcgZnVuY3Rpb24pIAotICB7Ci0gICAgTWV0aG9kW10gbWV0aG9kcyA9IG1fY2xhc3NPYmouZ2V0TWV0aG9kcygpOwotICAgIGludCBuTWV0aG9kcyA9IG1ldGhvZHMubGVuZ3RoOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbk1ldGhvZHM7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobWV0aG9kc1tpXS5nZXROYW1lKCkuZXF1YWxzKGZ1bmN0aW9uKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlc3RzIHdoZXRoZXIgYSBjZXJ0YWluIGVsZW1lbnQgbmFtZSBpcyBrbm93biB3aXRoaW4gdGhpcyBuYW1lc3BhY2UuCi0gICAqIExvb2tzIGZvciBhIG1ldGhvZCB3aXRoIHRoZSBhcHByb3ByaWF0ZSBuYW1lIGFuZCBzaWduYXR1cmUuCi0gICAqIFRoaXMgbWV0aG9kIGV4YW1pbmVzIGJvdGggc3RhdGljIGFuZCBpbnN0YW5jZSBtZXRob2RzLgotICAgKiBAcGFyYW0gZWxlbWVudCBuYW1lIG9mIHRoZSBlbGVtZW50IGJlaW5nIHRlc3RlZAotICAgKiBAcmV0dXJuIHRydWUgaWYgaXRzIGtub3duLCBmYWxzZSBpZiBub3QuCi0gICAqLwotCi0gIHB1YmxpYyBib29sZWFuIGlzRWxlbWVudEF2YWlsYWJsZShTdHJpbmcgZWxlbWVudCkgCi0gIHsKLSAgICBNZXRob2RbXSBtZXRob2RzID0gbV9jbGFzc09iai5nZXRNZXRob2RzKCk7Ci0gICAgaW50IG5NZXRob2RzID0gbWV0aG9kcy5sZW5ndGg7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuTWV0aG9kczsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtZXRob2RzW2ldLmdldE5hbWUoKS5lcXVhbHMoZWxlbWVudCkpCi0gICAgICB7Ci0gICAgICAgIENsYXNzW10gcGFyYW1UeXBlcyA9IG1ldGhvZHNbaV0uZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLSAgICAgICAgaWYgKCAocGFyYW1UeXBlcy5sZW5ndGggPT0gMikKLSAgICAgICAgICAmJiBwYXJhbVR5cGVzWzBdLmlzQXNzaWduYWJsZUZyb20oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLlhTTFByb2Nlc3NvckNvbnRleHQuY2xhc3MpCi0gICAgICAgICAgJiYgcGFyYW1UeXBlc1sxXS5pc0Fzc2lnbmFibGVGcm9tKG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1FeHRlbnNpb25DYWxsLmNsYXNzKSApCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGEgY2FsbCB0byBhIGZ1bmN0aW9uIGluIHRoZSBqYXZhIGNsYXNzIHJlcHJlc2VudGVkIGJ5Ci0gICAqIHRoaXMgPGNvZGU+RXh0ZW5zaW9uSGFuZGxlckphdmFDbGFzczxjb2RlPi4KLSAgICogVGhlcmUgYXJlIHRocmVlIHBvc3NpYmxlIHR5cGVzIG9mIGNhbGxzOgotICAgKiA8cHJlPgotICAgKiAgIENvbnN0cnVjdG9yOgotICAgKiAgICAgY2xhc3NuczpuZXcoYXJnMSwgYXJnMiwgLi4uKQotICAgKgotICAgKiAgIFN0YXRpYyBtZXRob2Q6Ci0gICAqICAgICBjbGFzc25zOm1ldGhvZChhcmcxLCBhcmcyLCAuLi4pCi0gICAqCi0gICAqICAgSW5zdGFuY2UgbWV0aG9kOgotICAgKiAgICAgY2xhc3NuczptZXRob2Qob2JqLCBhcmcxLCBhcmcyLCAuLi4pCi0gICAqIDwvcHJlPgotICAgKiBXZSB1c2UgdGhlIGZvbGxvd2luZyBydWxlcyB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgY2FsbCBtYWRlOgotICAgKiA8b2wgdHlwZT0iMSI+Ci0gICAqIDxsaT5JZiB0aGUgZnVuY3Rpb24gbmFtZSBpcyAibmV3IiwgY2FsbCB0aGUgYmVzdCBjb25zdHJ1Y3RvciBmb3IKLSAgICogICAgIGNsYXNzIHJlcHJlc2VudGVkIGJ5IHRoZSBuYW1lc3BhY2UgVVJJPC9saT4KLSAgICogPGxpPklmIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgZnVuY3Rpb24gaXMgb2YgdGhlIGNsYXNzIHNwZWNpZmllZAotICAgKiAgICAgaW4gdGhlIG5hbWVzcGFjZSBvciBpcyBhIHN1YmNsYXNzIG9mIHRoYXQgY2xhc3MsIGxvb2sgZm9yIHRoZSBiZXN0Ci0gICAqICAgICBtZXRob2Qgb2YgdGhlIGNsYXNzIHNwZWNpZmllZCBpbiB0aGUgbmFtZXNwYWNlIHdpdGggdGhlIHNwZWNpZmllZAotICAgKiAgICAgYXJndW1lbnRzLiAgQ29tcGFyZSBhbGwgc3RhdGljIGFuZCBpbnN0YW5jZSBtZXRob2RzIHdpdGggdGhlIGNvcnJlY3QKLSAgICogICAgIG1ldGhvZCBuYW1lLiAgRm9yIHN0YXRpYyBtZXRob2RzLCB1c2UgYWxsIGFyZ3VtZW50cyBpbiB0aGUgY29tcGFyZS4KLSAgICogICAgIEZvciBpbnN0YW5jZSBtZXRob2RzLCB1c2UgYWxsIGFyZ3VtZW50cyBhZnRlciB0aGUgZmlyc3QuPC9saT4KLSAgICogPGxpPk90aGVyd2lzZSwgc2VsZWN0IHRoZSBiZXN0IHN0YXRpYyBvciBpbnN0YW5jZSBtZXRob2QgbWF0Y2hpbmcKLSAgICogICAgIGFsbCBvZiB0aGUgYXJndW1lbnRzLiAgSWYgdGhlIGJlc3QgbWV0aG9kIGlzIGFuIGluc3RhbmNlIG1ldGhvZCwKLSAgICogICAgIGNhbGwgdGhlIGZ1bmN0aW9uIHVzaW5nIGEgZGVmYXVsdCBvYmplY3QsIGNyZWF0aW5nIGl0IGlmIG5lZWRlZC48L2xpPgotICAgKiA8L29sPgotICAgKgotICAgKiBAcGFyYW0gZnVuY05hbWUgRnVuY3Rpb24gbmFtZS4KLSAgICogQHBhcmFtIGFyZ3MgICAgIFRoZSBhcmd1bWVudHMgb2YgdGhlIGZ1bmN0aW9uIGNhbGwuCi0gICAqIEBwYXJhbSBtZXRob2RLZXkgQSBrZXkgdGhhdCB1bmlxdWVseSBpZGVudGlmaWVzIHRoaXMgY2xhc3MgYW5kIG1ldGhvZCBjYWxsLgotICAgKiBAcGFyYW0gZXhwckNvbnRleHQgVGhlIGNvbnRleHQgaW4gd2hpY2ggdGhpcyBleHByZXNzaW9uIGlzIGJlaW5nIGV4ZWN1dGVkLgotICAgKiBAcmV0dXJuIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIGV2YWx1YXRpb24uCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0KLSAgcHVibGljIE9iamVjdCBjYWxsRnVuY3Rpb24gKFN0cmluZyBmdW5jTmFtZSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3IgYXJncywgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgbWV0aG9kS2V5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIAotICB7Ci0KLSAgICBPYmplY3RbXSBtZXRob2RBcmdzOwotICAgIE9iamVjdFtdW10gY29udmVydGVkQXJnczsKLSAgICBDbGFzc1tdIHBhcmFtVHlwZXM7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAoZnVuY05hbWUuZXF1YWxzKCJuZXciKSkgeyAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgY29uc3RydWN0b3IgY2FsbAotCi0gICAgICAgIG1ldGhvZEFyZ3MgPSBuZXcgT2JqZWN0W2FyZ3Muc2l6ZSgpXTsKLSAgICAgICAgY29udmVydGVkQXJncyA9IG5ldyBPYmplY3RbMV1bXTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RBcmdzLmxlbmd0aDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgbWV0aG9kQXJnc1tpXSA9IGFyZ3MuZWxlbWVudEF0KGkpOwotICAgICAgICB9Ci0gICAgICAgIENvbnN0cnVjdG9yIGMgPSAoQ29uc3RydWN0b3IpIGdldEZyb21DYWNoZShtZXRob2RLZXksIG51bGwsIG1ldGhvZEFyZ3MpOwotICAgICAgICBpZiAoYyAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgdHJ5Ci0gICAgICAgICAgewotICAgICAgICAgICAgcGFyYW1UeXBlcyA9IGMuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLSAgICAgICAgICAgIE1ldGhvZFJlc29sdmVyLmNvbnZlcnRQYXJhbXMobWV0aG9kQXJncywgY29udmVydGVkQXJncywgcGFyYW1UeXBlcywgZXhwckNvbnRleHQpOwotICAgICAgICAgICAgcmV0dXJuIGMubmV3SW5zdGFuY2UoY29udmVydGVkQXJnc1swXSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIE11c3Qgbm90IGhhdmUgYmVlbiB0aGUgcmlnaHQgb25lCi0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGMgPSBNZXRob2RSZXNvbHZlci5nZXRDb25zdHJ1Y3RvcihtX2NsYXNzT2JqLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZEFyZ3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWRBcmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwckNvbnRleHQpOwotICAgICAgICBwdXRUb0NhY2hlKG1ldGhvZEtleSwgbnVsbCwgbWV0aG9kQXJncywgYyk7Ci0gICAgICAgIHJldHVybiBjLm5ld0luc3RhbmNlKGNvbnZlcnRlZEFyZ3NbMF0pOwotICAgICAgfQotCi0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgaW50IHJlc29sdmVUeXBlOwotICAgICAgICBPYmplY3QgdGFyZ2V0T2JqZWN0ID0gbnVsbDsKLSAgICAgICAgbWV0aG9kQXJncyA9IG5ldyBPYmplY3RbYXJncy5zaXplKCldOwotICAgICAgICBjb252ZXJ0ZWRBcmdzID0gbmV3IE9iamVjdFsxXVtdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZEFyZ3MubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBtZXRob2RBcmdzW2ldID0gYXJncy5lbGVtZW50QXQoaSk7Ci0gICAgICAgIH0KLSAgICAgICAgTWV0aG9kIG0gPSAoTWV0aG9kKSBnZXRGcm9tQ2FjaGUobWV0aG9kS2V5LCBudWxsLCBtZXRob2RBcmdzKTsKLSAgICAgICAgaWYgKG0gIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBhcmFtVHlwZXMgPSBtLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICAgICAgICBNZXRob2RSZXNvbHZlci5jb252ZXJ0UGFyYW1zKG1ldGhvZEFyZ3MsIGNvbnZlcnRlZEFyZ3MsIHBhcmFtVHlwZXMsIGV4cHJDb250ZXh0KTsKLSAgICAgICAgICAgIGlmIChNb2RpZmllci5pc1N0YXRpYyhtLmdldE1vZGlmaWVycygpKSkKLSAgICAgICAgICAgICAgcmV0dXJuIG0uaW52b2tlKG51bGwsIGNvbnZlcnRlZEFyZ3NbMF0pOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRyaWNreS4gIFdlIGdldCB0aGUgYWN0dWFsIG51bWJlciBvZiB0YXJnZXQgYXJndW1lbnRzIChleGNsdWRpbmcgYW55Ci0gICAgICAgICAgICAgIC8vICAgRXhwcmVzc2lvbkNvbnRleHQpLiAgSWYgd2UgcGFzc2VkIGluIHRoZSBzYW1lIG51bWJlciwgd2UgbmVlZCB0aGUgaW1wbGllZCBvYmplY3QuCi0gICAgICAgICAgICAgIGludCBuVGFyZ2V0QXJncyA9IGNvbnZlcnRlZEFyZ3NbMF0ubGVuZ3RoOwotICAgICAgICAgICAgICBpZiAoRXhwcmVzc2lvbkNvbnRleHQuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShwYXJhbVR5cGVzWzBdKSkKLSAgICAgICAgICAgICAgICBuVGFyZ2V0QXJncy0tOwotICAgICAgICAgICAgICBpZiAobWV0aG9kQXJncy5sZW5ndGggPD0gblRhcmdldEFyZ3MpCi0gICAgICAgICAgICAgICAgcmV0dXJuIG0uaW52b2tlKG1fZGVmYXVsdEluc3RhbmNlLCBjb252ZXJ0ZWRBcmdzWzBdKTsKLSAgICAgICAgICAgICAgZWxzZSAgCi0gICAgICAgICAgICAgICAgcmV0dXJuIG0uaW52b2tlKG1ldGhvZEFyZ3NbMF0sIGNvbnZlcnRlZEFyZ3NbMF0pOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBNdXN0IG5vdCBoYXZlIGJlZW4gdGhlIHJpZ2h0IG9uZQotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmIChhcmdzLnNpemUoKSA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICB0YXJnZXRPYmplY3QgPSBtZXRob2RBcmdzWzBdOwotCi0gICAgICAgICAgaWYgKHRhcmdldE9iamVjdCBpbnN0YW5jZW9mIFhPYmplY3QpCi0gICAgICAgICAgICB0YXJnZXRPYmplY3QgPSAoKFhPYmplY3QpIHRhcmdldE9iamVjdCkub2JqZWN0KCk7Ci0KLSAgICAgICAgICBpZiAobV9jbGFzc09iai5pc0Fzc2lnbmFibGVGcm9tKHRhcmdldE9iamVjdC5nZXRDbGFzcygpKSkKLSAgICAgICAgICAgIHJlc29sdmVUeXBlID0gTWV0aG9kUmVzb2x2ZXIuRFlOQU1JQzsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXNvbHZlVHlwZSA9IE1ldGhvZFJlc29sdmVyLlNUQVRJQ19BTkRfSU5TVEFOQ0U7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgdGFyZ2V0T2JqZWN0ID0gbnVsbDsKLSAgICAgICAgICByZXNvbHZlVHlwZSA9IE1ldGhvZFJlc29sdmVyLlNUQVRJQ19BTkRfSU5TVEFOQ0U7Ci0gICAgICAgIH0KLQotICAgICAgICBtID0gTWV0aG9kUmVzb2x2ZXIuZ2V0TWV0aG9kKG1fY2xhc3NPYmosCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kQXJncywgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydGVkQXJncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByQ29udGV4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlVHlwZSk7Ci0gICAgICAgIHB1dFRvQ2FjaGUobWV0aG9kS2V5LCBudWxsLCBtZXRob2RBcmdzLCBtKTsKLQotICAgICAgICBpZiAoTWV0aG9kUmVzb2x2ZXIuRFlOQU1JQyA9PSByZXNvbHZlVHlwZSkgICAgICAgICAgLy8gRmlyc3QgYXJndW1lbnQgd2FzIG9iamVjdCB0eXBlCi0gICAgICAgICAgcmV0dXJuIG0uaW52b2tlKHRhcmdldE9iamVjdCwgY29udmVydGVkQXJnc1swXSk7Ci0gICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmlyc3QgYXJnIHdhcyBub3Qgb2JqZWN0LiAgU2VlIGlmIHdlIG5lZWQgdGhlIGltcGxpZWQgb2JqZWN0LgotICAgICAgICB7Ci0gICAgICAgICAgaWYgKE1vZGlmaWVyLmlzU3RhdGljKG0uZ2V0TW9kaWZpZXJzKCkpKQotICAgICAgICAgICAgcmV0dXJuIG0uaW52b2tlKG51bGwsIGNvbnZlcnRlZEFyZ3NbMF0pOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSBtX2RlZmF1bHRJbnN0YW5jZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgbV9kZWZhdWx0SW5zdGFuY2UgPSBtX2NsYXNzT2JqLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbS5pbnZva2UobV9kZWZhdWx0SW5zdGFuY2UsIGNvbnZlcnRlZEFyZ3NbMF0pOwotICAgICAgICAgIH0gIAotICAgICAgICB9Ci0KLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlKQotICAgIHsKLSAgICAgIFRocm93YWJsZSByZWFsRXhjZXB0aW9uID0gaXRlLmdldFRhcmdldEV4Y2VwdGlvbigpOwotICAgICAgaWYgKHJlYWxFeGNlcHRpb24gaW5zdGFuY2VvZiBFeGNlcHRpb24pCi0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbigoRXhjZXB0aW9uKSByZWFsRXhjZXB0aW9uKTsKLSAgICAgIGVsc2UKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGl0ZSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAvLyBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYSBjYWxsIHRvIHRoaXMgZXh0ZW5zaW9uIG5hbWVzcGFjZSB2aWEgYW4gZWxlbWVudC4gQXMgYSBzaWRlCi0gICAqIGVmZmVjdCwgdGhlIHJlc3VsdHMgYXJlIHNlbnQgdG8gdGhlIFRyYW5zZm9ybWVySW1wbCdzIHJlc3VsdCB0cmVlLiAKLSAgICogV2UgaW52b2tlIHRoZSBzdGF0aWMgb3IgaW5zdGFuY2UgbWV0aG9kIGluIHRoZSBjbGFzcyByZXByZXNlbnRlZCBieQotICAgKiBieSB0aGUgbmFtZXNwYWNlIFVSSS4gIElmIHdlIGRvbid0IGFscmVhZHkgaGF2ZSBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLAotICAgKiB3ZSBjcmVhdGUgb25lIHVwb24gdGhlIGZpcnN0IGNhbGwuCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbFBhcnQgICAgICBFbGVtZW50IG5hbWUncyBsb2NhbCBwYXJ0LgotICAgKiBAcGFyYW0gZWxlbWVudCAgICAgICAgVGhlIGV4dGVuc2lvbiBlbGVtZW50IGJlaW5nIHByb2Nlc3NlZC4KLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyICAgICAgSGFuZGxlIHRvIFRyYW5zZm9ybWVySW1wbC4KLSAgICogQHBhcmFtIHN0eWxlc2hlZXRUcmVlIFRoZSBjb21waWxlZCBzdHlsZXNoZWV0IHRyZWUuCi0gICAqIEBwYXJhbSBzb3VyY2VUcmVlICAgICBUaGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUgKGJ1dCBkb24ndCBhc3N1bWUKLSAgICogICAgICAgICAgICAgICAgICAgICAgIGl0J3MgYSBEb2N1bWVudCkuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlICAgICBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBtb2RlICAgICAgICAgICBUaGUgY3VycmVudCBtb2RlLgotICAgKiBAcGFyYW0gbWV0aG9kS2V5ICAgICAgQSBrZXkgdGhhdCB1bmlxdWVseSBpZGVudGlmaWVzIHRoaXMgZWxlbWVudCBjYWxsLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICAgICAgICAgICBpZiBsb2FkaW5nIHRyb3VibGUKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiAgICAgICAgICBpZiBwYXJzaW5nIHRyb3VibGUKLSAgICovCi0KLSAgcHVibGljIHZvaWQgcHJvY2Vzc0VsZW1lbnQoU3RyaW5nIGxvY2FsUGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldFRyZWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBtZXRob2RLZXkpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbgotICB7Ci0gICAgT2JqZWN0IHJlc3VsdCA9IG51bGw7Ci0KLSAgICBNZXRob2QgbSA9IChNZXRob2QpIGdldEZyb21DYWNoZShtZXRob2RLZXksIG51bGwsIG51bGwpOwotICAgIGlmIChudWxsID09IG0pCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIG0gPSBNZXRob2RSZXNvbHZlci5nZXRFbGVtZW50TWV0aG9kKG1fY2xhc3NPYmosIGxvY2FsUGFydCk7Ci0gICAgICAgIGlmICggKG51bGwgPT0gbV9kZWZhdWx0SW5zdGFuY2UpICYmICFNb2RpZmllci5pc1N0YXRpYyhtLmdldE1vZGlmaWVycygpKSApCi0gICAgICAgICAgbV9kZWZhdWx0SW5zdGFuY2UgPSBtX2NsYXNzT2JqLm5ld0luc3RhbmNlKCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIGUucHJpbnRTdGFja1RyYWNlICgpOwotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24gKGUuZ2V0TWVzc2FnZSAoKSwgZSk7Ci0gICAgICB9Ci0gICAgICBwdXRUb0NhY2hlKG1ldGhvZEtleSwgbnVsbCwgbnVsbCwgbSk7Ci0gICAgfQotCi0gICAgWFNMUHJvY2Vzc29yQ29udGV4dCB4cGMgPSBuZXcgWFNMUHJvY2Vzc29yQ29udGV4dCh0cmFuc2Zvcm1lciwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0VHJlZSk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXN1bHQgPSBtLmludm9rZShtX2RlZmF1bHRJbnN0YW5jZSwgbmV3IE9iamVjdFtdIHt4cGMsIGVsZW1lbnR9KTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIGUucHJpbnRTdGFja1RyYWNlICgpOwotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uIChlLmdldE1lc3NhZ2UgKCksIGUpOwotICAgIH0KLQotICAgIGlmIChyZXN1bHQgIT0gbnVsbCkKLSAgICB7Ci0gICAgICB4cGMub3V0cHV0VG9SZXN1bHRUcmVlIChzdHlsZXNoZWV0VHJlZSwgcmVzdWx0KTsKLSAgICB9Ci0gCi0gIH0KLSAKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlckphdmFQYWNrYWdlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbkhhbmRsZXJKYXZhUGFja2FnZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNjU5NzUwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvRXh0ZW5zaW9uSGFuZGxlckphdmFQYWNrYWdlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NzkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogUmVwcmVzZW50cyBhbiBleHRlbnNpb24gbmFtZXNwYWNlIGZvciBYUGF0aCB0aGF0IGhhbmRsZXMgamF2YSBwYWNrYWdlcwotICogdGhhdCBtYXkgYmUgZnVsbHkgb3IgcGFydGlhbGx5IHNwZWNpZmllZC4KLSAqIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhlIGNsYXNzIFVSSSBiZSBvZiBvbmUgb2YgdGhlIGZvbGxvd2luZyBmb3JtczoKLSAqIDxwcmU+Ci0gKiAgIHhhbGFuOi8vcGFydGlhbC5jbGFzcy5uYW1lCi0gKiAgIHhhbGFuOi8vCi0gKiAgIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0L2phdmEgKHdoaWNoIGlzIHRoZSBzYW1lIGFzIHhhbGFuOi8vKQotICogPC9wcmU+Ci0gKiBIb3dldmVyLCB3ZSBkbyBub3QgZW5mb3JjZSB0aGlzLiAgSWYgdGhlIGNsYXNzIG5hbWUgY29udGFpbnMgYQotICogYSAvLCB3ZSBvbmx5IHVzZSB0aGUgcGFydCB0byB0aGUgcmlnaHQgb2YgdGhlIHJpZ2h0bW9zdCBzbGFzaC4KLSAqIEluIGFkZGl0aW9uLCB3ZSBpZ25vcmUgYW55ICJjbGFzczoiIHByZWZpeC4KLSAqIFByb3ZpZGVzIGZ1bmN0aW9ucyB0byB0ZXN0IGEgZnVuY3Rpb24ncyBleGlzdGVuY2UgYW5kIGNhbGwgYSBmdW5jdGlvbi4KLSAqIEFsc28gcHJvdmlkZXMgZnVuY3Rpb25zIHRvIHRlc3QgYW4gZWxlbWVudCdzIGV4aXN0ZW5jZSBhbmQgY2FsbCBhbgotICogZWxlbWVudC4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpnYXJ5cEBmaXJzdGVjaC5jb20iPkdhcnkgTCBQZXNraW48L2E+Ci0gKgotICovCi0KLQotcHVibGljIGNsYXNzIEV4dGVuc2lvbkhhbmRsZXJKYXZhUGFja2FnZSBleHRlbmRzIEV4dGVuc2lvbkhhbmRsZXJKYXZhCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBleHRlbnNpb24gbmFtZXNwYWNlIGhhbmRsZXIgZ2l2ZW4gYWxsIHRoZSBpbmZvcm1hdGlvbgotICAgKiBuZWVkZWQuIAotICAgKiAKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVyaSB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBVUkkgdGhhdCBJJ20gaW1wbGVtZW50aW5nCi0gICAqIEBwYXJhbSBzY3JpcHRMYW5nICAgbGFuZ3VhZ2Ugb2YgY29kZSBpbXBsZW1lbnRpbmcgdGhlIGV4dGVuc2lvbgotICAgKiBAcGFyYW0gY2xhc3NOYW1lICAgIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNsYXNzIG5hbWUgb2YgdGhlIGNsYXNzLiAgVGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBiZSBmb2xsb3dlZCBieSBhIGRvdCAoLikKLSAgICovCi0gIHB1YmxpYyBFeHRlbnNpb25IYW5kbGVySmF2YVBhY2thZ2UoU3RyaW5nIG5hbWVzcGFjZVVyaSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc2NyaXB0TGFuZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lKQotICB7Ci0gICAgc3VwZXIobmFtZXNwYWNlVXJpLCBzY3JpcHRMYW5nLCBjbGFzc05hbWUpOwotICB9Ci0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciBhIGNlcnRhaW4gZnVuY3Rpb24gbmFtZSBpcyBrbm93biB3aXRoaW4gdGhpcyBuYW1lc3BhY2UuCi0gICAqIFNpbmNlIHRoaXMgaXMgZm9yIGEgcGFja2FnZSwgd2UgY29uY2F0ZW5hdGUgdGhlIHBhY2thZ2UgbmFtZSB1c2VkIHdoZW4KLSAgICogdGhpcyBoYW5kbGVyIHdhcyBjcmVhdGVkIGFuZCB0aGUgZnVuY3Rpb24gbmFtZSBzcGVjaWZpZWQgaW4gdGhlIGFyZ3VtZW50LgotICAgKiBUaGVyZSBpcwotICAgKiBubyBpbmZvcm1hdGlvbiByZWdhcmRpbmcgdGhlIGFyZ3VtZW50cyB0byB0aGUgZnVuY3Rpb24gY2FsbCBvcgotICAgKiB3aGV0aGVyIHRoZSBtZXRob2QgaW1wbGVtZW50aW5nIHRoZSBmdW5jdGlvbiBpcyBhIHN0YXRpYyBtZXRob2Qgb3IKLSAgICogYW4gaW5zdGFuY2UgbWV0aG9kLgotICAgKiBAcGFyYW0gZnVuY3Rpb24gbmFtZSBvZiB0aGUgZnVuY3Rpb24gYmVpbmcgdGVzdGVkCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBpdHMga25vd24sIGZhbHNlIGlmIG5vdC4KLSAgICovCi0KLSAgcHVibGljIGJvb2xlYW4gaXNGdW5jdGlvbkF2YWlsYWJsZShTdHJpbmcgZnVuY3Rpb24pIAotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIGZ1bGxOYW1lID0gbV9jbGFzc05hbWUgKyBmdW5jdGlvbjsKLSAgICAgIGludCBsYXN0RG90ID0gZnVsbE5hbWUubGFzdEluZGV4T2YoIi4iKTsKLSAgICAgIGlmIChsYXN0RG90ID49IDApCi0gICAgICB7Ci0gICAgICAgIENsYXNzIG15Q2xhc3MgPSBnZXRDbGFzc0Zvck5hbWUoZnVsbE5hbWUuc3Vic3RyaW5nKDAsIGxhc3REb3QpKTsKLSAgICAgICAgTWV0aG9kW10gbWV0aG9kcyA9IG15Q2xhc3MuZ2V0TWV0aG9kcygpOwotICAgICAgICBpbnQgbk1ldGhvZHMgPSBtZXRob2RzLmxlbmd0aDsKLSAgICAgICAgZnVuY3Rpb24gPSBmdWxsTmFtZS5zdWJzdHJpbmcobGFzdERvdCArIDEpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5NZXRob2RzOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobWV0aG9kc1tpXS5nZXROYW1lKCkuZXF1YWxzKGZ1bmN0aW9uKSkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHt9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBUZXN0cyB3aGV0aGVyIGEgY2VydGFpbiBlbGVtZW50IG5hbWUgaXMga25vd24gd2l0aGluIHRoaXMgbmFtZXNwYWNlLgotICAgKiBMb29rcyBmb3IgYSBtZXRob2Qgd2l0aCB0aGUgYXBwcm9wcmlhdGUgbmFtZSBhbmQgc2lnbmF0dXJlLgotICAgKiBUaGlzIG1ldGhvZCBleGFtaW5lcyBib3RoIHN0YXRpYyBhbmQgaW5zdGFuY2UgbWV0aG9kcy4KLSAgICogQHBhcmFtIGZ1bmN0aW9uIG5hbWUgb2YgdGhlIGZ1bmN0aW9uIGJlaW5nIHRlc3RlZAotICAgKiBAcmV0dXJuIHRydWUgaWYgaXRzIGtub3duLCBmYWxzZSBpZiBub3QuCi0gICAqLwotCi0gIHB1YmxpYyBib29sZWFuIGlzRWxlbWVudEF2YWlsYWJsZShTdHJpbmcgZWxlbWVudCkgCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBTdHJpbmcgZnVsbE5hbWUgPSBtX2NsYXNzTmFtZSArIGVsZW1lbnQ7Ci0gICAgICBpbnQgbGFzdERvdCA9IGZ1bGxOYW1lLmxhc3RJbmRleE9mKCIuIik7Ci0gICAgICBpZiAobGFzdERvdCA+PSAwKQotICAgICAgewotICAgICAgICBDbGFzcyBteUNsYXNzID0gZ2V0Q2xhc3NGb3JOYW1lKGZ1bGxOYW1lLnN1YnN0cmluZygwLCBsYXN0RG90KSk7Ci0gICAgICAgIE1ldGhvZFtdIG1ldGhvZHMgPSBteUNsYXNzLmdldE1ldGhvZHMoKTsKLSAgICAgICAgaW50IG5NZXRob2RzID0gbWV0aG9kcy5sZW5ndGg7Ci0gICAgICAgIGVsZW1lbnQgPSBmdWxsTmFtZS5zdWJzdHJpbmcobGFzdERvdCArIDEpOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5NZXRob2RzOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobWV0aG9kc1tpXS5nZXROYW1lKCkuZXF1YWxzKGVsZW1lbnQpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIENsYXNzW10gcGFyYW1UeXBlcyA9IG1ldGhvZHNbaV0uZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLSAgICAgICAgICAgIGlmICggKHBhcmFtVHlwZXMubGVuZ3RoID09IDIpCi0gICAgICAgICAgICAgICYmIHBhcmFtVHlwZXNbMF0uaXNBc3NpZ25hYmxlRnJvbSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuWFNMUHJvY2Vzc29yQ29udGV4dC5jbGFzcykKLSAgICAgICAgICAgICAgJiYgcGFyYW1UeXBlc1sxXS5pc0Fzc2lnbmFibGVGcm9tKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUV4dGVuc2lvbkNhbGwuY2xhc3MpICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHt9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGEgY2FsbCB0byBhIGZ1bmN0aW9uIGluIHRoZSBwYWNrYWdlIGphdmEgbmFtZXNwYWNlLgotICAgKiBUaGVyZSBhcmUgdGhyZWUgcG9zc2libGUgdHlwZXMgb2YgY2FsbHM6Ci0gICAqIDxwcmU+Ci0gICAqICAgQ29uc3RydWN0b3I6Ci0gICAqICAgICBwYWNrYWdlbnM6Y2xhc3MubmFtZS5uZXcoYXJnMSwgYXJnMiwgLi4uKQotICAgKgotICAgKiAgIFN0YXRpYyBtZXRob2Q6Ci0gICAqICAgICBwYWNrYWdlbnM6Y2xhc3MubmFtZS5tZXRob2QoYXJnMSwgYXJnMiwgLi4uKQotICAgKgotICAgKiAgIEluc3RhbmNlIG1ldGhvZDoKLSAgICogICAgIHBhY2thZ2VuczptZXRob2Qob2JqLCBhcmcxLCBhcmcyLCAuLi4pCi0gICAqIDwvcHJlPgotICAgKiBXZSB1c2UgdGhlIGZvbGxvd2luZyBydWxlcyB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgY2FsbCBtYWRlOgotICAgKiA8b2wgdHlwZT0iMSI+Ci0gICAqIDxsaT5JZiB0aGUgZnVuY3Rpb24gbmFtZSBlbmRzIHdpdGggYSAiLm5ldyIsIGNhbGwgdGhlIGJlc3QgY29uc3RydWN0b3IgZm9yCi0gICAqICAgICBjbGFzcyB3aG9zZSBuYW1lIGlzIGZvcm1lZCBieSBjb25jYXRlbmF0aW5nIHRoZSB2YWx1ZSBzcGVjaWZpZWQgb24KLSAgICogICAgIHRoZSBuYW1lc3BhY2Ugd2l0aCB0aGUgdmFsdWUgc3BlY2lmaWVkIGluIHRoZSBmdW5jdGlvbiBpbnZvY2F0aW9uCi0gICAqICAgICBiZWZvcmUgIi5uZXciLjwvbGk+Ci0gICAqIDxsaT5JZiB0aGUgZnVuY3Rpb24gbmFtZSBjb250YWlucyBhIHBlcmlvZCwgY2FsbCB0aGUgYmVzdCBzdGF0aWMgbWV0aG9kICJtZXRob2QiCi0gICAqICAgICBpbiB0aGUgY2xhc3Mgd2hvc2UgbmFtZSBpcyBmb3JtZWQgYnkgY29uY2F0ZW5hdGluZyB0aGUgdmFsdWUgc3BlY2lmaWVkIG9uCi0gICAqICAgICB0aGUgbmFtZXNwYWNlIHdpdGggdGhlIHZhbHVlIHNwZWNpZmllZCBpbiB0aGUgZnVuY3Rpb24gaW52b2NhdGlvbi48L2xpPgotICAgKiA8bGk+T3RoZXJ3aXNlLCBjYWxsIHRoZSBiZXN0IGluc3RhbmNlIG1ldGhvZCAibWV0aG9kIgotICAgKiAgICAgaW4gdGhlIGNsYXNzIHdob3NlIG5hbWUgaXMgZm9ybWVkIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIHZhbHVlIHNwZWNpZmllZCBvbgotICAgKiAgICAgdGhlIG5hbWVzcGFjZSB3aXRoIHRoZSB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGZ1bmN0aW9uIGludm9jYXRpb24uCi0gICAqICAgICBOb3RlIHRoYXQgYSBzdGF0aWMgbWV0aG9kIG9mIHRoZSBzYW1lCi0gICAqICAgICBuYW1lIHdpbGwgPGk+bm90PC9pPiBiZSBjYWxsZWQgaW4gdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24uICBUaGlzCi0gICAqICAgICBtb2R1bGUgZG9lcyBub3QgdmVyaWZ5IHRoYXQgdGhlIG9iaiBhcmd1bWVudCBpcyBhIG1lbWJlciBvZiB0aGUKLSAgICogICAgIHBhY2thZ2UgbmFtZXNwYWNlLjwvbGk+Ci0gICAqIDwvb2w+Ci0gICAqCi0gICAqIEBwYXJhbSBmdW5jTmFtZSBGdW5jdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gYXJncyAgICAgVGhlIGFyZ3VtZW50cyBvZiB0aGUgZnVuY3Rpb24gY2FsbC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBmdW5jdGlvbiBldmFsdWF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uICAgICAgICAgIGlmIHBhcnNpbmcgdHJvdWJsZQotICAgKi8KLQotICBwdWJsaWMgT2JqZWN0IGNhbGxGdW5jdGlvbiAoU3RyaW5nIGZ1bmNOYW1lLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3RvciBhcmdzLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdCBtZXRob2RLZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHByZXNzaW9uQ29udGV4dCBleHByQ29udGV4dCkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gCi0gIHsKLQotICAgIFN0cmluZyBjbGFzc05hbWU7Ci0gICAgU3RyaW5nIG1ldGhvZE5hbWU7Ci0gICAgQ2xhc3MgIGNsYXNzT2JqOwotICAgIE9iamVjdCB0YXJnZXRPYmplY3Q7Ci0gICAgaW50IGxhc3REb3QgPSBmdW5jTmFtZS5sYXN0SW5kZXhPZigiLiIpOwotICAgIE9iamVjdFtdIG1ldGhvZEFyZ3M7Ci0gICAgT2JqZWN0W11bXSBjb252ZXJ0ZWRBcmdzOwotICAgIENsYXNzW10gcGFyYW1UeXBlczsKLQotICAgIHRyeQotICAgIHsKLQotICAgICAgaWYgKGZ1bmNOYW1lLmVuZHNXaXRoKCIubmV3IikpIHsgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIGNvbnN0cnVjdG9yIGNhbGwKLQotICAgICAgICBtZXRob2RBcmdzID0gbmV3IE9iamVjdFthcmdzLnNpemUoKV07Ci0gICAgICAgIGNvbnZlcnRlZEFyZ3MgPSBuZXcgT2JqZWN0WzFdW107Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kQXJncy5sZW5ndGg7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIG1ldGhvZEFyZ3NbaV0gPSBhcmdzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgfQotICAgICAgICBDb25zdHJ1Y3RvciBjID0gKENvbnN0cnVjdG9yKSBnZXRGcm9tQ2FjaGUobWV0aG9kS2V5LCBudWxsLCBtZXRob2RBcmdzKTsKLSAgICAgICAgaWYgKGMgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBhcmFtVHlwZXMgPSBjLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICAgICAgICBNZXRob2RSZXNvbHZlci5jb252ZXJ0UGFyYW1zKG1ldGhvZEFyZ3MsIGNvbnZlcnRlZEFyZ3MsIHBhcmFtVHlwZXMsIGV4cHJDb250ZXh0KTsKLSAgICAgICAgICAgIHJldHVybiBjLm5ld0luc3RhbmNlKGNvbnZlcnRlZEFyZ3NbMF0pOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBNdXN0IG5vdCBoYXZlIGJlZW4gdGhlIHJpZ2h0IG9uZQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjbGFzc05hbWUgPSBtX2NsYXNzTmFtZSArIGZ1bmNOYW1lLnN1YnN0cmluZygwLCBsYXN0RG90KTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBjbGFzc09iaiA9IGdldENsYXNzRm9yTmFtZShjbGFzc05hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIAotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGMgPSBNZXRob2RSZXNvbHZlci5nZXRDb25zdHJ1Y3RvcihjbGFzc09iaiwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2RBcmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydGVkQXJncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJDb250ZXh0KTsKLSAgICAgICAgcHV0VG9DYWNoZShtZXRob2RLZXksIG51bGwsIG1ldGhvZEFyZ3MsIGMpOwotICAgICAgICByZXR1cm4gYy5uZXdJbnN0YW5jZShjb252ZXJ0ZWRBcmdzWzBdKTsKLSAgICAgIH0KLQotICAgICAgZWxzZSBpZiAoLTEgIT0gbGFzdERvdCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgc3RhdGljIG1ldGhvZCBjYWxsCi0KLSAgICAgICAgbWV0aG9kQXJncyA9IG5ldyBPYmplY3RbYXJncy5zaXplKCldOwotICAgICAgICBjb252ZXJ0ZWRBcmdzID0gbmV3IE9iamVjdFsxXVtdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZEFyZ3MubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBtZXRob2RBcmdzW2ldID0gYXJncy5lbGVtZW50QXQoaSk7Ci0gICAgICAgIH0KLSAgICAgICAgTWV0aG9kIG0gPSAoTWV0aG9kKSBnZXRGcm9tQ2FjaGUobWV0aG9kS2V5LCBudWxsLCBtZXRob2RBcmdzKTsKLSAgICAgICAgaWYgKG0gIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBhcmFtVHlwZXMgPSBtLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICAgICAgICBNZXRob2RSZXNvbHZlci5jb252ZXJ0UGFyYW1zKG1ldGhvZEFyZ3MsIGNvbnZlcnRlZEFyZ3MsIHBhcmFtVHlwZXMsIGV4cHJDb250ZXh0KTsKLSAgICAgICAgICAgIHJldHVybiBtLmludm9rZShudWxsLCBjb252ZXJ0ZWRBcmdzWzBdKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gTXVzdCBub3QgaGF2ZSBiZWVuIHRoZSByaWdodCBvbmUKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2xhc3NOYW1lID0gbV9jbGFzc05hbWUgKyBmdW5jTmFtZS5zdWJzdHJpbmcoMCwgbGFzdERvdCk7Ci0gICAgICAgIG1ldGhvZE5hbWUgPSBmdW5jTmFtZS5zdWJzdHJpbmcobGFzdERvdCArIDEpOwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGNsYXNzT2JqID0gZ2V0Q2xhc3NGb3JOYW1lKGNsYXNzTmFtZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICAgICAgbSA9IE1ldGhvZFJlc29sdmVyLmdldE1ldGhvZChjbGFzc09iaiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZEFyZ3MsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZEFyZ3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwckNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kUmVzb2x2ZXIuU1RBVElDX09OTFkpOwotICAgICAgICBwdXRUb0NhY2hlKG1ldGhvZEtleSwgbnVsbCwgbWV0aG9kQXJncywgbSk7Ci0gICAgICAgIHJldHVybiBtLmludm9rZShudWxsLCBjb252ZXJ0ZWRBcmdzWzBdKTsKLSAgICAgIH0KLQotICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgaW5zdGFuY2UgbWV0aG9kIGNhbGwKLQotICAgICAgICBpZiAoYXJncy5zaXplKCkgPCAxKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lOU1RBTkNFX01USERfQ0FMTF9SRVFVSVJFUywgbmV3IE9iamVjdFtde2Z1bmNOYW1lIH0pKTsgLy8iSW5zdGFuY2UgbWV0aG9kIGNhbGwgdG8gbWV0aG9kICIgKyBmdW5jTmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICIgcmVxdWlyZXMgYW4gT2JqZWN0IGluc3RhbmNlIGFzIGZpcnN0IGFyZ3VtZW50Iik7Ci0gICAgICAgIH0KLSAgICAgICAgdGFyZ2V0T2JqZWN0ID0gYXJncy5lbGVtZW50QXQoMCk7Ci0gICAgICAgIGlmICh0YXJnZXRPYmplY3QgaW5zdGFuY2VvZiBYT2JqZWN0KSAgICAgICAgICAvLyBOZXh0IGxldmVsIGRvd24gZm9yIFhPYmplY3RzCi0gICAgICAgICAgdGFyZ2V0T2JqZWN0ID0gKChYT2JqZWN0KSB0YXJnZXRPYmplY3QpLm9iamVjdCgpOwotICAgICAgICBtZXRob2RBcmdzID0gbmV3IE9iamVjdFthcmdzLnNpemUoKSAtIDFdOwotICAgICAgICBjb252ZXJ0ZWRBcmdzID0gbmV3IE9iamVjdFsxXVtdOwotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZEFyZ3MubGVuZ3RoOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBtZXRob2RBcmdzW2ldID0gYXJncy5lbGVtZW50QXQoaSsxKTsKLSAgICAgICAgfQotICAgICAgICBNZXRob2QgbSA9IChNZXRob2QpIGdldEZyb21DYWNoZShtZXRob2RLZXksIHRhcmdldE9iamVjdCwgbWV0aG9kQXJncyk7Ci0gICAgICAgIGlmIChtICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwYXJhbVR5cGVzID0gbS5nZXRQYXJhbWV0ZXJUeXBlcygpOwotICAgICAgICAgICAgTWV0aG9kUmVzb2x2ZXIuY29udmVydFBhcmFtcyhtZXRob2RBcmdzLCBjb252ZXJ0ZWRBcmdzLCBwYXJhbVR5cGVzLCBleHByQ29udGV4dCk7Ci0gICAgICAgICAgICByZXR1cm4gbS5pbnZva2UodGFyZ2V0T2JqZWN0LCBjb252ZXJ0ZWRBcmdzWzBdKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gTXVzdCBub3QgaGF2ZSBiZWVuIHRoZSByaWdodCBvbmUKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgY2xhc3NPYmogPSB0YXJnZXRPYmplY3QuZ2V0Q2xhc3MoKTsKLSAgICAgICAgbSA9IE1ldGhvZFJlc29sdmVyLmdldE1ldGhvZChjbGFzc09iaiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2RBcmdzLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWRBcmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFJlc29sdmVyLklOU1RBTkNFX09OTFkpOwotICAgICAgICBwdXRUb0NhY2hlKG1ldGhvZEtleSwgdGFyZ2V0T2JqZWN0LCBtZXRob2RBcmdzLCBtKTsKLSAgICAgICAgcmV0dXJuIG0uaW52b2tlKHRhcmdldE9iamVjdCwgY29udmVydGVkQXJnc1swXSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZSkKLSAgICB7Ci0gICAgICBUaHJvd2FibGUgcmVhbEV4Y2VwdGlvbiA9IGl0ZS5nZXRUYXJnZXRFeGNlcHRpb24oKTsKLSAgICAgIGlmIChyZWFsRXhjZXB0aW9uIGluc3RhbmNlb2YgRXhjZXB0aW9uKQotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oKEV4Y2VwdGlvbikgcmVhbEV4Y2VwdGlvbik7Ci0gICAgICBlbHNlCi0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihpdGUpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGEgY2FsbCB0byB0aGlzIGV4dGVuc2lvbiBuYW1lc3BhY2UgdmlhIGFuIGVsZW1lbnQuIEFzIGEgc2lkZQotICAgKiBlZmZlY3QsIHRoZSByZXN1bHRzIGFyZSBzZW50IHRvIHRoZSBUcmFuc2Zvcm1lckltcGwncyByZXN1bHQgdHJlZS4KLSAgICogRm9yIHRoaXMgbmFtZXNwYWNlLCBvbmx5IHN0YXRpYyBlbGVtZW50IG1ldGhvZHMgYXJlIGN1cnJlbnRseSBzdXBwb3J0ZWQuCi0gICAqIElmIGluc3RhbmNlIG1ldGhvZHMgYXJlIG5lZWRlZCwgcGxlYXNlIGxldCB1cyBrbm93IHlvdXIgcmVxdWlyZW1lbnRzLgotICAgKiBAcGFyYW0gbG9jYWxQYXJ0ICAgICAgRWxlbWVudCBuYW1lJ3MgbG9jYWwgcGFydC4KLSAgICogQHBhcmFtIGVsZW1lbnQgICAgICAgIFRoZSBleHRlbnNpb24gZWxlbWVudCBiZWluZyBwcm9jZXNzZWQuCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciAgICAgIEhhbmRsZSB0byBUcmFuc2Zvcm1lckltcGwuCi0gICAqIEBwYXJhbSBzdHlsZXNoZWV0VHJlZSBUaGUgY29tcGlsZWQgc3R5bGVzaGVldCB0cmVlLgotICAgKiBAcGFyYW0gbW9kZSAgICAgICAgICAgVGhlIGN1cnJlbnQgbW9kZS4KLSAgICogQHBhcmFtIHNvdXJjZVRyZWUgICAgIFRoZSByb290IG9mIHRoZSBzb3VyY2UgdHJlZSAoYnV0IGRvbid0IGFzc3VtZQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgaXQncyBhIERvY3VtZW50KS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgICAgIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICogQHBhcmFtIG1vZGUgICAgICAgICAgIFRoZSBjdXJyZW50IG1vZGUuCi0gICAqIEBwYXJhbSBtZXRob2RLZXkgICAgICBBIGtleSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBlbGVtZW50IGNhbGwuCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gICAgICAgICAgIGlmIGxvYWRpbmcgdHJvdWJsZQotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uICAgICAgICAgIGlmIHBhcnNpbmcgdHJvdWJsZQotICAgKi8KLQotICBwdWJsaWMgdm9pZCBwcm9jZXNzRWxlbWVudCAoU3RyaW5nIGxvY2FsUGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldFRyZWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgbWV0aG9kS2V5KQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KLSAgewotICAgIE9iamVjdCByZXN1bHQgPSBudWxsOwotICAgIENsYXNzIGNsYXNzT2JqOwotCi0gICAgTWV0aG9kIG0gPSAoTWV0aG9kKSBnZXRGcm9tQ2FjaGUobWV0aG9kS2V5LCBudWxsLCBudWxsKTsKLSAgICBpZiAobnVsbCA9PSBtKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBTdHJpbmcgZnVsbE5hbWUgPSBtX2NsYXNzTmFtZSArIGxvY2FsUGFydDsKLSAgICAgICAgaW50IGxhc3REb3QgPSBmdWxsTmFtZS5sYXN0SW5kZXhPZigiLiIpOwotICAgICAgICBpZiAobGFzdERvdCA8IDApCi0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lOVkFMSURfRUxFTUVOVF9OQU1FLCBuZXcgT2JqZWN0W117ZnVsbE5hbWUgfSkpOyAvLyJJbnZhbGlkIGVsZW1lbnQgbmFtZSBzcGVjaWZpZWQgIiArIGZ1bGxOYW1lKTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBjbGFzc09iaiA9IGdldENsYXNzRm9yTmFtZShmdWxsTmFtZS5zdWJzdHJpbmcoMCwgbGFzdERvdCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIAotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICAgIGxvY2FsUGFydCA9IGZ1bGxOYW1lLnN1YnN0cmluZyhsYXN0RG90ICsgMSk7Ci0gICAgICAgIG0gPSBNZXRob2RSZXNvbHZlci5nZXRFbGVtZW50TWV0aG9kKGNsYXNzT2JqLCBsb2NhbFBhcnQpOwotICAgICAgICBpZiAoIU1vZGlmaWVyLmlzU3RhdGljKG0uZ2V0TW9kaWZpZXJzKCkpKQotICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQywgbmV3IE9iamVjdFtde2Z1bGxOYW1lIH0pKTsgLy8iRWxlbWVudCBuYW1lIG1ldGhvZCBtdXN0IGJlIHN0YXRpYyAiICsgZnVsbE5hbWUpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICAvLyBlLnByaW50U3RhY2tUcmFjZSAoKTsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uIChlKTsKLSAgICAgIH0KLSAgICAgIHB1dFRvQ2FjaGUobWV0aG9kS2V5LCBudWxsLCBudWxsLCBtKTsKLSAgICB9Ci0KLSAgICBYU0xQcm9jZXNzb3JDb250ZXh0IHhwYyA9IG5ldyBYU0xQcm9jZXNzb3JDb250ZXh0KHRyYW5zZm9ybWVyLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlc2hlZXRUcmVlKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG0uaW52b2tlKG51bGwsIG5ldyBPYmplY3RbXSB7eHBjLCBlbGVtZW50fSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICAvLyBlLnByaW50U3RhY2tUcmFjZSAoKTsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiAoZSk7Ci0gICAgfQotCi0gICAgaWYgKHJlc3VsdCAhPSBudWxsKQotICAgIHsKLSAgICAgIHhwYy5vdXRwdXRUb1Jlc3VsdFRyZWUgKHN0eWxlc2hlZXRUcmVlLCByZXN1bHQpOwotICAgIH0KLSAKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbnNUYWJsZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9FeHRlbnNpb25zVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWQ0NmE4OS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4dGVuc2lvbnNUYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzI4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVsbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgaG9sZGluZyBhIHRhYmxlIHJlZ2lzdGVyZWQgZXh0ZW5zaW9uIG5hbWVzcGFjZSBoYW5kbGVycwotICovCi1wdWJsaWMgY2xhc3MgRXh0ZW5zaW9uc1RhYmxlCi17Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBUYWJsZSBvZiBleHRlbnNpb25zIHRoYXQgbWF5IGJlIGNhbGxlZCBmcm9tIHRoZSBleHByZXNzaW9uIGxhbmd1YWdlCi0gICAqIHZpYSB0aGUgY2FsbChuYW1lLCAuLi4pIGZ1bmN0aW9uLiAgT2JqZWN0cyBhcmUga2V5ZWQgb24gdGhlIGNhbGwKLSAgICogbmFtZS4KLSAgICovCi0gIHB1YmxpYyBIYXNodGFibGUgbV9leHRlbnNpb25GdW5jdGlvbk5hbWVzcGFjZXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBQcmltZXMgdGhlIG5ldyBFeHRlbnNpb25zVGFibGUgb2JqZWN0IHdpdGggYnVpbHQtaW4gbmFtZXNwYWNlcy4KLSAgICovCi0gIHB1YmxpYyBFeHRlbnNpb25zVGFibGUoKQotICB7Ci0KLSAgICAvLyByZWdpc3RlciB0aGUgamF2YSBuYW1lc3BhY2UgYXMgYmVpbmcgaW1wbGVtZW50ZWQgYnkgdGhlIAotICAgIC8vIHhzbHQtamF2YWNsYXNzIGVuZ2luZS4gTm90ZSB0aGF0IHRoZXJlJ3Mgbm8gcmVhbCBjb2RlCi0gICAgLy8gcGVyIHNlIGZvciB0aGlzIGV4dGVuc2lvbiBhcyB0aGUgZnVuY3Rpb25zIGNhcnJ5IHRoZSAKLSAgICAvLyBvYmplY3Qgb24gd2hpY2ggdG8gY2FsbCBldGMuIGFuZCBhbGwgdGhlIGxvZ2ljIG9mIGJyZWFraW5nCi0gICAgLy8gdGhhdCB1cCBpcyBpbiB0aGUgeHNsdC1qYXZhY2xhc3MgZW5naW5lLgotICAgIFN0cmluZyB1cmkgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQvamF2YSI7Ci0gICAgRXh0ZW5zaW9uSGFuZGxlciBmaCA9IG5ldyBFeHRlbnNpb25IYW5kbGVySmF2YVBhY2thZ2UodXJpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0LWphdmFjbGFzcyIsICIiKTsKLQotICAgIGFkZEV4dGVuc2lvbk5hbWVzcGFjZSh1cmksIGZoKTsKLQotICAgIHVyaSA9ICJodHRwOi8veHNsLmxvdHVzLmNvbS9qYXZhIjsKLQotICAgIGFkZEV4dGVuc2lvbk5hbWVzcGFjZSh1cmksIGZoKTsKLQotICAgIHVyaSA9ICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4iOwotICAgIGZoID0gbmV3IEV4dGVuc2lvbkhhbmRsZXJKYXZhQ2xhc3ModXJpLCAiamF2YWNsYXNzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcmcuYXBhY2hlLnhhbGFuLmxpYi5FeHRlbnNpb25zIik7Ci0KLSAgICBhZGRFeHRlbnNpb25OYW1lc3BhY2UodXJpLCBmaCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIEV4dGVuc2lvbkhhbmRsZXIgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUKLSAgICogZ2l2ZW4gbmFtZXNwYWNlLgotICAgKiBAcGFyYW0gZXh0bnMgQSB2YWxpZCBleHRlbnNpb24gbmFtZXNwYWNlLgotICAgKgotICAgKiBAcmV0dXJuIEV4dGVuc2lvbkhhbmRsZXIgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUKLSAgICogZ2l2ZW4gbmFtZXNwYWNlLgotICAgKi8KLSAgcHVibGljIEV4dGVuc2lvbkhhbmRsZXIgZ2V0KFN0cmluZyBleHRucykKLSAgewotICAgIHJldHVybiAoRXh0ZW5zaW9uSGFuZGxlcikgbV9leHRlbnNpb25GdW5jdGlvbk5hbWVzcGFjZXMuZ2V0KGV4dG5zKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogUmVnaXN0ZXIgYW4gZXh0ZW5zaW9uIG5hbWVzcGFjZSBoYW5kbGVyLiBUaGlzIGhhbmRsZXIgcHJvdmlkZXMKLSAgICogZnVuY3Rpb25zIGZvciB0ZXN0aW5nIHdoZXRoZXIgYSBmdW5jdGlvbiBpcyBrbm93biB3aXRoaW4gdGhlCi0gICAqIG5hbWVzcGFjZSBhbmQgYWxzbyBmb3IgaW52b2tpbmcgdGhlIGZ1bmN0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIHVyaSB0aGUgVVJJIGZvciB0aGUgZXh0ZW5zaW9uLgotICAgKiBAcGFyYW0gZXh0TlMgdGhlIGV4dGVuc2lvbiBoYW5kbGVyLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkRXh0ZW5zaW9uTmFtZXNwYWNlKFN0cmluZyB1cmksIEV4dGVuc2lvbkhhbmRsZXIgZXh0TlMpCi0gIHsKLSAgICBtX2V4dGVuc2lvbkZ1bmN0aW9uTmFtZXNwYWNlcy5wdXQodXJpLCBleHROUyk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24tYXZhaWxhYmxlKCkgZnVuY3Rpb24uCi0gICAqIEBwYXJhbSBucyAgICAgICB0aGUgVVJJIG9mIG5hbWVzcGFjZSBpbiB3aGljaCB0aGUgZnVuY3Rpb24gaXMgbmVlZGVkCi0gICAqIEBwYXJhbSBmdW5jTmFtZSB0aGUgZnVuY3Rpb24gbmFtZSBiZWluZyB0ZXN0ZWQKLSAgICoKLSAgICogQHJldHVybiB3aGV0aGVyIHRoZSBnaXZlbiBmdW5jdGlvbiBpcyBhdmFpbGFibGUgb3Igbm90LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGZ1bmN0aW9uQXZhaWxhYmxlKFN0cmluZyBucywgU3RyaW5nIGZ1bmNOYW1lKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGJvb2xlYW4gaXNBdmFpbGFibGUgPSBmYWxzZTsKLQotICAgIGlmIChudWxsICE9IG5zKQotICAgIHsKLSAgICAgIEV4dGVuc2lvbkhhbmRsZXIgZXh0TlMgPQotICAgICAgICAoRXh0ZW5zaW9uSGFuZGxlcikgbV9leHRlbnNpb25GdW5jdGlvbk5hbWVzcGFjZXMuZ2V0KG5zKTsKLQotICAgICAgaWYgKGV4dE5TID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGV4dE5TID0gbWFrZUphdmFOYW1lc3BhY2UobnMpOwotCi0gICAgICAgIGFkZEV4dGVuc2lvbk5hbWVzcGFjZShucywgZXh0TlMpOwotICAgICAgfQotCi0gICAgICBpZiAoZXh0TlMgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgaXNBdmFpbGFibGUgPSBleHROUy5pc0Z1bmN0aW9uQXZhaWxhYmxlKGZ1bmNOYW1lKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBTeXN0ZW0uZXJyLnByaW50bG4gKCI+Pj4gZnVuY3Rpb25BdmFpbGFibGUgKG5zPSIgKyBucyArIAotICAgIC8vICAgICAgICAgICAgICAgICAgICAiLCBmdW5jPSIgKyBmdW5jTmFtZSArICIpID0gIiArIGlzQXZhaWxhYmxlKTsKLSAgICByZXR1cm4gaXNBdmFpbGFibGU7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZWxlbWVudC1hdmFpbGFibGUoKSBmdW5jdGlvbi4KLSAgICogQHBhcmFtIG5zICAgICAgIHRoZSBVUkkgb2YgbmFtZXNwYWNlIGluIHdoaWNoIHRoZSBmdW5jdGlvbiBpcyBuZWVkZWQKLSAgICogQHBhcmFtIGZ1bmNOYW1lIHRoZSBmdW5jdGlvbiBuYW1lIGJlaW5nIHRlc3RlZAotICAgKiBAcGFyYW0gZWxlbU5hbWUgbmFtZSBvZiBlbGVtZW50IGJlaW5nIHRlc3RlZAotICAgKgotICAgKiBAcmV0dXJuIHdoZXRoZXIgdGhlIGdpdmVuIGZ1bmN0aW9uIGlzIGF2YWlsYWJsZSBvciBub3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZWxlbWVudEF2YWlsYWJsZShTdHJpbmcgbnMsIFN0cmluZyBlbGVtTmFtZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBib29sZWFuIGlzQXZhaWxhYmxlID0gZmFsc2U7Ci0KLSAgICBpZiAobnVsbCAhPSBucykKLSAgICB7Ci0gICAgICBFeHRlbnNpb25IYW5kbGVyIGV4dE5TID0KLSAgICAgICAgKEV4dGVuc2lvbkhhbmRsZXIpIG1fZXh0ZW5zaW9uRnVuY3Rpb25OYW1lc3BhY2VzLmdldChucyk7Ci0KLSAgICAgIGlmIChleHROUyA9PSBudWxsKQotICAgICAgewotICAgICAgICBleHROUyA9IG1ha2VKYXZhTmFtZXNwYWNlKG5zKTsKLQotICAgICAgICBhZGRFeHRlbnNpb25OYW1lc3BhY2UobnMsIGV4dE5TKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGV4dE5TICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGlzQXZhaWxhYmxlID0gZXh0TlMuaXNFbGVtZW50QXZhaWxhYmxlKGVsZW1OYW1lKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBTeXN0ZW0uZXJyLnByaW50bG4gKCI+Pj4gZWxlbWVudEF2YWlsYWJsZSAobnM9IiArIG5zICsgCi0gICAgLy8gICAgICAgICAgICAgICAgICAgICIsIGVsZW09IiArIGVsZW1OYW1lICsgIikgPSAiICsgaXNBdmFpbGFibGUpOwotICAgIHJldHVybiBpc0F2YWlsYWJsZTsKLSAgfQotCi0gIC8qKgotICAgKiBIYW5kbGUgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKiBAcGFyYW0gbnMgICAgICAgIHRoZSBVUkkgb2YgbmFtZXNwYWNlIGluIHdoaWNoIHRoZSBmdW5jdGlvbiBpcyBuZWVkZWQKLSAgICogQHBhcmFtIGZ1bmNOYW1lICB0aGUgZnVuY3Rpb24gbmFtZSBiZWluZyBjYWxsZWQKLSAgICogQHBhcmFtIGFyZ1ZlYyAgICBhcmd1bWVudHMgdG8gdGhlIGZ1bmN0aW9uIGluIGEgdmVjdG9yCi0gICAqIEBwYXJhbSBtZXRob2RLZXkgYSB1bmlxdWUga2V5IGlkZW50aWZ5aW5nIHRoaXMgZnVuY3Rpb24gaW5zdGFuY2UgaW4gdGhlCi0gICAqICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldAotICAgKiBAcGFyYW0gZXhwckNvbnRleHQgYSBjb250ZXh0IHdoaWNoIG1heSBiZSBwYXNzZWQgdG8gYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uCi0gICAqICAgICAgICAgICAgICAgICAgYW5kIHByb3ZpZGVzIGNhbGxiYWNrIGZ1bmN0aW9ucyB0byBhY2Nlc3MgdmFyaW91cwotICAgKiAgICAgICAgICAgICAgICAgIGFyZWFzIGluIHRoZSBlbnZpcm9ubWVudAotICAgKgotICAgKiBAcmV0dXJuIHJlc3VsdCBvZiBleGVjdXRpbmcgdGhlIGZ1bmN0aW9uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBleHRGdW5jdGlvbigKLSAgICAgICAgICBTdHJpbmcgbnMsIFN0cmluZyBmdW5jTmFtZSwgVmVjdG9yIGFyZ1ZlYywgT2JqZWN0IG1ldGhvZEtleSwgCi0gICAgICAgICAgRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBPYmplY3QgcmVzdWx0ID0gbnVsbDsKLQotICAgIGlmIChudWxsICE9IG5zKQotICAgIHsKLSAgICAgIEV4dGVuc2lvbkhhbmRsZXIgZXh0TlMgPQotICAgICAgICAoRXh0ZW5zaW9uSGFuZGxlcikgbV9leHRlbnNpb25GdW5jdGlvbk5hbWVzcGFjZXMuZ2V0KG5zKTsKLQotICAgICAgLy8gSWYgdGhlIGhhbmRsZXIgZm9yIHRoaXMgZXh0ZW5zaW9uIFVSSSBpcyBub3QgZm91bmQgdHJ5IHRvIGF1dG8gZGVjbGFyZSAKLSAgICAgIC8vIHRoaXMgZXh0ZW5zaW9uIG5hbWVzcGFjZToKLSAgICAgIGlmIChudWxsID09IGV4dE5TKQotICAgICAgewotICAgICAgICBleHROUyA9IG1ha2VKYXZhTmFtZXNwYWNlKG5zKTsKLQotICAgICAgICBhZGRFeHRlbnNpb25OYW1lc3BhY2UobnMsIGV4dE5TKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG51bGwgIT0gZXh0TlMpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgcmVzdWx0ID0gZXh0TlMuY2FsbEZ1bmN0aW9uKGZ1bmNOYW1lLCBhcmdWZWMsIG1ldGhvZEtleSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwckNvbnRleHQpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBlOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBYUGF0aFByb2Nlc3NvckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOLCBuZXcgT2JqZWN0W117bnMsIGZ1bmNOYW1lIH0pKTsgLy8iRXh0ZW5zaW9uIGZ1bmN0aW9uICciICsgbnMgKyAiOiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKyBmdW5jTmFtZSArICInIGlzIHVua25vd24iKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci0KLSAgLyoqCi0gICAqIERlY2xhcmUgdGhlIGFwcHJvcHJpYXRlIGphdmEgZXh0ZW5zaW9uIGhhbmRsZXIuCi0gICAqIEBwYXJhbSBucyAgICAgICAgdGhlIFVSSSBvZiBuYW1lc3BhY2UgaW4gd2hpY2ggdGhlIGZ1bmN0aW9uIGlzIG5lZWRlZAotICAgKiBAcmV0dXJuICAgICAgICAgIGFuIEV4dGVuc2lvbkhhbmRsZXIgZm9yIHRoaXMgbmFtZXNwYWNlLCBvciBudWxsIGlmIAotICAgKiAgICAgICAgICAgICAgICAgIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRXh0ZW5zaW9uSGFuZGxlciBtYWtlSmF2YU5hbWVzcGFjZShTdHJpbmcgbnMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwgPT0gbnMgfHwgbnMudHJpbSgpLmxlbmd0aCgpID09IDApIC8vIGRlZmVuc2l2ZS4gSSBkb24ndCB0aGluayBpdCdzIG5lZWRlZC4gIC1zYgotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAvLyBGaXJzdCwgcHJlcGFyZSB0aGUgbmFtZSBvZiB0aGUgYWN0dWFsIGNsYXNzIG9yIHBhY2thZ2UuICBXZSBzdHJpcAotICAgIC8vIG91dCBhbnkgbGVhZGluZyAiY2xhc3M6Ii4gIE5leHQsIHdlIHNlZSBpZiB0aGVyZSBpcyBhIC8uICBJZiBzbywKLSAgICAvLyBvbmx5IGxvb2sgYXQgYW55dGhpbmcgdG8gdGhlIHJpZ2h0IG9mIHRoZSByaWdodG1vc3QgLy4KLSAgICAvLyBJbiB0aGUgZG9jdW1lbnRhdGlvbiwgd2Ugc3RhdGUgdGhhdCBhbnkgY2xhc3NlcyBvciBwYWNrYWdlcwotICAgIC8vIGRlY2xhcmVkIHVzaW5nIHRoaXMgdGVjaG5pcXVlIG11c3Qgc3RhcnQgd2l0aCB4YWxhbjovLy4gIEhvd2V2ZXIsCi0gICAgLy8gaW4gdGhpcyB2ZXJzaW9uLCB3ZSBkb24ndCBlbmZvcmNlIHRoYXQuCi0gICAgU3RyaW5nIGNsYXNzTmFtZSA9IG5zOwotCi0gICAgaWYgKGNsYXNzTmFtZS5zdGFydHNXaXRoKCJjbGFzczoiKSkKLSAgICB7Ci0gICAgICBjbGFzc05hbWUgPSBjbGFzc05hbWUuc3Vic3RyaW5nKDYpOwotICAgIH0KLQotICAgIGludCBsYXN0U2xhc2ggPSBjbGFzc05hbWUubGFzdEluZGV4T2YoIi8iKTsKLQotICAgIGlmICgtMSAhPSBsYXN0U2xhc2gpCi0gICAgICBjbGFzc05hbWUgPSBjbGFzc05hbWUuc3Vic3RyaW5nKGxhc3RTbGFzaCArIDEpOwotICAgICAgCi0gICAgLy8gVGhlIGNsYXNzTmFtZSBjYW4gYmUgbnVsbCBoZXJlLCBhbmQgY2FuIGNhdXNlIGFuIGVycm9yIGluIGdldENsYXNzRm9yTmFtZQotICAgIC8vIGluIEpESyAxLjguCi0gICAgaWYobnVsbCA9PSBjbGFzc05hbWUgfHwgY2xhc3NOYW1lLnRyaW0oKS5sZW5ndGgoKSA9PSAwKSAKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgRXh0ZW5zaW9uSGFuZGxlci5nZXRDbGFzc0Zvck5hbWUoY2xhc3NOYW1lKTsKLQotICAgICAgcmV0dXJuIG5ldyBFeHRlbnNpb25IYW5kbGVySmF2YUNsYXNzKG5zLCAiamF2YWNsYXNzIiwgY2xhc3NOYW1lKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IEV4dGVuc2lvbkhhbmRsZXJKYXZhUGFja2FnZShucywgImphdmFwYWNrYWdlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSArICIuIik7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL01ldGhvZFJlc29sdmVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL01ldGhvZFJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA0MzI4MzIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9NZXRob2RSZXNvbHZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Ob2RlUHJveHk7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIFV0aWxpdHkgY2xhc3MgdG8gaGVscCByZXNvbHZlIG1ldGhvZCBvdmVybG9hZGluZyB3aXRoIFhhbGFuIFhTTFQgCi0gKiBhcmd1bWVudCB0eXBlcy4KLSAqLwotcHVibGljIGNsYXNzIE1ldGhvZFJlc29sdmVyCi17Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmllcyBhIHNlYXJjaCBmb3Igc3RhdGljIG1ldGhvZHMgb25seS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUQVRJQ19PTkxZICAgICAgICAgPSAxOwotCi0gIC8qKgotICAgKiBTcGVjaWZpZXMgYSBzZWFyY2ggZm9yIGluc3RhbmNlIG1ldGhvZHMgb25seS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOU1RBTkNFX09OTFkgICAgICAgPSAyOwotCi0gIC8qKgotICAgKiBTcGVjaWZpZXMgYSBzZWFyY2ggZm9yIGJvdGggc3RhdGljIGFuZCBpbnN0YW5jZSBtZXRob2RzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBVElDX0FORF9JTlNUQU5DRSA9IDM7Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmllcyBhIER5bmFtaWMgbWV0aG9kIHNlYXJjaC4gIElmIHRoZSBtZXRob2QgYmVpbmcKLSAgICogZXZhbHVhdGVkIGlzIGEgc3RhdGljIG1ldGhvZCwgYWxsIGFyZ3VtZW50cyBhcmUgdXNlZC4KLSAgICogT3RoZXJ3aXNlLCBpdCBpcyBhbiBpbnN0YW5jZSBtZXRob2QgYW5kIG9ubHkgYXJndW1lbnRzCi0gICAqIGJlZ2lubmluZyB3aXRoIHRoZSBzZWNvbmQgYXJndW1lbnQgYXJlIHVzZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEWU5BTUlDICAgICAgICAgICAgID0gNDsKLQotICAvKioKLSAgICogR2l2ZW4gYSBjbGFzcywgZmlndXJlIG91dCB0aGUgcmVzb2x1dGlvbiBvZiAKLSAgICogdGhlIEphdmEgQ29uc3RydWN0b3IgZnJvbSB0aGUgWFNMVCBhcmd1bWVudCB0eXBlcywgYW5kIHBlcmZvcm0gdGhlIAotICAgKiBjb252ZXJzaW9uIG9mIHRoZSBhcmd1bWVudHMuCi0gICAqIEBwYXJhbSBjbGFzc09iaiB0aGUgQ2xhc3Mgb2YgdGhlIG9iamVjdCB0byBiZSBjb25zdHJ1Y3RlZC4KLSAgICogQHBhcmFtIGFyZ3NJbiBBbiBhcnJheSBvZiBYU0xUL1hQYXRoIGFyZ3VtZW50cy4KLSAgICogQHBhcmFtIGFyZ3NPdXQgQW4gYXJyYXkgb2YgdGhlIGV4YWN0IHNpemUgYXMgYXJnc0luLCB3aGljaCB3aWxsIGJlIAotICAgKiBwb3B1bGF0ZWQgd2l0aCBjb252ZXJ0ZWQgYXJndW1lbnRzIGlmIGEgc3VpdGFibGUgbWV0aG9kIGlzIGZvdW5kLgotICAgKiBAcmV0dXJuIEEgY29uc3RydWN0b3IgdGhhdCB3aWxsIHdvcmsgd2l0aCB0aGUgYXJnc091dCBhcnJheS4KLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGZvciBYYWxhbiBjb252ZXJzaW9uCi0gICAqIGV4Y2VwdGlvbnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIENvbnN0cnVjdG9yIGdldENvbnN0cnVjdG9yKENsYXNzIGNsYXNzT2JqLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RbXSBhcmdzSW4sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdW10gYXJnc091dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHByZXNzaW9uQ29udGV4dCBleHByQ29udGV4dCkKLSAgICB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uLAotICAgICAgICAgICBTZWN1cml0eUV4Y2VwdGlvbiwKLSAgICAgICAgICAgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIENvbnN0cnVjdG9yIGJlc3RDb25zdHJ1Y3RvciA9IG51bGw7Ci0gICAgQ2xhc3NbXSBiZXN0UGFyYW1UeXBlcyA9IG51bGw7Ci0gICAgQ29uc3RydWN0b3JbXSBjb25zdHJ1Y3RvcnMgPSBjbGFzc09iai5nZXRDb25zdHJ1Y3RvcnMoKTsKLSAgICBpbnQgbk1ldGhvZHMgPSBjb25zdHJ1Y3RvcnMubGVuZ3RoOwotICAgIGludCBiZXN0U2NvcmUgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICBpbnQgYmVzdFNjb3JlQ291bnQgPSAwOwotICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuTWV0aG9kczsgaSsrKQotICAgIHsKLSAgICAgIENvbnN0cnVjdG9yIGN0b3IgPSBjb25zdHJ1Y3RvcnNbaV07Ci0gICAgICBDbGFzc1tdIHBhcmFtVHlwZXMgPSBjdG9yLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICBpbnQgbnVtYmVyTWV0aG9kUGFyYW1zID0gcGFyYW1UeXBlcy5sZW5ndGg7Ci0gICAgICBpbnQgcGFyYW1TdGFydCA9IDA7Ci0gICAgICBib29sZWFuIGlzRmlyc3RFeHByZXNzaW9uQ29udGV4dCA9IGZhbHNlOwotICAgICAgaW50IHNjb3JlU3RhcnQ7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm51bWJlck1ldGhvZFBhcmFtczogIitudW1iZXJNZXRob2RQYXJhbXMpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhcmdzSW4ubGVuZ3RoOiAiK2FyZ3NJbi5sZW5ndGgpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJleHByQ29udGV4dDogIitleHByQ29udGV4dCk7Ci0gICAgICBpZihudW1iZXJNZXRob2RQYXJhbXMgPT0gKGFyZ3NJbi5sZW5ndGgrMSkpCi0gICAgICB7Ci0gICAgICAgIENsYXNzIGphdmFDbGFzcyA9IHBhcmFtVHlwZXNbMF07Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZmlyc3QgamF2YUNsYXNzOiAiK2phdmFDbGFzcy5nZXROYW1lKCkpOwotICAgICAgICBpZihFeHByZXNzaW9uQ29udGV4dC5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGphdmFDbGFzcykpCi0gICAgICAgIHsKLSAgICAgICAgICBpc0ZpcnN0RXhwcmVzc2lvbkNvbnRleHQgPSB0cnVlOwotICAgICAgICAgIHNjb3JlU3RhcnQgPSAwOwotICAgICAgICAgIHBhcmFtU3RhcnQrKzsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkluY3JlbWVudGluZyBwYXJhbVN0YXJ0OiAiK3BhcmFtU3RhcnQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgICBzY29yZVN0YXJ0ID0gMTAwMDsKLSAgICAgIAotICAgICAgaWYoYXJnc0luLmxlbmd0aCA9PSAobnVtYmVyTWV0aG9kUGFyYW1zIC0gcGFyYW1TdGFydCkpCi0gICAgICB7Ci0gICAgICAgIC8vIHRoZW4gd2UgaGF2ZSBvdXIgY2FuZGlkYXRlLgotICAgICAgICBpbnQgc2NvcmUgPSBzY29yZU1hdGNoKHBhcmFtVHlwZXMsIHBhcmFtU3RhcnQsIGFyZ3NJbiwgc2NvcmVTdGFydCk7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigic2NvcmU6ICIrc2NvcmUpOwotICAgICAgICBpZigtMSA9PSBzY29yZSkJCi0gICAgICAgICAgY29udGludWU7Ci0gICAgICAgIGlmKHNjb3JlIDwgYmVzdFNjb3JlKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJBc3NpZ25pbmcgYmVzdCBjdG9yOiAiK2N0b3IpOwotICAgICAgICAgIGJlc3RDb25zdHJ1Y3RvciA9IGN0b3I7Ci0gICAgICAgICAgYmVzdFBhcmFtVHlwZXMgPSBwYXJhbVR5cGVzOwotICAgICAgICAgIGJlc3RTY29yZSA9IHNjb3JlOwotICAgICAgICAgIGJlc3RTY29yZUNvdW50ID0gMTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChzY29yZSA9PSBiZXN0U2NvcmUpCi0gICAgICAgICAgYmVzdFNjb3JlQ291bnQrKzsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZihudWxsID09IGJlc3RDb25zdHJ1Y3RvcikKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXhjZXB0aW9uKGVyclN0cmluZygiZnVuY3Rpb24iLCAiY29uc3RydWN0b3IiLCBjbGFzc09iaiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIiLCAwLCBhcmdzSW4pKTsKLSAgICB9Ci0gICAgLyoqKiBUaGlzIGlzIGNvbW1lbnRlZCBvdXQgdW50aWwgd2UgY2FuIGRvIGEgYmV0dGVyIG9iamVjdCAtPiBvYmplY3Qgc2NvcmluZyAKLSAgICBlbHNlIGlmIChiZXN0U2NvcmVDb3VudCA+IDEpCi0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiwgbmV3IE9iamVjdFtde2NsYXNzT2JqLmdldE5hbWUoKX0pKTsgLy8iTW9yZSB0aGFuIG9uZSBiZXN0IG1hdGNoIGZvciBjb25zdHJ1Y3RvciBmb3IgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2xhc3NPYmouZ2V0TmFtZSgpKTsKLSAgICAqKiovCi0gICAgZWxzZQotICAgICAgY29udmVydFBhcmFtcyhhcmdzSW4sIGFyZ3NPdXQsIGJlc3RQYXJhbVR5cGVzLCBleHByQ29udGV4dCk7Ci0gICAgCi0gICAgcmV0dXJuIGJlc3RDb25zdHJ1Y3RvcjsKLSAgfQotCi0gIAotICAvKioKLSAgICogR2l2ZW4gdGhlIG5hbWUgb2YgYSBtZXRob2QsIGZpZ3VyZSBvdXQgdGhlIHJlc29sdXRpb24gb2YgCi0gICAqIHRoZSBKYXZhIE1ldGhvZCBmcm9tIHRoZSBYU0xUIGFyZ3VtZW50IHR5cGVzLCBhbmQgcGVyZm9ybSB0aGUgCi0gICAqIGNvbnZlcnNpb24gb2YgdGhlIGFyZ3VtZW50cy4KLSAgICogQHBhcmFtIGNsYXNzT2JqIFRoZSBDbGFzcyBvZiB0aGUgb2JqZWN0IHRoYXQgc2hvdWxkIGhhdmUgdGhlIG1ldGhvZC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBiZSBpbnZva2VkLgotICAgKiBAcGFyYW0gYXJnc0luIEFuIGFycmF5IG9mIFhTTFQvWFBhdGggYXJndW1lbnRzLgotICAgKiBAcGFyYW0gYXJnc091dCBBbiBhcnJheSBvZiB0aGUgZXhhY3Qgc2l6ZSBhcyBhcmdzSW4sIHdoaWNoIHdpbGwgYmUgCi0gICAqIHBvcHVsYXRlZCB3aXRoIGNvbnZlcnRlZCBhcmd1bWVudHMgaWYgYSBzdWl0YWJsZSBtZXRob2QgaXMgZm91bmQuCi0gICAqIEByZXR1cm4gQSBtZXRob2QgdGhhdCB3aWxsIHdvcmsgd2l0aCB0aGUgYXJnc091dCBhcnJheS4KLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGZvciBYYWxhbiBjb252ZXJzaW9uCi0gICAqIGV4Y2VwdGlvbnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE1ldGhvZCBnZXRNZXRob2QoQ2xhc3MgY2xhc3NPYmosCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RbXSBhcmdzSW4sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W11bXSBhcmdzT3V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2VhcmNoTWV0aG9kKQotICAgIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24sCi0gICAgICAgICAgIFNlY3VyaXR5RXhjZXB0aW9uLAotICAgICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCItLS0+IExvb2tpbmcgZm9yIG1ldGhvZDogIituYW1lKTsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLT4gY2xhc3NPYmo6ICIrY2xhc3NPYmopOwotICAgIE1ldGhvZCBiZXN0TWV0aG9kID0gbnVsbDsKLSAgICBDbGFzc1tdIGJlc3RQYXJhbVR5cGVzID0gbnVsbDsKLSAgICBNZXRob2RbXSBtZXRob2RzID0gY2xhc3NPYmouZ2V0TWV0aG9kcygpOwotICAgIGludCBuTWV0aG9kcyA9IG1ldGhvZHMubGVuZ3RoOwotICAgIGludCBiZXN0U2NvcmUgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICBpbnQgYmVzdFNjb3JlQ291bnQgPSAwOwotICAgIGJvb2xlYW4gaXNTdGF0aWM7Ci0gICAgZm9yKGludCBpID0gMDsgaSA8IG5NZXRob2RzOyBpKyspCi0gICAgewotICAgICAgTWV0aG9kIG1ldGhvZCA9IG1ldGhvZHNbaV07Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImxvb2tpbmcgYXQgbWV0aG9kOiAiK21ldGhvZCk7Ci0gICAgICBpbnQgeHNsdFBhcmFtU3RhcnQgPSAwOwotICAgICAgaWYobWV0aG9kLmdldE5hbWUoKS5lcXVhbHMobmFtZSkpCi0gICAgICB7Ci0gICAgICAgIGlzU3RhdGljID0gTW9kaWZpZXIuaXNTdGF0aWMobWV0aG9kLmdldE1vZGlmaWVycygpKTsKLSAgICAgICAgc3dpdGNoKHNlYXJjaE1ldGhvZCkKLSAgICAgICAgewotICAgICAgICAgIGNhc2UgU1RBVElDX09OTFk6Ci0gICAgICAgICAgICBpZiAoIWlzU3RhdGljKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgY2FzZSBJTlNUQU5DRV9PTkxZOgotICAgICAgICAgICAgaWYgKGlzU3RhdGljKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgY2FzZSBTVEFUSUNfQU5EX0lOU1RBTkNFOgotICAgICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgICBjYXNlIERZTkFNSUM6Ci0gICAgICAgICAgICBpZiAoIWlzU3RhdGljKQotICAgICAgICAgICAgICB4c2x0UGFyYW1TdGFydCA9IDE7Ci0gICAgICAgIH0KLSAgICAgICAgaW50IGphdmFQYXJhbVN0YXJ0ID0gMDsKLSAgICAgICAgQ2xhc3NbXSBwYXJhbVR5cGVzID0gbWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICAgIGludCBudW1iZXJNZXRob2RQYXJhbXMgPSBwYXJhbVR5cGVzLmxlbmd0aDsKLSAgICAgICAgYm9vbGVhbiBpc0ZpcnN0RXhwcmVzc2lvbkNvbnRleHQgPSBmYWxzZTsKLSAgICAgICAgaW50IHNjb3JlU3RhcnQ7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibnVtYmVyTWV0aG9kUGFyYW1zOiAiK251bWJlck1ldGhvZFBhcmFtcyk7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYXJnc0luLmxlbmd0aDogIithcmdzSW4ubGVuZ3RoKTsKLSAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJleHByQ29udGV4dDogIitleHByQ29udGV4dCk7Ci0gICAgICAgIGludCBhcmdzTGVuID0gKG51bGwgIT0gYXJnc0luKSA/IGFyZ3NJbi5sZW5ndGggOiAwOwotICAgICAgICBpZihudW1iZXJNZXRob2RQYXJhbXMgPT0gKGFyZ3NMZW4teHNsdFBhcmFtU3RhcnQrMSkpCi0gICAgICAgIHsKLSAgICAgICAgICBDbGFzcyBqYXZhQ2xhc3MgPSBwYXJhbVR5cGVzWzBdOwotICAgICAgICAgIGlmKEV4cHJlc3Npb25Db250ZXh0LmNsYXNzLmlzQXNzaWduYWJsZUZyb20oamF2YUNsYXNzKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpc0ZpcnN0RXhwcmVzc2lvbkNvbnRleHQgPSB0cnVlOwotICAgICAgICAgICAgc2NvcmVTdGFydCA9IDA7Ci0gICAgICAgICAgICBqYXZhUGFyYW1TdGFydCsrOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIHNjb3JlU3RhcnQgPSAxMDAwOwotICAgICAgICAKLSAgICAgICAgaWYoKGFyZ3NMZW4gLSB4c2x0UGFyYW1TdGFydCkgPT0gKG51bWJlck1ldGhvZFBhcmFtcyAtIGphdmFQYXJhbVN0YXJ0KSkKLSAgICAgICAgewotICAgICAgICAgIC8vIHRoZW4gd2UgaGF2ZSBvdXIgY2FuZGlkYXRlLgotICAgICAgICAgIGludCBzY29yZSA9IHNjb3JlTWF0Y2gocGFyYW1UeXBlcywgamF2YVBhcmFtU3RhcnQsIGFyZ3NJbiwgc2NvcmVTdGFydCk7Ci0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJzY29yZTogIitzY29yZSk7Ci0gICAgICAgICAgaWYoLTEgPT0gc2NvcmUpCi0gICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICBpZihzY29yZSA8IGJlc3RTY29yZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkFzc2lnbmluZyBiZXN0IG1ldGhvZDogIittZXRob2QpOwotICAgICAgICAgICAgYmVzdE1ldGhvZCA9IG1ldGhvZDsKLSAgICAgICAgICAgIGJlc3RQYXJhbVR5cGVzID0gcGFyYW1UeXBlczsKLSAgICAgICAgICAgIGJlc3RTY29yZSA9IHNjb3JlOwotICAgICAgICAgICAgYmVzdFNjb3JlQ291bnQgPSAxOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChzY29yZSA9PSBiZXN0U2NvcmUpCi0gICAgICAgICAgICBiZXN0U2NvcmVDb3VudCsrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIAotICAgIGlmIChudWxsID09IGJlc3RNZXRob2QpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbihlcnJTdHJpbmcoImZ1bmN0aW9uIiwgIm1ldGhvZCIsIGNsYXNzT2JqLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHNlYXJjaE1ldGhvZCwgYXJnc0luKSk7Ci0gICAgfQotICAgIC8qKiogVGhpcyBpcyBjb21tZW50ZWQgb3V0IHVudGlsIHdlIGNhbiBkbyBhIGJldHRlciBvYmplY3QgLT4gb2JqZWN0IHNjb3JpbmcgCi0gICAgZWxzZSBpZiAoYmVzdFNjb3JlQ291bnQgPiAxKQotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX01PUkVfTUFUQ0hfTUVUSE9ELCBuZXcgT2JqZWN0W117bmFtZX0pKTsgLy8iTW9yZSB0aGFuIG9uZSBiZXN0IG1hdGNoIGZvciBtZXRob2QgIiArIG5hbWUpOwotICAgICoqKi8KLSAgICBlbHNlCi0gICAgICBjb252ZXJ0UGFyYW1zKGFyZ3NJbiwgYXJnc091dCwgYmVzdFBhcmFtVHlwZXMsIGV4cHJDb250ZXh0KTsKLSAgICAKLSAgICByZXR1cm4gYmVzdE1ldGhvZDsKLSAgfQotCi0gIAotICAvKioKLSAgICogR2l2ZW4gdGhlIG5hbWUgb2YgYSBtZXRob2QsIGZpZ3VyZSBvdXQgdGhlIHJlc29sdXRpb24gb2YgCi0gICAqIHRoZSBKYXZhIE1ldGhvZAotICAgKiBAcGFyYW0gY2xhc3NPYmogVGhlIENsYXNzIG9mIHRoZSBvYmplY3QgdGhhdCBzaG91bGQgaGF2ZSB0aGUgbWV0aG9kLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGJlIGludm9rZWQuCi0gICAqIEByZXR1cm4gQSBtZXRob2QgdGhhdCB3aWxsIHdvcmsgdG8gYmUgY2FsbGVkIGFzIGFuIGVsZW1lbnQuCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gbWF5IGJlIHRocm93biBmb3IgWGFsYW4gY29udmVyc2lvbgotICAgKiBleGNlcHRpb25zLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBNZXRob2QgZ2V0RWxlbWVudE1ldGhvZChDbGFzcyBjbGFzc09iaiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSkKLSAgICB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uLAotICAgICAgICAgICBTZWN1cml0eUV4Y2VwdGlvbiwKLSAgICAgICAgICAgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tPiBMb29raW5nIGZvciBlbGVtZW50IG1ldGhvZDogIituYW1lKTsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLT4gY2xhc3NPYmo6ICIrY2xhc3NPYmopOwotICAgIE1ldGhvZCBiZXN0TWV0aG9kID0gbnVsbDsKLSAgICBNZXRob2RbXSBtZXRob2RzID0gY2xhc3NPYmouZ2V0TWV0aG9kcygpOwotICAgIGludCBuTWV0aG9kcyA9IG1ldGhvZHMubGVuZ3RoOwotICAgIGludCBiZXN0U2NvcmVDb3VudCA9IDA7Ci0gICAgZm9yKGludCBpID0gMDsgaSA8IG5NZXRob2RzOyBpKyspCi0gICAgewotICAgICAgTWV0aG9kIG1ldGhvZCA9IG1ldGhvZHNbaV07Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImxvb2tpbmcgYXQgbWV0aG9kOiAiK21ldGhvZCk7Ci0gICAgICBpZihtZXRob2QuZ2V0TmFtZSgpLmVxdWFscyhuYW1lKSkKLSAgICAgIHsKLSAgICAgICAgQ2xhc3NbXSBwYXJhbVR5cGVzID0gbWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICAgIGlmICggKHBhcmFtVHlwZXMubGVuZ3RoID09IDIpCi0gICAgICAgICAgICYmIHBhcmFtVHlwZXNbMV0uaXNBc3NpZ25hYmxlRnJvbShvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtRXh0ZW5zaW9uQ2FsbC5jbGFzcykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgcGFyYW1UeXBlc1swXS5pc0Fzc2lnbmFibGVGcm9tKG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5YU0xQcm9jZXNzb3JDb250ZXh0LmNsYXNzKSApCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoICsrYmVzdFNjb3JlQ291bnQgPT0gMSApCi0gICAgICAgICAgICBiZXN0TWV0aG9kID0gbWV0aG9kOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIAotICAgIGlmIChudWxsID09IGJlc3RNZXRob2QpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbihlcnJTdHJpbmcoImVsZW1lbnQiLCAibWV0aG9kIiwgY2xhc3NPYmosCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCAwLCBudWxsKSk7Ci0gICAgfQotICAgIGVsc2UgaWYgKGJlc3RTY29yZUNvdW50ID4gMSkKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9NT1JFX01BVENIX0VMRU1FTlQsIG5ldyBPYmplY3RbXXtuYW1lfSkpOyAvLyJNb3JlIHRoYW4gb25lIGJlc3QgbWF0Y2ggZm9yIGVsZW1lbnQgbWV0aG9kICIgKyBuYW1lKTsKLSAgICAKLSAgICByZXR1cm4gYmVzdE1ldGhvZDsKLSAgfQotICAKLQotICAvKioKLSAgICogQ29udmVydCBhIHNldCBvZiBwYXJhbWV0ZXJzIGJhc2VkIG9uIGEgc2V0IG9mIHBhcmFtVHlwZXMuCi0gICAqIEBwYXJhbSBhcmdzSW4gQW4gYXJyYXkgb2YgWFNMVC9YUGF0aCBhcmd1bWVudHMuCi0gICAqIEBwYXJhbSBhcmdzT3V0IEFuIGFycmF5IG9mIHRoZSBleGFjdCBzaXplIGFzIGFyZ3NJbiwgd2hpY2ggd2lsbCBiZSAKLSAgICogcG9wdWxhdGVkIHdpdGggY29udmVydGVkIGFyZ3VtZW50cy4KLSAgICogQHBhcmFtIHBhcmFtVHlwZXMgQW4gYXJyYXkgb2YgY2xhc3Mgb2JqZWN0cywgb2YgdGhlIGV4YWN0IHNhbWUgCi0gICAqIHNpemUgYXMgYXJnc0luIGFuZCBhcmdzT3V0LgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIG1heSBiZSB0aHJvd24gZm9yIFhhbGFuIGNvbnZlcnNpb24KLSAgICogZXhjZXB0aW9ucy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBjb252ZXJ0UGFyYW1zKE9iamVjdFtdIGFyZ3NJbiwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFtdW10gYXJnc091dCwgQ2xhc3NbXSBwYXJhbVR5cGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHByZXNzaW9uQ29udGV4dCBleHByQ29udGV4dCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJJbiBjb252ZXJ0UGFyYW1zIik7Ci0gICAgaWYgKHBhcmFtVHlwZXMgPT0gbnVsbCkKLSAgICAgIGFyZ3NPdXRbMF0gPSBudWxsOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgblBhcmFtcyA9IHBhcmFtVHlwZXMubGVuZ3RoOwotICAgICAgYXJnc091dFswXSA9IG5ldyBPYmplY3RbblBhcmFtc107Ci0gICAgICBpbnQgcGFyYW1JbmRleCA9IDA7Ci0gICAgICBpZigoblBhcmFtcyA+IDApIAotICAgICAgICAgJiYgRXhwcmVzc2lvbkNvbnRleHQuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShwYXJhbVR5cGVzWzBdKSkKLSAgICAgIHsKLSAgICAgICAgYXJnc091dFswXVswXSA9IGV4cHJDb250ZXh0OwotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkluY3JlbWVudGluZyBwYXJhbUluZGV4IGluIGNvbnZlcnRQYXJhbXM6ICIrcGFyYW1JbmRleCk7Ci0gICAgICAgIHBhcmFtSW5kZXgrKzsKLSAgICAgIH0KLQotICAgICAgaWYgKGFyZ3NJbiAhPSBudWxsKQotICAgICAgewotICAgICAgICBmb3IoaW50IGkgPSBhcmdzSW4ubGVuZ3RoIC0gblBhcmFtcyArIHBhcmFtSW5kZXggOyBwYXJhbUluZGV4IDwgblBhcmFtczsgaSsrLCBwYXJhbUluZGV4KyspCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInBhcmFtVHlwZXNbaV06ICIrcGFyYW1UeXBlc1tpXSk7Ci0gICAgICAgICAgYXJnc091dFswXVtwYXJhbUluZGV4XSA9IGNvbnZlcnQoYXJnc0luW2ldLCBwYXJhbVR5cGVzW3BhcmFtSW5kZXhdKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFNpbXBsZSBjbGFzcyB0byBob2xkIGluZm9ybWF0aW9uIGFib3V0IGFsbG93ZWQgY29udmVyc2lvbnMgCi0gICAqIGFuZCB0aGVpciByZWxhdGl2ZSBzY29yZXMsIGZvciB1c2UgYnkgdGhlIHRhYmxlIGJlbG93LgotICAgKi8KLSAgc3RhdGljIGNsYXNzIENvbnZlcnNpb25JbmZvCi0gIHsKLSAgICBDb252ZXJzaW9uSW5mbyhDbGFzcyBjbCwgaW50IHNjb3JlKQotICAgIHsKLSAgICAgIG1fY2xhc3MgPSBjbDsKLSAgICAgIG1fc2NvcmUgPSBzY29yZTsKLSAgICB9Ci0gICAgCi0gICAgQ2xhc3MgbV9jbGFzczsgIC8vIEphdmEgY2xhc3MgdG8gY29udmVydCB0by4KLSAgICBpbnQgbV9zY29yZTsgLy8gTWF0Y2ggc2NvcmUsIGNsb3NlciB0byB6ZXJvIGlzIG1vcmUgbWF0Y2hlZC4KLSAgfQotICAKLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNDT1JFQkFTRT0xOwotICAKLSAgLyoqCi0gICAqIFNwZWNpZmljYXRpb24gb2YgY29udmVyc2lvbnMgZnJvbSBYU0xUIHR5cGUgQ0xBU1NfVU5LTk9XTgotICAgKiAoaS5lLiBzb21lIHVua25vd24gSmF2YSBvYmplY3QpIHRvIGFsbG93ZWQgSmF2YSB0eXBlcy4KLSAgICovCi0gIHN0YXRpYyBDb252ZXJzaW9uSW5mb1tdIG1famF2YU9iakNvbnZlcnNpb25zID0gewotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhEb3VibGUuVFlQRSwgMTEpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhGbG9hdC5UWVBFLCAxMiksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKExvbmcuVFlQRSwgMTMpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhJbnRlZ2VyLlRZUEUsIDE0KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oU2hvcnQuVFlQRSwgMTUpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhDaGFyYWN0ZXIuVFlQRSwgMTYpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhCeXRlLlRZUEUsIDE3KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oamF2YS5sYW5nLlN0cmluZy5jbGFzcywgMTgpCi0gIH07Ci0gIAotICAvKioKLSAgICogU3BlY2lmaWNhdGlvbiBvZiBjb252ZXJzaW9ucyBmcm9tIFhTTFQgdHlwZSBDTEFTU19CT09MRUFOCi0gICAqIHRvIGFsbG93ZWQgSmF2YSB0eXBlcy4KLSAgICovCi0gIHN0YXRpYyBDb252ZXJzaW9uSW5mb1tdIG1fYm9vbGVhbkNvbnZlcnNpb25zID0gewotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhCb29sZWFuLlRZUEUsIDApLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhqYXZhLmxhbmcuQm9vbGVhbi5jbGFzcywgMSksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKGphdmEubGFuZy5PYmplY3QuY2xhc3MsIDIpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLCAzKQotICB9OwotCi0gIC8qKgotICAgKiBTcGVjaWZpY2F0aW9uIG9mIGNvbnZlcnNpb25zIGZyb20gWFNMVCB0eXBlIENMQVNTX05VTUJFUgotICAgKiB0byBhbGxvd2VkIEphdmEgdHlwZXMuCi0gICAqLwotICBzdGF0aWMgQ29udmVyc2lvbkluZm9bXSBtX251bWJlckNvbnZlcnNpb25zID0gewotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhEb3VibGUuVFlQRSwgMCksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKGphdmEubGFuZy5Eb3VibGUuY2xhc3MsIDEpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhGbG9hdC5UWVBFLCAzKSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oTG9uZy5UWVBFLCA0KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oSW50ZWdlci5UWVBFLCA1KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oU2hvcnQuVFlQRSwgNiksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKENoYXJhY3Rlci5UWVBFLCA3KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oQnl0ZS5UWVBFLCA4KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oQm9vbGVhbi5UWVBFLCA5KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oamF2YS5sYW5nLlN0cmluZy5jbGFzcywgMTApLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhqYXZhLmxhbmcuT2JqZWN0LmNsYXNzLCAxMSkKLSAgfTsKLQotICAvKioKLSAgICogU3BlY2lmaWNhdGlvbiBvZiBjb252ZXJzaW9ucyBmcm9tIFhTTFQgdHlwZSBDTEFTU19TVFJJTkcKLSAgICogdG8gYWxsb3dlZCBKYXZhIHR5cGVzLgotICAgKi8KLSAgc3RhdGljIENvbnZlcnNpb25JbmZvW10gbV9zdHJpbmdDb252ZXJzaW9ucyA9IHsKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oamF2YS5sYW5nLlN0cmluZy5jbGFzcywgMCksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKGphdmEubGFuZy5PYmplY3QuY2xhc3MsIDEpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhDaGFyYWN0ZXIuVFlQRSwgMiksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKERvdWJsZS5UWVBFLCAzKSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oRmxvYXQuVFlQRSwgMyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKExvbmcuVFlQRSwgMyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKEludGVnZXIuVFlQRSwgMyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKFNob3J0LlRZUEUsIDMpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhCeXRlLlRZUEUsIDMpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhCb29sZWFuLlRZUEUsIDQpCi0gIH07Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmljYXRpb24gb2YgY29udmVyc2lvbnMgZnJvbSBYU0xUIHR5cGUgQ0xBU1NfUlRSRUVGUkFHCi0gICAqIHRvIGFsbG93ZWQgSmF2YSB0eXBlcy4KLSAgICovCi0gIHN0YXRpYyBDb252ZXJzaW9uSW5mb1tdIG1fcnRmQ29udmVyc2lvbnMgPSB7Ci0gICAgbmV3IENvbnZlcnNpb25JbmZvKG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IuY2xhc3MsIDApLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhvcmcudzNjLmRvbS5Ob2RlTGlzdC5jbGFzcywgMSksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKG9yZy53M2MuZG9tLk5vZGUuY2xhc3MsIDIpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLCAzKSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oamF2YS5sYW5nLk9iamVjdC5jbGFzcywgNSksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKENoYXJhY3Rlci5UWVBFLCA2KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oRG91YmxlLlRZUEUsIDcpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhGbG9hdC5UWVBFLCA3KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oTG9uZy5UWVBFLCA3KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oSW50ZWdlci5UWVBFLCA3KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oU2hvcnQuVFlQRSwgNyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKEJ5dGUuVFlQRSwgNyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKEJvb2xlYW4uVFlQRSwgOCkKLSAgfTsKLSAgCi0gIC8qKgotICAgKiBTcGVjaWZpY2F0aW9uIG9mIGNvbnZlcnNpb25zIGZyb20gWFNMVCB0eXBlIENMQVNTX05PREVTRVQKLSAgICogdG8gYWxsb3dlZCBKYXZhIHR5cGVzLiAgKFRoaXMgaXMgdGhlIHNhbWUgYXMgZm9yIENMQVNTX1JUUkVFRlJBRykKLSAgICovCi0gIHN0YXRpYyBDb252ZXJzaW9uSW5mb1tdIG1fbm9kZXNldENvbnZlcnNpb25zID0gewotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yLmNsYXNzLCAwKSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8ob3JnLnczYy5kb20uTm9kZUxpc3QuY2xhc3MsIDEpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhvcmcudzNjLmRvbS5Ob2RlLmNsYXNzLCAyKSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oamF2YS5sYW5nLlN0cmluZy5jbGFzcywgMyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKGphdmEubGFuZy5PYmplY3QuY2xhc3MsIDUpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhDaGFyYWN0ZXIuVFlQRSwgNiksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKERvdWJsZS5UWVBFLCA3KSwKLSAgICBuZXcgQ29udmVyc2lvbkluZm8oRmxvYXQuVFlQRSwgNyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKExvbmcuVFlQRSwgNyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKEludGVnZXIuVFlQRSwgNyksCi0gICAgbmV3IENvbnZlcnNpb25JbmZvKFNob3J0LlRZUEUsIDcpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhCeXRlLlRZUEUsIDcpLAotICAgIG5ldyBDb252ZXJzaW9uSW5mbyhCb29sZWFuLlRZUEUsIDgpCi0gIH07Ci0gIAotICAvKioKLSAgICogT3JkZXIgaXMgc2lnbmlmaWNhbnQgaW4gdGhlIGxpc3QgYmVsb3csIGJhc2VkIG9uIAotICAgKiBYT2JqZWN0LkNMQVNTX1hYWCB2YWx1ZXMuCi0gICAqLwotICBzdGF0aWMgQ29udmVyc2lvbkluZm9bXVtdIG1fY29udmVyc2lvbnMgPSAKLSAgewotICAgIG1famF2YU9iakNvbnZlcnNpb25zLCAvLyBDTEFTU19VTktOT1dOID0gMDsKLSAgICBtX2Jvb2xlYW5Db252ZXJzaW9ucywgLy8gQ0xBU1NfQk9PTEVBTiA9IDE7Ci0gICAgbV9udW1iZXJDb252ZXJzaW9ucywgIC8vIENMQVNTX05VTUJFUiA9IDI7Ci0gICAgbV9zdHJpbmdDb252ZXJzaW9ucywgIC8vIENMQVNTX1NUUklORyA9IDM7Ci0gICAgbV9ub2Rlc2V0Q29udmVyc2lvbnMsIC8vIENMQVNTX05PREVTRVQgPSA0OwotICAgIG1fcnRmQ29udmVyc2lvbnMgICAgICAvLyBDTEFTU19SVFJFRUZSQUcgPSA1OwotICB9OwotICAKLSAgLyoqCi0gICAqIFNjb3JlIHRoZSBjb252ZXJzaW9uIG9mIGEgc2V0IG9mIFhTTFQgYXJndW1lbnRzIHRvIGEgCi0gICAqIGdpdmVuIHNldCBvZiBKYXZhIHBhcmFtZXRlcnMuCi0gICAqIElmIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGZ1bmN0aW9uIGZvciBhIG1ldGhvZCB3aXRoIAotICAgKiB0aGUgc2FtZSBuYW1lIHJldHVybiB0aGUgc2FtZSBwb3NpdGl2ZSB2YWx1ZSwgdGhlbiBhIGNvbmZsaWN0IAotICAgKiBoYXMgb2NjdXJlZCwgYW5kIGFuIGVycm9yIHNob3VsZCBiZSBzaWduYWxlZC4KLSAgICogQHBhcmFtIGphdmFQYXJhbVR5cGVzIE11c3QgYmUgZmlsbGVkIHdpdGggdmFsaWQgY2xhc3MgbmFtZXMsIGFuZCAKLSAgICogb2YgdGhlIHNhbWUgbGVuZ3RoIGFzIHhzbHRBcmdzLgotICAgKiBAcGFyYW0geHNsdEFyZ3MgTXVzdCBiZSBmaWxsZWQgd2l0aCB2YWxpZCBvYmplY3QgaW5zdGFuY2VzLCBhbmQgCi0gICAqIG9mIHRoZSBzYW1lIGxlbmd0aCBhcyBqYXZlUGFyYW1UeXBlcy4KLSAgICogQHJldHVybiAtMSBmb3Igbm8gYWxsb3dlZCBjb252ZXJzaW9uLCBvciBhIHBvc2l0aXZlIHNjb3JlIAotICAgKiB0aGF0IGlzIGNsb3NlciB0byB6ZXJvIGZvciBtb3JlIHByZWZlcnJlZCwgb3IgZnVydGhlciBmcm9tIAotICAgKiB6ZXJvIGZvciBsZXNzIHByZWZlcnJlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IHNjb3JlTWF0Y2goQ2xhc3NbXSBqYXZhUGFyYW1UeXBlcywgaW50IGphdmFQYXJhbXNTdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RbXSB4c2x0QXJncywgaW50IHNjb3JlKQotICB7Ci0gICAgaWYgKCh4c2x0QXJncyA9PSBudWxsKSB8fCAoamF2YVBhcmFtVHlwZXMgPT0gbnVsbCkpCi0gICAgICByZXR1cm4gc2NvcmU7Ci0gICAgaW50IG5QYXJhbXMgPSB4c2x0QXJncy5sZW5ndGg7Ci0gICAgZm9yKGludCBpID0gblBhcmFtcyAtIGphdmFQYXJhbVR5cGVzLmxlbmd0aCArIGphdmFQYXJhbXNTdGFydCwgamF2YVBhcmFtVHlwZXNJbmRleCA9IGphdmFQYXJhbXNTdGFydDsgCi0gICAgICAgIGkgPCBuUGFyYW1zOyAKLSAgICAgICAgaSsrLCBqYXZhUGFyYW1UeXBlc0luZGV4KyspCi0gICAgewotICAgICAgT2JqZWN0IHhzbHRPYmogPSB4c2x0QXJnc1tpXTsKLSAgICAgIGludCB4c2x0Q2xhc3NUeXBlID0gKHhzbHRPYmogaW5zdGFuY2VvZiBYT2JqZWN0KSAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoKFhPYmplY3QpeHNsdE9iaikuZ2V0VHlwZSgpIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogWE9iamVjdC5DTEFTU19VTktOT1dOOwotICAgICAgQ2xhc3MgamF2YUNsYXNzID0gamF2YVBhcmFtVHlwZXNbamF2YVBhcmFtVHlwZXNJbmRleF07Ci0gICAgICAKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiQ2hlY2tpbmcgeHNsdDogIit4c2x0T2JqLmdldENsYXNzKCkuZ2V0TmFtZSgpKwotICAgICAgLy8gICAgICAgICAgICAgICAgICAgIiBhZ2FpbnN0IGphdmE6ICIramF2YUNsYXNzLmdldE5hbWUoKSk7Ci0gICAgICAKLSAgICAgIGlmKHhzbHRDbGFzc1R5cGUgPT0gWE9iamVjdC5DTEFTU19OVUxMKQotICAgICAgewotICAgICAgICAvLyBJbiBYYWxhbiBJIGhhdmUgb2JqZWN0cyBvZiBDTEFTU19OVUxMLCB0aG91Z2ggSSdtIG5vdCAKLSAgICAgICAgLy8gc3VyZSB0aGV5J3JlIHVzZWQgYW55IG1vcmUuICBGb3Igbm93LCBkbyBzb21ldGhpbmcgZnVua3kuCi0gICAgICAgIGlmKCFqYXZhQ2xhc3MuaXNQcmltaXRpdmUoKSkKLSAgICAgICAgewotICAgICAgICAgIC8vIFRoZW4gYXNzdW1lIHRoYXQgYSBudWxsIGNhbiBiZSB1c2VkLCBidXQgZ2l2ZSBpdCBhIGxvdyBzY29yZS4KLSAgICAgICAgICBzY29yZSArPSAxMDsKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIC0xOyAgLy8gbm8gbWF0Y2guCi0gICAgICB9Ci0gICAgICAKLSAgICAgIENvbnZlcnNpb25JbmZvW10gY29udkluZm8gPSBtX2NvbnZlcnNpb25zW3hzbHRDbGFzc1R5cGVdOwotICAgICAgaW50IG5Db252ZXJzaW9ucyA9IGNvbnZJbmZvLmxlbmd0aDsKLSAgICAgIGludCBrOwotICAgICAgZm9yKGsgPSAwOyBrIDwgbkNvbnZlcnNpb25zOyBrKyspCi0gICAgICB7Ci0gICAgICAgIENvbnZlcnNpb25JbmZvIGNpbmZvID0gY29udkluZm9ba107Ci0gICAgICAgIGlmKGphdmFDbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGNpbmZvLm1fY2xhc3MpKQotICAgICAgICB7Ci0gICAgICAgICAgc2NvcmUgKz0gY2luZm8ubV9zY29yZTsKLSAgICAgICAgICBicmVhazsgLy8gZnJvbSBrIGxvb3AKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoayA9PSBuQ29udmVyc2lvbnMpCi0gICAgICB7Ci0gICAgICAgIC8vIElmIHdlIGdldCBoZXJlLCB3ZSBoYXZlbid0IG1hZGUgYSBtYXRjaCBvbiB0aGlzIHBhcmFtZXRlciB1c2luZyAKLSAgICAgICAgLy8gdGhlIENvbnZlcnNpb25JbmZvIGFycmF5LiAgV2Ugbm93IHRyeSB0byBoYW5kbGUgdGhlIG9iamVjdCAtPiBvYmplY3QKLSAgICAgICAgLy8gbWFwcGluZyB3aGljaCB3ZSBjYW4ndCBoYW5kbGUgdGhyb3VnaCB0aGUgYXJyYXkgbWVjaGFuaXNtLiAgVG8gZG8gdGhpcywKLSAgICAgICAgLy8gd2UgbXVzdCBkZXRlcm1pbmUgdGhlIGNsYXNzIG9mIHRoZSBhcmd1bWVudCBwYXNzZWQgZnJvbSB0aGUgc3R5bGVzaGVldC4KLQotICAgICAgICAvLyBJZiB3ZSB3ZXJlIHBhc3NlZCBhIHN1YmNsYXNzIG9mIFhPYmplY3QsIHJlcHJlc2VudGluZyBvbmUgb2YgdGhlIGFjdHVhbAotICAgICAgICAvLyBYU0xUIHR5cGVzLCBhbmQgd2UgYXJlIGhlcmUsIHdlIHJlamVjdCB0aGlzIGV4dGVuc2lvbiBtZXRob2QgYXMgYSBjYW5kaWRhdGUKLSAgICAgICAgLy8gYmVjYXVzZSBhIG1hdGNoIHNob3VsZCBoYXZlIGJlZW4gbWFkZSB1c2luZyB0aGUgQ29udmVyc2lvbkluZm8gYXJyYXkuICBJZiB3ZSAKLSAgICAgICAgLy8gd2VyZSBwYXNzZWQgYW4gWE9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyBhIG5vbi1YU0xUIHR5cGUgb3Igd2UKLSAgICAgICAgLy8gd2VyZSBwYXNzZWQgYSBub24tWFNMVCB0eXBlIGRpcmVjdGx5LCB3ZSBjb250aW51ZS4KLQotICAgICAgICAvLyBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiAoY29udHJpYnV0ZWQgYnkgS2VsbHkgQ2FtcGJlbGwgPGNhbWtAY2hhbm5lbHBvaW50LmNvbT4pCi0gICAgICAgIC8vIGNoZWNrcyB0byBzZWUgaWYgd2Ugd2VyZSBwYXNzZWQgYW4gWE9iamVjdCBmcm9tIHRoZSBYU0xUIHN0eWxlc2hlZXQuICBJZiBub3QsCi0gICAgICAgIC8vIHdlIHVzZSB0aGUgY2xhc3Mgb2YgdGhlIG9iamVjdCB0aGF0IHdhcyBwYXNzZWQgYW5kIG1ha2Ugc3VyZSB0aGF0IGl0IHdpbGwKLSAgICAgICAgLy8gbWFwIHRvIHRoZSBjbGFzcyB0eXBlIG9mIHRoZSBwYXJhbWV0ZXIgaW4gdGhlIGV4dGVuc2lvbiBmdW5jdGlvbi4KLSAgICAgICAgLy8gSWYgd2Ugd2VyZSBwYXNzZWQgYW4gWE9iamVjdCwgd2UgYXR0ZW1wdCB0byBnZXQgdGhlIGNsYXNzIG9mIHRoZSBhY3R1YWwKLSAgICAgICAgLy8gb2JqZWN0IGVuY2Fwc3VsYXRlZCBpbnNpZGUgdGhlIFhPYmplY3QuICBJZiB0aGUgZW5jYXBzdWxhdGVkIG9iamVjdCBpcyBudWxsLAotICAgICAgICAvLyB3ZSBqdWRnZSB0aGlzIG1ldGhvZCBhcyBhIG1hdGNoIGJ1dCBnaXZlIGl0IGEgbG93IHNjb3JlLiAgCi0gICAgICAgIC8vIElmIHRoZSBlbmNhcHN1bGF0ZWQgb2JqZWN0IGlzIG5vdCBudWxsLCB3ZSB1c2UgaXRzIHR5cGUgdG8gZGV0ZXJtaW5lCi0gICAgICAgIC8vIHdoZXRoZXIgdGhpcyBqYXZhIG1ldGhvZCBpcyBhIHZhbGlkIG1hdGNoIGZvciB0aGlzIGV4dGVuc2lvbiBmdW5jdGlvbiBjYWxsLgotICAgICAgICAvLyBUaGlzIGFwcHJvYWNoIGVsaW1pbmF0ZXMgdGhlIE51bGxQb2ludGVyRXhjZXB0aW9uIGluIHRoZSBlYXJsaWVyIGltcGxlbWVudGF0aW9uCi0gICAgICAgIC8vIHRoYXQgcmVzdWx0ZWQgZnJvbSBwYXNzaW5nIGFuIFhPYmplY3QgZW5jYXBzdWxhdGluZyB0aGUgbnVsbCBqYXZhIG9iamVjdC4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgIC8vIFRPRE86ICBUaGlzIG5lZWRzIHRvIGJlIGltcHJvdmVkIHRvIGFzc2lnbiByZWxhdGl2ZSBzY29yZXMgdG8gc3ViY2xhc3NlcywKLSAgICAgICAgLy8gZXRjLiAKLQotICAgICAgICBpZiAoWE9iamVjdC5DTEFTU19VTktOT1dOID09IHhzbHRDbGFzc1R5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBDbGFzcyByZWFsQ2xhc3MgPSBudWxsOwotCi0gICAgICAgICAgaWYgKHhzbHRPYmogaW5zdGFuY2VvZiBYT2JqZWN0KQotICAgICAgICAgIHsKLSAgICAgICAgICAgIE9iamVjdCByZWFsT2JqID0gKChYT2JqZWN0KSB4c2x0T2JqKS5vYmplY3QoKTsKLSAgICAgICAgICAgIGlmIChudWxsICE9IHJlYWxPYmopCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHJlYWxDbGFzcyA9IHJlYWxPYmouZ2V0Q2xhc3MoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgLy8gZG8gdGhlIHNhbWUgYXMgaWYgd2Ugd2VyZSBwYXNzZWQgWE9iamVjdC5DTEFTU19OVUxMCi0gICAgICAgICAgICAgIHNjb3JlICs9IDEwOwotICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJlYWxDbGFzcyA9IHhzbHRPYmouZ2V0Q2xhc3MoKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoamF2YUNsYXNzLmlzQXNzaWduYWJsZUZyb20ocmVhbENsYXNzKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBzY29yZSArPSAwOyAgICAgICAgIC8vIFRPRE86IFRvIGJlIGFzc2lnbmVkIGJhc2VkIG9uIHN1YmNsYXNzICJkaXN0YW5jZSIKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICB9Ci0gICAgfQotICAgIHJldHVybiBzY29yZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnZlcnQgdGhlIGdpdmVuIFhTTFQgb2JqZWN0IHRvIGFuIG9iamVjdCBvZiAKLSAgICogdGhlIGdpdmVuIGNsYXNzLgotICAgKiBAcGFyYW0geHNsdE9iaiBUaGUgWFNMVCBvYmplY3QgdGhhdCBuZWVkcyBjb252ZXJzaW9uLgotICAgKiBAcGFyYW0gamF2YUNsYXNzIFRoZSB0eXBlIG9mIG9iamVjdCB0byBjb252ZXJ0IHRvLgotICAgKiBAcmV0dXJucyBBbiBvYmplY3Qgc3VpdGFibGUgZm9yIHBhc3NpbmcgdG8gdGhlIE1ldGhvZC5pbnZva2UgCi0gICAqIGZ1bmN0aW9uIGluIHRoZSBhcmdzIGFycmF5LCB3aGljaCBtYXkgYmUgbnVsbCBpbiBzb21lIGNhc2VzLgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIG1heSBiZSB0aHJvd24gZm9yIFhhbGFuIGNvbnZlcnNpb24KLSAgICogZXhjZXB0aW9ucy4KLSAgICovCi0gIHN0YXRpYyBPYmplY3QgY29udmVydChPYmplY3QgeHNsdE9iaiwgQ2xhc3MgamF2YUNsYXNzKQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpZih4c2x0T2JqIGluc3RhbmNlb2YgWE9iamVjdCkKLSAgICB7Ci0gICAgICBYT2JqZWN0IHhvYmogPSAoKFhPYmplY3QpeHNsdE9iaik7Ci0gICAgICBpbnQgeHNsdENsYXNzVHlwZSA9IHhvYmouZ2V0VHlwZSgpOwotCi0gICAgICBzd2l0Y2goeHNsdENsYXNzVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19OVUxMOgotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgCi0gICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfQk9PTEVBTjoKLSAgICAgICAgewotICAgICAgICAgIGlmKGphdmFDbGFzcyA9PSBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzKQotICAgICAgICAgICAgcmV0dXJuIHhvYmouc3RyKCk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKHhvYmouYm9vbCgpKTsKLSAgICAgICAgfQotICAgICAgICAvLyBicmVhazsgVW5yZWFjaGFibGUKLSAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19OVU1CRVI6Ci0gICAgICAgIHsKLSAgICAgICAgICBpZihqYXZhQ2xhc3MgPT0gamF2YS5sYW5nLlN0cmluZy5jbGFzcykKLSAgICAgICAgICAgIHJldHVybiB4b2JqLnN0cigpOwotICAgICAgICAgIGVsc2UgaWYoamF2YUNsYXNzID09IEJvb2xlYW4uVFlQRSkKLSAgICAgICAgICAgIHJldHVybiBuZXcgQm9vbGVhbih4b2JqLmJvb2woKSk7Ci0gICAgICAgICAgZWxzZSAKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gY29udmVydERvdWJsZVRvTnVtYmVyKHhvYmoubnVtKCksIGphdmFDbGFzcyk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vIGJyZWFrOyBVbnJlYWNoYWJsZQotICAgICAgICAKLSAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19TVFJJTkc6Ci0gICAgICAgIHsKLSAgICAgICAgICBpZigoamF2YUNsYXNzID09IGphdmEubGFuZy5TdHJpbmcuY2xhc3MpIHx8Ci0gICAgICAgICAgICAgKGphdmFDbGFzcyA9PSBqYXZhLmxhbmcuT2JqZWN0LmNsYXNzKSkKLSAgICAgICAgICAgIHJldHVybiB4b2JqLnN0cigpOwotICAgICAgICAgIGVsc2UgaWYoamF2YUNsYXNzID09IENoYXJhY3Rlci5UWVBFKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyBzdHIgPSB4b2JqLnN0cigpOwotICAgICAgICAgICAgaWYoc3RyLmxlbmd0aCgpID4gMCkKLSAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGFyYWN0ZXIoc3RyLmNoYXJBdCgwKSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyA/PwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmKGphdmFDbGFzcyA9PSBCb29sZWFuLlRZUEUpCi0gICAgICAgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oeG9iai5ib29sKCkpOwotICAgICAgICAgIGVsc2UgCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnREb3VibGVUb051bWJlcih4b2JqLm51bSgpLCBqYXZhQ2xhc3MpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBicmVhazsgVW5yZWFjaGFibGUKLSAgICAgICAgCi0gICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfUlRSRUVGUkFHOgotICAgICAgICB7Ci0gICAgICAgICAgLy8gR0xQOiAgSSBkb24ndCBzZWUgdGhlIHJlYXNvbiBmb3IgdGhlIGlzQXNzaWduYWJsZUZyb20gY2FsbAotICAgICAgICAgIC8vICAgICAgIGluc3RlYWQgb2YgYW4gPT0gdGVzdCBhcyBpcyB1c2VkIGV2ZXJ5d2hlcmUgZWxzZS4KLSAgICAgICAgICAvLyAgICAgICBCZXNpZGVzLCBpZiB0aGUgamF2YUNsYXNzIGlzIGEgc3ViY2xhc3Mgb2YgTm9kZUl0ZXJhdG9yCi0gICAgICAgICAgLy8gICAgICAgdGhlIGNvbmRpdGlvbiB3aWxsIGJlIHRydWUgYW5kIHdlJ2xsIGNyZWF0ZSBhIE5vZGVJdGVyYXRvcgotICAgICAgICAgIC8vICAgICAgIHdoaWNoIG1heSBub3QgbWF0Y2ggdGhlIGphdmFDbGFzcywgY2F1c2luZyBhIFJ1bnRpbWVFeGNlcHRpb24uCi0gICAgICAgICAgLy8gaWYoKE5vZGVJdGVyYXRvci5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGphdmFDbGFzcykpIHx8Ci0gICAgICAgICAgaWYgKCAoamF2YUNsYXNzID09IE5vZGVJdGVyYXRvci5jbGFzcykgfHwKLSAgICAgICAgICAgICAgIChqYXZhQ2xhc3MgPT0gamF2YS5sYW5nLk9iamVjdC5jbGFzcykgKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIERUTUl0ZXJhdG9yIGR0bUl0ZXIgPSAoKFhSVHJlZUZyYWcpIHhvYmopLmFzTm9kZUl0ZXJhdG9yKCk7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IERUTU5vZGVJdGVyYXRvcihkdG1JdGVyKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoamF2YUNsYXNzID09IE5vZGVMaXN0LmNsYXNzKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiAoKFhSVHJlZUZyYWcpIHhvYmopLmNvbnZlcnRUb05vZGVzZXQoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgLy8gU2FtZSBjb21tZW50IGFzIGFib3ZlCi0gICAgICAgICAgLy8gZWxzZSBpZihOb2RlLmNsYXNzLmlzQXNzaWduYWJsZUZyb20oamF2YUNsYXNzKSkKLSAgICAgICAgICBlbHNlIGlmKGphdmFDbGFzcyA9PSBOb2RlLmNsYXNzKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIERUTUl0ZXJhdG9yIGl0ZXIgPSAoKFhSVHJlZUZyYWcpIHhvYmopLmFzTm9kZUl0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBpbnQgcm9vdEhhbmRsZSA9IGl0ZXIubmV4dE5vZGUoKTsKLSAgICAgICAgICAgIERUTSBkdG0gPSBpdGVyLmdldERUTShyb290SGFuZGxlKTsKLSAgICAgICAgICAgIHJldHVybiBkdG0uZ2V0Tm9kZShkdG0uZ2V0Rmlyc3RDaGlsZChyb290SGFuZGxlKSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYoamF2YUNsYXNzID09IGphdmEubGFuZy5TdHJpbmcuY2xhc3MpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIHhvYmouc3RyKCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYoamF2YUNsYXNzID09IEJvb2xlYW4uVFlQRSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oeG9iai5ib29sKCkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmKGphdmFDbGFzcy5pc1ByaW1pdGl2ZSgpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBjb252ZXJ0RG91YmxlVG9OdW1iZXIoeG9iai5udW0oKSwgamF2YUNsYXNzKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIERUTUl0ZXJhdG9yIGl0ZXIgPSAoKFhSVHJlZUZyYWcpIHhvYmopLmFzTm9kZUl0ZXJhdG9yKCk7Ci0gICAgICAgICAgICBpbnQgcm9vdEhhbmRsZSA9IGl0ZXIubmV4dE5vZGUoKTsKLSAgICAgICAgICAgIERUTSBkdG0gPSBpdGVyLmdldERUTShyb290SGFuZGxlKTsKLSAgICAgICAgICAgIE5vZGUgY2hpbGQgPSBkdG0uZ2V0Tm9kZShkdG0uZ2V0Rmlyc3RDaGlsZChyb290SGFuZGxlKSk7Ci0KLSAgICAgICAgICAgIGlmKGphdmFDbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGNoaWxkLmdldENsYXNzKCkpKQotICAgICAgICAgICAgICByZXR1cm4gY2hpbGQ7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBicmVhazsgVW5yZWFjaGFibGUKLSAgICAgICAgCi0gICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfTk9ERVNFVDoKLSAgICAgICAgewotICAgICAgICAgIC8vIEdMUDogIEkgZG9uJ3Qgc2VlIHRoZSByZWFzb24gZm9yIHRoZSBpc0Fzc2lnbmFibGVGcm9tIGNhbGwKLSAgICAgICAgICAvLyAgICAgICBpbnN0ZWFkIG9mIGFuID09IHRlc3QgYXMgaXMgdXNlZCBldmVyeXdoZXJlIGVsc2UuCi0gICAgICAgICAgLy8gICAgICAgQmVzaWRlcywgaWYgdGhlIGphdmFDbGFzcyBpcyBhIHN1YmNsYXNzIG9mIE5vZGVJdGVyYXRvcgotICAgICAgICAgIC8vICAgICAgIHRoZSBjb25kaXRpb24gd2lsbCBiZSB0cnVlIGFuZCB3ZSdsbCBjcmVhdGUgYSBOb2RlSXRlcmF0b3IKLSAgICAgICAgICAvLyAgICAgICB3aGljaCBtYXkgbm90IG1hdGNoIHRoZSBqYXZhQ2xhc3MsIGNhdXNpbmcgYSBSdW50aW1lRXhjZXB0aW9uLgotICAgICAgICAgIC8vIGlmKChOb2RlSXRlcmF0b3IuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShqYXZhQ2xhc3MpKSB8fAotICAgICAgICAgIGlmICggKGphdmFDbGFzcyA9PSBOb2RlSXRlcmF0b3IuY2xhc3MpIHx8Ci0gICAgICAgICAgICAgICAoamF2YUNsYXNzID09IGphdmEubGFuZy5PYmplY3QuY2xhc3MpICkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4geG9iai5ub2Rlc2V0KCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIC8vIFNhbWUgY29tbWVudCBhcyBhYm92ZQotICAgICAgICAgIC8vIGVsc2UgaWYoTm9kZUxpc3QuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShqYXZhQ2xhc3MpKQotICAgICAgICAgIGVsc2UgaWYoamF2YUNsYXNzID09IE5vZGVMaXN0LmNsYXNzKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiB4b2JqLm5vZGVsaXN0KCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIC8vIFNhbWUgY29tbWVudCBhcyBhYm92ZQotICAgICAgICAgIC8vIGVsc2UgaWYoTm9kZS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGphdmFDbGFzcykpCi0gICAgICAgICAgZWxzZSBpZihqYXZhQ2xhc3MgPT0gTm9kZS5jbGFzcykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBYYWxhbiBlbnN1cmVzIHRoYXQgaXRlcigpIGFsd2F5cyByZXR1cm5zIGFuCi0gICAgICAgICAgICAvLyBpdGVyYXRvciBwb3NpdGlvbmVkIGF0IHRoZSBiZWdpbm5pbmcuCi0gICAgICAgICAgICBEVE1JdGVyYXRvciBuaSA9IHhvYmouaXRlcigpOwotICAgICAgICAgICAgaW50IGhhbmRsZSA9IG5pLm5leHROb2RlKCk7ICAgICAgICAgICAKLSAgICAgICAgICAgIHJldHVybiBuaS5nZXREVE0oaGFuZGxlKS5nZXROb2RlKGhhbmRsZSk7IC8vIG1heSBiZSBudWxsLgotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmKGphdmFDbGFzcyA9PSBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiB4b2JqLnN0cigpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmKGphdmFDbGFzcyA9PSBCb29sZWFuLlRZUEUpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBCb29sZWFuKHhvYmouYm9vbCgpKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZihqYXZhQ2xhc3MuaXNQcmltaXRpdmUoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gY29udmVydERvdWJsZVRvTnVtYmVyKHhvYmoubnVtKCksIGphdmFDbGFzcyk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBEVE1JdGVyYXRvciBpdGVyID0geG9iai5pdGVyKCk7Ci0gICAgICAgICAgICBpbnQgY2hpbGRIYW5kbGUgPSBpdGVyLm5leHROb2RlKCk7Ci0gICAgICAgICAgICBEVE0gZHRtID0gaXRlci5nZXREVE0oY2hpbGRIYW5kbGUpOwotICAgICAgICAgICAgTm9kZSBjaGlsZCA9IGR0bS5nZXROb2RlKGNoaWxkSGFuZGxlKTsKLSAgICAgICAgICAgIGlmKGphdmFDbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGNoaWxkLmdldENsYXNzKCkpKQotICAgICAgICAgICAgICByZXR1cm4gY2hpbGQ7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLyBicmVhazsgVW5yZWFjaGFibGUKLSAgICAgICAgCi0gICAgICAgIC8vIE5vIGRlZmF1bHQ6LCBmYWxsLXRocm91Z2ggb24gcHVycG9zZQotICAgICAgfSAvLyBlbmQgc3dpdGNoCi0gICAgICB4c2x0T2JqID0geG9iai5vYmplY3QoKTsKLSAgICAgIAotICAgIH0gLy8gZW5kIGlmIGlmKHhzbHRPYmogaW5zdGFuY2VvZiBYT2JqZWN0KQotICAgIAotICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIGhhdmUgYSByYXcgamF2YSBvYmplY3QsIG5vdCBhbiBYT2JqZWN0LgotICAgIGlmIChudWxsICE9IHhzbHRPYmopCi0gICAgewotICAgICAgaWYoamF2YUNsYXNzID09IGphdmEubGFuZy5TdHJpbmcuY2xhc3MpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiB4c2x0T2JqLnRvU3RyaW5nKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKGphdmFDbGFzcy5pc1ByaW1pdGl2ZSgpKQotICAgICAgewotICAgICAgICAvLyBBc3N1bWUgYSBudW1iZXIgY29udmVyc2lvbgotICAgICAgICBYU3RyaW5nIHhzdHIgPSBuZXcgWFN0cmluZyh4c2x0T2JqLnRvU3RyaW5nKCkpOwotICAgICAgICBkb3VibGUgbnVtID0geHN0ci5udW0oKTsKLSAgICAgICAgcmV0dXJuIGNvbnZlcnREb3VibGVUb051bWJlcihudW0sIGphdmFDbGFzcyk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKGphdmFDbGFzcyA9PSBqYXZhLmxhbmcuQ2xhc3MuY2xhc3MpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiB4c2x0T2JqLmdldENsYXNzKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIEp1c3QgcGFzcyB0aGUgb2JqZWN0IGRpcmVjdGx5LCBhbmQgaG9wZSBmb3IgdGhlIGJlc3QuCi0gICAgICAgIHJldHVybiB4c2x0T2JqOwotICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gSnVzdCBwYXNzIHRoZSBvYmplY3QgZGlyZWN0bHksIGFuZCBob3BlIGZvciB0aGUgYmVzdC4KLSAgICAgIHJldHVybiB4c2x0T2JqOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIERvIGEgc3RhbmRhcmQgY29udmVyc2lvbiBvZiBhIGRvdWJsZSB0byB0aGUgc3BlY2lmaWVkIHR5cGUuCi0gICAqIEBwYXJhbSBudW0gVGhlIG51bWJlciB0byBiZSBjb252ZXJ0ZWQuCi0gICAqIEBwYXJhbSBqYXZhQ2xhc3MgVGhlIGNsYXNzIHR5cGUgdG8gYmUgY29udmVydGVkIHRvLgotICAgKiBAcmV0dXJuIEFuIG9iamVjdCBzcGVjaWZpZWQgYnkgamF2YUNsYXNzLCBvciBhIERvdWJsZSBpbnN0YW5jZS4KLSAgICovCi0gIHN0YXRpYyBPYmplY3QgY29udmVydERvdWJsZVRvTnVtYmVyKGRvdWJsZSBudW0sIENsYXNzIGphdmFDbGFzcykKLSAgewotICAgIC8vIEluIHRoZSBjb2RlIGJlbG93LCBJIGRvbid0IGNoZWNrIGZvciBOYU4sIGV0Yy4sIGluc3RlYWQgCi0gICAgLy8gdXNpbmcgdGhlIHN0YW5kYXJkIEphdmEgY29udmVyc2lvbiwgYXMgSSB0aGluayB3ZSBzaG91bGQgCi0gICAgLy8gc3BlY2lmeS4gIFNlZSBpc3N1ZS1ydW50aW1lLWVycm9ycy4KLSAgICBpZigoamF2YUNsYXNzID09IERvdWJsZS5UWVBFKSB8fAotICAgICAgIChqYXZhQ2xhc3MgPT0gamF2YS5sYW5nLkRvdWJsZS5jbGFzcykpCi0gICAgICByZXR1cm4gbmV3IERvdWJsZShudW0pOwotICAgIGVsc2UgaWYoamF2YUNsYXNzID09IEZsb2F0LlRZUEUpCi0gICAgICByZXR1cm4gbmV3IEZsb2F0KG51bSk7Ci0gICAgZWxzZSBpZihqYXZhQ2xhc3MgPT0gTG9uZy5UWVBFKQotICAgIHsKLSAgICAgIC8vIFVzZSBzdGFuZGFyZCBKYXZhIE5hcnJvd2luZyBQcmltaXRpdmUgQ29udmVyc2lvbgotICAgICAgLy8gU2VlIGh0dHA6Ly9qYXZhLnN1bi5jb20vZG9jcy9ib29rcy9qbHMvaHRtbC81LmRvYy5odG1sIzE3NTY3MgotICAgICAgcmV0dXJuIG5ldyBMb25nKChsb25nKW51bSk7Ci0gICAgfQotICAgIGVsc2UgaWYoamF2YUNsYXNzID09IEludGVnZXIuVFlQRSkKLSAgICB7Ci0gICAgICAvLyBVc2Ugc3RhbmRhcmQgSmF2YSBOYXJyb3dpbmcgUHJpbWl0aXZlIENvbnZlcnNpb24KLSAgICAgIC8vIFNlZSBodHRwOi8vamF2YS5zdW4uY29tL2RvY3MvYm9va3MvamxzL2h0bWwvNS5kb2MuaHRtbCMxNzU2NzIKLSAgICAgIHJldHVybiBuZXcgSW50ZWdlcigoaW50KW51bSk7Ci0gICAgfQotICAgIGVsc2UgaWYoamF2YUNsYXNzID09IFNob3J0LlRZUEUpCi0gICAgewotICAgICAgLy8gVXNlIHN0YW5kYXJkIEphdmEgTmFycm93aW5nIFByaW1pdGl2ZSBDb252ZXJzaW9uCi0gICAgICAvLyBTZWUgaHR0cDovL2phdmEuc3VuLmNvbS9kb2NzL2Jvb2tzL2pscy9odG1sLzUuZG9jLmh0bWwjMTc1NjcyCi0gICAgICByZXR1cm4gbmV3IFNob3J0KChzaG9ydCludW0pOwotICAgIH0KLSAgICBlbHNlIGlmKGphdmFDbGFzcyA9PSBDaGFyYWN0ZXIuVFlQRSkKLSAgICB7Ci0gICAgICAvLyBVc2Ugc3RhbmRhcmQgSmF2YSBOYXJyb3dpbmcgUHJpbWl0aXZlIENvbnZlcnNpb24KLSAgICAgIC8vIFNlZSBodHRwOi8vamF2YS5zdW4uY29tL2RvY3MvYm9va3MvamxzL2h0bWwvNS5kb2MuaHRtbCMxNzU2NzIKLSAgICAgIHJldHVybiBuZXcgQ2hhcmFjdGVyKChjaGFyKW51bSk7Ci0gICAgfQotICAgIGVsc2UgaWYoamF2YUNsYXNzID09IEJ5dGUuVFlQRSkKLSAgICB7Ci0gICAgICAvLyBVc2Ugc3RhbmRhcmQgSmF2YSBOYXJyb3dpbmcgUHJpbWl0aXZlIENvbnZlcnNpb24KLSAgICAgIC8vIFNlZSBodHRwOi8vamF2YS5zdW4uY29tL2RvY3MvYm9va3MvamxzL2h0bWwvNS5kb2MuaHRtbCMxNzU2NzIKLSAgICAgIHJldHVybiBuZXcgQnl0ZSgoYnl0ZSludW0pOwotICAgIH0KLSAgICBlbHNlICAgICAvLyBTb21lIG90aGVyIHR5cGUgb2Ygb2JqZWN0Ci0gICAgewotICAgICAgcmV0dXJuIG5ldyBEb3VibGUobnVtKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBGb3JtYXQgdGhlIG1lc3NhZ2UgZm9yIHRoZSBOb1N1Y2hNZXRob2RFeGNlcHRpb24gY29udGFpbmluZyAKLSAgICogYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbWV0aG9kIHdlJ3JlIGxvb2tpbmcgZm9yLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGVyclN0cmluZyhTdHJpbmcgY2FsbFR5cGUsICAgIC8vICJmdW5jdGlvbiIgb3IgImVsZW1lbnQiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNlYXJjaFR5cGUsICAvLyAibWV0aG9kIiBvciAiY29uc3RydWN0b3IiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgY2xhc3NPYmosCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZ1bmNOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzZWFyY2hNZXRob2QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0W10geHNsdEFyZ3MpCi0gIHsKLSAgICBTdHJpbmcgcmVzdWx0U3RyaW5nID0gIkZvciBleHRlbnNpb24gIiArIGNhbGxUeXBlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiLCBjb3VsZCBub3QgZmluZCAiICsgc2VhcmNoVHlwZSArICIgIjsKLSAgICBzd2l0Y2ggKHNlYXJjaE1ldGhvZCkKLSAgICB7Ci0gICAgICBjYXNlIFNUQVRJQ19PTkxZOgotICAgICAgICByZXR1cm4gcmVzdWx0U3RyaW5nICsgInN0YXRpYyAiICsgY2xhc3NPYmouZ2V0TmFtZSgpICsgIi4iIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZnVuY05hbWUgKyAiKFtFeHByZXNzaW9uQ29udGV4dCxdICIgKyBlcnJBcmdzKHhzbHRBcmdzLCAwKSArICIpLiI7Ci0KLSAgICAgIGNhc2UgSU5TVEFOQ0VfT05MWToKLSAgICAgICAgcmV0dXJuIHJlc3VsdFN0cmluZyArIGNsYXNzT2JqLmdldE5hbWUoKSArICIuIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZnVuY05hbWUgKyAiKFtFeHByZXNzaW9uQ29udGV4dCxdICIgKyBlcnJBcmdzKHhzbHRBcmdzLCAwKSArICIpLiI7Ci0KLSAgICAgIGNhc2UgU1RBVElDX0FORF9JTlNUQU5DRToKLSAgICAgICAgcmV0dXJuIHJlc3VsdFN0cmluZyArIGNsYXNzT2JqLmdldE5hbWUoKSArICIuIiArIGZ1bmNOYW1lICsgIihbRXhwcmVzc2lvbkNvbnRleHQsXSAiICsgZXJyQXJncyh4c2x0QXJncywgMCkgKyAiKS5cbiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJDaGVja2VkIGJvdGggc3RhdGljIGFuZCBpbnN0YW5jZSBtZXRob2RzLiI7Ci0KLSAgICAgIGNhc2UgRFlOQU1JQzoKLSAgICAgICAgcmV0dXJuIHJlc3VsdFN0cmluZyArICJzdGF0aWMgIiArIGNsYXNzT2JqLmdldE5hbWUoKSArICIuIiArIGZ1bmNOYW1lCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKFtFeHByZXNzaW9uQ29udGV4dCwgXSIgKyBlcnJBcmdzKHhzbHRBcmdzLCAwKSArICIpIG5vclxuIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2xhc3NPYmogKyAiLiIgKyBmdW5jTmFtZSArICIoW0V4cHJlc3Npb25Db250ZXh0LF0gIiArIGVyckFyZ3MoeHNsdEFyZ3MsIDEpICsgIikuIjsKLQotICAgICAgZGVmYXVsdDoKLSAgICAgICAgaWYgKGNhbGxUeXBlLmVxdWFscygiZnVuY3Rpb24iKSkgICAgICAvLyBtdXN0IGJlIGEgY29uc3RydWN0b3IKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiByZXN1bHRTdHJpbmcgKyBjbGFzc09iai5nZXROYW1lKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIoW0V4cHJlc3Npb25Db250ZXh0LF0gIiArIGVyckFyZ3MoeHNsdEFyZ3MsIDApICsgIikuIjsKLSAgICAgICAgfQotICAgICAgICBlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG11c3QgYmUgYW4gZWxlbWVudCBjYWxsCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gcmVzdWx0U3RyaW5nICsgY2xhc3NPYmouZ2V0TmFtZSgpICsgIi4iICsgZnVuY05hbWUKLSAgICAgICAgICAgICAgICAgICAgKyAiKG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5YU0xQcm9jZXNzb3JDb250ZXh0LCAiCi0gICAgICAgICAgICAgICAgICAgICsgIm9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1FeHRlbnNpb25DYWxsKS4iOwotICAgICAgICB9Ci0gICAgfQotICAgIAotICB9Ci0KLQotICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZXJyQXJncyhPYmplY3RbXSB4c2x0QXJncywgaW50IHN0YXJ0aW5nQXJnKQotICB7Ci0gICAgU3RyaW5nQnVmZmVyIHJldHVybkFyZ3MgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgZm9yIChpbnQgaSA9IHN0YXJ0aW5nQXJnOyBpIDwgeHNsdEFyZ3MubGVuZ3RoOyBpKyspCi0gICAgewotICAgICAgaWYgKGkgIT0gc3RhcnRpbmdBcmcpCi0gICAgICAgIHJldHVybkFyZ3MuYXBwZW5kKCIsICIpOwotICAgICAgaWYgKHhzbHRBcmdzW2ldIGluc3RhbmNlb2YgWE9iamVjdCkKLSAgICAgICAgcmV0dXJuQXJncy5hcHBlbmQoKChYT2JqZWN0KSB4c2x0QXJnc1tpXSkuZ2V0VHlwZVN0cmluZygpKTsgICAgICAKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuQXJncy5hcHBlbmQoeHNsdEFyZ3NbaV0uZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOwotICAgIH0KLSAgICByZXR1cm4gcmV0dXJuQXJncy50b1N0cmluZygpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvWFNMUHJvY2Vzc29yQ29udGV4dC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9YU0xQcm9jZXNzb3JDb250ZXh0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRhOTM4ZWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9YU0xQcm9jZXNzb3JDb250ZXh0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNTEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlJlc3VsdFRyZWVIYW5kbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuQ2xvbmVyVG9SZXN1bHRUcmVlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuRGVzY2VuZGFudEl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5PbmVTdGVwSXRlcmF0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi0vLyBpbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Lio7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFByb3ZpZGVzIHRyYW5zZm9ybWVyIGNvbnRleHQgdG8gYmUgcGFzc2VkIHRvIGFuIGV4dGVuc2lvbiBlbGVtZW50LgotICoKLSAqIEBhdXRob3IgU2Fuaml2YSBXZWVyYXdhcmFuYSAoc2Fuaml2YUB3YXRzb24uaWJtLmNvbSkKLSAqLwotcHVibGljIGNsYXNzIFhTTFByb2Nlc3NvckNvbnRleHQKLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgcHJvY2Vzc29yIGNvbnRleHQgdG8gYmUgcGFzc2VkIHRvIGFuIGV4dGVuc2lvbi4KLSAgICogKE5vdGljZSBpdCBpcyBhIHBhY2thZ2Utb25seSBjb25zdHJ1Y3RvcikuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCB0cmFuc2Zvcm1lciBpbnN0YW5jZQotICAgKiBAcGFyYW0gc3R5bGVzaGVldFRyZWUgVGhlIG93bmluZyBzdHlsZXNoZWV0Ci0gICAqIEBwYXJhbSBzb3VyY2VUcmVlIFRoZSBzb3VyY2UgZG9jdW1lbnQKLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgVGhlIGN1cnJlbnQgc291cmNlIG5vZGUKLSAgICogQHBhcmFtIG1vZGUgdGhlIGN1cnJlbnQgbW9kZSBiZWluZyBleGVjdXRlZC4KLSAgICovCi0gIHB1YmxpYyBYU0xQcm9jZXNzb3JDb250ZXh0KFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0VHJlZSkKLSAgewotCi0gICAgdGhpcy50cmFuc2Zvcm1lciA9IHRyYW5zZm9ybWVyOwotICAgIHRoaXMuc3R5bGVzaGVldFRyZWUgPSBzdHlsZXNoZWV0VHJlZTsKLSAgICAvLyAlVEJEJQotICAgIG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0IHhjdHh0ID0gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgdGhpcy5tb2RlID0gdHJhbnNmb3JtZXIuZ2V0TW9kZSgpOwotICAgIHRoaXMuc291cmNlTm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgdGhpcy5zb3VyY2VUcmVlID0geGN0eHQuZ2V0RFRNKHRoaXMuc291cmNlTm9kZSk7Ci0gIH0KLQotICAvKiogQW4gaW5zdGFuY2Ugb2YgYSB0cmFuc2Zvcm1lciAgICAgICAgICAqLwotICBwcml2YXRlIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcjsKLQotICAvKioKLSAgICogR2V0IHRoZSB0cmFuc2Zvcm1lci4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtZXIgaW5zdGFuY2UgZm9yIHRoaXMgY29udGV4dAotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVySW1wbCBnZXRUcmFuc2Zvcm1lcigpCi0gIHsKLSAgICByZXR1cm4gdHJhbnNmb3JtZXI7Ci0gIH0KLQotICAvKiogVGhlIG93bmluZyBzdHlsZXNoZWV0IGZvciB0aGlzIGNvbnRleHQgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBTdHlsZXNoZWV0IHN0eWxlc2hlZXRUcmVlOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIFN0eWxlc2hlZXQgYmVpbmcgZXhlY3V0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFN0eWxlc2hlZXQgYmVpbmcgZXhlY3V0ZWQuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldCBnZXRTdHlsZXNoZWV0KCkKLSAgewotICAgIHJldHVybiBzdHlsZXNoZWV0VHJlZTsKLSAgfQotCi0gIC8qKiAgVGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlIGJlaW5nIGV4ZWN1dGVkLiAgICAgICAgKi8KLSAgcHJpdmF0ZSBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNIHNvdXJjZVRyZWU7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUgYmVpbmcgZXhlY3V0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlIGJlaW5nIGV4ZWN1dGVkLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0U291cmNlVHJlZSgpCi0gIHsKLSAgICByZXR1cm4gc291cmNlVHJlZS5nZXROb2RlKHNvdXJjZVRyZWUuZ2V0RG9jdW1lbnQoKSk7Ci0gIH0KLQotICAvKiogdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLiAgICAgICAgICAqLwotICBwcml2YXRlIGludCBzb3VyY2VOb2RlOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBvcmcudzNjLmRvbS5Ob2RlIGdldENvbnRleHROb2RlKCkKLSAgewotICAgIHJldHVybiBzb3VyY2VUcmVlLmdldE5vZGUoc291cmNlTm9kZSk7Ci0gIH0KLQotICAvKiogdGhlIGN1cnJlbnQgbW9kZSBiZWluZyBleGVjdXRlZC4gICAgICAgICAqLwotICBwcml2YXRlIFFOYW1lIG1vZGU7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBtb2RlIGJlaW5nIGV4ZWN1dGVkLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IG1vZGUgYmVpbmcgZXhlY3V0ZWQuCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TW9kZSgpCi0gIHsKLSAgICByZXR1cm4gbW9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBPdXRwdXQgYW4gb2JqZWN0IHRvIHRoZSByZXN1bHQgdHJlZSBieSBkb2luZyB0aGUgcmlnaHQgY29udmVyc2lvbnMuCi0gICAqIFRoaXMgaXMgcHVibGljIGZvciBhY2Nlc3MgYnkgZXh0ZW5zaW9ucy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0eWxlc2hlZXRUcmVlIFRoZSBvd25pbmcgc3R5bGVzaGVldAotICAgKiBAcGFyYW0gb2JqIHRoZSBKYXZhIG9iamVjdCB0byBvdXRwdXQuIElmIGl0cyBvZiBhbiBYPHNvbWV0aGluZz4gdHlwZQotICAgKiAgICAgICAgdGhlbiB0aGF0IGNvbnZlcnNpb24gaXMgZG9uZSBmaXJzdCBhbmQgdGhlbiBzZW50IG91dC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKiBAdGhyb3dzIGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgb3V0cHV0VG9SZXN1bHRUcmVlKFN0eWxlc2hlZXQgc3R5bGVzaGVldFRyZWUsIE9iamVjdCBvYmopCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uLCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24sCi0gICAgICAgICAgICAgICAgIGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uLCBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFJlc3VsdFRyZWVIYW5kbGVyIHJ0cmVlSGFuZGxlciA9IHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCk7Ci0gICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICAgIFhPYmplY3QgdmFsdWU7Ci0KLSAgICAgIC8vIE1ha2UgdGhlIHJldHVybiBvYmplY3QgaW50byBhbiBYT2JqZWN0IGJlY2F1c2UgaXQKLSAgICAgIC8vIHdpbGwgYmUgZWFzaWVyIGJlbG93LiAgT25lIG9mIHRoZSByZWFzb25zIHRvIGRvIHRoaXMKLSAgICAgIC8vIGlzIHRvIGtlZXAgYWxsIHRoZSBjb252ZXJzaW9uIGZ1bmN0aW9uYWxpdHkgaW4gdGhlCi0gICAgICAvLyBYT2JqZWN0IGNsYXNzZXMuCi0gICAgICBpZiAob2JqIGluc3RhbmNlb2YgWE9iamVjdCkKLSAgICAgIHsKLSAgICAgICAgdmFsdWUgPSAoWE9iamVjdCkgb2JqOwotICAgICAgfQotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgU3RyaW5nKQotICAgICAgewotICAgICAgICB2YWx1ZSA9IG5ldyBYU3RyaW5nKChTdHJpbmcpIG9iaik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBCb29sZWFuKQotICAgICAgewotICAgICAgICB2YWx1ZSA9IG5ldyBYQm9vbGVhbigoKEJvb2xlYW4pIG9iaikuYm9vbGVhblZhbHVlKCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRG91YmxlKQotICAgICAgewotICAgICAgICB2YWx1ZSA9IG5ldyBYTnVtYmVyKCgoRG91YmxlKSBvYmopLmRvdWJsZVZhbHVlKCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkKLSAgICAgIHsKLSAgICAgICAgaW50IGhhbmRsZSA9IHhjdHh0LmdldERUTUhhbmRsZUZyb21Ob2RlKChEb2N1bWVudEZyYWdtZW50KW9iaik7Ci0gICAgICAgIAotICAgICAgICB2YWx1ZSA9IG5ldyBYUlRyZWVGcmFnKGhhbmRsZSwgeGN0eHQpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRFRNKQotICAgICAgewotICAgICAgICBEVE0gZHRtID0gKERUTSlvYmo7Ci0gICAgICAgIERUTUl0ZXJhdG9yIGl0ZXJhdG9yID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcigpOwotICAgICAgICBpdGVyYXRvci5zZXRSb290KGR0bS5nZXREb2N1bWVudCgpLCB4Y3R4dCk7Ci0gICAgICAgIHZhbHVlID0gbmV3IFhOb2RlU2V0KGl0ZXJhdG9yKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERUTUF4aXNJdGVyYXRvcikKLSAgICAgIHsKLSAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIgPSAoRFRNQXhpc0l0ZXJhdG9yKW9iajsKLSAgICAgICAgRFRNSXRlcmF0b3IgaXRlcmF0b3IgPSBuZXcgT25lU3RlcEl0ZXJhdG9yKGl0ZXIsIC0xKTsKLSAgICAgICAgdmFsdWUgPSBuZXcgWE5vZGVTZXQoaXRlcmF0b3IpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRFRNSXRlcmF0b3IpCi0gICAgICB7Ci0gICAgICAgIHZhbHVlID0gbmV3IFhOb2RlU2V0KChEVE1JdGVyYXRvcikgb2JqKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikKLSAgICAgIHsKLSAgICAgICAgdmFsdWUgPSBuZXcgWE5vZGVTZXQobmV3IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTSgoKE5vZGVJdGVyYXRvcilvYmopLCB4Y3R4dCkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2Ygb3JnLnczYy5kb20uTm9kZSkKLSAgICAgIHsKLSAgICAgICAgdmFsdWUgPQotICAgICAgICAgIG5ldyBYTm9kZVNldCh4Y3R4dC5nZXREVE1IYW5kbGVGcm9tTm9kZSgob3JnLnczYy5kb20uTm9kZSkgb2JqKSwKLSAgICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0RFRNTWFuYWdlcigpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgdmFsdWUgPSBuZXcgWFN0cmluZyhvYmoudG9TdHJpbmcoKSk7Ci0gICAgICB9Ci0KLSAgICAgIGludCB0eXBlID0gdmFsdWUuZ2V0VHlwZSgpOwotICAgICAgU3RyaW5nIHM7Ci0KLSAgICAgIHN3aXRjaCAodHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19CT09MRUFOIDoKLSAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19OVU1CRVIgOgotICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX1NUUklORyA6Ci0gICAgICAgIHMgPSB2YWx1ZS5zdHIoKTsKLQotICAgICAgICBydHJlZUhhbmRsZXIuY2hhcmFjdGVycyhzLnRvQ2hhckFycmF5KCksIDAsIHMubGVuZ3RoKCkpOwotICAgICAgICBicmVhazsKLQotICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX05PREVTRVQgOiAgLy8gU3lzdGVtLm91dC5wcmludGxuKHZhbHVlKTsKLSAgICAgICAgRFRNSXRlcmF0b3IgbmwgPSB2YWx1ZS5pdGVyKCk7Ci0gICAgICAgIAotICAgICAgICBpbnQgcG9zOwotCi0gICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAocG9zID0gbmwubmV4dE5vZGUoKSkpCi0gICAgICAgIHsKLSAgICAgICAgICBEVE0gZHRtID0gbmwuZ2V0RFRNKHBvcyk7Ci0gICAgICAgICAgaW50IHRvcCA9IHBvczsKLQotICAgICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSBwb3MpCi0gICAgICAgICAgewotICAgICAgICAgICAgcnRyZWVIYW5kbGVyLmZsdXNoUGVuZGluZygpOwotICAgICAgICAgICAgQ2xvbmVyVG9SZXN1bHRUcmVlLmNsb25lVG9SZXN1bHRUcmVlKHBvcywgZHRtLmdldE5vZGVUeXBlKHBvcyksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRtLCBydHJlZUhhbmRsZXIsIHRydWUpOwotCi0gICAgICAgICAgICBpbnQgbmV4dE5vZGUgPSBkdG0uZ2V0Rmlyc3RDaGlsZChwb3MpOwotCi0gICAgICAgICAgICB3aGlsZSAoRFRNLk5VTEwgPT0gbmV4dE5vZGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IGR0bS5nZXROb2RlVHlwZShwb3MpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcnRyZWVIYW5kbGVyLmVuZEVsZW1lbnQoIiIsICIiLCBkdG0uZ2V0Tm9kZU5hbWUocG9zKSk7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBpZiAodG9wID09IHBvcykKLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICBuZXh0Tm9kZSA9IGR0bS5nZXROZXh0U2libGluZyhwb3MpOwotCi0gICAgICAgICAgICAgIGlmIChEVE0uTlVMTCA9PSBuZXh0Tm9kZSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHBvcyA9IGR0bS5nZXRQYXJlbnQocG9zKTsKLQotICAgICAgICAgICAgICAgIGlmICh0b3AgPT0gcG9zKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IGR0bS5nZXROb2RlVHlwZShwb3MpKQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBydHJlZUhhbmRsZXIuZW5kRWxlbWVudCgiIiwgIiIsIGR0bS5nZXROb2RlTmFtZShwb3MpKTsKLSAgICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBEVE0uTlVMTDsKLQotICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHBvcyA9IG5leHROb2RlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19SVFJFRUZSQUcgOgotICAgICAgICBydHJlZUhhbmRsZXIub3V0cHV0UmVzdWx0VHJlZUZyYWdtZW50KHZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJIG5lZWQgYSAiTm9kZSB0cmFuc2Zvcm1Ob2RlIChOb2RlKSIgbWV0aG9kIHNvbWV3aGVyZSB0aGF0IHRoZQotICAgKiB1c2VyIGNhbiBjYWxsIHRvIHByb2Nlc3MgdGhlIHRyYW5zZm9ybWF0aW9uIG9mIGEgbm9kZSBidXQgbm90Ci0gICAqIHNlcmlhbGl6ZSBvdXQgYXV0b21hdGljYWxseS4gPz8/Pz8/Pz8/Pz8/Pz8/PwotICAgKgotICAgKiBEb2VzIEVsZW1UZW1wbGF0ZUVsZW1lbnQuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKCkgY3V0IGl0PyBJdCBzZW5kcwotICAgKiByZXN1bHRzIG91dCB0byB0aGUgc3RyZWFtIGRpcmVjdGx5LCBzbyB0aGF0IGNvdWxkIGJlIGEgcHJvYmxlbS4KLSAgICovCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL2V4dGVuc2lvbnMuZGZQYWNrYWdlIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9leHRlbnNpb25zLmRmUGFja2FnZQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTIxOGMyNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL2V4dGVuc2lvbnMuZGZQYWNrYWdlCisrKyAvZGV2L251bGwKQEAgLTEsMjIgKzAsMCBAQAotcGFja2FnZSBpZGNvd2M2d3QwMndhYzZ3dDlvc3c7Ci0KLS8qKgotQHZlcnNpb24gMi4wCi1AcGh5c2ljYWxQYWNrYWdlCi1AX19tb2RlbFR5cGUgZGlhZ3JhbSAKLSovCi1jbGFzcyBkaWFncmFtIHsKLX0vKioKLUBfX3RhZ3MKLUBzaGFwZVR5cGUgQ2xhc3NEaWFncmFtIAotKi8KLWNsYXNzIF9fdGFncyB7Ci19LyoqCi1AX19vcHRpb25zIAotKi8KLWNsYXNzIF9fb3B0aW9ucyB7Ci19LyoqCi1AX19wb3NpdGlvbnMgCi0qLwotY2xhc3MgX19wb3NpdGlvbnMgewotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdiZTMxOGMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw4ICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WGFsYW4gRXh0ZW5zaW9uIE1lY2hhbmlzbSBQYWNrYWdlLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkltcGxlbWVudGF0aW9uIG9mIFhhbGFuIEV4dGVuc2lvbiBNZWNoYW5pc20uPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9FeHRlbnNpb25zLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvRXh0ZW5zaW9ucy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMGVlZDg3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9FeHRlbnNpb25zLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWI7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRE9NSGVscGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuRXhwcmVzc2lvbkNvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotLy8gTm90ZTogd2Ugc2hvdWxkIGNvbnNpZGVyIGxvYWRpbmcgRW52aXJvbm1lbnRDaGVjayBhdCBydW50aW1lCi0vLyAgdG8gc2ltcGxpZnkgaW50ZXItcGFja2FnZSBkZXBlbmRlbmNpZXMgU2VwLTAxIC1zYwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdC5FbnZpcm9ubWVudENoZWNrOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyBjb250YWlucyBtYW55IG9mIHRoZSBYYWxhbi1zdXBwbGllZCBleHRlbnNpb25zLgotICogSXQgaXMgYWNjZXNzZWQgYnkgc3BlY2lmeWluZyBhIG5hbWVzcGFjZSBVUkkgYXMgZm9sbG93czoKLSAqIDxwcmU+Ci0gKiAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuIgotICogPC9wcmU+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFeHRlbnNpb25zCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEV4dGVuc2lvbnMKLSAgICoKLSAgICovCi0gIHByaXZhdGUgRXh0ZW5zaW9ucygpe30gIC8vIE1ha2Ugc3VyZSBjbGFzcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkCi0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGlzIGFuIGV4dGVuc2lvbiB0aGF0IGltcGxlbWVudHMgYXMgYSBYYWxhbiBleHRlbnNpb24KLSAgICogdGhlIG5vZGUtc2V0IGZ1bmN0aW9uIGFsc28gZm91bmQgaW4geHQgYW5kIHNheG9uLgotICAgKiBJZiB0aGUgYXJndW1lbnQgaXMgYSBSZXN1bHQgVHJlZSBGcmFnbWVudCwgdGhlbiA8Y29kZT5ub2Rlc2V0PC9jb2RlPgotICAgKiByZXR1cm5zIGEgbm9kZS1zZXQgY29uc2lzdGluZyBvZiBhIHNpbmdsZSByb290IG5vZGUgYXMgZGVzY3JpYmVkIGluCi0gICAqIHNlY3Rpb24gMTEuMSBvZiB0aGUgWFNMVCAxLjAgUmVjb21tZW5kYXRpb24uICBJZiB0aGUgYXJndW1lbnQgaXMgYQotICAgKiBub2RlLXNldCwgPGNvZGU+bm9kZXNldDwvY29kZT4gcmV0dXJucyBhIG5vZGUtc2V0LiAgSWYgdGhlIGFyZ3VtZW50Ci0gICAqIGlzIGEgc3RyaW5nLCBudW1iZXIsIG9yIGJvb2xlYW4sIHRoZW4gPGNvZGU+bm9kZXNldDwvY29kZT4gcmV0dXJucwotICAgKiBhIG5vZGUtc2V0IGNvbnNpc3Rpbmcgb2YgYSBzaW5nbGUgcm9vdCBub2RlIHdpdGggYSBzaW5nbGUgdGV4dCBub2RlCi0gICAqIGNoaWxkIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBYUGF0aCBzdHJpbmcoKSBmdW5jdGlvbiBvbiB0aGUKLSAgICogcGFzc2VkIHBhcmFtZXRlci4gIElmIHRoZSBhcmd1bWVudCBpcyBhbnl0aGluZyBlbHNlLCB0aGVuIGEgbm9kZS1zZXQKLSAgICogaXMgcmV0dXJuZWQgY29uc2lzdGluZyBvZiBhIHNpbmdsZSByb290IG5vZGUgd2l0aCBhIHNpbmdsZSB0ZXh0IG5vZGUKLSAgICogY2hpbGQgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIGphdmEgPGNvZGU+dG9TdHJpbmcoKTwvY29kZT4KLSAgICogbWV0aG9kIG9uIHRoZSBwYXNzZWQgYXJndW1lbnQuCi0gICAqIE1vc3Qgb2YgdGhlCi0gICAqIGFjdHVhbCB3b3JrIGhlcmUgaXMgZG9uZSBpbiA8Y29kZT5NZXRob2RSZXNvbHZlcjwvY29kZT4gYW5kCi0gICAqIDxjb2RlPlhSVHJlZUZyYWc8L2NvZGU+LgotICAgKiBAcGFyYW0gbXlQcm9jZXNzb3IgQ29udGV4dCBwYXNzZWQgYnkgdGhlIGV4dGVuc2lvbiBwcm9jZXNzb3IKLSAgICogQHBhcmFtIHJ0ZiBBcmd1bWVudCBpbiB0aGUgc3R5bGVzaGVldCB0byB0aGUgbm9kZXNldCBleHRlbnNpb24gZnVuY3Rpb24KLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlU2V0IG5vZGVzZXQoRXhwcmVzc2lvbkNvbnRleHQgbXlQcm9jZXNzb3IsIE9iamVjdCBydGYpCi0gIHsKLQotICAgIFN0cmluZyB0ZXh0Tm9kZVZhbHVlOwotCi0gICAgaWYgKHJ0ZiBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IE5vZGVTZXQoKE5vZGVJdGVyYXRvcikgcnRmKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChydGYgaW5zdGFuY2VvZiBTdHJpbmcpCi0gICAgICB7Ci0gICAgICAgIHRleHROb2RlVmFsdWUgPSAoU3RyaW5nKSBydGY7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChydGYgaW5zdGFuY2VvZiBCb29sZWFuKQotICAgICAgewotICAgICAgICB0ZXh0Tm9kZVZhbHVlID0gbmV3IFhCb29sZWFuKCgoQm9vbGVhbikgcnRmKS5ib29sZWFuVmFsdWUoKSkuc3RyKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChydGYgaW5zdGFuY2VvZiBEb3VibGUpCi0gICAgICB7Ci0gICAgICAgIHRleHROb2RlVmFsdWUgPSBuZXcgWE51bWJlcigoKERvdWJsZSkgcnRmKS5kb3VibGVWYWx1ZSgpKS5zdHIoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgdGV4dE5vZGVWYWx1ZSA9IHJ0Zi50b1N0cmluZygpOwotICAgICAgfQotCi0gICAgICAvLyBUaGlzIG5vIGxvbmdlciB3aWxsIHdvcmsgcmlnaHQgc2luY2UgdGhlIERUTS4KLSAgICAgIC8vIERvY3VtZW50IG15RG9jID0gbXlQcm9jZXNzb3IuZ2V0Q29udGV4dE5vZGUoKS5nZXRPd25lckRvY3VtZW50KCk7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkYmYgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgIERvY3VtZW50QnVpbGRlciBkYiA9IGRiZi5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLSAgICAgICAgRG9jdW1lbnQgbXlEb2MgPSBkYi5uZXdEb2N1bWVudCgpOwotICAgICAgICAKLSAgICAgICAgVGV4dCB0ZXh0Tm9kZSA9IG15RG9jLmNyZWF0ZVRleHROb2RlKHRleHROb2RlVmFsdWUpOwotICAgICAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWcgPSBteURvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0gIAotICAgICAgICBkb2NGcmFnLmFwcGVuZENoaWxkKHRleHROb2RlKTsKLSAgCi0gICAgICAgIHJldHVybiBuZXcgTm9kZVNldChkb2NGcmFnKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24ocGNlKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW50ZXJzZWN0aW9uIG9mIHR3byBub2RlLXNldHMuCi0gICAqIEBwYXJhbSBuMSBOb2RlSXRlcmF0b3IgZm9yIGZpcnN0IG5vZGUtc2V0Ci0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBuaTEKLSAgICogQHBhcmFtIG5pMiBOb2RlSXRlcmF0b3IgZm9yIHNlY29uZCBub2RlLXNldAotICAgKiBAcmV0dXJuIGEgTm9kZVNldCBjb250YWluaW5nIHRoZSBub2RlcyBpbiBuaTEgdGhhdCBhcmUgYWxzbwotICAgKiBpbiBuaTIKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVTZXQgaW50ZXJzZWN0aW9uKE5vZGVJdGVyYXRvciBuaTEsIE5vZGVJdGVyYXRvciBuaTIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgTm9kZVNldCBuczEgPSBuZXcgTm9kZVNldChuaTEpOwotICAgIE5vZGVTZXQgbnMyID0gbmV3IE5vZGVTZXQobmkyKTsKLSAgICBOb2RlU2V0IGludGVyID0gbmV3IE5vZGVTZXQoKTsKLQotICAgIGludGVyLnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5zMS5nZXRMZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbiA9IG5zMS5lbGVtZW50QXQoaSk7Ci0KLSAgICAgIGlmIChuczIuY29udGFpbnMobikpCi0gICAgICAgIGludGVyLmFkZEVsZW1lbnQobik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGludGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gbm9kZS1zZXRzLgotICAgKiBAcGFyYW0gbjEgTm9kZUl0ZXJhdG9yIGZvciBmaXJzdCBub2RlLXNldAotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gbmkxCi0gICAqIEBwYXJhbSBuaTIgTm9kZUl0ZXJhdG9yIGZvciBzZWNvbmQgbm9kZS1zZXQKLSAgICogQHJldHVybiBhIE5vZGVTZXQgY29udGFpbmluZyB0aGUgbm9kZXMgaW4gbmkxIHRoYXQgYXJlIG5vdAotICAgKiBpbiBuaTIKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVTZXQgZGlmZmVyZW5jZShOb2RlSXRlcmF0b3IgbmkxLCBOb2RlSXRlcmF0b3IgbmkyKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIE5vZGVTZXQgbnMxID0gbmV3IE5vZGVTZXQobmkxKTsKLSAgICBOb2RlU2V0IG5zMiA9IG5ldyBOb2RlU2V0KG5pMik7Ci0KLSAgICAvLyBOb2RlU2V0IGludGVyPSBuZXcgTm9kZVNldCgpOwotICAgIE5vZGVTZXQgZGlmZiA9IG5ldyBOb2RlU2V0KCk7Ci0KLSAgICBkaWZmLnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5zMS5nZXRMZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbiA9IG5zMS5lbGVtZW50QXQoaSk7Ci0KLSAgICAgIGlmICghbnMyLmNvbnRhaW5zKG4pKQotICAgICAgICBkaWZmLmFkZEVsZW1lbnQobik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGRpZmY7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBub2RlLXNldCBjb250YWluaW5nIGRpc3RpbmN0IHN0cmluZyB2YWx1ZXMuCi0gICAqIEBwYXJhbSBuaSBOb2RlSXRlcmF0b3IgZm9yIG5vZGUtc2V0Ci0gICAqIEByZXR1cm4gYSBOb2RlU2V0IHdpdGggbm9kZXMgZnJvbSBuaSBjb250YWluaW5nIGRpc3RpbmN0IHN0cmluZyB2YWx1ZXMuCi0gICAqIEluIG90aGVyIHdvcmRzLCBpZiBtb3JlIHRoYW4gb25lIG5vZGUgaW4gbmkgY29udGFpbnMgdGhlIHNhbWUgc3RyaW5nIHZhbHVlLAotICAgKiBvbmx5IGluY2x1ZGUgdGhlIGZpcnN0IHN1Y2ggbm9kZSBmb3VuZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVTZXQgZGlzdGluY3QoRXhwcmVzc2lvbkNvbnRleHQgbXlDb250ZXh0LCBOb2RlSXRlcmF0b3IgbmkpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU2V0IHVwIG91ciByZXN1bHRpbmcgTm9kZVNldCBhbmQgdGhlIGhhc2h0YWJsZSB3ZSB1c2UgdG8ga2VlcCB0cmFjayBvZiBkdXBsaWNhdGUKLSAgICAvLyBzdHJpbmdzLgotCi0gICAgTm9kZVNldCBkaXN0ID0gbmV3IE5vZGVTZXQoKTsKLSAgICBkaXN0LnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0KLSAgICBIYXNodGFibGUgc3RyaW5nVGFibGUgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICBOb2RlIGN1cnJOb2RlID0gbmkubmV4dE5vZGUoKTsKLQotICAgIHdoaWxlIChjdXJyTm9kZSAhPSBudWxsKQotICAgIHsKLSAgICAgIFN0cmluZyBrZXkgPSBteUNvbnRleHQudG9TdHJpbmcoY3Vyck5vZGUpOwotCi0gICAgICBpZiAoIXN0cmluZ1RhYmxlLmNvbnRhaW5zS2V5KGtleSkpCi0gICAgICB7Ci0gICAgICAgIHN0cmluZ1RhYmxlLnB1dChrZXksIGN1cnJOb2RlKTsKLSAgICAgICAgZGlzdC5hZGRFbGVtZW50KGN1cnJOb2RlKTsKLSAgICAgIH0KLSAgICAgIGN1cnJOb2RlID0gbmkubmV4dE5vZGUoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZGlzdDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgb2YgYm90aCBub2RlLXNldHMgY29udGFpbiB0aGUgc2FtZSBzZXQgb2Ygbm9kZXMuCi0gICAqIEBwYXJhbSBuMSBOb2RlSXRlcmF0b3IgZm9yIGZpcnN0IG5vZGUtc2V0Ci0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBuaTEKLSAgICogQHBhcmFtIG5pMiBOb2RlSXRlcmF0b3IgZm9yIHNlY29uZCBub2RlLXNldAotICAgKiBAcmV0dXJuIHRydWUgaWYgbmkxIGFuZCBuaTIgY29udGFpbiBleGFjdGx5IHRoZSBzYW1lIHNldCBvZiBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNTYW1lTm9kZXMoTm9kZUl0ZXJhdG9yIG5pMSwgTm9kZUl0ZXJhdG9yIG5pMikKLSAgewotCi0gICAgTm9kZVNldCBuczEgPSBuZXcgTm9kZVNldChuaTEpOwotICAgIE5vZGVTZXQgbnMyID0gbmV3IE5vZGVTZXQobmkyKTsKLQotICAgIGlmIChuczEuZ2V0TGVuZ3RoKCkgIT0gbnMyLmdldExlbmd0aCgpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuczEuZ2V0TGVuZ3RoKCk7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG4gPSBuczEuZWxlbWVudEF0KGkpOwotCi0gICAgICBpZiAoIW5zMi5jb250YWlucyhuKSkKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIHRoZSBhcmd1bWVudCBhcyBhIHN0cmluZyBjb250YWluaW5nCi0gICAqIGFuIFhQYXRoIGV4cHJlc3Npb24uICBVc2VkIHdoZXJlIHRoZSBYUGF0aCBleHByZXNzaW9uIGlzIG5vdCBrbm93biB1bnRpbAotICAgKiBydW4tdGltZS4gIFRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZCBhcyBpZiB0aGUgcnVuLXRpbWUgdmFsdWUgb2YgdGhlCi0gICAqIGFyZ3VtZW50IGFwcGVhcmVkIGluIHBsYWNlIG9mIHRoZSBldmFsdWF0ZSBmdW5jdGlvbiBjYWxsIGF0IGNvbXBpbGUgdGltZS4KLSAgICogQHBhcmFtIG15Q29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gcGFzc2VkIGluIGJ5IHRoZQotICAgKiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiBtZWNoYW5pc20uICBUaGlzIG11c3QgYmUgYW4gWFBhdGhDb250ZXh0LgotICAgKiBAcGFyYW0geHBhdGhFeHRyIFRoZSBYUGF0aCBleHByZXNzaW9uIHRvIGJlIGV2YWx1YXRlZC4KLSAgICogTkVFRFNET0MgQHBhcmFtIHhwYXRoRXhwcgotICAgKiBAcmV0dXJuIHRoZSBYT2JqZWN0IHJlc3VsdGluZyBmcm9tIGV2YWx1YXRpbmcgdGhlIFhQYXRoCi0gICAqCi0gICAqIEB0aHJvd3MgRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhPYmplY3QgZXZhbHVhdGUoCi0gICAgICAgICAgRXhwcmVzc2lvbkNvbnRleHQgbXlDb250ZXh0LCBTdHJpbmcgeHBhdGhFeHByKQotICAgICAgICAgICAgdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiwgRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChteUNvbnRleHQgaW5zdGFuY2VvZiBYUGF0aENvbnRleHQuWFBhdGhFeHByZXNzaW9uQ29udGV4dCkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0ID0KLSAgICAgICAgICAgICAgICAgICAgKChYUGF0aENvbnRleHQuWFBhdGhFeHByZXNzaW9uQ29udGV4dCkgbXlDb250ZXh0KS5nZXRYUGF0aENvbnRleHQoKTsKLSAgICAgICAgWFBhdGggZHluYW1pY1hQYXRoID0gbmV3IFhQYXRoKHhwYXRoRXhwciwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGguU0VMRUNUKTsKLQotICAgICAgICByZXR1cm4gZHluYW1pY1hQYXRoLmV4ZWN1dGUoeGN0eHQsIG15Q29udGV4dC5nZXRDb250ZXh0Tm9kZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgZTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VELCBuZXcgT2JqZWN0W117bXlDb250ZXh0IH0pKTsgLy8iSW52YWxpZCBjb250ZXh0IHBhc3NlZCB0byBldmFsdWF0ZSAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBteUNvbnRleHQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBOb2RlU2V0IGNvbnRhaW5pbmcgb25lIHRleHQgbm9kZSBmb3IgZWFjaCB0b2tlbiBpbiB0aGUgZmlyc3QgYXJndW1lbnQuCi0gICAqIERlbGltaXRlcnMgYXJlIHNwZWNpZmllZCBpbiB0aGUgc2Vjb25kIGFyZ3VtZW50LgotICAgKiBUb2tlbnMgYXJlIGRldGVybWluZWQgYnkgYSBjYWxsIHRvIDxjb2RlPlN0cmluZ1Rva2VuaXplcjwvY29kZT4uCi0gICAqIElmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgY29udGFpbnMgb25seSBkZWxpbWl0ZXJzLCB0aGUgcmVzdWx0Ci0gICAqIHdpbGwgYmUgYW4gZW1wdHkgTm9kZVNldC4KLSAgICogQ29udHJpYnV0ZWQgdG8gWGFsYW5KMSBieSA8YSBocmVmPSJtYWlsdG86YmVub2l0LmNlcnJpbmFAd3JpdGVtZS5jb20iPkJlbm9pdCBDZXJyaW5hPC9hPi4KLSAgICogQHBhcmFtIG15Q29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gcGFzc2VkIGluIGJ5IHRoZQotICAgKiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiBtZWNoYW5pc20uICBUaGlzIG11c3QgYmUgYW4gWFBhdGhDb250ZXh0LgotICAgKiBAcGFyYW0gdG9Ub2tlbml6ZSBUaGUgc3RyaW5nIHRvIGJlIHNwbGl0IGludG8gdGV4dCB0b2tlbnMuCi0gICAqIEBwYXJhbSBkZWxpbXMgVGhlIGRlbGltaXRlcnMgdG8gdXNlLgotICAgKiBAcmV0dXJuIGEgTm9kZVNldCBhcyBkZXNjcmliZWQgYWJvdmUuCi0gICAqCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVTZXQgdG9rZW5pemUoRXhwcmVzc2lvbkNvbnRleHQgbXlDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRvVG9rZW5pemUsIFN0cmluZyBkZWxpbXMpCi0gIHsKLQotICAgIERvY3VtZW50IGxEb2M7Ci0KLSAgICAvLyBEb2N1bWVudCBsRG9jID0gbXlDb250ZXh0LmdldENvbnRleHROb2RlKCkuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgIHRyeQotICAgIHsKLSAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgbERvYyA9IGRiLm5ld0RvY3VtZW50KCk7Ci0gICAgfQotICAgIGNhdGNoKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihwY2UpOwotICAgIH0KLQotICAgIFN0cmluZ1Rva2VuaXplciBsVG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih0b1Rva2VuaXplLCBkZWxpbXMpOwotICAgIE5vZGVTZXQgcmVzdWx0U2V0ID0gbmV3IE5vZGVTZXQoKTsKLQotICAgIHdoaWxlIChsVG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSkKLSAgICB7Ci0gICAgICByZXN1bHRTZXQuYWRkTm9kZShsRG9jLmNyZWF0ZVRleHROb2RlKGxUb2tlbml6ZXIubmV4dFRva2VuKCkpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0U2V0OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBOb2RlU2V0IGNvbnRhaW5pbmcgb25lIHRleHQgbm9kZSBmb3IgZWFjaCB0b2tlbiBpbiB0aGUgZmlyc3QgYXJndW1lbnQuCi0gICAqIERlbGltaXRlcnMgYXJlIHdoaXRlc3BhY2UuICBUaGF0IGlzLCB0aGUgZGVsaW1pdGVycyB0aGF0IGFyZSB1c2VkIGFyZSB0YWIgKCYjeDA5KSwKLSAgICogbGluZWZlZWQgKCYjeDBBKSwgcmV0dXJuICgmI3gwRCksIGFuZCBzcGFjZSAoJiN4MjApLgotICAgKiBUb2tlbnMgYXJlIGRldGVybWluZWQgYnkgYSBjYWxsIHRvIDxjb2RlPlN0cmluZ1Rva2VuaXplcjwvY29kZT4uCi0gICAqIElmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgY29udGFpbnMgb25seSBkZWxpbWl0ZXJzLCB0aGUgcmVzdWx0Ci0gICAqIHdpbGwgYmUgYW4gZW1wdHkgTm9kZVNldC4KLSAgICogQ29udHJpYnV0ZWQgdG8gWGFsYW5KMSBieSA8YSBocmVmPSJtYWlsdG86YmVub2l0LmNlcnJpbmFAd3JpdGVtZS5jb20iPkJlbm9pdCBDZXJyaW5hPC9hPi4KLSAgICogQHBhcmFtIG15Q29udGV4dCBhbiA8Y29kZT5FeHByZXNzaW9uQ29udGV4dDwvY29kZT4gcGFzc2VkIGluIGJ5IHRoZQotICAgKiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiBtZWNoYW5pc20uICBUaGlzIG11c3QgYmUgYW4gWFBhdGhDb250ZXh0LgotICAgKiBAcGFyYW0gdG9Ub2tlbml6ZSBUaGUgc3RyaW5nIHRvIGJlIHNwbGl0IGludG8gdGV4dCB0b2tlbnMuCi0gICAqIEByZXR1cm4gYSBOb2RlU2V0IGFzIGRlc2NyaWJlZCBhYm92ZS4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZVNldCB0b2tlbml6ZShFeHByZXNzaW9uQ29udGV4dCBteUNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdG9Ub2tlbml6ZSkKLSAgewotICAgIHJldHVybiB0b2tlbml6ZShteUNvbnRleHQsIHRvVG9rZW5pemUsICIgXHRcblxyIik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGEgTm9kZSBvZiBiYXNpYyBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24gZnJvbSB0aGUgCi0gICAqIEVudmlyb25tZW50Q2hlY2sgdXRpbGl0eSBhYm91dCB0aGUgSmF2YSBlbnZpcm9ubWVudC4KLSAgICoKLSAgICogPHA+U2ltcGx5IGNhbGxzIHRoZSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi54c2x0LkVudmlyb25tZW50Q2hlY2t9Ci0gICAqIHV0aWxpdHkgdG8gZ3JhYiBpbmZvIGFib3V0IHRoZSBKYXZhIGVudmlyb25tZW50IGFuZCBDTEFTU1BBVEgsIAotICAgKiBldGMuLCBhbmQgdGhlbiByZXR1cm5zIHRoZSByZXN1bHRpbmcgTm9kZS4gIFN0eWxlc2hlZXRzIGNhbiAKLSAgICogdGhlbiBtYW5pdXBsYXRlIHRoaXMgZGF0YSBvciBzaW1wbHkgeHNsOmNvcHktb2YgdGhlIE5vZGUuPC9wPgotICAgKgotICAgKiA8cD5XZSB0aHJvdyBhIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uIGluIHRoZSB1bmxpa2VseSBjYXNlIAotICAgKiB0aGF0IHJlYWRpbmcgaW5mb3JtYXRpb24gZnJvbSB0aGUgZW52aXJvbm1lbnQgdGhyb3dzIHVzIGFuIAotICAgKiBleGNlcHRpb24uIChJcyB0aGlzIHJlYWxseSB0aGUgYmVzdCB0aGluZyB0byBkbz8pPC9wPgotICAgKgotICAgKiBAcGFyYW0gbXlDb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiBwYXNzZWQgaW4gYnkgdGhlCi0gICAqICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uIG1lY2hhbmlzbS4gIFRoaXMgbXVzdCBiZSBhbiBYUGF0aENvbnRleHQuCi0gICAqIEByZXR1cm4gYSBOb2RlIGFzIGRlc2NyaWJlZCBhYm92ZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBjaGVja0Vudmlyb25tZW50KEV4cHJlc3Npb25Db250ZXh0IG15Q29udGV4dCkKLSAgewotCi0gICAgRG9jdW1lbnQgZmFjdG9yeURvY3VtZW50OwotICAgIHRyeQotICAgIHsKLSAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgZmFjdG9yeURvY3VtZW50ID0gZGIubmV3RG9jdW1lbnQoKTsKLSAgICB9Ci0gICAgY2F0Y2goUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHBjZSk7Ci0gICAgfQotCi0gICAgTm9kZSByZXN1bHROb2RlID0gbnVsbDsKLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXN1bHROb2RlID0gZmFjdG9yeURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNoZWNrRW52aXJvbm1lbnRFeHRlbnNpb24iKTsKLSAgICAgIEVudmlyb25tZW50Q2hlY2sgZW52Q2hlY2tlciA9IG5ldyBFbnZpcm9ubWVudENoZWNrKCk7Ci0gICAgICBIYXNodGFibGUgaCA9IGVudkNoZWNrZXIuZ2V0RW52aXJvbm1lbnRIYXNoKCk7Ci0gICAgICBlbnZDaGVja2VyLmFwcGVuZEVudmlyb25tZW50UmVwb3J0KHJlc3VsdE5vZGUsIGZhY3RvcnlEb2N1bWVudCwgaCk7Ci0gICAgICBlbnZDaGVja2VyID0gbnVsbDsKLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHROb2RlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9Ob2RlSW5mby5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL05vZGVJbmZvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ5Y2RiNzcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL05vZGVJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgT3ZpZGl1Ci0gKiBQcmVkZXNjdSA8b3ZpZGl1QGN1cC5ocC5jb20+IG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlCi0gKiBGb3VuZGF0aW9uIGFuZCB3YXMgb3JpZ2luYWxseSBkZXZlbG9wZWQgYXQgSGV3bGV0dCBQYWNrYXJkIENvbXBhbnkuCi0gKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ubGliOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Ob2RlUHJveHk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLkV4cHJlc3Npb25Db250ZXh0OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotLyoqCi0gKiA8Y29kZT5Ob2RlSW5mbzwvY29kZT4gZGVmaW5lcyB0aGUgWFNMVCBleHRlbnNpb24gZnVuY3Rpb25zIHRvIGJlCi0gKiB1c2VkIGZyb20gc3R5bGVzaGVldHMuCi0gKgotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86b3ZpZGl1QGN1cC5ocC5jb20iPk92aWRpdSBQcmVkZXNjdTwvYT4KLSAqIEBzaW5jZSBNYXkgMjQsIDIwMDEKLSAqLwotcHVibGljIGNsYXNzIE5vZGVJbmZvCi17Ci0gIC8qKgotICAgKiA8Y29kZT5zeXN0ZW1JZDwvY29kZT4gcmV0dXJucyB0aGUgc3lzdGVtIGlkIG9mIHRoZSBjdXJyZW50Ci0gICAqIGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgYW4gPGNvZGU+RXhwcmVzc2lvbkNvbnRleHQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBzeXN0ZW1JZChFeHByZXNzaW9uQ29udGV4dCBjb250ZXh0KQotICB7Ci0gICAgTm9kZSBjb250ZXh0Tm9kZSA9IGNvbnRleHQuZ2V0Q29udGV4dE5vZGUoKTsKLSAgICBpbnQgbm9kZUhhbmRsZXIgPSAoKERUTU5vZGVQcm94eSljb250ZXh0Tm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9ICgoRFRNTm9kZVByb3h5KWNvbnRleHROb2RlKS5nZXREVE0oKQotICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBsb2NhdG9yLmdldFN5c3RlbUlkKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPGNvZGU+c3lzdGVtSWQ8L2NvZGU+IHJldHVybnMgdGhlIHN5c3RlbSBpZCBvZiB0aGUgbm9kZSBwYXNzZWQgYXMKLSAgICogYXJndW1lbnQuIElmIGEgbm9kZSBzZXQgaXMgcGFzc2VkIGFzIGFyZ3VtZW50LCB0aGUgc3lzdGVtIGlkIG9mCi0gICAqIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQgaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiB2YWx1ZQotICAgKiBAcGFyYW0gbm9kZUxpc3QgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN5c3RlbUlkKE5vZGVMaXN0IG5vZGVMaXN0KQotICB7Ci0gICAgaWYgKG5vZGVMaXN0ID09IG51bGwgfHwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiBudWxsOwotICAgIAotICAgIE5vZGUgbm9kZSA9IG5vZGVMaXN0Lml0ZW0oMCk7Ci0gICAgaW50IG5vZGVIYW5kbGVyID0gKChEVE1Ob2RlUHJveHkpbm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9ICgoRFRNTm9kZVByb3h5KW5vZGUpLmdldERUTSgpCi0gICAgICAuZ2V0U291cmNlTG9jYXRvckZvcihub2RlSGFuZGxlcik7Ci0KLSAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgcmV0dXJuIGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5wdWJsaWNJZDwvY29kZT4gcmV0dXJucyB0aGUgc3lzdGVtIGlkIG9mIHRoZSBjdXJyZW50Ci0gICAqIGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgYW4gPGNvZGU+RXhwcmVzc2lvbkNvbnRleHQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBwdWJsaWNJZChFeHByZXNzaW9uQ29udGV4dCBjb250ZXh0KQotICB7Ci0gICAgTm9kZSBjb250ZXh0Tm9kZSA9IGNvbnRleHQuZ2V0Q29udGV4dE5vZGUoKTsKLSAgICBpbnQgbm9kZUhhbmRsZXIgPSAoKERUTU5vZGVQcm94eSljb250ZXh0Tm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9ICgoRFRNTm9kZVByb3h5KWNvbnRleHROb2RlKS5nZXREVE0oKQotICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBsb2NhdG9yLmdldFB1YmxpY0lkKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPGNvZGU+cHVibGljSWQ8L2NvZGU+IHJldHVybnMgdGhlIHN5c3RlbSBpZCBvZiB0aGUgbm9kZSBwYXNzZWQgYXMKLSAgICogYXJndW1lbnQuIElmIGEgbm9kZSBzZXQgaXMgcGFzc2VkIGFzIGFyZ3VtZW50LCB0aGUgc3lzdGVtIGlkIG9mCi0gICAqIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQgaXMgcmV0dXJuZWQuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiB2YWx1ZQotICAgKiBAcGFyYW0gbm9kZUxpc3QgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHB1YmxpY0lkKE5vZGVMaXN0IG5vZGVMaXN0KQotICB7Ci0gICAgaWYgKG5vZGVMaXN0ID09IG51bGwgfHwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiBudWxsOwotICAgIAotICAgIE5vZGUgbm9kZSA9IG5vZGVMaXN0Lml0ZW0oMCk7Ci0gICAgaW50IG5vZGVIYW5kbGVyID0gKChEVE1Ob2RlUHJveHkpbm9kZSkuZ2V0RFRNTm9kZU51bWJlcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9ICgoRFRNTm9kZVByb3h5KW5vZGUpLmdldERUTSgpCi0gICAgICAuZ2V0U291cmNlTG9jYXRvckZvcihub2RlSGFuZGxlcik7Ci0KLSAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgcmV0dXJuIGxvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5saW5lTnVtYmVyPC9jb2RlPiByZXR1cm5zIHRoZSBsaW5lIG51bWJlciBvZiB0aGUgY3VycmVudAotICAgKiBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IGFuIDxjb2RlPkV4cHJlc3Npb25Db250ZXh0PC9jb2RlPiB2YWx1ZQotICAgKiBAcmV0dXJuIGFuIDxjb2RlPmludDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGxpbmVOdW1iZXIoRXhwcmVzc2lvbkNvbnRleHQgY29udGV4dCkKLSAgewotICAgIE5vZGUgY29udGV4dE5vZGUgPSBjb250ZXh0LmdldENvbnRleHROb2RlKCk7Ci0gICAgaW50IG5vZGVIYW5kbGVyID0gKChEVE1Ob2RlUHJveHkpY29udGV4dE5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSljb250ZXh0Tm9kZSkuZ2V0RFRNKCkKLSAgICAgIC5nZXRTb3VyY2VMb2NhdG9yRm9yKG5vZGVIYW5kbGVyKTsKLQotICAgIGlmIChsb2NhdG9yICE9IG51bGwpCi0gICAgICByZXR1cm4gbG9jYXRvci5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmxpbmVOdW1iZXI8L2NvZGU+IHJldHVybnMgdGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBub2RlCi0gICAqIHBhc3NlZCBhcyBhcmd1bWVudC4gSWYgYSBub2RlIHNldCBpcyBwYXNzZWQgYXMgYXJndW1lbnQsIHRoZSBsaW5lCi0gICAqIG51bWJlciBvZiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUxpc3QgYSA8Y29kZT5Ob2RlTGlzdDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBsaW5lTnVtYmVyKE5vZGVMaXN0IG5vZGVMaXN0KQotICB7Ci0gICAgaWYgKG5vZGVMaXN0ID09IG51bGwgfHwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiAtMTsKLSAgICAKLSAgICBOb2RlIG5vZGUgPSBub2RlTGlzdC5pdGVtKDApOwotICAgIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KW5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSlub2RlKS5nZXREVE0oKQotICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogPGNvZGU+Y29sdW1uTnVtYmVyPC9jb2RlPiByZXR1cm5zIHRoZSBjb2x1bW4gbnVtYmVyIG9mIHRoZQotICAgKiBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgYW4gPGNvZGU+RXhwcmVzc2lvbkNvbnRleHQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYW4gPGNvZGU+aW50PC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgY29sdW1uTnVtYmVyKEV4cHJlc3Npb25Db250ZXh0IGNvbnRleHQpCi0gIHsKLSAgICBOb2RlIGNvbnRleHROb2RlID0gY29udGV4dC5nZXRDb250ZXh0Tm9kZSgpOwotICAgIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KWNvbnRleHROb2RlKS5nZXREVE1Ob2RlTnVtYmVyKCk7Ci0gICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gKChEVE1Ob2RlUHJveHkpY29udGV4dE5vZGUpLmdldERUTSgpCi0gICAgICAuZ2V0U291cmNlTG9jYXRvckZvcihub2RlSGFuZGxlcik7Ci0KLSAgICBpZiAobG9jYXRvciAhPSBudWxsKQotICAgICAgcmV0dXJuIGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmNvbHVtbk51bWJlcjwvY29kZT4gcmV0dXJucyB0aGUgY29sdW1uIG51bWJlciBvZiB0aGUgbm9kZQotICAgKiBwYXNzZWQgYXMgYXJndW1lbnQuIElmIGEgbm9kZSBzZXQgaXMgcGFzc2VkIGFzIGFyZ3VtZW50LCB0aGUgbGluZQotICAgKiBudW1iZXIgb2YgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldCBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVMaXN0IGEgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYW4gPGNvZGU+aW50PC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgY29sdW1uTnVtYmVyKE5vZGVMaXN0IG5vZGVMaXN0KQotICB7Ci0gICAgaWYgKG5vZGVMaXN0ID09IG51bGwgfHwgbm9kZUxpc3QuZ2V0TGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiAtMTsKLSAgICAKLSAgICBOb2RlIG5vZGUgPSBub2RlTGlzdC5pdGVtKDApOwotICAgIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KW5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSlub2RlKS5nZXREVE0oKQotICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgaWYgKGxvY2F0b3IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiAtMTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL1BpcGVEb2N1bWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL1BpcGVEb2N1bWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYjYwMGUyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9QaXBlRG9jdW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3MyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWI7Ci0vLyBJbXBvcnRlZCBjbGFzc2VzIGZvciBFeHRlbnNpb24gZWxlbWVudHMKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuWFNMUHJvY2Vzc29yQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtRXh0ZW5zaW9uQ2FsbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtTGl0ZXJhbFJlc3VsdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5BVlQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8vIEltcG9ydGVkIEpBWFAvVHJBWCBjbGFzc2VzCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLQotLy8gSW1wb3J0ZWQgSkFYUCBwYXJzaW5nIGNsYXNzZXMKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOyAKLQotLy8gSW1wb3J0ZWQgU0FYIGNsYXNzZXMKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5QYXJzZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5QYXJzZXJBZGFwdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi0vLyBJbXBvcnRlZCBET00gY2xhc3NlcwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotLy8gSW1wb3J0ZWQgU2VyaWFsaXplciBjbGFzc2VzCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotCi0vLyBPdGhlciBvcmcuYXBhY2hlIGltcG9ydHMKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TeXN0ZW1JRFJlc29sdmVyOwotCi0vLyBJbXBvcnRlZCBqYXZhLmlvIGFuZCBqYXZhLnV0aWwgY2xhc3NlcwotaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLS8qKgotICogU2V0cyBzdHlsZXNoZWV0IHBhcmFtcyBhbmQgcGlwZXMgYW4gWE1MIGRvY3VtZW50IHRocm91Z2ggYSBzZXJpZXMgb2YgMSBvciBtb3JlIHN0eWxlc2hlZXRzLgotICogUGlwZURvY3VtZW50IGlzIGludm9rZWQgZnJvbSBhIHN0eWxlc2hlZXQgYXMgdGhlIHtAbGluayAjcGlwZURvY3VtZW50IHBpcGVEb2N1bWVudCBleHRlbnNpb24gZWxlbWVudH0uCi0gKiAKLSAqIEBhdXRob3IgRG9uYWxkIExlc2xpZQotICovCi1wdWJsaWMgY2xhc3MgUGlwZURvY3VtZW50Ci17Ci0vKioKLSAqIEV4dGVuc2lvbiBlbGVtZW50IGZvciBwaXBpbmcgYW4gWE1MIGRvY3VtZW50IHRocm91Z2ggYSBzZXJpZXMgb2YgMSBvciBtb3JlIHRyYW5zZm9ybWF0aW9ucy4KLSAqIAotICogPHByZT5Db21tb24gdXNhZ2UgcGF0dGVybjogQSBzdHlsZXNoZWV0IHRyYW5zZm9ybXMgYSBsaXN0aW5nIG9mIGRvY3VtZW50cyB0byBiZQotICogdHJhbnNmb3JtZWQgaW50byBhIFRPQy4gRm9yIGVhY2ggZG9jdW1lbnQgaW4gdGhlIGxpc3RpbmcgY2FsbHMgdGhlIHBpcGVEb2N1bWVudAotICogZXh0ZW5zaW9uIGVsZW1lbnQgdG8gcGlwZSB0aGF0IGRvY3VtZW50IHRocm91Z2ggYSBzZXJpZXMgb2YgMSBvciBtb3JlIHN0eWxlc2hlZXRzIAotICogdG8gdGhlIGRlc2lyZWQgb3V0cHV0IGRvY3VtZW50LgotICogCi0gKiBTeW50YXg6Ci0gKiAmbHQ7eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIgotICogICAgICAgICAgICAgICAgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gKiAgICAgICAgICAgICAgICB4bWxuczpwaXBlPSJ4YWxhbjovL1BpcGVEb2N1bWVudCIKLSAqICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJwaXBlIiZndDsKLSAqIC4uLgotICogJmx0O3BpcGU6cGlwZURvY3VtZW50ICAgc291cmNlPSJzb3VyY2UueG1sIiB0YXJnZXQ9InRhcmdldC54bWwiJmd0OwotICogICAmbHQ7c3R5bGVzaGVldCBocmVmPSJzczEueHNsIiZndDsKLSAqICAgICAmbHQ7cGFyYW0gbmFtZT0icGFyYW0xIiB2YWx1ZT0idmFsdWUxIi8mZ3Q7Ci0gKiAgICZsdDsvc3R5bGVzaGVldCZndDsKLSAqICAgJmx0O3N0eWxlc2hlZXQgaHJlZj0ic3MyLnhzbCImZ3Q7Ci0gKiAgICAgJmx0O3BhcmFtIG5hbWU9InBhcmFtMSIgdmFsdWU9InZhbHVlMSIvJmd0OwotICogICAgICZsdDtwYXJhbSBuYW1lPSJwYXJhbTIiIHZhbHVlPSJ2YWx1ZTIiLyZndDsKLSAqICAgJmx0Oy9zdHlsZXNoZWV0Jmd0OwotICogICAmbHQ7c3R5bGVzaGVldCBocmVmPSJzczEueHNsIi8mZ3Q7ICAgICAKLSAqICZsdDsvcGlwZTpwaXBlRG9jdW1lbnQmZ3Q7Ci0gKiAKLSAqIE5vdGVzOjwvcHJlPgotICogPHVsPgotICogICA8bGk+VGhlIGJhc2UgVVJJIGZvciB0aGUgc291cmNlIGF0dHJpYnV0ZSBpcyB0aGUgWE1MICJsaXN0aW5nIiBkb2N1bWVudC48bGkvPgotICogICA8bGk+VGhlIHRhcmdldCBhdHRyaWJ1dGUgaXMgdGFrZW4gYXMgaXMgKGJhc2UgaXMgdGhlIGN1cnJlbnQgdXNlciBkaXJlY3RvcnkpLjxsaS8+Ci0gKiAgIDxsaT5UaGUgc3R5bHNoZWV0IGNvbnRhaW5nIHRoZSBleHRlbnNpb24gZWxlbWVudCBpcyB0aGUgYmFzZSBVUkkgZm9yIHRoZQotICogICBzdHlsZXNoZWV0IGhyZWZzLjxsaS8+Ci0gKiA8L3VsPgotICovCi0gIHB1YmxpYyB2b2lkIHBpcGVEb2N1bWVudChYU0xQcm9jZXNzb3JDb250ZXh0IGNvbnRleHQsIEVsZW1FeHRlbnNpb25DYWxsIGVsZW0pCi0JICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgCi0gICAgICAgICBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBGaWxlTm90Rm91bmRFeGNlcHRpb24JICAgCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBTQVhUcmFuc2Zvcm1lckZhY3Rvcnkgc2F4VEZhY3RvcnkgPSAoU0FYVHJhbnNmb3JtZXJGYWN0b3J5KSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgIAotICAgICAgLy8gWE1MIGRvYyB0byB0cmFuc2Zvcm0uCi0gICAgICBTdHJpbmcgc291cmNlID0gIGVsZW0uZ2V0QXR0cmlidXRlKCJzb3VyY2UiLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRDb250ZXh0Tm9kZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldFRyYW5zZm9ybWVyKCkpOwotICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zSW1wbCA9IGNvbnRleHQuZ2V0VHJhbnNmb3JtZXIoKTsKLQotICAgICAgLy9CYXNlIFVSSSBmb3IgaW5wdXQgZG9jLCBzbyBiYXNlIGZvciByZWxhdGl2ZSBVUkkgdG8gWE1MIGRvYyB0byB0cmFuc2Zvcm0uCi0gICAgICBTdHJpbmcgYmFzZVVSTE9mU291cmNlID0gdHJhbnNJbXBsLmdldEJhc2VVUkxPZlNvdXJjZSgpOwotICAgICAgLy8gQWJzb2x1dGUgVVJJIGZvciBYTUwgZG9jIHRvIHRyYW5zZm9ybS4KLSAgICAgIFN0cmluZyBhYnNTb3VyY2VVUkwgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHNvdXJjZSwgYmFzZVVSTE9mU291cmNlKTsgICAgICAKLQotICAgICAgLy8gVHJhbnNmb3JtYXRpb24gdGFyZ2V0Ci0gICAgICBTdHJpbmcgdGFyZ2V0ID0gIGVsZW0uZ2V0QXR0cmlidXRlKCJ0YXJnZXQiLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRDb250ZXh0Tm9kZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldFRyYW5zZm9ybWVyKCkpOwotICAgICAgCi0gICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBjb250ZXh0LmdldFRyYW5zZm9ybWVyKCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgICBpbnQgeHQgPSB4Y3R4dC5nZXREVE1IYW5kbGVGcm9tTm9kZShjb250ZXh0LmdldENvbnRleHROb2RlKCkpOwotIAotICAgICAgLy8gR2V0IFN5c3RlbSBJZCBmb3Igc3R5bGVzaGVldDsgdG8gYmUgdXNlZCB0byByZXNvbHZlIFVSSXMgdG8gb3RoZXIgc3R5bGVzaGVldHMuCi0gICAgICBTdHJpbmcgc3lzSWQgPSBlbGVtLmdldFN5c3RlbUlkKCk7Ci0gICAgICAKLSAgICAgIE5vZGVMaXN0IHNzTm9kZXMgPSBudWxsOwotICAgICAgTm9kZUxpc3QgcGFyYW1Ob2RlcyA9IG51bGw7Ci0gICAgICBOb2RlIHNzTm9kZSA9IG51bGw7Ci0gICAgICBOb2RlIHBhcmFtTm9kZSA9IG51bGw7Ci0gICAgICBpZiAoZWxlbS5oYXNDaGlsZE5vZGVzKCkpCi0gICAgICB7Ci0gICAgICAgIHNzTm9kZXMgPSBlbGVtLmdldENoaWxkTm9kZXMoKTsgICAgICAgIAotICAgICAgICAvLyBWZWN0b3IgdG8gY29udGFpbiBUcmFuc2Zvcm1lckhhbmRsZXIgZm9yIGVhY2ggc3R5bGVzaGVldC4KLSAgICAgICAgVmVjdG9yIHZUSGFuZGxlciA9IG5ldyBWZWN0b3Ioc3NOb2Rlcy5nZXRMZW5ndGgoKSk7Ci0gICAgICAgIAotICAgICAgICAvLyBUaGUgY2hpbGQgbm9kZXMgb2YgYW4gZXh0ZW5zaW9uIGVsZW1lbnQgbm9kZSBhcmUgaW5zdGFuY2VzIG9mCi0gICAgICAgIC8vIEVsZW1MaXRlcmFsUmVzdWx0LCB3aGljaCByZXF1aXJlcyBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBzdGFuZGFyZAotICAgICAgICAvLyBOb2RlIGludGVyZmFjZS4gQWNjb3JkaW5nbHksIHNvbWUgc3BlY2lhbCBoYW5kbGluZyBpcyByZXF1aXJlZCAoc2VlIGJlbG93KQotICAgICAgICAvLyB0byBnZXQgYXR0cmlidXRlIHZhbHVlcy4KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzc05vZGVzLmdldExlbmd0aCgpOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBzc05vZGUgPSBzc05vZGVzLml0ZW0oaSk7Ci0gICAgICAgICAgaWYgKHNzTm9kZS5nZXROb2RlVHlwZSgpID09IHNzTm9kZS5FTEVNRU5UX05PREUKLSAgICAgICAgICAgICAgJiYgKChFbGVtZW50KXNzTm9kZSkuZ2V0VGFnTmFtZSgpLmVxdWFscygic3R5bGVzaGVldCIpCi0gICAgICAgICAgICAgICYmIHNzTm9kZSBpbnN0YW5jZW9mIEVsZW1MaXRlcmFsUmVzdWx0KQotICAgICAgICAgIHsKLSAgICAgICAgICAgIEFWVCBhdnQgPSAoKEVsZW1MaXRlcmFsUmVzdWx0KXNzTm9kZSkuZ2V0TGl0ZXJhbFJlc3VsdEF0dHJpYnV0ZSgiaHJlZiIpOwotICAgICAgICAgICAgU3RyaW5nIGhyZWYgPSBhdnQuZXZhbHVhdGUoeGN0eHQseHQsIGVsZW0pOwotICAgICAgICAgICAgU3RyaW5nIGFic1VSSSA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoaHJlZiwgc3lzSWQpOwotICAgICAgICAgICAgVGVtcGxhdGVzIHRtcGwgPSBzYXhURmFjdG9yeS5uZXdUZW1wbGF0ZXMobmV3IFN0cmVhbVNvdXJjZShhYnNVUkkpKTsKLSAgICAgICAgICAgIFRyYW5zZm9ybWVySGFuZGxlciB0SGFuZGxlciA9IHNheFRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVySGFuZGxlcih0bXBsKTsKLSAgICAgICAgICAgIFRyYW5zZm9ybWVyIHRyYW5zID0gdEhhbmRsZXIuZ2V0VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgLy8gQWRkVHJhbnNmb3JtZXJIYW5kbGVyIHRvIHZlY3RvcgotICAgICAgICAgICAgdlRIYW5kbGVyLmFkZEVsZW1lbnQodEhhbmRsZXIpOwotCi0gICAgICAgICAgICBwYXJhbU5vZGVzID0gc3NOb2RlLmdldENoaWxkTm9kZXMoKTsKLSAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcGFyYW1Ob2Rlcy5nZXRMZW5ndGgoKTsgaisrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBwYXJhbU5vZGUgPSBwYXJhbU5vZGVzLml0ZW0oaik7Ci0gICAgICAgICAgICAgIGlmIChwYXJhbU5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBwYXJhbU5vZGUuRUxFTUVOVF9OT0RFIAotICAgICAgICAgICAgICAgICAgJiYgKChFbGVtZW50KXBhcmFtTm9kZSkuZ2V0VGFnTmFtZSgpLmVxdWFscygicGFyYW0iKQotICAgICAgICAgICAgICAgICAgJiYgcGFyYW1Ob2RlIGluc3RhbmNlb2YgRWxlbUxpdGVyYWxSZXN1bHQpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgYXZ0ID0gKChFbGVtTGl0ZXJhbFJlc3VsdClwYXJhbU5vZGUpLmdldExpdGVyYWxSZXN1bHRBdHRyaWJ1dGUoIm5hbWUiKTsKLSAgICAgICAgICAgICAgICAgU3RyaW5nIHBOYW1lID0gYXZ0LmV2YWx1YXRlKHhjdHh0LHh0LCBlbGVtKTsKLSAgICAgICAgICAgICAgICAgYXZ0ID0gKChFbGVtTGl0ZXJhbFJlc3VsdClwYXJhbU5vZGUpLmdldExpdGVyYWxSZXN1bHRBdHRyaWJ1dGUoInZhbHVlIik7Ci0gICAgICAgICAgICAgICAgIFN0cmluZyBwVmFsdWUgPSBhdnQuZXZhbHVhdGUoeGN0eHQseHQsIGVsZW0pOwotICAgICAgICAgICAgICAgICB0cmFucy5zZXRQYXJhbWV0ZXIocE5hbWUsIHBWYWx1ZSk7Ci0gICAgICAgICAgICAgICB9IAotICAgICAgICAgICAgIH0KLSAgICAgICAgICAgfQotICAgICAgICAgfQotICAgICAgICAgdXNlUGlwZSh2VEhhbmRsZXIsIGFic1NvdXJjZVVSTCwgdGFyZ2V0KTsKLSAgICAgICB9Ci0gICAgIH0KLSAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICB7Ci0gICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgfQotICB9Ci0gIC8qKgotICAgKiBVc2VzIGEgVmVjdG9yIG9mIFRyYW5zZm9ybWVySGFuZGxlcnMgdG8gcGlwZSBYTUwgaW5wdXQgZG9jdW1lbnQgdGhyb3VnaAotICAgKiBhIHNlcmllcyBvZiAxIG9yIG1vcmUgdHJhbnNmb3JtYXRpb25zLiBDYWxsZWQgYnkge0BsaW5rICNwaXBlRG9jdW1lbnR9IGFuZCB7QGxpbmsgI21haW59LgotICAgKiAKLSAgICogQHBhcmFtIHZUSGFuZGxlciBWZWN0b3Igb2YgVHJhbnNmb3JtYXRpb24gSGFuZGxlcnMgKDEgcGVyIHN0eWxlc2hlZXQpLgotICAgKiBAcGFyYW0gc291cmNlIGFic29sdXRlIFVSSSB0byBYTUwgaW5wdXQKLSAgICogQHBhcmFtIHRhcmdldCBhYnNvbHV0ZSBwYXRoIHRvIHRyYW5zZm9ybWF0aW9uIG91dHB1dC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHVzZVBpcGUoVmVjdG9yIHZUSGFuZGxlciwgU3RyaW5nIHNvdXJjZSwgU3RyaW5nIHRhcmdldCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24sIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiwgCi0gICAgICAgICAgICAgICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiwgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbgotICB7Ci0gICAgWE1MUmVhZGVyIHJlYWRlciA9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgVHJhbnNmb3JtZXJIYW5kbGVyIHRIRmlyc3QgPSAoVHJhbnNmb3JtZXJIYW5kbGVyKXZUSGFuZGxlci5maXJzdEVsZW1lbnQoKTsKLSAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodEhGaXJzdCk7Ci0gICAgcmVhZGVyLnNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIiLCB0SEZpcnN0KTsKLSAgICBmb3IgKGludCBpID0gMTsgaSA8IHZUSGFuZGxlci5zaXplKCk7IGkrKykKLSAgICB7Ci0gICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgdEhGcm9tID0gKFRyYW5zZm9ybWVySGFuZGxlcil2VEhhbmRsZXIuZWxlbWVudEF0KGktMSk7Ci0gICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgdEhUbyA9IChUcmFuc2Zvcm1lckhhbmRsZXIpdlRIYW5kbGVyLmVsZW1lbnRBdChpKTsKLSAgICAgIHRIRnJvbS5zZXRSZXN1bHQobmV3IFNBWFJlc3VsdCh0SFRvKSk7ICAgICAgCi0gICAgfQotICAgIFRyYW5zZm9ybWVySGFuZGxlciB0SExhc3QgPSAoVHJhbnNmb3JtZXJIYW5kbGVyKXZUSGFuZGxlci5sYXN0RWxlbWVudCgpOwotICAgIFRyYW5zZm9ybWVyIHRyYW5zID0gdEhMYXN0LmdldFRyYW5zZm9ybWVyKCk7Ci0gICAgUHJvcGVydGllcyBvdXRwdXRQcm9wcyA9IHRyYW5zLmdldE91dHB1dFByb3BlcnRpZXMoKTsKLSAgICBTZXJpYWxpemVyIHNlcmlhbGl6ZXIgPSBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyKG91dHB1dFByb3BzKTsKLSAgICBzZXJpYWxpemVyLnNldE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSh0YXJnZXQpKTsKLSAgICB0SExhc3Quc2V0UmVzdWx0KG5ldyBTQVhSZXN1bHQoc2VyaWFsaXplci5hc0NvbnRlbnRIYW5kbGVyKCkpKTsKLSAgICAKLSAgICByZWFkZXIucGFyc2Uoc291cmNlKTsKLSAgfQotIAotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9SZWRpcmVjdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL1JlZGlyZWN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIxMzUzNjAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL1JlZGlyZWN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MjggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ubGliOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLlhTTFByb2Nlc3NvckNvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUV4dGVuc2lvbkNhbGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuT3V0cHV0UHJvcGVydGllczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotLyoqCi0gKiBJbXBsZW1lbnRzIHRocmVlIGV4dGVuc2lvbiBlbGVtZW50cyB0byBhbGxvdyBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIHRvCi0gKiByZWRpcmVjdCBpdHMgb3V0cHV0IHRvIG11bHRpcGxlIG91dHB1dCBmaWxlcy4KLSAqIFlvdSBtdXN0IGRlY2xhcmUgdGhlIFhhbGFuIG5hbWVzcGFjZSAoeG1sbnM6bHhzbHQ9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0IiksCi0gKiBhIG5hbWVzcGFjZSBmb3IgdGhlIGV4dGVuc2lvbiBwcmVmaXggKHN1Y2ggYXMgeG1sbnM6cmVkaXJlY3Q9Im9yZy5hcGFjaGUueGFsYW4ubGliLlJlZGlyZWN0IiksCi0gKiBhbmQgZGVjbGFyZSB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBhcyBhbiBleHRlbnNpb24gKGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJyZWRpcmVjdCIpLgotICogWW91IGNhbiBlaXRoZXIganVzdCB1c2UgcmVkaXJlY3Q6d3JpdGUsIGluIHdoaWNoIGNhc2UgdGhlIGZpbGUgd2lsbCBiZQotICogb3BlbmVkIGFuZCBpbW1lZGlhdGVseSBjbG9zZWQgYWZ0ZXIgdGhlIHdyaXRlLCBvciB5b3UgY2FuIGJyYWNrZXQgdGhlCi0gKiB3cml0ZSBjYWxscyBieSByZWRpcmVjdDpvcGVuIGFuZCByZWRpcmVjdDpjbG9zZSwgaW4gd2hpY2ggY2FzZSB0aGUKLSAqIGZpbGUgd2lsbCBiZSBrZXB0IG9wZW4gZm9yIG11bHRpcGxlIHdyaXRlcyB1bnRpbCB0aGUgY2xvc2UgY2FsbCBpcwotICogZW5jb3VudGVyZWQuICBDYWxscyBjYW4gYmUgbmVzdGVkLiAgQ2FsbHMgY2FuIHRha2UgYSAnZmlsZScgYXR0cmlidXRlCi0gKiBhbmQvb3IgYSAnc2VsZWN0JyBhdHRyaWJ1dGUgaW4gb3JkZXIgdG8gZ2V0IHRoZSBmaWxlbmFtZS4gIElmIGEgc2VsZWN0Ci0gKiBhdHRyaWJ1dGUgaXMgZW5jb3VudGVyZWQsIGl0IHdpbGwgZXZhbHVhdGUgdGhhdCBleHByZXNzaW9uIGZvciBhIHN0cmluZwotICogdGhhdCBpbmRpY2F0ZXMgdGhlIGZpbGVuYW1lLiAgSWYgdGhlIHN0cmluZyBldmFsdWF0ZXMgdG8gZW1wdHksIGl0IHdpbGwKLSAqIGF0dGVtcHQgdG8gdXNlIHRoZSAnZmlsZScgYXR0cmlidXRlIGFzIGEgZGVmYXVsdC4gIEZpbGVuYW1lcyBjYW4gYmUgcmVsYXRpdmUKLSAqIG9yIGFic29sdXRlLiAgSWYgdGhleSBhcmUgcmVsYXRpdmUsIHRoZSBiYXNlIGRpcmVjdG9yeSB3aWxsIGJlIHRoZSBzYW1lIGFzCi0gKiB0aGUgYmFzZSBkaXJlY3RvcnkgZm9yIHRoZSBvdXRwdXQgZG9jdW1lbnQuICBUaGlzIGlzIG9idGFpbmVkIGJ5IGNhbGxpbmcKLSAqIGdldE91dHB1dFRhcmdldCgpIG9uIHRoZSBUcmFuc2Zvcm1lckltcGwuICBZb3UgY2FuIHNldCB0aGlzIGJhc2UgZGlyZWN0b3J5Ci0gKiBieSBjYWxsaW5nIFRyYW5zZm9ybWVySW1wbC5zZXRPdXRwdXRUYXJnZXQoKSBvciBpdCBpcyBhdXRvbWF0aWNhbGx5IHNldAotICogd2hlbiB1c2luZyB0aGUgdHdvIGFyZ3VtZW50IGZvcm0gb2YgdHJhbnNmb3JtKCkgb3IgdHJhbnNmb3JtTm9kZSgpLgotICoKLSAqIDxwPkV4YW1wbGU6PC9wPgotICogPFBSRT4KLSAqICZsdDs/eG1sIHZlcnNpb249IjEuMCI/PgotICogJmx0O3hzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvWFNML1RyYW5zZm9ybS8xLjAiCi0gKiAgICAgICAgICAgICAgICAgeG1sbnM6bHhzbHQ9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0IgotICogICAgICAgICAgICAgICAgIHhtbG5zOnJlZGlyZWN0PSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5SZWRpcmVjdCIKLSAqICAgICAgICAgICAgICAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0icmVkaXJlY3QiPgotICoKLSAqICAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gKiAgICAgJmx0O291dD4KLSAqICAgICAgIGRlZmF1bHQgb3V0cHV0LgotICogICAgICZsdDsvb3V0PgotICogICAgICZsdDtyZWRpcmVjdDpvcGVuIGZpbGU9ImRvYzMub3V0Ii8+Ci0gKiAgICAgJmx0O3JlZGlyZWN0OndyaXRlIGZpbGU9ImRvYzMub3V0Ij4KLSAqICAgICAgICZsdDtvdXQ+Ci0gKiAgICAgICAgICZsdDtyZWRpcmVjdDp3cml0ZSBmaWxlPSJkb2MxLm91dCI+Ci0gKiAgICAgICAgICAgJmx0O291dD4KLSAqICAgICAgICAgICAgIGRvYzEgb3V0cHV0LgotICogICAgICAgICAgICAgJmx0O3JlZGlyZWN0OndyaXRlIGZpbGU9ImRvYzMub3V0Ij4KLSAqICAgICAgICAgICAgICAgU29tZSB0ZXh0IHRvIGRvYzMKLSAqICAgICAgICAgICAgICZsdDsvcmVkaXJlY3Q6d3JpdGU+Ci0gKiAgICAgICAgICAgJmx0Oy9vdXQ+Ci0gKiAgICAgICAgICZsdDsvcmVkaXJlY3Q6d3JpdGU+Ci0gKiAgICAgICAgICZsdDtyZWRpcmVjdDp3cml0ZSBmaWxlPSJkb2MyLm91dCI+Ci0gKiAgICAgICAgICAgJmx0O291dD4KLSAqICAgICAgICAgICAgIGRvYzIgb3V0cHV0LgotICogICAgICAgICAgICAgJmx0O3JlZGlyZWN0OndyaXRlIGZpbGU9ImRvYzMub3V0Ij4KLSAqICAgICAgICAgICAgICAgU29tZSBtb3JlIHRleHQgdG8gZG9jMwotICogICAgICAgICAgICAgICAmbHQ7cmVkaXJlY3Q6d3JpdGUgc2VsZWN0PSJkb2MvZm9vIj4KLSAqICAgICAgICAgICAgICAgICB0ZXh0IGZvciBkb2M0Ci0gKiAgICAgICAgICAgICAgICZsdDsvcmVkaXJlY3Q6d3JpdGU+Ci0gKiAgICAgICAgICAgICAmbHQ7L3JlZGlyZWN0OndyaXRlPgotICogICAgICAgICAgICZsdDsvb3V0PgotICogICAgICAgICAmbHQ7L3JlZGlyZWN0OndyaXRlPgotICogICAgICAgJmx0Oy9vdXQ+Ci0gKiAgICAgJmx0Oy9yZWRpcmVjdDp3cml0ZT4KLSAqICAgICAmbHQ7cmVkaXJlY3Q6Y2xvc2UgZmlsZT0iZG9jMy5vdXQiLz4KLSAqICAgJmx0Oy94c2w6dGVtcGxhdGU+Ci0gKgotICogJmx0Oy94c2w6c3R5bGVzaGVldD4KLSAqIDwvUFJFPgotICoKLSAqIEBhdXRob3IgU2NvdHQgQm9hZwotICogQHZlcnNpb24gMS4wCi0gKiBAc2VlIDxhIGhyZWY9Ii4uLy4uLy4uLy4uLy4uLy4uL2V4dGVuc2lvbnMuaHRtbCNleC1yZWRpcmVjdCIgdGFyZ2V0PSJfdG9wIj5FeGFtcGxlIHdpdGggUmVkaXJlY3QgZXh0ZW5zaW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgUmVkaXJlY3QKLXsKLSAgLyoqCi0gICAqIExpc3Qgb2YgZm9ybWF0dGVyIGxpc3RlbmVycyBpbmRleGVkIGJ5IGZpbGVuYW1lLgotICAgKi8KLSAgcHJvdGVjdGVkIEhhc2h0YWJsZSBtX2Zvcm1hdHRlckxpc3RlbmVycyA9IG5ldyBIYXNodGFibGUgKCk7Ci0KLSAgLyoqCi0gICAqIExpc3Qgb2Ygb3V0cHV0IHN0cmVhbXMgaW5kZXhlZCBieSBmaWxlbmFtZS4KLSAgICovCi0gIHByb3RlY3RlZCBIYXNodGFibGUgbV9vdXRwdXRTdHJlYW1zID0gbmV3IEhhc2h0YWJsZSAoKTsKLQotICAvKioKLSAgICogT3BlbiB0aGUgZ2l2ZW4gZmlsZSBhbmQgcHV0IGl0IGluIHRoZSBYTUwsIEhUTUwsIG9yIFRleHQgZm9ybWF0dGVyIGxpc3RlbmVyJ3MgdGFibGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBvcGVuKFhTTFByb2Nlc3NvckNvbnRleHQgY29udGV4dCwgRWxlbUV4dGVuc2lvbkNhbGwgZWxlbSkKLSAgICB0aHJvd3MgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgICAgICAgICBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwKLSAgICAgICAgICAgamF2YS5pby5JT0V4Y2VwdGlvbiwKLSAgICAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgU3RyaW5nIGZpbGVOYW1lID0gZ2V0RmlsZW5hbWUoY29udGV4dCwgZWxlbSk7Ci0gICAgT2JqZWN0IGZsaXN0ZW5lciA9IG1fZm9ybWF0dGVyTGlzdGVuZXJzLmdldChmaWxlTmFtZSk7Ci0gICAgaWYobnVsbCA9PSBmbGlzdGVuZXIpCi0gICAgewotICAgICAgU3RyaW5nIG1rZGlyc0V4cHIgCi0gICAgICAgID0gZWxlbS5nZXRBdHRyaWJ1dGUgKCJta2RpcnMiLCBjb250ZXh0LmdldENvbnRleHROb2RlKCksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldFRyYW5zZm9ybWVyKCkpOwotICAgICAgYm9vbGVhbiBta2RpcnMgPSAobWtkaXJzRXhwciAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICA/IChta2RpcnNFeHByLmVxdWFscygidHJ1ZSIpIHx8IG1rZGlyc0V4cHIuZXF1YWxzKCJ5ZXMiKSkgOiB0cnVlOwotICAgICAgICAgIC8vIENvbnRlbnRIYW5kbGVyIGZsID0gCi0gICAgICAgICAgbWFrZUZvcm1hdHRlckxpc3RlbmVyKGNvbnRleHQsIGVsZW0sIGZpbGVOYW1lLCB0cnVlLCBta2RpcnMpOwotICAgICAgICAgIC8vIGZsLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBXcml0ZSB0aGUgZXZhbHV0YXRpb24gb2YgdGhlIGVsZW1lbnQgY2hpbGRyZW4gdG8gdGhlIGdpdmVuIGZpbGUuIFRoZW4gY2xvc2UgdGhlIGZpbGUKLSAgICogdW5sZXNzIGl0IHdhcyBvcGVuZWQgd2l0aCB0aGUgb3BlbiBleHRlbnNpb24gZWxlbWVudCBhbmQgaXMgaW4gdGhlIGZvcm1hdHRlciBsaXN0ZW5lcidzIHRhYmxlLgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoWFNMUHJvY2Vzc29yQ29udGV4dCBjb250ZXh0LCBFbGVtRXh0ZW5zaW9uQ2FsbCBlbGVtKQotICAgIHRocm93cyBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24sCi0gICAgICAgICAgIGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAotICAgICAgICAgICBqYXZhLmlvLklPRXhjZXB0aW9uLAotICAgICAgICAgICBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBTdHJpbmcgZmlsZU5hbWUgPSBnZXRGaWxlbmFtZShjb250ZXh0LCBlbGVtKTsKLSAgICBPYmplY3QgZmxPYmplY3QgPSBtX2Zvcm1hdHRlckxpc3RlbmVycy5nZXQoZmlsZU5hbWUpOwotICAgIENvbnRlbnRIYW5kbGVyIGZvcm1hdHRlcjsKLSAgICBib29sZWFuIGluVGFibGUgPSBmYWxzZTsKLSAgICBpZihudWxsID09IGZsT2JqZWN0KQotICAgIHsKLSAgICAgIFN0cmluZyBta2RpcnNFeHByIAotICAgICAgICA9ICgoRWxlbUV4dGVuc2lvbkNhbGwpZWxlbSkuZ2V0QXR0cmlidXRlICgibWtkaXJzIiwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0Q29udGV4dE5vZGUoKSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0VHJhbnNmb3JtZXIoKSk7Ci0gICAgICBib29sZWFuIG1rZGlycyA9IChta2RpcnNFeHByICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgID8gKG1rZGlyc0V4cHIuZXF1YWxzKCJ0cnVlIikgfHwgbWtkaXJzRXhwci5lcXVhbHMoInllcyIpKSA6IHRydWU7Ci0gICAgICBmb3JtYXR0ZXIgPSBtYWtlRm9ybWF0dGVyTGlzdGVuZXIoY29udGV4dCwgZWxlbSwgZmlsZU5hbWUsIHRydWUsIG1rZGlycyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpblRhYmxlID0gdHJ1ZTsKLSAgICAgIGZvcm1hdHRlciA9IChDb250ZW50SGFuZGxlcilmbE9iamVjdDsKLSAgICB9Ci0gICAgCi0gICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZiA9IGNvbnRleHQuZ2V0VHJhbnNmb3JtZXIoKTsKLSAgICAKLSAgICB0cmFuc2YuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKGVsZW0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldENvbnRleHROb2RlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldE1vZGUoKSwgZm9ybWF0dGVyKTsKLSAgICAKLSAgICBpZighaW5UYWJsZSkKLSAgICB7Ci0gICAgICBPdXRwdXRTdHJlYW0gb3N0cmVhbSA9IChPdXRwdXRTdHJlYW0pbV9vdXRwdXRTdHJlYW1zLmdldChmaWxlTmFtZSk7Ci0gICAgICBpZihudWxsICE9IG9zdHJlYW0pCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgZm9ybWF0dGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICAgICAgfQotICAgICAgICBvc3RyZWFtLmNsb3NlKCk7Ci0gICAgICAgIG1fb3V0cHV0U3RyZWFtcy5yZW1vdmUoZmlsZU5hbWUpOwotICAgICAgICBtX2Zvcm1hdHRlckxpc3RlbmVycy5yZW1vdmUoZmlsZU5hbWUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIENsb3NlIHRoZSBnaXZlbiBmaWxlIGFuZCByZW1vdmUgaXQgZnJvbSB0aGUgZm9ybWF0dGVyIGxpc3RlbmVyJ3MgdGFibGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZShYU0xQcm9jZXNzb3JDb250ZXh0IGNvbnRleHQsIEVsZW1FeHRlbnNpb25DYWxsIGVsZW0pCi0gICAgdGhyb3dzIGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbiwKLSAgICBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbiwKLSAgICBqYXZhLmlvLklPRXhjZXB0aW9uLAotICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIFN0cmluZyBmaWxlTmFtZSA9IGdldEZpbGVuYW1lKGNvbnRleHQsIGVsZW0pOwotICAgIE9iamVjdCBmb3JtYXR0ZXJPYmogPSBtX2Zvcm1hdHRlckxpc3RlbmVycy5nZXQoZmlsZU5hbWUpOwotICAgIGlmKG51bGwgIT0gZm9ybWF0dGVyT2JqKQotICAgIHsKLSAgICAgIENvbnRlbnRIYW5kbGVyIGZsID0gKENvbnRlbnRIYW5kbGVyKWZvcm1hdHRlck9iajsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBmbC5lbmREb2N1bWVudCgpOwotICAgICAgfQotICAgICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgICAgfQotICAgICAgT3V0cHV0U3RyZWFtIG9zdHJlYW0gPSAoT3V0cHV0U3RyZWFtKW1fb3V0cHV0U3RyZWFtcy5nZXQoZmlsZU5hbWUpOwotICAgICAgaWYobnVsbCAhPSBvc3RyZWFtKQotICAgICAgewotICAgICAgICBvc3RyZWFtLmNsb3NlKCk7Ci0gICAgICAgIG1fb3V0cHV0U3RyZWFtcy5yZW1vdmUoZmlsZU5hbWUpOwotICAgICAgfQotICAgICAgbV9mb3JtYXR0ZXJMaXN0ZW5lcnMucmVtb3ZlKGZpbGVOYW1lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaWxlbmFtZSBmcm9tIHRoZSAnc2VsZWN0JyBvciB0aGUgJ2ZpbGUnIGF0dHJpYnV0ZS4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIGdldEZpbGVuYW1lKFhTTFByb2Nlc3NvckNvbnRleHQgY29udGV4dCwgRWxlbUV4dGVuc2lvbkNhbGwgZWxlbSkKLSAgICB0aHJvd3MgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgIGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAotICAgIGphdmEuaW8uSU9FeGNlcHRpb24sCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgU3RyaW5nIGZpbGVOYW1lOwotICAgIFN0cmluZyBmaWxlTmFtZUV4cHIgCi0gICAgICA9ICgoRWxlbUV4dGVuc2lvbkNhbGwpZWxlbSkuZ2V0QXR0cmlidXRlICgic2VsZWN0IiwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldENvbnRleHROb2RlKCksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRUcmFuc2Zvcm1lcigpKTsKLSAgICBpZihudWxsICE9IGZpbGVOYW1lRXhwcikKLSAgICB7Ci0gICAgICBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dCB4Y3R4dCAKLSAgICAgICAgPSBjb250ZXh0LmdldFRyYW5zZm9ybWVyKCkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgICBYUGF0aCBteXhwYXRoID0gbmV3IFhQYXRoKGZpbGVOYW1lRXhwciwgZWxlbSwgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLCBYUGF0aC5TRUxFQ1QpOwotICAgICAgWE9iamVjdCB4b2JqID0gbXl4cGF0aC5leGVjdXRlKHhjdHh0LCBjb250ZXh0LmdldENvbnRleHROb2RlKCksIGVsZW0pOwotICAgICAgZmlsZU5hbWUgPSB4b2JqLnN0cigpOwotICAgICAgaWYoKG51bGwgPT0gZmlsZU5hbWUpIHx8IChmaWxlTmFtZS5sZW5ndGgoKSA9PSAwKSkKLSAgICAgIHsKLSAgICAgICAgZmlsZU5hbWUgPSBlbGVtLmdldEF0dHJpYnV0ZSAoImZpbGUiLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRDb250ZXh0Tm9kZSgpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRUcmFuc2Zvcm1lcigpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGZpbGVOYW1lID0gZWxlbS5nZXRBdHRyaWJ1dGUgKCJmaWxlIiwgY29udGV4dC5nZXRDb250ZXh0Tm9kZSgpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0VHJhbnNmb3JtZXIoKSk7Ci0gICAgfQotICAgIGlmKG51bGwgPT0gZmlsZU5hbWUpCi0gICAgewotICAgICAgY29udGV4dC5nZXRUcmFuc2Zvcm1lcigpLmdldE1zZ01ncigpLmVycm9yKGVsZW0sIGVsZW0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0Q29udGV4dE5vZGUoKSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIlJlZGlyZWN0IGV4dGVuc2lvbjogQ291bGQgbm90IGdldCBmaWxlbmFtZSAtIGZpbGUgb3Igc2VsZWN0IGF0dHJpYnV0ZSBtdXN0IHJldHVybiB2YWxkIHN0cmluZy4iKTsKLSAgICB9Ci0gICAgcmV0dXJuIGZpbGVOYW1lOwotICB9Ci0gIAotICAvLyB5dWNrLgotICBwcml2YXRlIFN0cmluZyB1cmxUb0ZpbGVOYW1lKFN0cmluZyBiYXNlKQotICB7Ci0gICAgaWYobnVsbCAhPSBiYXNlKQotICAgIHsKLSAgICAgIGlmKGJhc2Uuc3RhcnRzV2l0aCgiZmlsZTovLy8vIikpCi0gICAgICB7Ci0gICAgICAgIGJhc2UgPSBiYXNlLnN1YnN0cmluZyg3KTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYoYmFzZS5zdGFydHNXaXRoKCJmaWxlOi8vLyIpKQotICAgICAgewotICAgICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoNik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKGJhc2Uuc3RhcnRzV2l0aCgiZmlsZTovLyIpKQotICAgICAgewotICAgICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoNSk7IC8vIGFic29sdXRlPwotICAgICAgfQotICAgICAgZWxzZSBpZihiYXNlLnN0YXJ0c1dpdGgoImZpbGU6LyIpKQotICAgICAgewotICAgICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoNSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKGJhc2Uuc3RhcnRzV2l0aCgiZmlsZToiKSkKLSAgICAgIHsKLSAgICAgICAgYmFzZSA9IGJhc2Uuc3Vic3RyaW5nKDQpOwotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gYmFzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQ29udGVudEhhbmRsZXIsIGJhc2VkIG9uIGF0dHJpYnV0ZXMgb2YgdGhlIGN1cnJlbnQgQ29udGVudEhhbmRsZXIuCi0gICAqLwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIG1ha2VGb3JtYXR0ZXJMaXN0ZW5lcihYU0xQcm9jZXNzb3JDb250ZXh0IGNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1FeHRlbnNpb25DYWxsIGVsZW0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRQdXRJblRhYmxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG1rZGlycykKLSAgICB0aHJvd3MgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uLAotICAgIGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uLAotICAgIGphdmEuaW8uSU9FeGNlcHRpb24sCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoZmlsZU5hbWUpOwotICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciA9IGNvbnRleHQuZ2V0VHJhbnNmb3JtZXIoKTsKLSAgICBTdHJpbmcgYmFzZTsgICAgICAgICAgLy8gQmFzZSBVUkkgdG8gdXNlIGZvciByZWxhdGl2ZSBwYXRocwotCi0gICAgaWYoIWZpbGUuaXNBYnNvbHV0ZSgpKQotICAgIHsKLSAgICAgIC8vIFRoaXMgY29kZSBpcyBhdHRyaWJ1dGVkIHRvIEpvbiBHcm92IDxqb25AbGlucHJvLm5vPi4gIEEgcmVsYXRpdmUgZmlsZSBuYW1lCi0gICAgICAvLyBpcyByZWxhdGl2ZSB0byB0aGUgUmVzdWx0IHVzZWQgdG8ga2ljayBvZmYgdGhlIHRyYW5zZm9ybS4gIElmIG5vIHN1Y2gKLSAgICAgIC8vIFJlc3VsdCB3YXMgc3VwcGxpZWQsIHRoZSBmaWxlbmFtZSBpcyByZWxhdGl2ZSB0byB0aGUgc291cmNlIGRvY3VtZW50LgotICAgICAgLy8gV2hlbiB0cmFuc2Zvcm1pbmcgd2l0aCBhIFNBWFJlc3VsdCBvciBET01SZXN1bHQsIGNhbGwKLSAgICAgIC8vIFRyYW5zZm9ybWVySW1wbC5zZXRPdXRwdXRUYXJnZXQoKSB0byBzZXQgdGhlIGRlc2lyZWQgUmVzdWx0IGJhc2UuCi0gIC8vICAgICAgU3RyaW5nIGJhc2UgPSB1cmxUb0ZpbGVOYW1lKGVsZW0uZ2V0U3R5bGVzaGVldCgpLmdldFN5c3RlbUlkKCkpOwotCi0gICAgICBSZXN1bHQgb3V0cHV0VGFyZ2V0ID0gdHJhbnNmb3JtZXIuZ2V0T3V0cHV0VGFyZ2V0KCk7Ci0gICAgICBpZiAoIChudWxsICE9IG91dHB1dFRhcmdldCkgJiYgKChiYXNlID0gb3V0cHV0VGFyZ2V0LmdldFN5c3RlbUlkKCkpICE9IG51bGwpICkgewotICAgICAgICBiYXNlID0gdXJsVG9GaWxlTmFtZShiYXNlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgYmFzZSA9IHVybFRvRmlsZU5hbWUodHJhbnNmb3JtZXIuZ2V0QmFzZVVSTE9mU291cmNlKCkpOwotICAgICAgfQotCi0gICAgICBpZihudWxsICE9IGJhc2UpCi0gICAgICB7Ci0gICAgICAgIEZpbGUgYmFzZUZpbGUgPSBuZXcgRmlsZShiYXNlKTsKLSAgICAgICAgZmlsZSA9IG5ldyBGaWxlKGJhc2VGaWxlLmdldFBhcmVudCgpLCBmaWxlTmFtZSk7Ci0gICAgICB9Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImZpbGUgaXM6ICIrZmlsZS50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICBpZihta2RpcnMpCi0gICAgewotICAgICAgU3RyaW5nIGRpclN0ciA9IGZpbGUuZ2V0UGFyZW50KCk7Ci0gICAgICBpZigobnVsbCAhPSBkaXJTdHIpICYmIChkaXJTdHIubGVuZ3RoKCkgPiAwKSkKLSAgICAgIHsKLSAgICAgICAgRmlsZSBkaXIgPSBuZXcgRmlsZShkaXJTdHIpOwotICAgICAgICBkaXIubWtkaXJzKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gVGhpcyBzaG91bGQgYmUgd29ya2VkIG9uIHNvIHRoYXQgdGhlIG91dHB1dCBmb3JtYXQgY2FuIGJlIAotICAgIC8vIGRlZmluZWQgYnkgYSBmaXJzdCBjaGlsZCBvZiB0aGUgcmVkaXJlY3QgZWxlbWVudC4KLSAgICBPdXRwdXRQcm9wZXJ0aWVzIGZvcm1hdCA9IHRyYW5zZm9ybWVyLmdldE91dHB1dEZvcm1hdCgpOwotCi0gICAgRmlsZU91dHB1dFN0cmVhbSBvc3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSk7Ci0gICAgCi0gICAgdHJ5Ci0gICAgewotICAgICAgQ29udGVudEhhbmRsZXIgZmxpc3RlbmVyIAotICAgICAgICA9IHRyYW5zZm9ybWVyLmNyZWF0ZVJlc3VsdENvbnRlbnRIYW5kbGVyKG5ldyBTdHJlYW1SZXN1bHQob3N0cmVhbSksIGZvcm1hdCk7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZmxpc3RlbmVyLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICAgIH0KLSAgICAgIGlmKHNob3VsZFB1dEluVGFibGUpCi0gICAgICB7Ci0gICAgICAgIG1fb3V0cHV0U3RyZWFtcy5wdXQoZmlsZU5hbWUsIG9zdHJlYW0pOwotICAgICAgICBtX2Zvcm1hdHRlckxpc3RlbmVycy5wdXQoZmlsZU5hbWUsIGZsaXN0ZW5lcik7Ci0gICAgICB9Ci0gICAgICByZXR1cm4gZmxpc3RlbmVyOwotICAgIH0KLSAgICBjYXRjaChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICAgIAotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWNiNGIxOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsOSArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIEV4dGVuc2lvbnMuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICA8cD5FeHRlbnNpb24gZWxlbWVudHMgYW5kIGZ1bmN0aW9ucyBzaGlwcGVkIHdpdGggWGFsYW4tSmF2YTwvcD4KLSAgIDxwPldlIGFyZSBhZGRpbmcgZXh0ZW5zaW9ucyB0byB0aGlzIHBhY2thZ2UuPHA+Ci0gIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL0Nvbm5lY3Rpb25Qb29sLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL0Nvbm5lY3Rpb25Qb29sLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRjNjlhNzguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9Db25uZWN0aW9uUG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ubGliLnNxbDsKLQotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEubGFuZy5TdHJpbmc7Ci1pbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKLWltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5zcWwuKjsKLQotLyoqCi0gKiBBbiBpbnRlcmZhY2UgdXNlZCB0byBidWlsZCB3cmFwcGVyIGNsYXNzZXMgYXJvdW5kIGV4aXN0aW5nCi0gKiBDb25uZWN0aW9uIFBvb2wgbGlicmFyaWVzLgotICogVGl0bGU6ICAgICBDb25uZWN0aW9uUG9vbDxwPgotICogQGF1dGhvciBKb2huIEdlbnRpbGluCi0gKiBAdmVyc2lvbiAxLjAKLSAqLwotcHVibGljIGludGVyZmFjZSBDb25uZWN0aW9uUG9vbAotewotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgaWYgYSBDb25uZWN0aW9uIFBvb2wgaGFzIGJlZW4gZGlzYWJsZWQuIElmIGEgQ29ubmVjdGlvbiBwb29sCi0gICAqIGlzIGRpc2FibGVkLCB0aGVuIGl0IHdpbGwgb25seSBtYW5hZ2UgY29ubmVjdGlvbnMgdGhhdCBhcmUgaW4gdXNlLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQoICk7Ci0KLSAgLyoqCi0gICAqIFRoZSBEcml2ZXIgYW5kIFVSTCBhcmUgdGhlIG9ubHkgcmVxdWlyZWQgcGFybWV0ZXJzLgotICAgKiBAcGFyYW0gZAotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREcml2ZXIoIFN0cmluZyBkICk7Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSB1cmwKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VVJMKCBTdHJpbmcgdXJsICk7Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IGRvd25zaXplaW5nIHRoZSBwb29sLCB0aGlzIHVzYWxseSBoYXBwZW5zIHJpZ2h0IGFmdGVyIHRoZQotICAgKiBwb29sIGhhcyBiZWVuIG1hcmtlZCBhcyBJbmFjdGl2ZSBhbmQgd2UgYXJlIHJlbW92aW5nIGNvbm5lY3Rpb25zCi0gICAqIHRoYXQgYXJlIG5vdCBjdXJyZW50bHkgaW51c2UuCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZyZWVVbnVzZWQoICk7Ci0KLQotICAvKioKLSAgICogUHJvdmlkZSBhbiBpbmRpY2F0b3IgdG8gdGhlIFBvb2xNYW5hZ2VyIHdoZW4gdGhlIFBvb2wgY2FuIGJlIHJlbW92ZWQKLSAgICogZnJvbSB0aGUgUG9vbCBUYWJsZS4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQWN0aXZlQ29ubmVjdGlvbnMoICk7Ci0KLSAgLyoqCi0gICAqIFRoZSByZXN0IG9mIHRoZSBwcm90b2NvbCBwYXJhbWV0ZXJzIGNhbiBlaXRlciBiZSBwYXNzZWQgaW4gYXMKLSAgICoganVzdCBVc2VybmFtZSBhbmQgUGFzc3dvcmQgb3IgYXMgYSBwcm9wZXJ0eSBjb2xsZWN0aW9uLiBJZiB0aGUKLSAgICogcHJvcGVydHkgY29sbGVjdGlvbiBpcyB1c2VkLCB0aGVuIHRoZSBzcGVyYXRlIHVzZXJuYW1lIGFuZCBwYXNzd29yZAotICAgKiBtYXkgYmUgaWdub3JlZCwgaXQgaXMgdXAgdG8gdGhlIHdyYXBwZXIgaW1wbGVtZW50YXRpb24gdG8gaGFuZGxlCi0gICAqIHRoZSBzaXR1YXRpb24uIElmIHRoZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGNoYW5nZXMgd2hpbGUgYWZ0ZXIgdGhlCi0gICAqIHBvb2wgaGFzIGJlZW4gZXN0YWJsaXNoZWQsIHRoZSB3cmFwcGVyIGltcGxlbWVudGF0aW9uIHNob3VsZCBpZ25vcmUKLSAgICogdGhlIGNoYW5nZSBhbmQgdGhyb3cgYW4gZXJyb3IuCi0gICAqIEBwYXJhbSBwCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFBhc3N3b3JkKCBTdHJpbmcgcCApOwotCi0gIC8qKgotICAgKiBAcGFyYW0gdQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRVc2VyKCBTdHJpbmcgdSApOwotCi0KLSAgLyoqCi0gICAqIFNldCB0bmUgbWluaW11bSBudW1iZXIgb2YgY29ubmVjdGlvbnMgdGhhdCBhcmUgdG8gYmUgbWFpbnRhaW5lZCBpbiB0aGUKLSAgICogcG9vbC4KLSAgICogQHBhcmFtIG4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TWluQ29ubmVjdGlvbnMoIGludCBuICk7Ci0KLSAgLyoqCi0gICAqIFRlc3QgdG8gc2VlIGlmIHRoZSBjb25uZWN0aW9uIGluZm8gaXMgdmFsaWQgdG8gbWFrZSBhIHJlYWwgY29ubmVjdGlvbgotICAgKiB0byB0aGUgZGF0YWJhc2UuIFRoaXMgbWV0aG9kIG1heSBjYXVzZSB0aGUgcG9vbCB0byBiZSBjcmF0ZWQgYW5kIGZpbGxlZAotICAgKiB3aXRoIG1pbiBjb25uZWN0aW9ucy4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gdGVzdENvbm5lY3Rpb24oICk7Ci0KLSAgLyoqCi0gICAqIFJldHJpdmUgYSBkYXRhYmFzZSBjb25uZWN0aW9uIGZyb20gdGhlIHBvb2wKLSAgICogQHJldHVybgotICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbiggKXRocm93cyBTUUxFeGNlcHRpb247Ci0KLSAgIC8qKgotICAgKiBSZXR1cm4gYSBjb25uZWN0aW9uIHRvIHRoZSBwb29sLCB0aGUgY29ubmVjdGlvbiBtYXkgYmUgY2xvc2VkIGlmIHRoZQotICAgKiBwb29sIGlzIGluYWN0aXZlIG9yIGhhcyBleGNlZWRlZCB0aGUgbWF4IG51bWJlciBvZiBmcmVlIGNvbm5lY3Rpb25zCi0gICAqIEBwYXJhbSBjb24KLSAgICogQHJldHVybgotICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVsZWFzZUNvbm5lY3Rpb24oIENvbm5lY3Rpb24gY29uICl0aHJvd3MgU1FMRXhjZXB0aW9uOwotCi0gICAvKioKLSAgICogUHJvdmlkZSBhIG1lY2hpbmlzbSB0byByZXR1cm4gYSBjb25uZWN0aW9uIHRvIHRoZSBwb29sIG9uIEVycm9yLgotICAgKiBBIGdvb2QgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gY2xvc2UgdGhpcyBjb25uZWN0aW9uIGFuZCBidWlsZAotICAgKiBhIG5ldyBvbmUgdG8gcmVwbGFjZSBpdC4gU29tZSBKREJDIGltcGwncyB3b24ndCBhbGxvdyB5b3UgdG8KLSAgICogcmV1c2UgYSBjb25uZWN0aW9uIGFmdGVyIGFuIGVycm9yIG9jY3Vycy4KLSAgICogQHBhcmFtIGNvbgotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZWxlYXNlQ29ubmVjdGlvbk9uRXJyb3IoIENvbm5lY3Rpb24gY29uICl0aHJvd3MgU1FMRXhjZXB0aW9uOwotCi0KLSAgLyoqCi0gICAqIFRoZSBQb29sIGNhbiBiZSBFbmFibGVkIGFuZCBEaXNhYmxlZC4gRGlzYWJsaW5nIHRoZSBwb29sCi0gICAqIGNsb3NlcyBhbGwgdGhlIG91dHN0YW5kaW5nIFVudXNlZCBjb25uZWN0aW9ucyBhbmQgYW55IG5ldwotICAgKiBjb25uZWN0aW9ucyB3aWxsIGJlIGNsb3NlZCB1cG9uIHJlbGVhc2UuCi0gICAqIEBwYXJhbSBmbGFnIENvbnRyb2wgdGhlIENvbm5lY3Rpb24gUG9vbC4gSWYgaXQgaXMgZW5hYmxlZAotICAgKiB0aGVuIENvbm5lY3Rpb25zIHdpbGwgYWN0dWFsbCBiZSBoZWxkIGFyb3VuZC4gSWYgZGlzYWJsZWQKLSAgICogdGhlbiBhbGwgdW51c2VkIGNvbm5lY3Rpb25zIHdpbGwgYmUgaW5zdGFudGx5IGNsb3NlZCBhbmQgYXMKLSAgICogY29ubmVjdGlvbnMgYXJlIHJlbGVhc2VkIHRoZXkgYXJlIGNsb3NlZCBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBwb29sLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQb29sRW5hYmxlZCggZmluYWwgYm9vbGVhbiBmbGFnICk7Ci0KLSAgLyoqCi0gICAqIFVzZWQgdG8gcGFzcyBpbiBleHRyYSBjb25maWd1cmF0aW9uIG9wdGlvbnMgZHVyaW5nIHRoZQotICAgKiBkYXRhYmFzZSBjb25uZWN0IHBoYXNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJvdG9jb2woUHJvcGVydGllcyBwKTsKLQotCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9Db25uZWN0aW9uUG9vbE1hbmFnZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvQ29ubmVjdGlvblBvb2xNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIxMjM0YmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9Db25uZWN0aW9uUG9vbE1hbmFnZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotCi0gcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqLwotcHVibGljIGNsYXNzIENvbm5lY3Rpb25Qb29sTWFuYWdlcgotewotICAvKioKLSAgICovCi0gIHN0YXRpYyBIYXNodGFibGUgbV9wb29sVGFibGUgPSBudWxsOwotICAvKioKLSAgICovCi0gIHN0YXRpYyBib29sZWFuIG1faXNJbml0ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqLwotICBwdWJsaWMgQ29ubmVjdGlvblBvb2xNYW5hZ2VyKCApCi0gIHsKLSAgICBpbml0KCk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgaW50ZXJuYWwgc3RydWN0dXJlcyBvZiB0aGUgUG9vbCBNYW5hZ2VyCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbml0KCApCi0gIHsKLSAgICAvLyBPbmx5IGRvIHRoaXMgcHJvY2VzcyBvbmNlCi0gICAgaWYgKG1faXNJbml0ID09IHRydWUpIHJldHVybjsKLQotCi0gICAgLy8KLSAgICAvLyBJbml0aWFsaXplIHRoZSBwb29sIHRhYmxlCi0gICAgLy8KLSAgICBtX3Bvb2xUYWJsZSA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIG1faXNJbml0ID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWdpc3RlciBhIG51ZXcgY29ubmVjdGlvbiBwb29sIHRvIHRoZSBnbG9iYWwgcG9vbCB0YWJsZS4KLSAgICogSWYgYSBwb29sIGJ5IHRoYXQgbmFtZSBjdXJyZW50bHkgZXhpc3RzLCB0aGVuIHRocm93IGFuCi0gICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBzdGF0aW5nIHRoYXQgdGhlIHBvb2wgYWxyZWFkeQotICAgKiBleGlzdC4KLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHBhcmFtIHBvb2wKLSAgICogQHJldHVybgotICAgKiBAbGluayBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuQ29ubmVjdGlvblBvb2x9Ci0gICAqIEByZXR1cm4KLSAgICogQHRocm93cyA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+LCB0aHJvdyB0aGlzIGV4Y2VwdGlvbgotICAgKiBpZiBhIHBvb2wgd2l0aCB0aGUgc2FtZSBuYW1lIGN1cnJlbnRseSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVnaXN0ZXJQb29sKCBTdHJpbmcgbmFtZSwgQ29ubmVjdGlvblBvb2wgcG9vbCApCi0gIHsKLSAgICBpZiAoIG1fcG9vbFRhYmxlLmNvbnRhaW5zS2V5KG5hbWUpICkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BPT0xfRVhJU1RTLCBudWxsKSk7IC8vIlBvb2wgYWxyZWFkeSBleGlzdHMiKTsKLSAgICB9Ci0KLSAgICBtX3Bvb2xUYWJsZS5wdXQobmFtZSwgcG9vbCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGEgcG9vbCBmcm9tIHRoZSBnbG9iYWwgdGFibGUuIElmIHRoZSBwb29sIHN0aWxsIGhhcwotICAgKiBhY3RpdmUgY29ubmVjdGlvbnMsIHRoZW4gb25seSBtYXJrIHRoaXMgcG9vbCBhcyBpbmFjdGl2ZSBhbmQKLSAgICogbGVhdmUgaXQgYXJvdW5kIHVudGlsIGFsbCB0aGUgZXhpc3RpbmcgY29ubmVjdGlvbnMgYXJlIGNsb3NlZC4KLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZVBvb2woIFN0cmluZyBuYW1lICkKLSAgewotICAgIENvbm5lY3Rpb25Qb29sIHBvb2wgPSBnZXRQb29sKG5hbWUpOwotCi0gICAgaWYgKG51bGwgIT0gcG9vbCkKLSAgICB7Ci0gICAgICAvLwotICAgICAgLy8gRGlzYWJsZSBmdXR1cmUgdXNlIG9mIHRoaXMgcG9vbCB1bmRlciB0aGUgWGFsYW4KLSAgICAgIC8vIGV4dGVuc2lvbiBvbmx5LiBUaGlzIGZsYWcgc2hvdWxkIG9ubHkgZXhpc3QgaW4gdGhlCi0gICAgICAvLyB3cmFwcGVyIGFuZCBub3QgaW4gdGhlIGFjdHVhbCBwb29sIGltcGxlbWVudGF0aW9uLgotICAgICAgcG9vbC5zZXRQb29sRW5hYmxlZChmYWxzZSk7Ci0KLQotICAgICAgLy8KLSAgICAgIC8vIFJlbW92ZSB0aGUgcG9vbCBmcm9tIHRoZSBIYXNodGFibGUgaWYgd2UgZG9uJ2QgaGF2ZQotICAgICAgLy8gYW55IGFjdGl2ZSBjb25uZWN0aW9ucy4KLSAgICAgIC8vCi0gICAgICBpZiAoICEgcG9vbC5oYXNBY3RpdmVDb25uZWN0aW9ucygpICkgbV9wb29sVGFibGUucmVtb3ZlKG5hbWUpOwotICAgIH0KLQotICB9Ci0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBjb25uZWN0aW9uIHBvb2wgcmVmZXJlbmNlZCBieSB0aGUgbmFtZQotICAgKiBAcGFyYW0gbmFtZQotICAgKiBAcmV0dXJuCi0gICAqIEByZXR1cm5zIDxjb2RlPkNvbm5lY3Rpb25Qb29sPC9jb2RlPiBhIHJlZmVyZW5jZSB0byB0aGUgQ29ubmVjdGlvblBvb2wKLSAgICogb2JqZWN0IHN0b3JlZCBpbiB0aGUgUG9vbCBUYWJsZS4gSWYgdGhlIG5hbWVkIHBvb2wgZG9lcyBub3QgZXhpc3QsIHJldHVybgotICAgKiBudWxsCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIENvbm5lY3Rpb25Qb29sIGdldFBvb2woIFN0cmluZyBuYW1lICkKLSAgewotICAgIHJldHVybiAoQ29ubmVjdGlvblBvb2wpIG1fcG9vbFRhYmxlLmdldChuYW1lKTsKLSAgfQotCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9EVE1Eb2N1bWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9EVE1Eb2N1bWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMjQ0NmNlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvRFRNRG9jdW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MjYgKzAsMCBAQAotLyoqCi0gKiBAKCMpIFNRTERvY3VtZW50LmphdmEKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ubGliLnNxbDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1XU0ZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTURlZmF1bHRCYXNlSXRlcmF0b3JzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUF4aXNUcmF2ZXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUF4aXNJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdWJhbGxvY2F0ZWRJbnRWZWN0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0Lio7Ci0KLS8qKgotICogVGhlIFNRTCBEb2N1bWVudCBpcyB0aGUgbWFpbiBjb250cm9sbGluZyBjbGFzcyB0aGUgZXhlY3V0ZXNhIFNRTCBRdWVyeQotICovCi1wdWJsaWMgY2xhc3MgRFRNRG9jdW1lbnQgZXh0ZW5kcyBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycwotewotICAgIC8vIEJpdG1hc2sgZm9yIHRoZSBwb3J0aW9uIG9mIGEgRFRNIE5vZGUgaGFuZGxlIHdoaWNoIHJlZmVycyBvbmx5Ci0gICAgLy8gdG8gdGhlIG5vZGUsIHdpdGhvdXQgdGhlIHBvcnRpb24gdGhhdCBzcGVjaWZpZXMgd2hpY2ggRFRNIGl0Ci0gICAgLy8gcmVzaWRlcyBpbi4KLSAgICBzdGF0aWMgZmluYWwgaW50IE5PREVJREVOVElUWUJJVFM9RFRNTWFuYWdlci5JREVOVF9OT0RFX0RFRkFVTFQ7Ci0KLSAgLyoqCi0gICAqLwotICBwdWJsaWMgaW50ZXJmYWNlIENoYXJhY3Rlck5vZGVIYW5kbGVyCi0gIHsKLSAgICAvKioKLSAgICAgKiBAcGFyYW0gbm9kZQotICAgICAqIEByZXR1cm4KLSAgICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoIE5vZGUgbm9kZSApdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiA7Ci0gIH0KLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19OQU1FU1BBQ0UgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL1NRTEV4dGVuc2lvbiI7Ci0KLSAgLyoqCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTX0FUVFJJQl9OT1RfU1VQUE9SVEVEID0gIk5vdCBTdXBwb3J0ZWQiOwotICAvKioKLSAgICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNfSVNUUlVFID0gInRydWUiOwotICAvKioKLSAgICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNfSVNGQUxTRSA9ICJmYWxzZSI7Ci0KLSAgLyoqCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTX0RPQ1VNRU5UID0gIiNyb290IjsKLSAgLyoqCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBTX1RFWFRfTk9ERSA9ICIjdGV4dCI7Ci0gIC8qKgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19FTEVNRU5UX05PREUgPSAiI2VsZW1lbnQiOwotCi0gIC8qKgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX0RvY3VtZW50X1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX1RleHROb2RlX1R5cGVJRCA9IDA7Ci0KLQotICAvKioKLSAgICogU3RvcmUgdGhlIFNRTCBEYXRhIGluIHRoaXMgZ3Jvd2FibGUgYXJyYXkKLSAgICovCi0gIHByb3RlY3RlZCBPYmplY3RBcnJheSBtX09iamVjdEFycmF5ID0gbmV3IE9iamVjdEFycmF5KCk7Ci0KLSAgLyoqCi0gICAqIEZvciBlYWNoIGVsZW1lbnQgbm9kZSwgdGhlcmUgY2FuIGJlIHplcm8gb3IgbW9yZSBhdHRyaWJ1dGVzLiBJZiBBdHRyaWJ1dGVzCi0gICAqIGFyZSBhc3NpZ25lZCwgdGhlIGZpcnN0IGF0dHJpYnV0ZSBmb3IgdGhhdCBlbGVtZW50IHdpbGwgYmUgdXNlIGhlcmUuCi0gICAqIFN1YnNlcXVlbnQgZWxlbWVudHMgd2lsbCB1c2UgdGhlIG1fbmV4dHNpYiwgbV9wcmV2c2liIGFycmF5LiBUaGUgc2libGluZwotICAgKiBhcnJheXMgYXJlIG5vdCBtZWVhbnQgdG8gaG9sZCBpbmRleGVzIHRvIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBidXQgYXMKLSAgICogbG9uZyBhcyB0aGVyZSBpcyBub3QgZGlyZWN0IGNvbm5lY3Rpb24gYmFjayBpbnRvIHRoZSBtYWluIERUTSB0cmVlCi0gICAqIHdlIHNob3VsZCBiZSBPSy4KLSAgICovCi0gIHByb3RlY3RlZCBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbV9hdHRyaWJ1dGU7Ci0KLSAgLyoqCi0gICAqIFRoZSBEb2N1bWVudCBJbmRleCB3aWxsIG1vc3QgbGlrZWx5IGJlIDAsIGJ1dCB3ZSB3aWxsIHJlZmVyZW5jZSBpdAotICAgKiBieSB2YXJpYWJsZSBpbiBjYXNlIHRoYXQgcGFyYWRpZ20gZmFsbHMgdGhyb3VnaC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9Eb2N1bWVudElkeDsKLQotCi0gIC8qKgotICAgKiBAcGFyYW0gbWdyCi0gICAqIEBwYXJhbSBpZGVudAotICAgKi8KLSAgcHVibGljIERUTURvY3VtZW50KCBEVE1NYW5hZ2VyIG1nciwgaW50IGlkZW50ICkKLSAgewotICAgIHN1cGVyKG1nciwgbnVsbCwgaWRlbnQsCi0gICAgICBudWxsLCBtZ3IuZ2V0WE1MU3RyaW5nRmFjdG9yeSgpLCB0cnVlKTsKLQotICAgIG1fYXR0cmlidXRlID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3RvcihtX2luaXRpYWxibG9ja3NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEEgY29tbW9uIHJvdXRpbmUgdGhhdCBhbGxvY2F0ZXMgYW4gT2JqZWN0IGZyb20gdGhlIE9iamVjdCBBcnJheS4KLSAgICogT25lIG9mIHRoZSBjb21tb24gYnVncyBpbiB0aGlzIGNvZGUgd2FzIHRvIGFsbG9jYXRlIGFuIE9iamVjdCBhbmQKLSAgICogbm90IGluY2VybWVudCBtX3NpemUsIHVzaW5nIHRoaXMgbWV0aG9kIHdpbGwgYXNzdXJlIHRoYXQgZnVuY3Rpb24uCi0gICAqIEBwYXJhbSBvCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByaXZhdGUgaW50IGFsbG9jYXRlTm9kZU9iamVjdCggT2JqZWN0IG8gKQotICB7Ci0gICAgLy8gTmVlZCB0byBrZWVwIHRoaXMgY291bnRlciBnb2luZyBldmVuIGlmIHdlIGRvbid0IHVzZSBpdC4KLSAgICBtX3NpemUrKzsKLSAgICByZXR1cm4gbV9PYmplY3RBcnJheS5hcHBlbmQobyk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG8KLSAgICogQHBhcmFtIGxldmVsCi0gICAqIEBwYXJhbSBleHRlbmRlZFR5cGUKLSAgICogQHBhcmFtIHBhcmVudAotICAgKiBAcGFyYW0gcHJldnNpYgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGFkZEVsZW1lbnRXaXRoRGF0YSggT2JqZWN0IG8sIGludCBsZXZlbCwgaW50IGV4dGVuZGVkVHlwZSwgaW50IHBhcmVudCwgaW50IHByZXZzaWIgKQotICB7Ci0gICAgaW50IGVsZW1lbnRJZHggPSBhZGRFbGVtZW50KGxldmVsLGV4dGVuZGVkVHlwZSxwYXJlbnQscHJldnNpYik7Ci0KLSAgICBpbnQgZGF0YSA9IGFsbG9jYXRlTm9kZU9iamVjdChvKTsKLSAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KGRhdGEsZWxlbWVudElkeCk7Ci0KLSAgICBtX2V4cHR5cGUuc2V0RWxlbWVudEF0KG1fVGV4dE5vZGVfVHlwZUlELCBkYXRhKTsKLSAgICAvLyBtX2xldmVsLnNldEVsZW1lbnRBdCgoYnl0ZSkobGV2ZWwpLCBkYXRhKTsKLSAgICBtX3BhcmVudC5zZXRFbGVtZW50QXQoZWxlbWVudElkeCwgZGF0YSk7Ci0KLSAgICBtX3ByZXZzaWIuc2V0RWxlbWVudEF0KERUTS5OVUxMLCBkYXRhKTsKLSAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KERUTS5OVUxMLCBkYXRhKTsKLSAgICBtX2F0dHJpYnV0ZS5zZXRFbGVtZW50QXQoRFRNLk5VTEwsIGRhdGEpOwotICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQoRFRNLk5VTEwsIGRhdGEpOwotCi0gICAgcmV0dXJuIGVsZW1lbnRJZHg7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGxldmVsCi0gICAqIEBwYXJhbSBleHRlbmRlZFR5cGUKLSAgICogQHBhcmFtIHBhcmVudAotICAgKiBAcGFyYW0gcHJldnNpYgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGFkZEVsZW1lbnQoIGludCBsZXZlbCwgaW50IGV4dGVuZGVkVHlwZSwgaW50IHBhcmVudCwgaW50IHByZXZzaWIgKQotICB7Ci0gICAgaW50IG5vZGUgPSBEVE0uTlVMTDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIEFkZCB0aGUgTm9kZSBhbmQgYWRqdXN0IGl0cyBFeHRlbmRlZCBUeXBlCi0gICAgICBub2RlID0gYWxsb2NhdGVOb2RlT2JqZWN0KFNfRUxFTUVOVF9OT0RFKTsKLQotICAgICAgbV9leHB0eXBlLnNldEVsZW1lbnRBdChleHRlbmRlZFR5cGUsIG5vZGUpOwotICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCwgbm9kZSk7Ci0gICAgICBtX3ByZXZzaWIuc2V0RWxlbWVudEF0KHByZXZzaWIsIG5vZGUpOwotCi0gICAgICBtX3BhcmVudC5zZXRFbGVtZW50QXQocGFyZW50LCBub2RlKTsKLSAgICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQoRFRNLk5VTEwsIG5vZGUpOwotICAgICAgLy8gbV9sZXZlbC5zZXRFbGVtZW50QXQoKGJ5dGUpbGV2ZWwsIG5vZGUpOwotICAgICAgbV9hdHRyaWJ1dGUuc2V0RWxlbWVudEF0KERUTS5OVUxMLCBub2RlKTsKLQotICAgICAgaWYgKHByZXZzaWIgIT0gRFRNLk5VTEwpCi0gICAgICB7Ci0gICAgICAgIC8vIElmIHRoZSBwcmV2aW91cyBzaWJsaW5nIGlzIGFscmVhZHkgYXNzaWduZWQsIHRoZW4gd2UgYXJlCi0gICAgICAgIC8vIGluc2VydGluZyBhIHZhbHVlIGludG8gdGhlIGNoYWluLgotICAgICAgICBpZiAobV9uZXh0c2liLmVsZW1lbnRBdChwcmV2c2liKSAhPSBEVE0uTlVMTCkKLSAgICAgICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KG1fbmV4dHNpYi5lbGVtZW50QXQocHJldnNpYiksIG5vZGUpOwotCi0gICAgICAgIC8vIFRlbGwgdGhlIHByb2V2aW91cyBzaWJsaW5nIHRoYXQgdGhleSBoYXZlIGEgbmV3IGJvdGhlci9zaXN0ZXIuCi0gICAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQobm9kZSwgcHJldnNpYik7Ci0gICAgICB9Ci0KLSAgICAgICAvLyBTbyBpZiB3ZSBoYXZlIGEgdmFsaWQgcGFyZW50IGFuZCB0aGUgbmV3IG5vZGUgZW5kZWQgdXAgYmVpbmcgZmlyc3QKLSAgICAgIC8vIGluIHRoZSBsaXN0LCBpLmUuIG5vIHByZXZzaWIsIHRoZW4gc2V0IHRoZSBuZXcgbm9kZSB1cCBhcyB0aGUKLSAgICAgIC8vIGZpcnN0IGNoaWxkIG9mIHRoZSBwYXJlbnQuIFNpbmNlIHdlIGNoYWluZWQgdGhlIG5vZGUgaW4gdGhlIGxpc3QsCi0gICAgICAvLyB0aGVyZSBzaG91bGQgYmUgbm8gcmVhc29uIHRvIHdvcnJ5IGFib3V0IHRoZSBjdXJyZW50IGZpcnN0IGNoaWxkCi0gICAgICAvLyBvZiB0aGUgcGFyZW50IG5vZGUuCi0gICAgICBpZiAoKHBhcmVudCAhPSBEVE0uTlVMTCkgJiYgKG1fcHJldnNpYi5lbGVtZW50QXQobm9kZSkgPT0gRFRNLk5VTEwpKQotICAgICAgewotICAgICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KG5vZGUsIHBhcmVudCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGVycm9yKCJFcnJvciBpbiBhZGRFbGVtZW50OiAiK2UuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBMaW5rIGFuIGF0dHJpYnV0ZSB0byBhIG5vZGUsIGlmIHRoZSBub2RlIGFscmVhZHkgaGFzIG9uZSBvciBtb3JlCi0gICAqIGF0dHJpYnV0ZXMgYXNzaWduZWQsIHRoZW4ganVzdCBsaW5rIHRoaXMgb25lIHRvIHRoZSBhdHRyaWJ1dGUgbGlzdC4KLSAgICogVGhlIGZpcnN0IGF0dHJpYnV0ZSBpcyBhdHRhY2hlZCB0byB0aGUgUGFyZW50IE5vZGUgKHBub2RlKSB0aHJvdWdoIHRoZQotICAgKiBtX2F0dHJpYnV0ZSBhcnJheSwgc3Vic2VxdWVudCBhdHRyaWJ1dGVzIGFyZSBsaW5rZWQgdGhyb3VnaCB0aGUKLSAgICogbV9wcmV2c2liLCBtX25leHRzaWIgYXJyYXlzLgotICAgKiBAcGFyYW0gbwotICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlCi0gICAqIEBwYXJhbSBwbm9kZQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGFkZEF0dHJpYnV0ZVRvTm9kZSggT2JqZWN0IG8sIGludCBleHRlbmRlZFR5cGUsIGludCBwbm9kZSApCi0gIHsKLSAgICBpbnQgYXR0cmliID0gRFRNLk5VTEw7Ci0gICAgaW50IHByZXZzaWIgPSBEVE0uTlVMTDsKLSAgICBpbnQgbGFzdGF0dHJpYiA9IERUTS5OVUxMOwotICAgIGludCB2YWx1ZSA9IERUTS5OVUxMOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgLy8gQWRkIHRoZSBOb2RlIGFuZCBhZGp1c3QgaXRzIEV4dGVuZGVkIFR5cGUKLSAgICAgIGF0dHJpYiA9IGFsbG9jYXRlTm9kZU9iamVjdChvKTsKLQotICAgICAgbV9hdHRyaWJ1dGUuc2V0RWxlbWVudEF0KERUTS5OVUxMLCBhdHRyaWIpOwotICAgICAgbV9leHB0eXBlLnNldEVsZW1lbnRBdChleHRlbmRlZFR5cGUsIGF0dHJpYik7Ci0gICAgICAvLyBtX2xldmVsLnNldEVsZW1lbnRBdCgoYnl0ZSkwLCBhdHRyaWIpOwotCi0gICAgICAvLyBDbGVhciB0aGUgc2libGluZyByZWZlcmVuY2VzCi0gICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KERUTS5OVUxMLCBhdHRyaWIpOwotICAgICAgbV9wcmV2c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCxhdHRyaWIpOwotICAgICAgLy8gU2V0IHRoZSBwYXJlbnQsIGFsdGhvdWdoIHRoZSB3YXMgd2UgYXJlIHVzaW5nIGF0dHJpYnV0ZXMKLSAgICAgIC8vIGluIHRoZSBTUUwgZXh0ZW5zaW9uIHRoaXMgcmVmZXJlbmNlIHdpbGwgbW9yZSB0aGFuIGxpa2x5Ci0gICAgICAvLyBiZSB3cm9uZwotICAgICAgbV9wYXJlbnQuc2V0RWxlbWVudEF0KHBub2RlLCBhdHRyaWIpOwotICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChEVE0uTlVMTCwgYXR0cmliKTsKLQotICAgICAgaWYgKG1fYXR0cmlidXRlLmVsZW1lbnRBdChwbm9kZSkgIT0gRFRNLk5VTEwpCi0gICAgICB7Ci0gICAgICAgIC8vIE9LLCB3ZSBhbHJlYWR5IGhhdmUgYW4gYXR0cmlidXRlIGFzc2lnbmVkIHRvIHRoaXMKLSAgICAgICAgLy8gTm9kZSwgSW5zZXJ0IHVzIGludG8gdGhlIGhlYWQgb2YgdGhlIGxpc3QuCi0gICAgICAgIGxhc3RhdHRyaWIgPSBtX2F0dHJpYnV0ZS5lbGVtZW50QXQocG5vZGUpOwotICAgICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KGxhc3RhdHRyaWIsIGF0dHJpYik7Ci0gICAgICAgIG1fcHJldnNpYi5zZXRFbGVtZW50QXQoYXR0cmliLCBsYXN0YXR0cmliKTsKLSAgICAgIH0KLSAgICAgIC8vIE9rYXkgc2V0IHRoZSBuZXcgYXR0cmlidXRlIHVwIGFzIHRoZSBmaXJzdCBhdHRyaWJ1dGUKLSAgICAgIC8vIGZvciB0aGUgbm9kZS4KLSAgICAgIG1fYXR0cmlidXRlLnNldEVsZW1lbnRBdChhdHRyaWIsIHBub2RlKTsKLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZXJyb3IoIkVycm9yIGluIGFkZEF0dHJpYnV0ZVRvTm9kZTogIitlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGF0dHJpYjsKLSAgfQotCi0gIC8qKgotICAgKiBBbGxvdyB0d28gbm9kZXMgdG8gc2hhcmUgdGhlIHNhbWUgc2V0IG9mIGF0dHJpYnV0ZXMuIFRoZXJlIG1heSBiZSBzb21lCi0gICAqIHByb2JsZW1zIGJlY2F1c2UgdGhlIHBhcmVudCBvZiBhbnkgYXR0cmlidXRlIHdpbGwgYmUgdGhlIG9yaWdpbmFsIG5vZGUKLSAgICogdGhleSB3ZXJlIGFzc2lnbmVkIHRvLiBOZWVkIHRvIHNlZSBob3cgdGhlIGF0dHJpYnV0ZSB3YWxrZXIgd29ya3MsIHRoZW4KLSAgICogd2Ugc2hvdWxkIGJlIGFibGUgdG8gZmFrZSBpdCBvdXQuCi0gICAqIEBwYXJhbSB0b05vZGUKLSAgICogQHBhcmFtIGZyb21Ob2RlCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNsb25lQXR0cmlidXRlRnJvbU5vZGUoIGludCB0b05vZGUsIGludCBmcm9tTm9kZSApCi0gIHsKLSAgIHRyeQotICAgIHsKLSAgICAgIGlmIChtX2F0dHJpYnV0ZS5lbGVtZW50QXQodG9Ob2RlKSAhPSBEVE0uTlVMTCkKLSAgICAgIHsKLSAgICAgICAgZXJyb3IoIkNsb25laW5nIEF0dHJpYnV0ZXMsIHdoZXJlIGZyb20gTm9kZSBhbHJlYWR5IGhhZCBhZGR0aWJ1cmVzIGFzc2lnbmVkIik7Ci0gICAgICB9Ci0KLSAgICAgIG1fYXR0cmlidXRlLnNldEVsZW1lbnRBdChtX2F0dHJpYnV0ZS5lbGVtZW50QXQoZnJvbU5vZGUpLCB0b05vZGUpOwotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlcnJvcigiQ2xvbmluZyBhdHRyaWJ1dGVzIik7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3RBdHRyaWJ1dGUoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0Rmlyc3RBdHRyaWJ1dGUoIisgKHBhcm0xJk5PREVJREVOVElUWUJJVFMpKyIpIik7Ci0gICAgaW50IG5vZGVJZHggPSBwYXJtMSAmIE5PREVJREVOVElUWUJJVFM7Ci0gICAgaWYgKG5vZGVJZHggIT0gRFRNLk5VTEwpIHJldHVybiBtX2F0dHJpYnV0ZS5lbGVtZW50QXQobm9kZUlkeCkgfCBtX2R0bUlkZW50OwotICAgIGVsc2UgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5vZGVWYWx1ZSgiICsgcGFybTEgKyAiKSIpOwotICAgIHRyeQotICAgIHsKLSAgICAgIE9iamVjdCBvID0gbV9PYmplY3RBcnJheS5nZXRBdChwYXJtMSAmIE5PREVJREVOVElUWUJJVFMpOwotICAgICAgaWYgKG8gIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG8udG9TdHJpbmcoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuICIiOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlcnJvcigiR2V0dGluZyBTdHJpbmcgVmFsdWUiKTsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldFN0cmluZ1ZhbHVlKCIgKyBwYXJtMSArICIpIik7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgT2JqZWN0IG8gPSBtX09iamVjdEFycmF5LmdldEF0KHBhcm0xICYgTk9ERUlERU5USVRZQklUUyk7Ci0gICAgICBpZiAobyAhPSBudWxsKQotICAgICAgewotICAgICAgICByZXR1cm4gbV94c3RyZi5uZXdzdHIoby50b1N0cmluZygpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1feHN0cmYuZW1wdHlzdHIoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZXJyb3IoIkdldHRpbmcgU3RyaW5nIFZhbHVlIik7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0QXR0cmlidXRlKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5leHRBdHRyaWJ1dGUoIiArIHBhcm0xICsgIikiKTsKLSAgICBpbnQgbm9kZUlkeCA9IHBhcm0xICYgTk9ERUlERU5USVRZQklUUzsKLSAgICBpZiAobm9kZUlkeCAhPSBEVE0uTlVMTCkgcmV0dXJuIG1fbmV4dHNpYi5lbGVtZW50QXQobm9kZUlkeCkgfCBtX2R0bUlkZW50OwotICAgIGVsc2UgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLQotICAvKioKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXROdW1iZXJPZk5vZGVzKCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0TnVtYmVyT2ZOb2RlcygpIik7Ci0gICAgcmV0dXJuIG1fc2l6ZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBuZXh0Tm9kZSggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIm5leHROb2RlKCkiKTsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBUaGUgRXhwYW5kZWQgTmFtZSB0YWJsZSBob2xkcyBhbGwgb2Ygb3VyIE5vZGUgbmFtZXMuIFRoZSBCYXNlIGNsYXNzCi0gICAqIHdpbGwgYWRkIHRoZSBjb21tb24gZWxlbWVudCB0eXBlcywgbmVlZCB0byBjYWxsIHRoaXMgZnVuY3Rpb24gZnJvbQotICAgKiB0aGUgZGVyaXZlZCBjbGFzcy4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY3JlYXRlRXhwYW5kZWROYW1lVGFibGUoICkKLSAgewotICAgIG1fRG9jdW1lbnRfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfRE9DVU1FTlQsIERUTS5ET0NVTUVOVF9OT0RFKTsKLQotICAgIG1fVGV4dE5vZGVfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfVEVYVF9OT0RFLCBEVE0uVEVYVF9OT0RFKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXBEVE0oICkKLSAgewotICAgIHRyeQotICAgIHsKLS8vICAgICAgRmlsZSBmID0gbmV3IEZpbGUoIkRUTUR1bXAiKygoT2JqZWN0KXRoaXMpLmhhc2hDb2RlKCkrIi50eHQiKTsKLSAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKCJEVE1EdW1wLnR4dCIpOwotICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJEdW1waW5nLi4uICIrZi5nZXRBYnNvbHV0ZVBhdGgoKSk7Ci0gICAgICBQcmludFN0cmVhbSBwcyA9IG5ldyBQcmludFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmKSk7Ci0KLSAgICAgIHdoaWxlIChuZXh0Tm9kZSgpKXt9Ci0KLSAgICAgIGludCBuUmVjb3JkcyA9IG1fc2l6ZTsKLQotICAgICAgcHMucHJpbnRsbigiVG90YWwgbm9kZXM6ICIgKyBuUmVjb3Jkcyk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgblJlY29yZHM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgcHMucHJpbnRsbigiPT09PT09PT09PT0gIiArIGkgKyAiID09PT09PT09PT09Iik7Ci0gICAgICAgIHBzLnByaW50bG4oIk5vZGVOYW1lOiAiICsgZ2V0Tm9kZU5hbWUoaSkpOwotICAgICAgICBwcy5wcmludGxuKCJOb2RlTmFtZVg6ICIgKyBnZXROb2RlTmFtZVgoaSkpOwotICAgICAgICBwcy5wcmludGxuKCJMb2NhbE5hbWU6ICIgKyBnZXRMb2NhbE5hbWUoaSkpOwotICAgICAgICBwcy5wcmludGxuKCJOYW1lc3BhY2VVUkk6ICIgKyBnZXROYW1lc3BhY2VVUkkoaSkpOwotICAgICAgICBwcy5wcmludGxuKCJQcmVmaXg6ICIgKyBnZXRQcmVmaXgoaSkpOwotCi0gICAgICAgIGludCBleFR5cGVJRCA9IGdldEV4cGFuZGVkVHlwZUlEKGkpOwotCi0gICAgICAgIHBzLnByaW50bG4oIkV4cGFuZGVkIFR5cGUgSUQ6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSW50ZWdlci50b0hleFN0cmluZyhleFR5cGVJRCkpOwotCi0gICAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUoaSk7Ci0gICAgICAgIFN0cmluZyB0eXBlc3RyaW5nOwotCi0gICAgICAgIHN3aXRjaCAodHlwZSkKLSAgICAgICAgewotICAgICAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJBVFRSSUJVVEVfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJDREFUQV9TRUNUSU9OX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5DT01NRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiQ09NTUVOVF9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJET0NVTUVOVF9GUkFHTUVOVF9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJET0NVTUVOVF9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfVFlQRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkRPQ1VNRU5UX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRUxFTUVOVF9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRU5USVRZX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRU5USVRZX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRU5USVRZX1JFRkVSRU5DRV9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTkFNRVNQQUNFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiTkFNRVNQQUNFX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5OT1RBVElPTl9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIk5PVEFUSU9OX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5OVUxMIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIk5VTEwiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uVEVYVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIlRFWFRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiVW5rbm93biEiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgcHMucHJpbnRsbigiVHlwZTogIiArIHR5cGVzdHJpbmcpOwotCi0gICAgICAgIGludCBmaXJzdENoaWxkID0gX2ZpcnN0Y2goaSk7Ci0KLSAgICAgICAgaWYgKERUTS5OVUxMID09IGZpcnN0Q2hpbGQpCi0gICAgICAgICAgcHMucHJpbnRsbigiRmlyc3QgY2hpbGQ6IERUTS5OVUxMIik7Ci0gICAgICAgIGVsc2UgaWYgKE5PVFBST0NFU1NFRCA9PSBmaXJzdENoaWxkKQotICAgICAgICAgIHBzLnByaW50bG4oIkZpcnN0IGNoaWxkOiBOT1RQUk9DRVNTRUQiKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHBzLnByaW50bG4oIkZpcnN0IGNoaWxkOiAiICsgZmlyc3RDaGlsZCk7Ci0KLSAgICAgICAgaW50IHByZXZTaWJsaW5nID0gX3ByZXZzaWIoaSk7Ci0KLSAgICAgICAgaWYgKERUTS5OVUxMID09IHByZXZTaWJsaW5nKQotICAgICAgICAgIHBzLnByaW50bG4oIlByZXYgc2libGluZzogRFRNLk5VTEwiKTsKLSAgICAgICAgZWxzZSBpZiAoTk9UUFJPQ0VTU0VEID09IHByZXZTaWJsaW5nKQotICAgICAgICAgIHBzLnByaW50bG4oIlByZXYgc2libGluZzogTk9UUFJPQ0VTU0VEIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcy5wcmludGxuKCJQcmV2IHNpYmxpbmc6ICIgKyBwcmV2U2libGluZyk7Ci0KLSAgICAgICAgaW50IG5leHRTaWJsaW5nID0gX25leHRzaWIoaSk7Ci0KLSAgICAgICAgaWYgKERUTS5OVUxMID09IG5leHRTaWJsaW5nKQotICAgICAgICAgIHBzLnByaW50bG4oIk5leHQgc2libGluZzogRFRNLk5VTEwiKTsKLSAgICAgICAgZWxzZSBpZiAoTk9UUFJPQ0VTU0VEID09IG5leHRTaWJsaW5nKQotICAgICAgICAgIHBzLnByaW50bG4oIk5leHQgc2libGluZzogTk9UUFJPQ0VTU0VEIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcy5wcmludGxuKCJOZXh0IHNpYmxpbmc6ICIgKyBuZXh0U2libGluZyk7Ci0KLSAgICAgICAgaW50IHBhcmVudCA9IF9wYXJlbnQoaSk7Ci0KLSAgICAgICAgaWYgKERUTS5OVUxMID09IHBhcmVudCkKLSAgICAgICAgICBwcy5wcmludGxuKCJQYXJlbnQ6IERUTS5OVUxMIik7Ci0gICAgICAgIGVsc2UgaWYgKE5PVFBST0NFU1NFRCA9PSBwYXJlbnQpCi0gICAgICAgICAgcHMucHJpbnRsbigiUGFyZW50OiBOT1RQUk9DRVNTRUQiKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHBzLnByaW50bG4oIlBhcmVudDogIiArIHBhcmVudCk7Ci0KLSAgICAgICAgaW50IGxldmVsID0gX2xldmVsKGkpOwotCi0gICAgICAgIHBzLnByaW50bG4oIkxldmVsOiAiICsgbGV2ZWwpOwotICAgICAgICBwcy5wcmludGxuKCJOb2RlIFZhbHVlOiAiICsgZ2V0Tm9kZVZhbHVlKGkpKTsKLSAgICAgICAgcHMucHJpbnRsbigiU3RyaW5nIFZhbHVlOiAiICsgZ2V0U3RyaW5nVmFsdWUoaSkpOwotCi0gICAgICAgIHBzLnByaW50bG4oIkZpcnN0IEF0dHJpYnV0ZSBOb2RlOiAiICsgbV9hdHRyaWJ1dGUuZWxlbWVudEF0KGkpKTsKLSAgICAgIH0KLQotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgaW9lLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKLSAgICAgIFN5c3RlbS5leGl0KC0xKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZSB0aGUgdGV4dCBjb250ZW50IG9mIGEgRE9NIHN1YnRyZWUsIGFwcGVuZGluZyBpdCBpbnRvIGEKLSAgICogdXNlci1zdXBwbGllZCBGYXN0U3RyaW5nQnVmZmVyIG9iamVjdC4gTm90ZSB0aGF0IGF0dHJpYnV0ZXMgYXJlCi0gICAqIG5vdCBjb25zaWRlcmVkIHBhcnQgb2YgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGFyZSBvcGVuIHF1ZXN0aW9ucyByZWdhcmRpbmcgd2hpdGVzcGFjZSBzdHJpcHBpbmcuCi0gICAqIEN1cnJlbnRseSB3ZSBtYWtlIG5vIHNwZWNpYWwgZWZmb3J0IGluIHRoYXQgcmVnYXJkLCBzaW5jZSB0aGUgc3RhbmRhcmQKLSAgICogRE9NIGRvZXNuJ3QgeWV0IHByb3ZpZGUgRFRELWJhc2VkIGluZm9ybWF0aW9uIHRvIGRpc3Rpbmd1aXNoCi0gICAqIHdoaXRlc3BhY2UtaW4tZWxlbWVudC1jb250ZXh0IGZyb20gZ2VudWluZSAjUENEQVRBLiBOb3RlIHRoYXQgd2UKLSAgICogc2hvdWxkIHByb2JhYmx5IGFsc28gY29uc2lkZXIgeG1sOnNwYWNlIGlmL3doZW4gd2UgYWRkcmVzcyB0aGlzLgotICAgKiBET00gTGV2ZWwgMyBtYXkgc29sdmUgdGhlIHByb2JsZW0gZm9yIHVzLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgTm90ZSB0aGF0IGFzIGEgRE9NLWxldmVsIG9wZXJhdGlvbiwgaXQgY2FuIGJlIGFyZ3VlZCB0aGF0IHRoaXMKLSAgICogcm91dGluZSBfc2hvdWxkbid0XyBwZXJmb3JtIGFueSBwcm9jZXNzaW5nIGJleW9uZCB3aGF0IHRoZSBET00gYWxyZWFkeQotICAgKiBkb2VzLCBhbmQgdGhhdCB3aGl0ZXNwYWNlIHN0cmlwcGluZyBhbmQgc28gb24gYmVsb25nIGF0IHRoZSBEVE0gbGV2ZWwuCi0gICAqIElmIHlvdSB3YW50IGEgc3RyaXBwZWQgRE9NIHZpZXcsIHdyYXAgRFRNMkRPTSBhcm91bmQgRE9NMkRUTS4KLSAgICogQHBhcmFtIG5vZGUgTm9kZSB3aG9zZSBzdWJ0cmVlIGlzIHRvIGJlIHdhbGtlZCwgZ2F0aGVyaW5nIHRoZQotICAgKiBjb250ZW50cyBvZiBhbGwgVGV4dCBvciBDREFUQVNlY3Rpb24gbm9kZXMuCi0gICAqIEBwYXJhbSBjaAotICAgKiBAcGFyYW0gZGVwdGgKLSAgICogQHJldHVybgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGRpc3BhdGNoTm9kZURhdGEoIE5vZGUgbm9kZSwgQ29udGVudEhhbmRsZXIgY2gsIGludCBkZXB0aCApdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiAKLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IG51bGwgIT0gY2hpbGQ7Ci0gICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkKLSAgICAgIHsKLSAgICAgICAgZGlzcGF0Y2hOb2RlRGF0YShjaGlsZCwgY2gsIGRlcHRoKzEpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDogLy8gJVJFVklFVyUKLSAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICAgIGlmKDAgIT0gZGVwdGgpCi0gICAgICAgIGJyZWFrOwotICAgICAgICAvLyBOT1RFOiBCZWNhdXNlIHRoaXMgb3BlcmF0aW9uIHdvcmtzIGluIHRoZSBET00gc3BhY2UsIGl0IGRvZXMgX25vdF8gYXR0ZW1wdAotICAgICAgICAvLyB0byBwZXJmb3JtIFRleHQgQ29hbGl0aW9uLiBUaGF0IHNob3VsZCBvbmx5IGJlIGRvbmUgaW4gRFRNIHNwYWNlLgotICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICBTdHJpbmcgc3RyID0gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAgIGlmKGNoIGluc3RhbmNlb2YgQ2hhcmFjdGVyTm9kZUhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgICgoQ2hhcmFjdGVyTm9kZUhhbmRsZXIpY2gpLmNoYXJhY3RlcnMobm9kZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGNoLmNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksIDAsIHN0ci5sZW5ndGgoKSk7Ci0gICAgICB9Ci0gICAgICBicmVhazsKLS8vICAgIC8qIGNhc2UgTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotLy8gICAgICAvLyB3YXJuaW5nKFhQQVRIRXJyb3JSZXNvdXJjZXMuV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HKTsKLS8vICAgICAgYnJlYWs7ICovCi0gICAgZGVmYXVsdCA6Ci0gICAgICAvLyBpZ25vcmUKLSAgICAgIGJyZWFrOwotICAgIH0KLSAgfQotCi0gIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gIC8qKioqKioqKioqKioqKioqKioqIEVuZCBvZiBGdW5jdGlvbnMgd2UgV3JvdGUgKioqKioqKioqKioqKioqKioqKioqKiovCi0gIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLQotICAvKioKLSAgICogRm9yIHRoZSBtb21lbnQgYWxsIHRoZSBydW4gdGltZSBwcm9wZXJ0aWVzIGFyZSBpZ25vcmVkIGJ5IHRoaXMKLSAgICogY2xhc3MuCi0gICAqIEBwYXJhbSBwcm9wZXJ0eSBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoIFN0cmluZyBwcm9wZXJ0eSwgT2JqZWN0IHZhbHVlICkKLSAgewotICB9Ci0KLSAgLyoqCi0gICAqIE5vIHNvdXJjZSBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgZm9yIERPTTJEVE0sIHNvIHJldHVybgotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBoZXJlLgotICAgKiBAcGFyYW0gbm9kZSBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvciggaW50IG5vZGUgKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGVJZGVudGl0eSggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXROZXh0Tm9kZUlkZW50eSgiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHBhcmFtIHBhcm0yCi0gICAqIEBwYXJhbSBwYXJtMwotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoIGludCBwYXJtMSwgU3RyaW5nIHBhcm0yLCBTdHJpbmcgcGFybTMgKQotICB7Ci0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICAgImdldEF0dHJpYnV0ZU5vZGUoIiArCi0gICAgICAgIHBhcm0xICsgIiwiICsKLSAgICAgICAgcGFybTIgKyAiLCIgKwotICAgICAgICBwYXJtMyArICIpIik7Ci0gICAgfQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoIGludCBwYXJtMSApCi0gIHsKLSAgICBpbnQgZXhJRCA9IHRoaXMuZ2V0RXhwYW5kZWRUeXBlSUQoIHBhcm0xICYgTk9ERUlERU5USVRZQklUUyApOwotCi0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIERFQlVHID0gZmFsc2U7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJnZXRMb2NhbE5hbWUoIiArIHBhcm0xICsgIikgLT4gIik7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi4uLiIgKyBnZXRMb2NhbE5hbWVGcm9tRXhwYW5kZWROYW1lSUQoZXhJRCkgKTsKLSAgICAgIERFQlVHID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZ2V0TG9jYWxOYW1lRnJvbUV4cGFuZGVkTmFtZUlEKGV4SUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaW50IGV4SUQgPSB0aGlzLmdldEV4cGFuZGVkVHlwZUlEKCBwYXJtMSAmIE5PREVJREVOVElUWUJJVFMgKTsKLSAgICBpZiAoREVCVUcpCi0gICAgewotICAgICAgREVCVUcgPSBmYWxzZTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoImdldExvY2FsTmFtZSgiICsgcGFybTEgKyAiKSAtPiAiKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLi4uIiArIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChleElEKSApOwotICAgICAgREVCVUcgPSB0cnVlOwotICAgIH0KLSAgICByZXR1cm4gZ2V0TG9jYWxOYW1lRnJvbUV4cGFuZGVkTmFtZUlEKGV4SUQpOwotICB9Ci0KLSAgIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGVTcGVjaWZpZWQoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiaXNBdHRyaWJ1dGVTcGVjaWZpZWQoIiArIHBhcm0xICsgIikiKTsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VW5wYXJzZWRFbnRpdHlVUkkoIFN0cmluZyBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0VW5wYXJzZWRFbnRpdHlVUkkoIiArIHBhcm0xICsgIikiKTsKLSAgICByZXR1cm4gIiI7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIERUREhhbmRsZXIgZ2V0RFRESGFuZGxlciggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldERUREhhbmRsZXIoKSIpOwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXRQcmVmaXgoIiArIHBhcm0xICArICIpIik7Ci0gICAgcmV0dXJuICIiOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBFbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlciggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldEVudGl0eVJlc29sdmVyKCkiKTsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uUHVibGljSWRlbnRpZmllciggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldF9EVERfUHViSWQoKSIpOwotICAgIHJldHVybiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgTGV4aWNhbEhhbmRsZXIgZ2V0TGV4aWNhbEhhbmRsZXIoICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXRMZXhpY2FsSGFuZGxlcigpIik7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIG5lZWRzVHdvVGhyZWFkcyggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIm5lZWRzVHdvVGhyZWFkcygpIik7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlciggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldENvbnRlbnRIYW5kbGVyKCkiKTsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHBhcmFtIHBhcm0yCi0gICAqIEByZXR1cm4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICogQHJldHVybgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hUb0V2ZW50cyggaW50IHBhcm0xLCBDb250ZW50SGFuZGxlciBwYXJtMiApdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiAKLSAgewotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAiZGlzcGF0aGNUb0V2ZW50cygiICsKLSAgICAgIHBhcm0xICsgIiwiICsKLSAgICAgIHBhcm0yICsgIikiKTsKLSAgICB9Ci0gICAgcmV0dXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXROYW1lc3BhY2VVUkkoIiArcGFybTErIikiKTsKLSAgICByZXR1cm4gIiI7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUKLSAgICogQHBhcmFtIGNoCi0gICAqIEBwYXJhbSBub3JtYWxpemUKLSAgICogQHJldHVybgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoIGludCBub2RlSGFuZGxlLCBDb250ZW50SGFuZGxlciBjaCwgYm9vbGVhbiBub3JtYWxpemUgKXRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gCi0gIHsKLSAgICBpZiAoREVCVUcpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJkaXNwYXRjaENoYXJhY3RlckV2ZW50cygiICsKLSAgICAgIG5vZGVIYW5kbGUgKyAiLCIgKwotICAgICAgY2ggKyAiLCIgKwotICAgICAgbm9ybWFsaXplICsgIikiKTsKLSAgICB9Ci0KLSAgICBpZihub3JtYWxpemUpCi0gICAgewotICAgICAgWE1MU3RyaW5nIHN0ciA9IGdldFN0cmluZ1ZhbHVlKG5vZGVIYW5kbGUpOwotICAgICAgc3RyID0gc3RyLmZpeFdoaXRlU3BhY2UodHJ1ZSwgdHJ1ZSwgZmFsc2UpOwotICAgICAgc3RyLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhjaCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLSAgICAgIGRpc3BhdGNoTm9kZURhdGEobm9kZSwgY2gsIDApOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBFdmVudCBvdmVycmlkaW5nIGZvciBEZWJ1ZwotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1ByZVN0cmlwcGluZyggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInN1cHBvcnRzUHJlU3RyaXBwaW5nKCkiKTsKLSAgICByZXR1cm4gc3VwZXIuc3VwcG9ydHNQcmVTdHJpcHBpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfZXhwdHlwZSggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJfZXhwdHlwZSgiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBzdXBlci5fZXhwdHlwZSggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yIGZpbmROYW1lc3BhY2VDb250ZXh0KCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIlN1YmFsbG9jYXRlZEludFZlY3RvcigiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBzdXBlci5maW5kTmFtZXNwYWNlQ29udGV4dCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9wcmV2c2liKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIl9wcmV2c2liKCIgKyBwYXJtMSsgIikiKTsKLSAgICByZXR1cm4gc3VwZXIuX3ByZXZzaWIoIHBhcm0xKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgc2hvcnQgX3R5cGUoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiX3R5cGUoIiArIHBhcm0xICsgIikiKTsKLSAgICByZXR1cm4gc3VwZXIuX3R5cGUoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Tm9kZSggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXROb2RlKCIgKyBwYXJtMSArICIpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmdldE5vZGUoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcmV2aW91c1NpYmxpbmcoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0UHJldlNpYigiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRQcmV2aW91c1NpYmxpbmcoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN0YW5kYWxvbmUoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0RE9jU3RhbmRBbG9uZSgiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXREb2N1bWVudFN0YW5kYWxvbmUoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0Tm9kZU5hbWVYKCIgKyBwYXJtMSArICIpIik7Ci0gICAgLy9yZXR1cm4gc3VwZXIuZ2V0Tm9kZU5hbWVYKCBwYXJtMSk7Ci0gICAgcmV0dXJuIGdldE5vZGVOYW1lKHBhcm0xKTsKLQotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RmVhdHVyZSggU3RyaW5nIHBhcm0xLCBib29sZWFuIHBhcm0yICkKLSAgewotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAgICJzZXRGZWF0dXJlKCIgKwotICAgICAgICBwYXJtMSArICIsIiArCi0gICAgICAgIHBhcm0yICsgIikiKTsKLSAgICB9Ci0gICAgc3VwZXIuc2V0RmVhdHVyZSggcGFybTEsICBwYXJtMik7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX3BhcmVudCggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJfcGFyZW50KCIgKyBwYXJtMSArICIpIik7Ci0gICAgcmV0dXJuIHN1cGVyLl9wYXJlbnQoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHBhcmFtIHBhcm0yCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluZGV4Tm9kZSggaW50IHBhcm0xLCBpbnQgcGFybTIgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImluZGV4Tm9kZSgiK3Bhcm0xKyIsIitwYXJtMisiKSIpOwotICAgIHN1cGVyLmluZGV4Tm9kZSggcGFybTEsICBwYXJtMik7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U2hvdWxkU3RyaXBXUygpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmdldFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHBvcFNob3VsZFN0cmlwV2hpdGVzcGFjZSggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInBvcFNob3VsZFN0cmlwV1MoKSIpOwotICAgIHN1cGVyLnBvcFNob3VsZFN0cmlwV2hpdGVzcGFjZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2RlQWZ0ZXIoIGludCBwYXJtMSwgaW50IHBhcm0yICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJpc05vZGVBZnRlcigiICsgcGFybTEgKyAiLCIgKyBwYXJtMiArICIpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmlzTm9kZUFmdGVyKCBwYXJtMSwgIHBhcm0yKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXROYW1lc3BhY2VUeXBlKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5hbWVzcGFjZVR5cGUoIiArIHBhcm0xICsgIikiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0TmFtZXNwYWNlVHlwZSggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9sZXZlbCggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJfbGV2ZWwoIiArIHBhcm0xICsgIikiKTsKLSAgICByZXR1cm4gc3VwZXIuX2xldmVsKCBwYXJtMSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgcHVzaFNob3VsZFN0cmlwV2hpdGVzcGFjZSggYm9vbGVhbiBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigicHVzaF9TaG91bGRTdHJpcFdTKCIgKyBwYXJtMSArICIpIik7Ci0gICAgc3VwZXIucHVzaFNob3VsZFN0cmlwV2hpdGVzcGFjZSggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VmVyc2lvbiggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXREb2NWZXIoIitwYXJtMSsiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXREb2N1bWVudFZlcnNpb24oIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHBhcmFtIHBhcm0yCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKCBTdHJpbmcgcGFybTEsIFN0cmluZyBwYXJtMiApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiaXNTdXBwb3J0ZWQoIitwYXJtMSsiLCIrcGFybTIrIikiKTsKLSAgICByZXR1cm4gc3VwZXIuaXNTdXBwb3J0ZWQoIHBhcm0xLCAgcGFybTIpOwotICB9Ci0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHNldFNob3VsZFN0cmlwV2hpdGVzcGFjZSggYm9vbGVhbiBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigic2V0X1Nob3VsZFN0cmlwV1MoIitwYXJtMSsiKSIpOwotICAgIHN1cGVyLnNldFNob3VsZFN0cmlwV2hpdGVzcGFjZSggcGFybTEpOwotICB9Ci0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEBwYXJhbSBwYXJtMgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlbnN1cmVTaXplT2ZJbmRleCggaW50IHBhcm0xLCBpbnQgcGFybTIgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImVuc3VyZVNpemVPZkluZGV4KCIrcGFybTErIiwiK3Bhcm0yKyIpIik7Ci0gICAgc3VwZXIuZW5zdXJlU2l6ZU9mSW5kZXgoIHBhcm0xLCAgcGFybTIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlbnN1cmVTaXplKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImVuc3VyZVNpemUoIitwYXJtMSsiKSIpOwotCi0gICAgLy8gSW50VmVjdG9ycyBpbiBEVE1EZWZhdWx0QmFzZSBhcmUgbm93IHNlbGYtc2l6aW5nLCBhbmQgZW5zdXJlU2l6ZSgpCi0gICAgLy8gaXMgYmVpbmcgZHJvcHBlZC4KLSAgICAvL3N1cGVyLmVuc3VyZVNpemUoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEVuY29kaW5nKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldERvY3VtZW50RW5jb2RpbmcoIitwYXJtMSsiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXREb2N1bWVudEVuY29kaW5nKCBwYXJtMSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEBwYXJhbSBwYXJtMgotICAgKiBAcGFyYW0gcGFybTMKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kQ2hpbGQoIGludCBwYXJtMSwgYm9vbGVhbiBwYXJtMiwgYm9vbGVhbiBwYXJtMyApCi0gIHsKLSAgICBpZiAoREVCVUcpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAiYXBwZW5kQ2hpbGQoIiArCi0gICAgICAgIHBhcm0xICsgIiwiICsKLSAgICAgICAgcGFybTIgKyAiLCIgKwotICAgICAgICBwYXJtMyArICIpIik7Ci0gICAgfQotICAgIHN1cGVyLmFwcGVuZENoaWxkKCBwYXJtMSwgIHBhcm0yLCAgcGFybTMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0TGV2ZWwoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0TGV2ZWwoIitwYXJtMSsiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRMZXZlbCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRCYXNlVVJJKCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0RG9jQmFzZVVSSSgpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmdldERvY3VtZW50QmFzZVVSSSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHBhcmFtIHBhcm0zCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dE5hbWVzcGFjZU5vZGUoIGludCBwYXJtMSwgaW50IHBhcm0yLCBib29sZWFuIHBhcm0zICkKLSAgewotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAiZ2V0TmV4dE5hbWVzYXBjZU5vZGUoIiArCi0gICAgICBwYXJtMSArICIsIiArCi0gICAgICBwYXJtMiArICIsIiArCi0gICAgICBwYXJtMyArICIpIik7Ci0gICAgfQotICAgIHJldHVybiBzdXBlci5nZXROZXh0TmFtZXNwYWNlTm9kZSggcGFybTEsICBwYXJtMiwgIHBhcm0zKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVGV4dENoaWxkKCBTdHJpbmcgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImFwcGVuZFRleHRDaGlsZCgiICsgcGFybTEgKyAiKSIpOwotICAgIHN1cGVyLmFwcGVuZFRleHRDaGlsZCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHBhcmFtIHBhcm0zCi0gICAqIEBwYXJhbSBwYXJtNAotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGZpbmRHVEUoIGludFtdIHBhcm0xLCBpbnQgcGFybTIsIGludCBwYXJtMywgaW50IHBhcm00ICkKLSAgewotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oCi0gICAgICAiZmluZEdURSgiKwotICAgICAgcGFybTEgKyAiLCIgKwotICAgICAgcGFybTIgKyAiLCIgKwotICAgICAgcGFybTMgKyAiKSIpOwotICAgIH0KLSAgICByZXR1cm4gc3VwZXIuZmluZEdURSggcGFybTEsICBwYXJtMiwgIHBhcm0zLCAgcGFybTQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRGaXJzdE5hbWVzcGFjZU5vZGUoIGludCBwYXJtMSwgYm9vbGVhbiBwYXJtMiApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKCkiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKCBwYXJtMSwgIHBhcm0yKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRTdHJpbmdWYWx1ZUNodW5rQ291bnQoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U3RyaW5nQ2h1bmtDb3VudCgiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRTdHJpbmdWYWx1ZUNodW5rQ291bnQoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0Q2hpbGQoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0TGFzdENoaWxkKCIgKyBwYXJtMSArICIpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmdldExhc3RDaGlsZCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImhhc0NoaWxkTm9kZXMoIiArIHBhcm0xICsgIikiKTsKLSAgICByZXR1cm4gc3VwZXIuaGFzQ2hpbGROb2RlcyggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpCi0gICAgewotICAgICAgREVCVUc9ZmFsc2U7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJnZXROb2RlVHlwZSgiICsgKHBhcm0xICYgTk9ERUlERU5USVRZQklUUykgKyAiKSAiKTsKLSAgICAgIGludCBleElEID0gdGhpcy5nZXRFeHBhbmRlZFR5cGVJRCggcGFybTEgJiBOT0RFSURFTlRJVFlCSVRTICk7Ci0gICAgICBTdHJpbmcgbmFtZSA9IGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChleElEKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICAgIi4uIE5vZGUgbmFtZSBbIiArIG5hbWUgKyAiXSIgKwotICAgICAgICAiWyIgKyBnZXROb2RlVHlwZSggcGFybTEpICsgIl0iKTsKLQotICAgICAgREVCVUc9dHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3VwZXIuZ2V0Tm9kZVR5cGUoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNDaGFyYWN0ZXJFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiaXNDaGFyYWN0ZXJFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoIiArIHBhcm0xICsiKSIpOwotICAgIHJldHVybiBzdXBlci5pc0NoYXJhY3RlckVsZW1lbnRDb250ZW50V2hpdGVzcGFjZSggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEZpcnN0Q2hpbGQoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0Rmlyc3RDaGlsZCgiICsgcGFybTEgKyAiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRGaXJzdENoaWxkKCBwYXJtMSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTeXN0ZW1JZGVudGlmaWVyKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldERvY1N5c0lEKCIgKyBwYXJtMSArICIpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmdldERvY3VtZW50U3lzdGVtSWRlbnRpZmllciggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZGVjbGFyZU5hbWVzcGFjZUluQ29udGV4dCggaW50IHBhcm0xLCBpbnQgcGFybTIgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImRlY2xhcmVOYW1lc3BhY2VDb250ZXh0KCIrcGFybTErIiwiK3Bhcm0yKyIpIik7Ci0gICAgc3VwZXIuZGVjbGFyZU5hbWVzcGFjZUluQ29udGV4dCggcGFybTEsICBwYXJtMik7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIERFQlVHID0gZmFsc2U7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJnZXROYW1lc3BhY2VGcm9tRXhwYW5kZWROYW1lSUQoIitwYXJtMSsiKSIpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIuLi4iICsgc3VwZXIuZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKCBwYXJtMSkgKTsKLSAgICAgIERFQlVHID0gdHJ1ZTsKLSAgICB9Ci0gICAgcmV0dXJuIHN1cGVyLmdldE5hbWVzcGFjZUZyb21FeHBhbmRlZE5hbWVJRCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRCggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBERUJVRyA9IGZhbHNlOwotICAgICAgU3lzdGVtLm91dC5wcmludCgiZ2V0TG9jYWxOYW1lRnJvbUV4cGFuZGVkTmFtZUlEKCIrcGFybTErIikiKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLi4uIiArIHN1cGVyLmdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRCggcGFybTEpKTsKLSAgICAgIERFQlVHID0gdHJ1ZTsKLSAgICB9Ci0gICAgcmV0dXJuIHN1cGVyLmdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldEV4cGFuZGVkVHlwZUlEKCIrcGFybTErIikiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0RXhwYW5kZWRUeXBlSUQoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgaW50IGdldERvY3VtZW50KCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0RG9jdW1lbnQoKSIpOwotICAgIHJldHVybiBzdXBlci5nZXREb2N1bWVudCgpOwotICB9Ci0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEBwYXJhbSBwYXJtMgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGZpbmRJblNvcnRlZFN1YmFsbG9jYXRlZEludFZlY3RvciggU3ViYWxsb2NhdGVkSW50VmVjdG9yIHBhcm0xLCBpbnQgcGFybTIgKQotICB7Ci0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICJmaW5kSW5Tb3J0ZWRTdWJBbGxvY3RlZFZlY3RvcigiICsKLSAgICAgIHBhcm0xICsgIiwiICsKLSAgICAgIHBhcm0yICsgIikiKTsKLSAgICB9Ci0gICAgcmV0dXJuIHN1cGVyLmZpbmRJblNvcnRlZFN1YmFsbG9jYXRlZEludFZlY3RvciggcGFybTEsICBwYXJtMik7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiaXNEb2N1bWVudEFsbERlY2xQcm9jKCIrcGFybTErIikiKTsKLSAgICByZXR1cm4gc3VwZXIuaXNEb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlcnJvciggU3RyaW5nIHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJlcnJvcigiK3Bhcm0xKyIpIik7Ci0gICAgc3VwZXIuZXJyb3IoIHBhcm0xKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9maXJzdGNoKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIl9maXJzdGNoKCIrcGFybTErIikiKTsKLSAgICByZXR1cm4gc3VwZXIuX2ZpcnN0Y2goIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRPd25lckRvY3VtZW50KCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldE93bmVyRG9jKCIrcGFybTErIikiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0T3duZXJEb2N1bWVudCggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9uZXh0c2liKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIl9uZXh0U2liKCIrcGFybTErIikiKTsKLSAgICByZXR1cm4gc3VwZXIuX25leHRzaWIoIHBhcm0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0U2libGluZyggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXROZXh0U2libGluZygiK3Bhcm0xKyIpIik7Ci0gICAgcmV0dXJuIHN1cGVyLmdldE5leHRTaWJsaW5nKCBwYXJtMSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXREb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZCggKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldERvY0FsbERlY2xQcm9jKCkiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0RG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRQYXJlbnQoIGludCBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0UGFyZW50KCIrcGFybTErIikiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0UGFyZW50KCBwYXJtMSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEBwYXJhbSBwYXJtMgotICAgKiBAcGFyYW0gcGFybTMKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRCggU3RyaW5nIHBhcm0xLCBTdHJpbmcgcGFybTIsIGludCBwYXJtMyApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0RXhwYW5kZWRUeXBlSUQoKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRFeHBhbmRlZFR5cGVJRCggcGFybTEsICBwYXJtMiwgIHBhcm0zKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gcGFybTEKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRCYXNlVVJJKCBTdHJpbmcgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInNldERvY0Jhc2VVUkkoKSIpOwotICAgIHN1cGVyLnNldERvY3VtZW50QmFzZVVSSSggcGFybTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcGFyYW0gcGFybTIKLSAgICogQHBhcmFtIHBhcm0zCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBjaGFyW10gZ2V0U3RyaW5nVmFsdWVDaHVuayggaW50IHBhcm0xLCBpbnQgcGFybTIsIGludFtdIHBhcm0zICkKLSAgewotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImdldFN0cmluZ0NodW5rVmFsdWUoIiArCi0gICAgICBwYXJtMSArICIsIiArCi0gICAgICBwYXJtMiArICIpIik7Ci0gICAgfQotICAgIHJldHVybiBzdXBlci5nZXRTdHJpbmdWYWx1ZUNodW5rKCBwYXJtMSwgIHBhcm0yLCAgcGFybTMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc1RyYXZlcnNlciBnZXRBeGlzVHJhdmVyc2VyKCBpbnQgcGFybTEgKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdldEF4aXhUcmF2ZXJzZXIoIitwYXJtMSsiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRBeGlzVHJhdmVyc2VyKCBwYXJtMSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEBwYXJhbSBwYXJtMgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKCBpbnQgcGFybTEsIGludCBwYXJtMiApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0VHlwZWRBeGlzSXRlcmF0b3IoIitwYXJtMSsiLCIrcGFybTIrIikiKTsKLSAgICByZXR1cm4gc3VwZXIuZ2V0VHlwZWRBeGlzSXRlcmF0b3IoIHBhcm0xLCAgcGFybTIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBwYXJtMQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvciggaW50IHBhcm0xICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXRBeGlzSXRlcmF0b3IoIitwYXJtMSsiKSIpOwotICAgIHJldHVybiBzdXBlci5nZXRBeGlzSXRlcmF0b3IoIHBhcm0xKTsKLSAgfQotICAvKioKLSAgICogQHBhcmFtIHBhcm0xCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RWxlbWVudEJ5SWQoIFN0cmluZyBwYXJtMSApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0RWxlbWVudEJ5SUQoIitwYXJtMSsiKSIpOwotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgRGVjbEhhbmRsZXIgZ2V0RGVjbEhhbmRsZXIoICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXREZWNsSGFuZGxlcigpIik7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIEVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnZXRFcnJvckhhbmRsZXIoKSIpOwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0X0RURC1TSUQoKSIpOwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9EZWZhdWx0Q29ubmVjdGlvblBvb2wuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvRGVmYXVsdENvbm5lY3Rpb25Qb29sLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmOTIxZWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9EZWZhdWx0Q29ubmVjdGlvblBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU4NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsOwotCi1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS5sYW5nLlN0cmluZzsKLWltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOwotaW1wb3J0IGphdmEuc3FsLlNRTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhOwotaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgamF2YS5zcWwuKjsKLQotLyoqCi0gKiBGb3IgaW50ZXJuYWwgY29ubmVjdGlvbmVzLCBpLmUuIENvbm5lY3Rpb24gaW5mb3JtYXRpb24gc3VwcGxpZXMgaW4gdGhlCi0gKiBTdHlsZXNoZWV0LiBUaGUgRGVmYXVsdCBDb25uZWN0aW9uIFBvb2wgd2lsbCBiZSB1c2VkLgotICovCi1wdWJsaWMgY2xhc3MgRGVmYXVsdENvbm5lY3Rpb25Qb29sIGltcGxlbWVudHMgQ29ubmVjdGlvblBvb2wKLXsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFRoZSBiYXNpYyBpbmZvcm1hdGlvbiB0byBtYWtlIGEgSkRCQyBDb25uZWN0aW9uCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX2RyaXZlciA9IG5ldyBTdHJpbmcoIiIpOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fdXJsID0gbmV3IFN0cmluZygiIik7Ci0KLQotICAvKioKLSAgICogVGhlIG1pbWltdW0gc2l6ZSBvZiB0aGUgY29ubmVjdGlvbiBwb29sLCBpZiB0aGUKLSAgICogbnVtYmVyIG9mIGF2YWlsYWJsZSBjb25uZWN0aW9ucyBmYWxscyBiZWxvdyB0aGlzCi0gICAqIG1hcmssIG1pbiBjb25uZWN0aW9ucyB3aWxsIGJlIGFsbG9jYXRlZC4gVGhlIENvbm5lY3Rpb24KLSAgICogUG9vbCB3aWxsIGFsd2F5cyBiZSBzb21ld2hlcmUgYmV0d2VlbiBNaW5TaXplIGFuZCBNaW5TaXplKjIKLSAgICovCi0gIHByaXZhdGUgaW50IG1fUG9vbE1pblNpemUgPSAxOwotCi0KLSAgLyoqCi0gICAqIEFsd2F5cyBpbXBsZW1lbnQgdGhlIHByb3BlcnRpZXMgbWVjaGluaXNtLCBpZiB0aGUgUGFzc3dvcmQKLSAgICogb3IgVXNlcm5hbWUgaXMgc2V0IHNlcGVyYXRseSB0aGVuIHdlIHdpbGwgYWRkIHRoZW0gdG8gdGhlCi0gICAqIHByb3BlcnR5IG1hbnVhbGx5LgotICAgKi8KLSAgcHJpdmF0ZSBQcm9wZXJ0aWVzIG1fQ29ubmVjdGlvblByb3RvY29sID0gbmV3IFByb3BlcnRpZXMoKTsKLQotICAvKioKLSAgICogU3RvcmFnZSBmb3IgdGhlIFBvb2xlZENvbm5lY3Rpb25zCi0gICAqLwotICBwcml2YXRlIFZlY3RvciBtX3Bvb2wgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIEFyZSB3ZSBhY3RpdmUgPz8KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX0lzQWN0aXZlID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqLwotICBwdWJsaWMgRGVmYXVsdENvbm5lY3Rpb25Qb29sKCApIHt9Ci0KLQotICAvKioKLSAgICogUmV0dXJuIG91ciBjdXJyZW50IEFjdGl2ZSBzdGF0ZQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQoICkKLSAgewotICAgIHJldHVybiBtX0lzQWN0aXZlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZHJpdmVyIGNhbGwgdG8gYmUgdXNlZCB0byBjcmVhdGUgY29ubmVjdGlvbnMKLSAgICogQHBhcmFtIGQKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RHJpdmVyKCBTdHJpbmcgZCApCi0gIHsKLSAgICBtX2RyaXZlciA9IGQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB1cmwgdXNlZCB0byBjb25uZWN0IHRvIHRoZSBkYXRhYmFzZQotICAgKiBAcGFyYW0gdXJsCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFVSTCggU3RyaW5nIHVybCApCi0gIHsKLSAgICBtX3VybCA9IHVybDsKLSAgfQotCi0gIC8qKgotICAgKiBHbyB0aHJvdWdoIHRoZSBjb25uZWN0aW9uIHBvb2wgYW5kIHJlbGVhc2UgYW55IGNvbm5lY3Rpb25zCi0gICAqIHRoYXQgYXJlIG5vdCBJblVzZTsKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgZnJlZVVudXNlZCggKQotICB7Ci0gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBlbnRpcmUgcG9vbCBjbG9zaW5nIHRoZQotICAgIC8vIEpEQkMgQ29ubmVjdGlvbnMuCi0gICAgZm9yICggaW50IHggPSAwOyB4IDwgbV9wb29sLnNpemUoKTsgeCsrICkKLSAgICB7Ci0KLQotICAgICAgUG9vbGVkQ29ubmVjdGlvbiBwY29uID0KLSAgICAgICAgKFBvb2xlZENvbm5lY3Rpb24pIG1fcG9vbC5lbGVtZW50QXQoeCk7Ci0KLSAgICAgIC8vIElmIHRoZSBQb29sZWRDb25uZWN0aW9uIGlzIG5vdCBpbiB1c2UsIGNsb3NlIGl0Ci0gICAgICBpZiAoIHBjb24uaW5Vc2UoKSA9PSBmYWxzZSApCi0gICAgICB7Ci0gICAgICAgIGlmIChERUJVRykKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ2xvc2luZyBKREJDIENvbm5lY3Rpb24gIiArIHgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcGNvbi5jbG9zZSgpOwotICAgICAgfQotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIElzIG91ciBDb25uZWN0aW9uUG9vbCBoYXZlIGFueSBjb25uZWN0aW9ucyB0aGF0IGFyZSBzdGlsbCBpbiBVc2UgPz8KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQWN0aXZlQ29ubmVjdGlvbnMoICkKLSAgewotICAgIHJldHVybiAobV9wb29sLnNpemUoKSA+IDApOwotICB9Ci0KLQotICAvKioKLSAgICogU2V0IHRoZSBwYXNzd29yZCBpbiB0aGUgcHJvcGVydHkgc2V0LgotICAgKiBAcGFyYW0gcAotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXNzd29yZCggU3RyaW5nIHAgKQotICB7Ci0gICAgbV9Db25uZWN0aW9uUHJvdG9jb2wucHV0KCJwYXNzd29yZCIsIHApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdXNlciBuYW1lIGluIHRoZSBwcm9wZXJ0eSBzZXQKLSAgICogQHBhcmFtIHUKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VXNlciggU3RyaW5nIHUgKQotICB7Ci0gICAgbV9Db25uZWN0aW9uUHJvdG9jb2wucHV0KCJ1c2VyIiwgdSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIFByb3RvY29sIHN0cmluZyBpcyB1c2VkIHRvIHBhc3MgaW4gb3RoZXIgY29ubmVjdGlvbgotICAgKiBwcm9wZXJ0aWVzLiBBIHByb3BlcnRpZXMgZmlsZSBpcyBhIGdlbmVyYWwgcHVycG9zZSBjb250YWluZXIKLSAgICoKLSAgICogQHBhcmFtIHAKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJvdG9jb2woIFByb3BlcnRpZXMgcCApCi0gIHsKLSAgICBFbnVtZXJhdGlvbiBlID0gcC5rZXlzKCk7Ci0gICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpIGUubmV4dEVsZW1lbnQoKTsKLSAgICAgIG1fQ29ubmVjdGlvblByb3RvY29sLnB1dChrZXksIHAuZ2V0UHJvcGVydHkoa2V5KSk7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogT3ZlcnJpZGUgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGNvbm5lY3Rpb25zIHRvIGtlZXAgaW4gdGhlIHBvb2wuIFRoaXMKLSAgICogc2V0dGluZyB3aWxsIG9ubHkgaGF2ZSBlZmZlY3Qgb24gYSBuZXcgcG9vbCBvciB3aGVuIGEgbmV3IGNvbm5lY3Rpb24KLSAgICogaXMgcmVxdWVzdGVkIGFuZCB0aGVyZSBpcyBsZXNzIGNvbm5lY3Rpb25zIHRoYXQgdGhpcyBzZXR0aW5nLgotICAgKiBAcGFyYW0gbgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNaW5Db25uZWN0aW9ucyggaW50IG4gKQotICB7Ci0gICAgbV9Qb29sTWluU2l6ZSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogVHJ5IHRvIGFxdWlyZSBhIG5ldyBjb25uZWN0aW9uLCBpZiBpdCBzdWNjZWVkcyB0aGVuIHJldHVybgotICAgKiB0cnVlLCBlbHNlIHJldHVybiBmYWxzZS4KLSAgICogTm90ZTogVGhpcyBtZXRob2Qgd2lsbCBjYXVzZSB0aGUgY29ubmVjdGlvbiBwb29sIHRvIGJlIGJ1aWx0LgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiB0ZXN0Q29ubmVjdGlvbiggKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKERFQlVHKQotICAgICAgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3RpbmcgQ29ubmVjdGlvbiIpOwotICAgICAgfQotCi0gICAgICBDb25uZWN0aW9uIGNvbm4gPSBnZXRDb25uZWN0aW9uKCk7Ci0KLSAgICAgIGlmIChERUJVRykKLSAgICAgIHsKLSAgICAgICAgRGF0YWJhc2VNZXRhRGF0YSBkbWEgPSBjb25uLmdldE1ldGFEYXRhKCk7Ci0KLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbkNvbm5lY3RlZCB0byAiICsgZG1hLmdldFVSTCgpKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJEcml2ZXIgICAiICsgZG1hLmdldERyaXZlck5hbWUoKSk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVmVyc2lvbiAgIiArIGRtYS5nZXREcml2ZXJWZXJzaW9uKCkpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOwotICAgICAgfQotCi0gICAgICBpZiAoY29ubiA9PSBudWxsKSByZXR1cm4gZmFsc2U7Ci0KLSAgICAgIHJlbGVhc2VDb25uZWN0aW9uKGNvbm4pOwotCi0gICAgICBpZiAoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVGVzdGluZyBDb25uZWN0aW9uLCBTVUNDRVNTIik7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBpZiAoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVGVzdGluZyBDb25uZWN0aW9uLCBGQUlMRUQiKTsKLSAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICB9Ci0KLQotICAvLyBGaW5kIGFuIGF2YWlsYWJsZSBjb25uZWN0aW9uCi0gIC8qKgotICAgKiBAcmV0dXJuIENvbm5lY3Rpb24KLSAgICogQHRocm93cyBTUUxFeGNlcHRpb24KLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgQ29ubmVjdGlvbiBnZXRDb25uZWN0aW9uKCApdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgU1FMRXhjZXB0aW9uCi0gIHsKLQotICAgIFBvb2xlZENvbm5lY3Rpb24gcGNvbiA9IG51bGw7Ci0KLSAgICAvLyBXZSB3aWxsIGZpbGwgdXAgdGhlIHBvb2wgYW55IHRpbWUgaXQgaXMgbGVzcyB0aGFuIHRoZQotICAgIC8vIE1pbmltdW0uIFRIaXMgY291bGQgYmUgY2F1c2UgYnkgdGhlIGVuYWJsZWluZyBhbmQgZGlzYWJsaW5nCi0gICAgLy8gb3IgdGhlIHBvb2wuCi0gICAgLy8KLSAgICBpZiAoIG1fcG9vbC5zaXplKCkgPCBtX1Bvb2xNaW5TaXplICkgeyBpbml0aWFsaXplUG9vbCgpOyB9Ci0KLSAgICAvLyBmaW5kIGEgY29ubmVjdGlvbiBub3QgaW4gdXNlCi0gICAgZm9yICggaW50IHggPSAwOyB4IDwgbV9wb29sLnNpemUoKTsgeCsrICkKLSAgICB7Ci0KLSAgICAgIHBjb24gPSAoUG9vbGVkQ29ubmVjdGlvbikgbV9wb29sLmVsZW1lbnRBdCh4KTsKLQotICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBDb25uZWN0aW9uIGlzIGluIHVzZQotICAgICAgaWYgKCBwY29uLmluVXNlKCkgPT0gZmFsc2UgKQotICAgICAgewotICAgICAgICAvLyBNYXJrIGl0IGFzIGluIHVzZQotICAgICAgICBwY29uLnNldEluVXNlKHRydWUpOwotICAgICAgICAvLyByZXR1cm4gdGhlIEpEQkMgQ29ubmVjdGlvbiBzdG9yZWQgaW4gdGhlCi0gICAgICAgIC8vIFBvb2xlZENvbm5lY3Rpb24gb2JqZWN0Ci0gICAgICAgIHJldHVybiBwY29uLmdldENvbm5lY3Rpb24oKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBDb3VsZCBub3QgZmluZCBhIGZyZWUgY29ubmVjdGlvbiwKLSAgICAvLyBjcmVhdGUgYW5kIGFkZCBhIG5ldyBvbmUKLQotICAgIC8vIENyZWF0ZSBhIG5ldyBKREJDIENvbm5lY3Rpb24KLSAgICBDb25uZWN0aW9uIGNvbiA9IGNyZWF0ZUNvbm5lY3Rpb24oKTsKLQotICAgIC8vIENyZWF0ZSBhIG5ldyBQb29sZWRDb25uZWN0aW9uLCBwYXNzaW5nIGl0IHRoZSBKREJDCi0gICAgLy8gQ29ubmVjdGlvbgotICAgIHBjb24gPSBuZXcgUG9vbGVkQ29ubmVjdGlvbihjb24pOwotCi0gICAgLy8gTWFyayB0aGUgY29ubmVjdGlvbiBhcyBpbiB1c2UKLSAgICBwY29uLnNldEluVXNlKHRydWUpOwotCi0gICAgLy8gQWRkIHRoZSBuZXcgUG9vbGVkQ29ubmVjdGlvbiBvYmplY3QgdG8gdGhlIHBvb2wKLSAgICBtX3Bvb2wuYWRkRWxlbWVudChwY29uKTsKLQotICAgIC8vIHJldHVybiB0aGUgbmV3IENvbm5lY3Rpb24KLSAgICByZXR1cm4gcGNvbi5nZXRDb25uZWN0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGNvbgotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVsZWFzZUNvbm5lY3Rpb24oIENvbm5lY3Rpb24gY29uICl0aHJvd3MgU1FMRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIGZpbmQgdGhlIFBvb2xlZENvbm5lY3Rpb24gT2JqZWN0Ci0gICAgZm9yICggaW50IHggPSAwOyB4IDwgbV9wb29sLnNpemUoKTsgeCsrICkKLSAgICB7Ci0KLSAgICAgIFBvb2xlZENvbm5lY3Rpb24gcGNvbiA9Ci0gICAgICAgIChQb29sZWRDb25uZWN0aW9uKSBtX3Bvb2wuZWxlbWVudEF0KHgpOwotCi0gICAgICAvLyBDaGVjayBmb3IgY29ycmVjdCBDb25uZWN0aW9uCi0gICAgICBpZiAoIHBjb24uZ2V0Q29ubmVjdGlvbigpID09IGNvbiApCi0gICAgICB7Ci0gICAgICAgIGlmIChERUJVRykKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVsZWFzaW5nIENvbm5lY3Rpb24gIiArIHgpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCEgaXNFbmFibGVkKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBjb24uY2xvc2UoKTsKLSAgICAgICAgICBtX3Bvb2wucmVtb3ZlRWxlbWVudEF0KHgpOwotICAgICAgICAgIGlmIChERUJVRykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tPkluYWN0aXZlIFBvb2wsIENsb3NpbmcgY29ubmVjdGlvbiIpOwotICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIC8vIFNldCBpdCdzIGludXNlIGF0dHJpYnV0ZSB0byBmYWxzZSwgd2hpY2gKLSAgICAgICAgICAvLyByZWxlYXNlcyBpdCBmb3IgdXNlCi0gICAgICAgICAgcGNvbi5zZXRJblVzZShmYWxzZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAcGFyYW0gY29uCi0gICAqIEByZXR1cm4KLSAgICogQHRocm93cyBTUUxFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZWxlYXNlQ29ubmVjdGlvbk9uRXJyb3IoIENvbm5lY3Rpb24gY29uICl0aHJvd3MgU1FMRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIGZpbmQgdGhlIFBvb2xlZENvbm5lY3Rpb24gT2JqZWN0Ci0gICAgZm9yICggaW50IHggPSAwOyB4IDwgbV9wb29sLnNpemUoKTsgeCsrICkKLSAgICB7Ci0KLSAgICAgIFBvb2xlZENvbm5lY3Rpb24gcGNvbiA9Ci0gICAgICAgIChQb29sZWRDb25uZWN0aW9uKSBtX3Bvb2wuZWxlbWVudEF0KHgpOwotCi0gICAgICAvLyBDaGVjayBmb3IgY29ycmVjdCBDb25uZWN0aW9uCi0gICAgICBpZiAoIHBjb24uZ2V0Q29ubmVjdGlvbigpID09IGNvbiApCi0gICAgICB7Ci0gICAgICAgIGlmIChERUJVRykKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVsZWFzaW5nIENvbm5lY3Rpb24gT24gRXJyb3IiICsgeCk7Ci0gICAgICAgIH0KLQotICAgICAgICBjb24uY2xvc2UoKTsKLSAgICAgICAgbV9wb29sLnJlbW92ZUVsZW1lbnRBdCh4KTsKLSAgICAgICAgaWYgKERFQlVHKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLT5JbmFjdGl2ZSBQb29sLCBDbG9zaW5nIGNvbm5lY3Rpb24iKTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIENvbm5lY3Rpb24gY3JlYXRlQ29ubmVjdGlvbiggKXRocm93cyBTUUxFeGNlcHRpb24KLSAgewotICAgIENvbm5lY3Rpb24gY29uID0gbnVsbDsKLQotICAgIC8vIENyZWF0ZSBhIENvbm5lY3Rpb24KLSAgICBjb24gPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oIG1fdXJsLCBtX0Nvbm5lY3Rpb25Qcm90b2NvbCApOwotCi0gICAgcmV0dXJuIGNvbjsKLSAgfQotCi0gIC8vIEluaXRpYWxpemUgdGhlIHBvb2wKLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICogQHRocm93cyBTUUxFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbml0aWFsaXplUG9vbCggKXRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIFNRTEV4Y2VwdGlvbgotICB7Ci0KLSAgICAgLy8gQ2hlY2sgb3VyIGluaXRpYWwgdmFsdWVzCi0gICAgIGlmICggbV9kcml2ZXIgPT0gbnVsbCApCi0gICAgIHsKLSAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJObyBEcml2ZXIgTmFtZSBTcGVjaWZpZWQhIik7Ci0gICAgIH0KLQotICAgICBpZiAoIG1fdXJsID09IG51bGwgKQotICAgICB7Ci0gICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm8gVVJMIFNwZWNpZmllZCEiKTsKLSAgICAgfQotCi0gICAgIGlmICggbV9Qb29sTWluU2l6ZSA8IDEgKQotICAgICB7Ci0gICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUG9vbCBzaXplIGlzIGxlc3MgdGhhbiAxISIpOwotICAgICB9Ci0KLSAgICAgLy8gQ3JlYXRlIHRoZSBDb25uZWN0aW9ucwotICAgICAvLyBMb2FkIHRoZSBEcml2ZXIgY2xhc3MgZmlsZQotCi0gICAgIHRyeQotICAgICB7Ci0gICAgICAgQ2xhc3MuZm9yTmFtZSggbV9kcml2ZXIgKTsKLSAgICAgfQotICAgICBjYXRjaChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpCi0gICAgIHsKLSAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIERyaXZlciBOYW1lIFNwZWNpZmllZCEiKTsKLSAgICAgfQotCi0gICAgIC8vIElGIHdlIGFyZSBub3QgYWN0aXZlLCBkb24ndCBhY3R1YWxsIGJ1aWxkIGEgcG9vbCB5ZXQKLSAgICAgLy8gSnVzdCBzZXQgdXAgdGhlIGRyaXZlciBhbmQgcGVyaXBoYWwgaXRlbXMuCi0gICAgIGlmICggIW1fSXNBY3RpdmUpIHJldHVybjsKLQotICAgIC8vIENyZWF0ZSBDb25uZWN0aW9ucyBiYXNlZCBvbiB0aGUgc2l6ZSBtZW1iZXIKLSAgICBkbwotICAgIHsKLQotICAgICAgQ29ubmVjdGlvbiBjb24gPSBjcmVhdGVDb25uZWN0aW9uKCk7Ci0KLSAgICAgIGlmICggY29uICE9IG51bGwgKQotICAgICAgewotCi0gICAgICAgIC8vIENyZWF0ZSBhIFBvb2xlZENvbm5lY3Rpb24gdG8gZW5jYXBzdWxhdGUgdGhlCi0gICAgICAgIC8vIHJlYWwgSkRCQyBDb25uZWN0aW9uCi0gICAgICAgIFBvb2xlZENvbm5lY3Rpb24gcGNvbiA9IG5ldyBQb29sZWRDb25uZWN0aW9uKGNvbik7Ci0KLSAgICAgICAgLy8gQWRkIHRoZSBDb25uZWN0aW9uIHRoZSBwb29sLgotICAgICAgICBhZGRDb25uZWN0aW9uKHBjb24pOwotCi0gICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJBZGRpbmcgREIgQ29ubmVjdGlvbiB0byB0aGUgUG9vbCIpOwotICAgICAgfQotICAgIH0KLSAgICB3aGlsZSAobV9wb29sLnNpemUoKSA8IG1fUG9vbE1pblNpemUpOwotICB9Ci0KLSAgLy8gQWRkcyB0aGUgUG9vbGVkQ29ubmVjdGlvbiB0byB0aGUgcG9vbAotICAvKioKLSAgICogQHBhcmFtIHZhbHVlCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBhZGRDb25uZWN0aW9uKCBQb29sZWRDb25uZWN0aW9uIHZhbHVlICkKLSAgewotICAgIC8vIEFkZCB0aGUgUG9vbGVkQ29ubmVjdGlvbiBPYmplY3QgdG8gdGhlIHZlY3RvcgotICAgIG1fcG9vbC5hZGRFbGVtZW50KHZhbHVlKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICogQHRocm93cyBUaHJvd2FibGUKLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCApdGhyb3dzIFRocm93YWJsZQotICB7Ci0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW4gRGVmYXVsdCBDb25uZWN0aW9uIFBvb2wsIEZpbmFsaXplIik7Ci0gICAgfQotCi0gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBlbnRpcmUgcG9vbCBjbG9zaW5nIHRoZQotICAgIC8vIEpEQkMgQ29ubmVjdGlvbnMuCi0gICAgZm9yICggaW50IHggPSAwOyB4IDwgbV9wb29sLnNpemUoKTsgeCsrICkKLSAgICB7Ci0KLSAgICAgIGlmIChERUJVRykKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJDbG9zaW5nIEpEQkMgQ29ubmVjdGlvbiAiICsgeCk7Ci0gICAgICB9Ci0KLSAgICAgIFBvb2xlZENvbm5lY3Rpb24gcGNvbiA9Ci0gICAgICAgIChQb29sZWRDb25uZWN0aW9uKSBtX3Bvb2wuZWxlbWVudEF0KHgpOwotCi0gICAgICAvLyBJZiB0aGUgUG9vbGVkQ29ubmVjdGlvbiBpcyBub3QgaW4gdXNlLCBjbG9zZSBpdAotICAgICAgaWYgKCBwY29uLmluVXNlKCkgPT0gZmFsc2UgKSB7IHBjb24uY2xvc2UoKTsgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaWYgKERFQlVHKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCItLT4gRm9yY2UgY2xvc2UiKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIGl0IHN0aWxsIGluIHVzZSwgc2xlZXAgZm9yIDMwIHNlY29uZHMgYW5kCi0gICAgICAgIC8vIGZvcmNlIGNsb3NlLgotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGphdmEubGFuZy5UaHJlYWQuc2xlZXAoMzAwMDApOwotICAgICAgICAgIHBjb24uY2xvc2UoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5lcnIucHJpbnRsbihpZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhpdCBEZWZhdWx0IENvbm5lY3Rpb24gUG9vbCwgRmluYWxpemUiKTsKLSAgICB9Ci0KLSAgICBzdXBlci5maW5hbGl6ZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBQb29sIGNhbiBiZSBFbmFibGVkIGFuZCBEaXNhYmxlZC4gRGlzYWJsaW5nIHRoZSBwb29sCi0gICAqIGNsb3NlcyBhbGwgdGhlIG91dHN0YW5kaW5nIFVudXNlZCBjb25uZWN0aW9ucyBhbmQgYW55IG5ldwotICAgKiBjb25uZWN0aW9ucyB3aWxsIGJlIGNsb3NlZCB1cG9uIHJlbGVhc2UuCi0gICAqIEBwYXJhbSBmbGFnIENvbnRyb2wgdGhlIENvbm5lY3Rpb24gUG9vbC4gSWYgaXQgaXMgZW5hYmxlZCB0aGVuIENvbm5lY3Rpb25zIHdpbGwgYWN0dWFsbCBiZSBoZWxkCi0gICAqIGFyb3VuZC4gSWYgZGlzYWJsZWQgdGhlbiBhbGwgdW51c2VkIGNvbm5lY3Rpb25zIHdpbGwgYmUgaW5zdGFudGx5IGNsb3NlZCBhbmQgYXMKLSAgICogY29ubmVjdGlvbnMgYXJlIHJlbGVhc2VkIHRoZXkgYXJlIGNsb3NlZCBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBwb29sLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQb29sRW5hYmxlZCggZmluYWwgYm9vbGVhbiBmbGFnICkKLSAgewotCi0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL09iamVjdEFycmF5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL09iamVjdEFycmF5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc1Njg5Y2UuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9PYmplY3RBcnJheS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA3ICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBQcm92aWRlIGEgc2ltcGxlIEFycmF5IHN0b3JhZ2UgbWVjaGluc2ltIHdoZXJlICBuYXRpdmUgQXJyYXlzIHdpbGwgYmUgdXNlIGFzCi0gKiB0aGUgYmFzaWMgc3RvcmFnZSBtZWNoaW5pc20gYnV0IHRoZSBBcnJheXMgd2lsbCBiZSBzdG9yZWQgYXMgYmxvY2tzLgotICogVGhlIHNpemUgb2YgdGhlIEFycmF5IGJsb2NrcyBpcyBkZXRlcm1pbmUgZHVyaW5nIG9iamVjdCBjb25zdHJ1Y3Rpb24uCi0gKiBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGEgc2ltcGxlIHN0b3JhZ2UgbWVjaGluc2ltIHdoZXJlIHRoZSBzdG9yYWdlIG9ubHkKLSAqIGNhbiBncm93LiBBcnJheSBlbGVtZW50cyBjYW4gbm90IGJlIHJlbW92ZWQsIG9ubHkgYWRkZWQgdG8uCi0gKi8KLXB1YmxpYyBjbGFzcyBPYmplY3RBcnJheQotewotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fbWluQXJyYXlTaXplID0gMTA7Ci0gIC8qKgotICAgKiBUaGUgY29udGFpbmVyIG9mIGFsbCB0aGUgc3ViIGFycmF5cwotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9BcnJheXMgPSBuZXcgVmVjdG9yKDIwMCk7Ci0KLSAgLyoqCi0gICAqIEFuIGluZGV4IHRoYXQgcG9ydmlkZXMgdGhlIFZlY3RvciBlbnRyeSBmb3IgdGhlIGN1cnJlbnQgQXJyYXkgdGhhdCBpcwotICAgKiBiZWluZyBhcHBlbmRlZCB0by4KLSAgICovCi0gIHByaXZhdGUgX09iamVjdEFycmF5IG1fY3VycmVudEFycmF5OwotCi0KLSAgLyoqCi0gICAqIFRoZSBuZXh0IG9mZnNldCBpbiB0aGUgY3VycmVudCBBcnJheSB0byBhcHBlbmQgYSBuZXcgb2JqZWN0Ci0gICAqLwotICBwcml2YXRlIGludCBtX25leHRTbG90OwotCi0KLSAgLyoqCi0gICAqLwotICBwdWJsaWMgT2JqZWN0QXJyYXkoICkKLSAgewotICAgIC8vCi0gICAgLy8gRGVmYXVsdCBjb25zdHJ1Y3RvciB3aWxsIHdvcmsgd2l0aCBhIG1pbmltYWwgZml4ZWQgc2l6ZQotICAgIC8vCi0gICAgaW5pdCgxMCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG1pbkFycmF5U2l6ZSBUaGUgc2l6ZSBvZiB0aGUgQXJyYXlzIHN0b3JlZCBpbiB0aGUgVmVjdG9yCi0gICAqLwotICBwdWJsaWMgT2JqZWN0QXJyYXkoIGZpbmFsIGludCBtaW5BcnJheVNpemUgKQotICB7Ci0gICAgaW5pdChtaW5BcnJheVNpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzaXplCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0KCBpbnQgc2l6ZSApCi0gIHsKLSAgICBtX21pbkFycmF5U2l6ZSA9IHNpemU7Ci0gICAgbV9jdXJyZW50QXJyYXkgPSBuZXcgX09iamVjdEFycmF5KG1fbWluQXJyYXlTaXplKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaWR4IEluZGV4IG9mIHRoZSBPYmplY3QgaW4gdGhlIEFycmF5Ci0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgZ2V0QXQoIGZpbmFsIGludCBpZHggKQotICB7Ci0gICAgaW50IGFycmF5SW5keCA9IGlkeCAvIG1fbWluQXJyYXlTaXplOwotICAgIGludCBhcnJheU9mZnNldCA9IGlkeCAtIChhcnJheUluZHggKiBtX21pbkFycmF5U2l6ZSk7Ci0KLSAgICAvLwotICAgIC8vIElmIHRoZSBhcnJheSBoYXMgYmVlbiBvZmYgbG9hZGVkIHRvIHRoZSBWZWN0b3IgU3RvcmFnZSB0aGVtCi0gICAgLy8gZ3JhYiBpdCBmcm9tIHRoZXJlLgotICAgIGlmIChhcnJheUluZHggPCBtX0FycmF5cy5zaXplKCkpCi0gICAgewotICAgICAgX09iamVjdEFycmF5IGEgPSAoX09iamVjdEFycmF5KW1fQXJyYXlzLmVsZW1lbnRBdChhcnJheUluZHgpOwotICAgICAgcmV0dXJuIGEub2JqZWN0c1thcnJheU9mZnNldF07Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAvLyBXZSBtdXN0IGJlIGluIHRoZSBjdXJyZW50IGFycmF5LCBzbyBwdWxsIGl0IGZyb20gdGhlcmUKLQotICAgICAgLy8gJVJFVklFVyUgV2UgbWF5IHdhbnQgdG8gY2hlY2sgdG8gc2VlIGlmIGFycmF5SW5keCBpcyBvbmx5Ci0gICAgICAvLyBvbmUgZnJlYXRlciB0aGF0IHRoZSBtX0FycmF5cy5zaXplKCk7IFRoaXMgY29kZSBpcyBzYWZlIGJ1dAotICAgICAgLy8gd2lsbCByZXBldGUgaWYgdGhlIGluZGV4IGlzIGdyZWF0ZXIgdGhhbiB0aGUgYXJyYXkgc2l6ZS4KLSAgICAgIHJldHVybiBtX2N1cnJlbnRBcnJheS5vYmplY3RzW2FycmF5T2Zmc2V0XTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGlkeCBJbmRleCBvZiB0aGUgT2JqZWN0IGluIHRoZSBBcnJheQotICAgKiBAcGFyYW0gb2JqICwgVGhlIHZhbHVlIHRvIHNldCBpbiB0aGUgQXJyYXkKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXQoIGZpbmFsIGludCBpZHgsIGZpbmFsIE9iamVjdCBvYmogKQotICB7Ci0gICAgaW50IGFycmF5SW5keCA9IGlkeCAvIG1fbWluQXJyYXlTaXplOwotICAgIGludCBhcnJheU9mZnNldCA9IGlkeCAtIChhcnJheUluZHggKiBtX21pbkFycmF5U2l6ZSk7Ci0KLSAgICAvLwotICAgIC8vIElmIHRoZSBhcnJheSBoYXMgYmVlbiBvZmYgbG9hZGVkIHRvIHRoZSBWZWN0b3IgU3RvcmFnZSB0aGVtCi0gICAgLy8gZ3JhYiBpdCBmcm9tIHRoZXJlLgotICAgIGlmIChhcnJheUluZHggPCBtX0FycmF5cy5zaXplKCkpCi0gICAgewotICAgICAgX09iamVjdEFycmF5IGEgPSAoX09iamVjdEFycmF5KW1fQXJyYXlzLmVsZW1lbnRBdChhcnJheUluZHgpOwotICAgICAgYS5vYmplY3RzW2FycmF5T2Zmc2V0XSA9IG9iajsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIFdlIG11c3QgYmUgaW4gdGhlIGN1cnJlbnQgYXJyYXksIHNvIHB1bGwgaXQgZnJvbSB0aGVyZQotCi0gICAgICAvLyAlUkVWSUVXJSBXZSBtYXkgd2FudCB0byBjaGVjayB0byBzZWUgaWYgYXJyYXlJbmR4IGlzIG9ubHkKLSAgICAgIC8vIG9uZSBmcmVhdGVyIHRoYXQgdGhlIG1fQXJyYXlzLnNpemUoKTsgVGhpcyBjb2RlIGlzIHNhZmUgYnV0Ci0gICAgICAvLyB3aWxsIHJlcGV0ZSBpZiB0aGUgaW5kZXggaXMgZ3JlYXRlciB0aGFuIHRoZSBhcnJheSBzaXplLgotICAgICAgbV9jdXJyZW50QXJyYXkub2JqZWN0c1thcnJheU9mZnNldF0gPSBvYmo7Ci0gICAgfQotICB9Ci0KLQotCi0gIC8qKgotICAgKiBAcGFyYW0gbyBPYmplY3QgdG8gYmUgYXBwZW5kZWQgdG8gdGhlIEFycmF5Ci0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgYXBwZW5kKCBPYmplY3QgbyApCi0gIHsKLSAgICBpZiAobV9uZXh0U2xvdCA+PSBtX21pbkFycmF5U2l6ZSkKLSAgICB7Ci0gICAgICBtX0FycmF5cy5hZGRFbGVtZW50KG1fY3VycmVudEFycmF5KTsKLSAgICAgIG1fbmV4dFNsb3QgPSAwOwotICAgICAgbV9jdXJyZW50QXJyYXkgPSBuZXcgX09iamVjdEFycmF5KG1fbWluQXJyYXlTaXplKTsKLSAgICB9Ci0KLSAgICBtX2N1cnJlbnRBcnJheS5vYmplY3RzW21fbmV4dFNsb3RdID0gbzsKLQotICAgIGludCBwb3MgPSAobV9BcnJheXMuc2l6ZSgpICogbV9taW5BcnJheVNpemUpICsgbV9uZXh0U2xvdDsKLQotICAgIG1fbmV4dFNsb3QrKzsKLQotICAgIHJldHVybiBwb3M7Ci0gIH0KLQotCi0gIC8qKgotICAgKi8KLSAgY2xhc3MgX09iamVjdEFycmF5Ci0gIHsKLSAgICAvKioKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0W10gb2JqZWN0czsKLSAgICAvKioKLSAgICAgKiBAcGFyYW0gc2l6ZQotICAgICAqLwotICAgIHB1YmxpYyBfT2JqZWN0QXJyYXkoIGludCBzaXplICkKLSAgICB7Ci0gICAgICBvYmplY3RzID0gbmV3IE9iamVjdFtzaXplXTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGFyZ3MKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oIFN0cmluZ1tdIGFyZ3MgKQotICB7Ci0gICAgU3RyaW5nW10gd29yZD17Ci0gICAgICAiWmVybyIsIk9uZSIsIlR3byIsIlRocmVlIiwiRm91ciIsIkZpdmUiLAotICAgICAgIlNpeCIsIlNldmVuIiwiRWlnaHQiLCJOaW5lIiwiVGVuIiwKLSAgICAgICJFbGV2ZW4iLCJUd2VsdmUiLCJUaGlydGVlbiIsIkZvdXJ0ZWVuIiwiRmlmdGVlbiIsCi0gICAgICAiU2l4dGVlbiIsIlNldmVudGVlbiIsIkVpZ2h0ZWVuIiwiTmluZXRlZW4iLCJUd2VudHkiLAotICAgICAgIlR3ZW50eS1PbmUiLCJUd2VudHktVHdvIiwiVHdlbnR5LVRocmVlIiwiVHdlbnR5LUZvdXIiLAotICAgICAgIlR3ZW50eS1GaXZlIiwiVHdlbnR5LVNpeCIsIlR3ZW50eS1TZXZlbiIsIlR3ZW50eS1FaWdodCIsCi0gICAgICAiVHdlbnR5LU5pbmUiLCJUaGlydHkiLCJUaGlydHktT25lIiwiVGhpcnR5LVR3byIsCi0gICAgICAiVGhpcnR5LVRocmVlIiwiVGhpcnR5LUZvdXIiLCJUaGlydHktRml2ZSIsIlRoaXJ0eS1TaXgiLAotICAgICAgIlRoaXJ0eS1TZXZlbiIsIlRoaXJ0eS1FaWdodCIsIlRoaXJ0eS1OaW5lIn07Ci0KLSAgICBPYmplY3RBcnJheSBtX09iamVjdEFycmF5ID0gbmV3IE9iamVjdEFycmF5KCk7Ci0gICAgLy8gQWRkIHRoZW0gaW4sIHVzaW5nIHRoZSBkZWZhdWx0IGJsb2NrIHNpemUKLSAgICBmb3IgKGludCB4ID0wOyB4PCB3b3JkLmxlbmd0aDsgeCsrKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiAtICIgKyBtX09iamVjdEFycmF5LmFwcGVuZCh3b3JkW3hdKSk7Ci0gICAgfQotCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcbiIpOwotICAgIC8vIE5vdyBsZXQncyByZWFkIHRoZW0gb3V0IHNlcXVlbnRhbGx5Ci0gICAgZm9yIChpbnQgeCA9MDsgeDwgd29yZC5sZW5ndGg7IHgrKykKLSAgICB7Ci0gICAgICBTdHJpbmcgcyA9IChTdHJpbmcpIG1fT2JqZWN0QXJyYXkuZ2V0QXQoeCk7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocyk7Ci0gICAgfQotCi0gICAgLy8gU29tZSBSYW5kb20gQWNjZXNzCi0gICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpIG1fT2JqZWN0QXJyYXkuZ2V0QXQoNSkpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigoU3RyaW5nKSBtX09iamVjdEFycmF5LmdldEF0KDEwKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpIG1fT2JqZWN0QXJyYXkuZ2V0QXQoMjApKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKFN0cmluZykgbV9PYmplY3RBcnJheS5nZXRBdCgyKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpIG1fT2JqZWN0QXJyYXkuZ2V0QXQoMTUpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKFN0cmluZykgbV9PYmplY3RBcnJheS5nZXRBdCgzMCkpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigoU3RyaW5nKSBtX09iamVjdEFycmF5LmdldEF0KDYpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKFN0cmluZykgbV9PYmplY3RBcnJheS5nZXRBdCg4KSk7Ci0KLSAgICAvLyBPdXQgb2YgYm91bmRzCi0gICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpIG1fT2JqZWN0QXJyYXkuZ2V0QXQoNDApKTsKLQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL1Bvb2xlZENvbm5lY3Rpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvUG9vbGVkQ29ubmVjdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMTYwZTAxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvUG9vbGVkQ29ubmVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWw7Ci0KLWltcG9ydCBqYXZhLnNxbC4qOwotaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247Ci0KLS8qKgotICovCi1wdWJsaWMgY2xhc3MgUG9vbGVkQ29ubmVjdGlvbgotewotCi0gIC8vIFJlYWwgSkRCQyBDb25uZWN0aW9uCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBudWxsOwotICAvLyBib29sZWFuIGZsYWcgdXNlZCB0byBkZXRlcm1pbmUgaWYgY29ubmVjdGlvbiBpcyBpbiB1c2UKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gaW51c2UgPSBmYWxzZTsKLQotICAvLyBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIHRoZSBwYXNzZWQgaW4gSkRCQyBDb25uZWN0aW9uCi0gIC8vIGFuZCBzdG9yZXMgaXQgaW4gdGhlIGNvbm5lY3Rpb24gYXR0cmlidXRlLgotICAvKioKLSAgICogQHBhcmFtIHZhbHVlCi0gICAqLwotICBwdWJsaWMgUG9vbGVkQ29ubmVjdGlvbiggQ29ubmVjdGlvbiB2YWx1ZSApCi0gIHsKLSAgICBpZiAoIHZhbHVlICE9IG51bGwgKSB7IGNvbm5lY3Rpb24gPSB2YWx1ZTsgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIEpEQkMgQ29ubmVjdGlvbgotICAgKiBAcmV0dXJuIENvbm5lY3Rpb24KLSAgICovCi0gIHB1YmxpYyBDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oICkKLSAgewotICAgIC8vIGdldCB0aGUgSkRCQyBDb25uZWN0aW9uCi0gICAgcmV0dXJuIGNvbm5lY3Rpb247Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBzdGF0dXMgb2YgdGhlIFBvb2xlZENvbm5lY3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJblVzZSggYm9vbGVhbiB2YWx1ZSApCi0gIHsKLSAgICBpbnVzZSA9IHZhbHVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBQb29sZWRDb25uZWN0aW9uLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpblVzZSggKSB7IHJldHVybiBpbnVzZTsgfQotCi0gIC8qKgotICAgKiAgQ2xvc2UgdGhlIHJlYWwgSkRCQyBDb25uZWN0aW9uCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsb3NlKCApCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBjb25uZWN0aW9uLmNsb3NlKCk7Ci0gICAgfQotICAgIGNhdGNoIChTUUxFeGNlcHRpb24gc3FsZSkKLSAgICB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oc3FsZS5nZXRNZXNzYWdlKCkpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9RdWVyeVBhcmFtZXRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9RdWVyeVBhcmFtZXRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MDQ2ZmM2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvUXVlcnlQYXJhbWV0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWw7Ci0KLS8qKgotICogVGl0bGU6ICAgICAgICA8cD4KLSAqIERlc2NyaXB0aW9uOiAgPHA+Ci0gKiBDb3B5cmlnaHQ6ICAgIENvcHlyaWdodCAoYykgPHA+Ci0gKiBDb21wYW55OiAgICAgIDxwPgotICogQGF1dGhvcgotICogQHZlcnNpb24gMS4wCi0gKi8KLXB1YmxpYyBjbGFzcyBRdWVyeVBhcmFtZXRlciAgICAgICAgIAotewotCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgdmFsdWU7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgdHlwZTsKLQotICAvKioKLSAgICogQHBhcmFtIHYKLSAgICogQHBhcmFtIHQKLSAgICovCi0gIHB1YmxpYyBRdWVyeVBhcmFtZXRlciggU3RyaW5nIHYsIFN0cmluZyB0ICkKLSAgewotICAgIHZhbHVlID0gdjsKLSAgICB0eXBlID0gdDsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCApIHsKLSAgICByZXR1cm4gdmFsdWU7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIG5ld1ZhbHVlCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFZhbHVlKCBTdHJpbmcgbmV3VmFsdWUgKSB7Ci0gICAgdmFsdWUgPSBuZXdWYWx1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gbmV3VHlwZQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUeXBlKCBTdHJpbmcgbmV3VHlwZSApIHsKLSAgICB0eXBlID0gbmV3VHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoICkgewotICAgIHJldHVybiB0eXBlOwotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9TUUxEb2N1bWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9TUUxEb2N1bWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYzA3MGQzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvU1FMRG9jdW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg2OCArMCwwIEBACi0vKioKLSAqIEAoIykgU1FMRG9jdW1lbnQuamF2YQotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBqYXZhLnNxbC5Db25uZWN0aW9uOwotaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKLWltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7Ci1pbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0TWV0YURhdGE7Ci1pbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuc3FsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi4qOwotCi0vKioKLSAqIFRoZSBTUUwgRG9jdW1lbnQgaXMgdGhlIG1haW4gY29udHJvbGxpbmcgY2xhc3MgdGhlIGV4ZWN1dGVzYSBTUUwgUXVlcnkKLSAqLwotcHVibGljIGNsYXNzIFNRTERvY3VtZW50IGV4dGVuZHMgRFRNRG9jdW1lbnQKLXsKLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfTkFNRVNQQUNFID0gImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9TUUxFeHRlbnNpb24iOwotCi0KLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19TUUwgPSAic3FsIjsKLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX1JPV19TRVQgPSAicm93LXNldCI7Ci0KLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19NRVRBREFUQSA9ICJtZXRhZGF0YSI7Ci0KLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19DT0xVTU5fSEVBREVSID0gImNvbHVtbi1oZWFkZXIiOwotCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfUk9XID0gInJvdyI7Ci0KLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19DT0wgPSAiY29sIjsKLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX0NBVEFMT0dVRV9OQU1FID0gImNhdGFsb2d1ZS1uYW1lIjsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19ESVNQTEFZX1NJWkUgPSAiY29sdW1uLWRpc3BsYXktc2l6ZSI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfQ09MVU1OX0xBQkVMID0gImNvbHVtbi1sYWJlbCI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfQ09MVU1OX05BTUUgPSAiY29sdW1uLW5hbWUiOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX0NPTFVNTl9UWVBFID0gImNvbHVtbi10eXBlIjsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19DT0xVTU5fVFlQRU5BTUUgPSAiY29sdW1uLXR5cGVuYW1lIjsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19QUkVDSVNJT04gPSAicHJlY2lzaW9uIjsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19TQ0FMRSA9ICJzY2FsZSI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfU0NIRU1BX05BTUUgPSAic2NoZW1hLW5hbWUiOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX1RBQkxFX05BTUUgPSAidGFibGUtbmFtZSI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfQ0FTRVNFTlNJVElWRSA9ICJjYXNlLXNlbnNpdGl2ZSI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfREVGSU5JVExFWVdSSVRBQkxFID0gImRlZmluaXRsZXktd3JpdGFibGUiOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX0lTTlVMTEFCTEUgPSAibnVsbGFibGUiOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX0lTU0lHTkVEID0gInNpZ25lZCI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfSVNXUklURUFCTEUgPSAid3JpdGFibGUiOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTX0lTU0VBUkNIQUJMRSA9ICJzZWFyY2hhYmxlIjsKLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fU1FMX1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9NZXRhRGF0YV9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sdW1uSGVhZGVyX1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Sb3dTZXRfVHlwZUlEID0gMDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX1Jvd19UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sX1R5cGVJRCA9IDA7Ci0KLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX0NvbEF0dHJpYl9DQVRBTE9HVUVfTkFNRV9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sQXR0cmliX0RJU1BMQVlfU0laRV9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sQXR0cmliX0NPTFVNTl9MQUJFTF9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sQXR0cmliX0NPTFVNTl9OQU1FX1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Db2xBdHRyaWJfQ09MVU1OX1RZUEVfVHlwZUlEID0gMDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX0NvbEF0dHJpYl9DT0xVTU5fVFlQRU5BTUVfVHlwZUlEID0gMDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX0NvbEF0dHJpYl9QUkVDSVNJT05fVHlwZUlEID0gMDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX0NvbEF0dHJpYl9TQ0FMRV9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sQXR0cmliX1NDSEVNQV9OQU1FX1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Db2xBdHRyaWJfVEFCTEVfTkFNRV9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sQXR0cmliX0NBU0VTRU5TSVRJVkVfVHlwZUlEID0gMDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX0NvbEF0dHJpYl9ERUZJTklUTEVZV1JJVEVBQkxFX1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Db2xBdHRyaWJfSVNOVUxMQUJMRV9UeXBlSUQgPSAwOwotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fQ29sQXR0cmliX0lTU0lHTkVEX1R5cGVJRCA9IDA7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Db2xBdHRyaWJfSVNXUklURUFCTEVfVHlwZUlEID0gMDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX0NvbEF0dHJpYl9JU1NFQVJDSEFCTEVfVHlwZUlEID0gMDsKLQotICAvKioKLSAgICogVGhlIERCTVMgQ29ubmVjdGlvbiB1c2VkIHRvIHByb2R1Y2UgdGhpcyBTUUwgRG9jdW1lbnQuCi0gICAqIFdpbGwgYmUgdXNlZCB0byBjbGVhciBmcmVlIHVwIHRoZSBkYXRhYmFzZSByZXNvdXJjZXMgb24KLSAgICogY2xvc2UuCi0gICAqLwotICBwcml2YXRlIENvbm5lY3Rpb24gbV9Db25uZWN0aW9uID0gbnVsbDsKLQotICAvKioKLSAgICogVGhlIFN0YXRlbWVudCB1c2VkIHRvIGV4dHJhY3QgdGhlIGRhdGEgZnJvbSB0aGUgRGF0YWJhc2UgY29ubmVjdGlvbi4KLSAgICogV2UgcmVhbGx5IGRvbid0IG5lZWQgdGhlIGNvbm5lY3Rpb24sIGJ1dCBpdCBpcyBOT1QgZGVmaW5lZCBmcm9tCi0gICAqIEpEQkMgRHJpdmVyIHRvIGRyaXZlciB3aGF0IGhhcHBlbnMgdG8gdGhlIFJlc3VsdFNldCBpZiB0aGUgc3RhdG1lbnQKLSAgICogaXMgY2xvc2VkIHByaW9yIHRvIHJlYWRpbmcgYWxsIHRoZSBkYXRhIG5lZWRlZC4gU28gYXMgbG9uZyBhcyB3ZSBhcmUKLSAgICogdXNpbmcgdGhlIFJlc3VsdFNldCwgd2Ugd2lsbCB0cmFjayB0aGUgU3RhdGVtZW50IHVzZWQgdG8gcHJvZHVjZSBpdC4KLSAgICovCi0gIHByaXZhdGUgU3RhdGVtZW50IG1fU3RhdGVtZW50ID0gbnVsbDsKLQotICAvKioKLSAgICogVGhlIGNvbmR1aXQgdG8gb3VyIGRhdGEgdGhhdCB3aWxsIGJlIHVzZWQgdG8gZmlsbCB0aGUgZG9jdW1lbnQuCi0gICAqLwotICBwcml2YXRlIFJlc3VsdFNldCBtX1Jlc3VsdFNldCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRoZSBDb25uZWN0aW9uIFBvb2wgdGhhdCBvcmlnaW5hbGx5IHByb2R1Y2VkIHRoZSBjb25uZWN0aW9uLgotICAgKi8KLSAgcHJpdmF0ZSBDb25uZWN0aW9uUG9vbCBtX0Nvbm5lY3Rpb25Qb29sID0gbnVsbDsKLQotCi0gIC8qKgotICAgKiBBcyB0aGUgY29sdW1uIGhlYWRlciBhcnJheSBpcyBidWlsdCwga2VlcCB0aGUgbm9kZSBpbmRleAotICAgKiBmb3IgZWFjaCBDb2x1bW4uCi0gICAqIFRoZSBwcmltYXJ5IHVzZSBvZiB0aGlzIGlzIHRvIGxvY2F0ZSB0aGUgZmlyc3QgYXR0cmlidXRlIGZvcgotICAgKiBlYWNoIGNvbHVtbiBpbiBlYWNoIHJvdyBhcyB3ZSBhZGQgcmVjb3Jkcy4KLSAgICovCi0gIHByaXZhdGUgaW50W10gbV9Db2xIZWFkZXJzSWR4OwotCi0gIC8qKgotICAgKiBBbiBpbmRpY2F0b3Igb24gaG93IG1hbnkgY29sdW1ucyBhcmUgaW4gdGhpcyBxdWVyeQotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Db2xDb3VudDsKLQotICAvKioKLSAgICogVGhlIEluZGV4IG9mIHRoZSBNZXRhRGF0YSBOb2RlLiBDdXJyZW50bHkgdGhlIE1ldGFEYXRhIE5vZGUgY29udGFpbnMgdGhlCi0gICAqCi0gICAqLwotICBwcml2YXRlIGludCBtX01ldGFEYXRhSWR4ID0gRFRNLk5VTEw7Ci0KLSAgLyoqCi0gICAqIFRoZSBpbmRleCBvZiB0aGUgUm93IFNldCBub2RlLiBUaGlzIGlzIHRoZSBzaWJsaW5nIGRpcmVjdGx5IGFmdGVyCi0gICAqIHRoZSBsYXN0IENvbHVtbiBIZWFkZXIuCi0gICAqLwotICBwcml2YXRlIGludCBtX1Jvd1NldElkeCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9TUUxJZHggPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogRGVtYXJrIHRoZSBmaXJzdCByb3cgZWxlbWVudCB3aGVyZSB3ZSBzdGFydGVkIGFkZGluZyByb3dzIGludG8gdGhlCi0gICAqIERvY3VtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9GaXJzdFJvd0lkeCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBMYXN0IHJvdyBpbnNlcnRlZCBpbnRvIHRoZSBEVE0gZnJvbSB0aGUgUmVzdWx0U2V0LgotICAgKiBUaGlzIHdpbGwgYmUgdXNlZCBhcyB0aGUgaW5kZXggb2YgdGhlIHBhcmVudCBSb3cgRWxlbWVudCB3aGVuIGFkZGluZwotICAgKiBhIHJvdy4KLSAgICovCi0gIHByaXZhdGUgaW50IG1fTGFzdFJvd0lkeCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiBTdHJlYW1pbmcgTW9kZSBDb250cm9sLCBJbiBTdHJlYW1pbmcgbW9kZSB3ZSByZWR1Y2UgdGhlIG1lbW9yeQotICAgKiBmb290cHJpbnQgc2luY2Ugd2Ugb25seSB1c2UgYSBzaW5nbGUgcm93IGluc3RhbmNlLgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fU3RyZWFtaW5nTW9kZSA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBtZ3IKLSAgICogQHBhcmFtIGlkZW50Ci0gICAqIEBwYXJhbSBwb29sCi0gICAqIEBwYXJhbSBjb24KLSAgICogQHBhcmFtIHN0bXQKLSAgICogQHBhcmFtIGRhdGEKLSAgICogQHBhcmFtIHN0cmVhbWluZ01vZGUKLSAgICogQHRocm93cyBTUUxFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTUUxEb2N1bWVudCggRFRNTWFuYWdlciBtZ3IsIGludCBpZGVudCwgQ29ubmVjdGlvblBvb2wgcG9vbCwgQ29ubmVjdGlvbiBjb24sIFN0YXRlbWVudCBzdG10LCBSZXN1bHRTZXQgZGF0YSwgYm9vbGVhbiBzdHJlYW1pbmdNb2RlICl0aHJvd3MgU1FMRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihtZ3IsIGlkZW50KTsKLQotICAgIG1fQ29ubmVjdGlvbiA9IGNvbjsKLSAgICBtX1N0YXRlbWVudCAgPSBzdG10OwotICAgIG1fUmVzdWx0U2V0ICA9IGRhdGE7Ci0gICAgbV9Db25uZWN0aW9uUG9vbCA9IHBvb2w7Ci0gICAgbV9TdHJlYW1pbmdNb2RlID0gc3RyZWFtaW5nTW9kZTsKLQotICAgIGNyZWF0ZUV4cGFuZGVkTmFtZVRhYmxlKCk7Ci0gICAgZXh0cmFjdFNRTE1ldGFEYXRhKG1fUmVzdWx0U2V0LmdldE1ldGFEYXRhKCkpOwotCi0gICAgLy8gT25seSBncmFiIHRoZSBmaXJzdCByb3csIHN1YnNlcXVlbnQgcm93cyB3aWxsIGJlCi0gICAgLy8gZmV0Y2hlZCBvbiBkZW1hbmQuCi0gICAgLy8gV2UgbmVlZCB0byBkbyB0aGlzIGhlcmUgc28gYXQgbGVhc3Qgb24gcm93IGlzIHNldCB1cAotICAgIC8vIHRvIG1lYXN1cmUgd2hlbiB3ZSBhcmUgYWN0dWFsbHkgcmVhZGluZyByb3dzLgotICAgIGFkZFJvd1RvRFRNRnJvbVJlc3VsdFNldCgpOwotCi0gICAgLy8gdGhpcy5kdW1wRFRNKCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBFeHRyYWN0IHRoZSBNZXRhIERhdGEgYW5kIGJ1aWxkIHRoZSBDb2x1bW4gQXR0cmlidXRlIExpc3QuCi0gICAqIEBwYXJhbSBtZXRhCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBleHRyYWN0U1FMTWV0YURhdGEoIFJlc3VsdFNldE1ldGFEYXRhIG1ldGEgKQotICB7Ci0gICAgLy8gQnVpbGQgdGhlIE5vZGUgVHJlZSwganVzdCBhZGQgdGhlIENvbHVtbiBIZWFkZXIKLSAgICAvLyBicmFuY2ggbm93LCB0aGUgUm93ICYgY29sIGVsZW1lbnRzIHdpbGwgYmUgYWRkZWQKLSAgICAvLyBvbiByZXF1ZXN0LgotCi0gICAgLy8gU3RhcnQgdGhlIGRvY3VtZW50IGhlcmUKLSAgICBtX0RvY3VtZW50SWR4ID0gYWRkRWxlbWVudCgwLCBtX0RvY3VtZW50X1R5cGVJRCwgRFRNLk5VTEwsIERUTS5OVUxMKTsKLQotICAgIC8vIEFkZCBpbiB0aGUgcm93LXNldCBFbGVtZW50Ci0gICAgbV9TUUxJZHggPSBhZGRFbGVtZW50KDEsIG1fU1FMX1R5cGVJRCwgIG1fRG9jdW1lbnRJZHgsIERUTS5OVUxMKTsKLQotICAgIC8vIEFkZCBpbiB0aGUgTWV0YURhdGEgRWxlbWVudAotICAgIG1fTWV0YURhdGFJZHggPSBhZGRFbGVtZW50KDEsIG1fTWV0YURhdGFfVHlwZUlELCAgbV9TUUxJZHgsIERUTS5OVUxMKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIG1fQ29sQ291bnQgPSBtZXRhLmdldENvbHVtbkNvdW50KCk7Ci0gICAgICBtX0NvbEhlYWRlcnNJZHggPSBuZXcgaW50W21fQ29sQ291bnRdOwotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlcnJvcigiRVJST1IgRXh0cmFjdGluZyBNZXRhZGF0YSIpOwotICAgIH0KLQotICAgIC8vIFRoZSBDb2xIZWFkZXJJZHggd2lsbCBiZSB1c2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlCi0gICAgLy8gRWxlbWVudCBlbnRyaWVzIGZvciB0aGUgaW5kaXZpZHVhbCBDb2x1bW4gSGVhZGVyLgotICAgIGludCBsYXN0Q29sSGVhZGVySWR4ID0gRFRNLk5VTEw7Ci0KLSAgICAvLyBKREJDIENvbHVtbXMgU3RhcnQgYXQgMQotICAgIGludCBpID0gMTsKLSAgICBmb3IgKGk9MTsgaTw9IG1fQ29sQ291bnQ7IGkrKykKLSAgICB7Ci0gICAgICBtX0NvbEhlYWRlcnNJZHhbaS0xXSA9Ci0gICAgICAgIGFkZEVsZW1lbnQoMixtX0NvbHVtbkhlYWRlcl9UeXBlSUQsIG1fTWV0YURhdGFJZHgsIGxhc3RDb2xIZWFkZXJJZHgpOwotCi0gICAgICBsYXN0Q29sSGVhZGVySWR4ID0gbV9Db2xIZWFkZXJzSWR4W2ktMV07Ci0gICAgICAvLyBBIGJpdCBicnV0ZSBmb3JjZSwgYnV0IG5vdCBzdXJlIGhvdyB0byBjbGVhbiBpdCB1cAotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuZ2V0Q29sdW1uTmFtZShpKSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9DT0xVTU5fTkFNRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBTX0FUVFJJQl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgIG1fQ29sQXR0cmliX0NPTFVNTl9OQU1FX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgbWV0YS5nZXRDb2x1bW5MYWJlbChpKSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9DT0xVTU5fTEFCRUxfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9DT0xVTU5fTEFCRUxfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBtZXRhLmdldENhdGFsb2dOYW1lKGkpLAotICAgICAgICAgIG1fQ29sQXR0cmliX0NBVEFMT0dVRV9OQU1FX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIFNfQVRUUklCX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfQ0FUQUxPR1VFX05BTUVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBuZXcgSW50ZWdlcihtZXRhLmdldENvbHVtbkRpc3BsYXlTaXplKGkpKSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9ESVNQTEFZX1NJWkVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9ESVNQTEFZX1NJWkVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBuZXcgSW50ZWdlcihtZXRhLmdldENvbHVtblR5cGUoaSkpLAotICAgICAgICAgIG1fQ29sQXR0cmliX0NPTFVNTl9UWVBFX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIFNfQVRUUklCX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfQ09MVU1OX1RZUEVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBtZXRhLmdldENvbHVtblR5cGVOYW1lKGkpLAotICAgICAgICAgIG1fQ29sQXR0cmliX0NPTFVNTl9UWVBFTkFNRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBTX0FUVFJJQl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgIG1fQ29sQXR0cmliX0NPTFVNTl9UWVBFTkFNRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG5ldyBJbnRlZ2VyKG1ldGEuZ2V0UHJlY2lzaW9uKGkpKSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9QUkVDSVNJT05fVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9QUkVDSVNJT05fVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgbmV3IEludGVnZXIobWV0YS5nZXRTY2FsZShpKSksCi0gICAgICAgICAgbV9Db2xBdHRyaWJfU0NBTEVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9TQ0FMRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuZ2V0U2NoZW1hTmFtZShpKSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9TQ0hFTUFfTkFNRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBTX0FUVFJJQl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgIG1fQ29sQXR0cmliX1NDSEVNQV9OQU1FX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuZ2V0VGFibGVOYW1lKGkpLAotICAgICAgICAgIG1fQ29sQXR0cmliX1RBQkxFX05BTUVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9UQUJMRV9OQU1FX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgbWV0YS5pc0Nhc2VTZW5zaXRpdmUoaSkgPyBTX0lTVFJVRSA6IFNfSVNGQUxTRSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9DQVNFU0VOU0lUSVZFX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIFNfQVRUUklCX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfQ0FTRVNFTlNJVElWRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuaXNEZWZpbml0ZWx5V3JpdGFibGUoaSkgPyBTX0lTVFJVRSA6IFNfSVNGQUxTRSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9ERUZJTklUTEVZV1JJVEVBQkxFX1R5cGVJRCwgbGFzdENvbEhlYWRlcklkeCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIFNfQVRUUklCX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfREVGSU5JVExFWVdSSVRFQUJMRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuaXNOdWxsYWJsZShpKSAhPSAwID8gU19JU1RSVUUgOiBTX0lTRkFMU0UsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfSVNOVUxMQUJMRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotICAgICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBTX0FUVFJJQl9OT1RfU1VQUE9SVEVELAotICAgICAgICAgIG1fQ29sQXR0cmliX0lTTlVMTEFCTEVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGFkZEF0dHJpYnV0ZVRvTm9kZSgKLSAgICAgICAgICBtZXRhLmlzU2lnbmVkKGkpID8gU19JU1RSVUUgOiBTX0lTRkFMU0UsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfSVNTSUdORURfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9JU1NJR05FRF9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuaXNXcml0YWJsZShpKSA9PSB0cnVlID8gU19JU1RSVUUgOiBTX0lTRkFMU0UsCi0gICAgICAgICAgbV9Db2xBdHRyaWJfSVNXUklURUFCTEVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9JU1dSSVRFQUJMRV9UeXBlSUQsIGxhc3RDb2xIZWFkZXJJZHgpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgYWRkQXR0cmlidXRlVG9Ob2RlKAotICAgICAgICAgIG1ldGEuaXNTZWFyY2hhYmxlKGkpID09IHRydWUgPyBTX0lTVFJVRSA6IFNfSVNGQUxTRSwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9JU1NFQVJDSEFCTEVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBhZGRBdHRyaWJ1dGVUb05vZGUoCi0gICAgICAgICAgU19BVFRSSUJfTk9UX1NVUFBPUlRFRCwKLSAgICAgICAgICBtX0NvbEF0dHJpYl9JU1NFQVJDSEFCTEVfVHlwZUlELCBsYXN0Q29sSGVhZGVySWR4KTsKLSAgICAgIH0KLQotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIFBvcHVsYXRlIHRoZSBFeHBhbmRlZCBOYW1lIFRhYmxlIHdpdGggdGhlIE5vZGUgdGhhdCB3ZSB3aWxsIHVzZS4KLSAgICogS2VlcCBhIHJlZmVyZW5jZSBvZiBlYWNoIG9mIHRoZSB0eXBlcyBmb3IgYWNjZXNzIHNwZWVkLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVFeHBhbmRlZE5hbWVUYWJsZSggKQotICB7Ci0gICAgc3VwZXIuY3JlYXRlRXhwYW5kZWROYW1lVGFibGUoKTsKLQotICAgIG1fU1FMX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX1NRTCwgRFRNLkVMRU1FTlRfTk9ERSk7Ci0KLSAgICBtX01ldGFEYXRhX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX01FVEFEQVRBLCBEVE0uRUxFTUVOVF9OT0RFKTsKLQotICAgIG1fQ29sdW1uSGVhZGVyX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX0NPTFVNTl9IRUFERVIsIERUTS5FTEVNRU5UX05PREUpOwotICAgIG1fUm93U2V0X1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX1JPV19TRVQsIERUTS5FTEVNRU5UX05PREUpOwotICAgIG1fUm93X1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX1JPVywgRFRNLkVMRU1FTlRfTk9ERSk7Ci0gICAgbV9Db2xfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfQ09MLCBEVE0uRUxFTUVOVF9OT0RFKTsKLQotCi0gICAgbV9Db2xBdHRyaWJfQ0FUQUxPR1VFX05BTUVfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfQ0FUQUxPR1VFX05BTUUsIERUTS5BVFRSSUJVVEVfTk9ERSk7Ci0gICAgbV9Db2xBdHRyaWJfRElTUExBWV9TSVpFX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX0RJU1BMQVlfU0laRSwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9DT0xVTU5fTEFCRUxfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfQ09MVU1OX0xBQkVMLCBEVE0uQVRUUklCVVRFX05PREUpOwotICAgIG1fQ29sQXR0cmliX0NPTFVNTl9OQU1FX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX0NPTFVNTl9OQU1FLCBEVE0uQVRUUklCVVRFX05PREUpOwotICAgIG1fQ29sQXR0cmliX0NPTFVNTl9UWVBFX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX0NPTFVNTl9UWVBFLCBEVE0uQVRUUklCVVRFX05PREUpOwotICAgIG1fQ29sQXR0cmliX0NPTFVNTl9UWVBFTkFNRV9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19DT0xVTU5fVFlQRU5BTUUsIERUTS5BVFRSSUJVVEVfTk9ERSk7Ci0gICAgbV9Db2xBdHRyaWJfUFJFQ0lTSU9OX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX1BSRUNJU0lPTiwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9TQ0FMRV9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19TQ0FMRSwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9TQ0hFTUFfTkFNRV9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19TQ0hFTUFfTkFNRSwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9UQUJMRV9OQU1FX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX1RBQkxFX05BTUUsIERUTS5BVFRSSUJVVEVfTk9ERSk7Ci0gICAgbV9Db2xBdHRyaWJfQ0FTRVNFTlNJVElWRV9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19DQVNFU0VOU0lUSVZFLCBEVE0uQVRUUklCVVRFX05PREUpOwotICAgIG1fQ29sQXR0cmliX0RFRklOSVRMRVlXUklURUFCTEVfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfREVGSU5JVExFWVdSSVRBQkxFLCBEVE0uQVRUUklCVVRFX05PREUpOwotICAgIG1fQ29sQXR0cmliX0lTTlVMTEFCTEVfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfSVNOVUxMQUJMRSwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9JU1NJR05FRF9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19JU1NJR05FRCwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9JU1dSSVRFQUJMRV9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19JU1dSSVRFQUJMRSwgRFRNLkFUVFJJQlVURV9OT0RFKTsKLSAgICBtX0NvbEF0dHJpYl9JU1NFQVJDSEFCTEVfVHlwZUlEID0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoU19OQU1FU1BBQ0UsIFNfSVNTRUFSQ0hBQkxFLCBEVE0uQVRUUklCVVRFX05PREUpOwotICB9Ci0KLQotICAvKioKLSAgICogUHVsbCBhIHJlY29yZCBmcm9tIHRoZSByZXN1bHQgc2V0IGFuZCBtYXAgaXQgdG8gYSBEVE0gYmFzZWQgUk9XCi0gICAqIElmIHdlIGFyZSBpbiBTdHJlYW1pbmcgbW9kZSwgdGhlbiBvbmx5IGNyZWF0ZSBhIHNpbmdsZSByb3cgYW5kCi0gICAqIGtlZXAgY29weWluZyB0aGUgZGF0YSBpbnRvIHRoZSBzYW1lIHJvdy4gVGhpcyB3aWxsIGtlZXAgdGhlIG1lbW9yeQotICAgKiBmb290cHJpbnQgY29uc3RpbnQgaW5kZXBlbmRhbnQgb2YgdGhlIFJlY29yZFNldCBTaXplLiBJZiB3ZSBhcmUgbm90Ci0gICAqIGluIFN0cmVhbWluZyBtb2RlIHRoZW4gY3JlYXRlIFJPV1MgZm9yIHRoZSB3aG9sZSB0cmVlLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gYWRkUm93VG9EVE1Gcm9tUmVzdWx0U2V0KCApCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0KLQotICAgICAgLy8gSWYgd2UgaGF2ZSBub3Qgc3RhcnRlZCB0aGUgUm93U2V0IHlldCwgdGhlbiBhZGQgaXQgdG8gdGhlCi0gICAgICAvLyB0cmVlLgotICAgICAgaWYgKG1fUm93U2V0SWR4ID09IERUTS5OVUxMKQotICAgICAgewotICAgICAgICBtX1Jvd1NldElkeCA9IGFkZEVsZW1lbnQoMSwgbV9Sb3dTZXRfVHlwZUlELCAgbV9TUUxJZHgsIG1fTWV0YURhdGFJZHgpOwotICAgICAgfQotCi0gICAgICAvLyBDaGVjayB0byBzZWUgaWYgYWxsIHRoZSBkYXRhIGhhcyBiZWVuIHJlYWQgZnJvbSB0aGUgUXVlcnkuCi0gICAgICAvLyBJZiB3ZSBhcmUgYXQgdGhlIGVuZCB0aGUgc2lnbmFsIHRoYXQgZXZlbnQKLSAgICAgIGlmICggISBtX1Jlc3VsdFNldC5uZXh0KCkpCi0gICAgICB7Ci0gICAgICAgIC8vIEluIFN0cmVhbWluZyBtb2RlLCB0aGUgY3VycmVudCBST1cgd2lsbCBhbHdheXMgcG9pbnQgYmFjawotICAgICAgICAvLyB0byBpdHNlbGYgdW50aWwgYWxsIHRoZSBkYXRhIHdhcyByZWFkLiBPbmNlIHRoZSBRdWVyeSBpcwotICAgICAgICAvLyBlbXB0eSB0aGVuIHBvaW50IHRoZSBuZXh0IHJvdyB0byBEVE0uTlVMTCBzbyB0aGF0IHRoZSBzdHJlYW0KLSAgICAgICAgLy8gZW5kcy4KLQotICAgICAgICBpZiAobV9TdHJlYW1pbmdNb2RlKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gV2UgYXJlIGF0IHRoZSBlbmQsIHNvIGxldCdzIHVudGllIHRoZSBtYXJrCi0gICAgICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCwgbV9MYXN0Um93SWR4KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSBoZXJlLCBzdGFydCB0aGUgbmV3IGxldmVsCi0gICAgICBpZiAobV9GaXJzdFJvd0lkeCA9PSBEVE0uTlVMTCkKLSAgICAgIHsKLSAgICAgICAgbV9GaXJzdFJvd0lkeCA9Ci0gICAgICAgICAgYWRkRWxlbWVudCgyLCBtX1Jvd19UeXBlSUQsIG1fUm93U2V0SWR4LCBEVE0uTlVMTCk7Ci0gICAgICAgIG1fTGFzdFJvd0lkeCA9IG1fRmlyc3RSb3dJZHg7Ci0KLSAgICAgICAgaWYgKG1fU3RyZWFtaW5nTW9kZSkKLSAgICAgICAgewotICAgICAgICAgIC8vIExldCdzIHRpZSB0aGUgcm93cyB0b2dldGhlciB1bnRpbCB0aGUgZW5kLgotICAgICAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQobV9MYXN0Um93SWR4LCBtX0xhc3RSb3dJZHgpOwotICAgICAgICB9Ci0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgLy8KLSAgICAgICAgLy8gSWYgd2UgYXJlIGluIFN0cmVhbWluZyBtb2RlLCB0aGVuIG9ubHkgdXNlIGEgc2luZ2xlIHJvdyBpbnN0YW5jZQotICAgICAgICBpZiAoISBtX1N0cmVhbWluZ01vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBtX0xhc3RSb3dJZHggPSBhZGRFbGVtZW50KDMsIG1fUm93X1R5cGVJRCwgbV9Sb3dTZXRJZHgsIG1fTGFzdFJvd0lkeCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy8gSWYgd2UgYXJlIG5vdCBpbiBzdHJlYW1pbmcgbW9kZSwgdGhpcyB3aWxsIGFsd2F5cyBiZSBEVE0uTlVMTAotICAgICAgLy8gSWYgd2UgYXJlIGluIHN0cmVhbWluZyBtb2RlLCBpdCB3aWxsIG9ubHkgYmUgRFRNLk5VTEwgdGhlIGZpcnN0IHRpbWUKLSAgICAgIGludCBjb2xJRCA9IF9maXJzdGNoKG1fTGFzdFJvd0lkeCk7Ci0KLSAgICAgIC8vIEtlZXAgVHJhY2sgb2Ygd2hvIG91ciBwYXJlbnQgd2FzIHdoZW4gYWRkaW5nIG5ldyBjb2wgb2JqZWN0cy4KLSAgICAgIGludCBwY29sSUQgPSBEVE0uTlVMTDsKLQotICAgICAgLy8gQ29sdW1ucyBpbiBKREJDIFN0YXJ0IGF0IDEgYW5kIGdvIHRvIHRoZSBFeHRlbnQKLSAgICAgIGZvciAoaW50IGk9MTsgaTw9IG1fQ29sQ291bnQ7IGkrKykKLSAgICAgIHsKLSAgICAgICAgLy8gSnVzdCBncmFiIHRoZSBDb2x1bW4gT2JqZWN0IFR5cGUsIHdlIHdpbGwgY29udmVydCBpdCB0byBhIHN0cmluZwotICAgICAgICAvLyBsYXRlci4KLSAgICAgICAgT2JqZWN0IG8gPSBtX1Jlc3VsdFNldC5nZXRPYmplY3QoaSk7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGNvbHVtbiBvYmplY3QgaWYgb25lIGRvZXMgbm90IGV4aXN0LgotICAgICAgICAvLyBJbiBTdHJlYW1pbmcgbW9kZSwgdGhpcyBtZWNoaW5pc20gd2lsbCByZXVzZSB0aGUgY29sdW1uCi0gICAgICAgIC8vIGRhdGEgdGhlIHNlY29uZCBhbmQgc3Vic2VxdWVudCByb3cgYWNjZXNzZXMuCi0gICAgICAgIGlmIChjb2xJRCA9PSBEVE0uTlVMTCkKLSAgICAgICAgewotICAgICAgICAgIHBjb2xJRCA9IGFkZEVsZW1lbnRXaXRoRGF0YShvLDMsbV9Db2xfVHlwZUlELCBtX0xhc3RSb3dJZHgsIHBjb2xJRCk7Ci0gICAgICAgICAgY2xvbmVBdHRyaWJ1dGVGcm9tTm9kZShwY29sSUQsIG1fQ29sSGVhZGVyc0lkeFtpLTFdKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBXZSBtdXN0IGJlIGluIHN0cmVhbWluZyBtb2RlLCBzbyBsZXQncyBqdXN0IHJlcGxhY2UgdGhlIGRhdGEKLSAgICAgICAgICAvLyBJZiB0aGUgZmlyc3RjaCB3YXMgbm90IHNldCB0aGVuIHdlIGhhdmUgYSBtYWpvciBlcnJvcgotICAgICAgICAgIGludCBkYXRhSWRlbnQgPSBfZmlyc3RjaChjb2xJRCk7Ci0gICAgICAgICAgaWYgKGRhdGFJZGVudCA9PSBEVE0uTlVMTCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBlcnJvcigiU3RyZWFtaW5nIE1vZGUsIERhdGEgRXJyb3IiKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG1fT2JqZWN0QXJyYXkuc2V0QXQoZGF0YUlkZW50LCBvKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0gLy8gSWYKLQotICAgICAgICAvLyBJbiBzdHJlYW1pbmcgbW9kZSwgdGhpcyB3aWxsIGJlICFEVE0uTlVMTAotICAgICAgICAvLyBTbyBpZiB0aGUgZWxlbWVudHMgd2VyZSBhbHJlYWR5IGVzdGFibGlzaGVkIHRoZW4gd2UKLSAgICAgICAgLy8gc2hvdWxkIGJlIGFibGUgdG8gd2FsayB0aGVtIGluIG9yZGVyLgotICAgICAgICBpZiAoY29sSUQgIT0gRFRNLk5VTEwpCi0gICAgICAgIHsKLSAgICAgICAgICBjb2xJRCA9IF9uZXh0c2liKGNvbElEKTsKLSAgICAgICAgfQotCi0gICAgICB9IC8vIEZvciBDb2wgTG9vcAotICAgIH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBpZiAoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICAgICAiU1FMIEVycm9yIEZldGNoaW5nIG5leHQgcm93IFsiICsgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkgKyAiXSIpOwotICAgICAgfQotCi0gICAgICBlcnJvcigiU1FMIEVycm9yIEZldGNoaW5nIG5leHQgcm93IFsiICsgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkgKyAiXSIpOwotICAgIH0KLQotICAgIC8vIE9ubHkgZG8gYSBzaW5nbGUgcm93Li4uCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDbGVhbiB1cCBvdXIgdGllcyB0byB0aGUgZGF0YWJhc2UgYnV0IHRoaXMgZG9lcyBub3QgbmVjZXNzYXJseQotICAgKiBjbGVhbiB1cCB0aGUgZG9jdW1lbnQuCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsb3NlKCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiY2xvc2UoKSIpOwotCi0gICAgdHJ5IHsgaWYgKG51bGwgIT0gbV9SZXN1bHRTZXQpIG1fUmVzdWx0U2V0LmNsb3NlKCk7IH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkgeyB9Ci0gICAgdHJ5IHsgaWYgKG51bGwgIT0gbV9TdGF0ZW1lbnQpIG1fU3RhdGVtZW50LmNsb3NlKCk7IH0KLSAgICBjYXRjaChFeGNlcHRpb24gZSkgeyB9Ci0gICAgdHJ5IHsKLSAgICAgIGlmIChudWxsICE9IG1fQ29ubmVjdGlvbikKLSAgICAgICAgbV9Db25uZWN0aW9uUG9vbC5yZWxlYXNlQ29ubmVjdGlvbihtX0Nvbm5lY3Rpb24pOwotICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsgfQotICB9Ci0KLSAgLyoqCi0gICAqIFdoZW4gYW4gZXJyb3Igb2NjdXJzLCB0aGUgWENvbm5lY3Rpb24gd2lsbCBjYWxsIHRoaXMgbWV0aG9kCi0gICAqIGRvIHRoYXQgd2UgY2FuIGRlYWwgd2l0aCB0aGUgQ29ubmVjdGlvbiBwcm9wZXJseQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZU9uRXJyb3IoICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJjbG9zZSgpIik7Ci0KLSAgICB0cnkgIHsgaWYgKG51bGwgIT0gbV9SZXN1bHRTZXQpIG1fUmVzdWx0U2V0LmNsb3NlKCk7ICAgfQotICAgIGNhdGNoKEV4Y2VwdGlvbiBlKSB7IH0KLSAgICB0cnkgIHsgaWYgKG51bGwgIT0gbV9TdGF0ZW1lbnQpIG1fU3RhdGVtZW50LmNsb3NlKCk7Ci0gICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeyB9Ci0gICAgdHJ5IHsKLSAgICAgIGlmIChudWxsICE9IG1fQ29ubmVjdGlvbikKLSAgICAgICAgbV9Db25uZWN0aW9uUG9vbC5yZWxlYXNlQ29ubmVjdGlvbk9uRXJyb3IobV9Db25uZWN0aW9uKTsKLSAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7IH0KLSAgfQotCi0KLQotICAvKioKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbmV4dE5vZGUoICkKLSAgewotICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJuZXh0Tm9kZSgpIik7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotLy8gICAgICByZXR1cm4gbV9SZXN1bHRTZXQuaXNBZnRlckxhc3QoKTsKLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gaWRlbnRpdHkKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfbmV4dHNpYiggaW50IGlkZW50aXR5ICkKLSAgewotICAgIC8vIElmIHdlIGFyZSBhc2tpbmcgZm9yIHRoZSBuZXh0IHJvdyBhbmQgd2UgaGF2ZSBub3QKLSAgICAvLyBiZWVuIHRoZXJlIHlldCB0aGVuIGxldCdzIHNlZSBpZiB3ZSBjYW4gZ2V0IGFub3RoZXIKLSAgICAvLyByb3cgZnJvbSB0aGUgUmVzdWx0U2V0LgotICAgIC8vCi0KLSAgICBpbnQgaWQgPSBfZXhwdHlwZShpZGVudGl0eSk7Ci0gICAgaWYgKAotICAgICAgKCBpZCA9PSBtX1Jvd19UeXBlSUQpICYmCi0gICAgICAoaWRlbnRpdHkgPj0gbV9MYXN0Um93SWR4KSkKLSAgICB7Ci0gICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigicmVhZGluZyBmcm9tIHRoZSBSZXN1bHRTZXQiKTsKLSAgICAgIGFkZFJvd1RvRFRNRnJvbVJlc3VsdFNldCgpOwotICAgIH0KLQotICAgIHJldHVybiBzdXBlci5fbmV4dHNpYihpZGVudGl0eSk7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlZ2lzdHJhdGlvbigpCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiRG9jdW1lbnQgUmVnaXN0cmF0aW9uIik7Ci0gIH0KLQotICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlbGVhc2UoKQotICB7Ci0gICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIkRvY3VtZW50IFJlbGVhc2UiKTsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvU1FMRXJyb3JEb2N1bWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9TUUxFcnJvckRvY3VtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJhODE3MmEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9TUUxFcnJvckRvY3VtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDMgKzAsMCBAQAotLyoqCi0gKiBAKCMpIFNRTEVycm9yRG9jdW1lbnQuamF2YQotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBqYXZhLnNxbC5TUUxFeGNlcHRpb247Ci0KLS8qKgotICoKLSAqIEEgYmFzZSBjbGFzcyB0aGF0IHdpbGwgY29udmVydCBhbiBleGNlcHRpb24gaW50byBhbiBYTUwgc3RyZWFtCi0gKiB0aGF0IGNhbiBiZSByZXR1cm5lZCBpbiBwbGFjZSBvZiB0aGUgc3RhbmRhcmQgcmVzdWx0LiBUaGUgWE1MCi0gKiBmb3JtYXQgcmV0dXJuZWQgaXMgYSBmb2xsb3dzLgotICoKLSAqIDxleHQtZXJyb3I+Ci0gKiAgPG1lc3NhZ2U+IFRoZSBNZXNzYWdlIGZvciBhIGdlbmVyaWMgZXJyb3IgPC9tZXNzYWdlPgotICogIDxzcWwtZXJyb3I+Ci0gKiAgICA8bWVzc2FnZT4gU1FMIE1lc3NhZ2UgZnJvbSB0aGUgRXhjZXB0aW9uIHRocm93biA8L21lc3NhZ2U+Ci0gKiAgICA8Y29kZT4gU1FMIEVycm9yIENvZGUgPC9zdGFjaz4KLSAqICA8L3NxbC1lcnJvcj4KLSAqIDxleHQtZXJyb3I+Ci0gKgotICovCi0KLS8qKgotICogVGhlIFNRTCBEb2N1bWVudCBpcyB0aGUgbWFpbiBjb250cm9sbGluZyBjbGFzcyB0aGUgZXhlY3V0ZXNhIFNRTCBRdWVyeQotICovCi1wdWJsaWMgY2xhc3MgU1FMRXJyb3JEb2N1bWVudCBleHRlbmRzIERUTURvY3VtZW50Ci17Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfRVhUX0VSUk9SID0gImV4dC1lcnJvciI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfU1FMX0VSUk9SID0gInNxbC1lcnJvciI7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNfTUVTU0FHRSA9ICJtZXNzYWdlIjsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19DT0RFID0gImNvZGUiOwotCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9FcnJvckV4dF9UeXBlSUQgPSBEVE0uTlVMTDsKLSAgLyoqCi0gICAqLwotICBwcml2YXRlIGludCBtX01lc3NhZ2VfVHlwZUlEID0gRFRNLk5VTEw7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9Db2RlX1R5cGVJRCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9TUUxFcnJvcl9UeXBlSUQgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgaW50IG1fcm9vdElEID0gRFRNLk5VTEw7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9leHRFcnJvcklEID0gRFRNLk5VTEw7Ci0gIC8qKgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9NYWluTWVzc2FnZUlEID0gRFRNLk5VTEw7Ci0KLSAgLyoqCi0gICAqIEJ1aWxkIHVwIGFuIFNRTEVycm9yRG9jdW1lbnQgdGhhdCBpbmNsdWRlcyB0aGUgYmFzaWMgZXJyb3IgaW5mb3JtYXRpb24KLSAgICogYWxvbmcgd2l0aCB0aGUgRXh0ZW5kZWQgU1FMIEVycm9yIGluZm9ybWF0aW9uLgotICAgKiBAcGFyYW0gbWdyCi0gICAqIEBwYXJhbSBpZGVudAotICAgKiBAcGFyYW0gZXJyb3IKLSAgICovCi0gIHB1YmxpYyBTUUxFcnJvckRvY3VtZW50KCBEVE1NYW5hZ2VyIG1nciwgaW50IGlkZW50LCBTUUxFeGNlcHRpb24gZXJyb3IgKQotICB7Ci0gICAgc3VwZXIobWdyLCBpZGVudCk7Ci0KLSAgICBjcmVhdGVFeHBhbmRlZE5hbWVUYWJsZSgpOwotICAgIGJ1aWxkQmFzaWNTdHJ1Y3R1cmUoZXJyb3IpOwotCi0gICAgaW50IHNxbEVycm9yID0gYWRkRWxlbWVudCgyLCBtX1NRTEVycm9yX1R5cGVJRCwgbV9leHRFcnJvcklELCBtX01haW5NZXNzYWdlSUQpOwotICAgIGludCBlbGVtZW50ID0gRFRNLk5VTEw7Ci0KLSAgICBlbGVtZW50ID0gYWRkRWxlbWVudFdpdGhEYXRhKAotICAgICAgbmV3IEludGVnZXIoZXJyb3IuZ2V0RXJyb3JDb2RlKCkpLCAzLAotICAgICAgbV9Db2RlX1R5cGVJRCwgc3FsRXJyb3IsIGVsZW1lbnQpOwotCi0gICAgZWxlbWVudCA9IGFkZEVsZW1lbnRXaXRoRGF0YSgKLSAgICAgIGVycm9yLmdldExvY2FsaXplZE1lc3NhZ2UoKSwgMywKLSAgICAgIG1fTWVzc2FnZV9UeXBlSUQsIHNxbEVycm9yLCBlbGVtZW50KTsKLQotLy8gICAgdGhpcy5kdW1wRFRNKCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBCdWlsZCB1cCBhbiBFcnJvciBFeGNlcHRpb24gd2l0aCBqdXN0IHRoZSBTdGFuZGFyZCBFcnJvciBJbmZvcm1hdGlvbgotICAgKiBAcGFyYW0gbWdyCi0gICAqIEBwYXJhbSBpZGVudAotICAgKiBAcGFyYW0gZXJyb3IKLSAgICovCi0gIHB1YmxpYyBTUUxFcnJvckRvY3VtZW50KCBEVE1NYW5hZ2VyIG1nciwgaW50IGlkZW50LCBFeGNlcHRpb24gZXJyb3IgKQotICB7Ci0gICAgc3VwZXIobWdyLCBpZGVudCk7Ci0gICAgY3JlYXRlRXhwYW5kZWROYW1lVGFibGUoKTsKLSAgICBidWlsZEJhc2ljU3RydWN0dXJlKGVycm9yKTsKLSAgfQotCi0gIC8qKgotICAgKiBCdWlsZCB1cCB0aGUgYmFzaWMgc3RydWN0dXJlIHRoYXQgaXMgY29tbW9uIGZvciBlYWNoIGVycm9yLgotICAgKiBAcGFyYW0gZQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcml2YXRlIHZvaWQgYnVpbGRCYXNpY1N0cnVjdHVyZSggRXhjZXB0aW9uIGUgKQotICB7Ci0gICAgbV9yb290SUQgPSBhZGRFbGVtZW50KDAsIG1fRG9jdW1lbnRfVHlwZUlELCBEVE0uTlVMTCwgRFRNLk5VTEwpOwotICAgIG1fZXh0RXJyb3JJRCA9IGFkZEVsZW1lbnQoMSwgbV9FcnJvckV4dF9UeXBlSUQsIG1fcm9vdElELCBEVE0uTlVMTCk7Ci0gICAgbV9NYWluTWVzc2FnZUlEID0gYWRkRWxlbWVudFdpdGhEYXRhCi0gICAgICAoZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCksIDIsIG1fTWVzc2FnZV9UeXBlSUQsIG1fZXh0RXJyb3JJRCwgRFRNLk5VTEwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcHVsYXRlIHRoZSBFeHBhbmRlZCBOYW1lIFRhYmxlIHdpdGggdGhlIE5vZGUgdGhhdCB3ZSB3aWxsIHVzZS4KLSAgICogS2VlcCBhIHJlZmVyZW5jZSBvZiBlYWNoIG9mIHRoZSB0eXBlcyBmb3IgYWNjZXNzIHNwZWVkLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVFeHBhbmRlZE5hbWVUYWJsZSggKQotICB7Ci0KLSAgICBzdXBlci5jcmVhdGVFeHBhbmRlZE5hbWVUYWJsZSgpOwotCi0gICAgbV9FcnJvckV4dF9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19FWFRfRVJST1IsIERUTS5FTEVNRU5UX05PREUpOwotCi0gICAgbV9TUUxFcnJvcl9UeXBlSUQgPQotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChTX05BTUVTUEFDRSwgU19TUUxfRVJST1IsIERUTS5FTEVNRU5UX05PREUpOwotCi0gICAgbV9NZXNzYWdlX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX01FU1NBR0UsIERUTS5FTEVNRU5UX05PREUpOwotCi0gICAgbV9Db2RlX1R5cGVJRCA9Ci0gICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKFNfTkFNRVNQQUNFLCBTX0NPREUsIERUTS5FTEVNRU5UX05PREUpOwotICB9Ci0KLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL1hDb25uZWN0aW9uLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL1hDb25uZWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIzN2QxNDQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9YQ29ubmVjdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM4OSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsOwotCi1pbXBvcnQgamF2YS5zcWwuQ29ubmVjdGlvbjsKLWltcG9ydCBqYXZhLnNxbC5EYXRhYmFzZU1ldGFEYXRhOwotaW1wb3J0IGphdmEuc3FsLkRyaXZlck1hbmFnZXI7Ci1pbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuc3FsLlN0YXRlbWVudDsKLWltcG9ydCBqYXZhLnNxbC5QcmVwYXJlZFN0YXRlbWVudDsKLWltcG9ydCBqYXZhLnNxbC5SZXN1bHRTZXQ7Ci1pbXBvcnQgamF2YS5zcWwuRGF0ZTsKLWltcG9ydCBqYXZhLnNxbC5UaW1lc3RhbXA7Ci1pbXBvcnQgamF2YS5zcWwuVGltZTsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1NYW5hZ2VyRGVmYXVsdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuRXhwcmVzc2lvbkNvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuU3RhdGljOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBqYXZhLnNxbC4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIEFuIFhTTFQgZXh0ZW5zaW9uIHRoYXQgYWxsb3dzIGEgc3R5bGVzaGVldCB0bwotICogYWNjZXNzIEpEQkMgZGF0YS4gRnJvbSB0aGUgc3R5bGVzaGVldCBwZXJzcGVjdGl2ZSwKLSAqIFhDb25uZWN0aW9uIHByb3ZpZGVzIDMgZXh0ZW5zaW9uIGZ1bmN0aW9uczogbmV3KCksCi0gKiBxdWVyeSgpLCBhbmQgY2xvc2UoKS4KLSAqIFVzZSBuZXcoKSB0byBjYWxsIG9uZSBvZiBYQ29ubmVjdGlvbiBjb25zdHJ1Y3RvcnMsIHdoaWNoCi0gKiBlc3RhYmxpc2hlcyBhIEpEQkMgZHJpdmVyIGNvbm5lY3Rpb24gdG8gYSBkYXRhIHNvdXJjZSBhbmQKLSAqIHJldHVybnMgYW4gWENvbm5lY3Rpb24gb2JqZWN0LgotICogVGhlbiB1c2UgdGhlIFhDb25uZWN0aW9uIG9iamVjdCBxdWVyeSgpIG1ldGhvZCB0byByZXR1cm4gYQotICogcmVzdWx0IHNldCBpbiB0aGUgZm9ybSBvZiBhIHJvdy1zZXQgZWxlbWVudC4KLSAqIFdoZW4geW91IGhhdmUgZmluaXNoZWQgd29ya2luZyB3aXRoIHRoZSByb3ctc2V0LCBjYWxsIHRoZQotICogWENvbm5lY3Rpb24gb2JqZWN0IGNsb3NlKCkgbWV0aG9kIHRvIHRlcm1pbmF0ZSB0aGUgY29ubmVjdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIFhDb25uZWN0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEZsYWcgZm9yIERFQlVHIG1vZGUKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogVGhlIEN1cnJlbnQgQ29ubmVjdGlvbiBQb29sIGluIFVzZS4gQW4gWENvbm5lY3Rpb24gY2FuIG9ubHkKLSAgICogcmVwcmVzZW50IG9uZSBxdWVyeSBhdCBhIHRpbWUsIHByaW9yIHRvIGRvaW5nIHNvbWUgdHlwZSBvZiBxdWVyeS4KLSAgICovCi0gIHByaXZhdGUgQ29ubmVjdGlvblBvb2wgbV9Db25uZWN0aW9uUG9vbCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIElmIGEgZGVmYXVsdCBDb25uZWN0aW9uIFBvb2wgaXMgdXNlZC4gaS5lLiBBIGNvbm5lY3Rpb24gUG9vbAotICAgKiB0aGF0IGlzIGNyZWF0ZWQgaW50ZXJuYWxseSwgdGhlbiBkbyB3ZSBhY3R1YWxseSBhbGxvdyBwb29scwotICAgKiB0byBiZSBjcmVhdGVkLiBEdWUgdG8gdGhlIGFyY2hpdGl0dXJlIG9mIHRoZSBYYWxhbiBFeHRlbnNpb25zLAotICAgKiB0aGVyZSBpcyBubyBub3RpZmljYXRpb24gb2Ygd2hlbiB0aGUgRXh0ZW5zaW9uIGlzIGJlaW5nIHVubG9hZGVkIGFuZAotICAgKiBhcyBzdWNoLCB0aGVyZSBpcyBhIGdvb2QgY2hhbmNlIHRoYXQgSkRCQyBDT25uZWN0aW9ucyBhcmUgbm90IGNsb3NlZC4KLSAgICogQSBmaW5hbGl6ZWQgaXMgcHJvdmlkZWQgdG8gdHJ5IGFuZCBjYXRjaCB0aGlzIHNpdHVhdGlvbiBidXQgc2luY2UKLSAgICogc3VwcG9ydCBvZiBmaW5hbGl6ZXJzIGlzIGluY29uc2lzdGFudCBhY3Jvc3MgSlZNJ3MgdGhpcyBtYXkgY2F1c2UKLSAgICogYSBwcm9ibGVtLiBUaGUgcm9idXN0bmVzcyBvZiB0aGUgSkRCQyBEcml2ZXIgaXMgYWxzbyBhdCBpc3N1ZSBoZXJlLgotICAgKiBpZiBhIGNvbnRyb2xsZWQgc2h1dGRvd24gaXMgcHJvdmlkZWQgYnkgdGhlIGRyaXZlciB0aGVuIGRlZmF1bHQKLSAgICogY29ubnRlY3Rpb20gcG9vbHMgYXJlIE9LLgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fRGVmYXVsdFBvb2xpbmdFbmFibGVkID0gZmFsc2U7Ci0KLQotICAvKioKLSAgICogQXMgd2UgZG8gcXVlcmllcywgd2Ugd2lsbCBwcm9kdWNlIFNRTCBEb2N1bWVudHMuIEFueSBvbnkgbWF5IHByb2R1Y2UKLSAgICogb25lIG9yIG1vcmUgU1FMIERvY3VtZW50cyBzbyB0aGF0IHRoZSBjdXJyZW50IGNvbm5lY3Rpb24gaW5mb3JtYXRpb24KLSAgICogbWF5IGJlIGVhc2lsbHkgcmV1c2VkLiBUaGlzIGNvbGxlY3Rpb24gd2lsbCBob2xkIGEgY29sbGVjdGlvbiBvZiBhbGwKLSAgICogdGhlIGRvY3VtZW50cyBjcmVhdGVkLiBBcyBEb2N1bWVudHMgYXJlIGNsb3NlZCwgdGhleSB3aWxsIGJlIHJlbW92ZWQKLSAgICogZnJvbSB0aGUgY29sbGVjdGlvbiBhbmQgdG9sZCB0byBmcmVlIGFsbCB0aGUgdXNlZCByZXNvdXJjZXMuCi0gICAqLwotICBwcml2YXRlIFZlY3RvciBtX09wZW5TUUxEb2N1bWVudHMgPSBuZXcgVmVjdG9yKCk7Ci0KLQotICAvKioKLSAgICogTGV0J3Mga2VlcCBhIGNvcHkgb2YgdGhlIENvbm5lY3Rpb25Qb29sTWdyIGluCi0gICAqIGFsaXZlIGhlcmUgc28gd2UgYXJlIGtlZXBpbmcgdGhlIHN0YXRpYyBwb29sIGFsaXZlCi0gICAqIFdlIHdpbGwgYWxzbyB1c2UgdGhpcyBQb29sIE1hbmFnZXIgdG8gcmVnaXN0ZXIgb3VyIGRlZmF1bHQgcG9vbHMuCi0gICAqLwotICBwcml2YXRlIENvbm5lY3Rpb25Qb29sTWFuYWdlciBtX1Bvb2xNZ3IgPSBuZXcgQ29ubmVjdGlvblBvb2xNYW5hZ2VyKCk7Ci0KLSAgLyoqCi0gICAqIEZvciBQcmVwYXJlZFN0YXRlbWVudHMsIHdlIG5lZWQgYSBwbGFjZSB0bwotICAgKiB0byBzdG9yZSB0aGUgcGFyYW1ldGVycyBpbiBhIHZlY3Rvci4KLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fUGFyYW1ldGVyTGlzdCA9IG5ldyBWZWN0b3IoKTsKLQotICAvKioKLSAgICogQWxsb3cgdGhlIFNRTCBFeHRlbnNpb25zIHRvIHJldHVybiBudWxsIG9uIGVycm9yLiBUaGUgRXJyb3IgaW5mb3JtYXRpb24gd2lsbAotICAgKiBiZSBzdG9yZWQgaW4gYSBzZXBlcmF0ZSBFcnJvciBEb2N1bWVudCB0aGF0IGNhbiBlYXNpbHkgYmUgcmV0cml2ZWQgdXNpbmcgdGhlCi0gICAqIGdldEVycm9yKCkgbWV0aG9kLgotICAgKiAlUkVWSUVXJSBUaGlzIGZ1bmN0aW9uYWxpdHkgd2lsbCBwcm9iYWJseSBiZSBidXJpZWQgaW5zaWRlIHRoZSBTUUxEb2N1bWVudC4KLSAgICovCi0gIHByaXZhdGUgU1FMRXJyb3JEb2N1bWVudCBtX0Vycm9yID0gbnVsbDsKLQotICAvKioKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX0lzRGVmYXVsdFBvb2wgPSBmYWxzZTsKLQotICAvKioKLSAgICogVGhpcyBmbGFnIHdpbGwgYmUgdXNlZCB0byBpbmRpY2F0ZSB0byB0aGUgU1FMRG9jdW1lbnQgdG8gdXNlCi0gICAqIFN0cmVhbWluZyBtb2RlLiBTdHJlZWFtaW5nIE1vZGUgd2lsbCByZWR1Y2UgdGhlIG1lbW9yeSBmb290cHJpbnQKLSAgICogdG8gYSBmaXhlZCBhbW91bnQgYnV0IHdpbGwgbm90IGxldCB5b3UgdHJhdmVyc2UgdGhlIHRyZWUgbW9yZSB0aGFuCi0gICAqIG9uY2Ugc2luY2UgdGhlIFJvdyBkYXRhIHdpbGwgYmUgcmV1c2VkIGZvciBldmVyeSBSb3cgaW4gdGhlIFF1ZXJ5LgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fSXNTdHJlYW1pbmdFbmFibGVkID0gdHJ1ZTsKLQotICAvKioKLSAgICovCi0gIHB1YmxpYyBYQ29ubmVjdGlvbiggKQotICB7Ci0gIH0KLQotICAvLyBUaGUgb3JpZ2luYWwgY29uc3RydWN0b3JzIHdpbGwgYmUga2VwdCBhcm91bmQgZm9yIGJhY2t3YXJkcwotICAvLyBjb21wYXRpYmlsaXR5LiBGdXR1cmUgU3R5bGVzaGVldHMgc2hvdWxkIHVzZSB0aGUgYXBwcm9haXRlCi0gIC8vIGNvbm5lY3QgbWV0aG9kIHRvIHJlY2VpdmUgZnVsbCBlcnJvciBpbmZvcm1hdGlvbi4KLSAgLy8KLSAgLyoqCi0gICAqIEBwYXJhbSBleHByQ29udGV4dAotICAgKiBAcGFyYW0gQ29ublBvb2xOYW1lCi0gICAqLwotICBwdWJsaWMgWENvbm5lY3Rpb24oIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBTdHJpbmcgQ29ublBvb2xOYW1lICkKLSAgewotICAgIGNvbm5lY3QoZXhwckNvbnRleHQsIENvbm5Qb29sTmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBkcml2ZXIKLSAgICogQHBhcmFtIGRiVVJMCi0gICAqLwotICBwdWJsaWMgWENvbm5lY3Rpb24oIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBTdHJpbmcgZHJpdmVyLCBTdHJpbmcgZGJVUkwgKQotICB7Ci0gICAgY29ubmVjdChleHByQ29udGV4dCwgZHJpdmVyLCBkYlVSTCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBsaXN0Ci0gICAqLwotICBwdWJsaWMgWENvbm5lY3Rpb24oIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBOb2RlTGlzdCBsaXN0ICkKLSAgewotICAgIGNvbm5lY3QoZXhwckNvbnRleHQsIGxpc3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBleHByQ29udGV4dAotICAgKiBAcGFyYW0gZHJpdmVyCi0gICAqIEBwYXJhbSBkYlVSTAotICAgKiBAcGFyYW0gdXNlcgotICAgKiBAcGFyYW0gcGFzc3dvcmQKLSAgICovCi0gIHB1YmxpYyBYQ29ubmVjdGlvbiggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIFN0cmluZyBkcml2ZXIsIFN0cmluZyBkYlVSTCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCApCi0gIHsKLSAgICBjb25uZWN0KGV4cHJDb250ZXh0LCBkcml2ZXIsIGRiVVJMLCB1c2VyLCBwYXNzd29yZCk7Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBkcml2ZXIKLSAgICogQHBhcmFtIGRiVVJMCi0gICAqIEBwYXJhbSBwcm90b2NvbEVsZW0KLSAgICovCi0gIHB1YmxpYyBYQ29ubmVjdGlvbiggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIFN0cmluZyBkcml2ZXIsIFN0cmluZyBkYlVSTCwgRWxlbWVudCBwcm90b2NvbEVsZW0gKQotICB7Ci0gICAgY29ubmVjdChleHByQ29udGV4dCwgZHJpdmVyLCBkYlVSTCwgcHJvdG9jb2xFbGVtKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYQ29ubmVjdGlvbiB1c2luZyB0aGUgbmFtZSBvZiBhbiBleGlzdGluZyBDb25uZWN0aW9uIFBvb2wKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBDb25uUG9vbE5hbWUKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFhCb29sZWFuU3RhdGljIGNvbm5lY3QoIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBTdHJpbmcgQ29ublBvb2xOYW1lICkKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIG1fQ29ubmVjdGlvblBvb2wgPSBtX1Bvb2xNZ3IuZ2V0UG9vbChDb25uUG9vbE5hbWUpOwotCi0gICAgICBpZiAobV9Db25uZWN0aW9uUG9vbCA9PSBudWxsKQotICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBQb29sIE5hbWUiKTsKLQotICAgICAgbV9Jc0RlZmF1bHRQb29sID0gZmFsc2U7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKHRydWUpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgYnVpbGRFcnJvckRvY3VtZW50KGV4cHJDb250ZXh0LCBlKTsKLSAgICAgIHJldHVybiBuZXcgWEJvb2xlYW5TdGF0aWMoZmFsc2UpOwotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYQ29ubmVjdGlvbiBvYmplY3Qgd2l0aCBqdXN0IGEgZHJpdmVyIGFuZCBkYXRhYmFzZSBVUkwuCi0gICAqIEBwYXJhbSBleHByQ29udGV4dAotICAgKiBAcGFyYW0gZHJpdmVyIEpEQkMgZHJpdmVyIG9mIHRoZSBmb3JtIGZvby5iYXIuRHJpdmVyLgotICAgKiBAcGFyYW0gZGJVUkwgZGF0YWJhc2UgVVJMIG9mIHRoZSBmb3JtIGpkYmM6c3VicHJvdG9jb2w6c3VibmFtZS4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFhCb29sZWFuU3RhdGljIGNvbm5lY3QoIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBTdHJpbmcgZHJpdmVyLCBTdHJpbmcgZGJVUkwgKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgaW5pdChkcml2ZXIsIGRiVVJMLCBuZXcgUHJvcGVydGllcygpKTsKLSAgICAgIHJldHVybiBuZXcgWEJvb2xlYW5TdGF0aWModHJ1ZSk7Ci0gICAgfQotICAgIGNhdGNoKFNRTEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBwcm90b2NvbEVsZW0KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFhCb29sZWFuU3RhdGljIGNvbm5lY3QoIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBFbGVtZW50IHByb3RvY29sRWxlbSApCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBpbml0RnJvbUVsZW1lbnQocHJvdG9jb2xFbGVtKTsKLSAgICAgIHJldHVybiBuZXcgWEJvb2xlYW5TdGF0aWModHJ1ZSk7Ci0gICAgfQotICAgIGNhdGNoKFNRTEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBsaXN0Ci0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBYQm9vbGVhblN0YXRpYyBjb25uZWN0KCBFeHByZXNzaW9uQ29udGV4dCBleHByQ29udGV4dCwgTm9kZUxpc3QgbGlzdCApCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBpbml0RnJvbUVsZW1lbnQoIChFbGVtZW50KSBsaXN0Lml0ZW0oMCkgKTsKLSAgICAgIHJldHVybiBuZXcgWEJvb2xlYW5TdGF0aWModHJ1ZSk7Ci0gICAgfQotICAgIGNhdGNoKFNRTEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKGZhbHNlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhDb25uZWN0aW9uIG9iamVjdCB3aXRoIHVzZXIgSUQgYW5kIHBhc3N3b3JkLgotICAgKiBAcGFyYW0gZXhwckNvbnRleHQKLSAgICogQHBhcmFtIGRyaXZlciBKREJDIGRyaXZlciBvZiB0aGUgZm9ybSBmb28uYmFyLkRyaXZlci4KLSAgICogQHBhcmFtIGRiVVJMIGRhdGFiYXNlIFVSTCBvZiB0aGUgZm9ybSBqZGJjOnN1YnByb3RvY29sOnN1Ym5hbWUuCi0gICAqIEBwYXJhbSB1c2VyIHVzZXIgSUQuCi0gICAqIEBwYXJhbSBwYXNzd29yZCBjb25uZWN0aW9uIHBhc3N3b3JkLgotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgWEJvb2xlYW5TdGF0aWMgY29ubmVjdCggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIFN0cmluZyBkcml2ZXIsIFN0cmluZyBkYlVSTCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCApCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBQcm9wZXJ0aWVzIHByb3AgPSBuZXcgUHJvcGVydGllcygpOwotICAgICAgcHJvcC5wdXQoInVzZXIiLCB1c2VyKTsKLSAgICAgIHByb3AucHV0KCJwYXNzd29yZCIsIHBhc3N3b3JkKTsKLQotICAgICAgaW5pdChkcml2ZXIsIGRiVVJMLCBwcm9wKTsKLQotICAgICAgcmV0dXJuIG5ldyBYQm9vbGVhblN0YXRpYyh0cnVlKTsKLSAgICB9Ci0gICAgY2F0Y2goU1FMRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgYnVpbGRFcnJvckRvY3VtZW50KGV4cHJDb250ZXh0LCBlKTsKLSAgICAgIHJldHVybiBuZXcgWEJvb2xlYW5TdGF0aWMoZmFsc2UpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgYnVpbGRFcnJvckRvY3VtZW50KGV4cHJDb250ZXh0LCBlKTsKLSAgICAgIHJldHVybiBuZXcgWEJvb2xlYW5TdGF0aWMoZmFsc2UpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYQ29ubmVjdGlvbiBvYmplY3Qgd2l0aCBhIGNvbm5lY3Rpb24gcHJvdG9jb2wKLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBkcml2ZXIgSkRCQyBkcml2ZXIgb2YgdGhlIGZvcm0gZm9vLmJhci5Ecml2ZXIuCi0gICAqIEBwYXJhbSBkYlVSTCBkYXRhYmFzZSBVUkwgb2YgdGhlIGZvcm0gamRiYzpzdWJwcm90b2NvbDpzdWJuYW1lLgotICAgKiBAcGFyYW0gcHJvdG9jb2xFbGVtIGxpc3Qgb2Ygc3RyaW5nIHRhZy92YWx1ZSBjb25uZWN0aW9uIGFyZ3VtZW50cywKLSAgICogbm9ybWFsbHkgaW5jbHVkaW5nIGF0IGxlYXN0ICJ1c2VyIiBhbmQgInBhc3N3b3JkIi4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIFhCb29sZWFuU3RhdGljIGNvbm5lY3QoIEV4cHJlc3Npb25Db250ZXh0IGV4cHJDb250ZXh0LCBTdHJpbmcgZHJpdmVyLCBTdHJpbmcgZGJVUkwsIEVsZW1lbnQgcHJvdG9jb2xFbGVtICkKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIFByb3BlcnRpZXMgcHJvcCA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAgIE5hbWVkTm9kZU1hcCBhdHRzID0gcHJvdG9jb2xFbGVtLmdldEF0dHJpYnV0ZXMoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRzLmdldExlbmd0aCgpOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHByb3AucHV0KGF0dHMuaXRlbShpKS5nZXROb2RlTmFtZSgpLCBhdHRzLml0ZW0oaSkuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgfQotCi0gICAgICBpbml0KGRyaXZlciwgZGJVUkwsIHByb3ApOwotCi0gICAgICByZXR1cm4gbmV3IFhCb29sZWFuU3RhdGljKHRydWUpOwotICAgIH0KLSAgICBjYXRjaChTUUxFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBidWlsZEVycm9yRG9jdW1lbnQoZXhwckNvbnRleHQsIGUpOwotICAgICAgcmV0dXJuIG5ldyBYQm9vbGVhblN0YXRpYyhmYWxzZSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBidWlsZEVycm9yRG9jdW1lbnQoZXhwckNvbnRleHQsIGUpOwotICAgICAgcmV0dXJuIG5ldyBYQm9vbGVhblN0YXRpYyhmYWxzZSk7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogQWxsb3cgdGhlIGRhdGFiYXNlIGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gdG8gYmUgc2VwY2lmaWVkIGluCi0gICAqIHRoZSBYTUwgdHJlZS4gVGhlIGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gY291bGQgYWxzbyBiZQotICAgKiBleHRlcm5hbGx5IG9yaWdpbmF0ZWQgYW5kIHBhc3NlZCBpbiBhcyBhbiBYU0wgUGFyYW1ldGVyLgotICAgKiBUaGUgcmVxdWlyZWQgWE1MIEZvcm1hdCBpcyBhcyBmb2xsb3dzLgotICAgKiBBIGRvY3VtZW50IGZyYWdtZW50IGlzIG5lZWRlZCB0byBzcGVjaWZ5IHRoZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uCi0gICAqIHRoZSB0b3AgdGFnIG5hbWUgaXMgbm90IHNwZWNpZmljIGZvciB0aGlzIGNvZGUsIHdlIGFyZSBvbmx5IGludGVyZXN0ZWQKLSAgICogaW4gdGhlIHRhZ3MgaW5zaWRlLgotICAgKiA8REJJTkZPLVRBRz4KLSAgICogU3BlY2lmeSB0aGUgZHJpdmVyIG5hbWUgZm9yIHRoaXMgY29ubmVjdGlvbiBwb29sCi0gICAqIDxkYmRyaXZlcj5kcml2ZXJuYW1lPC9kYmRyaXZlcj4KLSAgICogU3BlY2lmeSB0aGUgVVJMIGZvciB0aGUgZHJpdmVyIGluIHRoaXMgY29ubmVjdGlvbiBwb29sCi0gICAqIDxkYnVybD51cmw8L2RidXJsPgotICAgKiBTcGVjaWZ5IHRoZSBwYXNzd29yZCBmb3IgdGhpcyBjb25uZWN0aW9uIHBvb2wKLSAgICogPHBhc3N3b3JkPnBhc3N3b3JkPC9wYXNzd29yZD4KLSAgICogU3BlY2lmeSB0aGUgdXNlcm5hbWUgZm9yIHRoaXMgY29ubmVjdGlvbiBwb29sCi0gICAqIDx1c2VyPnVzZXJuYW1lPC91c2VyPgotICAgKiBZb3UgY2FuIGFkZCBleHRyYSBwcm90b2NvbCBpdGVtcyBpbmNsdWRpbmcgdGhlIFVzZXIgTmFtZSAmIFBhc3N3b3JkCi0gICAqIHdpdGggdGhlIHByb3RvY29sIHRhZy4gRm9yIGVhY2ggZXh0cmEgcHJvdG9jb2wgaXRlbSwgYWRkIGEgbmV3IGVsZW1lbnQKLSAgICogd2hlcmUgdGhlIG5hbWUgb2YgdGhlIGl0ZW0gaXMgc3BlY2lmaWVkIGFzIHRoZSBuYW1lIGF0dHJpYnV0ZSBhbmQKLSAgICogYW5kIGl0cyB2YWx1ZSBhcyB0aGUgZWxlbWVudHMgdmFsdWUuCi0gICAqIDxwcm90b2NvbCBuYW1lPSJuYW1lIG9mIHZhbHVlIj52YWx1ZTwvcHJvdG9jb2w+Ci0gICAqIDwvREJJTkZPLVRBRz4KLSAgICogQHBhcmFtIGUKLSAgICogQHJldHVybgotICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXRGcm9tRWxlbWVudCggRWxlbWVudCBlICl0aHJvd3MgU1FMRXhjZXB0aW9uCi0gIHsKLQotICAgIFByb3BlcnRpZXMgcHJvcCA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0gICAgU3RyaW5nIGRyaXZlciA9ICIiOwotICAgIFN0cmluZyBkYlVSTCA9ICIiOwotICAgIE5vZGUgbiA9IGUuZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgaWYgKG51bGwgPT0gbikgcmV0dXJuOyAvLyByZWFsbHkgbmVlZCB0byB0aHJvdyBhbiBlcnJvcgotCi0gICAgZG8KLSAgICB7Ci0gICAgICBTdHJpbmcgbk5hbWUgPSBuLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgIGlmIChuTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJkYmRyaXZlciIpKQotICAgICAgewotICAgICAgICBkcml2ZXIgPSAiIjsKLSAgICAgICAgTm9kZSBuMSA9IG4uZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICBpZiAobnVsbCAhPSBuMSkKLSAgICAgICAgewotICAgICAgICAgIGRyaXZlciA9IG4xLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChuTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJkYnVybCIpKQotICAgICAgewotICAgICAgICBkYlVSTCA9ICIiOwotICAgICAgICBOb2RlIG4xID0gbi5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgIGlmIChudWxsICE9IG4xKQotICAgICAgICB7Ci0gICAgICAgICAgZGJVUkwgPSBuMS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobk5hbWUuZXF1YWxzSWdub3JlQ2FzZSgicGFzc3dvcmQiKSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIHMgPSAiIjsKLSAgICAgICAgTm9kZSBuMSA9IG4uZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICBpZiAobnVsbCAhPSBuMSkKLSAgICAgICAgewotICAgICAgICAgIHMgPSBuMS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBwcm9wLnB1dCgicGFzc3dvcmQiLCBzKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG5OYW1lLmVxdWFsc0lnbm9yZUNhc2UoInVzZXIiKSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIHMgPSAiIjsKLSAgICAgICAgTm9kZSBuMSA9IG4uZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICBpZiAobnVsbCAhPSBuMSkKLSAgICAgICAgewotICAgICAgICAgIHMgPSBuMS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBwcm9wLnB1dCgidXNlciIsIHMpOwotICAgICAgfQotCi0gICAgICBpZiAobk5hbWUuZXF1YWxzSWdub3JlQ2FzZSgicHJvdG9jb2wiKSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIE5hbWUgPSAiIjsKLQotICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cnMgPSBuLmdldEF0dHJpYnV0ZXMoKTsKLSAgICAgICAgTm9kZSBuMSA9IGF0dHJzLmdldE5hbWVkSXRlbSgibmFtZSIpOwotICAgICAgICBpZiAobnVsbCAhPSBuMSkKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBzID0gIiI7Ci0gICAgICAgICAgTmFtZSA9IG4xLmdldE5vZGVWYWx1ZSgpOwotCi0gICAgICAgICAgTm9kZSBuMiA9IG4uZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgIGlmIChudWxsICE9IG4yKSBzID0gbjIuZ2V0Tm9kZVZhbHVlKCk7Ci0KLSAgICAgICAgICBwcm9wLnB1dChOYW1lLCBzKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgfSB3aGlsZSAoIChuID0gbi5nZXROZXh0U2libGluZygpKSAhPSBudWxsKTsKLQotICAgIGluaXQoZHJpdmVyLCBkYlVSTCwgcHJvcCk7Ci0gIH0KLQotCi0KLSAgLyoqCi0gICAqIEluaXRpbGl6ZSBpcyBiZWluZyBjYWxsZWQgYmVjYXVzZSB3ZSBkaWQgbm90IGhhdmUgYW4KLSAgICogZXhpc3RpbmcgQ29ubmVjdGlvbiBQb29sLCBzbyBsZXQncyBzZWUgaWYgd2UgY3JlYXRlZCBvbmUKLSAgICogYWxyZWFkeSBvciBsZXRzIGNyZWF0ZSBvbmUgb3Vyc2VsdmVzLgotICAgKiBAcGFyYW0gZHJpdmVyCi0gICAqIEBwYXJhbSBkYlVSTAotICAgKiBAcGFyYW0gcHJvcAotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdCggU3RyaW5nIGRyaXZlciwgU3RyaW5nIGRiVVJMLCBQcm9wZXJ0aWVzIHByb3AgKXRocm93cyBTUUxFeGNlcHRpb24KLSAgewotICAgIENvbm5lY3Rpb24gY29uID0gbnVsbDsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiWENvbm5lY3Rpb24sIENvbm5lY3Rpb24gSW5pdCIpOwotCi0gICAgU3RyaW5nIHVzZXIgPSBwcm9wLmdldFByb3BlcnR5KCJ1c2VyIik7Ci0gICAgaWYgKHVzZXIgPT0gbnVsbCkgdXNlciA9ICIiOwotCi0gICAgU3RyaW5nIHBhc3N3ZCA9IHByb3AuZ2V0UHJvcGVydHkoInBhc3N3b3JkIik7Ci0gICAgaWYgKHBhc3N3ZCA9PSBudWxsKSBwYXNzd2QgPSAiIjsKLQotCi0gICAgU3RyaW5nIHBvb2xOYW1lID0gZHJpdmVyICsgZGJVUkwgKyB1c2VyICsgcGFzc3dkOwotICAgIENvbm5lY3Rpb25Qb29sIGNwb29sID0gbV9Qb29sTWdyLmdldFBvb2wocG9vbE5hbWUpOwotCi0gICAgaWYgKGNwb29sID09IG51bGwpCi0gICAgewotCi0gICAgICBpZiAoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiWENvbm5lY3Rpb24sIENyZWF0aW5nIENvbm5lY3Rpb24iKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgRHJpdmVyICA6IiArIGRyaXZlcik7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIFVSTCAgICAgOiIgKyBkYlVSTCk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIHVzZXIgICAgOiIgKyB1c2VyKTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgcGFzc3dkICA6IiArIHBhc3N3ZCk7Ci0gICAgICB9Ci0KLQotICAgICAgRGVmYXVsdENvbm5lY3Rpb25Qb29sIGRlZnBvb2wgPSBuZXcgRGVmYXVsdENvbm5lY3Rpb25Qb29sKCk7Ci0KLSAgICAgIGlmICgoREVCVUcpICYmIChkZWZwb29sID09IG51bGwpKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWxlZCB0byBDcmVhdGUgYSBEZWZhdWx0IENvbm5lY3Rpb24gUG9vbCIpOwotCi0gICAgICBkZWZwb29sLnNldERyaXZlcihkcml2ZXIpOwotICAgICAgZGVmcG9vbC5zZXRVUkwoZGJVUkwpOwotICAgICAgZGVmcG9vbC5zZXRQcm90b2NvbChwcm9wKTsKLQotICAgICAgLy8gT25seSBlbmFibGUgcG9vbGluZyBpbiB0aGUgZGVmYXVsdCBwb29sIGlmIHdlIGFyZSBleHBsaWNhdGx5Ci0gICAgICAvLyB0b2xkIHRvby4KLSAgICAgIGlmIChtX0RlZmF1bHRQb29saW5nRW5hYmxlZCkgZGVmcG9vbC5zZXRQb29sRW5hYmxlZCh0cnVlKTsKLQotICAgICAgbV9Qb29sTWdyLnJlZ2lzdGVyUG9vbChwb29sTmFtZSwgZGVmcG9vbCk7Ci0gICAgICBtX0Nvbm5lY3Rpb25Qb29sID0gZGVmcG9vbDsKLQotCi0gICAgfQotCi0gICAgbV9Jc0RlZmF1bHRQb29sID0gdHJ1ZTsKLQotICAgIC8vCi0gICAgLy8gTGV0J3MgdGVzdCB0byBzZWUgaWYgd2UgcmVhbGx5IGNhbiBjb25uZWN0Ci0gICAgLy8gSnVzdCByZW1lbWJlciB0byBnaXZlIGl0IGJhY2sgYWZ0ZXIgdGhlIHRlc3QuCi0gICAgLy8KLSAgICB0cnkKLSAgICB7Ci0gICAgICBjb24gPSBtX0Nvbm5lY3Rpb25Qb29sLmdldENvbm5lY3Rpb24oKTsKLSAgICB9Ci0gICAgY2F0Y2goU1FMRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgaWYgKGNvbiAhPSBudWxsKQotICAgICAgewotICAgICAgICBtX0Nvbm5lY3Rpb25Qb29sLnJlbGVhc2VDb25uZWN0aW9uT25FcnJvcihjb24pOwotICAgICAgICBjb24gPSBudWxsOwotICAgICAgfQotICAgICAgdGhyb3cgZTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIG1fQ29ubmVjdGlvblBvb2wucmVsZWFzZUNvbm5lY3Rpb24oY29uKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGEgcXVlcnkgc3RhdGVtZW50IGJ5IGluc3RhbnRpYXRpbmcgYW4KLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBxdWVyeVN0cmluZyB0aGUgU1FMIHF1ZXJ5LgotICAgKiBAcmV0dXJuIFhTdGF0ZW1lbnQgaW1wbGVtZW50cyBOb2RlSXRlcmF0b3IuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqIEBsaW5rIG9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YU3RhdGVtZW50IFhTdGF0ZW1lbnR9Ci0gICAqIG9iamVjdC4gVGhlIFhTdGF0ZW1lbnQgZXhlY3V0ZXMgdGhlIHF1ZXJ5LCBhbmQgdXNlcyB0aGUgcmVzdWx0IHNldAotICAgKiB0byBjcmVhdGUgYQotICAgKiBAbGluayBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuUm93U2V0IFJvd1NldH0sCi0gICAqIGEgcm93LXNldCBlbGVtZW50LgotICAgKi8KLSAgcHVibGljIERUTSBxdWVyeSggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIFN0cmluZyBxdWVyeVN0cmluZyApCi0gIHsKLSAgICBDb25uZWN0aW9uIGNvbiA9IG51bGw7Ci0gICAgU3RhdGVtZW50IHN0bXQgPSBudWxsOwotICAgIFJlc3VsdFNldCBycyA9IG51bGw7Ci0KLSAgICBEVE1NYW5hZ2VyRGVmYXVsdCBtZ3JEZWZhdWx0ID0gbnVsbDsKLSAgICBTUUxEb2N1bWVudCBkb2MgPSBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInF1ZXJ5KCkiKTsKLSAgICAgIGlmIChudWxsID09IG1fQ29ubmVjdGlvblBvb2wpCi0gICAgICB7Ci0gICAgICAgIC8vIEJ1aWxkIGFuIEVycm9yIERvY3VtZW50LCBOT1QgQ29ubmVjdGVkCi0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgY29uID0gbV9Db25uZWN0aW9uUG9vbC5nZXRDb25uZWN0aW9uKCk7Ci0gICAgICAgIHN0bXQgPSBjb24uY3JlYXRlU3RhdGVtZW50KCk7Ci0gICAgICAgIHJzID0gc3RtdC5leGVjdXRlUXVlcnkocXVlcnlTdHJpbmcpOwotICAgICAgfQotICAgICAgY2F0Y2goU1FMRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIFdlIGhhdmUgbm90IGNyZWF0ZWQgYSBkb2N1bWVudCB5ZXQsIHNvIGxldHMgY2xvc2UgdGhlCi0gICAgICAgIC8vIGNvbm5lY3Rpb24gb3Vyc2VsdmVzIHRoZW4gbGV0IHRoZSBwcm9jZXNzIGRlYWwgd2l0aCB0aGUKLSAgICAgICAgLy8gZXJyb3IuCi0gICAgICAgIC8vCi0gICAgICAgIHRyeSAgeyBpZiAobnVsbCAhPSBycykgcnMuY2xvc2UoKTsgfQotICAgICAgICBjYXRjaChFeGNlcHRpb24gZTEpIHt9Ci0gICAgICAgIHRyeSAgeyBpZiAobnVsbCAhPSBzdG10KSBzdG10LmNsb3NlKCk7IH0KLSAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGUxKSB7IH0KLSAgICAgICAgdHJ5ICB7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gY29uKSBtX0Nvbm5lY3Rpb25Qb29sLnJlbGVhc2VDb25uZWN0aW9uT25FcnJvcihjb24pOwotICAgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlMSkgeyB9Ci0KLSAgICAgICAgLy8gUmUgdGhyb3cgdGhlIGVycm9yIHNvIHRoZSBwcm9jZXNzIGNhbiBoYW5kbGUgdGhlIGVycm9yCi0gICAgICAgIC8vIG5vcm1hbGx5Ci0gICAgICAgIHRocm93IGU7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIuLmNyZWF0aW5nU1FMRG9jdW1lbnQiKTsKLQotICAgICAgRFRNTWFuYWdlciBtZ3IgPQotICAgICAgICAoKFhQYXRoQ29udGV4dC5YUGF0aEV4cHJlc3Npb25Db250ZXh0KWV4cHJDb250ZXh0KS5nZXREVE1NYW5hZ2VyKCk7Ci0gICAgICBtZ3JEZWZhdWx0ID0gKERUTU1hbmFnZXJEZWZhdWx0KSBtZ3I7Ci0gICAgICBpbnQgZHRtSWRlbnQgPSBtZ3JEZWZhdWx0LmdldEZpcnN0RnJlZURUTUlEKCk7Ci0KLSAgICAgIGRvYyA9Ci0gICAgICAgIG5ldyBTUUxEb2N1bWVudCgKLSAgICAgICAgICBtZ3IsIGR0bUlkZW50IDw8IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUyAsCi0gICAgICAgICAgbV9Db25uZWN0aW9uUG9vbCwgY29uLCBzdG10LCBycywgbV9Jc1N0cmVhbWluZ0VuYWJsZWQpOwotCi0gICAgICBpZiAobnVsbCAhPSBkb2MpCi0gICAgICB7Ci0gICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIuLnJldHVybmluZyBEb2N1bWVudCIpOwotCi0gICAgICAgIC8vIFJlZ2lzdGVyIG91ciBkb2N1bWVudAotICAgICAgICBtZ3JEZWZhdWx0LmFkZERUTShkb2MsIGR0bUlkZW50KTsKLQotICAgICAgICAvLyBhbHNvIGtlZXAgYSBsb2NhbCByZWZlcmVuY2UKLSAgICAgICAgbV9PcGVuU1FMRG9jdW1lbnRzLmFkZEVsZW1lbnQoZG9jKTsKLSAgICAgICAgcmV0dXJuIGRvYzsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKFNRTEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGlmICgoZG9jICE9IG51bGwpICYmIChtZ3JEZWZhdWx0ICE9IG51bGwpKQotICAgICAgewotICAgICAgICBkb2MuY2xvc2VPbkVycm9yKCk7Ci0gICAgICAgIG1nckRlZmF1bHQucmVsZWFzZShkb2MsIHRydWUpOwotICAgICAgfQotICAgICAgYnVpbGRFcnJvckRvY3VtZW50KGV4cHJDb250ZXh0LCBlKTsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgaWYgKChkb2MgIT0gbnVsbCkgJiYgKG1nckRlZmF1bHQgIT0gbnVsbCkpCi0gICAgICB7Ci0gICAgICAgIGRvYy5jbG9zZU9uRXJyb3IoKTsKLSAgICAgICAgbWdyRGVmYXVsdC5yZWxlYXNlKGRvYywgdHJ1ZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJleGNlcHRpb24gaW4gcXVlcnkoKSIpOwotICAgICAgYnVpbGRFcnJvckRvY3VtZW50KGV4cHJDb250ZXh0LCBlKTsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImxlYXZpbmcgcXVlcnkoKSIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGEgcGFyYW1ldGVyaXplZCBxdWVyeSBzdGF0ZW1lbnQgYnkgaW5zdGFudGlhdGluZyBhbgotICAgKiBAcGFyYW0gZXhwckNvbnRleHQKLSAgICogQHBhcmFtIHF1ZXJ5U3RyaW5nIHRoZSBTUUwgcXVlcnkuCi0gICAqIEByZXR1cm4gWFN0YXRlbWVudCBpbXBsZW1lbnRzIE5vZGVJdGVyYXRvci4KLSAgICogQHRocm93cyBTUUxFeGNlcHRpb24KLSAgICogQGxpbmsgb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsLlhTdGF0ZW1lbnQgWFN0YXRlbWVudH0KLSAgICogb2JqZWN0LiBUaGUgWFN0YXRlbWVudCBleGVjdXRlcyB0aGUgcXVlcnksIGFuZCB1c2VzIHRoZSByZXN1bHQgc2V0Ci0gICAqIHRvIGNyZWF0ZSBhCi0gICAqIEBsaW5rIG9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5Sb3dTZXQgUm93U2V0fSwKLSAgICogYSByb3ctc2V0IGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgRFRNIHBxdWVyeSggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIFN0cmluZyBxdWVyeVN0cmluZyApCi0gIHsKLSAgICBDb25uZWN0aW9uIGNvbiA9IG51bGw7Ci0gICAgUHJlcGFyZWRTdGF0ZW1lbnQgc3RtdCA9IG51bGw7Ci0gICAgUmVzdWx0U2V0IHJzID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGludCBpbmR4OwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgY29uID0gbV9Db25uZWN0aW9uUG9vbC5nZXRDb25uZWN0aW9uKCk7Ci0gICAgICAgIHN0bXQgPSBjb24ucHJlcGFyZVN0YXRlbWVudChxdWVyeVN0cmluZyk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChTUUxFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgLy8gV2UgaGF2ZSBub3QgY3JlYXRlZCBhIGRvY3VtZW50IHlldCwgc28gbGV0cyBjbG9zZSB0aGUKLSAgICAgICAgLy8gY29ubmVjdGlvbiBvdXJzZWx2ZXMgdGhlbiBsZXQgdGhlIHByb2Nlc3MgZGVhbCB3aXRoIHRoZQotICAgICAgICAvLyBlcnJvci4KLSAgICAgICAgLy8KLSAgICAgICAgdHJ5IHsgaWYgKG51bGwgIT0gc3RtdCkgc3RtdC5jbG9zZSgpOyB9Ci0gICAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlMSkgeyB9Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gY29uKSBtX0Nvbm5lY3Rpb25Qb29sLnJlbGVhc2VDb25uZWN0aW9uT25FcnJvcihjb24pOwotICAgICAgICB9ICBjYXRjaChFeGNlcHRpb24gZTEpIHt9Ci0KLSAgICAgICAgLy8gUmUgdGhyb3cgdGhlIGVycm9yIHNvIHRoZSBwcm9jZXNzIGNhbiBoYW5kbGUgdGhlIGVycm9yCi0gICAgICAgIC8vIG5vcm1hbGx5Ci0gICAgICAgIHRocm93IGU7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIuLmJ1aWxkaW5nIFByZXBhcmVkIFN0YXRlbWVudCIpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgRW51bWVyYXRpb24gZW51bSA9IG1fUGFyYW1ldGVyTGlzdC5lbGVtZW50cygpOwotICAgICAgICBpbmR4ID0gMTsKLSAgICAgICAgd2hpbGUgKGVudW0uaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBRdWVyeVBhcmFtZXRlciBxcCA9IChRdWVyeVBhcmFtZXRlcikgZW51bS5uZXh0RWxlbWVudCgpOwotICAgICAgICAgIHNldFBhcmFtZXRlcihpbmR4LCBzdG10LCBxcCk7Ci0gICAgICAgICAgaW5keCsrOwotICAgICAgICB9Ci0KLSAgICAgICAgcnMgPSBzdG10LmV4ZWN1dGVRdWVyeSgpOwotICAgICAgfQotICAgICAgY2F0Y2goU1FMRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIFdlIGhhdmUgbm90IGNyZWF0ZWQgYSBkb2N1bWVudCB5ZXQsIHNvIGxldHMgY2xvc2UgdGhlCi0gICAgICAgIC8vIGNvbm5lY3Rpb24gb3Vyc2VsdmVzIHRoZW4gbGV0IHRoZSBwcm9jZXNzIGRlYWwgd2l0aCB0aGUKLSAgICAgICAgLy8gZXJyb3IuCi0gICAgICAgIC8vCi0gICAgICAgIHRyeSB7IGlmIChudWxsICE9IHJzKSBycy5jbG9zZSgpOyAgfQotICAgICAgICBjYXRjaChFeGNlcHRpb24gZTEpIHsgIH0KLSAgICAgICAgdHJ5IHsgaWYgKG51bGwgIT0gc3RtdCkgc3RtdC5jbG9zZSgpOyB9Ci0gICAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlMSkgeyAgfQotICAgICAgICB0cnkgIHsKLSAgICAgICAgICBpZiAobnVsbCAhPSBjb24pIG1fQ29ubmVjdGlvblBvb2wucmVsZWFzZUNvbm5lY3Rpb25PbkVycm9yKGNvbik7Ci0gICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUxKSB7IH0KLQotICAgICAgICAvLyBSZSB0aHJvdyB0aGUgZXJyb3Igc28gdGhlIHByb2Nlc3MgY2FuIGhhbmRsZSB0aGUgZXJyb3IKLSAgICAgICAgLy8gbm9ybWFsbHkKLSAgICAgICAgdGhyb3cgZTsKLSAgICAgIH0KLQotICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi4uY3JlYXRpbmdTUUxEb2N1bWVudCIpOwotCi0gICAgICBEVE1NYW5hZ2VyIG1nciA9Ci0gICAgICAgICgoWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQpZXhwckNvbnRleHQpLmdldERUTU1hbmFnZXIoKTsKLSAgICAgIERUTU1hbmFnZXJEZWZhdWx0IG1nckRlZmF1bHQgPSAoRFRNTWFuYWdlckRlZmF1bHQpIG1ncjsKLSAgICAgIGludCBkdG1JZGVudCA9IG1nckRlZmF1bHQuZ2V0Rmlyc3RGcmVlRFRNSUQoKTsKLQotICAgICAgU1FMRG9jdW1lbnQgZG9jID0KLSAgICAgICAgbmV3IFNRTERvY3VtZW50KG1nciwgZHRtSWRlbnQgPDwgRFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTLAotICAgICAgICBtX0Nvbm5lY3Rpb25Qb29sLCBjb24sIHN0bXQsIHJzLCBtX0lzU3RyZWFtaW5nRW5hYmxlZCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGRvYykKLSAgICAgIHsKLSAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi4ucmV0dXJuaW5nIERvY3VtZW50Iik7Ci0KLSAgICAgICAgLy8gUmVnaXN0ZXIgb3VyIGRvY3VtZW50Ci0gICAgICAgIG1nckRlZmF1bHQuYWRkRFRNKGRvYywgZHRtSWRlbnQpOwotCi0gICAgICAgIC8vIGFsc28ga2VlcCBhIGxvY2FsIHJlZmVyZW5jZQotICAgICAgICBtX09wZW5TUUxEb2N1bWVudHMuYWRkRWxlbWVudChkb2MpOwotICAgICAgICByZXR1cm4gZG9jOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICAvLyBCdWlsZCBFcnJvciBEb2MsIEJBRCBSZXN1bHQgU2V0Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChTUUxFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBidWlsZEVycm9yRG9jdW1lbnQoZXhwckNvbnRleHQsIGUpOwotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBidWlsZEVycm9yRG9jdW1lbnQoZXhwckNvbnRleHQsIGUpOwotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhIHBhcmFtZXRlcml6ZWQgcXVlcnkgc3RhdGVtZW50IGJ5IGluc3RhbnRpYXRpbmcgYW4KLSAgICogQHBhcmFtIGV4cHJDb250ZXh0Ci0gICAqIEBwYXJhbSBxdWVyeVN0cmluZyB0aGUgU1FMIHF1ZXJ5LgotICAgKiBAcGFyYW0gdHlwZUluZm8KLSAgICogQHJldHVybiBYU3RhdGVtZW50IGltcGxlbWVudHMgTm9kZUl0ZXJhdG9yLgotICAgKiBAdGhyb3dzIFNRTEV4Y2VwdGlvbgotICAgKiBAbGluayBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWFN0YXRlbWVudCBYU3RhdGVtZW50fQotICAgKiBvYmplY3QuIFRoZSBYU3RhdGVtZW50IGV4ZWN1dGVzIHRoZSBxdWVyeSwgYW5kIHVzZXMgdGhlIHJlc3VsdCBzZXQKLSAgICogdG8gY3JlYXRlIGEKLSAgICogQGxpbmsgb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsLlJvd1NldCBSb3dTZXR9LAotICAgKiBhIHJvdy1zZXQgZWxlbWVudC4KLSAgICogVGhpcyBtZXRob2QgYWxsb3dzIGZvciB0aGUgdXNlciB0byBwYXNzIGluIGEgY29tbWEgc2VwZXJhdGVkCi0gICAqIFN0cmluZyB0aGF0IHJlcHJlc2VudHMgYSBsaXN0IG9mIHBhcmFtZXRlciB0eXBlcy4gSWYgc3VwcGxpZWQKLSAgICogdGhlIHBhcmFtZXRlciB0eXBlcyB3aWxsIGJlIHVzZWQgdG8gb3ZlcmxvYWQgdGhlIGN1cnJlbnQgdHlwZXMKLSAgICogaW4gdGhlIGN1cnJlbnQgcGFyYW1ldGVyIGxpc3QuCi0gICAqLwotICBwdWJsaWMgRFRNIHBxdWVyeSggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIFN0cmluZyBxdWVyeVN0cmluZywgU3RyaW5nIHR5cGVJbmZvICkKLSAgewotICAgIENvbm5lY3Rpb24gY29uID0gbnVsbDsKLSAgICBQcmVwYXJlZFN0YXRlbWVudCBzdG10ID0gbnVsbDsKLSAgICBSZXN1bHRTZXQgcnMgPSBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaW50IGluZHg7Ci0KLSAgICAgIC8vIFBhcnNlIHVwIHRoZSBwYXJhbWV0ZXIgdHlwZXMgdGhhdCB3ZXJlIGRlZmluZWQKLSAgICAgIC8vIHdpdGggdGhlIHF1ZXJ5Ci0gICAgICBTdHJpbmdUb2tlbml6ZXIgcGxpc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHR5cGVJbmZvKTsKLQotICAgICAgLy8gT3ZlcnJpZGUgdGhlIGV4aXN0aW5nIHR5cGUgdGhhdCBpcyBzdG9yZWQgaW4gdGhlCi0gICAgICAvLyBwYXJhbWV0ZXIgbGlzdC4gSWYgdGhlcmUgYXJlIG1vcmUgdHlwZXMgdGhhbiBwYXJhbWV0ZXJzCi0gICAgICAvLyBpZ25vcmUgZm9yIG5vdywgYSBtb3JlIG1lYW5pbmdmdWxsIGVycm9yIHNob3VsZCBvY2N1cgotICAgICAgLy8gd2hlbiB0aGUgYWN0dWFsIHF1ZXJ5IGlzIGV4ZWN1dGVkLgotICAgICAgaW5keCA9IDA7Ci0gICAgICB3aGlsZSAocGxpc3QuaGFzTW9yZVRva2VucygpKQotICAgICAgewotICAgICAgICBTdHJpbmcgdmFsdWUgPSBwbGlzdC5uZXh0VG9rZW4oKTsKLSAgICAgICAgUXVlcnlQYXJhbWV0ZXIgcXAgPSAoUXVlcnlQYXJhbWV0ZXIpIG1fUGFyYW1ldGVyTGlzdC5lbGVtZW50QXQoaW5keCk7Ci0gICAgICAgIGlmICggbnVsbCAhPSBxcCApCi0gICAgICAgIHsKLSAgICAgICAgICBxcC5zZXRUeXBlKHZhbHVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZHgrKzsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGNvbiA9IG1fQ29ubmVjdGlvblBvb2wuZ2V0Q29ubmVjdGlvbigpOwotICAgICAgICBzdG10ID0gY29uLnByZXBhcmVTdGF0ZW1lbnQocXVlcnlTdHJpbmcpOwotICAgICAgfQotICAgICAgY2F0Y2goU1FMRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIFdlIGhhdmUgbm90IGNyZWF0ZWQgYSBkb2N1bWVudCB5ZXQsIHNvIGxldHMgY2xvc2UgdGhlCi0gICAgICAgIC8vIGNvbm5lY3Rpb24gb3Vyc2VsdmVzIHRoZW4gbGV0IHRoZSBwcm9jZXNzIGRlYWwgd2l0aCB0aGUKLSAgICAgICAgLy8gZXJyb3IuCi0gICAgICAgIC8vCi0gICAgICAgIHRyeSB7IGlmIChudWxsICE9IHN0bXQpIHN0bXQuY2xvc2UoKTsgfQotICAgICAgICBjYXRjaChFeGNlcHRpb24gZTEpIHsgfQotICAgICAgICB0cnkgewotICAgICAgICAgIGlmIChudWxsICE9IGNvbikgbV9Db25uZWN0aW9uUG9vbC5yZWxlYXNlQ29ubmVjdGlvbk9uRXJyb3IoY29uKTsKLSAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZTEpIHsgfQotCi0gICAgICAgIC8vIFJlIHRocm93IHRoZSBlcnJvciBzbyB0aGUgcHJvY2VzcyBjYW4gaGFuZGxlIHRoZSBlcnJvcgotICAgICAgICAvLyBub3JtYWxseQotICAgICAgICB0aHJvdyBlOwotICAgICAgfQotCi0KLQotICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi4uYnVpbGRpbmcgUHJlcGFyZWQgU3RhdGVtZW50Iik7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBFbnVtZXJhdGlvbiBlbnVtID0gbV9QYXJhbWV0ZXJMaXN0LmVsZW1lbnRzKCk7Ci0gICAgICAgIGluZHggPSAxOwotICAgICAgICB3aGlsZSAoZW51bS5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgewotICAgICAgICAgIFF1ZXJ5UGFyYW1ldGVyIHFwID0gKFF1ZXJ5UGFyYW1ldGVyKSBlbnVtLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgc2V0UGFyYW1ldGVyKGluZHgsIHN0bXQsIHFwKTsKLSAgICAgICAgICBpbmR4Kys7Ci0gICAgICAgIH0KLQotICAgICAgICBycyA9IHN0bXQuZXhlY3V0ZVF1ZXJ5KCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChTUUxFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgLy8gV2UgaGF2ZSBub3QgY3JlYXRlZCBhIGRvY3VtZW50IHlldCwgc28gbGV0cyBjbG9zZSB0aGUKLSAgICAgICAgLy8gY29ubmVjdGlvbiBvdXJzZWx2ZXMgdGhlbiBsZXQgdGhlIHByb2Nlc3MgZGVhbCB3aXRoIHRoZQotICAgICAgICAvLyBlcnJvci4KLSAgICAgICAgLy8KLSAgICAgICAgdHJ5IHsgaWYgKG51bGwgIT0gcnMpIHJzLmNsb3NlKCk7IH0KLSAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGUxKSB7IC8qIEVtcHR5ICovIH0KLSAgICAgICAgdHJ5IHsgaWYgKG51bGwgIT0gc3RtdCkgc3RtdC5jbG9zZSgpOyB9Ci0gICAgICAgIGNhdGNoKEV4Y2VwdGlvbiBlMSkgeyAvKiBFbXB0eSAqLyAgfQotICAgICAgICB0cnkgewotICAgICAgICAgIGlmIChudWxsICE9IGNvbikgbV9Db25uZWN0aW9uUG9vbC5yZWxlYXNlQ29ubmVjdGlvbk9uRXJyb3IoY29uKTsKLSAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZTEpIHsgLyogRW1wdHkgKi8gfQotCi0gICAgICAgIC8vIFJlIHRocm93IHRoZSBlcnJvciBzbyB0aGUgcHJvY2VzcyBjYW4gaGFuZGxlIHRoZSBlcnJvcgotICAgICAgICAvLyBub3JtYWxseQotICAgICAgICB0aHJvdyBlOwotICAgICAgfQotCi0KLSAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIuLmNyZWF0aW5nU1FMRG9jdW1lbnQiKTsKLQotICAgICAgRFRNTWFuYWdlciBtZ3IgPQotICAgICAgICAoKFhQYXRoQ29udGV4dC5YUGF0aEV4cHJlc3Npb25Db250ZXh0KWV4cHJDb250ZXh0KS5nZXREVE1NYW5hZ2VyKCk7Ci0gICAgICBEVE1NYW5hZ2VyRGVmYXVsdCBtZ3JEZWZhdWx0ID0gKERUTU1hbmFnZXJEZWZhdWx0KSBtZ3I7Ci0gICAgICBpbnQgZHRtSWRlbnQgPSBtZ3JEZWZhdWx0LmdldEZpcnN0RnJlZURUTUlEKCk7Ci0KLSAgICAgIFNRTERvY3VtZW50IGRvYyA9Ci0gICAgICAgIG5ldyBTUUxEb2N1bWVudChtZ3IsIGR0bUlkZW50IDw8IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUyAsCi0gICAgICAgIG1fQ29ubmVjdGlvblBvb2wsIGNvbiwgc3RtdCwgcnMsIG1fSXNTdHJlYW1pbmdFbmFibGVkKTsKLQotICAgICAgaWYgKG51bGwgIT0gZG9jKQotICAgICAgewotICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiLi5yZXR1cm5pbmcgRG9jdW1lbnQiKTsKLQotICAgICAgICAvLyBSZWdpc3RlciBvdXIgZG9jdW1lbnQKLSAgICAgICAgbWdyRGVmYXVsdC5hZGREVE0oZG9jLCBkdG1JZGVudCk7Ci0KLSAgICAgICAgLy8gYWxzbyBrZWVwIGEgbG9jYWwgcmVmZXJlbmNlCi0gICAgICAgIG1fT3BlblNRTERvY3VtZW50cy5hZGRFbGVtZW50KGRvYyk7Ci0gICAgICAgIHJldHVybiBkb2M7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIEJ1aWxkIEVycm9yIERvYywgQkFEIFJlc3VsdCBTZXQKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKFNRTEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGJ1aWxkRXJyb3JEb2N1bWVudChleHByQ29udGV4dCwgZSk7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGFuIHVudHlwZWQgdmFsdWUgdG8gdGhlIHBhcmFtZXRlciBsaXN0LgotICAgKiBAcGFyYW0gdmFsdWUKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkUGFyYW1ldGVyKCBTdHJpbmcgdmFsdWUgKQotICB7Ci0gICAgYWRkUGFyYW1ldGVyV2l0aFR5cGUodmFsdWUsIG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIHR5cGVkIHBhcmFtZXRlciB0byB0aGUgcGFyYW1ldGVyIGxpc3QuCi0gICAqIEBwYXJhbSB2YWx1ZQotICAgKiBAcGFyYW0gVHlwZQotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRQYXJhbWV0ZXJXaXRoVHlwZSggU3RyaW5nIHZhbHVlLCBTdHJpbmcgVHlwZSApCi0gIHsKLSAgICBtX1BhcmFtZXRlckxpc3QuYWRkRWxlbWVudCggbmV3IFF1ZXJ5UGFyYW1ldGVyKHZhbHVlLCBUeXBlKSApOwotICB9Ci0KLQotICAvKioKLSAgICogQWRkIGEgc2luZ2xlIHBhcmFtZXRlciB0byB0aGUgcGFyYW1ldGVyIGxpc3QKLSAgICogZm9ybWF0dGVkIGFzIGFuIEVsZW1lbnQKLSAgICogQHBhcmFtIGUKLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkUGFyYW1ldGVyRnJvbUVsZW1lbnQoIEVsZW1lbnQgZSApCi0gIHsKLSAgICBOYW1lZE5vZGVNYXAgYXR0cnMgPSBlLmdldEF0dHJpYnV0ZXMoKTsKLSAgICBOb2RlIFR5cGUgPSBhdHRycy5nZXROYW1lZEl0ZW0oInR5cGUiKTsKLSAgICBOb2RlIG4xICA9IGUuZ2V0Rmlyc3RDaGlsZCgpOwotICAgIGlmIChudWxsICE9IG4xKQotICAgIHsKLSAgICAgIFN0cmluZyB2YWx1ZSA9IG4xLmdldE5vZGVWYWx1ZSgpOwotICAgICAgaWYgKHZhbHVlID09IG51bGwpIHZhbHVlID0gIiI7Ci0gICAgICBtX1BhcmFtZXRlckxpc3QuYWRkRWxlbWVudCggbmV3IFF1ZXJ5UGFyYW1ldGVyKHZhbHVlLCBUeXBlLmdldE5vZGVWYWx1ZSgpKSApOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEFkZCBhIHNlY3Rpb24gb2YgcGFyYW1ldGVycyB0byB0aGUgUGFyYW1ldGVyIExpc3QKLSAgICogRG8gZWFjaCBlbGVtZW50IGZyb20gdGhlIGxpc3QKLSAgICogQHBhcmFtIG5sCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZFBhcmFtZXRlckZyb21FbGVtZW50KCBOb2RlTGlzdCBubCApCi0gIHsKLSAgICAvLwotICAgIC8vIEVhY2ggY2hpbGQgb2YgdGhlIE5vZGVMaXN0IHJlcHJlc2VudHMgYSBub2RlCi0gICAgLy8gbWF0Y2ggZnJvbSB0aGUgc2VsZWN0PSBzdGF0bWVudC4gUHJvY2VzcyBlYWNoCi0gICAgLy8gb2YgdGhlbSBhcyBhIHNlcGVyYXRlIGxpc3QuCi0gICAgLy8gVGhlIFhNTCBGb3JtYXQgaXMgYXMgZm9sbG93cwotICAgIC8vCi0gICAgLy8gPFNUQVJULVRBRz4KLSAgICAvLyAgIDxUQUcxIHR5cGU9ImludCI+dmFsdWU8L1RBRzE+Ci0gICAgLy8gICA8VEFHQSB0eXBlPSJpbnQiPnZhbHVlPC9UQUdBPgotICAgIC8vICAgPFRBRzIgdHlwZT0ic3RyaW5nIj52YWx1ZTwvVEFHMj4KLSAgICAvLyA8L1NUQVJULVRBRz4KLSAgICAvLwotICAgIC8vIFRoZSBYU0wgdG8gcHJvY2VzcyB0aGlzIGlzIGZvcm1hdHRlZCBhcyBmb2xsb3dzCi0gICAgLy8gPHhzbDpwYXJhbSBuYW1lPSJwbGlzdCIgc2VsZWN0PSIvL1NUQVJULVRBRyIgLz4KLSAgICAvLyA8c3FsOmFkZFBhcmFtZXRlciggJHBsaXN0ICk7Ci0gICAgLy8KLSAgICBpbnQgY291bnQgPSBubC5nZXRMZW5ndGgoKTsKLSAgICBmb3IgKGludCB4PTA7IHg8Y291bnQ7IHgrKykKLSAgICB7Ci0gICAgICBhZGRQYXJhbWV0ZXJzKCAoRWxlbWVudCkgbmwuaXRlbSh4KSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBlbGVtCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBhZGRQYXJhbWV0ZXJzKCBFbGVtZW50IGVsZW0gKQotICB7Ci0gICAgLy8KLSAgICAvLyBQcm9jZXNzIGFsbCBvZiB0aGUgQ2hpbGQgRWxlbWVudHMKLSAgICAvLyBUaGUgZm9ybWF0IGlzIGFzIGZvbGxvd3MKLSAgICAvLwotICAgIC8vPFRBRyB0eXBlID0idHlwZWlkIj52YWx1ZTwvVEFHPgotICAgIC8vPFRBRzEgdHlwZSA9InR5cGVpZCI+dmFsdWU8L1RBRzE+Ci0gICAgLy88VEFHQSB0eXBlID0idHlwZWlkIj52YWx1ZTwvVEFHQT4KLSAgICAvLwotICAgIC8vIFRoZSBuYW1lIG9mIHRoZSBOb2RlIGlzIG5vdCBpbXBvcnRhbnQganVzdCBpcyB2YWx1ZQotICAgIC8vIGFuZCBpZiBpdCBjb250YWlucyBhIHR5cGUgYXR0cmlidXRlCi0KLSAgICBOb2RlIG4gPSBlbGVtLmdldEZpcnN0Q2hpbGQoKTsKLQotICAgIGlmIChudWxsID09IG4pIHJldHVybjsKLQotICAgIGRvCi0gICAgewotICAgICAgaWYgKG4uZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgTmFtZWROb2RlTWFwIGF0dHJzID0gbi5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgIE5vZGUgVHlwZSA9IGF0dHJzLmdldE5hbWVkSXRlbSgidHlwZSIpOwotICAgICAgICBTdHJpbmcgVHlwZVN0cjsKLQotICAgICAgICBpZiAoVHlwZSA9PSBudWxsKSBUeXBlU3RyID0gInN0cmluZyI7Ci0gICAgICAgIGVsc2UgVHlwZVN0ciA9IFR5cGUuZ2V0Tm9kZVZhbHVlKCk7Ci0KLSAgICAgICAgTm9kZSBuMSAgPSBuLmdldEZpcnN0Q2hpbGQoKTsKLSAgICAgICAgaWYgKG51bGwgIT0gbjEpCi0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBuMS5nZXROb2RlVmFsdWUoKTsKLSAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgdmFsdWUgPSAiIjsKLQotCi0gICAgICAgICAgbV9QYXJhbWV0ZXJMaXN0LmFkZEVsZW1lbnQoCi0gICAgICAgICAgICBuZXcgUXVlcnlQYXJhbWV0ZXIodmFsdWUsIFR5cGVTdHIpICk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9IHdoaWxlICggKG4gPSBuLmdldE5leHRTaWJsaW5nKCkpICE9IG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsZWFyUGFyYW1ldGVycyggKQotICB7Ci0gICAgbV9QYXJhbWV0ZXJMaXN0LnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggc29tZSBKREJDIGRyaXZlcnMgd2hlbiBhIENvbm5lY3Rpb24KLSAgICogaXMgb3BlbiBhbmQgdGhlIEpWTSBzaHV0c2Rvd24uIElmIHRoZXJlIGlzIGEgcHJvYmxlbSwgdGhlcmUKLSAgICogaXMgbm8gd2F5IHRvIGNvbnRyb2wgdGhlIGN1cnJlbnRseSBvcGVuIGNvbm5lY3Rpb25zIGluIHRoZQotICAgKiBwb29sLiBTbyBmb3IgdGhlIGRlZmF1bHQgY29ubmVjdGlvbiBwb29sLCB0aGUgYWN0dWFsbCBwb29saW5nCi0gICAqIG1lY2hpbnNtIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQuIFRoZSBTdHlsZXNoZWV0IGRlc2lnbmVyIGNhbgotICAgKiByZS1lbmFibGVkIHBvb2xpbmcgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgY29ubmVjdGlvbiBwb29scy4KLSAgICogVGhlIGNvbm5lY3Rpb24gcG9vbCBjYW4gZXZlbiBiZSBkaXNhYmxlZCB3aGljaCB3aWxsIGNsb3NlIGFsbAotICAgKiBvdXRzdGFuZGluZyBjb25uZWN0aW9ucy4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5hYmxlRGVmYXVsdENvbm5lY3Rpb25Qb29sKCApCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRW5hYmxpbmcgRGVmYXVsdCBDb25uZWN0aW9uIFBvb2wiKTsKLQotICAgIG1fRGVmYXVsdFBvb2xpbmdFbmFibGVkID0gdHJ1ZTsKLQotICAgIGlmIChtX0Nvbm5lY3Rpb25Qb29sID09IG51bGwpIHJldHVybjsKLSAgICBpZiAobV9Jc0RlZmF1bHRQb29sKSByZXR1cm47Ci0KLSAgICBtX0Nvbm5lY3Rpb25Qb29sLnNldFBvb2xFbmFibGVkKHRydWUpOwotCi0gIH0KLQotICAvKioKLSAgICogU2VlIGVuYWJsZURlZmF1bHRDb25uZWN0aW9uUG9vbAotICAgKiBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNhYmxlRGVmYXVsdENvbm5lY3Rpb25Qb29sKCApCi0gIHsKLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRpc2FibGluZyBEZWZhdWx0IENvbm5lY3Rpb24gUG9vbCIpOwotCi0gICAgbV9EZWZhdWx0UG9vbGluZ0VuYWJsZWQgPSBmYWxzZTsKLQotICAgIGlmIChtX0Nvbm5lY3Rpb25Qb29sID09IG51bGwpIHJldHVybjsKLSAgICBpZiAoIW1fSXNEZWZhdWx0UG9vbCkgcmV0dXJuOwotCi0gICAgbV9Db25uZWN0aW9uUG9vbC5zZXRQb29sRW5hYmxlZChmYWxzZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDb250cm9sIGhvdyB0aGUgU1FMIERvY3VtZW50IHVzZXMgbWVtb3J5LiBJbiBTdHJlYW1pbmcgTW9kZSwKLSAgICogbWVtb3J5IGNvbnN1bXB0aW9uIGlzIGdyZWF0bHkgcmVkdWNlcyBzbyB5b3UgY2FuIGhhdmUgcXVlcmllcwotICAgKiBvZiB1bmxpbWl0ZWQgc2l6ZSBidXQgaXQgd2lsbCBub3QgbGV0IHlvdSB0cmF2ZXJzZSB0aGUgZGF0YQotICAgKiBtb3JlIHRoYW4gb25jZS4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5hYmxlU3RyZWFtaW5nTW9kZSggKQotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVuYWJsaW5nIFN0cmVhbWluZyBNb2RlIik7Ci0KLSAgICBtX0lzU3RyZWFtaW5nRW5hYmxlZCA9IHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogQ29udHJvbCBob3cgdGhlIFNRTCBEb2N1bWVudCB1c2VzIG1lbW9yeS4gSW4gU3RyZWFtaW5nIE1vZGUsCi0gICAqIG1lbW9yeSBjb25zdW1wdGlvbiBpcyBncmVhdGx5IHJlZHVjZXMgc28geW91IGNhbiBoYXZlIHF1ZXJpZXMKLSAgICogb2YgdW5saW1pdGVkIHNpemUgYnV0IGl0IHdpbGwgbm90IGxldCB5b3UgdHJhdmVyc2UgdGhlIGRhdGEKLSAgICogbW9yZSB0aGFuIG9uY2UuCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc2FibGVTdHJlYW1pbmdNb2RlKCApCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRGlzYWJsZSBTdHJlYW1pbmcgTW9kZSIpOwotCi0gICAgbV9Jc1N0cmVhbWluZ0VuYWJsZWQgPSBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm92aWRlIGFjY2VzcyB0byB0aGUgbGFzdCBlcnJvciB0aGF0IG9jY3VlZC4gVGhpcyBlcnJvcgotICAgKiBtYXkgYmUgb3ZlciB3cml0dGVuIHdoZW4gdGhlIG5leHQgb3BlcmF0aW9uIG9jY3Vycy4KLSAgICogQHJldHVybgotICAgKi8KLSAgcHVibGljIERUTSBnZXRFcnJvciggKQotICB7Ci0gICAgcmV0dXJuIG1fRXJyb3I7Ci0gIH0KLQotICAvKioKLSAgICogQ2xvc2UgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGEgc291cmNlLgotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSggKXRocm93cyBTUUxFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFbnRlcmluZyBYQ29ubmVjdGlvbi5jbG9zZSIpOwotCi0gICAgLy8KLSAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGluY2x1ZGVkIGp1c3QgZm9yIExlZ2FjeSBzdXBwb3J0Ci0gICAgLy8gSWYgaXQgaXMgcmVhbGx5IGNhbGxlZCB0aGVuIHdlIG11c3QgbWUgdXNpbmcgYSBzaW5nbGUKLSAgICAvLyBkb2N1bWVudCBpbnRlcmZhY2UsIHNvIGNsb3NlIGFsbCBvcGVuIGRvY3VtZW50cy4KLSAgICB3aGlsZShtX09wZW5TUUxEb2N1bWVudHMuc2l6ZSgpICE9IDApCi0gICAgewotICAgICAgU1FMRG9jdW1lbnQgZCA9IChTUUxEb2N1bWVudCkgbV9PcGVuU1FMRG9jdW1lbnRzLmVsZW1lbnRBdCgwKTsKLSAgICAgIGQuY2xvc2UoKTsKLSAgICAgIG1fT3BlblNRTERvY3VtZW50cy5yZW1vdmVFbGVtZW50QXQoMCk7Ci0gICAgfQotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGl0aW5nIFhDb25uZWN0aW9uLmNsb3NlIik7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBDbG9zZSB0aGUgY29ubmVjdGlvbiB0byB0aGUgZGF0YSBzb3VyY2UuIE9ubHkgY2xvc2UgdGhlIGNvbm5lY3Rpb25zCi0gICAqIGZvciBhIHNpbmdsZSBkb2N1bWVudC4KLSAgICogQHBhcmFtIHNxbGRvYwotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSggU1FMRG9jdW1lbnQgc3FsZG9jICl0aHJvd3MgU1FMRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVudGVyaW5nIFhDb25uZWN0aW9uLmNsb3NlIik7Ci0KLSAgICBpbnQgc2l6ZSA9IG1fT3BlblNRTERvY3VtZW50cy5zaXplKCk7Ci0KLSAgICBmb3IoaW50IHg9MDsgeDxzaXplOyB4KyspCi0gICAgewotICAgICAgU1FMRG9jdW1lbnQgZCA9IChTUUxEb2N1bWVudCkgbV9PcGVuU1FMRG9jdW1lbnRzLmVsZW1lbnRBdCh4KTsKLSAgICAgIGlmIChkID09IHNxbGRvYykKLSAgICAgIHsKLSAgICAgICAgZC5jbG9zZSgpOwotICAgICAgICBtX09wZW5TUUxEb2N1bWVudHMucmVtb3ZlRWxlbWVudEF0KHgpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHBhcmFtZXRlciBmb3IgYSBQcmVwYXJlZCBTdGF0ZW1lbnQKLSAgICogQHBhcmFtIHBvcwotICAgKiBAcGFyYW0gc3RtdAotICAgKiBAcGFyYW0gcAotICAgKiBAcmV0dXJuCi0gICAqIEB0aHJvd3MgU1FMRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoIGludCBwb3MsIFByZXBhcmVkU3RhdGVtZW50IHN0bXQsIFF1ZXJ5UGFyYW1ldGVyIHAgKXRocm93cyBTUUxFeGNlcHRpb24KLSAgewotICAgIFN0cmluZyB0eXBlID0gcC5nZXRUeXBlKCk7Ci0gICAgaWYgKHR5cGUuZXF1YWxzSWdub3JlQ2FzZSgic3RyaW5nIikpCi0gICAgewotICAgICAgc3RtdC5zZXRTdHJpbmcocG9zLCBwLmdldFZhbHVlKCkpOwotICAgIH0KLQotICAgIGlmICh0eXBlLmVxdWFsc0lnbm9yZUNhc2UoImJpZ2RlY2ltYWwiKSkKLSAgICB7Ci0gICAgICBzdG10LnNldEJpZ0RlY2ltYWwocG9zLCBuZXcgQmlnRGVjaW1hbChwLmdldFZhbHVlKCkpKTsKLSAgICB9Ci0KLSAgICBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJib29sZWFuIikpCi0gICAgewotICAgICAgSW50ZWdlciBpID0gbmV3IEludGVnZXIoIHAuZ2V0VmFsdWUoKSApOwotICAgICAgYm9vbGVhbiBiID0gKChpLmludFZhbHVlKCkgIT0gMCkgPyBmYWxzZSA6IHRydWUpOwotICAgICAgc3RtdC5zZXRCb29sZWFuKHBvcywgYik7Ci0gICAgfQotCi0gICAgaWYgKHR5cGUuZXF1YWxzSWdub3JlQ2FzZSgiYnl0ZXMiKSkKLSAgICB7Ci0gICAgICBzdG10LnNldEJ5dGVzKHBvcywgcC5nZXRWYWx1ZSgpLmdldEJ5dGVzKCkpOwotICAgIH0KLQotICAgIGlmICh0eXBlLmVxdWFsc0lnbm9yZUNhc2UoImRhdGUiKSkKLSAgICB7Ci0gICAgICBzdG10LnNldERhdGUocG9zLCBEYXRlLnZhbHVlT2YocC5nZXRWYWx1ZSgpKSk7Ci0gICAgfQotCi0gICAgaWYgKHR5cGUuZXF1YWxzSWdub3JlQ2FzZSgiZG91YmxlIikpCi0gICAgewotICAgICAgRG91YmxlIGQgPSBuZXcgRG91YmxlKHAuZ2V0VmFsdWUoKSk7Ci0gICAgICBzdG10LnNldERvdWJsZShwb3MsIGQuZG91YmxlVmFsdWUoKSApOwotICAgIH0KLQotICAgIGlmICh0eXBlLmVxdWFsc0lnbm9yZUNhc2UoImZsb2F0IikpCi0gICAgewotICAgICAgRmxvYXQgZiA9IG5ldyBGbG9hdChwLmdldFZhbHVlKCkpOwotICAgICAgc3RtdC5zZXRGbG9hdChwb3MsIGYuZmxvYXRWYWx1ZSgpKTsKLSAgICB9Ci0KLSAgICBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJsb25nIikpCi0gICAgewotICAgICAgTG9uZyBsID0gbmV3IExvbmcocC5nZXRWYWx1ZSgpKTsKLSAgICAgIHN0bXQuc2V0TG9uZyhwb3MsIGwubG9uZ1ZhbHVlKCkpOwotICAgIH0KLQotICAgIGlmICh0eXBlLmVxdWFsc0lnbm9yZUNhc2UoInNob3J0IikpCi0gICAgewotICAgICAgU2hvcnQgcyA9IG5ldyBTaG9ydChwLmdldFZhbHVlKCkpOwotICAgICAgc3RtdC5zZXRTaG9ydChwb3MsIHMuc2hvcnRWYWx1ZSgpKTsKLSAgICB9Ci0KLSAgICBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJ0aW1lIikpCi0gICAgewotICAgICAgc3RtdC5zZXRUaW1lKHBvcywgVGltZS52YWx1ZU9mKHAuZ2V0VmFsdWUoKSkgKTsKLSAgICB9Ci0KLSAgICBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJ0aW1lc3RhbXAiKSkKLSAgICB7Ci0KLSAgICAgIHN0bXQuc2V0VGltZXN0YW1wKHBvcywgVGltZXN0YW1wLnZhbHVlT2YocC5nZXRWYWx1ZSgpKSApOwotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBleHByQ29udGV4dAotICAgKiBAcGFyYW0gZXhjcAotICAgKiBAcmV0dXJuCi0gICAqLwotICBwcml2YXRlIHZvaWQgYnVpbGRFcnJvckRvY3VtZW50KCBFeHByZXNzaW9uQ29udGV4dCBleHByQ29udGV4dCwgU1FMRXhjZXB0aW9uIGV4Y3AgKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgRFRNTWFuYWdlciBtZ3IgPQotICAgICAgICAoKFhQYXRoQ29udGV4dC5YUGF0aEV4cHJlc3Npb25Db250ZXh0KWV4cHJDb250ZXh0KS5nZXREVE1NYW5hZ2VyKCk7Ci0gICAgICBEVE1NYW5hZ2VyRGVmYXVsdCBtZ3JEZWZhdWx0ID0gKERUTU1hbmFnZXJEZWZhdWx0KSBtZ3I7Ci0gICAgICBpbnQgZHRtSWRlbnQgPSBtZ3JEZWZhdWx0LmdldEZpcnN0RnJlZURUTUlEKCk7Ci0KLSAgICAgIG1fRXJyb3IgPSBuZXcgU1FMRXJyb3JEb2N1bWVudChtZ3IsIGR0bUlkZW50IDw8IERUTU1hbmFnZXIuSURFTlRfRFRNX05PREVfQklUUywgZXhjcCk7Ci0KLSAgICAgIC8vIFJlZ2lzdGVyIG91ciBkb2N1bWVudAotICAgICAgbWdyRGVmYXVsdC5hZGREVE0obV9FcnJvciwgZHRtSWRlbnQpOwotCi0gICAgfQotICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIG1fRXJyb3IgPSBudWxsOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBAcGFyYW0gZXhwckNvbnRleHQKLSAgICogQHBhcmFtIGV4Y3AKLSAgICogQHJldHVybgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGJ1aWxkRXJyb3JEb2N1bWVudCggRXhwcmVzc2lvbkNvbnRleHQgZXhwckNvbnRleHQsIEV4Y2VwdGlvbiBleGNwICkKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIERUTU1hbmFnZXIgbWdyID0KLSAgICAgICAgKChYUGF0aENvbnRleHQuWFBhdGhFeHByZXNzaW9uQ29udGV4dClleHByQ29udGV4dCkuZ2V0RFRNTWFuYWdlcigpOwotICAgICAgRFRNTWFuYWdlckRlZmF1bHQgbWdyRGVmYXVsdCA9IChEVE1NYW5hZ2VyRGVmYXVsdCkgbWdyOwotICAgICAgaW50IGR0bUlkZW50ID0gbWdyRGVmYXVsdC5nZXRGaXJzdEZyZWVEVE1JRCgpOwotCi0gICAgICBtX0Vycm9yID0gbmV3IFNRTEVycm9yRG9jdW1lbnQobWdyLCBkdG1JZGVudDw8RFRNTWFuYWdlci5JREVOVF9EVE1fTk9ERV9CSVRTLCBleGNwKTsKLQotICAgICAgLy8gUmVnaXN0ZXIgb3VyIGRvY3VtZW50Ci0gICAgICBtZ3JEZWZhdWx0LmFkZERUTShtX0Vycm9yLCBkdG1JZGVudCk7Ci0KLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgbV9FcnJvciA9IG51bGw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCApCi0gIHsKLSAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiSW4gWENvbm5lY3Rpb24sIGZpbmFsaXplIik7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgY2xvc2UoKTsKLSAgICB9Ci0gICAgY2F0Y2goRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gRW1wdHkgV2UgYXJlIGZpbmFsIEFueXdheQotICAgIH0KLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZDZjM2RlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsNzUgKzAsMCBAQAotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiBTUUwgRXh0ZW5zaW9uPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+PGVtPioqRXhwZXJpbWVudGFsKio8L2VtPiBQcm92aWRlcyBleHRlbnNpb24gZnVuY3Rpb25zIGZvciBjb25uZWN0aW5nIHRvIGEgSkRCQyBkYXRhIHNvdXJjZSwgZXhlY3V0aW5nIGEgcXVlcnksCi0gICAgYW5kIHdvcmtpbmcgaW5jcmVtZW50YWxseSB0aHJvdWdoICJzdHJlYW1hYmxlIiByZXN1bHQgc2V0LjxwPgotICAgPHA+PGVtPlRoZSBTUUwgZXh0ZW5zaW9uIHVzZSBvZiBhIHNpbmdsZSByb3ctc2V0IG5vZGUgdG8gaW5jcmVtZW50YWxseSByZXR1cm4gYSBxdWVyeSByZXN1bHQgc2V0IGlzIGV4cGVyaW1lbnRhbC4gS2VlcCBpbiBtaW5kIHRoYXQgeW91Ci0gICBjYW4gb25seSBhY2Nlc3Mgcm93IGVsZW1lbnRzIG9uZSBhdCBhIHRpbWUgbW92aW5nIGZvcndhcmQgdGhyb3VnaCB0aGUgcmVzdWx0IHNldC4gVGhlIHVzZSBvZiBYUGF0aCBleHByZXNzaW9ucyBpbiB5b3VyIHN0eWxlc2hlZXQsIGZvcgotICAgZXhhbXBsZSwgdGhhdCBhdHRlbXB0IHRvIHJldHVybiBub2RlcyBmcm9tIHRoZSByZXN1bHQgc2V0IGluIGFueSBvdGhlciBtYW5uZXIgbWF5IHByb2R1Y2UgdW5wcmVkaWN0YWJsZSByZXN1bHRzLjwvZW0+PC9wPiAgICAKLSAgICA8cD5YQ29ubmVjdGlvbiBwcm92aWRlcyB0aHJlZSBleHRlbnNpb24gZnVuY3Rpb25zIHRoYXQgeW91IGNhbiB1c2UgaW4geW91ciBzdHlsZXNoZWV0LjwvcD4KLSAgICA8b2w+Ci0gICAgICA8bGk+PHA+bmV3KCkgLS0gVXNlIG9uZSBvZiB0aGUgWENvbm5lY3Rpb24gY29uc3RydWN0b3JzIHRvIGNvbm5lY3QgdG8gYSBkYXRhIHNvdXJjZSwgYW5kIHJldHVybiBhbiBYQ29ubmVjdGlvbgotICAgICAgIG9iamVjdC48L3A+PC9saT4KLSAgICAgIDxsaT48cD5xdWVyeSgpIC0tIFVzZSB0aGUgWENvbm5lY3Rpb24gb2JqZWN0IHF1ZXJ5KCkgbWV0aG9kIHRvIHJldHVybiBhICJzdHJlYW1hYmxlIiByZXN1bHQgc2V0IGluIHRoZSBmb3JtIG9mIGEgcm93LXNldAotICAgICAgIG5vZGUuIFdvcmsgeW91ciB3YXkgdGhyb3VnaCB0aGUgcm93LXNldCBvbmUgcm93IGF0IGEgdGltZS4gVGhlIHNhbWUgcm93IGVsZW1lbnQgaXMgdXNlZCBvdmVyIGFuZCBvdmVyIGFnYWluLCBzbyB5b3UgY2FuCi0gICAgICAgYmVnaW4gInRyYW5zZm9ybWluZyIgdGhlIHJvdy1zZXQgYmVmb3JlIHRoZSBlbnRpcmUgcmVzdWx0IHNldCBoYXMgYmVlbiByZXR1cm5lZC48L3A+PC9saT4KLSAgICAgIDxsaT5jbG9zZSgpIC0tIFVzZSB0aGUgWENvbm5lY3Rpb24gb2JqZWN0IGNsb3NlKCkgbWV0aG9kIHRvIHRlcm1pbmF0ZSB0aGUgY29ubmVjdGlvbi48L2xpPiAgICAgIAotICAgIDwvb2w+Ci0gICAgPHA+VGhlIHF1ZXJ5KCkgZXh0ZW5zaW9uIGZ1bmN0aW9uIHJldHVybnMgYSBEb2N1bWVudCBub2RlIHRoYXQgY29udGFpbnMgKGFzIG5lZWRlZCkgYW4gYXJyYXkgb2YgY29sdW1uLWhlYWRlciBlbGVtZW50cywgCi0gICAgYSBzaW5nbGUgcm93IGVsZW1lbnQgdGhhdCBpcyB1c2VkIHJlcGVhdGVkbHksIGFuZCBhbiBhcnJheSBvZiBjb2wgZWxlbWVudHMuIEVhY2ggY29sdW1uLWhlYWRlciBlbGVtZW50IChvbmUgcGVyIGNvbHVtbiBpbiB0aGUKLSAgICByb3ctc2V0KSBjb250YWlucyBhbiBhdHRyaWJ1dGUgKENvbHVtbkF0dHJpYnV0ZSkgZm9yIGVhY2ggb2YgdGhlIGNvbHVtbiBkZXNjcmlwdG9ycyBpbiB0aGUgUmVzdWx0U2V0TWV0YURhdGEgb2JqZWN0LiAKLSAgICBFYWNoIGNvbCBlbGVtZW50IGNvbnRhaW5zIGEgdGV4dCBub2RlIHdpdGggYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBmb3IgdGhhdCBjb2x1bW4gaW4gdGhlIGN1cnJlbnQgcm93LjwvcD4KLSAgICA8aDI+RXhhbXBsZTwvaDI+Ci0gICAgPHA+VGhpcyBleGFtcGxlIGRpc3BsYXlzIHRoZSByZXN1bHQgc2V0IGZyb20gYSB0YWJsZSBpbiBhIHNhbXBsZSBJbnN0YW50REIgZGF0YWJhc2UuPC9wPgotPHByZT4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLSZsdDt4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB2ZXJzaW9uPSIxLjAiCi0gICAgICAgICAgICAgICAgeG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InNxbCImZ3Q7Ci0gICZsdDt4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLyZndDsKLSAgJmx0O3hzbDpwYXJhbSBuYW1lPSJxdWVyeSIgc2VsZWN0PSInU0VMRUNUICogRlJPTSBpbXBvcnQxJyIvJmd0OwotIAotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIiZndDsKLSAgICAmbHQ7IS0tIDEuIE1ha2UgdGhlIGNvbm5lY3Rpb24gLS0mZ3Q7Ci0gICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJwcm9kdWN0cyIKLSAgICAgICAgICAgICAgICAgIHNlbGVjdD0ic3FsOm5ldygnb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2pkYmM6aWRiOkQ6XGluc3RhbnRkYlxFeGFtcGxlc1xzYW1wbGUucHJwJykiLyZndDsKLSAgICAmbHQ7SFRNTCZndDsKLSAgICAgICZsdDtIRUFEJmd0OwotICAgICAgJmx0Oy9IRUFEJmd0OwotICAgICAgJmx0O0JPRFkmZ3Q7Ci0gICAgICAgICZsdDtUQUJMRSBib3JkZXI9IjEiJmd0OwotICAgICAgICAmbHQ7IS0tMi4gRXhlY3V0ZSB0aGUgcXVlcnkgLS0mZ3Q7Ci0gICAgICAgICZsdDt4c2w6dmFyaWFibGUgbmFtZT0idGFibGUiIHNlbGVjdD0nc3FsOnF1ZXJ5KCRwcm9kdWN0cywgJHF1ZXJ5KScvJmd0OwotICAgICAgICAgICZsdDtUUiZndDsKLSAgICAgICAgICAmbHQ7IS0tIEdldCBjb2x1bW4tbGFiZWwgYXR0cmlidXRlIGZyb20gZWFjaCBjb2x1bW4taGVhZGVyLS0mZ3Q7Ci0gICAgICAgICAgJmx0O3hzbDpmb3ItZWFjaCBzZWxlY3Q9IiR0YWJsZS9yb3ctc2V0L2NvbHVtbi1oZWFkZXIiJmd0OwotICAgICAgICAgICAgJmx0O1RIJmd0OyZsdDt4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAY29sdW1uLWxhYmVsIi8mZ3Q7Jmx0Oy9USCZndDsKLSAgICAgICAgICAmbHQ7L3hzbDpmb3ItZWFjaCZndDsKLSAgICAgICAgICAmbHQ7L1RSJmd0OwotICAgICAgICAgICZsdDt4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iJHRhYmxlL3Jvdy1zZXQvcm93Ii8mZ3Q7Ci0gICAgICAgICAgJmx0O3hzbDp0ZXh0Jmd0OyZhbXA7IzEwOyZsdDsveHNsOnRleHQmZ3Q7Ci0gICAgICAgICZsdDsvVEFCTEUmZ3Q7Ci0gICAgICAmbHQ7L0JPRFkmZ3Q7Ci0gICAgJmx0Oy9IVE1MJmd0OyAKLSAgICAmbHQ7IS0tIDMuIENsb3NlIHRoZSBjb25uZWN0aW9uIC0tJmd0OwotICAgICZsdDt4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzcWw6Y2xvc2UoJHByb2R1Y3RzKSIvJmd0OwotICAmbHQ7L3hzbDp0ZW1wbGF0ZSZndDsKLQotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSJyb3ciJmd0OwotICAgICAgICAmbHQ7VFImZ3Q7Ci0gICAgICAgICAgJmx0O3hzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJjb2wiLyZndDsKLSAgICAgICAgJmx0Oy9UUiZndDsKLSAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0KLSAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iY29sIiZndDsKLSAgICAmbHQ7VEQmZ3Q7Ci0gICAgICAmbHQ7IS0tIEhlcmUgaXMgdGhlIGNvbHVtbiBkYXRhIC0tPgotICAgICAgJmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9InRleHQoKSIvPgotICAgICZsdDsvVEQ+Ci0gICZsdDsveHNsOnRlbXBsYXRlPgotCi0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotPC9wcmU+ICAgIAotIDwvYm9keT4KLTwvaHRtbD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yQXR0cmlidXRlU2V0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yQXR0cmlidXRlU2V0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVhZDNhOWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckF0dHJpYnV0ZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUF0dHJpYnV0ZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcHJvY2Vzc2VzIHBhcnNlIGV2ZW50cyBmb3IgYW4geHNsOmF0dHJpYnV0ZS1zZXQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNhdHRyaWJ1dGUtc2V0cyI+YXR0cmlidXRlLXNldHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1jbGFzcyBQcm9jZXNzb3JBdHRyaWJ1dGVTZXQgZXh0ZW5kcyBYU0xURWxlbWVudFByb2Nlc3NvcgotewotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4geHNsOmF0dHJpYnV0ZS1zZXQgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGNhbGxpbmcgU3R5bGVzaGVldEhhbmRsZXIvVGVtcGxhdGVzQnVpbGRlci4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHJhdyBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgKiAgICAgICAgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMsIGl0IHNoYWxsIGJlIGFuIGVtcHR5Ci0gICAqICAgICAgICBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICogCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuU3R5bGVzaGVldEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudAotICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBFbGVtQXR0cmlidXRlU2V0IGVhdCA9IG5ldyBFbGVtQXR0cmlidXRlU2V0KCk7Ci0KLSAgICBlYXQuc2V0TG9jYXRlckluZm8oaGFuZGxlci5nZXRMb2NhdG9yKCkpOwotICAgIHRyeQotICAgIHsKLSAgICAgIGVhdC5zZXRQcmVmaXhlcyhoYW5kbGVyLmdldE5hbWVzcGFjZVN1cHBvcnQoKSk7Ci0gICAgfQotICAgIGNhdGNoKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgIH0KLQotICAgIGVhdC5zZXRET01CYWNrUG9pbnRlcihoYW5kbGVyLmdldE9yaWdpbmF0aW5nTm9kZSgpKTsKLSAgICBzZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoaGFuZGxlciwgcmF3TmFtZSwgYXR0cmlidXRlcywgZWF0KTsKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5zZXRBdHRyaWJ1dGVTZXQoZWF0KTsKLQotICAgIC8vIGhhbmRsZXIucHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQoZWF0KTsKLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHBhcmVudCA9IGhhbmRsZXIuZ2V0RWxlbVRlbXBsYXRlRWxlbWVudCgpOwotCi0gICAgcGFyZW50LmFwcGVuZENoaWxkKGVhdCk7Ci0gICAgaGFuZGxlci5wdXNoRWxlbVRlbXBsYXRlRWxlbWVudChlYXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaGFuZGxlci5wb3BFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JDaGFyYWN0ZXJzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yQ2hhcmFjdGVycy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1NTFmZGVjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JDaGFyYWN0ZXJzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBqYXZhLmxhbmcuU3RyaW5nQnVmZmVyOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRleHRMaXRlcmFsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBwcm9jZXNzZXMgY2hhcmFjdGVyIGV2ZW50cyBmb3IgYSBYU0xUIHRlbXBsYXRlIGVsZW1lbnQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNyZWF0aW5nLXRoZS1SZXN1bHQtVHJlZSI+c2VjdGlvbi1DcmVhdGluZy10aGUtUmVzdWx0LVRyZWUgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgUHJvY2Vzc29yQ2hhcmFjdGVycyBleHRlbmRzIFhTTFRFbGVtZW50UHJvY2Vzc29yCi17Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBzdGFydCBvZiB0aGUgbm9uLXRleHQgZXZlbnQuICBUaGlzCi0gICAqIGlzIHNlbnQgdG8gdGhlIGN1cnJlbnQgcHJvY2Vzc29yIHdoZW4gYW55IG5vbi10ZXh0IGV2ZW50IG9jY3Vycy4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0Tm9uVGV4dChTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAodGhpcyA9PSBoYW5kbGVyLmdldEN1cnJlbnRQcm9jZXNzb3IoKSkKLSAgICB7Ci0gICAgICBoYW5kbGVyLnBvcFByb2Nlc3NvcigpOwotICAgIH0KLQotICAgIGludCBuQ2hhcnMgPSBtX2FjY3VtdWxhdG9yLmxlbmd0aCgpOwotCi0gICAgaWYgKChuQ2hhcnMgPiAwKQotICAgICAgICAgICAgJiYgKChudWxsICE9IG1feHNsVGV4dEVsZW1lbnQpCi0gICAgICAgICAgICAgICAgfHwhWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UobV9hY2N1bXVsYXRvcikpIAotICAgICAgICAgICAgICAgIHx8IGhhbmRsZXIuaXNTcGFjZVByZXNlcnZlKCkpCi0gICAgewotICAgICAgRWxlbVRleHRMaXRlcmFsIGVsZW0gPSBuZXcgRWxlbVRleHRMaXRlcmFsKCk7Ci0KLSAgICAgIGVsZW0uc2V0RE9NQmFja1BvaW50ZXIobV9maXJzdEJhY2tQb2ludGVyKTsKLSAgICAgIGVsZW0uc2V0TG9jYXRlckluZm8oaGFuZGxlci5nZXRMb2NhdG9yKCkpOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGVsZW0uc2V0UHJlZml4ZXMoaGFuZGxlci5nZXROYW1lc3BhY2VTdXBwb3J0KCkpOwotICAgICAgfQotICAgICAgY2F0Y2goVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgICAgfQotCi0gICAgICBib29sZWFuIGRvZSA9IChudWxsICE9IG1feHNsVGV4dEVsZW1lbnQpCi0gICAgICAgICAgICAgICAgICAgID8gbV94c2xUZXh0RWxlbWVudC5nZXREaXNhYmxlT3V0cHV0RXNjYXBpbmcoKSA6IGZhbHNlOwotCi0gICAgICBlbGVtLnNldERpc2FibGVPdXRwdXRFc2NhcGluZyhkb2UpOwotICAgICAgZWxlbS5zZXRQcmVzZXJ2ZVNwYWNlKHRydWUpOwotCi0gICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcltuQ2hhcnNdOwotCi0gICAgICBtX2FjY3VtdWxhdG9yLmdldENoYXJzKDAsIG5DaGFycywgY2hhcnMsIDApOwotICAgICAgZWxlbS5zZXRDaGFycyhjaGFycyk7Ci0KLSAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgcGFyZW50ID0gaGFuZGxlci5nZXRFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0KLSAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtKTsKLSAgICB9Ci0KLSAgICBtX2FjY3VtdWxhdG9yLnNldExlbmd0aCgwKTsKLSAgICBtX2ZpcnN0QmFja1BvaW50ZXIgPSBudWxsOwotICB9Ci0gIAotICBwcm90ZWN0ZWQgTm9kZSBtX2ZpcnN0QmFja1BvaW50ZXIgPSBudWxsOwotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YSBpbnNpZGUgYW4gZWxlbWVudC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQotICAgKiAgICAgICAgICAgICAgIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycygKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgbV9hY2N1bXVsYXRvci5hcHBlbmQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIAotICAgIGlmKG51bGwgPT0gbV9maXJzdEJhY2tQb2ludGVyKQotICAgICAgbV9maXJzdEJhY2tQb2ludGVyID0gaGFuZGxlci5nZXRPcmlnaW5hdGluZ05vZGUoKTsKLQotICAgIC8vIENhdGNoIGFsbCBldmVudHMgdW50aWwgYSBub24tY2hhcmFjdGVyIGV2ZW50LgotICAgIGlmICh0aGlzICE9IGhhbmRsZXIuZ2V0Q3VycmVudFByb2Nlc3NvcigpKQotICAgICAgaGFuZGxlci5wdXNoUHJvY2Vzc29yKHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGNhbGxpbmcgU3R5bGVzaGVldEhhbmRsZXIvVGVtcGxhdGVzQnVpbGRlci4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHJhdyBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgKiAgICAgICAgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMsIGl0IHNoYWxsIGJlIGFuIGVtcHR5Ci0gICAqICAgICAgICBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5TdHlsZXNoZWV0SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5TdHlsZXNoZWV0SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRWxlbWVudAotICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFNpbmNlIHRoaXMgaGFzIGJlZW4gaW5zdGFsbGVkIGFzIHRoZSBjdXJyZW50IHByb2Nlc3Nvciwgd2UgCi0gICAgLy8gbWF5IGdldCBhbmQgZW5kIGVsZW1lbnQgZXZlbnQsIGluIHdoaWNoIGNhc2UsIHdlIHBvcCBhbmQgY2xlYXIgCi0gICAgLy8gYW5kIHRoZW4gY2FsbCB0aGUgcmVhbCBlbGVtZW50IHByb2Nlc3Nvci4KLSAgICBzdGFydE5vblRleHQoaGFuZGxlcik7Ci0gICAgaGFuZGxlci5nZXRDdXJyZW50UHJvY2Vzc29yKCkuZW5kRWxlbWVudChoYW5kbGVyLCB1cmksIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05hbWUpOwotICAgIGhhbmRsZXIucG9wUHJvY2Vzc29yKCk7Ci0gIH0KLQotICAvKioKLSAgICogQWNjdW11bGF0ZSBjaGFyYWN0ZXJzLCB1bnRpbCBhIG5vbi13aGl0ZXNwYWNlIGV2ZW50IGhhcwotICAgKiBvY2N1cmVkLgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgbV9hY2N1bXVsYXRvciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAvKioKLSAgICogVGhlIHhzbDp0ZXh0IHByb2Nlc3NvciB3aWxsIGNhbGwgdGhpcyB0byBzZXQgYQotICAgKiBwcmVzZXJ2ZSBzcGFjZSBzdGF0ZS4KLSAgICovCi0gIHByaXZhdGUgRWxlbVRleHQgbV94c2xUZXh0RWxlbWVudDsKLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHNldFhzbFRleHRFbGVtZW50LiBUaGUgeHNsOnRleHQgCi0gICAqIHByb2Nlc3NvciB3aWxsIGNhbGwgdGhpcyB0byBzZXQgYSBwcmVzZXJ2ZSBzcGFjZSBzdGF0ZS4KLSAgICoKLSAgICogQHBhcmFtIHhzbFRleHRFbGVtZW50IFRoZSBjdXJyZW50IHhzbFRleHRFbGVtZW50IHRoYXQgCi0gICAqICAgICAgICAgICAgICAgICAgICAgICBpcyBwcmVzZXJ2aW5nIHN0YXRlLCBvciBudWxsLgotICAgKi8KLSAgdm9pZCBzZXRYc2xUZXh0RWxlbWVudChFbGVtVGV4dCB4c2xUZXh0RWxlbWVudCkKLSAgewotICAgIG1feHNsVGV4dEVsZW1lbnQgPSB4c2xUZXh0RWxlbWVudDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckRlY2ltYWxGb3JtYXQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JEZWNpbWFsRm9ybWF0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg4MjM2ZmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckRlY2ltYWxGb3JtYXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkRlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogUHJvY2VzcyB4c2w6ZGVjaW1hbC1mb3JtYXQgYnkgY3JlYXRpbmcgYSBEZWNpbWFsRm9ybWF0UHJvcGVydGllcyAKLSAqIG9iamVjdCBhbmQgcGFzc2luZyBpdCB0byB0aGUgc3R5bGVzaGVldC4KLSAqIAotICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0I3NldERlY2ltYWxGb3JtYXQKLSAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMKLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNmb3JtYXQtbnVtYmVyIj5mb3JtYXQtbnVtYmVyIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotY2xhc3MgUHJvY2Vzc29yRGVjaW1hbEZvcm1hdCBleHRlbmRzIFhTTFRFbGVtZW50UHJvY2Vzc29yCi17Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgY2FsbGluZyBTdHlsZXNoZWV0SGFuZGxlci9UZW1wbGF0ZXNCdWlsZGVyLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyBYTUwgMS4wIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcmF3IG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudC4gIElmCi0gICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKLSAgICogICAgICAgIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlN0eWxlc2hlZXRIYW5kbGVyI3N0YXJ0RWxlbWVudAotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlN0eWxlc2hlZXRIYW5kbGVyI2VuZEVsZW1lbnQKLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlcwotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIERlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzIGRmcCA9IG5ldyBEZWNpbWFsRm9ybWF0UHJvcGVydGllcyhoYW5kbGVyLm5leHRVaWQoKSk7Ci0KLSAgICBzZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoaGFuZGxlciwgcmF3TmFtZSwgYXR0cmlidXRlcywgZGZwKTsKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5zZXREZWNpbWFsRm9ybWF0KGRmcCk7Ci0gICAgCi0gICAgaGFuZGxlci5nZXRTdHlsZXNoZWV0KCkuYXBwZW5kQ2hpbGQoZGZwKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3Nvckdsb2JhbFBhcmFtRGVjbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3Nvckdsb2JhbFBhcmFtRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MTg5ZTI5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JHbG9iYWxQYXJhbURlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVBhcmFtOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcHJvY2Vzc2VzIHBhcnNlIGV2ZW50cyBmb3IgYW4geHNsOnBhcmFtIGVsZW1lbnQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotY2xhc3MgUHJvY2Vzc29yR2xvYmFsUGFyYW1EZWNsIGV4dGVuZHMgUHJvY2Vzc29yVGVtcGxhdGVFbGVtCi17Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0aGUgY3VycmVudCB0ZW1wbGF0ZSBlbGVtZW50IHRvIHRoZSBjdXJyZW50Ci0gICAqIHRlbXBsYXRlIGVsZW1lbnQsIGFuZCB0aGVuIHB1c2ggaXQgb250byB0aGUgY3VycmVudCB0ZW1wbGF0ZQotICAgKiBlbGVtZW50IHN0YWNrLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gZWxlbSBUaGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBFbGVtUGFyYW0gZWxlbWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmRBbmRQdXNoKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSnVzdCBwdXNoLCBidXQgZG9uJ3QgYXBwZW5kLgotICAgIGhhbmRsZXIucHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQoZWxlbSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIEVsZW1QYXJhbSB2ID0gKEVsZW1QYXJhbSkgaGFuZGxlci5nZXRFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0KLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5hcHBlbmRDaGlsZCh2KTsKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5zZXRQYXJhbSh2KTsKLSAgICBzdXBlci5lbmRFbGVtZW50KGhhbmRsZXIsIHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3Nvckdsb2JhbFZhcmlhYmxlRGVjbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3Nvckdsb2JhbFZhcmlhYmxlRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDExNTM2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JHbG9iYWxWYXJpYWJsZURlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcHJvY2Vzc2VzIHBhcnNlIGV2ZW50cyBmb3IgYW4geHNsOnZhcmlhYmxlIGVsZW1lbnQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotY2xhc3MgUHJvY2Vzc29yR2xvYmFsVmFyaWFibGVEZWNsIGV4dGVuZHMgUHJvY2Vzc29yVGVtcGxhdGVFbGVtCi17Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0aGUgY3VycmVudCB0ZW1wbGF0ZSBlbGVtZW50IHRvIHRoZSBjdXJyZW50Ci0gICAqIHRlbXBsYXRlIGVsZW1lbnQsIGFuZCB0aGVuIHB1c2ggaXQgb250byB0aGUgY3VycmVudCB0ZW1wbGF0ZQotICAgKiBlbGVtZW50IHN0YWNrLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gZWxlbSBUaGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBFbGVtVmFyaWFibGUgZWxlbWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmRBbmRQdXNoKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSnVzdCBwdXNoLCBidXQgZG9uJ3QgYXBwZW5kLgotICAgIGhhbmRsZXIucHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQoZWxlbSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIEVsZW1WYXJpYWJsZSB2ID0gKEVsZW1WYXJpYWJsZSkgaGFuZGxlci5nZXRFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0KLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5hcHBlbmRDaGlsZCh2KTsKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5zZXRWYXJpYWJsZSh2KTsKLSAgICBzdXBlci5lbmRFbGVtZW50KGhhbmRsZXIsIHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckltcG9ydC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckltcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNWZiMWI3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JJbXBvcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlRyZWVXYWxrZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Q29tcG9zZWQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci0KLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBwcm9jZXNzZXMgcGFyc2UgZXZlbnRzIGZvciBhbiB4c2w6aW1wb3J0IGVsZW1lbnQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNpbXBvcnQiPmltcG9ydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLWNsYXNzIFByb2Nlc3NvckltcG9ydCBleHRlbmRzIFByb2Nlc3NvckluY2x1ZGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBzdHlsZXNoZWV0IHR5cGUgYXNzb2NpYXRlZCB3aXRoIGFuIGltcG9ydGVkIHN0eWxlc2hlZXQKLSAgICoKLSAgICogQHJldHVybiB0aGUgdHlwZSBvZiB0aGUgc3R5bGVzaGVldAotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRTdHlsZXNoZWV0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gU3R5bGVzaGVldEhhbmRsZXIuU1RZUEVfSU1QT1JUOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZXJyb3IgbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHR5cGUgb2Ygc3R5bGVzaGVldCBpbXBvcnRpbmcgaXRzZWxmCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGVycm9yIG51bWJlcgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBnZXRTdHlsZXNoZWV0SW5jbEVycigpCi0gIHsKLSAgICByZXR1cm4gWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lNUE9SVElOR19JVFNFTEY7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckluY2x1ZGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JJbmNsdWRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhkNDEwMzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckluY2x1ZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlRyZWVXYWxrZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotCi1pbXBvcnQgamF2YS5uZXQuVVJMOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLQotLyoqCi0gKiBUcmFuc2Zvcm1lckZhY3RvcnkgY2xhc3MgZm9yIHhzbDppbmNsdWRlIG1hcmt1cC4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdGQiPlhTTFQgRFREPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2luY2x1ZGUiPmluY2x1ZGUgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1jbGFzcyBQcm9jZXNzb3JJbmNsdWRlIGV4dGVuZHMgWFNMVEVsZW1lbnRQcm9jZXNzb3IKLXsKLQotICAvKioKLSAgICogVGhlIGJhc2UgVVJMIG9mIHRoZSBYU0wgZG9jdW1lbnQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1faHJlZiA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYmFzZSBpZGVudGlmaWVyIHdpdGggd2hpY2ggdGhpcyBzdHlsZXNoZWV0IGlzIGFzc29jaWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBocmVmIGF0dHJpYnV0ZSBzdHJpbmcsIG9yIAotICAgKiAgICAgICAgIG51bGwgaWYgc2V0SHJlZiBoYXMgbm90IGJlZW4gY2FsbGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRIcmVmKCkKLSAgewotICAgIHJldHVybiBtX2hyZWY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBiYXNlIGlkZW50aWZpZXIgd2l0aCB3aGljaCB0aGlzIHN0eWxlc2hlZXQgaXMgYXNzb2NpYXRlZC4KLSAgICoKLSAgICogQHBhcmFtIGJhc2VJZGVudCBTaG91bGQgYmUgYSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSB2YWxpZCBVUkwgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SHJlZihTdHJpbmcgYmFzZUlkZW50KQotICB7Ci0gICAgLy8gVmFsaWRhdGU/Ci0gICAgbV9ocmVmID0gYmFzZUlkZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3R5bGVzaGVldCB0eXBlIGFzc29jaWF0ZWQgd2l0aCBhbiBpbmNsdWRlZCBzdHlsZXNoZWV0Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIHR5cGUgb2YgdGhlIHN0eWxlc2hlZXQKLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0U3R5bGVzaGVldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIFN0eWxlc2hlZXRIYW5kbGVyLlNUWVBFX0lOQ0xVREU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBlcnJvciBudW1iZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgdHlwZSBvZiBzdHlsZXNoZWV0IGluY2x1ZGluZyBpdHNlbGYKLSAgICoKLSAgICogQHJldHVybiB0aGUgYXBwcm9wcmlhdGUgZXJyb3IgbnVtYmVyCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldFN0eWxlc2hlZXRJbmNsRXJyKCkKLSAgewotICAgIHJldHVybiBYU0xURXJyb3JSZXNvdXJjZXMuRVJfU1RZTEVTSEVFVF9JTkNMVURFU19JVFNFTEY7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGFuIHhzbDppbmNsdWRlIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBjYWxsaW5nIFN0eWxlc2hlZXRIYW5kbGVyL1RlbXBsYXRlc0J1aWxkZXIuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcmF3IFhNTCAxLjAgbmFtZSAod2l0aCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiByYXcgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LiAgSWYKLSAgICogICAgICAgIHRoZXJlIGFyZSBubyBhdHRyaWJ1dGVzLCBpdCBzaGFsbCBiZSBhbiBlbXB0eQotICAgKiAgICAgICAgQXR0cmlidXRlcyBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotCi0gICAgc2V0UHJvcGVydGllc0Zyb21BdHRyaWJ1dGVzKGhhbmRsZXIsIHJhd05hbWUsIGF0dHJpYnV0ZXMsIHRoaXMpOwotCi0gICAgU3RyaW5nIGhyZWZVcmwgPSBnZXRIcmVmKCk7Ci0KLSAgICBpZiAoaGFuZGxlci5pbXBvcnRTdGFja0NvbnRhaW5zKGhyZWZVcmwpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgZ2V0U3R5bGVzaGVldEluY2xFcnIoKSwgbmV3IE9iamVjdFtdeyBocmVmVXJsIH0pKTsgIC8vIihTdHlsZXNoZWV0SGFuZGxlcikgIitocmVmVXJsKyIgaXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbXBvcnRpbmcgaXRzZWxmISIpOwotICAgIH0KLQotICAgIGhhbmRsZXIucHVzaEltcG9ydFVSTChocmVmVXJsKTsKLQotICAgIGludCBzYXZlZFN0eWxlc2hlZXRUeXBlID0gaGFuZGxlci5nZXRTdHlsZXNoZWV0VHlwZSgpOwotCi0gICAgaGFuZGxlci5zZXRTdHlsZXNoZWV0VHlwZSh0aGlzLmdldFN0eWxlc2hlZXRUeXBlKCkpOwotICAgIGhhbmRsZXIucHVzaE5ld05hbWVzcGFjZVN1cHBvcnQoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHBhcnNlKGhhbmRsZXIsIHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCBhdHRyaWJ1dGVzKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGhhbmRsZXIuc2V0U3R5bGVzaGVldFR5cGUoc2F2ZWRTdHlsZXNoZWV0VHlwZSk7Ci0gICAgICBoYW5kbGVyLnBvcEltcG9ydFVSTCgpOwotICAgICAgaGFuZGxlci5wb3BOYW1lc3BhY2VTdXBwb3J0KCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBvZmYgYSBuZXcgcGFyc2UgZm9yIGFuIGluY2x1ZGVkIG9yIGltcG9ydGVkIHN0eWxlc2hlZXQuICBUaGlzIHdpbGwgCi0gICAqIHNldCB0aGUge0BsaW5rIFN0eWxlc2hlZXRIYW5kbGVyfSB0byBhIG5ldyBzdGF0ZSwgYW5kIHJlY3Vyc2UgaW4gd2l0aCAKLSAgICogYSBuZXcgc2V0IG9mIHBhcnNlIGV2ZW50cy4gIE9uY2UgdGhpcyBmdW5jdGlvbiByZXR1cm5zLCB0aGUgc3RhdGUgb2YgCi0gICAqIHRoZSBTdHlsZXNoZWV0SGFuZGxlciBzaG91bGQgYmUgcmVzdG9yZWQuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIHdoaWNoIHNob3VsZCBiZSB0aGUgWFNMVCBuYW1lc3BhY2UuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgd2hpY2ggc2hvdWxkIGJlICJpbmNsdWRlIiBvciAiaW1wb3J0Ii4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgb24gdGhlIHhzbDppbmNsdWRlIG9yIHhzbDppbXBvcnQgZWxlbWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBwYXJzZSgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCBwcm9jZXNzb3IgPSBoYW5kbGVyLmdldFN0eWxlc2hlZXRQcm9jZXNzb3IoKTsKLSAgICBVUklSZXNvbHZlciB1cmlyZXNvbHZlciA9IHByb2Nlc3Nvci5nZXRVUklSZXNvbHZlcigpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgU291cmNlIHNvdXJjZSA9IG51bGw7Ci0KLSAgICAgIGlmIChudWxsICE9IHVyaXJlc29sdmVyKQotICAgICAgewotICAgICAgICBzb3VyY2UgPSB1cmlyZXNvbHZlci5yZXNvbHZlKGdldEhyZWYoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmdldEJhc2VJZGVudGlmaWVyKCkpOwotCi0gICAgICAgIGlmIChudWxsICE9IHNvdXJjZSAmJiBzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpCi0gICAgICAgIHsKLSAgICAgICAgICBOb2RlIG5vZGUgPSAoKERPTVNvdXJjZSlzb3VyY2UpLmdldE5vZGUoKTsKLSAgICAgICAgICBUcmVlV2Fsa2VyIHdhbGtlciA9IG5ldyBUcmVlV2Fsa2VyKGhhbmRsZXIsIG5ldyBvcmcuYXBhY2hlLnhwYXRoLkRPTTJIZWxwZXIoKSwgc291cmNlLmdldFN5c3RlbUlkKCkpOwotCi0gICAgICAgICAgdHJ5Ci0gICAgICAgICAgewotICAgICAgICAgICAgd2Fsa2VyLnRyYXZlcnNlKG5vZGUpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGlmKG51bGwgPT0gc291cmNlKQotICAgICAgewotICAgICAgICBTdHJpbmcgYWJzVVJMID0gU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSShnZXRIcmVmKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuZ2V0QmFzZUlkZW50aWZpZXIoKSk7Ci0KLSAgICAgICAgc291cmNlID0gbmV3IFN0cmVhbVNvdXJjZShhYnNVUkwpOwotICAgICAgfQotICAgICAgCi0gICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbnVsbDsKLSAgICAgIAotICAgICAgaWYoc291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKQotICAgICAgewotICAgICAgICBTQVhTb3VyY2Ugc2F4U291cmNlID0gKFNBWFNvdXJjZSlzb3VyY2U7Ci0gICAgICAgIHJlYWRlciA9IHNheFNvdXJjZS5nZXRYTUxSZWFkZXIoKTsgLy8gbWF5IGJlIG51bGwKLSAgICAgIH0KLSAgICAgIAotICAgICAgYm9vbGVhbiBpc1VzZXJSZWFkZXIgPSAocmVhZGVyICE9IG51bGwpOwotICAgICAgCi0gICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IFNBWFNvdXJjZS5zb3VyY2VUb0lucHV0U291cmNlKHNvdXJjZSk7Ci0KLSAgICAgIGlmIChudWxsID09IHJlYWRlcikKLSAgICAgIHsgIAotICAgICAgICAvLyBVc2UgSkFYUDEuMSAoIGlmIHBvc3NpYmxlICkKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGZhY3Rvcnk9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKCB0cnVlICk7Ci0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyIGpheHBQYXJzZXI9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgICAgICAgICByZWFkZXI9amF4cFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAKLSAgICAgICAgfSBjYXRjaCggamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCApIHsKLSAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKCBleCApOwotICAgICAgICB9IGNhdGNoKCBqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSApIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oIGV4MS50b1N0cmluZygpICk7Ci0gICAgICAgIH0gCi0gICAgICAgIGNhdGNoKCBOb1N1Y2hNZXRob2RFcnJvciBleDIgKSAKLSAgICAgICAgewotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChBYnN0cmFjdE1ldGhvZEVycm9yIGFtZSl7fQotICAgICAgfQotICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKQotICAgICAgICByZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotCi0gICAgICBpZiAobnVsbCAhPSByZWFkZXIpCi0gICAgICB7Ci0gICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBpZighaXNVc2VyUmVhZGVyKQotICAgICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2R5bmFtaWMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7fQotICAgICAgICAKLSAgICAgICAgaGFuZGxlci5wdXNoQmFzZUluZGVudGlmaWVyKGlucHV0U291cmNlLmdldFN5c3RlbUlkKCkpOwotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgcmVhZGVyLnBhcnNlKGlucHV0U291cmNlKTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICBoYW5kbGVyLnBvcEJhc2VJbmRlbnRpZmllcigpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgaGFuZGxlci5lcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfSU9FWENFUFRJT04sCi0gICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0SHJlZigpIH0sIGlvZSk7Ci0gICAgfQotICAgIGNhdGNoKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIGhhbmRsZXIuZXJyb3IodGUuZ2V0TWVzc2FnZSgpLCB0ZSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yS2V5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yS2V5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVhOTE1OGUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvcktleS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuS2V5RGVjbGFyYXRpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIFRyYW5zZm9ybWVyRmFjdG9yeSBmb3IgeHNsOmtleSBtYXJrdXAuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDprZXkgRU1QVFk+Ci0gKiA8IUFUVExJU1QgeHNsOmtleQotICogICBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gKiAgIG1hdGNoICVwYXR0ZXJuOyAjUkVRVUlSRUQKLSAqICAgdXNlICVleHByOyAjUkVRVUlSRUQKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQja2V5Ij5rZXkgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1jbGFzcyBQcm9jZXNzb3JLZXkgZXh0ZW5kcyBYU0xURWxlbWVudFByb2Nlc3NvcgotewotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4geHNsOmtleSBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgY2FsbGluZyBTdHlsZXNoZWV0SGFuZGxlci9UZW1wbGF0ZXNCdWlsZGVyLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyBYTUwgMS4wIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcmF3IG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudC4gIElmCi0gICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKLSAgICogICAgICAgIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIEtleURlY2xhcmF0aW9uIGtkID0gbmV3IEtleURlY2xhcmF0aW9uKGhhbmRsZXIuZ2V0U3R5bGVzaGVldCgpLCBoYW5kbGVyLm5leHRVaWQoKSk7Ci0KLSAgICBrZC5zZXRET01CYWNrUG9pbnRlcihoYW5kbGVyLmdldE9yaWdpbmF0aW5nTm9kZSgpKTsKLSAgICBrZC5zZXRMb2NhdGVySW5mbyhoYW5kbGVyLmdldExvY2F0b3IoKSk7Ci0gICAgc2V0UHJvcGVydGllc0Zyb21BdHRyaWJ1dGVzKGhhbmRsZXIsIHJhd05hbWUsIGF0dHJpYnV0ZXMsIGtkKTsKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5zZXRLZXkoa2QpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gYXR0cmlidXRlIGxpc3QuCi0gICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBzdHlsZXNoZWV0J3MgQ29udGVudCBoYW5kbGVyLCBuZWVkZWQgZm9yCi0gICAqICAgICAgICAgICAgICAgIGVycm9yIHJlcG9ydGluZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyBuYW1lIG9mIHRoZSBvd25lciBlbGVtZW50LCBuZWVkZWQgZm9yCi0gICAqICAgICAgICAgICAgICAgIGVycm9yIHJlcG9ydGluZy4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGxpc3Qgb2YgYXR0cmlidXRlcy4KLSAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IGVsZW1lbnQgd2hlcmUgdGhlIHByb3BlcnRpZXMgd2lsbCBiZSBzZXQuCi0gICAqLwotICB2b2lkIHNldFByb3BlcnRpZXNGcm9tQXR0cmlidXRlcygKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBPYmplY3QgdGFyZ2V0KQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBYU0xURWxlbWVudERlZiBkZWYgPSBnZXRFbGVtRGVmKCk7Ci0KLSAgICAvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIFhTTFRBdHRyaWJ1dGVEZWZzIGhhdmUgYmVlbiBwcm9jZXNzZWQsIHNvIAotICAgIC8vIEkgY2FuIHNlZSB3aGljaCBkZWZhdWx0IHZhbHVlcyBuZWVkIHRvIGJlIHNldC4KLSAgICBWZWN0b3IgcHJvY2Vzc2VkRGVmcyA9IG5ldyBWZWN0b3IoKTsKLSAgICBpbnQgbkF0dHJzID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkF0dHJzOyBpKyspCi0gICAgewotICAgICAgU3RyaW5nIGF0dHJVcmkgPSBhdHRyaWJ1dGVzLmdldFVSSShpKTsKLSAgICAgIFN0cmluZyBhdHRyTG9jYWxOYW1lID0gYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaSk7Ci0gICAgICBYU0xUQXR0cmlidXRlRGVmIGF0dHJEZWYgPSBkZWYuZ2V0QXR0cmlidXRlRGVmKGF0dHJVcmksIGF0dHJMb2NhbE5hbWUpOwotCi0gICAgICBpZiAobnVsbCA9PSBhdHRyRGVmKQotICAgICAgewotCi0gICAgICAgIC8vIFRoZW4gYmFyZiwgYmVjYXVzZSB0aGlzIGVsZW1lbnQgZG9lcyBub3QgYWxsb3cgdGhpcyBhdHRyaWJ1dGUuCi0gICAgICAgIGhhbmRsZXIuZXJyb3IoYXR0cmlidXRlcy5nZXRRTmFtZShpKQotICAgICAgICAgICAgICAgICAgICAgICsgImF0dHJpYnV0ZSBpcyBub3QgYWxsb3dlZCBvbiB0aGUgIiArIHJhd05hbWUKLSAgICAgICAgICAgICAgICAgICAgICArICIgZWxlbWVudCEiLCBudWxsKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIHZhbHVlU3RyaW5nID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotICAgICAgICBpZiAodmFsdWVTdHJpbmcuaW5kZXhPZihvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLktleXdvcmRzLkZVTkNfS0VZX1NUUklORwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIoIikgPj0gMCkKLSAgICAgICAgICBoYW5kbGVyLmVycm9yKAotICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX0tFWV9DQUxMLCBudWxsKSwgbnVsbCk7Ci0KLSAgICAgICAgcHJvY2Vzc2VkRGVmcy5hZGRFbGVtZW50KGF0dHJEZWYpOwotICAgICAgICBhdHRyRGVmLnNldEF0dHJWYWx1ZShoYW5kbGVyLCBhdHRyVXJpLCBhdHRyTG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpLCBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQpOwotICAgICAgfQotICAgIH0KLQotICAgIFhTTFRBdHRyaWJ1dGVEZWZbXSBhdHRyRGVmcyA9IGRlZi5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgaW50IG5BdHRyRGVmcyA9IGF0dHJEZWZzLmxlbmd0aDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkF0dHJEZWZzOyBpKyspCi0gICAgewotICAgICAgWFNMVEF0dHJpYnV0ZURlZiBhdHRyRGVmID0gYXR0ckRlZnNbaV07Ci0gICAgICBTdHJpbmcgZGVmVmFsID0gYXR0ckRlZi5nZXREZWZhdWx0KCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGRlZlZhbCkKLSAgICAgIHsKLSAgICAgICAgaWYgKCFwcm9jZXNzZWREZWZzLmNvbnRhaW5zKGF0dHJEZWYpKQotICAgICAgICB7Ci0gICAgICAgICAgYXR0ckRlZi5zZXREZWZBdHRyVmFsdWUoaGFuZGxlciwgdGFyZ2V0KTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoYXR0ckRlZi5nZXRSZXF1aXJlZCgpKQotICAgICAgewotICAgICAgICBpZiAoIXByb2Nlc3NlZERlZnMuY29udGFpbnMoYXR0ckRlZikpCi0gICAgICAgICAgaGFuZGxlci5lcnJvcigKLSAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9SRVFVSVJFU19BVFRSSUIsIG5ldyBPYmplY3RbXXsgcmF3TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyRGVmLmdldE5hbWUoKSB9KSwgbnVsbCk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yTFJFLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yTFJFLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhhZGE1NmIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvckxSRS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzg4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUxpdGVyYWxSZXN1bHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1FeHRlbnNpb25DYWxsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuWE1MTlNEZWNsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlNBWFNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogUHJvY2Vzc2VzIGFuIFhTTFQgbGl0ZXJhbC1yZXN1bHQtZWxlbWVudCwgb3Igc29tZXRoaW5nIHRoYXQgbG9va3MgCi0gKiBsaWtlIG9uZS4gIFRoZSBhY3R1YWwge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnR9Ci0gKiBwcm9kdWNlZCBtYXkgYmUgYSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUxpdGVyYWxSZXN1bHR9LCAKLSAqIGEge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXRSb290fSwgb3IgYSAKLSAqIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtRXh0ZW5zaW9uQ2FsbH0uCi0gKiAKLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNsaXRlcmFsLXJlc3VsdC1lbGVtZW50Ij5saXRlcmFsLXJlc3VsdC1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUxpdGVyYWxSZXN1bHQKLSAqLwotcHVibGljIGNsYXNzIFByb2Nlc3NvckxSRSBleHRlbmRzIFByb2Nlc3NvclRlbXBsYXRlRWxlbQotewotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgcCA9IGhhbmRsZXIuZ2V0RWxlbVRlbXBsYXRlRWxlbWVudCgpOwotICAgICAgYm9vbGVhbiBleGNsdWRlWFNMRGVjbCA9IGZhbHNlOwotICAgICAgYm9vbGVhbiBpc0xSRUFzU3R5bGVTaGVldCA9IGZhbHNlOwotCi0gICAgICBpZiAobnVsbCA9PSBwKQotICAgICAgewotCi0gICAgICAgIC8vIExpdGVyYWwgUmVzdWx0IFRlbXBsYXRlIGFzIHN0eWxlc2hlZXQuCi0gICAgICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIGxyZVByb2Nlc3NvciA9IGhhbmRsZXIucG9wUHJvY2Vzc29yKCk7Ci0gICAgICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIHN0eWxlc2hlZXRQcm9jZXNzb3IgPQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmdldFByb2Nlc3NvckZvcihDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJzdHlsZXNoZWV0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbDpzdHlsZXNoZWV0Iik7Ci0KLSAgICAgICAgaGFuZGxlci5wdXNoUHJvY2Vzc29yKGxyZVByb2Nlc3Nvcik7Ci0KLSAgICAgICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0OwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIHN0eWxlc2hlZXQgPSBuZXcgU3R5bGVzaGVldFJvb3QoaGFuZGxlci5nZXRTY2hlbWEoKSwgaGFuZGxlci5nZXRTdHlsZXNoZWV0UHJvY2Vzc29yKCkuZ2V0RXJyb3JMaXN0ZW5lcigpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGZlKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHRmZSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBzdHlsZXNoZWV0LnNldERPTUJhY2tQb2ludGVyKGhhbmRsZXIuZ2V0T3JpZ2luYXRpbmdOb2RlKCkpOwotICAgICAgICAvLyAqKioqKiBOb3RlIHRoYXQgd2UncmUgYXNzaWduaW5nIGFuIGVtcHR5IGxvY2F0b3IuIElzIHRoaXMgbmVjZXNzYXJ5PwotICAgICAgICBTQVhTb3VyY2VMb2NhdG9yIHNsb2NhdG9yID0gbmV3IFNBWFNvdXJjZUxvY2F0b3IoKTsKLSAgICAgICAgTG9jYXRvciBsb2NhdG9yID0gaGFuZGxlci5nZXRMb2NhdG9yKCk7Ci0gICAgICAgIGlmKG51bGwgIT0gbG9jYXRvcikKLSAgICAgICAgewotICAgICAgICAgIHNsb2NhdG9yLnNldExpbmVOdW1iZXIobG9jYXRvci5nZXRMaW5lTnVtYmVyKCkpOwotICAgICAgICAgIHNsb2NhdG9yLnNldENvbHVtbk51bWJlcihsb2NhdG9yLmdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgICBzbG9jYXRvci5zZXRQdWJsaWNJZChsb2NhdG9yLmdldFB1YmxpY0lkKCkpOwotICAgICAgICAgIHNsb2NhdG9yLnNldFN5c3RlbUlkKGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgc3R5bGVzaGVldC5zZXRMb2NhdGVySW5mbyhzbG9jYXRvcik7Ci0gICAgICAgIHN0eWxlc2hlZXQuc2V0UHJlZml4ZXMoaGFuZGxlci5nZXROYW1lc3BhY2VTdXBwb3J0KCkpOwotICAgICAgICBoYW5kbGVyLnB1c2hTdHlsZXNoZWV0KHN0eWxlc2hlZXQpOwotCi0gICAgICAgIGlzTFJFQXNTdHlsZVNoZWV0ID0gdHJ1ZTsKLQotICAgICAgICBBdHRyaWJ1dGVzSW1wbCBzdHlsZXNoZWV0QXR0cnMgPSBuZXcgQXR0cmlidXRlc0ltcGwoKTsKLSAgICAgICAgQXR0cmlidXRlc0ltcGwgbHJlQXR0cnMgPSBuZXcgQXR0cmlidXRlc0ltcGwoKTsKLSAgICAgICAgaW50IG4gPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgU3RyaW5nIGF0dHJMb2NhbE5hbWUgPSBhdHRyaWJ1dGVzLmdldExvY2FsTmFtZShpKTsKLSAgICAgICAgICBTdHJpbmcgYXR0clVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0KLSAgICAgICAgICBpZiAoKG51bGwgIT0gYXR0clVyaSkgJiYgYXR0clVyaS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBzdHlsZXNoZWV0QXR0cnMuYWRkQXR0cmlidXRlKG51bGwsIGF0dHJMb2NhbE5hbWUsIGF0dHJMb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0VHlwZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRWYWx1ZShpKSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYgKChhdHRyTG9jYWxOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8IGF0dHJMb2NhbE5hbWUuZXF1YWxzKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxucyIpKSAmJiB2YWx1ZS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKSkKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIGlnbm9yZQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgbHJlQXR0cnMuYWRkQXR0cmlidXRlKGF0dHJVcmksIGF0dHJMb2NhbE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRRTmFtZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmdldFR5cGUoaSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRWYWx1ZShpKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgYXR0cmlidXRlcyA9IGxyZUF0dHJzOwotCi0gICAgICAgIC8vIFNldCBwcm9wZXJ0aWVzIGZyb20gdGhlIGF0dHJpYnV0ZXMsIGJ1dCBkb24ndCB0aHJvdyAKLSAgICAgICAgLy8gYW4gZXJyb3IgaWYgdGhlcmUgaXMgYW4gYXR0cmlidXRlIGRlZmluZWQgdGhhdCBpcyBub3QgCi0gICAgICAgIC8vIGFsbG93ZWQgb24gYSBzdHlsZXNoZWV0LgotCQkJCXRyeXsKLSAgICAgICAgc3R5bGVzaGVldFByb2Nlc3Nvci5zZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoaGFuZGxlciwgInN0eWxlc2hlZXQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0QXR0cnMsIHN0eWxlc2hlZXQpOwotCQkJCX0KLQkJCQljYXRjaCAoRXhjZXB0aW9uIGUpCi0JCQkJewotCQkJCQkvLyBUaGlzIGlzIHByZXR0eSB1Z2x5LCBidXQgaXQgd2lsbCBoYXZlIHRvIGRvIGZvciBub3cuIAotCQkJCQkvLyBUaGlzIGlzIGp1c3QgdHJ5aW5nIHRvIGFwcGVuZCBzb21lIHRleHQgc3BlY2lmeWluZyB0aGF0Ci0JCQkJCS8vIHRoaXMgZXJyb3IgY2FtZSBmcm9tIGEgbWlzc2luZyBvciBpbnZhbGlkIFhTTFQgbmFtZXNwYWNlCi0JCQkJCS8vIGRlY2xhcmF0aW9uLgotCQkJCQkvLyBJZiBzb21lb25lIGNvbWVzIHVwIHdpdGggYSBiZXR0ZXIgc29sdXRpb24sIHBsZWFzZSBmZWVsIAotCQkJCQkvLyBmcmVlIHRvIGNvbnRyaWJ1dGUgaXQuIC1tbQotCQkJCQlTdHJpbmcgbXNnID0gZS5nZXRNZXNzYWdlKCk7Ci0JCQkJCWlmIChzdHlsZXNoZWV0LmdldERlY2xhcmVkUHJlZml4ZXMoKSA9PSBudWxsIHx8IAotCQkJCQkJIWRlY2xhcmVkWFNMTlMoc3R5bGVzaGVldCkpCi0JCQkJCXsKLQkJCQkJCW1zZyA9IG1zZyArIjsgIiArIFhTTE1lc3NhZ2VzLmNyZWF0ZVdhcm5pbmcoWFNMVEVycm9yUmVzb3VyY2VzLldHX09MRF9YU0xUX05TLCBudWxsKTsKLQkJCQkJCQotCQkJCQl9Ci0JCQkJCS8vZWxzZQotCQkJCQkJdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihtc2csIGUpOwotCQkJCX0KLSAgICAgICAgaGFuZGxlci5wdXNoRWxlbVRlbXBsYXRlRWxlbWVudChzdHlsZXNoZWV0KTsKLQotICAgICAgICBFbGVtVGVtcGxhdGUgdGVtcGxhdGUgPSBuZXcgRWxlbVRlbXBsYXRlKCk7Ci0KLSAgICAgICAgYXBwZW5kQW5kUHVzaChoYW5kbGVyLCB0ZW1wbGF0ZSk7Ci0KLSAgICAgICAgWFBhdGggcm9vdE1hdGNoID0gbmV3IFhQYXRoKCIvIiwgc3R5bGVzaGVldCwgc3R5bGVzaGVldCwgWFBhdGguTUFUQ0gsIAotICAgICAgICAgICAgIGhhbmRsZXIuZ2V0U3R5bGVzaGVldFByb2Nlc3NvcigpLmdldEVycm9yTGlzdGVuZXIoKSk7Ci0KLSAgICAgICAgdGVtcGxhdGUuc2V0TWF0Y2gocm9vdE1hdGNoKTsKLQotICAgICAgICAvLyB0ZW1wbGF0ZS5zZXRET01CYWNrUG9pbnRlcihoYW5kbGVyLmdldE9yaWdpbmF0aW5nTm9kZSgpKTsKLSAgICAgICAgc3R5bGVzaGVldC5zZXRUZW1wbGF0ZSh0ZW1wbGF0ZSk7Ci0KLSAgICAgICAgcCA9IGhhbmRsZXIuZ2V0RWxlbVRlbXBsYXRlRWxlbWVudCgpOwotICAgICAgICBleGNsdWRlWFNMRGVjbCA9IHRydWU7Ci0gICAgICB9Ci0KLSAgICAgIFhTTFRFbGVtZW50RGVmIGRlZiA9IGdldEVsZW1EZWYoKTsKLSAgICAgIENsYXNzIGNsYXNzT2JqZWN0ID0gZGVmLmdldENsYXNzT2JqZWN0KCk7Ci0gICAgICBib29sZWFuIGlzRXh0ZW5zaW9uID0gZmFsc2U7Ci0gICAgICBib29sZWFuIGlzQ29tcG9uZW50RGVjbCA9IGZhbHNlOwotICAgICAgYm9vbGVhbiBpc1Vua25vd25Ub3BMZXZlbCA9IGZhbHNlOwotCi0gICAgICB3aGlsZSAobnVsbCAhPSBwKQotICAgICAgewotCi0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiQ2hlY2tpbmc6ICIrcCk7Ci0gICAgICAgIGlmIChwIGluc3RhbmNlb2YgRWxlbUxpdGVyYWxSZXN1bHQpCi0gICAgICAgIHsKLSAgICAgICAgICBFbGVtTGl0ZXJhbFJlc3VsdCBwYXJlbnRFbGVtID0gKEVsZW1MaXRlcmFsUmVzdWx0KSBwOwotCi0gICAgICAgICAgaXNFeHRlbnNpb24gPSBwYXJlbnRFbGVtLmNvbnRhaW5zRXh0ZW5zaW9uRWxlbWVudFVSSSh1cmkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHAgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KQotICAgICAgICB7Ci0gICAgICAgICAgU3R5bGVzaGVldCBwYXJlbnRFbGVtID0gKFN0eWxlc2hlZXQpIHA7Ci0KLSAgICAgICAgICBpc0V4dGVuc2lvbiA9IHBhcmVudEVsZW0uY29udGFpbnNFeHRlbnNpb25FbGVtZW50VVJJKHVyaSk7Ci0KLSAgICAgICAgICBpZiAoKGZhbHNlID09IGlzRXh0ZW5zaW9uKSAmJiAobnVsbCAhPSB1cmkpCi0gICAgICAgICAgICAgICYmIHVyaS5lcXVhbHMoQ29uc3RhbnRzLlNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaXNDb21wb25lbnREZWNsID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlzVW5rbm93blRvcExldmVsID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoaXNFeHRlbnNpb24pCi0gICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgcCA9IHAuZ2V0UGFyZW50RWxlbSgpOwotICAgICAgfQotCi0gICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IGVsZW0gPSBudWxsOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYgKGlzRXh0ZW5zaW9uKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkNyZWF0aW5nIGV4dGVuc2lvbigxKTogIit1cmkpOwotICAgICAgICAgIGVsZW0gPSBuZXcgRWxlbUV4dGVuc2lvbkNhbGwoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChpc0NvbXBvbmVudERlY2wpCi0gICAgICAgIHsKLSAgICAgICAgICBlbGVtID0gKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIGNsYXNzT2JqZWN0Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoaXNVbmtub3duVG9wTGV2ZWwpCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIFRCRDogSW52ZXN0aWdhdGUsIG5vdCBzdXJlIGFib3V0IHRoaXMuICAtc2IKLSAgICAgICAgICBlbGVtID0gKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIGNsYXNzT2JqZWN0Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgZWxlbSA9IChFbGVtVGVtcGxhdGVFbGVtZW50KSBjbGFzc09iamVjdC5uZXdJbnN0YW5jZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgZWxlbS5zZXRET01CYWNrUG9pbnRlcihoYW5kbGVyLmdldE9yaWdpbmF0aW5nTm9kZSgpKTsKLSAgICAgICAgZWxlbS5zZXRMb2NhdGVySW5mbyhoYW5kbGVyLmdldExvY2F0b3IoKSk7Ci0gICAgICAgIGVsZW0uc2V0UHJlZml4ZXMoaGFuZGxlci5nZXROYW1lc3BhY2VTdXBwb3J0KCksIGV4Y2x1ZGVYU0xEZWNsKTsKLQotICAgICAgICBpZiAoZWxlbSBpbnN0YW5jZW9mIEVsZW1MaXRlcmFsUmVzdWx0KQotICAgICAgICB7Ci0gICAgICAgICAgKChFbGVtTGl0ZXJhbFJlc3VsdCkgZWxlbSkuc2V0TmFtZXNwYWNlKHVyaSk7Ci0gICAgICAgICAgKChFbGVtTGl0ZXJhbFJlc3VsdCkgZWxlbSkuc2V0TG9jYWxOYW1lKGxvY2FsTmFtZSk7Ci0gICAgICAgICAgKChFbGVtTGl0ZXJhbFJlc3VsdCkgZWxlbSkuc2V0UmF3TmFtZShyYXdOYW1lKTsKLSAgICAgICAgICAoKEVsZW1MaXRlcmFsUmVzdWx0KSBlbGVtKS5zZXRJc0xpdGVyYWxSZXN1bHRBc1N0eWxlc2hlZXQoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzTFJFQXNTdHlsZVNoZWV0KTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWUpCi0gICAgICB7Ci0gICAgICAgIGhhbmRsZXIuZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCwgbnVsbCwgaWUpOy8vIkZhaWxlZCBjcmVhdGluZyBFbGVtTGl0ZXJhbFJlc3VsdCBpbnN0YW5jZSEiLCBpZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpCi0gICAgICB7Ci0gICAgICAgIGhhbmRsZXIuZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCwgbnVsbCwgaWFlKTsvLyJGYWlsZWQgY3JlYXRpbmcgRWxlbUxpdGVyYWxSZXN1bHQgaW5zdGFuY2UhIiwgaWFlKTsKLSAgICAgIH0KLQotICAgICAgc2V0UHJvcGVydGllc0Zyb21BdHRyaWJ1dGVzKGhhbmRsZXIsIHJhd05hbWUsIGF0dHJpYnV0ZXMsIGVsZW0pOwotCi0gICAgICAvLyBiaXQgb2YgYSBoYWNrIGhlcmUuLi4KLSAgICAgIGlmICghaXNFeHRlbnNpb24gJiYgKGVsZW0gaW5zdGFuY2VvZiBFbGVtTGl0ZXJhbFJlc3VsdCkpCi0gICAgICB7Ci0gICAgICAgIGlzRXh0ZW5zaW9uID0KLSAgICAgICAgICAgICAgICAgICAgICgoRWxlbUxpdGVyYWxSZXN1bHQpIGVsZW0pLmNvbnRhaW5zRXh0ZW5zaW9uRWxlbWVudFVSSSh1cmkpOwotCi0gICAgICAgIGlmIChpc0V4dGVuc2lvbikKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJDcmVhdGluZyBleHRlbnNpb24oMik6ICIrdXJpKTsKLSAgICAgICAgICBlbGVtID0gbmV3IEVsZW1FeHRlbnNpb25DYWxsKCk7Ci0KLSAgICAgICAgICBlbGVtLnNldExvY2F0ZXJJbmZvKGhhbmRsZXIuZ2V0TG9jYXRvcigpKTsKLSAgICAgICAgICBlbGVtLnNldFByZWZpeGVzKGhhbmRsZXIuZ2V0TmFtZXNwYWNlU3VwcG9ydCgpKTsKLSAgICAgICAgICAoKEVsZW1MaXRlcmFsUmVzdWx0KSBlbGVtKS5zZXROYW1lc3BhY2UodXJpKTsKLSAgICAgICAgICAoKEVsZW1MaXRlcmFsUmVzdWx0KSBlbGVtKS5zZXRMb2NhbE5hbWUobG9jYWxOYW1lKTsKLSAgICAgICAgICAoKEVsZW1MaXRlcmFsUmVzdWx0KSBlbGVtKS5zZXRSYXdOYW1lKHJhd05hbWUpOwotICAgICAgICAgIHNldFByb3BlcnRpZXNGcm9tQXR0cmlidXRlcyhoYW5kbGVyLCByYXdOYW1lLCBhdHRyaWJ1dGVzLCBlbGVtKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBhcHBlbmRBbmRQdXNoKGhhbmRsZXIsIGVsZW0pOwotICAgIH0KLSAgICBjYXRjaChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSA9IGhhbmRsZXIuZ2V0RWxlbVRlbXBsYXRlRWxlbWVudCgpOwotCi0gICAgaWYgKGVsZW0gaW5zdGFuY2VvZiBFbGVtTGl0ZXJhbFJlc3VsdCkKLSAgICB7Ci0gICAgICBpZiAoKChFbGVtTGl0ZXJhbFJlc3VsdCkgZWxlbSkuZ2V0SXNMaXRlcmFsUmVzdWx0QXNTdHlsZXNoZWV0KCkpCi0gICAgICB7Ci0gICAgICAgIGhhbmRsZXIucG9wU3R5bGVzaGVldCgpOwotICAgICAgfQotICAgIH0KLQotICAgIHN1cGVyLmVuZEVsZW1lbnQoaGFuZGxlciwgdXJpLCBsb2NhbE5hbWUsIHJhd05hbWUpOwotICB9Ci0JCi0JcHJpdmF0ZSBib29sZWFuIGRlY2xhcmVkWFNMTlMoU3R5bGVzaGVldCBzdHlsZXNoZWV0KQotCXsKLQkJVmVjdG9yIGRlY2xhcmVkUHJlZml4ZXMgPSBzdHlsZXNoZWV0LmdldERlY2xhcmVkUHJlZml4ZXMoKTsKLQkJaW50IG4gPSBkZWNsYXJlZFByZWZpeGVzLnNpemUoKTsKLQotCQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLQkJewotCQkJWE1MTlNEZWNsIGRlY2wgPSAoWE1MTlNEZWNsKSBkZWNsYXJlZFByZWZpeGVzLmVsZW1lbnRBdChpKTsKLQkJCWlmKGRlY2wuZ2V0VVJJKCkuZXF1YWxzKENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCkpCi0JCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JOYW1lc3BhY2VBbGlhcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3Nvck5hbWVzcGFjZUFsaWFzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM3MTk3OGUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3Nvck5hbWVzcGFjZUFsaWFzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5OYW1lc3BhY2VBbGlhczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLQotLyoqCi0gKiBUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIHhzbDpuYW1lc3BhY2UtYWxpYXMgbWFya3VwLgotICogQSBzdHlsZXNoZWV0IGNhbiB1c2UgdGhlIHhzbDpuYW1lc3BhY2UtYWxpYXMgZWxlbWVudCB0bwotICogZGVjbGFyZSB0aGF0IG9uZSBuYW1lc3BhY2UgVVJJIGlzIGFuIGFsaWFzIGZvciBhbm90aGVyIG5hbWVzcGFjZSBVUkkuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpuYW1lc3BhY2UtYWxpYXMgRU1QVFk+Ci0gKiA8IUFUVExJU1QgeHNsOm5hbWVzcGFjZS1hbGlhcwotICogICBzdHlsZXNoZWV0LXByZWZpeCBDREFUQSAjUkVRVUlSRUQKLSAqICAgcmVzdWx0LXByZWZpeCBDREFUQSAjUkVRVUlSRUQKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbGl0ZXJhbC1yZXN1bHQtZWxlbWVudCI+bGl0ZXJhbC1yZXN1bHQtZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLWNsYXNzIFByb2Nlc3Nvck5hbWVzcGFjZUFsaWFzIGV4dGVuZHMgWFNMVEVsZW1lbnRQcm9jZXNzb3IKLXsKLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGFuIHhzbDpuYW1lc3BhY2UtYWxpYXMgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGNhbGxpbmcgU3R5bGVzaGVldEhhbmRsZXIvVGVtcGxhdGVzQnVpbGRlci4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHJhdyBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgKiAgICAgICAgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMsIGl0IHNoYWxsIGJlIGFuIGVtcHR5Ci0gICAqICAgICAgICBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOYW1lc3BhY2VBbGlhcyBuYSA9IG5ldyBOYW1lc3BhY2VBbGlhcyhoYW5kbGVyLm5leHRVaWQoKSk7Ci0KLSAgICBzZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoaGFuZGxlciwgcmF3TmFtZSwgYXR0cmlidXRlcywgbmEpOwotICAgIFN0cmluZyBwcmVmaXggPSBuYS5nZXRTdHlsZXNoZWV0UHJlZml4KCk7Ci0gICAgaWYocHJlZml4LmVxdWFscygiI2RlZmF1bHQiKSkKLSAgICB7Ci0gICAgICBwcmVmaXggPSAiIjsKLSAgICAgIG5hLnNldFN0eWxlc2hlZXRQcmVmaXgocHJlZml4KTsKLSAgICB9Ci0gICAgU3RyaW5nIHN0eWxlc2hlZXROUyA9IGhhbmRsZXIuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0gICAgbmEuc2V0U3R5bGVzaGVldE5hbWVzcGFjZShzdHlsZXNoZWV0TlMpOwotICAgIHByZWZpeCA9IG5hLmdldFJlc3VsdFByZWZpeCgpOwotICAgIGlmKHByZWZpeC5lcXVhbHMoIiNkZWZhdWx0IikpCi0gICAgewotICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICBuYS5zZXRSZXN1bHRQcmVmaXgocHJlZml4KTsKLSAgICB9Ci0gICAgU3RyaW5nIHJlc3VsdE5TID0gaGFuZGxlci5nZXROYW1lc3BhY2VGb3JQcmVmaXgocHJlZml4KTsKLSAgICBuYS5zZXRSZXN1bHROYW1lc3BhY2UocmVzdWx0TlMpOwotICAgIGhhbmRsZXIuZ2V0U3R5bGVzaGVldCgpLnNldE5hbWVzcGFjZUFsaWFzKG5hKTsKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5hcHBlbmRDaGlsZChuYSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JPdXRwdXRFbGVtLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yT3V0cHV0RWxlbS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NjU5OWJiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JPdXRwdXRFbGVtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLk91dHB1dFByb3BlcnRpZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi0vKioKLSAqIFRyYW5zZm9ybWVyRmFjdG9yeSBmb3IgeHNsOm91dHB1dCBtYXJrdXAuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPm91dHB1dCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLWNsYXNzIFByb2Nlc3Nvck91dHB1dEVsZW0gZXh0ZW5kcyBYU0xURWxlbWVudFByb2Nlc3NvcgotewotCi0gIC8qKiBUaGUgb3V0cHV0IHByb3BlcnRpZXMsIHNldCB0ZW1wb3JhcmlseSB3aGlsZSB0aGUgcHJvcGVydGllcyBhcmUgCi0gICAqICBiZWluZyBzZXQgZnJvbSB0aGUgYXR0cmlidXRlcywgYW5kIHRoZW4gbnVsbGVkIGFmdGVyIHRoYXQgb3BlcmF0aW9uIAotICAgKiAgaXMgY29tcGxldGVkLiAgKi8KLSAgcHJpdmF0ZSBPdXRwdXRQcm9wZXJ0aWVzIG1fb3V0cHV0UHJvcGVydGllczsKLQotICAvKioKLSAgICogU2V0IHRoZSBjZGF0YS1zZWN0aW9uLWVsZW1lbnRzIHByb3BlcnR5IGZyb20gdGhlIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMjQ0RBVEFfU0VDVElPTl9FTEVNRU5UUwotICAgKiBAcGFyYW0gbmV3VmFsdWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByb2Nlc3NlZCBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDZGF0YVNlY3Rpb25FbGVtZW50cyhqYXZhLnV0aWwuVmVjdG9yIG5ld1ZhbHVlKQotICB7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldFFOYW1lUHJvcGVydGllcyhPdXRwdXRLZXlzLkNEQVRBX1NFQ1RJT05fRUxFTUVOVFMsIG5ld1ZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGRvY3R5cGUtcHVibGljIHByb3BlcnR5IGZyb20gdGhlIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMjRE9DVFlQRV9QVUJMSUMKLSAgICogQHBhcmFtIG5ld1ZhbHVlIG5vbi1udWxsIHJlZmVyZW5jZSB0byBwcm9jZXNzZWQgYXR0cmlidXRlIHZhbHVlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdHlwZVB1YmxpYyhTdHJpbmcgbmV3VmFsdWUpCi0gIHsKLSAgICBtX291dHB1dFByb3BlcnRpZXMuc2V0UHJvcGVydHkoT3V0cHV0S2V5cy5ET0NUWVBFX1BVQkxJQywgbmV3VmFsdWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZG9jdHlwZS1zeXN0ZW0gcHJvcGVydHkgZnJvbSB0aGUgYXR0cmlidXRlIHZhbHVlLgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cyNET0NUWVBFX1NZU1RFTQotICAgKiBAcGFyYW0gbmV3VmFsdWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByb2Nlc3NlZCBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N0eXBlU3lzdGVtKFN0cmluZyBuZXdWYWx1ZSkKLSAgewotICAgIG1fb3V0cHV0UHJvcGVydGllcy5zZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkRPQ1RZUEVfU1lTVEVNLCBuZXdWYWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBlbmNvZGluZyBwcm9wZXJ0eSBmcm9tIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzI0VOQ09ESU5HCi0gICAqIEBwYXJhbSBuZXdWYWx1ZSBub24tbnVsbCByZWZlcmVuY2UgdG8gcHJvY2Vzc2VkIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBuZXdWYWx1ZSkKLSAgewotICAgIG1fb3V0cHV0UHJvcGVydGllcy5zZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HLCBuZXdWYWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbmRlbnQgcHJvcGVydHkgZnJvbSB0aGUgYXR0cmlidXRlIHZhbHVlLgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cyNJTkRFTlQKLSAgICogQHBhcmFtIG5ld1ZhbHVlIG5vbi1udWxsIHJlZmVyZW5jZSB0byBwcm9jZXNzZWQgYXR0cmlidXRlIHZhbHVlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW5kZW50KGJvb2xlYW4gbmV3VmFsdWUpCi0gIHsKLSAgICBtX291dHB1dFByb3BlcnRpZXMuc2V0Qm9vbGVhblByb3BlcnR5KE91dHB1dEtleXMuSU5ERU5ULCBuZXdWYWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBtZWRpYSB0eXBlIHByb3BlcnR5IGZyb20gdGhlIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMjTUVESUFfVFlQRQotICAgKiBAcGFyYW0gbmV3VmFsdWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByb2Nlc3NlZCBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNZWRpYVR5cGUoU3RyaW5nIG5ld1ZhbHVlKQotICB7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuTUVESUFfVFlQRSwgbmV3VmFsdWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbWV0aG9kIHByb3BlcnR5IGZyb20gdGhlIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMjTUVUSE9ECi0gICAqIEBwYXJhbSBuZXdWYWx1ZSBub24tbnVsbCByZWZlcmVuY2UgdG8gcHJvY2Vzc2VkIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1ldGhvZChvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZSBuZXdWYWx1ZSkKLSAgewotICAgIG1fb3V0cHV0UHJvcGVydGllcy5zZXRRTmFtZVByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9ELCBuZXdWYWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBvbWl0LXhtbC1kZWNsYXJhdGlvbiBwcm9wZXJ0eSBmcm9tIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzI09NSVRfWE1MX0RFQ0xBUkFUSU9OCi0gICAqIEBwYXJhbSBuZXdWYWx1ZSBwcm9jZXNzZWQgYXR0cmlidXRlIHZhbHVlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T21pdFhtbERlY2xhcmF0aW9uKGJvb2xlYW4gbmV3VmFsdWUpCi0gIHsKLSAgICBtX291dHB1dFByb3BlcnRpZXMuc2V0Qm9vbGVhblByb3BlcnR5KE91dHB1dEtleXMuT01JVF9YTUxfREVDTEFSQVRJT04sIG5ld1ZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHN0YW5kYWxvbmUgcHJvcGVydHkgZnJvbSB0aGUgYXR0cmlidXRlIHZhbHVlLgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cyNTVEFOREFMT05FCi0gICAqIEBwYXJhbSBuZXdWYWx1ZSBwcm9jZXNzZWQgYXR0cmlidXRlIHZhbHVlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3RhbmRhbG9uZShib29sZWFuIG5ld1ZhbHVlKQotICB7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldEJvb2xlYW5Qcm9wZXJ0eShPdXRwdXRLZXlzLlNUQU5EQUxPTkUsIG5ld1ZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHZlcnNpb24gcHJvcGVydHkgZnJvbSB0aGUgYXR0cmlidXRlIHZhbHVlLgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cyNWRVJTSU9OCi0gICAqIEBwYXJhbSBuZXdWYWx1ZSBub24tbnVsbCByZWZlcmVuY2UgdG8gcHJvY2Vzc2VkIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFZlcnNpb24oU3RyaW5nIG5ld1ZhbHVlKQotICB7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KE91dHB1dEtleXMuVkVSU0lPTiwgbmV3VmFsdWUpOwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IGEgZm9yZWlnbiBwcm9wZXJ0eSBmcm9tIHRoZSBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqIEBwYXJhbSBuZXdWYWx1ZSBub24tbnVsbCByZWZlcmVuY2UgdG8gYXR0cmlidXRlIHZhbHVlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Rm9yZWlnbkF0dHIoU3RyaW5nIGF0dHJVcmksIFN0cmluZyBhdHRyTG9jYWxOYW1lLCBTdHJpbmcgYXR0clJhd05hbWUsIFN0cmluZyBhdHRyVmFsdWUpCi0gIHsKLSAgICBRTmFtZSBrZXkgPSBuZXcgUU5hbWUoYXR0clVyaSwgYXR0ckxvY2FsTmFtZSk7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KGtleSwgYXR0clZhbHVlKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldCBhIGZvcmVpZ24gcHJvcGVydHkgZnJvbSB0aGUgYXR0cmlidXRlIHZhbHVlLgotICAgKiBAcGFyYW0gbmV3VmFsdWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZExpdGVyYWxSZXN1bHRBdHRyaWJ1dGUoU3RyaW5nIGF0dHJVcmksIFN0cmluZyBhdHRyTG9jYWxOYW1lLCBTdHJpbmcgYXR0clJhd05hbWUsIFN0cmluZyBhdHRyVmFsdWUpCi0gIHsKLSAgICBRTmFtZSBrZXkgPSBuZXcgUU5hbWUoYXR0clVyaSwgYXR0ckxvY2FsTmFtZSk7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldFByb3BlcnR5KGtleSwgYXR0clZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4geHNsOm91dHB1dCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgY2FsbGluZyBTdHlsZXNoZWV0SGFuZGxlci9UZW1wbGF0ZXNCdWlsZGVyLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyBYTUwgMS4wIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcmF3IG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudC4gIElmCi0gICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKLSAgICogICAgICAgIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBIbW1tLi4uIGZvciB0aGUgbW9tZW50IEkgZG9uJ3QgdGhpbmsgSSdsbCBoYXZlIGRlZmF1bHQgcHJvcGVydGllcyBzZXQgZm9yIHRoaXMuIC1zYgotICAgIG1fb3V0cHV0UHJvcGVydGllcyA9IG5ldyBPdXRwdXRQcm9wZXJ0aWVzKCk7Ci0KLSAgICBtX291dHB1dFByb3BlcnRpZXMuc2V0RE9NQmFja1BvaW50ZXIoaGFuZGxlci5nZXRPcmlnaW5hdGluZ05vZGUoKSk7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLnNldExvY2F0ZXJJbmZvKGhhbmRsZXIuZ2V0TG9jYXRvcigpKTsKLSAgICBtX291dHB1dFByb3BlcnRpZXMuc2V0VWlkKGhhbmRsZXIubmV4dFVpZCgpKTsKLSAgICBzZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoaGFuZGxlciwgcmF3TmFtZSwgYXR0cmlidXRlcywgdGhpcyk7Ci0gICAgCi0gICAgLy8gQWNjZXNzIHRoaXMgb25seSBmcm9tIHRoZSBIYXNodGFibGUgbGV2ZWwuLi4gd2UgZG9uJ3Qgd2FudCB0byAKLSAgICAvLyBnZXQgZGVmYXVsdCBwcm9wZXJ0aWVzLgotICAgIFN0cmluZyBlbnRpdGllc0ZpbGVOYW1lID0KLSAgICAgIChTdHJpbmcpIG1fb3V0cHV0UHJvcGVydGllcy5nZXRQcm9wZXJ0aWVzKCkuZ2V0KE91dHB1dFByb3BlcnRpZXMuU19LRVlfRU5USVRJRVMpOwotCi0gICAgaWYgKG51bGwgIT0gZW50aXRpZXNGaWxlTmFtZSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGFic1VSTCA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoZW50aXRpZXNGaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5nZXRCYXNlSWRlbnRpZmllcigpKTsKLSAgICAgICAgbV9vdXRwdXRQcm9wZXJ0aWVzLmdldFByb3BlcnRpZXMoKS5wdXQoT3V0cHV0UHJvcGVydGllcy5TX0tFWV9FTlRJVElFUywgYWJzVVJMKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgICAgewotICAgICAgICBoYW5kbGVyLmVycm9yKHRlLmdldE1lc3NhZ2UoKSwgdGUpOwotICAgICAgfQotICAgIH0KLSAgICAKLSAgICBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKS5zZXRPdXRwdXQobV9vdXRwdXRQcm9wZXJ0aWVzKTsKLSAgICAKLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHBhcmVudCA9IGhhbmRsZXIuZ2V0RWxlbVRlbXBsYXRlRWxlbWVudCgpOwotICAgIHBhcmVudC5hcHBlbmRDaGlsZChtX291dHB1dFByb3BlcnRpZXMpOwotICAgIAotICAgIG1fb3V0cHV0UHJvcGVydGllcyA9IG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JQcmVzZXJ2ZVNwYWNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yUHJlc2VydmVTcGFjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZDJjZDMyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JQcmVzZXJ2ZVNwYWNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5XaGl0ZVNwYWNlSW5mbzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSBtYXJrdXAuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpwcmVzZXJ2ZS1zcGFjZSBFTVBUWT4KLSAqIDwhQVRUTElTVCB4c2w6cHJlc2VydmUtc3BhY2UgZWxlbWVudHMgQ0RBVEEgI1JFUVVJUkVEPgotICogPC9wcmU+Ci0gKi8KLWNsYXNzIFByb2Nlc3NvclByZXNlcnZlU3BhY2UgZXh0ZW5kcyBYU0xURWxlbWVudFByb2Nlc3NvcgotewotCi0gIC8qKgotICAgKiBCZWFuIHByb3BlcnR5IHRvIGFsbG93IHNldFByb3BlcnRpZXNGcm9tQXR0cmlidXRlcyB0bwotICAgKiBnZXQgdGhlIGVsZW1lbnRzIGF0dHJpYnV0ZS4KLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fZWxlbWVudHM7Ci0KLSAgLyoqCi0gICAqIFNldCBmcm9tIHRoZSBlbGVtZW50cyBhdHRyaWJ1dGUuICBUaGlzIGlzIGEgbGlzdCBvZiAKLSAgICogd2hpdGVzcGFjZSBkZWxpbWl0ZWQgZWxlbWVudCBxdWFsaWZpZWQgbmFtZXMgdGhhdCBzcGVjaWZ5Ci0gICAqIHByZXNlcnZhdGlvbiBvZiB3aGl0ZXNwYWNlLgotICAgKgotICAgKiBAcGFyYW0gZWxlbXMgU2hvdWxkIGJlIGEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgbGlzdCAKLSAgICogICAgICAgICAgICAgIG9mIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLlhQYXRofSBvYmplY3RzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RWxlbWVudHMoVmVjdG9yIGVsZW1zKQotICB7Ci0gICAgbV9lbGVtZW50cyA9IGVsZW1zOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcHJvcGVydHkgc2V0IGJ5IHNldEVsZW1lbnRzKCkuICBUaGlzIGlzIGEgbGlzdCBvZiAKLSAgICogd2hpdGVzcGFjZSBkZWxpbWl0ZWQgZWxlbWVudCBxdWFsaWZpZWQgbmFtZXMgdGhhdCBzcGVjaWZ5Ci0gICAqIHByZXNlcnZhdGlvbiBvZiB3aGl0ZXNwYWNlLgotICAgKgotICAgKiBAcmV0dXJuIEEgcmVmZXJlbmNlIHRvIGEgbGlzdCBvZiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5YUGF0aH0gb2JqZWN0cywgCi0gICAqICAgICAgICAgb3IgbnVsbC4KLSAgICovCi0gIFZlY3RvciBnZXRFbGVtZW50cygpCi0gIHsKLSAgICByZXR1cm4gbV9lbGVtZW50czsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gcHJlc2VydmUtc3BhY2UgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGNhbGxpbmcgU3R5bGVzaGVldEhhbmRsZXIvVGVtcGxhdGVzQnVpbGRlci4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHJhdyBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgKiAgICAgICAgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMsIGl0IHNoYWxsIGJlIGFuIGVtcHR5Ci0gICAqICAgICAgICBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBzZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoaGFuZGxlciwgcmF3TmFtZSwgYXR0cmlidXRlcywgdGhpcyk7Ci0KLSAgICBTdHlsZXNoZWV0IHRoaXNTaGVldCA9IGhhbmRsZXIuZ2V0U3R5bGVzaGVldCgpOwotICAgIFZlY3RvciB4cGF0aHMgPSBnZXRFbGVtZW50cygpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCB4cGF0aHMuc2l6ZSgpOyBpKyspCi0gICAgewotICAgICAgV2hpdGVTcGFjZUluZm8gd3NpID0gbmV3IFdoaXRlU3BhY2VJbmZvKChYUGF0aCkgeHBhdGhzLmVsZW1lbnRBdChpKSwgZmFsc2UsIHRoaXNTaGVldCk7Ci0gICAgICB3c2kuc2V0VWlkKGhhbmRsZXIubmV4dFVpZCgpKTsKLQotICAgICAgdGhpc1NoZWV0LnNldFByZXNlcnZlU3BhY2VzKHdzaSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yU3RyaXBTcGFjZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvclN0cmlwU3BhY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTFmODExOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yU3RyaXBTcGFjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTExICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuV2hpdGVTcGFjZUluZm87Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogVHJhbnNmb3JtZXJGYWN0b3J5IGZvciB4c2w6c3RyaXAtc3BhY2UgbWFya3VwLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6c3RyaXAtc3BhY2UgRU1QVFk+Ci0gKiA8IUFUVExJU1QgeHNsOnN0cmlwLXNwYWNlIGVsZW1lbnRzIENEQVRBICNSRVFVSVJFRD4KLSAqIDwvcHJlPgotICovCi1jbGFzcyBQcm9jZXNzb3JTdHJpcFNwYWNlIGV4dGVuZHMgUHJvY2Vzc29yUHJlc2VydmVTcGFjZQotewotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gc3RyaXAtc3BhY2UgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGNhbGxpbmcgU3R5bGVzaGVldEhhbmRsZXIvVGVtcGxhdGVzQnVpbGRlci4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHJhdyBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQuICBJZgotICAgKiAgICAgICAgdGhlcmUgYXJlIG5vIGF0dHJpYnV0ZXMsIGl0IHNoYWxsIGJlIGFuIGVtcHR5Ci0gICAqICAgICAgICBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgc2V0UHJvcGVydGllc0Zyb21BdHRyaWJ1dGVzKGhhbmRsZXIsIHJhd05hbWUsIGF0dHJpYnV0ZXMsIHRoaXMpOwotCi0gICAgU3R5bGVzaGVldCB0aGlzU2hlZXQgPSBoYW5kbGVyLmdldFN0eWxlc2hlZXQoKTsKLSAgICBWZWN0b3IgeHBhdGhzID0gZ2V0RWxlbWVudHMoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgeHBhdGhzLnNpemUoKTsgaSsrKQotICAgIHsKLSAgICAgIFdoaXRlU3BhY2VJbmZvIHdzaSA9IG5ldyBXaGl0ZVNwYWNlSW5mbygoWFBhdGgpIHhwYXRocy5lbGVtZW50QXQoaSksIHRydWUsIHRoaXNTaGVldCk7Ci0gICAgICB3c2kuc2V0VWlkKGhhbmRsZXIubmV4dFVpZCgpKTsKLQotICAgICAgdGhpc1NoZWV0LnNldFN0cmlwU3BhY2VzKHdzaSk7Ci0gICAgfQotCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JTdHlsZXNoZWV0RG9jLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yU3R5bGVzaGVldERvYy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5N2NmMDM2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JTdHlsZXNoZWV0RG9jLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgcHJvY2Vzc2VzIHRoZSB4c2w6c3R5bGVzaGVldCBlbGVtZW50LiAgQXQgdGhlIAotICogbW9tZW50LCBpdCBkZWZlcnMgYWxsIG1ldGhvZHMgdG8gaXQncyBzdXBlcmNsYXNzLgotICovCi1wdWJsaWMgY2xhc3MgUHJvY2Vzc29yU3R5bGVzaGVldERvYyBleHRlbmRzIFhTTFRFbGVtZW50UHJvY2Vzc29yCi17Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yU3R5bGVzaGVldEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JTdHlsZXNoZWV0RWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NTgyMmEwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JTdHlsZXNoZWV0RWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Q29tcG9zZWQ7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotLyoqCi0gKiBUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIHhzbDpzdHlsZXNoZWV0IG9yIHhzbDp0cmFuc2Zvcm0gbWFya3VwLgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3R5bGVzaGVldC1lbGVtZW50Ij5zdHlsZXNoZWV0LWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1jbGFzcyBQcm9jZXNzb3JTdHlsZXNoZWV0RWxlbWVudCBleHRlbmRzIFhTTFRFbGVtZW50UHJvY2Vzc29yCi17Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBzdGFydCBvZiBhbiBzdHJpcC1zcGFjZSBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgY2FsbGluZyBTdHlsZXNoZWV0SGFuZGxlci9UZW1wbGF0ZXNCdWlsZGVyLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyBYTUwgMS4wIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcmF3IG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudC4gIElmCi0gICAqICAgICAgICB0aGVyZSBhcmUgbm8gYXR0cmlidXRlcywgaXQgc2hhbGwgYmUgYW4gZW1wdHkKLSAgICogICAgICAgIEF0dHJpYnV0ZXMgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotCQlzdXBlci5zdGFydEVsZW1lbnQoaGFuZGxlciwgdXJpLCBsb2NhbE5hbWUsIHJhd05hbWUsIGF0dHJpYnV0ZXMpOwotICAgIHRyeQotICAgIHsKLSAgICAgIGludCBzdHlsZXNoZWV0VHlwZSA9IGhhbmRsZXIuZ2V0U3R5bGVzaGVldFR5cGUoKTsKLSAgICAgIFN0eWxlc2hlZXQgc3R5bGVzaGVldDsKLQotICAgICAgaWYgKHN0eWxlc2hlZXRUeXBlID09IFN0eWxlc2hlZXRIYW5kbGVyLlNUWVBFX1JPT1QpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgc3R5bGVzaGVldCA9IG5ldyBTdHlsZXNoZWV0Um9vdChoYW5kbGVyLmdldFNjaGVtYSgpLCBoYW5kbGVyLmdldFN0eWxlc2hlZXRQcm9jZXNzb3IoKS5nZXRFcnJvckxpc3RlbmVyKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB0ZmUpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24odGZlKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBTdHlsZXNoZWV0IHBhcmVudCA9IGhhbmRsZXIuZ2V0U3R5bGVzaGVldCgpOwotCi0gICAgICAgIGlmIChzdHlsZXNoZWV0VHlwZSA9PSBTdHlsZXNoZWV0SGFuZGxlci5TVFlQRV9JTVBPUlQpCi0gICAgICAgIHsKLSAgICAgICAgICBTdHlsZXNoZWV0Q29tcG9zZWQgc2MgPSBuZXcgU3R5bGVzaGVldENvbXBvc2VkKHBhcmVudCk7Ci0KLSAgICAgICAgICBwYXJlbnQuc2V0SW1wb3J0KHNjKTsKLQotICAgICAgICAgIHN0eWxlc2hlZXQgPSBzYzsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXQocGFyZW50KTsKLQotICAgICAgICAgIHBhcmVudC5zZXRJbmNsdWRlKHN0eWxlc2hlZXQpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHN0eWxlc2hlZXQuc2V0RE9NQmFja1BvaW50ZXIoaGFuZGxlci5nZXRPcmlnaW5hdGluZ05vZGUoKSk7Ci0gICAgICBzdHlsZXNoZWV0LnNldExvY2F0ZXJJbmZvKGhhbmRsZXIuZ2V0TG9jYXRvcigpKTsKLSAgICAgIHN0eWxlc2hlZXQuc2V0UHJlZml4ZXMoaGFuZGxlci5nZXROYW1lc3BhY2VTdXBwb3J0KCkpOwotICAgICAgaGFuZGxlci5wdXNoU3R5bGVzaGVldChzdHlsZXNoZWV0KTsKLSAgICAgIHNldFByb3BlcnRpZXNGcm9tQXR0cmlidXRlcyhoYW5kbGVyLCByYXdOYW1lLCBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuZ2V0U3R5bGVzaGVldCgpKTsKLSAgICAgIGhhbmRsZXIucHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQoaGFuZGxlci5nZXRTdHlsZXNoZWV0KCkpOwotICAgIH0KLSAgICBjYXRjaChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQkJc3VwZXIuZW5kRWxlbWVudChoYW5kbGVyLCB1cmksIGxvY2FsTmFtZSwgcmF3TmFtZSk7Ci0gICAgaGFuZGxlci5wb3BFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0gICAgaGFuZGxlci5wb3BTdHlsZXNoZWV0KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JUZW1wbGF0ZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvclRlbXBsYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMxOGE4MDYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvclRlbXBsYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi0vKioKLSAqIFRyYW5zZm9ybWVyRmFjdG9yeSBmb3IgeHNsOnRlbXBsYXRlIG1hcmt1cC4KLSAqLwotY2xhc3MgUHJvY2Vzc29yVGVtcGxhdGUgZXh0ZW5kcyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0KLXsKLSAgCi0gIC8qKgotICAgKiBBcHBlbmQgdGhlIGN1cnJlbnQgdGVtcGxhdGUgZWxlbWVudCB0byB0aGUgY3VycmVudAotICAgKiB0ZW1wbGF0ZSBlbGVtZW50LCBhbmQgdGhlbiBwdXNoIGl0IG9udG8gdGhlIGN1cnJlbnQgdGVtcGxhdGUKLSAgICogZWxlbWVudCBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIGVsZW0gTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGV9IG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmRBbmRQdXNoKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIuYXBwZW5kQW5kUHVzaChoYW5kbGVyLCBlbGVtKTsKLSAgICBlbGVtLnNldERPTUJhY2tQb2ludGVyKGhhbmRsZXIuZ2V0T3JpZ2luYXRpbmdOb2RlKCkpOwotICAgIGhhbmRsZXIuZ2V0U3R5bGVzaGVldCgpLnNldFRlbXBsYXRlKChFbGVtVGVtcGxhdGUpIGVsZW0pOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yVGVtcGxhdGVFbGVtLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yVGVtcGxhdGVFbGVtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkwZjA3MjkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvclRlbXBsYXRlRWxlbS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTcxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5JbnN0YW50aWF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb2Nlc3NlcyBwYXJzZSBldmVudHMgZm9yIGFuIFhTTFQgdGVtcGxhdGUgZWxlbWVudC4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdGQiPlhTTFQgRFREPC9hPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ3JlYXRpbmctdGhlLVJlc3VsdC1UcmVlIj5zZWN0aW9uLUNyZWF0aW5nLXRoZS1SZXN1bHQtVHJlZSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0gZXh0ZW5kcyBYU0xURWxlbWVudFByb2Nlc3NvcgotewotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIuc3RhcnRFbGVtZW50KGhhbmRsZXIsIHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCBhdHRyaWJ1dGVzKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyBFbGVtVGVtcGxhdGVFbGVtZW50IHBhcmVudCA9IGhhbmRsZXIuZ2V0RWxlbVRlbXBsYXRlRWxlbWVudCgpOwotICAgICAgWFNMVEVsZW1lbnREZWYgZGVmID0gZ2V0RWxlbURlZigpOwotICAgICAgQ2xhc3MgY2xhc3NPYmplY3QgPSBkZWYuZ2V0Q2xhc3NPYmplY3QoKTsKLSAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSA9IG51bGw7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBlbGVtID0gKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIGNsYXNzT2JqZWN0Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgZWxlbS5zZXRET01CYWNrUG9pbnRlcihoYW5kbGVyLmdldE9yaWdpbmF0aW5nTm9kZSgpKTsKLSAgICAgICAgZWxlbS5zZXRMb2NhdGVySW5mbyhoYW5kbGVyLmdldExvY2F0b3IoKSk7Ci0gICAgICAgIGVsZW0uc2V0UHJlZml4ZXMoaGFuZGxlci5nZXROYW1lc3BhY2VTdXBwb3J0KCkpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWUpCi0gICAgICB7Ci0gICAgICAgIGhhbmRsZXIuZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZBSUxFRF9DUkVBVElOR19FTEVNVE1QTCwgbnVsbCwgaWUpOy8vIkZhaWxlZCBjcmVhdGluZyBFbGVtVGVtcGxhdGVFbGVtZW50IGluc3RhbmNlISIsIGllKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlhZSkKLSAgICAgIHsKLSAgICAgICAgaGFuZGxlci5lcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMLCBudWxsLCBpYWUpOy8vIkZhaWxlZCBjcmVhdGluZyBFbGVtVGVtcGxhdGVFbGVtZW50IGluc3RhbmNlISIsIGlhZSk7Ci0gICAgICB9Ci0KLSAgICAgIHNldFByb3BlcnRpZXNGcm9tQXR0cmlidXRlcyhoYW5kbGVyLCByYXdOYW1lLCBhdHRyaWJ1dGVzLCBlbGVtKTsKLSAgICAgIGFwcGVuZEFuZFB1c2goaGFuZGxlciwgZWxlbSk7Ci0gICAgfQotICAgIGNhdGNoKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgdGhlIGN1cnJlbnQgdGVtcGxhdGUgZWxlbWVudCB0byB0aGUgY3VycmVudAotICAgKiB0ZW1wbGF0ZSBlbGVtZW50LCBhbmQgdGhlbiBwdXNoIGl0IG9udG8gdGhlIGN1cnJlbnQgdGVtcGxhdGUKLSAgICogZWxlbWVudCBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIGVsZW0gbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgdGhlIGN1cnJlbnQgdGVtcGxhdGUgZWxlbWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmRBbmRQdXNoKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBwYXJlbnQgPSBoYW5kbGVyLmdldEVsZW1UZW1wbGF0ZUVsZW1lbnQoKTsKLQotICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtKTsKLSAgICBoYW5kbGVyLnB1c2hFbGVtVGVtcGxhdGVFbGVtZW50KGVsZW0pOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuZW5kRWxlbWVudChoYW5kbGVyLCB1cmksIGxvY2FsTmFtZSwgcmF3TmFtZSk7Ci0gICAgaGFuZGxlci5wb3BFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JUZXh0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvUHJvY2Vzc29yVGV4dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3YmRlZWFjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JUZXh0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZXh0OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiBQcm9jZXNzIHhzbDp0ZXh0LgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZWxlbWVudC10ZXh0Ij5lbGVtZW50LXRleHQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgUHJvY2Vzc29yVGV4dCBleHRlbmRzIFByb2Nlc3NvclRlbXBsYXRlRWxlbQotewotCi0gIC8qKgotICAgKiBBcHBlbmQgdGhlIGN1cnJlbnQgdGVtcGxhdGUgZWxlbWVudCB0byB0aGUgY3VycmVudAotICAgKiB0ZW1wbGF0ZSBlbGVtZW50LCBhbmQgdGhlbiBwdXNoIGl0IG9udG8gdGhlIGN1cnJlbnQgdGVtcGxhdGUKLSAgICogZWxlbWVudCBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIGVsZW0gbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZXh0fS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmRBbmRQdXNoKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gRG9uJ3QgcHVzaCB0aGlzIGVsZW1lbnQgb250byB0aGUgZWxlbWVudCBzdGFjay4KLSAgICBQcm9jZXNzb3JDaGFyYWN0ZXJzIGNoYXJQcm9jZXNzb3IgPQotICAgICAgKFByb2Nlc3NvckNoYXJhY3RlcnMpIGhhbmRsZXIuZ2V0UHJvY2Vzc29yRm9yKG51bGwsICJ0ZXh0KCkiLCAidGV4dCIpOwotCi0gICAgY2hhclByb2Nlc3Nvci5zZXRYc2xUZXh0RWxlbWVudCgoRWxlbVRleHQpIGVsZW0pOwotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBwYXJlbnQgPSBoYW5kbGVyLmdldEVsZW1UZW1wbGF0ZUVsZW1lbnQoKTsKLQotICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtKTsKLSAgICBlbGVtLnNldERPTUJhY2tQb2ludGVyKGhhbmRsZXIuZ2V0T3JpZ2luYXRpbmdOb2RlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBQcm9jZXNzb3JDaGFyYWN0ZXJzIGNoYXJQcm9jZXNzb3IgCi0gICAgICA9IChQcm9jZXNzb3JDaGFyYWN0ZXJzKSBoYW5kbGVyLmdldFByb2Nlc3NvckZvcihudWxsLCAidGV4dCgpIiwgInRleHQiKTsKLQotICAgIGNoYXJQcm9jZXNzb3Iuc2V0WHNsVGV4dEVsZW1lbnQobnVsbCk7Ci0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvclVua25vd24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9Qcm9jZXNzb3JVbmtub3duLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM5ZmZkNDkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1Byb2Nlc3NvclVua25vd24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1MaXRlcmFsUmVzdWx0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtRXh0ZW5zaW9uQ2FsbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGNsYXNzIHByb2Nlc3NlcyBhbiB1bmtub3duIHRlbXBsYXRlIGVsZW1lbnQsIGFuZCBpZ25vcmVzIAotICogdGhlIHN0YXJ0RWxlbWVudCBhbmQgZW5kRWxlbWVudCBldmVudHMuICBJdCBpcyB1c2VkIGJvdGggCi0gKiBmb3IgdW5rbm93biB0b3AtbGV2ZWwgZWxlbWVudHMsIGFuZCBmb3IgZWxlbWVudHMgaW4gdGhlIAotICogeHNsdCBuYW1lc3BhY2Ugd2hlbiB0aGUgdmVyc2lvbiBpcyBoaWdoZXIgdGhhbiB0aGUgdmVyc2lvbiAKLSAqIG9mIFhTTFQgdGhhdCB3ZSBhcmUgc2V0IHVwIHRvIHByb2Nlc3MuCi0gKi8KLXB1YmxpYyBjbGFzcyBQcm9jZXNzb3JVbmtub3duIGV4dGVuZHMgUHJvY2Vzc29yVGVtcGxhdGVFbGVtCi17Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBzdGFydCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIHNwZWNpZmllZCBvciBkZWZhdWx0ZWQgYXR0cmlidXRlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbnt9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbnt9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvU3RvcFBhcnNlRXhjZXB0aW9uLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvU3RvcFBhcnNlRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ3M2UwZTEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1N0b3BQYXJzZUV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGlzIGEgc3BlY2lhbCBleGNlcHRpb24gdGhhdCBpcyB1c2VkIHRvIHN0b3AgcGFyc2luZyB3aGVuIAotICogc2VhcmNoIGZvciBhbiBlbGVtZW50LiAgRm9yIGluc3RhbmNlLCB3aGVuIHNlYXJjaGluZyBmb3IgeG1sOnN0eWxlc2hlZXQgCi0gKiBQSXMsIGl0IGlzIHVzZWQgdG8gc3RvcCB0aGUgcGFyc2Ugb25jZSB0aGUgZG9jdW1lbnQgZWxlbWVudCBpcyBmb3VuZC4KLSAqIEBzZWUgU3R5bGVzaGVldFBJSGFuZGxlcgotICovCi1wdWJsaWMgY2xhc3MgU3RvcFBhcnNlRXhjZXB0aW9uIGV4dGVuZHMgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFN0b3BQYXJzZUV4Y2VwdGlvbi4KLSAgICovCi0gIFN0b3BQYXJzZUV4Y2VwdGlvbigpCi0gIHsKLSAgICBzdXBlcigiU3R5bGVzaGVldCBQSXMgZm91bmQsIHN0b3AgdGhlIHBhcnNlIik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9TdHlsZXNoZWV0SGFuZGxlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1N0eWxlc2hlZXRIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY1MjIwNmYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1N0eWxlc2hlZXRIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjE5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgamF2YS5uZXQuVVJMOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVW5rbm93bjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5vZGVDb25zdW1lcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxDaGFyYWN0ZXJSZWNvZ25pemVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkJvb2xTdGFjazsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkZ1bmN0aW9uVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5YUGF0aFBhcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy5GdW5jdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5hbWVzcGFjZVN1cHBvcnQyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuRGVmYXVsdEhhbmRsZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TQVhTb3VyY2VMb2NhdG9yOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW5pdGlhbGl6ZXMgYW5kIHByb2Nlc3NlcyBhIHN0eWxlc2hlZXQgdmlhIFNBWCBldmVudHMuCi0gKiBUaGlzIGNsYXNzIGFjdHMgYXMgZXNzZW50aWFsbHkgYSBzdGF0ZSBtYWNoaW5lLCBtYWludGFpbmluZwotICogYSBDb250ZW50SGFuZGxlciBzdGFjaywgYW5kIHB1c2hpbmcgYXBwcm9wcmlhdGUgY29udGVudAotICogaGFuZGxlcnMgYXMgcGFyc2UgZXZlbnRzIG9jY3VyLgotICovCi1wdWJsaWMgY2xhc3MgU3R5bGVzaGVldEhhbmRsZXIgZXh0ZW5kcyBEZWZhdWx0SGFuZGxlcgotICAgICAgICBpbXBsZW1lbnRzIFRlbXBsYXRlc0hhbmRsZXIsIFByZWZpeFJlc29sdmVyLCBOb2RlQ29uc3VtZXIKLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgU3R5bGVzaGVldEhhbmRsZXIgb2JqZWN0LCBjcmVhdGluZyBhIHJvb3Qgc3R5bGVzaGVldAotICAgKiBhcyB0aGUgdGFyZ2V0LgotICAgKgotICAgKiBAcGFyYW0gcHJvY2Vzc29yIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNmb3JtZXIgZmFjdG9yeSB0aGF0IG93bnMgdGhpcyBoYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiBhIFN0eWxlc2hlZXRSb290Ci0gICAqIGNhbiBub3QgYmUgY29uc3RydWN0ZWQgZm9yIHNvbWUgcmVhc29uLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRIYW5kbGVyKFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgcHJvY2Vzc29yKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0gICAgLy8gbV9zY2hlbWEgPSBuZXcgWFNMVFNjaGVtYSgpOwotICAgIGluaXQocHJvY2Vzc29yKTsKLSAgfQotCi0gIC8qKgotICAgKiBTdGF0aWMgZmxhZyB0byBsZXQgdXMga25vdyBpZiB0aGUgWFBhdGggZnVuY3Rpb25zIHRhYmxlCi0gICAqIGhhcyBiZWVuIGluaXRpYWxpemVkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBtX3hwYXRoRnVuY3Rpb25zSW5pdGVkID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIERvIGNvbW1vbiBpbml0aWFsaXphdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHByb2Nlc3NvciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRyYW5zZm9ybWVyIGZhY3RvcnkgdGhhdCBvd25zIHRoaXMgaGFuZGxlci4KLSAgICovCi0gIHZvaWQgaW5pdChUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIHByb2Nlc3NvcikKLSAgewotCi0gICAgLy8gTm90IHN1cmUgYWJvdXQgZG91YmxlLWNoZWNrIG9mIHRoaXMgZmxhZywgYnV0Ci0gICAgLy8gaXQgc2VlbXMgc2FmZS4uLgotICAgIGlmIChmYWxzZSA9PSBtX3hwYXRoRnVuY3Rpb25zSW5pdGVkKQotICAgIHsKLSAgICAgIHN5bmNocm9uaXplZCAodGhpcykKLSAgICAgIHsKLSAgICAgICAgaWYgKGZhbHNlID09IG1feHBhdGhGdW5jdGlvbnNJbml0ZWQpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3hwYXRoRnVuY3Rpb25zSW5pdGVkID0gdHJ1ZTsKLQotICAgICAgICAgIEZ1bmN0aW9uIGZ1bmMgPSBuZXcgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRnVuY0RvY3VtZW50KCk7Ci0KLSAgICAgICAgICBGdW5jdGlvblRhYmxlLmluc3RhbGxGdW5jdGlvbigiZG9jdW1lbnQiLCBmdW5jKTsKLQotICAgICAgICAgIC8vIGZ1bmMgPSBuZXcgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRnVuY0tleSgpOwotICAgICAgICAgIC8vIEZ1bmN0aW9uVGFibGUuaW5zdGFsbEZ1bmN0aW9uKCJrZXkiLCBmdW5jKTsKLSAgICAgICAgICBmdW5jID0gbmV3IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkZ1bmNGb3JtYXROdW1iKCk7Ci0KLSAgICAgICAgICBGdW5jdGlvblRhYmxlLmluc3RhbGxGdW5jdGlvbigiZm9ybWF0LW51bWJlciIsIGZ1bmMpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbV9zdHlsZXNoZWV0UHJvY2Vzc29yID0gcHJvY2Vzc29yOwotCi0gICAgLy8gU2V0IHRoZSBpbml0aWFsIGNvbnRlbnQgaGFuZGxlci4KLSAgICBtX3Byb2Nlc3NvcnMucHVzaChtX3NjaGVtYS5nZXRFbGVtZW50UHJvY2Vzc29yKCkpOwotICAgIHRoaXMucHVzaE5ld05hbWVzcGFjZVN1cHBvcnQoKTsKLQotICAgIC8vIG1faW5jbHVkZVN0YWNrLnB1c2goU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSSh0aGlzLmdldEJhc2VJZGVudGlmaWVyKCksIG51bGwpKTsKLSAgICAvLyBpbml0WFBhdGgocHJvY2Vzc29yLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGV4cHJlc3Npb24gc3RyaW5nIGludG8gYW4gWFBhdGguCi0gICAqIE11c3QgYmUgcHVibGljIGZvciBhY2Nlc3MgYnkgdGhlIEFWVCBjbGFzcy4KLSAgICoKLSAgICogQHBhcmFtIHN0ciBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIHZhbGlkIG9yIGludmFsaWQgWFBhdGggZXhwcmVzc2lvbiBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYW4gWFBhdGggb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgc3RyaW5nIGFyZ3VtZW50LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGV4cHJlc3Npb24gY2FuIG5vdCBiZSBwcm9jZXNzZWQuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUV4cHJlc3Npb25zIj5TZWN0aW9uIDQgRXhwcmVzc2lvbnMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKi8KLSAgcHVibGljIFhQYXRoIGNyZWF0ZVhQYXRoKFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIEVycm9yTGlzdGVuZXIgaGFuZGxlciA9IG1fc3R5bGVzaGVldFByb2Nlc3Nvci5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgcmV0dXJuIG5ldyBYUGF0aChzdHIsIGdldExvY2F0b3IoKSwgdGhpcywgWFBhdGguU0VMRUNULCBoYW5kbGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGV4cHJlc3Npb24gc3RyaW5nIGludG8gYW4gWFBhdGguCi0gICAqCi0gICAqIEBwYXJhbSBzdHIgQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSB2YWxpZCBvciBpbnZhbGlkIG1hdGNoIHBhdHRlcm4gc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGFuIFhQYXRoIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZyBhcmd1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBwYXR0ZXJuIGNhbiBub3QgYmUgcHJvY2Vzc2VkLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjcGF0dGVybnMiPlNlY3Rpb24gNS4yIFBhdHRlcm5zIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICovCi0gIFhQYXRoIGNyZWF0ZU1hdGNoUGF0dGVyblhQYXRoKFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIEVycm9yTGlzdGVuZXIgaGFuZGxlciA9IG1fc3R5bGVzaGVldFByb2Nlc3Nvci5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgcmV0dXJuIG5ldyBYUGF0aChzdHIsIGdldExvY2F0b3IoKSwgdGhpcywgWFBhdGguTUFUQ0gsIGhhbmRsZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlLCBnZXQgdGhlIGNvcnJpc3BvbmRpbmcgcHJlZml4IGZyb20gdGhlIGN1cnJlbnQKLSAgICogbmFtZXNwYWNlIHN1cHBvcnQgY29udGV4dC4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgdXAsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcgKCIiKSBmb3IgdGhlIGRlZmF1bHQgTmFtZXNwYWNlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgdGhlIHByZWZpeAotICAgKiAgICAgICAgIGlzIHVuZGVjbGFyZWQgaW4gdGhpcyBjb250ZXh0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCkKLSAgewotICAgIHJldHVybiB0aGlzLmdldE5hbWVzcGFjZVN1cHBvcnQoKS5nZXRVUkkocHJlZml4KTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSwgZ2V0IHRoZSBjb3JyaXNwb25kaW5nIHByZWZpeC4gIFRoaXMgaXMgaGVyZSBvbmx5Ci0gICAqIHRvIHN1cHBvcnQgdGhlIHtAbGluayBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcn0gaW50ZXJmYWNlLAotICAgKiBhbmQgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiBpbnZva2VkIG9uIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayB1cCwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZyAoIiIpIGZvciB0aGUgZGVmYXVsdCBOYW1lc3BhY2UuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBub2RlIGNvbnRleHQgZnJvbSB3aGljaCB0byBsb29rIHVwIHRoZSBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0ZWQgTmFtZXNwYWNlIFVSSSwgb3IgbnVsbCBpZiB0aGUgcHJlZml4Ci0gICAqICAgICAgICAgaXMgdW5kZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeChTdHJpbmcgcHJlZml4LCBvcmcudzNjLmRvbS5Ob2RlIGNvbnRleHQpCi0gIHsKLQotICAgIC8vIERvbid0IG5lZWQgdG8gc3VwcG9ydCB0aGlzIGhlcmUuICBSZXR1cm4gdGhlIGN1cnJlbnQgVVJJIGZvciB0aGUgcHJlZml4LAotICAgIC8vIGlnbm9yaW5nIHRoZSBjb250ZXh0LgotICAgIGFzc2VydGlvbih0cnVlLCAiY2FuJ3QgcHJvY2VzcyBhIGNvbnRleHQgbm9kZSBpbiBTdHlsZXNoZWV0SGFuZGxlciEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gc2VlIGlmIHRoZSBzdGFjayBjb250YWlucyB0aGUgZ2l2ZW4gVVJMLgotICAgKgotICAgKiBAcGFyYW0gc3RhY2sgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgU3RhY2suCi0gICAqIEBwYXJhbSB1cmwgVVJMIHN0cmluZyBvbiB3aGljaCBhbiBlcXVhbGl0eSB0ZXN0IHdpbGwgYmUgcGVyZm9ybWVkLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0YWNrIGNvbnRhaW5zIHRoZSB1cmwgYXJndW1lbnQuCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gc3RhY2tDb250YWlucyhTdGFjayBzdGFjaywgU3RyaW5nIHVybCkKLSAgewotCi0gICAgaW50IG4gPSBzdGFjay5zaXplKCk7Ci0gICAgYm9vbGVhbiBjb250YWlucyA9IGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgU3RyaW5nIHVybDIgPSAoU3RyaW5nKSBzdGFjay5lbGVtZW50QXQoaSk7Ci0KLSAgICAgIGlmICh1cmwyLmVxdWFscyh1cmwpKQotICAgICAgewotICAgICAgICBjb250YWlucyA9IHRydWU7Ci0KLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGNvbnRhaW5zOwotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIFRSQVggVGVtcGxhdGVzQnVpbGRlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFdoZW4gdGhpcyBvYmplY3QgaXMgdXNlZCBhcyBhIENvbnRlbnRIYW5kbGVyIG9yIENvbnRlbnRIYW5kbGVyLCBpdCB3aWxsCi0gICAqIGNyZWF0ZSBhIFRlbXBsYXRlcyBvYmplY3QsIHdoaWNoIHRoZSBjYWxsZXIgY2FuIGdldCBvbmNlCi0gICAqIHRoZSBTQVggZXZlbnRzIGhhdmUgYmVlbiBjb21wbGV0ZWQuCi0gICAqIEByZXR1cm4gVGhlIHN0eWxlc2hlZXQgb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgZHVyaW5nCi0gICAqIHRoZSBTQVggZXZlbnQgcHJvY2Vzcywgb3IgbnVsbCBpZiBubyBzdHlsZXNoZWV0IGhhcwotICAgKiBiZWVuIGNyZWF0ZWQuCi0gICAqCi0gICAqIEB2ZXJzaW9uIEFscGhhCi0gICAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOnNjb3R0X2JvYWdAbG90dXMuY29tIj5TY290dCBCb2FnPC9hPgotICAgKi8KLSAgcHVibGljIFRlbXBsYXRlcyBnZXRUZW1wbGF0ZXMoKQotICB7Ci0gICAgcmV0dXJuIGdldFN0eWxlc2hlZXRSb290KCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIElEIChVUkwgb3Igc3lzdGVtIElEKSBmb3IgdGhlIHN0eWxlc2hlZXQKLSAgICogY3JlYXRlZCBieSB0aGlzIGJ1aWxkZXIuICBUaGlzIG11c3QgYmUgc2V0IGluIG9yZGVyIHRvCi0gICAqIHJlc29sdmUgcmVsYXRpdmUgVVJMcyBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHBhcmFtIGJhc2VJRCBCYXNlIFVSTCBmb3IgdGhpcyBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIGJhc2VJRCkKLSAgewotICAgIHB1c2hCYXNlSW5kZW50aWZpZXIoYmFzZUlEKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGJhc2UgSUQgKFVSSSBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgcmVsYXRpdmUKLSAgICogVVJMcyB3aWxsIGJlIHJlc29sdmVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzZXQgd2l0aCB7QGxpbmsgI3NldFN5c3RlbUlkfS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKQotICB7Ci0gICAgcmV0dXJuIHRoaXMuZ2V0QmFzZUlkZW50aWZpZXIoKTsKLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBFbnRpdHlSZXNvbHZlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlc29sdmUgYW4gZXh0ZXJuYWwgZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmZXIsIG9yIG51bGwgaWYgbm9uZSBpcwotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIHByb3ZpZGVkIGluIHRoZSBYTUwKLSAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50LgotICAgKiBAcmV0dXJuIFRoZSBuZXcgaW5wdXQgc291cmNlLCBvciBudWxsIHRvIHJlcXVpcmUgdGhlCi0gICAqICAgICAgICAgZGVmYXVsdCBiZWhhdmlvdXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlmIHRoZSBlbnRpdHkgY2FuIG5vdCBiZSByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBnZXRDdXJyZW50UHJvY2Vzc29yKCkucmVzb2x2ZUVudGl0eSh0aGlzLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgRFRESGFuZGxlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBrZWVwIHRyYWNrIG9mIHRoZSBub3RhdGlvbnMKLSAgICogZGVjbGFyZWQgaW4gYSBkb2N1bWVudC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBub3RhdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vdGF0aW9uIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vdGF0aW9uIHN5c3RlbSBpZGVudGlmaWVyLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjbm90YXRpb25EZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICB7Ci0gICAgZ2V0Q3VycmVudFByb2Nlc3NvcigpLm5vdGF0aW9uRGVjbCh0aGlzLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVudGl0eSBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGVudGl0eSBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub3QKLSAgICogICAgICAgICAgICAgICAgIGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBlbnRpdHkgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqIEBwYXJhbSBub3RhdGlvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgbm90YXRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKQotICB7Ci0gICAgZ2V0Q3VycmVudFByb2Nlc3NvcigpLnVucGFyc2VkRW50aXR5RGVjbCh0aGlzLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RhdGlvbk5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlIFVSSSwgYW5kIGEgbG9jYWwgbmFtZSBvciBhIG5vZGUgdHlwZSwgZ2V0IHRoZSBwcm9jZXNzb3IKLSAgICogZm9yIHRoZSBlbGVtZW50LCBvciByZXR1cm4gbnVsbCBpZiBub3QgYWxsb3dlZC4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKgotICAgKiBAcmV0dXJuIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgZWxlbWVudCBwcm9jZXNzb3IuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlmIHRoZSBlbGVtZW50IGlzIG5vdCBhbGxvd2VkIGluIHRoZQotICAgKiBmb3VuZCBwb3NpdGlvbiBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICovCi0gIFhTTFRFbGVtZW50UHJvY2Vzc29yIGdldFByb2Nlc3NvckZvcigKLSAgICAgICAgICBTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgY3VycmVudFByb2Nlc3NvciA9IGdldEN1cnJlbnRQcm9jZXNzb3IoKTsKLSAgICBYU0xURWxlbWVudERlZiBkZWYgPSBjdXJyZW50UHJvY2Vzc29yLmdldEVsZW1EZWYoKTsKLSAgICBYU0xURWxlbWVudFByb2Nlc3NvciBlbGVtUHJvY2Vzc29yID0gZGVmLmdldFByb2Nlc3NvckZvcih1cmksIGxvY2FsTmFtZSk7Ci0KLSAgICBpZiAobnVsbCA9PSBlbGVtUHJvY2Vzc29yCi0gICAgICAgICAgICAmJiAoKG51bGwgPT0gZ2V0U3R5bGVzaGVldCgpCi0gICAgICAgICAgICAgICAgfHwgRG91YmxlLnZhbHVlT2YoZ2V0U3R5bGVzaGVldCgpLmdldFZlcnNpb24oKSkuZG91YmxlVmFsdWUoKQotICAgICAgICAgICAgICAgICAgID4gQ29uc3RhbnRzLlhTTFRWRVJTVVBQT1JURUQpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCF1cmkuZXF1YWxzKENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCkgJiYKLSAgICAgICAgICAgICAgICBjdXJyZW50UHJvY2Vzc29yIGluc3RhbmNlb2YgUHJvY2Vzc29yU3R5bGVzaGVldEVsZW1lbnQpKSkKLSAgICB7Ci0gICAgICBlbGVtUHJvY2Vzc29yID0gZGVmLmdldFByb2Nlc3NvckZvclVua25vd24odXJpLCBsb2NhbE5hbWUpOwotICAgIH0KLQotICAgIGlmIChudWxsID09IGVsZW1Qcm9jZXNzb3IpCi0gICAgICBlcnJvcihyYXdOYW1lICsgIiBpcyBub3QgYWxsb3dlZCBpbiB0aGlzIHBvc2l0aW9uIGluIHRoZSBzdHlsZXNoZWV0ISIsCi0gICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgICAgICAKLSAgICByZXR1cm4gZWxlbVByb2Nlc3NvcjsKLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVjZWl2ZSBhIExvY2F0b3Igb2JqZWN0IGZvciBkb2N1bWVudCBldmVudHMuCi0gICAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBwYXJzZXIgdG8gcHVzaCBhIGxvY2F0b3IgZm9yIHRoZQotICAgKiBzdHlsZXNoZWV0IGJlaW5nIHBhcnNlZC4gVGhlIHN0YWNrIG5lZWRzIHRvIGJlIHBvcHBlZAotICAgKiBhZnRlciB0aGUgc3R5bGVzaGVldCBoYXMgYmVlbiBwYXJzZWQuIFdlIHBvcCBpbgotICAgKiBwb3BTdHlsZXNoZWV0LgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBBIGxvY2F0b3IgZm9yIGFsbCBTQVggZG9jdW1lbnQgZXZlbnRzLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NldERvY3VtZW50TG9jYXRvcgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigicHVzaGluZyBsb2NhdG9yIGZvcjogIitsb2NhdG9yLmdldFN5c3RlbUlkKCkpOwotICAgIG1fc3R5bGVzaGVldExvY2F0b3JTdGFjay5wdXNoKG5ldyBTQVhTb3VyY2VMb2NhdG9yKGxvY2F0b3IpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbGV2ZWwgb2YgdGhlIHN0eWxlc2hlZXQgd2UgYXJlIGF0LgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9zdHlsZXNoZWV0TGV2ZWwgPSAtMTsKLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnREb2N1bWVudAotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX3N0eWxlc2hlZXRMZXZlbCsrOwotICAgIHB1c2hTcGFjZUhhbmRsaW5nKGZhbHNlKTsKLSAgfQotCi0gIC8qKiBtX3BhcnNpbmdDb21wbGV0ZSBiZWNvbWVzIHRydWUgd2hlbiB0aGUgdG9wLWxldmVsIHN0eWxlc2hlZXQgYW5kIGFsbAotICAgKiBpdHMgaW5jbHVkZWQvaW1wb3J0ZWQgc3R5bGVzaGVldHMgaGF2ZSBiZWVuIGJlZW4gZnVsbHkgcGFyc2VkLCBhcyBhbgotICAgKiBpbmRpY2F0aW9uIHRoYXQgY29tcG9zaXRpb24vb3B0aW1pemF0aW9uL2NvbXBpbGF0aW9uIGNhbiBiZWdpbi4KLSAgICogQHNlZSBpc1N0eWxlc2hlZXRQYXJzaW5nQ29tcGxldGUgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX3BhcnNpbmdDb21wbGV0ZSA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUZXN0IHdoZXRoZXIgdGhlIF9sYXN0XyBlbmREb2N1bWVudCgpIGhhcyBiZWVuIHByb2Nlc3NlZC4KLSAgICogVGhpcyBpcyBuZWVkZWQgYXMgZ3VpZGFuY2UgZm9yIHN0eWxlc2hlZXQgb3B0aW1pemF0aW9uCi0gICAqIGFuZCBjb21waWxhdGlvbiBlbmdpbmVzLCB3aGljaCBnZW5lcmFsbHkgZG9uJ3Qgd2FudCB0byBzdGFydAotICAgKiB1bnRpbCBhbGwgaW5jbHVkZWQgYW5kIGltcG9ydGVkIHN0eWxlc2hlZXRzIGhhdmUgYmVlbiBmdWxseQotICAgKiBwYXJzZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZmYgdGhlIGNvbXBsZXRlIHN0eWxlc2hlZXQgdHJlZSBoYXMgYmVlbiBidWlsdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3R5bGVzaGVldFBhcnNpbmdDb21wbGV0ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9wYXJzaW5nQ29tcGxldGU7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgIT0gZ2V0U3R5bGVzaGVldFJvb3QoKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKDAgPT0gbV9zdHlsZXNoZWV0TGV2ZWwpCi0gICAgICAgICAgZ2V0U3R5bGVzaGVldFJvb3QoKS5yZWNvbXBvc2UoKTsgICAgICAgIAotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fU1RZTEVTSEVFVFJPT1QsIG51bGwpKTsgLy8iRGlkIG5vdCBmaW5kIHRoZSBzdHlsZXNoZWV0IHJvb3QhIik7Ci0KLSAgICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIGVsZW1Qcm9jZXNzb3IgPSBnZXRDdXJyZW50UHJvY2Vzc29yKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGVsZW1Qcm9jZXNzb3IpCi0gICAgICAgIGVsZW1Qcm9jZXNzb3Iuc3RhcnROb25UZXh0KHRoaXMpOwotCi0gICAgICBtX3N0eWxlc2hlZXRMZXZlbC0tOwkJCQotICAgICAgCi0gICAgICBwb3BTcGFjZUhhbmRsaW5nKCk7Ci0KLSAgICAgIC8vIFdBUk5JTkc6IFRoaXMgdGVzdCB3b3JrcyBvbmx5IGFzIGxvbmcgYXMgc3R5bGVzaGVldHMgYXJlIHBhcnNlZAotICAgICAgLy8gbW9yZSBvciBsZXNzIHJlY3Vyc2l2ZWx5LiBJZiB3ZSBzd2l0Y2ggdG8gYW4gaXRlcmF0aXZlICJ3b3JrLWxpc3QiCi0gICAgICAvLyBtb2RlbCwgdGhpcyB3aWxsIGJlY29tZSB0cnVlIHByZW1hdHVyZWx5LiBJbiB0aGF0IGNhc2UsCi0gICAgICAvLyBpc1N0eWxlc2hlZXRQYXJzaW5nQ29tcGxldGUoKSB3aWxsIGhhdmUgdG8gYmUgYWRqdXN0ZWQgdG8gYmUgYXdhcmUKLSAgICAgIC8vIG9mIHRoZSB3b3JrbGlzdC4KLSAgICAgIG1fcGFyc2luZ0NvbXBsZXRlID0gKG1fc3R5bGVzaGVldExldmVsIDwgMCk7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLSAgCi0gIHByaXZhdGUgamF2YS51dGlsLlZlY3RvciBtX3ByZWZpeE1hcHBpbmdzID0gbmV3IGphdmEudXRpbC5WZWN0b3IoKTsKLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGEgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKLSAgICogZWFjaCBlbGVtZW50IChzdWNoIGFzIGFsbG9jYXRpbmcgYSBuZXcgdHJlZSBub2RlIG9yIHdyaXRpbmcKLSAgICogb3V0cHV0IHRvIGEgZmlsZSkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIG1hcHBlZCB0byB0aGUgcHJlZml4LgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbV9uc1N1cHBvcnQucHVzaENvbnRleHQoKTsKLSAgICAvLyB0aGlzLmdldE5hbWVzcGFjZVN1cHBvcnQoKS5kZWNsYXJlUHJlZml4KHByZWZpeCwgdXJpKTsKLSAgICAvL21fcHJlZml4TWFwcGluZ3MuYWRkKHByZWZpeCk7IC8vIEpESyAxLjIrIG9ubHkgLXNjCi0gICAgLy9tX3ByZWZpeE1hcHBpbmdzLmFkZCh1cmkpOyAvLyBKREsgMS4yKyBvbmx5IC1zYwotICAgIG1fcHJlZml4TWFwcGluZ3MuYWRkRWxlbWVudChwcmVmaXgpOyAvLyBKREsgMS4xLnggY29tcGF0IC1zYwotICAgIG1fcHJlZml4TWFwcGluZ3MuYWRkRWxlbWVudCh1cmkpOyAvLyBKREsgMS4xLnggY29tcGF0IC1zYwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBzdGFydCBvZgotICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyBhIG5ldyB0cmVlIG5vZGUgb3Igd3JpdGluZwotICAgKiBvdXRwdXQgdG8gYSBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIE5hbWVzcGFjZSBwcmVmaXggYmVpbmcgZGVjbGFyZWQuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBtX25zU3VwcG9ydC5wb3BDb250ZXh0KCk7Ci0gIH0KLQotICAvKioKLSAgICogRmx1c2ggdGhlIGNoYXJhY3RlcnMgYnVmZmVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGZsdXNoQ2hhcmFjdGVycygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgZWxlbVByb2Nlc3NvciA9IGdldEN1cnJlbnRQcm9jZXNzb3IoKTsKLQotICAgIGlmIChudWxsICE9IGVsZW1Qcm9jZXNzb3IpCi0gICAgICBlbGVtUHJvY2Vzc29yLnN0YXJ0Tm9uVGV4dCh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgICAgTmFtZXNwYWNlU3VwcG9ydCBuc3N1cHBvcnQgPSB0aGlzLmdldE5hbWVzcGFjZVN1cHBvcnQoKTsKLSAgICBuc3N1cHBvcnQucHVzaENvbnRleHQoKTsKLSAgICAKLSAgICBpbnQgbiA9IG1fcHJlZml4TWFwcGluZ3Muc2l6ZSgpOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSAKLSAgICB7Ci0gICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZyltX3ByZWZpeE1hcHBpbmdzLmVsZW1lbnRBdChpKyspOwotICAgICAgU3RyaW5nIG5zVVJJID0gKFN0cmluZyltX3ByZWZpeE1hcHBpbmdzLmVsZW1lbnRBdChpKTsKLSAgICAgIG5zc3VwcG9ydC5kZWNsYXJlUHJlZml4KHByZWZpeCwgbnNVUkkpOwotICAgIH0KLSAgICAvL21fcHJlZml4TWFwcGluZ3MuY2xlYXIoKTsgLy8gSkRLIDEuMisgb25seSAtc2MKLSAgICBtX3ByZWZpeE1hcHBpbmdzLnJlbW92ZUFsbEVsZW1lbnRzKCk7IC8vIEpESyAxLjEueCBjb21wYXQgLXNjCi0KLSAgICBtX2VsZW1lbnRJRCsrOwotCi0gICAgLy8gVGhpcyBjaGVjayBpcyBjdXJyZW50bHkgZG9uZSBmb3IgYWxsIGVsZW1lbnRzLiAgV2Ugc2hvdWxkIHBvc3NpYmx5IGNvbnNpZGVyCi0gICAgLy8gbGltaXRpbmcgdGhpcyBjaGVjayB0byB4c2w6c3R5bGVzaGVldCBlbGVtZW50cyBvbmx5IHNpbmNlIHRoYXQgaXMgYWxsIGl0IHJlYWxseQotICAgIC8vIGFwcGxpZXMgdG8uICBBbHNvLCBpdCBjb3VsZCBiZSBieXBhc3NlZCBpZiBtX3Nob3VsZFByb2Nlc3MgaXMgYWxyZWFkeSB0cnVlLgotICAgIC8vIEluIG90aGVyIHdvcmRzLCB0aGUgbmV4dCB0d28gc3RhdGVtZW50cyBjb3VsZCBpbnN0ZWFkIGxvb2sgc29tZXRoaW5nIGxpa2UgdGhpczoKLSAgICAvLyBpZiAoIW1fc2hvdWxkUHJvY2VzcykKLSAgICAvLyB7Ci0gICAgLy8gICBpZiAobG9jYWxOYW1lLmVxdWFscyhDb25zdGFudHMuRUxFTU5BTUVfU1RZTEVTSEVFVF9TVFJJTkcpICYmCi0gICAgLy8gICAgICAgdXJsLmVxdWFscyhDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwpKQotICAgIC8vICAgewotICAgIC8vICAgICBjaGVja0ZvckZyYWdtZW50SUQoYXR0cmlidXRlcyk7Ci0gICAgLy8gICAgIGlmICghbV9zaG91bGRQcm9jZXNzKQotICAgIC8vICAgICAgIHJldHVybjsKLSAgICAvLyAgIH0KLSAgICAvLyAgIGVsc2UKLSAgICAvLyAgICAgcmV0dXJuOwotICAgIC8vIH0gCi0gICAgLy8gSSBkaWRuJ3QgaW5jbHVkZSB0aGlzIGNvZGUgc3RhdGVtZW50IGF0IHRoaXMgdGltZSBiZWNhdXNlIGluIHByYWN0aWNlIAotICAgIC8vIGl0IGlzIGEgc21hbGwgcGVyZm9ybWFuY2UgaGl0IGFuZCBJIHdhcyB3YWl0aW5nIHRvIHNlZSBpZiBpdHMgYWJzZW5jZQotICAgIC8vIGNhdXNlZCBhIHByb2JsZW0uIC0gR0xQCi0KLSAgICBjaGVja0ZvckZyYWdtZW50SUQoYXR0cmlidXRlcyk7Ci0KLSAgICBpZiAoIW1fc2hvdWxkUHJvY2VzcykKLSAgICAgIHJldHVybjsKLQotICAgIGZsdXNoQ2hhcmFjdGVycygpOwotICAgIAotICAgIHB1c2hTcGFjZUhhbmRsaW5nKGF0dHJpYnV0ZXMpOwotCi0gICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgZWxlbVByb2Nlc3NvciA9IGdldFByb2Nlc3NvckZvcih1cmksIGxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOYW1lKTsKLQotICAgIHRoaXMucHVzaFByb2Nlc3NvcihlbGVtUHJvY2Vzc29yKTsKLSAgICBlbGVtUHJvY2Vzc29yLnN0YXJ0RWxlbWVudCh0aGlzLCB1cmksIGxvY2FsTmFtZSwgcmF3TmFtZSwgYXR0cmlidXRlcyk7Ci0gICAgICAgICAgICAgICAgCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcmF3TmFtZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIG1fZWxlbWVudElELS07Ci0KLSAgICBpZiAoIW1fc2hvdWxkUHJvY2VzcykKLSAgICAgIHJldHVybjsKLQotICAgIGlmICgobV9lbGVtZW50SUQgKyAxKSA9PSBtX2ZyYWdtZW50SUQpCi0gICAgICBtX3Nob3VsZFByb2Nlc3MgPSBmYWxzZTsKLQotICAgIGZsdXNoQ2hhcmFjdGVycygpOwotICAgIAotICAgIHBvcFNwYWNlSGFuZGxpbmcoKTsKLQotICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIHAgPSBnZXRDdXJyZW50UHJvY2Vzc29yKCk7Ci0KLSAgICBwLmVuZEVsZW1lbnQodGhpcywgdXJpLCBsb2NhbE5hbWUsIHJhd05hbWUpOwotICAgIHRoaXMucG9wUHJvY2Vzc29yKCk7Ci0gICAgdGhpcy5nZXROYW1lc3BhY2VTdXBwb3J0KCkucG9wQ29udGV4dCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhIGluc2lkZSBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKCFtX3Nob3VsZFByb2Nlc3MpCi0gICAgICByZXR1cm47Ci0KLSAgICBYU0xURWxlbWVudFByb2Nlc3NvciBlbGVtUHJvY2Vzc29yID0gZ2V0Q3VycmVudFByb2Nlc3NvcigpOwotICAgIFhTTFRFbGVtZW50RGVmIGRlZiA9IGVsZW1Qcm9jZXNzb3IuZ2V0RWxlbURlZigpOwotCi0gICAgaWYgKGRlZi5nZXRUeXBlKCkgIT0gWFNMVEVsZW1lbnREZWYuVF9QQ0RBVEEpCi0gICAgICBlbGVtUHJvY2Vzc29yID0gZGVmLmdldFByb2Nlc3NvckZvcihudWxsLCAidGV4dCgpIik7Ci0KLSAgICBpZiAobnVsbCA9PSBlbGVtUHJvY2Vzc29yKQotICAgIHsKLQotICAgICAgLy8gSWYgaXQncyB3aGl0ZXNwYWNlLCBqdXN0IGlnbm9yZSBpdCwgb3RoZXJ3aXNlIGZsYWcgYW4gZXJyb3IuCi0gICAgICBpZiAoIVhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKSkKLSAgICAgICAgZXJyb3IoCi0gICAgICAgICAgIk5vbi13aGl0ZXNwYWNlIHRleHQgaXMgbm90IGFsbG93ZWQgaW4gdGhpcyBwb3NpdGlvbiBpbiB0aGUgc3R5bGVzaGVldCEiLAotICAgICAgICAgIG51bGwpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBlbGVtUHJvY2Vzc29yLmNoYXJhY3RlcnModGhpcywgY2gsIHN0YXJ0LCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKCFtX3Nob3VsZFByb2Nlc3MpCi0gICAgICByZXR1cm47Ci0KLSAgICBnZXRDdXJyZW50UHJvY2Vzc29yKCkuaWdub3JhYmxlV2hpdGVzcGFjZSh0aGlzLCBjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2gKLSAgICogcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgc3VjaCBhcyBzZXR0aW5nIHN0YXR1cyB2YXJpYWJsZXMgb3IKLSAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICAgICAgIG5vbmUgaXMgc3VwcGxpZWQuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKCFtX3Nob3VsZFByb2Nlc3MpCi0gICAgICByZXR1cm47Ci0KLSAgICBmbHVzaENoYXJhY3RlcnMoKTsKLSAgICBnZXRDdXJyZW50UHJvY2Vzc29yKCkucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRoaXMsIHRhcmdldCwgZGF0YSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBza2lwcGVkIGVudGl0eS4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoCi0gICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMgc2V0dGluZyBzdGF0dXMgdmFyaWFibGVzIG9yCi0gICAqIGludm9raW5nIG90aGVyIG1ldGhvZHMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoIW1fc2hvdWxkUHJvY2VzcykKLSAgICAgIHJldHVybjsKLQotICAgIGdldEN1cnJlbnRQcm9jZXNzb3IoKS5za2lwcGVkRW50aXR5KHRoaXMsIG5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBXYXJuIHRoZSB1c2VyIG9mIGFuIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gaW5kZXggaW50byB0aGUge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlc30KLSAgICogdGFibGUsIHRoYXQgaXMgb25lIG9mIHRoZSBXR18gcHJlZml4ZWQgZGVmaW5pdGlvbnMuCi0gICAqIEBwYXJhbSBhcmdzIEFuIGFycmF5IG9mIGFyZ3VtZW50cyBmb3IgdGhlIGdpdmVuIHdhcm5pbmcuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHRoYXQgd3JhcHMgYQotICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbn0gaWYgdGhlIGN1cnJlbnQKLSAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lciN3YXJuaW5nfQotICAgKiBtZXRob2QgY2hvb3NlcyB0byBmbGFnIHRoaXMgY29uZGl0aW9uIGFzIGFuIGVycm9yLgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybihpbnQgbXNnLCBPYmplY3QgYXJnc1tdKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmb3JtYXR0ZWRNc2cgPSBtX1hTTE1lc3NhZ2VzLmNyZWF0ZVdhcm5pbmcobXNnLCBhcmdzKTsKLSAgICBTQVhTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBnZXRMb2NhdG9yKCk7Ci0gICAgRXJyb3JMaXN0ZW5lciBoYW5kbGVyID0gbV9zdHlsZXNoZWV0UHJvY2Vzc29yLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IGhhbmRsZXIpCi0gICAgICAgIGhhbmRsZXIud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLCBsb2NhdG9yKSk7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIEFzc2VydCB0aGF0IGEgY29uZGl0aW9uIGlzIHRydWUuICBJZiBpdCBpcyBub3QgdHJ1ZSwgdGhyb3cgYW4gZXJyb3IuCi0gICAqCi0gICAqIEBwYXJhbSBjb25kaXRpb24gZmFsc2UgaWYgYW4gZXJyb3Igc2hvdWxkIG5vdCBiZSB0aHJvd24sIG90aGVyd2lzZSB0cnVlLgotICAgKiBAcGFyYW0gbXNnIEVycm9yIG1lc3NhZ2UgdG8gYmUgcGFzc2VkIHRvIHRoZSBSdW50aW1lRXhjZXB0aW9uIGFzIGFuCi0gICAqIGFyZ3VtZW50LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgdGhlIGNvbmRpdGlvbiBpcyBub3QgdHJ1ZS4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBhc3NlcnRpb24oYm9vbGVhbiBjb25kaXRpb24sIFN0cmluZyBtc2cpIHRocm93cyBSdW50aW1lRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoIWNvbmRpdGlvbikKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKG1zZyk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbWVzc2FnZS4KLSAgICogQHBhcmFtIGUgQW4gZXJyb3Igd2hpY2ggdGhlIFNBWEV4Y2VwdGlvbiBzaG91bGQgd3JhcC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gdGhhdCB3cmFwcyBhCi0gICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSBpZiB0aGUgY3VycmVudAotICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyI2Vycm9yfQotICAgKiBtZXRob2QgY2hvb3NlcyB0byBmbGFnIHRoaXMgY29uZGl0aW9uIGFzIGFuIGVycm9yLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTQVhTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBnZXRMb2NhdG9yKCk7Ci0gICAgRXJyb3JMaXN0ZW5lciBoYW5kbGVyID0gbV9zdHlsZXNoZWV0UHJvY2Vzc29yLmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBwZTsKLQotICAgIGlmICghKGUgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckV4Y2VwdGlvbikpCi0gICAgewotICAgICAgcGUgPSAobnVsbCA9PSBlKQotICAgICAgICAgICA/IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIGxvY2F0b3IpCi0gICAgICAgICAgIDogbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1zZywgbG9jYXRvciwgZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHBlID0gKFRyYW5zZm9ybWVyRXhjZXB0aW9uKSBlOwotCi0gICAgaWYgKG51bGwgIT0gaGFuZGxlcikKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaGFuZGxlci5lcnJvcihwZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHBlKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG1zZyBBbiBpbmRleCBpbnRvIHRoZSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzfQotICAgKiB0YWJsZSwgdGhhdCBpcyBvbmUgb2YgdGhlIFdHXyBwcmVmaXhlZCBkZWZpbml0aW9ucy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIGZvciB0aGUgZ2l2ZW4gd2FybmluZy4KLSAgICogQHBhcmFtIGUgQW4gZXJyb3Igd2hpY2ggdGhlIFNBWEV4Y2VwdGlvbiBzaG91bGQgd3JhcC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gdGhhdCB3cmFwcyBhCi0gICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSBpZiB0aGUgY3VycmVudAotICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyI2Vycm9yfQotICAgKiBtZXRob2QgY2hvb3NlcyB0byBmbGFnIHRoaXMgY29uZGl0aW9uIGFzIGFuIGVycm9yLgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoaW50IG1zZywgT2JqZWN0IGFyZ3NbXSwgRXhjZXB0aW9uIGUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgZm9ybWF0dGVkTXNnID0gbV9YU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKG1zZywgYXJncyk7Ci0KLSAgICBlcnJvcihmb3JtYXR0ZWRNc2csIGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgWFNMVCBwcm9jZXNzaW5nIHdhcm5pbmcuCi0gICAqCi0gICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiB0aGF0IHdyYXBzIGEKLSAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259IGlmIHRoZSBjdXJyZW50Ci0gICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXIjd2FybmluZ30KLSAgICogbWV0aG9kIGNob29zZXMgdG8gZmxhZyB0aGlzIGNvbmRpdGlvbiBhcyBhbiBlcnJvci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm5pbmcob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmb3JtYXR0ZWRNc2cgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICBTQVhTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBnZXRMb2NhdG9yKCk7Ci0gICAgRXJyb3JMaXN0ZW5lciBoYW5kbGVyID0gbV9zdHlsZXNoZWV0UHJvY2Vzc29yLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGhhbmRsZXIud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLCBsb2NhdG9yKSk7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBYU0xUIHByb2Nlc3NpbmcgZXJyb3IuCi0gICAqCi0gICAqIEBwYXJhbSBlIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gdGhhdCB3cmFwcyBhCi0gICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSBpZiB0aGUgY3VycmVudAotICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyI2Vycm9yfQotICAgKiBtZXRob2QgY2hvb3NlcyB0byBmbGFnIHRoaXMgY29uZGl0aW9uIGFzIGFuIGVycm9yLgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3Iob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmb3JtYXR0ZWRNc2cgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICBTQVhTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBnZXRMb2NhdG9yKCk7Ci0gICAgRXJyb3JMaXN0ZW5lciBoYW5kbGVyID0gbV9zdHlsZXNoZWV0UHJvY2Vzc29yLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGhhbmRsZXIuZXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZvcm1hdHRlZE1zZywgbG9jYXRvcikpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhIGZhdGFsIFhTTFQgcHJvY2Vzc2luZyBlcnJvci4KLSAgICoKLSAgICogQHBhcmFtIGUgVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiB0aGF0IHdyYXBzIGEKLSAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259IGlmIHRoZSBjdXJyZW50Ci0gICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXIjZmF0YWxFcnJvcn0KLSAgICogbWV0aG9kIGNob29zZXMgdG8gZmxhZyB0aGlzIGNvbmRpdGlvbiBhcyBhbiBlcnJvci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3Iob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmb3JtYXR0ZWRNc2cgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICBTQVhTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBnZXRMb2NhdG9yKCk7Ci0gICAgRXJyb3JMaXN0ZW5lciBoYW5kbGVyID0gbV9zdHlsZXNoZWV0UHJvY2Vzc29yLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLCBsb2NhdG9yKSk7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSWYgd2UgaGF2ZSBhIFVSTCB0byBhIFhNTCBmcmFnbWVudCwgdGhpcyBpcyBzZXQKLSAgICogdG8gZmFsc2UgdW50aWwgdGhlIElEIGlzIGZvdW5kLgotICAgKiAod2FybmluZzogSSB3b3JyeSB0aGF0IHRoaXMgc2hvdWxkIGJlIGluIGEgc3RhY2spLgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fc2hvdWxkUHJvY2VzcyA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIElmIHdlIGhhdmUgYSBVUkwgdG8gYSBYTUwgZnJhZ21lbnQsIHRoZSB2YWx1ZSBpcyBzdG9yZWQKLSAgICogaW4gdGhpcyBzdHJpbmcsIGFuZCB0aGUgbV9zaG91bGRQcm9jZXNzIGZsYWcgaXMgc2V0IHRvCi0gICAqIGZhbHNlIHVudGlsIHdlIG1hdGNoIGFuIElEIHdpdGggdGhpcyBzdHJpbmcuCi0gICAqICh3YXJuaW5nOiBJIHdvcnJ5IHRoYXQgdGhpcyBzaG91bGQgYmUgaW4gYSBzdGFjaykuCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX2ZyYWdtZW50SURTdHJpbmc7Ci0KLSAgLyoqCi0gICAqIEtlZXAgdHJhY2sgb2YgdGhlIGVsZW1lbnRJRCwgc28gd2UgY2FuIHRlbGwgd2hlbgotICAgKiBpcyBoYXMgY29tcGxldGVkLiAgVGhpcyBpc24ndCBhIHJlYWwgSUQsIGJ1dCByYXRoZXIKLSAgICogYSBuZXN0aW5nIGxldmVsLiAgSG93ZXZlciwgaXQncyBnb29kIGVub3VnaCBmb3IKLSAgICogb3VyIHB1cnBvc2VzLgotICAgKiAod2FybmluZzogSSB3b3JyeSB0aGF0IHRoaXMgc2hvdWxkIGJlIGluIGEgc3RhY2spLgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9lbGVtZW50SUQgPSAwOwotCi0gIC8qKgotICAgKiBUaGUgSUQgb2YgdGhlIGZyYWdtZW50IHRoYXQgaGFzIGJlZW4gZm91bmQKLSAgICogKHdhcm5pbmc6IEkgd29ycnkgdGhhdCB0aGlzIHNob3VsZCBiZSBpbiBhIHN0YWNrKS4KLSAgICovCi0gIHByaXZhdGUgaW50IG1fZnJhZ21lbnRJRCA9IDA7Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRvIHNlZSBpZiBhbiBJRCBhdHRyaWJ1dGUgbWF0Y2hlZCB0aGUgI2lkLCBjYWxsZWQKLSAgICogZnJvbSBzdGFydEVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwcml2YXRlIHZvaWQgY2hlY2tGb3JGcmFnbWVudElEKEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgewotCi0gICAgaWYgKCFtX3Nob3VsZFByb2Nlc3MpCi0gICAgewotICAgICAgaWYgKChudWxsICE9IGF0dHJpYnV0ZXMpICYmIChudWxsICE9IG1fZnJhZ21lbnRJRFN0cmluZykpCi0gICAgICB7Ci0gICAgICAgIGludCBuID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBuYW1lID0gYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKLQotICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhDb25zdGFudHMuQVRUUk5BTUVfSUQpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyB2YWwgPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotCi0gICAgICAgICAgICBpZiAodmFsLmVxdWFsc0lnbm9yZUNhc2UobV9mcmFnbWVudElEU3RyaW5nKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgbV9zaG91bGRQcm9jZXNzID0gdHJ1ZTsKLSAgICAgICAgICAgICAgbV9mcmFnbWVudElEID0gbV9lbGVtZW50SUQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgWFNMVCBUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIG5lZWRlZCBzZXJ2aWNlcy4KLSAgICovCi0gIHByaXZhdGUgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCBtX3N0eWxlc2hlZXRQcm9jZXNzb3I7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgWFNMVCBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIGZvciBuZWVkZWQgc2VydmljZXMuCi0gICAqIFRPRE86IFRoaXMgbWV0aG9kIHNob3VsZCBiZSByZW5hbWVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIHRoYXQgb3ducyB0aGlzIGhhbmRsZXIuCi0gICAqLwotICBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIGdldFN0eWxlc2hlZXRQcm9jZXNzb3IoKQotICB7Ci0gICAgcmV0dXJuIG1fc3R5bGVzaGVldFByb2Nlc3NvcjsKLSAgfQotCi0gIC8qKgotICAgKiBJZiB7QGxpbmsgI2dldFN0eWxlc2hlZXRUeXBlfSByZXR1cm5zIHRoaXMgdmFsdWUsIHRoZSBjdXJyZW50IHN0eWxlc2hlZXQKLSAgICogIGlzIGEgcm9vdCBzdHlsZXNoZWV0LgotICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBTVFlQRV9ST09UID0gMTsKLQotICAvKioKLSAgICogSWYge0BsaW5rICNnZXRTdHlsZXNoZWV0VHlwZX0gcmV0dXJucyB0aGlzIHZhbHVlLCB0aGUgY3VycmVudCBzdHlsZXNoZWV0Ci0gICAqICBpcyBhbiBpbmNsdWRlZCBzdHlsZXNoZWV0LgotICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBTVFlQRV9JTkNMVURFID0gMjsKLQotICAvKioKLSAgICogSWYge0BsaW5rICNnZXRTdHlsZXNoZWV0VHlwZX0gcmV0dXJucyB0aGlzIHZhbHVlLCB0aGUgY3VycmVudCBzdHlsZXNoZWV0Ci0gICAqICBpcyBhbiBpbXBvcnRlZCBzdHlsZXNoZWV0LgotICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBTVFlQRV9JTVBPUlQgPSAzOwotCi0gIC8qKiBUaGUgY3VycmVudCBzdHlsZXNoZWV0IHR5cGUuICovCi0gIHByaXZhdGUgaW50IG1fc3R5bGVzaGVldFR5cGUgPSBTVFlQRV9ST09UOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHR5cGUgb2Ygc3R5bGVzaGVldCB0aGF0IHNob3VsZCBiZSBidWlsdAotICAgKiBvciBpcyBiZWluZyBwcm9jZXNzZWQuCi0gICAqCi0gICAqIEByZXR1cm4gb25lIG9mIFNUWVBFX1JPT1QsIFNUWVBFX0lOQ0xVREUsIG9yIFNUWVBFX0lNUE9SVC4KLSAgICovCi0gIGludCBnZXRTdHlsZXNoZWV0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZXNoZWV0VHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHR5cGUgb2Ygc3R5bGVzaGVldCB0aGF0IHNob3VsZCBiZSBidWlsdAotICAgKiBvciBpcyBiZWluZyBwcm9jZXNzZWQuCi0gICAqCi0gICAqIEBwYXJhbSB0eXBlIE11c3QgYmUgb25lIG9mIFNUWVBFX1JPT1QsIFNUWVBFX0lOQ0xVREUsIG9yIFNUWVBFX0lNUE9SVC4KLSAgICovCi0gIHZvaWQgc2V0U3R5bGVzaGVldFR5cGUoaW50IHR5cGUpCi0gIHsKLSAgICBtX3N0eWxlc2hlZXRUeXBlID0gdHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc3RhY2sgb2Ygc3R5bGVzaGVldHMgYmVpbmcgcHJvY2Vzc2VkLgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX3N0eWxlc2hlZXRzID0gbmV3IFN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3R5bGVzaGVldCB0aGF0IHRoaXMgaGFuZGxlciBpcyBjb25zdHJ1Y3RpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3R5bGVzaGVldCB0aGF0IGlzIG9uIHRvcCBvZiB0aGUgc3R5bGVzaGVldHMgc3RhY2ssCi0gICAqICBvciBudWxsIGlmIG5vIHN0eWxlc2hlZXQgaXMgb24gdGhlIHN0eWxlc2hlZXRzIHN0YWNrLgotICAgKi8KLSAgU3R5bGVzaGVldCBnZXRTdHlsZXNoZWV0KCkKLSAgewotICAgIHJldHVybiAobV9zdHlsZXNoZWV0cy5zaXplKCkgPT0gMCkKLSAgICAgICAgICAgPyBudWxsIDogKFN0eWxlc2hlZXQpIG1fc3R5bGVzaGVldHMucGVlaygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbGFzdCBzdHlsZXNoZWV0IHRoYXQgd2FzIHBvcHBlZCBvZmYgdGhlIHN0eWxlc2hlZXRzIHN0YWNrLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsYXN0IHBvcHBlZCBzdHlsZXNoZWV0LCBvciBudWxsLgotICAgKi8KLSAgU3R5bGVzaGVldCBnZXRMYXN0UG9wcGVkU3R5bGVzaGVldCgpCi0gIHsKLSAgICByZXR1cm4gbV9sYXN0UG9wcGVkU3R5bGVzaGVldDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN0eWxlc2hlZXQgcm9vdCB0aGF0IHRoaXMgaGFuZGxlciBpcyBjb25zdHJ1Y3RpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJvb3Qgc3R5bGVzaGVldCBvZiB0aGUgc3R5bGVzaGVldHMgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdCBnZXRTdHlsZXNoZWV0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZXNoZWV0Um9vdDsKLSAgfQotCi0gIC8qKiBUaGUgcm9vdCBzdHlsZXNoZWV0IG9mIHRoZSBzdHlsZXNoZWV0cyB0cmVlLiAqLwotICBTdHlsZXNoZWV0Um9vdCBtX3N0eWxlc2hlZXRSb290OwotICAgICAgICAKLSAgICAgICAgLyoqIFRoZSBsYXN0IHN0eWxlc2hlZXQgdGhhdCB3YXMgcG9wcGVkIG9mZiB0aGUgc3R5bGVzaGVldHMgc3RhY2suICovCi0gIFN0eWxlc2hlZXQgbV9sYXN0UG9wcGVkU3R5bGVzaGVldDsKLQotICAvKioKLSAgICogUHVzaCB0aGUgY3VycmVudCBzdHlsZXNoZWV0IGJlaW5nIGNvbnN0cnVjdGVkLiBJZiBubyBvdGhlciBzdHlsZXNoZWV0cwotICAgKiBoYXZlIGJlZW4gcHVzaGVkIG9udG8gdGhlIHN0YWNrLCBhc3N1bWUgdGhlIGFyZ3VtZW50IGlzIGEgc3R5bGVzaGVldAotICAgKiByb290LCBhbmQgYWxzbyBzZXQgdGhlIHN0eWxlc2hlZXQgcm9vdCBtZW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBzIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIHN0eWxlc2hlZXQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBwdXNoU3R5bGVzaGVldChTdHlsZXNoZWV0IHMpCi0gIHsKLQotICAgIGlmIChtX3N0eWxlc2hlZXRzLnNpemUoKSA9PSAwKQotICAgICAgbV9zdHlsZXNoZWV0Um9vdCA9IChTdHlsZXNoZWV0Um9vdCkgczsKLQotICAgIG1fc3R5bGVzaGVldHMucHVzaChzKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGxhc3Qgc3R5bGVzaGVldCBwdXNoZWQsIGFuZCByZXR1cm4gdGhlIHN0eWxlc2hlZXQgdGhhdCB0aGlzCi0gICAqIGhhbmRsZXIgaXMgY29uc3RydWN0aW5nLCBhbmQgc2V0IHRoZSBsYXN0IHBvcHBlZCBzdHlsZXNoZWV0IG1lbWJlci4KLSAgICogQWxzbyBwb3AgdGhlIHN0eWxlc2hlZXQgbG9jYXRvciBzdGFjay4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3R5bGVzaGVldCBwb3BwZWQgb2ZmIHRoZSBzdGFjaywgb3IgdGhlIGxhc3QgcG9wcGVkIHN0eWxlc2hlZXQuCi0gICAqLwotICBTdHlsZXNoZWV0IHBvcFN0eWxlc2hlZXQoKQotICB7Ci0KLSAgICAvLyBUaGUgc3R5bGVzaGVldExvY2F0b3JTdGFjayBuZWVkcyB0byBiZSBwb3BwZWQgYmVjYXVzZQotICAgIC8vIGEgbG9jYXRvciB3YXMgcHVzaGVkIGluIGZvciB0aGlzIHN0eWxlc2hlZXQgYnkgdGhlIFNBWHBhcnNlciBieSBjYWxsaW5nCi0gICAgLy8gc2V0RG9jdW1lbnRMb2NhdG9yKCkuCi0gICAgaWYgKCFtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2suaXNFbXB0eSgpKQotICAgICAgbV9zdHlsZXNoZWV0TG9jYXRvclN0YWNrLnBvcCgpOwotCi0gICAgaWYgKCFtX3N0eWxlc2hlZXRzLmlzRW1wdHkoKSkKLSAgICAgIG1fbGFzdFBvcHBlZFN0eWxlc2hlZXQgPSAoU3R5bGVzaGVldCkgbV9zdHlsZXNoZWV0cy5wb3AoKTsKLQotICAgIC8vIFNob3VsZG4ndCB0aGlzIGJlIG51bGwgaWYgc3R5bGVzaGVldHMgaXMgZW1wdHk/ICAtc2IKLSAgICByZXR1cm4gbV9sYXN0UG9wcGVkU3R5bGVzaGVldDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgc3RhY2sgb2YgY3VycmVudCBwcm9jZXNzb3JzLgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX3Byb2Nlc3NvcnMgPSBuZXcgU3RhY2soKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IFhTTFRFbGVtZW50UHJvY2Vzc29yIGF0IHRoZSB0b3Agb2YgdGhlIHN0YWNrLgotICAgKgotICAgKiBAcmV0dXJuIFZhbGlkIFhTTFRFbGVtZW50UHJvY2Vzc29yLCB3aGljaCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICovCi0gIFhTTFRFbGVtZW50UHJvY2Vzc29yIGdldEN1cnJlbnRQcm9jZXNzb3IoKQotICB7Ci0gICAgcmV0dXJuIChYU0xURWxlbWVudFByb2Nlc3NvcikgbV9wcm9jZXNzb3JzLnBlZWsoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIHRoZSBjdXJyZW50IFhTTFRFbGVtZW50UHJvY2Vzc29yIG9udG8gdGhlIHRvcCBvZiB0aGUgc3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSBwcm9jZXNzb3Igbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IGVsZW1lbnQgcHJvY2Vzc29yLgotICAgKi8KLSAgdm9pZCBwdXNoUHJvY2Vzc29yKFhTTFRFbGVtZW50UHJvY2Vzc29yIHByb2Nlc3NvcikKLSAgewotICAgIG1fcHJvY2Vzc29ycy5wdXNoKHByb2Nlc3Nvcik7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IFhTTFRFbGVtZW50UHJvY2Vzc29yIGZyb20gdGhlIHRvcCBvZiB0aGUgc3RhY2suCi0gICAqIEByZXR1cm4gdGhlIFhTTFRFbGVtZW50UHJvY2Vzc29yIHdoaWNoIHdhcyBwb3BwZWQuCi0gICAqLwotICBYU0xURWxlbWVudFByb2Nlc3NvciBwb3BQcm9jZXNzb3IoKQotICB7Ci0gICAgcmV0dXJuIChYU0xURWxlbWVudFByb2Nlc3NvcikgbV9wcm9jZXNzb3JzLnBvcCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSByb290IG9mIHRoZSBYU0xUIFNjaGVtYSwgd2hpY2ggdGVsbHMgdXMgaG93IHRvCi0gICAqIHRyYW5zaXRpb24gY29udGVudCBoYW5kbGVycywgY3JlYXRlIGVsZW1lbnRzLCBldGMuCi0gICAqIEZvciB0aGUgbW9tZW50IGF0IGxlYXN0LCB0aGlzIGNhbid0IGJlIHN0YXRpYywgc2luY2UKLSAgICogdGhlIHByb2Nlc3NvcnMgc3RvcmUgc3RhdGUuCi0gICAqLwotICBwcml2YXRlIFhTTFRTY2hlbWEgbV9zY2hlbWEgPSBuZXcgWFNMVFNjaGVtYSgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJvb3Qgb2YgdGhlIFhTTFQgU2NoZW1hLCB3aGljaCB0ZWxscyB1cyBob3cgdG8KLSAgICogdHJhbnNpdGlvbiBjb250ZW50IGhhbmRsZXJzLCBjcmVhdGUgZWxlbWVudHMsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcm9vdCBYU0xUIFNjaGVtYSwgd2hpY2ggc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqLwotICBYU0xUU2NoZW1hIGdldFNjaGVtYSgpCi0gIHsKLSAgICByZXR1cm4gbV9zY2hlbWE7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHN0YWNrIG9mIGVsZW1lbnRzLCBwdXNoZWQgYW5kIHBvcHBlZCBhcyBldmVudHMgb2NjdXIuCi0gICAqLwotICBwcml2YXRlIFN0YWNrIG1fZWxlbXMgPSBuZXcgU3RhY2soKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2suCi0gICAqIEByZXR1cm4gVmFsaWQgRWxlbVRlbXBsYXRlRWxlbWVudCwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqLwotICBFbGVtVGVtcGxhdGVFbGVtZW50IGdldEVsZW1UZW1wbGF0ZUVsZW1lbnQoKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXR1cm4gKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG1fZWxlbXMucGVlaygpOwotICAgIH0KLSAgICBjYXRjaCAoamF2YS51dGlsLkVtcHR5U3RhY2tFeGNlcHRpb24gZXNlKQotICAgIHsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgfSAgCi0KLSAgLyoqIEFuIGluY3JlYXNpbmcgbnVtYmVyIHRoYXQgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgb3JkZXIgaW4gd2hpY2ggdGhpcyBlbGVtZW50Ci0gICAqICB3YXMgZW5jb3VudGVyZWQgZHVyaW5nIHRoZSBwYXJzZSBvZiB0aGUgWFNMVCB0cmVlLgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9kb2NPcmRlckNvdW50ID0gMDsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmV4dCBtX2RvY09yZGVyQ291bnQgbnVtYmVyIGFuZCBpbmNyZW1lbnRzIHRoZSBudW1iZXIgZm9yIGZ1dHVyZSB1c2UuCi0gICAqLwotICBpbnQgbmV4dFVpZCgpCi0gIHsKLSAgICByZXR1cm4gbV9kb2NPcmRlckNvdW50Kys7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaCB0aGUgY3VycmVudCBYU0xURWxlbWVudFByb2Nlc3NvciB0byB0aGUgdG9wIG9mIHRoZSBzdGFjay4gIEFzIGEKLSAgICogc2lkZS1lZmZlY3QsIHNldCB0aGUgZG9jdW1lbnQgb3JkZXIgaW5kZXggKHNpbXBseSBiZWNhdXNlIHRoaXMgaXMgYQotICAgKiBjb252ZW5pZW50IHBsYWNlIHRvIHNldCBpdCkuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIFNob3VsZCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgaW50ZW5kZWQgY3VycmVudAotICAgKiB0ZW1wbGF0ZSBlbGVtZW50LgotICAgKi8KLSAgdm9pZCBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudChFbGVtVGVtcGxhdGVFbGVtZW50IGVsZW0pCi0gIHsKLQotICAgIGlmIChlbGVtLmdldFVpZCgpID09IC0xKQotICAgICAgZWxlbS5zZXRVaWQobmV4dFVpZCgpKTsKLQotICAgIG1fZWxlbXMucHVzaChlbGVtKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgWFNMVEVsZW1lbnRQcm9jZXNzb3IgZnJvbSB0aGUgdG9wIG9mIHRoZSBzdGFjay4KLSAgICogQHJldHVybiB0aGUgRWxlbVRlbXBsYXRlRWxlbWVudCB3aGljaCB3YXMgcG9wcGVkLgotICAgKi8KLSAgRWxlbVRlbXBsYXRlRWxlbWVudCBwb3BFbGVtVGVtcGxhdGVFbGVtZW50KCkKLSAgewotICAgIHJldHVybiAoRWxlbVRlbXBsYXRlRWxlbWVudCkgbV9lbGVtcy5wb3AoKTsKLSAgfQotCi0gIAotICAvKioKLSAgICogQSBYU0xNZXNzYWdlcyBpbnN0YW5jZSBjYXBhYmxlIG9mIHByb2R1Y2luZyB1c2VyIG1lc3NhZ2VzLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgWFNMTWVzc2FnZXMgbV9YU0xNZXNzYWdlcyA9IG5ldyBYU0xNZXNzYWdlcygpOwotCi0gIC8qKgotICAgKiBHZXQgYW4gWFNMTWVzc2FnZXMgaW5zdGFuY2UgY2FwYWJsZSBvZiBwcm9kdWNpbmcgdXNlciBtZXNzYWdlcy4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGVycm9yIGFuZCB3YXJuaW5ncyB0YWJsZS4KLSAgICovCi0gIFhTTE1lc3NhZ2VzIGdldFhTTE1lc3NhZ2VzKCkKLSAgewotICAgIHJldHVybiBtX1hTTE1lc3NhZ2VzOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgd2lsbCBhY3QgYXMgYSBzdGFjayB0byBrZWVwIHRyYWNrIG9mIHRoZQotICAgKiBjdXJyZW50IGluY2x1ZGUgYmFzZS4KLSAgICovCi0gIFN0YWNrIG1fYmFzZUlkZW50aWZpZXJzID0gbmV3IFN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIFB1c2ggYSBiYXNlIGlkZW50aWZpZXIgb250byB0aGUgYmFzZSBVUkkgc3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSBiYXNlSUQgVGhlIGN1cnJlbnQgYmFzZSBpZGVudGlmaWVyIGZvciB0aGlzIHBvc2l0aW9uIGluIHRoZQotICAgKiBzdHlsZXNoZWV0LCB3aGljaCBtYXkgYmUgYSBmcmFnbWVudCBpZGVudGlmaWVyLCBvciB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Jhc2UtdXJpIj4KLSAgICogU2VjdGlvbiAzLjIgQmFzZSBVUkkgb2YgWFNMVCBzcGVjaWZpY2F0aW9uLjwvYT4KLSAgICovCi0gIHZvaWQgcHVzaEJhc2VJbmRlbnRpZmllcihTdHJpbmcgYmFzZUlEKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBiYXNlSUQpCi0gICAgewotICAgICAgaW50IHBvc09mSGFzaCA9IGJhc2VJRC5pbmRleE9mKCcjJyk7Ci0KLSAgICAgIGlmIChwb3NPZkhhc2ggPiAtMSkKLSAgICAgIHsKLSAgICAgICAgbV9mcmFnbWVudElEU3RyaW5nID0gYmFzZUlELnN1YnN0cmluZyhwb3NPZkhhc2ggKyAxKTsKLSAgICAgICAgbV9zaG91bGRQcm9jZXNzID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIG1fc2hvdWxkUHJvY2VzcyA9IHRydWU7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIG1fc2hvdWxkUHJvY2VzcyA9IHRydWU7Ci0KLSAgICBtX2Jhc2VJZGVudGlmaWVycy5wdXNoKGJhc2VJRCk7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIGEgYmFzZSBVUkkgZnJvbSB0aGUgc3RhY2suCi0gICAqIEByZXR1cm4gYmFzZUlkZW50aWZpZXIuCi0gICAqLwotICBTdHJpbmcgcG9wQmFzZUluZGVudGlmaWVyKCkKLSAgewotICAgIHJldHVybiAoU3RyaW5nKSBtX2Jhc2VJZGVudGlmaWVycy5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGJhc2UgaWRlbnRpZmllci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYmFzZSBpZGVudGlmaWVyIG9mIHRoZSBjdXJyZW50IHN0eWxlc2hlZXQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJhc2VJZGVudGlmaWVyKCkKLSAgewotCi0gICAgLy8gVHJ5IHRvIGdldCB0aGUgYmFzZUlkZW50aWZpZXIgZnJvbSB0aGUgYmFzZUlkZW50aWZpZXIncyBzdGFjaywKLSAgICAvLyB3aGljaCBtYXkgbm90IGJlIHRoZSBzYW1lIHRoaW5nIGFzIHRoZSB2YWx1ZSBmb3VuZCBpbiB0aGUKLSAgICAvLyBTb3VyY2VMb2NhdG9ycyBzdGFjay4KLSAgICBTdHJpbmcgYmFzZSA9IChTdHJpbmcpIChtX2Jhc2VJZGVudGlmaWVycy5pc0VtcHR5KCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG51bGwgOiBtX2Jhc2VJZGVudGlmaWVycy5wZWVrKCkpOwotCi0gICAgLy8gT3RoZXJ3aXNlIHRyeSB0aGUgc3R5bGVzaGVldC4KLSAgICBpZiAobnVsbCA9PSBiYXNlKQotICAgIHsKLSAgICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9IGdldExvY2F0b3IoKTsKLQotICAgICAgYmFzZSA9IChudWxsID09IGxvY2F0b3IpID8gIiIgOiBsb2NhdG9yLmdldFN5c3RlbUlkKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJhc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHRvcCBvZiB0aGlzIHN0YWNrIHNob3VsZCBjb250YWluIHRoZSBjdXJyZW50bHkgcHJvY2Vzc2VkCi0gICAqIHN0eWxlc2hlZXQgU0FYIGxvY2F0b3Igb2JqZWN0LgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2sgPSBuZXcgU3RhY2soKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IHN0eWxlc2hlZXQgTG9jYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IGxvY2F0b3Igb2JqZWN0LgotICAgKi8KLSAgcHVibGljIFNBWFNvdXJjZUxvY2F0b3IgZ2V0TG9jYXRvcigpCi0gIHsKLQotICAgIGlmIChtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2suaXNFbXB0eSgpKQotICAgIHsKLSAgICAgIFNBWFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9IG5ldyBTQVhTb3VyY2VMb2NhdG9yKCk7Ci0KLSAgICAgIGxvY2F0b3Iuc2V0U3lzdGVtSWQodGhpcy5nZXRTdHlsZXNoZWV0UHJvY2Vzc29yKCkuZ2V0RE9Nc3lzdGVtSUQoKSk7Ci0KLSAgICAgIHJldHVybiBsb2NhdG9yOwotCi0gICAgICAvLyBtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2sucHVzaChsb2NhdG9yKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gKChTQVhTb3VyY2VMb2NhdG9yKSBtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2sucGVlaygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBBIHN0YWNrIG9mIFVSTCBocmVmcyBmb3IgaW1wb3J0ZWQgc3R5bGVzaGVldHMuICBUaGlzIGlzCi0gICAqIHVzZWQgdG8gZGlhZ25vc2UgY2lyY3VsYXIgaW1wb3J0cy4KLSAgICovCi0gIHByaXZhdGUgU3RhY2sgbV9pbXBvcnRTdGFjayA9IG5ldyBTdGFjaygpOwotCi0gIC8qKgotICAgKiBQdXNoIGFuIGltcG9ydCBocmVmIG9udG8gdGhlIHN0eWxlc2hlZXQgc3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSBocmVmVXJsIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgVVJMIGZvciB0aGUgY3VycmVudCBpbXBvcnRlZAotICAgKiBzdHlsZXNoZWV0LgotICAgKi8KLSAgdm9pZCBwdXNoSW1wb3J0VVJMKFN0cmluZyBocmVmVXJsKQotICB7Ci0gICAgbV9pbXBvcnRTdGFjay5wdXNoKGhyZWZVcmwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlZSBpZiB0aGUgaW1wb3J0ZWQgc3R5bGVzaGVldCBzdGFjayBhbHJlYWR5IGNvbnRhaW5zCi0gICAqIHRoZSBnaXZlbiBVUkwuICBVc2VkIHRvIHRlc3QgZm9yIHJlY3Vyc2l2ZSBpbXBvcnRzLgotICAgKgotICAgKiBAcGFyYW0gaHJlZlVybCBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBVUkwgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIFVSTCBpcyBvbiB0aGUgaW1wb3J0IHN0YWNrLgotICAgKi8KLSAgYm9vbGVhbiBpbXBvcnRTdGFja0NvbnRhaW5zKFN0cmluZyBocmVmVXJsKQotICB7Ci0gICAgcmV0dXJuIHN0YWNrQ29udGFpbnMobV9pbXBvcnRTdGFjaywgaHJlZlVybCk7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIGFuIGltcG9ydCBocmVmIGZyb20gdGhlIHN0eWxlc2hlZXQgc3RhY2suCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBpbXBvcnQgVVJMIHRoYXQgd2FzIHBvcHBlZC4KLSAgICovCi0gIFN0cmluZyBwb3BJbXBvcnRVUkwoKQotICB7Ci0gICAgcmV0dXJuIChTdHJpbmcpIG1faW1wb3J0U3RhY2sucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhpcyBpcyBzZXQgdG8gdHJ1ZSwgd2UndmUgYWxyZWFkeSB3YXJuZWQgYWJvdXQgdXNpbmcgdGhlCi0gICAqIG9sZGVyIFhTTFQgbmFtZXNwYWNlIFVSTC4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiB3YXJuZWRBYm91dE9sZFhTTFROYW1lc3BhY2UgPSBmYWxzZTsKLQotICAvKiogU3RhY2sgb2YgTmFtZXNwYWNlU3VwcG9ydCBvYmplY3RzLiAqLwotICBTdGFjayBtX25zU3VwcG9ydFN0YWNrID0gbmV3IFN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIFB1c2ggYSBuZXcgTmFtZXNwYWNlU3VwcG9ydCBpbnN0YW5jZS4KLSAgICovCi0gIHZvaWQgcHVzaE5ld05hbWVzcGFjZVN1cHBvcnQoKQotICB7Ci0gICAgbV9uc1N1cHBvcnRTdGFjay5wdXNoKG5ldyBOYW1lc3BhY2VTdXBwb3J0MigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgTmFtZXNwYWNlU3VwcG9ydCBvYmplY3QuCi0gICAqCi0gICAqLwotICB2b2lkIHBvcE5hbWVzcGFjZVN1cHBvcnQoKQotICB7Ci0gICAgbV9uc1N1cHBvcnRTdGFjay5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgTmFtZXNwYWNlU3VwcG9ydCBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgTmFtZXNwYWNlU3VwcG9ydCBvYmplY3QsCi0gICAqIHdoaWNoIGlzIHRoZSB0b3Agb2YgdGhlIG5hbWVzcGFjZSBzdXBwb3J0IHN0YWNrLgotICAgKi8KLSAgTmFtZXNwYWNlU3VwcG9ydCBnZXROYW1lc3BhY2VTdXBwb3J0KCkKLSAgewotICAgIHJldHVybiAoTmFtZXNwYWNlU3VwcG9ydCkgbV9uc1N1cHBvcnRTdGFjay5wZWVrKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG9yaWdpbmF0aW5nIG5vZGUgaWYgdGhlIGN1cnJlbnQgc3R5bGVzaGVldCBpcyBiZWluZyBjcmVhdGVkCi0gICAqICBmcm9tIGEgRE9NLgotICAgKiAgQHNlZSBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlQ29uc3VtZXIKLSAgICovCi0gIHByaXZhdGUgTm9kZSBtX29yaWdpbmF0aW5nTm9kZTsKLQotICAvKioKLSAgICogU2V0IHRoZSBub2RlIHRoYXQgaXMgb3JpZ2luYXRpbmcgdGhlIFNBWCBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIG4gUmVmZXJlbmNlIHRvIG5vZGUgdGhhdCBvcmlnaW5hdGVkIHRoZSBjdXJyZW50IGV2ZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueG1sLnV0aWxzLk5vZGVDb25zdW1lcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3JpZ2luYXRpbmdOb2RlKE5vZGUgbikKLSAgewotICAgIG1fb3JpZ2luYXRpbmdOb2RlID0gbjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5vZGUgdGhhdCBpcyBvcmlnaW5hdGluZyB0aGUgU0FYIGV2ZW50LgotICAgKgotICAgKiBAcmV0dXJuIFJlZmVyZW5jZSB0byBub2RlIHRoYXQgb3JpZ2luYXRlZCB0aGUgY3VycmVudCBldmVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlQ29uc3VtZXIKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldE9yaWdpbmF0aW5nTm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9vcmlnaW5hdGluZ05vZGU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTdGFjayBvZiBib29sZWFucyB0aGF0IGFyZSBwdXNoZWQgYW5kIHBvcHBlZCBpbiBzdGFydC9lbmRFbGVtZW50IGRlcGVuZGluZyAKLSAgICogb24gdGhlIHZhbHVlIG9mIHhtbDpzcGFjZT1kZWZhdWx0L3ByZXNlcnZlLgotICAgKi8KLSAgcHJpdmF0ZSBCb29sU3RhY2sgbV9zcGFjZVByZXNlcnZlU3RhY2sgPSBuZXcgQm9vbFN0YWNrKCk7Ci0gIAotICAvKioKLSAgICogUmV0dXJuIGJvb2xlYW4gdmFsdWUgZnJvbSB0aGUgc3BhY2VQcmVzZXJ2ZSBzdGFjayBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIAotICAgKiBvZiB4bWw6c3BhY2U9ZGVmYXVsdC9wcmVzZXJ2ZS4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBzcGFjZSBzaG91bGQgYmUgcHJlc2VydmVkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAqLwotICBib29sZWFuIGlzU3BhY2VQcmVzZXJ2ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9zcGFjZVByZXNlcnZlU3RhY2sucGVlaygpOwotICB9Ci0gIAotICAvKioKLSAgICogUG9wIGJvb2xlYW4gdmFsdWUgZnJvbSB0aGUgc3BhY2VQcmVzZXJ2ZSBzdGFjay4KLSAgICovCi0gIHZvaWQgcG9wU3BhY2VIYW5kbGluZygpCi0gIHsKLSAgICBtX3NwYWNlUHJlc2VydmVTdGFjay5wb3AoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFB1c2ggYm9vbGVhbiB2YWx1ZSBvbiB0byB0aGUgc3BhY2VQcmVzZXJ2ZSBzdGFjay4KLSAgICogCi0gICAqIEBwYXJhbSBiIHRydWUgaWYgc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZCwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKi8KLSAgdm9pZCBwdXNoU3BhY2VIYW5kbGluZyhib29sZWFuIGIpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gIHsKLSAgICBtX3NwYWNlUHJlc2VydmVTdGFjay5wdXNoKGIpOwotICB9Ci0gIAotICAvKioKLSAgICogUHVzaCBib29sZWFuIHZhbHVlIG9uIHRvIHRoZSBzcGFjZVByZXNlcnZlIHN0YWNrIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgCi0gICAqIG9mIHhtbDpzcGFjZT1kZWZhdWx0L3ByZXNlcnZlLgotICAgKiAKLSAgICogQHBhcmFtIGF0dHJzIGxpc3Qgb2YgYXR0cmlidXRlcyB0aGF0IHdlcmUgcGFzc2VkIHRvIHN0YXJ0RWxlbWVudC4KLSAgICovCi0gIHZvaWQgcHVzaFNwYWNlSGFuZGxpbmcoQXR0cmlidXRlcyBhdHRycykKLSAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgeyAgICAKLSAgICBTdHJpbmcgdmFsdWUgPSBhdHRycy5nZXRWYWx1ZSgieG1sOnNwYWNlIik7Ci0gICAgaWYobnVsbCA9PSB2YWx1ZSkKLSAgICB7Ci0gICAgICBtX3NwYWNlUHJlc2VydmVTdGFjay5wdXNoKG1fc3BhY2VQcmVzZXJ2ZVN0YWNrLnBlZWsoKSk7Ci0gICAgfQotICAgIGVsc2UgaWYodmFsdWUuZXF1YWxzKCJwcmVzZXJ2ZSIpKQotICAgIHsKLSAgICAgIG1fc3BhY2VQcmVzZXJ2ZVN0YWNrLnB1c2godHJ1ZSk7Ci0gICAgfQotICAgIGVsc2UgaWYodmFsdWUuZXF1YWxzKCJkZWZhdWx0IikpCi0gICAgewotICAgICAgbV9zcGFjZVByZXNlcnZlU3RhY2sucHVzaChmYWxzZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTQVhTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBnZXRMb2NhdG9yKCk7Ci0gICAgICBFcnJvckxpc3RlbmVyIGhhbmRsZXIgPSBtX3N0eWxlc2hlZXRQcm9jZXNzb3IuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBoYW5kbGVyLmVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFLCBudWxsKSwgbG9jYXRvcikpOyAvLyJJbGxlZ2FsIHZhbHVlIGZvciB4bWw6c3BhY2UiLCBsb2NhdG9yKSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbih0ZS5nZXRNZXNzYWdlKCksIGxvY2F0b3IsIHRlKTsKLSAgICAgIH0KLSAgICAgIG1fc3BhY2VQcmVzZXJ2ZVN0YWNrLnB1c2gobV9zcGFjZVByZXNlcnZlU3RhY2sucGVlaygpKTsKLSAgICB9Ci0gIH0KLX0KLQotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9TdHlsZXNoZWV0UElIYW5kbGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvU3R5bGVzaGVldFBJSGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZDJhYzc0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9TdHlsZXNoZWV0UElIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNjIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkRlZmF1bHRIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLQotLyoqCi0gKiBTZWFyY2ggZm9yIHRoZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBpbiBhbiBYTUwgZG9jdW1lbnQuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3htbC1zdHlsZXNoZWV0LyI+QXNzb2NpYXRpbmcgU3R5bGUgU2hlZXRzIHdpdGggWE1MIGRvY3VtZW50cywgVmVyc2lvbiAxLjA8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBTdHlsZXNoZWV0UElIYW5kbGVyIGV4dGVuZHMgRGVmYXVsdEhhbmRsZXIKLXsKLSAgLyoqIFRoZSBiYXNlSUQgb2YgdGhlIGRvY3VtZW50IGJlaW5nIHByb2Nlc3NlZC4gICovCi0gIFN0cmluZyBtX2Jhc2VJRDsKLQotICAvKiogVGhlIGRlc2lyZWQgbWVkaWEgY3JpdGVyaWEuICovCi0gIFN0cmluZyBtX21lZGlhOwotCi0gIC8qKiBUaGUgZGVzaXJlZCB0aXRsZSBjcml0ZXJpYS4gICovCi0gIFN0cmluZyBtX3RpdGxlOwotCi0gIC8qKiBUaGUgZGVzaXJlZCBjaGFyYWN0ZXIgc2V0IGNyaXRlcmlhLiAgICovCi0gIFN0cmluZyBtX2NoYXJzZXQ7Ci0KLSAgLyoqIEEgbGlzdCBvZiBTQVhTb3VyY2Ugb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBjcml0ZXJpYS4gICovCi0gIFZlY3RvciBtX3N0eWxlc2hlZXRzID0gbmV3IFZlY3RvcigpOwotICAKLSAgLy8gQWRkIGNvZGUgdG8gdXNlIGEgVVJJUmVzb2x2ZXIuIFBhdGNoIGZyb20gRG1pdHJpIElseWluLiAKLSAgCi0gIC8qKgotICAgKiBUaGUgb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAotICAgKiBvciBudWxsLgotICAgKi8KLSAgVVJJUmVzb2x2ZXIgbV91cmlSZXNvbHZlcjsKLQotICAvKioKLSAgICogR2V0IHRoZSBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIGluIGhyZWYgCi0gICAqIGluIHhtbC1zdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSByZXNvbHZlciBBbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBVUklSZXNvbHZlciBpbnRlcmZhY2UsCi0gICAqIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcikKLSAgewotICAgIG1fdXJpUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgdXNlZCB0byByZXNvbHZlIFVSSXMgaW4gaHJlZiAKLSAgICogaW4geG1sLXN0eWxlc2hlZXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgVVJJUmVzb2x2ZXIgdGhhdCB3YXMgc2V0IHdpdGggc2V0VVJJUmVzb2x2ZXIuCi0gICAqLwotICBwdWJsaWMgVVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fdXJpUmVzb2x2ZXI7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgU3R5bGVzaGVldFBJSGFuZGxlciBpbnN0YW5jZSB0aGF0IHdpbGwgc2VhcmNoIAotICAgKiBmb3IgeG1sLXN0eWxlc2hlZXQgUElzIGJhc2VkIG9uIHRoZSBnaXZlbiBjcml0ZXJpYS4KLSAgICoKLSAgICogQHBhcmFtIGJhc2VJRCBUaGUgYmFzZSBJRCBvZiB0aGUgWE1MIGRvY3VtZW50LCBuZWVkZWQgdG8gcmVzb2x2ZSAKLSAgICogICAgICAgICAgICAgICByZWxhdGl2ZSBJRHMuCi0gICAqIEBwYXJhbSBtZWRpYSBUaGUgZGVzaXJlZCBtZWRpYSBjcml0ZXJpYS4KLSAgICogQHBhcmFtIHRpdGxlIFRoZSBkZXNpcmVkIHRpdGxlIGNyaXRlcmlhLgotICAgKiBAcGFyYW0gY2hhcnNldCBUaGUgZGVzaXJlZCBjaGFyYWN0ZXIgc2V0IGNyaXRlcmlhLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRQSUhhbmRsZXIoU3RyaW5nIGJhc2VJRCwgU3RyaW5nIG1lZGlhLCBTdHJpbmcgdGl0bGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjaGFyc2V0KQotICB7Ci0KLSAgICBtX2Jhc2VJRCA9IGJhc2VJRDsKLSAgICBtX21lZGlhID0gbWVkaWE7Ci0gICAgbV90aXRsZSA9IHRpdGxlOwotICAgIG1fY2hhcnNldCA9IGNoYXJzZXQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBsYXN0IHN0eWxlc2hlZXQgZm91bmQgdGhhdCBtYXRjaCB0aGUgY29uc3RyYWludHMuCi0gICAqCi0gICAqIEByZXR1cm4gU291cmNlIG9iamVjdCB0aGF0IHJlZmVyZW5jZXMgdGhlIGxhc3Qgc3R5bGVzaGVldCByZWZlcmVuY2UgCi0gICAqICAgICAgICAgdGhhdCBtYXRjaGVzIHRoZSBjb25zdHJhaW50cy4KLSAgICovCi0gIHB1YmxpYyBTb3VyY2UgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoKQotICB7Ci0KLSAgICBpbnQgc3ogPSBtX3N0eWxlc2hlZXRzLnNpemUoKTsKLQotICAgIGlmIChzeiA+IDApCi0gICAgewotICAgICAgU291cmNlIHNvdXJjZSA9IChTb3VyY2UpIG1fc3R5bGVzaGVldHMuZWxlbWVudEF0KHN6LTEpOwotICAgICAgcmV0dXJuIHNvdXJjZTsgICAgICAKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogSGFuZGxlIHRoZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgotICAgKiAgICAgICAgICAgICBub25lIGlzIHN1cHBsaWVkLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94bWwtc3R5bGVzaGVldC8iPkFzc29jaWF0aW5nIFN0eWxlIFNoZWV0cyB3aXRoIFhNTCBkb2N1bWVudHMsIFZlcnNpb24gMS4wPC9hPgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHRhcmdldC5lcXVhbHMoInhtbC1zdHlsZXNoZWV0IikpCi0gICAgewotICAgICAgU3RyaW5nIGhyZWYgPSBudWxsOyAgLy8gQ0RBVEEgI1JFUVVJUkVECi0gICAgICBTdHJpbmcgdHlwZSA9IG51bGw7ICAvLyBDREFUQSAjUkVRVUlSRUQKLSAgICAgIFN0cmluZyB0aXRsZSA9IG51bGw7ICAvLyBDREFUQSAjSU1QTElFRAotICAgICAgU3RyaW5nIG1lZGlhID0gbnVsbDsgIC8vIENEQVRBICNJTVBMSUVECi0gICAgICBTdHJpbmcgY2hhcnNldCA9IG51bGw7ICAvLyBDREFUQSAjSU1QTElFRAotICAgICAgYm9vbGVhbiBhbHRlcm5hdGUgPSBmYWxzZTsgIC8vICh5ZXN8bm8pICJubyIKLSAgICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGRhdGEsICIgXHQ9IiwgdHJ1ZSk7Ci0gICAgICBib29sZWFuIGxvb2tlZEFoZWFkID0gZmFsc2U7IAotICAgICAgU291cmNlIHNvdXJjZSA9IG51bGw7Ci0KLSAgICAgIFN0cmluZyB0b2tlbiA9ICIiOwotICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICB7ICAgICAgICAKLSAgICAgICAgaWYgKCFsb29rZWRBaGVhZCkKLSAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIGxvb2tlZEFoZWFkID0gZmFsc2U7Ci0gICAgICAgIGlmICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpICYmIAotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIpIHx8IHRva2VuLmVxdWFscygiXHQiKSB8fCB0b2tlbi5lcXVhbHMoIj0iKSkpCi0gICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgCi0gICAgICAgIFN0cmluZyBuYW1lID0gdG9rZW47ICAKLSAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ0eXBlIikpCi0gICAgICAgIHsgCi0gICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkgJiYgCi0gICAgICAgICAgICAgICAodG9rZW4uZXF1YWxzKCIgIiApIHx8IHRva2VuLmVxdWFscygiXHQiKSB8fCB0b2tlbi5lcXVhbHMoIj0iKSkpCi0gICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICB0eXBlID0gdG9rZW4uc3Vic3RyaW5nKDEsIHRva2VuLmxlbmd0aCgpIC0gMSk7Ci0gICAgICAgICAgCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImhyZWYiKSkKLSAgICAgICAgewotICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIHdoaWxlICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpICYmIAotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIgKSB8fCB0b2tlbi5lcXVhbHMoIlx0IikgfHwgdG9rZW4uZXF1YWxzKCI9IikpKQotICAgICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgaHJlZiA9IHRva2VuOwotICAgICAgICAgIGlmICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgLy8gSWYgdGhlIGhyZWYgdmFsdWUgaGFzIHBhcmFtZXRlcnMgdG8gYmUgcGFzc2VkIHRvIGEgCi0gICAgICAgICAgICAvLyBzZXJ2bGV0KHNvbWV0aGluZyBsaWtlICJmb29iYXI/aWQ9MTIuLi4iKSwgCi0gICAgICAgICAgICAvLyB3ZSB3YW50IHRvIG1ha2Ugc3VyZSB3ZSBnZXQgdGhlbSBhZGRlZCB0bwotICAgICAgICAgICAgLy8gdGhlIGhyZWYgdmFsdWUuIFdpdGhvdXQgdGhpcyBjaGVjaywgd2Ugd291bGQgbW92ZSBvbiAKLSAgICAgICAgICAgIC8vIHRvIHRyeSB0byBwcm9jZXNzIGFub3RoZXIgYXR0cmlidXRlIGFuZCB0aGF0IHdvdWxkIGJlCi0gICAgICAgICAgICAvLyB3cm9uZy4KLSAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gc2V0IGxvb2tlZEFoZWFkIGhlcmUgdG8gZmxhZyB0aGF0IHdlCi0gICAgICAgICAgICAvLyBhbHJlYWR5IGhhdmUgdGhlIG5leHQgdG9rZW4uIAotICAgICAgICAgICAgd2hpbGUgKCB0b2tlbi5lcXVhbHMoIj0iKSAmJiB0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotICAgICAgICAgICAgeyAgCi0gICAgICAgICAgICAgIGhyZWYgPSBocmVmICsgdG9rZW4gKyB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgIGlmICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotICAgICAgICAgICAgICB7ICAKLSAgICAgICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgICBsb29rZWRBaGVhZCA9IHRydWU7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgaHJlZiA9IGhyZWYuc3Vic3RyaW5nKDEsIGhyZWYubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7IAotICAgICAgICAgICAgLy8gQWRkIGNvZGUgdG8gdXNlIGEgVVJJUmVzb2x2ZXIuIFBhdGNoIGZyb20gRG1pdHJpIElseWluLiAKLSAgICAgICAgICAgIGlmIChtX3VyaVJlc29sdmVyICE9IG51bGwpIAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBzb3VyY2UgPSBtX3VyaVJlc29sdmVyLnJlc29sdmUoaHJlZiwgbV9iYXNlSUQpOwotICAgICAgICAgICAgfSAKLSAgICAgICAgICAgZWxzZSAKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaHJlZiA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoaHJlZiwgbV9iYXNlSUQpOwotICAgICAgICAgICAgICBzb3VyY2UgPSBuZXcgU0FYU291cmNlKG5ldyBJbnB1dFNvdXJjZShocmVmKSk7Ci0gICAgICAgICAgICB9ICAgICAgICAgICAgCi0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygidGl0bGUiKSkKLSAgICAgICAgewotICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIHdoaWxlICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpICYmIAotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIgKSB8fCB0b2tlbi5lcXVhbHMoIlx0IikgfHwgdG9rZW4uZXF1YWxzKCI9IikpKQotICAgICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgdGl0bGUgPSB0b2tlbi5zdWJzdHJpbmcoMSwgdG9rZW4ubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibWVkaWEiKSkKLSAgICAgICAgewotICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIHdoaWxlICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpICYmIAotICAgICAgICAgICAgICAgKHRva2VuLmVxdWFscygiICIgKSB8fCB0b2tlbi5lcXVhbHMoIlx0IikgfHwgdG9rZW4uZXF1YWxzKCI9IikpKQotICAgICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgbWVkaWEgPSB0b2tlbi5zdWJzdHJpbmcoMSwgdG9rZW4ubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiY2hhcnNldCIpKQotICAgICAgICB7Ci0gICAgICAgICAgdG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgd2hpbGUgKHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkgJiYgCi0gICAgICAgICAgICAgICh0b2tlbi5lcXVhbHMoIiAiICkgfHwgdG9rZW4uZXF1YWxzKCJcdCIpIHx8IHRva2VuLmVxdWFscygiPSIpKSkKLSAgICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIGNoYXJzZXQgPSB0b2tlbi5zdWJzdHJpbmcoMSwgdG9rZW4ubGVuZ3RoKCkgLSAxKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiYWx0ZXJuYXRlIikpCi0gICAgICAgIHsKLSAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICB3aGlsZSAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSAmJiAKLSAgICAgICAgICAgICAgICh0b2tlbi5lcXVhbHMoIiAiICkgfHwgdG9rZW4uZXF1YWxzKCJcdCIpIHx8IHRva2VuLmVxdWFscygiPSIpKSkKLSAgICAgICAgICAgIHRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgIGFsdGVybmF0ZSA9IHRva2VuLnN1YnN0cmluZygxLCB0b2tlbi5sZW5ndGgoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAxKS5lcXVhbHMoInllcyIpOwotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgfQotCi0gICAgICBpZiAoKG51bGwgIT0gdHlwZSkgCi0gICAgICAgICAgJiYgKHR5cGUuZXF1YWxzKCJ0ZXh0L3hzbCIpIHx8IHR5cGUuZXF1YWxzKCJ0ZXh0L3htbCIpIHx8IHR5cGUuZXF1YWxzKCJhcHBsaWNhdGlvbi94bWwreHNsdCIpKSAgCi0gICAgICAgICAgJiYgKG51bGwgIT0gaHJlZikpCi0gICAgICB7Ci0gICAgICAgIGlmIChudWxsICE9IG1fbWVkaWEpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCAhPSBtZWRpYSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoIW1lZGlhLmVxdWFscyhtX21lZGlhKSkKLSAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCAhPSBtX2NoYXJzZXQpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCAhPSBjaGFyc2V0KQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmICghY2hhcnNldC5lcXVhbHMobV9jaGFyc2V0KSkKLSAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCAhPSBtX3RpdGxlKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gdGl0bGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKCF0aXRsZS5lcXVhbHMobV90aXRsZSkpCi0gICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9zdHlsZXNoZWV0cy5hZGRFbGVtZW50KHNvdXJjZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0gIAotICAKLSAgLyoqCi0gICAqIFRoZSBzcGVjIG5vdGVzIHRoYXQgIlRoZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGlzIGFsbG93ZWQgb25seSBpbiB0aGUgcHJvbG9nIG9mIGFuIFhNTCBkb2N1bWVudC4iLAotICAgKiBzbywgYXQgbGVhc3QgZm9yIHJpZ2h0IG5vdywgSSdtIGdvaW5nIHRvIGdvIGFoZWFkIGFuIHRocm93IGEgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICogaW4gb3JkZXIgdG8gc3RvcCB0aGUgcGFyc2UuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIHNwZWNpZmllZCBvciBkZWZhdWx0ZWQgYXR0cmlidXRlcy4KLSAgICoKLSAgICogQHRocm93cyBTdG9wUGFyc2VFeGNlcHRpb24gc2luY2UgdGhlcmUgY2FuIGJlIG5vIHZhbGlkIHhtbC1zdHlsZXNoZWV0IHByb2Nlc3NpbmcgCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RydWN0aW9ucyBwYXN0IHRoZSBmaXJzdCBlbGVtZW50LgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IFN0b3BQYXJzZUV4Y2VwdGlvbigpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODdkMzQ4Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAzMCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3NvcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlRyZWVXYWxrZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJZGVudGl0eUltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UckFYRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotaW1wb3J0IGphdmEuaW8uU3RyaW5nUmVhZGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi0vKioKLSAqIFRoZSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLCB3aGljaCBpbXBsZW1lbnRzIHRoZSBUUmFYIFRyYW5zZm9ybWVyRmFjdG9yeQotICogaW50ZXJmYWNlLCBwcm9jZXNzZXMgWFNMVCBzdHlsZXNoZWV0cyBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdAotICogKGEgU3R5bGVzaGVldFJvb3QpLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCBleHRlbmRzIFNBWFRyYW5zZm9ybWVyRmFjdG9yeQotewotCi0gIC8qKiAKLSAgICogVGhlIHBhdGgvZmlsZW5hbWUgb2YgdGhlIHByb3BlcnR5IGZpbGU6IFhTTFRJbmZvLnByb3BlcnRpZXMgIAotICAgKiBNYWludGVuYW5jZSBub3RlOiBzZWUgYWxzbyBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy5GdW5jU3lzdGVtUHJvcGVydHkuWFNMVF9QUk9QRVJUSUVTCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBYU0xUX1BST1BFUlRJRVMgPQotICAgICJvcmcvYXBhY2hlL3hhbGFuL3Jlcy9YU0xUSW5mby5wcm9wZXJ0aWVzIjsKLQotICAvKiogRmxhZyB0ZWxscyBpZiB0aGUgcHJvcGVydGllcyBmaWxlIGhhcyBiZWVuIGxvYWRlZCB0byB0aGUgc3lzdGVtICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJbml0ZWQgPSBmYWxzZTsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbAotICAgKgotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwoKQotICB7Ci0gICAgbG9hZFByb3BlcnR5RmlsZVRvU3lzdGVtKFhTTFRfUFJPUEVSVElFUyk7Ci0gIH0KLQotICAvKiogYSB6ZXJvIGxlbmd0aCBDbGFzcyBhcnJheSB1c2VkIGluIGxvYWRQcm9wZXJ0eUZpbGVUb1N5c3RlbSgpICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzW10gTk9fQ0xBU1NFUyA9IG5ldyBDbGFzc1swXTsKLQotICAvKiogYSB6ZXJvIGxlbmd0aCBPYmplY3QgYXJyYXkgdXNlZCBpbiBsb2FkUHJvcGVydHlGaWxlVG9TeXN0ZW0oKSAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBOT19PQkpTID0gbmV3IE9iamVjdFswXTsKLSAgCi0gIC8qKiBTdGF0aWMgc3RyaW5nIHRvIGJlIHVzZWQgZm9yIGluY3JlbWVudGFsIGZlYXR1cmUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRV9JTkNSRU1FTlRBTCA9ICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvaW5jcmVtZW50YWwiOwotCi0gIC8qKiBTdGF0aWMgc3RyaW5nIHRvIGJlIHVzZWQgZm9yIG9wdGltaXplIGZlYXR1cmUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkVBVFVSRV9PUFRJTUlaRSA9ICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvb3B0aW1pemUiOwotCi0KLSAgLyoqCi0gICAqIFJldHJpZXZlIGEgcHJvcGVyeSBidW5kbGUgZnJvbSBhIHNwZWNpZmllZCBmaWxlIGFuZCBsb2FkIGl0Ci0gICAqIGludCB0aGUgU3lzdGVtIHByb3BlcnRpZXMuCi0gICAqCi0gICAqIEBwYXJhbSBmaWxlIFRoZSBwcm9wZXJ0aWVzIGZpbGUgdG8gYmUgcHJvY2Vzc2VkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkUHJvcGVydHlGaWxlVG9TeXN0ZW0oU3RyaW5nIGZpbGUpCi0gIHsKLQotICAgIGlmIChmYWxzZSA9PSBpc0luaXRlZCkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOwotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAgICAgICB0cnkgewotICAgICAgICAgICAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIGdldENDTCA9IFRocmVhZC5jbGFzcy5nZXRNZXRob2QoImdldENvbnRleHRDbGFzc0xvYWRlciIsIE5PX0NMQVNTRVMpOwotICAgICAgICAgICAgaWYgKGdldENDTCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgIENsYXNzTG9hZGVyIGNvbnRleHRDbGFzc0xvYWRlciA9IChDbGFzc0xvYWRlcikgZ2V0Q0NMLmludm9rZShUaHJlYWQuY3VycmVudFRocmVhZCgpLCBOT19PQkpTKTsKLSAgICAgICAgICAgICAgaXMgPSBjb250ZXh0Q2xhc3NMb2FkZXIuZ2V0UmVzb3VyY2VBc1N0cmVhbShmaWxlKTsgLy8gZmlsZSBzaG91bGQgYmUgYWxyZWFkeSBmdWxseSBzcGVjaWZpZWQKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgICAgIC8vIE5PVEUhIEZvciB0aGUgYmVsb3cgZ2V0UmVzb3VyY2VBc1N0cmVhbSBpbiBTdW4gSkRLIDEuMS44TQotICAgICAgICAgICAgLy8gIHdlIGFwcGFyZW50bHkgbXVzdCBhZGQgdGhlIGxlYWRpbmcgc2xhc2ggY2hhcmFjdGVyIC0gSSAKLSAgICAgICAgICAgIC8vICBkb24ndCBrbm93IHdoeSwgYnV0IGlmIGl0J3Mgbm90IHRoZXJlLCB3ZSB0aHJvdyBhbiBOUEUgZnJvbSB0aGUgYmVsb3cgbG9hZGluZwotICAgICAgICAgICAgaXMgPSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oIi8iICsgZmlsZSk7IC8vIGZpbGUgc2hvdWxkIGJlIGFscmVhZHkgZnVsbHkgc3BlY2lmaWVkCi0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gZ2V0IGEgYnVmZmVyZWQgdmVyc2lvbgotICAgICAgICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpOwotCi0gICAgICAgICAgcHJvcHMubG9hZChiaXMpOyAgLy8gYW5kIGxvYWQgdXAgdGhlIHByb3BlcnR5IGJhZyBmcm9tIHRoaXMKLSAgICAgICAgICBiaXMuY2xvc2UoKTsgIC8vIGNsb3NlIG91dCBhZnRlciByZWFkaW5nCi0KLSAgICAgICAgICAvLyBPSywgbm93IHdlIG9ubHkgd2FudCB0byBzZXQgc3lzdGVtIHByb3BlcnRpZXMgdGhhdCAKLSAgICAgICAgICAvLyBhcmUgbm90IGFscmVhZHkgc2V0LgotICAgICAgICAgIFByb3BlcnRpZXMgc3lzdGVtUHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOwotICAgICAgICAgIEVudW1lcmF0aW9uIHByb3BFbnVtID0gcHJvcHMucHJvcGVydHlOYW1lcygpOwotCi0gICAgICAgICAgd2hpbGUgKHByb3BFbnVtLmhhc01vcmVFbGVtZW50cygpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyBwcm9wID0gKFN0cmluZykgcHJvcEVudW0ubmV4dEVsZW1lbnQoKTsKLQotICAgICAgICAgICAgaWYgKCFzeXN0ZW1Qcm9wcy5jb250YWluc0tleShwcm9wKSkKLSAgICAgICAgICAgICAgc3lzdGVtUHJvcHMucHV0KHByb3AsIHByb3BzLmdldFByb3BlcnR5KHByb3ApKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydGllcyhzeXN0ZW1Qcm9wcyk7Ci0KLSAgICAgICAgICBpc0luaXRlZCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCl7fQotICAgICAgfQotICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgewotCi0gICAgICAgIC8vIEluIHRoaXMgY2FzZSB0aGUgY2FsbGVyIGlzIHJlcXVpcmVkIHRvIGhhdmUgCi0gICAgICAgIC8vIHRoZSBuZWVkZWQgYXR0cmlidXRlcyBhbHJlYWR5IGRlZmluZWQuCi0gICAgICB9Ci0gICAgfQotICB9Ci0KLXB1YmxpYyBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlcyBwcm9jZXNzRnJvbU5vZGUoTm9kZSBub2RlKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgVGVtcGxhdGVzSGFuZGxlciBidWlsZGVyID0gbmV3VGVtcGxhdGVzSGFuZGxlcigpOwotICAgICAgVHJlZVdhbGtlciB3YWxrZXIgPSBuZXcgVHJlZVdhbGtlcihidWlsZGVyLCBuZXcgb3JnLmFwYWNoZS54cGF0aC5ET00ySGVscGVyKCksIGJ1aWxkZXIuZ2V0U3lzdGVtSWQoKSk7Ci0KLSAgICAgIHdhbGtlci50cmF2ZXJzZShub2RlKTsKLQotICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0VGVtcGxhdGVzKCk7Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgaWYgKG1fZXJyb3JMaXN0ZW5lciAhPSBudWxsKQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIG1fZXJyb3JMaXN0ZW5lci5mYXRhbEVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleCkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0KLSAgICAgICAgLy8gU2hvdWxkIHJlbW92ZSB0aGlzIGxhdGVyLi4uIGJ1dCByaWdodCBub3cgZGlhZ25vc3RpY3MgZnJvbSAKLSAgICAgICAgLy8gVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGFyZSBub3QgZ29vZC4KLSAgICAgICAgLy8gc2UucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCwgbnVsbCksIHNlKTsgLy8icHJvY2Vzc0Zyb21Ob2RlIGZhaWxlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zZSk7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gdGNlKQotICAgIHsKLSAgICAgIC8vIEFzc3VtZSBpdCdzIGFscmVhZHkgYmVlbiByZXBvcnRlZCB0byB0aGUgZXJyb3IgbGlzdGVuZXIuCi0gICAgICB0aHJvdyB0Y2U7Ci0gICAgfQotICAgLyogY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRjZSkKLSAgICB7Ci0gICAgICAvLyBBc3N1bWUgaXQncyBhbHJlYWR5IGJlZW4gcmVwb3J0ZWQgdG8gdGhlIGVycm9yIGxpc3RlbmVyLgotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbih0Y2UuZ2V0TWVzc2FnZSgpLCB0Y2UpOwotICAgIH0qLwotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBpZiAobV9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgbV9lcnJvckxpc3RlbmVyLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXgpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotICAgICAgZWxzZQotCi0gICAgICAgIC8vIFNob3VsZCByZW1vdmUgdGhpcyBsYXRlci4uLiBidXQgcmlnaHQgbm93IGRpYWdub3N0aWNzIGZyb20gCi0gICAgICAgIC8vIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBhcmUgbm90IGdvb2QuCi0gICAgICAgIC8vIHNlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BST0NFU1NGUk9NTk9ERV9GQUlMRUQsIG51bGwpLCBlKTsgLy8icHJvY2Vzc0Zyb21Ob2RlIGZhaWxlZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHN5c3RlbUlEIHRoYXQgd2FzIHNwZWNpZmllZCBpbgotICAgKiBwcm9jZXNzRnJvbU5vZGUoTm9kZSBub2RlLCBTdHJpbmcgc3lzdGVtSUQpLgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9ET01zeXN0ZW1JRCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzcGVjaWZpZWQgaW4KLSAgICogcHJvY2Vzc0Zyb21Ob2RlKE5vZGUgbm9kZSwgU3RyaW5nIHN5c3RlbUlEKS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3lzdGVtSUQsIG9yIG51bGwuCi0gICAqLwotICBTdHJpbmcgZ2V0RE9Nc3lzdGVtSUQoKQotICB7Ci0gICAgcmV0dXJuIG1fRE9Nc3lzdGVtSUQ7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyB0aGUgc3R5bGVzaGVldCBmcm9tIGEgRE9NIHRyZWUsIGlmIHRoZQotICAgKiBwcm9jZXNzb3Igc3VwcG9ydHMgdGhlICJodHRwOi8veG1sLm9yZy90cmF4L2ZlYXR1cmVzL2RvbS9pbnB1dCIKLSAgICogZmVhdHVyZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgQSBET00gdHJlZSB3aGljaCBtdXN0IGNvbnRhaW4KLSAgICogdmFsaWQgdHJhbnNmb3JtIGluc3RydWN0aW9ucyB0aGF0IHRoaXMgcHJvY2Vzc29yIHVuZGVyc3RhbmRzLgotICAgKiBAcGFyYW0gc3lzdGVtSUQgVGhlIHN5c3RlbUlEIGZyb20gd2hlcmUgeHNsOmluY2x1ZGVzIGFuZCB4c2w6aW1wb3J0cwotICAgKiBzaG91bGQgYmUgcmVzb2x2ZWQgZnJvbS4KLSAgICoKLSAgICogQHJldHVybiBBIFRlbXBsYXRlcyBvYmplY3QgY2FwYWJsZSBvZiBiZWluZyB1c2VkIGZvciB0cmFuc2Zvcm1hdGlvbiBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICovCi0gIGphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzIHByb2Nlc3NGcm9tTm9kZShOb2RlIG5vZGUsIFN0cmluZyBzeXN0ZW1JRCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLQotICAgIG1fRE9Nc3lzdGVtSUQgPSBzeXN0ZW1JRDsKLQotICAgIHJldHVybiBwcm9jZXNzRnJvbU5vZGUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IElucHV0U291cmNlIHNwZWNpZmljYXRpb24ocykgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZQotICAgKiBnaXZlbiBkb2N1bWVudCBzcGVjaWZpZWQgaW4gdGhlIHNvdXJjZSBwYXJhbSwKLSAgICogdmlhIHRoZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAqIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXN0eWxlc2hlZXQvKSwgYW5kIHRoYXQgbWF0Y2hlcwotICAgKiB0aGUgZ2l2ZW4gY3JpdGVyaWEuICBOb3RlIHRoYXQgaXQgaXMgcG9zc2libGUgdG8gcmV0dXJuIHNldmVyYWwgc3R5bGVzaGVldHMKLSAgICogdGhhdCBtYXRjaCB0aGUgY3JpdGVyaWEsIGluIHdoaWNoIGNhc2UgdGhleSBhcmUgYXBwbGllZCBhcyBpZiB0aGV5IHdlcmUKLSAgICogYSBsaXN0IG9mIGltcG9ydHMgb3IgY2FzY2FkZXMuCi0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBET00yIGhhcyBpdCdzIG93biBtZWNoYW5pc20gZm9yIGRpc2NvdmVyaW5nIHN0eWxlc2hlZXRzLgotICAgKiBUaGVyZWZvcmUsIHRoZXJlIGlzbid0IGEgRE9NIHZlcnNpb24gb2YgdGhpcyBtZXRob2QuPC9wPgotICAgKgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBYTUwgc291cmNlIHRoYXQgaXMgdG8gYmUgc2VhcmNoZWQuCi0gICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuICBNYXkgYmUgbnVsbCwgaW4gd2hpY2gKLSAgICogICAgICAgICAgICAgIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgKiBAcGFyYW0gdGl0bGUgVGhlIHZhbHVlIG9mIHRoZSB0aXRsZSBhdHRyaWJ1dGUgdG8gbWF0Y2guICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gIE1heSBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIEEgU291cmNlIG9iamVjdCBjYXBhYmxlIG9mIGJlaW5nIHVzZWQgdG8gY3JlYXRlIGEgVGVtcGxhdGVzIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTb3VyY2UgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoCi0gICAgICAgICAgU291cmNlIHNvdXJjZSwgU3RyaW5nIG1lZGlhLCBTdHJpbmcgdGl0bGUsIFN0cmluZyBjaGFyc2V0KQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgYmFzZUlEOwotICAgIElucHV0U291cmNlIGlzb3VyY2UgPSBudWxsOwotICAgIE5vZGUgbm9kZSA9IG51bGw7Ci0gICAgWE1MUmVhZGVyIHJlYWRlciA9IG51bGw7Ci0KLSAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKQotICAgIHsKLSAgICAgIERPTVNvdXJjZSBkc291cmNlID0gKERPTVNvdXJjZSkgc291cmNlOwotCi0gICAgICBub2RlID0gZHNvdXJjZS5nZXROb2RlKCk7Ci0gICAgICBiYXNlSUQgPSBkc291cmNlLmdldFN5c3RlbUlkKCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpc291cmNlID0gU0FYU291cmNlLnNvdXJjZVRvSW5wdXRTb3VyY2Uoc291cmNlKTsKLSAgICAgIGJhc2VJRCA9IGlzb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLSAgICB9Ci0KLSAgICAvLyBXaGF0IEkgdHJ5IHRvIGRvIGhlcmUgaXMgcGFyc2UgdW50aWwgdGhlIGZpcnN0IHN0YXJ0RWxlbWVudAotICAgIC8vIGlzIGZvdW5kLCB0aGVuIHRocm93IGEgc3BlY2lhbCBleGNlcHRpb24gaW4gb3JkZXIgdG8gdGVybWluYXRlIAotICAgIC8vIHRoZSBwYXJzZS4KLSAgICBTdHlsZXNoZWV0UElIYW5kbGVyIGhhbmRsZXIgPSBuZXcgU3R5bGVzaGVldFBJSGFuZGxlcihiYXNlSUQsIG1lZGlhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUsIGNoYXJzZXQpOwotICAgIAotICAgIC8vIFVzZSBVUklSZXNvbHZlci4gUGF0Y2ggZnJvbSBEbWl0cmkgSWx5aW4gCi0gICAgaWYgKG1fdXJpUmVzb2x2ZXIgIT0gbnVsbCkgCi0gICAgewotICAgICAgaGFuZGxlci5zZXRVUklSZXNvbHZlcihtX3VyaVJlc29sdmVyKTsgCi0gICAgfQotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgIT0gbm9kZSkKLSAgICAgIHsKLSAgICAgICAgVHJlZVdhbGtlciB3YWxrZXIgPSBuZXcgVHJlZVdhbGtlcihoYW5kbGVyLCBuZXcgb3JnLmFwYWNoZS54cGF0aC5ET00ySGVscGVyKCksIGJhc2VJRCk7Ci0KLSAgICAgICAgd2Fsa2VyLnRyYXZlcnNlKG5vZGUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIFVzZSBKQVhQMS4xICggaWYgcG9zc2libGUgKQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9Ci0gICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCi0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyIGpheHBQYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCi0gICAgICAgICAgcmVhZGVyID0gamF4cFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgxLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBleDIpe30KLSAgICAgICAgY2F0Y2ggKEFic3RyYWN0TWV0aG9kRXJyb3IgYW1lKXt9Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKQotICAgICAgICB7Ci0gICAgICAgICAgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5lZWQgdG8gc2V0IG9wdGlvbnMhCi0gICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgICAgICAgcmVhZGVyLnBhcnNlKGlzb3VyY2UpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoU3RvcFBhcnNlRXhjZXB0aW9uIHNwZSkKLSAgICB7Ci0KLSAgICAgIC8vIE9LLCBnb29kLgotICAgIH0KLSAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICJnZXRBc3NvY2lhdGVkU3R5bGVzaGVldHMgZmFpbGVkIiwgc2UpOwotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICJnZXRBc3NvY2lhdGVkU3R5bGVzaGVldHMgZmFpbGVkIiwgaW9lKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gaGFuZGxlci5nZXRBc3NvY2lhdGVkU3R5bGVzaGVldCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBUcmFuc2Zvcm1lciBvYmplY3QgdGhhdCBwZXJmb3JtcyBhIGNvcHkKLSAgICogb2YgdGhlIHNvdXJjZSB0byB0aGUgcmVzdWx0LgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIEFuIG9iamVjdCB0aGF0IGhvbGRzIGEgVVJJLCBpbnB1dCBzdHJlYW0sIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIFRyYW5zZm9ybWVyIG9iamVjdCB0aGF0IG1heSBiZSB1c2VkIHRvIHBlcmZvcm0gYSB0cmFuc2Zvcm1hdGlvbgotICAgKiBpbiBhIHNpbmdsZSB0aHJlYWQsIG5ldmVyIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIE1heSB0aHJvdyB0aGlzIGR1cmluZwotICAgKiAgICAgICAgICAgIHRoZSBwYXJzZSB3aGVuIGl0IGlzIGNvbnN0cnVjdGluZyB0aGUKLSAgICogICAgICAgICAgICBUZW1wbGF0ZXMgb2JqZWN0IGFuZCBmYWlscy4KLSAgICovCi0gIHB1YmxpYyBUZW1wbGF0ZXNIYW5kbGVyIG5ld1RlbXBsYXRlc0hhbmRsZXIoKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgU3R5bGVzaGVldEhhbmRsZXIodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlLgotICAgKgotICAgKiA8cD5UaGUgZmVhdHVyZSBuYW1lIGlzIGFueSBmdWxseS1xdWFsaWZpZWQgVVJJLiAgSXQgaXMKLSAgICogcG9zc2libGUgZm9yIGFuIFRyYW5zZm9ybWVyRmFjdG9yeSB0byByZWNvZ25pemUgYSBmZWF0dXJlIG5hbWUgYnV0Ci0gICAqIHRvIGJlIHVuYWJsZSB0byByZXR1cm4gaXRzIHZhbHVlOyB0aGlzIGlzIGVzcGVjaWFsbHkgdHJ1ZQotICAgKiBpbiB0aGUgY2FzZSBvZiBhbiBhZGFwdGVyIGZvciBhIFNBWDEgUGFyc2VyLCB3aGljaCBoYXMKLSAgICogbm8gd2F5IG9mIGtub3dpbmcgd2hldGhlciB0aGUgdW5kZXJseWluZyBwYXJzZXIgaXMKLSAgICogdmFsaWRhdGluZywgZm9yIGV4YW1wbGUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZmVhdHVyZSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgLy8gVHJ5IGZpcnN0IHdpdGggaWRlbnRpdHkgY29tcGFyaXNvbiwgd2hpY2ggCi0gICAgLy8gd2lsbCBiZSBmYXN0ZXIuCi0gICAgaWYgKChET01SZXN1bHQuRkVBVFVSRSA9PSBuYW1lKSB8fCAoRE9NU291cmNlLkZFQVRVUkUgPT0gbmFtZSkKLSAgICAgICAgICAgIHx8IChTQVhSZXN1bHQuRkVBVFVSRSA9PSBuYW1lKSB8fCAoU0FYU291cmNlLkZFQVRVUkUgPT0gbmFtZSkKLSAgICAgICAgICAgIHx8IChTdHJlYW1SZXN1bHQuRkVBVFVSRSA9PSBuYW1lKQotICAgICAgICAgICAgfHwgKFN0cmVhbVNvdXJjZS5GRUFUVVJFID09IG5hbWUpCi0gICAgICAgICAgICB8fCAoU0FYVHJhbnNmb3JtZXJGYWN0b3J5LkZFQVRVUkUgPT0gbmFtZSkKLSAgICAgICAgICAgIHx8IChTQVhUcmFuc2Zvcm1lckZhY3RvcnkuRkVBVFVSRV9YTUxGSUxURVIgPT0gbmFtZSkpCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICBlbHNlIGlmICgoRE9NUmVzdWx0LkZFQVRVUkUuZXF1YWxzKG5hbWUpKQotICAgICAgICAgICAgIHx8IChET01Tb3VyY2UuRkVBVFVSRS5lcXVhbHMobmFtZSkpCi0gICAgICAgICAgICAgfHwgKFNBWFJlc3VsdC5GRUFUVVJFLmVxdWFscyhuYW1lKSkKLSAgICAgICAgICAgICB8fCAoU0FYU291cmNlLkZFQVRVUkUuZXF1YWxzKG5hbWUpKQotICAgICAgICAgICAgIHx8IChTdHJlYW1SZXN1bHQuRkVBVFVSRS5lcXVhbHMobmFtZSkpCi0gICAgICAgICAgICAgfHwgKFN0cmVhbVNvdXJjZS5GRUFUVVJFLmVxdWFscyhuYW1lKSkKLSAgICAgICAgICAgICB8fCAoU0FYVHJhbnNmb3JtZXJGYWN0b3J5LkZFQVRVUkUuZXF1YWxzKG5hbWUpKQotICAgICAgICAgICAgIHx8IChTQVhUcmFuc2Zvcm1lckZhY3RvcnkuRkVBVFVSRV9YTUxGSUxURVIuZXF1YWxzKG5hbWUpKSkKLSAgICAgIHJldHVybiB0cnVlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIG1fb3B0aW1pemUgPSB0cnVlOwotICAKLSAgLyoqCi0gICAqIEFsbG93cyB0aGUgdXNlciB0byBzZXQgc3BlY2lmaWMgYXR0cmlidXRlcyBvbiB0aGUgdW5kZXJseWluZwotICAgKiBpbXBsZW1lbnRhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlOyBCb29sZWFuIG9yIFN0cmluZz0idHJ1ZSJ8ImZhbHNlIgotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHVuZGVybHlpbmcKLSAgICogaW1wbGVtZW50YXRpb24gZG9lc24ndCByZWNvZ25pemUgdGhlIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgewotICAgIGlmIChuYW1lLmVxdWFscyhGRUFUVVJFX0lOQ1JFTUVOVEFMKSkKLSAgICB7Ci0gICAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4pCi0gICAgICB7Ci0gICAgICAgIC8vIEFjY2VwdCBhIEJvb2xlYW4gb2JqZWN0Li4KLSAgICAgICAgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXIuc2V0SW5jcmVtZW50YWwoKChCb29sZWFuKXZhbHVlKS5ib29sZWFuVmFsdWUoKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKQotICAgICAgewotICAgICAgICAvLyAuLiBvciBhIFN0cmluZyBvYmplY3QKLSAgICAgICAgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXIuc2V0SW5jcmVtZW50YWwoKG5ldyBCb29sZWFuKChTdHJpbmcpdmFsdWUpKS5ib29sZWFuVmFsdWUoKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIEdpdmUgYSBtb3JlIG1lYW5pbmdmdWwgZXJyb3IgbWVzc2FnZQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0JBRF9WQUxVRSwgbmV3IE9iamVjdFtde25hbWUsIHZhbHVlfSkpOyAvL25hbWUgKyAiIGJhZCB2YWx1ZSAiICsgdmFsdWUpOwotICAgICAgfQotCX0KLSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhGRUFUVVJFX09QVElNSVpFKSkKLSAgICB7Ci0gICAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIEJvb2xlYW4pCi0gICAgICB7Ci0gICAgICAgIC8vIEFjY2VwdCBhIEJvb2xlYW4gb2JqZWN0Li4KLSAgICAgICAgbV9vcHRpbWl6ZSA9ICgoQm9vbGVhbil2YWx1ZSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKQotICAgICAgewotICAgICAgICAvLyAuLiBvciBhIFN0cmluZyBvYmplY3QKLSAgICAgICAgbV9vcHRpbWl6ZSA9IChuZXcgQm9vbGVhbigoU3RyaW5nKXZhbHVlKSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIEdpdmUgYSBtb3JlIG1lYW5pbmdmdWwgZXJyb3IgbWVzc2FnZQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0JBRF9WQUxVRSwgbmV3IE9iamVjdFtde25hbWUsIHZhbHVlfSkpOyAvL25hbWUgKyAiIGJhZCB2YWx1ZSAiICsgdmFsdWUpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT1RfU1VQUE9SVEVELCBuZXcgT2JqZWN0W117bmFtZX0pKTsgLy9uYW1lICsgIm5vdCBzdXBwb3J0ZWQiKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWxsb3dzIHRoZSB1c2VyIHRvIHJldHJpZXZlIHNwZWNpZmljIGF0dHJpYnV0ZXMgb24gdGhlIHVuZGVybHlpbmcKLSAgICogaW1wbGVtZW50YXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqIEByZXR1cm4gdmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biBpZiB0aGUgdW5kZXJseWluZwotICAgKiBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHJlY29nbml6ZSB0aGUgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgewotICAgIC8vIFBsZWFzZSBpbXBsZW1lbnQgdGhpcyBtZXRob2QgZm9yIHRlc3RpbmcgcHVycG9zZXMgMjUtSnVuLTAxIC1zYwotICAgIGlmIChuYW1lLmVxdWFscyhGRUFUVVJFX0lOQ1JFTUVOVEFMKSkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORCwgbmV3IE9iamVjdFtde25hbWV9KSk7IC8vbmFtZSArICIgYXR0cmlidXRlIHZhbHVlIG5vdCBmb3VuZCIpOwotICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKEZFQVRVUkVfT1BUSU1JWkUpKQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5ELCBuZXcgT2JqZWN0W117bmFtZX0pKTsgLy9uYW1lICsgIiBhdHRyaWJ1dGUgdmFsdWUgbm90IGZvdW5kIik7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9BVFRSSUJfVkFMVUVfTk9UX1JFQ09HTklaRUQsIG5ldyBPYmplY3RbXXtuYW1lfSkpOyAvL25hbWUgKyAiIGF0dHJpYnV0ZSBub3QgcmVjb2duaXplZCIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYTUxGaWx0ZXIgdGhhdCB1c2VzIHRoZSBnaXZlbiBzb3VyY2UgYXMgdGhlCi0gICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIHNyYyBUaGUgc291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MRmlsdGVyIG9iamVjdCwgb3IgbnVsbCBpZiB0aGlzIGZlYXR1cmUgaXMgbm90IHN1cHBvcnRlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYTUxGaWx0ZXIgbmV3WE1MRmlsdGVyKFNvdXJjZSBzcmMpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0KLSAgICBUZW1wbGF0ZXMgdGVtcGxhdGVzID0gbmV3VGVtcGxhdGVzKHNyYyk7Ci0gICAgaWYoIHRlbXBsYXRlcz09bnVsbCApIHJldHVybiBudWxsOwotICAgIAotICAgIHJldHVybiBuZXdYTUxGaWx0ZXIodGVtcGxhdGVzKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE1MRmlsdGVyIHRoYXQgdXNlcyB0aGUgZ2l2ZW4gc291cmNlIGFzIHRoZQotICAgKiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBzcmMgVGhlIHNvdXJjZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgKgotICAgKiBAcGFyYW0gdGVtcGxhdGVzIG5vbi1udWxsIHJlZmVyZW5jZSB0byBUZW1wbGF0ZXMgb2JqZWN0LgotICAgKgotICAgKiBAcmV0dXJuIEFuIFhNTEZpbHRlciBvYmplY3QsIG9yIG51bGwgaWYgdGhpcyBmZWF0dXJlIGlzIG5vdCBzdXBwb3J0ZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihUZW1wbGF0ZXMgdGVtcGxhdGVzKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIHRyeSB7Ci0gICAgICByZXR1cm4gbmV3IFRyQVhGaWx0ZXIodGVtcGxhdGVzKTsKLSAgICB9IGNhdGNoKCBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gZXggKSB7Ci0gICAgICBpZiggbV9lcnJvckxpc3RlbmVyICE9IG51bGwpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICBtX2Vycm9yTGlzdGVuZXIuZmF0YWxFcnJvciggZXggKTsKLSAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBjYXRjaCggVHJhbnNmb3JtZXJFeGNlcHRpb24gZXgxICkgewotICAgICAgICAgIG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oZXgxKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgdGhyb3cgZXg7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVgKLSAgICogQ29udGVudEhhbmRsZXIgZXZlbnRzIGludG8gYSBSZXN1bHQsIGJhc2VkIG9uIHRoZSB0cmFuc2Zvcm1hdGlvbgotICAgKiBpbnN0cnVjdGlvbnMgc3BlY2lmaWVkIGJ5IHRoZSBhcmd1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIHNyYyBUaGUgc291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAqCi0gICAqIEByZXR1cm4gVHJhbnNmb3JtZXJIYW5kbGVyIHJlYWR5IHRvIHRyYW5zZm9ybSBTQVggZXZlbnRzLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoU291cmNlIHNyYykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLQotICAgIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBuZXdUZW1wbGF0ZXMoc3JjKTsKLSAgICBpZiggdGVtcGxhdGVzPT1udWxsICkgcmV0dXJuIG51bGw7Ci0gICAgCi0gICAgcmV0dXJuIG5ld1RyYW5zZm9ybWVySGFuZGxlcih0ZW1wbGF0ZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVgKLSAgICogQ29udGVudEhhbmRsZXIgZXZlbnRzIGludG8gYSBSZXN1bHQsIGJhc2VkIG9uIHRoZSBUZW1wbGF0ZXMgYXJndW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSB0ZW1wbGF0ZXMgVGhlIHNvdXJjZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgKgotICAgKiBAcmV0dXJuIFRyYW5zZm9ybWVySGFuZGxlciByZWFkeSB0byB0cmFuc2Zvcm0gU0FYIGV2ZW50cy4KLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKFRlbXBsYXRlcyB0ZW1wbGF0ZXMpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5IHsKLSAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciA9Ci0gICAgICAgIChUcmFuc2Zvcm1lckltcGwpIHRlbXBsYXRlcy5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgdHJhbnNmb3JtZXIuc2V0VVJJUmVzb2x2ZXIobV91cmlSZXNvbHZlcik7Ci0gICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgdGggPQotICAgICAgICAoVHJhbnNmb3JtZXJIYW5kbGVyKSB0cmFuc2Zvcm1lci5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKHRydWUpOwotCi0gICAgICByZXR1cm4gdGg7Ci0gICAgfSBjYXRjaCggVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4ICkgewotICAgICAgaWYoIG1fZXJyb3JMaXN0ZW5lciAhPSBudWxsICkgewotICAgICAgICB0cnkgewotICAgICAgICAgIG1fZXJyb3JMaXN0ZW5lci5mYXRhbEVycm9yKCBleCApOwotICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleDEgKSB7Ci0gICAgICAgICAgZXg9bmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihleDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICB0aHJvdyBleDsKLSAgICB9Ci0gICAgCi0gIH0KLQotLy8gIC8qKiBUaGUgaWRlbnRpdHkgdHJhbnNmb3JtIHN0cmluZywgZm9yIHN1cHBvcnQgb2YgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKCkKLS8vICAgKiAgYW5kIG5ld1RyYW5zZm9ybWVyKCkuICAqLwotLy8gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBpZGVudGl0eVRyYW5zZm9ybSA9Ci0vLyAgICAiPHhzbDpzdHlsZXNoZWV0ICIgKyAieG1sbnM6eHNsPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0nICIKLS8vICAgICsgInZlcnNpb249JzEuMCc+IiArICI8eHNsOnRlbXBsYXRlIG1hdGNoPScvfG5vZGUoKSc+IgotLy8gICAgKyAiPHhzbDpjb3B5LW9mIHNlbGVjdD0nLicvPiIgKyAiPC94c2w6dGVtcGxhdGU+IiArICI8L3hzbDpzdHlsZXNoZWV0PiI7Ci0vLwotLy8gIC8qKiBUaGUgaWRlbnRpdHkgdHJhbnNmb3JtIFRlbXBsYXRlcywgYnVpbHQgZnJvbSBpZGVudGl0eVRyYW5zZm9ybSwgCi0vLyAgICogIGZvciBzdXBwb3J0IG9mIG5ld1RyYW5zZm9ybWVySGFuZGxlcigpIGFuZCBuZXdUcmFuc2Zvcm1lcigpLiAgKi8KLS8vICBwcml2YXRlIHN0YXRpYyBUZW1wbGF0ZXMgbV9pZGVudGl0eVRlbXBsYXRlID0gbnVsbDsKLQotICAvKioKLSAgICogR2V0IGEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWAotICAgKiBDb250ZW50SGFuZGxlciBldmVudHMgaW50byBhIFJlc3VsdC4KLSAgICoKLSAgICogQHBhcmFtIHNyYyBUaGUgc291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAqCi0gICAqIEByZXR1cm4gVHJhbnNmb3JtZXJIYW5kbGVyIHJlYWR5IHRvIHRyYW5zZm9ybSBTQVggZXZlbnRzLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0vLyAgICBpZiAobnVsbCA9PSBtX2lkZW50aXR5VGVtcGxhdGUpCi0vLyAgICB7Ci0vLyAgICAgIHN5bmNocm9uaXplZCAoaWRlbnRpdHlUcmFuc2Zvcm0pCi0vLyAgICAgIHsKLS8vICAgICAgICBpZiAobnVsbCA9PSBtX2lkZW50aXR5VGVtcGxhdGUpCi0vLyAgICAgICAgewotLy8gICAgICAgICAgU3RyaW5nUmVhZGVyIHJlYWRlciA9IG5ldyBTdHJpbmdSZWFkZXIoaWRlbnRpdHlUcmFuc2Zvcm0pOwotLy8KLS8vICAgICAgICAgIG1faWRlbnRpdHlUZW1wbGF0ZSA9IG5ld1RlbXBsYXRlcyhuZXcgU3RyZWFtU291cmNlKHJlYWRlcikpOwotLy8gICAgICAgIH0KLS8vICAgICAgfQotLy8gICAgfQotLy8KLS8vICAgIHJldHVybiBuZXdUcmFuc2Zvcm1lckhhbmRsZXIobV9pZGVudGl0eVRlbXBsYXRlKTsKLSAgICByZXR1cm4gbmV3IFRyYW5zZm9ybWVySWRlbnRpdHlJbXBsKCk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyB0aGUgc291cmNlIGludG8gYSBUcmFuc2Zvcm1lciBvYmplY3QuICBDYXJlIG11c3QKLSAgICogYmUgZ2l2ZW4gdG8ga25vdyB0aGF0IHRoaXMgb2JqZWN0IGNhbiBub3QgYmUgdXNlZCBjb25jdXJyZW50bHkKLSAgICogaW4gbXVsdGlwbGUgdGhyZWFkcy4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSBBbiBvYmplY3QgdGhhdCBob2xkcyBhIFVSTCwgaW5wdXQgc3RyZWFtLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lciBvYmplY3QgY2FwYWJsZSBvZgotICAgKiBiZWluZyB1c2VkIGZvciB0cmFuc2Zvcm1hdGlvbiBwdXJwb3NlcyBpbiBhIHNpbmdsZSB0aHJlYWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIE1heSB0aHJvdyB0aGlzIGR1cmluZyB0aGUgcGFyc2Ugd2hlbiBpdAotICAgKiAgICAgICAgICAgIGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzIG9iamVjdCBhbmQgZmFpbHMuCi0gICAqLwotICBwdWJsaWMgVHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoU291cmNlIHNvdXJjZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkgewotICAgICAgVGVtcGxhdGVzIHRtcGw9bmV3VGVtcGxhdGVzKCBzb3VyY2UgKTsKLSAgICAgIC8qIHRoaXMgY2FuIGhhcHBlbiBpZiBhbiBFcnJvckxpc3RlbmVyIGlzIHByZXNlbnQgYW5kIGl0IGRvZXNuJ3QKLSAgICAgICAgIHRocm93IGFueSBleGNlcHRpb24gaW4gZmF0YWxFcnJvci4gCi0gICAgICAgICBUaGUgc3BlYyBzYXlzOiAiYSBUcmFuc2Zvcm1lciBtdXN0IHVzZSB0aGlzIGludGVyZmFjZQotICAgICAgICAgaW5zdGVhZCBvZiB0aHJvd2luZyBhbiBleGNlcHRpb24iIC0gdGhlIG5ld1RlbXBsYXRlcygpIGRvZXMKLSAgICAgICAgIHRoYXQsIGFuZCByZXR1cm5zIG51bGwuCi0gICAgICAqLwotICAgICAgaWYoIHRtcGw9PW51bGwgKSByZXR1cm4gbnVsbDsKLSAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdG1wbC5uZXdUcmFuc2Zvcm1lcigpOwotICAgICAgdHJhbnNmb3JtZXIuc2V0VVJJUmVzb2x2ZXIobV91cmlSZXNvbHZlcik7Ci0gICAgICByZXR1cm4gdHJhbnNmb3JtZXI7Ci0gICAgfSBjYXRjaCggVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4ICkgewotICAgICAgaWYoIG1fZXJyb3JMaXN0ZW5lciAhPSBudWxsICkgewotICAgICAgICB0cnkgewotICAgICAgICAgIG1fZXJyb3JMaXN0ZW5lci5mYXRhbEVycm9yKCBleCApOwotICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGNhdGNoKCBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleDEgKSB7Ci0gICAgICAgICAgZXg9bmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiggZXgxICk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHRocm93IGV4OwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgVHJhbnNmb3JtZXIgb2JqZWN0IHRoYXQgcGVyZm9ybXMgYSBjb3B5Ci0gICAqIG9mIHRoZSBzb3VyY2UgdG8gdGhlIHJlc3VsdC4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSBBbiBvYmplY3QgdGhhdCBob2xkcyBhIFVSTCwgaW5wdXQgc3RyZWFtLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lciBvYmplY3QgY2FwYWJsZSBvZgotICAgKiBiZWluZyB1c2VkIGZvciB0cmFuc2Zvcm1hdGlvbiBwdXJwb3NlcyBpbiBhIHNpbmdsZSB0aHJlYWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIE1heSB0aHJvdyB0aGlzIGR1cmluZwotICAgKiAgICAgICAgICAgIHRoZSBwYXJzZSB3aGVuIGl0IGlzIGNvbnN0cnVjdGluZyB0aGUKLSAgICogICAgICAgICAgICBUZW1wbGF0ZXMgb2JqZWN0IGFuZCBpdCBmYWlscy4KLSAgICovCi0gIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0vLyAgICBpZiAobnVsbCA9PSBtX2lkZW50aXR5VGVtcGxhdGUpCi0vLyAgICB7Ci0vLyAgICAgIHN5bmNocm9uaXplZCAoaWRlbnRpdHlUcmFuc2Zvcm0pCi0vLyAgICAgIHsKLS8vICAgICAgICBpZiAobnVsbCA9PSBtX2lkZW50aXR5VGVtcGxhdGUpCi0vLyAgICAgICAgewotLy8gICAgICAgICAgU3RyaW5nUmVhZGVyIHJlYWRlciA9IG5ldyBTdHJpbmdSZWFkZXIoaWRlbnRpdHlUcmFuc2Zvcm0pOwotLy8KLS8vICAgICAgICAgIG1faWRlbnRpdHlUZW1wbGF0ZSA9IG5ld1RlbXBsYXRlcyhuZXcgU3RyZWFtU291cmNlKHJlYWRlcikpOwotLy8gICAgICAgIH0KLS8vICAgICAgfQotLy8gICAgfQotLy8KLS8vICAgIHJldHVybiBtX2lkZW50aXR5VGVtcGxhdGUubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgIHJldHVybiBuZXcgVHJhbnNmb3JtZXJJZGVudGl0eUltcGwoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIHRoZSBzb3VyY2UgaW50byBhIFRlbXBsYXRlcyBvYmplY3QsIHdoaWNoIGlzIGxpa2VseQotICAgKiBhIGNvbXBpbGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzb3VyY2UuIFRoaXMgVGVtcGxhdGVzIG9iamVjdAotICAgKiBtYXkgdGhlbiBiZSB1c2VkIGNvbmN1cnJlbnRseSBhY3Jvc3MgbXVsdGlwbGUgdGhyZWFkcy4gIENyZWF0aW5nCi0gICAqIGEgVGVtcGxhdGVzIG9iamVjdCBhbGxvd3MgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBkbyBkZXRhaWxlZAotICAgKiBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gb2YgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCB3aXRob3V0Ci0gICAqIHBlbmFsaXppbmcgcnVudGltZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSBBbiBvYmplY3QgdGhhdCBob2xkcyBhIFVSTCwgaW5wdXQgc3RyZWFtLCBldGMuCi0gICAqIEByZXR1cm4gQSBUZW1wbGF0ZXMgb2JqZWN0IGNhcGFibGUgb2YgYmVpbmcgdXNlZCBmb3IgdHJhbnNmb3JtYXRpb24gcHVycG9zZXMuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIE1heSB0aHJvdyB0aGlzIGR1cmluZyB0aGUgcGFyc2Ugd2hlbiBpdAotICAgKiAgICAgICAgICAgIGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzIG9iamVjdCBhbmQgZmFpbHMuCi0gICAqLwotICBwdWJsaWMgVGVtcGxhdGVzIG5ld1RlbXBsYXRlcyhTb3VyY2Ugc291cmNlKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0gICAgVGVtcGxhdGVzSGFuZGxlciBidWlsZGVyID0gbmV3VGVtcGxhdGVzSGFuZGxlcigpOwotICAgIFN0cmluZyBiYXNlSUQgPSBzb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLQotICAgIGlmIChudWxsID09IGJhc2VJRCkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGN1cnJlbnREaXIgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuZGlyIik7Ci0gICAgICAgIAotICAgICAgICBpZiAoY3VycmVudERpci5zdGFydHNXaXRoKGphdmEuaW8uRmlsZS5zZXBhcmF0b3IpKQotICAgICAgICAgIGJhc2VJRCA9ICJmaWxlOi8vIiArIGN1cnJlbnREaXIgKyBqYXZhLmlvLkZpbGUuc2VwYXJhdG9yQ2hhcgotICAgICAgICAgICAgICAgICAgICsgc291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgYmFzZUlEID0gImZpbGU6Ly8vIiArIGN1cnJlbnREaXIgKyBqYXZhLmlvLkZpbGUuc2VwYXJhdG9yQ2hhcgotICAgICAgICAgICAgICAgICAgICsgc291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgewotCi0gICAgICAgIC8vIEZvciB1bnRydXN0ZWQgYXBwbGV0IGNhc2UsIHVzZXIuZGlyIGlzIG91dHNpZGUgdGhlIHNhbmRib3ggCi0gICAgICAgIC8vICBhbmQgbm90IGFjY2Vzc2libGU6IGp1c3QgbGVhdmUgYmFzZUlEIGFzIG51bGwgKC1zYiAmIC1zYykKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBiYXNlSUQgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKGJhc2VJRCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24odGUpOwotICAgICAgfQotICAgIH0KLQotICAgIGJ1aWxkZXIuc2V0U3lzdGVtSWQoYmFzZUlEKTsKLQotICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpCi0gICAgewotICAgICAgRE9NU291cmNlIGRzb3VyY2UgPSAoRE9NU291cmNlKSBzb3VyY2U7Ci0gICAgICBOb2RlIG5vZGUgPSBkc291cmNlLmdldE5vZGUoKTsKLQotICAgICAgaWYgKG51bGwgIT0gbm9kZSkKLSAgICAgICAgcmV0dXJuIHByb2Nlc3NGcm9tTm9kZShub2RlLCBiYXNlSUQpOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBTdHJpbmcgbWVzc2FnZVN0ciA9IFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVULCBudWxsKTsKLQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG1lc3NhZ2VTdHIpOwotICAgICAgfQotICAgIH0KLQotICAgIHRyeQotICAgIHsKLSAgICAgIElucHV0U291cmNlIGlzb3VyY2UgPSBTQVhTb3VyY2Uuc291cmNlVG9JbnB1dFNvdXJjZShzb3VyY2UpOwotICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IG51bGw7Ci0KLSAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBTQVhTb3VyY2UpCi0gICAgICAgIHJlYWRlciA9ICgoU0FYU291cmNlKSBzb3VyY2UpLmdldFhNTFJlYWRlcigpOwotICAgICAgICAKLSAgICAgIGJvb2xlYW4gaXNVc2VyUmVhZGVyID0gKHJlYWRlciAhPSBudWxsKTsKLQotICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKQotICAgICAgewotCi0gICAgICAgIC8vIFVzZSBKQVhQMS4xICggaWYgcG9zc2libGUgKQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9Ci0gICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCi0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyIGpheHBQYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCi0gICAgICAgICAgcmVhZGVyID0gamF4cFBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5GYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yIGV4MSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgxLnRvU3RyaW5nKCkpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBleDIpe30KLSAgICAgICAgY2F0Y2ggKEFic3RyYWN0TWV0aG9kRXJyb3IgYW1lKXt9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChudWxsID09IHJlYWRlcikKLSAgICAgICAgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLQotICAgICAgLy8gSWYgeW91IHNldCB0aGUgbmFtZXNwYWNlcyB0byB0cnVlLCB3ZSdsbCBlbmQgdXAgZ2V0dGluZyBkb3VibGUgCi0gICAgICAvLyB4bWxucyBhdHRyaWJ1dGVzLiAgTmVlZHMgdG8gYmUgZml4ZWQuICAtc2IKLSAgICAgIC8vIHJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwgdHJ1ZSk7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYoIWlzVXNlclJlYWRlcikKLSAgICAgICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGV4KQotICAgICAgewotCi0gICAgICAgIC8vIGZlYXR1cmUgbm90IHJlY29nbml6ZWQKLSAgICAgIH0KLQotICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGJ1aWxkZXIpOwotICAgICAgcmVhZGVyLnBhcnNlKGlzb3VyY2UpOwotICAgIH0KLSAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIGlmIChtX2Vycm9yTGlzdGVuZXIgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBtX2Vycm9yTGlzdGVuZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXgxKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihleDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpLCBzZSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBpZiAobV9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgbV9lcnJvckxpc3RlbmVyLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpKTsKLQotICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleDEpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKGV4MSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGJ1aWxkZXIuZ2V0VGVtcGxhdGVzKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIFVSSVJlc29sdmVyIG1fdXJpUmVzb2x2ZXI7Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogeHNsOmltcG9ydCwgZXRjLiAgVGhpcyB3aWxsIGJlIHVzZWQgYXMgdGhlIGRlZmF1bHQgZm9yIHRoZQotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICogQHBhcmFtIHJlc29sdmVyIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKQotICB7Ci0gICAgbV91cmlSZXNvbHZlciA9IHJlc29sdmVyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluCi0gICAqIHhzbDppbXBvcnQsIGV0Yy4gIFRoaXMgd2lsbCBiZSB1c2VkIGFzIHRoZSBkZWZhdWx0IGZvciB0aGUKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFVSSVJlc29sdmVyIHRoYXQgd2FzIHNldCB3aXRoIHNldFVSSVJlc29sdmVyLgotICAgKi8KLSAgcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkKLSAgewotICAgIHJldHVybiBtX3VyaVJlc29sdmVyOwotICB9Ci0KLSAgLyoqIFRoZSBlcnJvciBsaXN0ZW5lci4gICAqLwotICBwcml2YXRlIEVycm9yTGlzdGVuZXIgbV9lcnJvckxpc3RlbmVyID0gbmV3IERlZmF1bHRFcnJvckhhbmRsZXIoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBlcnJvciBsaXN0ZW5lciBpbiBlZmZlY3QgZm9yIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAqCi0gICAqIEByZXR1cm4gQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYW4gZXJyb3IgbGlzdGVuZXIuCi0gICAqLwotICBwdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkKLSAgewotICAgIHJldHVybiBtX2Vycm9yTGlzdGVuZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIGVycm9yIGxpc3RlbmVyIGZvciB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgKgotICAgKiBAcGFyYW0gbGlzdGVuZXIgTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhbiBFcnJvckxpc3RlbmVyLgotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbGlzdGVuZXIgYXJndW1lbnQgaXMgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IGxpc3RlbmVyKQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRXJyb3JMaXN0ZW5lciIpOwotCi0gICAgbV9lcnJvckxpc3RlbmVyID0gbGlzdGVuZXI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xQcm9jZXNzb3JWZXJzaW9uLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvWFNMUHJvY2Vzc29yVmVyc2lvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNjFiODNmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xQcm9jZXNzb3JWZXJzaW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIEFkbWluaXN0cmF0aXZlIGNsYXNzIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHZlcnNpb24gbnVtYmVyIG9mCi0gKiB0aGUgWGFsYW4gcmVsZWFzZS4KLSAqIDxQPlNlZSBhbHNvOiBvcmcvYXBhY2hlL3hhbGFuL3Jlcy9YU0xUSW5mby5wcm9wZXJ0aWVzPC9QPgotICovCi1wdWJsaWMgY2xhc3MgWFNMUHJvY2Vzc29yVmVyc2lvbgotewotCi0gIC8qKgotICAgKiBQcmludCB0aGUgcHJvY2Vzc29yIHZlcnNpb24gdG8gdGhlIGNvbW1hbmQgbGluZS4KLSAgICoKLSAgICogQHBhcmFtIGFyZ3YgY29tbWFuZCBsaW5lIGFyZ3VtZW50cywgdW51c2VkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkKLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbihTX1ZFUlNJT04pOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0YW50IG5hbWUgb2YgcHJvZHVjdC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST0RVQ1QgPSAiWGFsYW4iOwotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRhdGlvbiBMYW5ndWFnZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIExBTkdVQUdFID0gIkphdmEiOwotCi0gIC8qKgotICAgKiBNYWpvciB2ZXJzaW9uIG51bWJlci4KLSAgICogVmVyc2lvbiBudW1iZXIuIFRoaXMgY2hhbmdlcyBvbmx5IHdoZW4gdGhlcmUgaXMgYQotICAgKiAgICAgICAgICBzaWduaWZpY2FudCwgZXh0ZXJuYWxseSBhcHBhcmVudCBlbmhhbmNlbWVudCBmcm9tCi0gICAqICAgICAgICAgIHRoZSBwcmV2aW91cyByZWxlYXNlLiAnbicgcmVwcmVzZW50cyB0aGUgbid0aAotICAgKiAgICAgICAgICB2ZXJzaW9uLgotICAgKgotICAgKiAgICAgICAgICBDbGllbnRzIHNob3VsZCBjYXJlZnVsbHkgY29uc2lkZXIgdGhlIGltcGxpY2F0aW9ucwotICAgKiAgICAgICAgICBvZiBuZXcgdmVyc2lvbnMgYXMgZXh0ZXJuYWwgaW50ZXJmYWNlcyBhbmQgYmVoYXZpb3VyCi0gICAqICAgICAgICAgIG1heSBoYXZlIGNoYW5nZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBWRVJTSU9OID0gMjsKLQotICAvKioKLSAgICogUmVsZWFzZSBOdW1iZXIuCi0gICAqIFJlbGVhc2UgbnVtYmVyLiBUaGlzIGNoYW5nZXMgd2hlbjoKLSAgICogICAgICAgICAgICAtICBhIG5ldyBzZXQgb2YgZnVuY3Rpb25hbGl0eSBpcyB0byBiZSBhZGRlZCwgZWcsCi0gICAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gb2YgYSBuZXcgVzNDIHNwZWNpZmljYXRpb24uCi0gICAqICAgICAgICAgICAgLSAgQVBJIG9yIGJlaGF2aW91ciBjaGFuZ2UuCi0gICAqICAgICAgICAgICAgLSAgaXRzIGRlc2lnbmF0ZWQgYXMgYSByZWZlcmVuY2UgcmVsZWFzZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IFJFTEVBU0UgPSAyOwotCi0gIC8qKgotICAgKiBNYWludGVuYW5jZSBEcm9wIE51bWJlci4KLSAgICogT3B0aW9uYWwgaWRlbnRpZmllciB1c2VkIHRvIGRlc2lnbmF0ZSBtYWludGVuYW5jZQotICAgKiAgICAgICAgICBkcm9wIGFwcGxpZWQgdG8gYSBzcGVjaWZpYyByZWxlYXNlIGFuZCBjb250YWlucwotICAgKiAgICAgICAgICBmaXhlcyBmb3IgZGVmZWN0cyByZXBvcnRlZC4gSXQgbWFpbnRhaW5zIGNvbXBhdGliaWxpdHkKLSAgICogICAgICAgICAgd2l0aCB0aGUgcmVsZWFzZSBhbmQgY29udGFpbnMgbm8gQVBJIGNoYW5nZXMuCi0gICAqICAgICAgICAgIFdoZW4gbWlzc2luZywgaXQgZGVzaWduYXRlcyB0aGUgZmluYWwgYW5kIGNvbXBsZXRlCi0gICAqICAgICAgICAgIGRldmVsb3BtZW50IGRyb3AgZm9yIGEgcmVsZWFzZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IE1BSU5URU5BTkNFID0gMDsKLQotICAvKioKLSAgICogRGV2ZWxvcG1lbnQgRHJvcCBOdW1iZXIuCi0gICAqIE9wdGlvbmFsIGlkZW50aWZpZXIgZGVzaWduYXRlcyBkZXZlbG9wbWVudCBkcm9wIG9mCi0gICAqICAgICAgICAgIGEgc3BlY2lmaWMgcmVsZWFzZS4gRDAxIGlzIHRoZSBmaXJzdCBkZXZlbG9wbWVudCBkcm9wCi0gICAqICAgICAgICAgIG9mIGEgbmV3IHJlbGVhc2UuCi0gICAqCi0gICAqICAgICAgICAgIERldmVsb3BtZW50IGRyb3BzIGFyZSB3b3JrcyBpbiBwcm9ncmVzcyB0b3dhcmRzIGEKLSAgICogICAgICAgICAgY29tcGVsZXRlZCwgZmluYWwgcmVsZWFzZS4gQSBzcGVjaWZpYyBkZXZlbG9wbWVudCBkcm9wCi0gICAqICAgICAgICAgIG1heSBub3QgY29tcGxldGVseSBpbXBsZW1lbnQgYWxsIGFzcGVjdHMgb2YgYSBuZXcKLSAgICogICAgICAgICAgZmVhdHVyZSwgd2hpY2ggbWF5IHRha2Ugc2V2ZXJhbCBkZXZlbG9wbWVudCBkcm9wcyB0bwotICAgKiAgICAgICAgICBjb21wbGV0ZS4gQXQgdGhlIHBvaW50IG9mIHRoZSBmaW5hbCBkcm9wIGZvciB0aGUKLSAgICogICAgICAgICAgcmVsZWFzZSwgdGhlIEQgc3VmZml4IHdpbGwgYmUgb21pdHRlZC4KLSAgICoKLSAgICogICAgICAgICAgRWFjaCAnRCcgZHJvcHMgY2FuIGNvbnRhaW4gZnVuY3Rpb25hbCBlbmhhbmNlbWVudHMgYXMKLSAgICogICAgICAgICAgd2VsbCBhcyBkZWZlY3QgZml4ZXMuICdEJyBkcm9wcyBtYXkgbm90IGJlIGFzIHN0YWJsZSBhcwotICAgKiAgICAgICAgICB0aGUgZmluYWwgcmVsZWFzZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBERVZFTE9QTUVOVCA9IDEwOwotICAKLSAgLyoqCi0gICAqIFZlcnNpb24gU3RyaW5nIGxpa2UgPENPREU+IjxCPlhhbGFuPC9CPiA8Qj5MYW5ndWFnZTwvQj4gCi0gICAqIHYuclsuZGR8IDxCPkQ8L0I+bm5dIjwvQ09ERT4uCi0gICAqIDxQPlNlbWFudGljcyBvZiB0aGUgdmVyc2lvbiBzdHJpbmcgYXJlIGlkZW50aWNhbCB0byB0aGUgWGVyY2VzIHByb2plY3QuPC9QPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgU19WRVJTSU9OID0gUFJPRFVDVCsiICIrTEFOR1VBR0UrIiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICtWRVJTSU9OKyIuIitSRUxFQVNFKyIuIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArKERFVkVMT1BNRU5UID4gMCA/ICgiRCIrREVWRUxPUE1FTlQpIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKCIiK01BSU5URU5BTkNFKSk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xUQXR0cmlidXRlRGVmLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvWFNMVEF0dHJpYnV0ZURlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMjFkODMxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xUQXR0cmlidXRlRGVmLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTE3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3RyaW5nVG9JbnRUYWJsZTsKLQotaW1wb3J0IGphdmEubGFuZy5JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5JbmRleE91dE9mQm91bmRzRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5JbnN0YW50aWF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5Ob1N1Y2hNZXRob2RFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci1pbXBvcnQgamF2YS5sYW5nLlN0cmluZ0J1ZmZlcjsKLQotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkFWVDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50czsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBkZWZpbmVzIGFuIGF0dHJpYnV0ZSBmb3IgYW4gZWxlbWVudCBpbiBhIFhTTFQgc3R5bGVzaGVldCwKLSAqIGlzIG1lYW50IHRvIHJlZmxlY3QgdGhlIHN0cnVjdHVyZSBkZWZpbmVkIGluIGh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkLCBhbmQgdGhlCi0gKiBtYXBwaW5nIGJldHdlZW4gWGFsYW4gY2xhc3NlcyBhbmQgdGhlIG1hcmt1cCBhdHRyaWJ1dGVzIGluIHRoZSBlbGVtZW50LgotICovCi1wdWJsaWMgY2xhc3MgWFNMVEF0dHJpYnV0ZURlZgotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gaW5zdGFuY2Ugb2YgWFNMVEF0dHJpYnV0ZURlZi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gdHlwZSBPbmUgb2YgVF9DREFUQSwgVF9VUkwsIFRfQVZULCBUX1BBVFRFUk4sIFRfRVhQUiwgVF9DSEFSLAotICAgKiBUX1BSSU9SSVRZLCBUX1lFU05PLCBUX1FOQU1FLCBUX1FOQU1FUywgVF9FTlVNLCBUX1NJTVBMRVBBVFRFUk5MSVNULAotICAgKiBUX05NVE9LRU4sIFRfU1RSSU5HTElTVCwgVF9QUkVGSVhfVVJMTElTVC4KLSAgICogQHBhcmFtIHJlcXVpcmVkIHRydWUgaWYgdGhpcyBpcyBhdHRyaWJ1dGUgaXMgcmVxdWlyZWQgYnkgdGhlIFhTTFQgc3BlY2lmaWNhdGlvbi4KLSAgICovCi0gIFhTTFRBdHRyaWJ1dGVEZWYoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUsIGludCB0eXBlLCBib29sZWFuIHJlcXVpcmVkKQotICB7Ci0KLSAgICB0aGlzLm1fbmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgIHRoaXMubV9uYW1lID0gbmFtZTsKLSAgICB0aGlzLm1fdHlwZSA9IHR5cGU7Ci0gICAgdGhpcy5tX3JlcXVpcmVkID0gcmVxdWlyZWQ7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIFhTTFRBdHRyaWJ1dGVEZWYuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHR5cGUgT25lIG9mIFRfQ0RBVEEsIFRfVVJMLCBUX0FWVCwgVF9QQVRURVJOLCBUX0VYUFIsCi0gICAqIFRfQ0hBUiwgVF9QUklPUklUWSwgVF9ZRVNOTywgVF9RTkFNRSwgVF9RTkFNRVMsIFRfRU5VTSwKLSAgICogVF9TSU1QTEVQQVRURVJOTElTVCwgVF9OTVRPS0VOLCBUX1NUUklOR0xJU1QsIFRfUFJFRklYX1VSTExJU1QuCi0gICAqIEBwYXJhbSBkZWZhdWx0VmFsIFRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIGF0dHJpYnV0ZS4KLSAgICovCi0gIFhTTFRBdHRyaWJ1dGVEZWYoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUsIGludCB0eXBlLCBTdHJpbmcgZGVmYXVsdFZhbCkKLSAgewotCi0gICAgdGhpcy5tX25hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICB0aGlzLm1fbmFtZSA9IG5hbWU7Ci0gICAgdGhpcy5tX3R5cGUgPSB0eXBlOwotICAgIHRoaXMubV9yZXF1aXJlZCA9IGZhbHNlOwotICAgIHRoaXMubV9kZWZhdWx0ID0gZGVmYXVsdFZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gaW5zdGFuY2Ugb2YgWFNMVEF0dHJpYnV0ZURlZiB0aGF0IHVzZXMgdHdvCi0gICAqIGVudW1lcmF0ZWQgdmFsdWVzLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByZXF1aXJlZCB0cnVlIGlmIHRoaXMgYXR0cmlidXRlIGlzIHJlcXVpcmVkIGJ5IHRoZSBYU0xUIHNwZWNpZmljYXRpb24uCi0gICAqIEBwYXJhbSBrMSBUaGUgWFNMVCBuYW1lIG9mIHRoZSBlbnVtZXJhdGVkIHZhbHVlLgotICAgKiBAcGFyYW0gdjEgQW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiBrMS4KLSAgICogQHBhcmFtIGsyIFRoZSBYU0xUIG5hbWUgb2YgdGhlIGVudW1lcmF0ZWQgdmFsdWUuCi0gICAqIEBwYXJhbSB2MiBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIGsyLgotICAgKi8KLSAgWFNMVEF0dHJpYnV0ZURlZihTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSwgYm9vbGVhbiByZXF1aXJlZCwKLSAgICAgICAgICAgICAgICAgICBTdHJpbmcgazEsIGludCB2MSwgU3RyaW5nIGsyLCBpbnQgdjIpCi0gIHsKLQotICAgIHRoaXMubV9uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgdGhpcy5tX25hbWUgPSBuYW1lOwotICAgIHRoaXMubV90eXBlID0gdGhpcy5UX0VOVU07Ci0gICAgdGhpcy5tX3JlcXVpcmVkID0gcmVxdWlyZWQ7Ci0gICAgbV9lbnVtcyA9IG5ldyBTdHJpbmdUb0ludFRhYmxlKDIpOwotCi0gICAgbV9lbnVtcy5wdXQoazEsIHYxKTsKLSAgICBtX2VudW1zLnB1dChrMiwgdjIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZSBvZiBYU0xUQXR0cmlidXRlRGVmIHRoYXQgdXNlcyB0aHJlZQotICAgKiBlbnVtZXJhdGVkIHZhbHVlcy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmVxdWlyZWQgdHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyByZXF1aXJlZCBieSB0aGUgWFNMVCBzcGVjaWZpY2F0aW9uLgotICAgKiBAcGFyYW0gazEgVGhlIFhTTFQgbmFtZSBvZiB0aGUgZW51bWVyYXRlZCB2YWx1ZS4KLSAgICogQHBhcmFtIHYxIEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgazEuCi0gICAqIEBwYXJhbSBrMiBUaGUgWFNMVCBuYW1lIG9mIHRoZSBlbnVtZXJhdGVkIHZhbHVlLgotICAgKiBAcGFyYW0gdjIgQW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiBrMi4KLSAgICogQHBhcmFtIGszIFRoZSBYU0xUIG5hbWUgb2YgdGhlIGVudW1lcmF0ZWQgdmFsdWUuCi0gICAqIEBwYXJhbSB2MyBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIGszLgotICAgKi8KLSAgWFNMVEF0dHJpYnV0ZURlZihTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSwgYm9vbGVhbiByZXF1aXJlZCwKLSAgICAgICAgICAgICAgICAgICBTdHJpbmcgazEsIGludCB2MSwgU3RyaW5nIGsyLCBpbnQgdjIsIFN0cmluZyBrMywgaW50IHYzKQotICB7Ci0KLSAgICB0aGlzLm1fbmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgIHRoaXMubV9uYW1lID0gbmFtZTsKLSAgICB0aGlzLm1fdHlwZSA9IHRoaXMuVF9FTlVNOwotICAgIHRoaXMubV9yZXF1aXJlZCA9IHJlcXVpcmVkOwotICAgIG1fZW51bXMgPSBuZXcgU3RyaW5nVG9JbnRUYWJsZSgzKTsKLQotICAgIG1fZW51bXMucHV0KGsxLCB2MSk7Ci0gICAgbV9lbnVtcy5wdXQoazIsIHYyKTsKLSAgICBtX2VudW1zLnB1dChrMywgdjMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZSBvZiBYU0xUQXR0cmlidXRlRGVmIHRoYXQgdXNlcyB0aHJlZQotICAgKiBlbnVtZXJhdGVkIHZhbHVlcy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmVxdWlyZWQgdHJ1ZSBpZiB0aGlzIGF0dHJpYnV0ZSBpcyByZXF1aXJlZCBieSB0aGUgWFNMVCBzcGVjaWZpY2F0aW9uLgotICAgKiBAcGFyYW0gazEgVGhlIFhTTFQgbmFtZSBvZiB0aGUgZW51bWVyYXRlZCB2YWx1ZS4KLSAgICogQHBhcmFtIHYxIEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgazEuCi0gICAqIEBwYXJhbSBrMiBUaGUgWFNMVCBuYW1lIG9mIHRoZSBlbnVtZXJhdGVkIHZhbHVlLgotICAgKiBAcGFyYW0gdjIgQW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiBrMi4KLSAgICogQHBhcmFtIGszIFRoZSBYU0xUIG5hbWUgb2YgdGhlIGVudW1lcmF0ZWQgdmFsdWUuCi0gICAqIEBwYXJhbSB2MyBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIGszLgotICAgKiBAcGFyYW0gazQgVGhlIFhTTFQgbmFtZSBvZiB0aGUgZW51bWVyYXRlZCB2YWx1ZS4KLSAgICogQHBhcmFtIHY0IEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgazQuCi0gICAqLwotICBYU0xUQXR0cmlidXRlRGVmKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBib29sZWFuIHJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgIFN0cmluZyBrMSwgaW50IHYxLCBTdHJpbmcgazIsIGludCB2MiwgU3RyaW5nIGszLCBpbnQgdjMsCi0gICAgICAgICAgICAgICAgICAgU3RyaW5nIGs0LCBpbnQgdjQpCi0gIHsKLQotICAgIHRoaXMubV9uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgdGhpcy5tX25hbWUgPSBuYW1lOwotICAgIHRoaXMubV90eXBlID0gdGhpcy5UX0VOVU07Ci0gICAgdGhpcy5tX3JlcXVpcmVkID0gcmVxdWlyZWQ7Ci0gICAgbV9lbnVtcyA9IG5ldyBTdHJpbmdUb0ludFRhYmxlKDQpOwotCi0gICAgbV9lbnVtcy5wdXQoazEsIHYxKTsKLSAgICBtX2VudW1zLnB1dChrMiwgdjIpOwotICAgIG1fZW51bXMucHV0KGszLCB2Myk7Ci0gICAgbV9lbnVtcy5wdXQoazQsIHY0KTsKLSAgfQotCi0gIC8qKiBUeXBlIHZhbHVlcyB0aGF0IHJlcHJlc2VudCBYU0xUIGF0dHJpYnV0ZSB0eXBlcy4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBUX0NEQVRBID0gMSwKLQotICAvLyA8IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGEgVVJJIHJlZmVyZW5jZS4tLT4KLSAgVF9VUkwgPSAyLAotCi0gIC8vIDwhLS0gVXNlZCBmb3IgdGhlIHR5cGUgb2YgYW4gYXR0cmlidXRlIHZhbHVlIHRoYXQgaXMgYW4KLSAgLy8gYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlLi0tPgotICBUX0FWVCA9IDMsICAvLyBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGUKLQotICAvLyA8IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGEgcGF0dGVybi4tLT4KLSAgVF9QQVRURVJOID0gNCwKLQotICAvLyA8IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGFuIGV4cHJlc3Npb24uLS0+Ci0gIFRfRVhQUiA9IDUsCi0KLSAgLy8gPCEtLSBVc2VkIGZvciB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBjb25zaXN0cwotICAvLyBvZiBhIHNpbmdsZSBjaGFyYWN0ZXIuLS0+Ci0gIFRfQ0hBUiA9IDYsCi0KLSAgLy8gPCEtLSBVc2VkIGZvciB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBpcyBhIHByaW9yaXR5LiAtLT4KLSAgVF9QUklPUklUWSA9IDcsCi0KLSAgLy8gVXNlZCBmb3IgYm9vbGVhbiB2YWx1ZXMKLSAgVF9ZRVNOTyA9IDgsCi0KLSAgLy8gPCEtLSBVc2VkIGZvciB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBpcyBhIFFOYW1lOyB0aGUgcHJlZml4Ci0gIC8vIGdldHMgZXhwYW5kZWQgYnkgdGhlIFhTTFQgcHJvY2Vzc29yLiAtLT4KLSAgVF9RTkFNRSA9IDksCi0KLSAgLy8gPCEtLSBMaWtlIHFuYW1lIGJ1dCBhIHdoaXRlc3BhY2Utc2VwYXJhdGVkIGxpc3Qgb2YgUU5hbWVzLiAtLT4KLSAgVF9RTkFNRVMgPSAxMCwKLQotICAvLyA8IS0tIFVzZWQgZm9yIGVudW1lcmF0ZWQgdmFsdWVzIC0tPgotICBUX0VOVU0gPSAxMSwKLQotICAvLyBVc2VkIGZvciBzaW1wbGUgbWF0Y2ggcGF0dGVybnMsIGkuZS4geHNsOnN0cmlwLXNwYWNlIHNwZWMuCi0gIFRfU0lNUExFUEFUVEVSTkxJU1QgPSAxMiwKLQotICAvLyBVc2VkIGZvciBhIGtub3duIHRva2VuLgotICBUX05NVE9LRU4gPSAxMywKLQotICAvLyBVc2VkIGZvciBhIGxpc3Qgb2Ygd2hpdGUtc3BhY2UgZGVsaW1pdGVkIHN0cmluZ3MuCi0gIFRfU1RSSU5HTElTVCA9IDE0LAotCi0gIC8vIFVzZWQgZm9yIGEgbGlzdCBvZiB3aGl0ZS1zcGFjZSBkZWxpbWl0ZWQgc3RyaW5ncy4KLSAgVF9QUkVGSVhfVVJMTElTVCA9IDE1OwotCi0gIC8qKiBSZXByZXNlbnRhdGlvbiBmb3IgYW4gYXR0cmlidXRlIGluIGEgZm9yZWlnbiBuYW1lc3BhY2UuICovCi0gIHN0YXRpYyBYU0xUQXR0cmlidXRlRGVmIG1fZm9yZWlnbkF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZigiKiIsICIqIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0NEQVRBLCBmYWxzZSk7Ci0KLSAgLyoqIE1ldGhvZCBuYW1lIHRoYXQgb2JqZWN0cyBtYXkgaW1wbGVtZW50IGlmIHRoZXkgd2lzaCB0byBoYXZlIGZvcmVpbiBhdHRyaWJ1dGVzIHNldC4gKi8KLSAgc3RhdGljIFN0cmluZyBTX0ZPUkVJR05BVFRSX1NFVFRFUiA9ICJzZXRGb3JlaWduQXR0ciI7Ci0KLSAgLyoqCi0gICAqIFRoZSBhbGxvd2VkIG5hbWVzcGFjZSBmb3IgdGhpcyBlbGVtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9uYW1lc3BhY2U7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYWxsb3dlZCBuYW1lc3BhY2UgZm9yIHRoaXMgYXR0cmlidXRlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhbGxvd2VkIG5hbWVzcGFjZSBmb3IgdGhpcyBhdHRyaWJ1dGUsIHdoaWNoIG1heSBiZSBudWxsLCBvciBtYXkgYmUgIioiLgotICAgKi8KLSAgU3RyaW5nIGdldE5hbWVzcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lc3BhY2U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG5hbWUgb2YgdGhpcyBlbGVtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9uYW1lOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhpcyBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBuYW1lIG9mIHRoaXMgYXR0cmlidXRlLCB3aGljaCBtYXkgYmUgIioiLgotICAgKi8KLSAgU3RyaW5nIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgdHlwZSBvZiB0aGlzIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICovCi0gIHByaXZhdGUgaW50IG1fdHlwZTsKLQotICAvKioKLSAgICogR2V0IHRoZSB0eXBlIG9mIHRoaXMgYXR0cmlidXRlIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIE9uZSBvZiBUX0NEQVRBLCBUX1VSTCwgVF9BVlQsIFRfUEFUVEVSTiwgVF9FWFBSLCBUX0NIQVIsCi0gICAqIFRfUFJJT1JJVFksIFRfWUVTTk8sIFRfUU5BTUUsIFRfUU5BTUVTLCBUX0VOVU0sIFRfU0lNUExFUEFUVEVSTkxJU1QsCi0gICAqIFRfTk1UT0tFTiwgVF9TVFJJTkdMSVNULCBUX1BSRUZJWF9VUkxMSVNULgotICAgKi8KLSAgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIG1fdHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiB0aGlzIGVsZW1lbnQgaXMgb2YgdHlwZSBUX0VOVU0sIHRoaXMgd2lsbCBjb250YWluCi0gICAqIGEgbWFwIGZyb20gdGhlIGF0dHJpYnV0ZSBzdHJpbmcgdG8gdGhlIFhhbGFuIGludGVnZXIKLSAgICogdmFsdWUuCi0gICAqLwotICBwcml2YXRlIFN0cmluZ1RvSW50VGFibGUgbV9lbnVtczsKLQotICAvKioKLSAgICogSWYgdGhpcyBlbGVtZW50IGlzIG9mIHR5cGUgVF9FTlVNLCB0aGlzIHdpbGwgcmV0dXJuCi0gICAqIGEgbWFwIGZyb20gdGhlIGF0dHJpYnV0ZSBzdHJpbmcgdG8gdGhlIFhhbGFuIGludGVnZXIKLSAgICogdmFsdWUuCi0gICAqIEBwYXJhbSBrZXkgVGhlIFhTTFQgYXR0cmlidXRlIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbnVtZXJhdGVkIHZhbHVlIGZvciB0aGlzIGF0dHJpYnV0ZS4KLSAgICogQHRocm93cyBUaHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgbV9lbnVtcyBpcyBudWxsLgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgZ2V0RW51bShTdHJpbmcga2V5KQotICB7Ci0gICAgcmV0dXJuIG1fZW51bXMuZ2V0KGtleSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgYXR0cmlidXRlLgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9kZWZhdWx0OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgYXR0cmlidXRlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIGF0dHJpYnV0ZSwgb3IgbnVsbC4KLSAgICovCi0gIFN0cmluZyBnZXREZWZhdWx0KCkKLSAgewotICAgIHJldHVybiBtX2RlZmF1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIGRlZiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgYXR0cmlidXRlLgotICAgKi8KLSAgdm9pZCBzZXREZWZhdWx0KFN0cmluZyBkZWYpCi0gIHsKLSAgICBtX2RlZmF1bHQgPSBkZWY7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdHJ1ZSwgdGhpcyBpcyBhIHJlcXVpcmVkIGF0dHJpYnV0ZS4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX3JlcXVpcmVkOwotCi0gIC8qKgotICAgKiBHZXQgd2hldGhlciBvciBub3QgdGhpcyBpcyBhIHJlcXVpcmVkIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSByZXF1aXJlZCBhdHRyaWJ1dGUuCi0gICAqLwotICBib29sZWFuIGdldFJlcXVpcmVkKCkKLSAgewotICAgIHJldHVybiBtX3JlcXVpcmVkOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0cmluZyB0aGF0IHNob3VsZCByZXByZXNlbnQgdGhlIHNldHRlciBtZXRob2Qgd2hpY2ggd2hpY2gKLSAgICogbWF5IGJlIHVzZWQgb24gb2JqZWN0cyB0byBzZXQgYSB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgdGhpcyBhdHRyaWJ1dGUgIAotICAgKi8KLSAgU3RyaW5nIG1fc2V0dGVyU3RyaW5nID0gbnVsbDsKLQotICAvKioKLSAgICogUmV0dXJuIGEgc3RyaW5nIHRoYXQgc2hvdWxkIHJlcHJlc2VudCB0aGUgc2V0dGVyIG1ldGhvZC4KLSAgICogVGhlIHNldHRlciBtZXRob2QgbmFtZSB3aWxsIGJlIGNyZWF0ZWQgYWxnb3JpdGhtaWNhbGx5IHRoZQotICAgKiBmaXJzdCB0aW1lIHRoaXMgbWV0aG9kIGlzIGFjY2Vzc2VkLCBhbmQgdGhlbiBjYWNoZWQgZm9yIHJldHVybgotICAgKiBieSBzdWJzZXF1ZW50IGludm9jYXRpb25zIG9mIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyB0aGF0IHNob3VsZCByZXByZXNlbnQgdGhlIHNldHRlciBtZXRob2Qgd2hpY2ggd2hpY2gKLSAgICogbWF5IGJlIHVzZWQgb24gb2JqZWN0cyB0byBzZXQgYSB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgdGhpcyBhdHRyaWJ1dGUsCi0gICAqIG9mIG51bGwgaWYgbm8gc2V0dGVyIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTZXR0ZXJNZXRob2ROYW1lKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9zZXR0ZXJTdHJpbmcpCi0gICAgewotICAgICAgaWYgKG1fZm9yZWlnbkF0dHIgPT0gdGhpcykKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIFNfRk9SRUlHTkFUVFJfU0VUVEVSOwotICAgICAgfQotICAgICAgZWxzZSBpZiAobV9uYW1lLmVxdWFscygiKiIpKQotICAgICAgewotICAgICAgICBtX3NldHRlclN0cmluZyA9ICJhZGRMaXRlcmFsUmVzdWx0QXR0cmlidXRlIjsKLQotICAgICAgICByZXR1cm4gbV9zZXR0ZXJTdHJpbmc7Ci0gICAgICB9Ci0KLSAgICAgIFN0cmluZ0J1ZmZlciBvdXRCdWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAgIG91dEJ1Zi5hcHBlbmQoInNldCIpOwotCi0gICAgICBpZiAoKG1fbmFtZXNwYWNlICE9IG51bGwpCi0gICAgICAgICAgICAgICYmIG1fbmFtZXNwYWNlLmVxdWFscyhDb25zdGFudHMuU19YTUxOQU1FU1BBQ0VVUkkpKQotICAgICAgewotICAgICAgICBvdXRCdWYuYXBwZW5kKCJYbWwiKTsKLSAgICAgIH0KLQotICAgICAgaW50IG4gPSBtX25hbWUubGVuZ3RoKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgewotICAgICAgICBjaGFyIGMgPSBtX25hbWUuY2hhckF0KGkpOwotCi0gICAgICAgIGlmICgnLScgPT0gYykKLSAgICAgICAgewotICAgICAgICAgIGkrKzsKLQotICAgICAgICAgIGMgPSBtX25hbWUuY2hhckF0KGkpOwotICAgICAgICAgIGMgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UoYyk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoMCA9PSBpKQotICAgICAgICB7Ci0gICAgICAgICAgYyA9IENoYXJhY3Rlci50b1VwcGVyQ2FzZShjKTsKLSAgICAgICAgfQotCi0gICAgICAgIG91dEJ1Zi5hcHBlbmQoYyk7Ci0gICAgICB9Ci0KLSAgICAgIG1fc2V0dGVyU3RyaW5nID0gb3V0QnVmLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG1fc2V0dGVyU3RyaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYW4gYXR0cmlidXRlIHN0cmluZyBvZiB0eXBlIFRfQVZUIGludG8KLSAgICogYSBBVlQgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSB2YWx1ZSBTaG91bGQgYmUgYW4gQXR0cmlidXRlIFZhbHVlIFRlbXBsYXRlIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBBbiBBVlQgb2JqZWN0IHRoYXQgbWF5IGJlIHVzZWQgdG8gZXZhbHVhdGUgdGhlIEF0dHJpYnV0ZSBWYWx1ZSBUZW1wbGF0ZS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gd2hpY2ggd2lsbCB3cmFwIGEKLSAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259LCBpZiB0aGVyZSBpcyBhIHN5bnRheCBlcnJvcgotICAgKiBpbiB0aGUgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIHN0cmluZy4KLSAgICovCi0gIEFWVCBwcm9jZXNzQVZUKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBBVlQgYXZ0ID0gbmV3IEFWVChoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsIHZhbHVlKTsKLQotICAgICAgcmV0dXJuIGF2dDsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX0NEQVRBIGludG8KLSAgICogYSBTdHJpbmcgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSB2YWx1ZSBub24tbnVsbCBzdHJpbmcgcmVmZXJlbmNlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBhcmd1bWVudC4KLSAgICovCi0gIE9iamVjdCBwcm9jZXNzQ0RBVEEoU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgewotICAgIHJldHVybiB2YWx1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX0NIQVIgaW50bwotICAgKiBhIENoYXJhY3RlciB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIHZhbHVlIFNob3VsZCBiZSBhIHN0cmluZyB3aXRoIGEgbGVuZ3RoIG9mIDEuCi0gICAqCi0gICAqIEByZXR1cm4gQ2hhcmFjdGVyIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgdGhlIHN0cmluZyBpcyBub3QgYSBsZW5ndGggb2YgMS4KLSAgICovCi0gIE9iamVjdCBwcm9jZXNzQ0hBUigKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHZhbHVlLmxlbmd0aCgpICE9IDEpCi0gICAgewotICAgICAgaGFuZGxlci5lcnJvcigKLSAgICAgICAgIkFuIFhTTFQgYXR0cmlidXRlIG9mIHR5cGUgVF9DSEFSIG11c3QgYmUgb25seSAxIGNoYXJhY3RlciEiLCBudWxsKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3IENoYXJhY3Rlcih2YWx1ZS5jaGFyQXQoMCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYW4gYXR0cmlidXRlIHN0cmluZyBvZiB0eXBlIFRfRU5VTSBpbnRvCi0gICAqIGEgaW50IHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKiBAcGFyYW0gdmFsdWUgbm9uLW51bGwgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyBhbiBlbnVtZXJhdGVkIHZhbHVlIHRoYXQgaXMKLSAgICogdmFsaWQgZm9yIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiBBbiBJbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbnVtZXJhdGVkIHZhbHVlLgotICAgKi8KLSAgT2JqZWN0IHByb2Nlc3NFTlVNKFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgewotCi0gICAgaW50IGVudW0gPSB0aGlzLmdldEVudW0odmFsdWUpOwotCi0gICAgcmV0dXJuIG5ldyBJbnRlZ2VyKGVudW0pOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYW4gYXR0cmlidXRlIHN0cmluZyBvZiB0eXBlIFRfRVhQUiBpbnRvCi0gICAqIGFuIFhQYXRoIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKiBAcGFyYW0gdmFsdWUgQW4gWFNMVCBleHByZXNzaW9uIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBhbiBYUGF0aCBvYmplY3QgdGhhdCBtYXkgYmUgdXNlZCBmb3IgZXZhbHVhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gdGhhdCB3cmFwcyBhCi0gICAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9ufSBpZiB0aGUgZXhwcmVzc2lvbgotICAgKiBzdHJpbmcgY29udGFpbnMgYSBzeW50YXggZXJyb3IuCi0gICAqLwotICBPYmplY3QgcHJvY2Vzc0VYUFIoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIG5hbWUsIFN0cmluZyByYXdOYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFhQYXRoIGV4cHIgPSBoYW5kbGVyLmNyZWF0ZVhQYXRoKHZhbHVlKTsKLQotICAgICAgcmV0dXJuIGV4cHI7Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UgPSBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX05NVE9LRU4gaW50bwotICAgKiBhIFN0cmluZyB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIHZhbHVlIEEgTk1UT0tFTiBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHZhbHVlIGFyZ3VtZW50LgotICAgKi8KLSAgT2JqZWN0IHByb2Nlc3NOTVRPS0VOKFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgewotICAgIHJldHVybiB2YWx1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX1BBVFRFUk4gaW50bwotICAgKiBhbiBYUGF0aCBtYXRjaCBwYXR0ZXJuIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKiBAcGFyYW0gdmFsdWUgQSBtYXRjaCBwYXR0ZXJuIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBBbiBYUGF0aCBwYXR0ZXJuIHRoYXQgbWF5IGJlIHVzZWQgdG8gZXZhbHVhdGUgdGhlIFhQYXRoLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiB0aGF0IHdyYXBzIGEKLSAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb259IGlmIHRoZSBtYXRjaCBwYXR0ZXJuCi0gICAqIHN0cmluZyBjb250YWlucyBhIHN5bnRheCBlcnJvci4KLSAgICovCi0gIE9iamVjdCBwcm9jZXNzUEFUVEVSTigKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgWFBhdGggcGF0dGVybiA9IGhhbmRsZXIuY3JlYXRlTWF0Y2hQYXR0ZXJuWFBhdGgodmFsdWUpOwotCi0gICAgICByZXR1cm4gcGF0dGVybjsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24odGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX1BSSU9SSVRZIGludG8KLSAgICogYSBkb3VibGUgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSB2YWx1ZSBBIHN0cmluZyB0aGF0IGNhbiBiZSBwYXJzZWQgaW50byBhIGRvdWJsZSB2YWx1ZS4KLSAgICoKLSAgICogQHJldHVybiBBIERvdWJsZSBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHRoYXQgd3JhcHMgYQotICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbn0KLSAgICogaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBjb250YWluIGEgcGFyc2FibGUgbnVtYmVyLgotICAgKi8KLSAgT2JqZWN0IHByb2Nlc3NQUklPUklUWSgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgcmV0dXJuIERvdWJsZS52YWx1ZU9mKHZhbHVlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpCi0gICAgewotICAgICAgaGFuZGxlci5lcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfUFJJT1JJVFlfTk9UX1BBUlNBQkxFLCBudWxsLCBuZmUpOy8vIlByaW9yaXR5IHZhbHVlIGRvZXMgbm90IGNvbnRhaW4gYSBwYXJzYWJsZSBudW1iZXIuIiwKLSAgICAgICAgICAgICAgICAgICAgLy9uZmUpOwotCi0gICAgICByZXR1cm4gbmV3IERvdWJsZSgwLjApOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX1FOQU1FIGludG8KLSAgICogYSBRTmFtZSB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIHZhbHVlIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyBhIHBvdGVudGlhbGx5IHByZWZpeCBxdWFsaWZpZWQgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBBIFFOYW1lIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgdGhlIHN0cmluZyBjb250YWlucyBhIHByZWZpeCB0aGF0IGNhbiBub3QgYmUKLSAgICogcmVzb2x2ZWQsIG9yIHRoZSBzdHJpbmcgY29udGFpbnMgc3ludGF4IHRoYXQgaXMgaW52YWxpZCBmb3IgYSBxdWFsaWZpZWQgbmFtZS4KLSAgICovCi0gIE9iamVjdCBwcm9jZXNzUU5BTUUoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIG5hbWUsIFN0cmluZyByYXdOYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFFOYW1lKHZhbHVlLCBoYW5kbGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX1FOQU1FUyBpbnRvCi0gICAqIGEgdmVjdG9yIG9mIFFOYW1lcy4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIHZhbHVlIEEgd2hpdGVzcGFjZSBkZWxpbWl0ZWQgbGlzdCBvZiBxdWFsaWZpZWQgbmFtZXMuCi0gICAqCi0gICAqIEByZXR1cm4gYSBWZWN0b3Igb2YgUU5hbWUgb2JqZWN0cy4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgdGhlIG9uZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgc3RyaW5ncwotICAgKiBjb250YWlucyBhIHByZWZpeCB0aGF0IGNhbiBub3QgYmUKLSAgICogcmVzb2x2ZWQsIG9yIGEgcXVhbGlmaWVkIG5hbWUgY29udGFpbnMgc3ludGF4IHRoYXQgaXMgaW52YWxpZCBmb3IgYSBxdWFsaWZpZWQgbmFtZS4KLSAgICovCi0gIFZlY3RvciBwcm9jZXNzUU5BTUVTKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcdFxuXHJcZiIpOwotICAgIGludCBuUU5hbWVzID0gdG9rZW5pemVyLmNvdW50VG9rZW5zKCk7Ci0gICAgVmVjdG9yIHFuYW1lcyA9IG5ldyBWZWN0b3IoblFOYW1lcyk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5RTmFtZXM7IGkrKykKLSAgICB7Ci0gICAgICAvLyBGaXggZnJvbSBBbGV4YW5kZXIgUnVkbmV2Ci0gICAgICBxbmFtZXMuYWRkRWxlbWVudChuZXcgUU5hbWUodG9rZW5pemVyLm5leHRUb2tlbigpLCBoYW5kbGVyKSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHFuYW1lczsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX1NJTVBMRVBBVFRFUk5MSVNUIGludG8KLSAgICogYSB2ZWN0b3Igb2YgWFBhdGggbWF0Y2ggcGF0dGVybnMuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSB2YWx1ZSBBIHdoaXRlc3BhY2UgZGVsaW1pdGVkIGxpc3Qgb2Ygc2ltcGxlIG1hdGNoIHBhdHRlcm5zLgotICAgKgotICAgKiBAcmV0dXJuIEEgVmVjdG9yIG9mIFhQYXRoIG9iamVjdHMuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHRoYXQgd3JhcHMgYQotICAgKiB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbn0gaWYgb25lIG9mIHRoZSBtYXRjaCBwYXR0ZXJuCi0gICAqIHN0cmluZ3MgY29udGFpbnMgYSBzeW50YXggZXJyb3IuCi0gICAqLwotICBWZWN0b3IgcHJvY2Vzc1NJTVBMRVBBVFRFUk5MSVNUKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcdFxuXHJcZiIpOwotICAgICAgaW50IG5QYXR0ZXJucyA9IHRva2VuaXplci5jb3VudFRva2VucygpOwotICAgICAgVmVjdG9yIHBhdHRlcm5zID0gbmV3IFZlY3RvcihuUGF0dGVybnMpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5QYXR0ZXJuczsgaSsrKQotICAgICAgewotICAgICAgICBYUGF0aCBwYXR0ZXJuID0KLSAgICAgICAgICBoYW5kbGVyLmNyZWF0ZU1hdGNoUGF0dGVyblhQYXRoKHRva2VuaXplci5uZXh0VG9rZW4oKSk7Ci0KLSAgICAgICAgcGF0dGVybnMuYWRkRWxlbWVudChwYXR0ZXJuKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHBhdHRlcm5zOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYW4gYXR0cmlidXRlIHN0cmluZyBvZiB0eXBlIFRfU1RSSU5HTElTVCBpbnRvCi0gICAqIGEgdmVjdG9yIG9mIFhQYXRoIG1hdGNoIHBhdHRlcm5zLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKiBAcGFyYW0gdmFsdWUgYSB3aGl0ZXNwYWNlIGRlbGltaXRlZCBsaXN0IG9mIHN0cmluZyB2YWx1ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBTdHJpbmdWZWN0b3Igb2YgdGhlIHRva2VuaXplZCBzdHJpbmdzLgotICAgKi8KLSAgU3RyaW5nVmVjdG9yIHByb2Nlc3NTVFJJTkdMSVNUKFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSwgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgewotCi0gICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIodmFsdWUsICIgXHRcblxyXGYiKTsKLSAgICBpbnQgblN0cmluZ3MgPSB0b2tlbml6ZXIuY291bnRUb2tlbnMoKTsKLSAgICBTdHJpbmdWZWN0b3Igc3RyaW5ncyA9IG5ldyBTdHJpbmdWZWN0b3IoblN0cmluZ3MpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuU3RyaW5nczsgaSsrKQotICAgIHsKLSAgICAgIHN0cmluZ3MuYWRkRWxlbWVudCh0b2tlbml6ZXIubmV4dFRva2VuKCkpOwotICAgIH0KLQotICAgIHJldHVybiBzdHJpbmdzOwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgYW4gYXR0cmlidXRlIHN0cmluZyBvZiB0eXBlIFRfVVJMTElTVCBpbnRvCi0gICAqIGEgdmVjdG9yIG9mIHByZWZpeGVzIHRoYXQgbWF5IGJlIHJlc29sdmVkIHRvIFVSTHMuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSB2YWx1ZSBBIGxpc3Qgb2Ygd2hpdGVzcGFjZSBkZWxpbWl0ZWQgcHJlZml4ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gQSB2ZWN0b3Igb2Ygc3RyaW5ncyB0aGF0IG1heSBiZSByZXNvbHZlZCB0byBVUkxzLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBpZiBvbmUgb2YgdGhlIHByZWZpeGVzIGNhbiBub3QgYmUgcmVzb2x2ZWQuCi0gICAqLwotICBTdHJpbmdWZWN0b3IgcHJvY2Vzc1BSRUZJWF9VUkxMSVNUKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiBcdFxuXHJcZiIpOwotICAgIGludCBuU3RyaW5ncyA9IHRva2VuaXplci5jb3VudFRva2VucygpOwotICAgIFN0cmluZ1ZlY3RvciBzdHJpbmdzID0gbmV3IFN0cmluZ1ZlY3RvcihuU3RyaW5ncyk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5TdHJpbmdzOyBpKyspCi0gICAgewotICAgICAgU3RyaW5nIHByZWZpeCA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgIFN0cmluZyB1cmwgPSBoYW5kbGVyLmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotCi0gICAgICBzdHJpbmdzLmFkZEVsZW1lbnQodXJsKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3RyaW5nczsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIGFuIGF0dHJpYnV0ZSBzdHJpbmcgb2YgdHlwZSBUX1VSTCBpbnRvCi0gICAqIGEgVVJMIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLgotICAgKiBAcGFyYW0gdmFsdWUgbm9uLW51bGwgc3RyaW5nIHRoYXQgY29uZm9ybXMgdG8gdGhlIFVSTCBzeW50YXguCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vbi1hYnNvbHV0aXplZCBVUkwgYXJndW1lbnQsIGluIG90aGVyIHdvcmRzLCB0aGUgdmFsdWUgYXJndW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlmIHRoZSBVUkwgZG9lcyBub3QgY29uZm9ybSB0byB0aGUgVVJMIHN5bnRheC4KLSAgICovCi0gIFN0cmluZyBwcm9jZXNzVVJMKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBUT0RPOiBzeW50YXggY2hlY2sgVVJMIHZhbHVlLgotICAgIC8vIHJldHVybiBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHZhbHVlLCAKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5nZXRCYXNlSWRlbnRpZmllcigpKTsKLSAgICByZXR1cm4gdmFsdWU7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyBhbiBhdHRyaWJ1dGUgc3RyaW5nIG9mIHR5cGUgVF9ZRVNOTyBpbnRvCi0gICAqIGEgQm9vbGVhbiB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGhhbmRsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGN1cnJlbnQgU3R5bGVzaGVldEhhbmRsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcgdGhlIFRlbXBsYXRlcy4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KS4KLSAgICogQHBhcmFtIHZhbHVlIEEgc3RyaW5nIHRoYXQgc2hvdWxkIGJlICJ5ZXMiIG9yICJubyIuCi0gICAqCi0gICAqIEByZXR1cm4gQm9vbGVhbiBvYmplY3QgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBCb29sZWFuIHByb2Nlc3NZRVNOTygKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgdXJpLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSXMgdGhpcyBhbHJlYWR5IGNoZWNrZWQgc29tZXdoZXJlIGVsc2U/ICAtc2IKLSAgICBpZiAoISh2YWx1ZS5lcXVhbHMoInllcyIpIHx8IHZhbHVlLmVxdWFscygibm8iKSkpCi0gICAgICBoYW5kbGVyLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9WQUxVRV9TSE9VTERfRVFVQUwsIG5ldyBPYmplY3RbXXtuYW1lfSwgbnVsbCk7Ly8iVmFsdWUgZm9yICIgKyBuYW1lICsgIiBzaG91bGQgZXF1YWwgJ3llcycgb3IgJ25vJyIsCi0gICAgICAgICAgICAgICAgICAgIC8vbnVsbCk7Ci0KLSAgICByZXR1cm4gbmV3IEJvb2xlYW4odmFsdWUuZXF1YWxzKCJ5ZXMiKSA/IHRydWUgOiBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyBhbiBhdHRyaWJ1dGUgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wcm9jZXNzZWQgc3RyaW5nIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByb2Nlc3NlZCBPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBjYW4gbm90IGJlIHByb2Nlc3NlZC4KLSAgICovCi0gIE9iamVjdCBwcm9jZXNzVmFsdWUoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIG5hbWUsIFN0cmluZyByYXdOYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCB0eXBlID0gZ2V0VHlwZSgpOwotICAgIE9iamVjdCBwcm9jZXNzZWRWYWx1ZSA9IG51bGw7Ci0KLSAgICBzd2l0Y2ggKHR5cGUpCi0gICAgewotICAgIGNhc2UgVF9BVlQgOgotICAgICAgcHJvY2Vzc2VkVmFsdWUgPSBwcm9jZXNzQVZUKGhhbmRsZXIsIHVyaSwgbmFtZSwgcmF3TmFtZSwgdmFsdWUpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBUX0NEQVRBIDoKLSAgICAgIHByb2Nlc3NlZFZhbHVlID0gcHJvY2Vzc0NEQVRBKGhhbmRsZXIsIHVyaSwgbmFtZSwgcmF3TmFtZSwgdmFsdWUpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBUX0NIQVIgOgotICAgICAgcHJvY2Vzc2VkVmFsdWUgPSBwcm9jZXNzQ0hBUihoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsIHZhbHVlKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgVF9FTlVNIDoKLSAgICAgIHByb2Nlc3NlZFZhbHVlID0gcHJvY2Vzc0VOVU0oaGFuZGxlciwgdXJpLCBuYW1lLCByYXdOYW1lLCB2YWx1ZSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIFRfRVhQUiA6Ci0gICAgICBwcm9jZXNzZWRWYWx1ZSA9IHByb2Nlc3NFWFBSKGhhbmRsZXIsIHVyaSwgbmFtZSwgcmF3TmFtZSwgdmFsdWUpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBUX05NVE9LRU4gOgotICAgICAgcHJvY2Vzc2VkVmFsdWUgPSBwcm9jZXNzTk1UT0tFTihoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsIHZhbHVlKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgVF9QQVRURVJOIDoKLSAgICAgIHByb2Nlc3NlZFZhbHVlID0gcHJvY2Vzc1BBVFRFUk4oaGFuZGxlciwgdXJpLCBuYW1lLCByYXdOYW1lLCB2YWx1ZSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIFRfUFJJT1JJVFkgOgotICAgICAgcHJvY2Vzc2VkVmFsdWUgPSBwcm9jZXNzUFJJT1JJVFkoaGFuZGxlciwgdXJpLCBuYW1lLCByYXdOYW1lLCB2YWx1ZSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIFRfUU5BTUUgOgotICAgICAgcHJvY2Vzc2VkVmFsdWUgPSBwcm9jZXNzUU5BTUUoaGFuZGxlciwgdXJpLCBuYW1lLCByYXdOYW1lLCB2YWx1ZSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIFRfUU5BTUVTIDoKLSAgICAgIHByb2Nlc3NlZFZhbHVlID0gcHJvY2Vzc1FOQU1FUyhoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsIHZhbHVlKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgVF9TSU1QTEVQQVRURVJOTElTVCA6Ci0gICAgICBwcm9jZXNzZWRWYWx1ZSA9IHByb2Nlc3NTSU1QTEVQQVRURVJOTElTVChoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIFRfVVJMIDoKLSAgICAgIHByb2Nlc3NlZFZhbHVlID0gcHJvY2Vzc1VSTChoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsIHZhbHVlKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgVF9ZRVNOTyA6Ci0gICAgICBwcm9jZXNzZWRWYWx1ZSA9IHByb2Nlc3NZRVNOTyhoYW5kbGVyLCB1cmksIG5hbWUsIHJhd05hbWUsIHZhbHVlKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgVF9TVFJJTkdMSVNUIDoKLSAgICAgIHByb2Nlc3NlZFZhbHVlID0gcHJvY2Vzc1NUUklOR0xJU1QoaGFuZGxlciwgdXJpLCBuYW1lLCByYXdOYW1lLCB2YWx1ZSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIFRfUFJFRklYX1VSTExJU1QgOgotICAgICAgcHJvY2Vzc2VkVmFsdWUgPSBwcm9jZXNzUFJFRklYX1VSTExJU1QoaGFuZGxlciwgdXJpLCBuYW1lLCByYXdOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUpOwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgfQotCi0gICAgcmV0dXJuIHByb2Nlc3NlZFZhbHVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSBlbGVtIFRoZSBvYmplY3Qgb24gd2hpY2ggdGhlIHByb3BlcnR5IHdpbGwgYmUgc2V0LgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiB3cmFwcyBhbiBpbnZvY2F0aW9uIGV4Y2VwdGlvbiBpZiB0aGUKLSAgICogc2V0dGVyIG1ldGhvZCBjYW4gbm90IGJlIGludm9rZWQgb24gdGhlIG9iamVjdC4KLSAgICovCi0gIHZvaWQgc2V0RGVmQXR0clZhbHVlKFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIE9iamVjdCBlbGVtKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHNldEF0dHJWYWx1ZShoYW5kbGVyLCB0aGlzLmdldE5hbWVzcGFjZSgpLCB0aGlzLmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgdGhpcy5nZXROYW1lKCksIHRoaXMuZ2V0RGVmYXVsdCgpLCBlbGVtKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByaW1hdGl2ZSB0eXBlIGZvciB0aGUgY2xhc3MsIGlmIHRoZXJlCi0gICAqIGlzIG9uZS4gIElmIHRoZSBjbGFzcyBpcyBhIERvdWJsZSwgZm9yIGluc3RhbmNlLAotICAgKiB0aGlzIHdpbGwgcmV0dXJuIGRvdWJsZS5jbGFzcy4gIElmIHRoZSBjbGFzcyBpcyBub3Qgb25lCi0gICAqIG9mIHRoZSA5IHByaW1hdGl2ZSB0eXBlcywgaXQgd2lsbCByZXR1cm4gdGhlIHNhbWUKLSAgICogY2xhc3MgdGhhdCB3YXMgcGFzc2VkIGluLgotICAgKgotICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3Qgd2hpY2ggd2lsbCBiZSByZXNvbHZlZCB0byBhIHByaW1hdGl2ZSBjbGFzcyBvYmplY3QgaWYgcG9zc2libGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG1vc3QgcHJpbWF0aXZlIGNsYXNzIHJlcHJlc2VudGF0aW9uIHBvc3NpYmxlIGZvciB0aGUgb2JqZWN0LCBuZXZlciBudWxsLgotICAgKi8KLSAgcHJpdmF0ZSBDbGFzcyBnZXRQcmltYXRpdmVDbGFzcyhPYmplY3Qgb2JqKQotICB7Ci0KLSAgICBpZiAob2JqIGluc3RhbmNlb2YgWFBhdGgpCi0gICAgICByZXR1cm4gWFBhdGguY2xhc3M7Ci0KLSAgICBDbGFzcyBjbCA9IG9iai5nZXRDbGFzcygpOwotCi0gICAgaWYgKGNsID09IERvdWJsZS5jbGFzcykKLSAgICB7Ci0gICAgICBjbCA9IGRvdWJsZS5jbGFzczsKLSAgICB9Ci0KLSAgICBpZiAoY2wgPT0gRmxvYXQuY2xhc3MpCi0gICAgewotICAgICAgY2wgPSBmbG9hdC5jbGFzczsKLSAgICB9Ci0gICAgZWxzZSBpZiAoY2wgPT0gQm9vbGVhbi5jbGFzcykKLSAgICB7Ci0gICAgICBjbCA9IGJvb2xlYW4uY2xhc3M7Ci0gICAgfQotICAgIGVsc2UgaWYgKGNsID09IEJ5dGUuY2xhc3MpCi0gICAgewotICAgICAgY2wgPSBieXRlLmNsYXNzOwotICAgIH0KLSAgICBlbHNlIGlmIChjbCA9PSBDaGFyYWN0ZXIuY2xhc3MpCi0gICAgewotICAgICAgY2wgPSBjaGFyLmNsYXNzOwotICAgIH0KLSAgICBlbHNlIGlmIChjbCA9PSBTaG9ydC5jbGFzcykKLSAgICB7Ci0gICAgICBjbCA9IHNob3J0LmNsYXNzOwotICAgIH0KLSAgICBlbHNlIGlmIChjbCA9PSBJbnRlZ2VyLmNsYXNzKQotICAgIHsKLSAgICAgIGNsID0gaW50LmNsYXNzOwotICAgIH0KLSAgICBlbHNlIGlmIChjbCA9PSBMb25nLmNsYXNzKQotICAgIHsKLSAgICAgIGNsID0gbG9uZy5jbGFzczsKLSAgICB9Ci0KLSAgICByZXR1cm4gY2w7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgdmFsdWUgb24gYW4gYXR0cmlidXRlLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gYXR0clVyaSBUaGUgTmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBhdHRyTG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqIEBwYXJhbSBhdHRyUmF3TmFtZSBUaGUgcmF3IG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSwgaW5jbHVkaW5nIHBvc3NpYmxlIHByZWZpeC4KLSAgICogQHBhcmFtIGF0dHJWYWx1ZSBUaGUgYXR0cmlidXRlJ3MgdmFsdWUuCi0gICAqIEBwYXJhbSBlbGVtIFRoZSBvYmplY3QgdGhhdCBzaG91bGQgY29udGFpbiBhIHByb3BlcnR5IHRoYXQgcmVwcmVzZW50cyB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgdm9pZCBzZXRBdHRyVmFsdWUoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIGF0dHJVcmksIFN0cmluZyBhdHRyTG9jYWxOYW1lLCBTdHJpbmcgYXR0clJhd05hbWUsIFN0cmluZyBhdHRyVmFsdWUsIE9iamVjdCBlbGVtKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoYXR0clJhd05hbWUuZXF1YWxzKCJ4bWxucyIpIHx8IGF0dHJSYXdOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKQotICAgICAgcmV0dXJuOwotICAgICAgCi0gICAgU3RyaW5nIHNldHRlclN0cmluZyA9IGdldFNldHRlck1ldGhvZE5hbWUoKTsKLQotICAgIC8vIElmIHRoaXMgaXMgbnVsbCwgdGhlbiBpdCBpcyBhIGZvcmVpZ24gbmFtZXNwYWNlIGFuZCB3ZSAKLSAgICAvLyBkbyBub3QgcHJvY2VzcyBpdC4KLSAgICBpZiAobnVsbCAhPSBzZXR0ZXJTdHJpbmcpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIE1ldGhvZCBtZXRoOwotICAgICAgICBPYmplY3RbXSBhcmdzOwotCi0gICAgICAgIGlmKHNldHRlclN0cmluZy5lcXVhbHMoU19GT1JFSUdOQVRUUl9TRVRURVIpKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gd29ya2Fyb3VuZCBmb3IgcG9zc2libGUgY3JpbXNvbiBidWcKLSAgICAgICAgICBpZiggYXR0clVyaT09bnVsbCkgYXR0clVyaT0iIjsKLSAgICAgICAgICAvLyBGaXJzdCB0cnkgdG8gbWF0Y2ggd2l0aCB0aGUgcHJpbWF0aXZlIHZhbHVlLgotICAgICAgICAgIENsYXNzIHNjbGFzcyA9IGF0dHJVcmkuZ2V0Q2xhc3MoKTsKLSAgICAgICAgICBDbGFzc1tdIGFyZ1R5cGVzID0gbmV3IENsYXNzW117IHNjbGFzcywgc2NsYXNzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2xhc3MsIHNjbGFzcyB9OwotICAKLSAgICAgICAgICBtZXRoID0gZWxlbS5nZXRDbGFzcygpLmdldE1ldGhvZChzZXR0ZXJTdHJpbmcsIGFyZ1R5cGVzKTsKLSAgCi0gICAgICAgICAgYXJncyA9IG5ldyBPYmplY3RbXXsgYXR0clVyaSwgYXR0ckxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0clJhd05hbWUsIGF0dHJWYWx1ZSB9OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHByb2Nlc3NWYWx1ZShoYW5kbGVyLCBhdHRyVXJpLCBhdHRyTG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyUmF3TmFtZSwgYXR0clZhbHVlKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgLy8gRmlyc3QgdHJ5IHRvIG1hdGNoIHdpdGggdGhlIHByaW1hdGl2ZSB2YWx1ZS4KLSAgICAgICAgICBDbGFzc1tdIGFyZ1R5cGVzID0gbmV3IENsYXNzW117IGdldFByaW1hdGl2ZUNsYXNzKHZhbHVlKSB9OwotICAKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtZXRoID0gZWxlbS5nZXRDbGFzcygpLmdldE1ldGhvZChzZXR0ZXJTdHJpbmcsIGFyZ1R5cGVzKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc21lKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIENsYXNzIGNsID0gKChPYmplY3QpIHZhbHVlKS5nZXRDbGFzcygpOwotICAKLSAgICAgICAgICAgIC8vIElmIHRoaXMgZG9lc24ndCB3b3JrLCB0cnkgaXQgd2l0aCB0aGUgbm9uLXByaW1hdGl2ZSB2YWx1ZTsKLSAgICAgICAgICAgIGFyZ1R5cGVzWzBdID0gY2w7Ci0gICAgICAgICAgICBtZXRoID0gZWxlbS5nZXRDbGFzcygpLmdldE1ldGhvZChzZXR0ZXJTdHJpbmcsIGFyZ1R5cGVzKTsKLSAgICAgICAgICB9Ci0gIAotICAgICAgICAgIGFyZ3MgPSBuZXcgT2JqZWN0W117IHZhbHVlIH07Ci0gICAgICAgIH0KLQotICAgICAgICBtZXRoLmludm9rZShlbGVtLCBhcmdzKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gbnNtZSkKLSAgICAgIHsKLSAgICAgICAgaWYgKCFzZXR0ZXJTdHJpbmcuZXF1YWxzKFNfRk9SRUlHTkFUVFJfU0VUVEVSKSkKLSAgICAgICAgICBoYW5kbGVyLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GQUlMRURfQ0FMTElOR19NRVRIT0QsIG5ldyBPYmplY3RbXXtzZXR0ZXJTdHJpbmd9LCBuc21lKTsvLyJGYWlsZWQgY2FsbGluZyAiICsgc2V0dGVyU3RyaW5nICsgIiBtZXRob2QhIiwgbnNtZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpCi0gICAgICB7Ci0gICAgICAgIGhhbmRsZXIuZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZBSUxFRF9DQUxMSU5HX01FVEhPRCwgbmV3IE9iamVjdFtde3NldHRlclN0cmluZ30sIGlhZSk7Ly8iRmFpbGVkIGNhbGxpbmcgIiArIHNldHRlclN0cmluZyArICIgbWV0aG9kISIsIGlhZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBuc21lKQotICAgICAgewotICAgICAgICBoYW5kbGVyLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GQUlMRURfQ0FMTElOR19NRVRIT0QsIG5ldyBPYmplY3RbXXtzZXR0ZXJTdHJpbmd9LCBuc21lKTsvLyJGYWlsZWQgY2FsbGluZyAiICsgc2V0dGVyU3RyaW5nICsgIiBtZXRob2QhIiwgbnNtZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvWFNMVEVsZW1lbnREZWYuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xURWxlbWVudERlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYWJmNDAwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xURWxlbWVudERlZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODY2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBkZWZpbmVzIHRoZSBhbGxvd2VkIHN0cnVjdHVyZSBmb3IgYW4gZWxlbWVudCBpbiBhIFhTTFQgc3R5bGVzaGVldCwKLSAqIGlzIG1lYW50IHRvIHJlZmxlY3QgdGhlIHN0cnVjdHVyZSBkZWZpbmVkIGluIGh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkLCBhbmQgdGhlCi0gKiBtYXBwaW5nIGJldHdlZW4gWGFsYW4gY2xhc3NlcyBhbmQgdGhlIG1hcmt1cCBlbGVtZW50cyBpbiB0aGUgWFNMVCBpbnN0YW5jZS4KLSAqIFRoaXMgYWN0dWFsbHkgcmVwcmVzZW50cyBib3RoIHRleHQgbm9kZXMgYW5kIGVsZW1lbnRzLgotICovCi1wdWJsaWMgY2xhc3MgWFNMVEVsZW1lbnREZWYKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIFhTTFRFbGVtZW50RGVmLiAgVGhpcyBtdXN0IGJlIGZvbGxvd2VkIGJ5IGEKLSAgICogY2FsbCB0byBidWlsZCgpLgotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYoKXt9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZSBvZiBYU0xURWxlbWVudERlZi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSAgVGhlIE5hbWVzcGFjZSBVUkksICIqIiwgb3IgbnVsbC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgIioiLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZUFsaWFzIEEgcG90ZW50aWFsIGFsaWFzIGZvciB0aGUgbmFtZSwgb3IgbnVsbC4KLSAgICogQHBhcmFtIGVsZW1lbnRzIEFuIGFycmF5IG9mIGFsbG93ZWQgY2hpbGQgZWxlbWVudCBkZWZzLCBvciBudWxsLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBBbiBhcnJheSBvZiBhbGxvd2VkIGF0dHJpYnV0ZSBkZWZzLCBvciBudWxsLgotICAgKiBAcGFyYW0gY29udGVudEhhbmRsZXIgVGhlIGVsZW1lbnQgcHJvY2Vzc29yIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBjbGFzc09iamVjdCBUaGUgY2xhc3Mgb2YgdGhlIG9iamVjdCB0aGF0IHRoaXMgZWxlbWVudCBkZWYgc2hvdWxkIHByb2R1Y2UuCi0gICAqLwotICBYU0xURWxlbWVudERlZihYU0xUU2NoZW1hIHNjaGVtYSwgU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUsIFN0cmluZyBuYW1lQWxpYXMsCi0gICAgICAgICAgICAgICAgIFhTTFRFbGVtZW50RGVmW10gZWxlbWVudHMsIFhTTFRBdHRyaWJ1dGVEZWZbXSBhdHRyaWJ1dGVzLAotICAgICAgICAgICAgICAgICBYU0xURWxlbWVudFByb2Nlc3NvciBjb250ZW50SGFuZGxlciwgQ2xhc3MgY2xhc3NPYmplY3QpCi0gIHsKLSAgICBidWlsZChuYW1lc3BhY2UsIG5hbWUsIG5hbWVBbGlhcywgZWxlbWVudHMsIGF0dHJpYnV0ZXMsIGNvbnRlbnRIYW5kbGVyLAotICAgICAgICAgIGNsYXNzT2JqZWN0KTsKLSAgICBpZiAoIChudWxsICE9IG5hbWVzcGFjZSkKLSAgICAmJiAgKG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKQotICAgICAgICB8fCBuYW1lc3BhY2UuZXF1YWxzKENvbnN0YW50cy5TX0JVSUxUSU5fRVhURU5TSU9OU19VUkwpKSApCi0gICAgewotICAgICAgc2NoZW1hLmFkZEF2YWlsYWJsZUVsZW1lbnQobmV3IFFOYW1lKG5hbWVzcGFjZSwgbmFtZSkpOwotICAgICAgaWYobnVsbCAhPSBuYW1lQWxpYXMpCi0gICAgICAgIHNjaGVtYS5hZGRBdmFpbGFibGVFbGVtZW50KG5ldyBRTmFtZShuYW1lc3BhY2UsIG5hbWVBbGlhcykpOwotICAgIH0gCi0gIH0KLQkKLQkvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIFhTTFRFbGVtZW50RGVmLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlICBUaGUgTmFtZXNwYWNlIFVSSSwgIioiLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCAiKiIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lQWxpYXMgQSBwb3RlbnRpYWwgYWxpYXMgZm9yIHRoZSBuYW1lLCBvciBudWxsLgotICAgKiBAcGFyYW0gZWxlbWVudHMgQW4gYXJyYXkgb2YgYWxsb3dlZCBjaGlsZCBlbGVtZW50IGRlZnMsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIEFuIGFycmF5IG9mIGFsbG93ZWQgYXR0cmlidXRlIGRlZnMsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBjb250ZW50SGFuZGxlciBUaGUgZWxlbWVudCBwcm9jZXNzb3IgZm9yIHRoaXMgZWxlbWVudC4KLSAgICogQHBhcmFtIGNsYXNzT2JqZWN0IFRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IHRoYXQgdGhpcyBlbGVtZW50IGRlZiBzaG91bGQgcHJvZHVjZS4KLSAgICogQHBhcmFtIGhhc19yZXF1aXJlZCB0cnVlIGlmIHRoaXMgZWxlbWVudCBoYXMgcmVxdWlyZWQgZWxlbWVudHMgYnkgdGhlIFhTTFQgc3BlY2lmaWNhdGlvbi4KLSAgICovCi0gIFhTTFRFbGVtZW50RGVmKFhTTFRTY2hlbWEgc2NoZW1hLCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSwgU3RyaW5nIG5hbWVBbGlhcywKLSAgICAgICAgICAgICAgICAgWFNMVEVsZW1lbnREZWZbXSBlbGVtZW50cywgWFNMVEF0dHJpYnV0ZURlZltdIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIGNvbnRlbnRIYW5kbGVyLCBDbGFzcyBjbGFzc09iamVjdCwgYm9vbGVhbiBoYXNfcmVxdWlyZWQpCi0gIHsKLQkJdGhpcy5tX2hhc19yZXF1aXJlZCA9IGhhc19yZXF1aXJlZDsKLSAgICBidWlsZChuYW1lc3BhY2UsIG5hbWUsIG5hbWVBbGlhcywgZWxlbWVudHMsIGF0dHJpYnV0ZXMsIGNvbnRlbnRIYW5kbGVyLAotICAgICAgICAgIGNsYXNzT2JqZWN0KTsKLSAgICBpZiAoIChudWxsICE9IG5hbWVzcGFjZSkKLSAgICAmJiAgKG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKQotICAgICAgICB8fCBuYW1lc3BhY2UuZXF1YWxzKENvbnN0YW50cy5TX0JVSUxUSU5fRVhURU5TSU9OU19VUkwpKSApCi0gICAgewotICAgICAgc2NoZW1hLmFkZEF2YWlsYWJsZUVsZW1lbnQobmV3IFFOYW1lKG5hbWVzcGFjZSwgbmFtZSkpOwotICAgICAgaWYobnVsbCAhPSBuYW1lQWxpYXMpCi0gICAgICAgIHNjaGVtYS5hZGRBdmFpbGFibGVFbGVtZW50KG5ldyBRTmFtZShuYW1lc3BhY2UsIG5hbWVBbGlhcykpOwotICAgIH0gCi0JCQotICB9Ci0JCi0JLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZSBvZiBYU0xURWxlbWVudERlZi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSAgVGhlIE5hbWVzcGFjZSBVUkksICIqIiwgb3IgbnVsbC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgIioiLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZUFsaWFzIEEgcG90ZW50aWFsIGFsaWFzIGZvciB0aGUgbmFtZSwgb3IgbnVsbC4KLSAgICogQHBhcmFtIGVsZW1lbnRzIEFuIGFycmF5IG9mIGFsbG93ZWQgY2hpbGQgZWxlbWVudCBkZWZzLCBvciBudWxsLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBBbiBhcnJheSBvZiBhbGxvd2VkIGF0dHJpYnV0ZSBkZWZzLCBvciBudWxsLgotICAgKiBAcGFyYW0gY29udGVudEhhbmRsZXIgVGhlIGVsZW1lbnQgcHJvY2Vzc29yIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBjbGFzc09iamVjdCBUaGUgY2xhc3Mgb2YgdGhlIG9iamVjdCB0aGF0IHRoaXMgZWxlbWVudCBkZWYgc2hvdWxkIHByb2R1Y2UuCi0gICAqIEBwYXJhbSBoYXNfcmVxdWlyZWQgdHJ1ZSBpZiB0aGlzIGVsZW1lbnQgaGFzIHJlcXVpcmVkIGVsZW1lbnRzIGJ5IHRoZSBYU0xUIHNwZWNpZmljYXRpb24uCi0gICAqIEBwYXJhbSByZXF1aXJlZCB0cnVlIGlmIHRoaXMgZWxlbWVudCBpcyByZXF1aXJlZCBieSB0aGUgWFNMVCBzcGVjaWZpY2F0aW9uLgotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYoWFNMVFNjaGVtYSBzY2hlbWEsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBTdHJpbmcgbmFtZUFsaWFzLAotICAgICAgICAgICAgICAgICBYU0xURWxlbWVudERlZltdIGVsZW1lbnRzLCBYU0xUQXR0cmlidXRlRGVmW10gYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgY29udGVudEhhbmRsZXIsIENsYXNzIGNsYXNzT2JqZWN0LCAKLQkJCQkJCQkJIGJvb2xlYW4gaGFzX3JlcXVpcmVkLCBib29sZWFuIHJlcXVpcmVkKQotICB7Ci0gICAgdGhpcyhzY2hlbWEsIG5hbWVzcGFjZSwgbmFtZSwgIG5hbWVBbGlhcywKLSAgICAgICAgICAgICAgICAgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLCBjbGFzc09iamVjdCwgaGFzX3JlcXVpcmVkKTsKLQkJdGhpcy5tX3JlcXVpcmVkID0gcmVxdWlyZWQ7Ci0gIH0KLQkKLQkvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIFhTTFRFbGVtZW50RGVmLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlICBUaGUgTmFtZXNwYWNlIFVSSSwgIioiLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCAiKiIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lQWxpYXMgQSBwb3RlbnRpYWwgYWxpYXMgZm9yIHRoZSBuYW1lLCBvciBudWxsLgotICAgKiBAcGFyYW0gZWxlbWVudHMgQW4gYXJyYXkgb2YgYWxsb3dlZCBjaGlsZCBlbGVtZW50IGRlZnMsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIEFuIGFycmF5IG9mIGFsbG93ZWQgYXR0cmlidXRlIGRlZnMsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBjb250ZW50SGFuZGxlciBUaGUgZWxlbWVudCBwcm9jZXNzb3IgZm9yIHRoaXMgZWxlbWVudC4KLSAgICogQHBhcmFtIGNsYXNzT2JqZWN0IFRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IHRoYXQgdGhpcyBlbGVtZW50IGRlZiBzaG91bGQgcHJvZHVjZS4KLSAgICogQHBhcmFtIGhhc19yZXF1aXJlZCB0cnVlIGlmIHRoaXMgZWxlbWVudCBoYXMgcmVxdWlyZWQgZWxlbWVudHMgYnkgdGhlIFhTTFQgc3BlY2lmaWNhdGlvbi4KLSAgICogQHBhcmFtIHJlcXVpcmVkIHRydWUgaWYgdGhpcyBlbGVtZW50IGlzIHJlcXVpcmVkIGJ5IHRoZSBYU0xUIHNwZWNpZmljYXRpb24uCi0gICAqIEBwYXJhbSBvcmRlciB0aGUgb3JkZXIgdGhpcyBlbGVtZW50IHNob3VsZCBhcHBlYXIgYWNjb3JkaW5nIHRvIHRoZSBYU0xUIHNwZWNpZmljYXRpb24uICAgCi0gICAqIEBwYXJhbSBtdWx0aUFsbG93ZWQgd2hldGhlciB0aGlzIGVsZW1lbnQgaXMgYWxsb3dlZCBtb3JlIHRoYW4gb25jZQotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYoWFNMVFNjaGVtYSBzY2hlbWEsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBTdHJpbmcgbmFtZUFsaWFzLAotICAgICAgICAgICAgICAgICBYU0xURWxlbWVudERlZltdIGVsZW1lbnRzLCBYU0xUQXR0cmlidXRlRGVmW10gYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgY29udGVudEhhbmRsZXIsIENsYXNzIGNsYXNzT2JqZWN0LCAKLQkJCQkJCQkJIGJvb2xlYW4gaGFzX3JlcXVpcmVkLCBib29sZWFuIHJlcXVpcmVkLCBpbnQgb3JkZXIsIAotCQkJCQkJCQkgYm9vbGVhbiBtdWx0aUFsbG93ZWQpCi0gIHsKLQkJdGhpcyhzY2hlbWEsIG5hbWVzcGFjZSwgbmFtZSwgIG5hbWVBbGlhcywKLSAgICAgICAgICAgICAgICAgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLCBjbGFzc09iamVjdCwgaGFzX3JlcXVpcmVkLCByZXF1aXJlZCk7ICAgIAotCQl0aGlzLm1fb3JkZXIgPSBvcmRlcjsKLQkJdGhpcy5tX211bHRpQWxsb3dlZCA9IG11bHRpQWxsb3dlZDsKLSAgfQotCQotCS8qKgotICAgKiBDb25zdHJ1Y3QgYW4gaW5zdGFuY2Ugb2YgWFNMVEVsZW1lbnREZWYuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgIFRoZSBOYW1lc3BhY2UgVVJJLCAiKiIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksICIqIiwgb3IgbnVsbC4KLSAgICogQHBhcmFtIG5hbWVBbGlhcyBBIHBvdGVudGlhbCBhbGlhcyBmb3IgdGhlIG5hbWUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBlbGVtZW50cyBBbiBhcnJheSBvZiBhbGxvd2VkIGNoaWxkIGVsZW1lbnQgZGVmcywgb3IgbnVsbC4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQW4gYXJyYXkgb2YgYWxsb3dlZCBhdHRyaWJ1dGUgZGVmcywgb3IgbnVsbC4KLSAgICogQHBhcmFtIGNvbnRlbnRIYW5kbGVyIFRoZSBlbGVtZW50IHByb2Nlc3NvciBmb3IgdGhpcyBlbGVtZW50LgotICAgKiBAcGFyYW0gY2xhc3NPYmplY3QgVGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgdGhhdCB0aGlzIGVsZW1lbnQgZGVmIHNob3VsZCBwcm9kdWNlLgotICAgKiBAcGFyYW0gaGFzX3JlcXVpcmVkIHRydWUgaWYgdGhpcyBlbGVtZW50IGhhcyByZXF1aXJlZCBlbGVtZW50cyBieSB0aGUgWFNMVCBzcGVjaWZpY2F0aW9uLgotICAgKiBAcGFyYW0gcmVxdWlyZWQgdHJ1ZSBpZiB0aGlzIGVsZW1lbnQgaXMgcmVxdWlyZWQgYnkgdGhlIFhTTFQgc3BlY2lmaWNhdGlvbi4KLSAgICogQHBhcmFtIGhhc19vcmRlciB3aGV0aGVyIHRoaXMgZWxlbWVudCBoYXMgb3JkZXJlZCBjaGlsZCBlbGVtZW50cwotICAgKiBAcGFyYW0gb3JkZXIgdGhlIG9yZGVyIHRoaXMgZWxlbWVudCBzaG91bGQgYXBwZWFyIGFjY29yZGluZyB0byB0aGUgWFNMVCBzcGVjaWZpY2F0aW9uLiAgIAotICAgKiBAcGFyYW0gbXVsdGlBbGxvd2VkIHdoZXRoZXIgdGhpcyBlbGVtZW50IGlzIGFsbG93ZWQgbW9yZSB0aGFuIG9uY2UKLSAgICovCi0gIFhTTFRFbGVtZW50RGVmKFhTTFRTY2hlbWEgc2NoZW1hLCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSwgU3RyaW5nIG5hbWVBbGlhcywKLSAgICAgICAgICAgICAgICAgWFNMVEVsZW1lbnREZWZbXSBlbGVtZW50cywgWFNMVEF0dHJpYnV0ZURlZltdIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIGNvbnRlbnRIYW5kbGVyLCBDbGFzcyBjbGFzc09iamVjdCwgCi0JCQkJCQkJCSBib29sZWFuIGhhc19yZXF1aXJlZCwgYm9vbGVhbiByZXF1aXJlZCwgYm9vbGVhbiBoYXNfb3JkZXIsIGludCBvcmRlciwgCi0JCQkJCQkJCSBib29sZWFuIG11bHRpQWxsb3dlZCkKLSAgewotCQl0aGlzKHNjaGVtYSwgbmFtZXNwYWNlLCBuYW1lLCAgbmFtZUFsaWFzLAotICAgICAgICAgICAgICAgICBlbGVtZW50cywgYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgY29udGVudEhhbmRsZXIsIGNsYXNzT2JqZWN0LCBoYXNfcmVxdWlyZWQsIHJlcXVpcmVkKTsgICAgCi0JCXRoaXMubV9vcmRlciA9IG9yZGVyOwotCQl0aGlzLm1fbXVsdGlBbGxvd2VkID0gbXVsdGlBbGxvd2VkOwotICAgIHRoaXMubV9pc09yZGVyZWQgPSBoYXNfb3JkZXI7CQkKLSAgfQotCQotCS8qKgotICAgKiBDb25zdHJ1Y3QgYW4gaW5zdGFuY2Ugb2YgWFNMVEVsZW1lbnREZWYuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgIFRoZSBOYW1lc3BhY2UgVVJJLCAiKiIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksICIqIiwgb3IgbnVsbC4KLSAgICogQHBhcmFtIG5hbWVBbGlhcyBBIHBvdGVudGlhbCBhbGlhcyBmb3IgdGhlIG5hbWUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBlbGVtZW50cyBBbiBhcnJheSBvZiBhbGxvd2VkIGNoaWxkIGVsZW1lbnQgZGVmcywgb3IgbnVsbC4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQW4gYXJyYXkgb2YgYWxsb3dlZCBhdHRyaWJ1dGUgZGVmcywgb3IgbnVsbC4KLSAgICogQHBhcmFtIGNvbnRlbnRIYW5kbGVyIFRoZSBlbGVtZW50IHByb2Nlc3NvciBmb3IgdGhpcyBlbGVtZW50LgotICAgKiBAcGFyYW0gY2xhc3NPYmplY3QgVGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgdGhhdCB0aGlzIGVsZW1lbnQgZGVmIHNob3VsZCBwcm9kdWNlLgotICAgKiBAcGFyYW0gaGFzX29yZGVyIHdoZXRoZXIgdGhpcyBlbGVtZW50IGhhcyBvcmRlcmVkIGNoaWxkIGVsZW1lbnRzCi0gICAqIEBwYXJhbSBvcmRlciB0aGUgb3JkZXIgdGhpcyBlbGVtZW50IHNob3VsZCBhcHBlYXIgYWNjb3JkaW5nIHRvIHRoZSBYU0xUIHNwZWNpZmljYXRpb24uICAgCi0gICAqIEBwYXJhbSBtdWx0aUFsbG93ZWQgd2hldGhlciB0aGlzIGVsZW1lbnQgaXMgYWxsb3dlZCBtb3JlIHRoYW4gb25jZQotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYoWFNMVFNjaGVtYSBzY2hlbWEsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBTdHJpbmcgbmFtZUFsaWFzLAotICAgICAgICAgICAgICAgICBYU0xURWxlbWVudERlZltdIGVsZW1lbnRzLCBYU0xUQXR0cmlidXRlRGVmW10gYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgY29udGVudEhhbmRsZXIsIENsYXNzIGNsYXNzT2JqZWN0LCAKLQkJCQkJCQkJIGJvb2xlYW4gaGFzX29yZGVyLCBpbnQgb3JkZXIsIGJvb2xlYW4gbXVsdGlBbGxvd2VkKQotICB7Ci0gICAgdGhpcyhzY2hlbWEsIG5hbWVzcGFjZSwgbmFtZSwgIG5hbWVBbGlhcywKLSAgICAgICAgICAgICAgICAgZWxlbWVudHMsIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyLCBjbGFzc09iamVjdCwgCi0JCQkJCQkJCSBvcmRlciwgbXVsdGlBbGxvd2VkKTsKLQkJdGhpcy5tX2lzT3JkZXJlZCA9IGhhc19vcmRlcjsJCQotICB9Ci0JCi0JLyoqCi0gICAqIENvbnN0cnVjdCBhbiBpbnN0YW5jZSBvZiBYU0xURWxlbWVudERlZi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSAgVGhlIE5hbWVzcGFjZSBVUkksICIqIiwgb3IgbnVsbC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgIioiLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZUFsaWFzIEEgcG90ZW50aWFsIGFsaWFzIGZvciB0aGUgbmFtZSwgb3IgbnVsbC4KLSAgICogQHBhcmFtIGVsZW1lbnRzIEFuIGFycmF5IG9mIGFsbG93ZWQgY2hpbGQgZWxlbWVudCBkZWZzLCBvciBudWxsLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBBbiBhcnJheSBvZiBhbGxvd2VkIGF0dHJpYnV0ZSBkZWZzLCBvciBudWxsLgotICAgKiBAcGFyYW0gY29udGVudEhhbmRsZXIgVGhlIGVsZW1lbnQgcHJvY2Vzc29yIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBjbGFzc09iamVjdCBUaGUgY2xhc3Mgb2YgdGhlIG9iamVjdCB0aGF0IHRoaXMgZWxlbWVudCBkZWYgc2hvdWxkIHByb2R1Y2UuCi0gICAqIEBwYXJhbSBvcmRlciB0aGUgb3JkZXIgdGhpcyBlbGVtZW50IHNob3VsZCBhcHBlYXIgYWNjb3JkaW5nIHRvIHRoZSBYU0xUIHNwZWNpZmljYXRpb24uICAgCi0gICAqIEBwYXJhbSBtdWx0aUFsbG93ZWQgd2hldGhlciB0aGlzIGVsZW1lbnQgaXMgYWxsb3dlZCBtb3JlIHRoYW4gb25jZQotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYoWFNMVFNjaGVtYSBzY2hlbWEsIFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBuYW1lLCBTdHJpbmcgbmFtZUFsaWFzLAotICAgICAgICAgICAgICAgICBYU0xURWxlbWVudERlZltdIGVsZW1lbnRzLCBYU0xUQXR0cmlidXRlRGVmW10gYXR0cmlidXRlcywKLSAgICAgICAgICAgICAgICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgY29udGVudEhhbmRsZXIsIENsYXNzIGNsYXNzT2JqZWN0LCAKLQkJCQkJCQkJIGludCBvcmRlciwgYm9vbGVhbiBtdWx0aUFsbG93ZWQpCi0gIHsKLSAgICB0aGlzKHNjaGVtYSwgbmFtZXNwYWNlLCBuYW1lLCBuYW1lQWxpYXMsIGVsZW1lbnRzLCBhdHRyaWJ1dGVzLCBjb250ZW50SGFuZGxlciwKLSAgICAgICAgICBjbGFzc09iamVjdCk7Ci0gICAgdGhpcy5tX29yZGVyID0gb3JkZXI7Ci0JCXRoaXMubV9tdWx0aUFsbG93ZWQgPSBtdWx0aUFsbG93ZWQ7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIFhTTFRFbGVtZW50RGVmIHRoYXQgcmVwcmVzZW50cyB0ZXh0LgotICAgKgotICAgKiBAcGFyYW0gY2xhc3NPYmplY3QgVGhlIGNsYXNzIG9mIHRoZSBvYmplY3QgdGhhdCB0aGlzIGVsZW1lbnQgZGVmIHNob3VsZCBwcm9kdWNlLgotICAgKiBAcGFyYW0gY29udGVudEhhbmRsZXIgVGhlIGVsZW1lbnQgcHJvY2Vzc29yIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqIEBwYXJhbSB0eXBlIENvbnRlbnQgdHlwZSwgb25lIG9mIFRfRUxFTUVOVCwgVF9QQ0RBVEEsIG9yIFRfQU5ZLgotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYoQ2xhc3MgY2xhc3NPYmplY3QsIFhTTFRFbGVtZW50UHJvY2Vzc29yIGNvbnRlbnRIYW5kbGVyLAotICAgICAgICAgICAgICAgICBpbnQgdHlwZSkKLSAgewotCi0gICAgdGhpcy5tX2NsYXNzT2JqZWN0ID0gY2xhc3NPYmplY3Q7Ci0gICAgdGhpcy5tX3R5cGUgPSB0eXBlOwotCi0gICAgc2V0RWxlbWVudFByb2Nlc3Nvcihjb250ZW50SGFuZGxlcik7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIFhTTFRFbGVtZW50RGVmLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlICBUaGUgTmFtZXNwYWNlIFVSSSwgIioiLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCAiKiIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lQWxpYXMgQSBwb3RlbnRpYWwgYWxpYXMgZm9yIHRoZSBuYW1lLCBvciBudWxsLgotICAgKiBAcGFyYW0gZWxlbWVudHMgQW4gYXJyYXkgb2YgYWxsb3dlZCBjaGlsZCBlbGVtZW50IGRlZnMsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIEFuIGFycmF5IG9mIGFsbG93ZWQgYXR0cmlidXRlIGRlZnMsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBjb250ZW50SGFuZGxlciBUaGUgZWxlbWVudCBwcm9jZXNzb3IgZm9yIHRoaXMgZWxlbWVudC4KLSAgICogQHBhcmFtIGNsYXNzT2JqZWN0IFRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IHRoYXQgdGhpcyBlbGVtZW50IGRlZiBzaG91bGQgcHJvZHVjZS4KLSAgICovCi0gIHZvaWQgYnVpbGQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUsIFN0cmluZyBuYW1lQWxpYXMsCi0gICAgICAgICAgICAgWFNMVEVsZW1lbnREZWZbXSBlbGVtZW50cywgWFNMVEF0dHJpYnV0ZURlZltdIGF0dHJpYnV0ZXMsCi0gICAgICAgICAgICAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgY29udGVudEhhbmRsZXIsIENsYXNzIGNsYXNzT2JqZWN0KQotICB7Ci0KLSAgICB0aGlzLm1fbmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgIHRoaXMubV9uYW1lID0gbmFtZTsKLSAgICB0aGlzLm1fbmFtZUFsaWFzID0gbmFtZUFsaWFzOwotICAgIHRoaXMubV9lbGVtZW50cyA9IGVsZW1lbnRzOwotICAgIHRoaXMubV9hdHRyaWJ1dGVzID0gYXR0cmlidXRlczsKLQotICAgIHNldEVsZW1lbnRQcm9jZXNzb3IoY29udGVudEhhbmRsZXIpOwotCi0gICAgdGhpcy5tX2NsYXNzT2JqZWN0ID0gY2xhc3NPYmplY3Q7Ci0JCQotCQlpZiAoaGFzUmVxdWlyZWQoKSAmJiBtX2VsZW1lbnRzICE9IG51bGwpCi0JCXsKLQkJCWludCBuID0gbV9lbGVtZW50cy5sZW5ndGg7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLQkJCXsKLQkJCQlYU0xURWxlbWVudERlZiBkZWYgPSBtX2VsZW1lbnRzW2ldOwotCQkJCQotCQkJCWlmIChkZWYgIT0gbnVsbCAmJiBkZWYuZ2V0UmVxdWlyZWQoKSkKLQkJCQl7Ci0JCQkJCWlmIChtX3JlcXVpcmVkRm91bmQgPT0gbnVsbCkJCQkKLQkJCQkJCW1fcmVxdWlyZWRGb3VuZCA9IG5ldyBIYXNodGFibGUoKTsKLQkJCQkJbV9yZXF1aXJlZEZvdW5kLnB1dChkZWYuZ2V0TmFtZSgpLCAieHNsOiIgK2RlZi5nZXROYW1lKCkpOyAKLQkJCQl9Ci0JCQl9Ci0JCX0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBlcXVhbCwgd2hlbiBlaXRoZXIgb25lIG1heSBiZSBudWxsLgotICAgKiBJZiBib3RoIGFyZSBudWxsLCB0aGV5IGFyZSBjb25zaWRlcmVkIGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMSBBIHJlZmVyZW5jZSB0byB0aGUgZmlyc3Qgb2JqZWN0LCBvciBudWxsLgotICAgKiBAcGFyYW0gb2JqMiBBIHJlZmVyZW5jZSB0byB0aGUgc2Vjb25kIG9iamVjdCwgb3IgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0byBvYmplY3RzIGFyZSBlcXVhbCBieSBib3RoIGJlaW5nIG51bGwgb3IgCi0gICAqIGJlY2F1c2Ugb2JqMi5lcXVhbHMob2JqMSkgcmV0dXJucyB0cnVlLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBlcXVhbHNNYXlCZU51bGwoT2JqZWN0IG9iajEsIE9iamVjdCBvYmoyKQotICB7Ci0gICAgcmV0dXJuIChvYmoyID09IG9iajEpCi0gICAgICAgICAgIHx8ICgobnVsbCAhPSBvYmoxKSAmJiAobnVsbCAhPSBvYmoyKSAmJiBvYmoyLmVxdWFscyhvYmoxKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdHdvIHN0cmluZyByZWZzIGFyZSBlcXVhbCwKLSAgICogZXF1YWxpdHkgYmVpbmcgZGVmaW5lZCBhczoKLSAgICogMSkgQm90aCBzdHJpbmdzIGFyZSBudWxsLgotICAgKiAyKSBPbmUgc3RyaW5nIGlzIG51bGwgYW5kIHRoZSBvdGhlciBpcyBlbXB0eS4KLSAgICogMykgQm90aCBzdHJpbmdzIGFyZSBub24tbnVsbCwgYW5kIGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gczEgQSByZWZlcmVuY2UgdG8gdGhlIGZpcnN0IHN0cmluZywgb3IgbnVsbC4KLSAgICogQHBhcmFtIHMyIEEgcmVmZXJlbmNlIHRvIHRoZSBzZWNvbmQgc3RyaW5nLCBvciBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgQm90aCBzdHJpbmdzIGFyZSBudWxsLCBvciBpZiAKLSAgICogb25lIHN0cmluZyBpcyBudWxsIGFuZCB0aGUgb3RoZXIgaXMgZW1wdHksIG9yIGlmIAotICAgKiBib3RoIHN0cmluZ3MgYXJlIG5vbi1udWxsLCBhbmQgZXF1YWwgYmVjYXVzZSAKLSAgICogczEuZXF1YWxzKHMyKSByZXR1cm5zIHRydWUuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGVxdWFsc01heUJlTnVsbE9yWmVyb0xlbihTdHJpbmcgczEsIFN0cmluZyBzMikKLSAgewotCi0gICAgaW50IGxlbjEgPSAoczEgPT0gbnVsbCkgPyAwIDogczEubGVuZ3RoKCk7Ci0gICAgaW50IGxlbjIgPSAoczIgPT0gbnVsbCkgPyAwIDogczIubGVuZ3RoKCk7Ci0KLSAgICByZXR1cm4gKGxlbjEgIT0gbGVuMikgPyBmYWxzZSA6IChsZW4xID09IDApID8gdHJ1ZSA6IHMxLmVxdWFscyhzMik7Ci0gIH0KLQotICAvKiogQ29udGVudCB0eXBlIGVudW1lcmF0aW9ucyAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IFRfRUxFTUVOVCA9IDEsIFRfUENEQVRBID0gMiwgVF9BTlkgPSAzOwotCi0gIC8qKgotICAgKiBUaGUgdHlwZSBvZiB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwcml2YXRlIGludCBtX3R5cGUgPSBUX0VMRU1FTlQ7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gQ29udGVudCB0eXBlLCBvbmUgb2YgVF9FTEVNRU5ULCBUX1BDREFUQSwgb3IgVF9BTlkuCi0gICAqLwotICBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gbV90eXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdHlwZSBvZiB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSB0IENvbnRlbnQgdHlwZSwgb25lIG9mIFRfRUxFTUVOVCwgVF9QQ0RBVEEsIG9yIFRfQU5ZLgotICAgKi8KLSAgdm9pZCBzZXRUeXBlKGludCB0KQotICB7Ci0gICAgbV90eXBlID0gdDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgYWxsb3dlZCBuYW1lc3BhY2UgZm9yIHRoaXMgZWxlbWVudC4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbmFtZXNwYWNlOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFsbG93ZWQgbmFtZXNwYWNlIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIE5hbWVzcGFjZSBVUkksICIqIiwgb3IgbnVsbC4KLSAgICovCi0gIFN0cmluZyBnZXROYW1lc3BhY2UoKQotICB7Ci0gICAgcmV0dXJuIG1fbmFtZXNwYWNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lIG9mIHRoaXMgZWxlbWVudC4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbmFtZTsKLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBuYW1lIG9mIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbG9jYWwgbmFtZSBvZiB0aGlzIGVsZW1lbnQsICIqIiwgb3IgbnVsbC4KLSAgICovCi0gIFN0cmluZyBnZXROYW1lKCkKLSAgewotICAgIHJldHVybiBtX25hbWU7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG5hbWUgb2YgdGhpcyBlbGVtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9uYW1lQWxpYXM7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmFtZSBvZiB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBwb3RlbnRpYWwgYWxpYXMgZm9yIHRoZSBuYW1lLCBvciBudWxsLgotICAgKi8KLSAgU3RyaW5nIGdldE5hbWVBbGlhcygpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lQWxpYXM7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGFsbG93ZWQgZWxlbWVudHMgZm9yIHRoaXMgdHlwZS4KLSAgICovCi0gIHByaXZhdGUgWFNMVEVsZW1lbnREZWZbXSBtX2VsZW1lbnRzOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFsbG93ZWQgZWxlbWVudHMgZm9yIHRoaXMgdHlwZS4KLSAgICoKLSAgICogQHJldHVybiBBbiBhcnJheSBvZiBhbGxvd2VkIGNoaWxkIGVsZW1lbnQgZGVmcywgb3IgbnVsbC4KLSAgICovCi0gIFhTTFRFbGVtZW50RGVmW10gZ2V0RWxlbWVudHMoKQotICB7Ci0gICAgcmV0dXJuIG1fZWxlbWVudHM7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBhbGxvd2VkIGVsZW1lbnRzIGZvciB0aGlzIHR5cGUuCi0gICAqCi0gICAqIEBwYXJhbSBkZWZzIEFuIGFycmF5IG9mIGFsbG93ZWQgY2hpbGQgZWxlbWVudCBkZWZzLCBvciBudWxsLgotICAgKi8KLSAgdm9pZCBzZXRFbGVtZW50cyhYU0xURWxlbWVudERlZltdIGRlZnMpCi0gIHsKLSAgICBtX2VsZW1lbnRzID0gZGVmczsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBuYW1lc3BhY2UgVVJJIGFuZCBsb2NhbCBuYW1lIG1hdGNoIHRoaXMKLSAgICogZWxlbWVudC4KLSAgICogQHBhcmFtIHVyaSBUaGUgbmFtZXNwYWNlIHVyaSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgYW4gZWxlbWVudCwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdXJpIGFuZCBsb2NhbCBuYW1lIGFyZ3VtZW50cyBhcmUgY29uc2lkZXJlZCAKLSAgICogdG8gbWF0Y2ggdGhlIHVyaSBhbmQgbG9jYWwgbmFtZSBvZiB0aGlzIGVsZW1lbnQgZGVmLgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIFFOYW1lRXF1YWxzKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLQotICAgIHJldHVybiAoZXF1YWxzTWF5QmVOdWxsT3JaZXJvTGVuKG1fbmFtZXNwYWNlLCB1cmkpCi0gICAgICAgICAgICAmJiAoZXF1YWxzTWF5QmVOdWxsT3JaZXJvTGVuKG1fbmFtZSwgbG9jYWxOYW1lKQotICAgICAgICAgICAgICAgIHx8IGVxdWFsc01heUJlTnVsbE9yWmVyb0xlbihtX25hbWVBbGlhcywgbG9jYWxOYW1lKSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlIFVSSSwgYW5kIGEgbG9jYWwgbmFtZSwgZ2V0IHRoZSBwcm9jZXNzb3IKLSAgICogZm9yIHRoZSBlbGVtZW50LCBvciByZXR1cm4gbnVsbCBpZiBub3QgYWxsb3dlZC4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQgcHJvY2Vzc29yIHRoYXQgbWF0Y2hlcyB0aGUgYXJndW1lbnRzLCBvciBudWxsLgotICAgKi8KLSAgWFNMVEVsZW1lbnRQcm9jZXNzb3IgZ2V0UHJvY2Vzc29yRm9yKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpIAotCXsKLQotICAgIFhTTFRFbGVtZW50UHJvY2Vzc29yIGVsZW1EZWYgPSBudWxsOyAgLy8gcmV0dXJuIHZhbHVlCi0KLSAgICBpZiAobnVsbCA9PSBtX2VsZW1lbnRzKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBpbnQgbiA9IG1fZWxlbWVudHMubGVuZ3RoOwotICAgIGludCBvcmRlciA9IC0xOwotCQlib29sZWFuIG11bHRpQWxsb3dlZCA9IHRydWU7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgWFNMVEVsZW1lbnREZWYgZGVmID0gbV9lbGVtZW50c1tpXTsKLQotICAgICAgLy8gQSAiKiIgc2lnbmFscyB0aGF0IHRoZSBlbGVtZW50IGFsbG93cyBsaXRlcmFsIHJlc3VsdAotICAgICAgLy8gZWxlbWVudHMsIHNvIGp1c3QgYXNzaWduIHRoZSBkZWYsIGFuZCBjb250aW51ZSB0byAgCi0gICAgICAvLyBzZWUgaWYgYW55dGhpbmcgZWxzZSBtYXRjaGVzLgotICAgICAgaWYgKGRlZi5tX25hbWUuZXF1YWxzKCIqIikpCi0gICAgICB7Ci0JCQkJCi0gICAgICAgIC8vIERvbid0IGFsbG93IHhzbCBlbGVtZW50cwotICAgICAgICBpZiAoIWVxdWFsc01heUJlTnVsbE9yWmVyb0xlbih1cmksIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCkpCi0JCQkJewotICAgICAgICAgIGVsZW1EZWYgPSBkZWYubV9lbGVtZW50UHJvY2Vzc29yOwotCQkJCSAgb3JkZXIgPSBkZWYuZ2V0T3JkZXIoKTsKLQkJCQkJbXVsdGlBbGxvd2VkID0gZGVmLmdldE11bHRpQWxsb3dlZCgpOwotCQkJCX0KLSAgICAgIH0KLQkJCWVsc2UgaWYgKGRlZi5RTmFtZUVxdWFscyh1cmksIGxvY2FsTmFtZSkpCi0JCQl7CQotCQkJCWlmIChkZWYuZ2V0UmVxdWlyZWQoKSkKLQkJCQkJdGhpcy5zZXRSZXF1aXJlZEZvdW5kKGRlZi5nZXROYW1lKCksIHRydWUpOwotCQkJCW9yZGVyID0gZGVmLmdldE9yZGVyKCk7Ci0JCQkJbXVsdGlBbGxvd2VkID0gZGVmLmdldE11bHRpQWxsb3dlZCgpOwotCQkJCWVsZW1EZWYgPSBkZWYubV9lbGVtZW50UHJvY2Vzc29yOwotCQkJCWJyZWFrOwotCQkJfQotCQl9CQkKLQkJCi0JCWlmIChlbGVtRGVmICE9IG51bGwgJiYgdGhpcy5pc09yZGVyZWQoKSkKLQkJewkJCQotCQkJaW50IGxhc3RPcmRlciA9IGdldExhc3RPcmRlcigpOwotCQkJaWYgKG9yZGVyID4gbGFzdE9yZGVyKQotCQkJCXNldExhc3RPcmRlcihvcmRlcik7Ci0JCQllbHNlIGlmIChvcmRlciA9PSBsYXN0T3JkZXIgJiYgIW11bHRpQWxsb3dlZCkKLQkJCXsKLQkJCQlyZXR1cm4gbnVsbDsKLQkJCX0KLQkJCWVsc2UgaWYgKG9yZGVyIDwgbGFzdE9yZGVyICYmIG9yZGVyID4gMCkKLQkJCXsKLQkJCQlyZXR1cm4gbnVsbDsKLQkJCX0KLQkJfQotCi0gICAgcmV0dXJuIGVsZW1EZWY7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gdW5rbm93biBlbGVtZW50LCBnZXQgdGhlIHByb2Nlc3NvcgotICAgKiBmb3IgdGhlIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IG5hbWVzcGFjZSBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAcmV0dXJuIG5vcm1hbGx5IGEge0BsaW5rIFByb2Nlc3NvclVua25vd259IHJlZmVyZW5jZS4KLSAgICogQHNlZSBQcm9jZXNzb3JVbmtub3duCi0gICAqLwotICBYU0xURWxlbWVudFByb2Nlc3NvciBnZXRQcm9jZXNzb3JGb3JVbmtub3duKFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLQotICAgIC8vIFhTTFRFbGVtZW50UHJvY2Vzc29yIGxyZURlZiA9IG51bGw7IC8vIHJldHVybiB2YWx1ZQotICAgIGlmIChudWxsID09IG1fZWxlbWVudHMpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIGludCBuID0gbV9lbGVtZW50cy5sZW5ndGg7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBYU0xURWxlbWVudERlZiBkZWYgPSBtX2VsZW1lbnRzW2ldOwotCi0gICAgICBpZiAoZGVmLm1fbmFtZS5lcXVhbHMoInVua25vd24iKSAmJiB1cmkubGVuZ3RoKCkgPiAwKQotICAgICAgewotICAgICAgICByZXR1cm4gZGVmLm1fZWxlbWVudFByb2Nlc3NvcjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgYWxsb3dlZCBhdHRyaWJ1dGVzIGZvciB0aGlzIHR5cGUuCi0gICAqLwotICBwcml2YXRlIFhTTFRBdHRyaWJ1dGVEZWZbXSBtX2F0dHJpYnV0ZXM7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYWxsb3dlZCBhdHRyaWJ1dGVzIGZvciB0aGlzIHR5cGUuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gYXJyYXkgb2YgYWxsb3dlZCBhdHRyaWJ1dGUgZGVmcywgb3IgbnVsbC4KLSAgICovCi0gIFhTTFRBdHRyaWJ1dGVEZWZbXSBnZXRBdHRyaWJ1dGVzKCkKLSAgewotICAgIHJldHVybiBtX2F0dHJpYnV0ZXM7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UgVVJJLCBhbmQgYSBsb2NhbCBuYW1lLCByZXR1cm4gdGhlIGVsZW1lbnQncwotICAgKiBhdHRyaWJ1dGUgZGVmaW5pdGlvbiwgaWYgaXQgaGFzIG9uZS4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgbmFtZXNwYWNlIHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBkZWYgdGhhdCBtYXRjaGVzIHRoZSBhcmd1bWVudHMsIG9yIG51bGwuCi0gICAqLwotICBYU0xUQXR0cmlidXRlRGVmIGdldEF0dHJpYnV0ZURlZihTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0KLSAgICBYU0xUQXR0cmlidXRlRGVmIGRlZmF1bHREZWYgPSBudWxsOwotICAgIFhTTFRBdHRyaWJ1dGVEZWZbXSBhdHRyRGVmcyA9IGdldEF0dHJpYnV0ZXMoKTsKLSAgICBpbnQgbkF0dHJEZWZzID0gYXR0ckRlZnMubGVuZ3RoOwotCi0gICAgZm9yIChpbnQgayA9IDA7IGsgPCBuQXR0ckRlZnM7IGsrKykKLSAgICB7Ci0gICAgICBYU0xUQXR0cmlidXRlRGVmIGF0dHJEZWYgPSBhdHRyRGVmc1trXTsKLSAgICAgIFN0cmluZyB1cmlEZWYgPSBhdHRyRGVmLmdldE5hbWVzcGFjZSgpOwotICAgICAgU3RyaW5nIG5hbWVEZWYgPSBhdHRyRGVmLmdldE5hbWUoKTsKLSAgICAgIAotICAgICAgaWYgKG5hbWVEZWYuZXF1YWxzKCIqIikgJiYgKGVxdWFsc01heUJlTnVsbE9yWmVyb0xlbih1cmksIHVyaURlZikgfHwgCi0gICAgICAgICAgKHVyaURlZiAhPSBudWxsICYmIHVyaS5sZW5ndGgoKSA+IDAgJiYgdXJpRGVmLmVxdWFscygiKiIpKSkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBhdHRyRGVmOwotICAgICAgfQotICAgICAgZWxzZSBpZiAobmFtZURlZi5lcXVhbHMoIioiKSAmJiAodXJpRGVmID09IG51bGwpKQotICAgICAgewotCi0gICAgICAgIC8vIEluIHRoaXMgY2FzZSwgYWxsIGF0dHJpYnV0ZXMgYXJlIGxlZ2FsLCBzbyByZXR1cm4gCi0gICAgICAgIC8vIHRoaXMgYXMgdGhlIGxhc3QgcmVzb3J0LgotICAgICAgICBkZWZhdWx0RGVmID0gYXR0ckRlZjsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGVxdWFsc01heUJlTnVsbE9yWmVyb0xlbih1cmksIHVyaURlZikKLSAgICAgICAgICAgICAgICYmIGxvY2FsTmFtZS5lcXVhbHMobmFtZURlZikpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBhdHRyRGVmOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChudWxsID09IGRlZmF1bHREZWYpCi0gICAgewotICAgICAgaWYgKHVyaS5sZW5ndGgoKSA+IDAgJiYgIWVxdWFsc01heUJlTnVsbE9yWmVyb0xlbih1cmksIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBYU0xUQXR0cmlidXRlRGVmLm1fZm9yZWlnbkF0dHI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGRlZmF1bHREZWY7Ci0gIH0KLQotICAvKioKLSAgICogSWYgbm9uLW51bGwsIHRoZSBDb250ZW50SGFuZGxlci9UcmFuc2Zvcm1lckZhY3RvcnkgZm9yIHRoaXMgZWxlbWVudC4KLSAgICovCi0gIHByaXZhdGUgWFNMVEVsZW1lbnRQcm9jZXNzb3IgbV9lbGVtZW50UHJvY2Vzc29yOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIFhTTFRFbGVtZW50UHJvY2Vzc29yIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQgcHJvY2Vzc29yIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBYU0xURWxlbWVudFByb2Nlc3NvciBnZXRFbGVtZW50UHJvY2Vzc29yKCkKLSAgewotICAgIHJldHVybiBtX2VsZW1lbnRQcm9jZXNzb3I7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBYU0xURWxlbWVudFByb2Nlc3NvciBmb3IgdGhpcyBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgZWxlbWVudCBwcm9jZXNzb3IgZm9yIHRoaXMgZWxlbWVudC4KLSAgICovCi0gIHZvaWQgc2V0RWxlbWVudFByb2Nlc3NvcihYU0xURWxlbWVudFByb2Nlc3NvciBoYW5kbGVyKQotICB7Ci0KLSAgICBpZiAoaGFuZGxlciAhPSBudWxsKQotICAgIHsKLSAgICAgIG1fZWxlbWVudFByb2Nlc3NvciA9IGhhbmRsZXI7Ci0KLSAgICAgIG1fZWxlbWVudFByb2Nlc3Nvci5zZXRFbGVtRGVmKHRoaXMpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJZiBub24tbnVsbCwgdGhlIGNsYXNzIG9iamVjdCB0aGF0IHNob3VsZCBpbiBpbnN0YW50aWF0ZWQgZm9yCi0gICAqIGEgWGFsYW4gaW5zdGFuY2Ugb2YgdGhpcyBlbGVtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBDbGFzcyBtX2NsYXNzT2JqZWN0OwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGNsYXNzIG9iamVjdCB0aGF0IHNob3VsZCBpbiBpbnN0YW50aWF0ZWQgZm9yCi0gICAqIGEgWGFsYW4gaW5zdGFuY2Ugb2YgdGhpcyBlbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IHRoYXQgdGhpcyBlbGVtZW50IGRlZiBzaG91bGQgcHJvZHVjZSwgb3IgbnVsbC4KLSAgICovCi0gIENsYXNzIGdldENsYXNzT2JqZWN0KCkKLSAgewotICAgIHJldHVybiBtX2NsYXNzT2JqZWN0OwotICB9Ci0JCi0JLyoqCi0gICAqIElmIHRydWUsIHRoaXMgaGFzIGEgcmVxdWlyZWQgZWxlbWVudC4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2hhc19yZXF1aXJlZCA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBHZXQgd2hldGhlciBvciBub3QgdGhpcyBoYXMgYSByZXF1aXJlZCBlbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyB0aGlzIGhhcyBhIHJlcXVpcmVkIGVsZW1lbnQuCi0gICAqLwotICBib29sZWFuIGhhc1JlcXVpcmVkKCkKLSAgewotICAgIHJldHVybiBtX2hhc19yZXF1aXJlZDsKLSAgfQotCQotCS8qKgotICAgKiBJZiB0cnVlLCB0aGlzIGlzIGEgcmVxdWlyZWQgZWxlbWVudC4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX3JlcXVpcmVkID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIEdldCB3aGV0aGVyIG9yIG5vdCB0aGlzIGlzIGEgcmVxdWlyZWQgZWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSByZXF1aXJlZCBlbGVtZW50LgotICAgKi8KLSAgYm9vbGVhbiBnZXRSZXF1aXJlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9yZXF1aXJlZDsKLSAgfQotCQotCUhhc2h0YWJsZSBtX3JlcXVpcmVkRm91bmQ7Ci0JCi0JLyoqCi0gICAqIFNldCB0aGlzIHJlcXVpcmVkIGVsZW1lbnQgZm91bmQuCi0gICAqCi0gICAqLwotICB2b2lkIHNldFJlcXVpcmVkRm91bmQoU3RyaW5nIGVsZW0sIGJvb2xlYW4gZm91bmQpCi0gIHsKLSAgIGlmIChtX3JlcXVpcmVkRm91bmQuZ2V0KGVsZW0pICE9IG51bGwpIAotCQkgbV9yZXF1aXJlZEZvdW5kLnJlbW92ZShlbGVtKTsKLSAgfQotCQotCS8qKgotICAgKiBHZXQgd2hldGhlciBhbGwgcmVxdWlyZWQgZWxlbWVudHMgd2VyZSBmb3VuZC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIGFsbCByZXF1aXJlZCBlbGVtZW50cyB3ZXJlIGZvdW5kLgotICAgKi8KLSAgYm9vbGVhbiBnZXRSZXF1aXJlZEZvdW5kKCkKLSAgewotCQlpZiAobV9yZXF1aXJlZEZvdW5kID09IG51bGwpCi0JCQlyZXR1cm4gdHJ1ZTsKLSAgICByZXR1cm4gbV9yZXF1aXJlZEZvdW5kLmlzRW1wdHkoKTsKLSAgfQotCQotCS8qKgotICAgKiBHZXQgcmVxdWlyZWQgZWxlbWVudHMgdGhhdCB3ZXJlIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHJldHVybiByZXF1aXJlZCBlbGVtZW50cyB0aGF0IHdlcmUgbm90IGZvdW5kLgotICAgKi8KLSAgU3RyaW5nIGdldFJlcXVpcmVkRWxlbSgpCi0gIHsKLQkJaWYgKG1fcmVxdWlyZWRGb3VuZCA9PSBudWxsKQotCQkJcmV0dXJuIG51bGw7Ci0JCUVudW1lcmF0aW9uIGVsZW1zID0gbV9yZXF1aXJlZEZvdW5kLmVsZW1lbnRzKCk7Ci0JCVN0cmluZyBzID0gIiI7Ci0JCWJvb2xlYW4gZmlyc3QgPSB0cnVlOwotCQl3aGlsZSAoZWxlbXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0JCXsKLQkJCWlmIChmaXJzdCkKLQkJCQlmaXJzdCA9IGZhbHNlOwotCQkJZWxzZQotCQkJIHMgPSBzICsgIiwgIjsKLQkJCXMgPSBzICsgKFN0cmluZyllbGVtcy5uZXh0RWxlbWVudCgpOwotCQl9Ci0gICAgcmV0dXJuIHM7Ci0gIH0KLQkKLQlib29sZWFuIG1faXNPcmRlcmVkID0gZmFsc2U7CQotCQotCS8qKgotICAgKiBHZXQgd2hldGhlciB0aGlzIGVsZW1lbnQgcmVxdWlyZXMgb3JkZXJlZCBjaGlsZHJlbi4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgZWxlbWVudCByZXF1aXJlcyBvcmRlcmVkIGNoaWxkcmVuLgotICAgKi8KLSAgYm9vbGVhbiBpc09yZGVyZWQoKQotICB7Ci0JCS8qaWYgKCFtX0NoZWNrZWRPcmRlcmVkKQotCQl7Ci0JCQltX0NoZWNrZWRPcmRlcmVkID0gdHJ1ZTsKLQkJCW1faXNPcmRlcmVkID0gZmFsc2U7Ci0JCQlpZiAobnVsbCA9PSBtX2VsZW1lbnRzKQotCQkJCXJldHVybiBmYWxzZTsKLQotCQkJaW50IG4gPSBtX2VsZW1lbnRzLmxlbmd0aDsKLQotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0JCQl7Ci0JCQkJaWYgKG1fZWxlbWVudHNbaV0uZ2V0T3JkZXIoKSA+IDApCi0JCQkJewotCQkJCQltX2lzT3JkZXJlZCA9IHRydWU7Ci0JCQkJCXJldHVybiB0cnVlOwotCQkJCX0KLQkJCX0KLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCQllbHNlKi8KLQkJCXJldHVybiBtX2lzT3JkZXJlZDsKLSAgfQotCQotCS8qKgotICAgKiB0aGUgb3JkZXIgdGhhdCB0aGlzIGVsZW1lbnQgc2hvdWxkIGFwcGVhciwgb3IgLTEgaWYgbm90IG9yZGVyZWQKLSAgICovCi0gIHByaXZhdGUgaW50IG1fb3JkZXIgPSAtMTsKLQkKLQkvKioKLSAgICogR2V0IHRoZSBvcmRlciB0aGF0IHRoaXMgZWxlbWVudCBzaG91bGQgYXBwZWFyIC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgb3JkZXIgdGhhdCB0aGlzIGVsZW1lbnQgc2hvdWxkIGFwcGVhci4KLSAgICovCi0gIGludCBnZXRPcmRlcigpCi0gIHsKLSAgICByZXR1cm4gbV9vcmRlcjsKLSAgfQotCQotCS8qKgotICAgKiB0aGUgaGlnaGVzdCBvcmRlciBvZiBjaGlsZCBlbGVtZW50cyBoYXZlIGFwcGVhcmVkIHNvIGZhciwgCi0gICAqIG9yIC0xIGlmIG5vdCBvcmRlcmVkCi0gICAqLwotICBwcml2YXRlIGludCBtX2xhc3RPcmRlciA9IC0xOwotCQotCS8qKgotICAgKiBHZXQgdGhlIGhpZ2hlc3Qgb3JkZXIgb2YgY2hpbGQgZWxlbWVudHMgaGF2ZSBhcHBlYXJlZCBzbyBmYXIgLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBoaWdoZXN0IG9yZGVyIG9mIGNoaWxkIGVsZW1lbnRzIGhhdmUgYXBwZWFyZWQgc28gZmFyLgotICAgKi8KLSAgaW50IGdldExhc3RPcmRlcigpCi0gIHsKLSAgICByZXR1cm4gbV9sYXN0T3JkZXI7Ci0gIH0KLQkKLQkvKioKLSAgICogU2V0IHRoZSBoaWdoZXN0IG9yZGVyIG9mIGNoaWxkIGVsZW1lbnRzIGhhdmUgYXBwZWFyZWQgc28gZmFyIC4KLSAgICoKLSAgICogQHBhcmFtIG9yZGVyIHRoZSBoaWdoZXN0IG9yZGVyIG9mIGNoaWxkIGVsZW1lbnRzIGhhdmUgYXBwZWFyZWQgc28gZmFyLgotICAgKi8KLSAgdm9pZCBzZXRMYXN0T3JkZXIoaW50IG9yZGVyKQotICB7Ci0gICAgbV9sYXN0T3JkZXIgPSBvcmRlciA7Ci0gIH0KLQkKLQkvKioKLSAgICogVHJ1ZSBpZiB0aGlzIGVsZW1lbnQgY2FuIGFwcGVhciBtdWx0aXBsZSB0aW1lcwotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fbXVsdGlBbGxvd2VkID0gdHJ1ZTsKLQkKLQkvKioKLSAgICogR2V0IHdoZXRoZXIgdGhpcyBlbGVtZW50IGNhbiBhcHBlYXIgbXVsdGlwbGUgdGltZXMKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgZWxlbWVudCBjYW4gYXBwZWFyIG11bHRpcGxlIHRpbWVzCi0gICAqLwotICBib29sZWFuIGdldE11bHRpQWxsb3dlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9tdWx0aUFsbG93ZWQ7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xURWxlbWVudFByb2Nlc3Nvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1hTTFRFbGVtZW50UHJvY2Vzc29yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVhMmZlZTguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1hTTFRFbGVtZW50UHJvY2Vzc29yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MDkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuSW50U3RhY2s7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGFjdHMgYXMgdGhlIHN1cGVyY2xhc3MgZm9yIGFsbCBzdHlsZXNoZWV0IGVsZW1lbnQKLSAqIHByb2Nlc3NvcnMsIGFuZCBkZWFscyB3aXRoIHRoaW5ncyB0aGF0IGFyZSBjb21tb24gdG8gYWxsIGVsZW1lbnRzLgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBYU0xURWxlbWVudFByb2Nlc3NvcgotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBwcm9jZXNzb3IgZm9yIHRvcC1sZXZlbCBlbGVtZW50cy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gICAqLwotICBYU0xURWxlbWVudFByb2Nlc3Nvcigpe30KLQkKLQlwcml2YXRlIEludFN0YWNrIG1fc2F2ZWRMYXN0T3JkZXI7Ci0KLSAgLyoqCi0gICAqIFRoZSBlbGVtZW50IGRlZmluaXRpb24gdGhhdCB0aGlzIHByb2Nlc3NvciBjb25mb3JtcyB0by4KLSAgICovCi0gIHByaXZhdGUgWFNMVEVsZW1lbnREZWYgbV9lbGVtRGVmOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGVsZW1lbnQgZGVmaW5pdGlvbiB0aGF0IGJlbG9uZ3MgdG8gdGhpcyBlbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50IGRlZmluaXRpb24gb2JqZWN0IHRoYXQgcHJvZHVjZWQgYW5kIGNvbnN0cmFpbnMgdGhpcyBlbGVtZW50LgotICAgKi8KLSAgWFNMVEVsZW1lbnREZWYgZ2V0RWxlbURlZigpCi0gIHsKLSAgICByZXR1cm4gbV9lbGVtRGVmOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZWxlbWVudCBkZWZpbml0aW9uIHRoYXQgYmVsb25ncyB0byB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBkZWYgVGhlIGVsZW1lbnQgZGVmaW5pdGlvbiBvYmplY3QgdGhhdCBwcm9kdWNlZCBhbmQgY29uc3RyYWlucyB0aGlzIGVsZW1lbnQuCi0gICAqLwotICB2b2lkIHNldEVsZW1EZWYoWFNMVEVsZW1lbnREZWYgZGVmKQotICB7Ci0gICAgbV9lbGVtRGVmID0gZGVmOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc29sdmUgYW4gZXh0ZXJuYWwgZW50aXR5LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIHB1YmxpYyBpZGVudGlmZXIsIG9yIG51bGwgaWYgbm9uZSBpcwotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIHN5c3RlbSBpZGVudGlmaWVyIHByb3ZpZGVkIGluIHRoZSBYTUwKLSAgICogICAgICAgICAgICAgICAgIGRvY3VtZW50LgotICAgKiBAcmV0dXJuIFRoZSBuZXcgaW5wdXQgc291cmNlLCBvciBudWxsIHRvIHJlcXVpcmUgdGhlCi0gICAqICAgICAgICAgZGVmYXVsdCBiZWhhdmlvdXIuCi0gICAqLwotICBwdWJsaWMgSW5wdXRTb3VyY2UgcmVzb2x2ZUVudGl0eSgKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgbm90YXRpb24gZGVjbGFyYXRpb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBub3RhdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vdGF0aW9uIHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIG5vdGF0aW9uIHN5c3RlbSBpZGVudGlmaWVyLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjbm90YXRpb25EZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgewotCi0gICAgLy8gbm8gb3AKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhbiB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbnRpdHkgbmFtZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBlbnRpdHkgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm90Ci0gICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5IHN5c3RlbSBpZGVudGlmaWVyLgotICAgKiBAcGFyYW0gbm90YXRpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIG5vdGF0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBub3RhdGlvbk5hbWUpCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIHRoZSBub24tdGV4dCBldmVudC4gIFRoaXMKLSAgICogaXMgc2VudCB0byB0aGUgY3VycmVudCBwcm9jZXNzb3Igd2hlbiBhbnkgbm9uLXRleHQgZXZlbnQgb2NjdXJzLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnROb25UZXh0KFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8gb3AKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcykKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG1fc2F2ZWRMYXN0T3JkZXIgPT0gbnVsbCkKLQkJCQltX3NhdmVkTGFzdE9yZGVyID0gbmV3IEludFN0YWNrKCk7Ci0JCQltX3NhdmVkTGFzdE9yZGVyLnB1c2goZ2V0RWxlbURlZigpLmdldExhc3RPcmRlcigpKTsKLQkJCWdldEVsZW1EZWYoKS5zZXRMYXN0T3JkZXIoLTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vdCBuYW1lc3BhY2UgcHJvY2Vzc2luZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyByYXdOYW1lKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0JCWlmIChtX3NhdmVkTGFzdE9yZGVyICE9IG51bGwgJiYgIW1fc2F2ZWRMYXN0T3JkZXIuZW1wdHkoKSkKLQkJCWdldEVsZW1EZWYoKS5zZXRMYXN0T3JkZXIobV9zYXZlZExhc3RPcmRlci5wb3AoKSk7Ci0JCQotCQlpZiAoIWdldEVsZW1EZWYoKS5nZXRSZXF1aXJlZEZvdW5kKCkpCi0JCQloYW5kbGVyLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCwgbmV3IE9iamVjdFtde2dldEVsZW1EZWYoKS5nZXRSZXF1aXJlZEVsZW0oKX0sIG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhIGluc2lkZSBhbiBlbGVtZW50LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycygKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGhhbmRsZXIuZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NIQVJTX05PVF9BTExPV0VELCBudWxsLCBudWxsKTsvLyJDaGFyYWN0ZXJzIGFyZSBub3QgYWxsb3dlZCBhdCB0aGlzIHBvaW50IGluIHRoZSBkb2N1bWVudCEiLAotICAgICAgICAgICAgICAgICAgLy9udWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSBjaCBUaGUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQotICAgKiAgICAgICAgICAgICAgIGNoYXJhY3RlciBhcnJheS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIG5vIG9wCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaGFuZGxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY3VycmVudCBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZyB0aGUgVGVtcGxhdGVzLgotICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgotICAgKiAgICAgICAgICAgICBub25lIGlzIHN1cHBsaWVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKAotICAgICAgICAgIFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjdXJyZW50IFN0eWxlc2hlZXRIYW5kbGVyIHRoYXQgaXMgY29uc3RydWN0aW5nIHRoZSBUZW1wbGF0ZXMuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBza2lwcGVkIGVudGl0eS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIG5hbWUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gYXR0cmlidXRlIGxpc3QuCi0gICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBzdHlsZXNoZWV0J3MgQ29udGVudCBoYW5kbGVyLCBuZWVkZWQgZm9yCi0gICAqICAgICAgICAgICAgICAgIGVycm9yIHJlcG9ydGluZy4KLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyBuYW1lIG9mIHRoZSBvd25lciBlbGVtZW50LCBuZWVkZWQgZm9yCi0gICAqICAgICAgICAgICAgICAgIGVycm9yIHJlcG9ydGluZy4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGxpc3Qgb2YgYXR0cmlidXRlcy4KLSAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IGVsZW1lbnQgd2hlcmUgdGhlIHByb3BlcnRpZXMgd2lsbCBiZSBzZXQuCi0gICAqLwotICB2b2lkIHNldFByb3BlcnRpZXNGcm9tQXR0cmlidXRlcygKLSAgICAgICAgICBTdHlsZXNoZWV0SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgcmF3TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBPYmplY3QgdGFyZ2V0KQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgc2V0UHJvcGVydGllc0Zyb21BdHRyaWJ1dGVzKGhhbmRsZXIsIHJhd05hbWUsIGF0dHJpYnV0ZXMsIHRhcmdldCwgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBhdHRyaWJ1dGUgbGlzdC4KLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIHN0eWxlc2hlZXQncyBDb250ZW50IGhhbmRsZXIsIG5lZWRlZCBmb3IKLSAgICogICAgICAgICAgICAgICAgZXJyb3IgcmVwb3J0aW5nLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcmF3IG5hbWUgb2YgdGhlIG93bmVyIGVsZW1lbnQsIG5lZWRlZCBmb3IKLSAgICogICAgICAgICAgICAgICAgZXJyb3IgcmVwb3J0aW5nLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgbGlzdCBvZiBhdHRyaWJ1dGVzLgotICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgZWxlbWVudCB3aGVyZSB0aGUgcHJvcGVydGllcyB3aWxsIGJlIHNldC4KLSAgICogQHBhcmFtIHRocm93RXJyb3IgVHJ1ZSBpZiBpdCBzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgYW4KLSAgICogYXR0cmlidXRlIGlzIG5vdCBkZWZpbmVkLgotICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGVzIG5vdCBhbGxvd2VkIG9uIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgQXR0cmlidXRlcyBzZXRQcm9wZXJ0aWVzRnJvbUF0dHJpYnV0ZXMoCi0gICAgICAgICAgU3R5bGVzaGVldEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIHJhd05hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgT2JqZWN0IHRhcmdldCwgYm9vbGVhbiB0aHJvd0Vycm9yKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBYU0xURWxlbWVudERlZiBkZWYgPSBnZXRFbGVtRGVmKCk7Ci0gICAgQXR0cmlidXRlc0ltcGwgdW5kZWZpbmVzID0gdGhyb3dFcnJvciA/IG51bGwgOiBuZXcgQXR0cmlidXRlc0ltcGwoKTsKLQotICAgIC8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggWFNMVEF0dHJpYnV0ZURlZnMgaGF2ZSBiZWVuIHByb2Nlc3NlZCwgc28gCi0gICAgLy8gSSBjYW4gc2VlIHdoaWNoIGRlZmF1bHQgdmFsdWVzIG5lZWQgdG8gYmUgc2V0LgotICAgIFZlY3RvciBwcm9jZXNzZWREZWZzID0gbmV3IFZlY3RvcigpOwotICAgIGludCBuQXR0cnMgPSBhdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cnM7IGkrKykKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0clVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgLy8gSGFjayBmb3IgQ3JpbXNvbi4gIC1zYgotICAgICAgaWYoKG51bGwgIT0gYXR0clVyaSkgJiYgKGF0dHJVcmkubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChhdHRyaWJ1dGVzLmdldFFOYW1lKGkpLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8IAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSkuZXF1YWxzKCJ4bWxucyIpKSkKLSAgICAgIHsKLSAgICAgICAgYXR0clVyaSA9IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cy5TX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgIH0KLSAgICAgIFN0cmluZyBhdHRyTG9jYWxOYW1lID0gYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaSk7Ci0gICAgICBYU0xUQXR0cmlidXRlRGVmIGF0dHJEZWYgPSBkZWYuZ2V0QXR0cmlidXRlRGVmKGF0dHJVcmksIGF0dHJMb2NhbE5hbWUpOwotCi0gICAgICBpZiAobnVsbCA9PSBhdHRyRGVmKQotICAgICAgewotICAgICAgICBpZiAodGhyb3dFcnJvcikKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gVGhlbiBiYXJmLCBiZWNhdXNlIHRoaXMgZWxlbWVudCBkb2VzIG5vdCBhbGxvdyB0aGlzIGF0dHJpYnV0ZS4KLSAgICAgICAgICBoYW5kbGVyLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9BVFRSX05PVF9BTExPV0VELCBuZXcgT2JqZWN0W117YXR0cmlidXRlcy5nZXRRTmFtZShpKSwgcmF3TmFtZX0sIG51bGwpOy8vIlwiIithdHRyaWJ1dGVzLmdldFFOYW1lKGkpKyJcIiIKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vKyAiIGF0dHJpYnV0ZSBpcyBub3QgYWxsb3dlZCBvbiB0aGUgIiArIHJhd05hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgLy8gKyAiIGVsZW1lbnQhIiwgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgdW5kZWZpbmVzLmFkZEF0dHJpYnV0ZShhdHRyVXJpLCBhdHRyTG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRRTmFtZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0VHlwZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSkpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHByb2Nlc3NlZERlZnMuYWRkRWxlbWVudChhdHRyRGVmKTsKLSAgICAgICAgYXR0ckRlZi5zZXRBdHRyVmFsdWUoaGFuZGxlciwgYXR0clVyaSwgYXR0ckxvY2FsTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5nZXRRTmFtZShpKSwgYXR0cmlidXRlcy5nZXRWYWx1ZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBYU0xUQXR0cmlidXRlRGVmW10gYXR0ckRlZnMgPSBkZWYuZ2V0QXR0cmlidXRlcygpOwotICAgIGludCBuQXR0ckRlZnMgPSBhdHRyRGVmcy5sZW5ndGg7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRyRGVmczsgaSsrKQotICAgIHsKLSAgICAgIFhTTFRBdHRyaWJ1dGVEZWYgYXR0ckRlZiA9IGF0dHJEZWZzW2ldOwotICAgICAgU3RyaW5nIGRlZlZhbCA9IGF0dHJEZWYuZ2V0RGVmYXVsdCgpOwotCi0gICAgICBpZiAobnVsbCAhPSBkZWZWYWwpCi0gICAgICB7Ci0gICAgICAgIGlmICghcHJvY2Vzc2VkRGVmcy5jb250YWlucyhhdHRyRGVmKSkKLSAgICAgICAgewotICAgICAgICAgIGF0dHJEZWYuc2V0RGVmQXR0clZhbHVlKGhhbmRsZXIsIHRhcmdldCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKGF0dHJEZWYuZ2V0UmVxdWlyZWQoKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKCFwcm9jZXNzZWREZWZzLmNvbnRhaW5zKGF0dHJEZWYpKQotICAgICAgICAgIGhhbmRsZXIuZXJyb3IoCi0gICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfUkVRVUlSRVNfQVRUUklCLCBuZXcgT2JqZWN0W117IHJhd05hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckRlZi5nZXROYW1lKCkgfSksIG51bGwpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB1bmRlZmluZXM7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xUU2NoZW1hLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvWFNMVFNjaGVtYS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZWQ3ZjcxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xUU2NoZW1hLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OTEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGRlZmluZXMgdGhlIGFsbG93ZWQgc3RydWN0dXJlIGZvciBhIHN0eWxlc2hlZXQsIGFuZCB0aGUKLSAqIG1hcHBpbmcgYmV0d2VlbiBYYWxhbiBjbGFzc2VzIGFuZCB0aGUgbWFya3VwIGVsZW1lbnRzIGluIHRoZSBzdHlsZXNoZWV0LgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZCI+WFNMVCBEVEQ8L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBYU0xUU2NoZW1hIGV4dGVuZHMgWFNMVEVsZW1lbnREZWYKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWFNMVFNjaGVtYSB3aGljaCByZXByZXNlbnRzIHRoZSBYU0xUICJzY2hlbWEiLgotICAgKi8KLSAgWFNMVFNjaGVtYSgpCi0gIHsKLSAgICBidWlsZCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIGJ1aWxkcyBhbiBYU0xUICJzY2hlbWEiIGFjY29yZGluZyB0byBodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0ZC4gIFRoaXMKLSAgICogc2NoZW1hIHByb3ZpZGVzIGluc3RydWN0aW9ucyBmb3IgYnVpbGRpbmcgdGhlIFhhbGFuIFN0eWxlc2hlZXQgKFRlbXBsYXRlcykgc3RydWN0dXJlLgotICAgKi8KLSAgdm9pZCBidWlsZCgpCi0gIHsKLQotICAgIFhTTFRBdHRyaWJ1dGVEZWYgaHJlZkF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiaHJlZiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1VSTCwgdHJ1ZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBlbGVtZW50c0F0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiZWxlbWVudHMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfU0lNUExFUEFUVEVSTkxJU1QsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgIC8vIFhTTFRBdHRyaWJ1dGVEZWYgYW55TmFtZXNwYWNlZEF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZigiKiIsICIqIiwKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0NEQVRBLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBtZXRob2RBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgIm1ldGhvZCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUU5BTUUsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHZlcnNpb25BdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgInZlcnNpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9OTVRPS0VOLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBlbmNvZGluZ0F0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiZW5jb2RpbmciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0RBVEEsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIG9taXRYbWxEZWNsYXJhdGlvbkF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9taXQteG1sLWRlY2xhcmF0aW9uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9ZRVNOTywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHN0YW5kYWxvbmVBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RhbmRhbG9uZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1lFU05PLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBkb2N0eXBlUHVibGljQXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRvY3R5cGUtcHVibGljIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0RBVEEsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIGRvY3R5cGVTeXN0ZW1BdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZG9jdHlwZS1zeXN0ZW0iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DREFUQSwgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgY2RhdGFTZWN0aW9uRWxlbWVudHNBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNkYXRhLXNlY3Rpb24tZWxlbWVudHMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUU5BTUVTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBpbmRlbnRBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgImluZGVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfWUVTTk8sIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIG1lZGlhVHlwZUF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibWVkaWEtdHlwZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0RBVEEsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIG5hbWVBdHRyUmVxdWlyZWQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUU5BTUUsIHRydWUpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgbmFtZUF0dHJPcHQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1FOQU1FLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiB1c2VBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgInVzZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfRVhQUiwgdHJ1ZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBuYW1lQVZUUmVxdWlyZWQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibmFtZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsIHRydWUpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgbmFtZXNwYWNlQVZUT3B0ID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWVzcGFjZSIsIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIGRlY2ltYWxTZXBhcmF0b3JBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVjaW1hbC1zZXBhcmF0b3IiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DSEFSLCAiLiIpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgZ3JvdXBpbmdTZXBhcmF0b3JBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdyb3VwaW5nLXNlcGFyYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DSEFSLCAiLCIpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgaW5maW5pdHlBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgImluZmluaXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0NEQVRBLCAiSW5maW5pdHkiKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIG1pbnVzU2lnbkF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibWludXMtc2lnbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0hBUiwgIi0iKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIE5hTkF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiTmFOIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DREFUQSwgIk5hTiIpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgcGVyY2VudEF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAicGVyY2VudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0NIQVIsICIlIik7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBwZXJNaWxsZUF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAicGVyLW1pbGxlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0NIQVIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlIC8qICwiJiN4MjAzMDsiICovKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHplcm9EaWdpdEF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiemVyby1kaWdpdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0hBUiwgIjAiKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIGRpZ2l0QXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJkaWdpdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DSEFSLCAiIyIpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgcGF0dGVyblNlcGFyYXRvckF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYXR0ZXJuLXNlcGFyYXRvciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0NIQVIsICI7Iik7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiB1c2VBdHRyaWJ1dGVTZXRzQXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVzZS1hdHRyaWJ1dGUtc2V0cyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1FOQU1FUywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBzZWxlY3RBdHRyUmVxdWlyZWQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2VsZWN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0VYUFIsIHRydWUpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgdGVzdEF0dHJSZXF1aXJlZCA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJ0ZXN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9FWFBSLCB0cnVlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHNlbGVjdEF0dHJPcHQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAic2VsZWN0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9FWFBSLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBzZWxlY3RBdHRyRGVmTm9kZSA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJzZWxlY3QiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9FWFBSLCAibm9kZSgpIik7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBzZWxlY3RBdHRyRGVmRG90ID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgInNlbGVjdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfRVhQUiwgIi4iKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIG1hdGNoQXR0clJlcXVpcmVkID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgIm1hdGNoIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUEFUVEVSTiwgdHJ1ZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBtYXRjaEF0dHJPcHQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibWF0Y2giLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUEFUVEVSTiwgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgcHJpb3JpdHlBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgInByaW9yaXR5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1BSSU9SSVRZLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBtb2RlQXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJtb2RlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUU5BTUUsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHNwYWNlQXR0ciA9Ci0gICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZihDb25zdGFudHMuU19YTUxOQU1FU1BBQ0VVUkksICJzcGFjZSIsIGZhbHNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlZmF1bHQiLCBDb25zdGFudHMuQVRUUlZBTF9TVFJJUCwgInByZXNlcnZlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5BVFRSVkFMX1BSRVNFUlZFKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHNwYWNlQXR0ckxpdGVyYWwgPQotICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWYoQ29uc3RhbnRzLlNfWE1MTkFNRVNQQUNFVVJJLCAic3BhY2UiLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHN0eWxlc2hlZXRQcmVmaXhBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3R5bGVzaGVldC1wcmVmaXgiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DREFUQSwgdHJ1ZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiByZXN1bHRQcmVmaXhBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXN1bHQtcHJlZml4IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9DREFUQSwgdHJ1ZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBkaXNhYmxlT3V0cHV0RXNjYXBpbmdBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfWUVTTk8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBsZXZlbEF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibGV2ZWwiLCBmYWxzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNpbmdsZSIsIENvbnN0YW50cy5OVU1CRVJMRVZFTF9TSU5HTEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXBsZSIsIENvbnN0YW50cy5OVU1CRVJMRVZFTF9NVUxUSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFueSIsIENvbnN0YW50cy5OVU1CRVJMRVZFTF9BTlkpOwotCi0gICAgbGV2ZWxBdHRyLnNldERlZmF1bHQoInNpbmdsZSIpOwotCi0gICAgWFNMVEF0dHJpYnV0ZURlZiBjb3VudEF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiY291bnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfUEFUVEVSTiwgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgZnJvbUF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiZnJvbSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1BBVFRFUk4sIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHZhbHVlQXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJ2YWx1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9FWFBSLCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBmb3JtYXRBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgImZvcm1hdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQVZULCBmYWxzZSk7Ci0KLSAgICBmb3JtYXRBdHRyLnNldERlZmF1bHQoIjEiKTsKLQotICAgIFhTTFRBdHRyaWJ1dGVEZWYgbGFuZ0F0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAibGFuZyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0FWVCwgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgbGV0dGVyVmFsdWVBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxldHRlci12YWx1ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIGdyb3VwaW5nU2VwYXJhdG9yQVZUID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ3JvdXBpbmctc2VwYXJhdG9yIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQVZULCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBncm91cGluZ1NpemVBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJncm91cGluZy1zaXplIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIGRhdGFUeXBlQXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJkYXRhLXR5cGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQVZULCAidGV4dCIpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgb3JkZXJBdHRyID0gbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgIm9yZGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX0FWVCwgImFzY2VuZGluZyIpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgY2FzZU9yZGVyQXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJjYXNlLW9yZGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHRlcm1pbmF0ZUF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAidGVybWluYXRlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9ZRVNOTywgZmFsc2UpOwotCi0gICAgdGVybWluYXRlQXR0ci5zZXREZWZhdWx0KCJubyIpOwotCi0gICAgWFNMVEF0dHJpYnV0ZURlZiB4c2xFeGNsdWRlUmVzdWx0UHJlZml4ZXNBdHRyID0KLSAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmKENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfU1RSSU5HTElTVCwgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgeHNsRXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzQXR0ciA9Ci0gICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZihDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1BSRUZJWF9VUkxMSVNULCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiB4c2xVc2VBdHRyaWJ1dGVTZXRzQXR0ciA9Ci0gICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZihDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJ1c2UtYXR0cmlidXRlLXNldHMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1FOQU1FUywgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgeHNsVmVyc2lvbkF0dHIgPQotICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWYoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAidmVyc2lvbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfTk1UT0tFTiwgZmFsc2UpOwotICAgIFhTTFRFbGVtZW50RGVmIGNoYXJEYXRhID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsIG51bGwsICJ0ZXh0KCkiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sIG51bGwgLyogZWxlbWVudHMgKi8sIG51bGwsICAvKiBhdHRyaWJ1dGVzICovCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JDaGFyYWN0ZXJzKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1UZXh0TGl0ZXJhbC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8pOwotCi0gICAgY2hhckRhdGEuc2V0VHlwZShYU0xURWxlbWVudERlZi5UX1BDREFUQSk7Ci0KLSAgICBYU0xURWxlbWVudERlZiB3aGl0ZVNwYWNlT25seSA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLCBudWxsLCAidGV4dCgpIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLCBudWxsIC8qIGVsZW1lbnRzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCAgLyogYXR0cmlidXRlcyAqLwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtVGV4dExpdGVyYWwuY2xhc3MgLyogc2hvdWxkIGJlIG51bGw/IC1zYiAqLyk7Ci0KLSAgICBjaGFyRGF0YS5zZXRUeXBlKFhTTFRFbGVtZW50RGVmLlRfUENEQVRBKTsKLQotICAgIFhTTFRBdHRyaWJ1dGVEZWYgcmVzdWx0QXR0ciA9IG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICIqIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRBdHRyaWJ1dGVEZWYuVF9BVlQsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHhzbFJlc3VsdEF0dHIgPQotICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWYoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiKiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0RBVEEsIGZhbHNlKTsKLSAgICBYU0xURWxlbWVudERlZltdIHRlbXBsYXRlRWxlbWVudHMgPSBuZXcgWFNMVEVsZW1lbnREZWZbMjFdOwotICAgIFhTTFRFbGVtZW50RGVmW10gdGVtcGxhdGVFbGVtZW50c0FuZFBhcmFtcyA9IG5ldyBYU0xURWxlbWVudERlZlsyMl07Ci0gICAgWFNMVEVsZW1lbnREZWZbXSB0ZW1wbGF0ZUVsZW1lbnRzQW5kU29ydCA9IG5ldyBYU0xURWxlbWVudERlZlsyMl07Ci0gICAgWFNMVEVsZW1lbnREZWZbXSBjaGFyVGVtcGxhdGVFbGVtZW50cyA9IG5ldyBYU0xURWxlbWVudERlZlsxNV07Ci0gICAgWFNMVEVsZW1lbnREZWYgcmVzdWx0RWxlbWVudCA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLCBudWxsLCAiKiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlQXR0ckxpdGVyYWwsIC8vIHNwZWNpYWwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbEV4Y2x1ZGVSZXN1bHRQcmVmaXhlc0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2xFeHRlbnNpb25FbGVtZW50UHJlZml4ZXNBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsVXNlQXR0cmlidXRlU2V0c0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2xWZXJzaW9uQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbFJlc3VsdEF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRBdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JMUkUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtTGl0ZXJhbFJlc3VsdC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiB1bmtub3duRWxlbWVudCA9Ci0gICAgICBuZXcgWFNMVEVsZW1lbnREZWYodGhpcywgIioiLCAidW5rbm93biIsIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUVsZW1lbnRzQW5kUGFyYW1zIC8qIGVsZW1lbnRzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117IHhzbEV4Y2x1ZGVSZXN1bHRQcmVmaXhlc0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsRXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2xVc2VBdHRyaWJ1dGVTZXRzQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2xWZXJzaW9uQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2xSZXN1bHRBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEF0dHIgfSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclVua25vd24oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtVW5rbm93bi5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiB4c2xWYWx1ZU9mID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAidmFsdWUtb2YiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywgbnVsbCAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBzZWxlY3RBdHRyUmVxdWlyZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZU91dHB1dEVzY2FwaW5nQXR0ciB9LCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1WYWx1ZU9mLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbENvcHlPZiA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiY29weS1vZiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sIG51bGwgLyogZWxlbWVudHMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBzZWxlY3RBdHRyUmVxdWlyZWQgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1Db3B5T2YuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsTnVtYmVyID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJudW1iZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLCBudWxsIC8qIGVsZW1lbnRzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsgbGV2ZWxBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbUF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZ0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXR0ZXJWYWx1ZUF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cGluZ1NlcGFyYXRvckFWVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwaW5nU2l6ZUF0dHIgfSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbU51bWJlci5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLQotICAgIC8vIDwhLS0geHNsOnNvcnQgY2Fubm90IG9jY3VyIGFmdGVyIGFueSBvdGhlciBlbGVtZW50cyBvcgotICAgIC8vIGFueSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIgLS0+Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsU29ydCA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNvcnQiLCBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qIGVsZW1lbnRzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0QXR0ckRlZkRvdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZ0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlT3JkZXJBdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbVNvcnQuY2xhc3MvKiBjbGFzcyBvYmplY3QgKi8sIDE5LCB0cnVlICk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsV2l0aFBhcmFtID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aC1wYXJhbSIsIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sICAvLyAldGVtcGxhdGU7PgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsgbmFtZUF0dHJSZXF1aXJlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdEF0dHJPcHQgfSwgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtV2l0aFBhcmFtLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMTksIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbEFwcGx5VGVtcGxhdGVzID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFwcGx5LXRlbXBsYXRlcyIsIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRFbGVtZW50RGVmW117IHhzbFNvcnQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2xXaXRoUGFyYW0gfSAvKiBlbGVtZW50cyAqLywgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0QXR0ckRlZk5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVBdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtQXBwbHlUZW1wbGF0ZXMuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsQXBwbHlJbXBvcnRzID0KLSAgICAgIG5ldyBYU0xURWxlbWVudERlZih0aGlzLCBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJhcHBseS1pbXBvcnRzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sIG51bGwgLyogZWxlbWVudHMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXt9LAotICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtQXBwbHlJbXBvcnQuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovKTsKLSAgICBYU0xURWxlbWVudERlZiB4c2xGb3JFYWNoID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiZm9yLWVhY2giLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywgdGVtcGxhdGVFbGVtZW50c0FuZFNvcnQsICAvLyAoI1BDREFUQSAlaW5zdHJ1Y3Rpb25zOyAlcmVzdWx0LWVsZW1lbnRzOyB8IHhzbDpzb3J0KSoKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBzZWxlY3RBdHRyUmVxdWlyZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2VBdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yVGVtcGxhdGVFbGVtKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbUZvckVhY2guY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCB0cnVlLCBmYWxzZSwgdHJ1ZSwgMjAsIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbElmID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpZiIsIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUVsZW1lbnRzIC8qIGVsZW1lbnRzICovLCAgLy8gJXRlbXBsYXRlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0QXR0clJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2VBdHRyIH0sIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtSWYuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsV2hlbiA9Ci0gICAgICBuZXcgWFNMVEVsZW1lbnREZWYodGhpcywgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAid2hlbiIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLCB0ZW1wbGF0ZUVsZW1lbnRzIC8qIGVsZW1lbnRzICovLCAgLy8gJXRlbXBsYXRlOz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RBdHRyUmVxdWlyZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlQXR0ciB9LCBuZXcgUHJvY2Vzc29yVGVtcGxhdGVFbGVtKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtV2hlbi5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwgdHJ1ZSwgMSwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsT3RoZXJ3aXNlID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJvdGhlcndpc2UiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVFbGVtZW50cyAvKiBlbGVtZW50cyAqLywgIC8vICV0ZW1wbGF0ZTs+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBzcGFjZUF0dHIgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1PdGhlcndpc2UuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLCBmYWxzZSwgMiwgZmFsc2UpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbENob29zZSA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiY2hvb3NlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZltdeyB4c2xXaGVuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbE90aGVyd2lzZSB9IC8qIGVsZW1lbnRzICovLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBzcGFjZUF0dHIgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1DaG9vc2UuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCB0cnVlLCBmYWxzZSwgdHJ1ZSwgMjAsIHRydWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgWFNMVEVsZW1lbnREZWYgeHNsQXR0cmlidXRlID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJhdHRyaWJ1dGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhclRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sICAvLyAlY2hhci10ZW1wbGF0ZTs+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBuYW1lQVZUUmVxdWlyZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VBVlRPcHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZUF0dHIgfSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yVGVtcGxhdGVFbGVtKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtQXR0cmlidXRlLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbENhbGxUZW1wbGF0ZSA9Ci0gICAgICBuZXcgWFNMVEVsZW1lbnREZWYodGhpcywgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiY2FsbC10ZW1wbGF0ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZltdeyB4c2xXaXRoUGFyYW0gfSAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBuYW1lQXR0clJlcXVpcmVkIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1DYWxsVGVtcGxhdGUuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsVmFyaWFibGUgPSBuZXcgWFNMVEVsZW1lbnREZWYodGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAidmFyaWFibGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sICAvLyAldGVtcGxhdGU7PgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBuYW1lQXR0clJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RBdHRyT3B0IH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbVZhcmlhYmxlLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbFBhcmFtID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwgInBhcmFtIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUVsZW1lbnRzIC8qIGVsZW1lbnRzICovLCAgLy8gJXRlbXBsYXRlOz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsgbmFtZUF0dHJSZXF1aXJlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0QXR0ck9wdCB9LCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbVBhcmFtLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMTksIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbFRleHQgPQotICAgICAgbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwgInRleHQiLAotICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEVsZW1lbnREZWZbXXsgY2hhckRhdGEgfSAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBkaXNhYmxlT3V0cHV0RXNjYXBpbmdBdHRyIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRleHQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtVGV4dC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiB4c2xQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gPQotICAgICAgbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIsIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyVGVtcGxhdGVFbGVtZW50cyAvKiBlbGVtZW50cyAqLywgIC8vICVjaGFyLXRlbXBsYXRlOz4KLSAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lQVZUUmVxdWlyZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlQXR0ciB9LCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yVGVtcGxhdGVFbGVtKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1QSS5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiB4c2xFbGVtZW50ID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiZWxlbWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sICAvLyAldGVtcGxhdGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsgbmFtZUFWVFJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZUFWVE9wdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VBdHRyaWJ1dGVTZXRzQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZUF0dHIgfSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtRWxlbWVudC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiB4c2xDb21tZW50ID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiY29tbWVudCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJUZW1wbGF0ZUVsZW1lbnRzIC8qIGVsZW1lbnRzICovLCAgLy8gJWNoYXItdGVtcGxhdGU7PgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117IHNwYWNlQXR0ciB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtQ29tbWVudC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiB4c2xDb3B5ID0KLSAgICAgIG5ldyBYU0xURWxlbWVudERlZih0aGlzLCBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsICJjb3B5IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sIHRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sICAvLyAldGVtcGxhdGU7PgotICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZUF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZUF0dHJpYnV0ZVNldHNBdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbUNvcHkuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgeHNsTWVzc2FnZSA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwgIm1lc3NhZ2UiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUVsZW1lbnRzIC8qIGVsZW1lbnRzICovLCAgLy8gJXRlbXBsYXRlOz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyB0ZXJtaW5hdGVBdHRyIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvclRlbXBsYXRlRWxlbSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1NZXNzYWdlLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpOwotICAgIFhTTFRFbGVtZW50RGVmIHhzbEZhbGxiYWNrID0gbmV3IFhTTFRFbGVtZW50RGVmKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwgImZhbGxiYWNrIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUVsZW1lbnRzIC8qIGVsZW1lbnRzICovLCAgLy8gJXRlbXBsYXRlOz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsgc3BhY2VBdHRyIH0sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0oKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbUZhbGxiYWNrLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpOwotICAgIGludCBpID0gMDsKLQotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IGNoYXJEYXRhOyAgLy8gI1BDREFUQQotCi0gICAgLy8gY2hhci1pbnN0cnVjdGlvbnMKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xBcHBseVRlbXBsYXRlczsKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xDYWxsVGVtcGxhdGU7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsQXBwbHlJbXBvcnRzOwotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbEZvckVhY2g7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsVmFsdWVPZjsKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xDb3B5T2Y7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsTnVtYmVyOwotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbENob29zZTsKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xJZjsKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xUZXh0OwotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbENvcHk7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsVmFyaWFibGU7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsTWVzc2FnZTsKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xGYWxsYmFjazsKLQotICAgIC8vIGluc3RydWN0aW9ucwotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbFByb2Nlc3NpbmdJbnN0cnVjdGlvbjsKLSAgICB0ZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xDb21tZW50OwotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbEVsZW1lbnQ7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsQXR0cmlidXRlOwotICAgIHRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHJlc3VsdEVsZW1lbnQ7Ci0gICAgdGVtcGxhdGVFbGVtZW50c1tpKytdID0gdW5rbm93bkVsZW1lbnQ7Ci0KLSAgICBpbnQgazsKLQotICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspCi0gICAgewotICAgICAgdGVtcGxhdGVFbGVtZW50c0FuZFBhcmFtc1trXSA9IHRlbXBsYXRlRWxlbWVudHNba107Ci0gICAgfQotCi0gICAgdGVtcGxhdGVFbGVtZW50c0FuZFBhcmFtc1trXSA9IHhzbFBhcmFtOwotCi0gICAgZm9yIChrID0gMDsgayA8IGk7IGsrKykKLSAgICB7Ci0gICAgICB0ZW1wbGF0ZUVsZW1lbnRzQW5kU29ydFtrXSA9IHRlbXBsYXRlRWxlbWVudHNba107Ci0gICAgfQotCi0gICAgdGVtcGxhdGVFbGVtZW50c0FuZFNvcnRba10gPSB4c2xTb3J0OwotICAgIGkgPSAwOwotICAgIGNoYXJUZW1wbGF0ZUVsZW1lbnRzW2krK10gPSBjaGFyRGF0YTsgIC8vICNQQ0RBVEEKLQotICAgIC8vIGNoYXItaW5zdHJ1Y3Rpb25zCi0gICAgY2hhclRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbEFwcGx5VGVtcGxhdGVzOwotICAgIGNoYXJUZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xDYWxsVGVtcGxhdGU7Ci0gICAgY2hhclRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbEFwcGx5SW1wb3J0czsKLSAgICBjaGFyVGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsRm9yRWFjaDsKLSAgICBjaGFyVGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsVmFsdWVPZjsKLSAgICBjaGFyVGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsQ29weU9mOwotICAgIGNoYXJUZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xOdW1iZXI7Ci0gICAgY2hhclRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbENob29zZTsKLSAgICBjaGFyVGVtcGxhdGVFbGVtZW50c1tpKytdID0geHNsSWY7Ci0gICAgY2hhclRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbFRleHQ7Ci0gICAgY2hhclRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbENvcHk7Ci0gICAgY2hhclRlbXBsYXRlRWxlbWVudHNbaSsrXSA9IHhzbFZhcmlhYmxlOwotICAgIGNoYXJUZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xNZXNzYWdlOwotICAgIGNoYXJUZW1wbGF0ZUVsZW1lbnRzW2krK10gPSB4c2xGYWxsYmFjazsKLQotICAgIFhTTFRFbGVtZW50RGVmIGltcG9ydERlZiA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLCAiaW1wb3J0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywgbnVsbCAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117IGhyZWZBdHRyIH0sICAvLyBFTVBUWQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvckltcG9ydCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKiBjbGFzcyBvYmplY3QgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWYgaW5jbHVkZURlZiA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwgImluY2x1ZGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywgbnVsbCAvKiBlbGVtZW50cyAqLywgIC8vIEVNUFRZCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsgaHJlZkF0dHIgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29ySW5jbHVkZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyogY2xhc3Mgb2JqZWN0ICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyMCwgdHJ1ZSk7Ci0gICAgWFNMVEVsZW1lbnREZWZbXSB0b3BMZXZlbEVsZW1lbnRzID0gbmV3IFhTTFRFbGVtZW50RGVmW117IGluY2x1ZGVEZWYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydERlZiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzdWx0RWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpdGVTcGFjZU9ubHksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25FbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEVsZW1lbnREZWYoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0cmlwLXNwYWNlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzQXR0ciB9LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JTdHJpcFNwYWNlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRFbGVtZW50RGVmKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcmVzZXJ2ZS1zcGFjZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyogZWxlbWVudHMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50c0F0dHIgfSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yUHJlc2VydmVTcGFjZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3V0cHV0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25BdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmdBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb21pdFhtbERlY2xhcmF0aW9uQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YW5kYWxvbmVBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVB1YmxpY0F0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlU3lzdGVtQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNkYXRhU2VjdGlvbkVsZW1lbnRzQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGVudEF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVR5cGVBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5tX2ZvcmVpZ25BdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JPdXRwdXRFbGVtKCksIG51bGwgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRFbGVtZW50RGVmKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyogZWxlbWVudHMgKi8sICAvLyBFTVBUWQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBuYW1lQXR0clJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaEF0dHJSZXF1aXJlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlQXR0ciB9LCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NvcktleSgpLCBudWxsIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEVsZW1lbnREZWYoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlY2ltYWwtZm9ybWF0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKiBlbGVtZW50cyAqLywgIC8vIEVNUFRZCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lQXR0ck9wdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbFNlcGFyYXRvckF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwaW5nU2VwYXJhdG9yQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5maW5pdHlBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW51c1NpZ25BdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYU5BdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJjZW50QXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyTWlsbGVBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6ZXJvRGlnaXRBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdpdEF0dHIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm5TZXBhcmF0b3JBdHRyIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yRGVjaW1hbEZvcm1hdCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0cmlidXRlLXNldCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbEF0dHJpYnV0ZSB9IC8qIGVsZW1lbnRzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lQXR0clJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlQXR0cmlidXRlU2V0c0F0dHIgfSwgbmV3IFByb2Nlc3NvckF0dHJpYnV0ZVNldCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRFbGVtZW50RGVmKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ2YXJpYWJsZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAvKmFsaWFzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRWxlbWVudHMgLyogZWxlbWVudHMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWZbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVBdHRyUmVxdWlyZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RBdHRyT3B0IH0sIG5ldyBQcm9jZXNzb3JHbG9iYWxWYXJpYWJsZURlY2woKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbVZhcmlhYmxlLmNsYXNzIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEVsZW1lbnREZWYoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhcmFtIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVFbGVtZW50cyAvKiBlbGVtZW50cyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZUF0dHJSZXF1aXJlZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdEF0dHJPcHQgfSwgbmV3IFByb2Nlc3Nvckdsb2JhbFBhcmFtRGVjbCgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtUGFyYW0uY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGVtcGxhdGUiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUVsZW1lbnRzQW5kUGFyYW1zIC8qIGVsZW1lbnRzICovLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaEF0dHJPcHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lQXR0ck9wdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yaXR5QXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2VBdHRyIH0sIG5ldyBQcm9jZXNzb3JUZW1wbGF0ZSgpLCBFbGVtVGVtcGxhdGUuY2xhc3MgLyogY2xhc3Mgb2JqZWN0ICovLCAyMCwgdHJ1ZSksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRFbGVtZW50RGVmKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lc3BhY2UtYWxpYXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsIC8qYWxpYXMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyogZWxlbWVudHMgKi8sICAvLyBFTVBUWQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBzdHlsZXNoZWV0UHJlZml4QXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0UHJlZml4QXR0ciB9LCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9jZXNzb3JOYW1lc3BhY2VBbGlhcygpLCBudWxsIC8qIGNsYXNzIG9iamVjdCAqLywgMjAsIHRydWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEVsZW1lbnREZWYoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19CVUlMVElOX0VYVEVOU0lPTlNfVVJMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21wb25lbnQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEVsZW1lbnREZWZbXXsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xURWxlbWVudERlZigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLlNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNjcmlwdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgLyphbGlhcyAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRFbGVtZW50RGVmW117IGNoYXJEYXRhIH0gLyogZWxlbWVudHMgKi8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWYoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhbmciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX05NVE9LRU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAic3JjIiwgWFNMVEF0dHJpYnV0ZURlZi5UX1VSTCwgZmFsc2UpIH0sIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yTFJFKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbUV4dGVuc2lvblNjcmlwdC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8sIDIwLCB0cnVlKSB9LCAgLy8gRU1QVFkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZltdeyBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAicHJlZml4IiwgWFNMVEF0dHJpYnV0ZURlZi5UX05NVE9LRU4sIHRydWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJlbGVtZW50cyIsIFhTTFRBdHRyaWJ1dGVEZWYuVF9TVFJJTkdMSVNULCBmYWxzZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFhTTFRBdHRyaWJ1dGVEZWYobnVsbCwgImZ1bmN0aW9ucyIsIFhTTFRBdHRyaWJ1dGVEZWYuVF9TVFJJTkdMSVNULCBmYWxzZSkgfSwgbmV3IFByb2Nlc3NvckxSRSgpLCBFbGVtRXh0ZW5zaW9uRGVjbC5jbGFzcyAvKiBjbGFzcyBvYmplY3QgKi8pIH07Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBleGNsdWRlUmVzdWx0UHJlZml4ZXNBdHRyID0KLSAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmKG51bGwsICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfU1RSSU5HTElTVCwgZmFsc2UpOwotICAgIFhTTFRBdHRyaWJ1dGVEZWYgZXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzQXR0ciA9Ci0gICAgICBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX1BSRUZJWF9VUkxMSVNULCBmYWxzZSk7Ci0gICAgWFNMVEF0dHJpYnV0ZURlZiBpZEF0dHIgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLCAiaWQiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUQXR0cmlidXRlRGVmLlRfQ0RBVEEsIGZhbHNlKTsKLSAgICBYU0xUQXR0cmlidXRlRGVmIHZlcnNpb25BdHRyUmVxdWlyZWQgPSBuZXcgWFNMVEF0dHJpYnV0ZURlZihudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZlcnNpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEF0dHJpYnV0ZURlZi5UX05NVE9LRU4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICBYU0xURWxlbWVudERlZiBzdHlsZXNoZWV0RWxlbURlZiA9IG5ldyBYU0xURWxlbWVudERlZih0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHlsZXNoZWV0IiwgInRyYW5zZm9ybSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcExldmVsRWxlbWVudHMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBYU0xUQXR0cmlidXRlRGVmW117Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlUmVzdWx0UHJlZml4ZXNBdHRyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkQXR0ciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uQXR0clJlcXVpcmVkLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlQXR0ciB9LCBuZXcgUHJvY2Vzc29yU3R5bGVzaGVldEVsZW1lbnQoKSwgIC8qIENvbnRlbnRIYW5kbGVyICovCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgIC8qIGNsYXNzIG9iamVjdCAqLywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgLTEsIGZhbHNlKTsKLQotICAgIGltcG9ydERlZi5zZXRFbGVtZW50cyhuZXcgWFNMVEVsZW1lbnREZWZbXXsgc3R5bGVzaGVldEVsZW1EZWYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRFbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5rbm93bkVsZW1lbnQgfSk7Ci0gICAgaW5jbHVkZURlZi5zZXRFbGVtZW50cyhuZXcgWFNMVEVsZW1lbnREZWZbXXsgc3R5bGVzaGVldEVsZW1EZWYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0RWxlbWVudCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duRWxlbWVudCB9KTsKLSAgICBidWlsZChudWxsLCBudWxsLCBudWxsLCBuZXcgWFNMVEVsZW1lbnREZWZbXXsgc3R5bGVzaGVldEVsZW1EZWYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaXRlU3BhY2VPbmx5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRFbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duRWxlbWVudCB9LCBudWxsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHJvY2Vzc29yU3R5bGVzaGVldERvYygpLCAgLyogQ29udGVudEhhbmRsZXIgKi8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCAgLyogY2xhc3Mgb2JqZWN0ICovCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKLSAgfQotCi0gIC8qKgotICAgKiBBIGhhc2h0YWJsZSBvZiBhbGwgYXZhaWxhYmxlIGJ1aWx0LWluIGVsZW1lbnRzIGZvciB1c2UgYnkgdGhlIGVsZW1lbnQtYXZhaWxhYmxlCi0gICAqIGZ1bmN0aW9uLgotICAgKiBUT0RPOiAgV2hlbiB3ZSBjb252ZXJ0IHRvIEphdmEyLCB0aGlzIHNob3VsZCBiZSBhIFNldC4KLSAgICovCi0gIHByaXZhdGUgSGFzaHRhYmxlIG1fYXZhaWxFbGVtcyA9IG5ldyBIYXNodGFibGUoKTsKLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIHRhYmxlIG9mIGF2YWlsYWJsZSBlbGVtZW50cy4KLSAgICogCi0gICAqIEByZXR1cm4gdGFibGUgb2YgYXZhaWxhYmxlIGVsZW1lbnRzLCBrZXllZCBieSBxdWFsaWZpZWQgbmFtZXMsIGFuZCB3aXRoIAotICAgKiB2YWx1ZXMgb2YgdGhlIHNhbWUgcXVhbGlmaWVkIG5hbWVzLgotICAgKi8KLSAgcHVibGljIEhhc2h0YWJsZSBnZXRFbGVtc0F2YWlsYWJsZSgpIAotICB7Ci0gICAgcmV0dXJuIG1fYXZhaWxFbGVtczsKLSAgfQotCi0gIC8qKgotICAgKiBBZGRzIGEgbmV3IGVsZW1lbnQgbmFtZSB0byB0aGUgSGFzaHRhYmxlIG9mIGF2YWlsYWJsZSBlbGVtZW50cy4KLSAgICogQHBhcmFtIGVsZW1OYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHRvIGFkZCB0byB0aGUgSGFzaHRhYmxlIG9mIGF2YWlsYWJsZSBlbGVtZW50cy4KLSAgICovCi0gIHZvaWQgYWRkQXZhaWxhYmxlRWxlbWVudChRTmFtZSBlbGVtTmFtZSkKLSAgewotICAgIG1fYXZhaWxFbGVtcy5wdXQoZWxlbU5hbWUsIGVsZW1OYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHBhc3NlZCBlbGVtZW50IG5hbWUgaXMgcHJlc2VudCBpbiB0aGUgbGlzdCBvZiBhdmFpbGFibGUgZWxlbWVudHMuCi0gICAqIEBwYXJhbSBlbGVtTmFtZSBUaGUgbmFtZSBvZiB0aGUgZWxlbWVudCB0byBsb29rIHVwLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgYW4gZWxlbWVudCBjb3JyZXNwb25kaW5nIHRvIGVsZW1OYW1lIGlzIGF2YWlsYWJsZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVsZW1lbnRBdmFpbGFibGUoUU5hbWUgZWxlbU5hbWUpCi0gIHsKLSAgICByZXR1cm4gbV9hdmFpbEVsZW1zLmNvbnRhaW5zS2V5KGVsZW1OYW1lKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxNjk2ZDYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDIzICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WGFsYW4gUHJvY2Vzc29yIFBhY2thZ2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+UGFyc2VzIGFuIFhTTFQgc3R5bGVzaGVldCBkb2N1bWVudCAod2hpY2ggbWF5IGluY2x1ZGUgYW5kIGltcG9ydCBvdGhlciBzdHlsZXNoZWV0IGRvY3VtZW50cykgYW5kIHByb2R1Y2VzIGEgU3R5bGVzaGVldFJvb3QKLSAgICAoYSBUUmFYIFRlbXBsYXRlcyBvYmplY3QpLjwvcD4KLSAgICAKLSAgICA8cD5TdHlsZXNoZWV0UHJvY2Vzc29yIGltcGxlbWVudHMgdGhlIFRSYVgge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5fSBpbnRlcmZhY2UsCi0gICAgYXMgd2VsbCBhcyB0aGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeX0gaW50ZXJmYWNlLiAKLSAgICBJdCByZWdpc3RlcnMgdGhlIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5TdHlsZXNoZWV0SGFuZGxlcn0gb2JqZWN0IAotICAgIChhIFRyQVgge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXJ9IGltcGxlbWVudGF0aW9uKSAKLSAgICBhcyB0aGUgU0FYIENvbnRlbnRIYW5kbGVyIGZvciBhbiBYTUxSZWFkZXIsIGFuZCB1c2VzIHRoZSBYTUxSZWFkZXIgdG8gcGFyc2UgCi0gICAgdGhlIHN0eWxlc2hlZXQgZG9jdW1lbnQuPC9wPgotICAgIDxwPkJlZm9yZSBwYXJzaW5nIHRoZSBYU0xUIGlucHV0LCBTdHlsZXNoZWV0SGFuZGxlciBhc3NlbWJsZXMgYW4ge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlhTTFRTY2hlbWF9LCAKLSAgICB3aGljaCB1c2VzIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5YU0xURWxlbWVudERlZn0KLSAgICBhbmQge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlhTTFRBdHRyaWJ1dGVEZWZ9IG9iamVjdHMgdG8gCi0gICAgcmVjdXJzaXZlbHkgZGVmaW5lIHRoZSBlbGVtZW50cyBhbmQgYXR0cmlidXRlcyB0aGF0IGFuIFhTTFQgc3R5bGVzaGVldCBtYXkgCi0gICAgY29udGFpbi4gVGhlIFN0eWxlc2hlZXRIYW5kbGVyIHRoZW4gcGFzc2VzIG9uIGVhY2ggcGFyc2UgZXZlbnQgdG8gdGhlIAotICAgIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5YU0xURWxlbWVudFByb2Nlc3Nvcn0gd2hpY2ggdGhlIAotICAgIFhTTFRFbGVtZW50RGVmIGFzc2lnbmVkIHRvIHRoZSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGF0IGV2ZW50LjwvcD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzL1hTTE1lc3NhZ2VzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMvWFNMTWVzc2FnZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODdiNjFkOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMvWFNMTWVzc2FnZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGVCYXNlOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3RSZXNvdXJjZUJ1bmRsZTsKLWltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFNldHMgdGhpbmdzIHVwIGZvciBpc3N1aW5nIGVycm9yIG1lc3NhZ2VzLiAgVGhpcyBjbGFzcyBpcyBtaXNuYW1lZCwgYW5kCi0gKiBzaG91bGQgYmUgY2FsbGVkIFhhbGFuTWVzc2FnZXMsIG9yIHNvbWUgc3VjaC4KLSAqLwotcHVibGljIGNsYXNzIFhTTE1lc3NhZ2VzCi17Ci0KLSAgLyoqIFRoZSBsb2NhbCBvYmplY3QgdG8gdXNlLiAgKi8KLSAgcHJpdmF0ZSBMb2NhbGUgZkxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0KLSAgLyoqIFRoZSBsYW5ndWFnZSBzcGVjaWZpYyByZXNvdXJjZSBvYmplY3QgZm9yIFhhbGFuIG1lc3NhZ2VzLiAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgWFJlc291cmNlQnVuZGxlQmFzZSBYU0xUQnVuZGxlID0gbnVsbDsKLQotICAvKiogVGhlIGxhbmd1YWdlIHNwZWNpZmljIHJlc291cmNlIG9iamVjdCBmb3IgWFBhdGggbWVzc2FnZXMuICAqLwotICBwcml2YXRlIHN0YXRpYyBYUmVzb3VyY2VCdW5kbGVCYXNlIFhQQVRIQnVuZGxlID0gbnVsbDsKLQotICAvKiogVGhlIGNsYXNzIG5hbWUgb2YgdGhlIFhhbGFuIGVycm9yIG1lc3NhZ2Ugc3RyaW5nIHRhYmxlLiAgICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMVF9FUlJPUl9SRVNPVVJDRVMgPQotICAgICJvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXMiOwotCi0gIC8qKiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgWFBhdGggZXJyb3IgbWVzc2FnZSBzdHJpbmcgdGFibGUuICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFBBVEhfRVJST1JfUkVTT1VSQ0VTID0KLSAgICAib3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlcyI7Ci0KLSAgLyoqIFN0cmluZyB0byB1c2UgaWYgYSBiYWQgbWVzc2FnZSBjb2RlIGlzIHVzZWQuICovCi0gIHByaXZhdGUgc3RhdGljIFN0cmluZyBCQURfQ09ERSA9ICJCQURfQ09ERSI7Ci0KLSAgLyoqIFN0cmluZyB0byB1c2UgaWYgdGhlIG1lc3NhZ2UgZm9ybWF0IG9wZXJhdGlvbiBmYWlsZWQuICAqLwotICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgRk9STUFUX0ZBSUxFRCA9ICJGT1JNQVRfRkFJTEVEIjsKLQotICAvKioKLSAgICogU2V0IHRoZSBMb2NhbGUgb2JqZWN0IHRvIHVzZS4KLSAgICogCi0gICAqIEBwYXJhbSBsb2NhbGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIExvY2FsZSBvYmplY3QuCi0gICAqLwotICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpCi0gIHsKLSAgICBmTG9jYWxlID0gbG9jYWxlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgTG9jYWxlIG9iamVjdCB0aGF0IGlzIGJlaW5nIHVzZWQuCi0gICAqIAotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBMb2NhbGUgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKQotICB7Ci0gICAgcmV0dXJuIGZMb2NhbGU7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQKLSAgICogYXJndW1lbnRzLCBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBUaGUga2V5IGZvciB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBAcGFyYW0gYXJncyAgICAgIFRoZSBhcmd1bWVudHMgdG8gYmUgdXNlZCBhcyByZXBsYWNlbWVudCB0ZXh0Ci0gICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIG1lc3NhZ2UgY3JlYXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIHdhcm5pbmcgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY3JlYXRlWFBBVEhXYXJuaW5nKGludCBlcnJvckNvZGUsIE9iamVjdCBhcmdzW10pICAvL3Rocm93cyBFeGNlcHRpb24gCi0gIHsKLQotICAgIGlmIChYUEFUSEJ1bmRsZSA9PSBudWxsKQotICAgICAgWFBBVEhCdW5kbGUgPQotICAgICAgICAoWFJlc291cmNlQnVuZGxlQmFzZSkgbG9hZFJlc291cmNlQnVuZGxlKFhQQVRIX0VSUk9SX1JFU09VUkNFUyk7Ci0KLSAgICBYUmVzb3VyY2VCdW5kbGVCYXNlIGZSZXNvdXJjZUJ1bmRsZSA9IFhQQVRIQnVuZGxlOwotCi0gICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSAhPSBudWxsKQotICAgIHsKLSAgICAgIFN0cmluZyBtc2dLZXkgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0V2FybmluZ0tleShlcnJvckNvZGUpOwotCi0gICAgICByZXR1cm4gY3JlYXRlWFBBVEhNc2coZlJlc291cmNlQnVuZGxlLCBtc2dLZXksIGFyZ3MpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiI7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQKLSAgICogYXJndW1lbnRzLCBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBUaGUga2V5IGZvciB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBAcGFyYW0gYXJncyAgICAgIFRoZSBhcmd1bWVudHMgdG8gYmUgdXNlZCBhcyByZXBsYWNlbWVudCB0ZXh0Ci0gICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIG1lc3NhZ2UgY3JlYXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIG1lc3NhZ2Ugc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY3JlYXRlWFBBVEhNZXNzYWdlKGludCBlcnJvckNvZGUsIE9iamVjdCBhcmdzW10pICAvL3Rocm93cyBFeGNlcHRpb24gCi0gIHsKLQotICAgIGlmIChYUEFUSEJ1bmRsZSA9PSBudWxsKQotICAgICAgWFBBVEhCdW5kbGUgPQotICAgICAgICAoWFJlc291cmNlQnVuZGxlQmFzZSkgbG9hZFJlc291cmNlQnVuZGxlKFhQQVRIX0VSUk9SX1JFU09VUkNFUyk7Ci0KLSAgICBYUmVzb3VyY2VCdW5kbGVCYXNlIGZSZXNvdXJjZUJ1bmRsZSA9IFhQQVRIQnVuZGxlOwotCi0gICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSAhPSBudWxsKQotICAgIHsKLSAgICAgIFN0cmluZyBtc2dLZXkgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0TWVzc2FnZUtleShlcnJvckNvZGUpOwotCi0gICAgICByZXR1cm4gY3JlYXRlWFBBVEhNc2coZlJlc291cmNlQnVuZGxlLCBtc2dLZXksIGFyZ3MpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiI7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQKLSAgICogYXJndW1lbnRzLCBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBUaGUga2V5IGZvciB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKgotICAgKiBAcGFyYW0gZlJlc291cmNlQnVuZGxlIFRoZSByZXNvdXJjZSBidW5kbGUgdG8gdXNlLgotICAgKiBAcGFyYW0gbXNnS2V5ICBUaGUgbWVzc2FnZSBrZXkgdG8gdXNlLgotICAgKiBAcGFyYW0gYXJncyAgICAgIFRoZSBhcmd1bWVudHMgdG8gYmUgdXNlZCBhcyByZXBsYWNlbWVudCB0ZXh0Ci0gICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIG1lc3NhZ2UgY3JlYXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIG1lc3NhZ2Ugc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY3JlYXRlWFBBVEhNc2coWFJlc291cmNlQnVuZGxlQmFzZSBmUmVzb3VyY2VCdW5kbGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2dLZXksIE9iamVjdCBhcmdzW10pICAvL3Rocm93cyBFeGNlcHRpb24gCi0gIHsKLQotICAgIFN0cmluZyBmbXNnID0gbnVsbDsKLSAgICBib29sZWFuIHRocm93ZXggPSBmYWxzZTsKLSAgICBTdHJpbmcgbXNnID0gbnVsbDsKLQotICAgIGlmIChtc2dLZXkgIT0gbnVsbCkKLSAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcobXNnS2V5KTsKLQotICAgIGlmIChtc2cgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKFhQQVRIRXJyb3JSZXNvdXJjZXMuQkFEX0NPREUpOwotICAgICAgdGhyb3dleCA9IHRydWU7Ci0gICAgfQotCi0gICAgaWYgKGFyZ3MgIT0gbnVsbCkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLQotICAgICAgICAvLyBEbyB0aGlzIHRvIGtlZXAgZm9ybWF0IGZyb20gY3J5aW5nLgotICAgICAgICAvLyBUaGlzIGlzIGJldHRlciB0aGFuIG1ha2luZyBhIGJ1bmNoIG9mIGNvbmRpdGlvbmFsCi0gICAgICAgIC8vIGNvZGUgYWxsIG92ZXIgdGhlIHBsYWNlLgotICAgICAgICBpbnQgbiA9IGFyZ3MubGVuZ3RoOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgPT0gYXJnc1tpXSkKLSAgICAgICAgICAgIGFyZ3NbaV0gPSAiIjsKLSAgICAgICAgfQotCi0gICAgICAgIGZtc2cgPSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdC5mb3JtYXQobXNnLCBhcmdzKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgZm1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcoWFBBVEhFcnJvclJlc291cmNlcy5GT1JNQVRfRkFJTEVEKTsKLSAgICAgICAgZm1zZyArPSAiICIgKyBtc2c7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIGZtc2cgPSBtc2c7Ci0KLSAgICBpZiAodGhyb3dleCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihmbXNnKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZm1zZzsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGVzIGEgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQga2V5IGFuZCByZXBsYWNlbWVudAotICAgKiBhcmd1bWVudHMsIGxvY2FsaXplZCB0byB0aGUgZ2l2ZW4gbG9jYWxlLgotICAgKgotICAgKiBAcGFyYW0gZXJyb3JDb2RlIFRoZSBrZXkgZm9yIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIEBwYXJhbSBhcmdzICAgICAgVGhlIGFyZ3VtZW50cyB0byBiZSB1c2VkIGFzIHJlcGxhY2VtZW50IHRleHQKLSAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgbWVzc2FnZSBjcmVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBmb3JtYXR0ZWQgd2FybmluZyBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBjcmVhdGVXYXJuaW5nKGludCBlcnJvckNvZGUsIE9iamVjdCBhcmdzW10pICAvL3Rocm93cyBFeGNlcHRpb24gCi0gIHsKLQotICAgIGlmIChYU0xUQnVuZGxlID09IG51bGwpCi0gICAgICBYU0xUQnVuZGxlID0KLSAgICAgICAgKFhSZXNvdXJjZUJ1bmRsZUJhc2UpIGxvYWRSZXNvdXJjZUJ1bmRsZShYU0xUX0VSUk9SX1JFU09VUkNFUyk7Ci0KLSAgICBYUmVzb3VyY2VCdW5kbGVCYXNlIGZSZXNvdXJjZUJ1bmRsZSA9IFhTTFRCdW5kbGU7Ci0KLSAgICBpZiAoZlJlc291cmNlQnVuZGxlICE9IG51bGwpCi0gICAgewotICAgICAgU3RyaW5nIG1zZ0tleSA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRXYXJuaW5nS2V5KGVycm9yQ29kZSk7Ci0KLSAgICAgIHJldHVybiBjcmVhdGVNc2coZlJlc291cmNlQnVuZGxlLCBtc2dLZXksIGFyZ3MpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiI7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIGtleSBhbmQgcmVwbGFjZW1lbnQKLSAgICogYXJndW1lbnRzLCBsb2NhbGl6ZWQgdG8gdGhlIGdpdmVuIGxvY2FsZS4KLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBUaGUga2V5IGZvciB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBAcGFyYW0gYXJncyAgICAgIFRoZSBhcmd1bWVudHMgdG8gYmUgdXNlZCBhcyByZXBsYWNlbWVudCB0ZXh0Ci0gICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIG1lc3NhZ2UgY3JlYXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZm9ybWF0dGVkIG1lc3NhZ2Ugc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgY3JlYXRlTWVzc2FnZShpbnQgZXJyb3JDb2RlLCBPYmplY3QgYXJnc1tdKSAgLy90aHJvd3MgRXhjZXB0aW9uIAotICB7Ci0KLSAgICBpZiAoWFNMVEJ1bmRsZSA9PSBudWxsKQotICAgICAgWFNMVEJ1bmRsZSA9Ci0gICAgICAgIChYUmVzb3VyY2VCdW5kbGVCYXNlKSBsb2FkUmVzb3VyY2VCdW5kbGUoWFNMVF9FUlJPUl9SRVNPVVJDRVMpOwotCi0gICAgWFJlc291cmNlQnVuZGxlQmFzZSBmUmVzb3VyY2VCdW5kbGUgPSBYU0xUQnVuZGxlOwotCi0gICAgaWYgKGZSZXNvdXJjZUJ1bmRsZSAhPSBudWxsKQotICAgIHsKLSAgICAgIFN0cmluZyBtc2dLZXkgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0TWVzc2FnZUtleShlcnJvckNvZGUpOwotCi0gICAgICByZXR1cm4gY3JlYXRlTXNnKGZSZXNvdXJjZUJ1bmRsZSwgbXNnS2V5LCBhcmdzKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuICJDb3VsZCBub3QgbG9hZCBhbnkgcmVzb3VyY2UgYnVuZGxlcy4iOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCBrZXkgYW5kIHJlcGxhY2VtZW50Ci0gICAqIGFyZ3VtZW50cywgbG9jYWxpemVkIHRvIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAqCi0gICAqIEBwYXJhbSBlcnJvckNvZGUgVGhlIGtleSBmb3IgdGhlIG1lc3NhZ2UgdGV4dC4KLSAgICoKLSAgICogQHBhcmFtIGZSZXNvdXJjZUJ1bmRsZSBUaGUgcmVzb3VyY2UgYnVuZGxlIHRvIHVzZS4KLSAgICogQHBhcmFtIG1zZ0tleSAgVGhlIG1lc3NhZ2Uga2V5IHRvIHVzZS4KLSAgICogQHBhcmFtIGFyZ3MgICAgICBUaGUgYXJndW1lbnRzIHRvIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgdGV4dAotICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBtZXNzYWdlIGNyZWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGZvcm1hdHRlZCBtZXNzYWdlIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGNyZWF0ZU1zZyhYUmVzb3VyY2VCdW5kbGVCYXNlIGZSZXNvdXJjZUJ1bmRsZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtc2dLZXksIE9iamVjdCBhcmdzW10pICAvL3Rocm93cyBFeGNlcHRpb24gCi0gIHsKLQotICAgIFN0cmluZyBmbXNnID0gbnVsbDsKLSAgICBib29sZWFuIHRocm93ZXggPSBmYWxzZTsKLSAgICBTdHJpbmcgbXNnID0gbnVsbDsKLQotICAgIGlmIChtc2dLZXkgIT0gbnVsbCkKLSAgICAgIG1zZyA9IGZSZXNvdXJjZUJ1bmRsZS5nZXRTdHJpbmcobXNnS2V5KTsKLQotICAgIGlmIChtc2cgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKEJBRF9DT0RFKTsKLSAgICAgIHRocm93ZXggPSB0cnVlOwotICAgIH0KLQotICAgIGlmIChhcmdzICE9IG51bGwpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0KLSAgICAgICAgLy8gRG8gdGhpcyB0byBrZWVwIGZvcm1hdCBmcm9tIGNyeWluZy4KLSAgICAgICAgLy8gVGhpcyBpcyBiZXR0ZXIgdGhhbiBtYWtpbmcgYSBidW5jaCBvZiBjb25kaXRpb25hbAotICAgICAgICAvLyBjb2RlIGFsbCBvdmVyIHRoZSBwbGFjZS4KLSAgICAgICAgaW50IG4gPSBhcmdzLmxlbmd0aDsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIGlmIChudWxsID09IGFyZ3NbaV0pCi0gICAgICAgICAgICBhcmdzW2ldID0gIiI7Ci0gICAgICAgIH0KLQotICAgICAgICBmbXNnID0gamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1zZywgYXJncyk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGZtc2cgPSBmUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKEZPUk1BVF9GQUlMRUQpOwotICAgICAgICBmbXNnICs9ICIgIiArIG1zZzsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgZm1zZyA9IG1zZzsKLQotICAgIGlmICh0aHJvd2V4KQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZtc2cpOwotICAgIH0KLQotICAgIHJldHVybiBmbXNnOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYSBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCBrZXkgYW5kIHJlcGxhY2VtZW50Ci0gICAqIGFyZ3VtZW50cywgbG9jYWxpemVkIHRvIHRoZSBnaXZlbiBsb2NhbGUuCi0gICAqCi0gICAqIEBwYXJhbSBidW5kbGVOYW1lIFRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSBidW5kbGUgdG8gYmUKLSAgICogICAgICAgICAgICAgICAgICB1c2VkLgotICAgKiBAcGFyYW0gZXJyb3JDb2RlIFRoZSBrZXkgZm9yIHRoZSBtZXNzYWdlIHRleHQuCi0gICAqIEBwYXJhbSBhcmdzICAgICAgVGhlIGFyZ3VtZW50cyB0byBiZSB1c2VkIGFzIHJlcGxhY2VtZW50IHRleHQKLSAgICogICAgICAgICAgICAgICAgICBpbiB0aGUgbWVzc2FnZSBjcmVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBmb3JtYXR0ZWQgbWVzc2FnZSBzdHJpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgRXhjZXB0aW9uIGlmIHRoZSBtZXNzYWdlIGNhbiBub3QgYmUgbG9hZGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBjcmVhdGVNZXNzYWdlKFN0cmluZyBidW5kbGVOYW1lLCBpbnQgZXJyb3JDb2RlLCBPYmplY3QgYXJnc1tdKQotICAgICAgICAgIHRocm93cyBFeGNlcHRpb24KLSAgewotCi0gICAgYm9vbGVhbiB0aHJvd2V4ID0gZmFsc2U7Ci0gICAgaW50IG1ham9yQ29kZTsKLSAgICBpbnQgbWlub3JDb2RlOwotICAgIFN0cmluZyBmbXNnID0gbnVsbDsKLSAgICBYUmVzb3VyY2VCdW5kbGVCYXNlIGFSZXNvdXJjZUJ1bmRsZSA9IG51bGw7Ci0KLSAgICBhUmVzb3VyY2VCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlQmFzZSkgbG9hZFJlc291cmNlQnVuZGxlKGJ1bmRsZU5hbWUpOwotCi0gICAgU3RyaW5nIG1zZ0tleSA9IGFSZXNvdXJjZUJ1bmRsZS5nZXRNZXNzYWdlS2V5KGVycm9yQ29kZSk7Ci0gICAgU3RyaW5nIG1zZyA9IG51bGw7Ci0KLSAgICBpZiAobXNnS2V5ICE9IG51bGwpCi0gICAgICBtc2cgPSBhUmVzb3VyY2VCdW5kbGUuZ2V0U3RyaW5nKG1zZ0tleSk7Ci0KLSAgICBpZiAobXNnID09IG51bGwpCi0gICAgewotICAgICAgbXNnID0gYVJlc291cmNlQnVuZGxlLmdldFN0cmluZyhCQURfQ09ERSk7Ci0gICAgICB0aHJvd2V4ID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBpZiAoYXJncyAhPSBudWxsKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotCi0gICAgICAgIC8vIERvIHRoaXMgdG8ga2VlcCBmb3JtYXQgZnJvbSBjcnlpbmcuCi0gICAgICAgIC8vIFRoaXMgaXMgYmV0dGVyIHRoYW4gbWFraW5nIGEgYnVuY2ggb2YgY29uZGl0aW9uYWwKLSAgICAgICAgLy8gY29kZSBhbGwgb3ZlciB0aGUgcGxhY2UuCi0gICAgICAgIGludCBuID0gYXJncy5sZW5ndGg7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCA9PSBhcmdzW2ldKQotICAgICAgICAgICAgYXJnc1tpXSA9ICIiOwotICAgICAgICB9Ci0KLSAgICAgICAgZm1zZyA9IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIGFyZ3MpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBmbXNnID0gYVJlc291cmNlQnVuZGxlLmdldFN0cmluZyhGT1JNQVRfRkFJTEVEKTsKLSAgICAgICAgZm1zZyArPSAiICIgKyBtc2c7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIGZtc2cgPSBtc2c7Ci0KLSAgICBpZiAodGhyb3dleCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihmbXNnKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZm1zZzsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBuYW1lZCBSZXNvdXJjZUJ1bmRsZSBmb3IgYSBwYXJ0aWN1bGFyIGxvY2FsZS4gIFRoaXMgbWV0aG9kIG1pbWljcyB0aGUgYmVoYXZpb3IKLSAgICogb2YgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKCkuCi0gICAqCi0gICAqIEBwYXJhbSByZXMgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxvYWQuCi0gICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSB0byBwcmVmZXIgd2hlbiBzZWFyY2hpbmcgZm9yIHRoZSBidW5kbGUKLSAgICoKLSAgICogQHBhcmFtIGNsYXNzTmFtZSBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgcmVzb3VyY2UgYnVuZGxlLgotICAgKiBAcmV0dXJuIHRoZSBSZXNvdXJjZUJ1bmRsZQotICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBMaXN0UmVzb3VyY2VCdW5kbGUgbG9hZFJlc291cmNlQnVuZGxlKFN0cmluZyBjbGFzc05hbWUpCi0gICAgICAgICAgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgotICB7Ci0KLSAgICBMb2NhbGUgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKLQotICAgIC8vIFN0cmluZyBzdWZmaXggPSBnZXRSZXNvdXJjZVN1ZmZpeChsb2NhbGUpOyAgCi0gICAgdHJ5Ci0gICAgewotCi0gICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigicmVzb3VyY2UgIiArY2xhc3NOYW1lK3N1ZmZpeCk7Ci0gICAgICAvLyBmaXJzdCB0cnkgd2l0aCB0aGUgZ2l2ZW4gbG9jYWxlCi0gICAgICByZXR1cm4gKExpc3RSZXNvdXJjZUJ1bmRsZSkgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGNsYXNzTmFtZSwgbG9jYWxlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHRyeSAgLy8gdHJ5IHRvIGZhbGwgYmFjayB0byBlbl9VUyBpZiB3ZSBjYW4ndCBsb2FkCi0gICAgICB7Ci0KLSAgICAgICAgLy8gU2luY2Ugd2UgY2FuJ3QgZmluZCB0aGUgbG9jYWxpemVkIHByb3BlcnR5IGZpbGUsCi0gICAgICAgIC8vIGZhbGwgYmFjayB0byBlbl9VUy4KLSAgICAgICAgcmV0dXJuIChMaXN0UmVzb3VyY2VCdW5kbGUpIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZSgKLSAgICAgICAgICBYU0xUX0VSUk9SX1JFU09VUkNFUywgbmV3IExvY2FsZSgiZW4iLCAiVVMiKSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUyKQotICAgICAgewotCi0gICAgICAgIC8vIE5vdyB3ZSBhcmUgcmVhbGx5IGluIHRyb3VibGUuCi0gICAgICAgIC8vIHZlcnkgYmFkLCBkZWZpbml0ZWx5IHZlcnkgYmFkLi4ubm90IGdvaW5nIHRvIGdldCB2ZXJ5IGZhcgotICAgICAgICB0aHJvdyBuZXcgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uKAotICAgICAgICAgICJDb3VsZCBub3QgbG9hZCBhbnkgcmVzb3VyY2UgYnVuZGxlcy4iICsgY2xhc3NOYW1lLCBjbGFzc05hbWUsICIiKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSByZXNvdXJjZSBmaWxlIHN1ZmZpYyBmb3IgdGhlIGluZGljYXRlZCBsb2NhbGUKLSAgICogRm9yIG1vc3QgbG9jYWxlcywgdGhpcyB3aWxsIGJlIGJhc2VkIHRoZSBsYW5ndWFnZSBjb2RlLiAgSG93ZXZlcgotICAgKiBmb3IgQ2hpbmVzZSwgd2UgZG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBUYWl3YW4gYW5kIFBSQwotICAgKgotICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUKLSAgICogQHJldHVybiBhbiBTdHJpbmcgc3VmZml4IHdoaWNoIGNhbiBiZSBhcHBlbmRlZCB0byBhIHJlc291cmNlIG5hbWUKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBnZXRSZXNvdXJjZVN1ZmZpeChMb2NhbGUgbG9jYWxlKQotICB7Ci0KLSAgICBTdHJpbmcgc3VmZml4ID0gIl8iICsgbG9jYWxlLmdldExhbmd1YWdlKCk7Ci0gICAgU3RyaW5nIGNvdW50cnkgPSBsb2NhbGUuZ2V0Q291bnRyeSgpOwotCi0gICAgaWYgKGNvdW50cnkuZXF1YWxzKCJUVyIpKQotICAgICAgc3VmZml4ICs9ICJfIiArIGNvdW50cnk7Ci0KLSAgICByZXR1cm4gc3VmZml4OwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMvWFNMVEVycm9yUmVzb3VyY2VzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMvWFNMVEVycm9yUmVzb3VyY2VzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUzY2FkZjcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzL1hTTFRFcnJvclJlc291cmNlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY5NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGVCYXNlOwotCi1pbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotaW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsKLQotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotCi0vKioKLSAqIFNldCB1cCBlcnJvciBtZXNzYWdlcy4KLSAqIFdlIGJ1aWxkIGEgdHdvIGRpbWVuc2lvbmFsIGFycmF5IG9mIG1lc3NhZ2Uga2V5cyBhbmQKLSAqIG1lc3NhZ2Ugc3RyaW5ncy4gSW4gb3JkZXIgdG8gYWRkIGEgbmV3IG1lc3NhZ2UgaGVyZSwKLSAqIHlvdSBuZWVkIHRvIGZpcnN0IHVwZGF0ZSB0aGUgY291bnQgb2YgbWVzc2FnZXMoTUFYX0NPREUpb3IKLSAqIHRoZSBjb3VudCBvZiB3YXJuaW5ncyhNQVhfV0FSTklORykuIFRoZSBhcnJheSB3aWxsIGJlCi0gKiBhdXRvbWF0aWNhbGx5IGZpbGxlZCBpbiB3aXRoIHRoZSBrZXlzLCBidXQgeW91IG5lZWQgdG8KLSAqIGZpbGwgaW4gdGhlIGFjdHVhbCBtZXNzYWdlIHN0cmluZy4gRm9sbG93IHRoZSBpbnN0cnVjdGlvbnMKLSAqIGJlbG93LgotICovCi1wdWJsaWMgY2xhc3MgWFNMVEVycm9yUmVzb3VyY2VzIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlQmFzZQotewotCi0gIC8qKiBUaGUgZXJyb3Igc3VmZml4IGZvciBjb25zdHJ1Y3Rpb24gZXJyb3IgcHJvcGVydHkga2V5cy4gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVUZGSVggPSAiRVIiOwotCi0gIC8qKiBUaGUgd2FybmluZyBzdWZmaXggZm9yIGNvbnN0cnVjdGlvbiBlcnJvciBwcm9wZXJ0eSBrZXlzLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdBUk5JTkdfU1VGRklYID0gIldSIjsKLQotICAvKiogTWF4aW11bSBlcnJvciBtZXNzYWdlcywgdGhpcyBpcyBuZWVkZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfQ09ERSA9IDIxNjsgICAgICAgICAgCi0KLSAgLyoqIE1heGltdW0gd2FybmluZ3MsIHRoaXMgaXMgbmVlZGVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB3YXJuaW5ncy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1dBUk5JTkcgPSAyNjsKLQotICAvKiogTWF4aW11bSBtaXNjIHN0cmluZ3MuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX09USEVSUyA9IDQ1OwotCi0gIC8qKiBNYXhpbXVtIHRvdGFsIHdhcm5pbmdzIGFuZCBlcnJvciBtZXNzYWdlcy4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX01FU1NBR0VTID0gTUFYX0NPREUgKyBNQVhfV0FSTklORyArIDE7Ci0KLSAgLyoqIFRoZSBsb29rdXAgdGFibGUgZm9yIGVycm9yIG1lc3NhZ2VzLiAgICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgICBuZXcgT2JqZWN0W01BWF9NRVNTQUdFUyArIE1BWF9PVEhFUlMgKyAxXVsyXTsKLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSBrZXlzLgotICAgKiBUaGlzIGRvZXMgbm90IG5lZWQgdG8gYmUgdXBkYXRlZC4gSWYgTUFYX0NPREUgYW5kIE1BWF9XQVJOSU5HCi0gICAqIGFyZSBjb3JyZWN0LCB0aGUga2V5cyB3aWxsIGdldCBmaWxsZWQgaW4gYXV0b21hdGljYWxseSB3aXRoCi0gICAqIHRoZSB2YWx1ZSBFUnh4eHggKFdSeHh4eCBmb3Igd2FybmluZ3MpIHdoZXJlIHh4eHggaXMgYQotICAgKiBmb3JtYXR0ZWQgbnVtYmVyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGVycm9yIGNvZGUgKGkuZS4gRVIwMDAxKS4KLSAgICovCi0gIHN0YXRpYwotICB7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNQVhfQ09ERSArIDE7IGkrKykKLSAgICB7Ci0gICAgICBjb250ZW50c1tpXVswXSA9IGdldE1LZXkoaSk7Ci0gICAgfQotCi0gICAgZm9yIChpbnQgaSA9IDE7IGkgPCBNQVhfV0FSTklORyArIDE7IGkrKykKLSAgICB7Ci0gICAgICBjb250ZW50c1tpICsgTUFYX0NPREVdWzBdID0gZ2V0V0tleShpKTsKLSAgICB9Ci0gIH0KLQotICAvKgotICAgKiBOb3cgZmlsbCBpbiB0aGUgbWVzc2FnZSB0ZXh0LgotICAgKiBGaXJzdCBjcmVhdGUgYW4gaW50IGZvciB0aGUgbWVzc2FnZSBjb2RlLiBNYWtlIHN1cmUgeW91Ci0gICAqIHVwZGF0ZSBNQVhfQ09ERSBmb3IgZXJyb3IgbWVzc2FnZXMgYW5kIE1BWF9XQVJOSU5HIGZvciB3YXJuaW5ncwotICAgKiBUaGVuIGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dCBmb3IgdGhhdCBtZXNzYWdlIGNvZGUgaW4gdGhlCi0gICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgICovCi0KLSAgLy8gRXJyb3IgbWVzc2FnZXMuLi4KLQotICAvKiogRXJyb3IgbWVzc2FnZSBJRCB0aGF0IGhhcyBhIG51bGwgbWVzc2FnZSwgYnV0IHRha2VzIGluIGEgc2luZ2xlIG9iamVjdC4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJST1IwMDAwID0gMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSUk9SMDAwMF1bMV0gPSAiezB9IjsKLSAgfQotCi0gIC8qKiBFUl9OT19DVVJMWUJSQUNFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX0NVUkxZQlJBQ0UgPSAxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fQ1VSTFlCUkFDRV1bMV0gPQotICAgICAgIkVycm9yOiBDYW4gbm90IGhhdmUgJ3snIHdpdGhpbiBleHByZXNzaW9uIjsKLSAgfQotCi0gIC8qKiBFUl9JTExFR0FMX0FUVFJJQlVURSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTExFR0FMX0FUVFJJQlVURSA9IDI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTExFR0FMX0FUVFJJQlVURV1bMV0gPSAiezB9IGhhcyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZTogezF9IjsKLSAgfQotCi0gIC8qKiBFUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05VTExfU09VUkNFTk9ERV9BUFBMWUlNUE9SVFMgPSAzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTlVMTF9TT1VSQ0VOT0RFX0FQUExZSU1QT1JUU11bMV0gPQotICAgICAgInNvdXJjZU5vZGUgaXMgbnVsbCBpbiB4c2w6YXBwbHktaW1wb3J0cyEiOwotICB9Ci0KLSAgLyoqIEVSX0NBTk5PVF9BREQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOTk9UX0FERCA9IDQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DQU5OT1RfQUREXVsxXSA9ICJDYW4gbm90IGFkZCB7MH0gdG8gezF9IjsKLSAgfQotCi0gIC8qKiBFUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTlVMTF9TT1VSQ0VOT0RFX0hBTkRMRUFQUExZVEVNUExBVEVTID0gNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05VTExfU09VUkNFTk9ERV9IQU5ETEVBUFBMWVRFTVBMQVRFU11bMV0gPQotICAgICAgInNvdXJjZU5vZGUgaXMgbnVsbCBpbiBoYW5kbGVBcHBseVRlbXBsYXRlc0luc3RydWN0aW9uISI7Ci0gIH0KLQotICAvKiogRVJfTk9fTkFNRV9BVFRSSUIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fTkFNRV9BVFRSSUIgPSA2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fTkFNRV9BVFRSSUJdWzFdID0gInswfSBtdXN0IGhhdmUgYSBuYW1lIGF0dHJpYnV0ZS4iOwotICB9Ci0KLSAgLyoqIEVSX1RFTVBMQVRFX05PVF9GT1VORCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9URU1QTEFURV9OT1RfRk9VTkQgPSA3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfVEVNUExBVEVfTk9UX0ZPVU5EXVsxXSA9ICJDb3VsZCBub3QgZmluZCB0ZW1wbGF0ZSBuYW1lZDogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9DQU5UX1JFU09MVkVfTkFNRV9BVlQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOVF9SRVNPTFZFX05BTUVfQVZUID0gODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTlRfUkVTT0xWRV9OQU1FX0FWVF1bMV0gPQotICAgICAgIkNvdWxkIG5vdCByZXNvbHZlIG5hbWUgQVZUIGluIHhzbDpjYWxsLXRlbXBsYXRlLiI7Ci0gIH0KLQotICAvKiogRVJfUkVRVUlSRVNfQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1JFUVVJUkVTX0FUVFJJQiA9IDk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9SRVFVSVJFU19BVFRSSUJdWzFdID0gInswfSByZXF1aXJlcyBhdHRyaWJ1dGU6IHsxfSI7Ci0gIH0KLQotICAvKiogRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX01VU1RfSEFWRV9URVNUX0FUVFJJQiA9IDEwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTVVTVF9IQVZFX1RFU1RfQVRUUklCXVsxXSA9Ci0gICAgICAiezB9IG11c3QgaGF2ZSBhICd0ZXN0JyBhdHRyaWJ1dGUuIjsKLSAgfQotCi0gIC8qKiBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9CQURfVkFMX09OX0xFVkVMX0FUVFJJQiA9IDExOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQkFEX1ZBTF9PTl9MRVZFTF9BVFRSSUJdWzFdID0KLSAgICAgICJCYWQgdmFsdWUgb24gbGV2ZWwgYXR0cmlidXRlOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OQU1FX0NBTlRfQkVfWE1MID0gMTI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTkFNRV9DQU5UX0JFX1hNTF1bMV0gPQotICAgICAgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbmFtZSBjYW4gbm90IGJlICd4bWwnIjsKLSAgfQotCi0gIC8qKiBFUl9QUk9DRVNTSU5HSU5TVFJVQ1RJT05fTk9UVkFMSURfTkNOQU1FICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUUgPSAxMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST0NFU1NJTkdJTlNUUlVDVElPTl9OT1RWQUxJRF9OQ05BTUVdWzFdID0KLSAgICAgICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5hbWUgbXVzdCBiZSBhIHZhbGlkIE5DTmFtZTogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9ORUVEX01BVENIX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9ORUVEX01BVENIX0FUVFJJQiA9IDE0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTkVFRF9NQVRDSF9BVFRSSUJdWzFdID0KLSAgICAgICJ7MH0gbXVzdCBoYXZlIGEgbWF0Y2ggYXR0cmlidXRlIGlmIGl0IGhhcyBhIG1vZGUuIjsKLSAgfQotCi0gIC8qKiBFUl9ORUVEX05BTUVfT1JfTUFUQ0hfQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUIgPSAxNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05FRURfTkFNRV9PUl9NQVRDSF9BVFRSSUJdWzFdID0KLSAgICAgICJ7MH0gcmVxdWlyZXMgZWl0aGVyIGEgbmFtZSBvciBhIG1hdGNoIGF0dHJpYnV0ZS4iOwotICB9Ci0KLSAgLyoqIEVSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX1JFU09MVkVfTlNQUkVGSVggPSAxNjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTlRfUkVTT0xWRV9OU1BSRUZJWF1bMV0gPQotICAgICAgIkNhbiBub3QgcmVzb2x2ZSBuYW1lc3BhY2UgcHJlZml4OiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX0lMTEVHQUxfVkFMVUUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSUxMRUdBTF9WQUxVRSA9IDE3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSUxMRUdBTF9WQUxVRV1bMV0gPSAieG1sOnNwYWNlIGhhcyBhbiBpbGxlZ2FsIHZhbHVlOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX05PX09XTkVSRE9DICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX09XTkVSRE9DID0gMTg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT19PV05FUkRPQ11bMV0gPQotICAgICAgIkNoaWxkIG5vZGUgZG9lcyBub3QgaGF2ZSBhbiBvd25lciBkb2N1bWVudCEiOwotICB9Ci0KLSAgLyoqIEVSX0VMRU1URU1QTEFURUVMRU1fRVJSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0VMRU1URU1QTEFURUVMRU1fRVJSID0gMTk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FTEVNVEVNUExBVEVFTEVNX0VSUl1bMV0gPSAiRWxlbVRlbXBsYXRlRWxlbWVudCBlcnJvcjogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9OVUxMX0NISUxEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05VTExfQ0hJTEQgPSAyMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05VTExfQ0hJTERdWzFdID0gIlRyeWluZyB0byBhZGQgYSBudWxsIGNoaWxkISI7Ci0gIH0KLQotICAvKiogRVJfTkVFRF9TRUxFQ1RfQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05FRURfU0VMRUNUX0FUVFJJQiA9IDIxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTkVFRF9TRUxFQ1RfQVRUUklCXVsxXSA9ICJ7MH0gcmVxdWlyZXMgYSBzZWxlY3QgYXR0cmlidXRlLiI7Ci0gIH0KLQotICAvKiogRVJfTkVFRF9URVNUX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9ORUVEX1RFU1RfQVRUUklCID0gMjI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9ORUVEX1RFU1RfQVRUUklCXVsxXSA9Ci0gICAgICAieHNsOndoZW4gbXVzdCBoYXZlIGEgJ3Rlc3QnIGF0dHJpYnV0ZS4iOwotICB9Ci0KLSAgLyoqIEVSX05FRURfTkFNRV9BVFRSSUIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTkVFRF9OQU1FX0FUVFJJQiA9IDIzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTkVFRF9OQU1FX0FUVFJJQl1bMV0gPQotICAgICAgInhzbDp3aXRoLXBhcmFtIG11c3QgaGF2ZSBhICduYW1lJyBhdHRyaWJ1dGUuIjsKLSAgfQotCi0gIC8qKiBFUl9OT19DT05URVhUX09XTkVSRE9DICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX0NPTlRFWFRfT1dORVJET0MgPSAyNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX0NPTlRFWFRfT1dORVJET0NdWzFdID0KLSAgICAgICJjb250ZXh0IGRvZXMgbm90IGhhdmUgYW4gb3duZXIgZG9jdW1lbnQhIjsKLSAgfQotCi0gIC8qKiBFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT04gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09VTERfTk9UX0NSRUFURV9YTUxfUFJPQ19MSUFJU09OID0gMjU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DT1VMRF9OT1RfQ1JFQVRFX1hNTF9QUk9DX0xJQUlTT05dWzFdID0KLSAgICAgICJDb3VsZCBub3QgY3JlYXRlIFhNTCBUcmFuc2Zvcm1lckZhY3RvcnkgTGlhaXNvbjogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9QUk9DRVNTX05PVF9TVUNDRVNTRlVMICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUwgPSAyNjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST0NFU1NfTk9UX1NVQ0NFU1NGVUxdWzFdID0KLSAgICAgICJYYWxhbjogUHJvY2VzcyB3YXMgbm90IHN1Y2Nlc3NmdWwuIjsKLSAgfQotCi0gIC8qKiBFUl9OT1RfU1VDQ0VTU0ZVTCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT1RfU1VDQ0VTU0ZVTCA9IDI3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9UX1NVQ0NFU1NGVUxdWzFdID0gIlhhbGFuOiB3YXMgbm90IHN1Y2Nlc3NmdWwuIjsKLSAgfQotCi0gIC8qKiBFUl9FTkNPRElOR19OT1RfU1VQUE9SVEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0VOQ09ESU5HX05PVF9TVVBQT1JURUQgPSAyODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0VOQ09ESU5HX05PVF9TVVBQT1JURURdWzFdID0gIkVuY29kaW5nIG5vdCBzdXBwb3J0ZWQ6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVUxEX05PVF9DUkVBVEVfVFJBQ0VMSVNURU5FUiA9IDI5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ09VTERfTk9UX0NSRUFURV9UUkFDRUxJU1RFTkVSXVsxXSA9Ci0gICAgICAiQ291bGQgbm90IGNyZWF0ZSBUcmFjZUxpc3RlbmVyOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9LRVlfUkVRVUlSRVNfTkFNRV9BVFRSSUIgPSAzMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0tFWV9SRVFVSVJFU19OQU1FX0FUVFJJQl1bMV0gPQotICAgICAgInhzbDprZXkgcmVxdWlyZXMgYSAnbmFtZScgYXR0cmlidXRlISI7Ci0gIH0KLQotICAvKiogRVJfS0VZX1JFUVVJUkVTX01BVENIX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9LRVlfUkVRVUlSRVNfTUFUQ0hfQVRUUklCID0gMzE7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9LRVlfUkVRVUlSRVNfTUFUQ0hfQVRUUklCXVsxXSA9Ci0gICAgICAieHNsOmtleSByZXF1aXJlcyBhICdtYXRjaCcgYXR0cmlidXRlISI7Ci0gIH0KLQotICAvKiogRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfS0VZX1JFUVVJUkVTX1VTRV9BVFRSSUIgPSAzMjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0tFWV9SRVFVSVJFU19VU0VfQVRUUklCXVsxXSA9Ci0gICAgICAieHNsOmtleSByZXF1aXJlcyBhICd1c2UnIGF0dHJpYnV0ZSEiOwotICB9Ci0KLSAgLyoqIEVSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9SRVFVSVJFU19FTEVNRU5UU19BVFRSSUIgPSAzMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1JFUVVJUkVTX0VMRU1FTlRTX0FUVFJJQl1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IHJlcXVpcmVzIGFuICdlbGVtZW50cycgYXR0cmlidXRlISI7Ci0gIH0KLQotICAvKiogRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX01JU1NJTkdfUFJFRklYX0FUVFJJQiA9IDM0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTUlTU0lOR19QUkVGSVhfQVRUUklCXVsxXSA9Ci0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gYXR0cmlidXRlICdwcmVmaXgnIGlzIG1pc3NpbmciOwotICB9Ci0KLSAgLyoqIEVSX0JBRF9TVFlMRVNIRUVUX1VSTCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9CQURfU1RZTEVTSEVFVF9VUkwgPSAzNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0JBRF9TVFlMRVNIRUVUX1VSTF1bMV0gPSAiU3R5bGVzaGVldCBVUkwgaXMgYmFkOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX0ZJTEVfTk9UX0ZPVU5EICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0ZJTEVfTk9UX0ZPVU5EID0gMzY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9GSUxFX05PVF9GT1VORF1bMV0gPSAiU3R5bGVzaGVldCBmaWxlIHdhcyBub3QgZm91bmQ6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfSU9FWENFUFRJT04gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSU9FWENFUFRJT04gPSAzNzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lPRVhDRVBUSU9OXVsxXSA9Ci0gICAgICAiSGFkIElPIEV4Y2VwdGlvbiB3aXRoIHN0eWxlc2hlZXQgZmlsZTogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9OT19IUkVGX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19IUkVGX0FUVFJJQiA9IDM4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fSFJFRl9BVFRSSUJdWzFdID0KLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIENvdWxkIG5vdCBmaW5kIGhyZWYgYXR0cmlidXRlIGZvciB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NUWUxFU0hFRVRfSU5DTFVERVNfSVRTRUxGID0gMzk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TVFlMRVNIRUVUX0lOQ0xVREVTX0lUU0VMRl1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGlzIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW5jbHVkaW5nIGl0c2VsZiEiOwotICB9Ci0KLSAgLyoqIEVSX1BST0NFU1NJTkNMVURFX0VSUk9SICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BST0NFU1NJTkNMVURFX0VSUk9SID0gNDA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUk9DRVNTSU5DTFVERV9FUlJPUl1bMV0gPQotICAgICAgIlN0eWxlc2hlZXRIYW5kbGVyLnByb2Nlc3NJbmNsdWRlIGVycm9yLCB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX01JU1NJTkdfTEFOR19BVFRSSUIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTUlTU0lOR19MQU5HX0FUVFJJQiA9IDQxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTUlTU0lOR19MQU5HX0FUVFJJQl1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGF0dHJpYnV0ZSAnbGFuZycgaXMgbWlzc2luZyI7Ci0gIH0KLQotICAvKiogRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTUlTU0lOR19DT05UQUlORVJfRUxFTUVOVF9DT01QT05FTlQgPSA0MjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX01JU1NJTkdfQ09OVEFJTkVSX0VMRU1FTlRfQ09NUE9ORU5UXVsxXSA9Ci0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBtaXNwbGFjZWQgezB9IGVsZW1lbnQ/PyBNaXNzaW5nIGNvbnRhaW5lciBlbGVtZW50ICdjb21wb25lbnQnIjsKLSAgfQotCi0gIC8qKiBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5fT05MWV9PVVRQVVRfVE9fRUxFTUVOVCA9IDQzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOX09OTFlfT1VUUFVUX1RPX0VMRU1FTlRdWzFdID0KLSAgICAgICJDYW4gb25seSBvdXRwdXQgdG8gYW4gRWxlbWVudCwgRG9jdW1lbnRGcmFnbWVudCwgRG9jdW1lbnQsIG9yIFByaW50V3JpdGVyLiI7Ci0gIH0KLQotICAvKiogRVJfUFJPQ0VTU19FUlJPUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QUk9DRVNTX0VSUk9SID0gNDQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUk9DRVNTX0VSUk9SXVsxXSA9ICJTdHlsZXNoZWV0Um9vdC5wcm9jZXNzIGVycm9yIjsKLSAgfQotCi0gIC8qKiBFUl9VTklNUExOT0RFX0VSUk9SICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1VOSU1QTE5PREVfRVJST1IgPSA0NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOSU1QTE5PREVfRVJST1JdWzFdID0gIlVuSW1wbE5vZGUgZXJyb3I6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fU0VMRUNUX0VYUFJFU1NJT04gPSA0NjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1NFTEVDVF9FWFBSRVNTSU9OXVsxXSA9Ci0gICAgICAiRXJyb3IhIERpZCBub3QgZmluZCB4cGF0aCBzZWxlY3QgZXhwcmVzc2lvbiAoLXNlbGVjdCkuIjsKLSAgfQotCi0gIC8qKiBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5OT1RfU0VSSUFMSVpFX1hTTFBST0NFU1NPUiA9IDQ3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX1NFUklBTElaRV9YU0xQUk9DRVNTT1JdWzFdID0KLSAgICAgICJDYW4gbm90IHNlcmlhbGl6ZSBhbiBYU0xQcm9jZXNzb3IhIjsKLSAgfQotCi0gIC8qKiBFUl9OT19JTlBVVF9TVFlMRVNIRUVUICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX0lOUFVUX1NUWUxFU0hFRVQgPSA0ODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX0lOUFVUX1NUWUxFU0hFRVRdWzFdID0KLSAgICAgICJTdHlsZXNoZWV0IGlucHV0IHdhcyBub3Qgc3BlY2lmaWVkISI7Ci0gIH0KLQotICAvKiogRVJfRkFJTEVEX1BST0NFU1NfU1RZTEVTSEVFVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUID0gNDk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9GQUlMRURfUFJPQ0VTU19TVFlMRVNIRUVUXVsxXSA9Ci0gICAgICAiRmFpbGVkIHRvIHByb2Nlc3Mgc3R5bGVzaGVldCEiOwotICB9Ci0KLSAgLyoqIEVSX0NPVUxETlRfUEFSU0VfRE9DICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVUxETlRfUEFSU0VfRE9DID0gNTA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DT1VMRE5UX1BBUlNFX0RPQ11bMV0gPSAiQ291bGQgbm90IHBhcnNlIHswfSBkb2N1bWVudCEiOwotICB9Ci0KLSAgLyoqIEVSX0NPVUxETlRfRklORF9GUkFHTUVOVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DT1VMRE5UX0ZJTkRfRlJBR01FTlQgPSA1MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPVUxETlRfRklORF9GUkFHTUVOVF1bMV0gPSAiQ291bGQgbm90IGZpbmQgZnJhZ21lbnQ6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfTk9ERV9OT1RfRUxFTUVOVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT0RFX05PVF9FTEVNRU5UID0gNTI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT0RFX05PVF9FTEVNRU5UXVsxXSA9Ci0gICAgICAiTm9kZSBwb2ludGVkIHRvIGJ5IGZyYWdtZW50IGlkZW50aWZpZXIgd2FzIG5vdCBhbiBlbGVtZW50OiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9GT1JFQUNIX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPSA1MzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0ZPUkVBQ0hfTkVFRF9NQVRDSF9PUl9OQU1FX0FUVFJJQl1bMV0gPQotICAgICAgImZvci1lYWNoIG11c3QgaGF2ZSBlaXRoZXIgYSBtYXRjaCBvciBuYW1lIGF0dHJpYnV0ZSI7Ci0gIH0KLQotICAvKiogRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfVEVNUExBVEVTX05FRURfTUFUQ0hfT1JfTkFNRV9BVFRSSUIgPSA1NDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1RFTVBMQVRFU19ORUVEX01BVENIX09SX05BTUVfQVRUUklCXVsxXSA9Ci0gICAgICAidGVtcGxhdGVzIG11c3QgaGF2ZSBlaXRoZXIgYSBtYXRjaCBvciBuYW1lIGF0dHJpYnV0ZSI7Ci0gIH0KLQotICAvKiogRVJfTk9fQ0xPTkVfT0ZfRE9DVU1FTlRfRlJBRyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHID0gNTU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT19DTE9ORV9PRl9ET0NVTUVOVF9GUkFHXVsxXSA9Ci0gICAgICAiTm8gY2xvbmUgb2YgYSBkb2N1bWVudCBmcmFnbWVudCEiOwotICB9Ci0KLSAgLyoqIEVSX0NBTlRfQ1JFQVRFX0lURU0gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOVF9DUkVBVEVfSVRFTSA9IDU2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOVF9DUkVBVEVfSVRFTV1bMV0gPQotICAgICAgIkNhbiBub3QgY3JlYXRlIGl0ZW0gaW4gcmVzdWx0IHRyZWU6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfWE1MU1BBQ0VfSUxMRUdBTF9WQUxVRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFID0gNTc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTFVFXVsxXSA9Ci0gICAgICAieG1sOnNwYWNlIGluIHRoZSBzb3VyY2UgWE1MIGhhcyBhbiBpbGxlZ2FsIHZhbHVlOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX05PX1hTTEtFWV9ERUNMQVJBVElPTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19YU0xLRVlfREVDTEFSQVRJT04gPSA1ODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1hTTEtFWV9ERUNMQVJBVElPTl1bMV0gPQotICAgICAgIlRoZXJlIGlzIG5vIHhzbDprZXkgZGVjbGFyYXRpb24gZm9yIHswfSEiOwotICB9Ci0KLSAgLyoqIEVSX0NBTlRfQ1JFQVRFX1VSTCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX0NSRUFURV9VUkwgPSA1OTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTlRfQ1JFQVRFX1VSTF1bMV0gPSAiRXJyb3IhIENhbm5vdCBjcmVhdGUgdXJsIGZvcjogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWFNMRlVOQ1RJT05TX1VOU1VQUE9SVEVEID0gNjA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9YU0xGVU5DVElPTlNfVU5TVVBQT1JURURdWzFdID0gInhzbDpmdW5jdGlvbnMgaXMgdW5zdXBwb3J0ZWQiOwotICB9Ci0KLSAgLyoqIEVSX1BST0NFU1NPUl9FUlJPUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QUk9DRVNTT1JfRVJST1IgPSA2MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST0NFU1NPUl9FUlJPUl1bMV0gPSAiWFNMVCBUcmFuc2Zvcm1lckZhY3RvcnkgRXJyb3IiOwotICB9Ci0KLSAgLyoqIEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PVF9BTExPV0VEX0lOU0lERV9TVFlMRVNIRUVUID0gNjI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT1RfQUxMT1dFRF9JTlNJREVfU1RZTEVTSEVFVF1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IG5vdCBhbGxvd2VkIGluc2lkZSBhIHN0eWxlc2hlZXQhIjsKLSAgfQotCi0gIC8qKiBFUl9SRVNVTFROU19OT1RfU1VQUE9SVEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1JFU1VMVE5TX05PVF9TVVBQT1JURUQgPSA2MzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1JFU1VMVE5TX05PVF9TVVBQT1JURURdWzFdID0KLSAgICAgICJyZXN1bHQtbnMgbm8gbG9uZ2VyIHN1cHBvcnRlZCEgIFVzZSB4c2w6b3V0cHV0IGluc3RlYWQuIjsKLSAgfQotCi0gIC8qKiBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9ERUZBVUxUU1BBQ0VfTk9UX1NVUFBPUlRFRCA9IDY0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfREVGQVVMVFNQQUNFX05PVF9TVVBQT1JURURdWzFdID0KLSAgICAgICJkZWZhdWx0LXNwYWNlIG5vIGxvbmdlciBzdXBwb3J0ZWQhICBVc2UgeHNsOnN0cmlwLXNwYWNlIG9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSBpbnN0ZWFkLiI7Ci0gIH0KLQotICAvKiogRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSU5ERU5UUkVTVUxUX05PVF9TVVBQT1JURUQgPSA2NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lOREVOVFJFU1VMVF9OT1RfU1VQUE9SVEVEXVsxXSA9Ci0gICAgICAiaW5kZW50LXJlc3VsdCBubyBsb25nZXIgc3VwcG9ydGVkISAgVXNlIHhzbDpvdXRwdXQgaW5zdGVhZC4iOwotICB9Ci0KLSAgLyoqIEVSX0lMTEVHQUxfQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lMTEVHQUxfQVRUUklCID0gNjY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTExFR0FMX0FUVFJJQl1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGhhcyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZTogezF9IjsKLSAgfQotCi0gIC8qKiBFUl9VTktOT1dOX1hTTF9FTEVNICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1VOS05PV05fWFNMX0VMRU0gPSA2NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOS05PV05fWFNMX0VMRU1dWzFdID0gIlVua25vd24gWFNMIGVsZW1lbnQ6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfQkFEX1hTTFNPUlRfVVNFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0JBRF9YU0xTT1JUX1VTRSA9IDY4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQkFEX1hTTFNPUlRfVVNFXVsxXSA9Ci0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6c29ydCBjYW4gb25seSBiZSB1c2VkIHdpdGggeHNsOmFwcGx5LXRlbXBsYXRlcyBvciB4c2w6Zm9yLWVhY2guIjsKLSAgfQotCi0gIC8qKiBFUl9NSVNQTEFDRURfWFNMV0hFTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9NSVNQTEFDRURfWFNMV0hFTiA9IDY5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTUlTUExBQ0VEX1hTTFdIRU5dWzFdID0KLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIG1pc3BsYWNlZCB4c2w6d2hlbiEiOwotICB9Ci0KLSAgLyoqIEVSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9YU0xXSEVOX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPSA3MDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1hTTFdIRU5fTk9UX1BBUkVOVEVEX0JZX1hTTENIT09TRV1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgeHNsOndoZW4gbm90IHBhcmVudGVkIGJ5IHhzbDpjaG9vc2UhIjsKLSAgfQotCi0gIC8qKiBFUl9NSVNQTEFDRURfWFNMT1RIRVJXSVNFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX01JU1BMQUNFRF9YU0xPVEhFUldJU0UgPSA3MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX01JU1BMQUNFRF9YU0xPVEhFUldJU0VdWzFdID0KLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIG1pc3BsYWNlZCB4c2w6b3RoZXJ3aXNlISI7Ci0gIH0KLQotICAvKiogRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWFNMT1RIRVJXSVNFX05PVF9QQVJFTlRFRF9CWV9YU0xDSE9PU0UgPSA3MjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1hTTE9USEVSV0lTRV9OT1RfUEFSRU5URURfQllfWFNMQ0hPT1NFXVsxXSA9Ci0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB4c2w6b3RoZXJ3aXNlIG5vdCBwYXJlbnRlZCBieSB4c2w6Y2hvb3NlISI7Ci0gIH0KLQotICAvKiogRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PVF9BTExPV0VEX0lOU0lERV9URU1QTEFURSA9IDczOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9UX0FMTE9XRURfSU5TSURFX1RFTVBMQVRFXVsxXSA9Ci0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSB7MH0gaXMgbm90IGFsbG93ZWQgaW5zaWRlIGEgdGVtcGxhdGUhIjsKLSAgfQotCi0gIC8qKiBFUl9VTktOT1dOX0VYVF9OU19QUkVGSVggICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfVU5LTk9XTl9FWFRfTlNfUFJFRklYID0gNzQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9VTktOT1dOX0VYVF9OU19QUkVGSVhdWzFdID0KLSAgICAgICIoU3R5bGVzaGVldEhhbmRsZXIpIHswfSBleHRlbnNpb24gbmFtZXNwYWNlIHByZWZpeCB7MX0gdW5rbm93biI7Ci0gIH0KLQotICAvKiogRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lNUE9SVFNfQVNfRklSU1RfRUxFTSA9IDc1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSU1QT1JUU19BU19GSVJTVF9FTEVNXVsxXSA9Ci0gICAgICAiKFN0eWxlc2hlZXRIYW5kbGVyKSBJbXBvcnRzIGNhbiBvbmx5IG9jY3VyIGFzIHRoZSBmaXJzdCBlbGVtZW50cyBpbiB0aGUgc3R5bGVzaGVldCEiOwotICB9Ci0KLSAgLyoqIEVSX0lNUE9SVElOR19JVFNFTEYgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSU1QT1JUSU5HX0lUU0VMRiA9IDc2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSU1QT1JUSU5HX0lUU0VMRl1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgezB9IGlzIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW1wb3J0aW5nIGl0c2VsZiEiOwotICB9Ci0KLSAgLyoqIEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1hNTFNQQUNFX0lMTEVHQUxfVkFMID0gNzc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9YTUxTUEFDRV9JTExFR0FMX1ZBTF1bMV0gPQotICAgICAgIihTdHlsZXNoZWV0SGFuZGxlcikgIiArICJ4bWw6c3BhY2UgaGFzIGFuIGlsbGVnYWwgdmFsdWU6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUFJPQ0VTU1NUWUxFU0hFRVRfTk9UX1NVQ0NFU1NGVUwgPSA3ODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST0NFU1NTVFlMRVNIRUVUX05PVF9TVUNDRVNTRlVMXVsxXSA9Ci0gICAgICAicHJvY2Vzc1N0eWxlc2hlZXQgbm90IHN1Y2Nlc2Z1bGwhIjsKLSAgfQotCi0gIC8qKiBFUl9TQVhfRVhDRVBUSU9OICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NBWF9FWENFUFRJT04gPSA3OTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1NBWF9FWENFUFRJT05dWzFdID0gIlNBWCBFeGNlcHRpb24iOwotICB9Ci0KLSAgLyoqIEVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCA9IDgwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRF1bMV0gPSAiRnVuY3Rpb24gbm90IHN1cHBvcnRlZCEiOwotICB9Ci0KLSAgLyoqIEVSX1hTTFRfRVJST1IgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWFNMVF9FUlJPUiA9IDgxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfWFNMVF9FUlJPUl1bMV0gPSAiWFNMVCBFcnJvciI7Ci0gIH0KLQotICAvKiogRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCA9IDgyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ1VSUkVOQ1lfU0lHTl9JTExFR0FMXVsxXSA9Ci0gICAgICAiY3VycmVuY3kgc2lnbiBpcyBub3QgYWxsb3dlZCBpbiBmb3JtYXQgcGF0dGVybiBzdHJpbmciOwotICB9Ci0KLSAgLyoqIEVSX0RPQ1VNRU5UX0ZVTkNUSU9OX0lOVkFMSURfSU5fU1RZTEVTSEVFVF9ET00gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTSA9IDgzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRE9DVU1FTlRfRlVOQ1RJT05fSU5WQUxJRF9JTl9TVFlMRVNIRUVUX0RPTV1bMV0gPQotICAgICAgIkRvY3VtZW50IGZ1bmN0aW9uIG5vdCBzdXBwb3J0ZWQgaW4gU3R5bGVzaGVldCBET00hIjsKLSAgfQotCi0gIC8qKiBFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOVF9SRVNPTFZFX1BSRUZJWF9PRl9OT05fUFJFRklYX1JFU09MVkVSID0gODQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DQU5UX1JFU09MVkVfUFJFRklYX09GX05PTl9QUkVGSVhfUkVTT0xWRVJdWzFdID0KLSAgICAgICJDYW4ndCByZXNvbHZlIHByZWZpeCBvZiBub24tUHJlZml4IHJlc29sdmVyISI7Ci0gIH0KLQotICAvKiogRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUkVESVJFQ1RfQ09VTEROVF9HRVRfRklMRU5BTUUgPSA4NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1JFRElSRUNUX0NPVUxETlRfR0VUX0ZJTEVOQU1FXVsxXSA9Ci0gICAgICAiUmVkaXJlY3QgZXh0ZW5zaW9uOiBDb3VsZCBub3QgZ2V0IGZpbGVuYW1lIC0gZmlsZSBvciBzZWxlY3QgYXR0cmlidXRlIG11c3QgcmV0dXJuIHZhbGQgc3RyaW5nLiI7Ci0gIH0KLQotICAvKiogRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9CVUlMRF9GT1JNQVRURVJMSVNURU5FUl9JTl9SRURJUkVDVCA9IDg2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX0JVSUxEX0ZPUk1BVFRFUkxJU1RFTkVSX0lOX1JFRElSRUNUXVsxXSA9Ci0gICAgICAiQ2FuIG5vdCBidWlsZCBGb3JtYXR0ZXJMaXN0ZW5lciBpbiBSZWRpcmVjdCBleHRlbnNpb24hIjsKLSAgfQotCi0gIC8qKiBFUl9JTlZBTElEX1BSRUZJWF9JTl9FWENMVURFUkVTVUxUUFJFRklYICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVggPSA4NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lOVkFMSURfUFJFRklYX0lOX0VYQ0xVREVSRVNVTFRQUkVGSVhdWzFdID0KLSAgICAgICJQcmVmaXggaW4gZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgaXMgbm90IHZhbGlkOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX01JU1NJTkdfTlNfVVJJICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX01JU1NJTkdfTlNfVVJJID0gODg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9NSVNTSU5HX05TX1VSSV1bMV0gPQotICAgICAgIk1pc3NpbmcgbmFtZXNwYWNlIFVSSSBmb3Igc3BlY2lmaWVkIHByZWZpeCI7Ci0gIH0KLQotICAvKiogRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OID0gODk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OXVsxXSA9Ci0gICAgICAiTWlzc2luZyBhcmd1bWVudCBmb3Igb3B0aW9uOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX0lOVkFMSURfT1BUSU9OICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOVkFMSURfT1BUSU9OID0gOTA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlZBTElEX09QVElPTl1bMV0gPSAiSW52YWxpZCBvcHRpb246IHswfSI7Ci0gIH0KLQotICAvKiogRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcgPSA5MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX01BTEZPUk1FRF9GT1JNQVRfU1RSSU5HXVsxXSA9ICJNYWxmb3JtZWQgZm9ybWF0IHN0cmluZzogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUIgPSA5MjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1NUWUxFU0hFRVRfUkVRVUlSRVNfVkVSU0lPTl9BVFRSSUJdWzFdID0KLSAgICAgICJ4c2w6c3R5bGVzaGVldCByZXF1aXJlcyBhICd2ZXJzaW9uJyBhdHRyaWJ1dGUhIjsKLSAgfQotCi0gIC8qKiBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSA9IDkzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUVdWzFdID0KLSAgICAgICJBdHRyaWJ1dGU6IHswfSBoYXMgYW4gaWxsZWdhbCB2YWx1ZTogezF9IjsKLSAgfQotCi0gIC8qKiBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DSE9PU0VfUkVRVUlSRVNfV0hFTiA9IDk0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0hPT1NFX1JFUVVJUkVTX1dIRU5dWzFdID0gInhzbDpjaG9vc2UgcmVxdWlyZXMgYW4geHNsOndoZW4iOwotICB9Ci0KLSAgLyoqIEVSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0ggPSA5NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX0FQUExZX0lNUE9SVF9JTl9GT1JfRUFDSF1bMV0gPQotICAgICAgInhzbDphcHBseS1pbXBvcnRzIG5vdCBhbGxvd2VkIGluIGEgeHNsOmZvci1lYWNoIjsKLSAgfQotCi0gIC8qKiBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX1VTRV9EVE1fRk9SX09VVFBVVCA9IDk2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOVF9VU0VfRFRNX0ZPUl9PVVRQVVRdWzFdID0KLSAgICAgICJDYW5ub3QgdXNlIGEgRFRNTGlhaXNvbiBmb3IgYW4gb3V0cHV0IERPTSBub2RlLi4uIHBhc3MgYSBvcmcuYXBhY2hlLnhwYXRoLkRPTTJIZWxwZXIgaW5zdGVhZCEiOwotICB9Ci0KLSAgLyoqIEVSX0NBTlRfVVNFX0RUTV9GT1JfSU5QVVQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVCA9IDk3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOVF9VU0VfRFRNX0ZPUl9JTlBVVF1bMV0gPQotICAgICAgIkNhbm5vdCB1c2UgYSBEVE1MaWFpc29uIGZvciBhIGlucHV0IERPTSBub2RlLi4uIHBhc3MgYSBvcmcuYXBhY2hlLnhwYXRoLkRPTTJIZWxwZXIgaW5zdGVhZCEiOwotICB9Ci0KLSAgLyoqIEVSX0NBTExfVE9fRVhUX0ZBSUxFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQUxMX1RPX0VYVF9GQUlMRUQgPSA5ODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTExfVE9fRVhUX0ZBSUxFRF1bMV0gPQotICAgICAgIkNhbGwgdG8gZXh0ZW5zaW9uIGVsZW1lbnQgZmFpbGVkOiB7MH0iOwotICB9Ci0KLSAgLyoqIEVSX1BSRUZJWF9NVVNUX1JFU09MVkUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUFJFRklYX01VU1RfUkVTT0xWRSA9IDk5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUFJFRklYX01VU1RfUkVTT0xWRV1bMV0gPQotICAgICAgIlByZWZpeCBtdXN0IHJlc29sdmUgdG8gYSBuYW1lc3BhY2U6IHswfSI7Ci0gIH0KLQotICAvKiogRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSAxMDA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURV1bMV0gPQotICAgICAgIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogezB9ID8iOwotICB9Ci0KLSAgLyoqIEVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWFNMQVRUUlNFVF9VU0VEX0lUU0VMRiA9IDEwMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEZdWzFdID0KLSAgICAgICJ4c2w6YXR0cmlidXRlLXNldCB7MH0gdXNlZCBpdHNlbGYsIHdoaWNoIHdpbGwgY2F1c2UgYW4gaW5maW5pdGUgbG9vcC4iOwotICB9Ci0KLSAgLyoqIEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9NSVhfWEVSQ0VTRE9NID0gMTAyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX01JWF9YRVJDRVNET01dWzFdID0KLSAgICAgICJDYW4gbm90IG1peCBub24gWGVyY2VzLURPTSBpbnB1dCB3aXRoIFhlcmNlcy1ET00gb3V0cHV0ISI7Ci0gIH0KLQotICAvKiogRVJfVE9PX01BTllfTElTVEVORVJTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1RPT19NQU5ZX0xJU1RFTkVSUyA9IDEwMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1RPT19NQU5ZX0xJU1RFTkVSU11bMV0gPQotICAgICAgImFkZFRyYWNlTGlzdGVuZXJzVG9TdHlsZXNoZWV0IC0gVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbiI7Ci0gIH0KLQotICAvKiogRVJfSU5fRUxFTVRFTVBMQVRFRUxFTV9SRUFET0JKRUNUICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVCA9IDEwNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lOX0VMRU1URU1QTEFURUVMRU1fUkVBRE9CSkVDVF1bMV0gPQotICAgICAgIkluIEVsZW1UZW1wbGF0ZUVsZW1lbnQucmVhZE9iamVjdDogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFID0gMTA1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRFVQTElDQVRFX05BTUVEX1RFTVBMQVRFXVsxXSA9Ci0gICAgICAiRm91bmQgbW9yZSB0aGFuIG9uZSB0ZW1wbGF0ZSBuYW1lZDogezB9IjsKLSAgfQotCi0gIC8qKiBFUl9JTlZBTElEX0tFWV9DQUxMICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOVkFMSURfS0VZX0NBTEwgPSAxMDY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlZBTElEX0tFWV9DQUxMXVsxXSA9Ci0gICAgICAiSW52YWxpZCBmdW5jdGlvbiBjYWxsOiByZWN1cnNpdmUga2V5KCkgY2FsbHMgYXJlIG5vdCBhbGxvd2VkIjsKLSAgfQotICAKLSAgLyoqIFZhcmlhYmxlIGlzIHJlZmVyZW5jaW5nIGl0c2VsZiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9SRUZFUkVOQ0lOR19JVFNFTEYgPSAxMDc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9SRUZFUkVOQ0lOR19JVFNFTEZdWzFdID0KLSAgICAgICJWYXJpYWJsZSB7MH0gaXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSByZWZlcmVuY2luZyBpdHNlbGYhIjsKLSAgfQotICAKLSAgLyoqIElsbGVnYWwgRE9NU291cmNlIGlucHV0ICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lMTEVHQUxfRE9NU09VUkNFX0lOUFVUID0gMTA4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSUxMRUdBTF9ET01TT1VSQ0VfSU5QVVRdWzFdID0KLSAgICAgICJUaGUgaW5wdXQgbm9kZSBjYW4gbm90IGJlIG51bGwgZm9yIGEgRE9NU291cmNlIGZvciBuZXdUZW1wbGF0ZXMhIjsKLSAgfQotCQotCS8qKiBDbGFzcyBub3QgZm91bmQgZm9yIG9wdGlvbiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OID0gMTA5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT05dWzFdID0KLQkJCSJDbGFzcyBmaWxlIG5vdCBmb3VuZCBmb3Igb3B0aW9uIHswfSI7Ci0gIH0KLQkKLQkvKiogUmVxdWlyZWQgRWxlbWVudCBub3QgZm91bmQgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9SRVFVSVJFRF9FTEVNX05PVF9GT1VORCA9IDExMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1JFUVVJUkVEX0VMRU1fTk9UX0ZPVU5EXVsxXSA9Ci0JCQkiUmVxdWlyZWQgRWxlbWVudCBub3QgZm91bmQ6IHswfSI7Ci0gIH0KLSAgCi0gIC8qKiBJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOUFVUX0NBTk5PVF9CRV9OVUxMID0gMTExOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSU5QVVRfQ0FOTk9UX0JFX05VTExdWzFdID0KLQkJCSJJbnB1dFN0cmVhbSBjYW5ub3QgYmUgbnVsbCI7Ci0gIH0KLSAgCi0gIC8qKiBVUkkgY2Fubm90IGJlIG51bGwgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9VUklfQ0FOTk9UX0JFX05VTEwgPSAxMTI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9VUklfQ0FOTk9UX0JFX05VTExdWzFdID0KLQkJCSJVUkkgY2Fubm90IGJlIG51bGwiOwotICB9Ci0gIAotICAvKiogRmlsZSBjYW5ub3QgYmUgbnVsbCAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0ZJTEVfQ0FOTk9UX0JFX05VTEwgPSAxMTM7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9GSUxFX0NBTk5PVF9CRV9OVUxMXVsxXSA9Ci0JCQkiRmlsZSBjYW5ub3QgYmUgbnVsbCI7Ci0gIH0KLSAgCi0gICAvKiogSW5wdXRTb3VyY2UgY2Fubm90IGJlIG51bGwgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTEwgPSAxMTQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TT1VSQ0VfQ0FOTk9UX0JFX05VTExdWzFdID0KLQkJCSJJbnB1dFNvdXJjZSBjYW5ub3QgYmUgbnVsbCI7Ci0gIH0KLSAgCi0gIC8qKiBDYW4ndCBvdmVyd3JpdGUgY2F1c2UgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5OT1RfT1ZFUldSSVRFX0NBVVNFID0gMTE1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRV1bMV0gPQotCQkJIkNhbm5vdCBvdmVyd3JpdGUgY2F1c2UiOwotICB9Ci0gIAotICAvKiogQ291bGQgbm90IGluaXRpYWxpemUgQlNGIE1hbmFnZXIgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9JTklUX0JTRk1HUiA9IDExNjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTk5PVF9JTklUX0JTRk1HUl1bMV0gPQotCQkJIkNvdWxkIG5vdCBpbml0aWFsaXplIEJTRiBNYW5hZ2VyIjsKLSAgfQotICAKLSAgLyoqIENvdWxkIG5vdCBjb21waWxlIGV4dGVuc2lvbiAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5OT1RfQ01QTF9FWFRFTlNOID0gMTE3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX0NNUExfRVhURU5TTl1bMV0gPQotCQkJIkNvdWxkIG5vdCBjb21waWxlIGV4dGVuc2lvbiI7Ci0gIH0KLSAgCi0gIC8qKiBDb3VsZCBub3QgY3JlYXRlIGV4dGVuc2lvbiAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU04gPSAxMTg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DQU5OT1RfQ1JFQVRFX0VYVEVOU05dWzFdID0KLSAgICAgICJDb3VsZCBub3QgY3JlYXRlIGV4dGVuc2lvbjogezB9IGJlY2F1c2Ugb2Y6IHsxfSI7Ci0gIH0KLSAgCi0gIC8qKiBJbnN0YW5jZSBtZXRob2QgY2FsbCB0byBtZXRob2QgezB9IHJlcXVpcmVzIGFuIE9iamVjdCBpbnN0YW5jZSBhcyBmaXJzdCBhcmd1bWVudCAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVMgPSAxMTk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlNUQU5DRV9NVEhEX0NBTExfUkVRVUlSRVNdWzFdID0KLSAgICAgICJJbnN0YW5jZSBtZXRob2QgY2FsbCB0byBtZXRob2QgezB9IHJlcXVpcmVzIGFuIE9iamVjdCBpbnN0YW5jZSBhcyBmaXJzdCBhcmd1bWVudCI7Ci0gIH0KLSAgCi0gIC8qKiBJbnZhbGlkIGVsZW1lbnQgbmFtZSBzcGVjaWZpZWQgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSU5WQUxJRF9FTEVNRU5UX05BTUUgPSAxMjA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlZBTElEX0VMRU1FTlRfTkFNRV1bMV0gPQotICAgICAgIkludmFsaWQgZWxlbWVudCBuYW1lIHNwZWNpZmllZCB7MH0iOwotICB9Ci0gIAotICAgLyoqIEVsZW1lbnQgbmFtZSBtZXRob2QgbXVzdCBiZSBzdGF0aWMgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9FTEVNRU5UX05BTUVfTUVUSE9EX1NUQVRJQyA9IDEyMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0VMRU1FTlRfTkFNRV9NRVRIT0RfU1RBVElDXVsxXSA9Ci0gICAgICAiRWxlbWVudCBuYW1lIG1ldGhvZCBtdXN0IGJlIHN0YXRpYyB7MH0iOwotICB9Ci0gIAotICAgLyoqIEV4dGVuc2lvbiBmdW5jdGlvbiB7MH0gOiB7MX0gaXMgdW5rbm93biAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0VYVEVOU0lPTl9GVU5DX1VOS05PV04gPSAxMjI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FWFRFTlNJT05fRlVOQ19VTktOT1dOXVsxXSA9Ci0gICAgICAgICAgICAgIkV4dGVuc2lvbiBmdW5jdGlvbiB7MH0gOiB7MX0gaXMgdW5rbm93biI7Ci0gIH0KLSAgCi0gICAvKiogTW9yZSB0aGFuIG9uZSBiZXN0IG1hdGNoIGZvciBjb25zdHJ1Y3RvciBmb3IgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTU9SRV9NQVRDSF9DT05TVFJVQ1RPUiA9IDEyMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX01PUkVfTUFUQ0hfQ09OU1RSVUNUT1JdWzFdID0KLSAgICAgICAgICAgICAiTW9yZSB0aGFuIG9uZSBiZXN0IG1hdGNoIGZvciBjb25zdHJ1Y3RvciBmb3IgezB9IjsKLSAgfQotICAKLSAgIC8qKiBNb3JlIHRoYW4gb25lIGJlc3QgbWF0Y2ggZm9yIG1ldGhvZCAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX01PUkVfTUFUQ0hfTUVUSE9EID0gMTI0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTU9SRV9NQVRDSF9NRVRIT0RdWzFdID0KLSAgICAgICAgICAgICAiTW9yZSB0aGFuIG9uZSBiZXN0IG1hdGNoIGZvciBtZXRob2QgezB9IjsKLSAgfQotICAKLSAgIC8qKiBNb3JlIHRoYW4gb25lIGJlc3QgbWF0Y2ggZm9yIGVsZW1lbnQgbWV0aG9kICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTU9SRV9NQVRDSF9FTEVNRU5UID0gMTI1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTU9SRV9NQVRDSF9FTEVNRU5UXVsxXSA9Ci0gICAgICAgICAgICAgIk1vcmUgdGhhbiBvbmUgYmVzdCBtYXRjaCBmb3IgZWxlbWVudCBtZXRob2QgezB9IjsKLSAgfQotICAKLSAgIC8qKiBJbnZhbGlkIGNvbnRleHQgcGFzc2VkIHRvIGV2YWx1YXRlICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOVkFMSURfQ09OVEVYVF9QQVNTRUQgPSAxMjY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlZBTElEX0NPTlRFWFRfUEFTU0VEXVsxXSA9Ci0gICAgICAgICAgICAgIkludmFsaWQgY29udGV4dCBwYXNzZWQgdG8gZXZhbHVhdGUgezB9IjsKLSAgfQotICAKLSAgIC8qKiBQb29sIGFscmVhZHkgZXhpc3RzICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BPT0xfRVhJU1RTID0gMTI3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUE9PTF9FWElTVFNdWzFdID0KLSAgICAgICAgICAgICAiUG9vbCBhbHJlYWR5IGV4aXN0cyI7Ci0gIH0KLSAgCi0gICAvKiogTm8gZHJpdmVyIE5hbWUgc3BlY2lmaWVkICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fRFJJVkVSX05BTUUgPSAxMjg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT19EUklWRVJfTkFNRV1bMV0gPQotICAgICAgICAgICAgICJObyBkcml2ZXIgTmFtZSBzcGVjaWZpZWQiOwotICB9Ci0gIAotICAgLyoqIE5vIFVSTCBzcGVjaWZpZWQgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX1VSTCA9IDEyOTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1VSTF1bMV0gPQotICAgICAgICAgICAgICJObyBVUkwgc3BlY2lmaWVkIjsKLSAgfQotICAKLSAgIC8qKiBQb29sIHNpemUgaXMgbGVzcyB0aGFuIG9uZSAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QT09MX1NJWkVfTEVTU1RIQU5fT05FID0gMTMwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUE9PTF9TSVpFX0xFU1NUSEFOX09ORV1bMV0gPQotICAgICAgICAgICAgICJQb29sIHNpemUgaXMgbGVzcyB0aGFuIG9uZSEiOwotICB9Ci0gIAotICAgLyoqIEludmFsaWQgZHJpdmVyIG5hbWUgc3BlY2lmaWVkICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lOVkFMSURfRFJJVkVSID0gMTMxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSU5WQUxJRF9EUklWRVJdWzFdID0KLSAgICAgICAgICAgICAiSW52YWxpZCBkcml2ZXIgbmFtZSBzcGVjaWZpZWQhIjsKLSAgfQotICAKLSAgIC8qKiBEaWQgbm90IGZpbmQgdGhlIHN0eWxlc2hlZXQgcm9vdCAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19TVFlMRVNIRUVUUk9PVCA9IDEzMjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1NUWUxFU0hFRVRST09UXVsxXSA9Ci0gICAgICAgICAgICAgIkRpZCBub3QgZmluZCB0aGUgc3R5bGVzaGVldCByb290ISI7Ci0gIH0KLSAgCi0gICAvKiogSWxsZWdhbCB2YWx1ZSBmb3IgeG1sOnNwYWNlICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTExFR0FMX1hNTFNQQUNFX1ZBTFVFID0gMTMzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSUxMRUdBTF9YTUxTUEFDRV9WQUxVRV1bMV0gPQotICAgICAgICAgIklsbGVnYWwgdmFsdWUgZm9yIHhtbDpzcGFjZSI7Ci0gIH0KLSAgCi0gICAvKiogcHJvY2Vzc0Zyb21Ob2RlIGZhaWxlZCAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUFJPQ0VTU0ZST01OT0RFX0ZBSUxFRCA9IDEzNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST0NFU1NGUk9NTk9ERV9GQUlMRURdWzFdID0KLSAgICAgICAgICJwcm9jZXNzRnJvbU5vZGUgZmFpbGVkIjsKLSAgfQotICAKLSAgIC8qKiBUaGUgcmVzb3VyY2UgW10gY291bGQgbm90IGxvYWQ6ICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCA9IDEzNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1JFU09VUkNFX0NPVUxEX05PVF9MT0FEXVsxXSA9Ci0gICAgICAgICJUaGUgcmVzb3VyY2UgWyB7MH0gXSBjb3VsZCBub3QgbG9hZDogezF9IFxuIHsyfSBcdCB7M30iOwotICB9Ci0gICAKLSAgCi0gICAvKiogQnVmZmVyIHNpemUgPD0wICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPID0gMTM2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQlVGRkVSX1NJWkVfTEVTU1RIQU5fWkVST11bMV0gPQotICAgICAgICAiQnVmZmVyIHNpemUgPD0wIjsKLSAgfQotICAKLSAgIC8qKiBVbmtub3duIGVycm9yIHdoZW4gY2FsbGluZyBleHRlbnNpb24gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfVU5LTk9XTl9FUlJPUl9DQUxMSU5HX0VYVEVOU0lPTiA9IDEzNzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT05dWzFdID0KLSAgICAgICAgIlVua25vd24gZXJyb3Igd2hlbiBjYWxsaW5nIGV4dGVuc2lvbiI7Ci0gIH0KLSAgCi0gICAvKiogUHJlZml4IHswfSBkb2VzIG5vdCBoYXZlIGEgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fTkFNRVNQQUNFX0RFQ0wgPSAxMzg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT19OQU1FU1BBQ0VfREVDTF1bMV0gPQotICAgICAgICAiUHJlZml4IHswfSBkb2VzIG5vdCBoYXZlIGEgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24iOwotICB9Ci0gIAotICAgLyoqIEVsZW1lbnQgY29udGVudCBub3QgYWxsb3dlZCBmb3IgbGFuZz1qYXZhY2xhc3MgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQgPSAxMzk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRURdWzFdID0KLSAgICAgICAgIkVsZW1lbnQgY29udGVudCBub3QgYWxsb3dlZCBmb3IgbGFuZz1qYXZhY2xhc3MgezB9IjsKLSAgfSAgIAotICAKLSAgIC8qKiBTdHlsZXNoZWV0IGRpcmVjdGVkIHRlcm1pbmF0aW9uICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU1RZTEVTSEVFVF9ESVJFQ1RFRF9URVJNSU5BVElPTiA9IDE0MDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT05dWzFdID0KLSAgICAgICAgIlN0eWxlc2hlZXQgZGlyZWN0ZWQgdGVybWluYXRpb24iOwotICB9Ci0gIAotICAgLyoqIDEgb3IgMiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX09ORV9PUl9UV08gPSAxNDE7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9PTkVfT1JfVFdPXVsxXSA9Ci0gICAgICAgICIxIG9yIDIiOwotICB9Ci0gIAotICAgLyoqIDIgb3IgMyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1RXT19PUl9USFJFRSA9IDE0MjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1RXT19PUl9USFJFRV1bMV0gPQotICAgICAgICAiMiBvciAzIjsKLSAgfQotICAKLSAgIC8qKiBDb3VsZCBub3QgbG9hZCB7MH0gKGNoZWNrIENMQVNTUEFUSCksIG5vdyB1c2luZyBqdXN0IHRoZSBkZWZhdWx0cyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFID0gMTQzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ09VTERfTk9UX0xPQURfUkVTT1VSQ0VdWzFdID0KLSAgICAgICAgIkNvdWxkIG5vdCBsb2FkIHswfSAoY2hlY2sgQ0xBU1NQQVRIKSwgbm93IHVzaW5nIGp1c3QgdGhlIGRlZmF1bHRzIjsKLSAgfQotICAKLSAgIC8qKiBDYW5ub3QgaW5pdGlhbGl6ZSBkZWZhdWx0IHRlbXBsYXRlcyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9JTklUX0RFRkFVTFRfVEVNUExBVEVTID0gMTQ0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX0lOSVRfREVGQVVMVF9URU1QTEFURVNdWzFdID0KLSAgICAgICAgIkNhbm5vdCBpbml0aWFsaXplIGRlZmF1bHQgdGVtcGxhdGVzIjsKLSAgfQotICAKLSAgIC8qKiBSZXN1bHQgc2hvdWxkIG5vdCBiZSBudWxsICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUkVTVUxUX05VTEwgPSAxNDU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9SRVNVTFRfTlVMTF1bMV0gPQotICAgICAgICAiUmVzdWx0IHNob3VsZCBub3QgYmUgbnVsbCI7Ci0gIH0KLSAgICAKLSAgIC8qKiBSZXN1bHQgY291bGQgbm90IGJlIHNldCAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VUID0gMTQ2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUkVTVUxUX0NPVUxEX05PVF9CRV9TRVRdWzFdID0KLSAgICAgICAgIlJlc3VsdCBjb3VsZCBub3QgYmUgc2V0IjsKLSAgfQotICAKLSAgIC8qKiBObyBvdXRwdXQgc3BlY2lmaWVkICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fT1VUUFVUX1NQRUNJRklFRCA9IDE0NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX09VVFBVVF9TUEVDSUZJRURdWzFdID0KLSAgICAgICAgIk5vIG91dHB1dCBzcGVjaWZpZWQiOwotICB9Ci0gIAotICAgLyoqIENhbid0IHRyYW5zZm9ybSB0byBhIFJlc3VsdCBvZiB0eXBlICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOTk9UX1RSQU5TRk9STV9UT19SRVNVTFRfVFlQRSA9IDE0ODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEVdWzFdID0KLSAgICAgICAgIkNhbid0IHRyYW5zZm9ybSB0byBhIFJlc3VsdCBvZiB0eXBlIHswfSI7Ci0gIH0KLSAgCi0gICAvKiogQ2FuJ3QgdHJhbnNmb3JtIHRvIGEgU291cmNlIG9mIHR5cGUgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5OT1RfVFJBTlNGT1JNX1NPVVJDRV9UWVBFID0gMTQ5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX1RSQU5TRk9STV9TT1VSQ0VfVFlQRV1bMV0gPQotICAgICAgICAiQ2FuJ3QgdHJhbnNmb3JtIGEgU291cmNlIG9mIHR5cGUgezB9IjsKLSAgfQotICAKLSAgIC8qKiBOdWxsIGNvbnRlbnQgaGFuZGxlciAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTlVMTF9DT05URU5UX0hBTkRMRVIgPSAxNTA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OVUxMX0NPTlRFTlRfSEFORExFUl1bMV0gPQotICAgICAgICAiTnVsbCBjb250ZW50IGhhbmRsZXIiOwotICB9Ci0gIAotICAgLyoqIE51bGwgZXJyb3IgaGFuZGxlciAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTlVMTF9FUlJPUl9IQU5ETEVSID0gMTUxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTlVMTF9FUlJPUl9IQU5ETEVSXVsxXSA9Ci0gICAgICAgICJOdWxsIGVycm9yIGhhbmRsZXIiOwotICB9Ci0gIAotICAgLyoqIHBhcnNlIGNhbiBub3QgYmUgY2FsbGVkIGlmIHRoZSBDb250ZW50SGFuZGxlciBoYXMgbm90IGJlZW4gc2V0ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9DQUxMX1BBUlNFID0gMTUyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX0NBTExfUEFSU0VdWzFdID0KLSAgICAgICAgInBhcnNlIGNhbiBub3QgYmUgY2FsbGVkIGlmIHRoZSBDb250ZW50SGFuZGxlciBoYXMgbm90IGJlZW4gc2V0IjsKLSAgfQotICAKLSAgIC8qKiAgTm8gcGFyZW50IGZvciBmaWx0ZXIgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fUEFSRU5UX0ZPUl9GSUxURVIgPSAxNTM7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT19QQVJFTlRfRk9SX0ZJTFRFUl1bMV0gPQotICAgICAgICAiTm8gcGFyZW50IGZvciBmaWx0ZXIiOwotICB9Ci0gIAotICAKLSAgIC8qKiAgTm8gc3R5bGVzaGVldCBmb3VuZCBpbjogezB9LCBtZWRpYSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19TVFlMRVNIRUVUX0lOX01FRElBID0gMTU0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fU1RZTEVTSEVFVF9JTl9NRURJQV1bMV0gPQotICAgICAgICAgIk5vIHN0eWxlc2hlZXQgZm91bmQgaW46IHswfSwgbWVkaWE9IHsxfSI7Ci0gIH0KLSAgCi0gICAvKiogIE5vIHhtbC1zdHlsZXNoZWV0IFBJIGZvdW5kIGluICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX1NUWUxFU0hFRVRfUEkgPSAxNTU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT19TVFlMRVNIRUVUX1BJXVsxXSA9Ci0gICAgICAgICAiTm8geG1sLXN0eWxlc2hlZXQgUEkgZm91bmQgaW46IHswfSI7Ci0gIH0KLSAgCi0gICAvKiogIE5vIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm91bmQgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fREVGQVVMVF9JTVBMID0gMTU2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fREVGQVVMVF9JTVBMXVsxXSA9Ci0gICAgICAgICAiTm8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3VuZCAiOwotICB9Ci0gIAotICAgLyoqICBDaHVua2VkSW50QXJyYXkoezB9KSBub3QgY3VycmVudGx5IHN1cHBvcnRlZCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCA9IDE1NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NIVU5LRURJTlRBUlJBWV9OT1RfU1VQUE9SVEVEXVsxXSA9Ci0gICAgICAgIkNodW5rZWRJbnRBcnJheSh7MH0pIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkIjsKLSAgfQotICAKLSAgIC8qKiAgT2Zmc2V0IGJpZ2dlciB0aGFuIHNsb3QgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfT0ZGU0VUX0JJR0dFUl9USEFOX1NMT1QgPSAxNTg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVF1bMV0gPQotICAgICAgICJPZmZzZXQgYmlnZ2VyIHRoYW4gc2xvdCI7Ci0gIH0KLSAgCi0gICAvKiogIENvcm91dGluZSBub3QgYXZhaWxhYmxlLCBpZD0gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09ST1VUSU5FX05PVF9BVkFJTCA9IDE1OTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPUk9VVElORV9OT1RfQVZBSUxdWzFdID0KLSAgICAgICAiQ29yb3V0aW5lIG5vdCBhdmFpbGFibGUsIGlkPXswfSI7Ci0gIH0KLSAgCi0gICAvKiogIENvcm91dGluZU1hbmFnZXIgcmVjaWV2ZWQgY29fZXhpdCgpIHJlcXVlc3QgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09ST1VUSU5FX0NPX0VYSVQgPSAxNjA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DT1JPVVRJTkVfQ09fRVhJVF1bMV0gPQotICAgICAgICJDb3JvdXRpbmVNYW5hZ2VyIHJlY2VpdmVkIGNvX2V4aXQoKSByZXF1ZXN0IjsKLSAgfQotICAKLSAgIC8qKiAgY29fam9pbkNvcm91dGluZVNldCgpIGZhaWxlZCAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DT0pPSU5ST1VUSU5FU0VUX0ZBSUxFRCA9IDE2MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPSk9JTlJPVVRJTkVTRVRfRkFJTEVEXVsxXSA9Ci0gICAgICAgImNvX2pvaW5Db3JvdXRpbmVTZXQoKSBmYWlsZWQiOwotICB9Ci0gIAotICAgLyoqICBDb3JvdXRpbmUgcGFyYW1ldGVyIGVycm9yICgpICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPUk9VVElORV9QQVJBTSA9IDE2MjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPUk9VVElORV9QQVJBTV1bMV0gPQotICAgICAgICJDb3JvdXRpbmUgcGFyYW1ldGVyIGVycm9yICh7MH0pIjsKLSAgfQotICAKLSAgIC8qKiAgVU5FWFBFQ1RFRDogUGFyc2VyIGRvVGVybWluYXRlIGFuc3dlcnMgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTID0gMTYzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUEFSU0VSX0RPVEVSTUlOQVRFX0FOU1dFUlNdWzFdID0KLSAgICAgICAiXG5VTkVYUEVDVEVEOiBQYXJzZXIgZG9UZXJtaW5hdGUgYW5zd2VycyB7MH0iOwotICB9Ci0gIAotICAgLyoqICBwYXJzZSBtYXkgbm90IGJlIGNhbGxlZCB3aGlsZSBwYXJzaW5nICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lORyA9IDE2NDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1BBUlNFX0NBTExfV0hJTEVfUEFSU0lOR11bMV0gPQotICAgICAgICJwYXJzZSBtYXkgbm90IGJlIGNhbGxlZCB3aGlsZSBwYXJzaW5nIjsKLSAgfQotICAKLSAgIC8qKiAgRXJyb3I6IHR5cGVkIGl0ZXJhdG9yIGZvciBheGlzICB7MH0gbm90IGltcGxlbWVudGVkICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9UWVBFRF9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9IDE2NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1RZUEVEX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEXVsxXSA9Ci0gICAgICAgIkVycm9yOiB0eXBlZCBpdGVyYXRvciBmb3IgYXhpcyAgezB9IG5vdCBpbXBsZW1lbnRlZCI7Ci0gIH0KLSAgCi0gICAvKiogIEVycm9yOiBpdGVyYXRvciBmb3IgYXhpcyB7MH0gbm90IGltcGxlbWVudGVkICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JVEVSQVRPUl9BWElTX05PVF9JTVBMRU1FTlRFRCA9IDE2NjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVEXVsxXSA9Ci0gICAgICAgIkVycm9yOiBpdGVyYXRvciBmb3IgYXhpcyB7MH0gbm90IGltcGxlbWVudGVkICI7Ci0gIH0KLSAgCi0gICAvKiogIEl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lURVJBVE9SX0NMT05FX05PVF9TVVBQT1JURUQgPSAxNjc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVEXVsxXSA9Ci0gICAgICAgIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQiOwotICB9Ci0gIAotICAgLyoqICBVbmtub3duIGF4aXMgdHJhdmVyc2FsIHR5cGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1VOS05PV05fQVhJU19UWVBFID0gMTY4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfVU5LTk9XTl9BWElTX1RZUEVdWzFdID0KLSAgICAgICAiVW5rbm93biBheGlzIHRyYXZlcnNhbCB0eXBlOiB7MH0iOwotICB9Ci0gIAotICAgLyoqICBBeGlzIHRyYXZlcnNlciBub3Qgc3VwcG9ydGVkICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9BWElTX05PVF9TVVBQT1JURUQgPSAxNjk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9BWElTX05PVF9TVVBQT1JURURdWzFdID0KLSAgICAgICAiQXhpcyB0cmF2ZXJzZXIgbm90IHN1cHBvcnRlZDogezB9IjsKLSAgfQotICAKLSAgIC8qKiAgTm8gbW9yZSBEVE0gSURzIGFyZSBhdmFpbGFibGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX0RUTUlEU19BVkFJTCA9IDE3MDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX0RUTUlEU19BVkFJTF1bMV0gPQotICAgICAgICJObyBtb3JlIERUTSBJRHMgYXJlIGF2YWlsYWJsZSI7Ci0gIH0KLSAgCi0gICAvKiogIE5vdCBzdXBwb3J0ZWQgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PVF9TVVBQT1JURUQgPSAxNzE7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT1RfU1VQUE9SVEVEXVsxXSA9Ci0gICAgICAgIk5vdCBzdXBwb3J0ZWQ6IHswfSI7Ci0gIH0KLSAgCi0gICAvKiogIG5vZGUgbXVzdCBiZSBub24tbnVsbCBmb3IgZ2V0RFRNSGFuZGxlRnJvbU5vZGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PREVfTk9OX05VTEwgPSAxNzI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT0RFX05PTl9OVUxMXVsxXSA9Ci0gICAgICAgIk5vZGUgbXVzdCBiZSBub24tbnVsbCBmb3IgZ2V0RFRNSGFuZGxlRnJvbU5vZGUiOwotICB9Ci0gIAotICAgLyoqICBDb3VsZCBub3QgcmVzb2x2ZSB0aGUgbm9kZSB0byBhIGhhbmRsZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSA9IDE3MzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPVUxEX05PVF9SRVNPTFZFX05PREVdWzFdID0KLSAgICAgICAiQ291bGQgbm90IHJlc29sdmUgdGhlIG5vZGUgdG8gYSBoYW5kbGUiOwotICB9Ci0gIAotICAgLyoqICBzdGFydFBhcnNlIG1heSBub3QgYmUgY2FsbGVkIHdoaWxlIHBhcnNpbmcgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HID0gMTc0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfU1RBUlRQQVJTRV9XSElMRV9QQVJTSU5HXVsxXSA9Ci0gICAgICAgInN0YXJ0UGFyc2UgbWF5IG5vdCBiZSBjYWxsZWQgd2hpbGUgcGFyc2luZyI7Ci0gIH0KLSAgCi0gICAvKiogIHN0YXJ0UGFyc2UgbmVlZHMgYSBub24tbnVsbCBTQVhQYXJzZXIgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NUQVJUUEFSU0VfTkVFRFNfU0FYUEFSU0VSID0gMTc1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfU1RBUlRQQVJTRV9ORUVEU19TQVhQQVJTRVJdWzFdID0KLSAgICAgICAic3RhcnRQYXJzZSBuZWVkcyBhIG5vbi1udWxsIFNBWFBhcnNlciI7Ci0gIH0KLSAgCi0gICAvKiogIGNvdWxkIG5vdCBpbml0aWFsaXplIHBhcnNlciB3aXRoICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVUxEX05PVF9JTklUX1BBUlNFUiA9IDE3NjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPVUxEX05PVF9JTklUX1BBUlNFUl1bMV0gPQotICAgICAgICJjb3VsZCBub3QgaW5pdGlhbGl6ZSBwYXJzZXIgd2l0aCI7Ci0gIH0KLSAgCi0gICAvKiogIFZhbHVlIGZvciBwcm9wZXJ0eSB7MH0gc2hvdWxkIGJlIGEgQm9vbGVhbiBpbnN0YW5jZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiA9IDE3NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU5dWzFdID0KLSAgICAgICAiVmFsdWUgZm9yIHByb3BlcnR5IHswfSBzaG91bGQgYmUgYSBCb29sZWFuIGluc3RhbmNlIjsKLSAgfQotICAKLSAgIC8qKiAgZXhjZXB0aW9uIGNyZWF0aW5nIG5ldyBpbnN0YW5jZSBmb3IgcG9vbCAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRVhDRVBUSU9OX0NSRUFUSU5HX1BPT0wgPSAxNzg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTF1bMV0gPQotICAgICAgICJleGNlcHRpb24gY3JlYXRpbmcgbmV3IGluc3RhbmNlIGZvciBwb29sIjsKLSAgfQotICAKLSAgIC8qKiAgUGF0aCBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSA9IDE3OTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BBVEhfQ09OVEFJTlNfSU5WQUxJRF9FU0NBUEVfU0VRVUVOQ0VdWzFdID0KLSAgICAgICAiUGF0aCBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSI7Ci0gIH0KLSAgCi0gICAvKiogIFNjaGVtZSBpcyByZXF1aXJlZCEgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NDSEVNRV9SRVFVSVJFRCA9IDE4MDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1NDSEVNRV9SRVFVSVJFRF1bMV0gPQotICAgICAgICJTY2hlbWUgaXMgcmVxdWlyZWQhIjsKLSAgfQotICAKLSAgIC8qKiAgTm8gc2NoZW1lIGZvdW5kIGluIFVSSSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fU0NIRU1FX0lOX1VSSSA9IDE4MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1NDSEVNRV9JTl9VUkldWzFdID0KLSAgICAgICAiTm8gc2NoZW1lIGZvdW5kIGluIFVSSTogezB9IjsKLSAgfQotICAKLSAgIC8qKiAgTm8gc2NoZW1lIGZvdW5kIGluIFVSSSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9fU0NIRU1FX0lOVVJJID0gMTgyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fU0NIRU1FX0lOVVJJXVsxXSA9Ci0gICAgICAgIk5vIHNjaGVtZSBmb3VuZCBpbiBVUkkiOwotICB9Ci0gIAotICAgLyoqICBQYXRoIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyOiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BBVEhfSU5WQUxJRF9DSEFSID0gMTgzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUEFUSF9JTlZBTElEX0NIQVJdWzFdID0KLSAgICAgICAiUGF0aCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcjogezB9IjsKLSAgfQotICAKLSAgIC8qKiAgQ2Fubm90IHNldCBzY2hlbWUgZnJvbSBudWxsIHN0cmluZyAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcgPSAxODQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TQ0hFTUVfRlJPTV9OVUxMX1NUUklOR11bMV0gPQotICAgICAgICJDYW5ub3Qgc2V0IHNjaGVtZSBmcm9tIG51bGwgc3RyaW5nIjsKLSAgfQotICAKLSAgIC8qKiAgVGhlIHNjaGVtZSBpcyBub3QgY29uZm9ybWFudC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UID0gMTg1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfU0NIRU1FX05PVF9DT05GT1JNQU5UXVsxXSA9Ci0gICAgICAgIlRoZSBzY2hlbWUgaXMgbm90IGNvbmZvcm1hbnQuIjsKLSAgfQotICAKLSAgIC8qKiAgSG9zdCBpcyBub3QgYSB3ZWxsIGZvcm1lZCBhZGRyZXNzICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRUQgPSAxODY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9IT1NUX0FERFJFU1NfTk9UX1dFTExGT1JNRURdWzFdID0KLSAgICAgICAiSG9zdCBpcyBub3QgYSB3ZWxsIGZvcm1lZCBhZGRyZXNzIjsKLSAgfQotICAKLSAgIC8qKiAgUG9ydCBjYW5ub3QgYmUgc2V0IHdoZW4gaG9zdCBpcyBudWxsICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QT1JUX1dIRU5fSE9TVF9OVUxMID0gMTg3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUE9SVF9XSEVOX0hPU1RfTlVMTF1bMV0gPQotICAgICAgICJQb3J0IGNhbm5vdCBiZSBzZXQgd2hlbiBob3N0IGlzIG51bGwiOwotICB9Ci0gIAotICAgLyoqICBJbnZhbGlkIHBvcnQgbnVtYmVyICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTlZBTElEX1BPUlQgPSAxODg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JTlZBTElEX1BPUlRdWzFdID0KLSAgICAgICAiSW52YWxpZCBwb3J0IG51bWJlciI7Ci0gIH0KLSAgCi0gICAvKiogIEZyYWdtZW50IGNhbiBvbmx5IGJlIHNldCBmb3IgYSBnZW5lcmljIFVSSSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRlJBR19GT1JfR0VORVJJQ19VUkkgPSAxODk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9GUkFHX0ZPUl9HRU5FUklDX1VSSV1bMV0gPQotICAgICAgICJGcmFnbWVudCBjYW4gb25seSBiZSBzZXQgZm9yIGEgZ2VuZXJpYyBVUkkiOwotICB9Ci0gIAotICAgLyoqICBGcmFnbWVudCBjYW5ub3QgYmUgc2V0IHdoZW4gcGF0aCBpcyBudWxsICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9GUkFHX1dIRU5fUEFUSF9OVUxMID0gMTkwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRlJBR19XSEVOX1BBVEhfTlVMTF1bMV0gPQotICAgICAgICJGcmFnbWVudCBjYW5ub3QgYmUgc2V0IHdoZW4gcGF0aCBpcyBudWxsIjsKLSAgfQotICAKLSAgIC8qKiAgRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXIgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0ZSQUdfSU5WQUxJRF9DSEFSID0gMTkxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRlJBR19JTlZBTElEX0NIQVJdWzFdID0KLSAgICAgICAiRnJhZ21lbnQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXIiOwotICB9Ci0gIAotIAotICAKLSAgIC8qKiBQYXJzZXIgaXMgYWxyZWFkeSBpbiB1c2UgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BBUlNFUl9JTl9VU0UgPSAxOTI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QQVJTRVJfSU5fVVNFXVsxXSA9Ci0gICAgICAgICJQYXJzZXIgaXMgYWxyZWFkeSBpbiB1c2UiOwotICB9Ci0gIAotICAgLyoqIFBhcnNlciBpcyBhbHJlYWR5IGluIHVzZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HID0gMTkzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX0NIQU5HRV9XSElMRV9QQVJTSU5HXVsxXSA9Ci0gICAgICAgICJDYW5ub3QgY2hhbmdlIHswfSB7MX0gd2hpbGUgcGFyc2luZyI7Ci0gIH0KLSAgCi0gICAvKiogU2VsZi1jYXVzYXRpb24gbm90IHBlcm1pdHRlZCAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU0VMRl9DQVVTQVRJT05fTk9UX1BFUk1JVFRFRCA9IDE5NDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURURdWzFdID0KLSAgICAgICAgIlNlbGYtY2F1c2F0aW9uIG5vdCBwZXJtaXR0ZWQiOwotICB9Ci0gIAotICAgLyoqIHNyYyBhdHRyaWJ1dGUgbm90IHlldCBzdXBwb3J0ZWQgZm9yICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DT1VMRF9OT1RfRklORF9FWFRFUk5fU0NSSVBUID0gMTk1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ09VTERfTk9UX0ZJTkRfRVhURVJOX1NDUklQVF1bMV0gPQotICAgICAgICAgIkNvdWxkIG5vdCBnZXQgdG8gZXh0ZXJuYWwgc2NyaXB0IGF0IHswfSI7Ci0gIH0KLSAgCi0gIC8qKiBUaGUgcmVzb3VyY2UgW10gY291bGQgbm90IGJlIGZvdW5kICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9SRVNPVVJDRV9DT1VMRF9OT1RfRklORCA9IDE5NjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1JFU09VUkNFX0NPVUxEX05PVF9GSU5EXVsxXSA9Ci0gICAgICAgICJUaGUgcmVzb3VyY2UgWyB7MH0gXSBjb3VsZCBub3QgYmUgZm91bmQuXG4gezF9IjsKLSAgfQotICAKLSAgIC8qKiBvdXRwdXQgcHJvcGVydHkgbm90IHJlY29nbml6ZWQ6ICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQgPSAxOTc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRURdWzFdID0KLSAgICAgICAgIk91dHB1dCBwcm9wZXJ0eSBub3QgcmVjb2duaXplZDogezB9IjsKLSAgfQotICAKLSAgIC8qKiBVc2VyaW5mbyBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT19VU0VSSU5GT19JRl9OT19IT1NUID0gMTk4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fVVNFUklORk9fSUZfTk9fSE9TVF1bMV0gPQotICAgICAgICAiVXNlcmluZm8gbWF5IG5vdCBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBub3Qgc3BlY2lmaWVkIjsKLSAgfQotICAKLSAgIC8qKiBQb3J0IG1heSBub3QgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbm90IHNwZWNpZmllZCAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX1BPUlRfSUZfTk9fSE9TVCA9IDE5OTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05PX1BPUlRfSUZfTk9fSE9TVF1bMV0gPQotICAgICAgICAiUG9ydCBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQiOwotICB9Ci0gIAotICAgLyoqIFF1ZXJ5IHN0cmluZyBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIHBhdGggYW5kIHF1ZXJ5IHN0cmluZyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX1FVRVJZX1NUUklOR19JTl9QQVRIID0gMjAwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fUVVFUllfU1RSSU5HX0lOX1BBVEhdWzFdID0KLSAgICAgICAgIlF1ZXJ5IHN0cmluZyBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIHBhdGggYW5kIHF1ZXJ5IHN0cmluZyI7Ci0gIH0KLSAgCi0gICAvKiogRnJhZ21lbnQgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBib3RoIHRoZSBwYXRoIGFuZCBmcmFnbWVudCAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05PX0ZSQUdNRU5UX1NUUklOR19JTl9QQVRIID0gMjAxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9fRlJBR01FTlRfU1RSSU5HX0lOX1BBVEhdWzFdID0KLSAgICAgICAgIkZyYWdtZW50IGNhbm5vdCBiZSBzcGVjaWZpZWQgaW4gYm90aCB0aGUgcGF0aCBhbmQgZnJhZ21lbnQiOwotICB9Ci0gIAotICAgLyoqIENhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMgPSAyMDI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVNdWzFdID0KLSAgICAgICAgIkNhbm5vdCBpbml0aWFsaXplIFVSSSB3aXRoIGVtcHR5IHBhcmFtZXRlcnMiOwotICB9Ci0gIAotICAgLyoqIEZhaWxlZCBjcmVhdGluZyBFbGVtTGl0ZXJhbFJlc3VsdCBpbnN0YW5jZSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVCA9IDIwMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0ZBSUxFRF9DUkVBVElOR19FTEVNTElUUlNMVF1bMV0gPQotICAgICAgICAiRmFpbGVkIGNyZWF0aW5nIEVsZW1MaXRlcmFsUmVzdWx0IGluc3RhbmNlIjsKLSAgfSAgCi0gIAotICAgLyoqIFByaW9yaXR5IHZhbHVlIGRvZXMgbm90IGNvbnRhaW4gYSBwYXJzYWJsZSBudW1iZXIgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QUklPUklUWV9OT1RfUEFSU0FCTEUgPSAyMDQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUklPUklUWV9OT1RfUEFSU0FCTEVdWzFdID0KLSAgICAgICAgIlByaW9yaXR5IHZhbHVlIGRvZXMgbm90IGNvbnRhaW4gYSBwYXJzYWJsZSBudW1iZXIiOwotICB9Ci0gIAotICAgLyoqICBWYWx1ZSBmb3IgezB9IHNob3VsZCBlcXVhbCAneWVzJyBvciAnbm8nICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfVkFMVUVfU0hPVUxEX0VRVUFMID0gMjA1OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfVkFMVUVfU0hPVUxEX0VRVUFMXVsxXSA9Ci0gICAgICAgICIgVmFsdWUgZm9yIHswfSBzaG91bGQgZXF1YWwgeWVzIG9yIG5vIjsKLSAgfQotIAotICAgLyoqICBGYWlsZWQgY2FsbGluZyB7MH0gbWV0aG9kICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EID0gMjA2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRkFJTEVEX0NBTExJTkdfTUVUSE9EXVsxXSA9Ci0gICAgICAgICIgRmFpbGVkIGNhbGxpbmcgezB9IG1ldGhvZCI7Ci0gIH0KLSAgCi0gICAvKiogRmFpbGVkIGNyZWF0aW5nIEVsZW1MaXRlcmFsUmVzdWx0IGluc3RhbmNlICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMID0gMjA3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRkFJTEVEX0NSRUFUSU5HX0VMRU1UTVBMXVsxXSA9Ci0gICAgICAgICJGYWlsZWQgY3JlYXRpbmcgRWxlbVRlbXBsYXRlRWxlbWVudCBpbnN0YW5jZSI7Ci0gIH0KLSAgCi0gICAvKiogIENoYXJhY3RlcnMgYXJlIG5vdCBhbGxvd2VkIGF0IHRoaXMgcG9pbnQgaW4gdGhlIGRvY3VtZW50ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0hBUlNfTk9UX0FMTE9XRUQgPSAyMDg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DSEFSU19OT1RfQUxMT1dFRF1bMV0gPQotICAgICAgICAiQ2hhcmFjdGVycyBhcmUgbm90IGFsbG93ZWQgYXQgdGhpcyBwb2ludCBpbiB0aGUgZG9jdW1lbnQiOwotICB9Ci0gIAotICAvKiogIGF0dHJpYnV0ZSBpcyBub3QgYWxsb3dlZCBvbiB0aGUgZWxlbWVudCAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0FUVFJfTk9UX0FMTE9XRUQgPSAyMDk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9BVFRSX05PVF9BTExPV0VEXVsxXSA9Ci0gICAgICAgICJcInswfVwiIGF0dHJpYnV0ZSBpcyBub3QgYWxsb3dlZCBvbiB0aGUgezF9IGVsZW1lbnQhIjsKLSAgfQotICAKLSAgLyoqICBNZXRob2Qgbm90IHlldCBzdXBwb3J0ZWQgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTUVUSE9EX05PVF9TVVBQT1JURUQgPSAyMTA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9NRVRIT0RfTk9UX1NVUFBPUlRFRF1bMV0gPQotICAgICAgICAiTWV0aG9kIG5vdCB5ZXQgc3VwcG9ydGVkICI7Ci0gIH0KLSAKLSAgLyoqICBCYWQgdmFsdWUgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQkFEX1ZBTFVFID0gMjExOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQkFEX1ZBTFVFXVsxXSA9Ci0gICAgICJ7MH0gYmFkIHZhbHVlIHsxfSAiOwotICB9Ci0gIAotICAvKiogIGF0dHJpYnV0ZSB2YWx1ZSBub3QgZm91bmQgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9BVFRSSUJfVkFMVUVfTk9UX0ZPVU5EID0gMjEyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQVRUUklCX1ZBTFVFX05PVF9GT1VORF1bMV0gPQotICAgICAiezB9IGF0dHJpYnV0ZSB2YWx1ZSBub3QgZm91bmQgIjsKLSAgfQotICAKLSAgLyoqICBhdHRyaWJ1dGUgdmFsdWUgbm90IHJlY29nbml6ZWQgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEID0gMjEzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQVRUUklCX1ZBTFVFX05PVF9SRUNPR05JWkVEXVsxXSA9Ci0gICAgICJ7MH0gYXR0cmlidXRlIHZhbHVlIG5vdCByZWNvZ25pemVkICI7Ci0gIH0KLQotICAvKiogSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIG5vdCBjdXJyZW50bHkgcmVzdGFydGFibGUgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSA9IDIxNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lOQ1JTQVhTUkNGSUxURVJfTk9UX1JFU1RBUlRBQkxFXVsxXSA9Ci0gICAgICJJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgbm90IGN1cnJlbnRseSByZXN0YXJ0YWJsZSI7Ci0gIH0KLSAgCi0gIC8qKiBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgbm90IGN1cnJlbnRseSByZXN0YXJ0YWJsZSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UgPSAyMTU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9YTUxSRFJfTk9UX0JFRk9SRV9TVEFSVFBBUlNFXVsxXSA9Ci0gICAgICJYTUxSZWFkZXIgbm90IGJlZm9yZSBzdGFydFBhcnNlIHJlcXVlc3QiOwotICB9Ci0gIAotICAvKiogQXR0ZW1wdGluZyB0byBnZW5lcmF0ZSBhIG5hbWVzcGFjZSBwcmVmaXggd2l0aCBhIG51bGwgVVJJICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTlVMTF9VUklfTkFNRVNQQUNFID0gMjE2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTlVMTF9VUklfTkFNRVNQQUNFXVsxXSA9Ci0gICAgICJBdHRlbXB0aW5nIHRvIGdlbmVyYXRlIGEgbmFtZXNwYWNlIHByZWZpeCB3aXRoIGEgbnVsbCBVUkkiOwotICB9ICAgIAotICAKLSAgCi0gIC8qCi0gICAgLyoqICBDYW5ub3QgZmluZCBTQVgxIGRyaXZlciBjbGFzcyAgICAqCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9GSU5EX1NBWDFfRFJJVkVSID0gMTkwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX0ZJTkRfU0FYMV9EUklWRVJdWzFdID0KLSAgICAgICJDYW5ub3QgZmluZCBTQVgxIGRyaXZlciBjbGFzcyB7MH0iOwotICB9Ci0gIAotICAgLyoqICBTQVgxIGRyaXZlciBjbGFzcyB7MH0gZm91bmQgYnV0IGNhbm5vdCBiZSBsb2FkZWQgICAgKgotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9TQVgxX0RSSVZFUl9OT1RfTE9BREVEID0gMTkxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfU0FYMV9EUklWRVJfTk9UX0xPQURFRF1bMV0gPQotICAgICAgIlNBWDEgZHJpdmVyIGNsYXNzIHswfSBmb3VuZCBidXQgY2Fubm90IGJlIGxvYWRlZCI7Ci0gIH0KLSAgCi0gICAvKiogIFNBWDEgZHJpdmVyIGNsYXNzIHswfSBmb3VuZCBidXQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCAgICAqCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NBWDFfRFJJVkVSX05PVF9JTlNUQU5USUFURUQgPSAxOTI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TQVgxX0RSSVZFUl9OT1RfSU5TVEFOVElBVEVEXVsxXSA9Ci0gICAgICAiU0FYMSBkcml2ZXIgY2xhc3MgezB9IGxvYWRlZCBidXQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCI7Ci0gIH0KLSAgCi0gICAvKiogIFNBWDEgZHJpdmVyIGNsYXNzIHswfSBkb2VzIG5vdCBpbXBsZW1lbnQgb3JnLnhtbC5zYXguUGFyc2VyICAgICoKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU0FYMV9EUklWRVJfTk9UX0lNUExFTUVOVF9QQVJTRVIgPSAxOTM7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TQVgxX0RSSVZFUl9OT1RfSU1QTEVNRU5UX1BBUlNFUl1bMV0gPQotICAgICAgIlNBWDEgZHJpdmVyIGNsYXNzIHswfSBkb2VzIG5vdCBpbXBsZW1lbnQgb3JnLnhtbC5zYXguUGFyc2VyIjsKLSAgfQotICAKLSAgIC8qKiAgU3lzdGVtIHByb3BlcnR5IG9yZy54bWwuc2F4LnBhcnNlciBub3Qgc3BlY2lmaWVkICAgICoKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUEFSU0VSX1BST1BFUlRZX05PVF9TUEVDSUZJRUQgPSAxOTQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QQVJTRVJfUFJPUEVSVFlfTk9UX1NQRUNJRklFRF1bMV0gPQotICAgICAgIlN5c3RlbSBwcm9wZXJ0eSBvcmcueG1sLnNheC5wYXJzZXIgbm90IHNwZWNpZmllZCI7Ci0gIH0KLSAgCi0gICAvKiogIFBhcnNlciBhcmd1bWVudCBtdXN0IG5vdCBiZSBudWxsICAgICoKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUEFSU0VSX0FSR19DQU5OT1RfQkVfTlVMTCA9IDE5NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BBUlNFUl9BUkdfQ0FOTk9UX0JFX05VTExdWzFdID0KLSAgICAgICJQYXJzZXIgYXJndW1lbnQgbXVzdCBub3QgYmUgbnVsbCI7Ci0gIH0KLSAgCi0gICAvKiogIEZlYXR1cmU6ICAgICoKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRkVBVFVSRSA9IDE5NjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0ZFQVRVUkVdWzFdID0KLSAgICAgICAgIkZlYXR1cmU6IHswfSI7Ci0gIH0KLSAgCi0gICAvKiogIFByb3BlcnR5OiAgICAqCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BST1BFUlRZID0gMTk3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfUFJPUEVSVFldWzFdID0KLSAgICAgICAgIlByb3BlcnR5OiB7MH0iOwotICB9Ci0gIAotICAgLyoqIE51bGwgRW50aXR5IFJlc29sdmVyICAqCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05VTExfRU5USVRZX1JFU09MVkVSID0gMTk4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTlVMTF9FTlRJVFlfUkVTT0xWRVJdWzFdID0KLSAgICAgICAgIk51bGwgZW50aXR5IHJlc29sdmVyIjsKLSAgfQotICAKLSAgIC8qKiBOdWxsIERURCBoYW5kbGVyICAqCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05VTExfRFREX0hBTkRMRVIgPSAxOTk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OVUxMX0RURF9IQU5ETEVSXVsxXSA9Ci0gICAgICAgICJOdWxsIERURCBoYW5kbGVyIjsKLSAgfQotICAKLSAqLyAKLSAgCi0KLSAgLy8gV2FybmluZ3MuLi4KLQotICAvKiogV0dfRk9VTkRfQ1VSTFlCUkFDRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19GT1VORF9DVVJMWUJSQUNFID0gMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0ZPVU5EX0NVUkxZQlJBQ0UgKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIkZvdW5kICd9JyBidXQgbm8gYXR0cmlidXRlIHRlbXBsYXRlIG9wZW4hIjsKLSAgfQotCi0gIC8qKiBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiA9IDI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19DT1VOVF9BVFRSSUJfTUFUQ0hFU19OT19BTkNFU1RPUiArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiV2FybmluZzogY291bnQgYXR0cmlidXRlIGRvZXMgbm90IG1hdGNoIGFuIGFuY2VzdG9yIGluIHhzbDpudW1iZXIhIFRhcmdldCA9IHswfSI7Ci0gIH0KLQotICAvKiogV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgPSAzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfRVhQUl9BVFRSSUJfQ0hBTkdFRF9UT19TRUxFQ1QgKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIk9sZCBzeW50YXg6IFRoZSBuYW1lIG9mIHRoZSAnZXhwcicgYXR0cmlidXRlIGhhcyBiZWVuIGNoYW5nZWQgdG8gJ3NlbGVjdCcuIjsKLSAgfQotCi0gIC8qKiBXR19OT19MT0NBTEVfSU5fRk9STUFUTlVNQkVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX05PX0xPQ0FMRV9JTl9GT1JNQVROVU1CRVIgPSA0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfTk9fTE9DQUxFX0lOX0ZPUk1BVE5VTUJFUiArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiWGFsYW4gZG9lc24ndCB5ZXQgaGFuZGxlIHRoZSBsb2NhbGUgbmFtZSBpbiB0aGUgZm9ybWF0LW51bWJlciBmdW5jdGlvbi4iOwotICB9Ci0KLSAgLyoqIFdHX0xPQ0FMRV9OT1RfRk9VTkQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfTE9DQUxFX05PVF9GT1VORCA9IDU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19MT0NBTEVfTk9UX0ZPVU5EICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJXYXJuaW5nOiBDb3VsZCBub3QgZmluZCBsb2NhbGUgZm9yIHhtbDpsYW5nPXswfSI7Ci0gIH0KLQotICAvKiogV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gPSA2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfQ0FOTk9UX01BS0VfVVJMX0ZST00gKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIkNhbiBub3QgbWFrZSBVUkwgZnJvbTogezB9IjsKLSAgfQotCi0gIC8qKiBXR19DQU5OT1RfTE9BRF9SRVFVRVNURURfRE9DICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MgPSA3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQyArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiQ2FuIG5vdCBsb2FkIHJlcXVlc3RlZCBkb2M6IHswfSI7Ci0gIH0KLQotICAvKiogV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgPSA4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfQ0FOTk9UX0ZJTkRfQ09MTEFUT1IgKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIkNvdWxkIG5vdCBmaW5kIENvbGxhdG9yIGZvciA8c29ydCB4bWw6bGFuZz17MH0iOwotICB9Ci0KLSAgLyoqIFdHX0ZVTkNUSU9OU19TSE9VTERfVVNFX1VSTCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19GVU5DVElPTlNfU0hPVUxEX1VTRV9VUkwgPSA5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfRlVOQ1RJT05TX1NIT1VMRF9VU0VfVVJMICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJPbGQgc3ludGF4OiB0aGUgZnVuY3Rpb25zIGluc3RydWN0aW9uIHNob3VsZCB1c2UgYSB1cmwgb2YgezB9IjsKLSAgfQotCi0gIC8qKiBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjggICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfRU5DT0RJTkdfTk9UX1NVUFBPUlRFRF9VU0lOR19VVEY4ID0gMTA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX1VURjggKyBNQVhfQ09ERV1bMV0gPQotICAgICAgImVuY29kaW5nIG5vdCBzdXBwb3J0ZWQ6IHswfSwgdXNpbmcgVVRGLTgiOwotICB9Ci0KLSAgLyoqIFdHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEgPSAxMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0VOQ09ESU5HX05PVF9TVVBQT1JURURfVVNJTkdfSkFWQSArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiZW5jb2Rpbmcgbm90IHN1cHBvcnRlZDogezB9LCB1c2luZyBKYXZhIHsxfSI7Ci0gIH0KLQotICAvKiogV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX1NQRUNJRklDSVRZX0NPTkZMSUNUUyA9IDEyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfU1BFQ0lGSUNJVFlfQ09ORkxJQ1RTICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJTcGVjaWZpY2l0eSBjb25mbGljdHMgZm91bmQ6IHswfSBMYXN0IGZvdW5kIGluIHN0eWxlc2hlZXQgd2lsbCBiZSB1c2VkLiI7Ci0gIH0KLQotICAvKiogV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX1BBUlNJTkdfQU5EX1BSRVBBUklORyA9IDEzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HICsgTUFYX0NPREVdWzFdID0KLSAgICAgICI9PT09PT09PT0gUGFyc2luZyBhbmQgcHJlcGFyaW5nIHswfSA9PT09PT09PT09IjsKLSAgfQotCi0gIC8qKiBXR19BVFRSX1RFTVBMQVRFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0FUVFJfVEVNUExBVEUgPSAxNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0FUVFJfVEVNUExBVEUgKyBNQVhfQ09ERV1bMV0gPSAiQXR0ciBUZW1wbGF0ZSwgezB9IjsKLSAgfQotCi0gIC8qKiBXR19DT05GTElDVF9CRVRXRUVOX1hTTFNUUklQU1BBQ0VfQU5EX1hTTFBSRVNFUlZFU1BBQ0UgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfQ09ORkxJQ1RfQkVUV0VFTl9YU0xTVFJJUFNQQUNFX0FORF9YU0xQUkVTRVJWRVNQQUNFID0KLSAgICAxNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0NPTkZMSUNUX0JFVFdFRU5fWFNMU1RSSVBTUEFDRV9BTkRfWFNMUFJFU0VSVkVTUEFDRSArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiTWF0Y2ggY29uZmxpY3QgYmV0d2VlbiB4c2w6c3RyaXAtc3BhY2UgYW5kIHhzbDpwcmVzZXJ2ZS1zcGFjZSI7Ci0gIH0KLQotICAvKiogV0dfQVRUUklCX05PVF9IQU5ETEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0FUVFJJQl9OT1RfSEFORExFRCA9IDE2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfQVRUUklCX05PVF9IQU5ETEVEICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJYYWxhbiBkb2VzIG5vdCB5ZXQgaGFuZGxlIHRoZSB7MH0gYXR0cmlidXRlISI7Ci0gIH0KLQotICAvKiogV0dfTk9fREVDSU1BTEZPUk1BVF9ERUNMQVJBVElPTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OID0gMTc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJObyBkZWNsYXJhdGlvbiBmb3VuZCBmb3IgZGVjaW1hbCBmb3JtYXQ6IHswfSI7Ci0gIH0KLQotICAvKiogV0dfT0xEX1hTTFRfTlMgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfT0xEX1hTTFRfTlMgPSAxODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX09MRF9YU0xUX05TICsgTUFYX0NPREVdWzFdID0gIk1pc3Npbmcgb3IgaW5jb3JyZWN0IFhTTFQgTmFtZXNwYWNlLiAiOwotICB9Ci0KLSAgLyoqIFdHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19PTkVfREVGQVVMVF9YU0xERUNJTUFMRk9STUFUX0FMTE9XRUQgPSAxOTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiT25seSBvbmUgZGVmYXVsdCB4c2w6ZGVjaW1hbC1mb3JtYXQgZGVjbGFyYXRpb24gaXMgYWxsb3dlZC4iOwotICB9Ci0KLSAgLyoqIFdHX1hTTERFQ0lNQUxGT1JNQVRfTkFNRVNfTVVTVF9CRV9VTklRVUUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSA9IDIwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAieHNsOmRlY2ltYWwtZm9ybWF0IG5hbWVzIG11c3QgYmUgdW5pcXVlLiBOYW1lIFwiezB9XCIgaGFzIGJlZW4gZHVwbGljYXRlZC4iOwotICB9Ci0KLSAgLyoqIFdHX0lMTEVHQUxfQVRUUklCVVRFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0lMTEVHQUxfQVRUUklCVVRFID0gMjE7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19JTExFR0FMX0FUVFJJQlVURSArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiezB9IGhhcyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZTogezF9IjsKLSAgfQotCi0gIC8qKiBXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVggICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfQ09VTERfTk9UX1JFU09MVkVfUFJFRklYID0gMjI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVggKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIkNvdWxkIG5vdCByZXNvbHZlIG5hbWVzcGFjZSBwcmVmaXg6IHswfS4gVGhlIG5vZGUgd2lsbCBiZSBpZ25vcmVkLiI7Ci0gIH0KLQotICAvKiogV0dfU1RZTEVTSEVFVF9SRVFVSVJFU19WRVJTSU9OX0FUVFJJQiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCID0gMjM7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19TVFlMRVNIRUVUX1JFUVVJUkVTX1ZFUlNJT05fQVRUUklCICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJ4c2w6c3R5bGVzaGVldCByZXF1aXJlcyBhICd2ZXJzaW9uJyBhdHRyaWJ1dGUhIjsKLSAgfQotCi0gIC8qKiBXR19JTExFR0FMX0FUVFJJQlVURV9OQU1FICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgPSAyNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0lMTEVHQUxfQVRUUklCVVRFX05BTUUgKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIklsbGVnYWwgYXR0cmlidXRlIG5hbWU6IHswfSI7Ci0gIH0KLQotICAvKiogV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfSUxMRUdBTF9BVFRSSUJVVEVfVkFMVUUgPSAyNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJJbGxlZ2FsIHZhbHVlIHVzZWQgZm9yIGF0dHJpYnV0ZSB7MH06IHsxfSI7Ci0gIH0KLQotICAvKiogV0dfRU1QVFlfU0VDT05EX0FSRyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19FTVBUWV9TRUNPTkRfQVJHID0gMjY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19FTVBUWV9TRUNPTkRfQVJHICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJSZXN1bHRpbmcgbm9kZXNldCBmcm9tIHNlY29uZCBhcmd1bWVudCBvZiBkb2N1bWVudCBmdW5jdGlvbiBpcyBlbXB0eS4gVGhlIGZpcnN0IGFndW1lbnQgd2lsbCBiZSB1c2VkLiI7Ci0gIH0KLQotICAvLyBPdGhlciBtaXNjZWxsYW5lb3VzIHRleHQgdXNlZCBpbnNpZGUgdGhlIGNvZGUuLi4KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVNdWzBdID0gInVpX2xhbmd1YWdlIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVNdWzFdID0gImVuIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxXVswXSA9ICJoZWxwX2xhbmd1YWdlIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxXVsxXSA9ICJlbiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMl1bMF0gPSAibGFuZ3VhZ2UiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDJdWzFdID0gImVuIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzXVswXSA9ICJCQURfQ09ERSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgM11bMV0gPQotICAgICAgIlBhcmFtZXRlciB0byBjcmVhdGVNZXNzYWdlIHdhcyBvdXQgb2YgYm91bmRzIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0XVswXSA9ICJGT1JNQVRfRkFJTEVEIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0XVsxXSA9Ci0gICAgICAiRXhjZXB0aW9uIHRocm93biBkdXJpbmcgbWVzc2FnZUZvcm1hdCBjYWxsIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA1XVswXSA9ICJ2ZXJzaW9uIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA1XVsxXSA9ICI+Pj4+Pj4+IFhhbGFuIFZlcnNpb24gIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA2XVswXSA9ICJ2ZXJzaW9uMiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgNl1bMV0gPSAiPDw8PDw8PCI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgN11bMF0gPSAieWVzIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA3XVsxXSA9ICJ5ZXMiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDhdWzBdID0gImxpbmUiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDhdWzFdID0gIkxpbmUgIyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgOV1bMF0gPSAiY29sdW1uIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA5XVsxXSA9ICJDb2x1bW4gIyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTBdWzBdID0gInhzbGRvbmUiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDEwXVsxXSA9ICJYU0xQcm9jZXNzb3I6IGRvbmUiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDExXVswXSA9ICJ4c2xQcm9jX29wdGlvbiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTFdWzFdID0gIlhhbGFuLUogY29tbWFuZCBsaW5lIFByb2Nlc3MgY2xhc3Mgb3B0aW9uczoiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDEyXVswXSA9ICJvcHRpb25JTiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTJdWzFdID0gIiAgICAtSU4gaW5wdXRYTUxVUkwiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDEzXVswXSA9ICJvcHRpb25YU0wiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDEzXVsxXSA9ICIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE0XVswXSA9ICJvcHRpb25PVVQiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE0XVsxXSA9ICIgICBbLU9VVCBvdXRwdXRGaWxlTmFtZV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE1XVswXSA9ICJvcHRpb25MWENJTiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTVdWzFdID0KLSAgICAgICIgICBbLUxYQ0lOIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lSW5dIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxNl1bMF0gPSAib3B0aW9uTFhDT1VUIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxNl1bMV0gPQotICAgICAgIiAgIFstTFhDT1VUIGNvbXBpbGVkU3R5bGVzaGVldEZpbGVOYW1lT3V0T3V0XSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTddWzBdID0gIm9wdGlvblBBUlNFUiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTddWzFdID0KLSAgICAgICIgICBbLVBBUlNFUiBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiBwYXJzZXIgbGlhaXNvbl0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE4XVswXSA9ICJvcHRpb25FIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxOF1bMV0gPSAiICAgWy1FIChEbyBub3QgZXhwYW5kIGVudGl0eSByZWZzKV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE5XVswXSA9ICJvcHRpb25WIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxOV1bMV0gPSAiICAgWy1FIChEbyBub3QgZXhwYW5kIGVudGl0eSByZWZzKV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDIwXVswXSA9ICJvcHRpb25RQyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjBdWzFdID0KLSAgICAgICIgICBbLVFDIChRdWlldCBQYXR0ZXJuIENvbmZsaWN0cyBXYXJuaW5ncyldIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyMV1bMF0gPSAib3B0aW9uUSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjFdWzFdID0gIiAgIFstUSAgKFF1aWV0IE1vZGUpXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjJdWzBdID0gIm9wdGlvbkxGIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyMl1bMV0gPQotICAgICAgIiAgIFstTEYgKFVzZSBsaW5lZmVlZHMgb25seSBvbiBvdXRwdXQge2RlZmF1bHQgaXMgQ1IvTEZ9KV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDIzXVswXSA9ICJvcHRpb25DUiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjNdWzFdID0KLSAgICAgICIgICBbLUNSIChVc2UgY2FycmlhZ2UgcmV0dXJucyBvbmx5IG9uIG91dHB1dCB7ZGVmYXVsdCBpcyBDUi9MRn0pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjRdWzBdID0gIm9wdGlvbkVTQ0FQRSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjRdWzFdID0KLSAgICAgICIgICBbLUVTQ0FQRSAoV2hpY2ggY2hhcmFjdGVycyB0byBlc2NhcGUge2RlZmF1bHQgaXMgPD4mXCJcJ1xcclxcbn1dIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyNV1bMF0gPSAib3B0aW9uSU5ERU5UIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyNV1bMV0gPQotICAgICAgIiAgIFstSU5ERU5UIChDb250cm9sIGhvdyBtYW55IHNwYWNlcyB0byBpbmRlbnQge2RlZmF1bHQgaXMgMH0pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjZdWzBdID0gIm9wdGlvblRUIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyNl1bMV0gPQotICAgICAgIiAgIFstVFQgKFRyYWNlIHRoZSB0ZW1wbGF0ZXMgYXMgdGhleSBhcmUgYmVpbmcgY2FsbGVkLildIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyN11bMF0gPSAib3B0aW9uVEciOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDI3XVsxXSA9Ci0gICAgICAiICAgWy1URyAoVHJhY2UgZWFjaCBnZW5lcmF0aW9uIGV2ZW50LildIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyOF1bMF0gPSAib3B0aW9uVFMiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDI4XVsxXSA9ICIgICBbLVRTIChUcmFjZSBlYWNoIHNlbGVjdGlvbiBldmVudC4pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjldWzBdID0gIm9wdGlvblRUQyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMjldWzFdID0KLSAgICAgICIgICBbLVRUQyAoVHJhY2UgdGhlIHRlbXBsYXRlIGNoaWxkcmVuIGFzIHRoZXkgYXJlIGJlaW5nIHByb2Nlc3NlZC4pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzBdWzBdID0gIm9wdGlvblRDTEFTUyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzBdWzFdID0KLSAgICAgICIgICBbLVRDTEFTUyAoVHJhY2VMaXN0ZW5lciBjbGFzcyBmb3IgdHJhY2UgZXh0ZW5zaW9ucy4pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzFdWzBdID0gIm9wdGlvblZBTElEQVRFIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzMV1bMV0gPQotICAgICAgIiAgIFstVkFMSURBVEUgKFNldCB3aGV0aGVyIHZhbGlkYXRpb24gb2NjdXJzLiAgVmFsaWRhdGlvbiBpcyBvZmYgYnkgZGVmYXVsdC4pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzJdWzBdID0gIm9wdGlvbkVEVU1QIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzMl1bMV0gPQotICAgICAgIiAgIFstRURVTVAge29wdGlvbmFsIGZpbGVuYW1lfSAoRG8gc3RhY2tkdW1wIG9uIGVycm9yLildIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzM11bMF0gPSAib3B0aW9uWE1MIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzM11bMV0gPQotICAgICAgIiAgIFstWE1MIChVc2UgWE1MIGZvcm1hdHRlciBhbmQgYWRkIFhNTCBoZWFkZXIuKV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDM0XVswXSA9ICJvcHRpb25URVhUIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzNF1bMV0gPQotICAgICAgIiAgIFstVEVYVCAoVXNlIHNpbXBsZSBUZXh0IGZvcm1hdHRlci4pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzVdWzBdID0gIm9wdGlvbkhUTUwiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDM1XVsxXSA9ICIgICBbLUhUTUwgKFVzZSBIVE1MIGZvcm1hdHRlci4pXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzZdWzBdID0gIm9wdGlvblBBUkFNIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzNl1bMV0gPQotICAgICAgIiAgIFstUEFSQU0gbmFtZSBleHByZXNzaW9uIChTZXQgYSBzdHlsZXNoZWV0IHBhcmFtZXRlcildIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzN11bMF0gPSAibm9QYXJzZXJtc2cxIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzN11bMV0gPSAiWFNMIFByb2Nlc3Mgd2FzIG5vdCBzdWNjZXNzZnVsLiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzhdWzBdID0gIm5vUGFyc2VybXNnMiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzhdWzFdID0gIioqIENvdWxkIG5vdCBmaW5kIHBhcnNlciAqKiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzldWzBdID0gIm5vUGFyc2VybXNnMyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMzldWzFdID0gIlBsZWFzZSBjaGVjayB5b3VyIGNsYXNzcGF0aC4iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDQwXVswXSA9ICJub1BhcnNlcm1zZzQiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDQwXVsxXSA9Ci0gICAgICAiSWYgeW91IGRvbid0IGhhdmUgSUJNJ3MgWE1MIFBhcnNlciBmb3IgSmF2YSwgeW91IGNhbiBkb3dubG9hZCBpdCBmcm9tIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0MV1bMF0gPSAibm9QYXJzZXJtc2c1IjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0MV1bMV0gPQotICAgICAgIklCTSdzIEFscGhhV29ya3M6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIjsKLQkJY29udGVudHNbTUFYX01FU1NBR0VTICsgNDJdWzBdID0gIm9wdGlvblVSSVJFU09MVkVSIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0Ml1bMV0gPSAiICAgWy1VUklSRVNPTFZFUiBmdWxsIGNsYXNzIG5hbWUgKFVSSVJlc29sdmVyIHRvIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzKV0iOwotCQljb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0M11bMF0gPSAib3B0aW9uRU5USVRZUkVTT0xWRVIiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDQzXVsxXSA9ICIgICBbLUVOVElUWVJFU09MVkVSIGZ1bGwgY2xhc3MgbmFtZSAoRW50aXR5UmVzb2x2ZXIgdG8gYmUgdXNlZCB0byByZXNvbHZlIGVudGl0aWVzKV0iOwotCQljb250ZW50c1tNQVhfTUVTU0FHRVMgKyA0NF1bMF0gPSAib3B0aW9uQ09OVEVOVEhBTkRMRVIiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDQ0XVsxXSA9ICIgICBbLUNPTlRFTlRIQU5ETEVSIGZ1bGwgY2xhc3MgbmFtZSAoQ29udGVudEhhbmRsZXIgdG8gYmUgdXNlZCB0byBzZXJpYWxpemUgb3V0cHV0KV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDQ1XVswXSA9ICJvcHRpb25MSU5FTlVNQkVSUyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgNDVdWzFdID0gIiAgIFstTCB1c2UgbGluZSBudW1iZXJzIGZvciBzb3VyY2UgZG9jdW1lbnRdIjsKLQkJCi0gIH0KLQotICAvLyA9PT09PT09PT09PT09PT09PSBJTkZSQVNUUlVDVFVSRSA9PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqIFN0cmluZyBmb3IgdXNlIHdoZW4gYSBiYWQgZXJyb3IgY29kZSB3YXMgZW5jb3VudGVyZWQuICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBRF9DT0RFID0gIkJBRF9DT0RFIjsKLQotICAvKiogU3RyaW5nIGZvciB1c2Ugd2hlbiBmb3JtYXR0aW5nIG9mIHRoZSBlcnJvciBzdHJpbmcgZmFpbGVkLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEdlbmVyYWwgZXJyb3Igc3RyaW5nLiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBTdHJpbmcgdG8gcHJlcGVuZCB0byBlcnJvciBtZXNzYWdlcy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0hFQURFUiA9ICJFcnJvcjogIjsKLQotICAvKiogU3RyaW5nIHRvIHByZXBlbmQgdG8gd2FybmluZyBtZXNzYWdlcy4gICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklOR19IRUFERVIgPSAiV2FybmluZzogIjsKLQotICAvKiogU3RyaW5nIHRvIHNwZWNpZnkgdGhlIFhTTFQgbW9kdWxlLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMX0hFQURFUiA9ICJYU0xUICI7Ci0KLSAgLyoqIFN0cmluZyB0byBzcGVjaWZ5IHRoZSBYTUwgcGFyc2VyIG1vZHVsZS4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9IRUFERVIgPSAiWE1MICI7Ci0KLSAgLyoqIEkgZG9uJ3QgdGhpbmsgdGhpcyBpcyB1c2VkIGFueSBtb3JlLgotICAgKiBAZGVwcmVjYXRlZCAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVFUllfSEVBREVSID0gIlBBVFRFUk4gIjsKLQotICAvKioKLSAgICogR2V0IHRoZSBsb29rdXAgdGFibGUuIAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbnQgdG8gbWVzc2FnZSBsb29rdXAgdGFibGUuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICByZXR1cm4gY29udGVudHM7Ci0gIH0KLQotICAvKioKLSAgICogICBSZXR1cm4gYSBuYW1lZCBSZXNvdXJjZUJ1bmRsZSBmb3IgYSBwYXJ0aWN1bGFyIGxvY2FsZS4gIFRoaXMgbWV0aG9kIG1pbWljcyB0aGUgYmVoYXZpb3IKLSAgICogICBvZiBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoKS4KLSAgICogIAotICAgKiAgIEBwYXJhbSBjbGFzc05hbWUgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgcmVzb3VyY2UgYnVuZGxlLgotICAgKiAgIEByZXR1cm4gdGhlIFJlc291cmNlQnVuZGxlCi0gICAqICAgQHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgWFNMVEVycm9yUmVzb3VyY2VzIGxvYWRSZXNvdXJjZUJ1bmRsZShTdHJpbmcgY2xhc3NOYW1lKQotICAgICAgICAgIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KLSAgewotCi0gICAgTG9jYWxlIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgU3RyaW5nIHN1ZmZpeCA9IGdldFJlc291cmNlU3VmZml4KGxvY2FsZSk7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIGZpcnN0IHRyeSB3aXRoIHRoZSBnaXZlbiBsb2NhbGUKLSAgICAgIHJldHVybiAoWFNMVEVycm9yUmVzb3VyY2VzKSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoY2xhc3NOYW1lCi0gICAgICAgICAgICAgICsgc3VmZml4LCBsb2NhbGUpOwotICAgIH0KLSAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdHJ5ICAvLyB0cnkgdG8gZmFsbCBiYWNrIHRvIGVuX1VTIGlmIHdlIGNhbid0IGxvYWQKLSAgICAgIHsKLQotICAgICAgICAvLyBTaW5jZSB3ZSBjYW4ndCBmaW5kIHRoZSBsb2NhbGl6ZWQgcHJvcGVydHkgZmlsZSwKLSAgICAgICAgLy8gZmFsbCBiYWNrIHRvIGVuX1VTLgotICAgICAgICByZXR1cm4gKFhTTFRFcnJvclJlc291cmNlcykgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGNsYXNzTmFtZSwKLSAgICAgICAgICAgICAgICBuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZTIpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gTm93IHdlIGFyZSByZWFsbHkgaW4gdHJvdWJsZS4KLSAgICAgICAgLy8gdmVyeSBiYWQsIGRlZmluaXRlbHkgdmVyeSBiYWQuLi5ub3QgZ29pbmcgdG8gZ2V0IHZlcnkgZmFyCi0gICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oCi0gICAgICAgICAgIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiIsIGNsYXNzTmFtZSwgIiIpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHJlc291cmNlIGZpbGUgc3VmZmljIGZvciB0aGUgaW5kaWNhdGVkIGxvY2FsZQotICAgKiBGb3IgbW9zdCBsb2NhbGVzLCB0aGlzIHdpbGwgYmUgYmFzZWQgdGhlIGxhbmd1YWdlIGNvZGUuICBIb3dldmVyCi0gICAqIGZvciBDaGluZXNlLCB3ZSBkbyBkaXN0aW5ndWlzaCBiZXR3ZWVuIFRhaXdhbiBhbmQgUFJDCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQotICAgKiBAcmV0dXJuIGFuIFN0cmluZyBzdWZmaXggd2hpY2ggY2FuYmUgYXBwZW5kZWQgdG8gYSByZXNvdXJjZSBuYW1lCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0UmVzb3VyY2VTdWZmaXgoTG9jYWxlIGxvY2FsZSkKLSAgewotCi0gICAgU3RyaW5nIHN1ZmZpeCA9ICJfIiArIGxvY2FsZS5nZXRMYW5ndWFnZSgpOwotICAgIFN0cmluZyBjb3VudHJ5ID0gbG9jYWxlLmdldENvdW50cnkoKTsKLQotICAgIGlmIChjb3VudHJ5LmVxdWFscygiVFciKSkKLSAgICAgIHN1ZmZpeCArPSAiXyIgKyBjb3VudHJ5OwotCi0gICAgcmV0dXJuIHN1ZmZpeDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVycm9yIGNvZGUuCi0gICAqCi0gICAqIEBwYXJhbSBlcnJvckNvZGUgU2hvdWxkIGJlIGEgdmFsaWQgZXJyb3IgY29kZSBsZXNzIHRoYW4ge0BsaW5rICNNQVhfQ09ERX0uCi0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVycm9yIGNvZGUsIG9yIG51bGwgaWYgY29kZSBpcyAKLSAgICogZ3JlYXRlciB0aGFuIE1BWF9DT0RFLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlS2V5KGludCBlcnJvckNvZGUpCi0gIHsKLQotICAgIGlmIChlcnJvckNvZGUgPiBNQVhfQ09ERSkKLSAgICAgIHJldHVybiBudWxsOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBEZWNpbWFsRm9ybWF0IGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIjAwMDAiKTsKLQotICAgICAgcmV0dXJuIEVSUk9SX1NVRkZJWCArIGRmLmZvcm1hdChlcnJvckNvZGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHdhcm5pbmcgY29kZS4KLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBTaG91bGQgYmUgYSB2YWxpZCB3YXJuaW5nIGNvZGUgbGVzcyB0aGFuIHtAbGluayAjTUFYX1dBUk5JTkd9LgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB3YXJuaW5nIGNvZGUsIG9yIG51bGwgaWYgY29kZSBpcyAKLSAgICogZ3JlYXRlciB0aGFuIE1BWF9XQVJOSU5HLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRXYXJuaW5nS2V5KGludCBlcnJvckNvZGUpCi0gIHsKLQotICAgIGlmIChlcnJvckNvZGUgPiBNQVhfV0FSTklORykKLSAgICAgIHJldHVybiBudWxsOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBEZWNpbWFsRm9ybWF0IGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIjAwMDAiKTsKLQotICAgICAgcmV0dXJuIFdBUk5JTkdfU1VGRklYICsgZGYuZm9ybWF0KGVycm9yQ29kZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZSBjb2RlLiAoc2FtZSBhcyBnZXRNZXNzYWdlS2V5KS4KLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBTaG91bGQgYmUgYSB2YWxpZCBlcnJvciBjb2RlIGxlc3MgdGhhbiB7QGxpbmsgI01BWF9DT0RFfS4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZXJyb3IgY29kZSwgb3IgbnVsbCBpZiBjb2RlIGlzIAotICAgKiBncmVhdGVyIHRoYW4gTUFYX0NPREUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRNS2V5KGludCBlcnJvckNvZGUpCi0gIHsKLSAgICBpZiAoZXJyb3JDb2RlID4gTUFYX0NPREUpCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICBlbHNlCi0gICAgewotICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwMDAwIik7Ci0KLSAgICAgIHJldHVybiBFUlJPUl9TVUZGSVggKyBkZi5mb3JtYXQoZXJyb3JDb2RlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB3YXJuaW5nIGNvZGUuCi0gICAqCi0gICAqIEBwYXJhbSBlcnJvckNvZGUgU2hvdWxkIGJlIGEgdmFsaWQgd2FybmluZyBjb2RlIGxlc3MgdGhhbiB7QGxpbmsgI01BWF9XQVJOSU5HfS4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgd2FybmluZyBjb2RlLCBvciBudWxsIGlmIGNvZGUgaXMgCi0gICAqIGdyZWF0ZXIgdGhhbiBNQVhfV0FSTklORy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFdLZXkoaW50IGVycm9yQ29kZSkKLSAgewotCi0gICAgaWYgKGVycm9yQ29kZSA+IE1BWF9XQVJOSU5HKQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIERlY2ltYWxGb3JtYXQgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgiMDAwMCIpOwotCi0gICAgICByZXR1cm4gV0FSTklOR19TVUZGSVggKyBkZi5mb3JtYXQoZXJyb3JDb2RlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Jlcy9YU0xUSW5mby5wcm9wZXJ0aWVzIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzL1hTTFRJbmZvLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFhYTFkYzYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzL1hTTFRJbmZvLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwxNCArMCwwIEBACi0jCi0jICBYU0xUIFJlc291cmNlIEZpbGUKLSMKLQotdmVyc2lvbj0yLjIuRDEwCi12ZW5kb3I9QXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KLXZlbmRvci11cmw9aHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuLWoKLQotIyBUaGUgWE1MIFBhcnNlciBmb3IgU0FYMgotIyBTaW5jZSBYTUxSZWFkZXJGYWN0b3J5IGRvZXNuJ3QgaGF2ZSBpdCdzIG93biBwcm9wZXJ0aWVzIGZpbGUsIAotIyBidXQgc2ltcGx5IHJlYWRzIHRoZSBzeXN0ZW0gcHJvcGVydGllcywgWGFsYW4gdHJpZXMgdG8gbG9hZCAKLSMgdGhpcyB2YWx1ZSBpbnRvIHRoZSBzeXN0ZW0gcHJvcGVydGllcy4KLW9yZy54bWwuc2F4LmRyaXZlcj1vcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcgotIyBvcmcueG1sLnNheC5kcml2ZXI9b3JnLmFwYWNoZS5jcmltc29uLnBhcnNlci5YTUxSZWFkZXJJbXBsClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Jlcy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRiODVkN2YuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDggKzAsMCBAQAotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiByZXNvdXJjZSBQYWNrYWdlLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkNvbnRhaW5zIHN0cmluZ3MgdGhhdCByZXF1aXJlIGludGVybmF0aW9uYWxpemF0aW9uLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvQ2hhckluZm8uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9DaGFySW5mby5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2M2FlMmI5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9DaGFySW5mby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOwotCi1pbXBvcnQgamF2YS51dGlsLkJpdFNldDsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOwotCi1pbXBvcnQgamF2YS5uZXQuKjsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5DaGFyS2V5OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgc2VydmljZXMgdGhhdCB0ZWxsIGlmIGEgY2hhcmFjdGVyIHNob3VsZCBoYXZlCi0gKiBzcGVjaWFsIHRyZWF0ZW1lbnQsIHN1Y2ggYXMgZW50aXR5IHJlZmVyZW5jZSBzdWJzdGl0dXRpb24gb3Igbm9ybWFsaXphdGlvbgotICogb2YgYSBuZXdsaW5lIGNoYXJhY3Rlci4gIEl0IGFsc28gcHJvdmlkZXMgY2hhcmFjdGVyIHRvIGVudGl0eSByZWZlcmVuY2UKLSAqIGxvb2t1cC4KLSAqLwotcHVibGljIGNsYXNzIENoYXJJbmZvCi17Ci0KLSAgLyoqIEJpdCBtYXAgdGhhdCB0ZWxscyBpZiBhIGdpdmVuIGNoYXJhY3RlciBzaG91bGQgaGF2ZSBzcGVjaWFsIHRyZWF0bWVudC4gKi8KLSAgQml0U2V0IG1fc3BlY2lhbHNNYXAgPSBuZXcgQml0U2V0KDY1NTM1KTsKLQotICAvKiogTG9va3VwIHRhYmxlIGZvciBjaGFyYWN0ZXJzIHRvIGVudGl0eSByZWZlcmVuY2VzLiAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2NoYXJUb0VudGl0eVJlZiA9IG5ldyBIYXNodGFibGUoKTsKLQotICAvKioKLSAgICogVGhlIG5hbWUgb2YgdGhlIEhUTUwgZW50aXRpZXMgZmlsZS4KLSAgICogSWYgc3BlY2lmaWVkLCB0aGUgZmlsZSB3aWxsIGJlIHJlc291cmNlIGxvYWRlZCB3aXRoIHRoZSBkZWZhdWx0IGNsYXNzIGxvYWRlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIEhUTUxfRU5USVRJRVNfUkVTT1VSQ0UgPSAiSFRNTEVudGl0aWVzLnJlcyI7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lIG9mIHRoZSBYTUwgZW50aXRpZXMgZmlsZS4KLSAgICogSWYgc3BlY2lmaWVkLCB0aGUgZmlsZSB3aWxsIGJlIHJlc291cmNlIGxvYWRlZCB3aXRoIHRoZSBkZWZhdWx0IGNsYXNzIGxvYWRlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIFhNTF9FTlRJVElFU19SRVNPVVJDRSA9ICJYTUxFbnRpdGllcy5yZXMiOwotCi0gIC8qKiBUaGUgbGluZWZlZWQgY2hhcmFjdGVyLCB3aGljaCB0aGUgcGFyc2VyIHNob3VsZCBhbHdheXMgbm9ybWFsaXplLiAqLwotICBwdWJsaWMgc3RhdGljIGNoYXIgU19MSU5FRkVFRCA9IDB4MEE7Ci0KLSAgLyoqIFRoZSBjYXJyaWFnZSByZXR1cm4gY2hhcmFjdGVyLCB3aGljaCB0aGUgcGFyc2VyIHNob3VsZCBhbHdheXMgbm9ybWFsaXplLiAqLwotICBwdWJsaWMgc3RhdGljIGNoYXIgU19DQVJSSUFHRVJFVFVSTiA9IDB4MEQ7Ci0KLSAgLyoqIGEgemVybyBsZW5ndGggQ2xhc3MgYXJyYXkgdXNlZCBpbiB0aGUgY29uc3RydWN0b3IgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3NbXSBOT19DTEFTU0VTID0gbmV3IENsYXNzWzBdOwotCi0gIC8qKiBhIHplcm8gbGVuZ3RoIE9iamVjdCBhcnJheSB1c2VkIGluIHRoZSBjb25zdHJ1Y3RvciAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBOT19PQkpTID0gbmV3IE9iamVjdFswXTsKLQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciB0aGF0IHJlYWRzIGluIGEgcmVzb3VyY2UgZmlsZSB0aGF0IGRlc2NyaWJlcyB0aGUgbWFwcGluZyBvZgotICAgKiBjaGFyYWN0ZXJzIHRvIGVudGl0eSByZWZlcmVuY2VzLgotICAgKgotICAgKiBAcGFyYW0gZW50aXRpZXNSZXNvdXJjZSBOYW1lIG9mIGVudGl0aWVzIHJlc291cmNlIGZpbGUgdGhhdCBzaG91bGQKLSAgICogYmUgbG9hZGVkLCB3aGljaCBkZXNjcmliZXMgdGhhdCBtYXBwaW5nIG9mIGNoYXJhY3RlcnMgdG8gZW50aXR5IHJlZmVyZW5jZXMuCi0gICAqLwotICBwdWJsaWMgQ2hhckluZm8oU3RyaW5nIGVudGl0aWVzUmVzb3VyY2UpCi0gIHsKLQotICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKLSAgICBCdWZmZXJlZFJlYWRlciByZWFkZXIgPSBudWxsOwotICAgIGludCBpbmRleDsKLSAgICBTdHJpbmcgbmFtZTsKLSAgICBTdHJpbmcgdmFsdWU7Ci0gICAgaW50IGNvZGU7Ci0gICAgU3RyaW5nIGxpbmU7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIHRyeSB7Ci0gICAgICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBnZXRDQ0wgPSBUaHJlYWQuY2xhc3MuZ2V0TWV0aG9kKCJnZXRDb250ZXh0Q2xhc3NMb2FkZXIiLCBOT19DTEFTU0VTKTsKLSAgICAgICAgaWYgKGdldENDTCAhPSBudWxsKSB7Ci0gICAgICAgICAgQ2xhc3NMb2FkZXIgY29udGV4dENsYXNzTG9hZGVyID0gKENsYXNzTG9hZGVyKSBnZXRDQ0wuaW52b2tlKFRocmVhZC5jdXJyZW50VGhyZWFkKCksIE5PX09CSlMpOwotICAgICAgICAgIGlzID0gY29udGV4dENsYXNzTG9hZGVyLmdldFJlc291cmNlQXNTdHJlYW0oIm9yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplLyIgKyBlbnRpdGllc1Jlc291cmNlKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICBpZiAoaXMgPT0gbnVsbCkKLSAgICAgICAgaXMgPSBDaGFySW5mby5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKGVudGl0aWVzUmVzb3VyY2UpOwotCi0gICAgICBpZiAoaXMgPT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgVVJMIHVybCA9IG5ldyBVUkwoZW50aXRpZXNSZXNvdXJjZSk7Ci0KLSAgICAgICAgaXMgPSB1cmwub3BlblN0cmVhbSgpOwotICAgICAgfQotCi0gICAgICBpZiAoaXMgPT0gbnVsbCkKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUkVTT1VSQ0VfQ09VTERfTk9UX0ZJTkQsIG5ldyBPYmplY3RbXXtlbnRpdGllc1Jlc291cmNlLCBlbnRpdGllc1Jlc291cmNlIH0pKTsgLy8iVGhlIHJlc291cmNlIFsiICsgZW50aXRpZXNSZXNvdXJjZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgIl0gY291bGQgbm90IGJlIGZvdW5kLlxuIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgZW50aXRpZXNSZXNvdXJjZSk7Ci0KLSAgICAgIHJlYWRlciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMpKTsKLSAgICAgIGxpbmUgPSByZWFkZXIucmVhZExpbmUoKTsKLQotICAgICAgd2hpbGUgKGxpbmUgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgaWYgKGxpbmUubGVuZ3RoKCkgPT0gMCB8fCBsaW5lLmNoYXJBdCgwKSA9PSAnIycpCi0gICAgICAgIHsKLSAgICAgICAgICBsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCk7Ci0KLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4ID0gbGluZS5pbmRleE9mKCcgJyk7Ci0KLSAgICAgICAgaWYgKGluZGV4ID4gMSkKLSAgICAgICAgewotICAgICAgICAgIG5hbWUgPSBsaW5lLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICAgICAgICArK2luZGV4OwotCi0gICAgICAgICAgaWYgKGluZGV4IDwgbGluZS5sZW5ndGgoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB2YWx1ZSA9IGxpbmUuc3Vic3RyaW5nKGluZGV4KTsKLSAgICAgICAgICAgIGluZGV4ID0gdmFsdWUuaW5kZXhPZignICcpOwotCi0gICAgICAgICAgICBpZiAoaW5kZXggPiAwKQotICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygwLCBpbmRleCk7Ci0KLSAgICAgICAgICAgIGNvZGUgPSBJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKTsKLQotICAgICAgICAgICAgZGVmaW5lRW50aXR5KG5hbWUsIChjaGFyKSBjb2RlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBsaW5lID0gcmVhZGVyLnJlYWRMaW5lKCk7Ci0gICAgICB9Ci0KLSAgICAgIGlzLmNsb3NlKCk7Ci0gICAgICBtX3NwZWNpYWxzTWFwLnNldChTX0xJTkVGRUVEKTsKLSAgICAgIG1fc3BlY2lhbHNNYXAuc2V0KFNfQ0FSUklBR0VSRVRVUk4pOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGV4Y2VwdCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9SRVNPVVJDRV9DT1VMRF9OT1RfTE9BRCwgbmV3IE9iamVjdFtde2VudGl0aWVzUmVzb3VyY2UsICBleGNlcHQudG9TdHJpbmcoKSwgZW50aXRpZXNSZXNvdXJjZSwgZXhjZXB0LnRvU3RyaW5nKCkgfSkpOyAvLyJUaGUgcmVzb3VyY2UgWyIgKyBlbnRpdGllc1Jlc291cmNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIl0gY291bGQgbm90IGxvYWQ6ICIgKyBleGNlcHQudG9TdHJpbmcoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICJcbiIgKyBlbnRpdGllc1Jlc291cmNlICsgIlx0IgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIGV4Y2VwdC50b1N0cmluZygpKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmIChpcyAhPSBudWxsKQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGlzLmNsb3NlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleGNlcHQpe30KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRGVmaW5lcyBhIG5ldyBjaGFyYWN0ZXIgcmVmZXJlbmNlLiBUaGUgcmVmZXJlbmNlJ3MgbmFtZSBhbmQgdmFsdWUgYXJlCi0gICAqIHN1cHBsaWVkLiBOb3RoaW5nIGhhcHBlbnMgaWYgdGhlIGNoYXJhY3RlciByZWZlcmVuY2UgaXMgYWxyZWFkeSBkZWZpbmVkLgotICAgKiA8cD5Vbmxpa2UgaW50ZXJuYWwgZW50aXRpZXMsIGNoYXJhY3RlciByZWZlcmVuY2VzIGFyZSBhIHN0cmluZyB0byBzaW5nbGUKLSAgICogY2hhcmFjdGVyIG1hcHBpbmcuIFRoZXkgYXJlIHVzZWQgdG8gbWFwIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIGJvdGggb24KLSAgICogcGFyc2luZyBhbmQgcHJpbnRpbmcsIHByaW1hcmlseSBmb3IgSFRNTCBkb2N1bWVudHMuICcmbHQ7YW1wOycgaXMgYW4KLSAgICogZXhhbXBsZSBvZiBhIGNoYXJhY3RlciByZWZlcmVuY2UuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZW50aXR5J3MgbmFtZQotICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudGl0eSdzIHZhbHVlCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBkZWZpbmVFbnRpdHkoU3RyaW5nIG5hbWUsIGNoYXIgdmFsdWUpCi0gIHsKLQotICAgIENoYXJLZXkgY2hhcmFjdGVyID0gbmV3IENoYXJLZXkodmFsdWUpOwotCi0gICAgbV9jaGFyVG9FbnRpdHlSZWYucHV0KGNoYXJhY3RlciwgbmFtZSk7Ci0gICAgbV9zcGVjaWFsc01hcC5zZXQodmFsdWUpOwotICB9Ci0gIAotICBwcml2YXRlIENoYXJLZXkgbV9jaGFyS2V5ID0gbmV3IENoYXJLZXkoKTsKLQotICAvKioKLSAgICogUmVzb2x2ZSBhIGNoYXJhY3RlciB0byBhbiBlbnRpdHkgcmVmZXJlbmNlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBjaGFyYWN0ZXIgdmFsdWUgdGhhdCBzaG91bGQgYmUgcmVzb2x2ZWQgdG8gYSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIG5hbWUgb2YgY2hhcmFjdGVyIGVudGl0eSwgb3IgbnVsbCBpZiBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEVudGl0eU5hbWVGb3JDaGFyKGNoYXIgdmFsdWUpCi0gIHsKLSAgICBtX2NoYXJLZXkuc2V0Q2hhcih2YWx1ZSk7Ci0gICAgcmV0dXJuIChTdHJpbmcpIG1fY2hhclRvRW50aXR5UmVmLmdldChtX2NoYXJLZXkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGNoYXJhY3RlciBhcmd1bWVudCBzaG91bGQgaGF2ZSBzcGVjaWFsIHRyZWF0bWVudC4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIGNoYXJhY3RlciB2YWx1ZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgc2hvdWxkIGhhdmUgYW55IHNwZWNpYWwgdHJlYXRtZW50LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNTcGVjaWFsKGNoYXIgdmFsdWUpCi0gIHsKLSAgICByZXR1cm4gbV9zcGVjaWFsc01hcC5nZXQodmFsdWUpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvRE9NU2VyaWFsaXplci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL0RPTVNlcmlhbGl6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTBkOWJjNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvRE9NU2VyaWFsaXplci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBJbnRlcmZhY2UgZm9yIGEgRE9NIHNlcmlhbGl6ZXIgaW1wbGVtZW50YXRpb24uCi0gKiA8cD4KLSAqIFRoZSBET00gc2VyaWFsaXplciBpcyBhIGZhY2V0IG9mIGEgc2VyaWFsaXplci4gQSBzZXJpYWxpemVyIG1heSBvciBtYXkKLSAqIG5vdCBzdXBwb3J0IGEgRE9NIHNlcmlhbGl6ZXIuCi0gKiA8cD4KLSAqIEV4YW1wbGU6Ci0gKiA8cHJlPgotICogRG9jdW1lbnQgICAgIGRvYzsKLSAqIFNlcmlhbGl6ZXIgICBzZXI7Ci0gKiBPdXRwdXRTdHJlYW0gb3M7Ci0gKgotICogc2VyLnNldE91dHB1dFN0cmVhbSggb3MgKTsKLSAqIHNlci5hc0RPTVNlcmlhbGl6ZXIoIGRvYyApOwotICogPC9wcmU+Ci0gKgotICoKLSAqIEB2ZXJzaW9uIEFscGhhCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpTY290dF9Cb2FnL0NBTS9Mb3R1c0Bsb3R1cy5jb20iPlNjb3R0IEJvYWc8L2E+Ci0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBleG9mZmljZS5jb20iPkFzc2FmIEFya2luPC9hPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTVNlcmlhbGl6ZXIKLXsKLSAgLyoqCi0gICAqIFNlcmlhbGl6ZXMgdGhlIERPTSBub2RlLiBUaHJvd3MgYW4gZXhjZXB0aW9uIG9ubHkgaWYgYW4gSS9PCi0gICAqIGV4Y2VwdGlvbiBvY2N1cmVkIHdoaWxlIHNlcmlhbGl6aW5nLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBUaGUgZWxlbWVudCB0byBzZXJpYWxpemUKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBBbiBJL08gZXhjZXB0aW9uIG9jY3VyZWQgd2hpbGUgc2VyaWFsaXppbmcKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZShOb2RlIG5vZGUpIHRocm93cyBJT0V4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9FbGVtRGVzYy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL0VsZW1EZXNjLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZlYzM3ZjcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL0VsZW1EZXNjLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdUb0ludFRhYmxlOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhpcyBjbGFzcyBpcyBpbiBzdXBwb3J0IG9mIFNlcmlhbGl6ZXJUb0hUTUwsIGFuZCBhY3RzIGFzIGEgc29ydAotICogb2YgZWxlbWVudCByZXByZXNlbnRhdGl2ZSBmb3IgSFRNTCBlbGVtZW50cy4KLSAqLwotY2xhc3MgRWxlbURlc2MKLXsKLQotICAvKiogQml0IGZsYWdzIHRvIHRlbGwgYWJvdXQgdGhpcyBlbGVtZW50IHR5cGUuICovCi0gIGludCBtX2ZsYWdzOwotCi0gIC8qKgotICAgKiBUYWJsZSBvZiBhdHRyaWJ1dGUgbmFtZXMgdG8gaW50ZWdlcnMsIHdoaWNoIGNvbnRhaW4gYml0IGZsYWdzIHRlbGxpbmcgYWJvdXQKLSAgICogIHRoZSBhdHRyaWJ1dGVzLgotICAgKi8KLSAgU3RyaW5nVG9JbnRUYWJsZSBtX2F0dHJzID0gbnVsbDsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGVtcHR5LiAqLwotICBzdGF0aWMgZmluYWwgaW50IEVNUFRZID0gKDEgPDwgMSk7Ci0KLSAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBhIGZsb3cuICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgRkxPVyA9ICgxIDw8IDIpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBibG9jay4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBCTE9DSyA9ICgxIDw8IDMpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBibG9jayBmb3JtLiAqLwotICBzdGF0aWMgZmluYWwgaW50IEJMT0NLRk9STSA9ICgxIDw8IDQpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBibG9jayBmb3JtIGZpZWxkIHNldCAoPz8gLXNiKS4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBCTE9DS0ZPUk1GSUVMRFNFVCA9ICgxIDw8IDUpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgQ0RBVEEuICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQ0RBVEEgPSAoMSA8PCA2KTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIFBDREFUQS4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBQQ0RBVEEgPSAoMSA8PCA3KTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIHNob3VsZCBiZSByYXcgY2hhcmFjdGVycy4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBSQVcgPSAoMSA8PCA4KTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIHNob3VsZCBiZSBpbmxpbmVkLiAqLwotICBzdGF0aWMgZmluYWwgaW50IElOTElORSA9ICgxIDw8IDkpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgSU5MSU5FQSAoPz8gLXNiKS4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBJTkxJTkVBID0gKDEgPDwgMTApOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYW4gaW5saW5lIGxhYmVsLiAqLwotICBzdGF0aWMgZmluYWwgaW50IElOTElORUxBQkVMID0gKDEgPDwgMTEpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBmb250IHN0eWxlLiAqLwotICBzdGF0aWMgZmluYWwgaW50IEZPTlRTVFlMRSA9ICgxIDw8IDEyKTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgcGhyYXNlLiAqLwotICBzdGF0aWMgZmluYWwgaW50IFBIUkFTRSA9ICgxIDw8IDEzKTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgZm9ybSBjb250cm9sLiAqLwotICBzdGF0aWMgZmluYWwgaW50IEZPUk1DVFJMID0gKDEgPDwgMTQpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgPz8/LiAqLwotICBzdGF0aWMgZmluYWwgaW50IFNQRUNJQUwgPSAoMSA8PCAxNSk7Ci0KLSAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyA/Pz8uICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQVNQRUNJQUwgPSAoMSA8PCAxNik7Ci0KLSAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBhbiBvZGQgaGVhZGVyIGVsZW1lbnQuICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgSEVBRE1JU0MgPSAoMSA8PCAxNyk7Ci0KLSAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyBhIGhlYWQgZWxlbWVudCAoaS5lLiBIMSwgSDIsIGV0Yy4pICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgSEVBRCA9ICgxIDw8IDE4KTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgZWxlbWVudCB0eXBlIGlzIGEgbGlzdC4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBMSVNUID0gKDEgPDwgMTkpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBwcmVmb3JtYXR0ZWQgdHlwZS4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBQUkVGT1JNQVRURUQgPSAoMSA8PCAyMCk7Ci0KLSAgLyoqIEJpdCBwb3NpdGlvbiBpZiB0aGlzIGVsZW1lbnQgdHlwZSBpcyB3aGl0ZXNwYWNlIHNlbnNpdGl2ZS4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBXSElURVNQQUNFU0VOU0lUSVZFID0gKDEgPDwgMjEpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBlbGVtZW50IHR5cGUgaXMgYSBoZWFkZXIgZWxlbWVudCAoaS5lLiBIRUFEKS4gKi8KLSAgc3RhdGljIGZpbmFsIGludCBIRUFERUxFTSA9ICgxIDw8IDIyKTsKLQotICAvKiogQml0IHBvc2l0aW9uIGlmIHRoaXMgYXR0cmlidXRlIHR5cGUgaXMgYSBVUkwuICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQVRUUlVSTCA9ICgxIDw8IDEpOwotCi0gIC8qKiBCaXQgcG9zaXRpb24gaWYgdGhpcyBhdHRyaWJ1dGUgdHlwZSBpcyBhbiBlbXB0eSB0eXBlLiAqLwotICBzdGF0aWMgZmluYWwgaW50IEFUVFJFTVBUWSA9ICgxIDw8IDIpOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gRWxlbURlc2MgZnJvbSBhIHNldCBvZiBiaXQgZmxhZ3MuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBmbGFncyBCaXQgZmxhZ3MgdGhhdCBkZXNjcmliZSB0aGUgYmFzaWMgcHJvcGVydGllcyBvZiB0aGlzIGVsZW1lbnQgdHlwZS4KLSAgICovCi0gIEVsZW1EZXNjKGludCBmbGFncykKLSAgewotICAgIG1fZmxhZ3MgPSBmbGFnczsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZWxlbWVudCB0eXBlIGhhcyB0aGUgYmFzaWMgYml0IHByb3BlcnRpZXMgdGhhdCBhcmUgcGFzc2VkCi0gICAqIGFzIGFuIGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gZmxhZ3MgQml0IGZsYWdzIHRoYXQgZGVzY3JpYmUgdGhlIGJhc2ljIHByb3BlcnRpZXMgb2YgaW50ZXJlc3QuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBhbnkgb2YgdGhlIGZsYWcgYml0cyBhcmUgdHJ1ZS4KLSAgICovCi0gIGJvb2xlYW4gaXMoaW50IGZsYWdzKQotICB7Ci0KLSAgICAvLyBpbnQgd2hpY2ggPSAobV9mbGFncyAmIGZsYWdzKTsKLSAgICByZXR1cm4gKG1fZmxhZ3MgJiBmbGFncykgIT0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gYXR0cmlidXRlIG5hbWUgYW5kIGl0J3MgYml0IHByb3BlcnRpZXMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIG5vbi1udWxsIG5hbWUgb2YgYXR0cmlidXRlLCBpbiB1cHBlciBjYXNlLgotICAgKiBAcGFyYW0gZmxhZ3MgZmxhZyBiaXRzLgotICAgKi8KLSAgdm9pZCBzZXRBdHRyKFN0cmluZyBuYW1lLCBpbnQgZmxhZ3MpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fYXR0cnMpCi0gICAgICBtX2F0dHJzID0gbmV3IFN0cmluZ1RvSW50VGFibGUoKTsKLQotICAgIG1fYXR0cnMucHV0KG5hbWUsIGZsYWdzKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIGFueSBvZiB0aGUgYml0cyBvZiBpbnRlcmVzdCBhcmUgc2V0IGZvciBhIG5hbWVkIGF0dHJpYnV0ZSB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gYXR0cmlidXRlIG5hbWUsIGluIGFueSBjYXNlLgotICAgKiBAcGFyYW0gZmxhZ3MgZmxhZyBtYXNrLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgYW55IG9mIHRoZSBmbGFncyBhcmUgc2V0IGZvciB0aGUgbmFtZWQgYXR0cmlidXRlLgotICAgKi8KLSAgYm9vbGVhbiBpc0F0dHJGbGFnU2V0KFN0cmluZyBuYW1lLCBpbnQgZmxhZ3MpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9hdHRycykgPyAoKG1fYXR0cnMuZ2V0SWdub3JlQ2FzZShuYW1lKSAmIGZsYWdzKSAhPSAwKSA6IGZhbHNlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvRW5jb2RpbmdJbmZvLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvRW5jb2RpbmdJbmZvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEyZTEyZGMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL0VuY29kaW5nSW5mby5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLS8qKgotICogSG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgYSBnaXZlbiBlbmNvZGluZy4KLSAqLwotcHVibGljIGNsYXNzIEVuY29kaW5nSW5mbyBleHRlbmRzIE9iamVjdAotewotCi0gIC8qKgotICAgKiBUaGUgZW5jb2RpbmcgbmFtZS4KLSAgICovCi0gIGZpbmFsIFN0cmluZyBuYW1lOwotCi0gIC8qKgotICAgKiBUaGUgbmFtZSB1c2VkIGJ5IHRoZSBKYXZhIGNvbnZlcnRvci4KLSAgICovCi0gIGZpbmFsIFN0cmluZyBqYXZhTmFtZTsKLQotICAvKioKLSAgICogVGhlIGxhc3QgcHJpbnRhYmxlIGNoYXJhY3Rlci4KLSAgICovCi0gIGZpbmFsIGludCBsYXN0UHJpbnRhYmxlOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gRW5jb2RpbmdJbmZvIG9iamVjdCBiYXNlZCBvbiB0aGUgbmFtZSwgamF2YSBuYW1lLCBhbmQgdGhlIAotICAgKiBtYXggY2hhcmFjdGVyIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgSVNPIG5hbWUuCi0gICAqIEBwYXJhbSBqYXZhTmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIEphdmEgZW5jb2RpbmcgbmFtZS4KLSAgICogQHBhcmFtIGxhc3RQcmludGFibGUgVGhlIG1heGltdW0gY2hhcmFjdGVyIHRoYXQgY2FuIGJlIHdyaXR0ZW4uCi0gICAqLwotICBwdWJsaWMgRW5jb2RpbmdJbmZvKFN0cmluZyBuYW1lLCBTdHJpbmcgamF2YU5hbWUsIGludCBsYXN0UHJpbnRhYmxlKQotICB7Ci0KLSAgICB0aGlzLm5hbWUgPSBuYW1lOwotICAgIHRoaXMuamF2YU5hbWUgPSBqYXZhTmFtZTsKLSAgICB0aGlzLmxhc3RQcmludGFibGUgPSBsYXN0UHJpbnRhYmxlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvRW5jb2RpbmdzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvRW5jb2RpbmdzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2NGEyYjYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL0VuY29kaW5ncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzYyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOwotCi1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwotCi0vKioKLSAqIFByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGVuY29kaW5ncy4gRGVwZW5kcyBvbiB0aGUgSmF2YSBydW50aW1lCi0gKiB0byBwcm92aWRlcyB3cml0ZXJzIGZvciB0aGUgZGlmZmVyZW50IGVuY29kaW5ncywgYnV0IGNhbiBiZSB1c2VkCi0gKiB0byBvdmVycmlkZSBlbmNvZGluZyBuYW1lcyBhbmQgcHJvdmlkZSB0aGUgbGFzdCBwcmludGFibGUgY2hhcmFjdGVyCi0gKiBmb3IgZWFjaCBlbmNvZGluZy4KLSAqCi0gKiBAdmVyc2lvbiAkUmV2aXNpb24kICREYXRlJAotICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86YXJraW5AaW50YWxpby5jb20iPkFzc2FmIEFya2luPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRW5jb2RpbmdzIGV4dGVuZHMgT2JqZWN0Ci17Ci0KLSAgLyoqCi0gICAqIFRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIgZm9yIHVua25vd24gZW5jb2RpbmdzLgotICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBtX2RlZmF1bHRMYXN0UHJpbnRhYmxlID0gMHg3RjsKLQotICAvKioKLSAgICogUmV0dXJucyBhIHdyaXRlciBmb3IgdGhlIHNwZWNpZmllZCBlbmNvZGluZyBiYXNlZCBvbgotICAgKiBhbiBvdXRwdXQgc3RyZWFtLgotICAgKgotICAgKiBAcGFyYW0gb3V0cHV0IFRoZSBvdXRwdXQgc3RyZWFtCi0gICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgZW5jb2RpbmcKLSAgICogQHJldHVybiBBIHN1aXRhYmxlIHdyaXRlcgotICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gVGhlcmUgaXMgbm8gY29udmVydG9yCi0gICAqICB0byBzdXBwb3J0IHRoaXMgZW5jb2RpbmcKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgV3JpdGVyIGdldFdyaXRlcihPdXRwdXRTdHJlYW0gb3V0cHV0LCBTdHJpbmcgZW5jb2RpbmcpCi0gICAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfZW5jb2RpbmdzLmxlbmd0aDsgKytpKQotICAgIHsKLSAgICAgIGlmIChfZW5jb2RpbmdzW2ldLm5hbWUuZXF1YWxzSWdub3JlQ2FzZShlbmNvZGluZykpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0cHV0LCBfZW5jb2RpbmdzW2ldLmphdmFOYW1lKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCggamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIC8vIGphdmEgMS4xLjgKLSAgICAgICAgewotICAgICAgICAgIC8vIGtlZXAgdHJ5aW5nCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdXNlZSkKLSAgICAgICAgewotCi0gICAgICAgICAgLy8ga2VlcCB0cnlpbmcKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dHB1dCwgZW5jb2RpbmcpOwotICAgIH0KLSAgICBjYXRjaCggamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIC8vIGphdmEgMS4xLjgKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbihlbmNvZGluZyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxhc3QgcHJpbnRhYmxlIGNoYXJhY3RlciBmb3IgdGhlIHNwZWNpZmllZAotICAgKiBlbmNvZGluZy4KLSAgICoKLSAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBlbmNvZGluZwotICAgKiBAcmV0dXJuIFRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGdldExhc3RQcmludGFibGUoU3RyaW5nIGVuY29kaW5nKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IF9lbmNvZGluZ3MubGVuZ3RoOyArK2kpCi0gICAgewotICAgICAgaWYgKF9lbmNvZGluZ3NbaV0ubmFtZS5lcXVhbHNJZ25vcmVDYXNlKGVuY29kaW5nKQotICAgICAgICAgICAgICB8fCBfZW5jb2RpbmdzW2ldLmphdmFOYW1lLmVxdWFsc0lnbm9yZUNhc2UoZW5jb2RpbmcpKQotICAgICAgICByZXR1cm4gX2VuY29kaW5nc1tpXS5sYXN0UHJpbnRhYmxlOwotICAgIH0KLQotICAgIHJldHVybiBtX2RlZmF1bHRMYXN0UHJpbnRhYmxlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxhc3QgcHJpbnRhYmxlIGNoYXJhY3RlciBmb3IgYW4gdW5zcGVjaWZpZWQKLSAgICogZW5jb2RpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgc2l6ZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TGFzdFByaW50YWJsZSgpCi0gIHsKLSAgICByZXR1cm4gbV9kZWZhdWx0TGFzdFByaW50YWJsZTsKLSAgfQotCi0gIC8qKiBUaGUgZGVmYXVsdCBlbmNvZGluZywgSVNPIHN0eWxlLCBJU08gc3R5bGUuICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9NSU1FX0VOQ09ESU5HID0gIlVURi04IjsKLQotICAvKioKLSAgICogR2V0IHRoZSBwcm9wZXIgbWltZSBlbmNvZGluZy4gIEZyb20gdGhlIFhTTFQgcmVjb21tZW5kYXRpb246ICJUaGUgZW5jb2RpbmcKLSAgICogYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgcHJlZmVycmVkIGVuY29kaW5nIHRvIHVzZSBmb3Igb3V0cHV0dGluZyB0aGUgcmVzdWx0Ci0gICAqIHRyZWUuIFhTTFQgcHJvY2Vzc29ycyBhcmUgcmVxdWlyZWQgdG8gcmVzcGVjdCB2YWx1ZXMgb2YgVVRGLTggYW5kIFVURi0xNi4KLSAgICogRm9yIG90aGVyIHZhbHVlcywgaWYgdGhlIFhTTFQgcHJvY2Vzc29yIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNwZWNpZmllZAotICAgKiBlbmNvZGluZyBpdCBtYXkgc2lnbmFsIGFuIGVycm9yOyBpZiBpdCBkb2VzIG5vdCBzaWduYWwgYW4gZXJyb3IgaXQgc2hvdWxkCi0gICAqIHVzZSBVVEYtOCBvciBVVEYtMTYgaW5zdGVhZC4gVGhlIFhTTFQgcHJvY2Vzc29yIG11c3Qgbm90IHVzZSBhbiBlbmNvZGluZwotICAgKiB3aG9zZSBuYW1lIGRvZXMgbm90IG1hdGNoIHRoZSBFbmNOYW1lIHByb2R1Y3Rpb24gb2YgdGhlIFhNTCBSZWNvbW1lbmRhdGlvbgotICAgKiBbWE1MXS4gSWYgbm8gZW5jb2RpbmcgYXR0cmlidXRlIGlzIHNwZWNpZmllZCwgdGhlbiB0aGUgWFNMVCBwcm9jZXNzb3Igc2hvdWxkCi0gICAqIHVzZSBlaXRoZXIgVVRGLTggb3IgVVRGLTE2LiIKLSAgICoKLSAgICogQHBhcmFtIGVuY29kaW5nIFJlZmVyZW5jZSB0byBqYXZhLXN0eWxlIGVuY29kaW5nIHN0cmluZywgd2hpY2ggbWF5IGJlIG51bGwsIAotICAgKiBpbiB3aGljaCBjYXNlIGEgZGVmYXVsdCB3aWxsIGJlIGZvdW5kLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBJU08tc3R5bGUgZW5jb2Rpbmcgc3RyaW5nLCBvciBudWxsIGlmIGZhaWx1cmUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRNaW1lRW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBlbmNvZGluZykKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLQotICAgICAgICAvLyBHZXQgdGhlIGRlZmF1bHQgc3lzdGVtIGNoYXJhY3RlciBlbmNvZGluZy4gIFRoaXMgbWF5IGJlIAotICAgICAgICAvLyBpbmNvcnJlY3QgaWYgdGhleSBwYXNzZWQgaW4gYSB3cml0ZXIsIGJ1dCByaWdodCBub3cgdGhlcmUgCi0gICAgICAgIC8vIHNlZW1zIHRvIGJlIG5vIHdheSB0byBnZXQgdGhlIGVuY29kaW5nIGZyb20gYSB3cml0ZXIuCi0gICAgICAgIGVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIiwgIlVURjgiKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBlbmNvZGluZykKLSAgICAgICAgewotCi0gICAgICAgICAgLyoKLSAgICAgICAgICAqIFNlZSBpZiB0aGUgbWltZSB0eXBlIGlzIGVxdWFsIHRvIFVURjguICBJZiB5b3UgZG9uJ3QKLSAgICAgICAgICAqIGRvIHRoYXQsIHRoZW4gIGNvbnZlcnRKYXZhMk1pbWVFbmNvZGluZyB3aWxsIGNvbnZlcnQKLSAgICAgICAgICAqIDg4NTlfMSB0byAiSVNPLTg4NTktMSIsIHdoaWNoIGlzIG5vdCB3aGF0IHdlIHdhbnQsCi0gICAgICAgICAgKiBJIHRoaW5rLCBhbmQgSSBkb24ndCB0aGluayBJIHdhbnQgdG8gYWx0ZXIgdGhlIHRhYmxlcwotICAgICAgICAgICogdG8gY29udmVydCBldmVyeXRoaW5nIHRvIFVURi04LgotICAgICAgICAgICovCi0gICAgICAgICAgU3RyaW5nIGplbmNvZGluZyA9Ci0gICAgICAgICAgICAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiQ3AxMjUyIikgfHwgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgKLSAgICAgICAgICAgICJJU084ODU5XzEiKSB8fCBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCI4ODU5XzEiKSB8fCBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJVVEY4IikpID8gREVGQVVMVF9NSU1FX0VOQ09ESU5HCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbnZlcnRKYXZhMk1pbWVFbmNvZGluZygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcpOwotCi0gICAgICAgICAgZW5jb2RpbmcgPSAobnVsbCAhPSBqZW5jb2RpbmcpID8gamVuY29kaW5nIDogREVGQVVMVF9NSU1FX0VOQ09ESU5HOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGVuY29kaW5nID0gREVGQVVMVF9NSU1FX0VOQ09ESU5HOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpCi0gICAgICB7Ci0gICAgICAgIGVuY29kaW5nID0gREVGQVVMVF9NSU1FX0VOQ09ESU5HOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgZW5jb2RpbmcgPSBjb252ZXJ0SmF2YTJNaW1lRW5jb2RpbmcoZW5jb2RpbmcpOwotICAgIH0KLQotICAgIHJldHVybiBlbmNvZGluZzsKLSAgfQotCi0gIC8qKgotICAgKiBUcnkgdGhlIGJlc3Qgd2UgY2FuIHRvIGNvbnZlcnQgYSBKYXZhIGVuY29kaW5nIHRvIGEgWE1MLXN0eWxlIGVuY29kaW5nLgotICAgKgotICAgKiBAcGFyYW0gZW5jb2Rpbmcgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGVuY29kaW5nIHN0cmluZywgamF2YSBzdHlsZS4KLSAgICoKLSAgICogQHJldHVybiBJU08tc3R5bGUgZW5jb2Rpbmcgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgY29udmVydEphdmEyTWltZUVuY29kaW5nKFN0cmluZyBlbmNvZGluZykKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfZW5jb2RpbmdzLmxlbmd0aDsgKytpKQotICAgIHsKLSAgICAgIGlmIChfZW5jb2RpbmdzW2ldLmphdmFOYW1lLmVxdWFsc0lnbm9yZUNhc2UoZW5jb2RpbmcpKQotICAgICAgewotICAgICAgICByZXR1cm4gX2VuY29kaW5nc1tpXS5uYW1lOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBlbmNvZGluZzsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRyeSB0aGUgYmVzdCB3ZSBjYW4gdG8gY29udmVydCBhIEphdmEgZW5jb2RpbmcgdG8gYSBYTUwtc3R5bGUgZW5jb2RpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBlbmNvZGluZyBub24tbnVsbCByZWZlcmVuY2UgdG8gZW5jb2Rpbmcgc3RyaW5nLCBqYXZhIHN0eWxlLgotICAgKgotICAgKiBAcmV0dXJuIElTTy1zdHlsZSBlbmNvZGluZyBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBjb252ZXJ0TWltZTJKYXZhRW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IF9lbmNvZGluZ3MubGVuZ3RoOyArK2kpCi0gICAgewotICAgICAgaWYgKF9lbmNvZGluZ3NbaV0ubmFtZS5lcXVhbHNJZ25vcmVDYXNlKGVuY29kaW5nKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIF9lbmNvZGluZ3NbaV0uamF2YU5hbWU7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGVuY29kaW5nOwotICB9Ci0KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhIGxpc3Qgb2YgYWxsIHRoZSBzdXBwb3J0ZWQgZW5jb2RpbmdzLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5jb2RpbmdJbmZvW10gX2VuY29kaW5ncyA9IG5ldyBFbmNvZGluZ0luZm9bXQotICB7Ci0KLSAgICAvLyAgICA8cHJlZmVycmVkIE1JTUUgbmFtZT4sIDxKYXZhIGVuY29kaW5nIG5hbWU+Ci0gICAgLy8gbmV3IEVuY29kaW5nSW5mbyggIklTTyA4ODU5LTEiLCAiQ1AxMjUyIik7IC8vIENsb3NlIGVub3VnaCwgSSBndWVzcwotICAgIG5ldyBFbmNvZGluZ0luZm8oIldJTkRPV1MtMTI1MCIsICJDcDEyNTAiLCAweDAwRkYpLCAgLy8gUGV0ZXIgU21vbGlrCi0gICAgLy8gUGF0Y2ggYXR0cmlidXRlZCB0byBoYXZhcmR3QHVuZGVyZHVza2VuLm5vIChI5XZhcmQgV2lndGlsKQotICAgIG5ldyBFbmNvZGluZ0luZm8oIldJTkRPV1MtMTI1MiIsICJDcDEyNTIiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIlVURi04IiwgIlVURjgiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIlVTLUFTQ0lJIiwgIklTTzg4NTlfMSIsIDB4N0YpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTEiLCAiSVNPODg1OV8xIiwgMHgwMEZGKSwKLSAgICAvLyBQYXRjaCBhdHRyaWJ1dGVkIHRvIGhhdmFyZHdAdW5kZXJkdXNrZW4ubm8gKEjldmFyZCBXaWd0aWwpCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMSIsICJJU084ODU5LTEiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTIiLCAiSVNPODg1OV8yIiwgMHgwMEZGKSwKLSAgICAvLyBJJ20gZ29pbmcgdG8gYXBwbHkgIklTTzg4NTktWCIgdmFyaWFudCB0byBhbGwgdGhlc2UsIHRvIGJlIHNhZmUuCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMiIsICJJU084ODU5LTIiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTMiLCAiSVNPODg1OV8zIiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS0zIiwgIklTTzg4NTktMyIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNCIsICJJU084ODU5XzQiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTQiLCAiSVNPODg1OS00IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS01IiwgIklTTzg4NTlfNSIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNSIsICJJU084ODU5LTUiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTYiLCAiSVNPODg1OV82IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS02IiwgIklTTzg4NTktNiIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNyIsICJJU084ODU5XzciLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTciLCAiSVNPODg1OS03IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS04IiwgIklTTzg4NTlfOCIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOCIsICJJU084ODU5LTgiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTkiLCAiSVNPODg1OV85IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS05IiwgIklTTzg4NTktOSIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiVVMtQVNDSUkiLCAiODg1OV8xIiwgMHgwMEZGKSwgIC8vID8KLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS0xIiwgIjg4NTlfMSIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMiIsICI4ODU5XzIiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTMiLCAiODg1OV8zIiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS00IiwgIjg4NTlfNCIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNSIsICI4ODU5XzUiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTYiLCAiODg1OV82IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS03IiwgIjg4NTlfNyIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOCIsICI4ODU5XzgiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTkiLCAiODg1OV85IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS0xIiwgIjg4NTktMSIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMiIsICI4ODU5LTIiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTMiLCAiODg1OS0zIiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS00IiwgIjg4NTktNCIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNSIsICI4ODU5LTUiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTYiLCAiODg1OS02IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tODg1OS03IiwgIjg4NTktNyIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOCIsICI4ODU5LTgiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTkiLCAiODg1OS05IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tMjAyMi1KUCIsICJKSVMiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIlNISUZUX0pJUyIsICJTSklTIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtSlAiLCAiRVVDX0pQIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtS1IiLCAiRVVDX0tSIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtQ04iLCAiRVVDX0NOIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtVFciLCAiRVVDX1RXIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJHQjIzMTIiLCAiRVVDX0NOIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtSlAiLCAiRVVDLUpQIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtS1IiLCAiRVVDLUtSIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtQ04iLCAiRVVDLUNOIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtVFciLCAiRVVDLVRXIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJHQjIzMTIiLCAiRVVDLUNOIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJHQjIzMTIiLCAiR0IyMzEyIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJCSUc1IiwgIkJpZzUiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVVQy1KUCIsICJFVUNKSVMiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVVQy1LUiIsICJLU0M1NjAxIiwgMHhGRkZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tMjAyMi1LUiIsICJJU08yMDIyS1IiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIktPSTgtUiIsICJLT0k4X1IiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1VUyIsICJDcDAzNyIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLUNBIiwgIkNwMDM3IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtTkwiLCAiQ3AwMzciLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1ESyIsICJDcDI3NyIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLU5PIiwgIkNwMjc3IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtRkkiLCAiQ3AyNzgiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1TRSIsICJDcDI3OCIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLUlUIiwgIkNwMjgwIiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtRVMiLCAiQ3AyODQiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1HQiIsICJDcDI4NSIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLUZSIiwgIkNwMjk3IiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtQVIxIiwgIkNwNDIwIiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtSEUiLCAiQ3A0MjQiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1DSCIsICJDcDUwMCIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLVJPRUNFIiwgIkNwODcwIiwgMHgwMEZGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtWVUiLCAiQ3A4NzAiLCAweDAwRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1JUyIsICJDcDg3MSIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLUFSMiIsICJDcDkxOCIsIDB4MDBGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiTWFjUm9tYW4iLCAiTWFjVEVDIiwgMHhGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiQVNDSUkiLCAiQVNDSUkiLCAweDdGKSwKLSAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tTGF0aW4tMSIsICJBU0NJSSIsIDB4RkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIlVURi04IiwgIlVURjgiLCAweEZGRkYpLAotICAgIG5ldyBFbmNvZGluZ0luZm8oIlVOSUNPREUiLCAiVW5pY29kZSIsIDB4RkZGRiksCi0gICAgbmV3IEVuY29kaW5nSW5mbygiVVRGLTE2IiwgIlVuaWNvZGUiLCAweEZGRkYpCi0gIH07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvSFRNTEVudGl0aWVzLnJlcyBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9IVE1MRW50aXRpZXMucmVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYzA2YWI4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9IVE1MRW50aXRpZXMucmVzCisrKyAvZGV2L251bGwKQEAgLTEsMjkyICswLDAgQEAKLSMgJElkJAotIwotIyBAdmVyc2lvbiAkUmV2aXNpb24kICREYXRlJAotIyBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzphcmtpbkBpbnRhbGlvLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0jCi0jIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBmb3IgbWFya3VwLXNpZ25pZmljYW50Ci0jCi1xdW90IDM0Ci1hbXAgMzgKLWx0IDYwCi1ndCA2MgotbmJzcCAxNjAKLSMKLSMgQ2hhcmFjdGVyIGVudGl0eSByZWZlcmVuY2VzIGZvciBJU08gODg1OS0xIGNoYXJhY3RlcnMKLSMKLWlleGNsIDE2MQotY2VudCAxNjIKLXBvdW5kIDE2MwotY3VycmVuIDE2NAoteWVuIDE2NQotYnJ2YmFyIDE2Ngotc2VjdCAxNjcKLXVtbCAxNjgKLWNvcHkgMTY5Ci1vcmRmIDE3MAotbGFxdW8gMTcxCi1ub3QgMTcyCi1zaHkgMTczCi1yZWcgMTc0Ci1tYWNyIDE3NQotZGVnIDE3NgotcGx1c21uIDE3Nwotc3VwMiAxNzgKLXN1cDMgMTc5Ci1hY3V0ZSAxODAKLW1pY3JvIDE4MQotcGFyYSAxODIKLW1pZGRvdCAxODMKLWNlZGlsIDE4NAotc3VwMSAxODUKLW9yZG0gMTg2Ci1yYXF1byAxODcKLWZyYWMxNCAxODgKLWZyYWMxMiAxODkKLWZyYWMzNCAxOTAKLWlxdWVzdCAxOTEKLUFncmF2ZSAxOTIKLUFhY3V0ZSAxOTMKLUFjaXJjIDE5NAotQXRpbGRlIDE5NQotQXVtbCAxOTYKLUFyaW5nIDE5NwotQUVsaWcgMTk4Ci1DY2VkaWwgMTk5Ci1FZ3JhdmUgMjAwCi1FYWN1dGUgMjAxCi1FY2lyYyAyMDIKLUV1bWwgMjAzCi1JZ3JhdmUgMjA0Ci1JYWN1dGUgMjA1Ci1JY2lyYyAyMDYKLUl1bWwgMjA3Ci1FVEggMjA4Ci1OdGlsZGUgMjA5Ci1PZ3JhdmUgMjEwCi1PYWN1dGUgMjExCi1PY2lyYyAyMTIKLU90aWxkZSAyMTMKLU91bWwgMjE0Ci10aW1lcyAyMTUKLU9zbGFzaCAyMTYKLVVncmF2ZSAyMTcKLVVhY3V0ZSAyMTgKLVVjaXJjIDIxOQotVXVtbCAyMjAKLVlhY3V0ZSAyMjEKLVRIT1JOIDIyMgotc3psaWcgMjIzCi1hZ3JhdmUgMjI0Ci1hYWN1dGUgMjI1Ci1hY2lyYyAyMjYKLWF0aWxkZSAyMjcKLWF1bWwgMjI4Ci1hcmluZyAyMjkKLWFlbGlnIDIzMAotY2NlZGlsIDIzMQotZWdyYXZlIDIzMgotZWFjdXRlIDIzMwotZWNpcmMgMjM0Ci1ldW1sIDIzNQotaWdyYXZlIDIzNgotaWFjdXRlIDIzNwotaWNpcmMgMjM4Ci1pdW1sIDIzOQotZXRoIDI0MAotbnRpbGRlIDI0MQotb2dyYXZlIDI0Mgotb2FjdXRlIDI0Mwotb2NpcmMgMjQ0Ci1vdGlsZGUgMjQ1Ci1vdW1sIDI0NgotZGl2aWRlIDI0Nwotb3NsYXNoIDI0OAotdWdyYXZlIDI0OQotdWFjdXRlIDI1MAotdWNpcmMgMjUxCi11dW1sIDI1MgoteWFjdXRlIDI1MwotdGhvcm4gMjU0Ci15dW1sIDI1NQotIwotIyBDaGFyYWN0ZXIgZW50aXR5IHJlZmVyZW5jZXMgZm9yIHN5bWJvbHMsIG1hdGhlbWF0aWNhbCBzeW1ib2xzLCBhbmQgR3JlZWsgbGV0dGVycwotIwotIyBMYXRpbiBFeHRlbmRlZAotZm5vZiA0MDIKLSMKLSMgR3JlZWsKLUFscGhhIDkxMwotQmV0YSA5MTQKLUdhbW1hIDkxNQotRGVsdGEgOTE2Ci1FcHNpbG9uIDkxNwotWmV0YSA5MTgKLUV0YSA5MTkKLVRoZXRhIDkyMAotSW90YSA5MjEKLUthcHBhIDkyMgotTGFtYmRhIDkyMwotTXUgOTI0Ci1OdSA5MjUKLVhpIDkyNgotT21pY3JvbiA5MjcKLVBpIDkyOAotUmhvIDkyOQotU2lnbWEgOTMxCi1UYXUgOTMyCi1VcHNpbG9uIDkzMwotUGhpIDkzNAotQ2hpIDkzNQotUHNpIDkzNgotT21lZ2EgOTM3Ci1hbHBoYSA5NDUKLWJldGEgOTQ2Ci1nYW1tYSA5NDcKLWRlbHRhIDk0OAotZXBzaWxvbiA5NDkKLXpldGEgOTUwCi1ldGEgOTUxCi10aGV0YSA5NTIKLWlvdGEgOTUzCi1rYXBwYSA5NTQKLWxhbWJkYSA5NTUKLW11IDk1NgotbnUgOTU3Ci14aSA5NTgKLW9taWNyb24gOTU5Ci1waSA5NjAKLXJobyA5NjEKLXNpZ21hZiA5NjIKLXNpZ21hIDk2MwotdGF1IDk2NAotdXBzaWxvbiA5NjUKLXBoaSA5NjYKLWNoaSA5NjcKLXBzaSA5NjgKLW9tZWdhIDk2OQotdGhldGFzeW0gOTc3Ci11cHNpaCA5NzgKLXBpdiA5ODIKLSMKLSMgR2VuZXJhbCBQdW5jdHVhdGlvbgotYnVsbCA4MjI2Ci1oZWxsaXAgODIzMAotcHJpbWUgODI0MgotUHJpbWUgODI0Mwotb2xpbmUgODI1NAotZnJhc2wgODI2MAotIwotIyBMZXR0ZXJsaWtlIFN5bWJvbHMKLXdlaWVycCA4NDcyCi1pbWFnZSA4NDY1Ci1yZWFsIDg0NzYKLXRyYWRlIDg0ODIKLWFsZWZzeW0gODUwMQotIwotIyBBcnJvd3MKLWxhcnIgODU5MgotdWFyciA4NTkzCi1yYXJyIDg1OTQKLWRhcnIgODU5NQotaGFyciA4NTk2Ci1jcmFyciA4NjI5Ci1sQXJyIDg2NTYKLXVBcnIgODY1NwotckFyciA4NjU4Ci1kQXJyIDg2NTkKLWhBcnIgODY2MAotIwotIyBNYXRoZW1hdGljYWwgT3BlcmF0b3JzCi1mb3JhbGwgODcwNAotcGFydCA4NzA2Ci1leGlzdCA4NzA3Ci1lbXB0eSA4NzA5Ci1uYWJsYSA4NzExCi1pc2luIDg3MTIKLW5vdGluIDg3MTMKLW5pIDg3MTUKLXByb2QgODcxOQotc3VtIDg3MjEKLW1pbnVzIDg3MjIKLWxvd2FzdCA4NzI3Ci1yYWRpYyA4NzMwCi1wcm9wIDg3MzMKLWluZmluIDg3MzQKLWFuZyA4NzM2Ci1hbmQgODc0Mwotb3IgODc0NAotY2FwIDg3NDUKLWN1cCA4NzQ2Ci1pbnQgODc0NwotdGhlcmU0IDg3NTYKLXNpbSA4NzY0Ci1jb25nIDg3NzMKLWFzeW1wIDg3NzYKLW5lIDg4MDAKLWVxdWl2IDg4MDEKLWxlIDg4MDQKLWdlIDg4MDUKLXN1YiA4ODM0Ci1zdXAgODgzNQotbnN1YiA4ODM2Ci1zdWJlIDg4MzgKLXN1cGUgODgzOQotb3BsdXMgODg1Mwotb3RpbWVzIDg4NTUKLXBlcnAgODg2OQotc2RvdCA4OTAxCi0jCi0jIE1pc2NlbGxhbmVvdXMgVGVjaG5pY2FsCi1sY2VpbCA4OTY4Ci1yY2VpbCA4OTY5Ci1sZmxvb3IgODk3MAotcmZsb29yIDg5NzEKLWxhbmcgOTAwMQotcmFuZyA5MDAyCi0jCi0jIEdlb21ldHJpYyBTaGFwZXMKLWxveiA5Njc0Ci0jCi0jIE1pc2NlbGxhbmVvdXMgU3ltYm9scwotc3BhZGVzIDk4MjQKLWNsdWJzIDk4MjcKLWhlYXJ0cyA5ODI5Ci1kaWFtcyA5ODMwCi0jCi0jIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBmb3IgaW50ZXJuYXRpb25hbGl6YXRpb24gY2hhcmFjdGVycwotIwotIyBMYXRpbiBFeHRlbmRlZC1BCi1PRWxpZyAzMzgKLW9lbGlnIDMzOQotCi0jLS0gTk4gNC43IGRvZXMgbm90IHNlZW0gdG8gc3VwcG9ydCB0aGVzZSwgc28gdGhleSBtaWdodCBvdWdodCB0byBiZSBjb21tZW50ZWQuCi1TY2Fyb24gMzUyCi1zY2Fyb24gMzUzCi1ZdW1sIDM3NgotIwotIyBTcGFjaW5nIE1vZGlmaWVyIExldHRlcnMKLWNpcmMgNzEwCi10aWxkZSA3MzIKLSMKLSMgR2VuZXJhbCBQdW5jdHVhdGlvbgotZW5zcCA4MTk0Ci1lbXNwIDgxOTUKLXRoaW5zcCA4MjAxCi16d25qIDgyMDQKLXp3aiA4MjA1Ci1scm0gODIwNgotcmxtIDgyMDcKLW5kYXNoIDgyMTEKLW1kYXNoIDgyMTIKLWxzcXVvIDgyMTYKLXJzcXVvIDgyMTcKLXNicXVvIDgyMTgKLWxkcXVvIDgyMjAKLXJkcXVvIDgyMjEKLWJkcXVvIDgyMjIKLWRhZ2dlciA4MjI0Ci1EYWdnZXIgODIyNQotcGVybWlsIDgyNDAKLWxzYXF1byA4MjQ5Ci1yc2FxdW8gODI1MAotZXVybyA4MzY0CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvTWV0aG9kLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvTWV0aG9kLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZjMGZmN2EuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL01ldGhvZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLS8qKgotICogTmFtZXMgb2YgdGhlIGZvdXIgZGVmYXVsdCBvdXRwdXQgbWV0aG9kcy4KLSAqIDxwPgotICogRm91ciBkZWZhdWx0IG91dHB1dCBtZXRob2RzIGFyZSBkZWZpbmVkOiBYTUwsIEhUTUwsIFhIVE1MIGFuZCBURVhULgotICogU2VyaWFsaXplcnMgbWF5IHN1cHBvcnQgYWRkaXRpb25hbCBvdXRwdXQgbWV0aG9kcy4gVGhlIG5hbWVzIG9mCi0gKiB0aGVzZSBvdXRwdXQgbWV0aG9kcyBzaG91bGQgYmUgZW5jb2RlZCBhcyA8dHQ+bmFtZXNwYWNlOmxvY2FsPC90dD4uCi0gKgotICogQHZlcnNpb24gQWxwaGEKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGV4b2ZmaWNlLmNvbSI+QXNzYWYgQXJraW48L2E+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBNZXRob2QKLXsKLQotICAvKioKLSAgICogVGhlIG91dHB1dCBtZXRob2QgZm9yIFhNTCBkb2N1bWVudHM6IDx0dD54bWw8L3R0Pi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTCA9ICJ4bWwiOwotCi0gIC8qKgotICAgKiBUaGUgb3V0cHV0IG1ldGhvZCBmb3IgSFRNTCBkb2N1bWVudHM6IDx0dD5odG1sPC90dD4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIVE1MID0gImh0bWwiOwotCi0gIC8qKgotICAgKiBUaGUgb3V0cHV0IG1ldGhvZCBmb3IgWEhUTUwgZG9jdW1lbnRzOiA8dHQ+eGh0bWw8L3R0Pi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhIVE1MID0gInhodG1sIjsKLQotICAvKioKLSAgICogVGhlIG91dHB1dCBtZXRob2QgZm9yIHRleHQgZG9jdW1lbnRzOiA8dHQ+dGV4dDwvdHQ+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVGV4dCA9ICJ0ZXh0IjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9TZXJpYWxpemVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvU2VyaWFsaXplci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5YTA4M2Q5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9TZXJpYWxpemVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLS8qKgotICogVGhlIFNlcmlhbGl6ZXIgaW50ZXJmYWNlIGlzIGltcGxlbWVudGVkIGJ5IFNlcmlhbGl6ZXJzIHRvIHB1Ymxpc2ggbWV0aG9kcyAKLSAqIHRvIGdldCBhbmQgc2V0IHN0cmVhbXMgYW5kIHdyaXRlcnMsIHRvIHNldCB0aGUgb3V0cHV0IHByb3BlcnRpZXMsIGFuZCAKLSAqIGdldCB0aGUgU2VyaWFsaXplciBhcyBhIENvbnRlbnRIYW5kbGVyIG9yIERPTVNlcmlhbGl6ZXIuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgU2VyaWFsaXplcgotewotCi0gIC8qKgotICAgKiBTcGVjaWZpZXMgYW4gb3V0cHV0IHN0cmVhbSB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlCi0gICAqIHNlcmlhbGl6ZWQuIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIHdoaWxlIHRoZQotICAgKiBzZXJpYWxpemVyIGlzIGluIHRoZSBwcm9jZXNzIG9mIHNlcmlhbGl6aW5nIGEgZG9jdW1lbnQuCi0gICAqIDxwPgotICAgKiBUaGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBvdXRwdXQge0BsaW5rIFByb3BlcnRpZXN9IGlzIHVzZWQsIG9yCi0gICAqIGlmIG5vIGVuY29kaW5nIHdhcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGZvciB0aGUgc2VsZWN0ZWQKLSAgICogb3V0cHV0IG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIG91dHB1dCBzdHJlYW0gd2hlcmUgdGhlIGV2ZW50cyB3aWxsIGJlIHNlcmlhbGl6ZWQgdG8uCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSByZXN1bHQgc3RyZWFtLCBvciBudWxsIG9mIG9ubHkgYSB3cml0ZXIgd2FzCi0gICAqIHNldC4KLSAgICovCi0gIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCk7Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmllcyBhIHdyaXRlciB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuCi0gICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIHdoaWxlIHRoZSBzZXJpYWxpemVyIGlzIGluCi0gICAqIHRoZSBwcm9jZXNzIG9mIHNlcmlhbGl6aW5nIGEgZG9jdW1lbnQuCi0gICAqIDxwPgotICAgKiBUaGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGZvciB0aGUgb3V0cHV0IHtAbGluayBQcm9wZXJ0aWVzfSBtdXN0IGJlCi0gICAqIGlkZW50aWNhbCB0byB0aGUgb3V0cHV0IGZvcm1hdCB1c2VkIHdpdGggdGhlIHdyaXRlci4KLSAgICoKLSAgICogQHBhcmFtIHdyaXRlciBUaGUgb3V0cHV0IHdyaXRlciBzdHJlYW0KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFdyaXRlcihXcml0ZXIgd3JpdGVyKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBjaGFyYWN0ZXIgc3RyZWFtIHdoZXJlIHRoZSBldmVudHMgd2lsbCBiZSBzZXJpYWxpemVkIHRvLgotICAgKgotICAgKiBAcmV0dXJuIFJlZmVyZW5jZSB0byB0aGUgcmVzdWx0IFdyaXRlciwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBXcml0ZXIgZ2V0V3JpdGVyKCk7Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmllcyBhbiBvdXRwdXQgZm9ybWF0IGZvciB0aGlzIHNlcmlhbGl6ZXIuIEl0IHRoZQotICAgKiBzZXJpYWxpemVyIGhhcyBhbHJlYWR5IGJlZW4gYXNzb2NpYXRlZCB3aXRoIGFuIG91dHB1dCBmb3JtYXQsCi0gICAqIGl0IHdpbGwgc3dpdGNoIHRvIHRoZSBuZXcgZm9ybWF0LiBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlCi0gICAqIGNhbGxlZCB3aGlsZSB0aGUgc2VyaWFsaXplciBpcyBpbiB0aGUgcHJvY2VzcyBvZiBzZXJpYWxpemluZwotICAgKiBhIGRvY3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0IHRvIHVzZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KFByb3BlcnRpZXMgZm9ybWF0KTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgb3V0cHV0IGZvcm1hdCBmb3IgdGhpcyBzZXJpYWxpemVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvdXRwdXQgZm9ybWF0IGluIHVzZQotICAgKi8KLSAgcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0Rm9ybWF0KCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHtAbGluayBDb250ZW50SGFuZGxlcn0gaW50ZXJmYWNlIGludG8gdGhpcyBzZXJpYWxpemVyLgotICAgKiBJZiB0aGUgc2VyaWFsaXplciBkb2VzIG5vdCBzdXBwb3J0IHRoZSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9Ci0gICAqIGludGVyZmFjZSwgaXQgc2hvdWxkIHJldHVybiBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIEEge0BsaW5rIENvbnRlbnRIYW5kbGVyfSBpbnRlcmZhY2UgaW50byB0aGlzIHNlcmlhbGl6ZXIsCi0gICAqICBvciBudWxsIGlmIHRoZSBzZXJpYWxpemVyIGlzIG5vdCBTQVggMiBjYXBhYmxlCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkCi0gICAqLwotICBwdWJsaWMgQ29udGVudEhhbmRsZXIgYXNDb250ZW50SGFuZGxlcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQotICAvKioKLSAgICogUmV0dXJuIGEge0BsaW5rIERPTVNlcmlhbGl6ZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplci4KLSAgICogSWYgdGhlIHNlcmlhbGl6ZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUge0BsaW5rIERPTVNlcmlhbGl6ZXJ9Ci0gICAqIGludGVyZmFjZSwgaXQgc2hvdWxkIHJldHVybiBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIEEge0BsaW5rIERPTVNlcmlhbGl6ZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplciwKLSAgICogIG9yIG51bGwgaWYgdGhlIHNlcmlhbGl6ZXIgaXMgbm90IERPTSBjYXBhYmxlCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gQW4gSS9PIGV4Y2VwdGlvbiBvY2N1cmVkCi0gICAqLwotICBwdWJsaWMgRE9NU2VyaWFsaXplciBhc0RPTVNlcmlhbGl6ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFJlc2V0cyB0aGUgc2VyaWFsaXplci4gSWYgdGhpcyBtZXRob2QgcmV0dXJucyB0cnVlLCB0aGUKLSAgICogc2VyaWFsaXplciBtYXkgYmUgdXNlZCBmb3Igc3Vic2VxdWVudCBzZXJpYWxpemF0aW9uIG9mIG5ldwotICAgKiBkb2N1bWVudHMuIEl0IGlzIHBvc3NpYmxlIHRvIGNoYW5nZSB0aGUgb3V0cHV0IGZvcm1hdCBhbmQKLSAgICogb3V0cHV0IHN0cmVhbSBwcmlvciB0byBzZXJpYWxpemluZywgb3IgdG8gdXNlIHRoZSBleGlzdGluZwotICAgKiBvdXRwdXQgZm9ybWF0IGFuZCBvdXRwdXQgc3RyZWFtLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgc2VyaWFsaXplciBoYXMgYmVlbiByZXNldCBhbmQgY2FuIGJlIHJldXNlZAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gcmVzZXQoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9TZXJpYWxpemVyRmFjdG9yeS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1NlcmlhbGl6ZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhMWU1MWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1NlcmlhbGl6ZXJGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuT3V0cHV0UHJvcGVydGllczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbjsKLQotLyoqCi0gKiBGYWN0b3J5IGZvciBjcmVhdGluZyBzZXJpYWxpemVycy4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIFNlcmlhbGl6ZXJGYWN0b3J5Ci17Ci0KLSAgLyoKLSAgICogQXNzb2NpYXRlcyBvdXRwdXQgbWV0aG9kcyB0byBzZXJpYWxpemVyIGNsYXNzZXMuCi0gICAqIChEb24ndCB1c2UgdGhpcyByaWdodCBub3cuICAtc2IKLSAgICovCi0KLSAgLy8gcHJpdmF0ZSBzdGF0aWMgSGFzaHRhYmxlIF9zZXJpYWxpemVycyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAvKioKLSAgICogQXNzb2NpYXRlcyBvdXRwdXQgbWV0aG9kcyB0byBkZWZhdWx0IG91dHB1dCBmb3JtYXRzLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgSGFzaHRhYmxlIF9mb3JtYXRzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgc2VyaWFsaXplciBmb3IgdGhlIHNwZWNpZmllZCBvdXRwdXQgbWV0aG9kLiBSZXR1cm5zCi0gICAqIG51bGwgaWYgbm8gaW1wbGVtZW50YXRpb24gZXhpc3RzIHRoYXQgc3VwcG9ydHMgdGhlIHNwZWNpZmllZAotICAgKiBvdXRwdXQgbWV0aG9kLiBGb3IgYSBsaXN0IG9mIHRoZSBkZWZhdWx0IG91dHB1dCBtZXRob2RzIHNlZQotICAgKiB7QGxpbmsgTWV0aG9kfS4KLSAgICoKLSAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdAotICAgKiBAcmV0dXJuIEEgc3VpdGFibGUgc2VyaWFsaXplciwgb3IgbnVsbAotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAoYXBwYXJlbnRseSAtc2MpIGlmIG1ldGhvZCBpcyAKLSAgICogbnVsbCBvciBhbiBhcHByb3ByaWF0ZSBzZXJpYWxpemVyIGNhbid0IGJlIGZvdW5kCi0gICAqIEB0aHJvd3MgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24gKGFwcGFyZW50bHkgLXNjKSBpZiBhbiAKLSAgICogZXhjZXB0aW9uIGlzIHRocm93biB3aGlsZSB0cnlpbmcgdG8gZmluZCBzZXJpYWxpemVyCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFNlcmlhbGl6ZXIgZ2V0U2VyaWFsaXplcihQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgewotCi0gICAgU2VyaWFsaXplciBzZXIgPSBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgQ2xhc3MgY2xzOwotICAgICAgU3RyaW5nIG1ldGhvZCA9IGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLk1FVEhPRCk7Ci0KLSAgICAgIGlmIChtZXRob2QgPT0gbnVsbCkKLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICAgICAiVGhlIG91dHB1dCBmb3JtYXQgaGFzIGEgbnVsbCBtZXRob2QgbmFtZSIpOwotCi0gICAgICBjbHMgPSBudWxsOyAgLy8gKENsYXNzKV9zZXJpYWxpemVycy5nZXQobWV0aG9kKTsKLQotICAgICAgaWYgKGNscyA9PSBudWxsKQotICAgICAgewotICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0KLSAgICAgICAgICBmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0UHJvcGVydGllcy5TX0tFWV9DT05URU5UX0hBTkRMRVIpOwotCi0gICAgICAgIGlmIChudWxsID09IGNsYXNzTmFtZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAiVGhlIG91dHB1dCBmb3JtYXQgbXVzdCBoYXZlIGEgJyIKLSAgICAgICAgICAgICsgT3V0cHV0UHJvcGVydGllcy5TX0tFWV9DT05URU5UX0hBTkRMRVIgKyAiJyBwcm9wZXJ0eSEiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGNscyA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKLQotICAgICAgICAvLyBfc2VyaWFsaXplcnMucHV0KG1ldGhvZCwgY2xzKTsKLSAgICAgIH0KLQotICAgICAgc2VyID0gKFNlcmlhbGl6ZXIpIGNscy5uZXdJbnN0YW5jZSgpOwotCi0gICAgICBzZXIuc2V0T3V0cHV0Rm9ybWF0KGZvcm1hdCk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHNlcjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1NlcmlhbGl6ZXJUb0hUTUwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9TZXJpYWxpemVyVG9IVE1MLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIzNzRlZjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1NlcmlhbGl6ZXJUb0hUTUwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNzIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuQm9vbFN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlRyaWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ1RvSW50VGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuT3V0cHV0UHJvcGVydGllczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5czsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogU2VyaWFsaXplclRvSFRNTCBmb3JtYXRzIFNBWC1zdHlsZSBldmVudHMgaW50byBYTUwuCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyVG9IVE1MIGV4dGVuZHMgU2VyaWFsaXplclRvWE1MCi17Ci0KLSAgLyoqIFN0YXRlIHN0YWNrIHRvIGtlZXAgdHJhY2sgb2YgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBoYXMgb3V0cHV0IAotICAgKiAgZXNjYXBpbmcgZGlzYWJsZWQuICovCi0gIHByb3RlY3RlZCBCb29sU3RhY2sgbV9pc1Jhd1N0YWNrID0gbmV3IEJvb2xTdGFjaygpOwotCi0gIC8qKiBUcnVlIGlmIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgYSBibG9jayBlbGVtZW50LiAgKHNlZW1zIGxpa2UgCi0gICAqICB0aGlzIG5lZWRzIHRvIGJlIGEgc3RhY2suIC1zYikuICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2luQmxvY2tFbGVtID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIE1hcCB0aGF0IHRlbGxzIHdoaWNoIFhNTCBjaGFyYWN0ZXJzIHNob3VsZCBoYXZlIHNwZWNpYWwgdHJlYXRtZW50LCBhbmQgaXQKLSAgICogIHByb3ZpZGVzIGNoYXJhY3RlciB0byBlbnRpdHkgbmFtZSBsb29rdXAuCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIENoYXJJbmZvIG1faHRtbGNoYXJJbmZvID0KLSAgICBuZXcgQ2hhckluZm8oQ2hhckluZm8uSFRNTF9FTlRJVElFU19SRVNPVVJDRSk7Ci0KLSAgLyoqIEEgZGlnaXRhbCBzZWFyY2ggdHJpZSBmb3IgZmFzdCwgY2FzZSBpbnNlbnNpdGl2ZSBsb29rdXAgb2YgRWxlbURlc2Mgb2JqZWN0cy4gKi8KLSAgc3RhdGljIFRyaWUgbV9lbGVtZW50RmxhZ3MgPSBuZXcgVHJpZSgpOwotCi0gIHN0YXRpYwotICB7Ci0KLSAgICAvLyBIVE1MIDQuMCBsb29zZSBEVEQKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkJBU0VGT05UIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiRlJBTUUiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkVNUFRZIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkZSQU1FU0VUIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiTk9GUkFNRVMiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJJU0lOREVYIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJBUFBMRVQiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLldISVRFU1BBQ0VTRU5TSVRJVkUpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkNFTlRFUiIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkRJUiIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIk1FTlUiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0KLSAgICAvLyBIVE1MIDQuMCBzdHJpY3QgRFRECi0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJUVCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9OVFNUWUxFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJJIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT05UU1RZTEUpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPTlRTVFlMRSkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQklHIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT05UU1RZTEUpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlNNQUxMIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT05UU1RZTEUpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkVNIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5QSFJBU0UpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlNUUk9ORyIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJERk4iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQ09ERSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTQU1QIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5QSFJBU0UpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIktCRCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJWQVIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQ0lURSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUEhSQVNFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJBQkJSIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5QSFJBU0UpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkFDUk9OWU0iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlBIUkFTRSkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiU1VQIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5TUEVDSUFMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkFTUEVDSUFMKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTVUIiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQVNQRUNJQUwpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlNQQU4iLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQVNQRUNJQUwpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkJETyIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuU1BFQ0lBTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5BU1BFQ0lBTCkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQlIiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwgfCBFbGVtRGVzYy5BU1BFQ0lBTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJCT0RZIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiQUREUkVTUyIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0sgfCBFbGVtRGVzYy5CTE9DS0ZPUk0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkRJViIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0sgfCBFbGVtRGVzYy5CTE9DS0ZPUk0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkEiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIk1BUCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuU1BFQ0lBTCB8IEVsZW1EZXNjLkFTUEVDSUFMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJBUkVBIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5FTVBUWSB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJMSU5LIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFETUlTQyB8IEVsZW1EZXNjLkVNUFRZCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJJTUciLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwgfCBFbGVtRGVzYy5BU1BFQ0lBTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5FTVBUWQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5XSElURVNQQUNFU0VOU0lUSVZFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJPQkpFQ1QiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLlNQRUNJQUwgfCBFbGVtRGVzYy5BU1BFQ0lBTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5IRUFETUlTQwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5XSElURVNQQUNFU0VOU0lUSVZFKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJQQVJBTSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRU1QVFkpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkhSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSyB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DS0ZPUk1GSUVMRFNFVAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5FTVBUWSkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiUCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0sgfCBFbGVtRGVzYy5CTE9DS0ZPUk0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkgxIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkgyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkgzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkg0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkg1IiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkg2IiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFEIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlBSRSIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuUFJFRk9STUFUVEVECi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJRIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5TUEVDSUFMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkFTUEVDSUFMKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJCTE9DS1FVT1RFIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSyB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DS0ZPUk1GSUVMRFNFVCkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiSU5TIiwgbmV3IEVsZW1EZXNjKDApKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkRFTCIsIG5ldyBFbGVtRGVzYygwKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJETCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0sgfCBFbGVtRGVzYy5CTE9DS0ZPUk0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkRUIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiREQiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJPTCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuTElTVCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJVTCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuTElTVCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJMSSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkZPUk0iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJMQUJFTCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9STUNUUkwpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIklOUFVUIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT1JNQ1RSTAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5JTkxJTkVMQUJFTCB8IEVsZW1EZXNjLkVNUFRZKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTRUxFQ1QiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPUk1DVFJMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLklOTElORUxBQkVMKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJPUFRHUk9VUCIsIG5ldyBFbGVtRGVzYygwKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJPUFRJT04iLCBuZXcgRWxlbURlc2MoMCkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVEVYVEFSRUEiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPUk1DVFJMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLklOTElORUxBQkVMKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJGSUVMRFNFVCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0sgfCBFbGVtRGVzYy5CTE9DS0ZPUk0pKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkxFR0VORCIsIG5ldyBFbGVtRGVzYygwKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJCVVRUT04iLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkZPUk1DVFJMCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLklOTElORUxBQkVMKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJUQUJMRSIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0sgfCBFbGVtRGVzYy5CTE9DS0ZPUk0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0tGT1JNRklFTERTRVQpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkNBUFRJT04iLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJUSEVBRCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlRGT09UIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVEJPRFkiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJDT0xHUk9VUCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkNPTCIsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRU1QVFkgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVFIiLCBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJUSCIsIG5ldyBFbGVtRGVzYygwKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJURCIsIG5ldyBFbGVtRGVzYygwKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJIRUFEIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSyB8IEVsZW1EZXNjLkhFQURFTEVNKSk7Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJUSVRMRSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkJBU0UiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkVNUFRZIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIk1FVEEiLAotICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkhFQURNSVNDIHwgRWxlbURlc2MuRU1QVFkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuQkxPQ0spKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlNUWUxFIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5IRUFETUlTQyB8IEVsZW1EZXNjLlJBVwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DSykpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiU0NSSVBUIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5TUEVDSUFMIHwgRWxlbURlc2MuQVNQRUNJQUwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRWxlbURlc2MuSEVBRE1JU0MgfCBFbGVtRGVzYy5SQVcpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIk5PU0NSSVBUIiwKLSAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSyB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DS0ZPUk1GSUVMRFNFVCkpOwotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiSFRNTCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spKTsKLQotICAgIC8vIEZyb20gIkpvaG4gS3kiIDxoYW5kQHN5ZC5zcGVlZG5ldC5jb20uYXUKLSAgICAvLyBUcmFuc2l0aW9uYWwgRG9jdW1lbnQgVHlwZSBEZWZpbml0aW9uICgpCi0gICAgLy8gZmlsZTovLy9DOi9Eb2N1bWVudHMlMjBhbmQlMjBTZXR0aW5ncy9zYm9hZy5CT0FHNjAwRS9NeSUyMERvY3VtZW50cy9odG1sL3NnbWwvbG9vc2VkdGQuaHRtbCNiYXNlZm9udAotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiRk9OVCIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9OVFNUWUxFKSk7Ci0KLSAgICAvLyBmaWxlOi8vL0M6L0RvY3VtZW50cyUyMGFuZCUyMFNldHRpbmdzL3Nib2FnLkJPQUc2MDBFL015JTIwRG9jdW1lbnRzL2h0bWwvcHJlc2VudC9ncmFwaGljcy5odG1sI2VkZWYtU1RSSUtFCi0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJTIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT05UU1RZTEUpKTsKLSAgICBtX2VsZW1lbnRGbGFncy5wdXQoIlNUUklLRSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9OVFNUWUxFKSk7Ci0KLSAgICAvLyBmaWxlOi8vL0M6L0RvY3VtZW50cyUyMGFuZCUyMFNldHRpbmdzL3Nib2FnLkJPQUc2MDBFL015JTIwRG9jdW1lbnRzL2h0bWwvcHJlc2VudC9ncmFwaGljcy5odG1sI2VkZWYtVQotICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiVSIsIG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuRk9OVFNUWUxFKSk7Ci0KLSAgICAvLyBGcm9tICJKb2huIEt5IiA8aGFuZEBzeWQuc3BlZWRuZXQuY29tLmF1Ci0gICAgbV9lbGVtZW50RmxhZ3MucHV0KCJOT0JSIiwgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5GT05UU1RZTEUpKTsKLSAgICAKLSAgICAgLy8gSFRNTCA0LjAsIHNlY3Rpb24gMTYuNQotICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIklGUkFNRSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEVsZW1EZXNjKDAgfCBFbGVtRGVzYy5CTE9DSyB8IEVsZW1EZXNjLkJMT0NLRk9STQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbGVtRGVzYy5CTE9DS0ZPUk1GSUVMRFNFVCkpOwotICAgICAvLyBOUzQgZXh0ZW5zaW9ucwotICAgICBtX2VsZW1lbnRGbGFncy5wdXQoIkxBWUVSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLIHwgRWxlbURlc2MuQkxPQ0tGT1JNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gICAgIG1fZWxlbWVudEZsYWdzLnB1dCgiSUxBWUVSIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRWxlbURlc2MoMCB8IEVsZW1EZXNjLkJMT0NLIHwgRWxlbURlc2MuQkxPQ0tGT1JNCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEVsZW1EZXNjLkJMT0NLRk9STUZJRUxEU0VUKSk7Ci0gIAotICAgIEVsZW1EZXNjIGVsZW1EZXNjOwotCi0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiQVJFQSIpOwotCi0gICAgZWxlbURlc2Muc2V0QXR0cigiSFJFRiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIk5PSFJFRiIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJCQVNFIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJIUkVGIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJCTE9DS1FVT1RFIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJDSVRFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJRIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJDSVRFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJJTlMiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIkNJVEUiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLQotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIkRFTCIpOwotCi0gICAgZWxlbURlc2Muc2V0QXR0cigiQ0lURSIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiQSIpOwotCi0gICAgZWxlbURlc2Muc2V0QXR0cigiSFJFRiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIk5BTUUiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICAKLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJMSU5LIik7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiSFJFRiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotCi0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiSU5QVVQiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIlVTRU1BUCIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkNIRUNLRUQiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkRJU0FCTEVEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJJU01BUCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiUkVBRE9OTFkiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiU0VMRUNUIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJESVNBQkxFRCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiTVVMVElQTEUiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiT1BUR1JPVVAiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIkRJU0FCTEVEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIk9QVElPTiIpOwotCi0gICAgZWxlbURlc2Muc2V0QXR0cigiU0VMRUNURUQiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkRJU0FCTEVEIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIlRFWFRBUkVBIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJESVNBQkxFRCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiUkVBRE9OTFkiLCBFbGVtRGVzYy5BVFRSRU1QVFkpOwotCi0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiQlVUVE9OIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJESVNBQkxFRCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJTQ1JJUFQiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkZPUiIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkRFRkVSIiwgRWxlbURlc2MuQVRUUkVNUFRZKTsKLQotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIklNRyIpOwotCi0gICAgZWxlbURlc2Muc2V0QXR0cigiU1JDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiTE9OR0RFU0MiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJVU0VNQVAiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJJU01BUCIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJPQkpFQ1QiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIkNMQVNTSUQiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJDT0RFQkFTRSIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkRBVEEiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJBUkNISVZFIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiVVNFTUFQIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gICAgZWxlbURlc2Muc2V0QXR0cigiREVDTEFSRSIsIEVsZW1EZXNjLkFUVFJFTVBUWSk7Ci0KLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJGT1JNIik7Ci0KLSAgICBlbGVtRGVzYy5zZXRBdHRyKCJBQ1RJT04iLCBFbGVtRGVzYy5BVFRSVVJMKTsKLQotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIkhFQUQiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIlBST0ZJTEUiLCBFbGVtRGVzYy5BVFRSVVJMKTsKLQotICAgIC8vIEF0dHJpYnV0aW9uIHRvOiAiVm95dGVua28sIERpbWl0cnkiIDxEVm95dGVua29AU0VDVE9SQkFTRS5DT00+Ci0gICAgZWxlbURlc2MgPSAoRWxlbURlc2MpIG1fZWxlbWVudEZsYWdzLmdldCgiRlJBTUUiKTsKLQotICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkxPTkdERVNDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gCi0gICAgLy8gSFRNTCA0LjAsIHNlY3Rpb24gMTYuNQotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIklGUkFNRSIpOwotIAotICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotICAgIGVsZW1EZXNjLnNldEF0dHIoIkxPTkdERVNDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gCi0gICAgLy8gTlM0IGV4dGVuc2lvbnMKLSAgICBlbGVtRGVzYyA9IChFbGVtRGVzYykgbV9lbGVtZW50RmxhZ3MuZ2V0KCJMQVlFUiIpOwotIAotICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotIAotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIklMQVlFUiIpOwotIAotICAgIGVsZW1EZXNjLnNldEF0dHIoIlNSQyIsIEVsZW1EZXNjLkFUVFJVUkwpOwotIAotICAgIGVsZW1EZXNjID0gKEVsZW1EZXNjKSBtX2VsZW1lbnRGbGFncy5nZXQoIkRJViIpOwotCi0gICAgZWxlbURlc2Muc2V0QXR0cigiU1JDIiwgRWxlbURlc2MuQVRUUlVSTCk7Ci0gIH0KLQotICAvKioKLSAgICogRHVtbXkgZWxlbWVudCBmb3IgZWxlbWVudHMgbm90IGZvdW5kLgotICAgKi8KLSAgc3RhdGljIHByaXZhdGUgRWxlbURlc2MgbV9kdW1teSA9IG5ldyBFbGVtRGVzYygwIHwgRWxlbURlc2MuQkxPQ0spOwotCi0gIC8qKiBUcnVlIGlmIFVSTHMgc2hvdWxkIGJlIHNwZWNpYWxseSBlc2NhcGVkIHdpdGggdGhlICV4eCBmb3JtLiAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9zcGVjaWFsRXNjYXBlVVJMcyA9IHRydWU7Ci0KLSAgLyoqIFRydWUgaWYgdGhlIE1FVEEgdGFnIHNob3VsZCBiZSBvbWl0dGVkLiAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9vbWl0TWV0YVRhZyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGUgZm9ybWF0dGVyIHNob3VsZCB1c2Ugc3BlY2lhbCBVUkwgZXNjYXBpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBib29sIFRydWUgaWYgVVJMcyBzaG91bGQgYmUgc3BlY2lhbGx5IGVzY2FwZWQgd2l0aCB0aGUgJXh4IGZvcm0uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTcGVjaWFsRXNjYXBlVVJMcyhib29sZWFuIGJvb2wpCi0gIHsKLSAgICBtX3NwZWNpYWxFc2NhcGVVUkxzID0gYm9vbDsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGUgZm9ybWF0dGVyIHNob3VsZCBvbWl0IHRoZSBNRVRBIHRhZy4KLSAgICoKLSAgICogQHBhcmFtIGJvb2wgVHJ1ZSBpZiB0aGUgTUVUQSB0YWcgc2hvdWxkIGJlIG9taXR0ZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRPbWl0TWV0YVRhZyhib29sZWFuIGJvb2wpCi0gIHsKLSAgICBtX29taXRNZXRhVGFnID0gYm9vbDsKLSAgfQotCi0gIC8qKgotICAgKiBTcGVjaWZpZXMgYW4gb3V0cHV0IGZvcm1hdCBmb3IgdGhpcyBzZXJpYWxpemVyLiBJdCB0aGUKLSAgICogc2VyaWFsaXplciBoYXMgYWxyZWFkeSBiZWVuIGFzc29jaWF0ZWQgd2l0aCBhbiBvdXRwdXQgZm9ybWF0LAotICAgKiBpdCB3aWxsIHN3aXRjaCB0byB0aGUgbmV3IGZvcm1hdC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZQotICAgKiBjYWxsZWQgd2hpbGUgdGhlIHNlcmlhbGl6ZXIgaXMgaW4gdGhlIHByb2Nlc3Mgb2Ygc2VyaWFsaXppbmcKLSAgICogYSBkb2N1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdCB0byB1c2UKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE91dHB1dEZvcm1hdChQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgewotCi0gICAgbV9zcGVjaWFsRXNjYXBlVVJMcyA9Ci0gICAgICBPdXRwdXRQcm9wZXJ0aWVzLmdldEJvb2xlYW5Qcm9wZXJ0eShPdXRwdXRQcm9wZXJ0aWVzLlNfVVNFX1VSTF9FU0NBUElORywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCk7Ci0KLSAgICBtX29taXRNZXRhVGFnID0KLSAgICAgIE91dHB1dFByb3BlcnRpZXMuZ2V0Qm9vbGVhblByb3BlcnR5KE91dHB1dFByb3BlcnRpZXMuU19PTUlUX01FVEFfVEFHLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0KTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICBzdXBlci5zZXRPdXRwdXRGb3JtYXQoZm9ybWF0KTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGUgZm9ybWF0dGVyIHNob3VsZCB1c2Ugc3BlY2lhbCBVUkwgZXNjYXBpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBVUkxzIHNob3VsZCBiZSBzcGVjaWFsbHkgZXNjYXBlZCB3aXRoIHRoZSAleHggZm9ybS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFNwZWNpYWxFc2NhcGVVUkxzKCkKLSAgewotICAgIHJldHVybiBtX3NwZWNpYWxFc2NhcGVVUkxzOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoZSBmb3JtYXR0ZXIgc2hvdWxkIG9taXQgdGhlIE1FVEEgdGFnLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIE1FVEEgdGFnIHNob3VsZCBiZSBvbWl0dGVkLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0T21pdE1ldGFUYWcoKQotICB7Ci0gICAgcmV0dXJuIG1fb21pdE1ldGFUYWc7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgZGVzY3JpcHRpb24gb2YgdGhlIGdpdmVuIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIG5vbi1udWxsIG5hbWUgb2YgZWxlbWVudCwgY2FzZSBpbnNlbnNpdGl2ZS4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gRWxlbURlc2MsIHdoaWNoIG1heSBiZSBtX2R1bW15IGlmIG5vIAotICAgKiAgICAgICAgIGVsZW1lbnQgZGVzY3JpcHRpb24gbWF0Y2hlcyB0aGUgZ2l2ZW4gbmFtZS4KLSAgICovCi0gIEVsZW1EZXNjIGdldEVsZW1EZXNjKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBuYW1lKQotICAgIHsKLSAgICAgIE9iamVjdCBvYmogPSBtX2VsZW1lbnRGbGFncy5nZXQobmFtZSk7Ci0KLSAgICAgIGlmIChudWxsICE9IG9iaikKLSAgICAgICAgcmV0dXJuIChFbGVtRGVzYykgb2JqOwotICAgIH0KLQotICAgIHJldHVybiBtX2R1bW15OwotICB9Ci0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IuCi0gICAqLwotICBwdWJsaWMgU2VyaWFsaXplclRvSFRNTCgpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0gICAgbV9jaGFySW5mbyA9IG1faHRtbGNoYXJJbmZvOwotICB9Ci0KLSAgLyoqIFRoZSBuYW1lIG9mIHRoZSBjdXJyZW50IGVsZW1lbnQuICovCi0gIHByaXZhdGUgU3RyaW5nIG1fY3VycmVudEVsZW1lbnROYW1lID0gbnVsbDsKLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIG1fbmVlZFRvT3V0cHV0RG9jVHlwZURlY2wgPSB0cnVlOwotICAgIG1fc3RhcnROZXdMaW5lID0gZmFsc2U7Ci0gICAgbV9zaG91bGROb3RXcml0ZVhNTEhlYWRlciA9IHRydWU7Ci0KLSAgICBpZiAodHJ1ZSA9PSBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsKQotICAgIHsKLSAgICAgIGlmICgobnVsbCAhPSBtX2RvY3R5cGVTeXN0ZW0pIHx8IChudWxsICE9IG1fZG9jdHlwZVB1YmxpYykpCi0gICAgICB7Ci0gICAgICAgIGFjY3VtKCI8IURPQ1RZUEUgSFRNTCIpOwotCi0gICAgICAgIGlmIChudWxsICE9IG1fZG9jdHlwZVB1YmxpYykKLSAgICAgICAgewotICAgICAgICAgIGFjY3VtKCIgUFVCTElDIFwiIik7Ci0gICAgICAgICAgYWNjdW0obV9kb2N0eXBlUHVibGljKTsKLSAgICAgICAgICBhY2N1bSgiXCIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChudWxsICE9IG1fZG9jdHlwZVN5c3RlbSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChudWxsID09IG1fZG9jdHlwZVB1YmxpYykKLSAgICAgICAgICAgIGFjY3VtKCIgU1lTVEVNIFwiIik7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgYWNjdW0oIiBcIiIpOwotCi0gICAgICAgICAgYWNjdW0obV9kb2N0eXBlU3lzdGVtKTsKLSAgICAgICAgICBhY2N1bSgiXCIiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGFjY3VtKCI+Iik7Ci0gICAgICAgIG91dHB1dExpbmVTZXAoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsID0gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICoKLSAgICogIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogIEBwYXJhbSBsb2NhbE5hbWUKLSAgICogIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICogIEBwYXJhbSBhdHRzIFRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LCBpZiBhbnkuCi0gICAqICBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqICBAc2VlICNlbmRFbGVtZW50Ci0gICAqICBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJTZXJpYWxpemVyVG9IVE1MI3N0YXJ0RWxlbWVudCgiK25hbWVzcGFjZVVSSSsiLCAiK2xvY2FsTmFtZSsiLCAiK25hbWUrIiwgLi4uKTsiKTsKLQotICAgIGlmIChudWxsICE9IG5hbWVzcGFjZVVSSSAmJiBuYW1lc3BhY2VVUkkubGVuZ3RoKCkgPiAwKQotICAgIHsKLSAgICAgIHN1cGVyLnN0YXJ0RWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgbmFtZSwgYXR0cyk7Ci0KLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBib29sZWFuIHNhdmVkRG9JbmRlbnQgPSBtX2RvSW5kZW50OwotICAgIGJvb2xlYW4gbm9MaW5lQnJlYWs7Ci0KLSAgICB3cml0ZVBhcmVudFRhZ0VuZCgpOwotICAgIHB1c2hTdGF0ZSgKLSAgICAgIG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLAotICAgICAgbV9jZGF0YVNlY3Rpb25OYW1lcywgbV9jZGF0YVNlY3Rpb25TdGF0ZXMpOwotCi0gICAgLy8gcHVzaFN0YXRlKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBtX2Zvcm1hdC5nZXROb25Fc2NhcGluZ0VsZW1lbnRzKCksCi0gICAgLy8gICAgICAgICAgbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMpOwotICAgIEVsZW1EZXNjIGVsZW1EZXNjID0gZ2V0RWxlbURlc2MobmFtZSk7Ci0KLSAgICAvLyBFbGVtRGVzYyBwYXJlbnRFbGVtRGVzYyA9IGdldEVsZW1EZXNjKG1fY3VycmVudEVsZW1lbnROYW1lKTsKLSAgICBib29sZWFuIGlzQmxvY2tFbGVtZW50ID0gZWxlbURlc2MuaXMoRWxlbURlc2MuQkxPQ0spOwotICAgIGJvb2xlYW4gaXNIZWFkRWxlbWVudCA9IGVsZW1EZXNjLmlzKEVsZW1EZXNjLkhFQURFTEVNKTsKLQotICAgIC8vIGJvb2xlYW4gaXNXaGl0ZVNwYWNlU2Vuc2l0aXZlID0gZWxlbURlc2MuaXMoRWxlbURlc2MuV0hJVEVTUEFDRVNFTlNJVElWRSk7Ci0gICAgaWYgKG1faXNwcmVzZXJ2ZSkKLSAgICAgIG1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotICAgIGVsc2UgaWYgKG1fZG9JbmRlbnQgJiYgKG51bGwgIT0gbV9jdXJyZW50RWxlbWVudE5hbWUpCi0gICAgICAgICAgICAgJiYgKCFtX2luQmxvY2tFbGVtIHx8IGlzQmxvY2tFbGVtZW50KQotCi0gICAgLyogJiYgIWlzV2hpdGVTcGFjZVNlbnNpdGl2ZSAqLwotICAgICkKLSAgICB7Ci0gICAgICBtX3N0YXJ0TmV3TGluZSA9IHRydWU7Ci0KLSAgICAgIGluZGVudChtX2N1cnJlbnRJbmRlbnQpOwotICAgIH0KLQotICAgIG1faW5CbG9ja0VsZW0gPSAhaXNCbG9ja0VsZW1lbnQ7Ci0KLSAgICBtX2lzUmF3U3RhY2sucHVzaChlbGVtRGVzYy5pcyhFbGVtRGVzYy5SQVcpKTsKLQotICAgIG1fY3VycmVudEVsZW1lbnROYW1lID0gbmFtZTsKLQotICAgIC8vIG1fcGFyZW50cy5wdXNoKG1fY3VycmVudEVsZW1lbnROYW1lKTsKLSAgICB0aGlzLmFjY3VtKCc8Jyk7Ci0gICAgdGhpcy5hY2N1bShuYW1lKTsKLQotICAgIGludCBuQXR0cnMgPSBhdHRzLmdldExlbmd0aCgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cnM7IGkrKykKLSAgICB7Ci0gICAgICBwcm9jZXNzQXR0cmlidXRlKGF0dHMuZ2V0UU5hbWUoaSksIGVsZW1EZXNjLCBhdHRzLmdldFZhbHVlKGkpKTsKLSAgICB9Ci0KLSAgICAvLyBGbGFnIHRoZSBjdXJyZW50IGVsZW1lbnQgYXMgbm90IHlldCBoYXZpbmcgYW55IGNoaWxkcmVuLgotICAgIG9wZW5FbGVtZW50Rm9yQ2hpbGRyZW4oKTsKLQotICAgIG1fY3VycmVudEluZGVudCArPSB0aGlzLm1faW5kZW50QW1vdW50OwotICAgIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotICAgIG1fZG9JbmRlbnQgPSBzYXZlZERvSW5kZW50OwotCi0gICAgaWYgKGlzSGVhZEVsZW1lbnQpCi0gICAgewotICAgICAgd3JpdGVQYXJlbnRUYWdFbmQoKTsKLQotICAgICAgaWYgKCFtX29taXRNZXRhVGFnKQotICAgICAgewotICAgICAgICBpZiAobV9kb0luZGVudCkKLSAgICAgICAgICBpbmRlbnQobV9jdXJyZW50SW5kZW50KTsKLQotICAgICAgICBhY2N1bSgKLSAgICAgICAgICAiPE1FVEEgaHR0cC1lcXVpdj1cIkNvbnRlbnQtVHlwZVwiIGNvbnRlbnQ9XCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9Iik7Ci0KLSAgICAgICAgLy8gU3RyaW5nIGVuY29kaW5nID0gRW5jb2RpbmdzLmdldE1pbWVFbmNvZGluZyhtX2VuY29kaW5nKS50b0xvd2VyQ2FzZSgpOwotICAgICAgICBTdHJpbmcgZW5jb2RpbmcgPSBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKG1fZW5jb2RpbmcpOwotCi0gICAgICAgIGFjY3VtKGVuY29kaW5nKTsKLSAgICAgICAgYWNjdW0oJyInKTsKLSAgICAgICAgYWNjdW0oJz4nKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICoKLSAgICogIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogIEBwYXJhbSBsb2NhbE5hbWUKLSAgICogIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZQotICAgKiAgQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNlcmlhbGl6ZXJUb0hUTUwjZW5kRWxlbWVudCgiK25hbWVzcGFjZVVSSSsiLCAiK2xvY2FsTmFtZSsiLCAiK25hbWUrIik7Iik7Ci0gICAgaWYgKG51bGwgIT0gbmFtZXNwYWNlVVJJICYmIG5hbWVzcGFjZVVSSS5sZW5ndGgoKSA+IDApCi0gICAgewotICAgICAgc3VwZXIuZW5kRWxlbWVudChuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgbmFtZSk7Ci0KLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLSAgICBtX2N1cnJlbnRJbmRlbnQgLT0gdGhpcy5tX2luZGVudEFtb3VudDsKLQotICAgIGJvb2xlYW4gaGFzQ2hpbGROb2RlcyA9IGNoaWxkTm9kZXNXZXJlQWRkZWQoKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihtX2N1cnJlbnRFbGVtZW50TmFtZSk7Ci0gICAgLy8gbV9wYXJlbnRzLnBvcCgpOwotICAgIG1faXNSYXdTdGFjay5wb3AoKTsKLQotICAgIEVsZW1EZXNjIGVsZW1EZXNjID0gZ2V0RWxlbURlc2MobmFtZSk7Ci0KLSAgICAvLyBFbGVtRGVzYyBwYXJlbnRFbGVtRGVzYyA9IGdldEVsZW1EZXNjKG1fY3VycmVudEVsZW1lbnROYW1lKTsKLSAgICBib29sZWFuIGlzQmxvY2tFbGVtZW50ID0gZWxlbURlc2MuaXMoRWxlbURlc2MuQkxPQ0spOwotICAgIGJvb2xlYW4gc2hvdWxkSW5kZW50ID0gZmFsc2U7Ci0KLSAgICBpZiAobV9pc3ByZXNlcnZlKQotICAgIHsKLSAgICAgIG1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotICAgIH0KLSAgICBlbHNlIGlmIChtX2RvSW5kZW50ICYmICghbV9pbkJsb2NrRWxlbSB8fCBpc0Jsb2NrRWxlbWVudCkpCi0gICAgewotICAgICAgbV9zdGFydE5ld0xpbmUgPSB0cnVlOwotICAgICAgc2hvdWxkSW5kZW50ID0gdHJ1ZTsKLQotICAgICAgLy8gaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0gICAgfQotCi0gICAgbV9pbkJsb2NrRWxlbSA9ICFpc0Jsb2NrRWxlbWVudDsKLQotICAgIGlmIChoYXNDaGlsZE5vZGVzKQotICAgIHsKLSAgICAgIGlmIChzaG91bGRJbmRlbnQpCi0gICAgICAgIGluZGVudChtX2N1cnJlbnRJbmRlbnQpOwotCi0gICAgICB0aGlzLmFjY3VtKCI8LyIpOwotICAgICAgdGhpcy5hY2N1bShuYW1lKTsKLSAgICAgIHRoaXMuYWNjdW0oJz4nKTsKLQotICAgICAgbV9jdXJyZW50RWxlbWVudE5hbWUgPSBuYW1lOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKCFlbGVtRGVzYy5pcyhFbGVtRGVzYy5FTVBUWSkpCi0gICAgICB7Ci0gICAgICAgIHRoaXMuYWNjdW0oJz4nKTsKLQotICAgICAgICAvLyBBcyBwZXIgRGF2ZS9QYXVsIHJlY29tbWVuZGF0aW9uIDEyLzA2LzIwMDAKLSAgICAgICAgLy8gaWYgKHNob3VsZEluZGVudCkKLSAgICAgICAgLy8gIGluZGVudChtX2N1cnJlbnRJbmRlbnQpOwotCi0gICAgICAgIHRoaXMuYWNjdW0oJzwnKTsKLSAgICAgICAgdGhpcy5hY2N1bSgnLycpOwotICAgICAgICB0aGlzLmFjY3VtKG5hbWUpOwotICAgICAgICB0aGlzLmFjY3VtKCc+Jyk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHRoaXMuYWNjdW0oJz4nKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoZWxlbURlc2MuaXMoRWxlbURlc2MuV0hJVEVTUEFDRVNFTlNJVElWRSkpCi0gICAgICBtX2lzcHJlc2VydmUgPSB0cnVlOwotCi0gICAgaWYgKGhhc0NoaWxkTm9kZXMpCi0gICAgewotICAgICAgaWYgKCFtX3ByZXNlcnZlcy5pc0VtcHR5KCkpCi0gICAgICAgIG1fcHJlc2VydmVzLnBvcCgpOwotICAgIH0KLQotICAgIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotCi0gICAgLy8gbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMucG9wKCk7Ci0gICAgbV9jZGF0YVNlY3Rpb25TdGF0ZXMucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyBhbiBhdHRyaWJ1dGUuCi0gICAqIEBwYXJhbSAgIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKiBAcGFyYW0gZWxlbURlc2Mgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBvd25pbmcgZWxlbWVudCBkZXNjcmlwdGlvbi4KLSAgICogQHBhcmFtICAgdmFsdWUgICBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NBdHRyaWJ1dGUoCi0gICAgICAgICAgU3RyaW5nIG5hbWUsIEVsZW1EZXNjIGVsZW1EZXNjLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRoaXMuYWNjdW0oJyAnKTsKLQotICAgIGlmICgoKHZhbHVlLmxlbmd0aCgpID09IDApIHx8IHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpCi0gICAgICAgICAgICAmJiBlbGVtRGVzYy5pc0F0dHJGbGFnU2V0KG5hbWUsIEVsZW1EZXNjLkFUVFJFTVBUWSkpCi0gICAgewotICAgICAgdGhpcy5hY2N1bShuYW1lKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRoaXMuYWNjdW0obmFtZSk7Ci0gICAgICB0aGlzLmFjY3VtKCc9Jyk7Ci0KLSAgICAgIHRoaXMuYWNjdW0oJ1wiJyk7Ci0gICAgICBpZiAoZWxlbURlc2MuaXNBdHRyRmxhZ1NldChuYW1lLCBFbGVtRGVzYy5BVFRSVVJMKSkKLSAgICAgICAgd3JpdGVBdHRyVVJJKHZhbHVlLCBtX3NwZWNpYWxFc2NhcGVVUkxzKTsKLSAgICAgIGVsc2UKLSAgICAgICAgd3JpdGVBdHRyU3RyaW5nKHZhbHVlLCB0aGlzLm1fZW5jb2RpbmcpOwotICAgICAgdGhpcy5hY2N1bSgnXCInKTsKLQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgYSBjaGFyYWN0ZXIgaXMgYW4gQVNDSUkgZGlnaXQuCi0gICAqLwotICAgcHJpdmF0ZSBib29sZWFuIGlzQVNDSUlEaWdpdChjaGFyIGMpCi0gICB7Ci0gICAgICByZXR1cm4gKGMgPj0gJzAnICYmIGMgPD0gJzknKTsKLSAgIH0KLSAgIAotIC8qKgotICAqIE1ha2UgYW4gaW50ZWdlciBpbnRvIGFuIEhIIGhleCB2YWx1ZS4KLSAgKiBEb2VzIG5vIGNoZWNraW5nIG9uIHRoZSBzaXplIG9mIHRoZSBpbnB1dCwgc2luY2UgdGhpcyAKLSAgKiBpcyBvbmx5IG1lYW50IHRvIGJlIHVzZWQgbG9jYWxseSBieSB3cml0ZUF0dHJVUkkuCi0gICogCi0gICogQHBhcmFtIGkgbXVzdCBiZSBhIHZhbHVlIGxlc3MgdGhhbiAyNTUuCi0gICogCi0gICogQHJldHVybiBzaG91bGQgYmUgYSB0d28gY2hhcmFjdGVyIHN0cmluZy4KLSAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbWFrZUhIU3RyaW5nKGludCBpKQotICB7Ci0gICAgU3RyaW5nIHMgPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGkpLnRvVXBwZXJDYXNlKCk7Ci0gICAgaWYocy5sZW5ndGgoKSA9PSAxKQotICAgIHsKLSAgICAgIHMgPSAiMCIrczsKLSAgICB9Ci0gICAgcmV0dXJuIHM7Ci0gIH0KLSAgICAKLSAgLyoqCi0gICogRG1pdHJpIElseWluOiBNYWtlcyBzdXJlIGlmIHRoZSBTdHJpbmcgaXMgSEggZW5jb2RlZCBzaWduLgotICAqIEBwYXJhbSBzdHIgbXVzdCBiZSAyIGNoYXJhY3RlcnMgbG9uZwotICAqCi0gICogQHJldHVybiB0cnVlIG9yIGZhbHNlCi0gICovCi0gIHByaXZhdGUgYm9vbGVhbiBpc0hIU2lnbihTdHJpbmcgc3RyKSAKLSAgewotICAgIGJvb2xlYW4gc2lnbiA9IHRydWU7ICAKLSAgICB0cnkgewotICAgICAgY2hhciByID0gKGNoYXIpSW50ZWdlci5wYXJzZUludChzdHIsMTYpOwotICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBzaWduID0gZmFsc2U7ICAKLSAgICB9Ci0gICAgcmV0dXJuIHNpZ247Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBXcml0ZSB0aGUgc3BlY2lmaWVkIDx2YXI+c3RyaW5nPC92YXI+IGFmdGVyIHN1YnN0aXR1dGluZyBub24gQVNDSUkgY2hhcmFjdGVycywKLSAgICogd2l0aCA8Q09ERT4lSEg8L0NPREU+LCB3aGVyZSBISCBpcyB0aGUgaGV4IG9mIHRoZSBieXRlIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gICBzdHJpbmcgICAgICBTdHJpbmcgdG8gY29udmVydCB0byBYTUwgZm9ybWF0LgotICAgKiBAcGFyYW0gZG9VUkxFc2NhcGluZyBUcnVlIGlmIHdlIHNob3VsZCB0cnkgdG8gZW5jb2RlIGFzIAotICAgKiAgICAgICAgICAgICAgICAgICAgICBwZXIgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlmIGEgYmFkIHN1cnJvZ2F0ZSBwYWlyIGlzIGRldGVjdGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVBdHRyVVJJKFN0cmluZyBzdHJpbmcsIGJvb2xlYW4gZG9VUkxFc2NhcGluZykKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzk2LnR4dCBzYXlzOgotICAgIC8vIEEgVVJJIGlzIGFsd2F5cyBpbiBhbiAiZXNjYXBlZCIgZm9ybSwgc2luY2UgZXNjYXBpbmcgb3IgdW5lc2NhcGluZyBhCi0gICAgLy8gY29tcGxldGVkIFVSSSBtaWdodCBjaGFuZ2UgaXRzIHNlbWFudGljcy4gIE5vcm1hbGx5LCB0aGUgb25seSB0aW1lCi0gICAgLy8gZXNjYXBlIGVuY29kaW5ncyBjYW4gc2FmZWx5IGJlIG1hZGUgaXMgd2hlbiB0aGUgVVJJIGlzIGJlaW5nIGNyZWF0ZWQKLSAgICAvLyBmcm9tIGl0cyBjb21wb25lbnQgcGFydHM7IGVhY2ggY29tcG9uZW50IG1heSBoYXZlIGl0cyBvd24gc2V0IG9mCi0gICAgLy8gY2hhcmFjdGVycyB0aGF0IGFyZSByZXNlcnZlZCwgc28gb25seSB0aGUgbWVjaGFuaXNtIHJlc3BvbnNpYmxlIGZvcgotICAgIC8vIGdlbmVyYXRpbmcgb3IgaW50ZXJwcmV0aW5nIHRoYXQgY29tcG9uZW50IGNhbiBkZXRlcm1pbmUgd2hldGhlciBvcgotICAgIC8vIG5vdCBlc2NhcGluZyBhIGNoYXJhY3RlciB3aWxsIGNoYW5nZSBpdHMgc2VtYW50aWNzLiBMaWtld2lzZSwgYSBVUkkKLSAgICAvLyBtdXN0IGJlIHNlcGFyYXRlZCBpbnRvIGl0cyBjb21wb25lbnRzIGJlZm9yZSB0aGUgZXNjYXBlZCBjaGFyYWN0ZXJzCi0gICAgLy8gd2l0aGluIHRob3NlIGNvbXBvbmVudHMgY2FuIGJlIHNhZmVseSBkZWNvZGVkLgotICAgIC8vCi0gICAgLy8gLi4uU28gd2UgZG8gb3VyIGJlc3QgdG8gZG8gbGltaXRlZCBlc2NhcGluZyBvZiB0aGUgVVJMLCB3aXRob3V0IAotICAgIC8vIGNhdXNpbmcgZGFtYWdlLiAgSWYgdGhlIFVSTCBpcyBhbHJlYWR5IHByb3Blcmx5IGVzY2FwZWQsIGluIHRoZW9yeSwgdGhpcyAKLSAgICAvLyBmdW5jdGlvbiBzaG91bGQgbm90IGNoYW5nZSB0aGUgc3RyaW5nIHZhbHVlLgotCi0gICAgY2hhcltdIHN0cmluZ0FycmF5ID0gc3RyaW5nLnRvQ2hhckFycmF5KCk7Ci0gICAgaW50IGxlbiA9IHN0cmluZ0FycmF5Lmxlbmd0aDsKLSAgICAgICAgCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykKLSAgICB7Ci0gICAgICBjaGFyIGNoID0gc3RyaW5nQXJyYXlbaV07Ci0KLSAgICAgIGlmICgoY2ggPCAzMykgfHwgKGNoID4gMTI2KSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGRvVVJMRXNjYXBpbmcpCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBFbmNvZGUgVVRGMTYgdG8gVVRGOC4KLSAgICAgICAgICAvLyBSZWZlcmVuY2UgaXMgVW5pY29kZSwgQSBQcmltZXIsIGJ5IFRvbnkgR3JhaGFtLgotICAgICAgICAgIC8vIFBhZ2UgOTIuCi0gICAgICAgICAgCi0gICAgICAgICAgLy8gTm90ZSB0aGF0IEtheSBkb2Vzbid0IGVzY2FwZSAweDIwLi4uCi0gICAgICAgICAgLy8gIGlmKGNoID09IDB4MjApIC8vIE5vdCBzdXJlIGFib3V0IHRoaXMuLi4gLXNiCi0gICAgICAgICAgLy8gIHsKLSAgICAgICAgICAvLyAgICBhY2N1bShjaCk7Ci0gICAgICAgICAgLy8gIH0KLSAgICAgICAgICAvLyAgZWxzZSAKLSAgICAgICAgICBpZihjaCA8PSAweDdGKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGFjY3VtKCclJyk7Ci0gICAgICAgICAgICBhY2N1bShtYWtlSEhTdHJpbmcoY2gpKTsgICAgICAgICAgCi0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgaWYoY2ggPD0gMHg3RkYpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gQ2xlYXIgbG93IDYgYml0cyBiZWZvcmUgcm90YXRlLCBwdXQgaGlnaCA0IGJpdHMgaW4gbG93IGJ5dGUsIAotICAgICAgICAgICAgLy8gYW5kIHNldCB0d28gaGlnaCBiaXRzLgotICAgICAgICAgICAgaW50IGhpZ2ggPSAoY2ggPj4gNikgfCAweEMwOyAgCi0gICAgICAgICAgICBpbnQgbG93ID0gKGNoICYgMHgzRikgfCAweDgwOyAvLyBGaXJzdCA2IGJpdHMsICsgaGlnaCBiaXQKLSAgICAgICAgICAgIGFjY3VtKCclJyk7Ci0gICAgICAgICAgICBhY2N1bShtYWtlSEhTdHJpbmcoaGlnaCkpOwotICAgICAgICAgICAgYWNjdW0oJyUnKTsKLSAgICAgICAgICAgIGFjY3VtKG1ha2VISFN0cmluZyhsb3cpKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiggaXNVVEYxNlN1cnJvZ2F0ZShjaCkgKSAvLyBoaWdoIHN1cnJvZ2F0ZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIEknbSBzdXJlIHRoaXMgY2FuIGJlIGRvbmUgaW4gMyBpbnN0cnVjdGlvbnMsIGJ1dCBJIGNob29zZSAKLSAgICAgICAgICAgIC8vIHRvIHRyeSBhbmQgZG8gaXQgZXhhY3RseSBsaWtlIGl0IGlzIGRvbmUgaW4gdGhlIGJvb2ssIGF0IGxlYXN0IAotICAgICAgICAgICAgLy8gdW50aWwgd2UgYXJlIHN1cmUgdGhpcyBpcyB0b3RhbGx5IGNsZWFuLiAgSSBkb24ndCB0aGluayBwZXJmb3JtYW5jZSAKLSAgICAgICAgICAgIC8vIGlzIGEgYmlnIGlzc3VlIHdpdGggdGhpcyBwYXJ0aWN1bGFyIGZ1bmN0aW9uLCB0aG91Z2ggSSBjb3VsZCBiZSAKLSAgICAgICAgICAgIC8vIHdyb25nLiAgQWxzbywgdGhlIHN0dWZmIGJlbG93IGNsZWFybHkgZG9lcyBtb3JlIG1hc2tpbmcgdGhhbiAKLSAgICAgICAgICAgIC8vIGl0IG5lZWRzIHRvIGRvLgotICAgICAgICAgICAgCi0gICAgICAgICAgICAvLyBDbGVhciBoaWdoIDYgYml0cy4KLSAgICAgICAgICAgIGludCBoaWdoU3Vycm9nYXRlID0gKChpbnQpIGNoKSAmIDB4MDNGRjsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgLy8gTWlkZGxlIDQgYml0cyAod3d3dykgKyAxCi0gICAgICAgICAgICAvLyAiTm90ZSB0aGF0IHRoZSB2YWx1ZSBvZiB3d3d3IGZyb20gdGhlIGhpZ2ggc3Vycm9nYXRlIGJpdCBwYXR0ZXJuCi0gICAgICAgICAgICAvLyBpcyBpbmNyZW1lbnRlZCB0byBtYWtlIHRoZSB1dXV1dSBiaXQgcGF0dGVybiBpbiB0aGUgc2NhbGFyIHZhbHVlIAotICAgICAgICAgICAgLy8gc28gdGhlIHN1cnJvZ2F0ZSBwYWlyIGRvbid0IGFkZHJlc3MgdGhlIEJNUC4iCi0gICAgICAgICAgICBpbnQgd3d3dyA9ICgoaGlnaFN1cnJvZ2F0ZSAmIDB4MDNDMCkgPj4gNik7Ci0gICAgICAgICAgICBpbnQgdXV1dXUgPSB3d3d3KzE7ICAKLSAgICAgICAgICAgIAotICAgICAgICAgICAgLy8gbmV4dCA0IGJpdHMKLSAgICAgICAgICAgIGludCB6enp6ID0gKGhpZ2hTdXJyb2dhdGUgJiAweDAwM0MpID4+IDI7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vIGxvdyAyIGJpdHMKLSAgICAgICAgICAgIGludCB5eXl5eXkgPSAoKGhpZ2hTdXJyb2dhdGUgJiAweDAwMDMpIDw8IDQpICYgMHgzMDsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgLy8gR2V0IGxvdyBzdXJyb2dhdGUgY2hhcmFjdGVyLgotICAgICAgICAgICAgY2ggPSBzdHJpbmdBcnJheVsrK2ldOwotICAgICAgICAgICAgCi0gICAgICAgICAgICAvLyBDbGVhciBoaWdoIDYgYml0cy4KLSAgICAgICAgICAgIGludCBsb3dTdXJyb2dhdGUgPSAoKGludCkgY2gpICYgMHgwM0ZGOwotICAgICAgICAgICAgCi0gICAgICAgICAgICAvLyBwdXQgdGhlIG1pZGRsZSA0IGJpdHMgaW50byB0aGUgYm90dG9tIG9mIHl5eXl5eSAoYnl0ZSAzKQotICAgICAgICAgICAgeXl5eXl5ID0geXl5eXl5IHwgKChsb3dTdXJyb2dhdGUgJiAweDAzQzApID4+IDYpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICAvLyBib3R0b20gNiBiaXRzLgotICAgICAgICAgICAgaW50IHh4eHh4eCA9IChsb3dTdXJyb2dhdGUgJiAweDAwM0YpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICBpbnQgYnl0ZTEgPSAweEYwIHwgKHV1dXV1ID4+IDIpOyAvLyB0b3AgMyBiaXRzIG9mIHV1dXV1Ci0gICAgICAgICAgICBpbnQgYnl0ZTIgPSAweDgwIHwgKCgodXV1dXUgJiAweDAzKSA8PCA0KSAmIDB4MzApIHwgenp6ejsKLSAgICAgICAgICAgIGludCBieXRlMyA9IDB4ODAgfCB5eXl5eXk7Ci0gICAgICAgICAgICBpbnQgYnl0ZTQgPSAweDgwIHwgeHh4eHh4OwotICAgICAgICAgICAgCi0gICAgICAgICAgICBhY2N1bSgnJScpOwotICAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGJ5dGUxKSk7Ci0gICAgICAgICAgICBhY2N1bSgnJScpOwotICAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGJ5dGUyKSk7Ci0gICAgICAgICAgICBhY2N1bSgnJScpOwotICAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGJ5dGUzKSk7Ci0gICAgICAgICAgICBhY2N1bSgnJScpOwotICAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGJ5dGU0KSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGhpZ2ggPSAoY2ggPj4gMTIpIHwgMHhFMDsgLy8gdG9wIDQgYml0cwotICAgICAgICAgICAgaW50IG1pZGRsZSA9ICgoY2ggJiAweDBGQzApID4+IDYpIHwgMHg4MDsgLy8gbWlkZGxlIDYgYml0cwotICAgICAgICAgICAgaW50IGxvdyA9IChjaCAmIDB4M0YpIHwgMHg4MDsgLy8gRmlyc3QgNiBiaXRzLCArIGhpZ2ggYml0Ci0gICAgICAgICAgICBhY2N1bSgnJScpOwotICAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGhpZ2gpKTsKLSAgICAgICAgICAgIGFjY3VtKCclJyk7Ci0gICAgICAgICAgICBhY2N1bShtYWtlSEhTdHJpbmcobWlkZGxlKSk7Ci0gICAgICAgICAgICBhY2N1bSgnJScpOwotICAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGxvdykpOwotICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNoIDwgbV9tYXhDaGFyYWN0ZXIpCi0gICAgICAgIHsKLSAgICAgICAgICBhY2N1bShjaCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgYWNjdW0oIiYjIik7Ci0gICAgICAgICAgYWNjdW0oSW50ZWdlci50b1N0cmluZyhjaCkpOwotICAgICAgICAgIGFjY3VtKCc7Jyk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYoJyUnID09IGNoKQotICAgICAgewotICAgICAgICAvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIGEgJyUnIG51bWJlciBudW1iZXIsIHRyeSB0byBhdm9pZCBkb3VibGUtZXNjYXBpbmcuCi0gICAgICAgIC8vIFRoZXJlIGlzIGEgcXVlc3Rpb24gaWYgdGhpcyBpcyBsZWdhbCBiZWhhdmlvci4KLSAgICAgICAgICAKLS8vIERtaXRyaSBJbHlpbjogdG8gY2hlY2sgaWYgJyUnIG51bWJlciBudW1iZXIgaXMgaW52YWxpZC4gSXQgbXVzdCBiZSBjaGVja2VkIGlmICV4eCBpcyBhIHNpZ24sIHRoYXQgd291bGQgYmUgZW5jb2RlZAotLy8gVGhlIGVuY29kZWQgc2lnbmVzIGFyZSBpbiBIZXggZm9ybS4gU28gJXh4IG15IGJlIGluIGZvcm0gJTNDIHRoYXQgaXMgIjwiIHNpZ24uIEkgd2lsbCB0cnkgdG8gY2hhbmdlIGhlcmUgYSBsaXR0bGUuCi0gICAgICAgICAgCi0vLyAgICAgICAgaWYoICgoaSsyKSA8IGxlbikgJiYgaXNBU0NJSURpZ2l0KHN0cmluZ0FycmF5W2krMV0pICYmIGlzQVNDSUlEaWdpdChzdHJpbmdBcnJheVtpKzJdKSApCi0gICAgICAgIGlmICggKChpKzIpIDwgbGVuKSAmJiBpc0hIU2lnbihuZXcgU3RyaW5nKHN0cmluZ0FycmF5LGkrMSwyKSkgKQotICAgICAgICB7Ci0gICAgICAgICAgYWNjdW0oY2gpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGlmIChkb1VSTEVzY2FwaW5nKQotICAgICAgICAgIHsKLSAgICAgICAgICAgYWNjdW0oJyUnKTsKLSAgICAgICAgICAgYWNjdW0obWFrZUhIU3RyaW5nKGNoKSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGFjY3VtKGNoKTsKLSAgICAgICAgfSAgIAotICAgICAgICAgICAgICAgCi0gICAgICB9IAotICAgICAgLy8gU2luY2UgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQgcmVmZXJzIHRvIHRoZSBVUkkgZ3JhbW1hciBhcwotICAgICAgLy8gbm90IGFsbG93aW5nIHF1b3RlcyBpbiB0aGUgVVJJIHByb3BlciBzeW50YXgsIG5vciBpbiB0aGUgZnJhZ21lbnQgCi0gICAgICAvLyBpZGVudGlmaWVyLCB3ZSBiZWxpZXZlIHRoYXQgaXQncyBPSyB0byBkb3VibGUgZXNjYXBlIHF1b3Rlcy4KLSAgICAgIGVsc2UgaWYgKGNoID09ICciJykKLSAgICAgIHsKLSAgICAgICAgLy8gTWlrZSBLYXkgZW5jb2RlcyB0aGlzIGFzICYjMzQ7LCBzbyBoZSBtYXkga25vdyBzb21ldGhpbmcgSSBkb24ndD8KLSAgICAgICAgaWYgKGRvVVJMRXNjYXBpbmcpCi0gICAgICAgICAgYWNjdW0oIiUyMiIpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgYWNjdW0oIiZxdW90OyIpOyAvLyB3ZSBoYXZlIHRvIGVzY2FwZSB0aGlzLCBJIGd1ZXNzLgotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBhY2N1bShjaCk7Ci0gICAgICB9Ci0gICAgfQotICAgICAgICAgICAgICAKLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCA8dmFyPnN0cmluZzwvdmFyPiBhZnRlciBzdWJzdGl0dXRpbmcgPFZBUj5zcGVjaWFsczwvVkFSPiwKLSAgICogYW5kIFVURi0xNiBzdXJyb2dhdGVzIGZvciBjaGFyYWN0ZXIgcmVmZXJlbmNlcyA8Q09ERT4mYW1wOyN4bm48L0NPREU+LgotICAgKgotICAgKiBAcGFyYW0gICBzdHJpbmcgICAgICBTdHJpbmcgdG8gY29udmVydCB0byBYTUwgZm9ybWF0LgotICAgKiBAcGFyYW0gICBlbmNvZGluZyAgICBDVVJSRU5UTFkgTk9UIElNUExFTUVOVEVELgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGVBdHRyU3RyaW5nKFN0cmluZyBzdHJpbmcsIFN0cmluZyBlbmNvZGluZykKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGZpbmFsIGNoYXIgY2hhcnNbXSA9IHN0cmluZy50b0NoYXJBcnJheSgpOwotICAgIGZpbmFsIGludCBzdHJMZW4gPSBjaGFycy5sZW5ndGg7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0ckxlbjsgaSsrKQotICAgIHsKLSAgICAgIGNoYXIgY2ggPSBjaGFyc1tpXTsKLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJTUEVDSUFMU1NJWkU6ICIrU1BFQ0lBTFNTSVpFKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiY2g6ICIrKGludCljaCk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1fbWF4Q2hhcmFjdGVyOiAiKyhpbnQpbV9tYXhDaGFyYWN0ZXIpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJtX2F0dHJDaGFyc01hcFtjaF06ICIrKGludCltX2F0dHJDaGFyc01hcFtjaF0pOwotICAgICAgaWYgKChjaCA8IG1fbWF4Q2hhcmFjdGVyKSAmJiAoIW1fY2hhckluZm8uaXNTcGVjaWFsKGNoKSkpCi0gICAgICB7Ci0gICAgICAgIGFjY3VtKGNoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCc8JyA9PSBjaCB8fCAnPicgPT0gY2gpCi0gICAgICB7Ci0gICAgICAgIGFjY3VtKGNoKTsgIC8vIG5vIGVzY2FwaW5nIGluIHRoaXMgY2FzZSwgYXMgc3BlY2lmaWVkIGluIDE1LjIKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCgnJicgPT0gY2gpICYmICgoaSArIDEpIDwgc3RyTGVuKSAmJiAoJ3snID09IGNoYXJzW2kgKyAxXSkpCi0gICAgICB7Ci0gICAgICAgIGFjY3VtKGNoKTsgIC8vIG5vIGVzY2FwaW5nIGluIHRoaXMgY2FzZSwgYXMgc3BlY2lmaWVkIGluIDE1LjIKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IHBvcyA9IGFjY3VtRGVmYXVsdEVudGl0eShjaCwgaSwgY2hhcnMsIHN0ckxlbiwgZmFsc2UpOwotCi0gICAgICAgIGlmIChpICE9IHBvcykKLSAgICAgICAgewotICAgICAgICAgIGkgPSBwb3MgLSAxOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGlmIChpc1VURjE2U3Vycm9nYXRlKGNoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaSA9IHdyaXRlVVRGMTZTdXJyb2dhdGUoY2gsIGNoYXJzLCBpLCBzdHJMZW4pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gVGhlIG5leHQgaXMga2luZCBvZiBhIGhhY2sgdG8ga2VlcCBmcm9tIGVzY2FwaW5nIGluIHRoZSBjYXNlIAotICAgICAgICAgIC8vIG9mIFNoaWZ0X0pJUyBhbmQgdGhlIGxpa2UuCi0KLSAgICAgICAgICAvKgotICAgICAgICAgIGVsc2UgaWYgKChjaCA8IG1fbWF4Q2hhcmFjdGVyKSAmJiAobV9tYXhDaGFyYWN0ZXIgPT0gMHhGRkZGKQotICAgICAgICAgICYmIChjaCAhPSAxNjApKQotICAgICAgICAgIHsKLSAgICAgICAgICBhY2N1bShjaCk7ICAvLyBubyBlc2NhcGluZyBpbiB0aGlzIGNhc2UKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICovCi0gICAgICAgICAgU3RyaW5nIGVudGl0eU5hbWUgPSBtX2NoYXJJbmZvLmdldEVudGl0eU5hbWVGb3JDaGFyKGNoKTsKLQotICAgICAgICAgIGlmIChudWxsICE9IGVudGl0eU5hbWUpCi0gICAgICAgICAgewotICAgICAgICAgICAgYWNjdW0oJyYnKTsKLSAgICAgICAgICAgIGFjY3VtKGVudGl0eU5hbWUpOwotICAgICAgICAgICAgYWNjdW0oJzsnKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSBpZiAoY2ggPCBtX21heENoYXJhY3RlcikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhY2N1bShjaCk7ICAvLyBubyBlc2NhcGluZyBpbiB0aGlzIGNhc2UKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChjaCA8IG1fbWF4Q2hhcmFjdGVyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBhY2N1bShjaCk7ICAvLyBubyBlc2NhcGluZyBpbiB0aGlzIGNhc2UKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgYWNjdW0oIiYjIik7Ci0gICAgICAgICAgICAgIGFjY3VtKEludGVnZXIudG9TdHJpbmcoY2gpKTsKLSAgICAgICAgICAgICAgYWNjdW0oJzsnKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBhbiBlbnRpdHkgaW50byB0aGUgYWNjdW11bGF0aW9uIGJ1ZmZlci4KLSAgICoKLSAgICogQHBhcmFtIHMgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICogQHBhcmFtIHBvcyB1bnVzZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHBvcyBhcmd1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgaW50IGNvcHlFbnRpdHlJbnRvQnVmKFN0cmluZyBzLCBpbnQgcG9zKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGwgPSBzLmxlbmd0aCgpOwotCi0gICAgYWNjdW0oJyYnKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbDsgaSsrKQotICAgIHsKLSAgICAgIGFjY3VtKHMuY2hhckF0KGkpKTsKLSAgICB9Ci0KLSAgICBhY2N1bSgnOycpOwotCi0gICAgcmV0dXJuIHBvczsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICoKLSAgICogPHA+VGhlIFBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsgb2YKLSAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgKiBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKLSAgICogY2h1bmtzOyBob3dldmVyLCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudAotICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICogcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgKiBvdXRzaWRlIG9mIHRoZSBzcGVjaWZpZWQgcmFuZ2UuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAqIGlnbm9yYWJsZVdoaXRlc3BhY2UoKSBtZXRob2QgcmF0aGVyIHRoYW4gdGhpcyBvbmUgKHZhbGlkYXRpbmcKLSAgICogcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaGFycyBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaGFyc1tdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9pc1Jhd1N0YWNrLnBlZWtPckZhbHNlKCkpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIHdyaXRlUGFyZW50VGFnRW5kKCk7Ci0KLSAgICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLQotICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkpCi0gICAgICAgICAgaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0KLSAgICAgICAgLy8gdGhpcy5hY2N1bSgiPCFbQ0RBVEFbIik7Ci0gICAgICAgIC8vIHRoaXMuYWNjdW0oY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgICB3cml0ZU5vcm1hbGl6ZWRDaGFycyhjaGFycywgc3RhcnQsIGxlbmd0aCwgZmFsc2UpOwotCi0gICAgICAgIC8vIHRoaXMuYWNjdW0oIl1dPiIpOwotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKAotICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX09JRVJST1IsIG51bGwpLCBpb2UpOyAgLy8iSU8gZXJyb3IiLCBpb2UpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgc3VwZXIuY2hhcmFjdGVycyhjaGFycywgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjZGF0YS4KLSAgICoKLSAgICogIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAqICBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAqICBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKLSAgICogIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICogIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgKiAgcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uLjwvcD4KLSAgICoKLSAgICogIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAqCi0gICAqICA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAqICBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAqICBwYXJzZXJzIG11c3QgZG8gc28pLjwvcD4KLSAgICoKLSAgICogIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqICBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqICBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqICBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAqICBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNkYXRhKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKChudWxsICE9IG1fY3VycmVudEVsZW1lbnROYW1lKQotICAgICAgICAgICAgJiYgKG1fY3VycmVudEVsZW1lbnROYW1lLmVxdWFsc0lnbm9yZUNhc2UoIlNDUklQVCIpCi0gICAgICAgICAgICAgICAgfHwgbV9jdXJyZW50RWxlbWVudE5hbWUuZXF1YWxzSWdub3JlQ2FzZSgiU1RZTEUiKSkpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIHdyaXRlUGFyZW50VGFnRW5kKCk7Ci0KLSAgICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLQotICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkpCi0gICAgICAgICAgaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0KLSAgICAgICAgLy8gdGhpcy5hY2N1bShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICAgIHdyaXRlTm9ybWFsaXplZENoYXJzKGNoLCBzdGFydCwgbGVuZ3RoLCB0cnVlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfT0lFUlJPUiwgbnVsbCksIGlvZSk7ICAvLyJJTyBlcnJvciIsIGlvZSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyoKLSAgICBlbHNlIGlmKG1fc3RyaXBDRGF0YSkgLy8gc2hvdWxkIG5vcm1hbGx5IGFsd2F5cyBiZSBmYWxzZQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICB3cml0ZVBhcmVudFRhZ0VuZCgpOwotICAgICAgICBtX2lzcHJlc2VydmUgPSB0cnVlOwotICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkpCi0gICAgICAgICAgaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0gICAgICAgIC8vIHRoaXMuYWNjdW0oIjwhW0NEQVRBWyIpOwotICAgICAgICB0aGlzLmFjY3VtKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgICAgLy8gdGhpcy5hY2N1bSgiXV0+Iik7Ci0gICAgICB9Ci0gICAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfT0lFUlJPUiwgbnVsbCksaW9lKTsgLy8iSU8gZXJyb3IiLCBpb2UpOwotICAgICAgfQotICAgIH0KLSAgICAqLwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBzdXBlci5jZGF0YShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqICBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICogIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEsIG9yIG51bGwgaWYKLSAgICogICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KLSAgICogIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFVzZSBhIGZhaXJseSBuYXN0eSBoYWNrIHRvIHRlbGwgaWYgdGhlIG5leHQgbm9kZSBpcyBzdXBwb3NlZCB0byBiZSAKLSAgICAvLyB1bmVzY2FwZWQgdGV4dC4KLSAgICBpZiAodGFyZ2V0LmVxdWFscyhSZXN1bHQuUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcpKQotICAgIHsKLSAgICAgIHN0YXJ0Tm9uRXNjYXBpbmcoKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAodGFyZ2V0LmVxdWFscyhSZXN1bHQuUElfRU5BQkxFX09VVFBVVF9FU0NBUElORykpCi0gICAgewotICAgICAgZW5kTm9uRXNjYXBpbmcoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHdyaXRlUGFyZW50VGFnRW5kKCk7Ci0KLSAgICAgIGlmIChzaG91bGRJbmRlbnQoKSkKLSAgICAgICAgaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0KLSAgICAgIHRoaXMuYWNjdW0oIjw/IiArIHRhcmdldCk7Ci0KLSAgICAgIGlmIChkYXRhLmxlbmd0aCgpID4gMCAmJiFDaGFyYWN0ZXIuaXNTcGFjZUNoYXIoZGF0YS5jaGFyQXQoMCkpKQotICAgICAgICB0aGlzLmFjY3VtKCIgIik7Ci0KLSAgICAgIHRoaXMuYWNjdW0oZGF0YSArICI+Iik7ICAvLyBkaWZmZXJlbnQgZnJvbSBYTUwKLSAgICAgIAotICAgICAgLy8gQWx3YXlzIG91dHB1dCBhIG5ld2xpbmUgY2hhciBpZiBub3QgaW5zaWRlIG9mIGFuIAotICAgICAgLy8gZWxlbWVudC4gVGhlIHdoaXRlc3BhY2UgaXMgbm90IHNpZ25pZmljYW50IGluIHRoYXQKLSAgICAgIC8vIGNhc2UuCi0gICAgICBpZiAobV9lbGVtU3RhY2suaXNFbXB0eSgpKQotICAgICAgICAgb3V0cHV0TGluZVNlcCgpOwotCi0gICAgICBtX3N0YXJ0TmV3TGluZSA9IHRydWU7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aXZpY2F0aW9uIG9mIGEgZW50aXR5UmVmZXJlbmNlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gZW50aXR5IG5hbWUgc3RyaW5nLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRoaXMuYWNjdW0oIiYiKTsKLSAgICB0aGlzLmFjY3VtKG5hbWUpOwotICAgIHRoaXMuYWNjdW0oIjsiKTsKLSAgfQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvU2VyaWFsaXplclRvVGV4dC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1NlcmlhbGl6ZXJUb1RleHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGQ2YmVlZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvU2VyaWFsaXplclRvVGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTM3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotCi1pbXBvcnQgamF2YS5pby4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBUaGlzIGNsYXNzIHRha2VzIFNBWCBldmVudHMgKGluIGFkZGl0aW9uIHRvIHNvbWUgZXh0cmEgZXZlbnRzCi0gKiB0aGF0IFNBWCBkb2Vzbid0IGhhbmRsZSB5ZXQpIGFuZCBwcm9kdWNlcyBzaW1wbGUgdGV4dCBvbmx5LgotICovCi1wdWJsaWMgY2xhc3MgU2VyaWFsaXplclRvVGV4dCBleHRlbmRzIFNlcmlhbGl6ZXJUb1hNTAotewotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgotICAgKi8KLSAgcHVibGljIFNlcmlhbGl6ZXJUb1RleHQoKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgfQotCi0gICAvKioKLSAgICogUmVjZWl2ZSBhbiBvYmplY3QgZm9yIGxvY2F0aW5nIHRoZSBvcmlnaW4gb2YgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICoKLSAgICogPHA+U0FYIHBhcnNlcnMgYXJlIHN0cm9uZ2x5IGVuY291cmFnZWQgKHRob3VnaCBub3QgYWJzb2x1dGVseQotICAgKiByZXF1aXJlZCkgdG8gc3VwcGx5IGEgbG9jYXRvcjogaWYgaXQgZG9lcyBzbywgaXQgbXVzdCBzdXBwbHkKLSAgICogdGhlIGxvY2F0b3IgdG8gdGhlIGFwcGxpY2F0aW9uIGJ5IGludm9raW5nIHRoaXMgbWV0aG9kIGJlZm9yZQotICAgKiBpbnZva2luZyBhbnkgb2YgdGhlIG90aGVyIG1ldGhvZHMgaW4gdGhlIERvY3VtZW50SGFuZGxlcgotICAgKiBpbnRlcmZhY2UuPC9wPgotICAgKgotICAgKiA8cD5UaGUgbG9jYXRvciBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGRldGVybWluZSB0aGUgZW5kCi0gICAqIHBvc2l0aW9uIG9mIGFueSBkb2N1bWVudC1yZWxhdGVkIGV2ZW50LCBldmVuIGlmIHRoZSBwYXJzZXIgaXMKLSAgICogbm90IHJlcG9ydGluZyBhbiBlcnJvci4gIFR5cGljYWxseSwgdGhlIGFwcGxpY2F0aW9uIHdpbGwKLSAgICogdXNlIHRoaXMgaW5mb3JtYXRpb24gZm9yIHJlcG9ydGluZyBpdHMgb3duIGVycm9ycyAoc3VjaCBhcwotICAgKiBjaGFyYWN0ZXIgY29udGVudCB0aGF0IGRvZXMgbm90IG1hdGNoIGFuIGFwcGxpY2F0aW9uJ3MKLSAgICogYnVzaW5lc3MgcnVsZXMpLiAgVGhlIGluZm9ybWF0aW9uIHJldHVybmVkIGJ5IHRoZSBsb2NhdG9yCi0gICAqIGlzIHByb2JhYmx5IG5vdCBzdWZmaWNpZW50IGZvciB1c2Ugd2l0aCBhIHNlYXJjaCBlbmdpbmUuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGxvY2F0b3Igd2lsbCByZXR1cm4gY29ycmVjdCBpbmZvcm1hdGlvbiBvbmx5Ci0gICAqIGR1cmluZyB0aGUgaW52b2NhdGlvbiBvZiB0aGUgZXZlbnRzIGluIHRoaXMgaW50ZXJmYWNlLiAgVGhlCi0gICAqIGFwcGxpY2F0aW9uIHNob3VsZCBub3QgYXR0ZW1wdCB0byB1c2UgaXQgYXQgYW55IG90aGVyIHRpbWUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBBbiBvYmplY3QgdGhhdCBjYW4gcmV0dXJuIHRoZSBsb2NhdGlvbiBvZgotICAgKiAgICAgICAgICAgICAgICBhbnkgU0FYIGRvY3VtZW50IGV2ZW50LgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLQotICAgIC8vIE5vIGFjdGlvbiBmb3IgdGhlIG1vbWVudC4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9ubHkgb25jZSwgYmVmb3JlIGFueQotICAgKiBvdGhlciBtZXRob2RzIGluIHRoaXMgaW50ZXJmYWNlIG9yIGluIERUREhhbmRsZXIgKGV4Y2VwdCBmb3IKLSAgICogc2V0RG9jdW1lbnRMb2NhdG9yKS48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gTm8gYWN0aW9uIGZvciB0aGUgbW9tZW50LgotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25seSBvbmNlLCBhbmQgaXQgd2lsbAotICAgKiBiZSB0aGUgbGFzdCBtZXRob2QgaW52b2tlZCBkdXJpbmcgdGhlIHBhcnNlLiAgVGhlIHBhcnNlciBzaGFsbAotICAgKiBub3QgaW52b2tlIHRoaXMgbWV0aG9kIHVudGlsIGl0IGhhcyBlaXRoZXIgYWJhbmRvbmVkIHBhcnNpbmcKLSAgICogKGJlY2F1c2Ugb2YgYW4gdW5yZWNvdmVyYWJsZSBlcnJvcikgb3IgcmVhY2hlZCB0aGUgZW5kIG9mCi0gICAqIGlucHV0LjwvcD4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoV3JpdGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIGF0IHRoZSBiZWdpbm5pbmcgb2YgZXZlcnkKLSAgICogZWxlbWVudCBpbiB0aGUgWE1MIGRvY3VtZW50OyB0aGVyZSB3aWxsIGJlIGEgY29ycmVzcG9uZGluZwotICAgKiBlbmRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IHN0YXJ0RWxlbWVudCgpIGV2ZW50IChldmVuIHdoZW4gdGhlCi0gICAqIGVsZW1lbnQgaXMgZW1wdHkpLiBBbGwgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHdpbGwgYmUKLSAgICogcmVwb3J0ZWQsIGluIG9yZGVyLCBiZWZvcmUgdGhlIGNvcnJlc3BvbmRpbmcgZW5kRWxlbWVudCgpCi0gICAqIGV2ZW50LjwvcD4KLSAgICoKLSAgICogPHA+SWYgdGhlIGVsZW1lbnQgbmFtZSBoYXMgYSBuYW1lc3BhY2UgcHJlZml4LCB0aGUgcHJlZml4IHdpbGwKLSAgICogc3RpbGwgYmUgYXR0YWNoZWQuICBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSBsaXN0IHByb3ZpZGVkIHdpbGwKLSAgICogY29udGFpbiBvbmx5IGF0dHJpYnV0ZXMgd2l0aCBleHBsaWNpdCB2YWx1ZXMgKHNwZWNpZmllZCBvcgotICAgKiBkZWZhdWx0ZWQpOiAjSU1QTElFRCBhdHRyaWJ1dGVzIHdpbGwgYmUgb21pdHRlZC48L3A+Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kRWxlbWVudAotICAgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3QKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBhdCB0aGUgZW5kIG9mIGV2ZXJ5Ci0gICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKLSAgICogc3RhcnRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IGVuZEVsZW1lbnQoKSBldmVudCAoZXZlbiB3aGVuIHRoZQotICAgKiBlbGVtZW50IGlzIGVtcHR5KS48L3A+Ci0gICAqCi0gICAqIDxwPklmIHRoZSBlbGVtZW50IG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCwgdGhlIHByZWZpeCB3aWxsCi0gICAqIHN0aWxsIGJlIGF0dGFjaGVkIHRvIHRoZSBuYW1lLjwvcD4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZQotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIG5hbWUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAqIGNoYXJhY3RlciBkYXRhLiAgU0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyBjaGFyYWN0ZXIKLSAgICogZGF0YSBpbiBhIHNpbmdsZSBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsCi0gICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICogbXVzdCBjb21lIGZyb20gdGhlIHNhbWUgZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yCi0gICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHNvbWUgcGFyc2VycyB3aWxsIHJlcG9ydCB3aGl0ZXNwYWNlIHVzaW5nIHRoZQotICAgKiBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gdGhpcy5hY2N1bShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgd3JpdGVOb3JtYWxpemVkQ2hhcnMoY2gsIHN0YXJ0LCBsZW5ndGgsIGZhbHNlKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0gICAgdGhpcy5mbHVzaFdyaXRlcigpOwotCi0gICAgLy8gZmx1c2hXcml0ZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiBhdmFpbGFibGUsIHdoZW4gdGhlIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGF0dHJpYnV0ZSBpcyB1c2VkLAotICAgKiBvdXRwdXQgcmF3IHRleHQgd2l0aG91dCBlc2NhcGluZy4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVyc1JhdyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIGFjY3VtKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICB3cml0ZU5vcm1hbGl6ZWRDaGFycyhjaCwgc3RhcnQsIGxlbmd0aCwgZmFsc2UpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgICBmbHVzaFdyaXRlcigpOwotCi0gICAgLy8gZmx1c2hXcml0ZXIoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIE9uY2UgYSBzdXJyb2dhdGUgaGFzIGJlZW4gZGV0ZWN0ZWQsIHdyaXRlIHRoZSBwYWlyIGFzIGEgc2luZ2xlCi0gICAqIGNoYXJhY3RlciByZWZlcmVuY2UuCi0gICAqCi0gICAqIEBwYXJhbSBjIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBzdXJyb2dhdGUuCi0gICAqIEBwYXJhbSBjaCBDaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBpIHBvc2l0aW9uIFdoZXJlIHRoZSBzdXJyb2dhdGUgd2FzIGRldGVjdGVkLgotICAgKiBAcGFyYW0gZW5kIFRoZSBlbmQgaW5kZXggb2YgdGhlIHNpZ25pZmljYW50IGNoYXJhY3RlcnMuCi0gICAqIEByZXR1cm4gaSsxLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGlmIGludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgd3JpdGVVVEYxNlN1cnJvZ2F0ZShjaGFyIGMsIGNoYXIgY2hbXSwgaW50IGksIGludCBlbmQpCi0gICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gVVRGLTE2IHN1cnJvZ2F0ZQotICAgIGludCBzdXJyb2dhdGVWYWx1ZSA9IGdldFVSRjE2U3Vycm9nYXRlVmFsdWUoYywgY2gsIGksIGVuZCk7Ci0KLSAgICBpKys7Ci0KLSAgICAvLyBtX3dyaXRlci53cml0ZSgneCcpOwotICAgIG1fd3JpdGVyLndyaXRlKHN1cnJvZ2F0ZVZhbHVlKTsKLQotICAgIHJldHVybiBpOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBOb3JtYWxpemUgdGhlIGNoYXJhY3RlcnMsIGJ1dCBkb24ndCBlc2NhcGUuICBEaWZmZXJlbnQgZnJvbSAKLSAgICogU2VyaWFsaXplclRvWE1MI3dyaXRlTm9ybWFsaXplZENoYXJzIGJlY2F1c2UgaXQgZG9lcyBub3QgYXR0ZW1wdCB0byBkbyAKLSAgICogWE1MIGVzY2FwaW5nIGF0IGFsbC4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBpc0NEYXRhIHRydWUgaWYgYSBDREFUQSBibG9jayBzaG91bGQgYmUgYnVpbHQgYXJvdW5kIHRoZSBjaGFyYWN0ZXJzLgotICAgKgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICB2b2lkIHdyaXRlTm9ybWFsaXplZENoYXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoLCBib29sZWFuIGlzQ0RhdGEpCi0gICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGVuZCA9IHN0YXJ0ICsgbGVuZ3RoOwotCi0gICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspCi0gICAgewotICAgICAgY2hhciBjID0gY2hbaV07Ci0KLSAgICAgIGlmIChDaGFySW5mby5TX0xJTkVGRUVEID09IGMpCi0gICAgICB7Ci0gICAgICAgIG1fd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGlzQ0RhdGEgJiYgKGMgPiBtX21heENoYXJhY3RlcikpCi0gICAgICB7Ci0gICAgICAgIGlmIChpICE9IDApCi0gICAgICAgICAgbV93cml0ZXIud3JpdGUoIl1dPiIpOwotCi0gICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gZ28gaW50byBhIGZ1bmN0aW9uLi4uIAotICAgICAgICBpZiAoaXNVVEYxNlN1cnJvZ2F0ZShjKSkKLSAgICAgICAgewotICAgICAgICAgIGkgPSB3cml0ZVVURjE2U3Vycm9nYXRlKGMsIGNoLCBpLCBlbmQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG1fd3JpdGVyLndyaXRlKGMpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKChpICE9IDApICYmIChpIDwgKGVuZCAtIDEpKSkKLSAgICAgICAgICBtX3dyaXRlci53cml0ZSgiPCFbQ0RBVEFbIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChpc0NEYXRhCi0gICAgICAgICAgICAgICAmJiAoKGkgPCAoZW5kIC0gMikpICYmICgnXScgPT0gYykgJiYgKCddJyA9PSBjaFtpICsgMV0pCi0gICAgICAgICAgICAgICAgICAgJiYgKCc+JyA9PSBjaFtpICsgMl0pKSkKLSAgICAgIHsKLSAgICAgICAgbV93cml0ZXIud3JpdGUoIl1dXV0+PCFbQ0RBVEFbPiIpOwotCi0gICAgICAgIGkgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaWYgKGMgPD0gbV9tYXhDaGFyYWN0ZXIpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3dyaXRlci53cml0ZShjKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gZ28gaW50byBhIGZ1bmN0aW9uLi4uIAotICAgICAgICBlbHNlIGlmIChpc1VURjE2U3Vycm9nYXRlKGMpKQotICAgICAgICB7Ci0gICAgICAgICAgaSA9IHdyaXRlVVRGMTZTdXJyb2dhdGUoYywgY2gsIGksIGVuZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV93cml0ZXIud3JpdGUoYyk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2RhdGEuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAqIGNoYXJhY3RlciBkYXRhLiAgU0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyBjaGFyYWN0ZXIKLSAgICogZGF0YSBpbiBhIHNpbmdsZSBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsCi0gICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICogbXVzdCBjb21lIGZyb20gdGhlIHNhbWUgZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yCi0gICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHNvbWUgcGFyc2VycyB3aWxsIHJlcG9ydCB3aGl0ZXNwYWNlIHVzaW5nIHRoZQotICAgKiBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBjZGF0YShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIGFjY3VtKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICB3cml0ZU5vcm1hbGl6ZWRDaGFycyhjaCwgc3RhcnQsIGxlbmd0aCwgZmFsc2UpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgICBmbHVzaFdyaXRlcigpOwotCi0gICAgLy8gZmx1c2hXcml0ZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPlZhbGlkYXRpbmcgUGFyc2VycyBtdXN0IHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuawotICAgKiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSAoc2VlIHRoZSBXM0MgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiwKLSAgICogc2VjdGlvbiAyLjEwKTogbm9uLXZhbGlkYXRpbmcgcGFyc2VycyBtYXkgYWxzbyB1c2UgdGhpcyBtZXRob2QKLSAgICogaWYgdGhleSBhcmUgY2FwYWJsZSBvZiBwYXJzaW5nIGFuZCB1c2luZyBjb250ZW50IG1vZGVscy48L3A+Ci0gICAqCi0gICAqIDxwPlNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgd2hpdGVzcGFjZSBpbiBhIHNpbmdsZQotICAgKiBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsIGNodW5rczsgaG93ZXZlciwgYWxsIG9mCi0gICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICogZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yIHByb3ZpZGVzIHVzZWZ1bAotICAgKiBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlICNjaGFyYWN0ZXJzCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgd3JpdGVOb3JtYWxpemVkQ2hhcnMoY2gsIHN0YXJ0LCBsZW5ndGgsIGZhbHNlKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0gICAgZmx1c2hXcml0ZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBwcm9jZXNzaW5nCi0gICAqIGluc3RydWN0aW9uIGZvdW5kOiBub3RlIHRoYXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgbWF5IG9jY3VyCi0gICAqIGJlZm9yZSBvciBhZnRlciB0aGUgbWFpbiBkb2N1bWVudCBlbGVtZW50LjwvcD4KLSAgICoKLSAgICogPHA+QSBTQVggcGFyc2VyIHNob3VsZCBuZXZlciByZXBvcnQgYW4gWE1MIGRlY2xhcmF0aW9uIChYTUwgMS4wLAotICAgKiBzZWN0aW9uIDIuOCkgb3IgYSB0ZXh0IGRlY2xhcmF0aW9uIChYTUwgMS4wLCBzZWN0aW9uIDQuMy4xKQotICAgKiB1c2luZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLQotICAvKioKLSAgICogQ2FsbGVkIHdoZW4gYSBDb21tZW50IGlzIHRvIGJlIGNvbnN0cnVjdGVkLgotICAgKiBAcGFyYW0gICBkYXRhICBUaGUgY29tbWVudCBkYXRhLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbW1lbnQoU3RyaW5nIGRhdGEpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gTm8gYWN0aW9uIGZvciB0aGUgbW9tZW50LgotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aXZpY2F0aW9uIG9mIGEgZW50aXR5UmVmZXJlbmNlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIG5hbWUgb2YgdGhlIGVudGl0eS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9TZXJpYWxpemVyVG9YTUwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9TZXJpYWxpemVyVG9YTUwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTlmOTZjOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvU2VyaWFsaXplclRvWE1MLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDc4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOwotCi1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuQml0U2V0OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuRE9NU2VyaWFsaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkJvb2xTdGFjazsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN5c3RlbUlEUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFNlcmlhbGl6ZXJUb1hNTCBmb3JtYXRzIFNBWC1zdHlsZSBldmVudHMgaW50byBYTUwuCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyVG9YTUwKLSAgICAgICAgaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIsIERlY2xIYW5kbGVyLCBTZXJpYWxpemVyLAotICAgICAgICAgICAgICAgICAgIERPTVNlcmlhbGl6ZXIKLXsKLQotICAvKioKLSAgICogVGhlIHdyaXRlciB3aGVyZSB0aGUgWE1MIHdpbGwgYmUgd3JpdHRlbi4KLSAgICovCi0gIHByb3RlY3RlZCBXcml0ZXIgbV93cml0ZXIgPSBudWxsOwotCi0gIC8qKiBUcnVlIGlmIHdlIGNvbnRyb2wgdGhlIGJ1ZmZlciwgYW5kIHdlIHNob3VsZCBmbHVzaCB0aGUgb3V0cHV0IG9uIGVuZERvY3VtZW50LiAqLwotICBib29sZWFuIG1fc2hvdWxkRmx1c2ggPSB0cnVlOwotCi0gIC8vICAvKiogVGhlIG91dHB1dCBzdHJlYW0gd2hlcmUgdGhlIHJlc3VsdCBzdHJlYW0gaXMgd3JpdHRlbi4gKi8KLSAgLy8gIHByb3RlY3RlZCBPdXRwdXRTdHJlYW0gbV9vdXRwdXRTdHJlYW0gPSBTeXN0ZW0ub3V0OwotCi0gIC8qKgotICAgKiBUaGUgY2hhcmFjdGVyIGVuY29kaW5nLiAgTXVzdCBtYXRjaCB0aGUgZW5jb2RpbmcgdXNlZCBmb3IgdGhlIHByaW50V3JpdGVyLgotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBtX2VuY29kaW5nID0gbnVsbDsKLQotICAvKioKLSAgICogQXNzdW1lIGphdmEgZW5jb2RpbmcgbmFtZXMgYXJlIHRoZSBzYW1lIGFzIHRoZSBJU08gZW5jb2RpbmcgbmFtZXMgaWYgdGhpcyBpcyB0cnVlLgotICAgKi8KLSAgc3RhdGljIGJvb2xlYW4gamF2YUVuY29kaW5nSXNJU08gPSBmYWxzZTsKLQotICAvKioKLSAgICogVGVsbHMgaWYgd2Ugc2hvdWxkIHdyaXRlIHRoZSBYTUwgZGVjbGFyYXRpb24uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBtX3Nob3VsZE5vdFdyaXRlWE1MSGVhZGVyID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFRlbGxzIHRoZSBYTUwgdmVyc2lvbiwgZm9yIHdyaXRpbmcgb3V0IHRvIHRoZSBYTUwgZGVjbC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgbV92ZXJzaW9uID0gbnVsbDsKLQotICAvKioKLSAgICogQSBzdGFjayBvZiBCb29sZWFuIG9iamVjdHMgdGhhdCB0ZWxsIGlmIHRoZSBnaXZlbiBlbGVtZW50Ci0gICAqIGhhcyBjaGlsZHJlbi4KLSAgICovCi0gIHByb3RlY3RlZCBCb29sU3RhY2sgbV9lbGVtU3RhY2sgPSBuZXcgQm9vbFN0YWNrKCk7Ci0KLSAgLyoqIFN0YWNrIHRvIGtlZXAgdHJhY2sgb2YgZGlzYWJsaW5nIG91dHB1dCBlc2NhcGluZy4gKi8KLSAgcHJvdGVjdGVkIEJvb2xTdGFjayBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZ1N0YXRlcyA9IG5ldyBCb29sU3RhY2soKTsKLQotICAvKiogVHJ1ZSB3aWxsIGJlIHB1c2hlZCwgaWYgY2hhcmFjdGVycyBzaG91bGQgYmUgaW4gQ0RBVEEgc2VjdGlvbiBibG9ja3MuICovCi0gIHByb3RlY3RlZCBCb29sU3RhY2sgbV9jZGF0YVNlY3Rpb25TdGF0ZXMgPSBuZXcgQm9vbFN0YWNrKCk7Ci0KLSAgLyoqIExpc3Qgb2YgUU5hbWVzIG9idGFpbmVkIGZyb20gdGhlIHhzbDpvdXRwdXQgcHJvcGVydGllcy4gKi8KLSAgcHJvdGVjdGVkIFZlY3RvciBtX2NkYXRhU2VjdGlvbk5hbWVzID0gbnVsbDsKLQotICAvKiogVHJ1ZSBpZiB0aGUgY3VycmVudCBjaGFyYWN0ZXJzIHNob3VsZCBiZSBpbiBDREFUQSBibG9ja3MuICovCi0gIHByb3RlY3RlZCBib29sZWFuIG1faW5DRGF0YSA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBjaGFyYWN0ZXIgZXNjYXBpbmcgc2hvdWxkIGJlIGRpc2FibGVkIGZvciB0aGUgY3VycmVudCBzdGF0ZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgZXNjYXBpbmcgc2hvdWxkIGJlIGRpc2FibGVkLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gaXNFc2NhcGluZ0Rpc2FibGVkKCkKLSAgewotICAgIHJldHVybiBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZ1N0YXRlcy5wZWVrT3JGYWxzZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGN1cnJlbnQgc3RhdGUgc2hvdWxkIGJlIHB1dCBpbgotICAgKiBjZGF0YSBzZWN0aW9uIGJsb2Nrcy4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBjdXJyZW50IHN0YXRlIHNob3VsZCBiZSBwdXQgaW4KLSAgICogY2RhdGEgc2VjdGlvbiBibG9ja3MuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0NEYXRhU2VjdGlvbigpCi0gIHsKLSAgICByZXR1cm4gbV9pbkNEYXRhIHx8IG1fY2RhdGFTZWN0aW9uU3RhdGVzLnBlZWtPckZhbHNlKCk7Ci0gIH0KLQotICAvKioKLSAgICogVXNlIHRoZSBzeXN0ZW0gbGluZSBzZXBlcmF0b3IgdG8gd3JpdGUgbGluZSBicmVha3MuCi0gICAqLwotICBwcm90ZWN0ZWQgZmluYWwgY2hhcltdIG1fbGluZVNlcCA9Ci0gICAgU3lzdGVtLmdldFByb3BlcnR5KCJsaW5lLnNlcGFyYXRvciIpLnRvQ2hhckFycmF5KCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBsZW5ndGggb2YgdGhlIGxpbmUgc2VwZXJhdG9yLCBzaW5jZSB0aGUgd3JpdGUgaXMgZG9uZQotICAgKiBvbmUgY2hhcmFjdGVyIGF0IGEgdGltZS4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBpbnQgbV9saW5lU2VwTGVuID0gbV9saW5lU2VwLmxlbmd0aDsKLQotICAvKioKLSAgICogT3V0cHV0IGEgc3lzdGVtLWRlcGVuZGVudCBsaW5lIGJyZWFrLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgb3V0cHV0TGluZVNlcCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgbV93cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU3RhdGUgZmxhZyB0byB0ZWxsIGlmIHByZXNlcnZhdGlvbiBvZiB3aGl0ZXNwYWNlCi0gICAqIGlzIGltcG9ydGFudC4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIG1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBTdGFjayB0byBrZWVwIHRyYWNrIG9mIHdoZXRoZXIgb3Igbm90IHdlIG5lZWQgdG8KLSAgICogcHJlc2VydmUgd2hpdGVzcGFjZS4KLSAgICovCi0gIHByb3RlY3RlZCBCb29sU3RhY2sgbV9wcmVzZXJ2ZXMgPSBuZXcgQm9vbFN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIFN0YXRlIGZsYWcgdGhhdCB0ZWxscyBpZiB0aGUgcHJldmlvdXMgbm9kZSBwcm9jZXNzZWQKLSAgICogd2FzIHRleHQsIHNvIHdlIGNhbiB0ZWxsIGlmIHdlIHNob3VsZCBwcmVzZXJ2ZSB3aGl0ZXNwYWNlLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pc3ByZXZ0ZXh0ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIEZsYWcgdG8gdGVsbCBpZiBpbmRlbnRpbmcgKHByZXR0eS1wcmludGluZykgaXMgb24uCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2RvSW5kZW50ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIEZsYWcgdG8ga2VlcCB0cmFjayBvZiB0aGUgaW5kZW50IGFtb3VudC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9jdXJyZW50SW5kZW50ID0gMDsKLQotICAvKioKLSAgICogQW1vdW50IHRvIGluZGVudC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbV9pbmRlbnRBbW91bnQgPSAwOwotCi0gIC8qKgotICAgKiBDdXJyZW50IGxldmVsIG9mIGluZGVudC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgbGV2ZWwgPSAwOwotCi0gIC8qKgotICAgKiBGbGFnIHRvIHNpZ25hbCB0aGF0IGEgbmV3bGluZSBzaG91bGQgYmUgYWRkZWQuCi0gICAqLwotICBib29sZWFuIG1fc3RhcnROZXdMaW5lOwotCi0gIC8qKgotICAgKiBGbGFnIHRvIHRlbGwgdGhhdCB3ZSBuZWVkIHRvIGFkZCB0aGUgZG9jdHlwZSBkZWNsLAotICAgKiB3aGljaCB3ZSBjYW4ndCBkbyB1bnRpbCB0aGUgZmlyc3QgZWxlbWVudCBpcwotICAgKiBlbmNvdW50ZXJlZC4KLSAgICovCi0gIGJvb2xlYW4gbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIFRoZSBTeXN0ZW0gSUQgZm9yIHRoZSBkb2MgdHlwZS4KLSAgICovCi0gIFN0cmluZyBtX2RvY3R5cGVTeXN0ZW07Ci0KLSAgLyoqCi0gICAqIFRoZSBwdWJsaWMgSUQgZm9yIHRoZSBkb2MgdHlwZS4KLSAgICovCi0gIFN0cmluZyBtX2RvY3R5cGVQdWJsaWM7Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFuZGFsb25lIHZhbHVlIGZvciB0aGUgZG9jdHlwZS4KLSAgICovCi0gIGJvb2xlYW4gbV9zdGFuZGFsb25lID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFRydWUgaWYgc3RhbmRhbG9uZSB3YXMgc3BlY2lmaWVkLgotICAgKi8KLSAgYm9vbGVhbiBtX3N0YW5kYWxvbmVXYXNTcGVjaWZpZWQgPSBmYWxzZTsKLQotICAvKioKLSAgICogVGhlIG1lZGlhdHlwZS4gIE5vdCB1c2VkIHJpZ2h0IG5vdy4KLSAgICovCi0gIFN0cmluZyBtX21lZGlhdHlwZTsKLQotICAvKioKLSAgICogVGVsbHMgaWYgd2UncmUgaW4gYW4gRW50aXR5UmVmIGV2ZW50LgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pbkVudGl0eVJlZiA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUZWxscyBpZiB3ZSdyZSBpbiBhbiBpbnRlcm5hbCBkb2N1bWVudCB0eXBlIHN1YnNldC4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2luRG9jdHlwZSA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBNYXAgdGhhdCB0ZWxscyB3aGljaCBYTUwgY2hhcmFjdGVycyBzaG91bGQgaGF2ZSBzcGVjaWFsIHRyZWF0bWVudCwgYW5kIGl0Ci0gICAqICBwcm92aWRlcyBjaGFyYWN0ZXIgdG8gZW50aXR5IG5hbWUgbG9va3VwLgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBDaGFySW5mbyBtX3htbGNoYXJJbmZvID0KLSAgICBuZXcgQ2hhckluZm8oQ2hhckluZm8uWE1MX0VOVElUSUVTX1JFU09VUkNFKTsKLQotICAvKioKLSAgICogTWFwIHRoYXQgdGVsbHMgd2hpY2ggY2hhcmFjdGVycyBzaG91bGQgaGF2ZSBzcGVjaWFsIHRyZWF0bWVudCwgYW5kIGl0Ci0gICAqICBwcm92aWRlcyBjaGFyYWN0ZXIgdG8gZW50aXR5IG5hbWUgbG9va3VwLgotICAgKi8KLSAgcHJvdGVjdGVkIENoYXJJbmZvIG1fY2hhckluZm87Ci0KLSAgLyoqIFRhYmxlIG9mIHVzZXItc3BlY2lmaWVkIGNoYXIgaW5mb3MuICovCi0gIHByaXZhdGUgc3RhdGljIEhhc2h0YWJsZSBtX2NoYXJJbmZvcyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEZsYWcgdG8gcXVpY2tseSB0ZWxsIGlmIHRoZSBlbmNvZGluZyBpcyBVVEY4LgotICAgKi8KLSAgYm9vbGVhbiBtX2lzVVRGODsKLQotICAvKioKLSAgICogVGhlIG1heGltdW0gY2hhcmFjdGVyIHNpemUgYmVmb3JlIHdlIGhhdmUgdG8gcmVzb3J0Ci0gICAqIHRvIGVzY2FwaW5nLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX21heENoYXJhY3RlciA9IEVuY29kaW5ncy5nZXRMYXN0UHJpbnRhYmxlKCk7Ci0KLSAgLyoqCi0gICAqIEFkZCBzcGFjZSBiZWZvcmUgJy8+JyBmb3IgWEhUTUwuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBtX3NwYWNlQmVmb3JlQ2xvc2UgPSBmYWxzZTsKLQotICAvKiogVGhlIHhzbDpvdXRwdXQgcHJvcGVydGllcy4gKi8KLSAgcHJvdGVjdGVkIFByb3BlcnRpZXMgbV9mb3JtYXQ7Ci0KLSAgLyoqIEluZGljYXRlIHdoZXRoZXIgcnVubmluZyBpbiBEZWJ1ZyBtb2RlICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KLSAgICovCi0gIHB1YmxpYyBTZXJpYWxpemVyVG9YTUwoKQotICB7Ci0gICAgbV9jaGFySW5mbyA9IG1feG1sY2hhckluZm87Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBwcm9wZXJ0aWVzIGZyb20gYW5vdGhlciBTZXJpYWxpemVyVG9YTUwuCi0gICAqCi0gICAqIEBwYXJhbSB4bWxMaXN0ZW5lciBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBTZXJpYWxpemVyVG9YTUwgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgQ29weUZyb20oU2VyaWFsaXplclRvWE1MIHhtbExpc3RlbmVyKQotICB7Ci0KLSAgICBtX3dyaXRlciA9IHhtbExpc3RlbmVyLm1fd3JpdGVyOwotCi0gICAgLy8gbV9vdXRwdXRTdHJlYW0gPSB4bWxMaXN0ZW5lci5tX291dHB1dFN0cmVhbTsKLSAgICBtX2VuY29kaW5nID0geG1sTGlzdGVuZXIubV9lbmNvZGluZzsKLSAgICBqYXZhRW5jb2RpbmdJc0lTTyA9IHhtbExpc3RlbmVyLmphdmFFbmNvZGluZ0lzSVNPOwotICAgIG1fc2hvdWxkTm90V3JpdGVYTUxIZWFkZXIgPSB4bWxMaXN0ZW5lci5tX3Nob3VsZE5vdFdyaXRlWE1MSGVhZGVyOwotCi0gICAgLy8gbV9zaG91bGROb3RXcml0ZVhNTEhlYWRlciA9IHhtbExpc3RlbmVyLm1fc2hvdWxkTm90V3JpdGVYTUxIZWFkZXI7Ci0gICAgbV9lbGVtU3RhY2sgPSB4bWxMaXN0ZW5lci5tX2VsZW1TdGFjazsKLQotICAgIC8vIG1fbGluZVNlcCA9IHhtbExpc3RlbmVyLm1fbGluZVNlcDsKLSAgICAvLyBtX2xpbmVTZXBMZW4gPSB4bWxMaXN0ZW5lci5tX2xpbmVTZXBMZW47Ci0gICAgbV9pc3ByZXNlcnZlID0geG1sTGlzdGVuZXIubV9pc3ByZXNlcnZlOwotICAgIG1fcHJlc2VydmVzID0geG1sTGlzdGVuZXIubV9wcmVzZXJ2ZXM7Ci0gICAgbV9pc3ByZXZ0ZXh0ID0geG1sTGlzdGVuZXIubV9pc3ByZXZ0ZXh0OwotICAgIG1fZG9JbmRlbnQgPSB4bWxMaXN0ZW5lci5tX2RvSW5kZW50OwotICAgIG1fY3VycmVudEluZGVudCA9IHhtbExpc3RlbmVyLm1fY3VycmVudEluZGVudDsKLSAgICBtX2luZGVudEFtb3VudCA9IHhtbExpc3RlbmVyLm1faW5kZW50QW1vdW50OwotICAgIGxldmVsID0geG1sTGlzdGVuZXIubGV2ZWw7Ci0gICAgbV9zdGFydE5ld0xpbmUgPSB4bWxMaXN0ZW5lci5tX3N0YXJ0TmV3TGluZTsKLSAgICBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsID0geG1sTGlzdGVuZXIubV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbDsKLSAgICBtX2RvY3R5cGVTeXN0ZW0gPSB4bWxMaXN0ZW5lci5tX2RvY3R5cGVTeXN0ZW07Ci0gICAgbV9kb2N0eXBlUHVibGljID0geG1sTGlzdGVuZXIubV9kb2N0eXBlUHVibGljOwotICAgIG1fc3RhbmRhbG9uZSA9IHhtbExpc3RlbmVyLm1fc3RhbmRhbG9uZTsKLSAgICBtX21lZGlhdHlwZSA9IHhtbExpc3RlbmVyLm1fbWVkaWF0eXBlOwotICAgIG1fbWF4Q2hhcmFjdGVyID0geG1sTGlzdGVuZXIubV9tYXhDaGFyYWN0ZXI7Ci0gICAgbV9zcGFjZUJlZm9yZUNsb3NlID0geG1sTGlzdGVuZXIubV9zcGFjZUJlZm9yZUNsb3NlOwotICAgIG1faW5DRGF0YSA9IHhtbExpc3RlbmVyLm1faW5DRGF0YTsKLQotICAgIC8vIG1fcG9zID0geG1sTGlzdGVuZXIubV9wb3M7Ci0gICAgbV9wb3MgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIHNlcmlhbGl6ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIHdyaXRlciBhbmQgb3V0cHV0IGZvcm1hdC4KLSAgICogTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGNhbGxpbmcgYW55IG9mIHRoZSBzZXJpYWxpemUgbWV0aG9kcy4KLSAgICoKLSAgICogQHBhcmFtIHdyaXRlciBUaGUgd3JpdGVyIHRvIHVzZQotICAgKiBAcGFyYW0gZm9ybWF0IFRoZSBvdXRwdXQgZm9ybWF0Ci0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgaW5pdChXcml0ZXIgd3JpdGVyLCBQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgewotICAgIGluaXQod3JpdGVyLCBmb3JtYXQsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBzZXJpYWxpemVyIHdpdGggdGhlIHNwZWNpZmllZCB3cml0ZXIgYW5kIG91dHB1dCBmb3JtYXQuCi0gICAqIE11c3QgYmUgY2FsbGVkIGJlZm9yZSBjYWxsaW5nIGFueSBvZiB0aGUgc2VyaWFsaXplIG1ldGhvZHMuCi0gICAqCi0gICAqIEBwYXJhbSB3cml0ZXIgVGhlIHdyaXRlciB0byB1c2UKLSAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdAotICAgKiBAcGFyYW0gc2hvdWxkRmx1c2ggVHJ1ZSBpZiB0aGUgd3JpdGVyIHNob3VsZCBiZSBmbHVzaGVkIGF0IEVuZERvY3VtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBpbml0KFdyaXRlciB3cml0ZXIsIFByb3BlcnRpZXMgZm9ybWF0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRGbHVzaCkKLSAgewotCi0gICAgbV9zaG91bGRGbHVzaCA9IHNob3VsZEZsdXNoOwotICAgIG1fd3JpdGVyID0gd3JpdGVyOwotICAgIG1fZm9ybWF0ID0gZm9ybWF0OwotICAgIG1fY2RhdGFTZWN0aW9uTmFtZXMgPQotICAgICAgT3V0cHV0UHJvcGVydGllcy5nZXRRTmFtZVByb3BlcnRpZXMoT3V0cHV0S2V5cy5DREFUQV9TRUNUSU9OX0VMRU1FTlRTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0KTsKLSAgICBtX2luZGVudEFtb3VudCA9Ci0gICAgICBPdXRwdXRQcm9wZXJ0aWVzLmdldEludFByb3BlcnR5KE91dHB1dFByb3BlcnRpZXMuU19LRVlfSU5ERU5UX0FNT1VOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0KTsKLSAgICBtX2RvSW5kZW50ID0gT3V0cHV0UHJvcGVydGllcy5nZXRCb29sZWFuUHJvcGVydHkoT3V0cHV0S2V5cy5JTkRFTlQsCi0gICAgICAgICAgICBmb3JtYXQpOwotICAgIG1fc2hvdWxkTm90V3JpdGVYTUxIZWFkZXIgPQotICAgICAgT3V0cHV0UHJvcGVydGllcy5nZXRCb29sZWFuUHJvcGVydHkoT3V0cHV0S2V5cy5PTUlUX1hNTF9ERUNMQVJBVElPTiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCk7Ci0gICAgbV9kb2N0eXBlU3lzdGVtID0gZm9ybWF0LmdldFByb3BlcnR5KE91dHB1dEtleXMuRE9DVFlQRV9TWVNURU0pOwotICAgIG1fZG9jdHlwZVB1YmxpYyA9IGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkRPQ1RZUEVfUFVCTElDKTsKLSAgICBtX3N0YW5kYWxvbmVXYXNTcGVjaWZpZWQgPSAobnVsbCAhPSBmb3JtYXQuZ2V0KE91dHB1dEtleXMuU1RBTkRBTE9ORSkpOwotICAgIG1fc3RhbmRhbG9uZSA9IE91dHB1dFByb3BlcnRpZXMuZ2V0Qm9vbGVhblByb3BlcnR5KE91dHB1dEtleXMuU1RBTkRBTE9ORSwKLSAgICAgICAgICAgIGZvcm1hdCk7Ci0gICAgbV9tZWRpYXR5cGUgPSBmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRURJQV9UWVBFKTsKLQotICAgIGlmIChudWxsICE9IG1fZG9jdHlwZVB1YmxpYykKLSAgICB7Ci0gICAgICBpZiAobV9kb2N0eXBlUHVibGljLnN0YXJ0c1dpdGgoIi0vL1czQy8vRFREIFhIVE1MIikpCi0gICAgICAgIG1fc3BhY2VCZWZvcmVDbG9zZSA9IHRydWU7Ci0gICAgfQotCi0gICAgLy8gaW5pdENoYXJzTWFwKCk7Ci0gICAgaWYgKG51bGwgPT0gbV9lbmNvZGluZykKLSAgICAgIG1fZW5jb2RpbmcgPQotICAgICAgICBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKGZvcm1hdC5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HKSk7Ci0KLSAgICBtX2lzVVRGOCA9IG1fZW5jb2RpbmcuZXF1YWxzKEVuY29kaW5ncy5ERUZBVUxUX01JTUVfRU5DT0RJTkcpOwotICAgIG1fbWF4Q2hhcmFjdGVyID0gRW5jb2RpbmdzLmdldExhc3RQcmludGFibGUobV9lbmNvZGluZyk7Ci0KLSAgICAvLyBBY2Nlc3MgdGhpcyBvbmx5IGZyb20gdGhlIEhhc2h0YWJsZSBsZXZlbC4uLiB3ZSBkb24ndCB3YW50IHRvIAotICAgIC8vIGdldCBkZWZhdWx0IHByb3BlcnRpZXMuCi0gICAgU3RyaW5nIGVudGl0aWVzRmlsZU5hbWUgPQotICAgICAgKFN0cmluZykgZm9ybWF0LmdldChPdXRwdXRQcm9wZXJ0aWVzLlNfS0VZX0VOVElUSUVTKTsKLQotICAgIGlmIChudWxsICE9IGVudGl0aWVzRmlsZU5hbWUpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIG1fY2hhckluZm8gPSBudWxsOwotCi0gICAgICAgIGlmIChudWxsID09IG1fY2hhckluZm9zKQotICAgICAgICB7Ci0gICAgICAgICAgc3luY2hyb25pemVkIChtX3htbGNoYXJJbmZvKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChudWxsID09IG1fY2hhckluZm9zKSAgLy8gc2Vjb25kYXJ5IGNoZWNrCi0gICAgICAgICAgICAgIG1fY2hhckluZm9zID0gbmV3IEhhc2h0YWJsZSgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBtX2NoYXJJbmZvID0gKENoYXJJbmZvKSBtX2NoYXJJbmZvcy5nZXQoZW50aXRpZXNGaWxlTmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCA9PSBtX2NoYXJJbmZvKQotICAgICAgICB7Ci0gICAgICAgICAgU3RyaW5nIGFic29sdXRlRW50aXRpZXNGaWxlTmFtZTsKLQotICAgICAgICAgIGlmIChlbnRpdGllc0ZpbGVOYW1lLmluZGV4T2YoJzonKSA8IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgYWJzb2x1dGVFbnRpdGllc0ZpbGVOYW1lID0KLSAgICAgICAgICAgICAgU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSUZyb21SZWxhdGl2ZShlbnRpdGllc0ZpbGVOYW1lKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGFic29sdXRlRW50aXRpZXNGaWxlTmFtZSA9Ci0gICAgICAgICAgICAgIFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoZW50aXRpZXNGaWxlTmFtZSwgbnVsbCk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgbV9jaGFySW5mbyA9IG5ldyBDaGFySW5mbyhhYnNvbHV0ZUVudGl0aWVzRmlsZU5hbWUpOwotCi0gICAgICAgICAgbV9jaGFySW5mb3MucHV0KGVudGl0aWVzRmlsZU5hbWUsIG1fY2hhckluZm8pOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgc2VyaWFsaXplciB3aXRoIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbSBhbmQgb3V0cHV0IGZvcm1hdC4KLSAgICogTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGNhbGxpbmcgYW55IG9mIHRoZSBzZXJpYWxpemUgbWV0aG9kcy4KLSAgICoKLSAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbSB0byB1c2UKLSAgICogQHBhcmFtIGZvcm1hdCBUaGUgb3V0cHV0IGZvcm1hdAotICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gVGhlIGVuY29kaW5nIHNwZWNpZmllZAotICAgKiAgIGluIHRoZSBvdXRwdXQgZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQKLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbml0KE91dHB1dFN0cmVhbSBvdXRwdXQsIFByb3BlcnRpZXMgZm9ybWF0KQotICAgICAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IGZvcm1hdCkKLSAgICB7Ci0gICAgICBPdXRwdXRQcm9wZXJ0aWVzIG9wID0gbmV3IE91dHB1dFByb3BlcnRpZXMoTWV0aG9kLlhNTCk7Ci0KLSAgICAgIGZvcm1hdCA9IG9wLmdldFByb3BlcnRpZXMoKTsKLSAgICB9Ci0KLSAgICBtX2VuY29kaW5nID0KLSAgICAgIEVuY29kaW5ncy5nZXRNaW1lRW5jb2RpbmcoZm9ybWF0LmdldFByb3BlcnR5KE91dHB1dEtleXMuRU5DT0RJTkcpKTsKLQotICAgIGlmIChtX2VuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIlVURi04IikpCi0gICAgewotICAgICAgaWYob3V0cHV0IGluc3RhbmNlb2YgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbSkKLSAgICAgIHsKLSAgICAgICAgaW5pdChuZXcgV3JpdGVyVG9VVEY4KG91dHB1dCksIGZvcm1hdCwgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKG91dHB1dCBpbnN0YW5jZW9mIGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbSkKLSAgICAgIHsKLSAgICAgICAgaW5pdChuZXcgV3JpdGVyVG9VVEY4QnVmZmVyZWQob3V0cHV0KSwgZm9ybWF0LCB0cnVlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgLy8gTm90IHN1cmUgd2hhdCB0byBkbyBpbiB0aGlzIGNhc2UuICBJJ20gZ29pbmcgdG8gYmUgY29uc2VydmF0aXZlIAotICAgICAgICAvLyBhbmQgbm90IGJ1ZmZlci4KLSAgICAgICAgaW5pdChuZXcgV3JpdGVyVG9VVEY4KG91dHB1dCksIGZvcm1hdCwgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgICAKLSAgICB9Ci0gICAgZWxzZSBpZiAobV9lbmNvZGluZy5lcXVhbHMoIldJTkRPV1MtMTI1MCIpCi0gICAgICAgICAgICAgfHwgbV9lbmNvZGluZy5lcXVhbHMoIlVTLUFTQ0lJIikgfHwgbV9lbmNvZGluZy5lcXVhbHMoIkFTQ0lJIikpCi0gICAgewotICAgICAgaW5pdChuZXcgV3JpdGVyVG9BU0NJKG91dHB1dCksIGZvcm1hdCwgdHJ1ZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBXcml0ZXIgb3N3OwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgb3N3ID0gRW5jb2RpbmdzLmdldFdyaXRlcihvdXRwdXQsIG1fZW5jb2RpbmcpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWVlKQotICAgICAgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIldhcm5pbmc6IGVuY29kaW5nIFwiIiArIG1fZW5jb2RpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlwiIG5vdCBzdXBwb3J0ZWQiICsgIiwgdXNpbmcgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBFbmNvZGluZ3MuREVGQVVMVF9NSU1FX0VOQ09ESU5HKTsKLQotICAgICAgICBtX2VuY29kaW5nID0gRW5jb2RpbmdzLkRFRkFVTFRfTUlNRV9FTkNPRElORzsKLSAgICAgICAgb3N3ID0gRW5jb2RpbmdzLmdldFdyaXRlcihvdXRwdXQsIG1fZW5jb2RpbmcpOwotICAgICAgfQotCi0gICAgICBtX21heENoYXJhY3RlciA9IEVuY29kaW5ncy5nZXRMYXN0UHJpbnRhYmxlKG1fZW5jb2RpbmcpOwotCi0gICAgICBpbml0KG9zdywgZm9ybWF0LCB0cnVlKTsKLSAgICB9Ci0gICAgCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBhbiBvYmplY3QgZm9yIGxvY2F0aW5nIHRoZSBvcmlnaW4gb2YgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0b3IgQW4gb2JqZWN0IHRoYXQgY2FuIHJldHVybiB0aGUgbG9jYXRpb24gb2YKLSAgICogICAgICAgICAgICAgICAgYW55IFNBWCBkb2N1bWVudCBldmVudC4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0KLSAgICAvLyBJIGRvbid0IGRvIGFueXRoaW5nIHdpdGggdGhpcyB5ZXQuCi0gIH0KLQotICAvKioKLSAgICogT3V0cHV0IHRoZSBkb2MgdHlwZSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGRvY3VtZW50IHR5cGUgbmFtZS4KLSAgICogTkVFRFNET0MgQHBhcmFtIGNsb3NlRGVjbAotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgdm9pZCBvdXRwdXREb2NUeXBlRGVjbChTdHJpbmcgbmFtZSwgYm9vbGVhbiBjbG9zZURlY2wpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAKLSAgICAgIHdyaXRlci53cml0ZSgiPCFET0NUWVBFICIpOwotICAgICAgd3JpdGVyLndyaXRlKG5hbWUpOwotICAKLSAgICAgIGlmIChudWxsICE9IG1fZG9jdHlwZVB1YmxpYykKLSAgICAgIHsKLSAgICAgICAgd3JpdGVyLndyaXRlKCIgUFVCTElDIFwiIik7Ci0gICAgICAgIHdyaXRlci53cml0ZShtX2RvY3R5cGVQdWJsaWMpOwotICAgICAgICB3cml0ZXIud3JpdGUoJ1wiJyk7Ci0gICAgICB9Ci0gIAotICAgICAgaWYgKG51bGwgIT0gbV9kb2N0eXBlU3lzdGVtKQotICAgICAgewotICAgICAgICBpZiAobnVsbCA9PSBtX2RvY3R5cGVQdWJsaWMpCi0gICAgICAgICAgd3JpdGVyLndyaXRlKCIgU1lTVEVNIFwiIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICB3cml0ZXIud3JpdGUoIiBcIiIpOwotICAKLSAgICAgICAgd3JpdGVyLndyaXRlKG1fZG9jdHlwZVN5c3RlbSk7Ci0gIAotICAgICAgICBpZiAoY2xvc2VEZWNsKQotICAgICAgICB7Ci0gICAgICAgICAgd3JpdGVyLndyaXRlKCJcIj4iKTsKLSAgICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOzsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgd3JpdGVyLndyaXRlKCdcIicpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBPdXRwdXQgdGhlIGRvYyB0eXBlIGRlY2xhcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gZG9jdW1lbnQgdHlwZSBuYW1lLgotICAgKiBORUVEU0RPQyBAcGFyYW0gdmFsdWUKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgb3V0cHV0RW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgd3JpdGVyLndyaXRlKCI8IUVOVElUWSAiKTsKLSAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgIHdyaXRlci53cml0ZSgiIFwiIik7Ci0gICAgICB3cml0ZXIud3JpdGUodmFsdWUpOwotICAgICAgd3JpdGVyLndyaXRlKCJcIj4iKTsKLSAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgIHJldHVybjsKLQotICAgIG1fbmVlZFRvT3V0cHV0RG9jVHlwZURlY2wgPSB0cnVlOwotICAgIG1fc3RhcnROZXdMaW5lID0gZmFsc2U7Ci0KLSAgICBpZiAobV9zaG91bGROb3RXcml0ZVhNTEhlYWRlciA9PSBmYWxzZSkKLSAgICB7Ci0gICAgICBTdHJpbmcgZW5jb2RpbmcgPSBFbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKG1fZW5jb2RpbmcpOwotICAgICAgU3RyaW5nIHZlcnNpb24gPSAobnVsbCA9PSBtX3ZlcnNpb24pID8gIjEuMCIgOiBtX3ZlcnNpb247Ci0gICAgICBTdHJpbmcgc3RhbmRhbG9uZTsKLQotICAgICAgaWYgKG1fc3RhbmRhbG9uZVdhc1NwZWNpZmllZCkKLSAgICAgIHsKLSAgICAgICAgc3RhbmRhbG9uZSA9ICIgc3RhbmRhbG9uZT1cIiIgKyAobV9zdGFuZGFsb25lID8gInllcyIgOiAibm8iKSArICJcIiI7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHN0YW5kYWxvbmUgPSAiIjsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGZpbmFsIFdyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgd3JpdGVyLndyaXRlKCI8P3htbCB2ZXJzaW9uPVwiIik7Ci0gICAgICAgIHdyaXRlci53cml0ZSh2ZXJzaW9uKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCJcIiBlbmNvZGluZz1cIiIpOwotICAgICAgICB3cml0ZXIud3JpdGUoZW5jb2RpbmcpOwotICAgICAgICB3cml0ZXIud3JpdGUoJ1wiJyk7Ci0gICAgICAgIHdyaXRlci53cml0ZShzdGFuZGFsb25lKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCI/PiIpOwotICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgICAgfQotICAgICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG1fZG9JbmRlbnQgJiYhbV9pc3ByZXZ0ZXh0KQotICAgIHsKLSAgICAgIG91dHB1dExpbmVTZXAoKTsKLSAgICB9Ci0KLSAgICBmbHVzaFdyaXRlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgc3RhcnQgb2YgRFREIGRlY2xhcmF0aW9ucywgaWYgYW55LgotICAgKgotICAgKiBBbnkgZGVjbGFyYXRpb25zIGFyZSBhc3N1bWVkIHRvIGJlIGluIHRoZSBpbnRlcm5hbCBzdWJzZXQKLSAgICogdW5sZXNzIG90aGVyd2lzZSBpbmRpY2F0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBkb2N1bWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZQotICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBkZWNsYXJlZCBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlCi0gICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuCi0gICAqICAgICAgICAgICAgZXhjZXB0aW9uLgotICAgKiBAc2VlICNlbmREVEQKLSAgICogQHNlZSAjc3RhcnRFbnRpdHkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIG1fZG9jdHlwZVN5c3RlbSA9IHN5c3RlbUlkOwotICAgIG1fZG9jdHlwZVB1YmxpYyA9IHB1YmxpY0lkOwotCi0gICAgaWYgKCh0cnVlID09IG1fbmVlZFRvT3V0cHV0RG9jVHlwZURlY2wpKSAgLy8gJiYgKG51bGwgIT0gbV9kb2N0eXBlU3lzdGVtKSkKLSAgICB7Ci0gICAgICBvdXRwdXREb2NUeXBlRGVjbChuYW1lLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCA9IGZhbHNlOwotICAgIG1faW5Eb2N0eXBlID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBEVEQgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjc3RhcnREVEQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIGlmICghbV9pbkRvY3R5cGUpCi0gICAgICAgIG1fd3JpdGVyLndyaXRlKCJdPiIpOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3dyaXRlci53cml0ZSgnPicpOwotICAgICAgfQotICAKLSAgICAgIG1fd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0KLSAgICAvLyBEbyBub3RoaW5nIGZvciBub3cuCi0gIH0KLQotICAvKioKLSAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcKLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSB0aGUgcHJlZml4IGlzIG1hcHBlZCB0by4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ue30KLQotICAvKioKLSAgICogRW5kIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZwotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdGhhdCB3YXMgYmVpbmcgbWFwcGluZy4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbnt9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIHN0cmluZ3MgYXJlIGVxdWFsLCB3aXRob3V0IHdvcnJ5IGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgbnVsbC4KLSAgICoKLSAgICogQHBhcmFtIHAgU3RyaW5nIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSB0IFN0cmluZyByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgc3RyaW5ncyBhcmUgZXF1YWwuCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gc3ViUGFydE1hdGNoKFN0cmluZyBwLCBTdHJpbmcgdCkKLSAgewotICAgIHJldHVybiAocCA9PSB0KSB8fCAoKG51bGwgIT0gcCkgJiYgKHAuZXF1YWxzKHQpKSk7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaCBhIGJvb2xlYW4gc3RhdGUgYmFzZWQgb24gaWYgdGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQKLSAgICogaXMgZm91bmQgaW4gdGhlIGxpc3Qgb2YgcW5hbWVzLiAgQSBzdGF0ZSBpcyBhbHdheXMgcHVzaGVkLAotICAgKiBvbmUgd2F5IG9yIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBTaG91bGQgYmUgYSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIG5hbWVzcGFjZSBVUkwKLSAgICogICAgICAgIG9mIHRoZSBlbGVtZW50IHRoYXQgb3ducyB0aGUgc3RhdGUsIG9yIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBTaG91bGQgYmUgYSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGxvY2FsIG5hbWUKLSAgICogICAgICAgIG9mIHRoZSBlbGVtZW50IHRoYXQgb3ducyB0aGUgc3RhdGUuCi0gICAqIEBwYXJhbSBxbmFtZXMgVmVjdG9yIG9mIHF1YWxpZmllZCBuYW1lcyBvZiBlbGVtZW50cywgb3IgbnVsbC4KLSAgICogQHBhcmFtIHN0YXRlIFRoZSBzdGFjayB3aGVyZSB0aGUgc3RhdGUgc2hvdWxkIGJlIHB1c2hlZC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHB1c2hTdGF0ZShTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yIHFuYW1lcywgQm9vbFN0YWNrIHN0YXRlKQotICB7Ci0KLSAgICBib29sZWFuIGI7Ci0KLSAgICBpZiAobnVsbCAhPSBxbmFtZXMpCi0gICAgewotICAgICAgYiA9IGZhbHNlOwotCi0gICAgICBpZiAoKG51bGwgIT0gbmFtZXNwYWNlVVJJKSAmJiBuYW1lc3BhY2VVUkkubGVuZ3RoKCkgPT0gMCkKLSAgICAgICAgbmFtZXNwYWNlVVJJID0gbnVsbDsKLQotICAgICAgaW50IG5FbGVtcyA9IHFuYW1lcy5zaXplKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkVsZW1zOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFFOYW1lIHEgPSAoUU5hbWUpIHFuYW1lcy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgaWYgKHEuZ2V0TG9jYWxOYW1lKCkuZXF1YWxzKGxvY2FsTmFtZSkKLSAgICAgICAgICAgICAgICAmJiBzdWJQYXJ0TWF0Y2gobmFtZXNwYWNlVVJJLCBxLmdldE5hbWVzcGFjZVVSSSgpKSkKLSAgICAgICAgewotICAgICAgICAgIGIgPSB0cnVlOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGIgPSBzdGF0ZS5wZWVrT3JGYWxzZSgpOwotICAgIH0KLQotICAgIHN0YXRlLnB1c2goYik7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgZWxlbWVudCBoYXMgbm8gTmFtZXNwYWNlIFVSSSBvciBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcKLSAgICogICAgICAgIHBlcmZvcm1lZC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydEVsZW1lbnQKLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguQXR0cmlidXRlTGlzdAotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNlcmlhbGl6ZXJUb1hNTCAtIHN0YXJ0RWxlbWVudDogIiArIG5hbWVzcGFjZVVSSQotICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgIiArIGxvY2FsTmFtZSk7Ci0KLSAgICAgIGludCBuID0gYXR0cy5nZXRMZW5ndGgoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiYXR0c1siICsgaSArICJdOiAiICsgYXR0cy5nZXRRTmFtZShpKSArICIgPSAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICArIGF0dHMuZ2V0VmFsdWUoaSkpOwotICAgICAgfQotCi0gICAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VVUkkpCi0gICAgICB7Ci0gICAgICAgIChuZXcgUnVudGltZUV4Y2VwdGlvbihsb2NhbE5hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBoYXMgYSBudWxsIG5hbWVzcGFjZSEiKSkucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKG1faW5FbnRpdHlSZWYpCi0gICAgICByZXR1cm47Ci0KLSAgICBpZiAoKHRydWUgPT0gbV9uZWVkVG9PdXRwdXREb2NUeXBlRGVjbCkgJiYgKG51bGwgIT0gbV9kb2N0eXBlU3lzdGVtKSkKLSAgICB7Ci0gICAgICBvdXRwdXREb2NUeXBlRGVjbChuYW1lLCB0cnVlKTsKLSAgICB9Ci0KLSAgICBtX25lZWRUb091dHB1dERvY1R5cGVEZWNsID0gZmFsc2U7Ci0KLSAgICB3cml0ZVBhcmVudFRhZ0VuZCgpOwotICAgIHB1c2hTdGF0ZShuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgbV9jZGF0YVNlY3Rpb25OYW1lcywKLSAgICAgICAgICAgICAgbV9jZGF0YVNlY3Rpb25TdGF0ZXMpOwotCi0gICAgLy8gcHVzaFN0YXRlKG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBtX2Zvcm1hdC5nZXROb25Fc2NhcGluZ0VsZW1lbnRzKCksCi0gICAgLy8gICAgICAgICAgbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMpOwotICAgIG1faXNwcmVzZXJ2ZSA9IGZhbHNlOwotCi0gICAgLy8gIFN5c3RlbS5vdXQucHJpbnRsbihuYW1lKyI6IG1fZG9JbmRlbnQgPSAiK21fZG9JbmRlbnQrIiwgbV9pc3ByZXNlcnZlID0gIittX2lzcHJlc2VydmUrIiwgbV9pc3ByZXZ0ZXh0ID0gIittX2lzcHJldnRleHQpOwotICAgIGlmIChzaG91bGRJbmRlbnQoKSAmJiBtX3N0YXJ0TmV3TGluZSkKLSAgICB7Ci0gICAgICBpbmRlbnQobV9jdXJyZW50SW5kZW50KTsKLSAgICB9Ci0KLSAgICBtX3N0YXJ0TmV3TGluZSA9IHRydWU7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBtX3dyaXRlci53cml0ZSgnPCcpOwotICAgICAgbV93cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotCi0gICAgaW50IG5BdHRycyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRyczsgaSsrKQotICAgIHsKLSAgICAgIHByb2Nlc3NBdHRyaWJ1dGUoYXR0cy5nZXRRTmFtZShpKSwgYXR0cy5nZXRWYWx1ZShpKSk7Ci0gICAgfQotCi0gICAgLy8gRmxhZyB0aGUgY3VycmVudCBlbGVtZW50IGFzIG5vdCB5ZXQgaGF2aW5nIGFueSBjaGlsZHJlbi4KLSAgICBvcGVuRWxlbWVudEZvckNoaWxkcmVuKCk7Ci0KLSAgICBtX2N1cnJlbnRJbmRlbnQgKz0gbV9pbmRlbnRBbW91bnQ7Ci0gICAgbV9pc3ByZXZ0ZXh0ID0gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdG8gc2VlIGlmIGEgcGFyZW50J3MgIj4iIGhhcyBiZWVuIHdyaXR0ZW4sIGFuZCwgaWYKLSAgICogaXQgaGFzIG5vdCwgd3JpdGUgaXQuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCB3cml0ZVBhcmVudFRhZ0VuZCgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU2VlIGlmIHRoZSBwYXJlbnQgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIGZsYWdnZWQgYXMgaGF2aW5nIGNoaWxkcmVuLgotICAgIGlmICghbV9lbGVtU3RhY2sucGVla09yVHJ1ZSgpKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBtX3dyaXRlci53cml0ZSgnPicpOwotICAgICAgfQotICAgICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgICB9Ci0KLSAgICAgIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotCi0gICAgICBtX2VsZW1TdGFjay5zZXRUb3AodHJ1ZSk7Ci0gICAgICBtX3ByZXNlcnZlcy5wdXNoKG1faXNwcmVzZXJ2ZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZsYWcgdGhlIGN1cnJlbnQgZWxlbWVudCBhcyBub3QgeWV0IGhhdmluZyBhbnkKLSAgICogY2hpbGRyZW4uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBvcGVuRWxlbWVudEZvckNoaWxkcmVuKCkKLSAgewotCi0gICAgLy8gRmxhZyB0aGUgY3VycmVudCBlbGVtZW50IGFzIG5vdCB5ZXQgaGF2aW5nIGFueSBjaGlsZHJlbi4KLSAgICBtX2VsZW1TdGFjay5wdXNoKGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIGNoaWxkIG5vZGVzIGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgY3VycmVudAotICAgKiBlbGVtZW50LiAgTXVzdCBiZSBjYWxsZWQgaW4gYmFsYW5jZSB3aXRoIG9wZW5FbGVtZW50Rm9yQ2hpbGRyZW4oKS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIGNoaWxkIG5vZGVzIHdlcmUgYWRkZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBjaGlsZE5vZGVzV2VyZUFkZGVkKCkKLSAgewotICAgIHJldHVybiBtX2VsZW1TdGFjay5pc0VtcHR5KCkgPyBmYWxzZSA6IG1fZWxlbVN0YWNrLnBvcCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZQotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIG5hbWUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgIHJldHVybjsKLQotICAgIG1fY3VycmVudEluZGVudCAtPSBtX2luZGVudEFtb3VudDsKLQotICAgIGJvb2xlYW4gaGFzQ2hpbGROb2RlcyA9IGNoaWxkTm9kZXNXZXJlQWRkZWQoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFdyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgIGlmIChoYXNDaGlsZE5vZGVzKQotICAgICAgewotICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkpCi0gICAgICAgICAgaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0gIAotICAgICAgICB3cml0ZXIud3JpdGUoJzwnKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCcvJyk7Ci0gICAgICAgIHdyaXRlci53cml0ZShuYW1lKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChtX3NwYWNlQmVmb3JlQ2xvc2UpCi0gICAgICAgICAgd3JpdGVyLndyaXRlKCIgLz4iKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHdyaXRlci53cml0ZSgiLz4iKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0KLSAgICBpZiAoaGFzQ2hpbGROb2RlcykKLSAgICB7Ci0gICAgICBtX2lzcHJlc2VydmUgPSBtX3ByZXNlcnZlcy5pc0VtcHR5KCkgPyBmYWxzZSA6IG1fcHJlc2VydmVzLnBvcCgpOwotICAgIH0KLQotICAgIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotCi0gICAgLy8gbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmdTdGF0ZXMucG9wKCk7Ci0gICAgbV9jZGF0YVNlY3Rpb25TdGF0ZXMucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyBhbiBhdHRyaWJ1dGUuCi0gICAqIEBwYXJhbSAgIG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKiBAcGFyYW0gICB2YWx1ZSAgIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFdyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgIHdyaXRlci53cml0ZSgnICcpOwotICAgICAgd3JpdGVyLndyaXRlKG5hbWUpOwotICAgICAgd3JpdGVyLndyaXRlKCI9XCIiKTsKLSAgICAgIHdyaXRlQXR0clN0cmluZyh2YWx1ZSwgbV9lbmNvZGluZyk7Ci0gICAgICB3cml0ZXIud3JpdGUoJ1wiJyk7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0cyBhbiB1bi1lc2NhcGluZyBzZWN0aW9uLiBBbGwgY2hhcmFjdGVycyBwcmludGVkIHdpdGhpbiBhbgotICAgKiB1bi1lc2NhcGluZyBzZWN0aW9uIGFyZSBwcmludGVkIGFzIGlzLCB3aXRob3V0IGVzY2FwaW5nIHNwZWNpYWwKLSAgICogY2hhcmFjdGVycyBpbnRvIGVudGl0eSByZWZlcmVuY2VzLiBPbmx5IFhNTCBhbmQgSFRNTCBzZXJpYWxpemVycwotICAgKiBuZWVkIHRvIHN1cHBvcnQgdGhpcyBtZXRob2QuCi0gICAqIDxwPgotICAgKiBUaGUgY29udGVudHMgb2YgdGhlIHVuLWVzY2FwaW5nIHNlY3Rpb24gd2lsbCBiZSBkZWxpdmVyZWQgdGhyb3VnaAotICAgKiB0aGUgcmVndWxhciA8dHQ+Y2hhcmFjdGVyczwvdHQ+IGV2ZW50LgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnROb25Fc2NhcGluZygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nU3RhdGVzLnB1c2godHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogRW5kcyBhbiB1bi1lc2NhcGluZyBzZWN0aW9uLgotICAgKgotICAgKiBAc2VlICNzdGFydE5vbkVzY2FwaW5nCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmROb25Fc2NhcGluZygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nU3RhdGVzLnBvcCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0cyBhIHdoaXRlc3BhY2UgcHJlc2VydmluZyBzZWN0aW9uLiBBbGwgY2hhcmFjdGVycyBwcmludGVkCi0gICAqIHdpdGhpbiBhIHByZXNlcnZpbmcgc2VjdGlvbiBhcmUgcHJpbnRlZCB3aXRob3V0IGluZGVudGF0aW9uIGFuZAotICAgKiB3aXRob3V0IGNvbnNvbGlkYXRpbmcgbXVsdGlwbGUgc3BhY2VzLiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8KLSAgICogdGhlIDx0dD54bWw6c3BhY2U9JnF1b3Q7cHJlc2VydmUmcXVvdDs8L3R0PiBhdHRyaWJ1dGUuIE9ubHkgWE1MCi0gICAqIGFuZCBIVE1MIHNlcmlhbGl6ZXJzIG5lZWQgdG8gc3VwcG9ydCB0aGlzIG1ldGhvZC4KLSAgICogPHA+Ci0gICAqIFRoZSBjb250ZW50cyBvZiB0aGUgd2hpdGVzcGFjZSBwcmVzZXJ2aW5nIHNlY3Rpb24gd2lsbCBiZSBkZWxpdmVyZWQKLSAgICogdGhyb3VnaCB0aGUgcmVndWxhciA8dHQ+Y2hhcmFjdGVyczwvdHQ+IGV2ZW50LgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVzZXJ2aW5nKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBOb3Qgc3VyZSB0aGlzIGlzIHJlYWxseSB3aGF0IHdlIHdhbnQuICAtc2IKLSAgICBtX3ByZXNlcnZlcy5wdXNoKHRydWUpOwotCi0gICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBFbmRzIGEgd2hpdGVzcGFjZSBwcmVzZXJ2aW5nIHNlY3Rpb24uCi0gICAqCi0gICAqIEBzZWUgI3N0YXJ0UHJlc2VydmluZwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kUHJlc2VydmluZygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gTm90IHN1cmUgdGhpcyBpcyByZWFsbHkgd2hhdCB3ZSB3YW50LiAgLXNiCi0gICAgbV9pc3ByZXNlcnZlID0gbV9wcmVzZXJ2ZXMuaXNFbXB0eSgpID8gZmFsc2UgOiBtX3ByZXNlcnZlcy5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKG1faW5FbnRpdHlSZWYpCi0gICAgICByZXR1cm47Ci0KLSAgICBpZiAodGFyZ2V0LmVxdWFscyhSZXN1bHQuUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcpKQotICAgIHsKLSAgICAgIHN0YXJ0Tm9uRXNjYXBpbmcoKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAodGFyZ2V0LmVxdWFscyhSZXN1bHQuUElfRU5BQkxFX09VVFBVVF9FU0NBUElORykpCi0gICAgewotICAgICAgZW5kTm9uRXNjYXBpbmcoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBmaW5hbCBXcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICAgIHdyaXRlUGFyZW50VGFnRW5kKCk7Ci0gIAotICAgICAgICBpZiAoc2hvdWxkSW5kZW50KCkpCi0gICAgICAgICAgaW5kZW50KG1fY3VycmVudEluZGVudCk7Ci0gIAotICAgICAgICB3cml0ZXIud3JpdGUoJzwnKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCc/Jyk7Ci0gICAgICAgIHdyaXRlci53cml0ZSh0YXJnZXQpOwotICAKLSAgICAgICAgaWYgKGRhdGEubGVuZ3RoKCkgPiAwICYmIUNoYXJhY3Rlci5pc1NwYWNlQ2hhcihkYXRhLmNoYXJBdCgwKSkpCi0gICAgICAgICAgd3JpdGVyLndyaXRlKCcgJyk7Ci0gIAotICAgICAgICBpbnQgaW5kZXhPZlFMVCA9IGRhdGEuaW5kZXhPZigiPz4iKTsKLSAgCi0gICAgICAgIGlmIChpbmRleE9mUUxUID49IDApCi0gICAgICAgIHsKLSAgCi0gICAgICAgICAgLy8gU2VlIFhTTFQgc3BlYyBvbiBlcnJvciByZWNvdmVyeSBvZiAiPz4iIGluIFBJcy4KLSAgICAgICAgICBpZiAoaW5kZXhPZlFMVCA+IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGRhdGEuc3Vic3RyaW5nKDAsIGluZGV4T2ZRTFQpKTsKLSAgICAgICAgICB9Ci0gIAotICAgICAgICAgIHdyaXRlci53cml0ZSgiPyA+Iik7ICAvLyBhZGQgc3BhY2UgYmV0d2Vlbi4KLSAgCi0gICAgICAgICAgaWYgKChpbmRleE9mUUxUICsgMikgPCBkYXRhLmxlbmd0aCgpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZShkYXRhLnN1YnN0cmluZyhpbmRleE9mUUxUICsgMikpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICB3cml0ZXIud3JpdGUoZGF0YSk7Ci0gICAgICAgIH0KLSAgCi0gICAgICAgIHdyaXRlci53cml0ZSgnPycpOwotICAgICAgICB3cml0ZXIud3JpdGUoJz4nKTsKLSAgCi0gICAgICAgIC8vIEFsd2F5cyBvdXRwdXQgYSBuZXdsaW5lIGNoYXIgaWYgbm90IGluc2lkZSBvZiBhbiAKLSAgICAgICAgLy8gZWxlbWVudC4gVGhlIHdoaXRlc3BhY2UgaXMgbm90IHNpZ25pZmljYW50IGluIHRoYXQKLSAgICAgICAgLy8gY2FzZS4KLSAgICAgICAgaWYgKG1fZWxlbVN0YWNrLmlzRW1wdHkoKSkKLSAgICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAKLSAgICAgICAgbV9zdGFydE5ld0xpbmUgPSB0cnVlOwotICAgICAgfQotICAgICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIFRoaXMgY2FsbGJhY2sgd2lsbCBiZSB1c2VkIGZvciBjb21tZW50cyBpbnNpZGUgb3Igb3V0c2lkZSB0aGUKLSAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKLSAgICogc3Vic2V0IChpZiByZWFkKS4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tbWVudChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX2luRW50aXR5UmVmKQotICAgICAgcmV0dXJuOwotCi0gICAgd3JpdGVQYXJlbnRUYWdFbmQoKTsKLQotICAgIGlmIChzaG91bGRJbmRlbnQoKSkKLSAgICAgIGluZGVudChtX2N1cnJlbnRJbmRlbnQpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgd3JpdGVyLndyaXRlKCI8IS0tIik7Ci0gICAgICB3cml0ZXIud3JpdGUoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgICAgd3JpdGVyLndyaXRlKCItLT4iKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0KLSAgICBtX3N0YXJ0TmV3TGluZSA9IHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNlbmRDREFUQQotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIG1faW5DRGF0YSA9IHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjc3RhcnRDREFUQQotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX2luQ0RhdGEgPSBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjZGF0YS4KLSAgICoKLSAgICogPHA+VGhlIFBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsgb2YKLSAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgKiBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKLSAgICogY2h1bmtzOyBob3dldmVyLCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudAotICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICogcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgKiBvdXRzaWRlIG9mIHRoZSBzcGVjaWZpZWQgcmFuZ2UuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAqIGlnbm9yYWJsZVdoaXRlc3BhY2UoKSBtZXRob2QgcmF0aGVyIHRoYW4gdGhpcyBvbmUgKHZhbGlkYXRpbmcKLSAgICogcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNkYXRhKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgd3JpdGVQYXJlbnRUYWdFbmQoKTsKLQotICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLQotICAgICAgaWYgKHNob3VsZEluZGVudCgpKQotICAgICAgICBpbmRlbnQobV9jdXJyZW50SW5kZW50KTsKLQotICAgICAgYm9vbGVhbiB3cml0ZUNEYXRhQnJhY2tldHMgPSAoKChsZW5ndGggPj0gMSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoY2hbc3RhcnRdIDw9IG1fbWF4Q2hhcmFjdGVyKSkpOwotCi0gICAgICBpZiAod3JpdGVDRGF0YUJyYWNrZXRzKQotICAgICAgewotICAgICAgICBtX3dyaXRlci53cml0ZSgiPCFbQ0RBVEFbIik7Ci0gICAgICB9Ci0KLSAgICAgIC8vIG1fd3JpdGVyLndyaXRlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICAgIGlmIChpc0VzY2FwaW5nRGlzYWJsZWQoKSkKLSAgICAgIHsKLSAgICAgICAgY2hhcmFjdGVyc1JhdyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHdyaXRlTm9ybWFsaXplZENoYXJzKGNoLCBzdGFydCwgbGVuZ3RoLCB0cnVlKTsKLQotICAgICAgaWYgKHdyaXRlQ0RhdGFCcmFja2V0cykKLSAgICAgIHsKLSAgICAgICAgbV93cml0ZXIud3JpdGUoIl1dPiIpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX09JRVJST1IsIG51bGwpLAotICAgICAgICBpb2UpOyAgLy8iSU8gZXJyb3IiLCBpb2UpOwotICAgIH0KLSAgfQotCi0gIC8qKiBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9jaGFyQnVmIG9yIG1fYnl0ZUJ1Zi4gKi8KLSAgcHJvdGVjdGVkIGludCBtX3BvcyA9IDA7Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIGNoYXJhY3RlciB0byB0aGUgYnVmZmVyLgotICAgKgotICAgKiBAcGFyYW0gYiBieXRlIHRvIGJlIHdyaXR0ZW4gdG8gcmVzdWx0IHN0cmVhbS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFjY3VtKGNoYXIgYikgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBtX3dyaXRlci53cml0ZShiKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBBcHBlbmQgYSBjaGFyYWN0ZXIgdG8gdGhlIGJ1ZmZlci4KLSAgICoKLSAgICogQHBhcmFtIGNoYXJzIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBzdGFydCBTdGFydCBvZiBjaGFyYWN0ZXJzIHRvIGJlIHdyaXR0ZW4uCi0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgd3JpdHRlbi4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFjY3VtKGNoYXIgY2hhcnNbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgbV93cml0ZXIud3JpdGUoY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgfQotICAvKioKLSAgICogQXBwZW5kIGEgY2hhcmFjdGVyIHRvIHRoZSBidWZmZXIuCi0gICAqCi0gICAqIEBwYXJhbSBzIG5vbi1udWxsIHJlZmVyZW5jZSB0byBzdHJpbmcgdG8gYmUgd3JpdHRlbiB0byB0aGUgY2hhcmFjdGVyIGJ1ZmZlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCB2b2lkIGFjY3VtKFN0cmluZyBzKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIG1fd3JpdGVyLndyaXRlKHMpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihpb2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGbHVzaCB0aGUgZm9ybWF0dGVyJ3MgcmVzdWx0IHN0cmVhbS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGZsdXNoV3JpdGVyKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3dyaXRlcikKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fd3JpdGVyIGluc3RhbmNlb2YgV3JpdGVyVG9VVEY4QnVmZmVyZWQpCi0gICAgICAgIHsKLSAgICAgICAgICBpZihtX3Nob3VsZEZsdXNoKQotICAgICAgICAgICAgKChXcml0ZXJUb1VURjhCdWZmZXJlZCkgbV93cml0ZXIpLmZsdXNoKCk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgKChXcml0ZXJUb1VURjhCdWZmZXJlZCkgbV93cml0ZXIpLmZsdXNoQnVmZmVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG1fd3JpdGVyIGluc3RhbmNlb2YgV3JpdGVyVG9VVEY4KQotICAgICAgICB7Ci0gICAgICAgICAgaWYobV9zaG91bGRGbHVzaCkKLSAgICAgICAgICAgIG1fd3JpdGVyLmZsdXNoKCk7IAotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG1fd3JpdGVyIGluc3RhbmNlb2YgV3JpdGVyVG9BU0NJKQotICAgICAgICB7Ci0gICAgICAgICAgaWYobV9zaG91bGRGbHVzaCkKLSAgICAgICAgICAgIG1fd3JpdGVyLmZsdXNoKCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgLy8gRmx1c2ggYWx3YXlzLiAKLSAgICAgICAgICAvLyBOb3QgYSBncmVhdCB0aGluZyBpZiB0aGUgd3JpdGVyIHdhcyBjcmVhdGVkIAotICAgICAgICAgIC8vIGJ5IHRoaXMgY2xhc3MsIGJ1dCBkb24ndCBoYXZlIGEgY2hvaWNlLgotICAgICAgICAgIG1fd3JpdGVyLmZsdXNoKCk7IAotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuayBvZgotICAgKiBjaGFyYWN0ZXIgZGF0YS4gIFNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgY2hhcmFjdGVyCi0gICAqIGRhdGEgaW4gYSBzaW5nbGUgY2h1bmssIG9yIHRoZXkgbWF5IHNwbGl0IGl0IGludG8gc2V2ZXJhbAotICAgKiBjaHVua3M7IGhvd2V2ZXIsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiBhbnkgc2luZ2xlIGV2ZW50Ci0gICAqIG11c3QgY29tZSBmcm9tIHRoZSBzYW1lIGV4dGVybmFsIGVudGl0eSwgc28gdGhhdCB0aGUgTG9jYXRvcgotICAgKiBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24uPC9wPgotICAgKgotICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBub3QgYXR0ZW1wdCB0byByZWFkIGZyb20gdGhlIGFycmF5Ci0gICAqIG91dHNpZGUgb2YgdGhlIHNwZWNpZmllZCByYW5nZS48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBzb21lIHBhcnNlcnMgd2lsbCByZXBvcnQgd2hpdGVzcGFjZSB1c2luZyB0aGUKLSAgICogaWdub3JhYmxlV2hpdGVzcGFjZSgpIG1ldGhvZCByYXRoZXIgdGhhbiB0aGlzIG9uZSAodmFsaWRhdGluZwotICAgKiBwYXJzZXJzIG11c3QgZG8gc28pLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoYXJzIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyIGNoYXJzW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigwID09IGxlbmd0aCkKLSAgICAgIHJldHVybjsKLQotICAgIC8vICAgIGlmIChtX2luRW50aXR5UmVmKQotICAgIC8vICAgICAgcmV0dXJuOwotICAgIC8vICAgIGVsc2UgCi0gICAgaWYgKG1faW5DRGF0YSB8fCBtX2NkYXRhU2VjdGlvblN0YXRlcy5wZWVrT3JGYWxzZSgpKQotICAgIHsKLSAgICAgIGNkYXRhKGNoYXJzLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgcmV0dXJuOwotICAgIH0KLSAgICAKLSAgICB0cnkKLSAgICB7Ci0gICAgICAKLSAgICAgIGlmIChtX2Rpc2FibGVPdXRwdXRFc2NhcGluZ1N0YXRlcy5wZWVrT3JGYWxzZSgpKQotICAgICAgewotICAgICAgICBjaGFyYWN0ZXJzUmF3KGNoYXJzLCBzdGFydCwgbGVuZ3RoKTsKLSAgCi0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAKLSAgICAgIGZpbmFsIFdyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgIGlmICghbV9lbGVtU3RhY2sucGVla09yVHJ1ZSgpKQotICAgICAgewotICAgICAgICB3cml0ZXIud3JpdGUoJz4nKTsKLSAgCi0gICAgICAgIG1faXNwcmV2dGV4dCA9IGZhbHNlOwotICAKLSAgICAgICAgbV9lbGVtU3RhY2suc2V0VG9wKHRydWUpOwotICAgICAgICBtX3ByZXNlcnZlcy5wdXNoKG1faXNwcmVzZXJ2ZSk7Ci0gICAgICB9Ci0gIAotICAgICAgaW50IHN0YXJ0Q2xlYW4gPSBzdGFydDsKLSAgICAgIGludCBsZW5ndGhDbGVhbiA9IDA7Ci0gIAotICAgICAgLy8gaW50IHBvcyA9IDA7Ci0gICAgICBpbnQgZW5kID0gc3RhcnQgKyBsZW5ndGg7Ci0gICAgICBib29sZWFuIGNoZWNrV2hpdGUgPSB0cnVlOwotICAgICAgZmluYWwgaW50IG1heENoYXJhY3RlciA9IG1fbWF4Q2hhcmFjdGVyOwotICAgICAgZmluYWwgQml0U2V0IHNwZWNpYWxzTWFwID0gbV9jaGFySW5mby5tX3NwZWNpYWxzTWFwOwotICAKLSAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKQotICAgICAgewotICAgICAgICBjaGFyIGNoID0gY2hhcnNbaV07Ci0gIAotICAgICAgICBpZiAoY2hlY2tXaGl0ZQotICAgICAgICAgICAgICAgICYmICgoY2ggPiAweDIwKQotICAgICAgICAgICAgICAgICAgICB8fCEoKGNoID09IDB4MjApIHx8IChjaCA9PSAweDA5KSB8fCAoY2ggPT0gMHhEKQotICAgICAgICAgICAgICAgICAgICAgICAgfHwgKGNoID09IDB4QSkpKSkKLSAgICAgICAgewotICAgICAgICAgIG1faXNwcmVzZXJ2ZSA9IHRydWU7Ci0gICAgICAgICAgY2hlY2tXaGl0ZSA9IGZhbHNlOwotICAgICAgICB9Ci0gIAotICAgICAgICBpZiAoKChjaCA8IG1heENoYXJhY3RlcikgJiYgKCFzcGVjaWFsc01hcC5nZXQoY2gpKSkgfHwgKCciJyA9PSBjaCkpCi0gICAgICAgIHsKLSAgICAgICAgICBsZW5ndGhDbGVhbisrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGlmIChsZW5ndGhDbGVhbiA+IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGNoYXJzLCBzdGFydENsZWFuLCBsZW5ndGhDbGVhbik7Ci0gIAotICAgICAgICAgICAgbGVuZ3RoQ2xlYW4gPSAwOwotICAgICAgICAgIH0KLSAgCi0gICAgICAgICAgaWYgKENoYXJJbmZvLlNfTElORUZFRUQgPT0gY2gpCi0gICAgICAgICAgewotICAgICAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgCi0gICAgICAgICAgICBzdGFydENsZWFuID0gaSArIDE7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBzdGFydENsZWFuID0gYWNjdW1EZWZhdWx0RXNjYXBlKGNoLCBpLCBjaGFycywgZW5kLCBmYWxzZSk7Ci0gICAgICAgICAgICBpID0gc3RhcnRDbGVhbiAtIDE7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gIAotICAgICAgaWYgKGxlbmd0aENsZWFuID4gMCkKLSAgICAgIHsKLSAgICAgICAgd3JpdGVyLndyaXRlKGNoYXJzLCBzdGFydENsZWFuLCBsZW5ndGhDbGVhbik7Ci0gICAgICB9Ci0gICAgCi0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotCi0KLSAgICBtX2lzcHJldnRleHQgPSB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIGF2YWlsYWJsZSwgd2hlbiB0aGUgZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmcgYXR0cmlidXRlIGlzIHVzZWQsCi0gICAqIG91dHB1dCByYXcgdGV4dCB3aXRob3V0IGVzY2FwaW5nLgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnNSYXcoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAobV9pbkVudGl0eVJlZikKLSAgICAgICAgcmV0dXJuOwotICAKLSAgICAgIHdyaXRlUGFyZW50VGFnRW5kKCk7Ci0gIAotICAgICAgbV9pc3ByZXNlcnZlID0gdHJ1ZTsKLSAgCi0gICAgICBtX3dyaXRlci53cml0ZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgaXMgdGhlIGhpZ2ggbWVtYmVyIG9mIGEgc3Vycm9nYXRlIHBhaXIuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBjCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzVVRGMTZTdXJyb2dhdGUoY2hhciBjKQotICB7Ci0gICAgcmV0dXJuIChjICYgMHhGQzAwKSA9PSAweEQ4MDA7Ci0gIH0KLQotICAvKioKLSAgICogT25jZSBhIHN1cnJvZ2F0ZSBoYXMgYmVlbiBkZXRlY3RlZCwgZ2V0IHRoZSBwYWlyIGFzIGEgc2luZ2xlCi0gICAqIGludGVnZXIgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBjIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBzdXJyb2dhdGUuCi0gICAqIEBwYXJhbSBjaCBDaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBpIHBvc2l0aW9uIFdoZXJlIHRoZSBzdXJyb2dhdGUgd2FzIGRldGVjdGVkLgotICAgKiBAcGFyYW0gZW5kIFRoZSBlbmQgaW5kZXggb2YgdGhlIHNpZ25pZmljYW50IGNoYXJhY3RlcnMuCi0gICAqIEByZXR1cm4gaSsxLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBpZiBpbnZhbGlkIFVURi0xNiBzdXJyb2dhdGUgZGV0ZWN0ZWQuCi0gICAqLwotICBpbnQgZ2V0VVJGMTZTdXJyb2dhdGVWYWx1ZShjaGFyIGMsIGNoYXIgY2hbXSwgaW50IGksIGludCBlbmQpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgbmV4dDsKLQotICAgIGlmIChpICsgMSA+PSBlbmQpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBJbnRlZ2VyLnRvSGV4U3RyaW5nKChpbnQpIGMpIH0pKTsgIC8vIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogIgotCi0gICAgICAvLytJbnRlZ2VyLnRvSGV4U3RyaW5nKChpbnQpYykrICIgPyIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbmV4dCA9IGNoWysraV07Ci0KLSAgICAgIGlmICghKDB4ZGMwMCA8PSBuZXh0ICYmIG5leHQgPCAweGUwMDApKQotICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKAotICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117Ci0gICAgICAgICAgICAgIEludGVnZXIudG9IZXhTdHJpbmcoKGludCkgYykgKyAiICIKLSAgICAgICAgICAgICAgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKG5leHQpIH0pKTsgIC8vIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogIgotCi0gICAgICAvLytJbnRlZ2VyLnRvSGV4U3RyaW5nKChpbnQpYykrIiAiK0ludGVnZXIudG9IZXhTdHJpbmcobmV4dCkpOwotICAgICAgbmV4dCA9ICgoYyAtIDB4ZDgwMCkgPDwgMTApICsgbmV4dCAtIDB4ZGMwMCArIDB4MDAwMTAwMDA7Ci0gICAgfQotCi0gICAgcmV0dXJuIG5leHQ7Ci0gIH0KLQotICAvKioKLSAgICogT25jZSBhIHN1cnJvZ2F0ZSBoYXMgYmVlbiBkZXRlY3RlZCwgd3JpdGUgdGhlIHBhaXIgYXMgYSBzaW5nbGUKLSAgICogY2hhcmFjdGVyIHJlZmVyZW5jZS4KLSAgICoKLSAgICogQHBhcmFtIGMgdGhlIGZpcnN0IHBhcnQgb2YgdGhlIHN1cnJvZ2F0ZS4KLSAgICogQHBhcmFtIGNoIENoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGkgcG9zaXRpb24gV2hlcmUgdGhlIHN1cnJvZ2F0ZSB3YXMgZGV0ZWN0ZWQuCi0gICAqIEBwYXJhbSBlbmQgVGhlIGVuZCBpbmRleCBvZiB0aGUgc2lnbmlmaWNhbnQgY2hhcmFjdGVycy4KLSAgICogQHJldHVybiBpKzEuCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgaW52YWxpZCBVVEYtMTYgc3Vycm9nYXRlIGRldGVjdGVkLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCB3cml0ZVVURjE2U3Vycm9nYXRlKGNoYXIgYywgY2hhciBjaFtdLCBpbnQgaSwgaW50IGVuZCkKLSAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBVVEYtMTYgc3Vycm9nYXRlCi0gICAgaW50IHN1cnJvZ2F0ZVZhbHVlID0gZ2V0VVJGMTZTdXJyb2dhdGVWYWx1ZShjLCBjaCwgaSwgZW5kKTsKLQotICAgIGkrKzsKLQotICAgIG1fd3JpdGVyLndyaXRlKCcmJyk7Ci0gICAgbV93cml0ZXIud3JpdGUoJyMnKTsKLQotICAgIC8vIG1fd3JpdGVyLndyaXRlKCd4Jyk7Ci0gICAgbV93cml0ZXIud3JpdGUoSW50ZWdlci50b1N0cmluZyhzdXJyb2dhdGVWYWx1ZSkpOwotICAgIG1fd3JpdGVyLndyaXRlKCc7Jyk7Ci0KLSAgICByZXR1cm4gaTsKLSAgfQotCi0gIC8qKgotICAgKiBOb3JtYWxpemUgdGhlIGNoYXJhY3RlcnMsIGJ1dCBkb24ndCBlc2NhcGUuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gaXNDRGF0YSB0cnVlIGlmIGEgQ0RBVEEgYmxvY2sgc2hvdWxkIGJlIGJ1aWx0IGFyb3VuZCB0aGUgY2hhcmFjdGVycy4KLSAgICoKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgdm9pZCB3cml0ZU5vcm1hbGl6ZWRDaGFycyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCwgYm9vbGVhbiBpc0NEYXRhKQotICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBlbmQgPSBzdGFydCArIGxlbmd0aDsKLQotICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKQotICAgIHsKLSAgICAgIGNoYXIgYyA9IGNoW2ldOwotCi0gICAgICBpZiAoQ2hhckluZm8uU19MSU5FRkVFRCA9PSBjKQotICAgICAgewotICAgICAgICBtX3dyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChpc0NEYXRhICYmIChjID4gbV9tYXhDaGFyYWN0ZXIpKQotICAgICAgewotICAgICAgICBpZiAoaSAhPSAwKQotICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCJdXT4iKTsKLQotICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGdvIGludG8gYSBmdW5jdGlvbi4uLiAKLSAgICAgICAgaWYgKGlzVVRGMTZTdXJyb2dhdGUoYykpCi0gICAgICAgIHsKLSAgICAgICAgICBpID0gd3JpdGVVVEYxNlN1cnJvZ2F0ZShjLCBjaCwgaSwgZW5kKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBtX3dyaXRlci53cml0ZSgiJiMiKTsKLQotICAgICAgICAgIFN0cmluZyBpbnRTdHIgPSBJbnRlZ2VyLnRvU3RyaW5nKChpbnQpIGMpOwotCi0gICAgICAgICAgbV93cml0ZXIud3JpdGUoaW50U3RyKTsKLSAgICAgICAgICBtX3dyaXRlci53cml0ZSgnOycpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKChpICE9IDApICYmIChpIDwgKGVuZCAtIDEpKSkKLSAgICAgICAgICBtX3dyaXRlci53cml0ZSgiPCFbQ0RBVEFbIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChpc0NEYXRhCi0gICAgICAgICAgICAgICAmJiAoKGkgPCAoZW5kIC0gMikpICYmICgnXScgPT0gYykgJiYgKCddJyA9PSBjaFtpICsgMV0pCi0gICAgICAgICAgICAgICAgICAgJiYgKCc+JyA9PSBjaFtpICsgMl0pKSkKLSAgICAgIHsKLSAgICAgICAgbV93cml0ZXIud3JpdGUoIl1dXV0+PCFbQ0RBVEFbPiIpOwotCi0gICAgICAgIGkgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaWYgKGMgPD0gbV9tYXhDaGFyYWN0ZXIpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3dyaXRlci53cml0ZShjKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gZ28gaW50byBhIGZ1bmN0aW9uLi4uIAotICAgICAgICBlbHNlIGlmIChpc1VURjE2U3Vycm9nYXRlKGMpKQotICAgICAgICB7Ci0gICAgICAgICAgaSA9IHdyaXRlVVRGMTZTdXJyb2dhdGUoYywgY2gsIGksIGVuZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV93cml0ZXIud3JpdGUoIiYjIik7Ci0KLSAgICAgICAgICBTdHJpbmcgaW50U3RyID0gSW50ZWdlci50b1N0cmluZygoaW50KSBjKTsKLQotICAgICAgICAgIG1fd3JpdGVyLndyaXRlKGludFN0cik7Ci0gICAgICAgICAgbV93cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqIE5vdCBzdXJlIGhvdyB0byBnZXQgdGhpcyBpbnZva2VkIHF1aXRlIHlldC4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlICNjaGFyYWN0ZXJzCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKDAgPT0gbGVuZ3RoKQotICAgICAgcmV0dXJuOwotCi0gICAgY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBza2lwcGVkIGVudGl0eS4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNza2lwcGVkRW50aXR5Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBza2lwcGVkIGVudGl0eS4gIElmIGl0IGlzIGEKLSAgICogICAgICAgIHBhcmFtZXRlciBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScsIGFuZCBpZgotICAgKiAgICAgICAgaXQgaXMgdGhlIGV4dGVybmFsIERURCBzdWJzZXQsIGl0IHdpbGwgYmUgdGhlIHN0cmluZwotICAgKiAgICAgICAgIltkdGRdIi4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFRPRE86IFNob3VsZCBoYW5kbGUKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGJlZ2lubmluZyBvZiBhbiBlbnRpdHkuCi0gICAqCi0gICAqIFRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkgYXJlIG5vdCByZXBvcnRlZC4KLSAgICogVGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGV4dGVybmFsIERURCBzdWJzZXQgYXJlIHJlcG9ydGVkCi0gICAqIHVzaW5nIHRoZSBwc2V1ZG8tbmFtZSAiW2R0ZF0iLiAgQWxsIG90aGVyIGV2ZW50cyBtdXN0IGJlCi0gICAqIHByb3Blcmx5IG5lc3RlZCB3aXRoaW4gc3RhcnQvZW5kIGVudGl0eSBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kRW50aXR5Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2ludGVybmFsRW50aXR5RGVjbAotICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNleHRlcm5hbEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX2luRW50aXR5UmVmID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgdGhhdCBpcyBlbmRpbmcuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNzdGFydEVudGl0eQotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX2luRW50aXR5UmVmID0gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpdmljYXRpb24gb2YgYSBlbnRpdHlSZWZlcmVuY2UuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbnRpdHlSZWZlcmVuY2UoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgd3JpdGVQYXJlbnRUYWdFbmQoKTsKLQotICAgIGlmIChzaG91bGRJbmRlbnQoKSkKLSAgICAgIGluZGVudChtX2N1cnJlbnRJbmRlbnQpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgd3JpdGVyLndyaXRlKCImIik7Ci0gICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICB3cml0ZXIud3JpdGUoIjsiKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0KLSAgfQotCi0gIC8vIEltcGxlbWVudCBEZWNsSGFuZGxlcgotCi0gIC8qKgotICAgKiAgIFJlcG9ydCBhbiBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAqICAKLSAgICogICA8cD5UaGUgY29udGVudCBtb2RlbCB3aWxsIGNvbnNpc3Qgb2YgdGhlIHN0cmluZyAiRU1QVFkiLCB0aGUKLSAgICogICBzdHJpbmcgIkFOWSIsIG9yIGEgcGFyZW50aGVzaXNlZCBncm91cCwgb3B0aW9uYWxseSBmb2xsb3dlZAotICAgKiAgIGJ5IGFuIG9jY3VycmVuY2UgaW5kaWNhdG9yLiAgVGhlIG1vZGVsIHdpbGwgYmUgbm9ybWFsaXplZCBzbwotICAgKiAgIHRoYXQgYWxsIHdoaXRlc3BhY2UgaXMgcmVtb3ZlZCxhbmQgd2lsbCBpbmNsdWRlIHRoZSBlbmNsb3NpbmcKLSAgICogICBwYXJlbnRoZXNlcy48L3A+Ci0gICAqICAKLSAgICogICBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqICAgQHBhcmFtIG1vZGVsIFRoZSBjb250ZW50IG1vZGVsIGFzIGEgbm9ybWFsaXplZCBzdHJpbmcuCi0gICAqICAgQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIG1vZGVsKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBmaW5hbCBXcml0ZXIgd3JpdGVyID0gbV93cml0ZXI7Ci0gICAgICBpZiAobV9pbkRvY3R5cGUpCi0gICAgICB7Ci0gICAgICAgIHdyaXRlci53cml0ZSgiIFsiKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgCi0gICAgICAgIG1faW5Eb2N0eXBlID0gZmFsc2U7Ci0gICAgICB9Ci0gIAotICAgICAgd3JpdGVyLndyaXRlKCI8IUVMRU1FTlQgIik7Ci0gICAgICB3cml0ZXIud3JpdGUobmFtZSk7Ci0gICAgICB3cml0ZXIud3JpdGUoJyAnKTsKLSAgICAgIHdyaXRlci53cml0ZShtb2RlbCk7Ci0gICAgICB3cml0ZXIud3JpdGUoJz4nKTsKLSAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIE5FRURTRE9DIEZpZWxkIG1fZWxlbU5hbWUgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9lbGVtTmFtZSA9ICIiOwotCi0gIC8qKgotICAgKiBSZXBvcnQgYW4gYXR0cmlidXRlIHR5cGUgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPk9ubHkgdGhlIGVmZmVjdGl2ZSAoZmlyc3QpIGRlY2xhcmF0aW9uIGZvciBhbiBhdHRyaWJ1dGUgd2lsbAotICAgKiBiZSByZXBvcnRlZC4gIFRoZSB0eXBlIHdpbGwgYmUgb25lIG9mIHRoZSBzdHJpbmdzICJDREFUQSIsCi0gICAqICJJRCIsICJJRFJFRiIsICJJRFJFRlMiLCAiTk1UT0tFTiIsICJOTVRPS0VOUyIsICJFTlRJVFkiLAotICAgKiAiRU5USVRJRVMiLCBvciAiTk9UQVRJT04iLCBvciBhIHBhcmVudGhlc2l6ZWQgdG9rZW4gZ3JvdXAgd2l0aAotICAgKiB0aGUgc2VwYXJhdG9yICJ8IiBhbmQgYWxsIHdoaXRlc3BhY2UgcmVtb3ZlZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBlbGVtZW50LgotICAgKiBAcGFyYW0gYU5hbWUgVGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KLSAgICogQHBhcmFtIHR5cGUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgdHlwZS4KLSAgICogQHBhcmFtIHZhbHVlRGVmYXVsdCBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSBkZWZhdWx0Ci0gICAqICAgICAgICAoIiNJTVBMSUVEIiwgIiNSRVFVSVJFRCIsIG9yICIjRklYRUQiKSBvciBudWxsIGlmCi0gICAqICAgICAgICBub25lIG9mIHRoZXNlIGFwcGxpZXMuCi0gICAqIEBwYXJhbSB2YWx1ZSBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSdzIGRlZmF1bHQgdmFsdWUsCi0gICAqICAgICAgICBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbCgKLSAgICAgICAgICBTdHJpbmcgZU5hbWUsIFN0cmluZyBhTmFtZSwgU3RyaW5nIHR5cGUsIFN0cmluZyB2YWx1ZURlZmF1bHQsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAgICAgaWYgKG1faW5Eb2N0eXBlKQotICAgICAgewotICAgICAgICB3cml0ZXIud3JpdGUoIiBbIik7Ci0gICAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gIAotICAgICAgICBtX2luRG9jdHlwZSA9IGZhbHNlOwotICAgICAgfQotICAKLSAgICAgIGlmICghZU5hbWUuZXF1YWxzKG1fZWxlbU5hbWUpKQotICAgICAgewotICAgICAgICB3cml0ZXIud3JpdGUoIjwhQVRUTElTVCAiKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKGVOYW1lKTsKLSAgICAgICAgd3JpdGVyLndyaXRlKCIgIik7Ci0gIAotICAgICAgICBtX2VsZW1OYW1lID0gZU5hbWU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fcG9zIC09IDM7Ci0gIAotICAgICAgICB3cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAgICAgfQotICAKLSAgICAgIHdyaXRlci53cml0ZShhTmFtZSk7Ci0gICAgICB3cml0ZXIud3JpdGUoIiAiKTsKLSAgICAgIHdyaXRlci53cml0ZSh0eXBlKTsKLSAgICAgIHdyaXRlci53cml0ZSgiICIpOwotICAgICAgd3JpdGVyLndyaXRlKHZhbHVlRGVmYXVsdCk7Ci0gIAotICAgICAgLy9tX3dyaXRlci53cml0ZSgiICIpOwotICAgICAgLy9tX3dyaXRlci53cml0ZSh2YWx1ZSk7Ci0gICAgICB3cml0ZXIud3JpdGUoIj4iKTsKLSAgICAgIHdyaXRlci53cml0ZShtX2xpbmVTZXAsIDAsIG1fbGluZVNlcExlbik7Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPk9ubHkgdGhlIGVmZmVjdGl2ZSAoZmlyc3QpIGRlY2xhcmF0aW9uIGZvciBlYWNoIGVudGl0eQotICAgKiB3aWxsIGJlIHJlcG9ydGVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwbGFjZW1lbnQgdGV4dCBvZiB0aGUgZW50aXR5LgotICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG1faW5Eb2N0eXBlKQotICAgICAgewotICAgICAgICBtX3dyaXRlci53cml0ZSgiIFsiKTsKLSAgICAgICAgbV93cml0ZXIud3JpdGUobV9saW5lU2VwLCAwLCBtX2xpbmVTZXBMZW4pOwotICAKLSAgICAgICAgbV9pbkRvY3R5cGUgPSBmYWxzZTsKLSAgICAgIH0KLSAgCi0gICAgICBvdXRwdXRFbnRpdHlEZWNsKG5hbWUsIHZhbHVlKTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGEgcGFyc2VkIGV4dGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGVhY2ggZW50aXR5Ci0gICAqIHdpbGwgYmUgcmVwb3J0ZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBkZWNsYXJlZCBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LCBvcgotICAgKiAgICAgICAgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBkZWNsYXJlZCBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZW50aXR5LgotICAgKiBAZXhjZXB0aW9uIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjaW50ZXJuYWxFbnRpdHlEZWNsCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbCgKLSAgICAgICAgICBTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb257fQotCi0gIC8qKgotICAgKiBIYW5kbGUgb25lIG9mIHRoZSBkZWZhdWx0IGVudGl0aWVzLCByZXR1cm4gZmFsc2UgaWYgaXQKLSAgICogaXMgbm90IGEgZGVmYXVsdCBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBjaGFyYWN0ZXIgdG8gYmUgZXNjYXBlZC4KLSAgICogQHBhcmFtIGkgaW5kZXggaW50byBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBjaGFycyBub24tbnVsbCByZWZlcmVuY2UgdG8gY2hhcmFjdGVyIGFycmF5LgotICAgKiBAcGFyYW0gbGVuIGxlbmd0aCBvZiBjaGFycy4KLSAgICogQHBhcmFtIGVzY0xGIHRydWUgaWYgdGhlIGxpbmVmZWVkIHNob3VsZCBiZSBlc2NhcGVkLgotICAgKgotICAgKiBAcmV0dXJuIGkrMSBpZiB0aGUgY2hhcmFjdGVyIHdhcyB3cml0dGVuLCBlbHNlIGkuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGFjY3VtRGVmYXVsdEVudGl0eSgKLSAgICAgICAgICBjaGFyIGNoLCBpbnQgaSwgY2hhcltdIGNoYXJzLCBpbnQgbGVuLCBib29sZWFuIGVzY0xGKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAoIWVzY0xGICYmIENoYXJJbmZvLlNfTElORUZFRUQgPT0gY2gpCi0gICAgICB7Ci0gICAgICAgIG1fd3JpdGVyLndyaXRlKG1fbGluZVNlcCwgMCwgbV9saW5lU2VwTGVuKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fY2hhckluZm8uaXNTcGVjaWFsKGNoKSkKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBlbnRpdHlSZWYgPSBtX2NoYXJJbmZvLmdldEVudGl0eU5hbWVGb3JDaGFyKGNoKTsKLSAgCi0gICAgICAgICAgaWYgKG51bGwgIT0gZW50aXR5UmVmKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGZpbmFsIFdyaXRlciB3cml0ZXIgPSBtX3dyaXRlcjsKLSAgICAgICAgICAgIHdyaXRlci53cml0ZSgnJicpOwotICAgICAgICAgICAgd3JpdGVyLndyaXRlKGVudGl0eVJlZik7Ci0gICAgICAgICAgICB3cml0ZXIud3JpdGUoJzsnKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIGk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIHJldHVybiBpOwotICAgICAgfQotICAKLSAgICAgIHJldHVybiBpICsgMTsKLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRXNjYXBlIGFuZCBtX3dyaXRlci53cml0ZSBhIGNoYXJhY3Rlci4KLSAgICoKLSAgICogQHBhcmFtIGNoIGNoYXJhY3RlciB0byBiZSBlc2NhcGVkLgotICAgKiBAcGFyYW0gaSBpbmRleCBpbnRvIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGNoYXJzIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW4gbGVuZ3RoIG9mIGNoYXJzLgotICAgKiBAcGFyYW0gZXNjTEYgdHJ1ZSBpZiB0aGUgbGluZWZlZWQgc2hvdWxkIGJlIGVzY2FwZWQuCi0gICAqCi0gICAqIEByZXR1cm4gaSsxIGlmIHRoZSBjaGFyYWN0ZXIgd2FzIHdyaXR0ZW4sIGVsc2UgaS4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgYWNjdW1EZWZhdWx0RXNjYXBlKAotICAgICAgICAgIGNoYXIgY2gsIGludCBpLCBjaGFyW10gY2hhcnMsIGludCBsZW4sIGJvb2xlYW4gZXNjTEYpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBwb3MgPSBhY2N1bURlZmF1bHRFbnRpdHkoY2gsIGksIGNoYXJzLCBsZW4sIGVzY0xGKTsKLQotICAgIGlmIChpID09IHBvcykKLSAgICB7Ci0gICAgICBwb3MrKzsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGlmICgweGQ4MDAgPD0gY2ggJiYgY2ggPCAweGRjMDApCi0gICAgICAgIHsKLSAgCi0gICAgICAgICAgLy8gVVRGLTE2IHN1cnJvZ2F0ZQotICAgICAgICAgIGludCBuZXh0OwotICAKLSAgICAgICAgICBpZiAoaSArIDEgPj0gbGVuKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgSW50ZWdlci50b0hleFN0cmluZyhjaCkgfSkpOyAgLy8iSW52YWxpZCBVVEYtMTYgc3Vycm9nYXRlIGRldGVjdGVkOiAiCi0gIAotICAgICAgICAgICAgLy8rSW50ZWdlci50b0hleFN0cmluZyhjaCkrICIgPyIpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgbmV4dCA9IGNoYXJzWysraV07Ci0gIAotICAgICAgICAgICAgaWYgKCEoMHhkYzAwIDw9IG5leHQgJiYgbmV4dCA8IDB4ZTAwMCkpCi0gICAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX1VURjE2X1NVUlJPR0FURSwKLSAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsKLSAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b0hleFN0cmluZyhjaCkgKyAiICIKLSAgICAgICAgICAgICAgICAgICAgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKG5leHQpIH0pKTsgIC8vIkludmFsaWQgVVRGLTE2IHN1cnJvZ2F0ZSBkZXRlY3RlZDogIgotICAKLSAgICAgICAgICAgIC8vK0ludGVnZXIudG9IZXhTdHJpbmcoY2gpKyIgIitJbnRlZ2VyLnRvSGV4U3RyaW5nKG5leHQpKTsKLSAgICAgICAgICAgIG5leHQgPSAoKGNoIC0gMHhkODAwKSA8PCAxMCkgKyBuZXh0IC0gMHhkYzAwICsgMHgwMDAxMDAwMDsKLSAgICAgICAgICB9Ci0gIAotICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCImIyIpOwotICAgICAgICAgIG1fd3JpdGVyLndyaXRlKEludGVnZXIudG9TdHJpbmcobmV4dCkpOwotICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCI7Iik7Ci0gIAotICAgICAgICAgIC8qfSBlbHNlIGlmIChudWxsICE9IGN0YmMgJiYgIWN0YmMuY2FuQ29udmVydChjaCkpIHsKLSAgICAgICAgICBzYi5hcHBlbmQoIiYjeCIpOwotICAgICAgICAgIHNiLmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKChpbnQpY2gsIDE2KSk7Ci0gICAgICAgICAgc2IuYXBwZW5kKCI7Iik7Ki8KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoY2ggPiBtX21heENoYXJhY3RlciB8fCAobV9jaGFySW5mby5pc1NwZWNpYWwoY2gpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZSgiJiMiKTsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKEludGVnZXIudG9TdHJpbmcoY2gpKTsKLSAgICAgICAgICAgIG1fd3JpdGVyLndyaXRlKCI7Iik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX3dyaXRlci53cml0ZShjaCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcG9zOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHNwZWNpZmllZCA8dmFyPnN0cmluZzwvdmFyPiBhZnRlciBzdWJzdGl0dXRpbmcgPFZBUj5zcGVjaWFsczwvVkFSPiwKLSAgICogYW5kIFVURi0xNiBzdXJyb2dhdGVzIGZvciBjaHJhY3RlciByZWZlcmVuY2VzIDxDT0RFPiZhbXA7I3hubjwvQ09ERT4uCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0cmluZyAgICAgIFN0cmluZyB0byBjb252ZXJ0IHRvIFhNTCBmb3JtYXQuCi0gICAqIEBwYXJhbSAgIGVuY29kaW5nICAgIENVUlJFTlRMWSBOT1QgSU1QTEVNRU5URUQuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZUF0dHJTdHJpbmcoU3RyaW5nIHN0cmluZywgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgY2hhcltdIHN0cmluZ0NoYXJzID0gc3RyaW5nLnRvQ2hhckFycmF5KCk7Ci0gICAgICBmaW5hbCBpbnQgbGVuID0gc3RyaW5nQ2hhcnMubGVuZ3RoOwotICAgICAgZmluYWwgV3JpdGVyIHdyaXRlciA9IG1fd3JpdGVyOwotICAKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGNoYXIgY2ggPSBzdHJpbmdDaGFyc1tpXTsKLSAgCi0gICAgICAgIGlmICgoY2ggPCBtX21heENoYXJhY3RlcikgJiYgKCFtX2NoYXJJbmZvLmlzU3BlY2lhbChjaCkpKQotICAgICAgICB7Ci0gICAgICAgICAgd3JpdGVyLndyaXRlKGNoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgCi0gICAgICAgICAgLy8gSSBndWVzcyB0aGUgcGFyc2VyIGRvZXNuJ3Qgbm9ybWFsaXplIGNyL2xmIGluIGF0dHJpYnV0ZXMuIC1zYgotICAgICAgICAgIGlmICgoQ2hhckluZm8uU19DQVJSSUFHRVJFVFVSTiA9PSBjaCkgJiYgKChpICsgMSkgPCBsZW4pCi0gICAgICAgICAgICAgICAgICAmJiAoQ2hhckluZm8uU19MSU5FRkVFRCA9PSBzdHJpbmdDaGFyc1tpICsgMV0pKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGkrKzsKLSAgCi0gICAgICAgICAgICBjaCA9IENoYXJJbmZvLlNfTElORUZFRUQ7Ci0gICAgICAgICAgfQotICAKLSAgICAgICAgICBhY2N1bURlZmF1bHRFc2NhcGUoY2gsIGksIHN0cmluZ0NoYXJzLCBsZW4sIHRydWUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYsIGJhc2VkIG9uIHNwYWNlIHByZXNlcnZhdGlvbiBjb25zdHJhaW50cyBhbmQgdGhlIGRvSW5kZW50IHByb3BlcnR5LAotICAgKiBpZiBhbiBpbmRlbnQgc2hvdWxkIG9jY3VyLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgYW4gaW5kZW50IHNob3VsZCBvY2N1ci4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIHNob3VsZEluZGVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9kb0luZGVudCAmJiAoIW1faXNwcmVzZXJ2ZSAmJiFtX2lzcHJldnRleHQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50cyA8dmFyPm48L3Zhcj4gc3BhY2VzLgotICAgKiBAcGFyYW0gcHcgICAgICAgIFRoZSBjaGFyYWN0ZXIgb3V0cHV0IHN0cmVhbSB0byB1c2UuCi0gICAqIEBwYXJhbSBuICAgICAgICAgTnVtYmVyIG9mIHNwYWNlcyB0byBwcmludC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoZW4gd3JpdGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByaW50U3BhY2UoaW50IG4pIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIG1fd3JpdGVyLndyaXRlKCcgJyk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50cyBhIG5ld2xpbmUgY2hhcmFjdGVyIGFuZCA8dmFyPm48L3Zhcj4gc3BhY2VzLgotICAgKiBAcGFyYW0gcHcgICAgICAgIFRoZSBjaGFyYWN0ZXIgb3V0cHV0IHN0cmVhbSB0byB1c2UuCi0gICAqIEBwYXJhbSBuICAgICAgICAgTnVtYmVyIG9mIHNwYWNlcyB0byBwcmludC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB3cml0aW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5kZW50KGludCBuKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX3N0YXJ0TmV3TGluZSkKLSAgICAgIG91dHB1dExpbmVTZXAoKTsKLQotICAgIGlmIChtX2RvSW5kZW50KQotICAgIHsKLSAgICAgIHByaW50U3BhY2Uobik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmllcyBhbiBvdXRwdXQgc3RyZWFtIHRvIHdoaWNoIHRoZSBkb2N1bWVudCBzaG91bGQgYmUKLSAgICogc2VyaWFsaXplZC4gVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hpbGUgdGhlCi0gICAqIHNlcmlhbGl6ZXIgaXMgaW4gdGhlIHByb2Nlc3Mgb2Ygc2VyaWFsaXppbmcgYSBkb2N1bWVudC4KLSAgICogPHA+Ci0gICAqIFRoZSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGlzIHVzZWQsIG9yCi0gICAqIGlmIG5vIGVuY29kaW5nIHdhcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGZvciB0aGUgc2VsZWN0ZWQKLSAgICogb3V0cHV0IG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIG91dHB1dCBUaGUgb3V0cHV0IHN0cmVhbQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGluaXQob3V0cHV0LCBtX2Zvcm1hdCk7Ci0gICAgfQotICAgIGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVlZSkKLSAgICB7Ci0KLSAgICAgIC8vIFNob3VsZCBoYXZlIGJlZW4gd2FybmVkIGluIGluaXQsIEkgZ3Vlc3MuLi4KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvdXRwdXQgc3RyZWFtIHdoZXJlIHRoZSBldmVudHMgd2lsbCBiZSBzZXJpYWxpemVkIHRvLgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB0aGUgcmVzdWx0IHN0cmVhbSwgb3IgbnVsbCBvZiBvbmx5IGEgd3JpdGVyIHdhcwotICAgKiBzZXQuCi0gICAqLwotICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpCi0gIHsKLQotICAgIGlmIChtX3dyaXRlciBpbnN0YW5jZW9mIFdyaXRlclRvVVRGOEJ1ZmZlcmVkKQotICAgICAgcmV0dXJuICgoV3JpdGVyVG9VVEY4QnVmZmVyZWQpIG1fd3JpdGVyKS5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICBpZiAobV93cml0ZXIgaW5zdGFuY2VvZiBXcml0ZXJUb1VURjgpCi0gICAgICByZXR1cm4gKChXcml0ZXJUb1VURjgpIG1fd3JpdGVyKS5nZXRPdXRwdXRTdHJlYW0oKTsKLSAgICBlbHNlIGlmIChtX3dyaXRlciBpbnN0YW5jZW9mIFdyaXRlclRvQVNDSSkKLSAgICAgIHJldHVybiAoKFdyaXRlclRvQVNDSSkgbV93cml0ZXIpLmdldE91dHB1dFN0cmVhbSgpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNwZWNpZmllcyBhIHdyaXRlciB0byB3aGljaCB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuCi0gICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIHdoaWxlIHRoZSBzZXJpYWxpemVyIGlzIGluCi0gICAqIHRoZSBwcm9jZXNzIG9mIHNlcmlhbGl6aW5nIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSB3cml0ZXIgVGhlIG91dHB1dCB3cml0ZXIgc3RyZWFtCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRXcml0ZXIoV3JpdGVyIHdyaXRlcikKLSAgewotICAgIG1fd3JpdGVyID0gd3JpdGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY2hhcmFjdGVyIHN0cmVhbSB3aGVyZSB0aGUgZXZlbnRzIHdpbGwgYmUgc2VyaWFsaXplZCB0by4KLSAgICoKLSAgICogQHJldHVybiBSZWZlcmVuY2UgdG8gdGhlIHJlc3VsdCBXcml0ZXIsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgV3JpdGVyIGdldFdyaXRlcigpCi0gIHsKLSAgICByZXR1cm4gbV93cml0ZXI7Ci0gIH0KLQotICAvKioKLSAgICogU3BlY2lmaWVzIGFuIG91dHB1dCBmb3JtYXQgZm9yIHRoaXMgc2VyaWFsaXplci4gSXQgdGhlCi0gICAqIHNlcmlhbGl6ZXIgaGFzIGFscmVhZHkgYmVlbiBhc3NvY2lhdGVkIHdpdGggYW4gb3V0cHV0IGZvcm1hdCwKLSAgICogaXQgd2lsbCBzd2l0Y2ggdG8gdGhlIG5ldyBmb3JtYXQuIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUKLSAgICogY2FsbGVkIHdoaWxlIHRoZSBzZXJpYWxpemVyIGlzIGluIHRoZSBwcm9jZXNzIG9mIHNlcmlhbGl6aW5nCi0gICAqIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBmb3JtYXQgVGhlIG91dHB1dCBmb3JtYXQgdG8gdXNlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRGb3JtYXQoUHJvcGVydGllcyBmb3JtYXQpCi0gIHsKLQotICAgIGJvb2xlYW4gc2hvdWxkRmx1c2ggPSBtX3Nob3VsZEZsdXNoOwotCi0gICAgaW5pdChtX3dyaXRlciwgZm9ybWF0LCBmYWxzZSk7Ci0KLSAgICBtX3Nob3VsZEZsdXNoID0gc2hvdWxkRmx1c2g7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgb3V0cHV0IGZvcm1hdCBmb3IgdGhpcyBzZXJpYWxpemVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvdXRwdXQgZm9ybWF0IGluIHVzZQotICAgKi8KLSAgcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0Rm9ybWF0KCkKLSAgewotICAgIHJldHVybiBtX2Zvcm1hdDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSB7QGxpbmsgQ29udGVudEhhbmRsZXJ9IGludGVyZmFjZSBpbnRvIHRoaXMgc2VyaWFsaXplci4KLSAgICogSWYgdGhlIHNlcmlhbGl6ZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUge0BsaW5rIENvbnRlbnRIYW5kbGVyfQotICAgKiBpbnRlcmZhY2UsIGl0IHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBBIHtAbGluayBDb250ZW50SGFuZGxlcn0gaW50ZXJmYWNlIGludG8gdGhpcyBzZXJpYWxpemVyLAotICAgKiAgb3IgbnVsbCBpZiB0aGUgc2VyaWFsaXplciBpcyBub3QgU0FYIDIgY2FwYWJsZQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZAotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGFzQ29udGVudEhhbmRsZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHtAbGluayBET01TZXJpYWxpemVyfSBpbnRlcmZhY2UgaW50byB0aGlzIHNlcmlhbGl6ZXIuCi0gICAqIElmIHRoZSBzZXJpYWxpemVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHtAbGluayBET01TZXJpYWxpemVyfQotICAgKiBpbnRlcmZhY2UsIGl0IHNob3VsZCByZXR1cm4gbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBBIHtAbGluayBET01TZXJpYWxpemVyfSBpbnRlcmZhY2UgaW50byB0aGlzIHNlcmlhbGl6ZXIsCi0gICAqICBvciBudWxsIGlmIHRoZSBzZXJpYWxpemVyIGlzIG5vdCBET00gY2FwYWJsZQotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZAotICAgKi8KLSAgcHVibGljIERPTVNlcmlhbGl6ZXIgYXNET01TZXJpYWxpemVyKCkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gdGhpczsgIC8vIGZvciBub3cKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldHMgdGhlIHNlcmlhbGl6ZXIuIElmIHRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZSwgdGhlCi0gICAqIHNlcmlhbGl6ZXIgbWF5IGJlIHVzZWQgZm9yIHN1YnNlcXVlbnQgc2VyaWFsaXphdGlvbiBvZiBuZXcKLSAgICogZG9jdW1lbnRzLiBJdCBpcyBwb3NzaWJsZSB0byBjaGFuZ2UgdGhlIG91dHB1dCBmb3JtYXQgYW5kCi0gICAqIG91dHB1dCBzdHJlYW0gcHJpb3IgdG8gc2VyaWFsaXppbmcsIG9yIHRvIHVzZSB0aGUgZXhpc3RpbmcKLSAgICogb3V0cHV0IGZvcm1hdCBhbmQgb3V0cHV0IHN0cmVhbS4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHNlcmlhbGl6ZXIgaGFzIGJlZW4gcmVzZXQgYW5kIGNhbiBiZSByZXVzZWQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlc2V0KCkKLSAgewotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXJpYWxpemVzIHRoZSBET00gbm9kZS4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBvbmx5IGlmIGFuIEkvTwotICAgKiBleGNlcHRpb24gb2NjdXJlZCB3aGlsZSBzZXJpYWxpemluZy4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gVGhlIGVsZW1lbnQgdG8gc2VyaWFsaXplCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gc2VyaWFsaXplLgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIEFuIEkvTyBleGNlcHRpb24gb2NjdXJlZCB3aGlsZSBzZXJpYWxpemluZwotICAgKi8KLSAgcHVibGljIHZvaWQgc2VyaWFsaXplKE5vZGUgbm9kZSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFRyZWVXYWxrZXIgd2Fsa2VyID0gbmV3IFRyZWVXYWxrZXIodGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG9yZy5hcGFjaGUueHBhdGguRE9NMkhlbHBlcigpKTsKLQotICAgICAgd2Fsa2VyLnRyYXZlcnNlKG5vZGUpOwotICAgIH0KLSAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci19ICAvL1RvWE1MU3RyaW5nVmlzaXRvcgotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvV3JpdGVyVG9BU0NJLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvV3JpdGVyVG9BU0NJLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU2Y2Y5NDcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1dyaXRlclRvQVNDSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOwotCi1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3Mgd3JpdGVzIEFTQ0lJIHRvIGEgYnl0ZSBzdHJlYW0gYXMgcXVpY2tseSBhcyBwb3NzaWJsZS4gIEZvciB0aGUgCi0gKiBtb21lbnQgaXQgZG9lcyBub3QgZG8gYnVmZmVyaW5nLCB0aG91Z2ggSSByZXNlcnZlIHRoZSByaWdodCB0byBkbyBzb21lIAotICogYnVmZmVyaW5nIGRvd24gdGhlIGxpbmUgaWYgSSBjYW4gcHJvdmUgdGhhdCBpdCB3aWxsIGJlIGZhc3RlciBldmVuIGlmIHRoZSAKLSAqIG91dHB1dCBzdHJlYW0gaXMgYnVmZmVyZWQuCi0gKi8KLXB1YmxpYyBjbGFzcyBXcml0ZXJUb0FTQ0kgZXh0ZW5kcyBXcml0ZXIKLXsKLQotICAvKiogVGhlIGJ5dGUgc3RyZWFtIHRvIHdyaXRlIHRvLiAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRTdHJlYW0gbV9vczsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIHVuYnVmZmVyZWQgQVNDSUkgd3JpdGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb3MgVGhlIGJ5dGUgc3RyZWFtIHRvIHdyaXRlIHRvLgotICAgKi8KLSAgcHVibGljIFdyaXRlclRvQVNDSShPdXRwdXRTdHJlYW0gb3MpCi0gIHsKLSAgICBtX29zID0gb3M7Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBwb3J0aW9uIG9mIGFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAqCi0gICAqIEBwYXJhbSAgY2hhcnMgIEFycmF5IG9mIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtICBzdGFydCAgIE9mZnNldCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHdyaXRpbmcgY2hhcmFjdGVycwotICAgKiBAcGFyYW0gIGxlbmd0aCAgIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoY2hhciBjaGFyc1tdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotCi0gICAgaW50IG4gPSBsZW5ndGgrc3RhcnQ7Ci0KLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgbV9vcy53cml0ZShjaGFyc1tpXSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFdyaXRlIGEgc2luZ2xlIGNoYXJhY3Rlci4gIFRoZSBjaGFyYWN0ZXIgdG8gYmUgd3JpdHRlbiBpcyBjb250YWluZWQgaW4KLSAgICogdGhlIDE2IGxvdy1vcmRlciBiaXRzIG9mIHRoZSBnaXZlbiBpbnRlZ2VyIHZhbHVlOyB0aGUgMTYgaGlnaC1vcmRlciBiaXRzCi0gICAqIGFyZSBpZ25vcmVkLgotICAgKgotICAgKiA8cD4gU3ViY2xhc3NlcyB0aGF0IGludGVuZCB0byBzdXBwb3J0IGVmZmljaWVudCBzaW5nbGUtY2hhcmFjdGVyIG91dHB1dAotICAgKiBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBjICBpbnQgc3BlY2lmeWluZyBhIGNoYXJhY3RlciB0byBiZSB3cml0dGVuLgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0gICAgbV9vcy53cml0ZShjKTsKLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICBzdHIgIFN0cmluZyB0byBiZSB3cml0dGVuCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgcykgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgbiA9IHMubGVuZ3RoKCk7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgbV9vcy53cml0ZShzLmNoYXJBdChpKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZsdXNoIHRoZSBzdHJlYW0uICBJZiB0aGUgc3RyZWFtIGhhcyBzYXZlZCBhbnkgY2hhcmFjdGVycyBmcm9tIHRoZQotICAgKiB2YXJpb3VzIHdyaXRlKCkgbWV0aG9kcyBpbiBhIGJ1ZmZlciwgd3JpdGUgdGhlbSBpbW1lZGlhdGVseSB0byB0aGVpcgotICAgKiBpbnRlbmRlZCBkZXN0aW5hdGlvbi4gIFRoZW4sIGlmIHRoYXQgZGVzdGluYXRpb24gaXMgYW5vdGhlciBjaGFyYWN0ZXIgb3IKLSAgICogYnl0ZSBzdHJlYW0sIGZsdXNoIGl0LiAgVGh1cyBvbmUgZmx1c2goKSBpbnZvY2F0aW9uIHdpbGwgZmx1c2ggYWxsIHRoZQotICAgKiBidWZmZXJzIGluIGEgY2hhaW4gb2YgV3JpdGVycyBhbmQgT3V0cHV0U3RyZWFtcy4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotICAgIG1fb3MuZmx1c2goKTsKLSAgfQotCi0gIC8qKgotICAgKiBDbG9zZSB0aGUgc3RyZWFtLCBmbHVzaGluZyBpdCBmaXJzdC4gIE9uY2UgYSBzdHJlYW0gaGFzIGJlZW4gY2xvc2VkLAotICAgKiBmdXJ0aGVyIHdyaXRlKCkgb3IgZmx1c2goKSBpbnZvY2F0aW9ucyB3aWxsIGNhdXNlIGFuIElPRXhjZXB0aW9uIHRvIGJlCi0gICAqIHRocm93bi4gIENsb3NpbmcgYSBwcmV2aW91c2x5LWNsb3NlZCBzdHJlYW0sIGhvd2V2ZXIsIGhhcyBubyBlZmZlY3QuCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLSAgICBtX29zLmNsb3NlKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIG91dHB1dCBzdHJlYW0gd2hlcmUgdGhlIGV2ZW50cyB3aWxsIGJlIHNlcmlhbGl6ZWQgdG8uCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSByZXN1bHQgc3RyZWFtLCBvciBudWxsIG9mIG9ubHkgYSB3cml0ZXIgd2FzCi0gICAqIHNldC4KLSAgICovCi0gIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgewotICAgIHJldHVybiBtX29zOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9Xcml0ZXJUb1VURjguamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9Xcml0ZXJUb1VURjguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2RjZGJjMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvV3JpdGVyVG9VVEY4LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemU7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyB3cml0ZXMgQVNDSUkgdG8gYSBieXRlIHN0cmVhbSBhcyBxdWlja2x5IGFzIHBvc3NpYmxlLiAgRm9yIHRoZQotICogbW9tZW50IGl0IGRvZXMgbm90IGRvIGJ1ZmZlcmluZywgdGhvdWdoIEkgcmVzZXJ2ZSB0aGUgcmlnaHQgdG8gZG8gc29tZQotICogYnVmZmVyaW5nIGRvd24gdGhlIGxpbmUgaWYgSSBjYW4gcHJvdmUgdGhhdCBpdCB3aWxsIGJlIGZhc3RlciBldmVuIGlmIHRoZQotICogb3V0cHV0IHN0cmVhbSBpcyBidWZmZXJlZC4KLSAqLwotcHVibGljIGNsYXNzIFdyaXRlclRvVVRGOCBleHRlbmRzIFdyaXRlcgotewotCi0gIC8qKiBUaGUgYnl0ZSBzdHJlYW0gdG8gd3JpdGUgdG8uICovCi0gIHByaXZhdGUgZmluYWwgT3V0cHV0U3RyZWFtIG1fb3M7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiB1bmJ1ZmZlcmVkIFVURi04IHdyaXRlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9zIFRoZSBieXRlIHN0cmVhbSB0byB3cml0ZSB0by4KLSAgICoKLSAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV3JpdGVyVG9VVEY4KE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KLSAgewotICAgIG1fb3MgPSBvczsKLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHNpbmdsZSBjaGFyYWN0ZXIuICBUaGUgY2hhcmFjdGVyIHRvIGJlIHdyaXR0ZW4gaXMgY29udGFpbmVkIGluCi0gICAqIHRoZSAxNiBsb3ctb3JkZXIgYml0cyBvZiB0aGUgZ2l2ZW4gaW50ZWdlciB2YWx1ZTsgdGhlIDE2IGhpZ2gtb3JkZXIgYml0cwotICAgKiBhcmUgaWdub3JlZC4KLSAgICoKLSAgICogPHA+IFN1YmNsYXNzZXMgdGhhdCBpbnRlbmQgdG8gc3VwcG9ydCBlZmZpY2llbnQgc2luZ2xlLWNoYXJhY3RlciBvdXRwdXQKLSAgICogc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gYyAgaW50IHNwZWNpZnlpbmcgYSBjaGFyYWN0ZXIgdG8gYmUgd3JpdHRlbi4KLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGludCBjKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotCi0gICAgaWYgKGMgPCAweDgwKQotICAgICAgbV9vcy53cml0ZShjKTsKLSAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgewotICAgICAgbV9vcy53cml0ZSgweGMwICsgKGMgPj4gNikpOwotICAgICAgbV9vcy53cml0ZSgweDgwICsgKGMgJiAweDNmKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX29zLndyaXRlKDB4ZTAgKyAoYyA+PiAxMikpOwotICAgICAgbV9vcy53cml0ZSgweDgwICsgKChjID4+IDYpICYgMHgzZikpOwotICAgICAgbV9vcy53cml0ZSgweDgwICsgKGMgJiAweDNmKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFdyaXRlIGEgcG9ydGlvbiBvZiBhbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgotICAgKgotICAgKiBAcGFyYW0gIGNoYXJzICBBcnJheSBvZiBjaGFyYWN0ZXJzCi0gICAqIEBwYXJhbSAgc3RhcnQgICBPZmZzZXQgZnJvbSB3aGljaCB0byBzdGFydCB3cml0aW5nIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtICBsZW5ndGggICBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byB3cml0ZQotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIGNoYXIgY2hhcnNbXSwgZmluYWwgaW50IHN0YXJ0LCBmaW5hbCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLQotICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvcyA9IG1fb3M7Ci0KLSAgICBpbnQgbiA9IGxlbmd0aCtzdGFydDsKLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgZmluYWwgY2hhciBjID0gY2hhcnNbaV07Ci0KLSAgICAgIGlmIChjIDwgMHg4MCkKLSAgICAgICAgb3Mud3JpdGUoYyk7Ci0gICAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgICB7Ci0gICAgICAgIG9zLndyaXRlKDB4YzAgKyAoYyA+PiA2KSk7Ci0gICAgICAgIG9zLndyaXRlKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgb3Mud3JpdGUoMHhlMCArIChjID4+IDEyKSk7Ci0gICAgICAgIG9zLndyaXRlKDB4ODAgKyAoKGMgPj4gNikgJiAweDNmKSk7Ci0gICAgICAgIG9zLndyaXRlKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgcyAgU3RyaW5nIHRvIGJlIHdyaXR0ZW4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotCi0gICAgZmluYWwgaW50IG4gPSBzLmxlbmd0aCgpOwotICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvcyA9IG1fb3M7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBmaW5hbCBjaGFyIGMgPSBzLmNoYXJBdChpKTsKLQotICAgICAgaWYgKGMgPCAweDgwKQotICAgICAgICBvcy53cml0ZShjKTsKLSAgICAgIGVsc2UgaWYgKGMgPCAweDgwMCkKLSAgICAgIHsKLSAgICAgICAgb3Mud3JpdGUoMHhjMCArIChjID4+IDYpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBvcy53cml0ZSgweGUwICsgKGMgPj4gMTIpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGbHVzaCB0aGUgc3RyZWFtLiAgSWYgdGhlIHN0cmVhbSBoYXMgc2F2ZWQgYW55IGNoYXJhY3RlcnMgZnJvbSB0aGUKLSAgICogdmFyaW91cyB3cml0ZSgpIG1ldGhvZHMgaW4gYSBidWZmZXIsIHdyaXRlIHRoZW0gaW1tZWRpYXRlbHkgdG8gdGhlaXIKLSAgICogaW50ZW5kZWQgZGVzdGluYXRpb24uICBUaGVuLCBpZiB0aGF0IGRlc3RpbmF0aW9uIGlzIGFub3RoZXIgY2hhcmFjdGVyIG9yCi0gICAqIGJ5dGUgc3RyZWFtLCBmbHVzaCBpdC4gIFRodXMgb25lIGZsdXNoKCkgaW52b2NhdGlvbiB3aWxsIGZsdXNoIGFsbCB0aGUKLSAgICogYnVmZmVycyBpbiBhIGNoYWluIG9mIFdyaXRlcnMgYW5kIE91dHB1dFN0cmVhbXMuCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICB7Ci0gICAgbV9vcy5mbHVzaCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENsb3NlIHRoZSBzdHJlYW0sIGZsdXNoaW5nIGl0IGZpcnN0LiAgT25jZSBhIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQsCi0gICAqIGZ1cnRoZXIgd3JpdGUoKSBvciBmbHVzaCgpIGludm9jYXRpb25zIHdpbGwgY2F1c2UgYW4gSU9FeGNlcHRpb24gdG8gYmUKLSAgICogdGhyb3duLiAgQ2xvc2luZyBhIHByZXZpb3VzbHktY2xvc2VkIHN0cmVhbSwgaG93ZXZlciwgaGFzIG5vIGVmZmVjdC4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICoKLSAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLSAgICBtX29zLmNsb3NlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvdXRwdXQgc3RyZWFtIHdoZXJlIHRoZSBldmVudHMgd2lsbCBiZSBzZXJpYWxpemVkIHRvLgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB0aGUgcmVzdWx0IHN0cmVhbSwgb3IgbnVsbCBvZiBvbmx5IGEgd3JpdGVyIHdhcwotICAgKiBzZXQuCi0gICAqLwotICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpCi0gIHsKLSAgICByZXR1cm4gbV9vczsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1dyaXRlclRvVVRGOEJ1ZmZlcmVkLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvV3JpdGVyVG9VVEY4QnVmZmVyZWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGVjMmM4Mi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvV3JpdGVyVG9VVEY4QnVmZmVyZWQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQxMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZTsKLQotaW1wb3J0IGphdmEuaW8uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHdyaXRlcyBBU0NJSSB0byBhIGJ5dGUgc3RyZWFtIGFzIHF1aWNrbHkgYXMgcG9zc2libGUuICBGb3IgdGhlCi0gKiBtb21lbnQgaXQgZG9lcyBub3QgZG8gYnVmZmVyaW5nLCB0aG91Z2ggSSByZXNlcnZlIHRoZSByaWdodCB0byBkbyBzb21lCi0gKiBidWZmZXJpbmcgZG93biB0aGUgbGluZSBpZiBJIGNhbiBwcm92ZSB0aGF0IGl0IHdpbGwgYmUgZmFzdGVyIGV2ZW4gaWYgdGhlCi0gKiBvdXRwdXQgc3RyZWFtIGlzIGJ1ZmZlcmVkLgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgV3JpdGVyVG9VVEY4QnVmZmVyZWQgZXh0ZW5kcyBXcml0ZXIKLXsKLQotICAvKiogVGhlIGJ5dGUgc3RyZWFtIHRvIHdyaXRlIHRvLiAoc2MgJiBzYiByZW1vdmUgZmluYWwgdG8gY29tcGlsZSBpbiBKREsgMS4xLjgpICovCi0gIHByaXZhdGUgT3V0cHV0U3RyZWFtIG1fb3M7Ci0KLSAgLyoqCi0gICAqIFRoZSBpbnRlcm5hbCBidWZmZXIgd2hlcmUgZGF0YSBpcyBzdG9yZWQuIAotICAgKiAoc2MgJiBzYiByZW1vdmUgZmluYWwgdG8gY29tcGlsZSBpbiBKREsgMS4xLjgpCi0gICAqLwotICBwcml2YXRlIGJ5dGUgYnVmW107Ci0KLSAgLyoqCi0gICAqIFRoZSBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgaW4gdGhlIGJ1ZmZlci4gVGhpcyB2YWx1ZSBpcyBhbHdheXMKLSAgICogaW4gdGhlIHJhbmdlIDx0dD4wPC90dD4gdGhyb3VnaCA8dHQ+YnVmLmxlbmd0aDwvdHQ+OyBlbGVtZW50cwotICAgKiA8dHQ+YnVmWzBdPC90dD4gdGhyb3VnaCA8dHQ+YnVmW2NvdW50LTFdPC90dD4gY29udGFpbiB2YWxpZAotICAgKiBieXRlIGRhdGEuCi0gICAqLwotICBwcml2YXRlIGludCBjb3VudDsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGJ1ZmZlcmVkIFVURi04IHdyaXRlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtICAgb3V0ICAgIHRoZSB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0uCi0gICAqCi0gICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFdyaXRlclRvVVRGOEJ1ZmZlcmVkKE91dHB1dFN0cmVhbSBvdXQpCi0gICAgICAgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KLSAgewotICAgIHRoaXMob3V0LCA4ICogMTAyNCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGJ1ZmZlcmVkIFVURi04IHdyaXRlciB0byB3cml0ZSBkYXRhIHRvIHRoZQotICAgKiBzcGVjaWZpZWQgdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtIHdpdGggdGhlIHNwZWNpZmllZCBidWZmZXIKLSAgICogc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtICAgb3V0ICAgIHRoZSB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0uCi0gICAqIEBwYXJhbSAgIHNpemUgICB0aGUgYnVmZmVyIHNpemUuCi0gICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNpemUgPD0gMC4KLSAgICovCi0gIHB1YmxpYyBXcml0ZXJUb1VURjhCdWZmZXJlZChmaW5hbCBPdXRwdXRTdHJlYW0gb3V0LCBmaW5hbCBpbnQgc2l6ZSkKLSAgewotCi0gICAgbV9vcyA9IG91dDsKLQotICAgIGlmIChzaXplIDw9IDApCi0gICAgewotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9CVUZGRVJfU0laRV9MRVNTVEhBTl9aRVJPLCBudWxsKSk7IC8vIkJ1ZmZlciBzaXplIDw9IDAiKTsKLSAgICB9Ci0KLSAgICBidWYgPSBuZXcgYnl0ZVtzaXplXTsKLSAgICBjb3VudCA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBzaW5nbGUgY2hhcmFjdGVyLiAgVGhlIGNoYXJhY3RlciB0byBiZSB3cml0dGVuIGlzIGNvbnRhaW5lZCBpbgotICAgKiB0aGUgMTYgbG93LW9yZGVyIGJpdHMgb2YgdGhlIGdpdmVuIGludGVnZXIgdmFsdWU7IHRoZSAxNiBoaWdoLW9yZGVyIGJpdHMKLSAgICogYXJlIGlnbm9yZWQuCi0gICAqCi0gICAqIDxwPiBTdWJjbGFzc2VzIHRoYXQgaW50ZW5kIHRvIHN1cHBvcnQgZWZmaWNpZW50IHNpbmdsZS1jaGFyYWN0ZXIgb3V0cHV0Ci0gICAqIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGMgIGludCBzcGVjaWZ5aW5nIGEgY2hhcmFjdGVyIHRvIGJlIHdyaXR0ZW4uCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBpbnQgYykgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLSAgICAKLSAgICBpZiAoYyA8IDB4ODApCi0gICAgewotICAgICAgaWYgKGNvdW50ID49IGJ1Zi5sZW5ndGgpCi0gICAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKGMpOwotICAgIH0KLSAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgewotICAgICAgaWYgKGNvdW50KzEgPj0gYnVmLmxlbmd0aCkKLSAgICAgICAgZmx1c2hCdWZmZXIoKTsKLSAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhjMCArIChjID4+IDYpKTsKLSAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArIChjICYgMHgzZikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKGNvdW50KzIgPj0gYnVmLmxlbmd0aCkKLSAgICAgICAgZmx1c2hCdWZmZXIoKTsKLSAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhlMCArIChjID4+IDEyKSk7Ci0gICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoKGMgPj4gNikgJiAweDNmKSk7Ci0gICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgYSBwb3J0aW9uIG9mIGFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAqCi0gICAqIEBwYXJhbSAgY2hhcnMgIEFycmF5IG9mIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtICBzdGFydCAgIE9mZnNldCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHdyaXRpbmcgY2hhcmFjdGVycwotICAgKiBAcGFyYW0gIGxlbmd0aCAgIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlCi0gICAqCi0gICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBJZiBhbiBJL08gZXJyb3Igb2NjdXJzCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHdyaXRlRGlyZWN0KAotICAgICAgICAgIGZpbmFsIGNoYXIgY2hhcnNbXSwgZmluYWwgaW50IHN0YXJ0LCBmaW5hbCBpbnQgbGVuZ3RoKQotICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotCi0gICAgZmluYWwgT3V0cHV0U3RyZWFtIG9zID0gbV9vczsKLQotICAgIGludCBuID0gbGVuZ3RoK3N0YXJ0OwotICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBmaW5hbCBjaGFyIGMgPSBjaGFyc1tpXTsKLQotICAgICAgaWYgKGMgPCAweDgwKQotICAgICAgICBvcy53cml0ZShjKTsKLSAgICAgIGVsc2UgaWYgKGMgPCAweDgwMCkKLSAgICAgIHsKLSAgICAgICAgb3Mud3JpdGUoMHhjMCArIChjID4+IDYpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBvcy53cml0ZSgweGUwICsgKGMgPj4gMTIpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICBzICBTdHJpbmcgdG8gYmUgd3JpdHRlbgotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHdyaXRlRGlyZWN0KGZpbmFsIFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24KLSAgewotCi0gICAgZmluYWwgaW50IG4gPSBzLmxlbmd0aCgpOwotICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvcyA9IG1fb3M7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBmaW5hbCBjaGFyIGMgPSBzLmNoYXJBdChpKTsKLQotICAgICAgaWYgKGMgPCAweDgwKQotICAgICAgICBvcy53cml0ZShjKTsKLSAgICAgIGVsc2UgaWYgKGMgPCAweDgwMCkKLSAgICAgIHsKLSAgICAgICAgb3Mud3JpdGUoMHhjMCArIChjID4+IDYpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBvcy53cml0ZSgweGUwICsgKGMgPj4gMTIpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgICAgb3Mud3JpdGUoMHg4MCArIChjICYgMHgzZikpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHBvcnRpb24gb2YgYW4gYXJyYXkgb2YgY2hhcmFjdGVycy4KLSAgICoKLSAgICogQHBhcmFtICBjaGFycyAgQXJyYXkgb2YgY2hhcmFjdGVycwotICAgKiBAcGFyYW0gIHN0YXJ0ICAgT2Zmc2V0IGZyb20gd2hpY2ggdG8gc3RhcnQgd3JpdGluZyBjaGFyYWN0ZXJzCi0gICAqIEBwYXJhbSAgbGVuZ3RoICAgTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUKLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICoKLSAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBjaGFyIGNoYXJzW10sIGZpbmFsIGludCBzdGFydCwgZmluYWwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBXZSBtdWx0aXBseSB0aGUgbGVuZ3RoIGJ5IHRocmVlIHNpbmNlIHRoaXMgaXMgdGhlIG1heGltdW0gbGVuZ3RoCi0gICAgLy8gb2YgdGhlIGNoYXJhY3RlcnMgdGhhdCB3ZSBjYW4gcHV0IGludG8gdGhlIGJ1ZmZlci4gIEl0IGlzIHBvc3NpYmxlCi0gICAgLy8gZm9yIGVhY2ggVW5pY29kZSBjaGFyYWN0ZXIgdG8gZXhwYW5kIHRvIHRocmVlIGJ5dGVzLgotCi0gICAgaW50IGxlbmd0aHgzID0gKGxlbmd0aCA8PCAxKSArIGxlbmd0aDsKLQotICAgIGlmIChsZW5ndGh4MyA+PSBidWYubGVuZ3RoKQotICAgIHsKLQotICAgICAgLyogSWYgdGhlIHJlcXVlc3QgbGVuZ3RoIGV4Y2VlZHMgdGhlIHNpemUgb2YgdGhlIG91dHB1dCBidWZmZXIsCi0gICAgICAgICBmbHVzaCB0aGUgb3V0cHV0IGJ1ZmZlciBhbmQgdGhlbiB3cml0ZSB0aGUgZGF0YSBkaXJlY3RseS4KLSAgICAgICAgIEluIHRoaXMgd2F5IGJ1ZmZlcmVkIHN0cmVhbXMgd2lsbCBjYXNjYWRlIGhhcm1sZXNzbHkuICovCi0gICAgICBmbHVzaEJ1ZmZlcigpOwotICAgICAgd3JpdGVEaXJlY3QoY2hhcnMsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgaWYgKGxlbmd0aHgzID4gYnVmLmxlbmd0aCAtIGNvdW50KQotICAgIHsKLSAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgfQotCi0gICAgZmluYWwgT3V0cHV0U3RyZWFtIG9zID0gbV9vczsKLSAgICBpbnQgbiA9IGxlbmd0aCtzdGFydDsKLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgZmluYWwgY2hhciBjID0gY2hhcnNbaV07Ci0KLSAgICAgIGlmIChjIDwgMHg4MCkKLSAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpIChjKTsKLSAgICAgIGVsc2UgaWYgKGMgPCAweDgwMCkKLSAgICAgIHsKLSAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweGMwICsgKGMgPj4gNikpOwotICAgICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweGUwICsgKGMgPj4gMTIpKTsKLSAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweDgwICsgKChjID4+IDYpICYgMHgzZikpOwotICAgICAgICBidWZbY291bnQrK10gPSAoYnl0ZSkgKDB4ODAgKyAoYyAmIDB4M2YpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgfQotCi0gIC8qKgotICAgKiBXcml0ZSBhIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICBzICBTdHJpbmcgdG8gYmUgd3JpdHRlbgotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKi8KLSAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgU3RyaW5nIHMpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0KLSAgICBmaW5hbCBpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKLQotICAgIC8vIFdlIG11bHRpcGx5IHRoZSBsZW5ndGggYnkgdGhyZWUgc2luY2UgdGhpcyBpcyB0aGUgbWF4aW11bSBsZW5ndGgKLSAgICAvLyBvZiB0aGUgY2hhcmFjdGVycyB0aGF0IHdlIGNhbiBwdXQgaW50byB0aGUgYnVmZmVyLiAgSXQgaXMgcG9zc2libGUKLSAgICAvLyBmb3IgZWFjaCBVbmljb2RlIGNoYXJhY3RlciB0byBleHBhbmQgdG8gdGhyZWUgYnl0ZXMuCi0KLSAgICBpbnQgbGVuZ3RoeDMgPSAobGVuZ3RoIDw8IDEpICsgbGVuZ3RoOwotCi0gICAgaWYgKGxlbmd0aHgzID49IGJ1Zi5sZW5ndGgpCi0gICAgewotCi0gICAgICAvKiBJZiB0aGUgcmVxdWVzdCBsZW5ndGggZXhjZWVkcyB0aGUgc2l6ZSBvZiB0aGUgb3V0cHV0IGJ1ZmZlciwKLSAgICAgICAgIGZsdXNoIHRoZSBvdXRwdXQgYnVmZmVyIGFuZCB0aGVuIHdyaXRlIHRoZSBkYXRhIGRpcmVjdGx5LgotICAgICAgICAgSW4gdGhpcyB3YXkgYnVmZmVyZWQgc3RyZWFtcyB3aWxsIGNhc2NhZGUgaGFybWxlc3NseS4gKi8KLSAgICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgICB3cml0ZURpcmVjdChzKTsKLQotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIGlmIChsZW5ndGh4MyA+IGJ1Zi5sZW5ndGggLSBjb3VudCkKLSAgICB7Ci0gICAgICBmbHVzaEJ1ZmZlcigpOwotICAgIH0KLQotICAgIGZpbmFsIE91dHB1dFN0cmVhbSBvcyA9IG1fb3M7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKQotICAgIHsKLSAgICAgIGZpbmFsIGNoYXIgYyA9IHMuY2hhckF0KGkpOwotCi0gICAgICBpZiAoYyA8IDB4ODApCi0gICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoYyk7Ci0gICAgICBlbHNlIGlmIChjIDwgMHg4MDApCi0gICAgICB7Ci0gICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhjMCArIChjID4+IDYpKTsKLSAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweDgwICsgKGMgJiAweDNmKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHhlMCArIChjID4+IDEyKSk7Ci0gICAgICAgIGJ1Zltjb3VudCsrXSA9IChieXRlKSAoMHg4MCArICgoYyA+PiA2KSAmIDB4M2YpKTsKLSAgICAgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpICgweDgwICsgKGMgJiAweDNmKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogRmx1c2ggdGhlIGludGVybmFsIGJ1ZmZlcgotICAgKgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBmbHVzaEJ1ZmZlcigpIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoY291bnQgPiAwKQotICAgIHsKLSAgICAgIG1fb3Mud3JpdGUoYnVmLCAwLCBjb3VudCk7Ci0KLSAgICAgIGNvdW50ID0gMDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmx1c2ggdGhlIHN0cmVhbS4gIElmIHRoZSBzdHJlYW0gaGFzIHNhdmVkIGFueSBjaGFyYWN0ZXJzIGZyb20gdGhlCi0gICAqIHZhcmlvdXMgd3JpdGUoKSBtZXRob2RzIGluIGEgYnVmZmVyLCB3cml0ZSB0aGVtIGltbWVkaWF0ZWx5IHRvIHRoZWlyCi0gICAqIGludGVuZGVkIGRlc3RpbmF0aW9uLiAgVGhlbiwgaWYgdGhhdCBkZXN0aW5hdGlvbiBpcyBhbm90aGVyIGNoYXJhY3RlciBvcgotICAgKiBieXRlIHN0cmVhbSwgZmx1c2ggaXQuICBUaHVzIG9uZSBmbHVzaCgpIGludm9jYXRpb24gd2lsbCBmbHVzaCBhbGwgdGhlCi0gICAqIGJ1ZmZlcnMgaW4gYSBjaGFpbiBvZiBXcml0ZXJzIGFuZCBPdXRwdXRTdHJlYW1zLgotICAgKgotICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgSWYgYW4gSS9PIGVycm9yIG9jY3VycwotICAgKgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotICAgIGZsdXNoQnVmZmVyKCk7Ci0gICAgbV9vcy5mbHVzaCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENsb3NlIHRoZSBzdHJlYW0sIGZsdXNoaW5nIGl0IGZpcnN0LiAgT25jZSBhIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQsCi0gICAqIGZ1cnRoZXIgd3JpdGUoKSBvciBmbHVzaCgpIGludm9jYXRpb25zIHdpbGwgY2F1c2UgYW4gSU9FeGNlcHRpb24gdG8gYmUKLSAgICogdGhyb3duLiAgQ2xvc2luZyBhIHByZXZpb3VzbHktY2xvc2VkIHN0cmVhbSwgaG93ZXZlciwgaGFzIG5vIGVmZmVjdC4KLSAgICoKLSAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIElmIGFuIEkvTyBlcnJvciBvY2N1cnMKLSAgICoKLSAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gIHsKLSAgICBmbHVzaEJ1ZmZlcigpOwotICAgIG1fb3MuY2xvc2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG91dHB1dCBzdHJlYW0gd2hlcmUgdGhlIGV2ZW50cyB3aWxsIGJlIHNlcmlhbGl6ZWQgdG8uCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSByZXN1bHQgc3RyZWFtLCBvciBudWxsIG9mIG9ubHkgYSB3cml0ZXIgd2FzCi0gICAqIHNldC4KLSAgICovCi0gIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkKLSAgewotICAgIHJldHVybiBtX29zOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvWE1MRW50aXRpZXMucmVzIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL1hNTEVudGl0aWVzLnJlcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZThlM2M1ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvWE1MRW50aXRpZXMucmVzCisrKyAvZGV2L251bGwKQEAgLTEsMTIgKzAsMCBAQAotIyAkSWQkCi0jCi0jIEB2ZXJzaW9uICRSZXZpc2lvbiQgJERhdGUkCi0jIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KLSMKLSMgQ2hhcmFjdGVyIGVudGl0eSByZWZlcmVuY2VzIGZvciBtYXJrdXAtc2lnbmlmaWNhbnQKLSMKLXF1b3QgMzQKLWFtcCAzOAotbHQgNjAKLWd0IDYyCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzFiNTk2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyMSArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIFNlcmlhbGl6ZSBQYWNrYWdlLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPlByb2Nlc3NlcyBTQVggZXZlbnRzIGludG8gc3RyZWFtcy48L3A+Ci0gICAgCi0gICAgPHA+VGhlIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeX0gaXMgdXNlZCB0byAKLSAgICBjcmVhdGUgYSB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplcn0gZnJvbSBhIHNldCBvZiAKLSAgICBvdXRwdXQgcHJvcGVydGllcyAoc2VlIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXN9KS48L3A+Ci0gICAgPHA+e0BsaW5rIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1hNTH0gYWN0cyBhcyB0aGUgbWFpbiAKLSAgICBiYXNlY2xhc3MgZm9yIHRoZSBYYWxhbiBzZXJpYWxpemVyIGltcGxlbWVudGF0aW9ucy4gIAotICAgIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyVG9IVE1MfSBkZXJpdmVzIGZyb20gdGhpcyAKLSAgICB0byBpbXBsZW1lbnQgSFRNTCBzZXJpYWxpemF0aW9uLiAge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1RleHR9Ci0gICAgaW1wbGVtZW50cyBwbGFpbiB0ZXh0IHNlcmlhbGl6YXRpb24uPC9wPgotICAgIDxwPlhNTCBtYXBwaW5nIGZyb20gY2hhcmFjdGVycyB0byBlbnRpdHkgcmVmZXJlbmNlcyBpcyBkZWZpbmVkIGluIAotICAgIFhNTEVudGl0aWVzLnJlcy4gIEhUTUwgZW50aXR5IHJlZmVyZW5jZSBtYXBwaW5nIGlzIGRlZmluZWQgaW4gSFRNTEVudGl0aWVzLnJlcy4KLSAgICA8L3A+Ci0gICAgPHA+RW5jb2RpbmcgaW5mb3JtYXRpb24gaXMgZGVmaW5lZCBpbiB7QGxpbmsgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuRW5jb2RpbmdzfS48L3A+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9zZXJpYWxpemVyLnByb3BlcnRpZXMgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvc2VyaWFsaXplci5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3OTJkNjAwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9zZXJpYWxpemVyLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi0jCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvQVZULmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvQVZULmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE4NzZkYTAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0FWVC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjA2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ0J1ZmZlclBvb2w7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5TdHlsZXNoZWV0SGFuZGxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIENsYXNzIHRvIGhvbGQgYW4gQXR0cmlidXRlIFZhbHVlIFRlbXBsYXRlLgotICovCi1wdWJsaWMgY2xhc3MgQVZUIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUKLXsKLQotICAvKioKLSAgICogSWYgdGhlIEFWVCBpcyBub3QgY29tcGxleCwganVzdCBob2xkIHRoZSBzaW1wbGUgc3RyaW5nLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX3NpbXBsZVN0cmluZyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIElmIHRoZSBBVlQgaXMgY29tcGxleCwgaG9sZCBhIFZlY3RvciBvZiBBVlRQYXJ0cy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9wYXJ0cyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcmF3TmFtZTsKLQotICAvKioKLSAgICogR2V0IHRoZSByYXcgbmFtZSBvZiB0aGUgYXR0cmlidXRlLCB3aXRoIHRoZSBwcmVmaXggdW5wcm9jZXNzZWQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByZWZpeGVkIG5hbWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFJhd05hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fcmF3TmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJhdyBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUsIHdpdGggdGhlIHByZWZpeCB1bnByb2Nlc3NlZC4KLSAgICoKLSAgICogQHBhcmFtIHJhd05hbWUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByZWZpeGVkIG5hbWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSYXdOYW1lKFN0cmluZyByYXdOYW1lKQotICB7Ci0gICAgbV9yYXdOYW1lID0gcmF3TmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX25hbWU7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBuYW1lIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gbmFtZSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKQotICB7Ci0gICAgbV9uYW1lID0gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgb3duaW5nIGF0dHJpYnV0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV91cmk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBVUkksICIiIGlmIG51bGwgbmFtZXNwYWNlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVUkkoKQotICB7Ci0gICAgcmV0dXJuIG1fdXJpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAcGFyYW0gdXJpIG5vbi1udWxsIHJlZmVyZW5jZSB0byBVUkksICIiIGlmIG51bGwgbmFtZXNwYWNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VVJJKFN0cmluZyB1cmkpCi0gIHsKLSAgICBtX3VyaSA9IHVyaTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gQVZUIGJ5IHBhcnNpbmcgdGhlIHN0cmluZywgYW5kIGVpdGhlcgotICAgKiBjb25zdHJ1Y3RpbmcgYSB2ZWN0b3Igb2YgQVZUUGFydHMsIG9yIHNpbXBseSBob2xkCi0gICAqIG9uIHRvIHRoZSBzdHJpbmcgaWYgdGhlIEFWVCBpcyBzaW1wbGUuCi0gICAqCi0gICAqIEBwYXJhbSBoYW5kbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBTdHlsZXNoZWV0SGFuZGxlciB0aGF0IGlzIGNvbnN0cnVjdGluZy4KLSAgICogQHBhcmFtIHVyaSBub24tbnVsbCByZWZlcmVuY2UgdG8gVVJJLCAiIiBpZiBudWxsIG5hbWVzcGFjZS4KLSAgICogQHBhcmFtIG5hbWUgIG5vbi1udWxsIHJlZmVyZW5jZSB0byBuYW1lIHN0cmluZy4KLSAgICogQHBhcmFtIHJhd05hbWUgcHJlZml4ZWQgbmFtZS4KLSAgICogQHBhcmFtIHN0cmluZ2VkVmFsdWUgbm9uLW51bGwgcmF3IHN0cmluZyB2YWx1ZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQVZUKFN0eWxlc2hlZXRIYW5kbGVyIGhhbmRsZXIsIFN0cmluZyB1cmksIFN0cmluZyBuYW1lLCBTdHJpbmcgcmF3TmFtZSwgU3RyaW5nIHN0cmluZ2VkVmFsdWUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV91cmkgPSB1cmk7Ci0gICAgbV9uYW1lID0gbmFtZTsKLSAgICBtX3Jhd05hbWUgPSByYXdOYW1lOwotCi0gICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoc3RyaW5nZWRWYWx1ZSwgInt9XCJcJyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgaW50IG5Ub2tlbnMgPSB0b2tlbml6ZXIuY291bnRUb2tlbnMoKTsKLQotICAgIGlmIChuVG9rZW5zIDwgMikKLSAgICB7Ci0gICAgICBtX3NpbXBsZVN0cmluZyA9IHN0cmluZ2VkVmFsdWU7ICAvLyB0aGVuIGRvIHRoZSBzaW1wbGUgdGhpbmcKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmZmVyID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgZXhwckJ1ZmZlciA9IFN0cmluZ0J1ZmZlclBvb2wuZ2V0KCk7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBtX3BhcnRzID0gbmV3IFZlY3RvcihuVG9rZW5zICsgMSk7Ci0KLSAgICAgICAgU3RyaW5nIHQgPSBudWxsOyAgLy8gYmFzZSB0b2tlbgotICAgICAgICBTdHJpbmcgbG9va2FoZWFkID0gbnVsbDsgIC8vIG5leHQgdG9rZW4KLSAgICAgICAgU3RyaW5nIGVycm9yID0gbnVsbDsgIC8vIGlmIG5vbi1udWxsLCBicmVhayBmcm9tIGxvb3AKLQotICAgICAgICB3aGlsZSAodG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChsb29rYWhlYWQgIT0gbnVsbCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0ID0gbG9va2FoZWFkOwotICAgICAgICAgICAgbG9va2FoZWFkID0gbnVsbDsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgdCA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLQotICAgICAgICAgIGlmICh0Lmxlbmd0aCgpID09IDEpCi0gICAgICAgICAgewotICAgICAgICAgICAgc3dpdGNoICh0LmNoYXJBdCgwKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgIGNhc2UgKCdcIicpIDoKLSAgICAgICAgICAgIGNhc2UgKCdcJycpIDoKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAvLyBqdXN0IGtlZXAgb24gZ29pbmcsIHNpbmNlIHdlJ3JlIG5vdCBpbiBhbiBhdHRyaWJ1dGUgdGVtcGxhdGUKLSAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0KTsKLQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgKCd7JykgOgotICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgIC8vIEF0dHJpYnV0ZSBWYWx1ZSBUZW1wbGF0ZSBzdGFydAotICAgICAgICAgICAgICBsb29rYWhlYWQgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0KLSAgICAgICAgICAgICAgaWYgKGxvb2thaGVhZC5lcXVhbHMoInsiKSkKLSAgICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgLy8gRG91YmxlIGN1cmx5cyBtZWFuIGVzY2FwZSB0byBzaG93IGN1cmx5Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChsb29rYWhlYWQpOwotCi0gICAgICAgICAgICAgICAgbG9va2FoZWFkID0gbnVsbDsKLQotICAgICAgICAgICAgICAgIGJyZWFrOyAgLy8gZnJvbSBzd2l0Y2gKLSAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgIC8qCi0gICAgICAgICAgICAgIGVsc2UgaWYobG9va2FoZWFkLmVxdWFscygiXCIiKSB8fCBsb29rYWhlYWQuZXF1YWxzKCJcJyIpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIC8vIEVycm9yLiBFeHByZXNzaW9ucyBjYW4gbm90IGJlZ2luIHdpdGggcXVvdGVzLgotICAgICAgICAgICAgICBlcnJvciA9ICJFeHByZXNzaW9ucyBjYW4gbm90IGJlZ2luIHdpdGggcXVvdGVzLiI7Ci0gICAgICAgICAgICAgIGJyZWFrOyAvLyBmcm9tIHN3aXRjaAotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICovCi0gICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgPiAwKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIG1fcGFydHMuYWRkRWxlbWVudChuZXcgQVZUUGFydFNpbXBsZShidWZmZXIudG9TdHJpbmcoKSkpOwotICAgICAgICAgICAgICAgICAgYnVmZmVyLnNldExlbmd0aCgwKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBleHByQnVmZmVyLnNldExlbmd0aCgwKTsKLQotICAgICAgICAgICAgICAgIHdoaWxlIChudWxsICE9IGxvb2thaGVhZCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBpZiAobG9va2FoZWFkLmxlbmd0aCgpID09IDEpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAobG9va2FoZWFkLmNoYXJBdCgwKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBjYXNlICdcJycgOgotICAgICAgICAgICAgICAgICAgICBjYXNlICdcIicgOgotICAgICAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAvLyBTdHJpbmcgc3RhcnQKLSAgICAgICAgICAgICAgICAgICAgICBleHByQnVmZmVyLmFwcGVuZChsb29rYWhlYWQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHF1b3RlID0gbG9va2FoZWFkOwotCi0gICAgICAgICAgICAgICAgICAgICAgLy8gQ29uc3VtZSBzdHVmZiAndGlsbCBuZXh0IHF1b3RlCi0gICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotCi0gICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCFsb29rYWhlYWQuZXF1YWxzKHF1b3RlKSkKLSAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBleHByQnVmZmVyLmFwcGVuZChsb29rYWhlYWQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICBsb29rYWhlYWQgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgZXhwckJ1ZmZlci5hcHBlbmQobG9va2FoZWFkKTsKLQotICAgICAgICAgICAgICAgICAgICAgIGxvb2thaGVhZCA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLQotICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3snIDoKLSAgICAgICAgICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgICAgICAgLy8gV2hhdCdzIGFub3RoZXIgY3VybHkgZG9pbmcgaGVyZT8KLSAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fQ1VSTFlCUkFDRSwgbnVsbCk7ICAvLyJFcnJvcjogQ2FuIG5vdCBoYXZlIFwie1wiIHdpdGhpbiBleHByZXNzaW9uLiI7Ci0gICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gbnVsbDsgIC8vIGJyZWFrcyBvdXQgb2YgaW5uZXIgd2hpbGUgbG9vcAotCi0gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2FzZSAnfScgOgotICAgICAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAvLyBQcm9wZXIgY2xvc2Ugb2YgYXR0cmlidXRlIHRlbXBsYXRlLgotICAgICAgICAgICAgICAgICAgICAgIC8vIEV2YWx1YXRlIHRoZSBleHByZXNzaW9uLgotICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5zZXRMZW5ndGgoMCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICBYUGF0aCB4cGF0aCA9Ci0gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmNyZWF0ZVhQYXRoKGV4cHJCdWZmZXIudG9TdHJpbmcoKSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICBtX3BhcnRzLmFkZEVsZW1lbnQobmV3IEFWVFBhcnRYUGF0aCh4cGF0aCkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gbnVsbDsgIC8vIGJyZWFrcyBvdXQgb2YgaW5uZXIgd2hpbGUgbG9vcAotCi0gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgICAgICAgIC8vIHBhcnQgb2YgdGhlIHRlbXBsYXRlIHN0dWZmLCBqdXN0IGFkZCBpdC4KLSAgICAgICAgICAgICAgICAgICAgICBleHByQnVmZmVyLmFwcGVuZChsb29rYWhlYWQpOwotCi0gICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIH0gIC8vIGVuZCBpbm5lciBzd2l0Y2gKLSAgICAgICAgICAgICAgICAgIH0gIC8vIGVuZCBpZiBsb29rYWhlYWQgbGVuZ3RoID09IDEKLSAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgICAgICAvLyBwYXJ0IG9mIHRoZSB0ZW1wbGF0ZSBzdHVmZiwganVzdCBhZGQgaXQuCi0gICAgICAgICAgICAgICAgICAgIGV4cHJCdWZmZXIuYXBwZW5kKGxvb2thaGVhZCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gIC8vIGVuZCB3aGlsZSghbG9va2FoZWFkLmVxdWFscygifSIpKQotCi0gICAgICAgICAgICAgICAgaWYgKGVycm9yICE9IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgYnJlYWs7ICAvLyBmcm9tIGlubmVyIHdoaWxlIGxvb3AKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhc2UgKCd9JykgOgotICAgICAgICAgICAgewotICAgICAgICAgICAgICBsb29rYWhlYWQgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0KLSAgICAgICAgICAgICAgaWYgKGxvb2thaGVhZC5lcXVhbHMoIn0iKSkKLSAgICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgICAgLy8gRG91YmxlIGN1cmx5cyBtZWFuIGVzY2FwZSB0byBzaG93IGN1cmx5Ci0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChsb29rYWhlYWQpOwotCi0gICAgICAgICAgICAgICAgbG9va2FoZWFkID0gbnVsbDsgIC8vIHN3YWxsb3cKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAgIC8vIElsbGVnYWwsIEkgdGhpbmsuLi4KLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBoYW5kbGVyLndhcm4oWFNMVEVycm9yUmVzb3VyY2VzLldHX0ZPVU5EX0NVUkxZQlJBQ0UsIG51bGwpOyAgLy8iRm91bmQgXCJ9XCIgYnV0IG5vIGF0dHJpYnV0ZSB0ZW1wbGF0ZSBvcGVuISIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgifSIpOwotCi0gICAgICAgICAgICAgICAgLy8gbGVhdmUgdGhlIGxvb2thaGVhZCB0byBiZSBwcm9jZXNzZWQgYnkgdGhlIG5leHQgcm91bmQuCi0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGRlZmF1bHQgOgotICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgIC8vIEFueXRoaW5nIGVsc2UganVzdCBhZGQgdG8gc3RyaW5nLgotICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgfSAgLy8gZW5kIHN3aXRjaCB0Ci0gICAgICAgICAgfSAgLy8gZW5kIGlmIGxlbmd0aCA9PSAxCi0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gQW55dGhpbmcgZWxzZSBqdXN0IGFkZCB0byBzdHJpbmcuCi0gICAgICAgICAgICBidWZmZXIuYXBwZW5kKHQpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlmIChudWxsICE9IGVycm9yKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBoYW5kbGVyLndhcm4oWFNMVEVycm9yUmVzb3VyY2VzLldHX0FUVFJfVEVNUExBVEUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGVycm9yIH0pOyAgLy8iQXR0ciBUZW1wbGF0ZSwgIitlcnJvcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgIH0gIC8vIGVuZCB3aGlsZSh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotCi0gICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgbV9wYXJ0cy5hZGRFbGVtZW50KG5ldyBBVlRQYXJ0U2ltcGxlKGJ1ZmZlci50b1N0cmluZygpKSk7Ci0gICAgICAgICAgYnVmZmVyLnNldExlbmd0aCgwKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmZmVyKTsKLSAgICAgICAgU3RyaW5nQnVmZmVyUG9vbC5mcmVlKGV4cHJCdWZmZXIpOwotICAgICAgfQotICAgIH0gIC8vIGVuZCBlbHNlIG5Ub2tlbnMgPiAxCi0KLSAgICBpZiAobnVsbCA9PSBtX3BhcnRzICYmIChudWxsID09IG1fc2ltcGxlU3RyaW5nKSkKLSAgICB7Ci0KLSAgICAgIC8vIEVycm9yPwotICAgICAgbV9zaW1wbGVTdHJpbmcgPSAiIjsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBBVlQgYXMgdGhlIG9yaWdpbmFsIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgQVZUIGFzIHRoZSBvcmlnaW5hbCBzdHJpbmcKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U2ltcGxlU3RyaW5nKCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9zaW1wbGVTdHJpbmcpCi0gICAgewotICAgICAgcmV0dXJuIG1fc2ltcGxlU3RyaW5nOwotICAgIH0KLSAgICBlbHNlIGlmIChudWxsICE9IG1fcGFydHMpCi0gICAgewotICAgICAgRmFzdFN0cmluZ0J1ZmZlciBidWYgPSBTdHJpbmdCdWZmZXJQb29sLmdldCgpOwotICAgICAgU3RyaW5nIHM7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBidWYuc2V0TGVuZ3RoKDApOwotCi0gICAgICAgIGludCBuID0gbV9wYXJ0cy5zaXplKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBBVlRQYXJ0IHBhcnQgPSAoQVZUUGFydCkgbV9wYXJ0cy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgICBidWYuYXBwZW5kKHBhcnQuZ2V0U2ltcGxlU3RyaW5nKCkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcyA9IGJ1Zi50b1N0cmluZygpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHM7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXR1cm4gIiI7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoZSBBVlQgYW5kIHJldHVybiBhIFN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRlIFhQYXRoQ29udGV4dCB0byB1c2UgdG8gZXZhbHVhdGUgdGhpcy4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGN1cnJlbnQgc291cmNlIHRyZWUgY29udGV4dC4KLSAgICogQHBhcmFtIG5zTm9kZSBUaGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCAoc3R5bGVzaGVldCB0cmVlIGNvbnRleHQpLgotICAgKiBAcGFyYW0gTm9kZUxpc3QgVGhlIGN1cnJlbnQgQ29udGV4dCBOb2RlIExpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIEFWVCBldmFsdWF0ZWQgYXMgYSBzdHJpbmcKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGV2YWx1YXRlKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQsIG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyIG5zTm9kZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fc2ltcGxlU3RyaW5nKQotICAgICAgewotICAgICAgICByZXR1cm4gbV9zaW1wbGVTdHJpbmc7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChudWxsICE9IG1fcGFydHMpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5zZXRMZW5ndGgoMCk7Ci0KLSAgICAgICAgaW50IG4gPSBtX3BhcnRzLnNpemUoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIEFWVFBhcnQgcGFydCA9IChBVlRQYXJ0KSBtX3BhcnRzLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgIHBhcnQuZXZhbHVhdGUoeGN0eHQsIGJ1ZiwgY29udGV4dCwgbnNOb2RlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuICIiOwotICAgICAgfQotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgU3RyaW5nQnVmZmVyUG9vbC5mcmVlKGJ1Zik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3Qgd2hldGhlciB0aGUgQVZUIGlzIGluc2Vuc2l0aXZlIHRvIHRoZSBjb250ZXh0IGluIHdoaWNoCi0gICAqICBpdCBpcyBiZWluZyBldmFsdWF0ZWQuIFRoaXMgaXMgaW50ZW5kZWQgdG8gZmFjaWxpdGF0ZQotICAgKiAgY29tcGlsYXRpb24gb2YgdGVtcGxhdGVzLCBieSBhbGxvd2luZyBzaW1wbGUgQVZUcyB0byBiZQotICAgKiAgY29udmVydGVkIGJhY2sgaW50byBzdHJpbmdzLgotICAgKgotICAgKiAgQ3VycmVudGx5IHRoZSBvbmx5IGNhc2Ugd2UgcmVjb2duaXplIGlzIHNpbXBsZSBzdHJpbmdzLgotICAgKiBBRERFRCA5LzUvMjAwMCB0byBzdXBwb3J0IGNvbXBpbGF0aW9uIGV4cGVyaW1lbnQKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBtX3NpbXBsZVN0cmluZyBtZW1iZXIgb2YgdGhpcyBBVlQgaXMgbm90IG51bGwKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQ29udGV4dEluc2Vuc2l0aXZlKCkKLSAgewotICAgIHJldHVybiBudWxsICE9IG1fc2ltcGxlU3RyaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3BhcnRzKQotICAgIHsKLSAgICAgIGludCBuID0gbV9wYXJ0cy5zaXplKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgewotICAgICAgICBBVlRQYXJ0IHBhcnQgPSAoQVZUUGFydCkgbV9wYXJ0cy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgaWYgKHBhcnQuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUgCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0IAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdCAKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUgCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbiAKLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZCAKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgaWYgKG51bGwgIT0gbV9wYXJ0cykKLSAgICB7Ci0gICAgICBpbnQgbiA9IG1fcGFydHMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgQVZUUGFydCBwYXJ0ID0gKEFWVFBhcnQpIG1fcGFydHMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgIHBhcnQuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgICAgfQotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0FWVFBhcnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9BVlRQYXJ0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRjM2ZjMjUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0FWVFBhcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIENsYXNzIHRvIGhvbGQgYSBwYXJ0LCBlaXRoZXIgYSBzdHJpbmcgb3IgWFBhdGgsCi0gKiBvZiBhbiBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGUuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBVlRQYXJ0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgcGFydC4KLSAgICovCi0gIHB1YmxpYyBBVlRQYXJ0KCl7fQotCi0gIC8qKgotICAgKiBHZXQgdGhlIEFWVCBwYXJ0IGFzIHRoZSBvcmlnaW5hbCBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIEFWVCBwYXJ0IGFzIHRoZSBvcmlnaW5hbCBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFNpbXBsZVN0cmluZygpOwotCi0gIC8qKgotICAgKiBXcml0ZSB0aGUgZXZhbHVhdGVkIHZhbHVlIGludG8gdGhlIGdpdmVuCi0gICAqIHN0cmluZyBidWZmZXIuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggY29udGV4dCB0byB1c2UgdG8gZXZhbHVhdGUgdGhpcyBBVlQuCi0gICAqIEBwYXJhbSBidWYgQnVmZmVyIHRvIHdyaXRlIGludG8uCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjdXJyZW50IHNvdXJjZSB0cmVlIGNvbnRleHQuCi0gICAqIEBwYXJhbSBuc05vZGUgVGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQgKHN0eWxlc2hlZXQgdHJlZSBjb250ZXh0KS4KLSAgICogQHBhcmFtIE5vZGVMaXN0IFRoZSBjdXJyZW50IENvbnRleHQgTm9kZSBMaXN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGV2YWx1YXRlKAotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgRmFzdFN0cmluZ0J1ZmZlciBidWYsIGludCBjb250ZXh0LAotICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXIgbnNOb2RlKQotICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogU2V0IHRoZSBYUGF0aCBzdXBwb3J0LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBYUGF0aENvbnRleHQgdG8gc2V0LiAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFhQYXRoU3VwcG9ydChYUGF0aENvbnRleHQgc3VwcG9ydCl7fQotICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUgCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICAgewotICAgIHJldHVybiBmYWxzZTsKLSAgIH0KLSAgIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZSAKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QgCi0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0IAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZSAKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uIAotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkIAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpOwotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9BVlRQYXJ0U2ltcGxlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvQVZUUGFydFNpbXBsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYTFmYzdkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9BVlRQYXJ0U2ltcGxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogU2ltcGxlIHN0cmluZyBwYXJ0IG9mIGEgY29tcGxleCBBVlQuCi0gKi8KLXB1YmxpYyBjbGFzcyBBVlRQYXJ0U2ltcGxlIGV4dGVuZHMgQVZUUGFydAotewotCi0gIC8qKgotICAgKiBTaW1wbGUgc3RyaW5nIHZhbHVlOwotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX3ZhbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgc2ltcGxlIEFWVCBwYXJ0LgotICAgKiBAcGFyYW0gdmFsIEEgcHVyZSBzdHJpbmcgc2VjdGlvbiBvZiBhbiBBVlQuCi0gICAqLwotICBwdWJsaWMgQVZUUGFydFNpbXBsZShTdHJpbmcgdmFsKQotICB7Ci0gICAgbV92YWwgPSB2YWw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBBVlQgcGFydCBhcyB0aGUgb3JpZ2luYWwgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBBVlQgcGFydCBhcyB0aGUgb3JpZ2luYWwgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTaW1wbGVTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsOwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZSAKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QgCi0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0IAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZSAKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uIAotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkIAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICAvLyBuby1vcAotICB9Ci0KLQotICAvKioKLSAgICogV3JpdGUgdGhlIHZhbHVlIGludG8gdGhlIGJ1ZmZlci4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IEFuIFhQYXRoQ29udGV4dCBvYmplY3QsIHByb3ZpZGluZyBpbmZvbWF0aW9uIHNwZWNpZmljCi0gICAqIHRvIHRoaXMgaW52b2NhdGlvbiBhbmQgdGhpcyB0aHJlYWQuIE1haW50YWlucyBTQVggc3RhdGUsIHZhcmlhYmxlcywgCi0gICAqIGVycm9yIGhhbmRsZXIgYW5kICBzbyBvbiwgc28gdGhlIHRyYW5zZm9ybWF0aW9uL1hQYXRoIG9iamVjdCBpdHNlbGYKLSAgICogY2FuIGJlIHNpbXVsdGFuZW91c2x5IGludm9rZWQgZnJvbSBtdWx0aXBsZSB0aHJlYWRzLgotICAgKiBAcGFyYW0gYnVmIEJ1ZmZlciB0byB3cml0ZSBpbnRvLgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY3VycmVudCBzb3VyY2UgdHJlZSBjb250ZXh0LgotICAgKiBAcGFyYW0gbnNOb2RlIFRoZSBjdXJyZW50IG5hbWVzcGFjZSBjb250ZXh0IChzdHlsZXNoZWV0IHRyZWUgY29udGV4dCkuCi0gICAqIEBwYXJhbSBOb2RlTGlzdCBUaGUgY3VycmVudCBDb250ZXh0IE5vZGUgTGlzdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV2YWx1YXRlKFhQYXRoQ29udGV4dCB4Y3R4dCwgRmFzdFN0cmluZ0J1ZmZlciBidWYsCi0gICAgICAgICAgICAgICAgICAgICAgIGludCBjb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlciBuc05vZGUpCi0gIHsKLSAgICBidWYuYXBwZW5kKG1fdmFsKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0FWVFBhcnRYUGF0aC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0FWVFBhcnRYUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZjZlMzhiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9BVlRQYXJ0WFBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLlhQYXRoUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXI7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFNpbXBsZSBzdHJpbmcgcGFydCBvZiBhIGNvbXBsZXggQVZULgotICovCi1wdWJsaWMgY2xhc3MgQVZUUGFydFhQYXRoIGV4dGVuZHMgQVZUUGFydAotewotCi0gIC8qKgotICAgKiBUaGUgWFBhdGggb2JqZWN0IGNvbnRhaW5lZCBpbiB0aGlzIHBhcnQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgWFBhdGggbV94cGF0aDsKLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIG1feHBhdGguZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZSAKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gICB7Ci0gICAgcmV0dXJuIG1feHBhdGguZ2V0RXhwcmVzc2lvbigpLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKTsKLSAgIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgc2ltcGxlIEFWVCBwYXJ0LgotICAgKgotICAgKiBAcGFyYW0geHBhdGggWHBhdGggc2VjdGlvbiBvZiBBVlQgCi0gICAqLwotICBwdWJsaWMgQVZUUGFydFhQYXRoKFhQYXRoIHhwYXRoKQotICB7Ci0gICAgbV94cGF0aCA9IHhwYXRoOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIHNpbXBsZSBBVlQgcGFydC4KLSAgICogCi0gICAqIEBwYXJhbSB2YWwgQSBwdXJlIHN0cmluZyBzZWN0aW9uIG9mIGFuIEFWVC4KLSAgICogQHBhcmFtIG5zTm9kZSBBbiBvYmplY3Qgd2hpY2ggY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZQotICAgKiBOYW1lc3BhY2UgTmFtZSAoVVJJKSBmb3IgYW55IE5hbWVzcGFjZSBwcmVmaXggdXNlZCBpbiB0aGUgWFBhdGguIAotICAgKiBVc3VhbGx5IHRoaXMgaXMgYmFzZWQgb24gdGhlIGNvbnRleHQgd2hlcmUgdGhlIFhQYXRoIHdhcyBzcGVjaWZpZWQsCi0gICAqIHN1Y2ggYXMgYSBub2RlIHdpdGhpbiBhIFN0eWxlc2hlZXQuCi0gICAqIEBwYXJhbSB4cGF0aFByb2Nlc3NvciBYUGF0aCBwYXJzZXIKLSAgICogQHBhcmFtIGZhY3RvcnkgWFBhdGggZmFjdG9yeQotICAgKiBAcGFyYW0gbGlhaXNvbiBBbiBYUGF0aENvbnRleHQgb2JqZWN0LCBwcm92aWRpbmcgaW5mb21hdGlvbiBzcGVjaWZpYwotICAgKiB0byB0aGlzIGludm9jYXRpb24gYW5kIHRoaXMgdGhyZWFkLiBNYWludGFpbnMgU0FYIG91dHB1dCBzdGF0ZSwgCi0gICAqIHZhcmlhYmxlcywgZXJyb3IgaGFuZGxlciBhbmQgc28gb24sIHNvIHRoZSB0cmFuc2Zvcm1hdGlvbi9YUGF0aCAKLSAgICogb2JqZWN0IGl0c2VsZiBjYW4gYmUgc2ltdWx0YW5lb3VzbHkgaW52b2tlZCBmcm9tIG11bHRpcGxlIHRocmVhZHMuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKiBUT0RPOiBGaXggb3IgcmVtb3ZlIHRoaXMgdW51c2VkIGMndG9yLgotICAgKi8KLSAgcHVibGljIEFWVFBhcnRYUGF0aCgKLSAgICAgICAgICBTdHJpbmcgdmFsLCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlciBuc05vZGUsIAotICAgICAgICAgIFhQYXRoUGFyc2VyIHhwYXRoUHJvY2Vzc29yLCBYUGF0aEZhY3RvcnkgZmFjdG9yeSwgCi0gICAgICAgICAgWFBhdGhDb250ZXh0IGxpYWlzb24pCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgbV94cGF0aCA9IG5ldyBYUGF0aCh2YWwsIG51bGwsIG5zTm9kZSwgWFBhdGguU0VMRUNULCBsaWFpc29uLmdldEVycm9yTGlzdGVuZXIoKSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBBVlQgcGFydCBhcyB0aGUgb3JpZ2luYWwgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBBVlQgcGFydCBhcyB0aGUgb3JpZ2luYWwgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTaW1wbGVTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuICJ7IiArIG1feHBhdGguZ2V0UGF0dGVyblN0cmluZygpICsgIn0iOwotICB9Ci0KLSAgLyoqCi0gICAqIFdyaXRlIHRoZSB2YWx1ZSBpbnRvIHRoZSBidWZmZXIuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBBbiBYUGF0aENvbnRleHQgb2JqZWN0LCBwcm92aWRpbmcgaW5mb21hdGlvbiBzcGVjaWZpYwotICAgKiB0byB0aGlzIGludm9jYXRpb24gYW5kIHRoaXMgdGhyZWFkLiBNYWludGFpbnMgU0FYIHN0YXRlLCB2YXJpYWJsZXMsIAotICAgKiBlcnJvciBoYW5kbGVyIGFuZCAgc28gb24sIHNvIHRoZSB0cmFuc2Zvcm1hdGlvbi9YUGF0aCBvYmplY3QgaXRzZWxmCi0gICAqIGNhbiBiZSBzaW11bHRhbmVvdXNseSBpbnZva2VkIGZyb20gbXVsdGlwbGUgdGhyZWFkcy4KLSAgICogQHBhcmFtIGJ1ZiBCdWZmZXIgdG8gd3JpdGUgaW50by4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGN1cnJlbnQgc291cmNlIHRyZWUgY29udGV4dC4KLSAgICogQHBhcmFtIG5zTm9kZSBUaGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCAoc3R5bGVzaGVldCB0cmVlIGNvbnRleHQpLgotICAgKiBAcGFyYW0gTm9kZUxpc3QgVGhlIGN1cnJlbnQgQ29udGV4dCBOb2RlIExpc3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXZhbHVhdGUoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBGYXN0U3RyaW5nQnVmZmVyIGJ1ZiwgaW50IGNvbnRleHQsIG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyIG5zTm9kZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhPYmplY3QgeG9iaiA9IG1feHBhdGguZXhlY3V0ZSh4Y3R4dCwgY29udGV4dCwgbnNOb2RlKTsKLQotICAgIGlmIChudWxsICE9IHhvYmopCi0gICAgewotICAgICAgeG9iai5hcHBlbmRUb0ZzYihidWYpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0NvbnN0YW50cy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0NvbnN0YW50cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMTQ0ZmE3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9Db25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ2NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGU7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBQcmltYXJ5IGNvbnN0YW50cyB1c2VkIGluIHRoZSBUcmFuc2Zvcm1lckltcGwgY2xhc3Nlcy4KLSAqLwotcHVibGljIGNsYXNzIENvbnN0YW50cwotewotCi0gIC8qKiAKLSAgICogTW5lbW9uaWNzIGZvciBzdGFuZGFyZCBYTUwgTmFtZXNwYWNlIFVSSXMsIGFzIEphdmEgU3RyaW5nczoKLSAgICogPHVsPgotICAgKiA8bGk+U19YTUxOQU1FU1BBQ0VVUkkgKGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSkgaXMgdGhlCi0gICAqIFVSSSBwZXJtYW5hbnRseSBhc3NpZ25lZCB0byB0aGUgInhtbDoiIHByZWZpeC4gVGhpcyBpcyB1c2VkIGZvciBzb21lCi0gICAqIGZlYXR1cmVzIGJ1aWx0IGludG8gdGhlIFhNTCBzcGVjaWZpY2F0aW9uIGl0c2VsZiwgc3VjaCBhcyB4bWw6c3BhY2UgCi0gICAqIGFuZCB4bWw6bGFuZy4gSXQgd2FzIGRlZmluZWQgYnkgdGhlIFczQydzIFhNTCBOYW1lc3BhY2VzIHNwZWMuPC9saT4KLSAgICogPGxpPlNfWFNMTkFNRVNQQUNFVVJMIChodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0pIGlzIHRoZQotICAgKiBVUkkgd2hpY2ggaW5kaWNhdGVzIHRoYXQgYSBuYW1lIG1heSBiZSBhbiBYU0xUIGRpcmVjdGl2ZS4gSW4gbW9zdAotICAgKiBYU0xUIHN0eWxlc2hlZXRzLCB0aGlzIGlzIGJvdW5kIHRvIHRoZSAieHNsOiIgcHJlZml4LiBJdCdzIGRlZmluZWQKLSAgICogYnkgdGhlIFczQydzIFhTTFQgUmVjb21tZW5kYXRpb24uPC9saT4KLSAgICogPGxpPlNfT0xEWFNMTkFNRVNQQUNFVVJMIChodHRwOi8vd3d3LnczLm9yZy9YU0wvVHJhbnNmb3JtLzEuMCkgd2FzCi0gICAqIHVzZWQgaW4gZWFybHkgcHJvdG90eXBlcyBvZiBYU0xUIHByb2Nlc3NvcnMgZm9yIG11Y2ggdGhlIHNhbWUgcHVycG9zZQotICAgKiBhcyBTX1hTTE5BTUVTUEFDRVVSTC4gSXQgaXMgbm93IGNvbnNpZGVyZWQgb2Jzb2xldGUsIGFuZCB0aGUgdmVyc2lvbgotICAgKiBvZiBYU0xUIHdoaWNoIGl0IHNpZ25pZmllZCBpcyBub3QgZnVsbHkgY29tcGF0YWJsZSB3aXRoIHRoZSBmaW5hbAotICAgKiBYU0xUIFJlY29tbWVuZGF0aW9uLCBzbyB3aGF0IGl0IHJlYWxseSBzaWduaWZpZXMgaXMgYSBiYWRseSBvYnNvbGV0ZQotICAgKiBzdHlsZXNoZWV0LjwvbGk+Ci0gICAqIDwvdWw+ICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIAotCVNfWE1MTkFNRVNQQUNFVVJJID0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIsIAotCVNfWFNMTkFNRVNQQUNFVVJMID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIsIAotCVNfT0xEWFNMTkFNRVNQQUNFVVJMID0gImh0dHA6Ly93d3cudzMub3JnL1hTTC9UcmFuc2Zvcm0vMS4wIjsKLQotICAvKiogQXV0aG9yc2hpcCBtbmVtb25pY3MsIGFzIEphdmEgU3RyaW5ncy4gTm90IHN0YW5kYXJkaXplZCwgCi0gICAqIGFzIGZhciBhcyBJIGtub3cuCi0gICAqIDx1bD4KLSAgICogPGxpPlNfVkVORE9SIC0tIHRoZSBuYW1lIG9mIHRoZSBvcmdhbml6YXRpb24vaW5kaXZpZHVhbCB3aG8gcHVibGlzaGVkCi0gICAqIHRoaXMgWFNMVCBwcm9jZXNzb3IuIDwvbGk+Ci0gICAqIDxsaT5TX1ZFTkRPUlVSTCAtLSBVUkwgd2hlcmUgb25lIGNhbiBhdHRlbXB0IHRvIHJldHJpZXZlIG1vcmUKLSAgICogaW5mb3JtYXRpb24gYWJvdXQgdGhpcyBwdWJsaXNoZXIgYW5kIHByb2R1Y3QuPC9saT4KLSAgICogPC91bD4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIAotCVNfVkVORE9SID0gIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiwgCi0JU19WRU5ET1JVUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnIjsKLQotICAvKiogU19CVUlMVElOX0VYVEVOU0lPTlNfVVJMIGlzIGEgbW5lbW9uaWMgZm9yIHRoZSBYTUwgTmFtZXNwYWNlIAotICAgKihodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdCkgcHJlZGVmaW5lZCB0byBzaWduaWZ5IFhhbGFuJ3MKLSAgICogYnVpbHQtaW4gWFNMVCBFeHRlbnNpb25zLiBXaGVuIHVzZWQgaW4gc3R5bGVzaGVldHMsIHRoaXMgaXMgb2Z0ZW4gCi0gICAqIGJvdW5kIHRvIHRoZSAieGFsYW46IiBwcmVmaXguCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAKLSAgICBTX0JVSUxUSU5fRVhURU5TSU9OU19VUkwgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiOyAKLSAgCi0gIC8qKgotICAgKiBUaGUgbWluaW11bSB2ZXJzaW9uIG9mIFhTTFQgc3VwcG9ydGVkIGJ5IHRoaXMgcHJvY2Vzc29yLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgWFNMVFZFUlNVUFBPUlRFRCA9IDEuMDsKLQotICAvKioKLSAgICogSURzIGZvciBYU0wgZWxlbWVudCB0eXBlcy4gVGhlc2UgYXJlIGFzc29jaWF0ZWQKLSAgICogd2l0aCB0aGUgc3RyaW5nIGxpdGVyYWxzIGluIHRoZSBUcmFuc2Zvcm1lckltcGwgY2xhc3MuCi0gICAqIERvbid0IGNoYW5nZSB0aGUgbnVtYmVycy4gTk9URSBUSEFUIFRIRVNFIEFSRSBOT1QgSU4KLSAgICogQUxQSEFCRVRJQ0FMIE9SREVSIQotICAgKiAoSXQncyBhIHBpdHkgSmF2YSBkb2Vzbid0IGhhdmUgYSByZWFsIEVudW1lcmF0ZWQgTW5lbW9uaWMKLSAgICogZGF0YXR5cGUuLi4gb3IgYSBDLWxpa2UgcHJlcHJvY2Vzc29yIGluIGxpZXUgdGhlcmVvZiB3aGljaAotICAgKiBjb3VsZCBiZSB1c2VkIHRvIGdlbmVyYXRlIGFuZCBtYWludGFpbiBzeW5jaCBiZXR3ZWVuIHRoZXNlIGxpc3RzLikKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVMRU1OQU1FX1VOREVGSU5FRCA9IC0xLCBFTEVNTkFNRV9XSVRIUEFSQU0gPSAyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9BRERBVFRSSUJVVEUgPSA0LCBFTEVNTkFNRV9BTkNIT1IgPSAyMiwKLQotICAvLyAgRUxFTU5BTUVfQU5DSE9SX1BBVFRFUk4gPSAyMywKLSAgRUxFTU5BTUVfQVBQTFlfVEVNUExBVEVTID0gNTAsIEVMRU1OQU1FX1VTRSA9IDM0LCBFTEVNTkFNRV9DSElMRFJFTiA9IDYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DSE9PU0UgPSAzNywgRUxFTU5BTUVfQ09NTUVOVCA9IDU5LCAgLy8gbXkgb3duCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DT05TVFJVQ1QgPSA3LCAgLy8gbXkgb3duCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9DT05URU5UUyA9IDgsIEVMRU1OQU1FX0NPUFkgPSA5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfQ09QWV9PRiA9IDc0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfREVDSU1BTEZPUk1BVCA9IDgzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfREVGSU5FQVRUUklCVVRFU0VUID0gNDAsCi0KLSAgLy8gIEVMRU1OQU1FX0RFRklORUNPTlNUQU5UID0gMjksCi0gIC8vICBFTEVNTkFNRV9ERUZJTkVNQUNSTyA9IDEwLAotICBFTEVNTkFNRV9ERUZJTkVTQ1JJUFQgPSAxMSwgRUxFTU5BTUVfRElTUExBWUlGID0gMTIsICAvLyBteSBvd24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0VNUFRZID0gMTQsIEVMRU1OQU1FX0VWQUwgPSAxNSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0VYUEVDVEVEQ0hJTERSRU4gPSAxNiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0VYVEVOU0lPTiA9IDU0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfRVhURU5TSU9OSEFORExFUiA9IDYzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfRk9SRUFDSCA9IDI4LCBFTEVNTkFNRV9LRVkgPSAzMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0lGID0gMzYsIEVMRU1OQU1FX0lNUE9SVCA9IDI2LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfSU5DTFVERSA9IDI3LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfQ0FMTFRFTVBMQVRFID0gMTcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9QQVJBTVZBUklBQkxFID0gNDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9OVU1CRVIgPSAzNSwgRUxFTU5BTUVfTlNBTElBUyA9IDg0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfT1RIRVJXSVNFID0gMzksIEVMRU1OQU1FX1BJID0gNTgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9QUkVTRVJWRVNQQUNFID0gMzMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9SRU1PVkVBVFRSSUJVVEUgPSA1LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfVEVNUExBVEUgPSAxOSwgRUxFTU5BTUVfU09SVCA9IDY0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfU1RSSVBTUEFDRSA9IDMyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFTU5BTUVfU1RZTEVTSEVFVCA9IDI1LCBFTEVNTkFNRV9URVhUID0gNDIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9WQUxVRU9GID0gMzAsIEVMRU1OQU1FX1dIRU4gPSAzOCwKLQotICAvLyBQYXR0ZXJuIGJ5IGV4YW1wbGUgc3VwcG9ydCAgCi0gIEVMRU1OQU1FX1JPT1QgPSA0NCwgRUxFTU5BTUVfQU5ZID0gNDUsIEVMRU1OQU1FX0VMRU1FTlQgPSA0NiwKLSAgICAgICAgICAgICAgICAgICAgICBFTEVNTkFNRV9UQVJHRVRFTEVNRU5UID0gNDcsIEVMRU1OQU1FX0FUVFJJQlVURSA9IDQ4LAotICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX1RBUkdFVEFUVFJJQlVURSA9IDQ5LCBFTEVNTkFNRV9VUkwgPSA1MiwgIC8vIG15IG93bgotICAgICAgICAgICAgICAgICAgICAgIEVMRU1OQU1FX0NBTEwgPSA1NSwgIC8vIG15IG93bgotCi0gIC8vICBFTEVNTkFNRV9XSVRIUEFSQU0gPSA1NiwKLSAgRUxFTU5BTUVfRkFMTEJBQ0sgPSA1NywgIC8vIG15IG93bgotICBFTEVNTkFNRV9UQVJHRVRQSSA9IDYwLCAgLy8gbXkgb3duCi0gIEVMRU1OQU1FX1RBUkdFVENPTU1FTlQgPSA2MSwgIC8vIG15IG93bgotICBFTEVNTkFNRV9UQVJHRVRURVhUID0gNjIsICAvLyBteSBvd24KLSAgRUxFTU5BTUVfQ1NTU1RZTEVDT05WRVJTSU9OID0gNjUsICAvLyBteSBvd24KLSAgRUxFTU5BTUVfQ09VTlRFUiA9IDY2LCBFTEVNTkFNRV9DT1VOVEVSUyA9IDY3LAotICBFTEVNTkFNRV9DT1VOVEVSSU5DUkVNRU5UID0gNjgsIEVMRU1OQU1FX0NPVU5URVJSRVNFVCA9IDY5LAotICBFTEVNTkFNRV9DT1VOVEVSU0NPUEUgPSA3MSwgRUxFTU5BTUVfQVBQTFlfSU1QT1JUUyA9IDcyLAotICBFTEVNTkFNRV9WQVJJQUJMRSA9IDczLCBFTEVNTkFNRV9NRVNTQUdFID0gNzUsIEVMRU1OQU1FX0xPQ0FMRSA9IDc2LAotICBFTEVNTkFNRV9MSVRFUkFMUkVTVUxUID0gNzcsIEVMRU1OQU1FX1RFWFRMSVRFUkFMUkVTVUxUID0gNzgsCi0gIEVMRU1OQU1FX0VYVEVOU0lPTkNBTEwgPSA3OSwgRUxFTU5BTUVfRVhURU5TSU9OREVDTCA9IDg1LAotICBFTEVNTkFNRV9FWFRFTlNJT05TQ1JJUFQgPSA4NiwgRUxFTU5BTUVfT1VUUFVUID0gODAsCi0gIEVMRU1OQU1FX0NPTVBPTkVOVCA9IDgxLCBFTEVNTkFNRV9TQ1JJUFQgPSA4MjsKLQotICAvLyBOZXh0IGZyZWUgbnVtYmVyOiA4NwotCi0gIC8qKgotICAgKiBMaXRlcmFscyBmb3IgWFNMIGVsZW1lbnQgbmFtZXMuICBOb3RlIHRoYXQgdGhlcmUgYXJlIG1vcmUKLSAgICogbmFtZXMgdGhhbiBJRHMsIGJlY2F1c2Ugc29tZSBuYW1lcyBtYXAgdG8gdGhlIHNhbWUgSUQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyAgICAgICAKLQkgIEVMRU1OQU1FX0FOQ0hPUl9TVFJJTkcgPSAiYW5jaG9yIiwKLSAgICAgIEVMRU1OQU1FX0FOWV9TVFJJTkcgPSAiYW55IiwgIC8vIHBhdHRlcm4tYnktZXhhbXBsZSBzdXBwb3J0Ci0gICAgICBFTEVNTkFNRV9BUFBMWV9JTVBPUlRTX1NUUklORyA9ICJhcHBseS1pbXBvcnRzIiwKLSAgICAgIEVMRU1OQU1FX0FQUExZX1RFTVBMQVRFU19TVFJJTkcgPSAiYXBwbHktdGVtcGxhdGVzIiwKLSAgICAgIEVMRU1OQU1FX0FSR19TVFJJTkcgPSAiYXJnIiwKLSAgICAgIEVMRU1OQU1FX0FUVFJJQlVURVNFVF9TVFJJTkcgPSAiYXR0cmlidXRlLXNldCIsCi0gICAgICBFTEVNTkFNRV9BVFRSSUJVVEVfU1RSSU5HID0gImF0dHJpYnV0ZSIsICAvLyBwYXR0ZXJuLWJ5LWV4YW1wbGUgc3VwcG9ydAotICAgICAgRUxFTU5BTUVfQ0FMTFRFTVBMQVRFQVJHX1NUUklORyA9ICJpbnZva2UtYXJnIiwKLSAgICAgIEVMRU1OQU1FX0NBTExURU1QTEFURV9TVFJJTkcgPSAiY2FsbC10ZW1wbGF0ZSIsCi0gICAgICBFTEVNTkFNRV9DQUxMX1NUUklORyA9ICJjYWxsIiwKLSAgICAgIEVMRU1OQU1FX0NISUxEUkVOX1NUUklORyA9ICJjaGlsZHJlbiIsCi0gICAgICBFTEVNTkFNRV9DSE9PU0VfU1RSSU5HID0gImNob29zZSIsCi0gICAgICBFTEVNTkFNRV9DT01NRU5UX1NUUklORyA9ICJjb21tZW50IiwKLSAgICAgIEVMRU1OQU1FX0NPTVBPTkVOVF9TVFJJTkcgPSAiY29tcG9uZW50IiwKLSAgICAgIEVMRU1OQU1FX0NPTlNUUlVDVF9TVFJJTkcgPSAiY29uc3RydWN0IiwgIC8vIG15IG93bgotICAgICAgRUxFTU5BTUVfQ09OVEVOVFNfU1RSSU5HID0gImNvbnRlbnRzIiwgCi0gICAgICBFTEVNTkFNRV9DT1BZX09GX1NUUklORyA9ImNvcHktb2YiLAotICAgICAgRUxFTU5BTUVfQ09QWV9TVFJJTkcgPSAiY29weSIsCi0gICAgICBFTEVNTkFNRV9DT1VOVEVSSU5DUkVNRU5UX1NUUklORyA9ICJjb3VudGVyLWluY3JlbWVudCIsCi0gICAgICBFTEVNTkFNRV9DT1VOVEVSUkVTRVRfU1RSSU5HID0gImNvdW50ZXItcmVzZXQiLAotICAgICAgRUxFTU5BTUVfQ09VTlRFUlNDT1BFX1NUUklORyA9ICJjb3VudGVyLXNjb3BlIiwKLSAgICAgIEVMRU1OQU1FX0NPVU5URVJTX1NUUklORyA9ICJjb3VudGVycyIsCi0gICAgICBFTEVNTkFNRV9DT1VOVEVSX1NUUklORyA9ICJjb3VudGVyIiwKLSAgICAgIEVMRU1OQU1FX0NTU1NUWUxFQ09OVkVSU0lPTl9TVFJJTkcgPSAiY3NzLXN0eWxlLWNvbnZlcnNpb24iLAotICAgICAgRUxFTU5BTUVfREVDSU1BTEZPUk1BVF9TVFJJTkcgPSAiZGVjaW1hbC1mb3JtYXQiLAotICAgICAgRUxFTU5BTUVfRElTUExBWUlGX1NUUklORyA9ICJkaXNwbGF5LWlmIiwgIC8vIG15IG93bgotICAgICAgRUxFTU5BTUVfRUxFTUVOVF9TVFJJTkcgPSAiZWxlbWVudCIsICAvLyBwYXR0ZXJuLWJ5LWV4YW1wbGUgc3VwcG9ydAotICAgICAgRUxFTU5BTUVfRU1QVFlfU1RSSU5HID0gImVtcHR5IiwKLSAgICAgIEVMRU1OQU1FX0VWQUxfU1RSSU5HID0gImV2YWwiLAotICAgICAgRUxFTU5BTUVfRVhQRUNURURDSElMRFJFTl9TVFJJTkcgPSAiZXhwZWN0ZWRjaGlsZHJlbiIsCi0gICAgICBFTEVNTkFNRV9FWFRFTlNJT05IQU5ETEVSX1NUUklORyA9ICJjb2RlLWRpc3BhdGNoZXIiLAotICAgICAgRUxFTU5BTUVfRVhURU5TSU9OX1NUUklORyA9ICJmdW5jdGlvbnMiLAotICAgICAgRUxFTU5BTUVfRkFMTEJBQ0tfU1RSSU5HID0gImZhbGxiYWNrIiwKLSAgICAgIEVMRU1OQU1FX0ZPUkVBQ0hfU1RSSU5HID0gImZvci1lYWNoIiwKLSAgICAgIEVMRU1OQU1FX0lGX1NUUklORyA9ICJpZiIsCi0gICAgICBFTEVNTkFNRV9JTVBPUlRfU1RSSU5HID0gImltcG9ydCIsCi0gICAgICBFTEVNTkFNRV9JTkNMVURFX1NUUklORyA9ICJpbmNsdWRlIiwKLSAgICAgIEVMRU1OQU1FX0tFWV9TVFJJTkcgPSAia2V5IiwKLSAgICAgIEVMRU1OQU1FX0xPQ0FMRV9TVFJJTkcgPSAibG9jYWxlIiwKLSAgICAgIEVMRU1OQU1FX01FU1NBR0VfU1RSSU5HID0gIm1lc3NhZ2UiLAotICAgICAgRUxFTU5BTUVfTlNBTElBU19TVFJJTkcgPSAibmFtZXNwYWNlLWFsaWFzIiwKLSAgICAgIEVMRU1OQU1FX05VTUJFUl9TVFJJTkcgPSAibnVtYmVyIiwKLSAgICAgIEVMRU1OQU1FX09USEVSV0lTRV9TVFJJTkcgPSAib3RoZXJ3aXNlIiwKLSAgICAgIEVMRU1OQU1FX09VVFBVVF9TVFJJTkcgPSAib3V0cHV0IiwKLSAgICAgIEVMRU1OQU1FX1BBUkFNVkFSSUFCTEVfU1RSSU5HID0gInBhcmFtIiwKLSAgICAgIEVMRU1OQU1FX1BJX09MRF9TVFJJTkcgPSAicGkiLAotICAgICAgRUxFTU5BTUVfUElfU1RSSU5HID0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iLAotICAgICAgRUxFTU5BTUVfUFJFU0VSVkVTUEFDRV9TVFJJTkcgPSAicHJlc2VydmUtc3BhY2UiLAotICAgICAgRUxFTU5BTUVfUk9PVF9TVFJJTkcgPSAicm9vdCIsICAvLyBwYXR0ZXJuLWJ5LWV4YW1wbGUgc3VwcG9ydAotICAgICAgRUxFTU5BTUVfU0NSSVBUX1NUUklORyA9ICJzY3JpcHQiLAotICAgICAgRUxFTU5BTUVfU09SVF9TVFJJTkcgPSAic29ydCIsCi0gICAgICBFTEVNTkFNRV9TVFJJUFNQQUNFX1NUUklORyA9ICJzdHJpcC1zcGFjZSIsCi0gICAgICBFTEVNTkFNRV9TVFlMRVNIRUVUX1NUUklORyA9ICJzdHlsZXNoZWV0IiwKLSAgICAgIEVMRU1OQU1FX1RBUkdFVEFUVFJJQlVURV9TVFJJTkcgPSAidGFyZ2V0LWF0dHJpYnV0ZSIsICAvLyBwYXR0ZXJuLWJ5LWV4YW1wbGUgc3VwcG9ydAotICAgICAgRUxFTU5BTUVfVEFSR0VUQ09NTUVOVF9TVFJJTkcgPSAidGFyZ2V0LWNvbW1lbnQiLAotICAgICAgRUxFTU5BTUVfVEFSR0VURUxFTUVOVF9TVFJJTkcgPSAidGFyZ2V0LWVsZW1lbnQiLCAgLy8gcGF0dGVybi1ieS1leGFtcGxlIHN1cHBvcnQKLSAgICAgIEVMRU1OQU1FX1RBUkdFVFBJX1NUUklORyA9ICJ0YXJnZXQtcGkiLAotICAgICAgRUxFTU5BTUVfVEFSR0VUVEVYVF9TVFJJTkcgPSAidGFyZ2V0LXRleHQiLAotICAgICAgRUxFTU5BTUVfVEVNUExBVEVfU1RSSU5HID0gInRlbXBsYXRlIiwKLSAgICAgIEVMRU1OQU1FX1RFWFRfU1RSSU5HID0gInRleHQiLAotICAgICAgRUxFTU5BTUVfVFJBTlNGT1JNX1NUUklORyA9ICJ0cmFuc2Zvcm0iLAotICAgICAgRUxFTU5BTUVfVVJMX1NUUklORyA9ICJ1cmkiLCAgLy8gcGF0dGVybi1ieS1leGFtcGxlIHN1cHBvcnQKLSAgICAgIEVMRU1OQU1FX1VTRV9TVFJJTkcgPSAidXNlIiwKLSAgICAgIEVMRU1OQU1FX1ZBTFVFT0ZfU1RSSU5HID0gInZhbHVlLW9mIiwKLSAgICAgIEVMRU1OQU1FX1ZBUklBQkxFX1NUUklORyA9ICJ2YXJpYWJsZSIsCi0gICAgICBFTEVNTkFNRV9XSEVOX1NUUklORyA9ICJ3aGVuIiwKLSAgICAgIEVMRU1OQU1FX1dJVEhQQVJBTV9TVFJJTkcgPSAid2l0aC1wYXJhbSI7Ci0gIAotICAvKioKLSAgICogTGl0ZXJhbHMgZm9yIFhTTCBhdHRyaWJ1dGUgbmFtZXMuICBOb3RlIHRoYXQgdGhlcmUgbWF5IGJlIG1vcmUKLSAgICogbmFtZXMgdGhhbiBJRHMsIGJlY2F1c2Ugc29tZSBuYW1lcyBtYXkgbWFwIHRvIHRoZSBzYW1lIElELgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcKLQkgIEFUVFJOQU1FX0FNT1VOVCA9ICJhbW91bnQiLAotICAgICAgQVRUUk5BTUVfQU5DRVNUT1IgPSAiYW5jZXN0b3IiLAotICAgICAgQVRUUk5BTUVfQVJDSElWRSA9ICJhcmNoaXZlIiwKLSAgICAgIEFUVFJOQU1FX0FUVFJJQlVURSA9ICJhdHRyaWJ1dGUiLAotICAgICAgQVRUUk5BTUVfQVRUUklCVVRFX1NFVCA9ICJhdHRyaWJ1dGUtc2V0IiwKLSAgICAgIEFUVFJOQU1FX0NBU0VPUkRFUiA9ICJjYXNlLW9yZGVyIiwKLSAgICAgIEFUVFJOQU1FX0NMQVNTID0gImNsYXNzIiwKLSAgICAgIEFUVFJOQU1FX0NMQVNTSUQgPSAiY2xhc3NpZCIsCi0gICAgICBBVFRSTkFNRV9DT0RFQkFTRSA9ICJjb2RlYmFzZSIsCi0gICAgICBBVFRSTkFNRV9DT0RFVFlQRSA9ICJ0eXBlIiwKLSAgICAgIEFUVFJOQU1FX0NPTkRJVElPTiA9ICJjb25kaXRpb24iLAotICAgICAgQVRUUk5BTUVfQ09QWVRZUEUgPSAiY29weS10eXBlIiwKLSAgICAgIEFUVFJOQU1FX0NPVU5UID0gImNvdW50IiwKLSAgICAgIEFUVFJOQU1FX0RBVEFUWVBFID0gImRhdGEtdHlwZSIsCi0gICAgICBBVFRSTkFNRV9ERUNJTUFMU0VQQVJBVE9SID0gImRlY2ltYWwtc2VwYXJhdG9yIiwKLSAgICAgIEFUVFJOQU1FX0RFRkFVTFQgPSAiZGVmYXVsdCIsCi0gICAgICBBVFRSTkFNRV9ERUZBVUxUU1BBQ0UgPSAiZGVmYXVsdC1zcGFjZSIsCi0gICAgICBBVFRSTkFNRV9ERVBUSCA9ICJ3aXRoLWNoaWxkcmVuIiwKLSAgICAgIEFUVFJOQU1FX0RJR0lUID0gImRpZ2l0IiwKLSAgICAgIEFUVFJOQU1FX0RJR0lUR1JPVVBTRVAgPSAiZGlnaXQtZ3JvdXAtc2VwIiwKLSAgICAgIEFUVFJOQU1FX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HID0gImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiwKLSAgICAgIEFUVFJOQU1FX0VMRU1FTlQgPSAiZWxlbWVudCIsCi0gICAgICBBVFRSTkFNRV9FTEVNRU5UUyA9ICJlbGVtZW50cyIsCi0gICAgICBBVFRSTkFNRV9FWENMVURFX1JFU1VMVF9QUkVGSVhFUyA9ImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiwKLSAgICAgIEFUVFJOQU1FX0VYUFIgPSAiZXhwciIsCi0gICAgICBBVFRSTkFNRV9FWFRFTlNJT05FTEVNRU5UUFJFRklYRVMgPSAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiLAotICAgICAgQVRUUk5BTUVfRk9STUFUID0gImZvcm1hdCIsCi0gICAgICBBVFRSTkFNRV9GUk9NID0gImZyb20iLAotICAgICAgQVRUUk5BTUVfR1JPVVBJTkdTRVBBUkFUT1IgPSAiZ3JvdXBpbmctc2VwYXJhdG9yIiwKLSAgICAgIEFUVFJOQU1FX0dST1VQSU5HU0laRSA9ICJncm91cGluZy1zaXplIiwKLSAgICAgIEFUVFJOQU1FX0hSRUYgPSAiaHJlZiIsCi0gICAgICBBVFRSTkFNRV9JRCA9ICJpZCIsCi0gICAgICBBVFRSTkFNRV9JTVBPUlRBTkNFID0gImltcG9ydGFuY2UiLAotICAgICAgQVRUUk5BTUVfSU5ERU5UUkVTVUxUID0gImluZGVudC1yZXN1bHQiLAotICAgICAgQVRUUk5BTUVfSU5GSU5JVFkgPSAiaW5maW5pdHkiLAotICAgICAgQVRUUk5BTUVfTEFORyA9ICJsYW5nIiwKLSAgICAgIEFUVFJOQU1FX0xFVFRFUlZBTFVFID0gImxldHRlci12YWx1ZSIsCi0gICAgICBBVFRSTkFNRV9MRVZFTCA9ICJsZXZlbCIsCi0gICAgICBBVFRSTkFNRV9NQVRDSCA9ICJtYXRjaCIsCi0gICAgICBBVFRSTkFNRV9NRVRIT0QgPSAiY2FsbHMiLAotICAgICAgQVRUUk5BTUVfTUlOVVNTSUdOID0gIm1pbnVzLXNpZ24iLAotICAgICAgQVRUUk5BTUVfTU9ERSA9ICJtb2RlIiwKLSAgICAgIEFUVFJOQU1FX05BTUUgPSAibmFtZSIsCi0gICAgICBBVFRSTkFNRV9OQU1FU1BBQ0UgPSAibmFtZXNwYWNlIiwKLSAgICAgIEFUVFJOQU1FX05BTiA9ICJOYU4iLAotICAgICAgQVRUUk5BTUVfTkRJR0lUU1BFUkdST1VQID0gIm4tZGlnaXRzLXBlci1ncm91cCIsCi0gICAgICBBVFRSTkFNRV9OUyA9ICJucyIsCi0gICAgICBBVFRSTkFNRV9PTkxZID0gIm9ubHkiLAotICAgICAgQVRUUk5BTUVfT1JERVIgPSAib3JkZXIiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX0NEQVRBX1NFQ1RJT05fRUxFTUVOVFMgPSAiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfRE9DVFlQRV9QVUJMSUMgPSAiZG9jdHlwZS1wdWJsaWMiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX0RPQ1RZUEVfU1lTVEVNID0gImRvY3R5cGUtc3lzdGVtIiwKLSAgICAgIEFUVFJOQU1FX09VVFBVVF9FTkNPRElORyA9ICJlbmNvZGluZyIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfSU5ERU5UID0gImluZGVudCIsCi0gICAgICBBVFRSTkFNRV9PVVRQVVRfTUVESUFUWVBFID0gIm1lZGlhLXR5cGUiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX01FVEhPRCA9ICJtZXRob2QiLCAgLy8gcW5hbWUsIAotICAgICAgQVRUUk5BTUVfT1VUUFVUX09NSVRYTUxERUNMID0gIm9taXQteG1sLWRlY2xhcmF0aW9uIiwKLSAgICAgIEFUVFJOQU1FX09VVFBVVF9TVEFOREFMT05FID0gInN0YW5kYWxvbmUiLAotICAgICAgQVRUUk5BTUVfT1VUUFVUX1ZFUlNJT04gPSAidmVyc2lvbiIsCi0gICAgICBBVFRSTkFNRV9QQVRURVJOU0VQQVJBVE9SID0gInBhdHRlcm4tc2VwYXJhdG9yIiwKLSAgICAgIEFUVFJOQU1FX1BFUkNFTlQgPSAicGVyY2VudCIsCi0gICAgICBBVFRSTkFNRV9QRVJNSUxMRSA9ICJwZXItbWlsbGUiLAotICAgICAgQVRUUk5BTUVfUFJJT1JJVFkgPSAicHJpb3JpdHkiLAotICAgICAgQVRUUk5BTUVfUkVGSUQgPSAicmVmSUQiLAotICAgICAgQVRUUk5BTUVfUkVTVUxUTlMgPSAicmVzdWx0LW5zIiwKLSAgICAgIEFUVFJOQU1FX1JFU1VMVF9QUkVGSVggPSAicmVzdWx0LXByZWZpeCIsCi0gICAgICBBVFRSTkFNRV9TRUxFQ1QgPSAic2VsZWN0IiwKLSAgICAgIEFUVFJOQU1FX1NFUVVFTkNFU1JDID0gInNlcXVlbmNlLXNyYyIsCi0gICAgICBBVFRSTkFNRV9TVFlMRSA9ICJzdHlsZSIsCi0gICAgICBBVFRSTkFNRV9TVFlMRVNIRUVUX1BSRUZJWCA9ICJzdHlsZXNoZWV0LXByZWZpeCIsCi0gICAgICBBVFRSTkFNRV9URVJNSU5BVEUgPSAidGVybWluYXRlIiwKLSAgICAgIEFUVFJOQU1FX1RFU1QgPSAidGVzdCIsCi0gICAgICBBVFRSTkFNRV9UT1NUUklORyA9ICJ0by1zdHJpbmciLAotICAgICAgQVRUUk5BTUVfVFlQRSA9ICJ0eXBlIiwKLSAgICAgIEFUVFJOQU1FX1VTRSA9ICJ1c2UiLAotICAgICAgQVRUUk5BTUVfVVNFQVRUUklCVVRFU0VUUyA9ICJ1c2UtYXR0cmlidXRlLXNldHMiLAotICAgICAgQVRUUk5BTUVfVkFMVUUgPSAidmFsdWUiLAotICAgICAgQVRUUk5BTUVfVkVSU0lPTiA9ICJ2ZXJzaW9uIiwKLSAgICAgIEFUVFJOQU1FX1hNTE5TID0gInhtbG5zOiIsIC8vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBwcmVmaXggLS0gTk9UIGFuIGF0dHJpYnV0ZSBieSBpdHNlbGYKLSAgICAgIEFUVFJOQU1FX1hNTE5TREVGID0gInhtbG5zIiwgLy8gZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgIEFUVFJOQU1FX1hNTFNQQUNFID0gInhtbDpzcGFjZSIsIAotICAgICAgQVRUUk5BTUVfWkVST0RJR0lUID0gInplcm8tZGlnaXQiOwotCi0gIC8qKiBJRHMgZm9yIFhTTCBhdHRyaWJ1dGUgdHlwZXMuIFRoZXNlIGFyZSBhc3NvY2lhdGVkCi0gICAqIHdpdGggdGhlIHN0cmluZyBsaXRlcmFscyBpbiB0aGUgVHJhbnNmb3JtZXJJbXBsIGNsYXNzLgotICAgKiBEb24ndCBjaGFuZ2UgdGhlIG51bWJlcnMuIE5PVEUgVEhBVCBUSEVTRSBBUkUgTk9UIElOCi0gICAqIEFMUEhBQkVUSUNBTCBPUkRFUiEKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBVFRSTkFNRV9PVVRQVVRfTUVUSE9EID0gMSwgVEFUVFJOQU1FX0FNT1VOVCA9IDIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9BTkNFU1RPUiA9IDMsIFRBVFRSTkFNRV9BUkNISVZFID0gNCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0FUVFJJQlVURSA9IDUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9BVFRSSUJVVEVfU0VUID0gNiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0NBU0VPUkRFUiA9IDcsIFRBVFRSTkFNRV9DTEFTUyA9IDgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9DTEFTU0lEID0gOSwgVEFUVFJOQU1FX0NPREVCQVNFID0gMTAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9DT0RFVFlQRSA9IDExLCBUQVRUUk5BTUVfQ09ORElUSU9OID0gMTIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9DT1BZVFlQRSA9IDEzLCBUQVRUUk5BTUVfQ09VTlQgPSAxNCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0RBVEFUWVBFID0gMTUsIFRBVFRSTkFNRV9ERUZBVUxUID0gMTYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9ERUZBVUxUU1BBQ0UgPSAxNywgVEFUVFJOQU1FX0RFUFRIID0gMTgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9ESUdJVEdST1VQU0VQID0gMTksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9ESVNBQkxFX09VVFBVVF9FU0NBUElORyA9IDIwLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfRUxFTUVOVCA9IDIxLCBUQVRUUk5BTUVfRUxFTUVOVFMgPSAyMiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0VYUFIgPSAyMywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX0VYVEVOU0lPTkVMRU1FTlRQUkVGSVhFUyA9IDI0LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfRk9STUFUID0gMjUsIFRBVFRSTkFNRV9GUk9NID0gMjYsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9HUk9VUElOR1NFUEFSQVRPUiA9IDI3LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfR1JPVVBJTkdTSVpFID0gMjgsIFRBVFRSTkFNRV9IUkVGID0gMjksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9JRCA9IDMwLCBUQVRUUk5BTUVfSU1QT1JUQU5DRSA9IDMxLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfSU5ERU5UUkVTVUxUID0gMzIsIFRBVFRSTkFNRV9MQU5HID0gMzMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9MRVRURVJWQUxVRSA9IDM0LCBUQVRUUk5BTUVfTEVWRUwgPSAzNSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX01BVENIID0gMzYsIFRBVFRSTkFNRV9NRVRIT0QgPSAzNywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX01PREUgPSAzOCwgVEFUVFJOQU1FX05BTUUgPSAzOSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX05BTUVTUEFDRSA9IDQwLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfTkRJR0lUU1BFUkdST1VQID0gNDEsIFRBVFRSTkFNRV9OUyA9IDQyLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT05MWSA9IDQzLCBUQVRUUk5BTUVfT1JERVIgPSA0NCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX09VVFBVVF9DREFUQV9TRUNUSU9OX0VMRU1FTlRTID0gNDUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfRE9DVFlQRV9QVUJMSUMgPSA0NiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX09VVFBVVF9ET0NUWVBFX1NZU1RFTSA9IDQ3LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT1VUUFVUX0VOQ09ESU5HID0gNDgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfSU5ERU5UID0gNDksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfTUVESUFUWVBFID0gNTAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9PVVRQVVRfU1RBTkRBTE9ORSA9IDUxLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfT1VUUFVUX1ZFUlNJT04gPSA1MiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX09VVFBVVF9PTUlUWE1MREVDTCA9IDUzLAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfUFJJT1JJVFkgPSA1NCwgVEFUVFJOQU1FX1JFRklEID0gNTUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9SRVNVTFROUyA9IDU2LCBUQVRUUk5BTUVfU0VMRUNUID0gNTcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9TRVFVRU5DRVNSQyA9IDU4LCBUQVRUUk5BTUVfU1RZTEUgPSA1OSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX1RFU1QgPSA2MCwgVEFUVFJOQU1FX1RPU1RSSU5HID0gNjEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9UWVBFID0gNjIsIFRBVFRSTkFNRV9VU0UgPSA2MywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX1VTRUFUVFJJQlVURVNFVFMgPSA2NCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgVEFUVFJOQU1FX1ZBTFVFID0gNjUsIFRBVFRSTkFNRV9YTUxOU0RFRiA9IDY2LAotICAgICAgICAgICAgICAgICAgICAgICAgICBUQVRUUk5BTUVfWE1MTlMgPSA2NywgVEFUVFJOQU1FX1hNTFNQQUNFID0gNjgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRBVFRSTkFNRV9FWENMVURFX1JFU1VMVF9QUkVGSVhFUyA9IDY5OwotCi0gIC8qKiBNbmVtb25pY3MgZm9yIHRoZSBwb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIHhzbDpvdXRwdXQgZWxlbWVudCdzCi0gICAqIG1ldGhvZD0gYXR0cmlidXRlOgotICAgKiA8dWw+Ci0gICAqIDxsaT5BVFRSVkFMX09VVFBVVF9NRVRIT0RfWE1MID0gVXNlIGFuIFhNTCBmb3JtYXR0ZXIgdG8KLSAgICogcHJvZHVjZSB0aGUgb3V0cHV0IGRvY3VtZW50IChiYXNpYyBYU0xUIG9wZXJhdGlvbikuPC9saT4KLSAgICogPGxpPkFUVFJWQUxfT1VUUFVUX01FVEhPRF9IVE1MOiBVc2UgYW4gSFRNTCBmb3JtYXR0ZXIgdG8KLSAgICogcHJvZHVjZSB0aGUgb3V0cHV0IGRvY3VtZW50LiBXaGVuIGdlbmVyYXRpbmcgSFRNTCBkb2N1bWVudHMsCi0gICAqIHRoaXMgbWF5IHlpZWxkIGJldHRlciByZXN1bHRzOyBpdCBkb2VzIHRoaW5ncyBsaWtlIGVzY2FwaW5nCi0gICAqIGNoYXJhY3RlcnMgaW4gaHJlZiBhdHRyaWJ1dGVzLjwvbGk+Ci0gICAqIDwvbGk+QVRUUlZBTF9PVVRQVVRfTUVUSE9EX1RFWFQ6ICBVc2UgYSBUZXh0IGZvcm1hdHRlciB0bwotICAgKiBwcm9kdWNlIHRoZSBvdXRwdXQgZG9jdW1lbnQuIEdlbmVyYWxseSB0aGUgcmlnaHQgY2hvaWNlIGlmIHlvdXIKLSAgICogc3R5bGVzaGVldCB3YW50cyB0byB0YWtlIG92ZXIgX2FsbF8gdGhlIGRldGFpbHMgb2YgZm9ybWF0dGluZywKLSAgICogbW9zdCBvZnRlbiB3aGVuIHByb2R1Y2luZyBzb21ldGhpbmcgdGhhdCBpc24ndCBhbiBYTUwgb3IgSFRNTAotICAgKiBkb2N1bWVudC48L2xpPgotICAgKiA8L3VsPiAKLSAgICogKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUlZBTF9PVVRQVVRfTUVUSE9EX0hUTUwgPSAiaHRtbCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfT1VUUFVUX01FVEhPRF9YTUwgPSAieG1sIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9PVVRQVVRfTUVUSE9EX1RFWFQgPSAidGV4dCI7Ci0KLSAgCi0gIC8qIEZvciBzcGFjZS1hdHQqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRSVkFMX1BSRVNFUlZFID0gMSwgQVRUUlZBTF9TVFJJUCA9IDI7Ci0KLSAgCi0gIC8qKiBGb3IgaW5kZW50LXJlc3VsdCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gQVRUUlZBTF9ZRVMgPSB0cnVlLCBBVFRSVkFMX05PID0gZmFsc2U7Ci0KLSAgCi0gIC8qKiBGb3IgbGV0dGVyLXZhbHVlIGF0dHJpYnV0ZSAocGFydCBvZiBjb252ZXJzaW9uIGF0dHJpYnV0ZXMpLiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSVkFMX0FMUEhBQkVUSUMgPSAiYWxwaGFiZXRpYyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfT1RIRVIgPSAib3RoZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX1RSQURJVElPTkFMID0gInRyYWRpdGlvbmFsIjsKLQotICAKLSAgLyoqIEZvciBsZXZlbCBhdHRyaWJ1dGUgaW4geHNsOm51bWJlci4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUlZBTF9TSU5HTEUgPSAic2luZ2xlIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9NVUxUSSA9ICJtdWx0aXBsZSIsIEFUVFJWQUxfQU5ZID0gImFueSI7Ci0KLSAgCi0gIC8qKiBGb3IgU3R5bGVzaGVldC1wcmVmaXggYW5kIHJlc3VsdC1wcmVmaXggaW4geHNsOm5hbWVzcGFjZS1hbGlhcyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSVkFMX0RFRkFVTFRfUFJFRklYID0gIiNkZWZhdWx0IjsKLQotICAKLSAgLyoqIEludGVnZXIgZXF1aXZlbGVudHMgZm9yIGFib3ZlICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVU1CRVJMRVZFTF9TSU5HTEUgPSAxLCBOVU1CRVJMRVZFTF9NVUxUSSA9IDIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIE5VTUJFUkxFVkVMX0FOWSA9IDMsIE1BWF9NVUxUSV9DT1VOVElOR19ERVBUSCA9IDMyOwotCi0gIAotICAvKiogc29tZSBzdHVmZiBmb3IgbXkgcGF0dGVybnMtYnktZXhhbXBsZSAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJWQUxfVEhJUyA9ICIuIiwgQVRUUlZBTF9QQVJFTlQgPSAiLi4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX0FOQ0VTVE9SID0gImFuY2VzdG9yIiwgQVRUUlZBTF9JRCA9ICJpZCI7Ci0KLSAgCi0gIC8qKiBTdHVmZiBmb3Igc29ydGluZyAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJWQUxfREFUQVRZUEVfVEVYVCA9ICJ0ZXh0IiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9EQVRBVFlQRV9OVU1CRVIgPSAibnVtYmVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9PUkRFUl9BU0NFTkRJTkcgPSAiYXNjZW5kaW5nIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRUUlZBTF9PUkRFUl9ERVNDRU5ESU5HID0gImRlc2NlbmRpbmciLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX0NBU0VPUkRFUl9VUFBFUiA9ICJ1cHBlci1maXJzdCIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUVFJWQUxfQ0FTRU9SREVSX0xPV0VSID0gImxvd2VyLWZpcnN0IjsKLQotICAKLSAgLyoqIHNvbWUgc3R1ZmYgZm9yIERlY2ltYWwtZm9ybWF0ICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJWQUxfSU5GSU5JVFkgPSAiSW5maW5pdHkiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVFRSVkFMX05BTiA9ICJOYU4iLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERUZBVUxUX0RFQ0lNQUxfRk9STUFUID0gIiNkZWZhdWx0IjsKLQotICAKLSAgLyoqIHRlbXAgZHVtbXkgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSTkFNRV9YWFhYID0gIlhYWFgiOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0RlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTZlMmQyZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzMCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OwotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OwotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0U3ltYm9sczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmRlY2ltYWwtZm9ybWF0LgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6ZGVjaW1hbC1mb3JtYXQgRU1QVFk+Ci0gKiA8IUFUVExJU1QgeHNsOmRlY2ltYWwtZm9ybWF0Ci0gKiAgIG5hbWUgJXFuYW1lOyAjSU1QTElFRAotICogICBkZWNpbWFsLXNlcGFyYXRvciAlY2hhcjsgIi4iCi0gKiAgIGdyb3VwaW5nLXNlcGFyYXRvciAlY2hhcjsgIiwiCi0gKiAgIGluZmluaXR5IENEQVRBICJJbmZpbml0eSIKLSAqICAgbWludXMtc2lnbiAlY2hhcjsgIi0iCi0gKiAgIE5hTiBDREFUQSAiTmFOIgotICogICBwZXJjZW50ICVjaGFyOyAiJSIKLSAqICAgcGVyLW1pbGxlICVjaGFyOyAiJiN4MjAzMDsiCi0gKiAgIHplcm8tZGlnaXQgJWNoYXI7ICIwIgotICogICBkaWdpdCAlY2hhcjsgIiMiCi0gKiAgIHBhdHRlcm4tc2VwYXJhdG9yICVjaGFyOyAiOyIKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Zvcm1hdC1udW1iZXIiPmZvcm1hdC1udW1iZXIgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMgZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqIEFuIGluc3RhbmNlIG9mIERlY2ltYWxGb3JtYXRTeW1ib2xzIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqICBAc2VyaWFsICAgICAgICovCi0gIERlY2ltYWxGb3JtYXRTeW1ib2xzIG1fZGZzOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBEZWNpbWFsRm9ybWF0UHJvcGVydGllcwotICAgKgotICAgKi8KLSAgcHVibGljIERlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzKGludCBkb2NPcmRlck51bWJlcikKLSAgewotCi0gICAgbV9kZnMgPSBuZXcgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzKCk7Ci0KLSAgICAvLyBTZXQgZGVmYXVsdCB2YWx1ZXMsIHRoZXkgY2FuIGJlIG92ZXJpZGVuIGlmIG5lY2Vzc2FyeS4gIAotICAgIG1fZGZzLnNldEluZmluaXR5KENvbnN0YW50cy5BVFRSVkFMX0lORklOSVRZKTsKLSAgICBtX2Rmcy5zZXROYU4oQ29uc3RhbnRzLkFUVFJWQUxfTkFOKTsKLQotICAgIG1fZG9jT3JkZXJOdW1iZXIgPSBkb2NPcmRlck51bWJlcjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGRlY2ltYWwgZm9ybWF0IFN5bWJvbHMgZm9yIHRoaXMgZWxlbWVudC4KLSAgICogPHA+VGhlIHhzbDpkZWNpbWFsLWZvcm1hdCBlbGVtZW50IGRlY2xhcmVzIGEgZGVjaW1hbC1mb3JtYXQsCi0gICAqIHdoaWNoIGNvbnRyb2xzIHRoZSBpbnRlcnByZXRhdGlvbiBvZiBhIGZvcm1hdCBwYXR0ZXJuIHVzZWQgYnkKLSAgICogdGhlIGZvcm1hdC1udW1iZXIgZnVuY3Rpb24uIElmIHRoZXJlIGlzIGEgbmFtZSBhdHRyaWJ1dGUsIHRoZW4KLSAgICogdGhlIGVsZW1lbnQgZGVjbGFyZXMgYSBuYW1lZCBkZWNpbWFsLWZvcm1hdDsgb3RoZXJ3aXNlLCBpdAotICAgKiBkZWNsYXJlcyB0aGUgZGVmYXVsdCBkZWNpbWFsLWZvcm1hdC4gVGhlIHZhbHVlIG9mIHRoZSBuYW1lCi0gICAqIGF0dHJpYnV0ZSBpcyBhIFFOYW1lLCB3aGljaCBpcyBleHBhbmRlZCBhcyBkZXNjcmliZWQgaW4gWzIuNCBRdWFsaWZpZWQgTmFtZXNdLgotICAgKiBJdCBpcyBhbiBlcnJvciB0byBkZWNsYXJlIGVpdGhlciB0aGUgZGVmYXVsdCBkZWNpbWFsLWZvcm1hdCBvciBhCi0gICAqIGRlY2ltYWwtZm9ybWF0IHdpdGggYSBnaXZlbiBuYW1lIG1vcmUgdGhhbiBvbmNlIChldmVuIHdpdGggZGlmZmVyZW50Ci0gICAqIGltcG9ydCBwcmVjZWRlbmNlKSwgdW5sZXNzIGl0IGlzIGRlY2xhcmVkIGV2ZXJ5IHRpbWUgd2l0aCB0aGUgc2FtZQotICAgKiB2YWx1ZSBmb3IgYWxsIGF0dHJpYnV0ZXMgKHRha2luZyBpbnRvIGFjY291bnQgYW55IGRlZmF1bHQgdmFsdWVzKS48L3A+Ci0gICAqIDxwPlRoZSBvdGhlciBhdHRyaWJ1dGVzIG9uIHhzbDpkZWNpbWFsLWZvcm1hdCBjb3JyZXNwb25kIHRvIHRoZQotICAgKiBtZXRob2RzIG9uIHRoZSBKREsgMS4xIERlY2ltYWxGb3JtYXRTeW1ib2xzIGNsYXNzLiBGb3IgZWFjaCBnZXQvc2V0Ci0gICAqIG1ldGhvZCBwYWlyIHRoZXJlIGlzIGFuIGF0dHJpYnV0ZSBkZWZpbmVkIGZvciB0aGUgeHNsOmRlY2ltYWwtZm9ybWF0Ci0gICAqIGVsZW1lbnQuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBkZWNpbWFsIGZvcm1hdCBTeW1ib2xzIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKQotICB7Ci0gICAgcmV0dXJuIG1fZGZzOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIHRoZXJlIGlzIGEgbmFtZSBhdHRyaWJ1dGUsIHRoZW4gdGhlIGVsZW1lbnQgZGVjbGFyZXMgYSBuYW1lZAotICAgKiBkZWNpbWFsLWZvcm1hdDsgb3RoZXJ3aXNlLCBpdCBkZWNsYXJlcyB0aGUgZGVmYXVsdCBkZWNpbWFsLWZvcm1hdC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBRTmFtZSBtX3FuYW1lID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAibmFtZSIgYXR0cmlidXRlLgotICAgKiBJZiB0aGVyZSBpcyBhIG5hbWUgYXR0cmlidXRlLCB0aGVuIHRoZSBlbGVtZW50IGRlY2xhcmVzIGEgbmFtZWQKLSAgICogZGVjaW1hbC1mb3JtYXQ7IG90aGVyd2lzZSwgaXQgZGVjbGFyZXMgdGhlIGRlZmF1bHQgZGVjaW1hbC1mb3JtYXQuCi0gICAqCi0gICAqIEBwYXJhbSBxbmFtZSBUaGUgbmFtZSB0byBzZXQgYXMgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKFFOYW1lIHFuYW1lKQotICB7Ci0gICAgbV9xbmFtZSA9IHFuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogSWYgdGhlcmUgaXMgYSBuYW1lIGF0dHJpYnV0ZSwgdGhlbiB0aGUgZWxlbWVudCBkZWNsYXJlcyBhIG5hbWVkCi0gICAqIGRlY2ltYWwtZm9ybWF0OyBvdGhlcndpc2UsIGl0IGRlY2xhcmVzIHRoZSBkZWZhdWx0IGRlY2ltYWwtZm9ybWF0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkKLSAgewotCi0gICAgaWYgKG1fcW5hbWUgPT0gbnVsbCkKLSAgICAgIHJldHVybiBuZXcgUU5hbWUoIiIpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBtX3FuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImRlY2ltYWwtc2VwYXJhdG9yIiBhdHRyaWJ1dGUuCi0gICAqIGRlY2ltYWwtc2VwYXJhdG9yIHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHVzZWQgZm9yIHRoZSBkZWNpbWFsIHNpZ247Ci0gICAqIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBwZXJpb2QgY2hhcmFjdGVyICguKS4KLSAgICoKLSAgICogQHBhcmFtIGRzIENoYXJhY3RlciB0byBzZXQgYXMgZGVjaW1hbCBzZXBhcmF0b3IgCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREZWNpbWFsU2VwYXJhdG9yKGNoYXIgZHMpCi0gIHsKLSAgICBtX2Rmcy5zZXREZWNpbWFsU2VwYXJhdG9yKGRzKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJkZWNpbWFsLXNlcGFyYXRvciIgYXR0cmlidXRlLgotICAgKiBkZWNpbWFsLXNlcGFyYXRvciBzcGVjaWZpZXMgdGhlIGNoYXJhY3RlciB1c2VkIGZvciB0aGUgZGVjaW1hbCBzaWduOwotICAgKiB0aGUgZGVmYXVsdCB2YWx1ZSBpcyB0aGUgcGVyaW9kIGNoYXJhY3RlciAoLikuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGNoYXJhY3RlciB0byB1c2UgYXMgZGVjaW1hbCBzZXBhcmF0b3IKLSAgICovCi0gIHB1YmxpYyBjaGFyIGdldERlY2ltYWxTZXBhcmF0b3IoKQotICB7Ci0gICAgcmV0dXJuIG1fZGZzLmdldERlY2ltYWxTZXBhcmF0b3IoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlICJncm91cGluZy1zZXBhcmF0b3IiIGF0dHJpYnV0ZS4KLSAgICogZ3JvdXBpbmctc2VwYXJhdG9yIHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHVzZWQgYXMgYSBncm91cGluZwotICAgKiAoZS5nLiB0aG91c2FuZHMpIHNlcGFyYXRvcjsgdGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlIGNvbW1hIGNoYXJhY3RlciAoLCkuCi0gICAqCi0gICAqIEBwYXJhbSBncyBDaGFyYWN0ZXIgdG8gdXNlIGEgZ3JvdXBpbmcgc2VwYXJhdG9yIAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0R3JvdXBpbmdTZXBhcmF0b3IoY2hhciBncykKLSAgewotICAgIG1fZGZzLnNldEdyb3VwaW5nU2VwYXJhdG9yKGdzKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJncm91cGluZy1zZXBhcmF0b3IiIGF0dHJpYnV0ZS4KLSAgICogZ3JvdXBpbmctc2VwYXJhdG9yIHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHVzZWQgYXMgYSBncm91cGluZwotICAgKiAoZS5nLiB0aG91c2FuZHMpIHNlcGFyYXRvcjsgdGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlIGNvbW1hIGNoYXJhY3RlciAoLCkuCi0gICAqCi0gICAqIEByZXR1cm4gQ2hhcmFjdGVyIHRvIHVzZSBhIGdyb3VwaW5nIHNlcGFyYXRvciAKLSAgICovCi0gIHB1YmxpYyBjaGFyIGdldEdyb3VwaW5nU2VwYXJhdG9yKCkKLSAgewotICAgIHJldHVybiBtX2Rmcy5nZXRHcm91cGluZ1NlcGFyYXRvcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImluZmluaXR5IiBhdHRyaWJ1dGUuCi0gICAqIGluZmluaXR5IHNwZWNpZmllcyB0aGUgc3RyaW5nIHVzZWQgdG8gcmVwcmVzZW50IGluZmluaXR5OwotICAgKiB0aGUgZGVmYXVsdCB2YWx1ZSBpcyB0aGUgc3RyaW5nIEluZmluaXR5LgotICAgKgotICAgKiBAcGFyYW0gaW5mIFN0cmluZyB0byB1c2UgYXMgdGhlICJpbmZpbml0eSIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW5maW5pdHkoU3RyaW5nIGluZikKLSAgewotICAgIG1fZGZzLnNldEluZmluaXR5KGluZik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAiaW5maW5pdHkiIGF0dHJpYnV0ZS4KLSAgICogaW5maW5pdHkgc3BlY2lmaWVzIHRoZSBzdHJpbmcgdXNlZCB0byByZXByZXNlbnQgaW5maW5pdHk7Ci0gICAqIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBzdHJpbmcgSW5maW5pdHkuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIHRvIHVzZSBhcyB0aGUgImluZmluaXR5IiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEluZmluaXR5KCkKLSAgewotICAgIHJldHVybiBtX2Rmcy5nZXRJbmZpbml0eSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm1pbnVzLXNpZ24iIGF0dHJpYnV0ZS4KLSAgICogbWludXMtc2lnbiBzcGVjaWZpZXMgdGhlIGNoYXJhY3RlciB1c2VkIGFzIHRoZSBkZWZhdWx0IG1pbnVzIHNpZ247IHRoZQotICAgKiBkZWZhdWx0IHZhbHVlIGlzIHRoZSBoeXBoZW4tbWludXMgY2hhcmFjdGVyICgtLCAjeDJEKS4KLSAgICoKLSAgICogQHBhcmFtIHYgQ2hhcmFjdGVyIHRvIHVzZSBhcyBtaW51cyBzaWduCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNaW51c1NpZ24oY2hhciB2KQotICB7Ci0gICAgbV9kZnMuc2V0TWludXNTaWduKHYpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm1pbnVzLXNpZ24iIGF0dHJpYnV0ZS4KLSAgICogbWludXMtc2lnbiBzcGVjaWZpZXMgdGhlIGNoYXJhY3RlciB1c2VkIGFzIHRoZSBkZWZhdWx0IG1pbnVzIHNpZ247IHRoZQotICAgKiBkZWZhdWx0IHZhbHVlIGlzIHRoZSBoeXBoZW4tbWludXMgY2hhcmFjdGVyICgtLCAjeDJEKS4KLSAgICoKLSAgICogQHJldHVybiBDaGFyYWN0ZXIgdG8gdXNlIGFzIG1pbnVzIHNpZ24KLSAgICovCi0gIHB1YmxpYyBjaGFyIGdldE1pbnVzU2lnbigpCi0gIHsKLSAgICByZXR1cm4gbV9kZnMuZ2V0TWludXNTaWduKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSAiTmFOIiBhdHRyaWJ1dGUuCi0gICAqIE5hTiBzcGVjaWZpZXMgdGhlIHN0cmluZyB1c2VkIHRvIHJlcHJlc2VudCB0aGUgTmFOIHZhbHVlOwotICAgKiB0aGUgZGVmYXVsdCB2YWx1ZSBpcyB0aGUgc3RyaW5nIE5hTi4KLSAgICoKLSAgICogQHBhcmFtIHYgU3RyaW5nIHRvIHVzZSBhcyB0aGUgIk5hTiIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TmFOKFN0cmluZyB2KQotICB7Ci0gICAgbV9kZnMuc2V0TmFOKHYpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIk5hTiIgYXR0cmlidXRlLgotICAgKiBOYU4gc3BlY2lmaWVzIHRoZSBzdHJpbmcgdXNlZCB0byByZXByZXNlbnQgdGhlIE5hTiB2YWx1ZTsKLSAgICogdGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlIHN0cmluZyBOYU4uCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIHRvIHVzZSBhcyB0aGUgIk5hTiIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYU4oKQotICB7Ci0gICAgcmV0dXJuIG1fZGZzLmdldE5hTigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInBlcmNlbnQiIGF0dHJpYnV0ZS4KLSAgICogcGVyY2VudCBzcGVjaWZpZXMgdGhlIGNoYXJhY3RlciB1c2VkIGFzIGEgcGVyY2VudCBzaWduOyB0aGUgZGVmYXVsdAotICAgKiB2YWx1ZSBpcyB0aGUgcGVyY2VudCBjaGFyYWN0ZXIgKCUpLgotICAgKgotICAgKiBAcGFyYW0gdiBDaGFyYWN0ZXIgdG8gdXNlIGFzIHBlcmNlbnQgCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQZXJjZW50KGNoYXIgdikKLSAgewotICAgIG1fZGZzLnNldFBlcmNlbnQodik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAicGVyY2VudCIgYXR0cmlidXRlLgotICAgKiBwZXJjZW50IHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHVzZWQgYXMgYSBwZXJjZW50IHNpZ247IHRoZSBkZWZhdWx0Ci0gICAqIHZhbHVlIGlzIHRoZSBwZXJjZW50IGNoYXJhY3RlciAoJSkuCi0gICAqCi0gICAqIEByZXR1cm4gQ2hhcmFjdGVyIHRvIHVzZSBhcyBwZXJjZW50IAotICAgKi8KLSAgcHVibGljIGNoYXIgZ2V0UGVyY2VudCgpCi0gIHsKLSAgICByZXR1cm4gbV9kZnMuZ2V0UGVyY2VudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInBlci1taWxsZSIgYXR0cmlidXRlLgotICAgKiBwZXItbWlsbGUgc3BlY2lmaWVzIHRoZSBjaGFyYWN0ZXIgdXNlZCBhcyBhIHBlciBtaWxsZSBzaWduOyB0aGUgZGVmYXVsdAotICAgKiB2YWx1ZSBpcyB0aGUgVW5pY29kZSBwZXItbWlsbGUgY2hhcmFjdGVyICgjeDIwMzApLgotICAgKgotICAgKiBAcGFyYW0gdiBDaGFyYWN0ZXIgdG8gdXNlIGFzIHBlci1taWxsZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGVyTWlsbGUoY2hhciB2KQotICB7Ci0gICAgbV9kZnMuc2V0UGVyTWlsbCh2KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJwZXItbWlsbGUiIGF0dHJpYnV0ZS4KLSAgICogcGVyLW1pbGxlIHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHVzZWQgYXMgYSBwZXIgbWlsbGUgc2lnbjsgdGhlIGRlZmF1bHQKLSAgICogdmFsdWUgaXMgdGhlIFVuaWNvZGUgcGVyLW1pbGxlIGNoYXJhY3RlciAoI3gyMDMwKS4KLSAgICoKLSAgICogQHJldHVybiBDaGFyYWN0ZXIgdG8gdXNlIGFzIHBlci1taWxsZSAKLSAgICovCi0gIHB1YmxpYyBjaGFyIGdldFBlck1pbGxlKCkKLSAgewotICAgIHJldHVybiBtX2Rmcy5nZXRQZXJNaWxsKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSAiemVyby1kaWdpdCIgYXR0cmlidXRlLgotICAgKiB6ZXJvLWRpZ2l0IHNwZWNpZmllcyB0aGUgY2hhcmFjdGVyIHVzZWQgYXMgdGhlIGRpZ2l0IHplcm87IHRoZSBkZWZhdWx0Ci0gICAqIHZhbHVlIGlzIHRoZSBkaWdpdCB6ZXJvICgwKS4KLSAgICoKLSAgICogQHBhcmFtIHYgQ2hhcmFjdGVyIHRvIHVzZSBhcyB0aGUgZGlnaXQgemVybwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0WmVyb0RpZ2l0KGNoYXIgdikKLSAgewotICAgIG1fZGZzLnNldFplcm9EaWdpdCh2KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJ6ZXJvLWRpZ2l0IiBhdHRyaWJ1dGUuCi0gICAqIHplcm8tZGlnaXQgc3BlY2lmaWVzIHRoZSBjaGFyYWN0ZXIgdXNlZCBhcyB0aGUgZGlnaXQgemVybzsgdGhlIGRlZmF1bHQKLSAgICogdmFsdWUgaXMgdGhlIGRpZ2l0IHplcm8gKDApLgotICAgKgotICAgKiBAcmV0dXJuIENoYXJhY3RlciB0byB1c2UgYXMgdGhlIGRpZ2l0IHplcm8KLSAgICovCi0gIHB1YmxpYyBjaGFyIGdldFplcm9EaWdpdCgpCi0gIHsKLSAgICByZXR1cm4gbV9kZnMuZ2V0WmVyb0RpZ2l0KCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSAiZGlnaXQiIGF0dHJpYnV0ZS4KLSAgICogZGlnaXQgc3BlY2lmaWVzIHRoZSBjaGFyYWN0ZXIgdXNlZCBmb3IgYSBkaWdpdCBpbiB0aGUgZm9ybWF0IHBhdHRlcm47Ci0gICAqIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBudW1iZXIgc2lnbiBjaGFyYWN0ZXIgKCMpLgotICAgKgotICAgKiBAcGFyYW0gdiBDaGFyYWN0ZXIgdG8gdXNlIGZvciBhIGRpZ2l0IGluIGZvcm1hdCBwYXR0ZXJuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREaWdpdChjaGFyIHYpCi0gIHsKLSAgICBtX2Rmcy5zZXREaWdpdCh2KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJkaWdpdCIgYXR0cmlidXRlLgotICAgKiBkaWdpdCBzcGVjaWZpZXMgdGhlIGNoYXJhY3RlciB1c2VkIGZvciBhIGRpZ2l0IGluIHRoZSBmb3JtYXQgcGF0dGVybjsKLSAgICogdGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlIG51bWJlciBzaWduIGNoYXJhY3RlciAoIykuCi0gICAqCi0gICAqIEByZXR1cm4gQ2hhcmFjdGVyIHRvIHVzZSBmb3IgYSBkaWdpdCBpbiBmb3JtYXQgcGF0dGVybgotICAgKi8KLSAgcHVibGljIGNoYXIgZ2V0RGlnaXQoKQotICB7Ci0gICAgcmV0dXJuIG1fZGZzLmdldERpZ2l0KCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSAicGF0dGVybi1zZXBhcmF0b3IiIGF0dHJpYnV0ZS4KLSAgICogcGF0dGVybi1zZXBhcmF0b3Igc3BlY2lmaWVzIHRoZSBjaGFyYWN0ZXIgdXNlZCB0byBzZXBhcmF0ZSBwb3NpdGl2ZQotICAgKiBhbmQgbmVnYXRpdmUgc3ViIHBhdHRlcm5zIGluIGEgcGF0dGVybjsgdGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlCi0gICAqIHNlbWktY29sb24gY2hhcmFjdGVyICg7KS4KLSAgICoKLSAgICogQHBhcmFtIHYgQ2hhcmFjdGVyIHRvIHVzZSBhcyBhIHBhdHRlcm4gc2VwYXJhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXR0ZXJuU2VwYXJhdG9yKGNoYXIgdikKLSAgewotICAgIG1fZGZzLnNldFBhdHRlcm5TZXBhcmF0b3Iodik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAicGF0dGVybi1zZXBhcmF0b3IiIGF0dHJpYnV0ZS4KLSAgICogcGF0dGVybi1zZXBhcmF0b3Igc3BlY2lmaWVzIHRoZSBjaGFyYWN0ZXIgdXNlZCB0byBzZXBhcmF0ZSBwb3NpdGl2ZQotICAgKiBhbmQgbmVnYXRpdmUgc3ViIHBhdHRlcm5zIGluIGEgcGF0dGVybjsgdGhlIGRlZmF1bHQgdmFsdWUgaXMgdGhlCi0gICAqIHNlbWktY29sb24gY2hhcmFjdGVyICg7KS4KLSAgICoKLSAgICogQHJldHVybiBDaGFyYWN0ZXIgdG8gdXNlIGFzIGEgcGF0dGVybiBzZXBhcmF0b3IKLSAgICovCi0gIHB1YmxpYyBjaGFyIGdldFBhdHRlcm5TZXBhcmF0b3IoKQotICB7Ci0gICAgcmV0dXJuIG1fZGZzLmdldFBhdHRlcm5TZXBhcmF0b3IoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB0byByZWNvbXBvc2UoKSBhbGwgb2YgdGhlIGRlY2ltYWwgZm9ybWF0IHByb3BlcnRpZXMgZWxlbWVudHMuCi0gICAqIAotICAgKiBAcGFyYW0gcm9vdCBTdHlsZXNoZWV0IHJvb3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlY29tcG9zZShTdHlsZXNoZWV0Um9vdCByb290KQotICB7Ci0gICAgcm9vdC5yZWNvbXBvc2VEZWNpbWFsRm9ybWF0cyh0aGlzKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUFwcGx5SW1wb3J0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUFwcGx5SW1wb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ1Mzc0M2UuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1BcHBseUltcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDphcHBseS1pbXBvcnRzLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6YXBwbHktaW1wb3J0cyBFTVBUWT4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2FwcGx5LWltcG9ydHMiPmFwcGx5LWltcG9ydHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbUFwcGx5SW1wb3J0IGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVG9rZW4gSUQgZm9yIHhzbDphcHBseS1pbXBvcnRzIGVsZW1lbnQgdHlwZXMKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0WFNMVG9rZW4oKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9BUFBMWV9JTVBPUlRTOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIEVsZW1lbnQgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0FQUExZX0lNUE9SVFNfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIHhzbDphcHBseS1pbXBvcnRzIHRyYW5zZm9ybWF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAodHJhbnNmb3JtZXIuY3VycmVudFRlbXBsYXRlUnVsZUlzTnVsbCgpKQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmdldE1zZ01ncigpLmVycm9yKHRoaXMsCi0gICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19BUFBMWV9JTVBPUlRfSU5fRk9SX0VBQ0gpOyAgLy8ieHNsOmFwcGx5LWltcG9ydHMgbm90IGFsbG93ZWQgaW4gYSB4c2w6Zm9yLWVhY2giKTsKLSAgICB9Ci0KLSAgICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgIGludCBzb3VyY2VOb2RlID0gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBpZiAoRFRNLk5VTEwgIT0gc291cmNlTm9kZSkKLSAgICB7Ci0KLSAgICAgIC8vIFRoaXMgd2lsbCBoYXZlIHRvIGNoYW5nZSB0byBjdXJyZW50IHRlbXBsYXRlLCAod2hpY2ggd2lsbCBoYXZlIAotICAgICAgLy8gdG8gYmUgdGhlIHRvcCBvZiBhIGN1cnJlbnQgdGVtcGxhdGUgc3RhY2spLgotICAgICAgdHJhbnNmb3JtZXIuYXBwbHlUZW1wbGF0ZVRvTm9kZSh0aGlzLCBudWxsLCBzb3VyY2VOb2RlKTsKLSAgICB9Ci0gICAgZWxzZSAgLy8gaWYobnVsbCA9PSBzb3VyY2VOb2RlKQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmdldE1zZ01ncigpLmVycm9yKHRoaXMsCi0gICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9OVUxMX1NPVVJDRU5PREVfQVBQTFlJTVBPUlRTKTsgIC8vInNvdXJjZU5vZGUgaXMgbnVsbCBpbiB4c2w6YXBwbHktaW1wb3J0cyEiKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgY2hpbGQgdG8gdGhlIGNoaWxkIGxpc3QuCi0gICAqIDwhRUxFTUVOVCB4c2w6YXBwbHktaW1wb3J0cyBFTVBUWT4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIE5ldyBlbGVtZW50IHRvIGFwcGVuZCB0byB0aGlzIGVsZW1lbnQncyBjaGlsZHJlbiBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbCwgeHNsOmFwcGx5LUltcG9ydHMgY2Fubm90IGhhdmUgY2hpbGRyZW4gCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlRWxlbWVudCBhcHBlbmRDaGlsZChFbGVtVGVtcGxhdGVFbGVtZW50IG5ld0NoaWxkKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0FERCwKLSAgICAgICAgICBuZXcgT2JqZWN0W117IG5ld0NoaWxkLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldE5vZGVOYW1lKCkgfSk7ICAvLyJDYW4gbm90IGFkZCAiICsoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpbmV3Q2hpbGQpLm1fZWxlbU5hbWUgKwotCi0gICAgLy8iIHRvICIgKyB0aGlzLm1fZWxlbU5hbWUpOwotICAgIHJldHVybiBudWxsOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUFwcGx5VGVtcGxhdGVzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUFwcGx5VGVtcGxhdGVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDgxN2ZkZjUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1BcHBseVRlbXBsYXRlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDU1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5UcmFjZXJFdmVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5WYXJpYWJsZVN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5DbG9uZXJUb1Jlc3VsdFRyZWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUF4aXNUcmF2ZXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkF4aXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotCi0vLyBFeHBlcmVtZW50YWwKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkV4cGFuZGVkTmFtZVRhYmxlOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDphcHBseS10ZW1wbGF0ZXMuCi0gKiA8cHJlPgotICogJmFtcDshRUxFTUVOVCB4c2w6YXBwbHktdGVtcGxhdGVzICh4c2w6c29ydHx4c2w6d2l0aC1wYXJhbSkqPgotICogJmFtcDshQVRUTElTVCB4c2w6YXBwbHktdGVtcGxhdGVzCi0gKiAgIHNlbGVjdCAlZXhwcjsgIm5vZGUoKSIKLSAqICAgbW9kZSAlcW5hbWU7ICNJTVBMSUVECi0gKiAmYW1wOwotICogPC9wcmU+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1BcHBseWluZy1UZW1wbGF0ZS1SdWxlcyI+c2VjdGlvbi1BcHBseWluZy1UZW1wbGF0ZS1SdWxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtQXBwbHlUZW1wbGF0ZXMgZXh0ZW5kcyBFbGVtQ2FsbFRlbXBsYXRlCi17Ci0KLSAgLyoqCi0gICAqIG1vZGUgJXFuYW1lOyAjSU1QTElFRAotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFFOYW1lIG1fbW9kZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbW9kZSBhdHRyaWJ1dGUgZm9yIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNb2RlKFFOYW1lIG1vZGUpCi0gIHsKLSAgICBtX21vZGUgPSBtb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbW9kZSBhdHRyaWJ1dGUgZm9yIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbW9kZSBhdHRyaWJ1dGUgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIFFOYW1lIGdldE1vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fbW9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGJlbG9uZ3MgdG8gYSBkZWZhdWx0IHRlbXBsYXRlLAotICAgKiBpbiB3aGljaCBjYXNlIGl0IHdpbGwgYWN0IGRpZmZlcmVudCB3aXRoCi0gICAqIHJlZ2FyZCB0byBwcm9jZXNzaW5nIG1vZGVzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjYnVpbHQtaW4tcnVsZSI+YnVpbHQtaW4tcnVsZSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzRGVmYXVsdFRlbXBsYXRlID0gZmFsc2U7Ci0gIAotLy8gIC8qKgotLy8gICAqIExpc3Qgb2YgbmFtZXNwYWNlL2xvY2FsbmFtZSBJRHMsIGZvciBpZGVudGlmaWNhdGlvbiBvZiB4c2w6d2l0aC1wYXJhbSB0byAKLS8vICAgKiB4c2w6cGFyYW1zLiAgSW5pdGlhbGl6ZWQgaW4gdGhlIGNvbXBvc2UoKSBtZXRob2QuCi0vLyAgICovCi0vLyAgcHJpdmF0ZSBpbnRbXSBtX3BhcmFtSURzOwotCi0gIC8qKgotICAgKiBTZXQgaWYgdGhpcyBiZWxvbmdzIHRvIGEgZGVmYXVsdCB0ZW1wbGF0ZSwKLSAgICogaW4gd2hpY2ggY2FzZSBpdCB3aWxsIGFjdCBkaWZmZXJlbnQgd2l0aAotICAgKiByZWdhcmQgdG8gcHJvY2Vzc2luZyBtb2Rlcy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2J1aWx0LWluLXJ1bGUiPmJ1aWx0LWluLXJ1bGUgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gYiBib29sZWFuIHZhbHVlIHRvIHNldC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElzRGVmYXVsdFRlbXBsYXRlKGJvb2xlYW4gYikKLSAgewotICAgIG1faXNEZWZhdWx0VGVtcGxhdGUgPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUb2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50IHR5cGVzCi0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfQVBQTFlfVEVNUExBVEVTOwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgZXZlcnl0aGluZyBlbHNlIGhhcyBiZWVuCi0gICAqIHJlY29tcG9zZWQsIGFuZCBhbGxvd3MgdGhlIHRlbXBsYXRlIHRvIHNldCByZW1haW5pbmcKLSAgICogdmFsdWVzIHRoYXQgbWF5IGJlIGJhc2VkIG9uIHNvbWUgb3RoZXIgcHJvcGVydHkgdGhhdAotICAgKiBkZXBlbmRzIG9uIHJlY29tcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21wb3NlKFN0eWxlc2hlZXRSb290IHNyb290KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIEVsZW1lbnQgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0FQUExZX1RFTVBMQVRFU19TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQXBwbHkgdGhlIGNvbnRleHQgbm9kZSB0byB0aGUgbWF0Y2hpbmcgdGVtcGxhdGVzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1BcHBseWluZy1UZW1wbGF0ZS1SdWxlcyI+c2VjdGlvbi1BcHBseWluZy1UZW1wbGF0ZS1SdWxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJhbnNmb3JtZXIucHVzaEN1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwoZmFsc2UpOwotCi0gICAgYm9vbGVhbiBwdXNoTW9kZSA9IGZhbHNlOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgICAgLy8gJVJFVklFVyUgRG8gd2UgbmVlZCB0aGlzIGNoZWNrPz8KLSAgICAgIC8vICAgICAgaWYgKG51bGwgIT0gc291cmNlTm9kZSkKLSAgICAgIC8vICAgICAgewotICAgICAgLy8gYm9vbGVhbiBuZWVkVG9UdXJuT2ZmSW5maW5pdGVMb29wQ2hlY2sgPSBmYWxzZTsKLSAgICAgIFFOYW1lIG1vZGUgPSB0cmFuc2Zvcm1lci5nZXRNb2RlKCk7Ci0KLSAgICAgIGlmICghbV9pc0RlZmF1bHRUZW1wbGF0ZSkKLSAgICAgIHsKLSAgICAgICAgaWYgKCgobnVsbCA9PSBtb2RlKSAmJiAobnVsbCAhPSBtX21vZGUpKQotICAgICAgICAgICAgICAgIHx8ICgobnVsbCAhPSBtb2RlKSAmJiFtb2RlLmVxdWFscyhtX21vZGUpKSkKLSAgICAgICAgewotICAgICAgICAgIHB1c2hNb2RlID0gdHJ1ZTsKLQotICAgICAgICAgIHRyYW5zZm9ybWVyLnB1c2hNb2RlKG1fbW9kZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHRyYW5zZm9ybVNlbGVjdGVkTm9kZXModHJhbnNmb3JtZXIpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgaWYgKHB1c2hNb2RlKQotICAgICAgICB0cmFuc2Zvcm1lci5wb3BNb2RlKCk7Ci0KLSAgICAgIHRyYW5zZm9ybWVyLnBvcEN1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwoKTsKLSAgICB9Ci0gIH0KLQotICAKLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBQZXJmb3JtIGEgcXVlcnkgaWYgbmVlZGVkLCBhbmQgY2FsbCB0cmFuc2Zvcm1Ob2RlIGZvciBlYWNoIGNoaWxkLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHRlbXBsYXRlIFRoZSBvd25pbmcgdGVtcGxhdGUgY29udGV4dC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBUaHJvd24gaW4gYSB2YXJpZXR5IG9mIGNpcmN1bXN0YW5jZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm1TZWxlY3RlZE5vZGVzKFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBmaW5hbCBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICBmaW5hbCBpbnQgc291cmNlTm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgRFRNSXRlcmF0b3Igc291cmNlTm9kZXMgPSBtX3NlbGVjdEV4cHJlc3Npb24uYXNJdGVyYXRvcih4Y3R4dCwgc291cmNlTm9kZSk7Ci0gICAgVmFyaWFibGVTdGFjayB2YXJzID0geGN0eHQuZ2V0VmFyU3RhY2soKTsKLSAgICBpbnQgblBhcmFtcyA9IGdldFBhcmFtRWxlbUNvdW50KCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIGZpbmFsIFZlY3RvciBrZXlzID0gKG1fc29ydEVsZW1zID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgID8gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRyYW5zZm9ybWVyLnByb2Nlc3NTb3J0S2V5cyh0aGlzLCBzb3VyY2VOb2RlKTsKLQotICAgICAgLy8gU29ydCBpZiB3ZSBuZWVkIHRvLgotICAgICAgaWYgKG51bGwgIT0ga2V5cykKLSAgICAgICAgc291cmNlTm9kZXMgPSBzb3J0Tm9kZXMoeGN0eHQsIGtleXMsIHNvdXJjZU5vZGVzKTsKLQotICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlU2VsZWN0ZWRFdmVudChzb3VyY2VOb2RlLCB0aGlzLAotICAgICAgICAgICAgICAgICJzZWxlY3QiLCBuZXcgWFBhdGgobV9zZWxlY3RFeHByZXNzaW9uKSwKLSAgICAgICAgICAgICAgICBuZXcgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0KHNvdXJjZU5vZGVzKSk7Ci0KLSAgICAgIGZpbmFsIFJlc3VsdFRyZWVIYW5kbGVyIHJ0aCA9IHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCk7Ci0gICAgICBDb250ZW50SGFuZGxlciBjaGFuZGxlciA9IHJ0aC5nZXRDb250ZW50SGFuZGxlcigpOwotICAgICAgZmluYWwgU3R5bGVzaGVldFJvb3Qgc3Jvb3QgPSB0cmFuc2Zvcm1lci5nZXRTdHlsZXNoZWV0KCk7Ci0gICAgICBmaW5hbCBUZW1wbGF0ZUxpc3QgdGwgPSBzcm9vdC5nZXRUZW1wbGF0ZUxpc3RDb21wb3NlZCgpOwotICAgICAgZmluYWwgYm9vbGVhbiBxdWlldCA9IHRyYW5zZm9ybWVyLmdldFF1aWV0Q29uZmxpY3RXYXJuaW5ncygpOwotICAgICAgCi0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoRFRNLk5VTEwpOwotICAgICAgaW50W10gY3VycmVudE5vZGVzID0geGN0eHQuZ2V0Q3VycmVudE5vZGVTdGFjaygpOwotICAgICAgaW50IGN1cnJlbnROb2RlUG9zID0geGN0eHQuZ2V0Q3VycmVudE5vZGVGaXJzdEZyZWUoKSAtIDE7Ci0gICAgICAKLSAgICAgIHhjdHh0LnB1c2hDdXJyZW50RXhwcmVzc2lvbk5vZGUoRFRNLk5VTEwpOwotICAgICAgaW50W10gY3VycmVudEV4cHJlc3Npb25Ob2RlcyA9IHhjdHh0LmdldEN1cnJlbnRFeHByZXNzaW9uTm9kZVN0YWNrKCk7Ci0gICAgICBpbnQgY3VycmVudEV4cHJlc3Npb25Ob2RlUG9zID0geGN0eHQuZ2V0Q3VycmVudEV4cHJlc3Npb25Ob2Rlc0ZpcnN0RnJlZSgpIC0gMTsKLQotICAgICAgeGN0eHQucHVzaFNBWExvY2F0b3JOdWxsKCk7Ci0gICAgICB4Y3R4dC5wdXNoQ29udGV4dE5vZGVMaXN0KHNvdXJjZU5vZGVzKTsKLSAgICAgIHRyYW5zZm9ybWVyLnB1c2hFbGVtVGVtcGxhdGVFbGVtZW50KG51bGwpOwotICAgICAgLy8gcHVzaFBhcmFtcyh0cmFuc2Zvcm1lciwgeGN0eHQpOwotCi0gICAgICAvLyBTaG91bGQgYmUgYWJsZSB0byBnZXQgdGhpcyBmcm9tIHRoZSBpdGVyYXRvciBidXQgdGhlcmUgbXVzdCBiZSBhIGJ1Zy4KLSAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oc291cmNlTm9kZSk7Ci0gICAgICBpbnQgZG9jSUQgPSBzb3VyY2VOb2RlICYgRFRNTWFuYWdlci5JREVOVF9EVE1fREVGQVVMVDsKLSAgICAgIAotICAgICAgaW50IGFyZ3NGcmFtZSA9IC0xOwotICAgICAgaWYoblBhcmFtcyA+IDApCi0gICAgICB7Ci0gICAgICAgIC8vIFRoaXMgY29kZSB3aWxsIGNyZWF0ZSBhIHNlY3Rpb24gb24gdGhlIHN0YWNrIHRoYXQgaXMgYWxsIHRoZSAKLSAgICAgICAgLy8gZXZhbHVhdGVkIGFyZ3VtZW50cy4gIFRoZXNlIHdpbGwgYmUgY29waWVkIGludG8gdGhlIHJlYWwgcGFyYW1zIAotICAgICAgICAvLyBzZWN0aW9uIG9mIGVhY2ggY2FsbGVkIHRlbXBsYXRlLgotICAgICAgICBpbnQgdGhpc2ZyYW1lID0gdmFycy5nZXRTdGFja0ZyYW1lKCk7Ci0gICAgICAgIGFyZ3NGcmFtZSA9IHZhcnMubGluayhuUGFyYW1zKTsKLSAgICAgICAgdmFycy5zZXRTdGFja0ZyYW1lKHRoaXNmcmFtZSk7Ci0gICAgICAgIAotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5QYXJhbXM7IGkrKykgCi0gICAgICAgIHsKLSAgICAgICAgICBFbGVtV2l0aFBhcmFtIGV3cCA9IG1fcGFyYW1FbGVtc1tpXTsKLSAgICAgICAgICBYT2JqZWN0IG9iaiA9IGV3cC5nZXRWYWx1ZSh0cmFuc2Zvcm1lciwgc291cmNlTm9kZSk7Ci0gICAgICAgICAgCi0gICAgICAgICAgdmFycy5zZXRMb2NhbFZhcmlhYmxlKGksIG9iaiwgYXJnc0ZyYW1lKTsKLSAgICAgICAgfQotICAgICAgICB2YXJzLnNldFN0YWNrRnJhbWUoYXJnc0ZyYW1lKTsKLSAgICAgIH0KLSAgICAgIAotICAgICAgCi0gICAgICBpbnQgY2hpbGQ7Ci0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKGNoaWxkID0gc291cmNlTm9kZXMubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGN1cnJlbnROb2Rlc1tjdXJyZW50Tm9kZVBvc10gPSBjaGlsZDsKLSAgICAgICAgY3VycmVudEV4cHJlc3Npb25Ob2Rlc1tjdXJyZW50RXhwcmVzc2lvbk5vZGVQb3NdID0gY2hpbGQ7Ci0KLSAgICAgICAgaWYoKGNoaWxkICYgRFRNTWFuYWdlci5JREVOVF9EVE1fREVGQVVMVCkgIT0gZG9jSUQpCi0gICAgICAgIHsKLSAgICAgICAgICBkdG0gPSB4Y3R4dC5nZXREVE0oY2hpbGQpOwotICAgICAgICAgIGRvY0lEID0gc291cmNlTm9kZSAmIERUTU1hbmFnZXIuSURFTlRfRFRNX0RFRkFVTFQ7Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIGZpbmFsIGludCBleE5vZGVUeXBlID0gZHRtLmdldEV4cGFuZGVkVHlwZUlEKGNoaWxkKTsKLSAgICAgICAgZmluYWwgaW50IG5vZGVUeXBlID0gKGV4Tm9kZVR5cGUgPj4gRXhwYW5kZWROYW1lVGFibGUuUk9UQU1PVU5UX1RZUEUpOwotCi0gICAgICAgIGZpbmFsIFFOYW1lIG1vZGUgPSB0cmFuc2Zvcm1lci5nZXRNb2RlKCk7Ci0KLSAgICAgICAgRWxlbVRlbXBsYXRlIHRlbXBsYXRlID0gdGwuZ2V0VGVtcGxhdGVGYXN0KHhjdHh0LCBjaGlsZCwgZXhOb2RlVHlwZSwgbW9kZSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xLCBxdWlldCwgZHRtKTsKLQotICAgICAgICAvLyBJZiB0aGF0IGRpZG4ndCBsb2NhdGUgYSBub2RlLCBmYWxsIGJhY2sgdG8gYSBkZWZhdWx0IHRlbXBsYXRlIHJ1bGUuCi0gICAgICAgIC8vIFNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2J1aWx0LWluLXJ1bGUuCi0gICAgICAgIGlmIChudWxsID09IHRlbXBsYXRlKQotICAgICAgICB7Ci0gICAgICAgICAgc3dpdGNoIChub2RlVHlwZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICAgICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICAgIHRlbXBsYXRlID0gc3Jvb3QuZ2V0RGVmYXVsdFJ1bGUoKTsKLSAgICAgICAgICAgIC8vICVPUFQlIGRpcmVjdCBmYXN0ZXI/Ci0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICAgICAgY2FzZSBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgICAgICBjYXNlIERUTS5URVhUX05PREUgOgotICAgICAgICAgICAgLy8gaWYocnRoLm1fZWxlbUlzUGVuZGluZyB8fCBydGgubV9kb2NQZW5kaW5nKQotICAgICAgICAgICAgLy8gIHJ0aC5mbHVzaFBlbmRpbmcodHJ1ZSk7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5wdXNoUGFpckN1cnJlbnRNYXRjaGVkKHNyb290LmdldERlZmF1bHRUZXh0UnVsZSgpLCBjaGlsZCk7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5zZXRDdXJyZW50RWxlbWVudChzcm9vdC5nZXREZWZhdWx0VGV4dFJ1bGUoKSk7Ci0gICAgICAgICAgICAvLyBkdG0uZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKGNoaWxkLCBjaGFuZGxlciwgZmFsc2UpOwotICAgICAgICAgICAgZHRtLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhjaGlsZCwgcnRoLCBmYWxzZSk7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5wb3BDdXJyZW50TWF0Y2hlZCgpOwotICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgICAgICAgICB0ZW1wbGF0ZSA9IHNyb290LmdldERlZmF1bHRSb290UnVsZSgpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgZGVmYXVsdCA6Ci0KLSAgICAgICAgICAgIC8vIE5vIGRlZmF1bHQgcnVsZXMgZm9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGFuZCB0aGUgbGlrZS4KLSAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAKLSAgICAgICAgdHJhbnNmb3JtZXIucHVzaFBhaXJDdXJyZW50TWF0Y2hlZCh0ZW1wbGF0ZSwgY2hpbGQpOwotCi0gICAgICAgIGlmKHRlbXBsYXRlLm1fZnJhbWVTaXplID4gMCkKLSAgICAgICAgewotICAgICAgICAgIHZhcnMubGluayh0ZW1wbGF0ZS5tX2ZyYW1lU2l6ZSk7Ci0gICAgICAgICAgLy8gWW91IGNhbid0IGRvIHRoZSBjaGVjayBmb3IgblBhcmFtcyBoZXJlLCBvdGhlcndpc2UgdGhlIAotICAgICAgICAgIC8vIHhzbDpwYXJhbXMgbWlnaHQgbm90IGJlIG51bGxlZC4KLSAgICAgICAgICBpZigvKiBuUGFyYW1zID4gMCAmJiAqLyB0ZW1wbGF0ZS5tX2luQXJnc1NpemUgPiAwKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBwYXJhbUluZGV4ID0gMDsKLSAgICAgICAgICAgIGZvciAoRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtID0gdGVtcGxhdGUuZ2V0Rmlyc3RDaGlsZEVsZW0oKTsgCi0gICAgICAgICAgICAgICAgIG51bGwgIT0gZWxlbTsgZWxlbSA9IGVsZW0uZ2V0TmV4dFNpYmxpbmdFbGVtKCkpIAotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZihDb25zdGFudHMuRUxFTU5BTUVfUEFSQU1WQVJJQUJMRSA9PSBlbGVtLmdldFhTTFRva2VuKCkpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBFbGVtUGFyYW0gZXAgPSAoRWxlbVBhcmFtKWVsZW07Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgaW50IGk7Ci0gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG5QYXJhbXM7IGkrKykgCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgRWxlbVdpdGhQYXJhbSBld3AgPSBtX3BhcmFtRWxlbXNbaV07Ci0gICAgICAgICAgICAgICAgICBpZihld3AubV9xbmFtZUlEID09IGVwLm1fcW5hbWVJRCkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgWE9iamVjdCBvYmogPSB2YXJzLmdldExvY2FsVmFyaWFibGUoaSwgYXJnc0ZyYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgdmFycy5zZXRMb2NhbFZhcmlhYmxlKHBhcmFtSW5kZXgsIG9iaik7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBpZihpID09IG5QYXJhbXMpCi0gICAgICAgICAgICAgICAgICB2YXJzLnNldExvY2FsVmFyaWFibGUocGFyYW1JbmRleCwgbnVsbCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICBwYXJhbUluZGV4Kys7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBpZiAoY2hlY2spCi0gICAgICAgIC8vICBndWFyZC5wdXNoKHRoaXMsIGNoaWxkKTsKLQotICAgICAgICAvLyBGaXJlIGEgdHJhY2UgZXZlbnQgZm9yIHRoZSB0ZW1wbGF0ZS4KLSAgICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRlbXBsYXRlKTsKLQotICAgICAgICAvLyBBbmQgZXhlY3V0ZSB0aGUgY2hpbGQgdGVtcGxhdGVzLgotICAgICAgICAvLyBMb29wIHRocm91Z2ggdGhlIGNoaWxkcmVuIG9mIHRoZSB0ZW1wbGF0ZSwgY2FsbGluZyBleGVjdXRlIG9uIAotICAgICAgICAvLyBlYWNoIG9mIHRoZW0uCi0gICAgICAgIGZvciAoRWxlbVRlbXBsYXRlRWxlbWVudCB0ID0gdGVtcGxhdGUubV9maXJzdENoaWxkOyAKLSAgICAgICAgICAgICB0ICE9IG51bGw7IHQgPSB0Lm1fbmV4dFNpYmxpbmcpCi0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5zZXRTQVhMb2NhdG9yKHQpOwotICAgICAgICAgIHRyYW5zZm9ybWVyLnNldEN1cnJlbnRFbGVtZW50KHQpOwotICAgICAgICAgIHQuZXhlY3V0ZSh0cmFuc2Zvcm1lcik7Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIGlmKHRlbXBsYXRlLm1fZnJhbWVTaXplID4gMCkKLSAgICAgICAgICB2YXJzLnVubGluaygpOwotICAgICAgICAgIAotICAgICAgICB0cmFuc2Zvcm1lci5wb3BDdXJyZW50TWF0Y2hlZCgpOwotICAgICAgICAKLSAgICAgIH0gLy8gZW5kIHdoaWxlIChEVE0uTlVMTCAhPSAoY2hpbGQgPSBzb3VyY2VOb2Rlcy5uZXh0Tm9kZSgpKSkKLSAgICB9Ci0gICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0cmFuc2Zvcm1lci5nZXRFcnJvckxpc3RlbmVyKCkuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVNlbGVjdGVkRW5kRXZlbnQoc291cmNlTm9kZSwgdGhpcywKLSAgICAgICAgICAgICAgICAic2VsZWN0IiwgbmV3IFhQYXRoKG1fc2VsZWN0RXhwcmVzc2lvbiksCi0gICAgICAgICAgICAgICAgbmV3IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldChzb3VyY2VOb2RlcykpOwotCi0gICAgICBpZihuUGFyYW1zID4gMCkKLSAgICAgICAgdmFycy51bmxpbmsoKTsKLSAgICAgIHhjdHh0LnBvcFNBWExvY2F0b3IoKTsKLSAgICAgIHhjdHh0LnBvcENvbnRleHROb2RlTGlzdCgpOwotICAgICAgdHJhbnNmb3JtZXIucG9wRWxlbVRlbXBsYXRlRWxlbWVudCgpOwotICAgICAgeGN0eHQucG9wQ3VycmVudEV4cHJlc3Npb25Ob2RlKCk7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgc291cmNlTm9kZXMuZGV0YWNoKCk7Ci0gICAgfQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQXR0cmlidXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUF0dHJpYnV0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMzZiODg4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQXR0cmlidXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyOTYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5SZXN1bHRUcmVlSGFuZGxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCB4c2w6YXR0cmlidXRlLgotICogPHByZT4KLSAqICZhbXA7IUVMRU1FTlQgeHNsOmF0dHJpYnV0ZSAlY2hhci10ZW1wbGF0ZTs+Ci0gKiAmYW1wOyFBVFRMSVNUIHhzbDphdHRyaWJ1dGUKLSAqICAgbmFtZSAlYXZ0OyAjUkVRVUlSRUQKLSAqICAgbmFtZXNwYWNlICVhdnQ7ICNJTVBMSUVECi0gKiAgICVzcGFjZS1hdHQ7Ci0gKiAmYW1wOwotICogPC9wcmU+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY3JlYXRpbmctYXR0cmlidXRlcyI+Y3JlYXRpbmctYXR0cmlidXRlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtQXR0cmlidXRlIGV4dGVuZHMgRWxlbUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfQVRUUklCVVRFOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50IG5hbWUgCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfQVRUUklCVVRFX1NUUklORzsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gYXR0cmlidXRlIGluIHRoZSByZXN1bHQgdHJlZS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NyZWF0aW5nLWF0dHJpYnV0ZXMiPmNyZWF0aW5nLWF0dHJpYnV0ZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotCi0gICAgLy8gSWYgdGhleSBhcmUgdHJ5aW5nIHRvIGFkZCBhbiBhdHRyaWJ1dGUgd2hlbiB0aGVyZSBpc24ndCBhbiAKLSAgICAvLyBlbGVtZW50IHBlbmRpbmcsIGl0IGlzIGFuIGVycm9yLgotICAgIGlmICghcmhhbmRsZXIuaXNFbGVtZW50UGVuZGluZygpKQotICAgIHsKLSAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgdHJhY2UgZXZlbnQgaXMgc2VudC4KLSAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotICAgICAgaW50IHNvdXJjZU5vZGUgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgU3RyaW5nIGF0dHJOYW1lID0gbV9uYW1lX2F2dC5ldmFsdWF0ZSh4Y3R4dCwgc291cmNlTm9kZSwgdGhpcyk7Ci0gICAgICB0cmFuc2Zvcm1lci5nZXRNc2dNZ3IoKS53YXJuKHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5XR19JTExFR0FMX0FUVFJJQlVURSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBhdHRyTmFtZSB9KTsKLQotICAgICAgcmV0dXJuOwotCi0gICAgICAvLyB3YXJuKHRlbXBsYXRlQ2hpbGQsIHNvdXJjZU5vZGUsICJUcnlpbmcgdG8gYWRkIGF0dHJpYnV0ZSBhZnRlciBlbGVtZW50IGNoaWxkIGhhcyBiZWVuIGFkZGVkLCBpZ25vcmluZy4uLiIpOwotICAgIH0KLSAgICAKLSAgICBzdXBlci5leGVjdXRlKHRyYW5zZm9ybWVyKTsKLSAgICAKLSAgfQotICAKLSAgLyoqCi0gICAqIFJlc29sdmUgdGhlIG5hbWVzcGFjZSBpbnRvIGEgcHJlZml4LiAgQXQgdGhpcyBsZXZlbCwgaWYgbm8gcHJlZml4IGV4aXN0cywgCi0gICAqIHRoZW4gcmV0dXJuIGEgbWFudWZhY3R1cmVkIHByZWZpeC4KLSAgICoKLSAgICogQHBhcmFtIHJoYW5kbGVyIFRoZSBjdXJyZW50IHJlc3VsdCB0cmVlIGhhbmRsZXIuCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByb2JhYmxlIHByZWZpeCBpZiBhbHJlYWR5IGtub3duLgotICAgKiBAcGFyYW0gbm9kZU5hbWVzcGFjZSAgVGhlIG5hbWVzcGFjZSwgd2hpY2ggc2hvdWxkIG5vdCBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmVmaXggdG8gYmUgdXNlZC4KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgcmVzb2x2ZVByZWZpeChSZXN1bHRUcmVlSGFuZGxlciByaGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwcmVmaXgsIFN0cmluZyBub2RlTmFtZXNwYWNlKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBwcmVmaXggJiYgKHByZWZpeC5sZW5ndGgoKSA9PSAwIHx8IHByZWZpeC5lcXVhbHMoInhtbG5zIikpKQotICAgIHsKLSAgICAgIC8vIFNpbmNlIHdlIGNhbid0IHVzZSBkZWZhdWx0IG5hbWVzcGFjZSwgaW4gdGhpcyBjYXNlIHdlIHRyeSBhbmQgCi0gICAgICAvLyBzZWUgaWYgYSBwcmVmaXggaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkIG9yIHRoaXMgbmFtZXNwYWNlLgotICAgICAgcHJlZml4ID0gcmhhbmRsZXIuZ2V0UHJlZml4KG5vZGVOYW1lc3BhY2UpOwotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm5zUHJlZml4OiAiK25zUHJlZml4KTsgICAgICAgICAgIAotICAgICAgaWYgKG51bGwgPT0gcHJlZml4IHx8IHByZWZpeC5sZW5ndGgoKSA9PSAwIHx8IHByZWZpeC5lcXVhbHMoInhtbG5zIikpCi0gICAgICB7Ci0gICAgICAgIGlmKG5vZGVOYW1lc3BhY2UubGVuZ3RoKCkgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgcHJlZml4ID0gcmhhbmRsZXIuZ2V0TmV3VW5pcXVlTlNQcmVmaXgoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICB9Ci0gICAgfQotICAgIHJldHVybiBwcmVmaXg7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBWYWxpZGF0ZSB0aGF0IHRoZSBub2RlIG5hbWUgaXMgZ29vZC4KLSAgICogCi0gICAqIEBwYXJhbSBub2RlTmFtZSBOYW1lIG9mIHRoZSBub2RlIGJlaW5nIGNvbnN0cnVjdGVkLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSBuYW1lIGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UuCi0gICAqLwotICAgcHJvdGVjdGVkIGJvb2xlYW4gdmFsaWRhdGVOb2RlTmFtZShTdHJpbmcgbm9kZU5hbWUpCi0gICB7Ci0gICAgICBpZihudWxsID09IG5vZGVOYW1lKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICBpZihub2RlTmFtZS5lcXVhbHMoInhtbG5zIikpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIHJldHVybiBzdXBlci52YWxpZGF0ZU5vZGVOYW1lKG5vZGVOYW1lKTsKLSAgIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBub2RlIGluIHRoZSByZXN1bHQgdHJlZS4gIFRoaXMgbWV0aG9kIGlzIG92ZXJsb2FkZWQgYnkgCi0gICAqIHhzbDphdHRyaWJ1dGUuIEF0IHRoaXMgY2xhc3MgbGV2ZWwsIHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBub2RlLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IGZvciB0aGUgbmFtZXNwYWNlLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIG5vZGVOYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvZiB0aGUgbm9kZSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgY29uc3RydWN0Tm9kZSgKLSAgICAgICAgICBTdHJpbmcgbm9kZU5hbWUsIFN0cmluZyBwcmVmaXgsIFN0cmluZyBub2RlTmFtZXNwYWNlLCBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYobnVsbCAhPSBub2RlTmFtZSAmJiBub2RlTmFtZS5sZW5ndGgoKSA+IDApCi0gICAgewotICAgICAgUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotICAgICAgaWYocHJlZml4ICE9IG51bGwgJiYgcHJlZml4Lmxlbmd0aCgpID4gMCkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICByaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCBub2RlTmFtZXNwYWNlLCBmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goU0FYRXhjZXB0aW9uIHNlKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgU3RyaW5nIHZhbCA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVRvU3RyaW5nKHRoaXMpOwotICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IFFOYW1lLmdldExvY2FsUGFydChub2RlTmFtZSk7Ci0gICAgICByaGFuZGxlci5hZGRBdHRyaWJ1dGUobm9kZU5hbWVzcGFjZSwgbG9jYWxOYW1lLCBub2RlTmFtZSwgIkNEQVRBIiwgdmFsKTsKLSAgICB9Ci0gIH0KLQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICogPCFFTEVNRU5UIHhzbDphdHRyaWJ1dGUgJWNoYXItdGVtcGxhdGU7PgotICAgKiA8IUFUVExJU1QgeHNsOmF0dHJpYnV0ZQotICAgKiAgIG5hbWUgJWF2dDsgI1JFUVVJUkVECi0gICAqICAgbmFtZXNwYWNlICVhdnQ7ICNJTVBMSUVECi0gICAqICAgJXNwYWNlLWF0dDsKLSAgICogPgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYXBwZW5kIHRvIHRoZSBsaXN0IG9mIHRoaXMgbm9kZSdzIGNoaWxkcmVuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgd2UganVzdCBhcHBlbmRlZCB0byB0aGUgY2hpbGRyZW4gbGlzdCAKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGFwcGVuZENoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgbmV3Q2hpbGQpCi0gIHsKLQotICAgIGludCB0eXBlID0gKChFbGVtVGVtcGxhdGVFbGVtZW50KSBuZXdDaGlsZCkuZ2V0WFNMVG9rZW4oKTsKLQotICAgIHN3aXRjaCAodHlwZSkKLSAgICB7Ci0KLSAgICAvLyBjaGFyLWluc3RydWN0aW9ucyAKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVCA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQVBQTFlfVEVNUExBVEVTIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9BUFBMWV9JTVBPUlRTIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9DQUxMVEVNUExBVEUgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0ZPUkVBQ0ggOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX1ZBTFVFT0YgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0NPUFlfT0YgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX05VTUJFUiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQ0hPT1NFIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9JRiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfVEVYVCA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQ09QWSA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfVkFSSUFCTEUgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX01FU1NBR0UgOgotCi0gICAgICAvLyBpbnN0cnVjdGlvbnMgCi0gICAgICAvLyBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9QSToKLSAgICAgIC8vIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0NPTU1FTlQ6Ci0gICAgICAvLyBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9FTEVNRU5UOgotICAgICAgLy8gY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQVRUUklCVVRFOgotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0FERCwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbmV3Q2hpbGQuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXROb2RlTmFtZSgpIH0pOyAgLy8iQ2FuIG5vdCBhZGQgIiArKChFbGVtVGVtcGxhdGVFbGVtZW50KW5ld0NoaWxkKS5tX2VsZW1OYW1lICsKLQotICAgIC8vIiB0byAiICsgdGhpcy5tX2VsZW1OYW1lKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3VwZXIuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUF0dHJpYnV0ZVNldC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1BdHRyaWJ1dGVTZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDM5ZmUzNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUF0dHJpYnV0ZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmF0dHJpYnV0ZS1zZXQuCi0gKiA8cHJlPgotICogJmFtcDshRUxFTUVOVCB4c2w6YXR0cmlidXRlLXNldCAoeHNsOmF0dHJpYnV0ZSkqPgotICogJmFtcDshQVRUTElTVCB4c2w6YXR0cmlidXRlLXNldAotICogICBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gKiAgIHVzZS1hdHRyaWJ1dGUtc2V0cyAlcW5hbWVzOyAjSU1QTElFRAotICogJmFtcDsKLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2F0dHJpYnV0ZS1zZXRzIj5hdHRyaWJ1dGUtc2V0cyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtQXR0cmlidXRlU2V0IGV4dGVuZHMgRWxlbVVzZQotewotCi0gIC8qKgotICAgKiBUaGUgbmFtZSBhdHRyaWJ1dGUgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgc2V0LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwdWJsaWMgUU5hbWUgbV9xbmFtZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogVGhlIG5hbWUgYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHNldC4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBhdHRyaWJ1dGUgdG8gc2V0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKFFOYW1lIG5hbWUpCi0gIHsKLSAgICBtX3FuYW1lID0gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBuYW1lIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5hbWUgYXR0cmlidXRlIG9mIHRoZSBhdHRyaWJ1dGUgc2V0Ci0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9xbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVG9rZW4gSUQgb2YgdGhlIGVsZW1lbnQgCi0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfREVGSU5FQVRUUklCVVRFU0VUOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0FUVFJJQlVURVNFVF9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQXBwbHkgYSBzZXQgb2YgYXR0cmlidXRlcyB0byB0aGUgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZSgKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHRyYW5zZm9ybWVyLmlzUmVjdXJzaXZlQXR0clNldCh0aGlzKSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oCi0gICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX1hTTEFUVFJTRVRfVVNFRF9JVFNFTEYsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBtX3FuYW1lLmdldExvY2FsUGFydCgpIH0pKTsgIC8vInhzbDphdHRyaWJ1dGUtc2V0ICciK21fcW5hbWUubV9sb2NhbHBhcnQrCi0gICAgfQotCi0gICAgdHJhbnNmb3JtZXIucHVzaEVsZW1BdHRyaWJ1dGVTZXQodGhpcyk7Ci0gICAgc3VwZXIuZXhlY3V0ZSh0cmFuc2Zvcm1lcik7Ci0KLSAgICBFbGVtQXR0cmlidXRlIGF0dHIgPSAoRWxlbUF0dHJpYnV0ZSkgZ2V0Rmlyc3RDaGlsZEVsZW0oKTsKLQotICAgIHdoaWxlIChudWxsICE9IGF0dHIpCi0gICAgewotICAgICAgYXR0ci5leGVjdXRlKHRyYW5zZm9ybWVyKTsKLQotICAgICAgYXR0ciA9IChFbGVtQXR0cmlidXRlKSBhdHRyLmdldE5leHRTaWJsaW5nRWxlbSgpOwotICAgIH0KLQotICAgIHRyYW5zZm9ybWVyLnBvcEVsZW1BdHRyaWJ1dGVTZXQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICogPCFFTEVNRU5UIHhzbDphdHRyaWJ1dGUtc2V0ICh4c2w6YXR0cmlidXRlKSo+Ci0gICAqIDwhQVRUTElTVCB4c2w6YXR0cmlidXRlLXNldAotICAgKiAgIG5hbWUgJXFuYW1lOyAjUkVRVUlSRUQKLSAgICogICB1c2UtYXR0cmlidXRlLXNldHMgJXFuYW1lczsgI0lNUExJRUQKLSAgICogPgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYmUgYWRkZWQgdG8gdGhpcyBub2RlJ3MgbGlzdCBvZiBjaGlsZHJlbgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjaGlsZCB0aGF0IHdhcyBqdXN0IGFkZGVkIHRvIHRoZSBsaXN0IG9mIGNoaWxkcmVuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlRWxlbWVudCBhcHBlbmRDaGlsZEVsZW0oRWxlbVRlbXBsYXRlRWxlbWVudCBuZXdDaGlsZCkKLSAgewotCi0gICAgaW50IHR5cGUgPSAoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG5ld0NoaWxkKS5nZXRYU0xUb2tlbigpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9BVFRSSUJVVEUgOgotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0FERCwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbmV3Q2hpbGQuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXROb2RlTmFtZSgpIH0pOyAgLy8iQ2FuIG5vdCBhZGQgIiArKChFbGVtVGVtcGxhdGVFbGVtZW50KW5ld0NoaWxkKS5tX2VsZW1OYW1lICsKLQotICAgIC8vIiB0byAiICsgdGhpcy5tX2VsZW1OYW1lKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3VwZXIuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGR1cmluZyByZWNvbXBvc2l0aW9uIHRvCi0gICAqIGNvbnRyb2wgaG93IHRoaXMgZWxlbWVudCBpcyBjb21wb3NlZC4KLSAgICogQHBhcmFtIHJvb3QgVGhlIHJvb3Qgc3R5bGVzaGVldCBmb3IgdGhpcyB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlY29tcG9zZShTdHlsZXNoZWV0Um9vdCByb290KQotICB7Ci0gICAgcm9vdC5yZWNvbXBvc2VBdHRyaWJ1dGVTZXRzKHRoaXMpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ2FsbFRlbXBsYXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUNhbGxUZW1wbGF0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMDc0Y2I3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ2FsbFRlbXBsYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNzIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguVmFyaWFibGVTdGFjazsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCB4c2w6Y2FsbC10ZW1wbGF0ZS4KLSAqIDxwcmU+Ci0gKiAmYW1wOyFFTEVNRU5UIHhzbDpjYWxsLXRlbXBsYXRlICh4c2w6d2l0aC1wYXJhbSkqPgotICogJmFtcDshQVRUTElTVCB4c2w6Y2FsbC10ZW1wbGF0ZQotICogICBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gKiAmYW1wOwotICogPC9wcmU+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbmFtZWQtdGVtcGxhdGVzIj5uYW1lZC10ZW1wbGF0ZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbUNhbGxUZW1wbGF0ZSBleHRlbmRzIEVsZW1Gb3JFYWNoCi17Ci0KLSAgLyoqCi0gICAqIEFuIHhzbDpjYWxsLXRlbXBsYXRlIGVsZW1lbnQgaW52b2tlcyBhIHRlbXBsYXRlIGJ5IG5hbWU7Ci0gICAqIGl0IGhhcyBhIHJlcXVpcmVkIG5hbWUgYXR0cmlidXRlIHRoYXQgaWRlbnRpZmllcyB0aGUgdGVtcGxhdGUgdG8gYmUgaW52b2tlZC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHVibGljIFFOYW1lIG1fdGVtcGxhdGVOYW1lID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAibmFtZSIgYXR0cmlidXRlLgotICAgKiBBbiB4c2w6Y2FsbC10ZW1wbGF0ZSBlbGVtZW50IGludm9rZXMgYSB0ZW1wbGF0ZSBieSBuYW1lOwotICAgKiBpdCBoYXMgYSByZXF1aXJlZCBuYW1lIGF0dHJpYnV0ZSB0aGF0IGlkZW50aWZpZXMgdGhlIHRlbXBsYXRlIHRvIGJlIGludm9rZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgYXR0cmlidXRlIHRvIHNldAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TmFtZShRTmFtZSBuYW1lKQotICB7Ci0gICAgbV90ZW1wbGF0ZU5hbWUgPSBuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogQW4geHNsOmNhbGwtdGVtcGxhdGUgZWxlbWVudCBpbnZva2VzIGEgdGVtcGxhdGUgYnkgbmFtZTsKLSAgICogaXQgaGFzIGEgcmVxdWlyZWQgbmFtZSBhdHRyaWJ1dGUgdGhhdCBpZGVudGlmaWVzIHRoZSB0ZW1wbGF0ZSB0byBiZSBpbnZva2VkLgotICAgKgotICAgKiBAcmV0dXJuIE5hbWUgYXR0cmlidXRlIG9mIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIFFOYW1lIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fdGVtcGxhdGVOYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB0ZW1wbGF0ZSB3aGljaCBpcyBuYW1lZCBieSBRTmFtZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBFbGVtVGVtcGxhdGUgbV90ZW1wbGF0ZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudCAKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0WFNMVG9rZW4oKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9DQUxMVEVNUExBVEU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5hbWUgb2YgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfQ0FMTFRFTVBMQVRFX1NUUklORzsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICAKLSAgICAvLyBDYWxsIGNvbXBvc2Ugb24gZWFjaCBwYXJhbSBubyBtYXR0ZXIgaWYgdGhpcyBpcyBhcHBseS10ZW1wbGF0ZXMgCi0gICAgLy8gb3IgY2FsbCB0ZW1wbGF0ZXMuCi0gICAgaW50IGxlbmd0aCA9IGdldFBhcmFtRWxlbUNvdW50KCk7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgCi0gICAgewotICAgICAgRWxlbVdpdGhQYXJhbSBld3AgPSBnZXRQYXJhbUVsZW0oaSk7Ci0gICAgICBld3AuY29tcG9zZShzcm9vdCk7Ci0gICAgfQotICAgIAotICAgIGlmICgobnVsbCAhPSBtX3RlbXBsYXRlTmFtZSkgJiYgKG51bGwgPT0gbV90ZW1wbGF0ZSkpCi0gICAgewotICAgICAgbV90ZW1wbGF0ZSA9Ci0gICAgICAgIHRoaXMuZ2V0U3R5bGVzaGVldFJvb3QoKS5nZXRUZW1wbGF0ZUNvbXBvc2VkKG1fdGVtcGxhdGVOYW1lKTsKLSAgICAgICAgCi0gICAgICBpZihudWxsID09IG1fdGVtcGxhdGUpCi0gICAgICAgIHJldHVybjsgLy8gJVJFVklFVyUgZXJyb3I/Ci0gICAgCi0gICAgICBsZW5ndGggPSBnZXRQYXJhbUVsZW1Db3VudCgpOwotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgCi0gICAgICB7Ci0gICAgICAgIEVsZW1XaXRoUGFyYW0gZXdwID0gZ2V0UGFyYW1FbGVtKGkpOwotICAgICAgICBld3AubV9pbmRleCA9IC0xOwotICAgICAgICAvLyBGaW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgcGFyYW0gaW4gdGhlIHRlbXBsYXRlIGJlaW5nIGNhbGxlZCwgCi0gICAgICAgIC8vIGFuZCBzZXQgdGhlIGluZGV4IG9mIHRoZSBwYXJhbSBzbG90LgotICAgICAgICBpbnQgZXRlUG9zID0gMDsKLSAgICAgICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IGV0ZSA9IG1fdGVtcGxhdGUuZ2V0Rmlyc3RDaGlsZEVsZW0oKTsgCi0gICAgICAgICAgICAgbnVsbCAhPSBldGU7IGV0ZSA9IGV0ZS5nZXROZXh0U2libGluZ0VsZW0oKSkgCi0gICAgICAgIHsKLSAgICAgICAgICBpZihldGUuZ2V0WFNMVG9rZW4oKSA9PSBDb25zdGFudHMuRUxFTU5BTUVfUEFSQU1WQVJJQUJMRSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBFbGVtUGFyYW0gZXAgPSAoRWxlbVBhcmFtKWV0ZTsKLSAgICAgICAgICAgIGlmKGVwLmdldE5hbWUoKS5lcXVhbHMoZXdwLmdldE5hbWUoKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGV3cC5tX2luZGV4ID0gZXRlUG9zOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICBldGVQb3MrKzsKLSAgICAgICAgfQotICAgICAgICAKLSAgICAgIH0KLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGFmdGVyIHRoZSB0ZW1wbGF0ZSdzIGNoaWxkcmVuIGhhdmUgYmVlbiBjb21wb3NlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZENvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaW50IGxlbmd0aCA9IGdldFBhcmFtRWxlbUNvdW50KCk7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgCi0gICAgewotICAgICAgRWxlbVdpdGhQYXJhbSBld3AgPSBnZXRQYXJhbUVsZW0oaSk7Ci0gICAgICBld3AuZW5kQ29tcG9zZShzcm9vdCk7Ci0gICAgfSAgICAKLSAgICAKLSAgICBzdXBlci5lbmRDb21wb3NlKHNyb290KTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnZva2UgYSBuYW1lZCB0ZW1wbGF0ZS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I25hbWVkLXRlbXBsYXRlcyI+bmFtZWQtdGVtcGxhdGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZSgKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3RlbXBsYXRlKQotICAgIHsKLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotICAgICAgVmFyaWFibGVTdGFjayB2YXJzID0geGN0eHQuZ2V0VmFyU3RhY2soKTsKLQotICAgICAgaW50IHRoaXNmcmFtZSA9IHZhcnMuZ2V0U3RhY2tGcmFtZSgpOwotICAgICAgaW50IG5leHRGcmFtZSA9IHZhcnMubGluayhtX3RlbXBsYXRlLm1fZnJhbWVTaXplKTsKLSAgICAgIAotICAgICAgLy8gV2UgaGF2ZSB0byBjbGVhciB0aGUgc2VjdGlvbiBvZiB0aGUgc3RhY2sgZnJhbWUgdGhhdCBoYXMgcGFyYW1zIAotICAgICAgLy8gc28gdGhhdCB0aGUgZGVmYXVsdCBwYXJhbSBldmFsdWF0aW9uIHdpbGwgd29yayBjb3JyZWN0bHkuCi0gICAgICBpZihtX3RlbXBsYXRlLm1faW5BcmdzU2l6ZSA+IDApCi0gICAgICB7Ci0gICAgICAgIHZhcnMuY2xlYXJMb2NhbFNsb3RzKDAsIG1fdGVtcGxhdGUubV9pbkFyZ3NTaXplKTsKLSAgICAgIAotICAgICAgICBpZihudWxsICE9IG1fcGFyYW1FbGVtcykKLSAgICAgICAgewotICAgICAgICAgIGludCBjdXJyZW50Tm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICAgICAgdmFycy5zZXRTdGFja0ZyYW1lKHRoaXNmcmFtZSk7Ci0gICAgICAgICAgaW50IHNpemUgPSBtX3BhcmFtRWxlbXMubGVuZ3RoOwotICAgICAgICAgIAotICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSAKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBFbGVtV2l0aFBhcmFtIGV3cCA9IG1fcGFyYW1FbGVtc1tpXTsKLSAgICAgICAgICAgIGlmKGV3cC5tX2luZGV4ID49IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFhPYmplY3Qgb2JqID0gZXdwLmdldFZhbHVlKHRyYW5zZm9ybWVyLCBjdXJyZW50Tm9kZSk7Ci0gICAgICAgICAgICAgIAotICAgICAgICAgICAgICAvLyBOb3RlIGhlcmUgdGhhdCB0aGUgaW5kZXggZm9yIEVsZW1XaXRoUGFyYW0gbXVzdCBoYXZlIGJlZW4gCi0gICAgICAgICAgICAgIC8vIHN0YXRpY2FsbHkgbWFkZSByZWxhdGl2ZSB0byB0aGUgeHNsOnRlbXBsYXRlIGJlaW5nIGNhbGxlZCwgCi0gICAgICAgICAgICAgIC8vIE5PVCB0aGlzIHhzbDp0ZW1wbGF0ZS4KLSAgICAgICAgICAgICAgdmFycy5zZXRMb2NhbFZhcmlhYmxlKGV3cC5tX2luZGV4LCBvYmosIG5leHRGcmFtZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShuZXh0RnJhbWUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIFNvdXJjZUxvY2F0b3Igc2F2ZWRMb2NhdG9yID0geGN0eHQuZ2V0U0FYTG9jYXRvcigpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQuc2V0U0FYTG9jYXRvcihtX3RlbXBsYXRlKTsKLQotICAgICAgICAvLyB0ZW1wbGF0ZS5leGVjdXRlQ2hpbGRUZW1wbGF0ZXModHJhbnNmb3JtZXIsIHNvdXJjZU5vZGUsIG1vZGUsIHRydWUpOwotICAgICAgICB0cmFuc2Zvcm1lci5wdXNoRWxlbVRlbXBsYXRlRWxlbWVudChtX3RlbXBsYXRlKTsKLSAgICAgICAgbV90ZW1wbGF0ZS5leGVjdXRlKHRyYW5zZm9ybWVyKTsKLSAgICAgIH0KLSAgICAgIGZpbmFsbHkKLSAgICAgIHsKLSAgICAgICAgdHJhbnNmb3JtZXIucG9wRWxlbVRlbXBsYXRlRWxlbWVudCgpOwotICAgICAgICB4Y3R4dC5zZXRTQVhMb2NhdG9yKHNhdmVkTG9jYXRvcik7Ci0gICAgICAgIHZhcnMudW5saW5rKCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICB0cmFuc2Zvcm1lci5nZXRNc2dNZ3IoKS5lcnJvcih0aGlzLCBYU0xURXJyb3JSZXNvdXJjZXMuRVJfVEVNUExBVEVfTk9UX0ZPVU5ELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBtX3RlbXBsYXRlTmFtZSB9KTsgIC8vIkNvdWxkIG5vdCBmaW5kIHRlbXBsYXRlIG5hbWVkOiAnIit0ZW1wbGF0ZU5hbWUrIiciKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKiBWZWN0b3Igb2YgeHNsOnBhcmFtIGVsZW1lbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuIAotICAgKiAgQHNlcmlhbCAqLwotICBwcm90ZWN0ZWQgRWxlbVdpdGhQYXJhbVtdIG1fcGFyYW1FbGVtcyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY291bnQgeHNsOnBhcmFtIGVsZW1lbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB4c2w6cGFyYW0gZWxlbWVudHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFBhcmFtRWxlbUNvdW50KCkKLSAgewotICAgIHJldHVybiAobV9wYXJhbUVsZW1zID09IG51bGwpID8gMCA6IG1fcGFyYW1FbGVtcy5sZW5ndGg7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgeHNsOnBhcmFtIGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgZWxlbWVudCB0byBmaW5kCi0gICAqCi0gICAqIEByZXR1cm4geHNsOnBhcmFtIGVsZW1lbnQgYXQgZ2l2ZW4gaW5kZXgKLSAgICovCi0gIHB1YmxpYyBFbGVtV2l0aFBhcmFtIGdldFBhcmFtRWxlbShpbnQgaSkKLSAgewotICAgIHJldHVybiBtX3BhcmFtRWxlbXNbaV07Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgeHNsOnBhcmFtIGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIFBhcmFtRWxlbSB4c2w6cGFyYW0gZWxlbWVudCB0byBzZXQuIAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyYW1FbGVtKEVsZW1XaXRoUGFyYW0gUGFyYW1FbGVtKQotICB7Ci0gICAgaWYgKG51bGwgPT0gbV9wYXJhbUVsZW1zKQotICAgIHsKLSAgICAgIG1fcGFyYW1FbGVtcyA9IG5ldyBFbGVtV2l0aFBhcmFtWzFdOwotICAgICAgbV9wYXJhbUVsZW1zWzBdID0gUGFyYW1FbGVtOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gRXhwZW5zaXZlIDEgYXQgYSB0aW1lIGdyb3d0aCwgYnV0IHRoaXMgaXMgZG9uZSBhdCBidWlsZCB0aW1lLCBzbyAKLSAgICAgIC8vIEkgdGhpbmsgaXQncyBPSy4KLSAgICAgIGludCBsZW5ndGggPSBtX3BhcmFtRWxlbXMubGVuZ3RoOwotICAgICAgRWxlbVdpdGhQYXJhbVtdIGV3cCA9IG5ldyBFbGVtV2l0aFBhcmFtW2xlbmd0aCArIDFdOwotICAgICAgU3lzdGVtLmFycmF5Y29weShtX3BhcmFtRWxlbXMsIDAsIGV3cCwgMCwgbGVuZ3RoKTsKLSAgICAgIG1fcGFyYW1FbGVtcyA9IGV3cDsKLSAgICAgIGV3cFtsZW5ndGhdID0gUGFyYW1FbGVtOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICogPCFFTEVNRU5UIHhzbDphcHBseS10ZW1wbGF0ZXMgKHhzbDpzb3J0fHhzbDp3aXRoLXBhcmFtKSo+Ci0gICAqIDwhQVRUTElTVCB4c2w6YXBwbHktdGVtcGxhdGVzCi0gICAqICAgc2VsZWN0ICVleHByOyAibm9kZSgpIgotICAgKiAgIG1vZGUgJXFuYW1lOyAjSU1QTElFRAotICAgKiA+Ci0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBDaGlsZCB0byBhZGQgdG8gdGhpcyBub2RlJ3MgY2hpbGRyZW4gbGlzdAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjaGlsZCB0aGF0IHdhcyBqdXN0IGFkZGVkIHRoZSBjaGlsZHJlbiBsaXN0IAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXBwZW5kQ2hpbGQoRWxlbVRlbXBsYXRlRWxlbWVudCBuZXdDaGlsZCkKLSAgewotCi0gICAgaW50IHR5cGUgPSAoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG5ld0NoaWxkKS5nZXRYU0xUb2tlbigpOwotCi0gICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9XSVRIUEFSQU0gPT0gdHlwZSkKLSAgICB7Ci0gICAgICBzZXRQYXJhbUVsZW0oKEVsZW1XaXRoUGFyYW0pIG5ld0NoaWxkKTsKLSAgICB9Ci0KLSAgICAvLyBZb3Ugc3RpbGwgaGF2ZSB0byBhcHBlbmQsIGJlY2F1c2UgdGhpcyBlbGVtZW50IGNhbgotICAgIC8vIGNvbnRhaW4gYSBmb3ItZWFjaCwgYW5kIG90aGVyIGVsZW1lbnRzLgotICAgIHJldHVybiBzdXBlci5hcHBlbmRDaGlsZChuZXdDaGlsZCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ2hvb3NlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUNob29zZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzODVkOWZmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ2hvb3NlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5TZWxlY3Rpb25FdmVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDpjaG9vc2UuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpjaG9vc2UgKHhzbDp3aGVuKywgeHNsOm90aGVyd2lzZT8pPgotICogPCFBVFRMSVNUIHhzbDpjaG9vc2UgJXNwYWNlLWF0dDs+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNvbmRpdGlvbmFsLVByb2Nlc3Npbmctd2l0aC14c2w6Y2hvb3NlIj5YWFggaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbUNob29zZSBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfQ0hPT1NFOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50J3MgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0NIT09TRV9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRWxlbUNob29zZQotICAgKgotICAgKi8KLSAgcHVibGljIEVsZW1DaG9vc2UoKXt9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIHhzbDpjaG9vc2UgdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0KLSAgICBmb3IgKEVsZW1UZW1wbGF0ZUVsZW1lbnQgY2hpbGRFbGVtID0gZ2V0Rmlyc3RDaGlsZEVsZW0oKTsKLSAgICAgICAgICAgIGNoaWxkRWxlbSAhPSBudWxsOyBjaGlsZEVsZW0gPSBjaGlsZEVsZW0uZ2V0TmV4dFNpYmxpbmdFbGVtKCkpCi0gICAgewotICAgICAgaW50IHR5cGUgPSBjaGlsZEVsZW0uZ2V0WFNMVG9rZW4oKTsKLQotICAgICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9XSEVOID09IHR5cGUpCi0gICAgICB7Ci0gICAgICAgIGZvdW5kID0gdHJ1ZTsKLQotICAgICAgICBFbGVtV2hlbiB3aGVuID0gKEVsZW1XaGVuKSBjaGlsZEVsZW07Ci0KLSAgICAgICAgLy8gbXVzdCBiZSB4c2w6d2hlbgotICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICAgICAgaW50IHNvdXJjZU5vZGUgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotCi0gICAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgewotICAgICAgICAgIFhPYmplY3QgdGVzdCA9IHdoZW4uZ2V0VGVzdCgpLmV4ZWN1dGUoeGN0eHQsIHNvdXJjZU5vZGUsIHdoZW4pOwotCi0gICAgICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVNlbGVjdGVkRXZlbnQoc291cmNlTm9kZSwgd2hlbiwKLSAgICAgICAgICAgICAgICAgICAgInRlc3QiLCB3aGVuLmdldFRlc3QoKSwgdGVzdCk7Ci0KLSAgICAgICAgICBpZiAodGVzdC5ib29sKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQod2hlbik7Ci0gICAgICAgICAgICB0cmFuc2Zvcm1lci5leGVjdXRlQ2hpbGRUZW1wbGF0ZXMod2hlbiwgdHJ1ZSk7Ci0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICh3aGVuLmdldFRlc3QoKS5ib29sKHhjdHh0LCBzb3VyY2VOb2RlLCB3aGVuKSkKLSAgICAgICAgewotICAgICAgICAgIHRyYW5zZm9ybWVyLmV4ZWN1dGVDaGlsZFRlbXBsYXRlcyh3aGVuLCB0cnVlKTsKLQotICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSBpZiAoQ29uc3RhbnRzLkVMRU1OQU1FX09USEVSV0lTRSA9PSB0eXBlKQotICAgICAgewotICAgICAgICBmb3VuZCA9IHRydWU7Ci0KLSAgICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KGNoaWxkRWxlbSk7Ci0KLSAgICAgICAgLy8geHNsOm90aGVyd2lzZSAgICAgICAgICAgICAgICAKLSAgICAgICAgdHJhbnNmb3JtZXIuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKGNoaWxkRWxlbSwgdHJ1ZSk7Ci0KLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotICAgIH0KLQotICAgIGlmICghZm91bmQpCi0gICAgICB0cmFuc2Zvcm1lci5nZXRNc2dNZ3IoKS5lcnJvcigKLSAgICAgICAgdGhpcywgWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NIT09TRV9SRVFVSVJFU19XSEVOKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIENoaWxkIHRvIGFkZCB0byB0aGlzIG5vZGUncyBjaGlsZCBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNoaWxkIHRoYXQgd2FzIGp1c3QgYWRkZWQgdG8gdGhlIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGFwcGVuZENoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgbmV3Q2hpbGQpCi0gIHsKLQotICAgIGludCB0eXBlID0gKChFbGVtVGVtcGxhdGVFbGVtZW50KSBuZXdDaGlsZCkuZ2V0WFNMVG9rZW4oKTsKLQotICAgIHN3aXRjaCAodHlwZSkKLSAgICB7Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfV0hFTiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfT1RIRVJXSVNFIDoKLQotICAgICAgLy8gVE9ETzogUG9zaXRpb25hbCBjaGVja2luZwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0FERCwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbmV3Q2hpbGQuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXROb2RlTmFtZSgpIH0pOyAgLy8iQ2FuIG5vdCBhZGQgIiArKChFbGVtVGVtcGxhdGVFbGVtZW50KW5ld0NoaWxkKS5tX2VsZW1OYW1lICsKLQotICAgIC8vIiB0byAiICsgdGhpcy5tX2VsZW1OYW1lKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3VwZXIuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUNvbW1lbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ29tbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOTZmOGFiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ29tbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmNvbW1lbnQuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpjb21tZW50ICVjaGFyLXRlbXBsYXRlOz4KLSAqIDwhQVRUTElTVCB4c2w6Y29tbWVudCAlc3BhY2UtYXR0Oz4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ3JlYXRpbmctQ29tbWVudHMiPnNlY3Rpb24tQ3JlYXRpbmctQ29tbWVudHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbUNvbW1lbnQgZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0NPTU1FTlQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBlbGVtZW50J3MgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0NPTU1FTlRfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIHhzbDpjb21tZW50IHRyYW5zZm9ybWF0aW9uIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgICAgLy8gTm90ZSB0aGUgY29udGVudCBtb2RlbCBpczoKLSAgICAgIC8vIDwhRU5USVRZICUgaW5zdHJ1Y3Rpb25zICIKLSAgICAgIC8vICVjaGFyLWluc3RydWN0aW9uczsKLSAgICAgIC8vIHwgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24KLSAgICAgIC8vIHwgeHNsOmNvbW1lbnQKLSAgICAgIC8vIHwgeHNsOmVsZW1lbnQKLSAgICAgIC8vIHwgeHNsOmF0dHJpYnV0ZQotICAgICAgLy8gIj4KLSAgICAgIFN0cmluZyBkYXRhID0gdHJhbnNmb3JtZXIudHJhbnNmb3JtVG9TdHJpbmcodGhpcyk7Ci0KLSAgICAgIHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkuY29tbWVudChkYXRhKTsKLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIGNoaWxkIHRvIHRoZSBjaGlsZCBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYWRkIHRvIHRoaXMgbm9kZSdzIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHJldHVybiBDaGlsZCB0aGF0IHdhcyBqdXN0IGFkZGVkIHRvIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGFwcGVuZENoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgbmV3Q2hpbGQpCi0gIHsKLQotICAgIGludCB0eXBlID0gKChFbGVtVGVtcGxhdGVFbGVtZW50KSBuZXdDaGlsZCkuZ2V0WFNMVG9rZW4oKTsKLQotICAgIHN3aXRjaCAodHlwZSkKLSAgICB7Ci0KLSAgICAvLyBjaGFyLWluc3RydWN0aW9ucyAKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVCA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQVBQTFlfVEVNUExBVEVTIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9BUFBMWV9JTVBPUlRTIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9DQUxMVEVNUExBVEUgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0ZPUkVBQ0ggOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX1ZBTFVFT0YgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0NPUFlfT0YgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX05VTUJFUiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQ0hPT1NFIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9JRiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfVEVYVCA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQ09QWSA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfVkFSSUFCTEUgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX01FU1NBR0UgOgotCi0gICAgICAvLyBpbnN0cnVjdGlvbnMgCi0gICAgICAvLyBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9QSToKLSAgICAgIC8vIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0NPTU1FTlQ6Ci0gICAgICAvLyBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9FTEVNRU5UOgotICAgICAgLy8gY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQVRUUklCVVRFOgotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0FERCwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbmV3Q2hpbGQuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXROb2RlTmFtZSgpIH0pOyAgLy8iQ2FuIG5vdCBhZGQgIiArKChFbGVtVGVtcGxhdGVFbGVtZW50KW5ld0NoaWxkKS5tX2VsZW1OYW1lICsKLQotICAgIC8vIiB0byAiICsgdGhpcy5tX2VsZW1OYW1lKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc3VwZXIuYXBwZW5kQ2hpbGQobmV3Q2hpbGQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUNvcHkuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ29weS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZGEwZDVhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtQ29weS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTkwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5DbG9uZXJUb1Jlc3VsdFRyZWU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDpjb3B5LgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6Y29weSAldGVtcGxhdGU7PgotICogPCFBVFRMSVNUIHhzbDpjb3B5Ci0gKiAgICVzcGFjZS1hdHQ7Ci0gKiAgIHVzZS1hdHRyaWJ1dGUtc2V0cyAlcW5hbWVzOyAjSU1QTElFRAotICogPgotICogPC9wcmU+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29weWluZyI+Y29weWluZyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtQ29weSBleHRlbmRzIEVsZW1Vc2UKLXsKLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50IAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0NPUFk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBlbGVtZW50J3MgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0NPUFlfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB4c2w6Y29weSBlbGVtZW50IHByb3ZpZGVzIGFuIGVhc3kgd2F5IG9mIGNvcHlpbmcgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICogRXhlY3V0aW5nIHRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgbm9kZSBpbnRvIHRoZQotICAgKiByZXN1bHQgdHJlZS4KLSAgICogPHA+VGhlIG5hbWVzcGFjZSBub2RlcyBvZiB0aGUgY3VycmVudCBub2RlIGFyZSBhdXRvbWF0aWNhbGx5Ci0gICAqIGNvcGllZCBhcyB3ZWxsLCBidXQgdGhlIGF0dHJpYnV0ZXMgYW5kIGNoaWxkcmVuIG9mIHRoZSBub2RlIGFyZSBub3QKLSAgICogYXV0b21hdGljYWxseSBjb3BpZWQuIFRoZSBjb250ZW50IG9mIHRoZSB4c2w6Y29weSBlbGVtZW50IGlzIGEKLSAgICogdGVtcGxhdGUgZm9yIHRoZSBhdHRyaWJ1dGVzIGFuZCBjaGlsZHJlbiBvZiB0aGUgY3JlYXRlZCBub2RlOwotICAgKiB0aGUgY29udGVudCBpcyBpbnN0YW50aWF0ZWQgb25seSBmb3Igbm9kZXMgb2YgdHlwZXMgdGhhdCBjYW4gaGF2ZQotICAgKiBhdHRyaWJ1dGVzIG9yIGNoaWxkcmVuIChpLmUuIHJvb3Qgbm9kZXMgYW5kIGVsZW1lbnQgbm9kZXMpLjwvcD4KLSAgICogPHA+VGhlIHJvb3Qgbm9kZSBpcyB0cmVhdGVkIHNwZWNpYWxseSBiZWNhdXNlIHRoZSByb290IG5vZGUgb2YgdGhlCi0gICAqIHJlc3VsdCB0cmVlIGlzIGNyZWF0ZWQgaW1wbGljaXRseS4gV2hlbiB0aGUgY3VycmVudCBub2RlIGlzIHRoZQotICAgKiByb290IG5vZGUsIHhzbDpjb3B5IHdpbGwgbm90IGNyZWF0ZSBhIHJvb3Qgbm9kZSwgYnV0IHdpbGwganVzdCB1c2UKLSAgICogdGhlIGNvbnRlbnQgdGVtcGxhdGUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgICAgICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgICAKLSAgICB0cnkKLSAgICB7Ci0gICAgICBpbnQgc291cmNlTm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoc291cmNlTm9kZSk7Ci0gICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKHNvdXJjZU5vZGUpOwotICAgICAgc2hvcnQgbm9kZVR5cGUgPSBkdG0uZ2V0Tm9kZVR5cGUoc291cmNlTm9kZSk7Ci0KLSAgICAgIGlmICgoRFRNLkRPQ1VNRU5UX05PREUgIT0gbm9kZVR5cGUpICYmIChEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSAhPSBub2RlVHlwZSkpCi0gICAgICB7Ci0gICAgICAgIFJlc3VsdFRyZWVIYW5kbGVyIHJ0aGFuZGxlciA9IHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCk7Ci0KLSAgICAgICAgLy8gVE9ETzogUHJvY2VzcyB0aGUgdXNlLWF0dHJpYnV0ZS1zZXRzIHN0dWZmCi0gICAgICAgIENsb25lclRvUmVzdWx0VHJlZS5jbG9uZVRvUmVzdWx0VHJlZShzb3VyY2VOb2RlLCBub2RlVHlwZSwgZHRtLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ0aGFuZGxlciwgZmFsc2UpOwotCi0gICAgICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IG5vZGVUeXBlKQotICAgICAgICB7Ci0gICAgICAgICAgc3VwZXIuZXhlY3V0ZSh0cmFuc2Zvcm1lcik7Ci0gICAgICAgICAgcnRoYW5kbGVyLnByb2Nlc3NOU0RlY2xzKHNvdXJjZU5vZGUsIG5vZGVUeXBlLCBkdG0pOwotICAgICAgICAgIHRyYW5zZm9ybWVyLmV4ZWN1dGVDaGlsZFRlbXBsYXRlcyh0aGlzLCB0cnVlKTsKLSAgICAgICAgICAKLSAgICAgICAgICBTdHJpbmcgbnMgPSBkdG0uZ2V0TmFtZXNwYWNlVVJJKHNvdXJjZU5vZGUpOwotICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSBkdG0uZ2V0TG9jYWxOYW1lKHNvdXJjZU5vZGUpOwotICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkuZW5kRWxlbWVudChucywgbG9jYWxOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdG0uZ2V0Tm9kZU5hbWUoc291cmNlTm9kZSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgICAgICBzdXBlci5leGVjdXRlKHRyYW5zZm9ybWVyKTsKLSAgICAgICAgdHJhbnNmb3JtZXIuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKHRoaXMsIHRydWUpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICB9Ci0gICAgICAgICAgICAgICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUNvcHlPZi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1Db3B5T2YuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGZhZmQxZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUNvcHlPZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS4qOwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTVRyZWVXYWxrZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhY2UuU2VsZWN0aW9uRXZlbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJlZVdhbGtlcjJSZXN1bHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5SZXN1bHRUcmVlSGFuZGxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmNvcHktb2YuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpjb3B5LW9mIEVNUFRZPgotICogPCFBVFRMSVNUIHhzbDpjb3B5LW9mIHNlbGVjdCAlZXhwcjsgI1JFUVVJUkVEPgotICogPC9wcmU+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29weS1vZiI+Y29weS1vZiBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtQ29weU9mIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBUaGUgcmVxdWlyZWQgc2VsZWN0IGF0dHJpYnV0ZSBjb250YWlucyBhbiBleHByZXNzaW9uLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwdWJsaWMgWFBhdGggbV9zZWxlY3RFeHByZXNzaW9uID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuCi0gICAqIFRoZSByZXF1aXJlZCBzZWxlY3QgYXR0cmlidXRlIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEBwYXJhbSBleHByIEV4cHJlc3Npb24gZm9yIHNlbGVjdCBhdHRyaWJ1dGUgCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTZWxlY3QoWFBhdGggZXhwcikKLSAgewotICAgIG1fc2VsZWN0RXhwcmVzc2lvbiA9IGV4cHI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuCi0gICAqIFRoZSByZXF1aXJlZCBzZWxlY3QgYXR0cmlidXRlIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEByZXR1cm4gRXhwcmVzc2lvbiBmb3Igc2VsZWN0IGF0dHJpYnV0ZSAKLSAgICovCi0gIHB1YmxpYyBYUGF0aCBnZXRTZWxlY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fc2VsZWN0RXhwcmVzc2lvbjsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICAKLSAgICBTdHlsZXNoZWV0Um9vdC5Db21wb3NlU3RhdGUgY3N0YXRlID0gc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCk7Ci0gICAgbV9zZWxlY3RFeHByZXNzaW9uLmZpeHVwVmFyaWFibGVzKGNzdGF0ZS5nZXRWYXJpYWJsZU5hbWVzKCksIGNzdGF0ZS5nZXRHbG9iYWxzU2l6ZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRva2VuIElEIGZvciB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0WFNMVG9rZW4oKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9DT1BZX09GOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50J3MgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0NPUFlfT0ZfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB4c2w6Y29weS1vZiBlbGVtZW50IGNhbiBiZSB1c2VkIHRvIGluc2VydCBhIHJlc3VsdCB0cmVlCi0gICAqIGZyYWdtZW50IGludG8gdGhlIHJlc3VsdCB0cmVlLCB3aXRob3V0IGZpcnN0IGNvbnZlcnRpbmcgaXQgdG8KLSAgICogYSBzdHJpbmcgYXMgeHNsOnZhbHVlLW9mIGRvZXMgKHNlZSBbNy42LjEgR2VuZXJhdGluZyBUZXh0IHdpdGgKLSAgICogeHNsOnZhbHVlLW9mXSkuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotICAgICAgaW50IHNvdXJjZU5vZGUgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgWE9iamVjdCB2YWx1ZSA9IG1fc2VsZWN0RXhwcmVzc2lvbi5leGVjdXRlKHhjdHh0LCBzb3VyY2VOb2RlLCB0aGlzKTsKLQotICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlU2VsZWN0ZWRFdmVudChzb3VyY2VOb2RlLCB0aGlzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2VsZWN0IiwgbV9zZWxlY3RFeHByZXNzaW9uLCB2YWx1ZSk7Ci0KLSAgICAgIFJlc3VsdFRyZWVIYW5kbGVyIGhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotCi0gICAgICBpZiAobnVsbCAhPSB2YWx1ZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgaW50IHR5cGUgPSB2YWx1ZS5nZXRUeXBlKCk7Ci0gICAgICAgIFN0cmluZyBzOwotCi0gICAgICAgIHN3aXRjaCAodHlwZSkKLSAgICAgICAgewotICAgICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfQk9PTEVBTiA6Ci0gICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19OVU1CRVIgOgotICAgICAgICBjYXNlIFhPYmplY3QuQ0xBU1NfU1RSSU5HIDoKLSAgICAgICAgICBzID0gdmFsdWUuc3RyKCk7Ci0KLSAgICAgICAgICBoYW5kbGVyLmNoYXJhY3RlcnMocy50b0NoYXJBcnJheSgpLCAwLCBzLmxlbmd0aCgpKTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBYT2JqZWN0LkNMQVNTX05PREVTRVQgOgotCi0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKHZhbHVlKTsKLSAgICAgICAgICBEVE1JdGVyYXRvciBubCA9IHZhbHVlLml0ZXIoKTsKLQotICAgICAgICAgIC8vIENvcHkgdGhlIHRyZWUuCi0gICAgICAgICAgRFRNVHJlZVdhbGtlciB0dyA9IG5ldyBUcmVlV2Fsa2VyMlJlc3VsdCh0cmFuc2Zvcm1lciwgaGFuZGxlcik7Ci0gICAgICAgICAgaW50IHBvczsKLQotICAgICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAocG9zID0gbmwubmV4dE5vZGUoKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTU1hbmFnZXIoKS5nZXREVE0ocG9zKTsKLSAgICAgICAgICAgIHNob3J0IHQgPSBkdG0uZ2V0Tm9kZVR5cGUocG9zKTsKLQotICAgICAgICAgICAgLy8gSWYgd2UganVzdCBjb3B5IHRoZSB3aG9sZSBkb2N1bWVudCwgYSBzdGFydERvYyBhbmQgZW5kRG9jIGdldCAKLSAgICAgICAgICAgIC8vIGdlbmVyYXRlZCwgc28gd2UgbmVlZCB0byBvbmx5IHdhbGsgdGhlIGNoaWxkIG5vZGVzLgotICAgICAgICAgICAgaWYgKHQgPT0gRFRNLkRPQ1VNRU5UX05PREUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGZvciAoaW50IGNoaWxkID0gZHRtLmdldEZpcnN0Q2hpbGQocG9zKTsgY2hpbGQgIT0gRFRNLk5VTEw7Ci0gICAgICAgICAgICAgICAgICAgY2hpbGQgPSBkdG0uZ2V0TmV4dFNpYmxpbmcoY2hpbGQpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdHcudHJhdmVyc2UoY2hpbGQpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICh0ID09IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaGFuZGxlci5hZGRBdHRyaWJ1dGUocG9zKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdHcudHJhdmVyc2UocG9zKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgLy8gbmwuZGV0YWNoKCk7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgWE9iamVjdC5DTEFTU19SVFJFRUZSQUcgOgotICAgICAgICAgIGhhbmRsZXIub3V0cHV0UmVzdWx0VHJlZUZyYWdtZW50KHZhbHVlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpKTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgCi0gICAgICAgICAgcyA9IHZhbHVlLnN0cigpOwotCi0gICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKHMudG9DaGFyQXJyYXkoKSwgMCwgcy5sZW5ndGgoKSk7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgLy8gSSBkb24ndCB0aGluayB3ZSB3YW50IHRoaXMuICAtc2IKLSAgICAgIC8vICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICAvLyAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVNlbGVjdGVkRXZlbnQoc291cmNlTm9kZSwgdGhpcywKLSAgICAgIC8vICAiZW5kU2VsZWN0IiwgbV9zZWxlY3RFeHByZXNzaW9uLCB2YWx1ZSk7Ci0KLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogQWRkIGEgY2hpbGQgdG8gdGhlIGNoaWxkIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBDaGlsZCB0byBhZGQgdG8gdGhpcyBub2RlJ3MgY2hpbGQgbGlzdAotICAgKgotICAgKiBAcmV0dXJuIENoaWxkIGp1c3QgYWRkZWQgdG8gY2hpbGQgbGlzdAotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXBwZW5kQ2hpbGQoRWxlbVRlbXBsYXRlRWxlbWVudCBuZXdDaGlsZCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9BREQsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBuZXdDaGlsZC5nZXROb2RlTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXROb2RlTmFtZSgpIH0pOyAgLy8iQ2FuIG5vdCBhZGQgIiArKChFbGVtVGVtcGxhdGVFbGVtZW50KW5ld0NoaWxkKS5tX2VsZW1OYW1lICsKLQotICAgIC8vIiB0byAiICsgdGhpcy5tX2VsZW1OYW1lKTsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FbGVtZW50LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmE1OGY1Ni4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5SZXN1bHRUcmVlSGFuZGxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmVsZW1lbnQKLSAqIDxwcmU+Ci0gKiA8IUVMRU1FTlQgeHNsOmVsZW1lbnQgJXRlbXBsYXRlOz4KLSAqIDwhQVRUTElTVCB4c2w6ZWxlbWVudAotICogICBuYW1lICVhdnQ7ICNSRVFVSVJFRAotICogICBuYW1lc3BhY2UgJWF2dDsgI0lNUExJRUQKLSAqICAgdXNlLWF0dHJpYnV0ZS1zZXRzICVxbmFtZXM7ICNJTVBMSUVECi0gKiAgICVzcGFjZS1hdHQ7Ci0gKiA+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNyZWF0aW5nLUVsZW1lbnRzLXdpdGgteHNsOmVsZW1lbnQiPlhYWCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtRWxlbWVudCBleHRlbmRzIEVsZW1Vc2UKLXsKLQotICAvKioKLSAgICogVGhlIG5hbWUgYXR0cmlidXRlIGlzIGludGVycHJldGVkIGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZS4KLSAgICogSXQgaXMgYW4gZXJyb3IgaWYgdGhlIHN0cmluZyB0aGF0IHJlc3VsdHMgZnJvbSBpbnN0YW50aWF0aW5nIHRoZQotICAgKiBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUgaXMgbm90IGEgUU5hbWUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBBVlQgbV9uYW1lX2F2dCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogVGhlIG5hbWUgYXR0cmlidXRlIGlzIGludGVycHJldGVkIGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZS4KLSAgICogSXQgaXMgYW4gZXJyb3IgaWYgdGhlIHN0cmluZyB0aGF0IHJlc3VsdHMgZnJvbSBpbnN0YW50aWF0aW5nIHRoZQotICAgKiBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUgaXMgbm90IGEgUU5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSB2IE5hbWUgYXR0cmlidXRlIHRvIHNldCBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKEFWVCB2KQotICB7Ci0gICAgbV9uYW1lX2F2dCA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAibmFtZSIgYXR0cmlidXRlLgotICAgKiBUaGUgbmFtZSBhdHRyaWJ1dGUgaXMgaW50ZXJwcmV0ZWQgYXMgYW4gYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlLgotICAgKiBJdCBpcyBhbiBlcnJvciBpZiB0aGUgc3RyaW5nIHRoYXQgcmVzdWx0cyBmcm9tIGluc3RhbnRpYXRpbmcgdGhlCi0gICAqIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSBpcyBub3QgYSBRTmFtZS4KLSAgICoKLSAgICogQHJldHVybiBOYW1lIGF0dHJpYnV0ZSBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgQVZUIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fbmFtZV9hdnQ7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhlIG5hbWVzcGFjZSBhdHRyaWJ1dGUgaXMgcHJlc2VudCwgdGhlbiBpdCBhbHNvIGlzIGludGVycHJldGVkCi0gICAqIGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZS4gVGhlIHN0cmluZyB0aGF0IHJlc3VsdHMgZnJvbQotICAgKiBpbnN0YW50aWF0aW5nIHRoZSBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUgc2hvdWxkIGJlIGEgVVJJIHJlZmVyZW5jZS4KLSAgICogSXQgaXMgbm90IGFuIGVycm9yIGlmIHRoZSBzdHJpbmcgaXMgbm90IGEgc3ludGFjdGljYWxseSBsZWdhbCBVUkkgcmVmZXJlbmNlLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgQVZUIG1fbmFtZXNwYWNlX2F2dCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm5hbWVzcGFjZSIgYXR0cmlidXRlLgotICAgKiBJZiB0aGUgbmFtZXNwYWNlIGF0dHJpYnV0ZSBpcyBwcmVzZW50LCB0aGVuIGl0IGFsc28gaXMgaW50ZXJwcmV0ZWQKLSAgICogYXMgYW4gYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlLiBUaGUgc3RyaW5nIHRoYXQgcmVzdWx0cyBmcm9tCi0gICAqIGluc3RhbnRpYXRpbmcgdGhlIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSBzaG91bGQgYmUgYSBVUkkgcmVmZXJlbmNlLgotICAgKiBJdCBpcyBub3QgYW4gZXJyb3IgaWYgdGhlIHN0cmluZyBpcyBub3QgYSBzeW50YWN0aWNhbGx5IGxlZ2FsIFVSSSByZWZlcmVuY2UuCi0gICAqCi0gICAqIEBwYXJhbSB2IE5hbWVTcGFjZSBhdHRyaWJ1dGUgdG8gc2V0IGZvciB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5hbWVzcGFjZShBVlQgdikKLSAgewotICAgIG1fbmFtZXNwYWNlX2F2dCA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAibmFtZXNwYWNlIiBhdHRyaWJ1dGUuCi0gICAqIElmIHRoZSBuYW1lc3BhY2UgYXR0cmlidXRlIGlzIHByZXNlbnQsIHRoZW4gaXQgYWxzbyBpcyBpbnRlcnByZXRlZAotICAgKiBhcyBhbiBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUuIFRoZSBzdHJpbmcgdGhhdCByZXN1bHRzIGZyb20KLSAgICogaW5zdGFudGlhdGluZyB0aGUgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIHNob3VsZCBiZSBhIFVSSSByZWZlcmVuY2UuCi0gICAqIEl0IGlzIG5vdCBhbiBlcnJvciBpZiB0aGUgc3RyaW5nIGlzIG5vdCBhIHN5bnRhY3RpY2FsbHkgbGVnYWwgVVJJIHJlZmVyZW5jZS4KLSAgICoKLSAgICogQHJldHVybiBOYW1lc3BhY2UgYXR0cmlidXRlIGZvciB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBBVlQgZ2V0TmFtZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX25hbWVzcGFjZV9hdnQ7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciBldmVyeXRoaW5nIGVsc2UgaGFzIGJlZW4KLSAgICogcmVjb21wb3NlZCwgYW5kIGFsbG93cyB0aGUgdGVtcGxhdGUgdG8gc2V0IHJlbWFpbmluZwotICAgKiB2YWx1ZXMgdGhhdCBtYXkgYmUgYmFzZWQgb24gc29tZSBvdGhlciBwcm9wZXJ0eSB0aGF0Ci0gICAqIGRlcGVuZHMgb24gcmVjb21wb3NpdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuY29tcG9zZShzcm9vdCk7Ci0gICAgCi0gICAgU3R5bGVzaGVldFJvb3QuQ29tcG9zZVN0YXRlIGNzdGF0ZSA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpOwotICAgIGphdmEudXRpbC5WZWN0b3Igdm5hbWVzID0gY3N0YXRlLmdldFZhcmlhYmxlTmFtZXMoKTsKLSAgICBpZihudWxsICE9IG1fbmFtZV9hdnQpCi0gICAgICBtX25hbWVfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV9uYW1lc3BhY2VfYXZ0KQotICAgICAgbV9uYW1lc3BhY2VfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfRUxFTUVOVDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIGVsZW1lbnQncyBuYW1lIAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0VMRU1FTlRfU1RSSU5HOwotICB9Ci0gIAotICAvKioKLSAgICogVmFsaWRhdGUgdGhhdCB0aGUgbm9kZSBuYW1lIGlzIGdvb2QuCi0gICAqIAotICAgKiBAcGFyYW0gbm9kZU5hbWUgTmFtZSBvZiB0aGUgbm9kZSBiZWluZyBjb25zdHJ1Y3RlZCwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG5vZGUgbmFtZSBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKi8KLSAgIHByb3RlY3RlZCBib29sZWFuIHZhbGlkYXRlTm9kZU5hbWUoU3RyaW5nIG5vZGVOYW1lKQotICAgewotICAgIGlmKG5vZGVOYW1lID09IG51bGwpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICBpbnQgbGVuID0gbm9kZU5hbWUubGVuZ3RoKCk7Ci0gICAgCi0gICAgaWYobGVuID09IDApCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAKLSAgICBpbnQgaW5kZXhPZk5TU2VwID0gbm9kZU5hbWUuaW5kZXhPZignOicpOwotCi0gICAgaWYoaW5kZXhPZk5TU2VwICsgMSA9PSBsZW4pCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAKLSAgICBpZihpbmRleE9mTlNTZXAgPT0gMCkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIAotICAgIFN0cmluZyBsb2NhbE5hbWUgPSBRTmFtZS5nZXRMb2NhbFBhcnQobm9kZU5hbWUpOwotICAgICAgCi0gICAgaWYoaXNWYWxpZE5DTmFtZShsb2NhbE5hbWUpKQotICAgIHsKLSAgICAgIFN0cmluZyBwcmVmaXggPSBRTmFtZS5nZXRQcmVmaXhQYXJ0KG5vZGVOYW1lKTsKLSAgICAgIGlmKHByZWZpeC5sZW5ndGgoKSA9PSAwKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIGlmKGlzVmFsaWROQ05hbWUocHJlZml4KSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICAgfQotICAgCi0gIC8qKgotICAgKiBSZXNvbHZlIHRoZSBuYW1lc3BhY2UgaW50byBhIHByZWZpeC4gIE1lYW50IHRvIGJlCi0gICAqIG92ZXJpZGRlZCBieSBlbGVtQXR0cmlidXRlIGlmIHRoaXMgY2xhc3MgaXMgZGVyaXZlZC4KLSAgICoKLSAgICogQHBhcmFtIHJoYW5kbGVyIFRoZSBjdXJyZW50IHJlc3VsdCB0cmVlIGhhbmRsZXIuCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByb2JhYmxlIHByZWZpeCBpZiBhbHJlYWR5IGtub3duLgotICAgKiBAcGFyYW0gbm9kZU5hbWVzcGFjZSAgVGhlIG5hbWVzcGFjZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcHJlZml4IHRvIGJlIHVzZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIHJlc29sdmVQcmVmaXgoUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbm9kZU5hbWVzcGFjZSkKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0vLyAgICBpZiAobnVsbCAhPSBwcmVmaXggJiYgcHJlZml4Lmxlbmd0aCgpID09IDApCi0vLyAgICB7Ci0vLyAgICAgIFN0cmluZyBmb3VuZFByZWZpeCA9IHJoYW5kbGVyLmdldFByZWZpeChub2RlTmFtZXNwYWNlKTsKLS8vCi0vLyAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibnNQcmVmaXg6ICIrbnNQcmVmaXgpOyAgICAgICAgICAgCi0vLyAgICAgIGlmIChudWxsID09IGZvdW5kUHJlZml4KQotLy8gICAgICAgIGZvdW5kUHJlZml4ID0gIiI7Ci0vLyAgICB9Ci0gICAgcmV0dXJuIHByZWZpeDsKLSAgfQotICAgIAotICAvKioKLSAgICogQ3JlYXRlIGFuIGVsZW1lbnQgaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgKiBUaGUgeHNsOmVsZW1lbnQgZWxlbWVudCBhbGxvd3MgYW4gZWxlbWVudCB0byBiZSBjcmVhdGVkIHdpdGggYQotICAgKiBjb21wdXRlZCBuYW1lLiBUaGUgZXhwYW5kZWQtbmFtZSBvZiB0aGUgZWxlbWVudCB0byBiZSBjcmVhdGVkCi0gICAqIGlzIHNwZWNpZmllZCBieSBhIHJlcXVpcmVkIG5hbWUgYXR0cmlidXRlIGFuZCBhbiBvcHRpb25hbCBuYW1lc3BhY2UKLSAgICogYXR0cmlidXRlLiBUaGUgY29udGVudCBvZiB0aGUgeHNsOmVsZW1lbnQgZWxlbWVudCBpcyBhIHRlbXBsYXRlCi0gICAqIGZvciB0aGUgYXR0cmlidXRlcyBhbmQgY2hpbGRyZW4gb2YgdGhlIGNyZWF0ZWQgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZSgKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotICAgIGludCBzb3VyY2VOb2RlID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBTdHJpbmcgbm9kZU5hbWUgPSBtX25hbWVfYXZ0LmV2YWx1YXRlKHhjdHh0LCBzb3VyY2VOb2RlLCB0aGlzKTsKLQotICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgIFN0cmluZyBub2RlTmFtZXNwYWNlID0gIiI7Ci0KLSAgICBpZiAoIXZhbGlkYXRlTm9kZU5hbWUobm9kZU5hbWUpKQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmdldE1zZ01ncigpLndhcm4oCi0gICAgICAgIHRoaXMsIFhTTFRFcnJvclJlc291cmNlcy5XR19JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBDb25zdGFudHMuQVRUUk5BTUVfTkFNRSwgbm9kZU5hbWUgfSk7Ci0KLSAgICAgIG5vZGVOYW1lID0gbnVsbDsKLSAgICB9Ci0KLSAgICBlbHNlCi0gICAgewotICAgICAgcHJlZml4ID0gUU5hbWUuZ2V0UHJlZml4UGFydChub2RlTmFtZSk7Ci0KLSAgICAgIGlmIChudWxsICE9IG1fbmFtZXNwYWNlX2F2dCkKLSAgICAgIHsKLSAgICAgICAgbm9kZU5hbWVzcGFjZSA9IG1fbmFtZXNwYWNlX2F2dC5ldmFsdWF0ZSh4Y3R4dCwgc291cmNlTm9kZSwgdGhpcyk7Ci0gICAgICAgIGlmIChudWxsID09IG5vZGVOYW1lc3BhY2UgfHwgCi0gICAgICAgICAgICAocHJlZml4ICE9IG51bGwgJiYgcHJlZml4Lmxlbmd0aCgpPjAgJiYgbm9kZU5hbWVzcGFjZS5sZW5ndGgoKT09IDApICkKLSAgICAgICAgICB0cmFuc2Zvcm1lci5nZXRNc2dNZ3IoKS5lcnJvcigKLSAgICAgICAgICAgICAgdGhpcywgWFNMVEVycm9yUmVzb3VyY2VzLkVSX05VTExfVVJJX05BTUVTUEFDRSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGFjdHVhbCBwcmVmaXggdGhhdCB3ZSB3aWxsIHVzZSBmb3IgdGhpcyBub2RlTmFtZXNwYWNlCi0KLSAgICAgICAgcHJlZml4ID0gcmVzb2x2ZVByZWZpeChyaGFuZGxlciwgcHJlZml4LCBub2RlTmFtZXNwYWNlKTsKLSAgICAgICAgaWYgKG51bGwgPT0gcHJlZml4KQotICAgICAgICAgIHByZWZpeCA9ICIiOwotCi0gICAgICAgIGlmIChwcmVmaXgubGVuZ3RoKCkgPiAwKQotICAgICAgICAgIG5vZGVOYW1lID0gKHByZWZpeCArICI6IiArIFFOYW1lLmdldExvY2FsUGFydChub2RlTmFtZSkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgbm9kZU5hbWUgPSBRTmFtZS5nZXRMb2NhbFBhcnQobm9kZU5hbWUpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIE5vIG5hbWVzcGFjZSBhdHRyaWJ1dGUgd2FzIHN1cHBsaWVkLiBVc2UgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKLSAgICAgIC8vIGN1cnJlbnRseSBpbiBlZmZlY3QgZm9yIHRoZSB4c2w6ZWxlbWVudCBlbGVtZW50LgotICAgICAgZWxzZSAgICAKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAvLyBNYXliZSB0ZW1wb3JhcnksIHVudGlsIEkgZ2V0IHRoaXMgd29ya2VkIG91dC4gIHRlc3Q6IGF4ZXM1OQotICAgICAgICAgIG5vZGVOYW1lc3BhY2UgPSBnZXROYW1lc3BhY2VGb3JQcmVmaXgocHJlZml4KTsKLQotICAgICAgICAgIC8vIElmIHdlIGdldCBiYWNrIGEgbnVsbCBub2RlTmFtZXNwYWNlLCB0aGF0IG1lYW5zIHRoYXQgdGhpcyBwcmVmaXggY291bGQKLSAgICAgICAgICAvLyBub3QgYmUgZm91bmQgaW4gdGhlIHRhYmxlLiAgVGhpcyBpcyBva2F5IG9ubHkgZm9yIGEgZGVmYXVsdCBuYW1lc3BhY2UKLSAgICAgICAgICAvLyB0aGF0IGhhcyBuZXZlciBiZWVuIGRlY2xhcmVkLgotCi0gICAgICAgICAgaWYgKCAobnVsbCA9PSBub2RlTmFtZXNwYWNlKSAmJiAocHJlZml4Lmxlbmd0aCgpID09IDApICkKLSAgICAgICAgICAgIG5vZGVOYW1lc3BhY2UgPSAiIjsKLSAgICAgICAgICBlbHNlIGlmIChudWxsID09IG5vZGVOYW1lc3BhY2UpCi0gICAgICAgICAgewotICAgICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0TXNnTWdyKCkud2FybigKLSAgICAgICAgICAgICAgdGhpcywgWFNMVEVycm9yUmVzb3VyY2VzLldHX0NPVUxEX05PVF9SRVNPTFZFX1BSRUZJWCwKLSAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwcmVmaXggfSk7Ci0KLSAgICAgICAgICAgIG5vZGVOYW1lID0gbnVsbDsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQotICAgICAgICB7Ci0gICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0TXNnTWdyKCkud2FybigKLSAgICAgICAgICAgIHRoaXMsIFhTTFRFcnJvclJlc291cmNlcy5XR19DT1VMRF9OT1RfUkVTT0xWRV9QUkVGSVgsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IHByZWZpeCB9KTsKLQotICAgICAgICAgIG5vZGVOYW1lID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIGNvbnN0cnVjdE5vZGUobm9kZU5hbWUsIHByZWZpeCwgbm9kZU5hbWVzcGFjZSwgdHJhbnNmb3JtZXIpOwotICB9Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0IGEgbm9kZSBpbiB0aGUgcmVzdWx0IHRyZWUuICBUaGlzIG1ldGhvZCBpcyBvdmVybG9hZGVkIGJ5IAotICAgKiB4c2w6YXR0cmlidXRlLiBBdCB0aGlzIGNsYXNzIGxldmVsLCB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuIGVsZW1lbnQuCi0gICAqIElmIHRoZSBub2RlIGlzIG51bGwsIHdlIGluc3RhbnRpYXRlIG9ubHkgdGhlIGNvbnRlbnQgb2YgdGhlIG5vZGUgaW4gYWNjb3JkYW5jZQotICAgKiB3aXRoIHNlY3Rpb24gNy4xLjIgb2YgdGhlIFhTTFQgMS4wIFJlY29tbWVuZGF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbm9kZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG5vZGUsIHdoaWNoIG1heSBiZSA8Y29kZT5udWxsPC9jb2RlPi4gIElmIDxjb2RlPm51bGw8L2NvZGU+LAotICAgKiAgICAgICAgICAgICAgICAgb25seSB0aGUgbm9uLWF0dHJpYnV0ZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUgd2lsbCBiZSBwcm9jZXNzZWQuCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBmb3IgdGhlIG5hbWVzcGFjZSwgd2hpY2ggbWF5IGJlIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKiAgICAgICAgICAgICAgIElmIG5vdCA8Y29kZT5udWxsPC9jb2RlPiwgdGhpcyBwcmVmaXggd2lsbCBiZSBtYXBwZWQgYW5kIHVubWFwcGVkLgotICAgKiBAcGFyYW0gbm9kZU5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBub2RlLCB3aGljaCBtYXkgYmUgbm90IGJlIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgdm9pZCBjb25zdHJ1Y3ROb2RlKAotICAgICAgICAgIFN0cmluZyBub2RlTmFtZSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIG5vZGVOYW1lc3BhY2UsIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBib29sZWFuIHNob3VsZEFkZEF0dHJzOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotCi0gICAgICBpZiAobnVsbCA9PSBub2RlTmFtZSkKLSAgICAgIHsKLSAgICAgICAgc2hvdWxkQWRkQXR0cnMgPSBmYWxzZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgLy8gQWRkIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMuCi0gICAgICAgIGV4ZWN1dGVOU0RlY2xzKHRyYW5zZm9ybWVyKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBwcmVmaXgpCi0gICAgICAgIHsKLSAgICAgICAgICByaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCBub2RlTmFtZXNwYWNlLCB0cnVlKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJoYW5kbGVyLnN0YXJ0RWxlbWVudChub2RlTmFtZXNwYWNlLCBRTmFtZS5nZXRMb2NhbFBhcnQobm9kZU5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZU5hbWUsIG51bGwpOwotCi0gICAgICAgIHN1cGVyLmV4ZWN1dGUodHJhbnNmb3JtZXIpOwotCi0gICAgICAgIHNob3VsZEFkZEF0dHJzID0gdHJ1ZTsKLSAgICAgIH0KLQotICAgICAgdHJhbnNmb3JtZXIuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKHRoaXMsIHNob3VsZEFkZEF0dHJzKTsKLQotICAgICAgLy8gTm93IGVuZCB0aGUgZWxlbWVudCBpZiBuYW1lIHdhcyB2YWxpZAotICAgICAgaWYgKG51bGwgIT0gbm9kZU5hbWUpCi0gICAgICB7Ci0gICAgICAgIHJoYW5kbGVyLmVuZEVsZW1lbnQobm9kZU5hbWVzcGFjZSwgUU5hbWUuZ2V0TG9jYWxQYXJ0KG5vZGVOYW1lKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSk7Ci0gICAgICAgIGlmIChudWxsICE9IHByZWZpeCkKLSAgICAgICAgewotICAgICAgICAgIHJoYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgfQotICAgICAgICB1bmV4ZWN1dGVOU0RlY2xzKHRyYW5zZm9ybWVyKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FbXB0eS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FbXB0eS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNGU2NmUzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtRW1wdHkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBTaW1wbGUgZW1wdHkgZWxlbSB0byBwdXNoIG9uIHRoZSBzdGFjayB3aGVuIG5vdGhpbmcKLSAqIGVsc2UgZ290IHB1c2hlZCwgc28gdGhhdCBwb3AoKSB3b3JrcyBjb3JyZWN0bHkuCi0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtRW1wdHkgZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEVsZW1FbXB0eQotICAgKgotICAgKi8KLSAgcHVibGljIEVsZW1FbXB0eSgpe30KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtRXh0ZW5zaW9uQ2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FeHRlbnNpb25DYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE0NTFjZGEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FeHRlbnNpb25DYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MDkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy4qOwotCi1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5hbWVTcGFjZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdUb1N0cmluZ1RhYmxlOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk11dGFibGVBdHRyTGlzdEltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5FeHRlbnNpb25IYW5kbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5FeHRlbnNpb25zVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCBhbiBleHRlbnNpb24gZWxlbWVudC4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNleHRlbnNpb24tZWxlbWVudCI+ZXh0ZW5zaW9uLWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbUV4dGVuc2lvbkNhbGwgZXh0ZW5kcyBFbGVtTGl0ZXJhbFJlc3VsdAotewotCi0gIC8vIEV4dGVuc2lvbk5TSGFuZGxlciBuc2g7Ci0KLSAgLyoqIFRoZSBOYW1lc3BhY2UgVVJJIGZvciB0aGlzIGV4dGVuc2lvbiBjYWxsIGVsZW1lbnQuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIFN0cmluZyBtX2V4dG5zOwotCi0gIC8qKiBMYW5ndWFnZSB1c2VkIGJ5IGV4dGVuc2lvbi4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgU3RyaW5nIG1fbGFuZzsKLQotICAvKiogVVJMIHBvaW50aW5nIHRvIGV4dGVuc2lvbi4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgU3RyaW5nIG1fc3JjVVJMOwotCi0gIC8qKiBTb3VyY2UgZm9yIHNjcmlwdC4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgU3RyaW5nIG1fc2NyaXB0U3JjOwotCi0gIC8qKiBEZWNsYXJhdGlvbiBmb3IgRXh0ZW5zaW9uIGVsZW1lbnQuIAotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBFbGVtRXh0ZW5zaW9uRGVjbCBtX2RlY2wgPSBudWxsOwotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0VYVEVOU0lPTkNBTEw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotCi0gIC8vIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICAvLyB7Ci0gIC8vIFRPRE86IE5lZWQgcHJlZml4LgotICAvLyByZXR1cm4gbG9jYWxQYXJ0OwotICAvLyB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotICAgIG1fZXh0bnMgPSB0aGlzLmdldE5hbWVzcGFjZSgpOwotCi0gICAgU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldCA9IHRoaXMuZ2V0U3R5bGVzaGVldFJvb3QoKTsKLQotICAgIG1fZGVjbCA9IGdldEVsZW1FeHRlbnNpb25EZWNsKHN0eWxlc2hlZXQsIG1fZXh0bnMpOwotCi0gICAgaWYgKG51bGwgIT0gbV9kZWNsKQotICAgIHsKLSAgICAgIGZvciAoRWxlbVRlbXBsYXRlRWxlbWVudCBjaGlsZCA9IG1fZGVjbC5nZXRGaXJzdENoaWxkRWxlbSgpOwotICAgICAgICAgICAgICBjaGlsZCAhPSBudWxsOyBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nRWxlbSgpKQotICAgICAgewotICAgICAgICBpZiAoQ29uc3RhbnRzLkVMRU1OQU1FX0VYVEVOU0lPTlNDUklQVCA9PSBjaGlsZC5nZXRYU0xUb2tlbigpKQotICAgICAgICB7Ci0gICAgICAgICAgRWxlbUV4dGVuc2lvblNjcmlwdCBzZGVjbCA9IChFbGVtRXh0ZW5zaW9uU2NyaXB0KSBjaGlsZDsKLQotICAgICAgICAgIG1fbGFuZyA9IHNkZWNsLmdldExhbmcoKTsKLSAgICAgICAgICBtX3NyY1VSTCA9IHNkZWNsLmdldFNyYygpOwotCi0gICAgICAgICAgRWxlbVRlbXBsYXRlRWxlbWVudCBjaGlsZE9mU0RlY2wgPSBzZGVjbC5nZXRGaXJzdENoaWxkRWxlbSgpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gY2hpbGRPZlNEZWNsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChDb25zdGFudHMuRUxFTU5BTUVfVEVYVExJVEVSQUxSRVNVTFQKLSAgICAgICAgICAgICAgICAgICAgPT0gY2hpbGRPZlNEZWNsLmdldFhTTFRva2VuKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEVsZW1UZXh0TGl0ZXJhbCB0bCA9IChFbGVtVGV4dExpdGVyYWwpIGNoaWxkT2ZTRGVjbDsKLSAgICAgICAgICAgICAgY2hhcltdIGNoYXJzID0gdGwuZ2V0Q2hhcnMoKTsKLQotICAgICAgICAgICAgICBtX3NjcmlwdFNyYyA9IG5ldyBTdHJpbmcoY2hhcnMpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIHN0eWxlc2hlZXQuZXJyb3IoeHh4KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBFbGVtRXh0ZW5zaW9uRGVjbCBmb3IgdGhpcyBleHRlbnNpb24gZWxlbWVudCAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0eWxlc2hlZXQgU3R5bGVzaGVldCByb290IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAqIEBwYXJhbSBuYW1lc3BhY2UgTmFtZXNwYWNlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIEVsZW1FeHRlbnNpb25EZWNsIGZvciB0aGlzIGV4dGVuc2lvbiBlbGVtZW50LiAKLSAgICovCi0gIHByaXZhdGUgRWxlbUV4dGVuc2lvbkRlY2wgZ2V0RWxlbUV4dGVuc2lvbkRlY2woU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldCwKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlKQotICB7Ci0KLSAgICBFbGVtRXh0ZW5zaW9uRGVjbCBkZWNsID0gbnVsbDsKLSAgICBpbnQgbiA9IHN0eWxlc2hlZXQuZ2V0R2xvYmFsSW1wb3J0Q291bnQoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFN0eWxlc2hlZXQgaW1wb3J0ZWQgPSBzdHlsZXNoZWV0LmdldEdsb2JhbEltcG9ydChpKTsKLQotICAgICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IGNoaWxkID0gaW1wb3J0ZWQuZ2V0Rmlyc3RDaGlsZEVsZW0oKTsKLSAgICAgICAgICAgICAgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZ0VsZW0oKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9FWFRFTlNJT05ERUNMID09IGNoaWxkLmdldFhTTFRva2VuKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBkZWNsID0gKEVsZW1FeHRlbnNpb25EZWNsKSBjaGlsZDsKLQotICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBkZWNsLmdldFByZWZpeCgpOwotICAgICAgICAgIFN0cmluZyBkZWNsTmFtZXNwYWNlID0gY2hpbGQuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0KLSAgICAgICAgICBpZiAobmFtZXNwYWNlLmVxdWFscyhkZWNsTmFtZXNwYWNlKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZGVjbDsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZGVjbDsKLSAgfQotICAKLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZhbGxiYWNrcyB3aGVuIGFuIGV4dGVuc2lvbiBpcyBub3QgYXZhaWxhYmxlLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlRmFsbGJhY2tzKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IGNoaWxkID0gbV9maXJzdENoaWxkOyBjaGlsZCAhPSBudWxsOwotICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQubV9uZXh0U2libGluZykKLSAgICB7Ci0gICAgICBpZiAoY2hpbGQuZ2V0WFNMVG9rZW4oKSA9PSBDb25zdGFudHMuRUxFTU5BTUVfRkFMTEJBQ0spCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgdHJhbnNmb3JtZXIucHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQoY2hpbGQpOwotICAgICAgICAgICgoRWxlbUZhbGxiYWNrKSBjaGlsZCkuZXhlY3V0ZUZhbGxiYWNrKHRyYW5zZm9ybWVyKTsKLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICB0cmFuc2Zvcm1lci5wb3BFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gZXh0ZW5zaW9uLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpLmZsdXNoUGVuZGluZygpOwotCi0gICAgICBYUGF0aENvbnRleHQgbGlhaXNvbiA9ICgoWFBhdGhDb250ZXh0KSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKSk7Ci0gICAgICBFeHRlbnNpb25zVGFibGUgZXRhYmxlID0gbGlhaXNvbi5nZXRFeHRlbnNpb25zVGFibGUoKTsKLSAgICAgIEV4dGVuc2lvbkhhbmRsZXIgbnNoID0gZXRhYmxlLmdldChtX2V4dG5zKTsKLQotICAgICAgLy8gV2UncmUgc2VlaW5nIHRoaXMgZXh0ZW5zaW9uIG5hbWVzcGFjZSB1c2VkIGZvciB0aGUgZmlyc3QgdGltZS4gIFRyeSB0bwotICAgICAgLy8gYXV0b2RlY2xhcmUgaXQgYXMgYSBqYXZhIG5hbWVzcGFjZS4KLQotICAgICAgaWYgKG51bGwgPT0gbnNoKQotICAgICAgewotICAgICAgICBuc2ggPSBldGFibGUubWFrZUphdmFOYW1lc3BhY2UobV9leHRucyk7Ci0KLSAgICAgICAgaWYobnVsbCAhPSBuc2gpCi0gICAgICAgICAgZXRhYmxlLmFkZEV4dGVuc2lvbk5hbWVzcGFjZShtX2V4dG5zLCBuc2gpOwotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBleGVjdXRlRmFsbGJhY2tzKHRyYW5zZm9ybWVyKTsKLSAgICAgICAgICByZXR1cm47Ci0gICAgICAgIH0KLQotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgbnNoLnByb2Nlc3NFbGVtZW50KHRoaXMuZ2V0TG9jYWxOYW1lKCksIHRoaXMsIHRyYW5zZm9ybWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3R5bGVzaGVldCgpLCB0aGlzKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLQotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oZSk7Ci0gICAgICAgIC8vIGUucHJpbnR6U3RhY2tUcmFjZSgpOwotICAgICAgICBTdHJpbmcgbXNnID0gZS5nZXRNZXNzYWdlKCk7Ci0gICAgICAgIAotICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZTsKLSAgICAgICAgaWYoZSBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgICB7Ci0gICAgICAgICAgdGUgPSAoVHJhbnNmb3JtZXJFeGNlcHRpb24pZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBpZihudWxsICE9IG1zZykKLSAgICAgICAgICAgIHRlID0gbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHRlID0gbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1VOS05PV05fRVJST1JfQ0FMTElOR19FWFRFTlNJT04sIG51bGwpLCBlKTsgLy8iVW5rbm93biBlcnJvciB3aGVuIGNhbGxpbmcgZXh0ZW5zaW9uISIsIGUpOwotICAgICAgICB9Ci0gICAgICAgIGlmKG51bGwgPT0gdGUuZ2V0TG9jYXRvcigpKQotICAgICAgICAgIHRlLnNldExvY2F0b3IodGhpcyk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbXNnKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG1zZy5pbmRleE9mKCJmYXRhbCIpID49IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpLmZhdGFsRXJyb3IodGUpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmKGUgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKSAgICAgIAotICAgICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpLmVycm9yKHRlKTsgLy8gPz8KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB0cmFuc2Zvcm1lci5nZXRFcnJvckxpc3RlbmVyKCkud2FybmluZyh0ZSk7Ci0KLSAgICAgICAgfQotICAgICAgICBlbHNlICAgICAgCi0gICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpLmVycm9yKHRlKTsgLy8gPz8KLQotICAgICAgICBleGVjdXRlRmFsbGJhY2tzKAotICAgICAgICAgIHRyYW5zZm9ybWVyKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmdldEVycm9yTGlzdGVuZXIoKS5mYXRhbEVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHJhdyB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKgotICAgKiBAcGFyYW0gcmF3TmFtZSBSYXcgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIHRoZSByYXcgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBvciBudWxsIGlmIG5vdCBmb3VuZAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIHJhd05hbWUpCi0gIHsKLQotICAgIEFWVCBhdnQgPSBnZXRMaXRlcmFsUmVzdWx0QXR0cmlidXRlKHJhd05hbWUpOwotCi0gICAgaWYgKChudWxsICE9IGF2dCkgJiYgYXZ0LmdldFJhd05hbWUoKS5lcXVhbHMocmF3TmFtZSkpCi0gICAgewotICAgICAgcmV0dXJuIGF2dC5nZXRTaW1wbGVTdHJpbmcoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaW50ZXJwcmV0ZWQgYXMgYW4gQXR0cmlidXRlCi0gICAqIFZhbHVlIFRlbXBsYXRlIChpbiBvdGhlciB3b3JkcywgeW91IGNhbiB1c2UgY3VybHkgZXhwcmVzc2lvbnMKLSAgICogc3VjaCBhcyBocmVmPSJodHRwOi8ve3dlYnNpdGV9Ii4KLSAgICoKLSAgICogQHBhcmFtIHJhd05hbWUgUmF3IG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSB0byBnZXQKLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlKAotICAgICAgICAgIFN0cmluZyByYXdOYW1lLCBvcmcudzNjLmRvbS5Ob2RlIHNvdXJjZU5vZGUsIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBBVlQgYXZ0ID0gZ2V0TGl0ZXJhbFJlc3VsdEF0dHJpYnV0ZShyYXdOYW1lKTsKLQotICAgIGlmICgobnVsbCAhPSBhdnQpICYmIGF2dC5nZXRSYXdOYW1lKCkuZXF1YWxzKHJhd05hbWUpKQotICAgIHsKLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotCi0gICAgICByZXR1cm4gYXZ0LmV2YWx1YXRlKHhjdHh0LCAKLSAgICAgICAgICAgIHhjdHh0LmdldERUTUhhbmRsZUZyb21Ob2RlKHNvdXJjZU5vZGUpLCAKLSAgICAgICAgICAgIHRoaXMpOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0gIAotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FeHRlbnNpb25EZWNsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUV4dGVuc2lvbkRlY2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzU5OTYzZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUV4dGVuc2lvbkRlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5OYW1lU3BhY2U7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3RyaW5nVG9TdHJpbmdUYWJsZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLkV4dGVuc2lvbkhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLkV4dGVuc2lvbkhhbmRsZXJHZW5lcmFsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5FeHRlbnNpb25zVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogSW1wbGVtZW50IHRoZSBkZWNsYXJhdGlvbiBvZiBhbiBleHRlbnNpb24gZWxlbWVudCAKLSAqLwotcHVibGljIGNsYXNzIEVsZW1FeHRlbnNpb25EZWNsIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBFbGVtRXh0ZW5zaW9uRGVjbAotICAgKgotICAgKi8KLSAgcHVibGljIEVsZW1FeHRlbnNpb25EZWNsKCkKLSAgewotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJFbGVtRXh0ZW5zaW9uRGVjbCBjdG9yIik7Ci0gIH0KLQotICAvKiogUHJlZml4IHN0cmluZyBmb3IgdGhpcyBleHRlbnNpb24gZWxlbWVudC4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX3ByZWZpeCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcHJlZml4IGZvciB0aGlzIGV4dGVuc2lvbiBlbGVtZW50ICAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHYgUHJlZml4IHRvIHNldCBmb3IgdGhpcyBleHRlbnNpb24gZWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyB2KQotICB7Ci0gICAgbV9wcmVmaXggPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcHJlZml4IGZvciB0aGlzIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gUHJlZml4IGZvciB0aGlzIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpCi0gIHsKLSAgICByZXR1cm4gbV9wcmVmaXg7Ci0gIH0KLQotICAvKiogU3RyaW5nVmVjdG9yIGhvbGRpbmcgdGhlIG5hbWVzIG9mIGZ1bmN0aW9ucyBkZWZpbmVkIGluIHRoaXMgZXh0ZW5zaW9uLgotICAgKiAgQHNlcmlhbCAgICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmdWZWN0b3IgbV9mdW5jdGlvbnMgPSBuZXcgU3RyaW5nVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbmFtZXMgb2YgZnVuY3Rpb25zIGRlZmluZWQgaW4gdGhpcyBleHRlbnNpb24gIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gdiBTdHJpbmdWZWN0b3IgaG9sZGluZyB0aGUgbmFtZXMgb2YgZnVuY3Rpb25zIGRlZmluZWQgaW4gdGhpcyBleHRlbnNpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEZ1bmN0aW9ucyhTdHJpbmdWZWN0b3IgdikKLSAgewotICAgIG1fZnVuY3Rpb25zID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWVzIG9mIGZ1bmN0aW9ucyBkZWZpbmVkIGluIHRoaXMgZXh0ZW5zaW9uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nVmVjdG9yIGhvbGRpbmcgdGhlIG5hbWVzIG9mIGZ1bmN0aW9ucyBkZWZpbmVkIGluIHRoaXMgZXh0ZW5zaW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nVmVjdG9yIGdldEZ1bmN0aW9ucygpCi0gIHsKLSAgICByZXR1cm4gbV9mdW5jdGlvbnM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgZnVuY3Rpb24gYXQgYSBnaXZlbiBpbmRleCBpbiB0aGlzIGV4dGVuc2lvbiBlbGVtZW50IAotICAgKgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBmdW5jdGlvbiB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBOYW1lIG9mIEZ1bmN0aW9uIGF0IGdpdmVuIGluZGV4Ci0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEZ1bmN0aW9uKGludCBpKSB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fZnVuY3Rpb25zKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmV0dXJuIChTdHJpbmcpIG1fZnVuY3Rpb25zLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgY291bnQgb2YgZnVuY3Rpb25zIGRlZmluZWQgaW4gdGhpcyBleHRlbnNpb24gZWxlbWVudAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIGNvdW50IG9mIGZ1bmN0aW9ucyBkZWZpbmVkIGluIHRoaXMgZXh0ZW5zaW9uIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RnVuY3Rpb25Db3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9mdW5jdGlvbnMpID8gbV9mdW5jdGlvbnMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKiBTdHJpbmdWZWN0b3Igb2YgZWxlbWVudHMgZGVmaW5lZCBpbiB0aGlzIGV4dGVuc2lvbi4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZ1ZlY3RvciBtX2VsZW1lbnRzID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IFN0cmluZ1ZlY3RvciBvZiBlbGVtZW50cyBmb3IgdGhpcyBleHRlbnNpb24KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHYgU3RyaW5nVmVjdG9yIG9mIGVsZW1lbnRzIHRvIHNldAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RWxlbWVudHMoU3RyaW5nVmVjdG9yIHYpCi0gIHsKLSAgICBtX2VsZW1lbnRzID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgU3RyaW5nVmVjdG9yIG9mIGVsZW1lbnRzIGRlZmluZWQgZm9yIHRoaXMgZXh0ZW5zaW9uICAKLSAgICoKLSAgICoKLSAgICogQHJldHVybiBTdHJpbmdWZWN0b3Igb2YgZWxlbWVudHMgZGVmaW5lZCBmb3IgdGhpcyBleHRlbnNpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmdWZWN0b3IgZ2V0RWxlbWVudHMoKQotICB7Ci0gICAgcmV0dXJuIG1fZWxlbWVudHM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleAotICAgKgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBlbGVtZW50IHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleAotICAgKgotICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFbGVtZW50KGludCBpKSB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fZWxlbWVudHMpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKFN0cmluZykgbV9lbGVtZW50cy5lbGVtZW50QXQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBjb3VudCBvZiBlbGVtZW50cyBkZWZpbmVkIGZvciB0aGlzIGV4dGVuc2lvbiBlbGVtZW50IAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBjb3VudCBvZiBlbGVtZW50cyBkZWZpbmVkIGZvciB0aGlzIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldEVsZW1lbnRDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9lbGVtZW50cykgPyBtX2VsZW1lbnRzLnNpemUoKSA6IDA7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfRVhURU5TSU9OREVDTDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIG9uIHRvcC1sZXZlbCBlbGVtZW50cwotICAgKiBvbmx5LCBqdXN0IGJlZm9yZSB0aGUgdHJhbnNmb3JtIGJlZ2lucy4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIFRoZSBYU0xUIFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcnVudGltZUluaXQoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGxhbmcgPSBudWxsOwotICAgIFN0cmluZyBzcmNVUkwgPSBudWxsOwotICAgIFN0cmluZyBzY3JpcHRTcmMgPSBudWxsOwotICAgIFN0cmluZyBwcmVmaXggPSBnZXRQcmVmaXgoKTsKLSAgICBTdHJpbmcgZGVjbE5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotCi0gICAgaWYgKG51bGwgPT0gZGVjbE5hbWVzcGFjZSkKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19OQU1FU1BBQ0VfREVDTCwgbmV3IE9iamVjdFtde3ByZWZpeH0pKTsgLy8iUHJlZml4ICIgKyBwcmVmaXgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICIgZG9lcyBub3QgaGF2ZSBhIGNvcnJlc3BvbmRpbmcgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIm5hbWVzcGFjZSBkZWNsYXJhdGlvbiIpOwotCi0gICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IGNoaWxkID0gZ2V0Rmlyc3RDaGlsZEVsZW0oKTsgY2hpbGQgIT0gbnVsbDsKLSAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmdFbGVtKCkpCi0gICAgewotICAgICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9FWFRFTlNJT05TQ1JJUFQgPT0gY2hpbGQuZ2V0WFNMVG9rZW4oKSkKLSAgICAgIHsKLSAgICAgICAgRWxlbUV4dGVuc2lvblNjcmlwdCBzZGVjbCA9IChFbGVtRXh0ZW5zaW9uU2NyaXB0KSBjaGlsZDsKLQotICAgICAgICBsYW5nID0gc2RlY2wuZ2V0TGFuZygpOwotICAgICAgICBzcmNVUkwgPSBzZGVjbC5nZXRTcmMoKTsKLQotICAgICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IGNoaWxkT2ZTRGVjbCA9IHNkZWNsLmdldEZpcnN0Q2hpbGRFbGVtKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gY2hpbGRPZlNEZWNsKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVAotICAgICAgICAgICAgICAgICAgPT0gY2hpbGRPZlNEZWNsLmdldFhTTFRva2VuKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgRWxlbVRleHRMaXRlcmFsIHRsID0gKEVsZW1UZXh0TGl0ZXJhbCkgY2hpbGRPZlNEZWNsOwotICAgICAgICAgICAgY2hhcltdIGNoYXJzID0gdGwuZ2V0Q2hhcnMoKTsKLQotICAgICAgICAgICAgc2NyaXB0U3JjID0gbmV3IFN0cmluZyhjaGFycyk7Ci0KLSAgICAgICAgICAgIGlmIChzY3JpcHRTcmMudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgICAgICAgICAgIHNjcmlwdFNyYyA9IG51bGw7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKG51bGwgPT0gbGFuZykKLSAgICAgIGxhbmcgPSAiamF2YWNsYXNzIjsKLQotICAgIGlmIChsYW5nLmVxdWFscygiamF2YWNsYXNzIikgJiYgKHNjcmlwdFNyYyAhPSBudWxsKSkKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9FTEVNX0NPTlRFTlRfTk9UX0FMTE9XRUQsIG5ldyBPYmplY3RbXXtzY3JpcHRTcmN9KSk7IC8vIkVsZW1lbnQgY29udGVudCBub3QgYWxsb3dlZCBmb3IgbGFuZz1qYXZhY2xhc3MgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgc2NyaXB0U3JjKTsKLQotICAgIFhQYXRoQ29udGV4dCBsaWFpc29uID0gKChYUGF0aENvbnRleHQpIHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpKTsKLSAgICBFeHRlbnNpb25zVGFibGUgZXRhYmxlID0gbGlhaXNvbi5nZXRFeHRlbnNpb25zVGFibGUoKTsKLSAgICBFeHRlbnNpb25IYW5kbGVyIG5zaCA9IGV0YWJsZS5nZXQoZGVjbE5hbWVzcGFjZSk7Ci0KLSAgICAvLyBJZiB3ZSBoYXZlIG5vIHByaW9yIEV4dGVuc2lvbkhhbmRsZXIgZm9yIHRoaXMgbmFtZXNwYWNlLCB3ZSBuZWVkIHRvCi0gICAgLy8gY3JlYXRlIG9uZS4KLSAgICAvLyBJZiB0aGUgc2NyaXB0IGVsZW1lbnQgaXMgZm9yIGphdmFjbGFzcywgdGhpcyBpcyBvdXIgc3BlY2lhbCBjb21waWxlZCBqYXZhLgotICAgIC8vIEVsZW1lbnQgY29udGVudCBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIHNvIHdlIHRocm93IGFuIGV4Y2VwdGlvbiBpZgotICAgIC8vIGl0IGlzIHByb3ZpZGVkLiAgT3RoZXJ3aXNlLCB3ZSBsb29rIHVwIHRoZSBzcmNVUkwgdG8gc2VlIGlmIHdlIGFscmVhZHkgaGF2ZQotICAgIC8vIGFuIEV4dGVuc2lvbkhhbmRsZXIuCi0gICAgaWYgKG51bGwgPT0gbnNoKQotICAgIHsKLSAgICAgIGlmIChsYW5nLmVxdWFscygiamF2YWNsYXNzIikpCi0gICAgICB7Ci0gICAgICAgIGlmIChudWxsID09IHNyY1VSTCkKLSAgICAgICAgewotICAgICAgICAgIG5zaCA9IGV0YWJsZS5tYWtlSmF2YU5hbWVzcGFjZShkZWNsTmFtZXNwYWNlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBuc2ggPSBldGFibGUuZ2V0KHNyY1VSTCk7Ci0KLSAgICAgICAgICBpZiAobnVsbCA9PSBuc2gpCi0gICAgICAgICAgewotICAgICAgICAgICAgbnNoID0gZXRhYmxlLm1ha2VKYXZhTmFtZXNwYWNlKHNyY1VSTCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlICAvLyBub3QgamF2YQotICAgICAgewotICAgICAgICBuc2ggPSBuZXcgRXh0ZW5zaW9uSGFuZGxlckdlbmVyYWwoZGVjbE5hbWVzcGFjZSwgdGhpcy5tX2VsZW1lbnRzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tX2Z1bmN0aW9ucywgbGFuZywgc3JjVVJMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0U3JjLCBnZXRTeXN0ZW1JZCgpKTsKLQotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkFkZGluZyBOUyBIYW5kbGVyOiBkZWNsTmFtZXNwYWNlID0gIisKLSAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgZGVjbE5hbWVzcGFjZSsiLCBsYW5nID0gIitsYW5nKyIsIHNyY1VSTCA9ICIrCi0gICAgICAgIC8vICAgICAgICAgICAgICAgICAgIHNyY1VSTCsiLCBzY3JpcHRTcmM9IitzY3JpcHRTcmMpOwotICAgICAgfQotCi0gICAgICBldGFibGUuYWRkRXh0ZW5zaW9uTmFtZXNwYWNlKGRlY2xOYW1lc3BhY2UsIG5zaCk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUV4dGVuc2lvblNjcmlwdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FeHRlbnNpb25TY3JpcHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTZiMjc3Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUV4dGVuc2lvblNjcmlwdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogSW1wbGVtZW50IFNjcmlwdCBleHRlbnNpb24gZWxlbWVudAotICovCi1wdWJsaWMgY2xhc3MgRWxlbUV4dGVuc2lvblNjcmlwdCBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRWxlbUV4dGVuc2lvblNjcmlwdAotICAgKgotICAgKi8KLSAgcHVibGljIEVsZW1FeHRlbnNpb25TY3JpcHQoKQotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkVsZW1FeHRlbnNpb25TY3JpcHQgY3RvciIpOwotICB9Ci0KLSAgLyoqIExhbmd1YWdlIHVzZWQgaW4gZXh0ZW5zaW9uLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX2xhbmcgPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgbGFuZ3VhZ2UgdXNlZCBieSBleHRlbnNpb24KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHYgTGFuZ3VhZ2UgdXNlZCBieSBleHRlbnNpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExhbmcoU3RyaW5nIHYpCi0gIHsKLSAgICBtX2xhbmcgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBsYW5ndWFnZSB1c2VkIGJ5IGV4dGVuc2lvbgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIExhbmd1YWdlIHVzZWQgYnkgZXh0ZW5zaW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExhbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fbGFuZzsKLSAgfQotCi0gIC8qKiBFeHRlbnNpb24gaGFuZGxlci4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9zcmMgPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgRXh0ZW5zaW9uIGhhbmRsZXIgbmFtZSBmb3IgdGhpcyBleHRlbnNpb24KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHYgRXh0ZW5zaW9uIGhhbmRsZXIgbmFtZSB0byBzZXQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNyYyhTdHJpbmcgdikKLSAgewotICAgIG1fc3JjID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgRXh0ZW5zaW9uIGhhbmRsZXIgbmFtZSBmb3IgdGhpcyBleHRlbnNpb24KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBFeHRlbnNpb24gaGFuZGxlciBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFNyYygpCi0gIHsKLSAgICByZXR1cm4gbV9zcmM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBmb3IgdGhpcyBlbGVtZW50IAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0VYVEVOU0lPTlNDUklQVDsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1GYWxsYmFjay5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1GYWxsYmFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0Y2Q2NjkxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtRmFsbGJhY2suamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi0vLyBpbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhY2UuU2VsZWN0aW9uRXZlbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCB4c2w6ZmFsbGJhY2suCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpmYWxsYmFjayAldGVtcGxhdGU7PgotICogPCFBVFRMSVNUIHhzbDpmYWxsYmFjayAlc3BhY2UtYXR0Oz4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2ZhbGxiYWNrIj5mYWxsYmFjayBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtRmFsbGJhY2sgZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0ZBTExCQUNLOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBFbGVtZW50J3MgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0ZBTExCQUNLX1NUUklORzsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGlzIHRoZSBub3JtYWwgY2FsbCB3aGVuIHhzbDpmYWxsYmFjayBpcyBpbnN0YW50aWF0ZWQuCi0gICAqIEluIGFjY29yZGFuY2Ugd2l0aCB0aGUgWFNMVCAxLjAgUmVjb21tZW5kYXRpb24sIGNoYXB0ZXIgMTUsCi0gICAqICJOb3JtYWxseSwgaW5zdGFudGlhdGluZyBhbiB4c2w6ZmFsbGJhY2sgZWxlbWVudCBkb2VzIG5vdGhpbmcuIgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZmFsbGJhY2sgZWxlbWVudHMuICBUaGlzIG11c3QgYmUgZXhwbGljaXRseSBjYWxsZWQgdG8KLSAgICogaW5zdGFudGlhdGUgdGhlIGNvbnRlbnQgb2YgYW4geHNsOmZhbGxiYWNrIGVsZW1lbnQuCi0gICAqIFdoZW4gYW4gWFNMVCB0cmFuc2Zvcm1lciBwZXJmb3JtcyBmYWxsYmFjayBmb3IgYW4gaW5zdHJ1Y3Rpb24KLSAgICogZWxlbWVudCwgaWYgdGhlIGluc3RydWN0aW9uIGVsZW1lbnQgaGFzIG9uZSBvciBtb3JlIHhzbDpmYWxsYmFjawotICAgKiBjaGlsZHJlbiwgdGhlbiB0aGUgY29udGVudCBvZiBlYWNoIG9mIHRoZSB4c2w6ZmFsbGJhY2sgY2hpbGRyZW4KLSAgICogbXVzdCBiZSBpbnN0YW50aWF0ZWQgaW4gc2VxdWVuY2U7IG90aGVyd2lzZSwgYW4gZXJyb3IgbXVzdAotICAgKiBiZSBzaWduYWxlZC4gVGhlIGNvbnRlbnQgb2YgYW4geHNsOmZhbGxiYWNrIGVsZW1lbnQgaXMgYSB0ZW1wbGF0ZS4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZUZhbGxiYWNrKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoQ29uc3RhbnRzLkVMRU1OQU1FX0VYVEVOU0lPTkNBTEwgPT0gbV9wYXJlbnROb2RlLmdldFhTTFRva2VuKCkpCi0gICAgewotCi0gICAgICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotCi0gICAgICB0cmFuc2Zvcm1lci5leGVjdXRlQ2hpbGRUZW1wbGF0ZXModGhpcywgdHJ1ZSk7Ci0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gU2hvdWxkIG5ldmVyIGhhcHBlbgotICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAiRXJyb3IhICBwYXJlbnQgb2YgeHNsOmZhbGxiYWNrIG11c3QgYmUgYW4gZXh0ZW5zaW9uIGVsZW1lbnQhIik7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUZvckVhY2guamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtRm9yRWFjaC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNWRkMGQ4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtRm9yRWFjaC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDcyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS4qOwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNTWFuYWdlcjsKLQotLy8gRXhwZXJlbWVudGFsCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5FeHBhbmRlZE5hbWVUYWJsZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkNvbnRleHROb2RlTGlzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5Ob2RlU29ydGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5TdGFja0d1YXJkOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuQ2xvbmVyVG9SZXN1bHRUcmVlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmZvci1lYWNoLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6Zm9yLWVhY2gKLSAqICAoI1BDREFUQQotICogICAlaW5zdHJ1Y3Rpb25zOwotICogICAlcmVzdWx0LWVsZW1lbnRzOwotICogICB8IHhzbDpzb3J0KQotICogPgotICoKLSAqIDwhQVRUTElTVCB4c2w6Zm9yLWVhY2gKLSAqICAgc2VsZWN0ICVleHByOyAjUkVRVUlSRUQKLSAqICAgJXNwYWNlLWF0dDsKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Zvci1lYWNoIj5mb3ItZWFjaCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtRm9yRWFjaCBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgZWxlbWVudCByZXByZXNlbnRpbmcgeHNsOmZvci1lYWNoLgotICAgKi8KLSAgcHVibGljIEVsZW1Gb3JFYWNoKCl7fQotCi0gIC8qKgotICAgKiBUaGUgInNlbGVjdCIgZXhwcmVzc2lvbi4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbV9zZWxlY3RFeHByZXNzaW9uID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSB4cGF0aCBUaGUgWFBhdGggZXhwcmVzc2lvbiBmb3IgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNlbGVjdChYUGF0aCB4cGF0aCkKLSAgewotICAgIG1fc2VsZWN0RXhwcmVzc2lvbiA9IHhwYXRoLmdldEV4cHJlc3Npb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgWFBhdGggZXhwcmVzc2lvbiBmb3IgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uIGdldFNlbGVjdCgpCi0gIHsKLSAgICByZXR1cm4gbV9zZWxlY3RFeHByZXNzaW9uOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3Jvb3QKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotCi0gICAgaW50IGxlbmd0aCA9IGdldFNvcnRFbGVtQ291bnQoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspCi0gICAgewotICAgICAgZ2V0U29ydEVsZW0oaSkuY29tcG9zZShzcm9vdCk7Ci0gICAgfQotCi0gICAgamF2YS51dGlsLlZlY3RvciB2bmFtZXMgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKS5nZXRWYXJpYWJsZU5hbWVzKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3NlbGVjdEV4cHJlc3Npb24pCi0gICAgICBtX3NlbGVjdEV4cHJlc3Npb24uZml4dXBWYXJpYWJsZXMoCi0gICAgICAgIHZuYW1lcywgc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCkuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fc2VsZWN0RXhwcmVzc2lvbiA9Ci0gICAgICAgIGdldFN0eWxlc2hlZXRSb290KCkubV9zZWxlY3REZWZhdWx0LmdldEV4cHJlc3Npb24oKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGFmdGVyIHRoZSB0ZW1wbGF0ZSdzIGNoaWxkcmVuIGhhdmUgYmVlbiBjb21wb3NlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZENvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaW50IGxlbmd0aCA9IGdldFNvcnRFbGVtQ291bnQoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspCi0gICAgewotICAgICAgZ2V0U29ydEVsZW0oaSkuZW5kQ29tcG9zZShzcm9vdCk7Ci0gICAgfQotICAgIAotICAgIHN1cGVyLmVuZENvbXBvc2Uoc3Jvb3QpOwotICB9Ci0KLQotICAvLyAgLyoqCi0gIC8vICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciBldmVyeXRoaW5nIGVsc2UgaGFzIGJlZW4KLSAgLy8gICAqIHJlY29tcG9zZWQsIGFuZCBhbGxvd3MgdGhlIHRlbXBsYXRlIHRvIHNldCByZW1haW5pbmcKLSAgLy8gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgLy8gICAqIGRlcGVuZHMgb24gcmVjb21wb3NpdGlvbi4KLSAgLy8gICAqCi0gIC8vICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIC8vICAgKi8KLSAgLy8gIHB1YmxpYyB2b2lkIGNvbXBvc2UoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgLy8gIHsKLSAgLy8KLSAgLy8gICAgaWYgKG51bGwgPT0gbV9zZWxlY3RFeHByZXNzaW9uKQotICAvLyAgICB7Ci0gIC8vICAgICAgbV9zZWxlY3RFeHByZXNzaW9uID0KLSAgLy8gICAgICAgIGdldFN0eWxlc2hlZXRSb290KCkubV9zZWxlY3REZWZhdWx0LmdldEV4cHJlc3Npb24oKTsKLSAgLy8gICAgfQotICAvLyAgfQotCi0gIC8qKgotICAgKiBWZWN0b3IgY29udGFpbmluZyB0aGUgeHNsOnNvcnQgZWxlbWVudHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWxlbWVudC4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBWZWN0b3IgbV9zb3J0RWxlbXMgPSBudWxsOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGNvdW50IHhzbDpzb3J0IGVsZW1lbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB4c2w6c29ydCBlbGVtZW50cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0U29ydEVsZW1Db3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG1fc29ydEVsZW1zID09IG51bGwpID8gMCA6IG1fc29ydEVsZW1zLnNpemUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSB4c2w6c29ydCBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHhzbDpzb3J0IGVsZW1lbnQgdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4geHNsOnNvcnQgZWxlbWVudCBhdCBnaXZlbiBpbmRleAotICAgKi8KLSAgcHVibGljIEVsZW1Tb3J0IGdldFNvcnRFbGVtKGludCBpKQotICB7Ci0gICAgcmV0dXJuIChFbGVtU29ydCkgbV9zb3J0RWxlbXMuZWxlbWVudEF0KGkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhIHhzbDpzb3J0IGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHNvcnRFbGVtIHhzbDpzb3J0IGVsZW1lbnQgdG8gc2V0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTb3J0RWxlbShFbGVtU29ydCBzb3J0RWxlbSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9zb3J0RWxlbXMpCi0gICAgICBtX3NvcnRFbGVtcyA9IG5ldyBWZWN0b3IoKTsKLQotICAgIG1fc29ydEVsZW1zLmFkZEVsZW1lbnQoc29ydEVsZW0pOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0ZPUkVBQ0g7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfRk9SRUFDSF9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgeHNsOmZvci1lYWNoIHRyYW5zZm9ybWF0aW9uCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyYW5zZm9ybWVyLnB1c2hDdXJyZW50VGVtcGxhdGVSdWxlSXNOdWxsKHRydWUpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgICAgdHJhbnNmb3JtU2VsZWN0ZWROb2Rlcyh0cmFuc2Zvcm1lcik7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB0cmFuc2Zvcm1lci5wb3BDdXJyZW50VGVtcGxhdGVSdWxlSXNOdWxsKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0ZW1wbGF0ZSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGlzCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGVtcGxhdGUgZWxlbWVudCBhc3NvY2lhdGVkIHdpdGggdGhpcyAoaXRzZWxmKQotICAgKi8KLSAgcHJvdGVjdGVkIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZ2V0VGVtcGxhdGVNYXRjaCgpCi0gIHsKLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBTb3J0IGdpdmVuIG5vZGVzCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBzdGF0ZSBmb3IgdGhlIHNvcnQuCi0gICAqIEBwYXJhbSBrZXlzIFZlY3RvciBvZiBzb3J0IGtleXgKLSAgICogQHBhcmFtIHNvdXJjZU5vZGVzIEl0ZXJhdG9yIG9mIG5vZGVzIHRvIHNvcnQKLSAgICoKLSAgICogQHJldHVybiBpdGVyYXRvciBvZiBzb3J0ZWQgbm9kZXMKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIHNvcnROb2RlcygKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIFZlY3RvciBrZXlzLCBEVE1JdGVyYXRvciBzb3VyY2VOb2RlcykKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlU29ydGVyIHNvcnRlciA9IG5ldyBOb2RlU29ydGVyKHhjdHh0KTsKLQotICAgIHNvdXJjZU5vZGVzLnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0gICAgc291cmNlTm9kZXMucnVuVG8oLTEpOwotICAgIHhjdHh0LnB1c2hDb250ZXh0Tm9kZUxpc3Qoc291cmNlTm9kZXMpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgc29ydGVyLnNvcnQoc291cmNlTm9kZXMsIGtleXMsIHhjdHh0KTsKLSAgICAgIHNvdXJjZU5vZGVzLnNldEN1cnJlbnRQb3MoMCk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDb250ZXh0Tm9kZUxpc3QoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc291cmNlTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFBlcmZvcm0gYSBxdWVyeSBpZiBuZWVkZWQsIGFuZCBjYWxsIHRyYW5zZm9ybU5vZGUgZm9yIGVhY2ggY2hpbGQuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gdGVtcGxhdGUgVGhlIG93bmluZyB0ZW1wbGF0ZSBjb250ZXh0LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIFRocm93biBpbiBhIHZhcmlldHkgb2YgY2lyY3Vtc3RhbmNlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHRyYW5zZm9ybVNlbGVjdGVkTm9kZXMoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBmaW5hbCBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICBmaW5hbCBpbnQgc291cmNlTm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgRFRNSXRlcmF0b3Igc291cmNlTm9kZXMgPSBtX3NlbGVjdEV4cHJlc3Npb24uYXNJdGVyYXRvcih4Y3R4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlTm9kZSk7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIGZpbmFsIFZlY3RvciBrZXlzID0gKG1fc29ydEVsZW1zID09IG51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgID8gbnVsbAotICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRyYW5zZm9ybWVyLnByb2Nlc3NTb3J0S2V5cyh0aGlzLCBzb3VyY2VOb2RlKTsKLQotICAgICAgLy8gU29ydCBpZiB3ZSBuZWVkIHRvLgotICAgICAgaWYgKG51bGwgIT0ga2V5cykKLSAgICAgICAgc291cmNlTm9kZXMgPSBzb3J0Tm9kZXMoeGN0eHQsIGtleXMsIHNvdXJjZU5vZGVzKTsKLQotICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlU2VsZWN0ZWRFdmVudChzb3VyY2VOb2RlLCB0aGlzLAotICAgICAgICAgICAgICAgICJzZWxlY3QiLCBuZXcgWFBhdGgobV9zZWxlY3RFeHByZXNzaW9uKSwKLSAgICAgICAgICAgICAgICBuZXcgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0KHNvdXJjZU5vZGVzKSk7Ci0KLSAgICAgIGZpbmFsIFJlc3VsdFRyZWVIYW5kbGVyIHJ0aCA9IHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCk7Ci0gICAgICBDb250ZW50SGFuZGxlciBjaGFuZGxlciA9IHJ0aC5nZXRDb250ZW50SGFuZGxlcigpOwotCi0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoRFRNLk5VTEwpOwotCi0gICAgICBpbnRbXSBjdXJyZW50Tm9kZXMgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZVN0YWNrKCk7Ci0gICAgICBpbnQgY3VycmVudE5vZGVQb3MgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZUZpcnN0RnJlZSgpIC0gMTsKLQotICAgICAgeGN0eHQucHVzaEN1cnJlbnRFeHByZXNzaW9uTm9kZShEVE0uTlVMTCk7Ci0KLSAgICAgIGludFtdIGN1cnJlbnRFeHByZXNzaW9uTm9kZXMgPSB4Y3R4dC5nZXRDdXJyZW50RXhwcmVzc2lvbk5vZGVTdGFjaygpOwotICAgICAgaW50IGN1cnJlbnRFeHByZXNzaW9uTm9kZVBvcyA9Ci0gICAgICAgIHhjdHh0LmdldEN1cnJlbnRFeHByZXNzaW9uTm9kZXNGaXJzdEZyZWUoKSAtIDE7Ci0KLSAgICAgIHhjdHh0LnB1c2hTQVhMb2NhdG9yTnVsbCgpOwotICAgICAgeGN0eHQucHVzaENvbnRleHROb2RlTGlzdChzb3VyY2VOb2Rlcyk7Ci0gICAgICB0cmFuc2Zvcm1lci5wdXNoRWxlbVRlbXBsYXRlRWxlbWVudChudWxsKTsKLQotICAgICAgLy8gcHVzaFBhcmFtcyh0cmFuc2Zvcm1lciwgeGN0eHQpOwotICAgICAgLy8gU2hvdWxkIGJlIGFibGUgdG8gZ2V0IHRoaXMgZnJvbSB0aGUgaXRlcmF0b3IgYnV0IHRoZXJlIG11c3QgYmUgYSBidWcuCi0gICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKHNvdXJjZU5vZGUpOwotICAgICAgaW50IGRvY0lEID0gc291cmNlTm9kZSAmIERUTU1hbmFnZXIuSURFTlRfRFRNX0RFRkFVTFQ7Ci0gICAgICBpbnQgY2hpbGQ7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoY2hpbGQgPSBzb3VyY2VOb2Rlcy5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgY3VycmVudE5vZGVzW2N1cnJlbnROb2RlUG9zXSA9IGNoaWxkOwotICAgICAgICBjdXJyZW50RXhwcmVzc2lvbk5vZGVzW2N1cnJlbnRFeHByZXNzaW9uTm9kZVBvc10gPSBjaGlsZDsKLQotICAgICAgICBpZiAoKGNoaWxkICYgRFRNTWFuYWdlci5JREVOVF9EVE1fREVGQVVMVCkgIT0gZG9jSUQpCi0gICAgICAgIHsKLSAgICAgICAgICBkdG0gPSB4Y3R4dC5nZXREVE0oY2hpbGQpOwotICAgICAgICAgIGRvY0lEID0gc291cmNlTm9kZSAmIERUTU1hbmFnZXIuSURFTlRfRFRNX0RFRkFVTFQ7Ci0gICAgICAgIH0KLQotICAgICAgICBmaW5hbCBpbnQgZXhOb2RlVHlwZSA9IGR0bS5nZXRFeHBhbmRlZFR5cGVJRChjaGlsZCk7Ci0gICAgICAgIGZpbmFsIGludCBub2RlVHlwZSA9IChleE5vZGVUeXBlID4+IEV4cGFuZGVkTmFtZVRhYmxlLlJPVEFNT1VOVF9UWVBFKTsKLQotICAgICAgICAvLyBGaXJlIGEgdHJhY2UgZXZlbnQgZm9yIHRoZSB0ZW1wbGF0ZS4KLSAgICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotCi0gICAgICAgIC8vIEFuZCBleGVjdXRlIHRoZSBjaGlsZCB0ZW1wbGF0ZXMuCi0gICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgY2hpbGRyZW4gb2YgdGhlIHRlbXBsYXRlLCBjYWxsaW5nIGV4ZWN1dGUgb24gCi0gICAgICAgIC8vIGVhY2ggb2YgdGhlbS4KLSAgICAgICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IHQgPSB0aGlzLm1fZmlyc3RDaGlsZDsgdCAhPSBudWxsOwotICAgICAgICAgICAgICAgIHQgPSB0Lm1fbmV4dFNpYmxpbmcpCi0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5zZXRTQVhMb2NhdG9yKHQpOwotICAgICAgICAgIHRyYW5zZm9ybWVyLnNldEN1cnJlbnRFbGVtZW50KHQpOwotICAgICAgICAgIHQuZXhlY3V0ZSh0cmFuc2Zvcm1lcik7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVNlbGVjdGVkRW5kRXZlbnQoc291cmNlTm9kZSwgdGhpcywKLSAgICAgICAgICAgICAgICAic2VsZWN0IiwgbmV3IFhQYXRoKG1fc2VsZWN0RXhwcmVzc2lvbiksCi0gICAgICAgICAgICAgICAgbmV3IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldChzb3VyY2VOb2RlcykpOwotCi0gICAgICB4Y3R4dC5wb3BTQVhMb2NhdG9yKCk7Ci0gICAgICB4Y3R4dC5wb3BDb250ZXh0Tm9kZUxpc3QoKTsKLSAgICAgIHRyYW5zZm9ybWVyLnBvcEVsZW1UZW1wbGF0ZUVsZW1lbnQoKTsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnRFeHByZXNzaW9uTm9kZSgpOwotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIHNvdXJjZU5vZGVzLmRldGFjaCgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICogPCFFTEVNRU5UIHhzbDphcHBseS10ZW1wbGF0ZXMgKHhzbDpzb3J0fHhzbDp3aXRoLXBhcmFtKSo+Ci0gICAqIDwhQVRUTElTVCB4c2w6YXBwbHktdGVtcGxhdGVzCi0gICAqICAgc2VsZWN0ICVleHByOyAibm9kZSgpIgotICAgKiAgIG1vZGUgJXFuYW1lOyAjSU1QTElFRAotICAgKiA+Ci0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBDaGlsZCB0byBhZGQgdG8gY2hpbGQgbGlzdAotICAgKgotICAgKiBAcmV0dXJuIENoaWxkIGp1c3QgYWRkZWQgdG8gY2hpbGQgbGlzdAotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXBwZW5kQ2hpbGQoRWxlbVRlbXBsYXRlRWxlbWVudCBuZXdDaGlsZCkKLSAgewotCi0gICAgaW50IHR5cGUgPSAoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG5ld0NoaWxkKS5nZXRYU0xUb2tlbigpOwotCi0gICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9TT1JUID09IHR5cGUpCi0gICAgewotICAgICAgc2V0U29ydEVsZW0oKEVsZW1Tb3J0KSBuZXdDaGlsZCk7Ci0KLSAgICAgIHJldHVybiBuZXdDaGlsZDsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHN1cGVyLmFwcGVuZENoaWxkKG5ld0NoaWxkKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1JZi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1JZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNDM1MTAzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtSWYuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLlNlbGVjdGlvbkV2ZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOmlmLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6aWYgJXRlbXBsYXRlOz4KLSAqIDwhQVRUTElTVCB4c2w6aWYKLSAqICAgdGVzdCAlZXhwcjsgI1JFUVVJUkVECi0gKiAgICVzcGFjZS1hdHQ7Ci0gKiA+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNvbmRpdGlvbmFsLVByb2Nlc3Npbmctd2l0aC14c2w6aWYiPlhYWCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtSWYgZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqCi0gICAqIFRoZSB4c2w6aWYgZWxlbWVudCBtdXN0IGhhdmUgYSB0ZXN0IGF0dHJpYnV0ZSwgd2hpY2ggc3BlY2lmaWVzIGFuIGV4cHJlc3Npb24uCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgWFBhdGggbV90ZXN0ID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAidGVzdCIgYXR0cmlidXRlLgotICAgKiBUaGUgeHNsOmlmIGVsZW1lbnQgbXVzdCBoYXZlIGEgdGVzdCBhdHRyaWJ1dGUsIHdoaWNoIHNwZWNpZmllcyBhbiBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gdiB0ZXN0IGF0dHJpYnV0ZSB0byBzZXQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRlc3QoWFBhdGggdikKLSAgewotICAgIG1fdGVzdCA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAidGVzdCIgYXR0cmlidXRlLgotICAgKiBUaGUgeHNsOmlmIGVsZW1lbnQgbXVzdCBoYXZlIGEgdGVzdCBhdHRyaWJ1dGUsIHdoaWNoIHNwZWNpZmllcyBhbiBleHByZXNzaW9uLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSAidGVzdCIgYXR0cmlidXRlIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgWFBhdGggZ2V0VGVzdCgpCi0gIHsKLSAgICByZXR1cm4gbV90ZXN0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3Jvb3QKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotCi0gICAgamF2YS51dGlsLlZlY3RvciB2bmFtZXMgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKS5nZXRWYXJpYWJsZU5hbWVzKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Rlc3QpCi0gICAgICBtX3Rlc3QuZml4dXBWYXJpYWJsZXModm5hbWVzLCBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKS5nZXRHbG9iYWxzU2l6ZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRva2VuIElEIGZvciB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0WFNMVG9rZW4oKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9JRjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZWxlbWVudCdzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9JRl9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ29uZGl0aW9uYWxseSBleGVjdXRlIGEgc3ViLXRlbXBsYXRlLgotICAgKiBUaGUgZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQgYW5kIHRoZSByZXN1bHRpbmcgb2JqZWN0IGlzIGNvbnZlcnRlZAotICAgKiB0byBhIGJvb2xlYW4gYXMgaWYgYnkgYSBjYWxsIHRvIHRoZSBib29sZWFuIGZ1bmN0aW9uLiBJZiB0aGUgcmVzdWx0Ci0gICAqIGlzIHRydWUsIHRoZW4gdGhlIGNvbnRlbnQgdGVtcGxhdGUgaXMgaW5zdGFudGlhdGVkOyBvdGhlcndpc2UsIG5vdGhpbmcKLSAgICogaXMgY3JlYXRlZC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZShUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotICAgIGludCBzb3VyY2VOb2RlID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLQotICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICB7Ci0gICAgICBYT2JqZWN0IHRlc3QgPSBtX3Rlc3QuZXhlY3V0ZSh4Y3R4dCwgc291cmNlTm9kZSwgdGhpcyk7Ci0KLSAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVNlbGVjdGVkRXZlbnQoc291cmNlTm9kZSwgdGhpcywKLSAgICAgICAgICAgICAgICAidGVzdCIsIG1fdGVzdCwgdGVzdCk7Ci0KLSAgICAgIGlmICh0ZXN0LmJvb2woKSkKLSAgICAgIHsKLSAgICAgICAgdHJhbnNmb3JtZXIuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKHRoaXMsIHRydWUpOwotICAgICAgfQotCi0gICAgICAvLyBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdGhpcy4gIC1zYgotICAgICAgLy8gIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgIC8vICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVTZWxlY3RlZEV2ZW50KHNvdXJjZU5vZGUsIHRoaXMsCi0gICAgICAvLyAgICAgICAgICAgICJlbmRUZXN0IiwgbV90ZXN0LCB0ZXN0KTsKLSAgICB9Ci0gICAgZWxzZSBpZiAobV90ZXN0LmJvb2woeGN0eHQsIHNvdXJjZU5vZGUsIHRoaXMpKQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmV4ZWN1dGVDaGlsZFRlbXBsYXRlcyh0aGlzLCB0cnVlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtTGl0ZXJhbFJlc3VsdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1MaXRlcmFsUmVzdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYyYmU3NzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1MaXRlcmFsUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2ODkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy4qOwotCi1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5hbWVTcGFjZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdUb1N0cmluZ1RhYmxlOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5hbWVTcGFjZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS5pby4qOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgYSBMaXRlcmFsIFJlc3VsdCBFbGVtZW50LgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2xpdGVyYWwtcmVzdWx0LWVsZW1lbnQiPmxpdGVyYWwtcmVzdWx0LWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbUxpdGVyYWxSZXN1bHQgZXh0ZW5kcyBFbGVtVXNlCi17Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoaXMgZWxlbWVudCByZXByZXNlbnRzIGEgcm9vdCBlbGVtZW50Ci0gICAqIHRoYXQgaXMgYWxzbyB0aGUgc3R5bGVzaGVldCBlbGVtZW50LgotICAgKiBUT0RPOiBUaGlzIHNob3VsZCBiZSBhIGRlcml2ZWQgY2xhc3MuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBpc0xpdGVyYWxSZXN1bHRBc1N0eWxlc2hlZXQgPSBmYWxzZTsKLQotICAvKioKLSAgICogU2V0IHdoZXRoZXIgdGhpcyBlbGVtZW50IHJlcHJlc2VudHMgYSByb290IGVsZW1lbnQKLSAgICogdGhhdCBpcyBhbHNvIHRoZSBzdHlsZXNoZWV0IGVsZW1lbnQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBiIGJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBlbGVtZW50Ci0gICAqIHJlcHJlc2VudHMgYSByb290IGVsZW1lbnQgdGhhdCBpcyBhbHNvIHRoZSBzdHlsZXNoZWV0IGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJc0xpdGVyYWxSZXN1bHRBc1N0eWxlc2hlZXQoYm9vbGVhbiBiKQotICB7Ci0gICAgaXNMaXRlcmFsUmVzdWx0QXNTdHlsZXNoZWV0ID0gYjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIGVsZW1lbnQgcmVwcmVzZW50cyBhIHJvb3QgZWxlbWVudAotICAgKiB0aGF0IGlzIGFsc28gdGhlIHN0eWxlc2hlZXQgZWxlbWVudC4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBib29sZWFuIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgZWxlbWVudAotICAgKiByZXByZXNlbnRzIGEgcm9vdCBlbGVtZW50IHRoYXQgaXMgYWxzbyB0aGUgc3R5bGVzaGVldCBlbGVtZW50LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0SXNMaXRlcmFsUmVzdWx0QXNTdHlsZXNoZWV0KCkKLSAgewotICAgIHJldHVybiBpc0xpdGVyYWxSZXN1bHRBc1N0eWxlc2hlZXQ7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciBldmVyeXRoaW5nIGVsc2UgaGFzIGJlZW4KLSAgICogcmVjb21wb3NlZCwgYW5kIGFsbG93cyB0aGUgdGVtcGxhdGUgdG8gc2V0IHJlbWFpbmluZwotICAgKiB2YWx1ZXMgdGhhdCBtYXkgYmUgYmFzZWQgb24gc29tZSBvdGhlciBwcm9wZXJ0eSB0aGF0Ci0gICAqIGRlcGVuZHMgb24gcmVjb21wb3NpdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIuY29tcG9zZShzcm9vdCk7Ci0gICAgU3R5bGVzaGVldFJvb3QuQ29tcG9zZVN0YXRlIGNzdGF0ZSA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpOwotICAgIGphdmEudXRpbC5WZWN0b3Igdm5hbWVzID0gY3N0YXRlLmdldFZhcmlhYmxlTmFtZXMoKTsKLSAgICBpZiAobnVsbCAhPSBtX2F2dHMpCi0gICAgewotICAgICAgaW50IG5BdHRycyA9IG1fYXZ0cy5zaXplKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAobkF0dHJzIC0gMSk7IGkgPj0gMDsgaS0tKQotICAgICAgewotICAgICAgICBBVlQgYXZ0ID0gKEFWVCkgbV9hdnRzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgICAgfSAKLSAgICB9ICAgCi0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGUgY3JlYXRlZCBlbGVtZW50IG5vZGUgd2lsbCBoYXZlIHRoZSBhdHRyaWJ1dGUgbm9kZXMKLSAgICogdGhhdCB3ZXJlIHByZXNlbnQgb24gdGhlIGVsZW1lbnQgbm9kZSBpbiB0aGUgc3R5bGVzaGVldCB0cmVlLAotICAgKiBvdGhlciB0aGFuIGF0dHJpYnV0ZXMgd2l0aCBuYW1lcyBpbiB0aGUgWFNMVCBuYW1lc3BhY2UuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fYXZ0cyA9IG51bGw7Ci0KLSAgLyoqIExpc3Qgb2YgYXR0cmlidXRlcyB3aXRoIHRoZSBYU0xUIG5hbWVzcGFjZS4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV94c2xBdHRyID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IGEgbGl0ZXJhbCByZXN1bHQgYXR0cmlidXRlIChBVlRzIG9ubHkpLgotICAgKgotICAgKiBAcGFyYW0gYXZ0IGxpdGVyYWwgcmVzdWx0IGF0dHJpYnV0ZSB0byBhZGQgKEFWVCBvbmx5KQotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTGl0ZXJhbFJlc3VsdEF0dHJpYnV0ZShBVlQgYXZ0KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2F2dHMpCi0gICAgICBtX2F2dHMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBtX2F2dHMuYWRkRWxlbWVudChhdnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhIGxpdGVyYWwgcmVzdWx0IGF0dHJpYnV0ZSAodXNlZCBmb3IgeHNsIGF0dHJpYnV0ZXMpLgotICAgKgotICAgKiBAcGFyYW0gYXR0IGxpdGVyYWwgcmVzdWx0IGF0dHJpYnV0ZSB0byBhZGQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZExpdGVyYWxSZXN1bHRBdHRyaWJ1dGUoU3RyaW5nIGF0dCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV94c2xBdHRyKQotICAgICAgbV94c2xBdHRyID0gbmV3IFZlY3RvcigpOwotCi0gICAgbV94c2xBdHRyLmFkZEVsZW1lbnQoYXR0KTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgInhtbDpzcGFjZSIgYXR0cmlidXRlLgotICAgKiBBIHRleHQgbm9kZSBpcyBwcmVzZXJ2ZWQgaWYgYW4gYW5jZXN0b3IgZWxlbWVudCBvZiB0aGUgdGV4dCBub2RlCi0gICAqIGhhcyBhbiB4bWw6c3BhY2UgYXR0cmlidXRlIHdpdGggYSB2YWx1ZSBvZiBwcmVzZXJ2ZSwgYW5kCi0gICAqIG5vIGNsb3NlciBhbmNlc3RvciBlbGVtZW50IGhhcyB4bWw6c3BhY2Ugd2l0aCBhIHZhbHVlIG9mIGRlZmF1bHQuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzdHJpcCI+c3RyaXAgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1DcmVhdGluZy1UZXh0Ij5zZWN0aW9uLUNyZWF0aW5nLVRleHQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiAgRW51bWVyYXRlZCB2YWx1ZSwgZWl0aGVyIENvbnN0YW50cy5BVFRSVkFMX1BSRVNFUlZFIAotICAgKiBvciBDb25zdGFudHMuQVRUUlZBTF9TVFJJUC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFhtbFNwYWNlKEFWVCBhdnQpCi0gIHsKLSAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGEgYml0LW8taGFjaywgSSBndWVzcy4uLgotICAgIGFkZExpdGVyYWxSZXN1bHRBdHRyaWJ1dGUoYXZ0KTsKLSAgICBTdHJpbmcgdmFsID0gYXZ0LmdldFNpbXBsZVN0cmluZygpOwotICAgIGlmKHZhbC5lcXVhbHMoImRlZmF1bHQiKSkKLSAgICB7Ci0gICAgICBzdXBlci5zZXRYbWxTcGFjZShDb25zdGFudHMuQVRUUlZBTF9TVFJJUCk7Ci0gICAgfQotICAgIGVsc2UgaWYodmFsLmVxdWFscygicHJlc2VydmUiKSkKLSAgICB7Ci0gICAgICBzdXBlci5zZXRYbWxTcGFjZShDb25zdGFudHMuQVRUUlZBTF9QUkVTRVJWRSk7Ci0gICAgfQotICAgIC8vIGVsc2UgbWF5YmUgaXQncyBhIHJlYWwgQVZULCBzbyB3ZSBjYW4ndCByZXNvbHZlIGl0IGF0IHRoaXMgdGltZS4KLSAgfQotCi0KLSAgLyoqCi0gICAqIEdldCBhIGxpdGVyYWwgcmVzdWx0IGF0dHJpYnV0ZSBieSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIGxpdGVyYWwgcmVzdWx0IGF0dHJpYnV0ZSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBsaXRlcmFsIHJlc3VsdCBhdHRyaWJ1dGUgKEFWVCkKLSAgICovCi0gIHB1YmxpYyBBVlQgZ2V0TGl0ZXJhbFJlc3VsdEF0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9hdnRzKQotICAgIHsKLSAgICAgIGludCBuQXR0cnMgPSBtX2F2dHMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gKG5BdHRycyAtIDEpOyBpID49IDA7IGktLSkKLSAgICAgIHsKLSAgICAgICAgQVZUIGF2dCA9IChBVlQpIG1fYXZ0cy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgaWYgKGF2dC5nZXRSYXdOYW1lKCkuZXF1YWxzKG5hbWUpKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGF2dDsKLSAgICAgICAgfQotICAgICAgfSAgLy8gZW5kIGZvcgotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB3aGV0aGVyIG9yIG5vdCB0aGUgcGFzc2VkIFVSTCBpcyBjb250YWluZWQgZmxhZ2dlZCBieQotICAgKiB0aGUgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2V4dGVuc2lvbi1lbGVtZW50Ij5leHRlbnNpb24tZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByZWZpeCB0aGF0IG1pZ2h0IGJlIGV4Y2x1ZGVkLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHByZWZpeCBzaG91bGQgbm9ybWFsbHkgYmUgZXhjbHVkZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0V4Y2x1ZGVSZXN1bHRQcmVmaXgoU3RyaW5nIHByZWZpeCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9leGNsdWRlUmVzdWx0UHJlZml4ZXMpCi0gICAgICByZXR1cm4gc3VwZXIuY29udGFpbnNFeGNsdWRlUmVzdWx0UHJlZml4KHByZWZpeCk7Ci0KLSAgICBpZiAocHJlZml4Lmxlbmd0aCgpID09IDApCi0gICAgICBwcmVmaXggPSBDb25zdGFudHMuQVRUUlZBTF9ERUZBVUxUX1BSRUZJWDsKLQotICAgIGlmIChtX2V4Y2x1ZGVSZXN1bHRQcmVmaXhlcy5jb250YWlucyhwcmVmaXgpKQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHN1cGVyLmNvbnRhaW5zRXhjbHVkZVJlc3VsdFByZWZpeChwcmVmaXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEF1Z21lbnQgcmVzb2x2ZVByZWZpeFRhYmxlcywgcmVzb2x2aW5nIHRoZSBuYW1lc3BhY2UgYWxpYXNlcyBvbmNlCi0gICAqIHRoZSBzdXBlcmNsYXNzIGhhcyByZXNvbHZlZCB0aGUgdGFibGVzLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNvbHZlUHJlZml4VGFibGVzKCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyLnJlc29sdmVQcmVmaXhUYWJsZXMoKTsKLQotICAgIFN0eWxlc2hlZXRSb290IHN0eWxlc2hlZXQgPSBnZXRTdHlsZXNoZWV0Um9vdCgpOwotCi0gICAgaWYgKChudWxsICE9IG1fbmFtZXNwYWNlKSAmJiAobV9uYW1lc3BhY2UubGVuZ3RoKCkgPiAwKSkKLSAgICB7Ci0gICAgICBOYW1lc3BhY2VBbGlhcyBuc2EgPSBzdHlsZXNoZWV0LmdldE5hbWVzcGFjZUFsaWFzQ29tcG9zZWQobV9uYW1lc3BhY2UpOwotCi0gICAgICBpZiAobnVsbCAhPSBuc2EpCi0gICAgICB7Ci0gICAgICAgIG1fbmFtZXNwYWNlID0gbnNhLmdldFJlc3VsdE5hbWVzcGFjZSgpOwotCi0gICAgICAgIC8vIFN0cmluZyByZXN1bHRQcmVmaXggPSBuc2EuZ2V0UmVzdWx0UHJlZml4KCk7Ci0gICAgICAgIFN0cmluZyByZXN1bHRQcmVmaXggPSBuc2EuZ2V0U3R5bGVzaGVldFByZWZpeCgpOyAgLy8gQXMgcGVyIHhzbCBXRywgTWlrZSBLYXkKLQotICAgICAgICBpZiAoKG51bGwgIT0gcmVzdWx0UHJlZml4KSAmJiAocmVzdWx0UHJlZml4Lmxlbmd0aCgpID4gMCkpCi0gICAgICAgICAgbV9yYXdOYW1lID0gcmVzdWx0UHJlZml4ICsgIjoiICsgbV9sb2NhbE5hbWU7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBtX3Jhd05hbWUgPSBtX2xvY2FsTmFtZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAobnVsbCAhPSBtX2F2dHMpCi0gICAgewotICAgICAgaW50IG4gPSBtX2F2dHMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgQVZUIGF2dCA9IChBVlQpIG1fYXZ0cy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgLy8gU2hvdWxkIHRoaXMgc3R1ZmYgYmUgYSBtZXRob2Qgb24gQVZUPwotICAgICAgICBTdHJpbmcgbnMgPSBhdnQuZ2V0VVJJKCk7Ci0KLSAgICAgICAgaWYgKChudWxsICE9IG5zKSAmJiAobnMubGVuZ3RoKCkgPiAwKSkKLSAgICAgICAgewotICAgICAgICAgIE5hbWVzcGFjZUFsaWFzIG5zYSA9Ci0gICAgICAgICAgICBzdHlsZXNoZWV0LmdldE5hbWVzcGFjZUFsaWFzQ29tcG9zZWQobV9uYW1lc3BhY2UpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gbnNhKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBuc2EuZ2V0UmVzdWx0TmFtZXNwYWNlKCk7Ci0KLSAgICAgICAgICAgIC8vIFN0cmluZyByZXN1bHRQcmVmaXggPSBuc2EuZ2V0UmVzdWx0UHJlZml4KCk7Ci0gICAgICAgICAgICBTdHJpbmcgcmVzdWx0UHJlZml4ID0gbnNhLmdldFN0eWxlc2hlZXRQcmVmaXgoKTsgIC8vIEFzIHBlciBYU0wgV0cKLSAgICAgICAgICAgIFN0cmluZyByYXdOYW1lID0gYXZ0LmdldE5hbWUoKTsKLQotICAgICAgICAgICAgaWYgKChudWxsICE9IHJlc3VsdFByZWZpeCkgJiYgKHJlc3VsdFByZWZpeC5sZW5ndGgoKSA+IDApKQotICAgICAgICAgICAgICByYXdOYW1lID0gcmVzdWx0UHJlZml4ICsgIjoiICsgcmF3TmFtZTsKLQotICAgICAgICAgICAgYXZ0LnNldFVSSShuYW1lc3BhY2UpOwotICAgICAgICAgICAgYXZ0LnNldFJhd05hbWUocmF3TmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB3aGV0aGVyIHdlIG5lZWQgdG8gY2hlY2sgbmFtZXNwYWNlIHByZWZpeGVzCi0gICAqIGFnYWluc3QgYW5kIGV4Y2x1ZGUgcmVzdWx0IHByZWZpeGVzIGxpc3QuCi0gICAqIE5vdGUgdGhhdCB0aGlzIHdpbGwgY3JlYXRlIGEgbmV3IHByZWZpeCB0YWJsZSBpZiBvbmUKLSAgICogaGFzIG5vdCBiZWVuIGNyZWF0ZWQgYWxyZWFkeS4KLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgYm9vbGVhbiBuZWVkVG9DaGVja0V4Y2x1ZGUoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2V4Y2x1ZGVSZXN1bHRQcmVmaXhlcyAmJiBudWxsID09IG1fcHJlZml4VGFibGUpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gQ3JlYXRlIGEgbmV3IHByZWZpeCB0YWJsZSBpZiBvbmUgaGFzIG5vdCBhbHJlYWR5IGJlZW4gY3JlYXRlZC4KLSAgICAgIGlmIChudWxsID09IG1fcHJlZml4VGFibGUpCi0gICAgICAgIG1fcHJlZml4VGFibGUgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IHRvIGJlIGNyZWF0ZWQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbmFtZXNwYWNlOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIHJlc3VsdCBlbGVtZW50IHRvIGJlIGNyZWF0ZWQuCi0gICAqIE5vdGUgdGhhdCBhZnRlciByZXNvbHZlUHJlZml4VGFibGVzIGhhcyBiZWVuIGNhbGxlZCwgdGhpcyB3aWxsCi0gICAqIHJldHVybiB0aGUgYWxpYXNlZCByZXN1bHQgbmFtZXNwYWNlLCBub3QgdGhlIG9yaWdpbmFsIHN0eWxlc2hlZXQKLSAgICogbmFtZXNwYWNlLgotICAgKgotICAgKiBAcGFyYW0gbnMgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlKFN0cmluZyBucykKLSAgewotICAgIGlmKG51bGwgPT0gbnMpIC8vIGRlZmVuc2l2ZSwgc2hvdWxkbid0IGhhdmUgdG8gZG8gdGhpcy4KLSAgICAgIG5zID0gIiI7Ci0gICAgbV9uYW1lc3BhY2UgPSBuczsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG9yaWdpbmFsIG5hbWVzcGFjZSBvZiB0aGUgTGl0ZXJhbCBSZXN1bHQgRWxlbWVudC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lc3BhY2U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnQgdG8gYmUgY3JlYXRlZC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9sb2NhbE5hbWU7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgTFJFLgotICAgKgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCkgb2YgdGhlIHJlc3VsdCBlbGVtZW50Ci0gICAqICAgICAgICAgICAgICAgICAgdG8gYmUgY3JlYXRlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExvY2FsTmFtZShTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgbV9sb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBMaXRlcmFsIFJlc3VsdCBFbGVtZW50LgotICAgKiBOb3RlIHRoYXQgYWZ0ZXIgcmVzb2x2ZVByZWZpeFRhYmxlcyBoYXMgYmVlbiBjYWxsZWQsIHRoaXMgd2lsbAotICAgKiByZXR1cm4gdGhlIGFsaWFzZWQgbmFtZSBwcmVmaXgsIG5vdCB0aGUgb3JpZ2luYWwgc3R5bGVzaGVldAotICAgKiBuYW1lc3BhY2UgcHJlZml4LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCkgb2YgdGhlIHJlc3VsdCBlbGVtZW50Ci0gICAqICAgICAgICAgICAgICAgICAgdG8gYmUgY3JlYXRlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkKLSAgewotICAgIHJldHVybiBtX2xvY2FsTmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgcmF3IG5hbWUgb2YgdGhlIGVsZW1lbnQgdG8gYmUgY3JlYXRlZC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9yYXdOYW1lOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIHJhdyBuYW1lIG9mIHRoZSBMUkUuCi0gICAqCi0gICAqIEBwYXJhbSByYXdOYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSAod2l0aCBwcmVmaXgpLCBvciB0aGUKLSAgICogICAgICAgIGVtcHR5IHN0cmluZyBpZiBxdWFsaWZpZWQgbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSYXdOYW1lKFN0cmluZyByYXdOYW1lKQotICB7Ci0gICAgbV9yYXdOYW1lID0gcmF3TmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJhdyBuYW1lIG9mIHRoZSBMaXRlcmFsIFJlc3VsdCBFbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuICBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRSYXdOYW1lKCkKLSAgewotICAgIHJldHVybiBtX3Jhd05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIgcHJvcGVydHksIGFjdHVhbGx5IGNvbnRhaW5zIFVSSXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nVmVjdG9yIG1fRXh0ZW5zaW9uRWxlbWVudFVSSXM7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2V4dGVuc2lvbi1lbGVtZW50Ij5leHRlbnNpb24tZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFZlY3RvciBvZiBVUkkgdG8gc2V0IGFzIHRoZSAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiIHByb3BlcnR5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeHRlbnNpb25FbGVtZW50UHJlZml4ZXMoU3RyaW5nVmVjdG9yIHYpCi0gIHsKLSAgICBtX0V4dGVuc2lvbkVsZW1lbnRVUklzID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeCIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNleHRlbnNpb24tZWxlbWVudCI+ZXh0ZW5zaW9uLWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBVUkkgKCJleHRlbnNpb24tZWxlbWVudC1wcmVmaXgiIHByb3BlcnR5KSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBVUkkgYXQgZ2l2ZW4gaW5kZXggKCJleHRlbnNpb24tZWxlbWVudC1wcmVmaXgiIHByb3BlcnR5KQotICAgKgotICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFeHRlbnNpb25FbGVtZW50UHJlZml4KGludCBpKQotICAgICAgICAgIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9FeHRlbnNpb25FbGVtZW50VVJJcykKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKLQotICAgIHJldHVybiBtX0V4dGVuc2lvbkVsZW1lbnRVUklzLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiIFN0cmluZ3MuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNleHRlbnNpb24tZWxlbWVudCI+ZXh0ZW5zaW9uLWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiBTdHJpbmdzCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4dGVuc2lvbkVsZW1lbnRQcmVmaXhDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9FeHRlbnNpb25FbGVtZW50VVJJcykKLSAgICAgICAgICAgPyBtX0V4dGVuc2lvbkVsZW1lbnRVUklzLnNpemUoKSA6IDA7Ci0gIH0KLQotICAvKioKLSAgICogRmluZCBvdXQgaWYgdGhlIGdpdmVuICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXgiIHByb3BlcnR5IGlzIGRlZmluZWQuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNleHRlbnNpb24tZWxlbWVudCI+ZXh0ZW5zaW9uLWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBVUkkgdG8gZmluZAotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIFVSSSBpcyBmb3VuZAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFeHRlbnNpb25FbGVtZW50VVJJKFN0cmluZyB1cmkpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fRXh0ZW5zaW9uRWxlbWVudFVSSXMpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICByZXR1cm4gbV9FeHRlbnNpb25FbGVtZW50VVJJcy5jb250YWlucyh1cmkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX0xJVEVSQUxSRVNVTFQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotCi0gICAgLy8gVE9ETzogTmVlZCBwcmVmaXguCi0gICAgcmV0dXJuIG1fcmF3TmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgWFNMVCB2ZXJzaW9uIGFzIHNwZWNpZmllZCBieSB0aGlzIGVsZW1lbnQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fdmVyc2lvbjsKLQotICAvKioKLSAgICogU2V0IHRoZSAidmVyc2lvbiIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNmb3J3YXJkcyI+Zm9yd2FyZHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiBWZXJzaW9uIHByb3BlcnR5IHZhbHVlIHRvIHNldAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihTdHJpbmcgdikKLSAgewotICAgIG1fdmVyc2lvbiA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgcHJvcGVydHkuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nVmVjdG9yIG1fZXhjbHVkZVJlc3VsdFByZWZpeGVzOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgcHJvcGVydHkuCi0gICAqIFRoZSBkZXNpZ25hdGlvbiBvZiBhIG5hbWVzcGFjZSBhcyBhbiBleGNsdWRlZCBuYW1lc3BhY2UgaXMKLSAgICogZWZmZWN0aXZlIHdpdGhpbiB0aGUgc3VidHJlZSBvZiB0aGUgc3R5bGVzaGVldCByb290ZWQgYXQKLSAgICogdGhlIGVsZW1lbnQgYmVhcmluZyB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgb3IKLSAgICogeHNsOmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZTsgYSBzdWJ0cmVlIHJvb3RlZAotICAgKiBhdCBhbiB4c2w6c3R5bGVzaGVldCBlbGVtZW50IGRvZXMgbm90IGluY2x1ZGUgYW55IHN0eWxlc2hlZXRzCi0gICAqIGltcG9ydGVkIG9yIGluY2x1ZGVkIGJ5IGNoaWxkcmVuIG9mIHRoYXQgeHNsOnN0eWxlc2hlZXQgZWxlbWVudC4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2xpdGVyYWwtcmVzdWx0LWVsZW1lbnQiPmxpdGVyYWwtcmVzdWx0LWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiB2ZWN0b3Igb2YgcHJlZml4ZXMgdGhhdCBhcmUgcmVzb2x2YWJsZSB0byBzdHJpbmdzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RXhjbHVkZVJlc3VsdFByZWZpeGVzKFN0cmluZ1ZlY3RvciB2KQotICB7Ci0gICAgbV9leGNsdWRlUmVzdWx0UHJlZml4ZXMgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHJlc3VsdCBuYW1lc3BhY2UgZGVjbCBzaG91bGQgYmUgZXhjbHVkZWQuICBTaG91bGQgYmUgY2FsbGVkIGJlZm9yZQotICAgKiBuYW1lc3BhY2UgYWxpYXNpbmcgKEkgdGhpbmspLgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFByZWZpeCBvZiBuYW1lc3BhY2UgdG8gY2hlY2sKLSAgICogQHBhcmFtIHVyaSBVUkkgb2YgbmFtZXNwYWNlIHRvIGNoZWNrCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHNob3VsZCBiZSBleGNsdWRlZAotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gZXhjbHVkZVJlc3VsdE5TRGVjbChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2V4Y2x1ZGVSZXN1bHRQcmVmaXhlcykKLSAgICB7Ci0gICAgICBpZiAobV9leGNsdWRlUmVzdWx0UHJlZml4ZXMuY29udGFpbnMocHJlZml4KSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0gIAotICAvKioKLSAgICogQ29weSBhIExpdGVyYWwgUmVzdWx0IEVsZW1lbnQgaW50byB0aGUgUmVzdWx0IHRyZWUsIGNvcHkgdGhlCi0gICAqIG5vbi1leGNsdWRlZCBuYW1lc3BhY2UgYXR0cmlidXRlcywgY29weSB0aGUgYXR0cmlidXRlcyBub3QKLSAgICogb2YgdGhlIFhTTFQgbmFtZXNwYWNlLCBhbmQgZXhlY3V0ZSB0aGUgY2hpbGRyZW4gb2YgdGhlIExSRS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2xpdGVyYWwtcmVzdWx0LWVsZW1lbnQiPmxpdGVyYWwtcmVzdWx0LWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBSZXN1bHRUcmVlSGFuZGxlciByaGFuZGxlciA9IHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCk7Ci0KLSAgICAgIC8vIEFkZCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLgotICAgICAgZXhlY3V0ZU5TRGVjbHModHJhbnNmb3JtZXIpOwotICAgICAgcmhhbmRsZXIuc3RhcnRFbGVtZW50KGdldE5hbWVzcGFjZSgpLCBnZXRMb2NhbE5hbWUoKSwgZ2V0UmF3TmFtZSgpLCBudWxsKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0KLSAgICAgICAgLy8gUHJvY2VzcyBhbnkgcG9zc2libGUgYXR0cmlidXRlcyBmcm9tIHhzbDp1c2UtYXR0cmlidXRlLXNldHMgZmlyc3QKLSAgICAgICAgc3VwZXIuZXhlY3V0ZSh0cmFuc2Zvcm1lcik7Ci0KLSAgICAgICAgLy94c2w6dmVyc2lvbiwgZXhjbHVkZVJlc3VsdFByZWZpeGVzPz8/Ci0gICAgICAgIC8vIFByb2Nlc3MgdGhlIGxpc3Qgb2YgYXZ0cyBuZXh0Ci0gICAgICAgIGlmIChudWxsICE9IG1fYXZ0cykKLSAgICAgICAgewotICAgICAgICAgIGludCBuQXR0cnMgPSBtX2F2dHMuc2l6ZSgpOwotCi0gICAgICAgICAgZm9yIChpbnQgaSA9IChuQXR0cnMgLSAxKTsgaSA+PSAwOyBpLS0pCi0gICAgICAgICAgewotICAgICAgICAgICAgQVZUIGF2dCA9IChBVlQpIG1fYXZ0cy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICAgICAgICAgIGludCBzb3VyY2VOb2RlID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICAgICAgICAgIFN0cmluZyBzdHJpbmdlZFZhbHVlID0gYXZ0LmV2YWx1YXRlKHhjdHh0LCBzb3VyY2VOb2RlLCB0aGlzKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gc3RyaW5nZWRWYWx1ZSkKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAvLyBJbXBvcnRhbnQgTm90ZTogSSdtIG5vdCBnb2luZyB0byBjaGVjayBmb3IgZXhjbHVkZWQgbmFtZXNwYWNlIAotICAgICAgICAgICAgICAvLyBwcmVmaXhlcyBoZXJlLiAgSXQgc2VlbXMgbGlrZSBpdCdzIHRvIGV4cGVuc2l2ZSwgYW5kIEknbSBub3QgCi0gICAgICAgICAgICAgIC8vIGV2ZW4gc3VyZSB0aGlzIGlzIHJpZ2h0LiAgQnV0IEkgY291bGQgYmUgd3JvbmcsIHNvIHRoaXMgbmVlZHMgCi0gICAgICAgICAgICAgIC8vIHRvIGJlIHRlc3RlZCBhZ2FpbnN0IG90aGVyIGltcGxlbWVudGF0aW9ucy4KLSAgICAgICAgICAgICAgcmhhbmRsZXIuYWRkQXR0cmlidXRlKGF2dC5nZXRVUkkoKSwgYXZ0LmdldE5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2dC5nZXRSYXdOYW1lKCksICJDREFUQSIsIHN0cmluZ2VkVmFsdWUpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0gIC8vIGVuZCBmb3IKLSAgICAgICAgfQotCi0gICAgICAgIC8vIE5vdyBwcm9jZXNzIGFsbCB0aGUgZWxlbWVudHMgaW4gdGhpcyBzdWJ0cmVlCi0gICAgICAgIC8vIFRPRE86IFByb2Nlc3MgbV9leHRlbnNpb25FbGVtZW50UHJlZml4ZXMgJiYgbV9hdHRyaWJ1dGVTZXRzTmFtZXMKLSAgICAgICAgdHJhbnNmb3JtZXIuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKHRoaXMsIHRydWUpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICAvLyBJZiB5b3UgZG9uJ3QgZG8gdGhpcyBpbiBhIGZpbmFsbHkgc3RhdGVtZW50LCBhbiBleGNlcHRpb24gY291bGQgCi0gICAgICAgIC8vIGNhdXNlIGEgc3lzdGVtIGhhbmcuCi0gICAgICAgIHJoYW5kbGVyLmVuZEVsZW1lbnQoZ2V0TmFtZXNwYWNlKCksIGdldExvY2FsTmFtZSgpLCBnZXRSYXdOYW1lKCkpOwotICAgICAgICB1bmV4ZWN1dGVOU0RlY2xzKHRyYW5zZm9ybWVyKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxpbmcgdGVtcGxhdGVzIHJlcXVpcmVzIHRoYXQgd2UgYmUgYWJsZSB0byBsaXN0IHRoZSBBVlRzCi0gICAqIEFEREVEIDkvNS8yMDAwIHRvIHN1cHBvcnQgY29tcGlsYXRpb24gZXhwZXJpbWVudAotICAgKgotICAgKiBAcmV0dXJuIGFuIEVudW1lcmF0aW9uIG9mIHRoZSBsaXRlcmFsIHJlc3VsdCBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQKLSAgICogd2l0aCB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgRW51bWVyYXRpb24gZW51bWVyYXRlTGl0ZXJhbFJlc3VsdEF0dHJpYnV0ZXMoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fYXZ0cykgPyBudWxsIDogbV9hdnRzLmVsZW1lbnRzKCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtTWVzc2FnZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1NZXNzYWdlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNlZjNlYjYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1NZXNzYWdlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOm1lc3NhZ2UuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDptZXNzYWdlICV0ZW1wbGF0ZTs+Ci0gKiA8IUFUVExJU1QgeHNsOm1lc3NhZ2UKLSAqICAgJXNwYWNlLWF0dDsKLSAqICAgdGVybWluYXRlICh5ZXN8bm8pICJubyIKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21lc3NhZ2UiPm1lc3NhZ2UgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbU1lc3NhZ2UgZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqCi0gICAqIElmIHRoZSB0ZXJtaW5hdGUgYXR0cmlidXRlIGhhcyB0aGUgdmFsdWUgeWVzLCB0aGVuIHRoZQotICAgKiBYU0xUIHRyYW5zZm9ybWVyIHNob3VsZCB0ZXJtaW5hdGUgcHJvY2Vzc2luZyBhZnRlciBzZW5kaW5nCi0gICAqIHRoZSBtZXNzYWdlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBuby4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fdGVybWluYXRlID0gQ29uc3RhbnRzLkFUVFJWQUxfTk87ICAvLyBkZWZhdWx0IHZhbHVlIAotCi0gIC8qKgotICAgKiBTZXQgdGhlICJ0ZXJtaW5hdGUiIGF0dHJpYnV0ZS4KLSAgICogSWYgdGhlIHRlcm1pbmF0ZSBhdHRyaWJ1dGUgaGFzIHRoZSB2YWx1ZSB5ZXMsIHRoZW4gdGhlCi0gICAqIFhTTFQgdHJhbnNmb3JtZXIgc2hvdWxkIHRlcm1pbmF0ZSBwcm9jZXNzaW5nIGFmdGVyIHNlbmRpbmcKLSAgICogdGhlIG1lc3NhZ2UuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vLgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yICJ0ZXJtaW5hdGUiIGF0dHJpYnV0ZS4gCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUZXJtaW5hdGUoYm9vbGVhbiB2KQotICB7Ci0gICAgbV90ZXJtaW5hdGUgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgInRlcm1pbmF0ZSIgYXR0cmlidXRlLgotICAgKiBJZiB0aGUgdGVybWluYXRlIGF0dHJpYnV0ZSBoYXMgdGhlIHZhbHVlIHllcywgdGhlbiB0aGUKLSAgICogWFNMVCB0cmFuc2Zvcm1lciBzaG91bGQgdGVybWluYXRlIHByb2Nlc3NpbmcgYWZ0ZXIgc2VuZGluZwotICAgKiB0aGUgbWVzc2FnZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgbm8uCi0gICAqCi0gICAqIEByZXR1cm4gdmFsdWUgb2YgInRlcm1pbmF0ZSIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0VGVybWluYXRlKCkKLSAgewotICAgIHJldHVybiBtX3Rlcm1pbmF0ZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRva2VuIElEIGZvciB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0WFNMVG9rZW4oKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9NRVNTQUdFOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIGVsZW1lbnQgCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfTUVTU0FHRV9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogU2VuZCBhIG1lc3NhZ2UgdG8gZGlhZ25vc3RpY3MuCi0gICAqIFRoZSB4c2w6bWVzc2FnZSBpbnN0cnVjdGlvbiBzZW5kcyBhIG1lc3NhZ2UgaW4gYSB3YXkgdGhhdAotICAgKiBpcyBkZXBlbmRlbnQgb24gdGhlIFhTTFQgdHJhbnNmb3JtZXIuIFRoZSBjb250ZW50IG9mIHRoZSB4c2w6bWVzc2FnZQotICAgKiBpbnN0cnVjdGlvbiBpcyBhIHRlbXBsYXRlLiBUaGUgeHNsOm1lc3NhZ2UgaXMgaW5zdGFudGlhdGVkIGJ5Ci0gICAqIGluc3RhbnRpYXRpbmcgdGhlIGNvbnRlbnQgdG8gY3JlYXRlIGFuIFhNTCBmcmFnbWVudC4gVGhpcyBYTUwKLSAgICogZnJhZ21lbnQgaXMgdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2UuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotCi0gICAgU3RyaW5nIGRhdGEgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1Ub1N0cmluZyh0aGlzKTsKLQotICAgIHRyYW5zZm9ybWVyLmdldE1zZ01ncigpLm1lc3NhZ2UodGhpcywgZGF0YSwgbV90ZXJtaW5hdGUpOwotICAgIAotICAgIGlmKG1fdGVybWluYXRlKQotICAgICAgdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1NUWUxFU0hFRVRfRElSRUNURURfVEVSTUlOQVRJT04sIG51bGwpKSk7IC8vIlN0eWxlc2hlZXQgZGlyZWN0ZWQgdGVybWluYXRpb24iKSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtTnVtYmVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbU51bWJlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZTNhZjBmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtTnVtYmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTAxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZTsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OwotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuWFBhdGhQYXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3RyaW5nQnVmZmVyUG9vbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5EZWNpbWFsVG9Sb21hbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLkNvdW50ZXJzVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTm9kZVZlY3RvcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8vIGltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmR0bS4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDpudW1iZXIuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpudW1iZXIgRU1QVFk+Ci0gKiA8IUFUVExJU1QgeHNsOm51bWJlcgotICogICAgbGV2ZWwgKHNpbmdsZXxtdWx0aXBsZXxhbnkpICJzaW5nbGUiCi0gKiAgICBjb3VudCAlcGF0dGVybjsgI0lNUExJRUQKLSAqICAgIGZyb20gJXBhdHRlcm47ICNJTVBMSUVECi0gKiAgICB2YWx1ZSAlZXhwcjsgI0lNUExJRUQKLSAqICAgIGZvcm1hdCAlYXZ0OyAnMScKLSAqICAgIGxhbmcgJWF2dDsgI0lNUExJRUQKLSAqICAgIGxldHRlci12YWx1ZSAlYXZ0OyAjSU1QTElFRAotICogICAgZ3JvdXBpbmctc2VwYXJhdG9yICVhdnQ7ICNJTVBMSUVECi0gKiAgICBncm91cGluZy1zaXplICVhdnQ7ICNJTVBMSUVECi0gKiA+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNudW1iZXIiPm51bWJlciBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtTnVtYmVyIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBPbmx5IG5vZGVzIGFyZSBjb3VudGVkIHRoYXQgbWF0Y2ggdGhpcyBwYXR0ZXJuLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFhQYXRoIG1fY291bnRNYXRjaFBhdHRlcm4gPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJjb3VudCIgYXR0cmlidXRlLgotICAgKiBUaGUgY291bnQgYXR0cmlidXRlIGlzIGEgcGF0dGVybiB0aGF0IHNwZWNpZmllcyB3aGF0IG5vZGVzCi0gICAqIHNob3VsZCBiZSBjb3VudGVkIGF0IHRob3NlIGxldmVscy4gSWYgY291bnQgYXR0cmlidXRlIGlzIG5vdAotICAgKiBzcGVjaWZpZWQsIHRoZW4gaXQgZGVmYXVsdHMgdG8gdGhlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIGFueQotICAgKiBub2RlIHdpdGggdGhlIHNhbWUgbm9kZSB0eXBlIGFzIHRoZSBjdXJyZW50IG5vZGUgYW5kLCBpZiB0aGUKLSAgICogY3VycmVudCBub2RlIGhhcyBhbiBleHBhbmRlZC1uYW1lLCB3aXRoIHRoZSBzYW1lIGV4cGFuZGVkLW5hbWUKLSAgICogYXMgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IGZvciAiY291bnQiIGF0dHJpYnV0ZS4gCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDb3VudChYUGF0aCB2KQotICB7Ci0gICAgbV9jb3VudE1hdGNoUGF0dGVybiA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAiY291bnQiIGF0dHJpYnV0ZS4KLSAgICogVGhlIGNvdW50IGF0dHJpYnV0ZSBpcyBhIHBhdHRlcm4gdGhhdCBzcGVjaWZpZXMgd2hhdCBub2RlcwotICAgKiBzaG91bGQgYmUgY291bnRlZCBhdCB0aG9zZSBsZXZlbHMuIElmIGNvdW50IGF0dHJpYnV0ZSBpcyBub3QKLSAgICogc3BlY2lmaWVkLCB0aGVuIGl0IGRlZmF1bHRzIHRvIHRoZSBwYXR0ZXJuIHRoYXQgbWF0Y2hlcyBhbnkKLSAgICogbm9kZSB3aXRoIHRoZSBzYW1lIG5vZGUgdHlwZSBhcyB0aGUgY3VycmVudCBub2RlIGFuZCwgaWYgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSBoYXMgYW4gZXhwYW5kZWQtbmFtZSwgd2l0aCB0aGUgc2FtZSBleHBhbmRlZC1uYW1lCi0gICAqIGFzIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgImNvdW50IiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgWFBhdGggZ2V0Q291bnQoKQotICB7Ci0gICAgcmV0dXJuIG1fY291bnRNYXRjaFBhdHRlcm47Ci0gIH0KLQotICAvKioKLSAgICogU3BlY2lmaWVzIHdoZXJlIHRvIGNvdW50IGZyb20uCi0gICAqIEZvciBsZXZlbD0ic2luZ2xlIiBvciBsZXZlbD0ibXVsdGlwbGUiOgotICAgKiBPbmx5IGFuY2VzdG9ycyB0aGF0IGFyZSBzZWFyY2hlZCBhcmUKLSAgICogdGhvc2UgdGhhdCBhcmUgZGVzY2VuZGFudHMgb2YgdGhlIG5lYXJlc3QgYW5jZXN0b3IgdGhhdCBtYXRjaGVzCi0gICAqIHRoZSBmcm9tIHBhdHRlcm4uCi0gICAqIEZvciBsZXZlbD0iYW55OgotICAgKiBPbmx5IG5vZGVzIGFmdGVyIHRoZSBmaXJzdCBub2RlIGJlZm9yZSB0aGUKLSAgICogY3VycmVudCBub2RlIHRoYXQgbWF0Y2ggdGhlIGZyb20gcGF0dGVybiBhcmUgY29uc2lkZXJlZC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX2Zyb21NYXRjaFBhdHRlcm4gPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJmcm9tIiBhdHRyaWJ1dGUuIFNwZWNpZmllcyB3aGVyZSB0byBjb3VudCBmcm9tLgotICAgKiBGb3IgbGV2ZWw9InNpbmdsZSIgb3IgbGV2ZWw9Im11bHRpcGxlIjoKLSAgICogT25seSBhbmNlc3RvcnMgdGhhdCBhcmUgc2VhcmNoZWQgYXJlCi0gICAqIHRob3NlIHRoYXQgYXJlIGRlc2NlbmRhbnRzIG9mIHRoZSBuZWFyZXN0IGFuY2VzdG9yIHRoYXQgbWF0Y2hlcwotICAgKiB0aGUgZnJvbSBwYXR0ZXJuLgotICAgKiBGb3IgbGV2ZWw9ImFueToKLSAgICogT25seSBub2RlcyBhZnRlciB0aGUgZmlyc3Qgbm9kZSBiZWZvcmUgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSB0aGF0IG1hdGNoIHRoZSBmcm9tIHBhdHRlcm4gYXJlIGNvbnNpZGVyZWQuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgImZyb20iIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEZyb20oWFBhdGggdikKLSAgewotICAgIG1fZnJvbU1hdGNoUGF0dGVybiA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAiZnJvbSIgYXR0cmlidXRlLgotICAgKiBGb3IgbGV2ZWw9InNpbmdsZSIgb3IgbGV2ZWw9Im11bHRpcGxlIjoKLSAgICogT25seSBhbmNlc3RvcnMgdGhhdCBhcmUgc2VhcmNoZWQgYXJlCi0gICAqIHRob3NlIHRoYXQgYXJlIGRlc2NlbmRhbnRzIG9mIHRoZSBuZWFyZXN0IGFuY2VzdG9yIHRoYXQgbWF0Y2hlcwotICAgKiB0aGUgZnJvbSBwYXR0ZXJuLgotICAgKiBGb3IgbGV2ZWw9ImFueToKLSAgICogT25seSBub2RlcyBhZnRlciB0aGUgZmlyc3Qgbm9kZSBiZWZvcmUgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSB0aGF0IG1hdGNoIHRoZSBmcm9tIHBhdHRlcm4gYXJlIGNvbnNpZGVyZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgImZyb20iIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBYUGF0aCBnZXRGcm9tKCkKLSAgewotICAgIHJldHVybiBtX2Zyb21NYXRjaFBhdHRlcm47Ci0gIH0KLQotICAvKioKLSAgICogV2hlbiBsZXZlbD0ic2luZ2xlIiwgaXQgZ29lcyB1cCB0byB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgYW5jZXN0b3Itb3Itc2VsZiBheGlzCi0gICAqIHRoYXQgbWF0Y2hlcyB0aGUgY291bnQgcGF0dGVybiwgYW5kIGNvbnN0cnVjdHMgYSBsaXN0IG9mIGxlbmd0aCBvbmUgY29udGFpbmluZwotICAgKiBvbmUgcGx1cyB0aGUgbnVtYmVyIG9mIHByZWNlZGluZyBzaWJsaW5ncyBvZiB0aGF0IGFuY2VzdG9yIHRoYXQgbWF0Y2ggdGhlIGNvdW50Ci0gICAqIHBhdHRlcm4uIElmIHRoZXJlIGlzIG5vIHN1Y2ggYW5jZXN0b3IsIGl0IGNvbnN0cnVjdHMgYW4gZW1wdHkgbGlzdC4gSWYgdGhlIGZyb20KLSAgICogYXR0cmlidXRlIGlzIHNwZWNpZmllZCwgdGhlbiB0aGUgb25seSBhbmNlc3RvcnMgdGhhdCBhcmUgc2VhcmNoZWQgYXJlIHRob3NlCi0gICAqIHRoYXQgYXJlIGRlc2NlbmRhbnRzIG9mIHRoZSBuZWFyZXN0IGFuY2VzdG9yIHRoYXQgbWF0Y2hlcyB0aGUgZnJvbSBwYXR0ZXJuLgotICAgKiBQcmVjZWRpbmcgc2libGluZ3MgaGFzIHRoZSBzYW1lIG1lYW5pbmcgaGVyZSBhcyB3aXRoIHRoZSBwcmVjZWRpbmctc2libGluZyBheGlzLgotICAgKgotICAgKiBXaGVuIGxldmVsPSJtdWx0aXBsZSIsIGl0IGNvbnN0cnVjdHMgYSBsaXN0IG9mIGFsbCBhbmNlc3RvcnMgb2YgdGhlIGN1cnJlbnQgbm9kZQotICAgKiBpbiBkb2N1bWVudCBvcmRlciBmb2xsb3dlZCBieSB0aGUgZWxlbWVudCBpdHNlbGY7IGl0IHRoZW4gc2VsZWN0cyBmcm9tIHRoZSBsaXN0Ci0gICAqIHRob3NlIG5vZGVzIHRoYXQgbWF0Y2ggdGhlIGNvdW50IHBhdHRlcm47IGl0IHRoZW4gbWFwcyBlYWNoIG5vZGUgaW4gdGhlIGxpc3QgdG8KLSAgICogb25lIHBsdXMgdGhlIG51bWJlciBvZiBwcmVjZWRpbmcgc2libGluZ3Mgb2YgdGhhdCBub2RlIHRoYXQgbWF0Y2ggdGhlIGNvdW50IHBhdHRlcm4uCi0gICAqIElmIHRoZSBmcm9tIGF0dHJpYnV0ZSBpcyBzcGVjaWZpZWQsIHRoZW4gdGhlIG9ubHkgYW5jZXN0b3JzIHRoYXQgYXJlIHNlYXJjaGVkIGFyZQotICAgKiB0aG9zZSB0aGF0IGFyZSBkZXNjZW5kYW50cyBvZiB0aGUgbmVhcmVzdCBhbmNlc3RvciB0aGF0IG1hdGNoZXMgdGhlIGZyb20gcGF0dGVybi4KLSAgICogUHJlY2VkaW5nIHNpYmxpbmdzIGhhcyB0aGUgc2FtZSBtZWFuaW5nIGhlcmUgYXMgd2l0aCB0aGUgcHJlY2VkaW5nLXNpYmxpbmcgYXhpcy4KLSAgICoKLSAgICogV2hlbiBsZXZlbD0iYW55IiwgaXQgY29uc3RydWN0cyBhIGxpc3Qgb2YgbGVuZ3RoIG9uZSBjb250YWluaW5nIHRoZSBudW1iZXIgb2YKLSAgICogbm9kZXMgdGhhdCBtYXRjaCB0aGUgY291bnQgcGF0dGVybiBhbmQgYmVsb25nIHRvIHRoZSBzZXQgY29udGFpbmluZyB0aGUgY3VycmVudAotICAgKiBub2RlIGFuZCBhbGwgbm9kZXMgYXQgYW55IGxldmVsIG9mIHRoZSBkb2N1bWVudCB0aGF0IGFyZSBiZWZvcmUgdGhlIGN1cnJlbnQgbm9kZQotICAgKiBpbiBkb2N1bWVudCBvcmRlciwgZXhjbHVkaW5nIGFueSBuYW1lc3BhY2UgYW5kIGF0dHJpYnV0ZSBub2RlcyAoaW4gb3RoZXIgd29yZHMKLSAgICogdGhlIHVuaW9uIG9mIHRoZSBtZW1iZXJzIG9mIHRoZSBwcmVjZWRpbmcgYW5kIGFuY2VzdG9yLW9yLXNlbGYgYXhlcykuIElmIHRoZQotICAgKiBmcm9tIGF0dHJpYnV0ZSBpcyBzcGVjaWZpZWQsIHRoZW4gb25seSBub2RlcyBhZnRlciB0aGUgZmlyc3Qgbm9kZSBiZWZvcmUgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSB0aGF0IG1hdGNoIHRoZSBmcm9tIHBhdHRlcm4gYXJlIGNvbnNpZGVyZWQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgaW50IG1fbGV2ZWwgPSBDb25zdGFudHMuTlVNQkVSTEVWRUxfU0lOR0xFOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJsZXZlbCIgYXR0cmlidXRlLgotICAgKiBUaGUgbGV2ZWwgYXR0cmlidXRlIHNwZWNpZmllcyB3aGF0IGxldmVscyBvZiB0aGUgc291cmNlIHRyZWUgc2hvdWxkCi0gICAqIGJlIGNvbnNpZGVyZWQ7IGl0IGhhcyB0aGUgdmFsdWVzIHNpbmdsZSwgbXVsdGlwbGUgb3IgYW55LiBUaGUgZGVmYXVsdAotICAgKiBpcyBzaW5nbGUuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgImxldmVsIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMZXZlbChpbnQgdikKLSAgewotICAgIG1fbGV2ZWwgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImxldmVsIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBsZXZlbCBhdHRyaWJ1dGUgc3BlY2lmaWVzIHdoYXQgbGV2ZWxzIG9mIHRoZSBzb3VyY2UgdHJlZSBzaG91bGQKLSAgICogYmUgY29uc2lkZXJlZDsgaXQgaGFzIHRoZSB2YWx1ZXMgc2luZ2xlLCBtdWx0aXBsZSBvciBhbnkuIFRoZSBkZWZhdWx0Ci0gICAqIGlzIHNpbmdsZS4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiAibGV2ZWwiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGV2ZWwoKQotICB7Ci0gICAgcmV0dXJuIG1fbGV2ZWw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHZhbHVlIGF0dHJpYnV0ZSBjb250YWlucyBhbiBleHByZXNzaW9uLiBUaGUgZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQKLSAgICogYW5kIHRoZSByZXN1bHRpbmcgb2JqZWN0IGlzIGNvbnZlcnRlZCB0byBhIG51bWJlciBhcyBpZiBieSBhIGNhbGwgdG8gdGhlCi0gICAqIG51bWJlciBmdW5jdGlvbi4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX3ZhbHVlRXhwciA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInZhbHVlIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSB2YWx1ZSBhdHRyaWJ1dGUgY29udGFpbnMgYW4gZXhwcmVzc2lvbi4gVGhlIGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkCi0gICAqIGFuZCB0aGUgcmVzdWx0aW5nIG9iamVjdCBpcyBjb252ZXJ0ZWQgdG8gYSBudW1iZXIgYXMgaWYgYnkgYSBjYWxsIHRvIHRoZQotICAgKiBudW1iZXIgZnVuY3Rpb24uCi0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgInZhbHVlIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShYUGF0aCB2KQotICB7Ci0gICAgbV92YWx1ZUV4cHIgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgInZhbHVlIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSB2YWx1ZSBhdHRyaWJ1dGUgY29udGFpbnMgYW4gZXhwcmVzc2lvbi4gVGhlIGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkCi0gICAqIGFuZCB0aGUgcmVzdWx0aW5nIG9iamVjdCBpcyBjb252ZXJ0ZWQgdG8gYSBudW1iZXIgYXMgaWYgYnkgYSBjYWxsIHRvIHRoZQotICAgKiBudW1iZXIgZnVuY3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgInZhbHVlIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgWFBhdGggZ2V0VmFsdWUoKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsdWVFeHByOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAiZm9ybWF0IiBhdHRyaWJ1dGUgaXMgdXNlZCB0byBjb250cm9sIGNvbnZlcnNpb24gb2YgYSBsaXN0IG9mCi0gICAqIG51bWJlcnMgaW50byBhIHN0cmluZy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NvbnZlcnQiPmNvbnZlcnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEFWVCBtX2Zvcm1hdF9hdnQgPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJmb3JtYXQiIGF0dHJpYnV0ZS4KLSAgICogVGhlICJmb3JtYXQiIGF0dHJpYnV0ZSBpcyB1c2VkIHRvIGNvbnRyb2wgY29udmVyc2lvbiBvZiBhIGxpc3Qgb2YKLSAgICogbnVtYmVycyBpbnRvIGEgc3RyaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29udmVydCI+Y29udmVydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgImZvcm1hdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Rm9ybWF0KEFWVCB2KQotICB7Ci0gICAgbV9mb3JtYXRfYXZ0ID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJmb3JtYXQiIGF0dHJpYnV0ZS4KLSAgICogVGhlICJmb3JtYXQiIGF0dHJpYnV0ZSBpcyB1c2VkIHRvIGNvbnRyb2wgY29udmVyc2lvbiBvZiBhIGxpc3Qgb2YKLSAgICogbnVtYmVycyBpbnRvIGEgc3RyaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29udmVydCI+Y29udmVydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgImZvcm1hdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIEFWVCBnZXRGb3JtYXQoKQotICB7Ci0gICAgcmV0dXJuIG1fZm9ybWF0X2F2dDsKLSAgfQotCi0gIC8qKgotICAgKiBXaGVuIG51bWJlcmluZyB3aXRoIGFuIGFscGhhYmV0aWMgc2VxdWVuY2UsIHRoZSBsYW5nIGF0dHJpYnV0ZQotICAgKiBzcGVjaWZpZXMgd2hpY2ggbGFuZ3VhZ2UncyBhbHBoYWJldCBpcyB0byBiZSB1c2VkLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEFWVCBtX2xhbmdfYXZ0ID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAibGFuZyIgYXR0cmlidXRlLgotICAgKiBXaGVuIG51bWJlcmluZyB3aXRoIGFuIGFscGhhYmV0aWMgc2VxdWVuY2UsIHRoZSBsYW5nIGF0dHJpYnV0ZQotICAgKiBzcGVjaWZpZXMgd2hpY2ggbGFuZ3VhZ2UncyBhbHBoYWJldCBpcyB0byBiZSB1c2VkOyBpdCBoYXMgdGhlIHNhbWUKLSAgICogcmFuZ2Ugb2YgdmFsdWVzIGFzIHhtbDpsYW5nIFtYTUxdOyBpZiBubyBsYW5nIHZhbHVlIGlzIHNwZWNpZmllZCwKLSAgICogdGhlIGxhbmd1YWdlIHNob3VsZCBiZSBkZXRlcm1pbmVkIGZyb20gdGhlIHN5c3RlbSBlbnZpcm9ubWVudC4KLSAgICogSW1wbGVtZW50ZXJzIHNob3VsZCBkb2N1bWVudCBmb3Igd2hpY2ggbGFuZ3VhZ2VzIHRoZXkgc3VwcG9ydCBudW1iZXJpbmcuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNjb252ZXJ0Ij5jb252ZXJ0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IGZvciAibGFuZyIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TGFuZyhBVlQgdikKLSAgewotICAgIG1fbGFuZ19hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImxhbmciIGF0dHJpYnV0ZS4KLSAgICogV2hlbiBudW1iZXJpbmcgd2l0aCBhbiBhbHBoYWJldGljIHNlcXVlbmNlLCB0aGUgbGFuZyBhdHRyaWJ1dGUKLSAgICogc3BlY2lmaWVzIHdoaWNoIGxhbmd1YWdlJ3MgYWxwaGFiZXQgaXMgdG8gYmUgdXNlZDsgaXQgaGFzIHRoZSBzYW1lCi0gICAqIHJhbmdlIG9mIHZhbHVlcyBhcyB4bWw6bGFuZyBbWE1MXTsgaWYgbm8gbGFuZyB2YWx1ZSBpcyBzcGVjaWZpZWQsCi0gICAqIHRoZSBsYW5ndWFnZSBzaG91bGQgYmUgZGV0ZXJtaW5lZCBmcm9tIHRoZSBzeXN0ZW0gZW52aXJvbm1lbnQuCi0gICAqIEltcGxlbWVudGVycyBzaG91bGQgZG9jdW1lbnQgZm9yIHdoaWNoIGxhbmd1YWdlcyB0aGV5IHN1cHBvcnQgbnVtYmVyaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29udmVydCI+Y29udmVydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2ZyICJsYW5nIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgQVZUIGdldExhbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fbGFuZ19hdnQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGxldHRlci12YWx1ZSBhdHRyaWJ1dGUgZGlzYW1iaWd1YXRlcyBiZXR3ZWVuIG51bWJlcmluZwotICAgKiBzZXF1ZW5jZXMgdGhhdCB1c2UgbGV0dGVycy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBBVlQgbV9sZXR0ZXJ2YWx1ZV9hdnQgPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJsZXR0ZXItdmFsdWUiIGF0dHJpYnV0ZS4KLSAgICogVGhlIGxldHRlci12YWx1ZSBhdHRyaWJ1dGUgZGlzYW1iaWd1YXRlcyBiZXR3ZWVuIG51bWJlcmluZyBzZXF1ZW5jZXMKLSAgICogdGhhdCB1c2UgbGV0dGVycy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NvbnZlcnQiPmNvbnZlcnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yICJsZXR0ZXItdmFsdWUiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExldHRlclZhbHVlKEFWVCB2KQotICB7Ci0gICAgbV9sZXR0ZXJ2YWx1ZV9hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImxldHRlci12YWx1ZSIgYXR0cmlidXRlLgotICAgKiBUaGUgbGV0dGVyLXZhbHVlIGF0dHJpYnV0ZSBkaXNhbWJpZ3VhdGVzIGJldHdlZW4gbnVtYmVyaW5nIHNlcXVlbmNlcwotICAgKiB0aGF0IHVzZSBsZXR0ZXJzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29udmVydCI+Y29udmVydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgdG8gc2V0IGZvciAibGV0dGVyLXZhbHVlIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgQVZUIGdldExldHRlclZhbHVlKCkKLSAgewotICAgIHJldHVybiBtX2xldHRlcnZhbHVlX2F2dDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgZ3JvdXBpbmctc2VwYXJhdG9yIGF0dHJpYnV0ZSBnaXZlcyB0aGUgc2VwYXJhdG9yCi0gICAqIHVzZWQgYXMgYSBncm91cGluZyAoZS5nLiB0aG91c2FuZHMpIHNlcGFyYXRvciBpbiBkZWNpbWFsCi0gICAqIG51bWJlcmluZyBzZXF1ZW5jZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgQVZUIG1fZ3JvdXBpbmdTZXBhcmF0b3JfYXZ0ID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAiZ3JvdXBpbmctc2VwYXJhdG9yIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBncm91cGluZy1zZXBhcmF0b3IgYXR0cmlidXRlIGdpdmVzIHRoZSBzZXBhcmF0b3IKLSAgICogdXNlZCBhcyBhIGdyb3VwaW5nIChlLmcuIHRob3VzYW5kcykgc2VwYXJhdG9yIGluIGRlY2ltYWwKLSAgICogbnVtYmVyaW5nIHNlcXVlbmNlcy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NvbnZlcnQiPmNvbnZlcnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yICJncm91cGluZy1zZXBhcmF0b3IiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEdyb3VwaW5nU2VwYXJhdG9yKEFWVCB2KQotICB7Ci0gICAgbV9ncm91cGluZ1NlcGFyYXRvcl9hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImdyb3VwaW5nLXNlcGFyYXRvciIgYXR0cmlidXRlLgotICAgKiBUaGUgZ3JvdXBpbmctc2VwYXJhdG9yIGF0dHJpYnV0ZSBnaXZlcyB0aGUgc2VwYXJhdG9yCi0gICAqIHVzZWQgYXMgYSBncm91cGluZyAoZS5nLiB0aG91c2FuZHMpIHNlcGFyYXRvciBpbiBkZWNpbWFsCi0gICAqIG51bWJlcmluZyBzZXF1ZW5jZXMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNjb252ZXJ0Ij5jb252ZXJ0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiAiZ3JvdXBpbmctc2VwYXJhdG9yIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgQVZUIGdldEdyb3VwaW5nU2VwYXJhdG9yKCkKLSAgewotICAgIHJldHVybiBtX2dyb3VwaW5nU2VwYXJhdG9yX2F2dDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgb3B0aW9uYWwgZ3JvdXBpbmctc2l6ZSBzcGVjaWZpZXMgdGhlIHNpemUgKG5vcm1hbGx5IDMpIG9mIHRoZSBncm91cGluZy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBBVlQgbV9ncm91cGluZ1NpemVfYXZ0ID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAiZ3JvdXBpbmctc2l6ZSIgYXR0cmlidXRlLgotICAgKiBUaGUgb3B0aW9uYWwgZ3JvdXBpbmctc2l6ZSBzcGVjaWZpZXMgdGhlIHNpemUgKG5vcm1hbGx5IDMpIG9mIHRoZSBncm91cGluZy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NvbnZlcnQiPmNvbnZlcnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yICJncm91cGluZy1zaXplIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRHcm91cGluZ1NpemUoQVZUIHYpCi0gIHsKLSAgICBtX2dyb3VwaW5nU2l6ZV9hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImdyb3VwaW5nLXNpemUiIGF0dHJpYnV0ZS4KLSAgICogVGhlIG9wdGlvbmFsIGdyb3VwaW5nLXNpemUgc3BlY2lmaWVzIHRoZSBzaXplIChub3JtYWxseSAzKSBvZiB0aGUgZ3JvdXBpbmcuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNjb252ZXJ0Ij5jb252ZXJ0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiAiZ3JvdXBpbmctc2l6ZSIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIEFWVCBnZXRHcm91cGluZ1NpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fZ3JvdXBpbmdTaXplX2F2dDsKLSAgfQotCi0gIC8qKgotICAgKiBTaG91bGRuJ3QgdGhpcyBiZSBpbiB0aGUgdHJhbnNmb3JtZXI/ICBCaWcgd29ycmllcyBhYm91dCB0aHJlYWRzLi4uCi0gICAqLwotCi0gIC8vIHByaXZhdGUgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgLyoqCi0gICAqIFRhYmxlIHRvIGhlbHAgaW4gY29udmVydGluZyBkZWNpbWFscyB0byByb21hbiBudW1lcmFscy4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLkRlY2ltYWxUb1JvbWFuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHN0YXRpYyBEZWNpbWFsVG9Sb21hbiBtX3JvbWFuQ29udmVydFRhYmxlW10gPSB7Ci0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDEwMDAsICJNIiwgOTAwLCAiQ00iKSwKLSAgICBuZXcgRGVjaW1hbFRvUm9tYW4oNTAwLCAiRCIsIDQwMCwgIkNEIiksCi0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDEwMEwsICJDIiwgOTBMLCAiWEMiKSwKLSAgICBuZXcgRGVjaW1hbFRvUm9tYW4oNTBMLCAiTCIsIDQwTCwgIlhMIiksCi0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDEwTCwgIlgiLCA5TCwgIklYIiksCi0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDVMLCAiViIsIDRMLCAiSVYiKSwKLSAgICBuZXcgRGVjaW1hbFRvUm9tYW4oMUwsICJJIiwgMUwsICJJIikgfTsKLQotICAvKioKLSAgICogQ2hhcnMgZm9yIGNvbnZlcnRpbmcgaW50ZWdlcnMgaW50byBhbHBoYSBjb3VudHMuCi0gICAqIEBzZWUgVHJhbnNmb3JtZXJJbXBsI2ludDJhbHBoYUNvdW50Ci0gICAqLwotICBwcml2YXRlIHN0YXRpYyBjaGFyW10gbV9hbHBoYUNvdW50VGFibGUgPSBudWxsOwotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICBTdHlsZXNoZWV0Um9vdC5Db21wb3NlU3RhdGUgY3N0YXRlID0gc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCk7Ci0gICAgamF2YS51dGlsLlZlY3RvciB2bmFtZXMgPSBjc3RhdGUuZ2V0VmFyaWFibGVOYW1lcygpOwotICAgIGlmKG51bGwgIT0gbV9jb3VudE1hdGNoUGF0dGVybikKLSAgICAgIG1fY291bnRNYXRjaFBhdHRlcm4uZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgaWYobnVsbCAhPSBtX2Zvcm1hdF9hdnQpCi0gICAgICBtX2Zvcm1hdF9hdnQuZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgaWYobnVsbCAhPSBtX2Zyb21NYXRjaFBhdHRlcm4pCi0gICAgICBtX2Zyb21NYXRjaFBhdHRlcm4uZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgaWYobnVsbCAhPSBtX2dyb3VwaW5nU2VwYXJhdG9yX2F2dCkKLSAgICAgIG1fZ3JvdXBpbmdTZXBhcmF0b3JfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV9ncm91cGluZ1NpemVfYXZ0KQotICAgICAgbV9ncm91cGluZ1NpemVfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV9sYW5nX2F2dCkKLSAgICAgIG1fbGFuZ19hdnQuZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgaWYobnVsbCAhPSBtX2xldHRlcnZhbHVlX2F2dCkKLSAgICAgIG1fbGV0dGVydmFsdWVfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV92YWx1ZUV4cHIpCi0gICAgICBtX3ZhbHVlRXhwci5maXh1cFZhcmlhYmxlcyh2bmFtZXMsIGNzdGF0ZS5nZXRHbG9iYWxzU2l6ZSgpKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX05VTUJFUjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZWxlbWVudCdzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9OVU1CRVJfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4geHNsOm51bWJlciBpbnN0cnVjdGlvbi4gVGhlIHhzbDpudW1iZXIgZWxlbWVudCBpcwotICAgKiB1c2VkIHRvIGluc2VydCBhIGZvcm1hdHRlZCBudW1iZXIgaW50byB0aGUgcmVzdWx0IHRyZWUuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotCi0gICAgaW50IHNvdXJjZU5vZGUgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXRDdXJyZW50Tm9kZSgpOwotICAgIFN0cmluZyBjb3VudFN0cmluZyA9IGdldENvdW50U3RyaW5nKHRyYW5zZm9ybWVyLCBzb3VyY2VOb2RlKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmdldFJlc3VsdFRyZWVIYW5kbGVyKCkuY2hhcmFjdGVycyhjb3VudFN0cmluZy50b0NoYXJBcnJheSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIGNvdW50U3RyaW5nLmxlbmd0aCgpKTsKLSAgICB9Ci0gICAgY2F0Y2goU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIGNoaWxkIHRvIHRoZSBjaGlsZCBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYWRkIHRvIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHJldHVybiBDaGlsZCBqdXN0IGFkZGVkIHRvIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGFwcGVuZENoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgbmV3Q2hpbGQpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfQURELAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgbmV3Q2hpbGQuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0Tm9kZU5hbWUoKSB9KTsgIC8vIkNhbiBub3QgYWRkICIgKygoRWxlbVRlbXBsYXRlRWxlbWVudCluZXdDaGlsZCkubV9lbGVtTmFtZSArCi0KLSAgICAvLyIgdG8gIiArIHRoaXMubV9lbGVtTmFtZSk7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSAnZnJvbScgcGF0dGVybiAoYWxhIHhzbDpudW1iZXIpLCBhIG1hdGNoIHBhdHRlcm4KLSAgICogYW5kIGEgY29udGV4dCwgZmluZCB0aGUgZmlyc3QgYW5jZXN0b3IgdGhhdCBtYXRjaGVzIHRoZQotICAgKiBwYXR0ZXJuIChpbmNsdWRpbmcgdGhlIGNvbnRleHQgaGFuZGVkIGluKS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIHN0YXRlIGZvciB0aGlzLgotICAgKiBAcGFyYW0gZnJvbU1hdGNoUGF0dGVybiBUaGUgYW5jZXN0b3IgbXVzdCBtYXRjaCB0aGlzIHBhdHRlcm4uCi0gICAqIEBwYXJhbSBjb3VudE1hdGNoUGF0dGVybiBUaGUgYW5jZXN0b3IgbXVzdCBhbHNvIG1hdGNoIHRoaXMgcGF0dGVybi4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCBuYW1lc3BhY2VzIGluIHRoZQotICAgKiBxdWVyaWVzIGFyZSBzdXBwb3NlZCB0byBiZSBleHBhbmRlZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZmlyc3QgYW5jZXN0b3IgdGhhdCBtYXRjaGVzIHRoZSBnaXZlbiBwYXR0ZXJuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgaW50IGZpbmRBbmNlc3RvcigKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIFhQYXRoIGZyb21NYXRjaFBhdHRlcm4sIFhQYXRoIGNvdW50TWF0Y2hQYXR0ZXJuLCAKLSAgICAgICAgICBpbnQgY29udGV4dCwgRWxlbU51bWJlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgd2hpbGUgKERUTS5OVUxMICE9IGNvbnRleHQpCi0gICAgewotICAgICAgaWYgKG51bGwgIT0gZnJvbU1hdGNoUGF0dGVybikKLSAgICAgIHsKLSAgICAgICAgaWYgKGZyb21NYXRjaFBhdHRlcm4uZ2V0TWF0Y2hTY29yZSh4Y3R4dCwgY29udGV4dCkKLSAgICAgICAgICAgICAgICAhPSBYUGF0aC5NQVRDSF9TQ09SRV9OT05FKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvL2NvbnRleHQgPSBudWxsOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChudWxsICE9IGNvdW50TWF0Y2hQYXR0ZXJuKQotICAgICAgewotICAgICAgICBpZiAoY291bnRNYXRjaFBhdHRlcm4uZ2V0TWF0Y2hTY29yZSh4Y3R4dCwgY29udGV4dCkKLSAgICAgICAgICAgICAgICAhPSBYUGF0aC5NQVRDSF9TQ09SRV9OT05FKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgY29udGV4dCA9IGR0bS5nZXRQYXJlbnQoY29udGV4dCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSAnZnJvbScgcGF0dGVybiAoYWxhIHhzbDpudW1iZXIpLCBhIG1hdGNoIHBhdHRlcm4KLSAgICogYW5kIGEgY29udGV4dCwgZmluZCB0aGUgZmlyc3QgYW5jZXN0b3IgdGhhdCBtYXRjaGVzIHRoZQotICAgKiBwYXR0ZXJuIChpbmNsdWRpbmcgdGhlIGNvbnRleHQgaGFuZGVkIGluKS4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIHN0YXRlIGZvciB0aGlzLgotICAgKiBAcGFyYW0gZnJvbU1hdGNoUGF0dGVybiBUaGUgYW5jZXN0b3IgbXVzdCBtYXRjaCB0aGlzIHBhdHRlcm4uCi0gICAqIEBwYXJhbSBjb3VudE1hdGNoUGF0dGVybiBUaGUgYW5jZXN0b3IgbXVzdCBhbHNvIG1hdGNoIHRoaXMgcGF0dGVybi4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCBuYW1lc3BhY2VzIGluIHRoZQotICAgKiBxdWVyaWVzIGFyZSBzdXBwb3NlZCB0byBiZSBleHBhbmRlZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZmlyc3QgcHJlY2VkaW5nLCBhbmNlc3RvciBvciBzZWxmIG5vZGUgdGhhdCAKLSAgICogbWF0Y2hlcyB0aGUgZ2l2ZW4gcGF0dGVybgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgaW50IGZpbmRQcmVjZWRpbmdPckFuY2VzdG9yT3JTZWxmKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgWFBhdGggZnJvbU1hdGNoUGF0dGVybiwgWFBhdGggY291bnRNYXRjaFBhdHRlcm4sIAotICAgICAgICAgIGludCBjb250ZXh0LCBFbGVtTnVtYmVyIG5hbWVzcGFjZUNvbnRleHQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICB3aGlsZSAoRFRNLk5VTEwgIT0gY29udGV4dCkKLSAgICB7Ci0gICAgICBpZiAobnVsbCAhPSBmcm9tTWF0Y2hQYXR0ZXJuKQotICAgICAgewotICAgICAgICBpZiAoZnJvbU1hdGNoUGF0dGVybi5nZXRNYXRjaFNjb3JlKHhjdHh0LCBjb250ZXh0KQotICAgICAgICAgICAgICAgICE9IFhQYXRoLk1BVENIX1NDT1JFX05PTkUpCi0gICAgICAgIHsKLSAgICAgICAgICBjb250ZXh0ID0gRFRNLk5VTEw7Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobnVsbCAhPSBjb3VudE1hdGNoUGF0dGVybikKLSAgICAgIHsKLSAgICAgICAgaWYgKGNvdW50TWF0Y2hQYXR0ZXJuLmdldE1hdGNoU2NvcmUoeGN0eHQsIGNvbnRleHQpCi0gICAgICAgICAgICAgICAgIT0gWFBhdGguTUFUQ0hfU0NPUkVfTk9ORSkKLSAgICAgICAgewotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGludCBwcmV2U2libGluZyA9IGR0bS5nZXRQcmV2aW91c1NpYmxpbmcoY29udGV4dCk7Ci0KLSAgICAgIGlmIChEVE0uTlVMTCA9PSBwcmV2U2libGluZykKLSAgICAgIHsKLSAgICAgICAgY29udGV4dCA9IGR0bS5nZXRQYXJlbnQoY29udGV4dCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gTm93IGdvIGRvd24gdGhlIGNoYWluIG9mIGNoaWxkcmVuIG9mIHRoaXMgc2libGluZyAKLSAgICAgICAgY29udGV4dCA9IGR0bS5nZXRMYXN0Q2hpbGQocHJldlNpYmxpbmcpOwotCi0gICAgICAgIGlmIChjb250ZXh0ID09IERUTS5OVUxMKQotICAgICAgICAgIGNvbnRleHQgPSBwcmV2U2libGluZzsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gY29udGV4dDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGNvdW50IG1hdGNoIHBhdHRlcm4sIG9yIGEgZGVmYXVsdCB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUgZm9yIHRoaXMuCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0aGF0ICIuIiBleHByZXNzZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGNvdW50IG1hdGNoIHBhdHRlcm4sIG9yIGEgZGVmYXVsdCB2YWx1ZS4gCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgWFBhdGggZ2V0Q291bnRNYXRjaFBhdHRlcm4oWFBhdGhDb250ZXh0IHN1cHBvcnQsIGludCBjb250ZXh0Tm9kZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYUGF0aCBjb3VudE1hdGNoUGF0dGVybiA9IG1fY291bnRNYXRjaFBhdHRlcm47Ci0gICAgRFRNIGR0bSA9IHN1cHBvcnQuZ2V0RFRNKGNvbnRleHROb2RlKTsKLSAgICBpZiAobnVsbCA9PSBjb3VudE1hdGNoUGF0dGVybikKLSAgICB7Ci0gICAgICBzd2l0Y2ggKGR0bS5nZXROb2RlVHlwZShjb250ZXh0Tm9kZSkpCi0gICAgICB7Ci0gICAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotCi0gICAgICAgIC8vIGNvdW50TWF0Y2hQYXR0ZXJuID0gbV9zdHlsZXNoZWV0LmNyZWF0ZU1hdGNoUGF0dGVybihjb250ZXh0Tm9kZS5nZXROb2RlTmFtZSgpLCB0aGlzKTsKLSAgICAgICAgY291bnRNYXRjaFBhdHRlcm4gPSBuZXcgWFBhdGgoZHRtLmdldE5vZGVOYW1lKGNvbnRleHROb2RlKSwgdGhpcywgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGguTUFUQ0gsIHN1cHBvcnQuZ2V0RXJyb3JMaXN0ZW5lcigpKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0KLSAgICAgICAgLy8gY291bnRNYXRjaFBhdHRlcm4gPSBtX3N0eWxlc2hlZXQuY3JlYXRlTWF0Y2hQYXR0ZXJuKCJAIitjb250ZXh0Tm9kZS5nZXROb2RlTmFtZSgpLCB0aGlzKTsKLSAgICAgICAgY291bnRNYXRjaFBhdHRlcm4gPSBuZXcgWFBhdGgoIkAiICsgZHRtLmdldE5vZGVOYW1lKGNvbnRleHROb2RlKSwgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcywgWFBhdGguTUFUQ0gsIHN1cHBvcnQuZ2V0RXJyb3JMaXN0ZW5lcigpKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgY2FzZSBEVE0uVEVYVF9OT0RFIDoKLQotICAgICAgICAvLyBjb3VudE1hdGNoUGF0dGVybiA9IG1fc3R5bGVzaGVldC5jcmVhdGVNYXRjaFBhdHRlcm4oInRleHQoKSIsIHRoaXMpOwotICAgICAgICBjb3VudE1hdGNoUGF0dGVybiA9IG5ldyBYUGF0aCgidGV4dCgpIiwgdGhpcywgdGhpcywgWFBhdGguTUFUQ0gsIHN1cHBvcnQuZ2V0RXJyb3JMaXN0ZW5lcigpKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIERUTS5DT01NRU5UX05PREUgOgotCi0gICAgICAgIC8vIGNvdW50TWF0Y2hQYXR0ZXJuID0gbV9zdHlsZXNoZWV0LmNyZWF0ZU1hdGNoUGF0dGVybigiY29tbWVudCgpIiwgdGhpcyk7Ci0gICAgICAgIGNvdW50TWF0Y2hQYXR0ZXJuID0gbmV3IFhQYXRoKCJjb21tZW50KCkiLCB0aGlzLCB0aGlzLCBYUGF0aC5NQVRDSCwgc3VwcG9ydC5nZXRFcnJvckxpc3RlbmVyKCkpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREUgOgotCi0gICAgICAgIC8vIGNvdW50TWF0Y2hQYXR0ZXJuID0gbV9zdHlsZXNoZWV0LmNyZWF0ZU1hdGNoUGF0dGVybigiLyIsIHRoaXMpOwotICAgICAgICBjb3VudE1hdGNoUGF0dGVybiA9IG5ldyBYUGF0aCgiLyIsIHRoaXMsIHRoaXMsIFhQYXRoLk1BVENILCBzdXBwb3J0LmdldEVycm9yTGlzdGVuZXIoKSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLQotICAgICAgICAvLyBjb3VudE1hdGNoUGF0dGVybiA9IG1fc3R5bGVzaGVldC5jcmVhdGVNYXRjaFBhdHRlcm4oInBpKCIrY29udGV4dE5vZGUuZ2V0Tm9kZU5hbWUoKSsiKSIsIHRoaXMpOwotICAgICAgICBjb3VudE1hdGNoUGF0dGVybiA9IG5ldyBYUGF0aCgicGkoIiArIGR0bS5nZXROb2RlTmFtZShjb250ZXh0Tm9kZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiKSIsIHRoaXMsIHRoaXMsIFhQYXRoLk1BVENILCBzdXBwb3J0LmdldEVycm9yTGlzdGVuZXIoKSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIGNvdW50TWF0Y2hQYXR0ZXJuID0gbnVsbDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gY291bnRNYXRjaFBhdHRlcm47Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gWE1MIHNvdXJjZSBub2RlLCBnZXQgdGhlIGNvdW50IGFjY29yZGluZyB0byB0aGUKLSAgICogcGFyYW1ldGVycyBzZXQgdXAgYnkgdGhlIHhzbDpudW1iZXIgYXR0cmlidXRlcy4KLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIFRoZSBzb3VyY2Ugbm9kZSBiZWluZyBjb3VudGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBub2RlcwotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBTdHJpbmcgZ2V0Q291bnRTdHJpbmcoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLCBpbnQgc291cmNlTm9kZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50W10gbGlzdCA9IG51bGw7Ci0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgQ291bnRlcnNUYWJsZSBjdGFibGUgPSB0cmFuc2Zvcm1lci5nZXRDb3VudGVyc1RhYmxlKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3ZhbHVlRXhwcikKLSAgICB7Ci0gICAgICBYT2JqZWN0IGNvdW50T2JqID0gbV92YWx1ZUV4cHIuZXhlY3V0ZSh4Y3R4dCwgc291cmNlTm9kZSwgdGhpcyk7Ci0gICAgICBpbnQgY291bnQgPSAoaW50KSBqYXZhLmxhbmcuTWF0aC5mbG9vcihjb3VudE9iai5udW0oKSsgMC41KTsKLQotICAgICAgbGlzdCA9IG5ldyBpbnRbMV07Ci0gICAgICBsaXN0WzBdID0gY291bnQ7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpZiAoQ29uc3RhbnRzLk5VTUJFUkxFVkVMX0FOWSA9PSBtX2xldmVsKQotICAgICAgewotICAgICAgICBsaXN0ID0gbmV3IGludFsxXTsKLSAgICAgICAgbGlzdFswXSA9IGN0YWJsZS5jb3VudE5vZGUoeGN0eHQsIHRoaXMsIHNvdXJjZU5vZGUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBOb2RlVmVjdG9yIGFuY2VzdG9ycyA9Ci0gICAgICAgICAgZ2V0TWF0Y2hpbmdBbmNlc3RvcnMoeGN0eHQsIHNvdXJjZU5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLk5VTUJFUkxFVkVMX1NJTkdMRSA9PSBtX2xldmVsKTsKLSAgICAgICAgaW50IGxhc3RJbmRleCA9IGFuY2VzdG9ycy5zaXplKCkgLSAxOwotCi0gICAgICAgIGlmIChsYXN0SW5kZXggPj0gMCkKLSAgICAgICAgewotICAgICAgICAgIGxpc3QgPSBuZXcgaW50W2xhc3RJbmRleCArIDFdOwotCi0gICAgICAgICAgZm9yIChpbnQgaSA9IGxhc3RJbmRleDsgaSA+PSAwOyBpLS0pCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IHRhcmdldCA9IGFuY2VzdG9ycy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgICAgIGxpc3RbbGFzdEluZGV4IC0gaV0gPSBjdGFibGUuY291bnROb2RlKHhjdHh0LCB0aGlzLCB0YXJnZXQpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAobnVsbCAhPSBsaXN0KQotICAgICAgICAgICA/IGZvcm1hdE51bWJlckxpc3QodHJhbnNmb3JtZXIsIGxpc3QsIHNvdXJjZU5vZGUpIDogIiI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwcmV2aW91cyBub2RlIHRvIGJlIGNvdW50ZWQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBzdGF0ZSBmb3IgdGhpcy4KLSAgICogQHBhcmFtIHBvcyBUaGUgY3VycmVudCBub2RlCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIG5vZGUgdG8gYmUgY291bnRlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcmV2aW91c05vZGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgcG9zKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYUGF0aCBjb3VudE1hdGNoUGF0dGVybiA9IGdldENvdW50TWF0Y2hQYXR0ZXJuKHhjdHh0LCBwb3MpOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0ocG9zKTsKLQotICAgIGlmIChDb25zdGFudHMuTlVNQkVSTEVWRUxfQU5ZID09IG1fbGV2ZWwpCi0gICAgewotICAgICAgWFBhdGggZnJvbU1hdGNoUGF0dGVybiA9IG1fZnJvbU1hdGNoUGF0dGVybjsKLQotICAgICAgLy8gRG8gYSBiYWNrd2FyZHMgZG9jdW1lbnQtb3JkZXIgd2FsayAndGlsbCBhIG5vZGUgaXMgZm91bmQgdGhhdCBtYXRjaGVzIAotICAgICAgLy8gdGhlICdmcm9tJyBwYXR0ZXJuLCBvciBhIG5vZGUgaXMgZm91bmQgdGhhdCBtYXRjaGVzIHRoZSAnY291bnQnIHBhdHRlcm4sIAotICAgICAgLy8gb3IgdGhlIHRvcCBvZiB0aGUgdHJlZSBpcyBmb3VuZC4KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSBwb3MpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gR2V0IHRoZSBwcmV2aW91cyBzaWJsaW5nLCBpZiB0aGVyZSBpcyBubyBwcmV2aW91cyBzaWJsaW5nLCAKLSAgICAgICAgLy8gdGhlbiBjb3VudCB0aGUgcGFyZW50LCBidXQgaWYgdGhlcmUgaXMgYSBwcmV2aW91cyBzaWJsaW5nLCAKLSAgICAgICAgLy8gZGl2ZSBkb3duIHRvIHRoZSBsb3dlc3QgcmlnaHQtaGFuZCAobGFzdCkgY2hpbGQgb2YgdGhhdCBzaWJsaW5nLgotICAgICAgICBpbnQgbmV4dCA9IGR0bS5nZXRQcmV2aW91c1NpYmxpbmcocG9zKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgPT0gbmV4dCkKLSAgICAgICAgewotICAgICAgICAgIG5leHQgPSBkdG0uZ2V0UGFyZW50KHBvcyk7Ci0KLSAgICAgICAgICBpZiAoKERUTS5OVUxMICE9IG5leHQpICYmICgoKChudWxsICE9IGZyb21NYXRjaFBhdHRlcm4pICYmIChmcm9tTWF0Y2hQYXR0ZXJuLmdldE1hdGNoU2NvcmUoCi0gICAgICAgICAgICAgICAgICB4Y3R4dCwgbmV4dCkgIT0gWFBhdGguTUFUQ0hfU0NPUkVfTk9ORSkpKSAKLSAgICAgICAgICAgICAgfHwgKGR0bS5nZXROb2RlVHlwZShuZXh0KSA9PSBEVE0uRE9DVU1FTlRfTk9ERSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBvcyA9IERUTS5OVUxMOyAgLy8gcmV0dXJuIG51bGwgZnJvbSBmdW5jdGlvbi4KLQotICAgICAgICAgICAgYnJlYWs7ICAvLyBmcm9tIHdoaWxlIGxvb3AKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBkaXZlIGRvd24gdG8gdGhlIGxvd2VzdCByaWdodCBjaGlsZC4KLSAgICAgICAgICBpbnQgY2hpbGQgPSBuZXh0OwotCi0gICAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IGNoaWxkKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGNoaWxkID0gZHRtLmdldExhc3RDaGlsZChuZXh0KTsKLQotICAgICAgICAgICAgaWYgKERUTS5OVUxMICE9IGNoaWxkKQotICAgICAgICAgICAgICBuZXh0ID0gY2hpbGQ7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcG9zID0gbmV4dDsKLQotICAgICAgICBpZiAoKERUTS5OVUxMICE9IHBvcykKLSAgICAgICAgICAgICAgICAmJiAoKG51bGwgPT0gY291bnRNYXRjaFBhdHRlcm4pCi0gICAgICAgICAgICAgICAgICAgIHx8IChjb3VudE1hdGNoUGF0dGVybi5nZXRNYXRjaFNjb3JlKHhjdHh0LCBwb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICAhPSBYUGF0aC5NQVRDSF9TQ09SRV9OT05FKSkpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlICAvLyBOVU1CRVJMRVZFTF9NVUxUSSBvciBOVU1CRVJMRVZFTF9TSU5HTEUKLSAgICB7Ci0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gcG9zKQotICAgICAgewotICAgICAgICBwb3MgPSBkdG0uZ2V0UHJldmlvdXNTaWJsaW5nKHBvcyk7Ci0KLSAgICAgICAgaWYgKChEVE0uTlVMTCAhPSBwb3MpCi0gICAgICAgICAgICAgICAgJiYgKChudWxsID09IGNvdW50TWF0Y2hQYXR0ZXJuKQotICAgICAgICAgICAgICAgICAgICB8fCAoY291bnRNYXRjaFBhdHRlcm4uZ2V0TWF0Y2hTY29yZSh4Y3R4dCwgcG9zKQotICAgICAgICAgICAgICAgICAgICAgICAgIT0gWFBhdGguTUFUQ0hfU0NPUkVfTk9ORSkpKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gcG9zOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdGFyZ2V0IG5vZGUgdGhhdCB3aWxsIGJlIGNvdW50ZWQuLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUgZm9yIHRoaXMuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSB0YXJnZXQgbm9kZSB0aGF0IHdpbGwgYmUgY291bnRlZAotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgaW50IGdldFRhcmdldE5vZGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgc291cmNlTm9kZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHRhcmdldCA9IERUTS5OVUxMOwotICAgIFhQYXRoIGNvdW50TWF0Y2hQYXR0ZXJuID0gZ2V0Q291bnRNYXRjaFBhdHRlcm4oeGN0eHQsIHNvdXJjZU5vZGUpOwotCi0gICAgaWYgKENvbnN0YW50cy5OVU1CRVJMRVZFTF9BTlkgPT0gbV9sZXZlbCkKLSAgICB7Ci0gICAgICB0YXJnZXQgPSBmaW5kUHJlY2VkaW5nT3JBbmNlc3Rvck9yU2VsZih4Y3R4dCwgbV9mcm9tTWF0Y2hQYXR0ZXJuLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRNYXRjaFBhdHRlcm4sIHNvdXJjZU5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRhcmdldCA9IGZpbmRBbmNlc3Rvcih4Y3R4dCwgbV9mcm9tTWF0Y2hQYXR0ZXJuLCBjb3VudE1hdGNoUGF0dGVybiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VOb2RlLCB0aGlzKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdGFyZ2V0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYW5jZXN0b3JzLCB1cCB0byB0aGUgcm9vdCwgdGhhdCBtYXRjaCB0aGUKLSAgICogcGF0dGVybi4KLSAgICogCi0gICAqIEBwYXJhbSBwYXR0ZXJucyBpZiBub24tbnVsbCwgY291bnQgb25seSBub2RlcwotICAgKiB0aGF0IG1hdGNoIHRoaXMgcGF0dGVybiwgaWYgbnVsbCBjb3VudCBhbGwgYW5jZXN0b3JzLgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUgZm9yIHRoaXMuCi0gICAqIEBwYXJhbSBub2RlIENvdW50IHRoaXMgbm9kZSBhbmQgaXQncyBhbmNlc3RvcnMuCi0gICAqIEBwYXJhbSBzdG9wQXRGaXJzdEZvdW5kIEZsYWcgaW5kaWNhdGluZyB0byBzdG9wIGFmdGVyIHRoZQotICAgKiBmaXJzdCBub2RlIGlzIGZvdW5kIChkaWZmZXJlbmNlIGJldHdlZW4gbGV2ZWwgPSBzaW5nbGUKLSAgICogb3IgbXVsdGlwbGUpCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBhbmNlc3RvcnMgdGhhdCBtYXRjaCB0aGUgcGF0dGVybi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBOb2RlVmVjdG9yIGdldE1hdGNoaW5nQW5jZXN0b3JzKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IG5vZGUsIGJvb2xlYW4gc3RvcEF0Rmlyc3RGb3VuZCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIE5vZGVTZXREVE0gYW5jZXN0b3JzID0gbmV3IE5vZGVTZXREVE0oeGN0eHQuZ2V0RFRNTWFuYWdlcigpKTsKLSAgICBYUGF0aCBjb3VudE1hdGNoUGF0dGVybiA9IGdldENvdW50TWF0Y2hQYXR0ZXJuKHhjdHh0LCBub2RlKTsKLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKG5vZGUpOwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IG5vZGUpCi0gICAgewotICAgICAgaWYgKChudWxsICE9IG1fZnJvbU1hdGNoUGF0dGVybikKLSAgICAgICAgICAgICAgJiYgKG1fZnJvbU1hdGNoUGF0dGVybi5nZXRNYXRjaFNjb3JlKHhjdHh0LCBub2RlKQotICAgICAgICAgICAgICAgICAgIT0gWFBhdGguTUFUQ0hfU0NPUkVfTk9ORSkpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gVGhlIGZvbGxvd2luZyBpZiBzdGF0ZW1lbnQgZ2l2ZXMgbGV2ZWw9InNpbmdsZSIgZGlmZmVyZW50IAotICAgICAgICAvLyBiZWhhdmlvciBmcm9tIGxldmVsPSJtdWx0aXBsZSIsIHdoaWNoIHNlZW1zIGluY29ycmVjdCBhY2NvcmRpbmcgCi0gICAgICAgIC8vIHRvIHRoZSBYU0xUIHNwZWMuICBGb3Igbm93IHdlIGFyZSBsZWF2aW5nIHRoaXMgaW4gdG8gcmVwbGljYXRlIAotICAgICAgICAvLyB0aGUgc2FtZSBiZWhhdmlvciBpbiBYVCwgYnV0LCBmb3IgYWxsIGludGVudHMgYW5kIHB1cnBvc2VzIHdlIAotICAgICAgICAvLyB0aGluayB0aGlzIGlzIGEgYnVnLCBvciB0aGVyZSBpcyBzb21ldGhpbmcgYWJvdXQgbGV2ZWw9InNpbmdsZSIgCi0gICAgICAgIC8vIHRoYXQgd2Ugc3RpbGwgZG9uJ3QgdW5kZXJzdGFuZC4KLSAgICAgICAgaWYgKCFzdG9wQXRGaXJzdEZvdW5kKQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotCi0gICAgICBpZiAobnVsbCA9PSBjb3VudE1hdGNoUGF0dGVybikKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAgICJQcm9ncmFtbWVycyBlcnJvciEgY291bnRNYXRjaFBhdHRlcm4gc2hvdWxkIG5ldmVyIGJlIG51bGwhIik7Ci0KLSAgICAgIGlmIChjb3VudE1hdGNoUGF0dGVybi5nZXRNYXRjaFNjb3JlKHhjdHh0LCBub2RlKQotICAgICAgICAgICAgICAhPSBYUGF0aC5NQVRDSF9TQ09SRV9OT05FKQotICAgICAgewotICAgICAgICBhbmNlc3RvcnMuYWRkRWxlbWVudChub2RlKTsKLQotICAgICAgICBpZiAoc3RvcEF0Rmlyc3RGb3VuZCkKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgbm9kZSA9IGR0bS5nZXRQYXJlbnQobm9kZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGFuY2VzdG9yczsKLSAgfSAgLy8gZW5kIGdldE1hdGNoaW5nQW5jZXN0b3JzIG1ldGhvZAotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxvY2FsZSB3ZSBzaG91bGQgYmUgdXNpbmcuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsb2NhbGUgdG8gdXNlLiBNYXkgYmUgc3BlY2lmaWVkIGJ5ICJsYW5nIiBhdHRyaWJ1dGUsCi0gICAqIGJ1dCBpZiBub3QsIHVzZSBkZWZhdWx0IGxvY2FsZSBvbiB0aGUgc3lzdGVtLiAKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgTG9jYWxlIGdldExvY2FsZShUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsIGludCBjb250ZXh0Tm9kZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgTG9jYWxlIGxvY2FsZSA9IG51bGw7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xhbmdfYXZ0KQotICAgIHsKLSAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotICAgICAgU3RyaW5nIGxhbmdWYWx1ZSA9IG1fbGFuZ19hdnQuZXZhbHVhdGUoeGN0eHQsIGNvbnRleHROb2RlLCB0aGlzKTsKLQotICAgICAgaWYgKG51bGwgIT0gbGFuZ1ZhbHVlKQotICAgICAgewotCi0gICAgICAgIC8vIE5vdCByZWFsbHkgc3VyZSB3aGF0IHRvIGRvIGFib3V0IHRoZSBjb3VudHJ5IGNvZGUsIHNvIEkgdXNlIHRoZQotICAgICAgICAvLyBkZWZhdWx0IGZyb20gdGhlIHN5c3RlbS4KLSAgICAgICAgLy8gVE9ETzogZml4IHhtbDpsYW5nIGhhbmRsaW5nLgotICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGxhbmdWYWx1ZS50b1VwcGVyQ2FzZSgpLCAiIik7Ci0KLSAgICAgICAgLy9Mb2NhbGUuZ2V0RGVmYXVsdCgpLmdldERpc3BsYXlDb3VudHJ5KCkpOwotICAgICAgICBpZiAobnVsbCA9PSBsb2NhbGUpCi0gICAgICAgIHsKLSAgICAgICAgICB0cmFuc2Zvcm1lci5nZXRNc2dNZ3IoKS53YXJuKHRoaXMsIG51bGwsIHhjdHh0LmdldERUTShjb250ZXh0Tm9kZSkuZ2V0Tm9kZShjb250ZXh0Tm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuV0dfTE9DQUxFX05PVF9GT1VORCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbGFuZ1ZhbHVlIH0pOyAgLy8iV2FybmluZzogQ291bGQgbm90IGZpbmQgbG9jYWxlIGZvciB4bWw6bGFuZz0iK2xhbmdWYWx1ZSk7Ci0KLSAgICAgICAgICBsb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBsb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOwotICAgIH0KLQotICAgIHJldHVybiBsb2NhbGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgZm9ybWF0dGVyIHRvIGJlIHVzZWQgdGhlIGZvcm1hdCB0aGUgbnVtYmVycwotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRoYXQgIi4iIGV4cHJlc3Nlcy4KLSAgICoKLSAgICogKCRvYmplY3ROYW1lJCkgQHJldHVybiBUaGUgbnVtYmVyIGZvcm1hdHRlciB0byBiZSB1c2VkCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgRGVjaW1hbEZvcm1hdCBnZXROdW1iZXJGb3JtYXR0ZXIoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLCBpbnQgY29udGV4dE5vZGUpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgLy8gUGF0Y2ggZnJvbSBTdGV2ZW4gU2Vyb2NraQotICAgIC8vIE1heWJlIHdlIHJlYWxseSB3YW50IHRvIGRvIHRoZSBjbG9uZSBpbiBnZXRMb2NhbGUoKSBhbmQgcmV0dXJuICAKLSAgICAvLyBhIGNsb25lIG9mIHRoZSBkZWZhdWx0IExvY2FsZT8/Ci0gICAgTG9jYWxlIGxvY2FsZSA9IChMb2NhbGUpZ2V0TG9jYWxlKHRyYW5zZm9ybWVyLCBjb250ZXh0Tm9kZSkuY2xvbmUoKTsKLQotICAgIC8vIEhlbHBlciB0byBmb3JtYXQgbG9jYWwgc3BlY2lmaWMgbnVtYmVycyB0byBzdHJpbmdzLgotICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0dGVyOwotCi0gICAgLy9zeW5jaHJvbml6ZWQgKGxvY2FsZSkKLSAgICAvL3sKLSAgICAgIGZvcm1hdHRlciA9IChEZWNpbWFsRm9ybWF0KSBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UobG9jYWxlKTsKLSAgICAvL30KLQotICAgIFN0cmluZyBkaWdpdEdyb3VwU2VwVmFsdWUgPQotICAgICAgKG51bGwgIT0gbV9ncm91cGluZ1NlcGFyYXRvcl9hdnQpCi0gICAgICA/IG1fZ3JvdXBpbmdTZXBhcmF0b3JfYXZ0LmV2YWx1YXRlKAotICAgICAgdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCksIGNvbnRleHROb2RlLCB0aGlzKSA6IG51bGw7Ci0gICAgU3RyaW5nIG5EaWdpdHNQZXJHcm91cFZhbHVlID0KLSAgICAgIChudWxsICE9IG1fZ3JvdXBpbmdTaXplX2F2dCkKLSAgICAgID8gbV9ncm91cGluZ1NpemVfYXZ0LmV2YWx1YXRlKAotICAgICAgdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCksIGNvbnRleHROb2RlLCB0aGlzKSA6IG51bGw7Ci0KLSAgICAvLyBUT0RPOiBIYW5kbGUgZGlnaXQtZ3JvdXAgYXR0cmlidXRlcwotICAgIGlmICgobnVsbCAhPSBkaWdpdEdyb3VwU2VwVmFsdWUpICYmIChudWxsICE9IG5EaWdpdHNQZXJHcm91cFZhbHVlKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZm9ybWF0dGVyLnNldEdyb3VwaW5nU2l6ZSgKLSAgICAgICAgICBJbnRlZ2VyLnZhbHVlT2YobkRpZ2l0c1Blckdyb3VwVmFsdWUpLmludFZhbHVlKCkpOwotICAgICAgICBmb3JtYXR0ZXIuZ2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoKS5zZXRHcm91cGluZ1NlcGFyYXRvcigKLSAgICAgICAgICBkaWdpdEdyb3VwU2VwVmFsdWUuY2hhckF0KDApKTsKLSAgICAgICAgZm9ybWF0dGVyLnNldEdyb3VwaW5nVXNlZCh0cnVlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpCi0gICAgICB7Ci0gICAgICAgIGZvcm1hdHRlci5zZXRHcm91cGluZ1VzZWQoZmFsc2UpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmb3JtYXR0ZXI7Ci0gIH0KLQotICAvKioKLSAgICogRm9ybWF0IGEgdmVjdG9yIG9mIG51bWJlcnMgaW50byBhIGZvcm1hdHRlZCBzdHJpbmcuCi0gICAqIAotICAgKiBAcGFyYW0geHNsTnVtYmVyRWxlbWVudCBFbGVtZW50IHRoYXQgdGFrZXMgJWNvbnZlcnNpb24tYXR0czsgYXR0cmlidXRlcy4KLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBsaXN0IEFycmF5IG9mIG9uZSBvciBtb3JlIGludGVnZXIgbnVtYmVycy4KLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRoYXQgIi4iIGV4cHJlc3Nlcy4KLSAgICogQHJldHVybiBTdHJpbmcgdGhhdCByZXByZXNlbnRzIGxpc3QgYWNjb3JkaW5nIHRvCi0gICAqICVjb252ZXJzaW9uLWF0dHM7IGF0dHJpYnV0ZXMuCi0gICAqIFRPRE86IE9wdGltaXplIGZvcm1hdE51bWJlckxpc3Qgc28gdGhhdCBpdCBjYWNoZXMgdGhlIGxhc3QgY291bnQgYW5kCi0gICAqIHJldXNlcyB0aGF0IGluZm8gZm9yIHRoZSBuZXh0IGNvdW50LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBTdHJpbmcgZm9ybWF0TnVtYmVyTGlzdCgKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsIGludFtdIGxpc3QsIGludCBjb250ZXh0Tm9kZSkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgbnVtU3RyOwotICAgIEZhc3RTdHJpbmdCdWZmZXIgZm9ybWF0dGVkTnVtYmVyID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGludCBuTnVtYmVycyA9IGxpc3QubGVuZ3RoLCBudW1iZXJXaWR0aCA9IDE7Ci0gICAgICBjaGFyIG51bWJlclR5cGUgPSAnMSc7Ci0gICAgICBTdHJpbmcgZm9ybWF0VG9rZW4sIGxhc3RTZXBTdHJpbmcgPSBudWxsLCBmb3JtYXRUb2tlblN0cmluZyA9IG51bGw7Ci0KLSAgICAgIC8vIElmIGEgc2VwZXJhdG9yIGhhc24ndCBiZWVuIHNwZWNpZmllZCwgdGhlbiB1c2UgIi4iICAKLSAgICAgIC8vIGFzIGEgZGVmYXVsdCBzZXBhcmF0b3IuIAotICAgICAgLy8gRm9yIGluc3RhbmNlOiBbMl1bMV1bNV0gd2l0aCBhIGZvcm1hdCB2YWx1ZSBvZiAiMSAiCi0gICAgICAvLyBzaG91bGQgZm9ybWF0IHRvICIyLjEuNSAiIChJIHRoaW5rKS4KLSAgICAgIC8vIE90aGVyd2lzZSwgdXNlIHRoZSBzZXBlcmF0b3Igc3BlY2lmaWVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLgotICAgICAgLy8gRm9yIGluc3RhbmNlOiBbMl1bMV1bNV0gd2l0aCBhIGZvcm1hdCB2YWx1ZSBvZiAiMDEtMDAxLiAiCi0gICAgICAvLyBzaG91bGQgZm9ybWF0IHRvICIwMi0wMDEtMDA1ICIuCi0gICAgICBTdHJpbmcgbGFzdFNlcCA9ICIuIjsKLSAgICAgIGJvb2xlYW4gaXNGaXJzdFRva2VuID0gdHJ1ZTsgIC8vIHRydWUgaWYgZmlyc3QgdG9rZW4gIAotICAgICAgU3RyaW5nIGZvcm1hdFZhbHVlID0KLSAgICAgICAgKG51bGwgIT0gbV9mb3JtYXRfYXZ0KQotICAgICAgICA/IG1fZm9ybWF0X2F2dC5ldmFsdWF0ZSgKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCksIGNvbnRleHROb2RlLCB0aGlzKSA6IG51bGw7Ci0KLSAgICAgIGlmIChudWxsID09IGZvcm1hdFZhbHVlKQotICAgICAgICBmb3JtYXRWYWx1ZSA9ICIxIjsKLQotICAgICAgTnVtYmVyRm9ybWF0U3RyaW5nVG9rZW5pemVyIGZvcm1hdFRva2VuaXplciA9Ci0gICAgICAgIG5ldyBOdW1iZXJGb3JtYXRTdHJpbmdUb2tlbml6ZXIoZm9ybWF0VmFsdWUpOwotCi0gICAgICAvLyBpbnQgc2VwQ291bnQgPSAwOyAgICAgICAgICAgICAgICAgIC8vIGtlZXAgdHJhY2sgb2Ygc2VwZXJhdG9ycwotICAgICAgLy8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgbnVtYmVycyBpbiB0aGUgbGlzdC4KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbk51bWJlcnM7IGkrKykKLSAgICAgIHsKLQotICAgICAgICAvLyBMb29wIHRvIHRoZSBuZXh0IGRpZ2l0LCBsZXR0ZXIsIG9yIHNlcGFyYXRvci4KLSAgICAgICAgaWYgKGZvcm1hdFRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBmb3JtYXRUb2tlbiA9IGZvcm1hdFRva2VuaXplci5uZXh0VG9rZW4oKTsKLQotICAgICAgICAgIC8vIElmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhpcyB0b2tlbiBpcyBhIGNoYXJhY3RlciBvciBkaWdpdCwgdGhlbiAKLSAgICAgICAgICAvLyBpdCBpcyBhIG51bWJlciBmb3JtYXQgZGlyZWN0aXZlLgotICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KAotICAgICAgICAgICAgICAgICAgZm9ybWF0VG9rZW4uY2hhckF0KGZvcm1hdFRva2VuLmxlbmd0aCgpIC0gMSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG51bWJlcldpZHRoID0gZm9ybWF0VG9rZW4ubGVuZ3RoKCk7Ci0gICAgICAgICAgICBudW1iZXJUeXBlID0gZm9ybWF0VG9rZW4uY2hhckF0KG51bWJlcldpZHRoIC0gMSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBudW1iZXIgZm9ybWF0IGRpcmVjdGl2ZSBhaGVhZCwgCi0gICAgICAgICAgLy8gdGhlbiBhcHBlbmQgdGhlIGZvcm1hdFRva2VuLgotICAgICAgICAgIGVsc2UgaWYgKGZvcm1hdFRva2VuaXplci5pc0xldHRlck9yRGlnaXRBaGVhZCgpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGZvcm1hdFRva2VuU3RyaW5nID0gZm9ybWF0VG9rZW47Ci0KLSAgICAgICAgICAgIC8vIEFwcGVuZCB0aGUgZm9ybWF0VG9rZW4gc3RyaW5nLi4uCi0gICAgICAgICAgICAvLyBGb3IgaW5zdGFuY2UgWzJdWzFdWzVdIHdpdGggYSBmb3JtYXQgdmFsdWUgb2YgIjEtLTEuICIKLSAgICAgICAgICAgIC8vIHNob3VsZCBmb3JtYXQgdG8gIjItLTEtLTUuICIgKEkgZ3Vlc3MpLgotICAgICAgICAgICAgd2hpbGUgKGZvcm1hdFRva2VuaXplci5uZXh0SXNTZXAoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZm9ybWF0VG9rZW4gPSBmb3JtYXRUb2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICAgICAgICAgIGZvcm1hdFRva2VuU3RyaW5nICs9IGZvcm1hdFRva2VuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBSZWNvcmQgdGhpcyBzZXBhcmF0b3IsIHNvIGl0IGNhbiBiZSB1c2VkIGFzIHRoZSAKLSAgICAgICAgICAgIC8vIG5leHQgc2VwYXJhdG9yLCBpZiB0aGUgbmV4dCBpcyB0aGUgbGFzdC4KLSAgICAgICAgICAgIC8vIEZvciBpbnN0YW5jZTogWzJdWzFdWzVdIHdpdGggYSBmb3JtYXQgdmFsdWUgb2YgIjEtMSAiCi0gICAgICAgICAgICAvLyBzaG91bGQgZm9ybWF0IHRvICIyLTEtNSAiLgotICAgICAgICAgICAgaWYgKCFpc0ZpcnN0VG9rZW4pCi0gICAgICAgICAgICAgIGxhc3RTZXAgPSBmb3JtYXRUb2tlblN0cmluZzsKLQotICAgICAgICAgICAgLy8gU2luY2Ugd2Uga25vdyB0aGUgbmV4dCBpcyBhIG51bWJlciBvciBkaWdpdCwgd2UgZ2V0IGl0IG5vdy4KLSAgICAgICAgICAgIGZvcm1hdFRva2VuID0gZm9ybWF0VG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICAgICAgbnVtYmVyV2lkdGggPSBmb3JtYXRUb2tlbi5sZW5ndGgoKTsKLSAgICAgICAgICAgIG51bWJlclR5cGUgPSBmb3JtYXRUb2tlbi5jaGFyQXQobnVtYmVyV2lkdGggLSAxKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZSAgLy8gb25seSBzZXBhcmF0b3JzIGxlZnQKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIFNldCB1cCB0aGUgc3RyaW5nIGZvciB0aGUgdHJhaWxpbmcgY2hhcmFjdGVycyBhZnRlciAKLSAgICAgICAgICAgIC8vIHRoZSBsYXN0IG51bWJlciBpcyBmb3JtYXR0ZWQgKGkuZS4gYWZ0ZXIgdGhlIGxvb3ApLgotICAgICAgICAgICAgbGFzdFNlcFN0cmluZyA9IGZvcm1hdFRva2VuOwotCi0gICAgICAgICAgICAvLyBBbmQgYXBwZW5kIGFueSByZW1haW5pbmcgY2hhcmFjdGVycyB0byB0aGUgbGFzdFNlcFN0cmluZy4KLSAgICAgICAgICAgIHdoaWxlIChmb3JtYXRUb2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBmb3JtYXRUb2tlbiA9IGZvcm1hdFRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgICAgICAgbGFzdFNlcFN0cmluZyArPSBmb3JtYXRUb2tlbjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9ICAvLyBlbHNlCi0gICAgICAgIH0gIC8vIGVuZCBpZihmb3JtYXRUb2tlbml6ZXIuaGFzTW9yZVRva2VucygpKQotCi0gICAgICAgIC8vIGlmIHRoaXMgaXMgdGhlIGZpcnN0IHRva2VuIGFuZCB0aGVyZSB3YXMgYSBwcmVmaXgKLSAgICAgICAgLy8gYXBwZW5kIHRoZSBwcmVmaXggZWxzZSwgYXBwZW5kIHRoZSBzZXBhcmF0b3IKLSAgICAgICAgLy8gRm9yIGluc3RhbmNlLCBbMl1bMV1bNV0gd2l0aCBhIGZvcm1hdCB2YWx1ZSBvZiAiKDEtMS4pICIKLSAgICAgICAgLy8gc2hvdWxkIGZvcm1hdCB0byAiKDItMS01LikgIiAoSSBndWVzcykuCi0gICAgICAgIGlmIChudWxsICE9IGZvcm1hdFRva2VuU3RyaW5nICYmIGlzRmlyc3RUb2tlbikKLSAgICAgICAgewotICAgICAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQoZm9ybWF0VG9rZW5TdHJpbmcpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG51bGwgIT0gbGFzdFNlcCAmJiFpc0ZpcnN0VG9rZW4pCi0gICAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZChsYXN0U2VwKTsKLQotICAgICAgICBnZXRGb3JtYXR0ZWROdW1iZXIodHJhbnNmb3JtZXIsIGNvbnRleHROb2RlLCBudW1iZXJUeXBlLCBudW1iZXJXaWR0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RbaV0sIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgICAgaXNGaXJzdFRva2VuID0gZmFsc2U7ICAvLyBBZnRlciB0aGUgZmlyc3QgcGFzcywgdGhpcyBzaG91bGQgYmUgZmFsc2UKLSAgICAgIH0gIC8vIGVuZCBmb3IgbG9vcAotCi0gICAgICAvLyBDaGVjayB0byBzZWUgaWYgd2UgZmluaXNoZWQgdXAgdGhlIGZvcm1hdCBzdHJpbmcuLi4KLSAgICAgIC8vIFNraXAgcGFzdCBhbGwgcmVtYWluaW5nIGxldHRlcnMgb3IgZGlnaXRzCi0gICAgICB3aGlsZSAoZm9ybWF0VG9rZW5pemVyLmlzTGV0dGVyT3JEaWdpdEFoZWFkKCkpCi0gICAgICB7Ci0gICAgICAgIGZvcm1hdFRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGxhc3RTZXBTdHJpbmcgIT0gbnVsbCkKLSAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZChsYXN0U2VwU3RyaW5nKTsKLQotICAgICAgd2hpbGUgKGZvcm1hdFRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpCi0gICAgICB7Ci0gICAgICAgIGZvcm1hdFRva2VuID0gZm9ybWF0VG9rZW5pemVyLm5leHRUb2tlbigpOwotCi0gICAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQoZm9ybWF0VG9rZW4pOwotICAgICAgfQotCi0gICAgICBudW1TdHIgPSBmb3JtYXR0ZWROdW1iZXIudG9TdHJpbmcoKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIFN0cmluZ0J1ZmZlclBvb2wuZnJlZShmb3JtYXR0ZWROdW1iZXIpOwotICAgIH0KLQotICAgIHJldHVybiBudW1TdHI7Ci0gIH0gIC8vIGVuZCBmb3JtYXROdW1iZXJMaXN0IG1ldGhvZAotCi0gIC8qCi0gICogR2V0IEZvcm1hdHRlZCBudW1iZXIKLSAgKi8KLQotICAvKioKLSAgICogRm9ybWF0IHRoZSBnaXZlbiBudW1iZXIgYW5kIHN0b3JlIGl0IGluIHRoZSBnaXZlbiBidWZmZXIgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAcGFyYW0gbnVtYmVyVHlwZSBUeXBlIHRvIGZvcm1hdCB0bwotICAgKiBAcGFyYW0gbnVtYmVyV2lkdGggTWF4aW11bSBsZW5ndGggb2YgZm9ybWF0dGVkIG51bWJlcgotICAgKiBAcGFyYW0gbGlzdEVsZW1lbnQgTnVtYmVyIHRvIGZvcm1hdAotICAgKiBAcGFyYW0gZm9ybWF0dGVkTnVtYmVyIEJ1ZmZlciB0byBzdG9yZSBmb3JtYXR0ZWQgbnVtYmVyCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGdldEZvcm1hdHRlZE51bWJlcigKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsIGludCBjb250ZXh0Tm9kZSwgCi0gICAgICAgICAgY2hhciBudW1iZXJUeXBlLCBpbnQgbnVtYmVyV2lkdGgsIGludCBsaXN0RWxlbWVudCwgCi0gICAgICAgICAgRmFzdFN0cmluZ0J1ZmZlciBmb3JtYXR0ZWROdW1iZXIpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBEZWNpbWFsRm9ybWF0IGZvcm1hdHRlciA9IGdldE51bWJlckZvcm1hdHRlcih0cmFuc2Zvcm1lciwgY29udGV4dE5vZGUpOwotICAgIFN0cmluZyBwYWRTdHJpbmcgPSBmb3JtYXR0ZXIuZm9ybWF0KDApOwotICAgIFN0cmluZyBsZXR0ZXJWYWwgPQotICAgICAgKG1fbGV0dGVydmFsdWVfYXZ0ICE9IG51bGwpCi0gICAgICA/IG1fbGV0dGVydmFsdWVfYXZ0LmV2YWx1YXRlKAotICAgICAgdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCksIGNvbnRleHROb2RlLCB0aGlzKSA6IG51bGw7Ci0KLSAgICBzd2l0Y2ggKG51bWJlclR5cGUpCi0gICAgewotICAgIGNhc2UgJ0EnIDoKLSAgICAgIGlmIChtX2FscGhhQ291bnRUYWJsZSA9PSBudWxsKQotICAgICAgewotICAgICAgICBYUmVzb3VyY2VCdW5kbGUgdGhpc0J1bmRsZTsKLQotICAgICAgICB0aGlzQnVuZGxlID0KLSAgICAgICAgICAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5MQU5HX0JVTkRMRV9OQU1FLCBnZXRMb2NhbGUodHJhbnNmb3JtZXIsIGNvbnRleHROb2RlKSk7Ci0KLSAgICAgICAgY2hhcltdIGFscGhhYmV0OwotCi0gICAgICAgIGFscGhhYmV0ID0gKGNoYXJbXSkgdGhpc0J1bmRsZS5nZXRPYmplY3Qob3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5MQU5HX0FMUEhBQkVUKTsKLSAgICAgICAgbV9hbHBoYUNvdW50VGFibGUgPSBhbHBoYWJldDsKLSAgICAgIH0KLQotICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsIG1fYWxwaGFDb3VudFRhYmxlLCBmb3JtYXR0ZWROdW1iZXIpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSAnYScgOgotICAgICAgaWYgKG1fYWxwaGFDb3VudFRhYmxlID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIFhSZXNvdXJjZUJ1bmRsZSB0aGlzQnVuZGxlOwotCi0gICAgICAgIHRoaXNCdW5kbGUgPQotICAgICAgICAgIChYUmVzb3VyY2VCdW5kbGUpIFhSZXNvdXJjZUJ1bmRsZS5sb2FkUmVzb3VyY2VCdW5kbGUoCi0gICAgICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIGdldExvY2FsZSh0cmFuc2Zvcm1lciwgY29udGV4dE5vZGUpKTsKLQotICAgICAgICBjaGFyW10gYWxwaGFiZXQ7Ci0KLSAgICAgICAgYWxwaGFiZXQgPSAoY2hhcltdKSB0aGlzQnVuZGxlLmdldE9iamVjdChvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQUxQSEFCRVQpOwotICAgICAgICBtX2FscGhhQ291bnRUYWJsZSA9IGFscGhhYmV0OwotICAgICAgfQotCi0gICAgICBGYXN0U3RyaW5nQnVmZmVyIHN0cmluZ0J1ZiA9IFN0cmluZ0J1ZmZlclBvb2wuZ2V0KCk7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBpbnQyYWxwaGFDb3VudChsaXN0RWxlbWVudCwgbV9hbHBoYUNvdW50VGFibGUsIHN0cmluZ0J1Zik7Ci0gICAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQoCi0gICAgICAgICAgc3RyaW5nQnVmLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoCi0gICAgICAgICAgICBnZXRMb2NhbGUodHJhbnNmb3JtZXIsIGNvbnRleHROb2RlKSkpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoc3RyaW5nQnVmKTsKLSAgICAgIH0KLSAgICAgIGJyZWFrOwotICAgIGNhc2UgJ0knIDoKLSAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQobG9uZzJyb21hbihsaXN0RWxlbWVudCwgdHJ1ZSkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSAnaScgOgotICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZCgKLSAgICAgICAgbG9uZzJyb21hbihsaXN0RWxlbWVudCwgdHJ1ZSkudG9Mb3dlckNhc2UoCi0gICAgICAgICAgZ2V0TG9jYWxlKHRyYW5zZm9ybWVyLCBjb250ZXh0Tm9kZSkpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgMHgzMDQyIDoKLSAgICB7Ci0gICAgICBYUmVzb3VyY2VCdW5kbGUgdGhpc0J1bmRsZTsKLQotICAgICAgdGhpc0J1bmRsZSA9IChYUmVzb3VyY2VCdW5kbGUpIFhSZXNvdXJjZUJ1bmRsZS5sb2FkUmVzb3VyY2VCdW5kbGUoCi0gICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19CVU5ETEVfTkFNRSwgbmV3IExvY2FsZSgiamEiLCAiSlAiLCAiSEEiKSk7Ci0KLSAgICAgIGlmIChsZXR0ZXJWYWwgIT0gbnVsbAotICAgICAgICAgICAgICAmJiBsZXR0ZXJWYWwuZXF1YWxzKENvbnN0YW50cy5BVFRSVkFMX1RSQURJVElPTkFMKSkKLSAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZCh0cmFkQWxwaGFDb3VudChsaXN0RWxlbWVudCwgdGhpc0J1bmRsZSkpOwotICAgICAgZWxzZSAgLy9pZiAobV9sZXR0ZXJ2YWx1ZV9hdnQgIT0gbnVsbCAmJiBtX2xldHRlcnZhbHVlX2F2dC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfQUxQSEFCRVRJQykpCi0gICAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQoCi0gICAgICAgICAgaW50MnNpbmdsZWFscGhhQ291bnQoCi0gICAgICAgICAgICBsaXN0RWxlbWVudCwKLSAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCkpKTsKLQotICAgICAgYnJlYWs7Ci0gICAgfQotICAgIGNhc2UgMHgzMDQ0IDoKLSAgICB7Ci0gICAgICBYUmVzb3VyY2VCdW5kbGUgdGhpc0J1bmRsZTsKLQotICAgICAgdGhpc0J1bmRsZSA9IChYUmVzb3VyY2VCdW5kbGUpIFhSZXNvdXJjZUJ1bmRsZS5sb2FkUmVzb3VyY2VCdW5kbGUoCi0gICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19CVU5ETEVfTkFNRSwgbmV3IExvY2FsZSgiamEiLCAiSlAiLCAiSEkiKSk7Ci0KLSAgICAgIGlmICgobGV0dGVyVmFsICE9IG51bGwpCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZCgKLSAgICAgICAgICBpbnQyc2luZ2xlYWxwaGFDb3VudCgKLSAgICAgICAgICAgIGxpc3RFbGVtZW50LAotICAgICAgICAgICAgKGNoYXJbXSkgdGhpc0J1bmRsZS5nZXRPYmplY3Qob3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5MQU5HX0FMUEhBQkVUKSkpOwotCi0gICAgICBicmVhazsKLSAgICB9Ci0gICAgY2FzZSAweDMwQTIgOgotICAgIHsKLSAgICAgIFhSZXNvdXJjZUJ1bmRsZSB0aGlzQnVuZGxlOwotCi0gICAgICB0aGlzQnVuZGxlID0gKFhSZXNvdXJjZUJ1bmRsZSkgWFJlc291cmNlQnVuZGxlLmxvYWRSZXNvdXJjZUJ1bmRsZSgKLSAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5MQU5HX0JVTkRMRV9OQU1FLCBuZXcgTG9jYWxlKCJqYSIsICJKUCIsICJBIikpOwotCi0gICAgICBpZiAobGV0dGVyVmFsICE9IG51bGwKLSAgICAgICAgICAgICAgJiYgbGV0dGVyVmFsLmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9UUkFESVRJT05BTCkpCi0gICAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQodHJhZEFscGhhQ291bnQobGlzdEVsZW1lbnQsIHRoaXNCdW5kbGUpKTsKLSAgICAgIGVsc2UgIC8vaWYgKG1fbGV0dGVydmFsdWVfYXZ0ICE9IG51bGwgJiYgbV9sZXR0ZXJ2YWx1ZV9hdnQuZXF1YWxzKENvbnN0YW50cy5BVFRSVkFMX0FMUEhBQkVUSUMpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKAotICAgICAgICAgIGludDJzaW5nbGVhbHBoYUNvdW50KAotICAgICAgICAgICAgbGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAoY2hhcltdKSB0aGlzQnVuZGxlLmdldE9iamVjdChvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQUxQSEFCRVQpKSk7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBjYXNlIDB4MzBBNCA6Ci0gICAgewotICAgICAgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgICAgIHRoaXNCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIG5ldyBMb2NhbGUoImphIiwgIkpQIiwgIkkiKSk7Ci0KLSAgICAgIGlmIChsZXR0ZXJWYWwgIT0gbnVsbAotICAgICAgICAgICAgICAmJiBsZXR0ZXJWYWwuZXF1YWxzKENvbnN0YW50cy5BVFRSVkFMX1RSQURJVElPTkFMKSkKLSAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZCh0cmFkQWxwaGFDb3VudChsaXN0RWxlbWVudCwgdGhpc0J1bmRsZSkpOwotICAgICAgZWxzZSAgLy9pZiAobV9sZXR0ZXJ2YWx1ZV9hdnQgIT0gbnVsbCAmJiBtX2xldHRlcnZhbHVlX2F2dC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfQUxQSEFCRVRJQykpCi0gICAgICAgIGZvcm1hdHRlZE51bWJlci5hcHBlbmQoCi0gICAgICAgICAgaW50MnNpbmdsZWFscGhhQ291bnQoCi0gICAgICAgICAgICBsaXN0RWxlbWVudCwKLSAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCkpKTsKLQotICAgICAgYnJlYWs7Ci0gICAgfQotICAgIGNhc2UgMHg0RTAwIDoKLSAgICB7Ci0gICAgICBYUmVzb3VyY2VCdW5kbGUgdGhpc0J1bmRsZTsKLQotICAgICAgdGhpc0J1bmRsZSA9IChYUmVzb3VyY2VCdW5kbGUpIFhSZXNvdXJjZUJ1bmRsZS5sb2FkUmVzb3VyY2VCdW5kbGUoCi0gICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19CVU5ETEVfTkFNRSwgbmV3IExvY2FsZSgiemgiLCAiQ04iKSk7Ci0KLSAgICAgIGlmIChsZXR0ZXJWYWwgIT0gbnVsbAotICAgICAgICAgICAgICAmJiBsZXR0ZXJWYWwuZXF1YWxzKENvbnN0YW50cy5BVFRSVkFMX1RSQURJVElPTkFMKSkKLSAgICAgIHsKLSAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZCh0cmFkQWxwaGFDb3VudChsaXN0RWxlbWVudCwgdGhpc0J1bmRsZSkpOwotICAgICAgfQotICAgICAgZWxzZSAgLy9pZiAobV9sZXR0ZXJ2YWx1ZV9hdnQgIT0gbnVsbCAmJiBtX2xldHRlcnZhbHVlX2F2dC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfQUxQSEFCRVRJQykpCi0gICAgICAgIGludDJhbHBoYUNvdW50KGxpc3RFbGVtZW50LAotICAgICAgICAgICAgICAgICAgICAgICAoY2hhcltdKSB0aGlzQnVuZGxlLmdldE9iamVjdChvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQUxQSEFCRVQpLAotICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZWROdW1iZXIpOwotCi0gICAgICBicmVhazsKLSAgICB9Ci0gICAgY2FzZSAweDU4RjkgOgotICAgIHsKLSAgICAgIFhSZXNvdXJjZUJ1bmRsZSB0aGlzQnVuZGxlOwotCi0gICAgICB0aGlzQnVuZGxlID0gKFhSZXNvdXJjZUJ1bmRsZSkgWFJlc291cmNlQnVuZGxlLmxvYWRSZXNvdXJjZUJ1bmRsZSgKLSAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5MQU5HX0JVTkRMRV9OQU1FLCBuZXcgTG9jYWxlKCJ6aCIsICJUVyIpKTsKLQotICAgICAgaWYgKGxldHRlclZhbCAhPSBudWxsCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCksCi0gICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBjYXNlIDB4MEU1MSA6Ci0gICAgewotICAgICAgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgICAgIHRoaXNCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIG5ldyBMb2NhbGUoInRoIiwgIiIpKTsKLQotICAgICAgaWYgKGxldHRlclZhbCAhPSBudWxsCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCksCi0gICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBjYXNlIDB4MDVEMCA6Ci0gICAgewotICAgICAgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgICAgIHRoaXNCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIG5ldyBMb2NhbGUoImhlIiwgIiIpKTsKLQotICAgICAgaWYgKGxldHRlclZhbCAhPSBudWxsCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCksCi0gICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBjYXNlIDB4MTBEMCA6Ci0gICAgewotICAgICAgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgICAgIHRoaXNCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIG5ldyBMb2NhbGUoImthIiwgIiIpKTsKLQotICAgICAgaWYgKGxldHRlclZhbCAhPSBudWxsCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCksCi0gICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBjYXNlIDB4MDNCMSA6Ci0gICAgewotICAgICAgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgICAgIHRoaXNCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIG5ldyBMb2NhbGUoImVsIiwgIiIpKTsKLQotICAgICAgaWYgKGxldHRlclZhbCAhPSBudWxsCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCksCi0gICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBjYXNlIDB4MDQzMCA6Ci0gICAgewotICAgICAgWFJlc291cmNlQnVuZGxlIHRoaXNCdW5kbGU7Ci0KLSAgICAgIHRoaXNCdW5kbGUgPSAoWFJlc291cmNlQnVuZGxlKSBYUmVzb3VyY2VCdW5kbGUubG9hZFJlc291cmNlQnVuZGxlKAotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfQlVORExFX05BTUUsIG5ldyBMb2NhbGUoImN5IiwgIiIpKTsKLQotICAgICAgaWYgKGxldHRlclZhbCAhPSBudWxsCi0gICAgICAgICAgICAgICYmIGxldHRlclZhbC5lcXVhbHMoQ29uc3RhbnRzLkFUVFJWQUxfVFJBRElUSU9OQUwpKQotICAgICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKHRyYWRBbHBoYUNvdW50KGxpc3RFbGVtZW50LCB0aGlzQnVuZGxlKSk7Ci0gICAgICBlbHNlICAvL2lmIChtX2xldHRlcnZhbHVlX2F2dCAhPSBudWxsICYmIG1fbGV0dGVydmFsdWVfYXZ0LmVxdWFscyhDb25zdGFudHMuQVRUUlZBTF9BTFBIQUJFVElDKSkKLSAgICAgICAgaW50MmFscGhhQ291bnQobGlzdEVsZW1lbnQsCi0gICAgICAgICAgICAgICAgICAgICAgIChjaGFyW10pIHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19BTFBIQUJFVCksCi0gICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE51bWJlcik7Ci0KLSAgICAgIGJyZWFrOwotICAgIH0KLSAgICBkZWZhdWx0IDogIC8vICIxIgotICAgICAgU3RyaW5nIG51bVN0cmluZyA9IGZvcm1hdHRlci5mb3JtYXQobGlzdEVsZW1lbnQpOwotICAgICAgaW50IG5QYWRkaW5nID0gbnVtYmVyV2lkdGggLSBudW1TdHJpbmcubGVuZ3RoKCk7Ci0KLSAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgblBhZGRpbmc7IGsrKykKLSAgICAgIHsKLSAgICAgICAgZm9ybWF0dGVkTnVtYmVyLmFwcGVuZChwYWRTdHJpbmcpOwotICAgICAgfQotCi0gICAgICBmb3JtYXR0ZWROdW1iZXIuYXBwZW5kKG51bVN0cmluZyk7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGEgc3RyaW5nIHZhbHVlIGZvciB6ZXJvLCB3aGljaCBpcyBub3QgcmVhbGx5IGRlZmluZWQgYnkgdGhlIDEuMCBzcGVjLCAKLSAgICogdGhvdWdodCBJIHRoaW5rIGl0IG1pZ2h0IGJlIGNsZWFyZWQgdXAgYnkgdGhlIGVycmV0YS4KLSAgICovCi0gICBTdHJpbmcgZ2V0WmVyb1N0cmluZygpCi0gICB7Ci0gICAgIHJldHVybiAiIiswOwotICAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0IGEgbG9uZyBpbnRlZ2VyIGludG8gYWxwaGFiZXRpYyBjb3VudGluZywgaW4gb3RoZXIgd29yZHMKLSAgICogY291bnQgdXNpbmcgdGhlIHNlcXVlbmNlIEEgQiBDIC4uLiBaLgotICAgKiAKLSAgICogQHBhcmFtIHZhbCBWYWx1ZSB0byBjb252ZXJ0IC0tIG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm8uCi0gICAqIEBwYXJhbSB0YWJsZSBhIHRhYmxlIGNvbnRhaW5pbmcgb25lIGNoYXJhY3RlciBmb3IgZWFjaCBkaWdpdCBpbiB0aGUgcmFkaXgKLSAgICogQHJldHVybiBTdHJpbmcgcmVwcmVzZW50aW5nIGFscGhhIGNvdW50IG9mIG51bWJlci4KLSAgICogQHNlZSBUcmFuc2Zvcm1lckltcGwjRGVjaW1hbFRvUm9tYW4KLSAgICoKLSAgICogTm90ZSB0aGF0IHRoZSByYWRpeCBvZiB0aGUgY29udmVyc2lvbiBpcyBpbmZlcnJlZCBmcm9tIHRoZSBzaXplCi0gICAqIG9mIHRoZSB0YWJsZS4KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgaW50MnNpbmdsZWFscGhhQ291bnQoaW50IHZhbCwgY2hhcltdIHRhYmxlKQotICB7Ci0KLSAgICBpbnQgcmFkaXggPSB0YWJsZS5sZW5ndGg7Ci0KLSAgICAvLyBUT0RPOiAgdGhyb3cgZXJyb3Igb24gb3V0IG9mIHJhbmdlIGlucHV0Ci0gICAgaWYgKHZhbCA+IHJhZGl4KQotICAgIHsKLSAgICAgIHJldHVybiBnZXRaZXJvU3RyaW5nKCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiAobmV3IENoYXJhY3Rlcih0YWJsZVt2YWwgLSAxXSkpLnRvU3RyaW5nKCk7ICAvLyBpbmRleCBpbnRvIHRhYmxlIGlzIG9mZiBvbmUsIHN0YXJ0cyBhdCAwCi0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIGxvbmcgaW50ZWdlciBpbnRvIGFscGhhYmV0aWMgY291bnRpbmcsIGluIG90aGVyIHdvcmRzCi0gICAqIGNvdW50IHVzaW5nIHRoZSBzZXF1ZW5jZSBBIEIgQyAuLi4gWiBBQSBBQiBBQy4uLi4gZXRjLgotICAgKiAKLSAgICogQHBhcmFtIHZhbCBWYWx1ZSB0byBjb252ZXJ0IC0tIG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm8uCi0gICAqIEBwYXJhbSB0YWJsZSBhIHRhYmxlIGNvbnRhaW5pbmcgb25lIGNoYXJhY3RlciBmb3IgZWFjaCBkaWdpdCBpbiB0aGUgcmFkaXgKLSAgICogQHBhcmFtIGFUYWJsZSBBcnJheSBvZiBhbHBoYSBjaGFyYWN0ZXJzIHJlcHJlc2VudGluZyBudW1iZXJzCi0gICAqIEBwYXJhbSBzdHJpbmdCdWYgQnVmZmVyIHdoZXJlIHRvIHNhdmUgdGhlIHN0cmluZyByZXByZXNlbnRpbmcgYWxwaGEgY291bnQgb2YgbnVtYmVyLgotICAgKiAKLSAgICogQHNlZSBUcmFuc2Zvcm1lckltcGwjRGVjaW1hbFRvUm9tYW4KLSAgICoKLSAgICogTm90ZSB0aGF0IHRoZSByYWRpeCBvZiB0aGUgY29udmVyc2lvbiBpcyBpbmZlcnJlZCBmcm9tIHRoZSBzaXplCi0gICAqIG9mIHRoZSB0YWJsZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGludDJhbHBoYUNvdW50KGludCB2YWwsIGNoYXJbXSBhVGFibGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhc3RTdHJpbmdCdWZmZXIgc3RyaW5nQnVmKQotICB7Ci0KLSAgICBpbnQgcmFkaXggPSBhVGFibGUubGVuZ3RoOwotICAgIGNoYXJbXSB0YWJsZSA9IG5ldyBjaGFyW2FUYWJsZS5sZW5ndGhdOwotCi0gICAgLy8gc3RhcnQgdGFibGUgYXQgMSwgYWRkIGxhc3QgY2hhciBhdCBpbmRleCAwLiBSZWFzb24gZXhwbGFpbmVkIGFib3ZlIGFuZCBiZWxvdy4KLSAgICBpbnQgaTsKLQotICAgIGZvciAoaSA9IDA7IGkgPCBhVGFibGUubGVuZ3RoIC0gMTsgaSsrKQotICAgIHsKLSAgICAgIHRhYmxlW2kgKyAxXSA9IGFUYWJsZVtpXTsKLSAgICB9Ci0KLSAgICB0YWJsZVswXSA9IGFUYWJsZVtpXTsKLQotICAgIC8vIENyZWF0ZSBhIGJ1ZmZlciB0byBob2xkIHRoZSByZXN1bHQKLSAgICAvLyBUT0RPOiAgc2l6ZSBvZiB0aGUgdGFibGUgY2FuIGJlIGRldGVyZWluZWQgYnkgY29tcHV0aW5nCi0gICAgLy8gbG9ncyBvZiB0aGUgcmFkaXguICBGb3Igbm93LCB3ZSBmYWtlIGl0LgotICAgIGNoYXIgYnVmW10gPSBuZXcgY2hhclsxMDBdOwotCi0gICAgLy9zb21lIGxhbmd1YWdlcyBnbyBsZWZ0IHRvIHJpZ2h0KGllLiBlbmdsaXNoKSwgcmlnaHQgdG8gbGVmdCAoaWUuIEhlYnJldyksCi0gICAgLy90b3AgdG8gYm90dG9tIChpZS5KYXBhbmVzZSksIGV0Yy4uLiBIYW5kbGUgdGhlbSBkaWZmZXJlbnRseQotICAgIC8vU3RyaW5nIG9yaWVudGF0aW9uID0gdGhpc0J1bmRsZS5nZXRTdHJpbmcob3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5MQU5HX09SSUVOVEFUSU9OKTsKLSAgICAvLyBuZXh0IGNoYXJhY3RlciB0byBzZXQgaW4gdGhlIGJ1ZmZlcgotICAgIGludCBjaGFyUG9zOwotCi0gICAgY2hhclBvcyA9IGJ1Zi5sZW5ndGggLSAxOyAgLy8gd29yayBiYWNrd2FyZCB0aHJvdWdoIGJ1ZltdICAKLQotICAgIC8vIGluZGV4IGluIHRhYmxlIG9mIHRoZSBsYXN0IGNoYXJhY3RlciB0aGF0IHdlIHN0b3JlZAotICAgIGludCBsb29rdXBJbmRleCA9IDE7ICAvLyBzdGFydCBvZmYgd2l0aCBhbnl0aGluZyBvdGhlciB0aGFuIHplcm8gdG8gbWFrZSBjb3JyZWN0aW9uIHdvcmsKLQotICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29ycmVjdGlvbiBudW1iZXIKLSAgICAvLwotICAgIC8vICBDb3JyZWN0aW9uIGNhbiB0YWtlIG9uIGV4YWN0bHkgdHdvIHZhbHVlczoKLSAgICAvLwotICAgIC8vICAgICAgICAgIDAgICAgICAgaWYgdGhlIG5leHQgY2hhcmFjdGVyIGlzIHRvIGJlIGVtaXR0ZWQgaXMgdXN1YWwKLSAgICAvLwotICAgIC8vICAgICAgcmFkaXggLSAxCi0gICAgLy8gICAgICAgICAgICAgICAgICBpZiB0aGUgbmV4dCBjaGFyIHRvIGJlIGVtaXR0ZWQgc2hvdWxkIGJlIG9uZSBsZXNzIHRoYW4KLSAgICAvLyAgICAgICAgICAgICAgICAgIHlvdSB3b3VsZCBleHBlY3QKLSAgICAvLyAgICAgICAgICAgICAgICAgIAotICAgIC8vIEZvciBleGFtcGxlLCBjb25zaWRlciByYWRpeCAxMCwgd2hlcmUgMT0iQSIgYW5kIDEwPSJKIgotICAgIC8vCi0gICAgLy8gSW4gdGhpcyBzY2hlbWUsIHdlIGNvdW50OiBBLCBCLCBDIC4uLiAgIEgsIEksIEogKG5vdCBBMCBhbmQgY2VydGFpbmx5Ci0gICAgLy8gbm90IEFKKSwgQTEKLSAgICAvLwotICAgIC8vIFNvLCBob3cgZG8gd2Uga2VlcCBmcm9tIGVtaXR0aW5nIEFKIGZvciAxMD8gIEFmdGVyIGNvcnJlY3RseSBlbWl0dGluZyB0aGUKLSAgICAvLyBKLCBsb29rdXBJbmRleCBpcyB6ZXJvLiAgV2Ugbm93IGNvbXB1dGUgYSBjb3JyZWN0aW9uIG51bWJlciBvZiA5IChyYWRpeC0xKS4KLSAgICAvLyBJbiB0aGUgZm9sbG93aW5nIGxpbmUsIHdlJ2xsIGNvbXB1dGUgKHZhbCtjb3JyZWN0aW9uKSAlIHJhZGl4LCB3aGljaCBpcywKLSAgICAvLyAodmFsKzkpLzEwLiAgQnkgdGhpcyB0aW1lLCB2YWwgaXMgMSwgc28gd2UgY29tcHV0ZSAoMSs5KSAlIDEwLCB3aGljaAotICAgIC8vIGlzIDEwICUgMTAgb3IgemVyby4gIFNvLCB3ZSdsbCBwcmVwYXJlIHRvIGVtaXQgIkpKIiwgYnV0IHRoZW4gd2UnbGwKLSAgICAvLyBsYXRlciBzdXBwcmVzcyB0aGUgbGVhZGluZyBKIGFzIHJlcHJlc2VudGluZyB6ZXJvIChpbiB0aGUgbW9kIHN5c3RlbSwKLSAgICAvLyBpdCBjYW4gcmVwcmVzZW50IGVpdGhlciAxMCBvciB6ZXJvKS4gIEluIHN1bW1hcnksIHRoZSBjb3JyZWN0aW9uIHZhbHVlIG9mCi0gICAgLy8gInJhZGl4LTEiIGFjdHMgbGlrZSAiLTEiIHdoZW4gcnVuIHRocm91Z2ggdGhlIG1vZCBvcGVyYXRvciwgYnV0IHdpdGggdGhlCi0gICAgLy8gZGVzaXJlYWJsZSBjaGFyYWN0ZXJpc3RpYyB0aGF0IGl0IG5ldmVyIHByb2R1Y2VzIGEgbmVnYXRpdmUgbnVtYmVyLgotICAgIGludCBjb3JyZWN0aW9uID0gMDsKLQotICAgIC8vIFRPRE86ICB0aHJvdyBlcnJvciBvbiBvdXQgb2YgcmFuZ2UgaW5wdXQKLSAgICBkbwotICAgIHsKLQotICAgICAgLy8gbW9zdCBvZiB0aGUgY29ycmVjdGlvbiBjYWxjdWxhdGlvbiBpcyBleHBsYWluZWQgYWJvdmUsICB0aGUgcmVhc29uIGZvciB0aGUKLSAgICAgIC8vIHRlcm0gYWZ0ZXIgdGhlICJ8fCAiIGlzIHRoYXQgaXQgY29ycmVjdGx5IHByb3BhZ2F0ZXMgY2FycmllcyBhY3Jvc3MKLSAgICAgIC8vIG11bHRpcGxlIGNvbHVtbnMuCi0gICAgICBjb3JyZWN0aW9uID0KLSAgICAgICAgKChsb29rdXBJbmRleCA9PSAwKSB8fCAoY29ycmVjdGlvbiAhPSAwICYmIGxvb2t1cEluZGV4ID09IHJhZGl4IC0gMSkpCi0gICAgICAgID8gKHJhZGl4IC0gMSkgOiAwOwotCi0gICAgICAvLyBpbmRleCBpbiAidGFibGUiIG9mIHRoZSBuZXh0IGNoYXIgdG8gZW1pdAotICAgICAgbG9va3VwSW5kZXggPSAodmFsICsgY29ycmVjdGlvbikgJSByYWRpeDsKLQotICAgICAgLy8gc2hpZnQgaW5wdXQgYnkgb25lICJjb2x1bW4iCi0gICAgICB2YWwgPSAodmFsIC8gcmFkaXgpOwotCi0gICAgICAvLyBpZiB0aGUgbmV4dCB2YWx1ZSB3ZSdkIHB1dCBvdXQgd291bGQgYmUgYSBsZWFkaW5nIHplcm8sIHdlJ3JlIGRvbmUuCi0gICAgICBpZiAobG9va3VwSW5kZXggPT0gMCAmJiB2YWwgPT0gMCkKLSAgICAgICAgYnJlYWs7Ci0KLSAgICAgIC8vIHB1dCBvdXQgdGhlIG5leHQgY2hhcmFjdGVyIG9mIG91dHB1dAotICAgICAgYnVmW2NoYXJQb3MtLV0gPSB0YWJsZVtsb29rdXBJbmRleF07ICAvLyBsZWZ0IHRvIHJpZ2h0IG9yIHRvcCB0byBib3R0b20gICAKLSAgICB9Ci0gICAgd2hpbGUgKHZhbCA+IDApOwotCi0gICAgc3RyaW5nQnVmLmFwcGVuZChidWYsIGNoYXJQb3MgKyAxLCAoYnVmLmxlbmd0aCAtIGNoYXJQb3MgLSAxKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIGxvbmcgaW50ZWdlciBpbnRvIHRyYWRpdGlvbmFsIGFscGhhYmV0aWMgY291bnRpbmcsIGluIG90aGVyIHdvcmRzCi0gICAqIGNvdW50IHVzaW5nIHRoZSB0cmFkaXRpb25hbCBudW1iZXJpbmcuCi0gICAqIAotICAgKiBAcGFyYW0gdmFsIFZhbHVlIHRvIGNvbnZlcnQgLS0gbXVzdCBiZSBncmVhdGVyIHRoYW4gemVyby4KLSAgICogQHBhcmFtIHRhYmxlIGEgdGFibGUgY29udGFpbmluZyBvbmUgY2hhcmFjdGVyIGZvciBlYWNoIGRpZ2l0IGluIHRoZSByYWRpeAotICAgKiBAcGFyYW0gdGhpc0J1bmRsZSBSZXNvdXJjZSBidW5kbGUgdG8gdXNlCi0gICAqIAotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRpbmcgYWxwaGEgY291bnQgb2YgbnVtYmVyLgotICAgKiBAc2VlIFhTTFByb2Nlc3NvciNEZWNpbWFsVG9Sb21hbgotICAgKgotICAgKiBOb3RlIHRoYXQgdGhlIHJhZGl4IG9mIHRoZSBjb252ZXJzaW9uIGlzIGluZmVycmVkIGZyb20gdGhlIHNpemUKLSAgICogb2YgdGhlIHRhYmxlLgotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyB0cmFkQWxwaGFDb3VudChpbnQgdmFsLCBYUmVzb3VyY2VCdW5kbGUgdGhpc0J1bmRsZSkKLSAgewotCi0gICAgLy8gaWYgdGhpcyBudW1iZXIgaXMgbGFyZ2VyIHRoYW4gdGhlIGxhcmdlc3QgbnVtYmVyIHdlIGNhbiByZXByZXNlbnQsIGVycm9yIQotICAgIC8vaWYgKHZhbCA+ICgoSW50ZWdlcil0aGlzQnVuZGxlLmdldE9iamVjdCgiTWF4TnVtZXJpY2FsVmFsdWUiKSkuaW50VmFsdWUoKSkKLSAgICAvL3JldHVybiBYU0xURXJyb3JSZXNvdXJjZXMuRVJST1JfU1RSSU5HOwotICAgIGNoYXJbXSB0YWJsZSA9IG51bGw7Ci0KLSAgICAvLyBpbmRleCBpbiB0YWJsZSBvZiB0aGUgbGFzdCBjaGFyYWN0ZXIgdGhhdCB3ZSBzdG9yZWQKLSAgICBpbnQgbG9va3VwSW5kZXggPSAxOyAgLy8gc3RhcnQgb2ZmIHdpdGggYW55dGhpbmcgb3RoZXIgdGhhbiB6ZXJvIHRvIG1ha2UgY29ycmVjdGlvbiB3b3JrCi0KLSAgICAvLyBDcmVhdGUgYSBidWZmZXIgdG8gaG9sZCB0aGUgcmVzdWx0Ci0gICAgLy8gVE9ETzogIHNpemUgb2YgdGhlIHRhYmxlIGNhbiBiZSBkZXRlcmVpbmVkIGJ5IGNvbXB1dGluZwotICAgIC8vIGxvZ3Mgb2YgdGhlIHJhZGl4LiAgRm9yIG5vdywgd2UgZmFrZSBpdC4KLSAgICBjaGFyIGJ1ZltdID0gbmV3IGNoYXJbMTAwXTsKLQotICAgIC8vc29tZSBsYW5ndWFnZXMgZ28gbGVmdCB0byByaWdodChpZS4gZW5nbGlzaCksIHJpZ2h0IHRvIGxlZnQgKGllLiBIZWJyZXcpLAotICAgIC8vdG9wIHRvIGJvdHRvbSAoaWUuSmFwYW5lc2UpLCBldGMuLi4gSGFuZGxlIHRoZW0gZGlmZmVyZW50bHkKLSAgICAvL1N0cmluZyBvcmllbnRhdGlvbiA9IHRoaXNCdW5kbGUuZ2V0U3RyaW5nKG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19PUklFTlRBVElPTik7Ci0gICAgLy8gbmV4dCBjaGFyYWN0ZXIgdG8gc2V0IGluIHRoZSBidWZmZXIKLSAgICBpbnQgY2hhclBvczsKLQotICAgIGNoYXJQb3MgPSAwOyAgLy9zdGFydCBhdCAwCi0KLSAgICAvLyBhcnJheSBvZiBudW1iZXIgZ3JvdXBzOiBpZS4xMDAwLCAxMDAsIDEwLCAxCi0gICAgaW50W10gZ3JvdXBzID0gKGludFtdKSB0aGlzQnVuZGxlLmdldE9iamVjdChvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfTlVNQkVSR1JPVVBTKTsKLQotICAgIC8vIGFycmF5IG9mIHRhYmxlcyBvZiBodW5kcmVkcywgdGVucywgZGlnaXRzLi4uCi0gICAgU3RyaW5nW10gdGFibGVzID0KLSAgICAgIChTdHJpbmdbXSkgKHRoaXNCdW5kbGUuZ2V0T2JqZWN0KG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGUuTEFOR19OVU1fVEFCTEVTKSk7Ci0KLSAgICAvL3NvbWUgbGFuZ3VhZ2VzIGhhdmUgYWRkaXRpdmUgYWxwaGFiZXRpY2FsIG5vdGF0aW9uLAotICAgIC8vc29tZSBtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSwgZXRjLi4uIEhhbmRsZSB0aGVtIGRpZmZlcmVudGx5LgotICAgIFN0cmluZyBudW1iZXJpbmcgPSB0aGlzQnVuZGxlLmdldFN0cmluZyhvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfTlVNQkVSSU5HKTsKLQotICAgIC8vIGRvIG11bHRpcGxpY2F0aXZlIHBhcnQgZmlyc3QKLSAgICBpZiAobnVtYmVyaW5nLmVxdWFscyhvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfTVVMVF9BREQpKQotICAgIHsKLSAgICAgIFN0cmluZyBtdWx0X29yZGVyID0gdGhpc0J1bmRsZS5nZXRTdHJpbmcob3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5NVUxUX09SREVSKTsKLSAgICAgIGludFtdIG11bHRpcGxpZXIgPQotICAgICAgICAoaW50W10pICh0aGlzQnVuZGxlLmdldE9iamVjdChvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfTVVMVElQTElFUikpOwotICAgICAgY2hhcltdIHplcm9DaGFyID0gKGNoYXJbXSkgdGhpc0J1bmRsZS5nZXRPYmplY3QoInplcm8iKTsKLSAgICAgIGludCBpID0gMDsKLQotICAgICAgLy8gc2tpcCB0byBjb3JyZWN0IG11bHRpcGxpZXIKLSAgICAgIHdoaWxlIChpIDwgbXVsdGlwbGllci5sZW5ndGggJiYgdmFsIDwgbXVsdGlwbGllcltpXSkKLSAgICAgIHsKLSAgICAgICAgaSsrOwotICAgICAgfQotCi0gICAgICBkbwotICAgICAgewotICAgICAgICBpZiAoaSA+PSBtdWx0aXBsaWVyLmxlbmd0aCkKLSAgICAgICAgICBicmVhazsgIC8vbnVtYmVyIGlzIHNtYWxsZXIgdGhhbiBtdWx0aXBsaWVycwotCi0gICAgICAgIC8vIHNvbWUgbGFuZ3VhZ2VzIChpZSBjaGluZXNlKSBwdXQgYSB6ZXJvIGNoYXJhY3RlciAoYW5kIG9ubHkgb25lKSB3aGVuCi0gICAgICAgIC8vIHRoZSBtdWx0aXBsaWVyIGlzIG11bHRpcGxpZWQgYnkgemVyby4gKGllLCAxMDAxIGlzIDFYMTAwMCArIDBYMTAwICsgMFgxMCArIDEpCi0gICAgICAgIC8vIDBYMTAwIGlzIHJlcGxhY2VkIGJ5IHRoZSB6ZXJvIGNoYXJhY3Rlciwgd2UgZG9uJ3QgbmVlZCBvbmUgZm9yIDBYMTAKLSAgICAgICAgaWYgKHZhbCA8IG11bHRpcGxpZXJbaV0pCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoemVyb0NoYXIubGVuZ3RoID09IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgaSsrOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGJ1ZltjaGFyUG9zIC0gMV0gIT0gemVyb0NoYXJbMF0pCi0gICAgICAgICAgICAgIGJ1ZltjaGFyUG9zKytdID0gemVyb0NoYXJbMF07Ci0KLSAgICAgICAgICAgIGkrKzsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodmFsID49IG11bHRpcGxpZXJbaV0pCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgbXVsdCA9IHZhbCAvIG11bHRpcGxpZXJbaV07Ci0KLSAgICAgICAgICB2YWwgPSB2YWwgJSBtdWx0aXBsaWVyW2ldOyAgLy8gc2F2ZSB0aGlzLgotCi0gICAgICAgICAgaW50IGsgPSAwOwotCi0gICAgICAgICAgd2hpbGUgKGsgPCBncm91cHMubGVuZ3RoKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGxvb2t1cEluZGV4ID0gMTsgIC8vIGluaXRpYWxpemUgZm9yIGVhY2ggdGFibGUKLQotICAgICAgICAgICAgaWYgKG11bHQgLyBncm91cHNba10gPD0gMCkgIC8vIGxvb2sgZm9yIHJpZ2h0IHRhYmxlCi0gICAgICAgICAgICAgIGsrKzsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAvLyBnZXQgdGhlIHRhYmxlCi0gICAgICAgICAgICAgIGNoYXJbXSBUSEVsZXR0ZXJzID0gKGNoYXJbXSkgdGhpc0J1bmRsZS5nZXRPYmplY3QodGFibGVzW2tdKTsKLQotICAgICAgICAgICAgICB0YWJsZSA9IG5ldyBjaGFyW1RIRWxldHRlcnMubGVuZ3RoICsgMV07Ci0KLSAgICAgICAgICAgICAgaW50IGo7Ci0KLSAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IFRIRWxldHRlcnMubGVuZ3RoOyBqKyspCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0YWJsZVtqICsgMV0gPSBUSEVsZXR0ZXJzW2pdOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgdGFibGVbMF0gPSBUSEVsZXR0ZXJzW2ogLSAxXTsgIC8vIGRvbid0IG5lZWQgdGhpcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLQotICAgICAgICAgICAgICAvLyBpbmRleCBpbiAidGFibGUiIG9mIHRoZSBuZXh0IGNoYXIgdG8gZW1pdAotICAgICAgICAgICAgICBsb29rdXBJbmRleCA9IG11bHQgLyBncm91cHNba107Ci0KLSAgICAgICAgICAgICAgLy90aGlzIHNob3VsZCBub3QgaGFwcGVuCi0gICAgICAgICAgICAgIGlmIChsb29rdXBJbmRleCA9PSAwICYmIG11bHQgPT0gMCkKLSAgICAgICAgICAgICAgICBicmVhazsKLQotICAgICAgICAgICAgICBjaGFyIG11bHRpcGxpZXJDaGFyID0gKChjaGFyW10pICh0aGlzQnVuZGxlLmdldE9iamVjdCgKLSAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlLkxBTkdfTVVMVElQTElFUl9DSEFSKSkpW2ldOwotCi0gICAgICAgICAgICAgIC8vIHB1dCBvdXQgdGhlIG5leHQgY2hhcmFjdGVyIG9mIG91dHB1dCAgIAotICAgICAgICAgICAgICBpZiAobG9va3VwSW5kZXggPCB0YWJsZS5sZW5ndGgpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAobXVsdF9vcmRlci5lcXVhbHMob3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5NVUxUX1BSRUNFREVTKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBidWZbY2hhclBvcysrXSA9IG11bHRpcGxpZXJDaGFyOwotICAgICAgICAgICAgICAgICAgYnVmW2NoYXJQb3MrK10gPSB0YWJsZVtsb29rdXBJbmRleF07Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgICAgIC8vIGRvbid0IHB1dCBvdXQgMSAoaWUgMVgxMCBpcyBqdXN0IDEwKQotICAgICAgICAgICAgICAgICAgaWYgKGxvb2t1cEluZGV4ID09IDEgJiYgaSA9PSBtdWx0aXBsaWVyLmxlbmd0aCAtIDEpe30KLSAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgYnVmW2NoYXJQb3MrK10gPSB0YWJsZVtsb29rdXBJbmRleF07Ci0KLSAgICAgICAgICAgICAgICAgIGJ1ZltjaGFyUG9zKytdID0gbXVsdGlwbGllckNoYXI7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgYnJlYWs7ICAvLyBhbGwgZG9uZSEKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgcmV0dXJuIFhTTFRFcnJvclJlc291cmNlcy5FUlJPUl9TVFJJTkc7Ci0gICAgICAgICAgICB9ICAvL2VuZCBlbHNlCi0gICAgICAgICAgfSAgLy8gZW5kIHdoaWxlICAgICAgICAKLQotICAgICAgICAgIGkrKzsKLSAgICAgICAgfSAgLy8gZW5kIGVsc2UgaWYKLSAgICAgIH0gIC8vIGVuZCBkbyB3aGlsZQotICAgICAgd2hpbGUgKGkgPCBtdWx0aXBsaWVyLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgLy8gTm93IGRvIGFkZGl0aXZlIHBhcnQuLi4KLSAgICBpbnQgY291bnQgPSAwOwotICAgIFN0cmluZyB0YWJsZU5hbWU7Ci0KLSAgICAvLyBkbyB0aGlzIGZvciBlYWNoIHRhYmxlIG9mIGh1bmRyZWRzLCB0ZW5zLCBkaWdpdHMuLi4KLSAgICB3aGlsZSAoY291bnQgPCBncm91cHMubGVuZ3RoKQotICAgIHsKLSAgICAgIGlmICh2YWwgLyBncm91cHNbY291bnRdIDw9IDApICAvLyBsb29rIGZvciBjb3JyZWN0IHRhYmxlCi0gICAgICAgIGNvdW50Kys7Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGNoYXJbXSB0aGVsZXR0ZXJzID0gKGNoYXJbXSkgdGhpc0J1bmRsZS5nZXRPYmplY3QodGFibGVzW2NvdW50XSk7Ci0KLSAgICAgICAgdGFibGUgPSBuZXcgY2hhclt0aGVsZXR0ZXJzLmxlbmd0aCArIDFdOwotCi0gICAgICAgIGludCBqOwotCi0gICAgICAgIC8vIG5lZWQgdG8gc3RhcnQgZmlsbGluZyB0aGUgdGFibGUgdXAgYXQgaW5kZXggMQotICAgICAgICBmb3IgKGogPSAwOyBqIDwgdGhlbGV0dGVycy5sZW5ndGg7IGorKykKLSAgICAgICAgewotICAgICAgICAgIHRhYmxlW2ogKyAxXSA9IHRoZWxldHRlcnNbal07Ci0gICAgICAgIH0KLQotICAgICAgICB0YWJsZVswXSA9IHRoZWxldHRlcnNbaiAtIDFdOyAgLy8gZG9uJ3QgbmVlZCB0aGlzCi0KLSAgICAgICAgLy8gaW5kZXggaW4gInRhYmxlIiBvZiB0aGUgbmV4dCBjaGFyIHRvIGVtaXQKLSAgICAgICAgbG9va3VwSW5kZXggPSB2YWwgLyBncm91cHNbY291bnRdOwotCi0gICAgICAgIC8vIHNoaWZ0IGlucHV0IGJ5IG9uZSAiY29sdW1uIgotICAgICAgICB2YWwgPSB2YWwgJSBncm91cHNbY291bnRdOwotCi0gICAgICAgIC8vIHRoaXMgc2hvdWxkIG5vdCBoYXBwZW4KLSAgICAgICAgaWYgKGxvb2t1cEluZGV4ID09IDAgJiYgdmFsID09IDApCi0gICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgaWYgKGxvb2t1cEluZGV4IDwgdGFibGUubGVuZ3RoKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBwdXQgb3V0IHRoZSBuZXh0IGNoYXJhY3RlciBvZiBvdXRwdXQgICAgICAgCi0gICAgICAgICAgYnVmW2NoYXJQb3MrK10gPSB0YWJsZVtsb29rdXBJbmRleF07ICAvLyBsZWZ0IHRvIHJpZ2h0IG9yIHRvcCB0byBib3R0b20gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIFhTTFRFcnJvclJlc291cmNlcy5FUlJPUl9TVFJJTkc7Ci0KLSAgICAgICAgY291bnQrKzsKLSAgICAgIH0KLSAgICB9ICAvLyBlbmQgd2hpbGUKLQotICAgIC8vIFN0cmluZyBzID0gbmV3IFN0cmluZyhidWYsIDAsIGNoYXJQb3MpOwotICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgMCwgY2hhclBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIGxvbmcgaW50ZWdlciBpbnRvIHJvbWFuIG51bWVyYWxzLgotICAgKiBAcGFyYW0gdmFsIFZhbHVlIHRvIGNvbnZlcnQuCi0gICAqIEBwYXJhbSBwcmVmaXhlc0FyZU9LIHRydWVfIHRvIGVuYWJsZSBwcmVmaXggbm90YXRpb24gKGUuZy4gNCA9ICJJViIpLAotICAgKiBmYWxzZV8gdG8gZGlzYWJsZSBwcmVmaXggbm90YXRpb24gKGUuZy4gNCA9ICJJSUlJIikuCi0gICAqIEByZXR1cm4gUm9tYW4gbnVtZXJhbCBzdHJpbmcuCi0gICAqIEBzZWUgRGVjaW1hbFRvUm9tYW4KLSAgICogQHNlZSBtX3JvbWFuQ29udmVydFRhYmxlCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIGxvbmcycm9tYW4obG9uZyB2YWwsIGJvb2xlYW4gcHJlZml4ZXNBcmVPSykKLSAgewotCi0gICAgaWYgKHZhbCA8PSAwKQotICAgIHsKLSAgICAgIHJldHVybiBnZXRaZXJvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgU3RyaW5nIHJvbWFuID0gIiI7Ci0gICAgaW50IHBsYWNlID0gMDsKLQotICAgIGlmICh2YWwgPD0gMzk5OUwpCi0gICAgewotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgd2hpbGUgKHZhbCA+PSBtX3JvbWFuQ29udmVydFRhYmxlW3BsYWNlXS5tX3Bvc3RWYWx1ZSkKLSAgICAgICAgewotICAgICAgICAgIHJvbWFuICs9IG1fcm9tYW5Db252ZXJ0VGFibGVbcGxhY2VdLm1fcG9zdExldHRlcjsKLSAgICAgICAgICB2YWwgLT0gbV9yb21hbkNvbnZlcnRUYWJsZVtwbGFjZV0ubV9wb3N0VmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAocHJlZml4ZXNBcmVPSykKLSAgICAgICAgewotICAgICAgICAgIGlmICh2YWwgPj0gbV9yb21hbkNvbnZlcnRUYWJsZVtwbGFjZV0ubV9wcmVWYWx1ZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByb21hbiArPSBtX3JvbWFuQ29udmVydFRhYmxlW3BsYWNlXS5tX3ByZUxldHRlcjsKLSAgICAgICAgICAgIHZhbCAtPSBtX3JvbWFuQ29udmVydFRhYmxlW3BsYWNlXS5tX3ByZVZhbHVlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHBsYWNlKys7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAodmFsID4gMCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByb21hbiA9IFhTTFRFcnJvclJlc291cmNlcy5FUlJPUl9TVFJJTkc7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJvbWFuOwotICB9ICAvLyBlbmQgbG9uZzJyb21hbgotCi0gIC8qKgotICAgKiBUaGlzIGNsYXNzIHJldHVybnMgdG9rZW5zIHVzaW5nIG5vbi1hbHBoYW51bWJlcmljCi0gICAqIGNoYXJhY3RlcnMgYXMgZGVsaW1pdGVycy4KLSAgICovCi0gIGNsYXNzIE51bWJlckZvcm1hdFN0cmluZ1Rva2VuaXplcgotICB7Ci0KLSAgICAvKiogQ3VycmVudCBwb3NpdGlvbiBpbiB0aGUgZm9ybWF0IHN0cmluZyAgICAgICAgICAqLwotICAgIHByaXZhdGUgaW50IGN1cnJlbnRQb3NpdGlvbjsKLQotICAgIC8qKiBJbmRleCBvZiBsYXN0IGNoYXJhY3RlciBpbiB0aGUgZm9ybWF0IHN0cmluZyAgICAgICovCi0gICAgcHJpdmF0ZSBpbnQgbWF4UG9zaXRpb247Ci0KLSAgICAvKiogRm9ybWF0IHN0cmluZyB0byBiZSB0b2tlbml6ZWQgICAgICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgc3RyOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0IGEgTnVtYmVyRm9ybWF0U3RyaW5nVG9rZW5pemVyLgotICAgICAqCi0gICAgICogQHBhcmFtIHN0ciBGb3JtYXQgc3RyaW5nIHRvIGJlIHRva2VuaXplZAotICAgICAqLwotICAgIHB1YmxpYyBOdW1iZXJGb3JtYXRTdHJpbmdUb2tlbml6ZXIoU3RyaW5nIHN0cikKLSAgICB7Ci0gICAgICB0aGlzLnN0ciA9IHN0cjsKLSAgICAgIG1heFBvc2l0aW9uID0gc3RyLmxlbmd0aCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc2V0IHRva2VuaXplciBzbyB0aGF0IG5leHRUb2tlbigpIHN0YXJ0cyBmcm9tIHRoZSBiZWdpbm5pbmcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVzZXQoKQotICAgIHsKLSAgICAgIGN1cnJlbnRQb3NpdGlvbiA9IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiBmcm9tIHRoaXMgc3RyaW5nIHRva2VuaXplci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgIHRoZSBuZXh0IHRva2VuIGZyb20gdGhpcyBzdHJpbmcgdG9rZW5pemVyLgotICAgICAqIEB0aHJvd3MgIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gIGlmIHRoZXJlIGFyZSBubyBtb3JlIHRva2VucyBpbiB0aGlzCi0gICAgICogICAgICAgICAgICAgICB0b2tlbml6ZXIncyBzdHJpbmcuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBuZXh0VG9rZW4oKQotICAgIHsKLQotICAgICAgaWYgKGN1cnJlbnRQb3NpdGlvbiA+PSBtYXhQb3NpdGlvbikKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKLSAgICAgIH0KLQotICAgICAgaW50IHN0YXJ0ID0gY3VycmVudFBvc2l0aW9uOwotCi0gICAgICB3aGlsZSAoKGN1cnJlbnRQb3NpdGlvbiA8IG1heFBvc2l0aW9uKQotICAgICAgICAgICAgICYmIENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoc3RyLmNoYXJBdChjdXJyZW50UG9zaXRpb24pKSkKLSAgICAgIHsKLSAgICAgICAgY3VycmVudFBvc2l0aW9uKys7Ci0gICAgICB9Ci0KLSAgICAgIGlmICgoc3RhcnQgPT0gY3VycmVudFBvc2l0aW9uKQotICAgICAgICAgICAgICAmJiAoIUNoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoc3RyLmNoYXJBdChjdXJyZW50UG9zaXRpb24pKSkpCi0gICAgICB7Ci0gICAgICAgIGN1cnJlbnRQb3NpdGlvbisrOwotICAgICAgfQotCi0gICAgICByZXR1cm4gc3RyLnN1YnN0cmluZyhzdGFydCwgY3VycmVudFBvc2l0aW9uKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxscyBpZiB0aGVyZSBpcyBhIGRpZ2l0IG9yIGEgbGV0dGVyIGNoYXJhY3RlciBhaGVhZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gICAgIHRydWUgaWYgdGhlcmUgaXMgYSBudW1iZXIgb3IgY2hhcmFjdGVyIGFoZWFkLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzTGV0dGVyT3JEaWdpdEFoZWFkKCkKLSAgICB7Ci0KLSAgICAgIGludCBwb3MgPSBjdXJyZW50UG9zaXRpb247Ci0KLSAgICAgIHdoaWxlIChwb3MgPCBtYXhQb3NpdGlvbikKLSAgICAgIHsKLSAgICAgICAgaWYgKENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoc3RyLmNoYXJBdChwb3MpKSkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICBwb3MrKzsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGxzIGlmIHRoZXJlIGlzIGEgZGlnaXQgb3IgYSBsZXR0ZXIgY2hhcmFjdGVyIGFoZWFkLgotICAgICAqCi0gICAgICogQHJldHVybiAgICAgdHJ1ZSBpZiB0aGVyZSBpcyBhIG51bWJlciBvciBjaGFyYWN0ZXIgYWhlYWQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbmV4dElzU2VwKCkKLSAgICB7Ci0KLSAgICAgIGlmIChDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KHN0ci5jaGFyQXQoY3VycmVudFBvc2l0aW9uKSkpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbHMgaWYgPGNvZGU+bmV4dFRva2VuPC9jb2RlPiB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbgotICAgICAqIGlmIGl0IGlzIGNhbGxlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiA8Y29kZT5uZXh0VG9rZW48L2NvZGU+IGNhbiBiZSBjYWxsZWQKLSAgICAgKiB3aXRob3V0IHRocm93aW5nIGFuIGV4Y2VwdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlVG9rZW5zKCkKLSAgICB7Ci0gICAgICByZXR1cm4gKGN1cnJlbnRQb3NpdGlvbiA+PSBtYXhQb3NpdGlvbikgPyBmYWxzZSA6IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIHRpbWVzIHRoYXQgdGhpcyB0b2tlbml6ZXIncwotICAgICAqIDxjb2RlPm5leHRUb2tlbjwvY29kZT4gbWV0aG9kIGNhbiBiZSBjYWxsZWQgYmVmb3JlIGl0IGdlbmVyYXRlcyBhbgotICAgICAqIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIHRoZSBudW1iZXIgb2YgdG9rZW5zIHJlbWFpbmluZyBpbiB0aGUgc3RyaW5nIHVzaW5nIHRoZSBjdXJyZW50Ci0gICAgICogICAgICAgICAgZGVsaW1pdGVyIHNldC4KLSAgICAgKiBAc2VlICAgICBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyI25leHRUb2tlbigpCi0gICAgICovCi0gICAgcHVibGljIGludCBjb3VudFRva2VucygpCi0gICAgewotCi0gICAgICBpbnQgY291bnQgPSAwOwotICAgICAgaW50IGN1cnJwb3MgPSBjdXJyZW50UG9zaXRpb247Ci0KLSAgICAgIHdoaWxlIChjdXJycG9zIDwgbWF4UG9zaXRpb24pCi0gICAgICB7Ci0gICAgICAgIGludCBzdGFydCA9IGN1cnJwb3M7Ci0KLSAgICAgICAgd2hpbGUgKChjdXJycG9zIDwgbWF4UG9zaXRpb24pCi0gICAgICAgICAgICAgICAmJiBDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KHN0ci5jaGFyQXQoY3VycnBvcykpKQotICAgICAgICB7Ci0gICAgICAgICAgY3VycnBvcysrOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKChzdGFydCA9PSBjdXJycG9zKQotICAgICAgICAgICAgICAgICYmIChDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KHN0ci5jaGFyQXQoY3VycnBvcykpID09IGZhbHNlKSkKLSAgICAgICAgewotICAgICAgICAgIGN1cnJwb3MrKzsKLSAgICAgICAgfQotCi0gICAgICAgIGNvdW50Kys7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBjb3VudDsKLSAgICB9Ci0gIH0gIC8vIGVuZCBOdW1iZXJGb3JtYXRTdHJpbmdUb2tlbml6ZXIKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtT3RoZXJ3aXNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbU90aGVyd2lzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMTkwN2Q1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtT3RoZXJ3aXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5OSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCB4c2w6b3RoZXJ3aXNlLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6b3RoZXJ3aXNlICV0ZW1wbGF0ZTs+Ci0gKiA8IUFUVExJU1QgeHNsOm90aGVyd2lzZSAlc3BhY2UtYXR0Oz4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ29uZGl0aW9uYWwtUHJvY2Vzc2luZy13aXRoLXhzbDpjaG9vc2UiPlhYWCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtT3RoZXJ3aXNlIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRva2VuIElEIGZvciB0aGlzIGVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0WFNMVG9rZW4oKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9PVEhFUldJU0U7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfT1RIRVJXSVNFX1NUUklORzsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1QSS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1QSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NjRlZDY4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtUEkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiAlY2hhci10ZW1wbGF0ZTs+Ci0gKiA8IUFUVExJU1QgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24KLSAqICAgbmFtZSAlYXZ0OyAjUkVRVUlSRUQKLSAqICAgJXNwYWNlLWF0dDsKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ3JlYXRpbmctUHJvY2Vzc2luZy1JbnN0cnVjdGlvbnMiPnNlY3Rpb24tQ3JlYXRpbmctUHJvY2Vzc2luZy1JbnN0cnVjdGlvbnMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbVBJIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBUaGUgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gZWxlbWVudCBoYXMgYSByZXF1aXJlZCBuYW1lCi0gICAqIGF0dHJpYnV0ZSB0aGF0IHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2RlLgotICAgKiBUaGUgdmFsdWUgb2YgdGhlIG5hbWUgYXR0cmlidXRlIGlzIGludGVycHJldGVkIGFzIGFuCi0gICAqIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBBVlQgbV9uYW1lX2F0diA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogREpECi0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIGZvciB0aGUgbmFtZSBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5hbWUoQVZUIHYpCi0gIHsKLSAgICBtX25hbWVfYXR2ID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqIERKRAotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgIm5hbWUiIGF0dHJpYnV0ZSAKLSAgICovCi0gIHB1YmxpYyBBVlQgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lX2F0djsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldFZhcmlhYmxlTmFtZXMoKTsKLSAgICBpZihudWxsICE9IG1fbmFtZV9hdHYpCi0gICAgICBtX25hbWVfYXR2LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCkuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gIH0KLQotCi0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoZSBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfUEk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfUElfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaW4gdGhlIHJlc3VsdCB0cmVlLgotICAgKiBUaGUgY29udGVudCBvZiB0aGUgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gZWxlbWVudCBpcyBhCi0gICAqIHRlbXBsYXRlIGZvciB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5vZGUuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNyZWF0aW5nLVByb2Nlc3NpbmctSW5zdHJ1Y3Rpb25zIj5zZWN0aW9uLUNyZWF0aW5nLVByb2Nlc3NpbmctSW5zdHJ1Y3Rpb25zIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZSgKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICBpbnQgc291cmNlTm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgU3RyaW5nIHBpTmFtZSA9IG1fbmFtZV9hdHYuZXZhbHVhdGUoeGN0eHQsIHNvdXJjZU5vZGUsIHRoaXMpOwotCi0gICAgaWYgKHBpTmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJ4bWwiKSkKLSAgICB7Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05BTUVfQ0FOVF9CRV9YTUwpOyAgLy8icHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBuYW1lIGNhbiBub3QgYmUgJ3htbCciKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzVmFsaWROQ05hbWUocGlOYW1lKSkKLSAgICB7Ci0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfUFJPQ0VTU0lOR0lOU1RSVUNUSU9OX05PVFZBTElEX05DTkFNRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcGlOYW1lIH0pOyAgLy8icHJvY2Vzc2luZy1pbnN0cnVjdGlvbiBuYW1lIG11c3QgYmUgYSB2YWxpZCBOQ05hbWU6ICIrcGlOYW1lKTsKLSAgICB9Ci0KLSAgICAvLyBOb3RlIHRoZSBjb250ZW50IG1vZGVsIGlzOgotICAgIC8vIDwhRU5USVRZICUgaW5zdHJ1Y3Rpb25zICIKLSAgICAvLyAlY2hhci1pbnN0cnVjdGlvbnM7Ci0gICAgLy8gfCB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbgotICAgIC8vIHwgeHNsOmNvbW1lbnQKLSAgICAvLyB8IHhzbDplbGVtZW50Ci0gICAgLy8gfCB4c2w6YXR0cmlidXRlCi0gICAgLy8gIj4KLSAgICBTdHJpbmcgZGF0YSA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVRvU3RyaW5nKHRoaXMpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgdHJhbnNmb3JtZXIuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKS5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24ocGlOYW1lLCBkYXRhKTsKLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIGNoaWxkIHRvIHRoZSBjaGlsZCBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYWRkIHRvIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHJldHVybiBUaGUgY2hpbGQganVzdCBhZGRlZCB0byB0aGUgY2hpbGQgbGlzdAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXBwZW5kQ2hpbGQoRWxlbVRlbXBsYXRlRWxlbWVudCBuZXdDaGlsZCkKLSAgewotCi0gICAgaW50IHR5cGUgPSAoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG5ld0NoaWxkKS5nZXRYU0xUb2tlbigpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLQotICAgIC8vIGNoYXItaW5zdHJ1Y3Rpb25zIAotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX1RFWFRMSVRFUkFMUkVTVUxUIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9BUFBMWV9URU1QTEFURVMgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0FQUExZX0lNUE9SVFMgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0NBTExURU1QTEFURSA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfRk9SRUFDSCA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfVkFMVUVPRiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQ09QWV9PRiA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfTlVNQkVSIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9DSE9PU0UgOgotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0lGIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9URVhUIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9DT1BZIDoKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9WQVJJQUJMRSA6Ci0gICAgY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfTUVTU0FHRSA6Ci0KLSAgICAgIC8vIGluc3RydWN0aW9ucyAKLSAgICAgIC8vIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX1BJOgotICAgICAgLy8gY2FzZSBDb25zdGFudHMuRUxFTU5BTUVfQ09NTUVOVDoKLSAgICAgIC8vIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX0VMRU1FTlQ6Ci0gICAgICAvLyBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9BVFRSSUJVVEU6Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfQURELAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuZXdDaGlsZC5nZXROb2RlTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldE5vZGVOYW1lKCkgfSk7ICAvLyJDYW4gbm90IGFkZCAiICsoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpbmV3Q2hpbGQpLm1fZWxlbU5hbWUgKwotCi0gICAgLy8iIHRvICIgKyB0aGlzLm1fZWxlbU5hbWUpOwotICAgIH0KLQotICAgIHJldHVybiBzdXBlci5hcHBlbmRDaGlsZChuZXdDaGlsZCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtUGFyYW0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtUGFyYW0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTMxMzJjZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVBhcmFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDpwYXJhbS4KLSAqIDxwcmU+Ci0gKiA8IUVMRU1FTlQgeHNsOnBhcmFtICV0ZW1wbGF0ZTs+Ci0gKiA8IUFUVExJU1QgeHNsOnBhcmFtCi0gKiAgIG5hbWUgJXFuYW1lOyAjUkVRVUlSRUQKLSAqICAgc2VsZWN0ICVleHByOyAjSU1QTElFRAotICogPgotICogPC9wcmU+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjdmFyaWFibGVzIj52YXJpYWJsZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbVBhcmFtIGV4dGVuZHMgRWxlbVZhcmlhYmxlCi17Ci0gIGludCBtX3FuYW1lSUQ7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEVsZW1QYXJhbQotICAgKgotICAgKi8KLSAgcHVibGljIEVsZW1QYXJhbSgpe30KLQotICAvKioKLSAgICogR2V0IGFuIGludCBjb25zdGFudCBpZGVudGlmeWluZyB0aGUgdHlwZSBvZiBlbGVtZW50LgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0b2tlbiBJRCBvZiB0aGUgZWxlbWVudAotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX1BBUkFNVkFSSUFCTEU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfUEFSQU1WQVJJQUJMRV9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBjb25zdHJ1Y3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHBhcmFtIEVsZW1lbnQgZnJvbSBhbiB4c2w6cGFyYW0KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1QYXJhbShFbGVtUGFyYW0gcGFyYW0pIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIocGFyYW0pOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICBtX3FuYW1lSUQgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKS5nZXRRTmFtZUlEKG1fcW5hbWUpOwotICAgIGlmKG1fcGFyZW50Tm9kZS5nZXRYU0xUb2tlbigpID09IENvbnN0YW50cy5FTEVNTkFNRV9URU1QTEFURSkKLSAgICAgICgoRWxlbVRlbXBsYXRlKW1fcGFyZW50Tm9kZSkubV9pbkFyZ3NTaXplKys7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBFeGVjdXRlIGEgdmFyaWFibGUgZGVjbGFyYXRpb24gYW5kIHB1c2ggaXQgb250byB0aGUgdmFyaWFibGUgc3RhY2suCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN2YXJpYWJsZXMiPnZhcmlhYmxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotICAgICAgCi0gICAgVmFyaWFibGVTdGFjayB2YXJzID0gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0VmFyU3RhY2soKTsKLSAgICAKLSAgICBpZighdmFycy5pc0xvY2FsU2V0KG1faW5kZXgpKQotICAgIHsKLQotICAgICAgaW50IHNvdXJjZU5vZGUgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgWE9iamVjdCB2YXIgPSBnZXRWYWx1ZSh0cmFuc2Zvcm1lciwgc291cmNlTm9kZSk7Ci0gIAotICAgICAgLy8gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0VmFyU3RhY2soKS5wdXNoVmFyaWFibGUobV9xbmFtZSwgdmFyKTsKLSAgICAgIHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldFZhclN0YWNrKCkuc2V0TG9jYWxWYXJpYWJsZShtX2luZGV4LCB2YXIpOwotICAgIH0KLSAgfQotICAKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtU29ydC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1Tb3J0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcyMmU1MzMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1Tb3J0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzODYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOnNvcnQuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDpzb3J0IEVNUFRZPgotICogPCFBVFRMSVNUIHhzbDpzb3J0Ci0gKiAgIHNlbGVjdCAlZXhwcjsgIi4iCi0gKiAgIGxhbmcgJWF2dDsgI0lNUExJRUQKLSAqICAgZGF0YS10eXBlICVhdnQ7ICJ0ZXh0IgotICogICBvcmRlciAlYXZ0OyAiYXNjZW5kaW5nIgotICogICBjYXNlLW9yZGVyICVhdnQ7ICNJTVBMSUVECi0gKiA+Ci0gKiA8IS0tIHhzbDpzb3J0IGNhbm5vdCBvY2N1ciBhZnRlciBhbnkgb3RoZXIgZWxlbWVudHMgb3IKLSAqIGFueSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIgLS0+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzb3J0aW5nIj5zb3J0aW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotcHVibGljIGNsYXNzIEVsZW1Tb3J0IGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiB4c2w6c29ydCBoYXMgYSBzZWxlY3QgYXR0cmlidXRlIHdob3NlIHZhbHVlIGlzIGFuIGV4cHJlc3Npb24uCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgWFBhdGggbV9zZWxlY3RFeHByZXNzaW9uID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuCi0gICAqIHhzbDpzb3J0IGhhcyBhIHNlbGVjdCBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgYW4gZXhwcmVzc2lvbi4KLSAgICogRm9yIGVhY2ggbm9kZSB0byBiZSBwcm9jZXNzZWQsIHRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZAotICAgKiB3aXRoIHRoYXQgbm9kZSBhcyB0aGUgY3VycmVudCBub2RlIGFuZCB3aXRoIHRoZSBjb21wbGV0ZQotICAgKiBsaXN0IG9mIG5vZGVzIGJlaW5nIHByb2Nlc3NlZCBpbiB1bnNvcnRlZCBvcmRlciBhcyB0aGUgY3VycmVudAotICAgKiBub2RlIGxpc3QuIFRoZSByZXN1bHRpbmcgb2JqZWN0IGlzIGNvbnZlcnRlZCB0byBhIHN0cmluZyBhcyBpZgotICAgKiBieSBhIGNhbGwgdG8gdGhlIHN0cmluZyBmdW5jdGlvbjsgdGhpcyBzdHJpbmcgaXMgdXNlZCBhcyB0aGUKLSAgICogc29ydCBrZXkgZm9yIHRoYXQgbm9kZS4gVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHNlbGVjdCBhdHRyaWJ1dGUKLSAgICogaXMgLiwgd2hpY2ggd2lsbCBjYXVzZSB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBjdXJyZW50IG5vZGUgdG8KLSAgICogYmUgdXNlZCBhcyB0aGUgc29ydCBrZXkuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U2VsZWN0KFhQYXRoIHYpCi0gIHsKLQotICAgIGlmICh2LmdldFBhdHRlcm5TdHJpbmcoKS5pbmRleE9mKCJ7IikgPCAwKQotICAgICAgbV9zZWxlY3RFeHByZXNzaW9uID0gdjsKLSAgICBlbHNlCi0gICAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fQ1VSTFlCUkFDRSwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuCi0gICAqIHhzbDpzb3J0IGhhcyBhIHNlbGVjdCBhdHRyaWJ1dGUgd2hvc2UgdmFsdWUgaXMgYW4gZXhwcmVzc2lvbi4KLSAgICogRm9yIGVhY2ggbm9kZSB0byBiZSBwcm9jZXNzZWQsIHRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZAotICAgKiB3aXRoIHRoYXQgbm9kZSBhcyB0aGUgY3VycmVudCBub2RlIGFuZCB3aXRoIHRoZSBjb21wbGV0ZQotICAgKiBsaXN0IG9mIG5vZGVzIGJlaW5nIHByb2Nlc3NlZCBpbiB1bnNvcnRlZCBvcmRlciBhcyB0aGUgY3VycmVudAotICAgKiBub2RlIGxpc3QuIFRoZSByZXN1bHRpbmcgb2JqZWN0IGlzIGNvbnZlcnRlZCB0byBhIHN0cmluZyBhcyBpZgotICAgKiBieSBhIGNhbGwgdG8gdGhlIHN0cmluZyBmdW5jdGlvbjsgdGhpcyBzdHJpbmcgaXMgdXNlZCBhcyB0aGUKLSAgICogc29ydCBrZXkgZm9yIHRoYXQgbm9kZS4gVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHNlbGVjdCBhdHRyaWJ1dGUKLSAgICogaXMgLiwgd2hpY2ggd2lsbCBjYXVzZSB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBjdXJyZW50IG5vZGUgdG8KLSAgICogYmUgdXNlZCBhcyB0aGUgc29ydCBrZXkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBYUGF0aCBnZXRTZWxlY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fc2VsZWN0RXhwcmVzc2lvbjsKLSAgfQotCi0gIC8qKgotICAgKiBsYW5nIHNwZWNpZmllcyB0aGUgbGFuZ3VhZ2Ugb2YgdGhlIHNvcnQga2V5cy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBBVlQgbV9sYW5nX2F2dCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImxhbmciIGF0dHJpYnV0ZS4KLSAgICogbGFuZyBzcGVjaWZpZXMgdGhlIGxhbmd1YWdlIG9mIHRoZSBzb3J0IGtleXM7IGl0IGhhcyB0aGUgc2FtZQotICAgKiByYW5nZSBvZiB2YWx1ZXMgYXMgeG1sOmxhbmcgW1hNTF07IGlmIG5vIGxhbmcgdmFsdWUgaXMKLSAgICogc3BlY2lmaWVkLCB0aGUgbGFuZ3VhZ2Ugc2hvdWxkIGJlIGRldGVybWluZWQgZnJvbSB0aGUgc3lzdGVtIGVudmlyb25tZW50LgotICAgKgotICAgKiBAcGFyYW0gdiBUaGUgdmFsdWUgdG8gc2V0IGZvciB0aGUgImxhbmciIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TGFuZyhBVlQgdikKLSAgewotICAgIG1fbGFuZ19hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImxhbmciIGF0dHJpYnV0ZS4KLSAgICogbGFuZyBzcGVjaWZpZXMgdGhlIGxhbmd1YWdlIG9mIHRoZSBzb3J0IGtleXM7IGl0IGhhcyB0aGUgc2FtZQotICAgKiByYW5nZSBvZiB2YWx1ZXMgYXMgeG1sOmxhbmcgW1hNTF07IGlmIG5vIGxhbmcgdmFsdWUgaXMKLSAgICogc3BlY2lmaWVkLCB0aGUgbGFuZ3VhZ2Ugc2hvdWxkIGJlIGRldGVybWluZWQgZnJvbSB0aGUgc3lzdGVtIGVudmlyb25tZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgImxhbmciIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEFWVCBnZXRMYW5nKCkKLSAgewotICAgIHJldHVybiBtX2xhbmdfYXZ0OwotICB9Ci0KLSAgLyoqCi0gICAqIGRhdGEtdHlwZSBzcGVjaWZpZXMgdGhlIGRhdGEgdHlwZSBvZiB0aGUKLSAgICogc3RyaW5ncyB0byBiZSBzb3J0ZWQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgQVZUIG1fZGF0YVR5cGVfYXZ0ID0gbnVsbDsKLQotICAvKioKLSAgICogU2V0IHRoZSAiZGF0YS10eXBlIiBhdHRyaWJ1dGUuCi0gICAqIDxjb2RlPmRhdGEtdHlwZTwvY29kZT4gc3BlY2lmaWVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlCi0gICAqIHN0cmluZ3M7IHRoZSBmb2xsb3dpbmcgdmFsdWVzIGFyZSBhbGxvd2VkOgotICAgKiA8dWw+Ci0gICAqIDxsaT4KLSAgICogPGNvZGU+dGV4dDwvY29kZT4gc3BlY2lmaWVzIHRoYXQgdGhlIHNvcnQga2V5cyBzaG91bGQgYmUKLSAgICogc29ydGVkIGxleGljb2dyYXBoaWNhbGx5IGluIHRoZSBjdWx0dXJhbGx5IGNvcnJlY3QgbWFubmVyIGZvciB0aGUKLSAgICogbGFuZ3VhZ2Ugc3BlY2lmaWVkIGJ5IDxjb2RlPmxhbmc8L2NvZGU+LgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqIDxjb2RlPm51bWJlcjwvY29kZT4gc3BlY2lmaWVzIHRoYXQgdGhlIHNvcnQga2V5cyBzaG91bGQgYmUKLSAgICogY29udmVydGVkIHRvIG51bWJlcnMgYW5kIHRoZW4gc29ydGVkIGFjY29yZGluZyB0byB0aGUgbnVtZXJpYyB2YWx1ZTsKLSAgICogdGhlIHNvcnQga2V5IGlzIGNvbnZlcnRlZCB0byBhIG51bWJlciBhcyBpZiBieSBhIGNhbGwgdG8gdGhlCi0gICAqIDxiPjxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2Z1bmN0aW9uLW51bWJlciI+bnVtYmVyPC9hPjwvYj4gZnVuY3Rpb247IHRoZSA8Y29kZT5sYW5nPC9jb2RlPgotICAgKiBhdHRyaWJ1dGUgaXMgaWdub3JlZC4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiBBIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMjTlQtUU5hbWUiPlFOYW1lPC9hPiB3aXRoIGEgcHJlZml4Ci0gICAqIGlzIGV4cGFuZGVkIGludG8gYW4gPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZHQtZXhwYW5kZWQtbmFtZSI+ZXhwYW5kZWQtbmFtZTwvYT4gYXMgZGVzY3JpYmVkCi0gICAqIGluIDxhIGhyZWY9IiNxbmFtZSI+WzxiPjIuNCBRdWFsaWZpZWQgTmFtZXM8L2I+XTwvYT47IHRoZSBleHBhbmRlZC1uYW1lIGlkZW50aWZpZXMgdGhlIGRhdGEtdHlwZTsKLSAgICogdGhlIGJlaGF2aW9yIGluIHRoaXMgY2FzZSBpcyBub3Qgc3BlY2lmaWVkIGJ5IHRoaXMgZG9jdW1lbnQuCi0gICAqIDwvbGk+Ci0gICAqIDwvdWw+Ci0gICAqIDxwPlRoZSBkZWZhdWx0IHZhbHVlIGlzIDxjb2RlPnRleHQ8L2NvZGU+LjwvcD4KLSAgICogPGJsb2NrcXVvdGU+Ci0gICAqIDxiPk5PVEU6IDwvYj5UaGUgWFNMIFdvcmtpbmcgR3JvdXAgcGxhbnMgdGhhdCBmdXR1cmUgdmVyc2lvbnMgb2YgWFNMVCB3aWxsCi0gICAqIGxldmVyYWdlIFhNTCBTY2hlbWFzIHRvIGRlZmluZSBmdXJ0aGVyIHZhbHVlcyBmb3IgdGhpcwotICAgKiBhdHRyaWJ1dGUuPC9ibG9ja3F1b3RlPgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yIHRoZSAiZGF0YS10eXBlIiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERhdGFUeXBlKEFWVCB2KQotICB7Ci0gICAgbV9kYXRhVHlwZV9hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImRhdGEtdHlwZSIgYXR0cmlidXRlLgotICAgKiA8Y29kZT5kYXRhLXR5cGU8L2NvZGU+IHNwZWNpZmllcyB0aGUgZGF0YSB0eXBlIG9mIHRoZQotICAgKiBzdHJpbmdzOyB0aGUgZm9sbG93aW5nIHZhbHVlcyBhcmUgYWxsb3dlZDoKLSAgICogPHVsPgotICAgKiA8bGk+Ci0gICAqIDxjb2RlPnRleHQ8L2NvZGU+IHNwZWNpZmllcyB0aGF0IHRoZSBzb3J0IGtleXMgc2hvdWxkIGJlCi0gICAqIHNvcnRlZCBsZXhpY29ncmFwaGljYWxseSBpbiB0aGUgY3VsdHVyYWxseSBjb3JyZWN0IG1hbm5lciBmb3IgdGhlCi0gICAqIGxhbmd1YWdlIHNwZWNpZmllZCBieSA8Y29kZT5sYW5nPC9jb2RlPi4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiA8Y29kZT5udW1iZXI8L2NvZGU+IHNwZWNpZmllcyB0aGF0IHRoZSBzb3J0IGtleXMgc2hvdWxkIGJlCi0gICAqIGNvbnZlcnRlZCB0byBudW1iZXJzIGFuZCB0aGVuIHNvcnRlZCBhY2NvcmRpbmcgdG8gdGhlIG51bWVyaWMgdmFsdWU7Ci0gICAqIHRoZSBzb3J0IGtleSBpcyBjb252ZXJ0ZWQgdG8gYSBudW1iZXIgYXMgaWYgYnkgYSBjYWxsIHRvIHRoZQotICAgKiA8Yj48YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNmdW5jdGlvbi1udW1iZXIiPm51bWJlcjwvYT48L2I+IGZ1bmN0aW9uOyB0aGUgPGNvZGU+bGFuZzwvY29kZT4KLSAgICogYXR0cmlidXRlIGlzIGlnbm9yZWQuCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogQSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzI05ULVFOYW1lIj5RTmFtZTwvYT4gd2l0aCBhIHByZWZpeAotICAgKiBpcyBleHBhbmRlZCBpbnRvIGFuIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2R0LWV4cGFuZGVkLW5hbWUiPmV4cGFuZGVkLW5hbWU8L2E+IGFzIGRlc2NyaWJlZAotICAgKiBpbiA8YSBocmVmPSIjcW5hbWUiPls8Yj4yLjQgUXVhbGlmaWVkIE5hbWVzPC9iPl08L2E+OyB0aGUgZXhwYW5kZWQtbmFtZSBpZGVudGlmaWVzIHRoZSBkYXRhLXR5cGU7Ci0gICAqIHRoZSBiZWhhdmlvciBpbiB0aGlzIGNhc2UgaXMgbm90IHNwZWNpZmllZCBieSB0aGlzIGRvY3VtZW50LgotICAgKiA8L2xpPgotICAgKiA8L3VsPgotICAgKiA8cD5UaGUgZGVmYXVsdCB2YWx1ZSBpcyA8Y29kZT50ZXh0PC9jb2RlPi48L3A+Ci0gICAqIDxibG9ja3F1b3RlPgotICAgKiA8Yj5OT1RFOiA8L2I+VGhlIFhTTCBXb3JraW5nIEdyb3VwIHBsYW5zIHRoYXQgZnV0dXJlIHZlcnNpb25zIG9mIFhTTFQgd2lsbAotICAgKiBsZXZlcmFnZSBYTUwgU2NoZW1hcyB0byBkZWZpbmUgZnVydGhlciB2YWx1ZXMgZm9yIHRoaXMKLSAgICogYXR0cmlidXRlLjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlICJkYXRhLXR5cGUiIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEFWVCBnZXREYXRhVHlwZSgpCi0gIHsKLSAgICByZXR1cm4gbV9kYXRhVHlwZV9hdnQ7Ci0gIH0KLQotICAvKioKLSAgICogb3JkZXIgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIHN0cmluZ3Mgc2hvdWxkIGJlIHNvcnRlZCBpbiBhc2NlbmRpbmcKLSAgICogb3IgZGVzY2VuZGluZyBvcmRlci4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBBVlQgbV9vcmRlcl9hdnQgPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJvcmRlciIgYXR0cmlidXRlLgotICAgKiBvcmRlciBzcGVjaWZpZXMgd2hldGhlciB0aGUgc3RyaW5ncyBzaG91bGQgYmUgc29ydGVkIGluIGFzY2VuZGluZwotICAgKiBvciBkZXNjZW5kaW5nIG9yZGVyOyBhc2NlbmRpbmcgc3BlY2lmaWVzIGFzY2VuZGluZyBvcmRlcjsgZGVzY2VuZGluZwotICAgKiBzcGVjaWZpZXMgZGVzY2VuZGluZyBvcmRlcjsgdGhlIGRlZmF1bHQgaXMgYXNjZW5kaW5nLgotICAgKgotICAgKiBAcGFyYW0gdiBUaGUgdmFsdWUgdG8gc2V0IGZvciB0aGUgIm9yZGVyIiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE9yZGVyKEFWVCB2KQotICB7Ci0gICAgbV9vcmRlcl9hdnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm9yZGVyIiBhdHRyaWJ1dGUuCi0gICAqIG9yZGVyIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBzdHJpbmdzIHNob3VsZCBiZSBzb3J0ZWQgaW4gYXNjZW5kaW5nCi0gICAqIG9yIGRlc2NlbmRpbmcgb3JkZXI7IGFzY2VuZGluZyBzcGVjaWZpZXMgYXNjZW5kaW5nIG9yZGVyOyBkZXNjZW5kaW5nCi0gICAqIHNwZWNpZmllcyBkZXNjZW5kaW5nIG9yZGVyOyB0aGUgZGVmYXVsdCBpcyBhc2NlbmRpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSAib3JkZXIiIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEFWVCBnZXRPcmRlcigpCi0gIHsKLSAgICByZXR1cm4gbV9vcmRlcl9hdnQ7Ci0gIH0KLQotICAvKioKLSAgICogY2FzZS1vcmRlciBoYXMgdGhlIHZhbHVlIHVwcGVyLWZpcnN0IG9yIGxvd2VyLWZpcnN0LgotICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBsYW5ndWFnZSBkZXBlbmRlbnQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgQVZUIG1fY2FzZW9yZGVyX2F2dCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImNhc2Utb3JkZXIiIGF0dHJpYnV0ZS4KLSAgICogY2FzZS1vcmRlciBoYXMgdGhlIHZhbHVlIHVwcGVyLWZpcnN0IG9yIGxvd2VyLWZpcnN0OyB0aGlzIGFwcGxpZXMKLSAgICogd2hlbiBkYXRhLXR5cGU9InRleHQiLCBhbmQgc3BlY2lmaWVzIHRoYXQgdXBwZXItY2FzZSBsZXR0ZXJzIHNob3VsZAotICAgKiBzb3J0IGJlZm9yZSBsb3dlci1jYXNlIGxldHRlcnMgb3IgdmljZS12ZXJzYSByZXNwZWN0aXZlbHkuCi0gICAqIEZvciBleGFtcGxlLCBpZiBsYW5nPSJlbiIsIHRoZW4gQSBhIEIgYiBhcmUgc29ydGVkIHdpdGgKLSAgICogY2FzZS1vcmRlcj0idXBwZXItZmlyc3QiIGFuZCBhIEEgYiBCIGFyZSBzb3J0ZWQgd2l0aCBjYXNlLW9yZGVyPSJsb3dlci1maXJzdCIuCi0gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGxhbmd1YWdlIGRlcGVuZGVudC4KLSAgICoKLSAgICogQHBhcmFtIHYgVGhlIHZhbHVlIHRvIHNldCBmb3IgdGhlICJjYXNlLW9yZGVyIiBhdHRyaWJ1dGUKLSAgICogCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENhc2VPcmRlcihBVlQgdikKLSAgewotICAgIG1fY2FzZW9yZGVyX2F2dCA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAiY2FzZS1vcmRlciIgYXR0cmlidXRlLgotICAgKiBjYXNlLW9yZGVyIGhhcyB0aGUgdmFsdWUgdXBwZXItZmlyc3Qgb3IgbG93ZXItZmlyc3Q7IHRoaXMgYXBwbGllcwotICAgKiB3aGVuIGRhdGEtdHlwZT0idGV4dCIsIGFuZCBzcGVjaWZpZXMgdGhhdCB1cHBlci1jYXNlIGxldHRlcnMgc2hvdWxkCi0gICAqIHNvcnQgYmVmb3JlIGxvd2VyLWNhc2UgbGV0dGVycyBvciB2aWNlLXZlcnNhIHJlc3BlY3RpdmVseS4KLSAgICogRm9yIGV4YW1wbGUsIGlmIGxhbmc9ImVuIiwgdGhlbiBBIGEgQiBiIGFyZSBzb3J0ZWQgd2l0aAotICAgKiBjYXNlLW9yZGVyPSJ1cHBlci1maXJzdCIgYW5kIGEgQSBiIEIgYXJlIHNvcnRlZCB3aXRoIGNhc2Utb3JkZXI9Imxvd2VyLWZpcnN0Ii4KLSAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgbGFuZ3VhZ2UgZGVwZW5kZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgImNhc2Utb3JkZXIiIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIEFWVCBnZXRDYXNlT3JkZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fY2FzZW9yZGVyX2F2dDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50IGNvbnN0YW50IGlkZW50aWZ5aW5nIHRoZSB0eXBlIG9mIGVsZW1lbnQuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRva2VuIElEIG9mIHRoZSBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfU09SVDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZWxlbWVudCdzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9TT1JUX1NUUklORzsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIENoaWxkIHRvIGFkZCB0byB0aGUgY2hpbGQgbGlzdAotICAgKgotICAgKiBAcmV0dXJuIENoaWxkIGp1c3QgYWRkZWQgdG8gdGhlIGNoaWxkIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlIGFwcGVuZENoaWxkKE5vZGUgbmV3Q2hpbGQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9BREQsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBuZXdDaGlsZC5nZXROb2RlTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXROb2RlTmFtZSgpIH0pOyAgLy8iQ2FuIG5vdCBhZGQgIiArKChFbGVtVGVtcGxhdGVFbGVtZW50KW5ld0NoaWxkKS5tX2VsZW1OYW1lICsKLQotICAgIC8vIiB0byAiICsgdGhpcy5tX2VsZW1OYW1lKTsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotICAgIFN0eWxlc2hlZXRSb290LkNvbXBvc2VTdGF0ZSBjc3RhdGUgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKTsKLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IGNzdGF0ZS5nZXRWYXJpYWJsZU5hbWVzKCk7Ci0gICAgaWYobnVsbCAhPSBtX2Nhc2VvcmRlcl9hdnQpCi0gICAgICBtX2Nhc2VvcmRlcl9hdnQuZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgaWYobnVsbCAhPSBtX2RhdGFUeXBlX2F2dCkKLSAgICAgIG1fZGF0YVR5cGVfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV9sYW5nX2F2dCkKLSAgICAgIG1fbGFuZ19hdnQuZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgaWYobnVsbCAhPSBtX29yZGVyX2F2dCkKLSAgICAgIG1fb3JkZXJfYXZ0LmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV9zZWxlY3RFeHByZXNzaW9uKQotICAgICAgbV9zZWxlY3RFeHByZXNzaW9uLmZpeHVwVmFyaWFibGVzKHZuYW1lcywgY3N0YXRlLmdldEdsb2JhbHNTaXplKCkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRlbXBsYXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRlbXBsYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlkYTQwOWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1UZW1wbGF0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOnRlbXBsYXRlLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6dGVtcGxhdGUKLSAqICAoI1BDREFUQQotICogICAlaW5zdHJ1Y3Rpb25zOwotICogICAlcmVzdWx0LWVsZW1lbnRzOwotICogICB8IHhzbDpwYXJhbSkKLSAqID4KLSAqCi0gKiA8IUFUVExJU1QgeHNsOnRlbXBsYXRlCi0gKiAgIG1hdGNoICVwYXR0ZXJuOyAjSU1QTElFRAotICogICBuYW1lICVxbmFtZTsgI0lNUExJRUQKLSAqICAgcHJpb3JpdHkgJXByaW9yaXR5OyAjSU1QTElFRAotICogICBtb2RlICVxbmFtZTsgI0lNUExJRUQKLSAqICAgJXNwYWNlLWF0dDsKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tRGVmaW5pbmctVGVtcGxhdGUtUnVsZXMiPnNlY3Rpb24tRGVmaW5pbmctVGVtcGxhdGUtUnVsZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbVRlbXBsYXRlIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKiBUaGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX3B1YmxpY0lkOwotCi0gIC8qKiBUaGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX3N5c3RlbUlkOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudC4KLSAgICogPHA+VGhpcyB3aWxsIGJlIHRoZSBwdWJsaWMgaWRlbnRpZmllcgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvcgotICAgKiAgICAgICAgIG51bGwgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkKLSAgewotICAgIHJldHVybiBtX3B1YmxpY0lkOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgotICAgKgotICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBwYXJzZXIgbXVzdCByZXNvbHZlIGl0Ci0gICAqIGZ1bGx5IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwKLSAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHNlZSAjZ2V0UHVibGljSWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKQotICB7Ci0gICAgcmV0dXJuIG1fc3lzdGVtSWQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBmb3IgdGhpcyBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBTb3VyY2VMb2NhdG9yIGhvbGRpbmcgbG9jYXRpb24gaW5mb3JtYXRpb24gCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMb2NhdGVySW5mbyhTb3VyY2VMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLQotICAgIG1fcHVibGljSWQgPSBsb2NhdG9yLmdldFB1YmxpY0lkKCk7Ci0gICAgbV9zeXN0ZW1JZCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLQotICAgIHN1cGVyLnNldExvY2F0ZXJJbmZvKGxvY2F0b3IpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBvd25pbmcgc3R5bGVzaGVldC4KLSAgICogKFNob3VsZCB0aGlzIG9ubHkgYmUgcHV0IG9uIHRoZSB0ZW1wbGF0ZSBlbGVtZW50LCB0bwotICAgKiBjb25zZXJ2ZSBzcGFjZT8pCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3R5bGVzaGVldCBtX3N0eWxlc2hlZXQ7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3R5bGVzaGVldCBjb21wb3NlZCAocmVzb2x2ZXMgaW5jbHVkZXMgYW5kCi0gICAqIGltcG9ydHMgYW5kIGhhcyBtZXRob2RzIG9uIGl0IHRoYXQgcmV0dXJuICJjb21wb3NlZCIgcHJvcGVydGllcy4KLSAgICogCi0gICAqIEByZXR1cm4gVGhlIHN0eWxlc2hlZXQgY29tcG9zZWQuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldENvbXBvc2VkIGdldFN0eWxlc2hlZXRDb21wb3NlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZXNoZWV0LmdldFN0eWxlc2hlZXRDb21wb3NlZCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3duaW5nIHN0eWxlc2hlZXQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG93bmluZyBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXQgZ2V0U3R5bGVzaGVldCgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZXNoZWV0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgb3duaW5nIHN0eWxlc2hlZXQuCi0gICAqCi0gICAqIEBwYXJhbSBzaGVldCBUaGUgb3duaW5nIHN0eWxlc2hlZXQgZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3R5bGVzaGVldChTdHlsZXNoZWV0IHNoZWV0KQotICB7Ci0gICAgbV9zdHlsZXNoZWV0ID0gc2hlZXQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSByb290IHN0eWxlc2hlZXQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJvb3Qgc3R5bGVzaGVldCBmb3IgdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldFJvb3QgZ2V0U3R5bGVzaGVldFJvb3QoKQotICB7Ci0gICAgcmV0dXJuIG1fc3R5bGVzaGVldC5nZXRTdHlsZXNoZWV0Um9vdCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBhdHRyaWJ1dGUgaXMgYSBQYXR0ZXJuIHRoYXQgaWRlbnRpZmllcyB0aGUgc291cmNlCi0gICAqIG5vZGUgb3Igbm9kZXMgdG8gd2hpY2ggdGhlIHJ1bGUgYXBwbGllcy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX21hdGNoUGF0dGVybiA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm1hdGNoIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBtYXRjaCBhdHRyaWJ1dGUgaXMgYSBQYXR0ZXJuIHRoYXQgaWRlbnRpZmllcyB0aGUgc291cmNlCi0gICAqIG5vZGUgb3Igbm9kZXMgdG8gd2hpY2ggdGhlIHJ1bGUgYXBwbGllcy4gVGhlIG1hdGNoIGF0dHJpYnV0ZQotICAgKiBpcyByZXF1aXJlZCB1bmxlc3MgdGhlIHhzbDp0ZW1wbGF0ZSBlbGVtZW50IGhhcyBhIG5hbWUKLSAgICogYXR0cmlidXRlIChzZWUgWzYgTmFtZWQgVGVtcGxhdGVzXSkuIEl0IGlzIGFuIGVycm9yIGZvciB0aGUKLSAgICogdmFsdWUgb2YgdGhlIG1hdGNoIGF0dHJpYnV0ZSB0byBjb250YWluIGEgVmFyaWFibGVSZWZlcmVuY2UuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNwYXR0ZXJucyI+cGF0dGVybnMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yIHRoZSAibWF0Y2giIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TWF0Y2goWFBhdGggdikKLSAgewotICAgIG1fbWF0Y2hQYXR0ZXJuID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJtYXRjaCIgYXR0cmlidXRlLgotICAgKiBUaGUgbWF0Y2ggYXR0cmlidXRlIGlzIGEgUGF0dGVybiB0aGF0IGlkZW50aWZpZXMgdGhlIHNvdXJjZQotICAgKiBub2RlIG9yIG5vZGVzIHRvIHdoaWNoIHRoZSBydWxlIGFwcGxpZXMuIFRoZSBtYXRjaCBhdHRyaWJ1dGUKLSAgICogaXMgcmVxdWlyZWQgdW5sZXNzIHRoZSB4c2w6dGVtcGxhdGUgZWxlbWVudCBoYXMgYSBuYW1lCi0gICAqIGF0dHJpYnV0ZSAoc2VlIFs2IE5hbWVkIFRlbXBsYXRlc10pLiBJdCBpcyBhbiBlcnJvciBmb3IgdGhlCi0gICAqIHZhbHVlIG9mIHRoZSBtYXRjaCBhdHRyaWJ1dGUgdG8gY29udGFpbiBhIFZhcmlhYmxlUmVmZXJlbmNlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjcGF0dGVybnMiPnBhdHRlcm5zIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiB0aGUgIm1hdGNoIiBhdHRyaWJ1dGUgCi0gICAqLwotICBwdWJsaWMgWFBhdGggZ2V0TWF0Y2goKQotICB7Ci0gICAgcmV0dXJuIG1fbWF0Y2hQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIEFuIHhzbDp0ZW1wbGF0ZSBlbGVtZW50IHdpdGggYSBuYW1lIGF0dHJpYnV0ZSBzcGVjaWZpZXMgYSBuYW1lZCB0ZW1wbGF0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBRTmFtZSBtX25hbWUgPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqIEFuIHhzbDp0ZW1wbGF0ZSBlbGVtZW50IHdpdGggYSBuYW1lIGF0dHJpYnV0ZSBzcGVjaWZpZXMgYSBuYW1lZCB0ZW1wbGF0ZS4KLSAgICogSWYgYW4geHNsOnRlbXBsYXRlIGVsZW1lbnQgaGFzIGEgbmFtZSBhdHRyaWJ1dGUsIGl0IG1heSwgYnV0IG5lZWQgbm90LAotICAgKiBhbHNvIGhhdmUgYSBtYXRjaCBhdHRyaWJ1dGUuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNuYW1lZC10ZW1wbGF0ZXMiPm5hbWVkLXRlbXBsYXRlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TmFtZShRTmFtZSB2KQotICB7Ci0gICAgbV9uYW1lID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqIEFuIHhzbDp0ZW1wbGF0ZSBlbGVtZW50IHdpdGggYSBuYW1lIGF0dHJpYnV0ZSBzcGVjaWZpZXMgYSBuYW1lZCB0ZW1wbGF0ZS4KLSAgICogSWYgYW4geHNsOnRlbXBsYXRlIGVsZW1lbnQgaGFzIGEgbmFtZSBhdHRyaWJ1dGUsIGl0IG1heSwgYnV0IG5lZWQgbm90LAotICAgKiBhbHNvIGhhdmUgYSBtYXRjaCBhdHRyaWJ1dGUuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNuYW1lZC10ZW1wbGF0ZXMiPm5hbWVkLXRlbXBsYXRlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgdGhlICJuYW1lIiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBRTmFtZSBnZXROYW1lKCkKLSAgewotICAgIHJldHVybiBtX25hbWU7Ci0gIH0KLQotICAvKioKLSAgICogTW9kZXMgYWxsb3cgYW4gZWxlbWVudCB0byBiZSBwcm9jZXNzZWQgbXVsdGlwbGUgdGltZXMsCi0gICAqIGVhY2ggdGltZSBwcm9kdWNpbmcgYSBkaWZmZXJlbnQgcmVzdWx0LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFFOYW1lIG1fbW9kZTsKLQotICAvKioKLSAgICogU2V0IHRoZSAibW9kZSIgYXR0cmlidXRlLgotICAgKiBNb2RlcyBhbGxvdyBhbiBlbGVtZW50IHRvIGJlIHByb2Nlc3NlZCBtdWx0aXBsZSB0aW1lcywKLSAgICogZWFjaCB0aW1lIHByb2R1Y2luZyBhIGRpZmZlcmVudCByZXN1bHQuICBJZiB4c2w6dGVtcGxhdGUKLSAgICogZG9lcyBub3QgaGF2ZSBhIG1hdGNoIGF0dHJpYnV0ZSwgaXQgbXVzdCBub3QgaGF2ZSBhIG1vZGUgYXR0cmlidXRlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPm1vZGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IHRoZSAibW9kZSIgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNb2RlKFFOYW1lIHYpCi0gIHsKLSAgICBtX21vZGUgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm1vZGUiIGF0dHJpYnV0ZS4KLSAgICogTW9kZXMgYWxsb3cgYW4gZWxlbWVudCB0byBiZSBwcm9jZXNzZWQgbXVsdGlwbGUgdGltZXMsCi0gICAqIGVhY2ggdGltZSBwcm9kdWNpbmcgYSBkaWZmZXJlbnQgcmVzdWx0LiAgSWYgeHNsOnRlbXBsYXRlCi0gICAqIGRvZXMgbm90IGhhdmUgYSBtYXRjaCBhdHRyaWJ1dGUsIGl0IG11c3Qgbm90IGhhdmUgYSBtb2RlIGF0dHJpYnV0ZS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5tb2RlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgdGhlICJtb2RlIiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBRTmFtZSBnZXRNb2RlKCkKLSAgewotICAgIHJldHVybiBtX21vZGU7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHByaW9yaXR5IG9mIGEgdGVtcGxhdGUgcnVsZSBpcyBzcGVjaWZpZWQgYnkgdGhlIHByaW9yaXR5Ci0gICAqIGF0dHJpYnV0ZSBvbiB0aGUgdGVtcGxhdGUgcnVsZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBkb3VibGUgbV9wcmlvcml0eSA9IFhQYXRoLk1BVENIX1NDT1JFX05PTkU7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInByaW9yaXR5IiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBwcmlvcml0eSBvZiBhIHRlbXBsYXRlIHJ1bGUgaXMgc3BlY2lmaWVkIGJ5IHRoZSBwcmlvcml0eQotICAgKiBhdHRyaWJ1dGUgb24gdGhlIHRlbXBsYXRlIHJ1bGUuIFRoZSB2YWx1ZSBvZiB0aGlzIG11c3QgYmUgYQotICAgKiByZWFsIG51bWJlciAocG9zaXRpdmUgb3IgbmVnYXRpdmUpLCBtYXRjaGluZyB0aGUgcHJvZHVjdGlvbgotICAgKiBOdW1iZXIgd2l0aCBhbiBvcHRpb25hbCBsZWFkaW5nIG1pbnVzIHNpZ24gKC0pLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPmNvbmZsaWN0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVGhlIHZhbHVlIHRvIHNldCBmb3IgdGhlICJwcmlvcml0eSIgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcmlvcml0eShkb3VibGUgdikKLSAgewotICAgIG1fcHJpb3JpdHkgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgInByaW9yaXR5IiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBwcmlvcml0eSBvZiBhIHRlbXBsYXRlIHJ1bGUgaXMgc3BlY2lmaWVkIGJ5IHRoZSBwcmlvcml0eQotICAgKiBhdHRyaWJ1dGUgb24gdGhlIHRlbXBsYXRlIHJ1bGUuIFRoZSB2YWx1ZSBvZiB0aGlzIG11c3QgYmUgYQotICAgKiByZWFsIG51bWJlciAocG9zaXRpdmUgb3IgbmVnYXRpdmUpLCBtYXRjaGluZyB0aGUgcHJvZHVjdGlvbgotICAgKiBOdW1iZXIgd2l0aCBhbiBvcHRpb25hbCBsZWFkaW5nIG1pbnVzIHNpZ24gKC0pLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPmNvbmZsaWN0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlICJwcmlvcml0eSIgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgZG91YmxlIGdldFByaW9yaXR5KCkKLSAgewotICAgIHJldHVybiBtX3ByaW9yaXR5OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnQgY29uc3RhbnQgaWRlbnRpZnlpbmcgdGhlIHR5cGUgb2YgZWxlbWVudC4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5Db25zdGFudHMKLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4gSUQgZm9yIHRoZSBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfVEVNUExBVEU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfVEVNUExBVEVfU1RSSU5HOwotICB9Ci0gIAotICAvKioKLSAgICogVGhlIHN0YWNrIGZyYW1lIHNpemUgZm9yIHRoaXMgdGVtcGxhdGUsIHdoaWNoIGlzIGVxdWFsIHRvIHRoZSBtYXhpbXVtIG51bWJlciAKLSAgICogb2YgcGFyYW1zIGFuZCB2YXJpYWJsZXMgdGhhdCBjYW4gYmUgZGVjbGFyZWQgaW4gdGhlIHRlbXBsYXRlIGF0IG9uZSB0aW1lLgotICAgKi8KLSAgcHVibGljIGludCBtX2ZyYW1lU2l6ZTsKLSAgCi0gIC8qKgotICAgKiBUaGUgc2l6ZSBvZiB0aGUgcG9ydGlvbiBvZiB0aGUgc3RhY2sgZnJhbWUgdGhhdCBjYW4gaG9sZCBwYXJhbWV0ZXIgCi0gICAqIGFyZ3VtZW50cy4KLSAgICovCi0gIGludCBtX2luQXJnc1NpemU7Ci0gIAotICAvKioKLSAgICogTGlzdCBvZiBuYW1lc3BhY2UvbG9jYWwtbmFtZSBwYWlycywgRFRNIHN0eWxlLCB0aGF0IGFyZSB1bmlxdWUgCi0gICAqIHFuYW1lIGlkZW50aWZpZXJzIGZvciB0aGUgYXJndW1lbnRzLiAgVGhlIHBvc2l0aW9uIG9mIGEgZ2l2ZW4gcW5hbWUgCi0gICAqIGluIHRoZSBsaXN0IGlzIHRoZSBhcmd1bWVudCBJRCwgYW5kIHRodXMgdGhlIHBvc2l0aW9uIGluIHRoZSBzdGFjawotICAgKiBmcmFtZS4KLSAgICovCi0gIHByaXZhdGUgaW50W10gbV9hcmdzUU5hbWVJRHM7Ci0gIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgZXZlcnl0aGluZyBlbHNlIGhhcyBiZWVuCi0gICAqIHJlY29tcG9zZWQsIGFuZCBhbGxvd3MgdGhlIHRlbXBsYXRlIHRvIHNldCByZW1haW5pbmcKLSAgICogdmFsdWVzIHRoYXQgbWF5IGJlIGJhc2VkIG9uIHNvbWUgb3RoZXIgcHJvcGVydHkgdGhhdAotICAgKiBkZXBlbmRzIG9uIHJlY29tcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21wb3NlKFN0eWxlc2hlZXRSb290IHNyb290KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotICAgIFN0eWxlc2hlZXRSb290LkNvbXBvc2VTdGF0ZSBjc3RhdGUgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKTsKLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IGNzdGF0ZS5nZXRWYXJpYWJsZU5hbWVzKCk7Ci0gICAgaWYobnVsbCAhPSBtX21hdGNoUGF0dGVybikKLSAgICAgIG1fbWF0Y2hQYXR0ZXJuLmZpeHVwVmFyaWFibGVzKHZuYW1lcywgc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCkuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgICAKLSAgICBjc3RhdGUucmVzZXRTdGFja0ZyYW1lU2l6ZSgpOwotICAgIG1faW5BcmdzU2l6ZSA9IDA7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGFmdGVyIHRoZSB0ZW1wbGF0ZSdzIGNoaWxkcmVuIGhhdmUgYmVlbiBjb21wb3NlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZENvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgU3R5bGVzaGVldFJvb3QuQ29tcG9zZVN0YXRlIGNzdGF0ZSA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpOwotICAgIHN1cGVyLmVuZENvbXBvc2Uoc3Jvb3QpOwotICAgIG1fZnJhbWVTaXplID0gY3N0YXRlLmdldEZyYW1lU2l6ZSgpOwotICAgIAotICAgIGNzdGF0ZS5yZXNldFN0YWNrRnJhbWVTaXplKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29weSB0aGUgdGVtcGxhdGUgY29udGVudHMgaW50byB0aGUgcmVzdWx0IHRyZWUuCi0gICAqIFRoZSBjb250ZW50IG9mIHRoZSB4c2w6dGVtcGxhdGUgZWxlbWVudCBpcyB0aGUgdGVtcGxhdGUKLSAgICogdGhhdCBpcyBpbnN0YW50aWF0ZWQgd2hlbiB0aGUgdGVtcGxhdGUgcnVsZSBpcyBhcHBsaWVkLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICAgIC8vICVSRVZJRVclIGNvbW1lbnRpbmcgb3V0IG9mIHRoZSBjb2RlIGJlbG93LgotLy8gICAgaWYgKG51bGwgIT0gc291cmNlTm9kZSkKLS8vICAgIHsKLSAgICAgIHRyYW5zZm9ybWVyLmV4ZWN1dGVDaGlsZFRlbXBsYXRlcyh0aGlzLCB0cnVlKTsKLS8vICAgIH0KLS8vICAgIGVsc2UgIC8vIGlmKG51bGwgPT0gc291cmNlTm9kZSkKLS8vICAgIHsKLS8vICAgICAgdHJhbnNmb3JtZXIuZ2V0TXNnTWdyKCkuZXJyb3IodGhpcywKLS8vICAgICAgICB0aGlzLCBzb3VyY2VOb2RlLAotLy8gICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9OVUxMX1NPVVJDRU5PREVfSEFORExFQVBQTFlURU1QTEFURVMpOwotLy8KLS8vICAgICAgLy8ic291cmNlTm9kZSBpcyBudWxsIGluIGhhbmRsZUFwcGx5VGVtcGxhdGVzSW5zdHJ1Y3Rpb24hIik7Ci0vLyAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZHVyaW5nIHJlY29tcG9zaXRpb24gdG8KLSAgICogY29udHJvbCBob3cgdGhpcyBlbGVtZW50IGlzIGNvbXBvc2VkLgotICAgKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCBzdHlsZXNoZWV0IGZvciB0aGlzIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVjb21wb3NlKFN0eWxlc2hlZXRSb290IHJvb3QpCi0gIHsKLSAgICByb290LnJlY29tcG9zZVRlbXBsYXRlcyh0aGlzKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRlbXBsYXRlRWxlbWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1UZW1wbGF0ZUVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmUwNWI5ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRlbXBsYXRlRWxlbWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ2NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IGphdmEubGFuZy5JbnN0YW50aWF0aW9uRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLy8gWGFsYW4gaW1wb3J0cwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlVuSW1wbE5vZGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTmFtZVNwYWNlOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ1RvU3RyaW5nVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0TmFtZVNwYWNlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5WYXJpYWJsZVN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguV2hpdGVzcGFjZVN0cmlwcGluZ0VsZW1lbnRNYXRjaGVyOwotCi0vLyBUUmFYIGltcG9ydHMKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLS8vIERPTSBJbXBvcnRzCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotLy8gU0FYIEltcG9ydHMKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLk5hbWVzcGFjZVN1cHBvcnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTmFtZXNwYWNlU3VwcG9ydDI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gZWxlbWVudCBpbnNpZGUKLSAqIGFuIHhzbDp0ZW1wbGF0ZSBjbGFzcy4gIEl0IGhhcyBhIHNpbmdsZSAiZXhlY3V0ZSIgbWV0aG9kCi0gKiB3aGljaCBpcyBleHBlY3RlZCB0byBwZXJmb3JtIHRoZSBnaXZlbiBhY3Rpb24gb24gdGhlCi0gKiByZXN1bHQgdHJlZS4KLSAqIFRoaXMgY2xhc3MgYWN0cyBsaWtlIGEgRWxlbWVudCBub2RlLCBhbmQgaW1wbGVtZW50cyB0aGUKLSAqIEVsZW1lbnQgaW50ZXJmYWNlLCBidXQgaXMgbm90IGEgZnVsbCBpbXBsZW1lbnRhdGlvbgotICogb2YgdGhhdCBpbnRlcmZhY2UuLi4gaXQgb25seSBpbXBsZW1lbnRzIGVub3VnaCBmb3IKLSAqIGJhc2ljIHRyYXZlcnNhbCBvZiB0aGUgdHJlZS4KLSAqCi0gKiBAc2VlIFN0eWxlc2hlZXQKLSAqLwotcHVibGljIGNsYXNzIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZXh0ZW5kcyBVbkltcGxOb2RlCi0gICAgICAgIGltcGxlbWVudHMgUHJlZml4UmVzb2x2ZXIsIFNlcmlhbGl6YWJsZSwgU291cmNlTG9jYXRvciwgCi0gICAgICAgICAgICAgICAgICAgV2hpdGVzcGFjZVN0cmlwcGluZ0VsZW1lbnRNYXRjaGVyCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIHRlbXBsYXRlIGVsZW1lbnQgaW5zdGFuY2UuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBUaGUgWFNMVCBUcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAqIEBwYXJhbSBzdHlsZXNoZWV0VHJlZSBUaGUgb3duaW5nIHN0eWxlc2hlZXQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgKiBAcGFyYW0gYXR0cyBUaGUgZWxlbWVudCBhdHRyaWJ1dGVzLgotICAgKiBAcGFyYW0gbGluZU51bWJlciBUaGUgbGluZSBpbiB0aGUgWFNMVCBmaWxlIHRoYXQgdGhlIGVsZW1lbnQgb2NjdXJzIG9uLgotICAgKiBAcGFyYW0gY29sdW1uTnVtYmVyIFRoZSBjb2x1bW4gaW5kZXggaW4gdGhlIFhTTFQgZmlsZSB0aGF0IHRoZSBlbGVtZW50IG9jY3VycyBvbi4KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50KCl7fQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgdGVtcGxhdGUgaXMgYSBjb21waWxlZCB0ZW1wbGF0ZS4KLSAgICoKLSAgICogQHJldHVybiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgaXMgYSBjb21waWxlZCB0ZW1wbGF0ZSAgIAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNDb21waWxlZFRlbXBsYXRlKCkKLSAgewotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiB0aGUgZWxlbWVudCB0eXBlLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQsIGRlZmluZWQgaW4gdGhlCi0gICAqICAgICBDb25zdGFudHMgY2xhc3MuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfVU5ERUZJTkVEOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGludmFsaWQgbm9kZSBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiAiVW5rbm93biBYU0xUIEVsZW1lbnQiOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgb24gdG9wLWxldmVsIGVsZW1lbnRzCi0gICAqIG9ubHksIGp1c3QgYmVmb3JlIHRoZSB0cmFuc2Zvcm0gYmVnaW5zLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgVGhlIFhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW50aW1lSW5pdChUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbnt9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGVsZW1lbnQncyBwcmltYXJ5IGZ1bmN0aW9uLiAgU3ViY2xhc3NlcyBvZiB0aGlzCi0gICAqIGZ1bmN0aW9uIG1heSByZWN1cnNpdmx5IGV4ZWN1dGUgZG93biB0aGUgZWxlbWVudCB0cmVlLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgVGhlIFhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBtb2RlIFRoZSBjdXJyZW50IG1vZGUuCi0gICAqIAotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGFueSBjaGVja2VkIGV4Y2VwdGlvbiBvY2N1cnMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbnt9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3duaW5nICJjb21wb3NlZCIgc3R5bGVzaGVldC4gIFRoaXMgbG9va3MgdXAgdGhlCi0gICAqIGluaGVyaXRhbmNlIGNoYWluIHVudGlsIGl0IGNhbGxzIGdldFN0eWxlc2hlZXRDb21wb3NlZAotICAgKiBvbiBhIFN0eWxlc2hlZXQgb2JqZWN0LCB3aGljaCB3aWxsIEdldCB0aGUgb3duaW5nCi0gICAqIGFnZ3JlZ2F0ZWQgc3R5bGVzaGVldCwgb3IgdGhhdCBzdHlsZXNoZWV0IGlmIGl0IGlzIGFnZ3JlZ2F0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG93bmluZyAiY29tcG9zZWQiIHN0eWxlc2hlZXQuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldENvbXBvc2VkIGdldFN0eWxlc2hlZXRDb21wb3NlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9wYXJlbnROb2RlLmdldFN0eWxlc2hlZXRDb21wb3NlZCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3duaW5nIHN0eWxlc2hlZXQuICBUaGlzIGxvb2tzIHVwIHRoZQotICAgKiBpbmhlcml0YW5jZSBjaGFpbiB1bnRpbCBpdCBjYWxscyBnZXRTdHlsZXNoZWV0Ci0gICAqIG9uIGEgU3R5bGVzaGVldCBvYmplY3QsIHdoaWNoIHdpbGwgcmV0dXJuIGl0c2VsZi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgb3duaW5nIHN0eWxlc2hlZXQKLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0IGdldFN0eWxlc2hlZXQoKQotICB7Ci0gICAgcmV0dXJuIG1fcGFyZW50Tm9kZS5nZXRTdHlsZXNoZWV0KCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvd25pbmcgcm9vdCBzdHlsZXNoZWV0LiAgVGhpcyBsb29rcyB1cCB0aGUKLSAgICogaW5oZXJpdGFuY2UgY2hhaW4gdW50aWwgaXQgY2FsbHMgU3R5bGVzaGVldFJvb3QKLSAgICogb24gYSBTdHlsZXNoZWV0IG9iamVjdCwgd2hpY2ggd2lsbCByZXR1cm4gYSByZWZlcmVuY2UKLSAgICogdG8gdGhlIHJvb3Qgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgb3duaW5nIHJvb3Qgc3R5bGVzaGVldAotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRSb290IGdldFN0eWxlc2hlZXRSb290KCkKLSAgewotICAgIHJldHVybiBtX3BhcmVudE5vZGUuZ2V0U3R5bGVzaGVldFJvb3QoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBkdXJpbmcgcmVjb21wb3NpdGlvbiB0bwotICAgKiBjb250cm9sIGhvdyB0aGlzIGVsZW1lbnQgaXMgY29tcG9zZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZWNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciBldmVyeXRoaW5nIGVsc2UgaGFzIGJlZW4KLSAgICogcmVjb21wb3NlZCwgYW5kIGFsbG93cyB0aGUgdGVtcGxhdGUgdG8gc2V0IHJlbWFpbmluZwotICAgKiB2YWx1ZXMgdGhhdCBtYXkgYmUgYmFzZWQgb24gc29tZSBvdGhlciBwcm9wZXJ0eSB0aGF0Ci0gICAqIGRlcGVuZHMgb24gcmVjb21wb3NpdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmVzb2x2ZVByZWZpeFRhYmxlcygpOwotICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgdCA9IGdldEZpcnN0Q2hpbGRFbGVtKCk7Ci0gICAgbV9oYXNUZXh0TGl0T25seSA9ICgodCAhPSBudWxsKSAKLSAgICAgICAgICAgICAgJiYgKHQuZ2V0WFNMVG9rZW4oKSA9PSBDb25zdGFudHMuRUxFTU5BTUVfVEVYVExJVEVSQUxSRVNVTFQpIAotICAgICAgICAgICAgICAmJiAodC5nZXROZXh0U2libGluZ0VsZW0oKSA9PSBudWxsKSk7Ci0gICAgICAgICAgICAgIAotICAgIFN0eWxlc2hlZXRSb290LkNvbXBvc2VTdGF0ZSBjc3RhdGUgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKTsKLSAgICBjc3RhdGUucHVzaFN0YWNrTWFyaygpOwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBhZnRlciB0aGUgdGVtcGxhdGUncyBjaGlsZHJlbiBoYXZlIGJlZW4gY29tcG9zZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRDb21wb3NlKFN0eWxlc2hlZXRSb290IHNyb290KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIFN0eWxlc2hlZXRSb290LkNvbXBvc2VTdGF0ZSBjc3RhdGUgPSBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKTsKLSAgICBjc3RhdGUucG9wU3RhY2tNYXJrKCk7Ci0gIH0KLQotICAvKioKLSAgICogVmFsaWRhdGUgdGhhdCB0aGUgc3RyaW5nIGlzIGFuIE5DTmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHMgVGhlIG5hbWUgaW4gcXVlc3Rpb24uCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGEgdmFsaWQgTkNOYW1lIGFjY29yZGluZyB0byBYTUwgcnVsZXMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcyNOVC1OQ05hbWUiPlhYWCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1ZhbGlkTkNOYW1lKFN0cmluZyBzKQotICB7Ci0KLSAgICBpbnQgbGVuID0gcy5sZW5ndGgoKTsKLSAgICBjaGFyIGMgPSBzLmNoYXJBdCgwKTsKLQotICAgIGlmICghKENoYXJhY3Rlci5pc0xldHRlcihjKSB8fCAoYyA9PSAnXycpKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGlmIChsZW4gPiAwKQotICAgIHsKLSAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbGVuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGMgPSBzLmNoYXJBdChpKTsKLQotICAgICAgICBpZiAoIShDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KGMpIHx8IChjID09ICdfJykgfHwgKGMgPT0gJy0nKQotICAgICAgICAgICAgICB8fCAoYyA9PSAnLicpKSkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogVGhyb3cgYSB0ZW1wbGF0ZSBlbGVtZW50IHJ1bnRpbWUgZXJyb3IuICAoTm90ZTogc2hvdWxkIHdlIHRocm93IGEgVHJhbnNmb3JtZXJFeGNlcHRpb24gaW5zdGVhZD8pCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgRGVzY3JpcHRpb24gb2YgdGhlIGVycm9yIHRoYXQgb2NjdXJlZC4KLSAgICogQHBhcmFtIGFyZ3MgQXJndW1lbnRzIHRvIGJlIHVzZWQgaW4gdGhlIG1lc3NhZ2UKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKGludCBtc2csIE9iamVjdFtdIGFyZ3MpCi0gIHsKLQotICAgIFN0cmluZyB0aGVtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKG1zZywgYXJncyk7Ci0KLSAgICBlcnJvcigKLSAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9FTEVNVEVNUExBVEVFTEVNX0VSUiwgbmV3IE9iamVjdFtdeyB0aGVtc2cgfSkpOyAgLy8iRWxlbVRlbXBsYXRlRWxlbWVudCBlcnJvcjogIittc2cpOwotICB9Ci0gIAotICAvKioKLSAgICogVGhyb3cgYW4gZXJyb3IuCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSBjb2RlIGZvciB0aGUgZXJyb3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKGludCBtc2cpCi0gIHsKLSAgICBlcnJvcihtc2csIG51bGwpOwotICB9Ci0gIAotICAvKioKLSAgICogVGhyb3cgYSB0ZW1wbGF0ZSBlbGVtZW50IHJ1bnRpbWUgZXJyb3IuICAoTm90ZTogc2hvdWxkIHdlIHRocm93IGEgVHJhbnNmb3JtZXJFeGNlcHRpb24gaW5zdGVhZD8pCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgRGVzY3JpcHRpb24gb2YgdGhlIGVycm9yIHRoYXQgb2NjdXJlZC4KLSAgICogQHBhcmFtIGFyZ3MgQXJndW1lbnRzIHRvIGJlIHVzZWQgaW4gdGhlIG1lc3NhZ2UKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtc2cpCi0gIHsKLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihtc2cpOwotICB9Ci0gIAotCi0gIC8vIEltcGxlbWVudGVkIERPTSBFbGVtZW50IG1ldGhvZHMuCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICogTk9URTogVGhpcyBwcmVzdW1lcyB0aGUgY2hpbGQgZGlkIG5vdCBwcmV2aW91c2x5IGhhdmUgYSBwYXJlbnQuCi0gICAqIE1ha2luZyB0aGF0IGFzc3VtcHRpb24gbWFrZXMgdGhpcyBhIGxlc3MgZXhwZW5zaXZlIG9wZXJhdGlvbiAtLSBidXQKLSAgICogcmVxdWlyZXMgdGhhdCBpZiB5b3UgKmRvKiB3YW50IHRvIHJlcGFyZW50IGEgbm9kZSwgeW91IHVzZSByZW1vdmVDaGlsZCgpCi0gICAqIGZpcnN0IHRvIHJlbW92ZSBpdCBmcm9tIGl0cyBwcmV2aW91cyBjb250ZXh0LiBGYWlsaW5nIHRvIGRvIHNvIHdpbGwKLSAgICogZGFtYWdlIHRoZSB0cmVlLgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYmUgYWRkZWQgdG8gY2hpbGQgbGlzdAotICAgKgotICAgKiBAcmV0dXJuIENoaWxkIGp1c3QgYWRkZWQgdG8gdGhlIGNoaWxkIGxpc3QKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlIGFwcGVuZENoaWxkKE5vZGUgbmV3Q2hpbGQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gbmV3Q2hpbGQpCi0gICAgewotICAgICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05VTExfQ0hJTEQsIG51bGwpOyAgLy8iVHJ5aW5nIHRvIGFkZCBhIG51bGwgY2hpbGQhIik7Ci0gICAgfQotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtID0gKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG5ld0NoaWxkOwotCi0gICAgaWYgKG51bGwgPT0gbV9maXJzdENoaWxkKQotICAgIHsKLSAgICAgIG1fZmlyc3RDaGlsZCA9IGVsZW07Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IGxhc3QgPSAoRWxlbVRlbXBsYXRlRWxlbWVudCkgZ2V0TGFzdENoaWxkKCk7Ci0KLSAgICAgIGxhc3QubV9uZXh0U2libGluZyA9IGVsZW07Ci0gICAgfQotCi0gICAgZWxlbS5tX3BhcmVudE5vZGUgPSB0aGlzOwotCi0gICAgcmV0dXJuIG5ld0NoaWxkOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIGNoaWxkIHRvIHRoZSBjaGlsZCBsaXN0LgotICAgKiBOT1RFOiBUaGlzIHByZXN1bWVzIHRoZSBjaGlsZCBkaWQgbm90IHByZXZpb3VzbHkgaGF2ZSBhIHBhcmVudC4KLSAgICogTWFraW5nIHRoYXQgYXNzdW1wdGlvbiBtYWtlcyB0aGlzIGEgbGVzcyBleHBlbnNpdmUgb3BlcmF0aW9uIC0tIGJ1dAotICAgKiByZXF1aXJlcyB0aGF0IGlmIHlvdSAqZG8qIHdhbnQgdG8gcmVwYXJlbnQgYSBub2RlLCB5b3UgdXNlIHJlbW92ZUNoaWxkKCkKLSAgICogZmlyc3QgdG8gcmVtb3ZlIGl0IGZyb20gaXRzIHByZXZpb3VzIGNvbnRleHQuIEZhaWxpbmcgdG8gZG8gc28gd2lsbAotICAgKiBkYW1hZ2UgdGhlIHRyZWUuCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBDaGlsZCB0byBiZSBhZGRlZCB0byBjaGlsZCBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gQ2hpbGQganVzdCBhZGRlZCB0byB0aGUgY2hpbGQgbGlzdAotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXBwZW5kQ2hpbGQoRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBlbGVtKQotICAgIHsKLSAgICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9OVUxMX0NISUxELCBudWxsKTsgIC8vIlRyeWluZyB0byBhZGQgYSBudWxsIGNoaWxkISIpOwotICAgIH0KLQotICAgIGlmIChudWxsID09IG1fZmlyc3RDaGlsZCkKLSAgICB7Ci0gICAgICBtX2ZpcnN0Q2hpbGQgPSBlbGVtOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgRWxlbVRlbXBsYXRlRWxlbWVudCBsYXN0ID0gZ2V0TGFzdENoaWxkRWxlbSgpOwotCi0gICAgICBsYXN0Lm1fbmV4dFNpYmxpbmcgPSBlbGVtOwotICAgIH0KLQotICAgIGVsZW0uc2V0UGFyZW50RWxlbSh0aGlzKTsKLQotICAgIHJldHVybiBlbGVtOwotICB9Ci0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGVyZSBhcmUgY2hpbGQgbm9kZXMuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBhcmUgY2hpbGQgbm9kZXMKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkTm9kZXMoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fZmlyc3RDaGlsZCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB0eXBlIG9mIHRoZSBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIENvbnN0YW50IGZvciB0aGlzIG5vZGUgdHlwZQotICAgKi8KLSAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkKLSAgewotICAgIHJldHVybiBvcmcudzNjLmRvbS5Ob2RlLkVMRU1FTlRfTk9ERTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGVsaXN0IChzYW1lIHJlZmVyZW5jZSkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGVsaXN0IGNvbnRhaW5pbmcgdGhlIGNoaWxkIG5vZGVzICh0aGlzKQotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGEgY2hpbGQuCi0gICAqIEFEREVEIDkvOC8yMDAgdG8gc3VwcG9ydCBjb21waWxhdGlvbi4KLSAgICogVE9ETzogKioqKiogQWx0ZXJuYXRpdmUgaXMgInJlbW92ZU1lKCkgZnJvbSBteSBwYXJlbnQgaWYgYW55IgotICAgKiAuLi4gd2hpY2ggaXMgbGVzcyB3ZWxsIGNoZWNrZWQsIGJ1dCBtb3JlIGNvbnZlbmllbnQgaW4gc29tZSBjYXNlcy4KLSAgICogR2l2ZW4gdGhhdCB3ZSBhc3N1bWUgb25seSBleHBlcnRzIGFyZSBjYWxsaW5nIHRoaXMgY2xhc3MsIGl0IG1pZ2h0Ci0gICAqIGJlIHByZWZlcmFibGUuIEl0J3MgbGVzcyBET01pc2gsIHRob3VnaC4KLSAgICogCi0gICAqIEBwYXJhbSBjaGlsZEVURSBUaGUgY2hpbGQgdG8gcmVtb3ZlLiBUaGlzIG9wZXJhdGlvbiBpcyBhIG5vLW9wCi0gICAqIGlmIG9sZENoaWxkIGlzIG5vdCBhIGNoaWxkIG9mIHRoaXMgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmVtb3ZlZCBjaGlsZCwgb3IgbnVsbCBpZiB0aGUgc3BlY2lmaWVkCi0gICAqIG5vZGUgd2FzIG5vdCBhIGNoaWxkIG9mIHRoaXMgZWxlbWVudC4KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IHJlbW92ZUNoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgY2hpbGRFVEUpCi0gIHsKLQotICAgIGlmIChjaGlsZEVURSA9PSBudWxsIHx8IGNoaWxkRVRFLm1fcGFyZW50Tm9kZSAhPSB0aGlzKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAvLyBQb2ludGVycyB0byB0aGUgY2hpbGQKLSAgICBpZiAoY2hpbGRFVEUgPT0gbV9maXJzdENoaWxkKQotICAgICAgbV9maXJzdENoaWxkID0gY2hpbGRFVEUubV9uZXh0U2libGluZzsKLSAgICBlbHNlCi0gICAgewotICAgICAgRWxlbVRlbXBsYXRlRWxlbWVudCBwcmV2ID0gY2hpbGRFVEUuZ2V0UHJldmlvdXNTaWJsaW5nRWxlbSgpOwotCi0gICAgICBwcmV2Lm1fbmV4dFNpYmxpbmcgPSBjaGlsZEVURS5tX25leHRTaWJsaW5nOwotICAgIH0KLQotICAgIC8vIFBvaW50ZXJzIGZyb20gdGhlIGNoaWxkCi0gICAgY2hpbGRFVEUubV9wYXJlbnROb2RlID0gbnVsbDsKLSAgICBjaGlsZEVURS5tX25leHRTaWJsaW5nID0gbnVsbDsKLQotICAgIHJldHVybiBjaGlsZEVURTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBsYWNlIHRoZSBvbGQgY2hpbGQgd2l0aCBhIG5ldyBjaGlsZC4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIE5ldyBjaGlsZCB0byByZXBsYWNlIHdpdGgKLSAgICogQHBhcmFtIG9sZENoaWxkIE9sZCBjaGlsZCB0byBiZSByZXBsYWNlZAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXcgY2hpbGQKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlIHJlcGxhY2VDaGlsZChOb2RlIG5ld0NoaWxkLCBOb2RlIG9sZENoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChvbGRDaGlsZCA9PSBudWxsIHx8IG9sZENoaWxkLmdldFBhcmVudE5vZGUoKSAhPSB0aGlzKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IG5ld0NoaWxkRWxlbSA9ICgoRWxlbVRlbXBsYXRlRWxlbWVudCkgbmV3Q2hpbGQpOwotICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgb2xkQ2hpbGRFbGVtID0gKChFbGVtVGVtcGxhdGVFbGVtZW50KSBvbGRDaGlsZCk7Ci0KLSAgICAvLyBGaXggdXAgcHJldmlvdXMgc2libGluZy4KLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHByZXYgPQotICAgICAgKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG9sZENoaWxkRWxlbS5nZXRQcmV2aW91c1NpYmxpbmcoKTsKLQotICAgIGlmIChudWxsICE9IHByZXYpCi0gICAgICBwcmV2Lm1fbmV4dFNpYmxpbmcgPSBuZXdDaGlsZEVsZW07Ci0KLSAgICAvLyBGaXggdXAgcGFyZW50ICh0aGlzKQotICAgIGlmIChtX2ZpcnN0Q2hpbGQgPT0gb2xkQ2hpbGRFbGVtKQotICAgICAgbV9maXJzdENoaWxkID0gbmV3Q2hpbGRFbGVtOwotCi0gICAgbmV3Q2hpbGRFbGVtLm1fcGFyZW50Tm9kZSA9IHRoaXM7Ci0gICAgb2xkQ2hpbGRFbGVtLm1fcGFyZW50Tm9kZSA9IG51bGw7Ci0gICAgbmV3Q2hpbGRFbGVtLm1fbmV4dFNpYmxpbmcgPSBvbGRDaGlsZEVsZW0ubV9uZXh0U2libGluZzsKLSAgICBvbGRDaGlsZEVsZW0ubV9uZXh0U2libGluZyA9IG51bGw7Ci0KLSAgICAvLyBuZXdDaGlsZEVsZW0ubV9zdHlsZXNoZWV0ID0gb2xkQ2hpbGRFbGVtLm1fc3R5bGVzaGVldDsKLSAgICAvLyBvbGRDaGlsZEVsZW0ubV9zdHlsZXNoZWV0ID0gbnVsbDsKLSAgICByZXR1cm4gbmV3Q2hpbGRFbGVtOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcGxhY2UgdGhlIG9sZCBjaGlsZCB3aXRoIGEgbmV3IGNoaWxkLgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgTmV3IGNoaWxkIHRvIHJlcGxhY2Ugd2l0aAotICAgKiBAcGFyYW0gb2xkQ2hpbGQgT2xkIGNoaWxkIHRvIGJlIHJlcGxhY2VkCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ldyBjaGlsZAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgcmVwbGFjZUNoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgbmV3Q2hpbGRFbGVtLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgb2xkQ2hpbGRFbGVtKQotICB7Ci0KLSAgICBpZiAob2xkQ2hpbGRFbGVtID09IG51bGwgfHwgb2xkQ2hpbGRFbGVtLmdldFBhcmVudEVsZW0oKSAhPSB0aGlzKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAvLyBGaXggdXAgcHJldmlvdXMgc2libGluZy4KLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHByZXYgPQotICAgICAgb2xkQ2hpbGRFbGVtLmdldFByZXZpb3VzU2libGluZ0VsZW0oKTsKLQotICAgIGlmIChudWxsICE9IHByZXYpCi0gICAgICBwcmV2Lm1fbmV4dFNpYmxpbmcgPSBuZXdDaGlsZEVsZW07Ci0KLSAgICAvLyBGaXggdXAgcGFyZW50ICh0aGlzKQotICAgIGlmIChtX2ZpcnN0Q2hpbGQgPT0gb2xkQ2hpbGRFbGVtKQotICAgICAgbV9maXJzdENoaWxkID0gbmV3Q2hpbGRFbGVtOwotCi0gICAgbmV3Q2hpbGRFbGVtLm1fcGFyZW50Tm9kZSA9IHRoaXM7Ci0gICAgb2xkQ2hpbGRFbGVtLm1fcGFyZW50Tm9kZSA9IG51bGw7Ci0gICAgbmV3Q2hpbGRFbGVtLm1fbmV4dFNpYmxpbmcgPSBvbGRDaGlsZEVsZW0ubV9uZXh0U2libGluZzsKLSAgICBvbGRDaGlsZEVsZW0ubV9uZXh0U2libGluZyA9IG51bGw7Ci0KLSAgICAvLyBuZXdDaGlsZEVsZW0ubV9zdHlsZXNoZWV0ID0gb2xkQ2hpbGRFbGVtLm1fc3R5bGVzaGVldDsKLSAgICAvLyBvbGRDaGlsZEVsZW0ubV9zdHlsZXNoZWV0ID0gbnVsbDsKLSAgICByZXR1cm4gbmV3Q2hpbGRFbGVtOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vZGVMaXN0IG1ldGhvZDogQ291bnQgdGhlIGltbWVkaWF0ZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUKLSAgICoKLSAgICogQHJldHVybiBUaGUgY291bnQgb2YgY2hpbGRyZW4gb2YgdGhpcyBub2RlCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLQotICAgIC8vIEl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgZ2V0Q2hpbGROb2RlcyBjYWxsIHN5bmNocm9uaXplZAotICAgIC8vIHRoZSBjaGlsZHJlbi4gVGhlcmVmb3JlLCB3ZSBjYW4gYWNjZXNzIHRoZSBmaXJzdCBjaGlsZAotICAgIC8vIHJlZmVyZW5jZSBkaXJlY3RseS4KLSAgICBpbnQgY291bnQgPSAwOwotCi0gICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IG5vZGUgPSBtX2ZpcnN0Q2hpbGQ7IG5vZGUgIT0gbnVsbDsKLSAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dFNpYmxpbmcpCi0gICAgewotICAgICAgY291bnQrKzsKLSAgICB9Ci0KLSAgICByZXR1cm4gY291bnQ7Ci0gIH0gIC8vIGdldExlbmd0aCgpOmludAotCi0gIC8qKgotICAgKiBOb2RlTGlzdCBtZXRob2Q6IFJldHVybiB0aGUgTnRoIGltbWVkaWF0ZSBjaGlsZCBvZiB0aGlzIG5vZGUsIG9yCi0gICAqIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCBvZiBib3VuZHMuCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiBjaGlsZCB0byBmaW5kCi0gICAqIEByZXR1cm4gb3JnLnczYy5kb20uTm9kZTogdGhlIGNoaWxkIG5vZGUgYXQgZ2l2ZW4gaW5kZXgKLSAgICovCi0gIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGluZGV4KQotICB7Ci0KLSAgICAvLyBJdCBpcyBhc3N1bWVkIHRoYXQgdGhlIGdldENoaWxkTm9kZXMgY2FsbCBzeW5jaHJvbml6ZWQKLSAgICAvLyB0aGUgY2hpbGRyZW4uIFRoZXJlZm9yZSwgd2UgY2FuIGFjY2VzcyB0aGUgZmlyc3QgY2hpbGQKLSAgICAvLyByZWZlcmVuY2UgZGlyZWN0bHkuCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBub2RlID0gbV9maXJzdENoaWxkOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbmRleCAmJiBub2RlICE9IG51bGw7IGkrKykKLSAgICB7Ci0gICAgICBub2RlID0gbm9kZS5tX25leHRTaWJsaW5nOwotICAgIH0KLQotICAgIHJldHVybiBub2RlOwotICB9ICAvLyBpdGVtKGludCk6Tm9kZQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHN0eWxlc2hlZXQgb3duZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0eWxlc2hlZXQgb3duZXIKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkKLSAgewotICAgIHJldHVybiBnZXRTdHlsZXNoZWV0KCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBlbGVtZW50IG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUYWdOYW1lKCkKLSAgewotICAgIHJldHVybiBnZXROb2RlTmFtZSgpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGVsZW1lbnQgb25seSBoYXMgb25lIHRleHQgY2hpbGQsIGZvciBvcHRpbWl6YXRpb24gcHVycG9zZXMuCi0gICAqIEByZXR1cm4gdHJ1ZSBvZiB0aGlzIGVsZW1lbnQgb25seSBoYXMgb25lIHRleHQgbGl0ZXJhbCBjaGlsZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc1RleHRMaXRPbmx5KCkKLSAgewotICAgIHJldHVybiBtX2hhc1RleHRMaXRPbmx5OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYmFzZSBpZGVudGlmaWVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBiYXNlIGlkZW50aWZpZXIgCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJhc2VJZGVudGlmaWVyKCkKLSAgewotCi0gICAgLy8gU2hvdWxkIHRoaXMgYWx3YXlzIGJlIGFic29sdXRlPwotICAgIHJldHVybiB0aGlzLmdldFN5c3RlbUlkKCk7Ci0gIH0KLQotICAvKiogbGluZSBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2xpbmVOdW1iZXI7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICogTm90ZSB0aGF0IHRoaXMgaXMgdGhlIGxpbmUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoYXJhY3RlcgotICAgKiBhZnRlciB0aGUgdGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50IGV2ZW50LgotICAgKiBAcmV0dXJuIFRoZSBsaW5lIG51bWJlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAqIEBzZWUgI2dldENvbHVtbk51bWJlcgotICAgKi8KLSAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKCkKLSAgewotICAgIHJldHVybiBtX2xpbmVOdW1iZXI7Ci0gIH0KLQotICAvKiogdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICogIEBzZXJpYWwgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fY29sdW1uTnVtYmVyOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQgZW5kcy4KLSAgICogTm90ZSB0aGF0IHRoaXMgaXMgdGhlIGNvbHVtbiBudW1iZXIgb2YgdGhlIGZpcnN0Ci0gICAqIGNoYXJhY3RlciBhZnRlciB0aGUgdGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIGRvY3VtZW50Ci0gICAqIGV2ZW50LiAgVGhlIGZpcnN0IGNvbHVtbiBpbiBhIGxpbmUgaXMgcG9zaXRpb24gMS4KLSAgICogQHJldHVybiBUaGUgY29sdW1uIG51bWJlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAqIEBzZWUgI2dldExpbmVOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKCkKLSAgewotICAgIHJldHVybiBtX2NvbHVtbk51bWJlcjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudC4KLSAgICogPHA+VGhpcyB3aWxsIGJlIHRoZSBwdWJsaWMgaWRlbnRpZmllcgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHB1YmxpYyBpZGVudGlmaWVyLCBvcgotICAgKiAgICAgICAgIG51bGwgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAqIEBzZWUgI2dldFN5c3RlbUlkCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkKCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3BhcmVudE5vZGUpID8gbV9wYXJlbnROb2RlLmdldFB1YmxpY0lkKCkgOiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50LgotICAgKgotICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBwYXJzZXIgbXVzdCByZXNvbHZlIGl0Ci0gICAqIGZ1bGx5IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwKLSAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHNlZSAjZ2V0UHVibGljSWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKQotICB7Ci0gICAgcmV0dXJuIHRoaXMuZ2V0U3R5bGVzaGVldCgpLmdldEhyZWYoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGxvY2F0aW9uIGluZm9ybWF0aW9uIGZvciB0aGlzIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhdG9yIFNvdXJjZSBMb2NhdG9yIHdpdGggbG9jYXRpb24gaW5mb3JtYXRpb24gZm9yIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TG9jYXRlckluZm8oU291cmNlTG9jYXRvciBsb2NhdG9yKQotICB7Ci0gICAgbV9saW5lTnVtYmVyID0gbG9jYXRvci5nZXRMaW5lTnVtYmVyKCk7Ci0gICAgbV9jb2x1bW5OdW1iZXIgPSBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBlbGVtZW50IGhhcyB0aGUgZGVmYXVsdCBzcGFjZSBoYW5kbGluZwotICAgKiB0dXJuZWQgb2ZmIG9yIG9uIGFjY29yZGluZyB0byB0aGUgeG1sOnNwYWNlIGF0dHJpYnV0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fZGVmYXVsdFNwYWNlID0gdHJ1ZTsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGVsZW1lbnQgb25seSBoYXMgb25lIHRleHQgY2hpbGQsIGZvciBvcHRpbWl6YXRpb24gcHVycG9zZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2hhc1RleHRMaXRPbmx5ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBlbGVtZW50IG9ubHkgaGFzIG9uZSB0ZXh0IGNoaWxkLCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2hhc1ZhcmlhYmxlRGVjbCA9IGZhbHNlOwotICAKLSAgcHVibGljIGJvb2xlYW4gaGFzVmFyaWFibGVEZWNsKCkKLSAgewotICAgIHJldHVybiBtX2hhc1ZhcmlhYmxlRGVjbDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlICJ4bWw6c3BhY2UiIGF0dHJpYnV0ZS4KLSAgICogQSB0ZXh0IG5vZGUgaXMgcHJlc2VydmVkIGlmIGFuIGFuY2VzdG9yIGVsZW1lbnQgb2YgdGhlIHRleHQgbm9kZQotICAgKiBoYXMgYW4geG1sOnNwYWNlIGF0dHJpYnV0ZSB3aXRoIGEgdmFsdWUgb2YgcHJlc2VydmUsIGFuZAotICAgKiBubyBjbG9zZXIgYW5jZXN0b3IgZWxlbWVudCBoYXMgeG1sOnNwYWNlIHdpdGggYSB2YWx1ZSBvZiBkZWZhdWx0LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ3JlYXRpbmctVGV4dCI+c2VjdGlvbi1DcmVhdGluZy1UZXh0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgIEVudW1lcmF0ZWQgdmFsdWUsIGVpdGhlciBDb25zdGFudHMuQVRUUlZBTF9QUkVTRVJWRSAKLSAgICogb3IgQ29uc3RhbnRzLkFUVFJWQUxfU1RSSVAuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRYbWxTcGFjZShpbnQgdikKLSAgewotICAgIG1fZGVmYXVsdFNwYWNlID0gKChDb25zdGFudHMuQVRUUlZBTF9TVFJJUCA9PSB2KSA/IHRydWUgOiBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAieG1sOnNwYWNlIiBhdHRyaWJ1dGUuCi0gICAqIEEgdGV4dCBub2RlIGlzIHByZXNlcnZlZCBpZiBhbiBhbmNlc3RvciBlbGVtZW50IG9mIHRoZSB0ZXh0IG5vZGUKLSAgICogaGFzIGFuIHhtbDpzcGFjZSBhdHRyaWJ1dGUgd2l0aCBhIHZhbHVlIG9mIHByZXNlcnZlLCBhbmQKLSAgICogbm8gY2xvc2VyIGFuY2VzdG9yIGVsZW1lbnQgaGFzIHhtbDpzcGFjZSB3aXRoIGEgdmFsdWUgb2YgZGVmYXVsdC4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3N0cmlwIj5zdHJpcCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNyZWF0aW5nLVRleHQiPnNlY3Rpb24tQ3JlYXRpbmctVGV4dCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSB4bWw6c3BhY2UgYXR0cmlidXRlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRYbWxTcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gbV9kZWZhdWx0U3BhY2U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGxpc3Qgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBmb3IgdGhpcyBlbGVtZW50IG9ubHkuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fZGVjbGFyZWRQcmVmaXhlczsKLQotICAvKioKLSAgICogUmV0dXJuIGEgdGFibGUgdGhhdCBjb250YWlucyBhbGwgcHJlZml4ZXMgYXZhaWxhYmxlCi0gICAqIHdpdGhpbiB0aGlzIGVsZW1lbnQgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBWZWN0b3IgY29udGFpbmluZyB0aGUgcHJlZml4ZXMgYXZhaWxhYmxlIHdpdGhpbiB0aGlzCi0gICAqIGVsZW1lbnQgY29udGV4dCAKLSAgICovCi0gIHB1YmxpYyBWZWN0b3IgZ2V0RGVjbGFyZWRQcmVmaXhlcygpCi0gIHsKLSAgICByZXR1cm4gbV9kZWNsYXJlZFByZWZpeGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEZyb20gdGhlIFNBWDIgaGVscGVyIGNsYXNzLCBzZXQgdGhlIG5hbWVzcGFjZSB0YWJsZSBmb3IKLSAgICogdGhpcyBlbGVtZW50LiAgVGFrZSBjYXJlIHRvIGNhbGwgcmVzb2x2ZUluaGVyaXRlZE5hbWVzcGFjZURlY2xzLgotICAgKiBhZnRlciBhbGwgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBoYXZlIGJlZW4gYWRkZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuc1N1cHBvcnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIE5hbWVzcGFjZVN1cHBvcnQgZnJvbSAKLSAgICogdGhlIENvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcmVmaXhlcyhOYW1lc3BhY2VTdXBwb3J0IG5zU3VwcG9ydCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzZXRQcmVmaXhlcyhuc1N1cHBvcnQsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGZyb20gdGhlIE5hbWVzcGFjZVN1cHBvcnQgb2JqZWN0LiAgCi0gICAqIFRha2UgY2FyZSB0byBjYWxsIHJlc29sdmVJbmhlcml0ZWROYW1lc3BhY2VEZWNscy4KLSAgICogYWZ0ZXIgYWxsIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaGF2ZSBiZWVuIGFkZGVkLgotICAgKgotICAgKiBAcGFyYW0gbnNTdXBwb3J0IG5vbi1udWxsIHJlZmVyZW5jZSB0byBOYW1lc3BhY2VTdXBwb3J0IGZyb20gCi0gICAqIHRoZSBDb250ZW50SGFuZGxlci4KLSAgICogQHBhcmFtIGV4Y2x1ZGVYU0xEZWNsIHRydWUgaWYgWFNMVCBuYW1lc3BhY2VzIHNob3VsZCBiZSBpZ25vcmVkLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcmVmaXhlcyhOYW1lc3BhY2VTdXBwb3J0IG5zU3VwcG9ydCwgYm9vbGVhbiBleGNsdWRlWFNMRGVjbCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRW51bWVyYXRpb24gZGVjbHMgPSBuc1N1cHBvcnQuZ2V0RGVjbGFyZWRQcmVmaXhlcygpOwotCi0gICAgd2hpbGUgKGRlY2xzLmhhc01vcmVFbGVtZW50cygpKQotICAgIHsKLSAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKSBkZWNscy5uZXh0RWxlbWVudCgpOwotCi0gICAgICBpZiAobnVsbCA9PSBtX2RlY2xhcmVkUHJlZml4ZXMpCi0gICAgICAgIG1fZGVjbGFyZWRQcmVmaXhlcyA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgU3RyaW5nIHVyaSA9IG5zU3VwcG9ydC5nZXRVUkkocHJlZml4KTsKLQotICAgICAgaWYgKGV4Y2x1ZGVYU0xEZWNsICYmIHVyaS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKSkKLSAgICAgICAgY29udGludWU7Ci0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigic2V0UHJlZml4ZXMgLSAiK3ByZWZpeCsiLCAiK3VyaSk7Ci0gICAgICBYTUxOU0RlY2wgZGVjbCA9IG5ldyBYTUxOU0RlY2wocHJlZml4LCB1cmksIGZhbHNlKTsKLQotICAgICAgbV9kZWNsYXJlZFByZWZpeGVzLmFkZEVsZW1lbnQoZGVjbCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZ1bGxmaWxsIHRoZSBQcmVmaXhSZXNvbHZlciBpbnRlcmZhY2UuICBDYWxsaW5nIHRoaXMgZm9yIHRoaXMgY2xhc3MgCi0gICAqIHdpbGwgdGhyb3cgYW4gZXJyb3IuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBsb29rIHVwLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nICgiIikgCi0gICAqICAgICAgICAgICAgICAgZm9yIHRoZSBkZWZhdWx0IE5hbWVzcGFjZS4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIG5vZGUgY29udGV4dCBmcm9tIHdoaWNoIHRvIGxvb2sgdXAgdGhlIFVSSS4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoZSBlcnJvciBsaXN0ZW5lciBkb2VzIG5vdCBjaG9vc2UgdG8gdGhyb3cgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCwgb3JnLnczYy5kb20uTm9kZSBjb250ZXh0KQotICB7Ci0KLSAgICB0aGlzLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5UX1JFU09MVkVfTlNQUkVGSVgsIG51bGwpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UsIGdldCB0aGUgY29ycmlzcG9uZGluZyBwcmVmaXguCi0gICAqIDkvMTUvMDA6IFRoaXMgaGFkIGJlZW4gaXRlcmF0aXZlbHkgZXhhbWluaW5nIHRoZSBtX2RlY2xhcmVkUHJlZml4ZXMKLSAgICogZmllbGQgZm9yIHRoaXMgbm9kZSBhbmQgaXRzIHBhcmVudHMuIFRoYXQgbWFrZXMgbGlmZSBkaWZmaWN1bHQgZm9yCi0gICAqIHRoZSBjb21waWxhdGlvbiBleHBlcmltZW50LCB3aGljaCBkb2Vzbid0IGhhdmUgYSBzdGF0aWMgdmVjdG9yIG9mCi0gICAqIGxvY2FsIGRlY2xhcmF0aW9ucy4gUmVwbGFjZWQgYSByZWN1cnNpdmUgc29sdXRpb24sIHdoaWNoIHBlcm1pdHMKLSAgICogZWFzaWVyIHN1YmNsYXNzaW5nL292ZXJyaWRpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByZWZpeCBzdHJpbmcsIHdoaWNoIHNob3VsZCBtYXAgCi0gICAqICAgICAgICAgICAgICAgdG8gYSBuYW1lc3BhY2UgVVJMLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2UgVVJMIHRoYXQgdGhlIHByZWZpeCBtYXBzIHRvLCBvciBudWxsIGlmIG5vIAotICAgKiAgICAgICAgIG1hcHBpbmcgY2FuIGJlIGZvdW5kLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCkKLSAgewotLy8gICAgaWYgKG51bGwgIT0gcHJlZml4ICYmIHByZWZpeC5lcXVhbHMoInhtbG5zIikpCi0vLyAgICB7Ci0vLyAgICAgIHJldHVybiBDb25zdGFudHMuU19YTUxOQU1FU1BBQ0VVUkk7Ci0vLyAgICB9Ci0KLSAgICBWZWN0b3IgbnNEZWNscyA9IG1fZGVjbGFyZWRQcmVmaXhlczsKLQotICAgIGlmIChudWxsICE9IG5zRGVjbHMpCi0gICAgewotICAgICAgaW50IG4gPSBuc0RlY2xzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFhNTE5TRGVjbCBkZWNsID0gKFhNTE5TRGVjbCkgbnNEZWNscy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMoZGVjbC5nZXRQcmVmaXgoKSkpCi0gICAgICAgICAgcmV0dXJuIGRlY2wuZ2V0VVJJKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gTm90IGZvdW5kOyBhc2sgb3VyIGFuY2VzdG9ycwotICAgIGlmIChudWxsICE9IG1fcGFyZW50Tm9kZSkKLSAgICAgIHJldHVybiBtX3BhcmVudE5vZGUuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0KLSAgICAvLyBObyBwYXJlbnQsIHNvIG5vIGRlZmluaXRpb24KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgdGFibGUgb2Yge0BsaW5rIFhNTE5TRGVjbH1zIGZvciB0aGlzIGVsZW1lbnQKLSAgICogYW5kIGFsbCBwYXJlbnQgZWxlbWVudHMsIHNjcmVlbmVkIGZvciBleGNsdWRlZCBwcmVmaXhlcy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgVmVjdG9yIG1fcHJlZml4VGFibGU7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHRhYmxlIHRoYXQgY29udGFpbnMgYWxsIHByZWZpeGVzIGF2YWlsYWJsZQotICAgKiB3aXRoaW4gdGhpcyBlbGVtZW50IGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHZlY3RvciBvZiB7QGxpbmsgWE1MTlNEZWNsfXMsIHdoaWNoIG1heSBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIFZlY3RvciBnZXRQcmVmaXhlcygpCi0gIHsKLSAgICByZXR1cm4gbV9wcmVmaXhUYWJsZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB3aGV0aGVyIG9yIG5vdCB0aGUgcGFzc2VkIFVSTCBpcyBjb250YWluZWQgZmxhZ2dlZCBieQotICAgKiB0aGUgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiBwcm9wZXJ0eS4gIFRoaXMgbWV0aG9kIGlzIG92ZXJyaWRkZW4gCi0gICAqIGJ5IHtAbGluayBFbGVtTGl0ZXJhbFJlc3VsdCNjb250YWluc0V4Y2x1ZGVSZXN1bHRQcmVmaXh9LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZXh0ZW5zaW9uLWVsZW1lbnQiPmV4dGVuc2lvbi1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBub24tbnVsbCByZWZlcmVuY2UgdG8gcHJlZml4IHRoYXQgbWlnaHQgYmUgZXhjbHVkZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJlZml4IHNob3VsZCBub3JtYWxseSBiZSBleGNsdWRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRXhjbHVkZVJlc3VsdFByZWZpeChTdHJpbmcgcHJlZml4KQotICB7Ci0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBwYXJlbnQgPSB0aGlzLmdldFBhcmVudEVsZW0oKTsKLSAgICBpZihudWxsICE9IHBhcmVudCkKLSAgICAgIHJldHVybiBwYXJlbnQuY29udGFpbnNFeGNsdWRlUmVzdWx0UHJlZml4KHByZWZpeCk7Ci0gICAgICAKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgcmVzdWx0IG5hbWVzcGFjZSBkZWNsIHNob3VsZCBiZSBleGNsdWRlZC4gIFNob3VsZCBiZSBjYWxsZWQgYmVmb3JlCi0gICAqIG5hbWVzcGFjZSBhbGlhc2luZyAoSSB0aGluaykuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByZWZpeC4KLSAgICogQHBhcmFtIHVyaSByZWZlcmVuY2UgdG8gbmFtZXNwYWNlIHRoYXQgcHJlZml4IG1hcHMgdG8sIHdoaWNoIGlzIHByb3RlY3RlZCAKLSAgICogICAgICAgICAgICBmb3IgbnVsbCwgYnV0IHNob3VsZCByZWFsbHkgbmV2ZXIgYmUgcGFzc2VkIGFzIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHNob3VsZCBiZSBleGNsdWRlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIGV4Y2x1ZGVSZXN1bHROU0RlY2woU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHVyaSAhPSBudWxsKQotICAgIHsKLSAgICAgIGlmICh1cmkuZXF1YWxzKENvbnN0YW50cy5TX1hTTE5BTUVTUEFDRVVSTCkKLSAgICAgICAgICAgICAgfHwgZ2V0U3R5bGVzaGVldCgpLmNvbnRhaW5zRXh0ZW5zaW9uRWxlbWVudFVSSSh1cmkpCi0gICAgICAgICAgICAgIHx8IHVyaS5lcXVhbHMoQ29uc3RhbnRzLlNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCkpCi0gICAgICAgIHJldHVybiB0cnVlOwotCi0gICAgICBpZiAoY29udGFpbnNFeGNsdWRlUmVzdWx0UHJlZml4KHByZWZpeCkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbWJpbmUgdGhlIHBhcmVudCdzIG5hbWVzcGFjZXMgd2l0aCB0aGlzIG5hbWVzcGFjZQotICAgKiBmb3IgZmFzdCBwcm9jZXNzaW5nLCB0YWtpbmcgY2FyZSB0byByZWZlcmVuY2UgdGhlCi0gICAqIHBhcmVudCdzIG5hbWVzcGFjZSBpZiB0aGlzIG5hbWVzcGFjZSBhZGRzIG5vdGhpbmcgbmV3LgotICAgKiAoUmVjdXJzaXZlIG1ldGhvZCwgd2Fsa2luZyB0aGUgZWxlbWVudHMgZGVwdGgtZmlyc3QsCi0gICAqIHByb2Nlc3NpbmcgcGFyZW50cyBiZWZvcmUgY2hpbGRyZW4pLgotICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgYnVpbGRzIG1fcHJlZml4VGFibGUgd2l0aCBhbGlhc2VkIAotICAgKiBuYW1lc3BhY2VzLCAqbm90KiB0aGUgb3JpZ2luYWwgbmFtZXNwYWNlcy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzb2x2ZVByZWZpeFRhYmxlcygpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgLy8gQWx3YXlzIHN0YXJ0IHdpdGggYSBmcmVzaCBwcmVmaXggdGFibGUhCi0gICAgbV9wcmVmaXhUYWJsZSA9IG51bGw7Ci0KLSAgICAvLyBJZiB3ZSBoYXZlIGRlY2xhcmVkIGRlY2xhcmF0aW9ucywgdGhlbiB3ZSBsb29rIGZvciAKLSAgICAvLyBhIHBhcmVudCB0aGF0IGhhcyBuYW1lc3BhY2UgZGVjbHMsIGFuZCBhZGQgdGhlbSAKLSAgICAvLyB0byB0aGlzIGVsZW1lbnQncyBkZWNscy4gIE90aGVyd2lzZSB3ZSBqdXN0IHBvaW50IAotICAgIC8vIHRvIHRoZSBwYXJlbnQgdGhhdCBoYXMgZGVjbHMuCi0gICAgaWYgKG51bGwgIT0gdGhpcy5tX2RlY2xhcmVkUHJlZml4ZXMpCi0gICAgewotICAgICAgU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldCA9IHRoaXMuZ2V0U3R5bGVzaGVldFJvb3QoKTsKLSAgICAgIAotICAgICAgLy8gQWRkIHRoaXMgZWxlbWVudCdzIGRlY2xhcmVkIHByZWZpeGVzIHRvIHRoZSAKLSAgICAgIC8vIHByZWZpeCB0YWJsZS4KLSAgICAgIGludCBuID0gbV9kZWNsYXJlZFByZWZpeGVzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFhNTE5TRGVjbCBkZWNsID0gKFhNTE5TRGVjbCkgbV9kZWNsYXJlZFByZWZpeGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IGRlY2wuZ2V0UHJlZml4KCk7Ci0gICAgICAgIFN0cmluZyB1cmkgPSBkZWNsLmdldFVSSSgpOwotICAgICAgICBpZihudWxsID09IHVyaSkKLSAgICAgICAgICB1cmkgPSAiIjsKLSAgICAgICAgYm9vbGVhbiBzaG91bGRFeGNsdWRlID0gZXhjbHVkZVJlc3VsdE5TRGVjbChwcmVmaXgsIHVyaSk7Ci0KLSAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHByZWZpeCB0YWJsZSBpZiBvbmUgaGFzIG5vdCBhbHJlYWR5IGJlZW4gY3JlYXRlZC4KLSAgICAgICAgaWYgKG51bGwgPT0gbV9wcmVmaXhUYWJsZSkKLSAgICAgICAgICBtX3ByZWZpeFRhYmxlID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgIE5hbWVzcGFjZUFsaWFzIG5zQWxpYXMgPSBzdHlsZXNoZWV0LmdldE5hbWVzcGFjZUFsaWFzQ29tcG9zZWQodXJpKTsKLSAgICAgICAgaWYobnVsbCAhPSBuc0FsaWFzKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gU2hvdWxkIEkgbGVhdmUgdGhlIG5vbi1hbGlhc2VkIGVsZW1lbnQgaW4gdGhlIHRhYmxlIGFzIAotICAgICAgICAgIC8vIGFuIGV4Y2x1ZGVkIGVsZW1lbnQ/Ci0gICAgICAgICAgCi0gICAgICAgICAgLy8gVGhlIGV4Y2x1c2lvbiBzaG91bGQgYXBwbHkgdG8gdGhlIG5vbi1hbGlhc2VkIHByZWZpeCwgc28gCi0gICAgICAgICAgLy8gd2UgZG9uJ3QgY2FsY3VsYXRlIGl0IGhlcmUuICAtc2IKLSAgICAgICAgICAvLyBVc2Ugc3R5bGVzaGVldCBwcmVmaXgsIGFzIHBlciB4c2wgV0cKLSAgICAgICAgICBkZWNsID0gbmV3IFhNTE5TRGVjbChuc0FsaWFzLmdldFN0eWxlc2hlZXRQcmVmaXgoKSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc0FsaWFzLmdldFJlc3VsdE5hbWVzcGFjZSgpLCBzaG91bGRFeGNsdWRlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgZGVjbCA9IG5ldyBYTUxOU0RlY2wocHJlZml4LCB1cmksIHNob3VsZEV4Y2x1ZGUpOwotCi0gICAgICAgIG1fcHJlZml4VGFibGUuYWRkRWxlbWVudChkZWNsKTsKLSAgICAgICAgCi0gICAgICB9Ci0gICAgfQotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBwYXJlbnQgPSB0aGlzLmdldFBhcmVudE5vZGVFbGVtKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBwYXJlbnQpCi0gICAgewotCi0gICAgICAvLyBUaGUgcHJlZml4IHRhYmxlIG9mIHRoZSBwYXJlbnQgc2hvdWxkIG5ldmVyIGJlIG51bGwhCi0gICAgICBWZWN0b3IgcHJlZml4ZXMgPSBwYXJlbnQubV9wcmVmaXhUYWJsZTsKLQotICAgICAgaWYgKG51bGwgPT0gbV9wcmVmaXhUYWJsZSAmJiAhbmVlZFRvQ2hlY2tFeGNsdWRlKCkpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gTm90aGluZyB0byBjb21iaW5lLCBzbyBqdXN0IHVzZSBwYXJlbnQncyB0YWJsZSEKLSAgICAgICAgdGhpcy5tX3ByZWZpeFRhYmxlID0gcGFyZW50Lm1fcHJlZml4VGFibGU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gQWRkIHRoZSBwcmVmaXhlcyBmcm9tIHRoZSBwYXJlbnQncyBwcmVmaXggdGFibGUuCi0gICAgICAgIGludCBuID0gcHJlZml4ZXMuc2l6ZSgpOwotICAgICAgICAKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBYTUxOU0RlY2wgZGVjbCA9IChYTUxOU0RlY2wpIHByZWZpeGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgICBib29sZWFuIHNob3VsZEV4Y2x1ZGUgPSBleGNsdWRlUmVzdWx0TlNEZWNsKGRlY2wuZ2V0UHJlZml4KCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNsLmdldFVSSSgpKTsKLQotICAgICAgICAgIGlmIChzaG91bGRFeGNsdWRlICE9IGRlY2wuZ2V0SXNFeGNsdWRlZCgpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGRlY2wgPSBuZXcgWE1MTlNEZWNsKGRlY2wuZ2V0UHJlZml4KCksIGRlY2wuZ2V0VVJJKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRFeGNsdWRlKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgCi0gICAgICAgICAgLy9tX3ByZWZpeFRhYmxlLmFkZEVsZW1lbnQoZGVjbCk7Ci0gICAgICAgICAgYWRkT3JSZXBsYWNlRGVjbHMoZGVjbCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAobnVsbCA9PSBtX3ByZWZpeFRhYmxlKQotICAgIHsKLQotICAgICAgLy8gTXVzdCBiZSBzdHlsZXNoZWV0IGVsZW1lbnQgd2l0aG91dCBhbnkgcmVzdWx0IHByZWZpeGVzIQotICAgICAgbV9wcmVmaXhUYWJsZSA9IG5ldyBWZWN0b3IoKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBBZGQgb3IgcmVwbGFjZSB0aGlzIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiBsaXN0Ci0gICAqIG9mIG5hbWVzcGFjZXMgaW4gc2NvcGUgZm9yIHRoaXMgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5ld0RlY2wgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHRvIGFkZCB0byBsaXN0Ci0gICAqLwotICB2b2lkIGFkZE9yUmVwbGFjZURlY2xzKFhNTE5TRGVjbCBuZXdEZWNsKQotICB7Ci0gICAgICBpbnQgbiA9IG1fcHJlZml4VGFibGUuc2l6ZSgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+PSAwOyBpLS0pCi0gICAgICAgIHsKLSAgICAgICAgICBYTUxOU0RlY2wgZGVjbCA9IChYTUxOU0RlY2wpIG1fcHJlZml4VGFibGUuZWxlbWVudEF0KGkpOwotCi0gICAgICAgICAgaWYgKGRlY2wuZ2V0UHJlZml4KCkuZXF1YWxzKG5ld0RlY2wuZ2V0UHJlZml4KCkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIG1fcHJlZml4VGFibGUuYWRkRWxlbWVudChuZXdEZWNsKTsgICAgCi0gICAgCi0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm4gd2hldGhlciB3ZSBuZWVkIHRvIGNoZWNrIG5hbWVzcGFjZSBwcmVmaXhlcyAKLSAgICogYWdhaW5zdCBhbmQgZXhjbHVkZSByZXN1bHQgcHJlZml4ZXMgbGlzdC4KLSAgICovCi0gIGJvb2xlYW4gbmVlZFRvQ2hlY2tFeGNsdWRlKCkKLSAgewotICAgIHJldHVybiBmYWxzZTsgICAgCi0gIH0gCi0KLSAgLyoqCi0gICAqIFNlbmQgc3RhcnRQcmVmaXhNYXBwaW5nIGV2ZW50cyB0byB0aGUgcmVzdWx0IHRyZWUgaGFuZGxlcgotICAgKiBmb3IgYWxsIGRlY2xhcmVkIHByZWZpeCBtYXBwaW5ncyBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgZXhlY3V0ZU5TRGVjbHMoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgIT0gbV9wcmVmaXhUYWJsZSkKLSAgICAgIHsKLSAgICAgICAgUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotICAgICAgICBpbnQgbiA9IG1fcHJlZml4VGFibGUuc2l6ZSgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+PSAwOyBpLS0pCi0gICAgICAgIHsKLSAgICAgICAgICBYTUxOU0RlY2wgZGVjbCA9IChYTUxOU0RlY2wpIG1fcHJlZml4VGFibGUuZWxlbWVudEF0KGkpOwotCi0gICAgICAgICAgaWYgKCFkZWNsLmdldElzRXhjbHVkZWQoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcoZGVjbC5nZXRQcmVmaXgoKSwgZGVjbC5nZXRVUkkoKSwgdHJ1ZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTZW5kIHN0YXJ0UHJlZml4TWFwcGluZyBldmVudHMgdG8gdGhlIHJlc3VsdCB0cmVlIGhhbmRsZXIKLSAgICogZm9yIGFsbCBkZWNsYXJlZCBwcmVmaXggbWFwcGluZ3MgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICB2b2lkIHVuZXhlY3V0ZU5TRGVjbHMoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgIT0gbV9wcmVmaXhUYWJsZSkKLSAgICAgIHsKLSAgICAgICAgUmVzdWx0VHJlZUhhbmRsZXIgcmhhbmRsZXIgPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotICAgICAgICBpbnQgbiA9IG1fcHJlZml4VGFibGUuc2l6ZSgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgWE1MTlNEZWNsIGRlY2wgPSAoWE1MTlNEZWNsKSBtX3ByZWZpeFRhYmxlLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgIGlmICghZGVjbC5nZXRJc0V4Y2x1ZGVkKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhkZWNsLmdldFByZWZpeCgpKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci0gIAotICAvKiogVGhlICpyZWxhdGl2ZSogZG9jdW1lbnQgb3JkZXIgbnVtYmVyIG9mIHRoaXMgZWxlbWVudC4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJvdGVjdGVkIGludCBtX2RvY09yZGVyTnVtYmVyID0gLTE7Ci0gIAotICAvKioKLSAgICogU2V0IHRoZSBVSUQgKGRvY3VtZW50IG9yZGVyIGluZGV4KS4KLSAgICoKLSAgICogQHBhcmFtIGtJbmRleCBJbmRleCBvZiB0aGlzIGNoaWxkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VWlkKGludCBpKQotICB7Ci0gICAgbV9kb2NPcmRlck51bWJlciA9IGk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBVSUQgKGRvY3VtZW50IG9yZGVyIGluZGV4KS4KLSAgICoKLSAgICogQHJldHVybiBJbmRleCBvZiB0aGlzIGNoaWxkCi0gICAqLwotICBwdWJsaWMgaW50IGdldFVpZCgpCi0gIHsKLSAgICByZXR1cm4gbV9kb2NPcmRlck51bWJlcjsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFBhcmVudCBub2RlLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgRWxlbVRlbXBsYXRlRWxlbWVudCBtX3BhcmVudE5vZGU7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcGFyZW50IGFzIGEgTm9kZS4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIG5vZGUncyBwYXJlbnQgbm9kZQotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0UGFyZW50Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9wYXJlbnROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcGFyZW50IGFzIGFuIEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBub2RlJ3MgcGFyZW50IGFzIGFuIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGdldFBhcmVudEVsZW0oKQotICB7Ci0gICAgcmV0dXJuIG1fcGFyZW50Tm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHBhcmVudCBhcyBhbiBFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gcGFyZW50IFRoaXMgbm9kZSdzIHBhcmVudCBhcyBhbiBFbGVtVGVtcGxhdGVFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXJlbnRFbGVtKEVsZW1UZW1wbGF0ZUVsZW1lbnQgcCkKLSAgewotICAgIG1fcGFyZW50Tm9kZSA9IHA7Ci0gIH0KLQotICAvKioKLSAgICogTmV4dCBzaWJsaW5nLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBFbGVtVGVtcGxhdGVFbGVtZW50IG1fbmV4dFNpYmxpbmc7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBzaWJsaW5nIChhcyBhIE5vZGUpIG9yIHJldHVybiBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIHRoaXMgbm9kZSdzIG5leHQgc2libGluZyBvciBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXROZXh0U2libGluZygpCi0gIHsKLSAgICByZXR1cm4gbV9uZXh0U2libGluZzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByZXZpb3VzIHNpYmxpbmcgKGFzIGEgTm9kZSkgb3IgcmV0dXJuIG51bGwuCi0gICAqIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBleHBlbnNpdmUgaWYgdGhlIHBhcmVudCBoYXMgbWFueSBraWRzOwotICAgKiB3ZSBhY2NlcHQgdGhhdCBwcmljZSBpbiBleGNoYW5nZSBmb3IgYXZvaWRpbmcgdGhlIHByZXYgcG9pbnRlcgotICAgKiBUT0RPOiBJZiB3ZSB3ZXJlIHN1cmUgcGFyZW50cyBhbmQgc2licyBhcmUgYWx3YXlzIEVsZW1UZW1wbGF0ZUVsZW1lbnRzLAotICAgKiB3ZSBjb3VsZCBoaXQgdGhlIGZpZWxkcyBkaXJlY3RseSByYXRoZXIgdGhhbiB0aHJ1IGFjY2Vzc29ycy4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIG5vZGUncyBwcmV2aW91cyBzaWJsaW5nIG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldFByZXZpb3VzU2libGluZygpCi0gIHsKLQotICAgIE5vZGUgd2Fsa2VyID0gZ2V0UGFyZW50Tm9kZSgpLCBwcmV2ID0gbnVsbDsKLQotICAgIGlmICh3YWxrZXIgIT0gbnVsbCkKLSAgICAgIGZvciAod2Fsa2VyID0gd2Fsa2VyLmdldEZpcnN0Q2hpbGQoKTsgd2Fsa2VyICE9IG51bGw7Ci0gICAgICAgICAgICAgIHByZXYgPSB3YWxrZXIsIHdhbGtlciA9IHdhbGtlci5nZXROZXh0U2libGluZygpKQotICAgICAgewotICAgICAgICBpZiAod2Fsa2VyID09IHRoaXMpCi0gICAgICAgICAgcmV0dXJuIHByZXY7Ci0gICAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByZXZpb3VzIHNpYmxpbmcgKGFzIGEgTm9kZSkgb3IgcmV0dXJuIG51bGwuCi0gICAqIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBleHBlbnNpdmUgaWYgdGhlIHBhcmVudCBoYXMgbWFueSBraWRzOwotICAgKiB3ZSBhY2NlcHQgdGhhdCBwcmljZSBpbiBleGNoYW5nZSBmb3IgYXZvaWRpbmcgdGhlIHByZXYgcG9pbnRlcgotICAgKiBUT0RPOiBJZiB3ZSB3ZXJlIHN1cmUgcGFyZW50cyBhbmQgc2licyBhcmUgYWx3YXlzIEVsZW1UZW1wbGF0ZUVsZW1lbnRzLAotICAgKiB3ZSBjb3VsZCBoaXQgdGhlIGZpZWxkcyBkaXJlY3RseSByYXRoZXIgdGhhbiB0aHJ1IGFjY2Vzc29ycy4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIG5vZGUncyBwcmV2aW91cyBzaWJsaW5nIG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGdldFByZXZpb3VzU2libGluZ0VsZW0oKQotICB7Ci0KLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHdhbGtlciA9IGdldFBhcmVudE5vZGVFbGVtKCk7Ci0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBwcmV2ID0gbnVsbDsKLQotICAgIGlmICh3YWxrZXIgIT0gbnVsbCkKLSAgICAgIGZvciAod2Fsa2VyID0gd2Fsa2VyLmdldEZpcnN0Q2hpbGRFbGVtKCk7IHdhbGtlciAhPSBudWxsOwotICAgICAgICAgICAgICBwcmV2ID0gd2Fsa2VyLCB3YWxrZXIgPSB3YWxrZXIuZ2V0TmV4dFNpYmxpbmdFbGVtKCkpCi0gICAgICB7Ci0gICAgICAgIGlmICh3YWxrZXIgPT0gdGhpcykKLSAgICAgICAgICByZXR1cm4gcHJldjsKLSAgICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IHNpYmxpbmcgKGFzIGEgRWxlbVRlbXBsYXRlRWxlbWVudCkgb3IgcmV0dXJuIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBub2RlJ3MgbmV4dCBzaWJsaW5nIChhcyBhIEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG9yIG51bGwgCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlRWxlbWVudCBnZXROZXh0U2libGluZ0VsZW0oKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dFNpYmxpbmc7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhcmVudCBlbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoaXMgbm9kZSdzIG5leHQgcGFyZW50IChhcyBhIEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG9yIG51bGwgCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlRWxlbWVudCBnZXRQYXJlbnROb2RlRWxlbSgpCi0gIHsKLSAgICByZXR1cm4gbV9wYXJlbnROb2RlOwotICB9Ci0KLQotICAvKioKLSAgICogRmlyc3QgY2hpbGQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIEVsZW1UZW1wbGF0ZUVsZW1lbnQgbV9maXJzdENoaWxkOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZpcnN0IGNoaWxkIGFzIGEgTm9kZS4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIG5vZGUncyBmaXJzdCBjaGlsZCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRGaXJzdENoaWxkKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0Q2hpbGQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaXJzdCBjaGlsZCBhcyBhIEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBub2RlJ3MgZmlyc3QgY2hpbGQgKGFzIGEgRWxlbVRlbXBsYXRlRWxlbWVudCkgb3IgbnVsbAotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZ2V0Rmlyc3RDaGlsZEVsZW0oKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RDaGlsZDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxhc3QgY2hpbGQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBub2RlJ3MgbGFzdCBjaGlsZAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0TGFzdENoaWxkKCkKLSAgewotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBsYXN0Q2hpbGQgPSBudWxsOwotCi0gICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IG5vZGUgPSBtX2ZpcnN0Q2hpbGQ7IG5vZGUgIT0gbnVsbDsKLSAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dFNpYmxpbmcpCi0gICAgewotICAgICAgbGFzdENoaWxkID0gbm9kZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbGFzdENoaWxkOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGFzdCBjaGlsZC4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIG5vZGUncyBsYXN0IGNoaWxkCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlRWxlbWVudCBnZXRMYXN0Q2hpbGRFbGVtKCkKLSAgewotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBsYXN0Q2hpbGQgPSBudWxsOwotCi0gICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IG5vZGUgPSBtX2ZpcnN0Q2hpbGQ7IG5vZGUgIT0gbnVsbDsKLSAgICAgICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dFNpYmxpbmcpCi0gICAgewotICAgICAgbGFzdENoaWxkID0gbm9kZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbGFzdENoaWxkOwotICB9Ci0KLQotICAvKiogRE9NIGJhY2twb2ludGVyIHRoYXQgdGhpcyBlbGVtZW50IG9yaWdpbmF0ZWQgZnJvbS4gICAgICAgICAgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgb3JnLnczYy5kb20uTm9kZSBtX0RPTUJhY2tQb2ludGVyOwotCi0gIC8qKgotICAgKiBJZiB0aGlzIHN0eWxlc2hlZXQgd2FzIGNyZWF0ZWQgZnJvbSBhIERPTSwgZ2V0IHRoZQotICAgKiBET00gYmFja3BvaW50ZXIgdGhhdCB0aGlzIGVsZW1lbnQgb3JpZ2luYXRlZCBmcm9tLgotICAgKiBGb3IgdG9vbGluZyB1c2UuCi0gICAqCi0gICAqIEByZXR1cm4gRE9NIGJhY2twb2ludGVyIHRoYXQgdGhpcyBlbGVtZW50IG9yaWdpbmF0ZWQgZnJvbSBvciBudWxsLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0RE9NQmFja1BvaW50ZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fRE9NQmFja1BvaW50ZXI7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhpcyBzdHlsZXNoZWV0IHdhcyBjcmVhdGVkIGZyb20gYSBET00sIHNldCB0aGUKLSAgICogRE9NIGJhY2twb2ludGVyIHRoYXQgdGhpcyBlbGVtZW50IG9yaWdpbmF0ZWQgZnJvbS4KLSAgICogRm9yIHRvb2xpbmcgdXNlLgotICAgKgotICAgKiBAcGFyYW0gbiBET00gYmFja3BvaW50ZXIgdGhhdCB0aGlzIGVsZW1lbnQgb3JpZ2luYXRlZCBmcm9tLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RE9NQmFja1BvaW50ZXIob3JnLnczYy5kb20uTm9kZSBuKQotICB7Ci0gICAgbV9ET01CYWNrUG9pbnRlciA9IG47Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIG9iamVjdCBmb3IgcHJlY2VkZW5jZSBvcmRlci4KLSAgICogVGhlIG9yZGVyIGlzIGRldGVybWluZWQgYnkgdGhlIGdldEltcG9ydENvdW50Q29tcG9zZWQoKSBvZiB0aGUgY29udGFpbmluZwotICAgKiBjb21wb3NlZCBzdHlsZXNoZWV0IGFuZCB0aGUgZ2V0VWlkKCkgb2YgdGhpcyBlbGVtZW50LgotICAgKiBSZXR1cm5zIGEgbmVnYXRpdmUgaW50ZWdlciwgemVybywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoaXMKLSAgICogb2JqZWN0IGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8sIG9yIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogCi0gICAqIEBwYXJhbSBvIFRoZSBvYmplY3QgdG8gYmUgY29tcGFyZWQgdG8gdGhpcyBvYmplY3QKLSAgICogQHJldHVybnMgYSBuZWdhdGl2ZSBpbnRlZ2VyLCB6ZXJvLCBvciBhIHBvc2l0aXZlIGludGVnZXIgYXMgdGhpcyBvYmplY3QgaXMKLSAgICogICAgICAgICAgbGVzcyB0aGFuLCBlcXVhbCB0bywgb3IgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgotICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCdzCi0gICAqICAgICAgICAgdHlwZSBwcmV2ZW50cyBpdCBmcm9tIGJlaW5nIGNvbXBhcmVkIHRvIHRoaXMgT2JqZWN0LgotICAgKi8KLSAgcHVibGljIGludCBjb21wYXJlVG8oT2JqZWN0IG8pIHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gewotICAgIAotICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgcm8gPSAoRWxlbVRlbXBsYXRlRWxlbWVudCkgbzsKLSAgICBpbnQgcm9QcmVjZWRlbmNlID0gcm8uZ2V0U3R5bGVzaGVldENvbXBvc2VkKCkuZ2V0SW1wb3J0Q291bnRDb21wb3NlZCgpOwotICAgIGludCBteVByZWNlZGVuY2UgPSB0aGlzLmdldFN0eWxlc2hlZXRDb21wb3NlZCgpLmdldEltcG9ydENvdW50Q29tcG9zZWQoKTsKLQotICAgIGlmIChteVByZWNlZGVuY2UgPCByb1ByZWNlZGVuY2UpCi0gICAgICByZXR1cm4gLTE7Ci0gICAgZWxzZSBpZiAobXlQcmVjZWRlbmNlID4gcm9QcmVjZWRlbmNlKQotICAgICAgcmV0dXJuIDE7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHRoaXMuZ2V0VWlkKCkgLSByby5nZXRVaWQoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIG9yIG5vdCBhbiBlbGVtZW50IHNob3VsZCBzdHJpcCB3aGl0ZXNwYWNlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEVsZW1lbnQgdG8gY2hlY2sKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB3aGl0ZXNwYWNlIHNob3VsZCBiZSBzdHJpcHBlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc2hvdWxkU3RyaXBXaGl0ZVNwYWNlKAotICAgICAgICAgIG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0IHN1cHBvcnQsIAotICAgICAgICAgIG9yZy53M2MuZG9tLkVsZW1lbnQgdGFyZ2V0RWxlbWVudCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBTdHlsZXNoZWV0Um9vdCBzcm9vdCA9IHRoaXMuZ2V0U3R5bGVzaGVldFJvb3QoKTsKLSAgICByZXR1cm4gKG51bGwgIT0gc3Jvb3QpID8gc3Jvb3Quc2hvdWxkU3RyaXBXaGl0ZVNwYWNlKHN1cHBvcnQsIHRhcmdldEVsZW1lbnQpIDpmYWxzZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIG9yIG5vdCB3aGl0ZXNwYWNlIGNhbiBiZSBzdHJpcHBlZC4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3N0cmlwIj5zdHJpcCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgd2hpdGVzcGFjZSBjYW4gYmUgc3RyaXBwZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjYW5TdHJpcFdoaXRlU3BhY2UoKQotICB7Ci0gICAgU3R5bGVzaGVldFJvb3Qgc3Jvb3QgPSB0aGlzLmdldFN0eWxlc2hlZXRSb290KCk7Ci0gICAgcmV0dXJuIChudWxsICE9IHNyb290KSA/IHNyb290LmNhblN0cmlwV2hpdGVTcGFjZSgpIDogZmFsc2U7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1UZXh0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRleHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzBkNDM1Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRleHQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5MyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDp0ZW1wbGF0ZS4KLSAqIFRoaXMgcHJpbWFyaWx5IGFjdHMgYXMgYSBtYXJrZXIgb24gdGhlIGVsZW1lbnQKLSAqIHN0YWNrIHRvIHNpZ25hbCB0aGF0IHdoaXRlc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZC4KLSAqIDxwcmU+Ci0gKiA8IUVMRU1FTlQgeHNsOnRleHQgKCNQQ0RBVEEpPgotICogPCFBVFRMSVNUIHhzbDp0ZXh0Ci0gKiAgIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nICh5ZXN8bm8pICJubyIKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ3JlYXRpbmctVGV4dCI+c2VjdGlvbi1DcmVhdGluZy1UZXh0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotcHVibGljIGNsYXNzIEVsZW1UZXh0IGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGVsZW1lbnQgc2hvdWxkIGRpc2FibGUgZXNjYXBpbmcuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgYXR0cmlidXRlLgotICAgKiBOb3JtYWxseSwgdGhlIHhtbCBvdXRwdXQgbWV0aG9kIGVzY2FwZXMgJiBhbmQgPCAoYW5kCi0gICAqIHBvc3NpYmx5IG90aGVyIGNoYXJhY3RlcnMpIHdoZW4gb3V0cHV0dGluZyB0ZXh0IG5vZGVzLgotICAgKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgb3V0cHV0IGlzIHdlbGwtZm9ybWVkIFhNTC4gSG93ZXZlciwKLSAgICogaXQgaXMgc29tZXRpbWVzIGNvbnZlbmllbnQgdG8gYmUgYWJsZSB0byBwcm9kdWNlIG91dHB1dAotICAgKiB0aGF0IGlzIGFsbW9zdCwgYnV0IG5vdCBxdWl0ZSB3ZWxsLWZvcm1lZCBYTUw7IGZvcgotICAgKiBleGFtcGxlLCB0aGUgb3V0cHV0IG1heSBpbmNsdWRlIGlsbC1mb3JtZWQgc2VjdGlvbnMKLSAgICogd2hpY2ggYXJlIGludGVuZGVkIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gd2VsbC1mb3JtZWQKLSAgICogWE1MIGJ5IGEgc3Vic2VxdWVudCBub24tWE1MIGF3YXJlIHByb2Nlc3MuIEZvciB0aGlzIHJlYXNvbiwKLSAgICogWFNMVCBwcm92aWRlcyBhIG1lY2hhbmlzbSBmb3IgZGlzYWJsaW5nIG91dHB1dCBlc2NhcGluZy4KLSAgICogQW4geHNsOnZhbHVlLW9mIG9yIHhzbDp0ZXh0IGVsZW1lbnQgbWF5IGhhdmUgYQotICAgKiBkaXNhYmxlLW91dHB1dC1lc2NhcGluZyBhdHRyaWJ1dGU7IHRoZSBhbGxvd2VkIHZhbHVlcwotICAgKiBhcmUgeWVzIG9yIG5vOyB0aGUgZGVmYXVsdCBpcyBubzsgaWYgdGhlIHZhbHVlIGlzIHllcywKLSAgICogdGhlbiBhIHRleHQgbm9kZSBnZW5lcmF0ZWQgYnkgaW5zdGFudGlhdGluZyB0aGUgeHNsOnZhbHVlLW9mCi0gICAqIG9yIHhzbDp0ZXh0IGVsZW1lbnQgc2hvdWxkIGJlIG91dHB1dCB3aXRob3V0IGFueSBlc2NhcGluZy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Rpc2FibGUtb3V0cHV0LWVzY2FwaW5nIj5kaXNhYmxlLW91dHB1dC1lc2NhcGluZyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IEJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBlbGVtZW50IHNob3VsZCBkaXNhYmxlIGVzY2FwaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREaXNhYmxlT3V0cHV0RXNjYXBpbmcoYm9vbGVhbiB2KQotICB7Ci0gICAgbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmcgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiBhdHRyaWJ1dGUuCi0gICAqIE5vcm1hbGx5LCB0aGUgeG1sIG91dHB1dCBtZXRob2QgZXNjYXBlcyAmIGFuZCA8IChhbmQKLSAgICogcG9zc2libHkgb3RoZXIgY2hhcmFjdGVycykgd2hlbiBvdXRwdXR0aW5nIHRleHQgbm9kZXMuCi0gICAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgaXMgd2VsbC1mb3JtZWQgWE1MLiBIb3dldmVyLAotICAgKiBpdCBpcyBzb21ldGltZXMgY29udmVuaWVudCB0byBiZSBhYmxlIHRvIHByb2R1Y2Ugb3V0cHV0Ci0gICAqIHRoYXQgaXMgYWxtb3N0LCBidXQgbm90IHF1aXRlIHdlbGwtZm9ybWVkIFhNTDsgZm9yCi0gICAqIGV4YW1wbGUsIHRoZSBvdXRwdXQgbWF5IGluY2x1ZGUgaWxsLWZvcm1lZCBzZWN0aW9ucwotICAgKiB3aGljaCBhcmUgaW50ZW5kZWQgdG8gYmUgdHJhbnNmb3JtZWQgaW50byB3ZWxsLWZvcm1lZAotICAgKiBYTUwgYnkgYSBzdWJzZXF1ZW50IG5vbi1YTUwgYXdhcmUgcHJvY2Vzcy4gRm9yIHRoaXMgcmVhc29uLAotICAgKiBYU0xUIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciBkaXNhYmxpbmcgb3V0cHV0IGVzY2FwaW5nLgotICAgKiBBbiB4c2w6dmFsdWUtb2Ygb3IgeHNsOnRleHQgZWxlbWVudCBtYXkgaGF2ZSBhCi0gICAqIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGF0dHJpYnV0ZTsgdGhlIGFsbG93ZWQgdmFsdWVzCi0gICAqIGFyZSB5ZXMgb3Igbm87IHRoZSBkZWZhdWx0IGlzIG5vOyBpZiB0aGUgdmFsdWUgaXMgeWVzLAotICAgKiB0aGVuIGEgdGV4dCBub2RlIGdlbmVyYXRlZCBieSBpbnN0YW50aWF0aW5nIHRoZSB4c2w6dmFsdWUtb2YKLSAgICogb3IgeHNsOnRleHQgZWxlbWVudCBzaG91bGQgYmUgb3V0cHV0IHdpdGhvdXQgYW55IGVzY2FwaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciPmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgZWxlbWVudCBzaG91bGQgZGlzYWJsZSBlc2NhcGluZwotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RGlzYWJsZU91dHB1dEVzY2FwaW5nKCkKLSAgewotICAgIHJldHVybiBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiB0aGUgZWxlbWVudCB0eXBlLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQsIGRlZmluZWQgaW4gdGhlCi0gICAqICAgICBDb25zdGFudHMgY2xhc3MuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfVEVYVDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZWxlbWVudCdzIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9URVhUX1NUUklORzsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBjaGlsZCB0byB0aGUgY2hpbGQgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIENoaWxkIHRvIGFkZCB0byBjaGlsZHJlbiBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gQ2hpbGQgYWRkZWQgdG8gY2hpbGRyZW4gbGlzdAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZUVsZW1lbnQgYXBwZW5kQ2hpbGQoRWxlbVRlbXBsYXRlRWxlbWVudCBuZXdDaGlsZCkKLSAgewotCi0gICAgaW50IHR5cGUgPSAoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIG5ld0NoaWxkKS5nZXRYU0xUb2tlbigpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVCA6Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfQURELAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuZXdDaGlsZC5nZXROb2RlTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldE5vZGVOYW1lKCkgfSk7ICAvLyJDYW4gbm90IGFkZCAiICsoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpbmV3Q2hpbGQpLm1fZWxlbU5hbWUgKwotCi0gICAgLy8iIHRvICIgKyB0aGlzLm1fZWxlbU5hbWUpOwotICAgIH0KLQotICAgIHJldHVybiBzdXBlci5hcHBlbmRDaGlsZChuZXdDaGlsZCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVGV4dExpdGVyYWwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVGV4dExpdGVyYWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTFjYTA2My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRleHRMaXRlcmFsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0gCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IGEgdGV4dCBsaXRlcmFsLgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tQ3JlYXRpbmctVGV4dCI+c2VjdGlvbi1DcmVhdGluZy1UZXh0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotcHVibGljIGNsYXNzIEVsZW1UZXh0TGl0ZXJhbCBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogVGVsbCBpZiBzcGFjZSBzaG91bGQgYmUgcHJlc2VydmVkLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9wcmVzZXJ2ZVNwYWNlOwotCi0gIC8qKgotICAgKiBTZXQgd2hldGhlciBvciBub3Qgc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZC4KLSAgICoKLSAgICogQHBhcmFtIHYgQm9vbGVhbiBmbGFnIGluZGljYXRpbmcgd2hldGhlciAKLSAgICogb3Igbm90IHNwYWNlIHNob3VsZCBiZSBwcmVzZXJ2ZWQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZXNlcnZlU3BhY2UoYm9vbGVhbiB2KQotICB7Ci0gICAgbV9wcmVzZXJ2ZVNwYWNlID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgd2hldGhlciBvciBub3Qgc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZC4KLSAgICoKLSAgICogQHJldHVybiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIAotICAgKiBvciBub3Qgc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZCAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFByZXNlcnZlU3BhY2UoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlc2VydmVTcGFjZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGNoYXIgbV9jaFtdOwotICAKLSAgLyoqCi0gICAqIFRoZSBjaGFyYWN0ZXIgYXJyYXkgYXMgYSBzdHJpbmcuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc3RyOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGNoYXJhY3RlcnMgdGhhdCB3aWxsIGJlIG91dHB1dCB0byB0aGUgcmVzdWx0IHRyZWUuLgotICAgKgotICAgKiBAcGFyYW0gdiBBcnJheSBvZiBjaGFyYWN0ZXJzIHRoYXQgd2lsbCBiZSBvdXRwdXQgdG8gdGhlIHJlc3VsdCB0cmVlIAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q2hhcnMoY2hhcltdIHYpCi0gIHsKLSAgICBtX2NoID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGNoYXJhY3RlcnMgdGhhdCB3aWxsIGJlIG91dHB1dCB0byB0aGUgcmVzdWx0IHRyZWUuLgotICAgKgotICAgKiBAcmV0dXJuIEFycmF5IG9mIGNoYXJhY3RlcnMgdGhhdCB3aWxsIGJlIG91dHB1dCB0byB0aGUgcmVzdWx0IHRyZWUKLSAgICovCi0gIHB1YmxpYyBjaGFyW10gZ2V0Q2hhcnMoKQotICB7Ci0gICAgcmV0dXJuIG1fY2g7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIG9mIHRoZSBub2RlIGFzIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIGdldE5vZGVWYWx1ZSgpCi0gIHsKLQotICAgIGlmKG51bGwgPT0gbV9zdHIpCi0gICAgewotICAgICAgbV9zdHIgPSBuZXcgU3RyaW5nKG1fY2gpOwotICAgIH0KLQotICAgIHJldHVybiBtX3N0cjsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoaXMgZWxlbWVudCBzaG91bGQgZGlzYWJsZSBlc2NhcGluZy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiBhdHRyaWJ1dGUuCi0gICAqIE5vcm1hbGx5LCB0aGUgeG1sIG91dHB1dCBtZXRob2QgZXNjYXBlcyAmIGFuZCA8IChhbmQKLSAgICogcG9zc2libHkgb3RoZXIgY2hhcmFjdGVycykgd2hlbiBvdXRwdXR0aW5nIHRleHQgbm9kZXMuCi0gICAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgaXMgd2VsbC1mb3JtZWQgWE1MLiBIb3dldmVyLAotICAgKiBpdCBpcyBzb21ldGltZXMgY29udmVuaWVudCB0byBiZSBhYmxlIHRvIHByb2R1Y2Ugb3V0cHV0Ci0gICAqIHRoYXQgaXMgYWxtb3N0LCBidXQgbm90IHF1aXRlIHdlbGwtZm9ybWVkIFhNTDsgZm9yCi0gICAqIGV4YW1wbGUsIHRoZSBvdXRwdXQgbWF5IGluY2x1ZGUgaWxsLWZvcm1lZCBzZWN0aW9ucwotICAgKiB3aGljaCBhcmUgaW50ZW5kZWQgdG8gYmUgdHJhbnNmb3JtZWQgaW50byB3ZWxsLWZvcm1lZAotICAgKiBYTUwgYnkgYSBzdWJzZXF1ZW50IG5vbi1YTUwgYXdhcmUgcHJvY2Vzcy4gRm9yIHRoaXMgcmVhc29uLAotICAgKiBYU0xUIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciBkaXNhYmxpbmcgb3V0cHV0IGVzY2FwaW5nLgotICAgKiBBbiB4c2w6dmFsdWUtb2Ygb3IgeHNsOnRleHQgZWxlbWVudCBtYXkgaGF2ZSBhCi0gICAqIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGF0dHJpYnV0ZTsgdGhlIGFsbG93ZWQgdmFsdWVzCi0gICAqIGFyZSB5ZXMgb3Igbm87IHRoZSBkZWZhdWx0IGlzIG5vOyBpZiB0aGUgdmFsdWUgaXMgeWVzLAotICAgKiB0aGVuIGEgdGV4dCBub2RlIGdlbmVyYXRlZCBieSBpbnN0YW50aWF0aW5nIHRoZSB4c2w6dmFsdWUtb2YKLSAgICogb3IgeHNsOnRleHQgZWxlbWVudCBzaG91bGQgYmUgb3V0cHV0IHdpdGhvdXQgYW55IGVzY2FwaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciPmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgQm9vbGVhbiB2YWx1ZSBmb3IgImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREaXNhYmxlT3V0cHV0RXNjYXBpbmcoYm9vbGVhbiB2KQotICB7Ci0gICAgbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmcgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiBhdHRyaWJ1dGUuCi0gICAqIE5vcm1hbGx5LCB0aGUgeG1sIG91dHB1dCBtZXRob2QgZXNjYXBlcyAmIGFuZCA8IChhbmQKLSAgICogcG9zc2libHkgb3RoZXIgY2hhcmFjdGVycykgd2hlbiBvdXRwdXR0aW5nIHRleHQgbm9kZXMuCi0gICAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgaXMgd2VsbC1mb3JtZWQgWE1MLiBIb3dldmVyLAotICAgKiBpdCBpcyBzb21ldGltZXMgY29udmVuaWVudCB0byBiZSBhYmxlIHRvIHByb2R1Y2Ugb3V0cHV0Ci0gICAqIHRoYXQgaXMgYWxtb3N0LCBidXQgbm90IHF1aXRlIHdlbGwtZm9ybWVkIFhNTDsgZm9yCi0gICAqIGV4YW1wbGUsIHRoZSBvdXRwdXQgbWF5IGluY2x1ZGUgaWxsLWZvcm1lZCBzZWN0aW9ucwotICAgKiB3aGljaCBhcmUgaW50ZW5kZWQgdG8gYmUgdHJhbnNmb3JtZWQgaW50byB3ZWxsLWZvcm1lZAotICAgKiBYTUwgYnkgYSBzdWJzZXF1ZW50IG5vbi1YTUwgYXdhcmUgcHJvY2Vzcy4gRm9yIHRoaXMgcmVhc29uLAotICAgKiBYU0xUIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciBkaXNhYmxpbmcgb3V0cHV0IGVzY2FwaW5nLgotICAgKiBBbiB4c2w6dmFsdWUtb2Ygb3IgeHNsOnRleHQgZWxlbWVudCBtYXkgaGF2ZSBhCi0gICAqIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGF0dHJpYnV0ZTsgdGhlIGFsbG93ZWQgdmFsdWVzCi0gICAqIGFyZSB5ZXMgb3Igbm87IHRoZSBkZWZhdWx0IGlzIG5vOyBpZiB0aGUgdmFsdWUgaXMgeWVzLAotICAgKiB0aGVuIGEgdGV4dCBub2RlIGdlbmVyYXRlZCBieSBpbnN0YW50aWF0aW5nIHRoZSB4c2w6dmFsdWUtb2YKLSAgICogb3IgeHNsOnRleHQgZWxlbWVudCBzaG91bGQgYmUgb3V0cHV0IHdpdGhvdXQgYW55IGVzY2FwaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciPmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBCb29sZWFuIHZhbHVlIG9mICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RGlzYWJsZU91dHB1dEVzY2FwaW5nKCkKLSAgewotICAgIHJldHVybiBtX2Rpc2FibGVPdXRwdXRFc2NhcGluZzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiB0aGUgZWxlbWVudCB0eXBlLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQsIGRlZmluZWQgaW4gdGhlCi0gICAqICAgICBDb25zdGFudHMgY2xhc3MuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfVEVYVExJVEVSQUxSRVNVTFQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVsZW1lbnQncyBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiAiI1RleHQiOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgdGhlIHRleHQgbGl0ZXJhbCB0byB0aGUgcmVzdWx0IHRyZWUuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotCi0gICAgICBSZXN1bHRUcmVlSGFuZGxlciBydGggPSB0cmFuc2Zvcm1lci5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotICAgICAgaWYgKG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nKQotICAgICAgewotICAgICAgICBydGgucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0RJU0FCTEVfT1VUUFVUX0VTQ0FQSU5HLCAiIik7Ci0gICAgICB9Ci0KLSAgICAgIHJ0aC5jaGFyYWN0ZXJzKG1fY2gsIDAsIG1fY2gubGVuZ3RoKTsKLQotICAgICAgaWYgKG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nKQotICAgICAgewotICAgICAgICBydGgucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVVua25vd24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVW5rbm93bi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMjI1YzYxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVW5rbm93bi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy4qOwotCi1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5hbWVTcGFjZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdUb1N0cmluZ1RhYmxlOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5hbWVTcGFjZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXI7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgYSBMaXRlcmFsIFJlc3VsdCBFbGVtZW50LgotICovCi1wdWJsaWMgY2xhc3MgRWxlbVVua25vd24gZXh0ZW5kcyBFbGVtTGl0ZXJhbFJlc3VsdAotewotCi0gIC8qKgotICAgKiBDb3B5IGFuIHVua25vd24gZWxlbWVudCB0byB0aGUgcmVzdWx0IHRyZWUKLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgdGhlIGN1cnJlbnQgdHJhbnNmb3JtLXRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZSgKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb257fQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1Vc2UuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRjZWUxNWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1Vc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLQotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCB4c2w6dXNlLgotICogVGhpcyBhY3RzIGFzIGEgc3VwZXJjbGFzcyBmb3IgRWxlbUNvcHksIEVsZW1BdHRyaWJ1dGVTZXQsCi0gKiBFbGVtRWxlbWVudCwgYW5kIEVsZW1MaXRlcmFsUmVzdWx0LCBvbiBvcmRlciB0byBpbXBsZW1lbnQKLSAqIHNoYXJlZCBiZWhhdmlvciB0aGUgdXNlLWF0dHJpYnV0ZS1zZXRzIGF0dHJpYnV0ZS4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNhdHRyaWJ1dGUtc2V0cyI+YXR0cmlidXRlLXNldHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbVVzZSBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogVGhlIHZhbHVlIG9mIHRoZSAidXNlLWF0dHJpYnV0ZS1zZXRzIiBhdHRyaWJ1dGUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgUU5hbWUgbV9hdHRyaWJ1dGVTZXRzTmFtZXNbXSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInVzZS1hdHRyaWJ1dGUtc2V0cyIgYXR0cmlidXRlLgotICAgKiBBdHRyaWJ1dGUgc2V0cyBhcmUgdXNlZCBieSBzcGVjaWZ5aW5nIGEgdXNlLWF0dHJpYnV0ZS1zZXRzCi0gICAqIGF0dHJpYnV0ZSBvbiB4c2w6ZWxlbWVudCwgeHNsOmNvcHkgKHNlZSBbNy41IENvcHlpbmddKSBvcgotICAgKiB4c2w6YXR0cmlidXRlLXNldCBlbGVtZW50cy4gVGhlIHZhbHVlIG9mIHRoZSB1c2UtYXR0cmlidXRlLXNldHMKLSAgICogYXR0cmlidXRlIGlzIGEgd2hpdGVzcGFjZS1zZXBhcmF0ZWQgbGlzdCBvZiBuYW1lcyBvZiBhdHRyaWJ1dGUKLSAgICogc2V0cy4gRWFjaCBuYW1lIGlzIHNwZWNpZmllZCBhcyBhIFFOYW1lLCB3aGljaCBpcyBleHBhbmRlZCBhcwotICAgKiBkZXNjcmliZWQgaW4gWzIuNCBRdWFsaWZpZWQgTmFtZXNdLgotICAgKgotICAgKiBAcGFyYW0gdiBUaGUgdmFsdWUgdG8gc2V0IGZvciB0aGUgInVzZS1hdHRyaWJ1dGUtc2V0cyIgYXR0cmlidXRlLiAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFVzZUF0dHJpYnV0ZVNldHMoVmVjdG9yIHYpCi0gIHsKLQotICAgIGludCBuID0gdi5zaXplKCk7Ci0KLSAgICBtX2F0dHJpYnV0ZVNldHNOYW1lcyA9IG5ldyBRTmFtZVtuXTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIG1fYXR0cmlidXRlU2V0c05hbWVzW2ldID0gKFFOYW1lKSB2LmVsZW1lbnRBdChpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSAidXNlLWF0dHJpYnV0ZS1zZXRzIiBhdHRyaWJ1dGUuCi0gICAqIEF0dHJpYnV0ZSBzZXRzIGFyZSB1c2VkIGJ5IHNwZWNpZnlpbmcgYSB1c2UtYXR0cmlidXRlLXNldHMKLSAgICogYXR0cmlidXRlIG9uIHhzbDplbGVtZW50LCB4c2w6Y29weSAoc2VlIFs3LjUgQ29weWluZ10pIG9yCi0gICAqIHhzbDphdHRyaWJ1dGUtc2V0IGVsZW1lbnRzLiBUaGUgdmFsdWUgb2YgdGhlIHVzZS1hdHRyaWJ1dGUtc2V0cwotICAgKiBhdHRyaWJ1dGUgaXMgYSB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIG5hbWVzIG9mIGF0dHJpYnV0ZQotICAgKiBzZXRzLiBFYWNoIG5hbWUgaXMgc3BlY2lmaWVkIGFzIGEgUU5hbWUsIHdoaWNoIGlzIGV4cGFuZGVkIGFzCi0gICAqIGRlc2NyaWJlZCBpbiBbMi40IFF1YWxpZmllZCBOYW1lc10uCi0gICAqCi0gICAqIEBwYXJhbSB2IFRoZSB2YWx1ZSB0byBzZXQgZm9yIHRoZSAidXNlLWF0dHJpYnV0ZS1zZXRzIiBhdHRyaWJ1dGUuIAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VXNlQXR0cmlidXRlU2V0cyhRTmFtZVtdIHYpCi0gIHsKLSAgICBtX2F0dHJpYnV0ZVNldHNOYW1lcyA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAidXNlLWF0dHJpYnV0ZS1zZXRzIiBhdHRyaWJ1dGUuCi0gICAqIEF0dHJpYnV0ZSBzZXRzIGFyZSB1c2VkIGJ5IHNwZWNpZnlpbmcgYSB1c2UtYXR0cmlidXRlLXNldHMKLSAgICogYXR0cmlidXRlIG9uIHhzbDplbGVtZW50LCB4c2w6Y29weSAoc2VlIFs3LjUgQ29weWluZ10pIG9yCi0gICAqIHhzbDphdHRyaWJ1dGUtc2V0IGVsZW1lbnRzLCBvciBhIHhzbDp1c2UtYXR0cmlidXRlLXNldHMgYXR0cmlidXRlIG9uCi0gICAqIExpdGVyYWwgUmVzdWx0IEVsZW1lbnRzLgotICAgKiBUaGUgdmFsdWUgb2YgdGhlIHVzZS1hdHRyaWJ1dGUtc2V0cwotICAgKiBhdHRyaWJ1dGUgaXMgYSB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIG5hbWVzIG9mIGF0dHJpYnV0ZQotICAgKiBzZXRzLiBFYWNoIG5hbWUgaXMgc3BlY2lmaWVkIGFzIGEgUU5hbWUsIHdoaWNoIGlzIGV4cGFuZGVkIGFzCi0gICAqIGRlc2NyaWJlZCBpbiBbMi40IFF1YWxpZmllZCBOYW1lc10uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSAidXNlLWF0dHJpYnV0ZS1zZXRzIiBhdHRyaWJ1dGUuIAotICAgKi8KLSAgcHVibGljIFFOYW1lW10gZ2V0VXNlQXR0cmlidXRlU2V0cygpCi0gIHsKLSAgICByZXR1cm4gbV9hdHRyaWJ1dGVTZXRzTmFtZXM7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBBZGQgdGhlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgbmFtZWQgYXR0cmlidXRlIHNldHMgdG8gdGhlIGF0dHJpYnV0ZSBsaXN0LgotICAgKiBUT0RPOiBFcnJvciBoYW5kbGluZyBmb3I6ICJJdCBpcyBhbiBlcnJvciBpZiB0aGVyZSBhcmUgdHdvIGF0dHJpYnV0ZSBzZXRzCi0gICAqIHdpdGggdGhlIHNhbWUgZXhwYW5kZWQtbmFtZSBhbmQgd2l0aCBlcXVhbCBpbXBvcnQgcHJlY2VkZW5jZSBhbmQgdGhhdCBib3RoCi0gICAqIGNvbnRhaW4gdGhlIHNhbWUgYXR0cmlidXRlIHVubGVzcyB0aGVyZSBpcyBhIGRlZmluaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBzZXQgd2l0aCBoaWdoZXIgaW1wb3J0IHByZWNlZGVuY2UgdGhhdCBhbHNvIGNvbnRhaW5zIHRoZSBhdHRyaWJ1dGUuIgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHN0eWxlc2hlZXQgVGhlIG93bmluZyByb290IHN0eWxlc2hlZXQKLSAgICogQHBhcmFtIGF0dHJpYnV0ZVNldHNOYW1lcyBMaXN0IG9mIGF0dHJpYnV0ZSBzZXRzIG5hbWVzIHRvIGFwcGx5Ci0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwbHlBdHRyU2V0cygKLSAgICAgICAgICBUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsIFN0eWxlc2hlZXRSb290IHN0eWxlc2hlZXQpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGFwcGx5QXR0clNldHModHJhbnNmb3JtZXIsIHN0eWxlc2hlZXQsIG1fYXR0cmlidXRlU2V0c05hbWVzKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgdGhlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgbmFtZWQgYXR0cmlidXRlIHNldHMgdG8gdGhlIGF0dHJpYnV0ZSBsaXN0LgotICAgKiBUT0RPOiBFcnJvciBoYW5kbGluZyBmb3I6ICJJdCBpcyBhbiBlcnJvciBpZiB0aGVyZSBhcmUgdHdvIGF0dHJpYnV0ZSBzZXRzCi0gICAqIHdpdGggdGhlIHNhbWUgZXhwYW5kZWQtbmFtZSBhbmQgd2l0aCBlcXVhbCBpbXBvcnQgcHJlY2VkZW5jZSBhbmQgdGhhdCBib3RoCi0gICAqIGNvbnRhaW4gdGhlIHNhbWUgYXR0cmlidXRlIHVubGVzcyB0aGVyZSBpcyBhIGRlZmluaXRpb24gb2YgdGhlIGF0dHJpYnV0ZQotICAgKiBzZXQgd2l0aCBoaWdoZXIgaW1wb3J0IHByZWNlZGVuY2UgdGhhdCBhbHNvIGNvbnRhaW5zIHRoZSBhdHRyaWJ1dGUuIgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHN0eWxlc2hlZXQgVGhlIG93bmluZyByb290IHN0eWxlc2hlZXQKLSAgICogQHBhcmFtIGF0dHJpYnV0ZVNldHNOYW1lcyBMaXN0IG9mIGF0dHJpYnV0ZSBzZXRzIG5hbWVzIHRvIGFwcGx5Ci0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgc291cmNlIG5vZGU8L2E+LgotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGFwcGx5QXR0clNldHMoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLCBTdHlsZXNoZWV0Um9vdCBzdHlsZXNoZWV0LCBRTmFtZSBhdHRyaWJ1dGVTZXRzTmFtZXNbXSkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBhdHRyaWJ1dGVTZXRzTmFtZXMpCi0gICAgewotICAgICAgaW50IG5OYW1lcyA9IGF0dHJpYnV0ZVNldHNOYW1lcy5sZW5ndGg7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbk5hbWVzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFFOYW1lIHFuYW1lID0gYXR0cmlidXRlU2V0c05hbWVzW2ldOwotICAgICAgICBWZWN0b3IgYXR0clNldHMgPSBzdHlsZXNoZWV0LmdldEF0dHJpYnV0ZVNldENvbXBvc2VkKHFuYW1lKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBhdHRyU2V0cykKLSAgICAgICAgewotICAgICAgICAgIGludCBuU2V0cyA9IGF0dHJTZXRzLnNpemUoKTsKLQotICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgblNldHM7IGsrKykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBFbGVtQXR0cmlidXRlU2V0IGF0dHJTZXQgPQotICAgICAgICAgICAgICAoRWxlbUF0dHJpYnV0ZVNldCkgYXR0clNldHMuZWxlbWVudEF0KGspOwotCi0gICAgICAgICAgICBhdHRyU2V0LmV4ZWN1dGUodHJhbnNmb3JtZXIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IGF0dHJpYnV0ZXMgc3BlY2lmaWVkIGJ5IHVzZS1hdHRyaWJ1dGUtc2V0cyB0byB0aGUgcmVzdWx0IHRyZWUuCi0gICAqIFNwZWNpZnlpbmcgYSB1c2UtYXR0cmlidXRlLXNldHMgYXR0cmlidXRlIGlzIGVxdWl2YWxlbnQgdG8gYWRkaW5nCi0gICAqIHhzbDphdHRyaWJ1dGUgZWxlbWVudHMgZm9yIGVhY2ggb2YgdGhlIGF0dHJpYnV0ZXMgaW4gZWFjaCBvZiB0aGUKLSAgICogbmFtZWQgYXR0cmlidXRlIHNldHMgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgY29udGVudCBvZiB0aGUgZWxlbWVudAotICAgKiB3aXRoIHRoZSB1c2UtYXR0cmlidXRlLXNldHMgYXR0cmlidXRlLCBpbiB0aGUgc2FtZSBvcmRlciBpbiB3aGljaAotICAgKiB0aGUgbmFtZXMgb2YgdGhlIGF0dHJpYnV0ZSBzZXRzIGFyZSBzcGVjaWZpZWQgaW4gdGhlIHVzZS1hdHRyaWJ1dGUtc2V0cwotICAgKiBhdHRyaWJ1dGUuIEl0IGlzIGFuIGVycm9yIGlmIHVzZSBvZiB1c2UtYXR0cmlidXRlLXNldHMgYXR0cmlidXRlcwotICAgKiBvbiB4c2w6YXR0cmlidXRlLXNldCBlbGVtZW50cyBjYXVzZXMgYW4gYXR0cmlidXRlIHNldCB0byBkaXJlY3RseQotICAgKiBvciBpbmRpcmVjdGx5IHVzZSBpdHNlbGYuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICB0cmFuc2Zvcm1lci5nZXRUcmFjZU1hbmFnZXIoKS5maXJlVHJhY2VFdmVudCh0aGlzKTsKLQotICAgIGlmIChudWxsICE9IG1fYXR0cmlidXRlU2V0c05hbWVzKQotICAgIHsKLSAgICAgIGFwcGx5QXR0clNldHModHJhbnNmb3JtZXIsIGdldFN0eWxlc2hlZXRSb290KCksCi0gICAgICAgICAgICAgICAgICAgIG1fYXR0cmlidXRlU2V0c05hbWVzKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVmFsdWVPZi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1WYWx1ZU9mLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxNDBmOGUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1WYWx1ZU9mLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNTggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLlNlbGVjdGlvbkV2ZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlJlc3VsdFRyZWVIYW5kbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOnZhbHVlLW9mLgotICogPHByZT4KLSAqIDwhRUxFTUVOVCB4c2w6dmFsdWUtb2YgRU1QVFk+Ci0gKiA8IUFUVExJU1QgeHNsOnZhbHVlLW9mCi0gKiAgIHNlbGVjdCAlZXhwcjsgI1JFUVVJUkVECi0gKiAgIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nICh5ZXN8bm8pICJubyIKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3ZhbHVlLW9mIj52YWx1ZS1vZiBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtVmFsdWVPZiBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogVGhlIHNlbGVjdCBleHByZXNzaW9uIHRvIGJlIGV4ZWN1dGVkLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFhQYXRoIG1fc2VsZWN0RXhwcmVzc2lvbiA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRydWUgaWYgdGhlIHBhdHRlcm4gaXMgYSBzaW1wbGUgIi4iLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9pc0RvdCA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICogVGhlIHJlcXVpcmVkIHNlbGVjdCBhdHRyaWJ1dGUgaXMgYW4gZXhwcmVzc2lvbjsgdGhpcyBleHByZXNzaW9uCi0gICAqIGlzIGV2YWx1YXRlZCBhbmQgdGhlIHJlc3VsdGluZyBvYmplY3QgaXMgY29udmVydGVkIHRvIGEKLSAgICogc3RyaW5nIGFzIGlmIGJ5IGEgY2FsbCB0byB0aGUgc3RyaW5nIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcGFyYW0gdiBUaGUgdmFsdWUgdG8gc2V0IGZvciB0aGUgInNlbGVjdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U2VsZWN0KFhQYXRoIHYpCi0gIHsKLQotICAgIGlmIChudWxsICE9IHYpCi0gICAgewotICAgICAgU3RyaW5nIHMgPSB2LmdldFBhdHRlcm5TdHJpbmcoKTsKLQotICAgICAgbV9pc0RvdCA9IChudWxsICE9IHMpICYmIHMuZXF1YWxzKCIuIik7Ci0gICAgfQotCi0gICAgbV9zZWxlY3RFeHByZXNzaW9uID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICogVGhlIHJlcXVpcmVkIHNlbGVjdCBhdHRyaWJ1dGUgaXMgYW4gZXhwcmVzc2lvbjsgdGhpcyBleHByZXNzaW9uCi0gICAqIGlzIGV2YWx1YXRlZCBhbmQgdGhlIHJlc3VsdGluZyBvYmplY3QgaXMgY29udmVydGVkIHRvIGEKLSAgICogc3RyaW5nIGFzIGlmIGJ5IGEgY2FsbCB0byB0aGUgc3RyaW5nIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgInNlbGVjdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIFhQYXRoIGdldFNlbGVjdCgpCi0gIHsKLSAgICByZXR1cm4gbV9zZWxlY3RFeHByZXNzaW9uOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoaXMgZWxlbWVudCBzaG91bGQgZGlzYWJsZSBlc2NhcGluZy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiBhdHRyaWJ1dGUuCi0gICAqIE5vcm1hbGx5LCB0aGUgeG1sIG91dHB1dCBtZXRob2QgZXNjYXBlcyAmIGFuZCA8IChhbmQKLSAgICogcG9zc2libHkgb3RoZXIgY2hhcmFjdGVycykgd2hlbiBvdXRwdXR0aW5nIHRleHQgbm9kZXMuCi0gICAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgaXMgd2VsbC1mb3JtZWQgWE1MLiBIb3dldmVyLAotICAgKiBpdCBpcyBzb21ldGltZXMgY29udmVuaWVudCB0byBiZSBhYmxlIHRvIHByb2R1Y2Ugb3V0cHV0Ci0gICAqIHRoYXQgaXMgYWxtb3N0LCBidXQgbm90IHF1aXRlIHdlbGwtZm9ybWVkIFhNTDsgZm9yCi0gICAqIGV4YW1wbGUsIHRoZSBvdXRwdXQgbWF5IGluY2x1ZGUgaWxsLWZvcm1lZCBzZWN0aW9ucwotICAgKiB3aGljaCBhcmUgaW50ZW5kZWQgdG8gYmUgdHJhbnNmb3JtZWQgaW50byB3ZWxsLWZvcm1lZAotICAgKiBYTUwgYnkgYSBzdWJzZXF1ZW50IG5vbi1YTUwgYXdhcmUgcHJvY2Vzcy4gRm9yIHRoaXMgcmVhc29uLAotICAgKiBYU0xUIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciBkaXNhYmxpbmcgb3V0cHV0IGVzY2FwaW5nLgotICAgKiBBbiB4c2w6dmFsdWUtb2Ygb3IgeHNsOnRleHQgZWxlbWVudCBtYXkgaGF2ZSBhCi0gICAqIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGF0dHJpYnV0ZTsgdGhlIGFsbG93ZWQgdmFsdWVzCi0gICAqIGFyZSB5ZXMgb3Igbm87IHRoZSBkZWZhdWx0IGlzIG5vOyBpZiB0aGUgdmFsdWUgaXMgeWVzLAotICAgKiB0aGVuIGEgdGV4dCBub2RlIGdlbmVyYXRlZCBieSBpbnN0YW50aWF0aW5nIHRoZSB4c2w6dmFsdWUtb2YKLSAgICogb3IgeHNsOnRleHQgZWxlbWVudCBzaG91bGQgYmUgb3V0cHV0IHdpdGhvdXQgYW55IGVzY2FwaW5nLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciPmRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVGhlIHZhbHVlIHRvIHNldCBmb3IgdGhlICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RGlzYWJsZU91dHB1dEVzY2FwaW5nKGJvb2xlYW4gdikKLSAgewotICAgIG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgYXR0cmlidXRlLgotICAgKiBOb3JtYWxseSwgdGhlIHhtbCBvdXRwdXQgbWV0aG9kIGVzY2FwZXMgJiBhbmQgPCAoYW5kCi0gICAqIHBvc3NpYmx5IG90aGVyIGNoYXJhY3RlcnMpIHdoZW4gb3V0cHV0dGluZyB0ZXh0IG5vZGVzLgotICAgKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgb3V0cHV0IGlzIHdlbGwtZm9ybWVkIFhNTC4gSG93ZXZlciwKLSAgICogaXQgaXMgc29tZXRpbWVzIGNvbnZlbmllbnQgdG8gYmUgYWJsZSB0byBwcm9kdWNlIG91dHB1dAotICAgKiB0aGF0IGlzIGFsbW9zdCwgYnV0IG5vdCBxdWl0ZSB3ZWxsLWZvcm1lZCBYTUw7IGZvcgotICAgKiBleGFtcGxlLCB0aGUgb3V0cHV0IG1heSBpbmNsdWRlIGlsbC1mb3JtZWQgc2VjdGlvbnMKLSAgICogd2hpY2ggYXJlIGludGVuZGVkIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gd2VsbC1mb3JtZWQKLSAgICogWE1MIGJ5IGEgc3Vic2VxdWVudCBub24tWE1MIGF3YXJlIHByb2Nlc3MuIEZvciB0aGlzIHJlYXNvbiwKLSAgICogWFNMVCBwcm92aWRlcyBhIG1lY2hhbmlzbSBmb3IgZGlzYWJsaW5nIG91dHB1dCBlc2NhcGluZy4KLSAgICogQW4geHNsOnZhbHVlLW9mIG9yIHhzbDp0ZXh0IGVsZW1lbnQgbWF5IGhhdmUgYQotICAgKiBkaXNhYmxlLW91dHB1dC1lc2NhcGluZyBhdHRyaWJ1dGU7IHRoZSBhbGxvd2VkIHZhbHVlcwotICAgKiBhcmUgeWVzIG9yIG5vOyB0aGUgZGVmYXVsdCBpcyBubzsgaWYgdGhlIHZhbHVlIGlzIHllcywKLSAgICogdGhlbiBhIHRleHQgbm9kZSBnZW5lcmF0ZWQgYnkgaW5zdGFudGlhdGluZyB0aGUgeHNsOnZhbHVlLW9mCi0gICAqIG9yIHhzbDp0ZXh0IGVsZW1lbnQgc2hvdWxkIGJlIG91dHB1dCB3aXRob3V0IGFueSBlc2NhcGluZy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Rpc2FibGUtb3V0cHV0LWVzY2FwaW5nIj5kaXNhYmxlLW91dHB1dC1lc2NhcGluZyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSAiZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldERpc2FibGVPdXRwdXRFc2NhcGluZygpCi0gIHsKLSAgICByZXR1cm4gbV9kaXNhYmxlT3V0cHV0RXNjYXBpbmc7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQgdHlwZS4KLSAgICoKLSAgICogQHJldHVybiBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50LCBkZWZpbmVkIGluIHRoZQotICAgKiAgICAgQ29uc3RhbnRzIGNsYXNzLgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX1ZBTFVFT0Y7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgZXZlcnl0aGluZyBlbHNlIGhhcyBiZWVuCi0gICAqIHJlY29tcG9zZWQsIGFuZCBhbGxvd3MgdGhlIHRlbXBsYXRlIHRvIHNldCByZW1haW5pbmcKLSAgICogdmFsdWVzIHRoYXQgbWF5IGJlIGJhc2VkIG9uIHNvbWUgb3RoZXIgcHJvcGVydHkgdGhhdAotICAgKiBkZXBlbmRzIG9uIHJlY29tcG9zaXRpb24uCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBzcm9vdAotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21wb3NlKFN0eWxlc2hlZXRSb290IHNyb290KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIuY29tcG9zZShzcm9vdCk7Ci0KLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldFZhcmlhYmxlTmFtZXMoKTsKLQotICAgIGlmIChudWxsICE9IG1fc2VsZWN0RXhwcmVzc2lvbikKLSAgICAgIG1fc2VsZWN0RXhwcmVzc2lvbi5maXh1cFZhcmlhYmxlcygKLSAgICAgICAgdm5hbWVzLCBzcm9vdC5nZXRDb21wb3NlU3RhdGUoKS5nZXRHbG9iYWxzU2l6ZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfVkFMVUVPRl9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgc3RyaW5nIGV4cHJlc3Npb24gYW5kIGNvcHkgdGhlIHRleHQgdG8gdGhlCi0gICAqIHJlc3VsdCB0cmVlLgotICAgKiBUaGUgcmVxdWlyZWQgc2VsZWN0IGF0dHJpYnV0ZSBpcyBhbiBleHByZXNzaW9uOyB0aGlzIGV4cHJlc3Npb24KLSAgICogaXMgZXZhbHVhdGVkIGFuZCB0aGUgcmVzdWx0aW5nIG9iamVjdCBpcyBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcKLSAgICogYXMgaWYgYnkgYSBjYWxsIHRvIHRoZSBzdHJpbmcgZnVuY3Rpb24uIFRoZSBzdHJpbmcgc3BlY2lmaWVzCi0gICAqIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIGNyZWF0ZWQgdGV4dCBub2RlLiBJZiB0aGUgc3RyaW5nIGlzCi0gICAqIGVtcHR5LCBubyB0ZXh0IG5vZGUgd2lsbCBiZSBjcmVhdGVkLiBUaGUgY3JlYXRlZCB0ZXh0IG5vZGUgd2lsbAotICAgKiBiZSBtZXJnZWQgd2l0aCBhbnkgYWRqYWNlbnQgdGV4dCBub2Rlcy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3ZhbHVlLW9mIj52YWx1ZS1vZiBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICogQHBhcmFtIG1vZGUgcmVmZXJlbmNlLCB3aGljaCBtYXkgYmUgbnVsbCwgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbW9kZXMiPmN1cnJlbnQgbW9kZTwvYT4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGUoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCk7Ci0gICAgUmVzdWx0VHJlZUhhbmRsZXIgcnRoID0gdHJhbnNmb3JtZXIuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGhpcyk7Ci0KLSAgICAgIC8vIE9wdGltaXplIGZvciAiLiIKLSAgICAgIGlmIChmYWxzZSAmJiBtX2lzRG90ICYmIVRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgewotICAgICAgICBpbnQgY2hpbGQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNoaWxkKTsKLQotICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY2hpbGQpOwotCi0gICAgICAgIGlmIChtX2Rpc2FibGVPdXRwdXRFc2NhcGluZykKLSAgICAgICAgICBydGgucHJvY2Vzc2luZ0luc3RydWN0aW9uKAotICAgICAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQuUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGR0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoY2hpbGQsIHJ0aCwgZmFsc2UpOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkKLSAgICAgICAgewotICAgICAgICAgIGlmIChtX2Rpc2FibGVPdXRwdXRFc2NhcGluZykKLSAgICAgICAgICAgIHJ0aC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCi0gICAgICAgICAgICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLQotICAgICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgeGN0eHQucHVzaE5hbWVzcGFjZUNvbnRleHQodGhpcyk7Ci0KLSAgICAgICAgaW50IGN1cnJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotCi0gICAgICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24oY3VycmVudCwgY3VycmVudCk7Ci0KLSAgICAgICAgaWYgKG1fZGlzYWJsZU91dHB1dEVzY2FwaW5nKQotICAgICAgICAgIHJ0aC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCi0gICAgICAgICAgICBqYXZheC54bWwudHJhbnNmb3JtLlJlc3VsdC5QSV9ESVNBQkxFX09VVFBVVF9FU0NBUElORywgIiIpOwotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgRXhwcmVzc2lvbiBleHByID0gbV9zZWxlY3RFeHByZXNzaW9uLmdldEV4cHJlc3Npb24oKTsKLQotICAgICAgICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBYT2JqZWN0IG9iaiA9IGV4cHIuZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVTZWxlY3RlZEV2ZW50KGN1cnJlbnQsIHRoaXMsCi0gICAgICAgICAgICAgICAgICAgICJzZWxlY3QiLCBtX3NlbGVjdEV4cHJlc3Npb24sIG9iaik7Ci0gICAgICAgICAgICBvYmouZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKHJ0aCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBleHByLmV4ZWN1dGVDaGFyc1RvQ29udGVudEhhbmRsZXIoeGN0eHQsIHJ0aCk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkKLSAgICAgICAgewotICAgICAgICAgIGlmIChtX2Rpc2FibGVPdXRwdXRFc2NhcGluZykKLSAgICAgICAgICAgIHJ0aC5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCi0gICAgICAgICAgICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLQotICAgICAgICAgIHhjdHh0LnBvcE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICAgICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24oKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhIGNoaWxkIHRvIHRoZSBjaGlsZCBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgQ2hpbGQgdG8gYWRkIHRvIGNoaWxkcmVuIGxpc3QKLSAgICoKLSAgICogQHJldHVybiBDaGlsZCBqdXN0IGFkZGVkIHRvIGNoaWxkcmVuIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGFwcGVuZENoaWxkKEVsZW1UZW1wbGF0ZUVsZW1lbnQgbmV3Q2hpbGQpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfQURELAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgbmV3Q2hpbGQuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0Tm9kZU5hbWUoKSB9KTsgIC8vIkNhbiBub3QgYWRkICIgKygoRWxlbVRlbXBsYXRlRWxlbWVudCluZXdDaGlsZCkubV9lbGVtTmFtZSArCi0KLSAgICAvLyIgdG8gIiArIHRoaXMubV9lbGVtTmFtZSk7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVmFyaWFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVmFyaWFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGEzODczZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVZhcmlhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NjMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhSVHJlZUZyYWc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhY2UuU2VsZWN0aW9uRXZlbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudCB4c2w6dmFyaWFibGUuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDp2YXJpYWJsZSAldGVtcGxhdGU7PgotICogPCFBVFRMSVNUIHhzbDp2YXJpYWJsZQotICogICBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gKiAgIHNlbGVjdCAlZXhwcjsgI0lNUExJRUQKLSAqID4KLSAqIDwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3ZhcmlhYmxlcyI+dmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotcHVibGljIGNsYXNzIEVsZW1WYXJpYWJsZSBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRWxlbVZhcmlhYmxlCi0gICAqCi0gICAqLwotICBwdWJsaWMgRWxlbVZhcmlhYmxlKCl7fQotCi0gIC8qKgotICAgKiBUaGlzIGlzIHRoZSBpbmRleCBpbnRvIHRoZSBzdGFjayBmcmFtZS4gIElmIHRoZSBpbmRleCBpcyBhYm92ZSB0aGUgCi0gICAqIGdsb2JhbCBhcmVhLCBpdCB3aWxsIGhhdmUgdG8gYmUgb2Zmc2V0IGF0IGV4ZWN1dGlvbiB0aW1lLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2luZGV4OwotICAKLSAgLyoqCi0gICAqIFNldHMgdGhlIHJlbGF0aXZlIHBvc2l0aW9uIG9mIHRoaXMgdmFyaWFibGUgd2l0aGluIHRoZSBzdGFjayBmcmFtZSAoaWYgbG9jYWwpCi0gICAqIG9yIHRoZSBnbG9iYWwgYXJlYSAoaWYgZ2xvYmFsKS4gIE5vdGUgdGhhdCB0aGlzIHNob3VsZCBiZSBjYWxsZWQgb25seSBmb3IKLSAgICogZ2xvYmFsIHZhcmlhYmxlcyBzaW5jZSB0aGUgbG9jYWwgcG9zaXRpb24gaXMgY29tcHV0ZWQgaW4gdGhlIGNvbXBvc2UoKSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbmRleChpbnQgaW5kZXgpCi0gIHsKLSAgICBtX2luZGV4ID0gaW5kZXg7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhpcyBlbGVtZW50IGlzIG5vdCBhdCB0aGUgdG9wLWxldmVsLCBnZXQgdGhlIHJlbGF0aXZlIHBvc2l0aW9uIG9mIHRoZQotICAgKiB2YXJpYWJsZSBpbnRvIHRoZSBzdGFjayBmcmFtZS4gIElmIHRoaXMgdmFyaWFibGUgaXMgYXQgdGhlIHRvcC1sZXZlbCwgZ2V0Ci0gICAqIHRoZSByZWxhdGl2ZSBwb3NpdGlvbiB3aXRoaW4gdGhlIGdsb2JhbCBhcmVhLgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbmRleCgpCi0gIHsKLSAgICByZXR1cm4gbV9pbmRleDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgdmFsdWUgb2YgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX3NlbGVjdFBhdHRlcm47Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInNlbGVjdCIgYXR0cmlidXRlLgotICAgKiBJZiB0aGUgdmFyaWFibGUtYmluZGluZyBlbGVtZW50IGhhcyBhIHNlbGVjdCBhdHRyaWJ1dGUsCi0gICAqIHRoZW4gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgbXVzdCBiZSBhbiBleHByZXNzaW9uIGFuZAotICAgKiB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGlzIHRoZSBvYmplY3QgdGhhdCByZXN1bHRzIGZyb20KLSAgICogZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbi4gSW4gdGhpcyBjYXNlLCB0aGUgY29udGVudAotICAgKiBvZiB0aGUgdmFyaWFibGUgbXVzdCBiZSBlbXB0eS4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IGZvciB0aGUgInNlbGVjdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U2VsZWN0KFhQYXRoIHYpCi0gIHsKLSAgICBtX3NlbGVjdFBhdHRlcm4gPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgInNlbGVjdCIgYXR0cmlidXRlLgotICAgKiBJZiB0aGUgdmFyaWFibGUtYmluZGluZyBlbGVtZW50IGhhcyBhIHNlbGVjdCBhdHRyaWJ1dGUsCi0gICAqIHRoZW4gdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgbXVzdCBiZSBhbiBleHByZXNzaW9uIGFuZAotICAgKiB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGlzIHRoZSBvYmplY3QgdGhhdCByZXN1bHRzIGZyb20KLSAgICogZXZhbHVhdGluZyB0aGUgZXhwcmVzc2lvbi4gSW4gdGhpcyBjYXNlLCB0aGUgY29udGVudAotICAgKiBvZiB0aGUgdmFyaWFibGUgbXVzdCBiZSBlbXB0eS4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiB0aGUgInNlbGVjdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIFhQYXRoIGdldFNlbGVjdCgpCi0gIHsKLSAgICByZXR1cm4gbV9zZWxlY3RQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB2YWx1ZSBvZiB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJvdGVjdGVkIFFOYW1lIG1fcW5hbWU7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogQm90aCB4c2w6dmFyaWFibGUgYW5kIHhzbDpwYXJhbSBoYXZlIGEgcmVxdWlyZWQgbmFtZQotICAgKiBhdHRyaWJ1dGUsIHdoaWNoIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUuIFRoZQotICAgKiB2YWx1ZSBvZiB0aGUgbmFtZSBhdHRyaWJ1dGUgaXMgYSBRTmFtZSwgd2hpY2ggaXMgZXhwYW5kZWQKLSAgICogYXMgZGVzY3JpYmVkIGluIFsyLjQgUXVhbGlmaWVkIE5hbWVzXS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3FuYW1lIj5xbmFtZSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKFFOYW1lIHYpCi0gIHsKLSAgICBtX3FuYW1lID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqIEJvdGggeHNsOnZhcmlhYmxlIGFuZCB4c2w6cGFyYW0gaGF2ZSBhIHJlcXVpcmVkIG5hbWUKLSAgICogYXR0cmlidXRlLCB3aGljaCBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIHZhcmlhYmxlLiBUaGUKLSAgICogdmFsdWUgb2YgdGhlIG5hbWUgYXR0cmlidXRlIGlzIGEgUU5hbWUsIHdoaWNoIGlzIGV4cGFuZGVkCi0gICAqIGFzIGRlc2NyaWJlZCBpbiBbMi40IFF1YWxpZmllZCBOYW1lc10uCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNxbmFtZSI+cW5hbWUgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIFZhbHVlIG9mIHRoZSAibmFtZSIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIFFOYW1lIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fcW5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpcyBhIHRvcC1sZXZlbCB2YXJpYWJsZSBvciBwYXJhbSwgb3Igbm90LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9pc1RvcExldmVsID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFNldCBpZiB0aGlzIGlzIGEgdG9wLWxldmVsIHZhcmlhYmxlIG9yIHBhcmFtLCBvciBub3QuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBpcyBhIHRvcC1sZXZlbCB2YXJpYWJsZQotICAgKiBvciBwYXJhbSwgb3Igbm90LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXNUb3BMZXZlbChib29sZWFuIHYpCi0gIHsKLSAgICBtX2lzVG9wTGV2ZWwgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBpZiB0aGlzIGlzIGEgdG9wLWxldmVsIHZhcmlhYmxlIG9yIHBhcmFtLCBvciBub3QuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGlzIGEgdG9wLWxldmVsIHZhcmlhYmxlCi0gICAqIG9yIHBhcmFtLCBvciBub3QuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRJc1RvcExldmVsKCkKLSAgewotICAgIHJldHVybiBtX2lzVG9wTGV2ZWw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQgdHlwZS4KLSAgICoKLSAgICogQHJldHVybiBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50LCBkZWZpbmVkIGluIHRoZQotICAgKiAgICAgQ29uc3RhbnRzIGNsYXNzLgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX1ZBUklBQkxFOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9WQVJJQUJMRV9TVFJJTkc7Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBjb25zdHJ1Y3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHBhcmFtIEFuIGVsZW1lbnQgY3JlYXRlZCBmcm9tIGFuIHhzbDp2YXJpYWJsZQotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRWxlbVZhcmlhYmxlKEVsZW1WYXJpYWJsZSBwYXJhbSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIG1fc2VsZWN0UGF0dGVybiA9IHBhcmFtLm1fc2VsZWN0UGF0dGVybjsKLSAgICBtX3FuYW1lID0gcGFyYW0ubV9xbmFtZTsKLSAgICBtX2lzVG9wTGV2ZWwgPSBwYXJhbS5tX2lzVG9wTGV2ZWw7Ci0KLSAgICAvLyBtX3ZhbHVlID0gcGFyYW0ubV92YWx1ZTsKLSAgICAvLyBtX3ZhckNvbnRleHQgPSBwYXJhbS5tX3ZhckNvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhIHZhcmlhYmxlIGRlY2xhcmF0aW9uIGFuZCBwdXNoIGl0IG9udG8gdGhlIHZhcmlhYmxlIHN0YWNrLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjdmFyaWFibGVzIj52YXJpYWJsZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlKFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lcikgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChUcmFuc2Zvcm1lckltcGwuU19ERUJVRykKLSAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVUcmFjZUV2ZW50KHRoaXMpOwotCi0gICAgaW50IHNvdXJjZU5vZGUgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXRDdXJyZW50Tm9kZSgpOwotICAgIFhPYmplY3QgdmFyID0gZ2V0VmFsdWUodHJhbnNmb3JtZXIsIHNvdXJjZU5vZGUpOwotCi0gICAgLy8gdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0VmFyU3RhY2soKS5wdXNoVmFyaWFibGUobV9xbmFtZSwgdmFyKTsKLSAgICB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXRWYXJTdGFjaygpLnNldExvY2FsVmFyaWFibGUobV9pbmRleCwgdmFyKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSB0aGUgY3VycmVudCB0cmFuc2Zvcm0tdGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBzb3VyY2Ugbm9kZTwvYT4uCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFhPYmplY3QgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBnZXRWYWx1ZShUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsIGludCBzb3VyY2VOb2RlKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IHZhcjsKLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLQotICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZShzb3VyY2VOb2RlKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fc2VsZWN0UGF0dGVybikKLSAgICAgIHsKLSAgICAgICAgdmFyID0gbV9zZWxlY3RQYXR0ZXJuLmV4ZWN1dGUoeGN0eHQsIHNvdXJjZU5vZGUsIHRoaXMpOwotCi0gICAgICAgIHZhci5hbGxvd0RldGFjaFRvUmVsZWFzZShmYWxzZSk7Ci0KLSAgICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICAgIHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpLmZpcmVTZWxlY3RlZEV2ZW50KHNvdXJjZU5vZGUsIHRoaXMsCi0gICAgICAgICAgICAgICAgICAic2VsZWN0IiwgbV9zZWxlY3RQYXR0ZXJuLCB2YXIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAobnVsbCA9PSBnZXRGaXJzdENoaWxkRWxlbSgpKQotICAgICAgewotICAgICAgICB2YXIgPSBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIFVzZSByZXN1bHQgdHJlZSBmcmFnbWVudAotICAgICAgICBpbnQgZGYgPSB0cmFuc2Zvcm1lci50cmFuc2Zvcm1Ub1JURih0aGlzKTsKLQotICAgICAgICB2YXIgPSBuZXcgWFJUcmVlRnJhZyhkZiwgeGN0eHQpOwotICAgICAgfQotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdmFyOwotICB9Ci0gIAotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBTZWUgaWYgd2UgY2FuIHJlZHVjZSBhbiBSVEYgdG8gYSBzZWxlY3Qgd2l0aCBhIHN0cmluZyBleHByZXNzaW9uLgotICAgIGlmKG51bGwgPT0gbV9zZWxlY3RQYXR0ZXJuICAKLSAgICAgICAmJiBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLm1fb3B0aW1pemUpCi0gICAgewotICAgICAgWFBhdGggbmV3U2VsZWN0ID0gcmV3cml0ZUNoaWxkVG9FeHByZXNzaW9uKHRoaXMpOwotICAgICAgaWYobnVsbCAhPSBuZXdTZWxlY3QpCi0gICAgICAgIG1fc2VsZWN0UGF0dGVybiA9IG5ld1NlbGVjdDsKLSAgICB9Ci0gICAgCi0gICAgU3R5bGVzaGVldFJvb3QuQ29tcG9zZVN0YXRlIGNzdGF0ZSA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpOwotICAgIAotICAgIC8vIFRoaXMgc2hvdWxkIGJlIGRvbmUgYmVmb3JlIGFkZFZhcmlhYmxlTmFtZSwgc28gd2UgZG9uJ3QgaGF2ZSB2aXNpYmlsaXR5IAotICAgIC8vIHRvIHRoZSB2YXJpYWJsZSBub3cgYmVpbmcgZGVmaW5lZC4KLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IGNzdGF0ZS5nZXRWYXJpYWJsZU5hbWVzKCk7Ci0gICAgaWYobnVsbCAhPSBtX3NlbGVjdFBhdHRlcm4pCi0gICAgICBtX3NlbGVjdFBhdHRlcm4uZml4dXBWYXJpYWJsZXModm5hbWVzLCBjc3RhdGUuZ2V0R2xvYmFsc1NpemUoKSk7Ci0gICAgICAKLSAgICAvLyBPbmx5IGFkZCB0aGUgdmFyaWFibGUgaWYgdGhpcyBpcyBub3QgYSBnbG9iYWwuICBJZiBpdCBpcyBhIGdsb2JhbCwgCi0gICAgLy8gaXQgd2FzIGFscmVhZHkgYWRkZWQgYnkgc3R5bGVzaGVldCByb290LgotICAgIGlmKCEobV9wYXJlbnROb2RlIGluc3RhbmNlb2YgU3R5bGVzaGVldCkpCi0gICAgICBtX2luZGV4ID0gY3N0YXRlLmFkZFZhcmlhYmxlTmFtZShtX3FuYW1lKSAtIGNzdGF0ZS5nZXRHbG9iYWxzU2l6ZSgpOwotICAgIAotICAgIC8vIFRoaXMgaGFzIHRvIGJlIGRvbmUgYWZ0ZXIgdGhlIGFkZFZhcmlhYmxlTmFtZSwgc28gdGhhdCB0aGUgdmFyaWFibGUgCi0gICAgLy8gcHVzaGVkIHdvbid0IGJlIGltbWVkaWF0ZWx5IHBvcHBlZCBhZ2FpbiBpbiBlbmRDb21wb3NlLgotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotICB9Ci0gIAotICAKLS8vICAvKioKLS8vICAgKiBUaGlzIGFmdGVyIHRoZSB0ZW1wbGF0ZSdzIGNoaWxkcmVuIGhhdmUgYmVlbiBjb21wb3NlZC4KLS8vICAgKi8KLS8vICBwdWJsaWMgdm9pZCBlbmRDb21wb3NlKCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0vLyAgewotLy8gICAgc3VwZXIuZW5kQ29tcG9zZSgpOwotLy8gIH0KLQotCi0gIC8qKgotICAgKiBJZiB0aGUgY2hpbGRyZW4gb2YgYSB2YXJpYWJsZSBpcyBhIHNpbmdsZSB4c2w6dmFsdWUtb2Ygb3IgdGV4dCBsaXRlcmFsLCAKLSAgICogaXQgaXMgY2hlYXBlciB0byBldmFsdWF0ZSB0aGlzIGFzIGFuIGV4cHJlc3Npb24sIHNvIHRyeSBhbmQgYWRhcHQgdGhlIAotICAgKiBjaGlsZCBhbiBhbiBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gdmFyRWxlbSBTaG91bGQgYmUgYSBFbGVtUGFyYW0sIEVsZW1WYXJpYWJsZSwgb3IgRWxlbVdpdGhQYXJhbS4KLSAgICoKLSAgICogQHJldHVybiBBbiBYUGF0aCBpZiByZXdyaXRlIGlzIHBvc3NpYmxlLCBlbHNlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBYUGF0aCByZXdyaXRlQ2hpbGRUb0V4cHJlc3Npb24oRWxlbVRlbXBsYXRlRWxlbWVudCB2YXJFbGVtKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHQgPSB2YXJFbGVtLmdldEZpcnN0Q2hpbGRFbGVtKCk7Ci0KLSAgICAvLyBEb3duIHRoZSBsaW5lIHRoaXMgY2FuIGJlIGRvbmUgd2l0aCBtdWx0aXBsZSBzdHJpbmcgb2JqZWN0cyB1c2luZyAKLSAgICAvLyB0aGUgY29uY2F0IGZ1bmN0aW9uLgotICAgIGlmIChudWxsICE9IHQgJiYgbnVsbCA9PSB0LmdldE5leHRTaWJsaW5nRWxlbSgpKQotICAgIHsKLSAgICAgIGludCBldHlwZSA9IHQuZ2V0WFNMVG9rZW4oKTsKLQotICAgICAgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9WQUxVRU9GID09IGV0eXBlKQotICAgICAgewotICAgICAgICBFbGVtVmFsdWVPZiB2YWx1ZW9mID0gKEVsZW1WYWx1ZU9mKSB0OwotCi0gICAgICAgIC8vICVUQkQlIEknbSB3b3JyaWVkIGFib3V0IGV4dGVuZGVkIGF0dHJpYnV0ZXMgaGVyZS4KLSAgICAgICAgaWYgKHZhbHVlb2YuZ2V0RGlzYWJsZU91dHB1dEVzY2FwaW5nKCkgPT0gZmFsc2UKLSAgICAgICAgICAgICAgICAmJiB2YWx1ZW9mLmdldERPTUJhY2tQb2ludGVyKCkgPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIHZhckVsZW0ubV9maXJzdENoaWxkID0gbnVsbDsKLQotICAgICAgICAgIHJldHVybiBuZXcgWFBhdGgobmV3IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyKHZhbHVlb2YuZ2V0U2VsZWN0KCkuZ2V0RXhwcmVzc2lvbigpKSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKENvbnN0YW50cy5FTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVCA9PSBldHlwZSkKLSAgICAgIHsKLSAgICAgICAgRWxlbVRleHRMaXRlcmFsIGxpdCA9IChFbGVtVGV4dExpdGVyYWwpIHQ7Ci0KLSAgICAgICAgaWYgKGxpdC5nZXREaXNhYmxlT3V0cHV0RXNjYXBpbmcoKSA9PSBmYWxzZQotICAgICAgICAgICAgICAgICYmIGxpdC5nZXRET01CYWNrUG9pbnRlcigpID09IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcgc3RyID0gbGl0LmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgIFhTdHJpbmcgeHN0ciA9IG5ldyBYU3RyaW5nKHN0cik7Ci0KLSAgICAgICAgICB2YXJFbGVtLm1fZmlyc3RDaGlsZCA9IG51bGw7Ci0KLSAgICAgICAgICByZXR1cm4gbmV3IFhQYXRoKG5ldyBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlcih4c3RyKSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBkdXJpbmcgcmVjb21wb3NpdGlvbiB0bwotICAgKiBjb250cm9sIGhvdyB0aGlzIGVsZW1lbnQgaXMgY29tcG9zZWQuCi0gICAqIEBwYXJhbSByb290IFRoZSByb290IHN0eWxlc2hlZXQgZm9yIHRoaXMgdHJhbnNmb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZWNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgcm9vdCkKLSAgewotICAgIHJvb3QucmVjb21wb3NlVmFyaWFibGVzKHRoaXMpOwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IHRoZSBwYXJlbnQgYXMgYW4gRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHBhcmVudCBUaGlzIG5vZGUncyBwYXJlbnQgYXMgYW4gRWxlbVRlbXBsYXRlRWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyZW50RWxlbShFbGVtVGVtcGxhdGVFbGVtZW50IHApCi0gIHsKLSAgICBzdXBlci5zZXRQYXJlbnRFbGVtKHApOwotICAgIHAubV9oYXNWYXJpYWJsZURlY2wgPSB0cnVlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtV2hlbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1XaGVuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQxZjhjNmEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1XaGVuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBJbXBsZW1lbnQgeHNsOndoZW4uCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDp3aGVuICV0ZW1wbGF0ZTs+Ci0gKiA8IUFUVExJU1QgeHNsOndoZW4KLSAqICAgdGVzdCAlZXhwcjsgI1JFUVVJUkVECi0gKiAgICVzcGFjZS1hdHQ7Ci0gKiA+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUNvbmRpdGlvbmFsLVByb2Nlc3Npbmctd2l0aC14c2w6Y2hvb3NlIj5YWFggaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgRWxlbVdoZW4gZXh0ZW5kcyBFbGVtVGVtcGxhdGVFbGVtZW50Ci17Ci0KLSAgLyoqCi0gICAqIEVhY2ggeHNsOndoZW4gZWxlbWVudCBoYXMgYSBzaW5nbGUgYXR0cmlidXRlLCB0ZXN0LAotICAgKiB3aGljaCBzcGVjaWZpZXMgYW4gZXhwcmVzc2lvbi4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX3Rlc3Q7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInRlc3QiIGF0dHJpYnV0ZS4KLSAgICogRWFjaCB4c2w6d2hlbiBlbGVtZW50IGhhcyBhIHNpbmdsZSBhdHRyaWJ1dGUsIHRlc3QsCi0gICAqIHdoaWNoIHNwZWNpZmllcyBhbiBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gdiBWYWx1ZSB0byBzZXQgZm9yIHRoZSAidGVzdCIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VGVzdChYUGF0aCB2KQotICB7Ci0gICAgbV90ZXN0ID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJ0ZXN0IiBhdHRyaWJ1dGUuCi0gICAqIEVhY2ggeHNsOndoZW4gZWxlbWVudCBoYXMgYSBzaW5nbGUgYXR0cmlidXRlLCB0ZXN0LAotICAgKiB3aGljaCBzcGVjaWZpZXMgYW4gZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiB0aGUgInRlc3QiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBYUGF0aCBnZXRUZXN0KCkKLSAgewotICAgIHJldHVybiBtX3Rlc3Q7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQgdHlwZS4KLSAgICoKLSAgICogQHJldHVybiBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50LCBkZWZpbmVkIGluIHRoZQotICAgKiAgICAgQ29uc3RhbnRzIGNsYXNzLgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX1dIRU47Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciBldmVyeXRoaW5nIGVsc2UgaGFzIGJlZW4KLSAgICogcmVjb21wb3NlZCwgYW5kIGFsbG93cyB0aGUgdGVtcGxhdGUgdG8gc2V0IHJlbWFpbmluZwotICAgKiB2YWx1ZXMgdGhhdCBtYXkgYmUgYmFzZWQgb24gc29tZSBvdGhlciBwcm9wZXJ0eSB0aGF0Ci0gICAqIGRlcGVuZHMgb24gcmVjb21wb3NpdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgc3Jvb3QpIAotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldFZhcmlhYmxlTmFtZXMoKTsKLSAgICBpZihudWxsICE9IG1fdGVzdCkKLSAgICAgIG1fdGVzdC5maXh1cFZhcmlhYmxlcyh2bmFtZXMsIHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldEdsb2JhbHNTaXplKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9XSEVOX1NUUklORzsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBFbGVtV2hlbgotICAgKgotICAgKi8KLSAgcHVibGljIEVsZW1XaGVuKCl7fQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1XaXRoUGFyYW0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtV2l0aFBhcmFtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ2YmUxZDUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1XaXRoUGFyYW0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW1wbGVtZW50IHhzbDp3aXRoLXBhcmFtLiAgeHNsOndpdGgtcGFyYW0gaXMgYWxsb3dlZCB3aXRoaW4KLSAqIGJvdGggeHNsOmNhbGwtdGVtcGxhdGUgYW5kIHhzbDphcHBseS10ZW1wbGF0ZXMuCi0gKiA8cHJlPgotICogPCFFTEVNRU5UIHhzbDp3aXRoLXBhcmFtICV0ZW1wbGF0ZTs+Ci0gKiA8IUFUVExJU1QgeHNsOndpdGgtcGFyYW0KLSAqICAgbmFtZSAlcW5hbWU7ICNSRVFVSVJFRAotICogICBzZWxlY3QgJWV4cHI7ICNJTVBMSUVECi0gKiA+Ci0gKiA8L3ByZT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNlbGVtZW50LXdpdGgtcGFyYW0iPmVsZW1lbnQtd2l0aC1wYXJhbSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBFbGVtV2l0aFBhcmFtIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotICAvKioKLSAgICogVGhpcyBpcyB0aGUgaW5kZXggdG8gdGhlIHN0YWNrIGZyYW1lIGJlaW5nIGNhbGxlZCwgPGVtcGg+bm90PC9lbXBoPiB0aGUgCi0gICAqIHN0YWNrIGZyYW1lIHRoYXQgY29udGFpbnMgdGhpcyBlbGVtZW50LgotICAgKi8KLSAgaW50IG1faW5kZXg7Ci0KLSAgLyoqCi0gICAqIFRoZSAic2VsZWN0IiBhdHRyaWJ1dGUsIHdoaWNoIHNwZWNpZmllcyB0aGUgdmFsdWUgb2YgdGhlCi0gICAqIGFyZ3VtZW50LCBpZiBlbGVtZW50IGNvbnRlbnQgaXMgbm90IHNwZWNpZmllZC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX3NlbGVjdFBhdHRlcm4gPSBudWxsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4KLSAgICogVGhlICJzZWxlY3QiIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIHZhbHVlIG9mIHRoZQotICAgKiBhcmd1bWVudCwgaWYgZWxlbWVudCBjb250ZW50IGlzIG5vdCBzcGVjaWZpZWQuCi0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIHRvIHNldCBmb3IgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZS4gCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTZWxlY3QoWFBhdGggdikKLSAgewotICAgIG1fc2VsZWN0UGF0dGVybiA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuCi0gICAqIFRoZSAic2VsZWN0IiBhdHRyaWJ1dGUgc3BlY2lmaWVzIHRoZSB2YWx1ZSBvZiB0aGUKLSAgICogYXJndW1lbnQsIGlmIGVsZW1lbnQgY29udGVudCBpcyBub3Qgc3BlY2lmaWVkLgotICAgKgotICAgKiBAcmV0dXJuIFZhbHVlIG9mIHRoZSAic2VsZWN0IiBhdHRyaWJ1dGUuIAotICAgKi8KLSAgcHVibGljIFhQYXRoIGdldFNlbGVjdCgpCi0gIHsKLSAgICByZXR1cm4gbV9zZWxlY3RQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSByZXF1aXJlZCBuYW1lIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlCi0gICAqIHBhcmFtZXRlciAodGhlIHZhcmlhYmxlIHRoZSB2YWx1ZSBvZiB3aG9zZSBiaW5kaW5nIGlzCi0gICAqIHRvIGJlIHJlcGxhY2VkKS4gVGhlIHZhbHVlIG9mIHRoZSBuYW1lIGF0dHJpYnV0ZSBpcyBhIFFOYW1lLAotICAgKiB3aGljaCBpcyBleHBhbmRlZCBhcyBkZXNjcmliZWQgaW4gWzIuNCBRdWFsaWZpZWQgTmFtZXNdLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFFOYW1lIG1fcW5hbWUgPSBudWxsOwotICAKLSAgaW50IG1fcW5hbWVJRDsKLQotICAvKioKLSAgICogU2V0IHRoZSAibmFtZSIgYXR0cmlidXRlLgotICAgKiBESkQKLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IGZvciB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5hbWUoUU5hbWUgdikKLSAgewotICAgIG1fcW5hbWUgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogREpECi0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9xbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBvZiB0aGUgZWxlbWVudCB0eXBlLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQsIGRlZmluZWQgaW4gdGhlCi0gICAqICAgICBDb25zdGFudHMgY2xhc3MuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzCi0gICAqLwotICBwdWJsaWMgaW50IGdldFhTTFRva2VuKCkKLSAgewotICAgIHJldHVybiBDb25zdGFudHMuRUxFTU5BTUVfV0lUSFBBUkFNOwotICB9Ci0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5vZGUgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0gICAgcmV0dXJuIENvbnN0YW50cy5FTEVNTkFNRV9XSVRIUEFSQU1fU1RSSU5HOwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgZXZlcnl0aGluZyBlbHNlIGhhcyBiZWVuCi0gICAqIHJlY29tcG9zZWQsIGFuZCBhbGxvd3MgdGhlIHRlbXBsYXRlIHRvIHNldCByZW1haW5pbmcKLSAgICogdmFsdWVzIHRoYXQgbWF5IGJlIGJhc2VkIG9uIHNvbWUgb3RoZXIgcHJvcGVydHkgdGhhdAotICAgKiBkZXBlbmRzIG9uIHJlY29tcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21wb3NlKFN0eWxlc2hlZXRSb290IHNyb290KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIC8vIFNlZSBpZiB3ZSBjYW4gcmVkdWNlIGFuIFJURiB0byBhIHNlbGVjdCB3aXRoIGEgc3RyaW5nIGV4cHJlc3Npb24uCi0gICAgaWYobnVsbCA9PSBtX3NlbGVjdFBhdHRlcm4gIAotICAgICAgICYmIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlRyYW5zZm9ybWVyRmFjdG9yeUltcGwubV9vcHRpbWl6ZSkKLSAgICB7Ci0gICAgICBYUGF0aCBuZXdTZWxlY3QgPSBFbGVtVmFyaWFibGUucmV3cml0ZUNoaWxkVG9FeHByZXNzaW9uKHRoaXMpOwotICAgICAgaWYobnVsbCAhPSBuZXdTZWxlY3QpCi0gICAgICAgIG1fc2VsZWN0UGF0dGVybiA9IG5ld1NlbGVjdDsKLSAgICB9Ci0gICAgbV9xbmFtZUlEID0gc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCkuZ2V0UU5hbWVJRChtX3FuYW1lKTsKLSAgICBzdXBlci5jb21wb3NlKHNyb290KTsKLSAgICAKLSAgICBqYXZhLnV0aWwuVmVjdG9yIHZuYW1lcyA9IHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldFZhcmlhYmxlTmFtZXMoKTsKLSAgICBpZihudWxsICE9IG1fc2VsZWN0UGF0dGVybikKLSAgICAgIG1fc2VsZWN0UGF0dGVybi5maXh1cFZhcmlhYmxlcyh2bmFtZXMsIHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldEdsb2JhbHNTaXplKCkpOwotICAgICAgCi0gICAgLy8gbV9pbmRleCBtdXN0IGJlIHJlc29sdmVkIGJ5IEVsZW1BcHBseVRlbXBsYXRlcyBhbmQgRWxlbUNhbGxUZW1wbGF0ZSEKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgcGFyZW50IGFzIGFuIEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBwYXJlbnQgVGhpcyBub2RlJ3MgcGFyZW50IGFzIGFuIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFBhcmVudEVsZW0oRWxlbVRlbXBsYXRlRWxlbWVudCBwKQotICB7Ci0gICAgc3VwZXIuc2V0UGFyZW50RWxlbShwKTsKLSAgICBwLm1faGFzVmFyaWFibGVEZWNsID0gdHJ1ZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgWE9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRoZSBjdXJyZW50IHRyYW5zZm9ybS10aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IHNvdXJjZSBub2RlPC9hPi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgWE9iamVjdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGdldFZhbHVlKFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciwgaW50IHNvdXJjZU5vZGUpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhPYmplY3QgdmFyOwotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotCi0gICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKHNvdXJjZU5vZGUpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgIT0gbV9zZWxlY3RQYXR0ZXJuKQotICAgICAgewotICAgICAgICB2YXIgPSBtX3NlbGVjdFBhdHRlcm4uZXhlY3V0ZSh4Y3R4dCwgc291cmNlTm9kZSwgdGhpcyk7Ci0KLSAgICAgICAgdmFyLmFsbG93RGV0YWNoVG9SZWxlYXNlKGZhbHNlKTsKLQotICAgICAgICBpZiAoVHJhbnNmb3JtZXJJbXBsLlNfREVCVUcpCi0gICAgICAgICAgdHJhbnNmb3JtZXIuZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVNlbGVjdGVkRXZlbnQoc291cmNlTm9kZSwgdGhpcywKLSAgICAgICAgICAgICAgICAgICJzZWxlY3QiLCBtX3NlbGVjdFBhdHRlcm4sIHZhcik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChudWxsID09IGdldEZpcnN0Q2hpbGRFbGVtKCkpCi0gICAgICB7Ci0gICAgICAgIHZhciA9IFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gVXNlIHJlc3VsdCB0cmVlIGZyYWdtZW50Ci0gICAgICAgIGludCBkZiA9IHRyYW5zZm9ybWVyLnRyYW5zZm9ybVRvUlRGKHRoaXMpOwotCi0gICAgICAgIHZhciA9IG5ldyBYUlRyZWVGcmFnKGRmLCB4Y3R4dCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgIH0KLQotICAgIHJldHVybiB2YXI7Ci0gIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRnVuY0RvY3VtZW50LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRnVuY0RvY3VtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE0YTU1MWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0Z1bmNEb2N1bWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDk1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uMkFyZ3M7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguU291cmNlVHJlZU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TQVhTb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIERvYygpIGZ1bmN0aW9uLgotICoKLSAqIFdoZW4gdGhlIGRvY3VtZW50IGZ1bmN0aW9uIGhhcyBleGFjdGx5IG9uZSBhcmd1bWVudCBhbmQgdGhlIGFyZ3VtZW50Ci0gKiBpcyBhIG5vZGUtc2V0LCB0aGVuIHRoZSByZXN1bHQgaXMgdGhlIHVuaW9uLCBmb3IgZWFjaCBub2RlIGluIHRoZQotICogYXJndW1lbnQgbm9kZS1zZXQsIG9mIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgZG9jdW1lbnQgZnVuY3Rpb24gd2l0aAotICogdGhlIGZpcnN0IGFyZ3VtZW50IGJlaW5nIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIG5vZGUsIGFuZCB0aGUgc2Vjb25kCi0gKiBhcmd1bWVudCBiZWluZyBhIG5vZGUtc2V0IHdpdGggdGhlIG5vZGUgYXMgaXRzIG9ubHkgbWVtYmVyLiBXaGVuIHRoZQotICogZG9jdW1lbnQgZnVuY3Rpb24gaGFzIHR3byBhcmd1bWVudHMgYW5kIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhIG5vZGUtc2V0LAotICogdGhlbiB0aGUgcmVzdWx0IGlzIHRoZSB1bmlvbiwgZm9yIGVhY2ggbm9kZSBpbiB0aGUgYXJndW1lbnQgbm9kZS1zZXQsCi0gKiBvZiB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIGRvY3VtZW50IGZ1bmN0aW9uIHdpdGggdGhlIGZpcnN0IGFyZ3VtZW50Ci0gKiBiZWluZyB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBub2RlLCBhbmQgd2l0aCB0aGUgc2Vjb25kIGFyZ3VtZW50IGJlaW5nCi0gKiB0aGUgc2Vjb25kIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZG9jdW1lbnQgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jRG9jdW1lbnQgZXh0ZW5kcyBGdW5jdGlvbjJBcmdzCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgCi0gICAgaW50IGRvY0NvbnRleHQgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLSAgICBYT2JqZWN0IGFyZyA9IChYT2JqZWN0KSB0aGlzLmdldEFyZzAoKS5leGVjdXRlKHhjdHh0KTsKLQotICAgIFN0cmluZyBiYXNlID0gIiI7Ci0gICAgRXhwcmVzc2lvbiBhcmcxRXhwciA9IHRoaXMuZ2V0QXJnMSgpOwotCi0gICAgaWYgKG51bGwgIT0gYXJnMUV4cHIpCi0gICAgewotCi0gICAgICAvLyBUaGUgVVJJIHJlZmVyZW5jZSBtYXkgYmUgcmVsYXRpdmUuIFRoZSBiYXNlIFVSSSAoc2VlIFszLjIgQmFzZSBVUkldKSAKLSAgICAgIC8vIG9mIHRoZSBub2RlIGluIHRoZSBzZWNvbmQgYXJndW1lbnQgbm9kZS1zZXQgdGhhdCBpcyBmaXJzdCBpbiBkb2N1bWVudCAKLSAgICAgIC8vIG9yZGVyIGlzIHVzZWQgYXMgdGhlIGJhc2UgVVJJIGZvciByZXNvbHZpbmcgdGhlIAotICAgICAgLy8gcmVsYXRpdmUgVVJJIGludG8gYW4gYWJzb2x1dGUgVVJJLiAKLSAgICAgIFhPYmplY3QgYXJnMiA9IGFyZzFFeHByLmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICBpZiAoWE9iamVjdC5DTEFTU19OT0RFU0VUID09IGFyZzIuZ2V0VHlwZSgpKQotICAgICAgewotICAgICAgICBpbnQgYmFzZU5vZGUgPSBhcmcyLml0ZXIoKS5uZXh0Tm9kZSgpOwotCi0gICAgICAgIGlmIChiYXNlTm9kZSA9PSBEVE0uTlVMTCkKLSAgICAgICAgICB3YXJuKHhjdHh0LCBYU0xURXJyb3JSZXNvdXJjZXMuV0dfRU1QVFlfU0VDT05EX0FSRywgbnVsbCk7Ci0gICAgICAgIAotICAgICAgICBEVE0gYmFzZURUTSA9IHhjdHh0LmdldERUTShiYXNlTm9kZSk7Ci0gICAgICAgIGJhc2UgPSBiYXNlRFRNLmdldERvY3VtZW50QmFzZVVSSSgpOwotCi0gICAgICAgIC8vICVSRVZJRVclIFRoaXMgZG9lc24ndCBzZWVtIHRvIGJlIGEgcHJvYmxlbSB3aXRoIHRoZSBjb25mb3JtYW5jZQotICAgICAgICAvLyBzdWl0ZSwgYnV0IG1heWJlIGl0J3MganVzdCBub3QgZG9pbmcgYSBnb29kIHRlc3Q/Ci0vLyAgICAgICAgaW50IGJhc2VEb2MgPSBiYXNlRFRNLmdldERvY3VtZW50KCk7Ci0vLwotLy8gICAgICAgIGlmIChiYXNlRG9jID09IERUTS5OVUxMIC8qIHx8IGJhc2VEb2MgaW5zdGFuY2VvZiBTdHlsZXNoZWV0ICAtLT5XaGF0IHRvIGRvPz8gKi8pCi0vLyAgICAgICAgewotLy8KLS8vICAgICAgICAgIC8vIGJhc2UgPSAoKFN0eWxlc2hlZXQpYmFzZURvYykuZ2V0QmFzZUlkZW50aWZpZXIoKTsKLS8vICAgICAgICAgIGJhc2UgPSB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0QmFzZUlkZW50aWZpZXIoKTsKLS8vICAgICAgICB9Ci0vLyAgICAgICAgZWxzZQotLy8gICAgICAgICAgYmFzZSA9IHhjdHh0LmdldFNvdXJjZVRyZWVNYW5hZ2VyKCkuZmluZFVSSUZyb21Eb2MoYmFzZURvYyk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGJhc2UgPSBhcmcyLnN0cigpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIG9taXR0ZWQsIHRoZW4gaXQgZGVmYXVsdHMgdG8gCi0gICAgICAvLyB0aGUgbm9kZSBpbiB0aGUgc3R5bGVzaGVldCB0aGF0IGNvbnRhaW5zIHRoZSBleHByZXNzaW9uIHRoYXQgCi0gICAgICAvLyBpbmNsdWRlcyB0aGUgY2FsbCB0byB0aGUgZG9jdW1lbnQgZnVuY3Rpb24uIE5vdGUgdGhhdCBhIAotICAgICAgLy8gemVyby1sZW5ndGggVVJJIHJlZmVyZW5jZSBpcyBhIHJlZmVyZW5jZSB0byB0aGUgZG9jdW1lbnQgCi0gICAgICAvLyByZWxhdGl2ZSB0byB3aGljaCB0aGUgVVJJIHJlZmVyZW5jZSBpcyBiZWluZyByZXNvbHZlZDsgdGh1cyAKLSAgICAgIC8vIGRvY3VtZW50KCIiKSByZWZlcnMgdG8gdGhlIHJvb3Qgbm9kZSBvZiB0aGUgc3R5bGVzaGVldDsgCi0gICAgICAvLyB0aGUgdHJlZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3R5bGVzaGVldCBpcyBleGFjdGx5IAotICAgICAgLy8gdGhlIHNhbWUgYXMgaWYgdGhlIFhNTCBkb2N1bWVudCBjb250YWluaW5nIHRoZSBzdHlsZXNoZWV0IAotICAgICAgLy8gd2FzIHRoZSBpbml0aWFsIHNvdXJjZSBkb2N1bWVudC4KLSAgICAgIGJhc2UgPSB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0QmFzZUlkZW50aWZpZXIoKTsKLSAgICB9Ci0KLSAgICBYTm9kZVNldCBub2RlcyA9IG5ldyBYTm9kZVNldCh4Y3R4dC5nZXREVE1NYW5hZ2VyKCkpOwotICAgIE5vZGVTZXREVE0gbW5sID0gbm9kZXMubXV0YWJsZU5vZGVzZXQoKTsKLSAgICBEVE1JdGVyYXRvciBpdGVyYXRvciA9IChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gYXJnLmdldFR5cGUoKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZy5pdGVyKCkgOiBudWxsOwotICAgIGludCBwb3MgPSBEVE0uTlVMTDsKLQotICAgIHdoaWxlICgobnVsbCA9PSBpdGVyYXRvcikgfHwgKERUTS5OVUxMICE9IChwb3MgPSBpdGVyYXRvci5uZXh0Tm9kZSgpKSkpCi0gICAgewotICAgICAgWE1MU3RyaW5nIHJlZiA9IChudWxsICE9IGl0ZXJhdG9yKQotICAgICAgICAgICAgICAgICAgID8geGN0eHQuZ2V0RFRNKHBvcykuZ2V0U3RyaW5nVmFsdWUocG9zKSA6IGFyZy54c3RyKCk7Ci0gICAgICAKLSAgICAgIC8vIFRoZSBmaXJzdCBhbmQgb25seSBhcmd1bWVudCB3YXMgYSBub2Rlc2V0LCB0aGUgYmFzZSBpbiB0aGF0Ci0gICAgICAvLyBjYXNlIGlzIHRoZSBiYXNlIFVSSSBvZiB0aGUgbm9kZSBmcm9tIHRoZSBmaXJzdCBhcmd1bWVudCBub2Rlc2V0LiAKLSAgICAgIC8vIFJlbWVtYmVyLCB3aGVuIHRoZSBkb2N1bWVudCBmdW5jdGlvbiBoYXMgZXhhY3RseSBvbmUgYXJndW1lbnQgYW5kCi0gICAgICAvLyB0aGUgYXJndW1lbnQgaXMgYSBub2RlLXNldCwgdGhlbiB0aGUgcmVzdWx0IGlzIHRoZSB1bmlvbiwgZm9yIGVhY2gKLSAgICAgIC8vIG5vZGUgaW4gdGhlIGFyZ3VtZW50IG5vZGUtc2V0LCBvZiB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIGRvY3VtZW50Ci0gICAgICAvLyBmdW5jdGlvbiB3aXRoIHRoZSBmaXJzdCBhcmd1bWVudCBiZWluZyB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBub2RlLAotICAgICAgLy8gYW5kIHRoZSBzZWNvbmQgYXJndW1lbnQgYmVpbmcgYSBub2RlLXNldCB3aXRoIHRoZSBub2RlIGFzIGl0cyBvbmx5IAotICAgICAgLy8gbWVtYmVyLgotICAgICAgaWYgKG51bGwgPT0gYXJnMUV4cHIgJiYgRFRNLk5VTEwgIT0gcG9zKQotICAgICAgewotICAgICAgICBEVE0gYmFzZURUTSA9IHhjdHh0LmdldERUTShwb3MpOwotICAgICAgICBiYXNlID0gYmFzZURUTS5nZXREb2N1bWVudEJhc2VVUkkoKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG51bGwgPT0gcmVmKQotICAgICAgICBjb250aW51ZTsKLQotICAgICAgaWYgKERUTS5OVUxMID09IGRvY0NvbnRleHQpCi0gICAgICB7Ci0gICAgICAgIGVycm9yKHhjdHh0LCBYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fQ09OVEVYVF9PV05FUkRPQywgbnVsbCk7ICAvLyJjb250ZXh0IGRvZXMgbm90IGhhdmUgYW4gb3duZXIgZG9jdW1lbnQhIik7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEZyb20gaHR0cDovL3d3dy5pY3MudWNpLmVkdS9wdWIvaWV0Zi91cmkvcmZjMTYzMC50eHQKLSAgICAgIC8vIEEgcGFydGlhbCBmb3JtIGNhbiBiZSBkaXN0aW5ndWlzaGVkIGZyb20gYW4gYWJzb2x1dGUgZm9ybSBpbiB0aGF0IHRoZQotICAgICAgLy8gbGF0dGVyIG11c3QgaGF2ZSBhIGNvbG9uIGFuZCB0aGF0IGNvbG9uIG11c3Qgb2NjdXIgYmVmb3JlIGFueSBzbGFzaAotICAgICAgLy8gY2hhcmFjdGVycy4gU3lzdGVtcyBub3QgcmVxdWlyaW5nIHBhcnRpYWwgZm9ybXMgc2hvdWxkIG5vdCB1c2UgYW55Ci0gICAgICAvLyB1bmVuY29kZWQgc2xhc2hlcyBpbiB0aGVpciBuYW1pbmcgc2NoZW1lcy4gIElmIHRoZXkgZG8sIGFic29sdXRlIFVSSXMKLSAgICAgIC8vIHdpbGwgc3RpbGwgd29yaywgYnV0IGNvbmZ1c2lvbiBtYXkgcmVzdWx0LgotICAgICAgaW50IGluZGV4T2ZDb2xvbiA9IHJlZi5pbmRleE9mKCc6Jyk7Ci0gICAgICBpbnQgaW5kZXhPZlNsYXNoID0gcmVmLmluZGV4T2YoJy8nKTsKLQotICAgICAgaWYgKChpbmRleE9mQ29sb24gIT0gLTEpICYmIChpbmRleE9mU2xhc2ggIT0gLTEpCi0gICAgICAgICAgICAgICYmIChpbmRleE9mQ29sb24gPCBpbmRleE9mU2xhc2gpKQotICAgICAgewotCi0gICAgICAgIC8vIFRoZSB1cmwgKG9yIGZpbGVuYW1lLCBmb3IgdGhhdCBtYXR0ZXIpIGlzIGFic29sdXRlLgotICAgICAgICBiYXNlID0gbnVsbDsKLSAgICAgIH0KLQotICAgICAgaW50IG5ld0RvYyA9IGdldERvYyh4Y3R4dCwgY29udGV4dCwgcmVmLnRvU3RyaW5nKCksIGJhc2UpOwotCi0gICAgICAvLyBub2Rlcy5tdXRhYmxlTm9kZXNldCgpLmFkZE5vZGUobmV3RG9jKTsgIAotICAgICAgaWYgKERUTS5OVUxMICE9IG5ld0RvYykKLSAgICAgIHsKLSAgICAgICAgLy8gVE9ETzogbW5sLmFkZE5vZGVJbkRvY09yZGVyKG5ld0RvYywgdHJ1ZSwgeGN0eHQpOyA/PwotICAgICAgICBpZiAoIW1ubC5jb250YWlucyhuZXdEb2MpKQotICAgICAgICB7Ci0gICAgICAgICAgbW5sLmFkZEVsZW1lbnQobmV3RG9jKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobnVsbCA9PSBpdGVyYXRvciB8fCBuZXdEb2MgPT0gRFRNLk5VTEwpCi0gICAgICAgIGJyZWFrOwotICAgIH0KLQotICAgIHJldHVybiBub2RlczsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGRvY3VtZW50IGZyb20gdGhlIGdpdmVuIFVSSSBhbmQgYmFzZQotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZQotICAgKiBAcGFyYW0gdXJpIFJlbGF0aXZlKD8pIFVSSSBvZiB0aGUgZG9jdW1lbnQKLSAgICogQHBhcmFtIGJhc2UgQmFzZSB0byByZXNvbHZlIHJlbGF0aXZlIFVSSSBmcm9tLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkb2N1bWVudCBOb2RlIHBvaW50aW5nIHRvIHRoZSBkb2N1bWVudCBhdCB0aGUgZ2l2ZW4gVVJJCi0gICAqIG9yIG51bGwKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBpbnQgZ2V0RG9jKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQsIFN0cmluZyB1cmksIFN0cmluZyBiYXNlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYmFzZTogIitiYXNlKyIsIHVyaTogIit1cmkpOwotICAgIFNvdXJjZVRyZWVNYW5hZ2VyIHRyZWVNZ3IgPSB4Y3R4dC5nZXRTb3VyY2VUcmVlTWFuYWdlcigpOwotICAgIFNvdXJjZSBzb3VyY2U7Ci0gICAKLSAgICBpbnQgbmV3RG9jOwotICAgIHRyeQotICAgIHsKLSAgICAgIHNvdXJjZSA9IHRyZWVNZ3IucmVzb2x2ZVVSSShiYXNlLCB1cmksIHhjdHh0LmdldFNBWExvY2F0b3IoKSk7Ci0gICAgICBuZXdEb2MgPSB0cmVlTWdyLmdldE5vZGUoc291cmNlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oaW9lLmdldE1lc3NhZ2UoKSwgCi0gICAgICAgIChTb3VyY2VMb2NhdG9yKXhjdHh0LmdldFNBWExvY2F0b3IoKSwgaW9lKTsKLSAgICB9Ci0gICAgY2F0Y2goVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gbmV3RG9jKQotICAgICAgcmV0dXJuIG5ld0RvYzsKLQotICAgIC8vIElmIHRoZSB1cmkgbGVuZ3RoIGlzIHplcm8sIGdldCB0aGUgdXJpIG9mIHRoZSBzdHlsZXNoZWV0LgotICAgIGlmICh1cmkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICAvLyBIbW1tLi4uIHRoaXMgc2VlbXMgcHJldHR5IGJvZ3VzIHRvIG1lLi4uIC1zYgotICAgICAgdXJpID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLmdldEJhc2VJZGVudGlmaWVyKCk7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgc291cmNlID0gdHJlZU1nci5yZXNvbHZlVVJJKGJhc2UsIHVyaSwgeGN0eHQuZ2V0U0FYTG9jYXRvcigpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihpb2UuZ2V0TWVzc2FnZSgpLCAKLSAgICAgICAgICAoU291cmNlTG9jYXRvcil4Y3R4dC5nZXRTQVhMb2NhdG9yKCksIGlvZSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgU3RyaW5nIGRpYWdub3N0aWNzU3RyaW5nID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmICgobnVsbCAhPSB1cmkpICYmICh1cmkudG9TdHJpbmcoKS5sZW5ndGgoKSA+IDApKQotICAgICAgewotICAgICAgICBuZXdEb2MgPSB0cmVlTWdyLmdldFNvdXJjZVRyZWUoc291cmNlLCB4Y3R4dC5nZXRTQVhMb2NhdG9yKCksIHhjdHh0KTsKLQotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm5ld0RvYzogIisoKERvY3VtZW50KW5ld0RvYykuZ2V0RG9jdW1lbnRFbGVtZW50KCkuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHdhcm4oeGN0eHQsIFhTTFRFcnJvclJlc291cmNlcy5XR19DQU5OT1RfTUFLRV9VUkxfRlJPTSwKLSAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICgoYmFzZSA9PSBudWxsKSA/ICIiIDogYmFzZSkgKyB1cmkgfSk7ICAvLyJDYW4gbm90IG1ha2UgVVJMIGZyb206ICIrKChiYXNlID09IG51bGwpID8gIiIgOiBiYXNlICkrdXJpKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFRocm93YWJsZSB0aHJvd2FibGUpCi0gICAgewotCi0gICAgICAvLyB0aHJvd2FibGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICBuZXdEb2MgPSBEVE0uTlVMTDsKLQotICAgICAgLy8gcGF0aC53YXJuKFhTTFRFcnJvclJlc291cmNlcy5XR19FTkNPRElOR19OT1RfU1VQUE9SVEVEX1VTSU5HX0pBVkEsIG5ldyBPYmplY3RbXXsoKGJhc2UgPT0gbnVsbCkgPyAiIiA6IGJhc2UgKSt1cml9KTsgLy8iQ2FuIG5vdCBsb2FkIHJlcXVlc3RlZCBkb2M6ICIrKChiYXNlID09IG51bGwpID8gIiIgOiBiYXNlICkrdXJpKTsKLSAgICAgIHdoaWxlICh0aHJvd2FibGUKLSAgICAgICAgICAgICBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICB0aHJvd2FibGUgPQotICAgICAgICAgICgob3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pIHRocm93YWJsZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIGlmICgodGhyb3dhYmxlIGluc3RhbmNlb2YgTnVsbFBvaW50ZXJFeGNlcHRpb24pCi0gICAgICAgICAgICAgIHx8ICh0aHJvd2FibGUgaW5zdGFuY2VvZiBDbGFzc0Nhc3RFeGNlcHRpb24pKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICAgKEV4Y2VwdGlvbikgdGhyb3dhYmxlKTsKLSAgICAgIH0KLQotICAgICAgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOwotICAgICAgUHJpbnRXcml0ZXIgZGlhZ25vc3RpY3NXcml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIoc3cpOwotCi0gICAgICBpZiAodGhyb3dhYmxlIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHNwZSA9IChUcmFuc2Zvcm1lckV4Y2VwdGlvbikgdGhyb3dhYmxlOwotCi0gICAgICAgIHsKLSAgICAgICAgICBUaHJvd2FibGUgZSA9IHNwZTsKLQotICAgICAgICAgIHdoaWxlIChudWxsICE9IGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKG51bGwgIT0gZS5nZXRNZXNzYWdlKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGRpYWdub3N0aWNzV3JpdGVyLnByaW50bG4oIiAoIiArIGUuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiKTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzcGUyID0gKFRyYW5zZm9ybWVyRXhjZXB0aW9uKSBlOwotCi0gICAgICAgICAgICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9IHNwZTIuZ2V0TG9jYXRvcigpOwotICAgICAgICAgICAgICBpZiAoKG51bGwgIT0gbG9jYXRvcikgJiYgKG51bGwgIT0gbG9jYXRvci5nZXRTeXN0ZW1JZCgpKSkKLSAgICAgICAgICAgICAgICBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKCIgICBJRDogIiArIGxvY2F0b3IuZ2V0U3lzdGVtSWQoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIExpbmUgIyIgKyBsb2NhdG9yLmdldExpbmVOdW1iZXIoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIENvbHVtbiAjIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBsb2NhdG9yLmdldENvbHVtbk51bWJlcigpKTsKLQotICAgICAgICAgICAgICBlID0gc3BlMi5nZXRFeGNlcHRpb24oKTsKLQotICAgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgICAgICAgICAgIGUgPSAoKG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKSBlKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgZSA9IG51bGw7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGRpYWdub3N0aWNzV3JpdGVyLnByaW50bG4oIiAoIiArIHRocm93YWJsZS5nZXRDbGFzcygpLmdldE5hbWUoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIik6ICIgKyB0aHJvd2FibGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgIH0KLQotICAgICAgZGlhZ25vc3RpY3NTdHJpbmcgPSB0aHJvd2FibGUuZ2V0TWVzc2FnZSgpOyAvL3N3LnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgaWYgKERUTS5OVUxMID09IG5ld0RvYykKLSAgICB7Ci0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2hhdD86ICIrYmFzZSsiLCB1cmk6ICIrdXJpKTsKLSAgICAgIGlmIChudWxsICE9IGRpYWdub3N0aWNzU3RyaW5nKQotICAgICAgewotICAgICAgICB3YXJuKHhjdHh0LCBYU0xURXJyb3JSZXNvdXJjZXMuV0dfQ0FOTk9UX0xPQURfUkVRVUVTVEVEX0RPQywKLSAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGRpYWdub3N0aWNzU3RyaW5nIH0pOyAgLy8iQ2FuIG5vdCBsb2FkIHJlcXVlc3RlZCBkb2M6ICIrKChiYXNlID09IG51bGwpID8gIiIgOiBiYXNlICkrdXJpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgd2Fybih4Y3R4dCwgWFNMVEVycm9yUmVzb3VyY2VzLldHX0NBTk5PVF9MT0FEX1JFUVVFU1RFRF9ET0MsCi0gICAgICAgICAgICAgbmV3IE9iamVjdFtdewotICAgICAgICAgICAgICAgdXJpID09IG51bGwKLSAgICAgICAgICAgICAgID8gKChiYXNlID09IG51bGwpID8gIiIgOiBiYXNlKSArIHVyaSA6IHVyaS50b1N0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBsb2FkIHJlcXVlc3RlZCBkb2M6ICIrKChiYXNlID09IG51bGwpID8gIiIgOiBiYXNlICkrdXJpKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vICVSRVZJRVclCi0gICAgICAvLyBUQkQ6IFdoYXQgdG8gZG8gYWJvdXQgWExvY2F0b3I/Ci0gICAgICAvLyB4Y3R4dC5nZXRTb3VyY2VUcmVlTWFuYWdlcigpLmFzc29jaWF0ZVhMb2NhdG9yVG9Ob2RlKG5ld0RvYywgdXJsLCBudWxsKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3RG9jOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBjb2RlCi0gICAqIEBwYXJhbSBhcmdzIEFyZ3VtZW50cyB0byBiZSB1c2VkIGluIHRoZSBlcnJvciBtZXNzYWdlCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IG1zZywgT2JqZWN0IGFyZ3NbXSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgZm9ybWF0dGVkTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShtc2csIGFyZ3MpOwotICAgIEVycm9yTGlzdGVuZXIgZXJySGFuZGxlciA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzcGUgPSBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNvdXJjZUxvY2F0b3IpeGN0eHQuZ2V0U0FYTG9jYXRvcigpKTsKLQotICAgIGlmIChudWxsICE9IGVyckhhbmRsZXIpCi0gICAgICBlcnJIYW5kbGVyLmVycm9yKHNwZSk7Ci0gICAgZWxzZQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdHRlZE1zZyk7Ci0gIH0KLQotICAvKioKLSAgICogV2FybiB0aGUgdXNlciBvZiBhIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIG1zZyBXYXJuaW5nIG1lc3NhZ2UgY29kZQotICAgKiBAcGFyYW0gYXJncyBBcmd1bWVudHMgdG8gYmUgdXNlZCBpbiB0aGUgd2FybmluZyBtZXNzYWdlCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm4oWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgbXNnLCBPYmplY3QgYXJnc1tdKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmb3JtYXR0ZWRNc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVXYXJuaW5nKG1zZywgYXJncyk7Ci0gICAgRXJyb3JMaXN0ZW5lciBlcnJIYW5kbGVyID0geGN0eHQuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHNwZSA9IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmb3JtYXR0ZWRNc2csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU291cmNlTG9jYXRvcil4Y3R4dC5nZXRTQVhMb2NhdG9yKCkpOwotCi0gICAgaWYgKG51bGwgIT0gZXJySGFuZGxlcikKLSAgICAgIGVyckhhbmRsZXIud2FybmluZyhzcGUpOwotICAgIGVsc2UKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihmb3JtYXR0ZWRNc2cpOwotICB9Ci0KLSAvKioKLSAgICogT3ZlcmlkZSB0aGUgc3VwZXJjbGFzcyBtZXRob2QgdG8gYWxsb3cgb25lIG9yIHR3byBhcmd1bWVudHMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gTnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgaW4gdG8gdGhpcyBmdW5jdGlvbgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIGlmICgoYXJnTnVtIDwgMSkgfHwgKGFyZ051bSA+IDIpKQotICAgICAgdGhyb3cgbmV3IFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9PTkVfT1JfVFdPLCBudWxsKSk7IC8vIjEgb3IgMiIpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIEluIG90aGVyIHdvcmRzLCB0ZWxsIAotICAgKiBpZiB5b3UgY2FuIGV4ZWN1dGUge0BsaW5rIGFzTm9kZSgpIGFzTm9kZX0gd2l0aG91dCBhbiBleGNlcHRpb24uCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZXhwcmVzc2lvbiBjYW4gYmUgcmVwcmVzZW50ZWQgYXMgYSBub2Rlc2V0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2Rlc2V0RXhwcigpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRnVuY0Zvcm1hdE51bWIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9GdW5jRm9ybWF0TnVtYi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMWRmMGM5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9GdW5jRm9ybWF0TnVtYi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uM0FyZ3M7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TQVhTb3VyY2VMb2NhdG9yOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgRm9ybWF0TnVtYmVyKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jRm9ybWF0TnVtYiBleHRlbmRzIEZ1bmN0aW9uM0FyZ3MKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEEgYml0IG9mIGFuIHVnbHkgaGFjayB0byBnZXQgb3VyIGNvbnRleHQuCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCB0ZW1wbEVsZW0gPQotICAgICAgKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICBTdHlsZXNoZWV0Um9vdCBzcyA9IHRlbXBsRWxlbS5nZXRTdHlsZXNoZWV0Um9vdCgpOwotICAgIGphdmEudGV4dC5EZWNpbWFsRm9ybWF0IGZvcm1hdHRlciA9IG51bGw7Ci0gICAgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzIGRmcyA9IG51bGw7Ci0gICAgZG91YmxlIG51bSA9IGdldEFyZzAoKS5leGVjdXRlKHhjdHh0KS5udW0oKTsKLSAgICBTdHJpbmcgcGF0dGVyblN0ciA9IGdldEFyZzEoKS5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLQotICAgIC8vIFRPRE86IHdoYXQgc2hvdWxkIGJlIHRoZSBiZWhhdmlvciBoZXJlPz8KLSAgICBpZiAocGF0dGVyblN0ci5pbmRleE9mKDB4MDBBNCkgPiAwKQotICAgICAgc3MuZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NVUlJFTkNZX1NJR05fSUxMRUdBTCk7ICAvLyBjdXJyZW5jeSBzaWduIG5vdCBhbGxvd2VkCi0KLSAgICAvLyB0aGlzIHRoaXJkIGFyZ3VtZW50IGlzIG5vdCBhIGxvY2FsZSBuYW1lLiBJdCBpcyB0aGUgbmFtZSBvZiBhCi0gICAgLy8gZGVjaW1hbC1mb3JtYXQgZGVjbGFyZWQgaW4gdGhlIHN0eWxlc2hlZXQhKHhzbDpkZWNpbWFsLWZvcm1hdAotICAgIHRyeQotICAgIHsKLSAgICAgIEV4cHJlc3Npb24gYXJnMkV4cHIgPSBnZXRBcmcyKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGFyZzJFeHByKQotICAgICAgewotICAgICAgICBTdHJpbmcgZGZOYW1lID0gYXJnMkV4cHIuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgICAgIFFOYW1lIHFuYW1lID0gbmV3IFFOYW1lKGRmTmFtZSwgeGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpKTsKLQotICAgICAgICBkZnMgPSBzcy5nZXREZWNpbWFsRm9ybWF0Q29tcG9zZWQocW5hbWUpOwotCi0gICAgICAgIGlmIChudWxsID09IGRmcykKLSAgICAgICAgewotICAgICAgICAgIHdhcm4oeGN0eHQsIFhTTFRFcnJvclJlc291cmNlcy5XR19OT19ERUNJTUFMRk9STUFUX0RFQ0xBUkFUSU9OLAotICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBkZk5hbWUgfSk7ICAvLyJub3QgZm91bmQhISEKLQotICAgICAgICAgIC8vZm9ybWF0dGVyID0gbmV3IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0KHBhdHRlcm5TdHIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotCi0gICAgICAgICAgLy9mb3JtYXR0ZXIgPSBuZXcgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQocGF0dGVyblN0ciwgZGZzKTsKLSAgICAgICAgICBmb3JtYXR0ZXIgPSBuZXcgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQoKTsKLQotICAgICAgICAgIGZvcm1hdHRlci5zZXREZWNpbWFsRm9ybWF0U3ltYm9scyhkZnMpOwotICAgICAgICAgIGZvcm1hdHRlci5hcHBseUxvY2FsaXplZFBhdHRlcm4ocGF0dGVyblN0cik7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy9lbHNlCi0gICAgICBpZiAobnVsbCA9PSBmb3JtYXR0ZXIpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gbG9vayBmb3IgYSBwb3NzaWJsZSBkZWZhdWx0IGRlY2ltYWwtZm9ybWF0Ci0gICAgICAgIGlmIChzcy5nZXREZWNpbWFsRm9ybWF0Q291bnQoKSA+IDApCi0gICAgICAgICAgZGZzID0gc3MuZ2V0RGVjaW1hbEZvcm1hdENvbXBvc2VkKG5ldyBRTmFtZSgiIikpOwotCi0gICAgICAgIGlmIChkZnMgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIGZvcm1hdHRlciA9IG5ldyBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdCgpOwotCi0gICAgICAgICAgZm9ybWF0dGVyLnNldERlY2ltYWxGb3JtYXRTeW1ib2xzKGRmcyk7Ci0gICAgICAgICAgZm9ybWF0dGVyLmFwcGx5TG9jYWxpemVkUGF0dGVybihwYXR0ZXJuU3RyKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBkZnMgPSBuZXcgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzKGphdmEudXRpbC5Mb2NhbGUuVVMpOwotCi0gICAgICAgICAgZGZzLnNldEluZmluaXR5KENvbnN0YW50cy5BVFRSVkFMX0lORklOSVRZKTsKLSAgICAgICAgICBkZnMuc2V0TmFOKENvbnN0YW50cy5BVFRSVkFMX05BTik7Ci0KLSAgICAgICAgICBmb3JtYXR0ZXIgPSBuZXcgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQoKTsKLQotICAgICAgICAgIGZvcm1hdHRlci5zZXREZWNpbWFsRm9ybWF0U3ltYm9scyhkZnMpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gcGF0dGVyblN0cikKLSAgICAgICAgICAgIGZvcm1hdHRlci5hcHBseUxvY2FsaXplZFBhdHRlcm4ocGF0dGVyblN0cik7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG5ldyBYU3RyaW5nKGZvcm1hdHRlci5mb3JtYXQobnVtKSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gaWFlKQotICAgIHsKLSAgICAgIHRlbXBsRWxlbS5lcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfTUFMRk9STUVEX0ZPUk1BVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwYXR0ZXJuU3RyIH0pOwotCi0gICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLQotICAgICAgLy90aHJvdyBuZXcgWFNMUHJvY2Vzc29yRXhjZXB0aW9uKGlhZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYSBwcm9ibGVtLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSBtc2cgV2FybmluZyBtZXNzYWdlIGNvZGUKLSAgICogQHBhcmFtIGFyZ3MgQXJndW1lbnRzIHRvIGJlIHVzZWQgaW4gd2FybmluZyBtZXNzYWdlCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm4oWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgbXNnLCBPYmplY3QgYXJnc1tdKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBmb3JtYXR0ZWRNc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVXYXJuaW5nKG1zZywgYXJncyk7Ci0gICAgRXJyb3JMaXN0ZW5lciBlcnJIYW5kbGVyID0geGN0eHQuZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0gICAgZXJySGFuZGxlci53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmb3JtYXR0ZWRNc2csCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU0FYU291cmNlTG9jYXRvcil4Y3R4dC5nZXRTQVhMb2NhdG9yKCkpKTsKLSAgfQotCi0gIC8qKgotICAgKiBPdmVyaWRlIHRoZSBzdXBlcmNsYXNzIG1ldGhvZCB0byBhbGxvdyBvbmUgb3IgdHdvIGFyZ3VtZW50cy4gCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gTnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgaW4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoZWNrTnVtYmVyQXJncyhpbnQgYXJnTnVtKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoKGFyZ051bSA+IDMpIHx8IChhcmdOdW0gPCAyKSkKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfVFdPX09SX1RIUkVFLCBudWxsKSk7IC8vIjIgb3IgMyIpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRnVuY0tleS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0Z1bmNLZXkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGJlY2MxMi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRnVuY0tleS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuRnVuY3Rpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuRnVuY3Rpb24yQXJnczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5VbmlvblBhdGhJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLktleU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgS2V5KCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jS2V5IGV4dGVuZHMgRnVuY3Rpb24yQXJncwotewotCi0gIC8qKiBEdW1teSB2YWx1ZSB0byBiZSB1c2VkIGluIHVzZWRyZWZzIGhhc2h0YWJsZSAgICAgICAgICAgKi8KLSAgc3RhdGljIHByaXZhdGUgQm9vbGVhbiBJU1RSVUUgPSBuZXcgQm9vbGVhbih0cnVlKTsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciA9IChUcmFuc2Zvcm1lckltcGwpeGN0eHQ7Ci0gICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyID0gKFRyYW5zZm9ybWVySW1wbCkgeGN0eHQuZ2V0T3duZXJPYmplY3QoKTsKLSAgICBYTm9kZVNldCBub2RlcyA9IG51bGw7Ci0gICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgaW50IGRvY0NvbnRleHQgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLQotICAgIGlmIChEVE0uTlVMTCA9PSBkb2NDb250ZXh0KQotICAgIHsKLQotICAgICAgLy8gcGF0aC5lcnJvcihjb250ZXh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DKTsgLy8iY29udGV4dCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISIpOwotICAgIH0KLQotICAgIFN0cmluZyB4a2V5bmFtZSA9IGdldEFyZzAoKS5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBRTmFtZSBrZXluYW1lID0gbmV3IFFOYW1lKHhrZXluYW1lLCB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkpOwotICAgIFhPYmplY3QgYXJnID0gZ2V0QXJnMSgpLmV4ZWN1dGUoeGN0eHQpOwotICAgIGJvb2xlYW4gYXJnSXNOb2RlU2V0RFRNID0gKFhPYmplY3QuQ0xBU1NfTk9ERVNFVCA9PSBhcmcuZ2V0VHlwZSgpKTsKLSAgICBLZXlNYW5hZ2VyIGttZ3IgPSB0cmFuc2Zvcm1lci5nZXRLZXlNYW5hZ2VyKCk7Ci0KLSAgICBpZiAoYXJnSXNOb2RlU2V0RFRNKQotICAgIHsKLSAgICAgIEhhc2h0YWJsZSB1c2VkcmVmcyA9IG51bGw7Ci0gICAgICBEVE1JdGVyYXRvciBuaSA9IGFyZy5pdGVyKCk7Ci0gICAgICBpbnQgcG9zOwotICAgICAgVW5pb25QYXRoSXRlcmF0b3IgdXBpID0gbmV3IFVuaW9uUGF0aEl0ZXJhdG9yKCk7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAocG9zID0gbmkubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGR0bSA9IHhjdHh0LmdldERUTShwb3MpOwotICAgICAgICBYTUxTdHJpbmcgcmVmID0gZHRtLmdldFN0cmluZ1ZhbHVlKHBvcyk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gcmVmKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIGlmIChudWxsID09IHVzZWRyZWZzKQotICAgICAgICAgIHVzZWRyZWZzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgICAgIGlmICh1c2VkcmVmcy5nZXQocmVmKSAhPSBudWxsKQotICAgICAgICB7Ci0gICAgICAgICAgY29udGludWU7ICAvLyBXZSBhbHJlYWR5IGhhdmUgJ2VtLgotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gSVNUUlVFIGJlaW5nIHVzZWQgYXMgYSBkdW1teSB2YWx1ZS4KLSAgICAgICAgICB1c2VkcmVmcy5wdXQocmVmLCBJU1RSVUUpOwotICAgICAgICB9Ci0KLSAgICAgICAgTG9jUGF0aEl0ZXJhdG9yIG5sID0KLSAgICAgICAgICBrbWdyLmdldE5vZGVTZXREVE1CeUtleSh4Y3R4dCwgZG9jQ29udGV4dCwga2V5bmFtZSwgcmVmLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKSk7Ci0KLS8vICAgICAgICB0cnkKLS8vICAgICAgICB7Ci0gICAgICAgICAgdXBpLmFkZEl0ZXJhdG9yKChMb2NQYXRoSXRlcmF0b3IpbmwuYXNJdGVyYXRvcih4Y3R4dCwgZG9jQ29udGV4dCkpOwotLy8gICAgICAgIH0KLS8vICAgICAgICBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotLy8gICAgICAgIHsKLS8vICAgICAgICAgIC8vIHdpbGwgbmV2ZXIgaGFwcGVuLgotLy8gICAgICAgIH0KLSAgICAgICAgLy9tbm9kZXNldC5hZGROb2Rlc0luRG9jT3JkZXIobmwsIHhjdHh0KTsgbmVlZGVkPz8KLSAgICAgIH0KLQotICAgICAgaW50IGN1cnJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgdXBpLnNldFJvb3QoY3VycmVudCwgeGN0eHQpOwotCi0gICAgICBub2RlcyA9IG5ldyBYTm9kZVNldCh1cGkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgWE1MU3RyaW5nIHJlZiA9IGFyZy54c3RyKCk7Ci0gICAgICBMb2NQYXRoSXRlcmF0b3IgbmwgPSBrbWdyLmdldE5vZGVTZXREVE1CeUtleSh4Y3R4dCwgZG9jQ29udGV4dCwga2V5bmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKSk7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBub2RlcyA9IG5ldyBYTm9kZVNldCgoTG9jUGF0aEl0ZXJhdG9yKW5sLmNsb25lV2l0aFJlc2V0KCkpOwotICAgICAgfQotICAgICAgY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICAgIHsKLSAgICAgICAgLy8gd2lsbCBuZXZlciBoYXBwZW4uCi0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG5vZGVzOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvS2V5RGVjbGFyYXRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9LZXlEZWNsYXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YzI5ZjM1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9LZXlEZWNsYXJhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjExICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEhvbGRzIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGZvciB0aGUgeHNsOmtleXMgZWxlbWVudC4KLSAqIEEgc3R5bGVzaGVldCBkZWNsYXJlcyBhIHNldCBvZiBrZXlzIGZvciBlYWNoIGRvY3VtZW50IHVzaW5nCi0gKiB0aGUgeHNsOmtleSBlbGVtZW50LiBXaGVuIHRoaXMgc2V0IG9mIGtleXMgY29udGFpbnMgYSBtZW1iZXIKLSAqIHdpdGggbm9kZSB4LCBuYW1lIHkgYW5kIHZhbHVlIHosIHdlIHNheSB0aGF0IG5vZGUgeCBoYXMgYSBrZXkKLSAqIHdpdGggbmFtZSB5IGFuZCB2YWx1ZSB6LgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2tleSI+a2V5IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAqLwotcHVibGljIGNsYXNzIEtleURlY2xhcmF0aW9uIGV4dGVuZHMgRWxlbVRlbXBsYXRlRWxlbWVudAotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGVsZW1lbnQgcmVwcmVzZW50aW5nIHRoZSB4c2w6a2V5LiAgVGhlIHBhcmFtZXRlcnMKLSAgICogYXJlIG5lZWRlZCB0byBwcmlvcml0aXplIHRoaXMga2V5IGVsZW1lbnQgYXMgcGFydCBvZiB0aGUgcmVjb21wb3NpbmcKLSAgICogcHJvY2Vzcy4gIEZvciB0aGlzIGVsZW1lbnQsIHRoZXkgYXJlIG5vdCBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQKLSAgICogYmVjYXVzZSB0aGUgZWxlbWVudCBpcyBuZXZlciBhZGRlZCBvbiB0byB0aGUgc3R5bGVzaGVldCBwYXJlbnQuCi0gICAqLwotICBwdWJsaWMgS2V5RGVjbGFyYXRpb24oU3R5bGVzaGVldCBwYXJlbnROb2RlLCBpbnQgZG9jT3JkZXJOdW1iZXIpCi0gIHsKLSAgICBtX3BhcmVudE5vZGUgPSBwYXJlbnROb2RlOwotICAgIHNldFVpZChkb2NPcmRlck51bWJlcik7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJuYW1lIiBwcm9wZXJ0eS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBRTmFtZSBtX25hbWU7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogVGhlIG5hbWUgYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUga2V5LiBUaGUgdmFsdWUKLSAgICogb2YgdGhlIG5hbWUgYXR0cmlidXRlIGlzIGEgUU5hbWUsIHdoaWNoIGlzIGV4cGFuZGVkIGFzCi0gICAqIGRlc2NyaWJlZCBpbiBbMi40IFF1YWxpZmllZCBOYW1lc10uCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFZhbHVlIHRvIHNldCBmb3IgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKFFOYW1lIG5hbWUpCi0gIHsKLSAgICBtX25hbWUgPSBuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm5hbWUiIGF0dHJpYnV0ZS4KLSAgICogVGhlIG5hbWUgYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUga2V5LiBUaGUgdmFsdWUKLSAgICogb2YgdGhlIG5hbWUgYXR0cmlidXRlIGlzIGEgUU5hbWUsIHdoaWNoIGlzIGV4cGFuZGVkIGFzCi0gICAqIGRlc2NyaWJlZCBpbiBbMi40IFF1YWxpZmllZCBOYW1lc10uCi0gICAqCi0gICAqIEByZXR1cm4gVmFsdWUgb2YgdGhlICJuYW1lIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAibWF0Y2giIGF0dHJpYnV0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBYUGF0aCBtX21hdGNoUGF0dGVybiA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgIm1hdGNoIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBtYXRjaCBhdHRyaWJ1dGUgaXMgYSBQYXR0ZXJuOyBhbiB4c2w6a2V5IGVsZW1lbnQgZ2l2ZXMKLSAgICogaW5mb3JtYXRpb24gYWJvdXQgdGhlIGtleXMgb2YgYW55IG5vZGUgdGhhdCBtYXRjaGVzIHRoZQotICAgKiBwYXR0ZXJuIHNwZWNpZmllZCBpbiB0aGUgbWF0Y2ggYXR0cmlidXRlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjcGF0dGVybnMiPnBhdHRlcm5zIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IGZvciB0aGUgIm1hdGNoIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNYXRjaChYUGF0aCB2KQotICB7Ci0gICAgbV9tYXRjaFBhdHRlcm4gPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgIm1hdGNoIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSBtYXRjaCBhdHRyaWJ1dGUgaXMgYSBQYXR0ZXJuOyBhbiB4c2w6a2V5IGVsZW1lbnQgZ2l2ZXMKLSAgICogaW5mb3JtYXRpb24gYWJvdXQgdGhlIGtleXMgb2YgYW55IG5vZGUgdGhhdCBtYXRjaGVzIHRoZQotICAgKiBwYXR0ZXJuIHNwZWNpZmllZCBpbiB0aGUgbWF0Y2ggYXR0cmlidXRlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjcGF0dGVybnMiPnBhdHRlcm5zIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBvZiB0aGUgIm1hdGNoIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgWFBhdGggZ2V0TWF0Y2goKQotICB7Ci0gICAgcmV0dXJuIG1fbWF0Y2hQYXR0ZXJuOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAidXNlIiBhdHRyaWJ1dGUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgWFBhdGggbV91c2U7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInVzZSIgYXR0cmlidXRlLgotICAgKiBUaGUgdXNlIGF0dHJpYnV0ZSBpcyBhbiBleHByZXNzaW9uIHNwZWNpZnlpbmcgdGhlIHZhbHVlcwotICAgKiBvZiB0aGUga2V5OyB0aGUgZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQgb25jZSBmb3IgZWFjaCBub2RlCi0gICAqIHRoYXQgbWF0Y2hlcyB0aGUgcGF0dGVybi4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgdG8gc2V0IGZvciB0aGUgInVzZSIgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VXNlKFhQYXRoIHYpCi0gIHsKLSAgICBtX3VzZSA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAidXNlIiBhdHRyaWJ1dGUuCi0gICAqIFRoZSB1c2UgYXR0cmlidXRlIGlzIGFuIGV4cHJlc3Npb24gc3BlY2lmeWluZyB0aGUgdmFsdWVzCi0gICAqIG9mIHRoZSBrZXk7IHRoZSBleHByZXNzaW9uIGlzIGV2YWx1YXRlZCBvbmNlIGZvciBlYWNoIG5vZGUKLSAgICogdGhhdCBtYXRjaGVzIHRoZSBwYXR0ZXJuLgotICAgKgotICAgKiBAcmV0dXJuIFZhbHVlIG9mIHRoZSAidXNlIiBhdHRyaWJ1dGUuCi0gICAqLwotICBwdWJsaWMgWFBhdGggZ2V0VXNlKCkKLSAgewotICAgIHJldHVybiBtX3VzZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSBoYXMgYmVlbgotICAgKiByZWNvbXBvc2VkLCBhbmQgYWxsb3dzIHRoZSB0ZW1wbGF0ZSB0byBzZXQgcmVtYWluaW5nCi0gICAqIHZhbHVlcyB0aGF0IG1heSBiZSBiYXNlZCBvbiBzb21lIG90aGVyIHByb3BlcnR5IHRoYXQKLSAgICogZGVwZW5kcyBvbiByZWNvbXBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkgCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyLmNvbXBvc2Uoc3Jvb3QpOwotICAgIGphdmEudXRpbC5WZWN0b3Igdm5hbWVzID0gc3Jvb3QuZ2V0Q29tcG9zZVN0YXRlKCkuZ2V0VmFyaWFibGVOYW1lcygpOwotICAgIGlmKG51bGwgIT0gbV9tYXRjaFBhdHRlcm4pCi0gICAgICBtX21hdGNoUGF0dGVybi5maXh1cFZhcmlhYmxlcyh2bmFtZXMsIHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldEdsb2JhbHNTaXplKCkpOwotICAgIGlmKG51bGwgIT0gbV91c2UpCi0gICAgICBtX3VzZS5maXh1cFZhcmlhYmxlcyh2bmFtZXMsIHNyb290LmdldENvbXBvc2VTdGF0ZSgpLmdldEdsb2JhbHNTaXplKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGR1cmluZyByZWNvbXBvc2l0aW9uIHRvCi0gICAqIGNvbnRyb2wgaG93IHRoaXMgZWxlbWVudCBpcyBjb21wb3NlZC4KLSAgICogQHBhcmFtIHJvb3QgVGhlIHJvb3Qgc3R5bGVzaGVldCBmb3IgdGhpcyB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlY29tcG9zZShTdHlsZXNoZWV0Um9vdCByb290KQotICB7Ci0gICAgcm9vdC5yZWNvbXBvc2VLZXlzKHRoaXMpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9OYW1lc3BhY2VBbGlhcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL05hbWVzcGFjZUFsaWFzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJjYzdkZmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL05hbWVzcGFjZUFsaWFzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLS8qKgotICogT2JqZWN0IHRvIGhvbGQgYW4geHNsOm5hbWVzcGFjZSBlbGVtZW50LgotICogQSBzdHlsZXNoZWV0IGNhbiB1c2UgdGhlIHhzbDpuYW1lc3BhY2UtYWxpYXMgZWxlbWVudCB0byBkZWNsYXJlCi0gKiB0aGF0IG9uZSBuYW1lc3BhY2UgVVJJIGlzIGFuIGFsaWFzIGZvciBhbm90aGVyIG5hbWVzcGFjZSBVUkkuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbGl0ZXJhbC1yZXN1bHQtZWxlbWVudCI+bGl0ZXJhbC1yZXN1bHQtZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lc3BhY2VBbGlhcyBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLXsKLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBOYW1lc3BhY2VBbGlhcwotICAgKiAKLSAgICogQHBhcmFtIGRvY09yZGVyTnVtYmVyIFRoZSBkb2N1bWVudCBvcmRlciBudW1iZXIKLSAgICoKLSAgICovCi0gIHB1YmxpYyBOYW1lc3BhY2VBbGlhcyhpbnQgZG9jT3JkZXJOdW1iZXIpCi0gIHsKLSAgICBzdXBlcigpOwotICAgIG1fZG9jT3JkZXJOdW1iZXIgPSBkb2NPcmRlck51bWJlcjsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgInN0eWxlc2hlZXQtcHJlZml4IiBhdHRyaWJ1dGUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fU3R5bGVzaGVldFByZWZpeDsKLQotICAvKioKLSAgICogU2V0IHRoZSAic3R5bGVzaGVldC1wcmVmaXgiIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIHYgbm9uLW51bGwgcHJlZml4IHZhbHVlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3R5bGVzaGVldFByZWZpeChTdHJpbmcgdikKLSAgewotICAgIG1fU3R5bGVzaGVldFByZWZpeCA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAic3R5bGVzaGVldC1wcmVmaXgiIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCBwcmVmaXggdmFsdWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN0eWxlc2hlZXRQcmVmaXgoKQotICB7Ci0gICAgcmV0dXJuIG1fU3R5bGVzaGVldFByZWZpeDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoZSBuYW1lc3BhY2UgaW4gdGhlIHN0eWxlc2hlZXQgc3BhY2UuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fU3R5bGVzaGVldE5hbWVzcGFjZTsKLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBmb3IgdGhlIHN0eWxlc2hlZXQgbmFtZXNwYWNlLgotICAgKgotICAgKiBAcGFyYW0gdiBub24tbnVsbCBwcmVmaXggdmFsdWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0TmFtZXNwYWNlKFN0cmluZyB2KQotICB7Ci0gICAgbV9TdHlsZXNoZWV0TmFtZXNwYWNlID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgc3R5bGVzaGVldCBuYW1lc3BhY2UuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcHJlZml4IHZhbHVlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTdHlsZXNoZWV0TmFtZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX1N0eWxlc2hlZXROYW1lc3BhY2U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJyZXN1bHQtcHJlZml4IiBhdHRyaWJ1dGUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fUmVzdWx0UHJlZml4OwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJyZXN1bHQtcHJlZml4IiBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSB2IG5vbi1udWxsIHByZWZpeCB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJlc3VsdFByZWZpeChTdHJpbmcgdikKLSAgewotICAgIG1fUmVzdWx0UHJlZml4ID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJyZXN1bHQtcHJlZml4IiBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcHJlZml4IHZhbHVlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRSZXN1bHRQcmVmaXgoKQotICB7Ci0gICAgcmV0dXJuIG1fUmVzdWx0UHJlZml4OwotICB9Ci0gIAotICAvKioKLSAgICogVGhlIHJlc3VsdCBuYW1lc3BhY2UuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fUmVzdWx0TmFtZXNwYWNlOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIHJlc3VsdCBuYW1lc3BhY2UuCi0gICAqCi0gICAqIEBwYXJhbSB2IG5vbi1udWxsIG5hbWVzcGFjZSB2YWx1ZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVzdWx0TmFtZXNwYWNlKFN0cmluZyB2KQotICB7Ci0gICAgbV9SZXN1bHROYW1lc3BhY2UgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcmVzdWx0IG5hbWVzcGFjZSB2YWx1ZS4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCBuYW1lc3BhY2UgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFJlc3VsdE5hbWVzcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gbV9SZXN1bHROYW1lc3BhY2U7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gcmVjb21wb3NlKCkgYWxsIG9mIHRoZSBuYW1lc3BhY2UgYWxpYXMgcHJvcGVydGllcyBlbGVtZW50cy4KLSAgICogCi0gICAqIEBwYXJhbSByb290IFRoZSBvd25pbmcgcm9vdCBzdHlsZXNoZWV0Ci0gICAqLwotICBwdWJsaWMgdm9pZCByZWNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgcm9vdCkKLSAgewotICAgIHJvb3QucmVjb21wb3NlTmFtZXNwYWNlQWxpYXNlcyh0aGlzKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvT3V0cHV0UHJvcGVydGllcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL091dHB1dFByb3BlcnRpZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDA1ODdiMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvT3V0cHV0UHJvcGVydGllcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA4MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgamF2YS5sYW5nLkNsb25lYWJsZTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5NZXRob2Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLkV4dGVuc2lvbkhhbmRsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5czsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGluZm9ybWF0aW9uIGZyb20geHNsOm91dHB1dCBlbGVtZW50cy4gSXQgaXMgbWFpbmx5Ci0gKiBhIHdyYXBwZXIgZm9yIHtAbGluayBqYXZhLnV0aWwuUHJvcGVydGllc30sIGJ1dCBjYW4gbm90IGV4dGVuZCB0aGF0IGNsYXNzCi0gKiBiZWNhdXNlIGl0IG11c3QgYmUgcGFydCBvZiB0aGUge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnR9Ci0gKiBoZWFyYXJjaHkuCi0gKiA8cD5BbiBPdXRwdXRQcm9wZXJ0aWVzIGxpc3QgY2FuIGNvbnRhaW4gYW5vdGhlciBPdXRwdXRQcm9wZXJ0aWVzIGxpc3QgYXMKLSAqIGl0cyAiZGVmYXVsdHMiOyB0aGlzIHNlY29uZCBwcm9wZXJ0eSBsaXN0IGlzIHNlYXJjaGVkIGlmIHRoZSBwcm9wZXJ0eSBrZXkKLSAqIGlzIG5vdCBmb3VuZCBpbiB0aGUgb3JpZ2luYWwgcHJvcGVydHkgbGlzdC48L3A+Ci0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHRkIj5YU0xUIERURDwvYT4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNvdXRwdXQiPnhzbDpvdXRwdXQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICogQAotICovCi1wdWJsaWMgY2xhc3MgT3V0cHV0UHJvcGVydGllcyBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUKLXsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhbiBlbXB0eSBPdXRwdXRQcm9wZXJ0aWVzIHdpdGggbm8gZGVmYXVsdCB2YWx1ZXMuCi0gICAqLwotICBwdWJsaWMgT3V0cHV0UHJvcGVydGllcygpCi0gIHsKLSAgICB0aGlzKE1ldGhvZC5YTUwpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYW4gZW1wdHkgT3V0cHV0UHJvcGVydGllcyB3aXRoIHRoZSBzcGVjaWZpZWQgZGVmYXVsdHMuCi0gICAqCi0gICAqIEBwYXJhbSAgIGRlZmF1bHRzICAgdGhlIGRlZmF1bHRzLgotICAgKi8KLSAgcHVibGljIE91dHB1dFByb3BlcnRpZXMoUHJvcGVydGllcyBkZWZhdWx0cykKLSAgewotICAgIG1fcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKGRlZmF1bHRzKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGVzIGFuIGVtcHR5IE91dHB1dFByb3BlcnRpZXMgd2l0aCB0aGUgZGVmYXVsdHMgc3BlY2lmaWVkIGJ5Ci0gICAqIGEgcHJvcGVydHkgZmlsZS4gIFRoZSBtZXRob2QgYXJndW1lbnQgaXMgdXNlZCB0byBjb25zdHJ1Y3QgYSBzdHJpbmcgb2YKLSAgICogdGhlIGZvcm0gb3V0cHV0X1ttZXRob2RdLnByb3BlcnRpZXMgKGZvciBpbnN0YW5jZSwgb3V0cHV0X2h0bWwucHJvcGVydGllcykuCi0gICAqIFRoZSBvdXRwdXRfeG1sLnByb3BlcnRpZXMgZmlsZSBpcyBhbHdheXMgdXNlZCBhcyB0aGUgYmFzZS4KLSAgICogPHA+QXQgdGhlIG1vbWVudCwgYW55dGhpbmcgb3RoZXIgdGhhbiAndGV4dCcsICd4bWwnLCBhbmQgJ2h0bWwnLCB3aWxsCi0gICAqIHVzZSB0aGUgb3V0cHV0X3htbC5wcm9wZXJ0aWVzIGZpbGUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gICBtZXRob2Qgbm9uLW51bGwgcmVmZXJlbmNlIHRvIG1ldGhvZCBuYW1lLgotICAgKi8KLSAgcHVibGljIE91dHB1dFByb3BlcnRpZXMoU3RyaW5nIG1ldGhvZCkKLSAgewotICAgIG1fcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKGdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzKG1ldGhvZCkpOwotICB9Ci0gIAotICBzdGF0aWMgZmluYWwgU3RyaW5nIFNfWFNMVF9QUkVGSVggPSAieHNsdC5vdXRwdXQuIjsKLSAgc3RhdGljIGZpbmFsIGludCBTX1hTTFRfUFJFRklYX0xFTiA9IFNfWFNMVF9QUkVGSVgubGVuZ3RoKCk7Ci0gIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19YQUxBTl9QUkVGSVggPSAib3JnLmFwYWNoZS54c2x0LiI7Ci0gIHN0YXRpYyBmaW5hbCBpbnQgU19YQUxBTl9QUkVGSVhfTEVOID0gU19YQUxBTl9QUkVGSVgubGVuZ3RoKCk7Ci0gIAotICAvKiogQnVpbHQtaW4gZXh0ZW5zaW9ucyBuYW1lc3BhY2UsIHJlZXhwcmVzc2VkIGluIHtuYW1lc3BhY2VVUkl9IHN5bnRheAotICAgKiBzdWl0YWJsZSBmb3IgcHJlcGVuZGluZyB0byBhIGxvY2FsbmFtZSB0byBwcm9kdWNlIGEgInVuaXZlcnNhbAotICAgKiBuYW1lIi4KLSAgICovCi0gIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMPQotICAgICAgICAieyIrQ29uc3RhbnRzLlNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCsifSI7Ci0gIAotICAvKioKLSAgICogRml4IHVwIGEgc3RyaW5nIGluIGFuIG91dHB1dCBwcm9wZXJ0aWVzIGZpbGUgYWNjb3JkaW5nIHRvIAotICAgKiB0aGUgcnVsZXMgb2Yge0BsaW5rICNsb2FkUHJvcGVydGllc0ZpbGV9LgotICAgKiAKLSAgICogQHBhcmFtIHMgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHN0cmluZyB0aGF0IG1heSBuZWVkIHRvIGJlIGZpeGVkIHVwLgotICAgKiBAcmV0dXJuIEEgbmV3IHN0cmluZyBpZiBmaXh1cCBvY2N1cmVkLCBvdGhlcndpc2UgdGhlIHMgYXJndW1lbnQuCi0gICAqLwotICBzdGF0aWMgcHJpdmF0ZSBTdHJpbmcgZml4dXBQcm9wZXJ0eVN0cmluZyhTdHJpbmcgcywgYm9vbGVhbiBkb0NsaXBwaW5nKQotICB7Ci0gICAgaW50IGluZGV4OwotICAgIGlmIChkb0NsaXBwaW5nICYmIHMuc3RhcnRzV2l0aChTX1hTTFRfUFJFRklYKSkKLSAgICB7Ci0gICAgICBzID0gcy5zdWJzdHJpbmcoU19YU0xUX1BSRUZJWF9MRU4pOwotICAgIH0KLSAgICBpZiAocy5zdGFydHNXaXRoKFNfWEFMQU5fUFJFRklYKSkKLSAgICB7Ci0gICAgICBzID0gU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMICsgcy5zdWJzdHJpbmcoU19YQUxBTl9QUkVGSVhfTEVOKTsKLSAgICB9Ci0gICAgaWYgKChpbmRleCA9IHMuaW5kZXhPZigiXFx1MDAzYSIpKSA+IDApCi0gICAgewotICAgICAgU3RyaW5nIHRlbXAgPSBzLnN1YnN0cmluZyhpbmRleCs2KTsKLSAgICAgIHMgPSBzLnN1YnN0cmluZygwLCBpbmRleCkgKyAiOiIgKyB0ZW1wOwotCi0gICAgfQotICAgIHJldHVybiBzOwotICB9Ci0gIAotICAvKioKLSAgICogTG9hZCB0aGUgcHJvcGVydGllcyBmaWxlIGZyb20gYSByZXNvdXJjZSBzdHJlYW0uICBJZiBhIAotICAgKiBrZXkgbmFtZSBzdWNoIGFzICJvcmcuYXBhY2hlLnhzbHQueHh4IiwgZml4IHVwIHRoZSBzdGFydCBvZiAKLSAgICogc3RyaW5nIHRvIGJlIGEgY3VybHkgbmFtZXNwYWNlLiAgSWYgYSBrZXkgbmFtZSBzdGFydHMgd2l0aCAKLSAgICogInhzbHQub3V0cHV0Lnh4eCIsIGNsaXAgb2ZmICJ4c2x0Lm91dHB1dC4iLiAgSWYgYSBrZXkgbmFtZSAqb3IqIGEgCi0gICAqIGtleSB2YWx1ZSBpcyBkaXNjb3ZlcmVkLCBjaGVjayBmb3IgXHUwMDNhIGluIHRoZSB0ZXh0LCBhbmQgCi0gICAqIGZpeCBpdCB1cCB0byBiZSAiOiIsIHNpbmNlIGVhcmxpZXIgdmVyc2lvbnMgb2YgdGhlIEpESyBkbyBub3QgCi0gICAqIGhhbmRsZSB0aGUgZXNjYXBlIHNlcXVlbmNlIChhdCBsZWFzdCBpbiBrZXkgbmFtZXMpLgotICAgKiAKLSAgICogQHBhcmFtIHJlc291cmNlTmFtZSBub24tbnVsbCByZWZlcmVuY2UgdG8gcmVzb3VyY2UgbmFtZS4KLSAgICogQHBhcmFtIGRlZmF1bHRzIERlZmF1bHQgcHJvcGVydGllcywgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqLwotICBzdGF0aWMgcHJpdmF0ZSBQcm9wZXJ0aWVzIGxvYWRQcm9wZXJ0aWVzRmlsZShTdHJpbmcgcmVzb3VyY2VOYW1lLCBQcm9wZXJ0aWVzIGRlZmF1bHRzKQotICAgIHRocm93cyBJT0V4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBUaGlzIHN0YXRpYyBtZXRob2Qgc2hvdWxkIGV2ZW50dWFsbHkgYmUgbW92ZWQgdG8gYSB0aHJlYWQtc3BlY2lmaWMgY2xhc3MKLSAgICAvLyBzbyB0aGF0IHdlIGNhbiBjYWNoZSB0aGUgQ29udGV4dENsYXNzTG9hZGVyIGFuZCBib3R0bGVuZWNrIGFsbCBwcm9wZXJ0aWVzIGZpbGUKLSAgICAvLyBsb2FkaW5nIHRocm91Z2hvdXQgWGFsYW4uCi0KLSAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoZGVmYXVsdHMpOwotCi0gICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOwotICAgIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gYmlzID0gbnVsbDsKLQotICAgIHRyeSB7Ci0gICAgICB0cnkgewotICAgICAgICBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgZ2V0Q0NMID0gVGhyZWFkLmNsYXNzLmdldE1ldGhvZCgiZ2V0Q29udGV4dENsYXNzTG9hZGVyIiwgTk9fQ0xBU1NFUyk7Ci0gICAgICAgIGlmIChnZXRDQ0wgIT0gbnVsbCkgewotICAgICAgICAgIENsYXNzTG9hZGVyIGNvbnRleHRDbGFzc0xvYWRlciA9IChDbGFzc0xvYWRlcikgZ2V0Q0NMLmludm9rZShUaHJlYWQuY3VycmVudFRocmVhZCgpLCBOT19PQkpTKTsKLSAgICAgICAgICBpcyA9IGNvbnRleHRDbGFzc0xvYWRlci5nZXRSZXNvdXJjZUFzU3RyZWFtKCJvcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy8iICsgcmVzb3VyY2VOYW1lKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7fQotCi0gICAgICBpZiAoIGlzID09IG51bGwgKSB7Ci0gICAgICAgIGlzID0gT3V0cHV0UHJvcGVydGllcy5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKHJlc291cmNlTmFtZSk7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGJpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKLSAgICAgIHByb3BzLmxvYWQoYmlzKTsKLSAgICB9IAotICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKLSAgICAgIGlmICggZGVmYXVsdHMgPT0gbnVsbCApIHsKLSAgICAgICAgdGhyb3cgaW9lOwotICAgICAgfQotICAgICAgZWxzZSB7Ci0gICAgICAgIHRocm93IG5ldyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1VMRF9OT1RfTE9BRF9SRVNPVVJDRSwgbmV3IE9iamVjdFtde3Jlc291cmNlTmFtZX0pLCBpb2UpOyAvLyJDb3VsZCBub3QgbG9hZCAnIityZXNvdXJjZU5hbWUrIicgKGNoZWNrIENMQVNTUEFUSCksIG5vdyB1c2luZyBqdXN0IHRoZSBkZWZhdWx0cyAiLCBpb2UpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpIHsKLSAgICAgIC8vIFJlcGVhdCBJT0V4Y2VwdGlvbiBoYW5kbGluZyBmb3Igc2FuZGJveC9hcHBsZXQgY2FzZSAtc2MKLSAgICAgIGlmICggZGVmYXVsdHMgPT0gbnVsbCApIHsKLSAgICAgICAgdGhyb3cgc2U7Ci0gICAgICB9Ci0gICAgICBlbHNlIHsKLSAgICAgICAgdGhyb3cgbmV3IFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NPVUxEX05PVF9MT0FEX1JFU09VUkNFLCBuZXcgT2JqZWN0W117cmVzb3VyY2VOYW1lfSksIHNlKTsgLy8iQ291bGQgbm90IGxvYWQgJyIrcmVzb3VyY2VOYW1lKyInIChjaGVjayBDTEFTU1BBVEgsIGFwcGxldCBzZWN1cml0eSksIG5vdyB1c2luZyBqdXN0IHRoZSBkZWZhdWx0cyAiLCBzZSk7Ci0gICAgICB9Ci0gICAgfSAKLSAgICBmaW5hbGx5IHsKLSAgICAgIGlmICggYmlzICE9IG51bGwgKSB7Ci0gICAgICAgIGJpcy5jbG9zZSgpOwotICAgICAgfQotICAgICAgaWYgKGlzICE9IG51bGwgKSB7Ci0gICAgICAgIGlzLmNsb3NlKCk7Ci0gICAgICB9Ci0gICAgfQotICAgIAotICAgIC8vIE5vdGUgdGhhdCB3ZSdyZSB3b3JraW5nIGF0IHRoZSBIYXNoVGFibGUgbGV2ZWwgaGVyZSwgCi0gICAgLy8gYW5kIG5vdCBhdCB0aGUgUHJvcGVydGllcyBsZXZlbCEgIFRoaXMgaXMgaW1wb3J0YW50IAotICAgIC8vIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBtb2RpZnkgdGhlIGRlZmF1bHQgcHJvcGVydGllcy4KLSAgICAvLyBOQjogSWYgZml4dXBQcm9wZXJ0eVN0cmluZyBlbmRzIHVwIGNoYW5naW5nIHRoZSBwcm9wZXJ0eQotICAgIC8vIG5hbWUgb3IgdmFsdWUsIHdlIG5lZWQgdG8gcmVtb3ZlIHRoZSBvbGQga2V5IGFuZCByZS1hZGQKLSAgICAvLyB3aXRoIHRoZSBuZXcga2V5IGFuZCB2YWx1ZS4gIEhvd2V2ZXIsIHRoZW4gb3VyIEVudW1lcmF0aW9uCi0gICAgLy8gY291bGQgbG9zZSBpdHMgcGxhY2UgaW4gdGhlIEhhc2hUYWJsZS4gIFNvLCB3ZSBmaXJzdAotICAgIC8vIGNsb25lIHRoZSBIYXNoVGFibGUgYW5kIGVudW1lcmF0ZSBvdmVyIHRoYXQgc2luY2UgdGhlCi0gICAgLy8gY2xvbmUgd2lsbCBub3QgY2hhbmdlLiAgV2hlbiB3ZSBtaWdyYXRlIHRvIENvbGxlY3Rpb25zLAotICAgIC8vIHRoaXMgY29kZSBzaG91bGQgYmUgcmV2aXNpdGVkIGFuZCBjbGVhbmVkIHVwIHRvIHVzZQotICAgIC8vIGFuIEl0ZXJhdG9yIHdoaWNoIG1heSAob3IgbWF5IG5vdCkgYWxsZXZpYXRlIHRoZSBuZWVkIGZvcgotICAgIC8vIHRoZSBjbG9uZS4gIE1hbnkgdGhhbmtzIHRvIFBhZHJhaWcgTydoSWNlYWRoYQotICAgIC8vIDxwYWRyYWlnQGdyYWRpZW50LmllPiBmb3IgZmluZGluZyB0aGlzIHByb2JsZW0uICBCdWd6aWxsYSAyMDAwLgotCi0gICAgRW51bWVyYXRpb24ga2V5cyA9ICgoUHJvcGVydGllcykgcHJvcHMuY2xvbmUoKSkua2V5cygpOwotICAgIHdoaWxlKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpa2V5cy5uZXh0RWxlbWVudCgpOwotICAgICAgLy8gTm93IGNoZWNrIGlmIHRoZSBnaXZlbiBrZXkgd2FzIHNwZWNpZmllZCBhcyBhIAotICAgICAgLy8gU3lzdGVtIHByb3BlcnR5LiBJZiBzbywgdGhlIHN5c3RlbSBwcm9wZXJ0eSAKLSAgICAgIC8vIG92ZXJpZGVzIHRoZSBkZWZhdWx0IHZhbHVlIGluIHRoZSBwcm9wZXJ5IGZpbGUuCi0gICAgICBTdHJpbmcgdmFsdWUgPSBudWxsOwotICAgICAgdHJ5IHsKLSAgICAgICAgdmFsdWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoa2V5KTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgewotICAgICAgICAvLyBOby1vcCBmb3Igc2FuZGJveC9hcHBsZXQgY2FzZSwgbGVhdmUgbnVsbCAtc2MKLSAgICAgIH0KLSAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSAgICAgIAotICAgICAgICB2YWx1ZSA9IChTdHJpbmcpcHJvcHMuZ2V0KGtleSk7ICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgIAotICAgICAgU3RyaW5nIG5ld0tleSA9IGZpeHVwUHJvcGVydHlTdHJpbmcoa2V5LCB0cnVlKTsKLSAgICAgIFN0cmluZyBuZXdWYWx1ZSA9IG51bGw7Ci0gICAgICB0cnkgewotICAgICAgICBuZXdWYWx1ZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eShuZXdLZXkpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7Ci0gICAgICAgIC8vIE5vLW9wIGZvciBzYW5kYm94L2FwcGxldCBjYXNlLCBsZWF2ZSBudWxsIC1zYwotICAgICAgfQotICAgICAgaWYgKG5ld1ZhbHVlID09IG51bGwpCi0gICAgICAgIG5ld1ZhbHVlID0gZml4dXBQcm9wZXJ0eVN0cmluZyh2YWx1ZSwgZmFsc2UpOwotICAgICAgZWxzZQotICAgICAgICBuZXdWYWx1ZSA9IGZpeHVwUHJvcGVydHlTdHJpbmcobmV3VmFsdWUsIGZhbHNlKTsKLSAgICAgICAKLSAgICAgIGlmKGtleSAhPSBuZXdLZXkgfHwgdmFsdWUgIT0gbmV3VmFsdWUpCi0gICAgICB7Ci0gICAgICAgIHByb3BzLnJlbW92ZShrZXkpOwotICAgICAgICBwcm9wcy5wdXQobmV3S2V5LCBuZXdWYWx1ZSk7Ci0gICAgICB9Ci0gICAgICAKLSAgICB9Ci0gICAgCi0gICAgcmV0dXJuIHByb3BzOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZXMgYW4gZW1wdHkgT3V0cHV0UHJvcGVydGllcyB3aXRoIHRoZSBkZWZhdWx0cyBzcGVjaWZpZWQgYnkKLSAgICogYSBwcm9wZXJ0eSBmaWxlLiAgVGhlIG1ldGhvZCBhcmd1bWVudCBpcyB1c2VkIHRvIGNvbnN0cnVjdCBhIHN0cmluZyBvZgotICAgKiB0aGUgZm9ybSBvdXRwdXRfW21ldGhvZF0ucHJvcGVydGllcyAoZm9yIGluc3RhbmNlLCBvdXRwdXRfaHRtbC5wcm9wZXJ0aWVzKS4KLSAgICogVGhlIG91dHB1dF94bWwucHJvcGVydGllcyBmaWxlIGlzIGFsd2F5cyB1c2VkIGFzIHRoZSBiYXNlLgotICAgKiA8cD5BdCB0aGUgbW9tZW50LCBhbnl0aGluZyBvdGhlciB0aGFuICd0ZXh0JywgJ3htbCcsIGFuZCAnaHRtbCcsIHdpbGwKLSAgICogdXNlIHRoZSBvdXRwdXRfeG1sLnByb3BlcnRpZXMgZmlsZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSAgIG1ldGhvZCBub24tbnVsbCByZWZlcmVuY2UgdG8gbWV0aG9kIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gUHJvcGVydGllcyBvYmplY3QgdGhhdCBob2xkcyB0aGUgZGVmYXVsdHMgZm9yIHRoZSBnaXZlbiBtZXRob2QuCi0gICAqLwotICBzdGF0aWMgcHVibGljIFByb3BlcnRpZXMgZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMoU3RyaW5nIG1ldGhvZCkKLSAgewotICAgIFN0cmluZyBmaWxlTmFtZSA9IG51bGw7Ci0gICAgUHJvcGVydGllcyBkZWZhdWx0UHJvcGVydGllcyA9IG51bGw7Ci0gICAgLy8gQWNjb3JkaW5nIHRvIHRoaXMgYXJ0aWNsZSA6IERvdWJsZS1jaGVjayBsb2NraW5nIGRvZXMgbm90IHdvcmsKLSAgICAvLyBodHRwOi8vd3d3LmphdmF3b3JsZC5jb20vamF2YXdvcmxkL2p3LTAyLTIwMDEvanctMDIwOS10b29sYm94Lmh0bWwKLSAgICB0cnkKLSAgICB7Ci0gICAgICBzeW5jaHJvbml6ZWQgKG1fc3luY2hfb2JqZWN0KQotICAgICAgewotICAgICAgICBpZiAobnVsbCA9PSBtX3htbF9wcm9wZXJ0aWVzKSAgLy8gZG91YmxlIGNoZWNrCi0gICAgICAgIHsKLSAgICAgICAgICBmaWxlTmFtZSA9ICJvdXRwdXRfeG1sLnByb3BlcnRpZXMiOwotICAgICAgICAgIG1feG1sX3Byb3BlcnRpZXMgPSBsb2FkUHJvcGVydGllc0ZpbGUoZmlsZU5hbWUsIG51bGwpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChtZXRob2QuZXF1YWxzKE1ldGhvZC5YTUwpKQotICAgICAgewotICAgICAgICBkZWZhdWx0UHJvcGVydGllcyA9IG1feG1sX3Byb3BlcnRpZXM7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChtZXRob2QuZXF1YWxzKE1ldGhvZC5IVE1MKSkKLSAgICAgIHsKLSAgICAgICAgICAgIGlmIChudWxsID09IG1faHRtbF9wcm9wZXJ0aWVzKSAgLy8gZG91YmxlIGNoZWNrCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGZpbGVOYW1lID0gIm91dHB1dF9odG1sLnByb3BlcnRpZXMiOwotICAgICAgICAgICAgICBtX2h0bWxfcHJvcGVydGllcyA9IGxvYWRQcm9wZXJ0aWVzRmlsZShmaWxlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV94bWxfcHJvcGVydGllcyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgZGVmYXVsdFByb3BlcnRpZXMgPSBtX2h0bWxfcHJvcGVydGllczsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG1ldGhvZC5lcXVhbHMoTWV0aG9kLlRleHQpKQotICAgICAgewotICAgICAgICAgICAgaWYgKG51bGwgPT0gbV90ZXh0X3Byb3BlcnRpZXMpICAvLyBkb3VibGUgY2hlY2sKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZmlsZU5hbWUgPSAib3V0cHV0X3RleHQucHJvcGVydGllcyI7Ci0gICAgICAgICAgICAgIG1fdGV4dF9wcm9wZXJ0aWVzID0gbG9hZFByb3BlcnRpZXNGaWxlKGZpbGVOYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3htbF9wcm9wZXJ0aWVzKTsKLSAgICAgICAgICAgICAgaWYobnVsbCA9PSBtX3RleHRfcHJvcGVydGllcy5nZXRQcm9wZXJ0eShPdXRwdXRLZXlzLkVOQ09ESU5HKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFN0cmluZyBtaW1lRW5jb2RpbmcgPSBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5FbmNvZGluZ3MuZ2V0TWltZUVuY29kaW5nKG51bGwpOwotICAgICAgICAgICAgICAgIG1fdGV4dF9wcm9wZXJ0aWVzLnB1dChPdXRwdXRLZXlzLkVOQ09ESU5HLCBtaW1lRW5jb2RpbmcpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgZGVmYXVsdFByb3BlcnRpZXMgPSBtX3RleHRfcHJvcGVydGllczsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLQotICAgICAgICAvLyBUT0RPOiBDYWxjdWxhdGUgcmVzIGZpbGUgZnJvbSBuYW1lLgotICAgICAgICBkZWZhdWx0UHJvcGVydGllcyA9IG1feG1sX3Byb3BlcnRpZXM7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgIk91dHB1dCBtZXRob2QgaXMgIittZXRob2QrIiBjb3VsZCBub3QgbG9hZCAiK2ZpbGVOYW1lKyIgKGNoZWNrIENMQVNTUEFUSCkiLAotICAgICAgICAgICAgIGlvZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGRlZmF1bHRQcm9wZXJ0aWVzOwotICB9Ci0KLSAgLyoqCi0gICAqIENsb25lIHRoaXMgT3V0cHV0UHJvcGVydGllcywgaW5jbHVkaW5nIGEgY2xvbmUgb2YgdGhlIHdyYXBwZWQgUHJvcGVydGllcwotICAgKiByZWZlcmVuY2UuCi0gICAqCi0gICAqIEByZXR1cm4gQSBuZXcgT3V0cHV0UHJvcGVydGllcyByZWZlcmVuY2UsIG11dGF0aW9uIG9mIHdoaWNoIHNob3VsZCBub3QKLSAgICogICAgICAgICBlZmZlY3QgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgT3V0cHV0UHJvcGVydGllcyBjbG9uZWQgPSAoT3V0cHV0UHJvcGVydGllcykgc3VwZXIuY2xvbmUoKTsKLQotICAgICAgY2xvbmVkLm1fcHJvcGVydGllcyA9IChQcm9wZXJ0aWVzKSBjbG9uZWQubV9wcm9wZXJ0aWVzLmNsb25lKCk7Ci0KLSAgICAgIHJldHVybiBjbG9uZWQ7Ci0gICAgfQotICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gb3V0cHV0IHByb3BlcnR5LgotICAgKgotICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gYmUgcGxhY2VkIGludG8gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgY29ycmVzcG9uZGluZyB0byA8dHQ+a2V5PC90dD4uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShRTmFtZSBrZXksIFN0cmluZyB2YWx1ZSkKLSAgewotICAgIHNldFByb3BlcnR5KGtleS50b05hbWVzcGFjZWRTdHJpbmcoKSwgdmFsdWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvdXRwdXQgcHJvcGVydHkuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byBiZSBwbGFjZWQgaW50byB0aGUgcHJvcGVydHkgbGlzdC4KLSAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIDx0dD5rZXk8L3R0Pi4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBrZXksIFN0cmluZyB2YWx1ZSkKLSAgewotICAgIGlmKGtleS5lcXVhbHMoT3V0cHV0S2V5cy5NRVRIT0QpKQotICAgIHsKLSAgICAgIHNldE1ldGhvZERlZmF1bHRzKHZhbHVlKTsKLSAgICB9Ci0gICAgbV9wcm9wZXJ0aWVzLnB1dChrZXksIHZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIElmIHRoZSBrZXkgaXMgbm90IGZvdW5kIGluIHRoaXMgcHJvcGVydHkgbGlzdCwgdGhlIGRlZmF1bHQgcHJvcGVydHkgbGlzdCwKLSAgICogYW5kIGl0cyBkZWZhdWx0cywgcmVjdXJzaXZlbHksIGFyZSB0aGVuIGNoZWNrZWQuIFRoZSBtZXRob2QgcmV0dXJucwotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IGZvdW5kLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByb3BlcnR5KFFOYW1lIGtleSkKLSAgewotICAgIHJldHVybiBtX3Byb3BlcnRpZXMuZ2V0UHJvcGVydHkoa2V5LnRvTmFtZXNwYWNlZFN0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIElmIHRoZSBrZXkgaXMgbm90IGZvdW5kIGluIHRoaXMgcHJvcGVydHkgbGlzdCwgdGhlIGRlZmF1bHQgcHJvcGVydHkgbGlzdCwKLSAgICogYW5kIGl0cyBkZWZhdWx0cywgcmVjdXJzaXZlbHksIGFyZSB0aGVuIGNoZWNrZWQuIFRoZSBtZXRob2QgcmV0dXJucwotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IGZvdW5kLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByb3BlcnR5KFN0cmluZyBrZXkpCi0gIHsKLSAgICByZXR1cm4gbV9wcm9wZXJ0aWVzLmdldFByb3BlcnR5KGtleSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIG91dHB1dCBwcm9wZXJ0eS4KLSAgICoKLSAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIGJlIHBsYWNlZCBpbnRvIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gPHR0PmtleTwvdHQ+LgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Qm9vbGVhblByb3BlcnR5KFFOYW1lIGtleSwgYm9vbGVhbiB2YWx1ZSkKLSAgewotICAgIG1fcHJvcGVydGllcy5wdXQoa2V5LnRvTmFtZXNwYWNlZFN0cmluZygpLCB2YWx1ZSA/ICJ5ZXMiIDogIm5vIik7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIG91dHB1dCBwcm9wZXJ0eS4KLSAgICoKLSAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIGJlIHBsYWNlZCBpbnRvIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gPHR0PmtleTwvdHQ+LgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Qm9vbGVhblByb3BlcnR5KFN0cmluZyBrZXksIGJvb2xlYW4gdmFsdWUpCi0gIHsKLSAgICBtX3Byb3BlcnRpZXMucHV0KGtleSwgdmFsdWUgPyAieWVzIiA6ICJubyIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgYm9vbGVhbiBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQsIG9yIGlmIHRoZSB2YWx1ZSBpcyBvdGhlcgotICAgKiB0aGFuICJ5ZXMiLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IGFzIGEgYm9vbGVhbiB2YWx1ZSwgb3IgZmFsc2UKLSAgICogaWYgbnVsbCBvciBub3QgInllcyIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sZWFuUHJvcGVydHkoUU5hbWUga2V5KQotICB7Ci0gICAgcmV0dXJuIGdldEJvb2xlYW5Qcm9wZXJ0eShrZXkudG9OYW1lc3BhY2VkU3RyaW5nKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgYm9vbGVhbiBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQsIG9yIGlmIHRoZSB2YWx1ZSBpcyBvdGhlcgotICAgKiB0aGFuICJ5ZXMiLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IGFzIGEgYm9vbGVhbiB2YWx1ZSwgb3IgZmFsc2UKLSAgICogaWYgbnVsbCBvciBub3QgInllcyIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sZWFuUHJvcGVydHkoU3RyaW5nIGtleSkKLSAgewotICAgIHJldHVybiBnZXRCb29sZWFuUHJvcGVydHkoa2V5LCBtX3Byb3BlcnRpZXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgYm9vbGVhbiBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQsIG9yIGlmIHRoZSB2YWx1ZSBpcyBvdGhlcgotICAgKiB0aGFuICJ5ZXMiLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcGFyYW0gICBwcm9wcyAgIHRoZSBsaXN0IG9mIHByb3BlcnRpZXMgdGhhdCB3aWxsIGJlIHNlYXJjaGVkLgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IGFzIGEgYm9vbGVhbiB2YWx1ZSwgb3IgZmFsc2UKLSAgICogaWYgbnVsbCBvciBub3QgInllcyIuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0Qm9vbGVhblByb3BlcnR5KFN0cmluZyBrZXksIFByb3BlcnRpZXMgcHJvcHMpCi0gIHsKLQotICAgIFN0cmluZyBzID0gcHJvcHMuZ2V0UHJvcGVydHkoa2V5KTsKLQotICAgIGlmIChudWxsID09IHMgfHwhcy5lcXVhbHMoInllcyIpKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiB0cnVlOwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IGFuIG91dHB1dCBwcm9wZXJ0eS4KLSAgICoKLSAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIGJlIHBsYWNlZCBpbnRvIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gPHR0PmtleTwvdHQ+LgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW50UHJvcGVydHkoUU5hbWUga2V5LCBpbnQgdmFsdWUpCi0gIHsKLSAgICBzZXRJbnRQcm9wZXJ0eShrZXkudG9OYW1lc3BhY2VkU3RyaW5nKCksIHZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gb3V0cHV0IHByb3BlcnR5LgotICAgKgotICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gYmUgcGxhY2VkIGludG8gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgY29ycmVzcG9uZGluZyB0byA8dHQ+a2V5PC90dD4uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbnRQcm9wZXJ0eShTdHJpbmcga2V5LCBpbnQgdmFsdWUpCi0gIHsKLSAgICBtX3Byb3BlcnRpZXMucHV0KGtleSwgSW50ZWdlci50b1N0cmluZyh2YWx1ZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgaW50IHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIElmIHRoZSBrZXkgaXMgbm90IGZvdW5kIGluIHRoaXMgcHJvcGVydHkgbGlzdCwgdGhlIGRlZmF1bHQgcHJvcGVydHkgbGlzdCwKLSAgICogYW5kIGl0cyBkZWZhdWx0cywgcmVjdXJzaXZlbHksIGFyZSB0aGVuIGNoZWNrZWQuIFRoZSBtZXRob2QgcmV0dXJucwotICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBmb3VuZCwgb3IgaWYgdGhlIHZhbHVlIGlzIG90aGVyCi0gICAqIHRoYW4gInllcyIuCi0gICAqCi0gICAqIEBwYXJhbSAgIGtleSAgIHRoZSBwcm9wZXJ0eSBrZXkuCi0gICAqIEByZXR1cm4gIHRoZSB2YWx1ZSBpbiB0aGlzIHByb3BlcnR5IGxpc3QgYXMgYSBpbnQgdmFsdWUsIG9yIGZhbHNlCi0gICAqIGlmIG51bGwgb3Igbm90IGEgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbnRQcm9wZXJ0eShRTmFtZSBrZXkpCi0gIHsKLSAgICByZXR1cm4gZ2V0SW50UHJvcGVydHkoa2V5LnRvTmFtZXNwYWNlZFN0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGludCBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQsIG9yIGlmIHRoZSB2YWx1ZSBpcyBvdGhlcgotICAgKiB0aGFuICJ5ZXMiLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IGFzIGEgaW50IHZhbHVlLCBvciBmYWxzZQotICAgKiBpZiBudWxsIG9yIG5vdCBhIG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0SW50UHJvcGVydHkoU3RyaW5nIGtleSkKLSAgewotICAgIHJldHVybiBnZXRJbnRQcm9wZXJ0eShrZXksIG1fcHJvcGVydGllcyk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBpbnQgcHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBpbiB0aGUgcHJvcGVydHkgbGlzdC4KLSAgICogSWYgdGhlIGtleSBpcyBub3QgZm91bmQgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0LCB0aGUgZGVmYXVsdCBwcm9wZXJ0eSBsaXN0LAotICAgKiBhbmQgaXRzIGRlZmF1bHRzLCByZWN1cnNpdmVseSwgYXJlIHRoZW4gY2hlY2tlZC4gVGhlIG1ldGhvZCByZXR1cm5zCi0gICAqIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IGZvdW5kLCBvciBpZiB0aGUgdmFsdWUgaXMgb3RoZXIKLSAgICogdGhhbiAieWVzIi4KLSAgICoKLSAgICogQHBhcmFtICAga2V5ICAgdGhlIHByb3BlcnR5IGtleS4KLSAgICogQHBhcmFtICAgcHJvcHMgICB0aGUgbGlzdCBvZiBwcm9wZXJ0aWVzIHRoYXQgd2lsbCBiZSBzZWFyY2hlZC4KLSAgICogQHJldHVybiAgdGhlIHZhbHVlIGluIHRoaXMgcHJvcGVydHkgbGlzdCBhcyBhIGludCB2YWx1ZSwgb3IgMAotICAgKiBpZiBudWxsIG9yIG5vdCBhIG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IGdldEludFByb3BlcnR5KFN0cmluZyBrZXksIFByb3BlcnRpZXMgcHJvcHMpCi0gIHsKLQotICAgIFN0cmluZyBzID0gcHJvcHMuZ2V0UHJvcGVydHkoa2V5KTsKLQotICAgIGlmIChudWxsID09IHMpCi0gICAgICByZXR1cm4gMDsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludChzKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gb3V0cHV0IHByb3BlcnR5IHdpdGggYSBRTmFtZSB2YWx1ZS4gIFRoZSBRTmFtZSB3aWxsIGJlIHR1cm5lZAotICAgKiBpbnRvIGEgc3RyaW5nIHdpdGggdGhlIG5hbWVzcGFjZSBpbiBjdXJseSBicmFja2V0cy4KLSAgICoKLSAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIGJlIHBsYWNlZCBpbnRvIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gPHR0PmtleTwvdHQ+LgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UU5hbWVQcm9wZXJ0eShRTmFtZSBrZXksIFFOYW1lIHZhbHVlKQotICB7Ci0gICAgc2V0UU5hbWVQcm9wZXJ0eShrZXkudG9OYW1lc3BhY2VkU3RyaW5nKCksIHZhbHVlKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBkZWZhdWx0IHByb3BlcnRpZXMgYmFzZWQgb24gdGhlIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIG1ldGhvZCB0aGUgbWV0aG9kIHZhbHVlLgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TWV0aG9kRGVmYXVsdHMoU3RyaW5nIG1ldGhvZCkKLSAgewotICAgIFN0cmluZyBkZWZhdWx0TWV0aG9kID0gbV9wcm9wZXJ0aWVzLmdldFByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9EKTsKLSAgICBpZigobnVsbCA9PSBkZWZhdWx0TWV0aG9kKSB8fCAhZGVmYXVsdE1ldGhvZC5lcXVhbHMobWV0aG9kKSkKLSAgICB7Ci0gICAgICBQcm9wZXJ0aWVzIHNhdmVkUHJvcHMgPSBtX3Byb3BlcnRpZXM7Ci0gICAgICBQcm9wZXJ0aWVzIG5ld0RlZmF1bHRzID0gZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMobWV0aG9kKTsKLSAgICAgIG1fcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKG5ld0RlZmF1bHRzKTsKLSAgICAgIGNvcHlGcm9tKHNhdmVkUHJvcHMsIGZhbHNlKTsKLSAgICB9Ci0gIH0KLSAgCi0KLSAgLyoqCi0gICAqIFNldCBhbiBvdXRwdXQgcHJvcGVydHkgd2l0aCBhIFFOYW1lIHZhbHVlLiAgVGhlIFFOYW1lIHdpbGwgYmUgdHVybmVkCi0gICAqIGludG8gYSBzdHJpbmcgd2l0aCB0aGUgbmFtZXNwYWNlIGluIGN1cmx5IGJyYWNrZXRzLgotICAgKgotICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gYmUgcGxhY2VkIGludG8gdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgY29ycmVzcG9uZGluZyB0byA8dHQ+a2V5PC90dD4uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRRTmFtZVByb3BlcnR5KFN0cmluZyBrZXksIFFOYW1lIHZhbHVlKQotICB7Ci0gICAgc2V0UHJvcGVydHkoa2V5LCB2YWx1ZS50b05hbWVzcGFjZWRTdHJpbmcoKSk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBxbmFtZSBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHBhcmFtICAga2V5ICAgdGhlIHByb3BlcnR5IGtleS4KLSAgICogQHJldHVybiAgdGhlIHZhbHVlIGluIHRoaXMgcHJvcGVydHkgbGlzdCBhcyBhIFFOYW1lIHZhbHVlLCBvciBmYWxzZQotICAgKiBpZiBudWxsIG9yIG5vdCAieWVzIi4KLSAgICovCi0gIHB1YmxpYyBRTmFtZSBnZXRRTmFtZVByb3BlcnR5KFFOYW1lIGtleSkKLSAgewotICAgIHJldHVybiBnZXRRTmFtZVByb3BlcnR5KGtleS50b05hbWVzcGFjZWRTdHJpbmcoKSk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBxbmFtZSBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHBhcmFtICAga2V5ICAgdGhlIHByb3BlcnR5IGtleS4KLSAgICogQHJldHVybiAgdGhlIHZhbHVlIGluIHRoaXMgcHJvcGVydHkgbGlzdCBhcyBhIFFOYW1lIHZhbHVlLCBvciBmYWxzZQotICAgKiBpZiBudWxsIG9yIG5vdCAieWVzIi4KLSAgICovCi0gIHB1YmxpYyBRTmFtZSBnZXRRTmFtZVByb3BlcnR5KFN0cmluZyBrZXkpCi0gIHsKLSAgICByZXR1cm4gZ2V0UU5hbWVQcm9wZXJ0eShrZXksIG1fcHJvcGVydGllcyk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBxbmFtZSBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHBhcmFtICAga2V5ICAgdGhlIHByb3BlcnR5IGtleS4KLSAgICogQHBhcmFtIHByb3BzIHRoZSBsaXN0IG9mIHByb3BlcnRpZXMgdG8gc2VhcmNoIGluLgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IGFzIGEgUU5hbWUgdmFsdWUsIG9yIGZhbHNlCi0gICAqIGlmIG51bGwgb3Igbm90ICJ5ZXMiLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBRTmFtZSBnZXRRTmFtZVByb3BlcnR5KFN0cmluZyBrZXksIFByb3BlcnRpZXMgcHJvcHMpCi0gIHsKLQotICAgIFN0cmluZyBzID0gcHJvcHMuZ2V0UHJvcGVydHkoa2V5KTsKLQotICAgIGlmIChudWxsICE9IHMpCi0gICAgICByZXR1cm4gUU5hbWUuZ2V0UU5hbWVGcm9tU3RyaW5nKHMpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvdXRwdXQgcHJvcGVydHkgd2l0aCBhIFFOYW1lIGxpc3QgdmFsdWUuICBUaGUgUU5hbWVzIHdpbGwgYmUgdHVybmVkCi0gICAqIGludG8gc3RyaW5ncyB3aXRoIHRoZSBuYW1lc3BhY2UgaW4gY3VybHkgYnJhY2tldHMuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byBiZSBwbGFjZWQgaW50byB0aGUgcHJvcGVydHkgbGlzdC4KLSAgICogQHBhcmFtIHYgbm9uLW51bGwgbGlzdCBvZiBRTmFtZXMgY29ycmVzcG9uZGluZyB0byA8dHQ+a2V5PC90dD4uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRRTmFtZVByb3BlcnRpZXMoUU5hbWUga2V5LCBWZWN0b3IgdikKLSAgewotICAgIHNldFFOYW1lUHJvcGVydGllcyhrZXkudG9OYW1lc3BhY2VkU3RyaW5nKCksIHYpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvdXRwdXQgcHJvcGVydHkgd2l0aCBhIFFOYW1lIGxpc3QgdmFsdWUuICBUaGUgUU5hbWVzIHdpbGwgYmUgdHVybmVkCi0gICAqIGludG8gc3RyaW5ncyB3aXRoIHRoZSBuYW1lc3BhY2UgaW4gY3VybHkgYnJhY2tldHMuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byBiZSBwbGFjZWQgaW50byB0aGUgcHJvcGVydHkgbGlzdC4KLSAgICogQHBhcmFtIHYgbm9uLW51bGwgbGlzdCBvZiBRTmFtZXMgY29ycmVzcG9uZGluZyB0byA8dHQ+a2V5PC90dD4uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRRTmFtZVByb3BlcnRpZXMoU3RyaW5nIGtleSwgVmVjdG9yIHYpCi0gIHsKLQotICAgIGludCBzID0gdi5zaXplKCk7Ci0KLSAgICAvLyBKdXN0IGFuIGluaXRpYWwgZ3Vlc3MgYXQgcmVhc29uYWJsZSB0dW5pbmcgcGFyYW1ldGVycwotICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIoOSw5KTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgczsgaSsrKQotICAgIHsKLSAgICAgIFFOYW1lIHFuYW1lID0gKFFOYW1lKSB2LmVsZW1lbnRBdChpKTsKLQotICAgICAgZnNiLmFwcGVuZChxbmFtZS50b05hbWVzcGFjZWRTdHJpbmcoKSk7Ci0gICAgICAvLyBEb24ndCBhcHBlbmQgc3BhY2UgYWZ0ZXIgbGFzdCB2YWx1ZQotICAgICAgaWYgKGkgPCBzLTEpIAotICAgICAgICBmc2IuYXBwZW5kKCcgJyk7Ci0gICAgfQotCi0gICAgbV9wcm9wZXJ0aWVzLnB1dChrZXksIGZzYi50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGxpc3Qgb2YgcW5hbWUgcHJvcGVydGllcyB3aXRoIHRoZSBzcGVjaWZpZWQga2V5IGluCi0gICAqIHRoZSBwcm9wZXJ0eSBsaXN0LgotICAgKiBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGlzIHByb3BlcnR5IGxpc3QsIHRoZSBkZWZhdWx0IHByb3BlcnR5IGxpc3QsCi0gICAqIGFuZCBpdHMgZGVmYXVsdHMsIHJlY3Vyc2l2ZWx5LCBhcmUgdGhlbiBjaGVja2VkLiBUaGUgbWV0aG9kIHJldHVybnMKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHBhcmFtICAga2V5ICAgdGhlIHByb3BlcnR5IGtleS4KLSAgICogQHJldHVybiAgdGhlIHZhbHVlIGluIHRoaXMgcHJvcGVydHkgbGlzdCBhcyBhIHZlY3RvciBvZiBRTmFtZXMsIG9yIGZhbHNlCi0gICAqIGlmIG51bGwgb3Igbm90ICJ5ZXMiLgotICAgKi8KLSAgcHVibGljIFZlY3RvciBnZXRRTmFtZVByb3BlcnRpZXMoUU5hbWUga2V5KQotICB7Ci0gICAgcmV0dXJuIGdldFFOYW1lUHJvcGVydGllcyhrZXkudG9OYW1lc3BhY2VkU3RyaW5nKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgbGlzdCBvZiBxbmFtZSBwcm9wZXJ0aWVzIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgaW4KLSAgICogdGhlIHByb3BlcnR5IGxpc3QuCi0gICAqIElmIHRoZSBrZXkgaXMgbm90IGZvdW5kIGluIHRoaXMgcHJvcGVydHkgbGlzdCwgdGhlIGRlZmF1bHQgcHJvcGVydHkgbGlzdCwKLSAgICogYW5kIGl0cyBkZWZhdWx0cywgcmVjdXJzaXZlbHksIGFyZSB0aGVuIGNoZWNrZWQuIFRoZSBtZXRob2QgcmV0dXJucwotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgcHJvcGVydHkgaXMgbm90IGZvdW5kLgotICAgKgotICAgKiBAcGFyYW0gICBrZXkgICB0aGUgcHJvcGVydHkga2V5LgotICAgKiBAcmV0dXJuICB0aGUgdmFsdWUgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0IGFzIGEgdmVjdG9yIG9mIFFOYW1lcywgb3IgZmFsc2UKLSAgICogaWYgbnVsbCBvciBub3QgInllcyIuCi0gICAqLwotICBwdWJsaWMgVmVjdG9yIGdldFFOYW1lUHJvcGVydGllcyhTdHJpbmcga2V5KQotICB7Ci0gICAgcmV0dXJuIGdldFFOYW1lUHJvcGVydGllcyhrZXksIG1fcHJvcGVydGllcyk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBsaXN0IG9mIHFuYW1lIHByb3BlcnRpZXMgd2l0aCB0aGUgc3BlY2lmaWVkIGtleSBpbgotICAgKiB0aGUgcHJvcGVydHkgbGlzdC4KLSAgICogSWYgdGhlIGtleSBpcyBub3QgZm91bmQgaW4gdGhpcyBwcm9wZXJ0eSBsaXN0LCB0aGUgZGVmYXVsdCBwcm9wZXJ0eSBsaXN0LAotICAgKiBhbmQgaXRzIGRlZmF1bHRzLCByZWN1cnNpdmVseSwgYXJlIHRoZW4gY2hlY2tlZC4gVGhlIG1ldGhvZCByZXR1cm5zCi0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBwcm9wZXJ0eSBpcyBub3QgZm91bmQuCi0gICAqCi0gICAqIEBwYXJhbSAgIGtleSAgIHRoZSBwcm9wZXJ0eSBrZXkuCi0gICAqIEBwYXJhbSBwcm9wcyB0aGUgbGlzdCBvZiBwcm9wZXJ0aWVzIHRvIHNlYXJjaCBpbi4KLSAgICogQHJldHVybiAgdGhlIHZhbHVlIGluIHRoaXMgcHJvcGVydHkgbGlzdCBhcyBhIHZlY3RvciBvZiBRTmFtZXMsIG9yIGZhbHNlCi0gICAqIGlmIG51bGwgb3Igbm90ICJ5ZXMiLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBWZWN0b3IgZ2V0UU5hbWVQcm9wZXJ0aWVzKFN0cmluZyBrZXksIFByb3BlcnRpZXMgcHJvcHMpCi0gIHsKLQotICAgIFN0cmluZyBzID0gcHJvcHMuZ2V0UHJvcGVydHkoa2V5KTsKLQotICAgIGlmIChudWxsICE9IHMpCi0gICAgewotICAgICAgVmVjdG9yIHYgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICBpbnQgbCA9IHMubGVuZ3RoKCk7Ci0gICAgICBib29sZWFuIGluQ3VybHkgPSBmYWxzZTsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIoKTsKLQotICAgICAgLy8gcGFyc2UgdGhyb3VnaCBzdHJpbmcsIGJyZWFraW5nIG9uIHdoaXRlc3BhY2VzLiAgSSBkbyB0aGlzIGluc3RlYWQgCi0gICAgICAvLyBvZiBhIHRva2VuaXplciBzbyBJIGNhbiB0cmFjayB3aGl0ZXNwYWNlIGluc2lkZSBvZiBjdXJseSBicmFja2V0cywgCi0gICAgICAvLyB3aGljaCB0aGVvcmV0aWNhbGx5IHNob3VsZG4ndCBoYXBwZW4gaWYgdGhleSBjb250YWluIGxlZ2FsIFVSTHMuCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGw7IGkrKykKLSAgICAgIHsKLSAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7Ci0KLSAgICAgICAgaWYgKENoYXJhY3Rlci5pc1doaXRlc3BhY2UoYykpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoIWluQ3VybHkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGJ1Zi5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFFOYW1lIHFuYW1lID0gUU5hbWUuZ2V0UU5hbWVGcm9tU3RyaW5nKGJ1Zi50b1N0cmluZygpKTsKLSAgICAgICAgICAgICAgdi5hZGRFbGVtZW50KHFuYW1lKTsKLSAgICAgICAgICAgICAgYnVmLnJlc2V0KCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoJ3snID09IGMpCi0gICAgICAgICAgaW5DdXJseSA9IHRydWU7Ci0gICAgICAgIGVsc2UgaWYgKCd9JyA9PSBjKQotICAgICAgICAgIGluQ3VybHkgPSBmYWxzZTsKLQotICAgICAgICBidWYuYXBwZW5kKGMpOwotICAgICAgfQotCi0gICAgICBpZiAoYnVmLmxlbmd0aCgpID4gMCkKLSAgICAgIHsKLSAgICAgICAgUU5hbWUgcW5hbWUgPSBRTmFtZS5nZXRRTmFtZUZyb21TdHJpbmcoYnVmLnRvU3RyaW5nKCkpOwotICAgICAgICB2LmFkZEVsZW1lbnQocW5hbWUpOwotICAgICAgICBidWYucmVzZXQoKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHY7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIHJlY29tcG9zZSBhbGwgb2YgdGhlIG91dHB1dCBmb3JtYXQgZXh0ZW5kZWQgZWxlbWVudHMuCi0gICAqCi0gICAqIEBwYXJhbSByb290IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgc3R5bGVzaGVldCByb290IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlY29tcG9zZShTdHlsZXNoZWV0Um9vdCByb290KQotICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcm9vdC5yZWNvbXBvc2VPdXRwdXQodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgZXZlcnl0aGluZyBlbHNlIGhhcyBiZWVuCi0gICAqIHJlY29tcG9zZWQsIGFuZCBhbGxvd3MgdGhlIHRlbXBsYXRlIHRvIHNldCByZW1haW5pbmcKLSAgICogdmFsdWVzIHRoYXQgbWF5IGJlIGJhc2VkIG9uIHNvbWUgb3RoZXIgcHJvcGVydHkgdGhhdAotICAgKiBkZXBlbmRzIG9uIHJlY29tcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21wb3NlKFN0eWxlc2hlZXRSb290IHNyb290KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIuY29tcG9zZShzcm9vdCk7Ci0KLSAgICBtX3Byb3BlcnRpZXNMZXZlbHMgPSBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgUHJvcGVydGllcyBvYmplY3QgdGhhdCB0aGlzIGNsYXNzIHdyYXBzLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBQcm9wZXJ0aWVzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBQcm9wZXJ0aWVzIGdldFByb3BlcnRpZXMoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJvcGVydGllczsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvcHkgdGhlIGtleXMgYW5kIHZhbHVlcyBmcm9tIHRoZSBzb3VyY2UgdG8gdGhpcyBvYmplY3QuICBUaGlzIHdpbGwKLSAgICogbm90IGNvcHkgdGhlIGRlZmF1bHQgdmFsdWVzLiAgVGhpcyBpcyBtZWFudCB0byBiZSB1c2VkIGJ5IGdvaW5nIGZyb20KLSAgICogYSBoaWdoZXIgcHJlY2VkZW5jZSBvYmplY3QgdG8gYSBsb3dlciBwcmVjZWRlbmNlIG9iamVjdCwgc28gdGhhdCBpZiBhCi0gICAqIGtleSBhbHJlYWR5IGV4aXN0cywgdGhpcyBtZXRob2Qgd2lsbCBub3QgcmVzZXQgaXQuCi0gICAqCi0gICAqIEBwYXJhbSBzcmMgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBzb3VyY2UgcHJvcGVydGllcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvcHlGcm9tKFByb3BlcnRpZXMgc3JjKQotICB7Ci0gICAgY29weUZyb20oc3JjLCB0cnVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IHRoZSBrZXlzIGFuZCB2YWx1ZXMgZnJvbSB0aGUgc291cmNlIHRvIHRoaXMgb2JqZWN0LiAgVGhpcyB3aWxsCi0gICAqIG5vdCBjb3B5IHRoZSBkZWZhdWx0IHZhbHVlcy4gIFRoaXMgaXMgbWVhbnQgdG8gYmUgdXNlZCBieSBnb2luZyBmcm9tCi0gICAqIGEgaGlnaGVyIHByZWNlZGVuY2Ugb2JqZWN0IHRvIGEgbG93ZXIgcHJlY2VkZW5jZSBvYmplY3QsIHNvIHRoYXQgaWYgYQotICAgKiBrZXkgYWxyZWFkeSBleGlzdHMsIHRoaXMgbWV0aG9kIHdpbGwgbm90IHJlc2V0IGl0LgotICAgKgotICAgKiBAcGFyYW0gc3JjIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgc291cmNlIHByb3BlcnRpZXMuCi0gICAqIEBwYXJhbSBzaG91bGRSZXNldERlZmF1bHRzIHRydWUgaWYgdGhlIGRlZmF1bHRzIHNob3VsZCBiZSByZXNldCBiYXNlZCBvbiAKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG1ldGhvZCBwcm9wZXJ0eS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvcHlGcm9tKFByb3BlcnRpZXMgc3JjLCBib29sZWFuIHNob3VsZFJlc2V0RGVmYXVsdHMpCi0gIHsKLQotICAgIEVudW1lcmF0aW9uIGVudW0gPSBzcmMua2V5cygpOwotCi0gICAgd2hpbGUgKGVudW0uaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpIGVudW0ubmV4dEVsZW1lbnQoKTsKLSAgICAgIE9iamVjdCBvbGRWYWx1ZSA9IG1fcHJvcGVydGllcy5nZXQoa2V5KTsKLSAgICAgIGlmIChudWxsID09IG9sZFZhbHVlKQotICAgICAgewotICAgICAgICBTdHJpbmcgdmFsID0gKFN0cmluZykgc3JjLmdldChrZXkpOwotICAgICAgICAKLSAgICAgICAgaWYoc2hvdWxkUmVzZXREZWZhdWx0cyAmJiBrZXkuZXF1YWxzKE91dHB1dEtleXMuTUVUSE9EKSkKLSAgICAgICAgewotICAgICAgICAgIHNldE1ldGhvZERlZmF1bHRzKHZhbCk7Ci0gICAgICAgIH0KLQotICAgICAgICBtX3Byb3BlcnRpZXMucHV0KGtleSwgdmFsKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGtleS5lcXVhbHMoT3V0cHV0S2V5cy5DREFUQV9TRUNUSU9OX0VMRU1FTlRTKSkKLSAgICAgIHsKLSAgICAgICAgbV9wcm9wZXJ0aWVzLnB1dChrZXksIChTdHJpbmcpIG9sZFZhbHVlICsgIiAiICsgKFN0cmluZykgc3JjLmdldChrZXkpKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29weSB0aGUga2V5cyBhbmQgdmFsdWVzIGZyb20gdGhlIHNvdXJjZSB0byB0aGlzIG9iamVjdC4gIFRoaXMgd2lsbAotICAgKiBub3QgY29weSB0aGUgZGVmYXVsdCB2YWx1ZXMuICBUaGlzIGlzIG1lYW50IHRvIGJlIHVzZWQgYnkgZ29pbmcgZnJvbQotICAgKiBhIGhpZ2hlciBwcmVjZWRlbmNlIG9iamVjdCB0byBhIGxvd2VyIHByZWNlZGVuY2Ugb2JqZWN0LCBzbyB0aGF0IGlmIGEKLSAgICoga2V5IGFscmVhZHkgZXhpc3RzLCB0aGlzIG1ldGhvZCB3aWxsIG5vdCByZXNldCBpdC4KLSAgICoKLSAgICogQHBhcmFtIG9wc3JjIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhbiBPdXRwdXRQcm9wZXJ0aWVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29weUZyb20oT3V0cHV0UHJvcGVydGllcyBvcHNyYykKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGNoZWNrRHVwbGljYXRlcyhvcHNyYyk7Ci0gICAgY29weUZyb20ob3BzcmMuZ2V0UHJvcGVydGllcygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0byBzZWUgaWYgYSBzZXQgb2YgcHJvcGVydGllcyBpcyBhdCB0aGUgc2FtZSBpbXBvcnQgbGV2ZWwgYXMgdGhlCi0gICAqIGxhc3Qgc2V0IG9mIHByb3BlcnRpZXMgc2V0IHRoYXQgd2FzIHBhc3NlZCBhcyBhbiBhcmd1bWVudCB0byB0aGlzIG1ldGhvZC4KLSAgICogVGhpcyBvcGVyYXRpb24gYXNzdW1lcyB0aGF0IHRoZSBPdXRwdXRQcm9wZXJ0aWVzIGFyZSBiZWluZyBjYWxsZWQKLSAgICogZnJvbSBtb3N0IGltcG9ydGFudCB0byBsZWFzdCBpbXBvcnRhbnQsIGluIGRvY3VtZW50IG9yZGVyLgotICAgKgotICAgKiBAcGFyYW0gbmV3UHJvcHMgbm9uLW51bGwgcmVmZXJlbmNlIHRvIE91dHB1dFByb3BlcnRpZXMgdGhhdCBpcyBhYm91dCB0bwotICAgKiAgICAgICAgICAgICAgICAgYmUgYWRkZWQgdG8gdGhpcyBzZXQuCi0gICAqLwotICBwcml2YXRlIHZvaWQgY2hlY2tEdXBsaWNhdGVzKE91dHB1dFByb3BlcnRpZXMgbmV3UHJvcHMpCi0gICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fcHJvcGVydGllc0xldmVscykKLSAgICAgIG1fcHJvcGVydGllc0xldmVscyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIC8vIFRoaXMgb3BlcmF0aW9uIGFzc3VtZXMgdGhhdCB0aGUgT3V0cHV0UHJvcGVydGllcyBhcmUgYmVpbmcgY2FsbGVkIAotICAgIC8vIGZyb20gbW9zdCBpbXBvcnRhbnQgdG8gbGVhc3QgaW1wb3J0YW50LCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotCi0gICAgaW50IG5ld1ByZWNlZGVuY2UgPSBuZXdQcm9wcy5nZXRTdHlsZXNoZWV0Q29tcG9zZWQoKS5nZXRJbXBvcnRDb3VudENvbXBvc2VkKCk7Ci0KLSAgICBQcm9wZXJ0aWVzIHAgPSBuZXdQcm9wcy5nZXRQcm9wZXJ0aWVzKCk7Ci0gICAgRW51bWVyYXRpb24gZW51bSA9IHAua2V5cygpOwotCi0gICAgd2hpbGUgKGVudW0uaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpIGVudW0ubmV4dEVsZW1lbnQoKTsKLQotICAgICAgaWYgKGtleS5lcXVhbHMoT3V0cHV0S2V5cy5DREFUQV9TRUNUSU9OX0VMRU1FTlRTKSkKLSAgICAgICAgY29udGludWU7Ci0KLSAgICAgIC8vIERvIHdlIGFscmVhZHkgaGF2ZSB0aGlzIHByb3BlcnR5PyBDYWxsIGhhc2h0YWJsZSBvcGVyYXRpb24sIAotICAgICAgLy8gc2luY2Ugd2UgZG9uJ3Qgd2FudCB0byBsb29rIGF0IGRlZmF1bHQgcHJvcGVydGllcy4KLSAgICAgIEludGVnZXIgb2xkUHJlY2VkZW5jZSA9IChJbnRlZ2VyKSBtX3Byb3BlcnRpZXNMZXZlbHMuZ2V0KGtleSk7Ci0gICAgICBpZiAobnVsbCA9PSBvbGRQcmVjZWRlbmNlKQotICAgICAgewotICAgICAgICBtX3Byb3BlcnRpZXNMZXZlbHMucHV0KGtleSwgbmV3IEludGVnZXIobmV3UHJlY2VkZW5jZSkpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAobmV3UHJlY2VkZW5jZSA+PSBvbGRQcmVjZWRlbmNlLmludFZhbHVlKCkpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBvbGRWYWx1ZSA9IChTdHJpbmcpIHRoaXMubV9wcm9wZXJ0aWVzLmdldChrZXkpOwotICAgICAgICBTdHJpbmcgbmV3VmFsdWUgPSAoU3RyaW5nKSBuZXdQcm9wcy5tX3Byb3BlcnRpZXMuZ2V0KGtleSk7Ci0gICAgICAgIGlmICggKChvbGRWYWx1ZSA9PSBudWxsKSAmJiAobmV3VmFsdWUgIT0gbnVsbCkpIHx8ICFvbGRWYWx1ZS5lcXVhbHMobmV3VmFsdWUpICkKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBtc2cgPSBrZXkgKyAiIGNhbiBub3QgYmUgbXVsdGlwbHkgZGVmaW5lZCBhdCB0aGUgc2FtZSAiCi0gICAgICAgICAgICAgICAgICAgICAgICsgImltcG9ydCBsZXZlbCEgT2xkIHZhbHVlID0gIiAKLSAgICAgICAgICAgICAgICAgICAgICAgKyBvbGRWYWx1ZSArICI7IE5ldyB2YWx1ZSA9ICIgKyBuZXdWYWx1ZTsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obXNnLCBuZXdQcm9wcyk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci19Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBpZiB0aGUga2V5IGdpdmVuIGFzIGFuIGFyZ3VtZW50IGlzIGEgbGVnYWwgeHNsOm91dHB1dCBrZXkuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGtleSBuYW1lLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYga2V5IGlzIGxlZ2FsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNMZWdhbFByb3BlcnR5S2V5KFN0cmluZyBrZXkpCi0gIHsKLQotICAgIHJldHVybiAoa2V5LmVxdWFscyhPdXRwdXRLZXlzLkNEQVRBX1NFQ1RJT05fRUxFTUVOVFMpCi0gICAgICAgICAgICB8fCBrZXkuZXF1YWxzKE91dHB1dEtleXMuRE9DVFlQRV9QVUJMSUMpCi0gICAgICAgICAgICB8fCBrZXkuZXF1YWxzKE91dHB1dEtleXMuRE9DVFlQRV9TWVNURU0pCi0gICAgICAgICAgICB8fCBrZXkuZXF1YWxzKE91dHB1dEtleXMuRU5DT0RJTkcpCi0gICAgICAgICAgICB8fCBrZXkuZXF1YWxzKE91dHB1dEtleXMuSU5ERU5UKQotICAgICAgICAgICAgfHwga2V5LmVxdWFscyhPdXRwdXRLZXlzLk1FRElBX1RZUEUpCi0gICAgICAgICAgICB8fCBrZXkuZXF1YWxzKE91dHB1dEtleXMuTUVUSE9EKQotICAgICAgICAgICAgfHwga2V5LmVxdWFscyhPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OKQotICAgICAgICAgICAgfHwga2V5LmVxdWFscyhPdXRwdXRLZXlzLlNUQU5EQUxPTkUpCi0gICAgICAgICAgICB8fCBrZXkuZXF1YWxzKE91dHB1dEtleXMuVkVSU0lPTikKLSAgICAgICAgICAgIHx8IChrZXkubGVuZ3RoKCkgPiAwKSAmJiAoa2V5LmNoYXJBdCgwKSA9PSAneycpKTsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhpcyB1Z2x5IGZpZWxkIGlzIHVzZWQgZHVyaW5nIHJlY29tcG9zaXRpb24gdG8gdHJhY2sgdGhlIGltcG9ydCBwcmVjZWRlbmNlCi0gICAqICBhdCB3aGljaCBlYWNoIGF0dHJpYnV0ZSB3YXMgZmlyc3Qgc3BlY2lmaWVkLCBzbyB3ZSBjYW4gZmxhZyBlcnJvcnMgYWJvdXQgdmFsdWVzIGJlaW5nCi0gICAqICBzZXQgbXVsdGlwbGUgdGltZSBhdCB0aGUgc2FtZSBwcmVjZWRlbmNlIGxldmVsLiBOb3RlIHRoYXQgdGhpcyBmaWVsZCBpcyBvbmx5IHVzZWQKLSAgICogIGR1cmluZyByZWNvbXBvc2l0aW9uLCB3aXRoIHRoZSBPdXRwdXRQcm9wZXJ0aWVzIG9iamVjdCBvd25lZCBieSB0aGUKLSAgICogIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdH0gb2JqZWN0LgotICAgKi8KLSAgcHJpdmF0ZSB0cmFuc2llbnQgSGFzaHRhYmxlIG1fcHJvcGVydGllc0xldmVsczsKLQotICAvKiogVGhlIG91dHB1dCBwcm9wZXJ0aWVzLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIFByb3BlcnRpZXMgbV9wcm9wZXJ0aWVzID0gbnVsbDsKLQotICAvLyBTb21lIHNwZWNpYWwgWGFsYW4ga2V5cy4KLQotICAvKiogVGhlIG51bWJlciBvZiB3aGl0ZXNwYWNlcyB0byBpbmRlbnQgYnksIGlmIGluZGVudD0ieWVzIi4gKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgU19LRVlfSU5ERU5UX0FNT1VOVCA9Ci0gICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMKyJpbmRlbnQtYW1vdW50IjsKLQotICAvKioKLSAgICogRnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgY2xhc3Mgd2l0aCBhIGRlZmF1bHQgY29uc3RydWN0b3IgdGhhdAotICAgKiAgaW1wbGVtZW50cyB0aGUgQ29udGVudEhhbmRsZXIgaW50ZXJmYWNlLCB3aGVyZSB0aGUgcmVzdWx0IHRyZWUgZXZlbnRzCi0gICAqICB3aWxsIGJlIHNlbnQgdG8uICAgICAgCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBTX0tFWV9DT05URU5UX0hBTkRMRVIgPQotICAgIFNfQlVJTFRJTl9FWFRFTlNJT05TX1VOSVZFUlNBTCsiY29udGVudC1oYW5kbGVyIjsKLQotICAvKiogRmlsZSBuYW1lIG9mIGZpbGUgdGhhdCBzcGVjaWZpZXMgY2hhcmFjdGVyIHRvIGVudGl0eSByZWZlcmVuY2UgbWFwcGluZ3MuICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIFNfS0VZX0VOVElUSUVTID0KLSAgICBTX0JVSUxUSU5fRVhURU5TSU9OU19VTklWRVJTQUwrImVudGl0aWVzIjsKLQotICAvKiogVXNlIGEgdmFsdWUgb2YgInllcyIgaWYgdGhlIGhyZWYgdmFsdWVzIGZvciBIVE1MIHNlcmlhbGl6YXRpb24gc2hvdWxkIAotICAgKiAgdXNlICV4eCBlc2NhcGluZy4gKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgU19VU0VfVVJMX0VTQ0FQSU5HID0KLSAgICBTX0JVSUxUSU5fRVhURU5TSU9OU19VTklWRVJTQUwrInVzZS11cmwtZXNjYXBpbmciOwotCi0gIC8qKiBVc2UgYSB2YWx1ZSBvZiAieWVzIiBpZiB0aGUgTUVUQSB0YWcgc2hvdWxkIGJlIG9taXR0ZWQgd2hlcmUgaXQgd291bGQKLSAgICogIG90aGVyd2lzZSBiZSBzdXBwbGllZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIFNfT01JVF9NRVRBX1RBRyA9Ci0gICAgU19CVUlMVElOX0VYVEVOU0lPTlNfVU5JVkVSU0FMKyJvbWl0LW1ldGEtdGFnIjsKLQotICAvKiogVGhlIGRlZmF1bHQgcHJvcGVydGllcyBvZiBhbGwgb3V0cHV0IGZpbGVzLiAqLwotICBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIG1feG1sX3Byb3BlcnRpZXMgPSBudWxsOwotCi0gIC8qKiBUaGUgZGVmYXVsdCBwcm9wZXJ0aWVzIHdoZW4gbWV0aG9kPSJodG1sIi4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgUHJvcGVydGllcyBtX2h0bWxfcHJvcGVydGllcyA9IG51bGw7Ci0KLSAgLyoqIFRoZSBkZWZhdWx0IHByb3BlcnRpZXMgd2hlbiBtZXRob2Q9InRleHQiLiAqLwotICBwcml2YXRlIHN0YXRpYyBQcm9wZXJ0aWVzIG1fdGV4dF9wcm9wZXJ0aWVzID0gbnVsbDsKLQotICAvKiogU3luY2hyb25pemF0aW9uIG9iamVjdCBmb3IgbGF6eSBpbml0aWFsaXphdGlvbiBvZiB0aGUgYWJvdmUgdGFibGVzLiAqLwotICBwcml2YXRlIHN0YXRpYyBJbnRlZ2VyIG1fc3luY2hfb2JqZWN0ID0gbmV3IEludGVnZXIoMSk7Ci0KLSAgLyoqIGEgemVybyBsZW5ndGggQ2xhc3MgYXJyYXkgdXNlZCBpbiBsb2FkUHJvcGVydGllc0ZpbGUoKSAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDbGFzc1tdIE5PX0NMQVNTRVMgPSBuZXcgQ2xhc3NbMF07Ci0KLSAgLyoqIGEgemVybyBsZW5ndGggT2JqZWN0IGFycmF5IHVzZWQgaW4gbG9hZFByb3BlcnRpZXNGaWxlKCkgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0W10gTk9fT0JKUyA9IG5ldyBPYmplY3RbMF07Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9TdHlsZXNoZWV0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvU3R5bGVzaGVldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NjY1YTc4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9TdHlsZXNoZWV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDAzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vLyBKYXZhIGltcG9ydHMKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXRTdHJlYW07Ci0KLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vLyBYYWxhbiBpbXBvcnRzCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLQotLy8gRE9NIEltcG9ydHMKLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi0vLyBTQVgyIEltcG9ydHMKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLS8qKgotICogUmVwcmVzZW50cyBhIHN0eWxlc2hlZXQgZWxlbWVudC4KLSAqIDxwPkFsbCBwcm9wZXJ0aWVzIGluIHRoaXMgY2xhc3MgaGF2ZSBhIGZpeGVkIGZvcm0gb2YgYmVhbi1zdHlsZSBwcm9wZXJ0eQotICogYWNjZXNzb3JzIGZvciBhbGwgcHJvcGVydGllcyB0aGF0IHJlcHJlc2VudCBYU0wgYXR0cmlidXRlcyBvciBlbGVtZW50cy4KLSAqIFRoZXNlIHByb3BlcnRpZXMgaGF2ZSBzZXR0ZXIgbWV0aG9kIG5hbWVzIGFjY2Vzc2VkIGdlbmVyaWNhbGx5IGJ5IHRoZQotICogcHJvY2Vzc29yLCBhbmQgc28gdGhlc2UgbmFtZXMgbXVzdCBiZSBmaXhlZCBhY2NvcmRpbmcgdG8gdGhlIHN5c3RlbQotICogZGVmaW5lZCBpbiB0aGUgPGEgaHJlZj0iWFNMVEF0dHJpYnV0ZURlZiNnZXRTZXR0ZXJNZXRob2ROYW1lIj5nZXRTZXR0ZXJNZXRob2ROYW1lPC9hPgotICogZnVuY3Rpb24uPC9wPgotICogPHA+PHByZT4KLSAqIDwhRU5USVRZICUgdG9wLWxldmVsICIKLSAqICAoeHNsOmltcG9ydCosCi0gKiAgICh4c2w6aW5jbHVkZQotICogICB8IHhzbDpzdHJpcC1zcGFjZQotICogICB8IHhzbDpwcmVzZXJ2ZS1zcGFjZQotICogICB8IHhzbDpvdXRwdXQKLSAqICAgfCB4c2w6a2V5Ci0gKiAgIHwgeHNsOmRlY2ltYWwtZm9ybWF0Ci0gKiAgIHwgeHNsOmF0dHJpYnV0ZS1zZXQKLSAqICAgfCB4c2w6dmFyaWFibGUKLSAqICAgfCB4c2w6cGFyYW0KLSAqICAgfCB4c2w6dGVtcGxhdGUKLSAqICAgfCB4c2w6bmFtZXNwYWNlLWFsaWFzCi0gKiAgICVub24teHNsLXRvcC1sZXZlbDspKikKLSAqICI+Ci0gKgotICogPCFFTlRJVFkgJSB0b3AtbGV2ZWwtYXR0cyAnCi0gKiAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIENEQVRBICNJTVBMSUVECi0gKiAgIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIENEQVRBICNJTVBMSUVECi0gKiAgIGlkIElEICNJTVBMSUVECi0gKiAgIHZlcnNpb24gTk1UT0tFTiAjUkVRVUlSRUQKLSAqICAgeG1sbnM6eHNsIENEQVRBICNGSVhFRCAiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICogICAlc3BhY2UtYXR0OwotICogJz4KLSAqCi0gKiA8IUVMRU1FTlQgeHNsOnN0eWxlc2hlZXQgJXRvcC1sZXZlbDs+Ci0gKiA8IUFUVExJU1QgeHNsOnN0eWxlc2hlZXQgJXRvcC1sZXZlbC1hdHRzOz4KLSAqCi0gKiA8IUVMRU1FTlQgeHNsOnRyYW5zZm9ybSAldG9wLWxldmVsOz4KLSAqIDwhQVRUTElTVCB4c2w6dHJhbnNmb3JtICV0b3AtbGV2ZWwtYXR0czs+Ci0gKgotICogPC9wPjwvcHJlPgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3NlY3Rpb24tU3R5bGVzaGVldC1TdHJ1Y3R1cmUiPnNlY3Rpb24tU3R5bGVzaGVldC1TdHJ1Y3R1cmUgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICovCi1wdWJsaWMgY2xhc3MgU3R5bGVzaGVldCBleHRlbmRzIEVsZW1UZW1wbGF0ZUVsZW1lbnQKLSAgICAgICAgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSAvKiAsIERvY3VtZW50ICovCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBhIFN0eWxlc2hlZXQuCi0gICAqIEBwYXJhbSBwYXJlbnQgIFRoZSBpbmNsdWRpbmcgb3IgaW1wb3J0aW5nIHN0eWxlc2hlZXQuCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldChTdHlsZXNoZWV0IHBhcmVudCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gcGFyZW50KQotICAgIHsKLSAgICAgIG1fc3R5bGVzaGVldFBhcmVudCA9IHBhcmVudDsKLSAgICAgIG1fc3R5bGVzaGVldFJvb3QgPSBwYXJlbnQuZ2V0U3R5bGVzaGVldFJvb3QoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvd25pbmcgc3R5bGVzaGVldC4gIFRoaXMgbG9va3MgdXAgdGhlCi0gICAqIGluaGVyaXRhbmNlIGNoYWluIHVudGlsIGl0IGNhbGxzIGdldFN0eWxlc2hlZXQKLSAgICogb24gYSBTdHlsZXNoZWV0IG9iamVjdCwgd2hpY2ggd2lsbCByZXR1cm4gaXRzZWxmLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvd25pbmcgc3R5bGVzaGVldCwgaXRzZWxmLgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXQgZ2V0U3R5bGVzaGVldCgpCi0gIHsKLSAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgY2FuIGJlIGNhc3QgdG8gYSBTdHlsZXNoZWV0Q29tcG9zZWQsIG1lYW5pbmcsIHlvdQotICAgKiBjYW4gYXNrIHF1ZXN0aW9ucyBmcm9tIGdldFhYWENvbXBvc2VkIGZ1bmN0aW9ucy4KLSAgICoKLSAgICogQHJldHVybiBGYWxzZSBpZiB0aGlzIGlzIG5vdCBhIFN0eWxlc2hlZXRDb21wb3NlZAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNBZ2dyZWdhdGVkVHlwZSgpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGlzIHRoZSByb290IG9mIHRoZSBzdHlsZXNoZWV0IHRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gRmFsc2UgaXMgdGhpcyBpcyBub3QgdGhlIHJvb3Qgb2YgdGhlIHN0eWxlc2hlZXQgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUm9vdCgpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogRXh0ZW5zaW9uIHRvIGJlIHVzZWQgd2hlbiBzZXJpYWxpemluZyB0byBkaXNrLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RZTEVTSEVFVF9FWFQgPSAiLmx4YyI7Ci0KLSAgLyoqCi0gICAqIFJlYWQgdGhlIHN0eWxlc2hlZXQgZnJvbSBhIHNlcmlhbGl6YXRpb24gc3RyZWFtLgotICAgKgotICAgKiBAcGFyYW0gc3RyZWFtIElucHV0IHN0cmVhbSB0byByZWFkIGZyb20KLSAgICoKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pCi0gICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlJlYWRpbmcgU3R5bGVzaGVldCIpOwotICAgIHRyeQotICAgIHsKLSAgICAgIHN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihjbmZlKTsKLSAgICB9Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkRvbmUgcmVhZGluZyBTdHlsZXNoZWV0Iik7Ci0gIH0KLQotICAvKioKLSAgICogV3JpdGUgb3V0IHRoZSBnaXZlbiBvdXRwdXQgc3RyZWFtIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gc3RyZWFtIFRoZSBvdXRwdXQgc3RyZWFtIHRvIHdyaXRlIG91dAotICAgKgotICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgd3JpdGVPYmplY3QoT2JqZWN0T3V0cHV0U3RyZWFtIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiV3JpdGluZyBTdHlsZXNoZWV0Iik7Ci0gICAgc3RyZWFtLmRlZmF1bHRXcml0ZU9iamVjdCgpOwotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJEb25lIHdyaXRpbmcgU3R5bGVzaGVldCIpOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PSBYU0xUIFByb3BlcnRpZXMgPT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGhlICJ4bWxuczp4c2wiIHByb3BlcnR5LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX1htbG5zWHNsOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJ4bWxuczp4c2wiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjeHNsdC1uYW1lc3BhY2UiPnhzbHQtbmFtZXNwYWNlIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVGhlIHZhbHVlIHRvIGJlIHNldCBmb3IgdGhlICJ4bWxuczp4c2wiIHByb3BlcnR5LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0WG1sbnNYc2woU3RyaW5nIHYpCi0gIHsKLSAgICBtX1htbG5zWHNsID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJ4bWxuczp4c2wiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjeHNsdC1uYW1lc3BhY2UiPnhzbHQtbmFtZXNwYWNlIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlICJ4bWxuczp4c2wiIHByb3BlcnR5LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRYbWxuc1hzbCgpCi0gIHsKLSAgICByZXR1cm4gbV9YbWxuc1hzbDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiBwcm9wZXJ0eSwgYWN0dWFsbHkgY29udGFpbnMgVVJJcy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmdWZWN0b3IgbV9FeHRlbnNpb25FbGVtZW50VVJJczsKLQotICAvKioKLSAgICogU2V0IHRoZSAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZXh0ZW5zaW9uLWVsZW1lbnQiPmV4dGVuc2lvbi1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVGhlIHZhbHVlIHRvIGJlIHNldCBmb3IgdGhlICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIgCi0gICAqIHByb3BlcnR5OiBhIHZlY3RvciBvZiBleHRlbnNpb24gZWxlbWVudCBVUklzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzKFN0cmluZ1ZlY3RvciB2KQotICB7Ci0gICAgbV9FeHRlbnNpb25FbGVtZW50VVJJcyA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuZCAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4IiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2V4dGVuc2lvbi1lbGVtZW50Ij5leHRlbnNpb24tZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIGV4dGVuc2lvbiBlbGVtZW50IFVSSSBpbiBsaXN0IAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBleHRlbnNpb24gZWxlbWVudCBVUkkgYXQgdGhlIGdpdmVuIGluZGV4Ci0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEV4dGVuc2lvbkVsZW1lbnRQcmVmaXgoaW50IGkpCi0gICAgICAgICAgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX0V4dGVuc2lvbkVsZW1lbnRVUklzKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmV0dXJuIG1fRXh0ZW5zaW9uRWxlbWVudFVSSXMuZWxlbWVudEF0KGkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIgU3RyaW5ncy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2V4dGVuc2lvbi1lbGVtZW50Ij5leHRlbnNpb24tZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIFVSSXMgaW4gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RXh0ZW5zaW9uRWxlbWVudFByZWZpeENvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX0V4dGVuc2lvbkVsZW1lbnRVUklzKQotICAgICAgICAgICA/IG1fRXh0ZW5zaW9uRWxlbWVudFVSSXMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIG91dCBpZiB0aGlzIGNvbnRhaW5zIGEgZ2l2ZW4gImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeCIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNleHRlbnNpb24tZWxlbWVudCI+ZXh0ZW5zaW9uLWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdXJpIFVSSSBvZiBleHRlbnNpb24gZWxlbWVudCB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIFVSSSB3YXMgZm91bmQgaW4gdGhlIGxpc3QgCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0V4dGVuc2lvbkVsZW1lbnRVUkkoU3RyaW5nIHVyaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9FeHRlbnNpb25FbGVtZW50VVJJcykKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIHJldHVybiBtX0V4dGVuc2lvbkVsZW1lbnRVUklzLmNvbnRhaW5zKHVyaSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgcHJvcGVydHkuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nVmVjdG9yIG1fRXhjbHVkZVJlc3VsdFByZWZpeHM7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBwcm9wZXJ0eS4KLSAgICogVGhlIGRlc2lnbmF0aW9uIG9mIGEgbmFtZXNwYWNlIGFzIGFuIGV4Y2x1ZGVkIG5hbWVzcGFjZSBpcwotICAgKiBlZmZlY3RpdmUgd2l0aGluIHRoZSBzdWJ0cmVlIG9mIHRoZSBzdHlsZXNoZWV0IHJvb3RlZCBhdAotICAgKiB0aGUgZWxlbWVudCBiZWFyaW5nIHRoZSBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBvcgotICAgKiB4c2w6ZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgYXR0cmlidXRlOyBhIHN1YnRyZWUgcm9vdGVkCi0gICAqIGF0IGFuIHhzbDpzdHlsZXNoZWV0IGVsZW1lbnQgZG9lcyBub3QgaW5jbHVkZSBhbnkgc3R5bGVzaGVldHMKLSAgICogaW1wb3J0ZWQgb3IgaW5jbHVkZWQgYnkgY2hpbGRyZW4gb2YgdGhhdCB4c2w6c3R5bGVzaGVldCBlbGVtZW50LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbGl0ZXJhbC1yZXN1bHQtZWxlbWVudCI+bGl0ZXJhbC1yZXN1bHQtZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IEEgU3RyaW5nVmVjdG9yIG9mIHByZWZpeGVzIHRvIGV4Y2x1ZGUgCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeGNsdWRlUmVzdWx0UHJlZml4ZXMoU3RyaW5nVmVjdG9yIHYpCi0gIHsKLSAgICBtX0V4Y2x1ZGVSZXN1bHRQcmVmaXhzID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gImV4Y2x1ZGUtcmVzdWx0LXByZWZpeCIgcHJvcGVydHkuCi0gICAqIFRoZSBkZXNpZ25hdGlvbiBvZiBhIG5hbWVzcGFjZSBhcyBhbiBleGNsdWRlZCBuYW1lc3BhY2UgaXMKLSAgICogZWZmZWN0aXZlIHdpdGhpbiB0aGUgc3VidHJlZSBvZiB0aGUgc3R5bGVzaGVldCByb290ZWQgYXQKLSAgICogdGhlIGVsZW1lbnQgYmVhcmluZyB0aGUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgb3IKLSAgICogeHNsOmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIGF0dHJpYnV0ZTsgYSBzdWJ0cmVlIHJvb3RlZAotICAgKiBhdCBhbiB4c2w6c3R5bGVzaGVldCBlbGVtZW50IGRvZXMgbm90IGluY2x1ZGUgYW55IHN0eWxlc2hlZXRzCi0gICAqIGltcG9ydGVkIG9yIGluY2x1ZGVkIGJ5IGNoaWxkcmVuIG9mIHRoYXQgeHNsOnN0eWxlc2hlZXQgZWxlbWVudC4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2xpdGVyYWwtcmVzdWx0LWVsZW1lbnQiPmxpdGVyYWwtcmVzdWx0LWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBwcmVmaXggdG8gZ2V0IGluIGxpc3QgCi0gICAqCi0gICAqIEByZXR1cm4gUHJlZml4IHRvIGJlIGV4Y2x1ZGVkIGF0IHRoZSBnaXZlbiBpbmRleAotICAgKgotICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRFeGNsdWRlUmVzdWx0UHJlZml4KGludCBpKQotICAgICAgICAgIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9FeGNsdWRlUmVzdWx0UHJlZml4cykKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKLQotICAgIHJldHVybiBtX0V4Y2x1ZGVSZXN1bHRQcmVmaXhzLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiAiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMiIFN0cmluZ3MuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNsaXRlcmFsLXJlc3VsdC1lbGVtZW50Ij5saXRlcmFsLXJlc3VsdC1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHByZWZpeCBzdHJpbmdzIHRvIGJlIGV4Y2x1ZGVkLiAKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RXhjbHVkZVJlc3VsdFByZWZpeENvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX0V4Y2x1ZGVSZXN1bHRQcmVmaXhzKQotICAgICAgICAgICA/IG1fRXhjbHVkZVJlc3VsdFByZWZpeHMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgd2hldGhlciBvciBub3QgdGhlIHBhc3NlZCBwcmVmaXggaXMgY29udGFpbmVkIGZsYWdnZWQgYnkKLSAgICogdGhlICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNsaXRlcmFsLXJlc3VsdC1lbGVtZW50Ij5saXRlcmFsLXJlc3VsdC1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBub24tbnVsbCByZWZlcmVuY2UgdG8gcHJlZml4IHRoYXQgbWlnaHQgYmUgZXhjbHVkZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJlZml4IHNob3VsZCBub3JtYWxseSBiZSBleGNsdWRlZC4+Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0V4Y2x1ZGVSZXN1bHRQcmVmaXgoU3RyaW5nIHByZWZpeCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9FeGNsdWRlUmVzdWx0UHJlZml4cykKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGlmIChwcmVmaXgubGVuZ3RoKCkgPT0gMCkKLSAgICAgIHByZWZpeCA9IENvbnN0YW50cy5BVFRSVkFMX0RFRkFVTFRfUFJFRklYOwotCi0gICAgcmV0dXJuIG1fRXhjbHVkZVJlc3VsdFByZWZpeHMuY29udGFpbnMocHJlZml4KTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgImlkIiBwcm9wZXJ0eS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9JZDsKLQotICAvKioKLSAgICogU2V0IHRoZSAiaWQiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1FbWJlZGRpbmctU3R5bGVzaGVldHMiPnNlY3Rpb24tRW1iZWRkaW5nLVN0eWxlc2hlZXRzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgVmFsdWUgZm9yIHRoZSAiaWQiIHByb3BlcnR5LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SWQoU3RyaW5nIHYpCi0gIHsKLSAgICBtX0lkID0gdjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlICJpZCIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLUVtYmVkZGluZy1TdHlsZXNoZWV0cyI+c2VjdGlvbi1FbWJlZGRpbmctU3R5bGVzaGVldHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgImlkIiBwcm9wZXJ0eS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0SWQoKQotICB7Ci0gICAgcmV0dXJuIG1fSWQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJ2ZXJzaW9uIiBwcm9wZXJ0eS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9WZXJzaW9uOwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJ2ZXJzaW9uIiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2ZvcndhcmRzIj5mb3J3YXJkcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFZhbHVlIGZvciB0aGUgInZlcnNpb24iIHByb3BlcnR5LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihTdHJpbmcgdikKLSAgewotICAgIG1fVmVyc2lvbiA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAidmVyc2lvbiIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNmb3J3YXJkcyI+Zm9yd2FyZHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgInZlcnNpb24iIHByb3BlcnR5LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRWZXJzaW9uKCkKLSAgewotICAgIHJldHVybiBtX1ZlcnNpb247Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJ4c2w6aW1wb3J0IiBsaXN0LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFZlY3RvciBtX2ltcG9ydHM7Ci0KLSAgLyoqCi0gICAqIEFkZCBhIHN0eWxlc2hlZXQgdG8gdGhlICJpbXBvcnQiIGxpc3QuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNpbXBvcnQiPmltcG9ydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFN0eWxlc2hlZXQgdG8gYWRkIHRvIHRoZSBpbXBvcnQgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW1wb3J0KFN0eWxlc2hlZXRDb21wb3NlZCB2KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2ltcG9ydHMpCi0gICAgICBtX2ltcG9ydHMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAvLyBJJ20gZ29pbmcgdG8gaW5zZXJ0IHRoZSBlbGVtZW50cyBpbiBiYWNrd2FyZHMgb3JkZXIsCi0gICAgLy8gc28gSSBjYW4gd2FsayB0aGVtIDAgdG8gbi4KLSAgICBtX2ltcG9ydHMuYWRkRWxlbWVudCh2KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBzdHlsZXNoZWV0IGZyb20gdGhlICJpbXBvcnQiIGxpc3QuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNpbXBvcnQiPmltcG9ydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHRoZSBzdHlsZXNoZWV0IHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHlsZXNoZWV0IGF0IHRoZSBnaXZlbiBpbmRleAotICAgKgotICAgKiBAdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0eWxlc2hlZXRDb21wb3NlZCBnZXRJbXBvcnQoaW50IGkpCi0gICAgICAgICAgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2ltcG9ydHMpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKFN0eWxlc2hlZXRDb21wb3NlZCkgbV9pbXBvcnRzLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBzdHlsZXNoZWV0cy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2ltcG9ydCI+aW1wb3J0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIHN0eWxlc2hlZXRzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbXBvcnRDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9pbXBvcnRzKSA/IG1faW1wb3J0cy5zaXplKCkgOiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAieHNsOmluY2x1ZGUiIHByb3BlcnRpZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1faW5jbHVkZXM7Ci0KLSAgLyoqCi0gICAqIEFkZCBhIHN0eWxlc2hlZXQgdG8gdGhlICJpbmNsdWRlIiBsaXN0LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjaW5jbHVkZSI+aW5jbHVkZSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IFN0eWxlc2hlZXQgdG8gYWRkIHRvIHRoZSAiaW5jbHVkZSIgbGlzdCAgCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbmNsdWRlKFN0eWxlc2hlZXQgdikKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9pbmNsdWRlcykKLSAgICAgIG1faW5jbHVkZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBtX2luY2x1ZGVzLmFkZEVsZW1lbnQodik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzdHlsZXNoZWV0IGF0IHRoZSBnaXZlbiBpbiBpbmRleCBpbiAiaW5jbHVkZSIgbGlzdAotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjaW5jbHVkZSI+aW5jbHVkZSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHN0eWxlc2hlZXQgdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4gU3R5bGVzaGVldCBhdCB0aGUgZ2l2ZW4gaW5kZXgKLSAgICoKLSAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0IGdldEluY2x1ZGUoaW50IGkpIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9pbmNsdWRlcykKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKLQotICAgIHJldHVybiAoU3R5bGVzaGVldCkgbV9pbmNsdWRlcy5lbGVtZW50QXQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2YgaW5jbHVkZWQgc3R5bGVzaGVldHMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNpbXBvcnQiPmltcG9ydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBpbmNsdWRlZCBzdHlsZXNoZWV0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0SW5jbHVkZUNvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX2luY2x1ZGVzKSA/IG1faW5jbHVkZXMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBUYWJsZSBvZiB0YWJsZXMgb2YgZWxlbWVudCBkZWNpbWFsLWZvcm1hdC4KLSAgICogQHNlZSBEZWNpbWFsRm9ybWF0UHJvcGVydGllcwotICAgKiBAc2VyaWFsCi0gICAqLwotICBTdGFjayBtX0RlY2ltYWxGb3JtYXREZWNsYXJhdGlvbnM7Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgdGhlIHhzbDpkZWNpbWFsLWZvcm1hdCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gZWRmIERlY2ltYWwtZm9ybWF0IGVsZW1lbnQgdG8gcHVzaCBpbnRvIHN0YWNrICAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERlY2ltYWxGb3JtYXQoRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMgZWRmKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX0RlY2ltYWxGb3JtYXREZWNsYXJhdGlvbnMpCi0gICAgICBtX0RlY2ltYWxGb3JtYXREZWNsYXJhdGlvbnMgPSBuZXcgU3RhY2soKTsKLQotICAgIC8vIEVsZW1lbnRzIGFyZSBwdXNoZWQgaW4gYnkgb3JkZXIgb2YgaW1wb3J0YW5jZQotICAgIC8vIHNvIHRoYXQgd2hlbiByZWNvbXBvc2VkLCB0aGV5IGdldCBvdmVyaWRlbiBwcm9wZXJseS4KLSAgICBtX0RlY2ltYWxGb3JtYXREZWNsYXJhdGlvbnMucHVzaChlZGYpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOmRlY2ltYWwtZm9ybWF0IiBwcm9wZXJ0eS4KLSAgICogCi0gICAqIEBzZWUgRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMKLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Zvcm1hdC1udW1iZXIiPmZvcm1hdC1udW1iZXIgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRlY2ltYWwgZm9ybWF0IHByb3BlcnR5LgotICAgKiBAcmV0dXJuIG51bGwgaWYgbm90IGZvdW5kLCBvdGhlcndpc2UgYSBEZWNpbWFsRm9ybWF0UHJvcGVydGllcwotICAgKiBvYmplY3QsIGZyb20gd2hpY2ggeW91IGNhbiBnZXQgYSBEZWNpbWFsRm9ybWF0U3ltYm9scyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMgZ2V0RGVjaW1hbEZvcm1hdChRTmFtZSBuYW1lKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX0RlY2ltYWxGb3JtYXREZWNsYXJhdGlvbnMpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIGludCBuID0gZ2V0RGVjaW1hbEZvcm1hdENvdW50KCk7Ci0KLSAgICBmb3IgKGludCBpID0gKG4gLSAxKTsgaSA+PSAwOyBpKyspCi0gICAgewotICAgICAgRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMgZGZwID0gZ2V0RGVjaW1hbEZvcm1hdChpKTsKLQotICAgICAgaWYgKGRmcC5nZXROYW1lKCkuZXF1YWxzKG5hbWUpKQotICAgICAgICByZXR1cm4gZGZwOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOmRlY2ltYWwtZm9ybWF0IiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2Zvcm1hdC1udW1iZXIiPmZvcm1hdC1udW1iZXIgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKiBAc2VlIERlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzCi0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIGRlY2ltYWwtZm9ybWF0IHByb3BlcnR5IGluIHN0YWNrCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRlY2ltYWwtZm9ybWF0IHByb3BlcnR5IGF0IHRoZSBnaXZlbiBpbmRleCAKLSAgICoKLSAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBEZWNpbWFsRm9ybWF0UHJvcGVydGllcyBnZXREZWNpbWFsRm9ybWF0KGludCBpKQotICAgICAgICAgIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9EZWNpbWFsRm9ybWF0RGVjbGFyYXRpb25zKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmV0dXJuIChEZWNpbWFsRm9ybWF0UHJvcGVydGllcykgbV9EZWNpbWFsRm9ybWF0RGVjbGFyYXRpb25zLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiB4c2w6ZGVjaW1hbC1mb3JtYXQgZGVjbGFyYXRpb25zLgotICAgKiBAc2VlIERlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiB4c2w6ZGVjaW1hbC1mb3JtYXQgZGVjbGFyYXRpb25zLgotICAgKi8KLSAgcHVibGljIGludCBnZXREZWNpbWFsRm9ybWF0Q291bnQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fRGVjaW1hbEZvcm1hdERlY2xhcmF0aW9ucykKLSAgICAgICAgICAgPyBtX0RlY2ltYWxGb3JtYXREZWNsYXJhdGlvbnMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgInhzbDpzdHJpcC1zcGFjZSIgcHJvcGVydGllcywKLSAgICogQSBsb29rdXAgdGFibGUgb2YgYWxsIHNwYWNlIHN0cmlwcGluZyBlbGVtZW50cy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV93aGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudHM7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInhzbDpzdHJpcC1zcGFjZSIgcHJvcGVydGllcy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3N0cmlwIj5zdHJpcCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB3c2kgV2hpdGVTcGFjZUluZm8gZWxlbWVudCB0byBhZGQgdG8gbGlzdCAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN0cmlwU3BhY2VzKFdoaXRlU3BhY2VJbmZvIHdzaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV93aGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudHMpCi0gICAgewotICAgICAgbV93aGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudHMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgfQotCi0gICAgbV93aGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudHMuYWRkRWxlbWVudCh3c2kpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOnN0cmlwLXNwYWNlIiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3N0cmlwIj5zdHJpcCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIFdoaXRlU3BhY2VJbmZvIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIFdoaXRlU3BhY2VJbmZvIGF0IGdpdmVuIGluZGV4Ci0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV2hpdGVTcGFjZUluZm8gZ2V0U3RyaXBTcGFjZShpbnQgaSkgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX3doaXRlc3BhY2VTdHJpcHBpbmdFbGVtZW50cykKLSAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKLQotICAgIHJldHVybiAoV2hpdGVTcGFjZUluZm8pIG1fd2hpdGVzcGFjZVN0cmlwcGluZ0VsZW1lbnRzLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiAieHNsOnN0cmlwLXNwYWNlIiBwcm9wZXJ0aWVzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mICJ4c2w6c3RyaXAtc3BhY2UiIHByb3BlcnRpZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0cmlwU3BhY2VDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV93aGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudHMpCi0gICAgICAgICAgID8gbV93aGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudHMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgInhzbDpwcmVzZXJ2ZS1zcGFjZSIgcHJvcGVydHksCi0gICAqIEEgbG9va3VwIHRhYmxlIG9mIGFsbCBzcGFjZSBwcmVzZXJ2aW5nIGVsZW1lbnRzLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFZlY3RvciBtX3doaXRlc3BhY2VQcmVzZXJ2aW5nRWxlbWVudHM7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInhzbDpwcmVzZXJ2ZS1zcGFjZSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzdHJpcCI+c3RyaXAgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gd3NpIFdoaXRlU3BhY2VJbmZvIGVsZW1lbnQgdG8gYWRkIHRvIGxpc3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZXNlcnZlU3BhY2VzKFdoaXRlU3BhY2VJbmZvIHdzaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV93aGl0ZXNwYWNlUHJlc2VydmluZ0VsZW1lbnRzKQotICAgIHsKLSAgICAgIG1fd2hpdGVzcGFjZVByZXNlcnZpbmdFbGVtZW50cyA9IG5ldyBWZWN0b3IoKTsKLSAgICB9Ci0KLSAgICBtX3doaXRlc3BhY2VQcmVzZXJ2aW5nRWxlbWVudHMuYWRkRWxlbWVudCh3c2kpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhICJ4c2w6cHJlc2VydmUtc3BhY2UiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgV2hpdGVTcGFjZUluZm8gdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4gV2hpdGVTcGFjZUluZm8gYXQgdGhlIGdpdmVuIGluZGV4Ci0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV2hpdGVTcGFjZUluZm8gZ2V0UHJlc2VydmVTcGFjZShpbnQgaSkgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX3doaXRlc3BhY2VQcmVzZXJ2aW5nRWxlbWVudHMpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKFdoaXRlU3BhY2VJbmZvKSBtX3doaXRlc3BhY2VQcmVzZXJ2aW5nRWxlbWVudHMuZWxlbWVudEF0KGkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mICJ4c2w6cHJlc2VydmUtc3BhY2UiIHByb3BlcnRpZXMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzdHJpcCI+c3RyaXAgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgInhzbDpwcmVzZXJ2ZS1zcGFjZSIgcHJvcGVydGllcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UHJlc2VydmVTcGFjZUNvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3doaXRlc3BhY2VQcmVzZXJ2aW5nRWxlbWVudHMpCi0gICAgICAgICAgID8gbV93aGl0ZXNwYWNlUHJlc2VydmluZ0VsZW1lbnRzLnNpemUoKSA6IDA7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJ4c2w6b3V0cHV0IiBwcm9wZXJ0aWVzLiAgVGhpcyBpcyBhIHZlY3RvciBvZiBPdXRwdXRQcm9wZXJ0aWVzIG9iamVjdHMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fb3V0cHV0OwotCi0gIC8qKgotICAgKiBTZXQgdGhlICJ4c2w6b3V0cHV0IiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+b3V0cHV0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBPdXRwdXRQcm9wZXJ0aWVzIG9iamVjdCB0byBiZSAKLSAgICogICAgICAgICAgYWRkZWQgdG8gdGhlIGNvbGxlY3Rpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRPdXRwdXQoT3V0cHV0UHJvcGVydGllcyB2KQotICB7Ci0gICAgaWYgKG51bGwgPT0gbV9vdXRwdXQpCi0gICAgewotICAgICAgbV9vdXRwdXQgPSBuZXcgVmVjdG9yKCk7Ci0gICAgfQotCi0gICAgbV9vdXRwdXQuYWRkRWxlbWVudCh2KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gInhzbDpvdXRwdXQiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij5vdXRwdXQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBPdXRwdXRGb3JtYXRFeHRlbmRlZCB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gYW4gT3V0cHV0UHJvcGVydGllcyBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT3V0cHV0UHJvcGVydGllcyBnZXRPdXRwdXQoaW50IGkpIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9vdXRwdXQpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKE91dHB1dFByb3BlcnRpZXMpIG1fb3V0cHV0LmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiAieHNsOm91dHB1dCIgcHJvcGVydGllcy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I291dHB1dCI+b3V0cHV0IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIE91dHB1dFByb3BlcnRpZXMgb2JqZWN0cyBjb250YWluZWQgaW4gdGhpcyBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRPdXRwdXRDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9vdXRwdXQpCi0gICAgICAgICAgID8gbV9vdXRwdXQuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgInhzbDprZXkiIHByb3BlcnR5LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFZlY3RvciBtX2tleURlY2xhcmF0aW9uczsKLQotICAvKioKLSAgICogU2V0IHRoZSAieHNsOmtleSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNrZXkiPmtleSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB2IEtleURlY2xhcmF0aW9uIGVsZW1lbnQgdG8gYWRkIHRvIHRoZSBsaXN0IG9mIGtleSBkZWNsYXJhdGlvbnMgCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRLZXkoS2V5RGVjbGFyYXRpb24gdikKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9rZXlEZWNsYXJhdGlvbnMpCi0gICAgICBtX2tleURlY2xhcmF0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLQotICAgIG1fa2V5RGVjbGFyYXRpb25zLmFkZEVsZW1lbnQodik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuICJ4c2w6a2V5IiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2tleSI+a2V5IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgS2V5RGVjbGFyYXRpb24gZWxlbWVudCB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiBLZXlEZWNsYXJhdGlvbiBlbGVtZW50IGF0IGdpdmVuIGluZGV4IGluIGxpc3QgCi0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgS2V5RGVjbGFyYXRpb24gZ2V0S2V5KGludCBpKSB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fa2V5RGVjbGFyYXRpb25zKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmV0dXJuIChLZXlEZWNsYXJhdGlvbikgbV9rZXlEZWNsYXJhdGlvbnMuZWxlbWVudEF0KGkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mICJ4c2w6a2V5IiBwcm9wZXJ0aWVzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQja2V5Ij5rZXkgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgInhzbDprZXkiIHByb3BlcnRpZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEtleUNvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX2tleURlY2xhcmF0aW9ucykgPyBtX2tleURlY2xhcmF0aW9ucy5zaXplKCkgOiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAieHNsOmF0dHJpYnV0ZS1zZXQiIHByb3BlcnR5LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFZlY3RvciBtX2F0dHJpYnV0ZVNldHM7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInhzbDphdHRyaWJ1dGUtc2V0IiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2F0dHJpYnV0ZS1zZXRzIj5hdHRyaWJ1dGUtc2V0cyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBhdHRyU2V0IEVsZW1BdHRyaWJ1dGVTZXQgdG8gYWRkIHRvIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZSBzZXRzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVTZXQoRWxlbUF0dHJpYnV0ZVNldCBhdHRyU2V0KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2F0dHJpYnV0ZVNldHMpCi0gICAgewotICAgICAgbV9hdHRyaWJ1dGVTZXRzID0gbmV3IFZlY3RvcigpOwotICAgIH0KLQotICAgIG1fYXR0cmlidXRlU2V0cy5hZGRFbGVtZW50KGF0dHJTZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOmF0dHJpYnV0ZS1zZXQiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjYXR0cmlidXRlLXNldHMiPmF0dHJpYnV0ZS1zZXRzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgRWxlbUF0dHJpYnV0ZVNldCB0byBnZXQgaW4gbGlzdAotICAgKgotICAgKiBAcmV0dXJuIEVsZW1BdHRyaWJ1dGVTZXQgYXQgdGhlIGdpdmVuIGluZGV4Ci0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRWxlbUF0dHJpYnV0ZVNldCBnZXRBdHRyaWJ1dGVTZXQoaW50IGkpCi0gICAgICAgICAgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2F0dHJpYnV0ZVNldHMpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKEVsZW1BdHRyaWJ1dGVTZXQpIG1fYXR0cmlidXRlU2V0cy5lbGVtZW50QXQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2YgInhzbDphdHRyaWJ1dGUtc2V0IiBwcm9wZXJ0aWVzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjYXR0cmlidXRlLXNldHMiPmF0dHJpYnV0ZS1zZXRzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mICJ4c2w6YXR0cmlidXRlLXNldCIgcHJvcGVydGllcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlU2V0Q291bnQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fYXR0cmlidXRlU2V0cykgPyBtX2F0dHJpYnV0ZVNldHMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgInhzbDp2YXJpYWJsZSIgYW5kICJ4c2w6cGFyYW0iIHByb3BlcnRpZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fdG9wTGV2ZWxWYXJpYWJsZXM7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgInhzbDp2YXJpYWJsZSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgRWxlbVZhcmlhYmxlIG9iamVjdCB0byBhZGQgdG8gbGlzdCBvZiB0b3AgbGV2ZWwgdmFyaWFibGVzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRWYXJpYWJsZShFbGVtVmFyaWFibGUgdikKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV90b3BMZXZlbFZhcmlhYmxlcykKLSAgICAgIG1fdG9wTGV2ZWxWYXJpYWJsZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBtX3RvcExldmVsVmFyaWFibGVzLmFkZEVsZW1lbnQodik7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgYW4gInhzbDp2YXJpYWJsZSIgb3IgInhzbDpwYXJhbSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBFbGVtVmFyaWFibGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBpbiB0aGUgbGlzdCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgRWxlbVZhcmlhYmxlIGdldFZhcmlhYmxlT3JQYXJhbShRTmFtZSBxbmFtZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV90b3BMZXZlbFZhcmlhYmxlcykKLSAgICB7Ci0gICAgICBpbnQgbiA9IGdldFZhcmlhYmxlT3JQYXJhbUNvdW50KCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgewotICAgICAgICBFbGVtVmFyaWFibGUgdmFyID0gKEVsZW1WYXJpYWJsZSkgZ2V0VmFyaWFibGVPclBhcmFtKGkpOwotCi0gICAgICAgIGlmICh2YXIuZ2V0TmFtZSgpLmVxdWFscyhxbmFtZSkpCi0gICAgICAgICAgcmV0dXJuIHZhcjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOnZhcmlhYmxlIiBwcm9wZXJ0eS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3RvcC1sZXZlbC12YXJpYWJsZXMiPnRvcC1sZXZlbC12YXJpYWJsZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgUXVhbGlmaWVkIG5hbWUgb2YgdGhlIHhzbDp2YXJpYWJsZSB0byBnZXQgCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHRoZSB2YXJpYWJsZSBuYW1lZCBieSBxbmFtZSwgb3IgbnVsbCBpZiBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgRWxlbVZhcmlhYmxlIGdldFZhcmlhYmxlKFFOYW1lIHFuYW1lKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3RvcExldmVsVmFyaWFibGVzKQotICAgIHsKLSAgICAgIGludCBuID0gZ2V0VmFyaWFibGVPclBhcmFtQ291bnQoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIEVsZW1WYXJpYWJsZSB2YXIgPSBnZXRWYXJpYWJsZU9yUGFyYW0oaSk7Ci0gICAgICAgIGlmKCh2YXIuZ2V0WFNMVG9rZW4oKSA9PSBDb25zdGFudHMuRUxFTU5BTUVfVkFSSUFCTEUpICYmCi0gICAgICAgICAgICh2YXIuZ2V0TmFtZSgpLmVxdWFscyhxbmFtZSkpKQotICAgICAgICAgIHJldHVybiB2YXI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuICJ4c2w6dmFyaWFibGUiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjdG9wLWxldmVsLXZhcmlhYmxlcyI+dG9wLWxldmVsLXZhcmlhYmxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHZhcmlhYmxlIHRvIGdldCBpbiB0aGUgbGlzdAotICAgKgotICAgKiBAcmV0dXJuIEVsZW1WYXJpYWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXggaW4gdGhlIGxpc3QgCi0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRWxlbVZhcmlhYmxlIGdldFZhcmlhYmxlT3JQYXJhbShpbnQgaSkgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX3RvcExldmVsVmFyaWFibGVzKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmV0dXJuIChFbGVtVmFyaWFibGUpIG1fdG9wTGV2ZWxWYXJpYWJsZXMuZWxlbWVudEF0KGkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mICJ4c2w6dmFyaWFibGUiIHByb3BlcnRpZXMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mICJ4c2w6dmFyaWFibGUiIHByb3BlcnRpZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFZhcmlhYmxlT3JQYXJhbUNvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3RvcExldmVsVmFyaWFibGVzKSA/IG1fdG9wTGV2ZWxWYXJpYWJsZXMuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gInhzbDpwYXJhbSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgQSBub24tbnVsbCBFbGVtUGFyYW0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyYW0oRWxlbVBhcmFtIHYpCi0gIHsKLSAgICBzZXRWYXJpYWJsZSh2KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gInhzbDpwYXJhbSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCN0b3AtbGV2ZWwtdmFyaWFibGVzIj50b3AtbGV2ZWwtdmFyaWFibGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIG5vbi1udWxsIHJlZmVyZW5jZSB0byBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgotICAgKgotICAgKiBAcmV0dXJuIEVsZW1QYXJhbSB3aXRoIHRoZSBnaXZlbiBuYW1lIGluIHRoZSBsaXN0IG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBFbGVtUGFyYW0gZ2V0UGFyYW0oUU5hbWUgcW5hbWUpCi0gIHsKLQotICAgIGlmIChudWxsICE9IG1fdG9wTGV2ZWxWYXJpYWJsZXMpCi0gICAgewotICAgICAgaW50IG4gPSBnZXRWYXJpYWJsZU9yUGFyYW1Db3VudCgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgRWxlbVZhcmlhYmxlIHZhciA9IGdldFZhcmlhYmxlT3JQYXJhbShpKTsKLSAgICAgICAgaWYoKHZhci5nZXRYU0xUb2tlbigpID09IENvbnN0YW50cy5FTEVNTkFNRV9QQVJBTVZBUklBQkxFKSAmJgotICAgICAgICAgICAodmFyLmdldE5hbWUoKS5lcXVhbHMocW5hbWUpKSkKLSAgICAgICAgICByZXR1cm4gKEVsZW1QYXJhbSl2YXI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJ4c2w6dGVtcGxhdGUiIHByb3BlcnRpZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fdGVtcGxhdGVzOwotCi0gIC8qKgotICAgKiBTZXQgYW4gInhzbDp0ZW1wbGF0ZSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIj5zZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHYgRWxlbVRlbXBsYXRlIHRvIGFkZCB0byBsaXN0IG9mIHRlbXBsYXRlcwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VGVtcGxhdGUoRWxlbVRlbXBsYXRlIHYpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fdGVtcGxhdGVzKQotICAgICAgbV90ZW1wbGF0ZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBtX3RlbXBsYXRlcy5hZGRFbGVtZW50KHYpOwotICAgIHYuc2V0U3R5bGVzaGVldCh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gInhzbDp0ZW1wbGF0ZSIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIj5zZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgRWxlbVRlbXBsYXRlIGluIHRoZSBsaXN0IHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIEVsZW1UZW1wbGF0ZSBhdCB0aGUgZ2l2ZW4gaW5kZXggaW4gdGhlIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZSBnZXRUZW1wbGF0ZShpbnQgaSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fdGVtcGxhdGVzKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmV0dXJuIChFbGVtVGVtcGxhdGUpIG1fdGVtcGxhdGVzLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiAieHNsOnRlbXBsYXRlIiBwcm9wZXJ0aWVzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1EZWZpbmluZy1UZW1wbGF0ZS1SdWxlcyI+c2VjdGlvbi1EZWZpbmluZy1UZW1wbGF0ZS1SdWxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiAieHNsOnRlbXBsYXRlIiBwcm9wZXJ0aWVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRUZW1wbGF0ZUNvdW50KCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3RlbXBsYXRlcykgPyBtX3RlbXBsYXRlcy5zaXplKCkgOiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAieHNsOm5hbWVzcGFjZS1hbGlhcyIgcHJvcGVydGllcy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9wcmVmaXhfYWxpYXNlczsKLQotICAvKioKLSAgICogU2V0IHRoZSAieHNsOm5hbWVzcGFjZS1hbGlhcyIgcHJvcGVydHkuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNsaXRlcmFsLXJlc3VsdC1lbGVtZW50Ij5saXRlcmFsLXJlc3VsdC1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIG5hIE5hbWVzcGFjZUFsaWFzIGVsZW1lZW50IHRvIGFkZCB0byB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TmFtZXNwYWNlQWxpYXMoTmFtZXNwYWNlQWxpYXMgbmEpCi0gIHsKLQotICAgIGlmIChtX3ByZWZpeF9hbGlhc2VzID09IG51bGwpCi0gICAgICBtX3ByZWZpeF9hbGlhc2VzID0gbmV3IFZlY3RvcigpOwotCi0gICAgbV9wcmVmaXhfYWxpYXNlcy5hZGRFbGVtZW50KG5hKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gInhzbDpuYW1lc3BhY2UtYWxpYXMiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjbGl0ZXJhbC1yZXN1bHQtZWxlbWVudCI+bGl0ZXJhbC1yZXN1bHQtZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIE5hbWVzcGFjZUFsaWFzIGVsZW1lbnQgdG8gZ2V0IGZyb20gdGhlIGxpc3QgCi0gICAqCi0gICAqIEByZXR1cm4gTmFtZXNwYWNlQWxpYXMgZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kZXggaW4gdGhlIGxpc3QKLSAgICoKLSAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOYW1lc3BhY2VBbGlhcyBnZXROYW1lc3BhY2VBbGlhcyhpbnQgaSkKLSAgICAgICAgICB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fcHJlZml4X2FsaWFzZXMpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKE5hbWVzcGFjZUFsaWFzKSBtX3ByZWZpeF9hbGlhc2VzLmVsZW1lbnRBdChpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiAieHNsOm5hbWVzcGFjZS1hbGlhcyIgcHJvcGVydGllcy4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3RvcC1sZXZlbC12YXJpYWJsZXMiPnRvcC1sZXZlbC12YXJpYWJsZXMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgInhzbDpuYW1lc3BhY2UtYWxpYXMiIHByb3BlcnRpZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5hbWVzcGFjZUFsaWFzQ291bnQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fcHJlZml4X2FsaWFzZXMpID8gbV9wcmVmaXhfYWxpYXNlcy5zaXplKCkgOiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSAibm9uLXhzbC10b3AtbGV2ZWwiIHByb3BlcnRpZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgSGFzaHRhYmxlIG1fTm9uWHNsVG9wTGV2ZWw7Ci0KLSAgLyoqCi0gICAqIFNldCBmb3VuZCBhIG5vbi14c2x0IGVsZW1lbnQuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzdHlsZXNoZWV0LWVsZW1lbnQiPnN0eWxlc2hlZXQtZWxlbWVudCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBvYmogVGhlIGVsZW1lbnQgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROb25Yc2xUb3BMZXZlbChRTmFtZSBuYW1lLCBPYmplY3Qgb2JqKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX05vblhzbFRvcExldmVsKQotICAgICAgbV9Ob25Yc2xUb3BMZXZlbCA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIG1fTm9uWHNsVG9wTGV2ZWwucHV0KG5hbWUsIG9iaik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgbm9uLXhzbHQgZWxlbWVudC4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3N0eWxlc2hlZXQtZWxlbWVudCI+c3R5bGVzaGVldC1lbGVtZW50IGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgUXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVsZW1lbnQgdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCBhc3NvY2lhdGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZSAKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgZ2V0Tm9uWHNsVG9wTGV2ZWwoUU5hbWUgbmFtZSkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX05vblhzbFRvcExldmVsKSA/IG1fTm9uWHNsVG9wTGV2ZWwuZ2V0KG5hbWUpIDogbnVsbDsKLSAgfQotCi0gIC8vID09PT09PT09PT09IEVuZCB0b3AtbGV2ZWwgWFNMVCBwcm9wZXJ0aWVzID09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFRoZSBiYXNlIFVSTCBvZiB0aGUgWFNMIGRvY3VtZW50LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBtX2hyZWYgPSBudWxsOwotCi0gIC8qKiBUaGUgZG9jdHlwZS1wdWJsaWMgZWxlbWVudC4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9wdWJsaWNJZDsKLQotICAvKiogVGhlIGRvY3R5cGUtc3lzdGVtIGVsZW1lbnQuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc3lzdGVtSWQ7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYmFzZSBpZGVudGlmaWVyIHdpdGggd2hpY2ggdGhpcyBzdHlsZXNoZWV0IGlzIGFzc29jaWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGJhc2UgaWRlbnRpZmllciB3aXRoIHdoaWNoIHRoaXMgc3R5bGVzaGVldCBpcyBhc3NvY2lhdGVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRIcmVmKCkKLSAgewotICAgIHJldHVybiBtX2hyZWY7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIGlkZW50aWZpZXIgd2l0aCB3aGljaCB0aGlzIHN0eWxlc2hlZXQgaXMgYXNzb2NpYXRlZC4KLSAgICoKLSAgICogQHBhcmFtIGJhc2VJZGVudCB0aGUgYmFzZSBpZGVudGlmaWVyIHdpdGggd2hpY2ggdGhpcyBzdHlsZXNoZWV0IGlzIGFzc29jaWF0ZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRIcmVmKFN0cmluZyBiYXNlSWRlbnQpCi0gIHsKLSAgICBtX2hyZWYgPSBiYXNlSWRlbnQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBmb3IgdGhpcyBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBTb3VyY2VMb2NhdG9yIG9iamVjdCB3aXRoIGxvY2F0aW9uIGluZm9ybWF0aW9uICAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExvY2F0ZXJJbmZvKFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbG9jYXRvcikKLSAgICB7Ci0gICAgICBtX3B1YmxpY0lkID0gbG9jYXRvci5nZXRQdWJsaWNJZCgpOwotICAgICAgbV9zeXN0ZW1JZCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLQotICAgICAgaWYgKG51bGwgIT0gbV9zeXN0ZW1JZCkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBtX2hyZWYgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKG1fc3lzdGVtSWQsIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSkKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gSWdub3JlIHRoaXMgZm9yIHJpZ2h0IG5vdwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHN1cGVyLnNldExvY2F0ZXJJbmZvKGxvY2F0b3IpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUaGUgcm9vdCBvZiB0aGUgc3R5bGVzaGVldCwgd2hlcmUgYWxsIHRoZSB0YWJsZXMgY29tbW9uCi0gICAqIHRvIGFsbCBzdHlsZXNoZWV0cyBhcmUga2VwdC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHlsZXNoZWV0Um9vdCBtX3N0eWxlc2hlZXRSb290OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJvb3Qgb2YgdGhlIHN0eWxlc2hlZXQsIHdoZXJlIGFsbCB0aGUgdGFibGVzIGNvbW1vbgotICAgKiB0byBhbGwgc3R5bGVzaGVldHMgYXJlIGtlcHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJvb3Qgb2YgdGhlIHN0eWxlc2hlZXQKLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdCBnZXRTdHlsZXNoZWV0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZXNoZWV0Um9vdDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHJvb3Qgb2YgdGhlIHN0eWxlc2hlZXQsIHdoZXJlIGFsbCB0aGUgdGFibGVzIGNvbW1vbgotICAgKiB0byBhbGwgc3R5bGVzaGVldHMgYXJlIGtlcHQuCi0gICAqCi0gICAqIEBwYXJhbSB2IHRoZSByb290IG9mIHRoZSBzdHlsZXNoZWV0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0Um9vdChTdHlsZXNoZWV0Um9vdCB2KQotICB7Ci0gICAgbV9zdHlsZXNoZWV0Um9vdCA9IHY7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHBhcmVudCBvZiB0aGUgc3R5bGVzaGVldC4gIFRoaXMgd2lsbCBiZSBudWxsIGlmIHRoaXMKLSAgICogaXMgdGhlIHJvb3Qgc3R5bGVzaGVldC4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBTdHlsZXNoZWV0IG1fc3R5bGVzaGVldFBhcmVudDsKLQotICAvKioKLSAgICogR2V0IHRoZSBwYXJlbnQgb2YgdGhlIHN0eWxlc2hlZXQuICBUaGlzIHdpbGwgYmUgbnVsbCBpZiB0aGlzCi0gICAqIGlzIHRoZSByb290IHN0eWxlc2hlZXQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBhcmVudCBvZiB0aGUgc3R5bGVzaGVldC4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0IGdldFN0eWxlc2hlZXRQYXJlbnQoKQotICB7Ci0gICAgcmV0dXJuIG1fc3R5bGVzaGVldFBhcmVudDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHBhcmVudCBvZiB0aGUgc3R5bGVzaGVldC4gIFRoaXMgc2hvdWxkIGJlIG51bGwgaWYgdGhpcwotICAgKiBpcyB0aGUgcm9vdCBzdHlsZXNoZWV0LgotICAgKgotICAgKiBAcGFyYW0gdiB0aGUgcGFyZW50IG9mIHRoZSBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3R5bGVzaGVldFBhcmVudChTdHlsZXNoZWV0IHYpCi0gIHsKLSAgICBtX3N0eWxlc2hlZXRQYXJlbnQgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3duaW5nIGFnZ3JlZ2F0ZWQgc3R5bGVzaGVldCwgb3IgdGhpcwotICAgKiBzdHlsZXNoZWV0IGlmIGl0IGlzIGFnZ3JlZ2F0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG93bmluZyBhZ2dyZWdhdGVkIHN0eWxlc2hlZXQgb3IgaXRzZWxmCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldENvbXBvc2VkIGdldFN0eWxlc2hlZXRDb21wb3NlZCgpCi0gIHsKLQotICAgIFN0eWxlc2hlZXQgc2hlZXQgPSB0aGlzOwotCi0gICAgd2hpbGUgKCFzaGVldC5pc0FnZ3JlZ2F0ZWRUeXBlKCkpCi0gICAgewotICAgICAgc2hlZXQgPSBzaGVldC5nZXRTdHlsZXNoZWV0UGFyZW50KCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIChTdHlsZXNoZWV0Q29tcG9zZWQpIHNoZWV0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdHlwZSBvZiB0aGUgbm9kZS4gIFdlJ2xsIHByZXRlbmQgd2UncmUgYSBEb2N1bWVudC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdHlwZSBvZiB0aGUgbm9kZTogZG9jdW1lbnQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpCi0gIHsKLSAgICByZXR1cm4gRFRNLkRPQ1VNRU5UX05PREU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnQgdHlwZS4KLSAgICoKLSAgICogQHJldHVybiBBbiBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50LCBkZWZpbmVkIGluIHRoZQotICAgKiAgICAgQ29uc3RhbnRzIGNsYXNzLgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cwotICAgKi8KLSAgcHVibGljIGludCBnZXRYU0xUb2tlbigpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX1NUWUxFU0hFRVQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZSgpCi0gIHsKLSAgICByZXR1cm4gQ29uc3RhbnRzLkVMRU1OQU1FX1NUWUxFU0hFRVRfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcGxhY2UgYW4gInhzbDp0ZW1wbGF0ZSIgcHJvcGVydHkuCi0gICAqIFRoaXMgaXMgYSBob29rIGZvciBDb21waWxpbmdTdHlsZXNoZWV0SGFuZGxlciwgdG8gYWxsb3cKLSAgICogdXMgdG8gYWNjZXNzIGEgdGVtcGxhdGUsIGNvbXBpbGUgaXQsIGluc3RhbnRpYXRlIGl0LAotICAgKiBhbmQgcmVwbGFjZSB0aGUgb3JpZ2luYWwgd2l0aCB0aGUgY29tcGlsZWQgaW5zdGFuY2UuCi0gICAqIEFEREVEIDkvNS8yMDAwIHRvIHN1cHBvcnQgY29tcGlsYXRpb24gZXhwZXJpbWVudAotICAgKgotICAgKiBAcGFyYW0gdiBDb21waWxlZCB0ZW1wbGF0ZSB0byByZXBsYWNlIHdpdGgKLSAgICogQHBhcmFtIGkgSW5kZXggb2YgdGVtcGxhdGUgdG8gYmUgcmVwbGFjZWQKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVwbGFjZVRlbXBsYXRlKEVsZW1UZW1wbGF0ZSB2LCBpbnQgaSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fdGVtcGxhdGVzKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwotCi0gICAgcmVwbGFjZUNoaWxkKHYsIChFbGVtVGVtcGxhdGVFbGVtZW50KW1fdGVtcGxhdGVzLmVsZW1lbnRBdChpKSk7Ci0gICAgbV90ZW1wbGF0ZXMuc2V0RWxlbWVudEF0KHYsIGkpOwotICAgIHYuc2V0U3R5bGVzaGVldCh0aGlzKTsKLSAgfQotICAKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9TdHlsZXNoZWV0Q29tcG9zZWQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9TdHlsZXNoZWV0Q29tcG9zZWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTVmYjljOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvU3R5bGVzaGVldENvbXBvc2VkLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNjMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdDsKLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7Ci0KLS8qKgotICogUmVwcmVzZW50cyBhIHN0eWxlc2hlZXQgdGhhdCBoYXMgbWV0aG9kcyB0aGF0IHJlc29sdmUgaW5jbHVkZXMgYW5kCi0gKiBpbXBvcnRzLiAgSXQgaGFzIG1ldGhvZHMgb24gaXQgdGhhdAotICogcmV0dXJuICJjb21wb3NlZCIgcHJvcGVydGllcywgd2hpY2ggbWVhbiB0aGF0OgotICogPG9sPgotICogPGxpPlByb3BlcnRpZXMgdGhhdCBhcmUgYWdncmVnYXRlcywgbGlrZSBPdXRwdXRQcm9wZXJ0aWVzLCB3aWxsCi0gKiBiZSBjb21wb3NlZCBvZiBwcm9wZXJ0aWVzIGRlY2xhcmVkIGluIHRoaXMgc3R5bHNoZWV0IGFuZCBhbGwKLSAqIGluY2x1ZGVkIHN0eWxlc2hlZXRzLjwvbGk+Ci0gKiA8bGk+UHJvcGVydGllcyB0aGF0IGFyZW4ndCBmb3VuZCwgd2lsbCBiZSBzZWFyY2hlZCBmb3IgZmlyc3QgaW4KLSAqIHRoZSBpbmNsdWRlcywgYW5kLCBpZiBub25lIGFyZSBsb2NhdGVkLCB3aWxsIGJlIHNlYXJjaGVkIGZvciBpbgotICogdGhlIGltcG9ydHMuPC9saT4KLSAqIDxsaT5Qcm9wZXJ0aWVzIGluIHRoYXQgYXJlIG5vdCBhdG9taWMgb24gYSBzdHlsZXNoZWV0IHdpbGwKLSAqIGhhdmUgdGhlIGZvcm0gZ2V0WFhYQ29tcG9zZWQuIFNvbWUgcHJvcGVydGllcywgbGlrZSB2ZXJzaW9uIGFuZCBpZCwKLSAqIGFyZSBub3QgaW5oZXJpdGVkLCBhbmQgc28gd29uJ3QgaGF2ZSBnZXRYWFhDb21wb3NlZCBtZXRob2RzLjwvbGk+Ci0gKiA8L29sPgotICogPHA+SW4gc29tZSBjYXNlcyBnZXRYWFhDb21wb3NlZCBtZXRob2RzIG1heSBjYWxjdWxhdGUgdGhlIGNvbXBvc2VkCi0gKiB2YWx1ZXMgZHluYW1pY2FsbHksIHdoaWxlIGluIG90aGVyIGNhc2VzIHRoZXkgbWF5IHN0b3JlIHRoZSBjb21wb3NlZAotICogdmFsdWVzLjwvcD4KLSAqLwotcHVibGljIGNsYXNzIFN0eWxlc2hlZXRDb21wb3NlZCBleHRlbmRzIFN0eWxlc2hlZXQKLXsKLQotICAvKioKLSAgICogVXNlcyBhbiBYU0wgc3R5bGVzaGVldCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHBhcmVudCAgVGhlIGluY2x1ZGluZyBvciBpbXBvcnRpbmcgc3R5bGVzaGVldC4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Q29tcG9zZWQoU3R5bGVzaGVldCBwYXJlbnQpCi0gIHsKLSAgICBzdXBlcihwYXJlbnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBjYW4gYmUgY2FzdCB0byBhIFN0eWxlc2hlZXRDb21wb3NlZCwgbWVhbmluZywgeW91Ci0gICAqIGNhbiBhc2sgcXVlc3Rpb25zIGZyb20gZ2V0WFhYQ29tcG9zZWQgZnVuY3Rpb25zLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgc2luY2UgdGhpcyBpcyBhIFN0eWxlc2hlZXRDb21wb3NlZCAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQWdncmVnYXRlZFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogQWRkcyBhbGwgcmVjb21wb3NhYmxlIHZhbHVlcyBmb3IgdGhpcyBwcmVjZWRlbmNlIGxldmVsIGludG8gdGhlIHJlY29tcG9zYWJsZUVsZW1lbnRzIFZlY3RvcgotICAgKiB0aGF0IHdhcyBwYXNzZWQgaW4gYXMgdGhlIGZpcnN0IHBhcmFtZXRlci4gIEFsbCBlbGVtZW50cyBhZGRlZCB0byB0aGUKLSAgICogcmVjb21wb3NhYmxlRWxlbWVudHMgdmVjdG9yIHNob3VsZCBleHRlbmQgRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICogQHBhcmFtIHJlY29tcG9zYWJsZUVsZW1lbnRzIGEgVmVjdG9yIG9mIEVsZW1UZW1wbGF0ZUVsZW1lbnQgb2JqZWN0cyB0aGF0IHdlIHdpbGwgYWRkIGFsbCBvZgotICAgKiAgICAgICAgb3VyIHJlY29tcG9zYWJsZSBvYmplY3RzIHRvLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVjb21wb3NlKFZlY3RvciByZWNvbXBvc2FibGVFbGVtZW50cykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJlY29tcG9zZUltcG9ydHMoKTsgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiB0aGlzIGltcG9ydC4KLSAgICByZWNvbXBvc2VJbmNsdWRlcyh0aGlzKTsgICAgLy8gQnVpbGQgdGhlIGdsb2JhbCBpbmNsdWRlIGxpc3QgZm9yIHRoaXMgc3R5bGVzaGVldC4KLQotICAgIC8vIE5vdyBhZGQgaW4gYWxsIG9mIHRoZSByZWNvbXBvc2FibGUgZWxlbWVudHMgYXQgdGhpcyBwcmVjZWRlbmNlIGxldmVsCi0KLSAgICBpbnQgbiA9IGdldEluY2x1ZGVDb3VudENvbXBvc2VkKCk7Ci0KLSAgICBmb3IgKGludCBpID0gLTE7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgU3R5bGVzaGVldCBpbmNsdWRlZCA9IGdldEluY2x1ZGVDb21wb3NlZChpKTsKLQotICAgICAgLy8gQWRkIGluIHRoZSBvdXRwdXQgZWxlbWVudHMKLQotICAgICAgaW50IHMgPSBpbmNsdWRlZC5nZXRPdXRwdXRDb3VudCgpOwotICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzOyBqKyspCi0gICAgICB7Ci0gICAgICAgIHJlY29tcG9zYWJsZUVsZW1lbnRzLmFkZEVsZW1lbnQoaW5jbHVkZWQuZ2V0T3V0cHV0KGopKTsKLSAgICAgIH0KLQotICAgICAgLy8gTmV4dCwgYWRkIGluIHRoZSBhdHRyaWJ1dGUtc2V0IGVsZW1lbnRzCi0KLSAgICAgIHMgPSBpbmNsdWRlZC5nZXRBdHRyaWJ1dGVTZXRDb3VudCgpOwotICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzOyBqKyspCi0gICAgICB7Ci0gICAgICAgIHJlY29tcG9zYWJsZUVsZW1lbnRzLmFkZEVsZW1lbnQoaW5jbHVkZWQuZ2V0QXR0cmlidXRlU2V0KGopKTsKLSAgICAgIH0KLQotICAgICAgLy8gTm93IHRoZSBkZWNpbWFsLWZvcm1hdHMKLQotICAgICAgcyA9IGluY2x1ZGVkLmdldERlY2ltYWxGb3JtYXRDb3VudCgpOwotICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzOyBqKyspCi0gICAgICB7Ci0gICAgICAgIHJlY29tcG9zYWJsZUVsZW1lbnRzLmFkZEVsZW1lbnQoaW5jbHVkZWQuZ2V0RGVjaW1hbEZvcm1hdChqKSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIE5vdyB0aGUga2V5cwotCi0gICAgICBzID0gaW5jbHVkZWQuZ2V0S2V5Q291bnQoKTsKLSAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgczsgaisrKQotICAgICAgewotICAgICAgICByZWNvbXBvc2FibGVFbGVtZW50cy5hZGRFbGVtZW50KGluY2x1ZGVkLmdldEtleShqKSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEFuZCB0aGUgbmFtZXNwYWNlIGFsaWFzZXMKLQotICAgICAgcyA9IGluY2x1ZGVkLmdldE5hbWVzcGFjZUFsaWFzQ291bnQoKTsKLSAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgczsgaisrKQotICAgICAgewotICAgICAgICByZWNvbXBvc2FibGVFbGVtZW50cy5hZGRFbGVtZW50KGluY2x1ZGVkLmdldE5hbWVzcGFjZUFsaWFzKGopKTsKLSAgICAgIH0KLQotICAgICAgLy8gTmV4dCBjb21lcyB0aGUgdGVtcGxhdGVzCi0KLSAgICAgIHMgPSBpbmNsdWRlZC5nZXRUZW1wbGF0ZUNvdW50KCk7Ci0gICAgICBmb3IgKGludCBqID0gMDsgaiA8IHM7IGorKykKLSAgICAgIHsKLSAgICAgICAgcmVjb21wb3NhYmxlRWxlbWVudHMuYWRkRWxlbWVudChpbmNsdWRlZC5nZXRUZW1wbGF0ZShqKSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIFRoZW4sIHRoZSB2YXJpYWJsZXMKLQotICAgICAgcyA9IGluY2x1ZGVkLmdldFZhcmlhYmxlT3JQYXJhbUNvdW50KCk7Ci0gICAgICBmb3IgKGludCBqID0gMDsgaiA8IHM7IGorKykKLSAgICAgIHsKLSAgICAgICAgcmVjb21wb3NhYmxlRWxlbWVudHMuYWRkRWxlbWVudChpbmNsdWRlZC5nZXRWYXJpYWJsZU9yUGFyYW0oaikpOwotICAgICAgfQotCi0gICAgICAvLyBBbmQgbGFzdGx5IHRoZSB3aGl0ZXNwYWNlIHByZXNlcnZpbmcgYW5kIHN0cmlwcGluZyBlbGVtZW50cwotCi0gICAgICBzID0gaW5jbHVkZWQuZ2V0U3RyaXBTcGFjZUNvdW50KCk7Ci0gICAgICBmb3IgKGludCBqID0gMDsgaiA8IHM7IGorKykKLSAgICAgIHsKLSAgICAgICAgcmVjb21wb3NhYmxlRWxlbWVudHMuYWRkRWxlbWVudChpbmNsdWRlZC5nZXRTdHJpcFNwYWNlKGopKTsKLSAgICAgIH0KLQotICAgICAgcyA9IGluY2x1ZGVkLmdldFByZXNlcnZlU3BhY2VDb3VudCgpOwotICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzOyBqKyspCi0gICAgICB7Ci0gICAgICAgIHJlY29tcG9zYWJsZUVsZW1lbnRzLmFkZEVsZW1lbnQoaW5jbHVkZWQuZ2V0UHJlc2VydmVTcGFjZShqKSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqIE9yZGVyIGluIGltcG9ydCBjaGFpbi4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2ltcG9ydE51bWJlciA9IC0xOwotCi0gIC8qKiBUaGUgcHJlY2VkZW5jZSBvZiB0aGlzIHN0eWxlc2hlZXQgaW4gdGhlIGdsb2JhbCBpbXBvcnQgbGlzdC4KLSAgICogIFRoZSBsb3dlc3QgcHJlY2VkZW5jZSBzdHlsZXNoZWV0IGlzIDAuICBBIGhpZ2hlcgotICAgKiAgbnVtYmVyIGhhcyBhIGhpZ2hlciBwcmVjZWRlbmNlLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9pbXBvcnRDb3VudENvbXBvc2VkOwotCi0gIC8qKgotICAgKiBSZWNhbGN1bGF0ZSB0aGUgcHJlY2VkZW5jZSBvZiB0aGlzIHN0eWxlc2hlZXQgaW4gdGhlIGdsb2JhbAotICAgKiBpbXBvcnQgbGlzdC4gIFRoZSBsb3dlc3QgcHJlY2VkZW5jZSBzdHlsZXNoZWV0IGlzIDAuICBBIGhpZ2hlcgotICAgKiBudW1iZXIgaGFzIGEgaGlnaGVyIHByZWNlZGVuY2UuCi0gICAqLwotICB2b2lkIHJlY29tcG9zZUltcG9ydHMoKQotICB7Ci0KLSAgICBtX2ltcG9ydE51bWJlciA9IGdldFN0eWxlc2hlZXRSb290KCkuZ2V0SW1wb3J0TnVtYmVyKHRoaXMpOwotCi0gICAgU3R5bGVzaGVldFJvb3Qgcm9vdCA9IGdldFN0eWxlc2hlZXRSb290KCk7Ci0gICAgaW50IGdsb2JhbEltcG9ydENvdW50ID0gcm9vdC5nZXRHbG9iYWxJbXBvcnRDb3VudCgpOwotCi0gICAgbV9pbXBvcnRDb3VudENvbXBvc2VkID0gKGdsb2JhbEltcG9ydENvdW50IC0gbV9pbXBvcnROdW1iZXIpIC0gMTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBzdHlsZXNoZWV0IGZyb20gdGhlICJpbXBvcnQiIGxpc3QuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNpbXBvcnQiPmltcG9ydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHN0eWxlc2hlZXQgaW4gaW1wb3J0IGxpc3QgCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0eWxlc2hlZXQgYXQgdGhlIGdpdmVuIGluZGV4Ci0gICAqCi0gICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3R5bGVzaGVldENvbXBvc2VkIGdldEltcG9ydENvbXBvc2VkKGludCBpKQotICAgICAgICAgIHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgewotCi0gICAgU3R5bGVzaGVldFJvb3Qgcm9vdCA9IGdldFN0eWxlc2hlZXRSb290KCk7Ci0KLSAgICAvLyBHZXQgdGhlIHN0eWxlc2hlZXQgdGhhdCBpcyBvZmZzZXQgcGFzdCB0aGlzIHN0eWxlc2hlZXQuCi0gICAgLy8gVGh1cywgaWYgdGhlIGluZGV4IG9mIHRoaXMgc3R5bGVzaGVldCBpcyAzLCBhbiBhcmd1bWVudCAKLSAgICAvLyB0byBnZXRJbXBvcnRDb21wb3NlZCBvZiAwIHdpbGwgcmV0dXJuIHRoZSA0dGggc3R5bGVzaGVldCAKLSAgICAvLyBpbiB0aGUgZ2xvYmFsIGltcG9ydCBsaXN0LgotICAgIHJldHVybiByb290LmdldEdsb2JhbEltcG9ydCgxICsgbV9pbXBvcnROdW1iZXIgKyBpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByZWNlZGVuY2Ugb2YgdGhpcyBzdHlsZXNoZWV0IGluIHRoZSBnbG9iYWwgaW1wb3J0IGxpc3QuCi0gICAqIFRoZSBsb3dlc3QgcHJlY2VkZW5jZSBpcyAwLiAgQSBoaWdoZXIgbnVtYmVyIGhhcyBhIGhpZ2hlciBwcmVjZWRlbmNlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjaW1wb3J0Ij5pbXBvcnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwcmVjZWRlbmNlIG9mIHRoaXMgc3R5bGVzaGVldCBpbiB0aGUgZ2xvYmFsIGltcG9ydCBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbXBvcnRDb3VudENvbXBvc2VkKCkKLSAgewotICAgIHJldHVybiBtX2ltcG9ydENvdW50Q29tcG9zZWQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGNvbWJpbmVkIGxpc3Qgb2YgaW5jbHVkZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgdHJhbnNpZW50IFZlY3RvciBtX2luY2x1ZGVzQ29tcG9zZWQ7Ci0KLSAgLyoqCi0gICAqIFJlY29tcG9zZSB0aGUgdmFsdWUgb2YgdGhlIGNvbXBvc2VkIGluY2x1ZGUgbGlzdC4gIEJ1aWxkcyBhIGNvbXBvc2l0ZQotICAgKiBsaXN0IG9mIGFsbCBzdHlsZXNoZWV0cyBpbmNsdWRlZCBieSB0aGlzIHN0eWxlc2hlZXQgdG8gYW55IGRlcHRoLgotICAgKgotICAgKiBAcGFyYW0gaW5jbHVkaW5nIFN0eWxlc2hlZXQgdG8gcmVjb21wb3NlCi0gICAqLwotICB2b2lkIHJlY29tcG9zZUluY2x1ZGVzKFN0eWxlc2hlZXQgaW5jbHVkaW5nKQotICB7Ci0KLSAgICBpbnQgbiA9IGluY2x1ZGluZy5nZXRJbmNsdWRlQ291bnQoKTsKLQotICAgIGlmIChuID4gMCkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX2luY2x1ZGVzQ29tcG9zZWQpCi0gICAgICAgIG1faW5jbHVkZXNDb21wb3NlZCA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFN0eWxlc2hlZXQgaW5jbHVkZWQgPSBpbmNsdWRpbmcuZ2V0SW5jbHVkZShpKTsKLSAgICAgICAgbV9pbmNsdWRlc0NvbXBvc2VkLmFkZEVsZW1lbnQoaW5jbHVkZWQpOwotICAgICAgICByZWNvbXBvc2VJbmNsdWRlcyhpbmNsdWRlZCk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOmluY2x1ZGUiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjaW5jbHVkZSI+aW5jbHVkZSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHN0eWxlc2hlZXQgaW4gImluY2x1ZGUiIGxpc3QgCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0eWxlc2hlZXQgYXQgdGhlIGdpdmVuIGluZGV4IGluIHRoZSAiaW5jbHVkZSIgbGlzdCAKLSAgICoKLSAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0IGdldEluY2x1ZGVDb21wb3NlZChpbnQgaSkKLSAgICAgICAgICB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICgtMSA9PSBpKQotICAgICAgcmV0dXJuIHRoaXM7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2luY2x1ZGVzQ29tcG9zZWQpCi0gICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7Ci0KLSAgICByZXR1cm4gKFN0eWxlc2hlZXQpIG1faW5jbHVkZXNDb21wb3NlZC5lbGVtZW50QXQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2YgaW5jbHVkZWQgc3R5bGVzaGVldHMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNpbXBvcnQiPmltcG9ydCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBpbmNsdWRlZCBzdHlsZXNoZWV0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0SW5jbHVkZUNvdW50Q29tcG9zZWQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1faW5jbHVkZXNDb21wb3NlZCkgPyBtX2luY2x1ZGVzQ29tcG9zZWQuc2l6ZSgpIDogMDsKLSAgfQotCi0gIC8qKgotICAgKiBGb3IgY29tcGlsYXRpb24gc3VwcG9ydCwgd2UgbmVlZCB0aGUgb3B0aW9uIG9mIG92ZXJ3cml0aW5nCi0gICAqIChyYXRoZXIgdGhhbiBhcHBlbmRpbmcgdG8pIHByZXZpb3VzIGNvbXBvc2l0aW9uLgotICAgKiBXZSBjb3VsZCBwaGFzZSBvdXQgdGhlIG9sZCBBUEkgaW4gZmF2b3Igb2YgdGhpcyBvbmUsIGJ1dCBJJ20KLSAgICogaG9sZGluZyBvZmYgdW50aWwgd2UndmUgbWFkZSB1cCBvdXIgbWluZHMgYWJvdXQgY29tcGlsYXRpb24uCi0gICAqIEFEREVEIDkvNS8yMDAwIHRvIHN1cHBvcnQgY29tcGlsYXRpb24gZXhwZXJpbWVudC4KLSAgICogTk9URTogR0xQIDI5LU5vdi0wMCBJJ3ZlIGxlZnQgdGhpcyBtZXRob2QgaW4gc28gdGhhdCBDb21waWxpbmdTdHlsZXNoZWV0SGFuZGxlciB3aWxsIGNvbXBpbGUuICBIb3dldmVyLAotICAgKiAgICAgICAgICAgICAgICAgICAgIEknbSBub3Qgc3VyZSB3aHkgaXQncyBuZWVkZWQgb3Igd2hhdCBpdCBkb2VzIGFuZCBJJ3ZlIGNvbW1lbnRlZCBvdXQgdGhlIGJvZHkuCi0gICAqCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIj5zZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICogQHBhcmFtIGZsdXNoRmlyc3QgRmxhZyBpbmRpY2F0aW5nIHRoZSBvcHRpb24gb2Ygb3ZlcndyaXRpbmcKLSAgICogKHJhdGhlciB0aGFuIGFwcGVuZGluZyB0bykgcHJldmlvdXMgY29tcG9zaXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlY29tcG9zZVRlbXBsYXRlcyhib29sZWFuIGZsdXNoRmlyc3QpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICBLRUVQIE1FVEhPRCBJTiBGT1IgQ09NUElMQVRJT04KLSAgICBpZiAoZmx1c2hGaXJzdCkKLSAgICAgIG1fdGVtcGxhdGVMaXN0ID0gbmV3IFRlbXBsYXRlTGlzdCh0aGlzKTsKLQotICAgIHJlY29tcG9zZVRlbXBsYXRlcygpOwotKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9TdHlsZXNoZWV0Um9vdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1N0eWxlc2hlZXRSb290LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxNWI4YzEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1N0eWxlc2hlZXRSb290LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjYyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi0vLyBpbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdDsKLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5YUGF0aFBhcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlhTTFRTY2hlbWE7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRXhwYW5kZWROYW1lVGFibGU7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyB0aGUgcm9vdCBvYmplY3Qgb2YgdGhlIHN0eWxlc2hlZXQgdHJlZS4KLSAqLwotcHVibGljIGNsYXNzIFN0eWxlc2hlZXRSb290IGV4dGVuZHMgU3R5bGVzaGVldENvbXBvc2VkCi0gICAgICAgIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUsIFRlbXBsYXRlcwotewotCi0gIC8qKgotICAgKiBVc2VzIGFuIFhTTCBzdHlsZXNoZWV0IGRvY3VtZW50LgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgYmFzZUlkZW50aWZpZXIgY2FuIG5vdCBiZSByZXNvbHZlZCB0byBhIFVSTC4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdChFcnJvckxpc3RlbmVyIGVycm9yTGlzdGVuZXIpIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIobnVsbCk7Ci0KLSAgICBzZXRTdHlsZXNoZWV0Um9vdCh0aGlzKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIG1fc2VsZWN0RGVmYXVsdCA9IG5ldyBYUGF0aCgibm9kZSgpIiwgdGhpcywgdGhpcywgWFBhdGguU0VMRUNULCBlcnJvckxpc3RlbmVyKTsKLQotICAgICAgaW5pdERlZmF1bHRSdWxlKGVycm9yTGlzdGVuZXIpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfSU5JVF9ERUZBVUxUX1RFTVBMQVRFUywgbnVsbCksIHNlKTsgLy8iQ2FuJ3QgaW5pdCBkZWZhdWx0IHRlbXBsYXRlcyEiLCBzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBzY2hlbWEgdXNlZCB3aGVuIGNyZWF0aW5nIHRoaXMgU3R5bGVzaGVldFJvb3QKLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBIYXNodGFibGUgbV9hdmFpbEVsZW1zOwotCi0gIC8qKgotICAgKiBDcmVhdGVzIGEgU3R5bGVzaGVldFJvb3QgYW5kIHJldGFpbnMgYSBwb2ludGVyIHRvIHRoZSBzY2hlbWEgdXNlZCB0byBjcmVhdGUgdGhpcwotICAgKiBTdHlsZXNoZWV0Um9vdC4gIFRoZSBzY2hlbWEgbWF5IGJlIG5lZWRlZCBsYXRlciBmb3IgYW4gZWxlbWVudC1hdmFpbGFibGUoKSBmdW5jdGlvbiBjYWxsLgotICAgKiAKLSAgICogQHBhcmFtIHNjaGVtYSBUaGUgc2NoZW1hIHVzZWQgdG8gY3JlYXRlIHRoaXMgc3R5bGVzaGVldAotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgYmFzZUlkZW50aWZpZXIgY2FuIG5vdCBiZSByZXNvbHZlZCB0byBhIFVSTC4KLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Um9vdChYU0xUU2NoZW1hIHNjaGVtYSwgRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikgdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0KLSAgICB0aGlzKGxpc3RlbmVyKTsKLSAgICBtX2F2YWlsRWxlbXMgPSBzY2hlbWEuZ2V0RWxlbXNBdmFpbGFibGUoKTsKLQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBpcyB0aGUgcm9vdCBvZiB0aGUgc3R5bGVzaGVldCB0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgc2luY2UgdGhpcyBpcyB0aGUgcm9vdCBvZiB0aGUgc3R5bGVzaGVldCB0cmVlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNSb290KCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgaGFzaHRhYmxlIG9mIGF2YWlsYWJsZSBlbGVtZW50cy4KLSAgICoKLSAgICogQHJldHVybiB0YWJsZSBvZiBhdmFpbGFibGUgZWxlbWVudHMsIGtleWVkIGJ5IHF1YWxpZmllZCBuYW1lcywgYW5kIHdpdGggCi0gICAqIHZhbHVlcyBvZiB0aGUgc2FtZSBxdWFsaWZpZWQgbmFtZXMuCi0gICAqLwotICBwdWJsaWMgSGFzaHRhYmxlIGdldEF2YWlsYWJsZUVsZW1lbnRzKCkKLSAgewotICAgIHJldHVybiBtX2F2YWlsRWxlbXM7Ci0gIH0KLQotICAvLz09PT09PT09PT09PT09IFRlbXBsYXRlcyBJbnRlcmZhY2UgPT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgdHJhbnNmb3JtYXRpb24gY29udGV4dCBmb3IgdGhpcyBUZW1wbGF0ZXMgb2JqZWN0LgotICAgKgotICAgKiBAcmV0dXJuIEEgVHJhbnNmb3JtZXIgaW5zdGFuY2UsIG5ldmVyIG51bGwuCi0gICAqLwotICBwdWJsaWMgVHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoKQotICB7Ci0gICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm1lckltcGwodGhpcyk7Ci0gIH0KLSAgCi0KLSAgcHVibGljIFByb3BlcnRpZXMgZ2V0RGVmYXVsdE91dHB1dFByb3BzKCkKLSAgewotICAgIHJldHVybiBtX291dHB1dFByb3BlcnRpZXMuZ2V0UHJvcGVydGllcygpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBzdGF0aWMgcHJvcGVydGllcyBmb3IgeHNsOm91dHB1dC4gIFRoZSBvYmplY3QgcmV0dXJuZWQgd2lsbAotICAgKiBiZSBhIGNsb25lIG9mIHRoZSBpbnRlcm5hbCB2YWx1ZXMsIGFuZCB0aHVzIGl0IGNhbiBiZSBtdXRhdGVkCi0gICAqIHdpdGhvdXQgbXV0YXRpbmcgdGhlIFRlbXBsYXRlcyBvYmplY3QsIGFuZCB0aGVuIGhhbmRlZCBpbiB0bwotICAgKiB0aGUgcHJvY2VzcyBtZXRob2QuCi0gICAqCi0gICAqIDxwPkZvciBYU0xULCBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGVzIGF0dHJpYnV0ZSB2YWx1ZXMgd2lsbAotICAgKiBiZSByZXR1cm5lZCB1bmV4cGFuZGVkIChzaW5jZSB0aGVyZSBpcyBubyBjb250ZXh0IGF0IHRoaXMgcG9pbnQpLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBBIFByb3BlcnRpZXMgb2JqZWN0LCBub3QgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKQotICB7ICAgIAotICAgIHJldHVybiAoUHJvcGVydGllcylnZXREZWZhdWx0T3V0cHV0UHJvcHMoKS5jbG9uZSgpOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PSBFbmQgVGVtcGxhdGVzIEludGVyZmFjZSA9PT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFJlY29tcG9zZSB0aGUgdmFsdWVzIG9mIGFsbCAiY29tcG9zZWQiIHByb3BlcnRpZXMsIG1lYW5pbmcKLSAgICogcHJvcGVydGllcyB0aGF0IG5lZWQgdG8gYmUgY29tYmluZWQgb3IgY2FsY3VsYXRlZCBmcm9tCi0gICAqIHRoZSBjb21iaW5hdGlvbiBvZiBpbXBvcnRlZCBhbmQgaW5jbHVkZWQgc3R5bGVzaGVldHMuICBUaGlzCi0gICAqIG1ldGhvZCBkZXRlcm1pbmVzIHRoZSBwcm9wZXIgaW1wb3J0IHByZWNlZGVuY2Ugb2YgYWxsIGltcG9ydGVkCi0gICAqIHN0eWxlc2hlZXRzLiAgSXQgdGhlbiBpdGVyYXRlcyB0aHJvdWdoIGFsbCBvZiB0aGUgZWxlbWVudHMgYW5kIAotICAgKiBwcm9wZXJ0aWVzIGluIHRoZSBwcm9wZXIgb3JkZXIgYW5kIHRyaWdnZXJzIHRoZSBpbmRpdmlkdWFsIHJlY29tcG9zZQotICAgKiBtZXRob2RzLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZWNvbXBvc2UoKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gRmlyc3QsIHdlIGJ1aWxkIHRoZSBnbG9iYWwgaW1wb3J0IHRyZWUuCi0KLSAgICBpZiAobnVsbCA9PSBtX2dsb2JhbEltcG9ydExpc3QpCi0gICAgewotCi0gICAgICBWZWN0b3IgaW1wb3J0TGlzdCA9IG5ldyBWZWN0b3IoKTsKLQotICAgICAgYWRkSW1wb3J0cyh0aGlzLCB0cnVlLCBpbXBvcnRMaXN0KTsKLQotICAgICAgLy8gTm93IHdlIGNyZWF0ZSBhbiBhcnJheSBhbmQgcmV2ZXJzZSB0aGUgb3JkZXIgb2YgdGhlIGltcG9ydExpc3QgdmVjdG9yLgotICAgICAgLy8gV2UgYnVpbHQgdGhlIGltcG9ydExpc3QgdmVjdG9yIGJhY2t3YXJkcyBzbyB0aGF0IHdlIGNvdWxkIHVzZSBhZGRFbGVtZW50Ci0gICAgICAvLyB0byBhcHBlbmQgdG8gdGhlIGVuZCBvZiB0aGUgdmVjdG9yIGluc3RlYWQgb2YgY29uc3RhbnRseSBwdXNoaW5nIG5ldwotICAgICAgLy8gc3R5bGVzaGVldHMgb250byB0aGUgZnJvbnQgb2YgdGhlIHZlY3RvciBhbmQgaGF2aW5nIHRvIHNoaWZ0IHRoZSByZXN0Ci0gICAgICAvLyBvZiB0aGUgdmVjdG9yIGVhY2ggdGltZS4KLQotICAgICAgbV9nbG9iYWxJbXBvcnRMaXN0ID0gbmV3IFN0eWxlc2hlZXRDb21wb3NlZFtpbXBvcnRMaXN0LnNpemUoKV07Ci0KLSAgICAgIGZvciAoaW50IGkgPSBpbXBvcnRMaXN0LnNpemUoKSAtIDEsIGo9IDA7IGkgPj0gMDsgaS0tKQotICAgICAgICBtX2dsb2JhbEltcG9ydExpc3RbaisrXSA9IChTdHlsZXNoZWV0Q29tcG9zZWQpIGltcG9ydExpc3QuZWxlbWVudEF0KGkpOwotICAgIH0KLQotICAgIC8vIE5vdyB3ZSBtYWtlIGEgVmVjdG9yIHRoYXQgaXMgZ29pbmcgdG8gaG9sZCBhbGwgb2YgdGhlIHJlY29tcG9zYWJsZSBlbGVtZW50cwotCi0gICAgVmVjdG9yIHJlY29tcG9zYWJsZUVsZW1lbnRzID0gbmV3IFZlY3RvcigpOwotCi0gICAgLy8gTmV4dCwgd2Ugd2FsayB0aGUgaW1wb3J0IHRyZWUgYW5kIGFkZCBhbGwgb2YgdGhlIHJlY29tcG9zYWJsZSBlbGVtZW50cyB0byB0aGUgdmVjdG9yLgotCi0gICAgaW50IG4gPSBnZXRHbG9iYWxJbXBvcnRDb3VudCgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgU3R5bGVzaGVldENvbXBvc2VkIGltcG9ydGVkID0gZ2V0R2xvYmFsSW1wb3J0KGkpOwotICAgICAgaW1wb3J0ZWQucmVjb21wb3NlKHJlY29tcG9zYWJsZUVsZW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvLyBXZSBzb3J0IHRoZSBlbGVtZW50cyBpbnRvIGFzY2VuZGluZyBvcmRlci4KLQotICAgIFF1aWNrU29ydDIocmVjb21wb3NhYmxlRWxlbWVudHMsIDAsIHJlY29tcG9zYWJsZUVsZW1lbnRzLnNpemUoKSAtIDEpOwotCi0gICAgLy8gV2Ugc2V0IHVwIHRoZSBnbG9iYWwgdmFyaWFibGVzIHRoYXQgd2lsbCBob2xkIHRoZSByZWNvbXBvc2VkIGluZm9ybWF0aW9uLgotCi0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzID0gbmV3IE91dHB1dFByb3BlcnRpZXMoTWV0aG9kLlhNTCk7Ci0gICAgCi0gICAgbV9hdHRyU2V0cyA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBtX2RlY2ltYWxGb3JtYXRTeW1ib2xzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIG1fa2V5RGVjbHMgPSBuZXcgVmVjdG9yKCk7Ci0gICAgbV9uYW1lc3BhY2VBbGlhc0NvbXBvc2VkID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIG1fdGVtcGxhdGVMaXN0ID0gbmV3IFRlbXBsYXRlTGlzdCgpOwotICAgIG1fdmFyaWFibGVzID0gbmV3IFZlY3RvcigpOwotCi0gICAgLy8gTm93IHdlIHNlcXVlbmNlIHRocm91Z2ggdGhlIHNvcnRlZCBlbGVtZW50cywgCi0gICAgLy8gY2FsbGluZyB0aGUgcmVjb21wb3NlKCkgZnVuY3Rpb24gb24gZWFjaCBvbmUuICBUaGlzIHdpbGwgY2FsbCBiYWNrIGludG8gdGhlCi0gICAgLy8gYXBwcm9wcmlhdGUgcm91dGluZSBoZXJlIHRvIGFjdHVhbGx5IGRvIHRoZSByZWNvbXBvc2l0aW9uLgotICAgIC8vIE5vdGUgdGhhdCB3ZSdyZSBnb2luZyBiYWNrd2FyZHMsIGVuY291bnRlcmluZyB0aGUgaGlnaGVzdCBwcmVjZWRlbmNlIGl0ZW1zIGZpcnN0LgotICAgIGZvciAoaW50IGkgPSByZWNvbXBvc2FibGVFbGVtZW50cy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkKLSAgICAgICgoRWxlbVRlbXBsYXRlRWxlbWVudCkgcmVjb21wb3NhYmxlRWxlbWVudHMuZWxlbWVudEF0KGkpKS5yZWNvbXBvc2UodGhpcyk7Ci0gICAgCi0gICAgaW5pdENvbXBvc2VTdGF0ZSgpOwotCi0gICAgLy8gTmVlZCBmaW5hbCBjb21wb3NpdGlvbiBvZiBUZW1wbGF0ZUxpc3QuICBUaGlzIGFkZHMgdGhlIHdpbGQgY2FyZHMgb250byB0aGUgY2hhaW5zLgotICAgIG1fdGVtcGxhdGVMaXN0LmNvbXBvc2UodGhpcyk7Ci0gICAgCi0gICAgLy8gTmVlZCB0byBjbGVhciBjaGVjayBmb3IgcHJvcGVydGllcyBhdCB0aGUgc2FtZSBpbXBvcnQgbGV2ZWwuCi0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLmNvbXBvc2UodGhpcyk7Ci0gICAgbV9vdXRwdXRQcm9wZXJ0aWVzLmVuZENvbXBvc2UodGhpcyk7Ci0gICAgCi0gICAgLy8gTm93IGNhbGwgdGhlIGNvbXBvc2UoKSBtZXRob2Qgb24gZXZlcnkgZWxlbWVudCB0byBnaXZlIGl0IGEgY2hhbmNlIHRvIGFkanVzdAotICAgIC8vIGJhc2VkIG9uIGNvbXBvc2VkIHZhbHVlcy4KLSAgICAKLSAgICBuID0gZ2V0R2xvYmFsSW1wb3J0Q291bnQoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFN0eWxlc2hlZXRDb21wb3NlZCBpbXBvcnRlZCA9IHRoaXMuZ2V0R2xvYmFsSW1wb3J0KGkpOwotICAgICAgaW50IGluY2x1ZGVkQ291bnQgPSBpbXBvcnRlZC5nZXRJbmNsdWRlQ291bnRDb21wb3NlZCgpOwotICAgICAgZm9yIChpbnQgaiA9IC0xOyBqIDwgaW5jbHVkZWRDb3VudDsgaisrKQotICAgICAgewotICAgICAgICBTdHlsZXNoZWV0IGluY2x1ZGVkID0gaW1wb3J0ZWQuZ2V0SW5jbHVkZUNvbXBvc2VkKGopOwotICAgICAgICBjb21wb3NlVGVtcGxhdGVzKGluY2x1ZGVkKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgCi0gICAgY2xlYXJDb21wb3NlU3RhdGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsIHRoZSBjb21wb3NlIGZ1bmN0aW9uIGZvciBlYWNoIEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSB0ZW1wbCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGVtcGxhdGUgZWxlbWVudCB0aGF0IHdpbGwgaGF2ZSAKLSAgICogdGhlIGNvbXBvc2VkIG1ldGhvZCBjYWxsZWQgb24gaXQsIGFuZCB3aWxsIGhhdmUgaXQncyBjaGlsZHJlbidzIGNvbXBvc2VkIAotICAgKiBtZXRob2RzIGNhbGxlZC4KLSAgICovCi0gIHZvaWQgY29tcG9zZVRlbXBsYXRlcyhFbGVtVGVtcGxhdGVFbGVtZW50IHRlbXBsKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdGVtcGwuY29tcG9zZSh0aGlzKTsKLQotICAgIGZvciAoRWxlbVRlbXBsYXRlRWxlbWVudCBjaGlsZCA9IHRlbXBsLmdldEZpcnN0Q2hpbGRFbGVtKCk7Ci0gICAgICAgICAgICBjaGlsZCAhPSBudWxsOyBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nRWxlbSgpKQotICAgIHsKLSAgICAgIGNvbXBvc2VUZW1wbGF0ZXMoY2hpbGQpOwotICAgIH0KLSAgICAKLSAgICB0ZW1wbC5lbmRDb21wb3NlKHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBjb21iaW5lZCBsaXN0IG9mIGltcG9ydHMuICBUaGUgc3R5bGVzaGVldCB3aXRoIHRoZSBoaWdoZXN0Ci0gICAqIGltcG9ydCBwcmVjZWRlbmNlIHdpbGwgYmUgYXQgZWxlbWVudCAwLiAgVGhlIG9uZSB3aXRoIHRoZSBsb3dlc3QKLSAgICogaW1wb3J0IHByZWNlZGVuY2Ugd2lsbCBiZSBhdCBlbGVtZW50IGxlbmd0aCAtIDEuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgU3R5bGVzaGVldENvbXBvc2VkW10gbV9nbG9iYWxJbXBvcnRMaXN0OwotCi0gIC8qKgotICAgKiBBZGQgdGhlIGltcG9ydHMgaW4gdGhlIGdpdmVuIHNoZWV0IHRvIHRoZSB3b3JraW5nIGltcG9ydExpc3QgdmVjdG9yLgotICAgKiBUaGUgd2lsbCBiZSBhZGRlZCBmcm9tIGhpZ2hlc3QgaW1wb3J0IHByZWNlZGVuY2UgdG8KLSAgICogbGVhc3QgaW1wb3J0IHByZWNlZGVuY2UuICBUaGlzIGlzIGEgcG9zdC1vcmRlciB0cmF2ZXJzYWwgb2YgdGhlCi0gICAqIGltcG9ydCB0cmVlIGFzIGRlc2NyaWJlZCBpbiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Lmh0bWwjaW1wb3J0Ij50aGUKLSAgICogWFNMVCBSZWNvbW1lbmRhdGlvbjwvYT4uCi0gICAqIDxwPkZvciBleGFtcGxlLCBzdXBwb3NlPC9wPgotICAgKiA8cD5zdHlsZXNoZWV0IEEgaW1wb3J0cyBzdHlsZXNoZWV0cyBCIGFuZCBDIGluIHRoYXQgb3JkZXI7PC9wPgotICAgKiA8cD5zdHlsZXNoZWV0IEIgaW1wb3J0cyBzdHlsZXNoZWV0IEQ7PC9wPgotICAgKiA8cD5zdHlsZXNoZWV0IEMgaW1wb3J0cyBzdHlsZXNoZWV0IEUuPC9wPgotICAgKiA8cD5UaGVuIHRoZSBvcmRlciBvZiBpbXBvcnQgcHJlY2VkZW5jZSAoaGlnaGVzdCBmaXJzdCkgaXMKLSAgICogQSwgQywgRSwgQiwgRC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBzdHlsZXNoZWV0IFN0eWxlc2hlZXQgdG8gZXhhbWluZSBmb3IgaW1wb3J0cy4KLSAgICogQHBhcmFtIGFkZFRvTGlzdCAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyB0ZW1wbGF0ZSBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGltcG9ydCBsaXN0Ci0gICAqIEBwYXJhbSBpbXBvcnRMaXN0IFRoZSB3b3JraW5nIGltcG9ydCBsaXN0LiAgVGVtcGxhdGVzIGFyZSBhZGRlZCBoZXJlIGluIHRoZSByZXZlcnNlCi0gICAqICAgICAgICBvcmRlciBvZiBwcmlvcml0eS4gIFdoZW4gd2UncmUgYWxsIGRvbmUsIHdlJ2xsIHJldmVyc2UgdGhpcyB0byB0aGUgY29ycmVjdAotICAgKiAgICAgICAgcHJpb3JpdHkgaW4gYW4gYXJyYXkuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBhZGRJbXBvcnRzKFN0eWxlc2hlZXQgc3R5bGVzaGVldCwgYm9vbGVhbiBhZGRUb0xpc3QsIFZlY3RvciBpbXBvcnRMaXN0KQotICB7Ci0KLSAgICAvLyBHZXQgdGhlIGRpcmVjdCBpbXBvcnRzIG9mIHRoaXMgc2hlZXQuCi0KLSAgICBpbnQgbiA9IHN0eWxlc2hlZXQuZ2V0SW1wb3J0Q291bnQoKTsKLQotICAgIGlmIChuID4gMCkKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgU3R5bGVzaGVldCBpbXBvcnRlZCA9IHN0eWxlc2hlZXQuZ2V0SW1wb3J0KGkpOwotCi0gICAgICAgIGFkZEltcG9ydHMoaW1wb3J0ZWQsIHRydWUsIGltcG9ydExpc3QpOwotICAgICAgfQotICAgIH0KLQotICAgIG4gPSBzdHlsZXNoZWV0LmdldEluY2x1ZGVDb3VudCgpOwotCi0gICAgaWYgKG4gPiAwKQotICAgIHsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgewotICAgICAgICBTdHlsZXNoZWV0IGluY2x1ZGVkID0gc3R5bGVzaGVldC5nZXRJbmNsdWRlKGkpOwotCi0gICAgICAgIGFkZEltcG9ydHMoaW5jbHVkZWQsIGZhbHNlLCBpbXBvcnRMaXN0KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoYWRkVG9MaXN0KQotICAgICAgaW1wb3J0TGlzdC5hZGRFbGVtZW50KHN0eWxlc2hlZXQpOwotCi0gIH0KLQotICAvKioKLSAgICogR2V0IGEgc3R5bGVzaGVldCBmcm9tIHRoZSBnbG9iYWwgaW1wb3J0IGxpc3QuIAotICAgKiBUT0RPOiBKS0VTUyBQUk9QT1NFUyBTUEVDSUFMLUNBU0UgRk9SIE5PIElNUE9SVCBMSVNULCBUTyBNQVRDSCBDT1VOVC4KLSAgICogCi0gICAqIEBwYXJhbSBpIEluZGV4IG9mIHN0eWxlc2hlZXQgdG8gZ2V0IGZyb20gZ2xvYmFsIGltcG9ydCBsaXN0IAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHlsZXNoZWV0IGF0IHRoZSBnaXZlbiBpbmRleCAKLSAgICovCi0gIHB1YmxpYyBTdHlsZXNoZWV0Q29tcG9zZWQgZ2V0R2xvYmFsSW1wb3J0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fZ2xvYmFsSW1wb3J0TGlzdFtpXTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHRvdGFsIG51bWJlciBvZiBpbXBvcnRzIGluIHRoZSBnbG9iYWwgaW1wb3J0IGxpc3QuCi0gICAqIAotICAgKiBAcmV0dXJuIFRoZSB0b3RhbCBudW1iZXIgb2YgaW1wb3J0ZWQgc3R5bGVzaGVldHMsIGluY2x1ZGluZwotICAgKiB0aGUgcm9vdCBzdHlsZXNoZWV0LCB0aHVzIHRoZSBudW1iZXIgd2lsbCBhbHdheXMgYmUgMSBvcgotICAgKiBncmVhdGVyLgotICAgKiBUT0RPOiBKS0VTUyBQUk9QT1NFUyBTUEVDSUFMLUNBU0UgRk9SIE5PIElNUE9SVCBMSVNULCBUTyBNQVRDSCBERVNDUklQVElPTi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0R2xvYmFsSW1wb3J0Q291bnQoKQotICB7Ci0gICAgICAgICAgcmV0dXJuIChtX2dsb2JhbEltcG9ydExpc3QhPW51bGwpCi0gICAgICAgICAgICAgICAgICAgICAgICA/IG1fZ2xvYmFsSW1wb3J0TGlzdC5sZW5ndGggCi0gICAgICAgICAgICAgICAgICAgICAgICAgIDogMTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHN0eWxlc2hlZXQsIHJldHVybiB0aGUgbnVtYmVyIG9mIHRoZSBzdHlsZXNoZWV0Ci0gICAqIGluIHRoZSBnbG9iYWwgaW1wb3J0IGxpc3QuCi0gICAqIEBwYXJhbSBzaGVldCBUaGUgc3R5bGVzaGVldCB3aGljaCB3aWxsIGJlIGxvY2F0ZWQgaW4gdGhlCi0gICAqIGdsb2JhbCBpbXBvcnQgbGlzdC4KLSAgICogQHJldHVybiBUaGUgaW5kZXggaW50byB0aGUgZ2xvYmFsIGltcG9ydCBsaXN0IG9mIHRoZSBnaXZlbiBzdHlsZXNoZWV0LAotICAgKiBvciAtMSBpZiBpdCBpcyBub3QgZm91bmQgKHdoaWNoIHNob3VsZCBuZXZlciBoYXBwZW4pLgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbXBvcnROdW1iZXIoU3R5bGVzaGVldENvbXBvc2VkIHNoZWV0KQotICB7Ci0KLSAgICBpZiAodGhpcyA9PSBzaGVldCkKLSAgICAgIHJldHVybiAwOwotCi0gICAgaW50IG4gPSBnZXRHbG9iYWxJbXBvcnRDb3VudCgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgaWYgKHNoZWV0ID09IGdldEdsb2JhbEltcG9ydChpKSkKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgd2lsbCBiZSBzZXQgdXAgd2l0aCB0aGUgZGVmYXVsdCB2YWx1ZXMsIGFuZCB0aGVuIHRoZSB2YWx1ZXMKLSAgICogd2lsbCBiZSBzZXQgYXMgc3R5bGVzaGVldHMgYXJlIGVuY291bnRlcmVkLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIE91dHB1dFByb3BlcnRpZXMgbV9vdXRwdXRQcm9wZXJ0aWVzOwotCi0gIC8qKgotICAgKiBSZWNvbXBvc2UgdGhlIG91dHB1dCBmb3JtYXQgb2JqZWN0IGZyb20gdGhlIGluY2x1ZGVkIGVsZW1lbnRzLgotICAgKgotICAgKiBAcGFyYW0gb3Byb3BzIG5vbi1udWxsIHJlZmVyZW5jZSB0byB4c2w6b3V0cHV0IHByb3BlcnRpZXMgcmVwcmVzZW50YXRpb24uCi0gICAqLwotICB2b2lkIHJlY29tcG9zZU91dHB1dChPdXRwdXRQcm9wZXJ0aWVzIG9wcm9wcykKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIAotICAgIG1fb3V0cHV0UHJvcGVydGllcy5jb3B5RnJvbShvcHJvcHMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY29tYmluZWQgInhzbDpvdXRwdXQiIHByb3BlcnR5IHdpdGggdGhlIHByb3BlcnRpZXMKLSAgICogY29tYmluZWQgZnJvbSB0aGUgaW5jbHVkZWQgc3R5bGVzaGVldHMuICBJZiBhIHhzbDpvdXRwdXQKLSAgICogaXMgbm90IGRlY2xhcmVkIGluIHRoaXMgc3R5bGVzaGVldCBvciBhbiBpbmNsdWRlZCBzdHlsZXNoZWV0LAotICAgKiBsb29rIGluIHRoZSBpbXBvcnRzLgotICAgKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgT3V0cHV0UHJvcGVydGllcwotICAgKiBvYmplY3QsIG5vdCBhIGNsb25lZCBvYmplY3QsIGxpa2UgZ2V0T3V0cHV0UHJvcGVydGllcyBkb2VzLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij5vdXRwdXQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21wb3NlZCBvdXRwdXQgcHJvcGVydGllcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgT3V0cHV0UHJvcGVydGllcyBnZXRPdXRwdXRDb21wb3NlZCgpCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0T3V0cHV0Q29tcG9zZWQuZ2V0SW5kZW50OiAiK21fb3V0cHV0UHJvcGVydGllcy5nZXRJbmRlbnQoKSk7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXRPdXRwdXRDb21wb3NlZC5nZXRJbmRlbnRpbmc6ICIrbV9vdXRwdXRQcm9wZXJ0aWVzLmdldEluZGVudGluZygpKTsKLSAgICByZXR1cm4gbV9vdXRwdXRQcm9wZXJ0aWVzOwotICB9Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIGFuIG91dHB1dCBtZXRob2QgaGFzIGJlZW4gc2V0IGJ5IHRoZSB1c2VyLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fb3V0cHV0TWV0aG9kU2V0ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBGaW5kIG91dCBpZiBhbiBvdXRwdXQgbWV0aG9kIGhhcyBiZWVuIHNldCBieSB0aGUgdXNlci4KLSAgICoKLSAgICogQHJldHVybiBWYWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgYW4gb3V0cHV0IG1ldGhvZCBoYXMgYmVlbiBzZXQgYnkgdGhlIHVzZXIKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0TWV0aG9kU2V0KCkKLSAgewotICAgIHJldHVybiBtX291dHB1dE1ldGhvZFNldDsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wb3NlZCBzZXQgb2YgYWxsIGluY2x1ZGVkIGFuZCBpbXBvcnRlZCBhdHRyaWJ1dGUgc2V0IHByb3BlcnRpZXMuCi0gICAqIEVhY2ggZW50cnkgaXMgYSB2ZWN0b3Igb2YgRWxlbUF0dHJpYnV0ZVNldCBvYmplY3RzLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2F0dHJTZXRzOwotCi0gIC8qKgotICAgKiBSZWNvbXBvc2UgdGhlIGF0dHJpYnV0ZS1zZXQgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAcGFyYW0gYXR0clNldCBBbiBhdHRyaWJ1dGUtc2V0IHRvIGFkZCB0byB0aGUgaGFzaHRhYmxlIG9mIGF0dHJpYnV0ZSBzZXRzLgotICAgKi8KLSAgdm9pZCByZWNvbXBvc2VBdHRyaWJ1dGVTZXRzKEVsZW1BdHRyaWJ1dGVTZXQgYXR0clNldCkKLSAgewotICAgIFZlY3RvciBhdHRyU2V0TGlzdCA9IChWZWN0b3IpIG1fYXR0clNldHMuZ2V0KGF0dHJTZXQuZ2V0TmFtZSgpKTsKLQotICAgIGlmIChudWxsID09IGF0dHJTZXRMaXN0KQotICAgIHsKLSAgICAgIGF0dHJTZXRMaXN0ID0gbmV3IFZlY3RvcigpOwotCi0gICAgICBtX2F0dHJTZXRzLnB1dChhdHRyU2V0LmdldE5hbWUoKSwgYXR0clNldExpc3QpOwotICAgIH0KLQotICAgIGF0dHJTZXRMaXN0LmFkZEVsZW1lbnQoYXR0clNldCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgbGlzdCAieHNsOmF0dHJpYnV0ZS1zZXQiIHByb3BlcnRpZXMgdGhhdCBtYXRjaCB0aGUgcW5hbWUuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNhdHRyaWJ1dGUtc2V0cyI+YXR0cmlidXRlLXNldHMgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBRdWFsaWZpZWQgbmFtZSBvZiBhdHRyaWJ1dGUgc2V0IHByb3BlcnRpZXMgdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4gQSB2ZWN0b3Igb2YgYXR0cmlidXRlIHNldHMgbWF0Y2hpbmcgdGhlIGdpdmVuIG5hbWUKLSAgICoKLSAgICogQHRocm93cyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBWZWN0b3IgZ2V0QXR0cmlidXRlU2V0Q29tcG9zZWQoUU5hbWUgbmFtZSkKLSAgICAgICAgICB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKFZlY3RvcikgbV9hdHRyU2V0cy5nZXQobmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogVGFibGUgb2YgRGVjaW1hbEZvcm1hdFN5bWJvbHMsIGtleWVkIGJ5IFFOYW1lLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2RlY2ltYWxGb3JtYXRTeW1ib2xzOwotCi0gIC8qKgotICAgKiBSZWNvbXBvc2UgdGhlIGRlY2ltYWwtZm9ybWF0IGRlY2xhcmF0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGRmcCBBIERlY2ltYWxGb3JtYXRQcm9wZXJ0aWVzIHRvIGFkZCB0byB0aGUgaGFzaHRhYmxlIG9mIGRlY2ltYWwgZm9ybWF0cy4KLSAgICovCi0gIHZvaWQgcmVjb21wb3NlRGVjaW1hbEZvcm1hdHMoRGVjaW1hbEZvcm1hdFByb3BlcnRpZXMgZGZwKQotICB7Ci0gICAgRGVjaW1hbEZvcm1hdFN5bWJvbHMgb2xkRGZzID0KLSAgICAgICAgICAgICAgICAgIChEZWNpbWFsRm9ybWF0U3ltYm9scykgbV9kZWNpbWFsRm9ybWF0U3ltYm9scy5nZXQoZGZwLmdldE5hbWUoKSk7Ci0gICAgaWYgKG51bGwgPT0gb2xkRGZzKQotICAgIHsKLSAgICAgIG1fZGVjaW1hbEZvcm1hdFN5bWJvbHMucHV0KGRmcC5nZXROYW1lKCksIGRmcC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWRmcC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpLmVxdWFscyhvbGREZnMpKQotICAgIHsKLSAgICAgIFN0cmluZyB0aGVtc2c7Ci0gICAgICBpZiAoZGZwLmdldE5hbWUoKS5lcXVhbHMobmV3IFFOYW1lKCIiKSkpCi0gICAgICB7Ci0gICAgICAgIC8vICJPbmx5IG9uZSBkZWZhdWx0IHhzbDpkZWNpbWFsLWZvcm1hdCBkZWNsYXJhdGlvbiBpcyBhbGxvd2VkLiIKLSAgICAgICAgdGhlbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlV2FybmluZygKLSAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLldHX09ORV9ERUZBVUxUX1hTTERFQ0lNQUxGT1JNQVRfQUxMT1dFRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFswXSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vICJ4c2w6ZGVjaW1hbC1mb3JtYXQgbmFtZXMgbXVzdCBiZSB1bmlxdWUuIE5hbWUgezB9IGhhcyBiZWVuIGR1cGxpY2F0ZWQuIgotICAgICAgICB0aGVtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVXYXJuaW5nKAotICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuV0dfWFNMREVDSU1BTEZPUk1BVF9OQU1FU19NVVNUX0JFX1VOSVFVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtkZnAuZ2V0TmFtZSgpfSk7Ci0gICAgICB9Ci0KLSAgICAgIGVycm9yKHRoZW1zZyk7ICAgLy8gU2hvdWxkIHdlIHRocm93IFRyYW5zZm9ybWVyRXhjZXB0aW9uIGluc3RlYWQ/Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSB2YWxpZCBlbGVtZW50IGRlY2ltYWwtZm9ybWF0IG5hbWUsIHJldHVybiB0aGUKLSAgICogZGVjaW1hbEZvcm1hdFN5bWJvbHMgd2l0aCB0aGF0IG5hbWUuCi0gICAqIDxwPkl0IGlzIGFuIGVycm9yIHRvIGRlY2xhcmUgZWl0aGVyIHRoZSBkZWZhdWx0IGRlY2ltYWwtZm9ybWF0IG9yCi0gICAqIGEgZGVjaW1hbC1mb3JtYXQgd2l0aCBhIGdpdmVuIG5hbWUgbW9yZSB0aGFuIG9uY2UgKGV2ZW4gd2l0aAotICAgKiBkaWZmZXJlbnQgaW1wb3J0IHByZWNlZGVuY2UpLCB1bmxlc3MgaXQgaXMgZGVjbGFyZWQgZXZlcnkKLSAgICogdGltZSB3aXRoIHRoZSBzYW1lIHZhbHVlIGZvciBhbGwgYXR0cmlidXRlcyAodGFraW5nIGludG8KLSAgICogYWNjb3VudCBhbnkgZGVmYXVsdCB2YWx1ZXMpLjwvcD4KLSAgICogPHA+V2hpY2ggbWVhbnMsIGFzIGZhciBhcyBJIGNhbiB0ZWxsLCB0aGUgZGVjaW1hbC1mb3JtYXQKLSAgICogcHJvcGVydGllcyBhcmUgbm90IGFkZGl0aXZlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgUXVhbGlmaWVkIG5hbWUgb2YgdGhlIGRlY2ltYWwgZm9ybWF0IHRvIGZpbmQgCi0gICAqIEByZXR1cm4gRGVjaW1hbEZvcm1hdFN5bWJvbHMgb2JqZWN0IG1hdGNoaW5nIHRoZSBnaXZlbiBuYW1lIG9yCi0gICAqIG51bGwgaWYgbmFtZSBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgRGVjaW1hbEZvcm1hdFN5bWJvbHMgZ2V0RGVjaW1hbEZvcm1hdENvbXBvc2VkKFFOYW1lIG5hbWUpCi0gIHsKLSAgICByZXR1cm4gKERlY2ltYWxGb3JtYXRTeW1ib2xzKSBtX2RlY2ltYWxGb3JtYXRTeW1ib2xzLmdldChuYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBBIGxpc3Qgb2YgYWxsIGtleSBkZWNsYXJhdGlvbnMgdmlzaWJsZSBmcm9tIHRoaXMgc3R5bGVzaGVldCBhbmQgYWxsCi0gICAqIGxlc3NlciBzdHlsZXNoZWV0cy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9rZXlEZWNsczsKLQotICAvKioKLSAgICogUmVjb21wb3NlIHRoZSBrZXkgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAcGFyYW0ga2V5RGVjbCBBIEtleURlY2xhcmF0aW9uIHRvIGJlIGFkZGVkIHRvIHRoZSB2ZWN0b3Igb2Yga2V5IGRlY2xhcmF0aW9ucy4KLSAgICovCi0gIHZvaWQgcmVjb21wb3NlS2V5cyhLZXlEZWNsYXJhdGlvbiBrZXlEZWNsKQotICB7Ci0gICAgbV9rZXlEZWNscy5hZGRFbGVtZW50KGtleURlY2wpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY29tcG9zZWQgInhzbDprZXkiIHByb3BlcnRpZXMuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNrZXkiPmtleSBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gQSB2ZWN0b3Igb2YgdGhlIGNvbXBvc2VkICJ4c2w6a2V5IiBwcm9wZXJ0aWVzLgotICAgKi8KLSAgcHVibGljIFZlY3RvciBnZXRLZXlzQ29tcG9zZWQoKQotICB7Ci0gICAgcmV0dXJuIG1fa2V5RGVjbHM7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcG9zZWQgc2V0IG9mIGFsbCBuYW1lc3BhY2UgYWxpYXNlcy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBIYXNodGFibGUgbV9uYW1lc3BhY2VBbGlhc0NvbXBvc2VkOwotCi0gIC8qKgotICAgKiBSZWNvbXBvc2UgdGhlIG5hbWVzcGFjZS1hbGlhcyBkZWNsYXJhdGlvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBuc0FsaWFzIEEgTmFtZXNwYWNlQWxpYXMgb2JqZWN0IHRvIGFkZCB0byB0aGUgaGFzaHRhYmxlIG9mIG5hbWVzcGFjZSBhbGlhc2VzLgotICAgKi8KLSAgdm9pZCByZWNvbXBvc2VOYW1lc3BhY2VBbGlhc2VzKE5hbWVzcGFjZUFsaWFzIG5zQWxpYXMpCi0gIHsKLSAgICBtX25hbWVzcGFjZUFsaWFzQ29tcG9zZWQucHV0KG5zQWxpYXMuZ2V0U3R5bGVzaGVldE5hbWVzcGFjZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnNBbGlhcyk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSAieHNsOm5hbWVzcGFjZS1hbGlhcyIgcHJvcGVydHkuCi0gICAqIFJldHVybiB0aGUgTmFtZXNwYWNlQWxpYXMgZm9yIGEgZ2l2ZW4gbmFtZXNwYWNlIHVyaS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2xpdGVyYWwtcmVzdWx0LWVsZW1lbnQiPmxpdGVyYWwtcmVzdWx0LWVsZW1lbnQgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gdXJpIG5vbi1udWxsIHJlZmVyZW5jZSB0byBuYW1lc3BhY2UgdGhhdCBpcyB0byBiZSBhbGlhc2VkLgotICAgKgotICAgKiBAcmV0dXJuIE5hbWVzcGFjZUFsaWFzIHRoYXQgbWF0Y2hlcyB1cmksIG9yIG51bGwgaWYgbm8gbWF0Y2guCi0gICAqLwotICBwdWJsaWMgTmFtZXNwYWNlQWxpYXMgZ2V0TmFtZXNwYWNlQWxpYXNDb21wb3NlZChTdHJpbmcgdXJpKQotICB7Ci0gICAgcmV0dXJuIChOYW1lc3BhY2VBbGlhcykgKChudWxsID09IG1fbmFtZXNwYWNlQWxpYXNDb21wb3NlZCkgCi0gICAgICAgICAgICAgICAgICAgID8gbnVsbCA6IG1fbmFtZXNwYWNlQWxpYXNDb21wb3NlZC5nZXQodXJpKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlICJ4c2w6dGVtcGxhdGUiIHByb3BlcnRpZXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVGVtcGxhdGVMaXN0IG1fdGVtcGxhdGVMaXN0OwotCi0gIC8qKgotICAgKiBSZWNvbXBvc2UgdGhlIHRlbXBsYXRlIGRlY2xhcmF0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIHRlbXBsYXRlIEFuIEVsZW1UZW1wbGF0ZSBvYmplY3QgdG8gYWRkIHRvIHRoZSB0ZW1wbGF0ZSBsaXN0LgotICAgKi8KLSAgdm9pZCByZWNvbXBvc2VUZW1wbGF0ZXMoRWxlbVRlbXBsYXRlIHRlbXBsYXRlKQotICB7Ci0gICAgbV90ZW1wbGF0ZUxpc3Quc2V0VGVtcGxhdGUodGVtcGxhdGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFjY2Vzc29yIG1ldGhvZCB0byByZXRyaWV2ZSB0aGUgPGNvZGU+VGVtcGxhdGVMaXN0PC9jb2RlPiBhc3NvY2lhdGVkIHdpdGgKLSAgICogdGhpcyBTdHlsZXNoZWV0Um9vdC4KLSAgICogCi0gICAqIEByZXR1cm4gVGhlIGNvbXBvc2VkIDxjb2RlPlRlbXBsYXRlTGlzdDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgZmluYWwgVGVtcGxhdGVMaXN0IGdldFRlbXBsYXRlTGlzdENvbXBvc2VkKCkKLSAgewotICAgIHJldHVybiBtX3RlbXBsYXRlTGlzdDsKLSAgfQotCi0gIC8qKgotICAgKiBNdXRhdG9yIG1ldGhvZCB0byBzZXQgdGhlIDxjb2RlPlRlbXBsYXRlTGlzdDwvY29kZT4gYXNzb2NpYXRlZCB3aXRoIHRoaXMKLSAgICogU3R5bGVzaGVldFJvb3QuICBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSB1c2VkIGJ5IHRoZSBjb21waWxlci4gIE5vcm1hbGx5LAotICAgKiB0aGUgdGVtcGxhdGUgbGlzdCBpcyBidWlsdCBkdXJpbmcgdGhlIHJlY29tcG9zZSBwcm9jZXNzIGFuZCBzaG91bGQgbm90IGJlCi0gICAqIGFsdGVyZWQgYnkgdGhlIHVzZXIuCi0gICAqIEBwYXJhbSB0ZW1wbGF0ZUxpc3QgVGhlIG5ldyA8Y29kZT5UZW1wbGF0ZUxpc3Q8L2NvZGU+IGZvciB0aGlzIFN0eWxlc2hlZXRSb290LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGVtcGxhdGVMaXN0Q29tcG9zZWQoVGVtcGxhdGVMaXN0IHRlbXBsYXRlTGlzdCkKLSAgewotICAgIG1fdGVtcGxhdGVMaXN0ID0gdGVtcGxhdGVMaXN0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiAieHNsOnRlbXBsYXRlIiBwcm9wZXJ0eSBieSBub2RlIG1hdGNoLiBUaGlzIGxvb2tzIGluIHRoZSBpbXBvcnRzIGFzCi0gICAqIHdlbGwgYXMgdGhpcyBzdHlsZXNoZWV0LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1EZWZpbmluZy1UZW1wbGF0ZS1SdWxlcyI+c2VjdGlvbi1EZWZpbmluZy1UZW1wbGF0ZS1SdWxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBub24tbnVsbCByZWZlcmVuY2UgdG8gWFBhdGggcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHBhcmFtIHRhcmdldE5vZGUgbm9uLW51bGwgcmVmZXJlbmNlIG9mIG5vZGUgdGhhdCB0aGUgdGVtcGxhdGUgbXVzdCBtYXRjaC4KLSAgICogQHBhcmFtIG1vZGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIG5vZGUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBtYXhJbXBvcnRMZXZlbCBUaGUgbWF4aW11bSBpbXBvcnRDb3VudENvbXBvc2VkIHRoYXQgd2Ugc2hvdWxkIGNvbnNpZGVyIG9yIC0xCi0gICAqICAgICAgICBpZiB3ZSBzaG91bGQgY29uc2lkZXIgYWxsIGltcG9ydCBsZXZlbHMuICBUaGlzIGlzIHVzZWQgYnkgYXBwbHktaW1wb3J0cyB0bwotICAgKiAgICAgICAgYWNjZXNzIHRlbXBsYXRlcyB0aGF0IGhhdmUgYmVlbiBvdmVycmlkZGVuLgotICAgKiBAcGFyYW0gcXVpZXRDb25mbGljdFdhcm5pbmdzIHRydWUgaWYgY29uZmxpY3Qgd2FybmluZ3Mgc2hvdWxkIG5vdCBiZSByZXBvcnRlZC4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8gRWxlbVRlbXBsYXRlIHRoYXQgaXMgdGhlIGJlc3QgbWF0Y2ggZm9yIHRhcmdldE5vZGUsIG9yIAotICAgKiAgICAgICAgIG51bGwgaWYgbm8gbWF0Y2ggY291bGQgYmUgbWFkZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZSBnZXRUZW1wbGF0ZUNvbXBvc2VkKFhQYXRoQ29udGV4dCB4Y3R4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0YXJnZXROb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUU5hbWUgbW9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXhJbXBvcnRMZXZlbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcXVpZXRDb25mbGljdFdhcm5pbmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNIGR0bSkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1fdGVtcGxhdGVMaXN0LmdldFRlbXBsYXRlKHhjdHh0LCB0YXJnZXROb2RlLCBtb2RlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4SW1wb3J0TGV2ZWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1aWV0Q29uZmxpY3RXYXJuaW5ncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRtKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gInhzbDp0ZW1wbGF0ZSIgcHJvcGVydHkuIFRoaXMgbG9va3MgaW4gdGhlIGltcG9ydHMgYXMKLSAgICogd2VsbCBhcyB0aGlzIHN0eWxlc2hlZXQuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIj5zZWN0aW9uLURlZmluaW5nLVRlbXBsYXRlLVJ1bGVzIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIG5vbi1udWxsIHJlZmVyZW5jZSB0byBxdWFsaWZpZWQgbmFtZSBvZiB0ZW1wbGF0ZS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8gbmFtZWQgdGVtcGxhdGUsIG9yIG51bGwgaWYgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZSBnZXRUZW1wbGF0ZUNvbXBvc2VkKFFOYW1lIHFuYW1lKQotICB7Ci0gICAgcmV0dXJuIG1fdGVtcGxhdGVMaXN0LmdldFRlbXBsYXRlKHFuYW1lKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbXBvc2VkIHNldCBvZiBhbGwgdmFyaWFibGVzIGFuZCBwYXJhbXMuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fdmFyaWFibGVzOwotCi0gIC8qKgotICAgKiBSZWNvbXBvc2UgdGhlIHRvcCBsZXZlbCB2YXJpYWJsZSBhbmQgcGFyYW1ldGVyIGRlY2xhcmF0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGVsZW1WYXIgQSB0b3AgbGV2ZWwgdmFyaWFibGUgb3IgcGFyYW1ldGVyIHRvIGJlIGFkZGVkIHRvIHRoZSBWZWN0b3IuCi0gICAqLwotICB2b2lkIHJlY29tcG9zZVZhcmlhYmxlcyhFbGVtVmFyaWFibGUgZWxlbVZhcikKLSAgewotICAgIC8vIERvbid0IG92ZXJpZGUgaGlnaGVyIHByaW9yaXR5IHZhcmlhYmxlICAgICAgICAKLSAgICBpZiAoZ2V0VmFyaWFibGVPclBhcmFtQ29tcG9zZWQoZWxlbVZhci5nZXROYW1lKCkpID09IG51bGwpCi0gICAgewotICAgICAgZWxlbVZhci5zZXRJc1RvcExldmVsKHRydWUpOyAgICAgICAgLy8gTWFyayBhcyBhIHRvcC1sZXZlbCB2YXJpYWJsZSBvciBwYXJhbQotICAgICAgZWxlbVZhci5zZXRJbmRleChtX3ZhcmlhYmxlcy5zaXplKCkpOwotICAgICAgbV92YXJpYWJsZXMuYWRkRWxlbWVudChlbGVtVmFyKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuICJ4c2w6dmFyaWFibGUiIHByb3BlcnR5LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjdG9wLWxldmVsLXZhcmlhYmxlcyI+dG9wLWxldmVsLXZhcmlhYmxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBxbmFtZSBRdWFsaWZpZWQgbmFtZSBvZiB2YXJpYWJsZSBvciBwYXJhbQotICAgKgotICAgKiBAcmV0dXJuIFRoZSBFbGVtVmFyaWFibGUgd2l0aCB0aGUgZ2l2ZW4gcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBFbGVtVmFyaWFibGUgZ2V0VmFyaWFibGVPclBhcmFtQ29tcG9zZWQoUU5hbWUgcW5hbWUpCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX3ZhcmlhYmxlcykKLSAgICB7Ci0gICAgICBpbnQgbiA9IG1fdmFyaWFibGVzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIEVsZW1WYXJpYWJsZSB2YXIgPSAoRWxlbVZhcmlhYmxlKW1fdmFyaWFibGVzLmVsZW1lbnRBdChpKTsKLSAgICAgICAgaWYodmFyLmdldE5hbWUoKS5lcXVhbHMocW5hbWUpKQotICAgICAgICAgIHJldHVybiB2YXI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFsbCBnbG9iYWwgInhzbDp2YXJpYWJsZSIgcHJvcGVydGllcyBpbiBzY29wZSBmb3IgdGhpcyBzdHlsZXNoZWV0LgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjdG9wLWxldmVsLXZhcmlhYmxlcyI+dG9wLWxldmVsLXZhcmlhYmxlcyBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEByZXR1cm4gVmVjdG9yIG9mIGFsbCB2YXJpYWJsZXMgYW5kIHBhcmFtcyBpbiBzY29wZQotICAgKi8KLSAgcHVibGljIFZlY3RvciBnZXRWYXJpYWJsZXNBbmRQYXJhbXNDb21wb3NlZCgpCi0gIHsKLSAgICByZXR1cm4gbV92YXJpYWJsZXM7Ci0gIH0KLQotICAvKioKLSAgICogQSBsaXN0IG9mIHByb3BlcnRpZXMgdGhhdCBzcGVjaWZ5IGhvdyB0byBkbyBzcGFjZQotICAgKiBzdHJpcHBpbmcuIFRoaXMgdXNlcyB0aGUgc2FtZSBleGFjdCBtZWNoYW5pc20gYXMgVGVtcGxhdGVzLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIFRlbXBsYXRlTGlzdCBtX3doaXRlU3BhY2VJbmZvTGlzdDsKLQotICAvKioKLSAgICogUmVjb21wb3NlIHRoZSBzdHJpcC1zcGFjZSBhbmQgcHJlc2VydmUtc3BhY2UgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAcGFyYW0gd3NpIEEgV2hpdGVTcGFjZUluZm8gZWxlbWVudCB0byBhZGQgdG8gdGhlIGxpc3Qgb2YgV2hpdGVTcGFjZUluZm8gZWxlbWVudHMuCi0gICAqLwotICB2b2lkIHJlY29tcG9zZVdoaXRlU3BhY2VJbmZvKFdoaXRlU3BhY2VJbmZvIHdzaSkKLSAgewotICAgIGlmIChudWxsID09IG1fd2hpdGVTcGFjZUluZm9MaXN0KQotICAgICAgbV93aGl0ZVNwYWNlSW5mb0xpc3QgPSBuZXcgVGVtcGxhdGVMaXN0KCk7Ci0KLSAgICBtX3doaXRlU3BhY2VJbmZvTGlzdC5zZXRUZW1wbGF0ZSh3c2kpOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRvIHNlZSBpZiB0aGUgY2FsbGVyIHNob3VsZCBib3RoZXIgd2l0aCBjaGVjayBmb3IKLSAgICogd2hpdGVzcGFjZSBub2Rlcy4KLSAgICoKLSAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjYWxsZXIgc2hvdWxkIGJvdGhlciB3aXRoIGNoZWNrIGZvcgotICAgKiB3aGl0ZXNwYWNlIG5vZGVzLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc2hvdWxkQ2hlY2tXaGl0ZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBudWxsICE9IG1fd2hpdGVTcGFjZUluZm9MaXN0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIG9yIG5vdCBhbiBlbGVtZW50IHNob3VsZCBzdHJpcCB3aGl0ZXNwYWNlLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgc3RhdGUuCi0gICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IEVsZW1lbnQgdG8gY2hlY2sKLSAgICoKLSAgICogQHJldHVybiBXaGl0ZVNwYWNlSW5mbyBmb3IgdGhlIGdpdmVuIGVsZW1lbnQKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFdoaXRlU3BhY2VJbmZvIGdldFdoaXRlU3BhY2VJbmZvKAotICAgICAgICAgIFhQYXRoQ29udGV4dCBzdXBwb3J0LCBpbnQgdGFyZ2V0RWxlbWVudCwgRFRNIGR0bSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsICE9IG1fd2hpdGVTcGFjZUluZm9MaXN0KQotICAgICAgcmV0dXJuIChXaGl0ZVNwYWNlSW5mbykgbV93aGl0ZVNwYWNlSW5mb0xpc3QuZ2V0VGVtcGxhdGUoc3VwcG9ydCwKLSAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudCwgbnVsbCwgLTEsIGZhbHNlLCBkdG0pOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgb3Igbm90IGFuIGVsZW1lbnQgc2hvdWxkIHN0cmlwIHdoaXRlc3BhY2UuCi0gICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNzdHJpcCI+c3RyaXAgaW4gWFNMVCBTcGVjaWZpY2F0aW9uPC9hPgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBzdGF0ZS4KLSAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgRWxlbWVudCB0byBjaGVjawotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHdoaXRlc3BhY2Ugc2hvdWxkIGJlIHN0cmlwcGVkLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzaG91bGRTdHJpcFdoaXRlU3BhY2UoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHN1cHBvcnQsIGludCB0YXJnZXRFbGVtZW50KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmIChudWxsICE9IG1fd2hpdGVTcGFjZUluZm9MaXN0KQotICAgIHsKLSAgICAgIHdoaWxlKERUTS5OVUxMICE9IHRhcmdldEVsZW1lbnQpCi0gICAgICB7Ci0gICAgICAgIERUTSBkdG0gPSBzdXBwb3J0LmdldERUTSh0YXJnZXRFbGVtZW50KTsKLSAgICAgICAgV2hpdGVTcGFjZUluZm8gaW5mbyA9IChXaGl0ZVNwYWNlSW5mbykgbV93aGl0ZVNwYWNlSW5mb0xpc3QuZ2V0VGVtcGxhdGUoc3VwcG9ydCwKLSAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50LCBudWxsLCAtMSwgZmFsc2UsIGR0bSk7Ci0gICAgICAgIGlmKG51bGwgIT0gaW5mbykKLSAgICAgICAgICByZXR1cm4gaW5mby5nZXRTaG91bGRTdHJpcFNwYWNlKCk7Ci0gICAgICAgIAotICAgICAgICBpbnQgcGFyZW50ID0gZHRtLmdldFBhcmVudCh0YXJnZXRFbGVtZW50KTsKLSAgICAgICAgaWYoRFRNLk5VTEwgIT0gcGFyZW50ICYmIERUTS5FTEVNRU5UX05PREUgPT0gZHRtLmdldE5vZGVUeXBlKHBhcmVudCkpCi0gICAgICAgICAgdGFyZ2V0RWxlbWVudCA9IHBhcmVudDsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHRhcmdldEVsZW1lbnQgPSBEVE0uTlVMTDsKLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgb3Igbm90IHdoaXRlc3BhY2UgY2FuIGJlIHN0cmlwcGVkLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB3aGl0ZXNwYWNlIGNhbiBiZSBzdHJpcHBlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblN0cmlwV2hpdGVTcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV93aGl0ZVNwYWNlSW5mb0xpc3QpOwotICB9Ci0gIAotCi0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBUaGUgZGVmYXVsdCB0ZW1wbGF0ZSB0byB1c2UgZm9yIHRleHQgbm9kZXMgaWYgd2UgZG9uJ3QgZmluZAotICAgKiBhbnl0aGluZyBlbHNlLiAgVGhpcyBpcyBpbml0aWFsaXplZCBpbiBpbml0RGVmYXVsdFJ1bGUoKS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBFbGVtVGVtcGxhdGUgbV9kZWZhdWx0VGV4dFJ1bGU7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBHZXQgdGhlIGRlZmF1bHQgdGVtcGxhdGUgZm9yIHRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgdGVtcGxhdGUgZm9yIHRleHQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgRWxlbVRlbXBsYXRlIGdldERlZmF1bHRUZXh0UnVsZSgpCi0gIHsKLSAgICByZXR1cm4gbV9kZWZhdWx0VGV4dFJ1bGU7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRoZSBkZWZhdWx0IHRlbXBsYXRlIHRvIHVzZSBpZiB3ZSBkb24ndCBmaW5kIGFueXRoaW5nCi0gICAqIGVsc2UuICBUaGlzIGlzIGluaXRpYWxpemVkIGluIGluaXREZWZhdWx0UnVsZSgpLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEVsZW1UZW1wbGF0ZSBtX2RlZmF1bHRSdWxlOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogR2V0IHRoZSBkZWZhdWx0IHRlbXBsYXRlIGZvciBlbGVtZW50cy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZGVmYXVsdCB0ZW1wbGF0ZSBmb3IgZWxlbWVudHMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgRWxlbVRlbXBsYXRlIGdldERlZmF1bHRSdWxlKCkKLSAgewotICAgIHJldHVybiBtX2RlZmF1bHRSdWxlOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBUaGUgZGVmYXVsdCB0ZW1wbGF0ZSB0byB1c2UgZm9yIHRoZSByb290IGlmIHdlIGRvbid0IGZpbmQKLSAgICogYW55dGhpbmcgZWxzZS4gIFRoaXMgaXMgaW5pdGlhbGl6ZWQgaW4gaW5pdERlZmF1bHRSdWxlKCkuCi0gICAqIFdlIGtpbmQgb2YgbmVlZCB0aGlzIGJlY2F1c2UgdGhlIGRlZmF1bHRSdWxlIGlzbid0IGdvb2QKLSAgICogZW5vdWdoIGJlY2F1c2UgaXQgZG9lc24ndCBzdXBwbHkgYSBkb2N1bWVudCBjb250ZXh0LgotICAgKiBGb3Igbm93LCBJIGRlZmF1bHQgdGhlIHJvb3QgZG9jdW1lbnQgZWxlbWVudCB0byAiSFRNTCIuCi0gICAqIERvbid0IGtub3cgaWYgdGhpcyBpcyByZWFsbHkgYSBnb29kIGlkZWEgb3Igbm90LgotICAgKiBJIHN1c3BlY3QgaXQgaXMgbm90LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEVsZW1UZW1wbGF0ZSBtX2RlZmF1bHRSb290UnVsZTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIEdldCB0aGUgZGVmYXVsdCB0ZW1wbGF0ZSBmb3IgYSByb290IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRlZmF1bHQgdGVtcGxhdGUgZm9yIGEgcm9vdCBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIEVsZW1UZW1wbGF0ZSBnZXREZWZhdWx0Um9vdFJ1bGUoKQotICB7Ci0gICAgcmV0dXJuIG1fZGVmYXVsdFJvb3RSdWxlOwotICB9Ci0gIAotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRoZSBzdGFydCBydWxlIHRvIGtpY2sgb2ZmIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBFbGVtVGVtcGxhdGUgbV9zdGFydFJ1bGU7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBHZXQgdGhlIGRlZmF1bHQgdGVtcGxhdGUgZm9yIGEgcm9vdCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0IHRlbXBsYXRlIGZvciBhIHJvb3Qgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBFbGVtVGVtcGxhdGUgZ2V0U3RhcnRSdWxlKCkKLSAgewotICAgIHJldHVybiBtX3N0YXJ0UnVsZTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFVzZWQgZm9yIGRlZmF1bHQgc2VsZWN0aW9uLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBYUGF0aCBtX3NlbGVjdERlZmF1bHQ7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSB0aGUgZGVmYXVsdCBydWxlIGlmIG5lZWRlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXREZWZhdWx0UnVsZShFcnJvckxpc3RlbmVyIGVycm9yTGlzdGVuZXIpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBUaGVuIG1hbnVmYWN0dXJlIGEgZGVmYXVsdAotICAgIG1fZGVmYXVsdFJ1bGUgPSBuZXcgRWxlbVRlbXBsYXRlKCk7Ci0KLSAgICBtX2RlZmF1bHRSdWxlLnNldFN0eWxlc2hlZXQodGhpcyk7Ci0KLSAgICBYUGF0aCBkZWZNYXRjaCA9IG5ldyBYUGF0aCgiKiIsIHRoaXMsIHRoaXMsIFhQYXRoLk1BVENILCBlcnJvckxpc3RlbmVyKTsKLQotICAgIG1fZGVmYXVsdFJ1bGUuc2V0TWF0Y2goZGVmTWF0Y2gpOwotCi0gICAgRWxlbUFwcGx5VGVtcGxhdGVzIGNoaWxkcmVuRWxlbWVudCA9IG5ldyBFbGVtQXBwbHlUZW1wbGF0ZXMoKTsKLQotICAgIGNoaWxkcmVuRWxlbWVudC5zZXRJc0RlZmF1bHRUZW1wbGF0ZSh0cnVlKTsKLSAgICBjaGlsZHJlbkVsZW1lbnQuc2V0U2VsZWN0KG1fc2VsZWN0RGVmYXVsdCk7Ci0gICAgbV9kZWZhdWx0UnVsZS5hcHBlbmRDaGlsZChjaGlsZHJlbkVsZW1lbnQpOwotICAgIAotICAgIG1fc3RhcnRSdWxlID0gbV9kZWZhdWx0UnVsZTsKLQotICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgbV9kZWZhdWx0VGV4dFJ1bGUgPSBuZXcgRWxlbVRlbXBsYXRlKCk7Ci0KLSAgICBtX2RlZmF1bHRUZXh0UnVsZS5zZXRTdHlsZXNoZWV0KHRoaXMpOwotCi0gICAgZGVmTWF0Y2ggPSBuZXcgWFBhdGgoInRleHQoKSB8IEAqIiwgdGhpcywgdGhpcywgWFBhdGguTUFUQ0gsIGVycm9yTGlzdGVuZXIpOwotCi0gICAgbV9kZWZhdWx0VGV4dFJ1bGUuc2V0TWF0Y2goZGVmTWF0Y2gpOwotCi0gICAgRWxlbVZhbHVlT2YgZWxlbVZhbHVlT2YgPSBuZXcgRWxlbVZhbHVlT2YoKTsKLQotICAgIG1fZGVmYXVsdFRleHRSdWxlLmFwcGVuZENoaWxkKGVsZW1WYWx1ZU9mKTsKLQotICAgIFhQYXRoIHNlbGVjdFBhdHRlcm4gPSBuZXcgWFBhdGgoIi4iLCB0aGlzLCB0aGlzLCBYUGF0aC5TRUxFQ1QsIGVycm9yTGlzdGVuZXIpOwotCi0gICAgZWxlbVZhbHVlT2Yuc2V0U2VsZWN0KHNlbGVjdFBhdHRlcm4pOwotCi0gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIG1fZGVmYXVsdFJvb3RSdWxlID0gbmV3IEVsZW1UZW1wbGF0ZSgpOwotCi0gICAgbV9kZWZhdWx0Um9vdFJ1bGUuc2V0U3R5bGVzaGVldCh0aGlzKTsKLQotICAgIGRlZk1hdGNoID0gbmV3IFhQYXRoKCIvIiwgdGhpcywgdGhpcywgWFBhdGguTUFUQ0gsIGVycm9yTGlzdGVuZXIpOwotCi0gICAgbV9kZWZhdWx0Um9vdFJ1bGUuc2V0TWF0Y2goZGVmTWF0Y2gpOwotCi0gICAgY2hpbGRyZW5FbGVtZW50ID0gbmV3IEVsZW1BcHBseVRlbXBsYXRlcygpOwotCi0gICAgY2hpbGRyZW5FbGVtZW50LnNldElzRGVmYXVsdFRlbXBsYXRlKHRydWUpOwotICAgIG1fZGVmYXVsdFJvb3RSdWxlLmFwcGVuZENoaWxkKGNoaWxkcmVuRWxlbWVudCk7Ci0gICAgY2hpbGRyZW5FbGVtZW50LnNldFNlbGVjdChtX3NlbGVjdERlZmF1bHQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgYSBnZW5lcmljIHZlcnNpb24gb2YgQy5BLlIgSG9hcmUncyBRdWljayBTb3J0Ci0gICAqIGFsZ29yaXRobS4gIFRoaXMgd2lsbCBoYW5kbGUgYXJyYXlzIHRoYXQgYXJlIGFscmVhZHkKLSAgICogc29ydGVkLCBhbmQgYXJyYXlzIHdpdGggZHVwbGljYXRlIGtleXMuICBJdCB3YXMgbGlmdGVkIGZyb20KLSAgICogdGhlIE5vZGVTb3J0ZXIgY2xhc3MgYnV0IHNob3VsZCBwcm9iYWJseSBiZSBlbGltaW5hdGVkIGFuZCByZXBsYWNlZAotICAgKiB3aXRoIGEgY2FsbCB0byBDb2xsZWN0aW9ucy5zb3J0IHdoZW4gd2UgbWlncmF0ZSB0byBKYXZhMi48QlI+Ci0gICAqCi0gICAqIElmIHlvdSB0aGluayBvZiBhIG9uZSBkaW1lbnNpb25hbCBhcnJheSBhcyBnb2luZyBmcm9tCi0gICAqIHRoZSBsb3dlc3QgaW5kZXggb24gdGhlIGxlZnQgdG8gdGhlIGhpZ2hlc3QgaW5kZXggb24gdGhlIHJpZ2h0Ci0gICAqIHRoZW4gdGhlIHBhcmFtZXRlcnMgdG8gdGhpcyBmdW5jdGlvbiBhcmUgbG93ZXN0IGluZGV4IG9yCi0gICAqIGxlZnQgYW5kIGhpZ2hlc3QgaW5kZXggb3IgcmlnaHQuICBUaGUgZmlyc3QgdGltZSB5b3UgY2FsbAotICAgKiB0aGlzIGZ1bmN0aW9uIGl0IHdpbGwgYmUgd2l0aCB0aGUgcGFyYW1ldGVycyAwLCBhLmxlbmd0aCAtIDEuCi0gICAqCi0gICAqIEBwYXJhbSB2ICAgICAgIGEgdmVjdG9yIG9mIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbWVudHMgCi0gICAqIEBwYXJhbSBsbzAgICAgIGxlZnQgYm91bmRhcnkgb2YgcGFydGl0aW9uCi0gICAqIEBwYXJhbSBoaTAgICAgIHJpZ2h0IGJvdW5kYXJ5IG9mIHBhcnRpdGlvbgotICAgKgotICAgKi8KLQotICBwcml2YXRlIHZvaWQgUXVpY2tTb3J0MihWZWN0b3IgdiwgaW50IGxvMCwgaW50IGhpMCkKLSAgICB7Ci0gICAgICBpbnQgbG8gPSBsbzA7Ci0gICAgICBpbnQgaGkgPSBoaTA7Ci0KLSAgICAgIGlmICggaGkwID4gbG8wKQotICAgICAgewotICAgICAgICAvLyBBcmJpdHJhcmlseSBlc3RhYmxpc2hpbmcgcGFydGl0aW9uIGVsZW1lbnQgYXMgdGhlIG1pZHBvaW50IG9mCi0gICAgICAgIC8vIHRoZSBhcnJheS4KLSAgICAgICAgRWxlbVRlbXBsYXRlRWxlbWVudCBtaWROb2RlID0gKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIHYuZWxlbWVudEF0KCAoIGxvMCArIGhpMCApIC8gMiApOwotCi0gICAgICAgIC8vIGxvb3AgdGhyb3VnaCB0aGUgYXJyYXkgdW50aWwgaW5kaWNlcyBjcm9zcwotICAgICAgICB3aGlsZSggbG8gPD0gaGkgKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gZmluZCB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bwotICAgICAgICAgIC8vIHRoZSBwYXJ0aXRpb24gZWxlbWVudCBzdGFydGluZyBmcm9tIHRoZSBsZWZ0IEluZGV4LgotICAgICAgICAgIHdoaWxlKCAobG8gPCBoaTApICYmICgoKEVsZW1UZW1wbGF0ZUVsZW1lbnQpIHYuZWxlbWVudEF0KGxvKSkuY29tcGFyZVRvKG1pZE5vZGUpIDwgMCkgKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICsrbG87Ci0gICAgICAgICAgfSAvLyBlbmQgd2hpbGUKLQotICAgICAgICAgIC8vIGZpbmQgYW4gZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0bwotICAgICAgICAgIC8vIHRoZSBwYXJ0aXRpb24gZWxlbWVudCBzdGFydGluZyBmcm9tIHRoZSByaWdodCBJbmRleC4KLSAgICAgICAgICB3aGlsZSggKGhpID4gbG8wKSAmJiAoKChFbGVtVGVtcGxhdGVFbGVtZW50KSB2LmVsZW1lbnRBdChoaSkpLmNvbXBhcmVUbyhtaWROb2RlKSA+IDApICkgICAgICAgICAgewotICAgICAgICAgICAgLS1oaTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAvLyBpZiB0aGUgaW5kZXhlcyBoYXZlIG5vdCBjcm9zc2VkLCBzd2FwCi0gICAgICAgICAgaWYoIGxvIDw9IGhpICkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IG5vZGUgPSAoRWxlbVRlbXBsYXRlRWxlbWVudCkgdi5lbGVtZW50QXQobG8pOwotICAgICAgICAgICAgdi5zZXRFbGVtZW50QXQodi5lbGVtZW50QXQoaGkpLCBsbyk7Ci0gICAgICAgICAgICB2LnNldEVsZW1lbnRBdChub2RlLCBoaSk7Ci0KLSAgICAgICAgICAgICsrbG87Ci0gICAgICAgICAgICAtLWhpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoZSByaWdodCBpbmRleCBoYXMgbm90IHJlYWNoZWQgdGhlIGxlZnQgc2lkZSBvZiBhcnJheQotICAgICAgICAvLyBtdXN0IG5vdyBzb3J0IHRoZSBsZWZ0IHBhcnRpdGlvbi4KLSAgICAgICAgaWYoIGxvMCA8IGhpICkKLSAgICAgICAgewotICAgICAgICAgIFF1aWNrU29ydDIoIHYsIGxvMCwgaGkgKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIElmIHRoZSBsZWZ0IGluZGV4IGhhcyBub3QgcmVhY2hlZCB0aGUgcmlnaHQgc2lkZSBvZiBhcnJheQotICAgICAgICAvLyBtdXN0IG5vdyBzb3J0IHRoZSByaWdodCBwYXJ0aXRpb24uCi0gICAgICAgIGlmKCBsbyA8IGhpMCApCi0gICAgICAgIHsKLSAgICAgICAgICBRdWlja1NvcnQyKCB2LCBsbywgaGkwICk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9IC8vIGVuZCBRdWlja1NvcnQyICAqLwotICAgIAotICAgIHByaXZhdGUgQ29tcG9zZVN0YXRlIG1fY29tcG9zZVN0YXRlOwotICAgIAotICAgIC8qKgotICAgICAqIEluaXRpYWxpemUgYSBuZXcgQ29tcG9zZVN0YXRlLgotICAgICAqLwotICAgIHZvaWQgaW5pdENvbXBvc2VTdGF0ZSgpCi0gICAgewotICAgICAgbV9jb21wb3NlU3RhdGUgPSBuZXcgQ29tcG9zZVN0YXRlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGNsYXNzIHRvIHRyYWNrIHN0YXRlIGdsb2JhbCBzdGF0ZSBkdXJpbmcgdGhlIGNvbXBvc2UoKSBvcGVyYXRpb24uCi0gICAgICogQHJldHVybiBDb21wb3NlU3RhdGUgcmVmZXJlbmNlLCBvciBudWxsIGlmIGVuZENvbXBvc2UgaGFzIGJlZW4gY2FsbGVkLgotICAgICAqLwotICAgIENvbXBvc2VTdGF0ZSBnZXRDb21wb3NlU3RhdGUoKQotICAgIHsKLSAgICAgIHJldHVybiBtX2NvbXBvc2VTdGF0ZTsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogQ2xlYXIgdGhlIGNvbXBvc2Ugc3RhdGUuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNsZWFyQ29tcG9zZVN0YXRlKCkKLSAgICB7Ci0gICAgICBtX2NvbXBvc2VTdGF0ZSA9IG51bGw7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIENsYXNzIHRvIHRyYWNrIHN0YXRlIGdsb2JhbCBzdGF0ZSBkdXJpbmcgdGhlIGNvbXBvc2UoKSBvcGVyYXRpb24uCi0gICAgICovCi0gICAgY2xhc3MgQ29tcG9zZVN0YXRlCi0gICAgewotICAgICAgQ29tcG9zZVN0YXRlKCkKLSAgICAgIHsKLSAgICAgICAgaW50IHNpemUgPSBtX3ZhcmlhYmxlcy5zaXplKCk7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSAKLSAgICAgICAgewotICAgICAgICAgIEVsZW1WYXJpYWJsZSBldiA9IChFbGVtVmFyaWFibGUpbV92YXJpYWJsZXMuZWxlbWVudEF0KGkpOwotICAgICAgICAgIG1fdmFyaWFibGVOYW1lcy5hZGRFbGVtZW50KGV2LmdldE5hbWUoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICB9Ci0gICAgICAKLSAgICAgIHByaXZhdGUgRXhwYW5kZWROYW1lVGFibGUgbV9lbnQgPSBuZXcgRXhwYW5kZWROYW1lVGFibGUoKTsKLSAgICAgIAotICAgICAgLyoqCi0gICAgICAgKiBHaXZlbiBhIHF1YWxpZmllZCBuYW1lLCByZXR1cm4gYW4gaW50ZWdlciBJRCB0aGF0IGNhbiBiZSAKLSAgICAgICAqIHF1aWNrbHkgY29tcGFyZWQuCi0gICAgICAgKgotICAgICAgICogQHBhcmFtIHFuYW1lIGEgcXVhbGlmaWVkIG5hbWUgb2JqZWN0LCBtdXN0IG5vdCBiZSBudWxsLgotICAgICAgICoKLSAgICAgICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIHF1YWxpZmllZCBuYW1lLgotICAgICAgICovCi0gICAgICBwdWJsaWMgaW50IGdldFFOYW1lSUQoUU5hbWUgcW5hbWUpCi0gICAgICB7Ci0gICAgICAgIAotICAgICAgICByZXR1cm4gbV9lbnQuZ2V0RXhwYW5kZWRUeXBlSUQocW5hbWUuZ2V0TmFtZXNwYWNlKCksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWUuZ2V0TG9jYWxOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgdHlwZSBkb2Vzbid0IG1hdHRlciBmb3Igb3VyIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHVycG9zZXMuIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54bWwuZHRtLkRUTS5FTEVNRU5UX05PREUpOwotICAgICAgfQotICAgICAgCi0gICAgICAvKioKLSAgICAgICAqIEEgVmVjdG9yIG9mIHRoZSBjdXJyZW50IHBhcmFtcyBhbmQgUU5hbWVzIHdpdGhpbiB0aGUgY3VycmVudCB0ZW1wbGF0ZS4KLSAgICAgICAqIFNldCBieSBFbGVtVGVtcGxhdGUgYW5kIHVzZWQgYnkgUHJvY2Vzc29yVmFyaWFibGUuCi0gICAgICAgKi8KLSAgICAgIHByaXZhdGUgamF2YS51dGlsLlZlY3RvciBtX3ZhcmlhYmxlTmFtZXMgPSBuZXcgamF2YS51dGlsLlZlY3RvcigpOwotICAgICAgICAgICAgCi0gICAgICAvKioKLSAgICAgICAqIEFkZCB0aGUgbmFtZSBvZiBhIHF1YWxpZmllZCBuYW1lIHdpdGhpbiB0aGUgdGVtcGxhdGUuICBUaGUgcG9zaXRpb24gaW4gCi0gICAgICAgKiB0aGUgdmVjdG9yIGlzIGl0cyBJRC4KLSAgICAgICAqIEBwYXJhbSBxbmFtZSBBIHF1YWxpZmllZCBuYW1lIG9mIGEgcGFyYW0gb3IgdmFyaWFibGUsIHNob3VsZCBiZSBub24tbnVsbC4KLSAgICAgICAqIEByZXR1cm4gdGhlIGluZGV4IHdoZXJlIHRoZSB2YXJpYWJsZSB3YXMgYWRkZWQuCi0gICAgICAgKi8KLSAgICAgIGludCBhZGRWYXJpYWJsZU5hbWUoZmluYWwgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWUgcW5hbWUpCi0gICAgICB7Ci0gICAgICAgIGludCBwb3MgPSBtX3ZhcmlhYmxlTmFtZXMuc2l6ZSgpOwotICAgICAgICBtX3ZhcmlhYmxlTmFtZXMuYWRkRWxlbWVudChxbmFtZSk7Ci0gICAgICAgIGludCBmcmFtZVNpemUgPSBtX3ZhcmlhYmxlTmFtZXMuc2l6ZSgpIC0gZ2V0R2xvYmFsc1NpemUoKTsKLSAgICAgICAgaWYoZnJhbWVTaXplID4gbV9tYXhTdGFja0ZyYW1lU2l6ZSkKLSAgICAgICAgICBtX21heFN0YWNrRnJhbWVTaXplKys7Ci0gICAgICAgIHJldHVybiBwb3M7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIHZvaWQgcmVzZXRTdGFja0ZyYW1lU2l6ZSgpCi0gICAgICB7Ci0gICAgICAgIG1fbWF4U3RhY2tGcmFtZVNpemUgPSAwOwotICAgICAgfQotICAgICAgCi0gICAgICBpbnQgZ2V0RnJhbWVTaXplKCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fbWF4U3RhY2tGcmFtZVNpemU7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIC8qKgotICAgICAgICogR2V0IHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHN0YWNrIGZyYW1lLiAgVXNlIHRoaXMgdG8gcmVjb3JkIHRoZSBwb3NpdGlvbiAKLSAgICAgICAqIGluIGEgdGVtcGxhdGUgZWxlbWVudCBhdCBzdGFydEVsZW1lbnQsIHNvIHRoYXQgaXQgY2FuIGJlIHBvcHBlZCAKLSAgICAgICAqIGF0IGVuZEVsZW1lbnQuCi0gICAgICAgKi8KLSAgICAgIGludCBnZXRDdXJyZW50U3RhY2tGcmFtZVNpemUoKQotICAgICAgewotICAgICAgICByZXR1cm4gbV92YXJpYWJsZU5hbWVzLnNpemUoKTsKLSAgICAgIH0KLSAgICAgIAotICAgICAgLyoqCi0gICAgICAgKiBTZXQgdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgc3RhY2sgZnJhbWUuCi0gICAgICAgKi8KLSAgICAgIHZvaWQgc2V0Q3VycmVudFN0YWNrRnJhbWVTaXplKGludCBzeikKLSAgICAgIHsKLSAgICAgICAgbV92YXJpYWJsZU5hbWVzLnNldFNpemUoc3opOwotICAgICAgfQotICAgICAgCi0gICAgICBpbnQgZ2V0R2xvYmFsc1NpemUoKQotICAgICAgewotICAgICAgICByZXR1cm4gbV92YXJpYWJsZXMuc2l6ZSgpOwotICAgICAgfQotICAgICAgCi0gICAgICBJbnRTdGFjayBtX21hcmtzID0gbmV3IEludFN0YWNrKCk7Ci0gICAgICAKLSAgICAgIHZvaWQgcHVzaFN0YWNrTWFyaygpCi0gICAgICB7Ci0gICAgICAgIG1fbWFya3MucHVzaChnZXRDdXJyZW50U3RhY2tGcmFtZVNpemUoKSk7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIHZvaWQgcG9wU3RhY2tNYXJrKCkKLSAgICAgIHsKLSAgICAgICAgaW50IG1hcmsgPSBtX21hcmtzLnBvcCgpOwotICAgICAgICBzZXRDdXJyZW50U3RhY2tGcmFtZVNpemUobWFyayk7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIC8qKgotICAgICAgICogR2V0IHRoZSBWZWN0b3Igb2YgdGhlIGN1cnJlbnQgcGFyYW1zIGFuZCBRTmFtZXMgdG8gYmUgY29sbGVjdGVkIAotICAgICAgICogd2l0aGluIHRoZSBjdXJyZW50IHRlbXBsYXRlLgotICAgICAgICogQHJldHVybiBBIHJlZmVyZW5jZSB0byB0aGUgdmVjdG9yIG9mIHZhcmlhYmxlIG5hbWVzLiAgVGhlIHJlZmVyZW5jZSAKLSAgICAgICAqIHJldHVybmVkIGlzIG93bmVkIGJ5IHRoaXMgY2xhc3MsIGFuZCBzbyBzaG91bGQgbm90IHJlYWxseSBiZSBtdXRhdGVkLCBvciAKLSAgICAgICAqIHN0b3JlZCBhbnl3aGVyZS4KLSAgICAgICAqLwotICAgICAgamF2YS51dGlsLlZlY3RvciBnZXRWYXJpYWJsZU5hbWVzKCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fdmFyaWFibGVOYW1lczsKLSAgICAgIH0KLSAgICAgIAotICAgICAgcHJpdmF0ZSBpbnQgbV9tYXhTdGFja0ZyYW1lU2l6ZTsKLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9UZW1wbGF0ZUxpc3QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9UZW1wbGF0ZUxpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTU0NGQ5NC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvVGVtcGxhdGVMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OTQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRXhwYW5kZWROYW1lVGFibGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLlBzdWVkb05hbWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLlN0ZXBQYXR0ZXJuOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuVW5pb25QYXR0ZXJuOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRW5jYXBzdWxhdGVzIGEgdGVtcGxhdGUgbGlzdCwgYW5kIGhlbHBzIGxvY2F0ZSBpbmRpdmlkdWFsIHRlbXBsYXRlcy4KLSAqLwotcHVibGljIGNsYXNzIFRlbXBsYXRlTGlzdCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFRlbXBsYXRlTGlzdCBvYmplY3QuIE5lZWRzIHRvIGJlIHB1YmxpYyBzbyBpdCBjYW4KLSAgICogYmUgaW52b2tlZCBmcm9tIHRoZSBDb21waWxpbmdTdHlsZXNoZWV0SGFuZGxlci4KLSAgICovCi0gIHB1YmxpYyBUZW1wbGF0ZUxpc3QoKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSB0ZW1wbGF0ZSB0byB0aGUgdGFibGUgb2YgbmFtZWQgdGVtcGxhdGVzIGFuZC9vciB0aGUgdGFibGUgb2YgdGVtcGxhdGVzCi0gICAqIHdpdGggbWF0Y2ggcGF0dGVybnMuICBUaGlzIHJvdXRpbmUgc2hvdWxkCi0gICAqIGJlIGNhbGxlZCBpbiBkZWNyZWFzaW5nIG9yZGVyIG9mIHByZWNlZGVuY2UgYnV0IGl0IGNoZWNrcyBub25ldGhlbGVzcy4KLSAgICoKLSAgICogQHBhcmFtIHRlbXBsYXRlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUZW1wbGF0ZShFbGVtVGVtcGxhdGUgdGVtcGxhdGUpCi0gIHsKLSAgICBpZiAobnVsbCAhPSB0ZW1wbGF0ZS5nZXROYW1lKCkpCi0gICAgewotICAgICAgRWxlbVRlbXBsYXRlIGV4aXN0aW5nVGVtcGxhdGUgPSAoRWxlbVRlbXBsYXRlKSBtX25hbWVkVGVtcGxhdGVzLmdldCh0ZW1wbGF0ZS5nZXROYW1lKCkpOwotICAgICAgaWYgKG51bGwgPT0gZXhpc3RpbmdUZW1wbGF0ZSkKLSAgICAgIHsKLSAgICAgICAgbV9uYW1lZFRlbXBsYXRlcy5wdXQodGVtcGxhdGUuZ2V0TmFtZSgpLCB0ZW1wbGF0ZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGludCBleGlzdGluZ1ByZWNlZGVuY2UgPQotICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdUZW1wbGF0ZS5nZXRTdHlsZXNoZWV0Q29tcG9zZWQoKS5nZXRJbXBvcnRDb3VudENvbXBvc2VkKCk7Ci0gICAgICAgIGludCBuZXdQcmVjZWRlbmNlID0gdGVtcGxhdGUuZ2V0U3R5bGVzaGVldENvbXBvc2VkKCkuZ2V0SW1wb3J0Q291bnRDb21wb3NlZCgpOwotICAgICAgICBpZiAobmV3UHJlY2VkZW5jZSA+IGV4aXN0aW5nUHJlY2VkZW5jZSkKLSAgICAgICAgewotICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgotICAgICAgICAgIG1fbmFtZWRUZW1wbGF0ZXMucHV0KHRlbXBsYXRlLmdldE5hbWUoKSwgdGVtcGxhdGUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKG5ld1ByZWNlZGVuY2UgPT0gZXhpc3RpbmdQcmVjZWRlbmNlKQotICAgICAgICAgIHRlbXBsYXRlLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9EVVBMSUNBVEVfTkFNRURfVEVNUExBVEUsCi0gICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgdGVtcGxhdGUuZ2V0TmFtZSgpIH0pOwotICAgICAgfQotICAgIH0KLQotICAgIFhQYXRoIG1hdGNoWFBhdGggPSB0ZW1wbGF0ZS5nZXRNYXRjaCgpOwotCi0gICAgaWYgKG51bGwgIT0gbWF0Y2hYUGF0aCkKLSAgICB7Ci0gICAgICBFeHByZXNzaW9uIG1hdGNoRXhwciA9IG1hdGNoWFBhdGguZ2V0RXhwcmVzc2lvbigpOwotCi0gICAgICBpZiAobWF0Y2hFeHByIGluc3RhbmNlb2YgU3RlcFBhdHRlcm4pCi0gICAgICB7Ci0gICAgICAgIGluc2VydFBhdHRlcm5JblRhYmxlKChTdGVwUGF0dGVybikgbWF0Y2hFeHByLCB0ZW1wbGF0ZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChtYXRjaEV4cHIgaW5zdGFuY2VvZiBVbmlvblBhdHRlcm4pCi0gICAgICB7Ci0gICAgICAgIFVuaW9uUGF0dGVybiB1cGF0ID0gKFVuaW9uUGF0dGVybikgbWF0Y2hFeHByOwotICAgICAgICBTdGVwUGF0dGVybltdIHBhdHMgPSB1cGF0LmdldFBhdHRlcm5zKCk7Ci0gICAgICAgIGludCBuID0gcGF0cy5sZW5ndGg7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpbnNlcnRQYXR0ZXJuSW5UYWJsZShwYXRzW2ldLCB0ZW1wbGF0ZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLQotICAgICAgICAvLyBUT0RPOiBhc3NlcnQgZXJyb3IKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKiogRmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIGluIERFQlVHIG1vZGUgICAgICAgICAgKi8KLSAgc3RhdGljIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogRHVtcCBhbGwgcGF0dGVybnMgYW5kIGVsZW1lbnRzIHRoYXQgbWF0Y2ggdGhvc2UgcGF0dGVybnMKLSAgICoKLSAgICovCi0gIHZvaWQgZHVtcEFzc29jaWF0aW9uVGFibGVzKCkKLSAgewotCi0gICAgRW51bWVyYXRpb24gYXNzb2NpYXRpb25zID0gbV9wYXR0ZXJuVGFibGUuZWxlbWVudHMoKTsKLQotICAgIHdoaWxlIChhc3NvY2lhdGlvbnMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gaGVhZCA9Ci0gICAgICAgIChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgYXNzb2NpYXRpb25zLm5leHRFbGVtZW50KCk7Ci0KLSAgICAgIHdoaWxlIChudWxsICE9IGhlYWQpCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIigiICsgaGVhZC5nZXRUYXJnZXRTdHJpbmcoKSArICIsICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIGhlYWQuZ2V0UGF0dGVybigpICsgIikiKTsKLQotICAgICAgICBoZWFkID0gaGVhZC5nZXROZXh0KCk7Ci0gICAgICB9Ci0KLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG4uLi4uLiIpOwotICAgIH0KLQotICAgIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGhlYWQgPSBtX3dpbGRDYXJkUGF0dGVybnM7Ci0KLSAgICBTeXN0ZW0ub3V0LnByaW50KCJ3aWxkIGNhcmQgbGlzdDogIik7Ci0KLSAgICB3aGlsZSAobnVsbCAhPSBoZWFkKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIigiICsgaGVhZC5nZXRUYXJnZXRTdHJpbmcoKSArICIsICIKLSAgICAgICAgICAgICAgICAgICAgICAgKyBoZWFkLmdldFBhdHRlcm4oKSArICIpIik7Ci0KLSAgICAgIGhlYWQgPSBoZWFkLmdldE5leHQoKTsKLSAgICB9Ci0KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuLi4uLi4iKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZnRlciBhbGwgdGVtcGxhdGVzIGhhdmUgYmVlbiBhZGRlZCwgdGhpcyBmdW5jdGlvbgotICAgKiBzaG91bGQgYmUgY2FsbGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tcG9zZShTdHlsZXNoZWV0Um9vdCBzcm9vdCkKLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQmVmb3JlIHdpbGRjYXJkIGluc2VydC4uLiIpOwotICAgICAgZHVtcEFzc29jaWF0aW9uVGFibGVzKCk7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gbV93aWxkQ2FyZFBhdHRlcm5zKQotICAgIHsKLSAgICAgIEVudW1lcmF0aW9uIGFzc29jaWF0aW9ucyA9IG1fcGF0dGVyblRhYmxlLmVsZW1lbnRzKCk7Ci0KLSAgICAgIHdoaWxlIChhc3NvY2lhdGlvbnMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgICB7Ci0gICAgICAgIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGhlYWQgPQotICAgICAgICAgIChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgYXNzb2NpYXRpb25zLm5leHRFbGVtZW50KCk7Ci0gICAgICAgIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIHdpbGQgPSBtX3dpbGRDYXJkUGF0dGVybnM7Ci0KLSAgICAgICAgd2hpbGUgKG51bGwgIT0gd2lsZCkKLSAgICAgICAgewotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGhlYWQgPSBpbnNlcnRBc3NvY2lhdGlvbkludG9MaXN0KAotICAgICAgICAgICAgICBoZWFkLCAoVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24pIHdpbGQuY2xvbmUoKSwgdHJ1ZSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKXt9Ci0KLSAgICAgICAgICB3aWxkID0gd2lsZC5nZXROZXh0KCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJBZnRlciB3aWxkY2FyZCBpbnNlcnQuLi4iKTsKLSAgICAgIGR1bXBBc3NvY2lhdGlvblRhYmxlcygpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgdGhlIGdpdmVuIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGludG8gdGhlIHRoZSBsaW5rZWQKLSAgICogbGlzdC4gIFNvcnQgYnkgaW1wb3J0IHByZWNlZGVuY2UsIHRoZW4gcHJpb3JpdHksIHRoZW4gYnkgZG9jdW1lbnQgb3JkZXIuCi0gICAqCi0gICAqIEBwYXJhbSBoZWFkIFRoZSBmaXJzdCBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBpbiB0aGUgbGlua2VkIGxpc3QuCi0gICAqIEBwYXJhbSBpdGVtIFRoZSBpdGVtIHRoYXQgd2Ugd2FudCB0byBpbnNlcnQgaW50byB0aGUgcHJvcGVyIHBsYWNlLgotICAgKiBAcGFyYW0gaXNXaWxkQ2FyZEluc2VydCA8Y29kZT50cnVlPC9jb2RlPiBpZiB3ZSBhcmUgaW5zZXJ0aW5nIGEgd2lsZCBjYXJkIAotICAgKiAgICAgICAgICAgICB0ZW1wbGF0ZSBvbnRvIHRoaXMgbGlzdC4KLSAgICogQHJldHVybiB0aGUgbmV3IGhlYWQgb2YgdGhlIGxpc3QuCi0gICAqLwotICBwcml2YXRlIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uCi0gICAgICAgICAgICAgIGluc2VydEFzc29jaWF0aW9uSW50b0xpc3QoVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gaGVhZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gaXRlbSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc1dpbGRDYXJkSW5zZXJ0KQotICB7Ci0KLSAgICAvLyBTb3J0IGZpcnN0IGJ5IGltcG9ydCBsZXZlbCAoaGlnaGVyIGxldmVsIGlzIGF0IGZyb250KSwKLSAgICAvLyB0aGVuIGJ5IHByaW9yaXR5IChoaWdoZXN0IHByaW9yaXR5IGlzIGF0IGZyb250KSwKLSAgICAvLyB0aGVuIGJ5IGRvY3VtZW50IG9yZGVyIChsYXRlciBpbiBkb2N1bWVudCBpcyBhdCBmcm9udCkuCi0KLSAgICBkb3VibGUgcHJpb3JpdHkgPSBnZXRQcmlvcml0eU9yU2NvcmUoaXRlbSk7Ci0gICAgZG91YmxlIHdvcmtQcmlvcml0eTsKLSAgICBpbnQgaW1wb3J0TGV2ZWwgPSBpdGVtLmdldEltcG9ydExldmVsKCk7Ci0gICAgaW50IGRvY09yZGVyID0gaXRlbS5nZXREb2NPcmRlclBvcygpOwotICAgIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGluc2VydFBvaW50ID0gaGVhZDsKLSAgICBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBuZXh0OwotICAgIGJvb2xlYW4gaW5zZXJ0QmVmb3JlOyAgICAgICAgIC8vIHRydWUgbWVhbnMgaW5zZXJ0IGJlZm9yZSBpbnNlcnRQb2ludDsgb3RoZXJ3aXNlIGFmdGVyCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBjYW4gb25seSBiZSB0cnVlIGlmIGluc2VydFBvaW50IGlzIHBvaW50aW5nIHRvCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IG9yIGxhc3QgdGVtcGxhdGUuCi0KLSAgICAvLyBTcGluIGRvd24gc28gdGhhdCBpbnNlcnRQb2ludCBwb2ludHMgdG86Ci0gICAgLy8gKGEpIHRoZSB0ZW1wbGF0ZSBpbW1lZGlhdGVseSBfYmVmb3JlXyB0aGUgZmlyc3QgdGVtcGxhdGUgb24gdGhlIGNoYWluIHdpdGgKLSAgICAvLyBhIHByZWNlZGVuY2UgdGhhdCBpcyBlaXRoZXIgKGkpIGxlc3MgdGhhbiBvdXJzIG9yIChpaSkgdGhlIHNhbWUgYXMgb3VycyBidXQKLSAgICAvLyB0aGUgdGVtcGxhdGUgZG9jdW1lbnQgcG9zaXRpb24gaXMgbGVzcyB0aGFuIG91cnMKLSAgICAvLyAtb3ItCi0gICAgLy8gKGIpIHRoZSBsYXN0IHRlbXBsYXRlIG9uIHRoZSBjaGFpbiBpZiBubyBzdWNoIHRlbXBsYXRlIGRlc2NyaWJlZCBpbiAoYSkgZXhpc3RzLgotICAgIC8vIElmIHdlIGFyZSBwb2ludGluZyB0byB0aGUgZmlyc3QgdGVtcGxhdGUgb3IgdGhlIGxhc3QgdGVtcGxhdGUgKHRoYXQgaXMsIGNhc2UgYiksCi0gICAgLy8gd2UgbmVlZCB0byBkZXRlcm1pbmUgd2hldGhlciB0byBpbnNlcnQgYmVmb3JlIG9yIGFmdGVyIHRoZSB0ZW1wbGF0ZS4gIE90aGVyd2lzZSwKLSAgICAvLyB3ZSBhbHdheXMgaW5zZXJ0IGFmdGVyIHRoZSBpbnNlcnRQb2ludC4KLQotICAgIHdoaWxlICh0cnVlKQotICAgIHsKLSAgICAgIG5leHQgPSBpbnNlcnRQb2ludC5nZXROZXh0KCk7Ci0gICAgICBpZiAobnVsbCA9PSBuZXh0KQotICAgICAgICBicmVhazsKLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgd29ya1ByaW9yaXR5ID0gZ2V0UHJpb3JpdHlPclNjb3JlKG5leHQpOwotICAgICAgICBpZiAoaW1wb3J0TGV2ZWwgPiBuZXh0LmdldEltcG9ydExldmVsKCkpCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGVsc2UgaWYgKGltcG9ydExldmVsIDwgbmV4dC5nZXRJbXBvcnRMZXZlbCgpKQotICAgICAgICAgIGluc2VydFBvaW50ID0gbmV4dDsKLSAgICAgICAgZWxzZSBpZiAocHJpb3JpdHkgPiB3b3JrUHJpb3JpdHkpICAgICAgICAgICAgICAgLy8gaW1wb3J0IHByZWNlZGVuY2UgaXMgZXF1YWwKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgZWxzZSBpZiAocHJpb3JpdHkgPCB3b3JrUHJpb3JpdHkpCi0gICAgICAgICAgaW5zZXJ0UG9pbnQgPSBuZXh0OwotICAgICAgICBlbHNlIGlmIChkb2NPcmRlciA+PSBuZXh0LmdldERvY09yZGVyUG9zKCkpICAgICAvLyBwcmlvcml0aWVzLCBpbXBvcnQgYXJlIGVxdWFsCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBpbnNlcnRQb2ludCA9IG5leHQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKCAobnVsbCA9PSBuZXh0KSB8fCAoaW5zZXJ0UG9pbnQgPT0gaGVhZCkgKSAgICAgIC8vIGluc2VydCBwb2ludCBpcyBmaXJzdCBvciBsYXN0Ci0gICAgewotICAgICAgd29ya1ByaW9yaXR5ID0gZ2V0UHJpb3JpdHlPclNjb3JlKGluc2VydFBvaW50KTsKLSAgICAgIGlmIChpbXBvcnRMZXZlbCA+IGluc2VydFBvaW50LmdldEltcG9ydExldmVsKCkpCi0gICAgICAgIGluc2VydEJlZm9yZSA9IHRydWU7Ci0gICAgICBlbHNlIGlmIChpbXBvcnRMZXZlbCA8IGluc2VydFBvaW50LmdldEltcG9ydExldmVsKCkpCi0gICAgICAgIGluc2VydEJlZm9yZSA9IGZhbHNlOwotICAgICAgZWxzZSBpZiAocHJpb3JpdHkgPiB3b3JrUHJpb3JpdHkpCi0gICAgICAgIGluc2VydEJlZm9yZSA9IHRydWU7Ci0gICAgICBlbHNlIGlmIChwcmlvcml0eSA8IHdvcmtQcmlvcml0eSkKLSAgICAgICAgaW5zZXJ0QmVmb3JlID0gZmFsc2U7Ci0gICAgICBlbHNlIGlmIChkb2NPcmRlciA+PSBpbnNlcnRQb2ludC5nZXREb2NPcmRlclBvcygpKQotICAgICAgICBpbnNlcnRCZWZvcmUgPSB0cnVlOwotICAgICAgZWxzZQotICAgICAgICBpbnNlcnRCZWZvcmUgPSBmYWxzZTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgaW5zZXJ0QmVmb3JlID0gZmFsc2U7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFwcGVuZGluZzogIit0YXJnZXQrIiB0byAiK21hdGNoUGF0LmdldFBhdHRlcm4oKSk7Ci0gICAgCi0gICAgaWYgKGlzV2lsZENhcmRJbnNlcnQpCi0gICAgewotICAgICAgaWYgKGluc2VydEJlZm9yZSkKLSAgICAgIHsKLSAgICAgICAgaXRlbS5zZXROZXh0KGluc2VydFBvaW50KTsKLQotICAgICAgICBTdHJpbmcga2V5ID0gaW5zZXJ0UG9pbnQuZ2V0VGFyZ2V0U3RyaW5nKCk7Ci0KLSAgICAgICAgaXRlbS5zZXRUYXJnZXRTdHJpbmcoa2V5KTsKLSAgICAgICAgcHV0SGVhZChrZXksIGl0ZW0pOwotICAgICAgICByZXR1cm4gaXRlbTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaXRlbS5zZXROZXh0KG5leHQpOwotICAgICAgICBpbnNlcnRQb2ludC5zZXROZXh0KGl0ZW0pOwotICAgICAgICByZXR1cm4gaGVhZDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChpbnNlcnRCZWZvcmUpCi0gICAgICB7Ci0gICAgICAgIGl0ZW0uc2V0TmV4dChpbnNlcnRQb2ludCk7Ci0KLSAgICAgICAgaWYgKGluc2VydFBvaW50LmlzV2lsZCgpIHx8IGl0ZW0uaXNXaWxkKCkpCi0gICAgICAgICAgbV93aWxkQ2FyZFBhdHRlcm5zID0gaXRlbTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIHB1dEhlYWQoaXRlbS5nZXRUYXJnZXRTdHJpbmcoKSwgaXRlbSk7Ci0gICAgICAgIHJldHVybiBpdGVtOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpdGVtLnNldE5leHQobmV4dCk7Ci0gICAgICAgIGluc2VydFBvaW50LnNldE5leHQoaXRlbSk7Ci0gICAgICAgIHJldHVybiBoZWFkOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSB0ZW1wbGF0ZSB0byB0aGUgdGVtcGxhdGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm4KLSAgICogQHBhcmFtIHRlbXBsYXRlCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5zZXJ0UGF0dGVybkluVGFibGUoU3RlcFBhdHRlcm4gcGF0dGVybiwgRWxlbVRlbXBsYXRlIHRlbXBsYXRlKQotICB7Ci0KLSAgICBTdHJpbmcgdGFyZ2V0ID0gcGF0dGVybi5nZXRUYXJnZXRTdHJpbmcoKTsKLQotICAgIGlmIChudWxsICE9IHRhcmdldCkKLSAgICB7Ci0gICAgICBTdHJpbmcgcHN0cmluZyA9IHRlbXBsYXRlLmdldE1hdGNoKCkuZ2V0UGF0dGVyblN0cmluZygpOwotICAgICAgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gYXNzb2NpYXRpb24gPQotICAgICAgICBuZXcgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24odGVtcGxhdGUsIHBhdHRlcm4sIHBzdHJpbmcpOwotCi0gICAgICAvLyBTZWUgaWYgdGhlcmUncyBhbHJlYWR5IG9uZSB0aGVyZQotICAgICAgYm9vbGVhbiBpc1dpbGRDYXJkID0gYXNzb2NpYXRpb24uaXNXaWxkKCk7Ci0gICAgICBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBoZWFkID0gaXNXaWxkQ2FyZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbV93aWxkQ2FyZFBhdHRlcm5zCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRIZWFkKHRhcmdldCk7Ci0KLSAgICAgIGlmIChudWxsID09IGhlYWQpCi0gICAgICB7Ci0gICAgICAgIGlmIChpc1dpbGRDYXJkKQotICAgICAgICAgIG1fd2lsZENhcmRQYXR0ZXJucyA9IGFzc29jaWF0aW9uOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcHV0SGVhZCh0YXJnZXQsIGFzc29jaWF0aW9uKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW5zZXJ0QXNzb2NpYXRpb25JbnRvTGlzdChoZWFkLCBhc3NvY2lhdGlvbiwgZmFsc2UpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG1hdGNoIHBhdHRlcm4gYW5kIHRlbXBsYXRlIGFzc29jaWF0aW9uLCByZXR1cm4gdGhlIAotICAgKiBzY29yZSBvZiB0aGF0IG1hdGNoLiAgVGhpcyBzY29yZSBvciBwcmlvcml0eSBjYW4gYWx3YXlzIGJlIAotICAgKiBzdGF0aWNhbGx5IGNhbGN1bGF0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBtYXRjaFBhdCBUaGUgbWF0Y2ggcGF0dGVybiB0byB0ZW1wbGF0ZSBhc3NvY2lhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sIAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PTkV9LCAKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LCAKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LCBvciAKLSAgICogICAgICAgICB0aGUgdmFsdWUgZGVmaW5lZCBieSB0aGUgcHJpb3JpdHkgYXR0cmlidXRlIG9mIHRoZSB0ZW1wbGF0ZS4KLSAgICoKLSAgICovCi0gIHByaXZhdGUgZG91YmxlIGdldFByaW9yaXR5T3JTY29yZShUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBtYXRjaFBhdCkKLSAgewotCi0gICAgZG91YmxlIHByaW9yaXR5ID0gbWF0Y2hQYXQuZ2V0VGVtcGxhdGUoKS5nZXRQcmlvcml0eSgpOwotCi0gICAgaWYgKHByaW9yaXR5ID09IFhQYXRoLk1BVENIX1NDT1JFX05PTkUpCi0gICAgewotICAgICAgRXhwcmVzc2lvbiBleCA9IG1hdGNoUGF0LmdldFN0ZXBQYXR0ZXJuKCk7Ci0KLSAgICAgIGlmIChleCBpbnN0YW5jZW9mIE5vZGVUZXN0KQotICAgICAgewotICAgICAgICByZXR1cm4gKChOb2RlVGVzdCkgZXgpLmdldERlZmF1bHRTY29yZSgpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBwcmlvcml0eTsKLSAgfQotCi0gIC8qKgotICAgKiBMb2NhdGUgYSBuYW1lZCB0ZW1wbGF0ZS4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lICBRdWFsaWZpZWQgbmFtZSBvZiB0aGUgdGVtcGxhdGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGVtcGxhdGUgYXJndW1lbnQgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUsIG9yIG51bGwgaWYgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZSBnZXRUZW1wbGF0ZShRTmFtZSBxbmFtZSkKLSAgewotICAgIHJldHVybiAoRWxlbVRlbXBsYXRlKSBtX25hbWVkVGVtcGxhdGVzLmdldChxbmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBoZWFkIG9mIHRoZSBtb3N0IGxpa2VseSBsaXN0IG9mIGFzc29jaWF0aW9ucyB0byBjaGVjaywgYmFzZWQgb24gCi0gICAqIHRoZSBuYW1lIGFuZCB0eXBlIG9mIHRoZSB0YXJnZXROb2RlIGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIHRhcmdldE5vZGUgVGhlIHRhcmdldCBub2RlIHRoYXQgd2lsbCBiZSBjaGVja2VkIGZvciBhIG1hdGNoLgotICAgKiBAcGFyYW0gZHRtIFRoZSBkdG0gb3duZXIgZm9yIHRoZSB0YXJnZXQgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgaGVhZCBvZiBhIGxpbmtlZCBsaXN0IHRoYXQgY29udGFpbnMgYWxsIHBvc3NpYmxlIG1hdGNoIHBhdHRlcm4gdG8gCi0gICAqIHRlbXBsYXRlIGFzc29jaWF0aW9ucy4KLSAgICovCi0gIHB1YmxpYyBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBnZXRIZWFkKFhQYXRoQ29udGV4dCB4Y3R4dCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0YXJnZXROb2RlLCBEVE0gZHRtKQotICB7Ci0gICAgc2hvcnQgdGFyZ2V0Tm9kZVR5cGUgPSBkdG0uZ2V0Tm9kZVR5cGUodGFyZ2V0Tm9kZSk7Ci0gICAgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gaGVhZDsKLQotICAgIHN3aXRjaCAodGFyZ2V0Tm9kZVR5cGUpCi0gICAgewotICAgIGNhc2UgRFRNLkVMRU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgaGVhZCA9IChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgbV9wYXR0ZXJuVGFibGUuZ2V0KAotICAgICAgICBkdG0uZ2V0TG9jYWxOYW1lKHRhcmdldE5vZGUpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgY2FzZSBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgIGhlYWQgPSBtX3RleHRQYXR0ZXJuczsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgY2FzZSBEVE0uRU5USVRZX05PREUgOgotICAgICAgaGVhZCA9IChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgbV9wYXR0ZXJuVGFibGUuZ2V0KAotICAgICAgICBkdG0uZ2V0Tm9kZU5hbWUodGFyZ2V0Tm9kZSkpOyAvLyAlUkVWSUVXJSBJIHRoaW5rIHRoaXMgaXMgcmlnaHQKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICBoZWFkID0gKFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uKSBtX3BhdHRlcm5UYWJsZS5nZXQoCi0gICAgICAgIGR0bS5nZXRMb2NhbE5hbWUodGFyZ2V0Tm9kZSkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFIDoKLSAgICAgIGhlYWQgPSBtX2NvbW1lbnRQYXR0ZXJuczsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREUgOgotICAgIGNhc2UgRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotICAgICAgaGVhZCA9IG1fZG9jUGF0dGVybnM7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5OT1RBVElPTl9OT0RFIDoKLSAgICBkZWZhdWx0IDoKLSAgICAgIGhlYWQgPSAoVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24pIG1fcGF0dGVyblRhYmxlLmdldCgKLSAgICAgICAgZHRtLmdldE5vZGVOYW1lKHRhcmdldE5vZGUpKTsgLy8gJVJFVklFVyUgSSB0aGluayB0aGlzIGlzIHJpZ2h0Ci0gICAgfQotCi0gICAgcmV0dXJuIChudWxsID09IGhlYWQpID8gbV93aWxkQ2FyZFBhdHRlcm5zIDogaGVhZDsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdpdmVuIGEgdGFyZ2V0IGVsZW1lbnQsIGZpbmQgdGhlIHRlbXBsYXRlIHRoYXQgYmVzdAotICAgKiBtYXRjaGVzIGluIHRoZSBnaXZlbiBYU0wgZG9jdW1lbnQsIGFjY29yZGluZwotICAgKiB0byB0aGUgcnVsZXMgc3BlY2lmaWVkIGluIHRoZSB4c2wgZHJhZnQuICBUaGlzIHZhcmlhdGlvbiBvZiBnZXRUZW1wbGF0ZSAKLSAgICogYXNzdW1lcyB0aGUgY3VycmVudCBub2RlIGFuZCBjdXJyZW50IGV4cHJlc3Npb24gbm9kZSBoYXZlIGFscmVhZHkgYmVlbiAKLSAgICogcHVzaGVkLiAKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0Ci0gICAqIEBwYXJhbSB0YXJnZXROb2RlCi0gICAqIEBwYXJhbSBtb2RlIEEgc3RyaW5nIGluZGljYXRpbmcgdGhlIGRpc3BsYXkgbW9kZS4KLSAgICogQHBhcmFtIG1heEltcG9ydExldmVsIFRoZSBtYXhpbXVtIGltcG9ydENvdW50Q29tcG9zZWQgdGhhdCB3ZSBzaG91bGQgY29uc2lkZXIgb3IgLTEKLSAgICogICAgICAgIGlmIHdlIHNob3VsZCBjb25zaWRlciBhbGwgaW1wb3J0IGxldmVscy4gIFRoaXMgaXMgdXNlZCBieSBhcHBseS1pbXBvcnRzIHRvCi0gICAqICAgICAgICBhY2Nlc3MgdGVtcGxhdGVzIHRoYXQgaGF2ZSBiZWVuIG92ZXJyaWRkZW4uCi0gICAqIEBwYXJhbSBxdWlldENvbmZsaWN0V2FybmluZ3MKLSAgICogQHJldHVybiBSdWxlIHRoYXQgYmVzdCBtYXRjaGVzIHRhcmdldEVsZW0uCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlIGdldFRlbXBsYXRlRmFzdChYUGF0aENvbnRleHQgeGN0eHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0YXJnZXROb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXhwVHlwZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRTmFtZSBtb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWF4SW1wb3J0TGV2ZWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcXVpZXRDb25mbGljdFdhcm5pbmdzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE0gZHRtKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAKLSAgICBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBoZWFkOwotCi0gICAgc3dpdGNoIChleHBUeXBlSUQgPj4gRXhwYW5kZWROYW1lVGFibGUuUk9UQU1PVU5UX1RZUEUpCi0gICAgewotICAgIGNhc2UgRFRNLkVMRU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgaGVhZCA9IChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgbV9wYXR0ZXJuVGFibGUuZ2V0KAotICAgICAgICBkdG0uZ2V0TG9jYWxOYW1lRnJvbUV4cGFuZGVkTmFtZUlEKGV4cFR5cGVJRCkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uVEVYVF9OT0RFIDoKLSAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgaGVhZCA9IG1fdGV4dFBhdHRlcm5zOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICBjYXNlIERUTS5FTlRJVFlfTk9ERSA6Ci0gICAgICBoZWFkID0gKFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uKSBtX3BhdHRlcm5UYWJsZS5nZXQoCi0gICAgICAgIGR0bS5nZXROb2RlTmFtZSh0YXJnZXROb2RlKSk7IC8vICVSRVZJRVclIEkgdGhpbmsgdGhpcyBpcyByaWdodAotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLSAgICAgIGhlYWQgPSAoVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24pIG1fcGF0dGVyblRhYmxlLmdldCgKLSAgICAgICAgZHRtLmdldExvY2FsTmFtZSh0YXJnZXROb2RlKSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5DT01NRU5UX05PREUgOgotICAgICAgaGVhZCA9IG1fY29tbWVudFBhdHRlcm5zOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICBoZWFkID0gbV9kb2NQYXR0ZXJuczsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLk5PVEFUSU9OX05PREUgOgotICAgIGRlZmF1bHQgOgotICAgICAgaGVhZCA9IChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgbV9wYXR0ZXJuVGFibGUuZ2V0KAotICAgICAgICBkdG0uZ2V0Tm9kZU5hbWUodGFyZ2V0Tm9kZSkpOyAvLyAlUkVWSUVXJSBJIHRoaW5rIHRoaXMgaXMgcmlnaHQKLSAgICB9Ci0KLSAgICBpZihudWxsID09IGhlYWQpCi0gICAgewotICAgICAgaGVhZCA9IG1fd2lsZENhcmRQYXR0ZXJuczsKLSAgICAgIGlmKG51bGwgPT0gaGVhZCkKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLQotICAgIC8vIFhTTFQgZnVuY3Rpb25zLCBzdWNoIGFzIHhzbDprZXksIG5lZWQgdG8gYmUgYWJsZSB0byBnZXQgdG8gCi0gICAgLy8gY3VycmVudCBFbGVtVGVtcGxhdGVFbGVtZW50IHZpYSBhIGNhc3QgdG8gdGhlIHByZWZpeCByZXNvbHZlci4KLSAgICAvLyBTZXR0aW5nIHRoaXMgZml4ZXMgYnVnIGlka2V5MDMuCi0gICAgeGN0eHQucHVzaE5hbWVzcGFjZUNvbnRleHROdWxsKCk7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgaWYgKCAobWF4SW1wb3J0TGV2ZWwgPiAtMSkgJiYgKGhlYWQuZ2V0SW1wb3J0TGV2ZWwoKSA+IG1heEltcG9ydExldmVsKSApCi0gICAgICAgIHsKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotICAgICAgICBFbGVtVGVtcGxhdGUgdGVtcGxhdGUgPSBoZWFkLmdldFRlbXBsYXRlKCk7ICAgICAgICAKLSAgICAgICAgeGN0eHQuc2V0TmFtZXNwYWNlQ29udGV4dCh0ZW1wbGF0ZSk7Ci0gICAgICAgIAotICAgICAgICBpZiAoKGhlYWQubV9zdGVwUGF0dGVybi5leGVjdXRlKHhjdHh0LCB0YXJnZXROb2RlLCBkdG0sIGV4cFR5cGVJRCkgIT0gTm9kZVRlc3QuU0NPUkVfTk9ORSkKLSAgICAgICAgICAgICAgICAmJiBoZWFkLm1hdGNoTW9kZShtb2RlKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChxdWlldENvbmZsaWN0V2FybmluZ3MpCi0gICAgICAgICAgICBjaGVja0NvbmZsaWN0cyhoZWFkLCB4Y3R4dCwgdGFyZ2V0Tm9kZSwgbW9kZSk7Ci0KLSAgICAgICAgICByZXR1cm4gdGVtcGxhdGU7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIHdoaWxlIChudWxsICE9IChoZWFkID0gaGVhZC5nZXROZXh0KCkpKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfSAgLy8gZW5kIGZpbmRUZW1wbGF0ZQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHRhcmdldCBlbGVtZW50LCBmaW5kIHRoZSB0ZW1wbGF0ZSB0aGF0IGJlc3QKLSAgICogbWF0Y2hlcyBpbiB0aGUgZ2l2ZW4gWFNMIGRvY3VtZW50LCBhY2NvcmRpbmcKLSAgICogdG8gdGhlIHJ1bGVzIHNwZWNpZmllZCBpbiB0aGUgeHNsIGRyYWZ0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQKLSAgICogQHBhcmFtIHRhcmdldE5vZGUKLSAgICogQHBhcmFtIG1vZGUgQSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgZGlzcGxheSBtb2RlLgotICAgKiBAcGFyYW0gbWF4SW1wb3J0TGV2ZWwgVGhlIG1heGltdW0gaW1wb3J0Q291bnRDb21wb3NlZCB0aGF0IHdlIHNob3VsZCBjb25zaWRlciBvciAtMQotICAgKiAgICAgICAgaWYgd2Ugc2hvdWxkIGNvbnNpZGVyIGFsbCBpbXBvcnQgbGV2ZWxzLiAgVGhpcyBpcyB1c2VkIGJ5IGFwcGx5LWltcG9ydHMgdG8KLSAgICogICAgICAgIGFjY2VzcyB0ZW1wbGF0ZXMgdGhhdCBoYXZlIGJlZW4gb3ZlcnJpZGRlbi4KLSAgICogQHBhcmFtIHF1aWV0Q29uZmxpY3RXYXJuaW5ncwotICAgKiBAcmV0dXJuIFJ1bGUgdGhhdCBiZXN0IG1hdGNoZXMgdGFyZ2V0RWxlbS4KLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGUgZ2V0VGVtcGxhdGUoWFBhdGhDb250ZXh0IHhjdHh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGFyZ2V0Tm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUU5hbWUgbW9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heEltcG9ydExldmVsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHF1aWV0Q29uZmxpY3RXYXJuaW5ncywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNIGR0bSkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBoZWFkID0gZ2V0SGVhZCh4Y3R4dCwgdGFyZ2V0Tm9kZSwgZHRtKTsKLQotICAgIGlmIChudWxsICE9IGhlYWQpCi0gICAgewotICAgICAgLy8gWFNMVCBmdW5jdGlvbnMsIHN1Y2ggYXMgeHNsOmtleSwgbmVlZCB0byBiZSBhYmxlIHRvIGdldCB0byAKLSAgICAgIC8vIGN1cnJlbnQgRWxlbVRlbXBsYXRlRWxlbWVudCB2aWEgYSBjYXN0IHRvIHRoZSBwcmVmaXggcmVzb2x2ZXIuCi0gICAgICAvLyBTZXR0aW5nIHRoaXMgZml4ZXMgYnVnIGlka2V5MDMuCi0gICAgICB4Y3R4dC5wdXNoTmFtZXNwYWNlQ29udGV4dE51bGwoKTsKLSAgICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZUFuZEV4cHJlc3Npb24odGFyZ2V0Tm9kZSwgdGFyZ2V0Tm9kZSk7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZG8KLSAgICAgICAgewotICAgICAgICAgIGlmICggKG1heEltcG9ydExldmVsID4gLTEpICYmIChoZWFkLmdldEltcG9ydExldmVsKCkgPiBtYXhJbXBvcnRMZXZlbCkgKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgIH0KLSAgICAgICAgICBFbGVtVGVtcGxhdGUgdGVtcGxhdGUgPSBoZWFkLmdldFRlbXBsYXRlKCk7ICAgICAgICAKLSAgICAgICAgICB4Y3R4dC5zZXROYW1lc3BhY2VDb250ZXh0KHRlbXBsYXRlKTsKLSAgICAgICAgICAKLSAgICAgICAgICBpZiAoKGhlYWQubV9zdGVwUGF0dGVybi5leGVjdXRlKHhjdHh0LCB0YXJnZXROb2RlKSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICAgICAgICAgICAgJiYgaGVhZC5tYXRjaE1vZGUobW9kZSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKHF1aWV0Q29uZmxpY3RXYXJuaW5ncykKLSAgICAgICAgICAgICAgY2hlY2tDb25mbGljdHMoaGVhZCwgeGN0eHQsIHRhcmdldE5vZGUsIG1vZGUpOwotCi0gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGU7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIHdoaWxlIChudWxsICE9IChoZWFkID0gaGVhZC5nZXROZXh0KCkpKTsKLSAgICAgIH0KLSAgICAgIGZpbmFsbHkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKCk7Ci0gICAgICAgIHhjdHh0LnBvcE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfSAgLy8gZW5kIGZpbmRUZW1wbGF0ZQotCi0gIC8qKgotICAgKiBHZXQgYSBUZW1wbGF0ZVdhbGtlciBmb3IgdXNlIGJ5IGEgY29tcGlsZXIuICBTZWUgdGhlIGRvY3VtZW50YXRpb24gZm9yCi0gICAqIHRoZSBUcmVlV2Fsa2VyIGlubmVyIGNsYXNzIGZvciBmdXJ0aGVyIGRldGFpbHMuCi0gICAqLwotICBwdWJsaWMgVGVtcGxhdGVXYWxrZXIgZ2V0V2Fsa2VyKCkKLSAgewotICAgIHJldHVybiBuZXcgVGVtcGxhdGVXYWxrZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayBmb3IgbWF0Y2ggY29uZmxpY3RzLCBhbmQgd2FybiB0aGUgc3R5bGVzaGVldCBhdXRob3IuCi0gICAqCi0gICAqIEBwYXJhbSBoZWFkIFRlbXBsYXRlIHBhdHRlcm4KLSAgICogQHBhcmFtIHhjdHh0IEN1cnJlbnQgWFBhdGggY29udGV4dAotICAgKiBAcGFyYW0gdGFyZ2V0Tm9kZSBOb2RlIG1hdGNoaW5nIHRoZSBwYXR0ZXJuCi0gICAqIEBwYXJhbSBtb2RlIHJlZmVyZW5jZSwgd2hpY2ggbWF5IGJlIG51bGwsIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I21vZGVzIj5jdXJyZW50IG1vZGU8L2E+LgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGNoZWNrQ29uZmxpY3RzKFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGhlYWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIGludCB0YXJnZXROb2RlLCBRTmFtZSBtb2RlKQotICB7Ci0KLSAgICAvLyBUT0RPOiBDaGVjayBmb3IgY29uZmxpY3RzLgotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBvYmplY3QgdG8gdmVjdG9yIGlmIG5vdCBhbHJlYWR5IHRoZXJlLgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqIEBwYXJhbSB2Ci0gICAqLwotICBwcml2YXRlIHZvaWQgYWRkT2JqZWN0SWZOb3RGb3VuZChPYmplY3Qgb2JqLCBWZWN0b3IgdikKLSAgewotCi0gICAgaW50IG4gPSB2LnNpemUoKTsKLSAgICBib29sZWFuIGFkZEl0ID0gdHJ1ZTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIGlmICh2LmVsZW1lbnRBdChpKSA9PSBvYmopCi0gICAgICB7Ci0gICAgICAgIGFkZEl0ID0gZmFsc2U7Ci0KLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKGFkZEl0KQotICAgIHsKLSAgICAgIHYuYWRkRWxlbWVudChvYmopOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBLZXllZCBvbiBzdHJpbmcgbWFjcm8gbmFtZXMsIGFuZCBob2xkaW5nIHZhbHVlcwotICAgKiB0aGF0IGFyZSBtYWNybyBlbGVtZW50cyBpbiB0aGUgWFNMIERPTSB0cmVlLgotICAgKiBJbml0aWFsaXplZCBpbiBpbml0TWFjcm9Mb29rdXBUYWJsZSwgYW5kIHVzZWQgaW4KLSAgICogZmluZE5hbWVkVGVtcGxhdGUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgSGFzaHRhYmxlIG1fbmFtZWRUZW1wbGF0ZXMgPSBuZXcgSGFzaHRhYmxlKDg5KTsKLQotICAvKioKLSAgICogVGhpcyB0YWJsZSBpcyBrZXllZCBvbiB0aGUgdGFyZ2V0IGVsZW1lbnRzCi0gICAqIG9mIHBhdHRlcm5zLCBhbmQgY29udGFpbnMgbGlua2VkIGxpc3RzIG9mCi0gICAqIHRoZSBhY3R1YWwgcGF0dGVybnMgdGhhdCBtYXRjaCB0aGUgdGFyZ2V0IGVsZW1lbnQKLSAgICogdG8gc29tZSBkZWdyZWUgb2Ygc3BlY2lmaXR5LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX3BhdHRlcm5UYWJsZSA9IG5ldyBIYXNodGFibGUoODkpOwotCi0gIC8qKiBXaWxkY2FyZCBwYXR0ZXJucy4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBtX3dpbGRDYXJkUGF0dGVybnMgPSBudWxsOwotCi0gIC8qKiBUZXh0IFBhdHRlcm5zLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIG1fdGV4dFBhdHRlcm5zID0gbnVsbDsKLQotICAvKiogUm9vdCBkb2N1bWVudCBQYXR0ZXJucy4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBtX2RvY1BhdHRlcm5zID0gbnVsbDsKLQotICAvKiogQ29tbWVudCBQYXR0ZXJucy4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbiBtX2NvbW1lbnRQYXR0ZXJucyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIEdldCB0YWJsZSBvZiBuYW1lZCBUZW1wbGF0ZXMuCi0gICAqIFRoZXNlIGFyZSBrZXllZCBvbiB0ZW1wbGF0ZSBuYW1lcywgYW5kIGhvbGRpbmcgdmFsdWVzCi0gICAqIHRoYXQgYXJlIHRlbXBsYXRlIGVsZW1lbnRzLgotICAgKgotICAgKiBAcmV0dXJuIEEgSGFzaHRhYmxlIGRpY3Rpb25hcnkgdGhhdCBjb250YWlucyB7QGxpbmsgamF2YS5sYW5nLlN0cmluZ31zIAotICAgKiBhcyB0aGUga2V5cywgYW5kIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGV9cyBhcyB0aGUgCi0gICAqIHZhbHVlcy4gCi0gICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBnZXROYW1lZFRlbXBsYXRlcygpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lZFRlbXBsYXRlczsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGFibGUgb2YgbmFtZWQgVGVtcGxhdGVzLgotICAgKiBUaGVzZSBhcmUga2V5ZWQgb24gc3RyaW5nIG1hY3JvIG5hbWVzLCBhbmQgaG9sZGluZyB2YWx1ZXMKLSAgICogdGhhdCBhcmUgdGVtcGxhdGUgZWxlbWVudHMgaW4gdGhlIFhTTCBET00gdHJlZS4KLSAgICoKLSAgICogQHBhcmFtIHYgSGFzaHRhYmxlIGRpY3Rpb25hcnkgdGhhdCBjb250YWlucyB7QGxpbmsgamF2YS5sYW5nLlN0cmluZ31zIAotICAgKiBhcyB0aGUga2V5cywgYW5kIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGV9cyBhcyB0aGUgCi0gICAqIHZhbHVlcy4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBzZXROYW1lZFRlbXBsYXRlcyhIYXNodGFibGUgdikKLSAgewotICAgIG1fbmFtZWRUZW1wbGF0ZXMgPSB2OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgaGVhZCBvZiB0aGUgYXNzb2NhdGlvbiBsaXN0IHRoYXQgaXMga2V5ZWQgYnkgdGFyZ2V0LgotICAgKgotICAgKiBAcGFyYW0ga2V5IFRoZSBuYW1lIG9mIGEgbm9kZS4gCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGhlYWQgb2YgYSBsaW5rZWQgbGlzdCB0aGF0IGNvbnRhaW5zIGFsbCBwb3NzaWJsZSBtYXRjaCBwYXR0ZXJuIHRvIAotICAgKiB0ZW1wbGF0ZSBhc3NvY2lhdGlvbnMgZm9yIHRoZSBnaXZlbiBrZXkuCi0gICAqLwotICBwcml2YXRlIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGdldEhlYWQoU3RyaW5nIGtleSkKLSAgewotICAgIHJldHVybiAoVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24pIG1fcGF0dGVyblRhYmxlLmdldChrZXkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgaGVhZCBvZiB0aGUgYXNzb2NhdGlvbiBsaXN0IHRoYXQgaXMga2V5ZWQgYnkgdGFyZ2V0LgotICAgKgotICAgKiBAcGFyYW0ga2V5Ci0gICAqIEBwYXJhbSBhc3NvYwotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHB1dEhlYWQoU3RyaW5nIGtleSwgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gYXNzb2MpCi0gIHsKLQotICAgIGlmIChrZXkuZXF1YWxzKFBzdWVkb05hbWVzLlBTRVVET05BTUVfVEVYVCkpCi0gICAgICBtX3RleHRQYXR0ZXJucyA9IGFzc29jOwotICAgIGVsc2UgaWYgKGtleS5lcXVhbHMoUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9ST09UKSkKLSAgICAgIG1fZG9jUGF0dGVybnMgPSBhc3NvYzsKLSAgICBlbHNlIGlmIChrZXkuZXF1YWxzKFBzdWVkb05hbWVzLlBTRVVET05BTUVfQ09NTUVOVCkpCi0gICAgICBtX2NvbW1lbnRQYXR0ZXJucyA9IGFzc29jOwotCi0gICAgbV9wYXR0ZXJuVGFibGUucHV0KGtleSwgYXNzb2MpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFuIGlubmVyIGNsYXNzIHVzZWQgYnkgYSBjb21waWxlciB0byBpdGVyYXRlIG92ZXIgYWxsIG9mIHRoZSBFbGVtVGVtcGxhdGVzCi0gICAqIHN0b3JlZCBpbiB0aGlzIFRlbXBsYXRlTGlzdC4gIFRoZSBjb21waWxlciBjYW4gcmVwbGFjZSByZXR1cm5lZCB0ZW1wbGF0ZXMKLSAgICogd2l0aCB0aGVpciBjb21waWxlZCBlcXVpdmFsZW50LgotICAgKi8KLSAgcHVibGljIGNsYXNzIFRlbXBsYXRlV2Fsa2VyCi0gIHsKLSAgICBwcml2YXRlIEVudW1lcmF0aW9uIGhhc2hJdGVyYXRvcjsKLSAgICBwcml2YXRlIGJvb2xlYW4gaW5QYXR0ZXJuczsKLSAgICBwcml2YXRlIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGN1clBhdHRlcm47Ci0KLSAgICBwcml2YXRlIEhhc2h0YWJsZSBtX2NvbXBpbGVyQ2FjaGUgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICBwcml2YXRlIFRlbXBsYXRlV2Fsa2VyKCkKLSAgICB7Ci0gICAgICBoYXNoSXRlcmF0b3IgPSBtX3BhdHRlcm5UYWJsZS5lbGVtZW50cygpOwotICAgICAgaW5QYXR0ZXJucyA9IHRydWU7Ci0gICAgICBjdXJQYXR0ZXJuID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRWxlbVRlbXBsYXRlIG5leHQoKQotICAgIHsKLQotICAgICAgRWxlbVRlbXBsYXRlIHJldFZhbHVlID0gbnVsbDsKLSAgICAgIEVsZW1UZW1wbGF0ZSBjdDsKLQotICAgICAgd2hpbGUgKHRydWUpCi0gICAgICB7Ci0gICAgICAgIGlmIChpblBhdHRlcm5zKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gY3VyUGF0dGVybikKLSAgICAgICAgICAgIGN1clBhdHRlcm4gPSBjdXJQYXR0ZXJuLmdldE5leHQoKTsKLQotICAgICAgICAgIGlmIChudWxsICE9IGN1clBhdHRlcm4pCi0gICAgICAgICAgICByZXRWYWx1ZSA9IGN1clBhdHRlcm4uZ2V0VGVtcGxhdGUoKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGhhc2hJdGVyYXRvci5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgY3VyUGF0dGVybiA9IChUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbikgaGFzaEl0ZXJhdG9yLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgIHJldFZhbHVlID0gIGN1clBhdHRlcm4uZ2V0VGVtcGxhdGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaW5QYXR0ZXJucyA9IGZhbHNlOwotICAgICAgICAgICAgICBoYXNoSXRlcmF0b3IgPSBtX25hbWVkVGVtcGxhdGVzLmVsZW1lbnRzKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKCFpblBhdHRlcm5zKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGhhc2hJdGVyYXRvci5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICAgICAgICAgIHJldFZhbHVlID0gKEVsZW1UZW1wbGF0ZSkgaGFzaEl0ZXJhdG9yLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICBjdCA9IChFbGVtVGVtcGxhdGUpIG1fY29tcGlsZXJDYWNoZS5nZXQobmV3IEludGVnZXIocmV0VmFsdWUuZ2V0VWlkKCkpKTsKLSAgICAgICAgaWYgKG51bGwgPT0gY3QpCi0gICAgICAgIHsKLSAgICAgICAgICBtX2NvbXBpbGVyQ2FjaGUucHV0KG5ldyBJbnRlZ2VyKHJldFZhbHVlLmdldFVpZCgpKSwgcmV0VmFsdWUpOwotICAgICAgICAgIHJldHVybiByZXRWYWx1ZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9UZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZDU1MTc1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9UZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjg2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLlN0ZXBQYXR0ZXJuOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotCi0vKioKLSAqIEEgY2xhc3MgdG8gY29udGFpbiBhIG1hdGNoIHBhdHRlcm4gYW5kIGl0J3MgY29ycmVzcG9uZGluZyB0ZW1wbGF0ZS4KLSAqIFRoaXMgY2xhc3MgYWxzbyBkZWZpbmVzIGEgbm9kZSBpbiBhIG1hdGNoIHBhdHRlcm4gbGlua2VkIGxpc3QuCi0gKi8KLWNsYXNzIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUKLXsKLQotICAvKiogU3RlcCBwYXR0ZXJuICAgICAgICAgICAqLwotICBTdGVwUGF0dGVybiBtX3N0ZXBQYXR0ZXJuOwotCi0gIC8qKiBUZW1wbGF0ZSBwYXR0ZXJuICAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcGF0dGVybjsKLQotICAvKiogVGhlIHRlbXBsYXRlIGVsZW1lbnQgICAgICAgICAqLwotICBwcml2YXRlIEVsZW1UZW1wbGF0ZSBtX3RlbXBsYXRlOwotCi0gIC8qKiBOZXh0IHBhdHRlcm4gICAgICAgICAqLwotICBwcml2YXRlIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIG1fbmV4dCA9IG51bGw7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgaXMgd2lsZCBjYXJkIHBhdHRlcm4gICAgICAgICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fd2lsZDsKLQotICAvKiogVGFyZ2V0IHN0cmluZyBmb3IgdGhpcyBtYXRjaCBwYXR0ZXJuICAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZyBtX3RhcmdldFN0cmluZzsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbWF0Y2ggcGF0dGVybiBmcm9tIGEgcGF0dGVybiBhbmQgdGVtcGxhdGUuCi0gICAqIEBwYXJhbSB0ZW1wbGF0ZSBUaGUgbm9kZSB0aGF0IGNvbnRhaW5zIHRoZSB0ZW1wbGF0ZSBmb3IgdGhpcyBwYXR0ZXJuLgotICAgKiBAcGFyYW0gcGF0dGVybiBBbiBleGVjdXRhYmxlIFhTTFQgU3RlcFBhdHRlcm4uCi0gICAqIEBwYXJhbSBwYXQgRm9yIG5vdyBhIE5vZGVsaXN0IHRoYXQgY29udGFpbnMgb2xkLXN0eWxlIGVsZW1lbnQgcGF0dGVybnMuCi0gICAqLwotICBUZW1wbGF0ZVN1YlBhdHRlcm5Bc3NvY2lhdGlvbihFbGVtVGVtcGxhdGUgdGVtcGxhdGUsIFN0ZXBQYXR0ZXJuIHBhdHRlcm4sIFN0cmluZyBwYXQpCi0gIHsKLQotICAgIG1fcGF0dGVybiA9IHBhdDsKLSAgICBtX3RlbXBsYXRlID0gdGVtcGxhdGU7Ci0gICAgbV9zdGVwUGF0dGVybiA9IHBhdHRlcm47Ci0gICAgbV90YXJnZXRTdHJpbmcgPSBtX3N0ZXBQYXR0ZXJuLmdldFRhcmdldFN0cmluZygpOwotICAgIG1fd2lsZCA9IG1fdGFyZ2V0U3RyaW5nLmVxdWFscygiKiIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENsb25lIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjbG9uZWQgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIHRzcGEgPQotICAgICAgKFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uKSBzdXBlci5jbG9uZSgpOwotCi0gICAgdHNwYS5tX25leHQgPSBudWxsOwotCi0gICAgcmV0dXJuIHRzcGE7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB0YXJnZXQgc3RyaW5nIG9mIHRoZSBwYXR0ZXJuLiAgRm9yIGluc3RhbmNlLCBpZiB0aGUgcGF0dGVybiBpcwotICAgKiAiZm9vL2Jhei9ib29bQGRhYmFdIiwgdGhpcyBzdHJpbmcgd2lsbCBiZSAiYm9vIi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgInRhcmdldCIgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRUYXJnZXRTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fdGFyZ2V0U3RyaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBUYXJnZXQgU3RyaW5nIGZvciB0aGlzIHRlbXBsYXRlIHBhdHRlcm4gIAotICAgKgotICAgKgotICAgKiBAcGFyYW0ga2V5IFRhcmdldCBzdHJpbmcgdG8gc2V0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRUYXJnZXRTdHJpbmcoU3RyaW5nIGtleSkKLSAgewotICAgIG1fdGFyZ2V0U3RyaW5nID0ga2V5OwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG1vZGVzIG1hdGNoIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgWFNMVC4KLSAgICoKLSAgICogQHBhcmFtIG0xIG1vZGUgdG8gbWF0Y2gKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiBtb2RlIG1hdGNoZXMgdGhpcyB0ZW1wbGF0ZSdzIG1vZGUKLSAgICovCi0gIGJvb2xlYW4gbWF0Y2hNb2RlKFFOYW1lIG0xKQotICB7Ci0gICAgcmV0dXJuIG1hdGNoTW9kZXMobTEsIG1fdGVtcGxhdGUuZ2V0TW9kZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBtb2RlcyBtYXRjaCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIG9mIFhTTFQuCi0gICAqCi0gICAqIEBwYXJhbSBtMSBGaXJzdCBtb2RlIHRvIG1hdGNoCi0gICAqIEBwYXJhbSBtMiBTZWNvbmQgbW9kZSB0byBtYXRjaAotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHR3byBnaXZlbiBtb2RlcyBtYXRjaAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1hdGNoTW9kZXMoUU5hbWUgbTEsIFFOYW1lIG0yKQotICB7Ci0gICAgcmV0dXJuICgoKG51bGwgPT0gbTEpICYmIChudWxsID09IG0yKSkKLSAgICAgICAgICAgIHx8ICgobnVsbCAhPSBtMSkgJiYgKG51bGwgIT0gbTIpICYmIG0xLmVxdWFscyhtMikpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG1vZGUgYXNzb2NpYXRlZCB3aXRoIHRoZSB0ZW1wbGF0ZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIGNvbnRleHQgdG8gdXNlIHdpdGggdGhpcyB0ZW1wbGF0ZQotICAgKiBAcGFyYW0gdGFyZ2V0Tm9kZSBUYXJnZXQgbm9kZQotICAgKiBAcGFyYW0gbW9kZSByZWZlcmVuY2UsIHdoaWNoIG1heSBiZSBudWxsLCB0byB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNtb2RlcyI+Y3VycmVudCBtb2RlPC9hPi4KLSAgICogQHJldHVybiBUaGUgbW9kZSBhc3NvY2lhdGVkIHdpdGggdGhlIHRlbXBsYXRlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IHRhcmdldE5vZGUsIFFOYW1lIG1vZGUpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGRvdWJsZSBzY29yZSA9IG1fc3RlcFBhdHRlcm4uZ2V0TWF0Y2hTY29yZSh4Y3R4dCwgdGFyZ2V0Tm9kZSk7Ci0KLSAgICByZXR1cm4gKFhQYXRoLk1BVENIX1NDT1JFX05PTkUgIT0gc2NvcmUpCi0gICAgICAgICAgICYmIG1hdGNoTW9kZXMobW9kZSwgbV90ZW1wbGF0ZS5nZXRNb2RlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHBhdHRlcm4gZm9yIHRoaXMgYXNzb2NpYXRpb24gaXMgYSB3aWxkY2FyZC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgcGF0dGVybiBpcyBjb25zaWRlcmVkIHRvIGJlIGEgd2lsZCBtYXRjaC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzV2lsZCgpCi0gIHsKLSAgICByZXR1cm4gbV93aWxkOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhc3NvY2lhdGVkIFhTTFQgU3RlcFBhdHRlcm4uCi0gICAqCi0gICAqIEByZXR1cm4gQW4gZXhlY3V0YWJsZSBTdGVwUGF0dGVybiBvYmplY3QsIG5ldmVyIG51bGwuCi0gICAqCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RlcFBhdHRlcm4gZ2V0U3RlcFBhdHRlcm4oKQotICB7Ci0gICAgcmV0dXJuIG1fc3RlcFBhdHRlcm47Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwYXR0ZXJuIHN0cmluZyBmb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcGF0dGVybiBzdHJpbmcgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFBhdHRlcm4oKQotICB7Ci0gICAgcmV0dXJuIG1fcGF0dGVybjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSB0ZW1wbGF0ZSBpbiBkb2N1bWVudAotICAgKiBvcmRlciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIHRlbXBsYXRlIGluIHRoZSBvdmVyYWxsIHRlbXBsYXRlIG9yZGVyLgotICAgKi8KLSAgcHVibGljIGludCBnZXREb2NPcmRlclBvcygpCi0gIHsKLSAgICByZXR1cm4gbV90ZW1wbGF0ZS5nZXRVaWQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGltcG9ydCBsZXZlbCBhc3NvY2lhdGVkIHdpdGggdGhlIHN0eWxlc2hlZXQgaW50byB3aGljaCAgCi0gICAqIHRoaXMgdGVtcGxhdGUgaXMgY29tcG9zZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGltcG9ydCBsZXZlbCBvZiB0aGlzIHRlbXBsYXRlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJbXBvcnRMZXZlbCgpCi0gIHsKLSAgICByZXR1cm4gbV90ZW1wbGF0ZS5nZXRTdHlsZXNoZWV0Q29tcG9zZWQoKS5nZXRJbXBvcnRDb3VudENvbXBvc2VkKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2F0ZWQgeHNsOnRlbXBsYXRlLgotICAgKgotICAgKiBAcmV0dXJuIEFuIEVsZW1UZW1wbGF0ZSwgbmV2ZXIgbnVsbC4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBFbGVtVGVtcGxhdGUgZ2V0VGVtcGxhdGUoKQotICB7Ci0gICAgcmV0dXJuIG1fdGVtcGxhdGU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IGFzc29jaWF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIEEgdmFsaWQgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24sIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgZmluYWwgVGVtcGxhdGVTdWJQYXR0ZXJuQXNzb2NpYXRpb24gZ2V0TmV4dCgpCi0gIHsKLSAgICByZXR1cm4gbV9uZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbmV4dCBlbGVtZW50IG9uIHRoaXMgYXNzb2NpYXRpb24KLSAgICogbGlzdCwgd2hpY2ggc2hvdWxkIGJlIGVxdWFsIG9yIGxlc3MgaW4gcHJpb3JpdHkgdG8KLSAgICogdGhpcyBhc3NvY2lhdGlvbiwgYW5kLCBpZiBlcXVhbCBwcmlvcml0eSwgc2hvdWxkIG9jY3VyCi0gICAqIGJlZm9yZSB0aGlzIHRlbXBsYXRlIGluIGRvY3VtZW50IG9yZGVyLgotICAgKgotICAgKiBAcGFyYW0gbXAgVGhlIG5leHQgYXNzb2NpYXRpb24gdG8gc2NvcmUgaWYgdGhpcyBvbmUgZmFpbHMuCi0gICAqCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROZXh0KFRlbXBsYXRlU3ViUGF0dGVybkFzc29jaWF0aW9uIG1wKQotICB7Ci0gICAgbV9uZXh0ID0gbXA7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9XaGl0ZVNwYWNlSW5mby5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1doaXRlU3BhY2VJbmZvLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDczMmY0NjcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1doaXRlU3BhY2VJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotCi0vKioKLSAqIFRoaXMgaXMgdXNlZCBhcyBhIHNwZWNpYWwgImZha2UiIHRlbXBsYXRlIHRoYXQgY2FuIGJlCi0gKiBoYW5kbGVkIGJ5IHRoZSBUZW1wbGF0ZUxpc3QgdG8gZG8gcGF0dGVybiBtYXRjaGluZwotICogb24gbm9kZXMuCi0gKi8KLXB1YmxpYyBjbGFzcyBXaGl0ZVNwYWNlSW5mbyBleHRlbmRzIEVsZW1UZW1wbGF0ZQotewotCi0gIC8qKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciB3aGl0ZXNwYWNlcyBzaG91bGQgYmUgc3RyaXBwZWQuCi0gICAqICBAc2VyaWFsICAgICAgICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9zaG91bGRTdHJpcFNwYWNlOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGVsZW1lbnQgc3BlY2lmaWVzIHRoYXQgdGhlIG5vZGUgdGhhdAotICAgKiBtYXRjaGVzIHRoZSBtYXRjaCBwYXR0ZXJuIHNob3VsZCBiZSBzdHJpcHBlZCwgb3RoZXJ3aXNlCi0gICAqIHRoZSBzcGFjZSBzaG91bGQgYmUgcHJlc2VydmVkLgotICAgKgotICAgKiBAcmV0dXJuIHZhbHVlIG9mIG1fc2hvdWxkU3RyaXBTcGFjZSBmbGFnCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTaG91bGRTdHJpcFNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX3Nob3VsZFN0cmlwU3BhY2U7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgV2hpdGVTcGFjZUluZm8KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG1hdGNoUGF0dGVybiBNYXRjaCBwYXR0ZXJuCi0gICAqIEBwYXJhbSBzaG91bGRTdHJpcFNwYWNlIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdAotICAgKiB0byBzdHJpcCB3aGl0ZXNwYWNlcwotICAgKiBAcGFyYW0gdGhpc1NoZWV0IFRoZSBjdXJyZW50IHN0eWxlc2hlZXQKLSAgICovCi0gIHB1YmxpYyBXaGl0ZVNwYWNlSW5mbyhYUGF0aCBtYXRjaFBhdHRlcm4sIGJvb2xlYW4gc2hvdWxkU3RyaXBTcGFjZSwgU3R5bGVzaGVldCB0aGlzU2hlZXQpCi0gIHsKLQotICAgIG1fc2hvdWxkU3RyaXBTcGFjZSA9IHNob3VsZFN0cmlwU3BhY2U7Ci0KLSAgICBzZXRNYXRjaChtYXRjaFBhdHRlcm4pOwotCi0gICAgc2V0U3R5bGVzaGVldCh0aGlzU2hlZXQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIHJlY29tcG9zZSgpIGFsbCBvZiB0aGUgV2hpdGVTcGFjZUluZm8gZWxlbWVudHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZWNvbXBvc2UoU3R5bGVzaGVldFJvb3Qgcm9vdCkKLSAgewotICAgIHJvb3QucmVjb21wb3NlV2hpdGVTcGFjZUluZm8odGhpcyk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1hNTE5TRGVjbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1hNTE5TRGVjbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZTIwNTcwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9YTUxOU0RlY2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczsKLQotLyoqCi0gKiBSZXByZXNlbnRzIGFuIHhtbG5zIGRlY2xhcmF0aW9uCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxOU0RlY2wKLSAgICAgICAgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSAvLyAyMDAwMTAwOSBqa2VzcwotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBYTUxOU0RlY2wKLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBub24tbnVsbCByZWZlcmVuY2UgdG8gcHJlZml4LCB1c2luZyAiIiBmb3IgZGVmYXVsdCBuYW1lc3BhY2UuCi0gICAqIEBwYXJhbSB1cmkgbm9uLW51bGwgcmVmZXJlbmNlIHRvIG5hbWVzcGFjZSBVUkkuCi0gICAqIEBwYXJhbSBpc0V4Y2x1ZGVkIHRydWUgaWYgdGhpcyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gc2hvdWxkIG5vcm1hbGx5IGJlIGV4Y2x1ZGVkLgotICAgKi8KLSAgcHVibGljIFhNTE5TRGVjbChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpLCBib29sZWFuIGlzRXhjbHVkZWQpCi0gIHsKLQotICAgIG1fcHJlZml4ID0gcHJlZml4OwotICAgIG1fdXJpID0gdXJpOwotICAgIG1faXNFeGNsdWRlZCA9IGlzRXhjbHVkZWQ7Ci0gIH0KLQotICAvKiogbm9uLW51bGwgcmVmZXJlbmNlIHRvIHByZWZpeCwgdXNpbmcgIiIgZm9yIGRlZmF1bHQgbmFtZXNwYWNlLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIFN0cmluZyBtX3ByZWZpeDsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBwcmVmaXguCi0gICAqIEByZXR1cm4gVGhlIHByZWZpeCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFVSSSwgb3IgbnVsbAotICAgKiBpZiB0aGUgWE1MTlNEZWNsIGlzIGRlY2xhcmluZyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpCi0gIHsKLSAgICByZXR1cm4gbV9wcmVmaXg7Ci0gIH0KLQotICAvKiogbm9uLW51bGwgcmVmZXJlbmNlIHRvIG5hbWVzcGFjZSBVUkkuCi0gICAqICBAc2VyaWFsICAqLwotICBwcml2YXRlIFN0cmluZyBtX3VyaTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBVUkkuCi0gICAqIEByZXR1cm4gVGhlIFVSSSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRlY2xhcmF0aW9uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVUkkoKQotICB7Ci0gICAgcmV0dXJuIG1fdXJpOwotICB9Ci0KLSAgLyoqIHRydWUgaWYgdGhpcyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gc2hvdWxkIG5vcm1hbGx5IGJlIGV4Y2x1ZGVkLgotICAgKiAgQHNlcmlhbCAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1faXNFeGNsdWRlZDsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGRlY2xhcmF0aW9uIHNob3VsZCBiZSBleGNsdWRlZCBmcm9tIHRoZQotICAgKiByZXN1bHQgbmFtZXNwYWNlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gc2hvdWxkIG5vcm1hbGx5IGJlIGV4Y2x1ZGVkLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0SXNFeGNsdWRlZCgpCi0gIHsKLSAgICByZXR1cm4gbV9pc0V4Y2x1ZGVkOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvWFVucmVzb2x2ZWRWYXJpYWJsZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL1hVbnJlc29sdmVkVmFyaWFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDZjMmY4ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvWFVucmVzb2x2ZWRWYXJpYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlZhcmlhYmxlU3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhSVHJlZUZyYWc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi0vKioKLSAqIEFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaG9sZHMgdW50byBhIHZhcmlhYmxlIHVudGlsIAotICogaXQgaXMgZXhlY3V0ZWQuICBJdCBpcyB1c2VkIGF0IHRoaXMgdGltZSBmb3IgZ2xvYmFsIAotICogdmFyaWFibGVzIHdoaWNoIG11c3QgKHdlIHRoaW5rKSBmb3J3YXJkIHJlZmVyZW5jZS4KLSAqLwotcHVibGljIGNsYXNzIFhVbnJlc29sdmVkVmFyaWFibGUgZXh0ZW5kcyBYT2JqZWN0Ci17ICAKLSAgLyoqIFRoZSBub2RlIGNvbnRleHQgZm9yIGV4ZWN1dGlvbi4gKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgaW50IG1fY29udGV4dDsKLSAgCi0gIC8qKiBUaGUgdHJhbnNmb3JtZXIgY29udGV4dCBmb3IgZXhlY3V0aW9uLiAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBUcmFuc2Zvcm1lckltcGwgbV90cmFuc2Zvcm1lcjsKLSAgCi0gIC8qKiBBbiBpbmRleCB0byB0aGUgcG9pbnQgaW4gdGhlIHZhcmlhYmxlIHN0YWNrIHdoZXJlIHdlIHNob3VsZAotICAgKiBiZWdpbiB2YXJpYWJsZSBzZWFyY2hlcyBmb3IgZXZhbHVhdGlvbiBvZiBleHByZXNzaW9ucy4KLSAgICogVGhpcyBpcyAtMSBpZiBtX2lzVG9wTGV2ZWwgaXMgZmFsc2UuIAotICAgKiovCi0gIHRyYW5zaWVudCBwcml2YXRlIGludCBtX3ZhclN0YWNrUG9zID0gLTE7Ci0KLSAgLyoqIEFuIGluZGV4IGludG8gdGhlIHZhcmlhYmxlIHN0YWNrIHdoZXJlIHRoZSB2YXJpYWJsZSBjb250ZXh0IAotICAgKiBlbmRzLCBpLmUuIGF0IHRoZSBwb2ludCB3ZSBzaG91bGQgdGVybWluYXRlIHRoZSBzZWFyY2guIAotICAgKiovCi0gIHRyYW5zaWVudCBwcml2YXRlIGludCBtX3ZhclN0YWNrQ29udGV4dDsKLSAgCi0gIC8qKiB0cnVlIGlmIHRoaXMgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGlzIGEgZ2xvYmFsLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9pc0dsb2JhbDsKLSAgCi0gIC8qKiB0cnVlIGlmIHRoaXMgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGlzIG5vdCBjdXJyZW50bHkgYmVpbmcgZXZhbHVhdGVkLiAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBib29sZWFuIG1fZG9uZUV2YWwgPSB0cnVlOwotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYVW5yZXNvbHZlZFZhcmlhYmxlLCB0aGF0IG1heSBiZSBleGVjdXRlZCBhdCBhIGxhdGVyIHRpbWUuCi0gICAqIFRoaXMgaXMgcHJpbWFyaWx5IHVzZWQgc28gdGhhdCBmb3J3YXJkIHJlZmVyZW5jaW5nIHdvcmtzIHdpdGggCi0gICAqIGdsb2JhbCB2YXJpYWJsZXMuICBBbiBYVW5yZXNvbHZlZFZhcmlhYmxlIGlzIGluaXRpYWxseSBwdXNoZWQgCi0gICAqIGludG8gdGhlIGdsb2JhbCB2YXJpYWJsZSBzdGFjaywgYW5kIHRoZW4gcmVwbGFjZWQgd2l0aCB0aGUgcmVhbCAKLSAgICogdGhpbmcgd2hlbiBpdCBpcyBhY2Nlc3NlZC4KLSAgICoKLSAgICogQHBhcmFtIG9iaiBNdXN0IGJlIGEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGFuIEVsZW1WYXJpYWJsZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgVGhlIG5vZGUgY29udGV4dCBmb3IgZXhlY3V0aW9uLgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgVGhlIHRyYW5zZm9ybWVyIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcGFyYW0gdmFyU3RhY2tQb3MgQW4gaW5kZXggdG8gdGhlIHBvaW50IGluIHRoZSB2YXJpYWJsZSBzdGFjayB3aGVyZSB3ZSBzaG91bGQKLSAgICogYmVnaW4gdmFyaWFibGUgc2VhcmNoZXMgZm9yIGV2YWx1YXRpb24gb2YgZXhwcmVzc2lvbnMuCi0gICAqIEBwYXJhbSB2YXJTdGFja0NvbnRleHQgQW4gaW5kZXggaW50byB0aGUgdmFyaWFibGUgc3RhY2sgd2hlcmUgdGhlIHZhcmlhYmxlIGNvbnRleHQgCi0gICAqIGVuZHMsIGkuZS4gYXQgdGhlIHBvaW50IHdlIHNob3VsZCB0ZXJtaW5hdGUgdGhlIHNlYXJjaC4KLSAgICogQHBhcmFtIGlzR2xvYmFsIHRydWUgaWYgdGhpcyBpcyBhIGdsb2JhbCB2YXJpYWJsZS4KLSAgICovCi0gIHB1YmxpYyBYVW5yZXNvbHZlZFZhcmlhYmxlKEVsZW1WYXJpYWJsZSBvYmosIGludCBzb3VyY2VOb2RlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmFyU3RhY2tQb3MsIGludCB2YXJTdGFja0NvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNHbG9iYWwpCi0gIHsKLSAgICBzdXBlcihvYmopOwotICAgIG1fY29udGV4dCA9IHNvdXJjZU5vZGU7Ci0gICAgbV90cmFuc2Zvcm1lciA9IHRyYW5zZm9ybWVyOwotICAgIAotICAgIC8vIEZvciBnbG9iYWxzLCB0aGlzIHZhbHVlIHdpbGwgaGF2ZSB0byBiZSB1cGRhdGVkIG9uY2Ugd2UgCi0gICAgLy8gaGF2ZSBkZXRlcm1pbmVkIGhvdyBtYW55IGdsb2JhbCB2YXJpYWJsZXMgaGF2ZSBiZWVuIHB1c2hlZC4KLSAgICBtX3ZhclN0YWNrUG9zID0gdmFyU3RhY2tQb3M7Ci0gICAgCi0gICAgLy8gRm9yIGdsb2JhbHMsIHRoaXMgc2hvdWxkIHplcm8uCi0gICAgbV92YXJTdGFja0NvbnRleHQgPSB2YXJTdGFja0NvbnRleHQ7Ci0gICAgCi0gICAgbV9pc0dsb2JhbCA9IGlzR2xvYmFsOwotICB9Ci0gICAgCi0gIC8qKgotICAgKiBGb3Igc3VwcG9ydCBvZiBsaXRlcmFsIG9iamVjdHMgaW4geHBhdGhzLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKCFtX2RvbmVFdmFsKSAKLSAgICB7Ci0gICAgICB0aGlzLm1fdHJhbnNmb3JtZXIuZ2V0TXNnTWdyKCkuZXJyb3IgICAgICAKLSAgICAgICAgKHhjdHh0LmdldFNBWExvY2F0b3IoKSwgWFNMVEVycm9yUmVzb3VyY2VzLkVSX1JFRkVSRU5DSU5HX0lUU0VMRiwgCi0gICAgICAgICAgbmV3IE9iamVjdFtdeygoRWxlbVZhcmlhYmxlKXRoaXMub2JqZWN0KCkpLmdldE5hbWUoKS5nZXRMb2NhbE5hbWUoKX0pOyAKLSAgICB9Ci0gICAgVmFyaWFibGVTdGFjayB2YXJzID0geGN0eHQuZ2V0VmFyU3RhY2soKTsKLSAgICAKLSAgICAvLyBUaGVzZSB0aHJlZSBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgIGludCBjdXJyZW50RnJhbWUgPSB2YXJzLmdldFN0YWNrRnJhbWUoKTsKLSAgICB2YXJzLnNldFN0YWNrRnJhbWUobV92YXJTdGFja1Bvcyk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBtX2RvbmVFdmFsID0gZmFsc2U7Ci0gICAgICBFbGVtVmFyaWFibGUgdmVsZW0gPSAoRWxlbVZhcmlhYmxlKW1fb2JqOwotICAgICAgWE9iamVjdCB2YXIgPSB2ZWxlbS5nZXRWYWx1ZShtX3RyYW5zZm9ybWVyLCBtX2NvbnRleHQpOwotICAgICAgbV9kb25lRXZhbCA9IHRydWU7Ci0gICAgICByZXR1cm4gdmFyOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgLy8gVGhlc2UgdHdvIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICB2YXJzLnNldFN0YWNrRnJhbWUoY3VycmVudEZyYW1lKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgYW4gaW5kZXggdG8gdGhlIHBvaW50IGluIHRoZSB2YXJpYWJsZSBzdGFjayB3aGVyZSB3ZSBzaG91bGQKLSAgICogYmVnaW4gdmFyaWFibGUgc2VhcmNoZXMgZm9yIGV2YWx1YXRpb24gb2YgZXhwcmVzc2lvbnMuCi0gICAqIFRoaXMgaXMgLTEgaWYgbV9pc1RvcExldmVsIGlzIGZhbHNlLiAKLSAgICogCi0gICAqIEBwYXJhbSB0b3AgQSB2YWxpZCB2YWx1ZSB0aGF0IHNwZWNpZmllcyB3aGVyZSBpbiB0aGUgdmFyaWFibGUgCi0gICAqIHN0YWNrIHRoZSBzZWFyY2ggc2hvdWxkIGJlZ2luLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VmFyU3RhY2tQb3MoaW50IHRvcCkKLSAgewotICAgIG1fdmFyU3RhY2tQb3MgPSB0b3A7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIGluZGV4IGludG8gdGhlIHZhcmlhYmxlIHN0YWNrIHdoZXJlIHRoZSB2YXJpYWJsZSBjb250ZXh0IAotICAgKiBlbmRzLCBpLmUuIGF0IHRoZSBwb2ludCB3ZSBzaG91bGQgdGVybWluYXRlIHRoZSBzZWFyY2guCi0gICAqIAotICAgKiBAcGFyYW0gVGhlIHBvaW50IGF0IHdoaWNoIHRoZSBzZWFyY2ggc2hvdWxkIHRlcm1pbmF0ZSwgbm9ybWFsbHkgCi0gICAqIHplcm8gZm9yIGdsb2JhbCB2YXJpYWJsZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRWYXJTdGFja0NvbnRleHQoaW50IGJvdHRvbSkKLSAgewotICAgIG1fdmFyU3RhY2tDb250ZXh0ID0gYm90dG9tOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCB3aGF0IGtpbmQgb2YgY2xhc3MgdGhpcyBpcy4KLSAgICoKLSAgICogQHJldHVybiBDTEFTU19VTlJFU09MVkVEVkFSSUFCTEUKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfVU5SRVNPTFZFRFZBUklBQkxFOwotICB9Ci0gIAotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGluZm9ybWF0aW9uYWwgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiWFVucmVzb2x2ZWRWYXJpYWJsZSAoIiArIG9iamVjdCgpLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIikiOwotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL291dHB1dF9odG1sLnByb3BlcnRpZXMgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvb3V0cHV0X2h0bWwucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTc2Njg1Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvb3V0cHV0X2h0bWwucHJvcGVydGllcworKysgL2Rldi9udWxsCkBAIC0xLDI1ICswLDAgQEAKLSMKLSMgU3BlY2lmeSBkZWZhdWx0cyB3aGVuIG1ldGhvZD0iaHRtbCIuICBUaGVzZSBkZWZhdWx0cyB1c2Ugb3V0cHV0X3htbC5wcm9wZXJ0aWVzIAotIyBhcyBhIGJhc2UuCi0jCi0KLSMgWFNMVCBwcm9wZXJ0aWVzIGRvIG5vdCBuZWVkIG5hbWVzcGFjZSBxdWFsaWZpY2F0aW9uLgotbWV0aG9kPWh0bWwKLWluZGVudD15ZXMKLW1lZGlhLXR5cGU9dGV4dC9odG1sCi12ZXJzaW9uPTQuMAotCi0jIFhhbGFuLXNwZWNpZmljIG91dHB1dCBwcm9wZXJ0aWVzLiAgVGhlc2UgY2FuIGJlIG92ZXJyaWRkZW4gaW4gdGhlIHN0eWxlc2hlZXQgCi0jIGFzc2lnbmluZyBhIHhhbGFuIG5hbWVzcGFjZS4gIEZvciBleGFtcGxlOgotIyA8eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIgotIyAgICAgICAgICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSMgICAgICAgICAgeG1sbnM6eGFsYW49Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0Ij4KLSMgIDx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgZW5jb2Rpbmc9IlVURi04IgotIyAgICAgICAgICAgICAgeGFsYW46Y29udGVudC1oYW5kbGVyPSJNeUNvbnRlbnRIYW5kbGVyIi8+Ci0jICAuLi4KLSMgTm90ZSB0aGF0IHRoZSBjb2xvbiBhZnRlciB0aGUgcHJvdG9jb2wgbmVlZHMgdG8gYmUgZXNjYXBlZC4KLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94c2x0fWluZGVudC1hbW91bnQ9MAote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hzbHR9Y29udGVudC1oYW5kbGVyPW9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb0hUTUwKLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94c2x0fWVudGl0aWVzPUhUTUxFbnRpdGllcy5yZXMKLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94c2x0fXVzZS11cmwtZXNjYXBpbmc9eWVzCi17aHR0cFx1MDAzYS8veG1sLmFwYWNoZS5vcmcveHNsdH1vbWl0LW1ldGEtdGFnPW5vCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvb3V0cHV0X3RleHQucHJvcGVydGllcyBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9vdXRwdXRfdGV4dC5wcm9wZXJ0aWVzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYjhmNTUxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9vdXRwdXRfdGV4dC5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMTggKzAsMCBAQAotIwotIyBTcGVjaWZ5IGRlZmF1bHRzIHdoZW4gbWV0aG9kPSJ0ZXh0Ii4KLSMKLQotIyBYU0xUIHByb3BlcnRpZXMgZG8gbm90IG5lZWQgbmFtZXNwYWNlIHF1YWxpZmljYXRpb24uCi1tZXRob2Q9dGV4dAotbWVkaWEtdHlwZT10ZXh0L3BsYWluCi0KLSMgWGFsYW4tc3BlY2lmaWMgb3V0cHV0IHByb3BlcnRpZXMuICBUaGVzZSBjYW4gYmUgb3ZlcnJpZGRlbiBpbiB0aGUgc3R5bGVzaGVldCAKLSMgYXNzaWduaW5nIGEgeGFsYW4gbmFtZXNwYWNlLiAgRm9yIGV4YW1wbGU6Ci0jIDx4c2w6c3R5bGVzaGVldCB2ZXJzaW9uPSIxLjAiCi0jICAgICAgICAgIHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotIyAgICAgICAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiPgotIyAgPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBlbmNvZGluZz0iVVRGLTgiCi0jICAgICAgICAgICAgICB4YWxhbjpjb250ZW50LWhhbmRsZXI9Ik15Q29udGVudEhhbmRsZXIiLz4KLSMgIC4uLgotIyBOb3RlIHRoYXQgdGhlIGNvbG9uIGFmdGVyIHRoZSBwcm90b2NvbCBuZWVkcyB0byBiZSBlc2NhcGVkLgote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hzbHR9Y29udGVudC1oYW5kbGVyPW9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1RleHQKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvb3V0cHV0X3htbC5wcm9wZXJ0aWVzIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL291dHB1dF94bWwucHJvcGVydGllcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGFlMGYzYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvb3V0cHV0X3htbC5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMjYgKzAsMCBAQAotIwotIyBTcGVjaWZ5IGRlZmF1bHRzIHdoZW4gbWV0aG9kPSJ4bWwiLiAgVGhlc2UgZGVmYXVsdHMgc2VydmUgYXMgYSBiYXNlIGZvciAKLSMgb3RoZXIgZGVmYXVsdHMsIHN1Y2ggYXMgb3V0cHV0X2h0bWwgYW5kIG91dHB1dF90ZXh0LgotIwotCi0jIFhTTFQgcHJvcGVydGllcyBkbyBub3QgbmVlZCBuYW1lc3BhY2UgcXVhbGlmaWNhdGlvbi4KLW1ldGhvZD14bWwKLXZlcnNpb249MS4wCi1lbmNvZGluZz1VVEYtOAotaW5kZW50PW5vCi1vbWl0LXhtbC1kZWNsYXJhdGlvbj1ubwotc3RhbmRhbG9uZT1ubwotbWVkaWEtdHlwZT10ZXh0L3htbAotCi0jIFhhbGFuLXNwZWNpZmljIG91dHB1dCBwcm9wZXJ0aWVzLiAgVGhlc2UgY2FuIGJlIG92ZXJyaWRkZW4gaW4gdGhlIHN0eWxlc2hlZXQgCi0jIGFzc2lnbmluZyBhIHhhbGFuIG5hbWVzcGFjZS4gIEZvciBleGFtcGxlOgotIyA8eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIgotIyAgICAgICAgICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSMgICAgICAgICAgeG1sbnM6eGFsYW49Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0Ij4KLSMgIDx4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgZW5jb2Rpbmc9IlVURi04IgotIyAgICAgICAgICAgICAgeGFsYW46Y29udGVudC1oYW5kbGVyPSJNeUNvbnRlbnRIYW5kbGVyIi8+Ci0jICAuLi4KLSMgTm90ZSB0aGF0IHRoZSBjb2xvbiBhZnRlciB0aGUgcHJvdG9jb2wgbmVlZHMgdG8gYmUgZXNjYXBlZC4KLXtodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94c2x0fWluZGVudC1hbW91bnQ9MAote2h0dHBcdTAwM2EvL3htbC5hcGFjaGUub3JnL3hzbHR9Y29udGVudC1oYW5kbGVyPW9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1hNTAotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzY1MjNhYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjYgKzAsMCBAQAotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiBUZW1wbGF0ZXMgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRzIHRoZSB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXN9IGludGVyZmFjZSwgCi0gICAgYW5kIGRlZmluZXMgYSBzZXQgb2YgY2xhc3NlcyB0aGF0IHJlcHJlc2VudCBhbiBYU0xUIHN0eWxlc2hlZXQuPC9wPgotICAgIAotICAgIDxwPntAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdH0gaW1wbGVtZW50cyB0aGUge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzfSBpbnRlcmZhY2UsIGFuZCAKLSAgICBleHRlbmRzIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Q29tcG9zZWR9LCAKLSAgICB3aGljaCBpcyBhIHtAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0fSBjb21wb3NlZCBvZiBpdHNlbGYgCi0gICAgYW5kIGl0cyBpbmNsdWRlZCBTdHlsZXNoZWV0IG9iamVjdHMuIEEgU3R5bGVzaGVldFJvb3QgYWxzbyBjb250YWlucyBhIAotICAgIGdsb2JhbCBsaXN0IG9mIGFsbCBpbXBvcnRlZCBTdHlsZXNoZWV0Q29tcG9zZWQgb2JqZWN0cy4gVGhlCi0gICAgcm9sZSBvZiB0aGVzZSBvYmplY3RzIGlzIHRvIGhvbGQgaW1tdXRhYmxlIHN0eWxlc2hlZXQgZGF0YSwgbm90IHRvIHBlcmZvcm0gCi0gICAgcHJvY2VkdXJhbCB0YXNrcyBhc3NvY2lhdGVkIHdpdGggdGhlCi0gICAgY29uc3RydWN0aW9uIG9mIHRoZSBkYXRhICh0aGUgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IgcGFja2FnZSkgb3Igd2l0aCB0aGUgdHJhbnNmb3JtYXRpb24gKHRoZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyCi0gICAgcGFja2FnZSkuPC9wPgotICAgIDxwPntAbGluayBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50fSBpcyB0aGUgc3VwZXJjbGFzcyBvZiAKLSAgICBhbGwgWFNMVCBpbnN0cnVjdGlvbiBlbGVtZW50cywgaW5jbHVkaW5nIFN0eWxlc2hlZXQuIFRoZSA8aT54PC9pPkZ1bmMgY2xhc3NlcwotICAgIGV4dGVuZCBtZW1iZXJzIG9mIHRoZSBvcmcuYXBhY2hlLnhwYXRoIHBhY2thZ2UgYW5kIGltcGxlbWVudCBYU0xUIGZ1bmN0aW9ucy4gVW5saWtlIAotICAgIHRoZSBTdHlsZXNoZWV0ICJjb250YWluZXIiIG9iamVjdHMsIHRoZQotICAgIGluc3RydWN0aW9uIGVsZW1lbnQgYW5kIGZ1bmN0aW9uIGNsYXNzZXMgZG8gY29udGFpbiBwcm9jZWR1cmFsIGV4ZWN1dGUoKSAKLSAgICBtZXRob2RzIHRoYXQgYXJlIGNhbGxlZCBkdXJpbmcgdGhlIHRyYW5zZm9ybWF0aW9uLjwvcD4KLSAgICA8cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvRW5kU2VsZWN0aW9uRXZlbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL0VuZFNlbGVjdGlvbkV2ZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiYjEwMzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvRW5kU2VsZWN0aW9uRXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3ICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFjZTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFdmVudCB0cmlnZ2VyZWQgYnkgY29tcGxldGlvbiBvZiBhIHhzbDpmb3ItZWFjaCBzZWxlY3Rpb24gb3IgYSAKLSAqIHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRW5kU2VsZWN0aW9uRXZlbnQgZXh0ZW5kcyBTZWxlY3Rpb25FdmVudAotewotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gRW5kU2VsZWN0aW9uRXZlbnQuCi0gICAqIAotICAgKiBAcGFyYW0gcHJvY2Vzc29yIFRoZSBYU0xUIFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgVGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKiBAcGFyYW0gbW9kZSBUaGUgY3VycmVudCBtb2RlLgotICAgKiBAcGFyYW0gc3R5bGVOb2RlIG5vZGUgaW4gdGhlIHN0eWxlIHRyZWUgcmVmZXJlbmNlIGZvciB0aGUgZXZlbnQuCi0gICAqIFNob3VsZCBub3QgYmUgbnVsbC4gIFRoYXQgaXMgbm90IGVuZm9yY2VkLgotICAgKiBAcGFyYW0gYXR0cmlidXRlTmFtZSBUaGUgYXR0cmlidXRlIG5hbWUgZnJvbSB3aGljaCB0aGUgc2VsZWN0aW9uIGlzIG1hZGUuCi0gICAqIEBwYXJhbSB4cGF0aCBUaGUgWFBhdGggdGhhdCBleGVjdXRlZCB0aGUgc2VsZWN0aW9uLgotICAgKiBAcGFyYW0gc2VsZWN0aW9uIFRoZSByZXN1bHQgb2YgdGhlIHNlbGVjdGlvbi4KLSAgICovCi0gIHB1YmxpYyBFbmRTZWxlY3Rpb25FdmVudChUcmFuc2Zvcm1lckltcGwgcHJvY2Vzc29yLCBOb2RlIHNvdXJjZU5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHN0eWxlTm9kZSwgU3RyaW5nIGF0dHJpYnV0ZU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBYUGF0aCB4cGF0aCwgWE9iamVjdCBzZWxlY3Rpb24pCi0gIHsKLQotICAgIHN1cGVyKHByb2Nlc3Nvciwgc291cmNlTm9kZSwgc3R5bGVOb2RlLCBhdHRyaWJ1dGVOYW1lLCB4cGF0aCwgc2VsZWN0aW9uKTsKLSAgfQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL0dlbmVyYXRlRXZlbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL0dlbmVyYXRlRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2JhODdjZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9HZW5lcmF0ZUV2ZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFjZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotaW1wb3J0IGphdmEuaW8uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXZlbnQgZ2VuZXJhdGVkIGJ5IHRoZSBYU0wgcHJvY2Vzc29yIGFmdGVyIGl0IGdlbmVyYXRlcyBhIG5ldyBub2RlIGluIHRoZSByZXN1bHQgdHJlZS4KLSAqIFRoaXMgZXZlbnQgcmVzcG9uZHMgdG8gYW5kIGlzIG1vZGVsZWQgb24gdGhlIFNBWCBldmVudHMgdGhhdCBhcmUgc2VudCB0byB0aGUKLSAqIGZvcm1hdHRlciBsaXN0ZW5lciBGb3JtYXR0ZXJUb1hYWCljbGFzc2VzLgotICoKLSAqIEBzZWUgb3JnLmFwYWNoZS54bWwudXRpbHMuRE9NQnVpbGRlcgotICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyVG9IVE1MCi0gKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1RleHQKLSAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplclRvWE1MCi0gKgotICovCi1wdWJsaWMgY2xhc3MgR2VuZXJhdGVFdmVudCBpbXBsZW1lbnRzIGphdmEudXRpbC5FdmVudExpc3RlbmVyCi17Ci0KLSAgLyoqCi0gICAqIFRoZSBYU0xUIFRyYW5zZm9ybWVyLCB3aGljaCBlaXRoZXIgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBjb250YWlucyBtb3N0IG5lZWRlZCBpbmZvcm1hdGlvbi4KLSAgICoKLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbAotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVySW1wbCBtX3Byb2Nlc3NvcjsKLQotICAvKioKLSAgICogVGhlIHR5cGUgb2YgU0FYIGV2ZW50IHRoYXQgd2FzIGdlbmVyYXRlZCwgYXMgZW51bWVyYXRlZCBpbiB0aGUgRVZFTlRUWVBFX1hYWCBjb25zdGFudHMgYmVsb3cuCi0gICAqLwotICBwdWJsaWMgaW50IG1fZXZlbnR0eXBlOwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGEgZG9jdW1lbnQgYmVnaW5zLgotICAgKgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX1NUQVJURE9DVU1FTlQgPSAxOwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGEgZG9jdW1lbnQgZW5kcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UVFlQRV9FTkRET0NVTUVOVCA9IDI7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIHdoZW4gYW4gZWxlbWVudCBiZWdpbnMgKGFmdGVyIHRoZSBhdHRyaWJ1dGVzIGhhdmUgYmVlbiBwcm9jZXNzZWQgYnV0IGJlZm9yZSB0aGUgY2hpbGRyZW4gaGF2ZSBiZWVuIGFkZGVkKS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UVFlQRV9TVEFSVEVMRU1FTlQgPSAzOwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCB3aGVuIGFuIGVsZW1lbnQgZW5kcywgYWZ0ZXIgaXQncyBjaGlsZHJlbiBoYXZlIGJlZW4gYWRkZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfRU5ERUxFTUVOVCA9IDQ7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIGZvciBjaGFyYWN0ZXIgZGF0YSAoQ0RBVEEgYW5kIElnbm9yYWJsZSBXaGl0ZXNwYWNlIGhhdmUgdGhlaXIgb3duIGV2ZW50cykuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfQ0hBUkFDVEVSUyA9IDU7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIGZvciBpZ25vcmFibGUgd2hpdGVzcGFjZSAoSSdtIG5vdCBzdXJlIGhvdyBtdWNoIHRoaXMgaXMgYWN0dWFsbHkgY2FsbGVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX0lHTk9SQUJMRVdISVRFU1BBQ0UgPSA2OwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCBmb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfUEkgPSA3OwotCi0gIC8qKgotICAgKiBFdmVudCB0eXBlIGdlbmVyYXRlZCBhZnRlciBhIGNvbW1lbnQgaGFzIGJlZW4gYWRkZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFVkVOVFRZUEVfQ09NTUVOVCA9IDg7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGUgYWZ0ZXIgYW4gZW50aXR5IHJlZiBpcyBjcmVhdGVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVZFTlRUWVBFX0VOVElUWVJFRiA9IDk7Ci0KLSAgLyoqCi0gICAqIEV2ZW50IHR5cGUgZ2VuZXJhdGVkIGFmdGVyIENEQVRBIGlzIGdlbmVyYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVWRU5UVFlQRV9DREFUQSA9IDEwOwotCi0gIC8qKgotICAgKiBDaGFyYWN0ZXIgZGF0YSBmcm9tIGEgY2hhcmFjdGVyIG9yIGNkYXRhIGV2ZW50LgotICAgKi8KLSAgcHVibGljIGNoYXIgbV9jaGFyYWN0ZXJzW107Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBkYXRhIGluIG1fY2hhcmFjdGVycy4KLSAgICovCi0gIHB1YmxpYyBpbnQgbV9zdGFydDsKLQotICAvKioKLSAgICogVGhlIGxlbmd0aCBvZiB0aGUgY3VycmVudCBkYXRhIGluIG1fY2hhcmFjdGVycy4KLSAgICovCi0gIHB1YmxpYyBpbnQgbV9sZW5ndGg7Ci0KLSAgLyoqCi0gICAqIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IG9yIFBJLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBtX25hbWU7Ci0KLSAgLyoqCi0gICAqIFRoZSBzdHJpbmcgZGF0YSBpbiB0aGUgZWxlbWVudCAoY29tbWVudHMgYW5kIFBJcykuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIG1fZGF0YTsKLQotICAvKioKLSAgICogVGhlIGN1cnJlbnQgYXR0cmlidXRlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgQXR0cmlidXRlcyBtX2F0dHM7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBzdGFydERvY3VtZW50LCBlbmREb2N1bWVudCBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgVGhlIFhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5IGluc3RhbmNlLgotICAgKiBAcGFyYW0gZXZlbnRUeXBlIE9uZSBvZiB0aGUgRVZFTlRUWVBFX1hYWCBjb25zdGFudHMuCi0gICAqLwotICBwdWJsaWMgR2VuZXJhdGVFdmVudChUcmFuc2Zvcm1lckltcGwgcHJvY2Vzc29yLCBpbnQgZXZlbnRUeXBlKQotICB7Ci0gICAgbV9wcm9jZXNzb3IgPSBwcm9jZXNzb3I7Ci0gICAgbV9ldmVudHR5cGUgPSBldmVudFR5cGU7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgZm9yIHN0YXJ0RWxlbWVudCwgZW5kRWxlbWVudCBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgVGhlIFhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5IEluc3RhbmNlLgotICAgKiBAcGFyYW0gZXZlbnRUeXBlIE9uZSBvZiB0aGUgRVZFTlRUWVBFX1hYWCBjb25zdGFudHMuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50LgotICAgKiBAcGFyYW0gYXR0cyBUaGUgU0FYIGF0dHJpYnV0ZSBsaXN0LgotICAgKi8KLSAgcHVibGljIEdlbmVyYXRlRXZlbnQoVHJhbnNmb3JtZXJJbXBsIHByb2Nlc3NvciwgaW50IGV2ZW50VHlwZSwgU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXMgYXR0cykKLSAgewotCi0gICAgbV9uYW1lID0gbmFtZTsKLSAgICBtX2F0dHMgPSBhdHRzOwotICAgIG1fcHJvY2Vzc29yID0gcHJvY2Vzc29yOwotICAgIG1fZXZlbnR0eXBlID0gZXZlbnRUeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBjaGFyYWN0ZXJzLCBjZGF0ZSBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgVGhlIFhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5IGluc3RhbmNlLgotICAgKiBAcGFyYW0gZXZlbnRUeXBlIE9uZSBvZiB0aGUgRVZFTlRUWVBFX1hYWCBjb25zdGFudHMuCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhciBhcnJheSBmcm9tIHRoZSBTQVggZXZlbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgb2Zmc2V0IHRvIGJlIHVzZWQgaW4gdGhlIGNoYXIgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIGVuZCBvZmZzZXQgdG8gYmUgdXNlZCBpbiB0aGUgY2hhcmEgYXJyYXkuCi0gICAqLwotICBwdWJsaWMgR2VuZXJhdGVFdmVudChUcmFuc2Zvcm1lckltcGwgcHJvY2Vzc29yLCBpbnQgZXZlbnRUeXBlLCBjaGFyIGNoW10sCi0gICAgICAgICAgICAgICAgICAgICAgIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotCi0gICAgbV9jaGFyYWN0ZXJzID0gY2g7Ci0gICAgbV9zdGFydCA9IHN0YXJ0OwotICAgIG1fbGVuZ3RoID0gbGVuZ3RoOwotICAgIG1fcHJvY2Vzc29yID0gcHJvY2Vzc29yOwotICAgIG1fZXZlbnR0eXBlID0gZXZlbnRUeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gZXZlbnRzLgotICAgKgotICAgKiBAcGFyYW0gcHJvY2Vzc29yIFRoZSBpbnN0YW5jZSBvZiB0aGUgWFNMVCBwcm9jZXNzb3IuCi0gICAqIEBwYXJhbSBldmVudFR5cGUgT25lIG9mIHRoZSBFVkVOVFRZUEVfWFhYIGNvbnN0YW50cy4KLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqIEBwYXJhbSBkYXRhIFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEuCi0gICAqLwotICBwdWJsaWMgR2VuZXJhdGVFdmVudChUcmFuc2Zvcm1lckltcGwgcHJvY2Vzc29yLCBpbnQgZXZlbnRUeXBlLCBTdHJpbmcgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRhdGEpCi0gIHsKLQotICAgIG1fbmFtZSA9IG5hbWU7Ci0gICAgbV9kYXRhID0gZGF0YTsKLSAgICBtX3Byb2Nlc3NvciA9IHByb2Nlc3NvcjsKLSAgICBtX2V2ZW50dHlwZSA9IGV2ZW50VHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBmb3IgY29tbWVudCBhbmQgZW50aXR5IHJlZiBldmVudHMuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgVGhlIFhTTFQgcHJvY2Vzc29yIGluc3RhbmNlLgotICAgKiBAcGFyYW0gZXZlbnRUeXBlIE9uZSBvZiB0aGUgRVZFTlRUWVBFX1hYWCBjb25zdGFudHMuCi0gICAqIEBwYXJhbSBkYXRhIFRoZSBjb21tZW50IG9yIGVudGl0eSByZWYgZGF0YS4KLSAgICovCi0gIHB1YmxpYyBHZW5lcmF0ZUV2ZW50KFRyYW5zZm9ybWVySW1wbCBwcm9jZXNzb3IsIGludCBldmVudFR5cGUsIFN0cmluZyBkYXRhKQotICB7Ci0KLSAgICBtX2RhdGEgPSBkYXRhOwotICAgIG1fcHJvY2Vzc29yID0gcHJvY2Vzc29yOwotICAgIG1fZXZlbnR0eXBlID0gZXZlbnRUeXBlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9QcmludFRyYWNlTGlzdGVuZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL1ByaW50VHJhY2VMaXN0ZW5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MTdiOGYzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL1ByaW50VHJhY2VMaXN0ZW5lci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzI0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhY2U7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGV4dExpdGVyYWw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Db250ZXh0Tm9kZUxpc3Q7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVQcm94eTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBUcmFjZUxpc3RlbmVyIGludGVyZmFjZSB0aGF0Ci0gKiBwcmludHMgZWFjaCBldmVudCB0byBzdGFuZGFyZCBvdXQgYXMgaXQgb2NjdXJzLgotICoKLSAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5UcmFjZXJFdmVudAotICovCi1wdWJsaWMgY2xhc3MgUHJpbnRUcmFjZUxpc3RlbmVyIGltcGxlbWVudHMgVHJhY2VMaXN0ZW5lcgotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSB0cmFjZSBsaXN0ZW5lci4KLSAgICoKLSAgICogQHBhcmFtIHB3IFByaW50V3JpdGVyIHRvIHVzZSBmb3IgdHJhY2luZyBldmVudHMKLSAgICovCi0gIHB1YmxpYyBQcmludFRyYWNlTGlzdGVuZXIoamF2YS5pby5QcmludFdyaXRlciBwdykKLSAgewotICAgIG1fcHcgPSBwdzsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgcHJpbnQgd3JpdGVyIHdoZXJlIHRoZSBldmVudHMgc2hvdWxkIGJlIHdyaXR0ZW4uCi0gICAqLwotICBqYXZhLmlvLlByaW50V3JpdGVyIG1fcHc7Ci0KLSAgLyoqCi0gICAqIFRoaXMgbmVlZHMgdG8gYmUgc2V0IHRvIHRydWUgaWYgdGhlIGxpc3RlbmVyIGlzIHRvIHByaW50IGFuIGV2ZW50IHdoZW5ldmVyIGEgdGVtcGxhdGUgaXMgaW52b2tlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIG1fdHJhY2VUZW1wbGF0ZXMgPSBmYWxzZTsKLQotICAvKioKLSAgICogU2V0IHRvIHRydWUgaWYgdGhlIGxpc3RlbmVyIGlzIHRvIHByaW50IGV2ZW50cyB0aGF0IG9jY3VyIGFzIGVhY2ggbm9kZSBpcyAnZXhlY3V0ZWQnIGluIHRoZSBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbV90cmFjZUVsZW1lbnRzID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFNldCB0byB0cnVlIGlmIHRoZSBsaXN0ZW5lciBpcyB0byBwcmludCBpbmZvcm1hdGlvbiBhZnRlciBlYWNoIHJlc3VsdC10cmVlIGdlbmVyYXRpb24gZXZlbnQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBtX3RyYWNlR2VuZXJhdGlvbiA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBTZXQgdG8gdHJ1ZSBpZiB0aGUgbGlzdGVuZXIgaXMgdG8gcHJpbnQgaW5mb3JtYXRpb24gYWZ0ZXIgZWFjaCBzZWxlY3Rpb24gZXZlbnQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBtX3RyYWNlU2VsZWN0aW9uID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFByaW50IGluZm9ybWF0aW9uIGFib3V0IGEgVHJhY2VyRXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBldiB0aGUgdHJhY2UgZXZlbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmFjZShUcmFjZXJFdmVudCBldikKLSAgewotCi0gICAgc3dpdGNoIChldi5tX3N0eWxlTm9kZS5nZXRYU0xUb2tlbigpKQotICAgIHsKLSAgICBjYXNlIENvbnN0YW50cy5FTEVNTkFNRV9URVhUTElURVJBTFJFU1VMVCA6Ci0gICAgICBpZiAobV90cmFjZUVsZW1lbnRzKQotICAgICAgewotICAgICAgICBtX3B3LnByaW50KGV2Lm1fc3R5bGVOb2RlLmdldFN5c3RlbUlkKCkrICIgTGluZSAjIiArIGV2Lm1fc3R5bGVOb2RlLmdldExpbmVOdW1iZXIoKSArICIsICIKLSAgICAgICAgICAgICAgICAgICArICJDb2x1bW4gIyIgKyBldi5tX3N0eWxlTm9kZS5nZXRDb2x1bW5OdW1iZXIoKSArICIgLS0gIgotICAgICAgICAgICAgICAgICAgICsgZXYubV9zdHlsZU5vZGUuZ2V0Tm9kZU5hbWUoKSArICI6ICIpOwotCi0gICAgICAgIEVsZW1UZXh0TGl0ZXJhbCBldGwgPSAoRWxlbVRleHRMaXRlcmFsKSBldi5tX3N0eWxlTm9kZTsKLSAgICAgICAgU3RyaW5nIGNoYXJzID0gbmV3IFN0cmluZyhldGwuZ2V0Q2hhcnMoKSwgMCwgZXRsLmdldENoYXJzKCkubGVuZ3RoKTsKLQotICAgICAgICBtX3B3LnByaW50bG4oIiAgICAiICsgY2hhcnMudHJpbSgpKTsKLSAgICAgIH0KLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQ29uc3RhbnRzLkVMRU1OQU1FX1RFTVBMQVRFIDoKLSAgICAgIGlmIChtX3RyYWNlVGVtcGxhdGVzIHx8IG1fdHJhY2VFbGVtZW50cykKLSAgICAgIHsKLSAgICAgICAgRWxlbVRlbXBsYXRlIGV0ID0gKEVsZW1UZW1wbGF0ZSkgZXYubV9zdHlsZU5vZGU7Ci0KLSAgICAgICAgbV9wdy5wcmludChldC5nZXRTeXN0ZW1JZCgpKyAiIExpbmUgIyIgKyBldC5nZXRMaW5lTnVtYmVyKCkgKyAiLCAiICsgIkNvbHVtbiAjIgotICAgICAgICAgICAgICAgICAgICsgZXQuZ2V0Q29sdW1uTnVtYmVyKCkgKyAiOiAiICsgZXQuZ2V0Tm9kZU5hbWUoKSArICIgIik7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gZXQuZ2V0TWF0Y2goKSkKLSAgICAgICAgewotICAgICAgICAgIG1fcHcucHJpbnQoIm1hdGNoPSciICsgZXQuZ2V0TWF0Y2goKS5nZXRQYXR0ZXJuU3RyaW5nKCkgKyAiJyAiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChudWxsICE9IGV0LmdldE5hbWUoKSkKLSAgICAgICAgewotICAgICAgICAgIG1fcHcucHJpbnQoIm5hbWU9JyIgKyBldC5nZXROYW1lKCkgKyAiJyAiKTsKLSAgICAgICAgfQotCi0gICAgICAgIG1fcHcucHJpbnRsbigpOwotICAgICAgfQotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBpZiAobV90cmFjZUVsZW1lbnRzKQotICAgICAgewotICAgICAgICBtX3B3LnByaW50bG4oZXYubV9zdHlsZU5vZGUuZ2V0U3lzdGVtSWQoKSsgIiBMaW5lICMiICsgZXYubV9zdHlsZU5vZGUuZ2V0TGluZU51bWJlcigpICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgKyAiQ29sdW1uICMiICsgZXYubV9zdHlsZU5vZGUuZ2V0Q29sdW1uTnVtYmVyKCkgKyAiOiAiCi0gICAgICAgICAgICAgICAgICAgICArIGV2Lm1fc3R5bGVOb2RlLmdldE5vZGVOYW1lKCkpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgdGhhdCBpcyBjYWxsZWQganVzdCBhZnRlciBhIHNlbGVjdCBhdHRyaWJ1dGUgaGFzIGJlZW4gZXZhbHVhdGVkLgotICAgKgotICAgKiBAcGFyYW0gZXYgdGhlIGdlbmVyYXRlIGV2ZW50LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV90cmFjZVNlbGVjdGlvbikKLSAgICB7Ci0gICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IGV0ZSA9IChFbGVtVGVtcGxhdGVFbGVtZW50KSBldi5tX3N0eWxlTm9kZTsKLSAgICAgIE5vZGUgc291cmNlTm9kZSA9IGV2Lm1fc291cmNlTm9kZTsKLSAgICAgIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KXNvdXJjZU5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSAgICAgIAotICAgICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gKChEVE1Ob2RlUHJveHkpc291cmNlTm9kZSkuZ2V0RFRNKCkKLSAgICAgICAgLmdldFNvdXJjZUxvY2F0b3JGb3Iobm9kZUhhbmRsZXIpOwotCi0gICAgICBpZiAobG9jYXRvciAhPSBudWxsKSAgICAgIAotICAgICAgICBtX3B3LnByaW50bG4oIlNlbGVjdGVkIHNvdXJjZSBub2RlICciICsgc291cmNlTm9kZS5nZXROb2RlTmFtZSgpCi0gICAgICAgICAgICAgICAgICsgIicsIGF0ICIgKyBsb2NhdG9yKTsKLQotICAgICAgaWYgKGV2Lm1fc3R5bGVOb2RlLmdldExpbmVOdW1iZXIoKSA9PSAwKQotICAgICAgewotCi0gICAgICAgIC8vIFlvdSBtYXkgbm90IGhhdmUgbGluZSBudW1iZXJzIGlmIHRoZSBzZWxlY3Rpb24gaXMgb2NjdXJpbmcgZnJvbSBhCi0gICAgICAgIC8vIGRlZmF1bHQgdGVtcGxhdGUuCi0gICAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgcGFyZW50ID0KLSAgICAgICAgICAoRWxlbVRlbXBsYXRlRWxlbWVudCkgZXRlLmdldFBhcmVudEVsZW0oKTsKLQotICAgICAgICBpZiAocGFyZW50ID09IGV0ZS5nZXRTdHlsZXNoZWV0Um9vdCgpLmdldERlZmF1bHRSb290UnVsZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgbV9wdy5wcmludCgiKGRlZmF1bHQgcm9vdCBydWxlKSAiKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChwYXJlbnQgPT0gZXRlLmdldFN0eWxlc2hlZXRSb290KCkuZ2V0RGVmYXVsdFRleHRSdWxlKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBtX3B3LnByaW50KCIoZGVmYXVsdCB0ZXh0IHJ1bGUpICIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHBhcmVudCA9PSBldGUuZ2V0U3R5bGVzaGVldFJvb3QoKS5nZXREZWZhdWx0UnVsZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgbV9wdy5wcmludCgiKGRlZmF1bHQgcnVsZSkgIik7Ci0gICAgICAgIH0KLQotICAgICAgICBtX3B3LnByaW50KGV0ZS5nZXROb2RlTmFtZSgpICsgIiwgIiArIGV2Lm1fYXR0cmlidXRlTmFtZSArICI9JyIKLSAgICAgICAgICAgICAgICAgICArIGV2Lm1feHBhdGguZ2V0UGF0dGVyblN0cmluZygpICsgIic6ICIpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3B3LnByaW50KGV2Lm1fc3R5bGVOb2RlLmdldFN5c3RlbUlkKCkrICIgTGluZSAjIiArIGV2Lm1fc3R5bGVOb2RlLmdldExpbmVOdW1iZXIoKSArICIsICIKLSAgICAgICAgICAgICAgICAgICArICJDb2x1bW4gIyIgKyBldi5tX3N0eWxlTm9kZS5nZXRDb2x1bW5OdW1iZXIoKSArICI6ICIKLSAgICAgICAgICAgICAgICAgICArIGV0ZS5nZXROb2RlTmFtZSgpICsgIiwgIiArIGV2Lm1fYXR0cmlidXRlTmFtZSArICI9JyIKLSAgICAgICAgICAgICAgICAgICArIGV2Lm1feHBhdGguZ2V0UGF0dGVyblN0cmluZygpICsgIic6ICIpOwotICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXYubV9zZWxlY3Rpb24uZ2V0VHlwZSgpID09IGV2Lm1fc2VsZWN0aW9uLkNMQVNTX05PREVTRVQpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcHcucHJpbnRsbigpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yIG5sID0gZXYubV9zZWxlY3Rpb24uaXRlcigpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmwgPSBubC5jbG9uZVdpdGhSZXNldCgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3B3LnByaW50bG4oIiAgICAgW0Nhbid0IHRyYWNlIG5vZGVsaXN0IGJlY2F1c2UgaXQgaXQgdGhyZXcgYSBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbl0iKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBvcyA9IG5sLm5leHROb2RlKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERUTS5OVUxMID09IHBvcykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcHcucHJpbnRsbigiICAgICBbZW1wdHkgbm9kZSBsaXN0XSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSBwb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbV9wdy5wcmludGxuKCIgICAgICIgKyBldi5tX3Byb2Nlc3Nvci5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0ocG9zKS5nZXROb2RlKHBvcykpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRNIGR0bSA9IGV2Lm1fcHJvY2Vzc29yLmdldFhQYXRoQ29udGV4dCgpLmdldERUTShwb3MpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wdy5wcmludCgiICAgICAiKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcHcucHJpbnQoSW50ZWdlci50b0hleFN0cmluZyhwb3MpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcHcucHJpbnQoIjogIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3B3LnByaW50bG4oZHRtLmdldE5vZGVOYW1lKHBvcykpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBubC5uZXh0Tm9kZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fcHcucHJpbnRsbihldi5tX3NlbGVjdGlvbi5zdHIoKSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50IGluZm9ybWF0aW9uIGFib3V0IGEgR2VuZXJhdGUgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBldiB0aGUgdHJhY2UgZXZlbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBnZW5lcmF0ZWQoR2VuZXJhdGVFdmVudCBldikKLSAgewotCi0gICAgaWYgKG1fdHJhY2VHZW5lcmF0aW9uKQotICAgIHsKLSAgICAgIHN3aXRjaCAoZXYubV9ldmVudHR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX1NUQVJURE9DVU1FTlQgOgotICAgICAgICBtX3B3LnByaW50bG4oIlNUQVJURE9DVU1FTlQiKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX0VORERPQ1VNRU5UIDoKLSAgICAgICAgbV9wdy5wcmludGxuKCJFTkRET0NVTUVOVCIpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfU1RBUlRFTEVNRU5UIDoKLSAgICAgICAgbV9wdy5wcmludGxuKCJTVEFSVEVMRU1FTlQ6ICIgKyBldi5tX25hbWUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfRU5ERUxFTUVOVCA6Ci0gICAgICAgIG1fcHcucHJpbnRsbigiRU5ERUxFTUVOVDogIiArIGV2Lm1fbmFtZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBHZW5lcmF0ZUV2ZW50LkVWRU5UVFlQRV9DSEFSQUNURVJTIDoKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGNoYXJzID0gbmV3IFN0cmluZyhldi5tX2NoYXJhY3RlcnMsIGV2Lm1fc3RhcnQsIGV2Lm1fbGVuZ3RoKTsKLQotICAgICAgICBtX3B3LnByaW50bG4oIkNIQVJBQ1RFUlM6ICIgKyBjaGFycyk7Ci0gICAgICB9Ci0gICAgICBicmVhazsKLSAgICAgIGNhc2UgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfQ0RBVEEgOgotICAgICAgewotICAgICAgICBTdHJpbmcgY2hhcnMgPSBuZXcgU3RyaW5nKGV2Lm1fY2hhcmFjdGVycywgZXYubV9zdGFydCwgZXYubV9sZW5ndGgpOwotCi0gICAgICAgIG1fcHcucHJpbnRsbigiQ0RBVEE6ICIgKyBjaGFycyk7Ci0gICAgICB9Ci0gICAgICBicmVhazsKLSAgICAgIGNhc2UgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfQ09NTUVOVCA6Ci0gICAgICAgIG1fcHcucHJpbnRsbigiQ09NTUVOVDogIiArIGV2Lm1fZGF0YSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBHZW5lcmF0ZUV2ZW50LkVWRU5UVFlQRV9QSSA6Ci0gICAgICAgIG1fcHcucHJpbnRsbigiUEk6ICIgKyBldi5tX25hbWUgKyAiLCAiICsgZXYubV9kYXRhKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX0VOVElUWVJFRiA6Ci0gICAgICAgIG1fcHcucHJpbnRsbigiRU5USVRZUkVGOiAiICsgZXYubV9uYW1lKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX0lHTk9SQUJMRVdISVRFU1BBQ0UgOgotICAgICAgICBtX3B3LnByaW50bG4oIklHTk9SQUJMRVdISVRFU1BBQ0UiKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9TZWxlY3Rpb25FdmVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvU2VsZWN0aW9uRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDE0NGU0My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9TZWxlY3Rpb25FdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhY2U7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXZlbnQgdHJpZ2dlcmVkIGJ5IHNlbGVjdGlvbiBvZiBhIG5vZGUgaW4gdGhlIHN0eWxlIHN0cmVlLgotICovCi1wdWJsaWMgY2xhc3MgU2VsZWN0aW9uRXZlbnQgaW1wbGVtZW50cyBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcgotewotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpbiB0aGUgc3R5bGUgdHJlZSB3aGVyZSB0aGUgZXZlbnQgb2NjdXJzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgbV9zdHlsZU5vZGU7Ci0KLSAgLyoqCi0gICAqIFRoZSBYU0xUIHByb2Nlc3NvciBpbnN0YW5jZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBUcmFuc2Zvcm1lckltcGwgbV9wcm9jZXNzb3I7Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlIG1fc291cmNlTm9kZTsKLQotICAvKioKLSAgICogVGhlIGF0dHJpYnV0ZSBuYW1lIGZyb20gd2hpY2ggdGhlIHNlbGVjdGlvbiBpcyBtYWRlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBtX2F0dHJpYnV0ZU5hbWU7Ci0KLSAgLyoqCi0gICAqIFRoZSBYUGF0aCB0aGF0IGV4ZWN1dGVkIHRoZSBzZWxlY3Rpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgWFBhdGggbV94cGF0aDsKLQotICAvKioKLSAgICogVGhlIHJlc3VsdCBvZiB0aGUgc2VsZWN0aW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFhPYmplY3QgbV9zZWxlY3Rpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBldmVudCBvcmlnaW5hdGluZyBhdCB0aGUgZ2l2ZW4gbm9kZSBvZiB0aGUgc3R5bGUgdHJlZS4KLSAgICogCi0gICAqIEBwYXJhbSBwcm9jZXNzb3IgVGhlIFhTTFQgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBtb2RlIFRoZSBjdXJyZW50IG1vZGUuCi0gICAqIEBwYXJhbSBzdHlsZU5vZGUgbm9kZSBpbiB0aGUgc3R5bGUgdHJlZSByZWZlcmVuY2UgZm9yIHRoZSBldmVudC4KLSAgICogU2hvdWxkIG5vdCBiZSBudWxsLiAgVGhhdCBpcyBub3QgZW5mb3JjZWQuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVOYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZSBmcm9tIHdoaWNoIHRoZSBzZWxlY3Rpb24gaXMgbWFkZS4KLSAgICogQHBhcmFtIHhwYXRoIFRoZSBYUGF0aCB0aGF0IGV4ZWN1dGVkIHRoZSBzZWxlY3Rpb24uCi0gICAqIEBwYXJhbSBzZWxlY3Rpb24gVGhlIHJlc3VsdCBvZiB0aGUgc2VsZWN0aW9uLgotICAgKi8KLSAgcHVibGljIFNlbGVjdGlvbkV2ZW50KFRyYW5zZm9ybWVySW1wbCBwcm9jZXNzb3IsIE5vZGUgc291cmNlTm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgc3R5bGVOb2RlLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIFhQYXRoIHhwYXRoLCBYT2JqZWN0IHNlbGVjdGlvbikKLSAgewotCi0gICAgdGhpcy5tX3Byb2Nlc3NvciA9IHByb2Nlc3NvcjsKLSAgICB0aGlzLm1fc291cmNlTm9kZSA9IHNvdXJjZU5vZGU7Ci0gICAgdGhpcy5tX3N0eWxlTm9kZSA9IHN0eWxlTm9kZTsKLSAgICB0aGlzLm1fYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWU7Ci0gICAgdGhpcy5tX3hwYXRoID0geHBhdGg7Ci0gICAgdGhpcy5tX3NlbGVjdGlvbiA9IHNlbGVjdGlvbjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VMaXN0ZW5lci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VMaXN0ZW5lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YjM3NDU1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL1RyYWNlTGlzdGVuZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhY2U7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogSW50ZXJmYWNlIHRoZSBYU0wgcHJvY2Vzc29yIGNhbGxzIHdoZW4gaXQgbWF0Y2hlcyBhIHNvdXJjZSBub2RlLCBzZWxlY3RzIGEgc2V0IG9mIHNvdXJjZSBub2RlcywKLSAqIG9yIGdlbmVyYXRlcyBhIHJlc3VsdCBub2RlLgotICogSWYgeW91IHdhbnQgYW4gb2JqZWN0IGluc3RhbmNlIHRvIGJlIGNhbGxlZCB3aGVuIGEgdHJhY2UgZXZlbnQgb2NjdXJzLCB1c2UgdGhlIFRyYW5zZm9ybWVySW1wbCBzZXRUcmFjZUxpc3RlbmVyIG1ldGhvZC4KLSAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5UcmFjZXJFdmVudAotICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLlRyYWNlTWFuYWdlciNhZGRUcmFjZUxpc3RlbmVyCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVHJhY2VMaXN0ZW5lciBleHRlbmRzIGphdmEudXRpbC5FdmVudExpc3RlbmVyCi17Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCB0aGF0IGlzIGNhbGxlZCB3aGVuIGEgdHJhY2UgZXZlbnQgb2NjdXJzLgotICAgKiBUaGUgbWV0aG9kIGlzIGJsb2NraW5nLiAgSXQgbXVzdCByZXR1cm4gYmVmb3JlIHByb2Nlc3NpbmcgY29udGludWVzLgotICAgKgotICAgKiBAcGFyYW0gZXYgdGhlIHRyYWNlIGV2ZW50LgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhY2UoVHJhY2VyRXZlbnQgZXYpOwotCi0gIC8qKgotICAgKiBNZXRob2QgdGhhdCBpcyBjYWxsZWQganVzdCBhZnRlciB0aGUgZm9ybWF0dGVyIGxpc3RlbmVyIGlzIGNhbGxlZC4KLSAgICoKLSAgICogQHBhcmFtIGV2IHRoZSBnZW5lcmF0ZSBldmVudC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldikgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCB0aGF0IGlzIGNhbGxlZCBqdXN0IGFmdGVyIHRoZSBmb3JtYXR0ZXIgbGlzdGVuZXIgaXMgY2FsbGVkLgotICAgKgotICAgKiBAcGFyYW0gZXYgdGhlIGdlbmVyYXRlIGV2ZW50LgotICAgKi8KLSAgcHVibGljIHZvaWQgZ2VuZXJhdGVkKEdlbmVyYXRlRXZlbnQgZXYpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VMaXN0ZW5lckV4LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9UcmFjZUxpc3RlbmVyRXguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmFhYWI5Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9UcmFjZUxpc3RlbmVyRXguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFjZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4dGVuZHMgVHJhY2VMaXN0ZW5lciBidXQgYWRkcyBhIFNlbGVjdEVuZCBldmVudC4KLSAqLwotcHVibGljIGludGVyZmFjZSBUcmFjZUxpc3RlbmVyRXggZXh0ZW5kcyBUcmFjZUxpc3RlbmVyCi17Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCB0aGF0IGlzIGNhbGxlZCBhZnRlciBhbiB4c2w6YXBwbHktdGVtcGxhdGVzIG9yIHhzbDpmb3ItZWFjaCAKLSAgICogc2VsZWN0aW9uIG9jY3Vycy4KLSAgICoKLSAgICogQHBhcmFtIGV2IHRoZSBnZW5lcmF0ZSBldmVudC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZWxlY3RFbmQoRW5kU2VsZWN0aW9uRXZlbnQgZXYpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VNYW5hZ2VyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9UcmFjZU1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjJlOWNmMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9UcmFjZU1hbmFnZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBtYW5hZ2VzIHRyYWNlIGxpc3RlbmVycywgYW5kIGFjdHMgYXMgYW4KLSAqIGludGVyZmFjZSBmb3IgdGhlIHRyYWNpbmcgZnVuY3Rpb25hbGl0eSBpbiBYYWxhbi4KLSAqLwotcHVibGljIGNsYXNzIFRyYWNlTWFuYWdlcgotewotCi0gIC8qKiBBIHRyYW5zZm9ybWVyIGluc3RhbmNlICovCi0gIHByaXZhdGUgVHJhbnNmb3JtZXJJbXBsIG1fdHJhbnNmb3JtZXI7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciB0aGUgdHJhY2UgbWFuYWdlci4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIGEgbm9uLW51bGwgaW5zdGFuY2Ugb2YgYSB0cmFuc2Zvcm1lcgotICAgKi8KLSAgcHVibGljIFRyYWNlTWFuYWdlcihUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpCi0gIHsKLSAgICBtX3RyYW5zZm9ybWVyID0gdHJhbnNmb3JtZXI7Ci0gIH0KLQotICAvKioKLSAgICogTGlzdCBvZiBsaXN0ZW5lcnMgd2hvIGFyZSBpbnRlcmVzdGVkIGluIHRyYWNpbmcgd2hhdCdzCi0gICAqIGJlaW5nIGdlbmVyYXRlZC4KLSAgICovCi0gIHByaXZhdGUgVmVjdG9yIG1fdHJhY2VMaXN0ZW5lcnMgPSBudWxsOwotCi0gIC8qKgotICAgKiBBZGQgYSB0cmFjZSBsaXN0ZW5lciBmb3IgdGhlIHB1cnBvc2VzIG9mIGRlYnVnZ2luZyBhbmQgZGlhZ25vc2lzLgotICAgKiBAcGFyYW0gdGwgVHJhY2UgbGlzdGVuZXIgdG8gYmUgYWRkZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVG9vTWFueUxpc3RlbmVyc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkVHJhY2VMaXN0ZW5lcihUcmFjZUxpc3RlbmVyIHRsKQotICAgICAgICAgIHRocm93cyBUb29NYW55TGlzdGVuZXJzRXhjZXB0aW9uCi0gIHsKLQotICAgIFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHID0gdHJ1ZTsKLQotICAgIGlmIChudWxsID09IG1fdHJhY2VMaXN0ZW5lcnMpCi0gICAgICBtX3RyYWNlTGlzdGVuZXJzID0gbmV3IFZlY3RvcigpOwotCi0gICAgbV90cmFjZUxpc3RlbmVycy5hZGRFbGVtZW50KHRsKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgYSB0cmFjZSBsaXN0ZW5lci4KLSAgICogQHBhcmFtIHRsIFRyYWNlIGxpc3RlbmVyIHRvIGJlIHJlbW92ZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVUcmFjZUxpc3RlbmVyKFRyYWNlTGlzdGVuZXIgdGwpCi0gIHsKLQotICAgIGlmIChudWxsICE9IG1fdHJhY2VMaXN0ZW5lcnMpCi0gICAgewotICAgICAgbV90cmFjZUxpc3RlbmVycy5yZW1vdmVFbGVtZW50KHRsKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmlyZSBhIGdlbmVyYXRlIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gdGUgR2VuZXJhdGUgRXZlbnQgdG8gZmlyZQotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZUdlbmVyYXRlRXZlbnQoR2VuZXJhdGVFdmVudCB0ZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV90cmFjZUxpc3RlbmVycykKLSAgICB7Ci0gICAgICBpbnQgbkxpc3RlbmVycyA9IG1fdHJhY2VMaXN0ZW5lcnMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5MaXN0ZW5lcnM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgVHJhY2VMaXN0ZW5lciB0bCA9IChUcmFjZUxpc3RlbmVyKSBtX3RyYWNlTGlzdGVuZXJzLmVsZW1lbnRBdChpKTsKLQotICAgICAgICB0bC5nZW5lcmF0ZWQodGUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRyYWNlIGxpc3RlbmVycyBhcmUgcHJlc2VudC4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGFyZSB0cmFjZSBsaXN0ZW5lcnMKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc1RyYWNlTGlzdGVuZXJzKCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3RyYWNlTGlzdGVuZXJzKTsKLSAgfQotCi0gIC8qKgotICAgKiBGaXJlIGEgdHJhY2UgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIEN1cnJlbnQgc291cmNlIG5vZGUKLSAgICogQHBhcmFtIG1vZGUgVGVtcGxhdGUgbW9kZQotICAgKiBAcGFyYW0gc3R5bGVOb2RlIFN0eWxlc2hlZXQgdGVtcGxhdGUgbm9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZVRyYWNlRXZlbnQoRWxlbVRlbXBsYXRlRWxlbWVudCBzdHlsZU5vZGUpCi0gIHsKLQotICAgIGlmIChoYXNUcmFjZUxpc3RlbmVycygpKQotICAgIHsKLSAgICAgIGludCBzb3VyY2VOb2RlID0gbV90cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgTm9kZSBzb3VyY2UgPSBtX3RyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldERUTSgKLSAgICAgICAgc291cmNlTm9kZSkuZ2V0Tm9kZShzb3VyY2VOb2RlKTsKLQotICAgICAgZmlyZVRyYWNlRXZlbnQobmV3IFRyYWNlckV2ZW50KG1fdHJhbnNmb3JtZXIsIHNvdXJjZSwgCi0gICAgICAgICAgICAgICAgICAgICBtX3RyYW5zZm9ybWVyLmdldE1vZGUoKSwgIC8qc291cmNlTm9kZSwgbW9kZSwqLwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlTm9kZSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaXJlIGEgdHJhY2UgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSB0ZSBUcmFjZSBldmVudCB0byBmaXJlCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXJlVHJhY2VFdmVudChUcmFjZXJFdmVudCB0ZSkKLSAgewotCi0gICAgaWYgKGhhc1RyYWNlTGlzdGVuZXJzKCkpCi0gICAgewotICAgICAgaW50IG5MaXN0ZW5lcnMgPSBtX3RyYWNlTGlzdGVuZXJzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuTGlzdGVuZXJzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFRyYWNlTGlzdGVuZXIgdGwgPSAoVHJhY2VMaXN0ZW5lcikgbV90cmFjZUxpc3RlbmVycy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgdGwudHJhY2UodGUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaXJlIGEgc2VsZWN0aW9uIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBDdXJyZW50IHNvdXJjZSBub2RlCi0gICAqIEBwYXJhbSBzdHlsZU5vZGUgbm9kZSBpbiB0aGUgc3R5bGUgdHJlZSByZWZlcmVuY2UgZm9yIHRoZSBldmVudC4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lIGZyb20gd2hpY2ggdGhlIHNlbGVjdGlvbiBpcyBtYWRlLgotICAgKiBAcGFyYW0geHBhdGggVGhlIFhQYXRoIHRoYXQgZXhlY3V0ZWQgdGhlIHNlbGVjdGlvbi4KLSAgICogQHBhcmFtIHNlbGVjdGlvbiBUaGUgcmVzdWx0IG9mIHRoZSBzZWxlY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZVNlbGVjdGVkRXZlbnQoCi0gICAgICAgICAgaW50IHNvdXJjZU5vZGUsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgc3R5bGVOb2RlLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwgCi0gICAgICAgICAgWFBhdGggeHBhdGgsIFhPYmplY3Qgc2VsZWN0aW9uKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKGhhc1RyYWNlTGlzdGVuZXJzKCkpCi0gICAgewotICAgICAgTm9kZSBzb3VyY2UgPSBtX3RyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldERUTSgKLSAgICAgICAgc291cmNlTm9kZSkuZ2V0Tm9kZShzb3VyY2VOb2RlKTsKLQotICAgICAgZmlyZVNlbGVjdGVkRXZlbnQobmV3IFNlbGVjdGlvbkV2ZW50KG1fdHJhbnNmb3JtZXIsIHNvdXJjZSwgc3R5bGVOb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWUsIHhwYXRoLCBzZWxlY3Rpb24pKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBGaXJlIGEgc2VsZWN0aW9uIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBDdXJyZW50IHNvdXJjZSBub2RlCi0gICAqIEBwYXJhbSBzdHlsZU5vZGUgbm9kZSBpbiB0aGUgc3R5bGUgdHJlZSByZWZlcmVuY2UgZm9yIHRoZSBldmVudC4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZU5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lIGZyb20gd2hpY2ggdGhlIHNlbGVjdGlvbiBpcyBtYWRlLgotICAgKiBAcGFyYW0geHBhdGggVGhlIFhQYXRoIHRoYXQgZXhlY3V0ZWQgdGhlIHNlbGVjdGlvbi4KLSAgICogQHBhcmFtIHNlbGVjdGlvbiBUaGUgcmVzdWx0IG9mIHRoZSBzZWxlY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZVNlbGVjdGVkRW5kRXZlbnQoCi0gICAgICAgICAgaW50IHNvdXJjZU5vZGUsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgc3R5bGVOb2RlLCBTdHJpbmcgYXR0cmlidXRlTmFtZSwgCi0gICAgICAgICAgWFBhdGggeHBhdGgsIFhPYmplY3Qgc2VsZWN0aW9uKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKGhhc1RyYWNlTGlzdGVuZXJzKCkpCi0gICAgewotICAgICAgTm9kZSBzb3VyY2UgPSBtX3RyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldERUTSgKLSAgICAgICAgc291cmNlTm9kZSkuZ2V0Tm9kZShzb3VyY2VOb2RlKTsKLQotICAgICAgZmlyZVNlbGVjdGVkRW5kRXZlbnQobmV3IEVuZFNlbGVjdGlvbkV2ZW50KG1fdHJhbnNmb3JtZXIsIHNvdXJjZSwgc3R5bGVOb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWUsIHhwYXRoLCBzZWxlY3Rpb24pKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBGaXJlIGEgc2VsZWN0aW9uIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gc2UgU2VsZWN0aW9uIGV2ZW50IHRvIGZpcmUKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXJlU2VsZWN0ZWRFbmRFdmVudChFbmRTZWxlY3Rpb25FdmVudCBzZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoaGFzVHJhY2VMaXN0ZW5lcnMoKSkKLSAgICB7Ci0gICAgICBpbnQgbkxpc3RlbmVycyA9IG1fdHJhY2VMaXN0ZW5lcnMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5MaXN0ZW5lcnM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgVHJhY2VMaXN0ZW5lciB0bCA9IChUcmFjZUxpc3RlbmVyKSBtX3RyYWNlTGlzdGVuZXJzLmVsZW1lbnRBdChpKTsKLQotICAgICAgICBpZih0bCBpbnN0YW5jZW9mIFRyYWNlTGlzdGVuZXJFeCkKLSAgICAgICAgICAoKFRyYWNlTGlzdGVuZXJFeCl0bCkuc2VsZWN0RW5kKHNlKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmlyZSBhIHNlbGVjdGlvbiBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIHNlIFNlbGVjdGlvbiBldmVudCB0byBmaXJlCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmlyZVNlbGVjdGVkRXZlbnQoU2VsZWN0aW9uRXZlbnQgc2UpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKGhhc1RyYWNlTGlzdGVuZXJzKCkpCi0gICAgewotICAgICAgaW50IG5MaXN0ZW5lcnMgPSBtX3RyYWNlTGlzdGVuZXJzLnNpemUoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuTGlzdGVuZXJzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIFRyYWNlTGlzdGVuZXIgdGwgPSAoVHJhY2VMaXN0ZW5lcikgbV90cmFjZUxpc3RlbmVycy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgdGwuc2VsZWN0ZWQoc2UpOwotICAgICAgfQotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VyRXZlbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL1RyYWNlckV2ZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYyODhiZmQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VyRXZlbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBQYXJlbnQgY2xhc3Mgb2YgZXZlbnRzIGdlbmVyYXRlZCBmb3IgdHJhY2luZyB0aGUKLSAqIHByb2dyZXNzIG9mIHRoZSBYU0wgcHJvY2Vzc29yLgotICovCi1wdWJsaWMgY2xhc3MgVHJhY2VyRXZlbnQgaW1wbGVtZW50cyBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcgotewotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpbiB0aGUgc3R5bGUgdHJlZSB3aGVyZSB0aGUgZXZlbnQgb2NjdXJzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIEVsZW1UZW1wbGF0ZUVsZW1lbnQgbV9zdHlsZU5vZGU7Ci0KLSAgLyoqCi0gICAqIFRoZSBYU0xUIHByb2Nlc3NvciBpbnN0YW5jZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBUcmFuc2Zvcm1lckltcGwgbV9wcm9jZXNzb3I7Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlIG1fc291cmNlTm9kZTsKLQotICAvKioKLSAgICogVGhlIGN1cnJlbnQgbW9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBRTmFtZSBtX21vZGU7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBldmVudCBvcmlnaW5hdGluZyBhdCB0aGUgZ2l2ZW4gbm9kZSBvZiB0aGUgc3R5bGUgdHJlZS4KLSAgICogQHBhcmFtIHByb2Nlc3NvciBUaGUgWFNMVCBUcmFuc2Zvcm1lckZhY3RvcnkuCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICogQHBhcmFtIG1vZGUgVGhlIGN1cnJlbnQgbW9kZS4KLSAgICogQHBhcmFtIG1fc3R5bGVOb2RlIG5vZGUgaW4gdGhlIHN0eWxlIHRyZWUgcmVmZXJlbmNlIGZvciB0aGUgZXZlbnQuCi0gICAqIFNob3VsZCBub3QgYmUgbnVsbC4gIFRoYXQgaXMgbm90IGVuZm9yY2VkLgotICAgKiBAcGFyYW0gc3R5bGVOb2RlIFRoZSBzdHlsZXNoZWV0IGVsZW1lbnQgdGhhdCBpcyBleGVjdXRpbmcuCi0gICAqLwotICBwdWJsaWMgVHJhY2VyRXZlbnQoVHJhbnNmb3JtZXJJbXBsIHByb2Nlc3NvciwgTm9kZSBzb3VyY2VOb2RlLCBRTmFtZSBtb2RlLAotICAgICAgICAgICAgICAgICAgICAgRWxlbVRlbXBsYXRlRWxlbWVudCBzdHlsZU5vZGUpCi0gIHsKLQotICAgIHRoaXMubV9wcm9jZXNzb3IgPSBwcm9jZXNzb3I7Ci0gICAgdGhpcy5tX3NvdXJjZU5vZGUgPSBzb3VyY2VOb2RlOwotICAgIHRoaXMubV9tb2RlID0gbW9kZTsKLSAgICB0aGlzLm1fc3R5bGVOb2RlID0gc3R5bGVOb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG5vZGUuCi0gICAqIFRoZSBzdHJpbmcgcmV0dXJuZWQgZm9yIGVsZW1lbnRzIHdpbGwgY29udGFpbiB0aGUgZWxlbWVudCBuYW1lCi0gICAqIGFuZCBhbnkgYXR0cmlidXRlcyBlbmNsb3NlZCBpbiBhbmdsZSBicmFja2V0cy4KLSAgICogVGhlIHN0cmluZyByZXR1cm5lZCBmb3IgYXR0cmlidXRlcyB3aWxsIGJlIG9mIGZvcm0sICJuYW1lPXZhbHVlLiIKLSAgICoKLSAgICogQHBhcmFtIG4gYW55IERPTSBub2RlLiBNdXN0IG5vdCBiZSBudWxsLgotICAgKgotICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgcHJpbnROb2RlKE5vZGUgbikKLSAgewotCi0gICAgU3RyaW5nIHIgPSBuLmhhc2hDb2RlKCkgKyAiICI7Ci0KLSAgICBpZiAobiBpbnN0YW5jZW9mIEVsZW1lbnQpCi0gICAgewotICAgICAgciArPSAiPCIgKyBuLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgIE5vZGUgYyA9IG4uZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgICB3aGlsZSAobnVsbCAhPSBjKQotICAgICAgewotICAgICAgICBpZiAoYyBpbnN0YW5jZW9mIEF0dHIpCi0gICAgICAgIHsKLSAgICAgICAgICByICs9IHByaW50Tm9kZShjKSArICIgIjsKLSAgICAgICAgfQotCi0gICAgICAgIGMgPSBjLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICB9Ci0KLSAgICAgIHIgKz0gIj4iOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyKQotICAgICAgewotICAgICAgICByICs9IG4uZ2V0Tm9kZU5hbWUoKSArICI9IiArIG4uZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHIgKz0gbi5nZXROb2RlTmFtZSgpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiByOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG5vZGUgbGlzdC4KLSAgICogVGhlIHN0cmluZyB3aWxsIGNvbnRhaW4gdGhlIGxpc3Qgb2Ygbm9kZXMgaW5zaWRlIHNxdWFyZSBicmFjZXMuCi0gICAqIEVsZW1lbnRzIHdpbGwgY29udGFpbiB0aGUgZWxlbWVudCBuYW1lCi0gICAqIGFuZCBhbnkgYXR0cmlidXRlcyBlbmNsb3NlZCBpbiBhbmdsZSBicmFja2V0cy4KLSAgICogQXR0cmlidXRlcyB3aWxsIGJlIG9mIGZvcm0sICJuYW1lPXZhbHVlLiIKLSAgICoKLSAgICogQHBhcmFtIGwgYW55IERPTSBub2RlIGxpc3QuIE11c3Qgbm90IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHByaW50Tm9kZUxpc3QoTm9kZUxpc3QgbCkKLSAgewotCi0gICAgU3RyaW5nIHIgPSBsLmhhc2hDb2RlKCkgKyAiWyI7Ci0gICAgaW50IGxlbiA9IGwuZ2V0TGVuZ3RoKCkgLSAxOwotICAgIGludCBpID0gMDsKLQotICAgIHdoaWxlIChpIDwgbGVuKQotICAgIHsKLSAgICAgIE5vZGUgbiA9IGwuaXRlbShpKTsKLQotICAgICAgaWYgKG51bGwgIT0gbikKLSAgICAgIHsKLSAgICAgICAgciArPSBwcmludE5vZGUobikgKyAiLCAiOwotICAgICAgfQotCi0gICAgICArK2k7Ci0gICAgfQotCi0gICAgaWYgKGkgPT0gbGVuKQotICAgIHsKLSAgICAgIE5vZGUgbiA9IGwuaXRlbShsZW4pOwotCi0gICAgICBpZiAobnVsbCAhPSBuKQotICAgICAgewotICAgICAgICByICs9IHByaW50Tm9kZShuKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gciArICJdIjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNmQwMTUzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDggKzAsMCBAQAotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiBUcmFjZSAoZGVidWdnZXIpIFBhY2thZ2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gVHJhY2UgZXZlbnRzLCBmb3IgdXNlIGJ5IGEgZGVidWdnZXIuPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0Nsb25lclRvUmVzdWx0VHJlZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvQ2xvbmVyVG9SZXN1bHRUcmVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ4MmU4YWUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvQ2xvbmVyVG9SZXN1bHRUcmVlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLlN0eWxlc2hlZXQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIENsYXNzIHVzZWQgdG8gY2xvbmUgYSBub2RlLCBwb3NzaWJseSBpbmNsdWRpbmcgaXRzIGNoaWxkcmVuIHRvIAotICogYSByZXN1bHQgdHJlZS4KLSAqLwotcHVibGljIGNsYXNzIENsb25lclRvUmVzdWx0VHJlZQotewotCi0gIC8qKiBSZXN1bHQgdHJlZSBoYW5kbGVyIGZvciB0aGUgY2xvbmVkIHRyZWUgICAgICAgICAgICovCi0gIHByaXZhdGUgUmVzdWx0VHJlZUhhbmRsZXIgbV9ydGg7Ci0KLSAgLyoqIFRyYW5zZm9ybWVyIGluc3RhbmNlIHRvIHVzZSBmb3IgY2xvbmluZyAgICAgICAgICAqLwotICBwcml2YXRlIFRyYW5zZm9ybWVySW1wbCBtX3RyYW5zZm9ybWVyOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBDbG9uZXJUb1Jlc3VsdFRyZWUKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHRyYW5zZm9ybWVyIGluc3RhbmNlIHRvIHVzZSBmb3IgdGhlIGNsb25pbmcKLSAgICogQHBhcmFtIHJ0aCBub24tbnVsbCByZXN1bHQgdHJlZSBoYW5kbGVyIGZvciB0aGUgY2xvbmVkIHRyZWUKLSAgICovCi0gIHB1YmxpYyBDbG9uZXJUb1Jlc3VsdFRyZWUoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdFRyZWVIYW5kbGVyIHJ0aCkKLSAgewotICAgIG1fcnRoID0gcnRoOwotICAgIG1fdHJhbnNmb3JtZXIgPSB0cmFuc2Zvcm1lcjsKLSAgfQotCi0vLyAgLyoqCi0vLyAgICogQ2xvbmUgYW4gZWxlbWVudCB3aXRoIG9yIHdpdGhvdXQgY2hpbGRyZW4uCi0vLyAgICogVE9ETzogRml4IG9yIGZpZ3VyZSBvdXQgbm9kZSBjbG9uZSBmYWlsdXJlIQotLy8gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBjbG9uZQotLy8gICAqIEBwYXJhbSBzaG91bGRDbG9uZUF0dHJpYnV0ZXMgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gCi0vLyAgICogY2xvbmUgY2hpbGRyZW4gYXR0cmlidXRlcwotLy8gICAqIAotLy8gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLS8vICAgKi8KLS8vICBwdWJsaWMgdm9pZCBjbG9uZVRvUmVzdWx0VHJlZShpbnQgbm9kZSwgYm9vbGVhbiBzaG91bGRDbG9uZUF0dHJpYnV0ZXMpCi0vLyAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLS8vICB7Ci0vLwotLy8gICAgdHJ5Ci0vLyAgICB7Ci0vLyAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG1fdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCk7Ci0vLyAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0obm9kZSk7Ci0vLwotLy8gICAgICBpbnQgdHlwZSA9IGR0bS5nZXROb2RlVHlwZShub2RlKTsKLS8vICAgICAgc3dpdGNoICh0eXBlKQotLy8gICAgICB7Ci0vLyAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0vLyAgICAgICAgZHRtLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhub2RlLCBtX3J0aCwgZmFsc2UpOwotLy8gICAgICAgIGJyZWFrOwotLy8gICAgICBjYXNlIERUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLS8vICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0vLwotLy8gICAgICAgIC8vIENhbid0IGNsb25lIGEgZG9jdW1lbnQsIGJ1dCByZWZyYWluIGZyb20gdGhyb3dpbmcgYW4gZXJyb3IKLS8vICAgICAgICAvLyBzbyB0aGF0IGNvcHktb2Ygd2lsbCB3b3JrCi0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGNhc2UgRFRNLkVMRU1FTlRfTk9ERSA6Ci0vLyAgICAgICAgewotLy8gICAgICAgICAgQXR0cmlidXRlcyBhdHRzOwotLy8KLS8vICAgICAgICAgIGlmIChzaG91bGRDbG9uZUF0dHJpYnV0ZXMpCi0vLyAgICAgICAgICB7Ci0vLyAgICAgICAgICAgIG1fcnRoLmFkZEF0dHJpYnV0ZXMobm9kZSk7Ci0vLyAgICAgICAgICAgIG1fcnRoLnByb2Nlc3NOU0RlY2xzKG5vZGUsIHR5cGUsIGR0bSk7Ci0vLyAgICAgICAgICB9Ci0vLwotLy8gICAgICAgICAgU3RyaW5nIG5zID0gZHRtLmdldE5hbWVzcGFjZVVSSShub2RlKTsKLS8vICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSBkdG0uZ2V0TG9jYWxOYW1lKG5vZGUpOwotLy8KLS8vICAgICAgICAgIG1fcnRoLnN0YXJ0RWxlbWVudChucywgbG9jYWxOYW1lLCBkdG0uZ2V0Tm9kZU5hbWVYKG5vZGUpLCBudWxsKTsKLS8vICAgICAgICB9Ci0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGNhc2UgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0vLyAgICAgICAgbV9ydGguc3RhcnRDREFUQSgpOyAgICAgICAgICAKLS8vICAgICAgICBkdG0uZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG5vZGUsIG1fcnRoLCBmYWxzZSk7Ci0vLyAgICAgICAgbV9ydGguZW5kQ0RBVEEoKTsKLS8vICAgICAgICBicmVhazsKLS8vICAgICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotLy8gICAgICAgIG1fcnRoLmFkZEF0dHJpYnV0ZShub2RlKTsKLS8vICAgICAgICBicmVhazsKLS8vICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFIDoKLS8vICAgICAgICBYTUxTdHJpbmcgeHN0ciA9IGR0bS5nZXRTdHJpbmdWYWx1ZSAobm9kZSk7Ci0vLyAgICAgICAgeHN0ci5kaXNwYXRjaEFzQ29tbWVudChtX3J0aCk7Ci0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0vLyAgICAgICAgbV9ydGguZW50aXR5UmVmZXJlbmNlKGR0bS5nZXROb2RlTmFtZVgobm9kZSkpOwotLy8gICAgICAgIGJyZWFrOwotLy8gICAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotLy8gICAgICAgIHsKLS8vICAgICAgICAgIC8vICVSRVZJRVclIElzIHRoZSBub2RlIG5hbWUgdGhlIHNhbWUgYXMgdGhlICJ0YXJnZXQiPwotLy8gICAgICAgICAgbV9ydGgucHJvY2Vzc2luZ0luc3RydWN0aW9uKGR0bS5nZXROb2RlTmFtZVgobm9kZSksIAotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0bS5nZXROb2RlVmFsdWUobm9kZSkpOwotLy8gICAgICAgIH0KLS8vICAgICAgICBicmVhazsKLS8vICAgICAgZGVmYXVsdCA6Ci0vLyAgICAgICAgLy8iQ2FuIG5vdCBjcmVhdGUgaXRlbSBpbiByZXN1bHQgdHJlZTogIitub2RlLmdldE5vZGVOYW1lKCkpOwotLy8gICAgICAgIG1fdHJhbnNmb3JtZXIuZ2V0TXNnTWdyKCkuZXJyb3IobnVsbCwgCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DUkVBVEVfSVRFTSwKLS8vICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZHRtLmdldE5vZGVOYW1lKG5vZGUpIH0pOyAgCi0vLyAgICAgIH0KLS8vICAgIH0KLS8vICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLS8vICAgIHsKLS8vICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLS8vICAgIH0KLS8vICB9ICAvLyBlbmQgY2xvbmVUb1Jlc3VsdFRyZWUgZnVuY3Rpb24KLSAgCi0gIC8qKgotICAgKiBDbG9uZSBhbiBlbGVtZW50IHdpdGggb3Igd2l0aG91dCBjaGlsZHJlbi4KLSAgICogVE9ETzogRml4IG9yIGZpZ3VyZSBvdXQgbm9kZSBjbG9uZSBmYWlsdXJlIQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBjbG9uZQotICAgKiBAcGFyYW0gc2hvdWxkQ2xvbmVBdHRyaWJ1dGVzIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIAotICAgKiBjbG9uZSBjaGlsZHJlbiBhdHRyaWJ1dGVzCi0gICAqIAotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgY2xvbmVUb1Jlc3VsdFRyZWUoaW50IG5vZGUsIGludCBub2RlVHlwZSwgRFRNIGR0bSwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXN1bHRUcmVlSGFuZGxlciBydGgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHNob3VsZENsb25lQXR0cmlidXRlcykKLSAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgc3dpdGNoIChub2RlVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgICAgIGR0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMobm9kZSwgcnRoLCBmYWxzZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICBjYXNlIERUTS5ET0NVTUVOVF9OT0RFIDoKLQotICAgICAgICAvLyBDYW4ndCBjbG9uZSBhIGRvY3VtZW50LCBidXQgcmVmcmFpbiBmcm9tIHRocm93aW5nIGFuIGVycm9yCi0gICAgICAgIC8vIHNvIHRoYXQgY29weS1vZiB3aWxsIHdvcmsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgICAgICB7Ci0gICAgICAgICAgQXR0cmlidXRlcyBhdHRzOwotCi0gICAgICAgICAgaWYgKHNob3VsZENsb25lQXR0cmlidXRlcykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBydGguYWRkQXR0cmlidXRlcyhub2RlKTsKLSAgICAgICAgICAgIHJ0aC5wcm9jZXNzTlNEZWNscyhub2RlLCBub2RlVHlwZSwgZHRtKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBTdHJpbmcgbnMgPSBkdG0uZ2V0TmFtZXNwYWNlVVJJKG5vZGUpOwotICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUgPSBkdG0uZ2V0TG9jYWxOYW1lKG5vZGUpOwotCi0gICAgICAgICAgcnRoLnN0YXJ0RWxlbWVudChucywgbG9jYWxOYW1lLCBkdG0uZ2V0Tm9kZU5hbWVYKG5vZGUpLCBudWxsKTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICAgIHJ0aC5zdGFydENEQVRBKCk7ICAgICAgICAgIAotICAgICAgICBkdG0uZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG5vZGUsIHJ0aCwgZmFsc2UpOwotICAgICAgICBydGguZW5kQ0RBVEEoKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICAgIHJ0aC5hZGRBdHRyaWJ1dGUobm9kZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgWE1MU3RyaW5nIHhzdHIgPSBkdG0uZ2V0U3RyaW5nVmFsdWUgKG5vZGUpOwotICAgICAgICB4c3RyLmRpc3BhdGNoQXNDb21tZW50KHJ0aCk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBEVE0uRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICAgICAgcnRoLmVudGl0eVJlZmVyZW5jZShkdG0uZ2V0Tm9kZU5hbWVYKG5vZGUpKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgICAgICB7Ci0gICAgICAgICAgLy8gJVJFVklFVyUgSXMgdGhlIG5vZGUgbmFtZSB0aGUgc2FtZSBhcyB0aGUgInRhcmdldCI/Ci0gICAgICAgICAgcnRoLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihkdG0uZ2V0Tm9kZU5hbWVYKG5vZGUpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRtLmdldE5vZGVWYWx1ZShub2RlKSk7Ci0gICAgICAgIH0KLSAgICAgICAgYnJlYWs7Ci0gICAgICBkZWZhdWx0IDoKLSAgICAgICAgLy8iQ2FuIG5vdCBjcmVhdGUgaXRlbSBpbiByZXN1bHQgdHJlZTogIitub2RlLmdldE5vZGVOYW1lKCkpOwotICAgICAgICB0aHJvdyBuZXcgIFRyYW5zZm9ybWVyRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICJDYW4ndCBjbG9uZSBub2RlOiAiK2R0bS5nZXROb2RlTmFtZShub2RlKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgfSAgLy8gZW5kIGNsb25lVG9SZXN1bHRUcmVlIGZ1bmN0aW9uCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Db3VudGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Db3VudGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQyM2UwYzEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvQ291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5vZGVWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOyAgLy8gZm9yIGlzTm9kZUFmdGVyIHN1cHBvcnQKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLk5vZGVTZXREVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtTnVtYmVyOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQSBjbGFzcyB0aGF0IGRvZXMgaW5jcmVtZW50YWwgY291bnRpbmcgZm9yIHN1cHBvcnQgb2YgeHNsOm51bWJlci4KLSAqIFRoaXMgY2xhc3Mgc3RvcmVzIGEgY2FjaGUgb2YgY291bnRlZCBub2RlcyAobV9jb3VudE5vZGVzKS4KLSAqIEl0IHRyaWVzIHRvIGNhY2hlIHRoZSBjb3VudGVkIG5vZGVzIGluIGRvY3VtZW50IG9yZGVyLi4uCi0gKiB0aGUgbm9kZSBjb3VudCBpcyBiYXNlZCBvbiBpdHMgcG9zaXRpb24gaW4gdGhlIGNhY2hlIGxpc3QKLSAqLwotcHVibGljIGNsYXNzIENvdW50ZXIKLXsKLQotICAvKioKLSAgICogU2V0IHRoZSBtYXhpbXVtIGFtbW91bnQgdGhlIG1fY291bnROb2RlcyBsaXN0IGNhbgotICAgKiBncm93IHRvLgotICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBNQVhDT1VOVE5PREVTID0gNTAwOwotCi0gIC8qKgotICAgKiBUaGUgc3RhcnQgY291bnQgZnJvbSB3aGVyZSBtX2NvdW50Tm9kZXMgY291bnRzCi0gICAqIGZyb20uICBJbiBvdGhlciB3b3JkcywgdGhlIGNvdW50IG9mIGEgZ2l2ZW4gbm9kZQotICAgKiBpbiB0aGUgbV9jb3VudE5vZGVzIHZlY3RvciBpcyBub2RlIHBvc2l0aW9uICsKLSAgICogbV9jb3VudE5vZGVzU3RhcnRDb3VudC4KLSAgICovCi0gIGludCBtX2NvdW50Tm9kZXNTdGFydENvdW50ID0gMDsKLQotICAvKioKLSAgICogQSB2ZWN0b3Igb2YgYWxsIG5vZGVzIGNvdW50ZWQgc28gZmFyLgotICAgKi8KLSAgTm9kZVNldERUTSBtX2NvdW50Tm9kZXM7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGZyb20gd2hlcmUgdGhlIGNvdW50aW5nIHN0YXJ0cy4gIFRoaXMgaXMgbmVlZGVkIHRvCi0gICAqIGZpbmQgYSBjb3VudGVyIGlmIHRoZSBub2RlIGJlaW5nIGNvdW50ZWQgaXMgbm90IGltbWVkaWF0bHkKLSAgICogZm91bmQgaW4gdGhlIG1fY291bnROb2RlcyB2ZWN0b3IuCi0gICAqLwotICBpbnQgbV9mcm9tTm9kZSA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiBUaGUgb3duaW5nIHhzbDpudW1iZXIgZWxlbWVudC4KLSAgICovCi0gIEVsZW1OdW1iZXIgbV9udW1iZXJFbGVtOwotCi0gIC8qKgotICAgKiBWYWx1ZSB0byBzdG9yZSByZXN1bHQgb2YgbGFzdCBnZXRDb3VudCBjYWxsLCBmb3IgYmVuaWZpdAotICAgKiBvZiByZXR1cm5pbmcgdmFsIGZyb20gQ291bnRlcnNUYWJsZS5nZXRDb3VudGVyQnlDb3VudGVkLAotICAgKiB3aG8gY2FsbHMgZ2V0Q291bnQuCi0gICAqLwotICBpbnQgbV9jb3VudFJlc3VsdDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgY291bnRlciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBudW1iZXJFbGVtIFRoZSBvd25pbmcgeHNsOm51bWJlciBlbGVtZW50LiAKLSAgICogQHBhcmFtIGNvdW50Tm9kZXMgQSB2ZWN0b3Igb2YgYWxsIG5vZGVzIGNvdW50ZWQgc28gZmFyLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBDb3VudGVyKEVsZW1OdW1iZXIgbnVtYmVyRWxlbSwgTm9kZVNldERUTSBjb3VudE5vZGVzKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIG1fY291bnROb2RlcyA9IGNvdW50Tm9kZXM7Ci0gICAgbV9udW1iZXJFbGVtID0gbnVtYmVyRWxlbTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBjb3VudGVyIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIG51bWJlckVsZW0gVGhlIG93bmluZyB4c2w6bnVtYmVyIGVsZW1lbnQuIAotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqCi0gIENvdW50ZXIoRWxlbU51bWJlciBudW1iZXJFbGVtKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIG1fbnVtYmVyRWxlbSA9IG51bWJlckVsZW07Ci0gIH0qLwotCi0gIC8qKgotICAgKiBUcnkgYW5kIGZpbmQgYSBub2RlIHRoYXQgd2FzIHByZXZpb3VzbHkgY291bnRlZC4gSWYgZm91bmQsCi0gICAqIHJldHVybiBhIHBvc2l0aXZlIGludGVnZXIgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgY291bnQuCi0gICAqCi0gICAqIEBwYXJhbSBzdXBwb3J0IFRoZSBYUGF0aCBjb250ZXh0IHRvIHVzZQotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBiZSBjb3VudGVkLgotICAgKiAKLSAgICogQHJldHVybiBUaGUgY291bnQgb2YgdGhlIG5vZGUsIG9yIC0xIGlmIG5vdCBmb3VuZC4KLSAgICovCi0gIGludCBnZXRQcmV2aW91c2x5Q291bnRlZChYUGF0aENvbnRleHQgc3VwcG9ydCwgaW50IG5vZGUpCi0gIHsKLQotICAgIGludCBuID0gbV9jb3VudE5vZGVzLnNpemUoKTsKLQotICAgIG1fY291bnRSZXN1bHQgPSAwOwotCi0gICAgZm9yIChpbnQgaSA9IG4gLSAxOyBpID49IDA7IGktLSkKLSAgICB7Ci0gICAgICBpbnQgY291bnRlZE5vZGUgPSBtX2NvdW50Tm9kZXMuZWxlbWVudEF0KGkpOwotCi0gICAgICBpZiAobm9kZSA9PSBjb3VudGVkTm9kZSkKLSAgICAgIHsKLQotICAgICAgICAvLyBTaW5jZSB0aGUgbGlzdCBpcyBpbiBiYWNrd2FyZHMgb3JkZXIsIHRoZSBjb3VudCBpcyAKLSAgICAgICAgLy8gaG93IG1hbnkgYXJlIGluIHRoZSByZXN0IG9mIHRoZSBsaXN0LgotICAgICAgICBtX2NvdW50UmVzdWx0ID0gaSArIDEgKyBtX2NvdW50Tm9kZXNTdGFydENvdW50OwotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgCi0gICAgICBEVE0gZHRtID0gc3VwcG9ydC5nZXREVE0oY291bnRlZE5vZGUpOwotCi0gICAgICAvLyBUcnkgdG8gc2VlIGlmIHRoZSBnaXZlbiBub2RlIGZhbGxzIGFmdGVyIHRoZSBjb3VudGVkIG5vZGUuLi4KLSAgICAgIC8vIGlmIGl0IGRvZXMsIGRvbid0IGtlZXAgc2VhcmNoaW5nIGJhY2t3YXJkcy4KLSAgICAgIGlmIChkdG0uaXNOb2RlQWZ0ZXIoY291bnRlZE5vZGUsIG5vZGUpKQotICAgICAgICBicmVhazsKLSAgICB9Ci0KLSAgICByZXR1cm4gbV9jb3VudFJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxhc3Qgbm9kZSBpbiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbGFzdCBub2RlIGluIHRoZSBsaXN0LgotICAgKi8KLSAgaW50IGdldExhc3QoKQotICB7Ci0KLSAgICBpbnQgc2l6ZSA9IG1fY291bnROb2Rlcy5zaXplKCk7Ci0KLSAgICByZXR1cm4gKHNpemUgPiAwKSA/IG1fY291bnROb2Rlcy5lbGVtZW50QXQoc2l6ZSAtIDEpIDogRFRNLk5VTEw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0NvdW50ZXJzVGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0NvdW50ZXJzVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTMyODU0My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Db3VudGVyc1RhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1OdW1iZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGlzIGEgdGFibGUgb2YgY291bnRlcnMsIGtleWVkIGJ5IEVsZW1OdW1iZXIgb2JqZWN0cywgZWFjaAotICogb2Ygd2hpY2ggaGFzIGEgbGlzdCBvZiBDb3VudGVyIG9iamVjdHMuICBUaGlzIHJlYWxseSBpc24ndCBhIHRydWUKLSAqIHRhYmxlLCBpdCBpcyBtb3JlIGxpa2UgYSBsaXN0IG9mIGxpc3RzICh0aGVyZSBtdXN0IGJlIGEgdGVjaG5pY2FsCi0gKiB0ZXJtIGZvciB0aGF0Li4uKS4KLSAqLwotcHVibGljIGNsYXNzIENvdW50ZXJzVGFibGUgZXh0ZW5kcyBIYXNodGFibGUKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgQ291bnRlcnNUYWJsZS4KLSAgICovCi0gIHB1YmxpYyBDb3VudGVyc1RhYmxlKCl7fQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxpc3Qgb2YgY291bnRlcnMgdGhhdCBjb3JyZXNwb25kcyB0bwotICAgKiB0aGUgZ2l2ZW4gRWxlbU51bWJlciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBudW1iZXJFbGVtIHRoZSBnaXZlbiB4c2w6bnVtYmVyIGVsZW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgY291bnRlcnMgdGhhdCBjb3JyZXNwb25kcyB0bwotICAgKiB0aGUgZ2l2ZW4gRWxlbU51bWJlciBvYmplY3QuCi0gICAqLwotICBWZWN0b3IgZ2V0Q291bnRlcnMoRWxlbU51bWJlciBudW1iZXJFbGVtKQotICB7Ci0KLSAgICBWZWN0b3IgY291bnRlcnMgPSAoVmVjdG9yKSB0aGlzLmdldChudW1iZXJFbGVtKTsKLQotICAgIHJldHVybiAobnVsbCA9PSBjb3VudGVycykgPyBwdXRFbGVtTnVtYmVyKG51bWJlckVsZW0pIDogY291bnRlcnM7Ci0gIH0KLQotICAvKioKLSAgICogUHV0IGEgY291bnRlciBpbnRvIHRoZSB0YWJsZSBhbmQgY3JlYXRlIGFuIGVtcHR5Ci0gICAqIHZlY3RvciBhcyBpdCdzIHZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gbnVtYmVyRWxlbSB0aGUgZ2l2ZW4geHNsOm51bWJlciBlbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuIGFuIGVtcHR5IHZlY3RvciB0byBiZSB1c2VkIHRvIHN0b3JlIGNvdW50cwotICAgKiBmb3IgdGhpcyBudW1iZXIgZWxlbWVudC4KLSAgICovCi0gIFZlY3RvciBwdXRFbGVtTnVtYmVyKEVsZW1OdW1iZXIgbnVtYmVyRWxlbSkKLSAgewotCi0gICAgVmVjdG9yIGNvdW50ZXJzID0gbmV3IFZlY3RvcigpOwotCi0gICAgdGhpcy5wdXQobnVtYmVyRWxlbSwgY291bnRlcnMpOwotCi0gICAgcmV0dXJuIGNvdW50ZXJzOwotICB9Ci0KLSAgLyoqCi0gICAqIFBsYWNlIHRvIGNvbGxlY3QgbmV3IGNvdW50ZXJzLgotICAgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgTm9kZVNldERUTSBtX25ld0ZvdW5kOwotCi0gIC8qKgotICAgKiBBZGQgYSBsaXN0IG9mIGNvdW50ZWQgbm9kZXMgdGhhdCB3ZXJlIGJ1aWx0IGluIGJhY2t3YXJkcyBkb2N1bWVudAotICAgKiBvcmRlciwgb3IgYSBsaXN0IG9mIGNvdW50ZWQgbm9kZXMgdGhhdCBhcmUgaW4gZm9yd2FyZHMgZG9jdW1lbnQKLSAgICogb3JkZXIuCi0gICAqCi0gICAqIEBwYXJhbSBmbGlzdCBWZWN0b3Igb2Ygbm9kZXMgYnVpbHQgaW4gZm9yd2FyZHMgZG9jdW1lbnQgb3JkZXIKLSAgICogQHBhcmFtIGJsaXN0IFZlY3RvciBvZiBub2RlcyBidWlsdCBpbiBiYWNrd2FyZHMgZG9jdW1lbnQgb3JkZXIKLSAgICovCi0gIHZvaWQgYXBwZW5kQnRvRkxpc3QoTm9kZVNldERUTSBmbGlzdCwgTm9kZVNldERUTSBibGlzdCkKLSAgewotCi0gICAgaW50IG4gPSBibGlzdC5zaXplKCk7Ci0KLSAgICBmb3IgKGludCBpID0gKG4gLSAxKTsgaSA+PSAwOyBpLS0pCi0gICAgewotICAgICAgZmxpc3QuYWRkRWxlbWVudChibGlzdC5pdGVtKGkpKTsKLSAgICB9Ci0gIH0KLQotICAvLyBGb3IgZGlhZ25vc3RpY3MKLQotICAvKiogTnVtYmVyIG9mIGNvdW50ZXJzIGNyZWF0ZWQgc28gZmFyICAgICAgICAgICovCi0gIHRyYW5zaWVudCBpbnQgbV9jb3VudGVyc01hZGUgPSAwOwotCi0gIC8qKgotICAgKiBDb3VudCBmb3J3YXJkIHVudGlsIHRoZSBnaXZlbiBub2RlIGlzIGZvdW5kLCBvciB1bnRpbAotICAgKiB3ZSBoYXZlIGxvb2tlZCB0byB0aGUgZ2l2ZW4gYW1vdW50LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggY29udGV4dCB0byB1c2UgIAotICAgKiBAcGFyYW0gbnVtYmVyRWxlbSBUaGUgZ2l2ZW4geHNsOm51bWJlciBlbGVtZW50LgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBjb3VudC4KLSAgICogCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgY291bnQsIG9yIDAgaWYgbm90IGZvdW5kLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgaW50IGNvdW50Tm9kZShYUGF0aENvbnRleHQgc3VwcG9ydCwgRWxlbU51bWJlciBudW1iZXJFbGVtLCBpbnQgbm9kZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvdW50ID0gMDsKLSAgICBWZWN0b3IgY291bnRlcnMgPSBnZXRDb3VudGVycyhudW1iZXJFbGVtKTsKLSAgICBpbnQgbkNvdW50ZXJzID0gY291bnRlcnMuc2l6ZSgpOwotCi0gICAgLy8gWFBhdGggY291bnRNYXRjaFBhdHRlcm4gPSBudW1iZXJFbGVtLmdldENvdW50TWF0Y2hQYXR0ZXJuKHN1cHBvcnQsIG5vZGUpOwotICAgIC8vIFhQYXRoIGZyb21NYXRjaFBhdHRlcm4gPSBudW1iZXJFbGVtLm1fZnJvbU1hdGNoUGF0dGVybjsKLSAgICBpbnQgdGFyZ2V0ID0gbnVtYmVyRWxlbS5nZXRUYXJnZXROb2RlKHN1cHBvcnQsIG5vZGUpOwotCi0gICAgaWYgKERUTS5OVUxMICE9IHRhcmdldCkKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5Db3VudGVyczsgaSsrKQotICAgICAgewotICAgICAgICBDb3VudGVyIGNvdW50ZXIgPSAoQ291bnRlcikgY291bnRlcnMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgIGNvdW50ID0gY291bnRlci5nZXRQcmV2aW91c2x5Q291bnRlZChzdXBwb3J0LCB0YXJnZXQpOwotCi0gICAgICAgIGlmIChjb3VudCA+IDApCi0gICAgICAgICAgcmV0dXJuIGNvdW50OwotICAgICAgfQotCi0gICAgICAvLyBJbiB0aGUgbG9vcCBiZWxvdywgd2UgY29sbGVjdCB0aGUgbm9kZXMgaW4gYmFja3dhcmRzIGRvYyBvcmRlciwgc28gCi0gICAgICAvLyB3ZSBkb24ndCBoYXZlIHRvIGRvIGluc2VydHMsIGJ1dCB0aGVuIHdlIHN0b3JlIHRoZSBub2RlcyBpbiBmb3J3YXJkcyAKLSAgICAgIC8vIGRvY3VtZW50IG9yZGVyLCBzbyB3ZSBkb24ndCBoYXZlIHRvIGluc2VydCBub2RlcyBpbnRvIHRoYXQgbGlzdCwgCi0gICAgICAvLyBzbyB0aGF0J3Mgd2hhdCB0aGUgYXBwZW5kQnRvRkxpc3Qgc3R1ZmYgaXMgYWxsIGFib3V0LiAgSW4gY2FzZXMgCi0gICAgICAvLyBvZiBmb3J3YXJkIGNvdW50aW5nIGJ5IG9uZSwgdGhpcyB3aWxsIG1lYW4gYSBzaW5nbGUgbm9kZSBjb3B5IGZyb20gCi0gICAgICAvLyB0aGUgYmFja3dhcmRzIGxpc3QgKG1fbmV3Rm91bmQpIHRvIHRoZSBmb3J3YXJkcyBsaXN0IChjb3VudGVyLm1fY291bnROb2RlcykuCi0gICAgICBjb3VudCA9IDA7Ci0gICAgICBpZiAobV9uZXdGb3VuZCA9PSBudWxsKQotICAgICAgICBtX25ld0ZvdW5kID0gbmV3IE5vZGVTZXREVE0oc3VwcG9ydC5nZXREVE1NYW5hZ2VyKCkpOwotCi0gICAgICBmb3IgKDsgRFRNLk5VTEwgIT0gdGFyZ2V0OwotICAgICAgICAgICAgICB0YXJnZXQgPSBudW1iZXJFbGVtLmdldFByZXZpb3VzTm9kZShzdXBwb3J0LCB0YXJnZXQpKQotICAgICAgewotCi0gICAgICAgIC8vIEZpcnN0IHRpbWUgaW4sIHdlIHNob3VsZCBub3QgaGF2ZSB0byBjaGVjayBmb3IgcHJldmlvdXMgY291bnRzLCAKLSAgICAgICAgLy8gc2luY2UgdGhlIG9yaWdpbmFsIHRhcmdldCBub2RlIHdhcyBhbHJlYWR5IGNoZWNrZWQgaW4gdGhlIAotICAgICAgICAvLyBibG9jayBhYm92ZS4KLSAgICAgICAgaWYgKDAgIT0gY291bnQpCi0gICAgICAgIHsKLSAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5Db3VudGVyczsgaSsrKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIENvdW50ZXIgY291bnRlciA9IChDb3VudGVyKSBjb3VudGVycy5lbGVtZW50QXQoaSk7Ci0gICAgICAgICAgICBpbnQgY2FjaGVMZW4gPSBjb3VudGVyLm1fY291bnROb2Rlcy5zaXplKCk7Ci0KLSAgICAgICAgICAgIGlmICgoY2FjaGVMZW4gPiAwKQotICAgICAgICAgICAgICAgICAgICAmJiAoY291bnRlci5tX2NvdW50Tm9kZXMuZWxlbWVudEF0KGNhY2hlTGVuCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIDEpID09IHRhcmdldCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGNvdW50ICs9IChjYWNoZUxlbiArIGNvdW50ZXIubV9jb3VudE5vZGVzU3RhcnRDb3VudCk7Ci0KLSAgICAgICAgICAgICAgaWYgKGNhY2hlTGVuID4gMCkKLSAgICAgICAgICAgICAgICBhcHBlbmRCdG9GTGlzdChjb3VudGVyLm1fY291bnROb2RlcywgbV9uZXdGb3VuZCk7Ci0KLSAgICAgICAgICAgICAgbV9uZXdGb3VuZC5yZW1vdmVBbGxFbGVtZW50cygpOwotCi0gICAgICAgICAgICAgIHJldHVybiBjb3VudDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBtX25ld0ZvdW5kLmFkZEVsZW1lbnQodGFyZ2V0KTsKLQotICAgICAgICBjb3VudCsrOwotICAgICAgfQotCi0gICAgICAvLyBJZiB3ZSBnb3QgdG8gdGhpcyBwb2ludCwgdGhlbiB3ZSBkaWRuJ3QgZmluZCBhIGNvdW50ZXIsIHNvIG1ha2UgCi0gICAgICAvLyBvbmUgYW5kIGFkZCBpdCB0byB0aGUgbGlzdC4KLSAgICAgIENvdW50ZXIgY291bnRlciA9IG5ldyBDb3VudGVyKG51bWJlckVsZW0sIG5ldyBOb2RlU2V0RFRNKHN1cHBvcnQuZ2V0RFRNTWFuYWdlcigpKSk7Ci0KLSAgICAgIG1fY291bnRlcnNNYWRlKys7ICAvLyBmb3IgZGlhZ25vc3RpY3MKLQotICAgICAgYXBwZW5kQnRvRkxpc3QoY291bnRlci5tX2NvdW50Tm9kZXMsIG1fbmV3Rm91bmQpOwotICAgICAgbV9uZXdGb3VuZC5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgY291bnRlcnMuYWRkRWxlbWVudChjb3VudGVyKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gY291bnQ7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0RlY2ltYWxUb1JvbWFuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9EZWNpbWFsVG9Sb21hbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhMmJjOWVlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0RlY2ltYWxUb1JvbWFuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogU3RydWN0dXJlIHRvIGhlbHAgaW4gY29udmVydGluZyBpbnRlZ2VycyB0byByb21hbiBudW1lcmFscwotICovCi1wdWJsaWMgY2xhc3MgRGVjaW1hbFRvUm9tYW4KLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRGVjaW1hbFRvUm9tYW4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBvc3RWYWx1ZSBNaW5pbXVtIHZhbHVlIGZvciBhIGdpdmVuIHJhbmdlIG9mIAotICAgKiByb21hbiBudW1iZXJzCi0gICAqIEBwYXJhbSBwb3N0TGV0dGVyIENvcnJlc3BvZGluZyBsZXR0ZXIgKHJvbWFuKSB0byBwb3N0VmFsdWUKLSAgICogQHBhcmFtIHByZVZhbHVlIFZhbHVlIG9mIGxhc3QgcHJlZml4ZWQgbnVtYmVyIHdpdGhpbiAKLSAgICogdGhhdCBzYW1lIHJhbmdlIChpLmUuIElWIGlmIHBvc3R2YWwgaXMgNSAoVikpCi0gICAqIEBwYXJhbSBwcmVMZXR0ZXIgQ29ycmVzcG9kaW5nIGxldHRlcihyb21hbikgdG8gcHJlVmFsdWUKLSAgICovCi0gIHB1YmxpYyBEZWNpbWFsVG9Sb21hbihsb25nIHBvc3RWYWx1ZSwgU3RyaW5nIHBvc3RMZXR0ZXIsIGxvbmcgcHJlVmFsdWUsCi0gICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcHJlTGV0dGVyKQotICB7Ci0KLSAgICB0aGlzLm1fcG9zdFZhbHVlID0gcG9zdFZhbHVlOwotICAgIHRoaXMubV9wb3N0TGV0dGVyID0gcG9zdExldHRlcjsKLSAgICB0aGlzLm1fcHJlVmFsdWUgPSBwcmVWYWx1ZTsKLSAgICB0aGlzLm1fcHJlTGV0dGVyID0gcHJlTGV0dGVyOwotICB9Ci0KLSAgLyoqIE1pbmltdW0gdmFsdWUgZm9yIGEgZ2l2ZW4gcmFuZ2Ugb2Ygcm9tYW4gbnVtYmVycyAgICAgICAgICAqLwotICBwdWJsaWMgbG9uZyBtX3Bvc3RWYWx1ZTsKLQotICAvKiogQ29ycmVzcG9kaW5nIGxldHRlciAocm9tYW4pIHRvIG1fcG9zdFZhbHVlICAgICAgICAgICovCi0gIHB1YmxpYyBTdHJpbmcgbV9wb3N0TGV0dGVyOwotCi0gIC8qKiBWYWx1ZSBvZiBsYXN0IHByZWZpeGVkIG51bWJlciB3aXRoaW4gdGhhdCBzYW1lIHJhbmdlICAqLwotICBwdWJsaWMgbG9uZyBtX3ByZVZhbHVlOwotCi0gIC8qKiBDb3JyZXNwb2RpbmcgbGV0dGVyIChyb21hbikgdG8gbV9wcmVWYWx1ZSAgICAgICAgICAqLwotICBwdWJsaWMgU3RyaW5nIG1fcHJlTGV0dGVyOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5SXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0tleUl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFmNGRlYWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5SXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5XYWxraW5nSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLktleURlY2xhcmF0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBvcHRpbWl6ZWQgaXRlcmF0b3IgZm9yIAotICogImtleSgpIiBwYXR0ZXJucy4gVGhpcyBpdGVyYXRvciBpbmNyZW1lbnRhbGx5IHdhbGtzIHRoZSAKLSAqIHNvdXJjZSB0cmVlIGFuZCBmaW5kcyBhbGwgdGhlIG5vZGVzIHRoYXQgbWF0Y2gKLSAqIGEgZ2l2ZW4ga2V5IG5hbWUgYW5kIG1hdGNoIHBhdHRlcm4uCi0gKi8KLXB1YmxpYyBjbGFzcyBLZXlJdGVyYXRvciBleHRlbmRzIFdhbGtpbmdJdGVyYXRvcgotewotICAKLSAgLyoqIFRoZSBrZXkgdGFibGUgdGhpcyBpdGVyYXRvciBpcyBhc3NvY2lhdGVkIHRvLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIEtleVRhYmxlIG1fa2V5VGFibGU7Ci0KLSAgLyoqIEtleSBuYW1lLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBRTmFtZSBtX25hbWU7Ci0gIAotICAvKiogCi0gICAqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB3aG9sZSBzb3VyY2UgdHJlZSBoYXMgYmVlbiB3YWxrZWQuICAgICAKLSAgICogVHJ1ZSBpZiB3ZSBzdGlsbCBuZWVkIHRvIGZpbmlzaCB3YWxraW5nIHRoZSB0cmVlLgotICAgKiAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBib29sZWFuIG1fbG9va0Zvck1vcmVOb2RlcyA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUga2V5IG5hbWUgZnJvbSBhIGtleSBkZWNsYXJhdGlvbiB0aGlzIGl0ZXJhdG9yIHdpbGwgcHJvY2VzcwotICAgKgotICAgKgotICAgKiBAcmV0dXJuIEtleSBuYW1lCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lOwotICB9Ci0KLSAgLyoqIFZlY3RvciBvZiBLZXkgZGVjbGFyYXRpb25zIGluIHRoZSBzdHlsZXNoZWV0LgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIFZlY3RvciBtX2tleURlY2xhcmF0aW9uczsKLQotICAvKioKLSAgICogR2V0IHRoZSBrZXkgZGVjbGFyYXRpb25zIGZyb20gdGhlIHN0eWxlc2hlZXQgCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gVmVjdG9yIGNvbnRhaW5pbmcgdGhlIGtleSBkZWNsYXJhdGlvbnMgZnJvbSB0aGUgc3R5bGVzaGVldAotICAgKi8KLSAgcHVibGljIFZlY3RvciBnZXRLZXlEZWNsYXJhdGlvbnMoKQotICB7Ci0gICAgcmV0dXJuIG1fa2V5RGVjbGFyYXRpb25zOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEtleUl0ZXJhdG9yCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IG5vZGUKLSAgICogQHBhcmFtIG5zY29udGV4dCBUaGUgcHJlZml4IHJlc29sdmVyIGZvciB0aGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBrZXkgbmFtZQotICAgKiBAcGFyYW0ga2V5RGVjbGFyYXRpb25zIFRoZSBrZXkgZGVjbGFyYXRpb25zIGZyb20gdGhlIHN0eWxlc2hlZXQgCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBzdGF0ZQotICAgKi8KLSAgcHVibGljIEtleUl0ZXJhdG9yKGludCBkb2MsIFByZWZpeFJlc29sdmVyIG5zY29udGV4dCwgUU5hbWUgbmFtZSwKLSAgICAgICAgICAgICAgICAgICAgIFZlY3RvciBrZXlEZWNsYXJhdGlvbnMsIFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotCi0gICAgc3VwZXIobnNjb250ZXh0KTsKLQotICAgIGludCBjdXJyZW50ID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBzZXRSb290KGN1cnJlbnQsIHhjdHh0KTsKLQotICAgIG1fbmFtZSA9IG5hbWU7Ci0gICAgbV9rZXlEZWNsYXJhdGlvbnMgPSBrZXlEZWNsYXJhdGlvbnM7Ci0gICAgbV9maXJzdFdhbGtlciA9IG5ldyBLZXlXYWxrZXIodGhpcyk7Ci0KLSAgICB0aGlzLnNldExhc3RVc2VkV2Fsa2VyKG1fZmlyc3RXYWxrZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIG5leHQgbm9kZSBpbiB0aGUgc2V0IGFuZCBhZHZhbmNlcyB0aGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIGl0ZXJhdG9yIGluIHRoZSBzZXQuIEFmdGVyIGEgTm9kZUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAqIHRvIG5leHROb2RlKCkgcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKiAKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotCi0gICAgLy8gSWYgdGhlIGNhY2hlIGlzIG9uLCBhbmQgdGhlIG5vZGUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdGhlbiAKLSAgICAvLyBqdXN0IHJldHVybiBmcm9tIHRoZSBsaXN0LgotICAgIGludCBuID0gc3VwZXIubmV4dE5vZGUoKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiLS0+ICIrKChudWxsID09IG4pID8gIm51bGwiIDogbi5nZXROb2RlTmFtZSgpKSk7Ci0gICAgcmV0dXJuIG47Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBvZiB0aGUga2V5IHRoYXQgdGhpcyBpdGVyYXRvciB3aWxsIGxvb2sgZm9yIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gbG9va3VwS2V5IHZhbHVlIG9mIHRoZSBrZXkgdG8gbG9vayBmb3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExvb2t1cEtleShYTUxTdHJpbmcgbG9va3VwS2V5KQotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInNldExvb2t1cEtleSAtIGxvb2t1cEtleTogIitsb29rdXBLZXkpOwotICAgICgoS2V5V2Fsa2VyKSBtX2ZpcnN0V2Fsa2VyKS5tX2xvb2t1cEtleSA9IGxvb2t1cEtleTsKLQotICAgIGludCBjb250ZXh0ID0gZ2V0Q29udGV4dCgpOwotICAgIERUTSBkdG0gPSB0aGlzLmdldERUTShjb250ZXh0KTsKLSAgICBtX2ZpcnN0V2Fsa2VyLnNldFJvb3QoZHRtLmdldERvY3VtZW50KCkpOwotICAgIHRoaXMuc2V0TGFzdFVzZWRXYWxrZXIobV9maXJzdFdhbGtlcik7Ci0gICAgdGhpcy5zZXROZXh0UG9zaXRpb24oMCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIEtleVRhYmxlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGl0ZXJhdG9yICAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGtleVRhYmxlLCB0aGUgS2V5VGFibGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaXRlcmF0b3IKLSAgICovCi0gIHZvaWQgc2V0S2V5VGFibGUoS2V5VGFibGUga2V5VGFibGUpCi0gIHsKLSAgICBtX2tleVRhYmxlID0ga2V5VGFibGU7Ci0gIH0gIAotICAKLSAgLyoqCi0gICAqIEFkZCB0aGlzIHZhbHVlKHJlZikgdG8gdGhlIHJlZnNUYWJsZSBpbiBLZXlUYWJsZSAgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByZWYgS2V5IHZhbHVlKHJlZikoZnJvbSBrZXkgdXNlIGZpZWxkKQotICAgKiBAcGFyYW0gbm9kZSBOb2RlIG1hdGNoaW5nIHRoYXQgcmVmIAotICAgKi8KLSAgdm9pZCBhZGRSZWZOb2RlKFhNTFN0cmluZyByZWYsIGludCBub2RlKQotICB7Ci0gICAgbV9rZXlUYWJsZS5hZGRSZWZOb2RlKHJlZiwgbm9kZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBJbmRpY2F0ZSB3aGV0aGVyIHdlIGhhdmUgd2Fsa2VkIHRoZSB3aG9sZSB0cmVlICAKLSAgICoKLSAgICogQHBhcmFtIGIgRmFsc2UgaWYgd2UgaGF2ZSB3YWxrZWQgdGhlIHdob2xlIHRyZWUKLSAgICovCi0gIHZvaWQgc2V0TG9va0Zvck1vcmVOb2Rlcyhib29sZWFuIGIpCi0gIHsKLSAgICBtX2xvb2tGb3JNb3JlTm9kZXMgPSBiOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHdlIGhhdmUgd2Fsa2VkIHRoZSB3aG9sZSB0cmVlICAKLSAgICoKLSAgICovCi0gIGJvb2xlYW4gZ2V0TG9va0Zvck1vcmVOb2RlcygpCi0gIHsKLSAgICByZXR1cm4gbV9sb29rRm9yTW9yZU5vZGVzOwotICB9Ci0gIAotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5TWFuYWdlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5TWFuYWdlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiN2M3ZTVlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0tleU1hbmFnZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgbWFuYWdlcyB0aGUga2V5IHRhYmxlcy4KLSAqLwotcHVibGljIGNsYXNzIEtleU1hbmFnZXIKLXsKLQotICAvKioKLSAgICogVGFibGUgb2YgdGFibGVzIG9mIGVsZW1lbnQga2V5cy4KLSAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLktleVRhYmxlCi0gICAqLwotICBwcml2YXRlIHRyYW5zaWVudCBWZWN0b3IgbV9rZXlfdGFibGVzID0gbnVsbDsKLQotICAvKioKLSAgICogR2l2ZW4gYSB2YWxpZCBlbGVtZW50IGtleSwgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIHN0YXRlCi0gICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IG5vZGUKLSAgICogQHBhcmFtIG5hbWUgVGhlIGtleSBlbGVtZW50IG5hbWUKLSAgICogQHBhcmFtIHJlZiBUaGUga2V5IHZhbHVlIHdlJ3JlIGxvb2tpbmcgZm9yIAotICAgKiBAcGFyYW0gbnNjb250ZXh0IFRoZSBwcmVmaXggcmVzb2x2ZXIgZm9yIHRoZSBleGVjdXRpb24gY29udGV4dAotICAgKgotICAgKiBAcmV0dXJuIEEgbm9kZWxpc3Qgb2Ygbm9kZXMgbWF0aGluZyB0aGUgZ2l2ZW4ga2V5Ci0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIExvY1BhdGhJdGVyYXRvciBnZXROb2RlU2V0RFRNQnlLZXkoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgZG9jLCBRTmFtZSBuYW1lLCBYTUxTdHJpbmcgcmVmLCBQcmVmaXhSZXNvbHZlciBuc2NvbnRleHQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBMb2NQYXRoSXRlcmF0b3IgbmwgPSBudWxsOwotICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgdGVtcGxhdGUgPSAoRWxlbVRlbXBsYXRlRWxlbWVudCkgbnNjb250ZXh0OyAgLy8geXVjayAtc2IKLQotICAgIGlmICgobnVsbCAhPSB0ZW1wbGF0ZSkKLSAgICAgICAgICAgICYmIG51bGwgIT0gdGVtcGxhdGUuZ2V0U3R5bGVzaGVldFJvb3QoKS5nZXRLZXlzQ29tcG9zZWQoKSkKLSAgICB7Ci0gICAgICBib29sZWFuIGZvdW5kRG9jID0gZmFsc2U7Ci0KLSAgICAgIGlmIChudWxsID09IG1fa2V5X3RhYmxlcykKLSAgICAgIHsKLSAgICAgICAgbV9rZXlfdGFibGVzID0gbmV3IFZlY3Rvcig0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IG5LZXlUYWJsZXMgPSBtX2tleV90YWJsZXMuc2l6ZSgpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbktleVRhYmxlczsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgS2V5VGFibGUga3QgPSAoS2V5VGFibGUpIG1fa2V5X3RhYmxlcy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgICAgICBpZiAoa3QuZ2V0S2V5VGFibGVOYW1lKCkuZXF1YWxzKG5hbWUpICYmIGRvYyA9PSBrdC5nZXREb2NLZXkoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBubCA9IGt0LmdldE5vZGVTZXREVE1CeUtleShuYW1lLCByZWYpOwotCi0gICAgICAgICAgICBpZiAobmwgIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZm91bmREb2MgPSB0cnVlOwotCi0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoKG51bGwgPT0gbmwpICYmIWZvdW5kRG9jIC8qICYmIG1fbmVlZFRvQnVpbGRLZXlzVGFibGUgKi8pCi0gICAgICB7Ci0gICAgICAgIEtleVRhYmxlIGt0ID0KLSAgICAgICAgICBuZXcgS2V5VGFibGUoZG9jLCBuc2NvbnRleHQsIG5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlLmdldFN0eWxlc2hlZXRSb290KCkuZ2V0S2V5c0NvbXBvc2VkKCksCi0gICAgICAgICAgICAgICAgICAgICAgIHhjdHh0KTsKLQotICAgICAgICBtX2tleV90YWJsZXMuYWRkRWxlbWVudChrdCk7Ci0KLSAgICAgICAgaWYgKGRvYyA9PSBrdC5nZXREb2NLZXkoKSkKLSAgICAgICAgewotICAgICAgICAgIGZvdW5kRG9jID0gdHJ1ZTsKLSAgICAgICAgICBubCA9IGt0LmdldE5vZGVTZXREVE1CeUtleShuYW1lLCByZWYpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG5sOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9LZXlSZWZJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5UmVmSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2MwODFlOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9LZXlSZWZJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkxvY1BhdGhJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuS2V5RGVjbGFyYXRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBvcHRpbWl6ZWQgaXRlcmF0b3IgZm9yIAotICogImtleSgpIiBwYXR0ZXJucy4gSXQgdXNlcyBhIEtleUl0ZXJhdG9yIHRvIHdhbGsgdGhlIAotICogc291cmNlIHRyZWUgYW5kIGluY3JlbWVudGFsbHkgYnVpbGQgYSBsaXN0IG9mIG5vZGVzIHRoYXQgbWF0Y2gKLSAqIGEgZ2l2ZW4ga2V5IG5hbWUsIG1hdGNoIHBhdHRlcm4gYW5kIHZhbHVlLiAgCi0gKi8KLXB1YmxpYyBjbGFzcyBLZXlSZWZJdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotCi0gIC8qKiBLZXkgbmFtZS4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIGZpbmFsIFFOYW1lIG1fbmFtZTsgICAgCi0gIAotICAvKiogVXNlIGZpZWxkIG9mIGtleSBmdW5jdGlvbi4KLSAgICogIEBzZXJpYWwgICAgICAgICAqLwotICBwcml2YXRlIGZpbmFsIFhNTFN0cmluZyBtX2xvb2t1cEtleTsgIAotICAKLSAgLyoqIE1haW4gS2V5IGl0ZXJhdG9yIGZvciB0aGlzIGl0ZXJhdG9yLgotICAgKiAgQHNlcmlhbCAgICAqLwotICBwcml2YXRlIGZpbmFsIEtleUl0ZXJhdG9yIG1fa2k7ICAgIAotICAKLSAgLyoqCi0gICAqIEdldCBrZXkgbmFtZQotICAgKgotICAgKgotICAgKiBAcmV0dXJuIEtleSBuYW1lCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbV9uYW1lOwotICB9Ci0gIAotICAKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgS2V5UmVmSXRlcmF0b3IKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHJlZiBLZXkgdmFsdWUgdG8gbWF0Y2gKLSAgICogQHBhcmFtIGtpIFRoZSBtYWluIGtleSBpdGVyYXRvciB1c2VkIHRvIHdhbGsgdGhlIHNvdXJjZSB0cmVlIAotICAgKi8KLSAgcHVibGljIEtleVJlZkl0ZXJhdG9yKFhNTFN0cmluZyByZWYsIEtleUl0ZXJhdG9yIGtpKQotICB7Ci0KLSAgICBzdXBlcihraS5nZXRQcmVmaXhSZXNvbHZlcigpKTsgICAKLSAgICBtX2tpID0ga2k7Ci0gICAgbV9uYW1lID0ga2kuZ2V0TmFtZSgpOwotICAgIG1fbG9va3VwS2V5ID0gcmVmOwotICAgIHRoaXMubV9leGVjQ29udGV4dCA9IGtpLmdldFhQYXRoQ29udGV4dCgpOwotICAgIHNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIG5leHQgbm9kZSBpbiB0aGUgc2V0IGFuZCBhZHZhbmNlcyB0aGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIGl0ZXJhdG9yIGluIHRoZSBzZXQuIEFmdGVyIGEgTm9kZUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAqIHRvIG5leHROb2RlKCkgcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKiAKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotCi0gICBpZiAobV9mb3VuZExhc3QpCi0gICB7Ci0gICAgICBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICB9Ci0gICAgCi0gICAgLy8gSWYgdGhlIGNhY2hlIGlzIG9uLCBhbmQgdGhlIG5vZGUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdGhlbiAKLSAgICAvLyBqdXN0IHJldHVybiBmcm9tIHRoZSBsaXN0LgotICAgIE5vZGVTZXREVE0gbV9jYWNoZWROb2RlcyA9IGdldENhY2hlZE5vZGVzKCk7Ci0gICAgCi0gICAgLy8gV2UgYXJlIG5vdCB1c2luZyB0aGUgTm9kZVNldERUTSBtZXRob2RzIGdldEN1cnJlbnRQb3MoKSBhbmQgbmV4dE5vZGUoKQotICAgIC8vIGluIHRoaXMgY2FzZSBiZWNhdXNlIHRoZSBub2Rlc2V0IGlzIG5vdCBjbG9uZWQgYW5kIHRoZXJlZm9yZQotICAgIC8vIHRoZSBwb3NpdGlvbnMgaXQgaW5kaWNhdGVzIG1heSBub3QgYmUgYXNzb2NpYXRlZCB3aXRoIHRoZSAKLSAgICAvLyBjdXJyZW50IGl0ZXJhdG9yLgotICAgIGlmICgobnVsbCAhPSBtX2NhY2hlZE5vZGVzKQotICAgICAgICAgICAgJiYgKG1fbmV4dCA8IG1fY2FjaGVkTm9kZXMuc2l6ZSgpKSkgICAgICAgIAotICAgIHsKLSAgICAgIGludCBuZXh0ID0gbV9jYWNoZWROb2Rlcy5lbGVtZW50QXQobV9uZXh0KTsgCi0gICAgICB0aGlzLnNldEN1cnJlbnRQb3MoKyttX25leHQpOyAKLSAgICAgIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgICAgCi0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9ICAgIAotCi0gICAgaW50IG5leHQgPSBEVE0uTlVMTDsgICAgICAgCi0gICAgaWYgKCBtX2tpLmdldExvb2tGb3JNb3JlTm9kZXMoKSkgCi0gICAgewotICAgICAgKChLZXlXYWxrZXIpbV9raS5nZXRGaXJzdFdhbGtlcigpKS5tX2xvb2t1cEtleSA9IG1fbG9va3VwS2V5OwotICAgICAgbmV4dCA9IG1fa2kubmV4dE5vZGUoKTsgICAgICAgIAotICAgIH0KLSAgICAKLSAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dCkKLSAgICB7ICAKLSAgICAgIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgICAgdGhpcy5zZXRDdXJyZW50UG9zKCsrbV9uZXh0KTsKLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7ICAgICAgICAgICAgICAgICAgICAgIAotICAgIAotICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgTG9jUGF0aEl0ZXJhdG9yIHRoYXQgaG9sZHMgdGhlIHNhbWUgCi0gICAqIHBvc2l0aW9uIGFzIHRoaXMgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gQSBjbG9uZSBvZiB0aGlzIGl0ZXJhdG9yIHRoYXQgaG9sZHMgdGhlIHNhbWUgbm9kZSBwb3NpdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiAKLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotICAgIC8vIEkgd29uZGVyIGlmIHdlIHJlYWxseSB3YW50IHRvIGNsb25lIHRoZSBzZWNvbmQgdGltZS4gIE15cmlhbSByZXZpZXcuCi0gICAgS2V5UmVmSXRlcmF0b3IgY2xvbmUgPSAoS2V5UmVmSXRlcmF0b3Ipc3VwZXIuY2xvbmUoKTsKLSAgICAvLyBjbG9uZS5tX2tpID0gKEtleUl0ZXJhdG9yKW1fa2kuY2xvbmUoKTsKLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotICAKLS8vICAvKioKLS8vICAgKiBHZXQgYSBjbG9uZWQgSXRlcmF0b3IgdGhhdCBpcyByZXNldCB0byB0aGUgYmVnaW5uaW5nIAotLy8gICAqIG9mIHRoZSBxdWVyeS4KLS8vICAgKgotLy8gICAqIEByZXR1cm4gQSBjbG9uZWQgTm9kZUl0ZXJhdG9yIHNldCBvZiB0aGUgc3RhcnQgb2YgdGhlIHF1ZXJ5LgotLy8gICAqCi0vLyAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotLy8gICAqLwotLy8gIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVXaXRoUmVzZXQoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLS8vICB7Ci0vLyAgICBLZXlSZWZJdGVyYXRvciBjbG9uZSA9IChLZXlSZWZJdGVyYXRvcilzdXBlci5jbG9uZVdpdGhSZXNldCgpOwotLy8KLS8vICAgIHJldHVybiBjbG9uZTsKLS8vICB9Ci0gIAotICAvKioKLSAgICogUmVzZXQgdGhlIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgc3VwZXIucmVzZXQoKTsKLSAgICAvLyBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotICAgIHNldEN1cnJlbnRQb3MoMCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiAgRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgeyAgICAKLSAgICAvLyBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdG8gZGV0YWNoIGF0IGFsbCBmb3IgdGhpcyBpdGVyYXRvci4KLSAgICAvLyBNeXJpYW0gbmVlZHMgdG8gcmV2aWV3LiAgLXNiLgotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBBZGQgYSBub2RlIG1hdGNoaW5nIHRoaXMgcmVmIHRvIHRoZSBjYWNoZWQgbm9kZXMgZm9yIHRoaXMgaXRlcmF0b3IgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gYWRkIHRvIGNhY2hlZCBub2RlcwotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTm9kZShpbnQgbm9kZSkgCi0gIHsKLSAgICBOb2RlU2V0RFRNIG1fY2FjaGVkTm9kZXMgPSBnZXRDYWNoZWROb2RlcygpOwotICAgIGlmIChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgewotICAgICAgaWYoIW1fY2FjaGVkTm9kZXMuY29udGFpbnMobm9kZSkpCi0gICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChub2RlKTsKLSAgICB9Ci0gIH0gIAotICAgICAgIAotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5VGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL0tleVRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIyOWU4ZWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5VGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotLy9pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotLy9pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5ET01IZWxwZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuS2V5RGVjbGFyYXRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Mb2NQYXRoSXRlcmF0b3I7Ci0KLS8vIGltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmR0bS4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGFibGUgb2YgZWxlbWVudCBrZXlzLCBrZXllZCBieSBkb2N1bWVudCBub2RlLiAgQW4gaW5zdGFuY2Ugb2YgdGhpcwotICogY2xhc3MgaXMga2V5ZWQgYnkgYSBEb2N1bWVudCBub2RlIHRoYXQgc2hvdWxkIGJlIG1hdGNoZWQgd2l0aCB0aGUKLSAqIHJvb3Qgb2YgdGhlIGN1cnJlbnQgY29udGV4dC4gIEl0IGNvbnRhaW5zIGEgdGFibGUgb2YgbmFtZSBtYXBwaW5ncwotICogdG8gdGFibGVzIHRoYXQgY29udGFpbiBtYXBwaW5ncyBvZiBpZGVudGlmaWVyIHZhbHVlcyB0byBub2Rlcy4KLSAqLwotcHVibGljIGNsYXNzIEtleVRhYmxlCi17Ci0KLSAgLyoqCi0gICAqIFRoZSBkb2N1bWVudCBrZXkuICBUaGlzIHRhYmxlIHNob3VsZCBvbmx5IGJlIHVzZWQgd2l0aCBjb250ZXh0cwotICAgKiB3aG9zZSBEb2N1bWVudCByb290cyBtYXRjaCB0aGlzIGtleS4KLSAgICovCi0gIHByaXZhdGUgaW50IG1fZG9jS2V5OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGRvY3VtZW50IHJvb3QgbWF0Y2hpbmcgdGhpcyBrZXkuICAKLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgcm9vdCBtYXRjaGluZyB0aGlzIGtleQotICAgKi8KLSAgcHVibGljIGludCBnZXREb2NLZXkoKQotICB7Ci0gICAgcmV0dXJuIG1fZG9jS2V5OwotICB9Ci0KLSAgLyoqIAotICAgKiBUaGUgbWFpbiBpdGVyYXRvciB0aGF0IHdpbGwgd2FsayB0aHJvdWdoIHRoZSBzb3VyY2UgIAotICAgKiB0cmVlIGZvciB0aGlzIGtleS4KLSAgICovCi0gIHByaXZhdGUgS2V5SXRlcmF0b3IgbV9rZXlJdGVyOwotICAKLSAgLyoqCi0gICAqIEhhc2h0YWJsZSBvZiBrZXlzLgotICAgKiBUaGUgdGFibGUgaXM6Ci0gICAqIGEpIGtleWVkIGJ5IGtleSBuYW1lLAotICAgKiBiKSB3aXRoIGEgdmFsdWUgdGhhdCBpcyBhIGhhc2h0YWJsZSBrZXllZCBieSBrZXkgdmFsdWVzIAotICAgKiB3aXRoIGF0IHZhbHVlIG9mIEtleVJlZkl0ZXJhdG9yKGNsb25lZCkuCi0gICAqLwotICBwcml2YXRlIEhhc2h0YWJsZSBtX2RlZnNUYWJsZTsKLQotICAvKioKLSAgICogQnVpbGQgYSBrZXlzIHRhYmxlLgotICAgKiBAcGFyYW0gZG9jIFRoZSBvd25lciBkb2N1bWVudCBrZXkuCi0gICAqIEBwYXJhbSBuc2NvbnRleHQgVGhlIHN0eWxlc2hlZXQncyBuYW1lc3BhY2UgY29udGV4dC4KLSAgICogQHBhcmFtIG5hbWUgVGhlIGtleSBuYW1lCi0gICAqIEBwYXJhbSBrZXlEZWNsYXJhdGlvbnMgVGhlIHN0eWxlc2hlZXQncyB4c2w6a2V5IGRlY2xhcmF0aW9ucy4KLSAgICogQHBhcmFtIHhtbExpYWlzb24gVGhlIHBhcnNlciBsaWFpc29uIGZvciBzdXBwb3J0IG9mIGdldE5vZGVEYXRhKHVzZU5vZGUpLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBLZXlUYWJsZSgKLSAgICAgICAgICBpbnQgZG9jLCBQcmVmaXhSZXNvbHZlciBuc2NvbnRleHQsIFFOYW1lIG5hbWUsIFZlY3RvciBrZXlEZWNsYXJhdGlvbnMsIFhQYXRoQ29udGV4dCB4bWxMaWFpc29uKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV9kb2NLZXkgPSBkb2M7Ci0gICAgbV9rZXlJdGVyID0gbmV3IEtleUl0ZXJhdG9yKGRvYywgbnNjb250ZXh0LCBuYW1lLCBrZXlEZWNsYXJhdGlvbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbExpYWlzb24pOwotICAgIG1fa2V5SXRlci5zZXRLZXlUYWJsZSh0aGlzKTsKLSAgfSAgCi0KLSAgLyoqCi0gICAqIEdpdmVuIGEgdmFsaWQgZWxlbWVudCBrZXksIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBub2RlIGxpc3QuCi0gICAqIAotICAgKiBAcGFyYW0gVGhlIG5hbWUgb2YgdGhlIGtleSwgd2hpY2ggbXVzdCBtYXRjaCB0aGUgJ25hbWUnIGF0dHJpYnV0ZSBvbiB4c2w6a2V5LgotICAgKiBAcGFyYW0gcmVmIFRoZSB2YWx1ZSB0aGF0IG11c3QgbWF0Y2ggdGhlIHZhbHVlIGZvdW5kIGJ5IHRoZSAnbWF0Y2gnIGF0dHJpYnV0ZSBvbiB4c2w6a2V5LgotICAgKiBAcmV0dXJuIElmIHRoZSBuYW1lIHdhcyBub3QgZGVjbGFyZWQgd2l0aCB4c2w6a2V5LCB0aGlzIHdpbGwgcmV0dXJuIG51bGwsCi0gICAqIGlmIHRoZSBpZGVudGlmaWVyIGlzIG5vdCBmb3VuZCwgaXQgd2lsbCByZXR1cm4gbnVsbCwKLSAgICogb3RoZXJ3aXNlIGl0IHdpbGwgcmV0dXJuIGEgTG9jUGF0aEl0ZXJhdG9yIGluc3RhbmNlLgotICAgKi8KLSAgcHVibGljIExvY1BhdGhJdGVyYXRvciBnZXROb2RlU2V0RFRNQnlLZXkoUU5hbWUgbmFtZSwgWE1MU3RyaW5nIHJlZikKLSAgewotCi0gICAgS2V5SXRlcmF0b3Iga2k7Ci0gICAgS2V5UmVmSXRlcmF0b3Iga2lSZWY7Ci0gICAgSGFzaHRhYmxlIHJlZnNUYWJsZSA9IG51bGw7Ci0KLSAgICAvLyBGaXJzdCBsb29rIGZvciB0aGUga2V5IGluIHRoZSBleGlzdGluZyBrZXkgbmFtZXMgdGFibGUKLSAgICBpZiAobV9kZWZzVGFibGUgIT0gbnVsbCkKLSAgICB7Ci0gICAgICByZWZzVGFibGUgPSAoSGFzaHRhYmxlKW1fZGVmc1RhYmxlLmdldChuYW1lKTsKLSAgICAgIGlmIChyZWZzVGFibGUgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgT2JqZWN0IGtpT2JqID0gcmVmc1RhYmxlLmdldChyZWYpOwotICAgICAgICBpZiAoa2lPYmogIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIC8vIEFuIGVudHJ5IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGtleSBuYW1lIGFuZCB2YWx1ZS4KLSAgICAgICAgICAvLyBSZXR1cm4gYSBjbG9uZSBvZiB0aGUgbm9kZSBpdGVyYXRvciBmb3VuZC4KLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBjbG9uZSB3aXRoIHJlc2V0Pz8KLSAgICAgICAgICAgIGtpUmVmID0gKEtleVJlZkl0ZXJhdG9yKSgoS2V5UmVmSXRlcmF0b3Ipa2lPYmopLmNsb25lKCk7Ci0gICAgICAgICAgICByZXR1cm4ga2lSZWY7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGtpID0gbnVsbDsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBObyBlbnRyeSB3YXMgZm91bmQgZm9yIHRoaXMga2V5IG5hbWUgYW5kIHZhbHVlLiBDcmVhdGUgb25lLgotICAgIHsKLSAgICAgIGlmIChtX2RlZnNUYWJsZSA9PSBudWxsKQotICAgICAgICBtX2RlZnNUYWJsZSA9IG5ldyBIYXNodGFibGUoKTsKLSAgICAgIGlmIChyZWZzVGFibGUgPT0gbnVsbCkKLSAgICAgICAgcmVmc1RhYmxlID0gbmV3IEhhc2h0YWJsZSgpOwotICAgICAgCi0gICAgICAvLyBpbml0aWFsaXplIHdhbGtlciBvbmx5IG9uY2UhCi0gICAgICBpZiAobV9rZXlJdGVyLmdldEZpcnN0V2Fsa2VyKCkuZ2V0Um9vdCgpID09IERUTS5OVUxMKQotICAgICAgICBtX2tleUl0ZXIuc2V0TG9va3VwS2V5KHJlZik7Ci0gICAgICBlbHNlCi0gICAgICAgICgoS2V5V2Fsa2VyKW1fa2V5SXRlci5nZXRGaXJzdFdhbGtlcigpKS5tX2xvb2t1cEtleSA9IHJlZjsKLSAgICAgIGtpUmVmID0gbmV3IEtleVJlZkl0ZXJhdG9yKHJlZiwgbV9rZXlJdGVyKTsKLSAgICAgIHJlZnNUYWJsZS5wdXQocmVmLCBraVJlZik7Ci0gICAgICBtX2RlZnNUYWJsZS5wdXQobmFtZSxyZWZzVGFibGUpOwotICAgICAgcmV0dXJuIGtpUmVmOyAgICAgICAgICAgICAgCi0gICAgfSAKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgS2V5IE5hbWUgZm9yIHRoaXMgS2V5VGFibGUgIAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIEtleSBuYW1lCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0S2V5VGFibGVOYW1lKCkKLSAgewotICAgIHJldHVybiBtX2tleUl0ZXIuZ2V0TmFtZSgpOwotICB9Ci0gIAotICAvKioKLSAgICogQWRkIHRoaXMgbm9kZSB0byB0aGUgbm9kZWxpc3QgbWF0Y2hpbmcgdGhpcyBrZXkgdmFsdWUuIAotICAgKiBJZiB0aGVyZSB3YXMgbm8gZXhpc3RpbmcgZW50cnkgZm9yIHRoYXQga2V5IHZhbHVlLCBjcmVhdGUKLSAgICogb25lLiAgIAotICAgKgotICAgKiBAcGFyYW0gcmVmIEtleSByZWYoZnJvbSBrZXkgdXNlIGZpZWxkKQotICAgKiBAcGFyYW0gbm9kZSBOb2RlIG1hdGNoaW5nIHRoYXQgcmVmIAotICAgKi8KLSAgdm9pZCBhZGRSZWZOb2RlKFhNTFN0cmluZyByZWYsIGludCBub2RlKQotICB7Ci0gICAgS2V5UmVmSXRlcmF0b3Iga2lSZWYgPSBudWxsOwotICAgIEhhc2h0YWJsZSByZWZzVGFibGUgPSBudWxsOwotICAgIGlmIChtX2RlZnNUYWJsZSAhPSBudWxsKQotICAgIHsKLSAgICAgIHJlZnNUYWJsZSA9IChIYXNodGFibGUpbV9kZWZzVGFibGUuZ2V0KGdldEtleVRhYmxlTmFtZSgpKTsKLSAgICAgIGlmIChyZWZzVGFibGUgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgT2JqZWN0IGtpT2JqID0gcmVmc1RhYmxlLmdldChyZWYpOwotICAgICAgICBpZiAoa2lPYmogIT0gbnVsbCkKLSAgICAgICAgeyAgICAgICAgICAKLSAgICAgICAgICBraVJlZiA9IChLZXlSZWZJdGVyYXRvcilraU9iajsgICAgICAgICAgICAKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBpZiAoa2lSZWYgPT0gbnVsbCkKLSAgICB7ICAKLSAgICAgIGlmIChtX2RlZnNUYWJsZSA9PSBudWxsKQotICAgICAgICBtX2RlZnNUYWJsZSA9IG5ldyBIYXNodGFibGUoKTsKLSAgICAgIGlmIChyZWZzVGFibGUgPT0gbnVsbCkKLSAgICAgIHsgIAotICAgICAgICByZWZzVGFibGUgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgICAgIG1fZGVmc1RhYmxlLnB1dChnZXRLZXlUYWJsZU5hbWUoKSxyZWZzVGFibGUpOwotICAgICAgfQotICAgICAga2lSZWYgPSBuZXcgS2V5UmVmSXRlcmF0b3IocmVmLCBtX2tleUl0ZXIpOwotICAgICAgcmVmc1RhYmxlLnB1dChyZWYsIGtpUmVmKTsgICAgICAKLSAgICB9Ci0gICAga2lSZWYuYWRkTm9kZShub2RlKTsgCi0gIH0KLSAgCi0gIAotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvS2V5V2Fsa2VyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9LZXlXYWxrZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTEzNjJlNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9LZXlXYWxrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Mb2NQYXRoSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLktleURlY2xhcmF0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuQXhlc1dhbGtlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBXYWxrZXIgZm9yIGEgS2V5KCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBLZXlXYWxrZXIgZXh0ZW5kcyBBeGVzV2Fsa2VyCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEtleVdhbGtlciB1c2luZyBhIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIGxvY1BhdGhJdGVyYXRvcjogdGhpcyBpcyB1c3VhbGx5IGEgS2V5SXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBLZXlXYWxrZXIoTG9jUGF0aEl0ZXJhdG9yIGxvY1BhdGhJdGVyYXRvcikKLSAgewotICAgIHN1cGVyKGxvY1BhdGhJdGVyYXRvciwgQXhpcy5ERVNDRU5EQU5UT1JTRUxGKTsKLSAgfQotCi0gIC8qKgotICAgKiAgU2V0IHRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIuCi0gICAqCi0gICAqIEBwYXJhbSByb290IERvY3VtZW50IHJvb3Qgbm9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgcm9vdCkKLSAgewotCi0gICAgbV9uZXh0QXR0ciA9IERUTS5OVUxMOwotICAgIG1fZm91bmRBdHRycyA9IGZhbHNlOwotCi0gICAgc3VwZXIuc2V0Um9vdChyb290KTsKLSAgfQotCi0gIC8qKiBGaXJzdCBhdHRyaWJ1dGUgb2YgdGhlIGN1cnJlbnQgbm9kZS4gICAgICAqLwotICB0cmFuc2llbnQgaW50IG1fbmV4dEF0dHI7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB0aGF0IGF0dGlidXRlIG5vZGVzIHdlcmUgZm91bmQgZm9yIHRoZSBjdXJyZW50IG5vZGUgICAgKi8KLSAgdHJhbnNpZW50IGJvb2xlYW4gbV9mb3VuZEF0dHJzOwotCi0gIC8qKiBLZXkgdmFsdWUgdGhhdCB0aGlzIGlzIGxvb2tpbmcgZm9yLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAgKi8KLSAgWE1MU3RyaW5nIG1fbG9va3VwS2V5OwotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiBkb2N1bWVudCBvcmRlciBvbiB0aGUgYXhlcy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGZvdW5kIG9yIG51bGwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotCi0gICAgaW50IGN1cnJlbnROb2RlID0gZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBEVE0gZHRtID0gdGhpcy5tX2xwaS5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0oY3VycmVudE5vZGUpOwotICAgIGlmICghbV9mb3VuZEF0dHJzKQotICAgIHsKLSAgICAgIG1fbmV4dEF0dHIgPSBkdG0uZ2V0Rmlyc3RBdHRyaWJ1dGUoY3VycmVudE5vZGUpOwotICAgICAgbV9mb3VuZEF0dHJzID0gdHJ1ZTsKLSAgICAgIGlmIChEVE0uTlVMTCAhPSBtX25leHRBdHRyKQotICAgICAgICByZXR1cm4gbV9uZXh0QXR0cjsKLSAgICB9IAotICAgIGVsc2UgaWYgKERUTS5OVUxMICE9IG1fbmV4dEF0dHIpCi0gICAgewotICAgICAgbV9uZXh0QXR0ciA9IGR0bS5nZXROZXh0QXR0cmlidXRlKG1fbmV4dEF0dHIpOwotICAgICAgaWYgKERUTS5OVUxMICE9IG1fbmV4dEF0dHIpCi0gICAgICAgIHJldHVybiBtX25leHRBdHRyOwotICAgIH0KLQotICAgIGludCBuZXh0ID0gc3VwZXIuZ2V0TmV4dE5vZGUoKTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgICAgbV9mb3VuZEF0dHJzID0gZmFsc2U7Ci0KLSAgICByZXR1cm4gbmV4dDsKLSAgfQotCi0gIC8qKgotICAgKiAgVGVzdCB3aGV0aGVyIGEgc3BlY2lmaWVkIG5vZGUgaXMgdmlzaWJsZSBpbiB0aGUgbG9naWNhbCB2aWV3IG9mIGEKLSAgICogVHJlZVdhbGtlciBvciBOb2RlSXRlcmF0b3IuIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYnkgdGhlCi0gICAqIGltcGxlbWVudGF0aW9uIG9mIFRyZWVXYWxrZXIgYW5kIE5vZGVJdGVyYXRvcjsgaXQgaXMgbm90IGludGVuZGVkIHRvCi0gICAqIGJlIGNhbGxlZCBkaXJlY3RseSBmcm9tIHVzZXIgY29kZS4KLSAgICogCi0gICAqIEBwYXJhbSB0ZXN0bm9kZSAgVGhlIG5vZGUgdG8gY2hlY2sgdG8gc2VlIGlmIGl0IHBhc3NlcyB0aGUgZmlsdGVyIG9yIG5vdC4KLSAgICoKLSAgICogQHJldHVybiAgYSBjb25zdGFudCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbm9kZSBpcyBhY2NlcHRlZCwKLSAgICogICByZWplY3RlZCwgb3Igc2tpcHBlZCwgYXMgZGVmaW5lZCAgYWJvdmUgLgotICAgKi8KLSAgcHVibGljIHNob3J0IGFjY2VwdE5vZGUoaW50IHRlc3ROb2RlKQotICB7Ci0gICAgYm9vbGVhbiBmb3VuZEtleSA9IGZhbHNlOwotICAgIEtleUl0ZXJhdG9yIGtpID0gKEtleUl0ZXJhdG9yKSBtX2xwaTsKLSAgICBWZWN0b3Iga2V5cyA9IGtpLmdldEtleURlY2xhcmF0aW9ucygpOwotCi0gICAgUU5hbWUgbmFtZSA9IGtpLmdldE5hbWUoKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBYTUxTdHJpbmcgbG9va3VwS2V5ID0gbV9sb29rdXBLZXk7Ci0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibG9va3VwS2V5OiAiK2xvb2t1cEtleSk7Ci0gICAgICBpbnQgbkRlY2xhcmF0aW9ucyA9IGtleXMuc2l6ZSgpOwotCi0gICAgICAvLyBXYWxrIHRocm91Z2ggZWFjaCBvZiB0aGUgZGVjbGFyYXRpb25zIG1hZGUgd2l0aCB4c2w6a2V5Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5EZWNsYXJhdGlvbnM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgS2V5RGVjbGFyYXRpb24ga2QgPSAoS2V5RGVjbGFyYXRpb24pIGtleXMuZWxlbWVudEF0KGkpOwotCi0gICAgICAgIC8vIE9ubHkgY29udGludWUgaWYgdGhlIG5hbWUgb24gdGhpcyBrZXkgZGVjbGFyYXRpb24KLSAgICAgICAgLy8gbWF0Y2hlcyB0aGUgbmFtZSBvbiB0aGUgaXRlcmF0b3IgZm9yIHRoaXMgd2Fsa2VyLiAKLSAgICAgICAgaWYoIWtkLmdldE5hbWUoKS5lcXVhbHMobmFtZSkpIAotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRLZXkgPSB0cnVlOwotICAgICAgICBraS5nZXRYUGF0aENvbnRleHQoKS5zZXROYW1lc3BhY2VDb250ZXh0KGtpLmdldFByZWZpeFJlc29sdmVyKCkpOwotCi0gICAgICAgIC8vIFNlZSBpZiBvdXIgbm9kZSBtYXRjaGVzIHRoZSBnaXZlbiBrZXkgZGVjbGFyYXRpb24gYWNjb3JkaW5nIHRvIAotICAgICAgICAvLyB0aGUgbWF0Y2ggYXR0cmlidXRlIG9uIHhzbDprZXkuCi0gICAgICAgIGRvdWJsZSBzY29yZSA9IGtkLmdldE1hdGNoKCkuZ2V0TWF0Y2hTY29yZShraS5nZXRYUGF0aENvbnRleHQoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3ROb2RlKTsKLQotICAgICAgICBpZiAoc2NvcmUgPT0ga2QuZ2V0TWF0Y2goKS5NQVRDSF9TQ09SRV9OT05FKQotICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAgCi0gICAgICAgICAgICAgICAgCi0gICAgICAgIC8vIFF1ZXJ5IGZyb20gdGhlIG5vZGUsIGFjY29yZGluZyB0aGUgdGhlIHNlbGVjdCBwYXR0ZXJuIGluIHRoZQotICAgICAgICAvLyB1c2UgYXR0cmlidXRlIGluIHhzbDprZXkuCi0gICAgICAgIFhPYmplY3QgeHVzZSA9IGtkLmdldFVzZSgpLmV4ZWN1dGUoa2kuZ2V0WFBhdGhDb250ZXh0KCksIHRlc3ROb2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpLmdldFByZWZpeFJlc29sdmVyKCkpOwotCi0gICAgICAgIGlmICh4dXNlLmdldFR5cGUoKSAhPSB4dXNlLkNMQVNTX05PREVTRVQpCi0gICAgICAgIHsKLSAgICAgICAgICBYTUxTdHJpbmcgZXhwclJlc3VsdCA9IHh1c2UueHN0cigpOwotICAgICAgICAgICgoS2V5SXRlcmF0b3IpbV9scGkpLmFkZFJlZk5vZGUoZXhwclJlc3VsdCwgdGVzdE5vZGUpOwotICAgICAgICAgIAotICAgICAgICAgIGlmIChsb29rdXBLZXkuZXF1YWxzKGV4cHJSZXN1bHQpKQotICAgICAgICAgICAgcmV0dXJuIERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgRFRNSXRlcmF0b3IgbmwgPSB4dXNlLml0ZXIoKTsKLSAgICAgICAgICBpbnQgdXNlTm9kZTsKLSAgICAgICAgICBzaG9ydCByZXN1bHQgPSAtMTsKLSAgICAgICAgICAvKgotICAgICAgICAgIFdlIGFyZSB3YWxraW5nIHRocm91Z2ggYWxsIHRoZSBub2RlcyBpbiB0aGlzIG5vZGVzZXQKLSAgICAgICAgICByYXRoZXIgdGhhbiBzdG9wcGluZyB3aGVuIHdlIGZpbmQgdGhlIG9uZSB3ZSdyZSBsb29raW5nCi0gICAgICAgICAgZm9yIGJlY2F1c2Ugd2UgZG9uJ3QgY3VycmVudGx5IHNhdmUgdGhlIHN0YXRlIG9mIEtleVdhbGtlcgotICAgICAgICAgIHN1Y2ggdGhhdCB0aGUgbmV4dCB0aW1lIGl0IGdldHMgY2FsbGVkIGl0IHdvdWxkIGNvbnRpbnVlCi0gICAgICAgICAgdG8gbG9vayBpbiB0aGlzIG5vZGVzZXQgZm9yIGFueSBmdXJ0aGVyIG1hdGNoZXMuIAotICAgICAgICAgIFRPRE86IFRyeSB0byBzYXZlIHRoZSBzdGF0ZSBvZiBLZXlXYWxrZXIsIGkuZS4ga2VlcCB0aGlzIG5vZGUKLSAgICAgICAgICBpdGVyYXRvciBzYXZlZCBzb21ld2hlcmUgYW5kIGZpbmlzaCB3YWxraW5nIHRocm91Z2ggaXRzIG5vZGVzCi0gICAgICAgICAgdGhlIG5leHQgdGltZSBLZXlXYWxrZXIgaXMgY2FsbGVkIGJlZm9yZSB3ZSBsb29rIGZvciBhbnkgbmV3Ci0gICAgICAgICAgbWF0Y2hlcy4gV2hhdCBpZiB0aGUgbmV4dCBjYWxsIGlzIGZvciB0aGUgc2FtZSBtYXRjaCt1c2UgCi0gICAgICAgICAgY29tYmluYXRpb24/PwotICAgICAgICAgICovCi0gICAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9ICh1c2VOb2RlID0gbmwubmV4dE5vZGUoKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgRFRNIGR0bSA9IGdldERUTSh1c2VOb2RlKTsKLSAgICAgICAgICAgIFhNTFN0cmluZyBleHByUmVzdWx0ID0gZHRtLmdldFN0cmluZ1ZhbHVlKHVzZU5vZGUpOwotICAgICAgICAgICAgKChLZXlJdGVyYXRvciltX2xwaSkuYWRkUmVmTm9kZShleHByUmVzdWx0LCB0ZXN0Tm9kZSk7IAotICAgICAgICAgICAgCi0gICAgICAgICAgICBpZiAoKG51bGwgIT0gZXhwclJlc3VsdCkgJiYgbG9va3VwS2V5LmVxdWFscyhleHByUmVzdWx0KSkKLSAgICAgICAgICAgICAgcmVzdWx0ID0gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVDsKLSAgICAgICAgICAgICAgLy9yZXR1cm4gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVDsKLSAgICAgICAgICB9Ci0gICAgICAgICAgaWYgKC0xICE9IHJlc3VsdCkKLSAgICAgICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICAgIH0gICAgICAgCi0gICAgICAgIAotICAgICAgfSAgLy8gZW5kIGZvcihpbnQgaSA9IDA7IGkgPCBuRGVjbGFyYXRpb25zOyBpKyspCi0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0KLSAgICAgIC8vIFRPRE86IFdoYXQgdG8gZG8/Ci0gICAgfQotCi0gICAgICAgICAgICAgICAgaWYgKCFmb3VuZEtleSkKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19YU0xLRVlfREVDTEFSQVRJT04sIG5ldyBPYmplY3RbXXtuYW1lLmdldExvY2FsTmFtZSgpfSkpOwotICAgIHJldHVybiBEVE1JdGVyYXRvci5GSUxURVJfUkVKRUNUOwotICB9Ci0gIAotICAgLyoqCi0gICAqICBNb3ZlcyB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gdG8gdGhlIG5leHQgdmlzaWJsZSBub2RlIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IG5vZGUsIGFuZCByZXR1cm5zIHRoZSBuZXcgbm9kZS4gSWYgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSBoYXMgbm8gbmV4dCBub2RlLCAgb3IgaWYgdGhlIHNlYXJjaCBmb3IgbmV4dE5vZGUgYXR0ZW1wdHMKLSAgICogdG8gc3RlcCB1cHdhcmQgZnJvbSB0aGUgVHJlZVdhbGtlcidzIHJvb3Qgbm9kZSwgcmV0dXJucwotICAgKiA8Y29kZT5udWxsPC9jb2RlPiAsIGFuZCByZXRhaW5zIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqIAotICAgKiBAcmV0dXJuICBUaGUgbmV3IG5vZGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBjdXJyZW50IG5vZGUgaGFzIG5vCi0gICAqICAgbmV4dCBub2RlICBpbiB0aGUgVHJlZVdhbGtlcidzIGxvZ2ljYWwgdmlldy4KLSAgICovCi0gIHB1YmxpYyBpbnQgbmV4dE5vZGUoKQotICB7Ci0gICAgaW50IG5vZGUgPSBzdXBlci5uZXh0Tm9kZSgpOwotICAgIC8vIElmIHRoZXJlIGlzIG5vIG5leHQgbm9kZSwgd2UgaGF2ZSB3YWxrZWQgdGhlIHdob2xlIHNvdXJjZSB0cmVlLgotICAgIC8vIE5vdGlmeSB0aGUgaXRlcmF0b3Igb2YgdGhhdCBzbyB0aGF0IGl0cyBjYWxsZXJzIGtub3cgdGhhdCB0aGVyZQotICAgIC8vIGFyZSBubyBtb3JlIG5vZGVzIHRvIGJlIGZvdW5kLgotICAgIGlmIChub2RlID09IERUTS5OVUxMKQotICAgICAgKChLZXlJdGVyYXRvciltX2xwaSkuc2V0TG9va0Zvck1vcmVOb2RlcyhmYWxzZSk7Ci0gICAgcmV0dXJuIG5vZGU7Ci0gIH0KLSAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Nc2dNZ3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL01zZ01nci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNGU0YmQ0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL01zZ01nci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzU2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Mb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHdpbGwgbWFuYWdlIGVycm9yIG1lc3NhZ2VzLCB3YXJuaW5nIG1lc3NhZ2VzLCBhbmQgb3RoZXIgdHlwZXMgb2YKLSAqIG1lc3NhZ2UgZXZlbnRzLgotICovCi1wdWJsaWMgY2xhc3MgTXNnTWdyCi17Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG1lc3NhZ2UgbWFuYWdlciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24gdHJhbnNmb3JtZXIgaW5zdGFuY2UKLSAgICovCi0gIHB1YmxpYyBNc2dNZ3IoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICB7Ci0gICAgbV90cmFuc2Zvcm1lciA9IHRyYW5zZm9ybWVyOwotICB9Ci0KLSAgLyoqIFRyYW5zZm9ybWVyIGluc3RhbmNlICAgICAgICAgICovCi0gIHByaXZhdGUgVHJhbnNmb3JtZXJJbXBsIG1fdHJhbnNmb3JtZXI7Ci0KLSAgLyoqIFhTTE1lc3NhZ2VzIGluc3RhbmNlLCBzZXRzIHRoaW5ncyB1cCBmb3IgaXNzdWluZyBtZXNzYWdlcyAgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBYU0xNZXNzYWdlcyBtX1hTTE1lc3NhZ2VzID0gbmV3IFhTTE1lc3NhZ2VzKCk7Ci0KLSAgLyoqCi0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYSBwcm9ibGVtLgotICAgKiBUaGlzIGlzIHB1YmxpYyBmb3IgYWNjZXNzIGJ5IGV4dGVuc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgVGhlIG1lc3NhZ2UgdGV4dCB0byBpc3N1ZQotICAgKiBAcGFyYW0gdGVybWluYXRlIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHRlcm1pbmF0ZSB0aGlzIHByb2Nlc3MKLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIG1lc3NhZ2UoU291cmNlTG9jYXRvciBzcmNMY3RyLCBTdHJpbmcgbXNnLCBib29sZWFuIHRlcm1pbmF0ZSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIEVycm9yTGlzdGVuZXIgZXJySGFuZGxlciA9IG1fdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0gICAgaWYgKG51bGwgIT0gZXJySGFuZGxlcikKLSAgICB7Ci0gICAgICBlcnJIYW5kbGVyLndhcm5pbmcobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1zZywgc3JjTGN0cikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKHRlcm1pbmF0ZSkKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1zZywgc3JjTGN0cik7Ci0gICAgICBlbHNlCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihtc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogV2FybiB0aGUgdXNlciBvZiBhIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSB0ZXh0IHRvIGlzc3VlCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuKFNvdXJjZUxvY2F0b3Igc3JjTGN0ciwgaW50IG1zZykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICB3YXJuKHNyY0xjdHIsIG51bGwsIG51bGwsIG1zZywgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYSBwcm9ibGVtLgotICAgKgotICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgdGV4dCB0byBpc3N1ZQotICAgKiBAcGFyYW0gYXJncyBBcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWVzc2FnZQotICAgKiBAdGhyb3dzIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhQYXRoQ29udGV4dCBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybihTb3VyY2VMb2NhdG9yIHNyY0xjdHIsIGludCBtc2csIE9iamVjdFtdIGFyZ3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgd2FybihzcmNMY3RyLCBudWxsLCBudWxsLCBtc2csIGFyZ3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBXYXJuIHRoZSB1c2VyIG9mIGEgcHJvYmxlbS4KLSAgICoKLSAgICogCi0gICAqIEBwYXJhbSBzdHlsZU5vZGUgU3R5bGVzaGVldCBub2RlCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIFNvdXJjZSB0cmVlIG5vZGUKLSAgICogQHBhcmFtIG1zZyBNZXNzYWdlIHRleHQgdG8gaXNzdWUKLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm4oU291cmNlTG9jYXRvciBzcmNMY3RyLCBOb2RlIHN0eWxlTm9kZSwgTm9kZSBzb3VyY2VOb2RlLCBpbnQgbXNnKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgd2FybihzcmNMY3RyLCBzdHlsZU5vZGUsIHNvdXJjZU5vZGUsIG1zZywgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYSBwcm9ibGVtLgotICAgKgotICAgKiBAcGFyYW0gc3R5bGVOb2RlIFN0eWxlc2hlZXQgbm9kZQotICAgKiBAcGFyYW0gc291cmNlTm9kZSBTb3VyY2UgdHJlZSBub2RlCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSB0ZXh0IHRvIGlzc3VlCi0gICAqIEBwYXJhbSBhcmdzIEFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXNzYWdlCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuKFNvdXJjZUxvY2F0b3Igc3JjTGN0ciwgTm9kZSBzdHlsZU5vZGUsIE5vZGUgc291cmNlTm9kZSwgaW50IG1zZywgT2JqZWN0IGFyZ3NbXSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZvcm1hdHRlZE1zZyA9IG1fWFNMTWVzc2FnZXMuY3JlYXRlV2FybmluZyhtc2csIGFyZ3MpOwotICAgIEVycm9yTGlzdGVuZXIgZXJySGFuZGxlciA9IG1fdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0gICAgaWYgKG51bGwgIT0gZXJySGFuZGxlcikKLSAgICAgIGVyckhhbmRsZXIud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLCBzcmNMY3RyKSk7Ci0gICAgZWxzZQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdHRlZE1zZyk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSB0ZXh0IHRvIGlzc3VlCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTb3VyY2VMb2NhdG9yIHNyY0xjdHIsIFN0cmluZyBtc2cpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBMb2NhdG9yIGxvY2F0b3IgPSBtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2suaXNFbXB0eSgpCi0gICAgLy8gICAgICAgICAgICAgICAgICA/IG51bGwgOgotICAgIC8vICAgICAgICAgICAgICAgICAgICAoKExvY2F0b3IpbV9zdHlsZXNoZWV0TG9jYXRvclN0YWNrLnBlZWsoKSk7Ci0gICAgLy8gTG9jYXRvciBsb2NhdG9yID0gbnVsbDsKLSAgICBFcnJvckxpc3RlbmVyIGVyckhhbmRsZXIgPSBtX3RyYW5zZm9ybWVyLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIGlmIChudWxsICE9IGVyckhhbmRsZXIpCi0gICAgICBlcnJIYW5kbGVyLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1zZywgc3JjTGN0cikpOwotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIHNyY0xjdHIpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgdGV4dCB0byBpc3N1ZQotICAgKiBAdGhyb3dzIFhTTFByb2Nlc3NvckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGFjdGl2ZSBQcm9ibGVtTGlzdGVuZXIgYW5kIFhQYXRoQ29udGV4dCBkZWNpZGUKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoU291cmNlTG9jYXRvciBzcmNMY3RyLCBpbnQgbXNnKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGVycm9yKHNyY0xjdHIsIG51bGwsIG51bGwsIG1zZywgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSB0ZXh0IHRvIGlzc3VlCi0gICAqIEBwYXJhbSBhcmdzIEFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gdGhlIG1lc3NhZ2UgCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTb3VyY2VMb2NhdG9yIHNyY0xjdHIsIGludCBtc2csIE9iamVjdFtdIGFyZ3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3Ioc3JjTGN0ciwgbnVsbCwgbnVsbCwgbXNnLCBhcmdzKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG1zZyBNZXNzYWdlIHRleHQgdG8gaXNzdWUKLSAgICogQHBhcmFtIGUgRXhjZXB0aW9uIHRvIHRocm93Ci0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTb3VyY2VMb2NhdG9yIHNyY0xjdHIsIGludCBtc2csIEV4Y2VwdGlvbiBlKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGVycm9yKHNyY0xjdHIsIG1zZywgbnVsbCwgZSk7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSB0ZXh0IHRvIGlzc3VlCi0gICAqIEBwYXJhbSBhcmdzIEFyZ3VtZW50cyB0byB1c2UgaW4gbWVzc2FnZQotICAgKiBAcGFyYW0gZSBFeGNlcHRpb24gdG8gdGhyb3cKLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFNvdXJjZUxvY2F0b3Igc3JjTGN0ciwgaW50IG1zZywgT2JqZWN0IGFyZ3NbXSwgRXhjZXB0aW9uIGUpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvL21zZyAgPSAobnVsbCA9PSBtc2cpID8gWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BST0NFU1NPUl9FUlJPUiA6IG1zZzsKLSAgICBTdHJpbmcgZm9ybWF0dGVkTXNnID0gbV9YU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKG1zZywgYXJncyk7Ci0KLSAgICAvLyBMb2NhdG9yIGxvY2F0b3IgPSBtX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2suaXNFbXB0eSgpCi0gICAgLy8gICAgICAgICAgICAgICAgICAgPyBudWxsIDoKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgKChMb2NhdG9yKW1fc3R5bGVzaGVldExvY2F0b3JTdGFjay5wZWVrKCkpOwotICAgIC8vIExvY2F0b3IgbG9jYXRvciA9IG51bGw7Ci0gICAgRXJyb3JMaXN0ZW5lciBlcnJIYW5kbGVyID0gbV90cmFuc2Zvcm1lci5nZXRFcnJvckxpc3RlbmVyKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBlcnJIYW5kbGVyKQotICAgICAgZXJySGFuZGxlci5mYXRhbEVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmb3JtYXR0ZWRNc2csIHNyY0xjdHIpKTsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLCBzcmNMY3RyKTsKLSAgfQotCi0gIC8qKgotICAgKiAgPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBzdHlsZU5vZGUgU3R5bGVzaGVldCBub2RlCi0gICAqIEBwYXJhbSBzb3VyY2VOb2RlIFNvdXJjZSB0cmVlIG5vZGUKLSAgICogQHBhcmFtIG1zZyBNZXNzYWdlIHRleHQgdG8gaXNzdWUKLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFNvdXJjZUxvY2F0b3Igc3JjTGN0ciwgTm9kZSBzdHlsZU5vZGUsIE5vZGUgc291cmNlTm9kZSwgaW50IG1zZykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGVycm9yKHNyY0xjdHIsIHN0eWxlTm9kZSwgc291cmNlTm9kZSwgbXNnLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHN0eWxlTm9kZSBTdHlsZXNoZWV0IG5vZGUKLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgU291cmNlIHRyZWUgbm9kZQotICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgdGV4dCB0byBpc3N1ZQotICAgKiBAcGFyYW0gYXJncyBBcmd1bWVudHMgdG8gdXNlIGluIG1lc3NhZ2UKLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFNvdXJjZUxvY2F0b3Igc3JjTGN0ciwgTm9kZSBzdHlsZU5vZGUsIE5vZGUgc291cmNlTm9kZSwgaW50IG1zZywgT2JqZWN0IGFyZ3NbXSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZvcm1hdHRlZE1zZyA9IG1fWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShtc2csIGFyZ3MpOwotCi0gICAgLy8gTG9jYXRvciBsb2NhdG9yID0gbV9zdHlsZXNoZWV0TG9jYXRvclN0YWNrLmlzRW1wdHkoKQotICAgIC8vICAgICAgICAgICAgICAgICAgID8gbnVsbCA6Ci0gICAgLy8gICAgICAgICAgICAgICAgICAgICgoTG9jYXRvciltX3N0eWxlc2hlZXRMb2NhdG9yU3RhY2sucGVlaygpKTsKLSAgICAvLyBMb2NhdG9yIGxvY2F0b3IgPSBudWxsOwotICAgIEVycm9yTGlzdGVuZXIgZXJySGFuZGxlciA9IG1fdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0gICAgaWYgKG51bGwgIT0gZXJySGFuZGxlcikKLSAgICAgIGVyckhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm9ybWF0dGVkTXNnLCBzcmNMY3RyKSk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZvcm1hdHRlZE1zZywgc3JjTGN0cik7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL05vZGVTb3J0S2V5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Ob2RlU29ydEtleS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNmQ5ZDc5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL05vZGVTb3J0S2V5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotCi1pbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogRGF0YSBzdHJ1Y3R1cmUgZm9yIHVzZSBieSB0aGUgTm9kZVNvcnRlciBjbGFzcy4KLSAqLwotY2xhc3MgTm9kZVNvcnRLZXkKLXsKLQotICAvKiogU2VsZWN0IHBhdHRlcm4gZm9yIHRoaXMgc29ydCBrZXkgICAgICAgICAgKi8KLSAgWFBhdGggbV9zZWxlY3RQYXQ7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHRyZWF0IHRoZWUgcmVzdWx0IGFzIGEgbnVtYmVyICAgICAqLwotICBib29sZWFuIG1fdHJlYXRBc051bWJlcnM7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHNvcnQgaW4gZGVzY2VuZGluZyBvcmRlciAgICAgICovCi0gIGJvb2xlYW4gbV9kZXNjZW5kaW5nOwotCi0gIC8qKiBGbGFnIGluZGljYXRpbmcgYnkgY2FzZSAgICAgICAgICAqLwotICBib29sZWFuIG1fY2FzZU9yZGVyVXBwZXI7Ci0KLSAgLyoqIENvbGxhdG9yIGluc3RhbmNlICAgICAgICAgICovCi0gIENvbGxhdG9yIG1fY29sOwotCi0gIC8qKiBMb2NhbGUgd2UncmUgaW4gICAgICAgICAgKi8KLSAgTG9jYWxlIG1fbG9jYWxlOwotCi0gIC8qKiBQcmVmaXggcmVzb2x2ZXIgdG8gdXNlICAgICAgICAgICovCi0gIG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyIG1fbmFtZXNwYWNlQ29udGV4dDsKLQotICAvKiogVHJhbnNmb3JtZXIgaW5zdGFuY2UgICAgICAgICAgKi8KLSAgVHJhbnNmb3JtZXJJbXBsIG1fcHJvY2Vzc29yOyAgLy8gbmVlZGVkIGZvciBlcnJvciByZXBvcnRpbmcuCi0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE5vZGVTb3J0S2V5Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24gbnVsbCB0cmFuc2Zvcm1lciBpbnN0YW5jZQotICAgKiBAcGFyYW0gc2VsZWN0UGF0IFNlbGVjdCBwYXR0ZXJuIGZvciB0aGlzIGtleSAKLSAgICogQHBhcmFtIHRyZWF0QXNOdW1iZXJzIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSByZXN1bHQgd2lsbCBiZSBhIG51bWJlcgotICAgKiBAcGFyYW0gZGVzY2VuZGluZyBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBzb3J0IGluIGRlc2NlbmRpbmcgb3JkZXIKLSAgICogQHBhcmFtIGxhbmdWYWx1ZSBMYW5nIHZhbHVlIHRvIHVzZSB0byBnZXQgbG9jYWxlCi0gICAqIEBwYXJhbSBjYXNlT3JkZXJVcHBlciBGbGFnIGluZGljYXRpbmcgd2hldGhlciBjYXNlIGlzIHJlbGV2YW50Ci0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IFByZWZpeCByZXNvbHZlcgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIE5vZGVTb3J0S2V5KAotICAgICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciwgWFBhdGggc2VsZWN0UGF0LCBib29sZWFuIHRyZWF0QXNOdW1iZXJzLCAKLSAgICAgICAgICBib29sZWFuIGRlc2NlbmRpbmcsIFN0cmluZyBsYW5nVmFsdWUsIGJvb2xlYW4gY2FzZU9yZGVyVXBwZXIsIAotICAgICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyIG5hbWVzcGFjZUNvbnRleHQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBtX3Byb2Nlc3NvciA9IHRyYW5zZm9ybWVyOwotICAgIG1fbmFtZXNwYWNlQ29udGV4dCA9IG5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgbV9zZWxlY3RQYXQgPSBzZWxlY3RQYXQ7Ci0gICAgbV90cmVhdEFzTnVtYmVycyA9IHRyZWF0QXNOdW1iZXJzOwotICAgIG1fZGVzY2VuZGluZyA9IGRlc2NlbmRpbmc7Ci0gICAgbV9jYXNlT3JkZXJVcHBlciA9IGNhc2VPcmRlclVwcGVyOwotCi0gICAgaWYgKG51bGwgIT0gbGFuZ1ZhbHVlICYmIG1fdHJlYXRBc051bWJlcnMgPT0gZmFsc2UpCi0gICAgewotICAgICAgLy8gU2VlIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9Mjg1MQotICAgICAgLy8gVGhlIGNvbnN0cnVjdG9yIG9mIExvY2FsZSBpcyBkZWZpbmVkIGFzIAotICAgICAgLy8gICBwdWJsaWMgTG9jYWxlKFN0cmluZyBsYW5ndWFnZSwgU3RyaW5nIGNvdW50cnkpCi0gICAgICAvLyB3aXRoCi0gICAgICAvLyAgIGxhbmd1YWdlIC0gbG93ZXJjYXNlIHR3by1sZXR0ZXIgSVNPLTYzOSBjb2RlCi0gICAgICAvLyAgIGNvdW50cnkgLSB1cHBlcmNhc2UgdHdvLWxldHRlciBJU08tMzE2NiBjb2RlCi0gICAgICAvLyBhKSBsYW5ndWFnZSBtdXN0IGJlIHByb3ZpZGVkIGFzIGEgbG93ZXItY2FzZSBJU08tY29kZSAKLSAgICAgIC8vICAgIGluc3RlYWQgb2YgYW4gdXBwZXItY2FzZSBjb2RlCi0gICAgICAvLyBiKSBjb3VudHJ5IG11c3QgYmUgcHJvdmlkZWQgYXMgYW4gSVNPLWNvZGUgCi0gICAgICAvLyAgICBpbnN0ZWFkIG9mIGEgZnVsbCBsb2NhbGl6ZWQgY291bnRyeSBuYW1lIChlLmcuICJGcmFuY2UiKQotICAgICAgbV9sb2NhbGUgPSBuZXcgTG9jYWxlKGxhbmdWYWx1ZS50b0xvd2VyQ2FzZSgpLCAKLSAgICAgICAgICAgICAgICAgIExvY2FsZS5nZXREZWZhdWx0KCkuZ2V0Q291bnRyeSgpKTsKLSAgICAgICAgICAgICAgICAgIAotICAgICAgLy8gKG9sZCwgYmVmb3JlIGJ1ZyByZXBvcnQgMjg1MSkuCi0gICAgICAvLyAgbV9sb2NhbGUgPSBuZXcgTG9jYWxlKGxhbmdWYWx1ZS50b1VwcGVyQ2FzZSgpLAotICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICBMb2NhbGUuZ2V0RGVmYXVsdCgpLmdldERpc3BsYXlDb3VudHJ5KCkpOyAgICAgICAgICAgICAgICAgICAgCi0KLSAgICAgIGlmIChudWxsID09IG1fbG9jYWxlKQotICAgICAgewotCi0gICAgICAgIC8vIG1fcHJvY2Vzc29yLndhcm4oIkNvdWxkIG5vdCBmaW5kIGxvY2FsZSBmb3IgPHNvcnQgeG1sOmxhbmc9IitsYW5nVmFsdWUpOwotICAgICAgICBtX2xvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX2xvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgfQotCi0gICAgbV9jb2wgPSBDb2xsYXRvci5nZXRJbnN0YW5jZShtX2xvY2FsZSk7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2NvbCkKLSAgICB7Ci0gICAgICBtX3Byb2Nlc3Nvci5nZXRNc2dNZ3IoKS53YXJuKG51bGwsIFhTTFRFcnJvclJlc291cmNlcy5XR19DQU5OT1RfRklORF9DT0xMQVRPUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBsYW5nVmFsdWUgfSk7ICAvLyJDb3VsZCBub3QgZmluZCBDb2xsYXRvciBmb3IgPHNvcnQgeG1sOmxhbmc9IitsYW5nVmFsdWUpOwotCi0gICAgICBtX2NvbCA9IENvbGxhdG9yLmdldEluc3RhbmNlKCk7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Ob2RlU29ydGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Ob2RlU29ydGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQyZmU2Y2UuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvTm9kZVNvcnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjE4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsKLWltcG9ydCBqYXZhLnRleHQuQ29sbGF0aW9uS2V5OwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Db250ZXh0Tm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgY2FuIHNvcnQgdmVjdG9ycyBvZiBET00gbm9kZXMgYWNjb3JkaW5nIHRvIGEgc2VsZWN0IHBhdHRlcm4uCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlU29ydGVyCi17Ci0KLSAgLyoqIEN1cnJlbnQgWFBhdGggY29udGV4dCAgICAgICAgICAgKi8KLSAgWFBhdGhDb250ZXh0IG1fZXhlY0NvbnRleHQ7Ci0KLSAgLyoqIFZlY3RvciBvZiBOb2RlU29ydEtleXMgICAgICAgICAgKi8KLSAgVmVjdG9yIG1fa2V5czsgIC8vIHZlY3RvciBvZiBOb2RlU29ydEtleXMKLQotLy8gIC8qKgotLy8gICAqIFRPRE86IEFkanVzdCB0aGlzIGZvciBsb2NhbGUuCi0vLyAgICovCi0vLyAgTnVtYmVyRm9ybWF0IG1fZm9ybWF0dGVyID0gTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIE5vZGVTb3J0ZXIsIHBhc3NpbmcgaW4gdGhlIFhTTCBUcmFuc2Zvcm1lckZhY3RvcnkKLSAgICogc28gaXQgY2FuIGtub3cgaG93IHRvIGdldCB0aGUgbm9kZSBkYXRhIGFjY29yZGluZyB0bwotICAgKiB0aGUgcHJvcGVyIHdoaXRlc3BhY2UgcnVsZXMuCi0gICAqCi0gICAqIEBwYXJhbSBwIFhwYXRoIGNvbnRleHQgdG8gdXNlCi0gICAqLwotICBwdWJsaWMgTm9kZVNvcnRlcihYUGF0aENvbnRleHQgcCkKLSAgewotICAgIG1fZXhlY0NvbnRleHQgPSBwOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgdmVjdG9yIG9mIG5vZGVzLCBzb3J0IGVhY2ggbm9kZSBhY2NvcmRpbmcgdG8KLSAgICogdGhlIGNyaXRlcmlhIGluIHRoZSBrZXlzLgotICAgKiBAcGFyYW0gdiBhbiB2ZWN0b3Igb2YgTm9kZXMuCi0gICAqIEBwYXJhbSBrZXlzIGEgdmVjdG9yIG9mIE5vZGVTb3J0S2V5cy4KLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzb3J0KERUTUl0ZXJhdG9yIHYsIFZlY3RvciBrZXlzLCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBtX2tleXMgPSBrZXlzOwotCi0gICAgLy8gUXVpY2tTb3J0Mih2LCAwLCB2LnNpemUoKSAtIDEgKTsKLSAgICBpbnQgbiA9IHYuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAvLyAlT1BUJSBDaGFuZ2UgbWVyZ2Vzb3J0IHRvIGp1c3QgdGFrZSBhIERUTUl0ZXJhdG9yPwotICAgIC8vIFdlIHdvdWxkIGFsc28gaGF2ZSB0byBhZGFwdCBEVE1JdGVyYXRvciB0byBoYXZlIHRoZSBmdW5jdGlvbiAKLSAgICAvLyBvZiBOb2RlQ29tcGFyZUVsZW0uCi0gICAgCi0gICAgLy8gQ3JlYXRlIGEgdmVjdG9yIG9mIG5vZGUgY29tcGFyZSBlbGVtZW50cwotICAgIC8vIGJhc2VkIG9uIHRoZSBpbnB1dCB2ZWN0b3Igb2Ygbm9kZXMKLSAgICBWZWN0b3Igbm9kZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBOb2RlQ29tcGFyZUVsZW0gZWxlbSA9IG5ldyBOb2RlQ29tcGFyZUVsZW0odi5pdGVtKGkpKTsKLQotICAgICAgbm9kZXMuYWRkRWxlbWVudChlbGVtKTsKLSAgICB9Ci0KLSAgICBWZWN0b3Igc2NyYXRjaFZlY3RvciA9IG5ldyBWZWN0b3IoKTsKLQotICAgIG1lcmdlc29ydChub2Rlcywgc2NyYXRjaFZlY3RvciwgMCwgbiAtIDEsIHN1cHBvcnQpOwotCi0gICAgLy8gcmV0dXJuIHNvcnRlZCB2ZWN0b3Igb2Ygbm9kZXMKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICB2LnNldEl0ZW0oKChOb2RlQ29tcGFyZUVsZW0pIG5vZGVzLmVsZW1lbnRBdChpKSkubV9ub2RlLCBpKTsKLSAgICB9Ci0gICAgdi5zZXRDdXJyZW50UG9zKDApOwotCi0gICAgLy8gb2xkIGNvZGUuLi4KLSAgICAvL05vZGVWZWN0b3Igc2NyYXRjaFZlY3RvciA9IG5ldyBOb2RlVmVjdG9yKG4pOwotICAgIC8vbWVyZ2Vzb3J0KHYsIHNjcmF0Y2hWZWN0b3IsIDAsIG4gLSAxLCBzdXBwb3J0KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHJlc3VsdHMgb2YgYSBjb21wYXJlIG9mIHR3byBub2Rlcy4KLSAgICogVE9ETzogT3B0aW1pemUgY29tcGFyZSAtLSBjYWNoZSB0aGUgZ2V0U3RyaW5nRXhwciByZXN1bHRzLCBrZXkgYnkgbV9zZWxlY3RQYXQgKyBoYXNoIG9mIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBuMSBGaXJzdCBub2RlIHRvIHVzZSBpbiBjb21wYXJlCi0gICAqIEBwYXJhbSBuMiBTZWNvbmQgbm9kZSB0byB1c2UgaW4gY29tcGFyZQotICAgKiBAcGFyYW0ga0luZGV4IEluZGV4IG9mIE5vZGVTb3J0S2V5IHRvIHVzZSBmb3Igc29ydAotICAgKiBAcGFyYW0gc3VwcG9ydCBYUGF0aCBjb250ZXh0IHRvIHVzZQotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHRzIG9mIHRoZSBjb21wYXJlIG9mIHRoZSB0d28gbm9kZXMuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIGludCBjb21wYXJlKAotICAgICAgICAgIE5vZGVDb21wYXJlRWxlbSBuMSwgTm9kZUNvbXBhcmVFbGVtIG4yLCBpbnQga0luZGV4LCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgcmVzdWx0ID0gMDsKLSAgICBOb2RlU29ydEtleSBrID0gKE5vZGVTb3J0S2V5KSBtX2tleXMuZWxlbWVudEF0KGtJbmRleCk7Ci0KLSAgICBpZiAoay5tX3RyZWF0QXNOdW1iZXJzKQotICAgIHsKLSAgICAgIGRvdWJsZSBuMU51bSwgbjJOdW07Ci0KLSAgICAgIGlmIChrSW5kZXggPT0gMCkKLSAgICAgIHsKLSAgICAgICAgbjFOdW0gPSAoKERvdWJsZSkgbjEubV9rZXkxVmFsdWUpLmRvdWJsZVZhbHVlKCk7Ci0gICAgICAgIG4yTnVtID0gKChEb3VibGUpIG4yLm1fa2V5MVZhbHVlKS5kb3VibGVWYWx1ZSgpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoa0luZGV4ID09IDEpCi0gICAgICB7Ci0gICAgICAgIG4xTnVtID0gKChEb3VibGUpIG4xLm1fa2V5MlZhbHVlKS5kb3VibGVWYWx1ZSgpOwotICAgICAgICBuMk51bSA9ICgoRG91YmxlKSBuMi5tX2tleTJWYWx1ZSkuZG91YmxlVmFsdWUoKTsKLSAgICAgIH0KLQotICAgICAgLyogTGVhdmUgdGhpcyBpbiBjYXNlIHdlIGRlY2lkZSB0byB1c2UgYW4gYXJyYXkgbGF0ZXIKLSAgICAgIGlmIChrSW5kZXggPCBtYXhrZXkpCi0gICAgICB7Ci0gICAgICBkb3VibGUgbjFOdW0gPSAoZG91YmxlKW4xLm1fa2V5VmFsdWVba0luZGV4XTsKLSAgICAgIGRvdWJsZSBuMk51bSA9IChkb3VibGUpbjIubV9rZXlWYWx1ZVtrSW5kZXhdOwotICAgICAgfSovCi0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gR2V0IHZhbHVlcyBkeW5hbWljYWxseQotICAgICAgICBYT2JqZWN0IHIxID0gay5tX3NlbGVjdFBhdC5leGVjdXRlKG1fZXhlY0NvbnRleHQsIG4xLm1fbm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrLm1fbmFtZXNwYWNlQ29udGV4dCk7Ci0gICAgICAgIFhPYmplY3QgcjIgPSBrLm1fc2VsZWN0UGF0LmV4ZWN1dGUobV9leGVjQ29udGV4dCwgbjIubV9ub2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGsubV9uYW1lc3BhY2VDb250ZXh0KTsKLSAgICAgICAgbjFOdW0gPSByMS5udW0oKTsKLQotICAgICAgICAvLyBDYW4ndCB1c2UgTmFOIGZvciBjb21wYXJlLiBUaGV5IGFyZSBuZXZlciBlcXVhbC4gVXNlIHplcm8gaW5zdGVhZC4KLSAgICAgICAgLy8gVGhhdCB3YXkgd2UgY2FuIGtlZXAgZWxlbWVudHMgaW4gZG9jdW1lbnQgb3JkZXIuIAotICAgICAgICAvL24xTnVtID0gRG91YmxlLmlzTmFOKGQpID8gMC4wIDogZDsKLSAgICAgICAgbjJOdW0gPSByMi5udW0oKTsKLSAgICAgICAgLy9uMk51bSA9IERvdWJsZS5pc05hTihkKSA/IDAuMCA6IGQ7Ci0gICAgICB9Ci0KLSAgICAgIGlmICgobjFOdW0gPT0gbjJOdW0pICYmICgoa0luZGV4ICsgMSkgPCBtX2tleXMuc2l6ZSgpKSkKLSAgICAgIHsKLSAgICAgICAgcmVzdWx0ID0gY29tcGFyZShuMSwgbjIsIGtJbmRleCArIDEsIHN1cHBvcnQpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBkb3VibGUgZGlmZjsKLSAgICAgICAgaWYgKERvdWJsZS5pc05hTihuMU51bSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoRG91YmxlLmlzTmFOKG4yTnVtKSkKLSAgICAgICAgICAgIGRpZmYgPSAwLjA7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgZGlmZiA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKERvdWJsZS5pc05hTihuMk51bSkpCi0gICAgICAgICAgIGRpZmYgPSAxOwotICAgICAgICBlbHNlCi0gICAgICAgICAgZGlmZiA9IG4xTnVtIC0gbjJOdW07Ci0KLSAgICAgICAgLy8gcHJvY2VzcyBvcmRlciBwYXJhbWV0ZXIgCi0gICAgICAgIHJlc3VsdCA9IChpbnQpICgoZGlmZiA8IDAuMCkKLSAgICAgICAgICAgICAgICAgICAgICAgID8gKGsubV9kZXNjZW5kaW5nID8gMSA6IC0xKQotICAgICAgICAgICAgICAgICAgICAgICAgOiAoZGlmZiA+IDAuMCkgPyAoay5tX2Rlc2NlbmRpbmcgPyAtMSA6IDEpIDogMCk7Ci0gICAgICB9Ci0gICAgfSAgLy8gZW5kIHRyZWF0IGFzIG51bWJlcnMgCi0gICAgZWxzZQotICAgIHsKLSAgICAgIENvbGxhdGlvbktleSBuMVN0cmluZywgbjJTdHJpbmc7Ci0KLSAgICAgIGlmIChrSW5kZXggPT0gMCkKLSAgICAgIHsKLSAgICAgICAgbjFTdHJpbmcgPSAoQ29sbGF0aW9uS2V5KSBuMS5tX2tleTFWYWx1ZTsKLSAgICAgICAgbjJTdHJpbmcgPSAoQ29sbGF0aW9uS2V5KSBuMi5tX2tleTFWYWx1ZTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGtJbmRleCA9PSAxKQotICAgICAgewotICAgICAgICBuMVN0cmluZyA9IChDb2xsYXRpb25LZXkpIG4xLm1fa2V5MlZhbHVlOwotICAgICAgICBuMlN0cmluZyA9IChDb2xsYXRpb25LZXkpIG4yLm1fa2V5MlZhbHVlOwotICAgICAgfQotCi0gICAgICAvKiBMZWF2ZSB0aGlzIGluIGNhc2Ugd2UgZGVjaWRlIHRvIHVzZSBhbiBhcnJheSBsYXRlcgotICAgICAgaWYgKGtJbmRleCA8IG1heGtleSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIG4xU3RyaW5nID0gKFN0cmluZyluMS5tX2tleVZhbHVlW2tJbmRleF07Ci0gICAgICAgIFN0cmluZyBuMlN0cmluZyA9IChTdHJpbmcpbjIubV9rZXlWYWx1ZVtrSW5kZXhdOwotICAgICAgfSovCi0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gR2V0IHZhbHVlcyBkeW5hbWljYWxseQotICAgICAgICBYT2JqZWN0IHIxID0gay5tX3NlbGVjdFBhdC5leGVjdXRlKG1fZXhlY0NvbnRleHQsIG4xLm1fbm9kZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrLm1fbmFtZXNwYWNlQ29udGV4dCk7Ci0gICAgICAgIFhPYmplY3QgcjIgPSBrLm1fc2VsZWN0UGF0LmV4ZWN1dGUobV9leGVjQ29udGV4dCwgbjIubV9ub2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGsubV9uYW1lc3BhY2VDb250ZXh0KTsKLQotICAgICAgICBuMVN0cmluZyA9IGsubV9jb2wuZ2V0Q29sbGF0aW9uS2V5KHIxLnN0cigpKTsKLSAgICAgICAgbjJTdHJpbmcgPSBrLm1fY29sLmdldENvbGxhdGlvbktleShyMi5zdHIoKSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIFVzZSBjb2xsYXRpb24ga2V5cyBmb3IgZmFzdGVyIGNvbXBhcmUsIGJ1dCBub3RlIHRoYXQgd2hpdGVzcGFjZXMgCi0gICAgICAvLyBldGMuLi4gYXJlIHRyZWF0ZWQgZGlmZmVyZW50bHkgZnJvbSBpZiB3ZSB3ZXJlIGNvbXBhcmluZyBTdHJpbmdzLgotICAgICAgcmVzdWx0ID0gbjFTdHJpbmcuY29tcGFyZVRvKG4yU3RyaW5nKTsKLQotICAgICAgLy9Qcm9jZXNzIGNhc2VPcmRlciBwYXJhbWV0ZXIKLSAgICAgIGlmIChrLm1fY2FzZU9yZGVyVXBwZXIpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyB0ZW1wTjEgPSBuMVN0cmluZy5nZXRTb3VyY2VTdHJpbmcoKS50b0xvd2VyQ2FzZSgpOwotICAgICAgICBTdHJpbmcgdGVtcE4yID0gbjJTdHJpbmcuZ2V0U291cmNlU3RyaW5nKCkudG9Mb3dlckNhc2UoKTsKLQotICAgICAgICBpZiAodGVtcE4xLmVxdWFscyh0ZW1wTjIpKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvL2phdmEgZGVmYXVsdHMgdG8gdXBwZXIgY2FzZSBpcyBncmVhdGVyLgotICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PSAwID8gMCA6IC1yZXN1bHQ7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgLy9Qcm9jZXNzIG9yZGVyIHBhcmFtZXRlcgotICAgICAgaWYgKGsubV9kZXNjZW5kaW5nKQotICAgICAgewotICAgICAgICByZXN1bHQgPSAtcmVzdWx0OwotICAgICAgfQotICAgIH0gIC8vZW5kIGVsc2UKLQotICAgIGlmICgwID09IHJlc3VsdCkKLSAgICB7Ci0gICAgICBpZiAoKGtJbmRleCArIDEpIDwgbV9rZXlzLnNpemUoKSkKLSAgICAgIHsKLSAgICAgICAgcmVzdWx0ID0gY29tcGFyZShuMSwgbjIsIGtJbmRleCArIDEsIHN1cHBvcnQpOwotICAgICAgfQotICAgIH0KLQotICAgIGlmICgwID09IHJlc3VsdCkKLSAgICB7Ci0KLSAgICAgIC8vIEkgc2hvdWxkbid0IGhhdmUgdG8gZG8gdGhpcyBleGNlcHQgdGhhdCB0aGVyZSBzZWVtcyB0byAKLSAgICAgIC8vIGJlIGEgZ2xpdGNoIGluIHRoZSBtZXJnZXNvcnQKLSAgICAgIC8vIGlmKHIxLmdldFR5cGUoKSA9PSByMS5DTEFTU19OT0RFU0VUKQotICAgICAgLy8gewotICAgICAgRFRNIGR0bSA9IHN1cHBvcnQuZ2V0RFRNKG4xLm1fbm9kZSk7IC8vICVPUFQlCi0gICAgICByZXN1bHQgPSBkdG0uaXNOb2RlQWZ0ZXIobjEubV9ub2RlLCBuMi5tX25vZGUpID8gLTEgOiAxOwotCi0gICAgICAvLyB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGltcGxlbWVudHMgYSBzdGFuZGFyZCBNZXJnZXNvcnQsIGFzIGRlc2NyaWJlZCBpbgotICAgKiBSb2JlcnQgU2VkZ2V3aWNrJ3MgQWxnb3JpdGhtcyBib29rLiAgVGhpcyBpcyBhIGJldHRlcgotICAgKiBzb3J0IGZvciBvdXIgcHVycG9zZSB0aGFuIHRoZSBRdWlja3NvcnQgYmVjYXVzZSBpdAotICAgKiBtYWludGFpbnMgdGhlIG9yaWdpbmFsIGRvY3VtZW50IG9yZGVyIG9mIHRoZSBpbnB1dCBpZgotICAgKiB0aGUgb3JkZXIgaXNuJ3QgY2hhbmdlZCBieSB0aGUgc29ydC4KLSAgICoKLSAgICogQHBhcmFtIGEgRmlyc3QgdmVjdG9yIG9mIG5vZGVzIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIGIgU2Vjb25kIHZlY3RvciBvZiAgbm9kZXMgdG8gY29tcGFyZSAKLSAgICogQHBhcmFtIGwgTGVmdCBib3VuZGFyeSBvZiAgcGFydGl0aW9uCi0gICAqIEBwYXJhbSByIFJpZ2h0IGJvdW5kYXJ5IG9mICBwYXJ0aXRpb24KLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgdm9pZCBtZXJnZXNvcnQoVmVjdG9yIGEsIFZlY3RvciBiLCBpbnQgbCwgaW50IHIsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoKHIgLSBsKSA+IDApCi0gICAgewotICAgICAgaW50IG0gPSAociArIGwpIC8gMjsKLQotICAgICAgbWVyZ2Vzb3J0KGEsIGIsIGwsIG0sIHN1cHBvcnQpOwotICAgICAgbWVyZ2Vzb3J0KGEsIGIsIG0gKyAxLCByLCBzdXBwb3J0KTsKLQotICAgICAgaW50IGksIGosIGs7Ci0KLSAgICAgIGZvciAoaSA9IG07IGkgPj0gbDsgaS0tKQotICAgICAgewotCi0gICAgICAgIC8vIGJbaV0gPSBhW2ldOwotICAgICAgICAvLyBVc2UgaW5zZXJ0IGlmIHdlIG5lZWQgdG8gaW5jcmVtZW50IHZlY3RvciBzaXplLgotICAgICAgICBpZiAoaSA+PSBiLnNpemUoKSkKLSAgICAgICAgICBiLmluc2VydEVsZW1lbnRBdChhLmVsZW1lbnRBdChpKSwgaSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBiLnNldEVsZW1lbnRBdChhLmVsZW1lbnRBdChpKSwgaSk7Ci0gICAgICB9Ci0KLSAgICAgIGkgPSBsOwotCi0gICAgICBmb3IgKGogPSAobSArIDEpOyBqIDw9IHI7IGorKykKLSAgICAgIHsKLQotICAgICAgICAvLyBiW3IrbSsxLWpdID0gYVtqXTsKLSAgICAgICAgaWYgKHIgKyBtICsgMSAtIGogPj0gYi5zaXplKCkpCi0gICAgICAgICAgYi5pbnNlcnRFbGVtZW50QXQoYS5lbGVtZW50QXQoaiksIHIgKyBtICsgMSAtIGopOwotICAgICAgICBlbHNlCi0gICAgICAgICAgYi5zZXRFbGVtZW50QXQoYS5lbGVtZW50QXQoaiksIHIgKyBtICsgMSAtIGopOwotICAgICAgfQotCi0gICAgICBqID0gcjsKLQotICAgICAgaW50IGNvbXBWYWw7Ci0KLSAgICAgIGZvciAoayA9IGw7IGsgPD0gcjsgaysrKQotICAgICAgewotCi0gICAgICAgIC8vIGlmKGJbaV0gPCBiW2pdKQotICAgICAgICBpZiAoaSA9PSBqKQotICAgICAgICAgIGNvbXBWYWwgPSAtMTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIGNvbXBWYWwgPSBjb21wYXJlKChOb2RlQ29tcGFyZUVsZW0pIGIuZWxlbWVudEF0KGkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIChOb2RlQ29tcGFyZUVsZW0pIGIuZWxlbWVudEF0KGopLCAwLCBzdXBwb3J0KTsKLQotICAgICAgICBpZiAoY29tcFZhbCA8IDApCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIGFba109YltpXTsKLSAgICAgICAgICBhLnNldEVsZW1lbnRBdChiLmVsZW1lbnRBdChpKSwgayk7Ci0KLSAgICAgICAgICBpKys7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoY29tcFZhbCA+IDApCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIGFba109YltqXTsgCi0gICAgICAgICAgYS5zZXRFbGVtZW50QXQoYi5lbGVtZW50QXQoaiksIGspOwotCi0gICAgICAgICAgai0tOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgYSBnZW5lcmljIHZlcnNpb24gb2YgQy5BLlIgSG9hcmUncyBRdWljayBTb3J0Ci0gICAqIGFsZ29yaXRobS4gIFRoaXMgd2lsbCBoYW5kbGUgYXJyYXlzIHRoYXQgYXJlIGFscmVhZHkKLSAgICogc29ydGVkLCBhbmQgYXJyYXlzIHdpdGggZHVwbGljYXRlIGtleXMuPEJSPgotICAgKgotICAgKiBJZiB5b3UgdGhpbmsgb2YgYSBvbmUgZGltZW5zaW9uYWwgYXJyYXkgYXMgZ29pbmcgZnJvbQotICAgKiB0aGUgbG93ZXN0IGluZGV4IG9uIHRoZSBsZWZ0IHRvIHRoZSBoaWdoZXN0IGluZGV4IG9uIHRoZSByaWdodAotICAgKiB0aGVuIHRoZSBwYXJhbWV0ZXJzIHRvIHRoaXMgZnVuY3Rpb24gYXJlIGxvd2VzdCBpbmRleCBvcgotICAgKiBsZWZ0IGFuZCBoaWdoZXN0IGluZGV4IG9yIHJpZ2h0LiAgVGhlIGZpcnN0IHRpbWUgeW91IGNhbGwKLSAgICogdGhpcyBmdW5jdGlvbiBpdCB3aWxsIGJlIHdpdGggdGhlIHBhcmFtZXRlcnMgMCwgYS5sZW5ndGggLSAxLgotICAgKgotICAgKiBAcGFyYW0gdiAgICAgICBhIHZlY3RvciBvZiBpbnRlZ2VycyAKLSAgICogQHBhcmFtIGxvMCAgICAgbGVmdCBib3VuZGFyeSBvZiBhcnJheSBwYXJ0aXRpb24KLSAgICogQHBhcmFtIGhpMCAgICAgcmlnaHQgYm91bmRhcnkgb2YgYXJyYXkgcGFydGl0aW9uCi0gICAqCi0gICAqLwotCi0gIC8qICBwcml2YXRlIHZvaWQgUXVpY2tTb3J0MihWZWN0b3IgdiwgaW50IGxvMCwgaW50IGhpMCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiwKLSAgICAgICAgICAgICBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24sCi0gICAgICAgICAgICAgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb24sCi0gICAgICAgICAgICAgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgIHsKLSAgICAgIGludCBsbyA9IGxvMDsKLSAgICAgIGludCBoaSA9IGhpMDsKLQotICAgICAgaWYgKCBoaTAgPiBsbzApCi0gICAgICB7Ci0gICAgICAgIC8vIEFyYml0cmFyaWx5IGVzdGFibGlzaGluZyBwYXJ0aXRpb24gZWxlbWVudCBhcyB0aGUgbWlkcG9pbnQgb2YKLSAgICAgICAgLy8gdGhlIGFycmF5LgotICAgICAgICBOb2RlIG1pZE5vZGUgPSAoTm9kZSl2LmVsZW1lbnRBdCggKCBsbzAgKyBoaTAgKSAvIDIgKTsKLQotICAgICAgICAvLyBsb29wIHRocm91Z2ggdGhlIGFycmF5IHVudGlsIGluZGljZXMgY3Jvc3MKLSAgICAgICAgd2hpbGUoIGxvIDw9IGhpICkKLSAgICAgICAgewotICAgICAgICAgIC8vIGZpbmQgdGhlIGZpcnN0IGVsZW1lbnQgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8KLSAgICAgICAgICAvLyB0aGUgcGFydGl0aW9uIGVsZW1lbnQgc3RhcnRpbmcgZnJvbSB0aGUgbGVmdCBJbmRleC4KLSAgICAgICAgICB3aGlsZSggKGxvIDwgaGkwKSAmJiAoY29tcGFyZSgoTm9kZSl2LmVsZW1lbnRBdChsbyksIG1pZE5vZGUsIDAsIHN1cHBvcnQpIDwgMCkgKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICsrbG87Ci0gICAgICAgICAgfSAvLyBlbmQgd2hpbGUKLQotICAgICAgICAgIC8vIGZpbmQgYW4gZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0bwotICAgICAgICAgIC8vIHRoZSBwYXJ0aXRpb24gZWxlbWVudCBzdGFydGluZyBmcm9tIHRoZSByaWdodCBJbmRleC4KLSAgICAgICAgICB3aGlsZSggKGhpID4gbG8wKSAmJiAoY29tcGFyZSgoTm9kZSl2LmVsZW1lbnRBdChoaSksIG1pZE5vZGUsIDAsIHN1cHBvcnQpID4gMCkgKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC0taGk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gaWYgdGhlIGluZGV4ZXMgaGF2ZSBub3QgY3Jvc3NlZCwgc3dhcAotICAgICAgICAgIGlmKCBsbyA8PSBoaSApCi0gICAgICAgICAgewotICAgICAgICAgICAgc3dhcCh2LCBsbywgaGkpOwotICAgICAgICAgICAgKytsbzsKLSAgICAgICAgICAgIC0taGk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIHJpZ2h0IGluZGV4IGhhcyBub3QgcmVhY2hlZCB0aGUgbGVmdCBzaWRlIG9mIGFycmF5Ci0gICAgICAgIC8vIG11c3Qgbm93IHNvcnQgdGhlIGxlZnQgcGFydGl0aW9uLgotICAgICAgICBpZiggbG8wIDwgaGkgKQotICAgICAgICB7Ci0gICAgICAgICAgUXVpY2tTb3J0MiggdiwgbG8wLCBoaSwgc3VwcG9ydCApOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhlIGxlZnQgaW5kZXggaGFzIG5vdCByZWFjaGVkIHRoZSByaWdodCBzaWRlIG9mIGFycmF5Ci0gICAgICAgIC8vIG11c3Qgbm93IHNvcnQgdGhlIHJpZ2h0IHBhcnRpdGlvbi4KLSAgICAgICAgaWYoIGxvIDwgaGkwICkKLSAgICAgICAgewotICAgICAgICAgIFF1aWNrU29ydDIoIHYsIGxvLCBoaTAsIHN1cHBvcnQgKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0gLy8gZW5kIFF1aWNrU29ydDIgICovCi0KLS8vICAvKioKLS8vICAgKiBTaW1wbGUgZnVuY3Rpb24gdG8gc3dhcCB0d28gZWxlbWVudHMgaW4KLS8vICAgKiBhIHZlY3Rvci4KLS8vICAgKiAKLS8vICAgKiBAcGFyYW0gdiBWZWN0b3Igb2Ygbm9kZXMgdG8gc3dhcAotLy8gICAqIEBwYXJhbSBpIEluZGV4IG9mIGZpcnN0IG5vZGUgdG8gc3dhcAotLy8gICAqIEBwYXJhbSBpIEluZGV4IG9mIHNlY29uZCBub2RlIHRvIHN3YXAKLS8vICAgKi8KLS8vICBwcml2YXRlIHZvaWQgc3dhcChWZWN0b3IgdiwgaW50IGksIGludCBqKQotLy8gIHsKLS8vCi0vLyAgICBpbnQgbm9kZSA9IChOb2RlKSB2LmVsZW1lbnRBdChpKTsKLS8vCi0vLyAgICB2LnNldEVsZW1lbnRBdCh2LmVsZW1lbnRBdChqKSwgaSk7Ci0vLyAgICB2LnNldEVsZW1lbnRBdChub2RlLCBqKTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBUaGlzIGNsYXNzIGhvbGRzIHRoZSB2YWx1ZShzKSBmcm9tIGV4ZWN1dGluZyB0aGUgZ2l2ZW4KLSAgICogbm9kZSBhZ2FpbnN0IHRoZSBzb3J0IGtleShzKS4gCi0gICAqLwotICBjbGFzcyBOb2RlQ29tcGFyZUVsZW0KLSAgewotCi0gICAgLyoqIEN1cnJlbnQgbm9kZSAgICAgICAgICAqLwotICAgIGludCBtX25vZGU7Ci0KLSAgICAvKiogVGhpcyBtYXhrZXkgdmFsdWUgd2FzIGNob3NlbiBhcmJpdHJhcmlseS4gV2UgYXJlIGFzc3VtaW5nIHRoYXQgdGhlICAgIAotICAgIC8vIG1heGtleSArIDEga2V5cyB3aWxsIG9ubHkgaGl0IGZhaXJseSByYXJlbHkgYW5kIHRoZXJlZm9yZSwgd2UKLSAgICAvLyB3aWxsIGdldCB0aGUgbm9kZSB2YWx1ZXMgZm9yIHRob3NlIGtleXMgZHluYW1pY2FsbHkuCi0gICAgKi8KLSAgICBpbnQgbWF4a2V5ID0gMjsKLQotICAgIC8vIEtlZXAgdGhpcyBpbiBjYXNlIHdlIGRlY2lkZSB0byB1c2UgYW4gYXJyYXkuIFJpZ2h0IG5vdwotICAgIC8vIHVzaW5nIHR3byB2YXJpYWJsZXMgaXMgY2hlYXBlci4KLSAgICAvL09iamVjdFtdIG1fS2V5VmFsdWUgPSBuZXcgT2JqZWN0WzJdOwotCi0gICAgLyoqIFZhbHVlIGZyb20gZmlyc3Qgc29ydCBrZXkgICAgICAgICAgICovCi0gICAgT2JqZWN0IG1fa2V5MVZhbHVlOwotCi0gICAgLyoqIFZhbHVlIGZyb20gc2Vjb25kIHNvcnQga2V5ICAgICAgICAgICAgKi8KLSAgICBPYmplY3QgbV9rZXkyVmFsdWU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBOb2RlQ29tcGFyZUVsZW0KLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgQ3VycmVudCBub2RlCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICAgKi8KLSAgICBOb2RlQ29tcGFyZUVsZW0oaW50IG5vZGUpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAgewotCi0gICAgICBib29sZWFuIHRyeU5leHRLZXkgPSB0cnVlOwotCi0gICAgICBtX25vZGUgPSBub2RlOwotCi0gICAgICBpZiAoIW1fa2V5cy5pc0VtcHR5KCkpCi0gICAgICB7Ci0gICAgICAgIE5vZGVTb3J0S2V5IGsxID0gKE5vZGVTb3J0S2V5KSBtX2tleXMuZWxlbWVudEF0KDApOwotICAgICAgICBYT2JqZWN0IHIgPSBrMS5tX3NlbGVjdFBhdC5leGVjdXRlKG1fZXhlY0NvbnRleHQsIG5vZGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgazEubV9uYW1lc3BhY2VDb250ZXh0KTsKLQotICAgICAgICBpZiAociA9PSBudWxsKQotICAgICAgICAgIHRyeU5leHRLZXkgPSBmYWxzZTsKLQotICAgICAgICBkb3VibGUgZDsKLQotICAgICAgICBpZiAoazEubV90cmVhdEFzTnVtYmVycykKLSAgICAgICAgewotICAgICAgICAgIGQgPSByLm51bSgpOwotCi0gICAgICAgICAgLy8gQ2FuJ3QgdXNlIE5hTiBmb3IgY29tcGFyZS4gVGhleSBhcmUgbmV2ZXIgZXF1YWwuIFVzZSB6ZXJvIGluc3RlYWQuICAKLSAgICAgICAgICBtX2tleTFWYWx1ZSA9IG5ldyBEb3VibGUoZCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV9rZXkxVmFsdWUgPSBrMS5tX2NvbC5nZXRDb2xsYXRpb25LZXkoci5zdHIoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoci5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gJVJFVklFVyUKLSAgICAgICAgICBEVE1JdGVyYXRvciBuaSA9IChEVE1JdGVyYXRvcilyLm9iamVjdCgpOwotICAgICAgICAgIGludCBjdXJyZW50ID0gbmkuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICAgICAgICBpZihEVE0uTlVMTCA9PSBjdXJyZW50KQotICAgICAgICAgICAgY3VycmVudCA9IG5pLm5leHROb2RlKCk7Ci0KLSAgICAgICAgICAvLyBpZiAobmkgaW5zdGFuY2VvZiBDb250ZXh0Tm9kZUxpc3QpIC8vICVSRVZJRVclCi0gICAgICAgICAgdHJ5TmV4dEtleSA9IChEVE0uTlVMTCAhPSBjdXJyZW50KTsKLQotICAgICAgICAgIC8vIGVsc2UgYWJkaWNhdGUuLi4gc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0Li4uIC1zYgotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG1fa2V5cy5zaXplKCkgPiAxKQotICAgICAgICB7Ci0gICAgICAgICAgTm9kZVNvcnRLZXkgazIgPSAoTm9kZVNvcnRLZXkpIG1fa2V5cy5lbGVtZW50QXQoMSk7Ci0KLSAgICAgICAgICBpZiAoIXRyeU5leHRLZXkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGsyLm1fdHJlYXRBc051bWJlcnMpCi0gICAgICAgICAgICAgIG1fa2V5MlZhbHVlID0gbmV3IERvdWJsZSgwLjApOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBtX2tleTJWYWx1ZSA9IGsyLm1fY29sLmdldENvbGxhdGlvbktleSgiIik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBYT2JqZWN0IHIyID0gazIubV9zZWxlY3RQYXQuZXhlY3V0ZShtX2V4ZWNDb250ZXh0LCBub2RlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgazIubV9uYW1lc3BhY2VDb250ZXh0KTsKLQotICAgICAgICAgICAgaWYgKGsyLm1fdHJlYXRBc051bWJlcnMpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGQgPSByMi5udW0oKTsKLSAgICAgICAgICAgICAgbV9rZXkyVmFsdWUgPSBuZXcgRG91YmxlKGQpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBtX2tleTJWYWx1ZSA9IGsyLm1fY29sLmdldENvbGxhdGlvbktleShyMi5zdHIoKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLyogTGVhdmUgdGhpcyBpbiBjYXNlIHdlIGRlY2lkZSB0byB1c2UgYW4gYXJyYXkgbGF0ZXIKLSAgICAgICAgd2hpbGUgKGtJbmRleCA8PSBtX2tleXMuc2l6ZSgpICYmIGtJbmRleCA8IG1heGtleSkKLSAgICAgICAgewotICAgICAgICAgIE5vZGVTb3J0S2V5IGsgPSAoTm9kZVNvcnRLZXkpbV9rZXlzLmVsZW1lbnRBdChrSW5kZXgpOwotICAgICAgICAgIFhPYmplY3QgciA9IGsubV9zZWxlY3RQYXQuZXhlY3V0ZShtX2V4ZWNDb250ZXh0LCBub2RlLCBrLm1fbmFtZXNwYWNlQ29udGV4dCk7Ci0gICAgICAgICAgaWYoay5tX3RyZWF0QXNOdW1iZXJzKQotICAgICAgICAgICAgbV9LZXlWYWx1ZVtrSW5kZXhdID0gci5udW0oKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBtX0tleVZhbHVlW2tJbmRleF0gPSByLnN0cigpOwotICAgICAgICB9ICovCi0gICAgICB9ICAvLyBlbmQgaWYgbm90IGVtcHR5ICAgIAotICAgIH0KLSAgfSAgLy8gZW5kIE5vZGVDb21wYXJlRWxlbSBjbGFzcwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvTnVtZXJhdG9yRm9ybWF0dGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9OdW1lcmF0b3JGb3JtYXR0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDVkOWUwMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9OdW1lcmF0b3JGb3JtYXR0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLWltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIENvbnZlcnRzIGVudW1lcmF0ZWQgbnVtYmVycyBpbnRvIHN0cmluZ3MsIHVzaW5nIHRoZSBYU0wgY29udmVyc2lvbiBhdHRyaWJ1dGVzLgotICogSGF2aW5nIHRoaXMgaW4gYSBjbGFzcyBoZWxwcyBhdm9pZCBiZWluZyBmb3JjZWQgdG8gZXh0cmFjdCB0aGUgYXR0cmlidXRlcyByZXBlYXRlZGx5LgotICovCi1jbGFzcyBOdW1lcmF0b3JGb3JtYXR0ZXIKLXsKLQotICAvKiogVGhlIG93bmluZyB4c2w6bnVtYmVyIGVsZW1lbnQuICAgICAgICAgICovCi0gIHByb3RlY3RlZCBFbGVtZW50IG1feHNsTnVtYmVyRWxlbWVudDsKLQotICAvKiogQW4gaW5zdGFuY2Ugb2YgYSBUb2tlbml6ZXIgICAgICAgICAgKi8KLSAgTnVtYmVyRm9ybWF0U3RyaW5nVG9rZW5pemVyIG1fZm9ybWF0VG9rZW5pemVyOwotCi0gIC8qKiBMb2NhbGUgd2UgbmVlZCB0byBmb3JtYXQgaW4gICAgICAgICAgKi8KLSAgTG9jYWxlIG1fbG9jYWxlOwotCi0gIC8qKiBBbiBpbnN0YW5jZSBvZiBhIE51bWJlckZvcm1hdCAgICAgICAgICovCi0gIGphdmEudGV4dC5OdW1iZXJGb3JtYXQgbV9mb3JtYXR0ZXI7Ci0KLSAgLyoqIEFuIGluc3RhbmNlIG9mIGEgdHJhbnNmb3JtZXIgICAgICAgICAgKi8KLSAgVHJhbnNmb3JtZXJJbXBsIG1fcHJvY2Vzc29yOwotCi0gIC8qKgotICAgKiBUYWJsZSB0byBoZWxwIGluIGNvbnZlcnRpbmcgZGVjaW1hbHMgdG8gcm9tYW4gbnVtZXJhbHMuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5EZWNpbWFsVG9Sb21hbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgRGVjaW1hbFRvUm9tYW4gbV9yb21hbkNvbnZlcnRUYWJsZVtdID0gewotICAgIG5ldyBEZWNpbWFsVG9Sb21hbigxMDAwLCAiTSIsIDkwMCwgIkNNIiksCi0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDUwMCwgIkQiLCA0MDAsICJDRCIpLAotICAgIG5ldyBEZWNpbWFsVG9Sb21hbigxMDBMLCAiQyIsIDkwTCwgIlhDIiksCi0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDUwTCwgIkwiLCA0MEwsICJYTCIpLAotICAgIG5ldyBEZWNpbWFsVG9Sb21hbigxMEwsICJYIiwgOUwsICJJWCIpLAotICAgIG5ldyBEZWNpbWFsVG9Sb21hbig1TCwgIlYiLCA0TCwgIklWIiksCi0gICAgbmV3IERlY2ltYWxUb1JvbWFuKDFMLCAiSSIsIDFMLCAiSSIpIH07Ci0KLSAgLyoqCi0gICAqIENoYXJzIGZvciBjb252ZXJ0aW5nIGludGVnZXJzIGludG8gYWxwaGEgY291bnRzLgotICAgKiBAc2VlIFRyYW5zZm9ybWVySW1wbCNpbnQyYWxwaGFDb3VudAotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2hhcltdIG1fYWxwaGFDb3VudFRhYmxlID0geyAnWicsICAvLyB6IGZvciB6ZXJvCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0snLCAnTCcsICdNJywgJ04nLCAnTycsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1UnLCAnVicsICdXJywgJ1gnLCAnWScgfTsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgTnVtZXJhdG9yRm9ybWF0dGVyIHVzaW5nIGFuIGVsZW1lbnQKLSAgICogdGhhdCBjb250YWlucyBYU0wgbnVtYmVyIGNvbnZlcnNpb24gYXR0cmlidXRlcyAtCi0gICAqIGZvcm1hdCwgbGV0dGVyLXZhbHVlLCB4bWw6bGFuZywgZGlnaXQtZ3JvdXAtc2VwLAotICAgKiBuLWRpZ2l0cy1wZXItZ3JvdXAsIGFuZCBzZXF1ZW5jZS1zcmMuCi0gICAqCi0gICAqIEBwYXJhbSB4c2xOdW1iZXJFbGVtZW50IFRoZSBnaXZlbiB4c2w6bnVtYmVyIGVsZW1lbnQKLSAgICogQHBhcmFtIHByb2Nlc3NvciBhIG5vbi1udWxsIHRyYW5zZm9ybWVyIGluc3RhbmNlCi0gICAqLwotICBOdW1lcmF0b3JGb3JtYXR0ZXIoRWxlbWVudCB4c2xOdW1iZXJFbGVtZW50LCBUcmFuc2Zvcm1lckltcGwgcHJvY2Vzc29yKQotICB7Ci0gICAgbV94c2xOdW1iZXJFbGVtZW50ID0geHNsTnVtYmVyRWxlbWVudDsKLSAgICBtX3Byb2Nlc3NvciA9IHByb2Nlc3NvcjsKLSAgfSAgLy8gZW5kIE51bWVyYXRvckZvcm1hdHRlcihFbGVtZW50KSBjb25zdHJ1Y3RvcgotCi0gIC8qKgotICAgKiBDb252ZXJ0IGEgbG9uZyBpbnRlZ2VyIGludG8gYWxwaGFiZXRpYyBjb3VudGluZywgaW4gb3RoZXIgd29yZHMKLSAgICogY291bnQgdXNpbmcgdGhlIHNlcXVlbmNlIEEgQiBDIC4uLiBaIEFBIEFCIEFDLi4uLiBldGMuCi0gICAqIAotICAgKiBAcGFyYW0gdmFsIFZhbHVlIHRvIGNvbnZlcnQgLS0gbXVzdCBiZSBncmVhdGVyIHRoYW4gemVyby4KLSAgICogQHBhcmFtIHRhYmxlIGEgdGFibGUgY29udGFpbmluZyBvbmUgY2hhcmFjdGVyIGZvciBlYWNoIGRpZ2l0IGluIHRoZSByYWRpeAotICAgKiBAcmV0dXJuIFN0cmluZyByZXByZXNlbnRpbmcgYWxwaGEgY291bnQgb2YgbnVtYmVyLgotICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuRGVjaW1hbFRvUm9tYW4KLSAgICoKLSAgICogTm90ZSB0aGF0IHRoZSByYWRpeCBvZiB0aGUgY29udmVyc2lvbiBpcyBpbmZlcnJlZCBmcm9tIHRoZSBzaXplCi0gICAqIG9mIHRoZSB0YWJsZS4KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgaW50MmFscGhhQ291bnQoaW50IHZhbCwgY2hhcltdIHRhYmxlKQotICB7Ci0KLSAgICBpbnQgcmFkaXggPSB0YWJsZS5sZW5ndGg7Ci0KLSAgICAvLyBDcmVhdGUgYSBidWZmZXIgdG8gaG9sZCB0aGUgcmVzdWx0Ci0gICAgLy8gVE9ETzogIHNpemUgb2YgdGhlIHRhYmxlIGNhbiBiZSBkZXRlcmVpbmVkIGJ5IGNvbXB1dGluZwotICAgIC8vIGxvZ3Mgb2YgdGhlIHJhZGl4LiAgRm9yIG5vdywgd2UgZmFrZSBpdC4KLSAgICBjaGFyIGJ1ZltdID0gbmV3IGNoYXJbMTAwXTsKLQotICAgIC8vIG5leHQgY2hhcmFjdGVyIHRvIHNldCBpbiB0aGUgYnVmZmVyCi0gICAgaW50IGNoYXJQb3MgPSBidWYubGVuZ3RoIC0gMTsgIC8vIHdvcmsgYmFja3dhcmQgdGhyb3VnaCBidWZbXQotCi0gICAgLy8gaW5kZXggaW4gdGFibGUgb2YgdGhlIGxhc3QgY2hhcmFjdGVyIHRoYXQgd2Ugc3RvcmVkCi0gICAgaW50IGxvb2t1cEluZGV4ID0gMTsgIC8vIHN0YXJ0IG9mZiB3aXRoIGFueXRoaW5nIG90aGVyIHRoYW4gemVybyB0byBtYWtlIGNvcnJlY3Rpb24gd29yawotCi0gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3JyZWN0aW9uIG51bWJlcgotICAgIC8vCi0gICAgLy8gIENvcnJlY3Rpb24gY2FuIHRha2Ugb24gZXhhY3RseSB0d28gdmFsdWVzOgotICAgIC8vCi0gICAgLy8gICAgICAgICAgMCAgICAgICBpZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaXMgdG8gYmUgZW1pdHRlZCBpcyB1c3VhbAotICAgIC8vCi0gICAgLy8gICAgICByYWRpeCAtIDEKLSAgICAvLyAgICAgICAgICAgICAgICAgIGlmIHRoZSBuZXh0IGNoYXIgdG8gYmUgZW1pdHRlZCBzaG91bGQgYmUgb25lIGxlc3MgdGhhbgotICAgIC8vICAgICAgICAgICAgICAgICAgeW91IHdvdWxkIGV4cGVjdAotICAgIC8vCi0gICAgLy8gRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHJhZGl4IDEwLCB3aGVyZSAxPSJBIiBhbmQgMTA9IkoiCi0gICAgLy8KLSAgICAvLyBJbiB0aGlzIHNjaGVtZSwgd2UgY291bnQ6IEEsIEIsIEMgLi4uICAgSCwgSSwgSiAobm90IEEwIGFuZCBjZXJ0YWlubHkKLSAgICAvLyBub3QgQUopLCBBMQotICAgIC8vCi0gICAgLy8gU28sIGhvdyBkbyB3ZSBrZWVwIGZyb20gZW1pdHRpbmcgQUogZm9yIDEwPyAgQWZ0ZXIgY29ycmVjdGx5IGVtaXR0aW5nIHRoZQotICAgIC8vIEosIGxvb2t1cEluZGV4IGlzIHplcm8uICBXZSBub3cgY29tcHV0ZSBhIGNvcnJlY3Rpb24gbnVtYmVyIG9mIDkgKHJhZGl4LTEpLgotICAgIC8vIEluIHRoZSBmb2xsb3dpbmcgbGluZSwgd2UnbGwgY29tcHV0ZSAodmFsK2NvcnJlY3Rpb24pICUgcmFkaXgsIHdoaWNoIGlzLAotICAgIC8vICh2YWwrOSkvMTAuICBCeSB0aGlzIHRpbWUsIHZhbCBpcyAxLCBzbyB3ZSBjb21wdXRlICgxKzkpICUgMTAsIHdoaWNoCi0gICAgLy8gaXMgMTAgJSAxMCBvciB6ZXJvLiAgU28sIHdlJ2xsIHByZXBhcmUgdG8gZW1pdCAiSkoiLCBidXQgdGhlbiB3ZSdsbAotICAgIC8vIGxhdGVyIHN1cHByZXNzIHRoZSBsZWFkaW5nIEogYXMgcmVwcmVzZW50aW5nIHplcm8gKGluIHRoZSBtb2Qgc3lzdGVtLAotICAgIC8vIGl0IGNhbiByZXByZXNlbnQgZWl0aGVyIDEwIG9yIHplcm8pLiAgSW4gc3VtbWFyeSwgdGhlIGNvcnJlY3Rpb24gdmFsdWUgb2YKLSAgICAvLyAicmFkaXgtMSIgYWN0cyBsaWtlICItMSIgd2hlbiBydW4gdGhyb3VnaCB0aGUgbW9kIG9wZXJhdG9yLCBidXQgd2l0aCB0aGUKLSAgICAvLyBkZXNpcmVhYmxlIGNoYXJhY3RlcmlzdGljIHRoYXQgaXQgbmV2ZXIgcHJvZHVjZXMgYSBuZWdhdGl2ZSBudW1iZXIuCi0gICAgaW50IGNvcnJlY3Rpb24gPSAwOwotCi0gICAgLy8gVE9ETzogIHRocm93IGVycm9yIG9uIG91dCBvZiByYW5nZSBpbnB1dAotICAgIGRvCi0gICAgewotCi0gICAgICAvLyBtb3N0IG9mIHRoZSBjb3JyZWN0aW9uIGNhbGN1bGF0aW9uIGlzIGV4cGxhaW5lZCBhYm92ZSwgIHRoZSByZWFzb24gZm9yIHRoZQotICAgICAgLy8gdGVybSBhZnRlciB0aGUgInx8ICIgaXMgdGhhdCBpdCBjb3JyZWN0bHkgcHJvcGFnYXRlcyBjYXJyaWVzIGFjcm9zcwotICAgICAgLy8gbXVsdGlwbGUgY29sdW1ucy4KLSAgICAgIGNvcnJlY3Rpb24gPQotICAgICAgICAoKGxvb2t1cEluZGV4ID09IDApIHx8IChjb3JyZWN0aW9uICE9IDAgJiYgbG9va3VwSW5kZXggPT0gcmFkaXggLSAxKSkKLSAgICAgICAgPyAocmFkaXggLSAxKSA6IDA7Ci0KLSAgICAgIC8vIGluZGV4IGluICJ0YWJsZSIgb2YgdGhlIG5leHQgY2hhciB0byBlbWl0Ci0gICAgICBsb29rdXBJbmRleCA9ICh2YWwgKyBjb3JyZWN0aW9uKSAlIHJhZGl4OwotCi0gICAgICAvLyBzaGlmdCBpbnB1dCBieSBvbmUgImNvbHVtbiIKLSAgICAgIHZhbCA9ICh2YWwgLyByYWRpeCk7Ci0KLSAgICAgIC8vIGlmIHRoZSBuZXh0IHZhbHVlIHdlJ2QgcHV0IG91dCB3b3VsZCBiZSBhIGxlYWRpbmcgemVybywgd2UncmUgZG9uZS4KLSAgICAgIGlmIChsb29rdXBJbmRleCA9PSAwICYmIHZhbCA9PSAwKQotICAgICAgICBicmVhazsKLQotICAgICAgLy8gcHV0IG91dCB0aGUgbmV4dCBjaGFyYWN0ZXIgb2Ygb3V0cHV0Ci0gICAgICBidWZbY2hhclBvcy0tXSA9IHRhYmxlW2xvb2t1cEluZGV4XTsKLSAgICB9Ci0gICAgd2hpbGUgKHZhbCA+IDApOwotCi0gICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmLCBjaGFyUG9zICsgMSwgKGJ1Zi5sZW5ndGggLSBjaGFyUG9zIC0gMSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnQgYSBsb25nIGludGVnZXIgaW50byByb21hbiBudW1lcmFscy4KLSAgICogQHBhcmFtIHZhbCBWYWx1ZSB0byBjb252ZXJ0LgotICAgKiBAcGFyYW0gcHJlZml4ZXNBcmVPSyB0cnVlXyB0byBlbmFibGUgcHJlZml4IG5vdGF0aW9uIChlLmcuIDQgPSAiSVYiKSwKLSAgICogZmFsc2VfIHRvIGRpc2FibGUgcHJlZml4IG5vdGF0aW9uIChlLmcuIDQgPSAiSUlJSSIpLgotICAgKiBAcmV0dXJuIFJvbWFuIG51bWVyYWwgc3RyaW5nLgotICAgKiBAc2VlIERlY2ltYWxUb1JvbWFuCi0gICAqIEBzZWUgbV9yb21hbkNvbnZlcnRUYWJsZQotICAgKi8KLSAgU3RyaW5nIGxvbmcycm9tYW4obG9uZyB2YWwsIGJvb2xlYW4gcHJlZml4ZXNBcmVPSykKLSAgewotCi0gICAgaWYgKHZhbCA8PSAwKQotICAgIHsKLSAgICAgIHJldHVybiAiI0UoIiArIHZhbCArICIpIjsKLSAgICB9Ci0KLSAgICBTdHJpbmcgcm9tYW4gPSAiIjsKLSAgICBpbnQgcGxhY2UgPSAwOwotCi0gICAgaWYgKHZhbCA8PSAzOTk5TCkKLSAgICB7Ci0gICAgICBkbwotICAgICAgewotICAgICAgICB3aGlsZSAodmFsID49IG1fcm9tYW5Db252ZXJ0VGFibGVbcGxhY2VdLm1fcG9zdFZhbHVlKQotICAgICAgICB7Ci0gICAgICAgICAgcm9tYW4gKz0gbV9yb21hbkNvbnZlcnRUYWJsZVtwbGFjZV0ubV9wb3N0TGV0dGVyOwotICAgICAgICAgIHZhbCAtPSBtX3JvbWFuQ29udmVydFRhYmxlW3BsYWNlXS5tX3Bvc3RWYWx1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChwcmVmaXhlc0FyZU9LKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKHZhbCA+PSBtX3JvbWFuQ29udmVydFRhYmxlW3BsYWNlXS5tX3ByZVZhbHVlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJvbWFuICs9IG1fcm9tYW5Db252ZXJ0VGFibGVbcGxhY2VdLm1fcHJlTGV0dGVyOwotICAgICAgICAgICAgdmFsIC09IG1fcm9tYW5Db252ZXJ0VGFibGVbcGxhY2VdLm1fcHJlVmFsdWU7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcGxhY2UrKzsKLSAgICAgIH0KLSAgICAgIHdoaWxlICh2YWwgPiAwKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHJvbWFuID0gIiNlcnJvciI7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJvbWFuOwotICB9ICAvLyBlbmQgbG9uZzJyb21hbgotCi0gIC8qKgotICAgKiBUaGlzIGNsYXNzIHJldHVybnMgdG9rZW5zIHVzaW5nIG5vbi1hbHBoYW51bWJlcmljCi0gICAqIGNoYXJhY3RlcnMgYXMgZGVsaW1pdGVycy4KLSAgICovCi0gIGNsYXNzIE51bWJlckZvcm1hdFN0cmluZ1Rva2VuaXplcgotICB7Ci0KLSAgICAvKiogRmllbGQgaG9sZGluZyB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgc3RyaW5nICAgICAgKi8KLSAgICBwcml2YXRlIGludCBjdXJyZW50UG9zaXRpb247Ci0KLSAgICAvKiogVGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgc3RyaW5nICAgICAgICAgICovCi0gICAgcHJpdmF0ZSBpbnQgbWF4UG9zaXRpb247Ci0KLSAgICAvKiogVGhlIHN0cmluZyB0byB0b2tlbml6ZSAgICAgICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIHN0cjsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdCBhIE51bWJlckZvcm1hdFN0cmluZ1Rva2VuaXplci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzdHIgVGhlIHN0cmluZyB0byB0b2tlbml6ZQotICAgICAqLwotICAgIE51bWJlckZvcm1hdFN0cmluZ1Rva2VuaXplcihTdHJpbmcgc3RyKQotICAgIHsKLSAgICAgIHRoaXMuc3RyID0gc3RyOwotICAgICAgbWF4UG9zaXRpb24gPSBzdHIubGVuZ3RoKCk7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIFJlc2V0IHRva2VuaXplciBzbyB0aGF0IG5leHRUb2tlbigpIHN0YXJ0cyBmcm9tIHRoZSBiZWdpbm5pbmcuIAotICAgICAqCi0gICAgICovCi0gICAgdm9pZCByZXNldCgpCi0gICAgewotICAgICAgY3VycmVudFBvc2l0aW9uID0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGZyb20gdGhpcyBzdHJpbmcgdG9rZW5pemVyLgotICAgICAqCi0gICAgICogQHJldHVybiAgICAgdGhlIG5leHQgdG9rZW4gZnJvbSB0aGlzIHN0cmluZyB0b2tlbml6ZXIuCi0gICAgICogQHRocm93cyAgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgdG9rZW5zIGluIHRoaXMKLSAgICAgKiAgICAgICAgICAgICAgIHRva2VuaXplcidzIHN0cmluZy4KLSAgICAgKi8KLSAgICBTdHJpbmcgbmV4dFRva2VuKCkKLSAgICB7Ci0KLSAgICAgIGlmIChjdXJyZW50UG9zaXRpb24gPj0gbWF4UG9zaXRpb24pCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIGludCBzdGFydCA9IGN1cnJlbnRQb3NpdGlvbjsKLQotICAgICAgd2hpbGUgKChjdXJyZW50UG9zaXRpb24gPCBtYXhQb3NpdGlvbikKLSAgICAgICAgICAgICAmJiBDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KHN0ci5jaGFyQXQoY3VycmVudFBvc2l0aW9uKSkpCi0gICAgICB7Ci0gICAgICAgIGN1cnJlbnRQb3NpdGlvbisrOwotICAgICAgfQotCi0gICAgICBpZiAoKHN0YXJ0ID09IGN1cnJlbnRQb3NpdGlvbikKLSAgICAgICAgICAgICAgJiYgKCFDaGFyYWN0ZXIuaXNMZXR0ZXJPckRpZ2l0KHN0ci5jaGFyQXQoY3VycmVudFBvc2l0aW9uKSkpKQotICAgICAgewotICAgICAgICBjdXJyZW50UG9zaXRpb24rKzsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHN0ci5zdWJzdHJpbmcoc3RhcnQsIGN1cnJlbnRQb3NpdGlvbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbHMgaWYgPGNvZGU+bmV4dFRva2VuPC9jb2RlPiB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiAgICAgICogaWYgaXQgaXMgY2FsbGVkLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIDxjb2RlPm5leHRUb2tlbjwvY29kZT4gY2FuIGJlIGNhbGxlZCAgICAgICogd2l0aG91dCB0aHJvd2luZyBhbiBleGNlcHRpb24uCi0gICAgICovCi0gICAgYm9vbGVhbiBoYXNNb3JlVG9rZW5zKCkKLSAgICB7Ci0gICAgICByZXR1cm4gKGN1cnJlbnRQb3NpdGlvbiA+PSBtYXhQb3NpdGlvbikgPyBmYWxzZSA6IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIHRpbWVzIHRoYXQgdGhpcyB0b2tlbml6ZXIncwotICAgICAqIDxjb2RlPm5leHRUb2tlbjwvY29kZT4gbWV0aG9kIGNhbiBiZSBjYWxsZWQgYmVmb3JlIGl0IGdlbmVyYXRlcyBhbgotICAgICAqIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gIHRoZSBudW1iZXIgb2YgdG9rZW5zIHJlbWFpbmluZyBpbiB0aGUgc3RyaW5nIHVzaW5nIHRoZSBjdXJyZW50Ci0gICAgICogICAgICAgICAgZGVsaW1pdGVyIHNldC4KLSAgICAgKiBAc2VlICAgICBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyI25leHRUb2tlbigpCi0gICAgICovCi0gICAgaW50IGNvdW50VG9rZW5zKCkKLSAgICB7Ci0KLSAgICAgIGludCBjb3VudCA9IDA7Ci0gICAgICBpbnQgY3VycnBvcyA9IGN1cnJlbnRQb3NpdGlvbjsKLQotICAgICAgd2hpbGUgKGN1cnJwb3MgPCBtYXhQb3NpdGlvbikKLSAgICAgIHsKLSAgICAgICAgaW50IHN0YXJ0ID0gY3VycnBvczsKLQotICAgICAgICB3aGlsZSAoKGN1cnJwb3MgPCBtYXhQb3NpdGlvbikKLSAgICAgICAgICAgICAgICYmIENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoc3RyLmNoYXJBdChjdXJycG9zKSkpCi0gICAgICAgIHsKLSAgICAgICAgICBjdXJycG9zKys7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoKHN0YXJ0ID09IGN1cnJwb3MpCi0gICAgICAgICAgICAgICAgJiYgKENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoc3RyLmNoYXJBdChjdXJycG9zKSkgPT0gZmFsc2UpKQotICAgICAgICB7Ci0gICAgICAgICAgY3VycnBvcysrOwotICAgICAgICB9Ci0KLSAgICAgICAgY291bnQrKzsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIGNvdW50OwotICAgIH0KLSAgfSAgLy8gZW5kIE51bWJlckZvcm1hdFN0cmluZ1Rva2VuaXplcgotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvUXVldWVkRXZlbnRzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9RdWV1ZWRFdmVudHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjViZGQxYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9RdWV1ZWRFdmVudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxMSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5PYmplY3RQb29sOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTXV0YWJsZUF0dHJMaXN0SW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZTsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3MgYWN0cyBhcyBhIGJhc2UgZm9yIFJlc3VsdFRyZWVIYW5kbGVyLCBhbmQga2VlcHMKLSAqIHF1ZXVkIHN0YWNrIGV2ZW50cy4gIEluIHRydXRoLCB3ZSBkb24ndCBuZWVkIGEgc3RhY2ssCi0gKiBzbyBJIG1heSBjaGFuZ2UgdGhpcyBkb3duIHRoZSBsaW5lIGEgYml0LgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgUXVldWVkRXZlbnRzCi17Ci0KLSAgLyoqIFRoZSBudW1iZXIgb2YgZXZlbnRzIHF1ZXVlZCAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZXZlbnRDb3VudCA9IDA7Ci0KLSAgLyoqIFF1ZXVlZCBzdGFydCBkb2N1bWVudCAgICAgICAgICAqLwotICAvLyBRdWV1ZWRTdGFydERvY3VtZW50IG1fc3RhcnREb2MgPSBuZXcgUXVldWVkU3RhcnREb2N1bWVudCgpOwotCi0gIC8qKiBRdWV1ZWQgc3RhcnQgZWxlbWVudCAgICAgICAgICAqLwotICAvLyBRdWV1ZWRTdGFydEVsZW1lbnQgbV9zdGFydEVsZW1lbnQgPSBuZXcgUXVldWVkU3RhcnRFbGVtZW50KCk7Ci0gIAotICBwdWJsaWMgYm9vbGVhbiBtX2RvY1BlbmRpbmcgPSBmYWxzZTsKLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9kb2NFbmRlZCA9IGZhbHNlOwotICAKLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB0aGF0IGFuIGV2ZW50IGlzIHBlbmRpbmcuICBQdWJsaWMgZm9yIAotICAgKiAgZmFzdCBhY2Nlc3MgYnkgRWxlbUZvckVhY2guICAgICAgICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbV9lbGVtSXNQZW5kaW5nID0gZmFsc2U7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB0aGF0IGFuIGV2ZW50IGlzIGVuZGVkICAgICAgICAgICovCi0gIHB1YmxpYyBib29sZWFuIG1fZWxlbUlzRW5kZWQgPSBmYWxzZTsKLSAgCi0gIC8qKgotICAgKiBUaGUgcGVuZGluZyBhdHRyaWJ1dGVzLiAgV2UgaGF2ZSB0byBkZWxheSB0aGUgY2FsbCB0bwotICAgKiBtX2ZsaXN0ZW5lci5zdGFydEVsZW1lbnQobmFtZSwgYXR0cykgYmVjYXVzZSBvZiB0aGUKLSAgICogeHNsOmF0dHJpYnV0ZSBhbmQgeHNsOmNvcHkgY2FsbHMuICBJbiBvdGhlciB3b3JkcywKLSAgICogdGhlIGF0dHJpYnV0ZXMgaGF2ZSB0byBiZSBmdWxseSBjb2xsZWN0ZWQgYmVmb3JlIHlvdQotICAgKiBjYW4gY2FsbCBzdGFydEVsZW1lbnQuCi0gICAqLwotICBwcm90ZWN0ZWQgTXV0YWJsZUF0dHJMaXN0SW1wbCBtX2F0dHJpYnV0ZXMgPSBuZXcgTXV0YWJsZUF0dHJMaXN0SW1wbCgpOwotCi0gIC8qKgotICAgKiBGbGFnIHRvIHRyeSBhbmQgZ2V0IHRoZSB4bWxucyBkZWNscyB0byB0aGUgYXR0cmlidXRlIGxpc3QKLSAgICogYmVmb3JlIG90aGVyIGF0dHJpYnV0ZXMgYXJlIGFkZGVkLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9uc0RlY2xzSGF2ZUJlZW5BZGRlZCA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUaGUgcGVuZGluZyBlbGVtZW50LCBuYW1lc3BhY2UsIGFuZCBsb2NhbCBuYW1lLgotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBtX25hbWU7Ci0KLSAgLyoqIE5hbWVzcGFjZSBVUkwgb2YgdGhlIGVsZW1lbnQgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBtX3VybDsKLQotICAvKiogTG9jYWwgcGFydCBvZiBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZWxlbWVudCAgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBtX2xvY2FsTmFtZTsKLSAgCi0gIAotICAvKiogVmVjdG9yIG9mIG5hbWVzcGFjZXMgZm9yIHRoaXMgZWxlbWVudCAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgVmVjdG9yIG1fbmFtZXNwYWNlcyA9IG51bGw7Ci0KLS8vICAvKioKLS8vICAgKiBHZXQgdGhlIHF1ZXVlZCBlbGVtZW50LgotLy8gICAqCi0vLyAgICogQHJldHVybiB0aGUgcXVldWVkIGVsZW1lbnQuCi0vLyAgICovCi0vLyAgUXVldWVkU3RhcnRFbGVtZW50IGdldFF1ZXVlZEVsZW0oKQotLy8gIHsKLS8vICAgIHJldHVybiAobV9ldmVudENvdW50ID4gMSkgPyBtX3N0YXJ0RWxlbWVudCA6IG51bGw7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBUbyByZS1pbml0aWFsaXplIHRoZSBkb2N1bWVudCBhbmQgZWxlbWVudCBldmVudHMgCi0gICAqCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCByZUluaXRFdmVudHMoKQotICB7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaCBkb2N1bWVudCBldmVudCBhbmQgcmUtaW5pdGlhbGl6ZSBldmVudHMgIAotICAgKgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgcHVzaERvY3VtZW50RXZlbnQoKTsKLSAgICByZUluaXRFdmVudHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIHRoZSBkb2N1bWVudCBldmVudC4gIFRoaXMgbmV2ZXIgZ2V0cyBwb3BwZWQuCi0gICAqLwotICB2b2lkIHB1c2hEb2N1bWVudEV2ZW50KCkKLSAgewotCi0gICAgLy8gbV9zdGFydERvYy5zZXRQZW5kaW5nKHRydWUpOwotICAgIC8vIGluaXRRU0UobV9zdGFydERvYyk7Ci0gICAgbV9kb2NQZW5kaW5nID0gdHJ1ZTsKLQotICAgIG1fZXZlbnRDb3VudCsrOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCBlbGVtZW50IGV2ZW50IAotICAgKgotICAgKi8KLSAgdm9pZCBwb3BFdmVudCgpCi0gIHsKLSAgICBtX2VsZW1Jc1BlbmRpbmcgPSBmYWxzZTsKLSAgICBtX2F0dHJpYnV0ZXMuY2xlYXIoKTsKLQotICAgIG1fbnNEZWNsc0hhdmVCZWVuQWRkZWQgPSBmYWxzZTsKLSAgICBtX25hbWUgPSBudWxsOwotICAgIG1fdXJsID0gbnVsbDsKLSAgICBtX2xvY2FsTmFtZSA9IG51bGw7Ci0gICAgbV9uYW1lc3BhY2VzID0gbnVsbDsKLQotICAgIG1fZXZlbnRDb3VudC0tOwotICB9Ci0KLSAgLyoqIEluc3RhbmNlIG9mIGEgc2VyaWFsaXplciAgICAgICAgICAqLwotICBwcml2YXRlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXIgbV9zZXJpYWxpemVyOwotCi0gIC8qKgotICAgKiBUaGlzIGlzIG9ubHkgZm9yIHVzZSBvZiBvYmplY3QgcG9vbGluZywgc28gdGhhdAotICAgKiBpdCBjYW4gYmUgcmVzZXQuCi0gICAqCi0gICAqIEBwYXJhbSBzIG5vbi1udWxsIGluc3RhbmNlIG9mIGEgc2VyaWFsaXplciAKLSAgICovCi0gIHZvaWQgc2V0U2VyaWFsaXplcihvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyIHMpCi0gIHsKLSAgICBtX3NlcmlhbGl6ZXIgPSBzOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgb25seSBmb3IgdXNlIG9mIG9iamVjdCBwb29saW5nLCBzbyB0aGUgdGhhdAotICAgKiBpdCBjYW4gYmUgcmVzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHNlcmlhbGl6ZXIKLSAgICovCi0gIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXIgZ2V0U2VyaWFsaXplcigpCi0gIHsKLSAgICByZXR1cm4gbV9zZXJpYWxpemVyOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9SZXN1bHROYW1lU3BhY2UuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1Jlc3VsdE5hbWVTcGFjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMjkyZTg3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1Jlc3VsdE5hbWVTcGFjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgcmVwcmVzZW50YXRpb24gb2YgYSByZXN1bHQgbmFtZXNwYWNlLiAgT25lIG9mIHRoZXNlIHdpbGwKLSAqIGJlIHB1c2hlZCBvbiB0aGUgcmVzdWx0IHRyZWUgbmFtZXNwYWNlIHN0YWNrIGZvciBlYWNoCi0gKiByZXN1bHQgdHJlZSBlbGVtZW50LgotICovCi1wdWJsaWMgY2xhc3MgUmVzdWx0TmFtZVNwYWNlCi17Ci0KLSAgLyoqIFBvaW50ZXIgdG8gbmV4dCBSZXN1bHROYW1lU3BhY2UgICAgICAgICAgKi8KLSAgcHVibGljIFJlc3VsdE5hbWVTcGFjZSBtX25leHQgPSBudWxsOwotCi0gIC8qKiBQcmVmaXggb2YgbmFtZXNwYWNlICAgICAgICAgKi8KLSAgcHVibGljIFN0cmluZyBtX3ByZWZpeDsKLQotICAvKiogTmFtZXNwYWNlIFVSSSAgICAgICAgICAqLwotICBwdWJsaWMgU3RyaW5nIG1fdXJpOyAgLy8gaWYgbnVsbCwgdGhlbiBFbGVtZW50IG5hbWVzcGFjZSBpcyBlbXB0eS4KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmFtZXNwYWNlIGZvciBwbGFjZW1lbnQgb24gdGhlCi0gICAqIHJlc3VsdCB0cmVlIG5hbWVzcGFjZSBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBvZiByZXN1bHQgbmFtZXNwYWNlCi0gICAqIEBwYXJhbSB1cmkgVVJJIG9mIHJlc3VsdCBuYW1lc3BhY2UKLSAgICovCi0gIHB1YmxpYyBSZXN1bHROYW1lU3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgewotICAgIG1fcHJlZml4ID0gcHJlZml4OwotICAgIG1fdXJpID0gdXJpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9SZXN1bHRUcmVlSGFuZGxlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvUmVzdWx0VHJlZUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzNiNjNkMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9SZXN1bHRUcmVlSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg2MyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Um9vdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLlRyYWNlTWFuYWdlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLkdlbmVyYXRlRXZlbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTXV0YWJsZUF0dHJMaXN0SW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk9iamVjdFBvb2w7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5OYW1lc3BhY2VTdXBwb3J0MjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIGEgbGF5ZXIgYmV0d2VlbiB0aGUgZGlyZWN0IGNhbGxzIHRvIHRoZSByZXN1bHQKLSAqIHRyZWUgY29udGVudCBoYW5kbGVyLCBhbmQgdGhlIHRyYW5zZm9ybWVyLiAgRm9yIG9uZSB0aGluZywKLSAqIHdlIGhhdmUgdG8gZGVsYXkgdGhlIGNhbGwgdG8KLSAqIGdldENvbnRlbnRIYW5kbGVyKCkuc3RhcnRFbGVtZW50KG5hbWUsIGF0dHMpIGJlY2F1c2Ugb2YgdGhlCi0gKiB4c2w6YXR0cmlidXRlIGFuZCB4c2w6Y29weSBjYWxscy4gIEluIG90aGVyIHdvcmRzLAotICogdGhlIGF0dHJpYnV0ZXMgaGF2ZSB0byBiZSBmdWxseSBjb2xsZWN0ZWQgYmVmb3JlIHlvdQotICogY2FuIGNhbGwgc3RhcnRFbGVtZW50LgotICovCi1wdWJsaWMgY2xhc3MgUmVzdWx0VHJlZUhhbmRsZXIgZXh0ZW5kcyBRdWV1ZWRFdmVudHMKLSAgICAgICAgaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIsIFRyYW5zZm9ybVN0YXRlLAotICAgICAgICBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLmRvbTJkdG0uRE9NMkRUTS5DaGFyYWN0ZXJOb2RlSGFuZGxlciwKLSAgICAgICAgRXJyb3JIYW5kbGVyCi17Ci0KLSAgLyoqIEluZGljYXRlIHdoZXRoZXIgcnVubmluZyBpbiBEZWJ1ZyBtb2RlICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogTnVsbCBjb25zdHJ1Y3RvciBmb3Igb2JqZWN0IHBvb2xpbmcuCi0gICAqLwotICBwdWJsaWMgUmVzdWx0VHJlZUhhbmRsZXIoKXt9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyByZXN1bHQgdHJlZSBoYW5kbGVyLiAgVGhlIHJlYWwgY29udGVudAotICAgKiBoYW5kbGVyIHdpbGwgYmUgdGhlIENvbnRlbnRIYW5kbGVyIHBhc3NlZCBhcyBhbiBhcmd1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIG5vbi1udWxsIHRyYW5zZm9ybWVyIGluc3RhbmNlCi0gICAqIEBwYXJhbSByZWFsSGFuZGxlciBDb250ZW50IEhhbmRsZXIgaW5zdGFuY2UKLSAgICovCi0gIHB1YmxpYyBSZXN1bHRUcmVlSGFuZGxlcihUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZW50SGFuZGxlciByZWFsSGFuZGxlcikKLSAgewotICAgIGluaXQodHJhbnNmb3JtZXIsIHJlYWxIYW5kbGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplciBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBub24tbnVsbCB0cmFuc2Zvcm1lciBpbnN0YW5jZQotICAgKiBAcGFyYW0gcmVhbEhhbmRsZXIgQ29udGVudCBIYW5kbGVyIGluc3RhbmNlCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbml0KFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciwgQ29udGVudEhhbmRsZXIgcmVhbEhhbmRsZXIpCi0gIHsKLQotICAgIG1fdHJhbnNmb3JtZXIgPSB0cmFuc2Zvcm1lcjsKLQotICAgIC8vIG1fc3RhcnREb2Muc2V0VHJhbnNmb3JtZXIobV90cmFuc2Zvcm1lcik7Ci0gICAgVHJhY2VNYW5hZ2VyIHRyYWNlciA9IHRyYW5zZm9ybWVyLmdldFRyYWNlTWFuYWdlcigpOwotCi0gICAgaWYgKChudWxsICE9IHRyYWNlcikgJiYgdHJhY2VyLmhhc1RyYWNlTGlzdGVuZXJzKCkpCi0gICAgICBtX3RyYWNlciA9IHRyYWNlcjsKLSAgICBlbHNlCi0gICAgICBtX3RyYWNlciA9IG51bGw7Ci0KLSAgICAvLyBtX3N0YXJ0RG9jLnNldFRyYWNlTWFuYWdlcihtX3RyYWNlcik7Ci0gICAgbV9jb250ZW50SGFuZGxlciA9IHJlYWxIYW5kbGVyOwotCi0gICAgLy8gbV9zdGFydERvYy5zZXRDb250ZW50SGFuZGxlcihtX2NvbnRlbnRIYW5kbGVyKTsKLSAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgbV9sZXhpY2FsSGFuZGxlciA9IChMZXhpY2FsSGFuZGxlcikgbV9jb250ZW50SGFuZGxlcjsKLSAgICBlbHNlCi0gICAgICBtX2xleGljYWxIYW5kbGVyID0gbnVsbDsKLQotICAgIG1faXNUcmFuc2Zvcm1DbGllbnQgPSAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyQ2xpZW50KTsKLQotICAgIG1fY2xvbmVyID0gbmV3IENsb25lclRvUmVzdWx0VHJlZSh0cmFuc2Zvcm1lciwgdGhpcyk7Ci0KLSAgICAvLyBUaGUgc3R5bGVzaGVldCBpcyBzZXQgYXQgYSByYXRoZXIgbGF0ZSBzdGFnZSwgc28gSSBkbyAKLSAgICAvLyB0aGlzIGhlcmUsIHRob3VnaCBpdCB3b3VsZCBwcm9iYWJseSBiZSBiZXR0ZXIgZG9uZSBlbHNld2hlcmUuCi0gICAgaWYgKG51bGwgIT0gbV90cmFuc2Zvcm1lcikKLSAgICAgIG1fc3R5bGVzaGVldFJvb3QgPSBtX3RyYW5zZm9ybWVyLmdldFN0eWxlc2hlZXQoKTsKLQotICAgIHB1c2hEb2N1bWVudEV2ZW50KCk7ICAvLyBub3QgcGVuZGluZyB5ZXQuCi0gIH0KLQotICAvKioKLSAgICogQm90dGxlbmVjayB0aGUgc3RhcnREb2N1bWVudCBldmVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ue30KLQotICAvKioKLSAgICogQm90dGxlbmVjayB0aGUgZW5kRG9jdW1lbnQgZXZlbnQuICBUaGlzIG1heSBiZSBjYWxsZWQKLSAgICogbW9yZSB0aGFuIG9uY2UgaW4gb3JkZXIgdG8gbWFrZSBzdXJlIHRoZSBwZW5kaW5nIHN0YXJ0Ci0gICAqIGRvY3VtZW50IGlzIGNhbGxlZC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0KLSAgICBpZiAoIW1fZG9jRW5kZWQpCi0gICAgewotICAgICAgbV9jb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotCi0gICAgICBpZiAobnVsbCAhPSBtX3RyYWNlcikKLSAgICAgIHsKLSAgICAgICAgR2VuZXJhdGVFdmVudCBnZSA9Ci0gICAgICAgICAgbmV3IEdlbmVyYXRlRXZlbnQobV90cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0ZUV2ZW50LkVWRU5UVFlQRV9FTkRET0NVTUVOVCwgbnVsbCk7Ci0KLSAgICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoZ2UpOwotICAgICAgfQotCi0gICAgICBtX2RvY0VuZGVkID0gdHJ1ZTsKLSAgICAgIG1fZG9jUGVuZGluZyA9IGZhbHNlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSBzdGFydEVsZW1lbnQgZXZlbnQuICBUaGlzIGlzIHVzZWQgdG8gInBlbmQiIGFuCi0gICAqIGVsZW1lbnQsIHNvIHRoYXQgYXR0cmlidXRlcyBjYW4gc3RpbGwgYmUgYWRkZWQgdG8gaXQgYmVmb3JlCi0gICAqIHRoZSByZWFsICJzdGFydEVsZW1lbnQiIGlzIGNhbGxlZCBvbiB0aGUgcmVzdWx0IHRyZWUgbGlzdGVuZXIuCi0gICAqCi0gICAqIEBwYXJhbSBucyBOYW1lc3BhY2UgVVJJIG9mIGVsZW1lbnQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBMb2NhbCBwYXJ0IG9mIHFuYW1lIG9mIGVsZW1lbnQKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiBlbGVtZW50Ci0gICAqIEBwYXJhbSBhdHRzIExpc3Qgb2YgYXR0cmlidXRlcyBmb3IgdGhlIGVsZW1lbnQKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudCgKLSAgICAgICAgICBTdHJpbmcgbnMsIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBpZiAobV9lbGVtSXNQZW5kaW5nKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIihSZXN1bHRUcmVlSGFuZGxlciNzdGFydEVsZW1lbnQgLSBwZW5kZWQ6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbV91cmwgKyAiIyIgKyBtX2xvY2FsTmFtZSk7Ci0KLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVzdWx0VHJlZUhhbmRsZXIjc3RhcnRFbGVtZW50OiAiICsgbnMgKyAiIyIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIGxvY2FsTmFtZSk7Ci0KLSAgICAgIC8vICAgICAgaWYobnVsbCA9PSBucykKLSAgICAgIC8vICAgICAgewotICAgICAgLy8gICAgICAgIChuZXcgUnVudGltZUV4Y2VwdGlvbihsb2NhbE5hbWUrIiBoYXMgYSBudWxsIG5hbWVzcGFjZSEiKSkucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAvLyAgICAgIH0KLSAgICB9Ci0KLSAgICBpZihtX2RvY1BlbmRpbmcpCi0gICAgICBjaGVja0ZvclNlcmlhbGl6ZXJTd2l0Y2gobnMsIGxvY2FsTmFtZSk7Ci0gICAgICAKLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0KLSAgICBpZiAoIW1fbnNDb250ZXh0UHVzaGVkKQotICAgIHsKLSAgICAgIGlmIChERUJVRykKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAgICJSZXN1bHRUcmVlSGFuZGxlciNzdGFydEVsZW1lbnQgLSBwdXNoKHN0YXJ0RWxlbWVudCkiKTsKLQotICAgICAgbV9uc1N1cHBvcnQucHVzaENvbnRleHQoKTsKLQotICAgICAgbV9uc0NvbnRleHRQdXNoZWQgPSB0cnVlOwotICAgIH0KLSAgICAKLSAgICBpZiAobnMgIT0gbnVsbCkKLSAgICAgIGVuc3VyZVByZWZpeElzRGVjbGFyZWQobnMsIG5hbWUpOwotCi0gICAgbV9uYW1lID0gbmFtZTsKLSAgICBtX3VybCA9IG5zOwotICAgIG1fbG9jYWxOYW1lID0gbG9jYWxOYW1lOwotCi0gICAgaWYgKG51bGwgIT0gYXR0cykKLSAgICAgIG1fYXR0cmlidXRlcy5hZGRBdHRyaWJ1dGVzKGF0dHMpOwotCi0gICAgbV9lbGVtSXNQZW5kaW5nID0gdHJ1ZTsKLSAgICBtX2VsZW1Jc0VuZGVkID0gZmFsc2U7Ci0gICAgCi0gICAgaWYobV9pc1RyYW5zZm9ybUNsaWVudCAmJiAobnVsbCAhPSBtX3RyYW5zZm9ybWVyKSkKLSAgICB7Ci0gICAgICBtX3NuYXBzaG90Lm1fY3VycmVudEVsZW1lbnQgPSBtX3RyYW5zZm9ybWVyLmdldEN1cnJlbnRFbGVtZW50KCk7Ci0gICAgICBtX3NuYXBzaG90Lm1fY3VycmVudFRlbXBsYXRlID0gbV90cmFuc2Zvcm1lci5nZXRDdXJyZW50VGVtcGxhdGUoKTsKLSAgICAgIG1fc25hcHNob3QubV9tYXRjaGVkVGVtcGxhdGUgPSBtX3RyYW5zZm9ybWVyLmdldE1hdGNoZWRUZW1wbGF0ZSgpOwotICAgICAgaW50IGN1cnJlbnROb2RlSGFuZGxlID0gbV90cmFuc2Zvcm1lci5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgRFRNIGR0bSA9IG1fdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0RFRNKGN1cnJlbnROb2RlSGFuZGxlKTsKLSAgICAgIG1fc25hcHNob3QubV9jdXJyZW50Tm9kZSA9IGR0bS5nZXROb2RlKGN1cnJlbnROb2RlSGFuZGxlKTsKLSAgICAgIG1fc25hcHNob3QubV9tYXRjaGVkTm9kZSA9IG1fdHJhbnNmb3JtZXIuZ2V0TWF0Y2hlZE5vZGUoKTsKLSAgICAgIG1fc25hcHNob3QubV9jb250ZXh0Tm9kZUxpc3QgPSBtX3RyYW5zZm9ybWVyLmdldENvbnRleHROb2RlTGlzdCgpOyAvLyBUT0RPOiBOZWVkIHRvIGNsb25lCi0gICAgfQotICAgIC8vIGluaXRRU0UobV9zdGFydEVsZW1lbnQpOwotCi0gICAgbV9ldmVudENvdW50Kys7Ci0gIH0KLQotICAvKioKLSAgICogQm90dGxlbmVjayB0aGUgZW5kRWxlbWVudCBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIG5zIE5hbWVzcGFjZSBVUkkgb2YgZWxlbWVudAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcW5hbWUgb2YgZWxlbWVudAotICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIGVsZW1lbnQKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5zLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICB7Ci0gICAgICBpZiAobV9lbGVtSXNQZW5kaW5nKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIihSZXN1bHRUcmVlSGFuZGxlciNlbmRFbGVtZW50IC0gcGVuZGVkOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICArIG1fdXJsICsgIiMiICsgbV9sb2NhbE5hbWUpOwotCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdFRyZWVIYW5kbGVyI2VuZEVsZW1lbnQ6ICIgKyBucyArICIjIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgbG9jYWxOYW1lKTsKLSAgICB9Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0gICAgbV9jb250ZW50SGFuZGxlci5lbmRFbGVtZW50KG5zLCBsb2NhbE5hbWUsIG5hbWUpOwotCi0gICAgaWYgKG51bGwgIT0gbV90cmFjZXIpCi0gICAgewotICAgICAgR2VuZXJhdGVFdmVudCBnZSA9IG5ldyBHZW5lcmF0ZUV2ZW50KG1fdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfRU5ERUxFTUVOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCAoQXR0cmlidXRlcyludWxsKTsKLQotICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoZ2UpOwotICAgIH0KLQotICAgIHNlbmRFbmRQcmVmaXhNYXBwaW5ncygpOwotICAgIHBvcEV2ZW50KCk7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdFRyZWVIYW5kbGVyI3N0YXJ0RWxlbWVudCBwb3A6ICIgKyBsb2NhbE5hbWUpOwotCi0gICAgbV9uc1N1cHBvcnQucG9wQ29udGV4dCgpOwotICB9Ci0KLSAgLyoqIEluZGljYXRlIHdoZXRoZXIgYSBuYW1lc3BhY2UgY29udGV4dCB3YXMgcHVzaGVkICovCi0gIGJvb2xlYW4gbV9uc0NvbnRleHRQdXNoZWQgPSBmYWxzZTsKLQotICAvKioKLSAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICogPHA+VGhlIGluZm9ybWF0aW9uIGZyb20gdGhpcyBldmVudCBpcyBub3QgbmVjZXNzYXJ5IGZvcgotICAgKiBub3JtYWwgTmFtZXNwYWNlIHByb2Nlc3Npbmc6IHRoZSBTQVggWE1MIHJlYWRlciB3aWxsCi0gICAqIGF1dG9tYXRpY2FsbHkgcmVwbGFjZSBwcmVmaXhlcyBmb3IgZWxlbWVudCBhbmQgYXR0cmlidXRlCi0gICAqIG5hbWVzIHdoZW4gdGhlIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzCi0gICAqIGZlYXR1cmUgaXMgdHJ1ZSAodGhlIGRlZmF1bHQpLjwvcD4KLSAgICoKLSAgICogPHA+VGhlcmUgYXJlIGNhc2VzLCBob3dldmVyLCB3aGVuIGFwcGxpY2F0aW9ucyBuZWVkIHRvCi0gICAqIHVzZSBwcmVmaXhlcyBpbiBjaGFyYWN0ZXIgZGF0YSBvciBpbiBhdHRyaWJ1dGUgdmFsdWVzLAotICAgKiB3aGVyZSB0aGV5IGNhbm5vdCBzYWZlbHkgYmUgZXhwYW5kZWQgYXV0b21hdGljYWxseTsgdGhlCi0gICAqIHN0YXJ0L2VuZFByZWZpeE1hcHBpbmcgZXZlbnQgc3VwcGxpZXMgdGhlIGluZm9ybWF0aW9uCi0gICAqIHRvIHRoZSBhcHBsaWNhdGlvbiB0byBleHBhbmQgcHJlZml4ZXMgaW4gdGhvc2UgY29udGV4dHMKLSAgICogaXRzZWxmLCBpZiBuZWNlc3NhcnkuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc3RhcnQvZW5kUHJlZml4TWFwcGluZyBldmVudHMgYXJlIG5vdAotICAgKiBndWFyYW50ZWVkIHRvIGJlIHByb3Blcmx5IG5lc3RlZCByZWxhdGl2ZSB0byBlYWNoLW90aGVyOgotICAgKiBhbGwgc3RhcnRQcmVmaXhNYXBwaW5nIGV2ZW50cyB3aWxsIG9jY3VyIGJlZm9yZSB0aGUKLSAgICogY29ycmVzcG9uZGluZyBzdGFydEVsZW1lbnQgZXZlbnQsIGFuZCBhbGwgZW5kUHJlZml4TWFwcGluZwotICAgKiBldmVudHMgd2lsbCBvY2N1ciBhZnRlciB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50IGV2ZW50LAotICAgKiBidXQgdGhlaXIgb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIHRoZSBwcmVmaXggaXMgbWFwcGVkIHRvLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICogQHNlZSAjZW5kUHJlZml4TWFwcGluZwotICAgKiBAc2VlICNzdGFydEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSwgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSB0aGUgcHJlZml4IGlzIG1hcHBlZCB0by4KLSAgICogQHBhcmFtIHNob3VsZEZsdXNoIEluZGljYXRlIHdoZXRoZXIgcGVuZGluZyBldmVudHMgbmVlZHMKLSAgICogdG8gYmUgZmx1c2hlZCBmaXJzdAotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZygKLSAgICAgICAgICBTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpLCBib29sZWFuIHNob3VsZEZsdXNoKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoc2hvdWxkRmx1c2gpCi0gICAgICBmbHVzaFBlbmRpbmcoZmFsc2UpOwotCi0gICAgaWYgKCFtX25zQ29udGV4dFB1c2hlZCkKLSAgICB7Ci0gICAgICBpZiAoREVCVUcpCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICAgICAiUmVzdWx0VHJlZUhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nIHB1c2goc3RhcnRQcmVmaXhNYXBwaW5nOiAiCi0gICAgICAgICAgKyBwcmVmaXggKyAiKSIpOwotCi0gICAgICBtX25zU3VwcG9ydC5wdXNoQ29udGV4dCgpOwotCi0gICAgICBtX25zQ29udGV4dFB1c2hlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgPT0gcHJlZml4KQotICAgICAgcHJlZml4ID0gIiI7ICAvLyBiaXQtby1oYWNrLCB0aGF0IHRoYXQncyBPSwotCi0gICAgU3RyaW5nIGV4aXN0aW5nVVJJID0gbV9uc1N1cHBvcnQuZ2V0VVJJKHByZWZpeCk7Ci0KLSAgICBpZiAobnVsbCA9PSBleGlzdGluZ1VSSSkKLSAgICAgIGV4aXN0aW5nVVJJID0gIiI7Ci0KLSAgICBpZiAobnVsbCA9PSB1cmkpCi0gICAgICB1cmkgPSAiIjsKLQotICAgIGlmICghZXhpc3RpbmdVUkkuZXF1YWxzKHVyaSkpCi0gICAgewotICAgICAgaWYgKERFQlVHKQotICAgICAgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdFRyZWVIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZyBQcmVmaXg6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcHJlZml4KTsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZXN1bHRUcmVlSGFuZGxlciNzdGFydFByZWZpeE1hcHBpbmcgdXJpOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICArIHVyaSk7Ci0gICAgICB9Ci0KLSAgICAgIG1fbnNTdXBwb3J0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBFbmQgdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBtYXBwaW5nLgotICAgKgotICAgKiA8cD5TZWUgc3RhcnRQcmVmaXhNYXBwaW5nIGZvciBkZXRhaWxzLiAgVGhpcyBldmVudCB3aWxsCi0gICAqIGFsd2F5cyBvY2N1ciBhZnRlciB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50IGV2ZW50LAotICAgKiBidXQgdGhlIG9yZGVyIG9mIGVuZFByZWZpeE1hcHBpbmcgZXZlbnRzIGlzIG5vdCBvdGhlcndpc2UKLSAgICogZ3VhcmFudGVlZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0aGF0IHdhcyBiZWluZyBtYXBwaW5nLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICogQHNlZSAjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAqIEBzZWUgI2VuZEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9ue30KLQotICAvKioKLSAgICogQm90dGxlbmVjayB0aGUgY2hhcmFjdGVycyBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFycmF5IG9mIGNoYXJhY3RlcnMgdG8gcHJvY2VzcwotICAgKiBAcGFyYW0gc3RhcnQgc3RhcnQgb2YgY2hhcmFjdGVycyBpbiB0aGUgYXJyYXkKLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgYXJyYXkKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBJdCB3b3VsZCBiZSBuaWNlIHRvIHN1cHByZXNzIGFsbCB3aGl0ZXNwYWNlIGJlZm9yZSB0aGUKLSAgICAvLyBmaXJzdCBlbGVtZW50LCBidXQgdGhpcyBpcyBnb2luZyB0byBjYXVzZSBwb3RlbnRpYWwgcHJvYmxlbXMgd2l0aCAKLSAgICAvLyB0ZXh0IHNlcmlhbGl6YXRpb24gYW5kIHdpdGggdGV4dCBlbnRpdGllcyAocmlnaHQgdGVybT8pLgotICAgIC8vIFNvIHRoaXMgcmVhbGx5IG5lZWRzIHRvIGJlIGRvbmUgYXQgdGhlIHNlcmlhbGl6ZXIgbGV2ZWwuCi0KLSAgICAvKmlmIChtX3N0YXJ0RG9jLmlzUGVuZGluZwotICAgICYmIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKSkKLSAgICByZXR1cm47Ki8KLSAgICBpZiAoREVCVUcpCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludCgiUmVzdWx0VHJlZUhhbmRsZXIjY2hhcmFjdGVyczogIik7Ci0KLSAgICAgIGludCBuID0gc3RhcnQgKyBsZW5ndGg7Ci0KLSAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYgKENoYXJhY3Rlci5pc1doaXRlc3BhY2UoY2hbaV0pKQotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlxcIiArICgoaW50KSBjaFtpXSkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgU3lzdGVtLm91dC5wcmludChjaFtpXSk7Ci0gICAgICB9Ci0KLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7Ci0gICAgfQotCi0gICAgZmx1c2hQZW5kaW5nKHRydWUpOwotICAgIG1fY29udGVudEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3RyYWNlcikKLSAgICB7Ci0gICAgICBHZW5lcmF0ZUV2ZW50IGdlID0gbmV3IEdlbmVyYXRlRXZlbnQobV90cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0ZUV2ZW50LkVWRU5UVFlQRV9DSEFSQUNURVJTLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoZ2UpOwotICAgIH0KLSAgfQotICAKLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhvcmcudzNjLmRvbS5Ob2RlIG5vZGUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0gICAgCi0gICAgaWYobV9pc1RyYW5zZm9ybUNsaWVudCkKLSAgICAgIG1fc25hcHNob3QubV9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICBTdHJpbmcgZGF0YSA9IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgY2hhciBbXSBjaCA9IG51bGw7Ci0gICAgaW50IGxlbmd0aCA9IDA7Ci0gICAgaWYgKGRhdGEgIT0gbnVsbCkKLSAgICB7Ci0gICAgY2ggPSBkYXRhLnRvQ2hhckFycmF5KCk7Ci0gICAgbGVuZ3RoID0gZGF0YS5sZW5ndGgoKTsKLSAgICBtX2NvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIDAsIGxlbmd0aCk7Ci0gICAgfQotICAgIAotICAgIGlmIChudWxsICE9IG1fdHJhY2VyKQotICAgIHsKLSAgICAgIEdlbmVyYXRlRXZlbnQgZ2UgPSBuZXcgR2VuZXJhdGVFdmVudChtX3RyYW5zZm9ybWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX0NIQVJBQ1RFUlMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2gsIDAsIGxlbmd0aCk7Ci0KLSAgICAgIG1fdHJhY2VyLmZpcmVHZW5lcmF0ZUV2ZW50KGdlKTsKLSAgICB9ICAKLSAgICBpZihtX2lzVHJhbnNmb3JtQ2xpZW50KQotICAgICAgbV9zbmFwc2hvdC5tX2N1cnJlbnROb2RlID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSBpZ25vcmFibGVXaGl0ZXNwYWNlIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gY2ggQXJyYXkgb2YgY2hhcmFjdGVycyB0byBwcm9jZXNzCi0gICAqIEBwYXJhbSBzdGFydCBzdGFydCBvZiBjaGFyYWN0ZXJzIGluIHRoZSBhcnJheQotICAgKiBAcGFyYW0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSBhcnJheQotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX2RvY1BlbmRpbmcKLSAgICAgICAgICAgICYmIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKSkKLSAgICAgIHJldHVybjsKLQotICAgIGZsdXNoUGVuZGluZyh0cnVlKTsKLSAgICBtX2NvbnRlbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgaWYgKG51bGwgIT0gbV90cmFjZXIpCi0gICAgewotICAgICAgR2VuZXJhdGVFdmVudCBnZSA9Ci0gICAgICAgIG5ldyBHZW5lcmF0ZUV2ZW50KG1fdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX0lHTk9SQUJMRVdISVRFU1BBQ0UsIGNoLAotICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoZ2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgUHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQgbmFtZQotICAgKiBAcGFyYW0gZGF0YSBQcm9jZXNzaW5nIGluc3RydWN0aW9uIGRhdGEKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGZsdXNoUGVuZGluZyh0cnVlKTsKLSAgICBtX2NvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotCi0gICAgaWYgKG51bGwgIT0gbV90cmFjZXIpCi0gICAgewotICAgICAgR2VuZXJhdGVFdmVudCBnZSA9IG5ldyBHZW5lcmF0ZUV2ZW50KG1fdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfUEksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LCBkYXRhKTsKLQotICAgICAgbV90cmFjZXIuZmlyZUdlbmVyYXRlRXZlbnQoZ2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSBjb21tZW50IGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gZGF0YSBDb21tZW50IGRhdGEKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbW1lbnQoU3RyaW5nIGRhdGEpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgZmx1c2hQZW5kaW5nKHRydWUpOwotCi0gICAgaWYgKG51bGwgIT0gbV9sZXhpY2FsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2xleGljYWxIYW5kbGVyLmNvbW1lbnQoZGF0YS50b0NoYXJBcnJheSgpLCAwLCBkYXRhLmxlbmd0aCgpKTsKLSAgICB9Ci0KLSAgICBpZiAobnVsbCAhPSBtX3RyYWNlcikKLSAgICB7Ci0gICAgICBHZW5lcmF0ZUV2ZW50IGdlID0gbmV3IEdlbmVyYXRlRXZlbnQobV90cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0ZUV2ZW50LkVWRU5UVFlQRV9DT01NRU5ULAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEpOwotCi0gICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChnZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEJvdHRsZW5lY2sgdGhlIGNvbW1lbnQgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBDaGFyYWN0ZXIgYXJyYXkgd2l0aCBjb21tZW50IGRhdGEKLSAgICogQHBhcmFtIHN0YXJ0IHN0YXJ0IG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5Ci0gICAqIEBwYXJhbSBsZW5ndGggbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgZmx1c2hQZW5kaW5nKHRydWUpOwotCi0gICAgaWYgKG51bGwgIT0gbV9sZXhpY2FsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2xleGljYWxIYW5kbGVyLmNvbW1lbnQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIGlmIChudWxsICE9IG1fdHJhY2VyKQotICAgIHsKLSAgICAgIEdlbmVyYXRlRXZlbnQgZ2UgPSBuZXcgR2VuZXJhdGVFdmVudChtX3RyYW5zZm9ybWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX0NPTU1FTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhjaCwgc3RhcnQsIGxlbmd0aCkpOwotCi0gICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChnZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEVudGl0eSByZWZlcmVuY2UgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgZW50aXR5Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbnRpdHlSZWZlcmVuY2UoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgZmx1c2hQZW5kaW5nKHRydWUpOwotCi0gICAgaWYgKG51bGwgIT0gbV9sZXhpY2FsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2xleGljYWxIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICAgICAgbV9sZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gbV90cmFjZXIpCi0gICAgewotICAgICAgR2VuZXJhdGVFdmVudCBnZSA9IG5ldyBHZW5lcmF0ZUV2ZW50KG1fdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfRU5USVRZUkVGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwotCi0gICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChnZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IGFuIGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgZW50aXR5Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuc3RhcnRFbnRpdHkobmFtZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEVuZCBhbiBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIGVudGl0eQotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGZsdXNoUGVuZGluZyh0cnVlKTsKLQotICAgIGlmIChudWxsICE9IG1fbGV4aWNhbEhhbmRsZXIpCi0gICAgewotICAgICAgbV9sZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gbV90cmFjZXIpCi0gICAgewotICAgICAgR2VuZXJhdGVFdmVudCBnZSA9IG5ldyBHZW5lcmF0ZUV2ZW50KG1fdHJhbnNmb3JtZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdGVFdmVudC5FVkVOVFRZUEVfRU5USVRZUkVGLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwotCi0gICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChnZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IHRoZSBEVEQuCi0gICAqCi0gICAqIEBwYXJhbSBzMSBUaGUgZG9jdW1lbnQgdHlwZSBuYW1lLgotICAgKiBAcGFyYW0gczIgVGhlIGRlY2xhcmVkIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUKLSAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAqIEBwYXJhbSBzMyBUaGUgZGVjbGFyZWQgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZQotICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFN0cmluZyBzMSwgU3RyaW5nIHMyLCBTdHJpbmcgczMpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuc3RhcnREVEQoczEsIHMyLCBzMyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEVuZCB0aGUgRFRELgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuZW5kRFREKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IHRoZSBDREFUQUNoYXJhY3RlcnMuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuc3RhcnRDREFUQSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBFbmQgdGhlIENEQVRBIGNoYXJhY3RlcnMuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgZmx1c2hQZW5kaW5nKHRydWUpOwotCi0gICAgaWYgKG51bGwgIT0gbV9sZXhpY2FsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2xleGljYWxIYW5kbGVyLmVuZENEQVRBKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBlbnRpdHkKLSAgICogc2tpcHBlZC4gIE5vbi12YWxpZGF0aW5nIHByb2Nlc3NvcnMgbWF5IHNraXAgZW50aXRpZXMgaWYgdGhleQotICAgKiBoYXZlIG5vdCBzZWVuIHRoZSBkZWNsYXJhdGlvbnMgKGJlY2F1c2UsIGZvciBleGFtcGxlLCB0aGUKLSAgICogZW50aXR5IHdhcyBkZWNsYXJlZCBpbiBhbiBleHRlcm5hbCBEVEQgc3Vic2V0KS4gIEFsbCBwcm9jZXNzb3JzCi0gICAqIG1heSBza2lwIGV4dGVybmFsIGVudGl0aWVzLCBkZXBlbmRpbmcgb24gdGhlIHZhbHVlcyBvZiB0aGUKLSAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLWdlbmVyYWwtZW50aXRpZXMgYW5kIHRoZQotICAgKiBodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvZXh0ZXJuYWwtcGFyYW1ldGVyLWVudGl0aWVzCi0gICAqIHByb3BlcnRpZXMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2tpcHBlZCBlbnRpdHkuICBJZiBpdCBpcyBhCi0gICAqICAgICAgICBwYXJhbWV0ZXIgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb257fQotCi0gIC8qKgotICAgKiBTZXQgd2hldGhlciBOYW1lc3BhY2UgZGVjbGFyYXRpb25zIGhhdmUgYmVlbiBhZGRlZCB0bwotICAgKiB0aGlzIGVsZW1lbnQKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGIgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgTmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICAgKiBoYXZlIGJlZW4gYWRkZWQgdG8gdGhpcyBlbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROU0RlY2xzSGF2ZUJlZW5BZGRlZChib29sZWFuIGIpCi0gIHsKLQotICAgIG1fbnNEZWNsc0hhdmVCZWVuQWRkZWQgPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIEZsdXNoIHRoZSBldmVudC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgdm9pZCBmbHVzaERvY0V2ZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9kb2NQZW5kaW5nKQotICAgIHsKLSAgICAgIG1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotCi0gICAgICBpZiAobnVsbCAhPSBtX3RyYWNlcikKLSAgICAgIHsKLSAgICAgICAgR2VuZXJhdGVFdmVudCBnZSA9Ci0gICAgICAgICAgbmV3IEdlbmVyYXRlRXZlbnQobV90cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0ZUV2ZW50LkVWRU5UVFlQRV9TVEFSVERPQ1VNRU5UKTsKLQotICAgICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChnZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJDbGllbnQpCi0gICAgICB7Ci0gICAgICAgICgoVHJhbnNmb3JtZXJDbGllbnQpIG1fY29udGVudEhhbmRsZXIpLnNldFRyYW5zZm9ybVN0YXRlKHRoaXMpOwotICAgICAgfQotCi0gICAgICBtX2RvY1BlbmRpbmcgPSBmYWxzZTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBGbHVzaCB0aGUgZXZlbnQuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICB2b2lkIGZsdXNoRWxlbSgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG1fZWxlbUlzUGVuZGluZykKLSAgICB7Ci0gICAgICBpZiAobnVsbCAhPSBtX25hbWUpCi0gICAgICB7Ci0gICAgICAgIG1fY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KG1fdXJsLCBtX2xvY2FsTmFtZSwgbV9uYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2F0dHJpYnV0ZXMpOwotICAgICAgICAKLSAgICAgICAgaWYobnVsbCAhPSBtX3RyYWNlcikKLSAgICAgICAgewotICAgICAgICAgIEdlbmVyYXRlRXZlbnQgZ2UgPQotICAgICAgICAgICAgbmV3IEdlbmVyYXRlRXZlbnQobV90cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRlRXZlbnQuRVZFTlRUWVBFX1NUQVJURUxFTUVOVCwgbV9uYW1lLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2F0dHJpYnV0ZXMpOwotICAKLSAgICAgICAgICBtX3RyYWNlci5maXJlR2VuZXJhdGVFdmVudChnZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYobV9pc1RyYW5zZm9ybUNsaWVudCkKLSAgICAgICAgICBtX3NuYXBzaG90Lm1fY3VycmVudE5vZGUgPSBudWxsOwotICAgICAgfQotCi0gICAgICBtX2VsZW1Jc1BlbmRpbmcgPSBmYWxzZTsKLSAgICAgIG1fYXR0cmlidXRlcy5jbGVhcigpOwotICAKLSAgICAgIG1fbnNEZWNsc0hhdmVCZWVuQWRkZWQgPSBmYWxzZTsKLSAgICAgIG1fbmFtZSA9IG51bGw7Ci0gICAgICBtX3VybCA9IG51bGw7Ci0gICAgICBtX2xvY2FsTmFtZSA9IG51bGw7Ci0gICAgICBtX25hbWVzcGFjZXMgPSBudWxsOwotCi0gICAgICAvLyBzdXBlci5mbHVzaCgpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIEZsdXNoIHRoZSBwZW5kaW5nIGVsZW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBmbHVzaFBlbmRpbmcoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBmbHVzaFBlbmRpbmcodHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogRmx1c2ggdGhlIHBlbmRpbmcgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHR5cGUgRXZlbnQgdHlwZQotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZmx1c2hQcmVmaXhlcwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgZmx1c2hQZW5kaW5nKGJvb2xlYW4gZmx1c2hQcmVmaXhlcykKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChmbHVzaFByZWZpeGVzICYmIG1fZG9jUGVuZGluZykKLSAgICB7Ci0gICAgICBmbHVzaERvY0V2ZW50KCk7Ci0gICAgfQotCi0gICAgaWYgKG1fZWxlbUlzUGVuZGluZykKLSAgICB7Ci0gICAgICAvLyBDb21iaW5lZCBsb29wIHNob3VkIGJlIG11Y2ggbW9yZSBlZmZpY2llbnQuCi0gICAgICAvLyAlUkVWSUVXJSAlT1BUJSBXaWxsIHRoZSAiZWxzZSIgY2FzZSBldmVyIGFyaXNlPwotICAgICAgaWYgKCFtX25zRGVjbHNIYXZlQmVlbkFkZGVkKQotLy8gICAgICAgIGFkZE5TRGVjbHNUb0F0dHJzKCk7Ci0gICAgICAgICAgc3RhcnRBbmRBZGRQcmVmaXhNYXBwaW5ncygpOyAgLy8gbmV3Ci0gICAgICBlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmV3Ci0gICAgICAgICAgc2VuZFN0YXJ0UHJlZml4TWFwcGluZ3MoKTsKLQotCi0gICAgICBpZiAoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVzdWx0VHJlZUhhbmRsZXIjZmx1c2hQZW5kaW5nIC0gc3RhcnQgZmx1c2g6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbV9uYW1lKTsKLSAgICAgIH0KLQotICAgICAgZmx1c2hFbGVtKCk7Ci0KLSAgICAgIGlmIChERUJVRykKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAgICJSZXN1bHRUcmVlSGFuZGxlciNmbHVzaFBlbmRpbmcgLSBhZnRlciBmbHVzaCwgaXNQZW5kaW5nOiAiCi0gICAgICAgICAgKyBtX2VsZW1Jc1BlbmRpbmcpOwotICAgICAgfQotCi0gICAgICBtX25zQ29udGV4dFB1c2hlZCA9IGZhbHNlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LCB3YWxrIHRoZSB0cmVlIGFuZAotICAgKiBvdXRwdXQgaXQgdG8gdGhlIHJlc3VsdCBzdHJlYW0uCi0gICAqCi0gICAqIEBwYXJhbSBvYmogUmVzdWx0IHRyZWUgZnJhZ21lbnQgb2JqZWN0Ci0gICAqIEBwYXJhbSBzdXBwb3J0IFhQYXRoIGNvbnRleHQgZm9yIHRoZSByZXN1bHQgdHJlZSBmcmFnbWVudAotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgb3V0cHV0UmVzdWx0VHJlZUZyYWdtZW50KFhPYmplY3Qgb2JqLCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBkb2MgPSBvYmoucnRmKCk7Ci0gICAgRFRNIGR0bSA9IHN1cHBvcnQuZ2V0RFRNKGRvYyk7Ci0KLSAgICBmb3IgKGludCBuID0gZHRtLmdldEZpcnN0Q2hpbGQoZG9jKTsgRFRNLk5VTEwgIT0gbjsKLSAgICAgICAgICAgIG4gPSBkdG0uZ2V0TmV4dFNpYmxpbmcobikpCi0gICAgewotICAgICAgZmx1c2hQZW5kaW5nKHRydWUpOyAgLy8gSSB0aGluay4KLSAgICAgIGR0bS5kaXNwYXRjaFRvRXZlbnRzKG4sIHRoaXMpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUbyBmdWxsZmlsbCB0aGUgRm9ybWF0dGVyTGlzdGVuZXIgaW50ZXJmYWNlLi4uIG5vIGFjdGlvbgotICAgKiBmb3IgdGhlIG1vbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0b3IgRG9jdW1lbnQgbG9jYXRvcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcil7fQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyB0byBtYWtlIHN1cmUgYSBnaXZlbiBwcmVmaXggaXMgcmVhbGx5Ci0gICAqIGRlY2xhcmVkLiAgSXQgbWlnaHQgbm90IGJlLCBiZWNhdXNlIGl0IG1heSBiZSBhbiBleGNsdWRlZCBwcmVmaXguCi0gICAqIElmIGl0J3Mgbm90LCBpdCBzdGlsbCBuZWVkcyB0byBiZSBkZWNsYXJlZCBhdCB0aGlzIHBvaW50LgotICAgKiBUT0RPOiBUaGlzIG5lZWRzIHRvIGJlIGRvbmUgYXQgYW4gZWFybGllciBzdGFnZSBpbiB0aGUgZ2FtZS4uLiAtc2IKLSAgICoKLSAgICogQHBhcmFtIG5zIE5hbWVzcGFjZSBVUkkgb2YgdGhlIGVsZW1lbnQKLSAgICogQHBhcmFtIHJhd05hbWUgUmF3IG5hbWUgb2YgZWxlbWVudCAod2l0aCBwcmVmaXgpCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbnN1cmVQcmVmaXhJc0RlY2xhcmVkKFN0cmluZyBucywgU3RyaW5nIHJhd05hbWUpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnMgIT0gbnVsbCAmJiBucy5sZW5ndGgoKSA+IDApCi0gICAgewotICAgICAgaW50IGluZGV4OwotICAgICAgU3RyaW5nIHByZWZpeCA9IChpbmRleCA9IHJhd05hbWUuaW5kZXhPZigiOiIpKSA8IDAKLSAgICAgICAgICAgICAgICAgICAgICA/ICIiIDogcmF3TmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotCi0gICAgICBpZiAobnVsbCAhPSBwcmVmaXgpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBmb3VuZFVSSSA9IG1fbnNTdXBwb3J0LmdldFVSSShwcmVmaXgpOwotCi0gICAgICAgIGlmICgobnVsbCA9PSBmb3VuZFVSSSkgfHwhZm91bmRVUkkuZXF1YWxzKG5zKSkKLSAgICAgICAgewotICAgICAgICAgIHN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIG5zLCBmYWxzZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBjaGVja3MgdG8gbWFrZSBzdXJlIGEgZ2l2ZW4gcHJlZml4IGlzIHJlYWxseQotICAgKiBkZWNsYXJlZC4gIEl0IG1pZ2h0IG5vdCBiZSwgYmVjYXVzZSBpdCBtYXkgYmUgYW4gZXhjbHVkZWQgcHJlZml4LgotICAgKiBJZiBpdCdzIG5vdCwgaXQgc3RpbGwgbmVlZHMgdG8gYmUgZGVjbGFyZWQgYXQgdGhpcyBwb2ludC4KLSAgICogVE9ETzogVGhpcyBuZWVkcyB0byBiZSBkb25lIGF0IGFuIGVhcmxpZXIgc3RhZ2UgaW4gdGhlIGdhbWUuLi4gLXNiCi0gICAqCi0gICAqIEBwYXJhbSBucyBOYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSByYXdOYW1lIFJhdyBuYW1lIG9mIGVsZW1lbnQgKHdpdGggcHJlZml4KQotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZHRtCi0gICAqIE5FRURTRE9DIEBwYXJhbSBuYW1lc3BhY2UKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuc3VyZU5hbWVzcGFjZURlY2xEZWNsYXJlZChEVE0gZHRtLCBpbnQgbmFtZXNwYWNlKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHVyaSA9IGR0bS5nZXROb2RlVmFsdWUobmFtZXNwYWNlKTsKLSAgICBTdHJpbmcgcHJlZml4ID0gZHRtLmdldE5vZGVOYW1lWChuYW1lc3BhY2UpOwotCi0gICAgaWYgKCh1cmkgIT0gbnVsbCAmJiB1cmkubGVuZ3RoKCkgPiAwKSAmJiAobnVsbCAhPSBwcmVmaXgpKQotICAgIHsKLSAgICAgIFN0cmluZyBmb3VuZFVSSSA9IG1fbnNTdXBwb3J0LmdldFVSSShwcmVmaXgpOwotCi0gICAgICBpZiAoKG51bGwgPT0gZm91bmRVUkkpIHx8IWZvdW5kVVJJLmVxdWFscyh1cmkpKQotICAgICAgewotICAgICAgICBzdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCB1cmksIGZhbHNlKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIHRoZSBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSBiZWVuIGRlY2xhcmVkIHRvIHRoZSBhdHRyaWJ1dGUgbGlzdC4KLSAgICogKFNlZW1zIGxpa2UgSSBzaG91bGRuJ3QgaGF2ZSB0byBkbyB0aGlzLi4uKQotICAgKiBJbnRlcm5hbGx5IGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgY29tYmluZWQgc3RhcnRBbmRBZGRQcmVmaXhNYXBwaW5ncygpOwotICAgKiAKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHNlbmRTdGFydFByZWZpeE1hcHBpbmdzKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgRW51bWVyYXRpb24gcHJlZml4ZXMgPSBtX25zU3VwcG9ydC5nZXREZWNsYXJlZFByZWZpeGVzKCk7Ci0gICAgQ29udGVudEhhbmRsZXIgaGFuZGxlciA9IG1fY29udGVudEhhbmRsZXI7Ci0gICAgd2hpbGUgKHByZWZpeGVzLmhhc01vcmVFbGVtZW50cygpKQotICAgIHsKLSAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKSBwcmVmaXhlcy5uZXh0RWxlbWVudCgpOwotICAgICAgaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCBtX25zU3VwcG9ydC5nZXRVUkkocHJlZml4KSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEpKSzogQ29tYmluYXRpb24gb2Ygc2VuZFN0YXJ0UHJlZml4TWFwcGluZ3MgYW5kCi0gICAqIGFkZE5TRGVjbHNUb0F0dHJzKCkgKHdoaWNoIGl0IG1vc3RseSByZXBsYWNlcykuICBNZXJnaW5nIHRoZSB0d28KLSAgICogbG9vcHMgaXMgc2lnbmlmaWNhbnRseSBtb3JlIGVmZmljaWVudC4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gKi8KLSAgcHJvdGVjdGVkIHZvaWQgc3RhcnRBbmRBZGRQcmVmaXhNYXBwaW5ncygpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgRW51bWVyYXRpb24gcHJlZml4ZXMgPSBtX25zU3VwcG9ydC5nZXREZWNsYXJlZFByZWZpeGVzKCk7Ci0gICAgQ29udGVudEhhbmRsZXIgaGFuZGxlciA9IG1fY29udGVudEhhbmRsZXI7Ci0KLSAgICB3aGlsZSAocHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpIHByZWZpeGVzLm5leHRFbGVtZW50KCk7Ci0gICAgICBTdHJpbmcgdXJpPW1fbnNTdXBwb3J0LmdldFVSSShwcmVmaXgpOwotICAgICAgCi0gICAgICAvLyBTZW5kIGV2ZW50Ci0gICAgICBoYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSk7Ci0KLSAgICAgIC8vIFNldCBhdHRyaWJ1dGUKLSAgICAgIGJvb2xlYW4gaXNEZWZhdWx0ID0gKHByZWZpeC5sZW5ndGgoKSA9PSAwKTsKLSAgICAgIFN0cmluZyBuYW1lOwotCi0gICAgICBpZiAoaXNEZWZhdWx0KQotICAgICAgewotICAgICAgICAvL3ByZWZpeCA9ICJ4bWwiOwotICAgICAgICBuYW1lID0gInhtbG5zIjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgbmFtZSA9ICJ4bWxuczoiICsgcHJlZml4OwotCi0gICAgICBpZiAobnVsbCA9PSB1cmkpCi0gICAgICAgIHVyaSA9ICIiOwotCi0gICAgICBtX2F0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgsIG5hbWUsICJDREFUQSIsIHVyaSk7Ci0gICAgfQotICAgIG1fbnNEZWNsc0hhdmVCZWVuQWRkZWQ9dHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgdGhlIGF0dHJpYnV0ZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgdG8gdGhlIGF0dHJpYnV0ZSBsaXN0LgotICAgKiAoU2VlbXMgbGlrZSBJIHNob3VsZG4ndCBoYXZlIHRvIGRvIHRoaXMuLi4pCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBzZW5kRW5kUHJlZml4TWFwcGluZ3MoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIEVudW1lcmF0aW9uIHByZWZpeGVzID0gbV9uc1N1cHBvcnQuZ2V0RGVjbGFyZWRQcmVmaXhlcygpOwotICAgIENvbnRlbnRIYW5kbGVyIGhhbmRsZXIgPSBtX2NvbnRlbnRIYW5kbGVyOwotCi0gICAgd2hpbGUgKHByZWZpeGVzLmhhc01vcmVFbGVtZW50cygpKQotICAgIHsKLSAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKSBwcmVmaXhlcy5uZXh0RWxlbWVudCgpOwotCi0gICAgICBoYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdG8gc2VlIGlmIHdlIHNob3VsZCBzd2l0Y2ggc2VyaWFsaXplcnMgYmFzZWQgb24gdGhlCi0gICAqIGZpcnN0IG91dHB1dCBlbGVtZW50IGJlaW5nIGFuIEhUTUwgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5zIE5hbWVzcGFjZSBVUkkgb2YgdGhlIGVsZW1lbnQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBMb2NhbCBwYXJ0IG9mIG5hbWUgb2YgdGhlIGVsZW1lbnQKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgdm9pZCBjaGVja0ZvclNlcmlhbGl6ZXJTd2l0Y2goU3RyaW5nIG5zLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG1fZG9jUGVuZGluZykKLSAgICAgIHsKLSAgICAgICAgU2VyaWFsaXplclN3aXRjaGVyLnN3aXRjaFNlcmlhbGl6ZXJJZkhUTUwobV90cmFuc2Zvcm1lciwgbnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsTmFtZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIHRoZSBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSBiZWVuIGRlY2xhcmVkIHRvIHRoZSBhdHRyaWJ1dGUgbGlzdC4KLSAgICoKLSAgICogJVJFVklFVyUgVGhpcyBzaG91bGQgaGF2ZSBiZWVuIGRvbmUgYXV0b21hdGljYWxseSBkdXJpbmcKLSAgICogZmx1c2hQZW5kaW5nKGJvb2xlYW4pOyBpcyBpdCBldmVyIGV4cGxpY2l0bHkgcmVpbnZva2VkPwotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTlNEZWNsc1RvQXR0cnMoKQotICB7Ci0KLSAgICBFbnVtZXJhdGlvbiBwcmVmaXhlcyA9IG1fbnNTdXBwb3J0LmdldERlY2xhcmVkUHJlZml4ZXMoKTsKLQotICAgIHdoaWxlIChwcmVmaXhlcy5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZykgcHJlZml4ZXMubmV4dEVsZW1lbnQoKTsKLSAgICAgIGJvb2xlYW4gaXNEZWZhdWx0ID0gKHByZWZpeC5sZW5ndGgoKSA9PSAwKTsKLSAgICAgIFN0cmluZyBuYW1lOwotCi0gICAgICBpZiAoaXNEZWZhdWx0KQotICAgICAgewotCi0gICAgICAgIC8vcHJlZml4ID0gInhtbCI7Ci0gICAgICAgIG5hbWUgPSAieG1sbnMiOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICBuYW1lID0gInhtbG5zOiIgKyBwcmVmaXg7Ci0KLSAgICAgIFN0cmluZyB1cmkgPSBtX25zU3VwcG9ydC5nZXRVUkkocHJlZml4KTsKLQotICAgICAgaWYgKG51bGwgPT0gdXJpKQotICAgICAgICB1cmkgPSAiIjsKLQotICAgICAgbV9hdHRyaWJ1dGVzLmFkZEF0dHJpYnV0ZSgiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy8iLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBuYW1lLCAiQ0RBVEEiLCB1cmkpOwotICAgIH0KLQotICAgIG1fbnNEZWNsc0hhdmVCZWVuQWRkZWQgPSB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgPEtCRD54bWxuczo8L0tCRD4gYXR0cmlidXRlcyBpbiBpZiBub3QgYWxyZWFkeSBpbiBzY29wZS4KLSAgICoKLSAgICogQHBhcmFtIHNyYyBTb3VyY2UgTm9kZQotICAgKiBORUVEU0RPQyBAcGFyYW0gdHlwZQotICAgKiBORUVEU0RPQyBAcGFyYW0gZHRtCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NOU0RlY2xzKGludCBzcmMsIGludCB0eXBlLCBEVE0gZHRtKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAodHlwZSA9PSBEVE0uRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBmb3IgKGludCBuYW1lc3BhY2UgPSBkdG0uZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKHNyYywgdHJ1ZSk7Ci0gICAgICAgICAgICAgICAgRFRNLk5VTEwgIT0gbmFtZXNwYWNlOwotICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IGR0bS5nZXROZXh0TmFtZXNwYWNlTm9kZShzcmMsIG5hbWVzcGFjZSwgdHJ1ZSkpCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIFN0cmluZyBwcmVmaXggPSBkdG0uZ2V0UHJlZml4KG5hbWVzcGFjZSk7Ci0gICAgICAgICAgU3RyaW5nIHByZWZpeCA9IGR0bS5nZXROb2RlTmFtZVgobmFtZXNwYWNlKTsKLSAgICAgICAgICBTdHJpbmcgZGVzdHVyaSA9IGdldFVSSShwcmVmaXgpOwotICAgICAgICAgIFN0cmluZyBzcmNVUkkgPSBkdG0uZ2V0Tm9kZVZhbHVlKG5hbWVzcGFjZSk7Ci0KLSAgICAgICAgICBpZiAoIXNyY1VSSS5lcXVhbHNJZ25vcmVDYXNlKGRlc3R1cmkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRoaXMuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgc3JjVVJJLCBmYWxzZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBwcmVmaXgsIHJldHVybiB0aGUgbmFtZXNwYWNlLAotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IEdpdmVuIHByZWZpeCBuYW1lCi0gICAqCi0gICAqIEByZXR1cm4gTmFtZXNwYWNlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gcHJlZml4LCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFVSSShTdHJpbmcgcHJlZml4KQotICB7Ci0gICAgcmV0dXJuIG1fbnNTdXBwb3J0LmdldFVSSShwcmVmaXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlLCB0cnkgYW5kIGZpbmQgYSBwcmVmaXguCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgR2l2ZW4gbmFtZXNwYWNlIFVSSQotICAgKgotICAgKiBAcmV0dXJuIFByZWZpeCBuYW1lIGFzc29jaWF0ZWQgd2l0aCBuYW1lc3BhY2UgVVJJCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChTdHJpbmcgbmFtZXNwYWNlKQotICB7Ci0KLSAgICAvLyBUaGlzIEVudW1lcmF0aW9uIGJ1c2luZXNzIG1heSBiZSB0b28gc2xvdyBmb3Igb3VyIHB1cnBvc2VzLi4uCi0gICAgRW51bWVyYXRpb24gZW51bSA9IG1fbnNTdXBwb3J0LmdldFByZWZpeGVzKCk7Ci0KLSAgICB3aGlsZSAoZW51bS5oYXNNb3JlRWxlbWVudHMoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZykgZW51bS5uZXh0RWxlbWVudCgpOwotCi0gICAgICBpZiAobV9uc1N1cHBvcnQuZ2V0VVJJKHByZWZpeCkuZXF1YWxzKG5hbWVzcGFjZSkpCi0gICAgICAgIHJldHVybiBwcmVmaXg7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBOYW1lc3BhY2VTdXBwb3J0IG9iamVjdC4KLSAgICoKLSAgICogQHJldHVybiBOYW1lc3BhY2VTdXBwb3J0IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBOYW1lc3BhY2VTdXBwb3J0IGdldE5hbWVzcGFjZVN1cHBvcnQoKQotICB7Ci0gICAgcmV0dXJuIG1fbnNTdXBwb3J0OwotICB9Ci0KLSAgLy8gIC8qKgotICAvLyAgICogT3ZlcnJpZGUgUXVldWVkRXZlbnRzI2luaXRRU0UuCi0gIC8vICAgKgotICAvLyAgICogQHBhcmFtIHFzZSBHaXZlIHF1ZXVlZCBTYXggZXZlbnQKLSAgLy8gICAqLwotICAvLyAgcHJvdGVjdGVkIHZvaWQgaW5pdFFTRShRdWV1ZWRTQVhFdmVudCBxc2UpCi0gIC8vICB7Ci0gIC8vCi0gIC8vICAgIC8vIHFzZS5zZXRDb250ZW50SGFuZGxlcihtX2NvbnRlbnRIYW5kbGVyKTsKLSAgLy8gICAgLy8gcXNlLnNldFRyYW5zZm9ybWVyKG1fdHJhbnNmb3JtZXIpOwotICAvLyAgICAvLyBxc2Uuc2V0VHJhY2VNYW5hZ2VyKG1fdHJhY2VyKTsKLSAgLy8gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBjdXJyZW50IGNvbnRlbnQgaGFuZGxlci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZW50IGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAqIEBzZWUgI3NldENvbnRlbnRIYW5kbGVyCi0gICAqLwotICBwdWJsaWMgZmluYWwgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fY29udGVudEhhbmRsZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IGNvbnRlbnQgaGFuZGxlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGNoIENvbnRlbnQgSGFuZGxlciB0byBiZSBzZXQKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBjb250ZW50IGhhbmRsZXIsIG9yIG51bGwgaWYgbm9uZQotICAgKiAgICAgICAgIGhhcyBiZWVuIHJlZ2lzdGVyZWQuCi0gICAqIEBzZWUgI2dldENvbnRlbnRIYW5kbGVyCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBjaCkKLSAgewotCi0gICAgbV9jb250ZW50SGFuZGxlciA9IGNoOwotCi0gICAgbV9pc1RyYW5zZm9ybUNsaWVudCA9IChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJDbGllbnQpOwotCi0gICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIgPSAoTGV4aWNhbEhhbmRsZXIpIG1fY29udGVudEhhbmRsZXI7Ci0gICAgZWxzZQotICAgICAgbV9sZXhpY2FsSGFuZGxlciA9IG51bGw7Ci0KLSAgICByZUluaXRFdmVudHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSB1bmlxdWUgbmFtZXNwYWNlIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIGEgdW5pcXVlIG5hbWVzcGFjZSB2YWx1ZSB0byBiZSB1c2VkIHdpdGggYQotICAgKiBmYWJyaWNhdGVkIHByZWZpeAotICAgKi8KLSAgcHVibGljIGludCBnZXRVbmlxdWVOU1ZhbHVlKCkKLSAgewotICAgIHJldHVybiBtX3VuaXF1ZU5TVmFsdWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgbmV3IHVuaXF1ZSBuYW1lc3BhY2UgcHJlZml4LgotICAgKgotICAgKiBAcmV0dXJuIFVuaXF1ZSBmYWJyaWNhdGVkIHByZWZpeC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmV3VW5pcXVlTlNQcmVmaXgoKQotICB7Ci0gICAgcmV0dXJuIFNfTkFNRVNQQUNFUFJFRklYICsgU3RyaW5nLnZhbHVlT2YoZ2V0VW5pcXVlTlNWYWx1ZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBlbmRpbmcgYXR0cmlidXRlcy4gIFdlIGhhdmUgdG8gZGVsYXkgdGhlIGNhbGwgdG8KLSAgICogbV9mbGlzdGVuZXIuc3RhcnRFbGVtZW50KG5hbWUsIGF0dHMpIGJlY2F1c2Ugb2YgdGhlCi0gICAqIHhzbDphdHRyaWJ1dGUgYW5kIHhzbDpjb3B5IGNhbGxzLiAgSW4gb3RoZXIgd29yZHMsCi0gICAqIHRoZSBhdHRyaWJ1dGVzIGhhdmUgdG8gYmUgZnVsbHkgY29sbGVjdGVkIGJlZm9yZSB5b3UKLSAgICogY2FuIGNhbGwgc3RhcnRFbGVtZW50LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwZW5kaW5nIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgTXV0YWJsZUF0dHJMaXN0SW1wbCBnZXRQZW5kaW5nQXR0cmlidXRlcygpCi0gIHsKLSAgICByZXR1cm4gbV9hdHRyaWJ1dGVzOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogPHA+RG8gbm90IHBhc3MgaW4geG1sbnMgZGVjbHMgdG8gdGhpcyBmdW5jdGlvbiEKLSAgICoKLSAgICogPHA+Rm9yIHRoZSBzYWtlIG9mIHNwZWVkLCB0aGlzIG1ldGhvZCBkb2VzIG5vIGNoZWNraW5nCi0gICAqIHRvIHNlZSBpZiB0aGUgYXR0cmlidXRlIGlzIGFscmVhZHkgaW4gdGhlIGxpc3Q6IHRoYXQgaXMKLSAgICogdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICogICAgICAgIG5vbmUgaXMgYXZhaWxhYmxlIG9yIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdAotICAgKiAgICAgICAgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqICAgICAgICBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcmF3TmFtZSBUaGUgcmF3IFhNTCAxLjAgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZwotICAgKiAgICAgICAgaWYgcmF3IG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gdHlwZSBUaGUgYXR0cmlidXRlIHR5cGUgYXMgYSBzdHJpbmcuCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRBdHRyaWJ1dGUoCi0gICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHJhd05hbWUsIFN0cmluZyB0eXBlLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gJVJFVklFVyUgJU9QVCUgSXMgdGhpcyBldmVyIG5lZWRlZD8/Pz8/Ci0gICAgaWYgKCFtX25zRGVjbHNIYXZlQmVlbkFkZGVkKQotICAgICAgYWRkTlNEZWNsc1RvQXR0cnMoKTsKLQotICAgIGlmIChudWxsID09IHVyaSkgIC8vIGRlZmVuc2l2ZSwgc2hvdWxkIG5vdCByZWFsbHkgbmVlZCB0aGlzLgotICAgICAgdXJpID0gIiI7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAoIXJhd05hbWUuZXF1YWxzKCJ4bWxucyIpKSAgLy8gZG9uJ3QgaGFuZGxlIHhtbG5zIGRlZmF1bHQgbmFtZXNwYWNlLgotICAgICAgICBlbnN1cmVQcmVmaXhJc0RlY2xhcmVkKHVyaSwgcmF3TmFtZSk7Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICB9Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlc3VsdFRyZWVIYW5kbGVyI2FkZEF0dHJpYnV0ZSBBZGRpbmcgYXR0cjogIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgbG9jYWxOYW1lICsgIiwgIiArIHVyaSk7Ci0KLSAgICBpZiAoIWlzRGVmaW5lZE5TRGVjbChyYXdOYW1lLCB2YWx1ZSkpCi0gICAgICBtX2F0dHJpYnV0ZXMuYWRkQXR0cmlidXRlKHVyaSwgbG9jYWxOYW1lLCByYXdOYW1lLCB0eXBlLCB2YWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHdoZXRoZXIgb3Igbm90IGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGRlZmluZWQKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHJhd05hbWUgUmF3IG5hbWUgb2YgbmFtZXNwYWNlIGVsZW1lbnQKLSAgICogQHBhcmFtIHZhbHVlIFVSSSBvZiBnaXZlbiBuYW1lc3BhY2UKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBuYW1lc3BhY2UgaXMgYWxyZWFkeSBkZWZpbmVkIGluIGxpc3Qgb2YKLSAgICogbmFtZXNwYWNlcwotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEZWZpbmVkTlNEZWNsKFN0cmluZyByYXdOYW1lLCBTdHJpbmcgdmFsdWUpCi0gIHsKLQotICAgIGlmIChyYXdOYW1lLmVxdWFscygieG1sbnMiKSB8fCByYXdOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKQotICAgIHsKLSAgICAgIGludCBpbmRleDsKLSAgICAgIFN0cmluZyBwcmVmaXggPSAoaW5kZXggPSByYXdOYW1lLmluZGV4T2YoIjoiKSkgPCAwCi0gICAgICAgICAgICAgICAgICAgICAgPyAiIiA6IHJhd05hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICAgIFN0cmluZyBkZWZpbmVkVVJJID0gbV9uc1N1cHBvcnQuZ2V0VVJJKHByZWZpeCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGRlZmluZWRVUkkpCi0gICAgICB7Ci0gICAgICAgIGlmIChkZWZpbmVkVVJJLmVxdWFscyh2YWx1ZSkpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHdoZXRoZXIgYSBuYW1lc3BhY2UgaXMgZGVmaW5lZAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXR0ciBOYW1lc3BhY2UgYXR0cmlidXRlIG5vZGUKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBuYW1lc3BhY2UgaXMgYWxyZWFkeSBkZWZpbmVkIGluCi0gICAqIGxpc3Qgb2YgbmFtZXNwYWNlcwotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEZWZpbmVkTlNEZWNsKGludCBhdHRyKQotICB7Ci0KLSAgICBEVE0gZHRtID0gbV90cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0oYXR0cik7Ci0KLSAgICBpZiAoRFRNLk5BTUVTUEFDRV9OT0RFID09IGR0bS5nZXROb2RlVHlwZShhdHRyKSkKLSAgICB7Ci0KLSAgICAgIC8vIFN0cmluZyBwcmVmaXggPSBkdG0uZ2V0UHJlZml4KGF0dHIpOwotICAgICAgU3RyaW5nIHByZWZpeCA9IGR0bS5nZXROb2RlTmFtZVgoYXR0cik7Ci0gICAgICBTdHJpbmcgdXJpID0gZ2V0VVJJKHByZWZpeCk7Ci0KLSAgICAgIGlmICgobnVsbCAhPSB1cmkpICYmIHVyaS5lcXVhbHMoZHRtLmdldFN0cmluZ1ZhbHVlKGF0dHIpKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgd2hldGhlciBhIG5hbWVzcGFjZSBpcyBkZWZpbmVkCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyIE5hbWVzcGFjZSBhdHRyaWJ1dGUgbm9kZQotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gdGhhdCBvd25zIGF0dHIuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbmFtZXNwYWNlIGlzIGFscmVhZHkgZGVmaW5lZCBpbgotICAgKiBsaXN0IG9mIG5hbWVzcGFjZXMKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRGVmaW5lZE5TRGVjbChpbnQgYXR0ciwgRFRNIGR0bSkKLSAgewotCi0gICAgaWYgKERUTS5OQU1FU1BBQ0VfTk9ERSA9PSBkdG0uZ2V0Tm9kZVR5cGUoYXR0cikpCi0gICAgewotCi0gICAgICAvLyBTdHJpbmcgcHJlZml4ID0gZHRtLmdldFByZWZpeChhdHRyKTsKLSAgICAgIFN0cmluZyBwcmVmaXggPSBkdG0uZ2V0Tm9kZU5hbWVYKGF0dHIpOwotICAgICAgU3RyaW5nIHVyaSA9IGdldFVSSShwcmVmaXgpOwotCi0gICAgICBpZiAoKG51bGwgIT0gdXJpKSAmJiB1cmkuZXF1YWxzKGR0bS5nZXRTdHJpbmdWYWx1ZShhdHRyKSkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IGFuIERPTSBhdHRyaWJ1dGUgdG8gdGhlIGNyZWF0ZWQgb3V0cHV0IGVsZW1lbnQsIGV4ZWN1dGluZwotICAgKiBhdHRyaWJ1dGUgdGVtcGxhdGVzIGFzIG5lZWQgYmUsIGFuZCBwcm9jZXNzaW5nIHRoZSB4c2w6dXNlCi0gICAqIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIGF0dHIgQXR0cmlidXRlIG5vZGUgdG8gYWRkIHRvIHJlc3VsdCB0cmVlCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShpbnQgYXR0cikgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTSBkdG0gPSBtX3RyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldERUTShhdHRyKTsKLQotICAgIGlmIChpc0RlZmluZWROU0RlY2woYXR0ciwgZHRtKSkKLSAgICAgIHJldHVybjsKLQotICAgIFN0cmluZyBucyA9IGR0bS5nZXROYW1lc3BhY2VVUkkoYXR0cik7Ci0KLSAgICBpZiAobnMgPT0gbnVsbCkKLSAgICAgIG5zID0gIiI7Ci0KLSAgICAvLyAlT1BUJSAuLi5jYW4gSSBqdXN0IHN0b3JlIHRoZSBub2RlIGhhbmRsZT8gICAgCi0gICAgYWRkQXR0cmlidXRlKG5zLCBkdG0uZ2V0TG9jYWxOYW1lKGF0dHIpLCBkdG0uZ2V0Tm9kZU5hbWUoYXR0ciksICJDREFUQSIsCi0gICAgICAgICAgICAgICAgIGR0bS5nZXROb2RlVmFsdWUoYXR0cikpOwotICB9ICAvLyBlbmQgY29weUF0dHJpYnV0ZVRvVGFyZ2V0IG1ldGhvZAotCi0gIC8qKgotICAgKiBDb3B5IERPTSBhdHRyaWJ1dGVzIHRvIHRoZSByZXN1bHQgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHNyYyBTb3VyY2Ugbm9kZSB3aXRoIHRoZSBhdHRyaWJ1dGVzCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZXMoaW50IHNyYykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTSBkdG0gPSBtX3RyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldERUTShzcmMpOwotCi0gICAgZm9yIChpbnQgbm9kZSA9IGR0bS5nZXRGaXJzdEF0dHJpYnV0ZShzcmMpOyBEVE0uTlVMTCAhPSBub2RlOwotICAgICAgICAgICAgbm9kZSA9IGR0bS5nZXROZXh0QXR0cmlidXRlKG5vZGUpKQotICAgIHsKLSAgICAgIGFkZEF0dHJpYnV0ZShub2RlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiBhbiBlbGVtZW50IGlzIHBlbmRpbmcsIHRvIGJlIG91dHB1dCB0byB0aGUgcmVzdWx0IHRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBhbiBlbGVtZW50IGlzIHBlbmRpbmcKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzRWxlbWVudFBlbmRpbmcoKQotICB7Ci0gICAgCi0gICAgcmV0dXJuIG1fZWxlbUlzUGVuZGluZzsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgdGhlIHN0eWxlc2hlZXQgZWxlbWVudCB0aGF0IHByb2R1Y2VkCi0gICAqIHRoZSBTQVggZXZlbnQuCi0gICAqCi0gICAqIDxwPlBsZWFzZSBub3RlIHRoYXQgdGhlIEVsZW1UZW1wbGF0ZUVsZW1lbnQgcmV0dXJuZWQgbWF5Ci0gICAqIGJlIGluIGEgZGVmYXVsdCB0ZW1wbGF0ZSwgYW5kIHRodXMgbWF5IG5vdCBiZQotICAgKiBkZWZpbmVkIGluIHRoZSBzdHlsZXNoZWV0LjwvcD4KLSAgICoKLSAgICogQHJldHVybiB0aGUgc3R5bGVzaGVldCBlbGVtZW50IHRoYXQgcHJvZHVjZWQgdGhlIFNBWCBldmVudC4KLSAgICovCi0gIHB1YmxpYyBFbGVtVGVtcGxhdGVFbGVtZW50IGdldEN1cnJlbnRFbGVtZW50KCkKLSAgewotCi0gICAgaWYgKG1fZWxlbUlzUGVuZGluZykKLSAgICAgIHJldHVybiBtX3NuYXBzaG90Lm1fY3VycmVudEVsZW1lbnQ7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fdHJhbnNmb3JtZXIuZ2V0Q3VycmVudEVsZW1lbnQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlCi0gICAqIGluIHRoZSBzb3VyY2UgdHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0Q3VycmVudE5vZGUoKQotICB7Ci0gICAgCi0gICAgaWYgKG1fc25hcHNob3QubV9jdXJyZW50Tm9kZSAhPSBudWxsKQotICAgIHsKLSAgICAgIHJldHVybiBtX3NuYXBzaG90Lm1fY3VycmVudE5vZGU7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBEVE0gZHRtID0gbV90cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0obV90cmFuc2Zvcm1lci5nZXRDdXJyZW50Tm9kZSgpKTsKLSAgICAgIHJldHVybiBkdG0uZ2V0Tm9kZShtX3RyYW5zZm9ybWVyLmdldEN1cnJlbnROb2RlKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIHhzbDp0ZW1wbGF0ZQotICAgKiB0aGF0IGlzIGluIGVmZmVjdCwgd2hpY2ggbWF5IGJlIGEgbWF0Y2hlZCB0ZW1wbGF0ZQotICAgKiBvciBhIG5hbWVkIHRlbXBsYXRlLgotICAgKgotICAgKiA8cD5QbGVhc2Ugbm90ZSB0aGF0IHRoZSBFbGVtVGVtcGxhdGUgcmV0dXJuZWQgbWF5Ci0gICAqIGJlIGEgZGVmYXVsdCB0ZW1wbGF0ZSwgYW5kIHRodXMgbWF5IG5vdCBoYXZlIGEgdGVtcGxhdGUKLSAgICogZGVmaW5lZCBpbiB0aGUgc3R5bGVzaGVldC48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIHhzbDp0ZW1wbGF0ZSB0aGF0IGlzIGluIGVmZmVjdAotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZSBnZXRDdXJyZW50VGVtcGxhdGUoKQotICB7Ci0KLSAgICBpZiAobV9lbGVtSXNQZW5kaW5nKQotICAgICAgcmV0dXJuIG1fc25hcHNob3QubV9jdXJyZW50VGVtcGxhdGU7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fdHJhbnNmb3JtZXIuZ2V0Q3VycmVudFRlbXBsYXRlKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgcmV0cmlldmVzIHRoZSB4c2w6dGVtcGxhdGUKLSAgICogdGhhdCB3YXMgbWF0Y2hlZC4gIE5vdGUgdGhhdCB0aGlzIG1heSBub3QgYmUKLSAgICogdGhlIHNhbWUgdGhpbmcgYXMgdGhlIGN1cnJlbnQgdGVtcGxhdGUgKHdoaWNoCi0gICAqIG1heSBiZSBmcm9tIGdldEN1cnJlbnRFbGVtZW50KCkpLCBzaW5jZSBhIG5hbWVkCi0gICAqIHRlbXBsYXRlIG1heSBiZSBpbiBlZmZlY3QuCi0gICAqCi0gICAqIDxwPlBsZWFzZSBub3RlIHRoYXQgdGhlIEVsZW1UZW1wbGF0ZSByZXR1cm5lZCBtYXkKLSAgICogYmUgYSBkZWZhdWx0IHRlbXBsYXRlLCBhbmQgdGh1cyBtYXkgbm90IGhhdmUgYSB0ZW1wbGF0ZQotICAgKiBkZWZpbmVkIGluIHRoZSBzdHlsZXNoZWV0LjwvcD4KLSAgICoKLSAgICogQHJldHVybiB0aGUgeHNsOnRlbXBsYXRlIHRoYXQgd2FzIG1hdGNoZWQuCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlIGdldE1hdGNoZWRUZW1wbGF0ZSgpCi0gIHsKLQotICAgIGlmIChtX2VsZW1Jc1BlbmRpbmcpCi0gICAgICByZXR1cm4gbV9zbmFwc2hvdC5tX21hdGNoZWRUZW1wbGF0ZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV90cmFuc2Zvcm1lci5nZXRNYXRjaGVkVGVtcGxhdGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlIHRoYXQgbWF0Y2hlZAotICAgKiB0aGUgdGVtcGxhdGUgb2J0YWluZWQgdmlhIGdldE1hdGNoZWRUZW1wbGF0ZSgpLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZSB0aGF0IG1hdGNoZWQKLSAgICogdGhlIHRlbXBsYXRlIG9idGFpbmVkIHZpYSBnZXRNYXRjaGVkVGVtcGxhdGUoKS4KLSAgICovCi0gIHB1YmxpYyBvcmcudzNjLmRvbS5Ob2RlIGdldE1hdGNoZWROb2RlKCkKLSAgewotCi0gICAgaWYgKG1fZWxlbUlzUGVuZGluZykKLSAgICB7Ci0gICAgICBEVE0gZHRtID0gbV90cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0obV9zbmFwc2hvdC5tX21hdGNoZWROb2RlKTsKLSAgICAgIHJldHVybiBkdG0uZ2V0Tm9kZShtX3NuYXBzaG90Lm1fbWF0Y2hlZE5vZGUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgRFRNIGR0bSA9IG1fdHJhbnNmb3JtZXIuZ2V0WFBhdGhDb250ZXh0KCkuZ2V0RFRNKG1fdHJhbnNmb3JtZXIuZ2V0TWF0Y2hlZE5vZGUoKSk7Ci0gICAgICByZXR1cm4gZHRtLmdldE5vZGUobV90cmFuc2Zvcm1lci5nZXRNYXRjaGVkTm9kZSgpKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IgZ2V0Q29udGV4dE5vZGVMaXN0KCkKLSAgewotCi0gICAgaWYgKG1fZWxlbUlzUGVuZGluZykKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKG1fc25hcHNob3QubV9jb250ZXh0Tm9kZUxpc3QpOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbmV3IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKG1fdHJhbnNmb3JtZXIuZ2V0Q29udGV4dE5vZGVMaXN0KCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgVHJBWCBUcmFuc2Zvcm1lciBvYmplY3QgaW4gZWZmZWN0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBUckFYIFRyYW5zZm9ybWVyIG9iamVjdCBpbiBlZmZlY3QuCi0gICAqLwotICBwdWJsaWMgVHJhbnNmb3JtZXIgZ2V0VHJhbnNmb3JtZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fdHJhbnNmb3JtZXI7Ci0gIH0KLSAgCi0gIAotICAvLyBJbXBsZW1lbnQgRXJyb3JIYW5kbGVyCi0gIAotICAvKioKLSAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgd2FybmluZy4KLSAgICAqCi0gICAgKiA8cD5TQVggcGFyc2VycyB3aWxsIHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgY29uZGl0aW9ucyB0aGF0Ci0gICAgKiBhcmUgbm90IGVycm9ycyBvciBmYXRhbCBlcnJvcnMgYXMgZGVmaW5lZCBieSB0aGUgWE1MIDEuMAotICAgICogcmVjb21tZW5kYXRpb24uICBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gdGFrZSBubyBhY3Rpb24uPC9wPgotICAgICoKLSAgICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKLSAgICAqIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kOiBpdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZQotICAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLjwvcD4KLSAgICAqCi0gICAgKiA8cD5GaWx0ZXJzIG1heSB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IG90aGVyLCBub24tWE1MIHdhcm5pbmdzCi0gICAgKiBhcyB3ZWxsLjwvcD4KLSAgICAqCi0gICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uIAotICAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm5pbmcgKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcikKLSAgICAgICgoRXJyb3JIYW5kbGVyKW1fY29udGVudEhhbmRsZXIpLndhcm5pbmcoZXhjZXB0aW9uKTsKLSAgfQotICAgIAotICAgIAotICAgLyoqCi0gICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIGVycm9yLgotICAgICoKLSAgICAqIDxwPlRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGRlZmluaXRpb24gb2YgImVycm9yIiBpbiBzZWN0aW9uIDEuMgotICAgICogb2YgdGhlIFczQyBYTUwgMS4wIFJlY29tbWVuZGF0aW9uLiAgRm9yIGV4YW1wbGUsIGEgdmFsaWRhdGluZwotICAgICogcGFyc2VyIHdvdWxkIHVzZSB0aGlzIGNhbGxiYWNrIHRvIHJlcG9ydCB0aGUgdmlvbGF0aW9uIG9mIGEKLSAgICAqIHZhbGlkaXR5IGNvbnN0cmFpbnQuICBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gdGFrZSBubwotICAgICogYWN0aW9uLjwvcD4KLSAgICAqCi0gICAgKiA8cD5UaGUgU0FYIHBhcnNlciBtdXN0IGNvbnRpbnVlIHRvIHByb3ZpZGUgbm9ybWFsIHBhcnNpbmcgZXZlbnRzCi0gICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4gIElmIHRoZQotICAgICogYXBwbGljYXRpb24gY2Fubm90IGRvIHNvLCB0aGVuIHRoZSBwYXJzZXIgc2hvdWxkIHJlcG9ydCBhIGZhdGFsCi0gICAgKiBlcnJvciBldmVuIGlmIHRoZSBYTUwgMS4wIHJlY29tbWVuZGF0aW9uIGRvZXMgbm90IHJlcXVpcmUgaXQgdG8KLSAgICAqIGRvIHNvLjwvcD4KLSAgICAqCi0gICAgKiA8cD5GaWx0ZXJzIG1heSB1c2UgdGhpcyBtZXRob2QgdG8gcmVwb3J0IG90aGVyLCBub24tWE1MIGVycm9ycwotICAgICogYXMgd2VsbC48L3A+Ci0gICAgKgotICAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KLSAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24gCi0gICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IgKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikKLSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcikKLSAgICAgICgoRXJyb3JIYW5kbGVyKW1fY29udGVudEhhbmRsZXIpLmVycm9yKGV4Y2VwdGlvbik7Ci0gIH0KLSAgICAKLSAgICAKLSAgIC8qKgotICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub24tcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAgKgotICAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZmF0YWwgZXJyb3IiIGluCi0gICAgKiBzZWN0aW9uIDEuMiBvZiB0aGUgVzNDIFhNTCAxLjAgUmVjb21tZW5kYXRpb24uICBGb3IgZXhhbXBsZSwgYQotICAgICogcGFyc2VyIHdvdWxkIHVzZSB0aGlzIGNhbGxiYWNrIHRvIHJlcG9ydCB0aGUgdmlvbGF0aW9uIG9mIGEKLSAgICAqIHdlbGwtZm9ybWVkbmVzcyBjb25zdHJhaW50LjwvcD4KLSAgICAqCi0gICAgKiA8cD5UaGUgYXBwbGljYXRpb24gbXVzdCBhc3N1bWUgdGhhdCB0aGUgZG9jdW1lbnQgaXMgdW51c2FibGUKLSAgICAqIGFmdGVyIHRoZSBwYXJzZXIgaGFzIGludm9rZWQgdGhpcyBtZXRob2QsIGFuZCBzaG91bGQgY29udGludWUKLSAgICAqIChpZiBhdCBhbGwpIG9ubHkgZm9yIHRoZSBzYWtlIG9mIGNvbGxlY3RpbmcgYWRkaXRpb24gZXJyb3IKLSAgICAqIG1lc3NhZ2VzOiBpbiBmYWN0LCBTQVggcGFyc2VycyBhcmUgZnJlZSB0byBzdG9wIHJlcG9ydGluZyBhbnkKLSAgICAqIG90aGVyIGV2ZW50cyBvbmNlIHRoaXMgbWV0aG9kIGhhcyBiZWVuIGludm9rZWQuPC9wPgotICAgICoKLSAgICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIGVycm9yIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uICAKLSAgICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgICAqLwotICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yIChTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pCi0gICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7ICAgICAgCi0gICAgbV9lbGVtSXNQZW5kaW5nID0gZmFsc2U7Ci0gICAgbV9kb2NFbmRlZCA9IHRydWU7Ci0gICAgbV9kb2NQZW5kaW5nID0gZmFsc2U7Ci0gICAgCi0gICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBFcnJvckhhbmRsZXIpCi0gICAgICAoKEVycm9ySGFuZGxlciltX2NvbnRlbnRIYW5kbGVyKS5mYXRhbEVycm9yKGV4Y2VwdGlvbik7Ci0gIH0KLSAgCi0gIGJvb2xlYW4gbV9pc1RyYW5zZm9ybUNsaWVudCA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBVc2UgdGhlIFNBWDIgaGVscGVyIGNsYXNzIHRvIHRyYWNrIHJlc3VsdCBuYW1lc3BhY2VzLgotICAgKi8KLSAgTmFtZXNwYWNlU3VwcG9ydCBtX25zU3VwcG9ydCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0MigpOwotCi0gIC8qKgotICAgKiBUaGUgdHJhbnNmb3JtZXIgb2JqZWN0LgotICAgKi8KLSAgcHJpdmF0ZSBUcmFuc2Zvcm1lckltcGwgbV90cmFuc2Zvcm1lcjsKLQotICAvKioKLSAgICogVGhlIGNvbnRlbnQgaGFuZGxlci4gIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgKiBjYXNlLCB3ZSdsbCBkZWZlciB0byB0aGUgY29udGVudCBoYW5kbGVyIGluIHRoZQotICAgKiB0cmFuc2Zvcm1lci4KLSAgICovCi0gIHByaXZhdGUgQ29udGVudEhhbmRsZXIgbV9jb250ZW50SGFuZGxlcjsKLQotICAvKiogVGhlIExleGljYWxIYW5kbGVyICovCi0gIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgbV9sZXhpY2FsSGFuZGxlcjsKLQotICAvKioKLSAgICogVGhlIHJvb3Qgb2YgYSBsaW5rZWQgc2V0IG9mIHN0eWxlc2hlZXRzLgotICAgKi8KLSAgcHJpdmF0ZSBTdHlsZXNoZWV0Um9vdCBtX3N0eWxlc2hlZXRSb290ID0gbnVsbDsKLQotICAvKioKLSAgICogVGhpcyBpcyB1c2VkIHdoZW5ldmVyIGEgdW5pcXVlIG5hbWVzcGFjZSBpcyBuZWVkZWQuCi0gICAqLwotICBwcml2YXRlIGludCBtX3VuaXF1ZU5TVmFsdWUgPSAwOwotCi0gIC8qKiBQcmVmaXggdXNlZCB0byBjcmVhdGUgdW5pcXVlIHByZWZpeCBuYW1lcyAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19OQU1FU1BBQ0VQUkVGSVggPSAibnMiOwotCi0gIC8qKgotICAgKiBUaGlzIGNsYXNzIGNsb25lcyBub2RlcyB0byB0aGUgcmVzdWx0IHRyZWUuCi0gICAqLwotICBwdWJsaWMgQ2xvbmVyVG9SZXN1bHRUcmVlIG1fY2xvbmVyOwotCi0gIC8qKgotICAgKiBUcmFjZSBtYW5hZ2VyIGZvciBkZWJ1ZyBzdXBwb3J0LgotICAgKi8KLSAgcHJpdmF0ZSBUcmFjZU1hbmFnZXIgbV90cmFjZXI7Ci0gIAotICBwcml2YXRlIFF1ZXVlZFN0YXRlU25hcHNob3QgbV9zbmFwc2hvdCA9IG5ldyBRdWV1ZWRTdGF0ZVNuYXBzaG90KCk7Ci0KLSAgLy8gVGhlc2UgYXJlIHBhc3NlZCB0byBmbHVzaFBlbmRpbmcsIHRvIGhlbHAgaXQgZGVjaWRlIGlmIGl0IAotICAvLyBzaG91bGQgcmVhbGx5IGZsdXNoLgotICAKLSAgY2xhc3MgUXVldWVkU3RhdGVTbmFwc2hvdAotICB7Ci0gICAgLyoqCi0gICAgICogVGhlIHN0eWxlc2hlZXQgZWxlbWVudCB0aGF0IHByb2R1Y2VkIHRoZSBTQVggZXZlbnQuCi0gICAgICovCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBtX2N1cnJlbnRFbGVtZW50OwotICAgIAotICAgIC8qKgotICAgICAqIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCi0gICAgICovCi0gICAgb3JnLnczYy5kb20uTm9kZSBtX2N1cnJlbnROb2RlOwotICAgIAotICAgIC8qKgotICAgICAqIFRoZSB4c2w6dGVtcGxhdGUgdGhhdCBpcyBpbiBlZmZlY3QsIHdoaWNoIG1heSBiZSBhIG1hdGNoZWQgdGVtcGxhdGUKLSAgICAgKiBvciBhIG5hbWVkIHRlbXBsYXRlLgotICAgICAqLwotICAgIEVsZW1UZW1wbGF0ZSBtX2N1cnJlbnRUZW1wbGF0ZTsKLSAgICAKLSAgICAvKioKLSAgICAgKiBUaGUgeHNsOnRlbXBsYXRlIHRoYXQgd2FzIG1hdGNoZWQuCi0gICAgICovCi0gICAgRWxlbVRlbXBsYXRlIG1fbWF0Y2hlZFRlbXBsYXRlOwotICAgIAotICAgIC8qKgotICAgICAqIFRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZSB0aGF0IG1hdGNoZWQKLSAgICAgKiB0aGUgdGVtcGxhdGUgb2J0YWluZWQgdmlhIGdldE1hdGNoZWRUZW1wbGF0ZSgpLgotICAgICAqLwotICAgIGludCBtX21hdGNoZWROb2RlOwotICAgIAotICAgIC8qKgotICAgICAqIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgICAqLwotICAgIERUTUl0ZXJhdG9yIG1fY29udGV4dE5vZGVMaXN0OwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9TZXJpYWxpemVyU3dpdGNoZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1NlcmlhbGl6ZXJTd2l0Y2hlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyODQzMGU1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1NlcmlhbGl6ZXJTd2l0Y2hlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBqYXZhLmlvLldyaXRlcjsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLQotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5NZXRob2Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuT3V0cHV0UHJvcGVydGllczsKLQotLyoqCi0gKiBUaGlzIGlzIGEgaGVscGVyIGNsYXNzIHRoYXQgZGVjaWRlcyBpZiBYYWxhbiBuZWVkcyB0byBzd2l0Y2gKLSAqIHNlcmlhbGl6ZXJzLCBiYXNlZCBvbiB0aGUgZmlyc3Qgb3V0cHV0IGVsZW1lbnQuCi0gKi8KLXB1YmxpYyBjbGFzcyBTZXJpYWxpemVyU3dpdGNoZXIKLXsKLQotICAvKioKLSAgICogU3dpdGNoIHRvIEhUTUwgc2VyaWFsaXplciBpZiBlbGVtZW50IGlzIEhUTUwKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIE5vbi1udWxsIHRyYW5zZm9ybWVyIGluc3RhbmNlCi0gICAqIEBwYXJhbSBucyBOYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgTG9jYWwgcGFydCBvZiBuYW1lIG9mIGVsZW1lbnQKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIHN3aXRjaFNlcmlhbGl6ZXJJZkhUTUwoCi0gICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLCBTdHJpbmcgbnMsIFN0cmluZyBsb2NhbE5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gdHJhbnNmb3JtZXIpCi0gICAgICByZXR1cm47Ci0KLSAgICBpZiAoKChudWxsID09IG5zKSB8fCAobnMubGVuZ3RoKCkgPT0gMCkpCi0gICAgICAgICAgICAmJiBsb2NhbE5hbWUuZXF1YWxzSWdub3JlQ2FzZSgiaHRtbCIpKQotICAgIHsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigidHJhbnNmb3JtZXIuZ2V0T3V0cHV0UHJvcGVydHlOb0RlZmF1bHQoT3V0cHV0S2V5cy5NRVRIT0QpOiAiKwotICAgICAgLy8gICAgICAgICAgICAgIHRyYW5zZm9ybWVyLmdldE91dHB1dFByb3BlcnR5Tm9EZWZhdWx0KE91dHB1dEtleXMuTUVUSE9EKSk7ICAgICAKLSAgICAgIC8vIEFjY2VzcyBhdCBsZXZlbCBvZiBoYXNodGFibGUgdG8gc2VlIGlmIHRoZSBtZXRob2QgaGFzIGJlZW4gc2V0LgotICAgICAgaWYgKG51bGwgIT0gdHJhbnNmb3JtZXIuZ2V0T3V0cHV0UHJvcGVydHlOb0RlZmF1bHQoT3V0cHV0S2V5cy5NRVRIT0QpKQotICAgICAgICByZXR1cm47Ci0KLSAgICAgIC8vIEdldHRpbmcgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIHRoaXMgd2F5IHdvbid0IGNhdXNlIGEgY2xvbmUgb2YgCi0gICAgICAvLyB0aGUgcHJvcGVydGllcy4KLSAgICAgIFByb3BlcnRpZXMgcHJldlByb3BlcnRpZXMgPSB0cmFuc2Zvcm1lci5nZXRPdXRwdXRGb3JtYXQoKS5nZXRQcm9wZXJ0aWVzKCk7Ci0gICAgICAKLSAgICAgIC8vIFdlIGhhdmUgdG8gbWFrZSBzdXJlIHdlIGdldCBhbiBvdXRwdXQgcHJvcGVydGllcyB3aXRoIHRoZSBwcm9wZXIgCi0gICAgICAvLyBkZWZhdWx0cyBmb3IgdGhlIEhUTUwgbWV0aG9kLiAgVGhlIGVhc2llc3Qgd2F5IHRvIGRvIHRoaXMgaXMgdG8gCi0gICAgICAvLyBoYXZlIHRoZSBPdXRwdXRQcm9wZXJ0aWVzIGNsYXNzIGRvIGl0LgotICAgICAgT3V0cHV0UHJvcGVydGllcyBodG1sT3V0cHV0UHJvcGVydGllcyA9IG5ldyBPdXRwdXRQcm9wZXJ0aWVzKE1ldGhvZC5IVE1MKTsKLQotICAgICAgaHRtbE91dHB1dFByb3BlcnRpZXMuY29weUZyb20ocHJldlByb3BlcnRpZXMsIHRydWUpOwotICAgICAgUHJvcGVydGllcyBodG1sUHJvcGVydGllcyA9IGh0bWxPdXRwdXRQcm9wZXJ0aWVzLmdldFByb3BlcnRpZXMoKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIFNlcmlhbGl6ZXIgb2xkU2VyaWFsaXplciA9IHRyYW5zZm9ybWVyLmdldFNlcmlhbGl6ZXIoKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBvbGRTZXJpYWxpemVyKQotICAgICAgICB7Ci0gICAgICAgICAgU2VyaWFsaXplciBzZXJpYWxpemVyID0KLSAgICAgICAgICAgIFNlcmlhbGl6ZXJGYWN0b3J5LmdldFNlcmlhbGl6ZXIoaHRtbFByb3BlcnRpZXMpOwotCi0gICAgICAgICAgV3JpdGVyIHdyaXRlciA9IG9sZFNlcmlhbGl6ZXIuZ2V0V3JpdGVyKCk7Ci0KLSAgICAgICAgICBpZiAobnVsbCAhPSB3cml0ZXIpCi0gICAgICAgICAgICBzZXJpYWxpemVyLnNldFdyaXRlcih3cml0ZXIpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBPdXRwdXRTdHJlYW0gb3MgPSBvbGRTZXJpYWxpemVyLmdldE91dHB1dFN0cmVhbSgpOwotCi0gICAgICAgICAgICBpZiAobnVsbCAhPSBvcykKLSAgICAgICAgICAgICAgc2VyaWFsaXplci5zZXRPdXRwdXRTdHJlYW0ob3MpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIHRyYW5zZm9ybWVyLnNldFNlcmlhbGl6ZXIoc2VyaWFsaXplcik7Ci0KLSAgICAgICAgICBDb250ZW50SGFuZGxlciBjaCA9IHNlcmlhbGl6ZXIuYXNDb250ZW50SGFuZGxlcigpOwotCi0gICAgICAgICAgdHJhbnNmb3JtZXIuc2V0Q29udGVudEhhbmRsZXIoY2gpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5LCB3aXRob3V0IHVzaW5nIHRoZSBkZWZhdWx0IHByb3BlcnRpZXMuICBUaGlzIAotICAgKiBjYW4gYmUgdXNlZCB0byB0ZXN0IGlmIGEgcHJvcGVydHkgaGFzIGJlZW4gZXhwbGljaXRseSBzZXQgYnkgdGhlIHN0eWxlc2hlZXQgCi0gICAqIG9yIHVzZXIuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSwgb3IgbnVsbCBpZiBub3QgZm91bmQuCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkLCAKLSAgICogYW5kIGlzIG5vdCBuYW1lc3BhY2VkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldE91dHB1dFByb3BlcnR5Tm9EZWZhdWx0KFN0cmluZyBxbmFtZVN0cmluZywgUHJvcGVydGllcyBwcm9wcykKLSAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gIHsgICAgCi0gICAgU3RyaW5nIHZhbHVlID0gKFN0cmluZylwcm9wcy5nZXQocW5hbWVTdHJpbmcpOwotICAgIAotICAgIHJldHVybiB2YWx1ZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFN3aXRjaCB0byBIVE1MIHNlcmlhbGl6ZXIgaWYgZWxlbWVudCBpcyBIVE1MCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBucyBOYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgTG9jYWwgcGFydCBvZiBuYW1lIG9mIGVsZW1lbnQKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKiBAcmV0dXJuIG5ldyBjb250ZW50SGFuZGxlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU2VyaWFsaXplciBzd2l0Y2hTZXJpYWxpemVySWZIVE1MKAotICAgICAgICAgIFN0cmluZyBucywgU3RyaW5nIGxvY2FsTmFtZSwgUHJvcGVydGllcyBwcm9wcywgU2VyaWFsaXplciBvbGRTZXJpYWxpemVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBTZXJpYWxpemVyIG5ld1NlcmlhbGl6ZXIgPSBvbGRTZXJpYWxpemVyOwotCi0gICAgaWYgKCgobnVsbCA9PSBucykgfHwgKG5zLmxlbmd0aCgpID09IDApKQotICAgICAgICAgICAgJiYgbG9jYWxOYW1lLmVxdWFsc0lnbm9yZUNhc2UoImh0bWwiKSkKLSAgICB7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInRyYW5zZm9ybWVyLmdldE91dHB1dFByb3BlcnR5Tm9EZWZhdWx0KE91dHB1dEtleXMuTUVUSE9EKTogIisKLSAgICAgIC8vICAgICAgICAgICAgICB0cmFuc2Zvcm1lci5nZXRPdXRwdXRQcm9wZXJ0eU5vRGVmYXVsdChPdXRwdXRLZXlzLk1FVEhPRCkpOyAgICAgCi0gICAgICAvLyBBY2Nlc3MgYXQgbGV2ZWwgb2YgaGFzaHRhYmxlIHRvIHNlZSBpZiB0aGUgbWV0aG9kIGhhcyBiZWVuIHNldC4KLSAgICAgIGlmIChudWxsICE9IGdldE91dHB1dFByb3BlcnR5Tm9EZWZhdWx0KE91dHB1dEtleXMuTUVUSE9ELCBwcm9wcykpCi0gICAgICAgIHJldHVybiBuZXdTZXJpYWxpemVyOwotCi0gICAgICAvLyBHZXR0aW5nIHRoZSBvdXRwdXQgcHJvcGVydGllcyB0aGlzIHdheSB3b24ndCBjYXVzZSBhIGNsb25lIG9mIAotICAgICAgLy8gdGhlIHByb3BlcnRpZXMuCi0gICAgICBQcm9wZXJ0aWVzIHByZXZQcm9wZXJ0aWVzID0gcHJvcHM7Ci0gICAgICAKLSAgICAgIC8vIFdlIGhhdmUgdG8gbWFrZSBzdXJlIHdlIGdldCBhbiBvdXRwdXQgcHJvcGVydGllcyB3aXRoIHRoZSBwcm9wZXIgCi0gICAgICAvLyBkZWZhdWx0cyBmb3IgdGhlIEhUTUwgbWV0aG9kLiAgVGhlIGVhc2llc3Qgd2F5IHRvIGRvIHRoaXMgaXMgdG8gCi0gICAgICAvLyBoYXZlIHRoZSBPdXRwdXRQcm9wZXJ0aWVzIGNsYXNzIGRvIGl0LgotICAgICAgT3V0cHV0UHJvcGVydGllcyBodG1sT3V0cHV0UHJvcGVydGllcyA9IG5ldyBPdXRwdXRQcm9wZXJ0aWVzKE1ldGhvZC5IVE1MKTsKLQotICAgICAgaHRtbE91dHB1dFByb3BlcnRpZXMuY29weUZyb20ocHJldlByb3BlcnRpZXMsIHRydWUpOwotICAgICAgUHJvcGVydGllcyBodG1sUHJvcGVydGllcyA9IGh0bWxPdXRwdXRQcm9wZXJ0aWVzLmdldFByb3BlcnRpZXMoKTsKLQotLy8gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgIT0gb2xkU2VyaWFsaXplcikKLSAgICAgICAgewotICAgICAgICAgIFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9Ci0gICAgICAgICAgICBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyKGh0bWxQcm9wZXJ0aWVzKTsKLQotICAgICAgICAgIFdyaXRlciB3cml0ZXIgPSBvbGRTZXJpYWxpemVyLmdldFdyaXRlcigpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gd3JpdGVyKQotICAgICAgICAgICAgc2VyaWFsaXplci5zZXRXcml0ZXIod3JpdGVyKTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG9zID0gc2VyaWFsaXplci5nZXRPdXRwdXRTdHJlYW0oKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gb3MpCi0gICAgICAgICAgICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0U3RyZWFtKG9zKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgbmV3U2VyaWFsaXplciA9IHNlcmlhbGl6ZXI7Ci0gICAgICAgIH0KLSAgICAgIH0KLS8vICAgICAgY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkKLS8vICAgICAgewotLy8gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLS8vICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gbmV3U2VyaWFsaXplcjsKLSAgfQotICAKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1N0YWNrR3VhcmQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1N0YWNrR3VhcmQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWUyNzk5Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9TdGFja0d1YXJkLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNzIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwotaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci0KLS8qKgotICogQ2xhc3MgdG8gZ3VhcmQgYWdhaW5zdCByZWN1cnNpb24gZ2V0dGluZyB0b28gZGVlcC4KLSAqLwotcHVibGljIGNsYXNzIFN0YWNrR3VhcmQKLXsKLQotICAvKioKLSAgICogVXNlZCBmb3IgaW5maW5pdGUgbG9vcCBjaGVjay4gSWYgdGhlIHZhbHVlIGlzIC0xLCBkbyBub3QKLSAgICogY2hlY2sgZm9yIGluZmluaXRlIGxvb3BzLiBBbnlvbmUgd2hvIHdhbnRzIHRvIGVuYWJsZSB0aGF0Ci0gICAqIGNoZWNrIHNob3VsZCBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoaXMgdmFyaWFibGUgdG8gYmUgdGhlCi0gICAqIGxldmVsIG9mIHJlY3Vyc2lvbiB0aGF0IHRoZXkgd2FudCB0byBjaGVjay4gQmUgY2FyZWZ1bCBzZXR0aW5nCi0gICAqIHRoaXMgdmFyaWFibGUsIGlmIHRoZSBudW1iZXIgaXMgdG9vIGxvdywgaXQgbWF5IHJlcG9ydCBhbgotICAgKiBpbmZpbml0ZSBsb29wIHNpdHVhdGlvbiwgd2hlbiB0aGVyZSBpcyBub25lLgotICAgKiBQb3N0IHZlcnNpb24gMS4wLjAsIHdlJ2xsIG1ha2UgdGhpcyBhIHJ1bnRpbWUgZmVhdHVyZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IG1fcmVjdXJzaW9uTGltaXQgPSAtMTsKLQotICAvKioKLSAgICogR2V0IHRoZSByZWN1cnNpb24gbGltaXQuCi0gICAqIFVzZWQgZm9yIGluZmluaXRlIGxvb3AgY2hlY2suIElmIHRoZSB2YWx1ZSBpcyAtMSwgZG8gbm90Ci0gICAqIGNoZWNrIGZvciBpbmZpbml0ZSBsb29wcy4gQW55b25lIHdobyB3YW50cyB0byBlbmFibGUgdGhhdAotICAgKiBjaGVjayBzaG91bGQgY2hhbmdlIHRoZSB2YWx1ZSBvZiB0aGlzIHZhcmlhYmxlIHRvIGJlIHRoZQotICAgKiBsZXZlbCBvZiByZWN1cnNpb24gdGhhdCB0aGV5IHdhbnQgdG8gY2hlY2suIEJlIGNhcmVmdWwgc2V0dGluZwotICAgKiB0aGlzIHZhcmlhYmxlLCBpZiB0aGUgbnVtYmVyIGlzIHRvbyBsb3csIGl0IG1heSByZXBvcnQgYW4KLSAgICogaW5maW5pdGUgbG9vcCBzaXR1YXRpb24sIHdoZW4gdGhlcmUgaXMgbm9uZS4KLSAgICogUG9zdCB2ZXJzaW9uIDEuMC4wLCB3ZSdsbCBtYWtlIHRoaXMgYSBydW50aW1lIGZlYXR1cmUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlY3Vyc2lvbiBsaW1pdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UmVjdXJzaW9uTGltaXQoKQotICB7Ci0gICAgcmV0dXJuIG1fcmVjdXJzaW9uTGltaXQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSByZWN1cnNpb24gbGltaXQuCi0gICAqIFVzZWQgZm9yIGluZmluaXRlIGxvb3AgY2hlY2suIElmIHRoZSB2YWx1ZSBpcyAtMSwgZG8gbm90Ci0gICAqIGNoZWNrIGZvciBpbmZpbml0ZSBsb29wcy4gQW55b25lIHdobyB3YW50cyB0byBlbmFibGUgdGhhdAotICAgKiBjaGVjayBzaG91bGQgY2hhbmdlIHRoZSB2YWx1ZSBvZiB0aGlzIHZhcmlhYmxlIHRvIGJlIHRoZQotICAgKiBsZXZlbCBvZiByZWN1cnNpb24gdGhhdCB0aGV5IHdhbnQgdG8gY2hlY2suIEJlIGNhcmVmdWwgc2V0dGluZwotICAgKiB0aGlzIHZhcmlhYmxlLCBpZiB0aGUgbnVtYmVyIGlzIHRvbyBsb3csIGl0IG1heSByZXBvcnQgYW4KLSAgICogaW5maW5pdGUgbG9vcCBzaXR1YXRpb24sIHdoZW4gdGhlcmUgaXMgbm9uZS4KLSAgICogUG9zdCB2ZXJzaW9uIDEuMC4wLCB3ZSdsbCBtYWtlIHRoaXMgYSBydW50aW1lIGZlYXR1cmUuCi0gICAqCi0gICAqIEBwYXJhbSBsaW1pdCBUaGUgcmVjdXJzaW9uIGxpbWl0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVjdXJzaW9uTGltaXQoaW50IGxpbWl0KQotICB7Ci0gICAgbV9yZWN1cnNpb25MaW1pdCA9IGxpbWl0OwotICB9Ci0KLSAgLyoqIFN0eWxlc2hlZXQgVGVtcGxhdGUgbm9kZSAgICAgICAgICAqLwotICBFbGVtVGVtcGxhdGVFbGVtZW50IG1feHNsUnVsZTsKLQotICAvKiogU291cmNlIG5vZGUgICAgICAgICAgKi8KLSAgaW50IG1fc291cmNlWE1MOwotCi0gIC8qKiBTdGFjayB3aGVyZSBFbGVtVGVtcGFsdGVFbGVtZW50cyB3aWxsIGJlIHB1c2hlZCAgICAgICAgICAqLwotICBqYXZhLnV0aWwuU3RhY2sgc3RhY2sgPSBuZXcgamF2YS51dGlsLlN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFN0YWNrR3VhcmQKLSAgICoKLSAgICovCi0gIHB1YmxpYyBTdGFja0d1YXJkKCl7fQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBTdGFja0d1YXJkCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4c2xUZW1wbGF0ZSBDdXJyZW50IHRlbXBsYXRlIG5vZGUKLSAgICogQHBhcmFtIHNvdXJjZVhNTCBTb3VyY2UgTm9kZQotICAgKi8KLSAgcHVibGljIFN0YWNrR3VhcmQoRWxlbVRlbXBsYXRlRWxlbWVudCB4c2xUZW1wbGF0ZSwgaW50IHNvdXJjZVhNTCkKLSAgewotICAgIG1feHNsUnVsZSA9IHhzbFRlbXBsYXRlOwotICAgIG1fc291cmNlWE1MID0gc291cmNlWE1MOwotICB9Ci0KLSAgLyoqCi0gICAqIE92ZXJpZGUgZXF1YWwgbWV0aG9kIGZvciBTdGFja0d1YXJkIG9iamVjdHMgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBvYmogU3RhY2tHdWFyZCBvYmplY3QgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIG9iamVjdCBtYXRjaGVzIHRoaXMgU3RhY2tHdWFyZCBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKQotICB7Ci0KLSAgICBpZiAoKChTdGFja0d1YXJkKSBvYmopLm1feHNsUnVsZS5lcXVhbHMobV94c2xSdWxlKQotICAgICAgICAgICAgJiYgKChTdGFja0d1YXJkKSBvYmopLm1fc291cmNlWE1MID09IG1fc291cmNlWE1MKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBPdXRwdXQgZGlhZ25vc3RpY3MgaWYgaW4gYW4gaW5maW5pdGUgbG9vcAotICAgKgotICAgKgotICAgKiBAcGFyYW0gcHcgTm9uLW51bGwgUHJpbnRXcml0ZXIgaW5zdGFuY2UgdG8gdXNlCi0gICAqLwotICBwdWJsaWMgdm9pZCBwcmludChQcmludFdyaXRlciBwdykKLSAgewotCi0gICAgLy8gZm9yIHRoZSBtb21lbnQsIHRoZXNlIGRpYWdub3N0aWNzIGFyZSByZWFsbHkgYmFkLi4uCi0gICAgLy8gJURUQkQlIFdlIG5lZWQgYW4gZXhlY3V0aW9uIGNvbnRleHQuCi0vLyAgICBpZiAobV9zb3VyY2VYTUwgaW5zdGFuY2VvZiBUZXh0KQotLy8gICAgewotLy8gICAgICBUZXh0IHR4ID0gKFRleHQpIG1fc291cmNlWE1MOwotLy8KLS8vICAgICAgcHcucHJpbnRsbih0eC5nZXREYXRhKCkpOwotLy8gICAgfQotLy8gICAgZWxzZSBpZiAobV9zb3VyY2VYTUwgaW5zdGFuY2VvZiBFbGVtZW50KQotLy8gICAgewotLy8gICAgICBFbGVtZW50IGVsZW0gPSAoRWxlbWVudCkgbV9zb3VyY2VYTUw7Ci0vLwotLy8gICAgICBwdy5wcmludGxuKGVsZW0uZ2V0Tm9kZU5hbWUoKSk7Ci0vLyAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgaWYgd2UgYXJlIGluIGFuIGluZmluaXRlIGxvb3AKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGd1YXJkIEN1cnJlbnQgU3RhY2tHdWFyZCBvYmplY3QgKG1hdGNoaW5nIGN1cnJlbnQgdGVtcGxhdGUpICAKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tGb3JJbmZpbmF0ZUxvb3AoU3RhY2tHdWFyZCBndWFyZCkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBuUnVsZXMgPSBzdGFjay5zaXplKCk7Ci0gICAgaW50IGxvb3BDb3VudCA9IDA7Ci0KLSAgICBmb3IgKGludCBpID0gKG5SdWxlcyAtIDEpOyBpID49IDA7IGktLSkKLSAgICB7Ci0gICAgICBpZiAoc3RhY2suZWxlbWVudEF0KGkpLmVxdWFscyhndWFyZCkpCi0gICAgICB7Ci0gICAgICAgIGxvb3BDb3VudCsrOwotICAgICAgfQotCi0gICAgICBpZiAobG9vcENvdW50ID49IG1fcmVjdXJzaW9uTGltaXQpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gUHJpbnQgb3V0IHJlYWxseSBiYWQgZGlhZ25vc3RpY3MuCi0gICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKLSAgICAgICAgUHJpbnRXcml0ZXIgcHcgPSBuZXcgUHJpbnRXcml0ZXIoc3cpOwotCi0gICAgICAgIHB3LnByaW50bG4oIkluZmluaXRlIGxvb3AgZGlhZ25vc2VkISAgU3RhY2sgdHJhY2U6Iik7Ci0KLSAgICAgICAgaW50IGs7Ci0KLSAgICAgICAgZm9yIChrID0gMDsgayA8IG5SdWxlczsgaysrKQotICAgICAgICB7Ci0gICAgICAgICAgcHcucHJpbnRsbigiU291cmNlIEVsZW0gIyIgKyBrICsgIiAiKTsKLQotICAgICAgICAgIFN0YWNrR3VhcmQgZ3VhcmRPblN0YWNrID0gKFN0YWNrR3VhcmQpIHN0YWNrLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgIGd1YXJkT25TdGFjay5wcmludChwdyk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdy5wcmludGxuKCJTb3VyY2UgRWxlbSAjIiArIGsgKyAiICIpOwotICAgICAgICBndWFyZC5wcmludChwdyk7Ci0gICAgICAgIHB3LnByaW50bG4oIkVuZCBvZiBpbmZpbml0ZSBsb29wIGRpYWdub3Npcy4iKTsKLQotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc3cuZ2V0QnVmZmVyKCkudG9TdHJpbmcoKSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2ggaW4gYSBTdGFja0d1YXJkIG9iamVjdCBtYXRoaW5nIGdpdmVuIHRlbXBsYXRlIAotICAgKgotICAgKgotICAgKiBAcGFyYW0geHNsVGVtcGxhdGUgQ3VycmVudCB0ZW1wbGF0ZSBiZWluZyBwcm9jZXNzZWQKLSAgICogQHBhcmFtIHNvdXJjZVhNTCBDdXJyZW50IFNvdXJjZSBOb2RlIAotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBwdXNoKEVsZW1UZW1wbGF0ZUVsZW1lbnQgeHNsVGVtcGxhdGUsIGludCBzb3VyY2VYTUwpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0YWNrR3VhcmQgZ3VhcmQgPSBuZXcgU3RhY2tHdWFyZCh4c2xUZW1wbGF0ZSwgc291cmNlWE1MKTsKLQotICAgIGNoZWNrRm9ySW5maW5hdGVMb29wKGd1YXJkKTsKLSAgICBzdGFjay5wdXNoKGd1YXJkKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3Agb3V0IFN0YWNrIG9mIFN0YWNrR3VhcmQgb2JqZWN0cyAKLSAgICoKLSAgICovCi0gIHB1YmxpYyB2b2lkIHBvcCgpCi0gIHsKLSAgICBzdGFjay5wb3AoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJBWEZpbHRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJBWEZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZmRjZmQ3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyQVhGaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxOCArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MRmlsdGVySW1wbDsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotcHVibGljIGNsYXNzIFRyQVhGaWx0ZXIgZXh0ZW5kcyBYTUxGaWx0ZXJJbXBsCi17Ci0gIHByaXZhdGUgVGVtcGxhdGVzIG1fdGVtcGxhdGVzOwotICBwcml2YXRlIFRyYW5zZm9ybWVySW1wbCBtX3RyYW5zZm9ybWVyOwotICAgIAotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGVtcHR5IFhNTCBmaWx0ZXIsIHdpdGggbm8gcGFyZW50LgotICAgKgotICAgKiA8cD5UaGlzIGZpbHRlciB3aWxsIGhhdmUgbm8gcGFyZW50OiB5b3UgbXVzdCBhc3NpZ24gYSBwYXJlbnQKLSAgICogYmVmb3JlIHlvdSBzdGFydCBhIHBhcnNlIG9yIGRvIGFueSBjb25maWd1cmF0aW9uIHdpdGgKLSAgICogc2V0RmVhdHVyZSBvciBzZXRQcm9wZXJ0eS48L3A+Ci0gICAqCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3NldEZlYXR1cmUKLSAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0UHJvcGVydHkKLSAgICovCi0gIHB1YmxpYyBUckFYRmlsdGVyIChUZW1wbGF0ZXMgdGVtcGxhdGVzKQotICAgIHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIG1fdGVtcGxhdGVzID0gdGVtcGxhdGVzOwotICAgIG1fdHJhbnNmb3JtZXIgPSAoVHJhbnNmb3JtZXJJbXBsKXRlbXBsYXRlcy5uZXdUcmFuc2Zvcm1lcigpOwotICB9Ci0gIAotICAvKiogU2V0IHRoZSBwYXJlbnQgcmVhZGVyLgotICAgKgotICAgKiA8cD5UaGlzIGlzIHRoZSB7QGxpbmsgb3JnLnhtbC5zYXguWE1MUmVhZGVyIFhNTFJlYWRlcn0gZnJvbSB3aGljaCAKLSAgICogdGhpcyBmaWx0ZXIgd2lsbCBvYnRhaW4gaXRzIGV2ZW50cyBhbmQgdG8gd2hpY2ggaXQgd2lsbCBwYXNzIGl0cyAKLSAgICogY29uZmlndXJhdGlvbiByZXF1ZXN0cy4gIFRoZSBwYXJlbnQgbWF5IGl0c2VsZiBiZSBhbm90aGVyIGZpbHRlci48L3A+Ci0gICAqCi0gICAqIDxwPklmIHRoZXJlIGlzIG5vIHBhcmVudCByZWFkZXIgc2V0LCBhbnkgYXR0ZW1wdCB0byBwYXJzZQotICAgKiBvciB0byBzZXQgb3IgZ2V0IGEgZmVhdHVyZSBvciBwcm9wZXJ0eSB3aWxsIGZhaWwuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcGFyZW50IFRoZSBwYXJlbnQgWE1MIHJlYWRlci4KLSAgICogQHRocm93cyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIHBhcmVudCBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyZW50IChYTUxSZWFkZXIgcGFyZW50KQotICB7IAotICAgIHN1cGVyLnNldFBhcmVudChwYXJlbnQpOwotICAgIAotICAgIGlmKG51bGwgIT0gcGFyZW50LmdldENvbnRlbnRIYW5kbGVyKCkpCi0gICAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKHBhcmVudC5nZXRDb250ZW50SGFuZGxlcigpKTsKLQotICAgIC8vIE5vdCByZWFsbHkgc3VyZSBpZiB3ZSBzaG91bGQgZG8gdGhpcyBoZXJlLCBidXQgCi0gICAgLy8gaXQgc2VlbXMgc2FmZXIgaW4gY2FzZSBzb21lb25lIGNhbGxzIHBhcnNlKCkgb24gCi0gICAgLy8gdGhlIHBhcmVudC4KLSAgICBzZXR1cFBhcnNlICgpOwotICB9Ci0gIAotICAvKioKLSAgICogUGFyc2UgYSBkb2N1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIGlucHV0IFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSBkb2N1bWVudCBlbnRpdHkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gQW4gSU8gZXhjZXB0aW9uIGZyb20gdGhlIHBhcnNlciwKLSAgICogICAgICAgICAgICBwb3NzaWJseSBmcm9tIGEgYnl0ZSBzdHJlYW0gb3IgY2hhcmFjdGVyIHN0cmVhbQotICAgKiAgICAgICAgICAgIHN1cHBsaWVkIGJ5IHRoZSBhcHBsaWNhdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjcGFyc2Uob3JnLnhtbC5zYXguSW5wdXRTb3VyY2UpCi0gICAqLwotICBwdWJsaWMgdm9pZCBwYXJzZSAoSW5wdXRTb3VyY2UgaW5wdXQpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwgPT0gZ2V0UGFyZW50KCkpCi0gICAgewotICAgICAgWE1MUmVhZGVyIHJlYWRlcj1udWxsOwotCi0gICAgICAvLyBVc2UgSkFYUDEuMSAoIGlmIHBvc3NpYmxlICkKLSAgICAgIHRyeSB7Ci0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5PQotICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSggdHJ1ZSApOwotICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyPQotICAgICAgICAgICAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgICAgIHJlYWRlcj1qYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgIAotICAgICAgfSBjYXRjaCggamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCApIHsKLSAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKCBleCApOwotICAgICAgfSBjYXRjaCggamF2YXgueG1sLnBhcnNlcnMuRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciBleDEgKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiggZXgxLnRvU3RyaW5nKCkgKTsKLSAgICAgIH0gY2F0Y2goIE5vU3VjaE1ldGhvZEVycm9yIGV4MiApIHsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChBYnN0cmFjdE1ldGhvZEVycm9yIGFtZSl7fQotCi0gICAgICBYTUxSZWFkZXIgcGFyZW50OwotICAgICAgaWYoIHJlYWRlcj09bnVsbCApCi0gICAgICAgICAgcGFyZW50PSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgZWxzZQotICAgICAgICAgIHBhcmVudD1yZWFkZXI7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgcGFyZW50LnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgICAgLy8gQ29tbWVudGVkIG91dCBhcyBwZXIgZGlzY3Vzc2lvbiB3aXRoIFRob21hczIuTWFlc2luZ0BiZ3MtYWcuZGUgCi0gICAgICAgIC8vIGFib3V0IGJ1ZyAyMTI0LgotLy8gICAgICAgIHBhcmVudC5zZXRGZWF0dXJlKCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvdmFsaWRhdGlvbi9keW5hbWljIiwKLS8vICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2Upe30KLSAgICAgIC8vIHNldFBhcmVudCBjYWxscyBzZXR1cFBhcnNlLi4uCi0gICAgICBzZXRQYXJlbnQocGFyZW50KTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIE1ha2Ugc3VyZSBldmVyeXRoaW5nIGlzIHNldCB1cC4KLSAgICAgIHNldHVwUGFyc2UgKCk7Ci0gICAgfQotICAgIGlmKG51bGwgPT0gbV90cmFuc2Zvcm1lci5nZXRDb250ZW50SGFuZGxlcigpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0NBTExfUEFSU0UsIG51bGwpKTsgLy8icGFyc2UgY2FuIG5vdCBiZSBjYWxsZWQgaWYgdGhlIENvbnRlbnRIYW5kbGVyIGhhcyBub3QgYmVlbiBzZXQhIik7Ci0gICAgfQotCi0gICAgZ2V0UGFyZW50KCkucGFyc2UoaW5wdXQpOwotICAgIEV4Y2VwdGlvbiBlID0gbV90cmFuc2Zvcm1lci5nZXRFeGNlcHRpb25UaHJvd24oKTsKLSAgICBpZihudWxsICE9IGUpCi0gICAgewotICAgICAgaWYoZSBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbikKLSAgICAgICAgdGhyb3cgKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbillOwotICAgICAgZWxzZQotICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKGUpOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFBhcnNlIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgYXMgYSBmdWxseS1xdWFsaWZpZWQgVVJJLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIEFuIElPIGV4Y2VwdGlvbiBmcm9tIHRoZSBwYXJzZXIsCi0gICAqICAgICAgICAgICAgcG9zc2libHkgZnJvbSBhIGJ5dGUgc3RyZWFtIG9yIGNoYXJhY3RlciBzdHJlYW0KLSAgICogICAgICAgICAgICBzdXBwbGllZCBieSB0aGUgYXBwbGljYXRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguWE1MUmVhZGVyI3BhcnNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgdm9pZCBwYXJzZSAoU3RyaW5nIHN5c3RlbUlkKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsKLSAgICBwYXJzZShuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFNldCB1cCBiZWZvcmUgYSBwYXJzZS4KLSAgICoKLSAgICogPHA+QmVmb3JlIGV2ZXJ5IHBhcnNlLCBjaGVjayB3aGV0aGVyIHRoZSBwYXJlbnQgaXMKLSAgICogbm9uLW51bGwsIGFuZCByZS1yZWdpc3RlciB0aGUgZmlsdGVyIGZvciBhbGwgb2YgdGhlIAotICAgKiBldmVudHMuPC9wPgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHNldHVwUGFyc2UgKCkKLSAgewotICAgIFhNTFJlYWRlciBwID0gZ2V0UGFyZW50KCk7Ci0gICAgaWYgKHAgPT0gbnVsbCkgewotICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PX1BBUkVOVF9GT1JfRklMVEVSLCBudWxsKSk7IC8vIk5vIHBhcmVudCBmb3IgZmlsdGVyIik7Ci0gICAgfQotICAgIAotICAgIENvbnRlbnRIYW5kbGVyIGNoID0gbV90cmFuc2Zvcm1lci5nZXRJbnB1dENvbnRlbnRIYW5kbGVyKCk7Ci0vLyAgICBpZihjaCBpbnN0YW5jZW9mIFNvdXJjZVRyZWVIYW5kbGVyKQotLy8gICAgICAoKFNvdXJjZVRyZWVIYW5kbGVyKWNoKS5zZXRVc2VNdWx0aVRocmVhZGluZyh0cnVlKTsKLSAgICBwLnNldENvbnRlbnRIYW5kbGVyKGNoKTsKLQotICAgIGlmKGNoIGluc3RhbmNlb2YgRW50aXR5UmVzb2x2ZXIpCi0gICAgICBwLnNldEVudGl0eVJlc29sdmVyKChFbnRpdHlSZXNvbHZlciljaCk7Ci0gICAgZWxzZQotICAgICAgcC5zZXRFbnRpdHlSZXNvbHZlcih0aGlzKTsKLSAgICAKLSAgICBpZihjaCBpbnN0YW5jZW9mIERUREhhbmRsZXIpCi0gICAgICBwLnNldERUREhhbmRsZXIoKERUREhhbmRsZXIpY2gpOwotICAgIGVsc2UKLSAgICAgIHAuc2V0RFRESGFuZGxlcih0aGlzKTsKLSAgICAKLSAgICBFcnJvckxpc3RlbmVyIGVsaXN0ZW5lciA9IG1fdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgIGlmKChudWxsICE9IGVsaXN0ZW5lcikgJiYgKGVsaXN0ZW5lciBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlcikpCi0gICAgICBwLnNldEVycm9ySGFuZGxlcigob3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyKWVsaXN0ZW5lcik7Ci0gICAgZWxzZQotICAgICAgcC5zZXRFcnJvckhhbmRsZXIodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjb250ZW50IGV2ZW50IGhhbmRsZXIuCi0gICAqCi0gICAqIEBwYXJhbSByZXNvbHZlciBUaGUgbmV3IGNvbnRlbnQgaGFuZGxlci4KLSAgICogQHRocm93cyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgdGhlIGhhbmRsZXIKLSAgICogICAgICAgICAgICBpcyBudWxsLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LlhNTFJlYWRlciNzZXRDb250ZW50SGFuZGxlcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIgKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICBtX3RyYW5zZm9ybWVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICAgIC8vIHN1cGVyLnNldENvbnRlbnRIYW5kbGVyKG1fdHJhbnNmb3JtZXIuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKSk7Ci0gIH0KLSAgCi0gIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIgKEVycm9yTGlzdGVuZXIgaGFuZGxlcikKLSAgewotICAgIG1fdHJhbnNmb3JtZXIuc2V0RXJyb3JMaXN0ZW5lcihoYW5kbGVyKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1TbmFwc2hvdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJhbnNmb3JtU25hcHNob3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2Y1YTFhNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1TbmFwc2hvdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAgKzAsMCBAQAotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi0vKioKLSAqIFRoaXMgaXMgYW4gb3BhcXVlIGludGVyZmFjZSB0aGF0IGFsbG93cyB0aGUgdHJhbnNmb3JtZXIgdG8gcmV0dXJuIGEgCi0gKiAic25hcHNob3QiIG9mIGl0J3MgY3VycmVudCBzdGF0ZSwgd2hpY2ggY2FuIGxhdGVyIGJlIHJlc3RvcmVkLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybVNuYXBzaG90Ci17Ci0KLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1TbmFwc2hvdEltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyYW5zZm9ybVNuYXBzaG90SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMTA5MmUwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyYW5zZm9ybVNuYXBzaG90SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzAwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlZhcmlhYmxlU3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkNvbnRleHROb2RlTGlzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlVmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkJvb2xTdGFjazsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLQotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5OYW1lc3BhY2VTdXBwb3J0MjsKLQotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGhvbGRzIGEgInNuYXBzaG90IiBvZiBpdCdzIGN1cnJlbnQgdHJhbnNmb3JtZXIgc3RhdGUsCi0gKiB3aGljaCBjYW4gbGF0ZXIgYmUgcmVzdG9yZWQuCi0gKgotICogVGhpcyBvbmx5IHNhdmVzIHN0YXRlIHdoaWNoIGNhbiBjaGFuZ2Ugb3ZlciB0aGUgY291cnNlIG9mIHRoZSBzaWRlLWVmZmVjdC1mcmVlCi0gKiAoaS5lLiBubyBleHRlbnNpb25zIHRoYXQgY2FsbCBzZXRVUklSZXNvbHZlciwgZXRjLikuCi0gKi8KLWNsYXNzIFRyYW5zZm9ybVNuYXBzaG90SW1wbCBpbXBsZW1lbnRzIFRyYW5zZm9ybVNuYXBzaG90Ci17Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFjayBvZiBWYXJpYWJsZSBzdGFjayBmcmFtZXMuCi0gICAqLwotICBwcml2YXRlIFZhcmlhYmxlU3RhY2sgbV92YXJpYWJsZVN0YWNrczsKLQotICAvKioKLSAgICogVGhlIHN0YWNrIG9mIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+IG9iamVjdHMuCi0gICAqICBOb3QgdG8gYmUgY29uZnVzZWQgd2l0aCB0aGUgY3VycmVudCBub2RlIGxpc3QuICAKLSAgICovCi0gIHByaXZhdGUgaW50W10gbV9jdXJyZW50Tm9kZXM7Ci0KLSAgLyoqIEEgc3RhY2sgb2YgdGhlIGN1cnJlbnQgc3ViLWV4cHJlc3Npb24gbm9kZXMuICovCi0gIHByaXZhdGUgaW50W10gbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzOwotCi0gIC8qKgotICAgKiBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdHMgc3RhY2suCi0gICAqLwotICBwcml2YXRlIFN0YWNrIG1fY29udGV4dE5vZGVMaXN0czsKLQotICAvKioKLSAgICogVGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqLwotICBwcml2YXRlIERUTUl0ZXJhdG9yIG1fY29udGV4dE5vZGVMaXN0OwotCi0gIC8qKgotICAgKiBTdGFjayBvZiBBeGVzSXRlcmF0b3JzLgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX2F4ZXNJdGVyYXRvclN0YWNrOwotCi0gIC8qKgotICAgKiBJcyA+IDAgd2hlbiB3ZSdyZSBwcm9jZXNzaW5nIGEgZm9yLWVhY2guCi0gICAqLwotICBwcml2YXRlIEJvb2xTdGFjayBtX2N1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGw7Ci0KLSAgLyoqCi0gICAqIEEgbm9kZSB2ZWN0b3IgdXNlZCBhcyBhIHN0YWNrIHRvIHRyYWNrIHRoZSBjdXJyZW50Ci0gICAqIEVsZW1UZW1wbGF0ZUVsZW1lbnQuICBOZWVkZWQgZm9yIHRoZQotICAgKiBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybVN0YXRlIGludGVyZmFjZSwKLSAgICogc28gYSB0b29sIGNhbiBkaXNjb3ZlciB0aGUgY2FsbGluZyB0ZW1wbGF0ZS4gCi0gICAqLwotICBwcml2YXRlIEVsZW1UZW1wbGF0ZUVsZW1lbnRbXSBtX2N1cnJlbnRUZW1wbGF0ZUVsZW1lbnRzOwotCi0gIC8qKgotICAgKiBBIG5vZGUgdmVjdG9yIHVzZWQgYXMgYSBzdGFjayB0byB0cmFjayB0aGUgY3VycmVudAotICAgKiBFbGVtVGVtcGxhdGUgdGhhdCB3YXMgbWF0Y2hlZCwgYXMgd2VsbCBhcyB0aGUgbm9kZSB0aGF0Ci0gICAqIHdhcyBtYXRjaGVkLiAgTmVlZGVkIGZvciB0aGUKLSAgICogb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1TdGF0ZSBpbnRlcmZhY2UsCi0gICAqIHNvIGEgdG9vbCBjYW4gZGlzY292ZXIgdGhlIG1hdGNoZWQgdGVtcGxhdGUsIGFuZCBtYXRjaGVkCi0gICAqIG5vZGUuIAotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX2N1cnJlbnRNYXRjaFRlbXBsYXRlczsKLQotICAvKioKLSAgICogQSBub2RlIHZlY3RvciB1c2VkIGFzIGEgc3RhY2sgdG8gdHJhY2sgdGhlIGN1cnJlbnQKLSAgICogRWxlbVRlbXBsYXRlIHRoYXQgd2FzIG1hdGNoZWQsIGFzIHdlbGwgYXMgdGhlIG5vZGUgdGhhdAotICAgKiB3YXMgbWF0Y2hlZC4gIE5lZWRlZCBmb3IgdGhlCi0gICAqIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtU3RhdGUgaW50ZXJmYWNlLAotICAgKiBzbyBhIHRvb2wgY2FuIGRpc2NvdmVyIHRoZSBtYXRjaGVkIHRlbXBsYXRlLCBhbmQgbWF0Y2hlZAotICAgKiBub2RlLiAKLSAgICovCi0gIHByaXZhdGUgTm9kZVZlY3RvciBtX2N1cnJlbnRNYXRjaE5vZGVzOwotCi0gIC8qKgotICAgKiBUaGUgdGFibGUgb2YgY291bnRlcnMgZm9yIHhzbDpudW1iZXIgc3VwcG9ydC4KLSAgICogQHNlZSBFbGVtTnVtYmVyCi0gICAqLwotICBwcml2YXRlIENvdW50ZXJzVGFibGUgbV9jb3VudGVyc1RhYmxlOwotCi0gIC8qKgotICAgKiBTdGFjayBmb3IgdGhlIHB1cnBvc2VzIG9mIGZsYWdnaW5nIGluZmluaXRlIHJlY3Vyc2lvbiB3aXRoCi0gICAqIGF0dHJpYnV0ZSBzZXRzLgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX2F0dHJTZXRTdGFjazsKLQotICAvKiogSW5kaWNhdGUgd2hldGhlciBhIG5hbWVzcGFjZSBjb250ZXh0IHdhcyBwdXNoZWQgKi8KLSAgYm9vbGVhbiBtX25zQ29udGV4dFB1c2hlZDsKLQotICAvKioKLSAgICogVXNlIHRoZSBTQVgyIGhlbHBlciBjbGFzcyB0byB0cmFjayByZXN1bHQgbmFtZXNwYWNlcy4KLSAgICovCi0gIHByaXZhdGUgTmFtZXNwYWNlU3VwcG9ydCBtX25zU3VwcG9ydDsKLQotICAvKiogVGhlIG51bWJlciBvZiBldmVudHMgcXVldWVkICovCi0gIGludCBtX2V2ZW50Q291bnQ7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFRyYW5zZm9ybVNuYXBzaG90SW1wbAotICAgKiBUYWtlIGEgc25hcHNob3Qgb2YgdGhlIGN1cnJlbnRseSBleGVjdXRpbmcgY29udGV4dC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIE5vbiBudWxsIHRyYW5zZm9ybWVyIGluc3RhbmNlCi0gICAqLwotICBUcmFuc2Zvcm1TbmFwc2hvdEltcGwoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIEFyZSBhbGwgdGhlc2UgY2xvbmVzIGRlZXAgZW5vdWdoPwotICAgICAgUmVzdWx0VHJlZUhhbmRsZXIgcnRmID0gdHJhbnNmb3JtZXIuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKTsKLQotICAgICAgbV9ldmVudENvdW50ID0gcnRmLm1fZXZlbnRDb3VudDsKLQotICAgICAgLy8geXVjay4gIE5vIGNsb25lLiBIb3BlIHRoaXMgaXMgZ29vZCBlbm91Z2guCi0gICAgICBtX25zU3VwcG9ydCA9IG5ldyBOYW1lc3BhY2VTdXBwb3J0MigpOwotCi0gICAgICBFbnVtZXJhdGlvbiBwcmVmaXhlcyA9IHJ0Zi5tX25zU3VwcG9ydC5nZXRQcmVmaXhlcygpOwotCi0gICAgICB3aGlsZSAocHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKSBwcmVmaXhlcy5uZXh0RWxlbWVudCgpOwotICAgICAgICBTdHJpbmcgdXJpID0gcnRmLm1fbnNTdXBwb3J0LmdldFVSSShwcmVmaXgpOwotCi0gICAgICAgIG1fbnNTdXBwb3J0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgfQotCi0gICAgICBtX25zQ29udGV4dFB1c2hlZCA9IHJ0Zi5tX25zQ29udGV4dFB1c2hlZDsKLQotICAgICAgWFBhdGhDb250ZXh0IHhwYyA9IHRyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpOwotCi0gICAgICBtX3ZhcmlhYmxlU3RhY2tzID0gKFZhcmlhYmxlU3RhY2spIHhwYy5nZXRWYXJTdGFjaygpLmNsb25lKCk7Ci0gICAgICBtX2N1cnJlbnROb2RlcyA9IChpbnRbXSkgeHBjLmdldEN1cnJlbnROb2RlU3RhY2soKS5jbG9uZSgpOwotICAgICAgbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzID0KLSAgICAgICAgKGludFtdKSB4cGMuZ2V0Q3VycmVudEV4cHJlc3Npb25Ob2RlU3RhY2soKS5jbG9uZSgpOwotICAgICAgbV9jb250ZXh0Tm9kZUxpc3RzID0gKFN0YWNrKSB4cGMuZ2V0Q29udGV4dE5vZGVMaXN0c1N0YWNrKCkuY2xvbmUoKTsKLQotICAgICAgaWYgKCFtX2NvbnRleHROb2RlTGlzdHMuZW1wdHkoKSkKLSAgICAgICAgbV9jb250ZXh0Tm9kZUxpc3QgPQotICAgICAgICAgIChEVE1JdGVyYXRvcikgeHBjLmdldENvbnRleHROb2RlTGlzdCgpLmNsb25lKCk7Ci0KLSAgICAgIG1fYXhlc0l0ZXJhdG9yU3RhY2sgPSAoU3RhY2spIHhwYy5nZXRBeGVzSXRlcmF0b3JTdGFja1N0YWNrcygpLmNsb25lKCk7Ci0gICAgICBtX2N1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwgPQotICAgICAgICAoQm9vbFN0YWNrKSB0cmFuc2Zvcm1lci5tX2N1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwuY2xvbmUoKTsKLSAgICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHMgPQotICAgICAgICAoRWxlbVRlbXBsYXRlRWxlbWVudFtdKSB0cmFuc2Zvcm1lci5tX2N1cnJlbnRUZW1wbGF0ZUVsZW1lbnRzLmNsb25lKCk7Ci0gICAgICBtX2N1cnJlbnRNYXRjaFRlbXBsYXRlcyA9Ci0gICAgICAgIChTdGFjaykgdHJhbnNmb3JtZXIubV9jdXJyZW50TWF0Y2hUZW1wbGF0ZXMuY2xvbmUoKTsKLSAgICAgIG1fY3VycmVudE1hdGNoTm9kZXMgPQotICAgICAgICAoTm9kZVZlY3RvcikgdHJhbnNmb3JtZXIubV9jdXJyZW50TWF0Y2hlZE5vZGVzLmNsb25lKCk7Ci0gICAgICBtX2NvdW50ZXJzVGFibGUgPQotICAgICAgICAoQ291bnRlcnNUYWJsZSkgdHJhbnNmb3JtZXIuZ2V0Q291bnRlcnNUYWJsZSgpLmNsb25lKCk7Ci0KLSAgICAgIGlmICh0cmFuc2Zvcm1lci5tX2F0dHJTZXRTdGFjayAhPSBudWxsKQotICAgICAgICBtX2F0dHJTZXRTdGFjayA9IChTdGFjaykgdHJhbnNmb3JtZXIubV9hdHRyU2V0U3RhY2suY2xvbmUoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGNuc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIHdpbGwgcmVzZXQgdGhlIHN0eWxlc2hlZXQgdG8gYSBnaXZlbiBleGVjdXRpb24gY29udGV4dAotICAgKiBiYXNlZCBvbiBzb21lIHByZXZpb3VzbHkgdGFrZW4gc25hcHNob3Qgd2hlcmUgd2UgY2FuIHRoZW4gc3RhcnQgZXhlY3V0aW9uIAotICAgKgotICAgKiBAcGFyYW0gdHJhbnNmb3JtZXIgTm9uIG51bGwgdHJhbnNmb3JtZXIgaW5zdGFuY2UKLSAgICovCi0gIHZvaWQgYXBwbHkoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIEFyZSBhbGwgdGhlc2UgY2xvbmVzIGRlZXAgZW5vdWdoPwotICAgICAgUmVzdWx0VHJlZUhhbmRsZXIgcnRmID0gdHJhbnNmb3JtZXIuZ2V0UmVzdWx0VHJlZUhhbmRsZXIoKTsKLQotICAgICAgaWYgKHJ0ZiAhPSBudWxsKQotICAgICAgewotICAgICAgICBydGYubV9ldmVudENvdW50ID0gMTsgIC8vMSBmb3Igc3RhcnQgZG9jdW1lbnQgZXZlbnQhIG1fZXZlbnRDb3VudDsKLQotICAgICAgICAvLyB5dWNrLiAgTm8gY2xvbmUuIEhvcGUgdGhpcyBpcyBnb29kIGVub3VnaC4KLSAgICAgICAgcnRmLm1fbnNTdXBwb3J0ID0gbmV3IE5hbWVzcGFjZVN1cHBvcnQoKTsKLQotICAgICAgICBFbnVtZXJhdGlvbiBwcmVmaXhlcyA9IG1fbnNTdXBwb3J0LmdldFByZWZpeGVzKCk7Ci0KLSAgICAgICAgd2hpbGUgKHByZWZpeGVzLmhhc01vcmVFbGVtZW50cygpKQotICAgICAgICB7Ci0gICAgICAgICAgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpIHByZWZpeGVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgU3RyaW5nIHVyaSA9IG1fbnNTdXBwb3J0LmdldFVSSShwcmVmaXgpOwotCi0gICAgICAgICAgcnRmLm1fbnNTdXBwb3J0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgICB9Ci0KLSAgICAgICAgcnRmLm1fbnNDb250ZXh0UHVzaGVkID0gbV9uc0NvbnRleHRQdXNoZWQ7Ci0gICAgICB9Ci0KLSAgICAgIFhQYXRoQ29udGV4dCB4cGMgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLQotICAgICAgeHBjLnNldFZhclN0YWNrKChWYXJpYWJsZVN0YWNrKSBtX3ZhcmlhYmxlU3RhY2tzLmNsb25lKCkpOwotICAgICAgeHBjLnNldEN1cnJlbnROb2RlU3RhY2soKGludFtdKSBtX2N1cnJlbnROb2Rlcy5jbG9uZSgpKTsKLSAgICAgIHhwYy5zZXRDdXJyZW50RXhwcmVzc2lvbk5vZGVTdGFjaygKLSAgICAgICAgKGludFtdKSBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXMuY2xvbmUoKSk7Ci0gICAgICB4cGMuc2V0Q29udGV4dE5vZGVMaXN0c1N0YWNrKChTdGFjaykgbV9jb250ZXh0Tm9kZUxpc3RzLmNsb25lKCkpOwotCi0gICAgICBpZiAobV9jb250ZXh0Tm9kZUxpc3QgIT0gbnVsbCkKLSAgICAgICAgeHBjLnB1c2hDb250ZXh0Tm9kZUxpc3QoKERUTUl0ZXJhdG9yKSBtX2NvbnRleHROb2RlTGlzdC5jbG9uZSgpKTsKLQotICAgICAgeHBjLnNldEF4ZXNJdGVyYXRvclN0YWNrU3RhY2tzKChTdGFjaykgbV9heGVzSXRlcmF0b3JTdGFjay5jbG9uZSgpKTsKLQotICAgICAgdHJhbnNmb3JtZXIubV9jdXJyZW50VGVtcGxhdGVSdWxlSXNOdWxsID0KLSAgICAgICAgKEJvb2xTdGFjaykgbV9jdXJyZW50VGVtcGxhdGVSdWxlSXNOdWxsLmNsb25lKCk7Ci0gICAgICB0cmFuc2Zvcm1lci5tX2N1cnJlbnRUZW1wbGF0ZUVsZW1lbnRzID0KLSAgICAgICAgKEVsZW1UZW1wbGF0ZUVsZW1lbnRbXSkgbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50cy5jbG9uZSgpOwotICAgICAgdHJhbnNmb3JtZXIubV9jdXJyZW50TWF0Y2hUZW1wbGF0ZXMgPQotICAgICAgICAoU3RhY2spIG1fY3VycmVudE1hdGNoVGVtcGxhdGVzLmNsb25lKCk7Ci0gICAgICB0cmFuc2Zvcm1lci5tX2N1cnJlbnRNYXRjaGVkTm9kZXMgPQotICAgICAgICAoTm9kZVZlY3RvcikgbV9jdXJyZW50TWF0Y2hOb2Rlcy5jbG9uZSgpOwotICAgICAgdHJhbnNmb3JtZXIubV9jb3VudGVyc1RhYmxlID0gKENvdW50ZXJzVGFibGUpIG1fY291bnRlcnNUYWJsZS5jbG9uZSgpOwotCi0gICAgICBpZiAobV9hdHRyU2V0U3RhY2sgIT0gbnVsbCkKLSAgICAgICAgdHJhbnNmb3JtZXIubV9hdHRyU2V0U3RhY2sgPSAoU3RhY2spIG1fYXR0clNldFN0YWNrLmNsb25lKCk7Ci0gICAgfQotICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihjbnNlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyYW5zZm9ybVN0YXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1TdGF0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZDlhMWZhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyYW5zZm9ybVN0YXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBpcyBtZWFudCB0byBiZSB1c2VkIGJ5IGEgY29uc3VtZXIgb2YKLSAqIFNBWDIgZXZlbnRzIHByb2R1Y2VkIGJ5IFhhbGFuLCBhbmQgZW5hYmxlcyB0aGUgY29uc3VtZXIKLSAqIHRvIGdldCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3RhdGUgb2YgdGhlIHRyYW5zZm9ybS4gIEl0Ci0gKiBpcyBwcmltYXJpbHkgaW50ZW5kZWQgYXMgYSB0b29saW5nIGludGVyZmFjZS4gIEEgY29udGVudAotICogaGFuZGxlciBjYW4gZ2V0IGEgcmVmZXJlbmNlIHRvIGEgVHJhbnNmb3JtU3RhdGUgYnkgaW1wbGVtZW50aW5nCi0gKiB0aGUgVHJhbnNmb3JtZXJDbGllbnQgaW50ZXJmYWNlLiAgWGFsYW4gd2lsbCBjaGVjayBmb3IKLSAqIHRoYXQgaW50ZXJmYWNlIGJlZm9yZSBpdCBjYWxscyBzdGFydERvY3VtZW50LCBhbmQsIGlmIGl0Ci0gKiBpcyBpbXBsZW1lbnRlZCwgcGFzcyBpbiBhIFRyYW5zZm9ybVN0YXRlIHJlZmVyZW5jZSB0byB0aGUKLSAqIHNldFRyYW5zZm9ybVN0YXRlIG1ldGhvZC4KLSAqCi0gKiA8cD5Ob3RlIHRoYXQgdGhlIGN1cnJlbnQgc3R5bGVzaGVldCBhbmQgcm9vdCBzdHlsZXNoZWV0IGNhbgotICogYmUgcmV0cmlldmVkIGZyb20gdGhlIEVsZW1UZW1wbGF0ZUVsZW1lbnQgb2J0YWluZWQgZnJvbQotICogZWl0aGVyIGdldEN1cnJlbnRFbGVtZW50KCkgb3IgZ2V0Q3VycmVudFRlbXBsYXRlKCkuPC9wPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybVN0YXRlCi17Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlcyB0aGUgc3R5bGVzaGVldCBlbGVtZW50IHRoYXQgcHJvZHVjZWQKLSAgICogdGhlIFNBWCBldmVudC4KLSAgICoKLSAgICogPHA+UGxlYXNlIG5vdGUgdGhhdCB0aGUgRWxlbVRlbXBsYXRlRWxlbWVudCByZXR1cm5lZCBtYXkKLSAgICogYmUgaW4gYSBkZWZhdWx0IHRlbXBsYXRlLCBhbmQgdGh1cyBtYXkgbm90IGJlCi0gICAqIGRlZmluZWQgaW4gdGhlIHN0eWxlc2hlZXQuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHlsZXNoZWV0IGVsZW1lbnQgdGhhdCBwcm9kdWNlZCB0aGUgU0FYIGV2ZW50LgotICAgKi8KLSAgRWxlbVRlbXBsYXRlRWxlbWVudCBnZXRDdXJyZW50RWxlbWVudCgpOwotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlCi0gICAqIGluIHRoZSBzb3VyY2UgdHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlLgotICAgKi8KLSAgTm9kZSBnZXRDdXJyZW50Tm9kZSgpOwotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIHhzbDp0ZW1wbGF0ZQotICAgKiB0aGF0IGlzIGluIGVmZmVjdCwgd2hpY2ggbWF5IGJlIGEgbWF0Y2hlZCB0ZW1wbGF0ZQotICAgKiBvciBhIG5hbWVkIHRlbXBsYXRlLgotICAgKgotICAgKiA8cD5QbGVhc2Ugbm90ZSB0aGF0IHRoZSBFbGVtVGVtcGxhdGUgcmV0dXJuZWQgbWF5Ci0gICAqIGJlIGEgZGVmYXVsdCB0ZW1wbGF0ZSwgYW5kIHRodXMgbWF5IG5vdCBoYXZlIGEgdGVtcGxhdGUKLSAgICogZGVmaW5lZCBpbiB0aGUgc3R5bGVzaGVldC48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIHhzbDp0ZW1wbGF0ZSB0aGF0IGlzIGluIGVmZmVjdAotICAgKi8KLSAgRWxlbVRlbXBsYXRlIGdldEN1cnJlbnRUZW1wbGF0ZSgpOwotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIHhzbDp0ZW1wbGF0ZQotICAgKiB0aGF0IHdhcyBtYXRjaGVkLiAgTm90ZSB0aGF0IHRoaXMgbWF5IG5vdCBiZQotICAgKiB0aGUgc2FtZSB0aGluZyBhcyB0aGUgY3VycmVudCB0ZW1wbGF0ZSAod2hpY2gKLSAgICogbWF5IGJlIGZyb20gZ2V0Q3VycmVudEVsZW1lbnQoKSksIHNpbmNlIGEgbmFtZWQKLSAgICogdGVtcGxhdGUgbWF5IGJlIGluIGVmZmVjdC4KLSAgICoKLSAgICogPHA+UGxlYXNlIG5vdGUgdGhhdCB0aGUgRWxlbVRlbXBsYXRlIHJldHVybmVkIG1heQotICAgKiBiZSBhIGRlZmF1bHQgdGVtcGxhdGUsIGFuZCB0aHVzIG1heSBub3QgaGF2ZSBhIHRlbXBsYXRlCi0gICAqIGRlZmluZWQgaW4gdGhlIHN0eWxlc2hlZXQuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIHRoZSB4c2w6dGVtcGxhdGUgdGhhdCB3YXMgbWF0Y2hlZC4KLSAgICovCi0gIEVsZW1UZW1wbGF0ZSBnZXRNYXRjaGVkVGVtcGxhdGUoKTsKLQotICAvKioKLSAgICogUmV0cmlldmVzIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZSB0aGF0IG1hdGNoZWQKLSAgICogdGhlIHRlbXBsYXRlIG9idGFpbmVkIHZpYSBnZXRNYXRjaGVkVGVtcGxhdGUoKS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUgdGhhdCBtYXRjaGVkCi0gICAqIHRoZSB0ZW1wbGF0ZSBvYnRhaW5lZCB2aWEgZ2V0TWF0Y2hlZFRlbXBsYXRlKCkuCi0gICAqLwotICBOb2RlIGdldE1hdGNoZWROb2RlKCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICovCi0gIE5vZGVJdGVyYXRvciBnZXRDb250ZXh0Tm9kZUxpc3QoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBUckFYIFRyYW5zZm9ybWVyIG9iamVjdCBpbiBlZmZlY3QuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFRyQVggVHJhbnNmb3JtZXIgb2JqZWN0IGluIGVmZmVjdC4KLSAgICovCi0gIFRyYW5zZm9ybWVyIGdldFRyYW5zZm9ybWVyKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lckNsaWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJhbnNmb3JtZXJDbGllbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTQ2NTRjOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lckNsaWVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotLyoqCi0gKiBBIGNvbnRlbnQgaGFuZGxlciBjYW4gZ2V0IGEgcmVmZXJlbmNlCi0gKiB0byBhIFRyYW5zZm9ybVN0YXRlIGJ5IGltcGxlbWVudGluZwotICogdGhlIFRyYW5zZm9ybWVyQ2xpZW50IGludGVyZmFjZS4gIFhhbGFuIHdpbGwgY2hlY2sgZm9yCi0gKiB0aGF0IGludGVyZmFjZSBiZWZvcmUgaXQgY2FsbHMgc3RhcnREb2N1bWVudCwgYW5kLCBpZiBpdAotICogaXMgaW1wbGVtZW50ZWQsIHBhc3MgaW4gYSBUcmFuc2Zvcm1TdGF0ZSByZWZlcmVuY2UgdG8gdGhlCi0gKiBzZXRUcmFuc2Zvcm1TdGF0ZSBtZXRob2QuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgVHJhbnNmb3JtZXJDbGllbnQKLXsKLQotICAvKioKLSAgICogUGFzcyBpbiBhIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybVN0YXRlIG9iamVjdCwgd2hpY2gKLSAgICogY2FuIGJlIHVzZWQgZHVyaW5nIFNBWCBDb250ZW50SGFuZGxlciBldmVudHMgdG8gb2J0YWluCi0gICAqIGluZm9ybWF0aW9uIGFib3V0IGhlIHN0YXRlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi4gVGhpcwotICAgKiBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgIGJlZm9yZSBlYWNoIHN0YXJ0RG9jdW1lbnQgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSB0cyBBIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybVN0YXRlIG9iamVjdAotICAgKi8KLSAgdm9pZCBzZXRUcmFuc2Zvcm1TdGF0ZShUcmFuc2Zvcm1TdGF0ZSB0cyk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lckhhbmRsZXJJbXBsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lckhhbmRsZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkZWQxNWEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEwNSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxGaWx0ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkRUREhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8vIGltcG9ydCBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuSW5jcmVtZW50YWxTQVhTb3VyY2U7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5JbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5zYXgyZHRtLlNBWDJEVE07Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiBBIFRyYW5zZm9ybWVySGFuZGxlcgotICogbGlzdGVucyBmb3IgU0FYIENvbnRlbnRIYW5kbGVyIHBhcnNlIGV2ZW50cyBhbmQgdHJhbnNmb3JtcwotICogdGhlbSB0byBhIFJlc3VsdC4KLSAqLwotcHVibGljIGNsYXNzIFRyYW5zZm9ybWVySGFuZGxlckltcGwKLSAgICAgICAgaW1wbGVtZW50cyBFbnRpdHlSZXNvbHZlciwgRFRESGFuZGxlciwgQ29udGVudEhhbmRsZXIsIEVycm9ySGFuZGxlciwKLSAgICAgICAgICAgICAgICAgICBMZXhpY2FsSGFuZGxlciwgVHJhbnNmb3JtZXJIYW5kbGVyLCBEZWNsSGFuZGxlcgotewotICAKLSAgcHJpdmF0ZSBib29sZWFuIG1faW5zaWRlUGFyc2UgPSBmYWxzZTsKLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBDb25zdHJ1Y3RvcnMuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFRyYW5zZm9ybWVySGFuZGxlckltcGwuCi0gICAqCi0gICAqIEBwYXJhbSB0cmFuc2Zvcm1lciBOb24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhhbGFuIHRyYW5zZm9ybWVyIGltcGwuCi0gICAqIEBwYXJhbSBkb0ZyYWdtZW50IFRydWUgaWYgdGhlIHJlc3VsdCBzaG91bGQgYmUgYSBkb2N1bWVudCBmcmFnZW1lbnQuCi0gICAqIEBwYXJhbSBiYXNlU3lzdGVtSUQgIFRoZSBzeXN0ZW0gSUQgdG8gdXNlIGFzIHRoZSBiYXNlIGZvciByZWxhdGl2ZSBVUkxzLgotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlckltcGwoVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvRnJhZ21lbnQsIFN0cmluZyBiYXNlU3lzdGVtSUQpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBtX3RyYW5zZm9ybWVyID0gdHJhbnNmb3JtZXI7Ci0gICAgbV9iYXNlU3lzdGVtSUQgPSBiYXNlU3lzdGVtSUQ7Ci0KLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSB0cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKG51bGwsIHRydWUsIHRyYW5zZm9ybWVyLCB0cnVlLCB0cnVlKTsKLSAgICAKLSAgICBtX2R0bSA9IGR0bTsKLSAgICBkdG0uc2V0RG9jdW1lbnRCYXNlVVJJKGJhc2VTeXN0ZW1JRCk7Ci0KLSAgICBtX2NvbnRlbnRIYW5kbGVyID0gZHRtLmdldENvbnRlbnRIYW5kbGVyKCk7Ci0gICAgbV9kdGRIYW5kbGVyID0gZHRtLmdldERUREhhbmRsZXIoKTsKLSAgICBtX2VudGl0eVJlc29sdmVyID0gZHRtLmdldEVudGl0eVJlc29sdmVyKCk7Ci0gICAgbV9lcnJvckhhbmRsZXIgPSBkdG0uZ2V0RXJyb3JIYW5kbGVyKCk7Ci0gICAgbV9sZXhpY2FsSGFuZGxlciA9IGR0bS5nZXRMZXhpY2FsSGFuZGxlcigpOwotICB9Ci0gIAotICAvKiogCi0gICAqIERvIHdoYXQgbmVlZHMgdG8gYmUgZG9uZSB0byBzaHV0IGRvd24gdGhlIENvUm91dGluZSBtYW5hZ2VtZW50LgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2xlYXJDb1JvdXRpbmUoKQotICB7Ci0gICAgY2xlYXJDb1JvdXRpbmUobnVsbCk7Ci0gIH0KLSAgCi0gIC8qKiAKLSAgICogRG8gd2hhdCBuZWVkcyB0byBiZSBkb25lIHRvIHNodXQgZG93biB0aGUgQ29Sb3V0aW5lIG1hbmFnZW1lbnQuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjbGVhckNvUm91dGluZShTQVhFeGNlcHRpb24gZXgpCi0gIHsKLSAgICBpZihudWxsICE9IGV4KQotICAgICAgbV90cmFuc2Zvcm1lci5zZXRFeGNlcHRpb25UaHJvd24oZXgpOwotICAgIAotICAgIGlmKG1fZHRtIGluc3RhbmNlb2YgU0FYMkRUTSkKLSAgICB7Ci0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJJbiBjbGVhckNvUm91dGluZS4uLiIpOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIFNBWDJEVE0gc2F4MmR0bSA9ICgoU0FYMkRUTSltX2R0bSk7ICAgICAgICAgIAotICAgICAgICBpZihudWxsICE9IG1fY29udGVudEhhbmRsZXIgCi0gICAgICAgICAgICYmIG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIpCi0gICAgICAgIHsKLSAgICAgICAgICBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgc3AgPQotICAgICAgICAgICAgKEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciltX2NvbnRlbnRIYW5kbGVyOwotICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5vdyBiZSBhbGwgdGhhdCdzIG5lZWRlZC4KLSAgICAgICAgICBzcC5kZWxpdmVyTW9yZU5vZGVzKGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICAKLSAgICAgICAgc2F4MmR0bS5jbGVhckNvUm91dGluZSh0cnVlKTsKLSAgICAgICAgbV9jb250ZW50SGFuZGxlciA9IG51bGw7Ci0gICAgICAgIG1fZHRkSGFuZGxlciA9IG51bGw7Ci0gICAgICAgIG1fZW50aXR5UmVzb2x2ZXIgPSBudWxsOwotICAgICAgICBtX2Vycm9ySGFuZGxlciA9IG51bGw7Ci0gICAgICAgIG1fbGV4aWNhbEhhbmRsZXIgPSBudWxsOwotICAgICAgfQotICAgICAgY2F0Y2goVGhyb3dhYmxlIHRocm93YWJsZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3dhYmxlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgfQotICAgICAgCi0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIuLi5leGl0aW5nIGNsZWFyQ29Sb3V0aW5lIik7Ci0gICAgfQotICB9Ci0gIAotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXIuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIEVuYWJsZXMgdGhlIHVzZXIgb2YgdGhlIFRyYW5zZm9ybWVySGFuZGxlciB0byBzZXQgdGhlCi0gICAqIHRvIHNldCB0aGUgUmVzdWx0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSByZXN1bHQgQSBSZXN1bHQgaW5zdGFuY2UsIHNob3VsZCBub3QgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcmVzdWx0IGlzIGludmFsaWQgZm9yIHNvbWUgcmVhc29uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVzdWx0KFJlc3VsdCByZXN1bHQpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgPT0gcmVzdWx0KQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9SRVNVTFRfTlVMTCwgbnVsbCkpOyAvLyJyZXN1bHQgc2hvdWxkIG5vdCBiZSBudWxsIik7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBDb250ZW50SGFuZGxlciBoYW5kbGVyID0KLSAgICAgICAgbV90cmFuc2Zvcm1lci5jcmVhdGVSZXN1bHRDb250ZW50SGFuZGxlcihyZXN1bHQpOwotCi0gICAgICBtX3RyYW5zZm9ybWVyLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICAgIH0KLSAgICBjYXRjaCAoamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1JFU1VMVF9DT1VMRF9OT1RfQkVfU0VULCBudWxsKSk7IC8vInJlc3VsdCBjb3VsZCBub3QgYmUgc2V0Iik7Ci0gICAgfQotCi0gICAgbV9yZXN1bHQgPSByZXN1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlCi0gICAqIFVSTHMgd2lsbCBiZSByZXNvbHZlZC4KLSAgICogQHBhcmFtIHN5c3RlbUlEIEJhc2UgVVJJIGZvciB0aGUgc291cmNlIHRyZWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSUQpCi0gIHsKLSAgICBtX2Jhc2VTeXN0ZW1JRCA9IHN5c3RlbUlEOwotICAgIG1fZHRtLnNldERvY3VtZW50QmFzZVVSSShzeXN0ZW1JRCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlCi0gICAqIFVSTHMgd2lsbCBiZSByZXNvbHZlZC4KLSAgICogQHJldHVybiBUaGUgc3lzdGVtSUQgdGhhdCB3YXMgc2V0IHdpdGgge0BsaW5rICNzZXRTeXN0ZW1JZH0uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkKLSAgewotICAgIHJldHVybiBtX2Jhc2VTeXN0ZW1JRDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFRyYW5zZm9ybWVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIsIHdoaWNoCi0gICAqIGlzIG5lZWRlZCBpbiBvcmRlciB0byBzZXQgcGFyYW1ldGVycyBhbmQgb3V0cHV0IHByb3BlcnRpZXMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFRyYW5zZm9ybWVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyBUcmFuc2Zvcm1lciBnZXRUcmFuc2Zvcm1lcigpCi0gIHsKLSAgICByZXR1cm4gbV90cmFuc2Zvcm1lcjsKLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyLgotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gIC8qKgotICAgKiBGaWx0ZXIgYW4gZXh0ZXJuYWwgZW50aXR5IHJlc29sdXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5J3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5J3Mgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqIEByZXR1cm4gQSBuZXcgSW5wdXRTb3VyY2Ugb3IgbnVsbCBmb3IgdGhlIGRlZmF1bHQuCi0gICAqCi0gICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdyBhbgotICAgKiAgICAgICAgICAgIEkvTy1yZWxhdGVkIGV4Y2VwdGlvbiB3aGlsZSBvYnRhaW5pbmcgdGhlCi0gICAqICAgICAgICAgICAgbmV3IElucHV0U291cmNlLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyI3Jlc29sdmVFbnRpdHkKLSAgICovCi0gIHB1YmxpYyBJbnB1dFNvdXJjZSByZXNvbHZlRW50aXR5KFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX2VudGl0eVJlc29sdmVyICE9IG51bGwpCi0gICAgewotICAgICAgcmV0dXJuIG1fZW50aXR5UmVzb2x2ZXIucmVzb2x2ZUVudGl0eShwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguRFRESGFuZGxlci4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogRmlsdGVyIGEgbm90YXRpb24gZGVjbGFyYXRpb24gZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBub3RhdGlvbiBuYW1lLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIG5vdGF0aW9uJ3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm90YXRpb24ncyBzeXN0ZW0gaWRlbnRpZmllciwgb3IgbnVsbC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciNub3RhdGlvbkRlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9kdGRIYW5kbGVyICE9IG51bGwpCi0gICAgewotICAgICAgbV9kdGRIYW5kbGVyLm5vdGF0aW9uRGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaWx0ZXIgYW4gdW5wYXJzZWQgZW50aXR5IGRlY2xhcmF0aW9uIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZW50aXR5IG5hbWUuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5J3MgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5J3Mgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBub3RhdGlvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgbm90YXRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjdW5wYXJzZWRFbnRpdHlEZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCB1bnBhcnNlZEVudGl0eURlY2woCi0gICAgICAgICAgU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9kdGRIYW5kbGVyICE9IG51bGwpCi0gICAgewotICAgICAgbV9kdGRIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsIG5vdGF0aW9uTmFtZSk7Ci0gICAgfQotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIEZpbHRlciBhIG5ldyBkb2N1bWVudCBsb2NhdG9yIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgZG9jdW1lbnQgbG9jYXRvci4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVHJhbnNmb3JtZXJIYW5kbGVySW1wbCNzZXREb2N1bWVudExvY2F0b3I6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIGxvY2F0b3IuZ2V0U3lzdGVtSWQoKSk7Ci0KLSAgICB0aGlzLm1fbG9jYXRvciA9IGxvY2F0b3I7Ci0gICAgCi0gICAgaWYobnVsbCA9PSBtX2Jhc2VTeXN0ZW1JRCkKLSAgICB7Ci0gICAgICBzZXRTeXN0ZW1JZChsb2NhdG9yLmdldFN5c3RlbUlkKCkpOwotICAgIH0KLQotICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyICE9IG51bGwpCi0gICAgewotICAgICAgbV9jb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobG9jYXRvcik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZpbHRlciBhIHN0YXJ0IGRvY3VtZW50IGV2ZW50LgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzdGFydERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjc3RhcnREb2N1bWVudCIpOwotICAgICAgCi0gICAgbV9pbnNpZGVQYXJzZSA9IHRydWU7Ci0KLSAgIC8vIFRocmVhZCBsaXN0ZW5lciA9IG5ldyBUaHJlYWQobV90cmFuc2Zvcm1lcik7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgIHsKLSAgICAgIC8vbV90cmFuc2Zvcm1lci5zZXRUcmFuc2Zvcm1UaHJlYWQobGlzdGVuZXIpOwotICAgICAgaWYoRFRNTWFuYWdlci5nZXRJbmNyZW1lbnRhbCgpKQotICAgICAgewotICAgICAgICBtX3RyYW5zZm9ybWVyLnNldFNvdXJjZVRyZWVEb2NGb3JUaHJlYWQobV9kdG0uZ2V0RG9jdW1lbnQoKSk7Ci0gICAgICAgICAgICAKLSAgICAgICAgaW50IGNwcmlvcml0eSA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0UHJpb3JpdHkoKTsKLSAgICAKLSAgICAgICAgLy8gcnVuVHJhbnNmb3JtVGhyZWFkIGlzIGVxdWl2YWxlbnQgd2l0aCB0aGUgMi4wLjEgY29kZSwKLSAgICAgICAgLy8gZXhjZXB0IHRoYXQgdGhlIFRocmVhZCBtYXkgY29tZSBmcm9tIGEgcG9vbC4KLSAgICAgICAgbV90cmFuc2Zvcm1lci5ydW5UcmFuc2Zvcm1UaHJlYWQoIGNwcmlvcml0eSApOwotICAgICAgfQotCi0gICAgICAvLyBUaGlzIGlzIG5vdyBkb25lIF9sYXN0XywgYmVjYXVzZSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIKLSAgICAgIC8vIHdpbGwgaW1tZWRpYXRlbHkgZ28gaW50byBhICJ3YWl0IHVudGlsIGV2ZW50cyBhcmUgcmVxdWVzdGVkIgotICAgICAgLy8gcGF1c2UuIEkgYmVsaWV2ZSB0aGF0IHdpbGwgY2xvc2Ugb3VyIHRpbWluZyB3aW5kb3cuCi0gICAgICAvLyAlUkVWSUVXJQotICAgICAgbV9jb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICB9Ci0gICAgICAgIAotICAgLy9saXN0ZW5lci5zZXREYWVtb24oZmFsc2UpOwotICAgLy9saXN0ZW5lci5zdGFydCgpOwotCi0gIH0KLQotICAvKioKLSAgICogRmlsdGVyIGFuIGVuZCBkb2N1bWVudCBldmVudC4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kRG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjZW5kRG9jdW1lbnQiKTsKLQotICAgIG1faW5zaWRlUGFyc2UgPSBmYWxzZTsKLSAgICAKLSAgICBpZiAobV9jb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgIHsKLSAgICAgIG1fY29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLSAgICB9Ci0gICAgCi0gICAgaWYoRFRNTWFuYWdlci5nZXRJbmNyZW1lbnRhbCgpKQotICAgIHsKLSAgICAgIG1fdHJhbnNmb3JtZXIud2FpdFRyYW5zZm9ybVRocmVhZCgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV90cmFuc2Zvcm1lci5zZXRTb3VyY2VUcmVlRG9jRm9yVGhyZWFkKG1fZHRtLmdldERvY3VtZW50KCkpOwotICAgICAgbV90cmFuc2Zvcm1lci5ydW4oKTsKLSAgICB9Ci0gICAvKiBUaHJlYWQgdHJhbnNmb3JtVGhyZWFkID0gbV90cmFuc2Zvcm1lci5nZXRUcmFuc2Zvcm1UaHJlYWQoKTsKLQotICAgIGlmIChudWxsICE9IHRyYW5zZm9ybVRocmVhZCkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLQotICAgICAgICAvLyBUaGlzIHNob3VsZCB3YWl0IHVudGlsIHRoZSB0cmFuc2Zvcm1UaHJlYWQgaXMgY29uc2lkZXJlZCBub3QgYWxpdmUuCi0gICAgICAgIHRyYW5zZm9ybVRocmVhZC5qb2luKCk7Ci0KLSAgICAgICAgaWYgKCFtX3RyYW5zZm9ybWVyLmhhc1RyYW5zZm9ybVRocmVhZEVycm9yQ2F0Y2hlcigpKQotICAgICAgICB7Ci0gICAgICAgICAgRXhjZXB0aW9uIGUgPSBtX3RyYW5zZm9ybWVyLmdldEV4Y2VwdGlvblRocm93bigpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gZSkKLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBtX3RyYW5zZm9ybWVyLnNldFRyYW5zZm9ybVRocmVhZChudWxsKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSl7fQotICAgIH0qLwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbHRlciBhIHN0YXJ0IE5hbWVzcGFjZSBwcmVmaXggbWFwcGluZyBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeC4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVHJhbnNmb3JtZXJIYW5kbGVySW1wbCNzdGFydFByZWZpeE1hcHBpbmc6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIHByZWZpeCArICIsICIgKyB1cmkpOwotCi0gICAgaWYgKG1fY29udGVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX2NvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhwcmVmaXgsIHVyaSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZpbHRlciBhbiBlbmQgTmFtZXNwYWNlIHByZWZpeCBtYXBwaW5nIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRQcmVmaXhNYXBwaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI2VuZFByZWZpeE1hcHBpbmc6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIHByZWZpeCk7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgIHsKLSAgICAgIG1fY29udGVudEhhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaWx0ZXIgYSBzdGFydCBlbGVtZW50IGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBlbGVtZW50J3MgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgZWxlbWVudCdzIGxvY2FsIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcuCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgZWxlbWVudCdzIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUsIG9yIHRoZSBlbXB0eQotICAgKiAgICAgICAgc3RyaW5nLgotICAgKiBAcGFyYW0gYXR0cyBUaGUgZWxlbWVudCdzIGF0dHJpYnV0ZXMuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KAotICAgICAgICAgIFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjc3RhcnRFbGVtZW50OiAiICsgcU5hbWUpOwotCi0gICAgaWYgKG1fY29udGVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX2NvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcU5hbWUsIGF0dHMpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaWx0ZXIgYW4gZW5kIGVsZW1lbnQgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIGVsZW1lbnQncyBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBlbGVtZW50J3MgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZy4KLSAgICogQHBhcmFtIHFOYW1lIFRoZSBlbGVtZW50J3MgcXVhbGlmaWVkIChwcmVmaXhlZCkgbmFtZSwgb3IgdGhlIGVtcHR5Ci0gICAqICAgICAgICBzdHJpbmcuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZEVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI2VuZEVsZW1lbnQ6ICIgKyBxTmFtZSk7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgIHsKLSAgICAgIG1fY29udGVudEhhbmRsZXIuZW5kRWxlbWVudCh1cmksIGxvY2FsTmFtZSwgcU5hbWUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaWx0ZXIgYSBjaGFyYWN0ZXIgZGF0YSBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI2NoYXJhY3RlcnM6ICIgKyBzdGFydCArICIsICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIGxlbmd0aCk7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgIHsKLSAgICAgIG1fY29udGVudEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZpbHRlciBhbiBpZ25vcmFibGUgd2hpdGVzcGFjZSBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBjbGllbnQgbWF5IHRocm93Ci0gICAqICAgICAgICAgICAgYW4gZXhjZXB0aW9uIGR1cmluZyBwcm9jZXNzaW5nLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2lnbm9yYWJsZVdoaXRlc3BhY2UKLSAgICovCi0gIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjaWdub3JhYmxlV2hpdGVzcGFjZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RhcnQgKyAiLCAiICsgbGVuZ3RoKTsKLQotICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyICE9IG51bGwpCi0gICAgewotICAgICAgbV9jb250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmlsdGVyIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIHRhcmdldCBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0YXJnZXQuCi0gICAqIEBwYXJhbSBkYXRhIFRoZSB0ZXh0IGZvbGxvd2luZyB0aGUgdGFyZ2V0LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVHJhbnNmb3JtZXJIYW5kbGVySW1wbCNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb246ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIHRhcmdldCArICIsICIgKyBkYXRhKTsKLQotICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyICE9IG51bGwpCi0gICAgewotICAgICAgbV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRmlsdGVyIGEgc2tpcHBlZCBlbnRpdHkgZXZlbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBza2lwcGVkIGVudGl0eS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eQotICAgKi8KLSAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjc2tpcHBlZEVudGl0eTogIiArIG5hbWUpOwotCi0gICAgaWYgKG1fY29udGVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX2NvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gICAgfQotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2Ygb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyLgotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gIC8qKgotICAgKiBGaWx0ZXIgYSB3YXJuaW5nIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gZSBUaGUgbndhcm5pbmcgYXMgYW4gZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgY2xpZW50IG1heSB0aHJvdwotICAgKiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiBkdXJpbmcgcHJvY2Vzc2luZy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjd2FybmluZwotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBUaGlzIGlzIG5vdCBncmVhdCwgYnV0IHdlIHJlYWxseSB3b3VsZCByYXRoZXIgaGF2ZSB0aGUgZXJyb3IgCi0gICAgLy8gaGFuZGxlciBiZSB0aGUgZXJyb3IgbGlzdGVuZXIgaWYgaXQgaXMgYSBlcnJvciBoYW5kbGVyLiAgQ29yb3V0aW5lJ3MgZmF0YWxFcnJvciAKLSAgICAvLyBjYW4ndCByZWFsbHkgYmUgY29uZmlndXJlZCwgc28gSSB0aGluayB0aGlzIGlzIHRoZSBiZXN0IHRoaW5nIHJpZ2h0IG5vdyAKLSAgICAvLyBmb3IgZXJyb3IgcmVwb3J0aW5nLiAgUG9zc2libHkgYW5vdGhlciBKQVhQIDEuMSBob2xlLiAgLXNiCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyIGVycm9yTGlzdGVuZXIgPSBtX3RyYW5zZm9ybWVyLmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICBpZihlcnJvckxpc3RlbmVyIGluc3RhbmNlb2YgRXJyb3JIYW5kbGVyKQotICAgIHsKLSAgICAgICgoRXJyb3JIYW5kbGVyKWVycm9yTGlzdGVuZXIpLndhcm5pbmcoZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZXJyb3JMaXN0ZW5lci53YXJuaW5nKG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IGU7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEZpbHRlciBhbiBlcnJvciBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIGUgVGhlIGVycm9yIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI2Vycm9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyAlUkVWSUVXJSBJIGRvbid0IHRoaW5rIHRoaXMgc2hvdWxkIGJlIGNhbGxlZC4gIC1zYgotICAgIC8vIGNsZWFyQ29Sb3V0aW5lKGUpOwotCi0gICAgLy8gVGhpcyBpcyBub3QgZ3JlYXQsIGJ1dCB3ZSByZWFsbHkgd291bGQgcmF0aGVyIGhhdmUgdGhlIGVycm9yIAotICAgIC8vIGhhbmRsZXIgYmUgdGhlIGVycm9yIGxpc3RlbmVyIGlmIGl0IGlzIGEgZXJyb3IgaGFuZGxlci4gIENvcm91dGluZSdzIGZhdGFsRXJyb3IgCi0gICAgLy8gY2FuJ3QgcmVhbGx5IGJlIGNvbmZpZ3VyZWQsIHNvIEkgdGhpbmsgdGhpcyBpcyB0aGUgYmVzdCB0aGluZyByaWdodCBub3cgCi0gICAgLy8gZm9yIGVycm9yIHJlcG9ydGluZy4gIFBvc3NpYmx5IGFub3RoZXIgSkFYUCAxLjEgaG9sZS4gIC1zYgotICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lciBlcnJvckxpc3RlbmVyID0gbV90cmFuc2Zvcm1lci5nZXRFcnJvckxpc3RlbmVyKCk7Ci0gICAgaWYoZXJyb3JMaXN0ZW5lciBpbnN0YW5jZW9mIEVycm9ySGFuZGxlcikKLSAgICB7Ci0gICAgICAoKEVycm9ySGFuZGxlcillcnJvckxpc3RlbmVyKS5lcnJvcihlKTsKLSAgICAgIGlmKG51bGwgIT0gbV9lcnJvckhhbmRsZXIpCi0gICAgICAgIG1fZXJyb3JIYW5kbGVyLmVycm9yKGUpOyAvLyBtYXkgbm90IGJlIGNhbGxlZC4KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBlcnJvckxpc3RlbmVyLmVycm9yKG5ldyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpKTsKLSAgICAgICAgaWYobnVsbCAhPSBtX2Vycm9ySGFuZGxlcikKLSAgICAgICAgICBtX2Vycm9ySGFuZGxlci5lcnJvcihlKTsgLy8gbWF5IG5vdCBiZSBjYWxsZWQuCi0gICAgICB9Ci0gICAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgICAgewotICAgICAgICB0aHJvdyBlOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaWx0ZXIgYSBmYXRhbCBlcnJvciBldmVudC4KLSAgICoKLSAgICogQHBhcmFtIGUgVGhlIGVycm9yIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGNsaWVudCBtYXkgdGhyb3cKLSAgICogICAgICAgICAgICBhbiBleGNlcHRpb24gZHVyaW5nIHByb2Nlc3NpbmcuCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI2ZhdGFsRXJyb3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCAhPSBtX2Vycm9ySGFuZGxlcikKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKFNBWFBhcnNlRXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICAvLyBpZ25vcmUKLSAgICAgIH0KLSAgICAgIC8vIGNsZWFyQ29Sb3V0aW5lKGUpOwotICAgIH0KLQotICAgIC8vIFRoaXMgaXMgbm90IGdyZWF0LCBidXQgd2UgcmVhbGx5IHdvdWxkIHJhdGhlciBoYXZlIHRoZSBlcnJvciAKLSAgICAvLyBoYW5kbGVyIGJlIHRoZSBlcnJvciBsaXN0ZW5lciBpZiBpdCBpcyBhIGVycm9yIGhhbmRsZXIuICBDb3JvdXRpbmUncyBmYXRhbEVycm9yIAotICAgIC8vIGNhbid0IHJlYWxseSBiZSBjb25maWd1cmVkLCBzbyBJIHRoaW5rIHRoaXMgaXMgdGhlIGJlc3QgdGhpbmcgcmlnaHQgbm93IAotICAgIC8vIGZvciBlcnJvciByZXBvcnRpbmcuICBQb3NzaWJseSBhbm90aGVyIEpBWFAgMS4xIGhvbGUuICAtc2IKLSAgICBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXIgZXJyb3JMaXN0ZW5lciA9IG1fdHJhbnNmb3JtZXIuZ2V0RXJyb3JMaXN0ZW5lcigpOwotICAgIAotICAgIGlmKGVycm9yTGlzdGVuZXIgaW5zdGFuY2VvZiBFcnJvckhhbmRsZXIpCi0gICAgewotICAgICAgKChFcnJvckhhbmRsZXIpZXJyb3JMaXN0ZW5lcikuZmF0YWxFcnJvcihlKTsKLSAgICAgIGlmKG51bGwgIT0gbV9lcnJvckhhbmRsZXIpCi0gICAgICAgIG1fZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3IoZSk7IC8vIG1heSBub3QgYmUgY2FsbGVkLgotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGVycm9yTGlzdGVuZXIuZmF0YWxFcnJvcihuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihlKSk7Ci0gICAgICAgIGlmKG51bGwgIT0gbV9lcnJvckhhbmRsZXIpCi0gICAgICAgICAgbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihlKTsgLy8gbWF5IG5vdCBiZSBjYWxsZWQuCi0gICAgICB9Ci0gICAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgICAgewotICAgICAgICB0aHJvdyBlOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlci4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBEVEQgZGVjbGFyYXRpb25zLCBpZiBhbnkuCi0gICAqCi0gICAqIDxwPkFueSBkZWNsYXJhdGlvbnMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gdGhlIGludGVybmFsIHN1YnNldAotICAgKiB1bmxlc3Mgb3RoZXJ3aXNlIGluZGljYXRlZCBieSBhIHtAbGluayAjc3RhcnRFbnRpdHkgc3RhcnRFbnRpdHl9Ci0gICAqIGV2ZW50LjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHRoZSBzdGFydC9lbmREVEQgZXZlbnRzIHdpbGwgYXBwZWFyIHdpdGhpbgotICAgKiB0aGUgc3RhcnQvZW5kRG9jdW1lbnQgZXZlbnRzIGZyb20gQ29udGVudEhhbmRsZXIgYW5kCi0gICAqIGJlZm9yZSB0aGUgZmlyc3Qgc3RhcnRFbGVtZW50IGV2ZW50LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGRvY3VtZW50IHR5cGUgbmFtZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBkZWNsYXJlZCBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlCi0gICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUKLSAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4KLSAgICogICAgICAgICAgICBleGNlcHRpb24uCi0gICAqIEBzZWUgI2VuZERURAotICAgKiBAc2VlICNzdGFydEVudGl0eQotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI3N0YXJ0RFREOiAiICsgbmFtZSArICIsICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIHB1YmxpY0lkICsgIiwgIiArIHN5c3RlbUlkKTsKLQotICAgIGlmIChudWxsICE9IG1fbGV4aWNhbEhhbmRsZXIpCi0gICAgewotICAgICAgbV9sZXhpY2FsSGFuZGxlci5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBEVEQgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjc3RhcnREVEQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZERURCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI2VuZERURCIpOwotCi0gICAgaWYgKG51bGwgIT0gbV9sZXhpY2FsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2xleGljYWxIYW5kbGVyLmVuZERURCgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGJlZ2lubmluZyBvZiBhbiBlbnRpdHkgaW4gY29udGVudC4KLSAgICoKLSAgICogPHA+PHN0cm9uZz5OT1RFOjwvZW50aXR5PiBlbnRpdHkgcmVmZXJlbmNlcyBpbiBhdHRyaWJ1dGUKLSAgICogdmFsdWVzIC0tIGFuZCB0aGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgZG9jdW1lbnQgZW50aXR5IC0tCi0gICAqIGFyZSBuZXZlciByZXBvcnRlZC48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBleHRlcm5hbCBEVEQgc3Vic2V0IGFyZSByZXBvcnRlZAotICAgKiB1c2luZyB0aGUgcHNldWRvLW5hbWUgIltkdGRdIi4gIEFsbCBvdGhlciBldmVudHMgbXVzdCBiZQotICAgKiBwcm9wZXJseSBuZXN0ZWQgd2l0aGluIHN0YXJ0L2VuZCBlbnRpdHkgZXZlbnRzLjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHNraXBwZWQgZW50aXRpZXMgd2lsbCBiZSByZXBvcnRlZCB0aHJvdWdoIHRoZQotICAgKiB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc2tpcHBlZEVudGl0eSBza2lwcGVkRW50aXR5fQotICAgKiBldmVudCwgd2hpY2ggaXMgcGFydCBvZiB0aGUgQ29udGVudEhhbmRsZXIgaW50ZXJmYWNlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNlbmRFbnRpdHkKLSAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjaW50ZXJuYWxFbnRpdHlEZWNsCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2V4dGVybmFsRW50aXR5RGVjbAotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI3N0YXJ0RW50aXR5OiAiICsgbmFtZSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuc3RhcnRFbnRpdHkobmFtZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgZW5kIG9mIGFuIGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eSB0aGF0IGlzIGVuZGluZy4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI2VuZEVudGl0eTogIiArIG5hbWUpOwotCi0gICAgaWYgKG51bGwgIT0gbV9sZXhpY2FsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2xleGljYWxIYW5kbGVyLmVuZEVudGl0eShuYW1lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIDxwPlRoZSBjb250ZW50cyBvZiB0aGUgQ0RBVEEgc2VjdGlvbiB3aWxsIGJlIHJlcG9ydGVkIHRocm91Z2gKLSAgICogdGhlIHJlZ3VsYXIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICogY2hhcmFjdGVyc30gZXZlbnQuPC9wPgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kQ0RBVEEKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVHJhbnNmb3JtZXJIYW5kbGVySW1wbCNzdGFydENEQVRBIik7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuc3RhcnRDREFUQSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNzdGFydENEQVRBCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKERFQlVHKQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc2Zvcm1lckhhbmRsZXJJbXBsI2VuZENEQVRBIik7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2xleGljYWxIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fbGV4aWNhbEhhbmRsZXIuZW5kQ0RBVEEoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIFhNTCBjb21tZW50IGFueXdoZXJlIGluIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+VGhpcyBjYWxsYmFjayB3aWxsIGJlIHVzZWQgZm9yIGNvbW1lbnRzIGluc2lkZSBvciBvdXRzaWRlIHRoZQotICAgKiBkb2N1bWVudCBlbGVtZW50LCBpbmNsdWRpbmcgY29tbWVudHMgaW4gdGhlIGV4dGVybmFsIERURAotICAgKiBzdWJzZXQgKGlmIHJlYWQpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tbWVudChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjY29tbWVudDogIiArIHN0YXJ0ICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgbGVuZ3RoKTsKLQotICAgIGlmIChudWxsICE9IG1fbGV4aWNhbEhhbmRsZXIpCi0gICAgewotICAgICAgbV9sZXhpY2FsSGFuZGxlci5jb21tZW50KGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPlRoZSBjb250ZW50IG1vZGVsIHdpbGwgY29uc2lzdCBvZiB0aGUgc3RyaW5nICJFTVBUWSIsIHRoZQotICAgKiBzdHJpbmcgIkFOWSIsIG9yIGEgcGFyZW50aGVzaXNlZCBncm91cCwgb3B0aW9uYWxseSBmb2xsb3dlZAotICAgKiBieSBhbiBvY2N1cnJlbmNlIGluZGljYXRvci4gIFRoZSBtb2RlbCB3aWxsIGJlIG5vcm1hbGl6ZWQgc28KLSAgICogdGhhdCBhbGwgd2hpdGVzcGFjZSBpcyByZW1vdmVkLGFuZCB3aWxsIGluY2x1ZGUgdGhlIGVuY2xvc2luZwotICAgKiBwYXJlbnRoZXNlcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICogQHBhcmFtIG1vZGVsIFRoZSBjb250ZW50IG1vZGVsIGFzIGEgbm9ybWFsaXplZCBzdHJpbmcuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjZWxlbWVudERlY2w6ICIgKyBuYW1lICsgIiwgIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgbW9kZWwpOwotCi0gICAgaWYgKG51bGwgIT0gbV9kZWNsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2RlY2xIYW5kbGVyLmVsZW1lbnREZWNsKG5hbWUsIG1vZGVsKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIGF0dHJpYnV0ZSB0eXBlIGRlY2xhcmF0aW9uLgotICAgKgotICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgYW4gYXR0cmlidXRlIHdpbGwKLSAgICogYmUgcmVwb3J0ZWQuICBUaGUgdHlwZSB3aWxsIGJlIG9uZSBvZiB0aGUgc3RyaW5ncyAiQ0RBVEEiLAotICAgKiAiSUQiLCAiSURSRUYiLCAiSURSRUZTIiwgIk5NVE9LRU4iLCAiTk1UT0tFTlMiLCAiRU5USVRZIiwKLSAgICogIkVOVElUSUVTIiwgb3IgIk5PVEFUSU9OIiwgb3IgYSBwYXJlbnRoZXNpemVkIHRva2VuIGdyb3VwIHdpdGgKLSAgICogdGhlIHNlcGFyYXRvciAifCIgYW5kIGFsbCB3aGl0ZXNwYWNlIHJlbW92ZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgZWxlbWVudC4KLSAgICogQHBhcmFtIGFOYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAqIEBwYXJhbSB0eXBlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIHR5cGUuCi0gICAqIEBwYXJhbSB2YWx1ZURlZmF1bHQgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgZGVmYXVsdAotICAgKiAgICAgICAgKCIjSU1QTElFRCIsICIjUkVRVUlSRUQiLCBvciAiI0ZJWEVEIikgb3IgbnVsbCBpZgotICAgKiAgICAgICAgbm9uZSBvZiB0aGVzZSBhcHBsaWVzLgotICAgKiBAcGFyYW0gdmFsdWUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUncyBkZWZhdWx0IHZhbHVlLAotICAgKiAgICAgICAgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woCi0gICAgICAgICAgU3RyaW5nIGVOYW1lLCBTdHJpbmcgYU5hbWUsIFN0cmluZyB0eXBlLCBTdHJpbmcgdmFsdWVEZWZhdWx0LCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVHJhbnNmb3JtZXJIYW5kbGVySW1wbCNhdHRyaWJ1dGVEZWNsOiAiICsgZU5hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgICArICIsICIgKyBhTmFtZSArICIsIGV0Yy4uLiIpOwotCi0gICAgaWYgKG51bGwgIT0gbV9kZWNsSGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2RlY2xIYW5kbGVyLmF0dHJpYnV0ZURlY2woZU5hbWUsIGFOYW1lLCB0eXBlLCB2YWx1ZURlZmF1bHQsIHZhbHVlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGVhY2ggZW50aXR5Ci0gICAqIHdpbGwgYmUgcmVwb3J0ZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNleHRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgKi8KLSAgcHVibGljIHZvaWQgaW50ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjaW50ZXJuYWxFbnRpdHlEZWNsOiAiICsgbmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgIiArIHZhbHVlKTsKLQotICAgIGlmIChudWxsICE9IG1fZGVjbEhhbmRsZXIpCi0gICAgewotICAgICAgbV9kZWNsSGFuZGxlci5pbnRlcm5hbEVudGl0eURlY2wobmFtZSwgdmFsdWUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgYSBwYXJzZWQgZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgKgotICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgZWFjaCBlbnRpdHkKLSAgICogd2lsbCBiZSByZXBvcnRlZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGRlY2xhcmVkIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHksIG9yCi0gICAqICAgICAgICBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNpbnRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgKi8KLSAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKAotICAgICAgICAgIFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoREVCVUcpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyYW5zZm9ybWVySGFuZGxlckltcGwjZXh0ZXJuYWxFbnRpdHlEZWNsOiAiICsgbmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgIiArIHB1YmxpY0lkICsgIiwgIiArIHN5c3RlbUlkKTsKLQotICAgIGlmIChudWxsICE9IG1fZGVjbEhhbmRsZXIpCi0gICAgewotICAgICAgbV9kZWNsSGFuZGxlci5leHRlcm5hbEVudGl0eURlY2wobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKTsKLSAgICB9Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbnRlcm5hbCBzdGF0ZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKiogU2V0IHRvIHRydWUgZm9yIGRpYWdub3N0aWNzIG91dHB1dC4gICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFRoZSB0cmFuc2Zvcm1lciB0aGlzIHdpbGwgdXNlIHRvIHRyYW5zZm9ybSBhCi0gICAqIHNvdXJjZSB0cmVlIGludG8gYSByZXN1bHQgdHJlZS4KLSAgICovCi0gIHByaXZhdGUgVHJhbnNmb3JtZXJJbXBsIG1fdHJhbnNmb3JtZXI7Ci0KLSAgLyoqIFRoZSBzeXN0ZW0gSUQgdG8gdXNlIGFzIGEgYmFzZSBmb3IgcmVsYXRpdmUgVVJMcy4gKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9iYXNlU3lzdGVtSUQ7Ci0KLSAgLyoqIFRoZSByZXN1bHQgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4gKi8KLSAgcHJpdmF0ZSBSZXN1bHQgbV9yZXN1bHQgPSBudWxsOwotCi0gIC8qKiBUaGUgbG9jYXRvciBmb3IgdGhpcyBUcmFuc2Zvcm1lckhhbmRsZXIuICovCi0gIHByaXZhdGUgTG9jYXRvciBtX2xvY2F0b3IgPSBudWxsOwotCi0gIC8qKiBUaGUgZW50aXR5IHJlc29sdmVyIHRvIGFnZ3JlZ2F0ZSB0by4gKi8KLSAgcHJpdmF0ZSBFbnRpdHlSZXNvbHZlciBtX2VudGl0eVJlc29sdmVyID0gbnVsbDsKLQotICAvKiogVGhlIERURCBoYW5kbGVyIHRvIGFnZ3JlZ2F0ZSB0by4gKi8KLSAgcHJpdmF0ZSBEVERIYW5kbGVyIG1fZHRkSGFuZGxlciA9IG51bGw7Ci0KLSAgLyoqIFRoZSBjb250ZW50IGhhbmRsZXIgdG8gYWdncmVnYXRlIHRvLiAqLwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIG1fY29udGVudEhhbmRsZXIgPSBudWxsOwotCi0gIC8qKiBUaGUgZXJyb3IgaGFuZGxlciB0byBhZ2dyZWdhdGUgdG8uICovCi0gIHByaXZhdGUgRXJyb3JIYW5kbGVyIG1fZXJyb3JIYW5kbGVyID0gbnVsbDsKLQotICAvKiogVGhlIGxleGljYWwgaGFuZGxlciB0byBhZ2dyZWdhdGUgdG8uICovCi0gIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgbV9sZXhpY2FsSGFuZGxlciA9IG51bGw7Ci0KLSAgLyoqIFRoZSBkZWNsIGhhbmRsZXIgdG8gYWdncmVnYXRlIHRvLiAqLwotICBwcml2YXRlIERlY2xIYW5kbGVyIG1fZGVjbEhhbmRsZXIgPSBudWxsOwotICAKLSAgLyoqIFRoZSBEb2N1bWVudCBUYWJsZSBJbnN0YW5jZSB3ZSBhcmUgdHJhbnNmb3JtaW5nLiAqLwotICBEVE0gbV9kdG07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lcklkZW50aXR5SW1wbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJhbnNmb3JtZXJJZGVudGl0eUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmYxOGUwZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lcklkZW50aXR5SW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQyMSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLS8vIFRSYVggSW1wb3J0cwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4Lio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uKjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLio7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkRPTUJ1aWxkZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuVHJlZVdhbGtlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLk1ldGhvZDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBpZGVudGl0eSB0cmFuc2Zvcm1lciBmb3IKLSAqIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkjbmV3VHJhbnNmb3JtZXJIYW5kbGVyKCkKLSAqIGFuZCB7QGxpbmsgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkjbmV3VHJhbnNmb3JtZXIoKX0uICBJdAotICogc2ltcGx5IGZlZWRzIFNBWCBldmVudHMgZGlyZWN0bHkgdG8gYSBzZXJpYWxpemVyIENvbnRlbnRIYW5kbGVyLCBpZiB0aGUKLSAqIHJlc3VsdCBpcyBhIHN0cmVhbS4gIElmIHRoZSByZXN1bHQgaXMgYSBET00sIGl0IHdpbGwgc2VuZCB0aGUgZXZlbnRzIHRvCi0gKiB7QGxpbmsgb3JnLmFwYWNoZS54bWwudXRpbHMuRE9NQnVpbGRlcn0uICBJZiB0aGUgcmVzdWx0IGlzIGFub3RoZXIKLSAqIGNvbnRlbnQgaGFuZGxlciwgaXQgd2lsbCBzaW1wbHkgcGFzcyB0aGUgZXZlbnRzIG9uLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtZXJJZGVudGl0eUltcGwgZXh0ZW5kcyBUcmFuc2Zvcm1lcgotICAgICAgICBpbXBsZW1lbnRzIFRyYW5zZm9ybWVySGFuZGxlciwgRGVjbEhhbmRsZXIKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgVHJhbnNmb3JtZXJJZGVudGl0eUltcGwgY3JlYXRlcyBhbiBpZGVudGl0eSB0cmFuc2Zvcm0uCi0gICAqCi0gICAqLwotICBwdWJsaWMgVHJhbnNmb3JtZXJJZGVudGl0eUltcGwoKQotICB7Ci0gICAgbV9vdXRwdXRGb3JtYXQgPSBuZXcgT3V0cHV0UHJvcGVydGllcyhNZXRob2QuWE1MKTsKLSAgfQotCi0gIC8qKgotICAgKiBFbmFibGVzIHRoZSB1c2VyIG9mIHRoZSBUcmFuc2Zvcm1lckhhbmRsZXIgdG8gc2V0IHRoZQotICAgKiB0byBzZXQgdGhlIFJlc3VsdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gcmVzdWx0IEEgUmVzdWx0IGluc3RhbmNlLCBzaG91bGQgbm90IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHJlc3VsdCBpcyBpbnZhbGlkIGZvciBzb21lIHJlYXNvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJlc3VsdChSZXN1bHQgcmVzdWx0KSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsID09IHJlc3VsdCkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUkVTVUxUX05VTEwsIG51bGwpKTsgLy8iUmVzdWx0IHNob3VsZCBub3QgYmUgbnVsbCIpOyAgICAgICAgCi0gICAgbV9yZXN1bHQgPSByZXN1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlCi0gICAqIFVSTHMgd2lsbCBiZSByZXNvbHZlZC4KLSAgICogQHBhcmFtIHN5c3RlbUlEIEJhc2UgVVJJIGZvciB0aGUgc291cmNlIHRyZWUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTeXN0ZW1JZChTdHJpbmcgc3lzdGVtSUQpCi0gIHsKLSAgICBtX3N5c3RlbUlEID0gc3lzdGVtSUQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlCi0gICAqIFVSTHMgd2lsbCBiZSByZXNvbHZlZC4KLSAgICogQHJldHVybiBUaGUgc3lzdGVtSUQgdGhhdCB3YXMgc2V0IHdpdGgge0BsaW5rICNzZXRTeXN0ZW1JZH0uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkKLSAgewotICAgIHJldHVybiBtX3N5c3RlbUlEOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgVHJhbnNmb3JtZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGFuZGxlciwgd2hpY2gKLSAgICogaXMgbmVlZGVkIGluIG9yZGVyIHRvIHNldCBwYXJhbWV0ZXJzIGFuZCBvdXRwdXQgcHJvcGVydGllcy4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHRyYW5zZm9ybWVyLgotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybWVyIGdldFRyYW5zZm9ybWVyKCkKLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIHJlc3VsdCBDb250ZW50SGFuZGxlciBmcm9tIGEgUmVzdWx0IG9iamVjdCwgYmFzZWQKLSAgICogb24gdGhlIGN1cnJlbnQgT3V0cHV0UHJvcGVydGllcy4KLSAgICoKLSAgICogQHBhcmFtIG91dHB1dFRhcmdldCBXaGVyZSB0aGUgdHJhbnNmb3JtIHJlc3VsdCBzaG91bGQgZ28sCi0gICAqIHNob3VsZCBub3QgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBBIHZhbGlkIENvbnRlbnRIYW5kbGVyIHRoYXQgd2lsbCBjcmVhdGUgdGhlCi0gICAqIHJlc3VsdCB0cmVlIHdoZW4gaXQgaXMgZmVkIFNBWCBldmVudHMuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgdm9pZCBjcmVhdGVSZXN1bHRDb250ZW50SGFuZGxlcihSZXN1bHQgb3V0cHV0VGFyZ2V0KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAob3V0cHV0VGFyZ2V0IGluc3RhbmNlb2YgU0FYUmVzdWx0KQotICAgIHsKLSAgICAgIFNBWFJlc3VsdCBzYXhSZXN1bHQgPSAoU0FYUmVzdWx0KSBvdXRwdXRUYXJnZXQ7Ci0KLSAgICAgIG1fcmVzdWx0Q29udGVudEhhbmRsZXIgPSBzYXhSZXN1bHQuZ2V0SGFuZGxlcigpOwotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlciA9IHNheFJlc3VsdC5nZXRMZXhpY2FsSGFuZGxlcigpOwotCi0gICAgICBpZiAobV9yZXN1bHRDb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIFNlcmlhbGl6ZXIpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gRHViaW91cyBidXQgbmVlZGVkLCBJIHRoaW5rLgotICAgICAgICBtX3NlcmlhbGl6ZXIgPSAoU2VyaWFsaXplcikgbV9yZXN1bHRDb250ZW50SGFuZGxlcjsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAob3V0cHV0VGFyZ2V0IGluc3RhbmNlb2YgRE9NUmVzdWx0KQotICAgIHsKLSAgICAgIERPTVJlc3VsdCBkb21SZXN1bHQgPSAoRE9NUmVzdWx0KSBvdXRwdXRUYXJnZXQ7Ci0gICAgICBOb2RlIG91dHB1dE5vZGUgPSBkb21SZXN1bHQuZ2V0Tm9kZSgpOwotICAgICAgRG9jdW1lbnQgZG9jOwotICAgICAgc2hvcnQgdHlwZTsKLQotICAgICAgaWYgKG51bGwgIT0gb3V0cHV0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgdHlwZSA9IG91dHB1dE5vZGUuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgZG9jID0gKE5vZGUuRE9DVU1FTlRfTk9ERSA9PSB0eXBlKQotICAgICAgICAgICAgICA/IChEb2N1bWVudCkgb3V0cHV0Tm9kZSA6IG91dHB1dE5vZGUuZ2V0T3duZXJEb2N1bWVudCgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICAgICAgZGJmLnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCi0gICAgICAgICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotCi0gICAgICAgICAgZG9jID0gZGIubmV3RG9jdW1lbnQoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBwY2UpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24ocGNlKTsKLSAgICAgICAgfQotCi0gICAgICAgIG91dHB1dE5vZGUgPSBkb2M7Ci0gICAgICAgIHR5cGUgPSBvdXRwdXROb2RlLmdldE5vZGVUeXBlKCk7Ci0KLSAgICAgICAgKChET01SZXN1bHQpIG91dHB1dFRhcmdldCkuc2V0Tm9kZShvdXRwdXROb2RlKTsKLSAgICAgIH0KLQotICAgICAgbV9yZXN1bHRDb250ZW50SGFuZGxlciA9Ci0gICAgICAgIChOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPT0gdHlwZSkKLSAgICAgICAgPyBuZXcgRE9NQnVpbGRlcihkb2MsIChEb2N1bWVudEZyYWdtZW50KSBvdXRwdXROb2RlKQotICAgICAgICA6IG5ldyBET01CdWlsZGVyKGRvYywgb3V0cHV0Tm9kZSk7Ci0gICAgICBtX3Jlc3VsdExleGljYWxIYW5kbGVyID0gKExleGljYWxIYW5kbGVyKSBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyOwotICAgIH0KLSAgICBlbHNlIGlmIChvdXRwdXRUYXJnZXQgaW5zdGFuY2VvZiBTdHJlYW1SZXN1bHQpCi0gICAgewotICAgICAgU3RyZWFtUmVzdWx0IHNyZXN1bHQgPSAoU3RyZWFtUmVzdWx0KSBvdXRwdXRUYXJnZXQ7Ci0gICAgICBTdHJpbmcgbWV0aG9kID0gbV9vdXRwdXRGb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRVRIT0QpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgU2VyaWFsaXplciBzZXJpYWxpemVyID0KLSAgICAgICAgICBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyKG1fb3V0cHV0Rm9ybWF0LmdldFByb3BlcnRpZXMoKSk7Ci0KLSAgICAgICAgbV9zZXJpYWxpemVyID0gc2VyaWFsaXplcjsKLQotICAgICAgICBpZiAobnVsbCAhPSBzcmVzdWx0LmdldFdyaXRlcigpKQotICAgICAgICAgIHNlcmlhbGl6ZXIuc2V0V3JpdGVyKHNyZXN1bHQuZ2V0V3JpdGVyKCkpOwotICAgICAgICBlbHNlIGlmIChudWxsICE9IHNyZXN1bHQuZ2V0T3V0cHV0U3RyZWFtKCkpCi0gICAgICAgICAgc2VyaWFsaXplci5zZXRPdXRwdXRTdHJlYW0oc3Jlc3VsdC5nZXRPdXRwdXRTdHJlYW0oKSk7Ci0gICAgICAgIGVsc2UgaWYgKG51bGwgIT0gc3Jlc3VsdC5nZXRTeXN0ZW1JZCgpKQotICAgICAgICB7Ci0gICAgICAgICAgU3RyaW5nIGZpbGVVUkwgPSBzcmVzdWx0LmdldFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgICBpZiAoZmlsZVVSTC5zdGFydHNXaXRoKCJmaWxlOi8vLyIpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChmaWxlVVJMLnN1YnN0cmluZyg4KS5pbmRleE9mKCI6IikgPjApCi0gICAgICAgICAgICAgIGZpbGVVUkwgPSBmaWxlVVJMLnN1YnN0cmluZyg4KTsKLSAgICAgICAgICAgIGVsc2UgCi0gICAgICAgICAgICAgIGZpbGVVUkwgPSBmaWxlVVJMLnN1YnN0cmluZyg3KTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBtX291dHB1dFN0cmVhbSA9IG5ldyBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW0oZmlsZVVSTCk7Ci0gICAgICAgICAgc2VyaWFsaXplci5zZXRPdXRwdXRTdHJlYW0obV9vdXRwdXRTdHJlYW0pOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fT1VUUFVUX1NQRUNJRklFRCwgbnVsbCkpOyAvLyJObyBvdXRwdXQgc3BlY2lmaWVkISIpOwotCi0gICAgICAgIG1fcmVzdWx0Q29udGVudEhhbmRsZXIgPSBzZXJpYWxpemVyLmFzQ29udGVudEhhbmRsZXIoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihpb2UpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUsIG5ldyBPYmplY3RbXXtvdXRwdXRUYXJnZXQuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7IC8vIkNhbid0IHRyYW5zZm9ybSB0byBhIFJlc3VsdCBvZiB0eXBlICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgb3V0cHV0VGFyZ2V0LmdldENsYXNzKCkuZ2V0TmFtZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyArICIhIik7Ci0gICAgfQotCi0gICAgaWYgKG1fcmVzdWx0Q29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBEVERIYW5kbGVyKQotICAgICAgbV9yZXN1bHREVERIYW5kbGVyID0gKERUREhhbmRsZXIpIG1fcmVzdWx0Q29udGVudEhhbmRsZXI7Ci0gICAgCi0gICAgaWYgKG1fcmVzdWx0Q29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBEZWNsSGFuZGxlcikKLSAgICAgIG1fcmVzdWx0RGVjbEhhbmRsZXIgPSAoRGVjbEhhbmRsZXIpIG1fcmVzdWx0Q29udGVudEhhbmRsZXI7Ci0KLSAgICBpZiAobV9yZXN1bHRDb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlciA9IChMZXhpY2FsSGFuZGxlcikgbV9yZXN1bHRDb250ZW50SGFuZGxlcjsKLSAgfQotCi0gIC8qKgotICAgKiBQcm9jZXNzIHRoZSBzb3VyY2UgdHJlZSB0byB0aGUgb3V0cHV0IHJlc3VsdC4KLSAgICogQHBhcmFtIHNvdXJjZSAgVGhlIGlucHV0IGZvciB0aGUgc291cmNlIHRyZWUuCi0gICAqCi0gICAqIEBwYXJhbSBvdXRwdXRUYXJnZXQgVGhlIG91dHB1dCB0YXJnZXQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gSWYgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBvY2N1cnMKLSAgICogZHVyaW5nIHRoZSBjb3Vyc2Ugb2YgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhbnNmb3JtKFNvdXJjZSBzb3VyY2UsIFJlc3VsdCBvdXRwdXRUYXJnZXQpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGNyZWF0ZVJlc3VsdENvbnRlbnRIYW5kbGVyKG91dHB1dFRhcmdldCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKQotICAgICAgewotICAgICAgICBET01Tb3VyY2UgZHNvdXJjZSA9IChET01Tb3VyY2UpIHNvdXJjZTsKLSAgCi0gICAgICAgIG1fc3lzdGVtSUQgPSBkc291cmNlLmdldFN5c3RlbUlkKCk7Ci0gIAotICAgICAgICBOb2RlIGROb2RlID0gZHNvdXJjZS5nZXROb2RlKCk7Ci0gIAotICAgICAgICBpZiAobnVsbCAhPSBkTm9kZSkKLSAgICAgICAgewotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmKGROb2RlLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICAgICAgICB0aGlzLnN0YXJ0RG9jdW1lbnQoKTsKLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZihkTm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuQVRUUklCVVRFX05PREUpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSA9IGROb2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGNoYXJbXSBjaGFycyA9IGRhdGEudG9DaGFyQXJyYXkoKTsKLSAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFRyZWVXYWxrZXIgd2Fsa2VyID0gbmV3IFRyZWVXYWxrZXIodGhpcywgbmV3IG9yZy5hcGFjaGUueHBhdGguRE9NMkhlbHBlcigpLCBtX3N5c3RlbUlEKTsKLSAgICAgICAgICAgICAgICB3YWxrZXIudHJhdmVyc2UoZE5vZGUpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBmaW5hbGx5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmKGROb2RlLmdldE5vZGVUeXBlKCkgIT0gTm9kZS5ET0NVTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgIHRoaXMuZW5kRG9jdW1lbnQoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBzZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgICAgICAgIH0KLSAgCi0gICAgICAgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBtZXNzYWdlU3RyID0gWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9JTExFR0FMX0RPTVNPVVJDRV9JTlBVVCwgbnVsbCk7Ci0gIAotICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obWVzc2FnZVN0cik7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgCi0gICAgICBJbnB1dFNvdXJjZSB4bWxTb3VyY2UgPSBTQVhTb3VyY2Uuc291cmNlVG9JbnB1dFNvdXJjZShzb3VyY2UpOwotICAKLSAgICAgIGlmIChudWxsID09IHhtbFNvdXJjZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9UUkFOU0ZPUk1fU09VUkNFX1RZUEUsIG5ldyBPYmplY3RbXXtzb3VyY2UuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7IC8vIkNhbid0IHRyYW5zZm9ybSBhIFNvdXJjZSBvZiB0eXBlICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBzb3VyY2UuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiISIpOwotICAgICAgfQotICAKLSAgICAgIGlmIChudWxsICE9IHhtbFNvdXJjZS5nZXRTeXN0ZW1JZCgpKQotICAgICAgICBtX3N5c3RlbUlEID0geG1sU291cmNlLmdldFN5c3RlbUlkKCk7Ci0gIAotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIFhNTFJlYWRlciByZWFkZXIgPSBudWxsOwotICAKLSAgICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSkKLSAgICAgICAgICByZWFkZXIgPSAoKFNBWFNvdXJjZSkgc291cmNlKS5nZXRYTUxSZWFkZXIoKTsKLSAgICAgICAgICAKLSAgICAgICAgYm9vbGVhbiBpc1VzZXJSZWFkZXIgPSAocmVhZGVyICE9IG51bGwpOwotICAKLSAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKQotICAgICAgICB7Ci0gIAotICAgICAgICAgIC8vIFVzZSBKQVhQMS4xICggaWYgcG9zc2libGUgKSAgICAgIAotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9Ci0gICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgCi0gICAgICAgICAgICBmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotICAKLSAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgCi0gICAgICAgICAgICByZWFkZXIgPSBqYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgxLnRvU3RyaW5nKCkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoTm9TdWNoTWV0aG9kRXJyb3IgZXgyKXt9Ci0gICAgICAgICAgY2F0Y2ggKEFic3RyYWN0TWV0aG9kRXJyb3IgYW1lKXt9Ci0gICAgICAgIH0KLSAgCi0gICAgICAgIGlmIChudWxsID09IHJlYWRlcikKLSAgICAgICAgewotICAgICAgICAgIHJlYWRlciA9IFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7Ci0gICAgICAgIH0KLSAgCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgICAvLyBDb21tZW50ZWQgb3V0IGFzIHBlciBkaXNjdXNzaW9uIHdpdGggVGhvbWFzMi5NYWVzaW5nQGJncy1hZy5kZSAKLSAgICAgICAgLy8gYWJvdXQgYnVnIDIxMjQuCi0vLyAgICAgICAgICBpZighaXNVc2VyUmVhZGVyKQotLy8gICAgICAgICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYyIsCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgICAgIHsKLSAgCi0gICAgICAgICAgLy8gV2UgZG9uJ3QgY2FyZS4KLSAgICAgICAgfQotICAKLSAgICAgICAgLy8gR2V0IHRoZSBpbnB1dCBjb250ZW50IGhhbmRsZXIsIHdoaWNoIHdpbGwgaGFuZGxlIHRoZSAKLSAgICAgICAgLy8gcGFyc2UgZXZlbnRzIGFuZCBjcmVhdGUgdGhlIHNvdXJjZSB0cmVlLiAKLSAgICAgICAgQ29udGVudEhhbmRsZXIgaW5wdXRIYW5kbGVyID0gdGhpczsKLSAgCi0gICAgICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihpbnB1dEhhbmRsZXIpOwotICAKLSAgICAgICAgaWYgKGlucHV0SGFuZGxlciBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LkRUREhhbmRsZXIpCi0gICAgICAgICAgcmVhZGVyLnNldERUREhhbmRsZXIoKG9yZy54bWwuc2F4LkRUREhhbmRsZXIpIGlucHV0SGFuZGxlcik7Ci0gIAotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGlmIChpbnB1dEhhbmRsZXIgaW5zdGFuY2VvZiBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIpCi0gICAgICAgICAgICByZWFkZXIuc2V0UHJvcGVydHkoImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRIYW5kbGVyKTsKLSAgCi0gICAgICAgICAgaWYgKGlucHV0SGFuZGxlciBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcikKLSAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgKLSAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RlY2xhcmF0aW9uLWhhbmRsZXIiLAotICAgICAgICAgICAgICBpbnB1dEhhbmRsZXIpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2Upe30KLSAgCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGlucHV0SGFuZGxlciBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcikKLSAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L2hhbmRsZXJzL0xleGljYWxIYW5kbGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dEhhbmRsZXIpOwotICAKLSAgICAgICAgICBpZiAoaW5wdXRIYW5kbGVyIGluc3RhbmNlb2Ygb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyKQotICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvaGFuZGxlcnMvRGVjbEhhbmRsZXIiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0SGFuZGxlcik7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gc25yZSl7fQotICAKLSAgICAgICAgcmVhZGVyLnBhcnNlKHhtbFNvdXJjZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAob3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24gd3JlKQotICAgICAgewotICAgICAgICBUaHJvd2FibGUgdGhyb3dhYmxlID0gd3JlLmdldEV4Y2VwdGlvbigpOwotICAKLSAgICAgICAgd2hpbGUgKHRocm93YWJsZQotICAgICAgICAgICAgICAgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbikKLSAgICAgICAgewotICAgICAgICAgIHRocm93YWJsZSA9Ci0gICAgICAgICAgICAoKG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKSB0aHJvd2FibGUpLmdldEV4Y2VwdGlvbigpOwotICAgICAgICB9Ci0gIAotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24od3JlLmdldEV4Y2VwdGlvbigpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihzZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oaW9lKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmKG51bGwgIT0gbV9vdXRwdXRTdHJlYW0pCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgbV9vdXRwdXRTdHJlYW0uY2xvc2UoKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaChJT0V4Y2VwdGlvbiBpb2Upe30KLSAgICAgICAgbV9vdXRwdXRTdHJlYW0gPSBudWxsOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBwYXJhbWV0ZXIgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICoKLSAgICogPHA+UGFzcyBhIHF1YWxpZmllZCBuYW1lIGFzIGEgdHdvLXBhcnQgc3RyaW5nLCB0aGUgbmFtZXNwYWNlIFVSSQotICAgKiBlbmNsb3NlZCBpbiBjdXJseSBicmFjZXMgKHt9KSwgZm9sbG93ZWQgYnkgdGhlIGxvY2FsIG5hbWUuIElmIHRoZQotICAgKiBuYW1lIGhhcyBhIG51bGwgVVJMLCB0aGUgU3RyaW5nIG9ubHkgY29udGFpbiB0aGUgbG9jYWwgbmFtZS4gQW4KLSAgICogYXBwbGljYXRpb24gY2FuIHNhZmVseSBjaGVjayBmb3IgYSBub24tbnVsbCBVUkkgYnkgdGVzdGluZyB0byBzZWUgaWYgdGhlIGZpcnN0Ci0gICAqIGNoYXJhY3RlciBvZiB0aGUgbmFtZSBpcyBhICd7JyBjaGFyYWN0ZXIuPC9wPgotICAgKiA8cD5Gb3IgZXhhbXBsZSwgaWYgYSBVUkkgYW5kIGxvY2FsIG5hbWUgd2VyZSBvYnRhaW5lZCBmcm9tIGFuIGVsZW1lbnQKLSAgICogZGVmaW5lZCB3aXRoICZsdDt4eXo6Zm9vIHhtbG5zOnh5ej0iaHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWwiLyZndDssCi0gICAqIHRoZW4gdGhlIHF1YWxpZmllZCBuYW1lIHdvdWxkIGJlICJ7aHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWx9Zm9vIi4gTm90ZSB0aGF0Ci0gICAqIG5vIHByZWZpeCBpcyB1c2VkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciwgd2hpY2ggbWF5IGJlZ2luIHdpdGggYSBuYW1lc3BhY2UgVVJJCi0gICAqIGluIGN1cmx5IGJyYWNlcyAoe30pLgotICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9iamVjdC4gIFRoaXMgY2FuIGJlIGFueSB2YWxpZCBKYXZhIG9iamVjdC4gSXQgaXMKLSAgICogdXAgdG8gdGhlIHByb2Nlc3NvciB0byBwcm92aWRlIHRoZSBwcm9wZXIgb2JqZWN0IGNvZXJzaW9uIG9yIHRvIHNpbXBseQotICAgKiBwYXNzIHRoZSBvYmplY3Qgb24gZm9yIHVzZSBpbiBhbiBleHRlbnNpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9wYXJhbXMpCi0gICAgewotICAgICAgbV9wYXJhbXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgfQotCi0gICAgbV9wYXJhbXMucHV0KG5hbWUsIHZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBwYXJhbWV0ZXIgdGhhdCB3YXMgZXhwbGljaXRseSBzZXQgd2l0aCBzZXRQYXJhbWV0ZXIKLSAgICogb3Igc2V0UGFyYW1ldGVycy4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgcmV0dXJuIGEgZGVmYXVsdCBwYXJhbWV0ZXIgdmFsdWUsIHdoaWNoCi0gICAqIGNhbm5vdCBiZSBkZXRlcm1pbmVkIHVudGlsIHRoZSBub2RlIGNvbnRleHQgaXMgZXZhbHVhdGVkIGR1cmluZwotICAgKiB0aGUgdHJhbnNmb3JtYXRpb24gcHJvY2Vzcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgcGFyYW1ldGVyLgotICAgKiBAcmV0dXJuIEEgcGFyYW1ldGVyIHRoYXQgaGFzIGJlZW4gc2V0IHdpdGggc2V0UGFyYW1ldGVyLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fcGFyYW1zKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICByZXR1cm4gbV9wYXJhbXMuZ2V0KG5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENsZWFyIGFsbCBwYXJhbWV0ZXJzIHNldCB3aXRoIHNldFBhcmFtZXRlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNsZWFyUGFyYW1ldGVycygpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fcGFyYW1zKQotICAgICAgcmV0dXJuOwotCi0gICAgbV9wYXJhbXMuY2xlYXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlc29sdmUgVVJJcyB1c2VkIGluCi0gICAqIGRvY3VtZW50KCkuCi0gICAqCi0gICAqIDxwPklmIHRoZSByZXNvbHZlciBhcmd1bWVudCBpcyBudWxsLCB0aGUgVVJJUmVzb2x2ZXIgdmFsdWUgd2lsbAotICAgKiBiZSBjbGVhcmVkLCBhbmQgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2lsbCBiZSB1c2VkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHJlc29sdmVyIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKQotICB7Ci0gICAgbV9VUklSZXNvbHZlciA9IHJlc29sdmVyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogZG9jdW1lbnQoKSwgZXRjLgotICAgKgotICAgKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpCi0gIHsKLSAgICByZXR1cm4gbV9VUklSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uICBUaGVzZQotICAgKiBwcm9wZXJ0aWVzIHdpbGwgb3ZlcnJpZGUgcHJvcGVydGllcyBzZXQgaW4gdGhlIFRlbXBsYXRlcwotICAgKiB3aXRoIHhzbDpvdXRwdXQuCi0gICAqCi0gICAqIDxwPklmIGFyZ3VtZW50IHRvIHRoaXMgZnVuY3Rpb24gaXMgbnVsbCwgYW55IHByb3BlcnRpZXMKLSAgICogcHJldmlvdXNseSBzZXQgYXJlIHJlbW92ZWQsIGFuZCB0aGUgdmFsdWUgd2lsbCByZXZlcnQgdG8gdGhlIHZhbHVlCi0gICAqIGRlZmluZWQgaW4gdGhlIHRlbXBsYXRlcyBvYmplY3QuPC9wPgotICAgKgotICAgKiA8cD5QYXNzIGEgcXVhbGlmaWVkIHByb3BlcnR5IGtleSBuYW1lIGFzIGEgdHdvLXBhcnQgc3RyaW5nLCB0aGUgbmFtZXNwYWNlIFVSSQotICAgKiBlbmNsb3NlZCBpbiBjdXJseSBicmFjZXMgKHt9KSwgZm9sbG93ZWQgYnkgdGhlIGxvY2FsIG5hbWUuIElmIHRoZQotICAgKiBuYW1lIGhhcyBhIG51bGwgVVJMLCB0aGUgU3RyaW5nIG9ubHkgY29udGFpbiB0aGUgbG9jYWwgbmFtZS4gQW4KLSAgICogYXBwbGljYXRpb24gY2FuIHNhZmVseSBjaGVjayBmb3IgYSBub24tbnVsbCBVUkkgYnkgdGVzdGluZyB0byBzZWUgaWYgdGhlIGZpcnN0Ci0gICAqIGNoYXJhY3RlciBvZiB0aGUgbmFtZSBpcyBhICd7JyBjaGFyYWN0ZXIuPC9wPgotICAgKiA8cD5Gb3IgZXhhbXBsZSwgaWYgYSBVUkkgYW5kIGxvY2FsIG5hbWUgd2VyZSBvYnRhaW5lZCBmcm9tIGFuIGVsZW1lbnQKLSAgICogZGVmaW5lZCB3aXRoICZsdDt4eXo6Zm9vIHhtbG5zOnh5ej0iaHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWwiLyZndDssCi0gICAqIHRoZW4gdGhlIHF1YWxpZmllZCBuYW1lIHdvdWxkIGJlICJ7aHR0cDovL3h5ei5mb28uY29tL3lhZGEvYmF6Lmh0bWx9Zm9vIi4gTm90ZSB0aGF0Ci0gICAqIG5vIHByZWZpeCBpcyB1c2VkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG9mb3JtYXQgQSBzZXQgb2Ygb3V0cHV0IHByb3BlcnRpZXMgdGhhdCB3aWxsIGJlCi0gICAqIHVzZWQgdG8gb3ZlcnJpZGUgYW55IG9mIHRoZSBzYW1lIHByb3BlcnRpZXMgaW4gYWZmZWN0Ci0gICAqIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzCi0gICAqIEBzZWUgamF2YS51dGlsLlByb3BlcnRpZXMKLSAgICoKLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBhcmd1bWVudCBrZXlzIGFyZSBub3QKLSAgICogcmVjb2duaXplZCBhbmQgYXJlIG5vdCBuYW1lc3BhY2UgcXVhbGlmaWVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0UHJvcGVydGllcyhQcm9wZXJ0aWVzIG9mb3JtYXQpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBvZm9ybWF0KQotICAgIHsKLQotICAgICAgLy8gU2VlIGlmIGFuICpleHBsaWNpdCogbWV0aG9kIHdhcyBzZXQuCi0gICAgICBTdHJpbmcgbWV0aG9kID0gKFN0cmluZykgb2Zvcm1hdC5nZXQoT3V0cHV0S2V5cy5NRVRIT0QpOwotCi0gICAgICBpZiAobnVsbCAhPSBtZXRob2QpCi0gICAgICAgIG1fb3V0cHV0Rm9ybWF0ID0gbmV3IE91dHB1dFByb3BlcnRpZXMobWV0aG9kKTsKLSAgICAgIGVsc2UKLSAgICAgICAgbV9vdXRwdXRGb3JtYXQgPSBuZXcgT3V0cHV0UHJvcGVydGllcygpOwotICAgIH0KLQotICAgIGlmIChudWxsICE9IG9mb3JtYXQpCi0gICAgewotICAgICAgbV9vdXRwdXRGb3JtYXQuY29weUZyb20ob2Zvcm1hdCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNvcHkgb2YgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIDxwPlRoZSBwcm9wZXJ0aWVzIHJldHVybmVkIHNob3VsZCBjb250YWluIHByb3BlcnRpZXMgc2V0IGJ5IHRoZSB1c2VyLAotICAgKiBhbmQgcHJvcGVydGllcyBzZXQgYnkgdGhlIHN0eWxlc2hlZXQsIGFuZCB0aGVzZSBwcm9wZXJ0aWVzCi0gICAqIGFyZSAiZGVmYXVsdGVkIiBieSBkZWZhdWx0IHByb3BlcnRpZXMgc3BlY2lmaWVkIGJ5IDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjb3V0cHV0Ij5zZWN0aW9uIDE2IG9mIHRoZQotICAgKiBYU0wgVHJhbnNmb3JtYXRpb25zIChYU0xUKSBXM0MgUmVjb21tZW5kYXRpb248L2E+LiAgVGhlIHByb3BlcnRpZXMgdGhhdAotICAgKiB3ZXJlIHNwZWNpZmljYWxseSBzZXQgYnkgdGhlIHVzZXIgb3IgdGhlIHN0eWxlc2hlZXQgc2hvdWxkIGJlIGluIHRoZSBiYXNlCi0gICAqIFByb3BlcnRpZXMgbGlzdCwgd2hpbGUgdGhlIFhTTFQgZGVmYXVsdCBwcm9wZXJ0aWVzIHRoYXQgd2VyZSBub3QKLSAgICogc3BlY2lmaWNhbGx5IHNldCBzaG91bGQgYmUgdGhlIGRlZmF1bHQgUHJvcGVydGllcyBsaXN0LiAgVGh1cywKLSAgICogZ2V0T3V0cHV0UHJvcGVydGllcygpLmdldFByb3BlcnR5KFN0cmluZyBrZXkpIHdpbGwgb2J0YWluIGFueQotICAgKiBwcm9wZXJ0eSBpbiB0aGF0IHdhcyBzZXQgYnkge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0eX0sCi0gICAqIHtAbGluayAjc2V0T3V0cHV0UHJvcGVydGllc30sIGluIHRoZSBzdHlsZXNoZWV0LCA8ZW0+b3I8L2VtPiB0aGUgZGVmYXVsdAotICAgKiBwcm9wZXJ0aWVzLCB3aGlsZQotICAgKiBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkuZ2V0KFN0cmluZyBrZXkpIHdpbGwgb25seSByZXRyaWV2ZSBwcm9wZXJ0aWVzCi0gICAqIHRoYXQgd2VyZSBleHBsaWNpdGx5IHNldCBieSB7QGxpbmsgI3NldE91dHB1dFByb3BlcnR5fSwKLSAgICoge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0aWVzfSwgb3IgaW4gdGhlIHN0eWxlc2hlZXQuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgbXV0YXRpb24gb2YgdGhlIFByb3BlcnRpZXMgb2JqZWN0IHJldHVybmVkIHdpbGwgbm90Ci0gICAqIGVmZmVjdCB0aGUgcHJvcGVydGllcyB0aGF0IHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250YWlucy48L3A+Ci0gICAqCi0gICAqIDxwPklmIGFueSBvZiB0aGUgYXJndW1lbnQga2V5cyBhcmUgbm90IHJlY29nbml6ZWQgYW5kIGFyZSBub3QKLSAgICogbmFtZXNwYWNlIHF1YWxpZmllZCwgdGhlIHByb3BlcnR5IHdpbGwgYmUgaWdub3JlZC4gIEluIG90aGVyIHdvcmRzIHRoZQotICAgKiBiZWhhdmlvdXIgaXMgbm90IG9ydGhvZ29uYWwgd2l0aCBzZXRPdXRwdXRQcm9wZXJ0aWVzLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBBIGNvcHkgb2YgdGhlIHNldCBvZiBvdXRwdXQgcHJvcGVydGllcyBpbiBlZmZlY3QKLSAgICogZm9yIHRoZSBuZXh0IHRyYW5zZm9ybWF0aW9uLgotICAgKgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKiBAc2VlIGphdmEudXRpbC5Qcm9wZXJ0aWVzCi0gICAqLwotICBwdWJsaWMgUHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkKLSAgewotICAgIHJldHVybiAoUHJvcGVydGllcykgbV9vdXRwdXRGb3JtYXQuZ2V0UHJvcGVydGllcygpLmNsb25lKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGFuIG91dHB1dCBwcm9wZXJ0eSB0aGF0IHdpbGwgYmUgaW4gZWZmZWN0IGZvciB0aGUKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIDxwPlBhc3MgYSBxdWFsaWZpZWQgcHJvcGVydHkgbmFtZSBhcyBhIHR3by1wYXJ0IHN0cmluZywgdGhlIG5hbWVzcGFjZSBVUkkKLSAgICogZW5jbG9zZWQgaW4gY3VybHkgYnJhY2VzICh7fSksIGZvbGxvd2VkIGJ5IHRoZSBsb2NhbCBuYW1lLiBJZiB0aGUKLSAgICogbmFtZSBoYXMgYSBudWxsIFVSTCwgdGhlIFN0cmluZyBvbmx5IGNvbnRhaW4gdGhlIGxvY2FsIG5hbWUuIEFuCi0gICAqIGFwcGxpY2F0aW9uIGNhbiBzYWZlbHkgY2hlY2sgZm9yIGEgbm9uLW51bGwgVVJJIGJ5IHRlc3RpbmcgdG8gc2VlIGlmIHRoZSBmaXJzdAotICAgKiBjaGFyYWN0ZXIgb2YgdGhlIG5hbWUgaXMgYSAneycgY2hhcmFjdGVyLjwvcD4KLSAgICogPHA+Rm9yIGV4YW1wbGUsIGlmIGEgVVJJIGFuZCBsb2NhbCBuYW1lIHdlcmUgb2J0YWluZWQgZnJvbSBhbiBlbGVtZW50Ci0gICAqIGRlZmluZWQgd2l0aCAmbHQ7eHl6OmZvbyB4bWxuczp4eXo9Imh0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sIi8mZ3Q7LAotICAgKiB0aGVuIHRoZSBxdWFsaWZpZWQgbmFtZSB3b3VsZCBiZSAie2h0dHA6Ly94eXouZm9vLmNvbS95YWRhL2Jhei5odG1sfWZvbyIuIE5vdGUgdGhhdAotICAgKiBubyBwcmVmaXggaXMgdXNlZC48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBQcm9wZXJ0aWVzIG9iamVjdCB0aGF0IHdhcyBwYXNzZWQgdG8ge0BsaW5rICNzZXRPdXRwdXRQcm9wZXJ0aWVzfSB3b24ndAotICAgKiBiZSBlZmZlY3RlZCBieSBjYWxsaW5nIHRoaXMgbWV0aG9kLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQSBub24tbnVsbCBTdHJpbmcgdGhhdCBzcGVjaWZpZXMgYW4gb3V0cHV0Ci0gICAqIHByb3BlcnR5IG5hbWUsIHdoaWNoIG1heSBiZSBuYW1lc3BhY2UgcXVhbGlmaWVkLgotICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5vbi1udWxsIHN0cmluZyB2YWx1ZSBvZiB0aGUgb3V0cHV0IHByb3BlcnR5LgotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkgaXMgbm90IHN1cHBvcnRlZCwgYW5kIGlzCi0gICAqIG5vdCBxdWFsaWZpZWQgd2l0aCBhIG5hbWVzcGFjZS4KLSAgICoKLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE91dHB1dFByb3BlcnR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoIW1fb3V0cHV0Rm9ybWF0LmlzTGVnYWxQcm9wZXJ0eUtleShuYW1lKSkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELCBuZXcgT2JqZWN0W117bmFtZX0pKTsgLy8ib3V0cHV0IHByb3BlcnR5IG5vdCByZWNvZ25pemVkOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBuYW1lKTsKLQotICAgIG1fb3V0cHV0Rm9ybWF0LnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gb3V0cHV0IHByb3BlcnR5IHRoYXQgaXMgaW4gZWZmZWN0IGZvciB0aGUKLSAgICogdHJhbnNmb3JtYXRpb24uICBUaGUgcHJvcGVydHkgc3BlY2lmaWVkIG1heSBiZSBhIHByb3BlcnR5Ci0gICAqIHRoYXQgd2FzIHNldCB3aXRoIHNldE91dHB1dFByb3BlcnR5LCBvciBpdCBtYXkgYmUgYQotICAgKiBwcm9wZXJ0eSBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEEgbm9uLW51bGwgU3RyaW5nIHRoYXQgc3BlY2lmaWVzIGFuIG91dHB1dAotICAgKiBwcm9wZXJ0eSBuYW1lLCB3aGljaCBtYXkgYmUgbmFtZXNwYWNlIHF1YWxpZmllZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBvdXRwdXQgcHJvcGVydHksIG9yIG51bGwKLSAgICogaWYgbm8gcHJvcGVydHkgd2FzIGZvdW5kLgotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkgaXMgbm90IHN1cHBvcnRlZC4KLSAgICoKLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLk91dHB1dEtleXMKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHZhbHVlID0gbnVsbDsKLSAgICBPdXRwdXRQcm9wZXJ0aWVzIHByb3BzID0gbV9vdXRwdXRGb3JtYXQ7Ci0KLSAgICB2YWx1ZSA9IHByb3BzLmdldFByb3BlcnR5KG5hbWUpOwotCi0gICAgaWYgKG51bGwgPT0gdmFsdWUpCi0gICAgewotICAgICAgaWYgKCFwcm9wcy5pc0xlZ2FsUHJvcGVydHlLZXkobmFtZSkpCi0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELCBuZXcgT2JqZWN0W117bmFtZX0pKTsgLy8ib3V0cHV0IHByb3BlcnR5IG5vdCByZWNvZ25pemVkOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyArIG5hbWUpOwotICAgIH0KLQotICAgIHJldHVybiB2YWx1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGxpc3RlbmVyIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbGlzdGVuZXIgVGhlIG5ldyBlcnJvciBsaXN0ZW5lci4KLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgbGlzdGVuZXIgaXMgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gIHsKLSAgICBtX2Vycm9yTGlzdGVuZXIgPSBsaXN0ZW5lcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIgaW4gZWZmZWN0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgd2hpY2ggc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkKLSAgewotICAgIHJldHVybiBtX2Vycm9yTGlzdGVuZXI7Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIERUREhhbmRsZXIgaW50ZXJmYWNlLgotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vdGF0aW9uIGRlY2xhcmF0aW9uLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyBpZiB0aGV5IHdpc2ggdG8ga2VlcCB0cmFjayBvZiB0aGUgbm90YXRpb25zCi0gICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbm90YXRpb24gbmFtZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBub3RhdGlvbiBwdWJsaWMgaWRlbnRpZmllciwgb3IgbnVsbCBpZiBub3QKLSAgICogICAgICAgICAgICAgICAgIGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBub3RhdGlvbiBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciNub3RhdGlvbkRlY2wKLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKG51bGwgIT0gbV9yZXN1bHREVERIYW5kbGVyKQotICAgICAgbV9yZXN1bHREVERIYW5kbGVyLm5vdGF0aW9uRGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8ga2VlcCB0cmFjayBvZiB0aGUgdW5wYXJzZWQgZW50aXRpZXMKLSAgICogZGVjbGFyZWQgaW4gYSBkb2N1bWVudC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbnRpdHkgbmFtZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBlbnRpdHkgcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm90Ci0gICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgZW50aXR5IHN5c3RlbSBpZGVudGlmaWVyLgotICAgKiBAcGFyYW0gbm90YXRpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIG5vdGF0aW9uLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKAotICAgICAgICAgIFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkKLSAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9yZXN1bHREVERIYW5kbGVyKQotICAgICAgbV9yZXN1bHREVERIYW5kbGVyLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGF0aW9uTmFtZSk7Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVjZWl2ZSBhIExvY2F0b3Igb2JqZWN0IGZvciBkb2N1bWVudCBldmVudHMuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBzdG9yZSB0aGUgbG9jYXRvciBmb3IgdXNlCi0gICAqIHdpdGggb3RoZXIgZG9jdW1lbnQgZXZlbnRzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0b3IgQSBsb2NhdG9yIGZvciBhbGwgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgPT0gbV9yZXN1bHRDb250ZW50SGFuZGxlcikKLSAgICAgICAgY3JlYXRlUmVzdWx0Q29udGVudEhhbmRsZXIobV9yZXN1bHQpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0KLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihsb2NhdG9yKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBiZWdpbm5pbmcKLSAgICogb2YgYSBkb2N1bWVudCAoc3VjaCBhcyBhbGxvY2F0aW5nIHRoZSByb290IG5vZGUgb2YgYSB0cmVlIG9yCi0gICAqIGNyZWF0aW5nIGFuIG91dHB1dCBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQKLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fcmVzdWx0Q29udGVudEhhbmRsZXIpCi0gICAgICAgIGNyZWF0ZVJlc3VsdENvbnRlbnRIYW5kbGVyKG1fcmVzdWx0KTsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24odGUuZ2V0TWVzc2FnZSgpLCB0ZSk7Ci0gICAgfQotCi0gICAgLy8gUmVzZXQgZm9yIG11bHRpcGxlIHRyYW5zZm9ybXMgd2l0aCB0aGlzIHRyYW5zZm9ybWVyLgotICAgIG1fZmx1c2hlZFN0YXJ0RG9jID0gZmFsc2U7Ci0gICAgbV9mb3VuZEZpcnN0RWxlbWVudCA9IGZhbHNlOwotICB9Ci0gIAotICBib29sZWFuIG1fZmx1c2hlZFN0YXJ0RG9jID0gZmFsc2U7Ci0gIAotICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBmbHVzaFN0YXJ0RG9jKCkKLSAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoIW1fZmx1c2hlZFN0YXJ0RG9jKQotICAgIHsKLSAgICAgIG1fcmVzdWx0Q29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgbV9mbHVzaGVkU3RhcnREb2MgPSB0cnVlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBlbmQKLSAgICogb2YgYSBkb2N1bWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBvciBjbG9zaW5nIGFuIG91dHB1dAotICAgKiBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50Ci0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGEgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKLSAgICogZWFjaCBOYW1lc3BhY2UgcHJlZml4IHNjb3BlIChzdWNoIGFzIHN0b3JpbmcgdGhlIHByZWZpeCBtYXBwaW5nKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIE5hbWVzcGFjZSBwcmVmaXggYmVpbmcgZGVjbGFyZWQuCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkgbWFwcGVkIHRvIHRoZSBwcmVmaXguCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0UHJlZml4TWFwcGluZwotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgZmx1c2hTdGFydERvYygpOwotICAgIG1fcmVzdWx0Q29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGEgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgZW5kIG9mCi0gICAqIGVhY2ggcHJlZml4IG1hcHBpbmcuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRQcmVmaXhNYXBwaW5nCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYW4gZWxlbWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBzdGFydCBvZgotICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgYWxsb2NhdGluZyBhIG5ldyB0cmVlIG5vZGUgb3Igd3JpdGluZwotICAgKiBvdXRwdXQgdG8gYSBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIHNwZWNpZmllZCBvciBkZWZhdWx0ZWQgYXR0cmlidXRlcy4KLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICghbV9mb3VuZEZpcnN0RWxlbWVudCAmJiBudWxsICE9IG1fc2VyaWFsaXplcikKLSAgICB7Ci0gICAgICBtX2ZvdW5kRmlyc3RFbGVtZW50ID0gdHJ1ZTsKLQotICAgICAgU2VyaWFsaXplciBuZXdTZXJpYWxpemVyOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgbmV3U2VyaWFsaXplciA9IFNlcmlhbGl6ZXJTd2l0Y2hlci5zd2l0Y2hTZXJpYWxpemVySWZIVE1MKHVyaSwKLSAgICAgICAgICAgICAgICBsb2NhbE5hbWUsIG1fb3V0cHV0Rm9ybWF0LmdldFByb3BlcnRpZXMoKSwgbV9zZXJpYWxpemVyKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbih0ZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChuZXdTZXJpYWxpemVyICE9IG1fc2VyaWFsaXplcikKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyID0gbmV3U2VyaWFsaXplci5hc0NvbnRlbnRIYW5kbGVyKCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgIC8vIHdoeT8KLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oaW9lKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChtX3Jlc3VsdENvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgRFRESGFuZGxlcikKLSAgICAgICAgICBtX3Jlc3VsdERUREhhbmRsZXIgPSAoRFRESGFuZGxlcikgbV9yZXN1bHRDb250ZW50SGFuZGxlcjsKLQotICAgICAgICBpZiAobV9yZXN1bHRDb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgICAgIG1fcmVzdWx0TGV4aWNhbEhhbmRsZXIgPSAoTGV4aWNhbEhhbmRsZXIpIG1fcmVzdWx0Q29udGVudEhhbmRsZXI7Ci0KLSAgICAgICAgbV9zZXJpYWxpemVyID0gbmV3U2VyaWFsaXplcjsKLSAgICAgIH0KLSAgICB9Ci0gICAgZmx1c2hTdGFydERvYygpOwotICAgIG1fcmVzdWx0Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cmlidXRlcyk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgotICAgKiBlYWNoIGVsZW1lbnQgKHN1Y2ggYXMgZmluYWxpc2luZyBhIHRyZWUgbm9kZSBvciB3cml0aW5nCi0gICAqIG91dHB1dCB0byBhIGZpbGUpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiB0aGUKLSAgICogICAgICAgIGVsZW1lbnQgaGFzIG5vIE5hbWVzcGFjZSBVUkkgb3IgaWYgTmFtZXNwYWNlCi0gICAqICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgKHdpdGhvdXQgcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgTmFtZXNwYWNlIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nCi0gICAqICAgICAgICBwZXJmb3JtZWQuCi0gICAqIEBwYXJhbSBxTmFtZSBUaGUgcXVhbGlmaWVkIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgc3BlY2lmaWVkIG9yIGRlZmF1bHRlZCBhdHRyaWJ1dGVzLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLmVuZEVsZW1lbnQodXJpLCBsb2NhbE5hbWUsIHFOYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YSBpbnNpZGUgYW4gZWxlbWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBjaGFyYWN0ZXIgZGF0YQotICAgKiAoc3VjaCBhcyBhZGRpbmcgdGhlIGRhdGEgdG8gYSBub2RlIG9yIGJ1ZmZlciwgb3IgcHJpbnRpbmcgaXQgdG8KLSAgICogYSBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycy4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUKLSAgICogICAgICAgICAgICAgICBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaCBjaHVuayBvZiBpZ25vcmFibGUKLSAgICogd2hpdGVzcGFjZSAoc3VjaCBhcyBhZGRpbmcgZGF0YSB0byBhIG5vZGUgb3IgYnVmZmVyLCBvciBwcmludGluZwotICAgKiBpdCB0byBhIGZpbGUpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIG1fcmVzdWx0Q29udGVudEhhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2gKLSAgICogcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgc3VjaCBhcyBzZXR0aW5nIHN0YXR1cyB2YXJpYWJsZXMgb3IKLSAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICAgICAgIG5vbmUgaXMgc3VwcGxpZWQuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3Byb2Nlc3NpbmdJbnN0cnVjdGlvbgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBmb3IgZWFjaAotICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBzdWNoIGFzIHNldHRpbmcgc3RhdHVzIHZhcmlhYmxlcyBvcgotICAgKiBpbnZva2luZyBvdGhlciBtZXRob2RzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHNraXBwZWQgZW50aXR5LgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBtX3Jlc3VsdENvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkobmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBEVEQgZGVjbGFyYXRpb25zLCBpZiBhbnkuCi0gICAqCi0gICAqIDxwPkFueSBkZWNsYXJhdGlvbnMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gdGhlIGludGVybmFsIHN1YnNldAotICAgKiB1bmxlc3Mgb3RoZXJ3aXNlIGluZGljYXRlZCBieSBhIHtAbGluayAjc3RhcnRFbnRpdHkgc3RhcnRFbnRpdHl9Ci0gICAqIGV2ZW50LjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHRoZSBzdGFydC9lbmREVEQgZXZlbnRzIHdpbGwgYXBwZWFyIHdpdGhpbgotICAgKiB0aGUgc3RhcnQvZW5kRG9jdW1lbnQgZXZlbnRzIGZyb20gQ29udGVudEhhbmRsZXIgYW5kCi0gICAqIGJlZm9yZSB0aGUgZmlyc3Qgc3RhcnRFbGVtZW50IGV2ZW50LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGRvY3VtZW50IHR5cGUgbmFtZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBkZWNsYXJlZCBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlCi0gICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUKLSAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4KLSAgICogICAgICAgICAgICBleGNlcHRpb24uCi0gICAqIEBzZWUgI2VuZERURAotICAgKiBAc2VlICNzdGFydEVudGl0eQotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlci5zdGFydERURChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgZW5kIG9mIERURCBkZWNsYXJhdGlvbnMuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNzdGFydERURAotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKG51bGwgIT0gbV9yZXN1bHRMZXhpY2FsSGFuZGxlcikKLSAgICAgIG1fcmVzdWx0TGV4aWNhbEhhbmRsZXIuZW5kRFREKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBiZWdpbm5pbmcgb2YgYW4gZW50aXR5IGluIGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPjxzdHJvbmc+Tk9URTo8L2VudGl0eT4gZW50aXR5IHJlZmVyZW5jZXMgaW4gYXR0cmlidXRlCi0gICAqIHZhbHVlcyAtLSBhbmQgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGRvY3VtZW50IGVudGl0eSAtLQotICAgKiBhcmUgbmV2ZXIgcmVwb3J0ZWQuPC9wPgotICAgKgotICAgKiA8cD5UaGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhcmUgcmVwb3J0ZWQKLSAgICogdXNpbmcgdGhlIHBzZXVkby1uYW1lICJbZHRkXSIuICBBbGwgb3RoZXIgZXZlbnRzIG11c3QgYmUKLSAgICogcHJvcGVybHkgbmVzdGVkIHdpdGhpbiBzdGFydC9lbmQgZW50aXR5IGV2ZW50cy48L3A+Ci0gICAqCi0gICAqIDxwPk5vdGUgdGhhdCBza2lwcGVkIGVudGl0aWVzIHdpbGwgYmUgcmVwb3J0ZWQgdGhyb3VnaCB0aGUKLSAgICoge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3NraXBwZWRFbnRpdHkgc2tpcHBlZEVudGl0eX0KLSAgICogZXZlbnQsIHdoaWNoIGlzIHBhcnQgb2YgdGhlIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kRW50aXR5Ci0gICAqIEBzZWUgb3JnLnhtbC5zYXguZXh0LkRlY2xIYW5kbGVyI2ludGVybmFsRW50aXR5RGVjbAotICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNleHRlcm5hbEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlci5zdGFydEVudGl0eShuYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgdGhhdCBpcyBlbmRpbmcuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNzdGFydEVudGl0eQotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIDxwPlRoZSBjb250ZW50cyBvZiB0aGUgQ0RBVEEgc2VjdGlvbiB3aWxsIGJlIHJlcG9ydGVkIHRocm91Z2gKLSAgICogdGhlIHJlZ3VsYXIge0BsaW5rIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2NoYXJhY3RlcnMKLSAgICogY2hhcmFjdGVyc30gZXZlbnQuPC9wPgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZW5kQ0RBVEEKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlci5zdGFydENEQVRBKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBlbmQgb2YgYSBDREFUQSBzZWN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjc3RhcnRDREFUQQotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kQ0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlci5lbmRDREFUQSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPlRoaXMgY2FsbGJhY2sgd2lsbCBiZSB1c2VkIGZvciBjb21tZW50cyBpbnNpZGUgb3Igb3V0c2lkZSB0aGUKLSAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKLSAgICogc3Vic2V0IChpZiByZWFkKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBBbiBhcnJheSBob2xkaW5nIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBjb21tZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlIGFycmF5LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGZsdXNoU3RhcnREb2MoKTsKLSAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdExleGljYWxIYW5kbGVyKQotICAgICAgbV9yZXN1bHRMZXhpY2FsSGFuZGxlci5jb21tZW50KGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgfQotICAKLSAgLy8gSW1wbGVtZW50IERlY2xIYW5kbGVyCi0gIAotICAvKioKLSAgICAgKiBSZXBvcnQgYW4gZWxlbWVudCB0eXBlIGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+VGhlIGNvbnRlbnQgbW9kZWwgd2lsbCBjb25zaXN0IG9mIHRoZSBzdHJpbmcgIkVNUFRZIiwgdGhlCi0gICAgICogc3RyaW5nICJBTlkiLCBvciBhIHBhcmVudGhlc2lzZWQgZ3JvdXAsIG9wdGlvbmFsbHkgZm9sbG93ZWQKLSAgICAgKiBieSBhbiBvY2N1cnJlbmNlIGluZGljYXRvci4gIFRoZSBtb2RlbCB3aWxsIGJlIG5vcm1hbGl6ZWQgc28KLSAgICAgKiB0aGF0IGFsbCB3aGl0ZXNwYWNlIGlzIHJlbW92ZWQsYW5kIHdpbGwgaW5jbHVkZSB0aGUgZW5jbG9zaW5nCi0gICAgICogcGFyZW50aGVzZXMuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgdHlwZSBuYW1lLgotICAgICAqIEBwYXJhbSBtb2RlbCBUaGUgY29udGVudCBtb2RlbCBhcyBhIG5vcm1hbGl6ZWQgc3RyaW5nLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVsZW1lbnREZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIG1vZGVsKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gbV9yZXN1bHREZWNsSGFuZGxlcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9yZXN1bHREZWNsSGFuZGxlci5lbGVtZW50RGVjbChuYW1lLCBtb2RlbCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgYW4gYXR0cmlidXRlIHR5cGUgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgYW4gYXR0cmlidXRlIHdpbGwKLSAgICAgKiBiZSByZXBvcnRlZC4gIFRoZSB0eXBlIHdpbGwgYmUgb25lIG9mIHRoZSBzdHJpbmdzICJDREFUQSIsCi0gICAgICogIklEIiwgIklEUkVGIiwgIklEUkVGUyIsICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgIkVOVElUWSIsCi0gICAgICogIkVOVElUSUVTIiwgb3IgIk5PVEFUSU9OIiwgb3IgYSBwYXJlbnRoZXNpemVkIHRva2VuIGdyb3VwIHdpdGggCi0gICAgICogdGhlIHNlcGFyYXRvciAifCIgYW5kIGFsbCB3aGl0ZXNwYWNlIHJlbW92ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQuCi0gICAgICogQHBhcmFtIGFOYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUuCi0gICAgICogQHBhcmFtIHR5cGUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgdHlwZS4KLSAgICAgKiBAcGFyYW0gdmFsdWVEZWZhdWx0IEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIGRlZmF1bHQKLSAgICAgKiAgICAgICAgKCIjSU1QTElFRCIsICIjUkVRVUlSRUQiLCBvciAiI0ZJWEVEIikgb3IgbnVsbCBpZgotICAgICAqICAgICAgICBub25lIG9mIHRoZXNlIGFwcGxpZXMuCi0gICAgICogQHBhcmFtIHZhbHVlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlJ3MgZGVmYXVsdCB2YWx1ZSwKLSAgICAgKiAgICAgICAgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgICAqIEBleGNlcHRpb24gU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2wgKFN0cmluZyBlTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlRGVmYXVsdCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgICB7Ci0gICAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdERlY2xIYW5kbGVyKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3Jlc3VsdERlY2xIYW5kbGVyLmF0dHJpYnV0ZURlY2woZU5hbWUsIGFOYW1lLCB0eXBlLCB2YWx1ZURlZmF1bHQsIHZhbHVlKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJlcG9ydCBhbiBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICoKLSAgICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgZWFjaCBlbnRpdHkKLSAgICAgKiB3aWxsIGJlIHJlcG9ydGVkLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBsYWNlbWVudCB0ZXh0IG9mIHRoZSBlbnRpdHkuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fcmVzdWx0RGVjbEhhbmRsZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcmVzdWx0RGVjbEhhbmRsZXIuaW50ZXJuYWxFbnRpdHlEZWNsKG5hbWUsIHZhbHVlKTsgCi0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXBvcnQgYSBwYXJzZWQgZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgICAqCi0gICAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGVhY2ggZW50aXR5Ci0gICAgICogd2lsbCBiZSByZXBvcnRlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgb2YgdGhlIGVudGl0eSwgb3IKLSAgICAgKiAgICAgICAgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAgICogQGV4Y2VwdGlvbiBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAgICogQHNlZSAjaW50ZXJuYWxFbnRpdHlEZWNsCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fcmVzdWx0RGVjbEhhbmRsZXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcmVzdWx0RGVjbEhhbmRsZXIuZXh0ZXJuYWxFbnRpdHlEZWNsKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gICAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgaXMgbnVsbCB1bmxlc3Mgd2Ugb3duIHRoZSBzdHJlYW0uCi0gICAqLwotICBwcml2YXRlIGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbSBtX291dHB1dFN0cmVhbSA9IG51bGw7Ci0KLSAgLyoqIFRoZSBjb250ZW50IGhhbmRsZXIgd2hlcmUgcmVzdWx0IGV2ZW50cyB3aWxsIGJlIHNlbnQuICovCi0gIHByaXZhdGUgQ29udGVudEhhbmRsZXIgbV9yZXN1bHRDb250ZW50SGFuZGxlcjsKLQotICAvKiogVGhlIGxleGljYWwgaGFuZGxlciB3aGVyZSByZXN1bHQgZXZlbnRzIHdpbGwgYmUgc2VudC4gKi8KLSAgcHJpdmF0ZSBMZXhpY2FsSGFuZGxlciBtX3Jlc3VsdExleGljYWxIYW5kbGVyOwotCi0gIC8qKiBUaGUgRFREIGhhbmRsZXIgd2hlcmUgcmVzdWx0IGV2ZW50cyB3aWxsIGJlIHNlbnQuICovCi0gIHByaXZhdGUgRFRESGFuZGxlciBtX3Jlc3VsdERUREhhbmRsZXI7Ci0gIAotICAvKiogVGhlIERlY2wgaGFuZGxlciB3aGVyZSByZXN1bHQgZXZlbnRzIHdpbGwgYmUgc2VudC4gKi8KLSAgcHJpdmF0ZSBEZWNsSGFuZGxlciBtX3Jlc3VsdERlY2xIYW5kbGVyOwotCi0gIC8qKiBUaGUgU2VyaWFsaXplciwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgbnVsbC4gKi8KLSAgcHJpdmF0ZSBTZXJpYWxpemVyIG1fc2VyaWFsaXplcjsKLQotICAvKiogVGhlIFJlc3VsdCBvYmplY3QuICovCi0gIHByaXZhdGUgUmVzdWx0IG1fcmVzdWx0OwotCi0gIC8qKgotICAgKiBUaGUgc3lzdGVtIElELCB3aGljaCBpcyB1bnVzZWQsIGJ1dCBtdXN0IGJlIHJldHVybmVkIHRvIGZ1bGxmaWxsIHRoZQotICAgKiAgVHJhbnNmb3JtZXJIYW5kbGVyIGludGVyZmFjZS4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc3lzdGVtSUQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBwYXJhbWV0ZXJzLCB3aGljaCBpcyB1bnVzZWQsIGJ1dCBtdXN0IGJlIHJldHVybmVkIHRvIGZ1bGxmaWxsIHRoZQotICAgKiAgVHJhbnNmb3JtZXIgaW50ZXJmYWNlLgotICAgKi8KLSAgcHJpdmF0ZSBIYXNodGFibGUgbV9wYXJhbXM7Ci0KLSAgLyoqIFRoZSBlcnJvciBsaXN0ZW5lciBmb3IgVHJBWCBlcnJvcnMgYW5kIHdhcm5pbmdzLiAqLwotICBwcml2YXRlIEVycm9yTGlzdGVuZXIgbV9lcnJvckxpc3RlbmVyID0KLSAgICBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuRGVmYXVsdEVycm9ySGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBUaGUgVVJJUmVzb2x2ZXIsIHdoaWNoIGlzIHVudXNlZCwgYnV0IG11c3QgYmUgcmV0dXJuZWQgdG8gZnVsbGZpbGwgdGhlCi0gICAqICBUcmFuc2Zvcm1lckhhbmRsZXIgaW50ZXJmYWNlLgotICAgKi8KLSAgVVJJUmVzb2x2ZXIgbV9VUklSZXNvbHZlcjsKLQotICAvKiogVGhlIG91dHB1dCBwcm9wZXJ0aWVzLiAqLwotICBwcml2YXRlIE91dHB1dFByb3BlcnRpZXMgbV9vdXRwdXRGb3JtYXQ7Ci0KLSAgLyoqIEZsYWcgdG8gc2V0IGlmIHdlJ3ZlIGZvdW5kIHRoZSBmaXJzdCBlbGVtZW50LCBzbyB3ZSBjYW4gdGVsbCBpZiB3ZSBoYXZlIAotICAgKiAgdG8gY2hlY2sgdG8gc2VlIGlmIHdlIHNob3VsZCBjcmVhdGUgYW4gSFRNTCBzZXJpYWxpemVyLiAgICAgICovCi0gIGJvb2xlYW4gbV9mb3VuZEZpcnN0RWxlbWVudDsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyYW5zZm9ybWVySW1wbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJhbnNmb3JtZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA3ZmI4NTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvVHJhbnNmb3JtZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjYxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI7Ci0KLS8vIEphdmEgaW1wb3J0cwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247Ci0KLS8vIFhhbGFuIGltcG9ydHMKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1BdHRyaWJ1dGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0Q29tcG9zZWQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUZvckVhY2g7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUFwcGx5VGVtcGxhdGVzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1Vc2U7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtV2l0aFBhcmFtOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1Tb3J0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkFWVDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVmFyaWFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVBhcmFtOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1DYWxsVGVtcGxhdGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZXh0TGl0ZXJhbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5UZW1wbGF0ZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuWFVucmVzb2x2ZWRWYXJpYWJsZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhY2UuVHJhY2VNYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuWGFsYW5Qcm9wZXJ0aWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkRPTUJ1aWxkZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTm9kZVZlY3RvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Cb29sU3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuT2JqZWN0UG9vbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TQVhTb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFJUcmVlRnJhZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkFyZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQVBJOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguVmFyaWFibGVTdGFjazsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlNvdXJjZVRyZWVNYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuWFBhdGhQYXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkNvbnRleHROb2RlTGlzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci0KLS8vIFNlcmlhbGl6ZXIgSW1wb3J0cwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuTWV0aG9kOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1XU0ZpbHRlcjsKLQotLy8gV2UgaGF2ZSB0byBmaWd1cmUgb3V0IHdoYXQgdG8gZG8gYWJvdXQgdGhpcyBvbmUuCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5FeHBhbmRlZE5hbWVUYWJsZTsKLQotLy8gU0FYMiBJbXBvcnRzCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxGaWx0ZXJJbXBsOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci0KLS8vIFRSYVggSW1wb3J0cwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotCi0vLyBJbXBvcnRlZCBKQVZBIEFQSSBmb3IgWE1MIFBhcnNpbmcgMS4wIGNsYXNzZXMKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZQotICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJ9IGludGVyZmFjZSwgYW5kIGlzIHRoZSBjb3JlCi0gKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgdHJhbnNmb3JtYXRpb24gZXhlY3V0aW9uLjwvcD4KLSAqLwotcHVibGljIGNsYXNzIFRyYW5zZm9ybWVySW1wbCBleHRlbmRzIFRyYW5zZm9ybWVyCi0gICAgICAgIGltcGxlbWVudHMgUnVubmFibGUsIERUTVdTRmlsdGVyCi17Ci0KLSAgLy8gU3luY2ggb2JqZWN0IHRvIGdhdXJkIGFnYWluc3Qgc2V0dGluZyB2YWx1ZXMgZnJvbSB0aGUgVHJBWCBpbnRlcmZhY2UgCi0gIC8vIG9yIHJlZW50cnkgd2hpbGUgdGhlIHRyYW5zZm9ybSBpcyBnb2luZyBvbi4KLQotICAvKiogTkVFRFNET0MgRmllbGQgbV9yZWVudHJ5R3VhcmQgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBCb29sZWFuIG1fcmVlbnRyeUd1YXJkID0gbmV3IEJvb2xlYW4odHJ1ZSk7Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgbnVsbCB1bmxlc3Mgd2Ugb3duIHRoZSBzdHJlYW0uCi0gICAqLwotICBwcml2YXRlIGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbSBtX291dHB1dFN0cmVhbSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRydWUgaWYgdGhlIHBhcnNlciBldmVudHMgc2hvdWxkIGJlIG9uIHRoZSBtYWluIHRocmVhZCwKLSAgICogZmFsc2UgaWYgbm90LiAgRXhwZXJlbWVudGFsLiAgQ2FuIG5vdCBiZSBzZXQgcmlnaHQgbm93LgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fcGFyc2VyRXZlbnRzT25NYWluID0gdHJ1ZTsKLQotICAvKiogVGhlIHRocmVhZCB0aGF0IHRoZSB0cmFuc2Zvcm1lciBpcyBydW5uaW5nIG9uLiAqLwotICBwcml2YXRlIFRocmVhZCBtX3RyYW5zZm9ybVRocmVhZDsKLQotICAvKiogVGhlIGJhc2UgVVJMIG9mIHRoZSBzb3VyY2UgdHJlZS4gKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV91cmxPZlNvdXJjZSA9IG51bGw7Ci0KLSAgLyoqIFRoZSBSZXN1bHQgb2JqZWN0IGF0IHRoZSBzdGFydCBvZiB0aGUgdHJhbnNmb3JtLCBpZiBhbnkuICovCi0gIHByaXZhdGUgUmVzdWx0IG1fb3V0cHV0VGFyZ2V0ID0gbnVsbDsKLQotICAvKioKLSAgICogVGhlIG91dHB1dCBmb3JtYXQgb2JqZWN0IHNldCBieSB0aGUgdXNlci4gIE1heSBiZSBudWxsLgotICAgKi8KLSAgcHJpdmF0ZSBPdXRwdXRQcm9wZXJ0aWVzIG1fb3V0cHV0Rm9ybWF0OwotCi0gIC8qKiBUaGUgb3V0cHV0IHNlcmlhbGl6ZXIgKi8KLSAgcHJpdmF0ZSBTZXJpYWxpemVyIG1fc2VyaWFsaXplcjsKLQotICAvKioKLSAgICogVGhlIGNvbnRlbnQgaGFuZGxlciBmb3IgdGhlIHNvdXJjZSBpbnB1dCB0cmVlLgotICAgKi8KLSAgQ29udGVudEhhbmRsZXIgbV9pbnB1dENvbnRlbnRIYW5kbGVyOwotCi0gIC8qKgotICAgKiBUaGUgY29udGVudCBoYW5kbGVyIGZvciB0aGUgcmVzdWx0IHRyZWUuCi0gICAqLwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIG1fb3V0cHV0Q29udGVudEhhbmRsZXIgPSBudWxsOwotCi0gIC8vICAvKgotICAvLyAgICogVXNlIG1lbWJlciB2YXJpYWJsZSB0byBzdG9yZSBwYXJhbSB2YXJpYWJsZXMgYXMgdGhleSdyZQotICAvLyAgICogYmVpbmcgY3JlYXRlZCwgdXNlIG1lbWJlciB2YXJpYWJsZSBzbyB3ZSBkb24ndAotICAvLyAgICogaGF2ZSB0byBjcmVhdGUgYSBuZXcgdmVjdG9yIGV2ZXJ5IHRpbWUuCi0gIC8vICAgKi8KLSAgLy8gIHByaXZhdGUgVmVjdG9yIG1fbmV3VmFycyA9IG5ldyBWZWN0b3IoKTsKLQotICAvKiogVGhlIEpBWFAgRG9jdW1lbnQgQnVpbGRlciwgbWFpbmx5IHRvIGNyZWF0ZSBSZXN1bHQgVHJlZSBGcmFnbWVudHMuICovCi0gIERvY3VtZW50QnVpbGRlciBtX2RvY0J1aWxkZXIgPSBudWxsOwotCi0gIC8qKgotICAgKiBBIHBvb2wgb2YgUmVzdWx0VHJlZUhhbmRsZXJzLCBmb3Igc2VyaWFsaXphdGlvbiBvZiBhIHN1YnRyZWUgdG8gdGV4dC4KLSAgICogIFBsZWFzZSBub3RlIHRoYXQgZWFjaCBvZiB0aGVzZSBhbHNvIGhvbGRzIG9udG8gYSBUZXh0IFNlcmlhbGl6ZXIuICAKLSAgICovCi0gIHByaXZhdGUgT2JqZWN0UG9vbCBtX3RleHRSZXN1bHRIYW5kbGVyT2JqZWN0UG9vbCA9Ci0gICAgbmV3IE9iamVjdFBvb2woIm9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXIiKTsKLQotICAvKioKLSAgICogUmVsYXRlZCB0byBtX3RleHRSZXN1bHRIYW5kbGVyT2JqZWN0UG9vbCwgdGhpcyBpcyBhIHBvb2wgb2YKLSAgICogU3RyaW5nV3JpdGVycywgd2hpY2ggYXJlIHBhc3NlZCB0byB0aGUgVGV4dCBTZXJpYWxpemVycy4KLSAgICogKEknbSBub3Qgc3VyZSBpZiB0aGlzIGlzIHJlYWxseSBuZWVkZWQgYW55IG1vcmUuICAtc2IpICAgICAgCi0gICAqLwotICBwcml2YXRlIE9iamVjdFBvb2wgbV9zdHJpbmdXcml0ZXJPYmplY3RQb29sID0KLSAgICBuZXcgT2JqZWN0UG9vbCgiamF2YS5pby5TdHJpbmdXcml0ZXIiKTsKLQotICAvKioKLSAgICogQSBzdGF0aWMgdGV4dCBmb3JtYXQgb2JqZWN0LCB3aGljaCBjYW4gYmUgdXNlZCBvdmVyIGFuZAotICAgKiBvdmVyIHRvIGNyZWF0ZSB0aGUgdGV4dCBzZXJpYWxpemVycy4gICAgCi0gICAqLwotICBwcml2YXRlIE91dHB1dFByb3BlcnRpZXMgbV90ZXh0Zm9ybWF0ID0gbmV3IE91dHB1dFByb3BlcnRpZXMoTWV0aG9kLlRleHQpOwotCi0gIC8vIENvbW1lbnRlZGVkIG91dCBpbiByZXNwb25zZSB0byBwcm9ibGVtIHJlcG9ydGVkIGJ5IAotICAvLyBOaWNvbGEgQnJvd24gPE5pY29sYS5Ccm93bkBqYWNvYnNyaW1lbGwuY29tPgotICAvLyAgLyoqCi0gIC8vICAgKiBGbGFnIHRvIGxldCB1cyBrbm93IGlmIGFuIGV4Y2VwdGlvbiBzaG91bGQgYmUgcmVwb3J0ZWQgaW5zaWRlIHRoZSAKLSAgLy8gICAqIHBvc3RFeGNlcHRpb25Gcm9tVGhyZWFkIG1ldGhvZC4gIFRoaXMgaXMgbmVlZGVkIGlmIHRoZSB0cmFuc2Zvcm0gaXMgCi0gIC8vICAgKiBiZWluZyBnZW5lcmF0ZWQgZnJvbSBTQVggZXZlbnRzLCBhbmQgdGh1cyB0aGVyZSBpcyBubyBjZW50cmFsIHBsYWNlIAotICAvLyAgICogdG8gcmVwb3J0IHRoZSBleGNlcHRpb24gZnJvbS4gIChBbiBleGNlcHRpb24gaXMgdXN1YWxseSBwaWNrZWQgdXAgaW4gCi0gIC8vICAgKiB0aGUgbWFpbiB0aHJlYWQgZnJvbSB0aGUgdHJhbnNmb3JtIHRocmVhZCBpbiB7QGxpbmsgI3RyYW5zZm9ybShTb3VyY2Ugc291cmNlKX0gCi0gIC8vICAgKiBmcm9tIHtAbGluayAjZ2V0RXhjZXB0aW9uVGhyb3duKCl9LiApCi0gIC8vICAgKi8KLSAgLy8gIHByaXZhdGUgYm9vbGVhbiBtX3JlcG9ydEluUG9zdEV4Y2VwdGlvbkZyb21UaHJlYWQgPSBmYWxzZTsKLQotICAvKioKLSAgICogQSBub2RlIHZlY3RvciB1c2VkIGFzIGEgc3RhY2sgdG8gdHJhY2sgdGhlIGN1cnJlbnQKLSAgICogRWxlbVRlbXBsYXRlRWxlbWVudC4gIE5lZWRlZCBmb3IgdGhlCi0gICAqIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtU3RhdGUgaW50ZXJmYWNlLAotICAgKiBzbyBhIHRvb2wgY2FuIGRpc2NvdmVyIHRoZSBjYWxsaW5nIHRlbXBsYXRlLiBOb3RlIHRoZSB1c2Ugb2YgYW4gYXJyYXkgCi0gICAqIGZvciB0aGlzIGxpbWl0cyB0aGUgcmVjdXJzaW9uIGRlcHRoIHRvIDRLLgotICAgKi8KLSAgRWxlbVRlbXBsYXRlRWxlbWVudFtdIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHMgCi0gICAgICA9IG5ldyBFbGVtVGVtcGxhdGVFbGVtZW50W1hQYXRoQ29udGV4dC5SRUNVUlNJT05MSU1JVF07Ci0gIAotICAvKiogVGhlIHRvcCBvZiB0aGUgY3VycmVudFRlbXBsYXRlRWxlbWVudHMgc3RhY2suICovCi0gIGludCBtX2N1cnJlbnRUZW1wbGF0ZUVsZW1lbnRzVG9wID0gMDsKLQotICAvKioKLSAgICogQSBub2RlIHZlY3RvciB1c2VkIGFzIGEgc3RhY2sgdG8gdHJhY2sgdGhlIGN1cnJlbnQKLSAgICogRWxlbVRlbXBsYXRlIHRoYXQgd2FzIG1hdGNoZWQuCi0gICAqIE5lZWRlZCBmb3IgdGhlCi0gICAqIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtU3RhdGUgaW50ZXJmYWNlLAotICAgKiBzbyBhIHRvb2wgY2FuIGRpc2NvdmVyIHRoZSBtYXRjaGVkIHRlbXBsYXRlCi0gICAqLwotICBTdGFjayBtX2N1cnJlbnRNYXRjaFRlbXBsYXRlcyA9IG5ldyBTdGFjaygpOwotCi0gIC8qKgotICAgKiBBIG5vZGUgdmVjdG9yIHVzZWQgYXMgYSBzdGFjayB0byB0cmFjayB0aGUgY3VycmVudAotICAgKiBub2RlIHRoYXQgd2FzIG1hdGNoZWQuCi0gICAqIE5lZWRlZCBmb3IgdGhlCi0gICAqIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtU3RhdGUgaW50ZXJmYWNlLAotICAgKiBzbyBhIHRvb2wgY2FuIGRpc2NvdmVyIHRoZSBtYXRjaGVkCi0gICAqIG5vZGUuIAotICAgKi8KLSAgTm9kZVZlY3RvciBtX2N1cnJlbnRNYXRjaGVkTm9kZXMgPSBuZXcgTm9kZVZlY3RvcigpOwotCi0gIC8qKgotICAgKiBUaGUgcm9vdCBvZiBhIGxpbmtlZCBzZXQgb2Ygc3R5bGVzaGVldHMuCi0gICAqLwotICBwcml2YXRlIFN0eWxlc2hlZXRSb290IG1fc3R5bGVzaGVldFJvb3QgPSBudWxsOwotCi0gIC8qKgotICAgKiBJZiB0aGlzIGlzIHNldCB0byB0cnVlLCBkbyBub3Qgd2FybiBhYm91dCBwYXR0ZXJuCi0gICAqIG1hdGNoIGNvbmZsaWN0cy4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX3F1aWV0Q29uZmxpY3RXYXJuaW5ncyA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIFRoZSBsaWFzb24gdG8gdGhlIFhNTCBwYXJzZXIsIHNvIHRoZSBYU0wgcHJvY2Vzc29yCi0gICAqIGNhbiBoYW5kbGUgaW5jbHVkZWQgZmlsZXMsIGFuZCB0aGUgbGlrZSwgYW5kIGRvIHRoZQotICAgKiBpbml0aWFsIHBhcnNlIG9mIHRoZSBYU0wgZG9jdW1lbnQuCi0gICAqLwotICBwcml2YXRlIFhQYXRoQ29udGV4dCBtX3hjb250ZXh0OwotCi0gIC8qKgotICAgKiBPYmplY3QgdG8gZ3VhcmQgYWdhaW5zIGluZmluaXRlIHJlY3Vyc2lvbiB3aGVuCi0gICAqIGRvaW5nIHF1ZXJpZXMuCi0gICAqLwotICBwcml2YXRlIFN0YWNrR3VhcmQgbV9zdGFja0d1YXJkID0gbmV3IFN0YWNrR3VhcmQoKTsKLQotICAvKioKLSAgICogT3V0cHV0IGhhbmRsZXIgdG8gYm90dGxlbmVjayBTQVggZXZlbnRzLgotICAgKi8KLSAgcHJpdmF0ZSBSZXN1bHRUcmVlSGFuZGxlciBtX3Jlc3VsdFRyZWVIYW5kbGVyOwotCi0gIC8qKiBUaGUga2V5IG1hbmFnZXIsIHdoaWNoIG1hbmFnZXMgeHNsOmtleXMuICovCi0gIHByaXZhdGUgS2V5TWFuYWdlciBtX2tleU1hbmFnZXIgPSBuZXcgS2V5TWFuYWdlcigpOwotCi0gIC8qKgotICAgKiBTdGFjayBmb3IgdGhlIHB1cnBvc2VzIG9mIGZsYWdnaW5nIGluZmluaXRlIHJlY3Vyc2lvbiB3aXRoCi0gICAqIGF0dHJpYnV0ZSBzZXRzLgotICAgKi8KLSAgU3RhY2sgbV9hdHRyU2V0U3RhY2sgPSBudWxsOwotCi0gIC8qKgotICAgKiBUaGUgdGFibGUgb2YgY291bnRlcnMgZm9yIHhzbDpudW1iZXIgc3VwcG9ydC4KLSAgICogQHNlZSBFbGVtTnVtYmVyCi0gICAqLwotICBDb3VudGVyc1RhYmxlIG1fY291bnRlcnNUYWJsZSA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIElzID4gMCB3aGVuIHdlJ3JlIHByb2Nlc3NpbmcgYSBmb3ItZWFjaC4KLSAgICovCi0gIEJvb2xTdGFjayBtX2N1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwgPSBuZXcgQm9vbFN0YWNrKCk7Ci0KLSAgLyoqCi0gICAqIFRoZSBtZXNzYWdlIG1hbmFnZXIsIHdoaWNoIG1hbmFnZXMgZXJyb3IgbWVzc2FnZXMsIHdhcm5pbmcKLSAgICogbWVzc2FnZXMsIGFuZCBvdGhlciB0eXBlcyBvZiBtZXNzYWdlIGV2ZW50cy4gICAKLSAgICovCi0gIHByaXZhdGUgTXNnTWdyIG1fbXNnTWdyOwotCi0gIC8qKgotICAgKiBUaGlzIGlzIGEgY29tcGlsZS10aW1lIGZsYWcgdG8gdHVybiBvZmYgY2FsbGluZwotICAgKiBvZiB0cmFjZSBsaXN0ZW5lcnMuIFNldCB0aGlzIHRvIGZhbHNlIGZvciBvcHRpbWl6YXRpb24gcHVycG9zZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gU19ERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBUaGlzIHByb3BlcnR5IHNwZWNpZmllcyB3aGV0aGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBwaGFzZSBzaG91bGQKLSAgICoga2VlcCB0cmFjayBvZiBsaW5lIGFuZCBjb2x1bW4gbnVtYmVycyBmb3IgdGhlIGlucHV0IHNvdXJjZQotICAgKiBkb2N1bWVudC4gQnkgZGVmYXVsdCBpcyBmYWxzZS4gKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV91c2VTb3VyY2VMb2NhdGlvblByb3BlcnR5ID0gZmFsc2U7Ci0gIAotICAvKioKLSAgICogVGhlIFNBWCBlcnJvciBoYW5kbGVyLCB3aGVyZSBlcnJvcnMgYW5kIHdhcm5pbmdzIGFyZSBzZW50LgotICAgKi8KLSAgcHJpdmF0ZSBFcnJvckxpc3RlbmVyIG1fZXJyb3JIYW5kbGVyID0KLSAgICBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuRGVmYXVsdEVycm9ySGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBUaGUgdHJhY2UgbWFuYWdlci4KLSAgICovCi0gIHByaXZhdGUgVHJhY2VNYW5hZ2VyIG1fdHJhY2VNYW5hZ2VyID0gbmV3IFRyYWNlTWFuYWdlcih0aGlzKTsKLQotICAvKioKLSAgICogSWYgdGhlIHRyYW5zZm9ybSB0aHJlYWQgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdGhlIGV4Y2VwdGlvbiBuZWVkcyB0bwotICAgKiBiZSBzdGFzaGVkIGF3YXkgc28gdGhhdCB0aGUgbWFpbiB0aHJlYWQgY2FuIHBhc3MgaXQgb24gdG8gdGhlCi0gICAqIGNsaWVudC4gCi0gICAqLwotICBwcml2YXRlIEV4Y2VwdGlvbiBtX2V4Y2VwdGlvblRocm93biA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRoZSBJbnB1dFNvdXJjZSBmb3IgdGhlIHNvdXJjZSB0cmVlLCB3aGljaCBpcyBuZWVkZWQgaWYgdGhlCi0gICAqIHBhcnNlIHRocmVhZCBpcyBub3QgdGhlIG1haW4gdGhyZWFkLCBpbiBvcmRlciBmb3IgdGhlIHBhcnNlCi0gICAqIHRocmVhZCdzIHJ1biBtZXRob2QgdG8gZ2V0IHRvIHRoZSBpbnB1dCBzb3VyY2UuCi0gICAqIChEZWxldGUgdGhpcyBpZiByZXZlcnNpbmcgdGhyZWFkcyBpcyBvdXRsYXdlZC4gLXNiKSAgICAKLSAgICovCi0gIHByaXZhdGUgU291cmNlIG1feG1sU291cmNlOwotCi0gIC8qKgotICAgKiBUaGlzIGlzIG5lZWRlZCBmb3Igc3VwcG9ydCBvZiBzZXRTb3VyY2VUcmVlRG9jRm9yVGhyZWFkKE5vZGUgZG9jKSwKLSAgICogd2hpY2ggbXVzdCBiZSBjYWxsZWQgaW4gb3JkZXIgZm9yIHRoZSB0cmFuc2Zvcm0gdGhyZWFkJ3MgcnVuCi0gICAqIG1ldGhvZCB0byBvYnRhaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlIHRvIGJlIHRyYW5zZm9ybWVkLiAgICAgCi0gICAqLwotICBwcml2YXRlIGludCBtX2RvYzsKLQotICAvKioKLSAgICogSWYgdGhlIHRoZSB0cmFuc2Zvcm0gaXMgb24gdGhlIHNlY29uZGFyeSB0aHJlYWQsIHdlCi0gICAqIG5lZWQgdG8ga25vdyB3aGVuIGl0IGlzIGRvbmUsIHNvIHdlIGNhbiByZXR1cm4uCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9pc1RyYW5zZm9ybURvbmUgPSBmYWxzZTsKLQotICAvKiogRmxhZyB0byB0byB0ZWxsIGlmIHRoZSB0cmFuZm9ybWVyIG5lZWRzIHRvIGJlIHJlc2V0LiAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9oYXNCZWVuUmVzZXQgPSBmYWxzZTsKLQotICAvKiogTkVFRFNET0MgRmllbGQgbV9zaG91bGRSZXNldCAgICAgICAgICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9zaG91bGRSZXNldCA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIE5FRURTRE9DIE1ldGhvZCBzZXRTaG91bGRSZXNldCAKLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHNob3VsZFJlc2V0Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaG91bGRSZXNldChib29sZWFuIHNob3VsZFJlc2V0KQotICB7Ci0gICAgbV9zaG91bGRSZXNldCA9IHNob3VsZFJlc2V0OwotICB9Ci0KLSAgLyoqCi0gICAqIEEgc3RhY2sgb2YgY3VycmVudCB0ZW1wbGF0ZSBtb2Rlcy4KLSAgICovCi0gIHByaXZhdGUgU3RhY2sgbV9tb2RlcyA9IG5ldyBTdGFjaygpOwotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBTRUNUSU9OOiBDb25zdHJ1Y3RvcnMKLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFRyYW5zZm9ybWVySW1wbC4KLSAgICoKLSAgICogQHBhcmFtIHN0eWxlc2hlZXQgVGhlIHJvb3Qgb2YgdGhlIHN0eWxlc2hlZXQgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBUcmFuc2Zvcm1lckltcGwoU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldCkKLSAgewotCi0gICAgc2V0U3R5bGVzaGVldChzdHlsZXNoZWV0KTsKLSAgICBzZXRYUGF0aENvbnRleHQobmV3IFhQYXRoQ29udGV4dCh0aGlzKSk7Ci0gICAgZ2V0WFBhdGhDb250ZXh0KCkuc2V0TmFtZXNwYWNlQ29udGV4dChzdHlsZXNoZWV0KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgc3RhdGUuICBUaGlzIG5lZWRzIHRvIGJlIGNhbGxlZCBhZnRlciBhIHByb2Nlc3MoKSBjYWxsCi0gICAqIGlzIGludm9rZWQsIGlmIHRoZSBwcm9jZXNzb3IgaXMgdG8gYmUgdXNlZCBhZ2Fpbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCkKLSAgewotCi0gICAgaWYgKCFtX2hhc0JlZW5SZXNldCAmJiBtX3Nob3VsZFJlc2V0KQotICAgIHsKLSAgICAgIG1faGFzQmVlblJlc2V0ID0gdHJ1ZTsKLQotICAgICAgaWYgKHRoaXMubV9vdXRwdXRTdHJlYW0gIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBtX291dHB1dFN0cmVhbS5jbG9zZSgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGlvZSl7fQotICAgICAgfQotCi0gICAgICBtX291dHB1dFN0cmVhbSA9IG51bGw7Ci0KLSAgICAgIC8vIEkgbmVlZCB0byBsb29rIG1vcmUgY2FyZWZ1bGx5IGF0IHdoaWNoIG9mIHRoZXNlIHJlYWxseQotICAgICAgLy8gbmVlZHMgdG8gYmUgcmVzZXQuCi0gICAgICBtX2NvdW50ZXJzVGFibGUgPSBudWxsOwotICAgICAgbV9zdGFja0d1YXJkID0gbmV3IFN0YWNrR3VhcmQoKTsKLQotICAgICAgbV94Y29udGV4dC5yZXNldCgpOwotICAgICAgbV94Y29udGV4dC5nZXRWYXJTdGFjaygpLnJlc2V0KCk7Ci0KLSAgICAgIGludCBuID0gbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50cy5sZW5ndGg7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgCi0gICAgICB7Ci0gICAgICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHNbaV0gPSBudWxsOwotICAgICAgfQotICAgICAgbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50c1RvcCA9IDA7Ci0gICAgICAKLSAgICAgIG1fY3VycmVudE1hdGNoVGVtcGxhdGVzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICBtX2N1cnJlbnRNYXRjaGVkTm9kZXMucmVtb3ZlQWxsRWxlbWVudHMoKTsKLQotICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlciA9IG51bGw7Ci0gICAgICBtX291dHB1dFRhcmdldCA9IG51bGw7Ci0gICAgICBtX2tleU1hbmFnZXIgPSBuZXcgS2V5TWFuYWdlcigpOwotICAgICAgbV9hdHRyU2V0U3RhY2sgPSBudWxsOwotICAgICAgbV9jb3VudGVyc1RhYmxlID0gbnVsbDsKLSAgICAgIG1fY3VycmVudFRlbXBsYXRlUnVsZUlzTnVsbCA9IG5ldyBCb29sU3RhY2soKTsKLSAgICAgIG1feG1sU291cmNlID0gbnVsbDsKLSAgICAgIG1fZG9jID0gRFRNLk5VTEw7Ci0gICAgICBtX2lzVHJhbnNmb3JtRG9uZSA9IGZhbHNlOwotICAgICAgbV90cmFuc2Zvcm1UaHJlYWQgPSBudWxsOwotCi0gICAgICAvLyBtX2lucHV0Q29udGVudEhhbmRsZXIgPSBudWxsOwotICAgICAgLy8gRm9yIG5vdywgcmVzZXQgdGhlIGRvY3VtZW50IGNhY2hlIGVhY2ggdGltZS4KLSAgICAgIG1feGNvbnRleHQuZ2V0U291cmNlVHJlZU1hbmFnZXIoKS5yZXNldCgpOwotICAgIH0KLQotICAgIC8vICAgIG1fcmVwb3J0SW5Qb3N0RXhjZXB0aW9uRnJvbVRocmVhZCA9IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPmdldFByb3BlcnR5PC9jb2RlPiByZXR1cm5zIHRoZSBjdXJyZW50IHNldHRpbmcgb2YgdGhlCi0gICAqIHByb3BlcnR5IGRlc2NyaWJlZCBieSB0aGUgPGNvZGU+cHJvcGVydHk8L2NvZGU+IGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gcHJvcGVydHkgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYSA8Y29kZT5ib29sZWFuPC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5KQotICB7Ci0gICAgaWYgKHByb3BlcnR5LmVxdWFscyhYYWxhblByb3BlcnRpZXMuU09VUkNFX0xPQ0FUSU9OKSkKLSAgICAgIHJldHVybiBtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHk7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGEgcnVudGltZSBwcm9wZXJ0eSBmb3IgdGhpcyA8Y29kZT5UcmFuc2Zvcm1lckltcGw8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gcHJvcGVydHkgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqIEBwYXJhbSB2YWx1ZSBhbiA8Y29kZT5PYmplY3Q8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcm9wZXJ0eShTdHJpbmcgcHJvcGVydHksIE9iamVjdCB2YWx1ZSkKLSAgewotICAgIGlmIChwcm9wZXJ0eS5lcXVhbHMoWGFsYW5Qcm9wZXJ0aWVzLlNPVVJDRV9MT0NBVElPTikpIHsKLSAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikpCi0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BST1BFUlRZX1ZBTFVFX0JPT0xFQU4sIG5ldyBPYmplY3RbXXtYYWxhblByb3BlcnRpZXMuU09VUkNFX0xPQ0FUSU9OfSkpOyAvLyJWYWx1ZSBmb3IgcHJvcGVydHkgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgWGFsYW5Qcm9wZXJ0aWVzLlNPVVJDRV9MT0NBVElPTgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIiBzaG91bGQgYmUgYSBCb29sZWFuIGluc3RhbmNlIik7Ci0gICAgICBtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkgPSAoKEJvb2xlYW4pdmFsdWUpLmJvb2xlYW5WYWx1ZSgpOwotICAgIH0KLSAgfQotCi0gIC8vID09PT09PT09PSBUcmFuc2Zvcm1lciBJbnRlcmZhY2UgSW1wbGVtZW50YXRpb24gPT09PT09PT09PQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZXhwZXJpbWVudGFsIi8+Ci0gICAqIEdldCB0cnVlIGlmIHRoZSBwYXJzZXIgZXZlbnRzIHNob3VsZCBiZSBvbiB0aGUgbWFpbiB0aHJlYWQsCi0gICAqIGZhbHNlIGlmIG5vdC4gIEV4cGVyaW1lbnRhbC4gIENhbiBub3QgYmUgc2V0IHJpZ2h0IG5vdy4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBwYXJzZXIgZXZlbnRzIHNob3VsZCBiZSBvbiB0aGUgbWFpbiB0aHJlYWQsCi0gICAqIGZhbHNlIGlmIG5vdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUGFyc2VyRXZlbnRzT25NYWluKCkKLSAgewotICAgIHJldHVybiBtX3BhcnNlckV2ZW50c09uTWFpbjsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSB0aHJlYWQgdGhhdCB0aGUgdHJhbnNmb3JtIHByb2Nlc3MgaXMgb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRocmVhZCB0aGF0IHRoZSB0cmFuc2Zvcm0gcHJvY2VzcyBpcyBvbiwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBUaHJlYWQgZ2V0VHJhbnNmb3JtVGhyZWFkKCkKLSAgewotICAgIHJldHVybiBtX3RyYW5zZm9ybVRocmVhZDsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSB0aHJlYWQgdGhhdCB0aGUgdHJhbnNmb3JtIHByb2Nlc3MgaXMgb24uCi0gICAqCi0gICAqIEBwYXJhbSB0IFRoZSB0cmFuc2Zvcm0gdGhyZWFkLCBtYXkgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFRyYW5zZm9ybVRocmVhZChUaHJlYWQgdCkKLSAgewotICAgIG1fdHJhbnNmb3JtVGhyZWFkID0gdDsKLSAgfQotCi0gIC8qKiBORUVEU0RPQyBGaWVsZCBtX2hhc1RyYW5zZm9ybVRocmVhZEVycm9yQ2F0Y2hlciAgICAgICAgICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9oYXNUcmFuc2Zvcm1UaHJlYWRFcnJvckNhdGNoZXIgPSBmYWxzZTsKLQotICAvKioKLSAgICogUmV0dXJuIHRydWUgaWYgdGhlIHRyYW5zZm9ybSB3YXMgaW5pdGlhdGVkIGZyb20gdGhlIHRyYW5zZm9ybSBtZXRob2QsCi0gICAqIG90aGVyd2lzZSBpdCB3YXMgcHJvYmFibHkgZG9uZSBmcm9tIGEgcHVyZSBwYXJzZSBldmVudHMuCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc1RyYW5zZm9ybVRocmVhZEVycm9yQ2F0Y2hlcigpCi0gIHsKLSAgICByZXR1cm4gbV9oYXNUcmFuc2Zvcm1UaHJlYWRFcnJvckNhdGNoZXI7Ci0gIH0KLSAgICAgICAgCi0gICAgICAgIC8qKgotICAgKiBQcm9jZXNzIHRoZSBzb3VyY2UgdHJlZSB0byBTQVggcGFyc2UgZXZlbnRzLgotICAgKiBAcGFyYW0gc291cmNlICBUaGUgaW5wdXQgZm9yIHRoZSBzb3VyY2UgdHJlZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhbnNmb3JtKFNvdXJjZSBzb3VyY2UpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgICAgICAgICAgICAgdHJhbnNmb3JtKHNvdXJjZSwgdHJ1ZSk7IAotICAgICAgICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgdGhlIHNvdXJjZSB0cmVlIHRvIFNBWCBwYXJzZSBldmVudHMuCi0gICAqIEBwYXJhbSBzb3VyY2UgIFRoZSBpbnB1dCBmb3IgdGhlIHNvdXJjZSB0cmVlLgotICAgKiBAcGFyYW0gc2hvdWxkUmVsZWFzZSAgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gcmVsZWFzZSBEVE1NYW5hZ2VyLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHNvdXJjZSwgYm9vbGVhbiBzaG91bGRSZWxlYXNlKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIGJhc2UgPSBzb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLSAgICAgIAotICAgICAgLy8gSWYgbm8gc3lzdGVtSUQgb2YgdGhlIHNvdXJjZSwgdXNlIHRoZSBiYXNlIG9mIHRoZSBzdHlsZXNoZWV0LgotICAgICAgaWYobnVsbCA9PSBiYXNlKQotICAgICAgewotICAgICAgICBiYXNlID0gbV9zdHlsZXNoZWV0Um9vdC5nZXRCYXNlSWRlbnRpZmllcigpOwotICAgICAgfQotCi0gICAgICAvLyBBcyBhIGxhc3QgcmVzb3J0LCB1c2UgdGhlIGN1cnJlbnQgdXNlciBkaXIuCi0gICAgICBpZihudWxsID09IGJhc2UpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBjdXJyZW50RGlyID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpOwotICAgICAgICAKLSAgICAgICAgaWYgKGN1cnJlbnREaXIuc3RhcnRzV2l0aChqYXZhLmlvLkZpbGUuc2VwYXJhdG9yKSkKLSAgICAgICAgICBiYXNlID0gImZpbGU6Ly8iICsgY3VycmVudERpcjsKLSAgICAgICAgZWxzZQotICAgICAgICAgIGJhc2UgPSAiZmlsZTovLy8iICsgY3VycmVudERpcjsKLSAgICAgICAgCi0gICAgICAgIGJhc2UgPSBiYXNlICsgamF2YS5pby5GaWxlLnNlcGFyYXRvckNoYXIKLSAgICAgICAgICAgICAgICsgc291cmNlLmdldENsYXNzKCkuZ2V0TmFtZSgpOwotICAgICAgfQotICAgICAgc2V0QmFzZVVSTE9mU291cmNlKGJhc2UpOwotICAgICAgRFRNTWFuYWdlciBtZ3IgPSBtX3hjb250ZXh0LmdldERUTU1hbmFnZXIoKTsKLSAgICAgIERUTSBkdG0gPSBtZ3IuZ2V0RFRNKHNvdXJjZSwgZmFsc2UsIHRoaXMsIHRydWUsIHRydWUpOwotICAgICAgZHRtLnNldFByb3BlcnR5KFhhbGFuUHJvcGVydGllcy5TT1VSQ0VfTE9DQVRJT04sCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IEJvb2xlYW4obV91c2VTb3VyY2VMb2NhdGlvblByb3BlcnR5KSk7Ci0gICAgICAKLSAgICAgIGJvb2xlYW4gaGFyZERlbGV0ZSA9IHRydWU7ICAvLyAlUkVWSUVXJSBJIGhhdmUgdG8gdGhpbmsgYWJvdXQgdGhpcy4gLXNiCi0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICB0aGlzLnRyYW5zZm9ybU5vZGUoZHRtLmdldERvY3VtZW50KCkpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBpZiAoc2hvdWxkUmVsZWFzZSkKLSAgICAgICAgICBtZ3IucmVsZWFzZShkdG0sIGhhcmREZWxldGUpOwotICAgICAgfQotCi0gICAgICAvLyBLaWNrIG9mZiB0aGUgcGFyc2UuICBXaGVuIHRoZSBDb250ZW50SGFuZGxlciBnZXRzIAotICAgICAgLy8gdGhlIHN0YXJ0RG9jdW1lbnQgZXZlbnQsIGl0IHdpbGwgY2FsbCB0cmFuc2Zvcm1Ob2RlKCBub2RlICkuCi0gICAgICAvLyByZWFkZXIucGFyc2UoIHhtbFNvdXJjZSApOwotICAgICAgLy8gVGhpcyBoYXMgdG8gYmUgZG9uZSB0byBjYXRjaCBleGNlcHRpb25zIHRocm93biBmcm9tIAotICAgICAgLy8gdGhlIHRyYW5zZm9ybSB0aHJlYWQgc3Bhd25lZCBieSB0aGUgU1RyZWUgaGFuZGxlci4KLSAgICAgIEV4Y2VwdGlvbiBlID0gZ2V0RXhjZXB0aW9uVGhyb3duKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IGUpCi0gICAgICB7Ci0gICAgICAgIGlmIChlIGluc3RhbmNlb2YgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbikKLSAgICAgICAgewotICAgICAgICAgIHRocm93IChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uKSBlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGUgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbikKLSAgICAgICAgewotICAgICAgICAgIG1fZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3IoCi0gICAgICAgICAgICBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgKChvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbikgZSkuZ2V0RXhjZXB0aW9uKCkpKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSBpZiAobnVsbCAhPSBtX3Jlc3VsdFRyZWVIYW5kbGVyKQotICAgICAgewotICAgICAgICBtX3Jlc3VsdFRyZWVIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbiB3cmUpCi0gICAgewotICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IHdyZS5nZXRFeGNlcHRpb24oKTsKLQotICAgICAgd2hpbGUgKHRocm93YWJsZQotICAgICAgICAgICAgIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIHRocm93YWJsZSA9Ci0gICAgICAgICAgKChvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbikgdGhyb3dhYmxlKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgIH0KLQotICAgICAgbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24od3JlLmdldEV4Y2VwdGlvbigpKSk7Ci0gICAgfQotCi0gICAgLy8gUGF0Y2ggYXR0cmlidXRlZCB0byBEYXZpZCBFaXNlbmJlcmcgPGRhdmlkQGNhdGNvZGUuY29tPgotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbiBzcGUpCi0gICAgewotICAgICAgU3RyaW5nIG1zZyA9IHNwZS5nZXRNZXNzYWdlKCk7Ci0gICAgICBTQVhTb3VyY2VMb2NhdG9yIGxvYyA9IG5ldyBTQVhTb3VyY2VMb2NhdG9yKHNwZSk7Ci0KLSAgICAgIC8vbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oIG1zZywgbG9jICkpOwotICAgICAgbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc3BlKSk7Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIG1faGFzVHJhbnNmb3JtVGhyZWFkRXJyb3JDYXRjaGVyID0gZmFsc2U7Ci0KLSAgICAgIC8vIFRoaXMgbG9va3MgdG8gYmUgcmVkdW5kZW50IHRvIHRoZSBvbmUgZG9uZSBpbiBUcmFuc2Zvcm1Ob2RlLgotICAgICAgcmVzZXQoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBiYXNlIFVSTCBvZiB0aGUgc291cmNlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBiYXNlIFVSTCBvZiB0aGUgc291cmNlIHRyZWUsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJhc2VVUkxPZlNvdXJjZSgpCi0gIHsKLSAgICByZXR1cm4gbV91cmxPZlNvdXJjZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGJhc2UgVVJMIG9mIHRoZSBzb3VyY2UuCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBiYXNlCi0gICAqIEByZXR1cm4gVGhlIGJhc2UgVVJMIG9mIHRoZSBzb3VyY2UgdHJlZSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEJhc2VVUkxPZlNvdXJjZShTdHJpbmcgYmFzZSkKLSAgewotICAgIG1fdXJsT2ZTb3VyY2UgPSBiYXNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgb3JpZ2luYWwgb3V0cHV0IHRhcmdldC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgUmVzdWx0IG9iamVjdCB1c2VkIHRvIGtpY2sgb2YgdGhlIHRyYW5zZm9ybSBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFJlc3VsdCBnZXRPdXRwdXRUYXJnZXQoKQotICB7Ci0gICAgcmV0dXJuIG1fb3V0cHV0VGFyZ2V0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgb3JpZ2luYWwgb3V0cHV0IHRhcmdldC4gIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYSBTQVggdHJhbnNmb3JtIGFuZAotICAgKiBzdXBwbHlpbmcgYSBDb250ZW50SGFuZGxlciBvciB3aGVuIHRoZSBVUkkgb2YgdGhlIG91dHB1dCB0YXJnZXQgc2hvdWxkCi0gICAqIG5vdCBiZSB0aGUgc2FtZSBhcyB0aGUgc3lzdGVtSUQgb2YgdGhlIG9yaWdpbmFsIG91dHB1dCB0YXJnZXQuCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBvdXRwdXRUYXJnZXQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE91dHB1dFRhcmdldChSZXN1bHQgb3V0cHV0VGFyZ2V0KQotICB7Ci0gICAgbV9vdXRwdXRUYXJnZXQgPSBvdXRwdXRUYXJnZXQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIG91dHB1dCBwcm9wZXJ0eSB0aGF0IGlzIGluIGVmZmVjdCBmb3IgdGhlCi0gICAqIHRyYW5zZm9ybWF0aW9uLiAgVGhlIHByb3BlcnR5IHNwZWNpZmllZCBtYXkgYmUgYSBwcm9wZXJ0eQotICAgKiB0aGF0IHdhcyBzZXQgd2l0aCBzZXRPdXRwdXRQcm9wZXJ0eSwgb3IgaXQgbWF5IGJlIGEKLSAgICogcHJvcGVydHkgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBBIG5vbi1udWxsIFN0cmluZyB0aGF0IHNwZWNpZmllcyBhbiBvdXRwdXQKLSAgICogcHJvcGVydHkgbmFtZSwgd2hpY2ggbWF5IGJlIG5hbWVzcGFjZSBxdWFsaWZpZWQuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBxbmFtZVN0cmluZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIG91dHB1dCBwcm9wZXJ0eSwgb3IgbnVsbAotICAgKiBpZiBubyBwcm9wZXJ0eSB3YXMgZm91bmQuCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIElmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkLgotICAgKgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uT3V0cHV0S2V5cwotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRPdXRwdXRQcm9wZXJ0eShTdHJpbmcgcW5hbWVTdHJpbmcpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgdmFsdWUgPSBudWxsOwotICAgIE91dHB1dFByb3BlcnRpZXMgcHJvcHMgPSBnZXRPdXRwdXRGb3JtYXQoKTsKLQotICAgIHZhbHVlID0gcHJvcHMuZ2V0UHJvcGVydHkocW5hbWVTdHJpbmcpOwotCi0gICAgaWYgKG51bGwgPT0gdmFsdWUpCi0gICAgewotICAgICAgaWYgKCFwcm9wcy5pc0xlZ2FsUHJvcGVydHlLZXkocW5hbWVTdHJpbmcpKQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX09VVFBVVF9QUk9QRVJUWV9OT1RfUkVDT0dOSVpFRCwgbmV3IE9iamVjdFtde3FuYW1lU3RyaW5nfSkpOyAvLyJvdXRwdXQgcHJvcGVydHkgbm90IHJlY29nbml6ZWQ6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgcW5hbWVTdHJpbmcpOwotICAgIH0KLQotICAgIHJldHVybiB2YWx1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHksIHdpdGhvdXQgdXNpbmcgdGhlIGRlZmF1bHQgcHJvcGVydGllcy4gIFRoaXMKLSAgICogY2FuIGJlIHVzZWQgdG8gdGVzdCBpZiBhIHByb3BlcnR5IGhhcyBiZWVuIGV4cGxpY2l0bHkgc2V0IGJ5IHRoZSBzdHlsZXNoZWV0Ci0gICAqIG9yIHVzZXIuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBxbmFtZVN0cmluZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHksIG9yIG51bGwgaWYgbm90IGZvdW5kLgotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgcHJvcGVydHkgaXMgbm90IHN1cHBvcnRlZCwKLSAgICogYW5kIGlzIG5vdCBuYW1lc3BhY2VkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRPdXRwdXRQcm9wZXJ0eU5vRGVmYXVsdChTdHJpbmcgcW5hbWVTdHJpbmcpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgdmFsdWUgPSBudWxsOwotICAgIE91dHB1dFByb3BlcnRpZXMgcHJvcHMgPSBnZXRPdXRwdXRGb3JtYXQoKTsKLQotICAgIHZhbHVlID0gKFN0cmluZykgcHJvcHMuZ2V0UHJvcGVydGllcygpLmdldChxbmFtZVN0cmluZyk7Ci0KLSAgICBpZiAobnVsbCA9PSB2YWx1ZSkKLSAgICB7Ci0gICAgICBpZiAoIXByb3BzLmlzTGVnYWxQcm9wZXJ0eUtleShxbmFtZVN0cmluZykpCi0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfT1VUUFVUX1BST1BFUlRZX05PVF9SRUNPR05JWkVELCBuZXcgT2JqZWN0W117cW5hbWVTdHJpbmd9KSk7IC8vIm91dHB1dCBwcm9wZXJ0eSBub3QgcmVjb2duaXplZDogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKyBxbmFtZVN0cmluZyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHZhbHVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eS4gIFJlY29nbml6ZWQgcHJvcGVydGllcyBhcmU6Ci0gICAqCi0gICAqIDxwPiJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdC9zb3VyY2ViYXNlIiAtIHRoZSBiYXNlIFVSTCBmb3IgdGhlCi0gICAqIHNvdXJjZSwgd2hpY2ggaXMgbmVlZGVkIHdoZW4gcHVyZSBTQVggQ29udGVudEhhbmRsZXIgdHJhbnNmb3JtYXRpb24KLSAgICogaXMgdG8gYmUgZG9uZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lLCB3aGljaCBpcyBhIGZ1bGx5LXF1YWxpZmllZCBVUkkuCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWVzdGVkIHZhbHVlIGZvciB0aGUgcHJvcGVydHkuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBwcm9wZXJ0eSBuYW1lIGlzIG5vdCBsZWdhbC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE91dHB1dFByb3BlcnR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICBzeW5jaHJvbml6ZWQgKG1fcmVlbnRyeUd1YXJkKQotICAgIHsKLQotICAgICAgLy8gR2V0IHRoZSBvdXRwdXQgZm9ybWF0IHRoYXQgd2FzIHNldCBieSB0aGUgdXNlciwgb3RoZXJ3aXNlIGdldCB0aGUgCi0gICAgICAvLyBvdXRwdXQgZm9ybWF0IGZyb20gdGhlIHN0eWxlc2hlZXQuCi0gICAgICBpZiAobnVsbCA9PSBtX291dHB1dEZvcm1hdCkKLSAgICAgIHsKLSAgICAgICAgbV9vdXRwdXRGb3JtYXQgPQotICAgICAgICAgIChPdXRwdXRQcm9wZXJ0aWVzKSBnZXRTdHlsZXNoZWV0KCkuZ2V0T3V0cHV0Q29tcG9zZWQoKS5jbG9uZSgpOwotICAgICAgfQotCi0gICAgICBpZiAoIW1fb3V0cHV0Rm9ybWF0LmlzTGVnYWxQcm9wZXJ0eUtleShuYW1lKSkKLSAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9PVVRQVVRfUFJPUEVSVFlfTk9UX1JFQ09HTklaRUQsIG5ldyBPYmplY3RbXXtuYW1lfSkpOyAvLyJvdXRwdXQgcHJvcGVydHkgbm90IHJlY29nbml6ZWQ6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgbmFtZSk7Ci0KLSAgICAgIG1fb3V0cHV0Rm9ybWF0LnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBvdXRwdXQgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiAgVGhlc2UKLSAgICogcHJvcGVydGllcyB3aWxsIG92ZXJyaWRlIHByb3BlcnRpZXMgc2V0IGluIHRoZSB0ZW1wbGF0ZXMKLSAgICogd2l0aCB4c2w6b3V0cHV0LgotICAgKgotICAgKiA8cD5JZiBhcmd1bWVudCB0byB0aGlzIGZ1bmN0aW9uIGlzIG51bGwsIGFueSBwcm9wZXJ0aWVzCi0gICAqIHByZXZpb3VzbHkgc2V0IHdpbGwgYmUgcmVtb3ZlZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBvZm9ybWF0IEEgc2V0IG9mIG91dHB1dCBwcm9wZXJ0aWVzIHRoYXQgd2lsbCBiZQotICAgKiB1c2VkIHRvIG92ZXJyaWRlIGFueSBvZiB0aGUgc2FtZSBwcm9wZXJ0aWVzIGluIGVmZmVjdAotICAgKiBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0UHJvcGVydGllcyhQcm9wZXJ0aWVzIG9mb3JtYXQpCi0gIHsKLQotICAgIHN5bmNocm9uaXplZCAobV9yZWVudHJ5R3VhcmQpCi0gICAgewotICAgICAgaWYgKG51bGwgIT0gb2Zvcm1hdCkKLSAgICAgIHsKLQotICAgICAgICAvLyBTZWUgaWYgYW4gKmV4cGxpY2l0KiBtZXRob2Qgd2FzIHNldC4KLSAgICAgICAgU3RyaW5nIG1ldGhvZCA9IChTdHJpbmcpIG9mb3JtYXQuZ2V0KE91dHB1dEtleXMuTUVUSE9EKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtZXRob2QpCi0gICAgICAgICAgbV9vdXRwdXRGb3JtYXQgPSBuZXcgT3V0cHV0UHJvcGVydGllcyhtZXRob2QpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgbV9vdXRwdXRGb3JtYXQgPSBuZXcgT3V0cHV0UHJvcGVydGllcygpOwotICAgICAgfQotCi0gICAgICBpZiAobnVsbCAhPSBvZm9ybWF0KQotICAgICAgewotICAgICAgICBtX291dHB1dEZvcm1hdC5jb3B5RnJvbShvZm9ybWF0KTsKLSAgICAgIH0KLQotICAgICAgLy8gY29weUZyb20gZG9lcyBub3Qgc2V0IHByb3BlcnRpZXMgdGhhdCBoYXZlIGJlZW4gYWxyZWFkeSBzZXQsIHNvIAotICAgICAgLy8gdGhpcyBtdXN0IGJlIGNhbGxlZCBhZnRlciwgd2hpY2ggaXMgYSBiaXQgaW4gdGhlIHJldmVyc2UgZnJvbSAKLSAgICAgIC8vIHdoYXQgb25lIG1pZ2h0IHRoaW5rLgotICAgICAgbV9vdXRwdXRGb3JtYXQuY29weUZyb20obV9zdHlsZXNoZWV0Um9vdC5nZXRPdXRwdXRQcm9wZXJ0aWVzKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBjb3B5IG9mIHRoZSBvdXRwdXQgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiAgVGhlc2UKLSAgICogcHJvcGVydGllcyB3aWxsIG92ZXJyaWRlIHByb3BlcnRpZXMgc2V0IGluIHRoZSB0ZW1wbGF0ZXMKLSAgICogd2l0aCB4c2w6b3V0cHV0LgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgbXV0YXRpb24gb2YgdGhlIFByb3BlcnRpZXMgb2JqZWN0IHJldHVybmVkIHdpbGwgbm90Ci0gICAqIGVmZmVjdCB0aGUgcHJvcGVydGllcyB0aGF0IHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250YWlucy48L3A+Ci0gICAqCi0gICAqIEByZXR1cm5zIEEgY29weSBvZiB0aGUgc2V0IG9mIG91dHB1dCBwcm9wZXJ0aWVzIGluIGVmZmVjdAotICAgKiBmb3IgdGhlIG5leHQgdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKQotICB7Ci0gICAgcmV0dXJuIChQcm9wZXJ0aWVzKSBnZXRPdXRwdXRGb3JtYXQoKS5nZXRQcm9wZXJ0aWVzKCkuY2xvbmUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSByZXN1bHQgQ29udGVudEhhbmRsZXIgZnJvbSBhIFJlc3VsdCBvYmplY3QsIGJhc2VkCi0gICAqIG9uIHRoZSBjdXJyZW50IE91dHB1dFByb3BlcnRpZXMuCi0gICAqCi0gICAqIEBwYXJhbSBvdXRwdXRUYXJnZXQgV2hlcmUgdGhlIHRyYW5zZm9ybSByZXN1bHQgc2hvdWxkIGdvLAotICAgKiBzaG91bGQgbm90IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gQSB2YWxpZCBDb250ZW50SGFuZGxlciB0aGF0IHdpbGwgY3JlYXRlIHRoZQotICAgKiByZXN1bHQgdHJlZSB3aGVuIGl0IGlzIGZlZCBTQVggZXZlbnRzLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQ29udGVudEhhbmRsZXIgY3JlYXRlUmVzdWx0Q29udGVudEhhbmRsZXIoUmVzdWx0IG91dHB1dFRhcmdldCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjcmVhdGVSZXN1bHRDb250ZW50SGFuZGxlcihvdXRwdXRUYXJnZXQsIGdldE91dHB1dEZvcm1hdCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBDb250ZW50SGFuZGxlciBmcm9tIGEgUmVzdWx0IG9iamVjdCBhbmQgYW4gT3V0cHV0UHJvcGVydGllcy4KLSAgICoKLSAgICogQHBhcmFtIG91dHB1dFRhcmdldCBXaGVyZSB0aGUgdHJhbnNmb3JtIHJlc3VsdCBzaG91bGQgZ28sCi0gICAqIHNob3VsZCBub3QgYmUgbnVsbC4KLSAgICogQHBhcmFtIGZvcm1hdCBUaGUgT3V0cHV0UHJvcGVydGllcyBvYmplY3QgdGhhdCB3aWxsIGNvbnRhaW4KLSAgICogaW5zdHJ1Y3Rpb25zIG9uIGhvdyB0byBzZXJpYWxpemUgdGhlIG91dHB1dC4KLSAgICoKLSAgICogQHJldHVybiBBIHZhbGlkIENvbnRlbnRIYW5kbGVyIHRoYXQgd2lsbCBjcmVhdGUgdGhlCi0gICAqIHJlc3VsdCB0cmVlIHdoZW4gaXQgaXMgZmVkIFNBWCBldmVudHMuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBDb250ZW50SGFuZGxlciBjcmVhdGVSZXN1bHRDb250ZW50SGFuZGxlcigKLSAgICAgICAgICBSZXN1bHQgb3V0cHV0VGFyZ2V0LCBPdXRwdXRQcm9wZXJ0aWVzIGZvcm1hdCkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBDb250ZW50SGFuZGxlciBoYW5kbGVyID0gbnVsbDsKLQotICAgIC8vIElmIHRoZSBSZXN1bHQgb2JqZWN0IGNvbnRhaW5zIGEgTm9kZSwgdGhlbiBjcmVhdGUgCi0gICAgLy8gYSBDb250ZW50SGFuZGxlciB0aGF0IHdpbGwgYWRkIG5vZGVzIHRvIHRoZSBpbnB1dCBub2RlLgotICAgIG9yZy53M2MuZG9tLk5vZGUgb3V0cHV0Tm9kZSA9IG51bGw7Ci0KLSAgICBpZiAob3V0cHV0VGFyZ2V0IGluc3RhbmNlb2YgRE9NUmVzdWx0KQotICAgIHsKLSAgICAgIG91dHB1dE5vZGUgPSAoKERPTVJlc3VsdCkgb3V0cHV0VGFyZ2V0KS5nZXROb2RlKCk7Ci0KLSAgICAgIG9yZy53M2MuZG9tLkRvY3VtZW50IGRvYzsKLSAgICAgIHNob3J0IHR5cGU7Ci0KLSAgICAgIGlmIChudWxsICE9IG91dHB1dE5vZGUpCi0gICAgICB7Ci0gICAgICAgIHR5cGUgPSBvdXRwdXROb2RlLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgIGRvYyA9IChvcmcudzNjLmRvbS5Ob2RlLkRPQ1VNRU5UX05PREUgPT0gdHlwZSkKLSAgICAgICAgICAgICAgPyAob3JnLnczYy5kb20uRG9jdW1lbnQpIG91dHB1dE5vZGUKLSAgICAgICAgICAgICAgOiBvdXRwdXROb2RlLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZG9jID0gb3JnLmFwYWNoZS54cGF0aC5ET01IZWxwZXIuY3JlYXRlRG9jdW1lbnQoKTsKLSAgICAgICAgb3V0cHV0Tm9kZSA9IGRvYzsKLSAgICAgICAgdHlwZSA9IG91dHB1dE5vZGUuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICAoKERPTVJlc3VsdCkgb3V0cHV0VGFyZ2V0KS5zZXROb2RlKG91dHB1dE5vZGUpOwotICAgICAgfQotCi0gICAgICBoYW5kbGVyID0KLSAgICAgICAgKG9yZy53M2MuZG9tLk5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9PSB0eXBlKQotICAgICAgICA/IG5ldyBET01CdWlsZGVyKGRvYywgKG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQpIG91dHB1dE5vZGUpCi0gICAgICAgIDogbmV3IERPTUJ1aWxkZXIoZG9jLCBvdXRwdXROb2RlKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAob3V0cHV0VGFyZ2V0IGluc3RhbmNlb2YgU0FYUmVzdWx0KQotICAgIHsKLSAgICAgIGhhbmRsZXIgPSAoKFNBWFJlc3VsdCkgb3V0cHV0VGFyZ2V0KS5nZXRIYW5kbGVyKCk7Ci0KLSAgICAgIGlmIChudWxsID09IGhhbmRsZXIpCi0gICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgImhhbmRsZXIgY2FuIG5vdCBiZSBudWxsIGZvciBhIFNBWFJlc3VsdCIpOwotICAgIH0KLQotICAgIC8vIE90aGVyd2lzZSwgY3JlYXRlIGEgQ29udGVudEhhbmRsZXIgdGhhdCB3aWxsIHNlcmlhbGl6ZSB0aGUgCi0gICAgLy8gcmVzdWx0IHRyZWUgdG8gZWl0aGVyIGEgc3RyZWFtIG9yIGEgd3JpdGVyLgotICAgIGVsc2UgaWYgKG91dHB1dFRhcmdldCBpbnN0YW5jZW9mIFN0cmVhbVJlc3VsdCkKLSAgICB7Ci0gICAgICBTdHJlYW1SZXN1bHQgc3Jlc3VsdCA9IChTdHJlYW1SZXN1bHQpIG91dHB1dFRhcmdldDsKLSAgICAgIFN0cmluZyBtZXRob2QgPSBmb3JtYXQuZ2V0UHJvcGVydHkoT3V0cHV0S2V5cy5NRVRIT0QpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgU2VyaWFsaXplciBzZXJpYWxpemVyID0KLSAgICAgICAgICBTZXJpYWxpemVyRmFjdG9yeS5nZXRTZXJpYWxpemVyKGZvcm1hdC5nZXRQcm9wZXJ0aWVzKCkpOwotCi0gICAgICAgIGlmIChudWxsICE9IHNyZXN1bHQuZ2V0V3JpdGVyKCkpCi0gICAgICAgICAgc2VyaWFsaXplci5zZXRXcml0ZXIoc3Jlc3VsdC5nZXRXcml0ZXIoKSk7Ci0gICAgICAgIGVsc2UgaWYgKG51bGwgIT0gc3Jlc3VsdC5nZXRPdXRwdXRTdHJlYW0oKSkKLSAgICAgICAgICBzZXJpYWxpemVyLnNldE91dHB1dFN0cmVhbShzcmVzdWx0LmdldE91dHB1dFN0cmVhbSgpKTsKLSAgICAgICAgZWxzZSBpZiAobnVsbCAhPSBzcmVzdWx0LmdldFN5c3RlbUlkKCkpCi0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcgZmlsZVVSTCA9IHNyZXN1bHQuZ2V0U3lzdGVtSWQoKTsKLQotICAgICAgICAgIGlmIChmaWxlVVJMLnN0YXJ0c1dpdGgoImZpbGU6Ly8vIikpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGZpbGVVUkwuc3Vic3RyaW5nKDgpLmluZGV4T2YoIjoiKSA+MCkKLSAgICAgICAgICAgICAgZmlsZVVSTCA9IGZpbGVVUkwuc3Vic3RyaW5nKDgpOwotICAgICAgICAgICAgZWxzZSAKLSAgICAgICAgICAgICAgZmlsZVVSTCA9IGZpbGVVUkwuc3Vic3RyaW5nKDcpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIG1fb3V0cHV0U3RyZWFtID0gbmV3IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbShmaWxlVVJMKTsKLQotICAgICAgICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0U3RyZWFtKG1fb3V0cHV0U3RyZWFtKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PX09VVFBVVF9TUEVDSUZJRUQsIG51bGwpKTsgLy8iTm8gb3V0cHV0IHNwZWNpZmllZCEiKTsKLQotICAgICAgICBoYW5kbGVyID0gc2VyaWFsaXplci5hc0NvbnRlbnRIYW5kbGVyKCk7Ci0KLSAgICAgICAgdGhpcy5zZXRTZXJpYWxpemVyKHNlcmlhbGl6ZXIpOwotICAgICAgfQotICAgICAgY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWVlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24odWVlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihpb2UpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NBTk5PVF9UUkFOU0ZPUk1fVE9fUkVTVUxUX1RZUEUsIG5ldyBPYmplY3RbXXtvdXRwdXRUYXJnZXQuZ2V0Q2xhc3MoKS5nZXROYW1lKCl9KSk7IC8vIkNhbid0IHRyYW5zZm9ybSB0byBhIFJlc3VsdCBvZiB0eXBlICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgb3V0cHV0VGFyZ2V0LmdldENsYXNzKCkuZ2V0TmFtZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rICIhIik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGhhbmRsZXI7Ci0gIH0KLSAgICAgICAgCi0gICAgICAgIC8qKgotICAgKiBQcm9jZXNzIHRoZSBzb3VyY2UgdHJlZSB0byB0aGUgb3V0cHV0IHJlc3VsdC4KLSAgICogQHBhcmFtIHhtbFNvdXJjZSAgVGhlIGlucHV0IGZvciB0aGUgc291cmNlIHRyZWUuCi0gICAqIEBwYXJhbSBvdXRwdXRUYXJnZXQgVGhlIG91dHB1dCBzb3VyY2UgdGFyZ2V0LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IG91dHB1dFRhcmdldCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgICAgICAgICAgICAgIHRyYW5zZm9ybSh4bWxTb3VyY2UsIG91dHB1dFRhcmdldCwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAvKioKLSAgICogUHJvY2VzcyB0aGUgc291cmNlIHRyZWUgdG8gdGhlIG91dHB1dCByZXN1bHQuCi0gICAqIEBwYXJhbSB4bWxTb3VyY2UgIFRoZSBpbnB1dCBmb3IgdGhlIHNvdXJjZSB0cmVlLgotICAgKiBAcGFyYW0gb3V0cHV0VGFyZ2V0IFRoZSBvdXRwdXQgc291cmNlIHRhcmdldC4KLSAgICogQHBhcmFtIHNob3VsZFJlbGVhc2UgIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHJlbGVhc2UgRFRNTWFuYWdlci4gCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShTb3VyY2UgeG1sU291cmNlLCBSZXN1bHQgb3V0cHV0VGFyZ2V0LCBib29sZWFuIHNob3VsZFJlbGVhc2UpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN5bmNocm9uaXplZCAobV9yZWVudHJ5R3VhcmQpCi0gICAgewotICAgICAgQ29udGVudEhhbmRsZXIgaGFuZGxlciA9IGNyZWF0ZVJlc3VsdENvbnRlbnRIYW5kbGVyKG91dHB1dFRhcmdldCk7Ci0KLSAgICAgIG1fb3V0cHV0VGFyZ2V0ID0gb3V0cHV0VGFyZ2V0OwotCi0gICAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICAgICAgdHJhbnNmb3JtKHhtbFNvdXJjZSwgc2hvdWxkUmVsZWFzZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgdGhlIHNvdXJjZSBub2RlIHRvIHRoZSBvdXRwdXQgcmVzdWx0LCBpZiB0aGUKLSAgICogcHJvY2Vzc29yIHN1cHBvcnRzIHRoZSAiaHR0cDovL3htbC5vcmcvdHJheC9mZWF0dXJlcy9kb20vaW5wdXQiCi0gICAqIGZlYXR1cmUuCi0gICAqICVSRVZJRVclIERvIHdlIG5lZWQgYSBOb2RlIHZlcnNpb24gb2YgdGhpcz8KLSAgICogQHBhcmFtIG5vZGUgIFRoZSBpbnB1dCBzb3VyY2Ugbm9kZSwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBEVE0gbm9kZS4KLSAgICogQHBhcmFtIG91dHB1dFRhcmdldCBUaGUgb3V0cHV0IHNvdXJjZSB0YXJnZXQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHRyYW5zZm9ybU5vZGUoaW50IG5vZGUsIFJlc3VsdCBvdXRwdXRUYXJnZXQpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIENvbnRlbnRIYW5kbGVyIGhhbmRsZXIgPSBjcmVhdGVSZXN1bHRDb250ZW50SGFuZGxlcihvdXRwdXRUYXJnZXQpOwotCi0gICAgbV9vdXRwdXRUYXJnZXQgPSBvdXRwdXRUYXJnZXQ7Ci0KLSAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotICAgIHRyYW5zZm9ybU5vZGUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvY2VzcyB0aGUgc291cmNlIG5vZGUgdG8gdGhlIG91dHB1dCByZXN1bHQsIGlmIHRoZQotICAgKiBwcm9jZXNzb3Igc3VwcG9ydHMgdGhlICJodHRwOi8veG1sLm9yZy90cmF4L2ZlYXR1cmVzL2RvbS9pbnB1dCIKLSAgICogZmVhdHVyZS4KLSAgICogJVJFVklFVyUgRG8gd2UgbmVlZCBhIE5vZGUgdmVyc2lvbiBvZiB0aGlzPwotICAgKiBAcGFyYW0gbm9kZSAgVGhlIGlucHV0IHNvdXJjZSBub2RlLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIERUTSBub2RlLgotICAgKiBAcGFyYW0gb3V0cHV0VGFyZ2V0IFRoZSBvdXRwdXQgc291cmNlIHRhcmdldC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhbnNmb3JtTm9kZShpbnQgbm9kZSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIE1ha2Ugc3VyZSB3ZSdyZSBub3Qgd3JpdGluZyB0byB0aGUgc2FtZSBvdXRwdXQgY29udGVudCBoYW5kbGVyLgotICAgIHN5bmNocm9uaXplZCAobV9vdXRwdXRDb250ZW50SGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2hhc0JlZW5SZXNldCA9IGZhbHNlOwotICAgICAgCi0gICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBnZXRYUGF0aENvbnRleHQoKTsKLSAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0obm9kZSk7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBwdXNoR2xvYmFsVmFycyhub2RlKTsKLQotICAgICAgICAvLyA9PT09PT09PT09Ci0gICAgICAgIC8vIEdpdmUgdGhlIHRvcC1sZXZlbCB0ZW1wbGF0ZXMgYSBjaGFuY2UgdG8gcGFzcyBpbmZvcm1hdGlvbiBpbnRvIAotICAgICAgICAvLyB0aGUgY29udGV4dCAodGhpcyBpcyBtYWlubHkgZm9yIHNldHRpbmcgdXAgdGFibGVzIGZvciBleHRlbnNpb25zKS4KLSAgICAgICAgU3R5bGVzaGVldFJvb3Qgc3R5bGVzaGVldCA9IHRoaXMuZ2V0U3R5bGVzaGVldCgpOwotICAgICAgICBpbnQgbiA9IHN0eWxlc2hlZXQuZ2V0R2xvYmFsSW1wb3J0Q291bnQoKTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIFN0eWxlc2hlZXRDb21wb3NlZCBpbXBvcnRlZCA9IHN0eWxlc2hlZXQuZ2V0R2xvYmFsSW1wb3J0KGkpOwotICAgICAgICAgIGludCBpbmNsdWRlZENvdW50ID0gaW1wb3J0ZWQuZ2V0SW5jbHVkZUNvdW50Q29tcG9zZWQoKTsKLQotICAgICAgICAgIGZvciAoaW50IGogPSAtMTsgaiA8IGluY2x1ZGVkQ291bnQ7IGorKykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTdHlsZXNoZWV0IGluY2x1ZGVkID0gaW1wb3J0ZWQuZ2V0SW5jbHVkZUNvbXBvc2VkKGopOwotCi0gICAgICAgICAgICBpbmNsdWRlZC5ydW50aW1lSW5pdCh0aGlzKTsKLQotICAgICAgICAgICAgZm9yIChFbGVtVGVtcGxhdGVFbGVtZW50IGNoaWxkID0gaW5jbHVkZWQuZ2V0Rmlyc3RDaGlsZEVsZW0oKTsKLSAgICAgICAgICAgICAgICAgICAgY2hpbGQgIT0gbnVsbDsgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZ0VsZW0oKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgY2hpbGQucnVudGltZUluaXQodGhpcyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8gPT09PT09PT09PT0KLSAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJDYWxsaW5nIGFwcGx5VGVtcGxhdGVUb05vZGUgLSAiK1RocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpKTsKLSAgICAgICAgRFRNSXRlcmF0b3IgZHRtSXRlciA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUoKTsKLSAgICAgICAgZHRtSXRlci5zZXRSb290KG5vZGUsIHhjdHh0KTsKLSAgICAgICAgeGN0eHQucHVzaENvbnRleHROb2RlTGlzdChkdG1JdGVyKTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICB0aGlzLmFwcGx5VGVtcGxhdGVUb05vZGUobnVsbCwgbnVsbCwgbm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWxseQotICAgICAgICB7Ci0gICAgICAgICAgeGN0eHQucG9wQ29udGV4dE5vZGVMaXN0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8gbV9zdHlsZXNoZWV0Um9vdC5nZXRTdGFydFJ1bGUoKS5leGVjdXRlKHRoaXMpOwotCi0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRG9uZSB3aXRoIGFwcGx5VGVtcGxhdGVUb05vZGUgLSAiK1RocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpKTsKLSAgICAgICAgaWYgKG51bGwgIT0gbV9yZXN1bHRUcmVlSGFuZGxlcikKLSAgICAgICAgewotICAgICAgICAgIG1fcmVzdWx0VHJlZUhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBzZSkKLSAgICAgIHsKLQotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkrIiB0aHJldyBhbiBleGNlcHRpb24hICIKLSAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgK3NlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIC8vIElmIGFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duLCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGFueSB3YWl0aW5nIAotICAgICAgICAvLyBoYW5kbGVycyBjYW4gdGVybWluYXRlLCB3aGljaCBJIGd1ZXNzIGlzIGJlc3QgZG9uZSBieSBzZW5kaW5nIAotICAgICAgICAvLyBhbiBlbmREb2N1bWVudC4KLSAgICAgICAgCi0gICAgICAgIC8vIFNBWFNvdXJjZUxvY2F0b3IKLSAgICAgICAgd2hpbGUoc2UgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbikKLSAgICAgICAgewotICAgICAgICAgIEV4Y2VwdGlvbiBlID0gKChvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbilzZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgICAgaWYobnVsbCAhPSBlKQotICAgICAgICAgICAgc2UgPSBlOwotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgICBpZiAobnVsbCAhPSBtX3Jlc3VsdFRyZWVIYW5kbGVyKQotICAgICAgICB7Ci0gICAgICAgICAgdHJ5Ci0gICAgICAgICAgewotICAgICAgICAgICAgaWYoc2UgaW5zdGFuY2VvZiBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbikKLSAgICAgICAgICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlci5mYXRhbEVycm9yKChvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbilzZSk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIG1fcmVzdWx0VHJlZUhhbmRsZXIuZmF0YWxFcnJvcihuZXcgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpLCBuZXcgU0FYU291cmNlTG9jYXRvcigpLCBzZSkpOyAgICAgICAgICAgICAgCi0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSl7fQotICAgICAgICB9ICAgICAgICAKLSAgICAgICAgCi0gICAgICAgIGlmKHNlIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICAgIHsKLSAgICAgICAgICBtX2Vycm9ySGFuZGxlci5mYXRhbEVycm9yKChUcmFuc2Zvcm1lckV4Y2VwdGlvbilzZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZihzZSBpbnN0YW5jZW9mIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAgICB7Ci0gICAgICAgICAgbV9lcnJvckhhbmRsZXIuZmF0YWxFcnJvcihuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpLCAKLSAgICAgICAgICAgICAgICAgICAgICBuZXcgU0FYU291cmNlTG9jYXRvcigob3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24pc2UpLCAKLSAgICAgICAgICAgICAgICAgICAgICBzZSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG1fZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKSk7Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICB9Ci0gICAgICBmaW5hbGx5Ci0gICAgICB7Ci0gICAgICAgIHRoaXMucmVzZXQoKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgU0FYMiBDb250ZW50SGFuZGxlciBmb3IgdGhlIGlucHV0LgotICAgKgotICAgKiBAcmV0dXJuIEEgdmFsaWQgQ29udGVudEhhbmRsZXIsIHdoaWNoIHNob3VsZCBuZXZlciBiZSBudWxsLCBhcwotICAgKiBsb25nIGFzIGdldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3RyYXgvZmVhdHVyZXMvc2F4L2lucHV0IikKLSAgICogcmV0dXJucyB0cnVlLgotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldElucHV0Q29udGVudEhhbmRsZXIoKQotICB7Ci0gICAgcmV0dXJuIGdldElucHV0Q29udGVudEhhbmRsZXIoZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIFNBWDIgQ29udGVudEhhbmRsZXIgZm9yIHRoZSBpbnB1dC4KLSAgICoKLSAgICogQHBhcmFtIGRvRG9jRnJhZyB0cnVlIGlmIGEgRG9jdW1lbnRGcmFnbWVudCBzaG91bGQgYmUgY3JlYXRlZCBhcwotICAgKiB0aGUgcm9vdCwgcmF0aGVyIHRoYW4gYSBEb2N1bWVudC4KLSAgICoKLSAgICogQHJldHVybiBBIHZhbGlkIENvbnRlbnRIYW5kbGVyLCB3aGljaCBzaG91bGQgbmV2ZXIgYmUgbnVsbCwgYXMKLSAgICogbG9uZyBhcyBnZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy90cmF4L2ZlYXR1cmVzL3NheC9pbnB1dCIpCi0gICAqIHJldHVybnMgdHJ1ZS4KLSAgICovCi0gIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRJbnB1dENvbnRlbnRIYW5kbGVyKGJvb2xlYW4gZG9Eb2NGcmFnKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2lucHV0Q29udGVudEhhbmRsZXIpCi0gICAgewotCi0gICAgICAvLyAgICAgIGlmKG51bGwgPT0gbV91cmxPZlNvdXJjZSAmJiBudWxsICE9IG1fc3R5bGVzaGVldFJvb3QpCi0gICAgICAvLyAgICAgICAgbV91cmxPZlNvdXJjZSA9IG1fc3R5bGVzaGVldFJvb3QuZ2V0QmFzZUlkZW50aWZpZXIoKTsKLSAgICAgIG1faW5wdXRDb250ZW50SGFuZGxlciA9IG5ldyBUcmFuc2Zvcm1lckhhbmRsZXJJbXBsKHRoaXMsIGRvRG9jRnJhZywKLSAgICAgICAgICAgICAgbV91cmxPZlNvdXJjZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG1faW5wdXRDb250ZW50SGFuZGxlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBTQVgyIERlY2xIYW5kbGVyIGZvciB0aGUgaW5wdXQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBEZWNsSGFuZGxlciwgd2hpY2ggc2hvdWxkIG5ldmVyIGJlIG51bGwsIGFzCi0gICAqIGxvbmcgYXMgZ2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvdHJheC9mZWF0dXJlcy9zYXgvaW5wdXQiKQotICAgKiByZXR1cm5zIHRydWUuCi0gICAqLwotICBwdWJsaWMgRGVjbEhhbmRsZXIgZ2V0SW5wdXREZWNsSGFuZGxlcigpCi0gIHsKLQotICAgIGlmIChtX2lucHV0Q29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBEZWNsSGFuZGxlcikKLSAgICAgIHJldHVybiAoRGVjbEhhbmRsZXIpIG1faW5wdXRDb250ZW50SGFuZGxlcjsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBTQVgyIExleGljYWxIYW5kbGVyIGZvciB0aGUgaW5wdXQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBMZXhpY2FsSGFuZGxlciwgd2hpY2ggc2hvdWxkIG5ldmVyIGJlIG51bGwsIGFzCi0gICAqIGxvbmcgYXMgZ2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvdHJheC9mZWF0dXJlcy9zYXgvaW5wdXQiKQotICAgKiByZXR1cm5zIHRydWUuCi0gICAqLwotICBwdWJsaWMgTGV4aWNhbEhhbmRsZXIgZ2V0SW5wdXRMZXhpY2FsSGFuZGxlcigpCi0gIHsKLQotICAgIGlmIChtX2lucHV0Q29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHJldHVybiAoTGV4aWNhbEhhbmRsZXIpIG1faW5wdXRDb250ZW50SGFuZGxlcjsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uICBUaGVzZQotICAgKiBwcm9wZXJ0aWVzIHdpbGwgb3ZlcnJpZGUgcHJvcGVydGllcyBzZXQgaW4gdGhlIHRlbXBsYXRlcwotICAgKiB3aXRoIHhzbDpvdXRwdXQuCi0gICAqCi0gICAqIEBwYXJhbSBvZm9ybWF0IEEgdmFsaWQgT3V0cHV0UHJvcGVydGllcyBvYmplY3QgKHdoaWNoIHdpbGwKLSAgICogbm90IGJlIG11dGF0ZWQpLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0T3V0cHV0Rm9ybWF0KE91dHB1dFByb3BlcnRpZXMgb2Zvcm1hdCkKLSAgewotICAgIG1fb3V0cHV0Rm9ybWF0ID0gb2Zvcm1hdDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIHVzZWQgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgb3V0cHV0IGZvcm1hdCB0aGF0IHdhcyBzZXQgYnkgdGhlIHVzZXIsCi0gICAqIG90aGVyd2lzZSB0aGUgb3V0cHV0IGZvcm1hdCBmcm9tIHRoZSBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIE91dHB1dFByb3BlcnRpZXMgZ2V0T3V0cHV0Rm9ybWF0KCkKLSAgewotCi0gICAgLy8gR2V0IHRoZSBvdXRwdXQgZm9ybWF0IHRoYXQgd2FzIHNldCBieSB0aGUgdXNlciwgb3RoZXJ3aXNlIGdldCB0aGUgCi0gICAgLy8gb3V0cHV0IGZvcm1hdCBmcm9tIHRoZSBzdHlsZXNoZWV0LgotICAgIE91dHB1dFByb3BlcnRpZXMgZm9ybWF0ID0gKG51bGwgPT0gbV9vdXRwdXRGb3JtYXQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGdldFN0eWxlc2hlZXQoKS5nZXRPdXRwdXRDb21wb3NlZCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG1fb3V0cHV0Rm9ybWF0OwotCi0gICAgcmV0dXJuIGZvcm1hdDsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSBjdXJyZW50IHNlcmlhbGl6ZXIgaW4gdXNlLCB3aGljaCBtYXkgd2VsbCBub3QKLSAgICogYmUgdGhlIG1haW4gc2VyaWFsaXplciAoZm9yIGluc3RhbmNlLCB0aGlzIG1heSB3ZWxsIGJlCi0gICAqIGEgdGV4dCBzZXJpYWxpemVyIGZvciBzdHJpbmcgY3JlYXRpb24gZnJvbSB0ZW1wbGF0ZXMpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHNlcmlhbGl6ZXIsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBTZXJpYWxpemVyIGdldFNlcmlhbGl6ZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fc2VyaWFsaXplcjsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogU2V0IHRoZSBjdXJyZW50IHNlcmlhbGl6ZXIuCi0gICAqCi0gICAqIEBwYXJhbSBzIFRoZSBjdXJyZW50IHNlcmlhbGl6ZXIsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTZXJpYWxpemVyKFNlcmlhbGl6ZXIgcykKLSAgewotICAgIG1fc2VyaWFsaXplciA9IHM7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgYSBwYXJhbWV0ZXIgZm9yIHRoZSB0ZW1wbGF0ZXMuCi0gICAqIAotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIHBhcmFtZXRlci4KLSAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvYmplY3QuICBUaGlzIGNhbiBiZSBhbnkgdmFsaWQgSmF2YSBvYmplY3QKLSAgICogLS0gaXQncyB1cCB0byB0aGUgcHJvY2Vzc29yIHRvIHByb3ZpZGUgdGhlIHByb3BlcgotICAgKiBjb2Vyc2lvbiB0byB0aGUgb2JqZWN0LCBvciBzaW1wbHkgcGFzcyBpdCBvbiBmb3IgdXNlCi0gICAqIGluIGV4dGVuc2lvbnMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBuYW1lc3BhY2UsIE9iamVjdCB2YWx1ZSkKLSAgewotCi0gICAgVmFyaWFibGVTdGFjayB2YXJzdGFjayA9IGdldFhQYXRoQ29udGV4dCgpLmdldFZhclN0YWNrKCk7Ci0gICAgUU5hbWUgcW5hbWUgPSBuZXcgUU5hbWUobmFtZXNwYWNlLCBuYW1lKTsKLSAgICBYT2JqZWN0IHhvYmplY3QgPSBYT2JqZWN0LmNyZWF0ZSh2YWx1ZSwgZ2V0WFBhdGhDb250ZXh0KCkpOwotICAgIAotICAgIFN0eWxlc2hlZXRSb290IHNyb290ID0gbV9zdHlsZXNoZWV0Um9vdDsKLSAgICBWZWN0b3IgdmFycyA9IHNyb290LmdldFZhcmlhYmxlc0FuZFBhcmFtc0NvbXBvc2VkKCk7Ci0gICAgaW50IGkgPSB2YXJzLnNpemUoKTsKLSAgICB3aGlsZSAoLS1pID49IDApCi0gICAgewotICAgICAgRWxlbVZhcmlhYmxlIHZhcmlhYmxlID0gKEVsZW1WYXJpYWJsZSl2YXJzLmVsZW1lbnRBdChpKTsKLSAgICAgIGlmKHZhcmlhYmxlLmdldFhTTFRva2VuKCkgPT0gQ29uc3RhbnRzLkVMRU1OQU1FX1BBUkFNVkFSSUFCTEUgJiYgCi0gICAgICAgICB2YXJpYWJsZS5nZXROYW1lKCkuZXF1YWxzKHFuYW1lKSkKLSAgICAgIHsKLSAgICAgICAgICB2YXJzdGFjay5zZXRHbG9iYWxWYXJpYWJsZShpLCB4b2JqZWN0KTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKiogTkVFRFNET0MgRmllbGQgbV91c2VyUGFyYW1zICAgICAgICAgICovCi0gIFZlY3RvciBtX3VzZXJQYXJhbXM7Ci0KLSAgLyoqCi0gICAqIFNldCBhIHBhcmFtZXRlciBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLAotICAgKiAgICAgICAgICAgICB3aGljaCBtYXkgaGF2ZSBhIG5hbWVzcGFjZSBVUkkuCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb2JqZWN0LiAgVGhpcyBjYW4gYmUgYW55IHZhbGlkIEphdmEgb2JqZWN0Ci0gICAqIC0tIGl0J3MgdXAgdG8gdGhlIHByb2Nlc3NvciB0byBwcm92aWRlIHRoZSBwcm9wZXIKLSAgICogY29lcnNpb24gdG8gdGhlIG9iamVjdCwgb3Igc2ltcGx5IHBhc3MgaXQgb24gZm9yIHVzZQotICAgKiBpbiBleHRlbnNpb25zLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpCi0gIHsKLQotICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgU3RyaW5nVG9rZW5pemVyKG5hbWUsICJ7fSIsIGZhbHNlKTsKLQotICAgIHRyeQotICAgIHsKLQotICAgICAgLy8gVGhlIGZpcnN0IHN0cmluZyBtaWdodCBiZSB0aGUgbmFtZXNwYWNlLCBvciBpdCBtaWdodCBiZSAKLSAgICAgIC8vIHRoZSBsb2NhbCBuYW1lLCBpZiB0aGUgbmFtZXNwYWNlIGlzIG51bGwuCi0gICAgICBTdHJpbmcgczEgPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7Ci0gICAgICBTdHJpbmcgczIgPSB0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpID8gdG9rZW5pemVyLm5leHRUb2tlbigpIDogbnVsbDsKLQotICAgICAgaWYgKG51bGwgPT0gbV91c2VyUGFyYW1zKQotICAgICAgICBtX3VzZXJQYXJhbXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAgIGlmIChudWxsID09IHMyKQotICAgICAgewotICAgICAgICByZXBsYWNlT3JQdXNoVXNlclBhcmFtKG5ldyBRTmFtZShzMSksIFhPYmplY3QuY3JlYXRlKHZhbHVlLCBnZXRYUGF0aENvbnRleHQoKSkpOwotICAgICAgICBzZXRQYXJhbWV0ZXIoczEsIG51bGwsIHZhbHVlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcmVwbGFjZU9yUHVzaFVzZXJQYXJhbShuZXcgUU5hbWUoczEsIHMyKSwgWE9iamVjdC5jcmVhdGUodmFsdWUsIGdldFhQYXRoQ29udGV4dCgpKSk7Ci0gICAgICAgIHNldFBhcmFtZXRlcihzMiwgczEsIHZhbHVlKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIG5zZWUpCi0gICAgewotCi0gICAgICAvLyBTaG91bGQgdGhyb3cgc29tZSBzb3J0IG9mIGFuIGVycm9yLgotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBORUVEU0RPQyBNZXRob2QgcmVwbGFjZU9yUHVzaFVzZXJQYXJhbSAKLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHFuYW1lCi0gICAqIE5FRURTRE9DIEBwYXJhbSB4dmFsCi0gICAqLwotICBwcml2YXRlIHZvaWQgcmVwbGFjZU9yUHVzaFVzZXJQYXJhbShRTmFtZSBxbmFtZSwgWE9iamVjdCB4dmFsKQotICB7Ci0KLSAgICBpbnQgbiA9IG1fdXNlclBhcmFtcy5zaXplKCk7Ci0KLSAgICBmb3IgKGludCBpID0gbiAtIDE7IGkgPj0gMDsgaS0tKQotICAgIHsKLSAgICAgIEFyZyBhcmcgPSAoQXJnKSBtX3VzZXJQYXJhbXMuZWxlbWVudEF0KGkpOwotCi0gICAgICBpZiAoYXJnLmdldFFOYW1lKCkuZXF1YWxzKHFuYW1lKSkKLSAgICAgIHsKLSAgICAgICAgbV91c2VyUGFyYW1zLnNldEVsZW1lbnRBdChuZXcgQXJnKHFuYW1lLCB4dmFsLCB0cnVlKSwgaSk7Ci0KLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotICAgIH0KLQotICAgIG1fdXNlclBhcmFtcy5hZGRFbGVtZW50KG5ldyBBcmcocW5hbWUsIHh2YWwsIHRydWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBwYXJhbWV0ZXIgdGhhdCB3YXMgZXhwbGljaXRseSBzZXQgd2l0aCBzZXRQYXJhbWV0ZXIKLSAgICogb3Igc2V0UGFyYW1ldGVycy4KLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIG5hbWUKLSAgICogQHJldHVybiBBIHBhcmFtZXRlciB0aGF0IGhhcyBiZWVuIHNldCB3aXRoIHNldFBhcmFtZXRlcgotICAgKiBvciBzZXRQYXJhbWV0ZXJzLAotICAgKiAqbm90KiBhbGwgdGhlIHhzbDpwYXJhbXMgb24gdGhlIHN0eWxlc2hlZXQgKHdoaWNoIHJlcXVpcmUKLSAgICogYSB0cmFuc2Zvcm1hdGlvbiBTb3VyY2UgdG8gYmUgZXZhbHVhdGVkKS4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIFZhcmlhYmxlU3RhY2sgdmFyc3RhY2sgPSBnZXRYUGF0aENvbnRleHQoKS5nZXRWYXJTdGFjaygpOwotICAgICAgLy8gVGhlIGZpcnN0IHN0cmluZyBtaWdodCBiZSB0aGUgbmFtZXNwYWNlLCBvciBpdCBtaWdodCBiZSAKLSAgICAgIC8vIHRoZSBsb2NhbCBuYW1lLCBpZiB0aGUgbmFtZXNwYWNlIGlzIG51bGwuCi0gICAgICBRTmFtZSBxbmFtZSA9IFFOYW1lLmdldFFOYW1lRnJvbVN0cmluZyhuYW1lKTsKLQotICAgICAgaWYgKG51bGwgPT0gbV91c2VyUGFyYW1zKQotICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgaW50IG4gPSBtX3VzZXJQYXJhbXMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gbiAtIDE7IGkgPj0gMDsgaS0tKQotICAgICAgewotICAgICAgICBBcmcgYXJnID0gKEFyZykgbV91c2VyUGFyYW1zLmVsZW1lbnRBdChpKTsKLQotICAgICAgICBpZiAoYXJnLmdldFFOYW1lKCkuZXF1YWxzKHFuYW1lKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBhcmcuZ2V0VmFsKCkub2JqZWN0KCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIGNhdGNoIChqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBuc2VlKQotICAgIHsKLQotICAgICAgLy8gU2hvdWxkIHRocm93IHNvbWUgc29ydCBvZiBhbiBlcnJvci4KLSAgICAgIHJldHVybiBudWxsOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYSBiYWcgb2YgcGFyYW1ldGVycyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiBOb3RlIHRoYXQKLSAgICogdGhlc2Ugd2lsbCBub3QgYmUgYWRkaXRpdmUsIHRoZXkgd2lsbCByZXBsYWNlIHRoZSBleGlzdGluZwotICAgKiBzZXQgb2YgcGFyYW1ldGVycy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciwKLSAgICogICAgICAgICAgICAgd2hpY2ggbWF5IGhhdmUgYSBuYW1lc3BhY2UgVVJJLgotICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9iamVjdC4gIFRoaXMgY2FuIGJlIGFueSB2YWxpZCBKYXZhIG9iamVjdAotICAgKiAtLSBpdCdzIHVwIHRvIHRoZSBwcm9jZXNzb3IgdG8gcHJvdmlkZSB0aGUgcHJvcGVyCi0gICAqIGNvZXJzaW9uIHRvIHRoZSBvYmplY3QsIG9yIHNpbXBseSBwYXNzIGl0IG9uIGZvciB1c2UKLSAgICogaW4gZXh0ZW5zaW9ucy4KLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHBhcmFtcwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGFyYW1ldGVycyhQcm9wZXJ0aWVzIHBhcmFtcykKLSAgewotCi0gICAgY2xlYXJQYXJhbWV0ZXJzKCk7Ci0KLSAgICBFbnVtZXJhdGlvbiBuYW1lcyA9IHBhcmFtcy5wcm9wZXJ0eU5hbWVzKCk7Ci0KLSAgICB3aGlsZSAobmFtZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgewotICAgICAgU3RyaW5nIG5hbWUgPSBwYXJhbXMuZ2V0UHJvcGVydHkoKFN0cmluZykgbmFtZXMubmV4dEVsZW1lbnQoKSk7Ci0gICAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihuYW1lLCAie30iLCBmYWxzZSk7Ci0KLSAgICAgIHRyeQotICAgICAgewotCi0gICAgICAgIC8vIFRoZSBmaXJzdCBzdHJpbmcgbWlnaHQgYmUgdGhlIG5hbWVzcGFjZSwgb3IgaXQgbWlnaHQgYmUgCi0gICAgICAgIC8vIHRoZSBsb2NhbCBuYW1lLCBpZiB0aGUgbmFtZXNwYWNlIGlzIG51bGwuCi0gICAgICAgIFN0cmluZyBzMSA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICAgICAgU3RyaW5nIHMyID0gdG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKSA/IHRva2VuaXplci5uZXh0VG9rZW4oKSA6IG51bGw7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gczIpCi0gICAgICAgICAgc2V0UGFyYW1ldGVyKHMxLCBudWxsLCBwYXJhbXMuZ2V0UHJvcGVydHkobmFtZSkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgc2V0UGFyYW1ldGVyKHMyLCBzMSwgcGFyYW1zLmdldFByb3BlcnR5KG5hbWUpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBuc2VlKQotICAgICAgewotCi0gICAgICAgIC8vIFNob3VsZCB0aHJvdyBzb21lIHNvcnQgb2YgYW4gZXJyb3IuCi0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBwYXJhbWV0ZXJzIHRvIGEgbnVsbCBsaXN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCkKLSAgewotCi0gICAgc3luY2hyb25pemVkIChtX3JlZW50cnlHdWFyZCkKLSAgICB7Ci0gICAgICBWYXJpYWJsZVN0YWNrIHZhcnN0YWNrID0gbmV3IFZhcmlhYmxlU3RhY2soKTsKLQotICAgICAgbV94Y29udGV4dC5zZXRWYXJTdGFjayh2YXJzdGFjayk7Ci0KLSAgICAgIG1fdXNlclBhcmFtcyA9IG51bGw7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogSW50ZXJuYWwgLS0gcHVzaCB0aGUgZ2xvYmFsIHZhcmlhYmxlcyBmcm9tIHRoZSBTdHlsZXNoZWV0IG9udG8KLSAgICogdGhlIGNvbnRleHQncyBydW50aW1lIHZhcmlhYmxlIHN0YWNrLgotICAgKiA8cD5JZiB3ZSBlbmNvdW50ZXIgYSB2YXJpYWJsZQotICAgKiB0aGF0IGlzIGFscmVhZHkgZGVmaW5lZCBpbiB0aGUgdmFyaWFibGUgc3RhY2ssIHdlIGlnbm9yZSBpdC4gIFRoaXMKLSAgICogaXMgYmVjYXVzZSB0aGUgc2Vjb25kIHZhcmlhYmxlIGRlZmluaXRpb24gd2lsbCBiZSBhdCBhIGxvd2VyIGltcG9ydAotICAgKiBwcmVjZWRlbmNlLiAgUHJlc3VtYWJseSwgZ2xvYmFsIHZhcmlhYmxlcyBhdCB0aGUgc2FtZSBpbXBvcnQgcHJlY2VkZW5jZQotICAgKiB3aXRoIHRoZSBzYW1lIG5hbWUgd2lsbCBoYXZlIGJlZW4gY2F1Z2h0IGR1cmluZyB0aGUgcmVjb21wb3NlIHByb2Nlc3MuCi0gICAqIDxwPkhvd2V2ZXIsIGlmIHdlIGVuY291bnRlciBhIHBhcmFtZXRlciB0aGF0IGlzIGFscmVhZHkgZGVmaW5lZCBpbiB0aGUKLSAgICogdmFyaWFibGUgc3RhY2ssIHdlIG5lZWQgdG8gc2VlIGlmIHRoaXMgaXMgYSBwYXJhbWV0ZXIgd2hvc2UgdmFsdWUgd2FzCi0gICAqIHN1cHBsaWVkIGJ5IGEgc2V0UGFyYW1ldGVyIGNhbGwuICBJZiBzbywgd2UgbmVlZCB0byAicmVjZWl2ZSIgdGhlIG9uZQotICAgKiBhbHJlYWR5IGluIHRoZSBzdGFjaywgaWdub3JpbmcgdGhpcyBvbmUuICBJZiBpdCBpcyBqdXN0IGFuIGVhcmxpZXIKLSAgICogeHNsOnBhcmFtIG9yIHhzbDp2YXJpYWJsZSBkZWZpbml0aW9uLCB3ZSBpZ25vcmUgaXQgdXNpbmcgdGhlIHNhbWUKLSAgICogcmVhc29uaW5nIGFzIGV4cGxhaW5lZCBhYm92ZSBmb3IgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlLCBjYW4ndCBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBwdXNoR2xvYmFsVmFycyhpbnQgY29udGV4dE5vZGUpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBtX3hjb250ZXh0OwotICAgIFZhcmlhYmxlU3RhY2sgdnMgPSB4Y3R4dC5nZXRWYXJTdGFjaygpOwotICAgIFN0eWxlc2hlZXRSb290IHNyID0gZ2V0U3R5bGVzaGVldCgpOwotICAgIFZlY3RvciB2YXJzID0gc3IuZ2V0VmFyaWFibGVzQW5kUGFyYW1zQ29tcG9zZWQoKTsKLSAgICAKLSAgICBpbnQgaSA9IHZhcnMuc2l6ZSgpOwotICAgIHZzLmxpbmsoaSk7Ci0KLSAgICB3aGlsZSAoLS1pID49IDApCi0gICAgewotICAgICAgRWxlbVZhcmlhYmxlIHYgPSAoRWxlbVZhcmlhYmxlKSB2YXJzLmVsZW1lbnRBdChpKTsKLQotICAgICAgLy8gWE9iamVjdCB4b2JqID0gdi5nZXRWYWx1ZSh0aGlzLCBjb250ZXh0Tm9kZSk7Ci0gICAgICBYT2JqZWN0IHhvYmogPSBuZXcgWFVucmVzb2x2ZWRWYXJpYWJsZSh2LCBjb250ZXh0Tm9kZSwgdGhpcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cy5nZXRTdGFja0ZyYW1lKCksIDAsIHRydWUpOwotICAgICAgCi0gICAgICBpZihudWxsID09IHZzLmVsZW1lbnRBdChpKSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgIHZzLnNldEdsb2JhbFZhcmlhYmxlKGksIHhvYmopOwotICAgIH0KLQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogZG9jdW1lbnQoKSwgZXRjLgotICAgKiBAcGFyYW0gcmVzb2x2ZXIgQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAotICAgKiBvciBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpCi0gIHsKLQotICAgIHN5bmNocm9uaXplZCAobV9yZWVudHJ5R3VhcmQpCi0gICAgewotICAgICAgbV94Y29udGV4dC5nZXRTb3VyY2VUcmVlTWFuYWdlcigpLnNldFVSSVJlc29sdmVyKHJlc29sdmVyKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIG9iamVjdCB0aGF0IHdpbGwgYmUgdXNlZCB0byByZXNvbHZlIFVSSXMgdXNlZCBpbgotICAgKiBkb2N1bWVudCgpLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAotICAgKiBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkKLSAgewotICAgIHJldHVybiBtX3hjb250ZXh0LmdldFNvdXJjZVRyZWVNYW5hZ2VyKCkuZ2V0VVJJUmVzb2x2ZXIoKTsKLSAgfQotCi0gIC8vID09PT09PT09IEVuZCBUcmFuc2Zvcm1lciBJbXBsZW1lbnRhdGlvbiA9PT09PT09PSAgCi0KLSAgLyoqCi0gICAqIFNldCB0aGUgY29udGVudCBldmVudCBoYW5kbGVyLgotICAgKgotICAgKiBAcGFyYW0gcmVzb2x2ZXIgVGhlIG5ldyBjb250ZW50IGhhbmRsZXIuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBoYW5kbGVyCi0gICAqIEB0aHJvd3MgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIElmIHRoZSBoYW5kbGVyCi0gICAqICAgICAgICAgICAgaXMgbnVsbC4KLSAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjc2V0Q29udGVudEhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLQotICAgIGlmIChoYW5kbGVyID09IG51bGwpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05VTExfQ09OVEVOVF9IQU5ETEVSLCBudWxsKSk7IC8vIk51bGwgY29udGVudCBoYW5kbGVyIik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX291dHB1dENvbnRlbnRIYW5kbGVyID0gaGFuZGxlcjsKLQotICAgICAgaWYgKG51bGwgPT0gbV9yZXN1bHRUcmVlSGFuZGxlcikKLSAgICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlciA9IG5ldyBSZXN1bHRUcmVlSGFuZGxlcih0aGlzLCBoYW5kbGVyKTsKLSAgICAgIGVsc2UKLSAgICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjb250ZW50IGV2ZW50IGhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgY29udGVudCBoYW5kbGVyLCBvciBudWxsIGlmIG5vbmUgd2FzIHNldC4KLSAgICogQHNlZSBvcmcueG1sLnNheC5YTUxSZWFkZXIjZ2V0Q29udGVudEhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpCi0gIHsKLSAgICByZXR1cm4gbV9vdXRwdXRDb250ZW50SGFuZGxlcjsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogR2l2ZW4gYSBzdHlsZXNoZWV0IGVsZW1lbnQsIGNyZWF0ZSBhIHJlc3VsdCB0cmVlIGZyYWdtZW50IGZyb20gaXQncwotICAgKiBjb250ZW50cy4KLSAgICogQHBhcmFtIHRlbXBsYXRlUGFyZW50IFRoZSB0ZW1wbGF0ZSBlbGVtZW50IHRoYXQgaG9sZHMgdGhlIGZyYWdtZW50LgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBUaGUgY3VycmVudCBzb3VyY2UgY29udGV4dCBub2RlLgotICAgKiBAcGFyYW0gbW9kZSBUaGUgbW9kZSB1bmRlciB3aGljaCB0aGUgdGVtcGxhdGUgaXMgb3BlcmF0aW5nLgotICAgKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgaW50IHRyYW5zZm9ybVRvUlRGKEVsZW1UZW1wbGF0ZUVsZW1lbnQgdGVtcGxhdGVQYXJlbnQpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG1feGNvbnRleHQ7Ci0gICAgRFRNIGR0bUZyYWcgPSB4Y3R4dC5nZXREVE0obnVsbCwgdHJ1ZSwgdGhpcywgZmFsc2UsIGZhbHNlKTsKLSAgICBDb250ZW50SGFuZGxlciBydGZIYW5kbGVyID0gZHRtRnJhZy5nZXRDb250ZW50SGFuZGxlcigpOwotCi0gICAgLy8gQ3JlYXRlIGEgUmVzdWx0VHJlZUZyYWcgb2JqZWN0LgotICAgIGludCByZXN1bHRGcmFnbWVudCA9IHJlc3VsdEZyYWdtZW50ID0gZHRtRnJhZy5nZXREb2N1bWVudCgpOwotCi0gICAgLy8gU2F2ZSB0aGUgY3VycmVudCByZXN1bHQgdHJlZSBoYW5kbGVyLgotICAgIFJlc3VsdFRyZWVIYW5kbGVyIHNhdmVkUlRyZWVIYW5kbGVyID0gdGhpcy5tX3Jlc3VsdFRyZWVIYW5kbGVyOwotCi0gICAgLy8gQW5kIG1ha2UgYSBuZXcgaGFuZGxlciBmb3IgdGhlIFJURi4KLSAgICBtX3Jlc3VsdFRyZWVIYW5kbGVyID0gbmV3IFJlc3VsdFRyZWVIYW5kbGVyKHRoaXMsIHJ0ZkhhbmRsZXIpOwotCi0gICAgUmVzdWx0VHJlZUhhbmRsZXIgcnRoID0gbV9yZXN1bHRUcmVlSGFuZGxlcjsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHJ0aC5zdGFydERvY3VtZW50KCk7Ci0KLSAgICAgIHRyeQotICAgICAgewotCi0gICAgICAgIC8vIERvIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgY2hpbGQgZWxlbWVudHMuCi0gICAgICAgIGV4ZWN1dGVDaGlsZFRlbXBsYXRlcyh0ZW1wbGF0ZVBhcmVudCwgdHJ1ZSk7Ci0KLSAgICAgICAgLy8gTWFrZSBzdXJlIGV2ZXJ5dGhpbmcgaXMgZmx1c2hlZCEKLSAgICAgICAgcnRoLmZsdXNoUGVuZGluZygpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBydGguZW5kRG9jdW1lbnQoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotCi0gICAgICAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyByZXN1bHQgdHJlZSBoYW5kbGVyLgotICAgICAgdGhpcy5tX3Jlc3VsdFRyZWVIYW5kbGVyID0gc2F2ZWRSVHJlZUhhbmRsZXI7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdEZyYWdtZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBHZXQgdGhlIFN0cmluZ1dyaXRlciBwb29sLCBzbyB0aGF0IFN0cmluZ1dyaXRlcgotICAgKiBvYmplY3RzIG1heSBiZSByZXVzZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB3cml0ZXIgcG9vbCwgbm90IG51bGwuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0UG9vbCBnZXRTdHJpbmdXcml0ZXJQb29sKCkKLSAgewotICAgIHJldHVybiBtX3N0cmluZ1dyaXRlck9iamVjdFBvb2w7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRha2UgdGhlIGNvbnRlbnRzIG9mIGEgdGVtcGxhdGUgZWxlbWVudCwgcHJvY2VzcyBpdCwgYW5kCi0gICAqIGNvbnZlcnQgaXQgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIFRoZSBwYXJlbnQgZWxlbWVudCB3aG9zZSBjaGlsZHJlbiB3aWxsIGJlIG91dHB1dAotICAgKiBhcyBhIHN0cmluZy4KLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIFRoZSBYU0xUIHRyYW5zZm9ybWVyIGluc3RhbmNlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBUaGUgY3VycmVudCBzb3VyY2Ugbm9kZSBjb250ZXh0LgotICAgKiBAcGFyYW0gbW9kZSBUaGUgY3VycmVudCB4c2x0IG1vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZ2l6ZWQgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGUgZWxlbWVudHMgY2hpbGRyZW4uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdHJhbnNmb3JtVG9TdHJpbmcoRWxlbVRlbXBsYXRlRWxlbWVudCBlbGVtKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCBmaXJzdENoaWxkID0gZWxlbS5nZXRGaXJzdENoaWxkRWxlbSgpOwotICAgIGlmKG51bGwgPT0gZmlyc3RDaGlsZCkKLSAgICAgIHJldHVybiAiIjsKLSAgICBpZihlbGVtLmhhc1RleHRMaXRPbmx5KCkgJiYgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5tX29wdGltaXplKQotICAgIHsKLSAgICAgIHJldHVybiAoKEVsZW1UZXh0TGl0ZXJhbClmaXJzdENoaWxkKS5nZXROb2RlVmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvLyBTYXZlIHRoZSBjdXJyZW50IHJlc3VsdCB0cmVlIGhhbmRsZXIuCi0gICAgUmVzdWx0VHJlZUhhbmRsZXIgc2F2ZWRSVHJlZUhhbmRsZXIgPSB0aGlzLm1fcmVzdWx0VHJlZUhhbmRsZXI7Ci0KLSAgICAvLyBDcmVhdGUgYSBTZXJpYWxpemVyIG9iamVjdCB0aGF0IHdpbGwgaGFuZGxlIHRoZSBTQVggZXZlbnRzIAotICAgIC8vIGFuZCBidWlsZCB0aGUgUmVzdWx0VHJlZUZyYWcgbm9kZXMuCi0gICAgU3RyaW5nV3JpdGVyIHN3ID0gKFN0cmluZ1dyaXRlcikgbV9zdHJpbmdXcml0ZXJPYmplY3RQb29sLmdldEluc3RhbmNlKCk7Ci0KLSAgICBtX3Jlc3VsdFRyZWVIYW5kbGVyID0KLSAgICAgIChSZXN1bHRUcmVlSGFuZGxlcikgbV90ZXh0UmVzdWx0SGFuZGxlck9iamVjdFBvb2wuZ2V0SW5zdGFuY2UoKTsKLQotICAgIFNlcmlhbGl6ZXIgc2VyaWFsaXplciA9IG1fcmVzdWx0VHJlZUhhbmRsZXIuZ2V0U2VyaWFsaXplcigpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKG51bGwgPT0gc2VyaWFsaXplcikKLSAgICAgIHsKLSAgICAgICAgc2VyaWFsaXplciA9Ci0gICAgICAgICAgU2VyaWFsaXplckZhY3RvcnkuZ2V0U2VyaWFsaXplcihtX3RleHRmb3JtYXQuZ2V0UHJvcGVydGllcygpKTsKLQotICAgICAgICBtX3Jlc3VsdFRyZWVIYW5kbGVyLnNldFNlcmlhbGl6ZXIoc2VyaWFsaXplcik7Ci0gICAgICAgIHNlcmlhbGl6ZXIuc2V0V3JpdGVyKHN3KTsKLQotICAgICAgICBDb250ZW50SGFuZGxlciBzaGFuZGxlciA9IHNlcmlhbGl6ZXIuYXNDb250ZW50SGFuZGxlcigpOwotCi0gICAgICAgIG1fcmVzdWx0VHJlZUhhbmRsZXIuaW5pdCh0aGlzLCBzaGFuZGxlcik7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gTGVhdmUgQ29tbWVudGVkLiAgLXNiCi0gICAgICAgIC8vIHNlcmlhbGl6ZXIuc2V0V3JpdGVyKHN3KTsKLSAgICAgICAgLy8gc2VyaWFsaXplci5zZXRPdXRwdXRGb3JtYXQobV90ZXh0Zm9ybWF0KTsKLSAgICAgICAgLy8gQ29udGVudEhhbmRsZXIgc2hhbmRsZXIgPSBzZXJpYWxpemVyLmFzQ29udGVudEhhbmRsZXIoKTsKLSAgICAgICAgLy8gbV9yZXN1bHRUcmVlSGFuZGxlci5zZXRDb250ZW50SGFuZGxlcihzaGFuZGxlcik7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGlvZSk7Ci0gICAgfQotCi0gICAgU3RyaW5nIHJlc3VsdDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHRoaXMubV9yZXN1bHRUcmVlSGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0KLSAgICAgIC8vIERvIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgY2hpbGQgZWxlbWVudHMuCi0gICAgICBleGVjdXRlQ2hpbGRUZW1wbGF0ZXMoZWxlbSwgdHJ1ZSk7Ci0gICAgICB0aGlzLm1fcmVzdWx0VHJlZUhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQotICAgICAgcmVzdWx0ID0gc3cudG9TdHJpbmcoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgc3cuZ2V0QnVmZmVyKCkuc2V0TGVuZ3RoKDApOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgc3cuY2xvc2UoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gaW9lKXt9Ci0KLSAgICAgIG1fc3RyaW5nV3JpdGVyT2JqZWN0UG9vbC5mcmVlSW5zdGFuY2Uoc3cpOwotICAgICAgbV90ZXh0UmVzdWx0SGFuZGxlck9iamVjdFBvb2wuZnJlZUluc3RhbmNlKG1fcmVzdWx0VHJlZUhhbmRsZXIpOwotICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlci5yZXNldCgpOwotCi0gICAgICAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyByZXN1bHQgdHJlZSBoYW5kbGVyLgotICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlciA9IHNhdmVkUlRyZWVIYW5kbGVyOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIEdpdmVuIGFuIGVsZW1lbnQgYW5kIG1vZGUsIGZpbmQgdGhlIGNvcnJlc3BvbmRpbmcKLSAgICogdGVtcGxhdGUgYW5kIHByb2Nlc3MgdGhlIGNvbnRlbnRzLgotICAgKgotICAgKiBAcGFyYW0geHNsSW5zdHJ1Y3Rpb24gVGhlIGNhbGxpbmcgZWxlbWVudC4KLSAgICogQHBhcmFtIHRlbXBsYXRlIFRoZSB0ZW1wbGF0ZSB0byB1c2UgaWYgeHNsOmZvci1lYWNoLCBvciBudWxsLgotICAgKiBAcGFyYW0gY2hpbGQgVGhlIHNvdXJjZSBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBtb2RlIFRoZSBjdXJyZW50IG1vZGUsIG1heSBiZSBudWxsLgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBhcHBsaWVkIGEgdGVtcGxhdGUsIGZhbHNlIGlmIG5vdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGFwcGx5VGVtcGxhdGVUb05vZGUoRWxlbVRlbXBsYXRlRWxlbWVudCB4c2xJbnN0cnVjdGlvbiwgIC8vIHhzbDphcHBseS10ZW1wbGF0ZXMgb3IgeHNsOmZvci1lYWNoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbVRlbXBsYXRlIHRlbXBsYXRlLCBpbnQgY2hpbGQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRFRNIGR0bSA9IG1feGNvbnRleHQuZ2V0RFRNKGNoaWxkKTsKLSAgICBzaG9ydCBub2RlVHlwZSA9IGR0bS5nZXROb2RlVHlwZShjaGlsZCk7Ci0gICAgYm9vbGVhbiBpc0RlZmF1bHRUZXh0UnVsZSA9IGZhbHNlOwotCi0gICAgaWYgKG51bGwgPT0gdGVtcGxhdGUpCi0gICAgewotICAgICAgaW50IG1heEltcG9ydExldmVsOwotICAgICAgYm9vbGVhbiBpc0FwcGx5SW1wb3J0cyA9ICgoeHNsSW5zdHJ1Y3Rpb24gPT0gbnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBmYWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHhzbEluc3RydWN0aW9uLmdldFhTTFRva2VuKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSBDb25zdGFudHMuRUxFTU5BTUVfQVBQTFlfSU1QT1JUUyk7Ci0KLSAgICAgIGlmIChpc0FwcGx5SW1wb3J0cykKLSAgICAgIHsKLSAgICAgICAgbWF4SW1wb3J0TGV2ZWwgPQotICAgICAgICAgIHhzbEluc3RydWN0aW9uLmdldFN0eWxlc2hlZXRDb21wb3NlZCgpLmdldEltcG9ydENvdW50Q29tcG9zZWQoKSAtIDE7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1heEltcG9ydExldmVsID0gLTE7Ci0gICAgICB9Ci0KLSAgICAgIC8vIElmIHdlJ3JlIHRyeWluZyBhbiB4c2w6YXBwbHktaW1wb3J0cyBhdCB0aGUgdG9wIGxldmVsIChpZSB0aGVyZSBhcmUgbm8KLSAgICAgIC8vIGltcG9ydGVkIHN0eWxlc2hlZXRzKSwgd2UgbmVlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZXJlIGlzIG5vIG1hdGNoaW5nIHRlbXBsYXRlLgotICAgICAgLy8gVGhlIGFib3ZlIGxvZ2ljIHdpbGwgY2FsY3VsYXRlIGEgbWF4SW1wb3J0TGV2ZWwgb2YgLTEgd2hpY2ggaW5kaWNhdGVzCi0gICAgICAvLyB0aGF0IHdlIHNob3VsZCBmaW5kIGFueSB0ZW1wbGF0ZS4gIFRoaXMgaXMgYmVjYXVzZSBhIHZhbHVlIG9mIC0xIGZvcgotICAgICAgLy8gbWF4SW1wb3J0TGV2ZWwgaGFzIGEgc3BlY2lhbCBtZWFuaW5nLiAgQnV0IHdlIGRvbid0IHdhbnQgdGhhdC4KLSAgICAgIC8vIFdlIHdhbnQgdG8gbWF0Y2ggLW5vLSB0ZW1wbGF0ZXMuIFNlZSBidWd6aWxsYSBidWcgMTE3MC4KLSAgICAgIGlmIChpc0FwcGx5SW1wb3J0cyAmJiAobWF4SW1wb3J0TGV2ZWwgPT0gLTEpKQotICAgICAgewotICAgICAgICB0ZW1wbGF0ZSA9IG51bGw7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gRmluZCB0aGUgWFNMIHRlbXBsYXRlIHRoYXQgaXMgdGhlIGJlc3QgbWF0Y2ggZm9yIHRoZSAKLSAgICAgICAgLy8gZWxlbWVudC4gICAgICAgIAotICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBtX3hjb250ZXh0OwotCi0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgeGN0eHQucHVzaE5hbWVzcGFjZUNvbnRleHQoeHNsSW5zdHJ1Y3Rpb24pOwotCi0gICAgICAgICAgUU5hbWUgbW9kZSA9IHRoaXMuZ2V0TW9kZSgpOwotCi0gICAgICAgICAgdGVtcGxhdGUgPSBtX3N0eWxlc2hlZXRSb290LmdldFRlbXBsYXRlQ29tcG9zZWQoeGN0eHQsIGNoaWxkLCBtb2RlLAotICAgICAgICAgICAgICAgICAgbWF4SW1wb3J0TGV2ZWwsIG1fcXVpZXRDb25mbGljdFdhcm5pbmdzLCBkdG0pOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkKLSAgICAgICAgewotICAgICAgICAgIHhjdHh0LnBvcE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICAvLyBJZiB0aGF0IGRpZG4ndCBsb2NhdGUgYSBub2RlLCBmYWxsIGJhY2sgdG8gYSBkZWZhdWx0IHRlbXBsYXRlIHJ1bGUuCi0gICAgICAvLyBTZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNidWlsdC1pbi1ydWxlLgotICAgICAgaWYgKG51bGwgPT0gdGVtcGxhdGUpCi0gICAgICB7Ci0gICAgICAgIHN3aXRjaCAobm9kZVR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICAgIGNhc2UgRFRNLkVMRU1FTlRfTk9ERSA6Ci0gICAgICAgICAgdGVtcGxhdGUgPSBtX3N0eWxlc2hlZXRSb290LmdldERlZmF1bHRSdWxlKCk7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFIDoKLSAgICAgICAgICB0ZW1wbGF0ZSA9IG1fc3R5bGVzaGVldFJvb3QuZ2V0RGVmYXVsdFRleHRSdWxlKCk7Ci0gICAgICAgICAgaXNEZWZhdWx0VGV4dFJ1bGUgPSB0cnVlOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5ET0NVTUVOVF9OT0RFIDoKLSAgICAgICAgICB0ZW1wbGF0ZSA9IG1fc3R5bGVzaGVldFJvb3QuZ2V0RGVmYXVsdFJvb3RSdWxlKCk7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGRlZmF1bHQgOgotCi0gICAgICAgICAgLy8gTm8gZGVmYXVsdCBydWxlcyBmb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgYW5kIHRoZSBsaWtlLgotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIC8vIElmIHdlIGFyZSBwcm9jZXNzaW5nIHRoZSBkZWZhdWx0IHRleHQgcnVsZSwgdGhlbiBqdXN0IGNsb25lIAotICAgIC8vIHRoZSB2YWx1ZSBkaXJlY3RseSB0byB0aGUgcmVzdWx0IHRyZWUuCi0gICAgdHJ5Ci0gICAgewotICAgICAgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQodGVtcGxhdGUpOwotICAgICAgbV94Y29udGV4dC5wdXNoQ3VycmVudE5vZGUoY2hpbGQpOwotICAgICAgcHVzaFBhaXJDdXJyZW50TWF0Y2hlZCh0ZW1wbGF0ZSwgY2hpbGQpOwotICAgICAgCi0gICAgICAvLyBGaXggY29weSBjb3B5MjkgdGVzdC4KLSAgICAgIERUTUl0ZXJhdG9yIGNubCA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLk5vZGVTZXREVE0oY2hpbGQsIG1feGNvbnRleHQuZ2V0RFRNTWFuYWdlcigpKTsKLSAgICAgIG1feGNvbnRleHQucHVzaENvbnRleHROb2RlTGlzdChjbmwpOwotCi0gICAgICBpZiAoaXNEZWZhdWx0VGV4dFJ1bGUpCi0gICAgICB7Ci0gICAgICAgIHN3aXRjaCAobm9kZVR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgICAgY2FzZSBEVE0uVEVYVF9OT0RFIDoKLSAgICAgICAgICBDbG9uZXJUb1Jlc3VsdFRyZWUuY2xvbmVUb1Jlc3VsdFRyZWUoY2hpbGQsIG5vZGVUeXBlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdG0sIGdldFJlc3VsdFRyZWVIYW5kbGVyKCksIGZhbHNlKTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgICAgIGR0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoY2hpbGQsIGdldFJlc3VsdFRyZWVIYW5kbGVyKCksIGZhbHNlKTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIEZpcmUgYSB0cmFjZSBldmVudCBmb3IgdGhlIHRlbXBsYXRlLgotICAgICAgICAgCi0gICAgICAgICAgICAgICAgaWYgKFRyYW5zZm9ybWVySW1wbC5TX0RFQlVHKQotICAgICAgICAgICAgICAgICAgZ2V0VHJhY2VNYW5hZ2VyKCkuZmlyZVRyYWNlRXZlbnQodGVtcGxhdGUpOwotICAgICAgICAvLyBBbmQgZXhlY3V0ZSB0aGUgY2hpbGQgdGVtcGxhdGVzLgotICAgICAgICAvLyA5LzExLzAwOiBJZiB0ZW1wbGF0ZSBoYXMgYmVlbiBjb21waWxlZCwgaGFuZCBvZmYgdG8gaXQKLSAgICAgICAgLy8gc2luY2UgbXVjaCAobW9zdD8gYWxsPykgb2YgdGhlIHByb2Nlc3NpbmcgaGFzIGJlZW4gaW5saW5lZC4KLSAgICAgICAgLy8gKEl0IHdvdWxkIGJlIG5pY2UgaWYgdGhlcmUgd2FzIGEgc2luZ2xlIGVudHJ5IHBvaW50IHRoYXQKLSAgICAgICAgLy8gd29ya2VkIGZvciBib3RoLi4uIGJ1dCB0aGUgaW50ZXJwcmV0aXZlIHN5c3RlbSB3b3JrcyBieQotICAgICAgICAvLyBoYXZpbmcgdGhlIFRyYW5mb3JtZXIgZXhlY3V0ZSB0aGUgY2hpbGRyZW4sIHdoaWxlIHRoZQotICAgICAgICAvLyBjb21waWxlZCBvYnZpb3VzbHkgaGFzIHRvIHJ1biBpdHMgb3duIGNvZGUuIEl0J3MKLSAgICAgICAgLy8gYWxzbyB1bmNsZWFyIHRoYXQgImV4ZWN1dGUiIGlzIHJlYWxseSB0aGUgcmlnaHQgbmFtZSBmb3IKLSAgICAgICAgLy8gdGhhdCBlbnRyeSBwb2ludC4pCi0gICAgICAgIG1feGNvbnRleHQuc2V0U0FYTG9jYXRvcih0ZW1wbGF0ZSk7Ci0gICAgICAgIC8vIG1feGNvbnRleHQuZ2V0VmFyU3RhY2soKS5saW5rKCk7Ci0gICAgICAgIG1feGNvbnRleHQuZ2V0VmFyU3RhY2soKS5saW5rKHRlbXBsYXRlLm1fZnJhbWVTaXplKTsKLSAgICAgICAgZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKHRlbXBsYXRlLCB0cnVlKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgbV94Y29udGV4dC5nZXRWYXJTdGFjaygpLnVubGluaygpOwotICAgICAgbV94Y29udGV4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgbV94Y29udGV4dC5wb3BDb250ZXh0Tm9kZUxpc3QoKTsKLSAgICAgIHBvcEN1cnJlbnRNYXRjaGVkKCk7Ci0gICAgICBwb3BFbGVtVGVtcGxhdGVFbGVtZW50KCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLSAgCi0gIAotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIEV4ZWN1dGUgZWFjaCBvZiB0aGUgY2hpbGRyZW4gb2YgYSB0ZW1wbGF0ZSBlbGVtZW50LiAgVGhpcyBtZXRob2QKLSAgICogaXMgb25seSBmb3IgZXh0ZW5zaW9uIHVzZS4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gVGhlIEVsZW1UZW1wbGF0ZUVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgY2hpbGRyZW4KLSAgICogdGhhdCBzaG91bGQgZXhlY3V0ZS4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgVGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKiBORUVEU0RPQyBAcGFyYW0gY29udGV4dAotICAgKiBAcGFyYW0gbW9kZSBUaGUgY3VycmVudCBtb2RlLgotICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgQ29udGVudEhhbmRsZXIgdG8gd2hlcmUgdGhlIHJlc3VsdCBldmVudHMKLSAgICogc2hvdWxkIGJlIGZlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKAotICAgICAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSwgb3JnLnczYy5kb20uTm9kZSBjb250ZXh0LCBRTmFtZSBtb2RlLCBDb250ZW50SGFuZGxlciBoYW5kbGVyKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG1feGNvbnRleHQ7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBpZihudWxsICE9IG1vZGUpCi0gICAgICAgIHB1c2hNb2RlKG1vZGUpOwotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKHhjdHh0LmdldERUTUhhbmRsZUZyb21Ob2RlKGNvbnRleHQpKTsKLSAgICAgIGV4ZWN1dGVDaGlsZFRlbXBsYXRlcyhlbGVtLCBoYW5kbGVyKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAKLSAgICAgIC8vIEknbSBub3Qgc3VyZSB3aGVyZSBvciB3aHkgdGhpcyB3YXMgaGVyZS4gIEl0IGlzIGNsZWFybHkgaW4gCi0gICAgICAvLyBlcnJvciB0aG91Z2gsIHdpdGhvdXQgYSBjb3JyZXNwb25kaW5nIHB1c2hNb2RlKCkuCi0gICAgICBpZiAobnVsbCAhPSBtb2RlKQotICAgICAgICBwb3BNb2RlKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBFeGVjdXRlIGVhY2ggb2YgdGhlIGNoaWxkcmVuIG9mIGEgdGVtcGxhdGUgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gVGhlIEVsZW1UZW1wbGF0ZUVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgY2hpbGRyZW4KLSAgICogdGhhdCBzaG91bGQgZXhlY3V0ZS4KLSAgICogQHBhcmFtIGhhbmRsZXIgVGhlIENvbnRlbnRIYW5kbGVyIHRvIHdoZXJlIHRoZSByZXN1bHQgZXZlbnRzCi0gICAqIHNob3VsZCBiZSBmZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGV4ZWN1dGVDaGlsZFRlbXBsYXRlcygKLSAgICAgICAgICBFbGVtVGVtcGxhdGVFbGVtZW50IGVsZW0sIENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgUmVzdWx0VHJlZUhhbmRsZXIgcnRoID0gdGhpcy5nZXRSZXN1bHRUcmVlSGFuZGxlcigpOwotCi0gICAgLy8gVGhlc2UgbWF5IHdlbGwgbm90IGJlIHRoZSBzYW1lISAgSW4gdGhpcyBjYXNlIHdoZW4gY2FsbGluZyAKLSAgICAvLyB0aGUgUmVkaXJlY3QgZXh0ZW5zaW9uLCBpdCBoYXMgYWxyZWFkeSBzZXQgdGhlIENvbnRlbnRIYW5kbGVyCi0gICAgLy8gaW4gdGhlIFRyYW5zZm9ybWVyLgotICAgIENvbnRlbnRIYW5kbGVyIHNhdmVkUlRISGFuZGxlciA9IHJ0aC5nZXRDb250ZW50SGFuZGxlcigpOwotICAgIENvbnRlbnRIYW5kbGVyIHNhdmVkSGFuZGxlciA9IHRoaXMuZ2V0Q29udGVudEhhbmRsZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGdldFJlc3VsdFRyZWVIYW5kbGVyKCkuZmx1c2hQZW5kaW5nKCk7Ci0gICAgICB0aGlzLnNldENvbnRlbnRIYW5kbGVyKGhhbmRsZXIpOwotCi0gICAgICAvLyAlUkVWSUVXJSBNYWtlIHN1cmUgY3VycmVudCBub2RlIGlzIGJlaW5nIHB1c2hlZC4KLSAgICAgIGV4ZWN1dGVDaGlsZFRlbXBsYXRlcyhlbGVtLCB0cnVlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgdGhpcy5zZXRDb250ZW50SGFuZGxlcihzYXZlZEhhbmRsZXIpOwotCi0gICAgICAvLyBUaGlzIGZpeGVzIGEgYnVnIHdoZXJlIHRoZSBSZXN1bHRUcmVlSGFuZGxlcidzIENvbnRlbnRIYW5kbGVyCi0gICAgICAvLyB3YXMgYmVpbmcgcmVzZXQgdG8gdGhlIHdyb25nIENvbnRlbnRIYW5kbGVyLgotICAgICAgcnRoLnNldENvbnRlbnRIYW5kbGVyKHNhdmVkUlRISGFuZGxlcik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBFeGVjdXRlIGVhY2ggb2YgdGhlIGNoaWxkcmVuIG9mIGEgdGVtcGxhdGUgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIFRoZSBYU0xUIHRyYW5zZm9ybWVyIGluc3RhbmNlLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBUaGUgRWxlbVRlbXBsYXRlRWxlbWVudCB0aGF0IGNvbnRhaW5zIHRoZSBjaGlsZHJlbgotICAgKiB0aGF0IHNob3VsZCBleGVjdXRlLgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBUaGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBtb2RlIFRoZSBjdXJyZW50IG1vZGUuCi0gICAqIEBwYXJhbSBzaG91bGRBZGRBdHRycyB0cnVlIGlmIHhzbDphdHRyaWJ1dGVzIHNob3VsZCBiZSBleGVjdXRlZC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKAotICAgICAgICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSwgYm9vbGVhbiBzaG91bGRBZGRBdHRycykKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBEb2VzIHRoaXMgZWxlbWVudCBoYXZlIGFueSBjaGlsZHJlbj8KLSAgICBFbGVtVGVtcGxhdGVFbGVtZW50IHQgPSBlbGVtLmdldEZpcnN0Q2hpbGRFbGVtKCk7Ci0KLSAgICBpZiAobnVsbCA9PSB0KQotICAgICAgcmV0dXJuOyAgICAgIAotICAgIAotICAgIGlmKGVsZW0uaGFzVGV4dExpdE9ubHkoKSAmJiBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLm1fb3B0aW1pemUpCi0gICAgeyAgICAgIAotICAgICAgY2hhcltdIGNoYXJzID0gKChFbGVtVGV4dExpdGVyYWwpdCkuZ2V0Q2hhcnMoKTsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICAvLyBIYXZlIHRvIHB1c2ggc3R1ZmYgb24gZm9yIHRvb2xpbmcuLi4KLSAgICAgICAgdGhpcy5wdXNoRWxlbVRlbXBsYXRlRWxlbWVudCh0KTsKLSAgICAgICAgbV9yZXN1bHRUcmVlSGFuZGxlci5jaGFyYWN0ZXJzKGNoYXJzLCAwLCBjaGFycy5sZW5ndGgpOwotICAgICAgfQotICAgICAgY2F0Y2goU0FYRXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oc2UpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICB0aGlzLnBvcEVsZW1UZW1wbGF0ZUVsZW1lbnQoKTsKLSAgICAgIH0KLSAgICAgIHJldHVybjsKLSAgICB9Ci0KLS8vICAgIC8vIENoZWNrIGZvciBpbmZpbml0ZSBsb29wcyBpZiB3ZSBoYXZlIHRvLgotLy8gICAgYm9vbGVhbiBjaGVjayA9IChtX3N0YWNrR3VhcmQubV9yZWN1cnNpb25MaW1pdCA+IC0xKTsKLS8vCi0vLyAgICBpZiAoY2hlY2spCi0vLyAgICAgIGdldFN0YWNrR3VhcmQoKS5wdXNoKGVsZW0sIHhjdHh0LmdldEN1cnJlbnROb2RlKCkpOwotCi0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbV94Y29udGV4dDsKLSAgICB4Y3R4dC5wdXNoU0FYTG9jYXRvck51bGwoKTsKLSAgICBpbnQgY3VycmVudFRlbXBsYXRlRWxlbWVudHNUb3AgPSBtX2N1cnJlbnRUZW1wbGF0ZUVsZW1lbnRzVG9wOwotICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHNUb3ArKzsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgY2hpbGRyZW4gb2YgdGhlIHRlbXBsYXRlLCBjYWxsaW5nIGV4ZWN1dGUgb24gCi0gICAgICAvLyBlYWNoIG9mIHRoZW0uCi0gICAgICBmb3IgKDsgdCAhPSBudWxsOyB0ID0gdC5nZXROZXh0U2libGluZ0VsZW0oKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKCFzaG91bGRBZGRBdHRycwotICAgICAgICAgICAgICAgICYmIHQuZ2V0WFNMVG9rZW4oKSA9PSBDb25zdGFudHMuRUxFTU5BTUVfQVRUUklCVVRFKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHhjdHh0LnNldFNBWExvY2F0b3IodCk7Ci0gICAgICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHNbY3VycmVudFRlbXBsYXRlRWxlbWVudHNUb3BdID0gdDsKLSAgICAgICAgdC5leGVjdXRlKHRoaXMpOwotICAgICAgfQotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50c1RvcC0tOwotICAgICAgeGN0eHQucG9wU0FYTG9jYXRvcigpOwotICAgIH0KLQotICAgIC8vIENoZWNrIGZvciBpbmZpbml0ZSBsb29wcyBpZiB3ZSBoYXZlIHRvCi0vLyAgICBpZiAoY2hlY2spCi0vLyAgICAgIGdldFN0YWNrR3VhcmQoKS5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogR2V0IHRoZSBrZXlzIGZvciB0aGUgeHNsOnNvcnQgZWxlbWVudHMuCi0gICAqIE5vdGU6IFNob3VsZCB0aGlzIGdvIGludG8gRWxlbUZvckVhY2g/Ci0gICAqCi0gICAqIEBwYXJhbSBmb3JlYWNoIFZhbGlkIEVsZW1Gb3JFYWNoIGVsZW1lbnQsIG5vdCBudWxsLgotICAgKiBAcGFyYW0gc291cmNlTm9kZUNvbnRleHQgVGhlIGN1cnJlbnQgbm9kZSBjb250ZXh0IGluIHRoZSBzb3VyY2UgdHJlZSwKLSAgICogbmVlZGVkIHRvIGV2YWx1YXRlIHRoZSBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGVzLgotICAgKgotICAgKiBAcmV0dXJuIEEgVmVjdG9yIG9mIE5vZGVTb3J0S2V5cywgb3IgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFZlY3RvciBwcm9jZXNzU29ydEtleXMoRWxlbUZvckVhY2ggZm9yZWFjaCwgaW50IHNvdXJjZU5vZGVDb250ZXh0KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBWZWN0b3Iga2V5cyA9IG51bGw7Ci0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbV94Y29udGV4dDsKLSAgICBpbnQgbkVsZW1zID0gZm9yZWFjaC5nZXRTb3J0RWxlbUNvdW50KCk7Ci0KLSAgICBpZiAobkVsZW1zID4gMCkKLSAgICAgIGtleXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgICAvLyBNYXJjaCBiYWNrd2FyZHMsIGNvbGxlY3RpbmcgdGhlIHNvcnQga2V5cy4KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5FbGVtczsgaSsrKQotICAgIHsKLSAgICAgIEVsZW1Tb3J0IHNvcnQgPSBmb3JlYWNoLmdldFNvcnRFbGVtKGkpOwotICAgICAgU3RyaW5nIGxhbmdTdHJpbmcgPQotICAgICAgICAobnVsbCAhPSBzb3J0LmdldExhbmcoKSkKLSAgICAgICAgPyBzb3J0LmdldExhbmcoKS5ldmFsdWF0ZSh4Y3R4dCwgc291cmNlTm9kZUNvbnRleHQsIGZvcmVhY2gpIDogbnVsbDsKLSAgICAgIFN0cmluZyBkYXRhVHlwZVN0cmluZyA9IHNvcnQuZ2V0RGF0YVR5cGUoKS5ldmFsdWF0ZSh4Y3R4dCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlTm9kZUNvbnRleHQsIGZvcmVhY2gpOwotCi0gICAgICBpZiAoZGF0YVR5cGVTdHJpbmcuaW5kZXhPZigiOiIpID49IDApCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICAgICAiVE9ETzogTmVlZCB0byB3cml0ZSB0aGUgaG9va3MgZm9yIFFOQU1FIHNvcnQgZGF0YSB0eXBlIik7Ci0gICAgICBlbHNlIGlmICghKGRhdGFUeXBlU3RyaW5nLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkFUVFJWQUxfREFUQVRZUEVfVEVYVCkpCi0gICAgICAgICAgICAgICAmJiEoZGF0YVR5cGVTdHJpbmcuZXF1YWxzSWdub3JlQ2FzZSgKLSAgICAgICAgICAgICAgICAgQ29uc3RhbnRzLkFUVFJWQUxfREFUQVRZUEVfTlVNQkVSKSkpCi0gICAgICAgIGZvcmVhY2guZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgQ29uc3RhbnRzLkFUVFJOQU1FX0RBVEFUWVBFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGVTdHJpbmcgfSk7Ci0KLSAgICAgIGJvb2xlYW4gdHJlYXRBc051bWJlcnMgPQotICAgICAgICAoKG51bGwgIT0gZGF0YVR5cGVTdHJpbmcpICYmIGRhdGFUeXBlU3RyaW5nLmVxdWFscygKLSAgICAgICAgQ29uc3RhbnRzLkFUVFJWQUxfREFUQVRZUEVfTlVNQkVSKSkgPyB0cnVlIDogZmFsc2U7Ci0gICAgICBTdHJpbmcgb3JkZXJTdHJpbmcgPSBzb3J0LmdldE9yZGVyKCkuZXZhbHVhdGUoeGN0eHQsIHNvdXJjZU5vZGVDb250ZXh0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKTsKLQotICAgICAgaWYgKCEob3JkZXJTdHJpbmcuZXF1YWxzSWdub3JlQ2FzZShDb25zdGFudHMuQVRUUlZBTF9PUkRFUl9BU0NFTkRJTkcpKQotICAgICAgICAgICAgICAmJiEob3JkZXJTdHJpbmcuZXF1YWxzSWdub3JlQ2FzZSgKLSAgICAgICAgICAgICAgICBDb25zdGFudHMuQVRUUlZBTF9PUkRFUl9ERVNDRU5ESU5HKSkpCi0gICAgICAgIGZvcmVhY2guZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lMTEVHQUxfQVRUUklCVVRFX1ZBTFVFLAotICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgQ29uc3RhbnRzLkFUVFJOQU1FX09SREVSLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJTdHJpbmcgfSk7Ci0KLSAgICAgIGJvb2xlYW4gZGVzY2VuZGluZyA9Ci0gICAgICAgICgobnVsbCAhPSBvcmRlclN0cmluZykgJiYgb3JkZXJTdHJpbmcuZXF1YWxzKAotICAgICAgICBDb25zdGFudHMuQVRUUlZBTF9PUkRFUl9ERVNDRU5ESU5HKSkgPyB0cnVlIDogZmFsc2U7Ci0gICAgICBBVlQgY2FzZU9yZGVyID0gc29ydC5nZXRDYXNlT3JkZXIoKTsKLSAgICAgIGJvb2xlYW4gY2FzZU9yZGVyVXBwZXI7Ci0KLSAgICAgIGlmIChudWxsICE9IGNhc2VPcmRlcikKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGNhc2VPcmRlclN0cmluZyA9IGNhc2VPcmRlci5ldmFsdWF0ZSh4Y3R4dCwgc291cmNlTm9kZUNvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCk7Ci0KLSAgICAgICAgaWYgKCEoY2FzZU9yZGVyU3RyaW5nLmVxdWFsc0lnbm9yZUNhc2UoQ29uc3RhbnRzLkFUVFJWQUxfQ0FTRU9SREVSX1VQUEVSKSkKLSAgICAgICAgICAgICAgICAmJiEoY2FzZU9yZGVyU3RyaW5nLmVxdWFsc0lnbm9yZUNhc2UoCi0gICAgICAgICAgICAgICAgICBDb25zdGFudHMuQVRUUlZBTF9DQVNFT1JERVJfTE9XRVIpKSkKLSAgICAgICAgICBmb3JlYWNoLmVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTExFR0FMX0FUVFJJQlVURV9WQUxVRSwKLSAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgQ29uc3RhbnRzLkFUVFJOQU1FX0NBU0VPUkRFUiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZU9yZGVyU3RyaW5nIH0pOwotCi0gICAgICAgIGNhc2VPcmRlclVwcGVyID0KLSAgICAgICAgICAoKG51bGwgIT0gY2FzZU9yZGVyU3RyaW5nKSAmJiBjYXNlT3JkZXJTdHJpbmcuZXF1YWxzKAotICAgICAgICAgIENvbnN0YW50cy5BVFRSVkFMX0NBU0VPUkRFUl9VUFBFUikpID8gdHJ1ZSA6IGZhbHNlOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBjYXNlT3JkZXJVcHBlciA9IGZhbHNlOwotICAgICAgfQotCi0gICAgICBrZXlzLmFkZEVsZW1lbnQobmV3IE5vZGVTb3J0S2V5KHRoaXMsIHNvcnQuZ2V0U2VsZWN0KCksIHRyZWF0QXNOdW1iZXJzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjZW5kaW5nLCBsYW5nU3RyaW5nLCBjYXNlT3JkZXJVcHBlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCkpOwotICAgIH0KLQotICAgIHJldHVybiBrZXlzOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIFNFQ1RJT046IFRyYW5zZm9ybVN0YXRlIGltcGxlbWVudGF0aW9uCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBQdXNoIHRoZSBjdXJyZW50IHRlbXBsYXRlIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIFRoZSBjdXJyZW50IEVsZW1UZW1wbGF0ZUVsZW1lbnQgKG1heSBiZSBudWxsLCBhbmQgdGhlbgotICAgKiBzZXQgdmlhIHNldEN1cnJlbnRFbGVtZW50KS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50KEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSkKLSAgewotICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHNbbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50c1RvcCsrXSA9IGVsZW07Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IHRlbXBsYXRlIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBwb3BFbGVtVGVtcGxhdGVFbGVtZW50KCkKLSAgewotICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHNUb3AtLTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHRvcCBvZiB0aGUgY3VycmVudCB0ZW1wbGF0ZSBlbGVtZW50cwotICAgKiBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtIGUgVGhlIGN1cnJlbnQgRWxlbVRlbXBsYXRlRWxlbWVudCBhYm91dCB0bwotICAgKiBiZSBleGVjdXRlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEN1cnJlbnRFbGVtZW50KEVsZW1UZW1wbGF0ZUVsZW1lbnQgZSkKLSAgewotICAgIG1fY3VycmVudFRlbXBsYXRlRWxlbWVudHNbbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50c1RvcC0xXSA9IGU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmVzIHRoZSBjdXJyZW50IEVsZW1UZW1wbGF0ZUVsZW1lbnQgdGhhdCBpcwotICAgKiBiZWluZyBleGVjdXRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBFbGVtVGVtcGxhdGVFbGVtZW50IHRoYXQgaXMgZXhlY3V0aW5nLAotICAgKiBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlRWxlbWVudCBnZXRDdXJyZW50RWxlbWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9jdXJyZW50VGVtcGxhdGVFbGVtZW50c1ttX2N1cnJlbnRUZW1wbGF0ZUVsZW1lbnRzVG9wLTFdOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUKLSAgICogaW4gdGhlIHNvdXJjZSB0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSAoc2hvdWxkIG5ldmVyIGJlIG51bGw/KS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q3VycmVudE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1feGNvbnRleHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIHhzbDp0ZW1wbGF0ZQotICAgKiB0aGF0IGlzIGluIGVmZmVjdCwgd2hpY2ggbWF5IGJlIGEgbWF0Y2hlZCB0ZW1wbGF0ZQotICAgKiBvciBhIG5hbWVkIHRlbXBsYXRlLgotICAgKgotICAgKiA8cD5QbGVhc2Ugbm90ZSB0aGF0IHRoZSBFbGVtVGVtcGxhdGUgcmV0dXJuZWQgbWF5Ci0gICAqIGJlIGEgZGVmYXVsdCB0ZW1wbGF0ZSwgYW5kIHRodXMgbWF5IG5vdCBoYXZlIGEgdGVtcGxhdGUKLSAgICogZGVmaW5lZCBpbiB0aGUgc3R5bGVzaGVldC48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgeHNsOnRlbXBsYXRlLCBzaG91bGQgbm90IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgRWxlbVRlbXBsYXRlIGdldEN1cnJlbnRUZW1wbGF0ZSgpCi0gIHsKLQotICAgIEVsZW1UZW1wbGF0ZUVsZW1lbnQgZWxlbSA9IGdldEN1cnJlbnRFbGVtZW50KCk7Ci0KLSAgICB3aGlsZSAoKG51bGwgIT0gZWxlbSkKLSAgICAgICAgICAgJiYgKGVsZW0uZ2V0WFNMVG9rZW4oKSAhPSBDb25zdGFudHMuRUxFTU5BTUVfVEVNUExBVEUpKQotICAgIHsKLSAgICAgIGVsZW0gPSBlbGVtLmdldFBhcmVudEVsZW0oKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gKEVsZW1UZW1wbGF0ZSkgZWxlbTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIGJvdGggdGhlIGN1cnJlbnQgeHNsOnRlbXBsYXRlIG9yIHhzbDpmb3ItZWFjaCBvbnRvIHRoZQotICAgKiBzdGFjaywgYWxvbmcgd2l0aCB0aGUgY2hpbGQgbm9kZSB0aGF0IHdhcyBtYXRjaGVkLgotICAgKiAoTm90ZTogc2hvdWxkIHRoaXMgb25seSBiZSB1c2VkIGZvciB4c2w6dGVtcGxhdGVzPz8gLXNiKQotICAgKgotICAgKiBAcGFyYW0gdGVtcGxhdGUgeHNsOnRlbXBsYXRlIG9yIHhzbDpmb3ItZWFjaC4KLSAgICogQHBhcmFtIGNoaWxkIFRoZSBjaGlsZCB0aGF0IHdhcyBtYXRjaGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgcHVzaFBhaXJDdXJyZW50TWF0Y2hlZChFbGVtVGVtcGxhdGVFbGVtZW50IHRlbXBsYXRlLCBpbnQgY2hpbGQpCi0gIHsKLSAgICBtX2N1cnJlbnRNYXRjaFRlbXBsYXRlcy5wdXNoKHRlbXBsYXRlKTsKLSAgICBtX2N1cnJlbnRNYXRjaGVkTm9kZXMucHVzaChjaGlsZCk7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBlbGVtZW50cyB0aGF0IHdlcmUgcHVzaGVkIHZpYSBwdXNoUGFpckN1cnJlbnRNYXRjaGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgcG9wQ3VycmVudE1hdGNoZWQoKQotICB7Ci0gICAgbV9jdXJyZW50TWF0Y2hUZW1wbGF0ZXMucG9wKCk7Ci0gICAgbV9jdXJyZW50TWF0Y2hlZE5vZGVzLnBvcCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyB0aGUgeHNsOnRlbXBsYXRlCi0gICAqIHRoYXQgd2FzIG1hdGNoZWQuICBOb3RlIHRoYXQgdGhpcyBtYXkgbm90IGJlCi0gICAqIHRoZSBzYW1lIHRoaW5nIGFzIHRoZSBjdXJyZW50IHRlbXBsYXRlICh3aGljaAotICAgKiBtYXkgYmUgZnJvbSBnZXRDdXJyZW50RWxlbWVudCgpKSwgc2luY2UgYSBuYW1lZAotICAgKiB0ZW1wbGF0ZSBtYXkgYmUgaW4gZWZmZWN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwdXNoZWQgdGVtcGxhdGUgdGhhdCB3YXMgcHVzaGVkIHZpYSBwdXNoUGFpckN1cnJlbnRNYXRjaGVkLgotICAgKi8KLSAgcHVibGljIEVsZW1UZW1wbGF0ZSBnZXRNYXRjaGVkVGVtcGxhdGUoKQotICB7Ci0gICAgcmV0dXJuIChFbGVtVGVtcGxhdGUpIG1fY3VycmVudE1hdGNoVGVtcGxhdGVzLnBlZWsoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlIHRoYXQgbWF0Y2hlZAotICAgKiB0aGUgdGVtcGxhdGUgb2J0YWluZWQgdmlhIGdldE1hdGNoZWRUZW1wbGF0ZSgpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBtYXRjaGVkIG5vZGUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUKLSAgICogbWF0Y2ggYXR0cmlidXRlIG9mIHRoZSBjdXJyZW50IHhzbDp0ZW1wbGF0ZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TWF0Y2hlZE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fY3VycmVudE1hdGNoZWROb2Rlcy5wZWVwVGFpbCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBBIHJlc2V0IGNsb25lIG9mIHRoZSBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBnZXRDb250ZXh0Tm9kZUxpc3QoKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBEVE1JdGVyYXRvciBjbmwgPSBtX3hjb250ZXh0LmdldENvbnRleHROb2RlTGlzdCgpOwotCi0gICAgICByZXR1cm4gKGNubCA9PSBudWxsKSA/IG51bGwgOiAoRFRNSXRlcmF0b3IpIGNubC5jbG9uZVdpdGhSZXNldCgpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0KLSAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4uCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBUckFYIFRyYW5zZm9ybWVyIG9iamVjdCBpbiBlZmZlY3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgVHJhbnNmb3JtZXIgZ2V0VHJhbnNmb3JtZXIoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gU0VDVElPTjogQWNjZXNzb3IgRnVuY3Rpb25zCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHN0eWxlc2hlZXQgZm9yIHRoaXMgcHJvY2Vzc29yLiAgSWYgdGhpcyBpcyBzZXQsIHRoZW4gdGhlCi0gICAqIHByb2Nlc3MgY2FsbHMgdGhhdCB0YWtlIG9ubHkgdGhlIGlucHV0IC54bWwgd2lsbCB1c2UKLSAgICogdGhpcyBpbnN0ZWFkIG9mIGxvb2tpbmcgZm9yIGEgc3R5bGVzaGVldCBQSS4gIEFsc28sCi0gICAqIHNldHRpbmcgdGhlIHN0eWxlc2hlZXQgaXMgbmVlZGVkIGlmIHlvdSBhcmUgZ29pbmcKLSAgICogdG8gdXNlIHRoZSBwcm9jZXNzb3IgYXMgYSBTQVggQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEBwYXJhbSBzdHlsZXNoZWV0Um9vdCBBIG5vbi1udWxsIFN0eWxlc2hlZXRSb290IG9iamVjdCwKLSAgICogb3IgbnVsbCBpZiB5b3Ugd2lzaCB0byBjbGVhciB0aGUgc3R5bGVzaGVldCByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0KFN0eWxlc2hlZXRSb290IHN0eWxlc2hlZXRSb290KQotICB7Ci0gICAgbV9zdHlsZXNoZWV0Um9vdCA9IHN0eWxlc2hlZXRSb290OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdHlsZXNoZWV0IGZvciB0aGlzIHByb2Nlc3Nvci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3R5bGVzaGVldCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzCi0gICAqIHRyYW5zZm9ybWVyLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0eWxlc2hlZXRSb290IGdldFN0eWxlc2hlZXQoKQotICB7Ci0gICAgcmV0dXJuIG1fc3R5bGVzaGVldFJvb3Q7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHF1aWV0Q29uZmxpY3RXYXJuaW5ncyBwcm9wZXJ0eS4gSWYgdGhlIHF1aWV0Q29uZmxpY3RXYXJuaW5ncwotICAgKiBwcm9wZXJ0eSBpcyBzZXQgdG8gdHJ1ZSwgd2FybmluZ3MgYWJvdXQgcGF0dGVybiBjb25mbGljdHMgd29uJ3QgYmUKLSAgICogcHJpbnRlZCB0byB0aGUgZGlhZ25vc3RpY3Mgc3RyZWFtLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyB0cmFuc2Zvcm1lciBzaG91bGQgbm90IHJlcG9ydAotICAgKiB0ZW1wbGF0ZSBtYXRjaCBjb25mbGljdHMuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRRdWlldENvbmZsaWN0V2FybmluZ3MoKQotICB7Ci0gICAgcmV0dXJuIG1fcXVpZXRDb25mbGljdFdhcm5pbmdzOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIHRoZSBxdWlldENvbmZsaWN0V2FybmluZ3MgcHJvcGVydHkgaXMgc2V0IHRvCi0gICAqIHRydWUsIHdhcm5pbmdzIGFib3V0IHBhdHRlcm4gY29uZmxpY3RzIHdvbid0IGJlCi0gICAqIHByaW50ZWQgdG8gdGhlIGRpYWdub3N0aWNzIHN0cmVhbS4KLSAgICogRmFsc2UgYnkgZGVmYXVsdC4KLSAgICogKEN1cnJlbnRseSBzZXR0aW5nIHRoaXMgcHJvcGVydHkgd2lsbCBoYXZlIG5vIGVmZmVjdC4pCi0gICAqCi0gICAqIEBwYXJhbSBiIHRydWUgaWYgY29uZmxpY3Qgd2FybmluZ3Mgc2hvdWxkIGJlIHN1cHByZXNzZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRRdWlldENvbmZsaWN0V2FybmluZ3MoYm9vbGVhbiBiKQotICB7Ci0gICAgbV9xdWlldENvbmZsaWN0V2FybmluZ3MgPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBTZXQgdGhlIGV4ZWN1dGlvbiBjb250ZXh0IGZvciBYUGF0aC4KLSAgICoKLSAgICogQHBhcmFtIHhjb250ZXh0IEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYUGF0aENvbnRleHQKLSAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgdHJhbnNmb3JtZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRYUGF0aENvbnRleHQoWFBhdGhDb250ZXh0IHhjb250ZXh0KQotICB7Ci0gICAgbV94Y29udGV4dCA9IHhjb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgWFBhdGggY29udGV4dCBhc3NvY2lhdGVkIHdpdGggdGhpcyB0cmFuc2Zvcm1lci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgWFBhdGhDb250ZXh0IHJlZmVyZW5jZSwgbmV2ZXIgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBYUGF0aENvbnRleHQgZ2V0WFBhdGhDb250ZXh0KCkKLSAgewotICAgIHJldHVybiBtX3hjb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBHZXQgdGhlIG9iamVjdCB1c2VkIHRvIGd1YXJkIHRoZSBzdGFjayBmcm9tCi0gICAqIHJlY3Vyc2lvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgU3RhY2tHdWFyZCBvYmplY3QsIHdoaWNoIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIFN0YWNrR3VhcmQgZ2V0U3RhY2tHdWFyZCgpCi0gIHsKLSAgICByZXR1cm4gbV9zdGFja0d1YXJkOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcmVjdXJzaW9uIGxpbWl0LgotICAgKiBVc2VkIGZvciBpbmZpbml0ZSBsb29wIGNoZWNrLiBJZiB0aGUgdmFsdWUgaXMgLTEsIGRvIG5vdAotICAgKiBjaGVjayBmb3IgaW5maW5pdGUgbG9vcHMuIEFueW9uZSB3aG8gd2FudHMgdG8gZW5hYmxlIHRoYXQKLSAgICogY2hlY2sgc2hvdWxkIGNoYW5nZSB0aGUgdmFsdWUgb2YgdGhpcyB2YXJpYWJsZSB0byBiZSB0aGUKLSAgICogbGV2ZWwgb2YgcmVjdXJzaW9uIHRoYXQgdGhleSB3YW50IHRvIGNoZWNrLiBCZSBjYXJlZnVsIHNldHRpbmcKLSAgICogdGhpcyB2YXJpYWJsZSwgaWYgdGhlIG51bWJlciBpcyB0b28gbG93LCBpdCBtYXkgcmVwb3J0IGFuCi0gICAqIGluZmluaXRlIGxvb3Agc2l0dWF0aW9uLCB3aGVuIHRoZXJlIGlzIG5vbmUuCi0gICAqIFBvc3QgdmVyc2lvbiAxLjAuMCwgd2UnbGwgbWFrZSB0aGlzIGEgcnVudGltZSBmZWF0dXJlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsaW1pdCBvbiByZWN1cnNpb24sIG9yIC0xIGlmIG5vIGNoZWNrIGlzIHRvIGJlIG1hZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFJlY3Vyc2lvbkxpbWl0KCkKLSAgewotICAgIHJldHVybiBtX3N0YWNrR3VhcmQuZ2V0UmVjdXJzaW9uTGltaXQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJlY3Vyc2lvbiBsaW1pdC4KLSAgICogVXNlZCBmb3IgaW5maW5pdGUgbG9vcCBjaGVjay4gSWYgdGhlIHZhbHVlIGlzIC0xLCBkbyBub3QKLSAgICogY2hlY2sgZm9yIGluZmluaXRlIGxvb3BzLiBBbnlvbmUgd2hvIHdhbnRzIHRvIGVuYWJsZSB0aGF0Ci0gICAqIGNoZWNrIHNob3VsZCBjaGFuZ2UgdGhlIHZhbHVlIG9mIHRoaXMgdmFyaWFibGUgdG8gYmUgdGhlCi0gICAqIGxldmVsIG9mIHJlY3Vyc2lvbiB0aGF0IHRoZXkgd2FudCB0byBjaGVjay4gQmUgY2FyZWZ1bCBzZXR0aW5nCi0gICAqIHRoaXMgdmFyaWFibGUsIGlmIHRoZSBudW1iZXIgaXMgdG9vIGxvdywgaXQgbWF5IHJlcG9ydCBhbgotICAgKiBpbmZpbml0ZSBsb29wIHNpdHVhdGlvbiwgd2hlbiB0aGVyZSBpcyBub25lLgotICAgKiBQb3N0IHZlcnNpb24gMS4wLjAsIHdlJ2xsIG1ha2UgdGhpcyBhIHJ1bnRpbWUgZmVhdHVyZS4KLSAgICoKLSAgICogQHBhcmFtIGxpbWl0IEEgbnVtYmVyIHRoYXQgcmVwcmVzZW50cyB0aGUgbGltaXQgb2YgcmVjdXJzaW9uLAotICAgKiBvciAtMSBpZiBubyBjaGVja2luZyBpcyB0byBiZSBkb25lLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVjdXJzaW9uTGltaXQoaW50IGxpbWl0KQotICB7Ci0gICAgbV9zdGFja0d1YXJkLnNldFJlY3Vyc2lvbkxpbWl0KGxpbWl0KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFJlc3VsdFRyZWVIYW5kbGVyIG9iamVjdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBSZXN1bHRUcmVlSGFuZGxlciwgd2hpY2ggbWF5IG5vdAotICAgKiBiZSB0aGUgbWFpbiByZXN1bHQgdHJlZSBtYW5hZ2VyLgotICAgKi8KLSAgcHVibGljIFJlc3VsdFRyZWVIYW5kbGVyIGdldFJlc3VsdFRyZWVIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiBtX3Jlc3VsdFRyZWVIYW5kbGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgS2V5TWFuYWdlciBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gQSByZWZlcmVuY2UgdG8gdGhlIEtleU1hbmFnZXIgb2JqZWN0LCB3aGljaCBzaG91bGQKLSAgICogbmV2ZXIgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBLZXlNYW5hZ2VyIGdldEtleU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fa2V5TWFuYWdlcjsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0byBzZWUgaWYgdGhpcyBpcyBhIHJlY3Vyc2l2ZSBhdHRyaWJ1dGUgZGVmaW5pdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGF0dHJTZXQgQSBub24tbnVsbCBFbGVtQXR0cmlidXRlU2V0IHJlZmVyZW5jZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgc2V0IGlzIHJlY3Vyc2l2ZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmVjdXJzaXZlQXR0clNldChFbGVtQXR0cmlidXRlU2V0IGF0dHJTZXQpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fYXR0clNldFN0YWNrKQotICAgIHsKLSAgICAgIG1fYXR0clNldFN0YWNrID0gbmV3IFN0YWNrKCk7Ci0gICAgfQotCi0gICAgaWYgKCFtX2F0dHJTZXRTdGFjay5lbXB0eSgpKQotICAgIHsKLSAgICAgIGludCBsb2MgPSBtX2F0dHJTZXRTdGFjay5zZWFyY2goYXR0clNldCk7Ci0KLSAgICAgIGlmIChsb2MgPiAtMSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2ggYW4gZXhlY3V0aW5nIGF0dHJpYnV0ZSBzZXQsIHNvIHdlIGNhbiBjaGVjayBmb3IKLSAgICogcmVjdXJzaXZlIGF0dHJpYnV0ZSBkZWZpbml0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGF0dHJTZXQgQSBub24tbnVsbCBFbGVtQXR0cmlidXRlU2V0IHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHB1c2hFbGVtQXR0cmlidXRlU2V0KEVsZW1BdHRyaWJ1dGVTZXQgYXR0clNldCkKLSAgewotICAgIG1fYXR0clNldFN0YWNrLnB1c2goYXR0clNldCk7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IGV4ZWN1dGluZyBhdHRyaWJ1dGUgc2V0LgotICAgKi8KLSAgcHVibGljIHZvaWQgcG9wRWxlbUF0dHJpYnV0ZVNldCgpCi0gIHsKLSAgICBtX2F0dHJTZXRTdGFjay5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHRhYmxlIG9mIGNvdW50ZXJzLCBmb3Igb3B0aW1pemVkIHhzbDpudW1iZXIgc3VwcG9ydC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgQ291bnRlcnNUYWJsZSwgbmV2ZXIgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBDb3VudGVyc1RhYmxlIGdldENvdW50ZXJzVGFibGUoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2NvdW50ZXJzVGFibGUpCi0gICAgICBtX2NvdW50ZXJzVGFibGUgPSBuZXcgQ291bnRlcnNUYWJsZSgpOwotCi0gICAgcmV0dXJuIG1fY291bnRlcnNUYWJsZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBjdXJyZW50IHRlbXBsYXRlIHJ1bGUgaXMgbnVsbCwgaS5lLiBpZiB3ZSBhcmUKLSAgICogZGlyZWN0bHkgd2l0aGluIGFuIGFwcGx5LXRlbXBsYXRlcy4gIFVzZWQgZm9yIHhzbDphcHBseS1pbXBvcnRzLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGN1cnJlbnQgdGVtcGxhdGUgcnVsZSBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY3VycmVudFRlbXBsYXRlUnVsZUlzTnVsbCgpCi0gIHsKLSAgICByZXR1cm4gKCghbV9jdXJyZW50VGVtcGxhdGVSdWxlSXNOdWxsLmlzRW1wdHkoKSkKLSAgICAgICAgICAgICYmIChtX2N1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwucGVlaygpID09IHRydWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIHRydWUgaWYgdGhlIGN1cnJlbnQgdGVtcGxhdGUgcnVsZSBpcyBudWxsLCBmYWxzZQotICAgKiBvdGhlcndpc2UuCi0gICAqCi0gICAqIEBwYXJhbSBiIFRydWUgaWYgdGhlIHdlIGFyZSBleGVjdXRpbmcgYW4geHNsOmZvci1lYWNoCi0gICAqIChvciB4c2w6Y2FsbC10ZW1wbGF0ZT8pLgotICAgKi8KLSAgcHVibGljIHZvaWQgcHVzaEN1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwoYm9vbGVhbiBiKQotICB7Ci0gICAgbV9jdXJyZW50VGVtcGxhdGVSdWxlSXNOdWxsLnB1c2goYik7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaCB0cnVlIGlmIHRoZSBjdXJyZW50IHRlbXBsYXRlIHJ1bGUgaXMgbnVsbCwgZmFsc2UKLSAgICogb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgcG9wQ3VycmVudFRlbXBsYXRlUnVsZUlzTnVsbCgpCi0gIHsKLSAgICBtX2N1cnJlbnRUZW1wbGF0ZVJ1bGVJc051bGwucG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBtZXNzYWdlIG1hbmFnZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UgbWFuYWdlciwgbmV2ZXIgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBNc2dNZ3IgZ2V0TXNnTWdyKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tc2dNZ3IpCi0gICAgICBtX21zZ01nciA9IG5ldyBNc2dNZ3IodGhpcyk7Ci0KLSAgICByZXR1cm4gbV9tc2dNZ3I7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBlcnJvciBldmVudCBsaXN0ZW5lci4KLSAgICoKLSAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBuZXcgZXJyb3IgbGlzdGVuZXIuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFcnJvckxpc3RlbmVyKEVycm9yTGlzdGVuZXIgbGlzdGVuZXIpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICBzeW5jaHJvbml6ZWQgKG1fcmVlbnRyeUd1YXJkKQotICAgIHsKLSAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKQotICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbnVsbCkpOyAvLyJOdWxsIGVycm9yIGhhbmRsZXIiKTsKLQotICAgICAgbV9lcnJvckhhbmRsZXIgPSBsaXN0ZW5lcjsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGVycm9yIGV2ZW50IGhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgZXJyb3IgaGFuZGxlciwgd2hpY2ggc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkKLSAgewotICAgIHJldHVybiBtX2Vycm9ySGFuZGxlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIHRyYWNlIG1hbmFnZXIgZm9yIHRoaXMgdHJhbnNmb3JtYXRpb24uCi0gICAqIFRoaXMgb2JqZWN0IGNhbiBiZSB1c2VkIHRvIHNldCB0cmFjZSBsaXN0ZW5lcnMgb24gdmFyaW91cwotICAgKiBldmVudHMgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBBIHJlZmVyZW5jZSB0byB0aGUgVHJhY2VNYW5hZ2VyLCBuZXZlciBudWxsLgotICAgKi8KLSAgcHVibGljIFRyYWNlTWFuYWdlciBnZXRUcmFjZU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fdHJhY2VNYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgdGhlIHZhbHVlIG9mIGEgZmVhdHVyZS4KLSAgICoKLSAgICogPHA+VGhlIGZlYXR1cmUgbmFtZSBpcyBhbnkgZnVsbHktcXVhbGlmaWVkIFVSSS4gIEl0IGlzCi0gICAqIHBvc3NpYmxlIGZvciBhbiBUcmFuc2Zvcm1lckZhY3RvcnkgdG8gcmVjb2duaXplIGEgZmVhdHVyZSBuYW1lIGJ1dAotICAgKiB0byBiZSB1bmFibGUgdG8gcmV0dXJuIGl0cyB2YWx1ZTsgdGhpcyBpcyBlc3BlY2lhbGx5IHRydWUKLSAgICogaW4gdGhlIGNhc2Ugb2YgYW4gYWRhcHRlciBmb3IgYSBTQVgxIFBhcnNlciwgd2hpY2ggaGFzCi0gICAqIG5vIHdheSBvZiBrbm93aW5nIHdoZXRoZXIgdGhlIHVuZGVybHlpbmcgcGFyc2VyIGlzCi0gICAqIHZhbGlkYXRpbmcsIGZvciBleGFtcGxlLjwvcD4KLSAgICoKLSAgICogPGgzPk9wZW4gaXNzdWVzOjwvaDM+Ci0gICAqIDxkbD4KLSAgICogICAgPGR0PjxoND5TaG91bGQgZ2V0RmVhdHVyZSBiZSBjaGFuZ2VkIHRvIGhhc0ZlYXR1cmU/PC9oND48L2R0PgotICAgKiAgICA8ZGQ+S2VpdGggVmlzY28gd3JpdGVzOiBTaG91bGQgZ2V0RmVhdHVyZSBiZSBjaGFuZ2VkIHRvIGhhc0ZlYXR1cmU/Ci0gICAqICAgICAgICBJdCByZXR1cm5zIGEgYm9vbGVhbiB3aGljaCBpbmRpY2F0ZWQgd2hldGhlciB0aGUgInN0YXRlIgotICAgKiAgICAgICAgb2YgZmVhdHVyZSBpcyAidHJ1ZSBvciBmYWxzZSIuIEkgYXNzdW1lIHRoaXMgbWVhbnMgd2hldGhlcgotICAgKiAgICAgICAgb3Igbm90IGEgZmVhdHVyZSBpcyBzdXBwb3J0ZWQ/IEkga25vdyBTQVggaXMgdXNpbmcgImdldEZlYXR1cmUiLAotICAgKiAgICAgICAgYnV0IHRvIG1lICJoYXNGZWF0dXJlIiBpcyBjbGVhbmVyLjwvZGQ+Ci0gICAqIDwvZGw+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUsIHdoaWNoIGlzIGEgZnVsbHktcXVhbGlmaWVkCi0gICAqICAgICAgICBVUkkuCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGZlYXR1cmUgKHRydWUgb3IgZmFsc2UpLgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gV2hlbiB0aGUKLSAgICogICAgICAgICAgICBUcmFuc2Zvcm1lckZhY3RvcnkgZG9lcyBub3QgcmVjb2duaXplIHRoZSBmZWF0dXJlIG5hbWUuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIFdoZW4gdGhlCi0gICAqICAgICAgICAgICAgVHJhbnNmb3JtZXJGYWN0b3J5IHJlY29nbml6ZXMgdGhlIGZlYXR1cmUgbmFtZSBidXQKLSAgICogICAgICAgICAgICBjYW5ub3QgZGV0ZXJtaW5lIGl0cyB2YWx1ZSBhdCB0aGlzIHRpbWUuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbgotICAgKiBAdGhyb3dzIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkKLSAgICAgICAgICB0aHJvd3MgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiwgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICgiaHR0cDovL3htbC5vcmcvdHJheC9mZWF0dXJlcy9zYXgvaW5wdXQiLmVxdWFscyhuYW1lKSkKLSAgICAgIHJldHVybiB0cnVlOwotICAgIGVsc2UgaWYgKCJodHRwOi8veG1sLm9yZy90cmF4L2ZlYXR1cmVzL2RvbS9pbnB1dCIuZXF1YWxzKG5hbWUpKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICB0aHJvdyBuZXcgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbihuYW1lKTsKLSAgfQotCi0gIC8vICVUT0RPJSBEb2MKLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGdldE1vZGUgCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIChnZXRNb2RlKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgUU5hbWUgZ2V0TW9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9tb2Rlcy5pc0VtcHR5KCkgPyBudWxsIDogKFFOYW1lKSBtX21vZGVzLnBlZWsoKTsKLSAgfQotCi0gIC8vICVUT0RPJSBEb2MKLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIHB1c2hNb2RlIAotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gbW9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgcHVzaE1vZGUoUU5hbWUgbW9kZSkKLSAgewotICAgIG1fbW9kZXMucHVzaChtb2RlKTsKLSAgfQotCi0gIC8vICVUT0RPJSBEb2MKLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIHBvcE1vZGUgCi0gICAqCi0gICAqLwotICBwdWJsaWMgdm9pZCBwb3BNb2RlKCkKLSAgewotICAgIG1fbW9kZXMucG9wKCk7Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50IFJ1bm5hYmxlIC8vICAKLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIEJhc2UgdGhyZWFkIGNvbnRyb2xlciBmb3IgeGFsYW4uIE11c3QgYmUgb3ZlcnJpZGVuIHdpdGgKLSAgICogYSBkZXJpdmVkIGNsYXNzIHRvIHN1cHBvcnQgdGhyZWFkIHBvb2xpbmcuCi0gICAqCi0gICAqIEFsbCB0aHJlYWQtcmVsYXRlZCBzdHVmZiBpcyBpbiB0aGlzIGNsYXNzLgotICAgKiAKLSAgICogPHA+PGVtPldBUk5JTkchPC9lbT4gIFRoaXMgY2xhc3Mgd2lsbCBwcm9iYWJseSBtb3ZlIHNpbmNlIHRoZSBEVE0gCi0gICAqIENvcm91dGluZVNBWFBhcnNlciBkZXBlbmRzIG9uIGl0LiAgVGhpcyBjbGFzcyBzaG91bGQgbW92ZSAKLSAgICogdG8gdGhlIENvcm91dGluZVNBWFBhcnNlci4gIFlvdSBjYW4gdXNlIGl0LCBidXQgYmUgYXdhcmUgCi0gICAqIHRoYXQgeW91ciBjb2RlIHdpbGwgaGF2ZSB0byBjaGFuZ2Ugd2hlbiB0aGUgbW92ZSBvY2N1cnMuPC9wPgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBjbGFzcyBUaHJlYWRDb250cm9sZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogV2lsbCBnZXQgYSB0aHJlYWQgZnJvbSB0aGUgcG9vbCwgZXhlY3V0ZSB0aGUgdGFzawotICAgICAqICBhbmQgcmV0dXJuIHRoZSB0aHJlYWQgdG8gdGhlIHBvb2wuCi0gICAgICoKLSAgICAgKiAgVGhlIHJldHVybiB2YWx1ZSBpcyB1c2VkIG9ubHkgdG8gd2FpdCBmb3IgY29tcGxldGlvbgotICAgICAqCi0gICAgICoKLSAgICAgKiBORUVEU0RPQyBAcGFyYW0gdGFzawotICAgICAqIEBwYXJhbSBwcmlvcml0eSBpZiA+MCB0aGUgdGFzayB3aWxsIHJ1biB3aXRoIHRoZSBnaXZlbiBwcmlvcml0eQotICAgICAqICAoIGRvZXNuJ3Qgc2VlbSB0byBiZSB1c2VkIGluIHhhbGFuLCBzaW5jZSBpdCdzIGFsbHdheXMgdGhlIGRlZmF1bHQgKQotICAgICAqIEByZXR1cm5zIFRoZSB0aHJlYWQgdGhhdCBpcyBydW5uaW5nIHRoZSB0YXNrLCBjYW4gYmUgdXNlZAotICAgICAqICAgICAgICAgIHRvIHdhaXQgZm9yIGNvbXBsZXRpb24KLSAgICAgKgotICAgICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGhyZWFkIHJ1bihSdW5uYWJsZSB0YXNrLCBpbnQgcHJpb3JpdHkpCi0gICAgewotCi0gICAgICBUaHJlYWQgdCA9IG5ldyBUaHJlYWQodGFzayk7Ci0KLSAgICAgIHQuc3RhcnQoKTsKLQotICAgICAgLy8gICAgICAgaWYoIHByaW9yaXR5ID4gMCApCi0gICAgICAvLyAgICAgIHQuc2V0UHJpb3JpdHkoIHByaW9yaXR5ICk7Ci0gICAgICByZXR1cm4gdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiAgV2FpdCB1bnRpbCB0aGUgdGFzayBpcyBjb21wbGV0ZWQgb24gdGhlIHdvcmtlcgotICAgICAqICB0aHJlYWQuCi0gICAgICoKLSAgICAgKiBORUVEU0RPQyBAcGFyYW0gd29ya2VyCi0gICAgICogTkVFRFNET0MgQHBhcmFtIHRhc2sKLSAgICAgKgotICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB3YWl0VGhyZWFkKFRocmVhZCB3b3JrZXIsIFJ1bm5hYmxlIHRhc2spCi0gICAgICAgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KLSAgICB7Ci0KLSAgICAgIC8vIFRoaXMgc2hvdWxkIHdhaXQgdW50aWwgdGhlIHRyYW5zZm9ybVRocmVhZCBpcyBjb25zaWRlcmVkIG5vdCBhbGl2ZS4KLSAgICAgIHdvcmtlci5qb2luKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqIE5FRURTRE9DIEZpZWxkIHRwb29sICAgICAgICAgICovCi0gIHN0YXRpYyBUaHJlYWRDb250cm9sZXIgdHBvb2wgPSBuZXcgVGhyZWFkQ29udHJvbGVyKCk7Ci0KLSAgLyoqCi0gICAqIENoYW5nZSB0aGUgVGhyZWFkQ29udHJvbGVyIHRoYXQgd2lsbCBiZSB1c2VkIHRvCi0gICAqICBtYW5hZ2UgdGhlIHRyYW5zZm9ybSB0aHJlYWRzLgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gdHAKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRUaHJlYWRDb250cm9sZXIoVGhyZWFkQ29udHJvbGVyIHRwKQotICB7Ci0gICAgdHBvb2wgPSB0cDsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgU291cmNlVHJlZUhhbmRsZXIgdG8gc3RhcnQgdGhlIHRyYW5zZm9ybWF0aW9uCi0gICAqICBpbiBhIHNlcGFyYXRlIHRocmVhZAotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gcHJpb3JpdHkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1blRyYW5zZm9ybVRocmVhZChpbnQgcHJpb3JpdHkpCi0gIHsKLQotICAgIC8vIHVzZWQgaW4gU291cmNlVHJlZUhhbmRsZXIKLSAgICBUaHJlYWQgdCA9IHRwb29sLnJ1bih0aGlzLCBwcmlvcml0eSk7Ci0KLSAgICB0aGlzLnNldFRyYW5zZm9ybVRocmVhZCh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgdGhpcy50cmFuc2Zvcm0oKSBpZiBpc1BhcnNlckV2ZW50c09uTWFpbigpPT1mYWxzZS4KLSAgICogIFNpbWlsYXIgd2l0aCBydW5UcmFuc2Zvcm1UaHJlYWQoKSwgYnV0IG5vIHByaW9yaXR5IGlzIHNldAotICAgKiAgYW5kIHNldFRyYW5zZm9ybVRocmVhZCBpcyBub3Qgc2V0LgotICAgKi8KLSAgcHVibGljIHZvaWQgcnVuVHJhbnNmb3JtVGhyZWFkKCkKLSAgewotICAgIHRwb29sLnJ1bih0aGlzLCAtMSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYWxsZWQgYnkgQ29Sb3V0aW5lU0FYUGFyc2VyLiBMYXVuY2hlcyB0aGUgQ29yb3V0aW5lU0FYUGFyc2VyCi0gICAqIGluIGEgdGhyZWFkLCBhbmQgcHJlcGFyZXMgaXQgdG8gaW52b2tlIHRoZSBwYXJzZXIgZnJvbSB0aGF0IHRocmVhZAotICAgKiB1cG9uIHJlcXVlc3QuIAotICAgKiAgCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgcnVuVHJhbnNmb3JtVGhyZWFkKFJ1bm5hYmxlIHJ1bm5hYmxlKQotICB7Ci0gICAgdHBvb2wucnVuKHJ1bm5hYmxlLCAtMSk7Ci0gIH0KLQotICAvKioKLSAgICogVXNlZCBieSBTb3VyY2VUcmVlSGFuZGxlciB0byB3YWl0IHVudGlsIHRoZSB0cmFuc2Zvcm0KLSAgICogICBjb21wbGV0ZXMKLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhaXRUcmFuc2Zvcm1UaHJlYWQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFRoaXMgaXMgY2FsbGVkIHRvIG1ha2Ugc3VyZSB0aGUgdGFzayBpcyBkb25lLgotICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIHRocmVhZCBoYXMgYmVlbiByZXVzZWQgLQotICAgIC8vIGJ1dCBmb3IgYSBkaWZmZXJlbnQgdHJhbnNmb3JtYXRpb24uICggd2hhdCBpZiB3ZSAKLSAgICAvLyByZWN5Y2xlIHRoZSB0cmFuc2Zvcm1lciA/IE5vdCBhIHByb2JsZW0gc2luY2UgdGhpcyBpcwotICAgIC8vIHN0aWxsIGluIHVzZS4gKQotICAgIFRocmVhZCB0cmFuc2Zvcm1UaHJlYWQgPSB0aGlzLmdldFRyYW5zZm9ybVRocmVhZCgpOwotCi0gICAgaWYgKG51bGwgIT0gdHJhbnNmb3JtVGhyZWFkKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICB0cG9vbC53YWl0VGhyZWFkKHRyYW5zZm9ybVRocmVhZCwgdGhpcyk7Ci0KLSAgICAgICAgaWYgKCF0aGlzLmhhc1RyYW5zZm9ybVRocmVhZEVycm9yQ2F0Y2hlcigpKQotICAgICAgICB7Ci0gICAgICAgICAgRXhjZXB0aW9uIGUgPSB0aGlzLmdldEV4Y2VwdGlvblRocm93bigpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICB0aGlzLnNldFRyYW5zZm9ybVRocmVhZChudWxsKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSl7fQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGV4Y2VwdGlvbiB0aHJvd24gYnkgdGhlIHNlY29uZGFyeSB0aHJlYWQgKG5vcm1hbGx5Ci0gICAqIHRoZSB0cmFuc2Zvcm0gdGhyZWFkKS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdGhyb3duIGV4Y2VwdGlvbiwgb3IgbnVsbCBpZiBubyBleGNlcHRpb24gd2FzCi0gICAqIHRocm93bi4KLSAgICovCi0gIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uVGhyb3duKCkKLSAgewotICAgIHJldHVybiBtX2V4Y2VwdGlvblRocm93bjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGV4Y2VwdGlvbiB0aHJvd24gYnkgdGhlIHNlY29uZGFyeSB0aHJlYWQgKG5vcm1hbGx5Ci0gICAqIHRoZSB0cmFuc2Zvcm0gdGhyZWFkKS4KLSAgICoKLSAgICogQHBhcmFtIGUgVGhlIHRocm93biBleGNlcHRpb24sIG9yIG51bGwgaWYgbm8gZXhjZXB0aW9uIHdhcwotICAgKiB0aHJvd24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeGNlcHRpb25UaHJvd24oRXhjZXB0aW9uIGUpCi0gIHsKLSAgICBtX2V4Y2VwdGlvblRocm93biA9IGU7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBpcyBqdXN0IGEgd2F5IHRvIHNldCB0aGUgZG9jdW1lbnQgZm9yIHJ1bigpLgotICAgKgotICAgKiBAcGFyYW0gZG9jIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSByb290IG9mIHRoZQotICAgKiB0cmVlIHRvIGJlIHRyYW5zZm9ybWVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U291cmNlVHJlZURvY0ZvclRocmVhZChpbnQgZG9jKQotICB7Ci0gICAgbV9kb2MgPSBkb2M7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSBzb3VyY2UgdHJlZSwgd2hpY2ggaXMgbmVlZGVkIGlmIHRoZQotICAgKiBwYXJzZSB0aHJlYWQgaXMgbm90IHRoZSBtYWluIHRocmVhZCwgaW4gb3JkZXIgZm9yIHRoZSBwYXJzZQotICAgKiB0aHJlYWQncyBydW4gbWV0aG9kIHRvIGdldCB0byB0aGUgaW5wdXQgc291cmNlLgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSBzb3VyY2UgdHJlZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFhNTFNvdXJjZShTb3VyY2Ugc291cmNlKQotICB7Ci0gICAgbV94bWxTb3VyY2UgPSBzb3VyY2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdHJhbnNmb3JtIG1ldGhvZCBpcyBjb21wbGV0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0cmFuc2Zvcm1Ob2RlIGhhcyBjb21wbGV0ZWQsIG9yCi0gICAqIGFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNUcmFuc2Zvcm1Eb25lKCkKLSAgewotCi0gICAgc3luY2hyb25pemVkICh0aGlzKQotICAgIHsKLSAgICAgIHJldHVybiBtX2lzVHJhbnNmb3JtRG9uZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IGlmIHRoZSB0cmFuc2Zvcm0gbWV0aG9kIGlzIGNvbXBsZXRlZC4KLSAgICoKLSAgICogQHBhcmFtIGRvbmUgVHJ1ZSBpZiB0cmFuc2Zvcm1Ob2RlIGhhcyBjb21wbGV0ZWQsIG9yCi0gICAqIGFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXNUcmFuc2Zvcm1Eb25lKGJvb2xlYW4gZG9uZSkKLSAgewotCi0gICAgc3luY2hyb25pemVkICh0aGlzKQotICAgIHsKLSAgICAgIG1faXNUcmFuc2Zvcm1Eb25lID0gZG9uZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRnJvbSBhIHNlY29uZGFyeSB0aHJlYWQsIHBvc3QgdGhlIGV4Y2VwdGlvbiwgc28gdGhhdAotICAgKiBpdCBjYW4gYmUgcGlja2VkIHVwIGZyb20gdGhlIG1haW4gdGhyZWFkLgotICAgKgotICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRoYXQgd2FzIHRocm93bi4KLSAgICovCi0gIHZvaWQgcG9zdEV4Y2VwdGlvbkZyb21UaHJlYWQoRXhjZXB0aW9uIGUpCi0gIHsKLQotICAgIC8vIENvbW1lbnRlZCBvdXQgaW4gcmVzcG9uc2UgdG8gcHJvYmxlbSByZXBvcnRlZCBieSBOaWNvbGEgQnJvd24gPE5pY29sYS5Ccm93bkBqYWNvYnNyaW1lbGwuY29tPgotICAgIC8vICAgIGlmKG1fcmVwb3J0SW5Qb3N0RXhjZXB0aW9uRnJvbVRocmVhZCkKLSAgICAvLyAgICB7Ci0gICAgLy8gICAgICAvLyBDb25zaWRlciByZS10aHJvd2luZyB0aGUgZXhjZXB0aW9uIGlmIHRoaXMgZmxhZyBpcyBzZXQuCi0gICAgLy8gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgIC8vICAgIH0KLSAgICAvLyAlUkVWSUVXIE5lZWQgRFRNIGVxdWl2ZWxlbnQ/ICAgIAotICAgIC8vICAgIGlmIChtX2lucHV0Q29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBTb3VyY2VUcmVlSGFuZGxlcikKLSAgICAvLyAgICB7Ci0gICAgLy8gICAgICBTb3VyY2VUcmVlSGFuZGxlciBzdGggPSAoU291cmNlVHJlZUhhbmRsZXIpIG1faW5wdXRDb250ZW50SGFuZGxlcjsKLSAgICAvLwotICAgIC8vICAgICAgc3RoLnNldEV4Y2VwdGlvblRocm93bihlKTsKLSAgICAvLyAgICB9Ci0gICAgQ29udGVudEhhbmRsZXIgY2ggPSBnZXRDb250ZW50SGFuZGxlcigpOwotCi0gICAgLy8gICAgaWYoY2ggaW5zdGFuY2VvZiBTb3VyY2VUcmVlSGFuZGxlcikKLSAgICAvLyAgICB7Ci0gICAgLy8gICAgICBTb3VyY2VUcmVlSGFuZGxlciBzdGggPSAoU291cmNlVHJlZUhhbmRsZXIpIGNoOwotICAgIC8vICAgICAgKChUcmFuc2Zvcm1lckltcGwpKHN0aC5nZXRUcmFuc2Zvcm1lcigpKSkucG9zdEV4Y2VwdGlvbkZyb21UaHJlYWQoZSk7Ci0gICAgLy8gICAgfQotICAgIG1faXNUcmFuc2Zvcm1Eb25lID0gdHJ1ZTsKLSAgICBtX2V4Y2VwdGlvblRocm93biA9IGU7Ci0gICAgOyAgLy8gc2hvdWxkIGhhdmUgYWxyZWFkeSBiZWVuIHJlcG9ydGVkIHZpYSB0aGUgZXJyb3IgaGFuZGxlcj8KLQotICAgIHN5bmNocm9uaXplZCAodGhpcykKLSAgICB7Ci0KLSAgICAgIC8vIFNlZSBtZXNzYWdlIGZyb20gbWUgb24gMy8yNy8yMDAxIHRvIFBhdHJpY2sgTW9vcmUuCi0gICAgICAvLyAgICAgIFN0cmluZyBtc2cgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAvLyBJcyB0aGlzIHJlYWxseSBuZWVkZWQ/ICAtc2IKLSAgICAgIG5vdGlmeUFsbCgpOwotCi0gICAgICAvLyAgICAgIGlmIChudWxsID09IG1zZykKLSAgICAgIC8vICAgICAgewotICAgICAgLy8KLSAgICAgIC8vICAgICAgICAvLyBtX3Rocm93TmV3RXJyb3IgPSBmYWxzZTsKLSAgICAgIC8vICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgLy8gICAgICB9Ci0gICAgICAvLyB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJ1biB0aGUgdHJhbnNmb3JtIHRocmVhZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1bigpCi0gIHsKLQotICAgIG1faGFzQmVlblJlc2V0ID0gZmFsc2U7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIGludCBuID0gKChTb3VyY2VUcmVlSGFuZGxlcilnZXRJbnB1dENvbnRlbnRIYW5kbGVyKCkpLmdldERUTVJvb3QoKTsKLSAgICAgIC8vIHRyYW5zZm9ybU5vZGUobik7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgbV9pc1RyYW5zZm9ybURvbmUgPSBmYWxzZTsKLSAgICAgICAgCi0gICAgICAgIC8vIFNob3VsZCBubyBsb25nZXIgYmUgbmVlZGVkLi4uCi0vLyAgICAgICAgICBpZihtX2lucHV0Q29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckhhbmRsZXJJbXBsKQotLy8gICAgICAgICAgewotLy8gICAgICAgICAgICBUcmFuc2Zvcm1lckhhbmRsZXJJbXBsIHRoaSA9IChUcmFuc2Zvcm1lckhhbmRsZXJJbXBsKW1faW5wdXRDb250ZW50SGFuZGxlcjsKLS8vICAgICAgICAgICAgdGhpLndhaXRGb3JJbml0aWFsRXZlbnRzKCk7Ci0vLyAgICAgICAgICB9Ci0KLSAgICAgICAgdHJhbnNmb3JtTm9kZShtX2RvYyk7Ci0gICAgICAgIAotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICAvLyBlLnByaW50U3RhY2tUcmFjZSgpOwotCi0gICAgICAgIC8vIFN0cmFuZ2UgdGhhdCB0aGUgb3RoZXIgY2F0Y2ggd29uJ3QgY2F0Y2ggdGhpcy4uLgotICAgICAgICBpZiAobnVsbCAhPSBtX3RyYW5zZm9ybVRocmVhZCkKLSAgICAgICAgICBwb3N0RXhjZXB0aW9uRnJvbVRocmVhZChlKTsgICAvLyBBc3N1bWUgd2UncmUgb24gdGhlIG1haW4gdGhyZWFkCi0gICAgICAgIGVsc2UgCi0gICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwotICAgICAgfQotICAgICAgZmluYWxseQotICAgICAgewotICAgICAgICBtX2lzVHJhbnNmb3JtRG9uZSA9IHRydWU7Ci0KLSAgICAgICAgaWYgKG1faW5wdXRDb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIFRyYW5zZm9ybWVySGFuZGxlckltcGwpCi0gICAgICAgIHsKLSAgICAgICAgICAoKFRyYW5zZm9ybWVySGFuZGxlckltcGwpIG1faW5wdXRDb250ZW50SGFuZGxlcikuY2xlYXJDb1JvdXRpbmUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpCi0gICAgICAgIC8vICAgICAgICB7Ci0gICAgICAgIC8vICAgICAgICAgIG5vdGlmeUFsbCgpOwotICAgICAgICAvLyAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotCi0gICAgICAvLyBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgaWYgKG51bGwgIT0gbV90cmFuc2Zvcm1UaHJlYWQpCi0gICAgICAgIHBvc3RFeGNlcHRpb25Gcm9tVGhyZWFkKGUpOwotICAgICAgZWxzZSAKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOyAgICAgICAgIC8vIEFzc3VtZSB3ZSdyZSBvbiB0aGUgbWFpbiB0aHJlYWQuCi0gICAgfQotICB9Ci0KLSAgLy8gRnJhZ21lbnQgcmUtZXhlY3V0aW9uIGludGVyZmFjZXMgZm9yIGEgdG9vbC4KLQotICAvKioKLSAgICogVGhpcyB3aWxsIGdldCBhIHNuYXBzaG90IG9mIHRoZSBjdXJyZW50IGV4ZWN1dGluZyBjb250ZXh0IAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRyYW5zZm9ybWVyU25hcHNob3Qgb2JqZWN0LCBzbmFwc2hvdCBvZiBleGVjdXRpbmcgY29udGV4dAotICAgKi8KLSAgcHVibGljIFRyYW5zZm9ybVNuYXBzaG90IGdldFNuYXBzaG90KCkKLSAgewotICAgIHJldHVybiBuZXcgVHJhbnNmb3JtU25hcHNob3RJbXBsKHRoaXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgd2lsbCBleGVjdXRlIHRoZSBmb2xsb3dpbmcgWFNMVCBpbnN0cnVjdGlvbnMKLSAgICogZnJvbSB0aGUgc25hcHNob3QgcG9pbnQsIGFmdGVyIHRoZSBzdHlsZXNoZWV0IGV4ZWN1dGlvbgotICAgKiBjb250ZXh0IGhhcyBiZWVuIHJlc2V0IGZyb20gdGhlIHNuYXBzaG90IHBvaW50LiAKLSAgICoKLSAgICogQHBhcmFtIHRzIFRoZSBzbmFwc2hvdCBvZiB3aGVyZSB0byBzdGFydCBleGVjdXRpb24KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXhlY3V0ZUZyb21TbmFwc2hvdChUcmFuc2Zvcm1TbmFwc2hvdCB0cykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRWxlbVRlbXBsYXRlRWxlbWVudCB0ZW1wbGF0ZSA9IGdldE1hdGNoZWRUZW1wbGF0ZSgpOwotICAgIGludCBjaGlsZCA9IGdldE1hdGNoZWROb2RlKCk7Ci0KLSAgICBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudCh0ZW1wbGF0ZSk7ICAvL25lZWRlZD8/Ci0gICAgbV94Y29udGV4dC5wdXNoQ3VycmVudE5vZGUoY2hpbGQpOyAgLy9uZWVkZWQ/PwotICAgIHRoaXMuZXhlY3V0ZUNoaWxkVGVtcGxhdGVzKHRlbXBsYXRlLCB0cnVlKTsgIC8vIGdldFJlc3VsdFRyZWVIYW5kbGVyKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgd2lsbCByZXNldCB0aGUgc3R5bGVzaGVldCBleGVjdXRpb24gY29udGV4dAotICAgKiBmcm9tIHRoZSBzbmFwc2hvdCBwb2ludC4KLSAgICoKLSAgICogQHBhcmFtIHRzIFRoZSBzbmFwc2hvdCBvZiB3aGVyZSB0byBzdGFydCBleGVjdXRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0VG9TdHlsZXNoZWV0KFRyYW5zZm9ybVNuYXBzaG90IHRzKQotICB7Ci0gICAgKChUcmFuc2Zvcm1TbmFwc2hvdEltcGwpIHRzKS5hcHBseSh0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBORUVEU0RPQyBNZXRob2Qgc3RvcFRyYW5zZm9ybWF0aW9uIAotICAgKgotICAgKi8KLSAgcHVibGljIHZvaWQgc3RvcFRyYW5zZm9ybWF0aW9uKCl7fQotCi0gIC8qKgotICAgKiBUZXN0IHdoZXRoZXIgd2hpdGVzcGFjZS1vbmx5IHRleHQgbm9kZXMgYXJlIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwKLSAgICogdmlldyBvZiA8Y29kZT5EVE08L2NvZGU+LiBOb3JtYWxseSwgdGhpcyBmdW5jdGlvbgotICAgKiB3aWxsIGJlIGNhbGxlZCBieSB0aGUgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+RFRNPC9jb2RlPjsKLSAgICogaXQgaXMgbm90IG5vcm1hbGx5IGNhbGxlZCBkaXJlY3RseSBmcm9tCi0gICAqIHVzZXIgY29kZS4KLSAgICoKLSAgICogQHBhcmFtIGVsZW1lbnRIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgZWxlbWVudC4KLSAgICogQHJldHVybiBvbmUgb2YgTk9UU1RSSVAsIFNUUklQLCBvciBJTkhFUklULgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldFNob3VsZFN0cmlwU3BhY2UoaW50IGVsZW1lbnRIYW5kbGUsIERUTSBkdG0pCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLldoaXRlU3BhY2VJbmZvIGluZm8gPQotICAgICAgICBtX3N0eWxlc2hlZXRSb290LmdldFdoaXRlU3BhY2VJbmZvKG1feGNvbnRleHQsIGVsZW1lbnRIYW5kbGUsIGR0bSk7Ci0KLSAgICAgIGlmIChudWxsID09IGluZm8pCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBEVE1XU0ZpbHRlci5JTkhFUklUOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U2hvdWxkU3RyaXBTcGFjZTogIitpbmZvLmdldFNob3VsZFN0cmlwU3BhY2UoKSk7Ci0gICAgICAgIHJldHVybiBpbmZvLmdldFNob3VsZFN0cmlwU3BhY2UoKQotICAgICAgICAgICAgICAgPyBEVE1XU0ZpbHRlci5TVFJJUCA6IERUTVdTRmlsdGVyLk5PVFNUUklQOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgcmV0dXJuIERUTVdTRmlsdGVyLklOSEVSSVQ7Ci0gICAgfQotICB9Ci19ICAvLyBlbmQgVHJhbnNmb3JtZXJJbXBsIGNsYXNzCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyZWVXYWxrZXIyUmVzdWx0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmVlV2Fsa2VyMlJlc3VsdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYjNmNmZhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1RyZWVXYWxrZXIyUmVzdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTVRyZWVXYWxrZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTXV0YWJsZUF0dHJMaXN0SW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRE9NSGVscGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogSGFuZGxlIGEgd2FsayBvZiBhIHRyZWUsIGJ1dCBzY3JlZW4gb3V0IGF0dHJpYnV0ZXMgZm9yCi0gKiB0aGUgcmVzdWx0IHRyZWUuCi0gKi8KLXB1YmxpYyBjbGFzcyBUcmVlV2Fsa2VyMlJlc3VsdCBleHRlbmRzIERUTVRyZWVXYWxrZXIKLXsKLQotICAvKiogVGhlIHRyYW5zZm9ybWVyIGluc3RhbmNlICAgICAgICAgICovCi0gIFRyYW5zZm9ybWVySW1wbCBtX3RyYW5zZm9ybWVyOwotCi0gIC8qKiBUaGUgcmVzdWx0IHRyZWUgaGFuZGxlciAgICAgICAgICAqLwotICBSZXN1bHRUcmVlSGFuZGxlciBtX2hhbmRsZXI7Ci0KLSAgLyoqIE5vZGUgd2hlcmUgdG8gc3RhcnQgdGhlIHRyZWUgd2FsayAgICAgICAgICAgKi8KLSAgaW50IG1fc3RhcnROb2RlOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHRyYW5zZm9ybWVyIE5vbi1udWxsIHRyYW5zZm9ybWVyIGluc3RhbmNlCi0gICAqIEBwYXJhbSBoYW5kbGVyIFRoZSBSZXN1bHQgdHJlZSBoYW5kbGVyIHRvIHVzZQotICAgKi8KLSAgcHVibGljIFRyZWVXYWxrZXIyUmVzdWx0KFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdFRyZWVIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLQotICAgIHN1cGVyKGhhbmRsZXIsIG51bGwpOwotCi0gICAgbV90cmFuc2Zvcm1lciA9IHRyYW5zZm9ybWVyOwotICAgIG1faGFuZGxlciA9IGhhbmRsZXI7Ci0gIH0KLQotICAvKioKLSAgICogUGVyZm9ybSBhIHByZS1vcmRlciB0cmF2ZXJzYWwgbm9uLXJlY3Vyc2l2ZSBzdHlsZS4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBTdGFydCBub2RlIGZvciB0cmF2ZXJzYWwKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhdmVyc2UoaW50IHBvcykgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbV9kdG0gPSBtX3RyYW5zZm9ybWVyLmdldFhQYXRoQ29udGV4dCgpLmdldERUTShwb3MpOwotICAgIG1fc3RhcnROb2RlID0gcG9zOwotCi0gICAgc3VwZXIudHJhdmVyc2UocG9zKTsKLSAgfQotICAgICAgICAKLSAgICAgICAgLyoqCi0gICAqIEVuZCBwcm9jZXNzaW5nIG9mIGdpdmVuIG5vZGUgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgd2UganVzdCBmaW5pc2hlZCBwcm9jZXNzaW5nCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlbmROb2RlKGludCBub2RlKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlci5lbmROb2RlKG5vZGUpOwotICAgIGlmKERUTS5FTEVNRU5UX05PREUgPT0gbV9kdG0uZ2V0Tm9kZVR5cGUobm9kZSkpCi0gICAgewotICAgICAgbV90cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKS5wb3BDdXJyZW50Tm9kZSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTdGFydCB0cmF2ZXJzYWwgb2YgdGhlIHRyZWUgYXQgdGhlIGdpdmVuIG5vZGUKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5vZGUgU3RhcnRpbmcgbm9kZSBmb3IgdHJhdmVyc2FsCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHN0YXJ0Tm9kZShpbnQgbm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBYUGF0aENvbnRleHQgeGNudHh0ID0gbV90cmFuc2Zvcm1lci5nZXRYUGF0aENvbnRleHQoKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAKLSAgICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IG1fZHRtLmdldE5vZGVUeXBlKG5vZGUpKQotICAgICAgewotICAgICAgICB4Y250eHQucHVzaEN1cnJlbnROb2RlKG5vZGUpOyAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgaWYobV9zdGFydE5vZGUgIT0gbm9kZSkKLSAgICAgICAgewotICAgICAgICAgIHN1cGVyLnN0YXJ0Tm9kZShub2RlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcgZWxlbU5hbWUgPSBtX2R0bS5nZXROb2RlTmFtZShub2RlKTsKLSAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gbV9kdG0uZ2V0TG9jYWxOYW1lKG5vZGUpOwotICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBtX2R0bS5nZXROYW1lc3BhY2VVUkkobm9kZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgLy94Y250eHQucHVzaEN1cnJlbnROb2RlKG5vZGUpOyAgICAgICAKLSAgICAgICAgICBtX2hhbmRsZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZSwgbG9jYWxOYW1lLCBlbGVtTmFtZSwgbnVsbCk7Ci0KLSAgICAgICAgICBib29sZWFuIGhhc05TRGVjbHMgPSBmYWxzZTsKLSAgICAgICAgICBEVE0gZHRtID0gbV9kdG07Ci0gICAgICAgICAgZm9yIChpbnQgbnMgPSBkdG0uZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKG5vZGUsIHRydWUpOyAKLSAgICAgICAgICAgICAgIERUTS5OVUxMICE9IG5zOyBucyA9IGR0bS5nZXROZXh0TmFtZXNwYWNlTm9kZShub2RlLCBucywgdHJ1ZSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgbV9oYW5kbGVyLmVuc3VyZU5hbWVzcGFjZURlY2xEZWNsYXJlZChkdG0sIG5zKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAvLyAlUkVWSUVXJSBUaGlzIGZsYWcgaXMgYXBwYXJlbnRseSBuZXZlciBzZXQgdHJ1ZS4gSXMgdGhhdAotICAgICAgICAgIC8vIGEgYnVnLCBvciBzaG91bGQgdGhpcyBjb2RlIGJlIHBoYXNlZCBvdXQ/Ci0gICAgICAgICAgaWYoaGFzTlNEZWNscykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2hhbmRsZXIuYWRkTlNEZWNsc1RvQXR0cnMoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICBmb3IgKGludCBhdHRyID0gZHRtLmdldEZpcnN0QXR0cmlidXRlKG5vZGUpOyAKLSAgICAgICAgICAgICAgIERUTS5OVUxMICE9IGF0dHI7IGF0dHIgPSBkdG0uZ2V0TmV4dEF0dHJpYnV0ZShhdHRyKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2hhbmRsZXIuYWRkQXR0cmlidXRlKGF0dHIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgeGNudHh0LnB1c2hDdXJyZW50Tm9kZShub2RlKTsKLSAgICAgICAgc3VwZXIuc3RhcnROb2RlKG5vZGUpOwotICAgICAgICB4Y250eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1hTTEluZmluaXRlTG9vcEV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvWFNMSW5maW5pdGVMb29wRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkZDBmOTAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvWFNMSW5maW5pdGVMb29wRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgdXNlZCB0byBjcmVhdGUgYW4gSW5maW5pdGUgTG9vcCBFeGNlcHRpb24gCi0gKi8KLWNsYXNzIFhTTEluZmluaXRlTG9vcEV4Y2VwdGlvbgotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBYU0xJbmZpbml0ZUxvb3BFeGNlcHRpb24KLSAgICoKLSAgICovCi0gIFhTTEluZmluaXRlTG9vcEV4Y2VwdGlvbigpCi0gIHsKLSAgICBzdXBlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBNZXNzYWdlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXhjZXB0aW9uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gTWVzc2FnZSBhc3NvY2lhdGVkIHdpdGggdGhlIGV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkKLSAgewotICAgIHJldHVybiAiUHJvY2Vzc2luZyBUZXJtaW5hdGVkLiI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1hhbGFuUHJvcGVydGllcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvWGFsYW5Qcm9wZXJ0aWVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI3YzE0YTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvWGFsYW5Qcm9wZXJ0aWVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBPdmlkaXUKLSAqIFByZWRlc2N1IDxvdmlkaXVAY3VwLmhwLmNvbT4gb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUKLSAqIEZvdW5kYXRpb24gYW5kIHdhcyBvcmlnaW5hbGx5IGRldmVsb3BlZCBhdCBIZXdsZXR0IFBhY2thcmQgQ29tcGFueS4KLSAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lcjsKLQotLyoqCi0gKiA8Y29kZT5YYWxhblByb3BlcnRpZXM8L2NvZGU+IGRlZmluZXMgdGhlIGZlYXR1cmVzIHVuZGVyc3Rvb2QgYnkKLSAqIFhhbGFuLgotICoKLSAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOm92aWRpdUBjdXAuaHAuY29tIj5PdmlkaXUgUHJlZGVzY3U8L2E+Ci0gQCBAc2luY2UgTWF5IDIzLCAyMDAxCi0gKi8KLXB1YmxpYyBjbGFzcyBYYWxhblByb3BlcnRpZXMKLXsKLSAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgU09VUkNFX0xPQ0FUSU9OCi0gICAgPSAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3Byb3BlcnRpZXMvc291cmNlLWxvY2F0aW9uIjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTI4MzgxNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyMSArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIFRyYW5zZm9ybWVyIFBhY2thZ2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW4gY2hhcmdlIG9mIHJ1bi10aW1lIHRyYW5zZm9ybWF0aW9ucyBhbmQgdGhlIHByb2R1Y3Rpb24gb2YgcmVzdWx0IHRyZWVzLjwvcD4KLSAgICAKLSAgICA8cD57QGxpbmsgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGx9IGltcGxlbWVudHMgdGhlIAotICAgIHtAbGluayBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyfSBpbnRlcmZhY2UsIGFuZCBpcyB0aGUgY29yZSByZXByZXNlbnRhdGlvbiAKLSAgICBvZiB0aGUgdHJhbnNmb3JtYXRpb24gZXhlY3V0aW9uLjwvcD4KLSAgICA8cD5Gb3IgZWFjaCBub2RlIGluIHRoZSBYTUwgc291cmNlLCBUcmFuc2Zvcm1lckltcGwgdXNlcyB0aGUgU3R5bGVzaGVldFJvb3QgYW5kIHVuZGVybHlpbmcgWFNMVCBzY2hlbWEgdG8gZGV0ZXJtaW5lIHdoaWNoCi0gICAgdGVtcGxhdGUgdG8gYXBwbHk6IG9uZSBvZiB0aGUgdGVtcGxhdGVzIGluIHRoZSBTdHlsZXNoZWV0Um9vdCwgYSBkZWZhdWx0IHRlbXBsYXRlIHJ1bGUgYXMgc3BlY2lmaWVkIGluIHRoZSBYU0xUIHNwZWMsIG9yCi0gICAgbm9uZS48L3A+Ci0gICAgPHA+VGhlIFRyYW5zZm9ybWVyIHdvcmtzIHdpdGgge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuUmVzdWx0VHJlZUhhbmRsZXJ9IHRvIAotICAgIGZvcndhcmQgdGhlIFNBWCBldmVudHMgcHJvZHVjZWQgYnkgdGhlCi0gICAgdHJhbnNmb3JtYXRpb24gdG8gdGhlIGFwcHJvcHJpYXRlIG91dHB1dCBDb250ZW50SGFuZGxlci48L3A+Ci0gICAgPHA+VG8gdGhlIGRlZ3JlZSBwb3NzaWJsZSwgdGhlIHBhcnNpbmcgb2YgdGhlIFhNTCBzb3VyY2UgYW5kIGFwcGxpY2F0aW9uIG9mIHRoZSBUZW1wbGF0ZXMgb2JqZWN0IHRvIHRoYXQgc291cmNlIGFyZSBwZXJmb3JtZWQKLSAgICBjb25jdXJyZW50bHkgaW4gc2VwYXJhdGUgdGhyZWFkcy4gV2hlbiBuZWNlc3NhcnksIHRoZSBUcmFuc2Zvcm1lciB3YWl0cyBmb3IgdGhlIHBhcnNlIGV2ZW50cyB0aGF0IG11c3QgYmUgaW4gcGxhY2UgYmVmb3JlIGEKLSAgICBnaXZlbiB0ZW1wbGF0ZSBtYXkgYmUgYXBwbGllZC48L3A+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvRW52aXJvbm1lbnRDaGVjay5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9FbnZpcm9ubWVudENoZWNrLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU1ZDgzNTcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9FbnZpcm9ubWVudENoZWNrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjIzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdDsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKLQotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotLy8gVXNlZCBpbiBhcHBlbmQqIG1ldGhvZHMgb25seQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiBVdGlsaXR5IGNsYXNzIHRvIHJlcG9ydCBzaW1wbGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGVudmlyb25tZW50LgotICogU2ltcGxpc3RpYyByZXBvcnRpbmcgYWJvdXQgY2VydGFpbiBjbGFzc2VzIGZvdW5kIGluIHlvdXIgSlZNIG1heSAKLSAqIGhlbHAgYW5zd2VyIHNvbWUgRkFRcyBmb3Igc2ltcGxlIHByb2JsZW1zLgotICoKLSAqIDxwPlVzYWdlLWNvbW1hbmQgbGluZTogIAotICogPGNvZGU+Ci0gKiBqYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5FbnZpcm9ubWVudENoZWNrIFstb3V0IG91dEZpbGVdCi0gKiA8L2NvZGU+PC9wPgotICogCi0gKiA8cD5Vc2FnZS1mcm9tIHByb2dyYW06ICAKLSAqIDxjb2RlPgotICogYm9vbGVhbiBlbnZpcm9ubWVudE9LID0gCi0gKiAobmV3IEVudmlyb25tZW50Q2hlY2soKSkuY2hlY2tFbnZpcm9ubWVudCh5b3VyUHJpbnRXcml0ZXIpOwotICogPC9jb2RlPjwvcD4KLSAqCi0gKiA8cD5Vc2FnZS1mcm9tIHN0eWxlc2hlZXQ6ICAKLSAqIDxjb2RlPjxwcmU+Ci0gKiAgICAmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLSAqICAgICZsdDt4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIgotICogICAgICAgIHhtbG5zOnhhbGFuPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4iCi0gKiAgICAgICAgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXM9InhhbGFuIiZndDsKLSAqICAgICZsdDt4c2w6b3V0cHV0IGluZGVudD0ieWVzIi8mZ3Q7Ci0gKiAgICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIiZndDsKLSAqICAgICAgJmx0O3hzbDpjb3B5LW9mIHNlbGVjdD0ieGFsYW46Y2hlY2tFbnZpcm9ubWVudCgpIi8mZ3Q7Ci0gKiAgICAmbHQ7L3hzbDp0ZW1wbGF0ZSZndDsKLSAqICAgICZsdDsveHNsOnN0eWxlc2hlZXQmZ3Q7Ci0gKiA8L3ByZT48L2NvZGU+PC9wPgotICogIAotICogPHA+WGFsYW4gdXNlcnMgcmVwb3J0aW5nIHByb2JsZW1zIGFyZSBlbmNvdXJhZ2VkIHRvIHVzZSB0aGlzIGNsYXNzIAotICogdG8gc2VlIGlmIHRoZXJlIGFyZSBwb3RlbnRpYWwgcHJvYmxlbXMgd2l0aCB0aGVpciBhY3R1YWwgCi0gKiBKYXZhIGVudmlyb25tZW50IDxiPmJlZm9yZTwvYj4gcmVwb3J0aW5nIGEgYnVnLiAgTm90ZSB0aGF0IHlvdSAKLSAqIHNob3VsZCBib3RoIGNoZWNrIGZyb20gdGhlIEpWTS9KUkUncyBjb21tYW5kIGxpbmUgYXMgd2VsbCBhcyAKLSAqIHRlbXBvcmFyaWx5IGNhbGxpbmcgY2hlY2tFbnZpcm9ubWVudCgpIGRpcmVjdGx5IGZyb20geW91ciBjb2RlLCAKLSAqIHNpbmNlIHRoZSBjbGFzc3BhdGggbWF5IGRpZmZlciAoZXNwZWNpYWxseSBmb3Igc2VydmxldHMsIGV0YykuPC9wPgotICoKLSAqIDxwPkFsc28gc2VlIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi1qL2ZhcS5odG1sPC9wPgotICoKLSAqIDxwPk5vdGU6IFRoaXMgY2xhc3MgaXMgcHJldHR5IHNpbXBsaXN0aWM6IGl0IGRvZXMgYSBmYWlybHkgc2ltcGxlIAotICogdW5vcmRlcmVkIHNlYXJjaCBvZiB0aGUgY2xhc3NwYXRoOyBpdCBvbmx5IHVzZXMgQ2xhc3MuZm9yTmFtZSgpIAotICogdG8gbG9hZCB0aGluZ3MsIG5vdCBhY3R1YWxseSBxdWVyeWluZyB0aGUgY2xhc3Nsb2FkZXI7IHNvIHRoZSAKLSAqIHJlc3VsdHMgYXJlIG5vdCBuZWNlc3NhcmlseSBkZWZpbml0aXZlIG5vciB3aWxsIGl0IGZpbmQgYWxsIAotICogcHJvYmxlbXMgcmVsYXRlZCB0byBlbnZpcm9ubWVudCBzZXR1cC4gIEFsc28sIHlvdSBzaG91bGQgYXZvaWQgCi0gKiBjYWxsaW5nIHRoaXMgaW4gZGVwbG95ZWQgcHJvZHVjdGlvbiBjb2RlLCBib3RoIGJlY2F1c2UgaXQgaXMgCi0gKiBxdWl0ZSBzbG93IGFuZCBiZWNhdXNlIGl0IGZvcmNlcyBjbGFzc2VzIHRvIGdldCBsb2FkZWQuPC9wPgotICoKLSAqIDxwPk5vdGU6IFRoaXMgY2xhc3MgZXhwbGljaXRseSBoYXMgdmVyeSBsaW1pdGVkIGNvbXBpbGUtdGltZSAKLSAqIGRlcGVuZGVuY2llcyB0byBlbmFibGUgZWFzeSBjb21waWxhdGlvbiBhbmQgdXNhZ2UgZXZlbiB3aGVuIAotICogWGFsYW4sIERPTS9TQVgvSkFYUCwgZXRjLiBhcmUgbm90IHByZXNlbnQuPC9wPgotICogCi0gKiBAYXV0aG9yIFNoYW5lX0N1cmN1cnVAbG90dXMuY29tCi0gKiBAdmVyc2lvbiAkSWQkCi0gKi8KLXB1YmxpYyBjbGFzcyBFbnZpcm9ubWVudENoZWNrCi17Ci0KLSAgLyoqCi0gICAqIENvbW1hbmQgbGluZSBydW5uYWJpbGl0eTogY2hlY2tzIGZvciBbLW91dCBvdXRGaWxlbmFtZV0gYXJnLgotICAgKiA8cD5Db21tYW5kIGxpbmUgZW50cnlwb2ludDsgU2V0cyBvdXRwdXQgYW5kIGNhbGxzIAotICAgKiB7QGxpbmsgI2NoZWNrRW52aXJvbm1lbnQoUHJpbnRXcml0ZXIpfS48L3A+Ci0gICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmdzCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQotICB7Ci0gICAgLy8gRGVmYXVsdCB0byBTeXN0ZW0ub3V0LCBhdXRvZmx1c2hpbmcKLSAgICBQcmludFdyaXRlciBzZW5kT3V0cHV0VG8gPSBuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLm91dCwgdHJ1ZSk7Ci0KLSAgICAvLyBSZWFkIG91ciBzaW1wbGlzdGljIGlucHV0IGFyZ3MsIGlmIHN1cHBsaWVkCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKQotICAgIHsKLSAgICAgIGlmICgiLW91dCIuZXF1YWxzSWdub3JlQ2FzZShhcmdzW2ldKSkKLSAgICAgIHsKLSAgICAgICAgaSsrOwotCi0gICAgICAgIGlmIChpIDwgYXJncy5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBzZW5kT3V0cHV0VG8gPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVXcml0ZXIoYXJnc1tpXSwgdHJ1ZSkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIjIFdBUk5JTkc6IC1vdXQgIiArIGFyZ3NbaV0gKyAiIHRocmV3ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGUudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICIjIFdBUk5JTkc6IC1vdXQgYXJndW1lbnQgc2hvdWxkIGhhdmUgYSBmaWxlbmFtZSwgb3V0cHV0IHNlbnQgdG8gY29uc29sZSIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgRW52aXJvbm1lbnRDaGVjayBhcHAgPSBuZXcgRW52aXJvbm1lbnRDaGVjaygpOwotICAgIGFwcC5jaGVja0Vudmlyb25tZW50KHNlbmRPdXRwdXRUbyk7Ci0gIH0KLQotICAvKioKLSAgICogUHJvZ3JhbW1hdGljIGVudHJ5cG9pbnQ6IFJlcG9ydCBvbiBiYXNpYyBKYXZhIGVudmlyb25tZW50IAotICAgKiBhbmQgQ0xBU1NQQVRIIHNldHRpbmdzIHRoYXQgYWZmZWN0IFhhbGFuLgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBjbGFzcyBpcyBub3QgYWR2YW5jZWQgZW5vdWdoIHRvIHRlbGwgeW91IAotICAgKiBldmVyeXRoaW5nIGFib3V0IHRoZSBlbnZpcm9ubWVudCB0aGF0IGFmZmVjdHMgWGFsYW4sIGFuZCAKLSAgICogc29tZXRpbWVzIHJlcG9ydHMgZXJyb3JzIHRoYXQgd2lsbCBub3QgYWN0dWFsbHkgYWZmZWN0IAotICAgKiBYYWxhbidzIGJlaGF2aW9yLiAgQ3VycmVudGx5LCBpdCB2ZXJ5IHNpbXBsaXN0aWNhbGx5IAotICAgKiBjaGVja3MgdGhlIEpWTSdzIGVudmlyb25tZW50IGZvciBzb21lIGJhc2ljIHByb3BlcnRpZXMgYW5kIAotICAgKiBsb2dzIHRoZW0gb3V0OyBpdCB3aWxsIHJlcG9ydCBhIHByb2JsZW0gaWYgaXQgZmluZHMgYSBzZXR0aW5nIAotICAgKiBvciAuamFyIGZpbGUgdGhhdCBpcyA8aT5saWtlbHk8L2k+IHRvIGNhdXNlIHByb2JsZW1zLjwvcD4KLSAgICoKLSAgICogPHA+QWR2YW5jZWQgdXNlcnMgY2FuIHBlcnVzZSB0aGUgY29kZSBoZXJlaW4gdG8gaGVscCB0aGVtIAotICAgKiBpbnZlc3RpZ2F0ZSBwb3RlbnRpYWwgZW52aXJvbm1lbnQgcHJvYmxlbXMgZm91bmQ7IG90aGVyIHVzZXJzIAotICAgKiBtYXkgc2ltcGx5IHNlbmQgdGhlIG91dHB1dCBmcm9tIHRoaXMgdG9vbCBhbG9uZyB3aXRoIGFueSBidWdzIAotICAgKiB0aGV5IHN1Ym1pdCB0byBoZWxwIHVzIGluIHRoZSBkZWJ1Z2dpbmcgcHJvY2Vzcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBwdyBQcmludFdyaXRlciB0byBzZW5kIG91dHB1dCB0bzsgY2FuIGJlIHNlbnQgdG8gYSAKLSAgICogZmlsZSB0aGF0IHdpbGwgbG9vayBzaW1pbGFyIHRvIGEgUHJvcGVydGllcyBmaWxlOyBkZWZhdWx0cyAKLSAgICogdG8gU3lzdGVtLm91dCBpZiBudWxsCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB5b3VyIGVudmlyb25tZW50IGFwcGVhcnMgdG8gaGF2ZSBubyBtYWpvciAKLSAgICogcHJvYmxlbXM7IGZhbHNlIGlmIHBvdGVudGlhbCBlbnZpcm9ubWVudCBwcm9ibGVtcyBmb3VuZAotICAgKiBAc2VlICNnZXRFbnZpcm9ubWVudEhhc2goKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY2hlY2tFbnZpcm9ubWVudChQcmludFdyaXRlciBwdykKLSAgewotCi0gICAgLy8gVXNlIHVzZXItc3BlY2lmaWVkIG91dHB1dCB3cml0ZXIgaWYgbm9uLW51bGwKLSAgICBpZiAobnVsbCAhPSBwdykKLSAgICAgIG91dFdyaXRlciA9IHB3OwotCi0gICAgLy8gU2V0dXAgYSBoYXNoIHRvIHN0b3JlIHZhcmlvdXMgZW52aXJvbm1lbnQgaW5mb3JtYXRpb24gaW4KLSAgICBIYXNodGFibGUgaGFzaCA9IGdldEVudmlyb25tZW50SGFzaCgpOwotCi0gICAgLy8gQ2hlY2sgZm9yIEVSUk9SIGtleXMgaW4gdGhlIGhhc2h0YWJsZSwgYW5kIHByaW50IHJlcG9ydAotICAgIGJvb2xlYW4gZW52aXJvbm1lbnRIYXNFcnJvcnMgPSB3cml0ZUVudmlyb25tZW50UmVwb3J0KGhhc2gpOwotCi0gICAgaWYgKGVudmlyb25tZW50SGFzRXJyb3JzKQotICAgIHsKLSAgICAgIC8vIE5vdGU6IG1hbnkgbG9nTXNnIGNhbGxzIGhhdmUgIyBhdCB0aGUgc3RhcnQgdG8gCi0gICAgICAvLyAgZmFrZSBhIHByb3BlcnR5LWZpbGUgbGlrZSBvdXRwdXQKLSAgICAgIGxvZ01zZygiIyBXQVJOSU5HOiBQb3RlbnRpYWwgcHJvYmxlbXMgZm91bmQgaW4geW91ciBlbnZpcm9ubWVudCEiKTsKLSAgICAgIGxvZ01zZygiIyAgICBDaGVjayBhbnkgJ0VSUk9SJyBpdGVtcyBhYm92ZSBhZ2FpbnN0IHRoZSBYYWxhbiBGQVFzIik7Ci0gICAgICBsb2dNc2coIiMgICAgdG8gY29ycmVjdCBwb3RlbnRpYWwgcHJvYmxlbXMgd2l0aCB5b3VyIGNsYXNzZXMvamFycyIpOwotICAgICAgbG9nTXNnKCIjICAgIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi1qL2ZhcS5odG1sIik7Ci0gICAgICBpZiAobnVsbCAhPSBvdXRXcml0ZXIpCi0gICAgICAgIG91dFdyaXRlci5mbHVzaCgpOwotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbG9nTXNnKCIjIFlBSE9PISBZb3VyIGVudmlyb25tZW50IHNlZW1zIHRvIGJlIE9LLiIpOwotICAgICAgaWYgKG51bGwgIT0gb3V0V3JpdGVyKQotICAgICAgICBvdXRXcml0ZXIuZmx1c2goKTsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaWxsIGEgaGFzaCB3aXRoIGJhc2ljIGVudmlyb25tZW50IHNldHRpbmdzIHRoYXQgYWZmZWN0IFhhbGFuLgotICAgKgotICAgKiA8cD5Xb3JrZXIgbWV0aG9kIGNhbGxlZCBmcm9tIHZhcmlvdXMgcGxhY2VzLjwvcD4KLSAgICogPHA+VmFyaW91cyBzeXN0ZW0gYW5kIENMQVNTUEFUSCwgZXRjLiBwcm9wZXJ0aWVzIGFyZSBwdXQgaW50byAKLSAgICogdGhlIGhhc2ggYXMga2V5cyB3aXRoIGEgYnJpZWYgZGVzY3JpcHRpb24gb2YgdGhlIGN1cnJlbnQgc3RhdGUgCi0gICAqIG9mIHRoYXQgaXRlbSBhcyB0aGUgdmFsdWUuICBBbnkgc2VyaW91cyBwcm9ibGVtcyB3aWxsIGJlIHB1dCBpbiAKLSAgICogd2l0aCBhIGtleSB0aGF0IGlzIHByZWZpeGVkIHdpdGgge0BsaW5rICNFUlJPUiAnRVJST1IuJ30gc28gaXQKLSAgICogc3RhbmRzIG91dCBpbiBhbnkgcmVzdWx0aW5nIHJlcG9ydDsgYWxzbyBhIGtleSB3aXRoIGp1c3QgdGhhdCAKLSAgICogY29uc3RhbnQgd2lsbCBiZSBzZXQgYXMgd2VsbCBmb3IgYW55IGVycm9yLjwvcD4KLSAgICogPHA+Tm90ZSB0aGF0IHNvbWUgbGVnaXRpbWF0ZSBjYXNlcyBhcmUgZmxhZ2VkIGFzIHBvdGVudGlhbCAKLSAgICogZXJyb3JzIC0gbmFtZWx5IHdoZW4gYSBkZXZlbG9wZXIgcmVjb21waWxlcyB4YWxhbi5qYXIgb24gdGhlaXIgCi0gICAqIG93biAtIGFuZCBldmVuIGEgbm9uLWVycm9yIHN0YXRlIGRvZXNuJ3QgZ3VhcnVudGVlIHRoYXQgCi0gICAqIGV2ZXJ5dGhpbmcgaW4gdGhlIGVudmlyb25tZW50IGlzIGNvcnJlY3QuICBCdXQgdGhpcyB3aWxsIGhlbHAgCi0gICAqIHBvaW50IG91dCB0aGUgbW9zdCBjb21tb24gY2xhc3NwYXRoIGFuZCBzeXN0ZW0gcHJvcGVydHkKLSAgICogcHJvYmxlbXMgdGhhdCB3ZSd2ZSBzZWVuLjwvcD4gICAKLSAgICoKLSAgICogQHJldHVybiBIYXNodGFibGUgZnVsbCBvZiB1c2VmdWwgZW52aXJvbm1lbnQgaW5mbyBhYm91dCBYYWxhbiAKLSAgICogYW5kIHJlbGF0ZWQgc3lzdGVtIHByb3BlcnRpZXMsIGV0Yy4KLSAgICovCi0gIHB1YmxpYyBIYXNodGFibGUgZ2V0RW52aXJvbm1lbnRIYXNoKCkKLSAgewotICAgIC8vIFNldHVwIGEgaGFzaCB0byBzdG9yZSB2YXJpb3VzIGVudmlyb25tZW50IGluZm9ybWF0aW9uIGluCi0gICAgSGFzaHRhYmxlIGhhc2ggPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICAvLyBDYWxsIHZhcmlvdXMgd29ya2VyIG1ldGhvZHMgdG8gZmlsbCBpbiB0aGUgaGFzaAotICAgIC8vICBUaGVzZSBhcmUgZXhwbGljaXRseSBzZXBhcmF0ZSBmb3IgbWFpbnRlbmFuY2UgYW5kIHNvIAotICAgIC8vICBhZHZhbmNlZCB1c2VycyBjb3VsZCBjYWxsIHRoZW0gc3RhbmRhbG9uZQotICAgIGNoZWNrSkFYUFZlcnNpb24oaGFzaCk7Ci0gICAgY2hlY2tQcm9jZXNzb3JWZXJzaW9uKGhhc2gpOwotICAgIGNoZWNrUGFyc2VyVmVyc2lvbihoYXNoKTsKLSAgICBjaGVja0RPTVZlcnNpb24oaGFzaCk7Ci0gICAgY2hlY2tTQVhWZXJzaW9uKGhhc2gpOwotICAgIGNoZWNrU3lzdGVtUHJvcGVydGllcyhoYXNoKTsKLQotICAgIHJldHVybiBoYXNoOwotICB9Ci0KLSAgLyoqCi0gICAqIER1bXAgYSBiYXNpYyBYYWxhbiBlbnZpcm9ubWVudCByZXBvcnQgdG8gb3V0V3JpdGVyLiAgCi0gICAqCi0gICAqIDxwPlRoaXMgZHVtcHMgYSBzaW1wbGUgaGVhZGVyIGFuZCB0aGVuIGVhY2ggb2YgdGhlIGVudHJpZXMgaW4gCi0gICAqIHRoZSBIYXNodGFibGUgdG8gb3VyIFByaW50V3JpdGVyOyBpdCBkb2VzIHNwZWNpYWwgcHJvY2Vzc2luZyAKLSAgICogZm9yIGVudHJpZXMgdGhhdCBhcmUgLmphcnMgZm91bmQgaW4gdGhlIGNsYXNzcGF0aC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBoIEhhc2h0YWJsZSBvZiBpdGVtcyB0byByZXBvcnQgb247IHByZXN1bWFibHkKLSAgICogZmlsbGVkIGluIGJ5IG91ciB2YXJpb3VzIGNoZWNrKigpIG1ldGhvZHMKLSAgICogQHJldHVybiB0cnVlIGlmIHlvdXIgZW52aXJvbm1lbnQgYXBwZWFycyB0byBoYXZlIG5vIG1ham9yIAotICAgKiBwcm9ibGVtczsgZmFsc2UgaWYgcG90ZW50aWFsIGVudmlyb25tZW50IHByb2JsZW1zIGZvdW5kCi0gICAqIEBzZWUgI2FwcGVuZEVudmlyb25tZW50UmVwb3J0KE5vZGUsIERvY3VtZW50LCBIYXNodGFibGUpCi0gICAqIGZvciBhbiBlcXVpdmFsZW50IHRoYXQgYXBwZW5kcyB0byBhIE5vZGUgaW5zdGVhZAotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gd3JpdGVFbnZpcm9ubWVudFJlcG9ydChIYXNodGFibGUgaCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gaCkKLSAgICB7Ci0gICAgICBsb2dNc2coIiMgRVJST1I6IHdyaXRlRW52aXJvbm1lbnRSZXBvcnQgY2FsbGVkIHdpdGggbnVsbCBIYXNodGFibGUiKTsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBib29sZWFuIGVycm9ycyA9IGZhbHNlOwotCi0gICAgbG9nTXNnKAotICAgICAgIiMtLS0tIEJFR0lOIHdyaXRlRW52aXJvbm1lbnRSZXBvcnQoJFJldmlzaW9uJCk6IFVzZWZ1bCBwcm9wZXJ0aWVzIGZvdW5kOiAtLS0tIik7Ci0KLSAgICAvLyBGYWtlIHRoZSBQcm9wZXJ0aWVzLWxpa2Ugb3V0cHV0Ci0gICAgZm9yIChFbnVtZXJhdGlvbiBlbnVtID0gaC5rZXlzKCk7IAotICAgICAgICAgZW51bS5oYXNNb3JlRWxlbWVudHMoKTsKLSAgICAgICAgLyogbm8gaW5jcmVtZW50IHBvcnRpb24gKi8KLSAgICAgICAgKQotICAgIHsKLSAgICAgIE9iamVjdCBrZXkgPSBlbnVtLm5leHRFbGVtZW50KCk7Ci0gICAgICBTdHJpbmcga2V5U3RyID0gKFN0cmluZykga2V5OwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIC8vIFNwZWNpYWwgcHJvY2Vzc2luZyBmb3IgY2xhc3NlcyBmb3VuZC4uCi0gICAgICAgIGlmIChrZXlTdHIuc3RhcnRzV2l0aChGT1VORENMQVNTRVMpKQotICAgICAgICB7Ci0gICAgICAgICAgVmVjdG9yIHYgPSAoVmVjdG9yKSBoLmdldChrZXlTdHIpOwotICAgICAgICAgIGVycm9ycyB8PSBsb2dGb3VuZEphcnModiwga2V5U3RyKTsKLSAgICAgICAgfQotICAgICAgICAvLyAuLm5vcm1hbCBwcm9jZXNzaW5nIGZvciBhbGwgb3RoZXIgZW50cmllcwotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBOb3RlOiB3ZSBjb3VsZCBqdXN0IGNoZWNrIGZvciB0aGUgRVJST1Iga2V5IGJ5IGl0c2VsZiwgCi0gICAgICAgICAgLy8gICAgc2luY2Ugd2Ugbm93IHNldCB0aGF0LCBidXQgc2luY2Ugd2UgaGF2ZSB0byBnbyAKLSAgICAgICAgICAvLyAgICB0aHJvdWdoIHRoZSB3aG9sZSBoYXNoIGFueXdheSwgZG8gaXQgdGhpcyB3YXksCi0gICAgICAgICAgLy8gICAgd2hpY2ggaXMgc2FmZXIgZm9yIG1haW50ZW5hbmNlCi0gICAgICAgICAgaWYgKGtleVN0ci5zdGFydHNXaXRoKEVSUk9SKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBlcnJvcnMgPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgICBsb2dNc2coa2V5U3RyICsgIj0iICsgaC5nZXQoa2V5U3RyKSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgbG9nTXNnKCJSZWFkaW5nLSIgKyBrZXkgKyAiPSB0aHJldzogIiArIGUudG9TdHJpbmcoKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbG9nTXNnKAotICAgICAgIiMtLS0tLSBFTkQgd3JpdGVFbnZpcm9ubWVudFJlcG9ydDogVXNlZnVsIHByb3BlcnRpZXMgZm91bmQ6IC0tLS0tIik7Ci0KLSAgICByZXR1cm4gZXJyb3JzOwotICB9Ci0KLSAgLyoqIFByZWZpeGVkIHRvIGhhc2gga2V5cyB0aGF0IHNpZ25pZnkgc2VyaW91cyBwcm9ibGVtcy4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SID0gIkVSUk9SLiI7Ci0KLSAgLyoqIEFkZGVkIHRvIGRlc2NyaXB0aW9ucyB0aGF0IHNpZ25pZnkgcG90ZW50aWFsIHByb2JsZW1zLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV0FSTklORyA9ICJXQVJOSU5HLiI7Ci0KLSAgLyoqIFZhbHVlIGZvciBhbnkgZXJyb3IgZm91bmQuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9GT1VORCA9ICJBdCBsZWFzdCBvbmUgZXJyb3Igd2FzIGZvdW5kISI7Ci0KLSAgLyoqIFByZWZpeGVkIHRvIGhhc2gga2V5cyB0aGF0IHNpZ25pZnkgdmVyc2lvbiBudW1iZXJzLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkVSU0lPTiA9ICJ2ZXJzaW9uLiI7Ci0KLSAgLyoqIFByZWZpeGVkIHRvIGhhc2gga2V5cyB0aGF0IHNpZ25pZnkgLmphcnMgZm91bmQgaW4gY2xhc3NwYXRoLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRk9VTkRDTEFTU0VTID0gImZvdW5kY2xhc3Nlcy4iOwotCi0gIC8qKiBNYXJrZXIgdGhhdCBhIGNsYXNzIG9yIC5qYXIgd2FzIGZvdW5kLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xBU1NfUFJFU0VOVCA9ICJwcmVzZW50LXVua25vd24tdmVyc2lvbiI7Ci0KLSAgLyoqIE1hcmtlciB0aGF0IGEgY2xhc3Mgb3IgLmphciB3YXMgbm90IGZvdW5kLiAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xBU1NfTk9UUFJFU0VOVCA9ICJub3QtcHJlc2VudCI7Ci0KLSAgLyoqIExpc3Rpbmcgb2YgY29tbW9uIC5qYXIgZmlsZXMgdGhhdCBpbmNsdWRlIFhhbGFuLXJlbGF0ZWQgY2xhc3Nlcy4gICovCi0gIHB1YmxpYyBTdHJpbmdbXSBqYXJOYW1lcyA9Ci0gIHsKLSAgICAieGFsYW4uamFyIiwgInhhbGFuc2FtcGxlcy5qYXIiLCAieGFsYW5qMWNvbXBhdC5qYXIiLCAieGFsYW5zZXJ2bGV0LmphciIsCi0gICAgInhlcmNlcy5qYXIiLCAKLSAgICAidGVzdHhzbC5qYXIiLCAKLSAgICAiY3JpbXNvbi5qYXIiLCAKLSAgICAibG90dXN4c2wuamFyIiwgCi0gICAgImpheHAuamFyIiwgInBhcnNlci5qYXIiLCAiZG9tLmphciIsICJzYXguamFyIiwgInhtbC5qYXIiLCAKLSAgICAieHNsdGMuamFyIgotICB9OwotCi0gIC8qKgotICAgKiBQcmludCBvdXQgcmVwb3J0IG9mIC5qYXJzIGZvdW5kIGluIGEgY2xhc3NwYXRoLiAKLSAgICoKLSAgICogVGFrZXMgdGhlIGluZm9ybWF0aW9uIGVuY29kZWQgZnJvbSBhIGNoZWNrUGF0aEZvckphcnMoKSAKLSAgICogY2FsbCBhbmQgZHVtcHMgaXQgb3V0IHRvIG91ciBQcmludFdyaXRlci4KLSAgICoKLSAgICogQHBhcmFtIHYgVmVjdG9yIG9mIEhhc2h0YWJsZXMgb2YgLmphciBmaWxlIGluZm8KLSAgICogQHBhcmFtIGRlc2MgZGVzY3JpcHRpb24gdG8gcHJpbnQgb3V0IGluIGhlYWRlcgotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlIGlmIE9LLCB0cnVlIGlmIGFueSAuamFycyB3ZXJlIHJlcG9ydGVkIAotICAgKiBhcyBoYXZpbmcgZXJyb3JzCi0gICAqIEBzZWUgI2NoZWNrUGF0aEZvckphcnMoU3RyaW5nLCBTdHJpbmdbXSkKLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIGxvZ0ZvdW5kSmFycyhWZWN0b3IgdiwgU3RyaW5nIGRlc2MpCi0gIHsKLQotICAgIGlmICgobnVsbCA9PSB2KSB8fCAodi5zaXplKCkgPCAxKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGJvb2xlYW4gZXJyb3JzID0gZmFsc2U7Ci0KLSAgICBsb2dNc2coIiMtLS0tIEJFR0lOIExpc3RpbmcgWE1MLXJlbGF0ZWQgamFycyBpbjogIiArIGRlc2MgKyAiIC0tLS0iKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdi5zaXplKCk7IGkrKykKLSAgICB7Ci0gICAgICBIYXNodGFibGUgc3ViaGFzaCA9IChIYXNodGFibGUpIHYuZWxlbWVudEF0KGkpOwotCi0gICAgICBmb3IgKEVudW1lcmF0aW9uIGVudW0gPSBzdWJoYXNoLmtleXMoKTsgCi0gICAgICAgICAgIGVudW0uaGFzTW9yZUVsZW1lbnRzKCk7Ci0gICAgICAgICAgIC8qIG5vIGluY3JlbWVudCBwb3J0aW9uICovCi0gICAgICAgICAgKQotICAgICAgewotICAgICAgICBPYmplY3Qga2V5ID0gZW51bS5uZXh0RWxlbWVudCgpOwotICAgICAgICBTdHJpbmcga2V5U3RyID0gKFN0cmluZykga2V5OwotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGlmIChrZXlTdHIuc3RhcnRzV2l0aChFUlJPUikpCi0gICAgICAgICAgewotICAgICAgICAgICAgZXJyb3JzID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgbG9nTXNnKGtleVN0ciArICI9IiArIHN1Ymhhc2guZ2V0KGtleVN0cikpOwotCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgICB7Ci0gICAgICAgICAgZXJyb3JzID0gdHJ1ZTsKLSAgICAgICAgICBsb2dNc2coIlJlYWRpbmctIiArIGtleSArICI9IHRocmV3OiAiICsgZS50b1N0cmluZygpKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIGxvZ01zZygiIy0tLS0tIEVORCBMaXN0aW5nIFhNTC1yZWxhdGVkIGphcnMgaW46ICIgKyBkZXNjICsgIiAtLS0tLSIpOwotCi0gICAgcmV0dXJuIGVycm9yczsKLSAgfQotCi0gIC8qKgotICAgKiBTdHlsZXNoZWV0IGV4dGVuc2lvbiBlbnRyeXBvaW50OiBEdW1wIGEgYmFzaWMgWGFsYW4gCi0gICAqIGVudmlyb25tZW50IHJlcG9ydCBmcm9tIGdldEVudmlyb25tZW50SGFzaCgpIHRvIGEgTm9kZS4gIAotICAgKiAKLSAgICogPHA+Q29weSBvZiB3cml0ZUVudmlyb25tZW50UmVwb3J0IHRoYXQgY3JlYXRlcyBhIE5vZGUgc3VpdGFibGUgCi0gICAqIGZvciBvdGhlciBwcm9jZXNzaW5nIGluc3RlYWQgb2YgYSBwcm9wZXJ0aWVzLWxpa2UgdGV4dCBvdXRwdXQuCi0gICAqIDwvcD4KLSAgICogQHBhcmFtIGNvbnRhaW5lciBOb2RlIHRvIGFwcGVuZCBvdXIgcmVwb3J0IHRvCi0gICAqIEBwYXJhbSBmYWN0b3J5IERvY3VtZW50IHByb3ZpZGluZyBjcmVhdGVFbGVtZW50LCBldGMuIHNlcnZpY2VzCi0gICAqIEBwYXJhbSBoIEhhc2ggcHJlc3VtYWJseSBmcm9tIHtAbGluayAjZ2V0RW52aXJvbm1lbnRIYXNoKCl9Ci0gICAqIEBzZWUgI3dyaXRlRW52aXJvbm1lbnRSZXBvcnQoSGFzaHRhYmxlKQotICAgKiBmb3IgYW4gZXF1aXZhbGVudCB0aGF0IHdyaXRlcyB0byBhIFByaW50V3JpdGVyIGluc3RlYWQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFwcGVuZEVudmlyb25tZW50UmVwb3J0KE5vZGUgY29udGFpbmVyLCBEb2N1bWVudCBmYWN0b3J5LCBIYXNodGFibGUgaCkKLSAgewotICAgIGlmICgobnVsbCA9PSBjb250YWluZXIpIHx8IChudWxsID09IGZhY3RvcnkpKQotICAgIHsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gIAotICAgIHRyeQotICAgIHsKLSAgICAgIEVsZW1lbnQgZW52Q2hlY2tOb2RlID0gZmFjdG9yeS5jcmVhdGVFbGVtZW50KCJFbnZpcm9ubWVudENoZWNrIik7Ci0gICAgICBlbnZDaGVja05vZGUuc2V0QXR0cmlidXRlKCJ2ZXJzaW9uIiwgIiRSZXZpc2lvbiQiKTsKLSAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChlbnZDaGVja05vZGUpOwotCi0gICAgICBpZiAobnVsbCA9PSBoKQotICAgICAgewotICAgICAgICBFbGVtZW50IHN0YXR1c05vZGUgPSBmYWN0b3J5LmNyZWF0ZUVsZW1lbnQoInN0YXR1cyIpOwotICAgICAgICBzdGF0dXNOb2RlLnNldEF0dHJpYnV0ZSgicmVzdWx0IiwgIkVSUk9SIik7Ci0gICAgICAgIHN0YXR1c05vZGUuYXBwZW5kQ2hpbGQoZmFjdG9yeS5jcmVhdGVUZXh0Tm9kZSgiYXBwZW5kRW52aXJvbm1lbnRSZXBvcnQgY2FsbGVkIHdpdGggbnVsbCBIYXNodGFibGUhIikpOwotICAgICAgICBlbnZDaGVja05vZGUuYXBwZW5kQ2hpbGQoc3RhdHVzTm9kZSk7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgYm9vbGVhbiBlcnJvcnMgPSBmYWxzZTsKLQotICAgICAgRWxlbWVudCBoYXNoTm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgiZW52aXJvbm1lbnQiKTsKLSAgICAgIGVudkNoZWNrTm9kZS5hcHBlbmRDaGlsZChoYXNoTm9kZSk7Ci0gICAgICAKLSAgICAgIGZvciAoRW51bWVyYXRpb24gZW51bSA9IGgua2V5cygpOyAKLSAgICAgICAgICAgZW51bS5oYXNNb3JlRWxlbWVudHMoKTsKLSAgICAgICAgICAvKiBubyBpbmNyZW1lbnQgcG9ydGlvbiAqLwotICAgICAgICAgICkKLSAgICAgIHsKLSAgICAgICAgT2JqZWN0IGtleSA9IGVudW0ubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgU3RyaW5nIGtleVN0ciA9IChTdHJpbmcpIGtleTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICAvLyBTcGVjaWFsIHByb2Nlc3NpbmcgZm9yIGNsYXNzZXMgZm91bmQuLgotICAgICAgICAgIGlmIChrZXlTdHIuc3RhcnRzV2l0aChGT1VORENMQVNTRVMpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFZlY3RvciB2ID0gKFZlY3RvcikgaC5nZXQoa2V5U3RyKTsKLSAgICAgICAgICAgIC8vIGVycm9ycyB8PSBsb2dGb3VuZEphcnModiwga2V5U3RyKTsKLSAgICAgICAgICAgIGVycm9ycyB8PSBhcHBlbmRGb3VuZEphcnMoaGFzaE5vZGUsIGZhY3RvcnksIHYsIGtleVN0cik7Ci0gICAgICAgICAgfQotICAgICAgICAgIC8vIC4ubm9ybWFsIHByb2Nlc3NpbmcgZm9yIGFsbCBvdGhlciBlbnRyaWVzCi0gICAgICAgICAgZWxzZSAKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBOb3RlOiB3ZSBjb3VsZCBqdXN0IGNoZWNrIGZvciB0aGUgRVJST1Iga2V5IGJ5IGl0c2VsZiwgCi0gICAgICAgICAgICAvLyAgICBzaW5jZSB3ZSBub3cgc2V0IHRoYXQsIGJ1dCBzaW5jZSB3ZSBoYXZlIHRvIGdvIAotICAgICAgICAgICAgLy8gICAgdGhyb3VnaCB0aGUgd2hvbGUgaGFzaCBhbnl3YXksIGRvIGl0IHRoaXMgd2F5LAotICAgICAgICAgICAgLy8gICAgd2hpY2ggaXMgc2FmZXIgZm9yIG1haW50ZW5hbmNlCi0gICAgICAgICAgICBpZiAoa2V5U3RyLnN0YXJ0c1dpdGgoRVJST1IpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBlcnJvcnMgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgRWxlbWVudCBub2RlID0gZmFjdG9yeS5jcmVhdGVFbGVtZW50KCJpdGVtIik7Ci0gICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgia2V5Iiwga2V5U3RyKTsKLSAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZmFjdG9yeS5jcmVhdGVUZXh0Tm9kZSgoU3RyaW5nKWguZ2V0KGtleVN0cikpKTsKLSAgICAgICAgICAgIGhhc2hOb2RlLmFwcGVuZENoaWxkKG5vZGUpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICBlcnJvcnMgPSB0cnVlOwotICAgICAgICAgIEVsZW1lbnQgbm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgiaXRlbSIpOwotICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJrZXkiLCBrZXlTdHIpOwotICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZmFjdG9yeS5jcmVhdGVUZXh0Tm9kZShFUlJPUiArICIgUmVhZGluZyAiICsga2V5ICsgIiB0aHJldzogIiArIGUudG9TdHJpbmcoKSkpOwotICAgICAgICAgIGhhc2hOb2RlLmFwcGVuZENoaWxkKG5vZGUpOwotICAgICAgICB9Ci0gICAgICB9IC8vIGVuZCBvZiBmb3IuLi4KLQotICAgICAgRWxlbWVudCBzdGF0dXNOb2RlID0gZmFjdG9yeS5jcmVhdGVFbGVtZW50KCJzdGF0dXMiKTsKLSAgICAgIHN0YXR1c05vZGUuc2V0QXR0cmlidXRlKCJyZXN1bHQiLCAoZXJyb3JzID8gIkVSUk9SIiA6ICJPSyIgKSk7Ci0gICAgICBlbnZDaGVja05vZGUuYXBwZW5kQ2hpbGQoc3RhdHVzTm9kZSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZTIpCi0gICAgewotICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJhcHBlbmRFbnZpcm9ubWVudFJlcG9ydCB0aHJldzogIiArIGUyLnRvU3RyaW5nKCkpOwotICAgICAgZTIucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfQotICB9ICAgIAotCi0gIC8qKgotICAgKiBQcmludCBvdXQgcmVwb3J0IG9mIC5qYXJzIGZvdW5kIGluIGEgY2xhc3NwYXRoLiAKLSAgICoKLSAgICogVGFrZXMgdGhlIGluZm9ybWF0aW9uIGVuY29kZWQgZnJvbSBhIGNoZWNrUGF0aEZvckphcnMoKSAKLSAgICogY2FsbCBhbmQgZHVtcHMgaXQgb3V0IHRvIG91ciBQcmludFdyaXRlci4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRhaW5lciBOb2RlIHRvIGFwcGVuZCBvdXIgcmVwb3J0IHRvCi0gICAqIEBwYXJhbSBmYWN0b3J5IERvY3VtZW50IHByb3ZpZGluZyBjcmVhdGVFbGVtZW50LCBldGMuIHNlcnZpY2VzCi0gICAqIEBwYXJhbSB2IFZlY3RvciBvZiBIYXNodGFibGVzIG9mIC5qYXIgZmlsZSBpbmZvCi0gICAqIEBwYXJhbSBkZXNjIGRlc2NyaXB0aW9uIHRvIHByaW50IG91dCBpbiBoZWFkZXIKLSAgICoKLSAgICogQHJldHVybiBmYWxzZSBpZiBPSywgdHJ1ZSBpZiBhbnkgLmphcnMgd2VyZSByZXBvcnRlZCAKLSAgICogYXMgaGF2aW5nIGVycm9ycwotICAgKiBAc2VlICNjaGVja1BhdGhGb3JKYXJzKFN0cmluZywgU3RyaW5nW10pCi0gICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBhcHBlbmRGb3VuZEphcnMoTm9kZSBjb250YWluZXIsIERvY3VtZW50IGZhY3RvcnksIAotICAgICAgICBWZWN0b3IgdiwgU3RyaW5nIGRlc2MpCi0gIHsKLQotICAgIGlmICgobnVsbCA9PSB2KSB8fCAodi5zaXplKCkgPCAxKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGJvb2xlYW4gZXJyb3JzID0gZmFsc2U7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IHYuc2l6ZSgpOyBpKyspCi0gICAgewotICAgICAgSGFzaHRhYmxlIHN1Ymhhc2ggPSAoSGFzaHRhYmxlKSB2LmVsZW1lbnRBdChpKTsKLQotICAgICAgZm9yIChFbnVtZXJhdGlvbiBlbnVtID0gc3ViaGFzaC5rZXlzKCk7IAotICAgICAgICAgICBlbnVtLmhhc01vcmVFbGVtZW50cygpOwotICAgICAgICAgICAvKiBubyBpbmNyZW1lbnQgcG9ydGlvbiAqLwotICAgICAgICAgICkKLSAgICAgIHsKLSAgICAgICAgT2JqZWN0IGtleSA9IGVudW0ubmV4dEVsZW1lbnQoKTsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcga2V5U3RyID0gKFN0cmluZykga2V5OwotICAgICAgICAgIGlmIChrZXlTdHIuc3RhcnRzV2l0aChFUlJPUikpCi0gICAgICAgICAgewotICAgICAgICAgICAgZXJyb3JzID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgRWxlbWVudCBub2RlID0gZmFjdG9yeS5jcmVhdGVFbGVtZW50KCJmb3VuZEphciIpOwotICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJuYW1lIiwga2V5U3RyLnN1YnN0cmluZygwLCBrZXlTdHIuaW5kZXhPZigiLSIpKSk7Ci0gICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoImRlc2MiLCBrZXlTdHIuc3Vic3RyaW5nKGtleVN0ci5pbmRleE9mKCItIikgKyAxKSk7Ci0gICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChmYWN0b3J5LmNyZWF0ZVRleHROb2RlKChTdHJpbmcpc3ViaGFzaC5nZXQoa2V5U3RyKSkpOwotICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgIHsKLSAgICAgICAgICBlcnJvcnMgPSB0cnVlOwotICAgICAgICAgIEVsZW1lbnQgbm9kZSA9IGZhY3RvcnkuY3JlYXRlRWxlbWVudCgiZm91bmRKYXIiKTsKLSAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGZhY3RvcnkuY3JlYXRlVGV4dE5vZGUoRVJST1IgKyAiIFJlYWRpbmcgIiArIGtleSArICIgdGhyZXc6ICIgKyBlLnRvU3RyaW5nKCkpKTsKLSAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgcmV0dXJuIGVycm9yczsKLSAgfQotCi0gIC8qKgotICAgKiBGaWxsaW4gaGFzaCB3aXRoIGluZm8gYWJvdXQgU3lzdGVtUHJvcGVydGllcy4gIAotICAgKgotICAgKiBMb2dzIGphdmEuY2xhc3MucGF0aCBhbmQgb3RoZXIgbGlrZWx5IHBhdGhzOyB0aGVuIGF0dGVtcHRzIAotICAgKiB0byBzZWFyY2ggdGhvc2UgcGF0aHMgZm9yIC5qYXIgZmlsZXMgd2l0aCBYYWxhbi1yZWxhdGVkIGNsYXNzZXMuCi0gICAqCi0gICAqIC8vQHRvZG8gTk9URTogV2UgZG9uJ3QgYWN0dWFsbHkgc2VhcmNoIGphdmEuZXh0LmRpcnMgZm9yIAotICAgKiAvLyAgKi5qYXIgZmlsZXMgdGhlcmVpbiEgVGhpcyBzaG91bGQgYmUgdXBkYXRlZAotICAgKgotICAgKiBAcGFyYW0gaCBIYXNodGFibGUgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqIEBzZWUgI2phck5hbWVzCi0gICAqIEBzZWUgI2NoZWNrUGF0aEZvckphcnMoU3RyaW5nLCBTdHJpbmdbXSkKLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNoZWNrU3lzdGVtUHJvcGVydGllcyhIYXNodGFibGUgaCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gaCkKLSAgICAgIGggPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICAvLyBHcmFiIGphdmEgdmVyc2lvbiBmb3IgbGF0ZXIgdXNlCi0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIGphdmFWZXJzaW9uID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnZlcnNpb24iKTsKLQotICAgICAgaC5wdXQoImphdmEudmVyc2lvbiIsIGphdmFWZXJzaW9uKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gRm9yIGFwcGxldCBjb250ZXh0LCBldGMuCi0gICAgICBoLnB1dCgKLSAgICAgICAgImphdmEudmVyc2lvbiIsCi0gICAgICAgICJXQVJOSU5HOiBTZWN1cml0eUV4Y2VwdGlvbiB0aHJvd24gYWNjZXNzaW5nIHN5c3RlbSB2ZXJzaW9uIHByb3BlcnRpZXMiKTsKLSAgICB9Ci0KLSAgICAvLyBQcmludG91dCBqYXIgZmlsZXMgb24gY2xhc3NwYXRoKHMpIHRoYXQgbWF5IGFmZmVjdCBvcGVyYXRpb24KLSAgICAvLyAgRG8gdGhpcyBpbiBvcmRlcgotICAgIHRyeQotICAgIHsKLQotICAgICAgLy8gVGhpcyBpcyBwcmVzZW50IGluIGFsbCBKVk0ncwotICAgICAgU3RyaW5nIGNwID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmNsYXNzLnBhdGgiKTsKLQotICAgICAgaC5wdXQoImphdmEuY2xhc3MucGF0aCIsIGNwKTsKLQotICAgICAgVmVjdG9yIGNsYXNzcGF0aEphcnMgPSBjaGVja1BhdGhGb3JKYXJzKGNwLCBqYXJOYW1lcyk7Ci0KLSAgICAgIGlmIChudWxsICE9IGNsYXNzcGF0aEphcnMpCi0gICAgICAgIGgucHV0KEZPVU5EQ0xBU1NFUyArICJqYXZhLmNsYXNzLnBhdGgiLCBjbGFzc3BhdGhKYXJzKTsKLQotICAgICAgLy8gQWxzbyBjaGVjayBmb3IgSkRLIDEuMisgdHlwZSBjbGFzc3BhdGhzCi0gICAgICBTdHJpbmcgb3RoZXJjcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgic3VuLmJvb3QuY2xhc3MucGF0aCIpOwotCi0gICAgICBpZiAobnVsbCAhPSBvdGhlcmNwKQotICAgICAgewotICAgICAgICBoLnB1dCgic3VuLmJvb3QuY2xhc3MucGF0aCIsIG90aGVyY3ApOwotCi0gICAgICAgIGNsYXNzcGF0aEphcnMgPSBjaGVja1BhdGhGb3JKYXJzKG90aGVyY3AsIGphck5hbWVzKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBjbGFzc3BhdGhKYXJzKQotICAgICAgICAgIGgucHV0KEZPVU5EQ0xBU1NFUyArICJzdW4uYm9vdC5jbGFzcy5wYXRoIiwgY2xhc3NwYXRoSmFycyk7Ci0gICAgICB9Ci0KLSAgICAgIC8vQHRvZG8gTk9URTogV2UgZG9uJ3QgYWN0dWFsbHkgc2VhcmNoIGphdmEuZXh0LmRpcnMgZm9yIAotICAgICAgLy8gICouamFyIGZpbGVzIHRoZXJlaW4hIFRoaXMgc2hvdWxkIGJlIHVwZGF0ZWQKLSAgICAgIG90aGVyY3AgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuZXh0LmRpcnMiKTsKLQotICAgICAgaWYgKG51bGwgIT0gb3RoZXJjcCkKLSAgICAgIHsKLSAgICAgICAgaC5wdXQoImphdmEuZXh0LmRpcnMiLCBvdGhlcmNwKTsKLQotICAgICAgICBjbGFzc3BhdGhKYXJzID0gY2hlY2tQYXRoRm9ySmFycyhvdGhlcmNwLCBqYXJOYW1lcyk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gY2xhc3NwYXRoSmFycykKLSAgICAgICAgICBoLnB1dChGT1VORENMQVNTRVMgKyAiamF2YS5leHQuZGlycyIsIGNsYXNzcGF0aEphcnMpOwotICAgICAgfQotCi0gICAgICAvL0B0b2RvIGFsc28gY2hlY2sgb3RoZXIgU3lzdGVtIHByb3BlcnRpZXMnIHBhdGhzPwotICAgICAgLy8gIHYyID0gY2hlY2tQYXRoRm9ySmFycyhTeXN0ZW0uZ2V0UHJvcGVydHkoInN1bi5ib290LmxpYnJhcnkucGF0aCIpLCBqYXJOYW1lcyk7ICAgLy8gPz8gbWF5IG5vdCBiZSBuZWVkZWQKLSAgICAgIC8vICB2MyA9IGNoZWNrUGF0aEZvckphcnMoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmxpYnJhcnkucGF0aCIpLCBqYXJOYW1lcyk7ICAgLy8gPz8gbWF5IG5vdCBiZSBuZWVkZWQKLSAgICB9Ci0gICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlMikKLSAgICB7Ci0gICAgICAvLyBGb3IgYXBwbGV0IGNvbnRleHQsIGV0Yy4KLSAgICAgIGgucHV0KAotICAgICAgICAiamF2YS5jbGFzcy5wYXRoIiwKLSAgICAgICAgIldBUk5JTkc6IFNlY3VyaXR5RXhjZXB0aW9uIHRocm93biBhY2Nlc3Npbmcgc3lzdGVtIGNsYXNzcGF0aCBwcm9wZXJ0aWVzIik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENoZWFwLW8gbGlzdGluZyBvZiBzcGVjaWZpZWQgLmphcnMgZm91bmQgaW4gdGhlIGNsYXNzcGF0aC4gCi0gICAqCi0gICAqIGNwIHNob3VsZCBiZSBzZXBhcmF0ZWQgYnkgdGhlIHVzdWFsIEZpbGUucGF0aFNlcGFyYXRvci4gIFdlIAotICAgKiB0aGVuIGRvIGEgc2ltcGxpc3RpYyBzZWFyY2ggb2YgdGhlIHBhdGggZm9yIGFueSByZXF1ZXN0ZWQgCi0gICAqIC5qYXIgZmlsZW5hbWVzLCBhbmQgcmV0dXJuIGEgbGlzdGluZyBvZiB0aGVpciBuYW1lcyBhbmQgCi0gICAqIHdoZXJlIChhcHBhcmVudGx5KSB0aGV5IGNhbWUgZnJvbS4KLSAgICoKLSAgICogQHBhcmFtIGNwIGNsYXNzcGF0aCB0byBzZWFyY2gKLSAgICogQHBhcmFtIGphcnMgYXJyYXkgb2YgLmphciBiYXNlIGZpbGVuYW1lcyB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFZlY3RvciBvZiBIYXNodGFibGVzIGZpbGxlZCB3aXRoIGluZm8gYWJvdXQgZm91bmQgLmphcnMKLSAgICogQHNlZSAjamFyTmFtZXMKLSAgICogQHNlZSAjbG9nRm91bmRKYXJzKFZlY3RvciwgU3RyaW5nKQotICAgKiBAc2VlICNhcHBlbmRGb3VuZEphcnMoTm9kZSwgRG9jdW1lbnQsIFZlY3RvciwgU3RyaW5nICkKLSAgICogQHNlZSAjZ2V0QXBwYXJlbnRWZXJzaW9uKFN0cmluZywgbG9uZykKLSAgICovCi0gIHByb3RlY3RlZCBWZWN0b3IgY2hlY2tQYXRoRm9ySmFycyhTdHJpbmcgY3AsIFN0cmluZ1tdIGphcnMpCi0gIHsKLQotICAgIGlmICgobnVsbCA9PSBjcCkgfHwgKG51bGwgPT0gamFycykgfHwgKDAgPT0gY3AubGVuZ3RoKCkpCi0gICAgICAgICAgICB8fCAoMCA9PSBqYXJzLmxlbmd0aCkpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIFZlY3RvciB2ID0gbmV3IFZlY3RvcigpOwotICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoY3AsIEZpbGUucGF0aFNlcGFyYXRvcik7Ci0KLSAgICB3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKQotICAgIHsKLQotICAgICAgLy8gTG9vayBhdCBlYWNoIGNsYXNzcGF0aCBlbnRyeSBmb3IgZWFjaCBvZiBvdXIgcmVxdWVzdGVkIGphck5hbWVzCi0gICAgICBTdHJpbmcgZmlsZW5hbWUgPSBzdC5uZXh0VG9rZW4oKS50b0xvd2VyQ2FzZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGphcnMubGVuZ3RoOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGlmIChmaWxlbmFtZS5pbmRleE9mKGphcnNbaV0pID4gLTEpCi0gICAgICAgIHsKLSAgICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShmaWxlbmFtZSk7Ci0KLSAgICAgICAgICBpZiAoZi5leGlzdHMoKSkKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIElmIGFueSByZXF1ZXN0ZWQgamFyTmFtZSBleGlzdHMsIHJlcG9ydCBvbiAKLSAgICAgICAgICAgIC8vICB0aGUgZGV0YWlscyBvZiB0aGF0IC5qYXIgZmlsZQotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIEhhc2h0YWJsZSBoID0gbmV3IEhhc2h0YWJsZSgyKTsKLSAgICAgICAgICAgICAgLy8gTm90ZSAiLSIgY2hhciBpcyBsb29rZWQgZm9yIGluIGFwcGVuZEZvdW5kSmFycwotICAgICAgICAgICAgICBoLnB1dChqYXJzW2ldICsgIi1wYXRoIiwgZi5nZXRBYnNvbHV0ZVBhdGgoKSk7Ci0gICAgICAgICAgICAgIGgucHV0KGphcnNbaV0gKyAiLWFwcGFyZW50LnZlcnNpb24iLAotICAgICAgICAgICAgICAgICAgICBnZXRBcHBhcmVudFZlcnNpb24oamFyc1tpXSwgZi5sZW5ndGgoKSkpOwotICAgICAgICAgICAgICB2LmFkZEVsZW1lbnQoaCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgICAgLyogbm8tb3AsIGRvbid0IGFkZCBpdCAgKi8KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIEhhc2h0YWJsZSBoID0gbmV3IEhhc2h0YWJsZSgyKTsKLSAgICAgICAgICAgIC8vIE5vdGUgIi0iIGNoYXIgaXMgbG9va2VkIGZvciBpbiBhcHBlbmRGb3VuZEphcnMKLSAgICAgICAgICAgIGgucHV0KGphcnNbaV0gKyAiLXBhdGgiLCBXQVJOSU5HICsgIiBDbGFzc3BhdGggZW50cnk6ICIgCi0gICAgICAgICAgICAgICAgICArIGZpbGVuYW1lICsgIiBkb2VzIG5vdCBleGlzdCIpOwotICAgICAgICAgICAgaC5wdXQoamFyc1tpXSArICItYXBwYXJlbnQudmVyc2lvbiIsIENMQVNTX05PVFBSRVNFTlQpOwotICAgICAgICAgICAgdi5hZGRFbGVtZW50KGgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB2OwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWFwLW8gbWV0aG9kIHRvIGRldGVybWluZSB0aGUgcHJvZHVjdCB2ZXJzaW9uIG9mIGEgLmphci4gICAKLSAgICoKLSAgICogQ3VycmVudGx5IGRvZXMgYSBsb29rdXAgaW50byBhIGxvY2FsIHRhYmxlIG9mIHNvbWUgcmVjZW50IAotICAgKiBzaGlwcGVkIFhhbGFuIGJ1aWxkcyB0byBkZXRlcm1pbmUgd2hlcmUgdGhlIC5qYXIgcHJvYmFibHkgCi0gICAqIGNhbWUgZnJvbS4gIE5vdGUgdGhhdCBpZiB5b3UgcmVjb21waWxlIFhhbGFuIG9yIFhlcmNlcyAKLSAgICogeW91cnNlbGYgdGhpcyB3aWxsIGxpa2VseSByZXBvcnQgYSBwb3RlbnRpYWwgZXJyb3IsIHNpbmNlIAotICAgKiB3ZSBjYW4ndCBjZXJ0aWZ5IGJ1aWxkcyBvdGhlciB0aGFuIHRoZSBvbmVzIHdlIHNoaXAuCi0gICAqIE9ubHkgcmVwb3J0cyBhZ2FpbnN0IHNlbGVjdGVkIHBvc3RlZCBYYWxhbi1KIGJ1aWxkcy4KLSAgICoKLSAgICogLy9AdG9kbyBhY3R1YWxseSBsb29rIHVwIHZlcnNpb24gaW5mbyBpbiBtYW5pZmVzdHMKLSAgICoKLSAgICogQHBhcmFtIGphck5hbWUgYmFzZSBmaWxlbmFtZSBvZiB0aGUgLmphcmZpbGUKLSAgICogQHBhcmFtIGphclNpemUgc2l6ZSBvZiB0aGUgLmphcmZpbGUKLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgZGVzY3JpYmluZyB3aGVyZSB0aGUgLmphciBmaWxlIHByb2JhYmx5IAotICAgKiBjYW1lIGZyb20KLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgZ2V0QXBwYXJlbnRWZXJzaW9uKFN0cmluZyBqYXJOYW1lLCBsb25nIGphclNpemUpCi0gIHsKLQotICAgIC8vIExvb2t1cCBpbiBhIG1hbnVhbCB0YWJsZSBvZiBrbm93biAuamFyIHNpemVzOyAKLSAgICAvLyAgb25seSBpbmNsdWRlcyBzaGlwcGVkIHZlcnNpb25zIG9mIGNlcnRhaW4gcHJvamVjdHMKLSAgICBIYXNodGFibGUgamFyVmVyc2lvbnMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICAvLyBrZXk9amFyc2l6ZSwgdmFsdWU9amFybmFtZSAnIGZyb20gJyBkaXN0cm8gbmFtZQotICAgIC8vIE5vdGUgYXNzdW1wdGlvbjogdHdvIGphcnMgY2Fubm90IGhhdmUgdGhlIHNhbWUgc2l6ZSEKLSAgICAvLyBOb3RlOiBoYWNraXNoIEhhc2h0YWJsZSwgdGhpcyBjb3VsZCB1c2UgaW1wcm92ZW1lbnQKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoODU3MTkyKSwgInhhbGFuLmphciBmcm9tIHhhbGFuLWpfMV8xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDQ0MDIzNyksICJ4YWxhbi5qYXIgZnJvbSB4YWxhbi1qXzFfMiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg0MzYwOTQpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8xXzJfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg0MjYyNDkpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8xXzJfMiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg3MDI1MzYpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzBfMCIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg3MjA5MzApLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzBfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg4NzIyNDEpLCAieGFsYW4uamFyIGZyb20geGFsYW4tal8yXzJfRDEwIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDg1NzE3MSksICJ4YWxhbi5qYXIgZnJvbSBsb3R1c3hzbC1qXzFfMF8xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDgwMjE2NSksICJ4YWxhbi5qYXIgZnJvbSBsb3R1c3hzbC1qXzJfMF8wIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDg1NzY5MiksICJ4YWxhbi5qYXIgZnJvbSBsb3R1c3hzbC1qXzJfMiIpOwotICAgIC8vIElmIHRoZSBiZWxvdyB3ZXJlIG1vcmUgY29tbW9uIEkgd291bGQgdXBkYXRlIGl0IHRvIHJlcG9ydCAKLSAgICAvLyAgZXJyb3JzIGJldHRlcjsgYnV0IHRoaXMgaXMgc28gb2xkIGhhcmRseSBhbnlvbmUgaGFzIGl0Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDQyNDQ5MCksICJ4YWxhbi5qYXIgZnJvbSBYZXJjZXMgVG9vbHMgcmVsZWFzZXMgLSBFUlJPUjpETyBOT1QgVVNFISIpOwotCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE1OTE4NTUpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMV8xIGZyb20geGVyY2VzLTEuLi4iKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTQ5ODY3OSksICJ4ZXJjZXMuamFyIGZyb20geGFsYW4tal8xXzIgZnJvbSB4ZXJjZXMtMV8yXzAuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE0ODQ4OTYpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMV8yXzEgZnJvbSB4ZXJjZXMtMV8yXzEuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDgwNDQ2MCksICAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMV8yXzIgZnJvbSB4ZXJjZXMtMV8yXzIuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE0OTkyNDQpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMl8wXzAgZnJvbSB4ZXJjZXMtMV8yXzMuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE2MDUyNjYpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMl8wXzEgZnJvbSB4ZXJjZXMtMV8zXzAuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDExOTA3NzYpLCAieGVyY2VzLmphciBmcm9tIGxvdHVzeHNsXzFfMF8xIGFwcGFyZW50bHktZnJvbSB4ZXJjZXMtMV8wXzMuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE0ODk0MDApLCAieGVyY2VzLmphciBmcm9tIGxvdHVzeHNsLWpfMl8wXzAgZnJvbSBYTUw0Si0zXzFfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxNzg3Nzk2KSwgInhlcmNlcy5qYXIgZnJvbSBsb3R1c3hzbC1qXzJfMiBvciB4ZXJjZXMtMV80XzEuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDkwNDAzMCksICJ4ZXJjZXMuamFyIGZyb20geGVyY2VzLTFfNF8wLmJpbiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxODAyODg1KSwgInhlcmNlcy5qYXIgZnJvbSB4ZXJjZXMtMV80XzIuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE4MDg4ODMpLCAieGVyY2VzLmphciBmcm9tIHhhbGFuLWpfMl8yX0QxMCBvciB4ZXJjZXMtMV80XzMuYmluIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE4MDM4NzcpLCAieGVyY2VzLmphciBmcm9tIFhNTDRKLTNfMl8xIik7Ci0KLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMzc0ODUpLCAieGFsYW5qMWNvbXBhdC5qYXIgZnJvbSB4YWxhbi1qXzJfMF8wIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDM4MTAwKSwgInhhbGFuajFjb21wYXQuamFyIGZyb20geGFsYW4tal8yXzBfMSIpOwotCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDE4Nzc5KSwgInhhbGFuc2VydmxldC5qYXIgZnJvbSB4YWxhbi1qXzJfMF8wIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDIxNDUzKSwgInhhbGFuc2VydmxldC5qYXIgZnJvbSB4YWxhbi1qXzJfMF8xIik7Ci0KLSAgICAvLyBGb3IgdGhvc2Ugd2hvJ3ZlIGRvd25sb2FkZWQgSkFYUCBmcm9tIHN1bgotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg1NjE4KSwgImpheHAuamFyIGZyb20gamF4cDEuMC4xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDEzNjEzMyksICJwYXJzZXIuamFyIGZyb20gamF4cDEuMC4xIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDI4NDA0KSwgImpheHAuamFyIGZyb20gamF4cC0xLjEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMTg3MTYyKSwgImNyaW1zb24uamFyIGZyb20gamF4cC0xLjEiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoODAxNzE0KSwgInhhbGFuLmphciBmcm9tIGpheHAtMS4xIik7Ci0KLSAgICAvLyBqYWthcnRhLWFudDogc2luY2UgbWFueSBwZW9wbGUgdXNlIGFudCB0aGVzZSBkYXlzCi0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDU1MzcpLCAiamF4cC5qYXIgZnJvbSBqYWthcnRhLWFudC0xLjMgb3IgMS4yIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDEzNjE5OCksCi0gICAgICAgICAgICAgICAgICAgICJwYXJzZXIuamFyIGZyb20gamFrYXJ0YS1hbnQtMS4zIG9yIDEuMiIpOwotCi0gICAgLy8gVmFyaW91cyBMb3R1c1hTTCB2ZXJzaW9ucywgd2hpY2ggYXJlIGJhc2VkIG9uIFhhbGFuIGNvZGUgCi0gICAgLy8gIChMb3R1c1hTTCB3YXMgZG9uYXRlZCBieSBMb3R1cyB0byBBcGFjaGUgdG8gYmVjb21lIFhhbGFuKQotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygxMjAyNzQpLCAibG90dXN4c2wuamFyIGZyb20gbG90dXN4c2wtMF8xNl80Iik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDEyMDI5MyksICJsb3R1c3hzbC5qYXIgZnJvbSBsb3R1c3hzbC0wXzE2XzUiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoMjgzNzc3KSwgImxvdHVzeHNsLmphciBmcm9tIGxvdHVzeHNsLTBfMTdfMiIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZygzMDU1NzcpLCAibG90dXN4c2wuamFyIGZyb20gbG90dXN4c2wtMF8xN18zIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDMwNDUwMCksICJsb3R1c3hzbC5qYXIgZnJvbSBsb3R1c3hzbC0wXzE3XzQiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoNzE0OTU5KSwgImxvdHVzeHNsLmphciBmcm9tIGxvdHVzeHNsLTBfMThfMSIpOwotICAgIGphclZlcnNpb25zLnB1dChuZXcgTG9uZyg3MTc2NzQpLCAibG90dXN4c2wuamFyIGZyb20gbG90dXN4c2wtMF8xOF8yIik7Ci0gICAgamFyVmVyc2lvbnMucHV0KG5ldyBMb25nKDc1MjM0MyksICJsb3R1c3hzbC5qYXIgZnJvbSBsb3R1c3hzbC0wXzE4XzMiKTsKLSAgICBqYXJWZXJzaW9ucy5wdXQobmV3IExvbmcoOTA3MTAxKSwgImxvdHVzeHNsLmphciBmcm9tIGxvdHVzeHNsLTBfMThfNCIpOwotICAgIAotCi0gICAgLy8gSWYgd2UgZm91bmQgYSBtYXRjaGluZyBzaXplIGFuZCBpdCdzIGZvciBvdXIgCi0gICAgLy8gIGphciwgdGhlbiByZXR1cm4gaXQncyBkZXNjcmlwdGlvbgotICAgIFN0cmluZyBmb3VuZFNpemUgPSAoU3RyaW5nKSBqYXJWZXJzaW9ucy5nZXQobmV3IExvbmcoamFyU2l6ZSkpOwotCi0gICAgaWYgKChudWxsICE9IGZvdW5kU2l6ZSkgJiYgKGZvdW5kU2l6ZS5zdGFydHNXaXRoKGphck5hbWUpKSkKLSAgICB7Ci0gICAgICByZXR1cm4gZm91bmRTaXplOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKCJ4ZXJjZXMuamFyIi5lcXVhbHNJZ25vcmVDYXNlKGphck5hbWUpCi0gICAgICAgICAgICAgIHx8ICJ4YWxhbi5qYXIiLmVxdWFsc0lnbm9yZUNhc2UoamFyTmFtZSkpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gRm9yIHhhbGFuLmphciBhbmQgeGVyY2VzLmphciwgd2hpY2ggd2Ugc2hpcCB0b2dldGhlcjoKLSAgICAgICAgLy8gVGhlIGphciBpcyBub3QgZnJvbSBhIHNoaXBwZWQgY29weSBvZiB4YWxhbi1qLCBzbyAKLSAgICAgICAgLy8gIGl0J3MgdXAgdG8gdGhlIHVzZXIgdG8gZW5zdXJlIHRoYXQgaXQncyBjb21wYXRpYmxlCi0gICAgICAgIHJldHVybiBqYXJOYW1lICsgIiAiICsgV0FSTklORyArIENMQVNTX1BSRVNFTlQ7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gT3RoZXJ3aXNlLCBpdCdzIGp1c3QgYSBqYXIgd2UgZG9uJ3QgaGF2ZSB0aGUgdmVyc2lvbiBpbmZvIGNhbGN1bGF0ZWQgZm9yCi0gICAgICAgIHJldHVybiBqYXJOYW1lICsgIiAiICsgQ0xBU1NfUFJFU0VOVDsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IHZlcnNpb24gaW5mb3JtYXRpb24gYWJvdXQgSkFYUCBpbnRlcmZhY2VzLgotICAgKgotICAgKiBDdXJyZW50bHkgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIEpBWFAgMS4wLjEgYW5kIEpBWFAgMS4xLCAKLSAgICogYW5kIG5vdCBmb3VuZDsgb25seSB0ZXN0cyB0aGUgaW50ZXJmYWNlcywgYW5kIGRvZXMgbm90IAotICAgKiBjaGVjayBmb3IgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIHZlcnNpb25zLgotICAgKgotICAgKiBAcGFyYW0gaCBIYXNodGFibGUgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjaGVja0pBWFBWZXJzaW9uKEhhc2h0YWJsZSBoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBoKQotICAgICAgaCA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIGZpbmFsIENsYXNzIG5vQXJnc1tdID0gbmV3IENsYXNzWzBdOwotICAgIENsYXNzIGNsYXp6ID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFN0cmluZyBKQVhQMV9DTEFTUyA9ICJqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXIiOwotICAgICAgZmluYWwgU3RyaW5nIEpBWFAxMV9NRVRIT0QgPSAiZ2V0RE9NSW1wbGVtZW50YXRpb24iOwotCi0gICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoSkFYUDFfQ0xBU1MpOwotCi0gICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKEpBWFAxMV9NRVRIT0QsIG5vQXJncyk7Ci0KLSAgICAgIC8vIElmIHdlIHN1Y2NlZWRlZCwgd2UgYXQgbGVhc3QgaGF2ZSBKQVhQIDEuMSBhdmFpbGFibGUKLSAgICAgIGgucHV0KFZFUlNJT04gKyAiSkFYUCIsICIxLjEiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IGNsYXp6KQotICAgICAgewotCi0gICAgICAgIC8vIFdlIG11c3QgaGF2ZSBmb3VuZCB0aGUgY2xhc3MgaXRzZWxmLCBqdXN0IG5vdCB0aGUgCi0gICAgICAgIC8vICBtZXRob2QsIHNvIHdlIChwcm9iYWJseSkgaGF2ZSBKQVhQIDEuMC4xCi0gICAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJKQVhQIiwgIjEuMC4xIik7Ci0gICAgICAgIGgucHV0KEVSUk9SLCBFUlJPUl9GT1VORCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gV2UgY291bGRuJ3QgZXZlbiBmaW5kIHRoZSBjbGFzcywgYW5kIGRvbid0IGhhdmUgCi0gICAgICAgIC8vICBhbnkgSkFYUCBzdXBwb3J0IGF0IGFsbAotICAgICAgICBoLnB1dChFUlJPUiArIFZFUlNJT04gKyAiSkFYUCIsIENMQVNTX05PVFBSRVNFTlQpOwotICAgICAgICBoLnB1dChFUlJPUiwgRVJST1JfRk9VTkQpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgcHJvZHVjdCB2ZXJzaW9uIGluZm9ybWF0aW9uIGZyb20gWGFsYW4tSi4KLSAgICoKLSAgICogTG9va3MgZm9yIHZlcnNpb24gaW5mbyBpbiB4YWxhbi5qYXIgZnJvbSBYYWxhbi1KIHByb2R1Y3RzLgotICAgKgotICAgKiBAcGFyYW0gaCBIYXNodGFibGUgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjaGVja1Byb2Nlc3NvclZlcnNpb24oSGFzaHRhYmxlIGgpCi0gIHsKLQotICAgIGlmIChudWxsID09IGgpCi0gICAgICBoID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgU3RyaW5nIFhBTEFOMV9WRVJTSU9OX0NMQVNTID0KLSAgICAgICAgIm9yZy5hcGFjaGUueGFsYW4ueHNsdC5YU0xQcm9jZXNzb3JWZXJzaW9uIjsKLSAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShYQUxBTjFfVkVSU0lPTl9DTEFTUyk7Ci0KLSAgICAgIC8vIEZvdW5kIFhhbGFuLUogMS54LCBncmFiIGl0J3MgdmVyc2lvbiBmaWVsZHMKLSAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgICBGaWVsZCBmID0gY2xhenouZ2V0RmllbGQoIlBST0RVQ1QiKTsKLQotICAgICAgYnVmLmFwcGVuZChmLmdldChudWxsKSk7Ci0gICAgICBidWYuYXBwZW5kKCc7Jyk7Ci0KLSAgICAgIGYgPSBjbGF6ei5nZXRGaWVsZCgiTEFOR1VBR0UiKTsKLQotICAgICAgYnVmLmFwcGVuZChmLmdldChudWxsKSk7Ci0gICAgICBidWYuYXBwZW5kKCc7Jyk7Ci0KLSAgICAgIGYgPSBjbGF6ei5nZXRGaWVsZCgiU19WRVJTSU9OIik7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoZi5nZXQobnVsbCkpOwotICAgICAgYnVmLmFwcGVuZCgnOycpOwotICAgICAgaC5wdXQoVkVSU0lPTiArICJ4YWxhbjEiLCBidWYudG9TdHJpbmcoKSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZTEpCi0gICAgewotICAgICAgaC5wdXQoVkVSU0lPTiArICJ4YWxhbjEiLCBDTEFTU19OT1RQUkVTRU5UKTsKLSAgICB9Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBmaW5hbCBTdHJpbmcgWEFMQU4yX1ZFUlNJT05fQ0xBU1MgPQotICAgICAgICAib3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuWFNMUHJvY2Vzc29yVmVyc2lvbiI7Ci0gICAgICBDbGFzcyBjbGF6eiA9IENsYXNzLmZvck5hbWUoWEFMQU4yX1ZFUlNJT05fQ0xBU1MpOwotCi0gICAgICAvLyBGb3VuZCBYYWxhbi1KIDIueCwgZ3JhYiBpdCdzIHZlcnNpb24gZmllbGRzCi0gICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotICAgICAgRmllbGQgZiA9IGNsYXp6LmdldEZpZWxkKCJQUk9EVUNUIik7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoZi5nZXQobnVsbCkpOwotICAgICAgYnVmLmFwcGVuZCgiOyIpOwotCi0gICAgICBmID0gY2xhenouZ2V0RmllbGQoIkxBTkdVQUdFIik7Ci0KLSAgICAgIGJ1Zi5hcHBlbmQoZi5nZXQobnVsbCkpOwotICAgICAgYnVmLmFwcGVuZCgiOyIpOwotCi0gICAgICBmID0gY2xhenouZ2V0RmllbGQoIlNfVkVSU0lPTiIpOwotCi0gICAgICBidWYuYXBwZW5kKGYuZ2V0KG51bGwpKTsKLSAgICAgIGJ1Zi5hcHBlbmQoIjsiKTsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGFsYW4yIiwgYnVmLnRvU3RyaW5nKCkpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUyKQotICAgIHsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAieGFsYW4yIiwgQ0xBU1NfTk9UUFJFU0VOVCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBwcm9kdWN0IHZlcnNpb24gaW5mb3JtYXRpb24gZnJvbSBjb21tb24gcGFyc2Vycy4KLSAgICoKLSAgICogTG9va3MgZm9yIHZlcnNpb24gaW5mbyBpbiB4ZXJjZXMuamFyL2NyaW1zb24uamFyLgotICAgKgotICAgKiAvL0B0b2RvIGFjdHVhbGx5IGxvb2sgdXAgdmVyc2lvbiBpbmZvIGluIGNyaW1zb24gbWFuaWZlc3QKLSAgICoKLSAgICogQHBhcmFtIGggSGFzaHRhYmxlIHRvIHB1dCBpbmZvcm1hdGlvbiBpbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY2hlY2tQYXJzZXJWZXJzaW9uKEhhc2h0YWJsZSBoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBoKQotICAgICAgaCA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIGZpbmFsIFN0cmluZyBYRVJDRVMxX1ZFUlNJT05fQ0xBU1MgPQotICAgICAgIm9yZy5hcGFjaGUueGVyY2VzLmZyYW1ld29yay5WZXJzaW9uIjsKLSAgICBmaW5hbCBTdHJpbmcgWEVSQ0VTMl9WRVJTSU9OX0NMQVNTID0KLSAgICAgICJvcmcuYXBhY2hlLnhlcmNlcy5pbXBsLlZlcnNpb24iOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgQ2xhc3MgY2xhenogPSBDbGFzcy5mb3JOYW1lKFhFUkNFUzFfVkVSU0lPTl9DTEFTUyk7Ci0KLSAgICAgIC8vIEZvdW5kIFhlcmNlcy1KIDEueCwgZ3JhYiBpdCdzIHZlcnNpb24gZmllbGRzCi0gICAgICBGaWVsZCBmID0gY2xhenouZ2V0RmllbGQoImZWZXJzaW9uIik7Ci0gICAgICBTdHJpbmcgcGFyc2VyVmVyc2lvbiA9IChTdHJpbmcpIGYuZ2V0KG51bGwpOwotCi0gICAgICBoLnB1dChWRVJTSU9OICsgInhlcmNlcyIsIHBhcnNlclZlcnNpb24pOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIC8vIE9vcHMsIG5vIDEueCBmb3VuZCwgbG9vayBmb3IgMi54Ci0gICAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShYRVJDRVMyX1ZFUlNJT05fQ0xBU1MpOwotCi0gICAgICAgIC8vIEZvdW5kIFhlcmNlcy1KIDIueCwgZ3JhYiBpdCdzIHZlcnNpb24gZmllbGRzCi0gICAgICAgIEZpZWxkIGYgPSBjbGF6ei5nZXRGaWVsZCgiZlZlcnNpb24iKTsKLSAgICAgICAgU3RyaW5nIHBhcnNlclZlcnNpb24gPSAoU3RyaW5nKSBmLmdldChudWxsKTsKLQotICAgICAgICBoLnB1dChWRVJTSU9OICsgInhlcmNlcyIsIHBhcnNlclZlcnNpb24pOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlMikKLSAgICAgIHsKLQotICAgICAgICAvLyBUaGlzIGlzbid0IG5lY2Vzc2FyaWx5IGFuIGVycm9yLCBzaW5jZSB0aGUgdXNlciBtaWdodCAKLSAgICAgICAgLy8gIGJlIHVzaW5nIHNvbWUgb3RoZXIgcGFyc2VyCi0gICAgICAgIGgucHV0KFZFUlNJT04gKyAieGVyY2VzIiwgQ0xBU1NfTk9UUFJFU0VOVCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIFRoaXMgaXNuJ3QgbmVjZXNzYXJpbHkgYW4gZXJyb3IsIHNpbmNlIHRoZSB1c2VyIG1pZ2h0IAotICAgICAgLy8gIGJlIHVzaW5nIHNvbWUgb3RoZXIgcGFyc2VyCi0gICAgICBoLnB1dChWRVJTSU9OICsgInhlcmNlcyIsIENMQVNTX05PVFBSRVNFTlQpOwotICAgIH0KLQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpbmFsIFN0cmluZyBDUklNU09OX0NMQVNTID0gIm9yZy5hcGFjaGUuY3JpbXNvbi5QYXJzZXIyIjsKLSAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShDUklNU09OX0NMQVNTKTsKLQotICAgICAgLy9AdG9kbyBkZXRlcm1pbmUgc3BlY2lmaWMgY3JpbXNvbiB2ZXJzaW9uCi0gICAgICBoLnB1dChWRVJTSU9OICsgImNyaW1zb24iLCBDTEFTU19QUkVTRU5UKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGgucHV0KFZFUlNJT04gKyAiY3JpbXNvbiIsIENMQVNTX05PVFBSRVNFTlQpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdmVyc2lvbiBpbmZvIGZyb20gRE9NIGludGVyZmFjZXMuIAotICAgKgotICAgKiBDdXJyZW50bHkgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIHByZS1ET00gbGV2ZWwgMiwgdGhlIERPTSAKLSAgICogbGV2ZWwgMiB3b3JraW5nIGRyYWZ0LCB0aGUgRE9NIGxldmVsIDIgZmluYWwgZHJhZnQsIAotICAgKiBhbmQgbm90IGZvdW5kLgotICAgKgotICAgKiBAcGFyYW0gaCBIYXNodGFibGUgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjaGVja0RPTVZlcnNpb24oSGFzaHRhYmxlIGgpCi0gIHsKLQotICAgIGlmIChudWxsID09IGgpCi0gICAgICBoID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgZmluYWwgU3RyaW5nIERPTV9MRVZFTDJfQ0xBU1MgPSAib3JnLnczYy5kb20uRG9jdW1lbnQiOwotICAgIGZpbmFsIFN0cmluZyBET01fTEVWRUwyX01FVEhPRCA9ICJjcmVhdGVFbGVtZW50TlMiOyAgLy8gU3RyaW5nLCBTdHJpbmcKLSAgICBmaW5hbCBTdHJpbmcgRE9NX0xFVkVMMldEX0NMQVNTID0gIm9yZy53M2MuZG9tLk5vZGUiOwotICAgIGZpbmFsIFN0cmluZyBET01fTEVWRUwyV0RfTUVUSE9EID0gInN1cHBvcnRlZCI7ICAvLyBTdHJpbmcsIFN0cmluZwotICAgIGZpbmFsIFN0cmluZyBET01fTEVWRUwyRkRfQ0xBU1MgPSAib3JnLnczYy5kb20uTm9kZSI7Ci0gICAgZmluYWwgU3RyaW5nIERPTV9MRVZFTDJGRF9NRVRIT0QgPSAiaXNTdXBwb3J0ZWQiOyAgLy8gU3RyaW5nLCBTdHJpbmcKLSAgICBmaW5hbCBDbGFzcyB0d29TdHJpbmdBcmdzW10gPSB7IGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzIH07Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBDbGFzcyBjbGF6eiA9IENsYXNzLmZvck5hbWUoRE9NX0xFVkVMMl9DTEFTUyk7Ci0gICAgICBNZXRob2QgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKERPTV9MRVZFTDJfTUVUSE9ELCB0d29TdHJpbmdBcmdzKTsKLQotICAgICAgLy8gSWYgd2Ugc3VjY2VlZGVkLCB3ZSBoYXZlIGxvYWRlZCBpbnRlcmZhY2VzIGZyb20gYSAKLSAgICAgIC8vICBsZXZlbCAyIERPTSBzb21ld2hlcmUKLSAgICAgIGgucHV0KFZFUlNJT04gKyAiRE9NIiwgIjIuMCIpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLQotICAgICAgICAvLyBDaGVjayBmb3IgdGhlIHdvcmtpbmcgZHJhZnQgdmVyc2lvbiwgd2hpY2ggaXMgCi0gICAgICAgIC8vICBjb21tb25seSBmb3VuZCwgYnV0IHdvbid0IHdvcmsgYW55bW9yZQotICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoRE9NX0xFVkVMMldEX0NMQVNTKTsKLSAgICAgICAgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKERPTV9MRVZFTDJXRF9NRVRIT0QsIHR3b1N0cmluZ0FyZ3MpOwotCi0gICAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJET00uZHJhZnRsZXZlbCIsICIyLjB3ZCIpOwotICAgICAgICBoLnB1dChFUlJPUiwgRVJST1JfRk9VTkQpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlMikKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLQotICAgICAgICAgIC8vIENoZWNrIGZvciB0aGUgZmluYWwgZHJhZnQgdmVyc2lvbiBhcyB3ZWxsCi0gICAgICAgICAgY2xhenogPSBDbGFzcy5mb3JOYW1lKERPTV9MRVZFTDJGRF9DTEFTUyk7Ci0gICAgICAgICAgbWV0aG9kID0gY2xhenouZ2V0TWV0aG9kKERPTV9MRVZFTDJGRF9NRVRIT0QsIHR3b1N0cmluZ0FyZ3MpOwotCi0gICAgICAgICAgaC5wdXQoVkVSU0lPTiArICJET00uZHJhZnRsZXZlbCIsICIyLjBmZCIpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChFeGNlcHRpb24gZTMpCi0gICAgICAgIHsKLSAgICAgICAgICBoLnB1dChFUlJPUiArIFZFUlNJT04gKyAiRE9NLmRyYWZ0bGV2ZWwiLCAiMi4wdW5rbm93biIpOwotICAgICAgICAgIGgucHV0KEVSUk9SLCBFUlJPUl9GT1VORCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJET00iLAotICAgICAgICAgICAgIkVSUk9SIGF0dGVtcHRpbmcgdG8gbG9hZCBET00gbGV2ZWwgMiBjbGFzczogIiArIGUudG9TdHJpbmcoKSk7Ci0gICAgICBoLnB1dChFUlJPUiwgRVJST1JfRk9VTkQpOwotICAgIH0KLQotICAgIC8vQHRvZG8gbG9hZCBhbiBhY3R1YWwgRE9NIGltcGxtZW1lbnRhdGlvbiBhbmQgcXVlcnkgaXQgYXMgd2VsbAotICAgIC8vQHRvZG8gbG9hZCBhbiBhY3R1YWwgRE9NIGltcGxtZW1lbnRhdGlvbiBhbmQgY2hlY2sgaWYgCi0gICAgLy8gIGlzTmFtZXNwYWNlQXdhcmUoKSA9PSB0cnVlLCB3aGljaCBpcyBuZWVkZWQgdG8gcGFyc2UgCi0gICAgLy8gIHhzbCBzdHlsZXNoZWV0IGZpbGVzIGludG8gYSBET00KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdmVyc2lvbiBpbmZvIGZyb20gU0FYIGludGVyZmFjZXMuIAotICAgKgotICAgKiBDdXJyZW50bHkgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIFNBWCAyLCBTQVggMi4wYmV0YTIsIAotICAgKiBTQVgxLCBhbmQgbm90IGZvdW5kLgotICAgKgotICAgKiBAcGFyYW0gaCBIYXNodGFibGUgdG8gcHV0IGluZm9ybWF0aW9uIGluCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjaGVja1NBWFZlcnNpb24oSGFzaHRhYmxlIGgpCi0gIHsKLQotICAgIGlmIChudWxsID09IGgpCi0gICAgICBoID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgZmluYWwgU3RyaW5nIFNBWF9WRVJTSU9OMV9DTEFTUyA9ICJvcmcueG1sLnNheC5QYXJzZXIiOwotICAgIGZpbmFsIFN0cmluZyBTQVhfVkVSU0lPTjFfTUVUSE9EID0gInBhcnNlIjsgIC8vIFN0cmluZwotICAgIGZpbmFsIFN0cmluZyBTQVhfVkVSU0lPTjJfQ0xBU1MgPSAib3JnLnhtbC5zYXguWE1MUmVhZGVyIjsKLSAgICBmaW5hbCBTdHJpbmcgU0FYX1ZFUlNJT04yX01FVEhPRCA9ICJwYXJzZSI7ICAvLyBTdHJpbmcKLSAgICBmaW5hbCBTdHJpbmcgU0FYX1ZFUlNJT04yQkVUQV9DTEFTU05GID0gIm9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwiOwotICAgIGZpbmFsIFN0cmluZyBTQVhfVkVSU0lPTjJCRVRBX01FVEhPRE5GID0gInNldEF0dHJpYnV0ZXMiOyAgLy8gQXR0cmlidXRlcwotICAgIGZpbmFsIENsYXNzIG9uZVN0cmluZ0FyZ1tdID0geyBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzIH07Ci0gICAgLy8gTm90ZSB0aGlzIGludHJvZHVjZXMgYSBtaW5vciBkZXBlbmRlbmN5IG9uIFNBWC4uLgotICAgIGZpbmFsIENsYXNzIGF0dHJpYnV0ZXNBcmdbXSA9IHsgb3JnLnhtbC5zYXguQXR0cmlidXRlcy5jbGFzcyB9OwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgLy8gVGhpcyBtZXRob2Qgd2FzIG9ubHkgYWRkZWQgaW4gdGhlIGZpbmFsIFNBWCAyLjAgcmVsZWFzZTsgCi0gICAgICAvLyAgc2VlIGNoYW5nZXMuaHRtbCAiQ2hhbmdlcyBmcm9tIFNBWCAyLjBiZXRhMiB0byBTQVggMi4wcHJlcmVsZWFzZSIKLSAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShTQVhfVkVSU0lPTjJCRVRBX0NMQVNTTkYpOwotICAgICAgTWV0aG9kIG1ldGhvZCA9IGNsYXp6LmdldE1ldGhvZChTQVhfVkVSU0lPTjJCRVRBX01FVEhPRE5GLCBhdHRyaWJ1dGVzQXJnKTsKLQotICAgICAgLy8gSWYgd2Ugc3VjY2VlZGVkLCB3ZSBoYXZlIGxvYWRlZCBpbnRlcmZhY2VzIGZyb20gYSAKLSAgICAgIC8vICByZWFsLCBmaW5hbCBTQVggdmVyc2lvbiAyLjAgc29tZXdoZXJlCi0gICAgICBoLnB1dChWRVJTSU9OICsgIlNBWCIsICIyLjAiKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIElmIHdlIGRpZG4ndCBmaW5kIHRoZSBTQVggMi4wIGNsYXNzLCBsb29rIGZvciBhIDIuMGJldGEyCi0gICAgICBoLnB1dChFUlJPUiArIFZFUlNJT04gKyAiU0FYIiwKLSAgICAgICAgICAgICJFUlJPUiBhdHRlbXB0aW5nIHRvIGxvYWQgU0FYIHZlcnNpb24gMiBjbGFzczogIiArIGUudG9TdHJpbmcoKSk7Ci0gICAgICBoLnB1dChFUlJPUiwgRVJST1JfRk9VTkQpOwotICAgICAgICAgICAgCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgQ2xhc3MgY2xhenogPSBDbGFzcy5mb3JOYW1lKFNBWF9WRVJTSU9OMl9DTEFTUyk7Ci0gICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoU0FYX1ZFUlNJT04yX01FVEhPRCwgb25lU3RyaW5nQXJnKTsKLQotICAgICAgICAvLyBJZiB3ZSBzdWNjZWVkZWQsIHdlIGhhdmUgbG9hZGVkIGludGVyZmFjZXMgZnJvbSBhIAotICAgICAgICAvLyAgU0FYIHZlcnNpb24gMi4wYmV0YTIgb3IgZWFybGllcjsgdGhlc2UgbWlnaHQgd29yayBidXQgCi0gICAgICAgIC8vICB5b3Ugc2hvdWxkIHJlYWxseSBoYXZlIHRoZSBmaW5hbCBTQVggMi4wIAotICAgICAgICBoLnB1dChWRVJTSU9OICsgIlNBWC1iYWNrbGV2ZWwiLCAiMi4wYmV0YTItb3ItZWFybGllciIpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlMikKLSAgICAgIHsKLSAgICAgICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgdGhlIFNBWCAyLjBiZXRhMiBjbGFzcywgbG9vayBmb3IgYSAxLjAgb25lCi0gICAgICAgIGgucHV0KEVSUk9SICsgVkVSU0lPTiArICJTQVgiLAotICAgICAgICAgICAgICAiRVJST1IgYXR0ZW1wdGluZyB0byBsb2FkIFNBWCB2ZXJzaW9uIDIgY2xhc3M6ICIgKyBlLnRvU3RyaW5nKCkpOwotICAgICAgICBoLnB1dChFUlJPUiwgRVJST1JfRk9VTkQpOwotICAgICAgICAgIAotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShTQVhfVkVSU0lPTjFfQ0xBU1MpOwotICAgICAgICAgIE1ldGhvZCBtZXRob2QgPSBjbGF6ei5nZXRNZXRob2QoU0FYX1ZFUlNJT04xX01FVEhPRCwgb25lU3RyaW5nQXJnKTsKLQotICAgICAgICAgIC8vIElmIHdlIHN1Y2NlZWRlZCwgd2UgaGF2ZSBsb2FkZWQgaW50ZXJmYWNlcyBmcm9tIGEgCi0gICAgICAgICAgLy8gIFNBWCB2ZXJzaW9uIDEuMCBzb21ld2hlcmU7IHdoaWNoIHdvbid0IHdvcmsgdmVyeSAKLSAgICAgICAgICAvLyAgd2VsbCBmb3IgSkFYUCAxLjEgb3IgYmV5b25kIQotICAgICAgICAgIGgucHV0KFZFUlNJT04gKyAiU0FYLWJhY2tsZXZlbCIsICIxLjAiKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUzKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgdGhlIFNBWCAyLjAgY2xhc3MsIGxvb2sgZm9yIGEgMS4wIG9uZQotICAgICAgICAgIC8vIE5vdGUgdGhhdCBlaXRoZXIgMS4wIG9yIG5vIFNBWCBhcmUgYm90aCBlcnJvcnMKLSAgICAgICAgICBoLnB1dChFUlJPUiArIFZFUlNJT04gKyAiU0FYLWJhY2tsZXZlbCIsCi0gICAgICAgICAgICAgICAgIkVSUk9SIGF0dGVtcHRpbmcgdG8gbG9hZCBTQVggdmVyc2lvbiAxIGNsYXNzOiAiICsgZTMudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKiBTaW1wbGUgUHJpbnRXcml0ZXIgd2Ugc2VuZCBvdXRwdXQgdG87IGRlZmF1bHRzIHRvIFN5c3RlbS5vdXQuICAqLwotICBwcm90ZWN0ZWQgUHJpbnRXcml0ZXIgb3V0V3JpdGVyID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5vdXQsIHRydWUpOwotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIG91dHB1dDogY2FsbHMgb3V0V3JpdGVyLnByaW50bG4ocykuICAKLSAgICogQHBhcmFtIHMgU3RyaW5nIHRvIHByaW50Ci0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBsb2dNc2coU3RyaW5nIHMpCi0gIHsKLSAgICBvdXRXcml0ZXIucHJpbnRsbihzKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdC9Qcm9jZXNzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1Byb2Nlc3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODRiZDI1ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L1Byb2Nlc3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQ7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uRmlsZVdyaXRlcjsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOwotCi1pbXBvcnQgamF2YS51dGlsLlRvb01hbnlMaXN0ZW5lcnNFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkRhdGU7Ci0KLS8vIE5lZWRlZCBYYWxhbiBjbGFzc2VzCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuWFNMUHJvY2Vzc29yVmVyc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldFJvb3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5YYWxhblByb3BlcnRpZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLlByaW50VHJhY2VMaXN0ZW5lcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnRyYWNlLlRyYWNlTGlzdGVuZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5UcmFjZU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRGVmYXVsdEVycm9ySGFuZGxlcjsKLQotLy8gTmVlZGVkIFRSYVggY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5Q29uZmlndXJhdGlvbkVycm9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5PdXRwdXRLZXlzOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5VUklSZXNvbHZlcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4Lio7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5OwotCi0vLyBOZWVkZWQgU2VyaWFsaXplciBjbGFzc2VzCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyRmFjdG9yeTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhlIG1haW4oKSBtZXRob2QgaGFuZGxlcyB0aGUgWGFsYW4gY29tbWFuZC1saW5lIGludGVyZmFjZS4KLSAqLwotcHVibGljIGNsYXNzIFByb2Nlc3MKLXsKLQotICAvKioKLSAgICogUHJpbnRzIGFyZ3VtZW50IG9wdGlvbnMuCi0gICAqCi0gICAqIEBwYXJhbSByZXNidW5kbGUgUmVzb3VyY2UgYnVuZGxlCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgcHJpbnRBcmdPcHRpb25zKFhTTFRFcnJvclJlc291cmNlcyByZXNidW5kbGUpCi0gIHsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJ4c2xQcm9jX29wdGlvbiIpKTsgIC8vInhzbHByb2Mgb3B0aW9uczogIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbklOIikpOyAgLy8iICAgIC1JTiBpbnB1dFhNTFVSTCIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25YU0wiKSk7ICAvLyIgICBbLVhTTCBYU0xUcmFuc2Zvcm1hdGlvblVSTF0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uT1VUIikpOyAgLy8iICAgWy1PVVQgb3V0cHV0RmlsZU5hbWVdIik7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uRSIpKTsgLy8iICAgWy1FIChEbyBub3QgZXhwYW5kIGVudGl0eSByZWZzKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uViIpKTsgIC8vIiAgIFstViAoVmVyc2lvbiBpbmZvKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uUUMiKSk7ICAvLyIgICBbLVFDIChRdWlldCBQYXR0ZXJuIENvbmZsaWN0cyBXYXJuaW5ncyldIik7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uUSIpKTsgIC8vIiAgIFstUSAgKFF1aWV0IE1vZGUpXSIpOyAvLyBzYyAyOC1GZWItMDEgY29tbWVudGVkIG91dAotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25UVCIpKTsgIC8vIiAgIFstVFQgKFRyYWNlIHRoZSB0ZW1wbGF0ZXMgYXMgdGhleSBhcmUgYmVpbmcgY2FsbGVkLildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvblRHIikpOyAgLy8iICAgWy1URyAoVHJhY2UgZWFjaCBnZW5lcmF0aW9uIGV2ZW50LildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvblRTIikpOyAgLy8iICAgWy1UUyAoVHJhY2UgZWFjaCBzZWxlY3Rpb24gZXZlbnQuKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uVFRDIikpOyAgLy8iICAgWy1UVEMgKFRyYWNlIHRoZSB0ZW1wbGF0ZSBjaGlsZHJlbiBhcyB0aGV5IGFyZSBiZWluZyBwcm9jZXNzZWQuKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uVENMQVNTIikpOyAgLy8iICAgWy1UQ0xBU1MgKFRyYWNlTGlzdGVuZXIgY2xhc3MgZm9yIHRyYWNlIGV4dGVuc2lvbnMuKV0iKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25WQUxJREFURSIpKTsgLy8iICAgWy1WQUxJREFURSAoU2V0IHdoZXRoZXIgdmFsaWRhdGlvbiBvY2N1cnMuICBWYWxpZGF0aW9uIGlzIG9mZiBieSBkZWZhdWx0LildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbkVEVU1QIikpOyAgLy8iICAgWy1FRFVNUCB7b3B0aW9uYWwgZmlsZW5hbWV9IChEbyBzdGFja2R1bXAgb24gZXJyb3IuKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uWE1MIikpOyAgLy8iICAgWy1YTUwgKFVzZSBYTUwgZm9ybWF0dGVyIGFuZCBhZGQgWE1MIGhlYWRlci4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25URVhUIikpOyAgLy8iICAgWy1URVhUIChVc2Ugc2ltcGxlIFRleHQgZm9ybWF0dGVyLildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbkhUTUwiKSk7ICAvLyIgICBbLUhUTUwgKFVzZSBIVE1MIGZvcm1hdHRlci4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25QQVJBTSIpKTsgIC8vIiAgIFstUEFSQU0gbmFtZSBleHByZXNzaW9uIChTZXQgYSBzdHlsZXNoZWV0IHBhcmFtZXRlcildIik7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoIm9wdGlvbkxJTkVOVU1CRVJTIikpOyAvLyIgICBbLUwgdXNlIGxpbmUgbnVtYmVyc10iCi0gICAgCi0gICAgLy8gc2MgMjgtRmViLTAxIHRoZXNlIGJlbG93IHNob3VsZCByZWFsbHkgYmUgYWRkZWQgYXMgcmVzb3VyY2VzCi0gICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgIiAgIFstTUVESUEgbWVkaWFUeXBlICh1c2UgbWVkaWEgYXR0cmlidXRlIHRvIGZpbmQgc3R5bGVzaGVldCBhc3NvY2lhdGVkIHdpdGggYSBkb2N1bWVudC4pXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigKLSAgICAgICIgICBbLUZMQVZPUiBmbGF2b3JOYW1lIChFeHBsaWNpdGx5IHVzZSBzMnM9U0FYIG9yIGQyZD1ET00gdG8gZG8gdHJhbnNmb3JtLildIik7ICAvLyBBZGRlZCBieSBzYm9hZy9zY3VyY3VydTsgZXhwZXJpbWVudGFsCi0gICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgIiAgIFstRElBRyAoUHJpbnQgb3ZlcmFsbCBtaWxsaXNlY29uZHMgdHJhbnNmb3JtIHRvb2suKV0iKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVzYnVuZGxlLmdldFN0cmluZygib3B0aW9uVVJJUkVTT0xWRVIiKSk7ICAvLyIgICBbLVVSSVJFU09MVkVSIGZ1bGwgY2xhc3MgbmFtZSAoVVJJUmVzb2x2ZXIgdG8gYmUgdXNlZCB0byByZXNvbHZlIFVSSXMpXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25FTlRJVFlSRVNPTFZFUiIpKTsgIC8vIiAgIFstRU5USVRZUkVTT0xWRVIgZnVsbCBjbGFzcyBuYW1lIChFbnRpdHlSZXNvbHZlciB0byBiZSB1c2VkIHRvIHJlc29sdmUgZW50aXRpZXMpXSIpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJvcHRpb25DT05URU5USEFORExFUiIpKTsgIC8vIiAgIFstQ09OVEVOVEhBTkRMRVIgZnVsbCBjbGFzcyBuYW1lIChDb250ZW50SGFuZGxlciB0byBiZSB1c2VkIHRvIHNlcmlhbGl6ZSBvdXRwdXQpXSIpOwotICB9Ci0gIAotICAvKioKLSAgICogQ29tbWFuZCBsaW5lIGludGVyZmFjZSB0byB0cmFuc2Zvcm0gYW4gWE1MIGRvY3VtZW50IGFjY29yZGluZyB0bwotICAgKiB0aGUgaW5zdHJ1Y3Rpb25zIGZvdW5kIGluIGFuIFhTTCBzdHlsZXNoZWV0LiAgCi0gICAqIDxwPlRoZSBQcm9jZXNzIGNsYXNzIHByb3ZpZGVzIGJhc2ljIGZ1bmN0aW9uYWxpdHkgZm9yIAotICAgKiBwZXJmb3JtaW5nIHRyYW5zZm9ybWF0aW9ucyBmcm9tIHRoZSBjb21tYW5kIGxpbmUuICBUbyBzZWUgYSAKLSAgICogbGlzdCBvZiBhcmd1bWVudHMgc3VwcG9ydGVkLCBjYWxsIHdpdGggemVybyBhcmd1bWVudHMuPC9wPgotICAgKiA8cD5UbyBzZXQgc3R5bGVzaGVldCBwYXJhbWV0ZXJzIGZyb20gdGhlIGNvbW1hbmQgbGluZSwgdXNlIAotICAgKiA8Y29kZT4tUEFSQU0gbmFtZSBleHByZXNzaW9uPC9jb2RlPi4gSWYgeW91IHdhbnQgdG8gc2V0IHRoZSAKLSAgICogcGFyYW1ldGVyIHRvIGEgc3RyaW5nIHZhbHVlLCBzaW1wbHkgcGFzcyB0aGUgc3RyaW5nIHZhbHVlIAotICAgKiBhcy1pcywgYW5kIGl0IHdpbGwgYmUgaW50ZXJwcmV0ZWQgYXMgYSBzdHJpbmcuICAoTm90ZTogaWYgCi0gICAqIHRoZSB2YWx1ZSBoYXMgc3BhY2VzIGluIGl0LCB5b3UgbWF5IG5lZWQgdG8gcXVvdGUgaXQgZGVwZW5kaW5nIAotICAgKiBvbiB5b3VyIHNoZWxsIGVudmlyb25tZW50KS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBhcmd2IElucHV0IHBhcmFtZXRlcnMgZnJvbSBjb21tYW5kIGxpbmUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pCi0gIHsKLSAgICAKLSAgICAvLyBSdW50aW1lLmdldFJ1bnRpbWUoKS50cmFjZU1ldGhvZENhbGxzKGZhbHNlKTsgLy8gdHVybnMgSmF2YSB0cmFjaW5nIG9mZgotICAgIGJvb2xlYW4gZG9TdGFja0R1bXBPbkVycm9yID0gZmFsc2U7Ci0gICAgYm9vbGVhbiBzZXRRdWlldE1vZGUgPSBmYWxzZTsKLSAgICBib29sZWFuIGRvRGlhZyA9IGZhbHNlOwotCi0gICAgLy8gUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VNZXRob2RDYWxscyhmYWxzZSk7Ci0gICAgLy8gUnVudGltZS5nZXRSdW50aW1lKCkudHJhY2VJbnN0cnVjdGlvbnMoZmFsc2UpOwotCi0gICAgLyoqCi0gICAgICogVGhlIGRlZmF1bHQgZGlhZ25vc3RpYyB3cml0ZXIuLi4KLSAgICAgKi8KLSAgICBqYXZhLmlvLlByaW50V3JpdGVyIGRpYWdub3N0aWNzV3JpdGVyID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpOwotICAgIGphdmEuaW8uUHJpbnRXcml0ZXIgZHVtcFdyaXRlciA9IGRpYWdub3N0aWNzV3JpdGVyOwotICAgIFhTTFRFcnJvclJlc291cmNlcyByZXNidW5kbGUgPQotICAgICAgKFhTTFRFcnJvclJlc291cmNlcykgKFhTTE1lc3NhZ2VzLmxvYWRSZXNvdXJjZUJ1bmRsZSgKLSAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZS5FUlJPUl9SRVNPVVJDRVMpKTsKLSAgICBTdHJpbmcgZmxhdm9yID0gInMycyI7Ci0KLSAgICBpZiAoYXJndi5sZW5ndGggPCAxKQotICAgIHsKLSAgICAgIHByaW50QXJnT3B0aW9ucyhyZXNidW5kbGUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgVHJhbnNmb3JtZXJGYWN0b3J5IHRmYWN0b3J5OwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgdGZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChUcmFuc2Zvcm1lckZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgcGZlKQotICAgICAgewotICAgICAgICBwZmUucHJpbnRTdGFja1RyYWNlKGR1bXBXcml0ZXIpOwotICAgICAgICBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKAotICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9UX1NVQ0NFU1NGVUwsIG51bGwpKTsgIC8vIlhTTCBQcm9jZXNzIHdhcyBub3Qgc3VjY2Vzc2Z1bC4iKTsKLQotICAgICAgICB0ZmFjdG9yeSA9IG51bGw7ICAvLyBzaHV0IHVwIGNvbXBpbGVyCi0KLSAgICAgICAgZG9FeGl0KC0xKTsKLSAgICAgIH0KLQotICAgICAgYm9vbGVhbiBmb3JtYXRPdXRwdXQgPSBmYWxzZTsKLSAgICAgIGJvb2xlYW4gdXNlU291cmNlTG9jYXRpb24gPSBmYWxzZTsKLSAgICAgIFN0cmluZyBpbkZpbGVOYW1lID0gbnVsbDsKLSAgICAgIFN0cmluZyBvdXRGaWxlTmFtZSA9IG51bGw7Ci0gICAgICBTdHJpbmcgZHVtcEZpbGVOYW1lID0gbnVsbDsKLSAgICAgIFN0cmluZyB4c2xGaWxlTmFtZSA9IG51bGw7Ci0gICAgICBTdHJpbmcgdHJlZWR1bXBGaWxlTmFtZSA9IG51bGw7Ci0gICAgICBQcmludFRyYWNlTGlzdGVuZXIgdHJhY2VyID0gbnVsbDsKLSAgICAgIFN0cmluZyBvdXRwdXRUeXBlID0gbnVsbDsKLSAgICAgIFN0cmluZyBtZWRpYSA9IG51bGw7Ci0gICAgICBWZWN0b3IgcGFyYW1zID0gbmV3IFZlY3RvcigpOwotICAgICAgYm9vbGVhbiBxdWlldENvbmZsaWN0V2FybmluZ3MgPSBmYWxzZTsKLSAgICAgIFVSSVJlc29sdmVyIHVyaVJlc29sdmVyID0gbnVsbDsKLSAgICAgIEVudGl0eVJlc29sdmVyIGVudGl0eVJlc29sdmVyID0gbnVsbDsKLSAgICAgIENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyID0gbnVsbDsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd2Lmxlbmd0aDsgaSsrKQotICAgICAgewotICAgICAgICBpZiAoIi1UVCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChudWxsID09IHRyYWNlcikKLSAgICAgICAgICAgIHRyYWNlciA9IG5ldyBQcmludFRyYWNlTGlzdGVuZXIoZGlhZ25vc3RpY3NXcml0ZXIpOwotCi0gICAgICAgICAgdHJhY2VyLm1fdHJhY2VUZW1wbGF0ZXMgPSB0cnVlOwotCi0gICAgICAgICAgLy8gdGZhY3Rvcnkuc2V0VHJhY2VUZW1wbGF0ZXModHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1URyIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChudWxsID09IHRyYWNlcikKLSAgICAgICAgICAgIHRyYWNlciA9IG5ldyBQcmludFRyYWNlTGlzdGVuZXIoZGlhZ25vc3RpY3NXcml0ZXIpOwotCi0gICAgICAgICAgdHJhY2VyLm1fdHJhY2VHZW5lcmF0aW9uID0gdHJ1ZTsKLQotICAgICAgICAgIC8vIHRmYWN0b3J5LnNldFRyYWNlU2VsZWN0KHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItVFMiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCA9PSB0cmFjZXIpCi0gICAgICAgICAgICB0cmFjZXIgPSBuZXcgUHJpbnRUcmFjZUxpc3RlbmVyKGRpYWdub3N0aWNzV3JpdGVyKTsKLQotICAgICAgICAgIHRyYWNlci5tX3RyYWNlU2VsZWN0aW9uID0gdHJ1ZTsKLQotICAgICAgICAgIC8vIHRmYWN0b3J5LnNldFRyYWNlVGVtcGxhdGVzKHRydWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItVFRDIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgPT0gdHJhY2VyKQotICAgICAgICAgICAgdHJhY2VyID0gbmV3IFByaW50VHJhY2VMaXN0ZW5lcihkaWFnbm9zdGljc1dyaXRlcik7Ci0KLSAgICAgICAgICB0cmFjZXIubV90cmFjZUVsZW1lbnRzID0gdHJ1ZTsKLQotICAgICAgICAgIC8vIHRmYWN0b3J5LnNldFRyYWNlVGVtcGxhdGVDaGlsZHJlbih0cnVlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLUlOREVOVCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGludCBpbmRlbnRBbW91bnQ7Ci0KLSAgICAgICAgICBpZiAoKChpICsgMSkgPCBhcmd2Lmxlbmd0aCkgJiYgKGFyZ3ZbaSArIDFdLmNoYXJBdCgwKSAhPSAnLScpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGluZGVudEFtb3VudCA9IEludGVnZXIucGFyc2VJbnQoYXJndlsrK2ldKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGluZGVudEFtb3VudCA9IDA7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gVEJEOgotICAgICAgICAgIC8vIHhtbFByb2Nlc3NvckxpYWlzb24uc2V0SW5kZW50KGluZGVudEFtb3VudCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1JTiIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChpICsgMSA8IGFyZ3YubGVuZ3RoKQotICAgICAgICAgICAgaW5GaWxlTmFtZSA9IGFyZ3ZbKytpXTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLUlOIiB9KSk7ICAvLyJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1NRURJQSIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChpICsgMSA8IGFyZ3YubGVuZ3RoKQotICAgICAgICAgICAgbWVkaWEgPSBhcmd2WysraV07Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1NRURJQSIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItT1VUIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgICBvdXRGaWxlTmFtZSA9IGFyZ3ZbKytpXTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLU9VVCIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItWFNMIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgICB4c2xGaWxlTmFtZSA9IGFyZ3ZbKytpXTsKLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLVhTTCIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRkxBVk9SIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgZmxhdm9yID0gYXJndlsrK2ldOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLUZMQVZPUiIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItUEFSQU0iLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDIgPCBhcmd2Lmxlbmd0aCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGFyZ3ZbKytpXTsKLQotICAgICAgICAgICAgcGFyYW1zLmFkZEVsZW1lbnQobmFtZSk7Ci0KLSAgICAgICAgICAgIFN0cmluZyBleHByZXNzaW9uID0gYXJndlsrK2ldOwotCi0gICAgICAgICAgICBwYXJhbXMuYWRkRWxlbWVudChleHByZXNzaW9uKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1QQVJBTSIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItdHJlZWR1bXAiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpICAvLyBzYyAyOC1GZWItMDEgYXBwZWFycyB0byBiZSB1bnVzZWQ7IGNhbiB3ZSByZW1vdmU/Ci0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCkKLSAgICAgICAgICAgIHRyZWVkdW1wRmlsZU5hbWUgPSBhcmd2WysraV07Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi10cmVlZHVtcCIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRiIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkgIC8vIHNjIDI4LUZlYi0wMSBhcHBlYXJzIHRvIGJlIHVudXNlZDsgY2FuIHdlIHJlbW92ZT8KLSAgICAgICAgewotICAgICAgICAgIGZvcm1hdE91dHB1dCA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1FIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBUQkQ6Ci0gICAgICAgICAgLy8geG1sUHJvY2Vzc29yTGlhaXNvbi5zZXRTaG91bGRFeHBhbmRFbnRpdHlSZWZzKGZhbHNlKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLVYiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKHJlc2J1bmRsZS5nZXRTdHJpbmcoInZlcnNpb24iKSAgLy8iPj4+Pj4+PiBYYWxhbiBWZXJzaW9uICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgWFNMUHJvY2Vzc29yVmVyc2lvbi5TX1ZFUlNJT04gKyAiLCAiICsKLQotICAgICAgICAgIC8qIHhtbFByb2Nlc3NvckxpYWlzb24uZ2V0UGFyc2VyRGVzY3JpcHRpb24oKSsgKi8KLSAgICAgICAgICByZXNidW5kbGUuZ2V0U3RyaW5nKCJ2ZXJzaW9uMiIpKTsgIC8vICI8PDw8PDw8Iik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1RQyIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIHF1aWV0Q29uZmxpY3RXYXJuaW5ncyA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1RIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgc2V0UXVpZXRNb2RlID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qCi0gICAgICAgIGVsc2UgaWYoIi1WQUxJREFURSIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIFN0cmluZyBzaG91bGRWYWxpZGF0ZTsKLSAgICAgICAgICBpZigoKGkrMSkgPCBhcmd2Lmxlbmd0aCkgJiYgKGFyZ3ZbaSsxXS5jaGFyQXQoMCkgIT0gJy0nKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBzaG91bGRWYWxpZGF0ZSA9IGFyZ3ZbKytpXTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHNob3VsZFZhbGlkYXRlID0gInllcyI7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8geG1sUHJvY2Vzc29yTGlhaXNvbi5zZXRVc2VWYWxpZGF0aW9uKHNob3VsZFZhbGlkYXRlLmVxdWFsc0lnbm9yZUNhc2UoInllcyIpKTsKLSAgICAgICAgfQotICAgICAgICAqLwotICAgICAgICBlbHNlIGlmICgiLURJQUciLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBkb0RpYWcgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItWE1MIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgb3V0cHV0VHlwZSA9ICJ4bWwiOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItVEVYVCIuZXF1YWxzSWdub3JlQ2FzZShhcmd2W2ldKSkKLSAgICAgICAgewotICAgICAgICAgIG91dHB1dFR5cGUgPSAidGV4dCI7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1IVE1MIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgb3V0cHV0VHlwZSA9ICJodG1sIjsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLUVEVU1QIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgZG9TdGFja0R1bXBPbkVycm9yID0gdHJ1ZTsKLQotICAgICAgICAgIGlmICgoKGkgKyAxKSA8IGFyZ3YubGVuZ3RoKSAmJiAoYXJndltpICsgMV0uY2hhckF0KDApICE9ICctJykpCi0gICAgICAgICAgewotICAgICAgICAgICAgZHVtcEZpbGVOYW1lID0gYXJndlsrK2ldOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLVVSSVJFU09MVkVSIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHVyaVJlc29sdmVyID0KLSAgICAgICAgICAgICAgICAoVVJJUmVzb2x2ZXIpIENsYXNzLmZvck5hbWUoYXJndlsrK2ldKS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICAgICAgICAgIHRmYWN0b3J5LnNldFVSSVJlc29sdmVyKHVyaVJlc29sdmVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gY25mZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0xBU1NfTk9UX0ZPVU5EX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItVVJJUmVzb2x2ZXIiIH0pKTsKLSAgICAgICAgICAgICAgZG9FeGl0KC0xKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICBYU0xURXJyb3JSZXNvdXJjZXMuRVJfTUlTU0lOR19BUkdfRk9SX09QVElPTiwKLSAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117ICItVVJJUmVzb2x2ZXIiIH0pKTsgIC8vIk1pc3NpbmcgYXJndW1lbnQgZm9yKTsKLSAgICAgICAgICAgIGRvRXhpdCgtMSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCItRU5USVRZUkVTT0xWRVIiLmVxdWFsc0lnbm9yZUNhc2UoYXJndltpXSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaSArIDEgPCBhcmd2Lmxlbmd0aCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZW50aXR5UmVzb2x2ZXIgPQotICAgICAgICAgICAgICAgIChFbnRpdHlSZXNvbHZlcikgQ2xhc3MuZm9yTmFtZShhcmd2WysraV0pLm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGNuZmUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NMQVNTX05PVF9GT1VORF9GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLUVudGl0eVJlc29sdmVyIiB9KSk7Ci0gICAgICAgICAgICAgIGRvRXhpdCgtMSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgICAgWFNMVEVycm9yUmVzb3VyY2VzLkVSX01JU1NJTkdfQVJHX0ZPUl9PUFRJT04sCi0gICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyAiLUVudGl0eVJlc29sdmVyIiB9KSk7ICAvLyJNaXNzaW5nIGFyZ3VtZW50IGZvcik7Ci0gICAgICAgICAgICBkb0V4aXQoLTEpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICgiLUNPTlRFTlRIQU5ETEVSIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGgpCi0gICAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGNvbnRlbnRIYW5kbGVyID0KLSAgICAgICAgICAgICAgICAoQ29udGVudEhhbmRsZXIpIENsYXNzLmZvck5hbWUoYXJndlsrK2ldKS5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBjbmZlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9DTEFTU19OT1RfRk9VTkRfRk9SX09QVElPTiwKLSAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1Db250ZW50SGFuZGxlciIgfSkpOwotICAgICAgICAgICAgICBkb0V4aXQoLTEpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKAotICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKAotICAgICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9NSVNTSU5HX0FSR19GT1JfT1BUSU9OLAotICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgIi1Db250ZW50SGFuZGxlciIgfSkpOyAgLy8iTWlzc2luZyBhcmd1bWVudCBmb3IpOwotICAgICAgICAgICAgZG9FeGl0KC0xKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIi1MIi5lcXVhbHNJZ25vcmVDYXNlKGFyZ3ZbaV0pKQotICAgICAgICAgIHVzZVNvdXJjZUxvY2F0aW9uID0gdHJ1ZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX09QVElPTiwgbmV3IE9iamVjdFtdeyBhcmd2W2ldIH0pKTsgIC8vIkludmFsaWQgYXJndW1lbnQ6KTsKLSAgICAgIH0KLQotICAgICAgLy8gTm90ZSB0aGF0IHRoZXJlIGFyZSB1c2FnZSBjYXNlcyBmb3IgY2FsbGluZyB1cyB3aXRob3V0IGEgLUlOIGFyZwotICAgICAgLy8gVGhlIG1haW4gWFNMIHRyYW5zZm9ybWF0aW9uIG9jY3VycyBoZXJlIQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBkdW1wRmlsZU5hbWUpCi0gICAgICAgIHsKLSAgICAgICAgICBkdW1wV3JpdGVyID0gbmV3IFByaW50V3JpdGVyKG5ldyBGaWxlV3JpdGVyKGR1bXBGaWxlTmFtZSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgVGVtcGxhdGVzIHN0eWxlc2hlZXQgPSBudWxsOwotCi0gICAgICAgIGlmIChudWxsICE9IHhzbEZpbGVOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGZsYXZvci5lcXVhbHMoImQyZCIpKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gUGFyc2UgaW4gdGhlIHhtbCBkYXRhIGludG8gYSBET00KLSAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGZhY3RvcnkgPQotICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgICAgICAgIGRmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCi0gICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgICAgICAgTm9kZSB4c2xET00gPSBkb2NCdWlsZGVyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZSh4c2xGaWxlTmFtZSkpOwotCi0gICAgICAgICAgICBzdHlsZXNoZWV0ID0gdGZhY3RvcnkubmV3VGVtcGxhdGVzKG5ldyBET01Tb3VyY2UoeHNsRE9NLAotICAgICAgICAgICAgICAgICAgICB4c2xGaWxlTmFtZSkpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJDYWxsaW5nIG5ld1RlbXBsYXRlczogIit4c2xGaWxlTmFtZSk7Ci0gICAgICAgICAgICBzdHlsZXNoZWV0ID0gdGZhY3RvcnkubmV3VGVtcGxhdGVzKG5ldyBTdHJlYW1Tb3VyY2UoeHNsRmlsZU5hbWUpKTsKLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRG9uZSBjYWxsaW5nIG5ld1RlbXBsYXRlczogIit4c2xGaWxlTmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgUHJpbnRXcml0ZXIgcmVzdWx0V3JpdGVyOwotICAgICAgICBTdHJlYW1SZXN1bHQgc3RyUmVzdWx0OwotCi0gICAgICAgIGlmIChudWxsICE9IG91dEZpbGVOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgc3RyUmVzdWx0ID0gbmV3IFN0cmVhbVJlc3VsdChuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRGaWxlTmFtZSkpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHN0clJlc3VsdCA9IG5ldyBTdHJlYW1SZXN1bHQoU3lzdGVtLm91dCk7Ci0gICAgICAgICAgdGZhY3Rvcnkuc2V0QXR0cmlidXRlKAotICAgICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLkZFQVRVUkVfSU5DUkVNRU5UQUwKLSAgICAgICAgICAgLCBCb29sZWFuLlRSVUUpOwotICAgICAgICB9Ci0KLSAgICAgICAgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHN0ZiA9IChTQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRmYWN0b3J5OwotCi0gICAgICAgIC8vIERpZCB0aGV5IHBhc3MgaW4gYSBzdHlsZXNoZWV0LCBvciBzaG91bGQgd2UgZ2V0IGl0IGZyb20gdGhlIAotICAgICAgICAvLyBkb2N1bWVudD8KLSAgICAgICAgaWYgKG51bGwgPT0gc3R5bGVzaGVldCkKLSAgICAgICAgewotICAgICAgICAgIFNvdXJjZSBzb3VyY2UgPQotICAgICAgICAgICAgc3RmLmdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KG5ldyBTdHJlYW1Tb3VyY2UoaW5GaWxlTmFtZSksIG1lZGlhLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIG51bGwpOwotCi0gICAgICAgICAgaWYgKG51bGwgIT0gc291cmNlKQotICAgICAgICAgICAgc3R5bGVzaGVldCA9IHRmYWN0b3J5Lm5ld1RlbXBsYXRlcyhzb3VyY2UpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCAhPSBtZWRpYSkKLSAgICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PX1NUWUxFU0hFRVRfSU5fTUVESUEsIG5ldyBPYmplY3RbXXtpbkZpbGVOYW1lLCBtZWRpYX0pKTsgLy8iTm8gc3R5bGVzaGVldCBmb3VuZCBpbjogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyArIGluRmlsZU5hbWUgKyAiLCBtZWRpYT0iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgbWVkaWEpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fU1RZTEVTSEVFVF9QSSwgbmV3IE9iamVjdFtde2luRmlsZU5hbWV9KSk7IC8vIk5vIHhtbC1zdHlsZXNoZWV0IFBJIGZvdW5kIGluOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgaW5GaWxlTmFtZSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gc3R5bGVzaGVldCkKLSAgICAgICAgewotICAgICAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gZmxhdm9yLmVxdWFscygidGgiKSA/IG51bGwgOiBzdHlsZXNoZWV0Lm5ld1RyYW5zZm9ybWVyKCk7Ci0KLSAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgb3V0cHV0IGZvcm1hdD8KLSAgICAgICAgICBpZiAobnVsbCAhPSBvdXRwdXRUeXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnNldE91dHB1dFByb3BlcnR5KE91dHB1dEtleXMuTUVUSE9ELCBvdXRwdXRUeXBlKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAodHJhbnNmb3JtZXIgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckltcGwpCi0gICAgICAgICAgewotICAgICAgICAgICAgVHJhbnNmb3JtZXJJbXBsIGltcGwgPSAoKFRyYW5zZm9ybWVySW1wbCkgdHJhbnNmb3JtZXIpOwotICAgICAgICAgICAgVHJhY2VNYW5hZ2VyIHRtID0gaW1wbC5nZXRUcmFjZU1hbmFnZXIoKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gdHJhY2VyKQotICAgICAgICAgICAgICB0bS5hZGRUcmFjZUxpc3RlbmVyKHRyYWNlcik7Ci0KLSAgICAgICAgICAgIGltcGwuc2V0UXVpZXRDb25mbGljdFdhcm5pbmdzKHF1aWV0Q29uZmxpY3RXYXJuaW5ncyk7Ci0KLSAgICAgICAgICAgIGlmICh1c2VTb3VyY2VMb2NhdGlvbikKLSAgICAgICAgICAgICAgaW1wbC5zZXRQcm9wZXJ0eShYYWxhblByb3BlcnRpZXMuU09VUkNFX0xPQ0FUSU9OLCBCb29sZWFuLlRSVUUpOwotCi0gICAgICAgICAgICAvLyBzYyAyOC1GZWItMDEgaWYgd2UgcmUtaW1wbGVtZW50IHRoaXMsIHBsZWFzZSB1bmNvbW1lbnQgaGVscG1zZyBpbiBwcmludEFyZ09wdGlvbnMKLSAgICAgICAgICAgIC8vIGltcGwuc2V0RGlhZ25vc3RpY3NPdXRwdXQoIHNldFF1aWV0TW9kZSA/IG51bGwgOiBkaWFnbm9zdGljc1dyaXRlciApOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGludCBuUGFyYW1zID0gcGFyYW1zLnNpemUoKTsKLQotICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgblBhcmFtczsgaSArPSAyKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnNldFBhcmFtZXRlcigoU3RyaW5nKSBwYXJhbXMuZWxlbWVudEF0KGkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTdHJpbmcpIHBhcmFtcy5lbGVtZW50QXQoaSArIDEpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAodXJpUmVzb2x2ZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHRyYW5zZm9ybWVyLnNldFVSSVJlc29sdmVyKHVyaVJlc29sdmVyKTsKLQotICAgICAgICAgIGlmIChudWxsICE9IGluRmlsZU5hbWUpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKGZsYXZvci5lcXVhbHMoImQyZCIpKQotICAgICAgICAgICAgewotCi0gICAgICAgICAgICAgIC8vIFBhcnNlIGluIHRoZSB4bWwgZGF0YSBpbnRvIGEgRE9NCi0gICAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGZhY3RvcnkgPQotICAgICAgICAgICAgICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgICAgICAgICBkZmFjdG9yeS5zZXRDb2FsZXNjaW5nKHRydWUpOwotICAgICAgICAgICAgICBkZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotCi0gICAgICAgICAgICAgIGlmIChlbnRpdHlSZXNvbHZlciAhPSBudWxsKQotICAgICAgICAgICAgICAgIGRvY0J1aWxkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZW50aXR5UmVzb2x2ZXIpOwotCi0gICAgICAgICAgICAgIE5vZGUgeG1sRG9jID0gZG9jQnVpbGRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpOwotICAgICAgICAgICAgICBEb2N1bWVudCBkb2MgPSBkb2NCdWlsZGVyLm5ld0RvY3VtZW50KCk7Ci0gICAgICAgICAgICAgIG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQgb3V0Tm9kZSA9Ci0gICAgICAgICAgICAgICAgZG9jLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IERPTVNvdXJjZSh4bWxEb2MsIGluRmlsZU5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERPTVJlc3VsdChvdXROb2RlKSk7Ci0KLSAgICAgICAgICAgICAgLy8gTm93IHNlcmlhbGl6ZSBvdXRwdXQgdG8gZGlzayB3aXRoIGlkZW50aXR5IHRyYW5zZm9ybWVyCi0gICAgICAgICAgICAgIFRyYW5zZm9ybWVyIHNlcmlhbGl6ZXIgPSBzdGYubmV3VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgICAgUHJvcGVydGllcyBzZXJpYWxpemF0aW9uUHJvcHMgPQotICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQuZ2V0T3V0cHV0UHJvcGVydGllcygpOwotCi0gICAgICAgICAgICAgIHNlcmlhbGl6ZXIuc2V0T3V0cHV0UHJvcGVydGllcyhzZXJpYWxpemF0aW9uUHJvcHMpOwotCi0gICAgICAgICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU0FYUmVzdWx0IHJlc3VsdCA9IG5ldyBTQVhSZXN1bHQoY29udGVudEhhbmRsZXIpOwotCi0gICAgICAgICAgICAgICAgc2VyaWFsaXplci50cmFuc2Zvcm0obmV3IERPTVNvdXJjZShvdXROb2RlKSwgcmVzdWx0KTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgc2VyaWFsaXplci50cmFuc2Zvcm0obmV3IERPTVNvdXJjZShvdXROb2RlKSwgc3RyUmVzdWx0KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGZsYXZvci5lcXVhbHMoInRoIikpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTsgaSsrKSAvLyBMb29wIGZvciBkaWFnbm9zaW5nIGJ1Z3Mgd2l0aCBpbmNvbnNpc3RlbnQgYmVoYXZpb3IKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3RpbmcgdGhlIFRyYW5zZm9ybWVySGFuZGxlci4uLiIpOwotCi0gICAgICAgICAgICAgIC8vID09PT09PT09PT09PT09PQotICAgICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbnVsbDsKLQotICAgICAgICAgICAgICAvLyBVc2UgSkFYUDEuMSAoIGlmIHBvc3NpYmxlICkgICAgICAKLSAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPQotICAgICAgICAgICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyID0KLSAgICAgICAgICAgICAgICAgIGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0KLSAgICAgICAgICAgICAgICByZWFkZXIgPSBqYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleDEudG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEVycm9yIGV4Mil7fQotICAgICAgICAgICAgICBjYXRjaCAoQWJzdHJhY3RNZXRob2RFcnJvciBhbWUpe30KLQotICAgICAgICAgICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIAotICAgICAgICAgICAgICBzdGYuc2V0QXR0cmlidXRlKG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlRyYW5zZm9ybWVyRmFjdG9yeUltcGwuRkVBVFVSRV9JTkNSRU1FTlRBTCwgCi0gICAgICAgICAgICAgICAgIEJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICBUcmFuc2Zvcm1lckhhbmRsZXIgdGggPSBzdGYubmV3VHJhbnNmb3JtZXJIYW5kbGVyKHN0eWxlc2hlZXQpOwotICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKHRoKTsKLSAgICAgICAgICAgICAgcmVhZGVyLnNldERUREhhbmRsZXIodGgpOwotICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgaWYodGggaW5zdGFuY2VvZiBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIpCi0gICAgICAgICAgICAgICAgcmVhZGVyLnNldEVycm9ySGFuZGxlcigob3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyKXRoKTsKLSAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmVhZGVyLnNldFByb3BlcnR5KAotICAgICAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsIHRoKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKXt9Ci0gICAgICAgICAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSl7fQotICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgICAgICAgICAgfSBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKSB7fQotICAgICAgICAKLSAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgICAgICAgICAgIH0gY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkge30KLSAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIHRoLnNldFJlc3VsdChzdHJSZXN1bHQpOwotICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJzZW5kaW5nIHBhcnNlIGV2ZW50cyB0byB0aGUgaGFuZGxlci4uLiIpOwotICAgICAgICAgICAgICAvLyBmb3IgKGludCBpID0gMDsgaSA8IDUwOyBpKyspIAotICAgICAgICAgICAgICB7Ci0vLyBTeXN0ZW0ub3V0LnByaW50KCIuIik7Ci0vLyBpZigoaSAlIDUwKSA9PSAwKQotLy8gICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOwotICAgICAgICAgICAgICAgIHJlYWRlci5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpOwotICAgICAgICAgICAgICAgIC8vIFRyYW5zZm9ybWVyIHQgPSAoKG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJIYW5kbGVySW1wbCl0aCkuZ2V0VHJhbnNmb3JtZXIoKTsKLSAgICAgICAgICAgICAgICAvLyBTeXN0ZW0uZXJyLnByaW50bG4oIkNhbGxpbmcgcmVzZXQiKTsKLSAgICAgICAgICAgICAgICAvLyAoKFRyYW5zZm9ybWVySW1wbCl0KS5yZXNldCgpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIAotICAgICAgICAgICAgICAKLQotLy8gICAgICAgICAgICAgIGlmIChjb250ZW50SGFuZGxlciAhPSBudWxsKQotLy8gICAgICAgICAgICAgIHsKLS8vICAgICAgICAgICAgICAgIFNBWFJlc3VsdCByZXN1bHQgPSBuZXcgU0FYUmVzdWx0KGNvbnRlbnRIYW5kbGVyKTsKLS8vCi0vLyAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oCi0vLyAgICAgICAgICAgICAgICAgIG5ldyBTQVhTb3VyY2UocmVhZGVyLCBuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpLCByZXN1bHQpOwotLy8gICAgICAgICAgICAgIH0KLS8vICAgICAgICAgICAgICBlbHNlCi0vLyAgICAgICAgICAgICAgewotLy8gICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKAotLy8gICAgICAgICAgICAgICAgICBuZXcgU0FYU291cmNlKHJlYWRlciwgbmV3IElucHV0U291cmNlKGluRmlsZU5hbWUpKSwKLS8vICAgICAgICAgICAgICAgICAgc3RyUmVzdWx0KTsKLS8vICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgLy8gPT09PT09PT09PT09PT09Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaWYgKGVudGl0eVJlc29sdmVyICE9IG51bGwpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBYTUxSZWFkZXIgcmVhZGVyID0gbnVsbDsKLQotICAgICAgICAgICAgICAgIC8vIFVzZSBKQVhQMS4xICggaWYgcG9zc2libGUgKSAgICAgIAotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9Ci0gICAgICAgICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgICAgICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgICAgICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyIGpheHBQYXJzZXIgPQotICAgICAgICAgICAgICAgICAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCi0gICAgICAgICAgICAgICAgICByZWFkZXIgPSBqYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKGV4KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oZXgxLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoTm9TdWNoTWV0aG9kRXJyb3IgZXgyKXt9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKEFic3RyYWN0TWV0aG9kRXJyb3IgYW1lKXt9Ci0KLSAgICAgICAgICAgICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICByZWFkZXIuc2V0RW50aXR5UmVzb2x2ZXIoZW50aXR5UmVzb2x2ZXIpOwotCi0gICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRIYW5kbGVyICE9IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgU0FYUmVzdWx0IHJlc3VsdCA9IG5ldyBTQVhSZXN1bHQoY29udGVudEhhbmRsZXIpOwotCi0gICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oCi0gICAgICAgICAgICAgICAgICAgIG5ldyBTQVhTb3VyY2UocmVhZGVyLCBuZXcgSW5wdXRTb3VyY2UoaW5GaWxlTmFtZSkpLAotICAgICAgICAgICAgICAgICAgICByZXN1bHQpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKAotICAgICAgICAgICAgICAgICAgICBuZXcgU0FYU291cmNlKHJlYWRlciwgbmV3IElucHV0U291cmNlKGluRmlsZU5hbWUpKSwKLSAgICAgICAgICAgICAgICAgICAgc3RyUmVzdWx0KTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZSBpZiAoY29udGVudEhhbmRsZXIgIT0gbnVsbCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFNBWFJlc3VsdCByZXN1bHQgPSBuZXcgU0FYUmVzdWx0KGNvbnRlbnRIYW5kbGVyKTsKLQotICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVyLnRyYW5zZm9ybShuZXcgU3RyZWFtU291cmNlKGluRmlsZU5hbWUpLCByZXN1bHQpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnRpbmcgdHJhbnNmb3JtIik7Ci0gICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoaW5GaWxlTmFtZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0clJlc3VsdCk7Ci0gICAgICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJEb25lIHdpdGggdHJhbnNmb3JtIik7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZ1JlYWRlciByZWFkZXIgPQotICAgICAgICAgICAgICBuZXcgU3RyaW5nUmVhZGVyKCI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/PiA8ZG9jLz4iKTsKLQotICAgICAgICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UocmVhZGVyKSwgc3RyUmVzdWx0KTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbigKLSAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoCi0gICAgICAgICAgICAgIFhTTFRFcnJvclJlc291cmNlcy5FUl9OT1RfU1VDQ0VTU0ZVTCwgbnVsbCkpOyAgLy8iWFNMIFByb2Nlc3Mgd2FzIG5vdCBzdWNjZXNzZnVsLiIpOwotICAgICAgICAgIGRvRXhpdCgtMSk7Ci0gICAgICAgIH0KLQotICAgICAgICBsb25nIHN0b3AgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLSAgICAgICAgbG9uZyBtaWxsaXNlY29uZHNEdXJhdGlvbiA9IHN0b3AgLSBzdGFydDsKLQotICAgICAgICBpZiAoZG9EaWFnKQotICAgICAgICAgIGRpYWdub3N0aWNzV3JpdGVyLnByaW50bG4oIlxuXG49PT09PT09PVxuVHJhbnNmb3JtIG9mICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgaW5GaWxlTmFtZSArICIgdmlhICIgKyB4c2xGaWxlTmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHRvb2sgIiArIG1pbGxpc2Vjb25kc0R1cmF0aW9uCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgbXMiKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChUaHJvd2FibGUgdGhyb3dhYmxlKQotICAgICAgewotICAgICAgICB3aGlsZSAodGhyb3dhYmxlCi0gICAgICAgICAgICAgICBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3dhYmxlID0KLSAgICAgICAgICAgICgob3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pIHRocm93YWJsZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoKHRocm93YWJsZSBpbnN0YW5jZW9mIE51bGxQb2ludGVyRXhjZXB0aW9uKQotICAgICAgICAgICAgICAgIHx8ICh0aHJvd2FibGUgaW5zdGFuY2VvZiBDbGFzc0Nhc3RFeGNlcHRpb24pKQotICAgICAgICAgIGRvU3RhY2tEdW1wT25FcnJvciA9IHRydWU7Ci0KLSAgICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbigpOwotCi0gICAgICAgIGlmIChkb1N0YWNrRHVtcE9uRXJyb3IpCi0gICAgICAgICAgdGhyb3dhYmxlLnByaW50U3RhY2tUcmFjZShkdW1wV3JpdGVyKTsKLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgRGVmYXVsdEVycm9ySGFuZGxlci5wcmludExvY2F0aW9uKGRpYWdub3N0aWNzV3JpdGVyLCB0aHJvd2FibGUpOwotICAgICAgICAgIGRpYWdub3N0aWNzV3JpdGVyLnByaW50bG4oCi0gICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9YU0xUX0VSUk9SLCBudWxsKQotICAgICAgICAgICAgKyAiICgiICsgdGhyb3dhYmxlLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIik6ICIKLSAgICAgICAgICAgICsgdGhyb3dhYmxlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBkaWFnbm9zdGljc1dyaXRlci5wcmludGxuKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PVF9TVUNDRVNTRlVMLCBudWxsKSk7IC8vIlhTTCBQcm9jZXNzIHdhcyBub3Qgc3VjY2Vzc2Z1bC4iKTsKLSAgICAgICAgaWYgKG51bGwgIT0gZHVtcEZpbGVOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgZHVtcFdyaXRlci5jbG9zZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgZG9FeGl0KC0xKTsKLSAgICAgIH0KLQotICAgICAgaWYgKG51bGwgIT0gZHVtcEZpbGVOYW1lKQotICAgICAgewotICAgICAgICBkdW1wV3JpdGVyLmNsb3NlKCk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChudWxsICE9IGRpYWdub3N0aWNzV3JpdGVyKQotICAgICAgewotCi0gICAgICAgIC8vIGRpYWdub3N0aWNzV3JpdGVyLmNsb3NlKCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGlmKCFzZXRRdWlldE1vZGUpCi0gICAgICAvLyAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbihyZXNidW5kbGUuZ2V0U3RyaW5nKCJ4c2xkb25lIikpOyAvLyJYYWxhbjogZG9uZSIpOwotICAgICAgLy8gZWxzZQotICAgICAgZGlhZ25vc3RpY3NXcml0ZXIucHJpbnRsbigiIik7ICAvLyJYYWxhbjogZG9uZSIpOwotICAgIH0KLSAgfQotICAKLSAgLyoqIEl0IGlzIF9tdWNoXyBlYXNpZXIgdG8gZGVidWcgdW5kZXIgVkorKyBpZiBJIGNhbiBzZXQgYSBzaW5nbGUgYnJlYWtwb2ludCAKLSAgICogYmVmb3JlIHRoaXMgYmxvd3MgaXRzZWxmIG91dCBvZiB0aGUgd2F0ZXIuLi4KLSAgICogKEkga2VlcCBjaGVja2luZyB0aGlzIGluLCBpdCBrZWVwcyB2YW5pc2hpbmcuIEdyciEpCi0gICAqICovCi0gIHN0YXRpYyB2b2lkIGRvRXhpdChpbnQgaSkKLSAgewotICAgICAgICAgIFN5c3RlbS5leGl0KGkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNjg2OTk2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsOCArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhhbGFuIGNvbW1hbmQtbGluZSBpbnRlcmZhY2UuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gY29tbWFuZC1saW5lIGludGVyZmFjZS48cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ET00uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmUwY2E4ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ET00uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0YzsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLXB1YmxpYyBpbnRlcmZhY2UgRE9NIHsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCAgRklSU1RfVFlQRSAgICAgICAgICAgICA9IDA7Ci0KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCAgTk9fVFlQRSAgICAgICAgICAgICAgICA9IC0xOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50ICBST09UICAgICAgICAgICAgICAgICAgID0gMDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCAgVEVYVCAgICAgICAgICAgICAgICAgICA9IDE7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgIFVOVVNFRCAgICAgICAgICAgICAgICAgPSAyOwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50ICBFTEVNRU5UICAgICAgICAgICAgICAgID0gMzsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCAgQVRUUklCVVRFICAgICAgICAgICAgICA9IDQ7Ci0gICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgIFBST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSA1OwotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50ICBDT01NRU5UICAgICAgICAgICAgICAgID0gNjsKLQkKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCAgTlRZUEVTICAgICAgICAgICAgICAgICA9IDc7Ci0gICAgCi0gICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgTm9kZUl0ZXJhdG9yLkVORAotICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE5VTEwgICAgID0gMDsKLSAgICAvLyBpbmRleCBvZiByb290IG5vZGUKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBST09UTk9ERSA9IDE7Ci0gICAgCi0gICAgLyoqIHJldHVybnMgc2luZ2xldG9uIGl0ZXJhdG9yIGNvbnRhaW5nIHRoZSBkb2N1bWVudCByb290ICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRJdGVyYXRvcigpOwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoKTsKLQkKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldENoaWxkcmVuKGZpbmFsIGludCBub2RlKTsKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldFR5cGVkQ2hpbGRyZW4oZmluYWwgaW50IHR5cGUpOwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0QXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzKTsKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgdHlwZSk7Ci0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROdGhEZXNjZW5kYW50KGludCBub2RlLCBpbnQgbik7Ci0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCBucyk7Ci0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROb2RlVmFsdWVJdGVyYXRvcihOb2RlSXRlcmF0b3IgaXRlciwKLQkJCQkJICAgICBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gb3ApOwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3Igb3JkZXJOb2RlcyhOb2RlSXRlcmF0b3Igc291cmNlLCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VOYW1lKGZpbmFsIGludCBub2RlKTsKLSAgICBwdWJsaWMgaW50IGdldFR5cGUoZmluYWwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlVHlwZShmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIGludCBnZXRQYXJlbnQoZmluYWwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShmaW5hbCBpbnQgZ1R5cGUsIGZpbmFsIGludCBlbGVtZW50KTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShmaW5hbCBpbnQgbm9kZSk7Ci0gICAgcHVibGljIHZvaWQgY29weShmaW5hbCBpbnQgbm9kZSwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGNvcHkoTm9kZUl0ZXJhdG9yIG5vZGVzLCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIFN0cmluZyBzaGFsbG93Q29weShmaW5hbCBpbnQgbm9kZSwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKTsKLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGZpbmFsIGludCB0ZXh0Tm9kZSwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKGludCBpbmRleCk7Ci0gICAgcHVibGljIE5vZGUgbWFrZU5vZGUoTm9kZUl0ZXJhdG9yIGl0ZXIpOwotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KTsKLSAgICBwdWJsaWMgTm9kZUxpc3QgbWFrZU5vZGVMaXN0KE5vZGVJdGVyYXRvciBpdGVyKTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldExhbmd1YWdlKGludCBub2RlKTsKLSAgICBwdWJsaWMgaW50IGdldFNpemUoKTsKLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKGludCBub2RlKTsKLSAgICBwdWJsaWMgaW50IGdldFR5cGVkUG9zaXRpb24oTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBpbnQgdHlwZSwgaW50IG5vZGUpOwotICAgIHB1YmxpYyBpbnQgZ2V0VHlwZWRMYXN0KE5vZGVJdGVyYXRvciBpdGVyYXRvciwgaW50IHR5cGUsIGludCBub2RlKTsKLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKTsKLSAgICBwdWJsaWMgdm9pZCBzZXR1cE1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIG5hbWVzcGFjZXMpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NQ2FjaGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL0RPTUNhY2hlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZiYzE0MDYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NQ2FjaGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5ET01JbXBsOwotCi1wdWJsaWMgaW50ZXJmYWNlIERPTUNhY2hlIHsKLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHJlc3BvbnNpYmxlIGZvcjoKLSAgICAgKgotICAgICAqICgxKSBidWlsZGluZyB0aGUgRE9NSW1wbCB0cmVlCi0gICAgICogIAotICAgICAqICAgICAgUGFyc2VyICBfcGFyc2VyID0gbmV3IFBhcnNlcigpOwotICAgICAqICAgICAgRE9NSW1wbCBfZG9tID0gbmV3IERPTUltcGwoKTsKLSAgICAgKiAgICAgIF9wYXJzZXIuc2V0RG9jdW1lbnRIYW5kbGVyKF9kb20uZ2V0QnVpbGRlcigpKTsKLSAgICAgKiAgICAgIF9wYXJzZXIucGFyc2UodXJpKTsKLSAgICAgKgotICAgICAqICgyKSBidWlsZGluZyBpbmRpY2llcyBmb3IgYWxsIElEIGVsZW1lbnRzIChkZWNsYXJlZCBpbiBEVEQpOgotICAgICAqCi0gICAgICogICAgICBEVERNb25pdG9yIF9kdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLSAgICAgKiAgICAgIF9wYXJzZXIuc2V0RFRESGFuZGxlcihfZHRkTW9uaXRvcik7Ci0gICAgICogICAgICB0cmFuc2xldC5zZXRJbmRleFNpemUoZG9tLmdldFNpemUoKSk7Ci0gICAgICogICAgICBkdGQuYnVpbGRJZEluZGV4KGRvbSwgbWFzaywgdHJhbnNsZXQpOwotICAgICAqCi0gICAgICogKDMpIHBhc3NpbmcgdW5wYXJzZWQgZW50aXR5IFVSSSBlbGVtZW50cyBmcm9tIERURCB0byB0cmFuc2xldDoKLSAgICAgKgotICAgICAqICAgICAgdHJhbnNsZXQuc2V0VW5wYXJzZWRFbnRpdHlVUklzKGR0ZC5nZXRVbnBhcnNlZEVudGl0eVVSSXMoKSk7Ci0gICAgICoKLSAgICAgKiAoNCkgc2V0dGluZyB0aGUgZG9jdW1lbnQgVVJJOgotICAgICAqCi0gICAgICogICAgICBfZG9tLnNldERvY3VtZW50VVJJKHVyaSk7Ci0gICAgICovCi0gICAgcHVibGljIERPTUltcGwgcmV0cmlldmVEb2N1bWVudChTdHJpbmcgdXJpLCBpbnQgbWFzaywgVHJhbnNsZXQgdHJhbnNsZXQpOwotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9Ob2RlSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL05vZGVJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZjMwNWFkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL05vZGVJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjOwotCi1wdWJsaWMgaW50ZXJmYWNlIE5vZGVJdGVyYXRvciBleHRlbmRzIENsb25lYWJsZSB7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5EID0gRE9NLk5VTEw7Ci0KLSAgICAvKiogCi0gICAgICogQ2FsbGVycyBzaG91bGQgbm90IGNhbGwgbmV4dCgpIGFmdGVyIGl0IHJldHVybnMgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpOwotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBpdGVyYXRvciB0byB0aGUgbGFzdCBzdGFydCBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgcmVzZXQoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgbm9kZSBpbiB0aGUgc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKTsKLQotICAgIC8qKgotICAgICAqIFJlbWVtYmVycyB0aGUgY3VycmVudCBub2RlIGZvciB0aGUgbmV4dCBjYWxsIHRvIGdvdG9NYXJrKCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpOwotCi0gICAgLyoqCi0gICAgICogUmVzdG9yZXMgdGhlIGN1cnJlbnQgbm9kZSByZW1lbWJlcmVkIGJ5IHNldE1hcmsoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpOwotCi0gICAgLyoqIAotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLCAKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpOwotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiB0aGlzIGl0ZXJhdG9yIGhhcyBhIHJldmVyc2VkIGF4aXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1N0cmlwRmlsdGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9TdHJpcEZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNjFmYjU1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1N0cmlwRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0YzsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotCi1wdWJsaWMgaW50ZXJmYWNlIFN0cmlwRmlsdGVyIHsKLSAgICBwdWJsaWMgYm9vbGVhbiBzdHJpcFNwYWNlKERPTSBkb20sIGludCBub2RlLCBpbnQgdHlwZSk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvVHJhbnNsZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDI4N2ExMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODEgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGM7Ci0KLXB1YmxpYyBpbnRlcmZhY2UgVHJhbnNsZXQgewotCi0gICAgcHVibGljIHZvaWQgdHJhbnNmb3JtKERPTSBkb2N1bWVudCwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShET00gZG9jdW1lbnQsIFRyYW5zbGV0T3V0cHV0SGFuZGxlcltdIGhhbmRsZXJzKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oRE9NIGRvY3VtZW50LCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IsCi0JCQkgIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLQotICAgIHB1YmxpYyBPYmplY3QgYWRkUGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpOwotCi0gICAgcHVibGljIHZvaWQgYnVpbGRLZXlzKERPTSBkb2N1bWVudCwgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLAotCQkJICBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlciwgaW50IHJvb3QpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvVHJhbnNsZXRFeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA3ODM2YzAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvVHJhbnNsZXRFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgVHJhbnNsZXRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewotICAgIHB1YmxpYyBUcmFuc2xldEV4Y2VwdGlvbigpIHsKLQlzdXBlcigpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgVHJhbnNsZXRFeGNlcHRpb24oRXhjZXB0aW9uIGUpIHsKLQlzdXBlcihlLnRvU3RyaW5nKCkpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgVHJhbnNsZXRFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKLQlzdXBlcihtZXNzYWdlKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldE91dHB1dEhhbmRsZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1RyYW5zbGV0T3V0cHV0SGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNTNmYTExLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1RyYW5zbGV0T3V0cHV0SGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0YzsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuSGFzaHRhYmxlOwotCi1wdWJsaWMgaW50ZXJmYWNlIFRyYW5zbGV0T3V0cHV0SGFuZGxlciB7Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgZWxlbWVudE5hbWUpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoYXJhY3RlcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZShTdHJpbmcgYXR0cmlidXRlTmFtZSwgU3RyaW5nIGF0dHJpYnV0ZVZhbHVlKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBuYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoU3RyaW5nIGNvbW1lbnQpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIHNldFR5cGUoaW50IHR5cGUpOwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudChib29sZWFuIGluZGVudCk7Ci0gICAgcHVibGljIHZvaWQgb21pdEhlYWRlcihib29sZWFuIHZhbHVlKTsKLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIHNldENkYXRhRWxlbWVudHMoSGFzaHRhYmxlIGVsZW1lbnRzKTsKLSAgICBwdWJsaWMgdm9pZCBjbG9zZSgpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY21kbGluZS9Db21waWxlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lL0NvbXBpbGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGRjNWZiNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lL0NvbXBpbGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNtZGxpbmU7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRPdXRwdXRIYW5kbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5YU0xUQzsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVXRpbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNtZGxpbmUuZ2V0b3B0Lio7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBDb21waWxlIHsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBVU0FHRV9TVFJJTkcgPQotCSJVc2FnZTpcbiIgKyAKLQkiICAgeHNsdGMgWy1vIDxvdXRwdXQ+XSBbLWQgPGRpcmVjdG9yeT5dIFstaiA8amFyZmlsZT5dXG4iKwotCSIgICAgICAgICBbLXAgPHBhY2thZ2UgbmFtZT5dIFsteF0gWy11XSA8c3R5bGVzaGVldD4uLi4gXG5cbiIrCi0JIiAgIFdoZXJlIDxvdXRwdXQ+IGlzIHRoZSBuYW1lIHRvIGdpdmUgdGhlIHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQuXG4iKwotCSIgICAgICAgICA8c3R5bGVzaGVldD4gaXMgb25lIG9yIG1vcmUgc3R5bGVzaGVldCBmaWxlIG5hbWVzLCBvciBpZixcbiIrCi0JIiAgICAgICAgIHRoZSAtdSBvcHRpb25zIGlzIHNwZWNpZmllZCwgb25lIG9yIG1vcmUgc3R5bGVzaGVldCBVUkxzLlxuIisKLQkiICAgICAgICAgPGRpcmVjdG9yeT4gaXMgdGhlIG91dHB1dCBkaXJlY3RvcnkuXG4iKwotCSIgICAgICAgICA8amFyZmlsZT4gaXMgdGhlIG5hbWUgb2YgYSBKQVItZmlsZSB0byBwdXQgYWxsIGdlbmVyYXRlZCBjbGFzc2VzIGluLlxuIisKLQkiICAgICAgICAgPHBhY2thZ2UtbmFtZT4gaXMgYSBwYWNrYWdlIG5hbWUgdG8gcHJlZml4IGFsbCBjbGFzcyBuYW1lcyB3aXRoLlxuXG4iKwotCSIgICBOb3RlczpcbiIrCi0JIiAgICAgICAgIFRoZSAtbyBvcHRpb24gaXMgaWdub3JlZCB3aGVuIG11bHRpcGxlIHN0eWxlc2hlZXRzIGFyZSBzcGVjaWZpZWQuXG4iKwotCSIgICAgICAgICBUaGUgLXggb3B0aW9uIHN3aXRjaGVkIG9uIGRlYnVnIG1lc3NhZ2VzLiI7Ci0gICAgCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50VXNhZ2UoKSB7Ci0JU3lzdGVtLmVyci5wcmludGxuKFVTQUdFX1NUUklORyk7Ci0JU3lzdGVtLmV4aXQoLTEpOwotICAgIH0KLQotICAgIC8qKiAKLSAgICAgKiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIHRoZSBjb21tYW5kIGxpbmUgY29tcGlsZXIuIFNlZSB0aGUgVVNBR0VfU1RSSU5HCi0gICAgICogY29uc3RhbnQgZm9yIGEgZGVzY3JpcHRpb24uIEl0IG1heSBtYWtlIHNlbnNlIHRvIG1vdmUgdGhlIGNvbW1hbmQtbGluZQotICAgICAqIGhhbmRsaW5nIHRvIGEgc2VwYXJhdGUgcGFja2FnZSAoaWUuIG1ha2Ugb25lIHhzbHRjLmNtZGxpbmUuQ29tcGlsZXIKLSAgICAgKiBjbGFzcyB0aGF0IGNvbnRhaW5zIHRoaXMgbWFpbigpIG1ldGhvZCBhbmQgb25lIHhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtCi0gICAgICogY2xhc3MgdGhhdCBjb250YWlucyB0aGUgRGVmYXVsdFJ1biBzdHVmZikuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewotCXRyeSB7Ci0JICAgIGJvb2xlYW4gaW5wdXRJc1VSTCA9IGZhbHNlOwotCi0JICAgIGZpbmFsIEdldE9wdCBnZXRvcHQgPSBuZXcgR2V0T3B0KGFyZ3MsICJvOmQ6ajpwOnV4aHMiKTsKLQkgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgcHJpbnRVc2FnZSgpOwotCi0JICAgIGZpbmFsIFhTTFRDIHhzbHRjID0gbmV3IFhTTFRDKCk7Ci0JICAgIHhzbHRjLmluaXQoKTsKLQotCSAgICBpbnQgYzsKLQkgICAgd2hpbGUgKChjID0gZ2V0b3B0LmdldE5leHRPcHRpb24oKSkgIT0gLTEpIHsKLQkJc3dpdGNoKGMpIHsKLQkJY2FzZSAnbyc6Ci0JCSAgICB4c2x0Yy5zZXRDbGFzc05hbWUoZ2V0b3B0LmdldE9wdGlvbkFyZygpKTsKLQkJICAgIGJyZWFrOwotCQljYXNlICdkJzoKLQkJICAgIHhzbHRjLnNldERlc3REaXJlY3RvcnkoZ2V0b3B0LmdldE9wdGlvbkFyZygpKTsKLQkJICAgIGJyZWFrOwotCQljYXNlICdwJzoKLQkJICAgIHhzbHRjLnNldFBhY2thZ2VOYW1lKGdldG9wdC5nZXRPcHRpb25BcmcoKSk7Ci0JCSAgICBicmVhazsKLQkJY2FzZSAnaic6ICAKLQkJICAgIHhzbHRjLnNldEphckZpbGVOYW1lKGdldG9wdC5nZXRPcHRpb25BcmcoKSk7Ci0JCSAgICBicmVhazsKLQkJY2FzZSAneCc6Ci0JCSAgICB4c2x0Yy5zZXREZWJ1Zyh0cnVlKTsKLQkJICAgIGJyZWFrOwotCQljYXNlICd1JzoKLQkJICAgIGlucHV0SXNVUkwgPSB0cnVlOwotCQkgICAgYnJlYWs7Ci0JCWNhc2UgJ2gnOgotCQlkZWZhdWx0OgotCQkgICAgcHJpbnRVc2FnZSgpOwotCQkgICAgYnJlYWs7IAotCQl9Ci0JICAgIH0KLQotCSAgICAvLyBHZW5lcmF0ZSBhIHZlY3RvciBjb250YWluZyBVUkxzIGZvciBhbGwgc3R5bGVzaGVldHMgc3BlY2lmaWVkCi0JICAgIGZpbmFsIFN0cmluZ1tdIHN0eWxlc2hlZXROYW1lcyA9IGdldG9wdC5nZXRDbWRBcmdzKCk7Ci0JICAgIGZpbmFsIFZlY3RvciAgIHN0eWxlc2hlZXRWZWN0b3IgPSBuZXcgVmVjdG9yKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3R5bGVzaGVldE5hbWVzLmxlbmd0aDsgaSsrKSB7Ci0JCWZpbmFsIFN0cmluZyBuYW1lID0gc3R5bGVzaGVldE5hbWVzW2ldOwotCQlVUkwgdXJsOwotCQlpZiAoaW5wdXRJc1VSTCkKLQkJICAgIHVybCA9IG5ldyBVUkwobmFtZSk7Ci0JCWVsc2UKLQkJICAgIHVybCA9IChuZXcgRmlsZShuYW1lKSkudG9VUkwoKTsKLQkJc3R5bGVzaGVldFZlY3Rvci5hZGRFbGVtZW50KHVybCk7Ci0JICAgIH0KLQotCSAgICAvLyBDb21waWxlIHRoZSBzdHlsZXNoZWV0IGFuZCBvdXRwdXQgY2xhc3MvamFyIGZpbGUocykKLQkgICAgaWYgKHhzbHRjLmNvbXBpbGUoc3R5bGVzaGVldFZlY3RvcikpIHsKLQkJeHNsdGMucHJpbnRXYXJuaW5ncygpOwotCQlpZiAoeHNsdGMuZ2V0SmFyRmlsZU5hbWUoKSAhPSBudWxsKSB4c2x0Yy5vdXRwdXRUb0phcigpOwotCQlTeXN0ZW0uZXhpdCgwKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJeHNsdGMucHJpbnRXYXJuaW5ncygpOwotCQl4c2x0Yy5wcmludEVycm9ycygpOwotCQlTeXN0ZW0uZXhpdCgtMSk7Ci0JICAgIH0KLQl9Ci0JY2F0Y2ggKEdldE9wdHNFeGNlcHRpb24gZXgpIHsKLQkgICAgU3lzdGVtLmVyci5wcmludGxuKGV4KTsKLQkgICAgcHJpbnRVc2FnZSgpOyAvLyBleGl0cyB3aXRoIGNvZGUgJy0xJwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLQkgICAgU3lzdGVtLmV4aXQoLTEpOwotCX0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvVHJhbnNmb3JtLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lL1RyYW5zZm9ybS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MTA2ZGJlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvVHJhbnNmb3JtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jbWRsaW5lOwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldE91dHB1dEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5ET01JbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRPTUJ1aWxkZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uQXhpczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5EVERNb25pdG9yOwotCi1maW5hbCBwdWJsaWMgY2xhc3MgVHJhbnNmb3JtIHsKLQotICAgIHByaXZhdGUgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIF9oYW5kbGVyOwotCi0gICAgcHJpdmF0ZSBTdHJpbmcgIF9maWxlTmFtZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX2NsYXNzTmFtZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX2phckZpbGVTcmM7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pc0phckZpbGVTcGVjaWZpZWQgPSBmYWxzZTsKLSAgICBwcml2YXRlIFZlY3RvciAgX3BhcmFtcyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF91cmksIF9kZWJ1ZzsKLQotICAgIHB1YmxpYyBUcmFuc2Zvcm0oU3RyaW5nIGNsYXNzTmFtZSwgU3RyaW5nIGZpbGVOYW1lLAotCQkgICAgIGJvb2xlYW4gdXJpLCBib29sZWFuIGRlYnVnKSB7Ci0JX2ZpbGVOYW1lID0gZmlsZU5hbWU7Ci0JX2NsYXNzTmFtZSA9IGNsYXNzTmFtZTsKLQlfdXJpID0gdXJpOwotCV9kZWJ1ZyA9IGRlYnVnOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcnMoVmVjdG9yIHBhcmFtcykgewotCV9wYXJhbXMgPSBwYXJhbXM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldEphckZpbGVJbnB1dFNyYyhib29sZWFuIGZsYWcsICBTdHJpbmcgamFyRmlsZSkgewotCS8vIFRPRE86IGF0IHRoaXMgdGltZSB3ZSBkbyBub3QgZG8gYW55dGhpbmcgd2l0aCB0aGlzCi0JLy8gaW5mb3JtYXRpb24sIGF0dGVtcHRzIHRvIGFkZCB0aGUgamFyZmlsZSB0byB0aGUgQ0xBU1NQQVRICi0JLy8gd2VyZSBzdWNjZXNzZnVsIHZpYSBTeXN0ZW0uc2V0UHJvcGVydHksIGJ1dCB0aGUgZWZmZWN0cwotCS8vIHdlcmUgbm90IHZpc2libGUgdG8gdGhlIHJ1bm5pbmcgSlZNLiBGb3Igbm93IHdlIGFkZCBqYXJmaWxlCi0JLy8gdG8gQ0xBU1NQQVRIIGluIHRoZSB3cmFwcGVyIHNjcmlwdCB0aGF0IGNhbGxzIHRoaXMgcHJvZ3JhbS4gCi0JX2lzSmFyRmlsZVNwZWNpZmllZCA9IGZsYWc7Ci0JLy8gVE9ETyB2ZXJpZnkgamFyRmlsZSBleGlzdHMuLi4KLQlfamFyRmlsZVNyYyA9IGphckZpbGU7CQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBkb1RyYW5zZm9ybSgpIHsKLQl0cnkgewotCSAgICBmaW5hbCBDbGFzcyBjbGF6eiA9IENsYXNzLmZvck5hbWUoX2NsYXNzTmFtZSk7Ci0JICAgIGZpbmFsIFRyYW5zbGV0IHRyYW5zbGV0ID0gKFRyYW5zbGV0KWNsYXp6Lm5ld0luc3RhbmNlKCk7Ci0KLQkgICAgLy8gQ3JlYXRlIGEgU0FYIHBhcnNlciBhbmQgZ2V0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGl0IHVzZXMKLQkgICAgZmluYWwgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCSAgICB0cnkgewotCQlmYWN0b3J5LnNldEZlYXR1cmUoQ29uc3RhbnRzLk5BTUVTUEFDRV9GRUFUVVJFLHRydWUpOwotCSAgICB9Ci0JICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotCQlmYWN0b3J5LnNldE5hbWVzcGFjZUF3YXJlKHRydWUpOwotCSAgICB9Ci0JICAgIGZpbmFsIFNBWFBhcnNlciBwYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCSAgICBmaW5hbCBYTUxSZWFkZXIgcmVhZGVyID0gcGFyc2VyLmdldFhNTFJlYWRlcigpOwotCi0JICAgIC8vIFNldCB0aGUgRE9NJ3MgRE9NIGJ1aWxkZXIgYXMgdGhlIFhNTFJlYWRlcidzIFNBWDIgY29udGVudCBoYW5kbGVyCi0JICAgIGZpbmFsIERPTUltcGwgZG9tID0gbmV3IERPTUltcGwoKTsKLQkgICAgZmluYWwgRE9NQnVpbGRlciBidWlsZGVyID0gZG9tLmdldEJ1aWxkZXIoKTsKLQkgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGJ1aWxkZXIpOwotCi0JICAgIHRyeSB7Ci0JCVN0cmluZyBwcm9wID0gImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciI7Ci0JCXJlYWRlci5zZXRQcm9wZXJ0eShwcm9wLCBidWlsZGVyKTsKLQkgICAgfQotCSAgICBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkJLy8gcXVpdGVseSBpZ25vcmVkCi0JICAgIH0KLQkgICAgCi0JICAgIC8vIENyZWF0ZSBhIERURCBtb25pdG9yIGFuZCBwYXNzIGl0IHRvIHRoZSBYTUxSZWFkZXIgb2JqZWN0Ci0JICAgIGZpbmFsIERURE1vbml0b3IgZHRkTW9uaXRvciA9IG5ldyBEVERNb25pdG9yKCk7Ci0JICAgIGR0ZE1vbml0b3IuaGFuZGxlRFREKHJlYWRlcik7Ci0KLQkgICAgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldDsKLQkgICAgZG9tLnNldERvY3VtZW50VVJJKF9maWxlTmFtZSk7Ci0JICAgIGlmIChfdXJpKQotCQlyZWFkZXIucGFyc2UoX2ZpbGVOYW1lKTsKLQkgICAgZWxzZQotCQlyZWFkZXIucGFyc2UoImZpbGU6IisobmV3IEZpbGUoX2ZpbGVOYW1lKS5nZXRBYnNvbHV0ZVBhdGgoKSkpOwotCSAgICAKLQkgICAgLy8gU2V0IHNpemUgb2Yga2V5L2lkIGluZGljZXMKLQkgICAgX3RyYW5zbGV0LnNldEluZGV4U2l6ZShkb20uZ2V0U2l6ZSgpKTsKLQkgICAgLy8gSWYgdGhlcmUgYXJlIGFueSBlbGVtZW50cyB3aXRoIElEIGF0dHJpYnV0ZXMsIGJ1aWxkIGFuIGluZGV4Ci0JICAgIGR0ZE1vbml0b3IuYnVpbGRJZEluZGV4KGRvbSwgMCwgX3RyYW5zbGV0KTsKLQotCSAgICBfdHJhbnNsZXQuc2V0RFRETW9uaXRvcihkdGRNb25pdG9yKTsKLQotCSAgICAvLyBQYXNzIGdsb2JhbCBwYXJhbWV0ZXJzCi0JICAgIGludCBuID0gX3BhcmFtcy5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCVBhcmFtZXRlciBwYXJhbSA9IChQYXJhbWV0ZXIpIF9wYXJhbXMuZWxlbWVudEF0KGkpOwotCQl0cmFuc2xldC5hZGRQYXJhbWV0ZXIocGFyYW0uX25hbWUsIHBhcmFtLl92YWx1ZSk7Ci0JICAgIH0KLQotCSAgICAvLyBUcmFuc2Zvcm0gdGhlIGRvY3VtZW50Ci0JICAgIFN0cmluZyBlbmNvZGluZyA9IF90cmFuc2xldC5fZW5jb2Rpbmc7Ci0KLQkgICAgLy8gQ3JlYXRlIG91ciBkZWZhdWx0IFNBWC9EVEQgaGFuZGxlcgotCSAgICBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlciBzYXhIYW5kbGVyID0KLQkJbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKFN5c3RlbS5vdXQsIGVuY29kaW5nKTsKLQkgICAgLy8gQ3JlYXRlIGEgdHJhbnNsZXQgb3V0cHV0IGhhbmRsZXIgYW5kIHBsdWcgaW4gdGhlIFNBWC9EVEQgaGFuZGxlcgotCSAgICBUZXh0T3V0cHV0IHRleHRPdXRwdXQgPQotCQluZXcgVGV4dE91dHB1dCgoQ29udGVudEhhbmRsZXIpc2F4SGFuZGxlciwKLQkJCSAgICAgICAoTGV4aWNhbEhhbmRsZXIpc2F4SGFuZGxlciwgZW5jb2RpbmcpOwotCSAgICAvLyBUcmFuc2Zvcm0gYW5kIHBhc3Mgb3V0cHV0IHRvIHRoZSB0cmFuc2xldCBvdXRwdXQgaGFuZGxlcgotCSAgICB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCB0ZXh0T3V0cHV0KTsKLQotCSAgICBpZiAoX2RlYnVnKSB7Ci0JCVRyYW5zbGV0T3V0cHV0QmFzZSBoYW5kbGVyID0gbmV3IFRyYW5zbGV0T3V0cHV0QmFzZSgpOwotCQlsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCWZpbmFsIGludCBuVGltZXMgPSAxMDA7Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgblRpbWVzOyBpKyspCi0JCSAgICB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCBkb20uZ2V0SXRlcmF0b3IoKSwgaGFuZGxlcik7Ci0JCWxvbmcgZW5kID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigidG90YWwgIiArIChlbmQgLSBzdGFydCkgKyAiIG1zZWMgZm9yICIgCi0JCQkJICAgKyBuVGltZXMgKyAiIHRyYW5zZm9ybWF0aW9ucyIpOwotCQlTeXN0ZW0ub3V0LnByaW50bG4oKChkb3VibGUpZW5kIC0gc3RhcnQpL25UaW1lcyArICIgbXNlYyBhdmciKTsKLQkgICAgfQotCX0KLQljYXRjaCAoVHJhbnNsZXRFeGNlcHRpb24gZSkgewotCSAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlxuVHJhbnNsZXQgRXJyb3I6ICIgKyBlLmdldE1lc3NhZ2UoKSk7Ci0JICAgIFN5c3RlbS5leGl0KC0xKTsJICAgIAotCX0KLQljYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0JICAgIGlmIChfZGVidWcpIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXG5SdW50aW1lIEVycm9yOiAiICsgZS5nZXRNZXNzYWdlKCkpOwotCSAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0JfQotCWNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgewotCSAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBGaWxlIG9yIFVSSSAnIitfZmlsZU5hbWUrIicgbm90IGZvdW5kLiIpOwotCSAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0JfQotCWNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotCSAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBJbnZhbGlkIFVSSSAnIitfZmlsZU5hbWUrIicuIik7Ci0JICAgIFN5c3RlbS5leGl0KC0xKTsKLQl9Ci0JY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotCSAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBDYW5ub3QgZmluZCBjbGFzcyAnIitfY2xhc3NOYW1lKyInLiIpOwotCSAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0JfQotICAgICAgICBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgewotCSAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBDYW4ndCByZXNvbHZlIFVSSSBzcGVjaWZpY2F0aW9uICciKyAKLQkJCSAgICAgICBfZmlsZU5hbWUrIicuIik7Ci0JICAgIFN5c3RlbS5leGl0KC0xKTsKLSAgICAgICAgfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBpZiAoX2RlYnVnKSBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiAiK2UuZ2V0TWVzc2FnZSgpKTsKLQkgICAgU3lzdGVtLmV4aXQoLTEpOwotCX0KLSAgICB9Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgVVNBR0VfU1RSSU5HID0KLQkiVXNhZ2U6IFxuIiArCi0JIiAgICAgeHNsdCBbLWogPGphcmZpbGU+XSB7LXUgPGRvY3VtZW50X3VybD4gfCA8ZG9jdW1lbnQ+fSA8Y2xhc3M+XG4iKwotCSIgICAgICAgICAgWzxuYW1lMT49PHZhbHVlMT4gLi4uXVxuXG4iICsKLQkiICAgICAgICAgICA8ZG9jdW1lbnQ+IGlzIHRoZSB4bWwgZG9jdW1lbnQgdG8gYmUgdHJhbnNmb3JtZWQsIG9yXG4iICsKLQkiICAgICAgICAgICA8ZG9jdW1lbnRfdXJsPiBpcyBhIHVybCBmb3IgdGhlIHhtbCBkb2N1bWVudCxcbiIgKwotCSIgICAgICAgICAgIDxjbGFzcz4gaXMgdGhlIHRyYW5zbGV0IGNsYXNzIHdoaWNoIGlzIGVpdGhlciBpblxuIiArCi0JIiAgICAgICAgICAgdXNlcidzIENMQVNTUEFUSCBvciBpbiB0aGUgPGphcmZpbGU+IHNwZWNpZmllZCBcbiIgKwotCSIgICAgICAgICAgIHdpdGggdGhlIC1qIG9wdGlvbi5cbiIgKwotCSIgICAgICAgICAgYWxzbzogWy14XSAoZGVidWcpLCBbLXNdIChkb24ndCBhbGxvdyBTeXN0ZW0uZXhpdCkiOwkKLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludFVzYWdlKCkgewotCVN5c3RlbS5lcnIucHJpbnRsbihVU0FHRV9TVFJJTkcpOwotCVN5c3RlbS5leGl0KC0xKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7Ci0JdHJ5IHsKLQkgICAgaWYgKGFyZ3MubGVuZ3RoID4gMCkgewotCQlpbnQgaTsKLQkJYm9vbGVhbiB1cmkgPSBmYWxzZSwgZGVidWcgPSBmYWxzZTsKLQkJYm9vbGVhbiBpc0phckZpbGVTcGVjaWZpZWQgPSBmYWxzZTsKLQkJU3RyaW5nICBqYXJGaWxlID0gbnVsbDsKLQotCQkvLyBQYXJzZSBvcHRpb25zIHN0YXJ0aW5nIHdpdGggJy0nCi0JCWZvciAoaSA9IDA7IGkgPCBhcmdzLmxlbmd0aCAmJiBhcmdzW2ldLmNoYXJBdCgwKSA9PSAnLSc7IGkrKykgewotCQkgICAgaWYgKGFyZ3NbaV0uZXF1YWxzKCItdSIpKSB7Ci0JCQl1cmkgPSB0cnVlOwotCQkgICAgfQotCQkgICAgZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi14IikpIHsKLQkJCWRlYnVnID0gdHJ1ZTsKLQkJICAgIH0KLQkJICAgIGVsc2UgaWYgKGFyZ3NbaV0uZXF1YWxzKCItaiIpKSB7Ci0JCQlpc0phckZpbGVTcGVjaWZpZWQgPSB0cnVlOwkKLQkJCWphckZpbGUgPSBhcmdzWysraV07Ci0JCSAgICB9Ci0JCSAgICBlbHNlIHsKLQkJCXByaW50VXNhZ2UoKTsKLQkJICAgIH0KLQkJfQotCi0JCS8vIEVub3VnaCBhcmd1bWVudHMgbGVmdCA/Ci0JCWlmIChhcmdzLmxlbmd0aCAtIGkgPCAyKSBwcmludFVzYWdlKCk7Ci0KLQkJLy8gR2V0IGRvY3VtZW50IGZpbGUgYW5kIGNsYXNzIG5hbWUKLQkJVHJhbnNmb3JtIGhhbmRsZXIgPSBuZXcgVHJhbnNmb3JtKGFyZ3NbaSsxXSxhcmdzW2ldLHVyaSxkZWJ1Zyk7Ci0JCWhhbmRsZXIuc2V0SmFyRmlsZUlucHV0U3JjKGlzSmFyRmlsZVNwZWNpZmllZCwJamFyRmlsZSk7Ci0KLQkJLy8gUGFyc2Ugc3R5bGVzaGVldCBwYXJhbWV0ZXJzCi0JCVZlY3RvciBwYXJhbXMgPSBuZXcgVmVjdG9yKCk7Ci0JCWZvciAoaSArPSAyOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgewotCQkgICAgZmluYWwgaW50IGVxdWFsID0gYXJnc1tpXS5pbmRleE9mKCc9Jyk7Ci0JCSAgICBpZiAoZXF1YWwgPiAwKSB7Ci0JCQlmaW5hbCBTdHJpbmcgbmFtZSAgPSBhcmdzW2ldLnN1YnN0cmluZygwLCBlcXVhbCk7Ci0JCQlmaW5hbCBTdHJpbmcgdmFsdWUgPSBhcmdzW2ldLnN1YnN0cmluZyhlcXVhbCsxKTsKLQkJCXBhcmFtcy5hZGRFbGVtZW50KG5ldyBQYXJhbWV0ZXIobmFtZSwgdmFsdWUpKTsKLQkJICAgIH0KLQkJICAgIGVsc2UgewotCQkJcHJpbnRVc2FnZSgpOwotCQkgICAgfQotCQl9Ci0KLQkJaWYgKGkgPT0gYXJncy5sZW5ndGgpIHsKLQkJICAgIGhhbmRsZXIuc2V0UGFyYW1ldGVycyhwYXJhbXMpOwotCQkgICAgaGFuZGxlci5kb1RyYW5zZm9ybSgpOwotCQkgICAgU3lzdGVtLmV4aXQoMCk7Ci0JCX0KLQkgICAgfSBlbHNlIHsKLQkJcHJpbnRVc2FnZSgpOwotCSAgICB9Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lL2dldG9wdC9HZXRPcHQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0dldE9wdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYzZiNjk4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0dldE9wdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk2ICswLDAgQEAKLS8qCi0gKiAkSWQkIAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgRyBUb2RkIE1pbGxlciAKLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNtZGxpbmUuZ2V0b3B0OyAKLQotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKLWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY21kbGluZS5nZXRvcHQuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY21kbGluZS5nZXRvcHQuTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbjsKLQotCi0vKioKLSogR2V0T3B0IGlzIGEgSmF2YSBlcXVpdmFsZW50IHRvIHRoZSBDIGdldG9wdCgpIGxpYnJhcnkgZnVuY3Rpb24KLSogZGlzY3Vzc2VkIGluIG1hbiBwYWdlIGdldG9wdCgzQykuIEl0IHByb3ZpZGVzIGNvbW1hbmQgbGluZQotKiBwYXJzaW5nIGZvciBKYXZhIGFwcGxpY2F0aW9ucy4gSXQgc3VwcG9ydHMgdGhlIG1vc3QgcnVsZXMgb2YgdGhlCi0qIGNvbW1hbmQgbGluZSBzdGFuZGFyZCAoc2VlIG1hbiBwYWdlIGludHJvKDEpKSBpbmNsdWRpbmcgc3RhY2tlZAotKiBvcHRpb25zIHN1Y2ggYXMgJy1zeG0nICh3aGljaCBpcyBlcXVpdmFsZW50IHRvIC1zIC14IC1tKTsgaXQKLSogaGFuZGxlcyBzcGVjaWFsICctLScgb3B0aW9uIHRoYXQgc2lnbmlmaWVzIHRoZSBlbmQgb2Ygb3B0aW9ucy4KLSogQWRkaXRpb25hbGx5IHRoaXMgaW1wbGVtZW50YXRpb24gb2YgZ2V0b3B0IHdpbGwgY2hlY2sgZm9yCi0qIG1hbmRhdG9yeSBhcmd1bWVudHMgdG8gb3B0aW9ucyBzdWNoIGFzIGluIHRoZSBjYXNlIG9mCi0qICctZCA8ZmlsZT4nIGl0IHdpbGwgdGhyb3cgYSBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uIGlmIHRoZSAKLSogb3B0aW9uIGFyZ3VtZW50ICc8ZmlsZT4nIGlzIG5vdCBpbmNsdWRlZCBvbiB0aGUgY29tbWFuZGxpbmUuCi0qIGdldG9wdCgzQykgZG9lcyBub3QgY2hlY2sgZm9yIHRoaXMuIAotKi8KLXB1YmxpYyBjbGFzcyBHZXRPcHR7Ci0gICAgcHVibGljIEdldE9wdChTdHJpbmdbXSBhcmdzLCBTdHJpbmcgb3B0U3RyaW5nKXsKLQl0aGVPcHRpb25zID0gbmV3IEFycmF5TGlzdCgpOwkJIAotCWludCBjdXJyT3B0SW5kZXggPSAwOyAKLQl0aGVDbWRBcmdzID0gbmV3IEFycmF5TGlzdCgpOyAKLQl0aGVPcHRpb25NYXRjaGVyID0gbmV3IE9wdGlvbk1hdGNoZXIob3B0U3RyaW5nKTsKLQkvLyBmaWxsIGluIHRoZSBvcHRpb25zIGxpc3QKLQlmb3IoaW50IGk9MDsgaTxhcmdzLmxlbmd0aDsgaSsrKXsKLQkgICAgU3RyaW5nIHRva2VuID0gYXJnc1tpXTsKLQkgICAgaW50IHRva2VuTGVuZ3RoID0gdG9rZW4ubGVuZ3RoKCk7Ci0JICAgIGlmKHRva2VuLmVxdWFscygiLS0iKSl7CSAgICAvLyBlbmQgb2Ygb3B0cwotCSAgICAgICAgY3Vyck9wdEluZGV4ID0gaSsxOwkgICAgLy8gc2V0IGluZGV4IG9mIGZpcnN0IG9wZXJhbmQKLSAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgLy8gZW5kIG9mIG9wdGlvbnMKLQkgICAgfQotCSAgICBlbHNlIGlmKHRva2VuLnN0YXJ0c1dpdGgoIi0iKSAmJiB0b2tlbkxlbmd0aCA9PSAyKXsgCi0JCS8vIHNpbXBsZSBvcHRpb24gdG9rZW4gc3VjaCBhcyAnLXMnIGZvdW5kCi0JCXRoZU9wdGlvbnMuYWRkKG5ldyBPcHRpb24odG9rZW4uY2hhckF0KDEpKSk7CQotCSAgICB9Ci0JICAgIGVsc2UgaWYodG9rZW4uc3RhcnRzV2l0aCgiLSIpICYmIHRva2VuTGVuZ3RoID4gMil7Ci0JCS8vIHN0YWNrZWQgb3B0aW9ucyBmb3VuZCwgc3VjaCBhcyAnLXNobScKLQkJLy8gaXRlcmF0ZSB0aHJ1IHRoZSB0b2tlbnMgYWZ0ZXIgdGhlIGRhc2ggYW5kCi0JCS8vIGFkZCB0aGVtIHRvIHRoZU9wdGlvbnMgbGlzdAotCQlmb3IoaW50IGo9MTsgajx0b2tlbkxlbmd0aDsgaisrKXsKLQkJICAgIHRoZU9wdGlvbnMuYWRkKG5ldyBPcHRpb24odG9rZW4uY2hhckF0KGopKSk7Ci0JCX0KLQkgICAgfQkJCi0JICAgIGVsc2UgaWYoIXRva2VuLnN0YXJ0c1dpdGgoIi0iKSl7Ci0JCS8vIGNhc2UgMS0gdGhlcmUgYXJlIG5vdCBvcHRpb25zIHN0b3JlZCB5ZXQgdGhlcmVmb3JlCi0JCS8vIHRoaXMgbXVzdCBiZSBhbiBjb21tYW5kIGFyZ3VtZW50LCBub3QgYW4gb3B0aW9uIGFyZ3VtZW50Ci0JCWlmKHRoZU9wdGlvbnMuc2l6ZSgpID09IDApewotCQkgICAgY3Vyck9wdEluZGV4ID0gaTsKLQkJICAgIGJyZWFrOwkJLy8gc3RvcCBwcm9jZXNzaW5nIG9wdGlvbnMKLQkJfQotCQllbHNlIHsKLQkJICAgIC8vIGNhc2UgMi0gCi0JCSAgICAvLyB0aGVyZSBhcmUgb3B0aW9ucyBzdG9yZWQsIGNoZWNrIHRvIHNlZSBpZgotCQkgICAgLy8gdGhpcyBhcmcgYmVsb25nIHRvIHRoZSBsYXN0IGFyZyBzdG9yZWQJCi0JCSAgICBpbnQgaW5kZXhvZmxhc3Q9MDsKLQkJICAgIGluZGV4b2ZsYXN0ID0gdGhlT3B0aW9ucy5zaXplKCktMTsKLQkJICAgIE9wdGlvbiBvcCA9IChPcHRpb24pdGhlT3B0aW9ucy5nZXQoaW5kZXhvZmxhc3QpOwotCQkgICAgY2hhciBvcExldHRlciA9IG9wLmdldEFyZ0xldHRlcigpOwotCQkgICAgaWYoIW9wLmhhc0FyZygpICYmIHRoZU9wdGlvbk1hdGNoZXIuaGFzQXJnKG9wTGV0dGVyKSl7Ci0JCSAgICAgICAgb3Auc2V0QXJnKHRva2VuKTsKLQkJICAgIH0KLQkJICAgIGVsc2V7Ci0JCSAgICAgICAgLy8gY2FzZSAzIC0gCi0JCSAgICAgICAgLy8gdGhlIGxhc3Qgb3B0aW9uIHN0b3JlZCBkb2VzIG5vdCB0YWtlCi0JCSAgICAgICAgLy8gYW4gYXJndW1lbnQsIHNvIGFnYWluLCB0aGlzIGFyZ3VtZW50Ci0JCSAgICAgICAgLy8gbXVzdCBiZSBhIGNvbW1hbmQgYXJndW1lbnQsIG5vdCAKLQkJICAgICAgICAvLyBhbiBvcHRpb24gYXJndW1lbnQKLQkJICAgICAgICBjdXJyT3B0SW5kZXggPSBpOwotCQkgICAgICAgIGJyZWFrOyAJCQkvLyBlbmQgb2Ygb3B0aW9ucyAKLQkJICAgIH0KLQkgIAl9Ci0JICAgIH0vLyBlbmQgb3B0aW9uIGRvZXMgbm90IHN0YXJ0IHdpdGggIi0iCi0JfSAvLyBlbmQgZm9yIGFyZ3MgbG9vcAotCi0gICAgICAgIC8vICBhdHRhY2ggYW4gaXRlcmF0b3IgdG8gbGlzdCBvZiBvcHRpb25zIAotCXRoZU9wdGlvbnNJdGVyYXRvciA9IHRoZU9wdGlvbnMubGlzdEl0ZXJhdG9yKCk7Ci0KLQkvLyBvcHRpb25zIGFyZSBkb25lLCBub3cgZmlsbCBvdXQgY21kIGFyZyBsaXN0IHdpdGggcmVtYWluaW5nIGFyZ3MKLQlmb3IoaW50IGk9Y3Vyck9wdEluZGV4OyBpPGFyZ3MubGVuZ3RoOyBpKyspewotCSAgICBTdHJpbmcgdG9rZW4gPSBhcmdzW2ldOwotCSAgICB0aGVDbWRBcmdzLmFkZCh0b2tlbik7Ci0JfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgKiBkZWJ1Z2dpbmcgcm91dGluZSB0byBwcmludCBvdXQgYWxsIG9wdGlvbnMgY29sbGVjdGVkCi0gICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludE9wdGlvbnMoKXsKLQlmb3IoTGlzdEl0ZXJhdG9yIGl0PXRoZU9wdGlvbnMubGlzdEl0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspewotCSAgICBPcHRpb24gb3B0ID0gKE9wdGlvbilpdC5uZXh0KCk7Ci0JICAgIFN5c3RlbS5vdXQucHJpbnQoIk9QVCA9IiArIG9wdC5nZXRBcmdMZXR0ZXIoKSk7Ci0JICAgIFN0cmluZyBhcmcgPSBvcHQuZ2V0QXJndW1lbnQoKTsKLQkgICAgaWYoYXJnICE9IG51bGwpewotCSAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgIiArIGFyZyk7Ci0JICAgIH0KLQkgICAgU3lzdGVtLm91dC5wcmludGxuKCk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICogZ2V0cyB0aGUgbmV4dCBvcHRpb24gZm91bmQgaW4gdGhlIGNvbW1hbmRsaW5lLiBEaXN0aW5ndWlzaGVzCi0gICAgKiBiZXR3ZWVuIHR3byBiYWQgY2FzZXMsIG9uZSBjYXNlIGlzIHdoZW4gYW4gaWxsZWdhbCBvcHRpb24KLSAgICAqIGlzIGZvdW5kLCBhbmQgdGhlbiBvdGhlciBjYXNlIGlzIHdoZW4gYW4gb3B0aW9uIHRha2VzIGFuCi0gICAgKiBhcmd1bWVudCBidXQgbm8gYXJndW1lbnQgd2FzIGZvdW5kIGZvciB0aGF0IG9wdGlvbi4KLSAgICAqIElmIHRoZSBvcHRpb24gZm91bmQgd2FzIG5vdCBkZWNsYXJlZCBpbiB0aGUgb3B0U3RyaW5nLCB0aGVuIAotICAgICogYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIChjYXNlIDEpLiAKLSAgICAqIElmIHRoZSBuZXh0IG9wdGlvbiBmb3VuZCBoYXMgYmVlbiBkZWNsYXJlZCB0byB0YWtlIGFuIGFyZ3VtZW50LCAKLSAgICAqIGFuZCBubyBzdWNoIGFyZ3VtZW50IGV4aXN0cywgdGhlbiBhIE1pc3NpbmdPcHRBcmdFeGNlcHRpb24KLSAgICAqIGlzIHRocm93biAoY2FzZSAyKS4KLSAgICAqIEBwYXJhbSBub25lCi0gICAgKiBAcmV0dXJuIGludCAtIHRoZSBuZXh0IG9wdGlvbiBmb3VuZC4KLSAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uLiAKLSAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dE9wdGlvbigpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIAotCU1pc3NpbmdPcHRBcmdFeGNlcHRpb24KLSAgICB7Ci0JaW50IHJldHZhbCA9IC0xOwotCWlmKHRoZU9wdGlvbnNJdGVyYXRvci5oYXNOZXh0KCkpewotCSAgICB0aGVDdXJyZW50T3B0aW9uID0gKE9wdGlvbil0aGVPcHRpb25zSXRlcmF0b3IubmV4dCgpOwotCSAgICBjaGFyIGMgPSB0aGVDdXJyZW50T3B0aW9uLmdldEFyZ0xldHRlcigpOwotCSAgICBib29sZWFuIHNob3VsZEhhdmVBcmcgPSB0aGVPcHRpb25NYXRjaGVyLmhhc0FyZyhjKTsKLQkgICAgU3RyaW5nIGFyZyA9IHRoZUN1cnJlbnRPcHRpb24uZ2V0QXJndW1lbnQoKTsKLQkgICAgaWYoIXRoZU9wdGlvbk1hdGNoZXIubWF0Y2goYykpewotCQl0aHJvdyAobmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiT3B0aW9uICIgKwotCQkJYyArICIgaXMgbm90IHZhbGlkLiIpKTsKLQkgICAgfQotCSAgICBlbHNlIGlmKHNob3VsZEhhdmVBcmcgJiYgKGFyZyA9PSBudWxsKSl7Ci0JCXRocm93IChuZXcgTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbigiT3B0aW9uICIgKyAKLQkJCWMgKyAiIGlzIG1pc3NpbmcgaXRzIGFyZ3VtZW50LiIpKTsKLQkgICAgfQotCSAgICByZXR2YWwgPSBjOwotCX0KLQlyZXR1cm4gcmV0dmFsOwotICAgIH0KLQotICAgIC8qKgotICAgICogZ2V0cyB0aGUgYXJndW1lbnQgZm9yIHRoZSBjdXJyZW50IHBhcnNlZCBvcHRpb24uIEZvciBleGFtcGxlLAotICAgICogaW4gY2FzZSBvZiAnLWQgPGZpbGU+JywgaWYgY3VycmVudCBvcHRpb24gcGFyc2VkIGlzICdkJyB0aGVuCi0gICAgKiBnZXRPcHRpb25BcmcoKSB3b3VsZCByZXR1cm4gJzxmaWxlPicuCi0gICAgKiBAcGFyYW0gbm9uZQotICAgICogQHJldHVybiBTdHJpbmcgLSBhcmd1bWVudCBmb3IgY3VycmVudCBwYXJzZWQgb3B0aW9uLgotICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRPcHRpb25BcmcoKXsKLQlTdHJpbmcgcmV0dmFsID0gbnVsbDsKLQlTdHJpbmcgdG1wID0gdGhlQ3VycmVudE9wdGlvbi5nZXRBcmd1bWVudCgpOwotCWNoYXIgYyA9IHRoZUN1cnJlbnRPcHRpb24uZ2V0QXJnTGV0dGVyKCk7Ci0JaWYodGhlT3B0aW9uTWF0Y2hlci5oYXNBcmcoYykpewotCSAgICByZXR2YWwgPSB0bXA7Ci0JfQotCXJldHVybiByZXR2YWw7CQotICAgIH0KLQotICAgIC8qKgotICAgICogZ2V0cyBsaXN0IG9mIHRoZSBjb21tYW5kbGluZSBhcmd1bWVudHMuIEZvciBleGFtcGxlLCBpbiBjb21tYW5kCi0gICAgKiBzdWNoIGFzICdjbWQgLXMgLWQgZmlsZSBmaWxlMiBmaWxlMyBmaWxlNCcgIHdpdGggdGhlIHVzYWdlCi0gICAgKiAnY21kIFstc10gWy1kIDxmaWxlPl0gPGZpbGU+Li4uJywgZ2V0Q21kQXJncygpIHdvdWxkIHJldHVybgotICAgICogdGhlIGxpc3Qge2ZpbGUyLCBmaWxlMywgZmlsZTR9LgotICAgICogQHBhcmFtcyBub25lCi0gICAgKiBAcmV0dXJuIFN0cmluZ1tdIC0gbGlzdCBvZiBjb21tYW5kIGFyZ3VtZW50cyB0aGF0IG1heSBhcHBlYXIKLSAgICAqICAgICAgICAgICAgICAgICAgICBhZnRlciBvcHRpb25zIGFuZCBvcHRpb24gYXJndW1lbnRzLgotICAgICovCi0gICAgcHVibGljIFN0cmluZ1tdIGdldENtZEFyZ3MoKXsKLQlTdHJpbmdbXSByZXR2YWwgPSBuZXcgU3RyaW5nW3RoZUNtZEFyZ3Muc2l6ZSgpXTsKLQlpbnQgaT0wOwotICAgICAgICBmb3IoTGlzdEl0ZXJhdG9yIGl0PXRoZUNtZEFyZ3MubGlzdEl0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspewotICAgICAgICAgICAgcmV0dmFsW2krK10gPSAoU3RyaW5nKWl0Lm5leHQoKTsKLSAgICAgICAgfQotCXJldHVybiByZXR2YWw7Ci0gICAgfQotCi0KLSAgICBwcml2YXRlIE9wdGlvbiB0aGVDdXJyZW50T3B0aW9uID0gbnVsbDsKLSAgICBwcml2YXRlIExpc3RJdGVyYXRvciB0aGVPcHRpb25zSXRlcmF0b3I7IAotICAgIHByaXZhdGUgTGlzdCB0aGVPcHRpb25zID0gbnVsbDsKLSAgICBwcml2YXRlIExpc3QgdGhlQ21kQXJncyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBPcHRpb25NYXRjaGVyIHRoZU9wdGlvbk1hdGNoZXIgPSBudWxsOwotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLwotICAgIC8vICAgSW5uZXIgQ2xhc3NlcwotICAgIC8vCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAgIC8vIGlubmVyIGNsYXNzIHRvIG1vZGVsIGFuIG9wdGlvbgotICAgIGNsYXNzIE9wdGlvbnsKLSAgICAgICAgcHJpdmF0ZSBjaGFyIHRoZUFyZ0xldHRlcjsKLSAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdGhlQXJndW1lbnQgPSBudWxsOwotICAgICAgICBwdWJsaWMgT3B0aW9uKGNoYXIgYXJnTGV0dGVyKSB7IHRoZUFyZ0xldHRlciA9IGFyZ0xldHRlcjsgfQotICAgICAgICBwdWJsaWMgdm9pZCBzZXRBcmcoU3RyaW5nIGFyZykgeyAKLQkgICAgdGhlQXJndW1lbnQgPSBhcmc7Ci0gICAgICAgIH0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQXJnKCkgeyByZXR1cm4gKHRoZUFyZ3VtZW50ICE9IG51bGwpOyB9IAotICAgICAgICBwdWJsaWMgY2hhciBnZXRBcmdMZXR0ZXIoKSB7IHJldHVybiB0aGVBcmdMZXR0ZXI7IH0KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRBcmd1bWVudCgpIHsgcmV0dXJuIHRoZUFyZ3VtZW50OyB9Ci0gICAgfSAvLyBlbmQgY2xhc3MgT3B0aW9uCi0KLQotICAgIC8vIGlubmVyIGNsYXNzIHRvIHF1ZXJ5IG9wdFN0cmluZyBmb3IgYSBwb3NzaWJsZSBvcHRpb24gbWF0Y2gsCi0gICAgLy8gYW5kIHdoZXRoZXIgb3Igbm90IGEgZ2l2ZW4gbGVnYWwgb3B0aW9uIHRha2VzIGFuIGFyZ3VtZW50LiAKLSAgICAvLyAgCi0gICAgY2xhc3MgT3B0aW9uTWF0Y2hlcnsKLSAgICAgICAgcHVibGljIE9wdGlvbk1hdGNoZXIoU3RyaW5nIG9wdFN0cmluZyl7Ci0JICAgIHRoZU9wdFN0cmluZyA9IG9wdFN0cmluZzsJCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goY2hhciBjKXsKLQkgICAgYm9vbGVhbiByZXR2YWwgPSBmYWxzZTsKLQkgICAgaWYodGhlT3B0U3RyaW5nLmluZGV4T2YoYykgIT0gLTEpewotCSAgICAgICAgcmV0dmFsID0gdHJ1ZTsKLQkgICAgfQotCSAgICByZXR1cm4gcmV0dmFsOwkKLSAgICAgICAgfQotICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBcmcoY2hhciBjKXsKLQkgICAgYm9vbGVhbiByZXR2YWwgPSBmYWxzZTsKLQkgICAgaW50IGluZGV4ID0gdGhlT3B0U3RyaW5nLmluZGV4T2YoYykrMTsgCi0JICAgIGlmIChpbmRleCA9PSB0aGVPcHRTdHJpbmcubGVuZ3RoKCkpewotCSAgICAgICAgLy8gcmVhY2hlZCBlbmQgb2YgdGhlT3B0U3RyaW5nCi0JICAgICAgICByZXR2YWwgPSBmYWxzZTsKLQkgICAgfQotICAgICAgICAgICAgZWxzZSBpZih0aGVPcHRTdHJpbmcuY2hhckF0KGluZGV4KSA9PSAnOicpewotICAgICAgICAgICAgICAgIHJldHZhbCA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gcmV0dmFsOwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgU3RyaW5nIHRoZU9wdFN0cmluZyA9IG51bGw7Ci0gICAgfSAvLyBlbmQgY2xhc3MgT3B0aW9uTWF0Y2hlcgotfS8vIGVuZCBjbGFzcyBHZXRPcHQKLSAgICAKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0dldE9wdHNFeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0dldE9wdHNFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTMyM2Y2Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lL2dldG9wdC9HZXRPcHRzRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OCArMCwwIEBACi0vKgotICogJElkJCAKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEcgVG9kZCBNaWxsZXIgCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNtZGxpbmUuZ2V0b3B0OyAKLQotcHVibGljIGNsYXNzIEdldE9wdHNFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb257Ci0gICAgcHVibGljIEdldE9wdHNFeGNlcHRpb24oU3RyaW5nIG1zZyl7Ci0Jc3VwZXIobXNnKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lL2dldG9wdC9JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMDFkMWNlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotLyoKLSAqICRJZCQgCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jbWRsaW5lLmdldG9wdDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY21kbGluZS5nZXRvcHQuR2V0T3B0c0V4Y2VwdGlvbjsKLQotY2xhc3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4dGVuZHMgR2V0T3B0c0V4Y2VwdGlvbnsKLSAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFN0cmluZyBtc2cpewotCXN1cGVyKG1zZyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY21kbGluZS9nZXRvcHQvTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY21kbGluZS9nZXRvcHQvTWlzc2luZ09wdEFyZ0V4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4Njg3YmE2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUvZ2V0b3B0L01pc3NpbmdPcHRBcmdFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiAkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBHIFRvZGQgTWlsbGVyIAotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jbWRsaW5lLmdldG9wdDsgCi0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNtZGxpbmUuZ2V0b3B0LkdldE9wdHNFeGNlcHRpb247Ci0KLWNsYXNzIE1pc3NpbmdPcHRBcmdFeGNlcHRpb24gZXh0ZW5kcyBHZXRPcHRzRXhjZXB0aW9uewotICAgIHB1YmxpYyBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uKFN0cmluZyBtc2cpewotCXN1cGVyKG1zZyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Fic29sdXRlTG9jYXRpb25QYXRoLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY4YTRiM2YuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEFic29sdXRlTG9jYXRpb25QYXRoIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9wYXRoOwkvLyBtYXkgYmUgbnVsbCAKLQotICAgIHB1YmxpYyBBYnNvbHV0ZUxvY2F0aW9uUGF0aCgpIHsKLQlfcGF0aCA9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIEFic29sdXRlTG9jYXRpb25QYXRoKEV4cHJlc3Npb24gcGF0aCkgewotCV9wYXRoID0gcGF0aDsKLQlpZiAocGF0aCAhPSBudWxsKSB7Ci0JICAgIF9wYXRoLnNldFBhcmVudCh0aGlzKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlpZiAoX3BhdGggIT0gbnVsbCkgewotCSAgICBfcGF0aC5zZXRQYXJzZXIocGFyc2VyKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0UGF0aCgpIHsKLQlyZXR1cm4oX3BhdGgpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAiQWJzb2x1dGVMb2NhdGlvblBhdGgoIiArCi0JICAgIChfcGF0aCAhPSBudWxsID8gX3BhdGgudG9TdHJpbmcoKSA6ICJudWxsIikgKyAnKSc7Ci0gICAgfQotCQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKF9wYXRoICE9IG51bGwpIHsKLQkgICAgZmluYWwgVHlwZSBwdHlwZSA9IF9wYXRoLnR5cGVDaGVjayhzdGFibGUpOwotCSAgICBpZiAocHR5cGUgaW5zdGFuY2VvZiBOb2RlVHlwZSkgewkJLy8gcHJvbW90ZSB0byBub2RlLXNldAotCQlfcGF0aCA9IG5ldyBDYXN0RXhwcihfcGF0aCwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCX0KLQlyZXR1cm4gX3R5cGUgPSBUeXBlLk5vZGVTZXQ7CQotICAgIH0KLQkKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlmIChfcGF0aCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBpbml0QUkgPSBjcGcuYWRkTWV0aG9kcmVmKEFCU09MVVRFX0lURVJBVE9SLAotCQkJCQkJIjxpbml0PiIsCi0JCQkJCQkiKCIKLQkJCQkJCSsgTk9ERV9JVEVSQVRPUl9TSUcKLQkJCQkJCSsgIilWIik7Ci0JICAgIC8vIENyZWF0ZSBuZXcgQWJzb2x1dGVJdGVyYXRvcgotCSAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoQUJTT0xVVEVfSVRFUkFUT1IpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCi0JICAgIC8vIENvbXBpbGUgcmVsYXRpdmUgcGF0aCBpdGVyYXRvcihzKQotCSAgICBfcGF0aC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgLy8gSW5pdGlhbGl6ZSBBYnNvbHV0ZUl0ZXJhdG9yIHdpdGggaXRlcmF0b3IgZnJvbSB0aGUgc3RhY2sKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRBSSkpOwotCX0KLQllbHNlIHsKLQkgICAgZmluYWwgaW50IGdpdHIgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAgICJnZXRJdGVyYXRvciIsCi0JCQkJCQkgICAgICAgIigpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0ciwgMSkpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BYnNvbHV0ZVBhdGhQYXR0ZXJuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BYnNvbHV0ZVBhdGhQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdjNzcwOTIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQWJzb2x1dGVQYXRoUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBBYnNvbHV0ZVBhdGhQYXR0ZXJuIGV4dGVuZHMgTG9jYXRpb25QYXRoUGF0dGVybiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIF9sZWZ0OyAvLyBtYXkgYmUgbnVsbAotCi0gICAgcHVibGljIEFic29sdXRlUGF0aFBhdHRlcm4oUmVsYXRpdmVQYXRoUGF0dGVybiBsZWZ0KSB7Ci0JX2xlZnQgPSBsZWZ0OwotCWlmIChsZWZ0ICE9IG51bGwpIHsKLQkgICAgbGVmdC5zZXRQYXJlbnQodGhpcyk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JaWYgKF9sZWZ0ICE9IG51bGwpCi0JICAgIF9sZWZ0LnNldFBhcnNlcihwYXJzZXIpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCXJldHVybiBfbGVmdCA9PSBudWxsID8gVHlwZS5Sb290IDogX2xlZnQudHlwZUNoZWNrKHN0YWJsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZCgpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCkgewotCXJldHVybiBfbGVmdCAhPSBudWxsID8gX2xlZnQuZ2V0S2VybmVsUGF0dGVybigpIDogbnVsbDsKLSAgICB9Ci0JCi0gICAgcHVibGljIHZvaWQgcmVkdWNlS2VybmVsUGF0dGVybigpIHsKLQlfbGVmdC5yZWR1Y2VLZXJuZWxQYXR0ZXJuKCk7Ci0gICAgfQotCQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlpZiAoX2xlZnQgIT0gbnVsbCkgewotCSAgICBpZiAoX2xlZnQgaW5zdGFuY2VvZiBTdGVwUGF0dGVybikgewotCQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIGxvY2FsID0gCi0JCSAgICAvLyBhYnNvbHV0ZSBwYXRoIHBhdHRlcm4gdGVtcG9yYXJ5Ci0JCSAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZTIoImFwcHRtcCIsIAotCQkJCQkJVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9TSUcpLAotCQkJCQkJaWwuZ2V0RW5kKCkpOwotCQlpbC5hcHBlbmQoRFVQKTsKLQkJaWwuYXBwZW5kKG5ldyBJU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSkpOwotCQlfbGVmdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkJbG9jYWwuc2V0RW5kKGlsLmFwcGVuZChuZXcgSUxPQUQobG9jYWwuZ2V0SW5kZXgoKSkpKTsKLQkJbWV0aG9kR2VuLnJlbW92ZUxvY2FsVmFyaWFibGUobG9jYWwpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlfbGVmdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQkgICAgX3RydWVMaXN0LmFwcGVuZChfbGVmdC5fdHJ1ZUxpc3QpOwotCSAgICBfZmFsc2VMaXN0LmFwcGVuZChfbGVmdC5fZmFsc2VMaXN0KTsKLQl9Ci0JZmluYWwgaW50IGdldFBhcmVudCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkJR0VUX1BBUkVOVCwKLQkJCQkJCQlHRVRfUEFSRU5UX1NJRyk7Ci0JZmluYWwgaW50IGdldFR5cGUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAgImdldFR5cGUiLCAiKEkpSSIpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQoU1dBUCk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0UGFyZW50LCAyKSk7Ci0JaWYgKF9sZWZ0IGluc3RhbmNlb2YgQW5jZXN0b3JQYXR0ZXJuKSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKFNXQVApOwotCX0KLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXRUeXBlLCAyKSk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRE9NLlJPT1QpKTsKLQlfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGX0lDTVBORShudWxsKSkpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAiYWJzb2x1dGVQYXRoUGF0dGVybigiICsgKF9sZWZ0IT1udWxsID8gX2xlZnQudG9TdHJpbmcoKSA6ICIpIik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQWx0ZXJuYXRpdmVQYXR0ZXJuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BbHRlcm5hdGl2ZVBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzNkOTE3Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BbHRlcm5hdGl2ZVBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEFsdGVybmF0aXZlUGF0dGVybiBleHRlbmRzIFBhdHRlcm4gewotICAgIHByaXZhdGUgZmluYWwgUGF0dGVybiBfbGVmdDsKLSAgICBwcml2YXRlIGZpbmFsIFBhdHRlcm4gX3JpZ2h0OwotCQkKLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYW4gYWx0ZXJuYXRpdmUgcGF0dGVybi4gVGhlIG1ldGhvZCA8Y29kZT5zZXRQYXJlbnQ8L2NvZGU+Ci0gICAgICogc2hvdWxkIG5vdCBiZSBjYWxsZWQgaW4gdGhpcyBjYXNlLgotICAgICAqLwotICAgIHB1YmxpYyBBbHRlcm5hdGl2ZVBhdHRlcm4oUGF0dGVybiBsZWZ0LCBQYXR0ZXJuIHJpZ2h0KSB7Ci0JX2xlZnQgPSBsZWZ0OwotCV9yaWdodCA9IHJpZ2h0OwotICAgIH0KLQkJCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlfbGVmdC5zZXRQYXJzZXIocGFyc2VyKTsKLQlfcmlnaHQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBQYXR0ZXJuIGdldExlZnQoKSB7Ci0JcmV0dXJuIF9sZWZ0OwotICAgIH0KLQotICAgIHB1YmxpYyBQYXR0ZXJuIGdldFJpZ2h0KCkgewotCXJldHVybiBfcmlnaHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIHR5cGUgb2YgYW4gJ3wnIGlzIG5vdCByZWFsbHkgZGVmaW5lZCwgaGVuY2UgbnVsbCBpcyByZXR1cm5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCV9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOwotCV9yaWdodC50eXBlQ2hlY2soc3RhYmxlKTsKLQlyZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZG91YmxlIGdldFByaW9yaXR5KCkgewotCWRvdWJsZSBsZWZ0ID0gX2xlZnQuZ2V0UHJpb3JpdHkoKTsKLQlkb3VibGUgcmlnaHQgPSBfcmlnaHQuZ2V0UHJpb3JpdHkoKTsKLQkKLQlpZiAobGVmdCA8IHJpZ2h0KQotCSAgICByZXR1cm4obGVmdCk7Ci0JZWxzZQotCSAgICByZXR1cm4ocmlnaHQpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJhbHRlcm5hdGl2ZSgiICsgX2xlZnQgKyAiLCAiICsgX3JpZ2h0ICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCV9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBnb3RvdCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCV9sZWZ0Ll90cnVlTGlzdC5iYWNrUGF0Y2goZ290b3QpOwotCV9sZWZ0Ll9mYWxzZUxpc3QuYmFja1BhdGNoKGdvdG90LmdldE5leHQoKSk7Ci0KLQlfdHJ1ZUxpc3QuYXBwZW5kKF9yaWdodC5fdHJ1ZUxpc3QuYWRkKGdvdG90KSk7Ci0JX2ZhbHNlTGlzdC5hcHBlbmQoX3JpZ2h0Ll9mYWxzZUxpc3QpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0FuY2VzdG9yUGF0dGVybi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQW5jZXN0b3JQYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwNGYwYzAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQW5jZXN0b3JQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBBbmNlc3RvclBhdHRlcm4gZXh0ZW5kcyBSZWxhdGl2ZVBhdGhQYXR0ZXJuIHsKLSAgICBwcml2YXRlIGZpbmFsIFBhdHRlcm4gX2xlZnQ7CS8vIG1heSBiZSBudWxsCi0gICAgcHJpdmF0ZSBmaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIF9yaWdodDsKLQkJCi0gICAgcHVibGljIEFuY2VzdG9yUGF0dGVybihSZWxhdGl2ZVBhdGhQYXR0ZXJuIHJpZ2h0KSB7Ci0JdGhpcyhudWxsLCByaWdodCk7Ci0gICAgfQotCi0gICAgcHVibGljIEFuY2VzdG9yUGF0dGVybihQYXR0ZXJuIGxlZnQsIFJlbGF0aXZlUGF0aFBhdHRlcm4gcmlnaHQpIHsKLQlfbGVmdCA9IGxlZnQ7Ci0JKF9yaWdodCA9IHJpZ2h0KS5zZXRQYXJlbnQodGhpcyk7Ci0JaWYgKGxlZnQgIT0gbnVsbCkgewotCSAgICBsZWZ0LnNldFBhcmVudCh0aGlzKTsKLQl9Ci0gICAgfQotCQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JaWYgKF9sZWZ0ICE9IG51bGwpIHsKLQkgICAgX2xlZnQuc2V0UGFyc2VyKHBhcnNlcik7Ci0JfQotCV9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZCgpIHsKLQkvLyEhISBjYW4gYmUgd2lsZGNhcmQKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCkgewotCXJldHVybiBfcmlnaHQuZ2V0S2VybmVsUGF0dGVybigpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlZHVjZUtlcm5lbFBhdHRlcm4oKSB7Ci0JX3JpZ2h0LnJlZHVjZUtlcm5lbFBhdHRlcm4oKTsKLSAgICB9Ci0JCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoX2xlZnQgIT0gbnVsbCkgX2xlZnQudHlwZUNoZWNrKHN0YWJsZSk7Ci0JcmV0dXJuIF9yaWdodC50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlJbnN0cnVjdGlvbkhhbmRsZSBsb29wLCBlbG9vcDsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIExvY2FsVmFyaWFibGVHZW4gbG9jYWwgPQotCSAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZTIoImFwcCIsIAotCQkJCQlVdGlsLmdldEpDUmVmVHlwZShOT0RFX1NJRyksCi0JCQkJCWlsLmdldEVuZCgpKTsKLQotCWZpbmFsIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLkluc3RydWN0aW9uIGxvYWRMb2NhbCA9Ci0JICAgIG5ldyBJTE9BRChsb2NhbC5nZXRJbmRleCgpKTsKLQlmaW5hbCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBzdG9yZUxvY2FsID0KLQkgICAgbmV3IElTVE9SRShsb2NhbC5nZXRJbmRleCgpKTsKLQotCWlmIChfcmlnaHQgaW5zdGFuY2VvZiBTdGVwUGF0dGVybikgewotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKHN0b3JlTG9jYWwpOwotCSAgICBfcmlnaHQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGlsLmFwcGVuZChsb2FkTG9jYWwpOwotCX0KLQllbHNlIHsKLQkgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0KLQlpZiAoX2xlZnQgIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgZ2V0UGFyZW50ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCQkgICAgR0VUX1BBUkVOVCwKLQkJCQkJCQkgICAgR0VUX1BBUkVOVF9TSUcpOwotCSAgICBsb29wID0gaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0UGFyZW50LCAyKSk7Ci0JICAgIAotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKHN0b3JlTG9jYWwpOwotCSAgICBfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpKTsKLQkgICAgaWwuYXBwZW5kKGxvYWRMb2NhbCk7Ci0KLQkgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0KLQkgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcCA9IGdldFBhcmVudCgpOwotCSAgICBpZiAoKHAgPT0gbnVsbCkgfHwgCi0JCShwIGluc3RhbmNlb2YgSW5zdHJ1Y3Rpb24pIHx8Ci0JCShwIGluc3RhbmNlb2YgVG9wTGV2ZWxFbGVtZW50KSkgewotCQkvLyBkbyBub3RoaW5nCi0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWlsLmFwcGVuZChsb2FkTG9jYWwpOwotCSAgICB9Ci0KLQkgICAgZmluYWwgQnJhbmNoSGFuZGxlIGV4aXQgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCSAgICBlbG9vcCA9IGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKGxvYWRMb2NhbCk7Ci0JICAgIGxvY2FsLnNldEVuZChlbG9vcCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgR09UTyhsb29wKSk7Ci0JICAgIGV4aXQuc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLQkgICAgX2xlZnQuYmFja1BhdGNoRmFsc2VMaXN0KGVsb29wKTsKLQotCSAgICBfdHJ1ZUxpc3QuYXBwZW5kKF9sZWZ0Ll90cnVlTGlzdCk7CQotCX0KLQllbHNlIHsKLQkgICAgaWwuYXBwZW5kKFBPUDIpOwotCX0KLQltZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShsb2NhbCk7Ci0KLQlfdHJ1ZUxpc3QuYXBwZW5kKF9yaWdodC5fdHJ1ZUxpc3QpOwotCV9mYWxzZUxpc3QuYXBwZW5kKF9yaWdodC5fZmFsc2VMaXN0KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAiQW5jZXN0b3JQYXR0ZXJuKCIgKyBfbGVmdCArICIsICIgKyBfcmlnaHQgKyAnKSc7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQXBwbHlJbXBvcnRzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BcHBseUltcG9ydHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTA4ZjZhNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BcHBseUltcG9ydHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxMCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEFwcGx5SW1wb3J0cyBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfc2VsZWN0OwotICAgIHByaXZhdGUgUU5hbWUgICAgICBfbW9kZU5hbWU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgIF9mdW5jdGlvbk5hbWU7Ci0JCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0JaW5kZW50KGluZGVudCk7Ci0JVXRpbC5wcmludGxuKCJBcHBseVRlbXBsYXRlcyIpOwotCWluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCVV0aWwucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotCWlmIChfbW9kZU5hbWUgIT0gbnVsbCkgewotCSAgICBpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQkgICAgVXRpbC5wcmludGxuKCJtb2RlICIgKyBfbW9kZU5hbWUpOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNXaXRoUGFyYW1zKCkgewotCXJldHVybiBoYXNDb250ZW50cygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCWZpbmFsIFN0cmluZyBzZWxlY3QgPSBnZXRBdHRyaWJ1dGUoInNlbGVjdCIpOwotCWZpbmFsIFN0cmluZyBtb2RlICAgPSBnZXRBdHRyaWJ1dGUoIm1vZGUiKTsKLQkKLQlpZiAoc2VsZWN0Lmxlbmd0aCgpID4gMCkgewotCSAgICBfc2VsZWN0ID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCAic2VsZWN0IiwgbnVsbCk7Ci0JfQotCQotCWlmIChtb2RlLmxlbmd0aCgpID4gMCkgewotCSAgICBfbW9kZU5hbWUgPSBwYXJzZXIuZ2V0UU5hbWUobW9kZSk7Ci0JfQotCQotCS8vIGluc3RhbnRpYXRlIE1vZGUgaWYgbmVlZGVkLCBjYWNoZSAoYXBwbHkgdGVtcCkgZnVuY3Rpb24gbmFtZQotCV9mdW5jdGlvbk5hbWUgPQotCSAgICBwYXJzZXIuZ2V0VG9wTGV2ZWxTdHlsZXNoZWV0KCkuZ2V0TW9kZShfbW9kZU5hbWUpLmZ1bmN0aW9uTmFtZSgpOwotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsJLy8gd2l0aC1wYXJhbXMKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWlmIChfc2VsZWN0ICE9IG51bGwpIHsKLQkgICAgVHlwZSB0c2VsZWN0ID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLQkgICAgaWYgKHRzZWxlY3QgaW5zdGFuY2VvZiBOb2RlVHlwZSB8fAotCQl0c2VsZWN0IGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgewotCQlfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuTm9kZVNldCk7Ci0JCXRzZWxlY3QgPSBUeXBlLk5vZGVTZXQ7Ci0JICAgIH0KLQkgICAgaWYgKHRzZWxlY3QgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSkgewotCQl0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwkJLy8gd2l0aC1wYXJhbXMKLQkJcmV0dXJuIFR5cGUuVm9pZDsKLQkgICAgfSAKLQkgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotCX0KLQllbHNlIHsKLQkgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsJCS8vIHdpdGgtcGFyYW1zCi0JICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBjYWxsLXRlbXBsYXRlLiBBIHBhcmFtZXRlciBmcmFtZSBpcyBwdXNoZWQgb25seSBpZgotICAgICAqIHNvbWUgdGVtcGxhdGUgaW4gdGhlIHN0eWxlc2hlZXQgdXNlcyBwYXJhbWV0ZXJzLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBTdHlsZXNoZWV0IHN0eWxlc2hlZXQgPSBjbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCk7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBpbnQgY3VycmVudCA9IG1ldGhvZEdlbi5nZXRMb2NhbEluZGV4KCJjdXJyZW50Iik7Ci0KLQkvLyBjaGVjayBpZiBzb3J0aW5nIG5vZGVzIGlzIHJlcXVpcmVkCi0JZmluYWwgVmVjdG9yIHNvcnRPYmplY3RzID0gbmV3IFZlY3RvcigpOwotCWZpbmFsIEVudW1lcmF0aW9uIGNoaWxkcmVuID0gZWxlbWVudHMoKTsKLQl3aGlsZSAoY2hpbGRyZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgT2JqZWN0IGNoaWxkID0gY2hpbGRyZW4ubmV4dEVsZW1lbnQoKTsKLQkgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgU29ydCkgewotCQlzb3J0T2JqZWN0cy5hZGRFbGVtZW50KGNoaWxkKTsKLQkgICAgfQotCX0KLQkKLQkvLyBQdXNoIGEgbmV3IHBhcmFtZXRlciBmcmFtZQotCWlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkpIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgZmluYWwgaW50IHB1c2hGcmFtZSA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkgICBQVVNIX1BBUkFNX0ZSQU1FLAotCQkJCQkJICAgUFVTSF9QQVJBTV9GUkFNRV9TSUcpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwocHVzaEZyYW1lKSk7Ci0JICAgIC8vIHRyYW5zbGF0ZSB3aXRoLXBhcmFtcwotCSAgICB0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0KLQkvLyBwdXNoIGFyZ3VtZW50cyBmb3IgZmluYWwgY2FsbCB0byBhcHBseVRlbXBsYXRlcwotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCQkKLQkvLyBjb21wdXRlIG5vZGUgaXRlcmF0b3IgZm9yIGFwcGx5VGVtcGxhdGVzCi0JaWYgKHNvcnRPYmplY3RzLnNpemUoKSA+IDApIHsKLQkgICAgU29ydC50cmFuc2xhdGVTb3J0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkgICAgICAgX3NlbGVjdCwgc29ydE9iamVjdHMpOwotCX0KLQllbHNlIHsKLQkgICAgaWYgKF9zZWxlY3QgPT0gbnVsbCkgewotCQlNb2RlLmNvbXBpbGVHZXRDaGlsZHJlbihjbGFzc0dlbiwgbWV0aG9kR2VuLCBjdXJyZW50KTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX3NlbGVjdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQl9Ci0JaWYgKF9zZWxlY3QgIT0gbnVsbCkgewotCSAgICBfc2VsZWN0LnN0YXJ0UmVzZXRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JCi0JLy8hISEgbmVlZCB0byBpbnN0YW50aWF0ZSBhbGwgbmVlZGVkIG1vZGVzCi0JZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldFN0eWxlc2hlZXQoKS5nZXRDbGFzc05hbWUoKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCWZpbmFsIFN0cmluZyBhcHBseVRlbXBsYXRlc1NpZyA9IGNsYXNzR2VuLmdldEFwcGx5VGVtcGxhdGVzU2lnKCk7Ci0JZmluYWwgaW50IGFwcGx5VGVtcGxhdGVzID0gY3BnLmFkZE1ldGhvZHJlZihjbGFzc05hbWUsCi0JCQkJCQkgICAgX2Z1bmN0aW9uTmFtZSwKLQkJCQkJCSAgICBhcHBseVRlbXBsYXRlc1NpZyk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGFwcGx5VGVtcGxhdGVzKSk7Ci0JCi0JLy8gUG9wIHBhcmFtZXRlciBmcmFtZQotCWlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkpIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgZmluYWwgaW50IHBvcEZyYW1lID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCSAgUE9QX1BBUkFNX0ZSQU1FLAotCQkJCQkJICBQT1BfUEFSQU1fRlJBTUVfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHBvcEZyYW1lKSk7Ci0JfQotICAgIH0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BcHBseVRlbXBsYXRlcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQXBwbHlUZW1wbGF0ZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGI3NTUzNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BcHBseVRlbXBsYXRlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQXBwbHlUZW1wbGF0ZXMgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9zZWxlY3Q7Ci0gICAgcHJpdmF0ZSBUeXBlICAgICAgIF90eXBlID0gbnVsbDsKLSAgICBwcml2YXRlIFFOYW1lICAgICAgX21vZGVOYW1lOwotICAgIHByaXZhdGUgU3RyaW5nICAgICBfZnVuY3Rpb25OYW1lOwotCQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVV0aWwucHJpbnRsbigiQXBwbHlUZW1wbGF0ZXMiKTsKLQlpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQlVdGlsLnByaW50bG4oInNlbGVjdCAiICsgX3NlbGVjdC50b1N0cmluZygpKTsKLQlpZiAoX21vZGVOYW1lICE9IG51bGwpIHsKLQkgICAgaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0JICAgIFV0aWwucHJpbnRsbigibW9kZSAiICsgX21vZGVOYW1lKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaGFzV2l0aFBhcmFtcygpIHsKLQlyZXR1cm4gaGFzQ29udGVudHMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQlmaW5hbCBTdHJpbmcgc2VsZWN0ID0gZ2V0QXR0cmlidXRlKCJzZWxlY3QiKTsKLQlmaW5hbCBTdHJpbmcgbW9kZSAgID0gZ2V0QXR0cmlidXRlKCJtb2RlIik7Ci0JCi0JaWYgKHNlbGVjdC5sZW5ndGgoKSA+IDApIHsKLQkgICAgX3NlbGVjdCA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgInNlbGVjdCIsIG51bGwpOwotCX0KLQkKLQlpZiAobW9kZS5sZW5ndGgoKSA+IDApIHsKLQkgICAgX21vZGVOYW1lID0gcGFyc2VyLmdldFFOYW1lKG1vZGUpOwotCX0KLQkKLQkvLyBpbnN0YW50aWF0ZSBNb2RlIGlmIG5lZWRlZCwgY2FjaGUgKGFwcGx5IHRlbXApIGZ1bmN0aW9uIG5hbWUKLQlfZnVuY3Rpb25OYW1lID0KLQkgICAgcGFyc2VyLmdldFRvcExldmVsU3R5bGVzaGVldCgpLmdldE1vZGUoX21vZGVOYW1lKS5mdW5jdGlvbk5hbWUoKTsKLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ly8gd2l0aC1wYXJhbXMKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWlmIChfc2VsZWN0ICE9IG51bGwpIHsKLQkgICAgX3R5cGUgPSBfc2VsZWN0LnR5cGVDaGVjayhzdGFibGUpOwotCSAgICBpZiAoX3R5cGUgaW5zdGFuY2VvZiBOb2RlVHlwZSB8fCBfdHlwZSBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLQkJX3NlbGVjdCA9IG5ldyBDYXN0RXhwcihfc2VsZWN0LCBUeXBlLk5vZGVTZXQpOwotCQlfdHlwZSA9IFR5cGUuTm9kZVNldDsKLQkgICAgfQotCSAgICBpZiAoX3R5cGUgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZXx8X3R5cGUgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotCQl0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOyAvLyB3aXRoLXBhcmFtcwotCQlyZXR1cm4gVHlwZS5Wb2lkOwotCSAgICB9Ci0JICAgIFN0cmluZyBtc2cgPSAiVW5zdXBwb3J0ZWQgdHlwZSBmb3IgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSciKwotCQlfdHlwZSsiJy8+IjsKLQkgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKG5ldyBFcnJvck1zZyhtc2cpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7CQkvLyB3aXRoLXBhcmFtcwotCSAgICByZXR1cm4gVHlwZS5Wb2lkOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgY2FsbC10ZW1wbGF0ZS4gQSBwYXJhbWV0ZXIgZnJhbWUgaXMgcHVzaGVkIG9ubHkgaWYKLSAgICAgKiBzb21lIHRlbXBsYXRlIGluIHRoZSBzdHlsZXNoZWV0IHVzZXMgcGFyYW1ldGVycy4gCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpOwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgaW50IGN1cnJlbnQgPSBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpOwotCi0JLy8gY2hlY2sgaWYgc29ydGluZyBub2RlcyBpcyByZXF1aXJlZAotCWZpbmFsIFZlY3RvciBzb3J0T2JqZWN0cyA9IG5ldyBWZWN0b3IoKTsKLQlmaW5hbCBFbnVtZXJhdGlvbiBjaGlsZHJlbiA9IGVsZW1lbnRzKCk7Ci0Jd2hpbGUgKGNoaWxkcmVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIGZpbmFsIE9iamVjdCBjaGlsZCA9IGNoaWxkcmVuLm5leHRFbGVtZW50KCk7Ci0JICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFNvcnQpIHsKLQkJc29ydE9iamVjdHMuYWRkRWxlbWVudChjaGlsZCk7Ci0JICAgIH0KLQl9Ci0JCi0JLy8gUHVzaCBhIG5ldyBwYXJhbWV0ZXIgZnJhbWUKLQlpZiAoc3R5bGVzaGVldC5oYXNMb2NhbFBhcmFtcygpKSB7Ci0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGZpbmFsIGludCBwdXNoRnJhbWUgPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJICAgUFVTSF9QQVJBTV9GUkFNRSwKLQkJCQkJCSAgIFBVU0hfUEFSQU1fRlJBTUVfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHB1c2hGcmFtZSkpOwotCSAgICAvLyB0cmFuc2xhdGUgd2l0aC1wYXJhbXMKLQkgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQotCS8vIFRoZSAnc2VsZWN0JyBleHByZXNzaW9uIGlzIGEgcmVzdWx0LXRyZWUKLQlpZiAoKF90eXBlICE9IG51bGwpICYmIChfdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSkgewotCSAgICAvLyA8eHNsOnNvcnQ+IGNhbm5vdCBiZSBhcHBsaWVkIHRvIGEgcmVzdWx0IHRyZWUgLSBpc3N1ZSB3YXJuaW5nCi0JICAgIGlmIChzb3J0T2JqZWN0cy5zaXplKCkgPiAwKSB7Ci0JCUVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5UUkVFU09SVF9FUlIpOwotCQlnZXRQYXJzZXIoKS5yZXBvcnRFcnJvcihXQVJOSU5HLCBtc2cpOwotCSAgICB9Ci0JICAgIC8vIFB1dCB0aGUgcmVzdWx0IHRyZWUgKGEgRE9NIGFkYXB0ZXIpIG9uIHRoZSBzdGFjawotCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsJCi0JICAgIC8vIEdldCBiYWNrIHRoZSBET00gYW5kIGl0ZXJhdG9yIChub3QganVzdCBpdGVyYXRvciEhISkKLQkgICAgX3R5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQotCSAgICAvLyBjb21wdXRlIG5vZGUgaXRlcmF0b3IgZm9yIGFwcGx5VGVtcGxhdGVzCi0JICAgIGlmIChzb3J0T2JqZWN0cy5zaXplKCkgPiAwKSB7Ci0JCVNvcnQudHJhbnNsYXRlU29ydEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCSAgIF9zZWxlY3QsIHNvcnRPYmplY3RzKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJaWYgKF9zZWxlY3QgPT0gbnVsbCkKLQkJICAgIE1vZGUuY29tcGlsZUdldENoaWxkcmVuKGNsYXNzR2VuLCBtZXRob2RHZW4sIGN1cnJlbnQpOwotCQllbHNlCi0JCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgfQotCX0KLQotCWlmIChfc2VsZWN0ICE9IG51bGwpIHsKLQkgICAgX3NlbGVjdC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCi0JLy8hISEgbmVlZCB0byBpbnN0YW50aWF0ZSBhbGwgbmVlZGVkIG1vZGVzCi0JZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldFN0eWxlc2hlZXQoKS5nZXRDbGFzc05hbWUoKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCWZpbmFsIFN0cmluZyBhcHBseVRlbXBsYXRlc1NpZyA9IGNsYXNzR2VuLmdldEFwcGx5VGVtcGxhdGVzU2lnKCk7Ci0JZmluYWwgaW50IGFwcGx5VGVtcGxhdGVzID0gY3BnLmFkZE1ldGhvZHJlZihjbGFzc05hbWUsCi0JCQkJCQkgICAgX2Z1bmN0aW9uTmFtZSwKLQkJCQkJCSAgICBhcHBseVRlbXBsYXRlc1NpZyk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGFwcGx5VGVtcGxhdGVzKSk7Ci0JCi0JLy8gUG9wIHBhcmFtZXRlciBmcmFtZQotCWlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkpIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgZmluYWwgaW50IHBvcEZyYW1lID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCSAgUE9QX1BBUkFNX0ZSQU1FLAotCQkJCQkJICBQT1BfUEFSQU1fRlJBTUVfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHBvcEZyYW1lKSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0FyZ3VtZW50TGlzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQXJndW1lbnRMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY2ZjY3ZWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQXJndW1lbnRMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotZmluYWwgY2xhc3MgQXJndW1lbnRMaXN0IHsKLSAgICBwcml2YXRlIGZpbmFsIEV4cHJlc3Npb24gICBfYXJnOwotICAgIHByaXZhdGUgZmluYWwgQXJndW1lbnRMaXN0IF9yZXN0OwotCQotICAgIHB1YmxpYyBBcmd1bWVudExpc3QoRXhwcmVzc2lvbiBhcmcsIEFyZ3VtZW50TGlzdCByZXN0KSB7Ci0JX2FyZyA9IGFyZzsKLQlfcmVzdCA9IHJlc3Q7Ci0gICAgfQotCQkKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiBfcmVzdCA9PSBudWxsCi0JICAgID8gX2FyZy50b1N0cmluZygpCi0JICAgIDogX2FyZy50b1N0cmluZygpICsgIiwgIiArIF9yZXN0LnRvU3RyaW5nKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQXR0cmlidXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYmU5NjBlNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEF0dHJpYnV0ZSBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICBwcml2YXRlIFFOYW1lIF9uYW1lOwotCQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVV0aWwucHJpbnRsbigiQXR0cmlidXRlICIgKyBfbmFtZSk7Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWUoZ2V0QXR0cmlidXRlKCJuYW1lIikpOwotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQkvLyEhISBhZGQgdGV4dCBub2RlcwotCS8vISEhIHRha2UgY2FyZSBvZiB2YWx1ZSB0ZW1wbGF0ZXMKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGVTZXQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZVNldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZGFkNWRjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBBdHRyaWJ1dGVTZXQgZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotCi0gICAgLy8gRXJyb3IgbWVzc2FnZXMKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fTkFNRV9FUlJPUiA9Ci0JIkF0dHJpYnV0ZSBzZXQgbWlzc2luZyAnbmFtZScgYXR0cmlidXRlLiI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU1RBUkRfRVJST1IgPQotCSJBdHRyaWJ1dGUgc2V0cyBjYW4gb25seSBoYXZlIDx4c2w6YXR0cmlidXRlPiBjaGlsZCBlbGVtZW50cy4iOwotCi0gICAgLy8gVGhpcyBwcmVmaXggaXMgdXNlZCBmb3IgdGhlIG1ldGhvZCBuYW1lIG9mIGF0dHJpYnV0ZSBzZXQgbWV0aG9kcwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBdHRyaWJ1dGVTZXRQcmVmaXggPSAiJGFzJCI7Ci0gICAgCi0gICAgLy8gRWxlbWVudCBjb250ZW50cwotICAgIHByaXZhdGUgUU5hbWUgICAgICAgICAgICBfbmFtZTsKLSAgICBwcml2YXRlIFVzZUF0dHJpYnV0ZVNldHMgX3VzZVNldHM7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICAgICAgIF9tZXRob2Q7Ci0gICAgcHJpdmF0ZSBib29sZWFuICAgICAgICAgIF9pZ25vcmUgPSBmYWxzZTsKLSAgICAKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBRTmFtZSBvZiB0aGlzIGF0dHJpYnV0ZSBzZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLQlyZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbWV0aG9kIG5hbWUgb2YgdGhpcyBhdHRyaWJ1dGUgc2V0LiBUaGlzIG1ldGhvZCBuYW1lIGlzCi0gICAgICogZ2VuZXJhdGVkIGJ5IHRoZSBjb21waWxlciAoWFNMVEMpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXRob2ROYW1lKCkgewotCXJldHVybiBfbWV0aG9kOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhbGwgdGhpcyBtZXRob2QgdG8gcHJldmVudCBhIG1ldGhvZCBmb3IgYmVpbmcgY29tcGlsZWQgZm9yIHRoaXMgc2V0LgotICAgICAqIFRoaXMgaXMgdXNlZCBpbiBjYXNlIHNldmVyYWwgPHhzbDphdHRyaWJ1dGUtc2V0Li4uPiBlbGVtZW50cyBjb25zdGl0dXRlCi0gICAgICogYSBzaW5nbGUgc2V0ICh3aXRoIG9uZSBuYW1lKS4gVGhlIGxhc3QgZWxlbWVudCB3aWxsIG1lcmdlIGl0c2VsZiB3aXRoCi0gICAgICogYW55IHByZXZpb3VzIHNldChzKSB3aXRoIHRoZSBzYW1lIG5hbWUgYW5kIGRpc2FibGUgdGhlIG90aGVyIHNldChzKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmUoKSB7Ci0JX2lnbm9yZSA9IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnRzIG9mIHRoaXMgYXR0cmlidXRlIHNldC4gUmVjb2duaXNlZCBhdHRyaWJ1dGVzIGFyZQotICAgICAqICJuYW1lIiAocmVxdWlyZWQpIGFuZCAidXNlLWF0dHJpYnV0ZS1zZXRzIiAob3B0aW9uYWwpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCQotCS8vIEdldCB0aGlzIGF0dHJpYnV0ZSBzZXQncyBuYW1lCi0JX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWUoZ2V0QXR0cmlidXRlKCJuYW1lIikpOwotCWlmICgoX25hbWUgPT0gbnVsbCkgfHwgKF9uYW1lLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSkgewotCSAgICBmaW5hbCBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coTk9fTkFNRV9FUlJPUiwgZ2V0TGluZU51bWJlcigpKTsKLQkgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbXNnKTsKLQl9Ci0KLQkvLyBHZXQgYW55IGluY2x1ZGVkIGF0dHJpYnV0ZSBzZXRzIChzaW1pbGFyIHRvIGluaGVyaXRhbmNlLi4uKQotCWZpbmFsIFN0cmluZyB1c2VTZXRzID0gZ2V0QXR0cmlidXRlKCJ1c2UtYXR0cmlidXRlLXNldHMiKTsKLQlpZiAodXNlU2V0cy5sZW5ndGgoKSA+IDApIHsKLQkgICAgX3VzZVNldHMgPSBuZXcgVXNlQXR0cmlidXRlU2V0cyh1c2VTZXRzLCBwYXJzZXIpOwotCX0KLQotCS8vIFBhcnNlIHRoZSBjb250ZW50cyBvZiB0aGlzIG5vZGUuIEFsbCBjaGlsZCBlbGVtZW50cyBtdXN0IGJlCi0JLy8gPHhzbDphdHRyaWJ1dGU+IGVsZW1lbnRzLiBPdGhlciBlbGVtZW50cyBjYXVzZSBhbiBlcnJvci4KLQlmaW5hbCBWZWN0b3IgY29udGVudHMgPSBnZXRDb250ZW50cygpOwotCWZpbmFsIGludCBjb3VudCA9IGNvbnRlbnRzLnNpemUoKTsKLQlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgewotCSAgICBTeW50YXhUcmVlTm9kZSBjaGlsZCA9IChTeW50YXhUcmVlTm9kZSljb250ZW50cy5lbGVtZW50QXQoaSk7Ci0JICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFhzbEF0dHJpYnV0ZSkgewotCQlwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5zZXRDdXJyZW50Tm9kZShjaGlsZCk7Ci0JCWNoaWxkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJZmluYWwgRXJyb3JNc2cgbXNnID0KLQkJICAgIG5ldyBFcnJvck1zZyhCQVNUQVJEX0VSUk9SLCBnZXRMaW5lTnVtYmVyKCkpOwotCQlwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotCSAgICB9Ci0JfQotCi0JLy8gUG9pbnQgdGhlIHN5bWJvbCB0YWJsZSBiYWNrIGF0IHVzLi4uCi0JcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuc2V0Q3VycmVudE5vZGUodGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayB0aGUgY29udGVudHMgb2YgdGhpcyBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQotCWlmIChfaWdub3JlKSByZXR1cm4gKFR5cGUuVm9pZCk7Ci0KLQlmaW5hbCBBdHRyaWJ1dGVTZXQgb3RoZXIgPSBzdGFibGUuYWRkQXR0cmlidXRlU2V0KHRoaXMpOwotCWlmIChvdGhlciAhPSBudWxsKSB7Ci0JICAgIF9tZXRob2QgPSBvdGhlci5nZXRNZXRob2ROYW1lKCk7Ci0JICAgIG1lcmdlKG90aGVyKTsKLQkgICAgb3RoZXIuaWdub3JlKCk7Ci0JfQotCWVsc2UgewotCSAgICBfbWV0aG9kID0gQXR0cmlidXRlU2V0UHJlZml4ICsgZ2V0WFNMVEMoKS5uZXh0QXR0cmlidXRlU2V0U2VyaWFsKCk7Ci0JfQotCi0JaWYgKF91c2VTZXRzICE9IG51bGwpIF91c2VTZXRzLnR5cGVDaGVjayhzdGFibGUpOwotCXR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXJnZSB0aGlzIGF0dHJpYnV0ZSBzZXQgd2l0aCBzb21lIG90aGVyIG9uZQotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBtZXJnZShBdHRyaWJ1dGVTZXQgb3RoZXIpIHsKLQkvLyBCb3RoIGF0dHJpYnV0ZSBzZXRzIG1heSBpbmhlcml0IGZyb20gb3RoZXIgc2V0cy4uLgotCWlmIChfdXNlU2V0cyA9PSBudWxsKQotCSAgICBfdXNlU2V0cyA9IG90aGVyLl91c2VTZXRzOwotCWVsc2UKLQkgICAgX3VzZVNldHMuYWRkQXR0cmlidXRlU2V0cyhvdGhlci5nZXRBdHRyaWJ1dGUoInVzZS1hdHRyaWJ1dGUtc2V0cyIpKTsKLQotCS8vIE1lcmdlIHRoZSBjb250ZW50cyBvZiB0aGUgdHdvIGF0dHJpYnV0ZSBzZXRzLi4uCi0JZmluYWwgRW51bWVyYXRpb24gYXR0cmlidXRlcyA9IG90aGVyLmVsZW1lbnRzKCk7Ci0Jd2hpbGUgKGF0dHJpYnV0ZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0JICAgIHNldEZpcnN0RWxlbWVudCgoWHNsQXR0cmlidXRlKWF0dHJpYnV0ZXMubmV4dEVsZW1lbnQoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSBhIG1ldGhvZCB0aGF0IG91dHB1dHMgdGhlIGF0dHJpYnV0ZXMgaW4gdGhpcyBzZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotCWlmIChfaWdub3JlKSByZXR1cm47Ci0KLQkvLyBDcmVhdGUgYSBuZXcgbWV0aG9kIGdlbmVyYXRvciBmb3IgYW4gYXR0cmlidXRlIHNldCBtZXRob2QKLQltZXRob2RHZW4gPSBuZXcgQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yKF9tZXRob2QsIGNsYXNzR2VuKTsKLQotCS8vIFRyYW5zbGF0ZSBvdGhlciB1c2VkIGF0dHJpYnV0ZSBzZXRzIGZpcnN0LCBhcyBsb2NhbCBhdHRyaWJ1dGVzCi0JLy8gdGFrZSBwcmVjZWRlbmNlIChsYXN0IGF0dHJpYnV0ZXMgb3ZlcnJpZGVzIGZpcnN0KQotCWlmIChfdXNlU2V0cyAhPSBudWxsKSBfdXNlU2V0cy50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkvLyBUcmFuc2xhdGUgYWxsIGxvY2FsIGF0dHJpYnV0ZXMKLQlmaW5hbCBFbnVtZXJhdGlvbiBhdHRyaWJ1dGVzID0gZWxlbWVudHMoKTsKLQl3aGlsZSAoYXR0cmlidXRlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBYc2xBdHRyaWJ1dGUgYXR0cmlidXRlID0KLQkJKFhzbEF0dHJpYnV0ZSlhdHRyaWJ1dGVzLm5leHRFbGVtZW50KCk7Ci0JICAgIGF0dHJpYnV0ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQoUkVUVVJOKTsKLQkKLQltZXRob2RHZW4uc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotCW1ldGhvZEdlbi5zZXRNYXhMb2NhbHMoKTsKLQltZXRob2RHZW4uc2V0TWF4U3RhY2soKTsKLQltZXRob2RHZW4ucmVtb3ZlTk9QcygpOwotCWNsYXNzR2VuLmFkZE1ldGhvZChtZXRob2RHZW4uZ2V0TWV0aG9kKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoImF0dHJpYnV0ZS1zZXQ6ICIpOwotCS8vIFRyYW5zbGF0ZSBhbGwgbG9jYWwgYXR0cmlidXRlcwotCWZpbmFsIEVudW1lcmF0aW9uIGF0dHJpYnV0ZXMgPSBlbGVtZW50cygpOwotCXdoaWxlIChhdHRyaWJ1dGVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIGZpbmFsIFhzbEF0dHJpYnV0ZSBhdHRyaWJ1dGUgPQotCQkoWHNsQXR0cmlidXRlKWF0dHJpYnV0ZXMubmV4dEVsZW1lbnQoKTsKLQkgICAgYnVmLmFwcGVuZChhdHRyaWJ1dGUpOwotCX0KLQlyZXR1cm4oYnVmLnRvU3RyaW5nKCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZVZhbHVlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGVWYWx1ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NGMwMzQwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0F0dHJpYnV0ZVZhbHVlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotYWJzdHJhY3QgY2xhc3MgQXR0cmlidXRlVmFsdWUgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQXR0cmlidXRlVmFsdWUgY3JlYXRlKFN5bnRheFRyZWVOb2RlIHBhcmVudCwKLQkJCQkJICAgICAgU3RyaW5nIHRleHQsIFBhcnNlciBwYXJzZXIpIHsKLQotCUF0dHJpYnV0ZVZhbHVlIHJlc3VsdDsKLQlpZiAodGV4dC5pbmRleE9mKCd7JykgIT0gLTEpIHsKLQkgICAgcmVzdWx0ID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUodGV4dCwgcGFyc2VyKTsKLQl9Ci0JZWxzZSBpZiAodGV4dC5pbmRleE9mKCd9JykgIT0gLTEpIHsKLQkgICAgcmVzdWx0ID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUodGV4dCwgcGFyc2VyKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJlc3VsdCA9IG5ldyBTaW1wbGVBdHRyaWJ1dGVWYWx1ZSh0ZXh0KTsKLQkgICAgcmVzdWx0LnNldFBhcnNlcihwYXJzZXIpOwotCX0KLQlyZXN1bHQuc2V0UGFyZW50KHBhcmVudCk7Ci0JcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9BdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc2YTgxMDEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQXR0cmlidXRlVmFsdWVUZW1wbGF0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjMyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuSW5zdHJ1Y3Rpb247Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSBleHRlbmRzIEF0dHJpYnV0ZVZhbHVlIHsKLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKFN0cmluZyB2YWx1ZSwgUGFyc2VyIHBhcnNlcikgewotCWNoZWNrKHZhbHVlKTsKLQlwYXJzZUFWVGVtcGxhdGUoMCwgdmFsdWUsIHBhcnNlcik7Ci0Jc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHBhcnNlQVZUZW1wbGF0ZShmaW5hbCBpbnQgc3RhcnQsIFN0cmluZyB0ZXh0LCBQYXJzZXIgcGFyc2VyKSB7Ci0JU3RyaW5nIHN0cjsKLQotCWlmICh0ZXh0ID09IG51bGwpIHJldHVybjsKLQotCS8vIEdldCBmaXJzdCBzaW5nbGUgb3BlbmluZyBicmFjZXMKLQlpbnQgb3BlbiA9IHN0YXJ0IC0gMjsKLQlkbyB7Ci0JICAgIG9wZW4gPSB0ZXh0LmluZGV4T2YoJ3snLCBvcGVuKzIpOwotCX0gd2hpbGUgKChvcGVuICE9IC0xKSAmJiAKLQkJIChvcGVuIDwgKHRleHQubGVuZ3RoKCktMSkpICYmIAotCQkgKHRleHQuY2hhckF0KG9wZW4rMSkgPT0gJ3snKSk7Ci0KLQlpZiAob3BlbiAhPSAtMSkgewotCSAgICAvLyBHZXQgZmlyc3Qgc2luZ2xlIGNsb3NpbmcgYnJhY2VzCi0JICAgIGludCBjbG9zZSA9IG9wZW4gLSAyOwotCSAgICBkbyB7Ci0JCWNsb3NlID0gdGV4dC5pbmRleE9mKCd9JywgY2xvc2UrMik7Ci0JICAgIH0gd2hpbGUgKChjbG9zZSAhPSAtMSkgJiYgCi0JCSAgICAgKGNsb3NlIDwgKHRleHQubGVuZ3RoKCktMSkpICYmIAotCQkgICAgICh0ZXh0LmNoYXJBdChjbG9zZSsxKSA9PSAnfScpKTsKLQkgICAgCi0JICAgIC8vIEFkZCBsaXRlcmFsIGV4cHJlc3Npb25nIGJlZm9yZSBBVlQKLQkgICAgaWYgKG9wZW4gPiBzdGFydCkgewotCQlzdHIgPSByZW1vdmVEdXBsaWNhdGVCcmFjZXModGV4dC5zdWJzdHJpbmcoc3RhcnQsIG9wZW4pKTsKLQkJYWRkRWxlbWVudChuZXcgTGl0ZXJhbEV4cHIoc3RyKSk7Ci0JICAgIH0KLQkgICAgLy8gQWRkIHRoZSBBVlQgaXRzZWxmCi0JICAgIGlmIChjbG9zZSA+IG9wZW4gKyAxKSB7Ci0JCXN0ciA9IHRleHQuc3Vic3RyaW5nKG9wZW4gKyAxLCBjbG9zZSk7Ci0JCXN0ciA9IHJlbW92ZUR1cGxpY2F0ZUJyYWNlcyh0ZXh0LnN1YnN0cmluZyhvcGVuKzEsY2xvc2UpKTsKLQkJYWRkRWxlbWVudChwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsIHN0cikpOwotCSAgICB9Ci0JICAgIC8vIFBhcnNlIHJlc3Qgb2Ygc3RyaW5nCi0JICAgIHBhcnNlQVZUZW1wbGF0ZShjbG9zZSArIDEsIHRleHQsIHBhcnNlcik7Ci0JICAgIAotCX0KLQllbHNlIGlmIChzdGFydCA8IHRleHQubGVuZ3RoKCkpIHsKLQkgICAgLy8gQWRkIGxpdGVyYWwgZXhwcmVzc2lvbiBmb2xsb3dpbmcgQVZUCi0JICAgIHN0ciA9IHJlbW92ZUR1cGxpY2F0ZUJyYWNlcyh0ZXh0LnN1YnN0cmluZyhzdGFydCkpOwotCSAgICBhZGRFbGVtZW50KG5ldyBMaXRlcmFsRXhwcihzdHIpKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyByZW1vdmVEdXBsaWNhdGVCcmFjZXMoU3RyaW5nIG9yaWcpIHsKLQlTdHJpbmcgcmVzdWx0ID0gb3JpZzsKLQlpbnQgaW5kZXg7Ci0KLQl3aGlsZSAoKGluZGV4ID0gcmVzdWx0LmluZGV4T2YoInt7IikpICE9IC0xKSB7Ci0JICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHJpbmcoMCxpbmRleCkgKyAKLQkJcmVzdWx0LnN1YnN0cmluZyhpbmRleCsxLHJlc3VsdC5sZW5ndGgoKSk7Ci0JfQotCi0Jd2hpbGUgKChpbmRleCA9IHJlc3VsdC5pbmRleE9mKCJ9fSIpKSAhPSAtMSkgewotCSAgICByZXN1bHQgPSByZXN1bHQuc3Vic3RyaW5nKDAsaW5kZXgpICsgCi0JCXJlc3VsdC5zdWJzdHJpbmcoaW5kZXgrMSxyZXN1bHQubGVuZ3RoKCkpOwotCX0KLQotCXJldHVybihyZXN1bHQpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JZmluYWwgVmVjdG9yIGNvbnRlbnRzID0gZ2V0Q29udGVudHMoKTsKLQlmaW5hbCBpbnQgbiA9IGNvbnRlbnRzLnNpemUoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCSAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IChFeHByZXNzaW9uKWNvbnRlbnRzLmVsZW1lbnRBdChpKTsKLQkgICAgaWYgKCFleHAudHlwZUNoZWNrKHN0YWJsZSkuaWRlbnRpY2FsVG8oVHlwZS5TdHJpbmcpKSB7Ci0JCWNvbnRlbnRzLnNldEVsZW1lbnRBdChuZXcgQ2FzdEV4cHIoZXhwLCBUeXBlLlN0cmluZyksIGkpOwotCSAgICB9Ci0JfQotCXJldHVybiBfdHlwZSA9IFR5cGUuU3RyaW5nOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoIkFWVDpbIik7Ci0JZmluYWwgaW50IGNvdW50ID0gZWxlbWVudENvdW50KCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0JICAgIGJ1ZmZlci5hcHBlbmQoZWxlbWVudEF0KGkpLnRvU3RyaW5nKCkpOwotCSAgICBpZiAoaSA8IGNvdW50IC0gMSkKLQkJYnVmZmVyLmFwcGVuZCgnICcpOwotCX0KLQlyZXR1cm4gYnVmZmVyLmFwcGVuZCgnXScpLnRvU3RyaW5nKCk7Ci0gICAgfQotCQkKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlpZiAoZWxlbWVudENvdW50KCkgPT0gMSkgewotCSAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IChFeHByZXNzaW9uKWVsZW1lbnRBdCgwKTsKLQkgICAgZXhwLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQkgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCSAgICBmaW5hbCBpbnQgaW5pdEJ1ZmZlciA9IGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0JVRkZFUl9DTEFTUywKLQkJCQkJCSAgICAiPGluaXQ+IiwgIigpViIpOwotCSAgICBmaW5hbCBJbnN0cnVjdGlvbiBhcHBlbmQgPQotCQluZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19CVUZGRVJfQ0xBU1MsCi0JCQkJCQkgICAiYXBwZW5kIiwKLQkJCQkJCSAgICIoIiArIFNUUklOR19TSUcgKyAiKSIKLQkJCQkJCSAgICsgU1RSSU5HX0JVRkZFUl9TSUcpKTsKLQkgICAgCi0JICAgIGZpbmFsIGludCB0b1N0cmluZyA9IGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0JVRkZFUl9DTEFTUywKLQkJCQkJCSAgInRvU3RyaW5nIiwKLQkJCQkJCSAgIigpIitTVFJJTkdfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKFNUUklOR19CVUZGRVJfQ0xBU1MpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdEJ1ZmZlcikpOwotCSAgICAvLyBTdHJpbmdCdWZmZXIgaXMgb24gdGhlIHN0YWNrCi0JICAgIGZpbmFsIEVudW1lcmF0aW9uIGVudW0gPSBlbGVtZW50cygpOwotCSAgICB3aGlsZSAoZW51bS5oYXNNb3JlRWxlbWVudHMoKSkgewotCQlmaW5hbCBFeHByZXNzaW9uIGV4cCA9IChFeHByZXNzaW9uKWVudW0ubmV4dEVsZW1lbnQoKTsKLQkJZXhwLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWwuYXBwZW5kKGFwcGVuZCk7Ci0JICAgIH0KLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHRvU3RyaW5nKSk7Ci0JfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjaGVjayhTdHJpbmcgdmFsdWUpIHsKLQkvLyAhISEgaG93IGFib3V0IHF1b3RlZC9lc2NhcGVkIGJyYWNlcz8KLQlpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuOwotCi0JZmluYWwgY2hhcltdIGNoYXJzID0gdmFsdWUudG9DaGFyQXJyYXkoKTsKLQlpbnQgbGV2ZWwgPSAwOwotCWZvciAoaW50IGkgPSAwOyBpIDwgY2hhcnMubGVuZ3RoOyBpKyspIHsKLQkgICAgc3dpdGNoIChjaGFyc1tpXSkgewotCSAgICBjYXNlICd7JzoKLQkJaWYgKCgoaSsxKSA9PSAoY2hhcnMubGVuZ3RoKSkgfHwgKGNoYXJzW2krMV0gIT0gJ3snKSkKLQkJICAgICsrbGV2ZWw7Ci0JCWVsc2UKLQkJICAgIGkrKzsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgJ30nOgkKLQkJaWYgKCgoaSsxKSA9PSAoY2hhcnMubGVuZ3RoKSkgfHwgKGNoYXJzW2krMV0gIT0gJ30nKSkKLQkJICAgIC0tbGV2ZWw7Ci0JCWVsc2UKLQkJICAgIGkrKzsKLQkJYnJlYWs7Ci0JICAgIGRlZmF1bHQ6Ci0JCWNvbnRpbnVlOwotCSAgICB9Ci0JICAgIHN3aXRjaCAobGV2ZWwpIHsKLQkgICAgY2FzZSAwOgotCSAgICBjYXNlIDE6Ci0JCWNvbnRpbnVlOwotCSAgICBkZWZhdWx0OgotCQl0aHJvdyBuZXcgRXJyb3IoImJhZCBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlOiAiICsgdmFsdWUpOwotCSAgICB9Ci0JfQotCWlmIChsZXZlbCAhPSAwKQotCSAgICB0aHJvdyBuZXcgRXJyb3IoImJhZCBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlOiAiICsgdmFsdWUpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Jpbk9wRXhwci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQmluT3BFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUxMTUyNmQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQmluT3BFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDggKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBCaW5PcEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQTFVTICA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUlOVVMgPSAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBESVYgICA9IDM7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9EICAgPSA0OwotCQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIE9wcyA9IHsKLQkiKyIsICItIiwgIioiLCAiLyIsICIlIgotICAgIH07Ci0KLSAgICBwcml2YXRlIGludCBfb3A7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sZWZ0LCBfcmlnaHQ7Ci0JCi0gICAgcHVibGljIEJpbk9wRXhwcihpbnQgb3AsIEV4cHJlc3Npb24gbGVmdCwgRXhwcmVzc2lvbiByaWdodCkgewotCV9vcCA9IG9wOwotCShfbGVmdCA9IGxlZnQpLnNldFBhcmVudCh0aGlzKTsKLQkoX3JpZ2h0ID0gcmlnaHQpLnNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotCXN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotCV9sZWZ0LnNldFBhcnNlcihwYXJzZXIpOwotCV9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBUeXBlIHRsZWZ0ID0gX2xlZnQudHlwZUNoZWNrKHN0YWJsZSk7IAotCWZpbmFsIFR5cGUgdHJpZ2h0ID0gX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotCWZpbmFsIE1ldGhvZFR5cGUgcHR5cGUgPSBsb29rdXBQcmltb3Aoc3RhYmxlLCBPcHNbX29wXSwKLQkJCQkJICAgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5Wb2lkLAotCQkJCQkJCSAgICAgdGxlZnQsIHRyaWdodCkpOyAKLQlpZiAocHR5cGUgIT0gbnVsbCkgewotCSAgICBmaW5hbCBUeXBlIGFyZzEgPSAoVHlwZSkgcHR5cGUuYXJnc1R5cGUoKS5lbGVtZW50QXQoMCk7Ci0JICAgIGlmICghYXJnMS5pZGVudGljYWxUbyh0bGVmdCkpIHsKLQkJX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIGFyZzEpOwotCSAgICB9Ci0JICAgIGZpbmFsIFR5cGUgYXJnMiA9IChUeXBlKSBwdHlwZS5hcmdzVHlwZSgpLmVsZW1lbnRBdCgxKTsKLQkgICAgaWYgKCFhcmcyLmlkZW50aWNhbFRvKHRyaWdodCkpIHsKLQkJX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgYXJnMSk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIF90eXBlID0gcHR5cGUucmVzdWx0VHlwZSgpOwotCX0KLQl0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCV9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQlzd2l0Y2ggKF9vcCkgewotCWNhc2UgUExVUzoKLQkgICAgaWwuYXBwZW5kKF90eXBlLkFERCgpKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBNSU5VUzoKLQkgICAgaWwuYXBwZW5kKF90eXBlLlNVQigpKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBUSU1FUzoKLQkgICAgaWwuYXBwZW5kKF90eXBlLk1VTCgpKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBESVY6Ci0JICAgIGlsLmFwcGVuZChfdHlwZS5ESVYoKSk7Ci0JICAgIGJyZWFrOwotCWNhc2UgTU9EOgotCSAgICBpbC5hcHBlbmQoX3R5cGUuUkVNKCkpOwotCSAgICBicmVhazsKLQlkZWZhdWx0OgotCSAgICBmaW5hbCBFcnJvck1zZyBtc2cgPQotCQluZXcgRXJyb3JNc2coIlVua25vd24gb3BlcmF0b3IgZm9yIGJpbmFyeSBleHByZXNzaW9uIik7Ci0JICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbXNnKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gT3BzW19vcF0gKyAnKCcgKyBfbGVmdCArICIsICIgKyBfcmlnaHQgKyAnKSc7Ci0gICAgfQotfSAKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Jvb2xlYW5DYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Cb29sZWFuQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYjkxOTdkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Jvb2xlYW5DYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQm9vbGVhbkNhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9hcmcgPSBudWxsOwotCi0gICAgcHVibGljIEJvb2xlYW5DYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0JX2FyZyA9IGFyZ3VtZW50KDApOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX2FyZy50eXBlQ2hlY2soc3RhYmxlKTsKLQlyZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JX2FyZy50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JZmluYWwgVHlwZSB0YXJnID0gX2FyZy5nZXRUeXBlKCk7Ci0JaWYgKCF0YXJnLmlkZW50aWNhbFRvKFR5cGUuQm9vbGVhbikpIHsKLQkgICAgX2FyZy5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIHRhcmcudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Cb29sZWFuKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQm9vbGVhbkV4cHIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Jvb2xlYW5FeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY1YmMzOGEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQm9vbGVhbkV4cHIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGlubGluZWQgY2FsbHMgdG8gdGhlIFhTTFQgc3RhbmRhcmQgZnVuY3Rpb25zIAotICogdHJ1ZSgpIGFuZCBmYWxzZSgpLgotICovCi1maW5hbCBjbGFzcyBCb29sZWFuRXhwciBleHRlbmRzIEV4cHJlc3Npb24gewotICAgIHByaXZhdGUgYm9vbGVhbiBfdmFsdWU7Ci0KLSAgICBwdWJsaWMgQm9vbGVhbkV4cHIoYm9vbGVhbiB2YWx1ZSkgewotCV92YWx1ZSA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0JcmV0dXJuIF90eXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuIF92YWx1ZSA/ICJ0cnVlKCkiIDogImZhbHNlKCkiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldFZhbHVlKCkgewotCXJldHVybiBfdmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gY29udGV4dERlcGVuZGVudCgpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdmFsdWUpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlmIChfdmFsdWUpIHsKLQkgICAgaWwuYXBwZW5kKE5PUCk7CS8vIHRydWUgbGlzdCBmYWxscyB0aHJvdWdoCi0JfQotCWVsc2UgewotCSAgICBfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ2FsbFRlbXBsYXRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DYWxsVGVtcGxhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWI2ZTgwMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DYWxsVGVtcGxhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQ2FsbFRlbXBsYXRlIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICAgIHByaXZhdGUgUU5hbWUgX25hbWU7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlTeXN0ZW0ub3V0LnByaW50KCJDYWxsVGVtcGxhdGUiKTsKLQlVdGlsLnByaW50bG4oIiBuYW1lICIgKyBfbmFtZSk7Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCQkKLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNXaXRoUGFyYW1zKCkgewotCXJldHVybiBlbGVtZW50Q291bnQoKSA+IDA7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWUoZ2V0QXR0cmlidXRlKCJuYW1lIikpOwotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0JCQotICAgIC8qKgotICAgICAqIFZlcmlmeSB0aGF0IGEgdGVtcGxhdGUgd2l0aCB0aGlzIG5hbWUgZXhpc3RzLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSBzdGFibGUubG9va3VwVGVtcGxhdGUoX25hbWUpOwotCWlmICh0ZW1wbGF0ZSAhPSBudWxsKSB7Ci0JICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JfQotCWVsc2UgewotCSAgICBFcnJvck1zZyBlcnJvck1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5UTVBVTkRFRl9FUlIsIF9uYW1lKTsKLQkgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKGVycm9yTXNnKTsKLQl9Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgY2FsbC10ZW1wbGF0ZS4KLSAgICAgKiBBIHBhcmFtZXRlciBmcmFtZSBpcyBwdXNoZWQgb25seSBpZiBzb21lIHRlbXBsYXRlIGluIHRoZSBzdHlsZXNoZWV0Ci0gICAgICogdXNlcyBwYXJhbWV0ZXJzLgotICAgICAqIFRPRE86IG9wdGltaXplIGJ5IGNoZWNraW5nIGlmIHRoZSBjYWxsZWUgaGFzIHBhcmFtZXRlcnMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpOwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBQdXNoIGEgbmV3IHBhcmFtZXRlciBmcmFtZQotCWlmIChzdHlsZXNoZWV0Lmhhc0xvY2FsUGFyYW1zKCkgfHwgaGFzQ29udGVudHMoKSkgewotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOyAvLyBwdXNoIHBhcmFtIGZyYW1lCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLCAKLQkJCQkJCQkgUFVTSF9QQVJBTV9GUkFNRSwKLQkJCQkJCQkgUFVTSF9QQVJBTV9GUkFNRV9TSUcpCi0JCQkJCSkpOwotCi0JICAgIC8vIHRyYW5zbGF0ZSB3aXRoLXBhcmFtcwotCSAgICB0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0KLQlmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gc3R5bGVzaGVldC5nZXRDbGFzc05hbWUoKTsKLQkvLyBHZW5lcmF0ZSBhIHZhbGlkIEphdmEgbWV0aG9kIG5hbWUKLQlTdHJpbmcgbWV0aG9kTmFtZSA9IF9uYW1lLnRvU3RyaW5nKCk7Ci0JbWV0aG9kTmFtZSA9IG1ldGhvZE5hbWUucmVwbGFjZSgnLicsICckJyk7Ci0JbWV0aG9kTmFtZSA9IG1ldGhvZE5hbWUucmVwbGFjZSgnLScsICckJyk7Ci0KLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKGNsYXNzTmFtZSwKLQkJCQkJCSAgICAgbWV0aG9kTmFtZSwKLQkJCQkJCSAgICAgIigiCi0JCQkJCQkgICAgICsgRE9NX0lOVEZfU0lHCi0JCQkJCQkgICAgICsgTk9ERV9JVEVSQVRPUl9TSUcKLQkJCQkJCSAgICAgKyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0JCQkJCQkgICAgICsgTk9ERV9TSUcKLQkJCQkJCSAgICAgKyIpViIpKSk7Ci0JCi0KLQkvLyBQb3AgcGFyYW1ldGVyIGZyYW1lCi0JaWYgKHN0eWxlc2hlZXQuaGFzTG9jYWxQYXJhbXMoKSB8fCBoYXNDb250ZW50cygpKSB7Ci0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7IC8vIHBvcCBwYXJhbSBmcmFtZQotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCQkgUE9QX1BBUkFNX0ZSQU1FLAotCQkJCQkJCSBQT1BfUEFSQU1fRlJBTUVfU0lHKQotCQkJCQkpKTsKLQkgICAgCi0JfQotICAgIH0KLX0gCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DYXN0RXhwci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ2FzdEV4cHIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjgyM2FiZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DYXN0RXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBDYXN0RXhwciBleHRlbmRzIEV4cHJlc3Npb24gewotICAgIHByaXZhdGUgZmluYWwgRXhwcmVzc2lvbiBfbGVmdDsKLQotICAgIC8qKgotICAgICAqIExlZ2FsIGNvbnZlcnNpb25zIGJldHdlZW4gaW50ZXJuYWwgdHlwZXMuCi0gICAgICovCi0gICAgc3RhdGljIHByaXZhdGUgTXVsdGlIYXNodGFibGUgSW50ZXJuYWxUeXBlTWFwID0gbmV3IE11bHRpSGFzaHRhYmxlKCk7Ci0KLSAgICBzdGF0aWMgewotCS8vIFBvc3NpYmxlIHR5cGUgY29udmVyc2lvbnMgYmV0d2VlbiBpbnRlcm5hbCB0eXBlcwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Cb29sZWFuLCBUeXBlLkJvb2xlYW4pOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Cb29sZWFuLCBUeXBlLlJlYWwpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Cb29sZWFuLCBUeXBlLlN0cmluZyk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkJvb2xlYW4sIFR5cGUuUmVmZXJlbmNlKTsKLQotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWFsLCBUeXBlLlJlYWwpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZWFsLCBUeXBlLkludCk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlYWwsIFR5cGUuQm9vbGVhbik7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlYWwsIFR5cGUuU3RyaW5nKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVhbCwgVHlwZS5SZWZlcmVuY2UpOwotCi0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkludCwgVHlwZS5JbnQpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5JbnQsIFR5cGUuUmVhbCk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkludCwgVHlwZS5Cb29sZWFuKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuSW50LCBUeXBlLlN0cmluZyk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLkludCwgVHlwZS5SZWZlcmVuY2UpOwotCi0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5TdHJpbmcsIFR5cGUuQm9vbGVhbik7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlN0cmluZywgVHlwZS5SZWFsKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuU3RyaW5nLCBUeXBlLlJlZmVyZW5jZSk7Ci0KLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZVNldCwgVHlwZS5Ob2RlU2V0KTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZVNldCwgVHlwZS5Cb29sZWFuKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZVNldCwgVHlwZS5SZWFsKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZVNldCwgVHlwZS5TdHJpbmcpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlU2V0LCBUeXBlLk5vZGUpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlU2V0LCBUeXBlLlJlZmVyZW5jZSk7Ci0KLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZSwgVHlwZS5Ob2RlKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZSwgVHlwZS5Cb29sZWFuKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZSwgVHlwZS5SZWFsKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuTm9kZSwgVHlwZS5TdHJpbmcpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlLCBUeXBlLk5vZGVTZXQpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5Ob2RlLCBUeXBlLlJlZmVyZW5jZSk7Ci0KLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVzdWx0VHJlZSwgVHlwZS5SZXN1bHRUcmVlKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVzdWx0VHJlZSwgVHlwZS5Cb29sZWFuKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVzdWx0VHJlZSwgVHlwZS5SZWFsKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVzdWx0VHJlZSwgVHlwZS5TdHJpbmcpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZXN1bHRUcmVlLCBUeXBlLk5vZGVTZXQpOwotCUludGVybmFsVHlwZU1hcC5wdXQoVHlwZS5SZXN1bHRUcmVlLCBUeXBlLlJlZmVyZW5jZSk7Ci0KLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVmZXJlbmNlLCBUeXBlLlJlZmVyZW5jZSk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5Cb29sZWFuKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVmZXJlbmNlLCBUeXBlLkludCk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5SZWFsKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVmZXJlbmNlLCBUeXBlLlN0cmluZyk7Ci0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlJlZmVyZW5jZSwgVHlwZS5Ob2RlKTsKLQlJbnRlcm5hbFR5cGVNYXAucHV0KFR5cGUuUmVmZXJlbmNlLCBUeXBlLk5vZGVTZXQpOwotCi0JSW50ZXJuYWxUeXBlTWFwLnB1dChUeXBlLlZvaWQsIFR5cGUuU3RyaW5nKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX3R5cGVUZXN0ID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3QgYSBjYXN0IGV4cHJlc3Npb24gYW5kIGNoZWNrIHRoYXQgdGhlIGNvbnZlcnNpb24gaXMgCi0gICAgICogdmFsaWQgYnkgY2FsbGluZyB0eXBlQ2hlY2soKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgQ2FzdEV4cHIoRXhwcmVzc2lvbiBsZWZ0LCBUeXBlIHR5cGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX2xlZnQgPSBsZWZ0OwotCV90eXBlID0gdHlwZTsJCS8vIHVzZSBpbmhlcml0ZWQgZmllbGQKLQotCWlmICgoX2xlZnQgaW5zdGFuY2VvZiBTdGVwKSAmJiAoX3R5cGUgPT0gVHlwZS5Cb29sZWFuKSkgewotCSAgICBTdGVwIHN0ZXAgPSAoU3RlcClfbGVmdDsKLQkgICAgaWYgKChzdGVwLmlzU2VsZigpKSAmJiAoc3RlcC5nZXROb2RlVHlwZSgpICE9IC0xKSkgCi0JCV90eXBlVGVzdCA9IHRydWU7Ci0JfQotCQotCS8vIGNoZWNrIGlmIGNvbnZlcnNpb24gaXMgdmFsaWQKLQlzZXRQYXJzZXIobGVmdC5nZXRQYXJzZXIoKSk7Ci0Jc2V0UGFyZW50KGxlZnQuZ2V0UGFyZW50KCkpOwotCWxlZnQuc2V0UGFyZW50KHRoaXMpOwotCXR5cGVDaGVjayhsZWZ0LmdldFBhcnNlcigpLmdldFN5bWJvbFRhYmxlKCkpOwotICAgIH0KLQkJCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcigpIHsKLQlyZXR1cm4gX2xlZnQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gImNhc3QoIiArIF9sZWZ0ICsgIiwgIiArIF90eXBlICsgIikiOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2tpbmcgYSBjYXN0IGV4cHJlc3Npb24gYW1vdW50cyB0byB2ZXJpZnlpbmcgdGhhdCB0aGUgIAotICAgICAqIHR5cGUgY29udmVyc2lvbiBpcyBsZWdhbC4gQ2FzdCBleHByZXNzaW9ucyBhcmUgY3JlYXRlZCBkdXJpbmcgCi0gICAgICogdHlwZSBjaGVja2luZywgYnV0IHR5cGVDaGVjaygpIGlzIHVzdWFsbHkgbm90IGNhbGxlZCBvbiB0aGVtLiAKLSAgICAgKiBBcyBhIHJlc3VsdCwgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZyb20gdGhlIGNvbnN0cnVjdG9yLgotICAgICAqLwkKLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCVR5cGUgdGxlZnQgPSBfbGVmdC5nZXRUeXBlKCk7Ci0JaWYgKHRsZWZ0ID09IG51bGwpIHsKLQkgICAgdGxlZnQgPSBfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JaWYgKHRsZWZ0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLQkgICAgdGxlZnQgPSBUeXBlLk5vZGU7CS8vIG11bHRpcGxlIGluc3RhbmNlcwotCX0KLQllbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0JICAgIHRsZWZ0ID0gVHlwZS5SZXN1bHRUcmVlOyAvLyBtdWx0aXBsZSBpbnN0YW5jZXMKLQl9Ci0JaWYgKEludGVybmFsVHlwZU1hcC5tYXBzKHRsZWZ0LCBfdHlwZSkpIHsKLQkgICAgcmV0dXJuIF90eXBlOwotCX0KLQl0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7CQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIAotCQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JRmxvd0xpc3QgZmw7Ci0JZmluYWwgVHlwZSBsdHlwZSA9IF9sZWZ0LmdldFR5cGUoKTsKLQotCS8vIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UgZm9yIHRoZSBzZWxmOjogYXhpcy4gSW5zdGVhZCBvZiBsZXR0aW5nCi0JLy8gdGhlIFN0ZXAgb2JqZWN0IGNyZWF0ZSBhbmQgaXRlcmF0b3IgdGhhdCB3ZSBjYXN0IGJhY2sgdG8gYSBzaW5nbGUKLQkvLyBub2RlLCB3ZSBzaW1wbHkgYXNrIHRoZSBET00gZm9yIHRoZSBub2RlIHR5cGUuCi0JaWYgKF90eXBlVGVzdCkgewotCSAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCSAgICBmaW5hbCBpbnQgaWR4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgICAgICJnZXRUeXBlIiwgIihJKUkiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBTSVBVU0goKHNob3J0KSgoU3RlcClfbGVmdCkuZ2V0Tm9kZVR5cGUoKSkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpZHgsIDIpKTsKLQkgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRl9JQ01QTkUobnVsbCkpKTsKLQl9Ci0JZWxzZSB7Ci0KLQkgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpZiAoX3R5cGUgIT0gbHR5cGUpIHsKLQkJX2xlZnQuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQlpZiAoX3R5cGUgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSkgewotCQkgICAgZmwgPSBsdHlwZS50cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkJCQlfdHlwZSk7Ci0JCSAgICBpZiAoZmwgIT0gbnVsbCkgewotCQkJX2ZhbHNlTGlzdC5hcHBlbmQoZmwpOwotCQkgICAgfQotCQl9Ci0JCWVsc2UgewotCQkgICAgbHR5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgX3R5cGUpOwkKLQkJfQotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIFR5cGUgbHR5cGUgPSBfbGVmdC5nZXRUeXBlKCk7Ci0JX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlmIChfdHlwZS5pZGVudGljYWxUbyhsdHlwZSkgPT0gZmFsc2UpIHsKLQkgICAgX2xlZnQuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBsdHlwZS50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBfdHlwZSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NlaWxpbmdDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DZWlsaW5nQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNWQxMTgxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NlaWxpbmdDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQ2VpbGluZ0NhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHB1YmxpYyBDZWlsaW5nQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JYXJndW1lbnQoMCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNwZy5hZGRNZXRob2RyZWYoTUFUSF9DTEFTUywKLQkJCQkJCSAgICAiY2VpbCIsICIoRClEIikpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DaG9vc2UuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Nob29zZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjUxNzBiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Nob29zZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjAwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIENob29zZSBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBNSVNTSU5HX1dIRU5fRVJST1IgPQotCSJBdCBsZWFzdCBvbmUgV2hlbiBlbGVtZW50IHJlcXVpcmVkIGluIENob29zZSI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIElMTEVHQUxfRUxFTUVOVF9FUlJPUiA9Ci0JIk9ubHkgV2hlbnxPdGhlcndpc2UgZWxlbWVudHMgYWxsb3dlZCBpbiBDaG9vc2UiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBNVUxUSVBMRV9PVEhFUldJU0VfRVJST1IgPQotCSJPbmx5IG9uZSBPdGhlcndpc2UgZWxlbWVudCBhbGxvd2VkIGluIENob29zZSI7Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5IHRoZSBlbGVtZW50IGNvbnRlbnRzIChhIGxvdCBvZiB3aGVuJ3MgYW5kIGFuIG90aGVyd2lzZSkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIkNob29zZSIpOwotCWluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCWRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQkKLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBDaG9vc2UgZWxlbWVudC4gR2VuZXJhdGUgYSB0ZXN0LWNoYWluIGZvciB0aGUgdmFyaW91cwotICAgICAqIDx4c2w6d2hlbj4gZWxlbWVudHMgYW5kIGRlZmF1bHQgdG8gdGhlIDx4c2w6b3RoZXJ3aXNlPiBpZiBwcmVzZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIFZlY3RvciB3aGVuRWxlbWVudHMgPSBuZXcgVmVjdG9yKCk7Ci0JT3RoZXJ3aXNlIG90aGVyd2lzZSA9IG51bGw7Ci0JRW51bWVyYXRpb24gZWxlbWVudHMgPSBlbGVtZW50cygpOwotCi0JLy8gVGhlc2UgdHdvIGFyZSBmb3IgcmVwb3J0aW5nIGVycm9ycyBvbmx5Ci0JRXJyb3JNc2cgZXJyb3IgPSBudWxsOwotCWZpbmFsIGludCBsaW5lID0gZ2V0TGluZU51bWJlcigpOwotCi0JLy8gVHJhdmVyc2UgYWxsIGNoaWxkIG5vZGVzIC0gbXVzdCBiZSBlaXRoZXIgV2hlbiBvciBPdGhlcndpc2UKLQl3aGlsZSAoZWxlbWVudHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgT2JqZWN0IGVsZW1lbnQgPSBlbGVtZW50cy5uZXh0RWxlbWVudCgpOwotCSAgICAvLyBBZGQgYSBXaGVuIGNoaWxkIGVsZW1lbnQKLQkgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBXaGVuKSB7Ci0JCXdoZW5FbGVtZW50cy5hZGRFbGVtZW50KGVsZW1lbnQpOwotCSAgICB9Ci0JICAgIC8vIEFkZCBhbiBPdGhlcndpc2UgY2hpbGQgZWxlbWVudAotCSAgICBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgT3RoZXJ3aXNlKSB7Ci0JCWlmIChvdGhlcndpc2UgPT0gbnVsbCkgewotCQkgICAgb3RoZXJ3aXNlID0gKE90aGVyd2lzZSllbGVtZW50OwotCQl9Ci0JCWVsc2UgewotCQkgICAgZXJyb3IgPSBuZXcgRXJyb3JNc2coTVVMVElQTEVfT1RIRVJXSVNFX0VSUk9SLCBsaW5lKTsKLQkJICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyb3IpOwotCQl9Ci0JICAgIH0KLQkgICAgLy8gSXQgaXMgYW4gZXJyb3IgaWYgd2UgZmluZCBzb21lIG90aGVyIGVsZW1lbnQgaGVyZQotCSAgICBlbHNlIHsKLQkJZXJyb3IgPSBuZXcgRXJyb3JNc2coSUxMRUdBTF9FTEVNRU5UX0VSUk9SLCBsaW5lKTsKLQkJZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnJvcik7Ci0JICAgIH0KLQl9Ci0KLQkvLyBNYWtlIHN1cmUgdGhhdCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgPHhzbDp3aGVuPiBlbGVtZW50Ci0JaWYgKHdoZW5FbGVtZW50cy5zaXplKCkgPT0gMCkgewotCSAgICBlcnJvciA9IG5ldyBFcnJvck1zZyhNSVNTSU5HX1dIRU5fRVJST1IsIGdldExpbmVOdW1iZXIoKSk7Ci0JICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgZXJyb3IpOwotCSAgICByZXR1cm47Ci0JfQotCi0JSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gbmV4dCBlbGVtZW50IHdpbGwgaG9sZCBhIGhhbmRsZSB0byB0aGUgYmVnaW5uaW5nIG9mIG5leHQKLQkvLyBXaGVuL090aGVyd2lzZSBpZiB0ZXN0IG9uIGN1cnJlbnQgV2hlbiBmYWlscwotCUJyYW5jaEhhbmRsZSBuZXh0RWxlbWVudCA9IG51bGw7Ci0JVmVjdG9yIGV4aXRIYW5kbGVzID0gbmV3IFZlY3RvcigpOwotCUluc3RydWN0aW9uSGFuZGxlIGV4aXQgPSBudWxsOwotCi0JRW51bWVyYXRpb24gd2hlbnMgPSB3aGVuRWxlbWVudHMuZWxlbWVudHMoKTsKLQl3aGlsZSAod2hlbnMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgV2hlbiB3aGVuID0gKFdoZW4pd2hlbnMubmV4dEVsZW1lbnQoKTsKLQkgICAgZmluYWwgRXhwcmVzc2lvbiB0ZXN0ID0gd2hlbi5nZXRUZXN0KCk7Ci0KLQkgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgdHJ1ZWMgPSBpbC5nZXRFbmQoKTsKLQotCSAgICBpZiAobmV4dEVsZW1lbnQgIT0gbnVsbCkgCi0JCW5leHRFbGVtZW50LnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0JICAgIHRlc3QudHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICBpZiAodGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uQ2FsbCkgewotCQlGdW5jdGlvbkNhbGwgY2FsbCA9IChGdW5jdGlvbkNhbGwpdGVzdDsKLQkJdHJ5IHsKLQkJICAgIFR5cGUgdHlwZSA9IGNhbGwudHlwZUNoZWNrKGdldFBhcnNlcigpLmdldFN5bWJvbFRhYmxlKCkpOwotCQkgICAgaWYgKHR5cGUgIT0gVHlwZS5Cb29sZWFuKSB7Ci0JCQl0ZXN0Ll9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotCQkgICAgfQotCQl9Ci0JCWNhdGNoIChUeXBlQ2hlY2tFcnJvciBlKSB7IAotCQkgICAgLy8gaGFuZGxlZCBsYXRlciEKLQkJfQotCSAgICB9Ci0JICAgIC8vIHJlbWVtYmVyIGVuZCBvZiBjb25kaXRpb24KLQkgICAgdHJ1ZWMgPSBpbC5nZXRFbmQoKTsKLQotCSAgICAvLyBUaGUgV2hlbiBvYmplY3Qgc2hvdWxkIGJlIGlnbm9yZWQgY29tcGxldGVseSBpbiBjYXNlIGl0IHRlc3RzCi0JICAgIC8vIGZvciB0aGUgc3VwcG9ydCBvZiBhIG5vbi1hdmFpbGFibGUgZWxlbWVudAotCSAgICBpZiAoIXdoZW4uaWdub3JlKCkpIHdoZW4udHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgLy8gZ290byBleGl0IGFmdGVyIGV4ZWN1dGluZyB0aGUgYm9keSBvZiB3aGVuCi0JICAgIGV4aXRIYW5kbGVzLmFkZEVsZW1lbnQoaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKSk7Ci0JICAgIGlmICh3aGVucy5oYXNNb3JlRWxlbWVudHMoKSB8fCBvdGhlcndpc2UgIT0gbnVsbCkgewotCQluZXh0RWxlbWVudCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JCXRlc3QuYmFja1BhdGNoRmFsc2VMaXN0KG5leHRFbGVtZW50KTsKLQkgICAgfQotCSAgICBlbHNlCi0JCXRlc3QuYmFja1BhdGNoRmFsc2VMaXN0KGV4aXQgPSBpbC5hcHBlbmQoTk9QKSk7Ci0JICAgIHRlc3QuYmFja1BhdGNoVHJ1ZUxpc3QodHJ1ZWMuZ2V0TmV4dCgpKTsKLQl9Ci0JCi0JLy8gVHJhbnNsYXRlIGFueSA8eHNsOm90aGVyd2lzZT4gZWxlbWVudAotCWlmIChvdGhlcndpc2UgIT0gbnVsbCkgewotCSAgICBuZXh0RWxlbWVudC5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotCSAgICBvdGhlcndpc2UudHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGV4aXQgPSBpbC5hcHBlbmQoTk9QKTsKLQl9Ci0KLQkvLyBub3cgdGhhdCBlbmQgaXMga25vd24gc2V0IHRhcmdldHMgb2YgZXhpdCBnb3RvcwotCUVudW1lcmF0aW9uIGV4aXRHb3RvcyA9IGV4aXRIYW5kbGVzLmVsZW1lbnRzKCk7Ci0Jd2hpbGUgKGV4aXRHb3Rvcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBCcmFuY2hIYW5kbGUgZ290b0V4aXQgPSAoQnJhbmNoSGFuZGxlKWV4aXRHb3Rvcy5uZXh0RWxlbWVudCgpOwotCSAgICBnb3RvRXhpdC5zZXRUYXJnZXQoZXhpdCk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbW1lbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTgyYTg2My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Db21tZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQ29tbWVudCBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCXR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JcmV0dXJuIFR5cGUuU3RyaW5nOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBTYXZlIHRoZSBjdXJyZW50IGhhbmRsZXIgYmFzZSBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCWlsLmFwcGVuZChEVVApOwkJLy8gZmlyc3QgYXJnIHRvICJjb21tZW50IiBjYWxsCi0KLQkvLyBHZXQgdGhlIHRyYW5zbGV0J3MgU3RyaW5nVmFsdWVIYW5kbGVyCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJICAgICAgICJzdHJpbmdWYWx1ZUhhbmRsZXIiLAotCQkJCQkgICAgICAgU1RSSU5HX1ZBTFVFX0hBTkRMRVJfU0lHKSkpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotCi0JLy8gdHJhbnNsYXRlIGNvbnRlbnRzIHdpdGggc3Vic3RpdHV0ZWQgaGFuZGxlcgotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gZ2V0IFN0cmluZyBvdXQgb2YgdGhlIGhhbmRsZXIKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfVkFMVUVfSEFORExFUiwKLQkJCQkJCSAgICAgImdldFZhbHVlIiwKLQkJCQkJCSAgICAgIigpIiArIFNUUklOR19TSUcpKSk7Ci0JLy8gY2FsbCAiY29tbWVudCIKLQlmaW5hbCBpbnQgY29tbWVudCA9Ci0JICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLQkJCQkgICAgICAiY29tbWVudCIsIAotCQkJCSAgICAgICIoIiArIFNUUklOR19TSUcgKyAiKVYiKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjb21tZW50LCAyKSk7Ci0JLy8gUmVzdG9yZSBvbGQgaGFuZGxlciBiYXNlIGZyb20gc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Db21waWxlckV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ29tcGlsZXJFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2FiZDI4MS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Db21waWxlckV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTEgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotcHVibGljIGZpbmFsIGNsYXNzIENvbXBpbGVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLQotICAgIHByaXZhdGUgU3RyaW5nIF9tc2c7Ci0KLSAgICBwdWJsaWMgQ29tcGlsZXJFeGNlcHRpb24oKSB7Ci0Jc3VwZXIoKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIENvbXBpbGVyRXhjZXB0aW9uKEV4Y2VwdGlvbiBlKSB7Ci0Jc3VwZXIoZS50b1N0cmluZygpKTsKLQlfbXNnID0gZS50b1N0cmluZygpOyAKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIENvbXBpbGVyRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7Ci0Jc3VwZXIobWVzc2FnZSk7Ci0JX21zZyA9IG1lc3NhZ2U7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewotCWZpbmFsIGludCBjb2wgPSBfbXNnLmluZGV4T2YoJzonKTsKLQotCWlmIChjb2wgPiAtMSkKLQkgICAgcmV0dXJuKF9tc2cuc3Vic3RyaW5nKGNvbCkpOwotCWVsc2UKLQkgICAgcmV0dXJuKF9tc2cpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbmNhdENhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbmNhdENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODQ3N2Y3Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Db25jYXRDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBDb25jYXRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgQ29uY2F0Q2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBhcmd1bWVudENvdW50KCk7IGkrKykgewotCSAgICBmaW5hbCBFeHByZXNzaW9uIGV4cCA9IGFyZ3VtZW50KGkpOwotCSAgICBpZiAoIWV4cC50eXBlQ2hlY2soc3RhYmxlKS5pZGVudGljYWxUbyhUeXBlLlN0cmluZykpIHsKLQkJc2V0QXJndW1lbnQoaSwgbmV3IENhc3RFeHByKGV4cCwgVHlwZS5TdHJpbmcpKTsKLQkgICAgfQotCX0KLQlyZXR1cm4gX3R5cGUgPSBUeXBlLlN0cmluZzsKLSAgICB9Ci0JCi0gICAgLyoqIHRyYW5zbGF0ZSBsZWF2ZXMgYSBTdHJpbmcgb24gdGhlIHN0YWNrICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBpbnQgbkFyZ3MgPSBhcmd1bWVudENvdW50KCk7Ci0JCi0Jc3dpdGNoIChuQXJncykgewotCWNhc2UgMDoKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSk7Ci0JICAgIGJyZWFrOwotCSAgICAKLQljYXNlIDE6Ci0JICAgIGFyZ3VtZW50KCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBicmVhazsKLQotCWRlZmF1bHQ6Ci0JICAgIGZpbmFsIGludCBpbml0QnVmZmVyID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQlVGRkVSX0NMQVNTLAotCQkJCQkJICAgICI8aW5pdD4iLCAiKClWIik7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uIGFwcGVuZCA9Ci0JCW5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0JVRkZFUl9DTEFTUywKLQkJCQkJCSAgICJhcHBlbmQiLAotCQkJCQkJICAgIigiK1NUUklOR19TSUcrIikiCi0JCQkJCQkgICArU1RSSU5HX0JVRkZFUl9TSUcpKTsKLQkgICAgCi0JICAgIGZpbmFsIGludCB0b1N0cmluZyA9IGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX0JVRkZFUl9DTEFTUywKLQkJCQkJCSAgInRvU3RyaW5nIiwKLQkJCQkJCSAgIigpIitTVFJJTkdfU0lHKTsKLQkgICAgCi0JICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhTVFJJTkdfQlVGRkVSX0NMQVNTKSkpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRCdWZmZXIpKTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXJnczsgaSsrKSB7Ci0JCWFyZ3VtZW50KGkpLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWwuYXBwZW5kKGFwcGVuZCk7Ci0JICAgIH0KLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKHRvU3RyaW5nKSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbnN0YW50cy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ29uc3RhbnRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYzZDM2MGMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ29uc3RhbnRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0ODQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbkNvbnN0YW50czsKLQotcHVibGljIGludGVyZmFjZSBDb25zdGFudHMgZXh0ZW5kcyBJbnN0cnVjdGlvbkNvbnN0YW50cyB7Ci0KLSAgICAvLyBFcnJvciBjYXRlZ29yaWVzIHVzZWQgdG8gcmVwb3J0IGVycm9ycyB0byBQYXJzZXIucmVwb3J0RXJyb3IoKQotCi0gICAgLy8gVW5leHBlY3RlZCBpbnRlcm5hbCBlcnJvcnMsIHN1Y2ggYXMgbnVsbC1wdHIgZXhjZXB0aW9ucywgZXRjLgotICAgIC8vIEltbWVkaWF0ZWx5IHRlcm1pbmF0ZXMgY29tcGlsYXRpb24sIG5vIHRyYW5zbGV0IHByb2R1Y2VkCi0gICAgcHVibGljIGZpbmFsIGludCBJTlRFUk5BTCAgICAgICAgPSAwOwotICAgIC8vIFhTTFQgZWxlbWVudHMgdGhhdCBhcmUgbm90IGltcGxlbWVudGVkIGFuZCB1bnN1cHBvcnRlZCBleHQuCi0gICAgLy8gSW1tZWRpYXRlbHkgdGVybWluYXRlcyBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLSAgICBwdWJsaWMgZmluYWwgaW50IFVOU1VQUE9SVEVEICAgICA9IDE7Ci0gICAgLy8gRmF0YWwgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKHBhcnNpbmcgb3IgY29udGVudCkKLSAgICAvLyBJbW1lZGlhdGVseSB0ZXJtaW5hdGVzIGNvbXBpbGF0aW9uLCBubyB0cmFuc2xldCBwcm9kdWNlZAotICAgIHB1YmxpYyBmaW5hbCBpbnQgRkFUQUwgICAgICAgICAgID0gMjsKLSAgICAvLyBPdGhlciBlcnJvciBpbiB0aGUgc3R5bGVzaGVldCBpbnB1dCAocGFyc2luZyBvciBjb250ZW50KQotICAgIC8vIERvZXMgbm90IHRlcm1pbmF0ZSBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLSAgICBwdWJsaWMgZmluYWwgaW50IEVSUk9SICAgICAgICAgICA9IDM7Ci0gICAgLy8gT3RoZXIgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKGNvbnRlbnQgZXJyb3JzIG9ubHkpCi0gICAgLy8gRG9lcyBub3QgdGVybWluYXRlIGNvbXBpbGF0aW9uLCBhIHRyYW5zbGV0IGlzIHByb2R1Y2VkCi0gICAgcHVibGljIGZpbmFsIGludCBXQVJOSU5HICAgICAgICAgPSA0OwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTUEFDRV9GRUFUVVJFID0KLQkiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL25hbWVzcGFjZXMiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfSU5URgotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX0lOVEZfU0lHICAgICAgICAKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldDsiOwotICAgIAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJJQlVURVNfU0lHIAotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlczsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfSVRFUkFUT1JfU0lHCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvTm9kZUl0ZXJhdG9yOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0lOVEZfU0lHCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0lNUExfQ0xBU1MKLQk9ICJvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9ET01JbXBsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET01fSU1QTF9TSUcKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRE9NSW1wbDsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9BREFQVEVSX0NMQVNTCi0JPSAib3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRE9NQWRhcHRlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0FEQVBURVJfU0lHCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUFkYXB0ZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNVUxUSV9ET01fQ0xBU1MKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5NdWx0aURPTSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTVVMVElfRE9NX1NJRwotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9NdWx0aURPTTsiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HICAgIAotCT0gImphdmEubGFuZy5TdHJpbmciOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX1BVQkxJQyAgICAKLQk9IGRlLmZ1Yi5ieXRlY29kZS5Db25zdGFudHMuQUNDX1BVQkxJQzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBQ0NfU1VQRVIgICAgIAotCT0gZGUuZnViLmJ5dGVjb2RlLkNvbnN0YW50cy5BQ0NfU1VQRVI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX0ZJTkFMICAgICAKLQk9IGRlLmZ1Yi5ieXRlY29kZS5Db25zdGFudHMuQUNDX0ZJTkFMOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFDQ19QUklWQVRFICAgCi0JPSBkZS5mdWIuYnl0ZWNvZGUuQ29uc3RhbnRzLkFDQ19QUklWQVRFOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFDQ19QUk9URUNURUQgCi0JPSBkZS5mdWIuYnl0ZWNvZGUuQ29uc3RhbnRzLkFDQ19QUk9URUNURUQ7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfU0lHICAgICAgICAgCi0JPSAiTGphdmEvbGFuZy9TdHJpbmc7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfQlVGRkVSX1NJRyAgCi0JPSAiTGphdmEvbGFuZy9TdHJpbmdCdWZmZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPQkpFQ1RfU0lHICAgICAgICAgCi0JPSAiTGphdmEvbGFuZy9PYmplY3Q7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET1VCTEVfU0lHICAgICAgICAgCi0JPSAiTGphdmEvbGFuZy9Eb3VibGU7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlRFR0VSX1NJRyAgICAgICAgCi0JPSAiTGphdmEvbGFuZy9JbnRlZ2VyOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09MTEFUT1JfQ0xBU1MKLSAgICAgICAgPSAiamF2YS90ZXh0L0NvbGxhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT0xMQVRPUl9TSUcKLSAgICAgICAgPSAiTGphdmEvdGV4dC9Db2xsYXRvcjsiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERSAgICAgICAgICAgICAgIAotCT0gImludCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9JVEVSQVRPUiAgICAgIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTT1JUX0lURVJBVE9SICAgICAgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uU29ydGluZ0l0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTT1JUX0lURVJBVE9SX1NJRyAgICAgCi0JPSAiTG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLlNvcnRpbmdJdGVyYXRvcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJFVkVSU0VfSVRFUkFUT1IgICAgICAKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5SZXZlcnNlSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfU09SVF9SRUNPUkQgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uTm9kZVNvcnRSZWNvcmQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfU09SVF9GQUNUT1JZCi0JPSAib3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmRGYWN0b3J5IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1NPUlRfUkVDT1JEX1NJRyAKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmQ7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1NPUlRfRkFDVE9SWV9TSUcKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmRGYWN0b3J5OyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSU5HX1ZBTFVFX0hBTkRMRVIKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuU3RyaW5nVmFsdWVIYW5kbGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfVkFMVUVfSEFORExFUl9TSUcgCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9TdHJpbmdWYWx1ZUhhbmRsZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPVVRQVVRfSEFORExFUgotCT0gIm9yZy9hcGFjaGUveGFsYW4veHNsdGMvVHJhbnNsZXRPdXRwdXRIYW5kbGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPVVRQVVRfSEFORExFUl9TSUcKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldE91dHB1dEhhbmRsZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBURVhUX09VVFBVVAotCT0gIm9yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9UZXh0T3V0cHV0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBURVhUX09VVFBVVF9TSUcKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1RleHRPdXRwdXQ7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxURVJfSU5URVJGQUNFICAgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRmlsdGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxURVJfSU5URVJGQUNFX1NJRyAgIAotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9GaWx0ZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVTklPTl9JVEVSQVRPUl9DTEFTUwotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLlVuaW9uSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNURVBfSVRFUkFUT1JfQ0xBU1MKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5TdGVwSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5USF9JVEVSQVRPUl9DTEFTUwotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLk50aEl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBQlNPTFVURV9JVEVSQVRPUgotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkFic29sdXRlSXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERVUF9GSUxURVJFRF9JVEVSQVRPUgotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkR1cEZpbHRlckl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDVVJSRU5UX05PREVfTElTVF9JVEVSQVRPUgotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDVVJSRU5UX05PREVfTElTVF9GSUxURVIKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5DdXJyZW50Tm9kZUxpc3RGaWx0ZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENVUlJFTlRfTk9ERV9MSVNUX0lURVJBVE9SX1NJRyAKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0SXRlcmF0b3I7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDVVJSRU5UX05PREVfTElTVF9GSUxURVJfU0lHCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0N1cnJlbnROb2RlTGlzdEZpbHRlcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTFRFUl9TVEVQX0lURVJBVE9SIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkZpbHRlcmVkU3RlcEl0ZXJhdG9yIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxURVJfSVRFUkFUT1IgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRmlsdGVySXRlcmF0b3IiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNJTkdMRVRPTl9JVEVSQVRPUiAKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5TaW5nbGV0b25JdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFUQ0hJTkdfSVRFUkFUT1IgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uTWF0Y2hpbmdJdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9TSUcgICAgICAgICAgIAotCT0gIkkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9QQVJFTlQgICAgICAgICAKLQk9ICJnZXRQYXJlbnQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9QQVJFTlRfU0lHICAgICAKLQk9ICIoIiArIE5PREVfU0lHICsgIikiICsgTk9ERV9TSUc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkVYVF9TSUcgICAgICAgICAgIAotCT0gIigpIiArIE5PREVfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5FWFQgICAgICAgICAgICAgICAKLQk9ICJuZXh0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQUtFX05PREUgICAgICAgICAgCi0JPSAibWFrZU5vZGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1BS0VfTk9ERV9MSVNUICAgICAKLQk9ICJtYWtlTm9kZUxpc3QiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19UT19SRUFMICAgICAKLQk9ICJzdHJpbmdUb1JlYWwiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19UT19SRUFMX1NJRyAKLQk9ICIoIiArIFNUUklOR19TSUcgKyAiKUQiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19UT19JTlQgICAgIAotCT0gInN0cmluZ1RvSW50IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfVE9fSU5UX1NJRyAKLQk9ICIoIiArIFNUUklOR19TSUcgKyAiKUkiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWFNMVF9QQUNLQUdFICAgICAgIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENPTVBJTEVSX1BBQ0tBR0UgICAKLQk9IFhTTFRfUEFDS0FHRSArICIuY29tcGlsZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFJVTlRJTUVfUEFDS0FHRSAgICAKLQk9IFhTTFRfUEFDS0FHRSArICIucnVudGltZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfQ0xBU1MgICAgIAotCT0gUlVOVElNRV9QQUNLQUdFICsgIi5BYnN0cmFjdFRyYW5zbGV0IjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX1NJRyAgICAgICAgCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0OyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5JT05fSVRFUkFUT1JfU0lHICAKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vVW5pb25JdGVyYXRvcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX09VVFBVVF9CQVNFX1NJRyAgICAKLQk9ICJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldE91dHB1dEJhc2U7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9PVVRQVVRfU0lHICAgIAotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1RyYW5zbGV0T3V0cHV0SGFuZGxlcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1BS0VfTk9ERV9TSUcgICAgICAgCi0JPSAiKEkpTG9yZy93M2MvZG9tL05vZGU7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQUtFX05PREVfU0lHMiAgICAgIAotCT0gIigiICsgTk9ERV9JVEVSQVRPUl9TSUcgKyAiKUxvcmcvdzNjL2RvbS9Ob2RlOyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFLRV9OT0RFX0xJU1RfU0lHICAKLQk9ICIoSSlMb3JnL3czYy9kb20vTm9kZUxpc3Q7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNQUtFX05PREVfTElTVF9TSUcyIAotCT0gIigiICsgTk9ERV9JVEVSQVRPUl9TSUcgKyAiKUxvcmcvdzNjL2RvbS9Ob2RlTGlzdDsiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9BRF9ET0NVTUVOVF9DTEFTUwotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkxvYWREb2N1bWVudCI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfSU5ERVhfQ0xBU1MKLQk9ICJvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9LZXlJbmRleCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgS0VZX0lOREVYX1NJRwotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9LZXlJbmRleDsiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0lOVEYKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9NX0lNUEwKLQk9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5ET01JbXBsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJTkdfQ0xBU1MgCQkKLQk9ICJqYXZhLmxhbmcuU3RyaW5nIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBPQkpFQ1RfQ0xBU1MgCQkKLQk9ICJqYXZhLmxhbmcuT2JqZWN0IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCT09MRUFOX0NMQVNTIAkJCi0JPSAiamF2YS5sYW5nLkJvb2xlYW4iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNUUklOR19CVUZGRVJfQ0xBU1MKLQk9ICJqYXZhLmxhbmcuU3RyaW5nQnVmZmVyIjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRSQU5TTEVUX09VVFBVVF9CQVNFICAgICAgIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRPdXRwdXRCYXNlIjsKLSAgICAvLyBvdXRwdXQgaW50ZXJmYWNlCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRQotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRPdXRwdXRIYW5kbGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCQVNJU19MSUJSQVJZX0NMQVNTIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJJQlVURV9MSVNUX0lNUExfQ0xBU1MgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkF0dHJpYnV0ZUxpc3RJbXBsIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBET1VCTEVfQ0xBU1MgICAgICAgCi0JPSAiamF2YS5sYW5nLkRvdWJsZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5URUdFUl9DTEFTUyAgICAgIAotCT0gImphdmEubGFuZy5JbnRlZ2VyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSVU5USU1FX05PREVfQ0xBU1MgCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLk5vZGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1BVEhfQ0xBU1MgICAgICAgICAKLQk9ICJqYXZhLmxhbmcuTWF0aCI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCT09MRUFOX1ZBTFVFICAgICAgCi0JPSAiYm9vbGVhblZhbHVlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCT09MRUFOX1ZBTFVFX1NJRyAgCi0JPSAiKClaIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTlRfVkFMVUUgICAgICAgICAgCi0JPSAiaW50VmFsdWUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVF9WQUxVRV9TSUcgICAgICAKLQk9ICIoKUkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPVUJMRV9WQUxVRSAgICAgICAKLQk9ICJkb3VibGVWYWx1ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9VQkxFX1ZBTFVFX1NJRyAgIAotCT0gIigpRCI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1BOQU1FICAgICAgICAgCi0JPSAibm9kZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfT1VUUFVUX1BOQU1FIAotCT0gImhhbmRsZXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElURVJBVE9SX1BOQU1FICAgICAKLQk9ICJpdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRE9DVU1FTlRfUE5BTUUgICAgIAotCT0gImRvY3VtZW50IjsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX05BTUUgICAgICAKLQk9ICJnZXROb2RlTmFtZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0hBUkFDVEVSU1cgICAgICAgIAotCT0gImNoYXJhY3RlcnMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9DSElMRFJFTiAgICAgICAKLQk9ICJnZXRDaGlsZHJlbiI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX1RZUEVEX0NISUxEUkVOIAotCT0gImdldFR5cGVkQ2hpbGRyZW4iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENIQVJBQ1RFUlMgICAgICAgICAKLQk9ICJjaGFyYWN0ZXJzIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBUFBMWV9URU1QTEFURVMgICAgCi0JPSAiYXBwbHlUZW1wbGF0ZXMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX1RZUEUgICAgICAKLQk9ICJnZXROb2RlVHlwZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX05PREVfVkFMVUUgICAgIAotCT0gImdldE5vZGVWYWx1ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX0VMRU1FTlRfVkFMVUUgIAotCT0gImdldEVsZW1lbnRWYWx1ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX0FUVFJJQlVURV9WQUxVRSAgCi0JPSAiZ2V0QXR0cmlidXRlVmFsdWUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEhBU19BVFRSSUJVVEUgICAgICAKLQk9ICJoYXNBdHRyaWJ1dGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFERF9JVEVSQVRPUiAgICAgICAKLQk9ICJhZGRJdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VUX1NUQVJUX05PREUgICAgIAotCT0gInNldFN0YXJ0Tm9kZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTRVQgICAgIAkgICAgCi0JPSAicmVzZXQiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9TRVRfU0lHCi0JPSAiKCIgKyBUUkFOU0xFVF9PVVRQVVRfU0lHICsgTk9ERV9JVEVSQVRPUl9TSUcgKyAiKVYiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX05PREVfTkFNRV9TSUcgICAKLQk9ICIoIiArIE5PREVfU0lHICsgIikiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDSEFSQUNURVJTV19TSUcgICAgIAotCT0gIigiICArIFNUUklOR19TSUcgKyBUUkFOU0xFVF9PVVRQVVRfU0lHICsgIilWIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDSEFSQUNURVJTX1NJRyAgICAgCi0JPSAiKCIgKyBOT0RFX1NJRyArIFRSQU5TTEVUX09VVFBVVF9TSUcgKyAiKVYiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9DSElMRFJFTl9TSUcKLQk9ICIoIiArIE5PREVfU0lHICsiKSIgKyBOT0RFX0lURVJBVE9SX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfVFlQRURfQ0hJTERSRU5fU0lHCi0JPSAiKEkpIiArIE5PREVfSVRFUkFUT1JfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEdFVF9OT0RFX1RZUEVfU0lHCi0JPSAiKClTIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfTk9ERV9WQUxVRV9TSUcKLQk9ICIoSSkiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfRUxFTUVOVF9WQUxVRV9TSUcKLQk9ICIoSSkiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfQVRUUklCVVRFX1ZBTFVFX1NJRwotCT0gIihJSSkiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBIQVNfQVRUUklCVVRFX1NJRwotCT0gIihJSSlaIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfSVRFUkFUT1JfU0lHCi0JPSAiKCkiICsgTk9ERV9JVEVSQVRPUl9TSUc7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU19JTkRFWAotCT0gIm5hbWVzQXJyYXkiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUVTX0lOREVYX1NJRwotCT0gIlsiICsgU1RSSU5HX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfSU5ERVgKLQk9ICJuYW1lc3BhY2VBcnJheSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0lOREVYX1NJRwotCT0gIlsiICsgU1RSSU5HX1NJRzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERPTV9GSUVMRAotCT0gIl9kb20iOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9TWU1CT0xTX0ZJRUxECSAKLQk9ICJmb3JtYXRfc3ltYm9scyI7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJVEVSQVRPUl9GSUVMRF9TSUcgICAgICAKLQk9IE5PREVfSVRFUkFUT1JfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfRklFTEQJCSAKLQk9ICJub2RlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX0ZJRUxEX1NJRwkJIAotCT0gIkkiOwotCQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZQVRUUl9GSUVMRAkgICAgIAotCT0gIkVtcHR5QXR0cmlidXRlcyI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUklCVVRFX0xJU1RfRklFTEQgICAgCi0JPSAiYXR0cmlidXRlTGlzdCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xFQVJfQVRUUklCVVRFUyAgICAgICAgCi0JPSAiY2xlYXIiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFERF9BVFRSSUJVVEUgICAgICAgICAgIAotCT0gImFkZEF0dHJpYnV0ZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUklCVVRFX0xJU1RfSU1QTF9TSUcgCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9BdHRyaWJ1dGVMaXN0SW1wbDsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENMRUFSX0FUVFJJQlVURVNfU0lHICAgIAotCT0gIigpIiArIEFUVFJJQlVURV9MSVNUX0lNUExfU0lHOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFERF9BVFRSSUJVVEVfU0lHICAgCi0JPSAiKCIgKyBTVFJJTkdfU0lHICsgU1RSSU5HX1NJRyArICIpIiArIEFUVFJJQlVURV9MSVNUX0lNUExfU0lHOwotCQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFERF9JVEVSQVRPUl9TSUcgICAKLQk9ICIoIiArIE5PREVfSVRFUkFUT1JfU0lHICsiKSIgKyBVTklPTl9JVEVSQVRPUl9TSUc7Ci0JCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VUX1NUQVJUX05PREVfU0lHICAgCi0JPSAiKCIgKyBOT0RFX1NJRyArICIpIiArIE5PREVfSVRFUkFUT1JfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9DT1VOVEVSIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLk5vZGVDb3VudGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX0NPVU5URVJfU0lHIAotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Ob2RlQ291bnRlcjsiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfTk9ERV9DT1VOVEVSIAotCT0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRlZmF1bHROb2RlQ291bnRlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9OT0RFX0NPVU5URVJfU0lHIAotCT0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9EZWZhdWx0Tm9kZUNvdW50ZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9GSUVMRCAKLQk9ICJ0cmFuc2xldCI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNMRVRfRklFTERfU0lHIAotCT0gVFJBTlNMRVRfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTRVRfU0lHICAgCSAgICAgICAKLQk9ICIoKSIgKyBOT0RFX0lURVJBVE9SX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfUEFSQU1FVEVSICAgICAgCi0JPSAiZ2V0UGFyYW1ldGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBRERfUEFSQU1FVEVSICAgICAgICAgCi0JPSAiYWRkUGFyYW1ldGVyIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQVVNIX1BBUkFNX0ZSQU1FCi0JPSAicHVzaFBhcmFtRnJhbWUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBVU0hfUEFSQU1fRlJBTUVfU0lHICAKLQk9ICIoKVYiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBPUF9QQVJBTV9GUkFNRSAgICAgICAKLQk9ICJwb3BQYXJhbUZyYW1lIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQT1BfUEFSQU1fRlJBTUVfU0lHICAgCi0JPSAiKClWIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfUEFSQU1FVEVSX1NJRyAgICAgCi0JPSAiKCIgKyBTVFJJTkdfU0lHICsgIikiICsgT0JKRUNUX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBRERfUEFSQU1FVEVSX1NJRwotCT0gIigiICsgU1RSSU5HX1NJRyArIE9CSkVDVF9TSUcgKyAiWikiICsgT0JKRUNUX1NJRzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQVVNIX1ZBUl9GUkFNRQotCT0gInB1c2hWYXJGcmFtZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFVTSF9WQVJfRlJBTUVfU0lHCi0JPSAiKEkpViI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUE9QX1ZBUl9GUkFNRQotCT0gInBvcFZhckZyYW1lIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQT1BfVkFSX0ZSQU1FX1NJRwotCT0gIigpViI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUREX1ZBUklBQkxFCi0JPSAiYWRkVmFyaWFibGUiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFERF9WQVJJQUJMRV9TSUcKLQk9ICIoSSIgKyBPQkpFQ1RfU0lHICsgIilWIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBHRVRfVkFSSUFCTEUKLQk9ICJnZXRWYXJpYWJsZSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX1ZBUklBQkxFX1NJRwotCT0gIihJKSIgKyBPQkpFQ1RfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSVBfU1BBQ0UKLQk9ICJzdHJpcFNwYWNlIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJUF9TUEFDRV9JTlRGCi0JPSAib3JnL2FwYWNoZS94YWxhbi94c2x0Yy9TdHJpcEZpbHRlciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RSSVBfU1BBQ0VfU0lHCi0JPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvU3RyaXBGaWx0ZXI7IjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVFJJUF9TUEFDRV9QQVJBTVMKLQk9ICIoTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvRE9NO0lJKVoiOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX05PREVfVkFMVUVfSVRFUkFUT1IKLQk9ICJnZXROb2RlVmFsdWVJdGVyYXRvciI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR0VUX05PREVfVkFMVUVfSVRFUkFUT1JfU0lHCi0JPSAiKCIrTk9ERV9JVEVSQVRPUl9TSUcrU1RSSU5HX1NJRysiWikiK05PREVfSVRFUkFUT1JfU0lHOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUE9TSVRJT05fSU5ERVggPSAyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExBU1RfSU5ERVggICAgID0gMzsKLQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTFRfVVJJCi0JPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVF9VUkkKLQk9ICJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4veHNsdGMiOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZBTExCQUNLX0NMQVNTCi0JPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5GYWxsYmFjayI7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Db250YWluc0NhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbnRhaW5zQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMmIyOGNmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvbnRhaW5zQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuRXJyb3JNc2c7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgQ29udGFpbnNDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfYmFzZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF90b2tlbiA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBjb250YWlucygpIGNhbGwgLSB0d28gYXJndW1lbnRzLCBib3RoIHN0cmluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgQ29udGFpbnNDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBYUGF0aCBmdW5jdGlvbiByZXR1cm5zIHRydWUvZmFsc2UgdmFsdWVzCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNCb29sZWFuKCkgewotCXJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgdGhlIHR3byBwYXJhbWV0ZXJzIGZvciB0aGlzIGZ1bmN0aW9uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQotCS8vIENoZWNrIHRoYXQgdGhlIGZ1bmN0aW9uIHdhcyBwYXNzZWQgZXhhY3RseSB0d28gYXJndW1lbnRzCi0JaWYgKGFyZ3VtZW50Q291bnQoKSAhPSAyKSB7Ci0JICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5GVU5SRVNPTF9FUlIsIGdldE5hbWUoKSk7Ci0JfQotCi0JLy8gVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBTdHJpbmcsIG9yIGNhc3QgdG8gYSBTdHJpbmcKLQlfYmFzZSA9IGFyZ3VtZW50KDApOwotCVR5cGUgYmFzZVR5cGUgPSBfYmFzZS50eXBlQ2hlY2soc3RhYmxlKTsJCi0JaWYgKGJhc2VUeXBlICE9IFR5cGUuU3RyaW5nKQotCSAgICBfYmFzZSA9IG5ldyBDYXN0RXhwcihfYmFzZSwgVHlwZS5TdHJpbmcpOwotCi0JLy8gVGhlIHNlY29uZCBhcmd1bWVudCBtdXN0IGFsc28gYmUgYSBTdHJpbmcsIG9yIGNhc3QgdG8gYSBTdHJpbmcKLQlfdG9rZW4gPSBhcmd1bWVudCgxKTsKLQlUeXBlIHRva2VuVHlwZSA9IF90b2tlbi50eXBlQ2hlY2soc3RhYmxlKTsJCi0JaWYgKHRva2VuVHlwZSAhPSBUeXBlLlN0cmluZykKLQkgICAgX3Rva2VuID0gbmV3IENhc3RFeHByKF90b2tlbiwgVHlwZS5TdHJpbmcpOwotCi0JcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgdGhlIGV4cHJlc3Npb24gLSBsZWF2ZSBib29sZWFuIGV4cHJlc3Npb24gb24gc3RhY2sKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQl0cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCXN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSBleHByZXNzaW9uIGFuZCB1cGRhdGUgdHJ1ZS9mYWxzZS1saXN0cwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCV9iYXNlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlfdG9rZW4udHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19DTEFTUywKLQkJCQkJCSAgICAgImluZGV4T2YiLAotCQkJCQkJICAgICAiKCIrU1RSSU5HX1NJRysiKUkiKSkpOwotCV9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZMVChudWxsKSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvcHkuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvcHkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGJmMDFlOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Db3B5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBDb3B5IGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICAgIHByaXZhdGUgVXNlQXR0cmlidXRlU2V0cyBfdXNlU2V0czsKLSAgICAKLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQlmaW5hbCBTdHJpbmcgdXNlU2V0cyA9IGdldEF0dHJpYnV0ZSgidXNlLWF0dHJpYnV0ZS1zZXRzIik7Ci0JaWYgKHVzZVNldHMubGVuZ3RoKCkgPiAwKSB7Ci0JICAgIF91c2VTZXRzID0gbmV3IFVzZUF0dHJpYnV0ZVNldHModXNlU2V0cywgcGFyc2VyKTsKLQl9Ci0JcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIkNvcHkiKTsKLQlpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQlkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWlmIChfdXNlU2V0cyAhPSBudWxsKSB7Ci0JICAgIF91c2VTZXRzLnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQl0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIG5hbWUgPQotCSAgICBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZTIoIm5hbWUiLAotCQkJCQlVdGlsLmdldEpDUmVmVHlwZShTVFJJTkdfU0lHKSwKLQkJCQkJaWwuZ2V0RW5kKCkpOwotCWZpbmFsIExvY2FsVmFyaWFibGVHZW4gbGVuZ3RoID0KLQkgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJsZW5ndGgiLAotCQkJCQlVdGlsLmdldEpDUmVmVHlwZSgiSSIpLAotCQkJCQlpbC5nZXRFbmQoKSk7Ci0KLQkvLyBHZXQgdGhlIG5hbWUgb2YgdGhlIG5vZGUgdG8gY29weSBhbmQgc2F2ZSBmb3IgbGF0ZXIKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlmaW5hbCBpbnQgY3B5ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgInNoYWxsb3dDb3B5IiwKLQkJCQkJCSAgIigiCi0JCQkJCQkgICsgTk9ERV9TSUcKLQkJCQkJCSAgKyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0JCQkJCQkgICsgIikiICsgU1RSSU5HX1NJRyk7IAotCWlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGNweSwgMykpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChuZXcgQVNUT1JFKG5hbWUuZ2V0SW5kZXgoKSkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrMSA9IGlsLmFwcGVuZChuZXcgSUZOVUxMKG51bGwpKTsKLQotCS8vIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBub2RlIG5hbWUgYW5kIHNhdmUgZm9yIGxhdGVyCi0JaWwuYXBwZW5kKG5ldyBBTE9BRChuYW1lLmdldEluZGV4KCkpKTsKLQlmaW5hbCBpbnQgbGVuZ3RoTWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsImxlbmd0aCIsIigpSSIpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChsZW5ndGhNZXRob2QpKTsKLQlpbC5hcHBlbmQobmV3IElTVE9SRShsZW5ndGguZ2V0SW5kZXgoKSkpOwotCi0JLy8gQ29weSBpbiBhdHRyaWJ1dGUgc2V0cyBpZiBzcGVjaWZpZWQKLQlpZiAoX3VzZVNldHMgIT0gbnVsbCkgewotCSAgICAvLyBJZiB0aGUgcGFyZW50IG9mIHRoaXMgZWxlbWVudCB3aWxsIHJlc3VsdCBpbiBhbiBlbGVtZW50IGJlaW5nCi0JICAgIC8vIG91dHB1dCB0aGVuIHdlIGtub3cgdGhhdCBpdCBpcyBzYWZlIHRvIGNvcHkgb3V0IHRoZSBhdHRyaWJ1dGVzCi0JICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCSAgICBpZiAoKHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSB8fAotCQkocGFyZW50IGluc3RhbmNlb2YgTGl0ZXJhbEVsZW1lbnQpKSB7Ci0JCV91c2VTZXRzLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgfQotCSAgICAvLyBJZiBub3Qgd2UgaGF2ZSB0byBjaGVjayB0byBzZWUgaWYgdGhlIGNvcHkgd2lsbCByZXN1bHQgaW4gYW4KLQkgICAgLy8gZWxlbWVudCBiZWluZyBvdXRwdXQuCi0JICAgIGVsc2UgewotCQkvLyBjaGVjayBpZiBlbGVtZW50OyBpZiBub3Qgc2tpcCB0byB0cmFuc2xhdGUgYm9keQotCQlpbC5hcHBlbmQobmV3IElMT0FEKGxlbmd0aC5nZXRJbmRleCgpKSk7Ci0JCWZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrMiA9IGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSk7Ci0JCS8vIGxlbmd0aCAhPSAwIC0+IGVsZW1lbnQgLT4gZG8gYXR0cmlidXRlIHNldHMKLQkJX3VzZVNldHMudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQkvLyBub3QgYW4gZWxlbWVudDsgcm9vdAotCQlpZkJsb2NrMi5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotCSAgICB9Ci0JfQotCi0JLy8gSW5zdGFudGlhdGUgYm9keSBvZiB4c2w6Y29weQotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gQ2FsbCB0aGUgb3V0cHV0IGhhbmRsZXIncyBlbmRFbGVtZW50KCkgaWYgd2UgY29waWVkIGFuIGVsZW1lbnQKLQkvLyAoVGhlIERPTS5zaGFsbG93Q29weSgpIG1ldGhvZCBjYWxscyBzdGFydEVsZW1lbnQoKS4pCi0JaWwuYXBwZW5kKG5ldyBJTE9BRChsZW5ndGguZ2V0SW5kZXgoKSkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrMyA9IGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IEFMT0FEKG5hbWUuZ2V0SW5kZXgoKSkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4uZW5kRWxlbWVudCgpKTsKLQkKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBlbmQgPSBpbC5hcHBlbmQoTk9QKTsKLQlpZkJsb2NrMS5zZXRUYXJnZXQoZW5kKTsKLQlpZkJsb2NrMy5zZXRUYXJnZXQoZW5kKTsKLQltZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShuYW1lKTsKLQltZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShsZW5ndGgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0NvcHlPZi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ29weU9mLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIzMTY1ZjAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvQ29weU9mLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIENvcHlPZiBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3NlbGVjdDsKLQkKLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIkNvcHlPZiIpOwotCWluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCVV0aWwucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCV9zZWxlY3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJzZWxlY3QiLCBudWxsKTsKLSAgICAgICAgLy8gbWFrZSBzdXJlIHJlcXVpcmVkIGF0dHJpYnV0ZShzKSBoYXZlIGJlZW4gc2V0Ci0gICAgICAgIGlmIChfc2VsZWN0LmlzRHVtbXkoKSkgewotCSAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLk5SRVFBVFRSX0VSUiwgInNlbGVjdCIpOwotCSAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICB9Ci0JCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBUeXBlIHRzZWxlY3QgPSBfc2VsZWN0LnR5cGVDaGVjayhzdGFibGUpOwotCWlmICh0c2VsZWN0IGluc3RhbmNlb2YgTm9kZVR5cGUgfHwKLQkgICAgdHNlbGVjdCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlIHx8Ci0JICAgIHRzZWxlY3QgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlIHx8Ci0JICAgIHRzZWxlY3QgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotCSAgICAvLyBmYWxscyB0aHJvdWdoIAotCX0KLQllbHNlIHsKLQkgICAgX3NlbGVjdCA9IG5ldyBDYXN0RXhwcihfc2VsZWN0LCBUeXBlLlN0cmluZyk7Ci0JfQotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgVHlwZSB0c2VsZWN0ID0gX3NlbGVjdC5nZXRUeXBlKCk7Ci0KLQlmaW5hbCBTdHJpbmcgQ1BZMV9TSUcgPSAiKCIrTk9ERV9JVEVSQVRPUl9TSUcrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiOwotCWZpbmFsIGludCBjcHkxID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwgImNvcHkiLCBDUFkxX1NJRyk7Ci0KLQlmaW5hbCBTdHJpbmcgQ1BZMl9TSUcgPSAiKCIrTk9ERV9TSUcrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiOwotCWZpbmFsIGludCBjcHkyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwgImNvcHkiLCBDUFkyX1NJRyk7Ci0KLQlpZiAodHNlbGVjdCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQotCSAgICAvLyBwdXNoIE5vZGVJdGVyYXRvcgotCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsJCi0JICAgIF9zZWxlY3Quc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JICAgIC8vIGNhbGwgY29weSBmcm9tIHRoZSBET00gJ2xpYnJhcnknCi0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGNweTEsIDMpKTsKLQl9Ci0JZWxzZSBpZiAodHNlbGVjdCBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgX3NlbGVjdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7CQotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjcHkyLCAzKSk7Ci0JfQotCWVsc2UgaWYgKHRzZWxlY3QgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsJCi0JICAgIC8vIFdlIHdhbnQgdGhlIHdob2xlIHRyZWUsIHNvIHdlIHN0YXJ0IHdpdGggdGhlIHJvb3Qgbm9kZQotCSAgICBpbC5hcHBlbmQoSUNPTlNUXzEpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjcHkyLCAzKSk7Ci0JfQotCWVsc2UgaWYgKHRzZWxlY3QgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSB7Ci0JICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCSAgICBmaW5hbCBpbnQgY29weSA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgImNvcHkiLAotCQkJCQkgICAgICAiKCIgCi0JCQkJCSAgICAgICsgT0JKRUNUX1NJRyAgCi0JCQkJCSAgICAgICsgVFJBTlNMRVRfT1VUUFVUX1NJRyAKLQkJCQkJICAgICAgKyBOT0RFX1NJRwotCQkJCQkgICAgICArIERPTV9JTlRGX1NJRwotCQkJCQkgICAgICArICIpViIpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjb3B5KSk7Ci0JfQotCWVsc2UgewotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsJCi0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJCSBDSEFSQUNURVJTVywKLQkJCQkJCQkgQ0hBUkFDVEVSU1dfU0lHKSkpOwotCX0KLQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0N1cnJlbnRDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9DdXJyZW50Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzZDUyNjMzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0N1cnJlbnRDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEN1cnJlbnRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgQ3VycmVudENhbGwoUU5hbWUgZm5hbWUpIHsKLQlzdXBlcihmbmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0RlY2ltYWxGb3JtYXR0aW5nLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9EZWNpbWFsRm9ybWF0dGluZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMzJkNzllLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0RlY2ltYWxGb3JtYXR0aW5nLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTggKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLQotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0OwotaW1wb3J0IGphdmEudGV4dC5EZWNpbWFsRm9ybWF0U3ltYm9sczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5BdHRyaWJ1dGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgRGVjaW1hbEZvcm1hdHRpbmcgZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERGU19DTEFTUyA9ICJqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHMiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERlNfU0lHICAgPSAiTGphdmEvdGV4dC9EZWNpbWFsRm9ybWF0U3ltYm9sczsiOwotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIHRoZSBjb25zdHJ1Y3RvciBpcyBjb21waWxlZCBpbgotICAgICAqIFN0eWxlc2hlZXQuY29tcGlsZUNvbnN0cnVjdG9yKCkgYW5kIG5vdCBhcyB0aGUgc3ludGF4IHRyZWUgaXMgdHJhdmVyc2VkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0JQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQkKLQkvLyBEZWNpbWFsRm9ybWF0U3ltYm9scy48aW5pdD4oKTsKLQlmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLCAiPGluaXQ+IiwgIigpViIpOwotCi0JLy8gUHVzaCB0aGUgZm9ybWF0IG5hbWUgb24gdGhlIHN0YWNrIGZvciBjYWxsIHRvIGFkZERlY2ltYWxGb3JtYXQoKQotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZ2V0QXR0cmlidXRlKCJuYW1lIikpKTsKLQotCS8vIE1hbnVmYWN0dXJlIGEgRGVjaW1hbEZvcm1hdFN5bWJvbHMgb24gdGhlIHN0YWNrCi0JLy8gZm9yIGNhbGwgdG8gYWRkRGVjaW1hbEZvcm1hdCgpCi0JaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKERGU19DTEFTUykpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotCQotCWZpbmFsIGludCBuQXR0cmlidXRlcyA9IF9hdHRyaWJ1dGVzLmdldExlbmd0aCgpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbkF0dHJpYnV0ZXM7IGkrKykgewotCSAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IF9hdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwotCSAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBfYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotCSAgICBib29sZWFuIHZhbGlkID0gdHJ1ZTsKLQkgICAgaW50IG1ldGhvZCA9IDA7Ci0KLQkgICAgaWYgKG5hbWUuZXF1YWxzKCJkZWNpbWFsLXNlcGFyYXRvciIpKSB7Ci0JCS8vIERlY2ltYWxGb3JtYXRTeW1ib2xzLnNldERlY2ltYWxTZXBhcmF0b3IoKTsKLQkJbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0JCQkJCSAgInNldERlY2ltYWxTZXBhcmF0b3IiLCAiKEMpViIpOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJncm91cGluZy1zZXBhcmF0b3IiKSkgewotCQltZXRob2QgPSAgY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0JCQkJCSAgICJzZXRHcm91cGluZ1NlcGFyYXRvciIsICIoQylWIik7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIm1pbnVzLXNpZ24iKSkgewotCQltZXRob2QgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLQkJCQkJICAic2V0TWludXNTaWduIiwgIihDKVYiKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygicGVyY2VudCIpKSB7Ci0JCW1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotCQkJCQkgICJzZXRQZXJjZW50IiwgIihDKVYiKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygicGVyLW1pbGxlIikpIHsKLQkJbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0JCQkJCSAgInNldFBlck1pbGwiLCAiKEMpViIpOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJ6ZXJvLWRpZ2l0IikpIHsKLQkJbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0JCQkJCSAgInNldFplcm9EaWdpdCIsICIoQylWIik7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImRpZ2l0IikpIHsKLQkJbWV0aG9kID0gY3BnLmFkZE1ldGhvZHJlZihERlNfQ0xBU1MsCi0JCQkJCSAgInNldERpZ2l0IiwgIihDKVYiKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygicGF0dGVybi1zZXBhcmF0b3IiKSkgewotCQltZXRob2QgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywKLQkJCQkJICAic2V0UGF0dGVyblNlcGFyYXRvciIsICIoQylWIik7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoIk5hTiIpKSB7Ci0JCW1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotCQkJCQkgICJzZXROYU4iLCAiKExqYXZhL2xhbmcvU3RyaW5nOylWIik7Ci0JICAgICAgICBpbC5hcHBlbmQoRFVQKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgdmFsdWUpKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKG1ldGhvZCkpOwotCQl2YWxpZCA9IGZhbHNlOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJpbmZpbml0eSIpKSB7Ci0JCW1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoREZTX0NMQVNTLAotCQkJCQkgICJzZXRJbmZpbml0eSIsCi0JCQkJCSAgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotCSAgICAgICAgaWwuYXBwZW5kKERVUCk7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHZhbHVlKSk7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChtZXRob2QpKTsKLQkJdmFsaWQgPSBmYWxzZTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJdmFsaWQgPSBmYWxzZTsKLQkgICAgfQotCi0JICAgIGlmICh2YWxpZCkgewotCQlpbC5hcHBlbmQoRFVQKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgdmFsdWUuY2hhckF0KDApKSk7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChtZXRob2QpKTsKLQkgICAgfQotCi0JfQotCi0JZmluYWwgaW50IHB1dCA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCSAiYWRkRGVjaW1hbEZvcm1hdCIsCi0JCQkJCSAiKCIrU1RSSU5HX1NJRytERlNfU0lHKyIpViIpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChwdXQpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIHRoZSBkZWZhdWx0LCBuYW1lbGVzcywgRGVjaW1hbEZvcm1hdCBvYmplY3QgaW4KLSAgICAgKiBBYnN0cmFjdFRyYW5zbGV0J3MgZm9ybWF0X3N5bWJvbHMgaGFzaHRhYmxlLgotICAgICAqIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBmb3IgZXZlcnkgc3R5bGVzaGVldCwgYW5kIHRoZSBlbnRyeQotICAgICAqIG1heSBiZSBvdmVycmlkZGVuIGJ5IGxhdGVyIG5hbWVsZXNzIHhzbDpkZWNpbWFsLWZvcm1hdCBpbnN0cnVjdGlvbnMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHRyYW5zbGF0ZURlZmF1bHRERlMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJCSAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotCUNvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgaW50IGluaXQgPSBjcGcuYWRkTWV0aG9kcmVmKERGU19DTEFTUywgIjxpbml0PiIsICIoKVYiKTsKLQotCS8vIFB1c2ggdGhlIGZvcm1hdCBuYW1lLCB3aGljaCBpcyBlbXB0eSwgb24gdGhlIHN0YWNrCi0JLy8gZm9yIGNhbGwgdG8gYWRkRGVjaW1hbEZvcm1hdCgpCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBDb25zdGFudHMuRU1QVFlTVFJJTkcpKTsKLQotCS8vIE1hbnVmYWN0dXJlIGEgRGVjaW1hbEZvcm1hdFN5bWJvbHMgb24gdGhlIHN0YWNrCi0JLy8gZm9yIGNhbGwgdG8gYWRkRGVjaW1hbEZvcm1hdCgpCi0JaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKERGU19DTEFTUykpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotCi0JZmluYWwgaW50IHB1dCA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCSAiYWRkRGVjaW1hbEZvcm1hdCIsCi0JCQkJCSAiKCIrU1RSSU5HX1NJRytERlNfU0lHKyIpViIpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChwdXQpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Eb2N1bWVudENhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0RvY3VtZW50Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNDkzNTczLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0RvY3VtZW50Q2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5FcnJvck1zZzsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBEb2N1bWVudENhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF91cmkgPSBudWxsOwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfYmFzZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBUeXBlICAgICAgIF91cmlUeXBlOwotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBmdW5jdGlvbiBjYWxsIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIERvY3VtZW50Q2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2tzIHRoZSBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uLiBUaGUgZmlyc3QKLSAgICAgKiBhcmd1bWVudCBjYW4gYmUgYW55IHR5cGUgKHdlIG11c3QgY2FzdCBpdCB0byBhIHN0cmluZykgYW5kIGNvbnRhaW5zIHRoZQotICAgICAqIFVSSSBvZiB0aGUgZG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCS8vIEF0IGxlYXN0IG9uZSBhcmd1bWVudCAtIHR3byBhdCBtb3N0Ci0JZmluYWwgaW50IGFjID0gYXJndW1lbnRDb3VudCgpOwotCWlmICgoYWMgPCAxKSB8fCAoYWMgPiAyKSkgewotCSAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coIklsbGVnYWwgbnVtYmVyIG9mIGFyZ3VtZW50cyAiKwotCQkJCQkidG8gZG9jdW1lbnQoKSBmdW5jdGlvbiIpOwotCSAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobXNnKTsKLQl9Ci0KLQkvLyBQYXJzZSB0aGUgZmlyc3QgYXJndW1lbnQgLSB0aGUgZG9jdW1lbnQgVVJJCi0JX3VyaSA9IGFyZ3VtZW50KDApOwotCWlmIChfdXJpIGluc3RhbmNlb2YgTGl0ZXJhbEV4cHIpIHsKLQkgICAgTGl0ZXJhbEV4cHIgZXhwciA9IChMaXRlcmFsRXhwcilfdXJpOwotCSAgICBpZiAoZXhwci5nZXRWYWx1ZSgpLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSB7Ci0JCVN0eWxlc2hlZXQgc3R5bGVzaGVldCA9IGdldFN0eWxlc2hlZXQoKTsKLQkJaWYgKHN0eWxlc2hlZXQgPT0gbnVsbCkgewotCQkgICAgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKCJJbGxlZ2FsIGFyZ3VtZW50ICIrCi0JCQkJCQkidG8gZG9jdW1lbnQoKSBmdW5jdGlvbiIpOwotCQkgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKG1zZyk7Ci0JCX0KLQkJX3VyaSA9IG5ldyBMaXRlcmFsRXhwcihzdHlsZXNoZWV0LmdldFN5c3RlbUlkKCksCi0JCQkJICAgICAgIENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0JICAgIH0KLQl9Ci0KLQlfdXJpVHlwZSA9IF91cmkudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKChfdXJpVHlwZSAhPSBUeXBlLk5vZGVTZXQpICYmIChfdXJpVHlwZSAhPSBUeXBlLlN0cmluZykpIHsKLQkgICAgX3VyaSA9IG5ldyBDYXN0RXhwcihfdXJpLCBUeXBlLlN0cmluZyk7Ci0JfQotCi0JLy8gUGFyc2UgdGhlIHNlY29uZCBhcmd1bWVudCAtIHRoZSBkb2N1bWVudCBVUkkgYmFzZQotCWlmIChhYyA9PSAyKSB7Ci0JICAgIF9iYXNlID0gYXJndW1lbnQoMSk7Ci0JICAgIGlmICghX2Jhc2UudHlwZUNoZWNrKHN0YWJsZSkuaWRlbnRpY2FsVG8oVHlwZS5Ob2RlU2V0KSkgewotCQlFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coIlNlY29uZCBhcmd1bWVudCB0byBkb2N1bWVudCgpICIrCi0JCQkJCSAgICAiZnVuY3Rpb24gbXVzdCBiZSBhIG5vZGUtc2V0LiIpOwotCQl0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobXNnKTsKLQkgICAgfQotCX0KLQotCXJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLSAgICB9Ci0JCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbiBjYWxsIHRvIGEgY2FsbCB0byBMb2FkRG9jdW1lbnQoKSdzCi0gICAgICogc3RhdGljIG1ldGhvZCBkb2N1bWVudCgpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlmaW5hbCBpbnQgZG9tRmllbGQgPSBjcGcuYWRkRmllbGRyZWYoY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCSAgICAgRE9NX0ZJRUxELAotCQkJCQkgICAgIERPTV9JTlRGX1NJRyk7Ci0JZmluYWwgU3RyaW5nIGRvY1BhcmFtTGlzdCA9Ci0JICAgICIoIitPQkpFQ1RfU0lHK1NUUklOR19TSUcrVFJBTlNMRVRfU0lHK0RPTV9JTlRGX1NJRysiKSIrCi0JICAgIE5PREVfSVRFUkFUT1JfU0lHOwotCWZpbmFsIGludCBkb2NJZHggPSBjcGcuYWRkTWV0aG9kcmVmKExPQURfRE9DVU1FTlRfQ0xBU1MsCi0JCQkJCSAgICAiZG9jdW1lbnQiLCBkb2NQYXJhbUxpc3QpOwotCi0JZmluYWwgaW50IHVyaUlkeCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgICJnZXREb2N1bWVudFVSSSIsCi0JCQkJCQkgICAgICIoSSkiK1NUUklOR19TSUcpOwotCi0JZmluYWwgaW50IG5leHRJZHggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0JCQkJCQkgICAgICBORVhULCBORVhUX1NJRyk7Ci0KLQkvLyBUaGUgVVJJIGNhbiBiZSBlaXRoZXIgYSBub2RlLXNldCBvciBzb21ldGhpbmcgZWxzZSBjYXN0IHRvIGEgc3RyaW5nCi0JX3VyaS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JaWYgKF91cmlUeXBlID09IFR5cGUuTm9kZVNldCkKLQkgICAgX3VyaS5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkvLyBUaGUgYmFzZSBvZiB0aGUgVVJJIG1heSBiZSBnaXZlbiBhcyBhIHNlY29uZCBhcmd1bWVudCAoYSBub2RlLXNldCkKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWYgKF9iYXNlICE9IG51bGwpIHsKLQkgICAgX2Jhc2UudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShuZXh0SWR4LCAxKSk7Ci0JfQotCWVsc2UgewotCSAgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JfQotCWlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKHVyaUlkeCwgMikpOwotCi0JLy8gRmVjayB0aGUgcmVzdCBvZiB0aGUgcGFyYW1ldGVycyBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChuZXcgR0VURklFTEQoZG9tRmllbGQpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhkb2NJZHgpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9FbGVtZW50QXZhaWxhYmxlQ2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRWxlbWVudEF2YWlsYWJsZUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTJmMGEzNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9FbGVtZW50QXZhaWxhYmxlQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBFbGVtZW50QXZhaWxhYmxlQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0KLSAgICBwdWJsaWMgRWxlbWVudEF2YWlsYWJsZUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3JjZSB0aGUgYXJndW1lbnQgdG8gdGhpcyBmdW5jdGlvbiB0byBiZSBhIGxpdGVyYWwgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKGFyZ3VtZW50KCkgaW5zdGFuY2VvZiBMaXRlcmFsRXhwcikgewotCSAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0JfQotCXRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5MSVRFUkFMU19FUlIsICJlbGVtZW50LWF2YWlsYWJsZSIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHJlc3VsdCB0aGF0IHRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXN1bHQoKSB7Ci0JZmluYWwgUGFyc2VyIHBhcnNlciA9IGdldFBhcnNlcigpOwotCWZpbmFsIExpdGVyYWxFeHByIGFyZyA9IChMaXRlcmFsRXhwcilhcmd1bWVudCgpOwotCWZpbmFsIFFOYW1lIHFuYW1lID0gcGFyc2VyLmdldFFOYW1lKGFyZy5nZXRWYWx1ZSgpKTsKLQlyZXR1cm4ocGFyc2VyLmVsZW1lbnRTdXBwb3J0ZWQocW5hbWUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYWxscyB0byAnZWxlbWVudC1hdmFpbGFibGUnIGFyZSByZXNvbHZlZCBhdCBjb21waWxlIHRpbWUgc2luY2UgCi0gICAgICogdGhlIG5hbWVzcGFjZXMgZGVjbGFyZWQgaW4gdGhlIHN0eWxzaGVldCBhcmUgbm90IGF2YWlsYWJsZSBhdCBydW4KLSAgICAgKiB0aW1lLiBDb25zZXF1ZW50bHksIGFyZ3VtZW50cyB0byB0aGlzIGZ1bmN0aW9uIG11c3QgYmUgbGl0ZXJhbHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIGJvb2xlYW4gcmVzdWx0ID0gZ2V0UmVzdWx0KCk7Ci0JbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChuZXcgUFVTSChjcGcsIHJlc3VsdCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0VxdWFsaXR5RXhwci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRXF1YWxpdHlFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiZTQzZTcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRXF1YWxpdHlFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNjQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5PcGVyYXRvcnM7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgRXF1YWxpdHlFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiBpbXBsZW1lbnRzIE9wZXJhdG9ycyB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX29wOwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfbGVmdDsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3JpZ2h0OwotCQkKLSAgICBwdWJsaWMgRXF1YWxpdHlFeHByKGludCBvcCwgRXhwcmVzc2lvbiBsZWZ0LCBFeHByZXNzaW9uIHJpZ2h0KSB7Ci0JX29wID0gb3A7Ci0JKF9sZWZ0ID0gbGVmdCkuc2V0UGFyZW50KHRoaXMpOwotCShfcmlnaHQgPSByaWdodCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JX2xlZnQuc2V0UGFyc2VyKHBhcnNlcik7Ci0JX3JpZ2h0LnNldFBhcnNlcihwYXJzZXIpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiBPcGVyYXRvcnMubmFtZXNbX29wXSArICcoJyArIF9sZWZ0ICsgIiwgIiArIF9yaWdodCArICcpJzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRMZWZ0KCkgewotCXJldHVybiBfbGVmdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRSaWdodCgpIHsKLQlyZXR1cm4gX3JpZ2h0OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGdldE9wKCkgewotCWlmIChfb3AgPT0gT3BlcmF0b3JzLk5FKQotCSAgICByZXR1cm4gZmFsc2U7Ci0JZWxzZQotCSAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgc3dhcEFyZ3VtZW50cygpIHsKLQlmaW5hbCBFeHByZXNzaW9uIHRlbXAgPSBfbGVmdDsKLQlfbGVmdCA9IF9yaWdodDsKLQlfcmlnaHQgPSB0ZW1wOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGluZyBydWxlczogc2VlIFhTTFQgUmVmZXJlbmNlIGJ5IE0uIEtheSBwYWdlIDM0NS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWZpbmFsIFR5cGUgdGxlZnQgPSBfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsgCi0JZmluYWwgVHlwZSB0cmlnaHQgPSBfcmlnaHQudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLQlpZiAodGxlZnQuaXNTaW1wbGUoKSAmJiB0cmlnaHQuaXNTaW1wbGUoKSkgewotCSAgICBpZiAodGxlZnQgIT0gdHJpZ2h0KSB7Ci0JCWlmICh0bGVmdCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0JCSAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLkJvb2xlYW4pOwotCQl9Ci0JCWVsc2UgaWYgKHRyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0JCSAgICBfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgVHlwZS5Cb29sZWFuKTsKLQkJfQotCQllbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIE51bWJlclR5cGUgfHwgCi0JCQkgdHJpZ2h0IGluc3RhbmNlb2YgTnVtYmVyVHlwZSkgewotCQkgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuUmVhbCk7Ci0JCSAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlJlYWwpOwotCQl9Ci0JCWVsc2UgewkJLy8gYm90aCBjb21wYXJlZCBhcyBzdHJpbmdzCi0JCSAgICBfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgICBUeXBlLlN0cmluZyk7Ci0JCSAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlN0cmluZyk7Ci0JCX0KLQkgICAgfQotCX0KLQllbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLQkgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5SZWZlcmVuY2UpOwotCX0KLQllbHNlIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSB7Ci0JICAgIF9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBUeXBlLlJlZmVyZW5jZSk7Ci0JfQotCS8vIHRoZSBmb2xsb3dpbmcgMiBjYXNlcyBvcHRpbWl6ZSBAYXR0cnwufC4uID0gJ3N0cmluZycKLQllbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIE5vZGVUeXBlICYmIHRyaWdodCA9PSBUeXBlLlN0cmluZykgewotCSAgICBfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgVHlwZS5TdHJpbmcpOwotCX0KLQllbHNlIGlmICh0bGVmdCA9PSBUeXBlLlN0cmluZyAmJiB0cmlnaHQgaW5zdGFuY2VvZiBOb2RlVHlwZSkgewotCSAgICBfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlN0cmluZyk7Ci0JfQotCS8vIG9wdGltaXplIG5vZGUvbm9kZQotCWVsc2UgaWYgKHRsZWZ0IGluc3RhbmNlb2YgTm9kZVR5cGUgJiYgdHJpZ2h0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLQkgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuU3RyaW5nKTsKLQkgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5TdHJpbmcpOwotCX0KLQllbHNlIGlmICh0bGVmdCBpbnN0YW5jZW9mIE5vZGVUeXBlICYmIHRyaWdodCBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlKSB7Ci0JICAgIC8vIGNvbXBhcmUoTm9kZSwgTm9kZVNldCkgd2lsbCBiZSBpbnZva2VkCi0JfQotCWVsc2UgaWYgKHRsZWZ0IGluc3RhbmNlb2YgTm9kZVNldFR5cGUgJiYgdHJpZ2h0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLQkgICAgc3dhcEFyZ3VtZW50cygpOwkvLyBmb3IgY29tcGFyZShOb2RlLCBOb2RlU2V0KQotCX0KLQllbHNlIHsJCi0JICAgIC8vIEF0IGxlYXN0IG9uZSBhcmd1bWVudCBpcyBvZiB0eXBlIG5vZGUsIG5vZGUtc2V0IG9yIHJlc3VsdC10cmVlCi0KLQkgICAgLy8gUHJvbW90ZSBhbiBleHByZXNzaW9uIG9mIHR5cGUgbm9kZSB0byBub2RlLXNldAotCSAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBOb2RlVHlwZSkgewotCQlfbGVmdCA9IG5ldyBDYXN0RXhwcihfbGVmdCwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCSAgICBpZiAodHJpZ2h0IGluc3RhbmNlb2YgTm9kZVR5cGUpIHsKLQkJX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCi0JICAgIC8vIElmIG9uZSBhcmcgaXMgYSBub2RlLXNldCB0aGVuIG1ha2UgaXQgdGhlIGxlZnQgb25lCi0JICAgIGlmICh0bGVmdC5pc1NpbXBsZSgpIHx8Ci0JCXRsZWZ0IGluc3RhbmNlb2YgUmVzdWx0VHJlZVR5cGUgJiYKLQkJdHJpZ2h0IGluc3RhbmNlb2YgTm9kZVNldFR5cGUpIHsKLQkJc3dhcEFyZ3VtZW50cygpOwotCSAgICB9Ci0KLQkgICAgLy8gUHJvbW90ZSBpbnRlZ2VycyB0byBkb3VibGVzIHRvIGhhdmUgZmV3ZXIgY29tcGFyZXMKLQkgICAgaWYgKF9yaWdodC5nZXRUeXBlKCkgaW5zdGFuY2VvZiBJbnRUeXBlKSB7Ci0JCV9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuUmVhbCk7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBUeXBlIHRsZWZ0ID0gX2xlZnQuZ2V0VHlwZSgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlmICh0bGVmdCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0JICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKF9vcCA9PSBPcGVyYXRvcnMuRVEgPyAKLQkJCQkgICAgIChCcmFuY2hJbnN0cnVjdGlvbiluZXcgSUZfSUNNUE5FKG51bGwpIDoKLQkJCQkgICAgIChCcmFuY2hJbnN0cnVjdGlvbiluZXcgSUZfSUNNUEVRKG51bGwpKSk7Ci0JfQotCWVsc2UgaWYgKHRsZWZ0IGluc3RhbmNlb2YgTnVtYmVyVHlwZSkgewotCSAgICBfbGVmdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgaWYgKHRsZWZ0IGluc3RhbmNlb2YgUmVhbFR5cGUpIHsKLQkJaWwuYXBwZW5kKERDTVBHKTsKLQkJX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKF9vcCA9PSBPcGVyYXRvcnMuRVEgPyAKLQkJCQkJIChCcmFuY2hJbnN0cnVjdGlvbiluZXcgSUZORShudWxsKSA6IAotCQkJCQkgKEJyYW5jaEluc3RydWN0aW9uKW5ldyBJRkVRKG51bGwpKSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCV9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChfb3AgPT0gT3BlcmF0b3JzLkVRID8gCi0JCQkJCSAoQnJhbmNoSW5zdHJ1Y3Rpb24pbmV3IElGX0lDTVBORShudWxsKSA6Ci0JCQkJCSAoQnJhbmNoSW5zdHJ1Y3Rpb24pbmV3IElGX0lDTVBFUShudWxsKSkpOwotCSAgICB9Ci0JfQotCWVsc2UgewotCSAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGRlc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWZpbmFsIFR5cGUgdGxlZnQgPSBfbGVmdC5nZXRUeXBlKCk7Ci0JVHlwZSB0cmlnaHQgPSBfcmlnaHQuZ2V0VHlwZSgpOwotCi0JaWYgKHRsZWZ0IGluc3RhbmNlb2YgQm9vbGVhblR5cGUgfHwgdGxlZnQgaW5zdGFuY2VvZiBOdW1iZXJUeXBlKSB7Ci0JICAgIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIHN5bnRoZXNpemUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIHJldHVybjsKLQl9Ci0KLQlpZiAodGxlZnQgaW5zdGFuY2VvZiBTdHJpbmdUeXBlKSB7Ci0JICAgIGZpbmFsIGludCBlcXVhbHMgPSBjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19DTEFTUywKLQkJCQkJCSJlcXVhbHMiLAotCQkJCQkJIigiICsgT0JKRUNUX1NJRyArIilaIik7Ci0JICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGVxdWFscykpOwotCi0JICAgIGlmIChfb3AgPT0gT3BlcmF0b3JzLk5FKSB7Ci0JCWlsLmFwcGVuZChJQ09OU1RfMSk7Ci0JCWlsLmFwcGVuZChJWE9SKTsJCQkvLyBub3QgeCA8LT4geCB4b3IgMQotCSAgICB9Ci0JICAgIHJldHVybjsKLQl9Ci0KLQlCcmFuY2hIYW5kbGUgdHJ1ZWMsIGZhbHNlYzsKLQkKLQlpZiAodGxlZnQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSkgewotCSAgICBpZiAodHJpZ2h0IGluc3RhbmNlb2YgQm9vbGVhblR5cGUpIHsKLQkJX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWYgKF9vcCA9PSBPcGVyYXRvcnMuTkUpIHsKLQkJICAgIGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0JCSAgICBpbC5hcHBlbmQoSVhPUik7IC8vIG5vdCB4IDwtPiB4IHhvciAxCi0JCX0KLQkJcmV0dXJuOwotCSAgICB9Ci0KLQkgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIFJlYWxUeXBlKSB7Ci0JCV9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJdGxlZnQudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWFsKTsKLQkJX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCQlpbC5hcHBlbmQoRENNUEcpOwotCQlmYWxzZWMgPSBpbC5hcHBlbmQoX29wID09IE9wZXJhdG9ycy5FUSA/IAotCQkJCSAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGTkUobnVsbCkgOiAKLQkJCQkgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkVRKG51bGwpKTsKLQkJaWwuYXBwZW5kKElDT05TVF8xKTsKLQkJdHJ1ZWMgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCQlmYWxzZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChJQ09OU1RfMCkpOwotCQl0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotCQlyZXR1cm47Ci0JICAgIH0KLQotCSAgICAvLyBOZXh0LCByZXN1bHQtdHJlZS9zdHJpbmcgYW5kIHJlc3VsdC10cmVlL3Jlc3VsdC10cmVlIGNvbXBhcmlzb25zCi0KLQkgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICB0bGVmdC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0JICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0JCXRyaWdodC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0JICAgIH0KLQotCSAgICBmaW5hbCBpbnQgZXF1YWxzID0gY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsCi0JCQkJCQkiZXF1YWxzIiwKLQkJCQkJCSIoIiArT0JKRUNUX1NJRysgIilaIik7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChlcXVhbHMpKTsKLQotCSAgICBpZiAoX29wID09IE9wZXJhdG9ycy5ORSkgewotCQlpbC5hcHBlbmQoSUNPTlNUXzEpOwotCQlpbC5hcHBlbmQoSVhPUik7CQkJLy8gbm90IHggPC0+IHggeG9yIDEKLQkgICAgfQotCSAgICByZXR1cm47Ci0JfQotCi0JaWYgKHRsZWZ0IGluc3RhbmNlb2YgTm9kZVNldFR5cGUgJiYgdHJpZ2h0IGluc3RhbmNlb2YgQm9vbGVhblR5cGUpIHsKLQkgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfbGVmdC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIFR5cGUuTm9kZVNldC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLkJvb2xlYW4pOwotCSAgICBfcmlnaHQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JICAgIGlsLmFwcGVuZChJWE9SKTsgLy8geCAhPSB5IDwtPiB4IHhvciB5Ci0JICAgIGlmIChfb3AgPT0gRVEpIHsKLQkJaWwuYXBwZW5kKElDT05TVF8xKTsKLQkJaWwuYXBwZW5kKElYT1IpOyAvLyBub3QgeCA8LT4geCB4b3IgMQotCSAgICB9Ci0JICAgIHJldHVybjsKLQl9Ci0KLQlpZiAodGxlZnQgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSAmJiB0cmlnaHQgaW5zdGFuY2VvZiBTdHJpbmdUeXBlKSB7Ci0JICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX2xlZnQuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOyAvLyBuZWVkZWQgPwotCSAgICBfcmlnaHQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfb3ApKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCSAgICBmaW5hbCBpbnQgY21wID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotCQkJCQkgICAgICJjb21wYXJlIiwKLQkJCQkJICAgICAiKCIKLQkJCQkJICAgICArIHRsZWZ0LnRvU2lnbmF0dXJlKCkgCi0JCQkJCSAgICAgKyB0cmlnaHQudG9TaWduYXR1cmUoKQotCQkJCQkgICAgICsgIkkiCi0JCQkJCSAgICAgKyBET01fSU5URl9TSUcKLQkJCQkJICAgICArICIpWiIpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjbXApKTsKLQkgICAgcmV0dXJuOwotCX0KLQotCS8vIE5leHQsIG5vZGUtc2V0L3QgZm9yIHQgaW4ge3JlYWwsIHN0cmluZywgbm9kZS1zZXQsIHJlc3VsdC10cmVlfQotCV9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlfbGVmdC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlfcmlnaHQuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gQ2FzdCBhIHJlc3VsdCB0cmVlIHRvIGEgc3RyaW5nIHRvIHVzZSBhbiBleGlzdGluZyBjb21wYXJlCi0JaWYgKHRyaWdodCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0JICAgIHRyaWdodC50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7CQotCSAgICB0cmlnaHQgPSBUeXBlLlN0cmluZzsKLQl9Ci0KLQkvLyBDYWxsIHRoZSBhcHByb3ByaWF0ZSBjb21wYXJlKCkgZnJvbSB0aGUgQmFzaXNMaWJyYXJ5Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX29wKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCi0JZmluYWwgaW50IGNvbXBhcmUgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCSAgICAgImNvbXBhcmUiLAotCQkJCQkgICAgICIoIgotCQkJCQkgICAgICsgdGxlZnQudG9TaWduYXR1cmUoKSAKLQkJCQkJICAgICArIHRyaWdodC50b1NpZ25hdHVyZSgpCi0JCQkJCSAgICAgKyAiSSIKLQkJCQkJICAgICArIE5PREVfU0lHCi0JCQkJCSAgICAgKyBET01fSU5URl9TSUcKLQkJCQkJICAgICArICIpWiIpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNvbXBhcmUpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9FeHByZXNzaW9uLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9FeHByZXNzaW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM5YjU1Y2EuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRXhwcmVzc2lvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjQyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotCi1hYnN0cmFjdCBjbGFzcyBFeHByZXNzaW9uIGV4dGVuZHMgU3ludGF4VHJlZU5vZGUgewotICAgIC8qKgotICAgICAqIFRoZSB0eXBlIG9mIHRoaXMgZXhwcmVzc2lvbi4gSXQgaXMgc2V0IGFmdGVyIGNhbGxpbmcgCi0gICAgICogPGNvZGU+dHlwZUNoZWNrKCk8L2NvZGU+LgotICAgICAqLwotICAgIHByb3RlY3RlZCBUeXBlIF90eXBlOwotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb24gaXMgb2Ygbm9kZS1zZXQgdHlwZSBhbmQgaXRzIGNvcnJlc3BvbmRpbmcKLSAgICAgKiBpdGVyYXRvciBoYXMgYmVlbiBzdGFydGVkIG9yIHJlc2V0LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIF9zdGFydFJlc2V0ID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBJbnN0cnVjdGlvbiBoYW5kbGVzIHRoYXQgY29tcHJpc2UgdGhlIHRydWUgbGlzdC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgRmxvd0xpc3QgX3RydWVMaXN0ID0gbmV3IEZsb3dMaXN0KCk7Ci0KLSAgICAvKioKLSAgICAgKiBJbnN0cnVjdGlvbiBoYW5kbGVzIHRoYXQgY29tcHJpc2UgdGhlIGZhbHNlIGxpc3QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIEZsb3dMaXN0IF9mYWxzZUxpc3QgPSBuZXcgRmxvd0xpc3QoKTsKLQotICAgIHB1YmxpYyBUeXBlIGdldFR5cGUoKSB7Ci0JcmV0dXJuIF90eXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdG9TdHJpbmcoKTsKLQkJCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCXJldHVybiB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGlzIG5vZGUgaW50byBKVk0gYnl0ZWNvZGVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWdldFBhcnNlcigpLm5vdFlldEltcGxlbWVudGVkKCJleHByZXNzaW9uOiAiICsgZ2V0Q2xhc3MoKSk7Ci0gICAgfQotCQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGlzIG5vZGUgaW50byBhIGZyZXNoIGluc3RydWN0aW9uIGxpc3QuCi0gICAgICogVGhlIG9yaWdpbmFsIGluc3RydWN0aW9uIGxpc3QgaXMgc2F2ZWQgYW5kIHJlc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgY29tcGlsZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkJIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgcmVzdWx0LCBzYXZlID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCW1ldGhvZEdlbi5zZXRJbnN0cnVjdGlvbkxpc3QocmVzdWx0ID0gbmV3IEluc3RydWN0aW9uTGlzdCgpKTsKLQl0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JbWV0aG9kR2VuLnNldEluc3RydWN0aW9uTGlzdChzYXZlKTsKLQlyZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlZGVmaW5lZCBieSBleHByZXNzaW9ucyBvZiB0eXBlIGJvb2xlYW4gdGhhdCB1c2UgZmxvdyBsaXN0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JdHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlmIChfdHlwZSBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0JICAgIGRlc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhbiBvYmplY3Qgb24gdGhlIHN0YWNrIGFuZCBpZiB0aGlzIG9iamVjdCBjYW4gYmUgcHJvdmVuCi0gICAgICogdG8gYmUgYSBub2RlIGl0ZXJhdG9yIHRoZW4gdGhlIGl0ZXJhdG9yIGlzIHJlc2V0IG9yIHN0YXJ0ZWQKLSAgICAgKiBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgdGhpcyBleHByZXNzaW9uLgotICAgICAqIElmIHRoaXMgZXhwcmVzc2lvbiBpcyBhIHZhciByZWZlcmVuY2UgdGhlbiB0aGUgaXRlcmF0b3IgCi0gICAgICogaXMgcmVzZXQsIG90aGVyd2lzZSBpdCBpcyBzdGFydGVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UmVzZXRJdGVyYXRvcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlmIChfc3RhcnRSZXNldCkgewotCSAgICByZXR1cm47CQkJLy8gYWxyZWFkeSBzdGFydGVkCi0JfQotCV9zdGFydFJlc2V0ID0gdHJ1ZTsKLQotCWlmIChfdHlwZSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlID09IGZhbHNlKSB7Ci0JICAgIHJldHVybjsJCS8vIG5vdGhpbmcgdG8gZG8KLQl9Ci0KLQlpZiAodGhpcyBpbnN0YW5jZW9mIFZhcmlhYmxlUmVmQmFzZSkgewotCSAgICAvLyBUaGUgbWV0aG9kIGNsb25lSXRlcmF0b3IoKSBhbHNvIGRvZXMgcmVzZXR0aW5nCi0JICAgIGZpbmFsIGludCBjbG9uZSA9Ci0JCWNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwKLQkJCQkJICAiY2xvbmVJdGVyYXRvciIsCi0JCQkJCSAgIigpIiArIE5PREVfSVRFUkFUT1JfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY2xvbmUsIDEpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnNldFN0YXJ0Tm9kZSgpKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3ludGhlc2l6ZSBhIGJvb2xlYW4gZXhwcmVzc2lvbiwgaS5lLiwgZWl0aGVyIHB1c2ggYSAwIG9yIDEgb250byB0aGUgCi0gICAgICogb3BlcmFuZCBzdGFjayBmb3IgdGhlIG5leHQgc3RhdGVtZW50IHRvIHN1Y2NlZWQuIFJldHVybnMgdGhlIGhhbmRsZQotICAgICAqIG9mIHRoZSBpbnN0cnVjdGlvbiB0byBiZSBiYWNrcGF0Y2hlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzeW50aGVzaXplKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlfdHJ1ZUxpc3QuYmFja1BhdGNoKGlsLmFwcGVuZChJQ09OU1RfMSkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UT19XKG51bGwpKTsKLQlfZmFsc2VMaXN0LmJhY2tQYXRjaChpbC5hcHBlbmQoSUNPTlNUXzApKTsKLQl0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRlc3ludGhlc2l6ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBiYWNrUGF0Y2hGYWxzZUxpc3QoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgpIHsKLQlfZmFsc2VMaXN0LmJhY2tQYXRjaChpaCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYmFja1BhdGNoVHJ1ZUxpc3QoSW5zdHJ1Y3Rpb25IYW5kbGUgaWgpIHsKLQlfdHJ1ZUxpc3QuYmFja1BhdGNoKGloKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZWFyY2ggZm9yIGEgcHJpbW9wIGluIHRoZSBzeW1ib2wgdGFibGUgdGhhdCBtYXRjaGVzIHRoZSBtZXRob2QgdHlwZSAKLSAgICAgKiA8Y29kZT5jdHlwZTwvY29kZT4uIFR3byBtZXRob2RzIG1hdGNoIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSBhcml0eS4KLSAgICAgKiBJZiBhIHByaW1vcCBpcyBvdmVybG9hZGVkIHRoZW4gdGhlICJjbG9zZXN0IG1hdGNoIiBpcyByZXR1cm5lZC4gVGhlCi0gICAgICogZmlyc3QgZW50cnkgaW4gdGhlIHZlY3RvciBvZiBwcmltb3BzIHRoYXQgaGFzIHRoZSByaWdodCBhcml0eSBpcyAKLSAgICAgKiBjb25zaWRlcmVkIHRvIGJlIHRoZSBkZWZhdWx0IG9uZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTWV0aG9kVHlwZSBsb29rdXBQcmltb3AoU3ltYm9sVGFibGUgc3RhYmxlLCBTdHJpbmcgb3AsCi0JCQkJICAgTWV0aG9kVHlwZSBjdHlwZSkgewotCU1ldGhvZFR5cGUgcmVzdWx0ID0gbnVsbDsKLQlmaW5hbCBWZWN0b3IgcHJpbW9wID0gc3RhYmxlLmxvb2t1cFByaW1vcChvcCk7Ci0JaWYgKHByaW1vcCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBuID0gcHJpbW9wLnNpemUoKTsKLQkgICAgaW50IG1pbkRpc3RhbmNlID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCWZpbmFsIE1ldGhvZFR5cGUgcHR5cGUgPSAoTWV0aG9kVHlwZSkgcHJpbW9wLmVsZW1lbnRBdChpKTsKLQkJLy8gU2tpcCBpZiBkaWZmZXJlbnQgYXJpdHkKLQkJaWYgKHB0eXBlLmFyZ3NDb3VudCgpICE9IGN0eXBlLmFyZ3NDb3VudCgpKSB7Ci0JCSAgICBjb250aW51ZTsKLQkJfQotCQkJCQotCQkvLyBUaGUgZmlyc3QgbWV0aG9kIHdpdGggdGhlIHJpZ2h0IGFyaXR5IGlzIHRoZSBkZWZhdWx0Ci0JCWlmIChyZXN1bHQgPT0gbnVsbCkgewotCQkgICAgcmVzdWx0ID0gcHR5cGU7CQkvLyBkZWZhdWx0IG1ldGhvZAotCQl9Ci0KLQkJLy8gQ2hlY2sgaWYgYmV0dGVyIHRoYW4gbGFzdCBvbmUgZm91bmQKLQkJZmluYWwgaW50IGRpc3RhbmNlID0gY3R5cGUuZGlzdGFuY2VUbyhwdHlwZSk7Ci0JCWlmIChkaXN0YW5jZSA8IG1pbkRpc3RhbmNlKSB7Ci0JCSAgICBtaW5EaXN0YW5jZSA9IGRpc3RhbmNlOwotCQkgICAgcmVzdWx0ID0gcHR5cGU7Ci0JCX0KLQkgICAgfQkJCi0JfQkKLQlyZXR1cm4gcmVzdWx0OwotICAgIH0JCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GYWxsYmFjay5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRmFsbGJhY2suamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGQ0ZWM4Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GYWxsYmFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBGYWxsYmFjayBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgYm9vbGVhbiBfYWN0aXZlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGVsZW1lbnQgbmV2ZXIgcHJvZHVjZXMgYW55IGRhdGEgb24gdGhlIHN0YWNrCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoX2FjdGl2ZSkgewotCSAgICByZXR1cm4odHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKSk7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4gVHlwZS5Wb2lkOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBY3RpdmF0ZSB0aGlzIGZhbGxiYWNrIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhY3RpdmF0ZSgpIHsKLQlfYWN0aXZlID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybigiZmFsbGJhY2siKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBjb250ZW50cyBvbmx5IGlmIHRoaXMgZmFsbGJhY2sgZWxlbWVudCBpcyBwdXQgaW4gcGxhY2Ugb2YKLSAgICAgKiBzb21lIHVuc3VwcG9ydGVkIGVsZW1lbnQgb3Igbm9uLVhTTFRDIGV4dGVuc2lvbiBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JaWYgKF9hY3RpdmUpIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgY29udGVudHMgb25seSBpZiB0aGlzIGZhbGxiYWNrIGVsZW1lbnQgaXMgcHV0IGluIHBsYWNlIG9mCi0gICAgICogc29tZSB1bnN1cHBvcnRlZCBlbGVtZW50IG9yIG5vbi1YU0xUQyBleHRlbnNpb24gZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlpZiAoX2FjdGl2ZSkgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRmlsdGVyRXhwci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRmlsdGVyRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNDNiN2FhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ZpbHRlckV4cHIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE5OCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotY2xhc3MgRmlsdGVyRXhwciBleHRlbmRzIEV4cHJlc3Npb24gewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiAgIF9wcmltYXJ5OwotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9wcmVkaWNhdGVzOwotCi0gICAgcHVibGljIEZpbHRlckV4cHIoRXhwcmVzc2lvbiBwcmltYXJ5LCBWZWN0b3IgcHJlZGljYXRlcykgewotCV9wcmltYXJ5ID0gcHJpbWFyeTsKLQlfcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0JcHJpbWFyeS5zZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlfcHJpbWFyeS5zZXRQYXJzZXIocGFyc2VyKTsKLQlpZiAoX3ByZWRpY2F0ZXMgIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkJZmluYWwgRXhwcmVzc2lvbiBleHAgPSAoRXhwcmVzc2lvbilfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0JCWV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLQkJZXhwLnNldFBhcmVudCh0aGlzKTsKLQkgICAgfQotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gImZpbHRlci1leHByKCIgKyBfcHJpbWFyeSArICIsICIgKyBfcHJlZGljYXRlcyArICIpIjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGEgRmlsdGVyUGFyZW50UGF0aC4gSWYgdGhlIGZpbHRlciBpcyBub3QgYSBub2RlLXNldCBhZGQgYSAKLSAgICAgKiBjYXN0IHRvIG5vZGUtc2V0IG9ubHkgaWYgaXQgaXMgb2YgcmVmZXJlbmNlIHR5cGUuIFRoaXMgdHlwZSBjb2VyY2lvbiAKLSAgICAgKiBpcyBuZWVkZWQgZm9yIGV4cHJlc3Npb25zIGxpa2UgJHggd2hlcmUgJHggaXMgYSBwYXJhbWV0ZXIgcmVmZXJlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JVHlwZSBwdHlwZSA9IF9wcmltYXJ5LnR5cGVDaGVjayhzdGFibGUpOwotCi0JaWYgKHB0eXBlIGluc3RhbmNlb2YgTm9kZVNldFR5cGUgPT0gZmFsc2UpIHsKLQkgICAgaWYgKHB0eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgIHsKLQkJX3ByaW1hcnkgPSBuZXcgQ2FzdEV4cHIoX3ByaW1hcnksIFR5cGUuTm9kZVNldCk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcih0aGlzKTsKLQkgICAgfQotCX0KLQotCWludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JICAgIEV4cHJlc3Npb24gcHJlZCA9IChFeHByZXNzaW9uKV9wcmVkaWNhdGVzLmVsZW1lbnRBdChpKTsKLQkgICAgcHJlZC50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JcmV0dXJuIF90eXBlID0gVHlwZS5Ob2RlU2V0OwkKLSAgICB9Ci0JCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIGEgZmlsdGVyIGV4cHJlc3Npb24gYnkgcHVzaGluZyB0aGUgYXBwcm9wcmlhdGUgaXRlcmF0b3IKLSAgICAgKiBvbnRvIHRoZSBzdGFjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlpZiAoX3ByZWRpY2F0ZXMuc2l6ZSgpID4gMCkgewotCSAgICB0cmFuc2xhdGVQcmVkaWNhdGVzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQllbHNlIHsKLQkgICAgX3ByaW1hcnkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfcHJpbWFyeS5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBhIHNlcXVlbmNlIG9mIHByZWRpY2F0ZXMuCi0gICAgICogRWFjaCBwcmVkaWNhdGUgaXMgdHJhbnNsYXRlZCBieSBjb25zdHJ1Y3RpbmcgYW4gaW5zdGFuY2UKLSAgICAgKiBvZiA8Y29kZT5DdXJyZW50Tm9kZUxpc3RJdGVyYXRvcjwvY29kZT4gd2hpY2ggaXMgaW5pdGlhbGl6ZWQgZnJvbQotICAgICAqIGFub3RoZXIgaXRlcmF0b3IgKHJlY3Vyc2l2ZSBjYWxsKSwgYSBmaWx0ZXIgYW5kIGEgY2xvc3VyZQotICAgICAqIChjYWxsIHRvIHRyYW5zbGF0ZSBvbiB0aGUgcHJlZGljYXRlKSBhbmQgInRoaXMiLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVQcmVkaWNhdGVzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlmIChfcHJlZGljYXRlcy5zaXplKCkgPT0gMCkgewotCSAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCWVsc2UgewotCSAgICBmaW5hbCBpbnQgaW5pdENOTEkgPSBjcGcuYWRkTWV0aG9kcmVmKENVUlJFTlRfTk9ERV9MSVNUX0lURVJBVE9SLAotCQkJCQkJICAiPGluaXQ+IiwKLQkJCQkJCSAgIigiK05PREVfSVRFUkFUT1JfU0lHKyJaIisKLQkJCQkJCSAgQ1VSUkVOVF9OT0RFX0xJU1RfRklMVEVSX1NJRyArCi0JCQkJCQkgIE5PREVfU0lHK1RSQU5TTEVUX1NJRysiKVYiKTsKLQotCSAgICBQcmVkaWNhdGUgcHJlZGljYXRlID0gKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5sYXN0RWxlbWVudCgpOwotCSAgICBfcHJlZGljYXRlcy5yZW1vdmUocHJlZGljYXRlKTsKLQotCSAgICBpZiAocHJlZGljYXRlLmlzTnRoUG9zaXRpb25GaWx0ZXIoKSkgewotCQlmaW5hbCBpbnQgc3RhcnQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0JCQkJCQkJICAgICJzZXRTdGFydE5vZGUiLCAKLQkJCQkJCQkgICAgIihJKSIrCi0JCQkJCQkJICAgIE5PREVfSVRFUkFUT1JfU0lHKTsKLQkJZmluYWwgaW50IHJlc2V0ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotCQkJCQkJCSAgICAicmVzZXQiLAotCQkJCQkJCSAgICAiKCkiKwotCQkJCQkJCSAgICBOT0RFX0lURVJBVE9SX1NJRyk7Ci0JCXRyYW5zbGF0ZVByZWRpY2F0ZXMoY2xhc3NHZW4sIG1ldGhvZEdlbik7IC8vIGdldCB0aGUgYmFzZSBpdHIuCi0JCXByZWRpY2F0ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7IC8vIGdldCB0aGUgcG9zaXRpb24KLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uoc3RhcnQsMikpOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShyZXNldCwxKSk7Ci0KLQkJZmluYWwgaW50IHNuZ2wgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCQkgICJnZXRTaW5nbGVOb2RlIiwKLQkJCQkJCSAgIigiK05PREVfSVRFUkFUT1JfU0lHKyIpIisKLQkJCQkJCSAgTk9ERV9JVEVSQVRPUl9TSUcpOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhzbmdsKSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCS8vIGNyZWF0ZSBuZXcgQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IKLQkJaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKENVUlJFTlRfTk9ERV9MSVNUX0lURVJBVE9SKSkpOwotCQlpbC5hcHBlbmQoRFVQKTsKLQkJdHJhbnNsYXRlUHJlZGljYXRlcyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsgLy8gcmVjdXJzaXZlIGNhbGwKLQkJaWwuYXBwZW5kKElDT05TVF8xKTsKLQkJcHJlZGljYXRlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0Q05MSSkpOwotCSAgICB9Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ZpbHRlclBhcmVudFBhdGguamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ZpbHRlclBhcmVudFBhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTg1NWMxZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GaWx0ZXJQYXJlbnRQYXRoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBGaWx0ZXJQYXJlbnRQYXRoIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9maWx0ZXJFeHByOwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfcGF0aDsKLQotICAgIHB1YmxpYyBGaWx0ZXJQYXJlbnRQYXRoKEV4cHJlc3Npb24gZmlsdGVyRXhwciwgRXhwcmVzc2lvbiBwYXRoKSB7Ci0JKF9wYXRoID0gcGF0aCkuc2V0UGFyZW50KHRoaXMpOwotCShfZmlsdGVyRXhwciA9IGZpbHRlckV4cHIpLnNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0JCQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JX2ZpbHRlckV4cHIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JX3BhdGguc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJGaWx0ZXJQYXJlbnRQYXRoKCIgKyBfZmlsdGVyRXhwciArICIsICIgKyBfcGF0aCArICcpJzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGEgRmlsdGVyUGFyZW50UGF0aC4gSWYgdGhlIGZpbHRlciBpcyBub3QgYSBub2RlLXNldCBhZGQgYSAKLSAgICAgKiBjYXN0IHRvIG5vZGUtc2V0IG9ubHkgaWYgaXQgaXMgb2YgcmVmZXJlbmNlIHR5cGUuIFRoaXMgdHlwZSBjb2VyY2lvbiBpcwotICAgICAqIG5lZWRlZCBmb3IgZXhwcmVzc2lvbnMgbGlrZSAkeC9MSU5FIHdoZXJlICR4IGlzIGEgcGFyYW1ldGVyIHJlZmVyZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWZpbmFsIFR5cGUgZnR5cGUgPSBfZmlsdGVyRXhwci50eXBlQ2hlY2soc3RhYmxlKTsKLQlpZiAoZnR5cGUgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSA9PSBmYWxzZSkgewotCSAgICBpZiAoZnR5cGUgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlKSAgewotCQlfZmlsdGVyRXhwciA9IG5ldyBDYXN0RXhwcihfZmlsdGVyRXhwciwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCSAgICAvKgotCSAgICBlbHNlIGlmIChmdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSAgewotCQlfZmlsdGVyRXhwciA9IG5ldyBDYXN0RXhwcihfZmlsdGVyRXhwciwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCSAgICAqLwotCSAgICBlbHNlIGlmIChmdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSAgewotCQlfZmlsdGVyRXhwciA9IG5ldyBDYXN0RXhwcihfZmlsdGVyRXhwciwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotCSAgICB9Ci0JfQotCi0JLy8gV3JhcCBzaW5nbGUgbm9kZSBwYXRoIGluIGEgbm9kZSBzZXQKLQlmaW5hbCBUeXBlIHB0eXBlID0gX3BhdGgudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKCEocHR5cGUgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSkpIHsKLQkgICAgX3BhdGggPSBuZXcgQ2FzdEV4cHIoX3BhdGgsIFR5cGUuTm9kZVNldCk7Ci0JfQotCi0JcmV0dXJuIF90eXBlID0gVHlwZS5Ob2RlU2V0OwkKLSAgICB9Ci0JCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQkvLyBDcmVhdGUgbmV3IFN0ZXBJdGVyYXRvcgotCWZpbmFsIGludCBpbml0U0kgPSBjcGcuYWRkTWV0aG9kcmVmKFNURVBfSVRFUkFUT1JfQ0xBU1MsCi0JCQkJCSAgICAiPGluaXQ+IiwKLQkJCQkJICAgICIoIgotCQkJCQkgICAgK05PREVfSVRFUkFUT1JfU0lHCi0JCQkJCSAgICArTk9ERV9JVEVSQVRPUl9TSUcKLQkJCQkJICAgICsiKVYiKTsKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU1RFUF9JVEVSQVRPUl9DTEFTUykpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQotCS8vIFJlY3Vyc2l2ZWx5IGNvbXBpbGUgMiBpdGVyYXRvcnMKLQlfZmlsdGVyRXhwci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JX3BhdGgudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gSW5pdGlhbGl6ZSBTdGVwSXRlcmF0b3Igd2l0aCBpdGVyYXRvcnMgZnJvbSB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdFNJKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRmlsdGVyZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRmlsdGVyZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMjBiZmNjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ZpbHRlcmVkQWJzb2x1dGVMb2NhdGlvblBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyIAotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9wYXRoOwkvLyBtYXkgYmUgbnVsbCAKLQotICAgIHB1YmxpYyBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoKCkgewotCV9wYXRoID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRmlsdGVyZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aChFeHByZXNzaW9uIHBhdGgpIHsKLQlfcGF0aCA9IHBhdGg7Ci0JaWYgKHBhdGggIT0gbnVsbCkgewotCSAgICBfcGF0aC5zZXRQYXJlbnQodGhpcyk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JaWYgKF9wYXRoICE9IG51bGwpIHsKLQkgICAgX3BhdGguc2V0UGFyc2VyKHBhcnNlcik7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldFBhdGgoKSB7Ci0JcmV0dXJuKF9wYXRoKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gIkZpbHRlcmVkQWJzb2x1dGVMb2NhdGlvblBhdGgoIiArCi0JICAgIChfcGF0aCAhPSBudWxsID8gX3BhdGgudG9TdHJpbmcoKSA6ICJudWxsIikgKyAnKSc7Ci0gICAgfQotCQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKF9wYXRoICE9IG51bGwpIHsKLQkgICAgZmluYWwgVHlwZSBwdHlwZSA9IF9wYXRoLnR5cGVDaGVjayhzdGFibGUpOwotCSAgICBpZiAocHR5cGUgaW5zdGFuY2VvZiBOb2RlVHlwZSkgewkJLy8gcHJvbW90ZSB0byBub2RlLXNldAotCQlfcGF0aCA9IG5ldyBDYXN0RXhwcihfcGF0aCwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCX0KLQlyZXR1cm4gX3R5cGUgPSBUeXBlLk5vZGVTZXQ7CQotICAgIH0KLQkKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlmIChfcGF0aCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBpbml0REZJID0gY3BnLmFkZE1ldGhvZHJlZihEVVBfRklMVEVSRURfSVRFUkFUT1IsCi0JCQkJCQkiPGluaXQ+IiwKLQkJCQkJCSIoIgotCQkJCQkJKyBOT0RFX0lURVJBVE9SX1NJRwotCQkJCQkJKyAiKVYiKTsKLQkgICAgLy8gQ3JlYXRlIG5ldyBEdXAgRmlsdGVyIEl0ZXJhdG9yCi0JICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhEVVBfRklMVEVSRURfSVRFUkFUT1IpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCi0JICAgIC8vIENvbXBpbGUgcmVsYXRpdmUgcGF0aCBpdGVyYXRvcihzKQotCSAgICBfcGF0aC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgLy8gSW5pdGlhbGl6ZSBEdXAgRmlsdGVyIEl0ZXJhdG9yIHdpdGggaXRlcmF0b3IgZnJvbSB0aGUgc3RhY2sKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXRERkkpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGZpbmFsIGludCBnaXQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAgImdldEl0ZXJhdG9yIiwKLQkJCQkJCSAgICAgICIoKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdCwgMSkpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GbG9vckNhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Zsb29yQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZDA0NmRmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Zsb29yQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEZsb29yQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHVibGljIEZsb29yQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWFyZ3VtZW50KCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCW1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKQotCSAgICAuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCkKLQkJCQkgICAgIC5hZGRNZXRob2RyZWYoTUFUSF9DTEFTUywKLQkJCQkJCSAgICJmbG9vciIsICIoRClEIikpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GbG93TGlzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRmxvd0xpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTI4MzExYi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GbG93TGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRmxvd0xpc3QgewotICAgIHByaXZhdGUgVmVjdG9yIF9lbGVtZW50czsKLQotICAgIHB1YmxpYyBGbG93TGlzdCgpIHsKLQlfZWxlbWVudHMgPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBGbG93TGlzdChJbnN0cnVjdGlvbkhhbmRsZSBiaCkgewotCV9lbGVtZW50cyA9IG5ldyBWZWN0b3IoKTsKLQlfZWxlbWVudHMuYWRkRWxlbWVudChiaCk7Ci0gICAgfQotCi0gICAgcHVibGljIEZsb3dMaXN0KEZsb3dMaXN0IGxpc3QpIHsKLQlfZWxlbWVudHMgPSBsaXN0Ll9lbGVtZW50czsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRmxvd0xpc3QgYWRkKEluc3RydWN0aW9uSGFuZGxlIGJoKSB7Ci0JaWYgKF9lbGVtZW50cyA9PSBudWxsKSB7Ci0JICAgIF9lbGVtZW50cyA9IG5ldyBWZWN0b3IoKTsKLQl9Ci0JX2VsZW1lbnRzLmFkZEVsZW1lbnQoYmgpOwotCXJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBGbG93TGlzdCBhcHBlbmQoRmxvd0xpc3QgcmlnaHQpIHsKLQlpZiAoX2VsZW1lbnRzID09IG51bGwpIHsKLQkgICAgX2VsZW1lbnRzID0gcmlnaHQuX2VsZW1lbnRzOwotCX0KLQllbHNlIHsKLQkgICAgZmluYWwgVmVjdG9yIHRlbXAgPSByaWdodC5fZWxlbWVudHM7Ci0JICAgIGlmICh0ZW1wICE9IG51bGwpIHsKLQkJZmluYWwgaW50IG4gPSB0ZW1wLnNpemUoKTsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkJICAgIF9lbGVtZW50cy5hZGRFbGVtZW50KHRlbXAuZWxlbWVudEF0KGkpKTsKLQkJfQotCSAgICB9Ci0JfQotCXJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJhY2sgcGF0Y2ggYSBmbG93IGxpc3QuIEFsbCBpbnN0cnVjdGlvbiBoYW5kbGVzIG11c3QgYmUgYnJhbmNoIGhhbmRsZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYmFja1BhdGNoKEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCkgewotCWlmIChfZWxlbWVudHMgIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgbiA9IF9lbGVtZW50cy5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCUJyYW5jaEhhbmRsZSBiaCA9IChCcmFuY2hIYW5kbGUpX2VsZW1lbnRzLmVsZW1lbnRBdChpKTsKLQkJYmguc2V0VGFyZ2V0KHRhcmdldCk7Ci0JICAgIH0KLQkgICAgX2VsZW1lbnRzLmNsZWFyKCk7CQkvLyBhdm9pZCBiYWNrcGF0Y2hpbmcgbW9yZSB0aGFuIG9uY2UKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRm9yRWFjaC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRm9yRWFjaC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ODgwN2JhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ZvckVhY2guamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyOSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEZvckVhY2ggZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3NlbGVjdDsKLSAgICBwcml2YXRlIFR5cGUgICAgICAgX3R5cGU7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIkZvckVhY2giKTsKLQlpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQlVdGlsLnByaW50bG4oInNlbGVjdCAiICsgX3NlbGVjdC50b1N0cmluZygpKTsKLQlkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0JCQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCV9zZWxlY3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJzZWxlY3QiLCBudWxsKTsKLQotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQotICAgICAgICAvLyBtYWtlIHN1cmUgcmVxdWlyZWQgYXR0cmlidXRlKHMpIGhhdmUgYmVlbiBzZXQKLSAgICAgICAgaWYgKF9zZWxlY3QuaXNEdW1teSgpKSB7Ci0JICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuTlJFUUFUVFJfRVJSLCAic2VsZWN0Iik7Ci0JICAgIHJldHVybjsKLSAgICAgICAgfQotICAgIH0KLQkKLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCV90eXBlID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLQotCWlmIChfdHlwZSBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUgfHwgX3R5cGUgaW5zdGFuY2VvZiBOb2RlVHlwZSkgewotCSAgICBfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuTm9kZVNldCk7Ci0JICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0JfQotCWlmIChfdHlwZSBpbnN0YW5jZW9mIE5vZGVTZXRUeXBlfHxfdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0JICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JICAgIHJldHVybiBUeXBlLlZvaWQ7Ci0JfQotCVN0cmluZyBtc2cgPSAiVW5zdXBwb3J0ZWQgdHlwZSBmb3IgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9JyIrX3R5cGUrIicvPiI7Ci0JdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKG5ldyBFcnJvck1zZyhtc2cpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gU2F2ZSBjdXJyZW50IG5vZGUgYW5kIGN1cnJlbnQgaXRlcmF0b3Igb24gdGhlIHN0YWNrCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0JCQotCS8vIENvbGxlY3Qgc29ydCBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGluc3RydWN0aW9uCi0JZmluYWwgVmVjdG9yIHNvcnRPYmplY3RzID0gbmV3IFZlY3RvcigpOwotCUVudW1lcmF0aW9uIGNoaWxkcmVuID0gZWxlbWVudHMoKTsKLQl3aGlsZSAoY2hpbGRyZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgT2JqZWN0IGNoaWxkID0gY2hpbGRyZW4ubmV4dEVsZW1lbnQoKTsKLQkgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgU29ydCkgewotCQlzb3J0T2JqZWN0cy5hZGRFbGVtZW50KGNoaWxkKTsKLQkgICAgfQotCX0KLQotCWlmICgoX3R5cGUgIT0gbnVsbCkgJiYgKF90eXBlIGluc3RhbmNlb2YgUmVzdWx0VHJlZVR5cGUpKSB7Ci0JICAgIC8vIFN0b3JlIGV4aXN0aW5nIERPTSBvbiBzdGFjayAtIG11c3QgYmUgcmVzdG9yZWQgd2hlbiBsb29wIGlzIGRvbmUKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCi0JICAgIC8vIDx4c2w6c29ydD4gY2Fubm90IGJlIGFwcGxpZWQgdG8gYSByZXN1bHQgdHJlZSAtIGlzc3VlIHdhcm5pbmcKLQkgICAgaWYgKHNvcnRPYmplY3RzLnNpemUoKSA+IDApIHsKLQkJRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlRSRUVTT1JUX0VSUik7Ci0JCWdldFBhcnNlcigpLnJlcG9ydEVycm9yKFdBUk5JTkcsIG1zZyk7Ci0JICAgIH0KLQotCSAgICAvLyBQdXQgdGhlIHJlc3VsdCB0cmVlIG9uIHRoZSBzdGFjayAoRE9NKQotCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgLy8gR2V0IGFuIGl0ZXJhdG9yIGZvciB0aGUgd2hvbGUgRE9NIC0gZXhjbHVkaW5nIHRoZSByb290IG5vZGUKLQkgICAgX3R5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgLy8gU3RvcmUgdGhlIHJlc3VsdCB0cmVlIGFzIHRoZSBkZWZhdWx0IERPTQotCSAgICBpbC5hcHBlbmQoU1dBUCk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVET00oKSk7Ci0JfQotCWVsc2UgewotCSAgICAvLyBDb21waWxlIG5vZGUgaXRlcmF0b3IKLQkgICAgaWYgKHNvcnRPYmplY3RzLnNpemUoKSA+IDApIHsKLQkJU29ydC50cmFuc2xhdGVTb3J0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkJICAgX3NlbGVjdCwgc29ydE9iamVjdHMpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWYgKF9zZWxlY3QgaW5zdGFuY2VvZiBTdGVwKSB7Ci0JCSAgICAoKFN0ZXApX3NlbGVjdCkub3JkZXJJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJfQotCSAgICB9Ci0JICAgIGlmICghKF90eXBlIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkpIHsKLQkJX3NlbGVjdC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQl9Ci0KLQotCS8vIE92ZXJ3cml0ZSBjdXJyZW50IGl0ZXJhdG9yCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUl0ZXJhdG9yKCkpOwotCi0JLy8gR2l2ZSBsb2NhbCB2YXJpYWJsZXMgKGlmIGFueSkgZGVmYXVsdCB2YWx1ZXMgYmVmb3JlIHN0YXJ0aW5nIGxvb3AKLQlpbml0aWFsaXplVmFyaWFibGVzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JZmluYWwgQnJhbmNoSGFuZGxlIG5leHROb2RlID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBsb29wID0gaWwuYXBwZW5kKE5PUCk7Ci0KLQl0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJICAgIAotCW5leHROb2RlLnNldFRhcmdldChpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0JaWwuYXBwZW5kKG5ldyBJRk5FKGxvb3ApKTsKLQotCS8vIFJlc3RvcmUgY3VycmVudCBET00gKGlmIHJlc3VsdCB0cmVlIHdhcyB1c2VkIGluc3RlYWQgZm9yIHRoaXMgbG9vcCkKLQlpZiAoKF90eXBlICE9IG51bGwpICYmIChfdHlwZSBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSkgewotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlRE9NKCkpOwkgICAgCi0JfQotCi0JLy8gUmVzdG9yZSBjdXJyZW50IG5vZGUgYW5kIGN1cnJlbnQgaXRlcmF0b3IgZnJvbSB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBjb2RlIHRoYXQgaXMgZ2VuZXJhdGVkIGJ5IG5lc3RlZCBmb3ItZWFjaCBsb29wcyBjYW4gYXBwZWFyIHRvIHNvbWUKLSAgICAgKiBKVk1zIGFzIGlmIGl0IGlzIGFjY2Vzc2luZyB1bi1pbml0aWFsaXplZCB2YXJpYWJsZXMuIFdlIG11c3QgYWRkIHNvbWUKLSAgICAgKiBjb2RlIHRoYXQgcHVzaGVzIHRoZSBkZWZhdWx0IHZhcmlhYmxlIHZhbHVlIG9uIHRoZSBzdGFjayBhbmQgcG9wcyBpdAotICAgICAqIGludG8gdGhlIHZhcmlhYmxlIHNsb3QuIFRoaXMgaXMgZG9uZSBieSB0aGUgVmFyaWFibGUuaW5pdGlhbGl6ZSgpCi0gICAgICogbWV0aG9kLiBUaGUgY29kZSB0aGF0IHdlIGNvbXBpbGUgZm9yIHRoaXMgbG9vcCBsb29rcyBsaWtlIHRoaXM6Ci0gICAgICoKLSAgICAgKiAgICAgICAgICAgaW5pdGlhbGl6ZSBpdGVyYXRvcgotICAgICAqICAgICAgICAgICBpbml0aWFsaXplIHZhcmlhYmxlcyA8LS0gSEVSRSEhIQotICAgICAqICAgICAgICAgICBnb3RvICAgSXRlcmF0ZQotICAgICAqICBMb29wOiAgICA6Ci0gICAgICogICAgICAgICAgIDogKGNvZGUgZm9yIDx4c2w6Zm9yLWVhY2g+IGNvbnRlbnRzKQotICAgICAqICAgICAgICAgICA6Ci0gICAgICogIEl0ZXJhdGU6IG5vZGUgPSBpdGVyYXRvci5uZXh0KCk7Ci0gICAgICogICAgICAgICAgIGlmIChub2RlICE9IEVORCkgZ290byBMb29wCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZVZhcmlhYmxlcyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgaW50IG4gPSBlbGVtZW50Q291bnQoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCSAgICBmaW5hbCBPYmplY3QgY2hpbGQgPSBnZXRDb250ZW50cygpLmVsZW1lbnRBdChpKTsKLQkgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgVmFyaWFibGUpIHsKLQkJVmFyaWFibGUgdmFyID0gKFZhcmlhYmxlKWNoaWxkOwotCQl2YXIuaW5pdGlhbGl6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Zvcm1hdE51bWJlckNhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0Zvcm1hdE51bWJlckNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTYzNzlmZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Gb3JtYXROdW1iZXJDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzUgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBGb3JtYXROdW1iZXJDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3ZhbHVlOwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfZm9ybWF0OwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfbmFtZTsKLQotICAgIHB1YmxpYyBGb3JtYXROdW1iZXJDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0JX3ZhbHVlID0gYXJndW1lbnQoMCk7Ci0JX2Zvcm1hdCA9IGFyZ3VtZW50KDEpOwotCV9uYW1lID0gYXJndW1lbnRDb3VudCgpID09IDMgPyBhcmd1bWVudCgyKSA6IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQkvLyBUaGUgc3R5bGVzaGVldCBlbGVtZW50IG9ubHkgYWRkcyBjb2RlIHRvIGluc3RhbmNpYXRlIHRoZQotCS8vIGRlZmF1bHQgRGVjaW1hbEZvcm1hdCBvYmplY3QgaWYgYXQgbGVhc3Qgb25lIGZvcm1hdC1udW1iZXIoKQotCS8vIGNhbGwgZXhpc3RzIGluIHRoZSBzdHlsZXNoZWV0LiBXZSBtdXN0IHNpZ25hbCB0aGlzIGNhbGwuLi4KLQlnZXRTdHlsZXNoZWV0KCkubnVtYmVyRm9ybWF0dGluZ1VzZWQoKTsKLQotCWZpbmFsIFR5cGUgdHZhbHVlID0gX3ZhbHVlLnR5cGVDaGVjayhzdGFibGUpOwotCWlmICh0dmFsdWUgaW5zdGFuY2VvZiBSZWFsVHlwZSA9PSBmYWxzZSkgewotCSAgICBfdmFsdWUgPSBuZXcgQ2FzdEV4cHIoX3ZhbHVlLCBUeXBlLlJlYWwpOwotCX0KLQlmaW5hbCBUeXBlIHRmb3JtYXQgPSBfZm9ybWF0LnR5cGVDaGVjayhzdGFibGUpOwotCWlmICh0Zm9ybWF0IGluc3RhbmNlb2YgU3RyaW5nVHlwZSA9PSBmYWxzZSkgewotCSAgICBfZm9ybWF0ID0gbmV3IENhc3RFeHByKF9mb3JtYXQsIFR5cGUuU3RyaW5nKTsKLQl9Ci0JaWYgKGFyZ3VtZW50Q291bnQoKSA9PSAzKSB7Ci0JICAgIGZpbmFsIFR5cGUgdG5hbWUgPSBfZm9ybWF0LnR5cGVDaGVjayhzdGFibGUpOwotCSAgICBpZiAodG5hbWUgaW5zdGFuY2VvZiBTdHJpbmdUeXBlID09IGZhbHNlKSB7Ci0JCV9uYW1lID0gbmV3IENhc3RFeHByKF9uYW1lLCBUeXBlLlN0cmluZyk7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIF90eXBlID0gVHlwZS5TdHJpbmc7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCV9mb3JtYXQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JZmluYWwgaW50IGZuM2FyZyA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywKLQkJCQkJICAgICJmb3JtYXROdW1iZXIiLAotCQkJCQkgICAgIihETGphdmEvbGFuZy9TdHJpbmc7IisKLQkJCQkJICAgICJMamF2YS90ZXh0L0RlY2ltYWxGb3JtYXQ7KSIrCi0JCQkJCSAgICAiTGphdmEvbGFuZy9TdHJpbmc7Iik7Ci0JZmluYWwgaW50IGdldCA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCSAiZ2V0RGVjaW1hbEZvcm1hdCIsCi0JCQkJCSAiKExqYXZhL2xhbmcvU3RyaW5nOykiKwotCQkJCQkgIkxqYXZhL3RleHQvRGVjaW1hbEZvcm1hdDsiKTsKLQkKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlmIChfbmFtZSA9PSBudWxsKSB7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIENvbnN0YW50cy5FTVBUWVNUUklORykpOwotCX0KLQllbHNlIHsKLQkgICAgX25hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoZ2V0KSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoZm4zYXJnKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRnVuY3Rpb25BdmFpbGFibGVDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GdW5jdGlvbkF2YWlsYWJsZUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTdjNjkxNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GdW5jdGlvbkF2YWlsYWJsZUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgRnVuY3Rpb25BdmFpbGFibGVDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHB1YmxpYyBGdW5jdGlvbkF2YWlsYWJsZUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3JjZSB0aGUgYXJndW1lbnQgdG8gdGhpcyBmdW5jdGlvbiB0byBiZSBhIGxpdGVyYWwgc3RyaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKGFyZ3VtZW50KCkgaW5zdGFuY2VvZiBMaXRlcmFsRXhwcikgewotCSAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0JfQotCXRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5MSVRFUkFMU19FUlIsICJmdW5jdGlvbi1hdmFpbGFibGUiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSByZXN1bHQgdGhhdCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZ2V0UmVzdWx0KCkgewotCWZpbmFsIFBhcnNlciBwYXJzZXIgPSBnZXRQYXJzZXIoKTsKLQlmaW5hbCBMaXRlcmFsRXhwciBhcmcgPSAoTGl0ZXJhbEV4cHIpYXJndW1lbnQoKTsKLQlyZXR1cm4ocGFyc2VyLmZ1bmN0aW9uU3VwcG9ydGVkKGFyZy5nZXRWYWx1ZSgpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2FsbHMgdG8gJ2Z1bmN0aW9uLWF2YWlsYWJsZScgYXJlIHJlc29sdmVkIGF0IGNvbXBpbGUgdGltZSBzaW5jZSAKLSAgICAgKiB0aGUgbmFtZXNwYWNlcyBkZWNsYXJlZCBpbiB0aGUgc3R5bHNoZWV0IGFyZSBub3QgYXZhaWxhYmxlIGF0IHJ1bgotICAgICAqIHRpbWUuIENvbnNlcXVlbnRseSwgYXJndW1lbnRzIHRvIHRoaXMgZnVuY3Rpb24gbXVzdCBiZSBsaXRlcmFscy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgYm9vbGVhbiByZXN1bHQgPSBnZXRSZXN1bHQoKTsKLQltZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKG5ldyBQVVNIKGNwZywgcmVzdWx0KSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvRnVuY3Rpb25DYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GdW5jdGlvbkNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjk4OTFhOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9GdW5jdGlvbkNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU5OCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWNsYXNzIEZ1bmN0aW9uQ2FsbCBleHRlbmRzIEV4cHJlc3Npb24gewotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgVmVjdG9yIF9lbXB0eUFyZ3MgPSBuZXcgVmVjdG9yKDApOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBfamF2YUV4dFByZWZpeCA9IFRSQU5TTEVUX1VSSSArICIvamF2YSI7Ci0gICAgCi0gICAgcHJpdmF0ZSBRTmFtZSAgX2ZuYW1lOwotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9hcmd1bWVudHM7Ci0gICAgCi0gICAgcHJpdmF0ZSBTdHJpbmcgICAgIF9jbGFzc05hbWU7Ci0gICAgcHJpdmF0ZSBNZXRob2QgICAgIF9jaG9zZW5NZXRob2Q7Ci0gICAgcHJpdmF0ZSBNZXRob2RUeXBlIF9jaG9zZW5NZXRob2RUeXBlOwotCi0gICAgLy8gRW5jYXBzdWxhdGVzIGFsbCB1bnN1cHBvcnRlZCBleHRlcm5hbCBmdW5jdGlvbiBjYWxscwotICAgIHByaXZhdGUgYm9vbGVhbiAgICB1bnJlc29sdmVkRXh0ZXJuYWw7Ci0KLSAgICAvLyBMZWdhbCBjb252ZXJzaW9ucyBiZXR3ZWVuIGludGVybmFsIGFuZCBKYXZhIHR5cGVzLgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE11bHRpSGFzaHRhYmxlIF9pbnRlcm5hbDJKYXZhID0gbmV3IE11bHRpSGFzaHRhYmxlKCk7Ci0KLSAgICAvLyBMZWdhbCBjb252ZXJzaW9ucyBiZXR3ZWVuIEphdmEgYW5kIGludGVybmFsIHR5cGVzLgotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2h0YWJsZSBfamF2YTJJbnRlcm5hbCA9IG5ldyBIYXNodGFibGUoKTsKLQkKLSAgICAvKioKLSAgICAgKiBEZWZpbmVzIDIgY29udmVyc2lvbiB0YWJsZXM6Ci0gICAgICogMS4gRnJvbSBpbnRlcm5hbCB0eXBlcyB0byBKYXZhIHR5cGVzIGFuZAotICAgICAqIDIuIEZyb20gSmF2YSB0eXBlcyB0byBpbnRlcm5hbCB0eXBlcy4KLSAgICAgKiBUaGVzZSB0d28gdGFibGVzIGFyZSB1c2VkIHdoZW4gY2FsbGluZyBleHRlcm5hbCAoSmF2YSkgZnVuY3Rpb25zLgotICAgICAqLwotICAgIHN0YXRpYyB7Ci0JdHJ5IHsKLQkgICAgZmluYWwgQ2xhc3Mgc3RyaW5nQ2xhc3MgICA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5TdHJpbmciKTsKLQkgICAgZmluYWwgQ2xhc3Mgbm9kZUNsYXNzICAgICA9IENsYXNzLmZvck5hbWUoIm9yZy53M2MuZG9tLk5vZGUiKTsKLQkgICAgZmluYWwgQ2xhc3Mgbm9kZUxpc3RDbGFzcyA9IENsYXNzLmZvck5hbWUoIm9yZy53M2MuZG9tLk5vZGVMaXN0Iik7Ci0KLQkgICAgLy8gUG9zc2libGUgY29udmVyc2lvbnMgYmV0d2VlbiBpbnRlcm5hbCBhbmQgSmF2YSB0eXBlcwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5Cb29sZWFuLCBCb29sZWFuLlRZUEUpOwotCi0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLkludCwgQ2hhcmFjdGVyLlRZUEUpOwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5JbnQsIEJ5dGUuVFlQRSk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLkludCwgU2hvcnQuVFlQRSk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLkludCwgSW50ZWdlci5UWVBFKTsKLQkgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuSW50LCBMb25nLlRZUEUpOwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5JbnQsIEZsb2F0LlRZUEUpOwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5JbnQsIERvdWJsZS5UWVBFKTsKLQotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBDaGFyYWN0ZXIuVFlQRSk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlJlYWwsIEJ5dGUuVFlQRSk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlJlYWwsIFNob3J0LlRZUEUpOwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBJbnRlZ2VyLlRZUEUpOwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBMb25nLlRZUEUpOwotCSAgICBfaW50ZXJuYWwySmF2YS5wdXQoVHlwZS5SZWFsLCBGbG9hdC5UWVBFKTsKLQkgICAgX2ludGVybmFsMkphdmEucHV0KFR5cGUuUmVhbCwgRG91YmxlLlRZUEUpOwotCi0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlN0cmluZywgc3RyaW5nQ2xhc3MpOwotCi0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGUsIG5vZGVDbGFzcyk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGUsIG5vZGVMaXN0Q2xhc3MpOwotCi0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGVTZXQsIEludGVnZXIuVFlQRSk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGVTZXQsIG5vZGVDbGFzcyk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLk5vZGVTZXQsIG5vZGVMaXN0Q2xhc3MpOwotCi0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlJlc3VsdFRyZWUsIG5vZGVDbGFzcyk7Ci0JICAgIF9pbnRlcm5hbDJKYXZhLnB1dChUeXBlLlJlc3VsdFRyZWUsIG5vZGVMaXN0Q2xhc3MpOwotCi0JICAgIC8vIFBvc3NpYmxlIGNvbnZlcnNpb25zIGJldHdlZW4gSmF2YSBhbmQgaW50ZXJuYWwgdHlwZXMKLQkgICAgX2phdmEySW50ZXJuYWwucHV0KEJvb2xlYW4uVFlQRSwgVHlwZS5Cb29sZWFuKTsKLQotCSAgICBfamF2YTJJbnRlcm5hbC5wdXQoQ2hhcmFjdGVyLlRZUEUsIFR5cGUuUmVhbCk7Ci0JICAgIF9qYXZhMkludGVybmFsLnB1dChCeXRlLlRZUEUsIFR5cGUuUmVhbCk7Ci0JICAgIF9qYXZhMkludGVybmFsLnB1dChTaG9ydC5UWVBFLCBUeXBlLlJlYWwpOwotCSAgICBfamF2YTJJbnRlcm5hbC5wdXQoSW50ZWdlci5UWVBFLCBUeXBlLlJlYWwpOwotCSAgICBfamF2YTJJbnRlcm5hbC5wdXQoTG9uZy5UWVBFLCBUeXBlLlJlYWwpOwotCSAgICBfamF2YTJJbnRlcm5hbC5wdXQoRmxvYXQuVFlQRSwgVHlwZS5SZWFsKTsKLQkgICAgX2phdmEySW50ZXJuYWwucHV0KERvdWJsZS5UWVBFLCBUeXBlLlJlYWwpOwotCi0JICAgIF9qYXZhMkludGVybmFsLnB1dChzdHJpbmdDbGFzcywgVHlwZS5TdHJpbmcpOwotCi0JICAgIC8vIENvbnZlcnNpb25zIGZyb20gb3JnLnczYy5kb20uTm9kZS9Ob2RlTGlzdCBhcmUgbm90IHN1cHBvcnRlZAotCX0KLQljYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbihlKTsKLQkgICAgLy9TeXN0ZW0uZXhpdCgxKTsKLQl9Ci0gICAgfQotCQkKLSAgICBwdWJsaWMgRnVuY3Rpb25DYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0JX2ZuYW1lID0gZm5hbWU7Ci0JX2FyZ3VtZW50cyA9IGFyZ3VtZW50czsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRnVuY3Rpb25DYWxsKFFOYW1lIGZuYW1lKSB7Ci0JdGhpcyhmbmFtZSwgX2VtcHR5QXJncyk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotCXJldHVybihfZm5hbWUudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlpZiAoX2FyZ3VtZW50cyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBuID0gX2FyZ3VtZW50cy5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCWZpbmFsIEV4cHJlc3Npb24gZXhwID0gKEV4cHJlc3Npb24pX2FyZ3VtZW50cy5lbGVtZW50QXQoaSk7Ci0JCWV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLQkJZXhwLnNldFBhcmVudCh0aGlzKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGEgZnVuY3Rpb24gY2FsbC4gU2luY2UgZGlmZmVyZW50IHR5cGUgY29udmVyc2lvbnMgYXBwbHksCi0gICAgICogdHlwZSBjaGVja2luZyBpcyBkaWZmZXJlbnQgZm9yIHN0YW5kYXJkIGFuZCBleHRlcm5hbCAoSmF2YSkgZnVuY3Rpb25zLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLQlmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gX2ZuYW1lLmdldE5hbWVzcGFjZSgpOwotCWZpbmFsIFN0cmluZyBsb2NhbCA9IF9mbmFtZS5nZXRMb2NhbFBhcnQoKTsKLQotCS8vIFhQYXRoIGZ1bmN0aW9ucyBoYXZlIG5vIG5hbWVzcGFjZQotCWlmIChpc1N0YW5kYXJkKCkpIHsKLQkgICAgcmV0dXJuIHR5cGVDaGVja1N0YW5kYXJkKHN0YWJsZSk7Ci0JfQotCS8vIEhhbmRsZSBleHRlbnNpb24gZnVuY3Rpb25zICh0aGV5IGFsbCBoYXZlIGEgbmFtZXNwYWNlKQotCWVsc2UgewotCSAgICBmaW5hbCBpbnQgbGVuID0gX2phdmFFeHRQcmVmaXgubGVuZ3RoKCk7Ci0JICAgIGlmIChuYW1lc3BhY2UuZXF1YWxzKF9qYXZhRXh0UHJlZml4KSkgewotCQlmaW5hbCBpbnQgcG9zID0gbG9jYWwuaW5kZXhPZignLicpOwotCQlfY2xhc3NOYW1lID0gbG9jYWwuc3Vic3RyaW5nKDAsIHBvcyk7Ci0JCV9mbmFtZSA9IG5ldyBRTmFtZShuYW1lc3BhY2UsIG51bGwsIGxvY2FsLnN1YnN0cmluZyhwb3MrMSkpOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKG5hbWVzcGFjZS5sZW5ndGgoKSA+PSBsZW4gJiYKLQkJbmFtZXNwYWNlLnN1YnN0cmluZygwLCBsZW4pLmVxdWFscyhfamF2YUV4dFByZWZpeCkpIHsKLQkJX2NsYXNzTmFtZSA9IG5hbWVzcGFjZS5zdWJzdHJpbmcobGVuICsgMSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCS8qCi0JCSAqIFdhcm4gdXNlciBpZiBleHRlcm5hbCBmdW5jdGlvbiBjb3VsZCBub3QgYmUgcmVzb2x2ZWQuCi0JCSAqIFdhcm5pbmcgd2lsbCBfTk9UXyBiZSBpc3N1ZWQgaXMgdGhlIGNhbGwgaXMgcHJvcGVybHkKLQkJICogd3JhcHBlZCBpbiBhbiA8eHNsOmlmPiBvciA8eHNsOndoZW4+IGVsZW1lbnQuIEZvciBkZXRhaWxzCi0JCSAqIHNlZSBJZi5wYXJzZXJDb250ZW50cygpIGFuZCBXaGVuLnBhcnNlckNvbnRlbnRzKCkKLQkJICovCi0JCWZpbmFsIFBhcnNlciBwYXJzZXIgPSBnZXRQYXJzZXIoKTsKLQkJaWYgKHBhcnNlciAhPSBudWxsKSB7Ci0JCSAgICByZXBvcnRXYXJuaW5nKHRoaXMgLHBhcnNlciwgRXJyb3JNc2cuRlVOUkVTT0xfRVJSLAotCQkJCSAgX2ZuYW1lLnRvU3RyaW5nKCkpOwotCQl9Ci0JCXVucmVzb2x2ZWRFeHRlcm5hbCA9IHRydWU7Ci0JCXJldHVybiBfdHlwZSA9IFR5cGUuVm9pZDsKLQkgICAgfQotCSAgICByZXR1cm4gdHlwZUNoZWNrRXh0ZXJuYWwoc3RhYmxlKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhIGNhbGwgdG8gYSBzdGFuZGFyZCBmdW5jdGlvbi4gSW5zZXJ0IENhc3RFeHBycyB3aGVuIG5lZWRlZC4KLSAgICAgKiBJZiBhcyBhIHJlc3VsdCBvZiB0aGUgaW5zZXJ0aW9uIG9mIGEgQ2FzdEV4cHIgYSB0eXBlIGNoZWNrIGVycm9yIGlzIAotICAgICAqIHRocm93biwgdGhlbiBjYXRjaCBpdCBhbmQgcmUtdGhyb3cgaXQgd2l0aCBhIG5ldyAidGhpcyIuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrU3RhbmRhcmQoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCi0JX2ZuYW1lLmNsZWFyTmFtZXNwYWNlKCk7IC8vIEhBQ0shISEKLQotCWZpbmFsIGludCBuID0gX2FyZ3VtZW50cy5zaXplKCk7Ci0JZmluYWwgVmVjdG9yIGFyZ3NUeXBlID0gdHlwZUNoZWNrQXJncyhzdGFibGUpOwotCWZpbmFsIE1ldGhvZFR5cGUgYXJncyA9IG5ldyBNZXRob2RUeXBlKFR5cGUuVm9pZCwgYXJnc1R5cGUpOwotCWZpbmFsIE1ldGhvZFR5cGUgcHR5cGUgPQotCSAgICBsb29rdXBQcmltb3Aoc3RhYmxlLCBfZm5hbWUuZ2V0TG9jYWxQYXJ0KCksIGFyZ3MpOwotCi0JaWYgKHB0eXBlICE9IG51bGwpIHsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkJZmluYWwgVHlwZSBhcmdUeXBlID0gKFR5cGUpIHB0eXBlLmFyZ3NUeXBlKCkuZWxlbWVudEF0KGkpOwotCQlmaW5hbCBFeHByZXNzaW9uIGV4cCA9IChFeHByZXNzaW9uKV9hcmd1bWVudHMuZWxlbWVudEF0KGkpOwotCQlpZiAoIWFyZ1R5cGUuaWRlbnRpY2FsVG8oZXhwLmdldFR5cGUoKSkpIHsKLQkJICAgIHRyeSB7Ci0JCQlfYXJndW1lbnRzLnNldEVsZW1lbnRBdChuZXcgQ2FzdEV4cHIoZXhwLCBhcmdUeXBlKSwgaSk7Ci0JCSAgICB9Ci0JCSAgICBjYXRjaCAoVHlwZUNoZWNrRXJyb3IgZSkgewotCQkJdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwkvLyBpbnZhbGlkIGNvbnZlcnNpb24KLQkJICAgIH0KLQkJfQotCSAgICB9Ci0JICAgIF9jaG9zZW5NZXRob2RUeXBlID0gcHR5cGU7Ci0JICAgIHJldHVybiBfdHlwZSA9IHB0eXBlLnJlc3VsdFR5cGUoKTsKLQl9Ci0JdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgYSBjYWxsIHRvIGFuIGV4dGVybmFsIChKYXZhKSBtZXRob2QuCi0gICAgICogVGhlIG1ldGhvZCBtdXN0IGJlIHN0YXRpYyBhbiBwdWJsaWMsIGFuZCBhIGxlZ2FsIHR5cGUgY29udmVyc2lvbgotICAgICAqIG11c3QgZXhpc3QgZm9yIGFsbCBpdHMgYXJndW1lbnRzIGFuZCBpdHMgcmV0dXJuIHR5cGUuCi0gICAgICogRXZlcnkgbWV0aG9kIG9mIG5hbWUgPGNvZGU+X2ZuYW1lPC9jb2RlPiBpcyBpbnNwZWN0ZWQKLSAgICAgKiBhcyBhIHBvc3NpYmxlIGNhbmRpZGF0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2tFeHRlcm5hbChTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JZmluYWwgVmVjdG9yIG1ldGhvZHMgPSBmaW5kTWV0aG9kcygpOwotCQotCWlmIChtZXRob2RzID09IG51bGwpIHsKLQkgICAgLy8gTWV0aG9kIG5vdCBmb3VuZCBpbiB0aGlzIGNsYXNzCi0JICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihFcnJvck1zZy5NRVRVTkRFRl9FUlIsIAotCQkJCSAgICAgX2ZuYW1lLmdldExvY2FsUGFydCgpKTsKLQl9Ci0KLQlmaW5hbCBpbnQgbk1ldGhvZHMgPSBtZXRob2RzLnNpemUoKTsKLQlmaW5hbCBpbnQgbkFyZ3MgPSBfYXJndW1lbnRzLnNpemUoKTsKLQlmaW5hbCBWZWN0b3IgYXJnc1R5cGUgPSB0eXBlQ2hlY2tBcmdzKHN0YWJsZSk7Ci0KLQkvLyBUcnkgYWxsIG1ldGhvZHMgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoaXMgZnVuY3Rpb24KLQlmb3IgKGludCBqLCBpID0gMDsgaSA8IG5NZXRob2RzOyBpKyspIHsKLQotCSAgICAvLyBDaGVjayBpZiBhbGwgcGFyYW10ZXRlcnMgdG8gdGhpcyBtZXRob2QgY2FuIGJlIGNvbnZlcnRlZAotCSAgICBmaW5hbCBNZXRob2QgbWV0aG9kID0gKE1ldGhvZCltZXRob2RzLmVsZW1lbnRBdChpKTsKLQkgICAgZmluYWwgQ2xhc3NbXSBwYXJhbVR5cGVzID0gbWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0JICAgIGZvciAoaiA9IDA7IGogPCBuQXJnczsgaisrKSB7Ci0JCS8vIENvbnZlcnQgZnJvbSBpbnRlcm5hbCAodHJhbnNsZXQpIHR5cGUgdG8gZXh0ZXJuYWwgKEphdmEpIHR5cGUKLQkJZmluYWwgVHlwZSBpbnRUeXBlID0gKFR5cGUpYXJnc1R5cGUuZWxlbWVudEF0KGopOwotCQlmaW5hbCBDbGFzcyBleHRUeXBlID0gcGFyYW1UeXBlc1tqXTsKLQkJaWYgKCFfaW50ZXJuYWwySmF2YS5tYXBzKGludFR5cGUsIGV4dFR5cGUpKSBicmVhazsKLQkgICAgfQotCi0JICAgIGlmIChqID09IG5BcmdzKSB7Ci0JCS8vIENoZWNrIGlmIHRoZSByZXR1cm4gdHlwZSBjYW4gYmUgY29udmVydGVkCi0JCWZpbmFsIENsYXNzIGV4dFR5cGUgPSBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpOwotCQlpZiAoZXh0VHlwZS5nZXROYW1lKCkuZXF1YWxzKCJ2b2lkIikpCi0JCSAgICBfdHlwZSA9IFR5cGUuVm9pZDsKLQkJZWxzZQotCQkgICAgX3R5cGUgPSAoVHlwZSlfamF2YTJJbnRlcm5hbC5nZXQoZXh0VHlwZSk7Ci0JCS8vIFVzZSB0aGlzIG1ldGhvZCBpZiBhbGwgcGFyYW1ldGVycyAmIHJldHVybiB0eXBlIG1hdGNoCi0JCWlmIChfdHlwZSAhPSBudWxsKSB7Ci0JCSAgICBfY2hvc2VuTWV0aG9kID0gbWV0aG9kOwotCQkgICAgcmV0dXJuIF90eXBlOwotCQl9Ci0JICAgIH0KLQl9Ci0KLQlTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigiQXR0ZW1wdGVkIHRvIGNhbGwgbWV0aG9kICIpOwotCWJ1Zi5hcHBlbmQoX2NsYXNzTmFtZSk7Ci0JYnVmLmFwcGVuZCgnLicpOwotCWJ1Zi5hcHBlbmQoX2ZuYW1lLmdldExvY2FsUGFydCgpKTsKLQlidWYuYXBwZW5kKCcoJyk7Ci0JZm9yIChpbnQgYT0wOyBhPG5BcmdzOyBhKyspIHsKLQkgICAgZmluYWwgVHlwZSBpbnRUeXBlID0gKFR5cGUpYXJnc1R5cGUuZWxlbWVudEF0KGEpOwotCSAgICBidWYuYXBwZW5kKGludFR5cGUudG9TdHJpbmcoKSk7Ci0JICAgIGlmIChhIDwgKG5BcmdzLTEpKSBidWYuYXBwZW5kKCIsICIpOwotCX0KLQlidWYuYXBwZW5kKCIpOyIpOwotCWdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5XQVJOSU5HLG5ldyBFcnJvck1zZyhidWYudG9TdHJpbmcoKSkpOwotCi0JdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKEVycm9yTXNnLkNBTk5PVENWX0VSUiwgCi0JCQkJIF9mbmFtZS5nZXRMb2NhbFBhcnQoKSwKLQkJCQkgX2NsYXNzTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayB0aGUgYWN0dWFsIGFyZ3VtZW50cyBvZiB0aGlzIGZ1bmN0aW9uIGNhbGwuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciB0eXBlQ2hlY2tBcmdzKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBWZWN0b3IgcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotCWZpbmFsIEVudW1lcmF0aW9uIGUgPSBfYXJndW1lbnRzLmVsZW1lbnRzKCk7CQotCXdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIGZpbmFsIEV4cHJlc3Npb24gZXhwID0gKEV4cHJlc3Npb24pZS5uZXh0RWxlbWVudCgpOwotCSAgICByZXN1bHQuYWRkRWxlbWVudChleHAudHlwZUNoZWNrKHN0YWJsZSkpOwotCX0KLQlyZXR1cm4gcmVzdWx0OwotICAgIH0KLQotICAgIHByb3RlY3RlZCBmaW5hbCBFeHByZXNzaW9uIGFyZ3VtZW50KGludCBpKSB7Ci0JcmV0dXJuIChFeHByZXNzaW9uKV9hcmd1bWVudHMuZWxlbWVudEF0KGkpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCBmaW5hbCBFeHByZXNzaW9uIGFyZ3VtZW50KCkgewotCXJldHVybiBhcmd1bWVudCgwKTsKLSAgICB9Ci0gICAgCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCBhcmd1bWVudENvdW50KCkgewotCXJldHVybiBfYXJndW1lbnRzLnNpemUoKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRBcmd1bWVudChpbnQgaSwgRXhwcmVzc2lvbiBleHApIHsKLQlfYXJndW1lbnRzLnNldEVsZW1lbnRBdChleHAsIGkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgdGhlIGZ1bmN0aW9uIGNhbGwgYW5kIHRyZWF0IGFzIGFuIGV4cHJlc3Npb24KLSAgICAgKiBVcGRhdGUgdHJ1ZS9mYWxzZS1saXN0cy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVEZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0KLQlUeXBlIHR5cGUgPSBUeXBlLkJvb2xlYW47Ci0JaWYgKF9jaG9zZW5NZXRob2RUeXBlICE9IG51bGwpCi0JICAgIHR5cGUgPSBfY2hvc2VuTWV0aG9kVHlwZS5yZXN1bHRUeXBlKCk7Ci0KLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JdHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JaWYgKCh0eXBlIGluc3RhbmNlb2YgQm9vbGVhblR5cGUpIHx8ICh0eXBlIGluc3RhbmNlb2YgSW50VHlwZSkpIHsKLQkgICAgX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7Ci0JfQotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIGEgZnVuY3Rpb24gY2FsbC4gVGhlIGNvbXBpbGVkIGNvZGUgd2lsbCBsZWF2ZSB0aGUgZnVuY3Rpb24ncwotICAgICAqIHJldHVybiB2YWx1ZSBvbiB0aGUgSlZNJ3Mgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgaW50IG4gPSBhcmd1bWVudENvdW50KCk7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbnQgaW5kZXg7Ci0KLQkvLyBUcmFuc2xhdGUgY2FsbHMgdG8gbWV0aG9kcyBpbiB0aGUgQmFzaXNMaWJyYXJ5Ci0JaWYgKGlzU3RhbmRhcmQoKSkgewotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCQlmaW5hbCBFeHByZXNzaW9uIGV4cCA9IGFyZ3VtZW50KGkpOwotCQlleHAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQlleHAuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICB9Ci0KLQkgICAgLy8gYXBwZW5kICJGIiB0byB0aGUgZnVuY3Rpb24ncyBuYW1lCi0JICAgIGZpbmFsIFN0cmluZyBuYW1lID0gX2ZuYW1lLnRvU3RyaW5nKCkucmVwbGFjZSgnLScsICdfJykgKyAiRiI7Ci0JICAgIFN0cmluZyBhcmdzID0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotCi0JICAgIC8vIFNwZWNpYWwgcHJlY2F1dGlvbnMgZm9yIHNvbWUgbWV0aG9kIGNhbGxzCi0JICAgIGlmIChuYW1lLmVxdWFscygic3VtRiIpKSB7Ci0JCWFyZ3MgPSBET01fSU5URl9TSUc7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibm9ybWFsaXplX3NwYWNlRiIpKSB7Ci0JCWlmIChfY2hvc2VuTWV0aG9kVHlwZS50b1NpZ25hdHVyZShhcmdzKS4KLQkJICAgIGVxdWFscygiKClMamF2YS9sYW5nL1N0cmluZzsiKSkgewotCQkgICAgYXJncyA9ICJJIitET01fSU5URl9TSUc7Ci0JCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLQkJICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkJfQotCSAgICB9Ci0KLQkgICAgLy8gSW52b2tlIHRoZSBtZXRob2QgaW4gdGhlIGJhc2lzIGxpYnJhcnkKLQkgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsIG5hbWUsCi0JCQkJICAgICBfY2hvc2VuTWV0aG9kVHlwZS50b1NpZ25hdHVyZShhcmdzKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0JfQotCS8vIEFkZCBjYWxsIHRvIEJhc2lzTGlicmFyeS51bnJlc29sdmVkX2V4dGVybmFsRigpIHRvIGdlbmVyYXRlCi0JLy8gcnVuLXRpbWUgZXJyb3IgbWVzc2FnZSBmb3IgdW5zdXBwb3J0ZWQgZXh0ZXJuYWwgZnVuY3Rpb25zCi0JZWxzZSBpZiAodW5yZXNvbHZlZEV4dGVybmFsKSB7Ci0JICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotCQkJCSAgICAgInVucmVzb2x2ZWRfZXh0ZXJuYWxGIiwKLQkJCQkgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2ZuYW1lLnRvU3RyaW5nKCkpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLQl9Ci0JLy8gSW52b2tlIGZ1bmN0aW9uIGNhbGxzIHRoYXQgYXJlIGhhbmRsZWQgaW4gc2VwYXJhdGUgY2xhc3NlcwotCWVsc2UgewotCSAgICBmaW5hbCBTdHJpbmcgY2xhenogPSBfY2hvc2VuTWV0aG9kLmdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpOwotCSAgICBDbGFzc1tdIHBhcmFtVHlwZXMgPSBfY2hvc2VuTWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0KLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkJZmluYWwgRXhwcmVzc2lvbiBleHAgPSBhcmd1bWVudChpKTsKLQkJZXhwLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJLy8gQ29udmVydCB0aGUgYXJndW1lbnQgdG8gaXRzIEphdmEgdHlwZQotCQlleHAuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQlleHAuX3R5cGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgcGFyYW1UeXBlc1tpXSk7Ci0JICAgIH0KLQotCSAgICBmaW5hbCBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCSAgICBidWZmZXIuYXBwZW5kKCcoJyk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1UeXBlcy5sZW5ndGg7IGkrKykgewotCQlidWZmZXIuYXBwZW5kKGdldFNpZ25hdHVyZShwYXJhbVR5cGVzW2ldKSk7Ci0JICAgIH0KLQkgICAgYnVmZmVyLmFwcGVuZCgnKScpOwotCSAgICBidWZmZXIuYXBwZW5kKGdldFNpZ25hdHVyZShfY2hvc2VuTWV0aG9kLmdldFJldHVyblR5cGUoKSkpOwotCi0JICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihjbGF6eiwKLQkJCQkgICAgIF9mbmFtZS5nZXRMb2NhbFBhcnQoKSwKLQkJCQkgICAgIGJ1ZmZlci50b1N0cmluZygpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLQotCSAgICAvLyBDb252ZXJ0IHRoZSByZXR1cm4gdHlwZSBiYWNrIHRvIG91ciBpbnRlcm5hbCB0eXBlCi0JICAgIF90eXBlLnRyYW5zbGF0ZUZyb20oY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQlfY2hvc2VuTWV0aG9kLmdldFJldHVyblR5cGUoKSk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJmdW5jYWxsKCIgKyBfZm5hbWUgKyAiLCAiICsgX2FyZ3VtZW50cyArICcpJzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YW5kYXJkKCkgewotCWZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSBfZm5hbWUuZ2V0TmFtZXNwYWNlKCk7Ci0JaWYgKChuYW1lc3BhY2UgPT0gbnVsbCkgfHwgKG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkpCi0JICAgIHJldHVybiB0cnVlOwotCWVsc2UKLQkgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSB2ZWN0b3Igd2l0aCBhbGwgbWV0aG9kcyBuYW1lZCA8Y29kZT5fZm5hbWU8L2NvZGU+Ci0gICAgICogYWZ0ZXIgc3RyaXBwaW5nIGl0cyBuYW1lc3BhY2Ugb3IgPGNvZGU+bnVsbDwvY29kZT4KLSAgICAgKiBpZiBubyBzdWNoIG1ldGhvZHMgZXhpc3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBWZWN0b3IgZmluZE1ldGhvZHMoKSB7Ci0JVmVjdG9yIHJlc3VsdCA9IG51bGw7Ci0JZmluYWwgU3RyaW5nIG5hbWVzcGFjZSA9IF9mbmFtZS5nZXROYW1lc3BhY2UoKTsKLQotCWlmIChuYW1lc3BhY2Uuc3RhcnRzV2l0aChfamF2YUV4dFByZWZpeCkpIHsKLQkgICAgZmluYWwgaW50IG5BcmdzID0gX2FyZ3VtZW50cy5zaXplKCk7Ci0JICAgIHRyeSB7Ci0JCWZpbmFsIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShfY2xhc3NOYW1lKTsKLQkJaWYgKGNsYXp6ID09IG51bGwpIHsKLQkJICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9Ci0JCQluZXcgRXJyb3JNc2coRXJyb3JNc2cuQ0xTVU5ERUZfRVJSLCBfY2xhc3NOYW1lKTsKLQkJICAgIGdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbXNnKTsKLQkJfQotCQllbHNlIHsKLQkJICAgIGZpbmFsIFN0cmluZyBtZXRob2ROYW1lID0gX2ZuYW1lLmdldExvY2FsUGFydCgpOwotCQkgICAgZmluYWwgTWV0aG9kW10gbWV0aG9kcyA9IGNsYXp6LmdldERlY2xhcmVkTWV0aG9kcygpOwotCi0JCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspIHsKLQkJCWZpbmFsIGludCBtb2RzID0gbWV0aG9kc1tpXS5nZXRNb2RpZmllcnMoKTsKLQotCQkJLy8gSXMgaXQgcHVibGljLCBzdGF0aWMgYW5kIHNhbWUgbnVtYmVyIG9mIGFyZ3MgPwotCQkJaWYgKE1vZGlmaWVyLmlzUHVibGljKG1vZHMpCi0JCQkgICAgJiYgTW9kaWZpZXIuaXNTdGF0aWMobW9kcykKLQkJCSAgICAmJiBtZXRob2RzW2ldLmdldE5hbWUoKS5lcXVhbHMobWV0aG9kTmFtZSkKLQkJCSAgICAmJiBtZXRob2RzW2ldLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoID09IG5BcmdzKQotCQkJICAgIHsKLQkJCQlpZiAocmVzdWx0ID09IG51bGwpIHsKLQkJCQkgICAgcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotCQkJCX0KLQkJCQlyZXN1bHQuYWRkRWxlbWVudChtZXRob2RzW2ldKTsKLQkJCSAgICB9Ci0JCSAgICB9Ci0JCX0KLQkgICAgfQotCSAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0JCWZpbmFsIEVycm9yTXNnIG1zZyA9Ci0JCSAgICBuZXcgRXJyb3JNc2coRXJyb3JNc2cuQ0xTVU5ERUZfRVJSLCBfY2xhc3NOYW1lKTsKLQkJZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotCSAgICB9Ci0JfQotCXJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSB0aGUgSlZNIHNpZ25hdHVyZSBmb3IgdGhlIGNsYXNzLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKENsYXNzIGNsYXp6KSB7Ci0JaWYgKGNsYXp6LmlzQXJyYXkoKSkgewotCSAgICBmaW5hbCBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0JICAgIENsYXNzIGNsID0gY2xheno7Ci0JICAgIHdoaWxlIChjbC5pc0FycmF5KCkpIHsKLQkJc2IuYXBwZW5kKCJbIik7Ci0JCWNsID0gY2wuZ2V0Q29tcG9uZW50VHlwZSgpOwotCSAgICB9Ci0JICAgIHNiLmFwcGVuZChnZXRTaWduYXR1cmUoY2wpKTsKLQkgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0JfQotCWVsc2UgaWYgKGNsYXp6LmlzUHJpbWl0aXZlKCkpIHsKLQkgICAgaWYgKGNsYXp6ID09IEludGVnZXIuVFlQRSkgewotCQlyZXR1cm4gIkkiOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKGNsYXp6ID09IEJ5dGUuVFlQRSkgewotCQlyZXR1cm4gIkIiOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKGNsYXp6ID09IExvbmcuVFlQRSkgewotCQlyZXR1cm4gIkoiOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKGNsYXp6ID09IEZsb2F0LlRZUEUpIHsKLQkJcmV0dXJuICJGIjsKLQkgICAgfQotCSAgICBlbHNlIGlmIChjbGF6eiA9PSBEb3VibGUuVFlQRSkgewotCQlyZXR1cm4gIkQiOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKGNsYXp6ID09IFNob3J0LlRZUEUpIHsKLQkJcmV0dXJuICJTIjsKLQkgICAgfQotCSAgICBlbHNlIGlmIChjbGF6eiA9PSBDaGFyYWN0ZXIuVFlQRSkgewotCQlyZXR1cm4gIkMiOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKGNsYXp6ID09IEJvb2xlYW4uVFlQRSkgewotCQlyZXR1cm4gIloiOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKGNsYXp6ID09IFZvaWQuVFlQRSkgewotCQlyZXR1cm4gIlYiOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQl0aHJvdyBuZXcgRXJyb3IoInVua25vd24gdHlwZSBpbiBnZXRTaWduYXR1cmUiKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgcmV0dXJuICJMIiArIGNsYXp6LmdldE5hbWUoKS5yZXBsYWNlKCcuJywgJy8nKSArICc7JzsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSB0aGUgSlZNIG1ldGhvZCBkZXNjcmlwdG9yIGZvciB0aGUgbWV0aG9kLgotICAgICAqLwotICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0U2lnbmF0dXJlKE1ldGhvZCBtZXRoKSB7Ci0JZmluYWwgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCXNiLmFwcGVuZCgnKCcpOwotCWZpbmFsIENsYXNzW10gcGFyYW1zID0gbWV0aC5nZXRQYXJhbWV0ZXJUeXBlcygpOyAvLyBhdm9pZCBjbG9uZQotCWZvciAoaW50IGogPSAwOyBqIDwgcGFyYW1zLmxlbmd0aDsgaisrKSB7Ci0JICAgIHNiLmFwcGVuZChnZXRTaWduYXR1cmUocGFyYW1zW2pdKSk7Ci0JfQotCXJldHVybiBzYi5hcHBlbmQoJyknKS5hcHBlbmQoZ2V0U2lnbmF0dXJlKG1ldGguZ2V0UmV0dXJuVHlwZSgpKSkKLQkgICAgLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcHV0ZSB0aGUgSlZNIGNvbnN0cnVjdG9yIGRlc2NyaXB0b3IgZm9yIHRoZSBjb25zdHJ1Y3Rvci4KLSAgICAgKi8KLSAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGdldFNpZ25hdHVyZShDb25zdHJ1Y3RvciBjb25zKSB7Ci0JZmluYWwgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCXNiLmFwcGVuZCgnKCcpOwotCWZpbmFsIENsYXNzW10gcGFyYW1zID0gY29ucy5nZXRQYXJhbWV0ZXJUeXBlcygpOyAvLyBhdm9pZCBjbG9uZQotCWZvciAoaW50IGogPSAwOyBqIDwgcGFyYW1zLmxlbmd0aDsgaisrKSB7Ci0JICAgIHNiLmFwcGVuZChnZXRTaWduYXR1cmUocGFyYW1zW2pdKSk7Ci0JfQotCXJldHVybiBzYi5hcHBlbmQoIilWIikudG9TdHJpbmcoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9HZW5lcmF0ZUlkQ2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvR2VuZXJhdGVJZENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjk2NTE5YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9HZW5lcmF0ZUlkQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEdlbmVyYXRlSWRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgR2VuZXJhdGVJZENhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWYgKGFyZ3VtZW50Q291bnQoKSA9PSAwKSB7Ci0JICAgIGlsLmFwcGVuZChuZXcgSUxPQUQobWV0aG9kR2VuLmdldExvY2FsSW5kZXgoImN1cnJlbnQiKSkpOwotCX0KLQllbHNlIHsJCQkvLyBvbmUgYXJndW1lbnQKLQkgICAgYXJndW1lbnQoKS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCQkgICAgImdlbmVyYXRlX2lkRiIsCi0JCQkJCQkgICAgLy8gcmV1c2Ugc2lnbmF0dXJlCi0JCQkJCQkgICAgR0VUX05PREVfTkFNRV9TSUcpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSWRLZXlQYXR0ZXJuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JZEtleVBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmEwODM2ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JZEtleVBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1MSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWFic3RyYWN0IGNsYXNzIElkS2V5UGF0dGVybiBleHRlbmRzIExvY2F0aW9uUGF0aFBhdHRlcm4gewotCi0gICAgcHJvdGVjdGVkIFJlbGF0aXZlUGF0aFBhdHRlcm4gX2xlZnQgPSBudWxsOzsKLSAgICBwcml2YXRlIFN0cmluZyBfaW5kZXggPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF92YWx1ZSA9IG51bGw7OwotCi0gICAgcHVibGljIElkS2V5UGF0dGVybihTdHJpbmcgaW5kZXgsIFN0cmluZyB2YWx1ZSkgewotCV9pbmRleCA9IGluZGV4OwotCV92YWx1ZSA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW5kZXhOYW1lKCkgewotCXJldHVybihfaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIFR5cGUuTm9kZVNldDsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZCgpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHNldExlZnQoUmVsYXRpdmVQYXRoUGF0dGVybiBsZWZ0KSB7Ci0JX2xlZnQgPSBsZWZ0OwotICAgIH0KLQotICAgIHB1YmxpYyBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCkgewotCXJldHVybihudWxsKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgcmVkdWNlS2VybmVsUGF0dGVybigpIHsgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gImlkL2tleVBhdHRlcm4oIiArIF9pbmRleCArICIsICIgKyBfdmFsdWUgKyAnKSc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIGNvbnN0cnVjdG9yIGlzIGNvbXBpbGVkIGluCi0gICAgICogU3R5bGVzaGVldC5jb21waWxlQ29uc3RydWN0b3IoKSBhbmQgbm90IGFzIHRoZSBzeW50YXggdHJlZSBpcyB0cmF2ZXJzZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0KLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gUmV0dXJucyB0aGUgS2V5SW5kZXggb2JqZWN0IG9mIGEgZ2l2ZW4gbmFtZQotCWZpbmFsIGludCBnZXRLZXlJbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkgImdldEtleUluZGV4IiwKLQkJCQkJCSAiKExqYXZhL2xhbmcvU3RyaW5nOykiKwotCQkJCQkJIEtFWV9JTkRFWF9TSUcpOwotCQotCS8vIEluaXRpYWxpc2VzIGEgS2V5SW5kZXggdG8gcmV0dXJuIG5vZGVzIHdpdGggc3BlY2lmaWMgdmFsdWVzCi0JZmluYWwgaW50IGxvb2t1cElkID0gY3BnLmFkZE1ldGhvZHJlZihLRVlfSU5ERVhfQ0xBU1MsCi0JCQkJCSAgICAgICJjb250YWluc0lEIiwKLQkJCQkJICAgICAgIihJTGphdmEvbGFuZy9PYmplY3Q7KUkiKTsKLQlmaW5hbCBpbnQgbG9va3VwS2V5ID0gY3BnLmFkZE1ldGhvZHJlZihLRVlfSU5ERVhfQ0xBU1MsCi0JCQkJCSAgICAgICAiY29udGFpbnNLZXkiLAotCQkJCQkgICAgICAgIihJTGphdmEvbGFuZy9PYmplY3Q7KUkiKTsKLQotCS8vIENhbGwgZ2V0S2V5SW5kZXggaW4gQWJzdHJhY3RUcmFuc2xldCB3aXRoIHRoZSBuYW1lIG9mIHRoZSBrZXkKLQkvLyB0byBnZXQgdGhlIGluZGV4IGZvciB0aGlzIGtleSAod2hpY2ggaXMgYWxzbyBhIG5vZGUgaXRlcmF0b3IpLgotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZyxfaW5kZXgpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoZ2V0S2V5SW5kZXgpKTsKLQkKLQkvLyBOb3cgdXNlIHRoZSB2YWx1ZSBpbiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGRldGVybWluZSB3aGF0IG5vZGVzCi0JLy8gdGhlIGl0ZXJhdG9yIHNob3VsZCByZXR1cm4uCi0JaWwuYXBwZW5kKFNXQVApOwotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsX3ZhbHVlKSk7Ci0JaWYgKHRoaXMgaW5zdGFuY2VvZiBJZFBhdHRlcm4pCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChsb29rdXBJZCkpOwotCWVsc2UKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGxvb2t1cEtleSkpOwotCi0JX3RydWVMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGTkUobnVsbCkpKTsKLQlfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpKTsKLSAgICB9Ci0KLX0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSWRQYXR0ZXJuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JZFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE1MGE3Ni4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JZFBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc0ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIElkUGF0dGVybiBleHRlbmRzIElkS2V5UGF0dGVybiB7Ci0KLSAgICBwdWJsaWMgSWRQYXR0ZXJuKFN0cmluZyBpZCkgewotCXN1cGVyKCIjI2lkIixpZCk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JZi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSWYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjg3MjA4ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JZi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIElmIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF90ZXN0OwotICAgIHByaXZhdGUgYm9vbGVhbiAgICBfaWdub3JlID0gZmFsc2U7Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5IHRoZSBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIklmIik7Ci0JaW5kZW50KGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0JU3lzdGVtLm91dC5wcmludCgidGVzdCAiKTsKLQlVdGlsLnByaW50bG4oX3Rlc3QudG9TdHJpbmcoKSk7Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlICJ0ZXN0IiBleHByZXNzaW9uIGFuZCBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JLy8gUGFyc2UgdGhlICJ0ZXN0IiBleHByZXNzaW9uCi0JX3Rlc3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJ0ZXN0IiwgbnVsbCk7Ci0KLSAgICAgICAgLy8gTWFrZSBzdXJlIHJlcXVpcmVkIGF0dHJpYnV0ZShzKSBoYXZlIGJlZW4gc2V0Ci0gICAgICAgIGlmIChfdGVzdC5pc0R1bW15KCkpIHsKLQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5OUkVRQVRUUl9FUlIsICJ0ZXN0Iik7Ci0JICAgIHJldHVybjsKLSAgICAgICAgfQotCi0JLy8gV2Ugd2lsbCBpZ25vcmUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgPHhzbDppZj4gaWYgd2Uga25vdyB0aGF0IHRoZQotCS8vIHRlc3Qgd2lsbCBhbHdheXMgcmV0dXJuICdmYWxzZScuCi0JaWYgKF90ZXN0IGluc3RhbmNlb2YgRWxlbWVudEF2YWlsYWJsZUNhbGwpIHsKLQkgICAgRWxlbWVudEF2YWlsYWJsZUNhbGwgY2FsbCA9IChFbGVtZW50QXZhaWxhYmxlQ2FsbClfdGVzdDsKLQkgICAgX2lnbm9yZSA9ICFjYWxsLmdldFJlc3VsdCgpOwotCSAgICByZXR1cm47Ci0JfQotCWlmIChfdGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uQXZhaWxhYmxlQ2FsbCkgewotCSAgICBGdW5jdGlvbkF2YWlsYWJsZUNhbGwgY2FsbCA9IChGdW5jdGlvbkF2YWlsYWJsZUNhbGwpX3Rlc3Q7Ci0JICAgIF9pZ25vcmUgPSAhY2FsbC5nZXRSZXN1bHQoKTsKLQkgICAgcmV0dXJuOwotCX0KLQotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlLWNoZWNrIHRoZSAidGVzdCIgZXhwcmVzc2lvbiBhbmQgY29udGVudHMgb2YgdGhpcyBlbGVtZW50LgotICAgICAqIFRoZSBjb250ZW50cyB3aWxsIGJlIGlnbm9yZWQgaWYgd2Uga25vdyB0aGUgdGVzdCB3aWxsIGFsd2F5cyBmYWlsLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JLy8gVHlwZS1jaGVjayB0aGUgInRlc3QiIGV4cHJlc3Npb24KLQlpZiAoX3Rlc3QudHlwZUNoZWNrKHN0YWJsZSkgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSA9PSBmYWxzZSkgewotCSAgICBfdGVzdCA9IG5ldyBDYXN0RXhwcihfdGVzdCwgVHlwZS5Cb29sZWFuKTsKLQl9Ci0JLy8gVHlwZSBjaGVjayB0aGUgZWxlbWVudCBjb250ZW50cwotCWlmICghX2lnbm9yZSkgewotCSAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCX0KLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGUgInRlc3QiIGV4cHJlc3Npb24gYW5kIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudC4KLSAgICAgKiBUaGUgY29udGVudHMgd2lsbCBiZSBpZ25vcmVkIGlmIHdlIGtub3cgdGhlIHRlc3Qgd2lsbCBhbHdheXMgZmFpbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JX3Rlc3QudHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkvLyByZW1lbWJlciBlbmQgb2YgY29uZGl0aW9uCi0JZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgdHJ1ZWMgPSBpbC5nZXRFbmQoKTsKLQlpZiAoIV9pZ25vcmUpIHsKLQkgICAgdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCV90ZXN0LmJhY2tQYXRjaEZhbHNlTGlzdChpbC5hcHBlbmQoTk9QKSk7Ci0JX3Rlc3QuYmFja1BhdGNoVHJ1ZUxpc3QodHJ1ZWMuZ2V0TmV4dCgpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JbGxlZ2FsQ2hhckV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSWxsZWdhbENoYXJFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDBjZWU2Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JbGxlZ2FsQ2hhckV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWNsYXNzIElsbGVnYWxDaGFyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLSAgICBwdWJsaWMgSWxsZWdhbENoYXJFeGNlcHRpb24oU3RyaW5nIHMpIHsKLQlzdXBlcihzKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JbXBvcnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ltcG9ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OGQ3ZjllLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0ltcG9ydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU2ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgR3VubmxhdWd1ciBCcmllbSA8Z3RoYkBkaW1vbi5pcz4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLQotZmluYWwgY2xhc3MgSW1wb3J0IGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIHByaXZhdGUgU3R5bGVzaGVldCBfaW1wb3J0ZWQgPSBudWxsOwotCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0SW1wb3J0ZWRTdHlsZXNoZWV0KCkgewotCXJldHVybihfaW1wb3J0ZWQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoZmluYWwgUGFyc2VyIHBhcnNlcikgewotCWZpbmFsIFN0eWxlc2hlZXQgY29udGV4dCA9IHBhcnNlci5nZXRDdXJyZW50U3R5bGVzaGVldCgpOwotCXRyeSB7Ci0JICAgIFN0cmluZyBkb2NUb0xvYWQgPSBnZXRBdHRyaWJ1dGUoImhyZWYiKTsKLQkgICAgaWYgKGNvbnRleHQuY2hlY2tGb3JMb29wKGRvY1RvTG9hZCkpIHsKLQkJZmluYWwgaW50IGVycm5vID0gRXJyb3JNc2cuQ0lSQ1VMQVJfSU5DOwotCQlmaW5hbCBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coZXJybm8sIGRvY1RvTG9hZCwgdGhpcyk7Ci0JCXBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG1zZyk7Ci0JCXJldHVybjsKLQkgICAgfQotCi0JICAgIGZpbmFsIFN0cmluZyBjdXJyTG9hZGVkRG9jID0gY29udGV4dC5nZXRTeXN0ZW1JZCgpOwotCSAgICBTb3VyY2VMb2FkZXIgbG9hZGVyID0gY29udGV4dC5nZXRTb3VyY2VMb2FkZXIoKTsKLQkgICAgSW5wdXRTb3VyY2UgaW5wdXQgPSBudWxsOwotCi0JICAgIGlmIChsb2FkZXIgIT0gbnVsbCkgewotCQlmaW5hbCBYU0xUQyB4c2x0YyA9IHBhcnNlci5nZXRYU0xUQygpOwotCQlpbnB1dCA9IGxvYWRlci5sb2FkU291cmNlKGRvY1RvTG9hZCwgY3VyckxvYWRlZERvYywgeHNsdGMpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlmaW5hbCBVUkwgdXJsID0gbmV3IFVSTChuZXcgVVJMKGN1cnJMb2FkZWREb2MpLCBkb2NUb0xvYWQpOwotCQlkb2NUb0xvYWQgPSB1cmwudG9TdHJpbmcoKTsKLQkJaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoZG9jVG9Mb2FkKTsKLQkgICAgfQotCi0JICAgIFN5bnRheFRyZWVOb2RlIHJvb3QgPSBwYXJzZXIucGFyc2UoaW5wdXQpOwotCi0JICAgIGlmIChyb290ID09IG51bGwpIHJldHVybjsKLQkgICAgZmluYWwgU3R5bGVzaGVldCBfaW1wb3J0ZWQgPSBwYXJzZXIubWFrZVN0eWxlc2hlZXQocm9vdCk7Ci0JICAgIGlmIChfaW1wb3J0ZWQgPT0gbnVsbCkgcmV0dXJuOwotCi0JICAgIF9pbXBvcnRlZC5zZXRTb3VyY2VMb2FkZXIobG9hZGVyKTsKLQkgICAgX2ltcG9ydGVkLnNldFN5c3RlbUlkKGRvY1RvTG9hZCk7Ci0JICAgIF9pbXBvcnRlZC5zZXRQYXJlbnRTdHlsZXNoZWV0KGNvbnRleHQpOwotCi0JICAgIC8vIHByZWNlZGVuY2UgZm9yIHRoZSBpbmNsdWRpbmcgc3R5bGVzaGVldAotCSAgICBmaW5hbCBpbnQgY3VyclByZWNlZGVuY2UgPSBwYXJzZXIuZ2V0Q3VycmVudEltcG9ydFByZWNlZGVuY2UoKTsKLQkgICAgZmluYWwgaW50IG5leHRQcmVjZWRlbmNlID0gcGFyc2VyLmdldE5leHRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0JICAgIF9pbXBvcnRlZC5zZXRJbXBvcnRQcmVjZWRlbmNlKGN1cnJQcmVjZWRlbmNlKTsKLQkgICAgY29udGV4dC5zZXRJbXBvcnRQcmVjZWRlbmNlKG5leHRQcmVjZWRlbmNlKTsKLQkgICAgcGFyc2VyLnNldEN1cnJlbnRTdHlsZXNoZWV0KF9pbXBvcnRlZCk7Ci0JICAgIF9pbXBvcnRlZC5wYXJzZUNvbnRlbnRzKHBhcnNlcik7Ci0KLQkgICAgZmluYWwgRW51bWVyYXRpb24gZWxlbWVudHMgPSBfaW1wb3J0ZWQuZWxlbWVudHMoKTsKLQkgICAgZmluYWwgU3R5bGVzaGVldCB0b3BTdHlsZXNoZWV0ID0gcGFyc2VyLmdldFRvcExldmVsU3R5bGVzaGVldCgpOwotCSAgICB3aGlsZSAoZWxlbWVudHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJZmluYWwgT2JqZWN0IGVsZW1lbnQgPSBlbGVtZW50cy5uZXh0RWxlbWVudCgpOwotCQlpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFRvcExldmVsRWxlbWVudCkgewotCQkgICAgdG9wU3R5bGVzaGVldC5hZGRFbGVtZW50KChUb3BMZXZlbEVsZW1lbnQpZWxlbWVudCk7Ci0JCX0KLQkgICAgfQotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLQl9Ci0JZmluYWxseSB7Ci0JICAgIHBhcnNlci5zZXRDdXJyZW50U3R5bGVzaGVldChjb250ZXh0KTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JLy8gZG8gbm90aGluZwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0luY2x1ZGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0luY2x1ZGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzE5NjZiMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JbmNsdWRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBHdW5ubGF1Z3VyIEJyaWVtIDxndGhiQGRpbW9uLmlzPgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci0KLWZpbmFsIGNsYXNzIEluY2x1ZGUgZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotCi0gICAgcHJpdmF0ZSBTdHlsZXNoZWV0IF9pbmNsdWRlZCA9IG51bGw7Ci0KLSAgICBwdWJsaWMgU3R5bGVzaGVldCBnZXRJbmNsdWRlZFN0eWxlc2hlZXQoKSB7Ci0JcmV0dXJuKF9pbmNsdWRlZCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhmaW5hbCBQYXJzZXIgcGFyc2VyKSB7Ci0JZmluYWwgU3R5bGVzaGVldCBjb250ZXh0ID0gcGFyc2VyLmdldEN1cnJlbnRTdHlsZXNoZWV0KCk7Ci0JdHJ5IHsKLQkgICAgU3RyaW5nIGRvY1RvTG9hZCA9IGdldEF0dHJpYnV0ZSgiaHJlZiIpOwotCSAgICBpZiAoY29udGV4dC5jaGVja0Zvckxvb3AoZG9jVG9Mb2FkKSkgewotCQlmaW5hbCBpbnQgZXJybm8gPSBFcnJvck1zZy5DSVJDVUxBUl9JTkM7Ci0JCWZpbmFsIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhlcnJubywgZG9jVG9Mb2FkLCB0aGlzKTsKLQkJcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgbXNnKTsKLQkJcmV0dXJuOwotCSAgICB9Ci0KLQkgICAgZmluYWwgU3RyaW5nIGN1cnJMb2FkZWREb2MgPSBjb250ZXh0LmdldFN5c3RlbUlkKCk7Ci0JICAgIFNvdXJjZUxvYWRlciBsb2FkZXIgPSBjb250ZXh0LmdldFNvdXJjZUxvYWRlcigpOwotCSAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG51bGw7Ci0KLQkgICAgaWYgKGxvYWRlciAhPSBudWxsKSB7Ci0JCWZpbmFsIFhTTFRDIHhzbHRjID0gcGFyc2VyLmdldFhTTFRDKCk7Ci0JCWlucHV0ID0gbG9hZGVyLmxvYWRTb3VyY2UoZG9jVG9Mb2FkLCBjdXJyTG9hZGVkRG9jLCB4c2x0Yyk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWZpbmFsIFVSTCB1cmwgPSBuZXcgVVJMKG5ldyBVUkwoY3VyckxvYWRlZERvYyksIGRvY1RvTG9hZCk7Ci0JCWRvY1RvTG9hZCA9IHVybC50b1N0cmluZygpOwotCQlpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShkb2NUb0xvYWQpOwotCSAgICB9Ci0KLQkgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgcm9vdCA9IHBhcnNlci5wYXJzZShpbnB1dCk7Ci0JICAgIGlmIChyb290ID09IG51bGwpIHJldHVybjsKLQkgICAgZmluYWwgU3R5bGVzaGVldCBfaW5jbHVkZWQgPSBwYXJzZXIubWFrZVN0eWxlc2hlZXQocm9vdCk7Ci0JICAgIGlmIChfaW5jbHVkZWQgPT0gbnVsbCkgcmV0dXJuOwotCi0JICAgIF9pbmNsdWRlZC5zZXRTb3VyY2VMb2FkZXIobG9hZGVyKTsKLQkgICAgX2luY2x1ZGVkLnNldFN5c3RlbUlkKGRvY1RvTG9hZCk7Ci0JICAgIF9pbmNsdWRlZC5zZXRQYXJlbnRTdHlsZXNoZWV0KGNvbnRleHQpOwotCi0JICAgIC8vIEFuIGluY2x1ZGVkIHN0eWxlc2hlZXQgZ2V0cyB0aGUgc2FtZSBpbXBvcnQgcHJlY2VkZW5jZQotCSAgICAvLyBhcyB0aGUgc3R5bGVzaGVldCB0aGF0IGluY2x1ZGVkIGl0LgotCSAgICBmaW5hbCBpbnQgcHJlY2VkZW5jZSA9IGNvbnRleHQuZ2V0SW1wb3J0UHJlY2VkZW5jZSgpOwotCSAgICBfaW5jbHVkZWQuc2V0SW1wb3J0UHJlY2VkZW5jZShwcmVjZWRlbmNlKTsKLQotCSAgICBwYXJzZXIuc2V0Q3VycmVudFN0eWxlc2hlZXQoX2luY2x1ZGVkKTsKLQkgICAgX2luY2x1ZGVkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLQotCSAgICBmaW5hbCBFbnVtZXJhdGlvbiBlbGVtZW50cyA9IF9pbmNsdWRlZC5lbGVtZW50cygpOwotCSAgICBmaW5hbCBTdHlsZXNoZWV0IHRvcFN0eWxlc2hlZXQgPSBwYXJzZXIuZ2V0VG9wTGV2ZWxTdHlsZXNoZWV0KCk7Ci0JICAgIHdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQlmaW5hbCBPYmplY3QgZWxlbWVudCA9IGVsZW1lbnRzLm5leHRFbGVtZW50KCk7Ci0JCWlmIChlbGVtZW50IGluc3RhbmNlb2YgVG9wTGV2ZWxFbGVtZW50KSB7Ci0JCSAgICB0b3BTdHlsZXNoZWV0LmFkZEVsZW1lbnQoKFRvcExldmVsRWxlbWVudCllbGVtZW50KTsKLQkJfQotCSAgICB9Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCX0KLQlmaW5hbGx5IHsKLQkgICAgcGFyc2VyLnNldEN1cnJlbnRTdHlsZXNoZWV0KGNvbnRleHQpOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQkvLyBkbyBub3RoaW5nCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSW5zdHJ1Y3Rpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0luc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY5N2MwY2EuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSW5zdHJ1Y3Rpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWFic3RyYWN0IGNsYXNzIEluc3RydWN0aW9uIGV4dGVuZHMgU3ludGF4VHJlZU5vZGUgewotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgYWxsIHRoZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlyZXR1cm4gdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBub2RlIGludG8gSlZNIGJ5dGVjb2Rlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlnZXRQYXJzZXIoKS5ub3RZZXRJbXBsZW1lbnRlZCgiaW5zdHJ1Y3Rpb246ICIgKyBnZXRDbGFzcygpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JbnRFeHByLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9JbnRFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBmYjY5MzMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvSW50RXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBJbnRFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX3ZhbHVlOwotCi0gICAgcHVibGljIEludEV4cHIoaW50IHZhbHVlKSB7Ci0gICAgICAgIF92YWx1ZSA9IHZhbHVlOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIF90eXBlID0gVHlwZS5JbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gImludC1leHByKCIgKyBfdmFsdWUgKyAnKSc7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdmFsdWUpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9LZXkuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0tleS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZDJiZDE3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0tleS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzEwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5BeGlzOwotCi1maW5hbCBjbGFzcyBLZXkgZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotCi0gICAgcHJpdmF0ZSBRTmFtZSAgICAgIF9uYW1lOyAgICAgLy8gVGhlIG5hbWUgb2YgdGhpcyBrZXkgKGllLiBpbmRleCkKLSAgICBwcml2YXRlIFBhdHRlcm4gICAgX21hdGNoOyAgICAvLyBUaGUgbm9kZXMgdG8gZ2VuZXJhdGUgaW5kZXgga2V5cyBmcm9tCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF91c2U7ICAgICAgLy8gVGhlIG5vZGVzIHRvIGluY2x1ZGUgaW4gdGhlIGtleQotICAgIHByaXZhdGUgVHlwZSAgICAgICBfdXNlVHlwZTsgIC8vIFRoZSBkYXRhIHR5cGUgb2YgdGhlIGtleSdzIGNvbnRlbnRzCi0KLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBVU0VfVFlQRV9FUlIgPQotCSJUaGUgdXNlLWF0dHJpYnV0ZSBvZiA8a2V5PiBtdXN0IGJlIG5vZGUsIG5vZGUtc2V0LCBzdHJpbmcgb3IgbnVtYmVyLiI7Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgPHhzbDprZXk+IGVsZW1lbnQgYW5kIGF0dHJpYnV0ZXMKLSAgICAgKiBAcGFyYW0gcGFyc2VyIEEgcmVmZXJlbmNlIHRvIHRoZSBzdHlsZXNoZWV0IHBhcnNlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCi0JLy8gR2V0IHRoZSByZXF1aXJlZCBhdHRyaWJ1dGVzIGFuZCBwYXJzZXIgWFBhdGggZXhwcmVzc2lvbnMKLQlfbmFtZSA9IHBhcnNlci5nZXRRTmFtZShnZXRBdHRyaWJ1dGUoIm5hbWUiKSk7Ci0JX21hdGNoID0gcGFyc2VyLnBhcnNlUGF0dGVybih0aGlzLCAibWF0Y2giLCBudWxsKTsKLQlfdXNlID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCAidXNlIiwgbnVsbCk7Ci0KLSAgICAgICAgLy8gTWFrZSBzdXJlIHJlcXVpcmVkIGF0dHJpYnV0ZShzKSBoYXZlIGJlZW4gc2V0Ci0gICAgICAgIGlmIChfbmFtZSA9PSBudWxsKSB7Ci0JICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuTlJFUUFUVFJfRVJSLCAibmFtZSIpOwotCSAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF9tYXRjaC5pc0R1bW15KCkpIHsKLQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5OUkVRQVRUUl9FUlIsICJtYXRjaCIpOwotCSAgICByZXR1cm47Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKF91c2UuaXNEdW1teSgpKSB7Ci0JICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuTlJFUUFUVFJfRVJSLCAidXNlIik7Ci0JICAgIHJldHVybjsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBTdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhpcyBrZXkncyBuYW1lCi0gICAgICogQHJldHVybiBUaGUga2V5J3MgbmFtZSAoZnJvbSB0aGUgPHhzbDprZXk+IGVsZW1lbnRzICduYW1lJyBhdHRyaWJ1dGUpLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLQlTdHJpbmcgbmFtZTsKLQlpZiAoX25hbWUuZ2V0UHJlZml4KCkgPT0gbnVsbCkKLQkgICAgbmFtZSA9IF9uYW1lLmdldExvY2FsUGFydCgpOwotCWVsc2UKLQkgICAgbmFtZSA9IF9uYW1lLmdldFByZWZpeCgpKyI6IitfbmFtZS5nZXRMb2NhbFBhcnQoKTsKLQlyZXR1cm4obmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUnVuIHR5cGUgY2hlY2sgb24gdGhlICJ1c2UiIGF0dHJpYnV0ZSBhbmQgbWFrZSBzdXJlIGl0IGlzIHNvbWV0aGluZwotICAgICAqIHdlIGNhbiB1c2UgdG8gZXh0cmFjdCBzb21lIHZhbHVlIGZyb20gbm9kZXMuCi0gICAgICogQHBhcmFtIHN0YWJsZSBUaGUgc3R5bGVzaGVldCBwYXJzZXIncyBzeW1ib2wgdGFibGUKLSAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLXR5cGUgb2YgdGhpcyBrZXkgKGFsd2F5cyB2b2lkKQotICAgICAqIEB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgSWYgdGhlIHVzZSBhdHRyaWJ1dGUgZG9lcyBub3QgcmVwcmVzZW50IGEgc3RyaW5nLAotICAgICAqICAgYSBub2RlLXNldCBvciBhIG51bWJlcgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX21hdGNoLnR5cGVDaGVjayhzdGFibGUpOwotCV91c2VUeXBlID0gX3VzZS50eXBlQ2hlY2soc3RhYmxlKTsKLQotCS8vIENhc3Qgbm9kZSB2YWx1ZXMgdG8gc3RyaW5nIHZhbHVlcwotCWlmIChfdXNlVHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0JICAgIF91c2UgPSBuZXcgQ2FzdEV4cHIoX3VzZSwgVHlwZS5TdHJpbmcpOwotCSAgICBfdXNlVHlwZSA9IFR5cGUuU3RyaW5nOwotCX0KLQotCS8vIElmIHRoZSAndXNlJyBhdHRyaWJ1dGUgaXMgbm90IGEgc3RyaW5nLCBub2RlLXNldCBvciBudW1iZXIKLQlpZiAoIShfdXNlVHlwZSBpbnN0YW5jZW9mIFN0cmluZ1R5cGUpICYmCi0JICAgICEoX3VzZVR5cGUgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSkgJiYKLQkgICAgIShfdXNlVHlwZSBpbnN0YW5jZW9mIFJlYWxUeXBlKSkgewotCSAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IobmV3IEVycm9yTXNnKFVTRV9UWVBFX0VSUikpOwotCX0KLQotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGlmIHRoZSAidXNlIiBhdHRyaWJ1dGUgb2YgdGhlIGtleSBjb250YWlucyBhCi0gICAgICogbm9kZSBzZXQuIEluIHRoaXMgY2FzZSB3ZSBtdXN0IHRyYXZlcnNlIGFsbCBub2RlcyBpbiB0aGUgc2V0IGFuZAotICAgICAqIGNyZWF0ZSBvbmUgZW50cnkgaW4gdGhpcyBrZXkncyBpbmRleCBmb3IgZWFjaCBub2RlIGluIHRoZSBzZXQuCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIFRoZSBKYXZhIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gVGhlIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmF2ZXJzZU5vZGVTZXQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLQkJCQlpbnQgYnVpbGRLZXlJbmRleCkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBET00uZ2V0Tm9kZVZhbHVlKG5vZGVJbmRleCkgPT4gU3RyaW5nCi0JZmluYWwgaW50IGdldE5vZGVWYWx1ZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkJICAgImdldE5vZGVWYWx1ZSIsCi0JCQkJCQkJICAgIihJKSIrU1RSSU5HX1NJRyk7Ci0KLQkvLyBUaGlzIHZhcmlhYmxlIGhvbGRzIHRoZSBpZCBvZiB0aGUgbm9kZSB3ZSBmb3VuZCB3aXRoIHRoZSAibWF0Y2giCi0JLy8gYXR0cmlidXRlIG9mIHhzbDprZXkuIFRoaXMgaXMgdGhlIGlkIHdlIHN0b3JlLCB3aXRoIHRoZSB2YWx1ZSB3ZQotCS8vIGdldCBmcm9tIHRoZSBub2RlcyB3ZSBmaW5kIGhlcmUsIGluIHRoZSBpbmRleCBmb3IgdGhpcyBrZXkuCi0JZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBwYXJlbnROb2RlID0KLQkgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInBhcmVudE5vZGUiLAotCQkJCSAgICAgICBVdGlsLmdldEpDUmVmVHlwZSgiSSIpLAotCQkJCSAgICAgICBpbC5nZXRFbmQoKSwgbnVsbCk7Ci0KLQkvLyBHZXQgdGhlICdwYXJhbWV0ZXInIGZyb20gdGhlIHN0YWNrIGFuZCBzdG9yZSBpdCBpbiBhIGxvY2FsIHZhci4KLQlpbC5hcHBlbmQobmV3IElTVE9SRShwYXJlbnROb2RlLmdldEluZGV4KCkpKTsKLQotCS8vIFNhdmUgY3VycmVudCBub2RlIGFuZCBjdXJyZW50IGl0ZXJhdG9yIG9uIHRoZSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotCi0JLy8gT3ZlcndyaXRlIGN1cnJlbnQgaXRlcmF0b3Igd2l0aCBvbmUgdGhhdCBnaXZlcyB1cyBvbmx5IHdoYXQgd2Ugd2FudAotCV91c2UudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCV91c2Uuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLQotCWZpbmFsIEJyYW5jaEhhbmRsZSBuZXh0Tm9kZSA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgbG9vcCA9IGlsLmFwcGVuZChOT1ApOwotCi0JLy8gUHJlcGFyZSB0byBjYWxsIGJ1aWxkS2V5SW5kZXgoU3RyaW5nIG5hbWUsIGludCBub2RlLCBTdHJpbmcgdmFsdWUpOwotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZ2V0TmFtZSgpKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTE9BRChwYXJlbnROb2RlLmdldEluZGV4KCkpKTsKLQotCS8vIE5vdyBnZXQgdGhlIG5vZGUgdmFsdWUgYW5kIGZlY2sgaXQgb24gdGhlIHBhcmFtZXRlciBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXROb2RlVmFsdWUsIDIpKTsKLQotCS8vIEZpbmFsbHkgZG8gdGhlIGNhbGwgdG8gYWRkIGFuIGVudHJ5IGluIHRoZSBpbmRleCBmb3IgdGhpcyBrZXkuCi0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGJ1aWxkS2V5SW5kZXgpKTsKLQotCW5leHROb2RlLnNldFRhcmdldChpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLQotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLQlpbC5hcHBlbmQobmV3IElGTkUobG9vcCkpOyAvLyBHbyBvbiB0byBuZXh0IG1hdGNoaW5nIG5vZGUuLi4uCi0KLQkvLyBSZXN0b3JlIGN1cnJlbnQgbm9kZSBhbmQgY3VycmVudCBpdGVyYXRvciBmcm9tIHRoZSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2F0aGVyIGFsbCBub2RlcyB0aGF0IG1hdGNoIHRoZSBleHByZXNzaW9uIGluIHRoZSBhdHRyaWJ1dGUgIm1hdGNoIgotICAgICAqIGFuZCBhZGQgb25lIChvciBtb3JlKSBlbnRyaWVzIGluIHRoaXMga2V5J3MgaW5kZXguCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIFRoZSBKYXZhIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gVGhlIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgaW50IGN1cnJlbnQgPSBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpOwotCi0JLy8gQWJzdHJhY3RUcmFuc2xldC5idWlsZEtleUluZGV4KG5hbWUsbm9kZV9pZCx2YWx1ZSkgPT4gdm9pZAotCWZpbmFsIGludCBrZXkgPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkgImJ1aWxkS2V5SW5kZXgiLAotCQkJCQkgIigiK1NUUklOR19TSUcrIkkiK09CSkVDVF9TSUcrIilWIik7Ci0KLQkvLyBET00uZ2V0QXhpc0l0ZXJhdG9yKHJvb3QpID0+IE5vZGVJdGVyYXRvcgotCWZpbmFsIGludCBnaXQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAiZ2V0QXhpc0l0ZXJhdG9yIiwKLQkJCQkJCSAgIihJKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0KLQkvLyBHZXQgYW4gaXRlcmF0b3IgZm9yIGFsbCBub2RlcyBpbiB0aGUgRE9NCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwkKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLEF4aXMuREVTQ0VOREFOVCkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdCwgMikpOwotCi0JLy8gUmVzZXQgdGhlIGl0ZXJhdG9yIHRvIHN0YXJ0IHdpdGggdGhlIHJvb3Qgbm9kZQotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc2V0U3RhcnROb2RlKCkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLQotCS8vIExvb3AgZm9yIHRyYXZlcnNpbmcgYWxsIG5vZGVzIGluIHRoZSBET00KLQlmaW5hbCBCcmFuY2hIYW5kbGUgbmV4dE5vZGUgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCWZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGxvb3AgPSBpbC5hcHBlbmQoTk9QKTsKLQotCS8vIENoZWNrIGlmIHRoZSBjdXJyZW50IG5vZGUgbWF0Y2hlcyB0aGUgcGF0dGVybiBpbiAibWF0Y2giCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JX21hdGNoLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlfbWF0Y2guc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsgLy8gTGVhdmVzIDAgb3IgMSBvbiBzdGFjawotCWZpbmFsIEJyYW5jaEhhbmRsZSBza2lwTm9kZSA9IGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSk7Ci0JCi0JLy8gSWYgdGhpcyBpcyBqdXN0IGEgc2luZ2xlIG5vZGUgd2Ugc2hvdWxkIGNvbnZlcnQgdGhhdCB0byBhIHN0cmluZwotCS8vIGFuZCB1c2UgdGhhdCBzdHJpbmcgYXMgdGhlIHZhbHVlIGluIHRoZSBpbmRleCBmb3IgdGhpcyBrZXkuCi0JaWYgKF91c2VUeXBlIGluc3RhbmNlb2YgUmVhbFR5cGUpIHsKLQkgICAgZmluYWwgaW50IGRibCA9IGNwZy5hZGRNZXRob2RyZWYoRE9VQkxFX0NMQVNTLCI8aW5pdD4iLCAiKEQpViIpOwotCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9uYW1lLnRvU3RyaW5nKCkpKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhET1VCTEVfQ0xBU1MpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBfdXNlLnRyYW5zbGF0ZShjbGFzc0dlbixtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoZGJsKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChrZXkpKTsKLQotCX0KLQllbHNlIGlmIChfdXNlVHlwZSBpbnN0YW5jZW9mIFN0cmluZ1R5cGUpIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX25hbWUudG9TdHJpbmcoKSkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkgICAgX3VzZS50cmFuc2xhdGUoY2xhc3NHZW4sbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGtleSkpOwotCX0KLQkvLyBJZiB0aGlzIGlzIGEgbm9kZS1zZXQgd2UgbXVzdCBnbyB0aHJvdWdoIGVhY2ggbm9kZSBpbiB0aGUgc2V0Ci0JLy8gYW5kIGNyZWF0ZSBvbmUgZW50cnkgaW4gdGhlIGtleSBpbmRleCBmb3IgZWFjaCBub2RlIGluIHRoZSBzZXQuCi0JZWxzZSB7Ci0JICAgIC8vIFBhc3MgY3VycmVudCBub2RlIGFzIHBhcmFtZXRlciAod2UncmUgaW5kZXhpbmcgb24gdGhhdCBub2RlKQotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkgICAgdHJhdmVyc2VOb2RlU2V0KGNsYXNzR2VuLG1ldGhvZEdlbixrZXkpOwotCX0KLQkKLQkvLyBHZXQgdGhlIG5leHQgbm9kZSBmcm9tIHRoZSBpdGVyYXRvciBhbmQgZG8gbG9vcCBhZ2Fpbi4uLgotCWZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHNraXAgPSBpbC5hcHBlbmQoTk9QKTsKLQkKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLm5leHROb2RlKCkpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLQlpbC5hcHBlbmQobmV3IElGTkUobG9vcCkpOwotCi0JLy8gUmVzdG9yZSBjdXJyZW50IG5vZGUgYW5kIGN1cnJlbnQgaXRlcmF0b3IgZnJvbSB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotCQotCW5leHROb2RlLnNldFRhcmdldChza2lwKTsKLQlza2lwTm9kZS5zZXRUYXJnZXQoc2tpcCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvS2V5Q2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvS2V5Q2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDlhMWY5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0tleUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyNyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIEtleUNhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9uYW1lOyAgICAgIC8vIFRoZSBuYW1lIG9mIHRoaXMga2V5Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF92YWx1ZTsgICAgIC8vIFRoZSB2YWx1ZSB0byBsb29rIHVwIGluIHRoZSBrZXkvaW5kZXgKLSAgICBwcml2YXRlIFR5cGUgICAgICAgX3ZhbHVlVHlwZTsgLy8gVGhlIHZhbHVlJ3MgZGF0YSB0eXBlCi0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHBhcmFtZXRlcnMgcGFzc2VkIHRvIGZ1bmN0aW9uOgotICAgICAqICAga2V5KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICogICBrZXkoU3RyaW5nIG5hbWUsIE5vZGVTZXQgdmFsdWUpCi0gICAgICogVGhlICdhcmd1bWVudHMnIHZlY3RvciBzaG91bGQgY29udGFpbiB0d28gcGFyYW1ldGVycyBmb3Iga2V5KCkgY2FsbHMsCi0gICAgICogb25lIGhvbGRpbmcgdGhlIGtleSBuYW1lIGFuZCBvbmUgaG9sZGluZyB0aGUgdmFsdWUocykgdG8gbG9vayB1cC4gVGhlCi0gICAgICogdmVjdG9yIGhhcyBvbmx5IG9uZSBwYXJhbWV0ZXIgZm9yIGlkKCkgY2FsbHMgKHRoZSBrZXkgbmFtZSBpcyBhbHdheXMKLSAgICAgKiAiIyNpZCIgZm9yIGlkKCkgY2FsbHMpLgotICAgICAqCi0gICAgICogQHBhcmFtIGZuYW1lIFRoZSBmdW5jdGlvbiBuYW1lIChzaG91bGQgYmUgJ2tleScgb3IgJ2lkJykKLSAgICAgKiBAcGFyYW0gYXJndW1lbnRzIEEgdmVjdG9yIGNvbnRhaW5pbmcgdGhlIGFyZ3VtZW50cyB0aGUgdGhlIGZ1bmN0aW9uCi0gICAgICovCi0gICAgcHVibGljIEtleUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLQlzd2l0Y2goYXJndW1lbnRDb3VudCgpKSB7Ci0JY2FzZSAxOgotCSAgICBfbmFtZSA9IG51bGw7Ci0JICAgIF92YWx1ZSA9IGFyZ3VtZW50KDApOwotCSAgICBicmVhazsKLQljYXNlIDI6Ci0JICAgIF9uYW1lID0gYXJndW1lbnQoMCk7Ci0JICAgIF92YWx1ZSA9IGFyZ3VtZW50KDEpOwotCSAgICBicmVhazsKLQlkZWZhdWx0OgotCSAgICBfbmFtZSA9IF92YWx1ZSA9IG51bGw7Ci0JICAgIGJyZWFrOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgaWQoKSBvciBrZXkoKSBmdW5jdGlvbi4KLSAgICAgKiBUaGUgaW5kZXggbmFtZSAoZm9yIGtleSgpIGNhbGwgb25seSkgbXVzdCBiZSBhIHN0cmluZyBvciBjb252ZXJ0YWJsZQotICAgICAqIHRvIGEgc3RyaW5nLCBhbmQgdGhlIGxvb2t1cC12YWx1ZSBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgbm9kZS1zZXQuCi0gICAgICogQHBhcmFtIHN0YWJsZSBUaGUgcGFyc2VyJ3Mgc3ltYm9sIHRhYmxlCi0gICAgICogQHRocm93cyBUeXBlQ2hlY2tFcnJvciBXaGVuIHRoZSBwYXJhbWV0ZXJzIGhhdmUgaWxsZWdhbCB0eXBlCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBUeXBlIHJldHVyblR5cGUgPSBzdXBlci50eXBlQ2hlY2soc3RhYmxlKTsKLQotCS8vIFJ1biB0eXBlIGNoZWNrIG9uIHRoZSBrZXkgbmFtZSAoZmlyc3QgYXJndW1lbnQpIC0gbXVzdCBiZSBhIHN0cmluZywKLQkvLyBhbmQgaWYgaXQgaXMgbm90IGl0IG11c3QgYmUgY29udmVydGVkIHRvIG9uZSB1c2luZyBzdHJpbmcoKSBydWxlcy4KLQlpZiAoX25hbWUgIT0gbnVsbCkgewotCSAgICBmaW5hbCBUeXBlIG5hbWVUeXBlID0gX25hbWUudHlwZUNoZWNrKHN0YWJsZSk7IAotCSAgICBpZiAoIShuYW1lVHlwZSBpbnN0YW5jZW9mIFN0cmluZ1R5cGUpKSB7Ci0JCV9uYW1lID0gbmV3IENhc3RFeHByKF9uYW1lLCBUeXBlLlN0cmluZyk7Ci0JICAgIH0KLQl9Ci0KLQkvLyBSdW4gdHlwZSBjaGVjayBvbiB0aGUgdmFsdWUgZm9yIHRoaXMga2V5LiBUaGlzIHZhbHVlIGNhbiBiZSBvZgotCS8vIGFueSBkYXRhIHR5cGUsIHNvIHRoaXMgc2hvdWxkIG5ldmVyIGNhdXNlIGFueSB0eXBlLWNoZWNrIGVycm9ycy4KLQkvLyBJZiB0aGUgdmFsdWUgaXMgbm90IGEgbm9kZS1zZXQgdGhlbiBpdCBzaG91bGQgYmUgY29udmVydGVkIHRvIGEKLQkvLyBzdHJpbmcgYmVmb3JlIHRoZSBsb29rdXAgaXMgZG9uZS4gSWYgdGhlIHZhbHVlIGlzIGEgbm9kZS1zZXQgdGhlbgotCS8vIHRoaXMgcHJvY2VzcyAoY29udmVydCB0byBzdHJpbmcsIHRoZW4gZG8gbG9va3VwKSBzaG91bGQgYmUgYXBwbGllZAotCS8vIHRvIGV2ZXJ5IG5vZGUgaW4gdGhlIHNldCwgYW5kIHRoZSByZXN1bHQgZnJvbSBhbGwgbG9va3VwcyBzaG91bGQKLQkvLyBiZSBhZGRlZCB0byB0aGUgcmVzdWx0aW5nIG5vZGUtc2V0LgotCV92YWx1ZVR5cGUgPSBfdmFsdWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0KLQlpZiAoKF92YWx1ZVR5cGUgIT0gVHlwZS5Ob2RlU2V0KSAmJgotCSAgICAoX3ZhbHVlVHlwZSAhPSBUeXBlLlJlc3VsdFRyZWUpICYmCi0JICAgIChfdmFsdWVUeXBlICE9IFR5cGUuU3RyaW5nKSAmJgotCSAgICAoX3ZhbHVlVHlwZSAhPSBUeXBlLlJlYWwpICYmCi0JICAgIChfdmFsdWVUeXBlICE9IFR5cGUuSW50KSkgewotCSAgICBfdmFsdWUgPSBuZXcgQ2FzdEV4cHIoX3ZhbHVlLCBUeXBlLlN0cmluZyk7Ci0JfQotCi0JcmV0dXJuIHJldHVyblR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIGNvbnN0cnVjdG9yIGlzIGNvbXBpbGVkIGluCi0gICAgICogU3R5bGVzaGVldC5jb21waWxlQ29uc3RydWN0b3IoKSBhbmQgbm90IGFzIHRoZSBzeW50YXggdHJlZSBpcyB0cmF2ZXJzZWQuCi0gICAgICogVGhpcyBtZXRob2QgaXMgYSB3cmFwcGVyIGZvciB0aGUgcmVhbCB0cmFuc2xhdGlvbiBtZXRob2QsIHdoaWNoIGlzCi0gICAgICogdGhlIHByaXZhdGUgbWV0aG9kIHRyYW5zbGF0ZUNhbGwoKSBiZWxvdy4gQWxsIHRoaXMgbWV0aG9kIGRvZXMgaXMgdG8KLSAgICAgKiB3cmFwIHRoZSBLZXlJbmRleCB0aGF0IHRoaXMgZnVuY3Rpb24gcmV0dXJucyBpbnNpZGUgYSBkdXBsaWNhdGUgZmlsdGVyLgotICAgICAqIFRoZSBkdXBsaWNhdGUgZmlsdGVyIGlzIHVzZWQgYm90aCB0byBlbGltaW5hdGUgZHVwbGljYXRlcyBhbmQgdG8KLSAgICAgKiBjYWNoZSB0aGUgbm9kZXMgaW4gdGhlIGluZGV4LgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBUaGUgSmF2YSBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIFRoZSBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCS8vIFdyYXAgdGhlIEtleUluZGV4IChpdGVyYXRvcikgaW5zaWRlIGEgZHVwbGljYXRlIGZpbHRlciBpdGVyYXRvcgotCS8vIHRvIHByZS1yZWFkIHRoZSBpbmRleGVkIG5vZGVzIGFuZCBjYWNoZSB0aGVtLgotCWZpbmFsIGludCBkdXBJbml0ID0gY3BnLmFkZE1ldGhvZHJlZihEVVBfRklMVEVSRURfSVRFUkFUT1IsCi0JCQkJCSAgICAgIjxpbml0PiIsCi0JCQkJCSAgICAgIigiK05PREVfSVRFUkFUT1JfU0lHKyIpViIpOwotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhEVVBfRklMVEVSRURfSVRFUkFUT1IpKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JdHJhbnNsYXRlQ2FsbChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoZHVwSW5pdCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGUgYWN0dWFsIGluZGV4IGxvb2t1cCAtIGxlYXZlcyBLZXlJbmRleCAoaXRlcmF0b3IpIG9uIHN0YWNrCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIFRoZSBKYXZhIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gVGhlIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgdHJhbnNsYXRlQ2FsbChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgZm9yIGEgbm9kZSBpbiB0aGUgRE9NCi0JZmluYWwgaW50IGdldE5vZGVWYWx1ZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkJICAgImdldE5vZGVWYWx1ZSIsCi0JCQkJCQkJICAgIihJKSIrU1RSSU5HX1NJRyk7Ci0KLQkvLyBSZXR1cm5zIHRoZSBLZXlJbmRleCBvYmplY3Qgb2YgYSBnaXZlbiBuYW1lCi0JZmluYWwgaW50IGdldEtleUluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCSAiZ2V0S2V5SW5kZXgiLAotCQkJCQkJICIoTGphdmEvbGFuZy9TdHJpbmc7KSIrCi0JCQkJCQkgS0VZX0lOREVYX1NJRyk7Ci0KLQkvLyBJbml0aWFsaXNlcyBhIEtleUluZGV4IHRvIHJldHVybiBub2RlcyB3aXRoIHNwZWNpZmljIHZhbHVlcwotCWZpbmFsIGludCBsb29rdXBJZCA9IGNwZy5hZGRNZXRob2RyZWYoS0VZX0lOREVYX0NMQVNTLAotCQkJCQkgICAgICAibG9va3VwSWQiLAotCQkJCQkgICAgICAiKExqYXZhL2xhbmcvT2JqZWN0OylWIik7Ci0JZmluYWwgaW50IGxvb2t1cEtleSA9IGNwZy5hZGRNZXRob2RyZWYoS0VZX0lOREVYX0NMQVNTLAotCQkJCQkgICAgICAgImxvb2t1cEtleSIsCi0JCQkJCSAgICAgICAiKExqYXZhL2xhbmcvT2JqZWN0OylWIik7Ci0KLQkvLyBNZXJnZXMgdGhlIG5vZGVzIGluIHR3byBLZXlJbmRleCBvYmplY3RzCi0JZmluYWwgaW50IG1lcmdlID0gY3BnLmFkZE1ldGhvZHJlZihLRVlfSU5ERVhfQ0xBU1MsCi0JCQkJCSAgICJtZXJnZSIsCi0JCQkJCSAgICIoIitLRVlfSU5ERVhfU0lHKyIpViIpOwotCi0JLy8gQ29uc3RydWN0b3IgZm9yIEtleUluZGV4IGNsYXNzCi0JZmluYWwgaW50IGluZGV4Q29uc3RydWN0b3IgPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJICAgICAgImNyZWF0ZUtleUluZGV4IiwKLQkJCQkJCSAgICAgICIoKSIrS0VZX0lOREVYX1NJRyk7Ci0JCi0JLy8gVGhpcyBsb2NhbCB2YXJpYWJsZSBob2xkcyB0aGUgaW5kZXgvaXRlcmF0b3Igd2Ugd2lsbCByZXR1cm4KLQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIHJldHVybkluZGV4ID0KLQkgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInJldHVybkluZGV4IiwKLQkJCQkgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoS0VZX0lOREVYX1NJRyksCi0JCQkJICAgICAgIGlsLmdldEVuZCgpLCBudWxsKTsKLQotCS8vIFRoaXMgbG9jYWwgdmFyaWFibGUgaG9sZHMgdGhlIGluZGV4IHdlJ3JlIHVzaW5nIGZvciBzZWFyY2gKLQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIHNlYXJjaEluZGV4ID0KLQkgICAgbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInNlYXJjaEluZGV4IiwKLQkJCQkgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoS0VZX0lOREVYX1NJRyksCi0JCQkJICAgICAgIGlsLmdldEVuZCgpLCBudWxsKTsKLQotCS8vIElmIHRoZSBzZWNvbmQgcGFyYW10ZXIgaXMgYSBub2RlLXNldCB3ZSBuZWVkIHRvIGdvIHRocm91Z2ggZWFjaAotCS8vIG5vZGUgaW4gdGhlIHNldCwgY29udmVydCBlYWNoIG9uZSB0byBhIHN0cmluZyBhbmQgZG8gYSBsb29rIHVwIGluCi0JLy8gdGhlIG5hbWVkIGluZGV4LCBhbmQgdGhlbiBtZXJnZSBhbGwgdGhlIHJlc3VsdGluZyBub2RlIHNldHMuCi0JaWYgKF92YWx1ZVR5cGUgPT0gVHlwZS5Ob2RlU2V0IHx8IF92YWx1ZVR5cGUgPT0gVHlwZS5SZXN1bHRUcmVlKSB7Ci0JICAgIC8vIFNhdmUgY3VycmVudCBub2RlIGFuZCBjdXJyZW50IGl0ZXJhdG9yIG9uIHRoZSBzdGFjawotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0KLQkgICAgLy8gR2V0IG5ldyBpdGVyYXRvciBmcm9tIDJuZCBwYXJhbWV0ZXIgbm9kZS1zZXQgJiBzdG9yZSBpbiB2YXJpYWJsZQotCSAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfdmFsdWUuc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0KLQkgICAgLy8gQ3JlYXRlIHRoZSBLZXlJbmRleCBvYmplY3QgKHRoZSBpdGVyYXRvcikgd2UnbGwgcmV0dXJuCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleENvbnN0cnVjdG9yKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKHJldHVybkluZGV4LmdldEluZGV4KCkpKTsKLQotCSAgICAvLyBJbml0aWFsaXNlIHRoZSBpbmRleCBzcGVjaWZpZWQgaW4gdGhlIGZpcnN0IHBhcmFtZXRlciBvZiBrZXkoKQotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBpZiAoX25hbWUgPT0gbnVsbCkgCi0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIiMjaWQiKSk7Ci0JICAgIGVsc2UKLQkJX25hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChnZXRLZXlJbmRleCkpOwotCSAgICBpbC5hcHBlbmQobmV3IEFTVE9SRShzZWFyY2hJbmRleC5nZXRJbmRleCgpKSk7Ci0KLQkgICAgLy8gTE9PUCBTVEFSVFMgSEVSRQotCi0JICAgIC8vIE5vdyB3ZSdyZSByZWFkeSB0byBzdGFydCB0cmF2ZXJzaW5nIHRoZSBub2RlLXNldCBnaXZlbiBpbgotCSAgICAvLyB0aGUga2V5KCkgZnVuY3Rpb24ncyBzZWNvbmQgYXJndW1lbnQuLi4uCi0JICAgIGZpbmFsIEJyYW5jaEhhbmRsZSBuZXh0Tm9kZSA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGxvb3AgPSBpbC5hcHBlbmQoTk9QKTsKLQotCSAgICAvLyBQdXNoIHJldHVybkluZGV4IG9uIHN0YWNrIHRvIHByZXBhcmUgZm9yIGNhbGwgdG8gbWVyZ2UoKQotCSAgICBpbC5hcHBlbmQobmV3IEFMT0FEKHJldHVybkluZGV4LmdldEluZGV4KCkpKTsKLQkgICAgCi0JICAgIC8vIExvb2t1cCBpbmRleCB1c2luZyB0aGUgc3RyaW5nIHZhbHVlIGZyb20gdGhlIGN1cnJlbnQgbm9kZQotCSAgICBpbC5hcHBlbmQobmV3IEFMT0FEKHNlYXJjaEluZGV4LmdldEluZGV4KCkpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldE5vZGVWYWx1ZSwgMikpOwotCSAgICBpZiAoX25hbWUgPT0gbnVsbCkKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGxvb2t1cElkKSk7Ci0JICAgIGVsc2UKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGxvb2t1cEtleSkpOwotCi0JICAgIC8vIENhbGwgdG8gcmV0dXJuSW5kZXgubWVyZ2Uoc2VhcmNoSW5kZXgpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwobWVyZ2UpKTsKLQkJCi0JICAgIC8vIEdvIG9uIHdpdGggbmV4dCBub2RlIGluIHRoZSAybmQgcGFyYW1ldGVyIG5vZGUtc2V0Ci0JICAgIG5leHROb2RlLnNldFRhcmdldChpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubmV4dE5vZGUoKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSUZORShsb29wKSk7Ci0KLQkgICAgLy8gTE9PUCBFTkRTIEhFUkUKLQotCSAgICAvLyBSZXN0b3JlIGN1cnJlbnQgbm9kZSBhbmQgY3VycmVudCBpdGVyYXRvciBmcm9tIHRoZSBzdGFjawotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSXRlcmF0b3IoKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLQotCSAgICAvLyBSZXR1cm4gd2l0aCB0aGUgYW4gaXRlcmF0b3IgZm9yIGFsbCByZXN1bHRpbmcgbm9kZXMKLQkgICAgaWwuYXBwZW5kKG5ldyBBTE9BRChyZXR1cm5JbmRleC5nZXRJbmRleCgpKSk7Ci0JfQotCS8vIElmIHRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIGEgc2luZ2xlIHZhbHVlIHdlIGp1c3QgbG9va3VwIHRoZSBuYW1lZAotCS8vIGluZGV4IGFuZCBpbml0aWFsaXNlIHRoZSBpdGVyYXRvciB0byByZXR1cm4gbm9kZXMgd2l0aCB0aGlzIHZhbHVlLgotCWVsc2UgewotCSAgICAvLyBDYWxsIGdldEtleUluZGV4IGluIEFic3RyYWN0VHJhbnNsZXQgd2l0aCB0aGUgbmFtZSBvZiB0aGUga2V5Ci0JICAgIC8vIHRvIGdldCB0aGUgaW5kZXggZm9yIHRoaXMga2V5ICh3aGljaCBpcyBhbHNvIGEgbm9kZSBpdGVyYXRvcikuCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlmIChfbmFtZSA9PSBudWxsKQotCQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCIjI2lkIikpOwotCSAgICBlbHNlCi0JCV9uYW1lLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGdldEtleUluZGV4KSk7Ci0KLQkgICAgLy8gTm93IHVzZSB0aGUgdmFsdWUgaW4gdGhlIHNlY29uZCBhcmd1bWVudCB0byBkZXRlcm1pbmUgd2hhdCBub2RlcwotCSAgICAvLyB0aGUgaXRlcmF0b3Igc2hvdWxkIHJldHVybi4KLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0KLQkgICAgaWYgKF92YWx1ZVR5cGUgPT0gVHlwZS5JbnQgfHwgX3ZhbHVlVHlwZSA9PSBUeXBlLlJlYWwpIHsKLQkJZmluYWwgaW50IGRibCA9IGNwZy5hZGRNZXRob2RyZWYoRE9VQkxFX0NMQVNTLCI8aW5pdD4iLCAiKEQpViIpOwotCQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoRE9VQkxFX0NMQVNTKSkpOwotCQlpbC5hcHBlbmQoRFVQKTsKLQkJX3ZhbHVlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWYgKF92YWx1ZVR5cGUgPT0gVHlwZS5JbnQpCi0JCSAgICBpbC5hcHBlbmQobmV3IEkyRCgpKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGRibCkpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICB9Ci0KLQkgICAgaWYgKF9uYW1lID09IG51bGwpCi0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChsb29rdXBJZCkpOwotCSAgICBlbHNlCi0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChsb29rdXBLZXkpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvS2V5UGF0dGVybi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvS2V5UGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNTYyZDVkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0tleVBhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcyICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1maW5hbCBjbGFzcyBLZXlQYXR0ZXJuIGV4dGVuZHMgSWRLZXlQYXR0ZXJuIHsKLQotICAgIHB1YmxpYyBLZXlQYXR0ZXJuKFN0cmluZyBpbmRleCwgU3RyaW5nIHZhbHVlKSB7Ci0Jc3VwZXIoaW5kZXgsdmFsdWUpOwotICAgIH0gICAgCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xhbmdDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9MYW5nQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwODk5MWI5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xhbmdDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBMYW5nQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sYW5nOwotICAgIHByaXZhdGUgVHlwZSBfbGFuZ1R5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHBhcmFtZXRlcnMgcGFzc2VkIHRvIGZ1bmN0aW9uOgotICAgICAqICAgbGFuZyhzdHJpbmcpCi0gICAgICovCi0gICAgcHVibGljIExhbmdDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0JX2xhbmcgPSBhcmd1bWVudCgwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX2xhbmdUeXBlID0gX2xhbmcudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKCEoX2xhbmdUeXBlIGluc3RhbmNlb2YgU3RyaW5nVHlwZSkpIHsKLQkgICAgX2xhbmcgPSBuZXcgQ2FzdEV4cHIoX2xhbmcsIFR5cGUuU3RyaW5nKTsKLQl9Ci0JcmV0dXJuIFR5cGUuQm9vbGVhbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIGdldFR5cGUoKSB7Ci0JcmV0dXJuKFR5cGUuQm9vbGVhbik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIGNvbnN0cnVjdG9yIGlzIGNvbXBpbGVkIGluCi0gICAgICogU3R5bGVzaGVldC5jb21waWxlQ29uc3RydWN0b3IoKSBhbmQgbm90IGFzIHRoZSBzeW50YXggdHJlZSBpcyB0cmF2ZXJzZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWZpbmFsIGludCB0c3QgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCSAidGVzdExhbmd1YWdlIiwKLQkJCQkJICIoIitTVFJJTkdfU0lHK0RPTV9JTlRGX1NJRysiSSlaIik7Ci0JX2xhbmcudHJhbnNsYXRlKGNsYXNzR2VuLG1ldGhvZEdlbik7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCWlmIChjbGFzc0dlbiBpbnN0YW5jZW9mIEZpbHRlckdlbmVyYXRvcikKLQkgICAgaWwuYXBwZW5kKG5ldyBJTE9BRCgxKSk7Ci0JZWxzZQotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyh0c3QpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9MYXN0Q2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTGFzdENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGQ5ZWIwNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9MYXN0Q2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5BeGlzOwotCi1maW5hbCBjbGFzcyBMYXN0Q2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0KLSAgICBwcml2YXRlIGludCBfdHlwZSA9IC0xOwotCi0gICAgcHVibGljIExhc3RDYWxsKFFOYW1lIGZuYW1lKSB7Ci0Jc3VwZXIoZm5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBMYXN0Q2FsbChRTmFtZSBmbmFtZSwgaW50IHR5cGUpIHsKLQl0aGlzKGZuYW1lKTsKLQlfdHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0KLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0JYm9vbGVhbiBsYXN0Q2hpbGQgPSBmYWxzZTsKLQotCS8vIElmIHdlJ3JlIGEgcGFydCBvZiBhbiBwYXR0ZXJuJ3MgcHJlZGljYXRlIHdlIHdhbnQgdG8ga25vdyB3aGF0Ci0JLy8gdHlwZSBvZiBub2RlIHdlIHdhbnQgdG8gYmUgbG9va2luZyBmb3IgKG5vdCBqdXN0IGFueSkuCi0JaWYgKGdldFBhcmVudCgpIGluc3RhbmNlb2YgRXhwcmVzc2lvbikgewotCSAgICBpZiAoZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCkgaW5zdGFuY2VvZiBQcmVkaWNhdGUpIHsKLQkJUHJlZGljYXRlIHByZWQgPSAoUHJlZGljYXRlKWdldFBhcmVudCgpLmdldFBhcmVudCgpOwotCQlfdHlwZSA9IHByZWQuZ2V0UG9zVHlwZSgpOwotCSAgICB9Ci0JfQotCi0JLy8gSWYgd2UncmUgYSBwYXJ0IG9mIGEgc3RlcC10eXBlIGV4cHJlc3Npb24gd2Ugd2FudCB0aGUgbGFzdCBvZiB0aGUKLQkvLyBjdXJyZW50IG5vZGUncyBjaGlsZHJlbiBhbmQgbm90IHRoZSBsYXN0IGluIHRoZSBjdXJyZW50IGl0ZXJhdG9yLgotCWlmIChnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIFByZWRpY2F0ZSkgewotCSAgICBfdHlwZSA9ICgoUHJlZGljYXRlKWdldFBhcmVudCgpKS5nZXRQb3NUeXBlKCk7Ci0JICAgIGlmIChnZXRQYXJlbnQoKS5nZXRQYXJlbnQoKSBpbnN0YW5jZW9mIFN0ZXApIHsKLQkJbGFzdENoaWxkID0gdHJ1ZTsKLQkgICAgfQotCX0KLQotCWlmIChtZXRob2RHZW4gaW5zdGFuY2VvZiBDb21wYXJlR2VuZXJhdG9yKSB7Ci0JICAgIGlsLmFwcGVuZCgoKENvbXBhcmVHZW5lcmF0b3IpbWV0aG9kR2VuKS5sb2FkTGFzdE5vZGUoKSk7Ci0JfQotCWVsc2UgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotCSAgICBpbC5hcHBlbmQobmV3IElMT0FEKExBU1RfSU5ERVgpKTsKLQl9Ci0JZWxzZSBpZiAoX3R5cGUgPT0gLTEpIHsKLQkgICAgZmluYWwgaW50IGxhc3QgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0JCQkJCQkgICAgICAgImdldExhc3QiLCAKLQkJCQkJCSAgICAgICAiKClJIik7Ci0JICAgIGZpbmFsIGludCBnaXQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAgImdldFR5cGVkQXhpc0l0ZXJhdG9yIiwgCi0JCQkJCQkgICAgICAiKElJKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotCSAgICBmaW5hbCBpbnQgc3RhcnQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE5PREVfSVRFUkFUT1IsCi0JCQkJCQkJInNldFN0YXJ0Tm9kZSIsIAotCQkJCQkJCSIoSSkiKwotCQkJCQkJCU5PREVfSVRFUkFUT1JfU0lHKTsKLQkgICAgaWYgKGxhc3RDaGlsZCkgewotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIEF4aXMuQ0hJTEQpKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRE9NLkVMRU1FTlQpKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0LCAzKSk7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShzdGFydCwgMikpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQkgICAgfQotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShsYXN0LCAxKSk7Ci0JfQotCWVsc2UgewotCSAgICAvLyBwdWJsaWMgaW50IGdldFR5cGVkUG9zaXRpb24oTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBpbnQgdHlwZSkgewotCSAgICBmaW5hbCBpbnQgbGFzdCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgICAgImdldFR5cGVkTGFzdCIsCi0JCQkJCQkgICAgICAgIigiKwotCQkJCQkJICAgICAgIE5PREVfSVRFUkFUT1JfU0lHKwotCQkJCQkJICAgICAgICJJSSlJIik7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF90eXBlKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShsYXN0LCA0KSk7Ci0KLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTGl0ZXJhbEF0dHJpYnV0ZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTGl0ZXJhbEF0dHJpYnV0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MGYyMmFlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxBdHRyaWJ1dGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgTGl0ZXJhbEF0dHJpYnV0ZSBleHRlbmRzIEluc3RydWN0aW9uIHsKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyAgX25hbWU7Ci0gICAgcHJpdmF0ZSBmaW5hbCBBdHRyaWJ1dGVWYWx1ZSBfdmFsdWU7Ci0KLSAgICBwdWJsaWMgTGl0ZXJhbEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlLCBQYXJzZXIgcGFyc2VyKSB7Ci0JX25hbWUgPSBuYW1lOwotCV92YWx1ZSA9IEF0dHJpYnV0ZVZhbHVlLmNyZWF0ZSh0aGlzLCB2YWx1ZSwgcGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIkxpdGVyYWxBdHRyaWJ1dGUgbmFtZT0iICsgX25hbWUgKyAiIHZhbHVlPSIgKyBfdmFsdWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX3ZhbHVlLnR5cGVDaGVjayhzdGFibGUpOwotCXR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250ZXh0RGVwZW5kZW50KCkgewotCXJldHVybiBfdmFsdWUuY29udGV4dERlcGVuZGVudCgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBwdXNoIGhhbmRsZXIKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCS8vIHB1c2ggYXR0cmlidXRlIG5hbWUgLSBuYW1lc3BhY2UgcHJlZml4IHNldCBieSBwYXJlbnQgbm9kZQotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9uYW1lKSk7Ci0JLy8gcHVzaCBhdHRyaWJ1dGUgdmFsdWUKLQlfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCS8vIGNhbGwgYXR0cmlidXRlCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5hdHRyaWJ1dGUoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTGl0ZXJhbEVsZW1lbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNlMjUxYWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTGl0ZXJhbEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM5NSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgTGl0ZXJhbEVsZW1lbnQgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX25hbWU7Ci0gICAgcHJpdmF0ZSBIYXNodGFibGUgX2FjY2Vzc2VkUHJlZml4ZXMgPSBudWxsOwotICAgIHByaXZhdGUgTGl0ZXJhbEVsZW1lbnQgX3BhcmVudDsKLSAgICBwcml2YXRlIFZlY3RvciBfYXR0cmlidXRlRWxlbWVudHMgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTE5TX1NUUklORyA9ICJ4bWxucyI7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBRTmFtZSBmb3IgdGhpcyBsaXRlcmFsIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLQlyZXR1cm4gX3FuYW1lOwotICAgIH0KLSAKLSAgICAvKioKLSAgICAgKiBEaXNwbGF5cyB0aGUgY29udGVudHMgb2YgdGhpcyBsaXRlcmFsIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIkxpdGVyYWxFbGVtZW50IG5hbWUgPSAiICsgX25hbWUpOwotCWRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgZm9yIHdoaWNoIGEgcHJlZml4IGlzIHBvaW50aW5nIHRvCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBhY2Nlc3NlZE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB7Ci0JaWYgKF9hY2Nlc3NlZFByZWZpeGVzID09IG51bGwpCi0JICAgIHJldHVybihudWxsKTsKLQllbHNlCi0JICAgIHJldHVybigoU3RyaW5nKV9hY2Nlc3NlZFByZWZpeGVzLmdldChwcmVmaXgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2QgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHdoYXQgbmFtZXNwYWNlcyB0aGF0IGFyZSByZWZlcmVuY2VzIGJ5Ci0gICAgICogdGhpcyBsaXRlcmFsIGVsZW1lbnQgYW5kIGl0cyBhdHRyaWJ1dGVzLiBUaGUgb3V0cHV0IG11c3QgY29udGFpbiBhCi0gICAgICogZGVmaW5pdGlvbiBmb3IgZWFjaCBuYW1lc3BhY2UsIHNvIHdlIHN0dWZmIHRoZW0gaW4gYSBoYXNodGFibGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVnaXN0ZXJOYW1lc3BhY2UoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSwKLQkJCQkgIFN5bWJvbFRhYmxlIHN0YWJsZSwgYm9vbGVhbiBkZWNsYXJlZCkgewotCi0JLy8gQ2hlY2sgaWYgdGhlIHBhcmVudCBoYXMgYSBkZWNsYXJhdGlvbiBmb3IgdGhpcyBuYW1lc3BhY2UKLQlpZiAoX3BhcmVudCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIFN0cmluZyBwYXJlbnRVcmkgPSBfcGFyZW50LmFjY2Vzc2VkTmFtZXNwYWNlKHByZWZpeCk7Ci0JICAgIGlmIChwYXJlbnRVcmkgPT0gbnVsbCkgewotCQlfcGFyZW50LnJlZ2lzdGVyTmFtZXNwYWNlKHByZWZpeCwgdXJpLCBzdGFibGUsIGRlY2xhcmVkKTsKLQkJcmV0dXJuOwotCSAgICB9Ci0JICAgIGlmIChwYXJlbnRVcmkuZXF1YWxzKHVyaSkpIHJldHVybjsKLQl9Ci0KLQkvLyBDaGVjayBpZiB3ZSBoYXZlIGFueSBkZWNsYXJlZCBuYW1lc2FjZXMKLQlpZiAoX2FjY2Vzc2VkUHJlZml4ZXMgPT0gbnVsbCkgewotCSAgICBfYWNjZXNzZWRQcmVmaXhlcyA9IG5ldyBIYXNodGFibGUoKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGlmICghZGVjbGFyZWQpIHsKLQkJLy8gQ2hlY2sgaWYgdGhpcyBub2RlIGhhcyBhIGRlY2xhcmF0aW9uIGZvciB0aGlzIG5hbWVzcGFjZQotCQlmaW5hbCBTdHJpbmcgb2xkID0gKFN0cmluZylfYWNjZXNzZWRQcmVmaXhlcy5nZXQocHJlZml4KTsKLQkJaWYgKG9sZCAhPSBudWxsKSB7Ci0JCSAgICBpZiAob2xkLmVxdWFscyh1cmkpKQotCQkJcmV0dXJuOwotCQkgICAgZWxzZQotCQkJcHJlZml4ID0gc3RhYmxlLmdlbmVyYXRlTmFtZXNwYWNlUHJlZml4KCk7Ci0JCX0KLQkgICAgfQotCX0KLQotCWlmICghcHJlZml4LmVxdWFscygieG1sIikpIHsKLQkgICAgX2FjY2Vzc2VkUHJlZml4ZXMucHV0KHByZWZpeCx1cmkpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIHRoZSBwcmVmaXggb2YgYSBRTmFtZSBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzIHNldCBpbgotICAgICAqIHRoZSBhdHRyaWJ1dGVzIG9mIHhzbDpzdHlsZXNoZWV0LiBBbHNvIHJlZ2lzdGVycyBhIFFOYW1lIHRvIGFzc3VyZQotICAgICAqIHRoYXQgdGhlIG91dHB1dCBlbGVtZW50IGNvbnRhaW5zIHRoZSBuZWNlc3NhcnkgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyB0cmFuc2xhdGVRTmFtZShRTmFtZSBxbmFtZSwgU3ltYm9sVGFibGUgc3RhYmxlKSB7Ci0JLy8gQnJlYWsgdXAgdGhlIFFOYW1lIGFuZCBnZXQgcHJlZml4OmxvY2FsbmFtZSBzdHJpbmdzCi0JU3RyaW5nIGxvY2FsbmFtZSA9IHFuYW1lLmdldExvY2FsUGFydCgpOwotCVN0cmluZyBwcmVmaXggPSBxbmFtZS5nZXRQcmVmaXgoKTsKLQotCS8vIFRyZWF0IGRlZmF1bHQgbmFtZXNwYWNlIGFzICIiIGFuZCBub3QgbnVsbAotCWlmIChwcmVmaXggPT0gbnVsbCkKLQkgICAgcHJlZml4ID0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotCWVsc2UgaWYgKHByZWZpeC5lcXVhbHMoWE1MTlNfU1RSSU5HKSkKLQkgICAgcmV0dXJuKFhNTE5TX1NUUklORyk7Ci0JCi0JLy8gQ2hlY2sgaWYgd2UgbXVzdCB0cmFuc2xhdGUgdGhlIHByZWZpeAotCWZpbmFsIFN0cmluZyBhbHRlcm5hdGl2ZSA9IHN0YWJsZS5sb29rdXBQcmVmaXhBbGlhcyhwcmVmaXgpOwotCWlmIChhbHRlcm5hdGl2ZSAhPSBudWxsKSB7Ci0JICAgIHN0YWJsZS5leGNsdWRlTmFtZXNwYWNlcyhwcmVmaXgpOwotCSAgICBwcmVmaXggPSBhbHRlcm5hdGl2ZTsKLQl9Ci0KLQkvLyBHZXQgdGhlIG5hbWVzcGFjZSB0aGlzIHByZWZpeCByZWZlcnMgdG8KLQlTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0JaWYgKHVyaSA9PSBudWxsKSByZXR1cm4obG9jYWxuYW1lKTsKLQotCS8vIFJlZ2lzdGVyIHRoZSBuYW1lc3BhY2UgYXMgYWNjZXNzZWQKLQlyZWdpc3Rlck5hbWVzcGFjZShwcmVmaXgsIHVyaSwgc3RhYmxlLCBmYWxzZSk7Ci0KLQkvLyBDb25zdHJ1Y3QgdGhlIG5ldyBuYW1lIGZvciB0aGUgZWxlbWVudCAobWF5IGJlIHVuY2hhbmdlZCkKLQlpZiAocHJlZml4ICE9IENvbnN0YW50cy5FTVBUWVNUUklORykKLQkgICAgcmV0dXJuKHByZWZpeCsiOiIrbG9jYWxuYW1lKTsKLQllbHNlCi0JICAgIHJldHVybihsb2NhbG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gdGhpcyBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlKFN5bnRheFRyZWVOb2RlIGF0dHJpYnV0ZSkgewotCWlmIChfYXR0cmlidXRlRWxlbWVudHMgPT0gbnVsbCkgewotCSAgICBfYXR0cmlidXRlRWxlbWVudHMgPSBuZXcgVmVjdG9yKDIpOwotCX0KLQlfYXR0cmlidXRlRWxlbWVudHMuYWRkKGF0dHJpYnV0ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBmaXJzdCBhdHRyaWJ1dGUgb2YgdGhpcyBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0Rmlyc3RBdHRyaWJ1dGUoU3ludGF4VHJlZU5vZGUgYXR0cmlidXRlKSB7Ci0JaWYgKF9hdHRyaWJ1dGVFbGVtZW50cyA9PSBudWxsKSB7Ci0JICAgIF9hdHRyaWJ1dGVFbGVtZW50cyA9IG5ldyBWZWN0b3IoMik7Ci0JfQotCV9hdHRyaWJ1dGVFbGVtZW50cy5pbnNlcnRFbGVtZW50QXQoYXR0cmlidXRlLDApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHlwZS1jaGVjayB0aGUgY29udGVudHMgb2YgdGhpcyBlbGVtZW50LiBUaGUgZWxlbWVudCBpdHNlbGYgZG9lcyBub3QKLSAgICAgKiBuZWVkIGFueSB0eXBlIGNoZWNraW5nIGFzIGl0IGxlYXZlcyBub3RoaWduIG9uIHRoZSBKVk0ncyBzdGFjay4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCS8vIFR5cGUtY2hlY2sgYWxsIGF0dHJpYnV0ZXMKLQlpZiAoX2F0dHJpYnV0ZUVsZW1lbnRzICE9IG51bGwpIHsKLQkgICAgZmluYWwgaW50IGNvdW50ID0gX2F0dHJpYnV0ZUVsZW1lbnRzLnNpemUoKTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0JCVN5bnRheFRyZWVOb2RlIG5vZGUgPSAKLQkJICAgIChTeW50YXhUcmVlTm9kZSlfYXR0cmlidXRlRWxlbWVudHMuZWxlbWVudEF0KGkpOwotCQlub2RlLnR5cGVDaGVjayhzdGFibGUpOwotCSAgICB9Ci0JfQotCXR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBzdGFydHMgYXQgYSBnaXZlbiBub2RlLCB0cmF2ZXJzZXMgYWxsIG5hbWVzcGFjZSBtYXBwaW5ncywKLSAgICAgKiBhbmQgYXNzZW1ibGVzIGEgbGlzdCBvZiBhbGwgcHJlZml4ZXMgdGhhdCAoZm9yIHRoZSBnaXZlbiBub2RlKSBtYXBzCi0gICAgICogdG8gX0FOWV8gbmFtZXNwYWNlIFVSSS4gVXNlZCBieSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cyB0byBkZXRlcm1pbmUKLSAgICAgKi8KLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0TmFtZXNwYWNlU2NvcGUoU3ludGF4VHJlZU5vZGUgbm9kZSkgewotCUhhc2h0YWJsZSBhbGwgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JCi0Jd2hpbGUgKG5vZGUgIT0gbnVsbCkgewotCSAgICBIYXNodGFibGUgbWFwcGluZyA9IG5vZGUuZ2V0UHJlZml4TWFwcGluZygpOwotCSAgICBpZiAobWFwcGluZyAhPSBudWxsKSB7Ci0JCUVudW1lcmF0aW9uIHByZWZpeGVzID0gbWFwcGluZy5rZXlzKCk7Ci0JCXdoaWxlIChwcmVmaXhlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkgICAgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpcHJlZml4ZXMubmV4dEVsZW1lbnQoKTsKLQkJICAgIGlmICghYWxsLmNvbnRhaW5zS2V5KHByZWZpeCkpIHsKLQkJCWFsbC5wdXQocHJlZml4LCBtYXBwaW5nLmdldChwcmVmaXgpKTsKLQkJICAgIH0KLQkJfQotCSAgICB9Ci0JICAgIG5vZGUgPSBub2RlLmdldFBhcmVudCgpOwotCX0KLQlyZXR1cm4oYWxsLmtleXMoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGV0ZXJtaW5lcyB0aGUgZmluYWwgUU5hbWUgZm9yIHRoZSBlbGVtZW50IGFuZCBpdHMgYXR0cmlidXRlcy4KLSAgICAgKiBSZWdpc3RlcnMgYWxsIG5hbWVzcGFjZXMgdGhhdCBhcmUgdXNlZCBieSB0aGUgZWxlbWVudC9hdHRyaWJ1dGVzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0KLQlmaW5hbCBTeW1ib2xUYWJsZSBzdGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLQlzdGFibGUuc2V0Q3VycmVudE5vZGUodGhpcyk7Ci0KLQkvLyBGaW5kIHRoZSBjbG9zZXN0IGxpdGVyYWwgZWxlbWVudCBhbmNlc3RvciAoaWYgdGhlcmUgaXMgb25lKQotCVN5bnRheFRyZWVOb2RlIF9wYXJlbnQgPSBnZXRQYXJlbnQoKTsKLQl3aGlsZSAoKF9wYXJlbnQgIT0gbnVsbCkgJiYgIShfcGFyZW50IGluc3RhbmNlb2YgTGl0ZXJhbEVsZW1lbnQpKQotCSAgICBfcGFyZW50ID0gX3BhcmVudC5nZXRQYXJlbnQoKTsKLQlpZiAoIShfcGFyZW50IGluc3RhbmNlb2YgTGl0ZXJhbEVsZW1lbnQpKQotCSAgICBfcGFyZW50ID0gbnVsbDsKLQotCV9uYW1lID0gdHJhbnNsYXRlUU5hbWUoX3FuYW1lLCBzdGFibGUpOwotCi0JLy8gUHJvY2VzcyBhbGwgYXR0cmlidXRlcyBhbmQgcmVnaXN0ZXIgYWxsIG5hbWVzcGFjZXMgdGhleSB1c2UKLQlmaW5hbCBpbnQgY291bnQgPSBfYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLQotCSAgICBmaW5hbCBRTmFtZSBxbmFtZSA9IHBhcnNlci5nZXRRTmFtZShfYXR0cmlidXRlcy5nZXRRTmFtZShpKSk7Ci0JICAgIGZpbmFsIFN0cmluZyB1cmkgPSBxbmFtZS5nZXROYW1lc3BhY2UoKTsKLQkgICAgZmluYWwgU3RyaW5nIHZhbCA9IF9hdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotCi0JICAgIC8vIEhhbmRsZSB4c2w6dXNlLWF0dHJpYnV0ZS1zZXRzLiBBdHRyaWJ1dGUgc2V0cyBhcmUgcGxhY2VkIGZpcnN0Ci0JICAgIC8vIGluIHRoZSB2ZWN0b3Igb3IgYXR0cmlidXRlcyB0byBtYWtlIHN1cmUgdGhhdCBsYXRlciBsb2NhbAotCSAgICAvLyBhdHRyaWJ1dGVzIGNhbiBvdmVycmlkZSBhbiBhdHRyaWJ1dGVzIGluIHRoZSBzZXQuCi0JICAgIGlmIChxbmFtZSA9PSBwYXJzZXIuZ2V0VXNlQXR0cmlidXRlU2V0cygpKSB7Ci0JCXNldEZpcnN0QXR0cmlidXRlKG5ldyBVc2VBdHRyaWJ1dGVTZXRzKHZhbCwgcGFyc2VyKSk7Ci0JICAgIH0KLQkgICAgLy8gSGFuZGxlIHhzbDpleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcwotCSAgICBlbHNlIGlmIChxbmFtZSA9PSBwYXJzZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudFByZWZpeGVzKCkpIHsKLQkJc3RhYmxlLmV4Y2x1ZGVOYW1lc3BhY2VzKHZhbCk7Ci0JICAgIH0KLQkgICAgLy8gSGFuZGxlIHhzbDpleGNsdWRlLXJlc3VsdC1wcmVmaXhlcwotCSAgICBlbHNlIGlmIChxbmFtZSA9PSBwYXJzZXIuZ2V0RXhjbHVkZVJlc3VsdFByZWZpeGVzKCkpIHsKLQkJc3RhYmxlLmV4Y2x1ZGVOYW1lc3BhY2VzKHZhbCk7Ci0JICAgIH0KLQkgICAgLy8gSWdub3JlIGFsbCBvdGhlciBhdHRyaWJ1dGVzIGluIFhTTCBuYW1lc3BhY2UKLQkgICAgZWxzZSBpZiAoKHVyaSAhPSBudWxsKSAmJiAodXJpLmVxdWFscyhYU0xUX1VSSSkpKSB7Ci0JCQotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSBsaXRlcmFsIGF0dHJpYnV0ZXMgKGF0dHJpYnV0ZXMgbm90IGluIFhTTCBuYW1lc3BhY2UpCi0JICAgIGVsc2UgewotCQlmaW5hbCBTdHJpbmcgbmFtZSA9IHRyYW5zbGF0ZVFOYW1lKHFuYW1lLCBzdGFibGUpOwotCQlMaXRlcmFsQXR0cmlidXRlIGF0dHIgPSBuZXcgTGl0ZXJhbEF0dHJpYnV0ZShuYW1lLCB2YWwsIHBhcnNlcik7Ci0JCWFkZEF0dHJpYnV0ZShhdHRyKTsKLQkJYXR0ci5zZXRQYXJlbnQodGhpcyk7Ci0JCWF0dHIucGFyc2VDb250ZW50cyhwYXJzZXIpOwotCSAgICB9Ci0JfQotCi0JLy8gUmVnaXN0ZXIgYWxsIG5hbWVzcGFjZXMgdGhhdCBhcmUgaW4gc2NvcGUsIGV4Y2VwdCBmb3IgdGhvc2UgdGhhdAotCS8vIGFyZSBsaXN0ZWQgaW4gdGhlIHhzbDpzdHlsZXNoZWV0IGVsZW1lbnQncyAqLXByZWZpeGVzIGF0dHJpYnV0ZXMKLQlmaW5hbCBFbnVtZXJhdGlvbiBpbmNsdWRlID0gZ2V0TmFtZXNwYWNlU2NvcGUodGhpcyk7Ci0Jd2hpbGUgKGluY2x1ZGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IChTdHJpbmcpaW5jbHVkZS5uZXh0RWxlbWVudCgpOwotCSAgICBpZiAoIXByZWZpeC5lcXVhbHMoInhtbCIpKSB7Ci0JCWZpbmFsIFN0cmluZyB1cmkgPSBsb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLQkJaWYgKCh1cmkgIT0gbnVsbCkgJiYgKCF1cmkuZXF1YWxzKFhTTFRfVVJJKSkpIHsKLQkJICAgIGlmICghc3RhYmxlLmlzRXhjbHVkZWROYW1lc3BhY2UodXJpKSkKLQkJCXJlZ2lzdGVyTmFtZXNwYWNlKHByZWZpeCx1cmksc3RhYmxlLHRydWUpOwotCQl9Ci0JICAgIH0KLQl9Ci0KLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0KLQkvLyBQcm9jZXNzIGFsbCBhdHRyaWJ1dGVzIGFuZCByZWdpc3RlciBhbGwgbmFtZXNwYWNlcyB0aGV5IHVzZQotCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCi0JICAgIGZpbmFsIFFOYW1lIHFuYW1lID0gcGFyc2VyLmdldFFOYW1lKF9hdHRyaWJ1dGVzLmdldFFOYW1lKGkpKTsKLQkgICAgZmluYWwgU3RyaW5nIHZhbCA9IF9hdHRyaWJ1dGVzLmdldFZhbHVlKGkpOwotCi0JICAgIC8vIEhhbmRsZSB4c2w6ZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMKLQkgICAgaWYgKHFuYW1lID09IHBhcnNlci5nZXRFeHRlbnNpb25FbGVtZW50UHJlZml4ZXMoKSkgewotCQlzdGFibGUudW5FeGNsdWRlTmFtZXNwYWNlcyh2YWwpOwotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSB4c2w6ZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMKLQkgICAgZWxzZSBpZiAocW5hbWUgPT0gcGFyc2VyLmdldEV4Y2x1ZGVSZXN1bHRQcmVmaXhlcygpKSB7Ci0JCXN0YWJsZS51bkV4Y2x1ZGVOYW1lc3BhY2VzKHZhbCk7Ci0JICAgIH0KLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGV4dERlcGVuZGVudCgpIHsKLQlyZXR1cm4gZGVwZW5kZW50Q29udGVudHMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBjb2RlIHRoYXQgZW1pdHMgdGhlIGxpdGVyYWwgZWxlbWVudCB0byB0aGUgb3V0cHV0IGhhbmRsZXIsCi0gICAgICogZmlyc3QgdGhlIHN0YXJ0IHRhZywgdGhlbiBuYW1lc3BhY2UgZGVjbGFyYXRpb24sIHRoZW4gYXR0cmlidXRlcywKLSAgICAgKiB0aGVuIHRoZSBlbGVtZW50IGNvbnRlbnRzLCBhbmQgdGhlbiB0aGUgZWxlbWVudCBlbmQgdGFnLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCS8vIENvbXBpbGUgY29kZSB0byBlbWl0IGVsZW1lbnQgc3RhcnQgdGFnCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbmFtZSkpOwotCWlsLmFwcGVuZChEVVAyKTsgLy8gZHVwbGljYXRlIHRoZXNlIDIgYXJncyBmb3IgZW5kRWxlbWVudAotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RhcnRFbGVtZW50KCkpOwotCi0JLy8gT3V0cHV0IGFsbCBhdHRyaWJ1dGVzCi0JaWYgKF9hdHRyaWJ1dGVFbGVtZW50cyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBjb3VudCA9IF9hdHRyaWJ1dGVFbGVtZW50cy5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQlTeW50YXhUcmVlTm9kZSBub2RlID0gCi0JCSAgICAoU3ludGF4VHJlZU5vZGUpX2F0dHJpYnV0ZUVsZW1lbnRzLmVsZW1lbnRBdChpKTsKLQkJbm9kZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQl9Ci0KLQkvLyBDb21waWxlIGNvZGUgdG8gZW1pdCBuYW1lc3BhY2UgYXR0cmlidXRlcwotCWlmIChfYWNjZXNzZWRQcmVmaXhlcyAhPSBudWxsKSB7Ci0JICAgIEVudW1lcmF0aW9uIGUgPSBfYWNjZXNzZWRQcmVmaXhlcy5rZXlzKCk7Ci0JICAgIHdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCWZpbmFsIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKWUubmV4dEVsZW1lbnQoKTsKLQkJZmluYWwgU3RyaW5nIHVyaSA9IChTdHJpbmcpX2FjY2Vzc2VkUHJlZml4ZXMuZ2V0KHByZWZpeCk7Ci0JCWlmICgodXJpICE9IENvbnN0YW50cy5FTVBUWVNUUklORykgfHwKLQkJICAgIChwcmVmaXggPT0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgewotCQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQkJICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcscHJlZml4KSk7Ci0JCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLHVyaSkpOwotCQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uYW1lc3BhY2UoKSk7Ci0JCX0KLQkgICAgfQotCX0KLQkKLQkvLyBDb21waWxlIGNvZGUgdG8gZW1pdCBhdHRyaWJ1dGVzIGFuZCBjaGlsZCBlbGVtZW50cwotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gQ29tcGlsZSBjb2RlIHRvIGVtaXQgZWxlbWVudCBlbmQgdGFnCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5lbmRFbGVtZW50KCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxFeHByLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9MaXRlcmFsRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MzYyMTlkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xpdGVyYWxFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTMgKzAsMCBAQAotCi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIExpdGVyYWxFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgX3ZhbHVlOwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9uYW1lc3BhY2U7Ci0KLSAgICBwdWJsaWMgTGl0ZXJhbEV4cHIoU3RyaW5nIHZhbHVlKSB7Ci0JX3ZhbHVlID0gdmFsdWU7Ci0JX25hbWVzcGFjZSA9IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIExpdGVyYWxFeHByKFN0cmluZyB2YWx1ZSwgU3RyaW5nIG5hbWVzcGFjZSkgewotCV92YWx1ZSA9IHZhbHVlOwotCWlmIChuYW1lc3BhY2UuZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpCi0JICAgIF9uYW1lc3BhY2UgPSBudWxsOwotCWVsc2UKLQkgICAgX25hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCXJldHVybiBfdHlwZSA9IFR5cGUuU3RyaW5nOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJsaXRlcmFsLWV4cHIoIiArIF92YWx1ZSArICcpJzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBjb250ZXh0RGVwZW5kZW50KCkgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgewotCXJldHVybiBfdmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7Ci0JcmV0dXJuIF9uYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdmFsdWUpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Mb2NhbE5hbWVDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Mb2NhbE5hbWVDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRhNTI1NjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTG9jYWxOYW1lQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgTG9jYWxOYW1lQ2FsbCBleHRlbmRzIE5hbWVCYXNlIHsKLQotICAgIC8qKgotICAgICAqIEhhbmRsZXMgY2FsbHMgd2l0aCBubyBwYXJhbWV0ZXIgKGN1cnJlbnQgbm9kZSBpcyBpbXBsaWNpdCBwYXJhbWV0ZXIpLgotICAgICAqLwotICAgIHB1YmxpYyBMb2NhbE5hbWVDYWxsKFFOYW1lIGZuYW1lKSB7Ci0Jc3VwZXIoZm5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEhhbmRsZXMgY2FsbHMgd2l0aCBvbmUgcGFyYW1ldGVyIChlaXRoZXIgbm9kZSBvciBub2RlLXNldCkuCi0gICAgICovCi0gICAgcHVibGljIExvY2FsTmFtZUNhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgY29uc3RydWN0b3IgaXMgY29tcGlsZWQgaW4KLSAgICAgKiBTdHlsZXNoZWV0LmNvbXBpbGVDb25zdHJ1Y3RvcigpIGFuZCBub3QgYXMgdGhlIHN5bnRheCB0cmVlIGlzIHRyYXZlcnNlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gUmV0dXJucyB0aGUgbmFtZSBvZiBhIG5vZGUgaW4gdGhlIERPTQotCWZpbmFsIGludCBnZXROb2RlTmFtZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkJICAiZ2V0Tm9kZU5hbWUiLAotCQkJCQkJCSAgIihJKSIrU1RSSU5HX1NJRyk7Ci0KLQlmaW5hbCBpbnQgZ2V0TG9jYWxOYW1lID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotCQkJCQkJICAiZ2V0TG9jYWxOYW1lIiwKLQkJCQkJCSAgIihMamF2YS9sYW5nL1N0cmluZzspIisKLQkJCQkJCSAgIkxqYXZhL2xhbmcvU3RyaW5nOyIpOwotCXN1cGVyLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXROb2RlTmFtZSwgMikpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGdldExvY2FsTmFtZSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xvY2F0aW9uUGF0aFBhdHRlcm4uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xvY2F0aW9uUGF0aFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGY0MGJmYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Mb2NhdGlvblBhdGhQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzggKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTG9jYXRpb25QYXRoUGF0dGVybiBleHRlbmRzIFBhdHRlcm4gewotICAgIHByaXZhdGUgVGVtcGxhdGUgX3RlbXBsYXRlOwotICAgIHByaXZhdGUgaW50IF9pbXBvcnRQcmVjZWRlbmNlOwotICAgIHByaXZhdGUgZG91YmxlIF9wcmlvcml0eSA9IERvdWJsZS5OYU47Ci0gICAgcHJpdmF0ZSBpbnQgX3Bvc2l0aW9uID0gMDsKLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIFR5cGUuVm9pZDsJCS8vIFRPRE8KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQkvLyBUT0RPOiBXaGF0IGRvZXMgaXQgbWVhbiB0byB0cmFuc2xhdGUgYSBQYXR0ZXJuID8KLSAgICB9Ci0JCi0gICAgcHVibGljIHZvaWQgc2V0VGVtcGxhdGUoZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUpIHsKLQlfdGVtcGxhdGUgPSB0ZW1wbGF0ZTsKLQlfcHJpb3JpdHkgPSB0ZW1wbGF0ZS5nZXRQcmlvcml0eSgpOwotCV9pbXBvcnRQcmVjZWRlbmNlID0gdGVtcGxhdGUuZ2V0SW1wb3J0UHJlY2VkZW5jZSgpOwotCV9wb3NpdGlvbiA9IHRlbXBsYXRlLmdldFBvc2l0aW9uKCk7Ci0gICAgfQotCQkKLSAgICBwdWJsaWMgVGVtcGxhdGUgZ2V0VGVtcGxhdGUoKSB7Ci0JcmV0dXJuIF90ZW1wbGF0ZTsKLSAgICB9Ci0JCQotICAgIHB1YmxpYyBmaW5hbCBkb3VibGUgZ2V0UHJpb3JpdHkoKSB7Ci0JcmV0dXJuIERvdWJsZS5pc05hTihfcHJpb3JpdHkpID8gZ2V0RGVmYXVsdFByaW9yaXR5KCkgOiBfcHJpb3JpdHk7Ci0gICAgfQotCQkKLSAgICBwdWJsaWMgZG91YmxlIGdldERlZmF1bHRQcmlvcml0eSgpIHsKLQlyZXR1cm4gMC41OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgYnkgdGhlIE1vZGUgY2xhc3MgdG8gcHJpb3JpdGlzZSBwYXR0ZXJucyBhbmQKLSAgICAgKiB0ZW1wbGF0ZS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciB0ZW1wbGF0ZXMgdGhhdCBhcmUgaW4gdGhlIHNhbWUKLSAgICAgKiBtb2RlIGFuZCB0aGF0IG1hdGNoIG9uIHRoZSBzYW1lIGNvcmUgcGF0dGVybi4gVGhlIHJ1bGVzIHVzZWQgYXJlOgotICAgICAqICBvKSBmaXJzdCBjaGVjayBwcmVjZWRlbmNlIC0gaGlnaGVzdCBwcmVjZWRlbmNlIHdpbnMKLSAgICAgKiAgbykgdGhlbiBjaGVjayBwcmlvcml0eSAtIGhpZ2hlc3QgcHJpb3JpdHkgd2lucwotICAgICAqICBvKSB0aGVuIGNoZWNrIHRoZSBwb3NpdGlvbiAtIHRoZSB0ZW1wbGF0ZSB0aGF0IG9jY3VyZWQgbGFzdCB3aW5zCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbm9TbWFsbGVyVGhhbihMb2NhdGlvblBhdGhQYXR0ZXJuIG90aGVyKSB7Ci0JaWYgKF9pbXBvcnRQcmVjZWRlbmNlID4gb3RoZXIuX2ltcG9ydFByZWNlZGVuY2UpIHsKLQkgICAgcmV0dXJuIHRydWU7Ci0JfQotCWVsc2UgaWYgKF9pbXBvcnRQcmVjZWRlbmNlID09IG90aGVyLl9pbXBvcnRQcmVjZWRlbmNlKSB7Ci0JICAgIGlmIChfcHJpb3JpdHkgPiBvdGhlci5fcHJpb3JpdHkpIHsKLQkJcmV0dXJuIHRydWU7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAoX3ByaW9yaXR5ID09IG90aGVyLl9wcmlvcml0eSkgewotCQlpZiAoX3Bvc2l0aW9uID4gb3RoZXIuX3Bvc2l0aW9uKSB7Ci0JCSAgICByZXR1cm4gdHJ1ZTsKLQkJfQotCSAgICB9Ci0JfQotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgCi0gICAgLyoqIHJldHVybiBsYXN0IHBhdHRlcm4gKG1hdGNoaW5nIHRoZSBjdXJyZW50IG5vZGUpICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0ZXBQYXR0ZXJuIGdldEtlcm5lbFBhdHRlcm4oKTsKLQkKLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZWR1Y2VLZXJuZWxQYXR0ZXJuKCk7Ci0JCQotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzV2lsZGNhcmQoKTsKLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJyb290KCkiOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xvZ2ljYWxFeHByLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Mb2dpY2FsRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3OTVjNzc4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0xvZ2ljYWxFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIExvZ2ljYWxFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUiAgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFORCA9IDE7Ci0JCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgIF9vcDsgICAgIC8vIG9wZXJhdG9yCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sZWZ0OyAgIC8vIGZpcnN0IG9wZXJhbmQKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3JpZ2h0OyAgLy8gc2Vjb25kIG9wZXJhbmQKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIE9wcyA9IHsgIm9yIiwgImFuZCIgfTsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgbG9naWNhbCBleHByZXNzaW9uIC0gZWl0aGVyIE9SIG9yIEFORC4gTm90ZSB0aGF0IHRoZQotICAgICAqIGxlZnQtIGFuZCByaWdodC1oYW5kIHNpZGUgZXhwcmVzc2lvbnMgY2FuIGFsc28gYmUgbG9naWNhbCBleHByZXNzaW9ucywKLSAgICAgKiB0aHVzIGNyZWF0aW5nIGxvZ2ljYWwgdHJlZXMgcmVwcmVzZW50aW5nIHN0cnVjdHVyZXMgc3VjaCBhcwotICAgICAqIChhIGFuZCAoYiBvciBjKSBhbmQgZCksIGV0Yy4uLgotICAgICAqLwotICAgIHB1YmxpYyBMb2dpY2FsRXhwcihpbnQgb3AsIEV4cHJlc3Npb24gbGVmdCwgRXhwcmVzc2lvbiByaWdodCkgewotCV9vcCA9IG9wOwotCShfbGVmdCA9IGxlZnQpLnNldFBhcmVudCh0aGlzKTsKLQkoX3JpZ2h0ID0gcmlnaHQpLnNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoaXMgbG9naWNhbCBleHByZXNzaW9uJ3Mgb3BlcmF0b3IgLSBPUiBvciBBTkQgcmVwcmVzZW50ZWQKLSAgICAgKiBieSAwIGFuZCAxIHJlc3BlY3RpdmVseS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE9wKCkgewotCXJldHVybihfb3ApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE92ZXJyaWRlIHRoZSBTeW50YXhUcmVlTm9kZS5zZXRQYXJzZXIoKSBtZXRob2QgdG8gbWFrZSBzdXJlIHRoYXQgdGhlCi0gICAgICogcGFyc2VyIGlzIHNldCBmb3Igc3ViLWV4cHJlc3Npb25zCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlfbGVmdC5zZXRQYXJzZXIocGFyc2VyKTsKLQlfcmlnaHQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHN0cmluZyBkZXNjcmliaW5nIHRoaXMgZXhwcmVzc2lvbgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuIE9wc1tfb3BdICsgJygnICsgX2xlZnQgKyAiLCAiICsgX3JpZ2h0ICsgJyknOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUtY2hlY2sgdGhpcyBleHByZXNzaW9uLCBhbmQgcG9zc2libHkgY2hpbGQgZXhwcmVzc2lvbnMuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQkvLyBHZXQgdGhlIGxlZnQgYW5kIHJpZ2h0IG9wZXJhbmQgdHlwZXMKLQlUeXBlIHRsZWZ0ID0gX2xlZnQudHlwZUNoZWNrKHN0YWJsZSk7IAotCVR5cGUgdHJpZ2h0ID0gX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotCi0JLy8gQ2hlY2sgaWYgdGhlIG9wZXJhdG9yIHN1cHBvcnRzIHRoZSB0d28gb3BlcmFuZCB0eXBlcwotCU1ldGhvZFR5cGUgd2FudFR5cGUgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlZvaWQsIHRsZWZ0LCB0cmlnaHQpOwotCU1ldGhvZFR5cGUgaGF2ZVR5cGUgPSBsb29rdXBQcmltb3Aoc3RhYmxlLCBPcHNbX29wXSwgd2FudFR5cGUpOwotCi0JLy8gWWVzLCB0aGUgb3BlcmF0aW9uIGlzIHN1cHBvcnRlZAotCWlmIChoYXZlVHlwZSAhPSBudWxsKSB7Ci0JICAgIC8vIENoZWNrIGlmIGxlZnQtaGFuZCBzaWRlIG9wZXJhbmQgbXVzdCBiZSB0eXBlIGNhc3RlZAotCSAgICBUeXBlIGFyZzEgPSAoVHlwZSloYXZlVHlwZS5hcmdzVHlwZSgpLmVsZW1lbnRBdCgwKTsKLQkgICAgaWYgKCFhcmcxLmlkZW50aWNhbFRvKHRsZWZ0KSkKLQkJX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIGFyZzEpOwotCSAgICAvLyBDaGVjayBpZiByaWdodC1oYW5kIHNpZGUgb3BlcmFuZCBtdXN0IGJlIHR5cGUgY2FzdGVkCi0JICAgIFR5cGUgYXJnMiA9IChUeXBlKSBoYXZlVHlwZS5hcmdzVHlwZSgpLmVsZW1lbnRBdCgxKTsKLQkgICAgaWYgKCFhcmcyLmlkZW50aWNhbFRvKHRyaWdodCkpCi0JCV9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIGFyZzEpOwotCSAgICAvLyBSZXR1cm4gdGhlIHJlc3VsdCB0eXBlIGZvciB0aGUgb3BlcmF0b3Igd2Ugd2lsbCB1c2UKLQkgICAgcmV0dXJuIF90eXBlID0gaGF2ZVR5cGUucmVzdWx0VHlwZSgpOwotCX0KLQl0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgZXhwcmVzc2lvbiAtIGxlYXZlIGJvb2xlYW4gZXhwcmVzc2lvbiBvbiBzdGFjawotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCXRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0Jc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGV4cHJlc3Npb24gYW5kIHVwZGF0ZSB0cnVlL2ZhbHNlLWxpc3RzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCi0JLy8gQ29tcGlsZSBBTkQtZXhwcmVzc2lvbgotCWlmIChfb3AgPT0gQU5EKSB7Ci0KLQkgICAgLy8gVHJhbnNsYXRlIGxlZnQgaGFuZCBzaWRlIC0gbXVzdCBiZSB0cnVlCi0JICAgIF9sZWZ0LnRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgLy8gTmVlZCB0aGlzIGZvciBjaGFpbmluZyBhbnkgT1ItZXhwcmVzc2lvbiBjaGlsZHJlbgotCSAgICBJbnN0cnVjdGlvbkhhbmRsZSBtaWRkbGUgPSBpbC5hcHBlbmQoTk9QKTsKLQotCSAgICAvLyBUcmFuc2xhdGUgbGVmdCByaWdodCBzaWRlIC0gbXVzdCBiZSB0cnVlCi0JICAgIF9yaWdodC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JICAgIC8vIE5lZWQgdGhpcyBmb3IgY2hhaW5pbmcgYW55IE9SLWV4cHJlc3Npb24gY2hpbGRyZW4KLQkgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgYWZ0ZXIgPSBpbC5hcHBlbmQoTk9QKTsKLQotCSAgICAvLyBBcHBlbmQgY2hpbGQgZXhwcmVzc2lvbiBmYWxzZS1saXN0cyB0byBvdXIgZmFsc2UtbGlzdAotCSAgICBfZmFsc2VMaXN0LmFwcGVuZChfcmlnaHQuX2ZhbHNlTGlzdC5hcHBlbmQoX2xlZnQuX2ZhbHNlTGlzdCkpOwotCi0JICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgT1ItZXhwcmVzc2lvbiBhcyBhIGxlZnQgY2hpbGQgb2YgQU5ELgotCSAgICAvLyBUaGUgdHJ1ZS1saXN0IG9mIE9SIG11c3QgcG9pbnQgdG8gc2Vjb25kIGNsYXVzZSBvZiBBTkQuCi0JICAgIGlmICgoX2xlZnQgaW5zdGFuY2VvZiBMb2dpY2FsRXhwcikgJiYKLQkJKCgoTG9naWNhbEV4cHIpX2xlZnQpLmdldE9wKCkgPT0gT1IpKSB7Ci0JCSgoTG9naWNhbEV4cHIpX2xlZnQpLmJhY2tQYXRjaFRydWVMaXN0KG1pZGRsZSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCV90cnVlTGlzdC5hcHBlbmQoX2xlZnQuX3RydWVMaXN0KTsKLQkgICAgfQotCi0JICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgT1ItZXhwcmVzc2lvbiBhcyBhIHJpZ2h0IGNoaWxkIG9mIEFORAotCSAgICAvLyBUaGUgdHJ1ZS1saXN0IG9mIE9SIG11c3QgcG9pbnQgdG8gdHJ1ZS1saXN0IG9mIEFORC4KLQkgICAgaWYgKChfcmlnaHQgaW5zdGFuY2VvZiBMb2dpY2FsRXhwcikgJiYKLQkJKCgoTG9naWNhbEV4cHIpX3JpZ2h0KS5nZXRPcCgpID09IE9SKSkgewotCQkoKExvZ2ljYWxFeHByKV9yaWdodCkuYmFja1BhdGNoVHJ1ZUxpc3QoYWZ0ZXIpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlfdHJ1ZUxpc3QuYXBwZW5kKF9yaWdodC5fdHJ1ZUxpc3QpOwotCSAgICB9Ci0KLQl9IAotCS8vIENvbXBpbGUgT1ItZXhwcmVzc2lvbgotCWVsc2UgewotCSAgICAvLyBUcmFuc2xhdGUgbGVmdC1oYW5kIHNpZGUgZXhwcmVzc2lvbiBhbmQgcHJvZHVjZSB0cnVlL2ZhbHNlIGxpc3QKLQkgICAgX2xlZnQudHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICAvLyBUaGlzIEdPVE8gaXMgdXNlZCB0byBza2lwIG92ZXIgdGhlIGNvZGUgZm9yIHRoZSBsYXN0IHRlc3QKLQkgICAgLy8gaW4gdGhlIGNhc2Ugd2hlcmUgdGhlIHRoZSBmaXJzdCB0ZXN0IHN1Y2NlZWRzCi0JICAgIEluc3RydWN0aW9uSGFuZGxlIGloID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLQotCSAgICAvLyBUcmFuc2xhdGUgcmlnaHQtaGFuZCBzaWRlIGV4cHJlc3Npb24gYW5kIHByb2R1Y2UgdHJ1ZS9mYWxzZSBsaXN0Ci0JICAgIF9yaWdodC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JICAgIF9sZWZ0Ll90cnVlTGlzdC5iYWNrUGF0Y2goaWgpOwotCSAgICBfbGVmdC5fZmFsc2VMaXN0LmJhY2tQYXRjaChpaC5nZXROZXh0KCkpOwotCQkJCi0JICAgIF9mYWxzZUxpc3QuYXBwZW5kKF9yaWdodC5fZmFsc2VMaXN0KTsKLQkgICAgX3RydWVMaXN0LmFkZChpaCkuYXBwZW5kKF9yaWdodC5fdHJ1ZUxpc3QpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9NYWtlZmlsZS5pbmMgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9NYWtlZmlsZS5pbmMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVjODUzOWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTWFrZWZpbGUuaW5jCisrKyAvZGV2L251bGwKQEAgLTEsMzggKzAsMCBAQAotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjCi0jIE1ha2VmaWxlLmluYyBmb3IgWFNMVCBjb21waWxlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwotIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIFVzZWZ1bCBtYWNyb3MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIwotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLQotSkFWQUMgPSBqYXZhYwotI0pBVkFDX0ZMQUdTID0gLWcgLWQgJChYU0xUKS9zcmMvY2xhc3NlcwotSkFWQUNfRkxBR1MgPSAtc291cmNlcGF0aCAkKFhTTFQpL3NyYwotSkFWQUNDID0gamF2YWNjCi1KQVZBQ0NfRkxBR1MgPSAtc3RhdGljPUZBTFNFIAotSkFWQUNVUCA9IGphdmFjdXAKLUpBVkFDVVBfRkxBR1MgPQotSkFWQUxFWCA9IGpsZXgKLUpBVkFMRVhfRkxBR1MgPQotCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyAgRXhwbGljaXQgcnVsZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMKLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0KLS5TVUZGSVhFUzogLmphdmEgLmNsYXNzIC5qaiAubGV4IC5jdXAKLQotLmphdmEuY2xhc3M6Ci0JJChKQVZBQykgJChKQVZBQ19GTEFHUykgJDwKLQotLmpqLmphdmE6Ci0JJChKQVZBQ0MpICQoSkFWQUNDX0ZMQUdTKSAkPAotCi0uY3VwLmphdmE6Ci0JJChKQVZBQ1VQKSAkKEpBVkFDVVBfRkxBR1MpICQ8Ci0KLS5sZXguamF2YToKLQkkKEpBVkFMRVgpICQoSkFWQUxFWF9GTEFHUykgJDwKLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTWVzc2FnZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTWVzc2FnZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NGE0YjIwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL01lc3NhZ2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzOSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuSmF2YUNsYXNzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIE1lc3NhZ2UgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF90ZXJtaW5hdGUgPSBmYWxzZTsKLQkKLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQlTdHJpbmcgdGVybXN0ciA9IGdldEF0dHJpYnV0ZSgidGVybWluYXRlIik7Ci0JaWYgKHRlcm1zdHIgIT0gbnVsbCkgewotICAgICAgICAgICAgX3Rlcm1pbmF0ZSA9IHRlcm1zdHIuZXF1YWxzKCJ5ZXMiKTsKLQl9Ci0JcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JCi0JLy8gU2F2ZSB0aGUgY3VycmVudCBoYW5kbGVyIGJhc2Ugb24gdGhlIHN0YWNrCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQkvLyBHZXQgdGhlIHRyYW5zbGV0J3MgU3RyaW5nVmFsdWVIYW5kbGVyCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJICAgICAgICJzdHJpbmdWYWx1ZUhhbmRsZXIiLAotCQkJCQkgICAgICAgU1RSSU5HX1ZBTFVFX0hBTkRMRVJfU0lHKSkpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotCi0JLy8gVHJhbnNsYXRlIGNvbnRlbnRzIHdpdGggc3Vic3RpdHV0ZWQgaGFuZGxlcgotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gR2V0IHN0cmluZyBmcm9tIGFsbCBjaGlsZHJlbiBmcm9tIHRoZSBoYW5kbGVyCi0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX1ZBTFVFX0hBTkRMRVIsCi0JCQkJCQkgICAgICJnZXRWYWx1ZSIsCi0JCQkJCQkgICAgICIoKSIgKyBTVFJJTkdfU0lHKSkpOwotCS8vIFB1c2ggdGhlIHRoaXMgcG9pbnRlciBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChTV0FQKTsKLQotCS8vIFNlbmQgdGhlIHJlc3VsdGluZyBzdHJpbmcgdG8gdGhlIG1lc3NhZ2UgaGFuZGxpbmcgbWV0aG9kCi0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkgICAgICJkaXNwbGF5TWVzc2FnZSIsCi0JCQkJCQkgICAgICIoIitTVFJJTkdfU0lHKyIpViIpKSk7Ci0KLQkvLyBJZiAndGVybWluYXRlJyBhdHRyaWJ1dGUgaXMgc2V0IHRvICd5ZXMnOiBJbnN0YW5jaWF0ZSBhCi0JLy8gUnVuVGltZUV4Y2VwdGlvbiwgYnV0IGl0IG9uIHRoZSBzdGFjayBhbmQgdGhyb3cgYW4gZXhjZXB0aW9uCi0JaWYgKF90ZXJtaW5hdGUgPT0gdHJ1ZSkgewotCSAgICAvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgUnVuVGltZUV4Y2VwdGlvbgotCSAgICBmaW5hbCBpbnQgZWluaXQgPSBjcGcuYWRkTWV0aG9kcmVmKCJqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbiIsCi0JCQkJCSAgICAgICAiPGluaXQ+IiwKLQkJCQkJICAgICAgICIoTGphdmEvbGFuZy9TdHJpbmc7KVYiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKCJqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbiIpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCJUZXJtaW5hdGlvbiBmb3JjZWQgYnkgYW4gIiArCi0JCQkgICAgICAgICAgICJ4c2w6bWVzc2FnZSBpbnN0cnVjdGlvbiIpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGVpbml0KSk7Ci0JICAgIGlsLmFwcGVuZChBVEhST1cpOwotCX0KLQotCS8vIENsZWFuIHVwOiBSZXN0b3JlL3BvcCBvbGQgaGFuZGxlciBiYXNlIGZyb20gc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLSAgICB9Ci0gICAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Nb2RlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Nb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNmNGRjMWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTW9kZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODk4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci0KLS8qKgotICogTW9kZSBnYXRoZXJzIGFsbCB0aGUgdGVtcGxhdGVzIGJlbG9uZ2luZyB0byBhIGdpdmVuIG1vZGU7IGl0IGlzIHJlc3BvbnNpYmxlCi0gKiBmb3IgZ2VuZXJhdGluZyBhbiBhcHByb3ByaWF0ZSBhcHBseVRlbXBsYXRlcyArIChtb2RlIG5hbWUpIGZ1bmN0aW9uCi0gKi8KLWZpbmFsIGNsYXNzIE1vZGUgaW1wbGVtZW50cyBDb25zdGFudHMgewotCi0gICAgcHJpdmF0ZSBmaW5hbCBRTmFtZSAgICAgIF9uYW1lOyAgICAgICAvLyBUaGUgUU5hbWUgb2YgdGhpcyBtb2RlCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHlsZXNoZWV0IF9zdHlsZXNoZWV0OyAvLyBUaGUgb3duaW5nIHN0eWxlc2hlZXQKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyAgICAgX21ldGhvZE5hbWU7IC8vIFRoZSBtZXRob2QgbmFtZSBmb3IgdGhpcyBtb2RlCi0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgICAgIF90ZW1wbGF0ZXM7ICAvLyBBbGwgdGVtcGxhdGVzIGluIHRoaXMgbW9kZQotCi0gICAgLy8gUGF0dGVybi90ZXN0IHNlcXVlbmNlIGZvciBwYXR0ZXJuIHdpdGggbm9kZSgpLXR5cGUga2VybmVsCi0gICAgcHJpdmF0ZSBWZWN0b3IgICAgX25vZGVHcm91cCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBUZXN0U2VxICAgX25vZGVUZXN0U2VxID0gbnVsbDsKLQotICAgIC8vIFBhdHRlcm4vdGVzdCBzZXF1ZW5jZSBmb3IgcGF0dGVybiB3aXRoIGlkKCkgb3Iga2V5KCktdHlwZSBrZXJuZWwKLSAgICBwcml2YXRlIFZlY3RvciAgICBfaWR4R3JvdXAgPSBudWxsOwotICAgIHByaXZhdGUgVGVzdFNlcSAgIF9pZHhUZXN0U2VxID0gbnVsbDsKLQotICAgIC8vIFBhdHRlcm4vdGVzdCBzZXF1ZW5jZSBmb3IgcGF0dGVybnMgd2l0aCBhbnkgb3RoZXIga2VybmVsIHR5cGUKLSAgICBwcml2YXRlIFZlY3RvcltdICBfcGF0dGVybkdyb3VwczsKLSAgICBwcml2YXRlIFRlc3RTZXFbXSBfdGVzdFNlcTsKLQotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF9uZWVkZWRUZW1wbGF0ZXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgX25hbWVkVGVtcGxhdGVzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF90ZW1wbGF0ZUlIcyA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZSBfdGVtcGxhdGVJTHMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgcHJpdmF0ZSBMb2NhdGlvblBhdGhQYXR0ZXJuIF9yb290UGF0dGVybiA9IG51bGw7Ci0KLSAgICAvLyBWYXJpYWJsZSBpbmRleCBmb3IgdGhlIGN1cnJlbnQgbm9kZSAtIHVzZWQgaW4gY29kZSBnZW5lcmF0aW9uCi0gICAgcHJpdmF0ZSBpbnQgX2N1cnJlbnRJbmRleDsKLQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBNb2RlCi0gICAgICogQHBhcmFtIG5hbWUgQSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlJ3MgUU5hbWUKLSAgICAgKiBAcGFyYW0gc3R5bGVzaGVldCBUaGUgU3R5bGVzaGVldCBpbiB3aGljaCB0aGUgbW9kZSBvY2N1cmVkCi0gICAgICogQHBhcmFtIHN1ZmZpeCBBIHN1ZmZpeCB0byBhcHBlbmQgdG8gdGhlIG1ldGhvZCBuYW1lIGZvciB0aGlzIG1vZGUKLSAgICAgKiAgICAgICAgICAgICAgIChub3JtYWxseSBhIHNlcXVlbmNlIG51bWJlciAtIHN0aWxsIGluIGEgU3RyaW5nKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTW9kZShRTmFtZSBuYW1lLCBTdHlsZXNoZWV0IHN0eWxlc2hlZXQsIFN0cmluZyBzdWZmaXgpIHsKLQkvLyBTYXZlIGdsb2JhbCBpbmZvCi0JX25hbWUgPSBuYW1lOwotCV9zdHlsZXNoZWV0ID0gc3R5bGVzaGVldDsKLQlfbWV0aG9kTmFtZSA9IEFQUExZX1RFTVBMQVRFUyArIHN1ZmZpeDsKLQkvLyBJbml0aWFsaXNlIHNvbWUgZGF0YSBzdHJ1Y3R1cmVzCi0JX3RlbXBsYXRlcyA9IG5ldyBWZWN0b3IoKTsKLQlfcGF0dGVybkdyb3VwcyA9IG5ldyBWZWN0b3JbMzJdOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCAoX25vdF8gZnVuY3Rpb24pIHRoYXQgd2lsbCBiZSBjb21waWxlZAotICAgICAqIGZvciB0aGlzIG1vZGUuIE5vcm1hbGx5IHRha2VzIHRoZSBmb3JtICdhcHBseVRlbXBsYXRlcygpJyBvcgotICAgICAqICdhcHBseVRlbXBsYXRlczIoKScuCi0gICAgICogQHJldHVybiBNZXRob2QgbmFtZSBmb3IgdGhpcyBtb2RlCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBmdW5jdGlvbk5hbWUoKSB7Ci0JcmV0dXJuIF9tZXRob2ROYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNob3J0Y3V0IHRvIGdldCB0aGUgY2xhc3MgY29tcGlsZWQgZm9yIHRoaXMgbW9kZSAod2lsbCBiZSBpbmxpbmVkKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0JcmV0dXJuIF9zdHlsZXNoZWV0LmdldENsYXNzTmFtZSgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhIHRlbXBsYXRlIHRvIHRoaXMgbW9kZQotICAgICAqIEBwYXJhbSB0ZW1wbGF0ZSBUaGUgdGVtcGxhdGUgdG8gYWRkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkVGVtcGxhdGUoVGVtcGxhdGUgdGVtcGxhdGUpIHsKLQlfdGVtcGxhdGVzLmFkZEVsZW1lbnQodGVtcGxhdGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByb2Nlc3MgYWxsIHRoZSB0ZXN0IHBhdHRlcm5zIGluIHRoaXMgbW9kZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NQYXR0ZXJucyhIYXNodGFibGUga2V5cykgewotCS8vIFRyYXZlcnNlIGFsbCB0ZW1wbGF0ZXMKLQlmaW5hbCBFbnVtZXJhdGlvbiB0ZW1wbGF0ZXMgPSBfdGVtcGxhdGVzLmVsZW1lbnRzKCk7Ci0Jd2hpbGUgKHRlbXBsYXRlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICAvLyBHZXQgdGhlIG5leHQgdGVtcGxhdGUKLQkgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSAoVGVtcGxhdGUpdGVtcGxhdGVzLm5leHRFbGVtZW50KCk7Ci0KLQkgICAgLy8gQWRkIHRoaXMgdGVtcGxhdGUgdG8gYSB0YWJsZSBvZiBuYW1lZCB0ZW1wbGF0ZXMgaWYgaXQgaGFzIGEgbmFtZS4KLQkgICAgLy8gSWYgdGhlcmUgYXJlIG11bHRpcGxlIHRlbXBsYXRlcyB3aXRoIHRoZSBzYW1lIG5hbWUsIGFsbCBidXQgb25lCi0JICAgIC8vICh0aGUgb25lIHdpdGggaGlnaGVzdCBwcmlvcml0eSkgd2lsbCBiZSBkaXNhYmxlZC4KLQkgICAgaWYgKHRlbXBsYXRlLmlzTmFtZWQoKSAmJiAhdGVtcGxhdGUuZGlzYWJsZWQoKSkKLQkJX25hbWVkVGVtcGxhdGVzLnB1dCh0ZW1wbGF0ZSwgdGhpcyk7Ci0KLQkgICAgLy8gQWRkIHRoaXMgdGVtcGxhdGUgdG8gYSB0ZXN0IHNlcXVlbmNlIGlmIGl0IGhhcyBhIHBhdHRlcm4KLQkgICAgZmluYWwgUGF0dGVybiBwYXR0ZXJuID0gdGVtcGxhdGUuZ2V0UGF0dGVybigpOwotCSAgICBpZiAocGF0dGVybiAhPSBudWxsKSBmbGF0dGVuQWx0ZXJuYXRpdmUocGF0dGVybiwgdGVtcGxhdGUsIGtleXMpOwotCX0KLQlwcmVwYXJlVGVzdFNlcXVlbmNlcygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYnJlYWsgdXAgYWx0ZXJuYXRpdmUgcGF0dGVybnMgKGllLiB1bmlvbnMgb2YgcGF0dGVybnMsCi0gICAgICogc3VjaCBhcyBtYXRjaD0iQS9CIHwgQy9CIikgYW5kIGFkZCB0aGUgYmFzaWMgcGF0dGVybnMgdG8gdGhlaXIKLSAgICAgKiByZXNwZWN0aXZlIHBhdHRlcm4gZ3JvdXBzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBmbGF0dGVuQWx0ZXJuYXRpdmUoUGF0dGVybiBwYXR0ZXJuLAotCQkJCSAgICBUZW1wbGF0ZSB0ZW1wbGF0ZSwKLQkJCQkgICAgSGFzaHRhYmxlIGtleXMpIHsKLQkvLyBQYXR0ZXJucyBvbiB0eXBlIGlkKCkgYW5kIGtleSgpIGFyZSBzcGVjaWFsIHNpbmNlIHRoZXkgZG8gbm90IGhhdmUKLQkvLyBhbnkga2VybmVsIG5vZGUgdHlwZSAoaXQgY2FuIGJlIGFueXRoaW5nIGFzIGxvbmcgYXMgdGhlIG5vZGUgaXMgaW4KLQkvLyB0aGUgaWQncyBvciBrZXkncyBpbmRleCkuCi0JaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBJZEtleVBhdHRlcm4pIHsKLQkgICAgZmluYWwgSWRLZXlQYXR0ZXJuIGlka2V5ID0gKElkS2V5UGF0dGVybilwYXR0ZXJuOwotCSAgICBpZGtleS5zZXRUZW1wbGF0ZSh0ZW1wbGF0ZSk7Ci0JICAgIGlmIChfaWR4R3JvdXAgPT0gbnVsbCkgX2lkeEdyb3VwID0gbmV3IFZlY3RvcigpOwotCSAgICBfaWR4R3JvdXAuYWRkKHBhdHRlcm4pOwotCX0KLQkvLyBBbHRlcm5hdGl2ZSBwYXR0ZXJucyBhcmUgYnJva2VuIHVwIGFuZCByZS1wcm9jZXNzZWQgcmVjdXJzaXZlbHkKLQllbHNlIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgQWx0ZXJuYXRpdmVQYXR0ZXJuKSB7Ci0JICAgIGZpbmFsIEFsdGVybmF0aXZlUGF0dGVybiBhbHQgPSAoQWx0ZXJuYXRpdmVQYXR0ZXJuKXBhdHRlcm47Ci0JICAgIGZsYXR0ZW5BbHRlcm5hdGl2ZShhbHQuZ2V0TGVmdCgpLCB0ZW1wbGF0ZSwga2V5cyk7Ci0JICAgIGZsYXR0ZW5BbHRlcm5hdGl2ZShhbHQuZ2V0UmlnaHQoKSwgdGVtcGxhdGUsIGtleXMpOwotCX0KLQkvLyBGaW5hbGx5IHdlIGhhdmUgYSBwYXR0ZXJuIHRoYXQgY2FuIGJlIGFkZGVkIHRvIGEgdGVzdCBzZXF1ZW5jZSEKLQllbHNlIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgTG9jYXRpb25QYXRoUGF0dGVybikgewotCSAgICBmaW5hbCBMb2NhdGlvblBhdGhQYXR0ZXJuIGxwcCA9IChMb2NhdGlvblBhdGhQYXR0ZXJuKXBhdHRlcm47Ci0JICAgIGxwcC5zZXRUZW1wbGF0ZSh0ZW1wbGF0ZSk7Ci0JICAgIGFkZFBhdHRlcm5Ub0dyb3VwKGxwcCk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgYSBwYXR0ZXJuIHRvIGEgcGF0dGVybiBncm91cAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBhZGRQYXR0ZXJuKGludCBrZXJuZWxUeXBlLCBMb2NhdGlvblBhdGhQYXR0ZXJuIHBhdHRlcm4pIHsKLQotCS8vIE1ha2Ugc3VyZSB0aGUgYXJyYXkgb2YgcGF0dGVybiBncm91cHMgaXMgbG9uZyBlbm91Z2gKLQlmaW5hbCBpbnQgb2xkTGVuZ3RoID0gX3BhdHRlcm5Hcm91cHMubGVuZ3RoOwotCWlmIChrZXJuZWxUeXBlID49IG9sZExlbmd0aCkgewotCSAgICBWZWN0b3JbXSBuZXdHcm91cHMgPSBuZXcgVmVjdG9yW2tlcm5lbFR5cGUgKiAyXTsKLQkgICAgU3lzdGVtLmFycmF5Y29weShfcGF0dGVybkdyb3VwcywgMCwgbmV3R3JvdXBzLCAwLCBvbGRMZW5ndGgpOwotCSAgICBfcGF0dGVybkdyb3VwcyA9IG5ld0dyb3VwczsKLQl9Ci0JCi0JLy8gRmluZCB0aGUgdmVjdG9yIHRvIHB1dCB0aGlzIHBhdHRlcm4gaW50bwotCVZlY3RvciBwYXR0ZXJuczsKLQotCS8vIFVzZSB0aGUgdmVjdG9yIGZvciBpZCgpL2tleSgpL25vZGUoKSBwYXR0ZXJucyBpZiBubyBrZXJuZWwgdHlwZQotCWlmIChrZXJuZWxUeXBlID09IC0xKQotCSAgICBwYXR0ZXJucyA9IF9ub2RlR3JvdXA7Ci0JZWxzZQotCSAgICBwYXR0ZXJucyA9IF9wYXR0ZXJuR3JvdXBzW2tlcm5lbFR5cGVdOwotCi0JLy8gQ3JlYXRlIGEgbmV3IHZlY3RvciBpZiBuZWVkZWQgYW5kIGluc2VydCB0aGUgdmVyeSBmaXJzdCBwYXR0ZXJuCi0JaWYgKHBhdHRlcm5zID09IG51bGwpIHsKLQkgICAgcGF0dGVybnMgPSBuZXcgVmVjdG9yKDIpOwotCSAgICBwYXR0ZXJucy5hZGRFbGVtZW50KHBhdHRlcm4pOwotCSAgICBpZiAoa2VybmVsVHlwZSA9PSAtMSkKLQkJX25vZGVHcm91cCA9IHBhdHRlcm5zOwotCSAgICBlbHNlCi0JCV9wYXR0ZXJuR3JvdXBzW2tlcm5lbFR5cGVdID0gcGF0dGVybnM7Ci0JfQotCS8vIE90aGVyd2lzZSBtYWtlIHN1cmUgcGF0dGVybnMgYXJlIG9yZGVyZWQgYnkgcHJlY2VkZW5jZS9wcmlvcml0aWVzCi0JZWxzZSB7Ci0JICAgIGJvb2xlYW4gaW5zZXJ0ZWQgPSBmYWxzZTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXR0ZXJucy5zaXplKCk7IGkrKykgewotCQlmaW5hbCBMb2NhdGlvblBhdGhQYXR0ZXJuIGxwcFRvQ29tcGFyZSA9Ci0JCSAgICAoTG9jYXRpb25QYXRoUGF0dGVybilwYXR0ZXJucy5lbGVtZW50QXQoaSk7Ci0JCWlmIChwYXR0ZXJuLm5vU21hbGxlclRoYW4obHBwVG9Db21wYXJlKSkgewotCQkgICAgaW5zZXJ0ZWQgPSB0cnVlOwotCQkgICAgcGF0dGVybnMuaW5zZXJ0RWxlbWVudEF0KHBhdHRlcm4sIGkpOwotCQkgICAgYnJlYWs7Ci0JCX0KLQkgICAgfQotCSAgICBpZiAoaW5zZXJ0ZWQgPT0gZmFsc2UpIHsKLQkJcGF0dGVybnMuYWRkRWxlbWVudChwYXR0ZXJuKTsKLQkgICAgfQotCX0KLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogR3JvdXAgcGF0dGVybnMgYnkgTm9kZVRlc3RzIG9mIHRoZWlyIGxhc3QgU3RlcAotICAgICAqIEtlZXAgdGhlbSBzb3J0ZWQgYnkgcHJpb3JpdHkgd2l0aGluIGdyb3VwCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGFkZFBhdHRlcm5Ub0dyb3VwKGZpbmFsIExvY2F0aW9uUGF0aFBhdHRlcm4gbHBwKSB7Ci0JLy8gaWQoKSBhbmQga2V5KCktdHlwZSBwYXR0ZXJucyBkbyBub3QgaGF2ZSBhIGtlcm5lbCB0eXBlCi0JaWYgKGxwcCBpbnN0YW5jZW9mIElkS2V5UGF0dGVybikgewotCSAgICBhZGRQYXR0ZXJuKC0xLCBscHApOwotCX0KLQkvLyBPdGhlcndpc2UgZ2V0IHRoZSBrZXJuZWwgcGF0dGVybiBmcm9tIHRoZSBMUFAKLQllbHNlIHsKLQkgICAgLy8ga2VybmVsIHBhdHRlcm4gaXMgdGhlIGxhc3QgKG1heWJlIG9ubHkpIFN0ZXAKLQkgICAgZmluYWwgU3RlcFBhdHRlcm4ga2VybmVsID0gbHBwLmdldEtlcm5lbFBhdHRlcm4oKTsKLQkgICAgaWYgKGtlcm5lbCAhPSBudWxsKSB7Ci0JCWFkZFBhdHRlcm4oa2VybmVsLmdldE5vZGVUeXBlKCksIGxwcCk7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAoX3Jvb3RQYXR0ZXJuID09IG51bGwgfHwKLQkJICAgICBscHAubm9TbWFsbGVyVGhhbihfcm9vdFBhdHRlcm4pKSB7Ci0JCV9yb290UGF0dGVybiA9IGxwcDsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCdWlsZCB0ZXN0IHNlcXVlbmNlcwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwcmVwYXJlVGVzdFNlcXVlbmNlcygpIHsKLQlmaW5hbCBWZWN0b3IgbmFtZXMgPSBfc3R5bGVzaGVldC5nZXRYU0xUQygpLmdldE5hbWVzSW5kZXgoKTsKLQlfdGVzdFNlcSA9IG5ldyBUZXN0U2VxW0RPTS5OVFlQRVMgKyBuYW1lcy5zaXplKCldOwotCQotCWZpbmFsIGludCBuID0gX3BhdHRlcm5Hcm91cHMubGVuZ3RoOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JICAgIGZpbmFsIFZlY3RvciBwYXR0ZXJucyA9IF9wYXR0ZXJuR3JvdXBzW2ldOwotCSAgICBpZiAocGF0dGVybnMgIT0gbnVsbCkgewotCQlmaW5hbCBUZXN0U2VxIHRlc3RTZXEgPSBuZXcgVGVzdFNlcShwYXR0ZXJucywgdGhpcyk7Ci0JCXRlc3RTZXEucmVkdWNlKCk7Ci0JCV90ZXN0U2VxW2ldID0gdGVzdFNlcTsKLQkJdGVzdFNlcS5maW5kVGVtcGxhdGVzKF9uZWVkZWRUZW1wbGF0ZXMpOwotCSAgICB9Ci0JfQotCi0JaWYgKChfbm9kZUdyb3VwICE9IG51bGwpICYmIChfbm9kZUdyb3VwLnNpemUoKSA+IDApKSB7Ci0JICAgIF9ub2RlVGVzdFNlcSA9IG5ldyBUZXN0U2VxKF9ub2RlR3JvdXAsIHRoaXMpOwotCSAgICBfbm9kZVRlc3RTZXEucmVkdWNlKCk7Ci0JICAgIF9ub2RlVGVzdFNlcS5maW5kVGVtcGxhdGVzKF9uZWVkZWRUZW1wbGF0ZXMpOwotCX0KLQotCWlmICgoX2lkeEdyb3VwICE9IG51bGwpICYmIChfaWR4R3JvdXAuc2l6ZSgpID4gMCkpIHsKLQkgICAgX2lkeFRlc3RTZXEgPSBuZXcgVGVzdFNlcShfaWR4R3JvdXAsIHRoaXMpOwotCSAgICBfaWR4VGVzdFNlcS5yZWR1Y2UoKTsKLQkgICAgX2lkeFRlc3RTZXEuZmluZFRlbXBsYXRlcyhfbmVlZGVkVGVtcGxhdGVzKTsKLQl9Ci0JCi0JaWYgKF9yb290UGF0dGVybiAhPSBudWxsKSB7Ci0JICAgIC8vIGRvZXNuJ3QgbWF0dGVyIHdoYXQgaXMgJ3B1dCcsIG9ubHkga2V5IG1hdHRlcnMKLQkgICAgX25lZWRlZFRlbXBsYXRlcy5wdXQoX3Jvb3RQYXR0ZXJuLmdldFRlbXBsYXRlKCksIHRoaXMpOwotCX0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZU5hbWVkVGVtcGxhdGUoVGVtcGxhdGUgdGVtcGxhdGUsCi0JCQkJICAgICAgQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCVN0cmluZyBtZXRob2ROYW1lID0gdGVtcGxhdGUuZ2V0TmFtZSgpLnRvU3RyaW5nKCk7Ci0JbWV0aG9kTmFtZSA9IG1ldGhvZE5hbWUucmVwbGFjZSgnLicsICckJyk7Ci0JbWV0aG9kTmFtZSA9IG1ldGhvZE5hbWUucmVwbGFjZSgnLScsICckJyk7Ci0KLQlmaW5hbCBOYW1lZE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4gPQotCSAgICBuZXcgTmFtZWRNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLQkJCQkgICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuVk9JRCwKLQkJCQkgICAgIG5ldyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlW10gewotCQkJCQkgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLQkJCQkJIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLQkJCQkJIFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpLAotCQkJCQkgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQKLQkJCQkgICAgIH0sCi0JCQkJICAgICBuZXcgU3RyaW5nW10gewotCQkJCQkgRE9DVU1FTlRfUE5BTUUsCi0JCQkJCSBJVEVSQVRPUl9QTkFNRSwKLQkJCQkJIFRSQU5TTEVUX09VVFBVVF9QTkFNRSwKLQkJCQkJIE5PREVfUE5BTUUKLQkJCQkgICAgIH0sCi0JCQkJICAgICBtZXRob2ROYW1lLAotCQkJCSAgICAgZ2V0Q2xhc3NOYW1lKCksCi0JCQkJICAgICBpbCwgY3BnKTsKLQkKLQlpbC5hcHBlbmQodGVtcGxhdGUuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuKSk7Ci0JaWwuYXBwZW5kKFJFVFVSTik7Ci0JCi0JbWV0aG9kR2VuLnN0cmlwQXR0cmlidXRlcyh0cnVlKTsKLQltZXRob2RHZW4uc2V0TWF4TG9jYWxzKCk7Ci0JbWV0aG9kR2VuLnNldE1heFN0YWNrKCk7Ci0JbWV0aG9kR2VuLnJlbW92ZU5PUHMoKTsKLQljbGFzc0dlbi5hZGRNZXRob2QobWV0aG9kR2VuLmdldE1ldGhvZCgpKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZVRlbXBsYXRlcyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0JCQkJICBJbnN0cnVjdGlvbkhhbmRsZSBuZXh0KSB7Ci0gICAgICAgIEVudW1lcmF0aW9uIHRlbXBsYXRlcyA9IF9uYW1lZFRlbXBsYXRlcy5rZXlzKCk7Ci0gICAgICAgIHdoaWxlICh0ZW1wbGF0ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLSAgICAgICAgICAgIGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gKFRlbXBsYXRlKXRlbXBsYXRlcy5uZXh0RWxlbWVudCgpOwotICAgICAgICAgICAgY29tcGlsZU5hbWVkVGVtcGxhdGUodGVtcGxhdGUsIGNsYXNzR2VuKTsKLSAgICAgICAgfQotCi0JdGVtcGxhdGVzID0gX25lZWRlZFRlbXBsYXRlcy5rZXlzKCk7Ci0Jd2hpbGUgKHRlbXBsYXRlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBUZW1wbGF0ZSB0ZW1wbGF0ZSA9IChUZW1wbGF0ZSl0ZW1wbGF0ZXMubmV4dEVsZW1lbnQoKTsKLQkgICAgaWYgKHRlbXBsYXRlLmhhc0NvbnRlbnRzKCkpIHsKLQkJLy8gISEhIFRPRE8gdGVtcGxhdGVzIGJvdGggbmFtZWQgYW5kIG1hdGNoZWQKLQkJSW5zdHJ1Y3Rpb25MaXN0IHRpbCA9IHRlbXBsYXRlLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCXRpbC5hcHBlbmQobmV3IEdPVE9fVyhuZXh0KSk7Ci0JCV90ZW1wbGF0ZUlMcy5wdXQodGVtcGxhdGUsIHRpbCk7Ci0JCV90ZW1wbGF0ZUlIcy5wdXQodGVtcGxhdGUsIHRpbC5nZXRTdGFydCgpKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJLy8gZW1wdHkgdGVtcGxhdGUKLQkJX3RlbXBsYXRlSUhzLnB1dCh0ZW1wbGF0ZSwgbmV4dCk7Ci0JICAgIH0KLQl9Ci0gICAgfQotCQotICAgIHByaXZhdGUgdm9pZCBhcHBlbmRUZW1wbGF0ZUNvZGUoSW5zdHJ1Y3Rpb25MaXN0IGJvZHkpIHsKLQlmaW5hbCBFbnVtZXJhdGlvbiB0ZW1wbGF0ZXMgPSBfbmVlZGVkVGVtcGxhdGVzLmtleXMoKTsKLQl3aGlsZSAodGVtcGxhdGVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIGZpbmFsIE9iamVjdCBpTGlzdCA9Ci0JCV90ZW1wbGF0ZUlMcy5nZXQodGVtcGxhdGVzLm5leHRFbGVtZW50KCkpOwotCSAgICBpZiAoaUxpc3QgIT0gbnVsbCkgewotCQlib2R5LmFwcGVuZCgoSW5zdHJ1Y3Rpb25MaXN0KWlMaXN0KTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYXBwZW5kVGVzdFNlcXVlbmNlcyhJbnN0cnVjdGlvbkxpc3QgYm9keSkgewotCWZpbmFsIGludCBuID0gX3Rlc3RTZXEubGVuZ3RoOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JICAgIGZpbmFsIFRlc3RTZXEgdGVzdFNlcSA9IF90ZXN0U2VxW2ldOwotCSAgICBpZiAodGVzdFNlcSAhPSBudWxsKSB7Ci0JCUluc3RydWN0aW9uTGlzdCBpbCA9IHRlc3RTZXEuZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JCWlmIChpbCAhPSBudWxsKQotCQkgICAgYm9keS5hcHBlbmQoaWwpOwotCQkvLyBlbHNlIHRyaXZpYWwgVGVzdFNlcQotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjb21waWxlR2V0Q2hpbGRyZW4oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJCSAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLQkJCQkJICBpbnQgbm9kZSkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgaW50IGdpdCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgIEdFVF9DSElMRFJFTiwKLQkJCQkJCSAgR0VUX0NISUxEUkVOX1NJRyk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCWlsLmFwcGVuZChuZXcgSUxPQUQobm9kZSkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdCwgMikpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIHRoZSBkZWZhdWx0IGhhbmRsaW5nIGZvciBET00gZWxlbWVudHM6IHRyYXZlcnNlIGFsbCBjaGlsZHJlbgotICAgICAqLwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb25MaXN0IGNvbXBpbGVEZWZhdWx0UmVjdXJzaW9uKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCQkJICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0JCQkJCQkgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dCkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgU3RyaW5nIGFwcGx5VGVtcGxhdGVzU2lnID0gY2xhc3NHZW4uZ2V0QXBwbHlUZW1wbGF0ZXNTaWcoKTsKLQlmaW5hbCBpbnQgZ2l0ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgR0VUX0NISUxEUkVOLAotCQkJCQkJICBHRVRfQ0hJTERSRU5fU0lHKTsKLQlmaW5hbCBpbnQgYXBwbHlUZW1wbGF0ZXMgPSBjcGcuYWRkTWV0aG9kcmVmKGdldENsYXNzTmFtZSgpLAotCQkJCQkJICAgIGZ1bmN0aW9uTmFtZSgpLAotCQkJCQkJICAgIGFwcGx5VGVtcGxhdGVzU2lnKTsKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTE9BRChfY3VycmVudEluZGV4KSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2l0LCAyKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoYXBwbHlUZW1wbGF0ZXMpKTsKLQlpbC5hcHBlbmQobmV3IEdPVE9fVyhuZXh0KSk7Ci0JcmV0dXJuIGlsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIHRoZSBkZWZhdWx0IGFjdGlvbiBmb3IgRE9NIHRleHQgbm9kZXMgYW5kIGF0dHJpYnV0ZSBub2RlczoKLSAgICAgKiBvdXRwdXQgdGhlIG5vZGUncyB0ZXh0IHZhbHVlCi0gICAgICovCi0gICAgcHJpdmF0ZSBJbnN0cnVjdGlvbkxpc3QgY29tcGlsZURlZmF1bHRUZXh0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLQkJCQkJICAgICAgIEluc3RydWN0aW9uSGFuZGxlIG5leHQpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCi0JZmluYWwgaW50IGNoYXJzID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgICBDSEFSQUNURVJTLAotCQkJCQkJICAgIENIQVJBQ1RFUlNfU0lHKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTE9BRChfY3VycmVudEluZGV4KSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShjaGFycywgMykpOwotCWlsLmFwcGVuZChuZXcgR09UT19XKG5leHQpKTsKLQlyZXR1cm4gaWw7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBJbnN0cnVjdGlvbkxpc3QgY29tcGlsZU5hbWVzcGFjZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJCSAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0JCQkJCSAgICAgIGJvb2xlYW5bXSBpc05hbWVzcGFjZSwKLQkJCQkJICAgICAgYm9vbGVhbltdIGlzQXR0cmlidXRlLAotCQkJCQkgICAgICBib29sZWFuIGF0dHJGbGFnLAotCQkJCQkgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBkZWZhdWx0VGFyZ2V0KSB7Ci0JZmluYWwgWFNMVEMgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQotCS8vIEFwcGVuZCBzd2l0Y2goKSBzdGF0ZW1lbnQgLSBuYW1lc3BhY2UgdGVzdCBkaXNwYXRjaCBsb29wCi0JZmluYWwgVmVjdG9yIG5hbWVzcGFjZXMgPSB4c2x0Yy5nZXROYW1lc3BhY2VJbmRleCgpOwotCWZpbmFsIFZlY3RvciBuYW1lcyA9IHhzbHRjLmdldE5hbWVzSW5kZXgoKTsKLQlmaW5hbCBpbnQgbmFtZXNwYWNlQ291bnQgPSBuYW1lc3BhY2VzLnNpemUoKSArIDE7Ci0JZmluYWwgaW50IG5hbWVzQ291bnQgPSBuYW1lcy5zaXplKCk7Ci0KLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgaW50W10gdHlwZXMgPSBuZXcgaW50W25hbWVzcGFjZUNvdW50XTsKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbdHlwZXMubGVuZ3RoXTsKLQotCWlmIChuYW1lc3BhY2VDb3VudCA+IDApIHsKLQkgICAgYm9vbGVhbiBjb21waWxlZCA9IGZhbHNlOwotCi0JICAgIC8vIEluaXRpYWxpemUgdGFyZ2V0cyBmb3IgbmFtZXNwYWNlKCkgc3dpdGNoIHN0YXRlbWVudAotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzcGFjZUNvdW50OyBpKyspIHsKLQkJdGFyZ2V0c1tpXSA9IGRlZmF1bHRUYXJnZXQ7Ci0JCXR5cGVzW2ldID0gaTsKLQkgICAgfQotCi0JICAgIC8vIEFkZCB0ZXN0IHNlcXVlbmNlcyBmb3Iga25vd24gbmFtZXNwYWNlIHR5cGVzCi0JICAgIGZvciAoaW50IGkgPSBET00uTlRZUEVTOyBpIDwgKERPTS5OVFlQRVMrbmFtZXNDb3VudCk7IGkrKykgewotCQlpZiAoKGlzTmFtZXNwYWNlW2ldKSAmJiAoaXNBdHRyaWJ1dGVbaV0gPT0gYXR0ckZsYWcpKSB7Ci0JCSAgICBTdHJpbmcgbmFtZSA9IChTdHJpbmcpbmFtZXMuZWxlbWVudEF0KGktRE9NLk5UWVBFUyk7Ci0JCSAgICBTdHJpbmcgbmFtZXNwYWNlID0gbmFtZS5zdWJzdHJpbmcoMCxuYW1lLmxhc3RJbmRleE9mKCc6JykpOwotCQkgICAgZmluYWwgaW50IHR5cGUgPSB4c2x0Yy5yZWdpc3Rlck5hbWVzcGFjZShuYW1lc3BhY2UpOwotCQkgICAgCi0JCSAgICBpZiAoKGkgPCBfdGVzdFNlcS5sZW5ndGgpICYmCi0JCQkoX3Rlc3RTZXFbaV0gIT0gbnVsbCkpIHsKLQkJCXRhcmdldHNbdHlwZV0gPQotCQkJICAgIChfdGVzdFNlcVtpXSkuY29tcGlsZShjbGFzc0dlbiwKLQkJCQkJCSAgICAgICBtZXRob2RHZW4sCi0JCQkJCQkgICAgICAgZGVmYXVsdFRhcmdldCk7Ci0JCQljb21waWxlZCA9IHRydWU7Ci0JCSAgICB9Ci0JCX0KLQkgICAgfQotCi0JICAgIC8vIFJldHVybiAibnVsbCIgaWYgbm8gdGVzdCBzZXF1ZW5jZXMgd2VyZSBjb21waWxlZAotCSAgICBpZiAoIWNvbXBpbGVkKSByZXR1cm4obnVsbCk7Ci0JCQotCSAgICAvLyBBcHBlbmQgZmlyc3QgY29kZSBpbiBhcHBseVRlbXBsYXRlcygpIC0gZ2V0IHR5cGUgb2YgY3VycmVudCBub2RlCi0JICAgIGZpbmFsIGludCBnZXROUyA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkJImdldE5hbWVzcGFjZVR5cGUiLAotCQkJCQkJCSIoSSlJIik7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChfY3VycmVudEluZGV4KSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldE5TLCAyKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgU1dJVENIKHR5cGVzLCB0YXJnZXRzLCBkZWZhdWx0VGFyZ2V0KSk7Ci0JICAgIHJldHVybihpbCk7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4obnVsbCk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEF1eGlsbGFyeSBtZXRob2QgdG8gZGV0ZXJtaW5lIGlmIGEgcW5hbWUgZGVzY3JpYmVzIGFuIGF0dHJpYnV0ZS9lbGVtZW50Ci0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0F0dHJpYnV0ZU5hbWUoU3RyaW5nIHFuYW1lKSB7Ci0JZmluYWwgaW50IGNvbCA9IHFuYW1lLmluZGV4T2YoJzonKSArIDE7Ci0JaWYgKHFuYW1lLmNoYXJBdChjb2wpID09ICdAJykKLQkgICAgcmV0dXJuKHRydWUpOwotCWVsc2UKLQkgICAgcmV0dXJuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTmFtZXNwYWNlTmFtZShTdHJpbmcgcW5hbWUpIHsKLQlmaW5hbCBpbnQgY29sID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLQlpZiAoKGNvbCA+IC0xKSAmJiAocW5hbWUuY2hhckF0KHFuYW1lLmxlbmd0aCgpLTEpID09ICcqJykpCi0JICAgIHJldHVybih0cnVlKTsKLQllbHNlCi0JICAgIHJldHVybihmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgdGhlIGFwcGx5VGVtcGxhdGVzKCkgbWV0aG9kIGFuZCBhZGRzIGl0IHRvIHRoZSB0cmFuc2xldC4KLSAgICAgKiBUaGlzIGlzIHRoZSBtYWluIGRpc3BhdGNoIG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21waWxlQXBwbHlUZW1wbGF0ZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLQlmaW5hbCBYU0xUQyB4c2x0YyA9IGNsYXNzR2VuLmdldFBhcnNlcigpLmdldFhTTFRDKCk7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIFZlY3RvciBuYW1lcyAgICAgID0geHNsdGMuZ2V0TmFtZXNJbmRleCgpOwotCi0JLy8gKCopIENyZWF0ZSB0aGUgYXBwbHlUZW1wbGF0ZXMoKSBtZXRob2QKLQlmaW5hbCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlW10gYXJnVHlwZXMgPQotCSAgICBuZXcgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVszXTsKLQlhcmdUeXBlc1swXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyk7Ci0JYXJnVHlwZXNbMV0gPSBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRyk7Ci0JYXJnVHlwZXNbMl0gPSBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9PVVRQVVRfU0lHKTsKLQotCWZpbmFsIFN0cmluZ1tdIGFyZ05hbWVzID0gbmV3IFN0cmluZ1szXTsKLQlhcmdOYW1lc1swXSA9IERPQ1VNRU5UX1BOQU1FOwotCWFyZ05hbWVzWzFdID0gSVRFUkFUT1JfUE5BTUU7Ci0JYXJnTmFtZXNbMl0gPSBUUkFOU0xFVF9PVVRQVVRfUE5BTUU7Ci0KLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgbWFpbklMID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4gPQotCSAgICBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMgfCBBQ0NfRklOQUwsIAotCQkJCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuVk9JRCwKLQkJCQlhcmdUeXBlcywgYXJnTmFtZXMsIGZ1bmN0aW9uTmFtZSgpLAotCQkJCWdldENsYXNzTmFtZSgpLCBtYWluSUwsCi0JCQkJY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCkpOwotCW1ldGhvZEdlbi5hZGRFeGNlcHRpb24oIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRFeGNlcHRpb24iKTsKLQotCS8vICgqKSBDcmVhdGUgdGhlIGxvY2FsIHZhcmlhYmxlYQotCWZpbmFsIExvY2FsVmFyaWFibGVHZW4gY3VycmVudDsKLQljdXJyZW50ID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKCJjdXJyZW50IiwKLQkJCQkJICAgICAgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQsCi0JCQkJCSAgICAgIG1haW5JTC5nZXRFbmQoKSk7Ci0JX2N1cnJlbnRJbmRleCA9IGN1cnJlbnQuZ2V0SW5kZXgoKTsKLQotCS8vICgqKSBDcmVhdGUgdGhlICJib2R5IiBpbnN0cnVjdGlvbiBsaXN0IHRoYXQgd2lsbCBldmVudHVhbGx5IGhvbGQgdGhlCi0JLy8gICAgIGNvZGUgZm9yIHRoZSBlbnRpcmUgbWV0aG9kIChvdGhlciBJTHMgd2lsbCBiZSBhcHBlbmRlZCkuCi0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGJvZHkgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JYm9keS5hcHBlbmQoTk9QKTsKLQotCS8vICgqKSBDcmVhdGUgYW4gaW5zdHJ1Y3Rpb24gbGlzdCB0aGF0IGNvbnRhaW5zIHRoZSBkZWZhdWx0IG5leHQtbm9kZQotCS8vICAgICBpdGVyYXRpb24KLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWxMb29wID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCWlsTG9vcC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQlpbExvb3AuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLQlpbExvb3AuYXBwZW5kKERVUCk7Ci0JaWxMb29wLmFwcGVuZChuZXcgSVNUT1JFKF9jdXJyZW50SW5kZXgpKTsKLQotCS8vIFRoZSBib2R5IG9mIHRoaXMgY29kZSBjYW4gZ2V0IHZlcnkgbGFyZ2UgLSBsYXJnZSB0aGFuIGNhbiBiZSBoYW5kbGVkCi0JLy8gYnkgYSBzaW5nbGUgSUZORShib2R5LmdldFN0YXJ0KCkpIGluc3RydWN0aW9uIC0gbmVlZCB3b3JrYXJvdW5kOgotICAgICAgICBmaW5hbCBCcmFuY2hIYW5kbGUgaWZlcSA9IGlsTG9vcC5hcHBlbmQobmV3IElGRVEobnVsbCkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBsb29wID0gaWxMb29wLmFwcGVuZChuZXcgR09UT19XKG51bGwpKTsKLQlpZmVxLnNldFRhcmdldChpbExvb3AuYXBwZW5kKFJFVFVSTikpOyAvLyBhcHBseVRlbXBsYXRlcygpIGVuZHMgaGVyZSEKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBpaExvb3AgPSBpbExvb3AuZ2V0U3RhcnQoKTsKLQotCS8vICgqKSBDb21waWxlIGRlZmF1bHQgaGFuZGxpbmcgb2YgZWxlbWVudHMgKHRyYXZlcnNlIGNoaWxkcmVuKQotCUluc3RydWN0aW9uTGlzdCBpbFJlY3Vyc2UgPQotCSAgICBjb21waWxlRGVmYXVsdFJlY3Vyc2lvbihjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaExvb3ApOwotCUluc3RydWN0aW9uSGFuZGxlIGloUmVjdXJzZSA9IGlsUmVjdXJzZS5nZXRTdGFydCgpOwotCi0JLy8gKCopIENvbXBpbGUgZGVmYXVsdCBoYW5kbGluZyBvZiB0ZXh0L2F0dHJpYnV0ZSBub2RlcyAob3V0cHV0IHRleHQpCi0JSW5zdHJ1Y3Rpb25MaXN0IGlsVGV4dCA9Ci0JICAgIGNvbXBpbGVEZWZhdWx0VGV4dChjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaExvb3ApOwotCUluc3RydWN0aW9uSGFuZGxlIGloVGV4dCA9IGlsVGV4dC5nZXRTdGFydCgpOwotCi0JLy8gRGlzdGluZ3Vpc2ggYXR0cmlidXRlL2VsZW1lbnQvbmFtZXNwYWNlIHRlc3RzIGZvciBmdXJ0aGVyIHByb2Nlc3NpbmcKLQlmaW5hbCBpbnRbXSB0eXBlcyA9IG5ldyBpbnRbRE9NLk5UWVBFUyArIG5hbWVzLnNpemUoKV07Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgdHlwZXNbaV0gPSBpOwotCi0JZmluYWwgYm9vbGVhbltdIGlzQXR0cmlidXRlID0gbmV3IGJvb2xlYW5bdHlwZXMubGVuZ3RoXTsKLQlmaW5hbCBib29sZWFuW10gaXNOYW1lc3BhY2UgPSBuZXcgYm9vbGVhblt0eXBlcy5sZW5ndGhdOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbmFtZXMuc2l6ZSgpOyBpKyspIHsKLQkgICAgZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLmVsZW1lbnRBdChpKTsKLQkgICAgaXNBdHRyaWJ1dGVbaStET00uTlRZUEVTXSA9IGlzQXR0cmlidXRlTmFtZShuYW1lKTsKLQkgICAgaXNOYW1lc3BhY2VbaStET00uTlRZUEVTXSA9IGlzTmFtZXNwYWNlTmFtZShuYW1lKTsKLQl9Ci0KLQkvLyAoKikgQ29tcGlsZSBhbGwgdGVtcGxhdGVzIC0gcmVnYXJkbGVzcyBvZiBwYXR0ZXJuIHR5cGUKLQljb21waWxlVGVtcGxhdGVzKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0KLQkvLyAoKikgSGFuZGxlIHRlbXBsYXRlIHdpdGggZXhwbGljaXQgIioiIHBhdHRlcm4KLQlmaW5hbCBUZXN0U2VxIGVsZW1UZXN0ID0gX3Rlc3RTZXFbRE9NLkVMRU1FTlRdOwotCUluc3RydWN0aW9uSGFuZGxlIGloRWxlbSA9IGloUmVjdXJzZTsKLQlpZiAoZWxlbVRlc3QgIT0gbnVsbCkKLQkgICAgaWhFbGVtID0gZWxlbVRlc3QuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaFJlY3Vyc2UpOwotCi0JLy8gKCopIEhhbmRsZSB0ZW1wbGF0ZSB3aXRoIGV4cGxpY2l0ICJAKiIgcGF0dGVybgotCWZpbmFsIFRlc3RTZXEgYXR0clRlc3QgPSBfdGVzdFNlcVtET00uQVRUUklCVVRFXTsKLQlJbnN0cnVjdGlvbkhhbmRsZSBpaEF0dHIgPSBpaFRleHQ7Ci0JaWYgKGF0dHJUZXN0ICE9IG51bGwpCi0JICAgIGloQXR0ciA9IGF0dHJUZXN0LmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhUZXh0KTsKLQotCS8vIERvIHRlc3RzIGZvciBpZCgpIGFuZCBrZXkoKSBwYXR0ZXJucyBmaXJzdAotCUluc3RydWN0aW9uTGlzdCBpbEtleSA9IG51bGw7Ci0JaWYgKF9pZHhUZXN0U2VxICE9IG51bGwpIHsKLQkgICAgbG9vcC5zZXRUYXJnZXQoX2lkeFRlc3RTZXEuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLCBib2R5LmdldFN0YXJ0KCkpKTsKLQkgICAgaWxLZXkgPSBfaWR4VGVzdFNlcS5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGxvb3Auc2V0VGFyZ2V0KGJvZHkuZ2V0U3RhcnQoKSk7Ci0JfQotCi0JLy8gKCopIElmIHRoZXJlIGlzIGEgbWF0Y2ggb24gbm9kZSgpIHdlIG5lZWQgdG8gcmVwbGFjZSBpaEVsZW0KLQkvLyAgICAgYW5kIGloVGV4dCAoZGVmYXVsdCBiZWhhdmlvdXIgZm9yIGVsZW1lbnRzICYgdGV4dCkuCi0JaWYgKF9ub2RlVGVzdFNlcSAhPSBudWxsKSB7Ci0JICAgIGRvdWJsZSBub2RlUHJpbyA9IC0wLjU7IC8vX25vZGVUZXN0U2VxLmdldFByaW9yaXR5KCk7Ci0JICAgIGludCAgICBub2RlUG9zICA9IF9ub2RlVGVzdFNlcS5nZXRQb3NpdGlvbigpOwotCSAgICBkb3VibGUgZWxlbVByaW8gPSAoMCAtIERvdWJsZS5NQVhfVkFMVUUpOwotCSAgICBpbnQgICAgZWxlbVBvcyAgPSBJbnRlZ2VyLk1JTl9WQUxVRTsKLQkgICAgaWYgKGVsZW1UZXN0ICE9IG51bGwpIHsKLQkJZWxlbVByaW8gPSBlbGVtVGVzdC5nZXRQcmlvcml0eSgpOwotCQllbGVtUG9zICA9IGVsZW1UZXN0LmdldFBvc2l0aW9uKCk7Ci0JICAgIH0KLQkgICAgaWYgKChlbGVtUHJpbyA9PSBEb3VibGUuTmFOKSB8fCAoZWxlbVByaW8gPCBub2RlUHJpbykgfHwKLQkJKChlbGVtUHJpbyA9PSBub2RlUHJpbykgJiYgKGVsZW1Qb3MgPCBub2RlUG9zKSkpIHsKLQkJaWhFbGVtID0gX25vZGVUZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhMb29wKTsKLQkJaWhUZXh0ID0gaWhFbGVtOwotCSAgICB9Ci0JfQotCi0JLy8gKCopIEhhbmRsZSB0ZW1wbGF0ZXMgd2l0aCAibnM6KiIgcGF0dGVybgotCUluc3RydWN0aW9uSGFuZGxlIGVsZW1OYW1lc3BhY2VIYW5kbGUgPSBpaEVsZW07Ci0JSW5zdHJ1Y3Rpb25MaXN0IG5zRWxlbSA9IGNvbXBpbGVOYW1lc3BhY2VzKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgICBpc05hbWVzcGFjZSwgaXNBdHRyaWJ1dGUsCi0JCQkJCQkgICBmYWxzZSwgaWhFbGVtKTsKLQlpZiAobnNFbGVtICE9IG51bGwpIGVsZW1OYW1lc3BhY2VIYW5kbGUgPSBuc0VsZW0uZ2V0U3RhcnQoKTsKLQotCS8vICgqKSBIYW5kbGUgdGVtcGxhdGVzIHdpdGggIm5zOkAqIiBwYXR0ZXJuCi0JSW5zdHJ1Y3Rpb25MaXN0IG5zQXR0ciA9IGNvbXBpbGVOYW1lc3BhY2VzKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgICBpc05hbWVzcGFjZSwgaXNBdHRyaWJ1dGUsCi0JCQkJCQkgICB0cnVlLCBpaEF0dHIpOwotCUluc3RydWN0aW9uSGFuZGxlIGF0dHJOYW1lc3BhY2VIYW5kbGUgPSBpaEF0dHI7Ci0JaWYgKG5zQXR0ciAhPSBudWxsKSBhdHRyTmFtZXNwYWNlSGFuZGxlID0gbnNBdHRyLmdldFN0YXJ0KCk7Ci0KLQkvLyAoKikgSGFuZGxlIHRlbXBsYXRlcyB3aXRoICJuczplbGVtIiBvciAibnM6QGF0dHIiIHBhdHRlcm4KLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbdHlwZXMubGVuZ3RoXTsKLQlmb3IgKGludCBpID0gRE9NLk5UWVBFUzsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHsKLQkgICAgZmluYWwgVGVzdFNlcSB0ZXN0U2VxID0gX3Rlc3RTZXFbaV07Ci0JICAgIC8vIEp1bXAgc3RyYWlnaHQgdG8gbmFtZXNwYWNlIHRlc3RzID8KLQkgICAgaWYgKGlzTmFtZXNwYWNlW2ldKSB7Ci0JCWlmIChpc0F0dHJpYnV0ZVtpXSkKLQkJICAgIHRhcmdldHNbaV0gPSBhdHRyTmFtZXNwYWNlSGFuZGxlOwotCQllbHNlCi0JCSAgICB0YXJnZXRzW2ldID0gZWxlbU5hbWVzcGFjZUhhbmRsZTsKLQkgICAgfQotCSAgICAvLyBUZXN0IGZpcnN0LCB0aGVuIGp1bXAgdG8gbmFtZXNwYWNlIHRlc3RzCi0JICAgIGVsc2UgaWYgKHRlc3RTZXEgIT0gbnVsbCkgewotCQlpZiAoaXNBdHRyaWJ1dGVbaV0pCi0JCSAgICB0YXJnZXRzW2ldID0gdGVzdFNlcS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgYXR0ck5hbWVzcGFjZUhhbmRsZSk7Ci0JCWVsc2UKLQkJICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkJCSBlbGVtTmFtZXNwYWNlSGFuZGxlKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJdGFyZ2V0c1tpXSA9IGloTG9vcDsKLQkgICAgfQotCX0KLQotCS8vIEhhbmRsZSBwYXR0ZXJuIHdpdGggbWF0Y2ggb24gcm9vdCBub2RlIC0gZGVmYXVsdDogdHJhdmVyc2UgY2hpbGRyZW4KLQl0YXJnZXRzW0RPTS5ST09UXSA9IF9yb290UGF0dGVybiAhPSBudWxsCi0JICAgID8gZ2V0VGVtcGxhdGVJbnN0cnVjdGlvbkhhbmRsZShfcm9vdFBhdHRlcm4uZ2V0VGVtcGxhdGUoKSkKLQkgICAgOiBpaFJlY3Vyc2U7Ci0JCi0JLy8gSGFuZGxlIGFueSBwYXR0ZXJuIHdpdGggbWF0Y2ggb24gdGV4dCBub2RlcyAtIGRlZmF1bHQ6IG91dHB1dCB0ZXh0Ci0JdGFyZ2V0c1tET00uVEVYVF0gPSBfdGVzdFNlcVtET00uVEVYVF0gIT0gbnVsbAotCSAgICA/IF90ZXN0U2VxW0RPTS5URVhUXS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloVGV4dCkKLQkgICAgOiBpaFRleHQ7Ci0KLQkvLyBUaGlzIERPTS10eXBlIGlzIG5vdCBpbiB1c2UgLSBkZWZhdWx0OiBwcm9jZXNzIG5leHQgbm9kZQotCXRhcmdldHNbRE9NLlVOVVNFRF0gPSBpaExvb3A7Ci0KLQkvLyBNYXRjaCB1bmtub3duIGVsZW1lbnQgaW4gRE9NIC0gZGVmYXVsdDogY2hlY2sgZm9yIG5hbWVzcGFjZSBtYXRjaAotCXRhcmdldHNbRE9NLkVMRU1FTlRdID0gZWxlbU5hbWVzcGFjZUhhbmRsZTsKLQotCS8vIE1hdGNoIHVua25vd24gYXR0cmlidXRlIGluIERPTSAtIGRlZmF1bHQ6IGNoZWNrIGZvciBuYW1lc3BhY2UgbWF0Y2gKLQl0YXJnZXRzW0RPTS5BVFRSSUJVVEVdID0gYXR0ck5hbWVzcGFjZUhhbmRsZTsKLQotCS8vIE1hdGNoIG9uIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gLSBkZWZhdWx0OiBwcm9jZXNzIG5leHQgbm9kZQotCXRhcmdldHNbRE9NLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05dID0KLQkgICAgX3Rlc3RTZXFbRE9NLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05dICE9IG51bGwKLQkgICAgPyBfdGVzdFNlcVtET00uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl0KLQkgICAgLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhMb29wKQotCSAgICA6IGloTG9vcDsKLQkKLQkvLyBNYXRjaCBvbiBjb21tZW50cyAtIGRlZmF1bHQ6IHByb2Nlc3MgbmV4dCBub2RlCi0JdGFyZ2V0c1tET00uQ09NTUVOVF0gPSBfdGVzdFNlcVtET00uQ09NTUVOVF0gIT0gbnVsbAotCSAgICA/IF90ZXN0U2VxW0RPTS5DT01NRU5UXS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCkKLQkgICAgOiBpaExvb3A7Ci0KLQkvLyBOb3cgY29tcGlsZSB0ZXN0IHNlcXVlbmNlcyBmb3IgdmFyaW91cyBtYXRjaCBwYXR0ZXJuczoKLQlmb3IgKGludCBpID0gRE9NLk5UWVBFUzsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHsKLQkgICAgZmluYWwgVGVzdFNlcSB0ZXN0U2VxID0gX3Rlc3RTZXFbaV07Ci0JICAgIC8vIEp1bXAgc3RyYWlnaHQgdG8gbmFtZXNwYWNlIHRlc3RzID8KLQkgICAgaWYgKCh0ZXN0U2VxID09IG51bGwpIHx8IChpc05hbWVzcGFjZVtpXSkpIHsKLQkJaWYgKGlzQXR0cmlidXRlW2ldKQotCQkgICAgdGFyZ2V0c1tpXSA9IGF0dHJOYW1lc3BhY2VIYW5kbGU7Ci0JCWVsc2UKLQkJICAgIHRhcmdldHNbaV0gPSBlbGVtTmFtZXNwYWNlSGFuZGxlOwotCSAgICB9Ci0JICAgIC8vIE1hdGNoIG9uIG5vZGUgdHlwZQotCSAgICBlbHNlIHsKLQkJaWYgKGlzQXR0cmlidXRlW2ldKQotCQkgICAgdGFyZ2V0c1tpXSA9IHRlc3RTZXEuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLAotCQkJCQkJIGF0dHJOYW1lc3BhY2VIYW5kbGUpOwotCQllbHNlCi0JCSAgICB0YXJnZXRzW2ldID0gdGVzdFNlcS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgZWxlbU5hbWVzcGFjZUhhbmRsZSk7Ci0JICAgIH0KLQl9Ci0KLQlpZiAoaWxLZXkgIT0gbnVsbCkgYm9keS5pbnNlcnQoaWxLZXkpOwotCi0JLy8gQXBwZW5kIGZpcnN0IGNvZGUgaW4gYXBwbHlUZW1wbGF0ZXMoKSAtIGdldCB0eXBlIG9mIGN1cnJlbnQgbm9kZQotCWZpbmFsIGludCBnZXRUeXBlID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgICAgICJnZXRUeXBlIiwgIihJKUkiKTsKLQlib2R5LmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlib2R5LmFwcGVuZChuZXcgSUxPQUQoX2N1cnJlbnRJbmRleCkpOwotCWJvZHkuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0VHlwZSwgMikpOwotCi0JLy8gQXBwZW5kIHN3aXRjaCgpIHN0YXRlbWVudCAtIG1haW4gZGlzcGF0Y2ggbG9vcCBpbiBhcHBseVRlbXBsYXRlcygpCi0JSW5zdHJ1Y3Rpb25IYW5kbGUgZGlzcCA9IGJvZHkuYXBwZW5kKG5ldyBTV0lUQ0godHlwZXMsIHRhcmdldHMsIGloTG9vcCkpOwotCi0JLy8gQXBwZW5kIGFsbCB0aGUgImNhc2U6IiBzdGF0ZW1lbnRzCi0JYXBwZW5kVGVzdFNlcXVlbmNlcyhib2R5KTsKLQkvLyBBcHBlbmQgdGhlIGFjdHVhbCB0ZW1wbGF0ZSBjb2RlCi0JYXBwZW5kVGVtcGxhdGVDb2RlKGJvZHkpOwotCi0JLy8gQXBwZW5kIE5TOiogbm9kZSB0ZXN0cyAoaWYgYW55KQotCWlmIChuc0VsZW0gIT0gbnVsbCkgYm9keS5hcHBlbmQobnNFbGVtKTsKLQkvLyBBcHBlbmQgTlM6QCogbm9kZSB0ZXN0cyAoaWYgYW55KQotCWlmIChuc0F0dHIgIT0gbnVsbCkgYm9keS5hcHBlbmQobnNBdHRyKTsKLQotCS8vIEFwcGVuZCBkZWZhdWx0IGFjdGlvbiBmb3IgZWxlbWVudCBhbmQgcm9vdCBub2RlcwotCWJvZHkuYXBwZW5kKGlsUmVjdXJzZSk7Ci0JLy8gQXBwZW5kIGRlZmF1bHQgYWN0aW9uIGZvciB0ZXh0IGFuZCBhdHRyaWJ1dGUgbm9kZXMKLQlib2R5LmFwcGVuZChpbFRleHQpOwotCi0JLy8gcHV0dGluZyB0b2dldGhlciBjb25zdGl0dWVudCBpbnN0cnVjdGlvbiBsaXN0cwotCW1haW5JTC5hcHBlbmQobmV3IEdPVE9fVyhpaExvb3ApKTsKLQltYWluSUwuYXBwZW5kKGJvZHkpOwotCS8vIGZhbGwgdGhyb3VnaCB0byBpbExvb3AKLQltYWluSUwuYXBwZW5kKGlsTG9vcCk7Ci0KLQlwZWVwSG9sZU9wdGltaXphdGlvbihtZXRob2RHZW4pOwotCW1ldGhvZEdlbi5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0JCi0JbWV0aG9kR2VuLnNldE1heExvY2FscygpOwotCW1ldGhvZEdlbi5zZXRNYXhTdGFjaygpOwotCW1ldGhvZEdlbi5yZW1vdmVOT1BzKCk7Ci0JY2xhc3NHZW4uYWRkTWV0aG9kKG1ldGhvZEdlbi5nZXRNZXRob2QoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGVlcGhvbGUgb3B0aW1pemF0aW9uOiBSZW1vdmUgc2VxdWVuY2VzIG9mIFtBTE9BRCwgUE9QXS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcGVlcEhvbGVPcHRpbWl6YXRpb24oTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlGaW5kUGF0dGVybiBmaW5kID0gbmV3IEZpbmRQYXR0ZXJuKGlsKTsKLQlJbnN0cnVjdGlvbkhhbmRsZSBpaDsKLQlTdHJpbmcgcGF0dGVybjsKLQotCS8vIFJlbW92ZSBzZXF1ZW5jZXMgb2YgQUxPQUQsIFBPUAotCXBhdHRlcm4gPSAiYEFMT0FEJ2BQT1AnYEluc3RydWN0aW9uJyI7Ci0JaWggPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsKLQl3aGlsZSAoaWggIT0gbnVsbCkgewotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gZmluZC5nZXRNYXRjaCgpOwotCSAgICB0cnkgewotCQlpZiAoKCFtYXRjaFswXS5oYXNUYXJnZXRlcnMoKSkgJiYgKCFtYXRjaFsxXS5oYXNUYXJnZXRlcnMoKSkpIHsKLQkJICAgIGlsLmRlbGV0ZShtYXRjaFswXSwgbWF0Y2hbMV0pOwotCQl9Ci0JICAgIH0KLQkgICAgY2F0Y2ggKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotCQkvLyBUT0RPOiBtb3ZlIHRhcmdldCBkb3duIGludG8gdGhlIGxpc3QKLQkgICAgfQotCSAgICBpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4sIG1hdGNoWzJdKTsKLQl9Ci0KLQkvLyBSZXBsYWNlIHNlcXVlbmNlcyBvZiBJTE9BRF8/LCBBTE9BRF8/LCBTV0FQIHdpdGggQUxPQURfPywgSUxPQURfPwotCXBhdHRlcm4gPSAiYElMT0FEX18nYEFMT0FEX18nYFNXQVAnYEluc3RydWN0aW9uJyI7Ci0JaWggPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsKLQl3aGlsZSAoaWggIT0gbnVsbCkgewotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gZmluZC5nZXRNYXRjaCgpOwotCSAgICB0cnkgewotCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBpbG9hZDsKLQkJZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuSW5zdHJ1Y3Rpb24gYWxvYWQ7Ci0JCWlmICgoIW1hdGNoWzBdLmhhc1RhcmdldGVycygpKSAmJgotCQkgICAgKCFtYXRjaFsxXS5oYXNUYXJnZXRlcnMoKSkgJiYKLQkJICAgICghbWF0Y2hbMl0uaGFzVGFyZ2V0ZXJzKCkpKSB7Ci0JCSAgICBpbG9hZCA9IG1hdGNoWzBdLmdldEluc3RydWN0aW9uKCk7Ci0JCSAgICBhbG9hZCA9IG1hdGNoWzFdLmdldEluc3RydWN0aW9uKCk7Ci0JCSAgICBpbC5pbnNlcnQobWF0Y2hbMF0sIGFsb2FkKTsKLQkJICAgIGlsLmluc2VydChtYXRjaFswXSwgaWxvYWQpOwotCQkgICAgaWwuZGVsZXRlKG1hdGNoWzBdLCBtYXRjaFsyXSk7Ci0JCX0KLQkgICAgfQotCSAgICBjYXRjaCAoVGFyZ2V0TG9zdEV4Y2VwdGlvbiBlKSB7Ci0JCS8vIFRPRE86IG1vdmUgdGFyZ2V0IGRvd24gaW50byB0aGUgbGlzdAotCSAgICB9Ci0JICAgIGloID0gZmluZC5zZWFyY2gocGF0dGVybiwgbWF0Y2hbM10pOwotCX0KLQotCS8vIFJlcGxhY2VzIHNlcXVlbmNlcyBvZiBBTE9BRF8xLCBBTE9BRF8xIHdpdGggQUxPQURfMSwgRFVQCi0JcGF0dGVybiA9ICJgQUxPQURfMSdgQUxPQURfMSdgSW5zdHJ1Y3Rpb24nIjsKLQlpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4pOwotCXdoaWxlIChpaCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSBmaW5kLmdldE1hdGNoKCk7Ci0JICAgIHRyeSB7Ci0JCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLkluc3RydWN0aW9uIGlsb2FkOwotCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBhbG9hZDsKLQkJaWYgKCghbWF0Y2hbMF0uaGFzVGFyZ2V0ZXJzKCkpICYmICghbWF0Y2hbMV0uaGFzVGFyZ2V0ZXJzKCkpKSB7Ci0JCSAgICBpbC5pbnNlcnQobWF0Y2hbMV0sIG5ldyBEVVAoKSk7Ci0JCSAgICBpbC5kZWxldGUobWF0Y2hbMV0pOwotCQl9Ci0JICAgIH0KLQkgICAgY2F0Y2ggKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotCQkvLyBUT0RPOiBtb3ZlIHRhcmdldCBkb3duIGludG8gdGhlIGxpc3QKLQkgICAgfQotCSAgICBpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4sIG1hdGNoWzJdKTsKLQl9Ci0KLQkvLyBSZW1vdmVzIHVuY2Vzc2VjYXJ5IEdPVE9zCi0JLyoKLQlwYXR0ZXJuID0gImBHT1RPJ2BHT1RPJ2BJbnN0cnVjdGlvbiciOwotCWloID0gZmluZC5zZWFyY2gocGF0dGVybik7Ci0Jd2hpbGUgKGloICE9IG51bGwpIHsKLQkgICAgZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGVbXSBtYXRjaCA9IGZpbmQuZ2V0TWF0Y2goKTsKLQkgICAgdHJ5IHsKLQkJZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuSW5zdHJ1Y3Rpb24gaWxvYWQ7Ci0JCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLkluc3RydWN0aW9uIGFsb2FkOwotCQlJbnN0cnVjdGlvblRhcmdldGVyIHRndHJzW10gPSBtYXRjaFsxXS5nZXRUYXJnZXRlcnMoKTsKLQkJaWYgKHRndHJzICE9IG51bGwpIHsKLQkJICAgIEluc3RydWN0aW9uSGFuZGxlIG5ld1RhcmdldCA9Ci0JCQkoKEJyYW5jaEhhbmRsZSltYXRjaFsxXSkuZ2V0VGFyZ2V0KCk7Ci0JCSAgICBmb3IgKGludCBpPTA7IGk8dGd0cnMubGVuZ3RoOyBpKyspCi0JCQl0Z3Ryc1tpXS51cGRhdGVUYXJnZXQobWF0Y2hbMV0sbmV3VGFyZ2V0KTsKLQkJfQotCQlpbC5kZWxldGUobWF0Y2hbMV0pOwotCSAgICB9Ci0JICAgIGNhdGNoIChUYXJnZXRMb3N0RXhjZXB0aW9uIGUpIHsKLQkJLy8gVE9ETzogbW92ZSB0YXJnZXQgZG93biBpbnRvIHRoZSBsaXN0Ci0JICAgIH0KLQkgICAgaWggPSBmaW5kLnNlYXJjaChwYXR0ZXJuLCBtYXRjaFsyXSk7Ci0JfQotCSovCi0JCi0JCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uSGFuZGxlIGdldFRlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGUoVGVtcGxhdGUgdGVtcGxhdGUpIHsKLQlyZXR1cm4gKEluc3RydWN0aW9uSGFuZGxlKV90ZW1wbGF0ZUlIcy5nZXQodGVtcGxhdGUpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL01vZGUuamF2YS5vbGQgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Nb2RlLmphdmEub2xkCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNjgyYWMxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL01vZGUuamF2YS5vbGQKKysrIC9kZXYvbnVsbApAQCAtMSw3OTIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogQ29weXJpZ2h0IDIwMDAtMjAwMSBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiAKLSAqIFRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uIG9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gIAotICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcy4KLSAqIAotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2UgY29tLnN1bi54c2x0LmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBjb20uc3VuLnhzbHQuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgY29tLnN1bi54c2x0LmNvbXBpbGVyLnV0aWwuKjsKLWltcG9ydCBjb20uc3VuLnhzbHQuRE9NOwotCi0vKioKLSAqIE1vZGUgZ2F0aGVycyBhbGwgdGhlIHRlbXBsYXRlcyBiZWxvbmdpbmcgdG8gYSBnaXZlbiBtb2RlOyBpdCBpcyByZXNwb25zaWJsZQotICogZm9yIGdlbmVyYXRpbmcgYW4gYXBwcm9wcmlhdGUgYXBwbHlUZW1wbGF0ZXMgKyAobW9kZSBuYW1lKSBmdW5jdGlvbgotICovCi1maW5hbCBjbGFzcyBNb2RlIGltcGxlbWVudHMgQ29uc3RhbnRzIHsKLSAgICBwcml2YXRlIGZpbmFsIFFOYW1lIF9uYW1lOwotICAgIAotICAgIC8vIHRoZSBvd25pbmcgc3R5bGVzaGVldAotICAgIHByaXZhdGUgZmluYWwgU3R5bGVzaGVldCBfc3R5bGVzaGVldDsKLQotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9mdW5jdGlvbk5hbWU7Ci0gICAgCi0gICAgLy8gYWxsIHRoZSB0ZW1wbGF0ZXMgaW4gdGhpcyBtb2RlCi0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgX3RlbXBsYXRlcyA9IG5ldyBWZWN0b3IoKTsKLSAgICAKLSAgICAvLyBQYXR0ZXJucy90ZXN0IHNlcXVlbmNlcyBmb3IgdGhlIHN0eWxlc2hlZXQncyB0ZW1wbGF0ZXMKLSAgICBwcml2YXRlIFZlY3RvcltdICBfcGF0dGVybkdyb3VwcyA9IG5ldyBWZWN0b3JbMzJdOwotICAgIHByaXZhdGUgVGVzdFNlcVtdIF9jb2RlMlRlc3RTZXE7Ci0gICAgLy8gUGF0dGVybi90ZXN0IHNlcXVlbmNlIGZvciBwYXR0ZXJuIHdpdGggJ25vZGUoKScga2VybmVsCi0gICAgcHJpdmF0ZSBWZWN0b3IgICAgX25vZGVHcm91cCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBUZXN0U2VxICAgX25vZGVUZXN0U2VxID0gbnVsbDsKLQotICAgIHByaXZhdGUgaW50IF9jdXJyZW50SW5kZXg7Ci0KLSAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZSBfbmVlZGVkVGVtcGxhdGVzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF9uYW1lZFRlbXBsYXRlcyA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZSBfdGVtcGxhdGVJbnN0cnVjdGlvbkhhbmRsZXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgX3RlbXBsYXRlSW5zdHJ1Y3Rpb25MaXN0cyA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIExvY2F0aW9uUGF0aFBhdHRlcm4gX2V4cGxpY2l0Um9vdFBhdHRlcm4gPSBudWxsOwotCQotICAgIHB1YmxpYyBNb2RlKFFOYW1lIG5hbWUsIFN0eWxlc2hlZXQgc3R5bGVzaGVldCwgU3RyaW5nIHN1ZmZpeCkgewotCV9uYW1lID0gbmFtZTsKLQlfc3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0JX2Z1bmN0aW9uTmFtZSA9IEFQUExZX1RFTVBMQVRFUyArIHN1ZmZpeDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGZ1bmN0aW9uTmFtZSgpIHsKLQlyZXR1cm4gX2Z1bmN0aW9uTmFtZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0JcmV0dXJuIF9zdHlsZXNoZWV0LmdldENsYXNzTmFtZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZFRlbXBsYXRlKFRlbXBsYXRlIHRlbXBsYXRlKSB7Ci0JX3RlbXBsYXRlcy5hZGRFbGVtZW50KHRlbXBsYXRlKTsKLQlVdGlsLnByaW50bG4oImFkZGVkIHRlbXBsYXRlLCBwYXR0ZXJuOiAiKyB0ZW1wbGF0ZS5nZXRQYXR0ZXJuKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NQYXR0ZXJucyhIYXNodGFibGUga2V5cykgewotU3lzdGVtLm91dC5wcmludGxuKCJHVE0+IElOIE1PREU6IHByb2Nlc3NQYXR0ZXJucyhIYXNodGFibGUga2V5cykiKTsKLQkvLyBUcmF2ZXJzZSBhbGwgdGVtcGxhdGVzCi0JZmluYWwgRW51bWVyYXRpb24gdGVtcGxhdGVzID0gX3RlbXBsYXRlcy5lbGVtZW50cygpOwotCXdoaWxlICh0ZW1wbGF0ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSAoVGVtcGxhdGUpdGVtcGxhdGVzLm5leHRFbGVtZW50KCk7Ci0JICAgIC8vIElzIHRoaXMgYSBuYW1lZCB0ZW1wbGF0ZT8KLQkgICAgaWYgKHRlbXBsYXRlLmlzTmFtZWQoKSkgewotCQkvLyBPbmx5IHByb2Nlc3MgdGVtcGxhdGUgd2l0aCBoaWdoZXN0IHByaW9yaXR5IHdoZW4gdGhlcmUKLQkJLy8gYXJlIG11bHRpcGxlIHRlbXBsYXRlcyB3aXRoIHRoZSBzYW5tZSBuYW1lCi0JCWlmICghdGVtcGxhdGUuZGlzYWJsZWQoKSkgewotCQkgICAgaWYgKHRlbXBsYXRlLmdldFBhdHRlcm4oKSA9PSBudWxsKSB7Ci0JCSAgICAgICAgX25hbWVkVGVtcGxhdGVzLnB1dCh0ZW1wbGF0ZSwgdGhpcyk7Ci0JCSAgICB9IGVsc2UgewotCQkJLy8gdGVtcGxhdGUgdGhhdCBpcyBib3RoIG5hbWVkIGFuZCBtYXRjaGVkLi4uCi0JCSAgICAgICAgLy9fbmVlZGVkVGVtcGxhdGVzLnB1dCh0ZW1wbGF0ZSwgdGhpcyk7Ci0JCQlwcm9jZXNzVGVtcGxhdGVQYXR0ZXJuKHRlbXBsYXRlLG51bGwpOwotCQkgICAgfQotCQl9Ci0JICAgIH0gCi0JICAgIGVsc2UgeyAKLQkJcHJvY2Vzc1RlbXBsYXRlUGF0dGVybih0ZW1wbGF0ZSxrZXlzKTsKLQkgICAgfQotLyoqKioqKioqKioqKioqKioqCi0JICAgIC8vR1RNLSBidWcgZml4IDQ0MzMxMzMsIAotCSAgICAvLyAgICAgaW5jbHVkZSBuYW1lZCB0ZW1wbGF0ZXMgaGVyZSBhbHNvIAotCSAgICBwcm9jZXNzVGVtcGxhdGVQYXR0ZXJuKHRlbXBsYXRlLGtleXMpOyAKLSoqKioqKioqKioqKioqKioqKioqLwotCX0KLQlwcmVwYXJlVGVzdFNlcXVlbmNlcygpOwotICAgIH0KLQkJCi0gICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NUZW1wbGF0ZVBhdHRlcm4oVGVtcGxhdGUgdGVtcGxhdGUsIEhhc2h0YWJsZSBrZXlzKSB7Ci1TeXN0ZW0ub3V0LnByaW50bG4oIkdUTT4gSU4gTU9ERTogcHJvY2Vzc1RlbXBsYXRlUGF0dGVybnMoVGVtcGxhdGUsSGFzaHRhYmxlKSIpOwotCWZpbmFsIFBhdHRlcm4gbWF0Y2hQYXR0ZXJuID0gdGVtcGxhdGUuZ2V0UGF0dGVybigpOwotCWlmIChtYXRjaFBhdHRlcm4gIT0gbnVsbCkKLQkgICAgZmxhdHRlbkFsdGVybmF0aXZlKG1hdGNoUGF0dGVybiwgdGVtcGxhdGUsIGtleXMpOwotICAgIH0KLQkJCi0gICAgcHJpdmF0ZSB2b2lkIGZsYXR0ZW5BbHRlcm5hdGl2ZShQYXR0ZXJuIHBhdHRlcm4sCi0JCQkJICAgIFRlbXBsYXRlIHRlbXBsYXRlLAotCQkJCSAgICBIYXNodGFibGUga2V5cykgewotU3lzdGVtLm91dC5wcmludGxuKCJHVE0+IElOIE1PREU6IGZsYXR0ZW5BbHRlcm5hdGl2ZSguLi4pIik7Ci0JaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBJZEtleVBhdHRlcm4pIHsKLVN5c3RlbS5vdXQucHJpbnRsbigiR1RNPiBwYXR0ZXJuIGluc3RhbmNlb2YgSWRLZXlQYXR0ZXJuIik7Ci0JICAgIC8qIFRPRE86IENhbm5vdCBoYW5kbGUgdGhpcyBraW5kIG9mIHBhdHRlcm4geWV0ISEhCi0KLQkgICAgSWRLZXlQYXR0ZXJuIGlka2V5ID0gKElkS2V5UGF0dGVybilwYXR0ZXJuOwotCSAgICBTdGVwUGF0dGVybiBrZXJuZWwgPSBpZGtleS5nZXRLZXJuZWxQYXR0ZXJuKCk7Ci0JICAgIGlmIChrZXJuZWwgPT0gbnVsbCkgewotCQlLZXkga2V5ID0gKEtleSlrZXlzLmdldChpZGtleS5nZXRJbmRleE5hbWUoKSk7Ci0JCWlka2V5LnNldEtlcm5lbFBhdHRlcm4oa2V5LmdldEtlcm5lbFBhdHRlcm4oKSk7Ci0JICAgIH0KLQkgICAgKi8KLQl9Ci0JZWxzZSBpZiAocGF0dGVybiBpbnN0YW5jZW9mIEFsdGVybmF0aXZlUGF0dGVybikgewotU3lzdGVtLm91dC5wcmludGxuKCJHVE0+IHBhdHRlcm4gaW5zdGFuY2VvZiBBbHRlcm5hdGl2ZVBhdHRlcm4iKTsKLQkgICAgZmluYWwgQWx0ZXJuYXRpdmVQYXR0ZXJuIGFsdCA9IChBbHRlcm5hdGl2ZVBhdHRlcm4pcGF0dGVybjsKLQkgICAgZmxhdHRlbkFsdGVybmF0aXZlKGFsdC5nZXRMZWZ0KCksIHRlbXBsYXRlLCBrZXlzKTsKLQkgICAgZmxhdHRlbkFsdGVybmF0aXZlKGFsdC5nZXRSaWdodCgpLCB0ZW1wbGF0ZSwga2V5cyk7Ci0JfQotCWVsc2UgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBMb2NhdGlvblBhdGhQYXR0ZXJuKSB7Ci1TeXN0ZW0ub3V0LnByaW50bG4oIkdUTT4gcGF0dGVybiBpbnN0YW5jZW9mIExvY2F0aW9uUGF0aFBhdHRlcm4iKTsKLQkgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBscHAgPSAoTG9jYXRpb25QYXRoUGF0dGVybilwYXR0ZXJuOwotCSAgICBscHAuc2V0VGVtcGxhdGUodGVtcGxhdGUpOwotCSAgICBhZGRQYXR0ZXJuVG9Hcm91cChscHApOwotCX0KLQllbHNlCi0JICAgIFV0aWwucHJpbnRsbigiQmFkIHBhdHRlcm46ICIgKyBwYXR0ZXJuKTsKLSAgICB9Ci0gICAgCi0gICAgcHJpdmF0ZSB2b2lkIGFkZFBhdHRlcm4oaW50IGNvZGUsIExvY2F0aW9uUGF0aFBhdHRlcm4gcGF0dGVybikgewotCWlmIChjb2RlID49IF9wYXR0ZXJuR3JvdXBzLmxlbmd0aCkgewotCSAgICBWZWN0b3JbXSBuZXdHcm91cHMgPSBuZXcgVmVjdG9yW2NvZGUqMl07Ci0JICAgIFN5c3RlbS5hcnJheWNvcHkoX3BhdHRlcm5Hcm91cHMsIDAsIG5ld0dyb3VwcywgMCwKLQkJCSAgICAgX3BhdHRlcm5Hcm91cHMubGVuZ3RoKTsKLQkgICAgX3BhdHRlcm5Hcm91cHMgPSBuZXdHcm91cHM7Ci0JfQotCQotCVZlY3RvciBwYXR0ZXJucyA9IGNvZGUgPT0gLTEKLQkgICAgPyBfbm9kZUdyb3VwCS8vIG5vZGUoKQotCSAgICA6IF9wYXR0ZXJuR3JvdXBzW2NvZGVdOwotCQotCWlmIChwYXR0ZXJucyA9PSBudWxsKSB7Ci0JICAgIHBhdHRlcm5zID0gbmV3IFZlY3RvcigyKTsKLQkgICAgcGF0dGVybnMuYWRkRWxlbWVudChwYXR0ZXJuKTsKLQl9Ci0JZWxzZSB7CS8vIGtlZXAgcGF0dGVybnMgb3JkZXJlZCBieSBkaW1pbmlzaGluZyBwcmVjZWRlbmNlL3ByaW9yaXRpZXMKLQkgICAgYm9vbGVhbiBpbnNlcnRlZCA9IGZhbHNlOwotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhdHRlcm5zLnNpemUoKTsgaSsrKSB7Ci0JCWZpbmFsIExvY2F0aW9uUGF0aFBhdHRlcm4gbHBwVG9Db21wYXJlID0KLQkJICAgIChMb2NhdGlvblBhdGhQYXR0ZXJuKXBhdHRlcm5zLmVsZW1lbnRBdChpKTsKLQkJaWYgKHBhdHRlcm4ubm9TbWFsbGVyVGhhbihscHBUb0NvbXBhcmUpKSB7Ci0JCSAgICBpbnNlcnRlZCA9IHRydWU7Ci0JCSAgICBwYXR0ZXJucy5pbnNlcnRFbGVtZW50QXQocGF0dGVybiwgaSk7Ci0JCSAgICBicmVhazsKLQkJfQotCSAgICB9Ci0JICAgIGlmIChpbnNlcnRlZCA9PSBmYWxzZSkgewotCQlwYXR0ZXJucy5hZGRFbGVtZW50KHBhdHRlcm4pOwotCSAgICB9Ci0JfQotCWlmIChjb2RlID09IC0xKSB7Ci0JICAgIF9ub2RlR3JvdXAgPSBwYXR0ZXJuczsKLQl9Ci0JZWxzZSB7Ci0JICAgIF9wYXR0ZXJuR3JvdXBzW2NvZGVdID0gcGF0dGVybnM7Ci0JfQotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBHcm91cCBwYXR0ZXJucyBieSBOb2RlVGVzdHMgb2YgdGhlaXIgbGFzdCBTdGVwCi0gICAgICogS2VlcCB0aGVtIHNvcnRlZCBieSBwcmlvcml0eSB3aXRoaW4gZ3JvdXAKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgYWRkUGF0dGVyblRvR3JvdXAoZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBscHApIHsKLQkvLyBrZXJuZWwgcGF0dGVybiBpcyB0aGUgbGFzdCAobWF5YmUgb25seSkgU3RlcAotCWZpbmFsIFN0ZXBQYXR0ZXJuIGtlcm5lbCA9IGxwcC5nZXRLZXJuZWxQYXR0ZXJuKCk7Ci0JaWYgKGtlcm5lbCAhPSBudWxsKSB7Ci0JICAgIGFkZFBhdHRlcm4oa2VybmVsLmdldE5vZGVUeXBlKCksIGxwcCk7Ci0JfQotCWVsc2UgaWYgKF9leHBsaWNpdFJvb3RQYXR0ZXJuID09IG51bGwgfHwKLQkJIGxwcC5ub1NtYWxsZXJUaGFuKF9leHBsaWNpdFJvb3RQYXR0ZXJuKSkgewotCSAgICBfZXhwbGljaXRSb290UGF0dGVybiA9IGxwcDsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQnVpbGQgdGVzdCBzZXF1ZW5jZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcHJlcGFyZVRlc3RTZXF1ZW5jZXMoKSB7Ci0JZmluYWwgVmVjdG9yIG5hbWVzID0gX3N0eWxlc2hlZXQuZ2V0WFNMVEMoKS5nZXROYW1lc0luZGV4KCk7Ci0JX2NvZGUyVGVzdFNlcSA9IG5ldyBUZXN0U2VxW0RPTS5OVFlQRVMgKyBuYW1lcy5zaXplKCldOwotCQotCWZpbmFsIGludCBuID0gX3BhdHRlcm5Hcm91cHMubGVuZ3RoOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JICAgIGZpbmFsIFZlY3RvciBwYXR0ZXJucyA9IF9wYXR0ZXJuR3JvdXBzW2ldOwotCSAgICBpZiAocGF0dGVybnMgIT0gbnVsbCkgewotCQlmaW5hbCBUZXN0U2VxIHRlc3RTZXEgPSBuZXcgVGVzdFNlcShwYXR0ZXJucywgdGhpcyk7Ci0JCXRlc3RTZXEucmVkdWNlKCk7Ci0JCV9jb2RlMlRlc3RTZXFbaV0gPSB0ZXN0U2VxOwotCQl0ZXN0U2VxLmZpbmRUZW1wbGF0ZXMoX25lZWRlZFRlbXBsYXRlcyk7Ci0JICAgIH0KLQl9Ci0KLQlpZiAoKF9ub2RlR3JvdXAgIT0gbnVsbCkgJiYgKF9ub2RlR3JvdXAuc2l6ZSgpID4gMCkpIHsKLQkgICAgX25vZGVUZXN0U2VxID0gbmV3IFRlc3RTZXEoX25vZGVHcm91cCwgdGhpcyk7Ci0JICAgIF9ub2RlVGVzdFNlcS5yZWR1Y2UoKTsKLQkgICAgX25vZGVUZXN0U2VxLmZpbmRUZW1wbGF0ZXMoX25lZWRlZFRlbXBsYXRlcyk7Ci0JfQotCQotCWlmIChfZXhwbGljaXRSb290UGF0dGVybiAhPSBudWxsKSB7Ci0JICAgIC8vIGRvZXNuJ3QgbWF0dGVyIHdoYXQgaXMgJ3B1dCcsIG9ubHkga2V5IG1hdHRlcnMKLQkgICAgX25lZWRlZFRlbXBsYXRlcy5wdXQoX2V4cGxpY2l0Um9vdFBhdHRlcm4uZ2V0VGVtcGxhdGUoKSwgdGhpcyk7Ci0JfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBjb21waWxlTmFtZWRUZW1wbGF0ZShUZW1wbGF0ZSB0ZW1wbGF0ZSwKLQkJCQkgICAgICBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgU3RyaW5nIERPTV9DTEFTU19TSUcgPSBjbGFzc0dlbi5nZXRET01DbGFzc1NpZygpOwotCWZpbmFsIE5hbWVkTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiA9Ci0JICAgIG5ldyBOYW1lZE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDLAotCQkJCSAgICAgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5WT0lELAotCQkJCSAgICAgbmV3IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbXSB7Ci0JCQkJCSBVdGlsLmdldEpDUmVmVHlwZShET01fQ0xBU1NfU0lHKSwKLQkJCQkJIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLQkJCQkJIFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpLAotCQkJCQkgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQKLQkJCQkgICAgIH0sCi0JCQkJICAgICBuZXcgU3RyaW5nW10gewotCQkJCQkgRE9DVU1FTlRfUE5BTUUsCi0JCQkJCSBJVEVSQVRPUl9QTkFNRSwKLQkJCQkJIFRSQU5TTEVUX09VVFBVVF9QTkFNRSwKLQkJCQkJIE5PREVfUE5BTUUKLQkJCQkgICAgIH0sCi0JCQkJICAgICAvLyEhISBtb3JlIG5hbWUgc29waGlzdGljYXRpb24gbmVlZGVkCi0JCQkJICAgICB0ZW1wbGF0ZS5nZXROYW1lKCkudG9TdHJpbmcoKSwKLQkJCQkgICAgIGdldENsYXNzTmFtZSgpLAotCQkJCSAgICAgaWwsIGNwZyk7Ci0JCi0JaWwuYXBwZW5kKHRlbXBsYXRlLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbikpOwotCWlsLmFwcGVuZChSRVRVUk4pOwotCQotCW1ldGhvZEdlbi5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0JbWV0aG9kR2VuLnNldE1heExvY2FscygpOwotCW1ldGhvZEdlbi5zZXRNYXhTdGFjaygpOwotCW1ldGhvZEdlbi5yZW1vdmVOT1BzKCk7Ci0JY2xhc3NHZW4uYWRkTWV0aG9kKG1ldGhvZEdlbi5nZXRNZXRob2QoKSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIGNvbXBpbGVUZW1wbGF0ZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotCQkJCSAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dCkgewotCUVudW1lcmF0aW9uIHRlbXBsYXRlcyA9IF9uZWVkZWRUZW1wbGF0ZXMua2V5cygpOwotCXdoaWxlICh0ZW1wbGF0ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgVGVtcGxhdGUgdGVtcGxhdGUgPSAoVGVtcGxhdGUpdGVtcGxhdGVzLm5leHRFbGVtZW50KCk7Ci0JICAgIGlmICh0ZW1wbGF0ZS5oYXNDb250ZW50cygpKSB7Ci0JCS8vICEhISBUT0RPIHRlbXBsYXRlcyBib3RoIG5hbWVkIGFuZCBtYXRjaGVkCi0JCUluc3RydWN0aW9uTGlzdCB0aWwgPSB0ZW1wbGF0ZS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQl0aWwuYXBwZW5kKG5ldyBHT1RPKG5leHQpKTsKLQkJX3RlbXBsYXRlSW5zdHJ1Y3Rpb25MaXN0cy5wdXQodGVtcGxhdGUsIHRpbCk7Ci0JCV90ZW1wbGF0ZUluc3RydWN0aW9uSGFuZGxlcy5wdXQodGVtcGxhdGUsIHRpbC5nZXRTdGFydCgpKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJLy8gZW1wdHkgdGVtcGxhdGUKLQkJX3RlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGVzLnB1dCh0ZW1wbGF0ZSwgbmV4dCk7Ci0JICAgIH0KLQl9Ci0JdGVtcGxhdGVzID0gX25hbWVkVGVtcGxhdGVzLmtleXMoKTsKLQl3aGlsZSAodGVtcGxhdGVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gKFRlbXBsYXRlKXRlbXBsYXRlcy5uZXh0RWxlbWVudCgpOwotCSAgICBjb21waWxlTmFtZWRUZW1wbGF0ZSh0ZW1wbGF0ZSwgY2xhc3NHZW4pOwotCX0KLSAgICB9Ci0JCi0gICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFRlbXBsYXRlQ29kZShJbnN0cnVjdGlvbkxpc3QgYm9keSkgewotCWZpbmFsIEVudW1lcmF0aW9uIHRlbXBsYXRlcyA9IF9uZWVkZWRUZW1wbGF0ZXMua2V5cygpOwotCXdoaWxlICh0ZW1wbGF0ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgT2JqZWN0IGlMaXN0ID0KLQkJX3RlbXBsYXRlSW5zdHJ1Y3Rpb25MaXN0cy5nZXQodGVtcGxhdGVzLm5leHRFbGVtZW50KCkpOwotCSAgICBpZiAoaUxpc3QgIT0gbnVsbCkgewotCQlib2R5LmFwcGVuZCgoSW5zdHJ1Y3Rpb25MaXN0KWlMaXN0KTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgYXBwZW5kVGVzdFNlcXVlbmNlcyhJbnN0cnVjdGlvbkxpc3QgYm9keSkgewotCWZpbmFsIGludCBuID0gX2NvZGUyVGVzdFNlcS5sZW5ndGg7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkgICAgZmluYWwgVGVzdFNlcSB0ZXN0U2VxID0gX2NvZGUyVGVzdFNlcVtpXTsKLQkgICAgaWYgKHRlc3RTZXEgIT0gbnVsbCkgewotCQlJbnN0cnVjdGlvbkxpc3QgaWwgPSB0ZXN0U2VxLmdldEluc3RydWN0aW9uTGlzdCgpOwotCQlpZiAoaWwgIT0gbnVsbCkKLQkJICAgIGJvZHkuYXBwZW5kKGlsKTsKLQkJLy8gZWxzZSB0cml2aWFsIFRlc3RTZXEKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY29tcGlsZUdldENoaWxkcmVuKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCQkgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0JCQkJCSAgaW50IG5vZGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIFN0cmluZyBET01fQ0xBU1MgPSBjbGFzc0dlbi5nZXRET01DbGFzcygpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQobmV3IElMT0FEKG5vZGUpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihET01fQ0xBU1MsCi0JCQkJCQkgICAgIEdFVF9DSElMRFJFTiwKLQkJCQkJCSAgICAgR0VUX0NISUxEUkVOX1NJRykpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyB0aGUgZGVmYXVsdCBoYW5kbGluZyBmb3IgRE9NIGVsZW1lbnRzOiB0cmF2ZXJzZSBhbGwgY2hpbGRyZW4KLSAgICAgKi8KLSAgICBwcml2YXRlIEluc3RydWN0aW9uTGlzdCBjb21waWxlRGVmYXVsdFJlY3Vyc2lvbihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkJCSAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotCQkJCQkJICAgIGludCBub2RlLAotCQkJCQkJICAgIEluc3RydWN0aW9uSGFuZGxlIG5leHQpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIFN0cmluZyBET01fQ0xBU1MgPSBjbGFzc0dlbi5nZXRET01DbGFzcygpOwotCWZpbmFsIFN0cmluZyBhcHBseVRlbXBsYXRlc1NpZyA9IGNsYXNzR2VuLmdldEFwcGx5VGVtcGxhdGVzU2lnKCk7Ci0JZmluYWwgaW50IGdldENoaWxkcmVuID0gY3BnLmFkZE1ldGhvZHJlZihET01fQ0xBU1MsCi0JCQkJCQkgR0VUX0NISUxEUkVOLAotCQkJCQkJIEdFVF9DSElMRFJFTl9TSUcpOwotCWZpbmFsIGludCBhcHBseVRlbXBsYXRlcyA9IGNwZy5hZGRNZXRob2RyZWYoZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCQkgICAgZnVuY3Rpb25OYW1lKCksCi0JCQkJCQkgICAgYXBwbHlUZW1wbGF0ZXNTaWcpOwotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCQotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQobmV3IElMT0FEKG5vZGUpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoZ2V0Q2hpbGRyZW4pKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChhcHBseVRlbXBsYXRlcykpOwotCWlsLmFwcGVuZChuZXcgR09UTyhuZXh0KSk7Ci0JcmV0dXJuIGlsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIHRoZSBkZWZhdWx0IGFjdGlvbiBmb3IgRE9NIHRleHQgbm9kZXMgYW5kIGF0dHJpYnV0ZSBub2RlczoKLSAgICAgKiBvdXRwdXQgdGhlIG5vZGUncyB0ZXh0IHZhbHVlCi0gICAgICovCi0gICAgcHJpdmF0ZSBJbnN0cnVjdGlvbkxpc3QgY29tcGlsZURlZmF1bHRUZXh0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLQkJCQkJICAgICAgIGludCBub2RlLAotCQkJCQkgICAgICAgSW5zdHJ1Y3Rpb25IYW5kbGUgbmV4dCkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgU3RyaW5nIERPTV9DTEFTUyA9IGNsYXNzR2VuLmdldERPTUNsYXNzKCk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCWlsLmFwcGVuZChuZXcgSUxPQUQobm9kZSkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoRE9NX0NMQVNTLAotCQkJCQkJICAgICBDSEFSQUNURVJTLAotCQkJCQkJICAgICBDSEFSQUNURVJTX1NJRykpKTsKLQlpbC5hcHBlbmQobmV3IEdPVE8obmV4dCkpOwotCXJldHVybiBpbDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIEluc3RydWN0aW9uTGlzdCBjb21waWxlTmFtZXNwYWNlcyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkJICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLQkJCQkJICAgICAgYm9vbGVhbltdIGlzTmFtZXNwYWNlLAotCQkJCQkgICAgICBib29sZWFuW10gaXNBdHRyaWJ1dGUsCi0JCQkJCSAgICAgIGJvb2xlYW4gYXR0ckZsYWcsCi0JCQkJCSAgICAgIEluc3RydWN0aW9uSGFuZGxlIGRlZmF1bHRUYXJnZXQpIHsKLQlmaW5hbCBYU0xUQyB4c2x0YyA9IGNsYXNzR2VuLmdldFBhcnNlcigpLmdldFhTTFRDKCk7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIFN0cmluZyBET01fQ0xBU1MgPSBjbGFzc0dlbi5nZXRET01DbGFzcygpOwotCi0JLy8gQXBwZW5kIHN3aXRjaCgpIHN0YXRlbWVudCAtIG5hbWVzcGFjZSB0ZXN0IGRpc3BhdGNoIGxvb3AKLQlmaW5hbCBWZWN0b3IgbmFtZXNwYWNlcyA9IHhzbHRjLmdldE5hbWVzcGFjZUluZGV4KCk7Ci0JZmluYWwgVmVjdG9yIG5hbWVzID0geHNsdGMuZ2V0TmFtZXNJbmRleCgpOwotCWZpbmFsIGludCBuYW1lc3BhY2VDb3VudCA9IG5hbWVzcGFjZXMuc2l6ZSgpICsgMTsKLQlmaW5hbCBpbnQgbmFtZXNDb3VudCA9IG5hbWVzLnNpemUoKTsKLQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBpbnRbXSB0eXBlcyA9IG5ldyBpbnRbbmFtZXNwYWNlQ291bnRdOwotCWZpbmFsIEluc3RydWN0aW9uSGFuZGxlW10gdGFyZ2V0cyA9IG5ldyBJbnN0cnVjdGlvbkhhbmRsZVt0eXBlcy5sZW5ndGhdOwotCi0JaWYgKG5hbWVzcGFjZUNvdW50ID4gMCkgewotCSAgICBib29sZWFuIGNvbXBpbGVkID0gZmFsc2U7Ci0KLQkgICAgLy8gSW5pdGlhbGl6ZSB0YXJnZXRzIGZvciBuYW1lc3BhY2UoKSBzd2l0Y2ggc3RhdGVtZW50Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZXNwYWNlQ291bnQ7IGkrKykgewotCQl0YXJnZXRzW2ldID0gZGVmYXVsdFRhcmdldDsKLQkJdHlwZXNbaV0gPSBpOwotCSAgICB9Ci0KLQkgICAgLy8gQWRkIHRlc3Qgc2VxdWVuY2VzIGZvciBrbm93biBuYW1lc3BhY2UgdHlwZXMKLQkgICAgZm9yIChpbnQgaSA9IERPTS5OVFlQRVM7IGkgPCAoRE9NLk5UWVBFUytuYW1lc0NvdW50KTsgaSsrKSB7Ci0JCWlmICgoaXNOYW1lc3BhY2VbaV0pICYmIChpc0F0dHJpYnV0ZVtpXSA9PSBhdHRyRmxhZykpIHsKLQkJICAgIFN0cmluZyBuYW1lID0gKFN0cmluZyluYW1lcy5lbGVtZW50QXQoaS1ET00uTlRZUEVTKTsKLQkJICAgIFN0cmluZyBuYW1lc3BhY2UgPSBuYW1lLnN1YnN0cmluZygwLG5hbWUubGFzdEluZGV4T2YoJzonKSk7Ci0JCSAgICBmaW5hbCBpbnQgdHlwZSA9IHhzbHRjLnJlZ2lzdGVyTmFtZXNwYWNlKG5hbWVzcGFjZSk7Ci0JCSAgICAKLQkJICAgIGlmICgoaSA8IF9jb2RlMlRlc3RTZXEubGVuZ3RoKSAmJgotCQkJKF9jb2RlMlRlc3RTZXFbaV0gIT0gbnVsbCkpIHsKLQkJCXRhcmdldHNbdHlwZV0gPQotCQkJICAgIChfY29kZTJUZXN0U2VxW2ldKS5jb21waWxlKGNsYXNzR2VuLAotCQkJCQkJICAgICAgIG1ldGhvZEdlbiwKLQkJCQkJCSAgICAgICBkZWZhdWx0VGFyZ2V0KTsKLQkJCWNvbXBpbGVkID0gdHJ1ZTsKLQkJICAgIH0KLQkJfQotCSAgICB9Ci0KLQkgICAgLy8gUmV0dXJuICJudWxsIiBpZiBubyB0ZXN0IHNlcXVlbmNlcyB3ZXJlIGNvbXBpbGVkCi0JICAgIGlmICghY29tcGlsZWQpIHJldHVybihudWxsKTsKLQkJCi0JICAgIC8vIEFwcGVuZCBmaXJzdCBjb2RlIGluIGFwcGx5VGVtcGxhdGVzKCkgLSBnZXQgdHlwZSBvZiBjdXJyZW50IG5vZGUKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElMT0FEKF9jdXJyZW50SW5kZXgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoRE9NX0NMQVNTLAotCQkJCQkJCSAgICAgImdldE5hbWVzcGFjZVR5cGUiLAotCQkJCQkJCSAgICAgIihJKUkiKSkpOwotCSAgICBpbC5hcHBlbmQobmV3IFNXSVRDSCh0eXBlcywgdGFyZ2V0cywgZGVmYXVsdFRhcmdldCkpOwotCSAgICByZXR1cm4oaWwpOwotCX0KLQllbHNlIHsKLQkgICAgcmV0dXJuKG51bGwpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBdXhpbGxhcnkgbWV0aG9kIHRvIGRldGVybWluZSBpZiBhIHFuYW1lIGRlc2NyaWJlcyBhbiBhdHRyaWJ1dGUvZWxlbWVudAotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNBdHRyaWJ1dGVOYW1lKFN0cmluZyBxbmFtZSkgewotCWZpbmFsIGludCBjb2wgPSBxbmFtZS5pbmRleE9mKCc6JykgKyAxOwotCWlmIChxbmFtZS5jaGFyQXQoY29sKSA9PSAnQCcpCi0JICAgIHJldHVybih0cnVlKTsKLQllbHNlCi0JICAgIHJldHVybihmYWxzZSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc05hbWVzcGFjZU5hbWUoU3RyaW5nIHFuYW1lKSB7Ci0JZmluYWwgaW50IGNvbCA9IHFuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0JaWYgKChjb2wgPiAtMSkgJiYgKHFuYW1lLmNoYXJBdChxbmFtZS5sZW5ndGgoKS0xKSA9PSAnKicpKQotCSAgICByZXR1cm4odHJ1ZSk7Ci0JZWxzZQotCSAgICByZXR1cm4oZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIHRoZSBhcHBseVRlbXBsYXRlcygpIG1ldGhvZCBhbmQgYWRkcyBpdCB0byB0aGUgdHJhbnNsZXQuCi0gICAgICogVGhpcyBpcyB0aGUgbWFpbiBkaXNwYXRjaCBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tcGlsZUFwcGx5VGVtcGxhdGVzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0JZmluYWwgWFNMVEMgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBWZWN0b3IgbmFtZXMgICAgICA9IHhzbHRjLmdldE5hbWVzSW5kZXgoKTsKLQlmaW5hbCBTdHJpbmcgRE9NX0NMQVNTID0gY2xhc3NHZW4uZ2V0RE9NQ2xhc3MoKTsKLQotCS8vICgqKSBDcmVhdGUgdGhlIGFwcGx5VGVtcGxhdGVzKCkgbWV0aG9kCi0JZmluYWwgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVtdIGFyZ1R5cGVzID0KLQkgICAgbmV3IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbM107Ci0JYXJnVHlwZXNbMF0gPSBVdGlsLmdldEpDUmVmVHlwZShjbGFzc0dlbi5nZXRET01DbGFzc1NpZygpKTsKLQlhcmdUeXBlc1sxXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKTsKLQlhcmdUeXBlc1syXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpOwotCi0JZmluYWwgU3RyaW5nW10gYXJnTmFtZXMgPSBuZXcgU3RyaW5nWzNdOwotCWFyZ05hbWVzWzBdID0gRE9DVU1FTlRfUE5BTUU7Ci0JYXJnTmFtZXNbMV0gPSBJVEVSQVRPUl9QTkFNRTsKLQlhcmdOYW1lc1syXSA9IFRSQU5TTEVUX09VVFBVVF9QTkFNRTsKLQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBtYWluSUwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiA9Ci0JICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQyB8IEFDQ19GSU5BTCwgCi0JCQkJZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5WT0lELAotCQkJCWFyZ1R5cGVzLCBhcmdOYW1lcywgZnVuY3Rpb25OYW1lKCksCi0JCQkJZ2V0Q2xhc3NOYW1lKCksIG1haW5JTCwKLQkJCQljbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0JbWV0aG9kR2VuLmFkZEV4Y2VwdGlvbigiY29tLnN1bi54c2x0LlRyYW5zbGV0RXhjZXB0aW9uIik7Ci0KLQkvLyAoKikgQ3JlYXRlIHRoZSBsb2NhbCB2YXJpYWJsZWEKLQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIGN1cnJlbnQ7Ci0JY3VycmVudCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMigiY3VycmVudCIsCi0JCQkJCSAgICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJCQkgICAgICBtYWluSUwuZ2V0RW5kKCkpOwotCV9jdXJyZW50SW5kZXggPSBjdXJyZW50LmdldEluZGV4KCk7Ci0KLQkvLyAoKikgQ3JlYXRlIHRoZSAiYm9keSIgaW5zdHJ1Y3Rpb24gbGlzdCB0aGF0IHdpbGwgZXZlbnR1YWxseSBob2xkIHRoZQotCS8vICAgICBjb2RlIGZvciB0aGUgZW50aXJlIG1ldGhvZCAob3RoZXIgSUxzIHdpbGwgYmUgYXBwZW5kZWQpLgotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBib2R5ID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCWJvZHkuYXBwZW5kKE5PUCk7Ci0KLQkvLyAoKikgQ3JlYXRlIGFuIGluc3RydWN0aW9uIGxpc3QgdGhhdCBjb250YWlucyB0aGUgZGVmYXVsdCBuZXh0LW5vZGUKLQkvLyAgICAgaXRlcmF0aW9uCi0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsTG9vcCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbExvb3AuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0JaWxMb29wLmFwcGVuZChtZXRob2RHZW4ubmV4dE5vZGUoKSk7Ci0JaWxMb29wLmFwcGVuZChEVVApOwotCWlsTG9vcC5hcHBlbmQobmV3IElTVE9SRShfY3VycmVudEluZGV4KSk7Ci0JaWxMb29wLmFwcGVuZChuZXcgSUZORShib2R5LmdldFN0YXJ0KCkpKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBpaExvb3AgPSBpbExvb3AuZ2V0U3RhcnQoKTsKLQotCS8vICgqKSBDb21waWxlIGRlZmF1bHQgaGFuZGxpbmcgb2YgZWxlbWVudHMgKHRyYXZlcnNlIGNoaWxkcmVuKQotCUluc3RydWN0aW9uTGlzdCBpbFJlY3Vyc2UgPQotCSAgY29tcGlsZURlZmF1bHRSZWN1cnNpb24oY2xhc3NHZW4sIG1ldGhvZEdlbiwgX2N1cnJlbnRJbmRleCwgaWhMb29wKTsKLQlJbnN0cnVjdGlvbkhhbmRsZSBpaFJlY3Vyc2UgPSBpbFJlY3Vyc2UuZ2V0U3RhcnQoKTsKLQotCS8vICgqKSBDb21waWxlIGRlZmF1bHQgaGFuZGxpbmcgb2YgdGV4dC9hdHRyaWJ1dGUgbm9kZXMgKG91dHB1dCB0ZXh0KQotCUluc3RydWN0aW9uTGlzdCBpbFRleHQgPSBjb21waWxlRGVmYXVsdFRleHQoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkJCSAgICBfY3VycmVudEluZGV4LCBpaExvb3ApOwotCUluc3RydWN0aW9uSGFuZGxlIGloVGV4dCA9IGlsVGV4dC5nZXRTdGFydCgpOwotCi0JLy8gRGlzdGluZ3Vpc2ggYXR0cmlidXRlL2VsZW1lbnQvbmFtZXNwYWNlIHRlc3RzIGZvciBmdXJ0aGVyIHByb2Nlc3NpbmcKLQlmaW5hbCBpbnRbXSB0eXBlcyA9IG5ldyBpbnRbRE9NLk5UWVBFUyArIG5hbWVzLnNpemUoKV07Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgdHlwZXNbaV0gPSBpOwotCi0JZmluYWwgYm9vbGVhbltdIGlzQXR0cmlidXRlID0gbmV3IGJvb2xlYW5bdHlwZXMubGVuZ3RoXTsKLQlmaW5hbCBib29sZWFuW10gaXNOYW1lc3BhY2UgPSBuZXcgYm9vbGVhblt0eXBlcy5sZW5ndGhdOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbmFtZXMuc2l6ZSgpOyBpKyspIHsKLQkgICAgZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLmVsZW1lbnRBdChpKTsKLQkgICAgaXNBdHRyaWJ1dGVbaStET00uTlRZUEVTXSA9IGlzQXR0cmlidXRlTmFtZShuYW1lKTsKLQkgICAgaXNOYW1lc3BhY2VbaStET00uTlRZUEVTXSA9IGlzTmFtZXNwYWNlTmFtZShuYW1lKTsKLQl9Ci0KLQkvLyAoKikgQ29tcGlsZSBhbGwgdGVtcGxhdGVzIC0gcmVnYXJkbGVzcyBvZiBwYXR0ZXJuIHR5cGUKLQljb21waWxlVGVtcGxhdGVzKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCk7Ci0KLQkvLyAoKikgSGFuZGxlIHRlbXBsYXRlIHdpdGggZXhwbGljaXQgIioiIHBhdHRlcm4KLQlmaW5hbCBUZXN0U2VxIGVsZW1UZXN0ID0gX2NvZGUyVGVzdFNlcVtET00uRUxFTUVOVF07Ci0JSW5zdHJ1Y3Rpb25IYW5kbGUgaWhFbGVtID0gaWhSZWN1cnNlOwotCWlmIChlbGVtVGVzdCAhPSBudWxsKQotCSAgICBpaEVsZW0gPSBlbGVtVGVzdC5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloUmVjdXJzZSk7Ci0KLQkvLyAoKikgSGFuZGxlIHRlbXBsYXRlIHdpdGggZXhwbGljaXQgIkAqIiBwYXR0ZXJuCi0JZmluYWwgVGVzdFNlcSBhdHRyVGVzdCA9IF9jb2RlMlRlc3RTZXFbRE9NLkFUVFJJQlVURV07Ci0JSW5zdHJ1Y3Rpb25IYW5kbGUgaWhBdHRyID0gaWhUZXh0OwotCWlmIChhdHRyVGVzdCAhPSBudWxsKQotCSAgICBpaEF0dHIgPSBhdHRyVGVzdC5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloVGV4dCk7Ci0KLQkvLyAoKikgSWYgdGhlcmUgaXMgYSBtYXRjaCBvbiBub2RlKCkgd2UgbmVlZCB0byByZXBsYWNlIGloRWxlbQotCS8vICAgICBhbmQgaWhUZXh0IChkZWZhdWx0IGJlaGF2aW91ciBmb3IgZWxlbWVudHMgJiB0ZXh0KS4KLQlpZiAoX25vZGVUZXN0U2VxICE9IG51bGwpIHsKLQkgICAgZG91YmxlIG5vZGVQcmlvID0gLTAuNTsvLyBfbm9kZVRlc3RTZXEuZ2V0UHJpb3JpdHkoKTsKLQkgICAgaW50ICAgIG5vZGVQb3MgID0gX25vZGVUZXN0U2VxLmdldFBvc2l0aW9uKCk7Ci0JICAgIGlmICgoZWxlbVRlc3QgPT0gbnVsbCkgfHwKLQkJKGVsZW1UZXN0LmdldFByaW9yaXR5KCkgPT0gRG91YmxlLk5hTikgfHwKLQkJKGVsZW1UZXN0LmdldFByaW9yaXR5KCkgPCBub2RlUHJpbykgfHwKLQkJKChlbGVtVGVzdC5nZXRQcmlvcml0eSgpID09IG5vZGVQcmlvKSAmJgotCQkgKGVsZW1UZXN0LmdldFBvc2l0aW9uKCkgPCBub2RlUG9zKSkpIHsKLQkJaWhFbGVtID0gX25vZGVUZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwgaWhMb29wKTsKLQkJaWhUZXh0ID0gaWhFbGVtOwotCSAgICB9Ci0JfQotCi0JLy8gKCopIEhhbmRsZSB0ZW1wbGF0ZXMgd2l0aCAibnM6KiIgcGF0dGVybgotCUluc3RydWN0aW9uSGFuZGxlIGVsZW1OYW1lc3BhY2VIYW5kbGUgPSBpaEVsZW07Ci0JSW5zdHJ1Y3Rpb25MaXN0IG5zRWxlbSA9IGNvbXBpbGVOYW1lc3BhY2VzKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgICBpc05hbWVzcGFjZSwgaXNBdHRyaWJ1dGUsCi0JCQkJCQkgICBmYWxzZSwgaWhFbGVtKTsKLQlpZiAobnNFbGVtICE9IG51bGwpIGVsZW1OYW1lc3BhY2VIYW5kbGUgPSBuc0VsZW0uZ2V0U3RhcnQoKTsKLQotCS8vICgqKSBIYW5kbGUgdGVtcGxhdGVzIHdpdGggIm5zOkAqIiBwYXR0ZXJuCi0JSW5zdHJ1Y3Rpb25MaXN0IG5zQXR0ciA9IGNvbXBpbGVOYW1lc3BhY2VzKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgICBpc05hbWVzcGFjZSwgaXNBdHRyaWJ1dGUsCi0JCQkJCQkgICB0cnVlLCBpaEF0dHIpOwotCUluc3RydWN0aW9uSGFuZGxlIGF0dHJOYW1lc3BhY2VIYW5kbGUgPSBpaEF0dHI7Ci0JaWYgKG5zQXR0ciAhPSBudWxsKSBhdHRyTmFtZXNwYWNlSGFuZGxlID0gbnNBdHRyLmdldFN0YXJ0KCk7Ci0KLQkvLyAoKikgSGFuZGxlIHRlbXBsYXRlcyB3aXRoICJuczplbGVtIiBvciAibnM6QGF0dHIiIHBhdHRlcm4KLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIHRhcmdldHMgPSBuZXcgSW5zdHJ1Y3Rpb25IYW5kbGVbdHlwZXMubGVuZ3RoXTsKLQlmb3IgKGludCBpID0gRE9NLk5UWVBFUzsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHsKLQkgICAgZmluYWwgVGVzdFNlcSB0ZXN0U2VxID0gX2NvZGUyVGVzdFNlcVtpXTsKLQkgICAgLy8gSnVtcCBzdHJhaWdodCB0byBuYW1lc3BhY2UgdGVzdHMgPwotCSAgICBpZiAoaXNOYW1lc3BhY2VbaV0pIHsKLQkJaWYgKGlzQXR0cmlidXRlW2ldKQotCQkgICAgdGFyZ2V0c1tpXSA9IGF0dHJOYW1lc3BhY2VIYW5kbGU7Ci0JCWVsc2UKLQkJICAgIHRhcmdldHNbaV0gPSBlbGVtTmFtZXNwYWNlSGFuZGxlOwotCSAgICB9Ci0JICAgIC8vIFRlc3QgZmlyc3QsIHRoZW4ganVtcCB0byBuYW1lc3BhY2UgdGVzdHMKLQkgICAgZWxzZSBpZiAodGVzdFNlcSAhPSBudWxsKSB7Ci0JCWlmIChpc0F0dHJpYnV0ZVtpXSkKLQkJICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkJCSBhdHRyTmFtZXNwYWNlSGFuZGxlKTsKLQkJZWxzZQotCQkgICAgdGFyZ2V0c1tpXSA9IHRlc3RTZXEuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLAotCQkJCQkJIGVsZW1OYW1lc3BhY2VIYW5kbGUpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQl0YXJnZXRzW2ldID0gaWhMb29wOwotCSAgICB9Ci0JfQotCi0JLy8gSGFuZGxlIHBhdHRlcm4gd2l0aCBtYXRjaCBvbiByb290IG5vZGUgLSBkZWZhdWx0OiB0cmF2ZXJzZSBjaGlsZHJlbgotCXRhcmdldHNbRE9NLlJPT1RdID0gX2V4cGxpY2l0Um9vdFBhdHRlcm4gIT0gbnVsbAotCSAgICA/IGdldFRlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGUoX2V4cGxpY2l0Um9vdFBhdHRlcm4uZ2V0VGVtcGxhdGUoKSkKLQkgICAgOiBpaFJlY3Vyc2U7Ci0JCi0JLy8gSGFuZGxlIGFueSBwYXR0ZXJuIHdpdGggbWF0Y2ggb24gdGV4dCBub2RlcyAtIGRlZmF1bHQ6IG91dHB1dCB0ZXh0Ci0JdGFyZ2V0c1tET00uVEVYVF0gPSBfY29kZTJUZXN0U2VxW0RPTS5URVhUXSAhPSBudWxsCi0JICAgID8gX2NvZGUyVGVzdFNlcVtET00uVEVYVF0uY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaExvb3ApCi0JICAgIDogaWhUZXh0OwotCi0JLy8gVGhpcyBET00tdHlwZSBpcyBub3QgaW4gdXNlIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLQl0YXJnZXRzW0RPTS5VTlVTRURdID0gaWhMb29wOwotCi0JLy8gTWF0Y2ggdW5rbm93biBlbGVtZW50IGluIERPTSAtIGRlZmF1bHQ6IGNoZWNrIGZvciBuYW1lc3BhY2UgbWF0Y2gKLQl0YXJnZXRzW0RPTS5FTEVNRU5UXSA9IGVsZW1OYW1lc3BhY2VIYW5kbGU7Ci0KLQkvLyBNYXRjaCB1bmtub3duIGF0dHJpYnV0ZSBpbiBET00gLSBkZWZhdWx0OiBjaGVjayBmb3IgbmFtZXNwYWNlIG1hdGNoCi0JdGFyZ2V0c1tET00uQVRUUklCVVRFXSA9IGF0dHJOYW1lc3BhY2VIYW5kbGU7Ci0KLQkvLyBNYXRjaCBvbiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLQl0YXJnZXRzW0RPTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OXSA9Ci0JICAgIF9jb2RlMlRlc3RTZXFbRE9NLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05dICE9IG51bGwKLQkgICAgPyBfY29kZTJUZXN0U2VxW0RPTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OXQotCSAgICAuY29tcGlsZShjbGFzc0dlbiwgbWV0aG9kR2VuLCBpaExvb3ApCi0JICAgIDogaWhMb29wOwotCQotCS8vIE1hdGNoIG9uIGNvbW1lbnRzIC0gZGVmYXVsdDogcHJvY2VzcyBuZXh0IG5vZGUKLQl0YXJnZXRzW0RPTS5DT01NRU5UXSA9IF9jb2RlMlRlc3RTZXFbRE9NLkNPTU1FTlRdICE9IG51bGwKLQkgICAgPyBfY29kZTJUZXN0U2VxW0RPTS5DT01NRU5UXS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sIGloTG9vcCkKLQkgICAgOiBpaExvb3A7Ci0KLQkvLyBOb3cgY29tcGlsZSB0ZXN0IHNlcXVlbmNlcyBmb3IgdmFyaW91cyBtYXRjaCBwYXR0ZXJuczoKLQlmb3IgKGludCBpID0gRE9NLk5UWVBFUzsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHsKLQkgICAgZmluYWwgVGVzdFNlcSB0ZXN0U2VxID0gX2NvZGUyVGVzdFNlcVtpXTsKLQkgICAgLy8gSnVtcCBzdHJhaWdodCB0byBuYW1lc3BhY2UgdGVzdHMgPwotCSAgICBpZiAoKHRlc3RTZXEgPT0gbnVsbCkgfHwgKGlzTmFtZXNwYWNlW2ldKSkgewotCQlpZiAoaXNBdHRyaWJ1dGVbaV0pCi0JCSAgICB0YXJnZXRzW2ldID0gYXR0ck5hbWVzcGFjZUhhbmRsZTsKLQkJZWxzZQotCQkgICAgdGFyZ2V0c1tpXSA9IGVsZW1OYW1lc3BhY2VIYW5kbGU7Ci0JICAgIH0KLQkgICAgLy8gTWF0Y2ggb24gbm9kZSB0eXBlCi0JICAgIGVsc2UgewotCQlpZiAoaXNBdHRyaWJ1dGVbaV0pCi0JCSAgICB0YXJnZXRzW2ldID0gdGVzdFNlcS5jb21waWxlKGNsYXNzR2VuLCBtZXRob2RHZW4sCi0JCQkJCQkgYXR0ck5hbWVzcGFjZUhhbmRsZSk7Ci0JCWVsc2UKLQkJICAgIHRhcmdldHNbaV0gPSB0ZXN0U2VxLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbiwKLQkJCQkJCSBlbGVtTmFtZXNwYWNlSGFuZGxlKTsKLQkgICAgfQotCX0KLQotCS8vIEFwcGVuZCBmaXJzdCBjb2RlIGluIGFwcGx5VGVtcGxhdGVzKCkgLSBnZXQgdHlwZSBvZiBjdXJyZW50IG5vZGUKLQlib2R5LmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlib2R5LmFwcGVuZChuZXcgSUxPQUQoX2N1cnJlbnRJbmRleCkpOwotCWJvZHkuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoRE9NX0NMQVNTLAotCQkJCQkJICAgICAgICJnZXRUeXBlIiwgIihJKUkiKSkpOwotCQotCS8vIEFwcGVuZCBzd2l0Y2goKSBzdGF0ZW1lbnQgLSBtYWluIGRpc3BhdGNoIGxvb3AgaW4gYXBwbHlUZW1wbGF0ZXMoKQotCWJvZHkuYXBwZW5kKG5ldyBTV0lUQ0godHlwZXMsIHRhcmdldHMsIGloTG9vcCkpOwotCS8vIEFwcGVuZCBhbGwgdGhlICJjYXNlOiIgc3RhdGVtZW50cwotCWFwcGVuZFRlc3RTZXF1ZW5jZXMoYm9keSk7Ci0JLy8gQXBwZW5kIHRoZSBhY3R1YWwgdGVtcGxhdGUgY29kZQotCWFwcGVuZFRlbXBsYXRlQ29kZShib2R5KTsKLQotCS8vIEFwcGVuZCBOUzoqIG5vZGUgdGVzdHMgKGlmIGFueSkKLQlpZiAobnNFbGVtICE9IG51bGwpIGJvZHkuYXBwZW5kKG5zRWxlbSk7Ci0JLy8gQXBwZW5kIE5TOkAqIG5vZGUgdGVzdHMgKGlmIGFueSkKLQlpZiAobnNBdHRyICE9IG51bGwpIGJvZHkuYXBwZW5kKG5zQXR0cik7Ci0KLQkvLyBBcHBlbmQgZGVmYXVsdCBhY3Rpb24gZm9yIGVsZW1lbnQgYW5kIHJvb3Qgbm9kZXMKLQlib2R5LmFwcGVuZChpbFJlY3Vyc2UpOwotCS8vIEFwcGVuZCBkZWZhdWx0IGFjdGlvbiBmb3IgdGV4dCBhbmQgYXR0cmlidXRlIG5vZGVzCi0JYm9keS5hcHBlbmQoaWxUZXh0KTsKLQotCS8vIHB1dHRpbmcgdG9nZXRoZXIgY29uc3RpdHVlbnQgaW5zdHJ1Y3Rpb24gbGlzdHMKLQltYWluSUwuYXBwZW5kKG5ldyBHT1RPKGloTG9vcCkpOwotCW1haW5JTC5hcHBlbmQoYm9keSk7Ci0JLy8gZmFsbCB0aHJvdWdoIHRvIGlsTG9vcAotCW1haW5JTC5hcHBlbmQoaWxMb29wKTsKLQltYWluSUwuYXBwZW5kKFJFVFVSTik7Ci0KLQlwZWVwSG9sZU9wdGltaXphdGlvbihtZXRob2RHZW4pOwotCW1ldGhvZEdlbi5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0JCi0JbWV0aG9kR2VuLnNldE1heExvY2FscygpOwotCW1ldGhvZEdlbi5zZXRNYXhTdGFjaygpOwotCW1ldGhvZEdlbi5yZW1vdmVOT1BzKCk7Ci0JY2xhc3NHZW4uYWRkTWV0aG9kKG1ldGhvZEdlbi5nZXRNZXRob2QoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGVlcGhvbGUgb3B0aW1pemF0aW9uOiBSZW1vdmUgc2VxdWVuY2VzIG9mIFtBTE9BRCwgUE9QXS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcGVlcEhvbGVPcHRpbWl6YXRpb24oTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlGaW5kUGF0dGVybiBmaW5kID0gbmV3IEZpbmRQYXR0ZXJuKGlsKTsKLQlJbnN0cnVjdGlvbkhhbmRsZSBpaDsKLQlTdHJpbmcgcGF0dGVybjsKLQotCS8vIFJlbW92ZSBzZXF1ZW5jZXMgb2YgQUxPQUQsIFBPUAotCXBhdHRlcm4gPSAiYEFMT0FEJ2BQT1AnYEluc3RydWN0aW9uJyI7Ci0JaWggPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsKLQl3aGlsZSAoaWggIT0gbnVsbCkgewotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gZmluZC5nZXRNYXRjaCgpOwotCSAgICB0cnkgewotCQlpZiAoKCFtYXRjaFswXS5oYXNUYXJnZXRlcnMoKSkgJiYgKCFtYXRjaFsxXS5oYXNUYXJnZXRlcnMoKSkpIHsKLQkJICAgIGlsLmRlbGV0ZShtYXRjaFswXSwgbWF0Y2hbMV0pOwotCQl9Ci0JICAgIH0KLQkgICAgY2F0Y2ggKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotCQkvLyBUT0RPOiBtb3ZlIHRhcmdldCBkb3duIGludG8gdGhlIGxpc3QKLQkgICAgfQotCSAgICBpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4sIG1hdGNoWzJdKTsKLQl9Ci0KLQkvLyBSZXBsYWNlIHNlcXVlbmNlcyBvZiBJTE9BRF8/LCBBTE9BRF8/LCBTV0FQIHdpdGggQUxPQURfPywgSUxPQURfPwotCXBhdHRlcm4gPSAiYElMT0FEX18nYEFMT0FEX18nYFNXQVAnYEluc3RydWN0aW9uJyI7Ci0JaWggPSBmaW5kLnNlYXJjaChwYXR0ZXJuKTsKLQl3aGlsZSAoaWggIT0gbnVsbCkgewotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZVtdIG1hdGNoID0gZmluZC5nZXRNYXRjaCgpOwotCSAgICB0cnkgewotCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBpbG9hZDsKLQkJZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuSW5zdHJ1Y3Rpb24gYWxvYWQ7Ci0JCWlmICgoIW1hdGNoWzBdLmhhc1RhcmdldGVycygpKSAmJgotCQkgICAgKCFtYXRjaFsxXS5oYXNUYXJnZXRlcnMoKSkgJiYKLQkJICAgICghbWF0Y2hbMl0uaGFzVGFyZ2V0ZXJzKCkpKSB7Ci0JCSAgICBpbG9hZCA9IG1hdGNoWzBdLmdldEluc3RydWN0aW9uKCk7Ci0JCSAgICBhbG9hZCA9IG1hdGNoWzFdLmdldEluc3RydWN0aW9uKCk7Ci0JCSAgICBpbC5pbnNlcnQobWF0Y2hbMF0sIGFsb2FkKTsKLQkJICAgIGlsLmluc2VydChtYXRjaFswXSwgaWxvYWQpOwotCQkgICAgaWwuZGVsZXRlKG1hdGNoWzBdLCBtYXRjaFsyXSk7Ci0JCX0KLQkgICAgfQotCSAgICBjYXRjaCAoVGFyZ2V0TG9zdEV4Y2VwdGlvbiBlKSB7Ci0JCS8vIFRPRE86IG1vdmUgdGFyZ2V0IGRvd24gaW50byB0aGUgbGlzdAotCSAgICB9Ci0JICAgIGloID0gZmluZC5zZWFyY2gocGF0dGVybiwgbWF0Y2hbM10pOwotCX0KLQotCS8vIFJlcGxhY2VzIHNlcXVlbmNlcyBvZiBBTE9BRF8xLCBBTE9BRF8xIHdpdGggQUxPQURfMSwgRFVQCi0JcGF0dGVybiA9ICJgQUxPQURfMSdgQUxPQURfMSdgSW5zdHJ1Y3Rpb24nIjsKLQlpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4pOwotCXdoaWxlIChpaCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSBmaW5kLmdldE1hdGNoKCk7Ci0JICAgIHRyeSB7Ci0JCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLkluc3RydWN0aW9uIGlsb2FkOwotCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBhbG9hZDsKLQkJaWYgKCghbWF0Y2hbMF0uaGFzVGFyZ2V0ZXJzKCkpICYmICghbWF0Y2hbMV0uaGFzVGFyZ2V0ZXJzKCkpKSB7Ci0JCSAgICBpbC5pbnNlcnQobWF0Y2hbMV0sIG5ldyBEVVAoKSk7Ci0JCSAgICBpbC5kZWxldGUobWF0Y2hbMV0pOwotCQl9Ci0JICAgIH0KLQkgICAgY2F0Y2ggKFRhcmdldExvc3RFeGNlcHRpb24gZSkgewotCQkvLyBUT0RPOiBtb3ZlIHRhcmdldCBkb3duIGludG8gdGhlIGxpc3QKLQkgICAgfQotCSAgICBpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4sIG1hdGNoWzJdKTsKLQl9Ci0KLQkvLyBSZW1vdmVzIHVuY2Vzc2VjYXJ5IEdPVE9zCi0JcGF0dGVybiA9ICJgR09UTydgR09UTydgSW5zdHJ1Y3Rpb24nIjsKLQlpaCA9IGZpbmQuc2VhcmNoKHBhdHRlcm4pOwotCXdoaWxlIChpaCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSBmaW5kLmdldE1hdGNoKCk7Ci0JICAgIHRyeSB7Ci0JCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLkluc3RydWN0aW9uIGlsb2FkOwotCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBhbG9hZDsKLQkJSW5zdHJ1Y3Rpb25UYXJnZXRlciB0Z3Ryc1tdID0gbWF0Y2hbMV0uZ2V0VGFyZ2V0ZXJzKCk7Ci0JCWlmICh0Z3RycyAhPSBudWxsKSB7Ci0JCSAgICBJbnN0cnVjdGlvbkhhbmRsZSBuZXdUYXJnZXQgPQotCQkJKChCcmFuY2hIYW5kbGUpbWF0Y2hbMV0pLmdldFRhcmdldCgpOwotCQkgICAgZm9yIChpbnQgaT0wOyBpPHRndHJzLmxlbmd0aDsgaSsrKQotCQkJdGd0cnNbaV0udXBkYXRlVGFyZ2V0KG1hdGNoWzFdLG5ld1RhcmdldCk7Ci0JCX0KLQkJaWwuZGVsZXRlKG1hdGNoWzFdKTsKLQkgICAgfQotCSAgICBjYXRjaCAoVGFyZ2V0TG9zdEV4Y2VwdGlvbiBlKSB7Ci0JCS8vIFRPRE86IG1vdmUgdGFyZ2V0IGRvd24gaW50byB0aGUgbGlzdAotCSAgICB9Ci0JICAgIGloID0gZmluZC5zZWFyY2gocGF0dGVybiwgbWF0Y2hbMl0pOwotCX0KLQkKLQkKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0VGVtcGxhdGVJbnN0cnVjdGlvbkhhbmRsZShUZW1wbGF0ZSB0ZW1wbGF0ZSkgewotCXJldHVybiAoSW5zdHJ1Y3Rpb25IYW5kbGUpX3RlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGVzLmdldCh0ZW1wbGF0ZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTmFtZUJhc2UuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL05hbWVCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEwODNhOGIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTmFtZUJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2MiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWNsYXNzIE5hbWVCYXNlIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfcGFyYW0gPSBudWxsOwotICAgIHByaXZhdGUgVHlwZSAgICAgICBfdHlwZSA9IFR5cGUuTm9kZTsKLQotICAgIC8qKgotICAgICAqIEhhbmRsZXMgY2FsbHMgd2l0aCBubyBwYXJhbWV0ZXIgKGN1cnJlbnQgbm9kZSBpcyBpbXBsaWNpdCBwYXJhbWV0ZXIpLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lQmFzZShRTmFtZSBmbmFtZSkgewotCXN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGVzIGNhbGxzIHdpdGggb25lIHBhcmFtZXRlciAoZWl0aGVyIG5vZGUgb3Igbm9kZS1zZXQpLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lQmFzZShRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotCV9wYXJhbSA9IGFyZ3VtZW50KDApOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogQ2hlY2sgdGhhdCB3ZSBlaXRoZXIgaGF2ZSBubyBwYXJhbWV0ZXJzIG9yIG9uZSBwYXJhbWV0ZXIgdGhhdCBpcwotICAgICAqIGVpdGhlciBhIG5vZGUgb3IgYSBub2RlLXNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCi0JLy8gQ2hlY2sgdGhlIGFyZ3VtZW50IHR5cGUgKGlmIGFueSkKLQlzd2l0Y2goYXJndW1lbnRDb3VudCgpKSB7Ci0JY2FzZSAwOgotCSAgICBfdHlwZSA9IFR5cGUuTm9kZTsKLQkgICAgYnJlYWs7Ci0JY2FzZSAxOgotCSAgICBfdHlwZSA9IF9wYXJhbS50eXBlQ2hlY2soc3RhYmxlKTsKLQkgICAgYnJlYWs7Ci0JZGVmYXVsdDoKLQkgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotCX0KLQotCS8vIFRoZSBhcmd1bWVudCBoYXMgdG8gYmUgYSBub2RlLCBhIG5vZGUtc2V0IG9yIGEgbm9kZSByZWZlcmVuY2UKLQlpZiAoKF90eXBlICE9IFR5cGUuTm9kZVNldCkgJiYKLQkgICAgKF90eXBlICE9IFR5cGUuTm9kZSkgJiYKLQkgICAgKF90eXBlICE9IFR5cGUuUmVmZXJlbmNlKSkgewotCSAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IodGhpcyk7Ci0JfQotCi0JcmV0dXJuIFR5cGUuU3RyaW5nOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIGdldFR5cGUoKSB7Ci0JcmV0dXJuIFR5cGUuU3RyaW5nOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIHRoZSBjb2RlIHJlcXVpcmVkIGZvciBnZXR0aW5nIHRoZSBub2RlIGZvciB3aGljaCB0aGUKLSAgICAgKiBRTmFtZSwgbG9jYWwtbmFtZSBvciBuYW1lc3BhY2UgVVJJIHNob3VsZCBiZSBleHRyYWN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkKLQkvLyBGdW5jdGlvbiB3YXMgY2FsbGVkIHdpdGggbm8gcGFyYW1ldGVycwotCWlmIChhcmd1bWVudENvdW50KCkgPT0gMCkgewotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQl9Ci0JLy8gRnVuY3Rpb24gd2FzIGNhbGxlZCB3aXRoIG5vZGUgcGFyYW1ldGVyCi0JZWxzZSBpZiAoX3R5cGUgPT0gVHlwZS5Ob2RlKSB7Ci0JICAgIF9wYXJhbS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCWVsc2UgaWYgKF90eXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0JICAgIF9wYXJhbS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNwZy5hZGRNZXRob2RyZWYKLQkJCQkgICAgICAgKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCSJyZWZlcmVuY2VUb05vZGVTZXQiLAotCQkJCQkiKExqYXZhL2xhbmcvT2JqZWN0OykiICsKLQkJCQkJIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjLyIgKwotCQkJCQkiTm9kZUl0ZXJhdG9yOyIpKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubmV4dE5vZGUoKSk7Ci0JfQotCS8vIEZ1bmN0aW9uIHdhcyBjYWxsZWQgd2l0aCBub2RlLXNldCBwYXJhbWV0ZXIKLQllbHNlIHsKLQkgICAgX3BhcmFtLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX3BhcmFtLnN0YXJ0UmVzZXRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTmFtZUNhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL05hbWVDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU4YmVjYmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTmFtZUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotCi1maW5hbCBjbGFzcyBOYW1lQ2FsbCBleHRlbmRzIE5hbWVCYXNlIHsKLQotICAgIC8qKgotICAgICAqIEhhbmRsZXMgY2FsbHMgd2l0aCBubyBwYXJhbWV0ZXIgKGN1cnJlbnQgbm9kZSBpcyBpbXBsaWNpdCBwYXJhbWV0ZXIpLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lQ2FsbChRTmFtZSBmbmFtZSkgewotCXN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIYW5kbGVzIGNhbGxzIHdpdGggb25lIHBhcmFtZXRlciAoZWl0aGVyIG5vZGUgb3Igbm9kZS1zZXQpLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBjb2RlIHRoYXQgbGVhdmVzIGEgbm9kZSdzIFFOYW1lIChhcyBhIFN0cmluZykgb24gdGhlIHN0YWNrCi0gICAgICovIAotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlmaW5hbCBpbnQgZ2V0TmFtZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgICBHRVRfTk9ERV9OQU1FLAotCQkJCQkJICAgICAgR0VUX05PREVfTkFNRV9TSUcpOwotCXN1cGVyLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXROYW1lLCAyKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTmFtZXNwYWNlQWxpYXMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZUFsaWFzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE4OGVlYzguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTmFtZXNwYWNlQWxpYXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIE5hbWVzcGFjZUFsaWFzIGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIHByaXZhdGUgU3RyaW5nIHNQcmVmaXg7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgclByZWZpeDsKLQkKLSAgICAvKgotICAgICAqIFRoZSBuYW1lc3BhY2UgYWxpYXMgZGVmaW5pdGlvbnMgZ2l2ZW4gaGVyZSBoYXZlIGFuIGltcGFjdCBvbmx5IG9uCi0gICAgICogbGl0ZXJhbCBlbGVtZW50cyBhbmQgbGl0ZXJhbCBhdHRyaWJ1dGVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCXNQcmVmaXggPSBnZXRBdHRyaWJ1dGUoInN0eWxlc2hlZXQtcHJlZml4Iik7Ci0JclByZWZpeCA9IGdldEF0dHJpYnV0ZSgicmVzdWx0LXByZWZpeCIpOwotCXBhcnNlci5nZXRTeW1ib2xUYWJsZSgpLmFkZFByZWZpeEFsaWFzKHNQcmVmaXgsclByZWZpeCk7Ci0gICAgfQotCQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0JCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JLy8gZG8gbmFkYQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZVVyaUNhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL05hbWVzcGFjZVVyaUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmU0OGY5Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9OYW1lc3BhY2VVcmlDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBOYW1lc3BhY2VVcmlDYWxsIGV4dGVuZHMgTmFtZUJhc2UgewotCi0gICAgLyoqCi0gICAgICogSGFuZGxlcyBjYWxscyB3aXRoIG5vIHBhcmFtZXRlciAoY3VycmVudCBub2RlIGlzIGltcGxpY2l0IHBhcmFtZXRlcikuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZVVyaUNhbGwoUU5hbWUgZm5hbWUpIHsKLQlzdXBlcihmbmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSGFuZGxlcyBjYWxscyB3aXRoIG9uZSBwYXJhbWV0ZXIgKGVpdGhlciBub2RlIG9yIG5vZGUtc2V0KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgTmFtZXNwYWNlVXJpQ2FsbChRTmFtZSBmbmFtZSwgVmVjdG9yIGFyZ3VtZW50cykgewotCXN1cGVyKGZuYW1lLCBhcmd1bWVudHMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBjb2RlIHRoYXQgbGVhdmVzIGEgbm9kZSdzIG5hbWVzcGFjZSBVUkkgKGFzIGEgU3RyaW5nKQotICAgICAqIG9uIHRoZSBzdGFjawotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgZm9yIGEgbm9kZSBpbiB0aGUgRE9NCi0JZmluYWwgaW50IGdldE5hbWVzcGFjZSA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkJICAgImdldE5hbWVzcGFjZU5hbWUiLAotCQkJCQkJCSAgICIoSSkiK1NUUklOR19TSUcpOwotCXN1cGVyLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXROYW1lc3BhY2UsIDIpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Ob2RlVGVzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTm9kZVRlc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzkyZWIxYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Ob2RlVGVzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLQotcHVibGljIGludGVyZmFjZSBOb2RlVGVzdCB7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVYVCAgICAgID0gRE9NLlRFWFQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NTUVOVCAgID0gRE9NLkNPTU1FTlQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEkgICAgICAgID0gRE9NLlBST0NFU1NJTkdfSU5TVFJVQ1RJT047Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9PVCAgICAgID0gRE9NLlJPT1Q7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUxFTUVOVCAgID0gRE9NLkVMRU1FTlQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRUUklCVVRFID0gRE9NLkFUVFJJQlVURTsKLSAgICAKLSAgICAvLyBnZW5lcmFsaXplZCB0eXBlCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR1RZUEUgICAgID0gRE9NLk5UWVBFUzsKLSAgICAKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTk9ERSAgICAgPSBET00uRklSU1RfVFlQRSAtIDE7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Ob3RDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Ob3RDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4NmNhNzAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTm90Q2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIE5vdENhbGwgZXh0ZW5kcyBGdW5jdGlvbkNhbGwgewotICAgIHB1YmxpYyBOb3RDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWFyZ3VtZW50KCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChJQ09OU1RfMSk7Ci0JaWwuYXBwZW5kKElYT1IpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgRXhwcmVzc2lvbiBleHAgPSBhcmd1bWVudCgpOwotCWV4cC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBnb3RvaCA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JX3RydWVMaXN0ID0gZXhwLl9mYWxzZUxpc3Q7IAkvLyBzd2FwIGZsb3cgbGlzdHMKLQlfZmFsc2VMaXN0ID0gZXhwLl90cnVlTGlzdDsKLQlfZmFsc2VMaXN0LmFkZChnb3RvaCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTnVtYmVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9OdW1iZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjdmYzkwNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9OdW1iZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU1MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuSmF2YUNsYXNzOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5GaWVsZDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBOdW1iZXIgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFVkVMX1NJTkdMRSAgID0gMDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEVWRUxfTVVMVElQTEUgPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMRVZFTF9BTlkgICAgICA9IDI7Ci0KLSAgICBwcml2YXRlIFBhdHRlcm4gX2Zyb20gPSBudWxsOwotICAgIHByaXZhdGUgUGF0dGVybiBfY291bnQgPSBudWxsOwotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfdmFsdWUgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9sYW5nID0gbnVsbDsKLSAgICBwcml2YXRlIEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUgX2Zvcm1hdCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9sZXR0ZXJWYWx1ZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9ncm91cGluZ1NlcGFyYXRvciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9ncm91cGluZ1NpemUgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBpbnQgX2xldmVsID0gTEVWRUxfU0lOR0xFOwotICAgIHByaXZhdGUgYm9vbGVhbiBfZm9ybWF0TmVlZGVkID0gZmFsc2U7Ci0KLSAgICBzdGF0aWMgZmluYWwgcHJpdmF0ZSBTdHJpbmdbXSBDbGFzc05hbWVzID0geyAKLQkib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uU2luZ2xlTm9kZUNvdW50ZXIiLAkgIC8vIExFVkVMX1NJTkdMRQotCSJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5NdWx0aXBsZU5vZGVDb3VudGVyIiwgLy8gTEVWRUxfTVVMVElQTEUKLQkib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uQW55Tm9kZUNvdW50ZXIiCSAgLy8gTEVWRUxfQU5ZCi0gICAgfTsKLQotICAgIHN0YXRpYyBmaW5hbCBwcml2YXRlIFN0cmluZ1tdIEZpZWxkTmFtZXMgPSB7IAotCSJfX19zaW5nbGVfbm9kZV9jb3VudGVyIiwJCSAgIC8vIExFVkVMX1NJTkdMRQotCSJfX19tdWx0aXBsZV9ub2RlX2NvdW50ZXIiLAkJICAgLy8gTEVWRUxfTVVMVElQTEUKLQkiX19fYW55X25vZGVfY291bnRlciIJCQkgICAvLyBMRVZFTF9BTlkKLSAgICB9OwotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JZmluYWwgaW50IGNvdW50ID0gX2F0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0KLQlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLQkgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBfYXR0cmlidXRlcy5nZXRRTmFtZShpKTsKLQkgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gX2F0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7Ci0KLQkgICAgaWYgKG5hbWUuZXF1YWxzKCJ2YWx1ZSIpKSB7Ci0JCV92YWx1ZSA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgbmFtZSwgbnVsbCk7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImNvdW50IikpIHsKLQkJX2NvdW50ID0gcGFyc2VyLnBhcnNlUGF0dGVybih0aGlzLCBuYW1lLCBudWxsKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygiZnJvbSIpKSB7Ci0JCV9mcm9tID0gcGFyc2VyLnBhcnNlUGF0dGVybih0aGlzLCBuYW1lLCBudWxsKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibGV2ZWwiKSkgewotCQlpZiAodmFsdWUuZXF1YWxzKCJzaW5nbGUiKSkgewotCQkgICAgX2xldmVsID0gTEVWRUxfU0lOR0xFOwotCQl9Ci0JCWVsc2UgaWYgKHZhbHVlLmVxdWFscygibXVsdGlwbGUiKSkgewotCQkgICAgX2xldmVsID0gTEVWRUxfTVVMVElQTEU7Ci0JCX0KLQkJZWxzZSBpZiAodmFsdWUuZXF1YWxzKCJhbnkiKSkgewotCQkgICAgX2xldmVsID0gTEVWRUxfQU5ZOwotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImZvcm1hdCIpKSB7Ci0JCV9mb3JtYXQgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSh2YWx1ZSwgcGFyc2VyKTsKLQkJX2Zvcm1hdE5lZWRlZCA9IHRydWU7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImxhbmciKSkgewotCQlfbGFuZyA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKHZhbHVlLCBwYXJzZXIpOwotCQlfZm9ybWF0TmVlZGVkID0gdHJ1ZTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscygibGV0dGVyLXZhbHVlIikpIHsKLQkJX2xldHRlclZhbHVlID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUodmFsdWUsIHBhcnNlcik7Ci0JCV9mb3JtYXROZWVkZWQgPSB0cnVlOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKCJncm91cGluZy1zZXBhcmF0b3IiKSkgewotCQlfZ3JvdXBpbmdTZXBhcmF0b3IgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZSh2YWx1ZSwgcGFyc2VyKTsKLQkJX2Zvcm1hdE5lZWRlZCA9IHRydWU7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoImdyb3VwaW5nLXNpemUiKSkgewotCQlfZ3JvdXBpbmdTaXplID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUodmFsdWUsIHBhcnNlcik7Ci0JCV9mb3JtYXROZWVkZWQgPSB0cnVlOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKF92YWx1ZSAhPSBudWxsKSB7Ci0JICAgIFR5cGUgdHZhbHVlID0gX3ZhbHVlLnR5cGVDaGVjayhzdGFibGUpOwotCSAgICBpZiAodHZhbHVlIGluc3RhbmNlb2YgUmVhbFR5cGUgPT0gZmFsc2UpIHsKLQkJX3ZhbHVlID0gbmV3IENhc3RFeHByKF92YWx1ZSwgVHlwZS5SZWFsKTsKLQkgICAgfQotCX0KLQlpZiAoX2NvdW50ICE9IG51bGwpIHsKLQkgICAgX2NvdW50LnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQlpZiAoX2Zyb20gIT0gbnVsbCkgewotCSAgICBfZnJvbS50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JaWYgKF9mb3JtYXQgIT0gbnVsbCkgewotCSAgICBfZm9ybWF0LnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQlpZiAoX2xhbmcgIT0gbnVsbCkgewotCSAgICBfbGFuZy50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JaWYgKF9sZXR0ZXJWYWx1ZSAhPSBudWxsKSB7Ci0JICAgIF9sZXR0ZXJWYWx1ZS50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JaWYgKF9ncm91cGluZ1NlcGFyYXRvciAhPSBudWxsKSB7Ci0JICAgIF9ncm91cGluZ1NlcGFyYXRvci50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JaWYgKF9ncm91cGluZ1NpemUgIT0gbnVsbCkgewotCSAgICBfZ3JvdXBpbmdTaXplLnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRydWUgaWYgdGhlIGhhcyBzcGVjaWZpZWQgYSB2YWx1ZSBmb3IgdGhpcyBpbnN0YW5jZSBvZiBudW1iZXIuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7Ci0JcmV0dXJuIF92YWx1ZSAhPSBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIGluc3RhbmNlIG9mIG51bWJlciBoYXMgbmVpdGhlcgotICAgICAqIGEgZnJvbSBub3IgYSBjb3VudCBwYXR0ZXJuLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzRGVmYXVsdCgpIHsKLQlyZXR1cm4gX2Zyb20gPT0gbnVsbCAmJiBfY291bnQgPT0gbnVsbDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZURlZmF1bHQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlpbnQgaW5kZXg7Ci0JQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWludFtdIGZpZWxkSW5kZXhlcyA9IGdldFhTTFRDKCkuZ2V0TnVtYmVyRmllbGRJbmRleGVzKCk7Ci0KLQlpZiAoZmllbGRJbmRleGVzW19sZXZlbF0gPT0gLTEpIHsKLQkgICAgRmllbGQgZGVmYXVsdE5vZGUgPSBuZXcgRmllbGQoQUNDX1BSSVZBVEUsIAotCQkJCQkgIGNwZy5hZGRVdGY4KEZpZWxkTmFtZXNbX2xldmVsXSksCi0JCQkJCSAgY3BnLmFkZFV0ZjgoTk9ERV9DT1VOVEVSX1NJRyksCi0JCQkJCSAgbnVsbCwgCi0JCQkJCSAgY3BnLmdldENvbnN0YW50UG9vbCgpKTsKLQotCSAgICAvLyBBZGQgYSBuZXcgcHJpdmF0ZSBmaWVsZCB0byB0aGlzIGNsYXNzCi0JICAgIGNsYXNzR2VuLmFkZEZpZWxkKGRlZmF1bHROb2RlKTsKLQotCSAgICAvLyBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIG5ld2x5IGFkZGVkIGZpZWxkCi0JICAgIGZpZWxkSW5kZXhlc1tfbGV2ZWxdID0gY3BnLmFkZEZpZWxkcmVmKGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLCAKLQkJCQkJCSAgIEZpZWxkTmFtZXNbX2xldmVsXSwKLQkJCQkJCSAgIE5PREVfQ09VTlRFUl9TSUcpOwotCX0KLQotCS8vIENoZWNrIGlmIGZpZWxkIGlzIGluaXRpYWxpemVkIChydW50aW1lKQotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChmaWVsZEluZGV4ZXNbX2xldmVsXSkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrMSA9IGlsLmFwcGVuZChuZXcgSUZOT05OVUxMKG51bGwpKTsKLQotCS8vIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBEZWZhdWx0Tm9kZUNvdW50ZXIKLQlpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQ2xhc3NOYW1lc1tfbGV2ZWxdLAotCQkJCSAiZ2V0RGVmYXVsdE5vZGVDb3VudGVyIiwgCi0JCQkJICIoIiArIFRSQU5TTEVUX0lOVEZfU0lHCi0JCQkJICsgRE9NX0lOVEZfU0lHCi0JCQkJICsgTk9ERV9JVEVSQVRPUl9TSUcgCi0JCQkJICsgIikiICsgTk9ERV9DT1VOVEVSX1NJRyk7Ci0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQotCS8vIFN0b3JlIHRoZSBub2RlIGNvdW50ZXIgaW4gdGhlIGZpZWxkCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQoU1dBUCk7Ci0JaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChmaWVsZEluZGV4ZXNbX2xldmVsXSkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBpZkJsb2NrMiA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0KLQkvLyBCYWNrcGF0Y2ggY29uZGl0aW9uYWxzCi0JaWZCbG9jazEuc2V0VGFyZ2V0KGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSkpOwotCWlsLmFwcGVuZChuZXcgR0VURklFTEQoZmllbGRJbmRleGVzW19sZXZlbF0pKTsKLQkKLQlpZkJsb2NrMi5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGEgY29uc3RydWN0b3IgZm9yIHRoZSBjbGFzcyA8dHQ+Y2xhc3NOYW1lPC90dD4gdGhhdAotICAgICAqIGluaGVyaXRzIGZyb20ge0FueSxTaW5nbGUsTXVsdGlwbGV9Tm9kZUNvdW50ZXIuIFRoaXMgY29uc3RydWN0b3IKLSAgICAgKiBzaW1wbHkgY2FsbHMgdGhlIHNhbWUgY29uc3RydWN0b3IgaW4gdGhlIHN1cGVyIGNsYXNzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb21waWxlQ29uc3RydWN0b3IoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lKSB7Ci0JTWV0aG9kR2VuZXJhdG9yIGNvbnM7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQotCWNvbnMgPSBuZXcgTWV0aG9kR2VuZXJhdG9yKEFDQ19QVUJMSUMsCi0JCQkJICAgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5WT0lELCAKLQkJCQkgICBuZXcgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVtdIHsKLQkJCQkgICAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfSU5URl9TSUcpLAotCQkJCSAgICAgICBVdGlsLmdldEpDUmVmVHlwZShET01fSU5URl9TSUcpLAotCQkJCSAgICAgICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRykKLQkJCQkgICB9LAotCQkJCSAgIG5ldyBTdHJpbmdbXSB7Ci0JCQkJICAgICAgICJkb20iLAotCQkJCSAgICAgICAidHJhbnNsZXQiLAotCQkJCSAgICAgICAiaXRlcmF0b3IiCi0JCQkJICAgfSwKLQkJCQkgICAiPGluaXQ+IiwgY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotCWlsLmFwcGVuZChBTE9BRF8wKTsgICAgIC8vIHRoaXMKLQlpbC5hcHBlbmQoQUxPQURfMSk7ICAgICAvLyB0cmFuc2xldAotCWlsLmFwcGVuZChBTE9BRF8yKTsgICAgIC8vIERPTQotCWlsLmFwcGVuZChuZXcgQUxPQUQoMykpOy8vIGl0ZXJhdG9yCi0KLQlpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKENsYXNzTmFtZXNbX2xldmVsXSwKLQkJCQkgICAgICI8aW5pdD4iLCAKLQkJCQkgICAgICIoIiArIFRSQU5TTEVUX0lOVEZfU0lHCi0JCQkJICAgICArIERPTV9JTlRGX1NJRwotCQkJCSAgICAgKyBOT0RFX0lURVJBVE9SX1NJRyAKLQkJCQkgICAgICsgIilWIik7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0JaWwuYXBwZW5kKFJFVFVSTik7Ci0JCi0JY29ucy5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0JY29ucy5zZXRNYXhMb2NhbHMoKTsKLQljb25zLnNldE1heFN0YWNrKCk7Ci0JY2xhc3NHZW4uYWRkTWV0aG9kKGNvbnMuZ2V0TWV0aG9kKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGNvbXBpbGVzIGNvZGUgdGhhdCBpcyBjb21tb24gdG8gbWF0Y2hlc0Zyb20oKSBhbmQKLSAgICAgKiBtYXRjaGVzQ291bnQoKSBpbiB0aGUgYXV4aWxsYXJ5IGNsYXNzLgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjb21waWxlTG9jYWxzKE5vZGVDb3VudGVyR2VuZXJhdG9yIG5vZGVDb3VudGVyR2VuLAotCQkJICAgICAgIE1hdGNoR2VuZXJhdG9yIG1hdGNoR2VuLAotCQkJICAgICAgIEluc3RydWN0aW9uTGlzdCBpbCkgewotCi0JQ29uc3RhbnRQb29sR2VuIGNwZyA9IG5vZGVDb3VudGVyR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBtYXRjaEdlbi5nZXRDbGFzc05hbWUoKTsKLQotCUxvY2FsVmFyaWFibGVHZW4gbG9jYWw7Ci0JaW50IGZpZWxkOwotCi0JLy8gR2V0IE5vZGVDb3VudGVyLl9pdGVyYXRvciBhbmQgc3RvcmUgbG9jYWxseQotCWxvY2FsID0gbWF0Y2hHZW4uYWRkTG9jYWxWYXJpYWJsZSgiaXRlcmF0b3IiLCAKLQkJCQkJICBVdGlsLmdldEpDUmVmVHlwZShOT0RFX0lURVJBVE9SX1NJRyksCi0JCQkJCSAgbnVsbCwgbnVsbCk7Ci0JZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoTk9ERV9DT1VOVEVSLCAiX2l0ZXJhdG9yIiwKLQkJCQlJVEVSQVRPUl9GSUVMRF9TSUcpOwotCWlsLmFwcGVuZChBTE9BRF8wKTsgLy8gJ3RoaXMnIHBvaW50ZXIgb24gc3RhY2sKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGZpZWxkKSk7Ci0JaWwuYXBwZW5kKG5ldyBBU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSkpOwotCW1hdGNoR2VuLnNldEl0ZXJhdG9ySW5kZXgobG9jYWwuZ2V0SW5kZXgoKSk7Ci0JCi0JLy8gR2V0IE5vZGVDb3VudGVyLl90cmFuc2xldCBhbmQgc3RvcmUgbG9jYWxseQotCWxvY2FsID0gbWF0Y2hHZW4uYWRkTG9jYWxWYXJpYWJsZSgidHJhbnNsZXQiLCAKLQkJCQkgIFV0aWwuZ2V0SkNSZWZUeXBlKCJMb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9UcmFuc2xldDsiKSwKLQkJCQkgIG51bGwsIG51bGwpOwotCWZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKE5PREVfQ09VTlRFUiwgIl90cmFuc2xldCIsCi0JCQkJIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1RyYW5zbGV0OyIpOwotCWlsLmFwcGVuZChBTE9BRF8wKTsgLy8gJ3RoaXMnIHBvaW50ZXIgb24gc3RhY2sKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGZpZWxkKSk7Ci0JaWwuYXBwZW5kKG5ldyBBU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSkpOwotCW5vZGVDb3VudGVyR2VuLnNldFRyYW5zbGV0SW5kZXgobG9jYWwuZ2V0SW5kZXgoKSk7Ci0KLQkvLyBHZXQgTm9kZUNvdW50ZXIuX2RvY3VtZW50IGFuZCBzdG9yZSBsb2NhbGx5Ci0JbG9jYWwgPSBtYXRjaEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJkb2N1bWVudCIsIAotCQkJCQkgIFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyksCi0JCQkJCSAgbnVsbCwgbnVsbCk7Ci0JZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoY2xhc3NOYW1lLCAiX2RvY3VtZW50IiwgRE9NX0lOVEZfU0lHKTsKLQlpbC5hcHBlbmQoQUxPQURfMCk7IC8vICd0aGlzJyBwb2ludGVyIG9uIHN0YWNrCi0JaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChmaWVsZCkpOwotCS8vIE1ha2Ugc3VyZSB3ZSBoYXZlIHRoZSBjb3JyZWN0IERPTSB0eXBlIG9uIHRoZSBzdGFjayEhIQotCWlsLmFwcGVuZChuZXcgQVNUT1JFKGxvY2FsLmdldEluZGV4KCkpKTsKLQltYXRjaEdlbi5zZXREb21JbmRleChsb2NhbC5nZXRJbmRleCgpKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZVBhdHRlcm5zKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JLy8hISEgIGxvY2FsIHZhcmlhYmxlcz8KLQlpbnQgY3VycmVudDsKLQlpbnQgZmllbGQ7Ci0JTG9jYWxWYXJpYWJsZUdlbiBsb2NhbDsKLQlNYXRjaEdlbmVyYXRvciBtYXRjaEdlbjsKLQlOb2RlQ291bnRlckdlbmVyYXRvciBub2RlQ291bnRlckdlbjsKLQotCWZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBnZXRYU0xUQygpLmdldEhlbHBlckNsYXNzTmFtZSgpOwotCW5vZGVDb3VudGVyR2VuID0gbmV3IE5vZGVDb3VudGVyR2VuZXJhdG9yKGNsYXNzTmFtZSwKLQkJCQkJCSAgQ2xhc3NOYW1lc1tfbGV2ZWxdLAotCQkJCQkJICB0b1N0cmluZygpLCAKLQkJCQkJCSAgQUNDX1BVQkxJQyB8IEFDQ19TVVBFUiwKLQkJCQkJCSAgbnVsbCwKLQkJCQkJCSAgY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpKTsKLQlJbnN0cnVjdGlvbkxpc3QgaWwgPSBudWxsOwotCUNvbnN0YW50UG9vbEdlbiBjcGcgPSBub2RlQ291bnRlckdlbi5nZXRDb25zdGFudFBvb2woKTsKLQotCS8vIEFkZCBhIHNpbmdsZSBjb25zdHJ1Y3RvciB0byB0aGUgY2xhc3MKLQljb21waWxlQ29uc3RydWN0b3Iobm9kZUNvdW50ZXJHZW4sIGNsYXNzTmFtZSk7Ci0KLQkvKgotCSAqIENvbXBpbGUgbWV0aG9kIG1hdGNoZXNGcm9tKCkKLQkgKi8KLQlpZiAoX2Zyb20gIT0gbnVsbCkgewotCSAgICBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQkgICAgbWF0Y2hHZW4gPQotCQluZXcgTWF0Y2hHZW5lcmF0b3IoQUNDX1BVQkxJQyB8IEFDQ19GSU5BTCwKLQkJCQkgICBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLkJPT0xFQU4sIAotCQkJCSAgIG5ldyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlW10gewotCQkJCSAgICAgICBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLklOVCwKLQkJCQkgICB9LAotCQkJCSAgIG5ldyBTdHJpbmdbXSB7Ci0JCQkJICAgICAgICJub2RlIiwKLQkJCQkgICB9LAotCQkJCSAgICJtYXRjaGVzRnJvbSIsIGNsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLQkgICAgY29tcGlsZUxvY2Fscyhub2RlQ291bnRlckdlbixtYXRjaEdlbixpbCk7Ci0KLQkgICAgLy8gVHJhbnNsYXRlIFBhdHRlcm4KLQkgICAgaWwuYXBwZW5kKG1hdGNoR2VuLmxvYWRDb250ZXh0Tm9kZSgpKTsKLQkgICAgX2Zyb20udHJhbnNsYXRlKG5vZGVDb3VudGVyR2VuLCBtYXRjaEdlbik7Ci0JICAgIF9mcm9tLnN5bnRoZXNpemUobm9kZUNvdW50ZXJHZW4sIG1hdGNoR2VuKTsKLQkgICAgaWwuYXBwZW5kKElSRVRVUk4pOwotCQkgICAgCi0JICAgIG1hdGNoR2VuLnN0cmlwQXR0cmlidXRlcyh0cnVlKTsKLQkgICAgbWF0Y2hHZW4uc2V0TWF4TG9jYWxzKCk7Ci0JICAgIG1hdGNoR2VuLnNldE1heFN0YWNrKCk7Ci0JICAgIG1hdGNoR2VuLnJlbW92ZU5PUHMoKTsKLQkgICAgbm9kZUNvdW50ZXJHZW4uYWRkTWV0aG9kKG1hdGNoR2VuLmdldE1ldGhvZCgpKTsKLQl9Ci0KLQkvKgotCSAqIENvbXBpbGUgbWV0aG9kIG1hdGNoZXNDb3VudCgpCi0JICovCi0JaWYgKF9jb3VudCAhPSBudWxsKSB7Ci0JICAgIGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCSAgICBtYXRjaEdlbiA9IG5ldyBNYXRjaEdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMLAotCQkJCQkgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuQk9PTEVBTiwgCi0JCQkJCSAgbmV3IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbXSB7Ci0JCQkJCSAgICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJCQkgIH0sCi0JCQkJCSAgbmV3IFN0cmluZ1tdIHsKLQkJCQkJICAgICAgIm5vZGUiLAotCQkJCQkgIH0sCi0JCQkJCSAgIm1hdGNoZXNDb3VudCIsIGNsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLQkgICAgY29tcGlsZUxvY2Fscyhub2RlQ291bnRlckdlbixtYXRjaEdlbixpbCk7Ci0JICAgIAotCSAgICAvLyBUcmFuc2xhdGUgUGF0dGVybgotCSAgICBpbC5hcHBlbmQobWF0Y2hHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCSAgICBfY291bnQudHJhbnNsYXRlKG5vZGVDb3VudGVyR2VuLCBtYXRjaEdlbik7Ci0JICAgIF9jb3VudC5zeW50aGVzaXplKG5vZGVDb3VudGVyR2VuLCBtYXRjaEdlbik7Ci0JICAgIAotCSAgICBpbC5hcHBlbmQoSVJFVFVSTik7Ci0JCSAgICAKLQkgICAgbWF0Y2hHZW4uc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotCSAgICBtYXRjaEdlbi5zZXRNYXhMb2NhbHMoKTsKLQkgICAgbWF0Y2hHZW4uc2V0TWF4U3RhY2soKTsKLQkgICAgbWF0Y2hHZW4ucmVtb3ZlTk9QcygpOwotCSAgICBub2RlQ291bnRlckdlbi5hZGRNZXRob2QobWF0Y2hHZW4uZ2V0TWV0aG9kKCkpOwotCX0KLQkKLQlnZXRYU0xUQygpLmR1bXBDbGFzcyhub2RlQ291bnRlckdlbi5nZXRKYXZhQ2xhc3MoKSk7Ci0KLQkvLyBQdXNoIGFuIGluc3RhbmNlIG9mIHRoZSBuZXdseSBjcmVhdGVkIGNsYXNzCi0JY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlmaW5hbCBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKGNsYXNzTmFtZSwgIjxpbml0PiIsIAotCQkJCQkgICAiKCIgKyBUUkFOU0xFVF9JTlRGX1NJRwotCQkJCQkgICArIERPTV9JTlRGX1NJRyAKLQkJCQkJICAgKyBOT0RFX0lURVJBVE9SX1NJRwotCQkJCQkgICArICIpViIpOwotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhjbGFzc05hbWUpKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JaW50IGluZGV4OwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBQdXNoICJ0aGlzIiBmb3IgdGhlIGNhbGwgdG8gY2hhcmFjdGVycygpCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQotCWlmIChoYXNWYWx1ZSgpKSB7Ci0JICAgIGNvbXBpbGVEZWZhdWx0KGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JICAgIC8vIFJvdW5kIHRoZSBudW1iZXIgdG8gdGhlIG5lYXJlc3QgaW50ZWdlcgotCSAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoTUFUSF9DTEFTUywgInJvdW5kIiwgIihEKUoiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoaW5kZXgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBMMkkoKSk7Ci0KLQkgICAgLy8gQ2FsbCBzZXRWYWx1ZSBvbiB0aGUgbm9kZSBjb3VudGVyCi0JICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihOT0RFX0NPVU5URVIsIAotCQkJCSAgICAgInNldFZhbHVlIiwgCi0JCQkJICAgICAiKEkpIiArIE5PREVfQ09VTlRFUl9TSUcpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLQl9Ci0JZWxzZSBpZiAoaXNEZWZhdWx0KCkpIHsKLQkgICAgY29tcGlsZURlZmF1bHQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCWVsc2UgewotCSAgICBjb21waWxlUGF0dGVybnMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCi0JLy8gQ2FsbCBzZXRTdGFydE5vZGUoKSAKLQlpZiAoIWhhc1ZhbHVlKCkpIHsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihOT0RFX0NPVU5URVIsIAotCQkJCSAgICAgU0VUX1NUQVJUX05PREUsIAotCQkJCSAgICAgIihJKSIgKyBOT0RFX0NPVU5URVJfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0JfQotCi0JLy8gQ2FsbCBnZXRDb3VudGVyKCkgd2l0aCBvciB3aXRob3V0IGFyZ3MKLQlpZiAoX2Zvcm1hdE5lZWRlZCkgewotCSAgICBpZiAoX2Zvcm1hdCAhPSBudWxsKSB7Ci0JCV9mb3JtYXQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAiMSIpKTsKLQkgICAgfQotCi0JICAgIGlmIChfbGFuZyAhPSBudWxsKSB7Ci0JCV9sYW5nLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgImVuIikpOyAJLy8gVE9ETyA/PwotCSAgICB9Ci0KLQkgICAgaWYgKF9sZXR0ZXJWYWx1ZSAhPSBudWxsKSB7Ci0JCV9sZXR0ZXJWYWx1ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIENvbnN0YW50cy5FTVBUWVNUUklORykpOwotCSAgICB9Ci0KLQkgICAgaWYgKF9ncm91cGluZ1NlcGFyYXRvciAhPSBudWxsKSB7Ci0JCV9ncm91cGluZ1NlcGFyYXRvci50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIENvbnN0YW50cy5FTVBUWVNUUklORykpOwotCSAgICB9Ci0KLQkgICAgaWYgKF9ncm91cGluZ1NpemUgIT0gbnVsbCkgewotCQlfZ3JvdXBpbmdTaXplLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgIjAiKSk7Ci0JICAgIH0KLQotCSAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoTk9ERV9DT1VOVEVSLCAiZ2V0Q291bnRlciIsIAotCQkJCSAgICAgIigiICsgU1RSSU5HX1NJRyArIFNUUklOR19TSUcgCi0JCQkJICAgICArIFNUUklOR19TSUcgKyBTVFJJTkdfU0lHIAotCQkJCSAgICAgKyBTVFJJTkdfU0lHICsgIikiICsgU1RSSU5HX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotCX0KLQllbHNlIHsKLQkgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKE5PREVfQ09VTlRFUiwgInNldERlZmF1bHRGb3JtYXR0aW5nIiwgCi0JCQkJICAgICAiKCkiICsgTk9ERV9DT1VOVEVSX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotCi0JICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihOT0RFX0NPVU5URVIsICJnZXRDb3VudGVyIiwgCi0JCQkJICAgICAiKCkiICsgU1RSSU5HX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotCX0KLQotCS8vIE91dHB1dCB0aGUgcmVzdWx0aW5nIHN0cmluZyB0byB0aGUgaGFuZGxlcgotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCSBDSEFSQUNURVJTVywKLQkJCQkgQ0hBUkFDVEVSU1dfU0lHKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9OdW1iZXJDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9OdW1iZXJDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYyYzNkNDEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvTnVtYmVyQ2FsbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAzICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBOdW1iZXJDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHB1YmxpYyBOdW1iZXJDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoYXJndW1lbnRDb3VudCgpID4gMCkgewotCSAgICBhcmd1bWVudCgpLnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQlyZXR1cm4gX3R5cGUgPSBUeXBlLlJlYWw7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCVR5cGUgdGFyZzsKLQkKLQlpZiAoYXJndW1lbnRDb3VudCgpID09IDApIHsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JICAgIHRhcmcgPSBUeXBlLk5vZGU7Ci0JfQotCWVsc2UgewotCSAgICBmaW5hbCBFeHByZXNzaW9uIGFyZyA9IGFyZ3VtZW50KCk7Ci0JICAgIGFyZy50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGFyZy5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIHRhcmcgPSBhcmcuZ2V0VHlwZSgpOwotCX0KLQotCWlmICghdGFyZy5pZGVudGljYWxUbyhUeXBlLlJlYWwpKSB7Ci0JICAgIHRhcmcudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWFsKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvT3RoZXJ3aXNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9PdGhlcndpc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTQzOWIzNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9PdGhlcndpc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGVDaGVja0Vycm9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBPdGhlcndpc2UgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0JaW5kZW50KGluZGVudCk7Ci0JVXRpbC5wcmludGxuKCJPdGhlcndpc2UiKTsKLQlpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQlkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0JCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQl0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgUGFyc2VyIHBhcnNlciA9IGdldFBhcnNlcigpOwotCWZpbmFsIEVycm9yTXNnIG1zZyA9IAotCSAgICBuZXcgRXJyb3JNc2coIidvdGhlcndpc2UnIG11c3QgYmUgdXNlZCB3aXRoaW4gYSAnY2hvb3NlJy4iLCAKLQkJCSBnZXRMaW5lTnVtYmVyKCkpOwotCXBhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsIG1zZyk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvT3V0cHV0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9PdXRwdXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDk2ZTU1Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9PdXRwdXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3NiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuVGV4dE91dHB1dDsKLQotZmluYWwgY2xhc3MgT3V0cHV0IGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIC8vIFRoZXNlIGF0dHJpYnV0ZXMgYXJlIGV4dHJhY3RlZCBmcm9tIHRoZSB4c2w6b3V0cHV0IGVsZW1lbnQuIFRoZXkgYWxzbwotICAgIC8vIGFwcGVhciBhcyBmaWVsZHMgKHdpdGggdGhlIHNhbWUgdHlwZSwgb25seSBwdWJsaWMpIGluIHRoZSB0cmFuc2xldAotICAgIHByaXZhdGUgU3RyaW5nICBfdmVyc2lvbjsKLSAgICBwcml2YXRlIFN0cmluZyAgX21ldGhvZDsKLSAgICBwcml2YXRlIFN0cmluZyAgX2VuY29kaW5nOwotICAgIHByaXZhdGUgYm9vbGVhbiBfb21pdEhlYWRlciA9IGZhbHNlOwotICAgIHByaXZhdGUgU3RyaW5nICBfc3RhbmRhbG9uZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX2RvY3R5cGVQdWJsaWM7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgIF9kb2N0eXBlU3lzdGVtOwotICAgIHByaXZhdGUgU3RyaW5nICBfY2RhdGE7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pbmRlbnQgPSBmYWxzZTsKLSAgICBwcml2YXRlIFN0cmluZyAgX21lZGlhVHlwZTsKLQotICAgIC8vIERpc2FibGVzIHRoaXMgb3V0cHV0IGVsZW1lbnQgKHdoZW4gb3RoZXIgZWxlbWVudCBoYXMgaGlnaGVyIHByZWNlZGVuY2UpCi0gICAgcHJpdmF0ZSBib29sZWFuIF9kaXNhYmxlZCA9IGZhbHNlOwotCi0gICAgLy8gU29tZSBnbG9iYWwgY29uc3RhbnRzCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFNUUklOR19TSUcgPSAiTGphdmEvbGFuZy9TdHJpbmc7IjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgT05FX0RPVF9aRVJPX1NUUklORyA9ICIxLjAiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBPVVRQVVRfVkVSU0lPTl9FUlJPUiA9Ci0JIk91dHB1dCBYTUwgZG9jdW1lbnQgdHlwZSBzaG91bGQgYmUgMS4wIjsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXlzIHRoZSBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQgKGZvciBkZWJ1Z2dpbmcpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0JaW5kZW50KGluZGVudCk7Ci0JVXRpbC5wcmludGxuKCJPdXRwdXQgIiArIF9tZXRob2QpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERpc2FibGVzIHRoaXMgPHhzbDpvdXRwdXQ+IGVsZW1lbnQgaW4gY2FzZSB3aGVyZSB0aGVyZSBhcmUgc29tZSBvdGhlcgotICAgICAqIDx4c2w6b3V0cHV0PiBlbGVtZW50IChmcm9tIGEgZGlmZmVyZW50IGltcG9ydGVkL2luY2x1ZGVkIHN0eWxlc2hlZXQpCi0gICAgICogd2l0aCBoaWdoZXIgcHJlY2VkZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNhYmxlKCkgewotCV9kaXNhYmxlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2NhbnMgdGhlIGF0dHJpYnV0ZSBsaXN0IGZvciB0aGUgeHNsOm91dHB1dCBpbnN0cnVjdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCi0JLy8gRG8gbm90aGluZyBpZiBvdGhlciA8eHNsOm91dHB1dD4gZWxlbWVudCBoYXMgaGlnaGVyIHByZWNlZGVuY2UKLQlpZiAoX2Rpc2FibGVkKSByZXR1cm47Ci0KLQlTdHJpbmcgYXR0cmliID0gbnVsbDsKLQotCS8vIEdldCB0aGUgb3V0cHV0IFhNTCB2ZXJzaW9uIC0gb25seSB2ZXJzaW9uICIxLjAiIHNob3VsZCBiZSB1c2VkCi0JX3ZlcnNpb24gPSBnZXRBdHRyaWJ1dGUoInZlcnNpb24iKTsKLQlpZiAoKF92ZXJzaW9uID09IG51bGwpIHx8IChfdmVyc2lvbi5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkpIHsKLQkgICAgX3ZlcnNpb24gPSBPTkVfRE9UX1pFUk9fU1RSSU5HOwotCX0KLQlpZiAoIV92ZXJzaW9uLmVxdWFscyhPTkVfRE9UX1pFUk9fU1RSSU5HKSkgewotCSAgICBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coT1VUUFVUX1ZFUlNJT05fRVJST1IpOwotCSAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLldBUk5JTkcsIG1zZyk7Ci0JfQotCi0JLy8gR2V0IHRoZSBvdXRwdXQgbWV0aG9kIC0gInhtbCIsICJodG1sIiwgInRleHQiIG9yIDxxbmFtZT4KLQlfbWV0aG9kID0gZ2V0QXR0cmlidXRlKCJtZXRob2QiKTsKLQlpZiAoX21ldGhvZC5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgX21ldGhvZCA9IG51bGw7Ci0JaWYgKF9tZXRob2QgIT0gbnVsbCkgX21ldGhvZCA9IF9tZXRob2QudG9Mb3dlckNhc2UoKTsKLQotCS8vIEdldCB0aGUgb3V0cHV0IGVuY29kaW5nIC0gYW55IHZhbHVlIGFjY2VwdGVkIGhlcmUKLQlfZW5jb2RpbmcgPSBnZXRBdHRyaWJ1dGUoImVuY29kaW5nIik7Ci0JaWYgKF9lbmNvZGluZy5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgX2VuY29kaW5nID0gbnVsbDsKLQotCS8vIFNob3VsZCB0aGUgWE1MIGhlYWRlciBiZSBvbWl0dGVkIC0gdHJhbnNsYXRlIHRvIHRydWUvZmFsc2UKLQlhdHRyaWIgPSBnZXRBdHRyaWJ1dGUoIm9taXQteG1sLWRlY2xhcmF0aW9uIik7Ci0JaWYgKChhdHRyaWIgIT0gbnVsbCkgJiYgKGF0dHJpYi5lcXVhbHMoInllcyIpKSkgX29taXRIZWFkZXIgPSB0cnVlOwotCi0JLy8gQWRkICdzdGFuZGFsb25lJyBkZWNhcmF0aW9uIHRvIG91dHB1dCAtIHVzZSB0ZXh0IGFzIGlzCi0JX3N0YW5kYWxvbmUgPSBnZXRBdHRyaWJ1dGUoInN0YW5kYWxvbmUiKTsKLQlpZiAoX3N0YW5kYWxvbmUuZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpIF9zdGFuZGFsb25lID0gbnVsbDsKLQotCS8vIEdldCBzeXN0ZW0vcHVibGljIGlkZW50aWZpZXJzIGZvciBvdXRwdXQgRE9DVFlQRSBkZWNsYXJhdGlvbgotCV9kb2N0eXBlU3lzdGVtID0gZ2V0QXR0cmlidXRlKCJkb2N0eXBlLXN5c3RlbSIpOwotCWlmIChfZG9jdHlwZVN5c3RlbS5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgX2RvY3R5cGVTeXN0ZW0gPSBudWxsOwotCV9kb2N0eXBlUHVibGljID0gZ2V0QXR0cmlidXRlKCJkb2N0eXBlLXB1YmxpYyIpOwotCWlmIChfZG9jdHlwZVB1YmxpYy5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgX2RvY3R5cGVQdWJsaWMgPSBudWxsOwotCi0JLy8gTmFtZXMgdGhlIGVsZW1lbnRzIG9mIHdob3NlIHRleHQgY29udGVudHMgc2hvdWxkIGJlIG91dHB1dCBhcyBDREFUQQotCV9jZGF0YSA9IGdldEF0dHJpYnV0ZSgiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIpOwotCWlmICgoX2NkYXRhICE9IG51bGwpICYmIChfY2RhdGEuZXF1YWxzKENvbnN0YW50cy5FTVBUWVNUUklORykpKQotCSAgICBfY2RhdGEgPSBudWxsOwotCi0JLy8gR2V0IHRoZSBpbmRlbnQgc2V0dGluZyAtIG9ubHkgaGFzIGVmZmVjdCBmb3IgeG1sIGFuZCBodG1sIG91dHB1dAotCWF0dHJpYiA9IGdldEF0dHJpYnV0ZSgiaW5kZW50Iik7Ci0JaWYgKChhdHRyaWIgIT0gbnVsbCkgJiYgKGF0dHJpYi5lcXVhbHMoInllcyIpKSkgX2luZGVudCA9IHRydWU7Ci0KLQkvLyBHZXQgdGhlIE1JTUUgdHlwZSBmb3IgdGhlIG91dHB1dCBmaWxlIC0gd2UgZG9uJ3QgZG8gYW55dGhpZ24gd2l0aCBpdCwKLQkvLyBidXQgb3VyIGNsaWVudCBtYXkgdXNlIGl0IHRvIHNwZWNpZnkgYSBkYXRhIHRyYW5zcG9ydCB0eXBlLCBldGMuCi0JX21lZGlhVHlwZSA9IGdldEF0dHJpYnV0ZSgibWVkaWEtdHlwZSIpOwotCWlmIChfbWVkaWFUeXBlLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSBfbWVkaWFUeXBlID0gbnVsbDsKLQotCS8vIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsgLSB0aGUgZWxlbWVudCBpcyBhbHdheXMgZW1wdHkKLQotCXBhcnNlci5zZXRPdXRwdXQodGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSBjb2RlIHRoYXQgcGFzc2VzIHRoZSBpbmZvcm1hdGlvbiBpbiB0aGlzIDx4c2w6b3V0cHV0PiBlbGVtZW50Ci0gICAgICogdG8gdGhlIGFwcHJvcHJpYXRlIGZpZWxkcyBpbiB0aGUgdHJhbnNsZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotCS8vIERvIG5vdGhpbmcgaWYgb3RoZXIgPHhzbDpvdXRwdXQ+IGVsZW1lbnQgaGFzIGhpZ2hlciBwcmVjZWRlbmNlCi0JaWYgKF9kaXNhYmxlZCkgcmV0dXJuOwotCi0JQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWludCBmaWVsZCA9IDA7Ci0gICAgICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0KLQkvLyBPbmx5IHVwZGF0ZSBfdmVyc2lvbiBmaWVsZCBpZiBzZXQgYW5kIGRpZmZlcmVudCBmcm9tIGRlZmF1bHQKLQlpZiAoKF92ZXJzaW9uICE9IG51bGwpICYmICghX3ZlcnNpb24uZXF1YWxzKE9ORV9ET1RfWkVST19TVFJJTkcpKSkgewotCSAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywgIl92ZXJzaW9uIiwgU1RSSU5HX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdmVyc2lvbikpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0JfQotCi0JLy8gT25seSB1cGRhdGUgX21ldGhvZCBmaWVsZCBpZiAibWV0aG9kIiBhdHRyaWJ1dGUgdXNlZAotCWlmIChfbWV0aG9kICE9IG51bGwpIHsKLQkgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfbWV0aG9kIiwgU1RSSU5HX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbWV0aG9kKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLQl9Ci0KLQkvLyBPbmx5IHVwZGF0ZSBpZiBfZW5jb2RpbmcgZmllbGQgaXMgImVuY29kaW5nIiBhdHRyaWJ1dGUgdXNlZAotCWlmIChfZW5jb2RpbmcgIT0gbnVsbCkgewotCSAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywgIl9lbmNvZGluZyIsIFNUUklOR19TSUcpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2VuY29kaW5nKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLQl9Ci0KLQkvLyBPbmx5IHVwZGF0ZSBpZiAib21pdC14bWwtZGVjbGFyYXRpb24iIHVzZWQgYW5kIHNldCB0byAneWVzJwotCWlmIChfb21pdEhlYWRlcikgewotCSAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywgIl9vbWl0SGVhZGVyIiwgIloiKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9vbWl0SGVhZGVyKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLQl9Ci0KLQkvLyBBZGQgJ3N0YW5kYWxvbmUnIGRlY2FyYXRpb24gdG8gb3V0cHV0IC0gdXNlIHRleHQgYXMgaXMKLQlpZiAoX3N0YW5kYWxvbmUgIT0gbnVsbCkgewotCSAgICBmaWVsZCA9IGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywgIl9zdGFuZGFsb25lIiwgU1RSSU5HX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfc3RhbmRhbG9uZSkpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0JfQotCi0JLy8gU2V0IHN5c3RlbS9wdWJsaWMgZG9jdHlwZSBvbmx5IGlmIGJvdGggYXJlIHNldAotCWZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLCJfZG9jdHlwZVN5c3RlbSIsU1RSSU5HX1NJRyk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX2RvY3R5cGVTeXN0ZW0pKTsKLQlpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGZpZWxkKSk7Ci0JZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsIl9kb2N0eXBlUHVibGljIixTVFJJTkdfU0lHKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfZG9jdHlwZVB1YmxpYykpOwotCWlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLQkKLQkvLyBBZGQgJ21lZHllLXR5cGUnIGRlY2FyYXRpb24gdG8gb3V0cHV0IC0gaWYgdXNlZAotCWlmIChfbWVkaWFUeXBlICE9IG51bGwpIHsKLQkgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfbWVkaWFUeXBlIiwgU1RSSU5HX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbWVkaWFUeXBlKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoZmllbGQpKTsKLQl9Ci0KLQkvLyBDb21waWxlIGNvZGUgdG8gc2V0IG91dHB1dCBpbmRlbnRhdGlvbiBvbi9vZmYKLQlpZiAoX2luZGVudCApIHsKLQkgICAgZmllbGQgPSBjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsICJfaW5kZW50IiwgIloiKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9pbmRlbnQpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChmaWVsZCkpOwotCX0KLQotCS8vIEZvcndhcmQgdG8gdGhlIHRyYW5zbGV0IGFueSBlbGVtZW50cyB0aGF0IHNob3VsZCBiZSBvdXRwdXQgYXMgQ0RBVEEKLQlpZiAoX2NkYXRhICE9IG51bGwpIHsKLQkgICAgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJICJhZGRDZGF0YUVsZW1lbnQiLAotCQkJCQkgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotCSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihfY2RhdGEpOwotCSAgICB3aGlsZSAodG9rZW5zLmhhc01vcmVUb2tlbnMoKSkgewotCQlpbC5hcHBlbmQoRFVQKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgdG9rZW5zLm5leHRUb2tlbigpKSk7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotCSAgICB9Ci0JfQotCWlsLmFwcGVuZChQT1ApOyAvLyBDbGVhbnVwIC0gcG9wIGxhc3QgdHJhbnNsZXQgcmVmZXJlbmNlIG9mZiBzdGFjawotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGFyYW0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhcmFtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDliZGVmN2YuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGFyYW0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2OSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgSm9obiBIb3dhcmQgPEpvaG5IQHNjaGVtYXNvZnQuY29tPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuRmllbGQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgUGFyYW0gZXh0ZW5kcyBWYXJpYWJsZUJhc2UgewotCi0gICAgLyoqCi0gICAgICogRGlzcGxheSB2YXJpYWJsZSBhcyBzaW5nbGUgc3RyaW5nCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4oInBhcmFtKCIrX25hbWUrIikiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5IHZhcmlhYmxlIGluIGEgZnVsbCBBU1QgZHVtcAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVN5c3RlbS5vdXQucHJpbnRsbigicGFyYW0gIiArIF9uYW1lKTsKLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNlbGVjdCAiICsgX3NlbGVjdC50b1N0cmluZygpKTsKLQl9Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcGFyYW1ldGVyJ3MgdHlwZS4gVGhpcyBpcyBuZWVkZWQgYnkgUGFyYW1ldGVyUmVmIHRvCi0gICAgICogZGV0ZXJtaW5lIHRoZSB0eXBlIG9mIHRoZSBwYXJhbWV0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgewotCXJldHVybiBfdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgY29udGVudHMgb2YgdGhlIDx4c2w6cGFyYW0+IGVsZW1lbnQuIFRoaXMgbWV0aG9kIG11c3QgcmVhZAotICAgICAqIHRoZSAnbmFtZScgKHJlcXVpcmVkKSBhbmQgJ3NlbGVjdCcgKG9wdGlvbmFsKSBhdHRyaWJ1dGVzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCS8vIFBhcnNlIGF0dHJpYnV0ZXMgbmFtZSBhbmQgc2VsZWN0IChpZiBwcmVzZW50KQotCWZpbmFsIFN0cmluZyBuYW1lID0gZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0KLQlpZiAobmFtZS5sZW5ndGgoKSA+IDApIHsKLQkgICAgc2V0TmFtZShwYXJzZXIuZ2V0UU5hbWUobmFtZSkpOwotCX0KLSAgICAgICAgZWxzZSB7Ci0JICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuTlJFUUFUVFJfRVJSLCAibmFtZSIpOwotICAgICAgICB9Ci0KLQkvLyBjaGVjayB3aGV0aGVyIHZhcmlhYmxlL3BhcmFtIG9mIHRoZSBzYW1lIG5hbWUgaXMgYWxyZWFkeSBpbiBzY29wZQotCWlmIChwYXJzZXIubG9va3VwVmFyaWFibGUoX25hbWUpICE9IG51bGwpIHsKLQkgICAgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKEVycm9yTXNnLlZBUlJFREVGX0VSUiwgX25hbWUsIHRoaXMpOwotCSAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotCX0KLQkKLQlmaW5hbCBTdHJpbmcgc2VsZWN0ID0gZ2V0QXR0cmlidXRlKCJzZWxlY3QiKTsKLQlpZiAoc2VsZWN0Lmxlbmd0aCgpID4gMCkgewotCSAgICBfc2VsZWN0ID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCAic2VsZWN0IiwgbnVsbCk7Ci0JfQotCi0JLy8gQ2hpbGRyZW4gbXVzdCBiZSBwYXJzZWQgZmlyc3QgLT4gc3RhdGljIHNjb3BpbmcKLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0KLQkvLyBBZGQgYSByZWYgdG8gdGhpcyBwYXJhbSB0byBpdHMgZW5jbG9zaW5nIGNvbnN0cnVjdAotCWZpbmFsIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0JICAgIF9pc0xvY2FsID0gZmFsc2U7Ci0JICAgICgoU3R5bGVzaGVldClwYXJlbnQpLmFkZFBhcmFtKHRoaXMpOwotCSAgICAvLyEhIGNoZWNrIGZvciByZWRlZgotCSAgICBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5hZGRQYXJhbSh0aGlzKTsKLQl9Ci0JZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgVGVtcGxhdGUpIHsKLQkgICAgX2lzTG9jYWwgPSB0cnVlOwotCSAgICAoKFRlbXBsYXRlKXBhcmVudCkuaGFzUGFyYW1zKHRydWUpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlLWNoZWNrcyB0aGUgcGFyYW1ldGVyLiBUaGUgcGFyYW1ldGVyIHR5cGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUKLSAgICAgKiAnc2VsZWN0JyBleHByZXNzaW9uIChpZiBwcmVzZW50KSBvciBpcyBhIHJlc3VsdCB0cmVlIGlmIHRoZSBwYXJhbWV0ZXIKLSAgICAgKiBlbGVtZW50IGhhcyBhIGJvZHkgYW5kIG5vICdzZWxlY3QnIGV4cHJlc3Npb24uCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQkvLyBHZXQgdGhlIHR5cGUgZnJvbSB0aGUgc2VsZWN0IGV4cmVwc3Npb24uLi4KLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIF90eXBlID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsgCi0JICAgIGlmIChfdHlwZSBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUgPT0gZmFsc2UpIHsKLQkJX3NlbGVjdCA9IG5ldyBDYXN0RXhwcihfc2VsZWN0LCBUeXBlLlJlZmVyZW5jZSk7Ci0JICAgIH0KLQl9Ci0JLy8gLi4ub3Igc2V0IHRoZSB0eXBlIHRvIHJlc3VsdCB0cmVlCi0JZWxzZSBpZiAoaGFzQ29udGVudHMoKSkgewotCSAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCX0KLQlfdHlwZSA9IFR5cGUuUmVmZXJlbmNlOwotCi0JLy8gVGhpcyBlbGVtZW50IGhhcyBubyB0eXBlICh0aGUgcGFyYW1ldGVyIGRvZXMsIGJ1dCB0aGUgcGFyYW1ldGVyCi0JLy8gZWxlbWVudCBpdHNlbGYgZG9lcyBub3QpLgotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZSB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciwgd2hpY2ggaXMgZWl0aGVyIGluIGFuIGV4cHJlc3Npb24gaW4KLSAgICAgKiBhICdzZWxlY3QnIGF0dHJpYnV0ZSwgb3IgaW4gdGhlIHBhcmFtZXRlciBlbGVtZW50J3MgYm9keQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVZhbHVlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQkvLyBDb21waWxlIGV4cHJlc3Npb24gaXMgJ3NlbGVjdCcgYXR0cmlidXRlIGlmIHByZXNlbnQKLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfdHlwZS50cmFuc2xhdGVCb3goY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIF9zZWxlY3Quc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQkvLyBJZiBub3QsIGNvbXBpbGUgcmVzdWx0IHRyZWUgZnJvbSBwYXJhbWV0ZXIgYm9keSBpZiBwcmVzZW50LgotCWVsc2UgaWYgKGhhc0NvbnRlbnRzKCkpIHsKLQkgICAgY29tcGlsZVJlc3VsdFRyZWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCS8vIElmIG5laXRoZXIgYXJlIHByZXNlbnQgdGhlbiBzdG9yZSBlbXB0eSBzdHJpbmcgaW4gcGFyYW1ldGVyIHNsb3QKLQllbHNlIHsKLQkgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIENvbnN0YW50cy5FTVBUWVNUUklORykpOwotCX0KLSAgICB9Ci0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlmIChfY29tcGlsZWQpIHJldHVybjsKLQlfY29tcGlsZWQgPSB0cnVlOwotCi0JZmluYWwgU3RyaW5nIG5hbWUgPSBnZXRWYXJpYWJsZSgpOwotCWZpbmFsIFN0cmluZyBzaWduYXR1cmUgPSBfdHlwZS50b1NpZ25hdHVyZSgpOwotCWZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBfdHlwZS5nZXRDbGFzc05hbWUoKTsKLQotCWlmIChpc0xvY2FsKCkpIHsKLQotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBuYW1lKSk7Ci0JICAgIHRyYW5zbGF0ZVZhbHVlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCB0cnVlKSk7Ci0KLQkgICAgLy8gQ2FsbCBhZGRQYXJhbWV0ZXIoKSBmcm9tIHRoaXMgY2xhc3MKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkJIEFERF9QQVJBTUVURVIsCi0JCQkJCQkJIEFERF9QQVJBTUVURVJfU0lHKSkpOwotCSAgICBpZiAoY2xhc3NOYW1lICE9IEVNUFRZU1RSSU5HKSB7Ci0JCWlsLmFwcGVuZChuZXcgQ0hFQ0tDQVNUKGNwZy5hZGRDbGFzcyhjbGFzc05hbWUpKSk7Ci0JICAgIH0KLQotCSAgICBfdHlwZS50cmFuc2xhdGVVbkJveChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICBpZiAoX3JlZnMuaXNFbXB0eSgpKSB7IC8vIG5vYm9keSB1c2VzIHRoZSB2YWx1ZQotCQlpbC5hcHBlbmQoX3R5cGUuUE9QKCkpOwotCQlfbG9jYWwgPSBudWxsOwotCSAgICB9Ci0JICAgIGVsc2UgewkJLy8gbm9ybWFsIGNhc2UKLQkJX2xvY2FsID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKG5hbWUsCi0JCQkJCQkgICAgIF90eXBlLnRvSkNUeXBlKCksCi0JCQkJCQkgICAgIGlsLmdldEVuZCgpKTsKLQkJLy8gQ2FjaGUgdGhlIHJlc3VsdCBvZiBhZGRQYXJhbWV0ZXIoKSBpbiBhIGxvY2FsIHZhcmlhYmxlCi0JCWlsLmFwcGVuZChfdHlwZS5TVE9SRShfbG9jYWwuZ2V0SW5kZXgoKSkpOwotCSAgICB9Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5hZGRGaWVsZChuZXcgRmllbGQoQUNDX1BVQkxJQywgY3BnLmFkZFV0ZjgobmFtZSksCi0JCQkJCWNwZy5hZGRVdGY4KHNpZ25hdHVyZSksCi0JCQkJCW51bGwsIGNwZy5nZXRDb25zdGFudFBvb2woKSkpOwotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbmFtZSkpOwotCSAgICB0cmFuc2xhdGVWYWx1ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgdHJ1ZSkpOwotCi0JICAgIC8vIENhbGwgYWRkUGFyYW1ldGVyKCkgZnJvbSB0aGlzIGNsYXNzCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJCSBBRERfUEFSQU1FVEVSLAotCQkJCQkJCSBBRERfUEFSQU1FVEVSX1NJRykpKTsKLQotCSAgICBfdHlwZS50cmFuc2xhdGVVbkJveChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICAvLyBDYWNoZSB0aGUgcmVzdWx0IG9mIGFkZFBhcmFtZXRlcigpIGluIGEgZmllbGQKLQkgICAgaWYgKGNsYXNzTmFtZSAhPSBFTVBUWVNUUklORykgewotCQlpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoY2xhc3NOYW1lKSkpOwotCSAgICB9Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVURklFTEQoY3BnLmFkZEZpZWxkcmVmKGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLAotCQkJCQkJICAgbmFtZSwgc2lnbmF0dXJlKSkpOwotCX0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhcmFtLmphdmEub3JpZyBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhcmFtLmphdmEub3JpZwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDEyN2U3MS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9QYXJhbS5qYXZhLm9yaWcKKysrIC9kZXYvbnVsbApAQCAtMSwyNTcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogQ29weXJpZ2h0IDIwMDAgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogCi0gKiBUaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wcmlldGFyeSBpbmZvcm1hdGlvbiBvZiBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuICAKLSAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMuCi0gKiAKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBjb20uc3VuLnhzbHQuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGNvbS5zdW4ueG1sLnRyZWUuRWxlbWVudEV4OwotaW1wb3J0IGNvbS5zdW4ueHNsdC5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgY29tLnN1bi54c2x0LmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuRmllbGQ7Ci1pbXBvcnQgY29tLnN1bi54c2x0LmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgUGFyYW0gZXh0ZW5kcyBUb3BMZXZlbEVsZW1lbnQgewotICAgIHByaXZhdGUgUU5hbWUgICAgICBfbmFtZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gICAgX2lzTG9jYWw7CS8vIHRydWUgaWYgdGhlIHBhcmFtIGlzIGxvY2FsCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9zZWxlY3Q7Ci0gICAgcHJpdmF0ZSBUeXBlICAgICAgIF90eXBlOwotICAgIC8vIGEgSmF2YUNsYXNzIGNvbnN0cnVjdCB0byByZWZlciB0byBhIEpWTSB2YXIKLSAgICBwcml2YXRlIExvY2FsVmFyaWFibGVHZW4gX2xvY2FsOwotICAgIC8vIGNhY2hlZCBKYXZhQ2xhc3MgaW5zdHJ1Y3Rpb24gdG8gcHVzaCB0aGUgY29udGVudHMgb2YgdGhpcyB2YXIKLSAgICBwcml2YXRlIEluc3RydWN0aW9uIF9sb2FkSW5zdHJ1Y3Rpb247Ci0gICAgLy8gcmVmZXJlbmNlcyB0byB0aGlzIHZhcmlhYmxlICh3aGVuIGxvY2FsKQotICAgIHByaXZhdGUgVmVjdG9yICAgICBfcmVmcyA9IG5ldyBWZWN0b3IoMik7Ci0gICAgLy8gdG8gbWFrZSBzdXJlIHBhcmFtZXRlciBmaWVsZCBpcyBub3QgYWRkZWQgdHdpY2UKLSAgICBwcml2YXRlIGJvb2xlYW4gICAgX2NvbXBpbGVkID0gZmFsc2U7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlTeXN0ZW0ub3V0LnByaW50bG4oInBhcmFtICIgKyBfbmFtZSk7Ci0JaWYgKF9zZWxlY3QgIT0gbnVsbCkgewotCSAgICBpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzZWxlY3QgIiArIF9zZWxlY3QudG9TdHJpbmcoKSk7Ci0JfQotCWRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZFJlZmVyZW5jZShQYXJhbWV0ZXJSZWYgcHJlZikgewotU3lzdGVtLm91dC5wcmludGxuKCJHVE0+IEluICBQYXJhbS5hZGRSZWZlcmVuY2UsIHBhcmFtIHJlZiA9ICIgKyBwcmVmKTsKLQlfcmVmcy5hZGRFbGVtZW50KHByZWYpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlbW92ZVJlZmVyZW5jZShQYXJhbWV0ZXJSZWYgcHJlZikgewotCV9yZWZzLnJlbW92ZShwcmVmKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlUmVmZXJlbmNlKFBhcmFtZXRlclJlZiBwcmVmLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci1TeXN0ZW0ub3V0LnByaW50bG4oIkdUTT4gSW4gUGFyYW0ucmVtb3ZlUmVmZXJlbmNlLCBwYXJhbSByZWYgPSAiICsgcHJlZik7Ci1TeXN0ZW0ub3V0LnByaW50bG4oIkdUTT4gSW4gUGFyYW0ucmVtb3ZlUmVmZXJlbmNlLCBfcmVmcyA9ICIgKyBfcmVmcyk7Ci0JX3JlZnMucmVtb3ZlKHByZWYpOwotCWlmIChfcmVmcy5pc0VtcHR5KCkpIHsKLQkgICAgX2xvY2FsLnNldEVuZChtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuZ2V0RW5kKCkpOwotCSAgICBtZXRob2RHZW4ucmVtb3ZlTG9jYWxWYXJpYWJsZShfbG9jYWwpOwotCSAgICBfcmVmcyA9IG51bGw7Ci0JICAgIF9sb2NhbCA9IG51bGw7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkSW5zdHJ1Y3Rpb24oKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb24gaW5zdHIgPSBfbG9hZEluc3RydWN0aW9uOwotCXJldHVybiBpbnN0ciAhPSBudWxsCi0JICAgID8gaW5zdHIgOiAoX2xvYWRJbnN0cnVjdGlvbiA9IF90eXBlLkxPQUQoX2xvY2FsLmdldEluZGV4KCkpKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFR5cGUgZ2V0VHlwZSgpIHsKLQlyZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNMb2NhbCgpIHsKLQlyZXR1cm4gX2lzTG9jYWw7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldE5hbWUoKSB7Ci0JcmV0dXJuIF9uYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoRWxlbWVudEV4IGVsZW1lbnQsIFBhcnNlciBwYXJzZXIpIHsKLQkvLyBQYXJzZSBhdHRyaWJ1dGVzIG5hbWUgYW5kIHNlbGVjdCAoaWYgcHJlc2VudCkKLQlmaW5hbCBTdHJpbmcgbmFtZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0KLQlpZiAobmFtZS5sZW5ndGgoKSA+IDApIHsKLQkgICAgX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWUobmFtZSk7Ci0JfQotICAgICAgICBlbHNlIHsKLQkgICAgcmVwb3J0RXJyb3IoZWxlbWVudCwgcGFyc2VyLCBFcnJvck1zZy5OUkVRQVRUUl9FUlIsICJuYW1lIik7Ci0gICAgICAgIH0KLQotCS8vIGNoZWNrIHdoZXRoZXIgdmFyaWFibGUvcGFyYW0gb2YgdGhlIHNhbWUgbmFtZSBpcyBhbHJlYWR5IGluIHNjb3BlCi0JaWYgKHBhcnNlci5sb29rdXBWYXJpYWJsZShfbmFtZSkgIT0gbnVsbCkgewotCSAgICBFcnJvck1zZyBlcnJvciA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5WQVJSRURFRl9FUlIsIF9uYW1lLCB0aGlzKTsKLQkgICAgcGFyc2VyLmFkZEVycm9yKGVycm9yKTsKLQl9Ci0JCi0JZmluYWwgU3RyaW5nIHNlbGVjdCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJzZWxlY3QiKTsKLQlpZiAoc2VsZWN0Lmxlbmd0aCgpID4gMCkgewotCSAgICBfc2VsZWN0ID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCBlbGVtZW50LCAic2VsZWN0Iik7Ci0JfQotCi0JLy8gQ2hpbGRyZW4gbXVzdCBiZSBwYXJzZWQgZmlyc3QgLT4gc3RhdGljIHNjb3BpbmcKLQlwYXJzZUNoaWxkcmVuKGVsZW1lbnQsIHBhcnNlcik7Ci0KLQkvLyBBZGQgYSByZWYgdG8gdGhpcyBwYXJhbSB0byBpdHMgZW5jbG9zaW5nIGNvbnN0cnVjdAotCWZpbmFsIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0JICAgIF9pc0xvY2FsID0gZmFsc2U7Ci0JICAgICgoU3R5bGVzaGVldClwYXJlbnQpLmFkZFBhcmFtKHRoaXMpOwotCSAgICAvLyEhIGNoZWNrIGZvciByZWRlZgotCSAgICBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5hZGRQYXJhbSh0aGlzKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIF9pc0xvY2FsID0gdHJ1ZTsKLQkgICAgcGFyZW50LmFkZFBhcmFtKHRoaXMpOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWlmIChfc2VsZWN0ICE9IG51bGwpIHsKLQkgICAgZmluYWwgVHlwZSB0c2VsZWN0ID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsgCi0JICAgIGlmICh0c2VsZWN0IGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSA9PSBmYWxzZSkgewotCQlfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuUmVmZXJlbmNlKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLQl9Ci0JX3R5cGUgPSBUeXBlLlJlZmVyZW5jZTsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNvbXBpbGVSZXN1bHRUcmVlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBTYXZlIHRoZSBjdXJyZW50IGhhbmRsZXIgYmFzZSBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCi0JLy8gQ3JlYXRlIG5ldyBpbnN0YW5jZSBvZiBET00gY2xhc3MgKHdpdGggNjQgbm9kZXMpCi0JZmluYWwgaW50IGluaXQgPSBjcGcuYWRkTWV0aG9kcmVmKERPTV9JTVBMLCAiPGluaXQ+IiwgIihJKVYiKTsKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoRE9NX0lNUEwpKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgNjQpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotCi0JLy8gT3ZlcndyaXRlIG9sZCBoYW5kbGVyIHdpdGggRE9NIGhhbmRsZXIKLQlmaW5hbCBpbnQgZ2V0T3V0cHV0RG9tQnVpbGRlciA9Ci0JICAgIGNwZy5hZGRNZXRob2RyZWYoRE9NX0lNUEwsCi0JCQkgICAgICJnZXRPdXRwdXREb21CdWlsZGVyIiwKLQkJCSAgICAgIigpIiArIFRSQU5TTEVUX09VVFBVVF9TSUcpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChnZXRPdXRwdXREb21CdWlsZGVyKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0KLQkvLyBDYWxsIHN0YXJ0RG9jdW1lbnQgb24gdGhlIG5ldyBoYW5kbGVyCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdGFydERvY3VtZW50KCkpOwotCi0JLy8gSW5zdGFudGlhdGUgcmVzdWx0IHRyZWUgZnJhZ21lbnQKLQl0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCS8vIENhbGwgZW5kRG9jdW1lbnQgb24gdGhlIG5ldyBoYW5kbGVyCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmVuZERvY3VtZW50KCkpOwotCi0JLy8gUmVzdG9yZSBvbGQgaGFuZGxlciBiYXNlIGZyb20gc3RhY2sKLQlpbC5hcHBlbmQoU1dBUCk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBTdHJpbmcgbmFtZSA9IF9uYW1lLmdldExvY2FsUGFydCgpOyAvLyBUT0RPOiBuYW1lc3BhY2UgPwotCi0JaWYgKF9jb21waWxlZCkgcmV0dXJuOwotCV9jb21waWxlZCA9IHRydWU7Ci0KLQlpZiAoaXNMb2NhbCgpKSB7Ci0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWUpKTsKLQkgICAgaWYgKF9zZWxlY3QgPT0gbnVsbCkgewotCQlpZiAoaGFzQ29udGVudHMoKSkgewotCQkgICAgY29tcGlsZVJlc3VsdFRyZWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7CQotCQl9Ci0JCWVsc2UgewotCQkgICAgLy8gSWYgbm8gc2VsZWN0IGFuZCBubyBjb250ZW50cyBwdXNoIHRoZSBlbXB0eSBzdHJpbmcKLQkJICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICIiKSk7Ci0JCX0KLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX3NlbGVjdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCV9zZWxlY3Quc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICB9Ci0KLQkgICAgLy8gQ2FsbCBhZGRQYXJhbWV0ZXIoKSBmcm9tIHRoaXMgY2xhc3MKLQkgICAgZmluYWwgaW50IGFkZFBhcmFtZXRlciA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkgICAgICBBRERfUEFSQU1FVEVSLAotCQkJCQkJICAgICAgQUREX1BBUkFNRVRFUl9TSUcpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoYWRkUGFyYW1ldGVyKSk7Ci0KLQkgICAgaWYgKF9yZWZzLmlzRW1wdHkoKSkgeyAvLyBub2JvZHkgdXNlcyB0aGUgdmFsdWUKLQkJaWwuYXBwZW5kKF90eXBlLlBPUCgpKTsKLQkJX2xvY2FsID0gbnVsbDsKLQkgICAgfQotCSAgICBlbHNlIHsJCS8vIG5vcm1hbCBjYXNlCi0JCV9sb2NhbCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMihuYW1lLCBfdHlwZS50b0pDVHlwZSgpLAotCQkJCQkJICAgICBpbC5nZXRFbmQoKSk7Ci0JCS8vIENhY2hlIHRoZSByZXN1bHQgb2YgYWRkUGFyYW1ldGVyKCkgaW4gYSBsb2NhbCB2YXJpYWJsZQotCQlpbC5hcHBlbmQoX3R5cGUuU1RPUkUoX2xvY2FsLmdldEluZGV4KCkpKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgU3RyaW5nIHNpZ25hdHVyZSA9IF90eXBlLnRvU2lnbmF0dXJlKCk7Ci0JICAgIGlmIChzaWduYXR1cmUuZXF1YWxzKERPTV9JTVBMX1NJRykpCi0JCXNpZ25hdHVyZSA9IGNsYXNzR2VuLmdldERPTUNsYXNzU2lnKCk7Ci0JICAgIGNsYXNzR2VuLmFkZEZpZWxkKG5ldyBGaWVsZChBQ0NfUFVCTElDLCBjcGcuYWRkVXRmOChuYW1lKSwKLQkJCQkJY3BnLmFkZFV0Zjgoc2lnbmF0dXJlKSwKLQkJCQkJbnVsbCwgY3BnLmdldENvbnN0YW50UG9vbCgpKSk7Ci0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBuYW1lKSk7Ci0KLQkgICAgaWYgKF9zZWxlY3QgPT0gbnVsbCkgewotCQlpZiAoaGFzQ29udGVudHMoKSkgewotCQkgICAgY29tcGlsZVJlc3VsdFRyZWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7CQotCQl9Ci0JCWVsc2UgewotCQkgICAgLy8gSWYgbm8gc2VsZWN0IGFuZCBubyBjb250ZW50cyBwdXNoIHRoZSBlbXB0eSBzdHJpbmcKLQkJICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICIiKSk7Ci0JCX0KLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX3NlbGVjdC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCV9zZWxlY3Quc3RhcnRSZXNldEl0ZXJhdG9yKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICB9Ci0KLQkgICAgLy8gQ2FsbCBhZGRQYXJhbWV0ZXIoKSBmcm9tIHRoaXMgY2xhc3MKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkJIEFERF9QQVJBTUVURVIsCi0JCQkJCQkJIEFERF9QQVJBTUVURVJfU0lHKSkpOwotCSAgICAvLyBDYWNoZSB0aGUgcmVzdWx0IG9mIGFkZFBhcmFtZXRlcigpIGluIGEgZmllbGQKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVRGSUVMRChjcGcuYWRkRmllbGRyZWYoY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCQkgICBuYW1lLCBzaWduYXR1cmUpKSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhcmFtZXRlclJlZi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGFyYW1ldGVyUmVmLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDExNzkxOTguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGFyYW1ldGVyUmVmLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFBhcmFtZXRlclJlZiBleHRlbmRzIFZhcmlhYmxlUmVmQmFzZSB7Ci0KLSAgICBwdWJsaWMgUGFyYW1ldGVyUmVmKFBhcmFtIHBhcmFtKSB7Ci0Jc3VwZXIocGFyYW0pOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJwYXJhbWV0ZXItcmVmKCIgKyBfdmFyaWFibGUuZ2V0TmFtZSgpICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JCQotCVN0cmluZyBuYW1lID0gX3ZhcmlhYmxlLmdldFZhcmlhYmxlKCk7Ci0KLQlpZiAoX3ZhcmlhYmxlLmlzTG9jYWwoKSkgewotCSAgICBpZiAoY2xhc3NHZW4uaXNFeHRlcm5hbCgpKSB7Ci0JCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWUpKTsKLQkJZmluYWwgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywgCi0JCQkJCQkgICBHRVRfUEFSQU1FVEVSLAotCQkJCQkJICAgR0VUX1BBUkFNRVRFUl9TSUcpOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoaW5kZXgpKTsKLQkJX3R5cGUudHJhbnNsYXRlVW5Cb3goY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWlsLmFwcGVuZChfdmFyaWFibGUubG9hZEluc3RydWN0aW9uKCkpOwotCQlfdmFyaWFibGUucmVtb3ZlUmVmZXJlbmNlKHRoaXMpOwotCSAgICB9Ci0JfQotCWVsc2UgewotCSAgICBmaW5hbCBTdHJpbmcgc2lnbmF0dXJlID0gX3R5cGUudG9TaWduYXR1cmUoKTsKLQkgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICAvLyBJZiBpbnNpZGUgYSBwcmVkaWNhdGUgd2UgbXVzdCBjYXN0IHRoaXMgcmVmIGRvd24KLQkgICAgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotCQlpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoY2xhc3NOYW1lKSkpOwotCSAgICB9Ci0JICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSxuYW1lLHNpZ25hdHVyZSkpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGFyZW50TG9jYXRpb25QYXRoLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9QYXJlbnRMb2NhdGlvblBhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjQyMmVhZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9QYXJlbnRMb2NhdGlvblBhdGguamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3NCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uQXhpczsKLQotZmluYWwgY2xhc3MgUGFyZW50TG9jYXRpb25QYXRoIGV4dGVuZHMgUmVsYXRpdmVMb2NhdGlvblBhdGggewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfc3RlcDsKLSAgICBwcml2YXRlIGZpbmFsIFJlbGF0aXZlTG9jYXRpb25QYXRoIF9wYXRoOwotICAgIHByaXZhdGUgVHlwZSBzdHlwZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX29yZGVyTm9kZXMgPSBmYWxzZTsKLQotICAgIHB1YmxpYyBQYXJlbnRMb2NhdGlvblBhdGgoUmVsYXRpdmVMb2NhdGlvblBhdGggcGF0aCwgRXhwcmVzc2lvbiBzdGVwKSB7Ci0JX3BhdGggPSBwYXRoOwotCV9zdGVwID0gc3RlcDsKLQlfcGF0aC5zZXRQYXJlbnQodGhpcyk7Ci0JX3N0ZXAuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQkJCi0gICAgcHVibGljIHZvaWQgc2V0QXhpcyhpbnQgYXhpcykgewotCV9wYXRoLnNldEF4aXMoYXhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIFJlbGF0aXZlTG9jYXRpb25QYXRoIGdldFBhdGgoKSB7Ci0JcmV0dXJuKF9wYXRoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRTdGVwKCkgewotCXJldHVybihfc3RlcCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlfc3RlcC5zZXRQYXJzZXIocGFyc2VyKTsKLQlfcGF0aC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gIlBhcmVudExvY2F0aW9uUGF0aCgiICsgX3BhdGggKyAiLCAiICsgX3N0ZXAgKyAnKSc7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlzdHlwZSA9IF9zdGVwLnR5cGVDaGVjayhzdGFibGUpOwotCV9wYXRoLnR5cGVDaGVjayhzdGFibGUpOwotCi0JaWYgKGRlc2NlbmRhbnRBeGlzKCkgJiYgX3BhdGguZGVzY2VuZGFudEF4aXMoKSkKLQkgICAgX29yZGVyTm9kZXMgPSB0cnVlOwotCi0JcmV0dXJuIF90eXBlID0gVHlwZS5Ob2RlU2V0OwkKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBkZXNjZW5kYW50QXhpcygpIHsKLQlpZiAoX3N0ZXAgaW5zdGFuY2VvZiBTdGVwKSB7Ci0JICAgIHJldHVybiAoKFN0ZXApX3N0ZXApLmRlc2NlbmRhbnRBeGlzKCk7Ci0JfQotCWVsc2UgaWYgKF9zdGVwIGluc3RhbmNlb2YgUGFyZW50TG9jYXRpb25QYXRoKSB7Ci0JICAgIHJldHVybiAoKFBhcmVudExvY2F0aW9uUGF0aClfc3RlcCkuZGVzY2VuZGFudEF4aXMoKTsKLQl9Ci0JcmV0dXJuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKgotICAgIHB1YmxpYyB2b2lkIGJsb2NrSXRlcmF0b3JSZXNldCgpIHsKLQlpZiAoX3BhdGggaW5zdGFuY2VvZiBSZWxhdGl2ZUxvY2F0aW9uUGF0aCkKLQkgICAgKChSZWxhdGl2ZUxvY2F0aW9uUGF0aClfcGF0aCkuYmxvY2tJdGVyYXRvclJlc2V0KCk7Ci0JaWYgKF9zdGVwIGluc3RhbmNlb2YgU3RlcCkKLQkgICAgKChTdGVwKV9zdGVwKS5ibG9ja0l0ZXJhdG9yUmVzZXQoKTsKLSAgICB9Ci0gICAgKi8KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBDcmVhdGUgbmV3IFN0ZXBJdGVyYXRvcgotCWZpbmFsIGludCBpbml0U0kgPSBjcGcuYWRkTWV0aG9kcmVmKFNURVBfSVRFUkFUT1JfQ0xBU1MsCi0JCQkJCSAgICAiPGluaXQ+IiwKLQkJCQkJICAgICIoIgotCQkJCQkgICAgK05PREVfSVRFUkFUT1JfU0lHCi0JCQkJCSAgICArTk9ERV9JVEVSQVRPUl9TSUcKLQkJCQkJICAgICsiKVYiKTsKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU1RFUF9JVEVSQVRPUl9DTEFTUykpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQotCS8vIENvbXBpbGUgcGF0aCBpdGVyYXRvcgotCV9wYXRoLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsgLy8gaXRlcmF0b3Igb24gc3RhY2suLi4uCi0JX3N0ZXAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0KLQkvLyBJbml0aWFsaXplIFN0ZXBJdGVyYXRvciB3aXRoIGl0ZXJhdG9ycyBmcm9tIHRoZSBzdGFjawotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0U0kpKTsKLQotCS8qCi0JICogSWYgdGhpcyBwYXR0ZXJuIGNvbnRhaW5zIGEgc2VxdWVuY2Ugb2YgZGVzY2VuZGFudCBpdGVyYXRvcnMgd2UKLQkgKiBydW4gdGhlIHJpc2sgb2YgcmV0dXJuaW5nIHRoZSBzYW1lIG5vZGUgc2V2ZXJhbCB0aW1lcy4gV2UgcHV0Ci0JICogYSBuZXcgaXRlcmF0b3Igb24gdG9wIG9mIHRoZSBleGlzdGluZyBvbmUgdG8gYXNzdXJlIG5vZGUgb3JkZXIKLQkgKiBhbmQgcHJldmVudCByZXR1cm5pbmcgYSBzaW5nbGUgbm9kZSBtdWx0aXBsZSB0aW1lcy4KLQkgKi8KLQlpZiAoX29yZGVyTm9kZXMpIHsKLQkgICAgZmluYWwgU3RyaW5nIHBhcmFtcyA9ICIoIitOT0RFX0lURVJBVE9SX1NJRysiSSkiK05PREVfSVRFUkFUT1JfU0lHOwotCSAgICBmaW5hbCBpbnQgb3JkZXIgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJCSJvcmRlck5vZGVzIiwKLQkJCQkJCQlwYXJhbXMpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGlsLmFwcGVuZChTV0FQKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKG9yZGVyLCAzKSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhcmVudFBhdHRlcm4uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhcmVudFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDZjYjNiMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9QYXJlbnRQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBQYXJlbnRQYXR0ZXJuIGV4dGVuZHMgUmVsYXRpdmVQYXRoUGF0dGVybiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBQYXR0ZXJuIF9sZWZ0OwotICAgIHByaXZhdGUgZmluYWwgUmVsYXRpdmVQYXRoUGF0dGVybiBfcmlnaHQ7Ci0JCQotICAgIHB1YmxpYyBQYXJlbnRQYXR0ZXJuKFBhdHRlcm4gbGVmdCwgUmVsYXRpdmVQYXRoUGF0dGVybiByaWdodCkgewotCShfbGVmdCA9IGxlZnQpLnNldFBhcmVudCh0aGlzKTsKLQkoX3JpZ2h0ID0gcmlnaHQpLnNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotCXN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotCV9sZWZ0LnNldFBhcnNlcihwYXJzZXIpOwotCV9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZCgpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCkgewotCXJldHVybiBfcmlnaHQuZ2V0S2VybmVsUGF0dGVybigpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgdm9pZCByZWR1Y2VLZXJuZWxQYXR0ZXJuKCkgewotCV9yaWdodC5yZWR1Y2VLZXJuZWxQYXR0ZXJuKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlfbGVmdC50eXBlQ2hlY2soc3RhYmxlKTsKLQlyZXR1cm4gX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBsb2NhbCA9Ci0JICAgIG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlMigicHB0IiwgCi0JCQkJCVV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfU0lHKSwKLQkJCQkJaWwuZ2V0RW5kKCkpOwotCQotCWZpbmFsIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLkluc3RydWN0aW9uIGxvYWRMb2NhbCA9Ci0JICAgIG5ldyBJTE9BRChsb2NhbC5nZXRJbmRleCgpKTsKLQlmaW5hbCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbiBzdG9yZUxvY2FsID0KLQkgICAgbmV3IElTVE9SRShsb2NhbC5nZXRJbmRleCgpKTsKLQotCWlmIChfcmlnaHQuaXNXaWxkY2FyZCgpKSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKFNXQVApOwotCX0KLQllbHNlIGlmIChfcmlnaHQgaW5zdGFuY2VvZiBTdGVwUGF0dGVybikgewotCSAgICAvLyEhISBjaGVjayB0aGlzCi0KLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChzdG9yZUxvY2FsKTsKLQkgICAgCi0JICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIAotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGxvY2FsLnNldEVuZChpbC5hcHBlbmQobG9hZExvY2FsKSk7Ci0JfQotCWVsc2UgewotCSAgICBfcmlnaHQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQotCWZpbmFsIGludCBnZXRQYXJlbnQgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJCUdFVF9QQVJFTlQsCi0JCQkJCQkJR0VUX1BBUkVOVF9TSUcpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdldFBhcmVudCwgMikpOwotCi0JZmluYWwgU3ludGF4VHJlZU5vZGUgcCA9IGdldFBhcmVudCgpOwotCWlmICgocCA9PSBudWxsKSB8fAotCSAgICAocCBpbnN0YW5jZW9mIEluc3RydWN0aW9uKSB8fAotCSAgICAocCBpbnN0YW5jZW9mIFRvcExldmVsRWxlbWVudCkpIHsKLQkgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQllbHNlIHsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChzdG9yZUxvY2FsKTsKLQkgICAgCi0JICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGxvY2FsLnNldEVuZChpbC5hcHBlbmQobG9hZExvY2FsKSk7Ci0JfQotCi0JbWV0aG9kR2VuLnJlbW92ZUxvY2FsVmFyaWFibGUobG9jYWwpOwotCQotCV90cnVlTGlzdC5hcHBlbmQoX3JpZ2h0Ll90cnVlTGlzdC5hcHBlbmQoX2xlZnQuX3RydWVMaXN0KSk7Ci0JX2ZhbHNlTGlzdC5hcHBlbmQoX3JpZ2h0Ll9mYWxzZUxpc3QuYXBwZW5kKF9sZWZ0Ll9mYWxzZUxpc3QpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAiUGFyZW50KCIgKyBfbGVmdCArICIsICIgKyBfcmlnaHQgKyAnKSc7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGFyc2VyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9QYXJzZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzg5ZjRjNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9QYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNzUgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgamF2YV9jdXAucnVudGltZS5TeW1ib2w7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQXR0cmlidXRlTGlzdDsKLQotcHVibGljIGNsYXNzIFBhcnNlciBpbXBsZW1lbnRzIENvbnN0YW50cywgQ29udGVudEhhbmRsZXIgewotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTCA9ICJ4c2wiOyAgICAgICAgICAgIC8vIHN0YW5kYXJkIHByZWZpeAotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0xFVCA9ICJ0cmFuc2xldCI7IC8vIGV4dGVuc2lvbiBwcmVmaXgKLSAgICAKLSAgICBwcml2YXRlIFhTTFRDIF94c2x0YzsgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHRvIHRoZSBjb21waWxlciBvYmplY3QuCi0gICAgcHJpdmF0ZSBYUGF0aFBhcnNlciBfeHBhdGhQYXJzZXI7IC8vIFJlZmVyZW5jZSB0byB0aGUgWFBhdGggcGFyc2VyLgotICAgIHByaXZhdGUgVmVjdG9yIF9lcnJvcnM7ICAgICAgICAgICAvLyBDb250YWlucyBhbGwgY29tcGlsYXRpb24gZXJyb3JzCi0gICAgcHJpdmF0ZSBWZWN0b3IgX3dhcm5pbmdzOyAgICAgICAgIC8vIENvbnRhaW5zIGFsbCBjb21waWxhdGlvbiBlcnJvcnMKLQotICAgIHByaXZhdGUgSGFzaHRhYmxlICAgX2luc3RydWN0aW9uQ2xhc3NlczsgLy8gTWFwcyBpbnN0cnVjdGlvbnMgdG8gY2xhc3NlcwotICAgIHByaXZhdGUgSGFzaHRhYmxlICAgX3FOYW1lczsKLSAgICBwcml2YXRlIEhhc2h0YWJsZSAgIF9uYW1lc3BhY2VzOwotICAgIHByaXZhdGUgUU5hbWUgICAgICAgX3VzZUF0dHJpYnV0ZVNldHM7Ci0gICAgcHJpdmF0ZSBRTmFtZSAgICAgICBfZXhjbHVkZVJlc3VsdFByZWZpeGVzOwotICAgIHByaXZhdGUgUU5hbWUgICAgICAgX2V4dGVuc2lvbkVsZW1lbnRQcmVmaXhlczsKLSAgICBwcml2YXRlIEhhc2h0YWJsZSAgIF92YXJpYWJsZVNjb3BlOwotICAgIHByaXZhdGUgU3R5bGVzaGVldCAgX2N1cnJlbnRTdHlsZXNoZWV0OwotICAgIHByaXZhdGUgU3ltYm9sVGFibGUgX3N5bWJvbFRhYmxlOyAvLyBNYXBzIFFOYW1lcyB0byBzeW50YXgtdHJlZSBub2RlcwotICAgIHByaXZhdGUgT3V0cHV0ICAgICAgX291dHB1dCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBUZW1wbGF0ZSAgICBfdGVtcGxhdGU7ICAgIC8vIFJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgYmVpbmcgcGFyc2VkLgotCi0gICAgcHJpdmF0ZSBib29sZWFuICAgICBfcm9vdE5hbWVzcGFjZURlZiA9IGZhbHNlOyAvLyBVc2VkIGZvciB2YWxpZGl0eSBjaGVjawotCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZSBfcm9vdCA9IG51bGw7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfdGFyZ2V0OwotCi0gICAgcHJpdmF0ZSBpbnQgX2N1cnJlbnRJbXBvcnRQcmVjZWRlbmNlID0gMTsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBDTEFTU19OT1RfRk9VTkQgPQotCSJJbnRlcm5hbCBYU0xUQyBjbGFzcyBub3QgaW4gY2xhc3NwYXRoOiAiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBJTlRFUk5BTF9FUlJPUiA9Ci0JIlVucmVjb3ZlcmFibGUgWFNMVEMgY29tcGlsYXRpb24gZXJyb3I6ICI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFVOU1VQUE9SVEVEX1hTTF9FUlJPUiA9Ci0JIlVuc3VwcG9ydGVkIFhTTCBlbGVtZW50OiAiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBJTlZBTElEX0VYVF9FUlJPUiA9Ci0JIkludmFsaWQgWFNMVEMgZXh0ZW5zaW9uOiAiOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBVTlNVUFBPUlRFRF9FWFRfRVJST1IgPQotCSJVbnN1cHBvcnRlZCBYU0xUIGV4dGVuc2lvbjogIjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgVEVYVF9OT0RFX0VSUk9SID0KLQkiVGV4dCBkYXRhIG91dHNpZGUgb2YgdG9wLWxldmVsIDx4c2w6c3R5bGVzaGVldD4gZWxlbWVudC4iOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBNSVNTSU5HX0hSRUZfRVJST1IgPQotCSJQcm9jZXNzaW5nIGluc3RydWN0aW9uIDw/eG1sLXN0eWxlc2hlZXQgLi4uID8+IGlzIG1pc3NpbmcgaHJlZiBkYXRhLiI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIE1JU1NJTkdfWFNMVF9VUklfRVJST1IgPQotCSJUaGUgaW5wdXQgZG9jdW1lbnQgaXMgbm90IGEgc3R5bGVzaGVldCAiKwotCSIodGhlIFhTTCBuYW1lc3BhY2UgaXMgbm90IGRlY2xhcmVkIGluIHRoZSByb290IGVsZW1lbnQpLiI7Ci0KLSAgICBwdWJsaWMgUGFyc2VyKFhTTFRDIHhzbHRjKSB7Ci0JX3hzbHRjID0geHNsdGM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgaW5pdCgpIHsKLQlfcU5hbWVzICAgICAgICAgICAgICA9IG5ldyBIYXNodGFibGUoNTEyKTsKLQlfbmFtZXNwYWNlcyAgICAgICAgICA9IG5ldyBIYXNodGFibGUoKTsKLQlfaW5zdHJ1Y3Rpb25DbGFzc2VzICA9IG5ldyBIYXNodGFibGUoKTsKLQlfdmFyaWFibGVTY29wZSAgICAgICA9IG5ldyBIYXNodGFibGUoKTsKLQlfdGVtcGxhdGUgICAgICAgICAgICA9IG51bGw7Ci0JX2Vycm9ycyAgICAgICAgICAgICAgPSBuZXcgVmVjdG9yKCk7Ci0JX3dhcm5pbmdzICAgICAgICAgICAgPSBuZXcgVmVjdG9yKCk7Ci0JX3N5bWJvbFRhYmxlICAgICAgICAgPSBuZXcgU3ltYm9sVGFibGUoKTsKLQlfeHBhdGhQYXJzZXIgICAgICAgICA9IG5ldyBYUGF0aFBhcnNlcih0aGlzKTsKLQlfY3VycmVudFN0eWxlc2hlZXQgICA9IG51bGw7Ci0JX2N1cnJlbnRJbXBvcnRQcmVjZWRlbmNlID0gMTsKLQkKLQlpbml0U3RkQ2xhc3NlcygpOwotCWluaXRFeHRDbGFzc2VzKCk7Ci0JaW5pdFN5bWJvbFRhYmxlKCk7Ci0JCi0JX3VzZUF0dHJpYnV0ZVNldHMgPQotCSAgICBnZXRRTmFtZShYU0xUX1VSSSwgWFNMLCAidXNlLWF0dHJpYnV0ZS1zZXRzIik7Ci0JX2V4Y2x1ZGVSZXN1bHRQcmVmaXhlcyA9Ci0JICAgIGdldFFOYW1lKFhTTFRfVVJJLCBYU0wsICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIpOwotCV9leHRlbnNpb25FbGVtZW50UHJlZml4ZXMgPQotCSAgICBnZXRRTmFtZShYU0xUX1VSSSwgWFNMLCAiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXQoT3V0cHV0IG91dHB1dCkgewotCWlmIChfb3V0cHV0ID09IG51bGwpCi0JICAgIF9vdXRwdXQgPSBvdXRwdXQ7Ci0JZWxzZQotCSAgICBvdXRwdXQuZGlzYWJsZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZFZhcmlhYmxlKFZhcmlhYmxlIHZhcikgewotCV92YXJpYWJsZVNjb3BlLnB1dCh2YXIuZ2V0TmFtZSgpLCB2YXIpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGFkZFBhcmFtZXRlcihQYXJhbSBwYXJhbSkgewotCV92YXJpYWJsZVNjb3BlLnB1dChwYXJhbS5nZXROYW1lKCksIHBhcmFtKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVWYXJpYWJsZShRTmFtZSBuYW1lKSB7Ci0JX3ZhcmlhYmxlU2NvcGUucmVtb3ZlKG5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTeW50YXhUcmVlTm9kZSBsb29rdXBWYXJpYWJsZShRTmFtZSBuYW1lKSB7Ci0JcmV0dXJuIChTeW50YXhUcmVlTm9kZSlfdmFyaWFibGVTY29wZS5nZXQobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0WFNMVEMoWFNMVEMgeHNsdGMpIHsKLQlfeHNsdGMgPSB4c2x0YzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgWFNMVEMgZ2V0WFNMVEMoKSB7Ci0JcmV0dXJuIF94c2x0YzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEN1cnJlbnRJbXBvcnRQcmVjZWRlbmNlKCkgewotCXJldHVybiBfY3VycmVudEltcG9ydFByZWNlZGVuY2U7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBpbnQgZ2V0TmV4dEltcG9ydFByZWNlZGVuY2UoKSB7Ci0JcmV0dXJuICsrX2N1cnJlbnRJbXBvcnRQcmVjZWRlbmNlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldEN1cnJlbnRTdHlsZXNoZWV0KFN0eWxlc2hlZXQgc3R5bGVzaGVldCkgewotCV9jdXJyZW50U3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0Q3VycmVudFN0eWxlc2hlZXQoKSB7Ci0JcmV0dXJuIF9jdXJyZW50U3R5bGVzaGVldDsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0VG9wTGV2ZWxTdHlsZXNoZWV0KCkgewotCXJldHVybiBfeHNsdGMuZ2V0U3R5bGVzaGVldCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXRRTmFtZVNhZmUoZmluYWwgU3RyaW5nIHN0cmluZ1JlcCkgewotCS8vIHBhcnNlIGFuZCByZXRyaWV2ZSBuYW1lc3BhY2UKLQlmaW5hbCBpbnQgY29sb24gPSBzdHJpbmdSZXAubGFzdEluZGV4T2YoJzonKTsKLQlpZiAoY29sb24gIT0gLTEpIHsKLQkgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IHN0cmluZ1JlcC5zdWJzdHJpbmcoMCwgY29sb24pOwotCSAgICBmaW5hbCBTdHJpbmcgbG9jYWxuYW1lID0gc3RyaW5nUmVwLnN1YnN0cmluZyhjb2xvbiArIDEpOwotCSAgICBTdHJpbmcgbmFtZXNwYWNlID0gbnVsbDsKLQkgICAgCi0JICAgIC8vIEdldCB0aGUgbmFtZXNwYWNlIHVyaSBmcm9tIHRoZSBzeW1ib2wgdGFibGUKLQkgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbG5zIikgPT0gZmFsc2UpIHsKLQkJbmFtZXNwYWNlID0gX3N5bWJvbFRhYmxlLmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCQlpZiAobmFtZXNwYWNlID09IG51bGwpIG5hbWVzcGFjZSA9IENvbnN0YW50cy5FTVBUWVNUUklORzsKLQkgICAgfQotCSAgICByZXR1cm4gZ2V0UU5hbWUobmFtZXNwYWNlLCBwcmVmaXgsIGxvY2FsbmFtZSk7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4gZ2V0UU5hbWUoX3N5bWJvbFRhYmxlLmxvb2t1cE5hbWVzcGFjZShDb25zdGFudHMuRU1QVFlTVFJJTkcpLCBudWxsLCBzdHJpbmdSZXApOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFFOYW1lIGdldFFOYW1lKGZpbmFsIFN0cmluZyBzdHJpbmdSZXApIHsKLQkvLyBwYXJzZSBhbmQgcmV0cmlldmUgbmFtZXNwYWNlCi0JZmluYWwgaW50IGNvbG9uID0gc3RyaW5nUmVwLmxhc3RJbmRleE9mKCc6Jyk7Ci0JaWYgKGNvbG9uICE9IC0xKSB7Ci0JICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBzdHJpbmdSZXAuc3Vic3RyaW5nKDAsIGNvbG9uKTsKLQkgICAgZmluYWwgU3RyaW5nIGxvY2FsbmFtZSA9IHN0cmluZ1JlcC5zdWJzdHJpbmcoY29sb24gKyAxKTsKLQkgICAgU3RyaW5nIG5hbWVzcGFjZSA9IG51bGw7Ci0JICAgIAotCSAgICAvLyBHZXQgdGhlIG5hbWVzcGFjZSB1cmkgZnJvbSB0aGUgc3ltYm9sIHRhYmxlCi0JICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWxucyIpID09IGZhbHNlKSB7Ci0JCW5hbWVzcGFjZSA9IF9zeW1ib2xUYWJsZS5sb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLQkJaWYgKG5hbWVzcGFjZSA9PSBudWxsKSB7Ci0JCSAgICByZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsCi0JCQluZXcgRXJyb3JNc2coRXJyb3JNc2cuTlNQVU5ERUZfRVJSLCBwcmVmaXgpKTsgCi0JCSAgICBFeGNlcHRpb24gZSA9IG5ldyBFeGNlcHRpb24oKTsKLQkJICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0JCX0KLQkgICAgfQotCSAgICByZXR1cm4gZ2V0UU5hbWUobmFtZXNwYWNlLCBwcmVmaXgsIGxvY2FsbmFtZSk7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4gZ2V0UU5hbWUoX3N5bWJvbFRhYmxlLmxvb2t1cE5hbWVzcGFjZShDb25zdGFudHMuRU1QVFlTVFJJTkcpLCBudWxsLCBzdHJpbmdSZXApOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsbmFtZSkgewotCWlmIChuYW1lc3BhY2UgPT0gbnVsbCkgewotCSAgICBRTmFtZSBuYW1lID0gKFFOYW1lKV9xTmFtZXMuZ2V0KGxvY2FsbmFtZSk7Ci0JICAgIGlmIChuYW1lID09IG51bGwpIHsKLQkJX3FOYW1lcy5wdXQobG9jYWxuYW1lLAotCQkJICAgIG5hbWUgPSBuZXcgUU5hbWUobnVsbCwgcHJlZml4LCBsb2NhbG5hbWUpKTsKLQkgICAgfQotCSAgICByZXR1cm4gbmFtZTsKLQl9Ci0JZWxzZSB7Ci0JICAgIERpY3Rpb25hcnkgc3BhY2UgPSAoRGljdGlvbmFyeSlfbmFtZXNwYWNlcy5nZXQobmFtZXNwYWNlKTsKLQkgICAgaWYgKHNwYWNlID09IG51bGwpIHsKLQkJZmluYWwgUU5hbWUgbmFtZSA9IG5ldyBRTmFtZShuYW1lc3BhY2UsIHByZWZpeCwgbG9jYWxuYW1lKTsKLQkJX25hbWVzcGFjZXMucHV0KG5hbWVzcGFjZSwgc3BhY2UgPSBuZXcgSGFzaHRhYmxlKCkpOwotCQlzcGFjZS5wdXQobG9jYWxuYW1lLCBuYW1lKTsKLQkJcmV0dXJuIG5hbWU7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCVFOYW1lIG5hbWUgPSAoUU5hbWUpc3BhY2UuZ2V0KGxvY2FsbmFtZSk7Ci0JCWlmIChuYW1lID09IG51bGwpIHsKLQkJICAgIG5hbWUgPSBuZXcgUU5hbWUobmFtZXNwYWNlLCBwcmVmaXgsIGxvY2FsbmFtZSk7Ci0JCSAgICBzcGFjZS5wdXQobG9jYWxuYW1lLCBuYW1lKTsKLQkJfQotCQlyZXR1cm4gbmFtZTsKLQkgICAgfQotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFFOYW1lIGdldFFOYW1lKFN0cmluZyBzY29wZSwgU3RyaW5nIG5hbWUpIHsKLQlyZXR1cm4gZ2V0UU5hbWUoc2NvcGUgKyBuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoUU5hbWUgc2NvcGUsIFFOYW1lIG5hbWUpIHsKLQlyZXR1cm4gZ2V0UU5hbWUoc2NvcGUudG9TdHJpbmcoKSArIG5hbWUudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldFVzZUF0dHJpYnV0ZVNldHMoKSB7Ci0JcmV0dXJuIF91c2VBdHRyaWJ1dGVTZXRzOwotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXRFeHRlbnNpb25FbGVtZW50UHJlZml4ZXMoKSB7Ci0JcmV0dXJuIF9leHRlbnNpb25FbGVtZW50UHJlZml4ZXM7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldEV4Y2x1ZGVSZXN1bHRQcmVmaXhlcygpIHsKLQlyZXR1cm4gX2V4Y2x1ZGVSZXN1bHRQcmVmaXhlczsKLSAgICB9Ci0gICAgCi0gICAgLyoqCQotICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgPGNvZGU+U3R5bGVzaGVldDwvY29kZT4gY2xhc3MsCi0gICAgICogYW5kIHRoZW4gcGFyc2UsIHR5cGVjaGVjayBhbmQgY29tcGlsZSB0aGUgaW5zdGFuY2UuCi0gICAgICogTXVzdCBiZSBjYWxsZWQgYWZ0ZXIgPGNvZGU+cGFyc2UoKTwvY29kZT4uCi0gICAgICovCi0gICAgcHVibGljIFN0eWxlc2hlZXQgbWFrZVN0eWxlc2hlZXQoU3ludGF4VHJlZU5vZGUgZWxlbWVudCkgCi0JdGhyb3dzIENvbXBpbGVyRXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQ7Ci0KLQkgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0JCXN0eWxlc2hlZXQgPSAoU3R5bGVzaGVldCllbGVtZW50OwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlzdHlsZXNoZWV0ID0gbmV3IFN0eWxlc2hlZXQoKTsKLQkJc3R5bGVzaGVldC5zZXRTaW1wbGlmaWVkKCk7Ci0JCXN0eWxlc2hlZXQuYWRkRWxlbWVudChlbGVtZW50KTsKLQkgICAgfQotCSAgICBzdHlsZXNoZWV0LnNldFBhcnNlcih0aGlzKTsKLQkgICAgcmV0dXJuIHN0eWxlc2hlZXQ7Ci0JfQotCWNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gZSkgewotCSAgICB0aHJvdyBuZXcgQ29tcGlsZXJFeGNlcHRpb24oIlRoZSBpbnB1dCBkb2N1bWVudCBkb2VzIG5vdCAiKwotCQkJCQkiY29udGFpbiBhbiBYU0wgc3R5bGVzaGVldC4iKTsKLQl9Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIEluc3RhbmNpYXRlcyBhIFNBWDIgcGFyc2VyIGFuZCBnZW5lcmF0ZSB0aGUgQVNUIGZyb20gdGhlIGlucHV0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNyZWF0ZUFTVChTdHlsZXNoZWV0IHN0eWxlc2hlZXQpIHsKLQl0cnkgewotCSAgICBpZiAoc3R5bGVzaGVldCAhPSBudWxsKSB7Ci0JCXN0eWxlc2hlZXQucGFyc2VDb250ZW50cyh0aGlzKTsKLQkJZmluYWwgaW50IHByZWNlZGVuY2UgPSBzdHlsZXNoZWV0LmdldEltcG9ydFByZWNlZGVuY2UoKTsKLQkJZmluYWwgRW51bWVyYXRpb24gZWxlbWVudHMgPSBzdHlsZXNoZWV0LmVsZW1lbnRzKCk7Ci0JCXdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkgICAgT2JqZWN0IGNoaWxkID0gZWxlbWVudHMubmV4dEVsZW1lbnQoKTsKLQkJICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFRleHQpIHsKLQkJCXJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwKLQkJCSAgICBuZXcgRXJyb3JNc2coVEVYVF9OT0RFX0VSUk9SKSk7Ci0JCSAgICB9Ci0JCX0KLQkJaWYgKCFlcnJvcnNGb3VuZCgpKSB7Ci0JCSAgICBzdHlsZXNoZWV0LnR5cGVDaGVjayhfc3ltYm9sVGFibGUpOwotCQl9Ci0JICAgIH0KLQl9Ci0JY2F0Y2ggKFR5cGVDaGVja0Vycm9yIGUpIHsKLQkgICAgcmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBuZXcgRXJyb3JNc2coZS50b1N0cmluZygpKSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyBhIHN0eWxlc2hlZXQgYW5kIGJ1aWxkcyB0aGUgaW50ZXJuYWwgYWJzdHJhY3Qgc3ludGF4IHRyZWUKLSAgICAgKiBAcGFyYW0gcmVhZGVyIEEgU0FYMiBTQVhSZWFkZXIgKHBhcnNlcikKLSAgICAgKiBAcGFyYW0gaW5wdXQgQSBTQVgyIElucHV0U291cmNlIGNhbiBiZSBwYXNzZWQgdG8gYSBTQVggcmVhZGVyCi0gICAgICogQHJldHVybiBUaGUgcm9vdCBvZiB0aGUgYWJzdHJhY3Qgc3ludGF4IHRyZWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3ludGF4VHJlZU5vZGUgcGFyc2UoWE1MUmVhZGVyIHJlYWRlciwgSW5wdXRTb3VyY2UgaW5wdXQpIHsKLQl0cnkgewotCSAgICAvLyBQYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgYW5kIGJ1aWxkIHRoZSBhYnN0cmFjdCBzeW50YXggdHJlZQotCSAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0JICAgIHJlYWRlci5wYXJzZShpbnB1dCk7Ci0JICAgIC8vIEZpbmQgdGhlIHN0YXJ0IG9mIHRoZSBzdHlsZXNoZWV0IHdpdGhpbiB0aGUgdHJlZQotCSAgICByZXR1cm4gKFN5bnRheFRyZWVOb2RlKWdldFN0eWxlc2hlZXQoX3Jvb3QpOwkKLQl9Ci0JY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLQkgICAgcmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLAotCQluZXcgRXJyb3JNc2coZS5nZXRNZXNzYWdlKCkpKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbmV3IEVycm9yTXNnKGUuZ2V0TWVzc2FnZSgpKSk7Ci0JfQotCWNhdGNoIChDb21waWxlckV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbmV3IEVycm9yTXNnKGUuZ2V0TWVzc2FnZSgpKSk7Ci0JfQotCXJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyBhIHN0eWxlc2hlZXQgYW5kIGJ1aWxkcyB0aGUgaW50ZXJuYWwgYWJzdHJhY3Qgc3ludGF4IHRyZWUKLSAgICAgKiBAcGFyYW0gaW5wdXQgQSBTQVgyIElucHV0U291cmNlIGNhbiBiZSBwYXNzZWQgdG8gYSBTQVggcmVhZGVyCi0gICAgICogQHJldHVybiBUaGUgcm9vdCBvZiB0aGUgYWJzdHJhY3Qgc3ludGF4IHRyZWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3ludGF4VHJlZU5vZGUgcGFyc2UoSW5wdXRTb3VyY2UgaW5wdXQpIHsKLQl0cnkgewotCSAgICAvLyBDcmVhdGUgYSBTQVggcGFyc2VyIGFuZCBnZXQgdGhlIFhNTFJlYWRlciBvYmplY3QgaXQgdXNlcwotCSAgICBmaW5hbCBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0JICAgIHRyeSB7Ci0JCWZhY3Rvcnkuc2V0RmVhdHVyZShDb25zdGFudHMuTkFNRVNQQUNFX0ZFQVRVUkUsdHJ1ZSk7Ci0JICAgIH0KLQkgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCWZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0JICAgIH0KLQkgICAgZmluYWwgU0FYUGFyc2VyIHBhcnNlciA9IGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0JICAgIGZpbmFsIFhNTFJlYWRlciByZWFkZXIgPSBwYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0JICAgIHJldHVybihwYXJzZShyZWFkZXIsIGlucHV0KSk7Ci0JfQotCWNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLQkgICAgcmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLAotCQluZXcgRXJyb3JNc2coIkpBWFAgcGFyc2VyIG5vdCBjb25maWd1cmVkIGNvcnJlY3RseSIpKTsKLQl9Ci0JY2F0Y2ggKFNBWFBhcnNlRXhjZXB0aW9uIGUpewotCSAgICByZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsCi0JCW5ldyBFcnJvck1zZyhlLmdldE1lc3NhZ2UoKSxlLmdldExpbmVOdW1iZXIoKSkpOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkgICAgcmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBuZXcgRXJyb3JNc2coZS5nZXRNZXNzYWdlKCkpKTsKLQl9Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN5bnRheFRyZWVOb2RlIGdldERvY3VtZW50Um9vdCgpIHsKLQlyZXR1cm4gX3Jvb3Q7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgX1BJbWVkaWEgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9QSXRpdGxlID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfUEljaGFyc2V0ID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgcGFyYW1ldGVycyB0byB1c2UgdG8gbG9jYXRlIHRoZSBjb3JyZWN0IDw/eG1sLXN0eWxlc2hlZXQgLi4uPz4KLSAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBpbnB1dCBkb2N1bWVudCBpcyBhbgotICAgICAqIFhNTCBkb2N1bWVudCB3aXRoIG9uZSBvciBtb3JlIHJlZmVyZW5jZXMgdG8gYSBzdHlsZXNoZWV0LgotICAgICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgICAqIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgICAqIEBwYXJhbSB0aXRsZSBUaGUgdmFsdWUgb2YgdGhlIHRpdGxlIGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0UElQYXJhbWV0ZXJzKFN0cmluZyBtZWRpYSwgU3RyaW5nIHRpdGxlLCBTdHJpbmcgY2hhcnNldCkgewotCV9QSW1lZGlhID0gbWVkaWE7Ci0JX1BJdGl0bGUgPSB0aXRsZTsKLQlfUEljaGFyc2V0ID0gY2hhcnNldDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0cyB0aGUgRE9NIGZvciB0aGUgc3R5bGVzaGVldC4gSW4gdGhlIGNhc2Ugb2YgYW4gZW1iZWRkZWQKLSAgICAgKiBzdHlsZXNoZWV0LCBpdCBleHRyYWN0cyB0aGUgRE9NIHN1YnRyZWUgY29ycmVzcG9uZGluZyB0byB0aGUgCi0gICAgICogZW1iZWRkZWQgc3R5bGVzaGVldCB0aGF0IGhhcyBhbiAnaWQnIGF0dHJpYnV0ZSB3aG9zZSB2YWx1ZSBpcyB0aGUKLSAgICAgKiBzYW1lIGFzIHRoZSB2YWx1ZSBkZWNsYXJlZCBpbiB0aGUgPD94bWwtc3R5bGVzaGVldC4uLj8+IHByb2Nlc3NpbmcgCi0gICAgICogaW5zdHJ1Y3Rpb24gKFAuSS4pLiBJbiB0aGUgeG1sLXN0eWxlc2hlZXQgUC5JLiB0aGUgdmFsdWUgaXMgbGFiZWxlZAotICAgICAqIGFzIHRoZSAnaHJlZicgZGF0YSBvZiB0aGUgUC5JLiBUaGUgZXh0cmFjdGVkIERPTSByZXByZXNlbnRpbmcgdGhlCi0gICAgICogc3R5bGVzaGVldCBpcyByZXR1cm5lZCBhcyBhbiBFbGVtZW50IG9iamVjdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN5bnRheFRyZWVOb2RlIGdldFN0eWxlc2hlZXQoU3ludGF4VHJlZU5vZGUgcm9vdCkKLQl0aHJvd3MgQ29tcGlsZXJFeGNlcHRpb24gewotCi0JLy8gQXNzdW1lIHRoYXQgdGhpcyBpcyBhIHB1cmUgWFNMIHN0eWxlc2hlZXQgaWYgdGhlcmUgaXMgbm90Ci0JLy8gPD94bWwtc3R5bGVzaGVldCAuLi4uPz4gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbgotCWlmIChfdGFyZ2V0ID09IG51bGwpIHsKLQkgICAgaWYgKCFfcm9vdE5hbWVzcGFjZURlZikKLQkJdGhyb3cgbmV3IENvbXBpbGVyRXhjZXB0aW9uKE1JU1NJTkdfWFNMVF9VUklfRVJST1IpOwotCSAgICByZXR1cm4ocm9vdCk7Ci0JfQotCi0JLy8gRmluZCB0aGUgeHNsOnN0eWxlc2hlZXQgb3IgeHNsOnRyYW5zZm9ybSB3aXRoIHRoaXMgcmVmZXJlbmNlCi0JaWYgKF90YXJnZXQuY2hhckF0KDApID09ICcjJykgewotCSAgICBTeW50YXhUcmVlTm9kZSBlbGVtZW50ID0gZmluZFN0eWxlc2hlZXQocm9vdCwgX3RhcmdldC5zdWJzdHJpbmcoMSkpOwotCSAgICByZXR1cm4oZWxlbWVudCk7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4obG9hZEV4dGVybmFsU3R5bGVzaGVldChfdGFyZ2V0KSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZpbmQgYSBTdHlsZXNoZWV0IGVsZW1lbnQgd2l0aCBhIHNwZWNpZmljIElEIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGZpbmQgYSBTdHlsZXNoZWV0IG5vZGUgdGhhdCBpcyByZWZlcnJlZAotICAgICAqIGluIGEgPD94bWwtc3R5bGVzaGVldCAuLi4gPz4gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN5bnRheFRyZWVOb2RlIGZpbmRTdHlsZXNoZWV0KFN5bnRheFRyZWVOb2RlIHJvb3QsIFN0cmluZyBocmVmKSB7Ci0KLQlpZiAocm9vdCA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQotCWlmIChyb290IGluc3RhbmNlb2YgU3R5bGVzaGVldCkgewotCSAgICBTdHJpbmcgaWQgPSByb290LmdldEF0dHJpYnV0ZSgiaWQiKTsKLQkgICAgaWYgKGlkLmVxdWFscyhocmVmKSkgcmV0dXJuIHJvb3Q7Ci0JfQotCVZlY3RvciBjaGlsZHJlbiA9IHJvb3QuZ2V0Q29udGVudHMoKTsKLQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgY291bnQgPSBjaGlsZHJlbi5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQlTeW50YXhUcmVlTm9kZSBjaGlsZCA9IChTeW50YXhUcmVlTm9kZSljaGlsZHJlbi5lbGVtZW50QXQoaSk7Ci0JCVN5bnRheFRyZWVOb2RlIG5vZGUgPSBmaW5kU3R5bGVzaGVldChjaGlsZCwgaHJlZik7Ci0JCWlmIChub2RlICE9IG51bGwpIHJldHVybiBub2RlOwotCSAgICB9Ci0JfQotCXJldHVybiBudWxsOwkKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGb3IgZW1iZWRkZWQgc3R5bGVzaGVldHM6IExvYWQgYW4gZXh0ZXJuYWwgZmlsZSB3aXRoIHN0eWxlc2hlZXQKLSAgICAgKi8KLSAgICBwcml2YXRlIFN5bnRheFRyZWVOb2RlIGxvYWRFeHRlcm5hbFN0eWxlc2hlZXQoU3RyaW5nIGxvY2F0aW9uKQotCXRocm93cyBDb21waWxlckV4Y2VwdGlvbiB7Ci0KLQlJbnB1dFNvdXJjZSBzb3VyY2U7Ci0KLQkvLyBDaGVjayBpZiB0aGUgbG9jYXRpb24gaXMgVVJMIG9yIGEgbG9jYWwgZmlsZQotCWlmICgobmV3IEZpbGUobG9jYXRpb24pKS5leGlzdHMoKSkKLQkgICAgc291cmNlID0gbmV3IElucHV0U291cmNlKCJmaWxlOiIrbG9jYXRpb24pOwotCWVsc2UKLQkgICAgc291cmNlID0gbmV3IElucHV0U291cmNlKGxvY2F0aW9uKTsKLQotCVN5bnRheFRyZWVOb2RlIGV4dGVybmFsID0gKFN5bnRheFRyZWVOb2RlKXBhcnNlKHNvdXJjZSk7Ci0JcmV0dXJuKGV4dGVybmFsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplIHRoZSBfaW5zdHJ1Y3Rpb25DbGFzc2VzIEhhc2h0YWJsZSwgd2hpY2ggbWFwcyBYU0wgZWxlbWVudAotICAgICAqIG5hbWVzIHRvIEphdmEgY2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGluaXRTdGRDbGFzc2VzKCkgewotCWluaXRTdGRDbGFzcygidGVtcGxhdGUiLCAiVGVtcGxhdGUiKTsKLQlpbml0U3RkQ2xhc3MoInN0eWxlc2hlZXQiLCAiU3R5bGVzaGVldCIpOwotCWluaXRTdGRDbGFzcygidHJhbnNmb3JtIiwgIlN0eWxlc2hlZXQiKTsKLQlpbml0U3RkQ2xhc3MoInRleHQiLCAiVGV4dCIpOwotCWluaXRTdGRDbGFzcygiaWYiLCAiSWYiKTsKLQlpbml0U3RkQ2xhc3MoImNob29zZSIsICJDaG9vc2UiKTsKLQlpbml0U3RkQ2xhc3MoIndoZW4iLCAiV2hlbiIpOwotCWluaXRTdGRDbGFzcygib3RoZXJ3aXNlIiwgIk90aGVyd2lzZSIpOwotCWluaXRTdGRDbGFzcygiZm9yLWVhY2giLCAiRm9yRWFjaCIpOwotCWluaXRTdGRDbGFzcygibWVzc2FnZSIsICJNZXNzYWdlIik7Ci0JaW5pdFN0ZENsYXNzKCJudW1iZXIiLCAiTnVtYmVyIik7Ci0JaW5pdFN0ZENsYXNzKCJjb21tZW50IiwgIkNvbW1lbnQiKTsKLQlpbml0U3RkQ2xhc3MoImNvcHkiLCAiQ29weSIpOwotCWluaXRTdGRDbGFzcygiY29weS1vZiIsICJDb3B5T2YiKTsKLQlpbml0U3RkQ2xhc3MoInBhcmFtIiwgIlBhcmFtIik7Ci0JaW5pdFN0ZENsYXNzKCJ3aXRoLXBhcmFtIiwgIldpdGhQYXJhbSIpOwotCWluaXRTdGRDbGFzcygidmFyaWFibGUiLCAiVmFyaWFibGUiKTsKLQlpbml0U3RkQ2xhc3MoIm91dHB1dCIsICJPdXRwdXQiKTsKLQlpbml0U3RkQ2xhc3MoInNvcnQiLCAiU29ydCIpOwotCWluaXRTdGRDbGFzcygia2V5IiwgIktleSIpOwotCWluaXRTdGRDbGFzcygiZmFsbGJhY2siLCAiRmFsbGJhY2siKTsKLQlpbml0U3RkQ2xhc3MoImF0dHJpYnV0ZSIsICJYc2xBdHRyaWJ1dGUiKTsKLQlpbml0U3RkQ2xhc3MoImF0dHJpYnV0ZS1zZXQiLCAiQXR0cmlidXRlU2V0Iik7Ci0JaW5pdFN0ZENsYXNzKCJ2YWx1ZS1vZiIsICJWYWx1ZU9mIik7Ci0JaW5pdFN0ZENsYXNzKCJlbGVtZW50IiwgIlhzbEVsZW1lbnQiKTsKLQlpbml0U3RkQ2xhc3MoImNhbGwtdGVtcGxhdGUiLCAiQ2FsbFRlbXBsYXRlIik7Ci0JaW5pdFN0ZENsYXNzKCJhcHBseS10ZW1wbGF0ZXMiLCAiQXBwbHlUZW1wbGF0ZXMiKTsKLQlpbml0U3RkQ2xhc3MoImFwcGx5LWltcG9ydHMiLCAiQXBwbHlJbXBvcnRzIik7Ci0JaW5pdFN0ZENsYXNzKCJkZWNpbWFsLWZvcm1hdCIsICJEZWNpbWFsRm9ybWF0dGluZyIpOwotCWluaXRTdGRDbGFzcygiaW1wb3J0IiwgIkltcG9ydCIpOwotCWluaXRTdGRDbGFzcygiaW5jbHVkZSIsICJJbmNsdWRlIik7Ci0JaW5pdFN0ZENsYXNzKCJzdHJpcC1zcGFjZSIsICJXaGl0ZXNwYWNlIik7Ci0JaW5pdFN0ZENsYXNzKCJwcmVzZXJ2ZS1zcGFjZSIsICJXaGl0ZXNwYWNlIik7Ci0JaW5pdFN0ZENsYXNzKCJwcm9jZXNzaW5nLWluc3RydWN0aW9uIiwgIlByb2Nlc3NpbmdJbnN0cnVjdGlvbiIpOwotCWluaXRTdGRDbGFzcygibmFtZXNwYWNlLWFsaWFzIiwgIk5hbWVzcGFjZUFsaWFzIik7Ci0gICAgfQotICAgIAotICAgIHByaXZhdGUgdm9pZCBpbml0U3RkQ2xhc3MoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgY2xhc3NOYW1lKSB7Ci0JX2luc3RydWN0aW9uQ2xhc3Nlcy5wdXQoZ2V0UU5hbWUoWFNMVF9VUkksIFhTTCwgZWxlbWVudE5hbWUpLAotCQkJCUNPTVBJTEVSX1BBQ0tBR0UgKyAnLicgKyBjbGFzc05hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGVsZW1lbnRTdXBwb3J0ZWQoUU5hbWUgcW5hbWUpIHsKLQlyZXR1cm4oX2luc3RydWN0aW9uQ2xhc3Nlcy5nZXQocW5hbWUpICE9IG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGZ1bmN0aW9uU3VwcG9ydGVkKFN0cmluZyBmbmFtZSkgewotCXJldHVybihfc3ltYm9sVGFibGUubG9va3VwUHJpbW9wKGZuYW1lKSAhPSBudWxsKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaW5pdEV4dENsYXNzZXMoKSB7Ci0JaW5pdEV4dENsYXNzKCJvdXRwdXQiLCAiVHJhbnNsZXRPdXRwdXQiKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgaW5pdEV4dENsYXNzKFN0cmluZyBlbGVtZW50TmFtZSwgU3RyaW5nIGNsYXNzTmFtZSkgewotCV9pbnN0cnVjdGlvbkNsYXNzZXMucHV0KGdldFFOYW1lKFRSQU5TTEVUX1VSSSwgVFJBTlNMRVQsIGVsZW1lbnROYW1lKSwKLQkJCQlDT01QSUxFUl9QQUNLQUdFICsgJy4nICsgY2xhc3NOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgcHJpbW9wcyBhbmQgYmFzZSBmdW5jdGlvbnMgdG8gdGhlIHN5bWJvbCB0YWJsZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgaW5pdFN5bWJvbFRhYmxlKCkgewotCU1ldGhvZFR5cGUgSV9WICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuSW50LCBUeXBlLlZvaWQpOwotCU1ldGhvZFR5cGUgSV9SICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuSW50LCBUeXBlLlJlYWwpOwotCU1ldGhvZFR5cGUgSV9TICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuSW50LCBUeXBlLlN0cmluZyk7Ci0JTWV0aG9kVHlwZSBJX0QgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5JbnQsIFR5cGUuTm9kZVNldCk7Ci0JTWV0aG9kVHlwZSBSX0kgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5SZWFsLCBUeXBlLkludCk7Ci0JTWV0aG9kVHlwZSBSX1YgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5SZWFsLCBUeXBlLlZvaWQpOwotCU1ldGhvZFR5cGUgUl9SICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuUmVhbCwgVHlwZS5SZWFsKTsKLQlNZXRob2RUeXBlIFJfRCAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlJlYWwsIFR5cGUuTm9kZVNldCk7Ci0JTWV0aG9kVHlwZSBSX08gID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5SZWFsLCBUeXBlLlJlZmVyZW5jZSk7Ci0JTWV0aG9kVHlwZSBJX0kgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5JbnQsIFR5cGUuSW50KTsKLSAJTWV0aG9kVHlwZSBEX08gID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Ob2RlU2V0LCBUeXBlLlJlZmVyZW5jZSk7Ci0JTWV0aG9kVHlwZSBEX1YgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Ob2RlU2V0LCBUeXBlLlZvaWQpOwotCU1ldGhvZFR5cGUgRF9TICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuTm9kZVNldCwgVHlwZS5TdHJpbmcpOwotCU1ldGhvZFR5cGUgRF9EICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuTm9kZVNldCwgVHlwZS5Ob2RlU2V0KTsKLQlNZXRob2RUeXBlIEFfViAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLk5vZGUsIFR5cGUuVm9pZCk7Ci0JTWV0aG9kVHlwZSBTX1YgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuVm9pZCk7Ci0JTWV0aG9kVHlwZSBTX1MgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLQlNZXRob2RUeXBlIFNfQSAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5Ob2RlKTsKLQlNZXRob2RUeXBlIFNfRCAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5Ob2RlU2V0KTsKLQlNZXRob2RUeXBlIFNfTyAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5SZWZlcmVuY2UpOwotCU1ldGhvZFR5cGUgQl9PICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuQm9vbGVhbiwgVHlwZS5SZWZlcmVuY2UpOwotCU1ldGhvZFR5cGUgQl9WICA9IG5ldyBNZXRob2RUeXBlKFR5cGUuQm9vbGVhbiwgVHlwZS5Wb2lkKTsKLQlNZXRob2RUeXBlIEJfQiAgPSBuZXcgTWV0aG9kVHlwZShUeXBlLkJvb2xlYW4sIFR5cGUuQm9vbGVhbik7Ci0JTWV0aG9kVHlwZSBCX1MgID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLlN0cmluZyk7Ci0JTWV0aG9kVHlwZSBSX1JSID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5SZWFsLCBUeXBlLlJlYWwsIFR5cGUuUmVhbCk7Ci0JTWV0aG9kVHlwZSBJX0lJID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5JbnQsIFR5cGUuSW50LCBUeXBlLkludCk7Ci0JTWV0aG9kVHlwZSBCX1JSID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLlJlYWwsIFR5cGUuUmVhbCk7Ci0JTWV0aG9kVHlwZSBCX0lJID0gbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLkludCwgVHlwZS5JbnQpOwotCU1ldGhvZFR5cGUgU19TUyA9IG5ldyBNZXRob2RUeXBlKFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcpOwotCU1ldGhvZFR5cGUgU19EUyA9IG5ldyBNZXRob2RUeXBlKFR5cGUuU3RyaW5nLCBUeXBlLlJlYWwsIFR5cGUuU3RyaW5nKTsKLQlNZXRob2RUeXBlIFNfU1IgPSBuZXcgTWV0aG9kVHlwZShUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuUmVhbCk7Ci0KLQlNZXRob2RUeXBlIERfU1MgPQotCSAgICBuZXcgTWV0aG9kVHlwZShUeXBlLk5vZGVTZXQsIFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZyk7Ci0JTWV0aG9kVHlwZSBEX1NEID0gCi0JICAgIG5ldyBNZXRob2RUeXBlKFR5cGUuTm9kZVNldCwgVHlwZS5TdHJpbmcsIFR5cGUuTm9kZVNldCk7Ci0JTWV0aG9kVHlwZSBCX0JCID0KLQkgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLkJvb2xlYW4sIFR5cGUuQm9vbGVhbik7Ci0JTWV0aG9kVHlwZSBCX1NTID0KLQkgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5Cb29sZWFuLCBUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcpOwotCU1ldGhvZFR5cGUgU19TRCA9Ci0JICAgIG5ldyBNZXRob2RUeXBlKFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZywgVHlwZS5Ob2RlU2V0KTsKLQlNZXRob2RUeXBlIFNfRFNTID0KLQkgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuUmVhbCwgVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLQlNZXRob2RUeXBlIFNfU1JSID0KLQkgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nLCBUeXBlLlJlYWwsIFR5cGUuUmVhbCk7Ci0JTWV0aG9kVHlwZSBTX1NTUyA9Ci0JICAgIG5ldyBNZXRob2RUeXBlKFR5cGUuU3RyaW5nLCBUeXBlLlN0cmluZywgVHlwZS5TdHJpbmcsIFR5cGUuU3RyaW5nKTsKLQotCS8qCi0JICogU3RhbmRhcmQgZnVuY3Rpb25zOiBpbXBsZW1lbnRlZCBidXQgbm90IGluIHRoaXMgdGFibGUgY29uY2F0KCkuCi0JICogV2hlbiBhZGRpbmcgYSBuZXcgZnVuY3Rpb24gbWFrZSBzdXJlIHRvIHVuY29tbWVudAotCSAqIHRoZSBjb3JyZXNwb25kaW5nIGxpbmUgaW4gPHR0PkZ1bmN0aW9uQXZhaWxhYmxlQ2FsbDwvdHQ+LgotCSAqLwotCi0JLy8gVGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgYXJlIGlubGluZWQKLQotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImN1cnJlbnQiLCBBX1YpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImxhc3QiLCBJX1YpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInBvc2l0aW9uIiwgSV9WKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJ0cnVlIiwgQl9WKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJmYWxzZSIsIEJfVik7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibm90IiwgQl9CKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJuYW1lIiwgU19WKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJuYW1lIiwgU19BKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJnZW5lcmF0ZS1pZCIsIFNfVik7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiZ2VuZXJhdGUtaWQiLCBTX0EpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImNlaWxpbmciLCBSX1IpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImZsb29yIiwgUl9SKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJyb3VuZCIsIElfUik7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiY29udGFpbnMiLCBCX1NTKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJudW1iZXIiLCBSX08pOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm51bWJlciIsIFJfVik7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiYm9vbGVhbiIsIEJfTyk7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgic3RyaW5nIiwgU19PKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdHJpbmciLCBTX1YpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInRyYW5zbGF0ZSIsIFNfU1NTKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdHJpbmctbGVuZ3RoIiwgSV9WKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdHJpbmctbGVuZ3RoIiwgSV9TKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdGFydHMtd2l0aCIsIEJfU1MpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImZvcm1hdC1udW1iZXIiLCBTX0RTKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJmb3JtYXQtbnVtYmVyIiwgU19EU1MpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInVucGFyc2VkLWVudGl0eS11cmkiLCBTX1MpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImtleSIsIERfU1MpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImtleSIsIERfU0QpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImlkIiwgRF9TKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJpZCIsIERfRCk7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibmFtZXNwYWNlLXVyaSIsIFNfVik7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiZnVuY3Rpb24tYXZhaWxhYmxlIiwgQl9TKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJlbGVtZW50LWF2YWlsYWJsZSIsIEJfUyk7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiZG9jdW1lbnQiLCBEX1MpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImRvY3VtZW50IiwgRF9WKTsKLQotCS8vIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGFyZSBpbXBsZW1lbnRlZCBpbiB0aGUgYmFzaXMgbGlicmFyeQotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImNvdW50IiwgSV9EKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdW0iLCBSX0QpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImxvY2FsLW5hbWUiLCBTX1YpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoImxvY2FsLW5hbWUiLCBTX0QpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm5hbWVzcGFjZS11cmkiLCBTX1YpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIm5hbWVzcGFjZS11cmkiLCBTX0QpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN1YnN0cmluZyIsIFNfU1IpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN1YnN0cmluZyIsIFNfU1JSKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdWJzdHJpbmctYWZ0ZXIiLCBTX1NTKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJzdWJzdHJpbmctYmVmb3JlIiwgU19TUyk7Ci0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgibm9ybWFsaXplLXNwYWNlIiwgU19WKTsKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJub3JtYWxpemUtc3BhY2UiLCBTX1MpOwotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoInN5c3RlbS1wcm9wZXJ0eSIsIFNfUyk7Ci0KLQkvLyBPcGVyYXRvcnMgKywgLSwgKiwgLywgJSBkZWZpbmVkIG9uIHJlYWwgdHlwZXMuCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiKyIsIFJfUlIpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCItIiwgUl9SUik7CQotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIioiLCBSX1JSKTsJCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiLyIsIFJfUlIpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCIlIiwgUl9SUik7CQotCi0JLy8gT3BlcmF0b3JzICssIC0sICogZGVmaW5lZCBvbiBpbnRlZ2VyIHR5cGVzLgotCS8vIE9wZXJhdG9ycyAvIGFuZCAlIGFyZSBub3QgIGRlZmluZWQgb24gaW50ZWdlcnMgKG1heSBjYXVzZSBleGNlcHRpb24pCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiKyIsIElfSUkpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCItIiwgSV9JSSk7CQotCV9zeW1ib2xUYWJsZS5hZGRQcmltb3AoIioiLCBJX0lJKTsJCi0KLQkgLy8gT3BlcmF0b3JzIDwsIDw9ID4sID49IGRlZmluZWQgb24gcmVhbCB0eXBlcy4KLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8IiwgIEJfUlIpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8PSIsIEJfUlIpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+IiwgIEJfUlIpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+PSIsIEJfUlIpOwkKLQotCS8vIE9wZXJhdG9ycyA8LCA8PSA+LCA+PSBkZWZpbmVkIG9uIGludCB0eXBlcy4KLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8IiwgIEJfSUkpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI8PSIsIEJfSUkpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+IiwgIEJfSUkpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCI+PSIsIEJfSUkpOwkKLQotCS8vIE9wZXJhdG9ycyA8LCA8PSA+LCA+PSBkZWZpbmVkIG9uIGJvb2xlYW4gdHlwZXMuCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPCIsICBCX0JCKTsJCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPD0iLCBCX0JCKTsJCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPiIsICBCX0JCKTsJCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiPj0iLCBCX0JCKTsJCi0KLQkvLyBPcGVyYXRvcnMgJ2FuZCcgYW5kICdvcicuCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgib3IiLCBCX0JCKTsJCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgiYW5kIiwgQl9CQik7CQotCi0JLy8gVW5hcnkgbWludXMuCi0JX3N5bWJvbFRhYmxlLmFkZFByaW1vcCgidS0iLCBSX1IpOwkKLQlfc3ltYm9sVGFibGUuYWRkUHJpbW9wKCJ1LSIsIElfSSk7CQotICAgIH0KLQotICAgIHB1YmxpYyBTeW1ib2xUYWJsZSBnZXRTeW1ib2xUYWJsZSgpIHsKLQlyZXR1cm4gX3N5bWJvbFRhYmxlOwotICAgIH0KLQotICAgIHB1YmxpYyBUZW1wbGF0ZSBnZXRUZW1wbGF0ZSgpIHsKLQlyZXR1cm4gX3RlbXBsYXRlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFRlbXBsYXRlKFRlbXBsYXRlIHRlbXBsYXRlKSB7Ci0JX3RlbXBsYXRlID0gdGVtcGxhdGU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBpbnQgX3RlbXBsYXRlSW5kZXggPSAwOwotCi0gICAgcHVibGljIGludCBnZXRUZW1wbGF0ZUluZGV4KCkgewotCXJldHVybihfdGVtcGxhdGVJbmRleCsrKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IG5vZGUgaW4gdGhlIGFic3RyYWN0IHN5bnRheCB0cmVlLiBUaGlzIG5vZGUgY2FuIGJlCi0gICAgICogIG8pIGEgc3VwcG9ydGVkIFhTTFQgMS4wIGVsZW1lbnQKLSAgICAgKiAgbykgYW4gdW5zdXBwb3J0ZWQgWFNMVCBlbGVtZW50IChwb3N0IDEuMCkKLSAgICAgKiAgbykgYSBzdXBwb3J0ZWQgWFNMVCBleHRlbnNpb24KLSAgICAgKiAgbykgYW4gdW5zdXBwb3J0ZWQgWFNMVCBleHRlbnNpb24KLSAgICAgKiAgbykgYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50IChub3QgYW4gWFNMVCBlbGVtZW50IGFuZCBub3QgYW4gZXh0ZW5zaW9uKQotICAgICAqIFVuc3VwcG9ydGVkIGVsZW1lbnRzIGRvIG5vdCBkaXJlY3RseSBnZW5lcmF0ZSBhbiBlcnJvci4gV2UgaGF2ZSB0byB3YWl0Ci0gICAgICogdW50aWwgd2UgaGF2ZSByZWNlaXZlZCBhbGwgY2hpbGQgZWxlbWVudHMgb2YgYW4gdW5zdXBwb3J0ZWQgZWxlbWVudCB0bwotICAgICAqIHNlZSBpZiBhbnkgPHhzbDpmYWxsYmFjaz4gZWxlbWVudHMgZXhpc3QuCi0gICAgICovCi0gICAgcHVibGljIFN5bnRheFRyZWVOb2RlIG1ha2VJbnN0YW5jZShTdHJpbmcgdXJpLCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWwpewotCVFOYW1lICBxbmFtZSA9IGdldFFOYW1lKHVyaSwgcHJlZml4LCBsb2NhbCk7Ci0JU3RyaW5nIGNsYXNzTmFtZSA9IChTdHJpbmcpX2luc3RydWN0aW9uQ2xhc3Nlcy5nZXQocW5hbWUpOwotCVN5bnRheFRyZWVOb2RlIG5vZGUgPSBudWxsOwotCi0JaWYgKGNsYXNzTmFtZSAhPSBudWxsKSB7Ci0JICAgIHRyeSB7Ci0JCWZpbmFsIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOwotCQlub2RlID0gKFN5bnRheFRyZWVOb2RlKWNsYXp6Lm5ld0luc3RhbmNlKCk7Ci0JCW5vZGUuc2V0UU5hbWUocW5hbWUpOwotCQlub2RlLnNldFBhcnNlcih0aGlzKTsKLQkJaWYgKG5vZGUgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0JCSAgICBfeHNsdGMuc2V0U3R5bGVzaGVldCgoU3R5bGVzaGVldClub2RlKTsKLQkJfQotCSAgICB9Ci0JICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLQkJcmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLAotCQkgICAgbmV3IEVycm9yTXNnKENMQVNTX05PVF9GT1VORCtjbGFzc05hbWUpKTsKLQkgICAgfQotCSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJcmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLAotCQkgICAgbmV3IEVycm9yTXNnKElOVEVSTkFMX0VSUk9SK2UuZ2V0TWVzc2FnZSgpKSk7Ci0JICAgIH0KLQl9Ci0JZWxzZSB7Ci0JICAgIGlmICh1cmkgIT0gbnVsbCkgewotCQkvLyBDaGVjayBpZiB0aGUgZWxlbWVudCBiZWxvbmdzIGluIG91ciBuYW1lc3BhY2UKLQkJaWYgKHVyaS5lcXVhbHMoWFNMVF9VUkkpKSB7Ci0JCSAgICBub2RlID0gbmV3IFVuc3VwcG9ydGVkRWxlbWVudCh1cmksIHByZWZpeCwgbG9jYWwpOwotCQkgICAgVW5zdXBwb3J0ZWRFbGVtZW50IGVsZW1lbnQgPSAoVW5zdXBwb3J0ZWRFbGVtZW50KW5vZGU7Ci0JCSAgICBlbGVtZW50LnNldEVycm9yTWVzc2FnZShVTlNVUFBPUlRFRF9YU0xfRVJST1IrbG9jYWwpOwotCQl9Ci0JCS8vIENoZWNrIGlmIHRoaXMgaXMgYW4gWFNMVEMgZXh0ZW5zaW9uIGVsZW1lbnQKLQkJZWxzZSBpZiAodXJpLmVxdWFscyhUUkFOU0xFVF9VUkkpKSB7Ci0JCSAgICBub2RlID0gbmV3IFVuc3VwcG9ydGVkRWxlbWVudCh1cmksIHByZWZpeCwgbG9jYWwpOwotCQkgICAgVW5zdXBwb3J0ZWRFbGVtZW50IGVsZW1lbnQgPSAoVW5zdXBwb3J0ZWRFbGVtZW50KW5vZGU7Ci0JCSAgICBlbGVtZW50LnNldEVycm9yTWVzc2FnZShJTlZBTElEX0VYVF9FUlJPUitsb2NhbCk7Ci0JCX0KLQkJLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBleHRlbnNpb24gb2Ygc29tZSBvdGhlciBYU0xUIHByb2Nlc3NvcgotCQllbHNlIHsKLQkJICAgIFN0eWxlc2hlZXQgc2hlZXQgPSBfeHNsdGMuZ2V0U3R5bGVzaGVldCgpOwotCQkgICAgaWYgKChzaGVldCAhPSBudWxsKSAmJiAoc2hlZXQuaXNFeHRlbnNpb24odXJpKSkpIHsKLQkJCWlmIChzaGVldCAhPSAoU3ludGF4VHJlZU5vZGUpX3BhcmVudFN0YWNrLnBlZWsoKSkgewotCQkJICAgIG5vZGUgPSBuZXcgVW5zdXBwb3J0ZWRFbGVtZW50KHVyaSwgcHJlZml4LCBsb2NhbCk7Ci0JCQkgICAgVW5zdXBwb3J0ZWRFbGVtZW50IGVsZW0gPSAoVW5zdXBwb3J0ZWRFbGVtZW50KW5vZGU7Ci0JCQkgICAgZWxlbS5zZXRFcnJvck1lc3NhZ2UoVU5TVVBQT1JURURfRVhUX0VSUk9SKwotCQkJCQkJIHByZWZpeCsiOiIrbG9jYWwpOwotCQkJfQotCQkgICAgfQotCQl9Ci0JICAgIH0KLQkgICAgaWYgKG5vZGUgPT0gbnVsbCkgbm9kZSA9IG5ldyBMaXRlcmFsRWxlbWVudCgpOwotCX0KLQlpZiAoKG5vZGUgIT0gbnVsbCkgJiYgKG5vZGUgaW5zdGFuY2VvZiBMaXRlcmFsRWxlbWVudCkpIHsKLQkgICAgKChMaXRlcmFsRWxlbWVudClub2RlKS5zZXRRTmFtZShxbmFtZSk7Ci0JfQotCXJldHVybihub2RlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbiBYUGF0aCBleHByZXNzaW9uOgotICAgICAqICBAcGFyZW50IC0gWFNMIGVsZW1lbnQgd2hlcmUgdGhlIGV4cHJlc3Npb24gb2NjdXJlZAotICAgICAqICBAZXhwICAgIC0gdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZXhwcmVzc2lvbgotICAgICAqLwotICAgIHB1YmxpYyBFeHByZXNzaW9uIHBhcnNlRXhwcmVzc2lvbihTeW50YXhUcmVlTm9kZSBwYXJlbnQsIFN0cmluZyBleHApIHsKLQlyZXR1cm4gKEV4cHJlc3Npb24pcGFyc2VUb3BMZXZlbChwYXJlbnQsICI8RVhQUkVTU0lPTj4iK2V4cCwgMCwgbnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWFBhdGggZXhwcmVzc2lvbjoKLSAgICAgKiAgQHBhcmVudCAtIFhTTCBlbGVtZW50IHdoZXJlIHRoZSBleHByZXNzaW9uIG9jY3VyZWQKLSAgICAgKiAgQGF0dHIgICAtIG5hbWUgb2YgdGhpcyBlbGVtZW50J3MgYXR0cmlidXRlIHRvIGdldCBleHByZXNzaW9uIGZyb20KLSAgICAgKiAgQGRlZiAgICAtIGRlZmF1bHQgZXhwcmVzc2lvbiAoaWYgdGhlIGF0dHJpYnV0ZSB3YXMgbm90IGZvdW5kKQotICAgICAqLwotICAgIHB1YmxpYyBFeHByZXNzaW9uIHBhcnNlRXhwcmVzc2lvbihTeW50YXhUcmVlTm9kZSBwYXJlbnQsCi0JCQkJICAgICAgU3RyaW5nIGF0dHIsIFN0cmluZyBkZWYpIHsKLQkvLyBHZXQgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGV4cHJlc3Npb24gKGlmIGFueSkKLSAgICAgICAgU3RyaW5nIGV4cCA9IHBhcmVudC5nZXRBdHRyaWJ1dGUoYXR0cik7Ci0JLy8gVXNlIHRoZSBkZWZhdWx0IGV4cHJlc3Npb24gaWYgbm9uZSB3YXMgZm91bmQKLSAgICAgICAgaWYgKChleHAubGVuZ3RoKCkgPT0gMCkgJiYgKGRlZiAhPSBudWxsKSkgZXhwID0gZGVmOwotCS8vIEludm9rZSB0aGUgWFBhdGggcGFyc2VyCi0gICAgICAgIHJldHVybiAoRXhwcmVzc2lvbilwYXJzZVRvcExldmVsKHBhcmVudCwgIjxFWFBSRVNTSU9OPiIrZXhwLCAwLCBleHApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhQYXRoIHBhdHRlcm46Ci0gICAgICogIEBwYXJlbnQgLSBYU0wgZWxlbWVudCB3aGVyZSB0aGUgcGF0dGVybiBvY2N1cmVkCi0gICAgICogIEBleHAgICAgLSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXR0ZXJuCi0gICAgICovCi0gICAgcHVibGljIFBhdHRlcm4gcGFyc2VQYXR0ZXJuKFN5bnRheFRyZWVOb2RlIHBhcmVudCwgU3RyaW5nIHBhdHRlcm4pIHsKLQlyZXR1cm4gKFBhdHRlcm4pcGFyc2VUb3BMZXZlbChwYXJlbnQsICI8UEFUVEVSTj4iK3BhdHRlcm4sIDAsIHBhdHRlcm4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIGFuIFhQYXRoIHBhdHRlcm46Ci0gICAgICogIEBwYXJlbnQgLSBYU0wgZWxlbWVudCB3aGVyZSB0aGUgcGF0dGVybiBvY2N1cmVkCi0gICAgICogIEBhdHRyICAgLSBuYW1lIG9mIHRoaXMgZWxlbWVudCdzIGF0dHJpYnV0ZSB0byBnZXQgcGF0dGVybiBmcm9tCi0gICAgICogIEBkZWYgICAgLSBkZWZhdWx0IHBhdHRlcm4gKGlmIHRoZSBhdHRyaWJ1dGUgd2FzIG5vdCBmb3VuZCkKLSAgICAgKi8KLSAgICBwdWJsaWMgUGF0dGVybiBwYXJzZVBhdHRlcm4oU3ludGF4VHJlZU5vZGUgcGFyZW50LAotCQkJCVN0cmluZyBhdHRyLCBTdHJpbmcgZGVmKSB7Ci0JLy8gR2V0IHRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXR0ZXJuIChpZiBhbnkpCi0gICAgICAgIFN0cmluZyBwYXR0ZXJuID0gcGFyZW50LmdldEF0dHJpYnV0ZShhdHRyKTsKLQkvLyBVc2UgdGhlIGRlZmF1bHQgcGF0dGVybiBpZiBub25lIHdhcyBmb3VuZAotCWlmICgocGF0dGVybi5sZW5ndGgoKSA9PSAwKSAmJiAoZGVmICE9IG51bGwpKSBwYXR0ZXJuID0gZGVmOwotCS8vIEludm9rZSB0aGUgWFBhdGggcGFyc2VyCi0gICAgICAgIHJldHVybiAoUGF0dGVybilwYXJzZVRvcExldmVsKHBhcmVudCwgIjxQQVRURVJOPiIrcGF0dGVybiwgMCwgcGF0dGVybik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYW4gWFBhdGggZXhwcmVzc2lvbiBvciBwYXR0ZXJuIHVzaW5nIHRoZSBnZW5lcmF0ZWQgWFBhdGhQYXJzZXIKLSAgICAgKiBUaGUgbWV0aG9kIHdpbGwgcmV0dXJuIGEgRHVtbXkgbm9kZSBpZiB0aGUgWFBhdGggcGFyc2VyIGZhaWxzLgotICAgICAqLwotICAgIHByaXZhdGUgU3ludGF4VHJlZU5vZGUgcGFyc2VUb3BMZXZlbChTeW50YXhUcmVlTm9kZSBwYXJlbnQsCi0JCQkJCSBTdHJpbmcgdGV4dCwgaW50IGxpbmUsCi0JCQkJCSBTdHJpbmcgZXhwcmVzc2lvbikgewotCXRyeSB7Ci0JICAgIF94cGF0aFBhcnNlci5zZXRTY2FubmVyKG5ldyBYUGF0aExleGVyKG5ldyBTdHJpbmdSZWFkZXIodGV4dCkpKTsKLQkgICAgU3ltYm9sIHJlc3VsdCA9IF94cGF0aFBhcnNlci5wYXJzZShsaW5lKTsKLQkgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0JCWZpbmFsIFN5bnRheFRyZWVOb2RlIG5vZGUgPSAoU3ludGF4VHJlZU5vZGUpcmVzdWx0LnZhbHVlOwotCQlpZiAobm9kZSAhPSBudWxsKSB7Ci0JCSAgICBub2RlLnNldFBhcnNlcih0aGlzKTsKLQkJICAgIG5vZGUuc2V0UGFyZW50KHBhcmVudCk7Ci0JCSAgICByZXR1cm4gbm9kZTsKLQkJfQotCSAgICB9IAotCSAgICByZXBvcnRFcnJvcihDb25zdGFudHMuRVJST1IsCi0JCW5ldyBFcnJvck1zZyhFcnJvck1zZy5YUEFUSFBBUl9FUlIsIGxpbmUsIGV4cHJlc3Npb24pKTsKLQl9Ci0JY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwKLQkJCW5ldyBFcnJvck1zZyhFcnJvck1zZy5YUEFUSFBBUl9FUlIsIGxpbmUsIGV4cHJlc3Npb24pKTsKLQl9Ci0JY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JICAgIGlmIChfeHNsdGMuZGVidWcoKSkgewotCQllLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICB9Ci0JICAgIC8vIEludGVudGlvbmFsIGZhbGwgdGhyb3VnaAotCX0KLQkvLyBSZXR1cm4gYSBkdW1teSBwYXR0ZXJuICh3aGljaCBpcyBhbiBleHByZXNzaW9uKQotCVN5bnRheFRyZWVOb2RlLkR1bW15LnNldFBhcnNlcih0aGlzKTsKLSAgICAgICAgcmV0dXJuIFN5bnRheFRyZWVOb2RlLkR1bW15OyAKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgd2VyZSBhbnkgZXJyb3JzIGR1cmluZyBjb21waWxhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGVycm9yc0ZvdW5kKCkgewotCXJldHVybiBfZXJyb3JzLnNpemUoKSA+IDA7Ci0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVycm9yKCkgewotCUV4Y2VwdGlvbiBlID0gbmV3IEV4Y2VwdGlvbigpOwotCWUucHJpbnRTdGFja1RyYWNlKCk7Ci0JcmVwb3J0RXJyb3IoQ29uc3RhbnRzLklOVEVSTkFMLAotCSAgICBuZXcgRXJyb3JNc2coIkludGVybmFsIGNvbXBpbGVyIGVycm9yLlxuIisKLSAgICAgICAgICAgICAgICAiUGxlYXNlIHJlcG9ydCB0byB4YWxhbi1kZXZAeG1sLmFwYWNoZS5vcmdcbiIrCi0gICAgICAgICAgICAgICAgIihpbmNsdWRlIHN0YWNrIHRyYWNlKSIpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBub3RZZXRJbXBsZW1lbnRlZChTdHJpbmcgbWVzc2FnZSkgewotCXJlcG9ydEVycm9yKENvbnN0YW50cy5VTlNVUFBPUlRFRCwgbmV3IEVycm9yTXNnKG1lc3NhZ2UpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFByaW50cyBhbGwgY29tcGlsZS10aW1lIGVycm9ycwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50RXJyb3JzKCkgewotCWZpbmFsIGludCBzaXplID0gX2Vycm9ycy5zaXplKCk7Ci0JaWYgKHNpemUgPiAwKSB7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ29tcGlsZSBlcnJvcnM6Iik7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7Ci0JCVN5c3RlbS5lcnIucHJpbnRsbigiICAiICsgX2Vycm9ycy5lbGVtZW50QXQoaSkpOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50cyBhbGwgY29tcGlsZS10aW1lIHdhcm5pbmdzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRXYXJuaW5ncygpIHsKLQlmaW5hbCBpbnQgc2l6ZSA9IF93YXJuaW5ncy5zaXplKCk7Ci0JaWYgKHNpemUgPiAwKSB7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbigiV2FybmluZzoiKTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLQkJU3lzdGVtLmVyci5wcmludGxuKCIgICIgKyBfd2FybmluZ3MuZWxlbWVudEF0KGkpKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21tb24gZXJyb3Ivd2FybmluZyBtZXNzYWdlIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCByZXBvcnRFcnJvcihmaW5hbCBpbnQgY2F0ZWdvcnksIGZpbmFsIEVycm9yTXNnIGVycm9yKSB7Ci0Jc3dpdGNoIChjYXRlZ29yeSkgewotCWNhc2UgQ29uc3RhbnRzLklOVEVSTkFMOgotCSAgICAvLyBVbmV4cGVjdGVkIGludGVybmFsIGVycm9ycywgc3VjaCBhcyBudWxsLXB0ciBleGNlcHRpb25zLCBldGMuCi0JICAgIC8vIEltbWVkaWF0ZWx5IHRlcm1pbmF0ZXMgY29tcGlsYXRpb24sIG5vIHRyYW5zbGV0IHByb2R1Y2VkCi0JICAgIF9lcnJvcnMuYWRkRWxlbWVudChlcnJvcik7Ci0JICAgIGJyZWFrOwotCWNhc2UgQ29uc3RhbnRzLlVOU1VQUE9SVEVEOgotCSAgICAvLyBYU0xUIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCBpbXBsZW1lbnRlZCBhbmQgdW5zdXBwb3J0ZWQgZXh0LgotCSAgICAvLyBJbW1lZGlhdGVseSB0ZXJtaW5hdGVzIGNvbXBpbGF0aW9uLCBubyB0cmFuc2xldCBwcm9kdWNlZAotCSAgICBfZXJyb3JzLmFkZEVsZW1lbnQoZXJyb3IpOwotCSAgICBicmVhazsKLQljYXNlIENvbnN0YW50cy5GQVRBTDoKLQkgICAgLy8gRmF0YWwgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKHBhcnNpbmcgb3IgY29udGVudCkKLQkgICAgLy8gSW1tZWRpYXRlbHkgdGVybWluYXRlcyBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLQkgICAgX2Vycm9ycy5hZGRFbGVtZW50KGVycm9yKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBDb25zdGFudHMuRVJST1I6Ci0JICAgIC8vIE90aGVyIGVycm9yIGluIHRoZSBzdHlsZXNoZWV0IGlucHV0IChwYXJzaW5nIG9yIGNvbnRlbnQpCi0JICAgIC8vIERvZXMgbm90IHRlcm1pbmF0ZSBjb21waWxhdGlvbiwgbm8gdHJhbnNsZXQgcHJvZHVjZWQKLQkgICAgX2Vycm9ycy5hZGRFbGVtZW50KGVycm9yKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBDb25zdGFudHMuV0FSTklORzoKLQkgICAgLy8gT3RoZXIgZXJyb3IgaW4gdGhlIHN0eWxlc2hlZXQgaW5wdXQgKGNvbnRlbnQgZXJyb3JzIG9ubHkpCi0JICAgIC8vIERvZXMgbm90IHRlcm1pbmF0ZSBjb21waWxhdGlvbiwgYSB0cmFuc2xldCBpcyBwcm9kdWNlZAotCSAgICBfd2FybmluZ3MuYWRkRWxlbWVudChlcnJvcik7Ci0JICAgIGJyZWFrOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgVmVjdG9yIGdldEVycm9ycygpIHsKLQlyZXR1cm4gX2Vycm9yczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmVjdG9yIGdldFdhcm5pbmdzKCkgewotCXJldHVybiBfd2FybmluZ3M7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVgyIENvbnRlbnRIYW5kbGVyIElOVEVSRkFDRSAqKioqKioqKioqKioqKioqKi8KLQotICAgIHByaXZhdGUgU3RhY2sgX3BhcmVudFN0YWNrID0gbnVsbDsKLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfcHJlZml4TWFwcGluZyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgZG9jdW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHsKLQlfcm9vdCA9IG51bGw7Ci0JX3RhcmdldCA9IG51bGw7Ci0JX3ByZWZpeE1hcHBpbmcgPSBudWxsOwotCV9wYXJlbnRTdGFjayA9IG5ldyBTdGFjaygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBlbmQgb2YgYSBkb2N1bWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHsgfQotCi0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBCZWdpbiB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgICAqICAgICAgIFRoaXMgaGFzIHRvIGJlIHBhc3NlZCBvbiB0byB0aGUgc3ltYm9sIHRhYmxlIQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0JaWYgKF9wcmVmaXhNYXBwaW5nID09IG51bGwpIF9wcmVmaXhNYXBwaW5nID0gbmV3IEhhc2h0YWJsZSgpOwotCV9wcmVmaXhNYXBwaW5nLnB1dChwcmVmaXgsIHVyaSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogRW5kIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICogICAgICAgVGhpcyBoYXMgdG8gYmUgcGFzc2VkIG9uIHRvIHRoZSBzeW1ib2wgdGFibGUhCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB7IH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KLSAgICAgKiAgICAgICBUaGUgcGFyc2VyIG1heSByZS11c2UgdGhlIGF0dHJpYnV0ZSBsaXN0IHRoYXQgd2UncmUgcGFzc2VkIHNvCi0gICAgICogICAgICAgd2UgY2xvbmUgdGhlIGF0dHJpYnV0ZXMgaW4gb3VyIG93biBBdHRyaWJ1dGVzIGltcGxlbWVudGF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbG5hbWUsCi0JCQkgICAgIFN0cmluZyBxbmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKSAKLQl0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQlmaW5hbCBpbnQgY29sID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLQlmaW5hbCBTdHJpbmcgcHJlZml4OwotCWlmIChjb2wgPT0gLTEpCi0JICAgIHByZWZpeCA9IG51bGw7Ci0JZWxzZQotCSAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgY29sKTsKLQotCVN5bnRheFRyZWVOb2RlIGVsZW1lbnQgPSBtYWtlSW5zdGFuY2UodXJpLCBwcmVmaXgsIGxvY2FsbmFtZSk7Ci0JaWYgKGVsZW1lbnQgPT0gbnVsbCkgewotCSAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKCJFcnJvciB3aGlsZSBwYXJzaW5nIHN0eWxlc2hlZXQuIik7Ci0JfQotCi0JLy8gSWYgdGhpcyBpcyB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSBYTUwgZG9jdW1lbnQgd2UgbmVlZCB0byBtYWtlIHN1cmUKLQkvLyB0aGF0IGl0IGNvbnRhaW5zIGEgZGVmaW5pdGlvbiBvZiB0aGUgWFNMIG5hbWVzcGFjZSBVUkkKLQlpZiAoX3Jvb3QgPT0gbnVsbCkgewotCSAgICBpZiAoKF9wcmVmaXhNYXBwaW5nID09IG51bGwpIHx8Ci0JCShfcHJlZml4TWFwcGluZy5jb250YWluc1ZhbHVlKENvbnN0YW50cy5YU0xUX1VSSSkgPT0gZmFsc2UpKQotCQlfcm9vdE5hbWVzcGFjZURlZiA9IGZhbHNlOwotCSAgICBlbHNlCi0JCV9yb290TmFtZXNwYWNlRGVmID0gdHJ1ZTsKLQkgICAgX3Jvb3QgPSBlbGVtZW50OwotCX0KLQllbHNlIHsKLQkgICAgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gKFN5bnRheFRyZWVOb2RlKV9wYXJlbnRTdGFjay5wZWVrKCk7Ci0JICAgIHBhcmVudC5hZGRFbGVtZW50KGVsZW1lbnQpOwotCSAgICBlbGVtZW50LnNldFBhcmVudChwYXJlbnQpOwotCX0KLQllbGVtZW50LnNldEF0dHJpYnV0ZXMoKEF0dHJpYnV0ZXMpbmV3IEF0dHJpYnV0ZUxpc3QoYXR0cmlidXRlcykpOwotCWVsZW1lbnQuc2V0UHJlZml4TWFwcGluZyhfcHJlZml4TWFwcGluZyk7Ci0JCi0JaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0JICAgIC8vIEV4dGVuc2lvbiBlbGVtZW50cyBhbmQgZXhjbHVkZWQgZWxlbWVudHMgaGF2ZSB0byBiZQotCSAgICAvLyBoYW5kbGVkIGF0IHRoaXMgcG9pbnQgaW4gb3JkZXIgdG8gY29ycmVjdGx5IGdlbmVyYXRlCi0JICAgIC8vIEZhbGxiYWNrIGVsZW1lbnRzIGZyb20gPHhzbDpmYWxsYmFjaz5zLgotCSAgICBnZXRTeW1ib2xUYWJsZSgpLnNldEN1cnJlbnROb2RlKGVsZW1lbnQpOwotCSAgICAoKFN0eWxlc2hlZXQpZWxlbWVudCkuZXhjbHVkZUV4dGVuc2lvblByZWZpeGVzKHRoaXMpOwotCX0KLQotCV9wcmVmaXhNYXBwaW5nID0gbnVsbDsKLQlfcGFyZW50U3RhY2sucHVzaChlbGVtZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxuYW1lLCBTdHJpbmcgcW5hbWUpIHsKLQlfcGFyZW50U3RhY2sucG9wKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgewotCVN0cmluZyBzdHJpbmcgPSBuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKTsKLQlTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSAoU3ludGF4VHJlZU5vZGUpX3BhcmVudFN0YWNrLnBlZWsoKTsKLQotCS8vIElmIHRoaXMgdGV4dCBvY2N1cnMgd2l0aGluIGFuIDx4c2w6dGV4dD4gZWxlbWVudCB3ZSBhcHBlbmQgaXQKLQkvLyBhcy1pcyB0byB0aGUgZXhpc3RpbmcgdGV4dCBlbGVtZW50Ci0JaWYgKHBhcmVudCBpbnN0YW5jZW9mIFRleHQpIHsKLQkgICAgaWYgKHN0cmluZy5sZW5ndGgoKSA+IDApIHsKLQkJKChUZXh0KXBhcmVudCkuc2V0VGV4dChzdHJpbmcpOwotCSAgICB9Ci0JfQotCS8vIElnbm9yZSB0ZXh0IG5vZGVzIHRoYXQgb2NjdXIgZGlyZWN0bHkgdW5kZXIgPHhzbDpzdHlsZXNoZWV0PgotCWVsc2UgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFN0eWxlc2hlZXQpIHsKLQotCX0KLQkvLyBBZGQgaXQgYXMgYSByZWd1bGFyIHRleHQgbm9kZSBvdGhlcndpc2UKLQllbHNlIHsKLQkgICAgaWYgKHN0cmluZy50cmltKCkubGVuZ3RoKCkgPiAwKSB7Ci0JCXBhcmVudC5hZGRFbGVtZW50KG5ldyBUZXh0KHN0cmluZykpOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGdldFRva2VuVmFsdWUoU3RyaW5nIHRva2VuKSB7Ci0JZmluYWwgaW50IHN0YXJ0ID0gdG9rZW4uaW5kZXhPZignIicpOwotCWZpbmFsIGludCBzdG9wID0gdG9rZW4ubGFzdEluZGV4T2YoJyInKTsKLQlyZXR1cm4gdG9rZW4uc3Vic3RyaW5nKHN0YXJ0KzEsIHN0b3ApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKiAgICAgICBUaGVzZSByZXF1aXJlIHNwZWNpYWwgaGFuZGxpbmcgZm9yIHN0eWxlc2hlZXQgUElzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7Ci0JLy8gV2Ugb25seSBoYW5kbGUgdGhlIDw/eG1sLXN0eWxlc2hlZXQgLi4uPz4gUEkKLQlpZiAoKF90YXJnZXQgPT0gbnVsbCkgJiYgKG5hbWUuZXF1YWxzKCJ4bWwtc3R5bGVzaGVldCIpKSkgewotCi0JICAgIFN0cmluZyBocmVmID0gbnVsbDsgICAgLy8gVVJJIG9mIHN0eWxlc2hlZXQgZm91bmQKLQkgICAgU3RyaW5nIG1lZGlhID0gbnVsbDsgICAvLyBNZWRpYSBvZiBzdHlsZXNoZWV0IGZvdW5kCi0JICAgIFN0cmluZyB0aXRsZSA9IG51bGw7ICAgLy8gVGl0bGUgb2Ygc3R5bGVzaGVldCBmb3VuZAotCSAgICBTdHJpbmcgY2hhcnNldCA9IG51bGw7IC8vIENoYXJzZXQgb2Ygc3R5bGVzaGVldCBmb3VuZAotCi0JICAgIC8vIEdldCB0aGUgYXR0cmlidXRlcyBmcm9tIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uCi0JICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbHVlKTsKLQkgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQlTdHJpbmcgdG9rZW4gPSAoU3RyaW5nKXRva2Vucy5uZXh0RWxlbWVudCgpOwotCQlpZiAodG9rZW4uc3RhcnRzV2l0aCgiaHJlZiIpKQotCQkgICAgaHJlZiA9IGdldFRva2VuVmFsdWUodG9rZW4pOwotCQllbHNlIGlmICh0b2tlbi5zdGFydHNXaXRoKCJtZWRpYSIpKQotCQkgICAgbWVkaWEgPSBnZXRUb2tlblZhbHVlKHRva2VuKTsKLQkJZWxzZSBpZiAodG9rZW4uc3RhcnRzV2l0aCgidGl0bGUiKSkKLQkJICAgIHRpdGxlID0gZ2V0VG9rZW5WYWx1ZSh0b2tlbik7Ci0JCWVsc2UgaWYgKHRva2VuLnN0YXJ0c1dpdGgoImNoYXJzZXQiKSkKLQkJICAgIGNoYXJzZXQgPSBnZXRUb2tlblZhbHVlKHRva2VuKTsKLQkgICAgfQotCi0JICAgIC8vIFNldCB0aGUgdGFyZ2V0IHRvIHRoaXMgUEkncyBocmVmIGlmIHRoZSBwYXJhbWV0ZXJzIGFyZQotCSAgICAvLyBudWxsIG9yIG1hdGNoIHRoZSBjb3JyZXNwb25kaW5nIGF0dHJpYnV0ZXMgb2YgdGhpcyBQSS4KLQkgICAgaWYgKCAoKF9QSW1lZGlhID09IG51bGwpIHx8IChfUEltZWRpYS5lcXVhbHMobWVkaWEpKSkgJiYKLQkJICgoX1BJdGl0bGUgPT0gbnVsbCkgfHwgKF9QSW1lZGlhLmVxdWFscyh0aXRsZSkpKSAmJgotCQkgKChfUEljaGFyc2V0ID09IG51bGwpIHx8IChfUEltZWRpYS5lcXVhbHMoY2hhcnNldCkpKSApIHsKLQkJX3RhcmdldCA9IGhyZWY7Ci0JICAgIH0KLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSUdOT1JFRCAtIGFsbCBpZ25vcmFibGUgd2hpdGVzcGFjZSBpcyBpZ25vcmVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgeyB9Ci0KLSAgICAvKioKLSAgICAgKiBJR05PUkVEIC0gd2UgZG8gbm90IGhhdmUgdG8gZG8gYW55dGhpbmcgd2l0aCBza2lwcGVkIGVudGl0aWVzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgeyB9Ci0KLSAgICAvKioKLSAgICAgKiBJR05PUkVEIC0gd2UgYWxyZWFkeSBrbm93IHdoYXQgdGhlIG9yaWdpbiBvZiB0aGUgZG9jdW1lbnQgaXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKSB7IH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGF0dGVybi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMTIxYWU3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1BhdHRlcm4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBQYXR0ZXJuIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiBhIHBhdHRlcm4sIHdoaWNoIGlzIGFsd2F5cyBhIDxjb2RlPk5vZGVUeXBlPC9jb2RlPi4KLSAgICAgKiBBIDxjb2RlPk5vZGVUeXBlPC9jb2RlPiBoYXMgYSBudW1iZXIgb2Ygc3VidHlwZXMgZGVmaW5lZCBieSAKLSAgICAgKiA8Y29kZT5Ob2RlVHlwZS5fdHlwZTwvY29kZT4gY29ycmVzcG9uZGluZyB0byBlYWNoIHR5cGUgb2Ygbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3I7Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhpcyBub2RlIGludG8gSlZNIGJ5dGVjb2Rlcy4gUGF0dGVybnMgYXJlIHRyYW5zbGF0ZWQgYXMKLSAgICAgKiBib29sZWFuIGV4cHJlc3Npb25zIHdpdGggdHJ1ZS9mYWxzZSBsaXN0cy4gQmVmb3JlIGNhbGxpbmcgCi0gICAgICogPGNvZGU+dHJhbnNsYXRlPC9jb2RlPiBvbiBhIHBhdHRlcm4sIG1ha2Ugc3VyZSB0aGF0IHRoZSBub2RlIGJlaW5nIAotICAgICAqIG1hdGNoZWQgaXMgb24gdG9wIG9mIHRoZSBzdGFjay4gQWZ0ZXIgY2FsbGluZyA8Y29kZT50cmFuc2xhdGU8L2NvZGU+LCAKLSAgICAgKiBtYWtlIHN1cmUgdG8gYmFja3BhdGNoIGJvdGggdHJ1ZSBhbmQgZmFsc2UgbGlzdHMuIFRydWUgbGlzdHMgYXJlIHRoZSAKLSAgICAgKiBkZWZhdWx0LCBpbiB0aGUgc2Vuc2UgdGhhdCB0aGV5IGFsd2F5cyA8ZW0+ImZhbGwgdGhyb3VnaCI8L2VtPi4gSWYgdGhpcwotICAgICAqIGlzIG5vdCB0aGUgaW50ZW5kZWQgc2VtYW50aWNzIChlLmcuLCBzZWUgCi0gICAgICoge0BsaW5rIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuQWx0ZXJuYXRpdmVQYXR0ZXJuI3RyYW5zbGF0ZSgpfSkKLSAgICAgKiB0aGVuIGEgR09UTyBtdXN0IGJlIGFwcGVuZGVkIHRvIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGFmdGVyIGNhbGxpbmcKLSAgICAgKiA8Y29kZT50cmFuc2xhdGU8L2NvZGU+LiAKLSAgICAgKi8KLSAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbik7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwcmlvcml0eSBvZiB0aGlzIHBhdHRlcm4gKHNlY3Rpb24gNS41IGluIHRoZSBYU0xUIHNwZWMpLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBkb3VibGUgZ2V0UHJpb3JpdHkoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1Bvc2l0aW9uQ2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUG9zaXRpb25DYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBiMTMzNWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUG9zaXRpb25DYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFBvc2l0aW9uQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0KLSAgICBwcml2YXRlIGludCBfdHlwZSA9IC0xOwotCi0gICAgcHVibGljIFBvc2l0aW9uQ2FsbChRTmFtZSBmbmFtZSkgewotCXN1cGVyKGZuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUG9zaXRpb25DYWxsKFFOYW1lIGZuYW1lLCBpbnQgdHlwZSkgewotCXRoaXMoZm5hbWUpOwotCV90eXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCS8vIElmIHdlJ3JlIGEgcGFydCBvZiBhbiBleHByZXNzaW9uJ3MgcHJlZmljYXRlIHdlIHdhbnQgdG8ga25vdyB3aGF0Ci0JLy8gdHlwZSBvZiBub2RlIHdlIHdhbnQgdG8gYmUgbG9va2luZyBmb3IKLQlpZiAoZ2V0UGFyZW50KCkgaW5zdGFuY2VvZiBFeHByZXNzaW9uKSB7Ci0JICAgIGlmIChnZXRQYXJlbnQoKS5nZXRQYXJlbnQoKSBpbnN0YW5jZW9mIFByZWRpY2F0ZSkgewotCQlQcmVkaWNhdGUgcHJlZCA9IChQcmVkaWNhdGUpZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCk7Ci0JCV90eXBlID0gcHJlZC5nZXRQb3NUeXBlKCk7Ci0JICAgIH0KLQl9Ci0KLQotCWlmIChtZXRob2RHZW4gaW5zdGFuY2VvZiBDb21wYXJlR2VuZXJhdG9yKSB7Ci0JICAgIGlsLmFwcGVuZCgoKENvbXBhcmVHZW5lcmF0b3IpbWV0aG9kR2VuKS5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JfQotCWVsc2UgaWYgKG1ldGhvZEdlbiBpbnN0YW5jZW9mIFRlc3RHZW5lcmF0b3IpIHsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTE9BRChQT1NJVElPTl9JTkRFWCkpOwotCX0KLQllbHNlIGlmIChfdHlwZSA9PSAtMSkgewotCSAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JICAgIGZpbmFsIGludCBnZXRQb3NpdGlvbiA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwKLQkJCQkJCQkgICAgICAiZ2V0UG9zaXRpb24iLCAKLQkJCQkJCQkgICAgICAiKClJIik7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShnZXRQb3NpdGlvbiwgMSkpOwotCX0KLQllbHNlIHsKLQkgICAgZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCSAgICAvLyBwdWJsaWMgaW50IGdldFR5cGVkUG9zaXRpb24oTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBpbnQgdHlwZSkgewotCSAgICBmaW5hbCBTdHJpbmcgcGFyYW1zID0gIigiK05PREVfSVRFUkFUT1JfU0lHKyJJSSlJIjsKLQkgICAgZmluYWwgaW50IHBvcyA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgICAiZ2V0VHlwZWRQb3NpdGlvbiIsCi0JCQkJCQkgICAgICBwYXJhbXMpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEl0ZXJhdG9yKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdHlwZSkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UocG9zLCA0KSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ByZWRpY2F0ZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUHJlZGljYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI0N2FlZDEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUHJlZGljYXRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MDcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuY2xhc3NmaWxlLkphdmFDbGFzczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuUmVmZXJlbmNlVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBQcmVkaWNhdGUgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfZXhwID0gbnVsbDsgLy8gRXhwcmVzc2lvbiB0byBiZSBjb21waWxlZCBpbnNpZGUgcHJlZC4KLSAgICBwcml2YXRlIFN0cmluZyAgX2NsYXNzTmFtZTsgICAgIC8vIE5hbWUgb2YgZmlsdGVyIHRvIGdlbmVyYXRlCi0gICAgcHJpdmF0ZSBib29sZWFuIF9udGhQb3NpdGlvbkZpbHRlciA9IGZhbHNlOwotICAgIHByaXZhdGUgYm9vbGVhbiBfbnRoRGVzY2VuZGFudCA9IGZhbHNlOwotICAgIHByaXZhdGUgaW50ICAgICBfcHR5cGUgPSAtMTsKLQotICAgIHB1YmxpYyBQcmVkaWNhdGUoRXhwcmVzc2lvbiBleHApIHsKLQkoX2V4cCA9IGV4cCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JX2V4cC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc050aERlc2NlbmRhbnQoKSB7Ci0JcmV0dXJuIF9udGhEZXNjZW5kYW50OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzTnRoUG9zaXRpb25GaWx0ZXIoKSB7Ci0JcmV0dXJuIF9udGhQb3NpdGlvbkZpbHRlcjsKLSAgICB9Ci0gICAgCi0gICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gaXNDbG9zdXJlQm91bmRhcnkoKSB7Ci0JcmV0dXJuIHRydWU7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBpbnQgZ2V0UG9zVHlwZSgpIHsKLQlpZiAoX3B0eXBlID09IC0xKSB7Ci0JICAgIFN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCSAgICBpZiAocGFyZW50IGluc3RhbmNlb2YgU3RlcFBhdHRlcm4pIHsKLQkJX3B0eXBlID0gKChTdGVwUGF0dGVybilwYXJlbnQpLmdldE5vZGVUeXBlKCk7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgQWJzb2x1dGVMb2NhdGlvblBhdGgpIHsKLQkJQWJzb2x1dGVMb2NhdGlvblBhdGggcGF0aCA9IChBYnNvbHV0ZUxvY2F0aW9uUGF0aClwYXJlbnQ7Ci0JCUV4cHJlc3Npb24gZXhwID0gcGF0aC5nZXRQYXRoKCk7Ci0JCWlmIChleHAgaW5zdGFuY2VvZiBTdGVwKSB7Ci0JCSAgICBfcHR5cGUgPSAoKFN0ZXApZXhwKS5nZXROb2RlVHlwZSgpOwotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgVmFyaWFibGVSZWZCYXNlKSB7Ci0JCWZpbmFsIFZhcmlhYmxlUmVmQmFzZSByZWYgPSAoVmFyaWFibGVSZWZCYXNlKXBhcmVudDsKLQkJZmluYWwgVmFyaWFibGVCYXNlIHZhciA9IHJlZi5nZXRWYXJpYWJsZSgpOwotCQlmaW5hbCBFeHByZXNzaW9uIGV4cCA9IHZhci5nZXRFeHByZXNzaW9uKCk7Ci0JCWlmIChleHAgaW5zdGFuY2VvZiBTdGVwKSB7Ci0JCSAgICBfcHR5cGUgPSAoKFN0ZXApZXhwKS5nZXROb2RlVHlwZSgpOwotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgU3RlcCkgewotCQlfcHR5cGUgPSAoKFN0ZXApcGFyZW50KS5nZXROb2RlVHlwZSgpOwotCSAgICB9Ci0JfQotCXJldHVybiBfcHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gcGFyZW50SXNQYXR0ZXJuKCkgewotCXJldHVybiAoZ2V0UGFyZW50KCkgaW5zdGFuY2VvZiBQYXR0ZXJuKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByKCkgewotCXJldHVybiBfZXhwOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JaWYgKGlzTnRoUG9zaXRpb25GaWx0ZXIoKSkKLQkgICAgcmV0dXJuICJwcmVkKFsiICsgX2V4cCArICJdLCIrZ2V0UG9zVHlwZSgpKyIpIjsKLQllbHNlCi0JICAgIHJldHVybiAicHJlZCgiICsgX2V4cCArICcpJzsKLSAgICB9Ci0JCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhIHByZWRpY2F0ZSBleHByZXNzaW9uLiBJZiB0aGUgdHlwZSBvZiB0aGUgZXhwcmVzc2lvbiBpcyAKLSAgICAgKiBudW1iZXIgY29udmVydCBpdCB0byBib29sZWFuIGJ5IGFkZGluZyBhIGNvbXBhcmlzb24gd2l0aCBwb3NpdGlvbigpLgotICAgICAqIE5vdGUgdGhhdCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIHBhcmFtZXRlciwgd2UgY2Fubm90IGRpc3Rpbmd1aXNoCi0gICAgICogYXQgY29tcGlsZSB0aW1lIGlmIGl0cyB0eXBlIGlzIG51bWJlciBvciBub3QuIEhlbmNlLCBleHByZXNzaW9ucyBvZiAKLSAgICAgKiByZWZlcmVuY2UgdHlwZSBhcmUgYWx3YXlzIGNvbnZlcnRlZCB0byBib29sZWFucy4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCi0JVHlwZSB0ZXhwID0gX2V4cC50eXBlQ2hlY2soc3RhYmxlKTsKLQotCS8vIFdlIG5lZWQgZXhwbGljaXQgdHlwZSBpbmZvcm1hdGlvbiBmb3IgcmVmZXJlbmNlIHR5cGVzIC0gbm8gZ29vZCEKLQlpZiAodGV4cCBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLQkgICAgdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotCX0KLQotCS8vIEEgcmVzdWx0IHRyZWUgZnJhZ21lbnQgc2hvdWxkIG5vdCBiZSBjYXN0IGRpcmVjdGx5IHRvIGEgbnVtYmVyIHR5cGUsCi0JLy8gYnV0IHJhdGhlciB0byBhIGJvb2xlYW4gdmFsdWUsIGFuZCB0aGVuIHRvIGEgbnVtZXIgKDAgb3IgMSkuCi0JLy8gUmVmLiBzZWN0aW9uIDExLjIgb2YgdGhlIFhTTFQgMS4wIHNwZWMKLQlpZiAodGV4cCBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKSB7Ci0JICAgIF9leHAgPSBuZXcgQ2FzdEV4cHIoX2V4cCwgVHlwZS5Cb29sZWFuKTsKLQkgICAgX2V4cCA9IG5ldyBDYXN0RXhwcihfZXhwLCBUeXBlLlJlYWwpOwotCSAgICB0ZXhwID0gX2V4cC50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0KLQkvLyBOdW1lcmljYWwgdHlwZXMgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gYSBwb3NpdGlvbiBmaWx0ZXIKLQlpZiAodGV4cCBpbnN0YW5jZW9mIE51bWJlclR5cGUpIHsKLQotCSAgICAvLyBDYXN0IGFueSBudW1lcmljYWwgdHlwZXMgdG8gYW4gaW50ZWdlcgotCSAgICBpZiAodGV4cCBpbnN0YW5jZW9mIEludFR5cGUgPT0gZmFsc2UpIHsKLQkJX2V4cCA9IG5ldyBDYXN0RXhwcihfZXhwLCBUeXBlLkludCk7Ci0JICAgIH0KLQotCSAgICAvLyBFeHBhbmQgW2xhc3QoKV0gaW50byBbcG9zaXRpb24oKSA9IGxhc3QoKV0KLQkgICAgaWYgKChfZXhwIGluc3RhbmNlb2YgTGFzdENhbGwpIHx8Ci0JCShnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIFBhdHRlcm4pIHx8Ci0JCShnZXRQYXJlbnQoKSBpbnN0YW5jZW9mIEZpbHRlckV4cHIpKSB7Ci0JCWZpbmFsIFFOYW1lIHBvc2l0aW9uID0gZ2V0UGFyc2VyKCkuZ2V0UU5hbWUoInBvc2l0aW9uIik7Ci0JCWZpbmFsIFBvc2l0aW9uQ2FsbCBwb3NpdGlvbkNhbGw7Ci0JCXBvc2l0aW9uQ2FsbCA9IG5ldyBQb3NpdGlvbkNhbGwocG9zaXRpb24sIC0xKTsKLQkJcG9zaXRpb25DYWxsLnNldFBhcnNlcihnZXRQYXJzZXIoKSk7Ci0JCXBvc2l0aW9uQ2FsbC5zZXRQYXJlbnQodGhpcyk7Ci0JCV9leHAgPSBuZXcgRXF1YWxpdHlFeHByKEVxdWFsaXR5RXhwci5FUSwgcG9zaXRpb25DYWxsLCBfZXhwKTsKLQotCQlpZiAoX2V4cC50eXBlQ2hlY2soc3RhYmxlKSAhPSBUeXBlLkJvb2xlYW4pIHsKLQkJICAgIF9leHAgPSBuZXcgQ2FzdEV4cHIoX2V4cCwgVHlwZS5Cb29sZWFuKTsKLQkJfQotCQlfbnRoUG9zaXRpb25GaWx0ZXIgPSBmYWxzZTsKLQkJcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotCSAgICB9Ci0JICAgIC8vIFVzZSBOdGhQb3NpdGlvbkl0ZXJhdG9yIHRvIGhhbmRsZSBbcG9zaXRpb24oKV0gb3IgW2FdCi0JICAgIGVsc2UgewotCQlTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLQkJaWYgKChwYXJlbnQgIT0gbnVsbCkgJiYgKHBhcmVudCBpbnN0YW5jZW9mIFN0ZXApKSB7Ci0JCSAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50KCk7Ci0JCSAgICBpZiAoKHBhcmVudCAhPSBudWxsKSAmJgotCQkJKHBhcmVudCBpbnN0YW5jZW9mIEFic29sdXRlTG9jYXRpb25QYXRoKSkgewotCQkJLy8gVE9ETzogU3BlY2lhbCBjYXNlIGZvciAiLy8qW25dIiBwYXR0ZXJuLi4uLgotCQkJX250aERlc2NlbmRhbnQgPSB0cnVlOwotCQkJcmV0dXJuIF90eXBlID0gVHlwZS5Ob2RlU2V0OwotCQkgICAgfQotCQl9Ci0JCV9udGhQb3NpdGlvbkZpbHRlciA9IHRydWU7Ci0JCXJldHVybiBfdHlwZSA9IFR5cGUuTm9kZVNldDsKLQkgICAgfQotCX0KLQkvLyBBbGwgb3RoZXIgdHlwZXMgd2lsbCBiZSBoYW5kbGVkIGFzIGJvb2xlYW4gdmFsdWVzCi0JZWxzZSBpZiAodGV4cCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlID09IGZhbHNlKSB7Ci0JICAgIF9leHAgPSBuZXcgQ2FzdEV4cHIoX2V4cCwgVHlwZS5Cb29sZWFuKTsKLQl9Ci0KLQlfbnRoUG9zaXRpb25GaWx0ZXIgPSBmYWxzZTsKLQlyZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0gICAgfQotCQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyAiRmlsdGVyIiBjbGFzcyBpbXBsZW1lbnRpbmcKLSAgICAgKiA8Y29kZT5DdXJyZW50Tm9kZUxpc3RGaWx0ZXI8L2NvZGU+LiBBbGxvY2F0ZSByZWdpc3RlcnMgZm9yIGxvY2FsIAotICAgICAqIHZhcmlhYmxlcyBhbmQgbG9jYWwgcGFyYW1ldGVycyBwYXNzZWQgaW4gdGhlIGNsb3N1cmUgdG8gdGVzdCgpLgotICAgICAqIE5vdGljZSB0aGF0IGxvY2FsIHZhcmlhYmxlcyBuZWVkIHRvIGJlICJ1bmJveGVkIi4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZUZpbHRlcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JVGVzdEdlbmVyYXRvciB0ZXN0R2VuOwotCUxvY2FsVmFyaWFibGVHZW4gbG9jYWw7Ci0JRmlsdGVyR2VuZXJhdG9yIGZpbHRlckdlbjsKLQotCV9jbGFzc05hbWUgPSBnZXRYU0xUQygpLmdldEhlbHBlckNsYXNzTmFtZSgpOwotCWZpbHRlckdlbiA9IG5ldyBGaWx0ZXJHZW5lcmF0b3IoX2NsYXNzTmFtZSwKLQkJCQkJImphdmEubGFuZy5PYmplY3QiLAotCQkJCQl0b1N0cmluZygpLCAKLQkJCQkJQUNDX1BVQkxJQyB8IEFDQ19TVVBFUiwKLQkJCQkJbmV3IFN0cmluZ1tdIHsKLQkJCQkJICAgIENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUgotCQkJCQl9LAotCQkJCQljbGFzc0dlbi5nZXRTdHlsZXNoZWV0KCkpOwkKLQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gZmlsdGVyR2VuLmdldENvbnN0YW50UG9vbCgpOwotCi0JdGVzdEdlbiA9IG5ldyBUZXN0R2VuZXJhdG9yKEFDQ19QVUJMSUMgfCBBQ0NfRklOQUwsCi0JCQkJICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuQk9PTEVBTiwgCi0JCQkJICAgIG5ldyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlW10gewotCQkJCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLklOVCwKLQkJCQkJZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQsCi0JCQkJCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLklOVCwKLQkJCQkJVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfU0lHKSwKLQkJCQkJVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpCi0JCQkJICAgIH0sCi0JCQkJICAgIG5ldyBTdHJpbmdbXSB7Ci0JCQkJCSJub2RlIiwKLQkJCQkJInBvc2l0aW9uIiwKLQkJCQkJImxhc3QiLAotCQkJCQkiY3VycmVudCIsCi0JCQkJCSJ0cmFuc2xldCIsCi0JCQkJCSJpdGVyYXRvciIKLQkJCQkgICAgfSwKLQkJCQkgICAgInRlc3QiLCBfY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQkJCi0JLy8gU3RvcmUgdGhlIGRvbSBpbiBhIGxvY2FsIHZhcmlhYmxlCi0JbG9jYWwgPSB0ZXN0R2VuLmFkZExvY2FsVmFyaWFibGUoImRvY3VtZW50IiwKLQkJCQkJIFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyksCi0JCQkJCSBudWxsLCBudWxsKTsKLQlmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCk7Ci0JaWwuYXBwZW5kKGZpbHRlckdlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzTmFtZSkpKTsKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihjbGFzc05hbWUsCi0JCQkJCSAgICAgICBET01fRklFTEQsIERPTV9JTlRGX1NJRykpKTsKLQlpbC5hcHBlbmQobmV3IEFTVE9SRShsb2NhbC5nZXRJbmRleCgpKSk7Ci0KLQkvLyBTdG9yZSB0aGUgZG9tIGluZGV4IGluIHRoZSB0ZXN0IGdlbmVyYXRvcgotCXRlc3RHZW4uc2V0RG9tSW5kZXgobG9jYWwuZ2V0SW5kZXgoKSk7Ci0KLQlfZXhwLnRyYW5zbGF0ZShmaWx0ZXJHZW4sIHRlc3RHZW4pOwotCWlsLmFwcGVuZChJUkVUVVJOKTsKLQkKLQl0ZXN0R2VuLnN0cmlwQXR0cmlidXRlcyh0cnVlKTsKLQl0ZXN0R2VuLnNldE1heExvY2FscygpOwotCXRlc3RHZW4uc2V0TWF4U3RhY2soKTsKLQl0ZXN0R2VuLnJlbW92ZU5PUHMoKTsKLQotCWZpbHRlckdlbi5hZGRFbXB0eUNvbnN0cnVjdG9yKEFDQ19QVUJMSUMpOwotCWZpbHRlckdlbi5hZGRNZXRob2QodGVzdEdlbi5nZXRNZXRob2QoKSk7Ci0JCQotCWdldFhTTFRDKCkuZHVtcENsYXNzKGZpbHRlckdlbi5nZXRKYXZhQ2xhc3MoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBwcmVkaWNhdGUgaXMgYSB0ZXN0IGZvciB0aGUgZXhpc3RhbmNlIG9mIGFuCi0gICAgICogZWxlbWVudCBvciBhdHRyaWJ1dGUuIEFsbCB3ZSBoYXZlIHRvIGRvIGlzIHRvIGdldCB0aGUgZmlyc3Qgbm9kZQotICAgICAqIGZyb20gdGhlIHN0ZXAsIGNoZWNrIGlmIGl0IGlzIHRoZXJlLCBhbmQgdGhlbiByZXR1cm4gdHJ1ZS9mYWxzZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0Jvb2xlYW5UZXN0KCkgewotCXJldHVybiAoX2V4cCBpbnN0YW5jZW9mIEJvb2xlYW5FeHByKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2QgdG8gc2VlIGlmIHdlIGNhbiBvcHRpbWlzZSB0aGUgcHJlZGljYXRlIGJ5IHVzaW5nIGEgc3BlY2lhbGlzZWQKLSAgICAgKiBpdGVyYXRvciBmb3IgZXhwcmVzc2lvbnMgbGlrZSAnL2Zvby9iYXJbQGF0dHIgPSAkdmFyXScsIHdoaWNoIGFyZQotICAgICAqIHZlcnkgY29tbW9uIGluIG1hbnkgc3R5bGVzaGVldHMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc05vZGVWYWx1ZVRlc3QoKSB7Ci0JaWYgKChnZXRTdGVwKCkgIT0gbnVsbCkgJiYgKGdldENvbXBhcmVWYWx1ZSgpICE9IG51bGwpKQotCSAgICByZXR1cm4gdHJ1ZTsKLQllbHNlCi0JICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3ZhbHVlID0gbnVsbDsKLSAgICBwcml2YXRlIFN0ZXAgX3N0ZXAgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2QgZm9yIG9wdGltaXNhdGlvbi4gU2VlIGlzTm9kZVZhbHVlVGVzdCgpCi0gICAgICovCi0gICAgcHVibGljIEV4cHJlc3Npb24gZ2V0Q29tcGFyZVZhbHVlKCkgewotCWlmIChfdmFsdWUgIT0gbnVsbCkgcmV0dXJuIF92YWx1ZTsKLQlpZiAoX2V4cCA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQotCWlmIChfZXhwIGluc3RhbmNlb2YgRXF1YWxpdHlFeHByKSB7Ci0JICAgIEVxdWFsaXR5RXhwciBleHAgPSAoRXF1YWxpdHlFeHByKV9leHA7Ci0JICAgIEV4cHJlc3Npb24gbGVmdCA9IGV4cC5nZXRMZWZ0KCk7Ci0JICAgIEV4cHJlc3Npb24gcmlnaHQgPSBleHAuZ2V0UmlnaHQoKTsKLQotCSAgICBUeXBlIHRsZWZ0ID0gbGVmdC5nZXRUeXBlKCk7Ci0JICAgIFR5cGUgdHJpZ2h0ID0gcmlnaHQuZ2V0VHlwZSgpOwotCi0JICAgIAotCSAgICBpZiAobGVmdCBpbnN0YW5jZW9mIENhc3RFeHByKSBsZWZ0ID0gKChDYXN0RXhwcilsZWZ0KS5nZXRFeHByKCk7Ci0JICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIENhc3RFeHByKSByaWdodCA9ICgoQ2FzdEV4cHIpcmlnaHQpLmdldEV4cHIoKTsKLQkgICAgCi0JICAgIHRyeSB7Ci0JCWlmICgodGxlZnQgPT0gVHlwZS5TdHJpbmcpICYmICghKGxlZnQgaW5zdGFuY2VvZiBTdGVwKSkpCi0JCSAgICBfdmFsdWUgPSBleHAuZ2V0TGVmdCgpOwotCQlpZiAobGVmdCBpbnN0YW5jZW9mIFZhcmlhYmxlUmVmQmFzZSkgCi0JCSAgICBfdmFsdWUgPSBuZXcgQ2FzdEV4cHIobGVmdCwgVHlwZS5TdHJpbmcpOwotCQlpZiAoX3ZhbHVlICE9IG51bGwpIHJldHVybiBfdmFsdWU7Ci0JICAgIH0KLQkgICAgY2F0Y2ggKFR5cGVDaGVja0Vycm9yIGUpIHsgfQotCi0JICAgIHRyeSB7Ci0JCWlmICgodHJpZ2h0ID09IFR5cGUuU3RyaW5nKSAmJiAoIShyaWdodCBpbnN0YW5jZW9mIFN0ZXApKSkKLQkJICAgIF92YWx1ZSA9IGV4cC5nZXRSaWdodCgpOwotCQlpZiAocmlnaHQgaW5zdGFuY2VvZiBWYXJpYWJsZVJlZkJhc2UpCi0JCSAgICBfdmFsdWUgPSBuZXcgQ2FzdEV4cHIocmlnaHQsIFR5cGUuU3RyaW5nKTsKLQkJaWYgKF92YWx1ZSAhPSBudWxsKSByZXR1cm4gX3ZhbHVlOwotCSAgICB9Ci0JICAgIGNhdGNoIChUeXBlQ2hlY2tFcnJvciBlKSB7IH0KLQotCX0KLQlyZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IG1ldGhvZCBmb3Igb3B0aW1pc2F0aW9uLiBTZWUgaXNOb2RlVmFsdWVUZXN0KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RlcCBnZXRTdGVwKCkgewotCWlmIChfc3RlcCAhPSBudWxsKSByZXR1cm4gX3N0ZXA7Ci0JaWYgKF9leHAgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLQlpZiAoX2V4cCBpbnN0YW5jZW9mIEVxdWFsaXR5RXhwcikgewotCSAgICBFcXVhbGl0eUV4cHIgZXhwID0gKEVxdWFsaXR5RXhwcilfZXhwOwotCSAgICBFeHByZXNzaW9uIGxlZnQgPSBleHAuZ2V0TGVmdCgpOwotCSAgICBFeHByZXNzaW9uIHJpZ2h0ID0gZXhwLmdldFJpZ2h0KCk7Ci0KLQkgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBDYXN0RXhwcikgbGVmdCA9ICgoQ2FzdEV4cHIpbGVmdCkuZ2V0RXhwcigpOwotCSAgICBpZiAobGVmdCBpbnN0YW5jZW9mIFN0ZXApIF9zdGVwID0gKFN0ZXApbGVmdDsKLQkgICAgCi0JICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIENhc3RFeHByKSByaWdodCA9ICgoQ2FzdEV4cHIpcmlnaHQpLmdldEV4cHIoKTsKLQkgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgU3RlcCkgX3N0ZXAgPSAoU3RlcClyaWdodDsKLQl9Ci0JLy9pZiAoKF9zdGVwICE9IG51bGwpICYmIChfc3RlcC5pc0FiYnJldmlhdGVkRG90KCkpKSBfc3RlcCA9IG51bGw7Ci0JcmV0dXJuIF9zdGVwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBhIHByZWRpY2F0ZSBleHByZXNzaW9uLiBUaGlzIHRyYW5zbGF0aW9uIHB1c2hlcwotICAgICAqIHR3byByZWZlcmVuY2VzIG9uIHRoZSBzdGFjazogYSByZWZlcmVuY2UgdG8gYSBuZXdseSBjcmVhdGVkCi0gICAgICogZmlsdGVyIG9iamVjdCBhbmQgYSByZWZlcmVuY2UgdG8gdGhlIHByZWRpY2F0ZSdzIGNsb3N1cmUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0KLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaWYgKF9udGhQb3NpdGlvbkZpbHRlciB8fCBfbnRoRGVzY2VuZGFudCkgewotCSAgICBfZXhwLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JZWxzZSBpZiAoaXNOb2RlVmFsdWVUZXN0KCkgJiYgKGdldFBhcmVudCgpIGluc3RhbmNlb2YgU3RlcCkpIHsKLQkgICAgX3ZhbHVlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgKChFcXVhbGl0eUV4cHIpX2V4cCkuZ2V0T3AoKSkpOwotCX0KLQllbHNlIHsKLQkgICAgY29tcGlsZUZpbHRlcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKF9jbGFzc05hbWUpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihfY2xhc3NOYW1lLAotCQkJCQkJCSAiPGluaXQ+IiwgIigpViIpKSk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1Byb2Nlc3NpbmdJbnN0cnVjdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzNTYxYWUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUHJvY2Vzc2luZ0luc3RydWN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24gZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIEF0dHJpYnV0ZVZhbHVlIF9uYW1lOyAvLyBuYW1lIHRyZWF0ZWQgYXMgQVZUICg3LjEuMykKLSAgICAKLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQlmaW5hbCBTdHJpbmcgbmFtZSAgPSBnZXRBdHRyaWJ1dGUoIm5hbWUiKTsKLQlfbmFtZSA9IEF0dHJpYnV0ZVZhbHVlLmNyZWF0ZSh0aGlzLCBuYW1lLCBwYXJzZXIpOwotCWlmIChuYW1lLmVxdWFscygieG1sIikpIHsKLQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5JTExFR19QSV9FUlIsICJ4bWwiKTsKLQl9Ci0JcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX25hbWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0JdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBTYXZlIHRoZSBjdXJyZW50IGhhbmRsZXIgYmFzZSBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCWlsLmFwcGVuZChEVVApOwkJLy8gZmlyc3QgYXJnIHRvICJhdHRyaWJ1dGVzIiBjYWxsCi0JCi0JLy8gcHVzaCBhdHRyaWJ1dGUgbmFtZQotCV9uYW1lLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsvLyAybmQgYXJnCi0KLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkgICAgICAgInN0cmluZ1ZhbHVlSGFuZGxlciIsCi0JCQkJCSAgICAgICBTVFJJTkdfVkFMVUVfSEFORExFUl9TSUcpKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0KLQkvLyB0cmFuc2xhdGUgY29udGVudHMgd2l0aCBzdWJzdGl0dXRlZCBoYW5kbGVyCi0JdHJhbnNsYXRlQ29udGVudHMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkvLyBnZXQgU3RyaW5nIG91dCBvZiB0aGUgaGFuZGxlcgotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19WQUxVRV9IQU5ETEVSLAotCQkJCQkJICAgICAiZ2V0VmFsdWUiLAotCQkJCQkJICAgICAiKCkiICsgU1RSSU5HX1NJRykpKTsKLQkvLyBjYWxsICJwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24iCi0JZmluYWwgaW50IHByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9Ci0JICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLQkJCQkgICAgICAicHJvY2Vzc2luZ0luc3RydWN0aW9uIiwgCi0JCQkJICAgICAgIigiCi0JCQkJICAgICAgKyBTVFJJTkdfU0lHCi0JCQkJICAgICAgKyBTVFJJTkdfU0lHCi0JCQkJICAgICAgKyAiKVYiKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24sIDMpKTsKLQkvLyBSZXN0b3JlIG9sZCBoYW5kbGVyIGJhc2UgZnJvbSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1FOYW1lLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9RTmFtZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZWFjZTEwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1FOYW1lLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzEgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotZmluYWwgY2xhc3MgUU5hbWUgewotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9sb2NhbG5hbWU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX3ByZWZpeDsKLSAgICBwcml2YXRlIFN0cmluZyBfbmFtZXNwYWNlOwotICAgIHByaXZhdGUgU3RyaW5nIF9zdHJpbmdSZXA7Ci0gICAgcHJpdmF0ZSBpbnQgICAgX2hhc2hDb2RlOwotCi0gICAgcHVibGljIFFOYW1lKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBwcmVmaXgsIFN0cmluZyBsb2NhbG5hbWUpIHsKLQlfbmFtZXNwYWNlID0gbmFtZXNwYWNlOwotCV9wcmVmaXggICAgPSBwcmVmaXg7Ci0JX2xvY2FsbmFtZSA9IGxvY2FsbmFtZTsKLQlpZiAoKG5hbWVzcGFjZSAhPSBudWxsKSAmJiAoIW5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkpIHsKLQkgICAgX3N0cmluZ1JlcCA9IG5hbWVzcGFjZSsnOicrbG9jYWxuYW1lOwotCX0KLQllbHNlIHsKLQkgICAgX3N0cmluZ1JlcCA9IGxvY2FsbmFtZTsKLQl9Ci0KLQlfaGFzaENvZGUgID0gX3N0cmluZ1JlcC5oYXNoQ29kZSgpICsgMTk7IC8vIGNhY2hlZCBmb3Igc3BlZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjbGVhckRlZmF1bHROYW1lc3BhY2UoKSB7Ci0JaWYgKChfcHJlZml4ID09IG51bGwpIHx8IChfcHJlZml4LmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSkgewotCSAgICBfbmFtZXNwYWNlID0gbnVsbDsKLQkgICAgX3N0cmluZ1JlcCA9IF9sb2NhbG5hbWU7Ci0JICAgIF9oYXNoQ29kZSAgPSBfc3RyaW5nUmVwLmhhc2hDb2RlKCkgKyAxOTsgLy8gY2FjaGVkIGZvciBzcGVlZAotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjbGVhck5hbWVzcGFjZSgpIHsKLQlfbmFtZXNwYWNlID0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuIF9zdHJpbmdSZXA7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRTdHJpbmdSZXAoKSB7Ci0JcmV0dXJuIF9zdHJpbmdSZXA7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewotCXJldHVybiB0aGlzID09IG90aGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxQYXJ0KCkgewotCXJldHVybiBfbG9jYWxuYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkgewotCXJldHVybiBfbmFtZXNwYWNlOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgewotCXJldHVybiBfcHJlZml4OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0JcmV0dXJuIF9oYXNoQ29kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGR1bXAoKSB7Ci0JcmV0dXJuKG5ldyBTdHJpbmcoIlFOYW1lOiAiK19uYW1lc3BhY2UrIigiK19wcmVmaXgrIik6IitfbG9jYWxuYW1lKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUmVhbEV4cHIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1JlYWxFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmMWRlMDAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUmVhbEV4cHIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgUmVhbEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIHsKLSAgICBwcml2YXRlIGRvdWJsZSBfdmFsdWU7Ci0KLSAgICBwdWJsaWMgUmVhbEV4cHIoZG91YmxlIHZhbHVlKSB7Ci0JX3ZhbHVlID0gdmFsdWU7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlyZXR1cm4gX3R5cGUgPSBUeXBlLlJlYWw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gInJlYWwtZXhwcigiICsgX3ZhbHVlICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCUNvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX3ZhbHVlKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUmVsYXRpb25hbEV4cHIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1JlbGF0aW9uYWxFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQ1MWQ3ZGQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUmVsYXRpb25hbEV4cHIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5PcGVyYXRvcnM7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgUmVsYXRpb25hbEV4cHIgZXh0ZW5kcyBFeHByZXNzaW9uIGltcGxlbWVudHMgT3BlcmF0b3JzIHsKLSAgICBwcml2YXRlIGludCBfb3A7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9sZWZ0LCBfcmlnaHQ7Ci0JCQotICAgIHB1YmxpYyBSZWxhdGlvbmFsRXhwcihpbnQgb3AsIEV4cHJlc3Npb24gbGVmdCwgRXhwcmVzc2lvbiByaWdodCkgewotCV9vcCA9IG9wOwotCShfbGVmdCA9IGxlZnQpLnNldFBhcmVudCh0aGlzKTsKLQkoX3JpZ2h0ID0gcmlnaHQpLnNldFBhcmVudCh0aGlzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotCXN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotCV9sZWZ0LnNldFBhcnNlcihwYXJzZXIpOwotCV9yaWdodC5zZXRQYXJzZXIocGFyc2VyKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUmVmZXJlbmNlQXJncygpIHsKLQlyZXR1cm4gX2xlZnQuZ2V0VHlwZSgpIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSB8fAotCSAgICBfcmlnaHQuZ2V0VHlwZSgpIGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNOb2RlQXJncygpIHsKLQlyZXR1cm4gX2xlZnQuZ2V0VHlwZSgpIGluc3RhbmNlb2YgTm9kZVR5cGUgfHwKLQkgICAgX3JpZ2h0LmdldFR5cGUoKSBpbnN0YW5jZW9mIE5vZGVUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGhhc05vZGVTZXRBcmdzKCkgewotCXJldHVybiBfbGVmdC5nZXRUeXBlKCkgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSB8fAotCSAgICBfcmlnaHQuZ2V0VHlwZSgpIGluc3RhbmNlb2YgTm9kZVNldFR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlUeXBlIHRsZWZ0ID0gX2xlZnQudHlwZUNoZWNrKHN0YWJsZSk7IAotCVR5cGUgdHJpZ2h0ID0gX3JpZ2h0LnR5cGVDaGVjayhzdGFibGUpOwotCi0JLy9idWcgZml4ICMgMjgzOCwgY2FzdCB0byByZWFscyBpZiBib3RoIGFyZSByZXN1bHQgdHJlZSBmcmFnbWVudHMKLQlpZiAodGxlZnQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSAmJgotCSAgICB0cmlnaHQgaW5zdGFuY2VvZiBSZXN1bHRUcmVlVHlwZSApIHsKLQkgICAgX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgVHlwZS5SZWFsKTsKLQkgICAgX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuUmVhbCk7Ci0JfQotCi0JLy8gSWYgb25lIGlzIG9mIHJlZmVyZW5jZSB0eXBlLCB0aGVuIGNvbnZlcnQgdGhlIG90aGVyIHRvbwotCWlmIChoYXNSZWZlcmVuY2VBcmdzKCkpIHsKLQkgICAgaWYgKHRsZWZ0IGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSkgewotCQlfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLlJlZmVyZW5jZSk7Ci0JICAgIH0KLQkgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIFJlZmVyZW5jZVR5cGUpIHsKLQkJX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIFR5cGUuUmVmZXJlbmNlKTsKLQkgICAgfQotCSAgICByZXR1cm4gX3R5cGUgPSBUeXBlLkJvb2xlYW47Ci0JfQotCi0JaWYgKGhhc05vZGVTZXRBcmdzKCkpIHsKLQkgICAgLy8gRW5zdXJlIHRoYXQgdGhlIG5vZGUtc2V0IGlzIHRoZSBsZWZ0IGFyZ3VtZW50Ci0JICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBOb2RlU2V0VHlwZSkgewotCQlmaW5hbCBFeHByZXNzaW9uIHRlbXAgPSBfcmlnaHQ7IF9yaWdodCA9IF9sZWZ0OyBfbGVmdCA9IHRlbXA7Ci0JCV9vcCA9IChfb3AgPT0gT3BlcmF0b3JzLkdUKSA/IE9wZXJhdG9ycy5MVCA6Ci0JCSAgICAoX29wID09IE9wZXJhdG9ycy5MVCkgPyBPcGVyYXRvcnMuR1QgOgotCQkgICAgKF9vcCA9PSBPcGVyYXRvcnMuR0UpID8gT3BlcmF0b3JzLkxFIDogT3BlcmF0b3JzLkdFOwotCQl0cmlnaHQgPSBfcmlnaHQuZ2V0VHlwZSgpOwotCSAgICB9Ci0KLQkgICAgLy8gUHJvbW90ZSBub2RlcyB0byBub2RlIHNldHMKLQkgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0JCV9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuTm9kZVNldCk7Ci0JICAgIH0KLQotCSAgICAvLyBQcm9tb3RlIGludGVnZXIgdG8gZG91YmxlcyB0byBoYXZlIGZld2VyIGNvbXBhcmVzCi0JICAgIGlmICh0cmlnaHQgaW5zdGFuY2VvZiBJbnRUeXBlKSB7Ci0JCV9yaWdodCA9IG5ldyBDYXN0RXhwcihfcmlnaHQsIFR5cGUuUmVhbCk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIF90eXBlID0gVHlwZS5Cb29sZWFuOwotCX0KLQotCS8vIEluIHRoZSBub2RlLWJvb2xlYW4gY2FzZSwgY29udmVydCBub2RlIHRvIGJvb2xlYW4gZmlyc3QKLQlpZiAoaGFzTm9kZUFyZ3MoKSkgewotCSAgICBpZiAodGxlZnQgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSkgewotCQlfcmlnaHQgPSBuZXcgQ2FzdEV4cHIoX3JpZ2h0LCBUeXBlLkJvb2xlYW4pOwotCQl0cmlnaHQgPSBUeXBlLkJvb2xlYW47Ci0JICAgIH0KLQkgICAgaWYgKHRyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlKSB7Ci0JCV9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBUeXBlLkJvb2xlYW4pOwotCQl0bGVmdCA9IFR5cGUuQm9vbGVhbjsKLQkgICAgfQotCX0KLQotCS8vIExvb2t1cCB0aGUgdGFibGUgb2YgcHJpbW9wcyB0byBmaW5kIHRoZSBiZXN0IG1hdGNoCi0JTWV0aG9kVHlwZSBwdHlwZSA9IGxvb2t1cFByaW1vcChzdGFibGUsIE9wZXJhdG9ycy5uYW1lc1tfb3BdLAotCQkJCQluZXcgTWV0aG9kVHlwZShUeXBlLlZvaWQsIAotCQkJCQkJICAgICAgIHRsZWZ0LCB0cmlnaHQpKTsgCi0KLQlpZiAocHR5cGUgIT0gbnVsbCkgewotCSAgICBUeXBlIGFyZzEgPSAoVHlwZSkgcHR5cGUuYXJnc1R5cGUoKS5lbGVtZW50QXQoMCk7Ci0JICAgIGlmICghYXJnMS5pZGVudGljYWxUbyh0bGVmdCkpIHsKLQkJX2xlZnQgPSBuZXcgQ2FzdEV4cHIoX2xlZnQsIGFyZzEpOwotCSAgICB9Ci0JICAgIFR5cGUgYXJnMiA9IChUeXBlKSBwdHlwZS5hcmdzVHlwZSgpLmVsZW1lbnRBdCgxKTsKLQkgICAgaWYgKCFhcmcyLmlkZW50aWNhbFRvKHRyaWdodCkpIHsKLQkJX3JpZ2h0ID0gbmV3IENhc3RFeHByKF9yaWdodCwgYXJnMSk7CQkJCQotCSAgICB9Ci0JICAgIHJldHVybiBfdHlwZSA9IHB0eXBlLnJlc3VsdFR5cGUoKTsKLQl9Ci0JdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWlmIChoYXNOb2RlU2V0QXJncygpIHx8IGhhc1JlZmVyZW5jZUFyZ3MoKSkgewotCSAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCSAgICAvLyBDYWxsIGNvbXBhcmUoKSBmcm9tIHRoZSBCYXNpc0xpYnJhcnkKLQkgICAgX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfbGVmdC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIF9yaWdodC50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIF9yaWdodC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgX29wKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0KLQkgICAgaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLCAiY29tcGFyZSIsCi0JCQkJCSAiKCIKLQkJCQkJICsgX2xlZnQuZ2V0VHlwZSgpLnRvU2lnbmF0dXJlKCkgCi0JCQkJCSArIF9yaWdodC5nZXRUeXBlKCkudG9TaWduYXR1cmUoKQotCQkJCQkgKyAiSSIKLQkJCQkJICsgTk9ERV9TSUcKLQkJCQkJICsgRE9NX0lOVEZfU0lHCi0JCQkJCSArICIpWiIpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotCX0KLQllbHNlIHsKLQkgICAgdHJhbnNsYXRlRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWlmIChoYXNOb2RlU2V0QXJncygpIHx8IGhhc1JlZmVyZW5jZUFyZ3MoKSkgewotCSAgICB0cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGRlc3ludGhlc2l6ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIEJyYW5jaEluc3RydWN0aW9uIGJpID0gbnVsbDsKLQkgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JICAgIF9sZWZ0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX3JpZ2h0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICAvLyBUT0RPOiBvcHRpbWl6ZSBpZiBvbmUgb2YgdGhlIGFyZ3MgaXMgMAotCi0JICAgIGJvb2xlYW4gdG96ZXJvID0gZmFsc2U7Ci0JICAgIFR5cGUgdGxlZnQgPSBfbGVmdC5nZXRUeXBlKCk7IAotCi0JICAgIGlmICh0bGVmdCBpbnN0YW5jZW9mIFJlYWxUeXBlKSB7Ci0JCWlsLmFwcGVuZCh0bGVmdC5DTVAoX29wID09IExUIHx8IF9vcCA9PSBMRSkpOwotCQl0bGVmdCA9IFR5cGUuSW50OwotCQl0b3plcm8gPSB0cnVlOwotCSAgICB9Ci0KLQkgICAgc3dpdGNoIChfb3ApIHsKLQkgICAgY2FzZSBMVDoKLQkJYmkgPSB0bGVmdC5HRSh0b3plcm8pOwkKLQkJYnJlYWs7Ci0JCQotCSAgICBjYXNlIEdUOgotCQliaSA9IHRsZWZ0LkxFKHRvemVybyk7Ci0JCWJyZWFrOwotCQkKLQkgICAgY2FzZSBMRToKLQkJYmkgPSB0bGVmdC5HVCh0b3plcm8pOwotCQlicmVhazsKLQkJCi0JICAgIGNhc2UgR0U6Ci0JCWJpID0gdGxlZnQuTFQodG96ZXJvKTsKLQkJYnJlYWs7Ci0JCQotCSAgICBkZWZhdWx0OgotCQlmaW5hbCBFcnJvck1zZyBtc2cgPSAKLQkJICAgIG5ldyBFcnJvck1zZygiVW5rbm93biBvcGVyYXRvciBmb3IgcmVsYXRpb25hbCBleHByZXNzaW9uIik7Ci0JCWdldFBhcnNlcigpLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgbXNnKTsKLQkgICAgfQotCi0JICAgIF9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChiaSkpOwkJLy8gbXVzdCBiZSBiYWNrcGF0Y2hlZAotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiBPcGVyYXRvcnMubmFtZXNbX29wXSArICcoJyArIF9sZWZ0ICsgIiwgIiArIF9yaWdodCArICcpJzsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9SZWxhdGl2ZUxvY2F0aW9uUGF0aC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUmVsYXRpdmVMb2NhdGlvblBhdGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzg3ZmExYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9SZWxhdGl2ZUxvY2F0aW9uUGF0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWFic3RyYWN0IGNsYXNzIFJlbGF0aXZlTG9jYXRpb25QYXRoIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0QXhpcyhpbnQgYXhpcyk7Ci0gICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZGVzY2VuZGFudEF4aXMoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1JlbGF0aXZlUGF0aFBhdHRlcm4uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1JlbGF0aXZlUGF0aFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTU0OGUwOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9SZWxhdGl2ZVBhdGhQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotYWJzdHJhY3QgY2xhc3MgUmVsYXRpdmVQYXRoUGF0dGVybiBleHRlbmRzIExvY2F0aW9uUGF0aFBhdHRlcm4ge30KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1JvdW5kQ2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUm91bmRDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNmY2Q0NzIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvUm91bmRDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgUm91bmRDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLSAgICBwdWJsaWMgUm91bmRDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlhcmd1bWVudCgpLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKE1BVEhfQ0xBU1MsCi0JCQkJCQkgICAgInJvdW5kIiwgIihEKUoiKSkpOwotCWlsLmFwcGVuZChMMkkpOwkJLy8gbm8gbG9uZyB0eXBlIDotKAotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1NpbXBsZUF0dHJpYnV0ZVZhbHVlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9TaW1wbGVBdHRyaWJ1dGVWYWx1ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjOTYyZmQyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1NpbXBsZUF0dHJpYnV0ZVZhbHVlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci0KLWZpbmFsIGNsYXNzIFNpbXBsZUF0dHJpYnV0ZVZhbHVlIGV4dGVuZHMgQXR0cmlidXRlVmFsdWUgewotICAgIHByaXZhdGUgU3RyaW5nIF92YWx1ZTsKLQkJCi0gICAgcHVibGljIFNpbXBsZUF0dHJpYnV0ZVZhbHVlKFN0cmluZyB2YWx1ZSkgewotCV92YWx1ZSA9IHZhbHVlOwotICAgIH0KLQkJCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlyZXR1cm4gX3R5cGUgPSBUeXBlLlN0cmluZzsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gX3ZhbHVlOwotICAgIH0KLQkKLSAgICBwdWJsaWMgYm9vbGVhbiBjb250ZXh0RGVwZW5kZW50KCkgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF92YWx1ZSkpOwotCWRpc3BsYXkoMCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU29ydC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU29ydC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzY2E1M2JiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1NvcnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUwNCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOwotaW1wb3J0IGphdmEudGV4dC5Db2xsYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5GaWVsZDsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuY2xhc3NmaWxlLk1ldGhvZDsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5Db25zdGFudHM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi0KLWZpbmFsIGNsYXNzIFNvcnQgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIEV4cHJlc3Npb24gICAgIF9zZWxlY3Q7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZSBfb3JkZXI7Ci0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZSBfY2FzZU9yZGVyOwotICAgIHByaXZhdGUgQXR0cmlidXRlVmFsdWUgX2RhdGFUeXBlOwotCi0gICAgcHVibGljICBTdHJpbmcgICAgICAgICBfbGFuZzsKLSAgICBwdWJsaWMgIFN0cmluZyAgICAgICAgIF9jb3VudHJ5OwotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5Db25zdGFudHMuRU1QVFlTVFJJTkc7Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSB0aGUgYXR0cmlidXRlcyBvZiB0aGUgeHNsOnNvcnQgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCS8vIFBhcnNlIHRoZSBzZWxlY3QgZXhwcmVzc2lvbiAobm9kZSBzdHJpbmcgdmFsdWUgaWYgbm8gZXhwcmVzc2lvbikKLQlfc2VsZWN0ID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCAic2VsZWN0IiwgInN0cmluZyguKSIpOwotCi0JLy8gR2V0IHRoZSBzb3J0IG9yZGVyOyBkZWZhdWx0IGlzICdhc2NlbmRpbmcnCi0JU3RyaW5nIHZhbCA9IGdldEF0dHJpYnV0ZSgib3JkZXIiKTsKLQlfb3JkZXIgPSBBdHRyaWJ1dGVWYWx1ZQotCSAgICAuY3JlYXRlKHRoaXMsIHZhbC5sZW5ndGgoKSA+IDAgPyB2YWwgOiAiYXNjZW5kaW5nIiwgcGFyc2VyKTsKLQotCS8vIEdldCB0aGUgY2FzZSBvcmRlcjsgZGVmYXVsdCBpcyBsYW5ndWFnZSBkZXBlbmRhbnQKLQl2YWwgPSBnZXRBdHRyaWJ1dGUoImNhc2Utb3JkZXIiKTsKLQlfY2FzZU9yZGVyID0gQXR0cmlidXRlVmFsdWUKLQkgICAgLmNyZWF0ZSh0aGlzLCB2YWwubGVuZ3RoKCkgPiAwID8gdmFsIDogInVwcGVyLWZpcnN0IiwgcGFyc2VyKTsKLQotCS8vIEdldCB0aGUgc29ydCBkYXRhIHR5cGU7IGRlZmF1bHQgaXMgdGV4dAotCXZhbCA9IGdldEF0dHJpYnV0ZSgiZGF0YS10eXBlIik7Ci0JX2RhdGFUeXBlID0gQXR0cmlidXRlVmFsdWUKLQkgICAgLmNyZWF0ZSh0aGlzLCB2YWwubGVuZ3RoKCkgPiAwID8gdmFsIDogInRleHQiLCBwYXJzZXIpOwotCi0JLy8gR2V0IHRoZSBsYW5ndWFnZSB3aG9zZSBzb3J0IHJ1bGVzIHdlIHdpbGwgdXNlOyBkZWZhdWx0IGlzIGVudi5kZXAuCi0JaWYgKCh2YWwgPSBnZXRBdHRyaWJ1dGUoImxhbmciKSkgIT0gbnVsbCkgewotCSAgICB0cnkgewotCQlTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHZhbCwiLSIsZmFsc2UpOwotCQlfbGFuZyA9IHN0Lm5leHRUb2tlbigpOwotCQlfY291bnRyeSA9IHN0Lm5leHRUb2tlbigpOwotCSAgICB9Ci0JICAgIGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGUpIHsgLy8gaWdub3JlCi0JICAgIH0KLQl9Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIFJ1biB0eXBlIGNoZWNrcyBvbiB0aGUgYXR0cmlidXRlczsgZXhwcmVzc2lvbiBtdXN0IHJldHVybiBhIHN0cmluZwotICAgICAqIHdoaWNoIHdlIHdpbGwgdXNlIGFzIGEgc29ydCBrZXkKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWZpbmFsIFR5cGUgdHNlbGVjdCA9IF9zZWxlY3QudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKHRzZWxlY3QgaW5zdGFuY2VvZiBTdHJpbmdUeXBlID09IGZhbHNlKSB7Ci0JICAgIF9zZWxlY3QgPSBuZXcgQ2FzdEV4cHIoX3NlbGVjdCwgVHlwZS5TdHJpbmcpOwotCX0KLQlfb3JkZXIudHlwZUNoZWNrKHN0YWJsZSk7Ci0JX2Nhc2VPcmRlci50eXBlQ2hlY2soc3RhYmxlKTsKLQlfZGF0YVR5cGUudHlwZUNoZWNrKHN0YWJsZSk7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGVzZSB0d28gbWV0aG9kcyBhcmUgbmVlZGVkIGluIHRoZSBzdGF0aWMgbWV0aG9kcyB0aGF0IGNvbXBpbGUgdGhlCi0gICAgICogb3ZlcmxvYWRlZCBOb2RlU29ydFJlY29yZC5jb21wYXJlVHlwZSgpIGFuZCBOb2RlU29ydFJlY29yZC5zb3J0T3JkZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U29ydFR5cGUoKSB7Ci0JcmV0dXJuIF9kYXRhVHlwZS50b1N0cmluZygpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIGdldFNvcnRPcmRlcigpIHsKLQlyZXR1cm4gX29yZGVyLnRvU3RyaW5nKCk7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGNvbXBpbGVzIGNvZGUgZm9yIHRoZSBzZWxlY3QgZXhwcmVzc2lvbiBmb3IgdGhpcwotICAgICAqIHhzbDpzb3J0IGVsZW1lbnQuIFRoZSBtZXRob2QgaXMgY2FsbGVkIGZyb20gdGhlIHN0YXRpYyBjb2RlLWdlbmVyYXRpbmcKLSAgICAgKiBtZXRob2RzIGluIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlU2VsZWN0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCU1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbixtZXRob2RHZW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgcHJvZHVjZSBhbnkgY29kZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCS8vIGVtcHR5Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgY29kZSB0aGF0IGluc3RhbnRpYXRlcyBhIFNvcnRpbmdJdGVyYXRvciBvYmplY3QuCi0gICAgICogVGhpcyBvYmplY3QncyBjb25zdHJ1Y3RvciBuZWVkcyByZWZlcmVuY2RlcyB0byB0aGUgY3VycmVudCBpdGVyYXRvcgotICAgICAqIGFuZCBhIG5vZGUgc29ydCByZWNvcmQgcHJvZHVjaW5nIG9iamVjdHMgYXMgaXRzIHBhcmFtZXRlcnMuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHRyYW5zbGF0ZVNvcnRJdGVyYXRvcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLAotCQkJCQkgICAgIEV4cHJlc3Npb24gbm9kZVNldCwKLQkJCQkJICAgICBWZWN0b3Igc29ydE9iamVjdHMpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gU29ydGluZ0l0ZXJhdG9yLlNvcnRpbmdJdGVyYXRvcihOb2RlSXRlcmF0b3IsTm9kZVNvcnRSZWNvcmRGYWN0b3J5KTsKLQlmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoU09SVF9JVEVSQVRPUiwgIjxpbml0PiIsCi0JCQkJCSAgIigiCi0JCQkJCSAgKyBOT0RFX0lURVJBVE9SX1NJRwotCQkJCQkgICsgTk9ERV9TT1JUX0ZBQ1RPUllfU0lHCi0JCQkJCSAgKyAiKVYiKTsJCi0KLQlmaW5hbCBpbnQgc2V0U3RhcnROb2RlID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotCQkJCQkJCSAgIFNFVF9TVEFSVF9OT0RFLAotCQkJCQkJCSAgICIoSSkiKwotCQkJCQkJCSAgIE5PREVfSVRFUkFUT1JfU0lHKTsKLQkKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU09SVF9JVEVSQVRPUikpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQotCS8vIEdldCB0aGUgY3VycmVudCBub2RlIGl0ZXJhdG9yCi0JaWYgKG5vZGVTZXQgPT0gbnVsbCkgewkvLyBhcHBseS10ZW1wbGF0ZXMgZGVmYXVsdAotCSAgICBNb2RlLmNvbXBpbGVHZXRDaGlsZHJlbihjbGFzc0dlbiwgbWV0aG9kR2VuLAotCQkJCSAgICBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIG5vZGVTZXQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLG1ldGhvZEdlbi5nZXRMb2NhbEluZGV4KCJjdXJyZW50IikpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uoc2V0U3RhcnROb2RlLDIpKTsKLQl9Ci0JCi0JLy8gQ29tcGlsZSB0aGUgY29kZSBmb3IgdGhlIE5vZGVTb3J0UmVjb3JkIHByb2R1Y2luZyBjbGFzcyBhbmQgcGFzcwotCS8vIHRoYXQgYXMgdGhlIGxhc3QgYXJndW1lbnQgdG8gdGhlIFNvcnRpbmdJdGVyYXRvciBjb25zdHJ1Y3Rvci4KLQljb21waWxlU29ydFJlY29yZEZhY3Rvcnkoc29ydE9iamVjdHMsIGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0KSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBjb2RlIHRoYXQgaW5zdGFudGlhdGVzIGEgTm9kZVNvcnRSZWNvcmRGYWN0b3J5IG9iamVjdCB3aGljaAotICAgICAqIHdpbGwgcHJvZHVjZSBOb2RlU29ydFJlY29yZCBvYmplY3RzIG9mIGEgc3BlY2lmaWMgdHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY29tcGlsZVNvcnRSZWNvcmRGYWN0b3J5KFZlY3RvciBzb3J0T2JqZWN0cywKLQkJCQkJCUNsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCQkJTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JCi0JLy8gTm9kZVNvcnRSZWNvcmRGYWN0b3J5Lk5vZGVTb3J0UmVjb3JkRmFjdG9yeShkb20sY2xhc3MsbGV2ZWxzLHRybGV0KTsKLQlmaW5hbCBTdHJpbmcgaW5pdFBhcmFtcyA9Ci0JICAgICIoIitET01fSU5URl9TSUcrU1RSSU5HX1NJRysgVFJBTlNMRVRfSU5URl9TSUcrIilWIjsKLQlmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoTk9ERV9TT1JUX0ZBQ1RPUlksCi0JCQkJCSAgIjxpbml0PiIsIGluaXRQYXJhbXMpOwotCi0JLy8gQ29tcGlsZSB0aGUgb2JqZWN0IHRoYXQgd2lsbCBlbmNhcHN1bGF0ZSBlYWNoIHNvcnQgb2JqZWN0IChub2RlKS4KLQkvLyBOb2RlU29ydFJlY29yZEZhY3RvcnkgbmVlZHMgdGhlIG5hbWUgb2YgdGhlIG5ldyBjbGFzcy4KLQlTdHJpbmcgY2xhc3NOYW1lID0gY29tcGlsZVNvcnRSZWNvcmQoc29ydE9iamVjdHMsIGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gVGhlIGNvbnN0cnVjdG9yIGZvciB0aGUgTm9kZVNvcnRSZWNvcmQgZ2VuZXJhdGluZyBjbGFzcyB0YWtlcyBubwotCS8vIHBhcmFtZXRlcnMgc28gd2UgbXVzdCB0byBwYXNzIGluaXRpYWxpemF0aW9uIHBhcmFtcyB0byBvdGhlciBtZXRob2RzCi0JaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKE5PREVfU09SVF9GQUNUT1JZKSkpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBjbGFzc05hbWUpKTsKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IGF1eGlsbGFyeSBjbGFzcyBleHRlbmRpbmcgTm9kZVNvcnRSZWNvcmQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNvbXBpbGVTb3J0UmVjb3JkKFZlY3RvciBzb3J0T2JqZWN0cywKLQkJCQkJICAgIENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCQkgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIFhTTFRDICB4c2x0YyA9ICgoU29ydClzb3J0T2JqZWN0cy5maXJzdEVsZW1lbnQoKSkuZ2V0WFNMVEMoKTsKLQlmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0geHNsdGMuZ2V0SGVscGVyQ2xhc3NOYW1lKCk7Ci0KLQkvLyBUaGlzIGdlbmVyYXRlcyBhIG5ldyBjbGFzcyBmb3IgaGFuZGxpbmcgdGhpcyBzcGVjaWZpYyBzb3J0Ci0JZmluYWwgTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3Igc29ydFJlY29yZCA9Ci0JICAgIG5ldyBOb2RlU29ydFJlY29yZEdlbmVyYXRvcihjbGFzc05hbWUsCi0JCQkJCU5PREVfU09SVF9SRUNPUkQsCi0JCQkJCSJzb3J0JDAuamF2YSIsCi0JCQkJCUFDQ19QVUJMSUMgfCBBQ0NfU1VQRVIgfCBBQ0NfRklOQUwsCi0JCQkJCW5ldyBTdHJpbmdbXSB7fSwKLQkJCQkJY2xhc3NHZW4uZ2V0U3R5bGVzaGVldCgpKTsKLQkKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gc29ydFJlY29yZC5nZXRDb25zdGFudFBvb2woKTsJCi0JCi0JTWV0aG9kIGNsaW5pdCA9IGNvbXBpbGVDbGFzc0luaXQoc29ydE9iamVjdHMsIHNvcnRSZWNvcmQsCi0JCQkJCSBjcGcsIGNsYXNzTmFtZSk7Ci0JTWV0aG9kIGV4dHJhY3QgPSBjb21waWxlRXh0cmFjdChzb3J0T2JqZWN0cywgc29ydFJlY29yZCwKLQkJCQkJY3BnLCBjbGFzc05hbWUpOwotCXNvcnRSZWNvcmQuYWRkTWV0aG9kKGNsaW5pdCk7Ci0Jc29ydFJlY29yZC5hZGRFbXB0eUNvbnN0cnVjdG9yKEFDQ19QVUJMSUMpOwotCXNvcnRSZWNvcmQuYWRkTWV0aG9kKGV4dHJhY3QpOwotCi0JLy8gT3ZlcmxvYWQgTm9kZVNvcnRSZWNvcmQuZ2V0Q29sbGF0b3IoKSBvbmx5IGlmIG5lZWRlZAotCWZvciAoaW50IGkgPSAwOyBpIDwgc29ydE9iamVjdHMuc2l6ZSgpOyBpKyspIHsKLQkgICAgaWYgKCgoU29ydCkoc29ydE9iamVjdHMuZWxlbWVudEF0KGkpKSkuX2xhbmcgIT0gbnVsbCkgewotCQlzb3J0UmVjb3JkLmFkZE1ldGhvZChjb21waWxlR2V0Q29sbGF0b3Ioc29ydE9iamVjdHMsCi0JCQkJCQkJc29ydFJlY29yZCwKLQkJCQkJCQljcGcsCi0JCQkJCQkJY2xhc3NOYW1lKSk7Ci0JCWkgPSBzb3J0T2JqZWN0cy5zaXplKCk7Ci0JICAgIH0KLQl9Ci0JCi0JeHNsdGMuZHVtcENsYXNzKHNvcnRSZWNvcmQuZ2V0SmF2YUNsYXNzKCkpOwotCXJldHVybiBjbGFzc05hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgY2xhc3MgY29uc3RydWN0b3IgZm9yIHRoZSBuZXcgY2xhc3MuIEFsbCB0aGlzIGNvbnN0cnVjdG9yIGRvZXMKLSAgICAgKiBpcyB0byBpbml0aWFsaXplIGEgY291cGxlIG9mIHRhYmxlcyB0aGF0IGNvbnRhaW4gaW5mb3JtYXRpb24gb24gc29ydAotICAgICAqIG9yZGVyIGFuZCBzb3J0IHR5cGUuIFRoZXNlIHN0YXRpYyB0YWJsZXMgY2Fubm90IGJlIGluIHRoZSBwYXJlbnQgY2xhc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIGNvbXBpbGVDbGFzc0luaXQoVmVjdG9yIHNvcnRPYmplY3RzLAotCQkJCQkgICBOb2RlU29ydFJlY29yZEdlbmVyYXRvciBzb3J0UmVjb3JkLAotCQkJCQkgICBDb25zdGFudFBvb2xHZW4gY3BnLAotCQkJCQkgICBTdHJpbmcgY2xhc3NOYW1lKSB7Ci0JLy8gQ2xhc3MgaW5pdGlhbGl6ZXIgLSB2b2lkIE5vZGVTb3J0UmVjb3JkLjxjbGluaXQ+KCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIENvbXBhcmVHZW5lcmF0b3IgY2xhc3NJbml0ID0KLQkgICAgbmV3IENvbXBhcmVHZW5lcmF0b3IoQUNDX1BVQkxJQyB8IEFDQ19GSU5BTCwKLQkJCQkgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5WT0lELCAKLQkJCQkgbmV3IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbXSB7IH0sCi0JCQkJIG5ldyBTdHJpbmdbXSB7IH0sCi0JCQkJICI8Y2xpbml0PiIsIGNsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLQlmaW5hbCBpbnQgaW5pdExvY2FsZSA9ICBjcGcuYWRkTWV0aG9kcmVmKCJqYXZhL3V0aWwvTG9jYWxlIiwKLQkJCQkJCSAiPGluaXQ+IiwKLQkJCQkJCSAiKExqYXZhL2xhbmcvU3RyaW5nOyIrCi0JCQkJCQkgIkxqYXZhL2xhbmcvU3RyaW5nOylWIik7Ci0JCi0JZmluYWwgaW50IGdldENvbGxhdG9yID0gY3BnLmFkZE1ldGhvZHJlZihDT0xMQVRPUl9DTEFTUywKLQkJCQkJCSAiZ2V0SW5zdGFuY2UiLAotCQkJCQkJICIoTGphdmEvdXRpbC9Mb2NhbGU7KSIrCi0JCQkJCQkgQ09MTEFUT1JfU0lHKTsKLQotCWZpbmFsIGludCBzZXRTdHJlbmd0aCA9IGNwZy5hZGRNZXRob2RyZWYoQ09MTEFUT1JfQ0xBU1MsCi0JCQkJCQkgInNldFN0cmVuZ3RoIiwgIihJKVYiKTsKLQotCWZpbmFsIGludCBsZXZlbHMgPSBzb3J0T2JqZWN0cy5zaXplKCk7Ci0KLQlmaW5hbCBpbnQgbGV2ZWxzRmllbGQgPSBjcGcuYWRkRmllbGRyZWYoY2xhc3NOYW1lLCAiX2xldmVscyIsICJJIik7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbGV2ZWxzKSk7Ci0JaWwuYXBwZW5kKG5ldyBQVVRTVEFUSUMobGV2ZWxzRmllbGQpKTsKLQotCS8vIENvbXBpbGUgY29kZSB0aGF0IGluaXRpYWxpemVzIHRoZSBzdGF0aWMgX2NvbXBhcmVUeXBlIGFycmF5Ci0JZmluYWwgaW50IGN0eXBlID0gY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSwgIl9jb21wYXJlVHlwZSIsICJbSSIpOwotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsbGV2ZWxzKSk7Ci0JaWwuYXBwZW5kKG5ldyBORVdBUlJBWShkZS5mdWIuYnl0ZWNvZGUuQ29uc3RhbnRzLlRfSU5UKSk7Ci0JZm9yIChpbnQgbGV2ZWwgPSAwOyBsZXZlbCA8IGxldmVsczsgbGV2ZWwrKykgewotCSAgICBmaW5hbCBTb3J0IHNvcnQgPSAoU29ydClzb3J0T2JqZWN0cy5lbGVtZW50QXQobGV2ZWwpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbGV2ZWwpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgc29ydC5nZXRTb3J0VHlwZSgpLmVxdWFscygibnVtYmVyIikKLQkJCSAgICAgICA/IE5vZGVTb3J0UmVjb3JkLkNPTVBBUkVfTlVNRVJJQwotCQkJICAgICAgIDogTm9kZVNvcnRSZWNvcmQuQ09NUEFSRV9TVFJJTkcpKTsKLQkgICAgaWwuYXBwZW5kKElBU1RPUkUpOwotCX0KLQlpbC5hcHBlbmQobmV3IFBVVFNUQVRJQyhjdHlwZSkpOwotCQotCS8vIENvbXBpbGUgY29kZSB0aGF0IGluaXRpYWxpemVzIHRoZSBzdGF0aWMgX3NvcnRPcmRlcgotCWZpbmFsIGludCBjb3JkZXIgPSBjcGcuYWRkRmllbGRyZWYoY2xhc3NOYW1lLCAiX3NvcnRPcmRlciIsICJbSSIpOwotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGxldmVscykpOwotCWlsLmFwcGVuZChuZXcgTkVXQVJSQVkoZGUuZnViLmJ5dGVjb2RlLkNvbnN0YW50cy5UX0lOVCkpOwotCWZvciAoaW50IGxldmVsID0gMDsgbGV2ZWwgPCBsZXZlbHM7IGxldmVsKyspIHsKLQkgICAgZmluYWwgU29ydCBzb3J0ID0gKFNvcnQpc29ydE9iamVjdHMuZWxlbWVudEF0KGxldmVsKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGxldmVsKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIHNvcnQuZ2V0U29ydE9yZGVyKCkuZXF1YWxzKCJkZXNjZW5kaW5nIikKLQkJCSAgICAgICA/IE5vZGVTb3J0UmVjb3JkLkNPTVBBUkVfREVTQ0VORElORwotCQkJICAgICAgIDogTm9kZVNvcnRSZWNvcmQuQ09NUEFSRV9BU0NFTkRJTkcpKTsKLQkgICAgaWwuYXBwZW5kKElBU1RPUkUpOwotCX0KLQlpbC5hcHBlbmQobmV3IFBVVFNUQVRJQyhjb3JkZXIpKTsKLQotCS8vIENvbXBpbGUgY29kZSB0aGF0IGluaXRpYWxpemVzIHRoZSBsb2NhbGUKLQlTdHJpbmcgbGFuZ3VhZ2UgPSBudWxsOwotCVN0cmluZyBjb3VudHJ5ID0gbnVsbDsKLQlTb3J0IHNvcnQgPSAoU29ydClzb3J0T2JqZWN0cy5lbGVtZW50QXQoMCk7Ci0KLQlmb3IgKGludCBsZXZlbCA9IDA7IGxldmVsIDwgbGV2ZWxzOyBsZXZlbCsrKSB7Ci0JICAgIGlmIChsYW5ndWFnZSA9PSBudWxsICYmIHNvcnQuX2xhbmcgIT0gbnVsbCkKLQkJbGFuZ3VhZ2UgPSBzb3J0Ll9sYW5nOwotCSAgICBpZiAoY291bnRyeSA9PSBudWxsICYmIHNvcnQuX2NvdW50cnkgIT0gbnVsbCkKLQkJY291bnRyeSA9IHNvcnQuX2NvdW50cnk7Ci0JfQotCi0JLy8gR2V0IGluZGV4IHRvIHByaXZhdGUgc3RhdGljIHJlZmVyZW5jZSBpbiBOb2RlU29ydFJlY3JkCi0JZmluYWwgaW50IGNvbGxhdG9yID0KLQkgICAgY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSwgIl9jb2xsYXRvciIsIENPTExBVE9SX1NJRyk7Ci0KLQlpZiAobGFuZ3VhZ2UgIT0gbnVsbCkgewotCSAgICAvLyBDcmVhdGUgbmV3IExvY2FsZSBvYmplY3Qgb24gc3RhY2sKLQkgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKCJqYXZhL3V0aWwvTG9jYWxlIikpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGxhbmd1YWdlKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIChjb3VudHJ5ICE9IG51bGwgPyBjb3VudHJ5IDogRU1QVFlTVFJJTkcpKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0TG9jYWxlKSk7Ci0JICAgIAotCSAgICAvLyBVc2UgdGhhdCBMb2NhbGUgb2JqZWN0IHRvIGdldCB0aGUgcmVxdWlyZWQgQ29sbGF0b3Igb2JqZWN0Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGdldENvbGxhdG9yKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVUU1RBVElDKGNvbGxhdG9yKSk7Ci0JfQotCi0JaWwuYXBwZW5kKG5ldyBHRVRTVEFUSUMoY29sbGF0b3IpKTsKLQlpbC5hcHBlbmQobmV3IElDT05TVChDb2xsYXRvci5URVJUSUFSWSkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChzZXRTdHJlbmd0aCkpOwotCi0JaWwuYXBwZW5kKFJFVFVSTik7Ci0KLQljbGFzc0luaXQuc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotCWNsYXNzSW5pdC5zZXRNYXhMb2NhbHMoKTsKLQljbGFzc0luaXQuc2V0TWF4U3RhY2soKTsKLQljbGFzc0luaXQucmVtb3ZlTk9QcygpOwotCi0JcmV0dXJuIGNsYXNzSW5pdC5nZXRNZXRob2QoKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGEgbWV0aG9kIHRoYXQgb3ZlcmxvYWRzIE5vZGVTb3J0UmVjb3JkLmV4dHJhY3RWYWx1ZUZyb21ET00oKQotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIE1ldGhvZCBjb21waWxlRXh0cmFjdChWZWN0b3Igc29ydE9iamVjdHMsCi0JCQkJCSBOb2RlU29ydFJlY29yZEdlbmVyYXRvciBzb3J0UmVjb3JkLAotCQkJCQkgQ29uc3RhbnRQb29sR2VuIGNwZywKLQkJCQkJIFN0cmluZyBjbGFzc05hbWUpIHsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JCi0JLy8gU3RyaW5nIE5vZGVTb3J0UmVjb3JkLmV4dHJhY3RWYWx1ZUZyb21ET00oZG9tLG5vZGUsbGV2ZWwpOwotCWZpbmFsIENvbXBhcmVHZW5lcmF0b3IgZXh0cmFjdE1ldGhvZCA9Ci0JICAgIG5ldyBDb21wYXJlR2VuZXJhdG9yKEFDQ19QVUJMSUMgfCBBQ0NfRklOQUwsCi0JCQkJIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuU1RSSU5HLCAKLQkJCQkgbmV3IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbXSB7Ci0JCSAgICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyksCi0JCQkJICAgICBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLklOVCwKLQkJCQkgICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJCSAgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfU0lHKSwKLQkJCQkgICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5UCi0JCQkJIH0sCi0JCQkJIG5ldyBTdHJpbmdbXSB7ICJkb20iLAotCQkJCQkJImN1cnJlbnQiLAotCQkJCQkJImxldmVsIiwKLQkJCQkJCSJ0cmFuc2xldCIsCi0JCQkJCQkibGFzdCIKLQkJCQkgfSwKLQkJCQkgImV4dHJhY3RWYWx1ZUZyb21ET00iLCBjbGFzc05hbWUsIGlsLCBjcGcpOwotCi0JLy8gVmFsdWVzIG5lZWRlZCBmb3IgdGhlIHN3aXRjaCBzdGF0ZW1lbnQKLQlmaW5hbCBpbnQgbGV2ZWxzID0gc29ydE9iamVjdHMuc2l6ZSgpOwotCWZpbmFsIGludCBtYXRjaFtdID0gbmV3IGludFtsZXZlbHNdOwotCWZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldFtdID0gbmV3IEluc3RydWN0aW9uSGFuZGxlW2xldmVsc107Ci0JSW5zdHJ1Y3Rpb25IYW5kbGUgdGJsc3dpdGNoID0gbnVsbDsKLQotCS8vIENvbXBpbGUgc3dpdGNoIHN0YXRlbWVudCBvbmx5IGlmIHRoZSBrZXkgaGFzIG11bHRpcGxlIGxldmVscwotCWlmIChsZXZlbHMgPiAxKSB7Ci0JICAgIC8vIFB1dCB0aGUgcGFyYW1ldGVyIHRvIHRoZSBzd3RpY2ggc3RhdGVtZW50IG9uIHRoZSBzdGFjawotCSAgICBpbC5hcHBlbmQobmV3IElMT0FEKGV4dHJhY3RNZXRob2QuZ2V0TG9jYWxJbmRleCgibGV2ZWwiKSkpOwotCSAgICAvLyBBcHBlbmQgdGhlIHN3aXRjaCBzdGF0ZW1lbnQgaGVyZSBsYXRlciBvbgotCSAgICB0Ymxzd2l0Y2ggPSBpbC5hcHBlbmQobmV3IE5PUCgpKTsKLQl9Ci0KLQkvLyBBcHBlbmQgYWxsIHRoZSBjYXNlcyBmb3IgdGhlIHN3aXRjaCBzdGF0bWVudAotCWZvciAoaW50IGxldmVsID0gMDsgbGV2ZWwgPCBsZXZlbHM7IGxldmVsKyspIHsKLQkgICAgbWF0Y2hbbGV2ZWxdID0gbGV2ZWw7Ci0JICAgIGZpbmFsIFNvcnQgc29ydCA9IChTb3J0KXNvcnRPYmplY3RzLmVsZW1lbnRBdChsZXZlbCk7Ci0JICAgIHRhcmdldFtsZXZlbF0gPSBpbC5hcHBlbmQoTk9QKTsKLQkgICAgc29ydC50cmFuc2xhdGVTZWxlY3Qoc29ydFJlY29yZCwgZXh0cmFjdE1ldGhvZCk7Ci0JICAgIGlsLmFwcGVuZChBUkVUVVJOKTsKLQl9Ci0JCi0JLy8gQ29tcGlsZSBkZWYuIHRhcmdldCBmb3Igc3dpdGNoIHN0YXRlbWVudCBpZiBrZXkgaGFzIG11bHRpcGxlIGxldmVscwotCWlmIChsZXZlbHMgPiAxKSB7Ci0JICAgIC8vIEFwcGVuZCB0aGUgZGVmYXVsdCB0YXJnZXQgLSBpdCB3aWxsIF9ORVZFUl8gYmUgcmVhY2hlZAotCSAgICBJbnN0cnVjdGlvbkhhbmRsZSBkZWZhdWx0VGFyZ2V0ID0KLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRU1QVFlTVFJJTkcpKTsKLQkgICAgaWwuaW5zZXJ0KHRibHN3aXRjaCxuZXcgVEFCTEVTV0lUQ0gobWF0Y2gsIHRhcmdldCwgZGVmYXVsdFRhcmdldCkpOwotCSAgICBpbC5hcHBlbmQoQVJFVFVSTik7Ci0JfQotCi0JZXh0cmFjdE1ldGhvZC5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0JZXh0cmFjdE1ldGhvZC5zZXRNYXhMb2NhbHMoKTsKLQlleHRyYWN0TWV0aG9kLnNldE1heFN0YWNrKCk7Ci0JZXh0cmFjdE1ldGhvZC5yZW1vdmVOT1BzKCk7Ci0KLQlyZXR1cm4gZXh0cmFjdE1ldGhvZC5nZXRNZXRob2QoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhIG1ldGhvZCB0aGF0IG92ZXJsb2FkcyBOb2RlU29ydFJlY29yZC5nZXRDb2xsYXRvcigpCi0gICAgICogVGhpcyBtZXRob2QgaXMgb25seSBjb21waWxlZCBpZiB0aGUgImxhbmciIGF0dHJpYnV0ZSBpcyB1c2VkLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIE1ldGhvZCBjb21waWxlR2V0Q29sbGF0b3IoVmVjdG9yIHNvcnRPYmplY3RzLAotCQkJCQkgICAgIE5vZGVTb3J0UmVjb3JkR2VuZXJhdG9yIHNvcnRSZWNvcmQsCi0JCQkJCSAgICAgQ29uc3RhbnRQb29sR2VuIGNwZywKLQkJCQkJICAgICBTdHJpbmcgY2xhc3NOYW1lKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCS8vIENvbGxhdG9yIE5vZGVTb3J0UmVjb3JkLmdldENvbGxhdG9yKCk7Ci0JZmluYWwgTWV0aG9kR2VuZXJhdG9yIGdldENvbGxhdG9yID0KLQkgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMLAotCQkJCVV0aWwuZ2V0SkNSZWZUeXBlKENPTExBVE9SX1NJRyksCi0JCQkJbmV3IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbXSB7fSwKLQkJCQluZXcgU3RyaW5nW10geyB9LAotCQkJCSJnZXRDb2xsYXRvciIsIGNsYXNzTmFtZSwgaWwsIGNwZyk7Ci0KLQkvLyBHZXQgaW5kZXggdG8gcHJpdmF0ZSBzdGF0aWMgcmVmZXJlbmNlIGluIE5vZGVTb3J0UmVjcmQKLQlmaW5hbCBpbnQgY29sbGF0b3IgPQotCSAgICBjcGcuYWRkRmllbGRyZWYoY2xhc3NOYW1lLCAiY29sbGF0b3IiLCBDT0xMQVRPUl9TSUcpOwotCS8vIEZlY2sgdGhlIENvbGxhdG9yIG9iamVjdCBvbiB0aGUgc3RhY2sgYW5kIHJldHVybiBpdAotCWlsLmFwcGVuZChuZXcgR0VUU1RBVElDKGNvbGxhdG9yKSk7Ci0JaWwuYXBwZW5kKEFSRVRVUk4pOwotCi0JZ2V0Q29sbGF0b3Iuc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotCWdldENvbGxhdG9yLnNldE1heExvY2FscygpOwotCWdldENvbGxhdG9yLnNldE1heFN0YWNrKCk7Ci0JZ2V0Q29sbGF0b3IucmVtb3ZlTk9QcygpOwotCi0JcmV0dXJuIGdldENvbGxhdG9yLmdldE1ldGhvZCgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1NvdXJjZUxvYWRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU291cmNlTG9hZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI1NGYzMWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU291cmNlTG9hZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYWt0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotCi1wdWJsaWMgaW50ZXJmYWNlIFNvdXJjZUxvYWRlciB7Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGludGVyZmFjZSBpcyB1c2VkIHRvIHBsdWcgZXh0ZXJuYWwgZG9jdW1lbnQgbG9hZGVycyBpbnRvIFhTTFRDCi0gICAgICogKHVzZWQgd2l0aCB0aGUgPHhzbDppbmNsdWRlPiBhbmQgPHhzbDppbXBvcnQ+IGVsZW1lbnRzLgotICAgICAqCi0gICAgICogQHBhcmFtIGhyZWYgVGhlIFVSSSBvZiB0aGUgZG9jdW1lbnQgdG8gbG9hZAotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBVUkkgb2YgdGhlIGN1cnJlbnRseSBsb2FkZWQgZG9jdW1lbnQKLSAgICAgKiBAcGFyYW0geHNsdGMgVGhlIGNvbXBpbGVyIHRoYXQgcmVzdWVzdHMgdGhlIGRvY3VtZW50Ci0gICAgICogQHJldHVybiBBbiBJbnB1dFNvdXJjZSB3aXRoIHRoZSBsb2FkZWQgZG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5wdXRTb3VyY2UgbG9hZFNvdXJjZShTdHJpbmcgaHJlZiwgU3RyaW5nIGNvbnRleHQsIFhTTFRDIHhzbHRjKTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU3RhcnRzV2l0aENhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0YXJ0c1dpdGhDYWxsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAzMzc2YmEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU3RhcnRzV2l0aENhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFN0YXJ0c1dpdGhDYWxsIGV4dGVuZHMgRnVuY3Rpb25DYWxsIHsKLQotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfYmFzZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF90b2tlbiA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBzdGFydHMtd2l0aCgpIGNhbGwgLSB0d28gYXJndW1lbnRzLCBib3RoIHN0cmluZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RhcnRzV2l0aENhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIHRoZSB0d28gcGFyYW1ldGVycyBmb3IgdGhpcyBmdW5jdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLQkvLyBDaGVjayB0aGF0IHRoZSBmdW5jdGlvbiB3YXMgcGFzc2VkIGV4YWN0bHkgdHdvIGFyZ3VtZW50cwotCWlmIChhcmd1bWVudENvdW50KCkgIT0gMikgewotCSAgICB0aHJvdyBuZXcgVHlwZUNoZWNrRXJyb3IoRXJyb3JNc2cuRlVOUkVTT0xfRVJSLCBnZXROYW1lKCkpOwotCX0KLQotCS8vIFRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgU3RyaW5nLCBvciBjYXN0IHRvIGEgU3RyaW5nCi0JX2Jhc2UgPSBhcmd1bWVudCgwKTsKLQlUeXBlIGJhc2VUeXBlID0gX2Jhc2UudHlwZUNoZWNrKHN0YWJsZSk7CQotCWlmIChiYXNlVHlwZSAhPSBUeXBlLlN0cmluZykKLQkgICAgX2Jhc2UgPSBuZXcgQ2FzdEV4cHIoX2Jhc2UsIFR5cGUuU3RyaW5nKTsKLQotCS8vIFRoZSBzZWNvbmQgYXJndW1lbnQgbXVzdCBhbHNvIGJlIGEgU3RyaW5nLCBvciBjYXN0IHRvIGEgU3RyaW5nCi0JX3Rva2VuID0gYXJndW1lbnQoMSk7Ci0JVHlwZSB0b2tlblR5cGUgPSBfdG9rZW4udHlwZUNoZWNrKHN0YWJsZSk7CQotCWlmICh0b2tlblR5cGUgIT0gVHlwZS5TdHJpbmcpCi0JICAgIF90b2tlbiA9IG5ldyBDYXN0RXhwcihfdG9rZW4sIFR5cGUuU3RyaW5nKTsKLQotCXJldHVybiBfdHlwZSA9IFR5cGUuQm9vbGVhbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIHRoZSBleHByZXNzaW9uIC0gbGVhdmUgYm9vbGVhbiBleHByZXNzaW9uIG9uIHN0YWNrCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlfYmFzZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JX3Rva2VuLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfQ0xBU1MsCi0JCQkJCQkgICAgICJzdGFydHNXaXRoIiwgCi0JCQkJCQkgICAgICIoIitTVFJJTkdfU0lHKyIpWiIpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU3RlcC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU3RlcC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMjQzMjMxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0ZXAuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ4MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkF4aXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci0KLWZpbmFsIGNsYXNzIFN0ZXAgZXh0ZW5kcyBSZWxhdGl2ZUxvY2F0aW9uUGF0aCB7Ci0KLSAgICAvLyBUaGlzIHN0ZXAncyBheGlzIGFzIGRlZmluZWQgaW4gY2xhc3MgQXhpcy4KLSAgICBwcml2YXRlIGludCBfYXhpczsKLQotICAgIC8vIEEgdmVjdG9yIG9mIHByZWRpY2F0ZXMgKGZpbHRlcnMpIGRlZmluZWQgb24gdGhpcyBzdGVwLgotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9wcmVkaWNhdGVzOyAJLy8gbWF5IGJlIG51bGwKLQotICAgIC8vIFR5cGUgb2YgdGhlIG5vZGUgdGVzdC4KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX2hhZFByZWRpY2F0ZXMgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIFN0ZXAoaW50IGF4aXMsIGludCBub2RlVHlwZSwgVmVjdG9yIHByZWRpY2F0ZXMpIHsKLQlfYXhpcyA9IGF4aXM7Ci0JX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0JX3ByZWRpY2F0ZXMgPSBwcmVkaWNhdGVzOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBwYXJzZXIgZm9yIHRoaXMgZWxlbWVudCBhbmQgYWxsIGNoaWxkIHByZWRpY2F0ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotCXN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotCWlmIChfcHJlZGljYXRlcyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCQlmaW5hbCBQcmVkaWNhdGUgZXhwID0gKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0JCWV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLQkJZXhwLnNldFBhcmVudCh0aGlzKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAKLSAgICAvKioKLSAgICAgKiBEZWZpbmUgdGhlIGF4aXMgKGRlZmluZWQgaW4gQXhpcyBjbGFzcykgZm9yIHRoaXMgc3RlcAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0QXhpcygpIHsKLQlyZXR1cm4gX2F4aXM7Ci0gICAgfQotCi0JCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBheGlzIChkZWZpbmVkIGluIEF4aXMgY2xhc3MpIGZvciB0aGlzIHN0ZXAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRBeGlzKGludCBheGlzKSB7Ci0JX2F4aXMgPSBheGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGRlc2NlbmRhbnRBeGlzKCkgewotCWlmICgoX2F4aXMgPT0gQXhpcy5ERVNDRU5EQU5UKSB8fCAoX2F4aXMgPT0gQXhpcy5ERVNDRU5EQU5UT1JTRUxGKSkKLQkgICAgcmV0dXJuKHRydWUpOwotCWVsc2UKLQkgICAgcmV0dXJuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NlbGYoKSB7Ci0JcmV0dXJuIChfYXhpcyA9PSBBeGlzLlNFTEYpOwotICAgIH0KLQkKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub2RlLXR5cGUgZm9yIHRoaXMgc3RlcAotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Tm9kZVR5cGUoKSB7Ci0JcmV0dXJuIF9ub2RlVHlwZTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHZlY3RvciBjb250YWluaW5nIGFsbCBwcmVkaWNhdGVzIGZvciB0aGlzIHN0ZXAuCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBnZXRQcmVkaWNhdGVzKCkgewotCXJldHVybiBfcHJlZGljYXRlczsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0UGFyZW50KFN5bnRheFRyZWVOb2RlIG5vZGUpIHsKLQlfcGFyZW50ID0gbm9kZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zICd0cnVlJyBpZiB0aGlzIHN0ZXAgaGFzIGEgcGFyZW50IHBhdHRlcm4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXJlbnQoKSB7Ci0JU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gZ2V0UGFyZW50KCk7Ci0JaWYgKChwYXJlbnQgaW5zdGFuY2VvZiBQYXJlbnRQYXR0ZXJuKSB8fAotCSAgICAocGFyZW50IGluc3RhbmNlb2YgUGFyZW50TG9jYXRpb25QYXRoKSB8fAotCSAgICAocGFyZW50IGluc3RhbmNlb2YgVW5pb25QYXRoRXhwcikgfHwKLQkgICAgKHBhcmVudCBpbnN0YW5jZW9mIEZpbHRlclBhcmVudFBhdGgpKQotCSAgICByZXR1cm4odHJ1ZSk7Ci0JZWxzZQotCSAgICByZXR1cm4oZmFsc2UpOwotICAgIH0KLQotICAgIAotICAgIC8qKgotICAgICAqIFJldHVybnMgJ3RydWUnIGlmIHRoaXMgc3RlcCBoYXMgYW55IHByZWRpY2F0ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmVkaWNhdGVzKCkgewotCXJldHVybiBfcHJlZGljYXRlcyAhPSBudWxsICYmIF9wcmVkaWNhdGVzLnNpemUoKSA+IDA7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgc3RlcCBpcyB0aGUgYWJicmV2aWF0ZWQgc3RlcCAnLicKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0FiYnJldmlhdGVkRG90KCkgewotCXJldHVybiBfbm9kZVR5cGUgPT0gTm9kZVRlc3QuQU5PREUgJiYgX2F4aXMgPT0gQXhpcy5TRUxGOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiB0aGlzIHN0ZXAgaXMgdGhlIGFiYnJldmlhdGVkIHN0ZXAgJy4uJwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzQWJicmV2aWF0ZWRERG90KCkgewotCXJldHVybiBfbm9kZVR5cGUgPT0gTm9kZVRlc3QuQU5PREUgJiYgX2F4aXMgPT0gQXhpcy5QQVJFTlQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayB0aGlzIHN0ZXAuIFRoZSBhYmJyZXZpYXRlZCBzdGVwcyAnLicgYW5kICdAYXR0cicgYXJlCi0gICAgICogYXNzaWduZWQgdHlwZSBub2RlIGlmIHRoZXkgaGF2ZSBubyBwcmVkaWNhdGVzLiBBbGwgb3RoZXIgc3RlcHMgCi0gICAgICogaGF2ZSB0eXBlIG5vZGUtc2V0LgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JX2hhZFByZWRpY2F0ZXMgPSBoYXNQcmVkaWNhdGVzKCk7Ci0KLQlpZiAoaXNBYmJyZXZpYXRlZERvdCgpKSB7Ci0JICAgIF90eXBlID0gVHlwZS5Ob2RlOwotCX0KLQllbHNlIGlmIChpc0FiYnJldmlhdGVkRERvdCgpKSB7Ci0JICAgIF90eXBlID0gVHlwZS5Ob2RlU2V0OwotCX0KLQllbHNlIHsKLQkgICAgLy8gU3BlY2lhbCBjYXNlIGZvciAnQGF0dHInIHdpdGggbm8gcGFyZW50IG9yIHByZWRpY2F0ZXMKLQkgICAgaWYgKF9heGlzID09IEF4aXMuQVRUUklCVVRFCi0JCSYmIF9ub2RlVHlwZSAhPSBOb2RlVGVzdC5BVFRSSUJVVEUKLQkJJiYgIWhhc1BhcmVudCgpCi0JCSYmICFoYXNQcmVkaWNhdGVzKCkpIHsKLQkJX3R5cGUgPSBUeXBlLk5vZGU7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCV90eXBlID0gVHlwZS5Ob2RlU2V0OwotCSAgICB9Ci0JfQotCWlmIChfcHJlZGljYXRlcyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCQlmaW5hbCBFeHByZXNzaW9uIHByZWQgPSAoRXhwcmVzc2lvbilfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0JCXByZWQudHlwZUNoZWNrKHN0YWJsZSk7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIF90eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSBhIHN0ZXAgYnkgcHVzaGluZyB0aGUgYXBwcm9wcmlhdGUgaXRlcmF0b3Igb250byB0aGUgc3RhY2suCi0gICAgICogVGhlIGFiYnJldmlhdGVkIHN0ZXBzICcuJyBhbmQgJ0BhdHRyJyBkbyBub3QgY3JlYXRlIG5ldyBpdGVyYXRvcnMKLSAgICAgKiBpZiB0aGV5IGFyZSBub3QgcGFydCBvZiBhIExvY2F0aW9uUGF0aCBhbmQgaGF2ZSBubyBmaWx0ZXJzLgotICAgICAqIEluIHRoZXNlIGNhc2VzIGEgbm9kZSBpbmRleCBpbnN0ZWFkIG9mIGFuIGl0ZXJhdG9yIGlzIHB1c2hlZAotICAgICAqIG9udG8gdGhlIHN0YWNrLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlpZiAoaGFzUHJlZGljYXRlcygpKSB7Ci0JICAgIHRyYW5zbGF0ZVByZWRpY2F0ZXMoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCWVsc2UgewotCSAgICAvLyBJZiBpdCBpcyBhbiBhdHRyaWJ1dGUgYnV0IG5vdCAnQConIG9yICdAYXR0cicgd2l0aCBhIHBhcmVudAotCSAgICBpZiAoKF9heGlzID09IEF4aXMuQVRUUklCVVRFKSAmJgotCQkoX25vZGVUeXBlICE9IE5vZGVUZXN0LkFUVFJJQlVURSkgJiYgKCFoYXNQYXJlbnQoKSkpIHsKLQkJaW50IG5vZGUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAiZ2V0QXR0cmlidXRlTm9kZSIsCi0JCQkJCQkgICAgICIoSUkpSSIpOwotCQlpbnQgaXRlciA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgICJnZXRUeXBlZEF4aXNJdGVyYXRvciIsCi0JCQkJCQkgICAgICIoSUkpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0JCWlmIChfdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB7Ci0JCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbm9kZVR5cGUpKTsKLQkJICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uobm9kZSwgMykpOwotCQl9Ci0JCS8vIElmIGl0IGlzIHRoZSBjYXNlICdAYXR0cltQXzFdLi4uW1Bfa10nCi0JCWVsc2UgaWYgKF90eXBlIGluc3RhbmNlb2YgTm9kZVNldFR5cGUpIHsKLQkJICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkJICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIEF4aXMuQVRUUklCVVRFKSk7Ci0JCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbm9kZVR5cGUpKTsKLQkJICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGl0ZXIsIDMpKTsKLQkJfQotCQlyZXR1cm47Ci0JICAgIH0KLQotCSAgICAvLyBTcGVjaWFsIGNhc2UgZm9yICcuJwotCSAgICBpZiAoX3R5cGUgPT0gVHlwZS5Ob2RlKSB7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCQlyZXR1cm47Ci0JICAgIH0KLQotCSAgICAvLyAiRUxFTUVOVCIgb3IgIioiIG9yICJAKiIgb3IgIi4uIiBvciAiQGF0dHIiIHdpdGggYSBwYXJlbnQuCi0JICAgIHN3aXRjaCAoX25vZGVUeXBlKSB7Ci0JICAgIGNhc2UgTm9kZVRlc3QuQVRUUklCVVRFOgotCQlfYXhpcyA9IEF4aXMuQVRUUklCVVRFOwotCSAgICBjYXNlIE5vZGVUZXN0LkFOT0RFOgotCQkvLyBET00uZ2V0QXhpc0l0ZXJhdG9yKGludCBheGlzKTsKLQkJaW50IGdpdCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgImdldEF4aXNJdGVyYXRvciIsCi0JCQkJCQkgICAgIihJKSIrTk9ERV9JVEVSQVRPUl9TSUcpOwotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9heGlzKSk7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGdpdCwgMikpOwotCQlicmVhazsKLQkgICAgZGVmYXVsdDoKLQkJZmluYWwgWFNMVEMgeHNsdGMgPSBnZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotCQlmaW5hbCBWZWN0b3IgbmkgPSB4c2x0Yy5nZXROYW1lc0luZGV4KCk7Ci0JCVN0cmluZyBuYW1lID0gbnVsbDsKLQkJaW50IHN0YXIgPSAwOwotCQkKLQkJaWYgKF9ub2RlVHlwZSA+PSBET00uTlRZUEVTKSB7Ci0JCSAgICBuYW1lID0gKFN0cmluZyluaS5lbGVtZW50QXQoX25vZGVUeXBlLURPTS5OVFlQRVMpOwotCQkgICAgc3RhciA9IG5hbWUubGFzdEluZGV4T2YoJyonKTsKLQkJfQotCQkKLQkJaWYgKHN0YXIgPiAxKSB7Ci0JCSAgICBmaW5hbCBTdHJpbmcgbmFtZXNwYWNlOwotCQkgICAgaWYgKF9heGlzID09IEF4aXMuQVRUUklCVVRFKQotCQkJbmFtZXNwYWNlID0gbmFtZS5zdWJzdHJpbmcoMCxzdGFyLTIpOwotCQkgICAgZWxzZQotCQkJbmFtZXNwYWNlID0gbmFtZS5zdWJzdHJpbmcoMCxzdGFyLTEpOwotCi0JCSAgICBmaW5hbCBpbnQgbnNUeXBlID0geHNsdGMucmVnaXN0ZXJOYW1lc3BhY2UobmFtZXNwYWNlKTsKLQkJICAgIGZpbmFsIGludCBucyA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgImdldE5hbWVzcGFjZUF4aXNJdGVyYXRvciIsCi0JCQkJCQkgICAgIihJSSkiK05PREVfSVRFUkFUT1JfU0lHKTsKLQkJICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkJICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9heGlzKSk7Ci0JCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBuc1R5cGUpKTsKLQkJICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKG5zLCAzKSk7Ci0JCSAgICBicmVhazsKLQkJfQotCSAgICBjYXNlIE5vZGVUZXN0LkVMRU1FTlQ6Ci0JCS8vIERPTS5nZXRUeXBlZEF4aXNJdGVyYXRvcihpbnQgYXhpcywgaW50IHR5cGUpOwotCQlmaW5hbCBpbnQgdHkgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJImdldFR5cGVkQXhpc0l0ZXJhdG9yIiwKLQkJCQkJCSIoSUkpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0JCS8vIEdldCB0aGUgdHlwZWQgaXRlcmF0b3Igd2UncmUgYWZ0ZXIKLQkJaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfYXhpcykpOwotCQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfbm9kZVR5cGUpKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UodHksIDMpKTsKLQkJICAgIAotCQkvLyBOb3csIGZvciByZXZlcnNlIGl0ZXJhdG9ycyB3ZSBtYXkgbmVlZCB0byByZS1hcnJhbmdlIHRoZQotCQkvLyBub2RlIG9yZGVyaW5nIChhbmNlc3Rvci10eXBlIGl0ZXJhdG9ycykuCi0JCWlmICghKGdldFBhcmVudCgpIGluc3RhbmNlb2YgRm9yRWFjaCkpIHsKLQkJICAgIGlmICgoIWhhc1BhcmVudCgpKSAmJiAoIV9oYWRQcmVkaWNhdGVzKSkKLQkJCW9yZGVySXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCX0KLQkJYnJlYWs7Ci0JICAgIH0KLQl9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgYSBzZXF1ZW5jZSBvZiBwcmVkaWNhdGVzLiBFYWNoIHByZWRpY2F0ZSBpcyB0cmFuc2xhdGVkCi0gICAgICogYnkgY29uc3RydWN0aW5nIGFuIGluc3RhbmNlIG9mIDxjb2RlPkN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yPC9jb2RlPgotICAgICAqIHdoaWNoIGlzIGluaXRpYWxpemVkIGZyb20gYW5vdGhlciBpdGVyYXRvciAocmVjdXJzaXZlIGNhbGwpLAotICAgICAqIGEgZmlsdGVyIGFuZCBhIGNsb3N1cmUgKGNhbGwgdG8gdHJhbnNsYXRlIG9uIHRoZSBwcmVkaWNhdGUpIGFuZCAidGhpcyIuIAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVByZWRpY2F0ZXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaWYgKF9wcmVkaWNhdGVzLnNpemUoKSA9PSAwKSB7Ci0JICAgIHRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGZpbmFsIFByZWRpY2F0ZSBwcmVkaWNhdGUgPSAoUHJlZGljYXRlKV9wcmVkaWNhdGVzLmxhc3RFbGVtZW50KCk7Ci0JICAgIF9wcmVkaWNhdGVzLnJlbW92ZShwcmVkaWNhdGUpOwotCi0JICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgcHJlZGljYXRlcyB0aGF0IGNhbiB1c2UgdGhlIE5vZGVWYWx1ZUl0ZXJhdG9yCi0JICAgIC8vIGluc3RlYWQgb2YgYW4gYXV4aWxpYXJ5IGNsYXNzLiBDZXJ0YWluIHBhdGgvcHJlZGljYXRlcyBwYWlycwotCSAgICAvLyBhcmUgdHJhbnNsYXRlZCBpbnRvIGEgYmFzZSBwYXRoLCBvbiB0b3Agb2Ygd2hpY2ggd2UgcGxhY2UgYQotCSAgICAvLyBub2RlIHZhbHVlIGl0ZXJhdG9yIHRoYXQgdGVzdHMgZm9yIHRoZSBkZXNpcmVkIHZhbHVlOgotCSAgICAvLyAgIGZvb1tAYXR0ciA9ICdzdHInXSAgLT4gIGZvby9AYXR0ciArIHRlc3QodmFsdWU9J3N0cicpCi0JICAgIC8vICAgZm9vW2JhciA9ICdzdHInXSAgICAtPiAgZm9vL2JhciArIHRlc3QodmFsdWU9J3N0cicpCi0JICAgIC8vICAgZm9vL2JhclsuID0gJ3N0ciddICAtPiAgZm9vL2JhciArIHRlc3QodmFsdWU9J3N0cicpCi0JICAgIGlmIChwcmVkaWNhdGUuaXNOb2RlVmFsdWVUZXN0KCkpIHsKLQkJU3RlcCBzdGVwID0gcHJlZGljYXRlLmdldFN0ZXAoKTsKLQotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JCS8vIElmIHRoZSBwcmVkaWNhdGUncyBTdGVwIGlzIHNpbXBseSAnLicgd2UgdHJhbnNsYXRlIHRoaXMgU3RlcAotCQkvLyBhbmQgcGxhY2UgdGhlIG5vZGUgdGVzdCBvbiB0b3Agb2YgdGhlIHJlc3VsdGluZyBpdGVyYXRvcgotCQlpZiAoc3RlcC5pc0FiYnJldmlhdGVkRG90KCkpIHsKLQkJICAgIHRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJfQotCQkvLyBPdGhlcndpc2Ugd2UgY3JlYXRlIGEgcGFyZW50IGxvY2F0aW9uIHBhdGggd2l0aCB0aGlzIFN0ZXAgYW5kCi0JCS8vIHRoZSBwcmVkaWNhdGVzIFN0ZXAsIGFuZCBwbGFjZSB0aGUgbm9kZSB0ZXN0IG9uIHRvcCBvZiB0aGF0Ci0JCWVsc2UgewotCQkgICAgUGFyZW50TG9jYXRpb25QYXRoIHBhdGggPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKHRoaXMsc3RlcCk7Ci0JCSAgICB0cnkgewotCQkJcGF0aC50eXBlQ2hlY2soZ2V0UGFyc2VyKCkuZ2V0U3ltYm9sVGFibGUoKSk7Ci0JCSAgICB9Ci0JCSAgICBjYXRjaCAoVHlwZUNoZWNrRXJyb3IgZSkgeyB9Ci0JCSAgICBwYXRoLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJfQotCQlwcmVkaWNhdGUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQlpbnQgaXRlciA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCSAgICAgR0VUX05PREVfVkFMVUVfSVRFUkFUT1IsCi0JCQkJCSAgICAgR0VUX05PREVfVkFMVUVfSVRFUkFUT1JfU0lHKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaXRlciwgNCkpOwotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSAnLy8qW25dJyBleHByZXNzaW9uCi0JICAgIGVsc2UgaWYgKHByZWRpY2F0ZS5pc050aERlc2NlbmRhbnQoKSkgewotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZENvbnRleHROb2RlKCkpOwotCQlwcmVkaWNhdGUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCQlpbnQgaXRlciA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICAgICJnZXROdGhEZXNjZW5kYW50IiwKLQkJCQkJCSAgICAgIihJSSkiK05PREVfSVRFUkFUT1JfU0lHKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaXRlciwgMykpOwotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSAnZWxlbVtuXScgZXhwcmVzc2lvbgotCSAgICBlbHNlIGlmIChwcmVkaWNhdGUuaXNOdGhQb3NpdGlvbkZpbHRlcigpKSB7Ci0JCWZpbmFsIGludCBpbml0TkkgPQotCQkgICAgY3BnLmFkZE1ldGhvZHJlZihOVEhfSVRFUkFUT1JfQ0xBU1MsCi0JCQkJICAgICAiPGluaXQ+IiwKLQkJCQkgICAgICIoIiArIE5PREVfSVRFUkFUT1JfU0lHICsgIkkpViIpOwotCQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoTlRIX0lURVJBVE9SX0NMQVNTKSkpOwotCQlpbC5hcHBlbmQoRFVQKTsKLQkJdHJhbnNsYXRlUHJlZGljYXRlcyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsgLy8gcmVjdXJzaXZlIGNhbGwKLQkJcHJlZGljYXRlLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXROSSkpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoQ1VSUkVOVF9OT0RFX0xJU1RfSVRFUkFUT1IsCi0JCQkJCQkgICI8aW5pdD4iLAotCQkJCQkJICAiKCIKLQkJCQkJCSAgKyBOT0RFX0lURVJBVE9SX1NJRwotCQkJCQkJICArIENVUlJFTlRfTk9ERV9MSVNUX0ZJTFRFUl9TSUcKLQkJCQkJCSAgKyBOT0RFX1NJRwotCQkJCQkJICArIFRSQU5TTEVUX1NJRwotCQkJCQkJICArICIpViIpOwotCQkvLyBjcmVhdGUgbmV3IEN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yCi0JCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhDVVJSRU5UX05PREVfTElTVF9JVEVSQVRPUikpKTsKLQkJaWwuYXBwZW5kKERVUCk7Ci0JCXRyYW5zbGF0ZVByZWRpY2F0ZXMoY2xhc3NHZW4sIG1ldGhvZEdlbik7IC8vIHJlY3Vyc2l2ZSBjYWxsCi0JCXByZWRpY2F0ZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCQotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkJaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkJaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotCQkgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotCQkgICAgaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzTmFtZSkpKTsKLQkJfQotCQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5pdCkpOwotCSAgICB9Ci0JfQotICAgIH0KLQotCi0gICAgLyoKLSAgICAgKiBPcmRlciBub2RlcyBmb3IgaXRlcmF0b3JzIHdpdGggcmV2ZXJzZSBheGlzCi0gICAgICoKLSAgICAgKiBTaG91bGQgYmUgZG9uZSBmb3IgcHJlY2VkaW5nIGFuZCBwcmVjZWRpbmctc2libGluZyBheGlzIGFzIHdlbGwsCi0gICAgICogYnV0IG91ciBpdGVyYXRvcnMgZm9yIHRob3NlIGF4aXMgYXJlIG5vdCByZXZlcnNlIChhcyB0aGV5IHNob3VsZCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBvcmRlckl0ZXJhdG9yKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlpZiAoKF9heGlzID09IEF4aXMuQU5DRVNUT1IpIHx8IChfYXhpcyA9PSBBeGlzLkFOQ0VTVE9ST1JTRUxGKSkgewotCSAgICBmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoUkVWRVJTRV9JVEVSQVRPUiwgIjxpbml0PiIsCi0JCQkJCSAgICAgICIoIitOT0RFX0lURVJBVE9SX1NJRysiKVYiKTsKLQotCSAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoUkVWRVJTRV9JVEVSQVRPUikpKTsKLQkgICAgaWwuYXBwZW5kKERVUF9YMSk7Ci0JICAgIGlsLmFwcGVuZChTV0FQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXQpKTsKLQl9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc3RlcC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCWZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCJzdGVwKFwiIik7Ci0JYnVmZmVyLmFwcGVuZChBeGlzLm5hbWVzW19heGlzXSkuYXBwZW5kKCJcIiwgIikuYXBwZW5kKF9ub2RlVHlwZSk7Ci0JaWYgKF9wcmVkaWNhdGVzICE9IG51bGwpIHsKLQkgICAgZmluYWwgaW50IG4gPSBfcHJlZGljYXRlcy5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCWZpbmFsIFByZWRpY2F0ZSBwcmVkID0gKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0JCWJ1ZmZlci5hcHBlbmQoIiwgIikuYXBwZW5kKHByZWQudG9TdHJpbmcoKSk7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIGJ1ZmZlci5hcHBlbmQoJyknKS50b1N0cmluZygpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0ZXBQYXR0ZXJuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9TdGVwUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwODVmMWEzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0ZXBQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NTYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkF4aXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuY2xhc3NmaWxlLkZpZWxkOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFN0ZXBQYXR0ZXJuIGV4dGVuZHMgUmVsYXRpdmVQYXRoUGF0dGVybiB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTk9fQ09OVEVYVCA9IDA7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJTVBMRV9DT05URVhUID0gMTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgR0VORVJBTF9DT05URVhUID0gMjsKLQotICAgIHByaXZhdGUgZmluYWwgaW50ICAgIF9heGlzOwotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9wcmVkaWNhdGVzOwotICAgIHByaXZhdGUgZmluYWwgaW50ICAgIF9ub2RlVHlwZTsKLQotICAgIHByaXZhdGUgU3RlcCAgICBfc3RlcCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pc0Vwc2lsb24gPSBmYWxzZTsKLSAgICBwcml2YXRlIGludCAgICAgX2NvbnRleHRDYXNlOwotCi0gICAgcHVibGljIFN0ZXBQYXR0ZXJuKGludCBheGlzLCBpbnQgbm9kZVR5cGUsIFZlY3RvciBwcmVkaWNhdGVzKSB7Ci0JX2F4aXMgPSBheGlzOwotCV9ub2RlVHlwZSA9IG5vZGVUeXBlOwotCV9wcmVkaWNhdGVzID0gcHJlZGljYXRlczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotCXN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotCWlmIChfcHJlZGljYXRlcyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCQlmaW5hbCBQcmVkaWNhdGUgZXhwID0gKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0JCWV4cC5zZXRQYXJzZXIocGFyc2VyKTsKLQkJZXhwLnNldFBhcmVudCh0aGlzKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldE5vZGVUeXBlKCkgewotCXJldHVybiBfbm9kZVR5cGU7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBTdGVwUGF0dGVybiBnZXRLZXJuZWxQYXR0ZXJuKCkgewotCXJldHVybiB0aGlzOwotICAgIH0KLQkKLSAgICBwdWJsaWMgYm9vbGVhbiBpc1dpbGRjYXJkKCkgewotCXJldHVybiBfaXNFcHNpbG9uICYmIGhhc1ByZWRpY2F0ZXMoKSA9PSBmYWxzZTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGJvb2xlYW4gaGFzUHJlZGljYXRlcygpIHsKLQlyZXR1cm4gX3ByZWRpY2F0ZXMgIT0gbnVsbCAmJiBfcHJlZGljYXRlcy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIHB1YmxpYyBkb3VibGUgZ2V0RGVmYXVsdFByaW9yaXR5KCkgewotCWlmIChoYXNQcmVkaWNhdGVzKCkpIHsKLQkgICAgcmV0dXJuIDAuNTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHN3aXRjaChfbm9kZVR5cGUpIHsKLQkgICAgY2FzZSAtMToKLQkJcmV0dXJuKC0wLjI1KTsKLQkgICAgY2FzZSAwOgotCQlyZXR1cm4oMC4wKTsKLQkgICAgZGVmYXVsdDoKLQkJaWYgKF9ub2RlVHlwZSA+PSBOb2RlVGVzdC5HVFlQRSkKLQkJICAgIHJldHVybigwLjApOwotCQllbHNlCi0JCSAgICByZXR1cm4oLTAuNSk7Ci0JICAgIH0KLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHJlZHVjZUtlcm5lbFBhdHRlcm4oKSB7Ci0JX2lzRXBzaWxvbiA9IHRydWU7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoInN0ZXBQYXR0ZXJuKFwiIik7Ci0JYnVmZmVyLmFwcGVuZChBeGlzLm5hbWVzW19heGlzXSkKLQkgICAgLmFwcGVuZCgiXCIsICIpCi0JICAgIC5hcHBlbmQoX2lzRXBzaWxvbiA/ICJlcHNpbG9uIiA6IEludGVnZXIudG9TdHJpbmcoX25vZGVUeXBlKSk7Ci0JaWYgKF9wcmVkaWNhdGVzICE9IG51bGwpCi0JICAgIGJ1ZmZlci5hcHBlbmQoIiwgIikuYXBwZW5kKF9wcmVkaWNhdGVzLnRvU3RyaW5nKCkpOwotCXJldHVybiBidWZmZXIuYXBwZW5kKCcpJykudG9TdHJpbmcoKTsKLSAgICB9Ci0gICAgCi0gICAgcHJpdmF0ZSBpbnQgYW5hbHl6ZUNhc2VzKCkgewotCWJvb2xlYW4gbm9Db250ZXh0ID0gdHJ1ZTsKLQlmaW5hbCBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG4gJiYgbm9Db250ZXh0OyBpKyspIHsKLQkgICAgZmluYWwgUHJlZGljYXRlIGV4cCA9IChQcmVkaWNhdGUpX3ByZWRpY2F0ZXMuZWxlbWVudEF0KGkpOwotCSAgICBpZiAoZXhwLmlzTnRoUG9zaXRpb25GaWx0ZXIoKSkKLQkJbm9Db250ZXh0ID0gZmFsc2U7Ci0JfQotCi0JaWYgKG5vQ29udGV4dCkgewotCSAgICByZXR1cm4gTk9fQ09OVEVYVDsKLQl9Ci0JZWxzZSBpZiAobiA9PSAxKSB7Ci0JICAgIHJldHVybiBTSU1QTEVfQ09OVEVYVDsKLQl9Ci0JcmV0dXJuIEdFTkVSQUxfQ09OVEVYVDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyBnZXROZXh0RmllbGROYW1lKCkgewotCXJldHVybiAgIl9fc3RlcF9wYXR0ZXJuX2l0ZXJfIiArIGdldFhTTFRDKCkubmV4dFN0ZXBQYXR0ZXJuU2VyaWFsKCk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoaGFzUHJlZGljYXRlcygpKSB7Ci0JICAgIC8vIFR5cGUgY2hlY2sgYWxsIHRoZSBwcmVkaWNhdGVzIChlIC0+IHBvc2l0aW9uKCkgPSBlKQotCSAgICBmaW5hbCBpbnQgbiA9IF9wcmVkaWNhdGVzLnNpemUoKTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkJZmluYWwgUHJlZGljYXRlIHByZWQgPSAoUHJlZGljYXRlKV9wcmVkaWNhdGVzLmVsZW1lbnRBdChpKTsKLQkJcHJlZC50eXBlQ2hlY2soc3RhYmxlKTsKLQkgICAgfQotCi0JICAgIC8vIEFuYWx5emUgY29udGV4dCBjYXNlcwotCSAgICBfY29udGV4dENhc2UgPSBhbmFseXplQ2FzZXMoKTsKLQotCSAgICAvLyBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgU3RlcCB0byBkbyB0aGUgdHJhbnNsYXRpb24KLQkgICAgaWYgKF9jb250ZXh0Q2FzZSA9PSBTSU1QTEVfQ09OVEVYVCkgewotCQlfc3RlcCA9IG5ldyBTdGVwKF9heGlzLCBfbm9kZVR5cGUsIG51bGwpOwotCQlfc3RlcC50eXBlQ2hlY2soc3RhYmxlKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChfY29udGV4dENhc2UgPT0gR0VORVJBTF9DT05URVhUKSB7Ci0JCV9zdGVwID0gbmV3IFN0ZXAoX2F4aXMsIF9ub2RlVHlwZSwgX3ByZWRpY2F0ZXMpOwotCQlfc3RlcC50eXBlQ2hlY2soc3RhYmxlKTsKLQkgICAgfQotCX0KLQlyZXR1cm4gX2F4aXMgPT0gQXhpcy5DSElMRCA/IFR5cGUuRWxlbWVudCA6IFR5cGUuQXR0cmlidXRlOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0cmFuc2xhdGVLZXJuZWwoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIAotCQkJCSBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQkKLQkvLyBjb250ZXh0IG5vZGUgaXMgb24gdGhlIHN0YWNrCi0JZmluYWwgaW50IGdldFR5cGUgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAgImdldFR5cGUiLCAiKEkpSSIpOwotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQoU1dBUCk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ2V0VHlwZSwgMikpOwotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIF9ub2RlVHlwZSkpOwotCQotCS8vIE5lZWQgdG8gYWxsb3cgZm9yIGxvbmcganVtcHMgaGVyZSAtIGRvbid0IGtub3cgaWYgMTAwJSBjb3JyZWN0Ci0JLy9fZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGX0lDTVBORShudWxsKSkpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSBpY21wID0gaWwuYXBwZW5kKG5ldyBJRl9JQ01QRVEobnVsbCkpOwotCV9mYWxzZUxpc3QuYWRkKGlsLmFwcGVuZChuZXcgR09UT19XKG51bGwpKSk7Ci0JaWNtcC5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCB0cmFuc2xhdGVOb0NvbnRleHQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIAotCQkJCSAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCS8vIFB1c2ggY3VycmVudCBub2RlIG9uIHRoZSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEN1cnJlbnROb2RlKCkpOwotCWlsLmFwcGVuZChTV0FQKTsKLQotCS8vIE92ZXJ3cml0ZSBjdXJyZW50IG5vZGUgd2l0aCBtYXRjaGluZyBub2RlCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotCi0JLy8gSWYgcGF0dGVybiBub3QgcmVkdWNlZCB0aGVuIGNoZWNrIGtlcm5lbAotCWlmICghX2lzRXBzaWxvbikgewotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQkgICAgdHJhbnNsYXRlS2VybmVsKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQotCS8vIENvbXBpbGUgdGhlIGV4cHJlc3Npb25zIHdpdGhpbiB0aGUgcHJlZGljYXRlcwotCWZpbmFsIGludCBuID0gX3ByZWRpY2F0ZXMuc2l6ZSgpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JICAgIGZpbmFsIFByZWRpY2F0ZSBwcmVkID0gKFByZWRpY2F0ZSlfcHJlZGljYXRlcy5lbGVtZW50QXQoaSk7Ci0JICAgIGZpbmFsIEV4cHJlc3Npb24gZXhwID0gcHJlZC5nZXRFeHByKCk7Ci0JICAgIGV4cC50cmFuc2xhdGVEZXN5bnRoZXNpemVkKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfdHJ1ZUxpc3QuYXBwZW5kKGV4cC5fdHJ1ZUxpc3QpOwotCSAgICBfZmFsc2VMaXN0LmFwcGVuZChleHAuX2ZhbHNlTGlzdCk7Ci0JfQotCi0JLy8gQmFja3BhdGNoIHRydWUgbGlzdCBhbmQgcmVzdG9yZSBjdXJyZW50IGl0ZXJhdG9yL25vZGUKLQlJbnN0cnVjdGlvbkhhbmRsZSByZXN0b3JlOwotCXJlc3RvcmUgPSBpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0JYmFja1BhdGNoVHJ1ZUxpc3QocmVzdG9yZSk7Ci0JQnJhbmNoSGFuZGxlIHNraXBGYWxzZSA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0KLQkvLyBCYWNrcGF0Y2ggZmFsc2UgbGlzdCBhbmQgcmVzdG9yZSBjdXJyZW50IGl0ZXJhdG9yL25vZGUKLQlyZXN0b3JlID0gaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUN1cnJlbnROb2RlKCkpOwotCWJhY2tQYXRjaEZhbHNlTGlzdChyZXN0b3JlKTsKLQlfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpKTsKLQotCS8vIFRydWUgbGlzdCBmYWxscyB0aHJvdWdoCi0Jc2tpcEZhbHNlLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRyYW5zbGF0ZVNpbXBsZUNvbnRleHQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIAotCQkJCQlNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JaW50IGluZGV4OwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBTdG9yZSBtYXRjaGluZyBub2RlIGludG8gYSBsb2NhbCB2YXJpYWJsZQotCUxvY2FsVmFyaWFibGVHZW4gbWF0Y2g7Ci0JbWF0Y2ggPSBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgic3RlcF9wYXR0ZXJuX3RtcDEiLCAKLQkJCQkJICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9TSUcpLAotCQkJCQkgICBpbC5nZXRFbmQoKSwgbnVsbCk7Ci0JaWwuYXBwZW5kKG5ldyBJU1RPUkUobWF0Y2guZ2V0SW5kZXgoKSkpOwotCi0JLy8gSWYgcGF0dGVybiBub3QgcmVkdWNlZCB0aGVuIGNoZWNrIGtlcm5lbAotCWlmICghX2lzRXBzaWxvbikgewotCSAgICBpbC5hcHBlbmQobmV3IElMT0FEKG1hdGNoLmdldEluZGV4KCkpKTsKLSAJICAgIHRyYW5zbGF0ZUtlcm5lbChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0KLQkvLyBQdXNoIGN1cnJlbnQgaXRlcmF0b3IgYW5kIGN1cnJlbnQgbm9kZSBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQotCS8vIENyZWF0ZSBhIG5ldyBtYXRjaGluZyBpdGVyYXRvciB1c2luZyB0aGUgbWF0Y2hpbmcgbm9kZQotCWluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihNQVRDSElOR19JVEVSQVRPUiwgIjxpbml0PiIsIAotCQkJCSAiKEkiICsgTk9ERV9JVEVSQVRPUl9TSUcgKyAiKVYiKTsKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoTUFUQ0hJTkdfSVRFUkFUT1IpKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKG5ldyBJTE9BRChtYXRjaC5nZXRJbmRleCgpKSk7Ci0JX3N0ZXAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbmRleCkpOwotCi0JLy8gR2V0IHRoZSBwYXJlbnQgb2YgdGhlIG1hdGNoaW5nIG5vZGUKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTE9BRChtYXRjaC5nZXRJbmRleCgpKSk7Ci0JaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLCBHRVRfUEFSRU5ULCBHRVRfUEFSRU5UX1NJRyk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQotCS8vIFN0YXJ0IHRoZSBpdGVyYXRvciB3aXRoIHRoZSBwYXJlbnQgCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zZXRTdGFydE5vZGUoKSk7Ci0KLQkvLyBPdmVyd3JpdGUgY3VycmVudCBpdGVyYXRvciBhbmQgY3VycmVudCBub2RlCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUl0ZXJhdG9yKCkpOwotCWlsLmFwcGVuZChuZXcgSUxPQUQobWF0Y2guZ2V0SW5kZXgoKSkpOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVDdXJyZW50Tm9kZSgpKTsKLQotCS8vIFRyYW5zbGF0ZSB0aGUgZXhwcmVzc2lvbiBvZiB0aGUgcHJlZGljYXRlIAotCWZpbmFsIFByZWRpY2F0ZSBwcmVkID0gKFByZWRpY2F0ZSkgX3ByZWRpY2F0ZXMuZWxlbWVudEF0KDApOwotCWZpbmFsIEV4cHJlc3Npb24gZXhwID0gcHJlZC5nZXRFeHByKCk7Ci0JZXhwLnRyYW5zbGF0ZURlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0KLQkvLyBCYWNrcGF0Y2ggdHJ1ZSBsaXN0IGFuZCByZXN0b3JlIGN1cnJlbnQgaXRlcmF0b3Ivbm9kZQotCUluc3RydWN0aW9uSGFuZGxlIHJlc3RvcmU7Ci0JcmVzdG9yZSA9IGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0JZXhwLmJhY2tQYXRjaFRydWVMaXN0KHJlc3RvcmUpOwotCUJyYW5jaEhhbmRsZSBza2lwRmFsc2UgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCi0JLy8gQmFja3BhdGNoIGZhbHNlIGxpc3QgYW5kIHJlc3RvcmUgY3VycmVudCBpdGVyYXRvci9ub2RlCi0JcmVzdG9yZSA9IGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVJdGVyYXRvcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlQ3VycmVudE5vZGUoKSk7Ci0JZXhwLmJhY2tQYXRjaEZhbHNlTGlzdChyZXN0b3JlKTsKLQlfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpKTsKLQotCS8vIFRydWUgbGlzdCBmYWxscyB0aHJvdWdoCi0Jc2tpcEZhbHNlLnNldFRhcmdldChpbC5hcHBlbmQoTk9QKSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHRyYW5zbGF0ZUdlbmVyYWxDb250ZXh0KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCAKLQkJCQkJIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaW50IGl0ZXJhdG9ySW5kZXggPSAwOwotCUJyYW5jaEhhbmRsZSBpZkJsb2NrID0gbnVsbDsKLQlMb2NhbFZhcmlhYmxlR2VuIGl0ZXIsIG5vZGUsIG5vZGUyOwotCWZpbmFsIFN0cmluZyBpdGVyYXRvck5hbWUgPSBnZXROZXh0RmllbGROYW1lKCk7Ci0KLQkvLyBTdG9yZSBub2RlIG9uIHRoZSBzdGFjayBpbnRvIGEgbG9jYWwgdmFyaWFibGUKLQlub2RlID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfcGF0dGVybl90bXAxIiwgCi0JCQkJCSAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9TSUcpLAotCQkJCQkgIGlsLmdldEVuZCgpLCBudWxsKTsKLQlpbC5hcHBlbmQobmV3IElTVE9SRShub2RlLmdldEluZGV4KCkpKTsKLQotCS8vIENyZWF0ZSBhIG5ldyBsb2NhbCB0byBzdG9yZSB0aGUgaXRlcmF0b3IKLQlpdGVyID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfcGF0dGVybl90bXAyIiwgCi0JCQkJCSAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpLAotCQkJCQkgIGlsLmdldEVuZCgpLCBudWxsKTsKLQotCS8vIEFkZCBhIG5ldyBwcml2YXRlIGZpZWxkIGlmIHRoaXMgaXMgdGhlIG1haW4gY2xhc3MKLQlpZiAoIWNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotCSAgICBmaW5hbCBGaWVsZCBpdGVyYXRvciA9Ci0JCW5ldyBGaWVsZChBQ0NfUFJJVkFURSwgCi0JCQkgIGNwZy5hZGRVdGY4KGl0ZXJhdG9yTmFtZSksCi0JCQkgIGNwZy5hZGRVdGY4KE5PREVfSVRFUkFUT1JfU0lHKSwKLQkJCSAgbnVsbCwgY3BnLmdldENvbnN0YW50UG9vbCgpKTsKLQkgICAgY2xhc3NHZW4uYWRkRmllbGQoaXRlcmF0b3IpOwotCSAgICBpdGVyYXRvckluZGV4ID0gY3BnLmFkZEZpZWxkcmVmKGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLCAKLQkJCQkJICAgIGl0ZXJhdG9yTmFtZSwKLQkJCQkJICAgIE5PREVfSVRFUkFUT1JfU0lHKTsKLQotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGl0ZXJhdG9ySW5kZXgpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKGl0ZXIuZ2V0SW5kZXgoKSkpOwotCSAgICBpZkJsb2NrID0gaWwuYXBwZW5kKG5ldyBJRk5PTk5VTEwobnVsbCkpOwotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCX0JCi0KLQkvLyBDb21waWxlIHRoZSBzdGVwIGNyZWF0ZWQgYXQgdHlwZSBjaGVja2luZyB0aW1lCi0JX3N0ZXAudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChuZXcgQVNUT1JFKGl0ZXIuZ2V0SW5kZXgoKSkpOwotCi0JLy8gSWYgaW4gdGhlIG1haW4gY2xhc3MgdXBkYXRlIHRoZSBmaWVsZCB0b28KLQlpZiAoIWNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotCSAgICBpbC5hcHBlbmQobmV3IEFMT0FEKGl0ZXIuZ2V0SW5kZXgoKSkpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGl0ZXJhdG9ySW5kZXgpKTsKLQkgICAgaWZCbG9jay5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotCX0KLQotCS8vIEdldCB0aGUgcGFyZW50IG9mIHRoZSBub2RlIG9uIHRoZSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbC5hcHBlbmQobmV3IElMT0FEKG5vZGUuZ2V0SW5kZXgoKSkpOwotCWludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCSAgICAgIEdFVF9QQVJFTlQsIEdFVF9QQVJFTlRfU0lHKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMikpOwotCi0JLy8gSW5pdGlhbGl6ZSB0aGUgaXRlcmF0b3Igd2l0aCB0aGUgcGFyZW50Ci0JaWwuYXBwZW5kKG5ldyBBTE9BRChpdGVyLmdldEluZGV4KCkpKTsKLQlpbC5hcHBlbmQoU1dBUCk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zZXRTdGFydE5vZGUoKSk7Ci0KLQkvKiAKLQkgKiBJbmxpbmUgbG9vcDoKLQkgKgotCSAqIGludCBub2RlMjsKLQkgKiB3aGlsZSAoKG5vZGUyID0gaXRlci5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQgCi0JICoJCSAgJiYgbm9kZTIgPCBub2RlKTsKLQkgKiByZXR1cm4gbm9kZTIgPT0gbm9kZTsgCi0JICovCi0JQnJhbmNoSGFuZGxlIHNraXBOZXh0OwotCUluc3RydWN0aW9uSGFuZGxlIGJlZ2luLCBuZXh0OwotCW5vZGUyID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUoInN0ZXBfcGF0dGVybl90bXAzIiwgCi0JCQkJCSAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfU0lHKSwKLQkJCQkJICAgaWwuZ2V0RW5kKCksIG51bGwpOwotCi0Jc2tpcE5leHQgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCW5leHQgPSBpbC5hcHBlbmQobmV3IEFMT0FEKGl0ZXIuZ2V0SW5kZXgoKSkpOwotCWJlZ2luID0gaWwuYXBwZW5kKG1ldGhvZEdlbi5uZXh0Tm9kZSgpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobmV3IElTVE9SRShub2RlMi5nZXRJbmRleCgpKSk7Ci0JX2ZhbHNlTGlzdC5hZGQoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7CS8vIE5vZGVJdGVyYXRvci5FTkQKLQotCWlsLmFwcGVuZChuZXcgSUxPQUQobm9kZTIuZ2V0SW5kZXgoKSkpOwotCWlsLmFwcGVuZChuZXcgSUxPQUQobm9kZS5nZXRJbmRleCgpKSk7Ci0JaWwuYXBwZW5kKG5ldyBJRl9JQ01QTFQobmV4dCkpOwotCi0JaWwuYXBwZW5kKG5ldyBJTE9BRChub2RlMi5nZXRJbmRleCgpKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTE9BRChub2RlLmdldEluZGV4KCkpKTsKLQlfZmFsc2VMaXN0LmFkZChpbC5hcHBlbmQobmV3IElGX0lDTVBORShudWxsKSkpOwotCi0Jc2tpcE5leHQuc2V0VGFyZ2V0KGJlZ2luKTsKLSAgICB9Ci0JCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlmIChoYXNQcmVkaWNhdGVzKCkpIHsKLQkgICAgc3dpdGNoIChfY29udGV4dENhc2UpIHsKLQkgICAgY2FzZSBOT19DT05URVhUOgotCQl0cmFuc2xhdGVOb0NvbnRleHQoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCWJyZWFrOwotCQkKLQkgICAgY2FzZSBTSU1QTEVfQ09OVEVYVDoKLQkJdHJhbnNsYXRlU2ltcGxlQ29udGV4dChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJYnJlYWs7Ci0JCQotCSAgICBkZWZhdWx0OgotCQl0cmFuc2xhdGVHZW5lcmFsQ29udGV4dChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkJYnJlYWs7Ci0JICAgIH0KLQl9Ci0JZWxzZSBpZiAoaXNXaWxkY2FyZCgpKSB7Ci0JICAgIGlsLmFwcGVuZChQT1ApOyAJLy8gdHJ1ZSBsaXN0IGZhbGxzIHRocm91Z2gKLQl9Ci0JZWxzZSB7Ci0JICAgIHRyYW5zbGF0ZUtlcm5lbChjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU3RyaW5nQ2FsbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvU3RyaW5nQ2FsbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMmFjNDVmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0cmluZ0NhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgU3RyaW5nQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHVibGljIFN0cmluZ0NhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWZpbmFsIGludCBhcmdjID0gYXJndW1lbnRDb3VudCgpOwotCWlmIChhcmdjID4gMSkgewotCSAgICBmaW5hbCBTdHJpbmcgZXJybXNnID0KLQkJIlRoZSBzdHJpbmcoKSBmdW5jdGlvbiBjYW5ub3QgdGFrZSBtb3JlIHRoYW4gb25lIHBhcmFtZXRlciI7Ci0JICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihuZXcgRXJyb3JNc2coZXJybXNnKSk7Ci0JfQotCi0JaWYgKGFyZ2MgPiAwKSB7Ci0JICAgIGFyZ3VtZW50KCkudHlwZUNoZWNrKHN0YWJsZSk7Ci0JfQotCXJldHVybiBfdHlwZSA9IFR5cGUuU3RyaW5nOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlUeXBlIHRhcmc7Ci0KLQlpZiAoYXJndW1lbnRDb3VudCgpID09IDApIHsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JICAgIHRhcmcgPSBUeXBlLk5vZGU7Ci0JfQotCWVsc2UgewotCSAgICBmaW5hbCBFeHByZXNzaW9uIGFyZyA9IGFyZ3VtZW50KCk7Ci0JICAgIGFyZy50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGFyZy5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIHRhcmcgPSBhcmcuZ2V0VHlwZSgpOwotCX0KLQotCWlmICghdGFyZy5pZGVudGljYWxUbyhUeXBlLlN0cmluZykpIHsKLQkgICAgdGFyZy50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0cmluZ0xlbmd0aENhbGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0cmluZ0xlbmd0aENhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTExODBhYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9TdHJpbmdMZW5ndGhDYWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgU3RyaW5nTGVuZ3RoQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHVibGljIFN0cmluZ0xlbmd0aENhbGwoUU5hbWUgZm5hbWUsIFZlY3RvciBhcmd1bWVudHMpIHsKLQlzdXBlcihmbmFtZSwgYXJndW1lbnRzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlmIChhcmd1bWVudENvdW50KCkgPiAwKSB7Ci0JICAgIGFyZ3VtZW50KCkudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQllbHNlIHsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ29udGV4dE5vZGUoKSk7Ci0JICAgIFR5cGUuTm9kZS50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0JfQotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19DTEFTUywKLQkJCQkJCSAgICAgImxlbmd0aCIsICIoKUkiKSkpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0eWxlc2hlZXQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N0eWxlc2hlZXQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTM5NTBkNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9TdHlsZXNoZWV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OTcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWFrdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuTWV0aG9kR2VuZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5DbGFzc0dlbmVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZUNoZWNrRXJyb3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5VdGlsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBTdHlsZXNoZWV0IGV4dGVuZHMgU3ludGF4VHJlZU5vZGUgewotCi0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICAgX3ZlcnNpb247Ci0gICAgcHJpdmF0ZSBRTmFtZSAgICAgICAgX25hbWU7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgICAgX3N5c3RlbUlkOwotICAgIHByaXZhdGUgU3R5bGVzaGVldCAgIF9wYXJlbnRTdHlsZXNoZWV0OwotCQotICAgIC8vIENvbnRhaW5zIGdsb2JhbCB2YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMgZGVmaW5lZCBpbiB0aGUgc3R5bGVzaGVldAotICAgIHByaXZhdGUgZmluYWwgVmVjdG9yIF9nbG9iYWxzID0gbmV3IFZlY3RvcigpOwotCi0gICAgLy8gVXNlZCB0byBjYWNoZSB0aGUgcmVzdWx0IHJldHVybmVkIGJ5IDxjb2RlPmhhc0xvY2FsUGFyYW1zKCk8L2NvZGU+LgotICAgIHByaXZhdGUgQm9vbGVhbiBfaGFzTG9jYWxQYXJhbXMgPSBudWxsOwotCi0gICAgLy8gIFRoZSBuYW1lIG9mIHRoZSBjbGFzcyBiZWluZyBnZW5lcmF0ZWQuCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2NsYXNzTmFtZTsKLSAgICAKLSAgICAvLyBDb250YWlucyBhbGwgdGVtcGxhdGVzIGRlZGluZWQgaW4gdGhpcyBzdHlsZXNoZWV0Ci0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgX3RlbXBsYXRlcyA9IG5ldyBWZWN0b3IoKTsKLQotICAgIHByaXZhdGUgaW50IF9uZXh0TW9kZVNlcmlhbCA9IDE7Ci0gICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgX21vZGVzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF9leHRlbnNpb25zID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgcHJpdmF0ZSBpbnQgX2ltcG9ydFByZWNlZGVuY2UgPSAxOwotICAgIHByaXZhdGUgTW9kZSBfZGVmYXVsdE1vZGU7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9tdWx0aURvY3VtZW50ID0gZmFsc2U7Ci0KLSAgICAvLyBBbGwgbmFtZWQga2V5IGVsZW1lbnRzIChuZWVkZWQgYnkgS2V5L0lkUGF0dGVybikKLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfa2V5cyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIHByaXZhdGUgYm9vbGVhbiBfbnVtYmVyRm9ybWF0dGluZ1VzZWQgPSBmYWxzZTsKLQotICAgIHByaXZhdGUgYm9vbGVhbiBfc2ltcGxpZmllZCA9IGZhbHNlOwotCi0gICAgcHJpdmF0ZSBTb3VyY2VMb2FkZXIgX2xvYWRlciA9IG51bGw7Ci0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU2ltcGxpZmllZCgpIHsKLQlyZXR1cm4oX3NpbXBsaWZpZWQpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFNpbXBsaWZpZWQoKSB7Ci0JX3NpbXBsaWZpZWQgPSB0cnVlOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aURvY3VtZW50KGJvb2xlYW4gZmxhZykgewkKLQlfbXVsdGlEb2N1bWVudCA9IGZsYWc7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNNdWx0aURPTSgpIHsKLQlyZXR1cm4gX211bHRpRG9jdW1lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNJbXBvcnRlZCgpIHsKLQlmaW5hbCBTeW50YXhUcmVlTm9kZSBwYXJlbnQgPSBnZXRQYXJlbnQoKTsKLQlyZXR1cm4gKChwYXJlbnQgIT0gbnVsbCkgJiYgKHBhcmVudCBpbnN0YW5jZW9mIEltcG9ydCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzSW5jbHVkZWQoKSB7Ci0JZmluYWwgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gZ2V0UGFyZW50KCk7Ci0JcmV0dXJuICgocGFyZW50ICE9IG51bGwpICYmIChwYXJlbnQgaW5zdGFuY2VvZiBJbmNsdWRlKSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgbnVtYmVyRm9ybWF0dGluZ1VzZWQoKSB7Ci0JX251bWJlckZvcm1hdHRpbmdVc2VkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRJbXBvcnRQcmVjZWRlbmNlKGZpbmFsIGludCBwcmVjZWRlbmNlKSB7Ci0JX2ltcG9ydFByZWNlZGVuY2UgPSBwcmVjZWRlbmNlOwotCi0JZmluYWwgRW51bWVyYXRpb24gZWxlbWVudHMgPSBlbGVtZW50cygpOwotCXdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBUb3BMZXZlbEVsZW1lbnQgY2hpbGQgPQotCQkoVG9wTGV2ZWxFbGVtZW50KWVsZW1lbnRzLm5leHRFbGVtZW50KCk7Ci0JICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIEluY2x1ZGUpIHsKLQkJU3R5bGVzaGVldCBpbmNsdWRlZCA9ICgoSW5jbHVkZSljaGlsZCkuZ2V0SW5jbHVkZWRTdHlsZXNoZWV0KCk7Ci0JCWlmIChpbmNsdWRlZCAhPSBudWxsKSB7Ci0JCSAgICBpbmNsdWRlZC5zZXRJbXBvcnRQcmVjZWRlbmNlKHByZWNlZGVuY2UpOwotCQl9Ci0JICAgIH0KLQl9Ci0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGludCBnZXRJbXBvcnRQcmVjZWRlbmNlKCkgewotCXJldHVybiBfaW1wb3J0UHJlY2VkZW5jZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBjaGVja0Zvckxvb3AoU3RyaW5nIHN5c3RlbUlkKSB7Ci0JLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBzdHlsZXNoZWV0IGluY2x1ZGVzL2ltcG9ydHMgaXRzZWxmCi0JaWYgKF9zeXN0ZW1JZC5lcXVhbHMoc3lzdGVtSWQpKQotCSAgICByZXR1cm4gdHJ1ZTsKLQkvLyBUaGVuIGNoZWNrIHdpdGggYW55IHN0eWxlc2hlZXRzIHRoYXQgaW5jbHVkZWQvaW1wb3J0ZWQgdGhpcyBvbmUKLQlpZiAoX3BhcmVudFN0eWxlc2hlZXQgIT0gbnVsbCkgCi0JICAgIHJldHVybiBfcGFyZW50U3R5bGVzaGVldC5jaGVja0Zvckxvb3Aoc3lzdGVtSWQpOwotCS8vIE90aGVyd2lzZSBPSwotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlzdXBlci5zZXRQYXJzZXIocGFyc2VyKTsKLQlfbmFtZSA9IG1ha2VTdHlsZXNoZWV0TmFtZSgiX19zdHlsZXNoZWV0XyIpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJlbnRTdHlsZXNoZWV0KFN0eWxlc2hlZXQgcGFyZW50KSB7Ci0JX3BhcmVudFN0eWxlc2hlZXQgPSBwYXJlbnQ7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBTdHlsZXNoZWV0IGdldFBhcmVudFN0eWxlc2hlZXQoKSB7Ci0JcmV0dXJuIF9wYXJlbnRTdHlsZXNoZWV0OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkKFN0cmluZyBzeXN0ZW1JZCkgewotCV9zeXN0ZW1JZCA9IHN5c3RlbUlkOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgewotCXJldHVybiBfc3lzdGVtSWQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0U291cmNlTG9hZGVyKFNvdXJjZUxvYWRlciBsb2FkZXIpIHsKLQlfbG9hZGVyID0gbG9hZGVyOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU291cmNlTG9hZGVyIGdldFNvdXJjZUxvYWRlcigpIHsKLQlyZXR1cm4gX2xvYWRlcjsKLSAgICB9Ci0KLSAgICBwcml2YXRlIFFOYW1lIG1ha2VTdHlsZXNoZWV0TmFtZShTdHJpbmcgcHJlZml4KSB7Ci0JcmV0dXJuIGdldFBhcnNlcigpLmdldFFOYW1lKHByZWZpeCtnZXRYU0xUQygpLm5leHRTdHlsZXNoZWV0U2VyaWFsKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHN0eWxlc2hlZXQgaGFzIGdsb2JhbCB2YXJzIG9yIHBhcmFtcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNHbG9iYWxzKCkgewotCXJldHVybiBfZ2xvYmFscy5zaXplKCkgPiAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgdGVtcGxhdGUgaW4gdGhlIHN0eWxlc2hlZXQgaGFzIHBhcmFtcwotICAgICAqIGRlZmluZWQuIFVzZXMgdGhlIHZhcmlhYmxlIDxjb2RlPl9oYXNMb2NhbFBhcmFtczwvY29kZT4gdG8gY2FjaGUgdGhlCi0gICAgICogcmVzdWx0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGhhc0xvY2FsUGFyYW1zKCkgewotCWlmIChfaGFzTG9jYWxQYXJhbXMgPT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgbiA9IF90ZW1wbGF0ZXMuc2l6ZSgpOwotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCQlmaW5hbCBUZW1wbGF0ZSB0ZW1wbGF0ZSA9IChUZW1wbGF0ZSlfdGVtcGxhdGVzLmVsZW1lbnRBdChpKTsKLQkJaWYgKHRlbXBsYXRlLmhhc1BhcmFtcygpKSB7Ci0JCSAgICBfaGFzTG9jYWxQYXJhbXMgPSBuZXcgQm9vbGVhbih0cnVlKTsKLQkJICAgIHJldHVybiB0cnVlOwotCQl9Ci0JICAgIH0KLQkgICAgX2hhc0xvY2FsUGFyYW1zID0gbmV3IEJvb2xlYW4oZmFsc2UpOwotCSAgICByZXR1cm4gZmFsc2U7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4gX2hhc0xvY2FsUGFyYW1zLmJvb2xlYW5WYWx1ZSgpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdG9yZSBleHRlbnNpb24gVVJJcwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBleHRlbnNpb25VUkkoU3RyaW5nIHByZWZpeGVzLCBTeW1ib2xUYWJsZSBzdGFibGUpIHsKLQlpZiAocHJlZml4ZXMgIT0gbnVsbCkgewotCSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihwcmVmaXhlcyk7Ci0JICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7Ci0JCWZpbmFsIFN0cmluZyBwcmVmaXggPSB0b2tlbnMubmV4dFRva2VuKCk7Ci0JCWZpbmFsIFN0cmluZyB1cmkgPSBsb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLQkJaWYgKHVyaSAhPSBudWxsKSB7Ci0JCSAgICBfZXh0ZW5zaW9ucy5wdXQodXJpLCBwcmVmaXgpOwotCQl9Ci0JICAgIH0KLQl9Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeHRlbnNpb24oU3RyaW5nIHVyaSkgewotCXJldHVybiAoX2V4dGVuc2lvbnMuZ2V0KHVyaSkgIT0gbnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZXhjbHVkZUV4dGVuc2lvblByZWZpeGVzKFBhcnNlciBwYXJzZXIpIHsKLQlmaW5hbCBTeW1ib2xUYWJsZSBzdGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLSAgICAJZmluYWwgU3RyaW5nIGV4Y2x1ZGVQcmVmaXhlcyA9IGdldEF0dHJpYnV0ZSgiZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMiKTsKLQlmaW5hbCBTdHJpbmcgZXh0ZW5zaW9uUHJlZml4ZXMgPSAKLQkgICAgZ2V0QXR0cmlidXRlKCJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIpOwotCXN0YWJsZS5leGNsdWRlTmFtZXNwYWNlcyhleGNsdWRlUHJlZml4ZXMpOwotCXN0YWJsZS5leGNsdWRlTmFtZXNwYWNlcyhleHRlbnNpb25QcmVmaXhlcyk7Ci0JZXh0ZW5zaW9uVVJJKGV4dGVuc2lvblByZWZpeGVzLCBzdGFibGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSB2ZXJzaW9uIGFuZCB1cmkgZmllbGRzIG9mIHRoZSBzdHlsZXNoZWV0IGFuZCBhZGQgYW4KLSAgICAgKiBlbnRyeSB0byB0aGUgc3ltYm9sIHRhYmxlIG1hcHBpbmcgdGhlIG5hbWUgPHR0Pl9fc3R5bGVzaGVldF88L3R0PgotICAgICAqIHRvIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JZmluYWwgU3ltYm9sVGFibGUgc3RhYmxlID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCk7Ci0KLQlfdmVyc2lvbiA9IGdldEF0dHJpYnV0ZSgidmVyc2lvbiIpOwotCi0JYWRkUHJlZml4TWFwcGluZygieG1sIiwgInhtbCIpOyAvLyBNYWtlIHN1cmUgJ3htbCcgbWFwcyB0byAneG1sJwotCi0JLy8gUmVwb3J0IGFuZCBlcnJvciBpZiBtb3JlIHRoYW4gb25lIHN0eWxlc2hlZXQgZGVmaW5lZAotCWZpbmFsIFN0eWxlc2hlZXQgc2hlZXQgPSBzdGFibGUuYWRkU3R5bGVzaGVldChfbmFtZSwgdGhpcyk7Ci0JaWYgKHNoZWV0ICE9IG51bGwpIHsKLQkgICAgLy8gRXJyb3I6IG1vcmUgdGhhdCBvbmUgc3R5bGVzaGVldCBkZWZpbmVkCi0JICAgIGZpbmFsIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhFcnJvck1zZy5TVExSRURFRl9FUlIsIHRoaXMpOwotCSAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotCX0KLQotCS8vIElmIHRoaXMgaXMgYSBzaW1wbGlmaWVkIHN0eWxlc2hlZXQgd2UgbXVzdCBjcmVhdGUgYSB0ZW1wbGF0ZSB0aGF0Ci0JLy8gZ3JhYnMgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgaW5wdXQgZG9jICggPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyIvPiApLgotCS8vIFRoaXMgdGVtcGxhdGUgbmVlZHMgdGhlIGN1cnJlbnQgZWxlbWVudCAodGhlIG9uZSBwYXNzZWQgdG8gdGhpcwotCS8vIG1ldGhvZCkgYXMgaXRzIG9ubHkgY2hpbGQsIHNvIHRoZSBUZW1wbGF0ZSBjbGFzcyBoYXMgYSBzcGVjaWFsCi0JLy8gbWV0aG9kIHRoYXQgaGFuZGxlcyB0aGlzIChwYXJzZVNpbXBsaWZpZWQoKSkuCi0JaWYgKF9zaW1wbGlmaWVkKSB7Ci0JICAgIHN0YWJsZS5leGNsdWRlVVJJKFhTTFRfVVJJKTsKLQkgICAgVGVtcGxhdGUgdGVtcGxhdGUgPSBuZXcgVGVtcGxhdGUoKTsKLQkgICAgdGVtcGxhdGUucGFyc2VTaW1wbGlmaWVkKHRoaXMsIHBhcnNlcik7Ci0JfQotCS8vIFBhcnNlIHRoZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUKLQllbHNlIHsKLQkgICAgcGFyc2VPd25DaGlsZHJlbihwYXJzZXIpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJzZSBhbGwgdGhlIGNoaWxkcmVuIG9mIDx0dD5lbGVtZW50PC90dD4uCi0gICAgICogWFNMVCBjb21tYW5kcyBhcmUgcmVjb2duaXplZCBieSB0aGUgWFNMVCBuYW1lc3BhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBwYXJzZU93bkNoaWxkcmVuKFBhcnNlciBwYXJzZXIpIHsKLQotCWZpbmFsIFZlY3RvciBjb250ZW50cyA9IGdldENvbnRlbnRzKCk7Ci0JZmluYWwgaW50IGNvdW50ID0gY29udGVudHMuc2l6ZSgpOwotCi0JLy8gV2UgaGF2ZSB0byBzY2FuIHRoZSBzdHlsZXNoZWV0IGVsZW1lbnQncyB0b3AtbGV2ZWwgZWxlbWVudHMgZm9yCi0JLy8gdmFyaWFibGVzIGFuZC9vciBwYXJhbWV0ZXJzIGJlZm9yZSB3ZSBwYXJzZSB0aGUgb3RoZXIgZWxlbWVudHMuLi4KLQlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgewotCSAgICBTeW50YXhUcmVlTm9kZSBjaGlsZCA9IChTeW50YXhUcmVlTm9kZSljb250ZW50cy5lbGVtZW50QXQoaSk7Ci0JICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgewotCQlwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5zZXRDdXJyZW50Tm9kZShjaGlsZCk7Ci0JCWNoaWxkLnBhcnNlQ29udGVudHMocGFyc2VyKTsKLQkgICAgfQotCX0KLQotCS8vIE5vdyBnbyB0aHJvdWdoIGFsbCB0aGUgb3RoZXIgdG9wLWxldmVsIGVsZW1lbnRzLi4uCi0JZm9yIChpbnQgaT0wOyBpPGNvdW50OyBpKyspIHsKLQkgICAgU3ludGF4VHJlZU5vZGUgY2hpbGQgPSAoU3ludGF4VHJlZU5vZGUpY29udGVudHMuZWxlbWVudEF0KGkpOwotCSAgICBpZiAoIShjaGlsZCBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkpIHsKLQkJcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuc2V0Q3VycmVudE5vZGUoY2hpbGQpOwotCQljaGlsZC5wYXJzZUNvbnRlbnRzKHBhcnNlcik7Ci0JICAgIH0KLQl9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc01vZGVzKCkgewotCWlmIChfZGVmYXVsdE1vZGUgPT0gbnVsbCkKLQkgICAgX2RlZmF1bHRNb2RlID0gbmV3IE1vZGUobnVsbCwgdGhpcywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLQlfZGVmYXVsdE1vZGUucHJvY2Vzc1BhdHRlcm5zKF9rZXlzKTsKLQlmaW5hbCBFbnVtZXJhdGlvbiBtb2RlcyA9IF9tb2Rlcy5lbGVtZW50cygpOwotCXdoaWxlIChtb2Rlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBNb2RlIG1vZGUgPSAoTW9kZSltb2Rlcy5uZXh0RWxlbWVudCgpOwotCSAgICBtb2RlLnByb2Nlc3NQYXR0ZXJucyhfa2V5cyk7Ci0JfQotICAgIH0KLQkKLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZU1vZGVzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0JX2RlZmF1bHRNb2RlLmNvbXBpbGVBcHBseVRlbXBsYXRlcyhjbGFzc0dlbik7Ci0JZmluYWwgRW51bWVyYXRpb24gbW9kZXMgPSBfbW9kZXMuZWxlbWVudHMoKTsKLQl3aGlsZSAobW9kZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgZmluYWwgTW9kZSBtb2RlID0gKE1vZGUpbW9kZXMubmV4dEVsZW1lbnQoKTsKLQkgICAgbW9kZS5jb21waWxlQXBwbHlUZW1wbGF0ZXMoY2xhc3NHZW4pOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTW9kZSBnZXRNb2RlKFFOYW1lIG1vZGVOYW1lKSB7Ci0JaWYgKG1vZGVOYW1lID09IG51bGwpIHsKLQkgICAgaWYgKF9kZWZhdWx0TW9kZSA9PSBudWxsKSB7Ci0JCV9kZWZhdWx0TW9kZSA9IG5ldyBNb2RlKG51bGwsIHRoaXMsIENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIF9kZWZhdWx0TW9kZTsKLQl9Ci0JZWxzZSB7Ci0JICAgIE1vZGUgbW9kZSA9IChNb2RlKV9tb2Rlcy5nZXQobW9kZU5hbWUpOwotCSAgICBpZiAobW9kZSA9PSBudWxsKSB7Ci0JCWZpbmFsIFN0cmluZyBzdWZmaXggPSBJbnRlZ2VyLnRvU3RyaW5nKF9uZXh0TW9kZVNlcmlhbCsrKTsKLQkJX21vZGVzLnB1dChtb2RlTmFtZSwgbW9kZSA9IG5ldyBNb2RlKG1vZGVOYW1lLCB0aGlzLCBzdWZmaXgpKTsKLQkgICAgfQotCSAgICByZXR1cm4gbW9kZTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZSBjaGVjayBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCXJldHVybiB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGUgc3R5bGVzaGVldCBpbnRvIEpWTSBieXRlY29kZXMuIAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCXRyYW5zbGF0ZSgpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBhZGRET01GaWVsZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotCWZpbmFsIEZpZWxkR2VuIGZnZW4gPSBuZXcgRmllbGRHZW4oQUNDX1BVQkxJQywKLQkJCQkJICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLQkJCQkJICAgRE9NX0ZJRUxELAotCQkJCQkgICBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0JY2xhc3NHZW4uYWRkRmllbGQoZmdlbi5nZXRGaWVsZCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGUgdGhlIHN0eWxlc2hlZXQgaW50byBKVk0gYnl0ZWNvZGVzLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoKSB7Ci0JT3V0cHV0IGxhc3RPdXRwdXRFbGVtZW50ID0gbnVsbDsKLQlfY2xhc3NOYW1lID0gZ2V0WFNMVEMoKS5nZXRDbGFzc05hbWUoKTsKLQotCS8vIERlZmluZSBhIG5ldyBjbGFzcyBieSBleHRlbmRpbmcgVFJBTlNMRVRfQ0xBU1MKLQlmaW5hbCBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiA9Ci0JICAgIG5ldyBDbGFzc0dlbmVyYXRvcihfY2xhc3NOYW1lLAotCQkJICAgICAgIFRSQU5TTEVUX0NMQVNTLAotCQkJICAgICAgIENvbnN0YW50cy5FTVBUWVNUUklORywKLQkJCSAgICAgICBBQ0NfUFVCTElDIHwgQUNDX1NVUEVSLAotCQkJICAgICAgIG51bGwsIHRoaXMpOwotCQotCWFkZERPTUZpZWxkKGNsYXNzR2VuKTsKLQotCS8vIENvbXBpbGUgdHJhbnNmb3JtKCkgdG8gaW5pdGlhbGl6ZSBwYXJhbWV0ZXJzLCBnbG9iYWxzICYgb3V0cHV0Ci0JLy8gYW5kIHJ1biB0aGUgdHJhbnNmb3JtYXRpb24KLQljb21waWxlVHJhbnNmb3JtKGNsYXNzR2VuKTsKLQotCS8vIFRyYW5zbGF0ZSBhbGwgbm9uLXRlbXBsYXRlIGVsZW1lbnRzIGFuZCBmaWx0ZXIgb3V0IGFsbCB0ZW1wbGF0ZXMKLQlmaW5hbCBFbnVtZXJhdGlvbiBlbGVtZW50cyA9IGVsZW1lbnRzKCk7Ci0Jd2hpbGUgKGVsZW1lbnRzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIE9iamVjdCBlbGVtZW50ID0gZWxlbWVudHMubmV4dEVsZW1lbnQoKTsKLQkgICAgLy8geHNsOnRlbXBsYXRlCi0JICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgVGVtcGxhdGUpIHsKLQkJLy8gU2VwYXJhdGUgdGVtcGxhdGVzIGJ5IG1vZGVzCi0JCWZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gKFRlbXBsYXRlKWVsZW1lbnQ7Ci0JCV90ZW1wbGF0ZXMuYWRkRWxlbWVudCh0ZW1wbGF0ZSk7Ci0JCWdldE1vZGUodGVtcGxhdGUuZ2V0TW9kZU5hbWUoKSkuYWRkVGVtcGxhdGUodGVtcGxhdGUpOwotCSAgICB9Ci0JICAgIC8vIHhzbDphdHRyaWJ1dGUtc2V0Ci0JICAgIGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBBdHRyaWJ1dGVTZXQpIHsKLQkJKChBdHRyaWJ1dGVTZXQpZWxlbWVudCkudHJhbnNsYXRlKGNsYXNzR2VuLCBudWxsKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgT3V0cHV0KSB7Ci0JCS8vIHNhdmUgdGhlIGVsZW1lbnQgZm9yIGxhdGVyIHRvIHBhc3MgdG8gY29tcGlsZUNvbnN0cnVjdG9yIAotCQlsYXN0T3V0cHV0RWxlbWVudCA9IChPdXRwdXQpZWxlbWVudDsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJLy8gR2xvYmFsIHZhcmlhYmxlcyBhbmQgcGFyYW1ldGVycyBhcmUgaGFuZGxlZCBlbHNld2hlcmUuCi0JCS8vIE90aGVyIHRvcC1sZXZlbCBub24tdGVtcGxhdGUgZWxlbWVudHMgYXJlIGlnbm9yZWQuIExpdGVyYWwKLQkJLy8gZWxlbWVudHMgb3V0c2lkZSBvZiB0ZW1wbGF0ZXMgd2lsbCBuZXZlciBiZSBvdXRwdXQuCi0JICAgIH0KLQl9Ci0KLQlwcm9jZXNzTW9kZXMoKTsKLQljb21waWxlTW9kZXMoY2xhc3NHZW4pOwotCi0JY29tcGlsZUNvbnN0cnVjdG9yKGNsYXNzR2VuLCBsYXN0T3V0cHV0RWxlbWVudCk7Ci0KLQlpZiAoIWdldFBhcnNlcigpLmVycm9yc0ZvdW5kKCkpIHsKLQkgICAgZ2V0WFNMVEMoKS5kdW1wQ2xhc3MoY2xhc3NHZW4uZ2V0SmF2YUNsYXNzKCkpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIHRoZSB0cmFuc2xldCdzIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNvbXBpbGVDb25zdHJ1Y3RvcihDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgT3V0cHV0IG91dHB1dCkgewotCi0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWZpbmFsIE1ldGhvZEdlbmVyYXRvciBjb25zdHJ1Y3RvciA9Ci0JICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLQkJCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLlZPSUQsIAotCQkJCW51bGwsIG51bGwsICI8aW5pdD4iLCAKLQkJCQlfY2xhc3NOYW1lLCBpbCwgY3BnKTsKLQotCS8vIENhbGwgdGhlIGNvbnN0cnVjdG9yIGluIHRoZSBBYnN0cmFjdFRyYW5zbGV0IHN1cGVyY2xhc3MKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJICAgICAiPGluaXQ+IiwgIigpViIpKSk7Ci0KLQkvLyBQdXQgdGhlIG5hbWVzIGFycmF5IGludG8gdGhlIHRyYW5zbGV0IC0gdXNlZCBmb3IgZG9tL3RyYW5zbGV0IG1hcHBpbmcKLQlmaW5hbCBWZWN0b3IgbmFtZXMgPSBnZXRYU0xUQygpLmdldE5hbWVzSW5kZXgoKTsKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWVzLnNpemUoKSkpOwotCWlsLmFwcGVuZChuZXcgQU5FV0FSUkFZKGNwZy5hZGRDbGFzcyhTVFJJTkcpKSk7CQkKLQotCWZvciAoaW50IGkgPSAwOyBpIDwgbmFtZXMuc2l6ZSgpOyBpKyspIHsKLQkgICAgZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLmVsZW1lbnRBdChpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGkpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbmFtZSkpOwotCSAgICBpbC5hcHBlbmQoQUFTVE9SRSk7Ci0JfQotCWlsLmFwcGVuZChuZXcgUFVURklFTEQoY3BnLmFkZEZpZWxkcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkgICAgICAgTkFNRVNfSU5ERVgsCi0JCQkJCSAgICAgICBOQU1FU19JTkRFWF9TSUcpKSk7Ci0KLQkvLyBQdXQgdGhlIG5hbWVzcGFjZSBuYW1lcyBhcnJheSBpbnRvIHRoZSB0cmFuc2xldAotCWZpbmFsIFZlY3RvciBuYW1lc3BhY2VzID0gZ2V0WFNMVEMoKS5nZXROYW1lc3BhY2VJbmRleCgpOwotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbmFtZXNwYWNlcy5zaXplKCkpKTsKLQlpbC5hcHBlbmQobmV3IEFORVdBUlJBWShjcGcuYWRkQ2xhc3MoU1RSSU5HKSkpOwkJCi0KLQlmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzcGFjZXMuc2l6ZSgpOyBpKyspIHsKLQkgICAgZmluYWwgU3RyaW5nIG5zID0gKFN0cmluZyluYW1lc3BhY2VzLmVsZW1lbnRBdChpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGkpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbnMpKTsKLQkgICAgaWwuYXBwZW5kKEFBU1RPUkUpOwotCX0KLQlpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJICAgICAgIE5BTUVTUEFDRV9JTkRFWCwKLQkJCQkJICAgICAgIE5BTUVTUEFDRV9JTkRFWF9TSUcpKSk7Ci0KLQkvLyBDb21waWxlIGluIGNvZGUgdG8gc2V0IHRoZSBvdXRwdXQgY29uZmlndXJhdGlvbiBmcm9tIDx4c2w6b3V0cHV0PgotCWlmIChvdXRwdXQgIT0gbnVsbCkgewotCSAgICAvLyBTZXQgYWxsIHRoZSBvdXRwdXQgc2V0dGluZ3MgZmlsZXMgaW4gdGhlIHRyYW5zbGV0Ci0JICAgIG91dHB1dC50cmFuc2xhdGUoY2xhc3NHZW4sIGNvbnN0cnVjdG9yKTsKLQl9Ci0KLQkvLyBDb21waWxlIGRlZmF1bHQgZGVjaW1hbCBmb3JtYXR0aW5nIHN5bWJvbHMuCi0JLy8gVGhpcyBpcyBhbiBpbXBsaWNpdCwgbmFtZWxlc3MgeHNsOmRlY2ltYWwtZm9ybWF0IHRvcC1sZXZlbCBlbGVtZW50LgotCWlmIChfbnVtYmVyRm9ybWF0dGluZ1VzZWQpCi0JICAgIERlY2ltYWxGb3JtYXR0aW5nLnRyYW5zbGF0ZURlZmF1bHRERlMoY2xhc3NHZW4sIGNvbnN0cnVjdG9yKTsKLQotCWlsLmFwcGVuZChSRVRVUk4pOwotCi0JY29uc3RydWN0b3Iuc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotCWNvbnN0cnVjdG9yLnNldE1heExvY2FscygpOwotCWNvbnN0cnVjdG9yLnNldE1heFN0YWNrKCk7Ci0JY2xhc3NHZW4uYWRkTWV0aG9kKGNvbnN0cnVjdG9yLmdldE1ldGhvZCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIGEgdG9wTGV2ZWwoKSBtZXRob2QgaW50byB0aGUgb3V0cHV0IGNsYXNzLiBUaGlzIG1ldGhvZCBpcyAKLSAgICAgKiBjYWxsZWQgZnJvbSB0cmFuc2Zvcm0oKSB0byBoYW5kbGUgYWxsIG5vbi10ZW1wbGF0ZSB0b3AtbGV2ZWwgZWxlbXRlbnRzLgotICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiB0aGUgdG9wTGV2ZWwoKSBtZXRob2QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgY29tcGlsZVRvcExldmVsKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgIEVudW1lcmF0aW9uIGVsZW1lbnRzKSB7Ci0KLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0KLQlmaW5hbCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlW10gYXJnVHlwZXMgPSB7Ci0JICAgIFV0aWwuZ2V0SkNSZWZUeXBlKERPTV9JTlRGX1NJRyksCi0JICAgIFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKSwKLQkgICAgVXRpbC5nZXRKQ1JlZlR5cGUoVFJBTlNMRVRfT1VUUFVUX1NJRykKLQl9OwotCi0JZmluYWwgU3RyaW5nW10gYXJnTmFtZXMgPSB7Ci0JICAgIERPQ1VNRU5UX1BOQU1FLCBJVEVSQVRPUl9QTkFNRSwgVFJBTlNMRVRfT1VUUFVUX1BOQU1FCi0JfTsKLQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWZpbmFsIE1ldGhvZEdlbmVyYXRvciB0b3BsZXZlbCA9Ci0JICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLQkJCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLlZPSUQsCi0JCQkJYXJnVHlwZXMsIGFyZ05hbWVzLAotCQkJCSJ0b3BMZXZlbCIsIF9jbGFzc05hbWUsIGlsLAotCQkJCWNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpKTsKLQotCXRvcGxldmVsLmFkZEV4Y2VwdGlvbigib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbiIpOwotCi0JLy8gRGVmaW5lIGFuZCBpbml0aWFsaXplICdjdXJyZW50JyB2YXJpYWJsZSB3aXRoIHRoZSByb290IG5vZGUKLQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIGN1cnJlbnQgPSAKLQkgICAgdG9wbGV2ZWwuYWRkTG9jYWxWYXJpYWJsZSgiY3VycmVudCIsCi0JCQkJICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJCSAgICBpbC5nZXRFbmQoKSwgbnVsbCk7Ci0KLQlmaW5hbCBpbnQgc2V0RmlsdGVyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCSAgICAgICAic2V0RmlsdGVyIiwKLQkJCSAgICAgICAiKExvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL1N0cmlwRmlsdGVyOylWIik7Ci0KLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBET00uUk9PVE5PREUpKTsKLQlpbC5hcHBlbmQobmV3IElTVE9SRShjdXJyZW50LmdldEluZGV4KCkpKTsKLQotCS8vIEluaXRpYWxpemUgZ2xvYmFsIHZhcmlhYmxlcyBhbmQgcGFyYW1ldGVybnMKLQlmaW5hbCBpbnQgbSA9IF9nbG9iYWxzLnNpemUoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG07IGkrKykgewotCSAgICBUb3BMZXZlbEVsZW1lbnQgZWxlbSA9IChUb3BMZXZlbEVsZW1lbnQpX2dsb2JhbHMuZWxlbWVudEF0KGkpOwotCSAgICBlbGVtLnRyYW5zbGF0ZShjbGFzc0dlbiwgdG9wbGV2ZWwpOwotCX0KLQotCVZlY3RvciB3aGl0ZXNwYWNlUnVsZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLQkvLyBDb21waWxlIGNvZGUgZm9yIG90aGVyIHRvcC1sZXZlbCBlbGVtZW50cwotCXdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBPYmplY3QgZWxlbWVudCA9IGVsZW1lbnRzLm5leHRFbGVtZW50KCk7Ci0JICAgIC8qCi0JICAgIC8vIHhzbDpvdXRwdXQKLQkgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBPdXRwdXQpIHsKLQkJKChPdXRwdXQpZWxlbWVudCkudHJhbnNsYXRlKGNsYXNzR2VuLCB0b3BsZXZlbCk7Ci0JICAgIH0KLQkgICAgLy8geHNsOmtleQotCSAgICBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgS2V5KSB7Ci0JCWZpbmFsIEtleSBrZXkgPSAoS2V5KWVsZW1lbnQ7Ci0JCWtleS50cmFuc2xhdGUoY2xhc3NHZW4sIHRvcGxldmVsKTsKLQkJX2tleXMucHV0KGtleS5nZXROYW1lKCksa2V5KTsKLQkgICAgfQotCSAgICAqLwotCSAgICAvLyB4c2w6ZGVjaW1hbC1mb3JtYXQKLQkgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBEZWNpbWFsRm9ybWF0dGluZykgewotCQkoKERlY2ltYWxGb3JtYXR0aW5nKWVsZW1lbnQpLnRyYW5zbGF0ZShjbGFzc0dlbix0b3BsZXZlbCk7Ci0JICAgIH0KLQkgICAgLy8geHNsOnN0cmlwL3ByZXNlcnZlLXNwYWNlCi0JICAgIGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBXaGl0ZXNwYWNlKSB7Ci0JCXdoaXRlc3BhY2VSdWxlcy5hZGRBbGwoKChXaGl0ZXNwYWNlKWVsZW1lbnQpLmdldFJ1bGVzKCkpOwotCSAgICB9Ci0JICAgIC8vIHhzbDp2YXJpYWJsZSBvciB4c2w6cGFyYW0KLQkgICAgZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgewotCQkoKFZhcmlhYmxlQmFzZSllbGVtZW50KS50cmFuc2xhdGUoY2xhc3NHZW4sdG9wbGV2ZWwpOwotCSAgICB9Ci0JfQotCi0JaWYgKHdoaXRlc3BhY2VSdWxlcy5zaXplKCkgPiAwKSB7Ci0JICAgIFdoaXRlc3BhY2UudHJhbnNsYXRlUnVsZXMod2hpdGVzcGFjZVJ1bGVzLGNsYXNzR2VuKTsKLQl9Ci0KLQlpZiAoY2xhc3NHZW4uY29udGFpbnNNZXRob2QoU1RSSVBfU1BBQ0UsIFNUUklQX1NQQUNFX1BBUkFNUykgIT0gbnVsbCkgewotCSAgICBpbC5hcHBlbmQodG9wbGV2ZWwubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uoc2V0RmlsdGVyLCAyKSk7Ci0JfQotCi0JaWwuYXBwZW5kKFJFVFVSTik7Ci0KLQkvLyBDb21wdXRlIG1heCBsb2NhbHMgKyBzdGFjayBhbmQgYWRkIG1ldGhvZCB0byBjbGFzcwotCXRvcGxldmVsLnN0cmlwQXR0cmlidXRlcyh0cnVlKTsKLQl0b3BsZXZlbC5zZXRNYXhMb2NhbHMoKTsKLQl0b3BsZXZlbC5zZXRNYXhTdGFjaygpOwotCXRvcGxldmVsLnJlbW92ZU5PUHMoKTsKLQotCWNsYXNzR2VuLmFkZE1ldGhvZCh0b3BsZXZlbC5nZXRNZXRob2QoKSk7Ci0JCi0JcmV0dXJuKCIoIitET01fSU5URl9TSUcrTk9ERV9JVEVSQVRPUl9TSUcrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgYSBidWlsZEtleXMoKSBtZXRob2QgaW50byB0aGUgb3V0cHV0IGNsYXNzLiBUaGlzIG1ldGhvZCBpcyAKLSAgICAgKiBjYWxsZWQgZnJvbSB0cmFuc2Zvcm0oKSB0byBoYW5kbGUgYnVpbGQgYWxsIGluZGV4ZXMgbmVlZGVkIGJ5IGtleSgpLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGNvbXBpbGVCdWlsZEtleXMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4pIHsKLQotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQotCWZpbmFsIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGVbXSBhcmdUeXBlcyA9IHsKLQkgICAgVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLQkgICAgVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpLAotCSAgICBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9PVVRQVVRfU0lHKSwKLQkgICAgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQKLQl9OwotCi0JZmluYWwgU3RyaW5nW10gYXJnTmFtZXMgPSB7Ci0JICAgIERPQ1VNRU5UX1BOQU1FLCBJVEVSQVRPUl9QTkFNRSwgVFJBTlNMRVRfT1VUUFVUX1BOQU1FLCAiY3VycmVudCIKLQl9OwotCi0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbmV3IEluc3RydWN0aW9uTGlzdCgpOwotCi0JZmluYWwgTWV0aG9kR2VuZXJhdG9yIGJ1aWxkS2V5cyA9Ci0JICAgIG5ldyBNZXRob2RHZW5lcmF0b3IoQUNDX1BVQkxJQywKLQkJCQlkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLlZPSUQsCi0JCQkJYXJnVHlwZXMsIGFyZ05hbWVzLAotCQkJCSJidWlsZEtleXMiLCBfY2xhc3NOYW1lLCBpbCwKLQkJCQljbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0KLQlmaW5hbCBpbnQgZG9tRmllbGQgPSBjcGcuYWRkRmllbGRyZWYoZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCSAgICAgRE9NX0ZJRUxELAotCQkJCQkgICAgIERPTV9JTlRGX1NJRyk7Ci0KLQlidWlsZEtleXMuYWRkRXhjZXB0aW9uKCJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uIik7Ci0KLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCWlsLmFwcGVuZChuZXcgR0VURklFTEQoZG9tRmllbGQpKTsgIC8vIFRoZSBET00gcmVmZXJlbmNlCi0JaWwuYXBwZW5kKG5ldyBBU1RPUkUoMSkpOwotCQotCWZpbmFsIEVudW1lcmF0aW9uIGVsZW1lbnRzID0gZWxlbWVudHMoKTsKLQkvLyBDb21waWxlIGNvZGUgZm9yIG90aGVyIHRvcC1sZXZlbCBlbGVtZW50cwotCXdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICAvLyB4c2w6a2V5Ci0JICAgIGZpbmFsIE9iamVjdCBlbGVtZW50ID0gZWxlbWVudHMubmV4dEVsZW1lbnQoKTsKLQkgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBLZXkpIHsKLQkJZmluYWwgS2V5IGtleSA9IChLZXkpZWxlbWVudDsKLQkJa2V5LnRyYW5zbGF0ZShjbGFzc0dlbiwgYnVpbGRLZXlzKTsKLQkJX2tleXMucHV0KGtleS5nZXROYW1lKCksa2V5KTsKLQkgICAgfQotCX0KLQkKLQlpbC5hcHBlbmQoUkVUVVJOKTsKLQkKLQkvLyBDb21wdXRlIG1heCBsb2NhbHMgKyBzdGFjayBhbmQgYWRkIG1ldGhvZCB0byBjbGFzcwotCWJ1aWxkS2V5cy5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0JYnVpbGRLZXlzLnNldE1heExvY2FscygpOwotCWJ1aWxkS2V5cy5zZXRNYXhTdGFjaygpOwotCWJ1aWxkS2V5cy5yZW1vdmVOT1BzKCk7Ci0KLQljbGFzc0dlbi5hZGRNZXRob2QoYnVpbGRLZXlzLmdldE1ldGhvZCgpKTsKLQkKLQlyZXR1cm4oIigiK0RPTV9JTlRGX1NJRytOT0RFX0lURVJBVE9SX1NJRytUUkFOU0xFVF9PVVRQVVRfU0lHKyJJKVYiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIHRyYW5zZm9ybSgpIGludG8gdGhlIG91dHB1dCBjbGFzcy4gVGhpcyBtZXRob2QgaXMgdXNlZCB0byAKLSAgICAgKiBpbml0aWFsaXplIGdsb2JhbCB2YXJpYWJsZXMgYW5kIGdsb2JhbCBwYXJhbWV0ZXJzLiBUaGUgY3VycmVudCBub2RlCi0gICAgICogaXMgc2V0IHRvIGJlIHRoZSBkb2N1bWVudCdzIHJvb3Qgbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZVRyYW5zZm9ybShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQotCS8qIAotCSAqIERlZmluZSB0aGUgdGhlIG1ldGhvZCB0cmFuc2Zvcm0gd2l0aCB0aGUgZm9sbG93aW5nIHNpZ25hdHVyZToKLQkgKiB2b2lkIHRyYW5zZm9ybShET00sIE5vZGVJdGVyYXRvciwgSGFuZGxlckJhc2UpCi0JICovCi0JZmluYWwgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVtdIGFyZ1R5cGVzID0gCi0JICAgIG5ldyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlWzNdOwotCWFyZ1R5cGVzWzBdID0gVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKTsKLQlhcmdUeXBlc1sxXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKE5PREVfSVRFUkFUT1JfU0lHKTsKLQlhcmdUeXBlc1syXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpOwotCi0JZmluYWwgU3RyaW5nW10gYXJnTmFtZXMgPSBuZXcgU3RyaW5nWzNdOwotCWFyZ05hbWVzWzBdID0gRE9DVU1FTlRfUE5BTUU7Ci0JYXJnTmFtZXNbMV0gPSBJVEVSQVRPUl9QTkFNRTsKLQlhcmdOYW1lc1syXSA9IFRSQU5TTEVUX09VVFBVVF9QTkFNRTsKLQotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBNZXRob2RHZW5lcmF0b3IgdHJhbnNmID0KLQkgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDLAotCQkJCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuVk9JRCwKLQkJCQlhcmdUeXBlcywgYXJnTmFtZXMsCi0JCQkJInRyYW5zZm9ybSIsCi0JCQkJX2NsYXNzTmFtZSwKLQkJCQlpbCwKLQkJCQljbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSk7Ci0JdHJhbnNmLmFkZEV4Y2VwdGlvbigib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbiIpOwotCi0JLy8gRGVmaW5lIGFuZCBpbml0aWFsaXplIGN1cnJlbnQgd2l0aCB0aGUgcm9vdCBub2RlCi0JZmluYWwgTG9jYWxWYXJpYWJsZUdlbiBjdXJyZW50ID0gCi0JICAgIHRyYW5zZi5hZGRMb2NhbFZhcmlhYmxlKCJjdXJyZW50IiwKLQkJCQkgICAgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQsCi0JCQkJICAgIGlsLmdldEVuZCgpLCBudWxsKTsKLQlmaW5hbCBTdHJpbmcgYXBwbHlUZW1wbGF0ZXNTaWcgPSBjbGFzc0dlbi5nZXRBcHBseVRlbXBsYXRlc1NpZygpOwotCWZpbmFsIGludCBhcHBseVRlbXBsYXRlcyA9IGNwZy5hZGRNZXRob2RyZWYoZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCQkgICAgImFwcGx5VGVtcGxhdGVzIiwKLQkJCQkJCSAgICBhcHBseVRlbXBsYXRlc1NpZyk7Ci0JZmluYWwgaW50IGRvbUZpZWxkID0gY3BnLmFkZEZpZWxkcmVmKGdldENsYXNzTmFtZSgpLAotCQkJCQkgICAgIERPTV9GSUVMRCwKLQkJCQkJICAgICBET01fSU5URl9TSUcpOwotCi0JLy8gcHVzaCB0cmFuc2xldCBmb3IgUFVURklFTEQKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCS8vIHByZXBhcmUgYXBwcm9wcmlhdGUgRE9NIGltcGxlbWVudGF0aW9uCi0JCi0JaWYgKGlzTXVsdGlET00oKSkgewotCSAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoTVVMVElfRE9NX0NMQVNTKSkpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQl9Ci0JCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQodHJhbnNmLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkgICAgICJtYWtlRE9NQWRhcHRlciIsCi0JCQkJCQkgICAgICIoIitET01fSU5URl9TSUcrIikiKwotCQkJCQkJICAgICBET01fQURBUFRFUl9TSUcpKSk7Ci0JLy8gRE9NQWRhcHRlciBpcyBvbiB0aGUgc3RhY2sKLQotCWlmIChpc011bHRpRE9NKCkpIHsKLQkgICAgZmluYWwgaW50IGluaXQgPSBjcGcuYWRkTWV0aG9kcmVmKE1VTFRJX0RPTV9DTEFTUywKLQkJCQkJICAgICAgIjxpbml0PiIsCi0JCQkJCSAgICAgICIoIitET01fSU5URl9TSUcrIilWIik7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbml0KSk7Ci0JICAgIC8vIE11bHRpRE9NIGlzIG9uIHRoZSBzdGFjawotCX0KLQkKLQkvL3N0b3JlIHRvIF9kb20gdmFyaWFibGUKLQlpbC5hcHBlbmQobmV3IFBVVEZJRUxEKGRvbUZpZWxkKSk7Ci0KLQkvLyBjb250aW51ZSB3aXRoIGdsb2JhbHMgaW5pdGlhbGl6YXRpb24KLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBET00uUk9PVE5PREUpKTsKLQlpbC5hcHBlbmQobmV3IElTVE9SRShjdXJyZW50LmdldEluZGV4KCkpKTsKLQotCS8vIFRyYW5zZmVyIHRoZSBvdXRwdXQgc2V0dGluZ3MgdG8gdGhlIG91dHB1dCBwb3N0LXByb2Nlc3NvcgotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKHRyYW5zZi5sb2FkSGFuZGxlcigpKTsKLQlmaW5hbCBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkgICAidHJhbnNmZXJPdXRwdXRTZXR0aW5ncyIsCi0JCQkJCSAgICIoIitPVVRQVVRfSEFORExFUl9TSUcrIilWIik7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0KLQkvLyBMb29rIGZvciB0b3AtbGV2ZWwgZWxlbWVudHMgdGhhdCBuZWVkIGhhbmRsaW5nCi0JZmluYWwgRW51bWVyYXRpb24gdG9wbGV2ZWwgPSBlbGVtZW50cygpOwotCWlmICgoX2dsb2JhbHMuc2l6ZSgpID4gMCkgfHwgKHRvcGxldmVsLmhhc01vcmVFbGVtZW50cygpKSkgewotCSAgICAvLyBDb21waWxlIG1ldGhvZCBmb3IgaGFuZGxpbmcgdG9wLWxldmVsIGVsZW1lbnRzCi0JICAgIGZpbmFsIFN0cmluZyB0b3BMZXZlbFNpZyA9IGNvbXBpbGVUb3BMZXZlbChjbGFzc0dlbiwgdG9wbGV2ZWwpOwotCSAgICAvLyBHZXQgYSByZWZlcmVuY2UgdG8gdGhhdCBtZXRob2QKLQkgICAgZmluYWwgaW50IHRvcExldmVsSWR4ID0gY3BnLmFkZE1ldGhvZHJlZihnZXRDbGFzc05hbWUoKSwKLQkJCQkJCSAgICAgInRvcExldmVsIiwKLQkJCQkJCSAgICAgdG9wTGV2ZWxTaWcpOwotCSAgICAvLyBQdXNoIGFsbCBwYXJhbWV0ZXJzIG9uIHRoZSBzdGFjayBhbmQgY2FsbCB0b3BMZXZlbCgpCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7IC8vIFRoZSAndGhpcycgcG9pbnRlcgotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGRvbUZpZWxkKSk7ICAvLyBUaGUgRE9NIHJlZmVyZW5jZQotCSAgICBpbC5hcHBlbmQodHJhbnNmLmxvYWRJdGVyYXRvcigpKTsKLQkgICAgaWwuYXBwZW5kKHRyYW5zZi5sb2FkSGFuZGxlcigpKTsgICAgLy8gVGhlIG91dHB1dCBoYW5kbGVyCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTCh0b3BMZXZlbElkeCkpOwotCX0KLQkKLQlmaW5hbCBTdHJpbmcga2V5U2lnID0gY29tcGlsZUJ1aWxkS2V5cyhjbGFzc0dlbik7Ci0JZmluYWwgaW50ICAgIGtleUlkeCA9IGNwZy5hZGRNZXRob2RyZWYoZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCSAgICAgICAiYnVpbGRLZXlzIiwga2V5U2lnKTsKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOyAgICAgLy8gVGhlICd0aGlzJyBwb2ludGVyCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGRvbUZpZWxkKSk7ICAgICAgLy8gVGhlIERPTSByZWZlcmVuY2UKLQlpbC5hcHBlbmQodHJhbnNmLmxvYWRJdGVyYXRvcigpKTsgICAgICAgLy8gTm90IHJlYWxseSB1c2VkLCBidXQuLi4KLQlpbC5hcHBlbmQodHJhbnNmLmxvYWRIYW5kbGVyKCkpOyAgICAgICAgLy8gVGhlIG91dHB1dCBoYW5kbGVyCi0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRE9NLlJPT1ROT0RFKSk7IC8vIFN0YXJ0IHdpdGggdGhlIHJvb3Qgbm9kZQotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChrZXlJZHgpKTsKLQotCS8vIHN0YXJ0IGRvY3VtZW50Ci0JaWwuYXBwZW5kKHRyYW5zZi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQodHJhbnNmLnN0YXJ0RG9jdW1lbnQoKSk7Ci0KLQkvLyBwdXNoIGZpcnN0IGFyZyBmb3IgYXBwbHlUZW1wbGF0ZXMKLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCS8vIHB1c2ggdHJhbnNsZXQgZm9yIEdFVEZJRUxEIHRvIGdldCBET00gYXJnCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGRvbUZpZWxkKSk7Ci0JLy8gcHVzaCByZW1haW5pbmcgMiBhcmdzCi0JaWwuYXBwZW5kKHRyYW5zZi5sb2FkSXRlcmF0b3IoKSk7Ci0JaWwuYXBwZW5kKHRyYW5zZi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoYXBwbHlUZW1wbGF0ZXMpKTsKLQkvLyBlbmREb2N1bWVudAotCWlsLmFwcGVuZCh0cmFuc2YubG9hZEhhbmRsZXIoKSk7Ci0JaWwuYXBwZW5kKHRyYW5zZi5lbmREb2N1bWVudCgpKTsKLQotCWlsLmFwcGVuZChSRVRVUk4pOwotCi0JLy8gQ29tcHV0ZSBtYXggbG9jYWxzICsgc3RhY2sgYW5kIGFkZCBtZXRob2QgdG8gY2xhc3MKLQl0cmFuc2Yuc3RyaXBBdHRyaWJ1dGVzKHRydWUpOwotCXRyYW5zZi5zZXRNYXhMb2NhbHMoKTsKLQl0cmFuc2Yuc2V0TWF4U3RhY2soKTsKLQl0cmFuc2YucmVtb3ZlTk9QcygpOwotCi0JY2xhc3NHZW4uYWRkTWV0aG9kKHRyYW5zZi5nZXRNZXRob2QoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGVlcGhvbGUgb3B0aW1pemF0aW9uOiBSZW1vdmUgc2VxdWVuY2VzIG9mIFtBTE9BRCwgUE9QXS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgcGVlcEhvbGVPcHRpbWl6YXRpb24oTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIFN0cmluZyBwYXQgPSAiYEFMT0FEJ2BQT1AnYEluc3RydWN0aW9uJyI7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIEZpbmRQYXR0ZXJuIGZpbmQgPSBuZXcgRmluZFBhdHRlcm4oaWwpOwotCi0JSW5zdHJ1Y3Rpb25IYW5kbGUgaWggPSBmaW5kLnNlYXJjaChwYXQpOwotCXdoaWxlIChpaCAhPSBudWxsKSB7Ci0JICAgIEluc3RydWN0aW9uSGFuZGxlW10gbWF0Y2ggPSBmaW5kLmdldE1hdGNoKCk7Ci0JICAgIHRyeSB7Ci0JCWlsLmRlbGV0ZShtYXRjaFswXSwgbWF0Y2hbMV0pOwotCSAgICB9Ci0JICAgIGNhdGNoIChUYXJnZXRMb3N0RXhjZXB0aW9uIGUpIHsKLQkJCQkvLyBUT0RPOiBtb3ZlIHRhcmdldCBkb3duIGludG8gdGhlIGxpc3QKLQkgICAgfQotCSAgICBpaCA9IGZpbmQuc2VhcmNoKHBhdCwgbWF0Y2hbMl0pOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGFkZFBhcmFtKFBhcmFtIHBhcmFtKSB7Ci0JX2dsb2JhbHMuYWRkRWxlbWVudChwYXJhbSk7Ci0JcmV0dXJuIF9nbG9iYWxzLnNpemUoKSAtIDE7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBhZGRWYXJpYWJsZShWYXJpYWJsZSBnbG9iYWwpIHsKLQlfZ2xvYmFscy5hZGRFbGVtZW50KGdsb2JhbCk7Ci0JcmV0dXJuIF9nbG9iYWxzLnNpemUoKSAtIDE7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0JaW5kZW50KGluZGVudCk7Ci0JVXRpbC5wcmludGxuKCJTdHlsZXNoZWV0Iik7Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLy8gZG8gd2UgbmVlZCB0aGlzIHdyYXBwZXIgPz8/Pz8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB7Ci0JcmV0dXJuIGxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgewotCXJldHVybiBfY2xhc3NOYW1lOwotICAgIH0KLQotICAgIHB1YmxpYyBWZWN0b3IgZ2V0VGVtcGxhdGVzKCkgewotCXJldHVybiBfdGVtcGxhdGVzOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N5bWJvbFRhYmxlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9TeW1ib2xUYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYmJjMGY2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N5bWJvbFRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjEgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgU3ltYm9sVGFibGUgewotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF90ZW1wbGF0ZXMgICA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZSBfc3R5bGVzaGVldHMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgX3ByaW1vcHMgICAgID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF92YXJpYWJsZXMgICA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZSBfYXRzZXRzICAgICAgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgX25hbWVzcGFjZXMgID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIHByaXZhdGUgZmluYWwgSGFzaHRhYmxlIF9wcmVmaXhlcyAgICA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZSBfYWxpYXNlcyAgICAgPSBuZXcgSGFzaHRhYmxlKCk7Ci0gICAgcHJpdmF0ZSBmaW5hbCBIYXNodGFibGUgX2V4Y2x1ZGVkVVJJID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgcHJpdmF0ZSBpbnQgbnNDb3VudGVyID0gMDsKLQotICAgIHB1YmxpYyBTdHlsZXNoZWV0IGFkZFN0eWxlc2hlZXQoUU5hbWUgbmFtZSwgU3R5bGVzaGVldCBub2RlKSB7Ci0JcmV0dXJuIChTdHlsZXNoZWV0KV9zdHlsZXNoZWV0cy5wdXQobmFtZSwgbm9kZSk7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdHlsZXNoZWV0IGxvb2t1cFN0eWxlc2hlZXQoUU5hbWUgbmFtZSkgewotCXJldHVybiAoU3R5bGVzaGVldClfc3R5bGVzaGVldHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBUZW1wbGF0ZSBhZGRUZW1wbGF0ZShUZW1wbGF0ZSB0ZW1wbGF0ZSkgewotCWZpbmFsIFFOYW1lIG5hbWUgPSB0ZW1wbGF0ZS5nZXROYW1lKCk7Ci0JbmFtZS5jbGVhckRlZmF1bHROYW1lc3BhY2UoKTsKLQlyZXR1cm4gKFRlbXBsYXRlKV90ZW1wbGF0ZXMucHV0KG5hbWUsIHRlbXBsYXRlKTsKLSAgICB9Ci0JCi0gICAgcHVibGljIFRlbXBsYXRlIGxvb2t1cFRlbXBsYXRlKFFOYW1lIG5hbWUpIHsKLQluYW1lLmNsZWFyRGVmYXVsdE5hbWVzcGFjZSgpOwotCXJldHVybiAoVGVtcGxhdGUpX3RlbXBsYXRlcy5nZXQobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFZhcmlhYmxlIGFkZFZhcmlhYmxlKFZhcmlhYmxlIHZhcmlhYmxlKSB7Ci0JZmluYWwgU3RyaW5nIG5hbWUgPSB2YXJpYWJsZS5nZXROYW1lKCkuZ2V0U3RyaW5nUmVwKCk7Ci0JcmV0dXJuIChWYXJpYWJsZSlfdmFyaWFibGVzLnB1dChuYW1lLCB2YXJpYWJsZSk7Ci0gICAgfQotCQotICAgIHB1YmxpYyBQYXJhbSBhZGRQYXJhbShQYXJhbSBwYXJhbWV0ZXIpIHsKLQlmaW5hbCBTdHJpbmcgbmFtZSA9IHBhcmFtZXRlci5nZXROYW1lKCkuZ2V0U3RyaW5nUmVwKCk7Ci0JcmV0dXJuIChQYXJhbSlfdmFyaWFibGVzLnB1dChuYW1lLCBwYXJhbWV0ZXIpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgVmFyaWFibGUgbG9va3VwVmFyaWFibGUoUU5hbWUgcW5hbWUpIHsKLQlmaW5hbCBTdHJpbmcgbmFtZSA9IHFuYW1lLmdldFN0cmluZ1JlcCgpOwotCWZpbmFsIE9iamVjdCBvYmogPSBfdmFyaWFibGVzLmdldChuYW1lKTsKLQlyZXR1cm4gb2JqIGluc3RhbmNlb2YgVmFyaWFibGUgPyAoVmFyaWFibGUpb2JqIDogbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUGFyYW0gbG9va3VwUGFyYW0oUU5hbWUgcW5hbWUpIHsKLQlmaW5hbCBTdHJpbmcgbmFtZSA9IHFuYW1lLmdldFN0cmluZ1JlcCgpOwotCWZpbmFsIE9iamVjdCBvYmogPSBfdmFyaWFibGVzLmdldChuYW1lKTsKLQlyZXR1cm4gb2JqIGluc3RhbmNlb2YgUGFyYW0gPyAoUGFyYW0pb2JqIDogbnVsbDsKLSAgICB9Ci0JCi0gICAgcHVibGljIFN5bnRheFRyZWVOb2RlIGxvb2t1cE5hbWUoUU5hbWUgcW5hbWUpIHsKLQlmaW5hbCBTdHJpbmcgbmFtZSA9IHFuYW1lLmdldFN0cmluZ1JlcCgpOwotCXJldHVybiAoU3ludGF4VHJlZU5vZGUpX3ZhcmlhYmxlcy5nZXQobmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIEF0dHJpYnV0ZVNldCBhZGRBdHRyaWJ1dGVTZXQoQXR0cmlidXRlU2V0IGF0dHMpIHsKLQlyZXR1cm4gKEF0dHJpYnV0ZVNldClfYXRzZXRzLnB1dChhdHRzLmdldE5hbWUoKSwgYXR0cyk7Ci0gICAgfQotCi0gICAgcHVibGljIEF0dHJpYnV0ZVNldCBsb29rdXBBdHRyaWJ1dGVTZXQoUU5hbWUgbmFtZSkgewotCXJldHVybiAoQXR0cmlidXRlU2V0KV9hdHNldHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZCBhIHByaW1pdGl2ZSBvcGVyYXRvciBvciBmdW5jdGlvbiB0byB0aGUgc3ltYm9sIHRhYmxlLiBUbyBhdm9pZAotICAgICAqIG5hbWUgY2xhc2hlcyB3aXRoIHVzZXItZGVmaW5lZCBuYW1lcywgdGhlIHByZWZpeCA8dHQ+UHJpbW9wUHJlZml4PC90dD4KLSAgICAgKiBpcyBwcmVwZW5kZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkUHJpbW9wKFN0cmluZyBuYW1lLCBNZXRob2RUeXBlIG10eXBlKSB7Ci0JVmVjdG9yIG1ldGhvZHMgPSAoVmVjdG9yKV9wcmltb3BzLmdldChuYW1lKTsKLQlpZiAobWV0aG9kcyA9PSBudWxsKSB7Ci0JICAgIF9wcmltb3BzLnB1dChuYW1lLCBtZXRob2RzID0gbmV3IFZlY3RvcigpKTsKLQl9Ci0JbWV0aG9kcy5hZGRFbGVtZW50KG10eXBlKTsKLSAgICB9Ci0JCi0gICAgLyoqCi0gICAgICogTG9va3VwIGEgcHJpbWl0aXZlIG9wZXJhdG9yIG9yIGZ1bmN0aW9uIGluIHRoZSBzeW1ib2wgdGFibGUgYnkKLSAgICAgKiBwcmVwZW5kaW5nIHRoZSBwcmVmaXggPHR0PlByaW1vcFByZWZpeDwvdHQ+LgotICAgICAqLwotICAgIHB1YmxpYyBWZWN0b3IgbG9va3VwUHJpbW9wKFN0cmluZyBuYW1lKSB7Ci0JcmV0dXJuIChWZWN0b3IpX3ByaW1vcHMuZ2V0KG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgdXNlZCBmb3IgeHNsOmF0dHJpYnV0ZSBlbGVtZW50cyB0aGF0IGhhdmUgYSAibmFtZXNwYWNlIgotICAgICAqIGF0dHJpYnV0ZSB0aGF0IGlzIGN1cnJlbnRseSBub3QgZGVmaW5lZCB1c2luZyB4bWxuczoKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdlbmVyYXRlTmFtZXNwYWNlUHJlZml4KCkgewotCWZpbmFsIFN0cmluZyBwcmVmaXggPSBuZXcgU3RyaW5nKCJucyIrKG5zQ291bnRlcisrKSk7Ci0JcmV0dXJuKHByZWZpeCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlIGEgbmFtZXNwYWNlIHByZWZpeCB0byBsb29rdXAgYSBuYW1lc3BhY2UgVVJJCi0gICAgICovCi0gICAgcHJpdmF0ZSBTeW50YXhUcmVlTm9kZSBfY3VycmVudCA9IG51bGw7Ci0gICAgcHVibGljIHZvaWQgc2V0Q3VycmVudE5vZGUoU3ludGF4VHJlZU5vZGUgbm9kZSkgewotCV9jdXJyZW50ID0gbm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB7Ci0JaWYgKF9jdXJyZW50ICE9IG51bGwpCi0JICAgIHJldHVybihfY3VycmVudC5sb29rdXBOYW1lc3BhY2UocHJlZml4KSk7Ci0JZWxzZQotCSAgICByZXR1cm4oQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGFuIGFsaWFzIGZvciBhIG5hbWVzcGFjZSBwcmVmaXgKLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgYWRkUHJlZml4QWxpYXMoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGFsaWFzKSB7Ci0JX2FsaWFzZXMucHV0KHByZWZpeCxhbGlhcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIGFueSBhbGlhcyBmb3IgYSBnaXZlbiBuYW1lc3BhY2UgcHJlZml4Ci0gICAgICovIAotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4QWxpYXMoU3RyaW5nIHByZWZpeCkgewotCXJldHVybiAoU3RyaW5nKV9hbGlhc2VzLmdldChwcmVmaXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXhjbHVkZVVSSShTdHJpbmcgdXJpKSB7Ci0JaWYgKHVyaSA9PSBudWxsKSByZXR1cm47Ci0JSW50ZWdlciByZWZjbnQgPSAoSW50ZWdlcilfZXhjbHVkZWRVUkkuZ2V0KHVyaSk7Ci0JaWYgKHJlZmNudCA9PSBudWxsKQotCSAgICByZWZjbnQgPSBuZXcgSW50ZWdlcigxKTsKLQllbHNlCi0JICAgIHJlZmNudCA9IG5ldyBJbnRlZ2VyKHJlZmNudC5pbnRWYWx1ZSgpICsgMSk7Ci0JX2V4Y2x1ZGVkVVJJLnB1dCh1cmkscmVmY250KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGV4Y2x1ZGVOYW1lc3BhY2VzKFN0cmluZyBwcmVmaXhlcykgewotCWlmIChwcmVmaXhlcyAhPSBudWxsKSB7Ci0JICAgIFN0cmluZ1Rva2VuaXplciB0b2tlbnMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHByZWZpeGVzKTsKLQkgICAgd2hpbGUgKHRva2Vucy5oYXNNb3JlVG9rZW5zKCkpIHsKLQkJZmluYWwgU3RyaW5nIHByZWZpeCA9IHRva2Vucy5uZXh0VG9rZW4oKTsKLQkJZmluYWwgU3RyaW5nIHVyaTsKLQkJaWYgKHByZWZpeC5lcXVhbHMoIiNkZWZhdWx0IikpCi0JCSAgICB1cmkgPSBsb29rdXBOYW1lc3BhY2UoQ29uc3RhbnRzLkVNUFRZU1RSSU5HKTsKLQkJZWxzZQotCQkgICAgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0JCWlmICh1cmkgIT0gbnVsbCkgZXhjbHVkZVVSSSh1cmkpOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeGNsdWRlZE5hbWVzcGFjZShTdHJpbmcgdXJpKSB7Ci0JaWYgKHVyaSA9PSBudWxsKSByZXR1cm4gZmFsc2U7Ci0JZmluYWwgSW50ZWdlciByZWZjbnQgPSAoSW50ZWdlcilfZXhjbHVkZWRVUkkuZ2V0KHVyaSk7Ci0JaWYgKHJlZmNudCA9PSBudWxsKSByZXR1cm4gZmFsc2U7Ci0JaWYgKHJlZmNudC5pbnRWYWx1ZSgpID4gMCkgcmV0dXJuIHRydWU7Ci0JcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5FeGNsdWRlTmFtZXNwYWNlcyhTdHJpbmcgcHJlZml4ZXMpIHsKLQlpZiAocHJlZml4ZXMgIT0gbnVsbCkgewotCSAgICBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihwcmVmaXhlcyk7Ci0JICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7Ci0JCWZpbmFsIFN0cmluZyBwcmVmaXggPSB0b2tlbnMubmV4dFRva2VuKCk7Ci0JCWZpbmFsIFN0cmluZyB1cmk7Ci0JCWlmIChwcmVmaXguZXF1YWxzKCIjZGVmYXVsdCIpKQotCQkgICAgdXJpID0gbG9va3VwTmFtZXNwYWNlKENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0JCWVsc2UKLQkJICAgIHVyaSA9IGxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCQlJbnRlZ2VyIHJlZmNudCA9IChJbnRlZ2VyKV9leGNsdWRlZFVSSS5nZXQodXJpKTsKLQkJaWYgKHJlZmNudCAhPSBudWxsKQotCQkgICAgX2V4Y2x1ZGVkVVJJLnB1dCh1cmksIG5ldyBJbnRlZ2VyKHJlZmNudC5pbnRWYWx1ZSgpIC0gMSkpOwotCSAgICB9Ci0JfQkKLSAgICB9Ci19Ci0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N5bnRheFRyZWVOb2RlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9TeW50YXhUcmVlTm9kZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MDU0NzY3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1N5bnRheFRyZWVOb2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NTcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBNb3J0ZW4gSm9yZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqIEBhdXRob3IgSm9obiBIb3dhcmQgPEpvaG5IQHNjaGVtYXNvZnQuY29tPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3ludGF4VHJlZU5vZGUgaW1wbGVtZW50cyBDb25zdGFudHMgewotCi0gICAgLy8gUmVmZXJlbmNlIHRvIHRoZSBBU1QgcGFyc2VyCi0gICAgcHJpdmF0ZSBQYXJzZXIgX3BhcnNlcjsKLQotICAgIC8vIFRoaXMgbm9kZSdzIGxpbmUgbnVtYmVyIGluIHRoZSBpbnB1dCBmaWxlIChub3Qgb2J0YWluYWJsZSEhISEpCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX2xpbmU7Ci0KLSAgICAvLyBSZWZlcmVuY2UgdG8gdGhpcyBub2RlJ3MgcGFyZW50IG5vZGUKLSAgICBwcm90ZWN0ZWQgU3ludGF4VHJlZU5vZGUgX3BhcmVudDsKLSAgICAvLyBDb250YWlucyBhbGwgY2hpbGQgbm9kZXMgb2YgdGhpcyBub2RlCi0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgICBfY29udGVudHMgPSBuZXcgVmVjdG9yKDIpOwotCi0gICAgLy8gVGhlIFFOYW1lIG9mIHRoaXMgZWxlbWVudCAoY29udGFpbnMgdXJpLCBwcmVmaXggYW5kIGxvY2FsbmFtZSkKLSAgICBwcm90ZWN0ZWQgUU5hbWUgICAgICBfcW5hbWU7Ci0gICAgLy8gVGhlIGF0dHJpYnV0ZXMgKGlmIGFueSkgb2YgdGhpcyBlbGVtZW50Ci0gICAgcHJvdGVjdGVkIEF0dHJpYnV0ZXMgX2F0dHJpYnV0ZXMgPSBudWxsOwotICAgIC8vIFRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIChpZiBhbnkpIG9mIHRoaXMgZWxlbWVudAotICAgIHByaXZhdGUgICBIYXNodGFibGUgX3ByZWZpeE1hcHBpbmcgPSBudWxsOwotCi0gICAgLy8gU2VudGluZWwKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN5bnRheFRyZWVOb2RlIER1bW15ID0gbmV3IEFic29sdXRlUGF0aFBhdHRlcm4obnVsbCk7Ci0KLSAgICAvLyBUaGVzZSB0d28gYXJlIHVzZWQgZm9yIGluZGVudGluZyBub2RlcyBpbiB0aGUgQVNUIChkZWJ1ZyBvdXRwdXQpCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIF9zcGFjZXMgPSAKLQkiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIudG9DaGFyQXJyYXkoKTsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBJbmRlbnRJbmNyZW1lbnQgPSA0OwotCi0gICAgcHVibGljIFN5bnRheFRyZWVOb2RlKCkgewotCV9saW5lID0gMDsKLQlfcW5hbWUgPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTeW50YXhUcmVlTm9kZShpbnQgbGluZSkgewotCV9saW5lID0gbGluZTsKLQlfcW5hbWUgPSBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTeW50YXhUcmVlTm9kZShTdHJpbmcgdXJpLCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWxuYW1lKSB7Ci0JX2xpbmUgPSAwOwotCXNldFFOYW1lKHVyaSwgcHJlZml4LCBsb2NhbG5hbWUpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFFOYW1lKFFOYW1lIHFuYW1lKSB7Ci0JX3FuYW1lID0gcW5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0UU5hbWUoU3RyaW5nIHVyaSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsbmFtZSkgewotCV9xbmFtZSA9IG5ldyBRTmFtZSh1cmksIHByZWZpeCwgbG9jYWxuYW1lKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0UU5hbWUoKSB7Ci0JcmV0dXJuKF9xbmFtZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlcyhBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKLQlfYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIHFuYW1lKSB7Ci0JaWYgKF9hdHRyaWJ1dGVzID09IG51bGwpCi0JICAgIHJldHVybihDb25zdGFudHMuRU1QVFlTVFJJTkcpOwotCWZpbmFsIFN0cmluZyB2YWx1ZSA9IF9hdHRyaWJ1dGVzLmdldFZhbHVlKHFuYW1lKTsKLQlpZiAodmFsdWUgPT0gbnVsbCkKLQkgICAgcmV0dXJuKENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0JZWxzZQotCSAgICByZXR1cm4odmFsdWUpOwotICAgIH0KLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVzIGdldEF0dHJpYnV0ZXMoKSB7Ci0JcmV0dXJuKF9hdHRyaWJ1dGVzKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXhNYXBwaW5nKEhhc2h0YWJsZSBtYXBwaW5nKSB7Ci0JX3ByZWZpeE1hcHBpbmcgPSBtYXBwaW5nOwotICAgIH0KLQotICAgIHB1YmxpYyBIYXNodGFibGUgZ2V0UHJlZml4TWFwcGluZygpIHsKLQlyZXR1cm4gX3ByZWZpeE1hcHBpbmc7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgYWRkUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0JaWYgKF9wcmVmaXhNYXBwaW5nID09IG51bGwpCi0JICAgIF9wcmVmaXhNYXBwaW5nID0gbmV3IEhhc2h0YWJsZSgpOwotCV9wcmVmaXhNYXBwaW5nLnB1dChwcmVmaXgsIHVyaSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBsb29rdXBOYW1lc3BhY2UoU3RyaW5nIHByZWZpeCkgewotCS8vIEluaXRpYWxpc2UgdGhlIG91dHB1dCAoZGVmYXVsdCBpcyAnbnVsbCcgZm9yIHVuZGVmaW5lZCkKLQlTdHJpbmcgdXJpID0gbnVsbDsKLQotCS8vIEZpcnN0IGxvb2sgdXAgdGhlIHByZWZpeC91cmkgbWFwcGluZyBpbiBvdXIgb3duIGhhc2h0YWJsZS4uLgotCWlmIChfcHJlZml4TWFwcGluZyAhPSBudWxsKQotCSAgICB1cmkgPSAoU3RyaW5nKV9wcmVmaXhNYXBwaW5nLmdldChwcmVmaXgpOwotCS8vIC4uLiBidXQgaWYgd2UgY2FuJ3QgZmluZCBpdCB0aGVyZSB3ZSBhc2sgb3VyIHBhcmVudCBmb3IgdGhlIG1hcHBpbmcKLQlpZiAoKHVyaSA9PSBudWxsKSAmJiAoX3BhcmVudCAhPSBudWxsKSkgewotCSAgICB1cmkgPSBfcGFyZW50Lmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCSAgICBpZiAoKHByZWZpeCA9PSBDb25zdGFudHMuRU1QVFlTVFJJTkcpICYmICh1cmkgPT0gbnVsbCkpCi0JCXVyaSA9IENvbnN0YW50cy5FTVBUWVNUUklORzsKLQl9Ci0JLy8gLi4uIGFuZCB0aGVuIHdlIHJldHVybiB3aGF0ZXZlciBVUkkgd2UndmUgZ290LgotCXJldHVybih1cmkpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyB1cmkpIHsKLQkvLyBJbml0aWFsaXNlIHRoZSBvdXRwdXQgKGRlZmF1bHQgaXMgJ251bGwnIGZvciB1bmRlZmluZWQpCi0JU3RyaW5nIHByZWZpeCA9IG51bGw7Ci0KLQkvLyBGaXJzdCBsb29rIHVwIHRoZSBwcmVmaXgvdXJpIG1hcHBpbmcgaW4gb3VyIG93biBoYXNodGFibGUuLi4KLQlpZiAoKF9wcmVmaXhNYXBwaW5nICE9IG51bGwpICYmCi0JICAgIChfcHJlZml4TWFwcGluZy5jb250YWlucyh1cmkpKSkgewotCSAgICBFbnVtZXJhdGlvbiBwcmVmaXhlcyA9IF9wcmVmaXhNYXBwaW5nLmtleXMoKTsKLQkgICAgd2hpbGUgKHByZWZpeGVzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCXByZWZpeCA9IChTdHJpbmcpcHJlZml4ZXMubmV4dEVsZW1lbnQoKTsKLQkJU3RyaW5nIG1hcHNUbyA9IChTdHJpbmcpX3ByZWZpeE1hcHBpbmcuZ2V0KHByZWZpeCk7Ci0JCWlmIChtYXBzVG8uZXF1YWxzKHVyaSkpIHJldHVybihwcmVmaXgpOwotCSAgICB9Ci0JfQotCS8vIC4uLiBidXQgaWYgd2UgY2FuJ3QgZmluZCBpdCB0aGVyZSB3ZSBhc2sgb3VyIHBhcmVudCBmb3IgdGhlIG1hcHBpbmcKLQllbHNlIGlmIChfcGFyZW50ICE9IG51bGwpIHsKLQkgICAgcHJlZml4ID0gX3BhcmVudC5sb29rdXBQcmVmaXgodXJpKTsKLQkgICAgaWYgKCh1cmkgPT0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSAmJiAocHJlZml4ID09IG51bGwpKQotCQlwcmVmaXggPSBDb25zdGFudHMuRU1QVFlTVFJJTkc7Ci0JfQotCXJldHVybihwcmVmaXgpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0JX3BhcnNlciA9IHBhcnNlcjsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQYXJlbnQoU3ludGF4VHJlZU5vZGUgcGFyZW50KSB7Ci0JaWYgKF9wYXJlbnQgPT0gbnVsbCkKLQkgICAgX3BhcmVudCA9IHBhcmVudDsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGZpbmFsIFN5bnRheFRyZWVOb2RlIGdldFBhcmVudCgpIHsKLQlyZXR1cm4gX3BhcmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3R5bGVzaGVldCBnZXRTdHlsZXNoZWV0KCkgewotCVN5bnRheFRyZWVOb2RlIHBhcmVudCA9IHRoaXM7Ci0Jd2hpbGUgKHBhcmVudCAhPSBudWxsKSB7Ci0JICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KQotCQlyZXR1cm4oKFN0eWxlc2hlZXQpcGFyZW50KTsKLQkgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudCgpOwotCX0KLQlyZXR1cm4oKFN0eWxlc2hlZXQpcGFyZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEltcG9ydFByZWNlZGVuY2UoKSB7Ci0JcmV0dXJuIGdldFN0eWxlc2hlZXQoKS5nZXRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkIFRlbXBsYXRlIGdldFRlbXBsYXRlKCkgewotCVN5bnRheFRyZWVOb2RlIHBhcmVudCA9IHRoaXM7Ci0Jd2hpbGUgKChwYXJlbnQgIT0gbnVsbCkgJiYgKCEocGFyZW50IGluc3RhbmNlb2YgVGVtcGxhdGUpKSkKLQkgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudCgpOwotCXJldHVybigoVGVtcGxhdGUpcGFyZW50KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0R1bW15KCkgewotICAgICAgICByZXR1cm4gdGhpcyA9PSBEdW1teTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgUGFyc2VyIGdldFBhcnNlcigpIHsKLQlyZXR1cm4gX3BhcnNlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgWFNMVEMgZ2V0WFNMVEMoKSB7Ci0JcmV0dXJuIF9wYXJzZXIuZ2V0WFNMVEMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgU3ltYm9sVGFibGUgZ2V0U3ltYm9sVGFibGUoKSB7Ci0JaWYgKF9wYXJzZXIgIT0gbnVsbCkKLQkgICAgcmV0dXJuIF9wYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLQllbHNlCi0JICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRvIGJlIG92ZXJyaWRkZW4gaW4gbm9kZXMgaW1wbGVtZW50ZWQgYnkgY29kZSBvdXRzaWRlIG9mIGFwcGx5VGVtcGxhdGVzCi0gICAgICogZWcuIGluIFByZWRpY2F0ZXMKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0Nsb3N1cmVCb3VuZGFyeSgpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgbm9ybWFsbHkgb3ZlcnJpZGVuIGJ5IHN1YmNsYXNzZXMuCi0gICAgICogQnkgZGVmYXVsdCwgaXQgcGFyc2VzIGFsbCB0aGUgY2hpbGRyZW4gb2YgPHR0PmVsZW1lbnQ8L3R0Pi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgYWxsIHRoZSBjaGlsZHJlbiBvZiA8dHQ+ZWxlbWVudDwvdHQ+LgotICAgICAqIFhTTFQgY29tbWFuZHMgYXJlIHJlY29nbml6ZWQgYnkgdGhlIFhTTFQgbmFtZXNwYWNlCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcGFyc2VDaGlsZHJlbihQYXJzZXIgcGFyc2VyKSB7Ci0KLQlWZWN0b3IgbG9jYWxzID0gbnVsbDsJLy8gb25seSBjcmVhdGUgd2hlbiBuZWVkZWQKLQkKLQlmaW5hbCBpbnQgY291bnQgPSBfY29udGVudHMuc2l6ZSgpOwotCWZvciAoaW50IGk9MDsgaTxjb3VudDsgaSsrKSB7Ci0JICAgIFN5bnRheFRyZWVOb2RlIGNoaWxkID0gKFN5bnRheFRyZWVOb2RlKV9jb250ZW50cy5lbGVtZW50QXQoaSk7Ci0JICAgIHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpLnNldEN1cnJlbnROb2RlKGNoaWxkKTsKLQkgICAgY2hpbGQucGFyc2VDb250ZW50cyhwYXJzZXIpOwotCSAgICAvLyBpZiB2YXJpYWJsZSBvciBwYXJhbWV0ZXIsIGFkZCBpdCB0byBzY29wZQotCSAgICBmaW5hbCBRTmFtZSB2YXJPclBhcmFtTmFtZSA9IHVwZGF0ZVNjb3BlKHBhcnNlciwgY2hpbGQpOwotCSAgICBpZiAodmFyT3JQYXJhbU5hbWUgIT0gbnVsbCkgewotCQlpZiAobG9jYWxzID09IG51bGwpIHsKLQkJICAgIGxvY2FscyA9IG5ldyBWZWN0b3IoMik7Ci0JCX0KLQkJbG9jYWxzLmFkZEVsZW1lbnQodmFyT3JQYXJhbU5hbWUpOwotCSAgICB9Ci0JfQotCi0JcGFyc2VyLmdldFN5bWJvbFRhYmxlKCkuc2V0Q3VycmVudE5vZGUodGhpcyk7Ci0KLQkvLyBhZnRlciB0aGUgbGFzdCBlbGVtZW50LCByZW1vdmUgYW55IGxvY2FscyBmcm9tIHNjb3BlCi0JaWYgKGxvY2FscyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBuTG9jYWxzID0gbG9jYWxzLnNpemUoKTsKLQkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuTG9jYWxzOyBpKyspIHsKLQkJcGFyc2VyLnJlbW92ZVZhcmlhYmxlKChRTmFtZSlsb2NhbHMuZWxlbWVudEF0KGkpKTsKLQkgICAgfQotCX0KLSAgICB9Ci0gICAKLSAgICAvKioKLSAgICAgKiBBZGQgYSBub2RlIHRvIHRoZSBjdXJyZW50IHNjb3BlIGFuZCByZXR1cm4gbmFtZSBvZiBhIHZhcmlhYmxlIG9yCi0gICAgICogcGFyYW1ldGVyIGlmIHRoZSBub2RlIHJlcHJlc2VudHMgYSB2YXJpYWJsZSBvciBhIHBhcmFtZXRlci4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgUU5hbWUgdXBkYXRlU2NvcGUoUGFyc2VyIHBhcnNlciwgU3ludGF4VHJlZU5vZGUgbm9kZSkgewotCWlmIChub2RlIGluc3RhbmNlb2YgVmFyaWFibGUpIHsKLQkgICAgZmluYWwgVmFyaWFibGUgdmFyID0gKFZhcmlhYmxlKW5vZGU7Ci0JICAgIHBhcnNlci5hZGRWYXJpYWJsZSh2YXIpOwotCSAgICByZXR1cm4gdmFyLmdldE5hbWUoKTsKLQl9Ci0JZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIFBhcmFtKSB7Ci0JICAgIGZpbmFsIFBhcmFtIHBhcmFtID0gKFBhcmFtKW5vZGU7Ci0JICAgIHBhcnNlci5hZGRQYXJhbWV0ZXIocGFyYW0pOwotCSAgICByZXR1cm4gcGFyYW0uZ2V0TmFtZSgpOwotCX0KLQllbHNlIHsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2sgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZS4gVGhlIHR5cGUgY2hlY2sgcGhhc2UgbWF5IGFkZAotICAgICAqIGNvZXJjaW9ucyAoQ2FzdEV4cHIpIHRvIHRoZSBBU1QuCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yOwotCi0gICAgLyoqCi0gICAgICogQ2FsbCB0eXBlQ2hlY2soKSBvbiBldmVyeSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrQ29udGVudHMoU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCWZpbmFsIGludCBuID0gZWxlbWVudENvdW50KCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkgICAgU3ludGF4VHJlZU5vZGUgaXRlbSA9IChTeW50YXhUcmVlTm9kZSlfY29udGVudHMuZWxlbWVudEF0KGkpOwotCSAgICBpdGVtLnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGlzIG5vZGUgaW50byBKVk0gYnl0ZWNvZGVzLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKTsKLQotICAgIC8qKgotICAgICAqIENhbGwgdHJhbnNsYXRlKCkgb24gZXZlcnkgY2hpbGRyZW4gb2YgdGhpcyBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUNvbnRlbnRzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIGludCBuID0gZWxlbWVudENvdW50KCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKLQkgICAgZmluYWwgU3ludGF4VHJlZU5vZGUgaXRlbSA9IChTeW50YXhUcmVlTm9kZSlfY29udGVudHMuZWxlbWVudEF0KGkpOwotCSAgICBpdGVtLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0KLQkvKioKLQkgKiBBZnRlciB0cmFuc2xhdGlvbiwgdW5tYXAgYW55IHJlZ2lzdGVycyBmb3IgYW55IHZhcmlhYmxlcy9wYXJhbWV0ZXJzCi0JICogdGhhdCB3ZXJlIGRlY2xhcmVkIGluIHRoaXMgc2NvcGUuIFBlcmZvcm1pbmcgdGhpcyB1bm1hcHBpbmcgaW4gdGhlCi0JICogc2FtZSBBU1Qgc2NvcGUgYXMgdGhlIGRlY2xhcmF0aW9uIGRlYWxzIHdpdGggdGhlIHByb2JsZW1zIG9mCi0JICogcmVmZXJlbmNlcyBmYWxsaW5nIG91dC1vZi1zY29wZSBpbnNpZGUgdGhlIGZvci1lYWNoIGVsZW1lbnQuCi0JICogKHRoZSBjYXVzZSBvZiB3aGljaCBiZWluZyAnbGF6eScgcmVnaXN0ZXIgYWxsb2NhdGlvbiBmb3IgcmVmZXJlbmNlcykKLQkgKi8KLQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCSAgICBpZiggX2NvbnRlbnRzLmVsZW1lbnRBdChpKSBpbnN0YW5jZW9mIFZhcmlhYmxlQmFzZSkgewotCQlmaW5hbCBWYXJpYWJsZUJhc2UgdmFyID0gKFZhcmlhYmxlQmFzZSlfY29udGVudHMuZWxlbWVudEF0KGkpOwotCQl2YXIudW5tYXBSZWdpc3RlcihtZXRob2RHZW4pOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIHVzZWQgYnkgcGFyYW1ldGVycyBhbmQgdmFyaWFibGVzIHRvIHN0b3JlIHJlc3VsdCB0cmVlcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvbXBpbGVSZXN1bHRUcmVlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJCSAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCi0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCS8vIFNhdmUgdGhlIGN1cnJlbnQgaGFuZGxlciBiYXNlIG9uIHRoZSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0KLQlmaW5hbCBTdHJpbmcgRE9NX0NMQVNTID0gY2xhc3NHZW4uZ2V0RE9NQ2xhc3MoKTsKLQotCS8vIENyZWF0ZSBuZXcgaW5zdGFuY2Ugb2YgRE9NIGNsYXNzICh3aXRoIDY0IG5vZGVzKQotCWludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoRE9NX0lNUEwsICI8aW5pdD4iLCAiKEkpViIpOwotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhET01fSU1QTCkpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCA2NCkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChpbmRleCkpOwotCi0JLy8gT3ZlcndyaXRlIG9sZCBoYW5kbGVyIHdpdGggRE9NIGhhbmRsZXIKLQlpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoRE9NX0lNUEwsCi0JCQkJICJnZXRPdXRwdXREb21CdWlsZGVyIiwKLQkJCQkgIigpIiArIFRSQU5TTEVUX09VVFBVVF9TSUcpOwotCi0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0KLQkvLyBDYWxsIHN0YXJ0RG9jdW1lbnQgb24gdGhlIG5ldyBoYW5kbGVyCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdGFydERvY3VtZW50KCkpOwotCi0JLy8gSW5zdGFudGlhdGUgcmVzdWx0IHRyZWUgZnJhZ21lbnQKLQl0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCS8vIENhbGwgZW5kRG9jdW1lbnQgb24gdGhlIG5ldyBoYW5kbGVyCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmVuZERvY3VtZW50KCkpOwotCi0JLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byB3cmFwIHRoZSBET01JbXBsIG9iamVjdCBpbiBhIERPTUFkYXB0ZXIgb2JqZWN0Ci0JaWYgKCFET01fQ0xBU1MuZXF1YWxzKERPTV9JTVBMX0NMQVNTKSkgewotCSAgICAvLyBuZXcgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NQWRhcHRlcihET01JbXBsLFN0cmluZ1tdKTsKLQkgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKERPTV9BREFQVEVSX0NMQVNTLAotCQkJCSAgICAgIjxpbml0PiIsCi0JCQkJICAgICAiKCIrRE9NX0lNUExfU0lHKwotCQkJCSAgICAgIlsiK1NUUklOR19TSUcrCi0JCQkJICAgICAiWyIrU1RSSU5HX1NJRysiKVYiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBORVcoY3BnLmFkZENsYXNzKERPTV9BREFQVEVSX0NMQVNTKSkpOwotCSAgICBpbC5hcHBlbmQobmV3IERVUF9YMSgpKTsKLQkgICAgaWwuYXBwZW5kKFNXQVApOwotCSAgICAvLyBHaXZlIHRoZSBET00gYWRhcHRlciBhbiBlbXB0eSB0eXBlIG1hcHBpbmcgdG8gc3RhcnQgd2l0aC4KLQkgICAgLy8gVHlwZSBtYXBwaW5nIGlzIGV4cGVuc2l2ZSBhbmQgd2lsbCBvbmx5IGJlIGRvbmUgd2hlbiBjYXN0aW5nCi0JICAgIC8vIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQgdG8gYSBub2RlLXNldC4KLQkgICAgaWwuYXBwZW5kKG5ldyBJQ09OU1QoMCkpOwotCSAgICBpbC5hcHBlbmQobmV3IEFORVdBUlJBWShjcGcuYWRkQ2xhc3MoU1RSSU5HKSkpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7IC8vIGxlYXZlIERPTUFkYXB0ZXIgb24gc3RhY2sKLQkgICAgCi0JICAgIC8vIE11c3Qgd2Ugd3JhcCB0aGUgRE9NQWRhcHRlciBvYmplY3QgaW4gYSBNdWx0aURPTSBvYmplY3Q/Ci0JICAgIC8qIE5vdCBuZWVkZWQgd2l0aCBuZXcgZGVzaWduIHVzaW5nIERPTSBpbnRlcmZhY2UgaW5zdGVhZCBvZgotCSAgICAgICByZWZlcmVuY2luZyBET00gY2xhc3NlcyBkaXJlY3RseQotCSAgICBpZiAoRE9NX0NMQVNTLmVxdWFscyhNVUxUSV9ET01fQ0xBU1MpKSB7Ci0JCS8vIG5ldyBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5NdWx0aURPTShET01BZGFwdGVyKTsKLQkJaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKE1VTFRJX0RPTV9DTEFTUywgIjxpbml0PiIsCi0JCQkJCSAiKCIrRE9NX0lOVEZfU0lHKyIpViIpOwotCQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoTVVMVElfRE9NX0NMQVNTKSkpOwotCQlpbC5hcHBlbmQobmV3IERVUF9YMSgpKTsKLQkJaWwuYXBwZW5kKFNXQVApOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5kZXgpKTsgLy8gbGVhdmUgTXVsdGlET00gb24gc3RhY2sKLQkgICAgfQotCSAgICAqLwotCX0KLQotCS8vIFJlc3RvcmUgb2xkIGhhbmRsZXIgYmFzZSBmcm9tIHN0YWNrCi0JaWwuYXBwZW5kKFNXQVApOwotCWlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGV4cHJlc3Npb24vaW5zdHJ1Y3Rpb24gZGVwZW5kcyBvbiB0aGUgY29udGV4dC4gQnkgCi0gICAgICogZGVmYXVsdCwgZXZlcnkgZXhwcmVzc2lvbi9pbnN0cnVjdGlvbiBkZXBlbmRzIG9uIHRoZSBjb250ZXh0IHVubGVzcyBpdCAKLSAgICAgKiBvdmVycmlkZXMgdGhpcyBtZXRob2QuIEN1cnJlbnRseSB1c2VkIHRvIGRldGVybWluZSBpZiByZXN1bHQgdHJlZXMgYXJlIAotICAgICAqIGNvbXBpbGVkIHVzaW5nIHByb2NlZHVyZXMgb3IgbGl0dGxlIERPTXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29udGV4dERlcGVuZGVudCgpIHsKLQlyZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdHJ1ZSBpZiBhbnkgb2YgdGhlIGV4cHJlc3Npb25zL2luc3RydWN0aW9ucyBpbiB0aGUgY29udGVudHMgb2YKLSAgICAgKiB0aGlzIG5vZGUgaXMgY29udGV4dCBkZXBlbmRlbnQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gZGVwZW5kZW50Q29udGVudHMoKSB7Ci0JZmluYWwgaW50IG4gPSBlbGVtZW50Q291bnQoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCSAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBpdGVtID0gKFN5bnRheFRyZWVOb2RlKV9jb250ZW50cy5lbGVtZW50QXQoaSk7Ci0JICAgIGlmIChpdGVtLmNvbnRleHREZXBlbmRlbnQoKSkgewotCQlyZXR1cm4gdHJ1ZTsKLQkgICAgfQotCX0KLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIHZvaWQgYWRkRWxlbWVudChTeW50YXhUcmVlTm9kZSBlbGVtZW50KSB7Ci0JX2NvbnRlbnRzLmFkZEVsZW1lbnQoZWxlbWVudCk7Ci0JZWxlbWVudC5zZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0Rmlyc3RFbGVtZW50KFN5bnRheFRyZWVOb2RlIGVsZW1lbnQpIHsKLQlfY29udGVudHMuaW5zZXJ0RWxlbWVudEF0KGVsZW1lbnQsMCk7Ci0JZWxlbWVudC5zZXRQYXJlbnQodGhpcyk7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlRWxlbWVudChTeW50YXhUcmVlTm9kZSBlbGVtZW50KSB7Ci0JX2NvbnRlbnRzLnJlbW92ZShlbGVtZW50KTsKLQllbGVtZW50LnNldFBhcmVudChudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgVmVjdG9yIGdldENvbnRlbnRzKCkgewotCXJldHVybiBfY29udGVudHM7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaGFzQ29udGVudHMoKSB7Ci0JcmV0dXJuIGVsZW1lbnRDb3VudCgpID4gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgaW50IGVsZW1lbnRDb3VudCgpIHsKLQlyZXR1cm4gX2NvbnRlbnRzLnNpemUoKTsKLSAgICB9Ci0JCi0gICAgcHVibGljIGZpbmFsIEVudW1lcmF0aW9uIGVsZW1lbnRzKCkgewotCXJldHVybiBfY29udGVudHMuZWxlbWVudHMoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGVsZW1lbnRBdChpbnQgaSkgewotCXJldHVybiBfY29udGVudHMuZWxlbWVudEF0KGkpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWRpc3BsYXlDb250ZW50cyhpbmRlbnQpOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIGRpc3BsYXlDb250ZW50cyhpbnQgaW5kZW50KSB7Ci0JZmluYWwgaW50IG4gPSBlbGVtZW50Q291bnQoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCSAgICBTeW50YXhUcmVlTm9kZSBpdGVtID0gKFN5bnRheFRyZWVOb2RlKV9jb250ZW50cy5lbGVtZW50QXQoaSk7Ci0JICAgIGl0ZW0uZGlzcGxheShpbmRlbnQpOwotCX0KLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBpbmRlbnQoaW50IGluZGVudCkgewotCVN5c3RlbS5vdXQucHJpbnQobmV3IFN0cmluZyhfc3BhY2VzLCAwLCBpbmRlbnQpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgaW50IGdldExpbmVOdW1iZXIoKSB7Ci0JcmV0dXJuIF9saW5lOwotICAgIH0KLQotICAgIHByb3RlY3RlZCB2b2lkIHJlcG9ydEVycm9yKFN5bnRheFRyZWVOb2RlIGVsZW1lbnQsIFBhcnNlciBwYXJzZXIsCi0JCQkgICAgICAgaW50IGVycm9yQ29kZSwgU3RyaW5nIG1lc3NhZ2UpIHsKLQlmaW5hbCBFcnJvck1zZyBlcnJvciA9IG5ldyBFcnJvck1zZyhlcnJvckNvZGUsIG1lc3NhZ2UsIHRoaXMpOwotICAgICAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnJvcik7Ci0gICAgfQotCi0gICAgcHJvdGVjdGVkICB2b2lkIHJlcG9ydFdhcm5pbmcoU3ludGF4VHJlZU5vZGUgZWxlbWVudCwgUGFyc2VyIHBhcnNlciwKLQkJCQkgIGludCBlcnJvckNvZGUsIFN0cmluZyBtZXNzYWdlKSB7Ci0JZmluYWwgRXJyb3JNc2cgZXJyb3IgPSBuZXcgRXJyb3JNc2coZXJyb3JDb2RlLCBtZXNzYWdlLCB0aGlzKTsKLSAgICAgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5XQVJOSU5HLCBlcnJvcik7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9UZW1wbGF0ZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVGVtcGxhdGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWU4OGEwOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9UZW1wbGF0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzU4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuSmF2YUNsYXNzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBUZW1wbGF0ZSBleHRlbmRzIFRvcExldmVsRWxlbWVudCB7Ci0KLSAgICBwcml2YXRlIFFOYW1lICAgX25hbWU7ICAgICAvLyBUaGUgbmFtZSBvZiB0aGUgdGVtcGxhdGUgKGlmIGFueSkKLSAgICBwcml2YXRlIFFOYW1lICAgX21vZGU7ICAgICAvLyBNb2RlIGluIHdoaWNoIHRoaXMgdGVtcGxhdGUgaXMgaW5zdGFudGlhdGVkLgotICAgIHByaXZhdGUgUGF0dGVybiBfcGF0dGVybjsgIC8vIE1hdGNoaW5nIHBhdHRlcm4gZGVmaW5lZCBmb3IgdGhpcyB0ZW1wbGF0ZS4KLSAgICBwcml2YXRlIGRvdWJsZSAgX3ByaW9yaXR5OyAvLyBNYXRjaGluZyBwcmlvcml0eSBvZiB0aGlzIHRlbXBsYXRlLgotICAgIHByaXZhdGUgaW50ICAgICBfcG9zaXRpb247IC8vIFBvc2l0aW9uIHdpdGhpbiBzdHlsZXNoZWV0IChwcmlvLiByZXNvbHV0aW9uKQotICAgIHByaXZhdGUgYm9vbGVhbiBfZGlzYWJsZWQgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2NvbXBpbGVkID0gZmFsc2U7Ly9tYWtlIHN1cmUgaXQgaXMgY29tcGlsZWQgb25seSBvbmNlCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdG8gPHR0PnRydWU8L3R0PiBieSB0aGUgWFBhdGggcGFyc2VyIGlmIHRoaXMgdGVtcGxhdGUKLSAgICAgKiBuZWVkcyB0byBjcmVhdGUgYSB2YXJpYWJsZSBmcmFtZS4gVmFyaWFibGUgZnJhbWVzIGFyZSBuZWVkZWQKLSAgICAgKiB3aGVuIGNlcnRhaW4gcGFydHMgb2YgYSB0ZW1wbGF0ZSBhcmUgY29tcGlsZWQgaW4gZXh0ZXJuYWwKLSAgICAgKiBjbGFzc2VzIChlLmcuLCBwcmVkaWNhdGVzLCB4c2w6bnVtYmVyLCB4c2w6c29ydCkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9oYXNWYXJpYWJsZUZyYW1lOwotICAgIHByaXZhdGUgYm9vbGVhbiBfaGFzUGFyYW1zID0gZmFsc2U7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9zaW1wbGlmaWVkID0gZmFsc2U7Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXJhbXMoKSB7Ci0JcmV0dXJuIF9oYXNQYXJhbXM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgaGFzUGFyYW1zKGJvb2xlYW4gaGFzUGFyYW1zKSB7Ci0JX2hhc1BhcmFtcyA9IGhhc1BhcmFtczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NpbXBsaWZpZWQoKSB7Ci0JcmV0dXJuKF9zaW1wbGlmaWVkKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRTaW1wbGlmaWVkKCkgewotCV9zaW1wbGlmaWVkID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNhYmxlKCkgewotCV9kaXNhYmxlZCA9IHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gZGlzYWJsZWQoKSB7Ci0JcmV0dXJuKF9kaXNhYmxlZCk7Ci0gICAgfQotCi0gICAgcHVibGljIGRvdWJsZSBnZXRQcmlvcml0eSgpIHsKLQlyZXR1cm4gX3ByaW9yaXR5OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7Ci0JcmV0dXJuKF9wb3NpdGlvbik7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNOYW1lZCgpIHsKLQlyZXR1cm4gX25hbWUgIT0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUGF0dGVybiBnZXRQYXR0ZXJuKCkgewotCXJldHVybiBfcGF0dGVybjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLQlyZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFFOYW1lIGdldE1vZGVOYW1lKCkgewotCXJldHVybiBfbW9kZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfdmFyaWFibGVzOwotICAgIHByaXZhdGUgaW50IF9uZXh0SW5kZXg7Ci0KLSAgICBwdWJsaWMgaW50IGFsbG9jYXRlSW5kZXgoUU5hbWUgdmFyTmFtZSkgewotCWlmIChfdmFyaWFibGVzID09IG51bGwpIHsgLy8gZmlyc3QgdGltZQotCSAgICBfaGFzVmFyaWFibGVGcmFtZSA9IHRydWU7Ci0JICAgIChfdmFyaWFibGVzID0gbmV3IEhhc2h0YWJsZSgpKS5wdXQodmFyTmFtZSwgbmV3IEludGVnZXIoMCkpOwotCSAgICBfbmV4dEluZGV4ID0gMTsKLQkgICAgcmV0dXJuIDA7Ci0JfQotCWVsc2UgewotCSAgICBJbnRlZ2VyIGluZGV4ID0gKEludGVnZXIpX3ZhcmlhYmxlcy5nZXQodmFyTmFtZSk7Ci0JICAgIGlmIChpbmRleCA9PSBudWxsKSB7Ci0JCV92YXJpYWJsZXMucHV0KHZhck5hbWUsIGluZGV4ID0gbmV3IEludGVnZXIoX25leHRJbmRleCsrKSk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIGluZGV4LmludFZhbHVlKCk7Ci0JfQotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgaW50IGxvY2FsVmFyaWFibGVzQ291bnQoKSB7Ci0JcmV0dXJuIF92YXJpYWJsZXMgPT0gbnVsbCA/IDAgOiBfdmFyaWFibGVzLnNpemUoKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0JVXRpbC5wcmludGxuKCdcbicpOwotCWluZGVudChpbmRlbnQpOwotCWlmIChfbmFtZSAhPSBudWxsKSB7Ci0JICAgIGluZGVudChpbmRlbnQpOwotCSAgICBVdGlsLnByaW50bG4oIm5hbWUgPSAiICsgX25hbWUpOwotCX0KLQllbHNlIGlmIChfcGF0dGVybiAhPSBudWxsKSB7Ci0JICAgIGluZGVudChpbmRlbnQpOwotCSAgICBVdGlsLnByaW50bG4oIm1hdGNoID0gIiArIF9wYXR0ZXJuLnRvU3RyaW5nKCkpOwotCX0KLQlpZiAoX21vZGUgIT0gbnVsbCkgewotCSAgICBpbmRlbnQoaW5kZW50KTsKLQkgICAgVXRpbC5wcmludGxuKCJtb2RlID0gIiArIF9tb2RlKTsKLQl9Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBib29sZWFuIHJlc29sdmVOYW1lZFRlbXBsYXRlcyhUZW1wbGF0ZSBvdGhlciwgUGFyc2VyIHBhcnNlcikgewotCi0JaWYgKG90aGVyID09IG51bGwpIHJldHVybiB0cnVlOwotCi0JU3ltYm9sVGFibGUgc3RhYmxlID0gcGFyc2VyLmdldFN5bWJvbFRhYmxlKCk7Ci0KLQlmaW5hbCBpbnQgdXMgPSB0aGlzLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLQlmaW5hbCBpbnQgdGhlbSA9IG90aGVyLmdldEltcG9ydFByZWNlZGVuY2UoKTsKLQotCWlmICh1cyA+IHRoZW0pIHsKLQkgICAgb3RoZXIuZGlzYWJsZSgpOwotCSAgICByZXR1cm4gdHJ1ZTsKLQl9Ci0JZWxzZSBpZiAodXMgPCB0aGVtKSB7Ci0JICAgIHN0YWJsZS5hZGRUZW1wbGF0ZShvdGhlcik7Ci0JICAgIHRoaXMuZGlzYWJsZSgpOwotCSAgICByZXR1cm4gdHJ1ZTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJldHVybiBmYWxzZTsKLQl9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHlsZXNoZWV0IF9zdHlsZXNoZWV0ID0gbnVsbDsKLQotICAgIHB1YmxpYyBTdHlsZXNoZWV0IGdldFN0eWxlc2hlZXQoKSB7Ci0JcmV0dXJuIF9zdHlsZXNoZWV0OwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCi0JZmluYWwgU3RyaW5nIG5hbWUgICAgID0gZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0JZmluYWwgU3RyaW5nIG1vZGUgICAgID0gZ2V0QXR0cmlidXRlKCJtb2RlIik7Ci0JZmluYWwgU3RyaW5nIG1hdGNoICAgID0gZ2V0QXR0cmlidXRlKCJtYXRjaCIpOwotCWZpbmFsIFN0cmluZyBwcmlvcml0eSA9IGdldEF0dHJpYnV0ZSgicHJpb3JpdHkiKTsKLQotCV9zdHlsZXNoZWV0ID0gc3VwZXIuZ2V0U3R5bGVzaGVldCgpOwotCi0JaWYgKG5hbWUubGVuZ3RoKCkgPiAwKSB7Ci0JICAgIF9uYW1lID0gcGFyc2VyLmdldFFOYW1lKG5hbWUpOwotCX0KLQkKLQlpZiAobW9kZS5sZW5ndGgoKSA+IDApIHsKLQkgICAgX21vZGUgPSBwYXJzZXIuZ2V0UU5hbWUobW9kZSk7Ci0JfQotCQotCWlmIChtYXRjaC5sZW5ndGgoKSA+IDApIHsKLQkgICAgX3BhdHRlcm4gPSBwYXJzZXIucGFyc2VQYXR0ZXJuKHRoaXMsICJtYXRjaCIsIG51bGwpOwotCX0KLQotCWlmIChwcmlvcml0eS5sZW5ndGgoKSA+IDApIHsKLQkgICAgX3ByaW9yaXR5ID0gRG91YmxlLnBhcnNlRG91YmxlKHByaW9yaXR5KTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGlmIChfcGF0dGVybiAhPSBudWxsKQotCQlfcHJpb3JpdHkgPSBfcGF0dGVybi5nZXRQcmlvcml0eSgpOwotCSAgICBlbHNlCi0JCV9wcmlvcml0eSA9IERvdWJsZS5OYU47Ci0JfQotCi0JX3Bvc2l0aW9uID0gcGFyc2VyLmdldFRlbXBsYXRlSW5kZXgoKTsKLQotCS8vIEFkZCB0aGUgKG5hbWVkKSB0ZW1wbGF0ZSB0byB0aGUgc3ltYm9sIHRhYmxlCi0JaWYgKF9uYW1lICE9IG51bGwpIHsKLQkgICAgVGVtcGxhdGUgb3RoZXIgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5hZGRUZW1wbGF0ZSh0aGlzKTsKLQkgICAgaWYgKCFyZXNvbHZlTmFtZWRUZW1wbGF0ZXMob3RoZXIsIHBhcnNlcikpIHsKLQkJcGFyc2VyLnJlcG9ydEVycm9yKCBDb25zdGFudHMuRVJST1IsCi0JCSAgICBuZXcgRXJyb3JNc2coRXJyb3JNc2cuVE1QUkVERUZfRVJSLF9uYW1lLHRoaXMpKTsKLQkgICAgfQotCX0KLQotCXBhcnNlci5zZXRUZW1wbGF0ZSh0aGlzKTsJLy8gc2V0IGN1cnJlbnQgdGVtcGxhdGUKLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0JcGFyc2VyLnNldFRlbXBsYXRlKG51bGwpOwkvLyBjbGVhciB0ZW1wbGF0ZQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFdoZW4gdGhlIHBhcnNlciByZWFsaXNlcyB0aGF0IGl0IGlzIGRlYWxpZ24gd2l0aCBhIHNpbXBsaWZpZWQgc3R5bGVzaGVldAotICAgICAqIGl0IHdpbGwgY3JlYXRlIGFuIGVtcHR5IFN0eWxlc2hlZXQgb2JqZWN0IHdpdGggdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUKLSAgICAgKiBzdHlsZXNoZWV0IChhIExpdGVyYWxFbGVtZW50IG9iamVjdCkgYXMgaXRzIG9ubHkgY2hpbGQuIFRoZSBTdHlsZXNoZWV0Ci0gICAgICogb2JqZWN0IHdpbGwgdGhlbiBjcmVhdGUgdGhpcyBUZW1wbGF0ZSBvYmplY3QgYW5kIGludm9rZSB0aGlzIG1ldGhvZCB0bwotICAgICAqIGZvcmNlIHNvbWUgc3BlY2lmaWMgYmVoYXZpb3VyLiBXaGF0IHdlIG5lZWQgdG8gZG8gaXM6Ci0gICAgICogIG8pIGNyZWF0ZSBhIHBhdHRlcm4gbWF0Y2hpbmcgb24gdGhlIHJvb3Qgbm9kZQotICAgICAqICBvKSBhZGQgdGhlIExSRSByb290IG5vZGUgKHRoZSBvbmx5IGNoaWxkIG9mIHRoZSBTdHlsZXNoZWV0KSBhcyBvdXIKLSAgICAgKiAgICAgb25seSBjaGlsZCBub2RlCi0gICAgICogIG8pIHNldCB0aGUgZW1wdHkgU3R5bGVzaGVldCBhcyBvdXIgcGFyZW50Ci0gICAgICogIG8pIHNldCB0aGlzIHRlbXBsYXRlIGFzIHRoZSBTdHlsZXNoZWV0J3Mgb25seSBjaGlsZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlU2ltcGxpZmllZChTdHlsZXNoZWV0IHN0eWxlc2hlZXQsIFBhcnNlciBwYXJzZXIpIHsKLQotCV9zdHlsZXNoZWV0ID0gc3R5bGVzaGVldDsKLQlzZXRQYXJlbnQoc3R5bGVzaGVldCk7Ci0KLQlfbmFtZSA9IG51bGw7Ci0JX21vZGUgPSBudWxsOwotCV9wcmlvcml0eSA9IERvdWJsZS5OYU47Ci0JX3BhdHRlcm4gPSBwYXJzZXIucGFyc2VQYXR0ZXJuKHRoaXMsICIvIik7Ci0KLQlmaW5hbCBWZWN0b3IgY29udGVudHMgPSBfc3R5bGVzaGVldC5nZXRDb250ZW50cygpOwotCWZpbmFsIFN5bnRheFRyZWVOb2RlIHJvb3QgPSAoU3ludGF4VHJlZU5vZGUpY29udGVudHMuZWxlbWVudEF0KDApOwotCi0JaWYgKHJvb3QgaW5zdGFuY2VvZiBMaXRlcmFsRWxlbWVudCkgewotCSAgICBhZGRFbGVtZW50KHJvb3QpOwotCSAgICByb290LnNldFBhcmVudCh0aGlzKTsKLQkgICAgY29udGVudHMuc2V0KDAsIHRoaXMpOwotCSAgICBwYXJzZXIuc2V0VGVtcGxhdGUodGhpcyk7Ci0JICAgIHJvb3QucGFyc2VDb250ZW50cyhwYXJzZXIpOwotCSAgICBwYXJzZXIuc2V0VGVtcGxhdGUobnVsbCk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKF9wYXR0ZXJuICE9IG51bGwpIHsKLQkgICAgX3BhdHRlcm4udHlwZUNoZWNrKHN0YWJsZSk7Ci0JfQotCi0JcmV0dXJuIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlmIChfZGlzYWJsZWQpIHJldHVybjsKLQkvLyBidWcgZml4ICM0NDMzMTMzLCBhZGQgYSBjYWxsIHRvIG5hbWVkIHRlbXBsYXRlIGZyb20gYXBwbHlUZW1wbGF0ZXMgCi0JU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotCi0JaWYgKF9jb21waWxlZCAmJiBpc05hbWVkKCkpewotCi0JICAgIFN0cmluZyBtZXRob2ROYW1lID0gX25hbWUudG9TdHJpbmcoKTsKLQkgICAgbWV0aG9kTmFtZSA9IG1ldGhvZE5hbWUucmVwbGFjZSgnLicsICckJyk7Ci0JICAgIG1ldGhvZE5hbWUgPSBtZXRob2ROYW1lLnJlcGxhY2UoJy0nLCAnJCcpOwotCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSXRlcmF0b3IoKSk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7IAotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRDdXJyZW50Tm9kZSgpKTsgCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKGNsYXNzTmFtZSwKLQkJCQkJCQkgbWV0aG9kTmFtZSwKLQkJCQkJCQkgIigiCi0JCQkJCQkJICsgRE9NX0lOVEZfU0lHCi0JCQkJCQkJICsgTk9ERV9JVEVSQVRPUl9TSUcKLQkJCQkJCQkgKyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0JCQkJCQkJICsgIkkpViIpKSk7Ci0JICAgIHJldHVybjsKLQl9Ci0KLQlfY29tcGlsZWQgPSB0cnVlOyAKLQkKLQlpZiAoX2hhc1ZhcmlhYmxlRnJhbWUpIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgbG9jYWxWYXJpYWJsZXNDb3VudCgpKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJCSBQVVNIX1ZBUl9GUkFNRSwKLQkJCQkJCQkgUFVTSF9WQVJfRlJBTUVfU0lHKSkpOwotCX0KLQkKLQlmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBzdGFydCA9IGlsLmdldEVuZCgpOwotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGVuZCA9IGlsLmdldEVuZCgpOwotCWlsLnNldFBvc2l0aW9ucyh0cnVlKTsKLQkKLQlpZiAoX2hhc1ZhcmlhYmxlRnJhbWUpIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsIAotCQkJCQkJCSBQT1BfVkFSX0ZSQU1FLAotCQkJCQkJCSBQT1BfVkFSX0ZSQU1FX1NJRykpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVGVzdFNlcS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVGVzdFNlcS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZjI1OGNjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1Rlc3RTZXEuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2NyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4gPG1vcnRlbi5qb3JnZW5zZW5Ac3VuLmNvbT4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFRlc3RTZXEgewotCi0gICAgLyoKLSAgICAgKiBBIHRlc3Qgc2VxdWVuY2UgaXMgYSBzZXF1ZW5jZSBvZiBwYXR0ZXJucyB0aGF0Ci0gICAgICoKLSAgICAgKiAgKDEpIG9jY3VyZWQgaW4gdGVtcGxhdGVzIGluIHRoZSBzYW1lIG1vZGUKLSAgICAgKiAgKDIpIHNoYXJlIHRoZSBzYW1lIGtlcm5lbCBub2RlIHR5cGUgKHN1Y2ggYXMgQS9CIGFuZCBDL0MvQikuCi0gICAgICoKLSAgICAgKiBBIHRlc3Qgc2VxdWVuY2UgbWF5IGhhdmUgYSBkZWZhdWx0IHRlbXBsYXRlLCB3aGljaCB3aWxsIGJlIHJ1biBpZgotICAgICAqIG5vbmUgb2YgdGhlIHBhdHRlcm5zIGRvIG5vdCBtYXRjaC4gVGhpcyB0ZW1wbGF0ZSBpcyBhbHdheXMgYSB0ZW1wbGF0ZQotICAgICAqIHRoYXQgbWF0Y2hlcyBzb2xlbHkgb24gdGhlIHNoYXJlZCBrZXJuZWwgbm9kZSB0eXBlLgotICAgICAqLwotICAgIHByaXZhdGUgVmVjdG9yICAgX3BhdHRlcm5zID0gbnVsbDsgLy8gYWxsIHBhdHRlcm5zCi0gICAgcHJpdmF0ZSBNb2RlICAgICBfbW9kZSAgICAgPSBudWxsOyAvLyB0aGUgc2hhcmVkIG1vZGUKLSAgICBwcml2YXRlIFRlbXBsYXRlIF9kZWZhdWx0ICA9IG51bGw7IC8vIHRoZSBkZWZhdWx0IHRlbXBsYXRlCi0KLSAgICBwcml2YXRlIEluc3RydWN0aW9uTGlzdCBfaW5zdHJ1Y3Rpb25MaXN0OwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyB0ZXN0IHNlcXVlbmNlLCBnaXZlbiBhIHNldCBvZiBwYXR0ZXJucyBhbmQgYSBtb2RlLgotICAgICAqLwotICAgIHB1YmxpYyBUZXN0U2VxKFZlY3RvciBwYXR0ZXJucywgTW9kZSBtb2RlKSB7Ci0JX3BhdHRlcm5zID0gcGF0dGVybnM7Ci0JX21vZGUgPSBtb2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBwcmlvcml0eSBpcyBvbmx5IGNhbGN1bGF0ZWQgaWYgdGhlIHRlc3Qgc2VxdWVuY2UgaGFzIGEgZGVmYXVsdAotICAgICAqIHRlbXBsYXRlLiBUaGlzIGlzIGJhZCwgYmFkLCBiYWQuIFdlIHNob3VsZCBnZXQgdGhlIHByaW9yaXR5IGZyb20gdGhlCi0gICAgICogb3RoZXIgdGVtcGxhdGVzIHRoYXQgbWFrZSB1cCB0aGUgdGVzdCBzZXF1ZW5jZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZG91YmxlIGdldFByaW9yaXR5KCkgewotCWRvdWJsZSBwcmlvID0gKDAgLSBEb3VibGUuTUFYX1ZBTFVFKTsKLQlmaW5hbCBpbnQgY291bnQgPSBfcGF0dGVybnMuc2l6ZSgpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCSAgICBmaW5hbCBQYXR0ZXJuIHBhdHRlcm4gPSAoUGF0dGVybilfcGF0dGVybnMuZWxlbWVudEF0KGkpOwotCSAgICBmaW5hbCBUZW1wbGF0ZSB0ZW1wbGF0ZSA9IHBhdHRlcm4uZ2V0VGVtcGxhdGUoKTsKLQkgICAgZmluYWwgZG91YmxlIHRwID0gdGVtcGxhdGUuZ2V0UHJpb3JpdHkoKTsKLQkgICAgaWYgKHRwID4gcHJpbykgcHJpbyA9IHRwOwotCX0KLQlpZiAoX2RlZmF1bHQgIT0gbnVsbCkgewotCSAgICBmaW5hbCBkb3VibGUgdHAgPSBfZGVmYXVsdC5nZXRQcmlvcml0eSgpOwotCSAgICBpZiAodHAgPiBwcmlvKSBwcmlvID0gdHA7Ci0JfQotCXJldHVybiBwcmlvOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCByZXR1cm4gdGhlIGxhc3QgcG9zaXRpb24gb2YgYW55IHRlbXBsYXRlIGluY2x1ZGVkCi0gICAgICogaW4gdGhpcyB0ZXN0IHNlcXVlbmNlLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7Ci0JaW50IHBvcyA9IEludGVnZXIuTUlOX1ZBTFVFOwotCWZpbmFsIGludCBjb3VudCA9IF9wYXR0ZXJucy5zaXplKCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0JICAgIGZpbmFsIFBhdHRlcm4gcGF0dGVybiA9IChQYXR0ZXJuKV9wYXR0ZXJucy5lbGVtZW50QXQoaSk7Ci0JICAgIGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gcGF0dGVybi5nZXRUZW1wbGF0ZSgpOwotCSAgICBmaW5hbCBpbnQgdHAgPSB0ZW1wbGF0ZS5nZXRQb3NpdGlvbigpOwotCSAgICBpZiAodHAgPiBwb3MpIHBvcyA9IHRwOwotCX0KLQlpZiAoX2RlZmF1bHQgIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgdHAgPSBfZGVmYXVsdC5nZXRQb3NpdGlvbigpOwotCSAgICBpZiAodHAgPiBwb3MpIHBvcyA9IHRwOwotCX0KLQlyZXR1cm4gcG9zOwotICAgIH0KLQkKLSAgICAvKioKLSAgICAgKiBSZWR1Y2UgdGhlIHBhdHRlcm5zIGluIHRoaXMgdGVzdCBzZXF1ZW5jZSB0byBleGNsdWRlIHRoZSBzaGFyZWQKLSAgICAgKiBrZXJuZWwgbm9kZSB0eXBlLiBBZnRlciB0aGUgc3dpdGNoKCkgaW4gdGhlIHRyYW5zbGV0J3MgYXBwbHlUZW1wbGF0ZXMoKQotICAgICAqIHdlIGFscmVhZHkga25vdyB0aGF0IHdlIGhhdmUgYSBoaXQgZm9yIHRoZSBrZXJuZWwgbm9kZSB0eXBlLCB3ZSBvbmx5Ci0gICAgICogaGF2ZSB0aGUgY2hlY2sgdGhlIHJlc3Qgb2YgdGhlIHBhdHRlbnMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVkdWNlKCkgewotCWZpbmFsIFZlY3RvciBuZXdQYXR0ZXJucyA9IG5ldyBWZWN0b3IoKTsKLQlmaW5hbCBpbnQgY291bnQgPSBfcGF0dGVybnMuc2l6ZSgpOwotCi0JLy8gVHJhdmVyc2UgdGhlIGV4aXN0aW5nIHNldCBvZiBwYXR0ZXJucyAodGhleSBhcmUgaW4gcHJpb3JpdGlzZWQgb3JkZXIpCi0JZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0JICAgIGZpbmFsIExvY2F0aW9uUGF0aFBhdHRlcm4gcGF0dGVybiA9Ci0JCShMb2NhdGlvblBhdGhQYXR0ZXJuKV9wYXR0ZXJucy5lbGVtZW50QXQoaSk7Ci0JICAgIC8vIFJlZHVjZSB0aGlzIHBhdHRlcm4gKGdldCByaWQgb2Yga2VybmVsIG5vZGUgdHlwZSkKLQkgICAgcGF0dGVybi5yZWR1Y2VLZXJuZWxQYXR0ZXJuKCk7Ci0JCQkKLQkgICAgLy8gQWRkIHRoaXMgcGF0dGVybiB0byB0aGUgbmV3IHZlY3RvciBvZiBwYXR0ZXJucy4KLQkgICAgaWYgKCFwYXR0ZXJuLmlzV2lsZGNhcmQoKSkgewotCQluZXdQYXR0ZXJucy5hZGRFbGVtZW50KHBhdHRlcm4pOwotCSAgICB9Ci0JICAgIC8vIFNldCB0ZW1wbGF0ZSBhcyBkZWZhdWx0IGlmIGl0cyBwYXR0ZXJuIG1hdGNoZXMgcHVyZWx5IG9uIGtlcm5lbAotCSAgICBlbHNlIHsKLQkJX2RlZmF1bHQgPSBwYXR0ZXJuLmdldFRlbXBsYXRlKCk7Ci0JCS8vIEZvbGxvd2luZyBwYXR0ZXJucyBjYW4gYmUgaWdub3JlZCBzaW5jZSBkZWZhdWx0IGhhcyBwcmlvcml0eQotCQlicmVhazsKLQkgICAgfQotCX0KLQlfcGF0dGVybnMgPSBuZXdQYXR0ZXJuczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zLCBieSByZWZlcmVuY2UsIHRoZSB0ZW1wbGF0ZXMgdGhhdCBhcmUgaW5jbHVkZWQgaW4gdGhpcyB0ZXN0Ci0gICAgICogc2VxdWVuY2UuIFJlbWVtYmVyIHRoYXQgYSBzaW5nbGUgdGVtcGxhdGUgY2FuIG9jY3VyIGluIHNldmVyYWwgdGVzdAotICAgICAqIHNlcXVlbmNlcyBpZiBpdHMgcGF0dGVybiBpcyBhIHVuaW9uIChleC4gbWF0Y2g9IkEvQiB8IEEvQyIpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGZpbmRUZW1wbGF0ZXMoRGljdGlvbmFyeSB0ZW1wbGF0ZXMpIHsKLQlpZiAoX2RlZmF1bHQgIT0gbnVsbCkKLQkgICAgdGVtcGxhdGVzLnB1dChfZGVmYXVsdCwgdGhpcyk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBfcGF0dGVybnMuc2l6ZSgpOyBpKyspIHsKLQkgICAgZmluYWwgTG9jYXRpb25QYXRoUGF0dGVybiBwYXR0ZXJuID0KLQkJKExvY2F0aW9uUGF0aFBhdHRlcm4pX3BhdHRlcm5zLmVsZW1lbnRBdChpKTsKLQkgICAgdGVtcGxhdGVzLnB1dChwYXR0ZXJuLmdldFRlbXBsYXRlKCksIHRoaXMpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGluc3RydWN0aW9uIGhhbmRsZSB0byBhIHRlbXBsYXRlJ3MgY29kZS4gVGhpcyBpcyB1c2VkIHdoZW4KLSAgICAgKiBhIHNpbmdsZSB0ZW1wbGF0ZSBvY2N1cnMgaW4gc2V2ZXJhbCB0ZXN0IHNlcXVlbmNlczsgdGhhdCBpcywgaWYgaXRzCi0gICAgICogcGF0dGVybiBpcyBhIHVuaW9uIG9mIHBhdHRlcm5zIChleC4gbWF0Y2g9IkEvQiB8IEEvQyIpLgotICAgICAqLwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb25IYW5kbGUgZ2V0VGVtcGxhdGVIYW5kbGUoVGVtcGxhdGUgdGVtcGxhdGUpIHsKLQlyZXR1cm4gKEluc3RydWN0aW9uSGFuZGxlKV9tb2RlLmdldFRlbXBsYXRlSW5zdHJ1Y3Rpb25IYW5kbGUodGVtcGxhdGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgcGF0dGVybiBuIGluIHRoaXMgdGVzdCBzZXF1ZW5jZQotICAgICAqLwotICAgIHByaXZhdGUgTG9jYXRpb25QYXRoUGF0dGVybiBnZXRQYXR0ZXJuKGludCBuKSB7Ci0JcmV0dXJuIChMb2NhdGlvblBhdGhQYXR0ZXJuKV9wYXR0ZXJucy5lbGVtZW50QXQobik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29waWxlIHRoZSBjb2RlIGZvciB0aGlzIHRlc3Qgc2VxdWVuY2UuIFRoZSBjb2RlIHdpbGwgZmlyc3QgdGVzdCBmb3IKLSAgICAgKiB0aGUgcGF0dGVybiB3aXRoIHRoZSBoaWdoZXN0IHByaW9yaXR5LCB0aGVuIGdvIG9uIHRvIHRoZSBuZXh0IG9uZXMsCi0gICAgICogdW50aWwgaXQgaGl0cyBvciBmaW5kcyB0aGUgZGVmYXVsdCB0ZW1wbGF0ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb25IYW5kbGUgY29tcGlsZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sCi0JCQkJICAgICBJbnN0cnVjdGlvbkhhbmRsZSBjb250aW51YXRpb24pIHsKLQotCWZpbmFsIGludCBjb3VudCA9IF9wYXR0ZXJucy5zaXplKCk7Ci0KLQkvLyBFWiBEQyBpZiB0aGVyZSBpcyBvbmx5IG9uZSAoZGVmYXVsdCkgcGF0dGVybgotCWlmIChjb3VudCA9PSAwKSBnZXRUZW1wbGF0ZUhhbmRsZShfZGVmYXVsdCk7Ci0KLQkvLyBUaGUgJ2ZhaWwnIGluc3RydWN0aW9uIGhhbmRsZSByZXByZXNlbnRzIGEgYnJhbmNoIHRvIGdvIHRvIHdoZW4KLQkvLyB0ZXN0IGZhaWxzLiBJdCBpcyB1cGRhdGVkIGluIGVhY2ggaXRlcmF0aW9uLCBzbyB0aGF0IHRoZSB0ZXN0cwotCS8vIGFyZSBsaW5rZWQgdG9nZXRoZXIgaW4gdGhlICBpZi1lbHNlaWYtZWxzZWlmLWVsc2UgZmFzaGlvbi4KLQlJbnN0cnVjdGlvbkhhbmRsZSBmYWlsOwotCi0JLy8gSW5pdGlhbGl6ZSAnZmFpbCcgdG8gZWl0aGVyIHRoZSBjb2RlIGZvciB0aGUgZGVmYXVsdCB0ZW1wbGF0ZQotCWlmIChfZGVmYXVsdCAhPSBudWxsKQotCSAgICBmYWlsID0gZ2V0VGVtcGxhdGVIYW5kbGUoX2RlZmF1bHQpOwotCS8vIC4ub3IgaWYgdGhhdCBkb2VzIG5vdCBleGlzdCwgdG8gYSBsb2NhdGlvbiBzZXQgYnkgdGhlIGNhbGxlci4KLQllbHNlCi0JICAgIGZhaWwgPSBjb250aW51YXRpb247Ci0KLQlmb3IgKGludCBuID0gKGNvdW50IC0gMSk7IG4gPj0gMDsgbi0tKSB7Ci0JICAgIGZpbmFsIExvY2F0aW9uUGF0aFBhdHRlcm4gcGF0dGVybiA9IGdldFBhdHRlcm4obik7Ci0JICAgIGZpbmFsIFRlbXBsYXRlIHRlbXBsYXRlID0gcGF0dGVybi5nZXRUZW1wbGF0ZSgpOwotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkgICAgLy8gUGF0dGVybnMgZXhwZWN0IGN1cnJlbnQgbm9kZSBvbiB0b3Agb2Ygc3RhY2sKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkQ3VycmVudE5vZGUoKSk7Ci0JICAgIC8vIEFwcGx5IHRoZSB0ZXN0LWNvZGUgY29tcGlsZWQgZm9yIHRoZSBwYXR0ZXJuCi0JICAgIGlsLmFwcGVuZChwYXR0ZXJuLmNvbXBpbGUoY2xhc3NHZW4sIG1ldGhvZEdlbikpOwotCi0JICAgIC8vIE9uIHN1Y2Nlc3MgYnJhbmNoIHRvIHRoZSB0ZW1wbGF0ZSBjb2RlCi0JICAgIGZpbmFsIEluc3RydWN0aW9uSGFuZGxlIGd0bXBsID0gZ2V0VGVtcGxhdGVIYW5kbGUodGVtcGxhdGUpOwotCSAgICBmaW5hbCBJbnN0cnVjdGlvbkhhbmRsZSBzdWNjZXNzID0gaWwuYXBwZW5kKG5ldyBHT1RPX1coZ3RtcGwpKTsKLQkgICAgcGF0dGVybi5iYWNrUGF0Y2hUcnVlTGlzdChzdWNjZXNzKTsKLQkgICAgcGF0dGVybi5iYWNrUGF0Y2hGYWxzZUxpc3QoZmFpbCk7Ci0KLQkgICAgLy8gV2UncmUgd29ya2luZyBiYWNrd2FyZHMgaGVyZS4gVGhlIG5leHQgcGF0dGVybidzICdmYWlsJyB0YXJnZXQKLQkgICAgLy8gaXMgdGhpcyBwYXR0ZXJuJ3MgZmlyc3QgaW5zdHJ1Y3Rpb24KLQkgICAgZmFpbCA9IGlsLmdldFN0YXJ0KCk7Ci0KLQkgICAgLy8gQXBwZW5kIGV4aXN0aW5nIGluc3RydWN0aW9uIGxpc3QgdG8gdGhlIGVuZCBvZiB0aGlzIG9uZQotCSAgICBpZiAoX2luc3RydWN0aW9uTGlzdCAhPSBudWxsKSBpbC5hcHBlbmQoX2luc3RydWN0aW9uTGlzdCk7Ci0KLQkgICAgLy8gU2V0IGN1cnJlbnQgaW5zdHJ1Y3Rpb24gbGlzdCB0byBiZSB0aGlzIG9uZS4KLQkgICAgX2luc3RydWN0aW9uTGlzdCA9IGlsOwotCX0KLQlyZXR1cm4gZmFpbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGZvciB0aGlzIHRlc3Qgc2VxdWVuY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb25MaXN0IGdldEluc3RydWN0aW9uTGlzdCgpIHsKLQlyZXR1cm4gX2luc3RydWN0aW9uTGlzdDsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1RleHQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1RleHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTM1OGRmZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9UZXh0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDggKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBUZXh0IGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICAgIHByaXZhdGUgU3RyaW5nIF90ZXh0OwotICAgIHByaXZhdGUgYm9vbGVhbiBfZXNjYXBpbmcgPSB0cnVlOwotCi0gICAgcHVibGljIFRleHQoKSB7fQotCi0gICAgcHVibGljIFRleHQoU3RyaW5nIHRleHQpIHsKLQlfdGV4dCA9IHRleHQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCkgewotCXJldHVybiBfdGV4dDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0KSB7Ci0JaWYgKF90ZXh0ID09IG51bGwpCi0JICAgIF90ZXh0ID0gdGV4dDsKLQllbHNlCi0JICAgIF90ZXh0ID0gX3RleHQgKyB0ZXh0OyAvLyBjb21wbGlhdGlvbiBwaGFzZSwgc28gT0sgKHdlbGwsIG1heWJlIG5vdCkKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIlRleHQiKTsKLQlpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQlVdGlsLnByaW50bG4oX3RleHQpOwotICAgIH0KLQkJCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBzdHIgPSBnZXRBdHRyaWJ1dGUoImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIik7Ci0JaWYgKChzdHIgIT0gbnVsbCkgJiYgKHN0ci5lcXVhbHMoInllcyIpKSkgewotCSAgICBfZXNjYXBpbmcgPSBmYWxzZTsKLQl9Ci0JcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgYm9vbGVhbiBjb250ZXh0RGVwZW5kZW50KCkgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaWYgKF90ZXh0ICE9IG51bGwgJiYgX3RleHQubGVuZ3RoKCkgPiAwKSB7Ci0JICAgIC8vIFR1cm4gb2ZmIGNoYXJhY3RlciBlc2NhcGluZyBpZiBzbyBpcyB3YW50ZWQuCi0JICAgIGZpbmFsIGludCBlc2MgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKE9VVFBVVF9IQU5ETEVSLAotCQkJCQkJICAgICAgInNldEVzY2FwaW5nIiwgIihaKVoiKTsKLQkgICAgLy8gc2V0IGVzY2FwaW5nIHZhbHVlIGluIG91dHB1dCBoYW5kbGVyIAotCSAgICBpZiAoX2VzY2FwaW5nKSB7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsdHJ1ZSkpOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShlc2MsIDIpKTsKLQkgICAgfSBlbHNlIHsKLQkJaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgZmFsc2UpKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZXNjLCAyKSk7Ci0JICAgIH0KLQotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdGV4dCkpOwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCQkgQ0hBUkFDVEVSU1csCi0JCQkJCQkJIENIQVJBQ1RFUlNXX1NJRykpKTsKLQotCSAgICAvLyBSZXN0b3JlIGNoYXJhY3RlciBlc2NhcGluZyBzZXR0aW5nIHRvIHdoYXRldmVyIGl0IHdhcy4KLQkgICAgLy8gTm90ZTogc2V0RXNjYXBpbmcoYm9vbCkgcmV0dXJucyB0aGUgb3JpZ2luYWwgKG9sZCkgdmFsdWUKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQkgICAgaWwuYXBwZW5kKFNXQVApOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShlc2MsIDIpKTsKLQkgICAgaWwuYXBwZW5kKFBPUCk7Ci0JfQotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1RvcExldmVsRWxlbWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVG9wTGV2ZWxFbGVtZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIwZWI1OGEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVG9wTGV2ZWxFbGVtZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlQ2hlY2tFcnJvcjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1jbGFzcyBUb3BMZXZlbEVsZW1lbnQgZXh0ZW5kcyBTeW50YXhUcmVlTm9kZSB7Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlIGNoZWNrIGFsbCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIHRoaXMgbm9kZSBpbnRvIEpWTSBieXRlY29kZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZ2V0UGFyc2VyKCkubm90WWV0SW1wbGVtZW50ZWQoInRvcC1sZXZlbC1lbGVtZW50OiAiICsgZ2V0Q2xhc3MoKSk7Ci0gICAgfQotCQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZSB0aGlzIG5vZGUgaW50byBhIGZyZXNoIGluc3RydWN0aW9uIGxpc3QuCi0gICAgICogVGhlIG9yaWdpbmFsIGluc3RydWN0aW9uIGxpc3QgaXMgc2F2ZWQgYW5kIHJlc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBJbnN0cnVjdGlvbkxpc3QgY29tcGlsZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IHJlc3VsdCwgc2F2ZSA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQltZXRob2RHZW4uc2V0SW5zdHJ1Y3Rpb25MaXN0KHJlc3VsdCA9IG5ldyBJbnN0cnVjdGlvbkxpc3QoKSk7Ci0JdHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCW1ldGhvZEdlbi5zZXRJbnN0cnVjdGlvbkxpc3Qoc2F2ZSk7Ci0JcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIlRvcExldmVsRWxlbWVudCIpOwotCWRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1RyYW5zbGV0T3V0cHV0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9UcmFuc2xldE91dHB1dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNWU5OWQ5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1RyYW5zbGV0T3V0cHV0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNTUgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFRyYW5zbGV0T3V0cHV0IGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9maWxlbmFtZTsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBNSVNTSU5HX0ZJTEVfQVRUUiA9Ci0JIlRoZSA8eHNsdGM6b3V0cHV0PiBlbGVtZW50IHJlcXVpcmVzIGEgJ2ZpbGUnIGF0dHJpYnV0ZS4iOwotCi0gICAgLyoqCi0gICAgICogRGlzcGxheXMgdGhlIGNvbnRlbnRzIG9mIHRoaXMgPHhzbHRjOm91dHB1dD4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIlRyYW5zbGV0T3V0cHV0OiAiICsgX2ZpbGVuYW1lKTsKLSAgICB9Ci0JCQotICAgIC8qKgotICAgICAqIFBhcnNlIHRoZSBjb250ZW50cyBvZiB0aGlzIDx4c2x0YzpvdXRwdXQ+IGVsZW1lbnQuIFRoZSBvbmx5IGF0dHJpYnV0ZQotICAgICAqIHdlIHJlY29nbmlzZSBpcyB0aGUgJ2ZpbGUnIGF0dHJpYnV0ZSB0aGF0IGNvbnRhaW5zIHRlaCBvdXRwdXQgZmlsZW5hbWUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JLy8gR2V0IHRoZSBvdXRwdXQgZmlsZW5hbWUgZnJvbSB0aGUgJ2ZpbGUnIGF0dHJpYnV0ZQotCVN0cmluZyBmaWxlbmFtZSA9IGdldEF0dHJpYnV0ZSgiZmlsZSIpOwotCi0JLy8gVmVyaWZ5IHRoYXQgdGhlIGZpbGVuYW1lIGlzIGluIGZhY3Qgc2V0Ci0JaWYgKChmaWxlbmFtZSA9PSBudWxsKSB8fCAoZmlsZW5hbWUuZXF1YWxzKEVNUFRZU1RSSU5HKSkpIHsKLQkgICAgZmluYWwgRXJyb3JNc2cgbXNnID0gbmV3IEVycm9yTXNnKE1JU1NJTkdfRklMRV9BVFRSKTsKLQkgICAgcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5FUlJPUiwgbXNnKTsKLQl9Ci0KLQkvLyBTYXZlIGZpbGVuYW1lIGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZQotCV9maWxlbmFtZSA9IEF0dHJpYnV0ZVZhbHVlLmNyZWF0ZSh0aGlzLCBmaWxlbmFtZSwgcGFyc2VyKTsKLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIFR5cGUgY2hlY2tzIHRoZSAnZmlsZScgYXR0cmlidXRlIChtdXN0IGJlIGFibGUgdG8gY29udmVydCBpdCB0byBhIHN0cikuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBUeXBlIHR5cGUgPSBfZmlsZW5hbWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKHR5cGUgaW5zdGFuY2VvZiBTdHJpbmdUeXBlID09IGZhbHNlKSB7Ci0JICAgIF9maWxlbmFtZSA9IG5ldyBDYXN0RXhwcihfZmlsZW5hbWUsIFR5cGUuU3RyaW5nKTsKLQl9Ci0JdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBDb21waWxlIGNvZGUgdGhhdCBvcGVucyB0aGUgZ2l2ZSBmaWxlIGZvciBvdXRwdXQsIGR1bXBzIHRoZSBjb250ZW50cyBvZgotICAgICAqIHRoZSBlbGVtZW50IHRvIHRoZSBmaWxlLCB0aGVuIGNsb3NlcyB0aGUgZmlsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gU2F2ZSB0aGUgY3VycmVudCBvdXRwdXQgaGFuZGxlciBvbiB0aGUgc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCQotCWZpbmFsIGludCBvcGVuID0gIGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCSAgICJvcGVuT3V0cHV0SGFuZGxlciIsCi0JCQkJCSAgICIoIitTVFJJTkdfU0lHKyIpIisKLQkJCQkJICAgVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0KLQlmaW5hbCBpbnQgY2xvc2UgPSAgY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJICAgICJjbG9zZU91dHB1dEhhbmRsZXIiLAotCQkJCQkgICAgIigiK1RSQU5TTEVUX09VVFBVVF9TSUcrIilWIik7Ci0KLQkvLyBDcmVhdGUgdGhlIG5ldyBvdXRwdXQgaGFuZGxlciAobGVhdmUgaXQgb24gc3RhY2spCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlfZmlsZW5hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChvcGVuKSk7Ci0KLQkvLyBPdmVyd3JpdGUgY3VycmVudCBoYW5kbGVyCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0JCi0JLy8gVHJhbnNsYXRlIGNvbnRlbnRzIHdpdGggc3Vic3RpdHV0ZWQgaGFuZGxlcgotCXRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCi0JLy8gQ2xvc2UgdGhlIG91dHB1dCBoYW5kbGVyIChjbG9zZSBmaWxlKQotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY2xvc2UpKTsKLQotCS8vIFJlc3RvcmUgb2xkIG91dHB1dCBoYW5kbGVyIGZyb20gc3RhY2sKLQlpbC5hcHBlbmQobWV0aG9kR2VuLnN0b3JlSGFuZGxlcigpKTsKLSAgICB9Ci19Ci0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1VuYXJ5T3BFeHByLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbmFyeU9wRXhwci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZWYyYzc4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1VuYXJ5T3BFeHByLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBVbmFyeU9wRXhwciBleHRlbmRzIEV4cHJlc3Npb24gewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfbGVmdDsKLQkKLSAgICBwdWJsaWMgVW5hcnlPcEV4cHIoRXhwcmVzc2lvbiBsZWZ0KSB7Ci0JKF9sZWZ0ID0gbGVmdCkuc2V0UGFyZW50KHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0Jc3VwZXIuc2V0UGFyc2VyKHBhcnNlcik7Ci0JX2xlZnQuc2V0UGFyc2VyKHBhcnNlcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JZmluYWwgVHlwZSB0bGVmdCA9IF9sZWZ0LnR5cGVDaGVjayhzdGFibGUpOyAKLQlmaW5hbCBNZXRob2RUeXBlIHB0eXBlID0gbG9va3VwUHJpbW9wKHN0YWJsZSwgInUtIiwKLQkJCQkJICAgICAgbmV3IE1ldGhvZFR5cGUoVHlwZS5Wb2lkLAotCQkJCQkJCSAgICAgdGxlZnQpKTsgCi0JCi0JaWYgKHB0eXBlICE9IG51bGwpIHsKLQkgICAgZmluYWwgVHlwZSBhcmcxID0gKFR5cGUpIHB0eXBlLmFyZ3NUeXBlKCkuZWxlbWVudEF0KDApOwotCSAgICBpZiAoIWFyZzEuaWRlbnRpY2FsVG8odGxlZnQpKSB7Ci0JCV9sZWZ0ID0gbmV3IENhc3RFeHByKF9sZWZ0LCBhcmcxKTsKLQkgICAgfQotCSAgICByZXR1cm4gX3R5cGUgPSBwdHlwZS5yZXN1bHRUeXBlKCk7Ci0JfQotCi0JdGhyb3cgbmV3IFR5cGVDaGVja0Vycm9yKHRoaXMpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJ1LSIgKyAnKCcgKyBfbGVmdCArICcpJzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JX2xlZnQudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCWlsLmFwcGVuZChfdHlwZS5ORUcoKSk7Ci0gICAgfQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbmlvblBhdGhFeHByLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbmlvblBhdGhFeHByLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNiZDJkMzMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVW5pb25QYXRoRXhwci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkF4aXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBVbmlvblBhdGhFeHByIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBFeHByZXNzaW9uIF9wYXRoRXhwcjsKLSAgICBwcml2YXRlIGZpbmFsIEV4cHJlc3Npb24gX3Jlc3Q7Ci0KLSAgICAvLyBsaW5lYXJpemF0aW9uIGZvciB0b3AgbGV2ZWwgVW5pb25QYXRoRXhwcnMKLSAgICBwcml2YXRlIEV4cHJlc3Npb25bXSBfY29tcG9uZW50czsKLSAgICAKLSAgICBwdWJsaWMgVW5pb25QYXRoRXhwcihFeHByZXNzaW9uIHBhdGhFeHByLCBFeHByZXNzaW9uIHJlc3QpIHsKLQlfcGF0aEV4cHIgPSBwYXRoRXhwcjsKLQlfcmVzdCAgICAgPSByZXN0OwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoUGFyc2VyIHBhcnNlcikgewotCXN1cGVyLnNldFBhcnNlcihwYXJzZXIpOwotCS8vIGZpbmQgYWxsIGV4cHJlc3Npb25zIGluIHRoaXMgVW5pb24KLQlmaW5hbCBWZWN0b3IgY29tcG9uZW50cyA9IG5ldyBWZWN0b3IoKTsKLQlmbGF0dGVuKGNvbXBvbmVudHMpOwotCWZpbmFsIGludCBzaXplID0gY29tcG9uZW50cy5zaXplKCk7Ci0JX2NvbXBvbmVudHMgPSAoRXhwcmVzc2lvbltdKWNvbXBvbmVudHMudG9BcnJheShuZXcgRXhwcmVzc2lvbltzaXplXSk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLQkgICAgX2NvbXBvbmVudHNbaV0uc2V0UGFyc2VyKHBhcnNlcik7Ci0JICAgIF9jb21wb25lbnRzW2ldLnNldFBhcmVudCh0aGlzKTsKLQkgICAgaWYgKF9jb21wb25lbnRzW2ldIGluc3RhbmNlb2YgU3RlcCkgewotCQlTdGVwIHN0ZXAgPSAoU3RlcClfY29tcG9uZW50c1tpXTsKLQkJaWYgKChzdGVwLmdldEF4aXMoKSA9PSBBeGlzLkFUVFJJQlVURSkgfHwKLQkJICAgIChzdGVwLmdldE5vZGVUeXBlKCkgPT0gRE9NLkFUVFJJQlVURSkpIHsKLQkJICAgIF9jb21wb25lbnRzW2ldID0gX2NvbXBvbmVudHNbMF07Ci0JCSAgICBfY29tcG9uZW50c1swXSA9IHN0ZXA7Ci0JCX0KLQkgICAgfQotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBpbnQgbGVuZ3RoID0gX2NvbXBvbmVudHMubGVuZ3RoOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkgICAgaWYgKF9jb21wb25lbnRzW2ldLnR5cGVDaGVjayhzdGFibGUpICE9IFR5cGUuTm9kZVNldCkgewotCQlfY29tcG9uZW50c1tpXSA9IG5ldyBDYXN0RXhwcihfY29tcG9uZW50c1tpXSwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgfQotCX0KLQlyZXR1cm4gX3R5cGUgPSBUeXBlLk5vZGVTZXQ7CQotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJ1bmlvbigiICsgX3BhdGhFeHByICsgIiwgIiArIF9yZXN0ICsgJyknOwotICAgIH0KLQkKLSAgICBwcml2YXRlIHZvaWQgZmxhdHRlbihWZWN0b3IgY29tcG9uZW50cykgewotCWNvbXBvbmVudHMuYWRkRWxlbWVudChfcGF0aEV4cHIpOwotCWlmIChfcmVzdCAhPSBudWxsKSB7Ci0JICAgIGlmIChfcmVzdCBpbnN0YW5jZW9mIFVuaW9uUGF0aEV4cHIpIHsKLQkJKChVbmlvblBhdGhFeHByKV9yZXN0KS5mbGF0dGVuKGNvbXBvbmVudHMpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQljb21wb25lbnRzLmFkZEVsZW1lbnQoX3Jlc3QpOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb24gYWRkSXRlcmF0b3IgPQotCSAgICBuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFVOSU9OX0lURVJBVE9SX0NMQVNTLAotCQkJCQkgICAgICAgQUREX0lURVJBVE9SLAotCQkJCQkgICAgICAgQUREX0lURVJBVE9SX1NJRykpOwotCS8vIGNyZWF0ZSBuZXcgVW5pb25JdGVyYXRvcgotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhVTklPTl9JVEVSQVRPUl9DTEFTUykpKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGNwZy5hZGRNZXRob2RyZWYoVU5JT05fSVRFUkFUT1JfQ0xBU1MsCi0JCQkJCQkgICAgICI8aW5pdD4iLAotCQkJCQkJICAgICAiKCIKLQkJCQkJCSAgICAgKyBET01fSU5URl9TSUcKLQkJCQkJCSAgICAgKyAiKVYiKSkpOwotCS8vIFVuaW9uSXRlcmF0b3IgaXMgb24gdGhlIHN0YWNrCi0JZmluYWwgaW50IGxlbmd0aCA9IF9jb21wb25lbnRzLmxlbmd0aDsKLQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JICAgIF9jb21wb25lbnRzW2ldLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgaWwuYXBwZW5kKGFkZEl0ZXJhdG9yKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVW5wYXJzZWRFbnRpdHlVcmlDYWxsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbnBhcnNlZEVudGl0eVVyaUNhbGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDIwOGE5Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbnBhcnNlZEVudGl0eVVyaUNhbGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFVucGFyc2VkRW50aXR5VXJpQ2FsbCBleHRlbmRzIEZ1bmN0aW9uQ2FsbCB7Ci0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF9lbnRpdHk7Ci0KLSAgICBwdWJsaWMgVW5wYXJzZWRFbnRpdHlVcmlDYWxsKFFOYW1lIGZuYW1lLCBWZWN0b3IgYXJndW1lbnRzKSB7Ci0Jc3VwZXIoZm5hbWUsIGFyZ3VtZW50cyk7Ci0JX2VudGl0eSA9IGFyZ3VtZW50KCk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlmaW5hbCBUeXBlIGVudGl0eSA9IF9lbnRpdHkudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKGVudGl0eSBpbnN0YW5jZW9mIFN0cmluZ1R5cGUgPT0gZmFsc2UpIHsKLQkgICAgX2VudGl0eSA9IG5ldyBDYXN0RXhwcihfZW50aXR5LCBUeXBlLlN0cmluZyk7Ci0JfQotCXJldHVybiBfdHlwZSA9IFR5cGUuU3RyaW5nOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCS8vIEZlY2sgdGhlIHRoaXMgcG9pbnRlciBvbiB0aGUgc3RhY2suLi4KLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCS8vIC4uLnRoZW4gdGhlIGVudGl0eSBuYW1lLi4uCi0JX2VudGl0eS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JLy8gLi4udG8gZ2V0IHRoZSB2YWx1ZSBmcm9tIHRoZSBoYXNodGFibGUgaW4gQWJzdHJhY3RUcmFuc2xldC4KLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCSAgICAgImdldFVucGFyc2VkRW50aXR5IiwKLQkJCQkJCSAgICAgIihMamF2YS9sYW5nL1N0cmluZzspIisKLQkJCQkJCSAgICAgIkxqYXZhL2xhbmcvU3RyaW5nOyIpKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVW5zdXBwb3J0ZWRFbGVtZW50LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbnN1cHBvcnRlZEVsZW1lbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjQ1NzY1MC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9VbnN1cHBvcnRlZEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2OCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBVbnN1cHBvcnRlZEVsZW1lbnQgZXh0ZW5kcyBTeW50YXhUcmVlTm9kZSB7Ci0KLSAgICBwcml2YXRlIEZhbGxiYWNrIF9mYWxsYmFjayA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX21lc3NhZ2UgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogQmFzaWMgY29uc3V0cmNvciAtIHN0b3JlcyBlbGVtZW50IHVyaS9wcmVmaXgvbG9jYWxuYW1lCi0gICAgICovCi0gICAgcHVibGljIFVuc3VwcG9ydGVkRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgbG9jYWwpIHsKLQlzdXBlcih1cmksIHByZWZpeCwgbG9jYWwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZXJlIGFyZSBkaWZmZXJlbnQgY2F0ZWdvcmllcyBvZiB1bnN1cHBvcnRlZCBlbGVtZW50cyAoYmVsaWV2ZSBpdAotICAgICAqIG9yIG5vdCk6IHRoZXJlIGFyZSBlbGVtZW50cyB3aXRoaW4gdGhlIFhTTFQgbmFtZXNwYWNlICh0aGVzZSB3b3VsZAotICAgICAqIGJlIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCB5ZXQgaW1wbGVtZW50ZWQpLCB0aGVyZSBhcmUgZXh0ZW5zaW9ucyBvZgotICAgICAqIG90aGVyIFhTTFQgcHJvY2Vzc29ycyBhbmQgdGhlcmUgYXJlIHVucmVjb2duaXNlZCBleHRlbnNpb24gZWxlbWVudHMKLSAgICAgKiBvZiB0aGlzIFhTTFQgcHJvY2Vzc29yLiBUaGUgZXJyb3IgbWVzc2FnZSBwYXNzZWQgdG8gdGhpcyBtZXRob2QKLSAgICAgKiBzaG91bGQgZGVzY3JpYmUgdGhlIHVuc3VwcG9ydGVkIGVsZW1lbnQgaXRzZWxmIGFuZCB3aGF0IGNhdGVnb3J5Ci0gICAgICogdGhlIGVsZW1lbnQgYmVsb25ncyBpbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRFcnJvck1lc3NhZ2UoU3RyaW5nIG1lc3NhZ2UpIHsKLQlfbWVzc2FnZSA9IG1lc3NhZ2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRGlzcGxheXMgdGhlIGNvbnRlbnRzIG9mIHRoaXMgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVV0aWwucHJpbnRsbigiVW5zdXBwb3J0ZWQgZWxlbWVudCA9ICIgKyBfcW5hbWUuZ2V0TmFtZXNwYWNlKCkgKwotCQkgICAgICI6IiArIF9xbmFtZS5nZXRMb2NhbFBhcnQoKSk7Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBTY2FuIGFsbCBkZXNjZW5kYW50cyBhbmQgZmluZCB0aGUgZmlyc3QgeHNsOmZhbGxiYWNrIGVsZW1lbnQgKGlmIGFueSkKLSAgICAgKi8KLSAgICBwcml2YXRlIFN5bnRheFRyZWVOb2RlIGZpbmRGYWxsYmFjayhTeW50YXhUcmVlTm9kZSByb290KSB7Ci0KLQkvLyBGaXJzdCBjaGVjayBpZiB0aGlzIGVsZW1lbnQgZXhpc3RzIGF0IGFsbAotCWlmIChyb290ID09IG51bGwpIHJldHVybiBudWxsOwotCi0JLy8gVGhlbiBjaGVjayBpZiB0aGUgZWxlbWVudCBpcyBhbiB4c2w6ZmFsbGJhY2sgZWxlbWVudAotCWlmIChyb290IGluc3RhbmNlb2YgRmFsbGJhY2spIHJldHVybigoRmFsbGJhY2spcm9vdCk7Ci0KLQkvLyBUaGVuIHRyYXZlcnNlIGFsbCBjaGlsZCBlbGVtZW50cwotCVZlY3RvciBjaGlsZHJlbiA9IHJvb3QuZ2V0Q29udGVudHMoKTsKLQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgY291bnQgPSBjaGlsZHJlbi5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQlTeW50YXhUcmVlTm9kZSBjaGlsZCA9IChTeW50YXhUcmVlTm9kZSljaGlsZHJlbi5lbGVtZW50QXQoaSk7Ci0JCVN5bnRheFRyZWVOb2RlIG5vZGUgPSBmaW5kRmFsbGJhY2soY2hpbGQpOwotCQlpZiAobm9kZSAhPSBudWxsKSByZXR1cm4gbm9kZTsKLQkgICAgfQotCX0KLQlyZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaW5kIGFueSBmYWxsYmFjayBpbiB0aGUgZGVzY2VuZGFudCBub2RlczsgdGhlbiBhY3RpdmF0ZSAmIHBhcnNlIGl0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JX2ZhbGxiYWNrID0gKEZhbGxiYWNrKWZpbmRGYWxsYmFjayh0aGlzKTsKLQlpZiAoX2ZhbGxiYWNrICE9IG51bGwpIHsKLQkgICAgX2ZhbGxiYWNrLmFjdGl2YXRlKCk7Ci0JICAgIF9mYWxsYmFjay5wYXJzZUNvbnRlbnRzKHBhcnNlcik7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJ1biB0eXBlIGNoZWNrIG9uIHRoZSBmYWxsYmFjayBlbGVtZW50IChpZiBhbnkpLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKF9mYWxsYmFjayA9PSBudWxsKSB7Ci0JICAgIHRocm93IG5ldyBUeXBlQ2hlY2tFcnJvcihuZXcgRXJyb3JNc2coX21lc3NhZ2UpKTsKLQl9Ci0JcmV0dXJuKF9mYWxsYmFjay50eXBlQ2hlY2soc3RhYmxlKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlIHRoZSBmYWxsYmFjayBlbGVtZW50IChpZiBhbnkpLiBUaGUgc3R5bGVzaGVldCBzaG91bGQgbmV2ZXIKLSAgICAgKiBiZSBjb21waWxlZCBpZiBhbiB1bnN1cHBvcnRlZCBlbGVtZW50IGRvZXMgbm90IGhhdmUgYSBmYWxsYmFjayBlbGVtZW50LAotICAgICAqIHNvIHRoaXMgbWV0aG9kIHNob3VsZCBuZXZlciBiZSBjYWxsZWQgdW5sZXNzIF9mYWxsYmFjayAhPSBudWxsCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JaWYgKF9mYWxsYmFjayAhPSBudWxsKSBfZmFsbGJhY2sudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1VzZUF0dHJpYnV0ZVNldHMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1VzZUF0dHJpYnV0ZVNldHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWNlNmJhZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Vc2VBdHRyaWJ1dGVTZXRzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDggKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgVXNlQXR0cmlidXRlU2V0cyBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIC8vIE9ubHkgZXJyb3IgdGhhdCBjYW4gb2NjdXI6Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEFUVFJfU0VUX05PVF9GT1VORCA9Ci0JIkF0dGVtcHRpbmcgdG8gdXNlIG5vbi1leGlzdGluZyBhdHRyaWJ1dGUgc2V0OiAiOwotCi0gICAgLy8gQ29udGFpbnMgdGhlIG5hbWVzIG9mIGFsbCByZWZlcmVuY2VzIGF0dHJpYnV0ZSBzZXRzCi0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgX3NldHMgPSBuZXcgVmVjdG9yKDIpOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0dXIgLSBkZWZpbmUgaW5pdGlhbCBhdHRyaWJ1dGUgc2V0cyB0byB1c2UKLSAgICAgKi8KLSAgICBwdWJsaWMgVXNlQXR0cmlidXRlU2V0cyhTdHJpbmcgc2V0TmFtZXMsIFBhcnNlciBwYXJzZXIpIHsKLQlzZXRQYXJzZXIocGFyc2VyKTsKLQlhZGRBdHRyaWJ1dGVTZXRzKHNldE5hbWVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBtYWRlIHB1YmxpYyB0byBlbmFibGUgYW4gQXR0cmlidXRlU2V0IG9iamVjdCB0byBtZXJnZQotICAgICAqIGl0c2VsZiB3aXRoIGFub3RoZXIgQXR0cmlidXRlU2V0IChpbmNsdWRpbmcgYW55IG90aGVyIEF0dHJpYnV0ZVNldHMKLSAgICAgKiB0aGUgdHdvIG1heSBpbmhlcml0IGZyb20pLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZVNldHMoU3RyaW5nIHNldE5hbWVzKSB7Ci0JaWYgKChzZXROYW1lcyAhPSBudWxsKSAmJiAoIXNldE5hbWVzLmVxdWFscyhDb25zdGFudHMuRU1QVFlTVFJJTkcpKSkgewotCSAgICBmaW5hbCBTdHJpbmdUb2tlbml6ZXIgdG9rZW5zID0gbmV3IFN0cmluZ1Rva2VuaXplcihzZXROYW1lcyk7Ci0JICAgIHdoaWxlICh0b2tlbnMuaGFzTW9yZVRva2VucygpKSB7Ci0JCWZpbmFsIFFOYW1lIHFuYW1lID0gZ2V0UGFyc2VyKCkuZ2V0UU5hbWUodG9rZW5zLm5leHRUb2tlbigpKTsKLQkJX3NldHMuYWRkKHFuYW1lKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEbyBuYWRhLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZW5lcmF0ZSBhIGNhbGwgdG8gdGhlIG1ldGhvZCBjb21waWxlZCBmb3IgdGhpcyBhdHRyaWJ1dGUgc2V0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0KLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIFN5bWJvbFRhYmxlIHN5bWJvbFRhYmxlID0gZ2V0UGFyc2VyKCkuZ2V0U3ltYm9sVGFibGUoKTsKLQotCS8vIEdvIHRocm91Z2ggZWFjaCBhdHRyaWJ1dGUgc2V0IGFuZCBnZW5lcmF0ZSBhIG1ldGhvZCBjYWxsCi0JZm9yIChpbnQgaT0wOyBpPF9zZXRzLnNpemUoKTsgaSsrKSB7Ci0JICAgIC8vIEdldCB0aGUgYXR0cmlidXRlIHNldCBuYW1lCi0JICAgIGZpbmFsIFFOYW1lIG5hbWUgPSAoUU5hbWUpX3NldHMuZWxlbWVudEF0KGkpOwotCSAgICAvLyBHZXQgdGhlIEF0dHJpYnV0ZVNldCByZWZlcmVuY2UgZnJvbSB0aGUgc3ltYm9sIHRhYmxlCi0JICAgIGZpbmFsIEF0dHJpYnV0ZVNldCBhdHRycyA9IHN5bWJvbFRhYmxlLmxvb2t1cEF0dHJpYnV0ZVNldChuYW1lKTsKLQkgICAgLy8gQ29tcGlsZSB0aGUgY2FsbCB0byB0aGUgc2V0J3MgbWV0aG9kIGlmIHRoZSBzZXQgZXhpc3RzCi0JICAgIGlmIChhdHRycyAhPSBudWxsKSB7Ci0JCWZpbmFsIFN0cmluZyBtZXRob2ROYW1lID0gYXR0cnMuZ2V0TWV0aG9kTmFtZSgpOwotCQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRJdGVyYXRvcigpKTsKLQkJZmluYWwgaW50IG1ldGhvZCA9IGNwZy5hZGRNZXRob2RyZWYoY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0JCQkJCQkgICAgbWV0aG9kTmFtZSwgQVRUUl9TRVRfU0lHKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKG1ldGhvZCkpOwotCSAgICB9Ci0JICAgIC8vIEdlbmVyYXRlIGFuIGVycm9yIGlmIHRoZSBhdHRyaWJ1dGUgc2V0IGRvZXMgbm90IGV4aXN0Ci0JICAgIGVsc2UgewotCQlmaW5hbCBFcnJvck1zZyBtc2cgPSAgbmV3IEVycm9yTXNnKEFUVFJfU0VUX05PVF9GT1VORCtuYW1lLAotCQkJCQkJICAgZ2V0TGluZU51bWJlcigpKTsKLQkJZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotCSAgICB9Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ZhbHVlT2YuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ZhbHVlT2YuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDcwNTg4YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYWx1ZU9mLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBWYWx1ZU9mIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotICAgIHByaXZhdGUgRXhwcmVzc2lvbiBfc2VsZWN0OwotICAgIHByaXZhdGUgYm9vbGVhbiBfZXNjYXBpbmcgPSB0cnVlOwotCQotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVV0aWwucHJpbnRsbigiVmFsdWVPZiIpOwotCWluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCVV0aWwucHJpbnRsbigic2VsZWN0ICIgKyBfc2VsZWN0LnRvU3RyaW5nKCkpOwotICAgIH0KLQkJCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JX3NlbGVjdCA9IHBhcnNlci5wYXJzZUV4cHJlc3Npb24odGhpcywgInNlbGVjdCIsIG51bGwpOwotCi0gICAgICAgIC8vIG1ha2Ugc3VyZSByZXF1aXJlZCBhdHRyaWJ1dGUocykgaGF2ZSBiZWVuIHNldAotICAgICAgICBpZiAoX3NlbGVjdC5pc0R1bW15KCkpIHsKLQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5OUkVRQVRUUl9FUlIsICJzZWxlY3QiKTsKLQkgICAgcmV0dXJuOwotICAgICAgICB9Ci0gICAgICAgIGZpbmFsIFN0cmluZyBzdHIgPSBnZXRBdHRyaWJ1dGUoImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIik7Ci0JaWYgKChzdHIgIT0gbnVsbCkgJiYgKHN0ci5lcXVhbHMoInllcyIpKSkgX2VzY2FwaW5nID0gZmFsc2U7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlUeXBlIHR5cGUgPSBfc2VsZWN0LnR5cGVDaGVjayhzdGFibGUpOwotCWlmICgodHlwZSAhPSBudWxsKSAmJiAodHlwZS5pZGVudGljYWxUbyhUeXBlLlN0cmluZykgPT0gZmFsc2UpKQotCSAgICBfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuU3RyaW5nKTsKLQlyZXR1cm4gVHlwZS5Wb2lkOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgaW50IHNldEVzY2FwaW5nID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihPVVRQVVRfSEFORExFUiwKLQkJCQkJCQkgICJzZXRFc2NhcGluZyIsIihaKVoiKTsKLQlmaW5hbCBpbnQgY2hhcmFjdGVycyA9IGNwZy5hZGRNZXRob2RyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQlDSEFSQUNURVJTVywKLQkJCQkJCUNIQVJBQ1RFUlNXX1NJRyk7Ci0KLQkvLyBUdXJuIG9mZiBjaGFyYWN0ZXIgZXNjYXBpbmcgaWYgc28gaXMgd2FudGVkLgotCWlmICghX2VzY2FwaW5nKSB7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsZmFsc2UpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0Uoc2V0RXNjYXBpbmcsMikpOwotCX0KLQotCS8vIFRyYW5zbGF0ZSB0aGUgY29udGVudHMuCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQlfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsJCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY2hhcmFjdGVycykpOwotCi0JLy8gUmVzdG9yZSBjaGFyYWN0ZXIgZXNjYXBpbmcgc2V0dGluZyB0byB3aGF0ZXZlciBpdCB3YXMuCi0JaWYgKCFfZXNjYXBpbmcpIHsKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQkgICAgaWwuYXBwZW5kKFNXQVApOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShzZXRFc2NhcGluZywyKSk7Ci0JICAgIGlsLmFwcGVuZChQT1ApOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYXJpYWJsZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVmFyaWFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTE4YWM1OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYXJpYWJsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzAxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBKb2huIEhvd2FyZCA8Sm9obkhAc2NoZW1hc29mdC5jb20+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuRmllbGQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uQXhpczsKLQotZmluYWwgY2xhc3MgVmFyaWFibGUgZXh0ZW5kcyBWYXJpYWJsZUJhc2UgewotCi0gICAgLy8gSW5kZXggb2YgdGhpcyB2YXJpYWJsZSBpbiB0aGUgdmFyaWFibGUgc3RhY2sgcmVsYXRpdmUgdG8gYmFzZSBwdHIKLSAgICBwcml2YXRlIGludCBfc3RhY2tJbmRleCA9IC0xOwotCi0gICAgcHJpdmF0ZSBib29sZWFuIF9lc2NhcGVzOyAvLyAndHJ1ZScgaWYgdGhlIHZhcmlhYmxlJ3MgdmFsdWUgY2FuIGNoYW5nZQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyAndHJ1ZScgaWYgdGhlIHZhcmlhYmxlIHZhbHVlIGNhbiBjaGFuZ2Ugb3ZlciB0aW1lLAotICAgICAqIHN1Y2ggYXMgd2l0aCB2YXJpYmxlcyBpbnNpZGUgYSBmb3ItZWFjaCBsb29wLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVzY2FwZXMoKSB7Ci0JX2VzY2FwZXMgPSB0cnVlOwotCWlmIChfc3RhY2tJbmRleCA9PSAtMSkgeyAvLyB1bmFzc2lnbmVkCi0JICAgIFRlbXBsYXRlIHRlbXBsYXRlID0gZ2V0VGVtcGxhdGUoKTsKLQkgICAgaWYgKHRlbXBsYXRlICE9IG51bGwpIHsKLQkJX3N0YWNrSW5kZXggPSB0ZW1wbGF0ZS5hbGxvY2F0ZUluZGV4KF9uYW1lKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U3RhY2tJbmRleCgpIHsKLQlyZXR1cm4gX3N0YWNrSW5kZXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGNvbnRlbnRzIG9mIHRoZSB2YXJpYWJsZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCS8vIHBhcnNlIGF0dHJpYnV0ZXMgbmFtZSBhbmQgc2VsZWN0IChpZiBwcmVzZW50KQotCWZpbmFsIFN0cmluZyBuYW1lID0gZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0JaWYgKG5hbWUubGVuZ3RoKCkgPiAwKSB7Ci0JICAgIHNldE5hbWUocGFyc2VyLmdldFFOYW1lKG5hbWUpKTsKLQl9Ci0gICAgICAgIGVsc2UgewotCSAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLk5SRVFBVFRSX0VSUiwgIm5hbWUiKTsKLQl9Ci0KLQkvLyBjaGVjayB3aGV0aGVyIHZhcmlhYmxlL3BhcmFtIG9mIHRoZSBzYW1lIG5hbWUgaXMgYWxyZWFkeSBpbiBzY29wZQotCWlmIChwYXJzZXIubG9va3VwVmFyaWFibGUoX25hbWUpICE9IG51bGwpIHsKLQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5WQVJSRURFRl9FUlIsIF9uYW1lLnRvU3RyaW5nKCkpOwotCX0KLQotCWZpbmFsIFN0cmluZyBzZWxlY3QgPSBnZXRBdHRyaWJ1dGUoInNlbGVjdCIpOwotCWlmIChzZWxlY3QubGVuZ3RoKCkgPiAwKSB7Ci0JICAgIF9zZWxlY3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJzZWxlY3QiLCBudWxsKTsKLQl9Ci0KLQkvLyBDaGlsZHJlbiBtdXN0IGJlIHBhcnNlZCBmaXJzdCAtPiBzdGF0aWMgc2NvcGluZwotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQotCS8vIEFkZCBhIHJlZiB0byB0aGlzIHZhciB0byBpdHMgZW5jbG9zaW5nIGNvbnN0cnVjdAotCVN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBTdHlsZXNoZWV0KSB7Ci0JICAgIC8vIE1hcmsgdGhpcyBhcyBhIGdsb2JhbCB2YXJpYWJsZQotCSAgICBfaXNMb2NhbCA9IGZhbHNlOwotCSAgICAvLyBDaGVjayBpZiBhIGdsb2JhbCB2YXJpYWJsZSB3aXRoIHRoaXMgbmFtZSBhbHJlYWR5IGV4aXN0cy4uLgotCSAgICBWYXJpYWJsZSB2YXIgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5sb29rdXBWYXJpYWJsZShfbmFtZSk7Ci0JICAgIC8vIC4uLmFuZCBpZiBpdCBkb2VzIHdlIG5lZWQgdG8gY2hlY2sgaW1wb3J0IHByZWNlZGVuY2UKLQkgICAgaWYgKHZhciAhPSBudWxsKSB7Ci0JCWZpbmFsIGludCB1cyA9IHRoaXMuZ2V0SW1wb3J0UHJlY2VkZW5jZSgpOwotCQlmaW5hbCBpbnQgdGhlbSA9IHZhci5nZXRJbXBvcnRQcmVjZWRlbmNlKCk7Ci0JCS8vIEl0IGlzIGFuIGVycm9yIGlmIHRoZSB0d28gaGF2ZSB0aGUgc2FtZSBpbXBvcnQgcHJlY2VkZW5jZQotCQlpZiAodXMgPT0gdGhlbSkgewotCQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5WQVJSRURFRl9FUlIsCi0JCQkJX25hbWUudG9TdHJpbmcoKSk7Ci0JCX0KLQkJLy8gSWdub3JlIHRoaXMgaWYgcHJldmlvdXMgZGVmaW5pdGlvbiBoYXMgaGlnaGVyIHByZWNlZGVuY2UKLQkJZWxzZSBpZiAodGhlbSA+IHVzKSB7Ci0JCSAgICByZXR1cm47Ci0JCX0KLQkJLy8gQWRkIHRoaXMgdmFyaWFibGUgaWYgd2UgaGF2ZSBoaWdoZXIgcHJlY2VkZW5jZQotCSAgICB9Ci0JICAgICgoU3R5bGVzaGVldClwYXJlbnQpLmFkZFZhcmlhYmxlKHRoaXMpOwotCSAgICBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKS5hZGRWYXJpYWJsZSh0aGlzKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIF9pc0xvY2FsID0gdHJ1ZTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUnVucyBhIHR5cGUgY2hlY2sgb24gZWl0aGVyIHRoZSB2YXJpYWJsZSBlbGVtZW50IGJvZHkgb3IgdGhlCi0gICAgICogZXhwcmVzc2lvbiBpbiB0aGUgJ3NlbGVjdCcgYXR0cmlidXRlCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQkvLyBUeXBlIGNoZWNrIHRoZSAnc2VsZWN0JyBleHByZXNzaW9uIGlmIHByZXNlbnQKLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIF90eXBlID0gX3NlbGVjdC50eXBlQ2hlY2soc3RhYmxlKTsKLQl9Ci0JLy8gVHlwZSBjaGVjayB0aGUgZWxlbWVudCBjb250ZW50cyBvdGhlcndpc2UKLQllbHNlIGlmIChoYXNDb250ZW50cygpKSB7Ci0JICAgIHR5cGVDaGVja0NvbnRlbnRzKHN0YWJsZSk7Ci0JICAgIF90eXBlID0gVHlwZS5SZXN1bHRUcmVlOwotCX0KLQllbHNlIHsKLQkgICAgX3R5cGUgPSBUeXBlLlJlZmVyZW5jZTsKLQl9Ci0JLy8gVGhlIHJldHVybiB0eXBlIGlzIHZvaWQgYXMgdGhlIHZhcmlhYmxlIGVsZW1lbnQgZG9lcyBub3QgbGVhdmUKLQkvLyBhbnl0aGluZyBvbiB0aGUgSlZNJ3Mgc3RhY2suIFRoZSAnX3R5cGUnIGdsb2JhbCB3aWxsIGJlIHJldHVybmVkCi0JLy8gYnkgdGhlIHJlZmVyZW5jZXMgdG8gdGhpcyB2YXJpYWJsZSwgYW5kIG5vdCBieSB0aGUgdmFyaWFibGUgaXRzZWxmLgotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgcGFydCBvZiBhIGxpdHRsZSB0cmljayB0aGF0IGlzIG5lZWRlZCB0byB1c2UgbG9jYWwKLSAgICAgKiB2YXJpYWJsZXMgaW5zaWRlIG5lc3RlZCBmb3ItZWFjaCBsb29wcy4gU2VlIHRoZSBpbml0aWFsaXplVmFyaWFibGVzKCkKLSAgICAgKiBtZXRob2QgaW4gdGhlIEZvckVhY2ggY2xhc3MgZm9yIGFuIGV4cGxhbmF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBUaGlzIGlzIG9ubHkgZG9uZSBmb3IgbG9jYWwgdmFyaWFibGVzIHRoYXQgYXJlIGFjdHVhbGx5IHVzZWQKLQlpZiAoaXNMb2NhbCgpICYmICFfcmVmcy5pc0VtcHR5KCkpIHsKLQkgICAgLy8gQ3JlYXRlIGEgdmFyaWFibGUgc2xvdCBpZiBub25lIGlzIGFsbG9jYXRlZAotCSAgICBpZiAoX2xvY2FsID09IG51bGwpIHsKLQkJX2xvY2FsID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKF9uYW1lLmdldExvY2FsUGFydCgpLAotCQkJCQkJICAgICBfdHlwZS50b0pDVHlwZSgpLAotCQkJCQkJICAgICBpbC5nZXRFbmQoKSk7Ci0JICAgIH0KLQkgICAgLy8gUHVzaCB0aGUgZGVmYXVsdCB2YWx1ZSBvbiB0aGUgSlZNJ3Mgc3RhY2sKLQkgICAgaWYgKChfdHlwZSBpbnN0YW5jZW9mIEludFR5cGUpIHx8Ci0JCShfdHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSB8fAotCQkoX3R5cGUgaW5zdGFuY2VvZiBCb29sZWFuVHlwZSkpCi0JCWlsLmFwcGVuZChuZXcgSUNPTlNUKDApKTsgLy8gMCBmb3Igbm9kZS1pZCwgaW50ZWdlciBhbmQgYm9vbGVhbgotCSAgICBlbHNlIGlmIChfdHlwZSBpbnN0YW5jZW9mIFJlYWxUeXBlKQotCQlpbC5hcHBlbmQobmV3IERDT05TVCgwKSk7IC8vIDAuMCBmb3IgZmxvYXRpbmcgcG9pbnQgbnVtYmVycwotCSAgICBlbHNlCi0JCWlsLmFwcGVuZChuZXcgQUNPTlNUX05VTEwoKSk7IC8vIGFuZCAnbnVsbCcgZm9yIGFueXRoaW5nIGVsc2UKLQkgICAgaWwuYXBwZW5kKF90eXBlLlNUT1JFKF9sb2NhbC5nZXRJbmRleCgpKSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGUgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSwgd2hpY2ggaXMgZWl0aGVyIGluIGFuIGV4cHJlc3Npb24gaW4KLSAgICAgKiBhICdzZWxlY3QnIGF0dHJpYnV0ZSwgb3IgaW4gdGhlIHZhcmlhYmxlIGVsZW1lbnRzIGJvZHkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVWYWx1ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JLy8gQ29tcGlsZSBleHByZXNzaW9uIGlzICdzZWxlY3QnIGF0dHJpYnV0ZSBpZiBwcmVzZW50Ci0JaWYgKF9zZWxlY3QgIT0gbnVsbCkgewotCSAgICBfc2VsZWN0LnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQkgICAgX3NlbGVjdC5zdGFydFJlc2V0SXRlcmF0b3IoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JfQotCS8vIElmIG5vdCwgY29tcGlsZSByZXN1bHQgdHJlZSBmcm9tIHBhcmFtZXRlciBib2R5IGlmIHByZXNlbnQuCi0JZWxzZSBpZiAoaGFzQ29udGVudHMoKSkgewotCSAgICBjb21waWxlUmVzdWx0VHJlZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JLy8gSWYgbmVpdGhlciBhcmUgcHJlc2VudCB0aGVuIHN0b3JlIGVtcHR5IHN0cmluZyBpbiB2YXJpYWJsZQotCWVsc2UgewotCSAgICBmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JICAgIGZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlmaW5hbCBTdHJpbmcgbmFtZSA9IGdldFZhcmlhYmxlKCk7Ci0KLQkvLyBNYWtlIHN1cmUgdGhhdCBhIHZhcmlhYmxlIGluc3RhbmNlIGlzIG9ubHkgY29tcGlsZWQgb25jZQotCWlmIChfY29tcGlsZWQpIHJldHVybjsKLQlfY29tcGlsZWQgPSB0cnVlOwotCi0JaWYgKGlzTG9jYWwoKSkgewotCSAgICAvLyBQdXNoIGFyZ3MgdG8gY2FsbCBhZGRWYXJpYWJsZSgpCi0JICAgIGlmIChfZXNjYXBlcykgewotCQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfc3RhY2tJbmRleCkpOwotCSAgICB9Ci0KLQkgICAgLy8gQ29tcGlsZSB2YXJpYWJsZSB2YWx1ZSBjb21wdXRhdGlvbgotCSAgICB0cmFuc2xhdGVWYWx1ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCSAgICAvLyBEdXAgdmFsdWUgb25seSB3aGVuIG5lZWRlZAotCSAgICBpZiAoX2VzY2FwZXMpIHsKLQkJaWwuYXBwZW5kKF90eXBlLkRVUCgpKTsKLQkgICAgfQotCi0JICAgIC8vIEFkZCBhIG5ldyBsb2NhbCB2YXJpYWJsZSBhbmQgc3RvcmUgdmFsdWUKLQkgICAgaWYgKF9yZWZzLmlzRW1wdHkoKSkgeyAvLyBSZW1vdmUgaXQgaWYgbm9ib2R5IHVzZXMgdGhlIHZhbHVlCi0JCWlsLmFwcGVuZChfdHlwZS5QT1AoKSk7Ci0JCV9sb2NhbCA9IG51bGw7Ci0JICAgIH0KLQkgICAgZWxzZSB7CQkgICAvLyBTdG9yZSBpbiBsb2NhbCB2YXIgc2xvdCBpZiByZWZlcmVuY2VkCi0JCWlmIChfbG9jYWwgPT0gbnVsbCkgbWFwUmVnaXN0ZXIobWV0aG9kR2VuKTsKLQkJaWwuYXBwZW5kKF90eXBlLlNUT1JFKF9sb2NhbC5nZXRJbmRleCgpKSk7Ci0JICAgIH0KLQotCSAgICAvLyBTdG9yZSBib3hlZCB2YWx1ZSBpbnRvIHRoZSB0ZW1wbGF0ZSdzIHZhcmlhYmxlIHN0YWNrCi0JICAgIGlmIChfZXNjYXBlcykgewotCQlfdHlwZS50cmFuc2xhdGVCb3goY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLAotCQkJCQkJCSAgICAgQUREX1ZBUklBQkxFLAotCQkJCQkJCSAgICAgQUREX1ZBUklBQkxFX1NJRykpKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgU3RyaW5nIHNpZ25hdHVyZSA9IF90eXBlLnRvU2lnbmF0dXJlKCk7Ci0KLQkgICAgLy8gR2xvYmFsIHZhcmlhYmxlcyBhcmUgc3RvcmUgaW4gY2xhc3MgZmllbGRzCi0JICAgIGlmIChjbGFzc0dlbi5jb250YWluc0ZpZWxkKG5hbWUpID09IG51bGwpIHsKLQkJY2xhc3NHZW4uYWRkRmllbGQobmV3IEZpZWxkKEFDQ19QVUJMSUMsIAotCQkJCQkgICAgY3BnLmFkZFV0ZjgobmFtZSksCi0JCQkJCSAgICBjcGcuYWRkVXRmOChzaWduYXR1cmUpLAotCQkJCQkgICAgbnVsbCwgY3BnLmdldENvbnN0YW50UG9vbCgpKSk7Ci0KLQkJLy8gUHVzaCBhIHJlZmVyZW5jZSB0byAidGhpcyIgZm9yIHB1dGZpZWxkCi0JCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JCS8vIENvbXBpbGUgdmFyaWFibGUgdmFsdWUgY29tcHV0YXRpb24KLQkJdHJhbnNsYXRlVmFsdWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JCS8vIFN0b3JlIHRoZSB2YXJpYWJsZSBpbiB0aGUgYWxsb2NhdGVkIGZpZWxkCi0JCWlsLmFwcGVuZChuZXcgUFVURklFTEQoY3BnLmFkZEZpZWxkcmVmKGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLAotCQkJCQkJICAgICAgIG5hbWUsIHNpZ25hdHVyZSkpKTsKLQkgICAgfQotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYXJpYWJsZUJhc2UuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ZhcmlhYmxlQmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjhmOWI1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ZhcmlhYmxlQmFzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBKb2huIEhvd2FyZCA8Sm9obkhAc2NoZW1hc29mdC5jb20+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5JbnN0cnVjdGlvbjsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5jbGFzc2ZpbGUuRmllbGQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uQXhpczsKLQotY2xhc3MgVmFyaWFibGVCYXNlIGV4dGVuZHMgVG9wTGV2ZWxFbGVtZW50IHsKLQotICAgIHByb3RlY3RlZCBRTmFtZSAgICAgICBfbmFtZTsgICAgICAgICAgICAvLyBUaGUgbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAgcHJvdGVjdGVkIFN0cmluZyAgICAgIF92YXJpYWJsZTsgICAgICAgIC8vIFRoZSByZWFsIG5hbWUgb2YgdGhlIHZhcmlhYmxlLgotICAgIHByb3RlY3RlZCBUeXBlICAgICAgICBfdHlwZTsgICAgICAgICAgICAvLyBUaGUgdHlwZSBvZiB0aGlzIHZhcmlhYmxlLgotICAgIHByb3RlY3RlZCBib29sZWFuICAgICBfaXNMb2NhbDsgICAgICAgICAvLyBUcnVlIGlmIHRoZSB2YXJpYWJsZSBpcyBsb2NhbC4KLSAgICBwcm90ZWN0ZWQgTG9jYWxWYXJpYWJsZUdlbiBfbG9jYWw7ICAgICAgLy8gUmVmZXJlbmNlIHRvIEpWTSB2YXJpYWJsZQotICAgIHByb3RlY3RlZCBJbnN0cnVjdGlvbiBfbG9hZEluc3RydWN0aW9uOyAvLyBJbnN0cnVjdGlvbiB0byBsb2FkIEpWTSB2YXJpYWJsZQotICAgIHByb3RlY3RlZCBFeHByZXNzaW9uICBfc2VsZWN0OyAgICAgICAgICAvLyBSZWZlcmVuY2UgdG8gdmFyaWFibGUgZXhwcmVzc2lvbgotICAgIHByb3RlY3RlZCBpbnQgICAgICAgICBfc3RhY2tJbmRleCA9IC0xOyAvLyBTdGFjayBpbmRleCByZWxhdGl2ZSB0byBiYXNlIHB0ci4KLQotICAgIC8vIFJlZmVyZW5jZXMgdG8gdGhpcyB2YXJpYWJsZSAod2hlbiBsb2NhbCkKLSAgICBwcm90ZWN0ZWQgVmVjdG9yICAgICAgX3JlZnMgPSBuZXcgVmVjdG9yKDIpOyAKLQotICAgIC8vIFVzZWQgdG8gbWFrZSBzdXJlIHBhcmFtZXRlciBmaWVsZCBpcyBub3QgYWRkZWQgdHdpY2UKLSAgICBwcm90ZWN0ZWQgYm9vbGVhbiAgICBfY29tcGlsZWQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIEFkZCBhIHJlZmVyZW5jZSB0byB0aGlzIHZhcmlhYmxlLiBDYWxsZWQgYnkgVmFyaWFibGVSZWYgd2hlbiBhbgotICAgICAqIGV4cHJlc3Npb24gY29udGFpbnMgYSByZWZlcmVuY2UgdG8gdGhpcyB2YXJpYWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRSZWZlcmVuY2UoVmFyaWFibGVSZWZCYXNlIHZyZWYpIHsKLQlfcmVmcy5hZGRFbGVtZW50KHZyZWYpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSBhIHJlZmVyZW5jZSB0byB0aGlzIHZhcmlhYmxlLiBDYWxsZWQgYnkgVmFyaWFibGVSZWYgd2hlbiB0aGlzCi0gICAgICogdmFyaWFibGUgZ29lcyBvdXQgb2Ygc2NvcGUuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcmVtb3ZlUmVmZXJlbmNlKFZhcmlhYmxlUmVmQmFzZSB2cmVmKSB7Ci0JX3JlZnMucmVtb3ZlKHZyZWYpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hcCB0aGlzIHZhcmlhYmxlIHRvIGEgcmVnaXN0ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBtYXBSZWdpc3RlcihNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0gICAgICAgIGlmIChfbG9jYWwgPT0gbnVsbCkgewotICAgICAgICAgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCSAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IF9uYW1lLmdldExvY2FsUGFydCgpOyAvLyBUT0RPOiBuYW1lc3BhY2UgPwotCSAgICBmaW5hbCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlIHZhclR5cGUgPSBfdHlwZS50b0pDVHlwZSgpOwotICAgICAgICAgICAgX2xvY2FsID0gbWV0aG9kR2VuLmFkZExvY2FsVmFyaWFibGUyKG5hbWUsIHZhclR5cGUsIGlsLmdldEVuZCgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlbW92ZSB0aGUgbWFwcGluZyBvZiB0aGlzIHZhcmlhYmxlIHRvIGEgcmVnaXN0ZXIuCi0gICAgICogQ2FsbGVkIHdoZW4gd2UgbGVhdmUgdGhlIEFTVCBzY29wZSBvZiB0aGUgdmFyaWFibGUncyBkZWNsYXJhdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVubWFwUmVnaXN0ZXIoTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWlmIChfcmVmcy5pc0VtcHR5KCkgJiYgKF9sb2NhbCAhPSBudWxsKSkgewotCSAgICBfbG9jYWwuc2V0RW5kKG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5nZXRFbmQoKSk7Ci0JICAgIG1ldGhvZEdlbi5yZW1vdmVMb2NhbFZhcmlhYmxlKF9sb2NhbCk7Ci0JICAgIF9yZWZzID0gbnVsbDsKLQkgICAgX2xvY2FsID0gbnVsbDsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIGhhbmRsZSB0byB0aGUgaW5zdHJ1Y3Rpb24gZm9yIGxvYWRpbmcgdGhlIHZhbHVlIG9mIHRoaXMKLSAgICAgKiB2YXJpYWJsZSBvbnRvIHRoZSBKVk0gc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRJbnN0cnVjdGlvbigpIHsKLQlmaW5hbCBJbnN0cnVjdGlvbiBpbnN0ciA9IF9sb2FkSW5zdHJ1Y3Rpb247Ci0JaWYgKF9sb2FkSW5zdHJ1Y3Rpb24gPT0gbnVsbCkgCi0JICAgIF9sb2FkSW5zdHJ1Y3Rpb24gPSBfdHlwZS5MT0FEKF9sb2NhbC5nZXRJbmRleCgpKTsKLQlyZXR1cm4gX2xvYWRJbnN0cnVjdGlvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIGZyb20gdGhpcyB2YXJpYWJsZSdzIHNlbGVjdCBhdHRyaWJ1dGUgKGlmIGFueSkKLSAgICAgKi8KLSAgICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkgewotCXJldHVybihfc2VsZWN0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5IHZhcmlhYmxlIGFzIHNpbmdsZSBzdHJpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybigidmFyaWFibGUoIitfbmFtZSsiKSIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERpc3BsYXkgdmFyaWFibGUgaW4gYSBmdWxsIEFTVCBkdW1wCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZGlzcGxheShpbnQgaW5kZW50KSB7Ci0JaW5kZW50KGluZGVudCk7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJWYXJpYWJsZSAiICsgX25hbWUpOwotCWlmIChfc2VsZWN0ICE9IG51bGwpIHsgCi0JICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNlbGVjdCAiICsgX3NlbGVjdC50b1N0cmluZygpKTsKLQl9Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgdmFyaWFibGUKLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgewotCXJldHVybiBfdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgYXMgaXQgd2lsbCBvY2N1ciBpbiB0aGUKLSAgICAgKiBjb21waWxlZCB0cmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgUU5hbWUgZ2V0TmFtZSgpIHsKLQlyZXR1cm4gX25hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGFzIGl0IG9jY3VyZWQgaW4gdGhlCi0gICAgICogc3R5bGVzaGVldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhcmlhYmxlKCkgewotCXJldHVybiBfdmFyaWFibGU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHJlcGxhY2UoU3RyaW5nIGJhc2UsIGNoYXIgYywgU3RyaW5nIHN0cikgewotCWZpbmFsIGludCBsZW4gPSBiYXNlLmxlbmd0aCgpIC0gMTsKLQlpbnQgcG9zOwotCXdoaWxlICgocG9zID0gYmFzZS5pbmRleE9mKGMpKSA+IC0xKSB7Ci0JICAgIGlmIChwb3MgPT0gMCkgewotCQlmaW5hbCBTdHJpbmcgYWZ0ZXIgPSBiYXNlLnN1YnN0cmluZygxKTsKLQkJYmFzZSA9IHN0ciArIGFmdGVyOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKHBvcyA9PSBsZW4pIHsKLQkJZmluYWwgU3RyaW5nIGJlZm9yZSA9IGJhc2Uuc3Vic3RyaW5nKDAsIHBvcyk7Ci0JCWJhc2UgPSBiZWZvcmUgKyBzdHI7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWZpbmFsIFN0cmluZyBiZWZvcmUgPSBiYXNlLnN1YnN0cmluZygwLCBwb3MpOwotCQlmaW5hbCBTdHJpbmcgYWZ0ZXIgPSBiYXNlLnN1YnN0cmluZyhwb3MrMSk7Ci0JCWJhc2UgPSBiZWZvcmUgKyBzdHIgKyBhZnRlcjsKLQkgICAgfQotCX0KLQlyZXR1cm4gYmFzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIG5hbWUgb2YgdGhlIHZhcmlhYmxlIG9yIHBhcmVtZXRlci4gRXNjYXBlIGFsbCBzcGVjaWFsIGNoYXJzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE5hbWUoUU5hbWUgbmFtZSkgewotCV9uYW1lID0gbmFtZTsKLQlfbmFtZS5jbGVhckRlZmF1bHROYW1lc3BhY2UoKTsKLQotCVN0cmluZyBwcmVmaXggPSBuYW1lLmdldFByZWZpeCgpOwotCVN0cmluZyBsb2NhbCA9IG5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0JbG9jYWwgPSByZXBsYWNlKGxvY2FsLCAnLicsICIkZG90JCIpOwotCWxvY2FsID0gcmVwbGFjZShsb2NhbCwgJy0nLCAiJGRhc2gkIik7Ci0JX3ZhcmlhYmxlID0gbG9jYWw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHJ1ZSBpZiB0aGUgdmFyaWFibGUgaXMgbG9jYWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0xvY2FsKCkgewotCXJldHVybiBfaXNMb2NhbDsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ZhcmlhYmxlUmVmLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYXJpYWJsZVJlZi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZTY3MmI3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1ZhcmlhYmxlUmVmLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFZhcmlhYmxlUmVmIGV4dGVuZHMgVmFyaWFibGVSZWZCYXNlIHsKLQotICAgIHByaXZhdGUgYm9vbGVhbiBfZXNjYXBlZDsKLQkKLSAgICBwdWJsaWMgVmFyaWFibGVSZWYoVmFyaWFibGUgdmFyaWFibGUpIHsKLQlzdXBlcih2YXJpYWJsZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoIChfdmFyaWFibGUuaXNMb2NhbCgpKSAmJiAoX2VzY2FwZWQgPSBpc0VzY2FwZWQoKSkgKQotCSAgICAoKFZhcmlhYmxlKV92YXJpYWJsZSkuc2V0RXNjYXBlcygpOwotCXJldHVybiBzdXBlci50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNFc2NhcGVkKCkgewotCWZpbmFsIFN5bnRheFRyZWVOb2RlIGxpbWl0ID0gX3ZhcmlhYmxlLmdldFBhcmVudCgpOwotCVN5bnRheFRyZWVOb2RlIHBhcmVudCA9IGdldFBhcmVudCgpOwotCWRvIHsKLQkgICAgaWYgKHBhcmVudC5pc0Nsb3N1cmVCb3VuZGFyeSgpKSB7Ci0JCXJldHVybiB0cnVlOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50KCk7Ci0JICAgIH0KLQl9Ci0Jd2hpbGUgKHBhcmVudCAhPSBsaW1pdCk7Ci0JcmV0dXJuIGxpbWl0LmlzQ2xvc3VyZUJvdW5kYXJ5KCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQkJCi0JU3RyaW5nIG5hbWUgPSBfdmFyaWFibGUuZ2V0VmFyaWFibGUoKTsKLQotCWlmIChfdHlwZS5pbXBsZW1lbnRlZEFzTWV0aG9kKCkpIHsKLQkgICAgLy8gRmFsbC10aHJvdWdoIGZvciB2YXJpYWJsZXMgdGhhdCBhcmUgaW1wbGVtZW50ZWQgYXMgbWV0aG9kcwotCSAgICByZXR1cm47Ci0JfQotCi0JaWYgKF92YXJpYWJsZS5pc0xvY2FsKCkpIHsKLQkgICAgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSB8fCBfZXNjYXBlZCkgewotCQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCQlmaW5hbCBpbnQgc2luZGV4ID0gKChWYXJpYWJsZSlfdmFyaWFibGUpLmdldFN0YWNrSW5kZXgoKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgc2luZGV4KSk7Ci0JCWZpbmFsIGludCBnZXRWYXIgPSBjcGcuYWRkTWV0aG9kcmVmKFRSQU5TTEVUX0NMQVNTLCAKLQkJCQkJCSAgICBHRVRfVkFSSUFCTEUsCi0JCQkJCQkgICAgR0VUX1ZBUklBQkxFX1NJRyk7Ci0JCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChnZXRWYXIpKTsKLQkJX3R5cGUudHJhbnNsYXRlVW5Cb3goY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWlsLmFwcGVuZChfdmFyaWFibGUubG9hZEluc3RydWN0aW9uKCkpOwotCQlfdmFyaWFibGUucmVtb3ZlUmVmZXJlbmNlKHRoaXMpOwotCSAgICB9Ci0JfQotCWVsc2UgewotCSAgICBmaW5hbCBTdHJpbmcgc2lnbmF0dXJlID0gX3R5cGUudG9TaWduYXR1cmUoKTsKLQkgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotCSAgICBpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOwotCSAgICAvLyBJZiBpbnNpZGUgYSBwcmVkaWNhdGUgd2UgbXVzdCBjYXN0IHRoaXMgcmVmIGRvd24KLQkgICAgaWYgKGNsYXNzR2VuLmlzRXh0ZXJuYWwoKSkgewotCQlpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoY2xhc3NOYW1lKSkpOwotCSAgICB9Ci0JICAgIGlsLmFwcGVuZChuZXcgR0VURklFTEQoY3BnLmFkZEZpZWxkcmVmKGNsYXNzTmFtZSxuYW1lLHNpZ25hdHVyZSkpKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvVmFyaWFibGVSZWZCYXNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYXJpYWJsZVJlZkJhc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjIzMmY3Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9WYXJpYWJsZVJlZkJhc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotY2xhc3MgVmFyaWFibGVSZWZCYXNlIGV4dGVuZHMgRXhwcmVzc2lvbiB7Ci0KLSAgICBwcm90ZWN0ZWQgZmluYWwgVmFyaWFibGVCYXNlIF92YXJpYWJsZTsgLy8gUmVmZXJlbmNlIHRvIHRoZSBhc3NvY2lhdGVkIHZhci4KLQotICAgIC8qKgotICAgICAqIENyZWF0ZWQgYSBuZXcgdmFyaWFibGUgb3IgcGFyYW1ldGVyIHJlZmVyZW5jZS4gTm90ZSB0aGF0IHRoaXMgYmFzZS0KLSAgICAgKiBjbGFzcyBpcyBub3QgaGVyZSBtb3N0bHkgYmVjYXVzZSB2YXJpYWJsZSBhbmQgcGFyYW1ldGVyIHJlZmVyZW5jZXMgc2hhcmUKLSAgICAgKiBhIGxvdCBvZiBmdW5jdGlvbmFsaXR5LiBUaGUgYmFzZSBjbGFzcyBpcyBuZWVkZWQgbW9yZSBmb3IgaGF2aW5nIGEKLSAgICAgKiBzaW5nbGUgY2xhc3MgdG8gcnVuICdpZiAoaW5zdGFuY2VvZiknIG9uIGluIHRoZSBjb21waWxlciBjb2RlLiBUaGUgc2FtZQotICAgICAqIGhvbGRzIGZvciB0aGUgdmFyaWFibGUgYmFzZSBjbGFzcy4KLSAgICAgKiBAcGFyYW0gdmFyaWFibGUgVGhlIHJlZmVyZW5jZWQgdmFyaWFibGUKLSAgICAgKi8KLSAgICBwdWJsaWMgVmFyaWFibGVSZWZCYXNlKFZhcmlhYmxlQmFzZSB2YXJpYWJsZSkgewotCV92YXJpYWJsZSA9IHZhcmlhYmxlOwotCXZhcmlhYmxlLmFkZFJlZmVyZW5jZSh0aGlzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBhc3NvY2lhdGVkIHZhcmlhYmxlCi0gICAgICogQHJldHVybiBUaGUgcmVmZXJlbmNlZCB2YXJpYWJsZQotICAgICAqLwotICAgIHB1YmxpYyBWYXJpYWJsZUJhc2UgZ2V0VmFyaWFibGUoKSB7Ci0JcmV0dXJuKF92YXJpYWJsZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhcmlhYmxlIHJlZmVyZW5jZSBvbiB0aGUKLSAgICAgKiBmb3JtYXQgJ3ZhcmlhYmxlLXJlZig8dmFyLW5hbWU+KScuCi0gICAgICogQHJldHVybiBWYXJpYWJsZSByZWZlcmVuY2UgZGVzY3JpcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAidmFyaWFibGUtcmVmKCIgKyBfdmFyaWFibGUuZ2V0TmFtZSgpICsgJyknOwotICAgIH0KLQotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0KLSAgICAgICAgLy8gQXR0ZW1wdCB0byBnZXQgdGhlIGNhY2hlZCB2YXJpYWJsZSB0eXBlCi0gICAgICAgIF90eXBlID0gX3ZhcmlhYmxlLmdldFR5cGUoKTsKLQotICAgICAgICAvLyBJZiB0aGF0IGRvZXMgbm90IHdvcmsgd2UgbXVzdCBmb3JjZSBhIHR5cGUtY2hlY2sgKHRoaXMgaXMgbm9ybWFsbHkKLSAgICAgICAgLy8gb25seSBuZWVkZWQgZm9yIGdsb2JhbHMgaW4gaW5jbHVkZWQvaW1wb3J0ZWQgc3R5bGVzaGVldHMKLSAgICAgICAgaWYgKF90eXBlID09IG51bGwpIHsKLSAgICAgICAgICAgIF92YXJpYWJsZS50eXBlQ2hlY2soc3RhYmxlKTsKLSAgICAgICAgICAgIF90eXBlID0gX3ZhcmlhYmxlLmdldFR5cGUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8vIFJldHVybiB0aGUgdHlwZSBvZiB0aGUgcmVmZXJlbmNlZCB2YXJpYWJsZQotICAgICAgICByZXR1cm4gX3R5cGU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9XaGVuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9XaGVuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQyOWMzMzguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvV2hlbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgV2hlbiBleHRlbmRzIEluc3RydWN0aW9uIHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT19DSE9PU0VfRVJST1IgPQotCSJJbnN0cnVjdGlvbiAnd2hlbicgbXVzdCBiZSB1c2VkIHdpdGhpbiBhICdjaG9vc2UnLiI7Ci0JCi0gICAgcHJpdmF0ZSBFeHByZXNzaW9uIF90ZXN0OwotICAgIHByaXZhdGUgYm9vbGVhbiBfaWdub3JlID0gZmFsc2U7Ci0KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIldoZW4iKTsKLQlpbmRlbnQoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLQlTeXN0ZW0ub3V0LnByaW50KCJ0ZXN0ICIpOwotCVV0aWwucHJpbnRsbihfdGVzdC50b1N0cmluZygpKTsKLQlkaXNwbGF5Q29udGVudHMoaW5kZW50ICsgSW5kZW50SW5jcmVtZW50KTsKLSAgICB9Ci0JCQotICAgIHB1YmxpYyBFeHByZXNzaW9uIGdldFRlc3QoKSB7Ci0JcmV0dXJuIF90ZXN0OwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlnbm9yZSgpIHsKLQlyZXR1cm4oX2lnbm9yZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JX3Rlc3QgPSBwYXJzZXIucGFyc2VFeHByZXNzaW9uKHRoaXMsICJ0ZXN0IiwgbnVsbCk7Ci0JaWYgKF90ZXN0IGluc3RhbmNlb2YgRWxlbWVudEF2YWlsYWJsZUNhbGwpIHsKLQkgICAgRWxlbWVudEF2YWlsYWJsZUNhbGwgY2FsbCA9IChFbGVtZW50QXZhaWxhYmxlQ2FsbClfdGVzdDsKLQkgICAgX2lnbm9yZSA9ICFjYWxsLmdldFJlc3VsdCgpOwotCX0KLQlpZiAoX3Rlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbkF2YWlsYWJsZUNhbGwpIHsKLQkgICAgRnVuY3Rpb25BdmFpbGFibGVDYWxsIGNhbGwgPSAoRnVuY3Rpb25BdmFpbGFibGVDYWxsKV90ZXN0OwotCSAgICBfaWdub3JlID0gIWNhbGwuZ2V0UmVzdWx0KCk7Ci0JfQotCi0JcGFyc2VDaGlsZHJlbihwYXJzZXIpOwotCi0JLy8gTWFrZSBzdXJlIHJlcXVpcmVkIGF0dHJpYnV0ZShzKSBoYXZlIGJlZW4gc2V0Ci0JaWYgKF90ZXN0LmlzRHVtbXkoKSkgewotCSAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLk5SRVFBVFRSX0VSUiwgInRlc3QiKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHlwZS1jaGVjayB0aGlzIHdoZW4gZWxlbWVudC4gVGhlIHRlc3Qgc2hvdWxkIGFsd2F5cyBiZSB0eXBlIGNoZWNrZWQsCi0gICAgICogd2hpbGUgd2UgZG8gbm90IGJvdGhlciB3aXRoIHRoZSBjb250ZW50cyBpZiB3ZSBrbm93IHRoZSB0ZXN0IGZhaWxzLgotICAgICAqIFRoaXMgaXMgaW1wb3J0YW50IGluIGNhc2VzIHdoZXJlIHRoZSAidGVzdCIgZXhwcmVzc2lvbiB0ZXN0cyBmb3IKLSAgICAgKiB0aGUgc3VwcG9ydCBvZiBhIG5vbi1hdmFpbGFibGUgZWxlbWVudCwgYW5kIHRoZSA8eHNsOndoZW4+IGJvZHkgY29udGFpbnMKLSAgICAgKiB0aGlzIG5vbi1hdmFpbGFibGUgZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZSB0eXBlQ2hlY2soU3ltYm9sVGFibGUgc3RhYmxlKSB0aHJvd3MgVHlwZUNoZWNrRXJyb3IgewotCS8vIFR5cGUtY2hlY2sgdGhlIHRlc3QgZXhwcmVzc2lvbgotCWlmIChfdGVzdC50eXBlQ2hlY2soc3RhYmxlKSBpbnN0YW5jZW9mIEJvb2xlYW5UeXBlID09IGZhbHNlKSB7Ci0JICAgIF90ZXN0ID0gbmV3IENhc3RFeHByKF90ZXN0LCBUeXBlLkJvb2xlYW4pOwotCX0KLQkvLyBUeXBlLWNoZWNrIHRoZSBjb250ZW50cyAoaWYgbmVjZXNzYXJ5KQotCWlmICghX2lnbm9yZSkgewotCSAgICB0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCX0KLQotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG5ldmVyIGJlIGNhbGxlZC4gQW4gT3RoZXJ3aXNlIG9iamVjdCB3aWxsIGV4cGxpY2l0bHkKLSAgICAgKiB0cmFuc2xhdGUgdGhlICJ0ZXN0IiBleHByZXNzaW9uIGFuZCBhbmQgY29udGVudHMgb2YgdGhpcyBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIEVycm9yTXNnIG1zZyA9IG5ldyBFcnJvck1zZyhOT19DSE9PU0VfRVJST1IsIGdldExpbmVOdW1iZXIoKSk7Ci0JZ2V0UGFyc2VyKCkucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1doaXRlc3BhY2UuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1doaXRlc3BhY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTVjODc1OS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9XaGl0ZXNwYWNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NzUgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5SZWZlcmVuY2VUeXBlOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5KYXZhQ2xhc3M7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmNsYXNzZmlsZS5GaWVsZDsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuY2xhc3NmaWxlLk1ldGhvZDsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgV2hpdGVzcGFjZSBleHRlbmRzIFRvcExldmVsRWxlbWVudCB7Ci0gICAgLy8gVGhyZWUgcG9zc2libGUgYWN0aW9ucyBmb3IgdGhlIHRyYW5zbGV0OgotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVTRV9QUkVESUNBVEUgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJUF9TUEFDRSAgICA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJFU0VSVkVfU1BBQ0UgPSAyOwotCi0gICAgLy8gVGhlIDMgZGlmZmVyZW50IGNhdGVnb3JpZXMgb2Ygc3RyaXAvcHJlc2VydmUgcnVsZXMgKG9yZGVyIGltcG9ydGFudCkKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSVUxFX05PTkUgICAgICA9IDA7IAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJVTEVfRUxFTUVOVCAgID0gMTsgLy8gcHJpb3JpdHkgMAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJVTEVfTkFNRVNQQUNFID0gMjsgLy8gcHJpb3JpdHkgLTEvNAotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJVTEVfQUxMICAgICAgID0gMzsgLy8gcHJpb3JpdHkgLTEvMgotCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2VsZW1lbnRMaXN0OwotICAgIHByaXZhdGUgaW50ICAgIF9hY3Rpb247Ci0gICAgcHJpdmF0ZSBpbnQgICAgX2ltcG9ydFByZWNlZGVuY2U7Ci0KLSAgICAvKioKLSAgICAgKiBBdXhpbGxhcnkgY2xhc3MgZm9yIGVuY2Fwc3VsYXRpbmcgYSBzaW5nbGUgc3RyaXAvcHJlc2VydmUgcnVsZQotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNsYXNzIFdoaXRlc3BhY2VSdWxlIHsKLQlwcml2YXRlIGZpbmFsIGludCBfYWN0aW9uOwotCXByaXZhdGUgU3RyaW5nIF9uYW1lc3BhY2U7IC8vIFNob3VsZCBiZSByZXBsYWNlZCBieSBOUyB0eXBlIChpbnQpCi0JcHJpdmF0ZSBTdHJpbmcgX2VsZW1lbnQ7ICAgLy8gU2hvdWxkIGJlIHJlcGxhY2VkIGJ5IG5vZGUgdHlwZSAoaW50KQotCXByaXZhdGUgaW50ICAgIF90eXBlOwotCXByaXZhdGUgaW50ICAgIF9wcmlvcml0eTsKLQkKLQkvKioKLQkgKiBTdHJpcC9wcmVzZXJ2ZSBydWxlIGNvbnN0cnVjdG9yCi0JICovCi0JcHVibGljIFdoaXRlc3BhY2VSdWxlKGludCBhY3Rpb24sIFN0cmluZyBlbGVtZW50LCBpbnQgcHJlY2VkZW5jZSkgewotIAkgICAgLy8gRGV0ZXJtaW5lIHRoZSBhY3Rpb24gKHN0cmlwIG9yIHByZXNlcnZlKSBmb3IgdGhpcyBydWxlCi0JICAgIF9hY3Rpb24gPSBhY3Rpb247Ci0KLQkgICAgLy8gR2V0IHRoZSBuYW1lc3BhY2UgYW5kIGVsZW1lbnQgbmFtZSBmb3IgdGhpcyBydWxlCi0JICAgIGZpbmFsIGludCBjb2xvbiA9IGVsZW1lbnQuaW5kZXhPZignOicpOwotCSAgICBpZiAoY29sb24gPj0gMCkgewotCQlfbmFtZXNwYWNlID0gZWxlbWVudC5zdWJzdHJpbmcoMCxjb2xvbik7Ci0JCV9lbGVtZW50ID0gZWxlbWVudC5zdWJzdHJpbmcoY29sb24rMSxlbGVtZW50Lmxlbmd0aCgpKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX25hbWVzcGFjZSA9IENvbnN0YW50cy5FTVBUWVNUUklORzsKLQkJX2VsZW1lbnQgPSBlbGVtZW50OwotCSAgICB9Ci0KLQkgICAgLy8gRGV0ZXJtaW5lIHRoZSBpbml0aWFsIHByaW9yaXR5IGZvciB0aGlzIHJ1bGUKLQkgICAgX3ByaW9yaXR5ID0gcHJlY2VkZW5jZSA8PCAyOwotCi0JICAgIC8vIEdldCB0aGUgc3RyaXAvcHJlc2VydmUgdHlwZTsgZWl0aGVyICJOUzpFTCIsICJOUzoqIiBvciAiKiIKLQkgICAgaWYgKF9lbGVtZW50LmVxdWFscygiKiIpKSB7Ci0JCWlmIChfbmFtZXNwYWNlID09IENvbnN0YW50cy5FTVBUWVNUUklORykgewotCQkgICAgX3R5cGUgPSBSVUxFX0FMTDsgICAgICAgLy8gU3RyaXAvcHJlc2VydmUgX2FsbF8gZWxlbWVudHMKLQkJICAgIF9wcmlvcml0eSArPSAyOyAgICAgICAgIC8vIExvd2VzdCBwcmlvcml0eQotCQl9Ci0JCWVsc2UgewotCQkgICAgX3R5cGUgPSBSVUxFX05BTUVTUEFDRTsgLy8gU3RyaXAvcmVzZXJ2ZSBlbGVtZW50cyB3aXRoaW4gTlMKLQkJICAgIF9wcmlvcml0eSArPSAxOyAgICAgICAgIC8vIE1lZGl1bSBwcmlvcml0eQotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCV90eXBlID0gUlVMRV9FTEVNRU5UOyAgICAgICAvLyBTdHJpcC9wcmVzZXJ2ZSBzaW5nbGUgZWxlbWVudAotCSAgICB9Ci0JfQotCi0JLyoqCi0JICogRm9yIHNvcnRpbmcgcnVsZXMgZGVwZW5kaW5nIG9uIHByaW9yaXR5Ci0JICovCi0JcHVibGljIGludCBjb21wYXJlVG8oV2hpdGVzcGFjZVJ1bGUgb3RoZXIpIHsKLQkgICAgcmV0dXJuIF9wcmlvcml0eSA8IG90aGVyLl9wcmlvcml0eQotCQk/IC0xCi0JCTogX3ByaW9yaXR5ID4gb3RoZXIuX3ByaW9yaXR5ID8gMSA6IDA7Ci0JfQotCi0JcHVibGljIGludCBnZXRBY3Rpb24oKSB7IHJldHVybiBfYWN0aW9uOyB9Ci0JcHVibGljIGludCBnZXRTdHJlbmd0aCgpIHsgcmV0dXJuIF90eXBlOyB9Ci0JcHVibGljIGludCBnZXRQcmlvcml0eSgpIHsgcmV0dXJuIF9wcmlvcml0eTsgfQotCXB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudCgpIHsgcmV0dXJuIF9lbGVtZW50OyB9Ci0JcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoKSB7IHJldHVybiBfbmFtZXNwYWNlOyB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHhzbDpzdHJpcC9wcmVzZXJ2ZS1zcGFjZSBlbGVtZW50LgotICAgICAqIFRoZSBlbGVtZW50IHNob3VsZCBoYXZlIG5vdCBjb250ZW50cyAoaWdub3JlZCBpZiBhbnkpLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBhcnNlQ29udGVudHMoUGFyc2VyIHBhcnNlcikgewotCS8vIERldGVybWluZSBpZiB0aGlzIGlzIGFuIHhzbDpzdHJpcC0gb3IgcHJlc2VydmUtc3BhY2UgZWxlbWVudAotCV9hY3Rpb24gPSBfcW5hbWUuZ2V0TG9jYWxQYXJ0KCkuZW5kc1dpdGgoInN0cmlwLXNwYWNlIikgCi0JICAgID8gU1RSSVBfU1BBQ0UgOiBQUkVTRVJWRV9TUEFDRTsKLQotCS8vIERldGVybWluZSB0aGUgaW1wb3J0IHByZWNlZGVuY2UKLQlfaW1wb3J0UHJlY2VkZW5jZSA9IHBhcnNlci5nZXRDdXJyZW50SW1wb3J0UHJlY2VkZW5jZSgpOwotCi0JLy8gR2V0IHRoZSBsaXN0IG9mIGVsZW1lbnRzIHRvIHN0cmlwL3ByZXNlcnZlCi0JX2VsZW1lbnRMaXN0ID0gZ2V0QXR0cmlidXRlKCJlbGVtZW50cyIpOwotCWlmIChfZWxlbWVudExpc3QgPT0gbnVsbCB8fCBfZWxlbWVudExpc3QubGVuZ3RoKCkgPT0gMCkgewotCSAgICByZXBvcnRFcnJvcih0aGlzLCBwYXJzZXIsIEVycm9yTXNnLk5SRVFBVFRSX0VSUiwgImVsZW1lbnRzIik7Ci0JICAgIHJldHVybjsKLQl9Ci0KLQlmaW5hbCBTeW1ib2xUYWJsZSBzdGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLQlTdHJpbmdUb2tlbml6ZXIgbGlzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoX2VsZW1lbnRMaXN0KTsKLQlTdHJpbmdCdWZmZXIgZWxlbWVudHMgPSBuZXcgU3RyaW5nQnVmZmVyKENvbnN0YW50cy5FTVBUWVNUUklORyk7Ci0KLQl3aGlsZSAobGlzdC5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBTdHJpbmcgdG9rZW4gPSBsaXN0Lm5leHRUb2tlbigpOwotCSAgICBTdHJpbmcgcHJlZml4OwotCSAgICBTdHJpbmcgbmFtZXNwYWNlOwotCSAgICBpbnQgY29sOwotCi0JICAgIGlmICgoY29sID0gdG9rZW4uaW5kZXhPZignOicpKSAhPSAtMSkgewotCQlwcmVmaXggID0gdG9rZW4uc3Vic3RyaW5nKDAsY29sKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJcHJlZml4ID0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotCSAgICB9Ci0KLQkgICAgbmFtZXNwYWNlID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0JICAgIGlmIChuYW1lc3BhY2UgIT0gbnVsbCkKLQkJZWxlbWVudHMuYXBwZW5kKG5hbWVzcGFjZSsiOiIrCi0JCQkJdG9rZW4uc3Vic3RyaW5nKGNvbCsxLHRva2VuLmxlbmd0aCgpKSk7Ci0JICAgIGVsc2UKLQkJZWxlbWVudHMuYXBwZW5kKHRva2VuKTsKLQotCSAgICBpZiAobGlzdC5oYXNNb3JlRWxlbWVudHMoKSkKLQkJZWxlbWVudHMuYXBwZW5kKCIgIik7Ci0JfQotCV9lbGVtZW50TGlzdCA9IGVsZW1lbnRzLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBEZS10b2tlbml6ZSB0aGUgZWxlbWVudHMgbGlzdGVkIGluIHRoZSAnZWxlbWVudHMnIGF0dHJpYnV0ZSBhbmQKLSAgICAgKiBpbnN0YW5jaWF0ZSBhIHNldCBvZiBzdHJpcC9wcmVzZXJ2ZSBydWxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgVmVjdG9yIGdldFJ1bGVzKCkgewotCWZpbmFsIFZlY3RvciBydWxlcyA9IG5ldyBWZWN0b3IoKTsKLQkvLyBHbyB0aHJvdWdoIGVhY2ggZWxlbWVudCBhbmQgaW5zdGFuY2lhdGUgc3RyaXAvcHJlc2VydmUtb2JqZWN0Ci0JZmluYWwgU3RyaW5nVG9rZW5pemVyIGxpc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKF9lbGVtZW50TGlzdCk7Ci0Jd2hpbGUgKGxpc3QuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkgICAgcnVsZXMuYWRkKG5ldyBXaGl0ZXNwYWNlUnVsZShfYWN0aW9uLAotCQkJCQkgbGlzdC5uZXh0VG9rZW4oKSwKLQkJCQkJIF9pbXBvcnRQcmVjZWRlbmNlKSk7Ci0JfQotCXJldHVybiBydWxlczsKLSAgICB9Ci0gICAgCi0gICAgCi0gICAgLyoqCi0gICAgICogU2NhbnMgdGhyb3VnaCB0aGUgcnVsZXMgdmVjdG9yIGFuZCBsb29rcyBmb3IgYSBydWxlIG9mIGhpZ2hlcgotICAgICAqIHByaW9yaXR5IHRoYXQgY29udHJhZGljdHMgdGhlIGN1cnJlbnQgcnVsZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBXaGl0ZXNwYWNlUnVsZSBmaW5kQ29udHJhZGljdGluZ1J1bGUoVmVjdG9yIHJ1bGVzLAotCQkJCQkJCVdoaXRlc3BhY2VSdWxlIHJ1bGUpIHsKLQlmb3IgKGludCBpID0gMDsgaSA8IHJ1bGVzLnNpemUoKTsgaSsrKSB7Ci0JICAgIC8vIEdldCB0aGUgbmV4dCBydWxlIGluIHRoZSBwcmlvcml0aXplZCBsaXN0Ci0JICAgIFdoaXRlc3BhY2VSdWxlIGN1cnJlbnRSdWxlID0gKFdoaXRlc3BhY2VSdWxlKXJ1bGVzLmVsZW1lbnRBdChpKTsKLQkgICAgLy8gV2Ugb25seSBjb25zaWRlciBydWxlcyB3aXRoIGhpZ2hlciBwcmlvcml0eQotCSAgICBpZiAoY3VycmVudFJ1bGUgPT0gcnVsZSkgewotCQlyZXR1cm4gbnVsbDsKLQkgICAgfQotCSAgICAKLQkgICAgLyoKLQkgICAgICogU2VlIGlmIHRoZXJlIGlzIGEgY29udHJhZGljdGluZyBydWxlIHdpdGggaGlnaGVyIHByaW9yaXR5LgotCSAgICAgKiBJZiB0aGUgcnVsZXMgaGFzIHRoZSBzYW1lIGFjdGlvbiB0aGVuIHRoaXMgcnVsZSBpcyByZWR1bmRhbnQsCi0JICAgICAqIGlmIHRoZXkgaGF2ZSBkaWZmZXJlbnQgYWN0aW9uIHRoZW4gdGhpcyBydWxlIHdpbGwgbmV2ZXIgd2luLgotCSAgICAgKi8KLQkgICAgc3dpdGNoIChjdXJyZW50UnVsZS5nZXRTdHJlbmd0aCgpKSB7Ci0JICAgIGNhc2UgUlVMRV9BTEw6Ci0JCXJldHVybiBjdXJyZW50UnVsZTsKLQkJCi0JICAgIGNhc2UgUlVMRV9FTEVNRU5UOgotCQlpZiAoIXJ1bGUuZ2V0RWxlbWVudCgpLmVxdWFscyhjdXJyZW50UnVsZS5nZXRFbGVtZW50KCkpKSB7Ci0JCSAgICBicmVhazsKLQkJfQotCQkvLyBpbnRlbnRpb25hbCBmYWxsLXRocm91Z2gKLQkgICAgY2FzZSBSVUxFX05BTUVTUEFDRToKLQkJaWYgKHJ1bGUuZ2V0TmFtZXNwYWNlKCkuZXF1YWxzKGN1cnJlbnRSdWxlLmdldE5hbWVzcGFjZSgpKSkgewotCQkgICAgcmV0dXJuIGN1cnJlbnRSdWxlOwotCQl9Ci0JCWJyZWFrOwotCSAgICB9Ci0JfQotCXJldHVybiBudWxsOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogT3JkZXJzIGEgc2V0IG9yIHJ1bGVzIGJ5IHByaW9yaXR5LCByZW1vdmVzIHJlZHVuZGFudCBydWxlcyBhbmQgcnVsZXMKLSAgICAgKiB0aGF0IGFyZSBzaGFkb3dlZCBieSBzdHJvbmdlciwgY29udHJhZGljdGluZyBydWxlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgcHJpb3JpdGl6ZVJ1bGVzKFZlY3RvciBydWxlcykgewotCVdoaXRlc3BhY2VSdWxlIGN1cnJlbnRSdWxlOwotCWludCBkZWZhdWx0QWN0aW9uID0gUFJFU0VSVkVfU1BBQ0U7Ci0KLQkvLyBTb3J0IGFsbCBydWxlcyB3aXRoIHJlZ2FyZCB0byBwcmlvcml0eQotCXF1aWNrc29ydChydWxlcywgMCwgcnVsZXMuc2l6ZSgpLTEpOwotCi0JLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIGFueSAieHNsOnN0cmlwLXNwYWNlIiBlbGVtZW50cyBhdCBhbGwuCi0JLy8gSWYgdGhlcmUgYXJlIG5vIHhzbDpzdHJpcCBlbGVtZW50cyB3ZSBjYW4gaWdub3JlIGFsbCB4c2w6cHJlc2VydmUKLQkvLyBlbGVtZW50cyBhbmQgc2lnbmFsIHRoYXQgYWxsIHdoaXRlc3BhY2VzIHNob3VsZCBiZSBwcmVzZXJ2ZWQKLQlib29sZWFuIHN0cmlwID0gZmFsc2U7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBydWxlcy5zaXplKCk7IGkrKykgewotCSAgICBjdXJyZW50UnVsZSA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5lbGVtZW50QXQoaSk7Ci0JICAgIGlmIChjdXJyZW50UnVsZS5nZXRBY3Rpb24oKSA9PSBTVFJJUF9TUEFDRSkgewotCQlzdHJpcCA9IHRydWU7Ci0JICAgIH0KLQl9Ci0JLy8gUmV0dXJuIHdpdGggZGVmYXVsdCBhY3Rpb246IFBSRVNFUlZFX1NQQUNFCi0JaWYgKCFzdHJpcCkgewotCSAgICBydWxlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotCSAgICByZXR1cm4gUFJFU0VSVkVfU1BBQ0U7Ci0JfQotCi0JLy8gUmVtb3ZlIGFsbCBydWxlcyB0aGF0IGFyZSBjb250cmFkaWN0ZWQgYnkgcnVsZXMgd2l0aCBoaWdoZXIgcHJpb3JpdHkKLQlmb3IgKGludCBpZHggPSAwOyBpZHggPCBydWxlcy5zaXplKCk7ICkgewotCSAgICBjdXJyZW50UnVsZSA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5lbGVtZW50QXQoaWR4KTsKLQkKLQkgICAgLy8gUmVtb3ZlIHRoaXMgc2luZ2xlIHJ1bGUgaWYgaXQgaGFzIG5vIHB1cnBvc2UKLQkgICAgaWYgKGZpbmRDb250cmFkaWN0aW5nUnVsZShydWxlcyxjdXJyZW50UnVsZSkgIT0gbnVsbCkgewotCQlydWxlcy5yZW1vdmUoaWR4KTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJLy8gUmVtb3ZlIGFsbCBmb2xsb3dpbmcgcnVsZXMgaWYgdGhpcyBvbmUgb3ZlcnJpZGVzIGFsbAotCQlpZiAoY3VycmVudFJ1bGUuZ2V0U3RyZW5ndGgoKSA9PSBSVUxFX0FMTCkgewotCQkgICAgZGVmYXVsdEFjdGlvbiA9IGN1cnJlbnRSdWxlLmdldEFjdGlvbigpOwotCQkgICAgZm9yIChpbnQgaSA9IGlkeDsgaSA8IHJ1bGVzLnNpemUoKTsgaSsrKSB7Ci0JCQlydWxlcy5yZW1vdmVFbGVtZW50QXQoaSk7Ci0JCSAgICB9Ci0JCX0KLQkJLy8gU2tpcCB0byBuZXh0IHJ1bGUgKHRoZXJlIG1pZ2h0IG5vdCBiZSBhbnkpLi4uCi0JCWlkeCsrOwotCSAgICB9Ci0JfQotCi0JLy8gVGhlIHJ1bGVzIHZlY3RvciBjb3VsZCBiZSBlbXB0eSBpZiBmaXJzdCBydWxlIGhhcyBzdHJlbmd0aCBSVUxFX0FMTAotCWlmIChydWxlcy5zaXplKCkgPT0gMCkgewotCSAgICByZXR1cm4gZGVmYXVsdEFjdGlvbjsKLQl9Ci0KLQkvLyBOb3cgd29yayBiYWNrd2FyZHMgYW5kIHN0cmlwIGF3YXkgYWxsIHJ1bGVzIHRoYXQgaGF2ZSB0aGUgc2FtZQotCS8vIGFjdGlvbiBhcyB0aGUgZGVmYXVsdCBydWxlIChubyByZWFzb24gdGhlIGNoZWNrIHRoZW0gYXQgdGhlIGVuZCkuCi0JZG8gewotCSAgICBjdXJyZW50UnVsZSA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5sYXN0RWxlbWVudCgpOwotCSAgICBpZiAoY3VycmVudFJ1bGUuZ2V0QWN0aW9uKCkgPT0gZGVmYXVsdEFjdGlvbikgewotCQlydWxlcy5yZW1vdmVFbGVtZW50QXQocnVsZXMuc2l6ZSgpIC0gMSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWJyZWFrOwotCSAgICB9Ci0JfSB3aGlsZSAocnVsZXMuc2l6ZSgpID4gMCk7Ci0JCi0JLy8gU2lnbmFsIHRoYXQgd2hpdGVzcGFjZSBkZXRlY3Rpb24gcHJlZGljYXRlIG11c3QgYmUgdXNlZC4KLQlyZXR1cm4gZGVmYXVsdEFjdGlvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY29tcGlsZVN0cmlwU3BhY2UoQnJhbmNoSGFuZGxlIHN0cmlwW10sIAotCQkJCQkgaW50IHNDb3VudCwKLQkJCQkJIEluc3RydWN0aW9uTGlzdCBpbCkgewotCWZpbmFsIEluc3RydWN0aW9uSGFuZGxlIHRhcmdldCA9IGlsLmFwcGVuZChJQ09OU1RfMSk7Ci0JaWwuYXBwZW5kKElSRVRVUk4pOwotCWZvciAoaW50IGkgPSAwOyBpIDwgc0NvdW50OyBpKyspIHsKLQkgICAgc3RyaXBbaV0uc2V0VGFyZ2V0KHRhcmdldCk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjb21waWxlUHJlc2VydmVTcGFjZShCcmFuY2hIYW5kbGUgcHJlc2VydmVbXSwgCi0JCQkJCSAgICBpbnQgcENvdW50LAotCQkJCQkgICAgSW5zdHJ1Y3Rpb25MaXN0IGlsKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25IYW5kbGUgdGFyZ2V0ID0gaWwuYXBwZW5kKElDT05TVF8wKTsKLQlpbC5hcHBlbmQoSVJFVFVSTik7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBwQ291bnQ7IGkrKykgewotCSAgICBwcmVzZXJ2ZVtpXS5zZXRUYXJnZXQodGFyZ2V0KTsKLQl9Ci0gICAgfQotCi0gICAgLyoKLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvbXBpbGVEZWJ1ZyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCQkgICAgIEluc3RydWN0aW9uTGlzdCBpbCkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBpbnQgcHJ0ID0gY3BnLmFkZE1ldGhvZHJlZigiamF2YS9sYW5nL1N5c3RlbS9vdXQiLAotCQkJCQkgInByaW50bG4iLAotCQkJCQkgIihMamF2YS9sYW5nL1N0cmluZzspViIpOwotCWlsLmFwcGVuZChEVVApOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHBydCkpOwotICAgIH0KLSAgICAqLwotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgdGhlIHByZWRpY2F0ZSBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvbXBpbGVQcmVkaWNhdGUoVmVjdG9yIHJ1bGVzLAotCQkJCQkgaW50IGRlZmF1bHRBY3Rpb24sCi0JCQkJCSBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgWFNMVEMgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotCi0JLy8gcHJpdmF0ZSBib29sZWFuIFRyYW5zbGV0LnN0cmlwU3BhY2UoaW50IHR5cGUpIC0gY2Fubm90IGJlIHN0YXRpYwotCWZpbmFsIE1ldGhvZEdlbmVyYXRvciBzdHJpcFNwYWNlID0KLQkgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMICwKLQkJCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuQk9PTEVBTiwgCi0JCQluZXcgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVtdIHsKLQkJCSAgICBVdGlsLmdldEpDUmVmVHlwZShET01fSU5URl9TSUcpLAotCQkJICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5UCi0JCQl9LAotCQkJbmV3IFN0cmluZ1tdIHsgImRvbSIsIm5vZGUiLCJ0eXBlIiB9LAotCQkJInN0cmlwU3BhY2UiLGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLGlsLGNwZyk7Ci0KLQljbGFzc0dlbi5hZGRJbnRlcmZhY2UoIm9yZy9hcGFjaGUveGFsYW4veHNsdGMvU3RyaXBGaWx0ZXIiKTsKLQotCWZpbmFsIGludCBwYXJhbURvbSA9IHN0cmlwU3BhY2UuZ2V0TG9jYWxJbmRleCgiZG9tIik7Ci0JZmluYWwgaW50IHBhcmFtQ3VycmVudCA9IHN0cmlwU3BhY2UuZ2V0TG9jYWxJbmRleCgibm9kZSIpOwotCWZpbmFsIGludCBwYXJhbVR5cGUgPSBzdHJpcFNwYWNlLmdldExvY2FsSW5kZXgoInR5cGUiKTsKLQotCUJyYW5jaEhhbmRsZSBzdHJpcFtdID0gbmV3IEJyYW5jaEhhbmRsZVtydWxlcy5zaXplKCldOwotCUJyYW5jaEhhbmRsZSBwcmVzZXJ2ZVtdID0gbmV3IEJyYW5jaEhhbmRsZVtydWxlcy5zaXplKCldOwotCWludCBzQ291bnQgPSAwOwotCWludCBwQ291bnQgPSAwOwotCi0JLy8gVHJhdmVyc2UgYWxsIHN0cmlwL3ByZXNlcnZlIHJ1bGVzCi0JZm9yIChpbnQgaSA9IDA7IGk8cnVsZXMuc2l6ZSgpOyBpKyspIHsKLQkgICAgLy8gR2V0IHRoZSBuZXh0IHJ1bGUgaW4gdGhlIHByaW9yaXRpc2VkIGxpc3QKLQkgICAgV2hpdGVzcGFjZVJ1bGUgcnVsZSA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5lbGVtZW50QXQoaSk7Ci0KLQkgICAgLy8gUmV0dXJucyB0aGUgbmFtZXNwYWNlIGZvciBhIG5vZGUgaW4gdGhlIERPTQotCSAgICBmaW5hbCBpbnQgZ25zID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgICAgICJnZXROYW1lc3BhY2VOYW1lIiwKLQkJCQkJCSAgICAgICIoSSlMamF2YS9sYW5nL1N0cmluZzsiKTsKLQotCSAgICBmaW5hbCBpbnQgc3RyY21wID0gY3BnLmFkZE1ldGhvZHJlZigiamF2YS9sYW5nL1N0cmluZyIsCi0JCQkJCQkiY29tcGFyZVRvIiwKLQkJCQkJCSIoTGphdmEvbGFuZy9TdHJpbmc7KUkiKTsKLQotCSAgICAvLyBIYW5kbGUgZWxlbWVudHM9Im5zOioiIHR5cGUgcnVsZQotCSAgICBpZiAocnVsZS5nZXRTdHJlbmd0aCgpID09IFJVTEVfTkFNRVNQQUNFKSB7Ci0JCWlsLmFwcGVuZChuZXcgQUxPQUQocGFyYW1Eb20pKTsKLQkJaWwuYXBwZW5kKG5ldyBJTE9BRChwYXJhbUN1cnJlbnQpKTsKLQkJaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoZ25zLDIpKTsKLQkJaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgcnVsZS5nZXROYW1lc3BhY2UoKSkpOwotCQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoc3RyY21wKSk7Ci0JCWlsLmFwcGVuZChJQ09OU1RfMCk7Ci0KLQkJaWYgKHJ1bGUuZ2V0QWN0aW9uKCkgPT0gU1RSSVBfU1BBQ0UpIHsKLQkJICAgIHN0cmlwW3NDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLQkJfQotCQllbHNlIHsKLQkJICAgIHByZXNlcnZlW3BDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLQkJfQotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSBlbGVtZW50cz0ibnM6ZWwiIHR5cGUgcnVsZQotCSAgICBlbHNlIGlmIChydWxlLmdldFN0cmVuZ3RoKCkgPT0gUlVMRV9FTEVNRU5UKSB7Ci0JCS8vIENyZWF0ZSB0aGUgUU5hbWUgZm9yIHRoZSBlbGVtZW50Ci0JCWZpbmFsIFBhcnNlciBwYXJzZXIgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKTsKLQkJUU5hbWUgcW5hbWU7Ci0JCWlmIChydWxlLmdldE5hbWVzcGFjZSgpICE9IENvbnN0YW50cy5FTVBUWVNUUklORyApCi0JCSAgICBxbmFtZSA9IHBhcnNlci5nZXRRTmFtZShydWxlLmdldE5hbWVzcGFjZSgpLCBudWxsLAotCQkJCQkgICAgcnVsZS5nZXRFbGVtZW50KCkpOwotCQllbHNlCi0JCSAgICBxbmFtZSA9IHBhcnNlci5nZXRRTmFtZShydWxlLmdldEVsZW1lbnQoKSk7Ci0KLQkJLy8gUmVnaXN0ZXIgdGhlIGVsZW1lbnQuCi0JCWZpbmFsIGludCBlbGVtZW50VHlwZSA9IHhzbHRjLnJlZ2lzdGVyRWxlbWVudChxbmFtZSk7Ci0JCWlsLmFwcGVuZChuZXcgSUxPQUQocGFyYW1UeXBlKSk7Ci0JCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIGVsZW1lbnRUeXBlKSk7Ci0KLQkJLy8gQ29tcGFyZSBjdXJyZW50IG5vZGUgdHlwZSB3aXRoIHdhbnRlZCBlbGVtZW50IHR5cGUKLQkJaWYgKHJ1bGUuZ2V0QWN0aW9uKCkgPT0gU1RSSVBfU1BBQ0UpCi0JCSAgICBzdHJpcFtzQ291bnQrK10gPSBpbC5hcHBlbmQobmV3IElGX0lDTVBFUShudWxsKSk7Ci0JCWVsc2UKLQkJICAgIHByZXNlcnZlW3BDb3VudCsrXSA9IGlsLmFwcGVuZChuZXcgSUZfSUNNUEVRKG51bGwpKTsKLQkgICAgfQotCX0KLQotCWlmIChkZWZhdWx0QWN0aW9uID09IFNUUklQX1NQQUNFKSB7Ci0JICAgIGNvbXBpbGVTdHJpcFNwYWNlKHN0cmlwLCBzQ291bnQsIGlsKTsKLQkgICAgY29tcGlsZVByZXNlcnZlU3BhY2UocHJlc2VydmUsIHBDb3VudCwgaWwpOwotCX0KLQllbHNlIHsKLQkgICAgY29tcGlsZVByZXNlcnZlU3BhY2UocHJlc2VydmUsIHBDb3VudCwgaWwpOwotCSAgICBjb21waWxlU3RyaXBTcGFjZShzdHJpcCwgc0NvdW50LCBpbCk7Ci0JfQotCi0Jc3RyaXBTcGFjZS5zdHJpcEF0dHJpYnV0ZXModHJ1ZSk7Ci0Jc3RyaXBTcGFjZS5zZXRNYXhMb2NhbHMoKTsKLQlzdHJpcFNwYWNlLnNldE1heFN0YWNrKCk7Ci0Jc3RyaXBTcGFjZS5yZW1vdmVOT1BzKCk7Ci0KLQljbGFzc0dlbi5hZGRNZXRob2Qoc3RyaXBTcGFjZS5nZXRNZXRob2QoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgdGhlIHByZWRpY2F0ZSBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvbXBpbGVEZWZhdWx0KGludCBkZWZhdWx0QWN0aW9uLAotCQkJCSAgICAgICBDbGFzc0dlbmVyYXRvciBjbGFzc0dlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBuZXcgSW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JZmluYWwgWFNMVEMgeHNsdGMgPSBjbGFzc0dlbi5nZXRQYXJzZXIoKS5nZXRYU0xUQygpOwotCi0JLy8gcHJpdmF0ZSBib29sZWFuIFRyYW5zbGV0LnN0cmlwU3BhY2UoaW50IHR5cGUpIC0gY2Fubm90IGJlIHN0YXRpYwotCWZpbmFsIE1ldGhvZEdlbmVyYXRvciBzdHJpcFNwYWNlID0KLQkgICAgbmV3IE1ldGhvZEdlbmVyYXRvcihBQ0NfUFVCTElDIHwgQUNDX0ZJTkFMICwKLQkJCWRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuQk9PTEVBTiwgCi0JCQluZXcgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVtdIHsKLQkJCSAgICBVdGlsLmdldEpDUmVmVHlwZShET01fSU5URl9TSUcpLAotCQkJICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5ULAotCQkJICAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuSU5UCi0JCQl9LAotCQkJbmV3IFN0cmluZ1tdIHsgImRvbSIsIm5vZGUiLCJ0eXBlIiB9LAotCQkJInN0cmlwU3BhY2UiLGNsYXNzR2VuLmdldENsYXNzTmFtZSgpLGlsLGNwZyk7Ci0KLQljbGFzc0dlbi5hZGRJbnRlcmZhY2UoIm9yZy9hcGFjaGUveGFsYW4veHNsdGMvU3RyaXBGaWx0ZXIiKTsKLQotCWlmIChkZWZhdWx0QWN0aW9uID09IFNUUklQX1NQQUNFKQotCSAgICBpbC5hcHBlbmQoSUNPTlNUXzEpOwotCWVsc2UKLQkgICAgaWwuYXBwZW5kKElDT05TVF8wKTsKLQlpbC5hcHBlbmQoSVJFVFVSTik7Ci0KLQlzdHJpcFNwYWNlLnN0cmlwQXR0cmlidXRlcyh0cnVlKTsKLQlzdHJpcFNwYWNlLnNldE1heExvY2FscygpOwotCXN0cmlwU3BhY2Uuc2V0TWF4U3RhY2soKTsKLQlzdHJpcFNwYWNlLnJlbW92ZU5PUHMoKTsKLQotCWNsYXNzR2VuLmFkZE1ldGhvZChzdHJpcFNwYWNlLmdldE1ldGhvZCgpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFRha2VzIGEgdmVjdG9yIG9mIFdoaXRlc3BhY2VSdWxlIG9iamVjdHMgYW5kIGdlbmVyYXRlcyBhIHByZWRpY2F0ZQotICAgICAqIG1ldGhvZC4gVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgdHJhbnNsZXRzIGRlZmF1bHQgYWN0aW9uIGZvciBoYW5kbGluZwotICAgICAqIHdoaXRlc3BhY2UgdGV4dC1ub2RlczoKLSAgICAgKiAgICAtIFVTRV9QUkVESUNBVEUgIChydW4gdGhlIG1ldGhvZCBnZW5lcmF0ZWQgYnkgdGhpcyBtZXRob2QpCi0gICAgICogICAgLSBTVFJJUF9TUEFDRSAgICAoYWx3YXlzIHN0cmlwIHdoaXRlc3BhY2UgdGV4dC1ub2RlcykKLSAgICAgKiAgICAtIFBSRVNFUlZFX1NQQUNFIChhbHdheXMgcHJlc2VydmUgd2hpdGVzcGFjZSB0ZXh0LW5vZGVzKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgaW50IHRyYW5zbGF0ZVJ1bGVzKFZlY3RvciBydWxlcywKLQkJCQkgICAgIENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKSB7Ci0JLy8gR2V0IHRoZSBjb3JlIHJ1bGVzIGluIHByaW9yaXRpemVkIG9yZGVyCi0JZmluYWwgaW50IGRlZmF1bHRBY3Rpb24gPSBwcmlvcml0aXplUnVsZXMocnVsZXMpOwotCS8vIFRoZSBydWxlcyB2ZWN0b3IgbWF5IGJlIGVtcHR5IGFmdGVyIHByaW9yaXRpc2luZwotCWlmIChydWxlcy5zaXplKCkgPT0gMCkgewotCSAgICBjb21waWxlRGVmYXVsdChkZWZhdWx0QWN0aW9uLGNsYXNzR2VuKTsKLQkgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb247Ci0JfQotCS8vIE5vdyAtIGNyZWF0ZSBhIHByZWRpY2F0ZSBtZXRob2QgYW5kIHNlcXVlbmNlIHRocm91Z2ggcnVsZXMuLi4KLQljb21waWxlUHJlZGljYXRlKHJ1bGVzLCBkZWZhdWx0QWN0aW9uLCBjbGFzc0dlbik7Ci0JLy8gUmV0dXJuIHdpdGggdGhlIHRyYW5zbGV0cyByZXF1aXJlZCBhY3Rpb24gKAotCXJldHVybiBVU0VfUFJFRElDQVRFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNvcnRzIGEgcmFuZ2Ugb2YgcnVsZXMgd2l0aCByZWdhcmQgdG8gUFJJT1JJVFkgb25seQotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcXVpY2tzb3J0KFZlY3RvciBydWxlcywgaW50IHAsIGludCByKSB7Ci0Jd2hpbGUgKHAgPCByKSB7Ci0JICAgIGZpbmFsIGludCBxID0gcGFydGl0aW9uKHJ1bGVzLCBwLCByKTsKLQkgICAgcXVpY2tzb3J0KHJ1bGVzLCBwLCBxKTsKLQkgICAgcCA9IHEgKyAxOwotCX0KLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogVXNlZCB3aXRoIHF1aWNrc29ydCBtZXRob2QgYWJvdmUKLSAgICAgKi8KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgcGFydGl0aW9uKFZlY3RvciBydWxlcywgaW50IHAsIGludCByKSB7Ci0JZmluYWwgV2hpdGVzcGFjZVJ1bGUgeCA9IChXaGl0ZXNwYWNlUnVsZSlydWxlcy5lbGVtZW50QXQoKHArcikgPj4+IDEpOwotCWludCBpID0gcCAtIDEsIGogPSByICsgMTsKLQl3aGlsZSAodHJ1ZSkgewotCSAgICB3aGlsZSAoeC5jb21wYXJlVG8oKFdoaXRlc3BhY2VSdWxlKXJ1bGVzLmVsZW1lbnRBdCgtLWopKSA8IDApIHsKLQkgICAgfQotCSAgICB3aGlsZSAoeC5jb21wYXJlVG8oKFdoaXRlc3BhY2VSdWxlKXJ1bGVzLmVsZW1lbnRBdCgrK2kpKSA+IDApIHsKLQkgICAgfQotCSAgICBpZiAoaSA8IGopIHsKLQkJZmluYWwgV2hpdGVzcGFjZVJ1bGUgdG1wID0gKFdoaXRlc3BhY2VSdWxlKXJ1bGVzLmVsZW1lbnRBdChpKTsKLQkJcnVsZXMuc2V0RWxlbWVudEF0KHJ1bGVzLmVsZW1lbnRBdChqKSwgaSk7Ci0JCXJ1bGVzLnNldEVsZW1lbnRBdCh0bXAsIGopOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlyZXR1cm4gajsKLQkgICAgfQotCX0KLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogVHlwZS1jaGVjayBjb250ZW50cy9hdHRyaWJ1dGVzIC0gbm90aGluZyB0byBkby4uLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JcmV0dXJuIFR5cGUuVm9pZDsgLy8gV2UgZG9uJ3QgcmV0dXJuIGFueXRoaW5nLgotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgcHJvZHVjZSBhbnkgY29kZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1dpdGhQYXJhbS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvV2l0aFBhcmFtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBjYjRmZTIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvV2l0aFBhcmFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIEpvaG4gSG93YXJkIDxKb2huSEBzY2hlbWFzb2Z0LmNvbT4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlJlZmVyZW5jZVR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjsKLQotZmluYWwgY2xhc3MgV2l0aFBhcmFtIGV4dGVuZHMgSW5zdHJ1Y3Rpb24gewotCi0gICAgcHJpdmF0ZSBRTmFtZSBfbmFtZTsKLSAgICBwcml2YXRlIEV4cHJlc3Npb24gX3NlbGVjdDsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXlzIHRoZSBjb250ZW50cyBvZiB0aGlzIGVsZW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBkaXNwbGF5KGludCBpbmRlbnQpIHsKLQlpbmRlbnQoaW5kZW50KTsKLQlVdGlsLnByaW50bG4oIndpdGgtcGFyYW0gIiArIF9uYW1lKTsKLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIGluZGVudChpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotCSAgICBVdGlsLnByaW50bG4oInNlbGVjdCAiICsgX3NlbGVjdC50b1N0cmluZygpKTsKLQl9Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIGNvbnRlbnRzIG9mIGEgPHhzbDp3aXRoLXBhcmFtPiBlbGVtZW50cyBhcmUgZWl0aGVyIGluIHRoZSBlbGVtZW50J3MKLSAgICAgKiAnc2VsZWN0JyBhdHRyaWJ1dGUgKHRoaXMgaGFzIHByZWNlZGVuY2UpIG9yIGluIHRoZSBlbGVtZW50IGJvZHkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0JZmluYWwgU3RyaW5nIG5hbWUgPSBnZXRBdHRyaWJ1dGUoIm5hbWUiKTsKLQlpZiAobmFtZS5sZW5ndGgoKSA+IDApIHsKLQkgICAgX25hbWUgPSBwYXJzZXIuZ2V0UU5hbWUobmFtZSk7Ci0JfQotICAgICAgICBlbHNlIHsKLQkgICAgcmVwb3J0RXJyb3IodGhpcywgcGFyc2VyLCBFcnJvck1zZy5OUkVRQVRUUl9FUlIsICJuYW1lIik7Ci0gICAgICAgIH0KLQkKLQlmaW5hbCBTdHJpbmcgc2VsZWN0ID0gZ2V0QXR0cmlidXRlKCJzZWxlY3QiKTsKLQlpZiAoc2VsZWN0Lmxlbmd0aCgpID4gMCkgewotCSAgICBfc2VsZWN0ID0gcGFyc2VyLnBhcnNlRXhwcmVzc2lvbih0aGlzLCAic2VsZWN0IiwgbnVsbCk7Ci0JfQotCQotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUeXBlLWNoZWNrIGVpdGhlciB0aGUgc2VsZWN0IGF0dHJpYnV0ZSBvciB0aGUgZWxlbWVudCBib2R5LCBkZXBlbmRpbmcKLSAgICAgKiBvbiB3aGljaCBpcyBpbiB1c2UuCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIFR5cGUgdHNlbGVjdCA9IF9zZWxlY3QudHlwZUNoZWNrKHN0YWJsZSk7Ci0JICAgIGlmICh0c2VsZWN0IGluc3RhbmNlb2YgUmVmZXJlbmNlVHlwZSA9PSBmYWxzZSkgewotCQlfc2VsZWN0ID0gbmV3IENhc3RFeHByKF9zZWxlY3QsIFR5cGUuUmVmZXJlbmNlKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgdHlwZUNoZWNrQ29udGVudHMoc3RhYmxlKTsKLQl9Ci0JcmV0dXJuIFR5cGUuVm9pZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlIHRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLCB3aGljaCBpcyBlaXRoZXIgaW4gYW4gZXhwcmVzc2lvbiBpbgotICAgICAqIGEgJ3NlbGVjdCcgYXR0cmlidXRlLCBvciBpbiB0aGUgd2l0aC1wYXJhbSBlbGVtZW50J3MgYm9keQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVZhbHVlKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQkvLyBDb21waWxlIGV4cHJlc3Npb24gaXMgJ3NlbGVjdCcgYXR0cmlidXRlIGlmIHByZXNlbnQKLQlpZiAoX3NlbGVjdCAhPSBudWxsKSB7Ci0JICAgIF9zZWxlY3QudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICBfc2VsZWN0LnN0YXJ0UmVzZXRJdGVyYXRvcihjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQl9Ci0JLy8gSWYgbm90LCBjb21waWxlIHJlc3VsdCB0cmVlIGZyb20gcGFyYW1ldGVyIGJvZHkgaWYgcHJlc2VudC4KLQllbHNlIGlmIChoYXNDb250ZW50cygpKSB7Ci0JICAgIGNvbXBpbGVSZXN1bHRUcmVlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLQkvLyBJZiBuZWl0aGVyIGFyZSBwcmVzZW50IHRoZW4gc3RvcmUgZW1wdHkgc3RyaW5nIGluIHBhcmFtZXRlciBzbG90Ci0JZWxzZSB7Ci0JICAgIGZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQkgICAgZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCSAgICBpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBDb25zdGFudHMuRU1QVFlTVFJJTkcpKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBjb2RlIGdlbmVyYXRlcyBhIHNlcXVlbmNlIG9mIGJ5dGVjb2RlcyB0aGF0IGNhbGwgdGhlCi0gICAgICogYWRkUGFyYW1ldGVyKCkgbWV0aG9kIGluIEFic3RyYWN0VHJhbnNsZXQuIFRoZSBtZXRob2QgY2FsbCB3aWxsIGFkZAotICAgICAqIChvciB1cGRhdGUpIHRoZSBwYXJhbWV0ZXIgZnJhbWUgd2l0aCB0aGUgbmV3IHBhcmFtZXRlciB2YWx1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gTWFrZSBuYW1lIGFjY2VwdGFibGUgZm9yIHVzZSBhcyBmaWVsZCBuYW1lIGluIGNsYXNzCi0JLy8gVE9ETzogY29udmVydCB0byBlc2NhcGUgc2VxdWVuY2UgbGlrZSAkZG90JCBhbmQgJGRhc2gkCi0JU3RyaW5nIG5hbWUgPSBfbmFtZS5nZXRMb2NhbFBhcnQoKTsgLy8gVE9ETzogbmFtZXNwYWNlID8KLQluYW1lID0gbmFtZS5yZXBsYWNlKCcuJywgJ18nKTsKLQluYW1lID0gbmFtZS5yZXBsYWNlKCctJywgJ18nKTsKLQotCS8vIExvYWQgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2xldCAobWV0aG9kIGlzIGluIEFic3RyYWN0VHJhbnNsZXQpCi0JaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQotCS8vIExvYWQgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlcgotCWlsLmFwcGVuZChuZXcgUFVTSChjcGcsIG5hbWUpKTsgLy8gVE9ETzogbmFtZXNwYWNlID8KLQkvLyBHZW5lcmV0ZSB0aGUgdmFsdWUgb2YgdGhlIHBhcmFtZXRlciAodXNlIHZhbHVlIGluICdzZWxlY3QnIGJ5IGRlZi4pCi0JdHJhbnNsYXRlVmFsdWUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JLy8gTWFyayB0aGlzIHBhcmFtZXRlciB2YWx1ZSBpcyBub3QgYmVpbmcgdGhlIGRlZmF1bHQgdmFsdWUKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBmYWxzZSkpOwotCS8vIFBhc3MgdGhlIHBhcmFtZXRlciB0byB0aGUgdGVtcGxhdGUKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJCSAgICAgQUREX1BBUkFNRVRFUiwKLQkJCQkJCSAgICAgQUREX1BBUkFNRVRFUl9TSUcpKSk7Ci0JaWwuYXBwZW5kKFBPUCk7IC8vIGNsZWFudXAgc3RhY2sKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9YU0xUQy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvWFNMVEMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjgwODI3Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9YU0xUQy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODMzICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5TZXQ7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5EYXRlOwotaW1wb3J0IGphdmEudXRpbC5NYXA7Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuamFyLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY21kbGluZS5nZXRvcHQuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuY2xhc3NmaWxlLkphdmFDbGFzczsKLQotcHVibGljIGZpbmFsIGNsYXNzIFhTTFRDIHsKLQotICAgIC8vIEEgcmVmZXJlbmNlIHRvIHRoZSBtYWluIHN0eWxlc2hlZXQgcGFyc2VyIG9iamVjdC4KLSAgICBwcml2YXRlIFBhcnNlciBfcGFyc2VyOwotCi0gICAgLy8gQSByZWZlcmVuY2UgdG8gYW4gZXh0ZXJuYWwgWE1MUmVhZGVyIChTQVggcGFyc2VyKSBwYXNzZWQgdG8gdXMKLSAgICBwcml2YXRlIFhNTFJlYWRlciBfcmVhZGVyID0gbnVsbDsKLQotICAgIC8vIEEgcmVmZXJlbmNlIHRvIGFuIGV4dGVybmFsIFNvdXJjZUxvYWRlciAoZm9yIHVzZSB3aXRoIGluY2x1ZGUvaW1wb3J0KQotICAgIHByaXZhdGUgU291cmNlTG9hZGVyIF9sb2FkZXIgPSBudWxsOwotICAgIAotICAgIC8vIEEgcmVmZXJlbmNlIHRvIHRoZSBzdHlsZXNoZWV0IGJlaW5nIGNvbXBpbGVkLgotICAgIHByaXZhdGUgU3R5bGVzaGVldCBfc3R5bGVzaGVldCA9IG51bGw7Ci0KLSAgICAvLyBDb3VudGVycyB1c2VkIGJ5IHZhcmlvdXMgY2xhc3NlcyB0byBnZW5lcmF0ZSB1bmlxdWUgbmFtZXMuCi0gICAgLy8gcHJpdmF0ZSBpbnQgX3ZhcmlhYmxlU2VyaWFsICAgICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX21vZGVTZXJpYWwgICAgICAgICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX3N0eWxlc2hlZXRTZXJpYWwgICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX3N0ZXBQYXR0ZXJuU2VyaWFsICA9IDE7Ci0gICAgcHJpdmF0ZSBpbnQgX2hlbHBlckNsYXNzU2VyaWFsICA9IDA7Ci0gICAgcHJpdmF0ZSBpbnQgX2F0dHJpYnV0ZVNldFNlcmlhbCA9IDA7Ci0gICAgCi0gICAgcHJpdmF0ZSBpbnRbXSBfbnVtYmVyRmllbGRJbmRleGVzOwotICAgIAotICAgIC8vIE5hbWUgaW5kZXggdGFibGVzCi0gICAgcHJpdmF0ZSBpbnQgICAgICAgX25leHRHVHlwZTsgIC8vIE5leHQgYXZhaWxhYmxlIGVsZW1lbnQgdHlwZQotICAgIHByaXZhdGUgVmVjdG9yICAgIF9uYW1lc0luZGV4OyAvLyBJbmRleCBvZiBhbGwgcmVnaXN0ZXJlZCBRTmFtZXMKLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfZWxlbWVudHM7ICAgLy8gSGFzaHRhYmxlIG9mIGFsbCByZWdpc3RlcmVkIGVsZW1lbnRzCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgX2F0dHJpYnV0ZXM7IC8vIEhhc2h0YWJsZSBvZiBhbGwgcmVnaXN0ZXJlZCBhdHRyaWJ1dGVzCi0KLSAgICAvLyBOYW1lc3BhY2UgaW5kZXggdGFibGVzCi0gICAgcHJpdmF0ZSBpbnQgICAgICAgX25leHROU1R5cGU7IC8vIE5leHQgYXZhaWxhYmxlIG5hbWVzcGFjZSB0eXBlCi0gICAgcHJpdmF0ZSBWZWN0b3IgICAgX25hbWVzcGFjZUluZGV4OyAvLyBJbmRleCBvZiBhbGwgcmVnaXN0ZXJlZCBuYW1lc3BhY2VzCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgX25hbWVzcGFjZXM7IC8vIEhhc2h0YWJsZSBvZiBhbGwgcmVnaXN0ZXJlZCBuYW1lc3BhY2VzCi0KLSAgICAvLyBUaGVzZSBkZWZpbmUgdGhlIHZhcmlvdXMgbWV0aG9kcyBmb3Igb3V0cHV0dGluZyB0aGUgdHJhbnNsZXQKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUxFX09VVFBVVCAgICAgICAgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpBUl9PVVRQVVQgICAgICAgICA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQllURUFSUkFZX09VVFBVVCAgID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU0xPQURFUl9PVVRQVVQgPSAzOwotCi0gICAgLy8gQ29tcGlsZXIgb3B0aW9ucyAocGFzc2VkIGZyb20gY29tbWFuZCBsaW5lIG9yIFhTTFRDIGNsaWVudCkKLSAgICBwcml2YXRlIGJvb2xlYW4gX2RlYnVnID0gZmFsc2U7ICAgICAgLy8gLXgKLSAgICBwcml2YXRlIFN0cmluZyAgX2phckZpbGVOYW1lID0gbnVsbDsgLy8gLWogPGphci1maWxlLW5hbWU+Ci0gICAgcHJpdmF0ZSBTdHJpbmcgIF9jbGFzc05hbWUgPSBudWxsOyAgIC8vIC1vIDxjbGFzcy1uYW1lPgotICAgIHByaXZhdGUgU3RyaW5nICBfcGFja2FnZU5hbWUgPSBudWxsOyAvLyAtcCA8cGFja2FnZS1uYW1lPgotICAgIHByaXZhdGUgRmlsZSAgICBfZGVzdERpciA9IG51bGw7ICAgICAvLyAtZCA8ZGlyZWN0b3J5LW5hbWU+Ci0gICAgcHJpdmF0ZSBpbnQgICAgIF9vdXRwdXRUeXBlID0gRklMRV9PVVRQVVQ7IC8vIGJ5IGRlZmF1bHQKLQotICAgIHByaXZhdGUgVmVjdG9yICBfY2xhc3NlczsKLSAgICBwcml2YXRlIGJvb2xlYW4gX211bHRpRG9jdW1lbnQgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIFhTTFRDIGNvbXBpbGVyIGNvbnN0cnVjdG9yCi0gICAgICovCi0gICAgcHVibGljIFhTTFRDKCkgewotCV9wYXJzZXIgPSBuZXcgUGFyc2VyKHRoaXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9ubHkgZm9yIHVzZXIgYnkgdGhlIGludGVybmFsIFRyQVggaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyc2VyKFBhcnNlciBwYXJzZXIpIHsKLQlfcGFyc2VyID0gcGFyc2VyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE9ubHkgZm9yIHVzZXIgYnkgdGhlIGludGVybmFsIFRyQVggaW1wbGVtZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0VHlwZShpbnQgdHlwZSkgewotCV9vdXRwdXRUeXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplcyB0aGUgY29tcGlsZXIgdG8gY29tcGlsZSBhIG5ldyBzdHlsZXNoZWV0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgaW5pdCgpIHsKLQlyZXNldCgpOwotCV9yZWFkZXIgPSBudWxsOwotCV9jbGFzc2VzID0gbmV3IFZlY3RvcigpOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXplcyB0aGUgY29tcGlsZXIgdG8gcHJvZHVjZSBhIG5ldyB0cmFuc2xldAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCByZXNldCgpIHsKLQlfbmV4dEdUeXBlICAgICAgPSBET00uTlRZUEVTOwotCV9lbGVtZW50cyAgICAgICA9IG5ldyBIYXNodGFibGUoKTsKLQlfYXR0cmlidXRlcyAgICAgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JX25hbWVzcGFjZXMgICAgID0gbmV3IEhhc2h0YWJsZSgpOwotCV9uYW1lc3BhY2VzLnB1dCgiIixuZXcgSW50ZWdlcihfbmV4dE5TVHlwZSkpOwotCV9uYW1lc0luZGV4ICAgICA9IG5ldyBWZWN0b3IoMTI4KTsKLQlfbmFtZXNwYWNlSW5kZXggPSBuZXcgVmVjdG9yKDMyKTsKLQlfcGFyc2VyLmluaXQoKTsKLQkvL192YXJpYWJsZVNlcmlhbCAgICAgPSAxOwotCV9tb2RlU2VyaWFsICAgICAgICAgPSAxOwotCV9zdHlsZXNoZWV0U2VyaWFsICAgPSAxOwotCV9zdGVwUGF0dGVyblNlcmlhbCAgPSAxOwotCV9oZWxwZXJDbGFzc1NlcmlhbCAgPSAwOwotCV9hdHRyaWJ1dGVTZXRTZXJpYWwgPSAwOwotCV9tdWx0aURvY3VtZW50ICAgICAgPSBmYWxzZTsKLQlfbnVtYmVyRmllbGRJbmRleGVzID0gbmV3IGludFtdIHsKLQkgICAgLTEsIAkvLyBMRVZFTF9TSU5HTEUKLQkgICAgLTEsIAkvLyBMRVZFTF9NVUxUSVBMRQotCSAgICAtMQkJLy8gTEVWRUxfQU5ZCi0JfTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWZpbmVzIGFuIGV4dGVybmFsIFNvdXJjZUxvYWRlciB0byBwcm92aWRlIHRoZSBjb21waWxlciB3aXRoIGRvY3VtZW50cwotICAgICAqIHJlZmVyZW5jZWQgaW4geHNsOmluY2x1ZGUvaW1wb3J0Ci0gICAgICogQHBhcmFtIGxvYWRlciBUaGUgU291cmNlTG9hZGVyIHRvIHVzZSBmb3IgaW5jbHVkZS9pbXBvcnQKLSAgICAgKi8gICAgCi0gICAgcHVibGljIHZvaWQgc2V0U291cmNlTG9hZGVyKFNvdXJjZUxvYWRlciBsb2FkZXIpIHsKLQlfbG9hZGVyID0gbG9hZGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgcGFyYW1ldGVycyB0byB1c2UgdG8gbG9jYXRlIHRoZSBjb3JyZWN0IDw/eG1sLXN0eWxlc2hlZXQgLi4uPz4KLSAgICAgKiBwcm9jZXNzaW5nIGluc3RydWN0aW9uIGluIHRoZSBjYXNlIHdoZXJlIHRoZSBpbnB1dCBkb2N1bWVudCB0byB0aGUKLSAgICAgKiBjb21waWxlciAoYW5kIHBhcnNlcikgaXMgYW4gWE1MIGRvY3VtZW50LgotICAgICAqIEBwYXJhbSBtZWRpYSBUaGUgbWVkaWEgYXR0cmlidXRlIHRvIGJlIG1hdGNoZWQuIE1heSBiZSBudWxsLCBpbiB3aGljaAotICAgICAqIGNhc2UgdGhlIHByZWZlcmVkIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWQgKGkuZS4gYWx0ZXJuYXRlID0gbm8pLgotICAgICAqIEBwYXJhbSB0aXRsZSBUaGUgdmFsdWUgb2YgdGhlIHRpdGxlIGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICogQHBhcmFtIGNoYXJzZXQgVGhlIHZhbHVlIG9mIHRoZSBjaGFyc2V0IGF0dHJpYnV0ZSB0byBtYXRjaC4gTWF5IGJlIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UElQYXJhbWV0ZXJzKFN0cmluZyBtZWRpYSwgU3RyaW5nIHRpdGxlLCBTdHJpbmcgY2hhcnNldCkgewotCV9wYXJzZXIuc2V0UElQYXJhbWV0ZXJzKG1lZGlhLCB0aXRsZSwgY2hhcnNldCk7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGFuIFhTTCBzdHlsZXNoZWV0IHBvaW50ZWQgdG8gYnkgYSBVUkwKLSAgICAgKiBAcGFyYW0gdXJsIEFuIFVSTCBjb250YWluaW5nIHRoZSBpbnB1dCBYU0wgc3R5bGVzaGVldAotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbXBpbGUoVVJMIHVybCkgewotCXRyeSB7Ci0JICAgIC8vIE9wZW4gaW5wdXQgc3RyZWFtIGZyb20gVVJMIGFuZCB3cmFwIGluc2lkZSBJbnB1dFNvdXJjZQotCSAgICBmaW5hbCBJbnB1dFN0cmVhbSBzdHJlYW0gPSB1cmwub3BlblN0cmVhbSgpOwotCSAgICBmaW5hbCBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShzdHJlYW0pOwotCSAgICBpbnB1dC5zZXRTeXN0ZW1JZCh1cmwudG9TdHJpbmcoKSk7Ci0JICAgIHJldHVybiBjb21waWxlKGlucHV0LCBfY2xhc3NOYW1lKTsKLQl9Ci0JY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLQkgICAgX3BhcnNlci5yZXBvcnRFcnJvcihDb25zdGFudHMuRkFUQUwsIG5ldyBFcnJvck1zZyhlLmdldE1lc3NhZ2UoKSkpOwotCSAgICByZXR1cm4gZmFsc2U7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBpbGVzIGFuIFhTTCBzdHlsZXNoZWV0IHBvaW50ZWQgdG8gYnkgYSBVUkwKLSAgICAgKiBAcGFyYW0gdXJsIEFuIFVSTCBjb250YWluaW5nIHRoZSBpbnB1dCBYU0wgc3R5bGVzaGVldAotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIHRvIGFzc2lnbiB0byB0aGUgdHJhbnNsZXQgY2xhc3MKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb21waWxlKFVSTCB1cmwsIFN0cmluZyBuYW1lKSB7Ci0JdHJ5IHsKLQkgICAgLy8gT3BlbiBpbnB1dCBzdHJlYW0gZnJvbSBVUkwgYW5kIHdyYXAgaW5zaWRlIElucHV0U291cmNlCi0JICAgIGZpbmFsIElucHV0U3RyZWFtIHN0cmVhbSA9IHVybC5vcGVuU3RyZWFtKCk7Ci0JICAgIGZpbmFsIElucHV0U291cmNlIGlucHV0ID0gbmV3IElucHV0U291cmNlKHN0cmVhbSk7Ci0JICAgIGlucHV0LnNldFN5c3RlbUlkKHVybC50b1N0cmluZygpKTsKLQkgICAgcmV0dXJuIGNvbXBpbGUoaW5wdXQsIG5hbWUpOwotCX0KLQljYXRjaCAoSU9FeGNlcHRpb24gZSkgewotCSAgICBfcGFyc2VyLnJlcG9ydEVycm9yKENvbnN0YW50cy5GQVRBTCwgbmV3IEVycm9yTXNnKGUuZ2V0TWVzc2FnZSgpKSk7Ci0JICAgIHJldHVybiBmYWxzZTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYW4gWFNMIHN0eWxlc2hlZXQgcGFzc2VkIGluIHRocm91Z2ggYW4gSW5wdXRTdHJlYW0KLSAgICAgKiBAcGFyYW0gaW5wdXQgQW4gSW5wdXRTdHJlYW0gdGhhdCB3aWxsIHBhc3MgaW4gdGhlIHN0eWxlc2hlZXQgY29udGVudHMKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MgdG8gZ2VuZXJhdGUKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiB0aGUgY29tcGlsYXRpb24gd2FzIHN1Y2Nlc3NmdWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb21waWxlKElucHV0U3RyZWFtIHN0cmVhbSwgU3RyaW5nIG5hbWUpIHsKLQlmaW5hbCBJbnB1dFNvdXJjZSBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShzdHJlYW0pOwotCWlucHV0LnNldFN5c3RlbUlkKG5hbWUpOyAvLyBXZSBoYXZlIG5vdGhpbmcgZWxzZSEhIQotCXJldHVybiBjb21waWxlKGlucHV0LCBuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb21waWxlcyBhbiBYU0wgc3R5bGVzaGVldCBwYXNzZWQgaW4gdGhyb3VnaCBhbiBJbnB1dFN0cmVhbQotICAgICAqIEBwYXJhbSBpbnB1dCBBbiBJbnB1dFNvdXJjZSB0aGF0IHdpbGwgcGFzcyBpbiB0aGUgc3R5bGVzaGVldCBjb250ZW50cwotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmFuc2xldCBjbGFzcyB0byBnZW5lcmF0ZSAtIGNhbiBiZSBudWxsCi0gICAgICogQHJldHVybiAndHJ1ZScgaWYgdGhlIGNvbXBpbGF0aW9uIHdhcyBzdWNjZXNzZnVsCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gY29tcGlsZShJbnB1dFNvdXJjZSBpbnB1dCwgU3RyaW5nIG5hbWUpIHsKLQl0cnkgewotCSAgICAvLyBSZXNldCBnbG9iYWxzIGluIGNhc2Ugd2UncmUgY2FsbGVkIGJ5IGNvbXBpbGUoVmVjdG9yIHYpOwotCSAgICByZXNldCgpOwotCi0JICAgIC8vIFRoZSBzeXN0ZW1JZCBtYXkgbm90IGJlIHNldCwgc28gd2UnbGwgaGF2ZSB0byBjaGVjayB0aGUgVVJMCi0JICAgIFN0cmluZyBzeXN0ZW1JZCA9IG51bGw7IAotCSAgICBpZiAoaW5wdXQgIT0gbnVsbCkgewotCSAgICAgICAgc3lzdGVtSWQgPSBpbnB1dC5nZXRTeXN0ZW1JZCgpOwotCSAgICB9Ci0KLQkgICAgLy8gU2V0IHRoZSB0cmFuc2xldCBjbGFzcyBuYW1lIGlmIG5vdCBhbHJlYWR5IHNldAotCSAgICBpZiAoX2NsYXNzTmFtZSA9PSBudWxsKSB7Ci0JCWlmIChuYW1lICE9IG51bGwpCi0JCSAgICBzZXRDbGFzc05hbWUobmFtZSk7Ci0JCWVsc2UgaWYgKHN5c3RlbUlkICE9IG51bGwpCi0JCSAgICBzZXRDbGFzc05hbWUoVXRpbC5iYXNlTmFtZShzeXN0ZW1JZCkpOwotCQllbHNlCi0JCSAgICBzZXRDbGFzc05hbWUoIkdyZWdvclNhbXNhIik7IC8vIGRlZmF1bHQgdHJhbnNsZXQgbmFtZQotCSAgICB9Ci0KLQkgICAgLy8gR2V0IHRoZSByb290IG5vZGUgb2YgdGhlIGFic3RyYWN0IHN5bnRheCB0cmVlCi0JICAgIFN5bnRheFRyZWVOb2RlIGVsZW1lbnQgPSBudWxsOwotCSAgICBpZiAoX3JlYWRlciA9PSBudWxsKSB7Ci0JCWVsZW1lbnQgPSBfcGFyc2VyLnBhcnNlKGlucHV0KTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJZWxlbWVudCA9IF9wYXJzZXIucGFyc2UoX3JlYWRlciwgaW5wdXQpOwotCSAgICB9Ci0KLQkgICAgLy8gQ29tcGlsZSB0aGUgdHJhbnNsZXQgLSB0aGlzIGlzIHdoZXJlIHRoZSB3b3JrIGlzIGRvbmUhCi0JICAgIGlmICgoIV9wYXJzZXIuZXJyb3JzRm91bmQoKSkgJiYgKGVsZW1lbnQgIT0gbnVsbCkpIHsKLQkJLy8gQ3JlYXRlIGEgU3R5bGVzaGVldCBlbGVtZW50IGZyb20gdGhlIHJvb3Qgbm9kZQotCQlfc3R5bGVzaGVldCA9IF9wYXJzZXIubWFrZVN0eWxlc2hlZXQoZWxlbWVudCk7Ci0JCV9zdHlsZXNoZWV0LnNldFNvdXJjZUxvYWRlcihfbG9hZGVyKTsKLQkJX3N0eWxlc2hlZXQuc2V0U3lzdGVtSWQoc3lzdGVtSWQpOwotCQlfc3R5bGVzaGVldC5zZXRQYXJlbnRTdHlsZXNoZWV0KG51bGwpOwotCQlfcGFyc2VyLnNldEN1cnJlbnRTdHlsZXNoZWV0KF9zdHlsZXNoZWV0KTsKLQkJLy8gQ3JlYXRlIEFTVCB1bmRlciB0aGUgU3R5bGVzaGVldCBlbGVtZW50IChwYXJzZSAmIHR5cGUtY2hlY2spCi0JCV9wYXJzZXIuY3JlYXRlQVNUKF9zdHlsZXNoZWV0KTsKLQkgICAgfQotCSAgICAvLyBHZW5lcmF0ZSB0aGUgYnl0ZWNvZGVzIGFuZCBvdXRwdXQgdGhlIHRyYW5zbGV0IGNsYXNzKGVzKQotCSAgICBpZiAoKCFfcGFyc2VyLmVycm9yc0ZvdW5kKCkpICYmIChfc3R5bGVzaGVldCAhPSBudWxsKSkgewotCQlfc3R5bGVzaGVldC5zZXRNdWx0aURvY3VtZW50KF9tdWx0aURvY3VtZW50KTsKLQkJX3N0eWxlc2hlZXQudHJhbnNsYXRlKCk7Ci0JICAgIH0KLQl9Ci0JY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JICAgIGlmIChfZGVidWcpIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0JICAgIF9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkZBVEFMLCBuZXcgRXJyb3JNc2coZS5nZXRNZXNzYWdlKCkpKTsKLQl9Ci0JZmluYWxseSB7Ci0JICAgIF9yZWFkZXIgPSBudWxsOyAvLyByZXNldCB0aGlzIGhlcmUgdG8gYmUgc3VyZSBpdCBpcyBub3QgcmUtdXNlZAotCSAgICByZXR1cm4gIV9wYXJzZXIuZXJyb3JzRm91bmQoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYSBzZXQgb2Ygc3R5bGVzaGVldHMgcG9pbnRlZCB0byBieSBhIFZlY3RvciBvZiBVUkxzCi0gICAgICogQHBhcmFtIHN0eWxlc2hlZXRzIEEgVmVjdG9yIGNvbnRhaW5pbmcgVVJMcyBwb2ludGluZyB0byB0aGUgc3R5bGVzaGVldHMKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiB0aGUgY29tcGlsYXRpb24gd2FzIHN1Y2Nlc3NmdWwKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBjb21waWxlKFZlY3RvciBzdHlsZXNoZWV0cykgewotCS8vIEdldCB0aGUgbnVtYmVyIG9mIHN0eWxlc2hlZXRzIChpZS4gVVJMcykgaW4gdGhlIHZlY3RvcgotCWZpbmFsIGludCBjb3VudCA9IHN0eWxlc2hlZXRzLnNpemUoKTsKLQkKLQkvLyBSZXR1cm4gc3RyYWlnaHQgYXdheSBpZiB0aGUgdmVjdG9yIGlzIGVtcHR5Ci0JaWYgKGNvdW50ID09IDApIHJldHVybiB0cnVlOwotCi0JLy8gU3BlY2lhbCBoYW5kbGluZyBuZWVkZWQgaWYgdGhlIFVSTCBjb3VudCBpcyBvbmUsIGJlY3Vhc2UgdGhlCi0JLy8gX2NsYXNzTmFtZSBnbG9iYWwgbXVzdCBub3QgYmUgcmVzZXQgaWYgaXQgd2FzIHNldCBleHBsaWNpdGx5Ci0JaWYgKGNvdW50ID09IDEpIHsKLQkgICAgZmluYWwgT2JqZWN0IHVybCA9IHN0eWxlc2hlZXRzLmZpcnN0RWxlbWVudCgpOwotCSAgICBpZiAodXJsIGluc3RhbmNlb2YgVVJMKQotCQlyZXR1cm4gY29tcGlsZSgoVVJMKXVybCk7Ci0JICAgIGVsc2UKLQkJcmV0dXJuIGZhbHNlOwotCX0KLQllbHNlIHsKLQkgICAgLy8gVHJhdmVyc2UgYWxsIGVsZW1lbnRzIGluIHRoZSB2ZWN0b3IgYW5kIGNvbXBpbGUKLQkgICAgZmluYWwgRW51bWVyYXRpb24gdXJscyA9IHN0eWxlc2hlZXRzLmVsZW1lbnRzKCk7Ci0JICAgIHdoaWxlICh1cmxzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCV9jbGFzc05hbWUgPSBudWxsOyAvLyByZXNldCwgc28gdGhhdCBuZXcgbmFtZSB3aWxsIGJlIGNvbXB1dGVkIAotCQlmaW5hbCBPYmplY3QgdXJsID0gdXJscy5uZXh0RWxlbWVudCgpOwotCQlpZiAodXJsIGluc3RhbmNlb2YgVVJMKSB7Ci0JCSAgICBpZiAoIWNvbXBpbGUoKFVSTCl1cmwpKSByZXR1cm4gZmFsc2U7Ci0JCX0KLQkgICAgfQotCX0KLQlyZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGJ5dGVjb2RlIGFycmF5cyBnZW5lcmF0ZWQgYnkgYSBjb21waWxhdGlvbi4KLSAgICAgKiBAcmV0dXJuIEpWTSBieXRlY29kZXMgdGhhdCByZXByZXNlbnQgdHJhbnNsZXQgY2xhc3MgZGVmaW5pdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBieXRlW11bXSBnZXRCeXRlY29kZXMoKSB7Ci0JZmluYWwgaW50IGNvdW50ID0gX2NsYXNzZXMuc2l6ZSgpOwotCWZpbmFsIGJ5dGVbXVtdIHJlc3VsdCA9IG5ldyBieXRlW2NvdW50XVsxXTsKLQlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspCi0JICAgIHJlc3VsdFtpXSA9IChieXRlW10pX2NsYXNzZXMuZWxlbWVudEF0KGkpOwotCXJldHVybiByZXN1bHQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgYSBzdHlsZXNoZWV0IHBvaW50ZWQgdG8gYnkgYSBVUkwuIFRoZSByZXN1bHQgaXMgcHV0IGluIGEKLSAgICAgKiBzZXQgb2YgYnl0ZSBhcnJheXMuIE9uZSBieXRlIGFycmF5IGZvciBlYWNoIGdlbmVyYXRlZCBjbGFzcy4KLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MgdG8gZ2VuZXJhdGUKLSAgICAgKiBAcGFyYW0gaW5wdXQgQW4gSW5wdXRTb3VyY2UgdGhhdCB3aWxsIHBhc3MgaW4gdGhlIHN0eWxlc2hlZXQgY29udGVudHMKLSAgICAgKiBAcmV0dXJuIEpWTSBieXRlY29kZXMgdGhhdCByZXByZXNlbnQgdHJhbnNsZXQgY2xhc3MgZGVmaW5pdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBieXRlW11bXSBjb21waWxlKFN0cmluZyBuYW1lLCBJbnB1dFNvdXJjZSBpbnB1dCkgewotCV9vdXRwdXRUeXBlID0gQllURUFSUkFZX09VVFBVVDsKLQlpZiAoY29tcGlsZShpbnB1dCwgbmFtZSkpCi0JICAgIHJldHVybiBnZXRCeXRlY29kZXMoKTsKLQllbHNlCi0JICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgWE1MUmVhZGVyIHRvIHVzZSBmb3IgcGFyc2luZyB0aGUgbmV4dCBpbnB1dCBzdHlsZXNoZWV0Ci0gICAgICogQHBhcmFtIHJlYWRlciBYTUxSZWFkZXIgKFNBWDIgcGFyc2VyKSB0byB1c2UKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRYTUxSZWFkZXIoWE1MUmVhZGVyIHJlYWRlcikgewotCV9yZWFkZXIgPSByZWFkZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGEgVmVjdG9yIGNvbnRhaW5pbmcgYWxsIGNvbXBpbGUgZXJyb3IgbWVzc2FnZXMKLSAgICAgKiBAcmV0dXJuIEEgVmVjdG9yIGNvbnRhaW5pbmcgYWxsIGNvbXBpbGUgZXJyb3IgbWVzc2FnZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgVmVjdG9yIGdldEVycm9ycygpIHsKLQlyZXR1cm4gX3BhcnNlci5nZXRFcnJvcnMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgYSBWZWN0b3IgY29udGFpbmluZyBhbGwgY29tcGlsZSB3YXJuaW5nIG1lc3NhZ2VzCi0gICAgICogQHJldHVybiBBIFZlY3RvciBjb250YWluaW5nIGFsbCBjb21waWxlIGVycm9yIG1lc3NhZ2VzCi0gICAgICovCi0gICAgcHVibGljIFZlY3RvciBnZXRXYXJuaW5ncygpIHsKLQlyZXR1cm4gX3BhcnNlci5nZXRXYXJuaW5ncygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50IGFsbCBjb21waWxlIGVycm9yIG1lc3NhZ2VzIHRvIHN0YW5kYXJkIG91dHB1dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50RXJyb3JzKCkgewotCV9wYXJzZXIucHJpbnRFcnJvcnMoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCBhbGwgY29tcGlsZSB3YXJuaW5nIG1lc3NhZ2VzIHRvIHN0YW5kYXJkIG91dHB1dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50V2FybmluZ3MoKSB7Ci0JX3BhcnNlci5wcmludFdhcm5pbmdzKCk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIFhQYXRoUGFyc2VyIHdoZW4gaXQgZW5jb3VudGVycyBhIGNhbGwKLSAgICAgKiB0byB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbi4gQWZmZWN0cyB0aGUgRE9NIHVzZWQgYnkgdGhlIHRyYW5zbGV0LgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldE11bHRpRG9jdW1lbnQoYm9vbGVhbiBmbGFnKSB7Ci0JX211bHRpRG9jdW1lbnQgPSBmbGFnOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzTXVsdGlEb2N1bWVudCgpIHsKLQlyZXR1cm4gX211bHRpRG9jdW1lbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBjbGFzcyBuYW1lIGZvciB0aGUgZ2VuZXJhdGVkIHRyYW5zbGV0LiBUaGlzIGNsYXNzIG5hbWUgaXMKLSAgICAgKiBvdmVycmlkZGVuIGlmIG11bHRpcGxlIHN0eWxlc2hlZXRzIGFyZSBjb21waWxlZCBpbiBvbmUgZ28gdXNpbmcgdGhlCi0gICAgICogY29tcGlsZShWZWN0b3IgdXJscykgbWV0aG9kLgotICAgICAqIEBwYXJhbSBjbGFzc05hbWUgVGhlIG5hbWUgdG8gYXNzaWduIHRvIHRoZSB0cmFuc2xldCBjbGFzcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENsYXNzTmFtZShTdHJpbmcgY2xhc3NOYW1lKSB7Ci0JZmluYWwgU3RyaW5nIGJhc2UgID0gVXRpbC5iYXNlTmFtZShjbGFzc05hbWUpOwotCWZpbmFsIFN0cmluZyBub2V4dCA9IFV0aWwubm9FeHROYW1lKGJhc2UpOyAKLQlmaW5hbCBTdHJpbmcgbmFtZSAgPSBVdGlsLnRvSmF2YU5hbWUobm9leHQpOwotCWlmIChfcGFja2FnZU5hbWUgPT0gbnVsbCkKLQkgICAgX2NsYXNzTmFtZSA9IG5hbWU7Ci0JZWxzZQotCSAgICBfY2xhc3NOYW1lID0gX3BhY2thZ2VOYW1lICsgJy4nICsgbmFtZTsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjbGFzcyBuYW1lIGZvciB0aGUgZ2VuZXJhdGVkIHRyYW5zbGV0LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgewotCXJldHVybiBfY2xhc3NOYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnZlcnQgZm9yIEphdmEgY2xhc3MgbmFtZSBvZiBsb2NhbCBzeXN0ZW0gZmlsZSBuYW1lLgotICAgICAqIChSZXBsYWNlICcuJyB3aXRoICcvJyBvbiBVTklYIGFuZCByZXBsYWNlICcuJyBieSAnXCcgb24gV2luZG93cy9ET1MuKQotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGNsYXNzRmlsZU5hbWUoZmluYWwgU3RyaW5nIGNsYXNzTmFtZSkgewotCXJldHVybiBjbGFzc05hbWUucmVwbGFjZSgnLicsIEZpbGUuc2VwYXJhdG9yQ2hhcikgKyAiLmNsYXNzIjsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogR2VuZXJhdGUgYW4gb3V0cHV0IEZpbGUgb2JqZWN0IHRvIHNlbmQgdGhlIHRyYW5zbGV0IHRvCi0gICAgICovCi0gICAgcHJpdmF0ZSBGaWxlIGdldE91dHB1dEZpbGUoU3RyaW5nIGNsYXNzTmFtZSkgewotCWlmIChfZGVzdERpciAhPSBudWxsKQotCSAgICByZXR1cm4gbmV3IEZpbGUoX2Rlc3REaXIsIGNsYXNzRmlsZU5hbWUoY2xhc3NOYW1lKSk7Ci0JZWxzZQotCSAgICByZXR1cm4gbmV3IEZpbGUoY2xhc3NGaWxlTmFtZShjbGFzc05hbWUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBmb3IgdGhlIHRyYW5zbGV0LgotICAgICAqIFRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IHdpbGwgYmUgdXNlZCBieSBkZWZhdWx0LgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIHNldERlc3REaXJlY3RvcnkoU3RyaW5nIGRzdERpck5hbWUpIHsKLQlmaW5hbCBGaWxlIGRpciA9IG5ldyBGaWxlKGRzdERpck5hbWUpOwotCWlmIChkaXIuZXhpc3RzKCkgfHwgZGlyLm1rZGlycygpKSB7Ci0JICAgIF9kZXN0RGlyID0gZGlyOwotCSAgICByZXR1cm4gdHJ1ZTsKLQl9Ci0JZWxzZSB7Ci0JICAgIF9kZXN0RGlyID0gbnVsbDsKLQkgICAgcmV0dXJuIGZhbHNlOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgYW4gb3B0aW9uYWwgcGFja2FnZSBuYW1lIGZvciB0aGUgdHJhbnNsZXQgYW5kIGF1eGlsaWFyeSBjbGFzc2VzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFja2FnZU5hbWUoU3RyaW5nIHBhY2thZ2VOYW1lKSB7Ci0JX3BhY2thZ2VOYW1lID0gcGFja2FnZU5hbWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBuYW1lIG9mIGFuIG9wdGlvbmFsIEpBUi1maWxlIHRvIGR1bXAgdGhlIHRyYW5zbGV0IGFuZAotICAgICAqIGF1eGlsaWFyeSBjbGFzc2VzIHRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SmFyRmlsZU5hbWUoU3RyaW5nIGphckZpbGVOYW1lKSB7Ci0JZmluYWwgU3RyaW5nIEpBUl9FWFQgPSAiLmphciI7Ci0JaWYgKGphckZpbGVOYW1lLmVuZHNXaXRoKEpBUl9FWFQpKQotCSAgICBfamFyRmlsZU5hbWUgPSBqYXJGaWxlTmFtZTsKLQllbHNlCi0JICAgIF9qYXJGaWxlTmFtZSA9IGphckZpbGVOYW1lICsgSkFSX0VYVDsKLQlfb3V0cHV0VHlwZSA9IEpBUl9PVVRQVVQ7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRKYXJGaWxlTmFtZSgpIHsKLQlyZXR1cm4gX2phckZpbGVOYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFN0eWxlc2hlZXQgZ2V0U3R5bGVzaGVldCgpIHsKLQlyZXR1cm4gX3N0eWxlc2hlZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdHlsZXNoZWV0KFN0eWxlc2hlZXQgc3R5bGVzaGVldCkgewotCWlmIChfc3R5bGVzaGVldCA9PSBudWxsKQotCSAgICBfc3R5bGVzaGVldCA9IHN0eWxlc2hlZXQ7Ci0gICAgfQotICAgCi0gICAgLyoqCi0gICAgICogUmVnaXN0ZXJzIGFuIGF0dHJpYnV0ZSBhbmQgZ2l2ZXMgaXQgYSB0eXBlIHNvIHRoYXQgaXQgY2FuIGJlIG1hcHBlZCB0bwotICAgICAqIERPTSBhdHRyaWJ1dGUgdHlwZXMgYXQgcnVuLXRpbWUuCi0gICAgICovCi0gICAgcHVibGljIGludCByZWdpc3RlckF0dHJpYnV0ZShRTmFtZSBuYW1lKSB7Ci0JSW50ZWdlciBjb2RlID0gKEludGVnZXIpX2F0dHJpYnV0ZXMuZ2V0KG5hbWUpOwotCWlmIChjb2RlID09IG51bGwpIHsKLQkgICAgX2F0dHJpYnV0ZXMucHV0KG5hbWUsIGNvZGUgPSBuZXcgSW50ZWdlcihfbmV4dEdUeXBlKyspKTsKLQkgICAgZmluYWwgU3RyaW5nIHVyaSA9IG5hbWUuZ2V0TmFtZXNwYWNlKCk7Ci0JICAgIGZpbmFsIFN0cmluZyBsb2NhbCA9ICJAIituYW1lLmdldExvY2FsUGFydCgpOwotCSAgICBpZiAoKHVyaSAhPSBudWxsKSAmJiAoIXVyaS5lcXVhbHMoIiIpKSkKLQkJX25hbWVzSW5kZXguYWRkRWxlbWVudCh1cmkrIjoiK2xvY2FsKTsKLQkgICAgZWxzZQotCQlfbmFtZXNJbmRleC5hZGRFbGVtZW50KGxvY2FsKTsKLQkgICAgaWYgKG5hbWUuZ2V0TG9jYWxQYXJ0KCkuZXF1YWxzKCIqIikpIHsKLQkJcmVnaXN0ZXJOYW1lc3BhY2UobmFtZS5nZXROYW1lc3BhY2UoKSk7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIGNvZGUuaW50VmFsdWUoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWdpc3RlcnMgYW4gZWxlbWVudCBhbmQgZ2l2ZXMgaXQgYSB0eXBlIHNvIHRoYXQgaXQgY2FuIGJlIG1hcHBlZCB0bwotICAgICAqIERPTSBlbGVtZW50IHR5cGVzIGF0IHJ1bi10aW1lLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgcmVnaXN0ZXJFbGVtZW50KFFOYW1lIG5hbWUpIHsKLQkvLyBSZWdpc3RlciBlbGVtZW50IChmdWxsIFFOYW1lKQotCUludGVnZXIgY29kZSA9IChJbnRlZ2VyKV9lbGVtZW50cy5nZXQobmFtZS50b1N0cmluZygpKTsKLQlpZiAoY29kZSA9PSBudWxsKSB7Ci0JICAgIF9lbGVtZW50cy5wdXQobmFtZS50b1N0cmluZygpLCBjb2RlID0gbmV3IEludGVnZXIoX25leHRHVHlwZSsrKSk7Ci0JICAgIF9uYW1lc0luZGV4LmFkZEVsZW1lbnQobmFtZS50b1N0cmluZygpKTsKLQl9Ci0JaWYgKG5hbWUuZ2V0TG9jYWxQYXJ0KCkuZXF1YWxzKCIqIikpIHsKLQkgICAgcmVnaXN0ZXJOYW1lc3BhY2UobmFtZS5nZXROYW1lc3BhY2UoKSk7Ci0JfQotCXJldHVybiBjb2RlLmludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVnaXN0ZXJzIGEgbmFtZXNwYWNlIGFuZCBnaXZlcyBpdCBhIHR5cGUgc28gdGhhdCBpdCBjYW4gYmUgbWFwcGVkIHRvCi0gICAgICogRE9NIG5hbWVzcGFjZSB0eXBlcyBhdCBydW4tdGltZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHJlZ2lzdGVyTmFtZXNwYWNlKFN0cmluZyBuYW1lc3BhY2VVUkkpIHsKLQlJbnRlZ2VyIGNvZGUgPSAoSW50ZWdlcilfbmFtZXNwYWNlcy5nZXQobmFtZXNwYWNlVVJJKTsKLQlpZiAoY29kZSA9PSBudWxsKSB7Ci0JICAgIGNvZGUgPSBuZXcgSW50ZWdlcihfbmV4dE5TVHlwZSsrKTsKLQkgICAgX25hbWVzcGFjZXMucHV0KG5hbWVzcGFjZVVSSSxjb2RlKTsKLQkgICAgX25hbWVzcGFjZUluZGV4LmFkZEVsZW1lbnQobmFtZXNwYWNlVVJJKTsKLQl9Ci0JcmV0dXJuIGNvZGUuaW50VmFsdWUoKTsKLSAgICB9Ci0gICAgCi0gICAgLyoKLSAgICBwdWJsaWMgaW50IG5leHRWYXJpYWJsZVNlcmlhbCgpIHsKLQlyZXR1cm4gX3ZhcmlhYmxlU2VyaWFsKys7Ci0gICAgfQotICAgICovCi0KLSAgICBwdWJsaWMgaW50IG5leHRNb2RlU2VyaWFsKCkgewotCXJldHVybiBfbW9kZVNlcmlhbCsrOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dFN0eWxlc2hlZXRTZXJpYWwoKSB7Ci0JcmV0dXJuIF9zdHlsZXNoZWV0U2VyaWFsKys7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0U3RlcFBhdHRlcm5TZXJpYWwoKSB7Ci0JcmV0dXJuIF9zdGVwUGF0dGVyblNlcmlhbCsrOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnRbXSBnZXROdW1iZXJGaWVsZEluZGV4ZXMoKSB7Ci0JcmV0dXJuIF9udW1iZXJGaWVsZEluZGV4ZXM7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0SGVscGVyQ2xhc3NTZXJpYWwoKSB7Ci0JcmV0dXJuIF9oZWxwZXJDbGFzc1NlcmlhbCsrOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgaW50IG5leHRBdHRyaWJ1dGVTZXRTZXJpYWwoKSB7Ci0JcmV0dXJuIF9hdHRyaWJ1dGVTZXRTZXJpYWwrKzsKLSAgICB9Ci0KLSAgICBwdWJsaWMgVmVjdG9yIGdldE5hbWVzSW5kZXgoKSB7Ci0JcmV0dXJuIF9uYW1lc0luZGV4OwotICAgIH0KLQotICAgIHB1YmxpYyBWZWN0b3IgZ2V0TmFtZXNwYWNlSW5kZXgoKSB7Ci0JcmV0dXJuIF9uYW1lc3BhY2VJbmRleDsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHVuaXF1ZSBuYW1lIGZvciBldmVyeSBoZWxwZXIgY2xhc3MgbmVlZGVkIHRvCi0gICAgICogZXhlY3V0ZSBhIHRyYW5zbGV0LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVscGVyQ2xhc3NOYW1lKCkgewotCXJldHVybiBnZXRDbGFzc05hbWUoKSArICckJyArIF9oZWxwZXJDbGFzc1NlcmlhbCsrOwotICAgIH0KLSAgIAotICAgIHB1YmxpYyB2b2lkIGR1bXBDbGFzcyhKYXZhQ2xhc3MgY2xhenopIHsKLQl0cnkgewotCSAgICBzd2l0Y2ggKF9vdXRwdXRUeXBlKSB7Ci0JICAgIGNhc2UgRklMRV9PVVRQVVQ6Ci0JCWNsYXp6LmR1bXAoZ2V0T3V0cHV0RmlsZShjbGF6ei5nZXRDbGFzc05hbWUoKSkpOwotCQlicmVhazsKLQkgICAgY2FzZSBKQVJfT1VUUFVUOgotCQlfY2xhc3Nlcy5hZGRFbGVtZW50KGNsYXp6KTsJIAotCQlicmVhazsKLQkgICAgY2FzZSBCWVRFQVJSQVlfT1VUUFVUOgotCSAgICBjYXNlIENMQVNTTE9BREVSX09VVFBVVDoKLQkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMjA0OCk7Ci0JCWNsYXp6LmR1bXAob3V0KTsKLQkJX2NsYXNzZXMuYWRkRWxlbWVudChvdXQudG9CeXRlQXJyYXkoKSk7Ci0JCWJyZWFrOwotCSAgICB9Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBGaWxlIHNlcGFyYXRvcnMgYXJlIGNvbnZlcnRlZCB0byBmb3J3YXJkIHNsYXNoZXMgZm9yIFpJUCBmaWxlcy4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBlbnRyeU5hbWUoRmlsZSBmKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCXJldHVybiBmLmdldE5hbWUoKS5yZXBsYWNlKEZpbGUuc2VwYXJhdG9yQ2hhciwgJy8nKTsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogR2VuZXJhdGUgb3V0cHV0IEpBUi1maWxlIGFuZCBwYWNrYWdlcwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG91dHB1dFRvSmFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkvLyBjcmVhdGUgdGhlIG1hbmlmZXN0Ci0JZmluYWwgTWFuaWZlc3QgbWFuaWZlc3QgPSBuZXcgTWFuaWZlc3QoKTsKLQlmaW5hbCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMgYXRycyA9IG1hbmlmZXN0LmdldE1haW5BdHRyaWJ1dGVzKCk7Ci0JYXRycy5wdXQoamF2YS51dGlsLmphci5BdHRyaWJ1dGVzLk5hbWUuTUFOSUZFU1RfVkVSU0lPTiwiMS4wIik7Ci0KLQlmaW5hbCBNYXAgbWFwID0gbWFuaWZlc3QuZ2V0RW50cmllcygpOwotCS8vIGNyZWF0ZSBtYW5pZmVzdAotCUVudW1lcmF0aW9uIGNsYXNzZXMgPSBfY2xhc3Nlcy5lbGVtZW50cygpOwotCWZpbmFsIFN0cmluZyBub3cgPSAobmV3IERhdGUoKSkudG9TdHJpbmcoKTsKLQlmaW5hbCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMuTmFtZSBkYXRlQXR0ciA9IAotCSAgICBuZXcgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzLk5hbWUoIkRhdGUiKTsKLQl3aGlsZSAoY2xhc3Nlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICBmaW5hbCBKYXZhQ2xhc3MgY2xhenogPSAoSmF2YUNsYXNzKWNsYXNzZXMubmV4dEVsZW1lbnQoKTsKLQkgICAgZmluYWwgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzIGF0dHIgPSBuZXcgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzKCk7Ci0JICAgIGF0dHIucHV0KGRhdGVBdHRyLCBub3cpOwotCSAgICBtYXAucHV0KGNsYXNzRmlsZU5hbWUoY2xhenouZ2V0Q2xhc3NOYW1lKCkpLCBhdHRyKTsKLQl9Ci0KLQlmaW5hbCBGaWxlIGphckZpbGUgPSBuZXcgRmlsZShfZGVzdERpciwgX2phckZpbGVOYW1lKTsKLQlmaW5hbCBKYXJPdXRwdXRTdHJlYW0gam9zID0KLQkgICAgbmV3IEphck91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShqYXJGaWxlKSwgbWFuaWZlc3QpOwotCWNsYXNzZXMgPSBfY2xhc3Nlcy5lbGVtZW50cygpOwotCXdoaWxlIChjbGFzc2VzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JICAgIGZpbmFsIEphdmFDbGFzcyBjbCA9IChKYXZhQ2xhc3MpY2xhc3Nlcy5uZXh0RWxlbWVudCgpOwotCSAgICBqb3MucHV0TmV4dEVudHJ5KG5ldyBKYXJFbnRyeShjbGFzc0ZpbGVOYW1lKGNsLmdldENsYXNzTmFtZSgpKSkpOwotCSAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgyMDQ4KTsKLQkgICAgY2wuZHVtcChvdXQpOwkvLyBkdW1wKCkgY2xvc2VzIGl0J3Mgb3V0cHV0IHN0cmVhbQotCSAgICBvdXQud3JpdGVUbyhqb3MpOwotCX0KLQlqb3MuY2xvc2UoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUdXJuIGRlYnVnZ2luZyBtZXNzYWdlcyBvbi9vZmYKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREZWJ1Zyhib29sZWFuIGRlYnVnKSB7Ci0JX2RlYnVnID0gZGVidWc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IGN1cnJlbnQgZGVidWdnaW5nIG1lc3NhZ2Ugc2V0dGluZwotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGRlYnVnKCkgewotCXJldHVybiBfZGVidWc7Ci0gICAgfQotICAgICAgICAKLSAgICAvKiogCi0gICAgICogVGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgY29tbWFuZCBsaW5lIGNvbXBpbGVyLiBTZWUgdGhlIFVTQUdFX1NUUklORwotICAgICAqIGNvbnN0YW50IGZvciBhIGRlc2NyaXB0aW9uLiBJdCBtYXkgbWFrZSBzZW5zZSB0byBtb3ZlIHRoZSBjb21tYW5kLWxpbmUKLSAgICAgKiBoYW5kbGluZyB0byBhIHNlcGFyYXRlIHBhY2thZ2UgKGllLiBtYWtlIG9uZSB4c2x0Yy5jbWRsaW5lLkNvbXBpbGVyCi0gICAgICogY2xhc3MgdGhhdCBjb250YWlucyB0aGlzIG1haW4oKSBtZXRob2QgYW5kIG9uZSB4c2x0Yy5jbWRsaW5lLlRyYW5zZm9ybQotICAgICAqIGNsYXNzIHRoYXQgY29udGFpbnMgdGhlIERlZmF1bHRSdW4gc3R1ZmYpLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKLQl0cnkgewotCSAgICBib29sZWFuIGlucHV0SXNVUkwgPSBmYWxzZTsKLQotCSAgICBmaW5hbCBHZXRPcHQgZ2V0b3B0ID0gbmV3IEdldE9wdChhcmdzLCAibzpkOmo6cDp1eGhzIik7Ci0JICAgIGlmIChhcmdzLmxlbmd0aCA8IDEpIHsKLQkJcHJpbnRVc2FnZSgpOwotCQlyZXR1cm47Ci0JICAgIH0KLQotCSAgICBmaW5hbCBYU0xUQyB4c2x0YyA9IG5ldyBYU0xUQygpOwotCSAgICB4c2x0Yy5pbml0KCk7Ci0KLQkgICAgaW50IGM7Ci0JICAgIHdoaWxlICgoYyA9IGdldG9wdC5nZXROZXh0T3B0aW9uKCkpICE9IC0xKSB7Ci0JCXN3aXRjaChjKSB7Ci0JCWNhc2UgJ28nOgotCQkgICAgeHNsdGMuc2V0Q2xhc3NOYW1lKGdldG9wdC5nZXRPcHRpb25BcmcoKSk7Ci0JCSAgICBicmVhazsKLQkJY2FzZSAnZCc6Ci0JCSAgICB4c2x0Yy5zZXREZXN0RGlyZWN0b3J5KGdldG9wdC5nZXRPcHRpb25BcmcoKSk7Ci0JCSAgICBicmVhazsKLQkJY2FzZSAncCc6Ci0JCSAgICB4c2x0Yy5zZXRQYWNrYWdlTmFtZShnZXRvcHQuZ2V0T3B0aW9uQXJnKCkpOwotCQkgICAgYnJlYWs7Ci0JCWNhc2UgJ2onOiAgCi0JCSAgICB4c2x0Yy5zZXRKYXJGaWxlTmFtZShnZXRvcHQuZ2V0T3B0aW9uQXJnKCkpOwotCQkgICAgYnJlYWs7Ci0JCWNhc2UgJ3gnOgotCQkgICAgeHNsdGMuc2V0RGVidWcodHJ1ZSk7Ci0JCSAgICBicmVhazsKLQkJY2FzZSAndSc6Ci0JCSAgICBpbnB1dElzVVJMID0gdHJ1ZTsKLQkJICAgIGJyZWFrOwotCQljYXNlICdzJzoKLQkJICAgIGFsbG93U3lzdGVtRXhpdCA9IGZhbHNlOwotCQkgICAgYnJlYWs7Ci0JCWNhc2UgJ2gnOgotCQlkZWZhdWx0OgotCQkgICAgcHJpbnRVc2FnZSgpOwotCQkgICAgYnJlYWs7IAotCQl9Ci0JICAgIH0KLQotCSAgICAvLyBHZW5lcmF0ZSBhIHZlY3RvciBjb250YWluZyBVUkxzIGZvciBhbGwgc3R5bGVzaGVldHMgc3BlY2lmaWVkCi0JICAgIGZpbmFsIFN0cmluZ1tdIHN0eWxlc2hlZXROYW1lcyA9IGdldG9wdC5nZXRDbWRBcmdzKCk7Ci0JICAgIGZpbmFsIFZlY3RvciAgIHN0eWxlc2hlZXRWZWN0b3IgPSBuZXcgVmVjdG9yKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3R5bGVzaGVldE5hbWVzLmxlbmd0aDsgaSsrKSB7Ci0JCWZpbmFsIFN0cmluZyBzdHlsZXNoZWV0TmFtZSA9IHN0eWxlc2hlZXROYW1lc1tpXTsKLQkJZmluYWwgVVJMICAgIHN0eWxlc2hlZXRVUkw7Ci0JCWlmIChpbnB1dElzVVJMKSB7Ci0JCSAgICBzdHlsZXNoZWV0VmVjdG9yLmFkZEVsZW1lbnQobmV3IFVSTChzdHlsZXNoZWV0TmFtZSkpOwotCQl9Ci0JCWVsc2UgewotCQkgICAgc3R5bGVzaGVldFZlY3Rvci5hZGRFbGVtZW50KChuZXcgRmlsZShzdHlsZXNoZWV0TmFtZSkpLnRvVVJMKCkpOwotCQl9Ci0KLQkgICAgfQotCi0JICAgIC8vIENvbXBpbGUgdGhlIHN0eWxlc2hlZXQgYW5kIG91dHB1dCBjbGFzcy9qYXIgZmlsZShzKQotCSAgICBpZiAoeHNsdGMuY29tcGlsZShzdHlsZXNoZWV0VmVjdG9yKSkgewotCQlpZiAoeHNsdGMuZ2V0SmFyRmlsZU5hbWUoKSAhPSBudWxsKSB4c2x0Yy5vdXRwdXRUb0phcigpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlVdGlsLnByaW50bG4oImNvbXBpbGF0aW9uIGZhaWxlZCIpOwotCQlkb1N5c3RlbUV4aXQoMSk7IHJldHVybjsKLQkgICAgfQotCX0KLQljYXRjaCAoR2V0T3B0c0V4Y2VwdGlvbiBleCkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oZXgpOwotCSAgICBwcmludFVzYWdlKCk7Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBkb1N5c3RlbUV4aXQoMSk7Ci0JfQotICAgIH0KLQotICAgIC8qKiBJZiB3ZSBzaG91bGQgY2FsbCBTeXN0ZW0uZXhpdCBvciBub3QgKi8KLSAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gYWxsb3dTeXN0ZW1FeGl0ID0gdHJ1ZTsKLQotICAgIC8qKiBXb3JrZXIgbWV0aG9kIHRvIGNhbGwgU3lzdGVtLmV4aXQgb3Igbm90ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGRvU3lzdGVtRXhpdChpbnQgcmV0VmFsKSB7Ci0gICAgICAgIGlmIChhbGxvd1N5c3RlbUV4aXQpCi0gICAgICAgICAgICBTeXN0ZW0uZXhpdChyZXRWYWwpOwotICAgIH0KLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBVU0FHRV9TVFJJTkcgPQotCSJVc2FnZTpcbiIgKyAKLQkiICAgeHNsdGMgWy1vIDxvdXRwdXQ+XSBbLWQgPGRpcmVjdG9yeT5dIFstaiA8amFyZmlsZT5dXG4iKwotCSIgICAgICAgICBbLXAgPHBhY2thZ2UgbmFtZT5dIFsteF0gWy1zXSBbLXVdIDxzdHlsZXNoZWV0Pi4uLiBcblxuIisKLQkiICAgV2hlcmUgPG91dHB1dD4gaXMgdGhlIG5hbWUgdG8gZ2l2ZSB0aGUgdGhlIGdlbmVyYXRlZCB0cmFuc2xldC5cbiIrCi0JIiAgICAgICAgIDxzdHlsZXNoZWV0PiBpcyBvbmUgb3IgbW9yZSBzdHlsZXNoZWV0IGZpbGUgbmFtZXMsIG9yIGlmLFxuIisKLQkiICAgICAgICAgdGhlIC11IG9wdGlvbnMgaXMgc3BlY2lmaWVkLCBvbmUgb3IgbW9yZSBzdHlsZXNoZWV0IFVSTHMuXG4iKwotCSIgICAgICAgICA8ZGlyZWN0b3J5PiBpcyB0aGUgb3V0cHV0IGRpcmVjdG9yeS5cbiIrCi0JIiAgICAgICAgIDxqYXJmaWxlPiBpcyB0aGUgbmFtZSBvZiBhIEpBUi1maWxlIHRvIHB1dCBhbGwgZ2VuZXJhdGVkIGNsYXNzZXMgaW4uXG4iKwotCSIgICAgICAgICA8cGFja2FnZS1uYW1lPiBpcyBhIHBhY2thZ2UgbmFtZSB0byBwcmVmaXggYWxsIGNsYXNzIG5hbWVzIHdpdGguXG5cbiIrCi0JIiAgIE5vdGVzOlxuIisKLQkiICAgICAgICAgVGhlIC1vIG9wdGlvbiBpcyBpZ25vcmVkIHdoZW4gbXVsdGlwbGUgc3R5bGVzaGVldHMgYXJlIHNwZWNpZmllZC5cbiIrCi0JIiAgICAgICAgIFRoZSAteCBvcHRpb24gc3dpdGNoZWQgb24gZGVidWcgbWVzc2FnZXMuXG4iKwotCSIgICAgICAgICBUaGUgLXMgb3B0aW9uIHByZXZlbnRzIHRoZSBjb21waWxlciBmcm9tIGV4aXRpbmdcbiI7Ci0gICAgCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50VXNhZ2UoKSB7Ci0JU3lzdGVtLmVyci5wcmludGxuKFVTQUdFX1NUUklORyk7Ci0JZG9TeXN0ZW1FeGl0KDEpOwotCXJldHVybjsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9Yc2xBdHRyaWJ1dGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1hzbEF0dHJpYnV0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NzlmYjM4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1hzbEF0dHJpYnV0ZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjYxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICogQGF1dGhvciBHdW5ubGF1Z3VyIEJyaWVtIDxndGhiQGRpbW9uLmlzPgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1maW5hbCBjbGFzcyBYc2xBdHRyaWJ1dGUgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICAvLyBFcnJvciBtZXNzYWdlczoKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgSUxMRUdBTF9BVFRSSUJVVEVfTkFNRSA9Ci0JIklsbGVnYWwgYXR0cmlidXRlIG5hbWU6ICd4bWxucyciOwotCi0gICAgLy8gQXR0cmlidXRlIGNvbnRlbnRzCi0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZSBfbmFtZTsgLy8gbmFtZSB0cmVhdGVkIGFzIEFWVCAoNy4xLjMpCi0gICAgcHJpdmF0ZSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlIF9uYW1lc3BhY2UgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9wcmVmaXg7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pZ25vcmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyBBdHRyaWJ1dGVWYWx1ZSBnZXROYW1lKCkgewotCXJldHVybiBfbmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEaXNwbGF5cyB0aGUgY29udGVudHMgb2YgdGhlIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVV0aWwucHJpbnRsbigiQXR0cmlidXRlICIgKyBfbmFtZSk7Ci0JZGlzcGxheUNvbnRlbnRzKGluZGVudCArIEluZGVudEluY3JlbWVudCk7Ci0gICAgfQotCQkKLSAgICAvKioKLSAgICAgKiBQYXJzZXMgdGhlIGF0dHJpYnV0ZSdzIGNvbnRlbnRzLiBTcGVjaWFsIGNhcmUgdGFrZW4gZm9yIG5hbWVzcGFjZXMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcGFyc2VDb250ZW50cyhQYXJzZXIgcGFyc2VyKSB7Ci0KLQlmaW5hbCBTeW1ib2xUYWJsZSBzdGFibGUgPSBwYXJzZXIuZ2V0U3ltYm9sVGFibGUoKTsKLQlTdHJpbmcgbmFtZXNwYWNlID0gZ2V0QXR0cmlidXRlKCJuYW1lc3BhY2UiKTsKLQlTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotCVFOYW1lIHFuYW1lID0gcGFyc2VyLmdldFFOYW1lKG5hbWUpOwotCWZpbmFsIFN0cmluZyBwcmVmaXggPSBxbmFtZS5nZXRQcmVmaXgoKTsKLQlib29sZWFuIGdlbmVyYXRlZCA9IGZhbHNlOwotCi0JaWYgKChwcmVmaXggIT0gbnVsbCkgJiYgKHByZWZpeC5lcXVhbHMoInhtbG5zIikpKSB7Ci0JICAgIHJlcG9ydEVycm9yKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuSUxMX0FUVFJfRVJSLCBuYW1lKTsKLQkgICAgcmV0dXJuOwotCX0KLQotCS8vIElnbm9yZSBhdHRyaWJ1dGUgaWYgcHJlY2VlZGVkIGJ5IHNvbWUgb3RoZXIgdHlwZSBvZiBlbGVtZW50Ci0JZmluYWwgU3ludGF4VHJlZU5vZGUgcGFyZW50ID0gZ2V0UGFyZW50KCk7Ci0JZmluYWwgVmVjdG9yIHNpYmxpbmdzID0gcGFyZW50LmdldENvbnRlbnRzKCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJlbnQuZWxlbWVudENvdW50KCk7IGkrKykgewotCSAgICBTeW50YXhUcmVlTm9kZSBpdGVtID0gKFN5bnRheFRyZWVOb2RlKXNpYmxpbmdzLmVsZW1lbnRBdChpKTsKLQkgICAgaWYgKGl0ZW0gPT0gdGhpcykgYnJlYWs7Ci0JICAgIC8vIFRoZXNlIHRocmVlIG9iamVjdHMgcmVzdWx0IGluIG9uZSBvciBtb3JlIGF0dHJpYnV0ZSBvdXRwdXQKLQkgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBYc2xBdHRyaWJ1dGUpIGNvbnRpbnVlOwotCSAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFVzZUF0dHJpYnV0ZVNldHMpIGNvbnRpbnVlOwotCSAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIExpdGVyYWxBdHRyaWJ1dGUpIGNvbnRpbnVlOwotCSAgICAvLyBUaGVzZSBvYmplY3RzIF9jYW5fIHJlc3VsdCBpbiBvbmUgb3IgbW9yZSBhdHRyaWJ1dGUKLQkgICAgLy8gVGhlIG91dHB1dCBoYW5kbGVyIHdpbGwgZ2VuZXJhdGUgYW4gZXJyb3IgaWYgbm90IChhdCBydW50aW1lKQotCSAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIElmKSBjb250aW51ZTsKLQkgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBDaG9vc2UpIGNvbnRpbnVlOwotCSAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIENvcHlPZikgY29udGludWU7ICAvLyBidWcgZml4IDMzMjAsIGcuIGJyaWVtCi0JICAgIF9pZ25vcmUgPSB0cnVlOwotCSAgICByZXBvcnRXYXJuaW5nKHRoaXMsIHBhcnNlciwgRXJyb3JNc2cuQVRUUk9VVFNfRVJSLCBuYW1lKTsKLQkgICAgcmV0dXJuOwotCX0KLQotCS8vIEdldCBuYW1lc3BhY2UgZnJvbSBuYW1lc3BhY2UgYXR0cmlidXRlPwotCWlmICgobmFtZXNwYWNlICE9IG51bGwpICYmIChuYW1lc3BhY2UgIT0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgewotCSAgICAvLyBQcmVmaXggY291bGQgYmUgaW4gc3ltYm9sIHRhYmxlCi0JICAgIF9wcmVmaXggPSBsb29rdXBQcmVmaXgobmFtZXNwYWNlKTsKLQkgICAgX25hbWVzcGFjZSA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKG5hbWVzcGFjZSwgcGFyc2VyKTsKLQl9Ci0JLy8gR2V0IG5hbWVzcGFjZSBmcm9tIHByZWZpeCBpbiBuYW1lIGF0dHJpYnV0ZT8KLQllbHNlIGlmICgocHJlZml4ICE9IG51bGwpICYmIChwcmVmaXggIT0gQ29uc3RhbnRzLkVNUFRZU1RSSU5HKSkgewotCSAgICBfcHJlZml4ID0gcHJlZml4OwotCSAgICBuYW1lc3BhY2UgPSBsb29rdXBOYW1lc3BhY2UocHJlZml4KTsKLQkgICAgaWYgKG5hbWVzcGFjZSAhPSBudWxsKQotCQlfbmFtZXNwYWNlID0gbmV3IEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUobmFtZXNwYWNlLCBwYXJzZXIpOwotCX0KLQkKLQkvLyBDb21tb24gaGFuZGxpbmcgZm9yIG5hbWVzcGFjZXM6Ci0JaWYgKF9uYW1lc3BhY2UgIT0gbnVsbCkgewotCi0JICAgIC8vIEdlbmVyYXRlIHByZWZpeCBpZiB3ZSBoYXZlIG5vbmUKLQkgICAgaWYgKF9wcmVmaXggPT0gbnVsbCkgewotCQlpZiAocHJlZml4ICE9IG51bGwpIHsKLQkJICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0JCX0KLQkJZWxzZSB7Ci0JCSAgICBfcHJlZml4ID0gc3RhYmxlLmdlbmVyYXRlTmFtZXNwYWNlUHJlZml4KCk7Ci0JCSAgICBnZW5lcmF0ZWQgPSB0cnVlOwotCQl9Ci0JICAgIH0KLQotCSAgICBpZiAoX3ByZWZpeCA9PSBDb25zdGFudHMuRU1QVFlTVFJJTkcpIHsKLQkJbmFtZSA9IHFuYW1lLmdldExvY2FsUGFydCgpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQluYW1lID0gX3ByZWZpeCsiOiIrcW5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0JCS8vIFBST0JMRU06Ci0JCS8vIFRoZSBuYW1lc3BhY2UgVVJJIG11c3QgYmUgcGFzc2VkIHRvIHRoZSBwYXJlbnQgZWxlbWVudCwKLQkJLy8gYnV0IHdlIGRvbid0IHlldCBrbm93IHdoYXQgdGhlIGFjdHVhbCBVUkkgaXMgKGFzIHdlIG9ubHkKLQkJLy8ga25vdyBpdCBhcyBhbiBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUpLiBOZXcgZGVzaWduIG5lZWRlZC4KLQkJaWYgKChwYXJlbnQgaW5zdGFuY2VvZiBMaXRlcmFsRWxlbWVudCkgJiYgKCFnZW5lcmF0ZWQpKSB7Ci0JCSAgICAoKExpdGVyYWxFbGVtZW50KXBhcmVudCkucmVnaXN0ZXJOYW1lc3BhY2UoX3ByZWZpeCwKLQkJCQkJCQkgICAgICAgbmFtZXNwYWNlLAotCQkJCQkJCSAgICAgICBzdGFibGUsZmFsc2UpOwotCQl9Ci0JICAgIH0KLQl9Ci0KLQlpZiAobmFtZS5lcXVhbHMoInhtbG5zIikpIHsKLQkgICAgZmluYWwgRXJyb3JNc2cgbXNnID0gCi0JCW5ldyBFcnJvck1zZyhJTExFR0FMX0FUVFJJQlVURV9OQU1FLCBnZXRMaW5lTnVtYmVyKCkpOwotCSAgICBwYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBtc2cpOwotCSAgICByZXR1cm47Ci0JfQotCi0JaWYgKHBhcmVudCBpbnN0YW5jZW9mIExpdGVyYWxFbGVtZW50KSB7Ci0JICAgICgoTGl0ZXJhbEVsZW1lbnQpcGFyZW50KS5hZGRBdHRyaWJ1dGUodGhpcyk7Ci0JfQotCi0JX25hbWUgPSBBdHRyaWJ1dGVWYWx1ZS5jcmVhdGUodGhpcywgbmFtZSwgcGFyc2VyKTsKLQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0gICAgfQotCQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHVibGljIFR5cGUgdHlwZUNoZWNrKFN5bWJvbFRhYmxlIHN0YWJsZSkgdGhyb3dzIFR5cGVDaGVja0Vycm9yIHsKLQlpZiAoX2lnbm9yZSkgcmV0dXJuKFR5cGUuVm9pZCk7Ci0JX25hbWUudHlwZUNoZWNrKHN0YWJsZSk7Ci0JaWYgKF9uYW1lc3BhY2UgIT0gbnVsbCkKLQkgICAgX25hbWVzcGFjZS50eXBlQ2hlY2soc3RhYmxlKTsKLQl0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaWYgKF9pZ25vcmUpIHJldHVybjsKLQlfaWdub3JlID0gdHJ1ZTsKLQotCS8vIENvbXBpbGUgY29kZSB0aGF0IGVtaXRzIGFueSBuZWVkZWQgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCi0JaWYgKF9uYW1lc3BhY2UgIT0gbnVsbCkgewotCSAgICAvLyBwdWJsaWMgdm9pZCBhdHRyaWJ1dGUoZmluYWwgU3RyaW5nIG5hbWUsIGZpbmFsIFN0cmluZyB2YWx1ZSkKLQkgICAgaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkSGFuZGxlcigpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZyxfcHJlZml4KSk7Ci0JICAgIF9uYW1lc3BhY2UudHJhbnNsYXRlKGNsYXNzR2VuLG1ldGhvZEdlbik7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubmFtZXNwYWNlKCkpOwotCX0KLQotCS8vIFNhdmUgdGhlIGN1cnJlbnQgaGFuZGxlciBiYXNlIG9uIHRoZSBzdGFjawotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZEhhbmRsZXIoKSk7Ci0JaWwuYXBwZW5kKERVUCk7CQkvLyBmaXJzdCBhcmcgdG8gImF0dHJpYnV0ZXMiIGNhbGwKLQkKLQkvLyBQdXNoIGF0dHJpYnV0ZSBuYW1lCi0JX25hbWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOy8vIDJuZCBhcmcKLQotCS8vIFB1c2ggYXR0cmlidXRlIHZhbHVlIC0gc2hvcnRjdXQgZm9yIGxpdGVyYWwgc3RyaW5ncwotCWlmICgoZWxlbWVudENvdW50KCkgPT0gMSkgJiYgKGVsZW1lbnRBdCgwKSBpbnN0YW5jZW9mIFRleHQpKSB7Ci0JICAgIGlsLmFwcGVuZChuZXcgUFVTSChjcGcsICgoVGV4dCllbGVtZW50QXQoMCkpLmdldFRleHQoKSkpOwotCX0KLQllbHNlIHsKLQkgICAgaWwuYXBwZW5kKGNsYXNzR2VuLmxvYWRUcmFuc2xldCgpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCQkgICAic3RyaW5nVmFsdWVIYW5kbGVyIiwKLQkJCQkJCSAgIFNUUklOR19WQUxVRV9IQU5ETEVSX1NJRykpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4uc3RvcmVIYW5kbGVyKCkpOwotCSAgICAvLyB0cmFuc2xhdGUgY29udGVudHMgd2l0aCBzdWJzdGl0dXRlZCBoYW5kbGVyCi0JICAgIHRyYW5zbGF0ZUNvbnRlbnRzKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCSAgICAvLyBnZXQgU3RyaW5nIG91dCBvZiB0aGUgaGFuZGxlcgotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihTVFJJTkdfVkFMVUVfSEFORExFUiwKLQkJCQkJCQkgImdldFZhbHVlIiwKLQkJCQkJCQkgIigpIiArIFNUUklOR19TSUcpKSk7Ci0JfQotCi0JLy8gY2FsbCAiYXR0cmlidXRlIgotCWlsLmFwcGVuZChtZXRob2RHZW4uYXR0cmlidXRlKCkpOwotCS8vIFJlc3RvcmUgb2xkIGhhbmRsZXIgYmFzZSBmcm9tIHN0YWNrCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5zdG9yZUhhbmRsZXIoKSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvWHNsRWxlbWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvWHNsRWxlbWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZDFhMjI3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL1hzbEVsZW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0NSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLio7Ci0KLWZpbmFsIGNsYXNzIFhzbEVsZW1lbnQgZXh0ZW5kcyBJbnN0cnVjdGlvbiB7Ci0KLSAgICBwcml2YXRlIEF0dHJpYnV0ZVZhbHVlIF9uYW1lOyAvLyBuYW1lIHRyZWF0ZWQgYXMgQVZUICg3LjEuMykKLSAgICBwcml2YXRlIEF0dHJpYnV0ZVZhbHVlVGVtcGxhdGUgX25hbWVzcGFjZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgIF9wcmVmaXg7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pZ25vcmUgPSBmYWxzZTsKLQotICAgIC8qKgotICAgICAqIERpc3BsYXlzIHRoZSBjb250ZW50cyBvZiB0aGUgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGRpc3BsYXkoaW50IGluZGVudCkgewotCWluZGVudChpbmRlbnQpOwotCVV0aWwucHJpbnRsbigiRWxlbWVudCAiICsgX25hbWUpOwotCWRpc3BsYXlDb250ZW50cyhpbmRlbnQgKyBJbmRlbnRJbmNyZW1lbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBhcnNlcyB0aGUgZWxlbWVudCdzIGNvbnRlbnRzLiBTcGVjaWFsIGNhcmUgdGFrZW4gZm9yIG5hbWVzcGFjZXMuCi0gICAgICogVE9ETzogVGhlIG5hbWVzcGFjZSBhdHRyaWJ1dGUgdGhhdCBzcGVjaWZpZXMgdGhlIG5hbWVzcGFjZSB0byB1c2UKLSAgICAgKiBmb3IgdGhlIGVsZW1lbnQgaXMgYW4gYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIGFuZCBub3QgYSBzdHJpbmcKLSAgICAgKiBjb25zdGFudC4gVGhpcyBtZWFucyB0aGF0IHdlIGRvIG5vdCBrbm93IHdoYXQgbmFtZXNwYWNlIGlzIHVzZWQKLSAgICAgKiBiZWZvcmUgcnVudGltZS4gVGhpcyBjYXVzZXMgYSBwcm9ibGVtIHdpdGggdGhlIHdheSBvdXRwdXQgbmFtZXNwYWNlcwotICAgICAqIGFyZSBoYW5kbGVkIGF0IGNvbXBpbGUtdGltZS4gV2UgdXNlIGEgc2hvcnRjdXQgaW4gdGhpcyBtZXRob2QgdG8gZ2V0Ci0gICAgICogYXJvdW5kIHRoZSBwcm9ibGVtIGJ5IHRyZWF0aW5nIHRoZSBuYW1hc3BhY2UgYXR0cmlidXRlIGFzIGEgY29uc3RhbnQuCi0gICAgICogICAgICAgICAgKFllcywgSSBrbm93IHRoaXMgaXMgYSBoYWNrLCBiYWQsIGJhZCwgYmFkLikKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwYXJzZUNvbnRlbnRzKFBhcnNlciBwYXJzZXIpIHsKLQotCWZpbmFsIFN5bWJvbFRhYmxlIHN0YWJsZSA9IHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpOwotCi0JLy8gR2V0IHRoZSAibmFtZSIgYXR0cmlidXRlIG9mIHRoZSA8eHNsOmVsZW1lbnQ+IGVsZW1lbnQKLQlTdHJpbmcgbmFtZSA9IGdldEF0dHJpYnV0ZSgibmFtZSIpOwotCWlmICgobmFtZSA9PSBudWxsKSB8fCAobmFtZS5lcXVhbHMoRU1QVFlTVFJJTkcpKSkgewotCSAgICBmaW5hbCBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coIllvdSBjYW4ndCBjYWxsIGFuIGVsZW1lbnQgXCJcIiIpOwotCSAgICBwYXJzZXIucmVwb3J0RXJyb3IoV0FSTklORywgbXNnKTsKLQkgICAgX2lnbm9yZSA9IHRydWU7IC8vIElnbm9yZSB0aGUgZWxlbWVudCBpZiB0aGUgUU5hbWUgaXMgaW52YWxpZAotCSAgICByZXR1cm47Ci0JfQotCi0JLy8gVHJ5IHRvIGNvbnN0cnVjdCBhIFFOYW1lIGFuZCB0aGVuIGdldCB0aGUgcHJlZml4IGFuZCBsb2NhbCBwYXJ0Ci0JUU5hbWUgIHFuYW1lICA9IHBhcnNlci5nZXRRTmFtZVNhZmUobmFtZSk7Ci0JU3RyaW5nIHByZWZpeCA9IHFuYW1lLmdldFByZWZpeCgpOwotCVN0cmluZyBsb2NhbCAgPSBxbmFtZS5nZXRMb2NhbFBhcnQoKTsKLQotCS8vIEZpcnN0IHRyeSB0byBnZXQgdGhlIG5hbWVzcGFjZSBVUkkgZnJvbSB0aGUgIm5hbWVzcGFjZSIgYXR0cmlidXRlCi0JU3RyaW5nIG5hbWVzcGFjZSA9IGdldEF0dHJpYnV0ZSgibmFtZXNwYWNlIik7Ci0KLQkvLyBUaGVuIHRyeSB0byBnZXQgaXQgZnJvbSB0aGUgIm5hbWUiIGF0dHJpYnV0ZSBRTmFtZSBwcmVmaXgKLQlpZiAoKG5hbWVzcGFjZSA9PSBudWxsKSB8fCAobmFtZXNwYWNlLmVxdWFscyhFTVBUWVNUUklORykpKSB7Ci0KLQkgICAgLy8gV2UgYXJlIHN1cHBvc2VkIHRvIHVzZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgVVJJIGlmIHRoZSBRTmFtZQotCSAgICAvLyBmcm9tIHRoZSAibmFtZSIgYXR0cmlidXRlIGlzIG5vdCBwcmVmaXhlZCwgc28gY2hlY2sgdGhhdCBmaXJzdAotCSAgICBpZiAocHJlZml4ID09IG51bGwpIHByZWZpeCA9IEVNUFRZU1RSSU5HOwotCSAgICAvLyBUaGVuIGxvb2sgdXAgdGhlIFVSSSB0aGF0IGlzIGluIHNjb3BlIGZvciB0aGUgcHJlZml4Ci0JICAgIG5hbWVzcGFjZSA9IGxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOyAKLQotCSAgICAvLyBTaWduYWwgZXJyb3IgaWYgdGhlIHByZWZpeCBkb2VzIG5vdCBtYXAgdG8gYW55IG5hbWVzcGFjZSBVUkkgCi0JICAgIGlmIChuYW1lc3BhY2UgPT0gbnVsbCkgewotCQlmaW5hbCBFcnJvck1zZyBtc2cgPSBuZXcgRXJyb3JNc2coRXJyb3JNc2cuTlNQVU5ERUZfRVJSLHByZWZpeCk7Ci0JCXBhcnNlci5yZXBvcnRFcnJvcihXQVJOSU5HLCBtc2cpOwotCQlwYXJzZUNoaWxkcmVuKHBhcnNlcik7Ci0JCV9pZ25vcmUgPSB0cnVlOyAvLyBJZ25vcmUgdGhlIGVsZW1lbnQgaWYgcHJlZml4IGlzIHVuZGVjbGFyZWQKLQkJcmV0dXJuOwotCSAgICB9Ci0JICAgIF9uYW1lc3BhY2UgPSBuZXcgQXR0cmlidXRlVmFsdWVUZW1wbGF0ZShuYW1lc3BhY2UsIHBhcnNlcik7Ci0JICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0JfQotCS8vIENoZWNrIGlmIHRoaXMgZWxlbWVudCBiZWxvbmdzIGluIGEgc3BlY2lmaWMgbmFtZXNwYWNlCi0JZWxzZSBpZiAobmFtZXNwYWNlICE9IEVNUFRZU1RSSU5HKSB7Ci0JICAgIC8vIEdldCB0aGUgbmFtZXNwYWNlIHJlcXVlc3RlZCBieSB0aGUgeHNsOmVsZW1lbnQKLQkgICAgX25hbWVzcGFjZSA9IG5ldyBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlKG5hbWVzcGFjZSwgcGFyc2VyKTsKLQkgICAgLy8gR2V0IHRoZSBjdXJyZW50IHByZWZpeCBmb3IgdGhhdCBuYW1lc3BhY2UgKGlmIGFueSkKLQkgICAgX3ByZWZpeCA9IGxvb2t1cFByZWZpeChuYW1lc3BhY2UpOwotCSAgICAvLyBJcyBpdCB0aGUgZGVmYXVsdCBuYW1lc3BhY2U/Ci0JICAgIGlmICgoX3ByZWZpeCA9IHByZWZpeCkgPT0gbnVsbCkgX3ByZWZpeCA9IEVNUFRZU1RSSU5HOwotCi0JICAgIC8vIENvbnN0cnVjdCBmaW5hbCBlbGVtZW50IFFOYW1lCi0JICAgIGlmIChfcHJlZml4ID09IEVNUFRZU1RSSU5HKQotCQluYW1lID0gcW5hbWUuZ2V0TG9jYWxQYXJ0KCk7Ci0JICAgIGVsc2UKLQkJbmFtZSA9IF9wcmVmaXgrIjoiK3FuYW1lLmdldExvY2FsUGFydCgpOwotCX0KLQotCV9uYW1lID0gQXR0cmlidXRlVmFsdWUuY3JlYXRlKHRoaXMsIG5hbWUsIHBhcnNlcik7Ci0KLQkvLyBOZXh0IGNoZWNrIHRoYXQgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIFFOYW1lIGlzIGxlZ2FsIChubyB3aGl0ZXNwYWNlKQotCWlmICgoX25hbWUgaW5zdGFuY2VvZiBTaW1wbGVBdHRyaWJ1dGVWYWx1ZSkgJiYKLQkgICAgKGxvY2FsLmluZGV4T2YoJyAnKSA+IC0xKSkgewotCSAgICBmaW5hbCBTdHJpbmcgZXJybXNnID0gIllvdSBjYW4ndCBjYWxsIGFuIGVsZW1lbnQgXCIiK2xvY2FsKyJcIiI7Ci0JICAgIHBhcnNlci5yZXBvcnRFcnJvcihXQVJOSU5HLCBuZXcgRXJyb3JNc2coZXJybXNnKSk7Ci0JICAgIHBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLQkgICAgX2lnbm9yZSA9IHRydWU7IC8vIElnbm9yZSB0aGUgZWxlbWVudCBpZiB0aGUgbG9jYWwgcGFydCBpcyBpbnZhbGlkCi0JICAgIHJldHVybjsKLQl9Ci0KLQkvLyBIYW5kbGUgdGhlICd1c2UtYXR0cmlidXRlLXNldHMnIGF0dHJpYnV0ZQotCWZpbmFsIFN0cmluZyB1c2VTZXRzID0gZ2V0QXR0cmlidXRlKCJ1c2UtYXR0cmlidXRlLXNldHMiKTsKLQlpZiAodXNlU2V0cy5sZW5ndGgoKSA+IDApIHsKLQkgICAgc2V0Rmlyc3RFbGVtZW50KG5ldyBVc2VBdHRyaWJ1dGVTZXRzKHVzZVNldHMsIHBhcnNlcikpOwotCX0KLQotCXBhcnNlQ2hpbGRyZW4ocGFyc2VyKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSdW4gdHlwZSBjaGVjayBvbiBlbGVtZW50IG5hbWUgJiBjb250ZW50cwotICAgICAqLwotICAgIHB1YmxpYyBUeXBlIHR5cGVDaGVjayhTeW1ib2xUYWJsZSBzdGFibGUpIHRocm93cyBUeXBlQ2hlY2tFcnJvciB7Ci0JaWYgKCFfaWdub3JlKSB7Ci0JICAgIF9uYW1lLnR5cGVDaGVjayhzdGFibGUpOwotCSAgICBpZiAoX25hbWVzcGFjZSAhPSBudWxsKQotCQlfbmFtZXNwYWNlLnR5cGVDaGVjayhzdGFibGUpOwotCX0KLQl0eXBlQ2hlY2tDb250ZW50cyhzdGFibGUpOwotCXJldHVybiBUeXBlLlZvaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29tcGlsZXMgY29kZSB0aGF0IGVtaXRzIHRoZSBlbGVtZW50IHdpdGggdGhlIG5lY2Vzc2FyeSBuYW1lc3BhY2UKLSAgICAgKiBkZWZpbml0aW9ucy4gVGhlIGVsZW1lbnQgaXRzZWxmIGlzIGlnbm9yZWQgaWYgdGhlIGVsZW1lbnQgZGVmaW5pdGlvbgotICAgICAqIHdhcyBpbiBhbnkgd2F5IGVycm9ub3VzLCBidXQgdGhlIGNoaWxkIG5vZGVzIGFyZSBzdGlsbCBwcm9jZXNzZWQuCi0gICAgICogU2VlIHRoZSBvdmVycmlkZW4gdHJhbnNsYXRlQ29udGVudHMoKSBtZXRob2QgYXMgd2VsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGUoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gSWdub3JlIHRoaXMgZWxlbWVudCBpZiBub3QgY29ycmVjdGx5IGRlY2xhcmVkCi0JaWYgKCFfaWdub3JlKSB7Ci0JICAgIC8vIENvbXBpbGUgY29kZSB0aGF0IGVtaXRzIHRoZSBlbGVtZW50IHN0YXJ0IHRhZwotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCSAgICBfbmFtZS50cmFuc2xhdGUoY2xhc3NHZW4sIG1ldGhvZEdlbik7Ci0JICAgIGlsLmFwcGVuZChEVVAyKTsJLy8gZHVwbGljYXRlIHRoZXNlIDIgYXJncyBmb3IgZW5kRWxlbWVudAotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLnN0YXJ0RWxlbWVudCgpKTsKLQotCSAgICAvLyBDb21waWxlIGNvZGUgdGhhdCBlbWl0cyBhbnkgbmVlZGVkIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotCSAgICBpZiAoX25hbWVzcGFjZSAhPSBudWxsKSB7Ci0JCS8vIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZShmaW5hbCBTdHJpbmcgbmFtZSwgZmluYWwgU3RyaW5nIHZhbHVlKQotCQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRIYW5kbGVyKCkpOwotCQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfcHJlZml4KSk7Ci0JCV9uYW1lc3BhY2UudHJhbnNsYXRlKGNsYXNzR2VuLG1ldGhvZEdlbik7Ci0JCWlsLmFwcGVuZChtZXRob2RHZW4ubmFtZXNwYWNlKCkpOwotCSAgICB9Ci0JfQotCi0JLy8gQ29tcGlsZSBjb2RlIHRoYXQgZW1pdHMgdGhlIGVsZW1lbnQgYXR0cmlidXRlcyBhbmQgY29udGVudHMKLQl0cmFuc2xhdGVDb250ZW50cyhjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQotCS8vIElnbm9yZSB0aGlzIGVsZW1lbnQgaWYgbm90IGNvcnJlY3RseSBkZWNsYXJlZAotCWlmICghX2lnbm9yZSkgewotCSAgICAvLyBDb21waWxlIGNvZGUgdGhhdCBlbWl0cyB0aGUgZWxlbWVudCBlbmQgdGFnCi0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4uZW5kRWxlbWVudCgpKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gbWFrZSBzdXJlIHRoYXQgeHNsOmF0dHJpYnV0ZXMgYXJlIG5vdAotICAgICAqIGNvcGllZCB0byBvdXRwdXQgaWYgdGhpcyB4c2w6ZWxlbWVudCBpcyB0byBiZSBpZ25vcmVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQ29udGVudHMoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkJICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgaW50IG4gPSBlbGVtZW50Q291bnQoKTsKLQlmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCSAgICBmaW5hbCBTeW50YXhUcmVlTm9kZSBpdGVtID0KLQkJKFN5bnRheFRyZWVOb2RlKWdldENvbnRlbnRzKCkuZWxlbWVudEF0KGkpOwotCSAgICBpZiAoKF9pZ25vcmUpICYmIChpdGVtIGluc3RhbmNlb2YgWHNsQXR0cmlidXRlKSkgY29udGludWU7Ci0JICAgIGl0ZW0udHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotCX0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL2hlYWRlci50eHQgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci9oZWFkZXIudHh0CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxOGUxZWY2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL2hlYWRlci50eHQKKysrIC9kZXYvbnVsbApAQCAtMSwxNCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBDb3B5cmlnaHQgMjAwMCBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiAKLSAqIFRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uIG9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gIAotICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcy4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiAKLSAqLwotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL0F0dHJpYnV0ZVNldE1ldGhvZEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNDVjZWM0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuVGVtcGxhdGU7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVTZXRNZXRob2RHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotICAgIHByaXZhdGUgc3RhdGljIGludCBIQU5ETEVSX0lOREVYID0gMTsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgSVRFUkFUT1JfSU5ERVggPSAyOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVtdIGFyZ1R5cGVzID0KLQluZXcgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZVsyXTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBhcmdOYW1lcyA9IG5ldyBTdHJpbmdbMl07Ci0gICAgCi0gICAgc3RhdGljIHsKLQlhcmdUeXBlc1swXSA9IFV0aWwuZ2V0SkNSZWZUeXBlKFRSQU5TTEVUX09VVFBVVF9TSUcpOwotCWFyZ05hbWVzWzBdID0gVFJBTlNMRVRfT1VUUFVUX1BOQU1FOwotCWFyZ1R5cGVzWzFdID0gVXRpbC5nZXRKQ1JlZlR5cGUoTk9ERV9JVEVSQVRPUl9TSUcpOwotCWFyZ05hbWVzWzFdID0gSVRFUkFUT1JfUE5BTUU7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYXN0b3JlSGFuZGxlcjsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZEhhbmRsZXI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYXN0b3JlSXRlcmF0b3I7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYWxvYWRJdGVyYXRvcjsKLSAgICAKLSAgICBwdWJsaWMgQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yKFN0cmluZyBtZXRob2ROYW1lLCBDbGFzc0dlbiBjbGFzc0dlbikgewotCXN1cGVyKGRlLmZ1Yi5ieXRlY29kZS5Db25zdGFudHMuQUNDX1BSSVZBVEUsCi0JICAgICAgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5WT0lELAotCSAgICAgIGFyZ1R5cGVzLCBhcmdOYW1lcywgbWV0aG9kTmFtZSwgCi0JICAgICAgY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCksCi0JICAgICAgbmV3IEluc3RydWN0aW9uTGlzdCgpLAotCSAgICAgIGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpKTsKLQkKLQlfYXN0b3JlSGFuZGxlciAgPSBuZXcgQVNUT1JFKEhBTkRMRVJfSU5ERVgpOwotCV9hbG9hZEhhbmRsZXIgICA9IG5ldyBBTE9BRChIQU5ETEVSX0lOREVYKTsKLQlfYXN0b3JlSXRlcmF0b3IgPSBuZXcgQVNUT1JFKElURVJBVE9SX0lOREVYKTsKLQlfYWxvYWRJdGVyYXRvciAgPSBuZXcgQUxPQUQoSVRFUkFUT1JfSU5ERVgpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUl0ZXJhdG9yKCkgewotCXJldHVybiBfYXN0b3JlSXRlcmF0b3I7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkSXRlcmF0b3IoKSB7Ci0JcmV0dXJuIF9hbG9hZEl0ZXJhdG9yOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SXRlcmF0b3JJbmRleCgpIHsKLQlyZXR1cm4gSVRFUkFUT1JfSU5ERVg7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlSGFuZGxlcigpIHsKLQlyZXR1cm4gX2FzdG9yZUhhbmRsZXI7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRIYW5kbGVyKCkgewotCXJldHVybiBfYWxvYWRIYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxJbmRleChTdHJpbmcgbmFtZSkgewotCXJldHVybiBJTlZBTElEX0lOREVYOwkvLyBub3QgYXZhaWxhYmxlCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Cb29sZWFuVHlwZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Cb29sZWFuVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ODZlYjU5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQm9vbGVhblR5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlBhcnNlcjsKLQotcHVibGljIGZpbmFsIGNsYXNzIEJvb2xlYW5UeXBlIGV4dGVuZHMgVHlwZSB7Ci0gICAgcHJvdGVjdGVkIEJvb2xlYW5UeXBlKCkge30KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJib29sZWFuIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZGVudGljYWxUbyhUeXBlIG90aGVyKSB7Ci0JcmV0dXJuIHRoaXMgPT0gb3RoZXI7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZSgpIHsKLQlyZXR1cm4gIloiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzU2ltcGxlKCkgewotCXJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHB1YmxpYyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotCXJldHVybiBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLkJPT0xFQU47Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlYWwgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4gVGhlCi0gICAgICogdHJhbnNsYXRpb24gdG8gaW50IGlzIHVuZGVmaW5lZCBzaW5jZSBib29sZWFucyBhcmUgYWx3YXlzIGNvbnZlcnRlZCB0bwotICAgICAqIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFR5cGUgdHlwZSkgewotCWlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlYWxUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5pbnRlcm5hbEVycm9yKCk7IC8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgYm9vbGVhbiBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHN0cmluZy4gSWYgdGhlIHZhbHVlIG9uIHRoZQotICAgICAqIHN0YWNrIGlzIHplcm8sIHRoZW4gdGhlIHN0cmluZyAnZmFsc2UnIGlzIHB1c2hlZC4gT3RoZXJ3aXNlLCB0aGUgc3RyaW5nCi0gICAgICogJ3RydWUnIGlzIHB1c2hlZC4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgU3RyaW5nVHlwZSB0eXBlKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBCcmFuY2hIYW5kbGUgZmFsc2VjID0gaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCAidHJ1ZSIpKTsKLQlmaW5hbCBCcmFuY2hIYW5kbGUgdHJ1ZWMgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCWZhbHNlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgImZhbHNlIikpKTsKLQl0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSBib29sZWFuIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgcmVhbC4gVGhlIHZhbHVlICJ0cnVlIiBpcwotICAgICAqIGNvbnZlcnRlZCB0byAxLjAgYW5kIHRoZSB2YWx1ZSAiZmFsc2UiIHRvIDAuMC4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgUmVhbFR5cGUgdHlwZSkgewotCW1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoSTJEKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgYm9vbGVhbiBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIGJvb2xlYW4uCi0gICAgICogQm94ZWQgYm9vbGVhbnMgYXJlIHJlcHJlc2VudGVkIGJ5IGFuIGluc3RhbmNlIG9mCi0gICAgICogPGNvZGU+amF2YS5sYW5nLkJvb2xlYW48L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWZlcmVuY2VUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhCT09MRUFOX0NMQVNTKSkpOwotCWlsLmFwcGVuZChEVVBfWDEpOwotCWlsLmFwcGVuZChTV0FQKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihCT09MRUFOX0NMQVNTLAotCQkJCQkJICAgICAiPGluaXQ+IiwKLQkJCQkJCSAgICAgIihaKVYiKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gaW50ZXJuYWwgYm9vbGVhbiBpbnRvIGFuIGV4dGVybmFsIChKYXZhKSBib29sZWFuLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBDbGFzcyBjbGF6eikgewotCWlmIChjbGF6eiA9PSBqYXZhLmxhbmcuQm9vbGVhbi5UWVBFKSB7Ci0JICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsgLy8gdW5kZWZpbmVkCi0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gZXh0ZXJuYWwgKEphdmEpIGJvb2xlYW4gaW50byBpbnRlcm5hbCBib29sZWFuLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUZyb20oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgICAgQ2xhc3MgY2xhenopIHsKLQl0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBjbGF6eik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKEJPT0xFQU5fQ0xBU1MpKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGNwZy5hZGRNZXRob2RyZWYoQk9PTEVBTl9DTEFTUywKLQkJCQkJCSAgICAgQk9PTEVBTl9WQUxVRSwgCi0JCQkJCQkgICAgIEJPT0xFQU5fVkFMVUVfU0lHKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0JcmV0dXJuIG5ldyBJTE9BRChzbG90KTsKLSAgICB9Ci0JCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0JcmV0dXJuIG5ldyBJU1RPUkUoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIEdUKGJvb2xlYW4gdG96ZXJvKSB7Ci0JcmV0dXJuIHRvemVybyA/IChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGR1QobnVsbCkgOiAKLQkgICAgKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZfSUNNUEdUKG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBHRShib29sZWFuIHRvemVybykgewotCXJldHVybiB0b3plcm8gPyAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkdFKG51bGwpIDogCi0JICAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGX0lDTVBHRShudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gTFQoYm9vbGVhbiB0b3plcm8pIHsKLQlyZXR1cm4gdG96ZXJvID8gKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZMVChudWxsKSA6IAotCSAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRl9JQ01QTFQobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIExFKGJvb2xlYW4gdG96ZXJvKSB7Ci0JcmV0dXJuIHRvemVybyA/IChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGTEUobnVsbCkgOiAKLQkgICAgKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZfSUNNUExFKG51bGwpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ2xhc3NHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ2xhc3NHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGNlY2E3MC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL0NsYXNzR2VuZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjEgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5TdHlsZXNoZWV0OwotCi0vKioKLSAqIFRoZSBjbGFzcyB0aGF0IGltcGxlbWVudHMgYW55IGNsYXNzIHRoYXQgaW5oZXJpdHMgZnJvbSAKLSAqIDx0dD5BYnN0cmFjdFRyYW5zbGV0PC90dD4sIGkuZS4gYW55IHRyYW5zbGV0LiBNZXRob2RzIGluIHRoaXMgCi0gKiBjbGFzcyBtYXkgYmUgb2YgdGhlIGZvbGxvd2luZyBraW5kczogCi0gKgotICogMS4gTWFpbiBtZXRob2Q6IGFwcGx5VGVtcGxhdGVzLCBpbXBsZW1lbnRlZCBieSBpbnRhbmNlcyBvZiAKLSAqIDx0dD5NZXRob2RHZW5lcmF0b3I8L3R0Pi4KLSAqCi0gKiAyLiBOYW1lZCBtZXRob2RzOiBmb3IgbmFtZWQgdGVtcGxhdGVzLCBpbXBsZW1lbnRlZCBieSBpbnN0YW5jZXMgCi0gKiBvZiA8dHQ+TmFtZWRNZXRob2RHZW5lcmF0b3I8L3R0Pi4KLSAqCi0gKiAzLiBSdCBtZXRob2RzOiBmb3IgcmVzdWx0IHRyZWUgZnJhZ21lbnRzLCBpbXBsZW1lbnRlZCBieSAKLSAqIGluc3RhbmNlcyBvZiA8dHQ+UnRNZXRob2RHZW5lcmF0b3I8L3R0Pi4KLSAqLwotcHVibGljIGNsYXNzIENsYXNzR2VuZXJhdG9yIGV4dGVuZHMgQ2xhc3NHZW4gewotICAgIHByb3RlY3RlZCBzdGF0aWMgaW50IFRSQU5TTEVUX0lOREVYID0gMDsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBJTlZBTElEX0lOREVYICA9IC0xOwotCi0gICAgcHJpdmF0ZSBTdHlsZXNoZWV0IF9zdHlsZXNoZWV0OwotICAgIHByaXZhdGUgZmluYWwgUGFyc2VyIF9wYXJzZXI7CQkvLyAtLT4gY2FuIGJlIG1vdmVkIHRvIFhTTFQKLSAgICAvLyBhICBzaW5nbGUgaW5zdGFuY2UgY2FjaGVkIGhlcmUKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZFRyYW5zbGV0OwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9kb21DbGFzczsKLSAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBfZG9tQ2xhc3NTaWc7Ci0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgX2FwcGx5VGVtcGxhdGVzU2lnOwotCi0gICAgcHVibGljIENsYXNzR2VuZXJhdG9yKFN0cmluZyBjbGFzc19uYW1lLCBTdHJpbmcgc3VwZXJfY2xhc3NfbmFtZSwKLQkJCSAgU3RyaW5nIGZpbGVfbmFtZSwKLQkJCSAgaW50IGFjY2Vzc19mbGFncywgU3RyaW5nW10gaW50ZXJmYWNlcywKLQkJCSAgU3R5bGVzaGVldCBzdHlsZXNoZWV0KSB7Ci0Jc3VwZXIoY2xhc3NfbmFtZSwgc3VwZXJfY2xhc3NfbmFtZSwgZmlsZV9uYW1lLAotCSAgICAgIGFjY2Vzc19mbGFncywgaW50ZXJmYWNlcyk7Ci0JX3N0eWxlc2hlZXQgPSBzdHlsZXNoZWV0OwotCV9wYXJzZXIgPSBzdHlsZXNoZWV0LmdldFBhcnNlcigpOwotCV9hbG9hZFRyYW5zbGV0ID0gbmV3IEFMT0FEKFRSQU5TTEVUX0lOREVYKTsKLQkKLQlpZiAoc3R5bGVzaGVldC5pc011bHRpRE9NKCkpIHsKLQkgICAgX2RvbUNsYXNzID0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLk11bHRpRE9NIjsKLQkgICAgX2RvbUNsYXNzU2lnID0gIkxvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9NdWx0aURPTTsiOwotCX0KLQllbHNlIHsKLQkgICAgX2RvbUNsYXNzID0gIm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRPTUFkYXB0ZXIiOwotCSAgICBfZG9tQ2xhc3NTaWcgPSAiTG9yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUFkYXB0ZXI7IjsKLQl9Ci0JX2FwcGx5VGVtcGxhdGVzU2lnID0gIigiIAotCSAgICArIENvbnN0YW50cy5ET01fSU5URl9TSUcKLQkgICAgKyBDb25zdGFudHMuTk9ERV9JVEVSQVRPUl9TSUcKLQkgICAgKyBDb25zdGFudHMuVFJBTlNMRVRfT1VUUFVUX1NJRwotCSAgICArICIpViI7IAotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBQYXJzZXIgZ2V0UGFyc2VyKCkgewotCXJldHVybiBfcGFyc2VyOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBTdHlsZXNoZWV0IGdldFN0eWxlc2hlZXQoKSB7Ci0JcmV0dXJuIF9zdHlsZXNoZWV0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByZXRlbmQgdGhpcyBpcyB0aGUgc3R5bGVzaGVldCBjbGFzcy4gVXNlZnVsIHdoZW4gY29tcGlsaW5nIAotICAgICAqIHJlZmVyZW5jZXMgdG8gZ2xvYmFsIHZhcmlhYmxlcyBpbnNpZGUgYSBwcmVkaWNhdGUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0JcmV0dXJuIF9zdHlsZXNoZWV0LmdldENsYXNzTmFtZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkVHJhbnNsZXQoKSB7Ci0JcmV0dXJuIF9hbG9hZFRyYW5zbGV0OwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0RE9NQ2xhc3MoKSB7Ci0JcmV0dXJuIF9kb21DbGFzczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldERPTUNsYXNzU2lnKCkgewotCXJldHVybiBfZG9tQ2xhc3NTaWc7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBcHBseVRlbXBsYXRlc1NpZygpIHsKLQlyZXR1cm4gX2FwcGx5VGVtcGxhdGVzU2lnOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBvciA8dHQ+ZmFsc2U8L3R0PiBkZXBlbmRpbmcgb24gd2hldGhlcgotICAgICAqIHRoaXMgY2xhc3MgaW5oZXJpdHMgZnJvbSA8dHQ+QWJzdHJhY3RUcmFuc2xldDwvdHQ+IG9yIG5vdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL0NvbXBhcmVHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ29tcGFyZUdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlZGVkNmUwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvQ29tcGFyZUdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLkNvbnN0YW50czsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlRlbXBsYXRlOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgQ29tcGFyZUdlbmVyYXRvciBleHRlbmRzIE1ldGhvZEdlbmVyYXRvciB7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgRE9NX0lOREVYICAgICAgPSAxOwotICAgIHByaXZhdGUgc3RhdGljIGludCBDVVJSRU5UX0lOREVYICA9IDI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IExFVkVMX0lOREVYICAgID0gMzsKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgVFJBTlNMRVRfSU5ERVggPSA0OwotICAgIHByaXZhdGUgc3RhdGljIGludCBMQVNUX0lOREVYICAgICA9IDU7Ci0gICAgcHJpdmF0ZSBpbnQgSVRFUkFUT1JfSU5ERVggPSA2OwotCi0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfaWxvYWRDdXJyZW50OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lzdG9yZUN1cnJlbnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYWxvYWREb207Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfaWxvYWRMYXN0OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkSXRlcmF0b3I7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYXN0b3JlSXRlcmF0b3I7Ci0KLSAgICBwdWJsaWMgQ29tcGFyZUdlbmVyYXRvcihpbnQgYWNjZXNzX2ZsYWdzLCBUeXBlIHJldHVybl90eXBlLAotCQkJICAgIFR5cGVbXSBhcmdfdHlwZXMsIFN0cmluZ1tdIGFyZ19uYW1lcywKLQkJCSAgICBTdHJpbmcgbWV0aG9kX25hbWUsIFN0cmluZyBjbGFzc19uYW1lLAotCQkJICAgIEluc3RydWN0aW9uTGlzdCBpbCwgQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0Jc3VwZXIoYWNjZXNzX2ZsYWdzLCByZXR1cm5fdHlwZSwgYXJnX3R5cGVzLCBhcmdfbmFtZXMsIG1ldGhvZF9uYW1lLCAKLQkgICAgICBjbGFzc19uYW1lLCBpbCwgY3ApOwotCQotCV9pbG9hZEN1cnJlbnQgPSBuZXcgSUxPQUQoQ1VSUkVOVF9JTkRFWCk7Ci0JX2lzdG9yZUN1cnJlbnQgPSBuZXcgSVNUT1JFKENVUlJFTlRfSU5ERVgpOwotCV9hbG9hZERvbSA9IG5ldyBBTE9BRChET01fSU5ERVgpOwotCV9pbG9hZExhc3QgPSBuZXcgSUxPQUQoTEFTVF9JTkRFWCk7Ci0KLQlMb2NhbFZhcmlhYmxlR2VuIGl0ZXJhdG9yID0KLQkgICAgYWRkTG9jYWxWYXJpYWJsZSgiaXRlcmF0b3IiLAotCQkJICAgICBVdGlsLmdldEpDUmVmVHlwZShDb25zdGFudHMuTk9ERV9JVEVSQVRPUl9TSUcpLAotCQkJICAgICBudWxsLCBudWxsKTsKLQlJVEVSQVRPUl9JTkRFWCA9IGl0ZXJhdG9yLmdldEluZGV4KCk7Ci0JX2Fsb2FkSXRlcmF0b3IgPSBuZXcgQUxPQUQoSVRFUkFUT1JfSU5ERVgpOwotCV9hc3RvcmVJdGVyYXRvciA9IG5ldyBBU1RPUkUoSVRFUkFUT1JfSU5ERVgpOwotCWlsLmFwcGVuZChuZXcgQUNPTlNUX05VTEwoKSk7Ci0JaWwuYXBwZW5kKHN0b3JlSXRlcmF0b3IoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRMYXN0Tm9kZSgpIHsKLQlyZXR1cm4gX2lsb2FkTGFzdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEN1cnJlbnROb2RlKCkgewotCXJldHVybiBfaWxvYWRDdXJyZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUN1cnJlbnROb2RlKCkgewotCXJldHVybiBfaXN0b3JlQ3VycmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZERPTSgpIHsKLQlyZXR1cm4gX2Fsb2FkRG9tOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SGFuZGxlckluZGV4KCkgewotCXJldHVybiBJTlZBTElEX0lOREVYOwkJLy8gbm90IGF2YWlsYWJsZQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SXRlcmF0b3JJbmRleCgpIHsKLQlyZXR1cm4gSU5WQUxJRF9JTkRFWDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVJdGVyYXRvcigpIHsKLQlyZXR1cm4gX2FzdG9yZUl0ZXJhdG9yOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEl0ZXJhdG9yKCkgewotCXJldHVybiBfYWxvYWRJdGVyYXRvcjsKLSAgICB9Ci0KLSAgICAvLz8/PyBtYXkgbm90IGJlIHVzZWQgYW55bW9yZQotICAgIHB1YmxpYyBpbnQgZ2V0TG9jYWxJbmRleChTdHJpbmcgbmFtZSkgewotCWlmIChuYW1lLmVxdWFscygiY3VycmVudCIpKSB7Ci0JICAgIHJldHVybiBDVVJSRU5UX0lOREVYOwotCX0KLQlyZXR1cm4gc3VwZXIuZ2V0TG9jYWxJbmRleChuYW1lKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTXNnLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL0Vycm9yTXNnLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE3ZDEzZDIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9FcnJvck1zZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlN5bnRheFRyZWVOb2RlOwotCi1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRXJyb3JNc2cgewotICAgIHByaXZhdGUgaW50IF9jb2RlOwotICAgIHByaXZhdGUgaW50IF9saW5lOwotICAgIHByaXZhdGUgU3RyaW5nIF9tZXNzYWdlID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfdXJsID0gbnVsbDsKLSAgICBPYmplY3RbXSBfcGFyYW1zID0gbnVsbDsKLQkKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVExSRURFRl9FUlIgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRNUFJFREVGX0VSUiA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFSUkVERUZfRVJSID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQVJVTkRFRl9FUlIgPSAzOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMU1VOREVGX0VSUiA9IDQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVUVU5ERUZfRVJSID0gNTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUTVBVTkRFRl9FUlIgPSA2OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENBTk5PVENWX0VSUiA9IDc7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklMRU5PVEZfRVJSID0gODsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlZBTFVSSV9FUlIgPSA5OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJTEVDQU5UX0VSUiA9IDEwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUWU9SVFJBX0VSUiA9IDExOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5TUFVOREVGX0VSUiA9IDEyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTlJFU09MX0VSUiA9IDEzOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExJVEVSQUxTX0VSUiA9IDE0OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFhQQVRIUEFSX0VSUiA9IDE1OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5SRVFBVFRSX0VSUiA9IDE2OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfVVNFX0VSUiA9IDE3OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElMTEVHX1BJX0VSUiA9IDE4OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVFJPVVRTX0VSUiA9IDE5OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElMTF9BVFRSX0VSUiA9IDIwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENJUkNVTEFSX0lOQyA9IDIxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSRUVTT1JUX0VSUiA9IDIyOwotCi0gICAgc3RhdGljIGZpbmFsIFN0cmluZyBtZXNzYWdlc19kW10gPSB7IAotCSJNb3JlIHRoYW4gb25lIHN0eWxlc2hlZXQgZGVmaW5lZCBpbiB0aGUgc2FtZSBmaWxlLiIsCi0JIlRlbXBsYXRlICcnezB9JycgYWxyZWFkeSBkZWZpbmVkIGluIHRoaXMgc3R5bGVzaGVldC4iLAotCSJWYXJpYWJsZSAnJ3swfScnIGlzIG11bHRpcGx5IGRlZmluZWQgaW4gdGhlIHNhbWUgc2NvcGUuIiwKLQkiVmFyaWFibGUgb3IgcGFyYW1ldGVyICcnezB9JycgaXMgdW5kZWZpbmVkLiIsCi0JIkNhbm5vdCBmaW5kIGV4dGVybmFsIGNsYXNzICcnezB9JycuIiwKLQkiQ2Fubm90IGZpbmQgZXh0ZXJuYWwgbWV0aG9kICcnezB9JycgKEl0IG11c3QgYmUgc3RhdGljIGFuZCBwdWJsaWMpLiIsCi0JIlRlbXBsYXRlICcnezB9Jycgbm90IGRlZmluZWQgaW4gdGhpcyBzdHlsZXNoZWV0LiIsCi0JIkNhbm5vdCBjb252ZXJ0IGFyZ3VtZW50L3JldHVybiB0eXBlIGluIGNhbGwgdG8gTWV0aG9kICcnezB9Jycgb2YgY2xhc3MgJyd7MX0nJy4iLAotCSJGaWxlIG9yIFVSSSAnJ3swfScnIG5vdCBmb3VuZC4iLAotCSJJbnZhbGlkIFVSSSAnJ3swfScnLiIsCi0JIkNhbm5vdCBvcGVuIGZpbGUgJyd7MH0nJy4iLAotCSInc3R5bGVzaGVldCcgb3IgJ3RyYW5zZm9ybScgZWxlbWVudCBleHBlY3RlZC4iLAotCSJFbGVtZW50IHByZWZpeCAnJ3swfScnIGlzIHVuZGVjbGFyZWQuIiwKLQkiVW5hYmxlIHRvIHJlc29sdmUgY2FsbCB0byBmdW5jdGlvbiAnJ3swfScnLiIsCi0JIkFyZ3VtZW50IHRvICcnezB9JycgbXVzdCBiZSBhIGxpdGVyYWwgc3RyaW5nLiIsCi0JIkVycm9yIHBhcnNpbmcgWFBhdGggZXhwcmVzc2lvbiAnJ3swfScnLiIsCi0JIlJlcXVpcmVkIGF0dHJpYnV0ZSAnJ3swfScnIGlzIG1pc3NpbmcuIiwKLQkiSWxsZWdhbCB1c2Ugb2YgZnVuY3Rpb24gJyd7MH0nJy4iLAotCSJJbGxlZ2FsIG5hbWUgJyd7MH0nJyBmb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4iLAotCSJBdHRyaWJ1dGUgJyd7MH0nJyBvdXRzaWRlIG9mIGVsZW1lbnQuIiwKLQkiSWxsZWdhbCBhdHRyaWJ1dGUgbmFtZSAnJ3swfScnLiIsCi0JIkNpcmN1bGFyIGltcG9ydC9pbmNsdWRlLiBTdHlsZXNoZWV0ICcnezB9JycgYWxyZWFkeSBsb2FkZWQuIiwKLQkiQXBwbHlpbmcgPHhzbDpzb3J0PiB0byBhIHJlc3VsdCB0cmVlIGlzIG5vdCBzdXBwb3J0ZWQgKDx4c2w6c29ydD4gIisKLQkiZWxlbWVudHMgYXJlIGlnbm9yZWQpLiBZb3UgY2FuLCBhbmQgc2hvdWxkLCBzb3J0IHRoZSBub2RlcyB3aGVuICIrCi0JImNyZWF0aW5nIHRoZSByZXN1bHQgdHJlZS4iCi0gICAgfTsKLQotICAgIHB1YmxpYyBFcnJvck1zZyhpbnQgY29kZSkgewotCV9jb2RlID0gY29kZTsKLQlfbGluZSA9IDA7Ci0gICAgfQotCQotICAgIHB1YmxpYyBFcnJvck1zZyhTdHJpbmcgbWVzc2FnZSkgewotCV9jb2RlID0gLTE7Ci0JX21lc3NhZ2UgPSBtZXNzYWdlOwotCV9saW5lID0gMDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coU3RyaW5nIG1lc3NhZ2UsIGludCBsaW5lKSB7Ci0JX2NvZGUgPSAtMTsKLQlfbWVzc2FnZSA9IG1lc3NhZ2U7Ci0JX2xpbmUgPSBsaW5lOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvck1zZyhpbnQgY29kZSwgaW50IGxpbmUsIE9iamVjdCBwYXJhbSkgewotCV9jb2RlID0gY29kZTsKLQlfbGluZSA9IGxpbmU7Ci0JX3BhcmFtcyA9IG5ldyBPYmplY3RbXSB7IHBhcmFtIH07Ci0gICAgfQotCi0gICAgcHVibGljIEVycm9yTXNnKGludCBjb2RlLCBPYmplY3QgcGFyYW0pIHsKLQl0aGlzKGNvZGUpOwotCV9wYXJhbXMgPSBuZXcgT2JqZWN0WzFdOwotCV9wYXJhbXNbMF0gPSBwYXJhbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coaW50IGNvZGUsIE9iamVjdCBwYXJhbTEsIE9iamVjdCBwYXJhbTIpIHsKLQl0aGlzKGNvZGUpOwotCV9wYXJhbXMgPSBuZXcgT2JqZWN0WzJdOwotCV9wYXJhbXNbMF0gPSBwYXJhbTE7Ci0JX3BhcmFtc1sxXSA9IHBhcmFtMjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coaW50IGNvZGUsIFN5bnRheFRyZWVOb2RlIG5vZGUpIHsKLQlfY29kZSA9IGNvZGU7Ci0JX3VybCAgPSBnZXRGaWxlTmFtZShub2RlKTsKLQlfbGluZSA9IG5vZGUuZ2V0TGluZU51bWJlcigpOwotICAgIH0KLQotICAgIHB1YmxpYyBFcnJvck1zZyhpbnQgY29kZSwgT2JqZWN0IHBhcmFtMSwgU3ludGF4VHJlZU5vZGUgbm9kZSkgewotCV9jb2RlID0gY29kZTsKLQlfdXJsICA9IGdldEZpbGVOYW1lKG5vZGUpOwotCV9saW5lID0gbm9kZS5nZXRMaW5lTnVtYmVyKCk7Ci0JX3BhcmFtcyA9IG5ldyBPYmplY3RbMV07Ci0JX3BhcmFtc1swXSA9IHBhcmFtMTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgRXJyb3JNc2coaW50IGNvZGUsIE9iamVjdCBwYXJhbTEsIE9iamVjdCBwYXJhbTIsCi0JCSAgICBTeW50YXhUcmVlTm9kZSBub2RlKSB7Ci0JX2NvZGUgPSBjb2RlOwotCV91cmwgID0gZ2V0RmlsZU5hbWUobm9kZSk7Ci0JX2xpbmUgPSBub2RlLmdldExpbmVOdW1iZXIoKTsKLQlfcGFyYW1zID0gbmV3IE9iamVjdFsyXTsKLQlfcGFyYW1zWzBdID0gcGFyYW0xOwotCV9wYXJhbXNbMV0gPSBwYXJhbTI7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0RmlsZU5hbWUoU3ludGF4VHJlZU5vZGUgbm9kZSkgewotCXJldHVybiBub2RlLmdldFN0eWxlc2hlZXQoKS5nZXRTeXN0ZW1JZCgpOwotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGZvcm1hdExpbmUoKSB7Ci0JU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQlpZiAoX3VybCAhPSBudWxsKSB7Ci0JICAgIHJlc3VsdC5hcHBlbmQoX3VybCk7Ci0JICAgIHJlc3VsdC5hcHBlbmQoIjogIik7Ci0JfQotCWlmIChfbGluZSA+IDApIHsKLQkgICAgcmVzdWx0LmFwcGVuZCgiTGluZSAiKTsKLQkgICAgcmVzdWx0LmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKF9saW5lKSk7Ci0JICAgIHJlc3VsdC5hcHBlbmQoIjogIik7Ci0JfQotCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0JCi0gICAgLyoqCi0gICAgICogVGhpcyB2ZXJzaW9uIG9mIHRvU3RyaW5nKCkgdXNlcyB0aGUgX3BhcmFtcyBpbnN0YW5jZSB2YXJpYWJsZQotICAgICAqIHRvIGZvcm1hdCB0aGUgbWVzc2FnZS4gSWYgdGhlIDxjb2RlPl9jb2RlPC9jb2RlPiBpcyBuZWdhdGl2ZQotICAgICAqIHRoZSB1c2UgX21lc3NhZ2UgYXMgdGhlIGVycm9yIHN0cmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCVN0cmluZyBzdWZmaXggPSAoX3BhcmFtcyA9PSBudWxsKSA/IAotCSAgICAoX2NvZGUgPj0gMCA/IG5ldyBTdHJpbmcobWVzc2FnZXNfZFtfY29kZV0pIDogX21lc3NhZ2UpCi0JICAgIDogTWVzc2FnZUZvcm1hdC5mb3JtYXQobWVzc2FnZXNfZFtfY29kZV0sIF9wYXJhbXMpOwotCXJldHVybiBmb3JtYXRMaW5lKCkgKyBzdWZmaXg7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoT2JqZWN0IG9iaikgewotCU9iamVjdCBwYXJhbXNbXSA9IG5ldyBPYmplY3RbMV07Ci0JcGFyYW1zWzBdID0gb2JqLnRvU3RyaW5nKCk7Ci0JU3RyaW5nIHN1ZmZpeCA9IE1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1lc3NhZ2VzX2RbX2NvZGVdLCBwYXJhbXMpOwotCXJldHVybiBmb3JtYXRMaW5lKCkgKyBzdWZmaXg7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoT2JqZWN0IG9iajAsIE9iamVjdCBvYmoxKSB7Ci0JT2JqZWN0IHBhcmFtc1tdID0gbmV3IE9iamVjdFsyXTsKLQlwYXJhbXNbMF0gPSBvYmowLnRvU3RyaW5nKCk7Ci0JcGFyYW1zWzFdID0gb2JqMS50b1N0cmluZygpOwotCVN0cmluZyBzdWZmaXggPSBNZXNzYWdlRm9ybWF0LmZvcm1hdChtZXNzYWdlc19kW19jb2RlXSwgcGFyYW1zKTsKLQlyZXR1cm4gZm9ybWF0TGluZSgpICsgc3VmZml4OwotICAgIH0KLX0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9GaWx0ZXJHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvRmlsdGVyR2VuZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY2Yzg1MzkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9GaWx0ZXJHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlN0eWxlc2hlZXQ7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGF1eGxpYXJ5IGNsYXNzZXMgbmVlZGVkIHRvIGNvbXBpbGUgCi0gKiBmaWx0ZXJzIChwcmVkaWNhdGVzKS4gVGhlc2UgY2xhc3NlcyBkZWZpbmVkIGEgc2luZ2xlIG1ldGhvZAotICogb2YgdHlwZSA8dHQ+VGVzdEdlbmVyYXRvcjwvdHQ+LgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgRmlsdGVyR2VuZXJhdG9yIGV4dGVuZHMgQ2xhc3NHZW5lcmF0b3IgewotICAgIHByaXZhdGUgc3RhdGljIGludCBUUkFOU0xFVF9JTkRFWCA9IDU7ICAgLy8gdHJhbnNsZXQKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZFRyYW5zbGV0OwotCi0gICAgcHVibGljIEZpbHRlckdlbmVyYXRvcihTdHJpbmcgY2xhc3NOYW1lLCBTdHJpbmcgc3VwZXJDbGFzc05hbWUsCi0JCQkgICBTdHJpbmcgZmlsZU5hbWUsCi0JCQkgICBpbnQgYWNjZXNzRmxhZ3MsIFN0cmluZ1tdIGludGVyZmFjZXMsCi0JCQkgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQpIHsKLQlzdXBlcihjbGFzc05hbWUsIHN1cGVyQ2xhc3NOYW1lLCBmaWxlTmFtZSwKLQkgICAgICBhY2Nlc3NGbGFncywgaW50ZXJmYWNlcywgc3R5bGVzaGVldCk7Ci0JCi0JX2Fsb2FkVHJhbnNsZXQgPSBuZXcgQUxPQUQoVFJBTlNMRVRfSU5ERVgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBpbmRleCBvZiB0aGUgdHJhbnNsZXQgcG9pbnRlciB3aXRoaW4gdGhlIGV4ZWN1dGlvbiBvZgotICAgICAqIHRoZSB0ZXN0IG1ldGhvZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gbG9hZFRyYW5zbGV0KCkgewotCXJldHVybiBfYWxvYWRUcmFuc2xldDsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IHNpbmNlIHRoaXMgY2xhc3MgaXMgZXh0ZXJuYWwgdG8gdGhlCi0gICAgICogdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeHRlcm5hbCgpIHsKLQlyZXR1cm4gdHJ1ZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL0ludFR5cGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvSW50VHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZjFkMjNiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvSW50VHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuRmxvd0xpc3Q7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBJbnRUeXBlIGV4dGVuZHMgTnVtYmVyVHlwZSB7Ci0gICAgcHJvdGVjdGVkIEludFR5cGUoKSB7fQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gImludCI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotCXJldHVybiB0aGlzID09IG90aGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TaWduYXR1cmUoKSB7Ci0JcmV0dXJuICJJIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLQlyZXR1cm4gZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5JTlQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSNkaXN0YW5jZVRvCi0gICAgICovCi0gICAgcHVibGljIGludCBkaXN0YW5jZVRvKFR5cGUgdHlwZSkgewotCWlmICh0eXBlID09IHRoaXMpIHsKLQkgICAgcmV0dXJuIDA7Ci0JfQotCWVsc2UgaWYgKHR5cGUgPT0gVHlwZS5SZWFsKSB7Ci0JICAgIHJldHVybiAxOwotCX0KLQllbHNlCi0JICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBpbnRlZ2VyIGludG8gYW4gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIGZpbmFsIFR5cGUgdHlwZSkgewotCWlmICh0eXBlID09IFR5cGUuUmVhbCkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVhbFR5cGUpIHR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5pbnRlcm5hbEVycm9yKCk7IC8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGFuIGludGVnZXIgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSByZWFsLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWFsVHlwZSB0eXBlKSB7Ci0JbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChJMkQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gaW50ZWdlciBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBpdHMgc3RyaW5nIHZhbHVlIGJ5IGNhbGxpbmcKLSAgICAgKiA8Y29kZT5JbnRlZ2VyLnRvU3RyaW5nKGludCBpKTwvY29kZT4uCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFN0cmluZ1R5cGUgdHlwZSkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZihJTlRFR0VSX0NMQVNTLAotCQkJCQkJICAgICJ0b1N0cmluZyIsCi0JCQkJCQkgICAgIihJKSIgKyBTVFJJTkdfU0lHKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gaW50ZWdlciBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIDAgaWYgaXRzIHZhbHVlIGlzIDAgYW5kCi0gICAgICogYSAxIG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQm9vbGVhblR5cGUgdHlwZSkgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlmaW5hbCBCcmFuY2hIYW5kbGUgZmFsc2VjID0gaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKTsKLQlpbC5hcHBlbmQoSUNPTlNUXzEpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JZmFsc2VjLnNldFRhcmdldChpbC5hcHBlbmQoSUNPTlNUXzApKTsKLQl0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gaW50ZWdlciBvbiB0aGUgc3RhY2sgYW5kIHRyYW5zbGF0ZXMgaXQgdG8gYSBub24tc3ludGhlc2l6ZWQKLSAgICAgKiBib29sZWFuLiBJdCBkb2VzIG5vdCBwdXNoIGEgMCBvciBhIDEgYnV0IGluc3RlYWQgcmV0dXJucyBicmFuY2hoYW5kbGUgCi0gICAgICogbGlzdCB0byBiZSBhcHBlbmRlZCB0byB0aGUgZmFsc2UgbGlzdC4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkCi0gICAgICovCi0gICAgcHVibGljIEZsb3dMaXN0IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgCi0JCQkJCSAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkJCSAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlyZXR1cm4gbmV3IEZsb3dMaXN0KGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gaW50ZWdlciBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIGludGVnZXIuCi0gICAgICogQm94ZWQgaW50ZWdlcnMgYXJlIHJlcHJlc2VudGVkIGJ5IGFuIGluc3RhbmNlIG9mCi0gICAgICogPGNvZGU+amF2YS5sYW5nLkludGVnZXI8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWZlcmVuY2VUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhJTlRFR0VSX0NMQVNTKSkpOwotCWlsLmFwcGVuZChEVVBfWDEpOwotCWlsLmFwcGVuZChTV0FQKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoY3BnLmFkZE1ldGhvZHJlZihJTlRFR0VSX0NMQVNTLAotCQkJCQkJICAgICAiPGluaXQ+IiwgIihJKVYiKSkpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBpbnRlZ2VyIGludG8gdGhlIEphdmEgdHlwZSBkZW5vdGVkIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPi4gCi0gICAgICogRXhwZWN0cyBhbiBpbnRlZ2VyIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgbnVtYmVyIG9mIHRoZSBhcHByb3ByaWF0ZQotICAgICAqIHR5cGUgYWZ0ZXIgY29lcmNpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIENsYXNzIGNsYXp6KSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlmIChjbGF6eiA9PSBDaGFyYWN0ZXIuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoSTJDKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gQnl0ZS5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChJMkIpOwotCX0KLQllbHNlIGlmIChjbGF6eiA9PSBTaG9ydC5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChJMlMpOwotCX0KLQllbHNlIGlmIChjbGF6eiA9PSBJbnRlZ2VyLlRZUEUpIHsKLQkgICAgaWwuYXBwZW5kKE5PUCk7Ci0JfQotCWVsc2UgaWYgKGNsYXp6ID09IExvbmcuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoSTJMKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gRmxvYXQuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoSTJGKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gRG91YmxlLlRZUEUpIHsKLQkgICAgaWwuYXBwZW5kKEkyRCk7Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5pbnRlcm5hbEVycm9yKCk7IC8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIGJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQl0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyB1bmJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoSU5URUdFUl9DTEFTUykpKTsKLQlmaW5hbCBpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKElOVEVHRVJfQ0xBU1MsCi0JCQkJCSAgIElOVF9WQUxVRSwgCi0JCQkJCSAgIElOVF9WQUxVRV9TSUcpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBBREQoKSB7Ci0JcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklBREQ7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNVQigpIHsKLQlyZXR1cm4gSW5zdHJ1Y3Rpb25Db25zdGFudHMuSVNVQjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTVVMKCkgewotCXJldHVybiBJbnN0cnVjdGlvbkNvbnN0YW50cy5JTVVMOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBESVYoKSB7Ci0JcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLklESVY7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFJFTSgpIHsKLQlyZXR1cm4gSW5zdHJ1Y3Rpb25Db25zdGFudHMuSVJFTTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTkVHKCkgewotCXJldHVybiBJbnN0cnVjdGlvbkNvbnN0YW50cy5JTkVHOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0JcmV0dXJuIG5ldyBJTE9BRChzbG90KTsKLSAgICB9Ci0JCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0JcmV0dXJuIG5ldyBJU1RPUkUoc2xvdCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIEdUKGJvb2xlYW4gdG96ZXJvKSB7Ci0JcmV0dXJuIHRvemVybyA/IChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGR1QobnVsbCkgOiAKLQkgICAgKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZfSUNNUEdUKG51bGwpOwotICAgIH0KLQotICAgIHB1YmxpYyBCcmFuY2hJbnN0cnVjdGlvbiBHRShib29sZWFuIHRvemVybykgewotCXJldHVybiB0b3plcm8gPyAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRkdFKG51bGwpIDogCi0JICAgIChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGX0lDTVBHRShudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gTFQoYm9vbGVhbiB0b3plcm8pIHsKLQlyZXR1cm4gdG96ZXJvID8gKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZMVChudWxsKSA6IAotCSAgICAoQnJhbmNoSW5zdHJ1Y3Rpb24pIG5ldyBJRl9JQ01QTFQobnVsbCk7Ci0gICAgfQotCi0gICAgcHVibGljIEJyYW5jaEluc3RydWN0aW9uIExFKGJvb2xlYW4gdG96ZXJvKSB7Ci0JcmV0dXJuIHRvemVybyA/IChCcmFuY2hJbnN0cnVjdGlvbikgbmV3IElGTEUobnVsbCkgOiAKLQkgICAgKEJyYW5jaEluc3RydWN0aW9uKSBuZXcgSUZfSUNNUExFKG51bGwpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWF0Y2hHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWF0Y2hHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM3N2M2NC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL01hdGNoR2VuZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlRlbXBsYXRlOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgTWF0Y2hHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotICAgIHByaXZhdGUgc3RhdGljIGludCBDVVJSRU5UX0lOREVYID0gMTsKLQotICAgIHByaXZhdGUgaW50IF9pdGVyYXRvckluZGV4ID0gSU5WQUxJRF9JTkRFWDsKLQotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lsb2FkQ3VycmVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9pc3RvcmVDdXJyZW50OwotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb24gX2Fsb2FkRG9tOwotICAgIAotICAgIHB1YmxpYyBNYXRjaEdlbmVyYXRvcihpbnQgYWNjZXNzX2ZsYWdzLCBUeXBlIHJldHVybl90eXBlLCAKLQkJCSAgVHlwZVtdIGFyZ190eXBlcywgU3RyaW5nW10gYXJnX25hbWVzLCAKLQkJCSAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLQkJCSAgSW5zdHJ1Y3Rpb25MaXN0IGlsLCBDb25zdGFudFBvb2xHZW4gY3ApIHsKLQlzdXBlcihhY2Nlc3NfZmxhZ3MsIHJldHVybl90eXBlLCBhcmdfdHlwZXMsIGFyZ19uYW1lcywgbWV0aG9kX25hbWUsIAotCSAgICAgIGNsYXNzX25hbWUsIGlsLCBjcCk7Ci0JCi0JX2lsb2FkQ3VycmVudCA9IG5ldyBJTE9BRChDVVJSRU5UX0lOREVYKTsKLQlfaXN0b3JlQ3VycmVudCA9IG5ldyBJU1RPUkUoQ1VSUkVOVF9JTkRFWCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRDdXJyZW50Tm9kZSgpIHsKLQlyZXR1cm4gX2lsb2FkQ3VycmVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVDdXJyZW50Tm9kZSgpIHsKLQlyZXR1cm4gX2lzdG9yZUN1cnJlbnQ7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBpbnQgZ2V0SGFuZGxlckluZGV4KCkgewotCXJldHVybiBJTlZBTElEX0lOREVYOwkJLy8gbm90IGF2YWlsYWJsZQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBpbmRleCBvZiB0aGUgcmVnaXN0ZXIgd2hlcmUgdGhlIERPTSBpcyBzdG9yZWQuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRET00oKSB7Ci0JcmV0dXJuIF9hbG9hZERvbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgaW5kZXggd2hlcmUgdGhlIHJlZmVyZW5jZSB0byB0aGUgRE9NIGlzIHN0b3JlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb21JbmRleChpbnQgZG9tSW5kZXgpIHsKLQlfYWxvYWREb20gPSBuZXcgQUxPQUQoZG9tSW5kZXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBpbmRleCBvZiB0aGUgcmVnaXN0ZXIgd2hlcmUgdGhlIGN1cnJlbnQgaXRlcmF0b3IgaXMgc3RvcmVkLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0SXRlcmF0b3JJbmRleCgpIHsKLQlyZXR1cm4gX2l0ZXJhdG9ySW5kZXg7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IGluZGV4IG9mIHRoZSByZWdpc3RlciB3aGVyZSB0aGUgY3VycmVudCBpdGVyYXRvciBpcyBzdG9yZWQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0SXRlcmF0b3JJbmRleChpbnQgaXRlcmF0b3JJbmRleCkgewotCV9pdGVyYXRvckluZGV4ID0gaXRlcmF0b3JJbmRleDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLQlpZiAobmFtZS5lcXVhbHMoImN1cnJlbnQiKSkgewotCSAgICByZXR1cm4gQ1VSUkVOVF9JTkRFWDsKLQl9Ci0JcmV0dXJuIHN1cGVyLmdldExvY2FsSW5kZXgobmFtZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9NZXRob2RHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWV0aG9kR2VuZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNhM2Q3OTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9NZXRob2RHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMwMCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuVGVtcGxhdGU7Ci0KLXB1YmxpYyBjbGFzcyBNZXRob2RHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW4KLSAgICBpbXBsZW1lbnRzIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzIHsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBJTlZBTElEX0lOREVYICAgPSAtMTsKLSAgICAKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBUlRfRUxFTUVOVF9TSUcgICAKLQk9ICIoIiArIFNUUklOR19TSUcgKyAiKVYiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTkRfRUxFTUVOVF9TSUcgICAgIAotCT0gU1RBUlRfRUxFTUVOVF9TSUc7Ci0gICAgCi0gICAgcHJpdmF0ZSBJbnN0cnVjdGlvbkxpc3QgX21hcFR5cGVTdWI7Ci0JCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERPTV9JTkRFWCAgICAgICA9IDE7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElURVJBVE9SX0lOREVYICA9IDI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhBTkRMRVJfSU5ERVggICA9IDM7Ci0KLSAgICBwcml2YXRlIEluc3RydWN0aW9uICAgICAgIF9pbG9hZEN1cnJlbnQ7Ci0gICAgcHJpdmF0ZSBJbnN0cnVjdGlvbiAgICAgICBfaXN0b3JlQ3VycmVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hc3RvcmVIYW5kbGVyOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkSGFuZGxlcjsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hc3RvcmVJdGVyYXRvcjsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hbG9hZEl0ZXJhdG9yOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkRG9tOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2FzdG9yZURvbTsKLSAgICAKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9zdGFydEVsZW1lbnQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfZW5kRWxlbWVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9zdGFydERvY3VtZW50OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2VuZERvY3VtZW50OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2F0dHJpYnV0ZTsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9uYW1lc3BhY2U7Ci0KLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9zZXRTdGFydE5vZGU7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfbmV4dE5vZGU7Ci0KLSAgICBwcml2YXRlIFNsb3RBbGxvY2F0b3IgX3Nsb3RBbGxvY2F0b3I7Ci0gICAgCi0gICAgcHVibGljIE1ldGhvZEdlbmVyYXRvcihpbnQgYWNjZXNzX2ZsYWdzLCBUeXBlIHJldHVybl90eXBlLAotCQkJICAgVHlwZVtdIGFyZ190eXBlcywgU3RyaW5nW10gYXJnX25hbWVzLAotCQkJICAgU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLQkJCSAgIEluc3RydWN0aW9uTGlzdCBpbCwgQ29uc3RhbnRQb29sR2VuIGNwZykgewotCXN1cGVyKGFjY2Vzc19mbGFncywgcmV0dXJuX3R5cGUsIGFyZ190eXBlcywgYXJnX25hbWVzLCBtZXRob2RfbmFtZSwgCi0JICAgICAgY2xhc3NfbmFtZSwgaWwsIGNwZyk7Ci0JCi0JX2FzdG9yZUhhbmRsZXIgID0gbmV3IEFTVE9SRShIQU5ETEVSX0lOREVYKTsKLQlfYWxvYWRIYW5kbGVyICAgPSBuZXcgQUxPQUQoSEFORExFUl9JTkRFWCk7Ci0JX2FzdG9yZUl0ZXJhdG9yID0gbmV3IEFTVE9SRShJVEVSQVRPUl9JTkRFWCk7Ci0JX2Fsb2FkSXRlcmF0b3IgID0gbmV3IEFMT0FEKElURVJBVE9SX0lOREVYKTsKLQlfYWxvYWREb20gICAgICAgPSBuZXcgQUxPQUQoRE9NX0lOREVYKTsKLQlfYXN0b3JlRG9tICAgICAgPSBuZXcgQVNUT1JFKERPTV9JTkRFWCk7Ci0JCi0JZmluYWwgaW50IHN0YXJ0RWxlbWVudCA9Ci0JICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLQkJCQkgICAgICAic3RhcnRFbGVtZW50IiwKLQkJCQkgICAgICBTVEFSVF9FTEVNRU5UX1NJRyk7Ci0JX3N0YXJ0RWxlbWVudCA9IG5ldyBJTlZPS0VJTlRFUkZBQ0Uoc3RhcnRFbGVtZW50LCAyKTsKLQkKLQlmaW5hbCBpbnQgZW5kRWxlbWVudCA9Ci0JICAgIGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoVFJBTlNMRVRfT1VUUFVUX0lOVEVSRkFDRSwKLQkJCQkgICAgICAiZW5kRWxlbWVudCIsCi0JCQkJICAgICAgRU5EX0VMRU1FTlRfU0lHKTsKLQlfZW5kRWxlbWVudCA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UoZW5kRWxlbWVudCwgMik7Ci0KLQlmaW5hbCBpbnQgYXR0cmlidXRlID0KLQkgICAgY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotCQkJCSAgICAgICJhdHRyaWJ1dGUiLCAKLQkJCQkgICAgICAiKCIKLQkJCQkgICAgICArIFNUUklOR19TSUcKLQkJCQkgICAgICArIFNUUklOR19TSUcKLQkJCQkgICAgICArICIpViIpOwotCV9hdHRyaWJ1dGUgPSBuZXcgSU5WT0tFSU5URVJGQUNFKGF0dHJpYnV0ZSwgMyk7Ci0KLQlmaW5hbCBpbnQgbmFtZXNwYWNlID0KLQkgICAgY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotCQkJCSAgICAgICJuYW1lc3BhY2UiLCAKLQkJCQkgICAgICAiKCIKLQkJCQkgICAgICArIFNUUklOR19TSUcKLQkJCQkgICAgICArIFNUUklOR19TSUcKLQkJCQkgICAgICArICIpViIpOwotCV9uYW1lc3BhY2UgPSBuZXcgSU5WT0tFSU5URVJGQUNFKG5hbWVzcGFjZSwgMyk7Ci0JCi0JaW50IGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotCQkJCQkgICAgICAic3RhcnREb2N1bWVudCIsCi0JCQkJCSAgICAgICIoKVYiKTsKLQlfc3RhcnREb2N1bWVudCA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpOwotCQotCWluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLAotCQkJCQkgICJlbmREb2N1bWVudCIsCi0JCQkJCSAgIigpViIpOwotCV9lbmREb2N1bWVudCA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpOwotCQotCQotCWluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotCQkJCQkgIFNFVF9TVEFSVF9OT0RFLAotCQkJCQkgIFNFVF9TVEFSVF9OT0RFX1NJRyk7Ci0JX3NldFN0YXJ0Tm9kZSA9IG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpOwotCQotCWluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLCBORVhULCBORVhUX1NJRyk7Ci0JX25leHROb2RlID0gbmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMSk7Ci0JCi0JX3Nsb3RBbGxvY2F0b3IgPSBuZXcgU2xvdEFsbG9jYXRvcigpOwotCV9zbG90QWxsb2NhdG9yLmluaXRpYWxpemUoZ2V0TG9jYWxWYXJpYWJsZXMoKSk7Ci0gICAgfQotCi0gICAgcHVibGljIExvY2FsVmFyaWFibGVHZW4gYWRkTG9jYWxWYXJpYWJsZShTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLAotCQkJCQkgICAgIEluc3RydWN0aW9uSGFuZGxlIHN0YXJ0LAotCQkJCQkgICAgIEluc3RydWN0aW9uSGFuZGxlIGVuZCkgewotCQotCXJldHVybiBzdXBlci5hZGRMb2NhbFZhcmlhYmxlKG5hbWUsIHR5cGUsIHN0YXJ0LCBlbmQpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgTG9jYWxWYXJpYWJsZUdlbiBhZGRMb2NhbFZhcmlhYmxlMihTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLAotCQkJCQkgICAgICBJbnN0cnVjdGlvbkhhbmRsZSBzdGFydCkgewotCXJldHVybiBzdXBlci5hZGRMb2NhbFZhcmlhYmxlKG5hbWUsIHR5cGUsCi0JCQkJICAgICAgX3Nsb3RBbGxvY2F0b3IuYWxsb2NhdGVTbG90KHR5cGUpLAotCQkJCSAgICAgIHN0YXJ0LCBudWxsKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZW1vdmVMb2NhbFZhcmlhYmxlKExvY2FsVmFyaWFibGVHZW4gbHZnKSB7Ci0JX3Nsb3RBbGxvY2F0b3IucmVsZWFzZVNsb3QobHZnKTsKLQlzdXBlci5yZW1vdmVMb2NhbFZhcmlhYmxlKGx2Zyk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRET00oKSB7Ci0JcmV0dXJuIF9hbG9hZERvbTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVET00oKSB7Ci0JcmV0dXJuIF9hc3RvcmVEb207Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUhhbmRsZXIoKSB7Ci0JcmV0dXJuIF9hc3RvcmVIYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkSGFuZGxlcigpIHsKLQlyZXR1cm4gX2Fsb2FkSGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVJdGVyYXRvcigpIHsKLQlyZXR1cm4gX2FzdG9yZUl0ZXJhdG9yOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZEl0ZXJhdG9yKCkgewotCXJldHVybiBfYWxvYWRJdGVyYXRvcjsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIHNldFN0YXJ0Tm9kZSgpIHsKLQlyZXR1cm4gX3NldFN0YXJ0Tm9kZTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIG5leHROb2RlKCkgewotCXJldHVybiBfbmV4dE5vZGU7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBzdGFydEVsZW1lbnQoKSB7Ci0JcmV0dXJuIF9zdGFydEVsZW1lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGZpbmFsIEluc3RydWN0aW9uIGVuZEVsZW1lbnQoKSB7Ci0JcmV0dXJuIF9lbmRFbGVtZW50OwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBzdGFydERvY3VtZW50KCkgewotCXJldHVybiBfc3RhcnREb2N1bWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gZW5kRG9jdW1lbnQoKSB7Ci0JcmV0dXJuIF9lbmREb2N1bWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgSW5zdHJ1Y3Rpb24gYXR0cmlidXRlKCkgewotCXJldHVybiBfYXR0cmlidXRlOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBuYW1lc3BhY2UoKSB7Ci0JcmV0dXJuIF9uYW1lc3BhY2U7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRDdXJyZW50Tm9kZSgpIHsKLQlyZXR1cm4gX2lsb2FkQ3VycmVudCAhPSBudWxsCi0JICAgID8gX2lsb2FkQ3VycmVudAotCSAgICA6IChfaWxvYWRDdXJyZW50ID0gbmV3IElMT0FEKGdldExvY2FsSW5kZXgoImN1cnJlbnQiKSkpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUN1cnJlbnROb2RlKCkgewotCXJldHVybiBfaXN0b3JlQ3VycmVudCAhPSBudWxsCi0JICAgID8gX2lzdG9yZUN1cnJlbnQKLQkgICAgOiAoX2lzdG9yZUN1cnJlbnQgPSBuZXcgSVNUT1JFKGdldExvY2FsSW5kZXgoImN1cnJlbnQiKSkpOwotICAgIH0KLQotICAgIC8qKiBieSBkZWZhdWx0IGNvbnRleHQgbm9kZSBpcyB0aGUgc2FtZSBhcyBjdXJyZW50IG5vZGUuIE1LNDM3ICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRDb250ZXh0Tm9kZSgpIHsKLQlyZXR1cm4gbG9hZEN1cnJlbnROb2RlKCk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlQ29udGV4dE5vZGUoKSB7Ci0JcmV0dXJuIHN0b3JlQ3VycmVudE5vZGUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLQlyZXR1cm4gZ2V0TG9jYWxWYXJpYWJsZShuYW1lKS5nZXRJbmRleCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBMb2NhbFZhcmlhYmxlR2VuIGdldExvY2FsVmFyaWFibGUoU3RyaW5nIG5hbWUpIHsKLQlmaW5hbCBMb2NhbFZhcmlhYmxlR2VuW10gdmFycyA9IGdldExvY2FsVmFyaWFibGVzKCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCB2YXJzLmxlbmd0aDsgaSsrKQotCSAgICBpZiAodmFyc1tpXS5nZXROYW1lKCkuZXF1YWxzKG5hbWUpKQotCQlyZXR1cm4gdmFyc1tpXTsKLQlyZXR1cm4gbnVsbDsJCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWF4TG9jYWxzKCkgewotCQotCS8vIEdldCB0aGUgY3VycmVudCBudW1iZXIgb2YgbG9jYWwgdmFyaWFibGUgc2xvdHMKLQlpbnQgbWF4TG9jYWxzID0gc3VwZXIuZ2V0TWF4TG9jYWxzKCk7Ci0JaW50IHByZXZMb2NhbHMgPSBtYXhMb2NhbHM7Ci0KLQkvLyBHZXQgbnVtZXIgb2YgYWN0dWFsIHZhcmlhYmxlcwotCWZpbmFsIExvY2FsVmFyaWFibGVHZW5bXSBsb2NhbFZhcnMgPSBzdXBlci5nZXRMb2NhbFZhcmlhYmxlcygpOwotCWlmIChsb2NhbFZhcnMgIT0gbnVsbCkgewotCSAgICBpZiAobG9jYWxWYXJzLmxlbmd0aCA+IG1heExvY2FscykKLQkJbWF4TG9jYWxzID0gbG9jYWxWYXJzLmxlbmd0aDsKLQl9Ci0KLQkvLyBXZSB3YW50IGF0IGxlYXN0IDUgbG9jYWwgdmFyaWFibGUgc2xvdHMgKGZvciBwYXJhbWV0ZXJzKQotCWlmIChtYXhMb2NhbHMgPCA1KSBtYXhMb2NhbHMgPSA1OwotCi0Jc3VwZXIuc2V0TWF4TG9jYWxzKG1heExvY2Fscyk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL01ldGhvZFR5cGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWV0aG9kVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MmUyNWVmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTWV0aG9kVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgTWV0aG9kVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByaXZhdGUgZmluYWwgVHlwZSBfcmVzdWx0VHlwZTsJCi0gICAgcHJpdmF0ZSBmaW5hbCBWZWN0b3IgX2FyZ3NUeXBlOwotCQotICAgIHB1YmxpYyBNZXRob2RUeXBlKFR5cGUgcmVzdWx0VHlwZSkgewotCV9hcmdzVHlwZSA9IG51bGw7Ci0JX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBNZXRob2RUeXBlKFR5cGUgcmVzdWx0VHlwZSwgVHlwZSBhcmcxKSB7Ci0JaWYgKGFyZzEgIT0gVHlwZS5Wb2lkKSB7Ci0JICAgIF9hcmdzVHlwZSA9IG5ldyBWZWN0b3IoKTsKLQkgICAgX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMSk7Ci0JfQotCWVsc2UgewotCSAgICBfYXJnc1R5cGUgPSBudWxsOwotCX0KLQlfcmVzdWx0VHlwZSA9IHJlc3VsdFR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIE1ldGhvZFR5cGUoVHlwZSByZXN1bHRUeXBlLCBUeXBlIGFyZzEsIFR5cGUgYXJnMikgewotCV9hcmdzVHlwZSA9IG5ldyBWZWN0b3IoMik7Ci0JX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMSk7Ci0JX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMik7Ci0JX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBNZXRob2RUeXBlKFR5cGUgcmVzdWx0VHlwZSwgVHlwZSBhcmcxLCBUeXBlIGFyZzIsIFR5cGUgYXJnMykgewotCV9hcmdzVHlwZSA9IG5ldyBWZWN0b3IoMyk7Ci0JX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMSk7Ci0JX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMik7Ci0JX2FyZ3NUeXBlLmFkZEVsZW1lbnQoYXJnMyk7Ci0JX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBNZXRob2RUeXBlKFR5cGUgcmVzdWx0VHlwZSwgVmVjdG9yIGFyZ3NUeXBlKSB7Ci0JX3Jlc3VsdFR5cGUgPSByZXN1bHRUeXBlOwotCV9hcmdzVHlwZSA9IGFyZ3NUeXBlLnNpemUoKSA+IDAgPyBhcmdzVHlwZSA6IG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigibWV0aG9keyIpOwotCWlmIChfYXJnc1R5cGUgIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgY291bnQgPSBfYXJnc1R5cGUuc2l6ZSgpOwotCSAgICBmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgewotCQlyZXN1bHQuYXBwZW5kKF9hcmdzVHlwZS5lbGVtZW50QXQoaSkpOwotCQlpZiAoaSAhPSAoY291bnQtMSkpIHJlc3VsdC5hcHBlbmQoJywnKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgcmVzdWx0LmFwcGVuZCgidm9pZCIpOwotCX0KLQlyZXN1bHQuYXBwZW5kKCd9Jyk7Ci0JcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TaWduYXR1cmUoKSB7Ci0JcmV0dXJuIHRvU2lnbmF0dXJlKCIiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzaWduYXR1cmUgb2YgdGhpcyBtZXRob2QgdGhhdCByZXN1bHRzIGJ5IGFkZGluZwotICAgICAqIDxjb2RlPmxhc3RBcmdTaWc8L2NvZGU+IHRvIHRoZSBlbmQgb2YgdGhlIGFyZ3VtZW50IGxpc3QuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZShTdHJpbmcgbGFzdEFyZ1NpZykgewotCWZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0JYnVmZmVyLmFwcGVuZCgnKCcpOwotCWlmIChfYXJnc1R5cGUgIT0gbnVsbCkgewotCSAgICBmaW5hbCBpbnQgbiA9IF9hcmdzVHlwZS5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCWJ1ZmZlci5hcHBlbmQoKChUeXBlKV9hcmdzVHlwZS5lbGVtZW50QXQoaSkpLnRvU2lnbmF0dXJlKCkpOwotCSAgICB9Ci0JfQotCXJldHVybiBidWZmZXIKLQkgICAgLmFwcGVuZChsYXN0QXJnU2lnKQotCSAgICAuYXBwZW5kKCcpJykKLQkgICAgLmFwcGVuZChfcmVzdWx0VHlwZS50b1NpZ25hdHVyZSgpKQotCSAgICAudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLQlyZXR1cm4gbnVsbDsJLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLQlib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotCWlmIChvdGhlciBpbnN0YW5jZW9mIE1ldGhvZFR5cGUpIHsKLQkgICAgZmluYWwgTWV0aG9kVHlwZSB0ZW1wID0gKE1ldGhvZFR5cGUpIG90aGVyOwotCSAgICBpZiAoX3Jlc3VsdFR5cGUuaWRlbnRpY2FsVG8odGVtcC5fcmVzdWx0VHlwZSkpIHsKLQkJZmluYWwgaW50IGxlbiA9IGFyZ3NDb3VudCgpOwotCQlyZXN1bHQgPSBsZW4gPT0gdGVtcC5hcmdzQ291bnQoKTsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW4gJiYgcmVzdWx0OyBpKyspIHsKLQkJICAgIGZpbmFsIFR5cGUgYXJnMSA9IChUeXBlKV9hcmdzVHlwZS5lbGVtZW50QXQoaSk7Ci0JCSAgICBmaW5hbCBUeXBlIGFyZzIgPSAoVHlwZSl0ZW1wLl9hcmdzVHlwZS5lbGVtZW50QXQoaSk7Ci0JCSAgICByZXN1bHQgPSBhcmcxLmlkZW50aWNhbFRvKGFyZzIpOwotCQl9Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIHJlc3VsdDsJCi0gICAgfQotCQotICAgIHB1YmxpYyBpbnQgZGlzdGFuY2VUbyhUeXBlIG90aGVyKSB7Ci0JaW50IHJlc3VsdCA9IEludGVnZXIuTUFYX1ZBTFVFOwotCWlmIChvdGhlciBpbnN0YW5jZW9mIE1ldGhvZFR5cGUpIHsKLQkgICAgZmluYWwgTWV0aG9kVHlwZSBtdHlwZSA9IChNZXRob2RUeXBlKSBvdGhlcjsKLQkgICAgaWYgKF9hcmdzVHlwZSAhPSBudWxsKSB7Ci0JCWZpbmFsIGludCBsZW4gPSBfYXJnc1R5cGUuc2l6ZSgpOwotCQlpZiAobGVuID09IG10eXBlLl9hcmdzVHlwZS5zaXplKCkpIHsKLQkJICAgIHJlc3VsdCA9IDA7Ci0JCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0JCQlUeXBlIGFyZzEgPSAoVHlwZSkgX2FyZ3NUeXBlLmVsZW1lbnRBdChpKTsKLQkJCVR5cGUgYXJnMiA9IChUeXBlKSBtdHlwZS5fYXJnc1R5cGUuZWxlbWVudEF0KGkpOwotCQkJZmluYWwgaW50IHRlbXAgPSBhcmcxLmRpc3RhbmNlVG8oYXJnMik7Ci0JCQlpZiAodGVtcCA9PSBJbnRlZ2VyLk1BWF9WQUxVRSkgewotCQkJICAgIHJlc3VsdCA9IHRlbXA7ICAvLyByZXR1cm4gTUFYX1ZBTFVFCi0JCQkgICAgYnJlYWs7Ci0JCQl9Ci0JCQllbHNlIHsKLQkJCSAgICByZXN1bHQgKz0gYXJnMS5kaXN0YW5jZVRvKGFyZzIpOwotCQkJfQotCQkgICAgfQotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobXR5cGUuX2FyZ3NUeXBlID09IG51bGwpIHsKLQkJcmVzdWx0ID0gMDsgICAvLyBib3RoIG1ldGhvZHMgaGF2ZSBubyBhcmdzCi0JICAgIH0KLQl9Ci0JcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0JCQotICAgIHB1YmxpYyBUeXBlIHJlc3VsdFR5cGUoKSB7Ci0JcmV0dXJuIF9yZXN1bHRUeXBlOwotICAgIH0KLQkJCi0gICAgcHVibGljIFZlY3RvciBhcmdzVHlwZSgpIHsKLQlyZXR1cm4gX2FyZ3NUeXBlOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgYXJnc0NvdW50KCkgewotCXJldHVybiBfYXJnc1R5cGUgPT0gbnVsbCA/IDAgOiBfYXJnc1R5cGUuc2l6ZSgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTXVsdGlIYXNodGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTXVsdGlIYXNodGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzUwMzgyZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL011bHRpSGFzaHRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgTXVsdGlIYXNodGFibGUgZXh0ZW5kcyBIYXNodGFibGUgewotICAgIHB1YmxpYyBPYmplY3QgcHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgewotCVZlY3RvciB2ZWN0b3IgPSAoVmVjdG9yKWdldChrZXkpOwotCWlmICh2ZWN0b3IgPT0gbnVsbCkKLQkgICAgc3VwZXIucHV0KGtleSwgdmVjdG9yID0gbmV3IFZlY3RvcigpKTsKLQl2ZWN0b3IuYWRkKHZhbHVlKTsKLQlyZXR1cm4gdmVjdG9yOwotICAgIH0KLQkKLSAgICBwdWJsaWMgYm9vbGVhbiBtYXBzKE9iamVjdCBmcm9tLCBPYmplY3QgdG8pIHsKLQlpZiAoZnJvbSA9PSBudWxsKSByZXR1cm4gZmFsc2U7Ci0JZmluYWwgVmVjdG9yIHZlY3RvciA9IChWZWN0b3IpIGdldChmcm9tKTsKLQlpZiAodmVjdG9yICE9IG51bGwpIHsKLQkgICAgZmluYWwgaW50IG4gPSB2ZWN0b3Iuc2l6ZSgpOwotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewotCQlpZiAodmVjdG9yLmVsZW1lbnRBdChpKS5lcXVhbHModG8pKSB7Ci0JCSAgICByZXR1cm4gdHJ1ZTsKLQkJfQotCSAgICB9Ci0JfQotCXJldHVybiBmYWxzZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL05hbWVkTWV0aG9kR2VuZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL05hbWVkTWV0aG9kR2VuZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU3Y2Q3MDMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9OYW1lZE1ldGhvZEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuVGVtcGxhdGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB1c2VkIGZvciBuYW1lZCB0ZW1wbGF0ZXMuIE5hbWVkIHRlbXBsYXRlIG1ldGhvZHMgaGF2ZSBhY2Nlc3MKLSAqIHRvIHRoZSBET00sIHRoZSBjdXJyZW50IGl0ZXJhdG9yLCB0aGUgaGFuZGxlciBhbmQgdGhlIGN1cnJlbnQgbm9kZS4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE5hbWVkTWV0aG9kR2VuZXJhdG9yIGV4dGVuZHMgTWV0aG9kR2VuZXJhdG9yIHsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBDVVJSRU5UX0lOREVYICA9IDQ7Ci0KLSAgICBwdWJsaWMgTmFtZWRNZXRob2RHZW5lcmF0b3IoaW50IGFjY2Vzc19mbGFncywgVHlwZSByZXR1cm5fdHlwZSwKLQkJCQlUeXBlW10gYXJnX3R5cGVzLCBTdHJpbmdbXSBhcmdfbmFtZXMsCi0JCQkJU3RyaW5nIG1ldGhvZF9uYW1lLCBTdHJpbmcgY2xhc3NfbmFtZSwKLQkJCQlJbnN0cnVjdGlvbkxpc3QgaWwsIENvbnN0YW50UG9vbEdlbiBjcCkgewotCXN1cGVyKGFjY2Vzc19mbGFncywgcmV0dXJuX3R5cGUsIGFyZ190eXBlcywgYXJnX25hbWVzLCBtZXRob2RfbmFtZSwgCi0JICAgICAgY2xhc3NfbmFtZSwgaWwsIGNwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLQlpZiAobmFtZS5lcXVhbHMoImN1cnJlbnQiKSkgewotCSAgICByZXR1cm4gQ1VSUkVOVF9JTkRFWDsKLQl9Ci0JcmV0dXJuIHN1cGVyLmdldExvY2FsSW5kZXgobmFtZSk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlQ291bnRlckdlbmVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlQ291bnRlckdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2Y2Q5ZWMyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZUNvdW50ZXJHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExMiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlN0eWxlc2hlZXQ7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGF1eGlsaWFyeSBjbGFzc2VzIG5lZWRlZCB0byBjb21waWxlIAotICogcGF0dGVybnMgaW4gPHR0PnhzbDpudW1iZXI8L3R0Pi4gVGhlc2UgY2xhc3NlcyBpbmhlcml0IGZyb20KLSAqIHtBbnksU2luZ2xlLE11bHRpcGxlfU5vZGVDb3VudGVyIGFuZCBvdmVycmlkZSB0aGUgCi0gKiA8dHQ+bWF0Y2hGcm9tPC90dD4gYW5kIDx0dD5tYXRjaENvdW50PC90dD4gbWV0aG9kcy4KLSAqLwotcHVibGljIGZpbmFsIGNsYXNzIE5vZGVDb3VudGVyR2VuZXJhdG9yIGV4dGVuZHMgQ2xhc3NHZW5lcmF0b3IgewotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb24gX2Fsb2FkVHJhbnNsZXQ7Ci0KLSAgICBwdWJsaWMgTm9kZUNvdW50ZXJHZW5lcmF0b3IoU3RyaW5nIGNsYXNzTmFtZSwgCi0JCQkJU3RyaW5nIHN1cGVyQ2xhc3NOYW1lLAotCQkJICAgICAgICBTdHJpbmcgZmlsZU5hbWUsCi0JCQkgICAgICAgIGludCBhY2Nlc3NGbGFncywgCi0JCQkJU3RyaW5nW10gaW50ZXJmYWNlcywKLQkJCSAgICAgICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0KSB7Ci0Jc3VwZXIoY2xhc3NOYW1lLCBzdXBlckNsYXNzTmFtZSwgZmlsZU5hbWUsCi0JICAgICAgYWNjZXNzRmxhZ3MsIGludGVyZmFjZXMsIHN0eWxlc2hlZXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgaW5kZXggb2YgdGhlIHJlZ2lzdGVyIHdoZXJlICJ0aGlzIiAodGhlIHBvaW50ZXIgdG8KLSAgICAgKiB0aGUgdHJhbnNsZXQpIGlzIHN0b3JlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRUcmFuc2xldEluZGV4KGludCBpbmRleCkgewotCV9hbG9hZFRyYW5zbGV0ID0gbmV3IEFMT0FEKGluZGV4KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgaW5kZXggb2YgdGhlIHRyYW5zbGV0IHBvaW50ZXIgd2l0aGluIHRoZSBleGVjdXRpb24gb2YKLSAgICAgKiBtYXRjaEZyb20gb3IgbWF0Y2hDb3VudC4KLSAgICAgKiBPdmVycmlkZGVuIGZyb20gQ2xhc3NHZW5lcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGFsb2FkVHJhbnNsZXQoKSB7Ci0JcmV0dXJuIF9hbG9hZFRyYW5zbGV0OwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gc2luY2UgdGhpcyBjbGFzcyBpcyBleHRlcm5hbCB0byB0aGUKLSAgICAgKiB0cmFuc2xldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVybmFsKCkgewotCXJldHVybiB0cnVlOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVNldFR5cGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVNldFR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTFiYTk0Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL05vZGVTZXRUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyOTYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5QYXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5GbG93TGlzdDsKLQotcHVibGljIGZpbmFsIGNsYXNzIE5vZGVTZXRUeXBlIGV4dGVuZHMgVHlwZSB7Ci0gICAgcHJvdGVjdGVkIE5vZGVTZXRUeXBlKCkge30KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJub2RlLXNldCI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotCXJldHVybiB0aGlzID09IG90aGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TaWduYXR1cmUoKSB7Ci0JcmV0dXJuIE5PREVfSVRFUkFUT1JfU0lHOwotICAgIH0KLQotICAgIHB1YmxpYyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotCXJldHVybiBuZXcgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuT2JqZWN0VHlwZShOT0RFX0lURVJBVE9SKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZS1zZXQgaW50byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZQotICAgICAqIDxjb2RlPnR5cGU8L2NvZGU+LiBUaGUgdHJhbnNsYXRpb24gdG8gaW50IGlzIHVuZGVmaW5lZAotICAgICAqIHNpbmNlIG5vZGUtc2V0cyBhcmUgYWx3YXlzIGNvbnZlcnRlZCB0bwotICAgICAqIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFR5cGUgdHlwZSkgewotCWlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlYWxUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLk5vZGUpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKE5vZGVUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5pbnRlcm5hbEVycm9yKCk7IC8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZS1zZXQgaW50byBhIHN5bnRoZXNpemVkIGJvb2xlYW4uCi0gICAgICogVGhlIGJvb2xlYW4gdmFsdWUgb2YgYSBub2RlLXNldCBpcyAidHJ1ZSIgaWYgbm9uLWVtcHR5Ci0gICAgICogYW5kICJmYWxzZSIgb3RoZXJ3aXNlLiBOb3RpY2UgdGhhdCB0aGUgCi0gICAgICogZnVuY3Rpb24gZ2V0Rmlyc3ROb2RlKCkgaXMgY2FsbGVkIGluIHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZCgpLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCUZsb3dMaXN0IGZhbHNlbCA9IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuLCB0eXBlKTsKLQlpbC5hcHBlbmQoSUNPTlNUXzEpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JZmFsc2VsLmJhY2tQYXRjaChpbC5hcHBlbmQoSUNPTlNUXzApKTsKLQl0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBub2RlLXNldCBpbnRvIGEgc3RyaW5nLiBUaGUgc3RyaW5nIHZhbHVlIG9mIGEgbm9kZS1zZXQgaXMKLSAgICAgKiB2YWx1ZSBvZiBpdHMgZmlyc3QgZWxlbWVudC4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgU3RyaW5nVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWdldEZpcnN0Tm9kZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlpbC5hcHBlbmQoRFVQKTsKLQlmaW5hbCBCcmFuY2hIYW5kbGUgZmFsc2VjID0gaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKTsKLQlUeXBlLk5vZGUudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0JZmluYWwgQnJhbmNoSGFuZGxlIHRydWVjID0gaWwuYXBwZW5kKG5ldyBHT1RPKG51bGwpKTsKLQlmYWxzZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChQT1ApKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCksICIiKSk7Ci0JdHJ1ZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgbm9kZS1zZXQgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSByZWFsLgotICAgICAqIEZpcnN0IHRoZSBub2RlLXNldCBpcyBjb252ZXJ0ZWQgdG8gc3RyaW5nLCBhbmQgZnJvbSBzdHJpbmcgdG8gcmVhbC4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgUmVhbFR5cGUgdHlwZSkgewotCXRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuU3RyaW5nKTsKLQlUeXBlLlN0cmluZy50cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlYWwpOwkKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgbm9kZS1zZXQgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBub2RlLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBOb2RlVHlwZSB0eXBlKSB7Ci0JZ2V0Rmlyc3ROb2RlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBub2RlLXNldCBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uIEl0IGRvZXMgbm90IAotICAgICAqIHB1c2ggYSAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlIGFwcGVuZGVkIAotICAgICAqIHRvIHRoZSBmYWxzZSBsaXN0LgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCAKLQkJCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCQkJICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWdldEZpcnN0Tm9kZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLQlyZXR1cm4gbmV3IEZsb3dMaXN0KGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSBub2RlLXNldCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIG5vZGUtc2V0LgotICAgICAqIE5vZGUgc2V0cyBhcmUgYWxyZWFkeSBib3hlZCBzbyB0aGUgdHJhbnNsYXRpb24gaXMganVzdCBhIE5PUC4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0JbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChOT1ApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBub2RlLXNldCBpbnRvIHRoZSBKYXZhIHR5cGUgZGVub3RlZCBieSA8Y29kZT5jbGF6ejwvY29kZT4uIAotICAgICAqIEV4cGVjdHMgYSBub2RlLXNldCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhbiBvYmplY3Qgb2YgdGhlIGFwcHJvcHJpYXRlCi0gICAgICogdHlwZSBhZnRlciBjb2VyY2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQ2xhc3MgY2xhenopIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWZpbmFsIFN0cmluZyBjbGFzc05hbWUgPSBjbGF6ei5nZXROYW1lKCk7Ci0KLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JaWwuYXBwZW5kKFNXQVApOwotCi0JaWYgKGNsYXNzTmFtZS5lcXVhbHMoIm9yZy53M2MuZG9tLk5vZGUiKSkgewotCSAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICBNQUtFX05PREUsCi0JCQkJCQkgIE1BS0VfTk9ERV9TSUcyKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQl9Ci0JZWxzZSBpZiAoY2xhc3NOYW1lLmVxdWFscygib3JnLnczYy5kb20uTm9kZUxpc3QiKSkgewotCSAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICBNQUtFX05PREVfTElTVCwKLQkJCQkJCSAgTUFLRV9OT0RFX0xJU1RfU0lHMik7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFSU5URVJGQUNFKGluZGV4LCAyKSk7Ci0JfQotCWVsc2UgaWYgKGNsYXNzTmFtZS5lcXVhbHMoImludCIpKSB7Ci0JICAgIGludCBuZXh0ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotCQkJCQkJICAibmV4dCIsICIoKUkiKTsKLQkgICAgaW50IGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgR0VUX05PREVfVkFMVUUsCi0JCQkJCQkgICIoSSkiK1NUUklOR19TSUcpOwotCSAgICBpbnQgc3RyID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotCQkJCQlTVFJJTkdfVE9fSU5ULAotCQkJCQlTVFJJTkdfVE9fSU5UX1NJRyk7Ci0KLQkgICAgLy8gR2V0IG5leHQgbm9kZSBmcm9tIHRoZSBpdGVyYXRvcgotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShuZXh0LCAxKSk7Ci0JICAgIC8vIEdldCB0aGUgbm9kZSdzIHN0cmluZyB2YWx1ZSAoZnJvbSB0aGUgRE9NKQotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMikpOwotCSAgICAvLyBDcmVhdGUgYSBuZXcgSW50ZWdlciBvYmplY3QgZnJvbSB0aGUgc3RyaW5nIHZhbHVlCi0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHN0cikpOwotCX0KLQllbHNlIHsKLQkgICAgY2xhc3NHZW4uZ2V0UGFyc2VyKCkuaW50ZXJuYWxFcnJvcigpOyAvLyB1bmRlZmluZWQKLQl9Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIFNvbWUgdHlwZSBjb252ZXJzaW9ucyByZXF1aXJlIGdldHR0aW5nIHRoZSBmaXJzdCBub2RlIGZyb20gdGhlIG5vZGUtc2V0LgotICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgZGVmaW5lZCB0byBhdm9pZCBjb2RlIHJlcGV0aXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGdldEZpcnN0Tm9kZShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihOT0RFX0lURVJBVE9SLAotCQkJCQkJCQlORVhULAotCQkJCQkJCQlORVhUX1NJRyksIDEpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIGJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQl0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyB1bmJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChOT1ApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGNsYXNzIG5hbWUgb2YgYW4gaW50ZXJuYWwgdHlwZSdzIGV4dGVybmFsIHJlcHJlc2VudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgewotCXJldHVybihOT0RFX0lURVJBVE9SKTsKLSAgICB9Ci0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0JcmV0dXJuIG5ldyBBTE9BRChzbG90KTsKLSAgICB9Ci0JCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNUT1JFKGludCBzbG90KSB7Ci0JcmV0dXJuIG5ldyBBU1RPUkUoc2xvdCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlU29ydFJlY29yZEdlbmVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Ob2RlU29ydFJlY29yZEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlODgyMWZlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5TdHlsZXNoZWV0OwotCi0vKioKLSAqCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBOb2RlU29ydFJlY29yZEdlbmVyYXRvciBleHRlbmRzIENsYXNzR2VuZXJhdG9yIHsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFJBTlNMRVRfSU5ERVggPSA0OyAgIC8vIHRyYW5zbGV0Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfYWxvYWRUcmFuc2xldDsKLQotICAgIHB1YmxpYyBOb2RlU29ydFJlY29yZEdlbmVyYXRvcihTdHJpbmcgY2xhc3NOYW1lLCBTdHJpbmcgc3VwZXJDbGFzc05hbWUsCi0JCQkJICAgU3RyaW5nIGZpbGVOYW1lLAotCQkJCSAgIGludCBhY2Nlc3NGbGFncywgU3RyaW5nW10gaW50ZXJmYWNlcywKLQkJCQkgICBTdHlsZXNoZWV0IHN0eWxlc2hlZXQpIHsKLQlzdXBlcihjbGFzc05hbWUsIHN1cGVyQ2xhc3NOYW1lLCBmaWxlTmFtZSwKLQkgICAgICBhY2Nlc3NGbGFncywgaW50ZXJmYWNlcywgc3R5bGVzaGVldCk7Ci0JX2Fsb2FkVHJhbnNsZXQgPSBuZXcgQUxPQUQoVFJBTlNMRVRfSU5ERVgpOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBUaGUgaW5kZXggb2YgdGhlIHRyYW5zbGV0IHBvaW50ZXIgd2l0aGluIHRoZSBleGVjdXRpb24gb2YKLSAgICAgKiB0aGUgdGVzdCBtZXRob2QuCi0gICAgICovCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRUcmFuc2xldCgpIHsKLQlyZXR1cm4gX2Fsb2FkVHJhbnNsZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IHNpbmNlIHRoaXMgY2xhc3MgaXMgZXh0ZXJuYWwgdG8gdGhlCi0gICAgICogdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFeHRlcm5hbCgpIHsKLQlyZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVR5cGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTm9kZVR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDM2ZGE4Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL05vZGVUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlOwotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5QYXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgTm9kZVR5cGUgZXh0ZW5kcyBUeXBlIHsKLSAgICBwcml2YXRlIGZpbmFsIGludCBfdHlwZTsKLQotICAgIHByb3RlY3RlZCBOb2RlVHlwZSgpIHsKLQl0aGlzKE5vZGVUZXN0LkFOT0RFKTsKLSAgICB9Ci0KLSAgICBwcm90ZWN0ZWQgTm9kZVR5cGUoaW50IHR5cGUpIHsKLQlfdHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRUeXBlKCkgewotCXJldHVybiBfdHlwZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAibm9kZS10eXBlIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZGVudGljYWxUbyhUeXBlIG90aGVyKSB7Ci0JcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgTm9kZVR5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKLQlyZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1NpZ25hdHVyZSgpIHsKLQlyZXR1cm4gIkkiOwotICAgIH0KLQotICAgIHB1YmxpYyBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlIHRvSkNUeXBlKCkgewotCXJldHVybiBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy5UeXBlLklOVDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZSBpbnRvIGFuIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqIFRoZSB0cmFuc2xhdGlvbiB0byBpbnQgaXMgdW5kZWZpbmVkIHNpbmNlIG5vZGVzIGFyZSBhbHdheXMgY29udmVydGVkCi0gICAgICogdG8gcmVhbHMgaW4gYXJpdGhtZXRpYyBleHByZXNzaW9ucy4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgVHlwZSB0eXBlKSB7Ci0JaWYgKHR5cGUgPT0gVHlwZS5TdHJpbmcpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFN0cmluZ1R5cGUpIHR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoQm9vbGVhblR5cGUpIHR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuUmVhbCkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVhbFR5cGUpIHR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuTm9kZVNldCkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoTm9kZVNldFR5cGUpIHR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuUmVmZXJlbmNlKSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChSZWZlcmVuY2VUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsgLy8gdW5kZWZpbmVkCi0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSBub2RlIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGl0cyBzdHJpbmcgdmFsdWUuIAotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBTdHJpbmdUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0Jc3dpdGNoIChfdHlwZSkgewotCWNhc2UgTm9kZVRlc3QuUk9PVDoKLQljYXNlIE5vZGVUZXN0LkVMRU1FTlQ6Ci0JICAgIGlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQkgICAgaWwuYXBwZW5kKFNXQVApOyAvLyBkb20gcmVmIG11c3QgYmUgYmVsb3cgbm9kZSBpbmRleAotCSAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICBHRVRfRUxFTUVOVF9WQUxVRSwKLQkJCQkJCSAgR0VUX0VMRU1FTlRfVkFMVUVfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQkgICAgYnJlYWs7Ci0KLQljYXNlIE5vZGVUZXN0LkFOT0RFOgotCWNhc2UgTm9kZVRlc3QuQ09NTUVOVDoKLQljYXNlIE5vZGVUZXN0LkFUVFJJQlVURToKLQljYXNlIE5vZGVUZXN0LlBJOgotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JICAgIGlsLmFwcGVuZChTV0FQKTsgLy8gZG9tIHJlZiBtdXN0IGJlIGJlbG93IG5vZGUgaW5kZXgKLQkgICAgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkgICAgICBHRVRfTk9ERV9WQUxVRSwKLQkJCQkJICAgICAgR0VUX05PREVfVkFMVUVfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQkgICAgYnJlYWs7Ci0JICAgIAotCWRlZmF1bHQ6Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsKLQkgICAgYnJlYWs7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBub2RlIGludG8gYSBzeW50aGVzaXplZCBib29sZWFuLgotICAgICAqIElmIHRoZSBleHByZXNzaW9uIGlzICJAYXR0ciIsIAotICAgICAqIHRoZW4gInRydWUiIGlzIHB1c2hlZCBpZmYgImF0dHIiIGlzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgICAqIElmIHRoZSBleHByZXNzaW9uIGlzICIuIiwgdGhlIHJlc3VsdCBpcyBhbHdheXMgInRydWUiLgkKLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQm9vbGVhblR5cGUgdHlwZSkgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlGbG93TGlzdCBmYWxzZWwgPSB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0JaWwuYXBwZW5kKElDT05TVF8xKTsKLQlmaW5hbCBCcmFuY2hIYW5kbGUgdHJ1ZWMgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCWZhbHNlbC5iYWNrUGF0Y2goaWwuYXBwZW5kKElDT05TVF8wKSk7Ci0JdHJ1ZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgbm9kZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHJlYWwuCi0gICAgICogRmlyc3QgdGhlIG5vZGUgaXMgY29udmVydGVkIHRvIHN0cmluZywgYW5kIGZyb20gc3RyaW5nIHRvIHJlYWwuCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFJlYWxUeXBlIHR5cGUpIHsKLQl0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlN0cmluZyk7Ci0JVHlwZS5TdHJpbmcudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWFsKTsJCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIG5vZGUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBzaW5nbGV0b24gbm9kZS1zZXQuIFNpbmdsZXRvbgotICAgICAqIGl0ZXJhdG9ycyBhcmUgYWxyZWFkeSBzdGFydGVkIGFmdGVyIGNvbnN0cnVjdGlvbi4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgTm9kZVNldFR5cGUgdHlwZSkgewotCUNvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgU2luZ2xldG9uSXRlcmF0b3IKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoU0lOR0xFVE9OX0lURVJBVE9SKSkpOwotCWlsLmFwcGVuZChEVVBfWDEpOwotCWlsLmFwcGVuZChTV0FQKTsKLQlmaW5hbCBpbnQgaW5pdCA9IGNwZy5hZGRNZXRob2RyZWYoU0lOR0xFVE9OX0lURVJBVE9SLCAiPGluaXQ+IiwKLQkJCQkJICAiKCIgKyBOT0RFX1NJRyArIilWIik7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluaXQpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgbm9kZSBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uIEl0IGRvZXMgbm90IHB1c2ggYSAKLSAgICAgKiAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlIGFwcGVuZGVkIHRvIHRoZSAKLSAgICAgKiBmYWxzZSBsaXN0LgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCAKLQkJCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCQkJICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCXJldHVybiBuZXcgRmxvd0xpc3QoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIG5vZGUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBib3hlZCBub2RlLiBCb3hlZCBub2RlcwotICAgICAqIGFyZSByZXByZXNlbnRlZCBieSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5vcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5Ob2RlPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgUmVmZXJlbmNlVHlwZSB0eXBlKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoUlVOVElNRV9OT0RFX0NMQVNTKSkpOwotCWlsLmFwcGVuZChEVVBfWDEpOwotCWlsLmFwcGVuZChTV0FQKTsKLQlpbC5hcHBlbmQobmV3IFBVU0goY3BnLCBfdHlwZSkpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1BFQ0lBTChjcGcuYWRkTWV0aG9kcmVmKFJVTlRJTUVfTk9ERV9DTEFTUywKLQkJCQkJCSAgICAgIjxpbml0PiIsICIoSUkpViIpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIG5vZGUgaW50byB0aGUgSmF2YSB0eXBlIGRlbm90ZWQgYnkgPGNvZGU+Y2xheno8L2NvZGU+LiAKLSAgICAgKiBFeHBlY3RzIGEgbm9kZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhbiBvYmplY3Qgb2YgdGhlIGFwcHJvcHJpYXRlCi0gICAgICogdHlwZSBhZnRlciBjb2VyY2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQ2xhc3MgY2xhenopIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaWwuYXBwZW5kKG1ldGhvZEdlbi5sb2FkRE9NKCkpOwotCWlsLmFwcGVuZChTV0FQKTsJCS8vIGRvbSByZWYgbXVzdCBiZSBiZWxvdyBub2RlIGluZGV4Ci0KLQlTdHJpbmcgY2xhc3NOYW1lID0gY2xhenouZ2V0TmFtZSgpOwotCWlmIChjbGFzc05hbWUuZXF1YWxzKCJvcmcudzNjLmRvbS5Ob2RlIikpIHsKLQkgICAgaW50IGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgTUFLRV9OT0RFLAotCQkJCQkJICBNQUtFX05PREVfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQl9Ci0JZWxzZSBpZiAoY2xhc3NOYW1lLmVxdWFscygib3JnLnczYy5kb20uTm9kZUxpc3QiKSkgewotCSAgICBpbnQgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICBNQUtFX05PREVfTElTVCwKLQkJCQkJCSAgTUFLRV9OT0RFX0xJU1RfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDIpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKFJVTlRJTUVfTk9ERV9DTEFTUykpKTsKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihSVU5USU1FX05PREVfQ0xBU1MsCi0JCQkJCSAgICAgICBOT0RFX0ZJRUxELAotCQkJCQkgICAgICAgTk9ERV9GSUVMRF9TSUcpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY2xhc3MgbmFtZSBvZiBhbiBpbnRlcm5hbCB0eXBlJ3MgZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0JcmV0dXJuKFJVTlRJTUVfTk9ERV9DTEFTUyk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IElMT0FEKHNsb3QpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IElTVE9SRShzbG90KTsKLSAgICB9Ci19Ci0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvTnVtYmVyVHlwZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9OdW1iZXJUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM5OGJmNjAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9OdW1iZXJUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBOdW1iZXJUeXBlIGV4dGVuZHMgVHlwZSB7Ci0gICAgcHVibGljIGJvb2xlYW4gaXNOdW1iZXIoKSB7Ci0JcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaXNTaW1wbGUoKSB7Ci0JcmV0dXJuIHRydWU7Ci0gICAgfQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1JlYWxUeXBlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1JlYWxUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGRjMTc4YzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9SZWFsVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzU2ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuRmxvd0xpc3Q7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBSZWFsVHlwZSBleHRlbmRzIE51bWJlclR5cGUgewotICAgIHByb3RlY3RlZCBSZWFsVHlwZSgpIHt9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiAicmVhbCI7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaWRlbnRpY2FsVG8oVHlwZSBvdGhlcikgewotCXJldHVybiB0aGlzID09IG90aGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TaWduYXR1cmUoKSB7Ci0JcmV0dXJuICJEIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLQlyZXR1cm4gZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5ET1VCTEU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSNkaXN0YW5jZVRvCi0gICAgICovCi0gICAgcHVibGljIGludCBkaXN0YW5jZVRvKFR5cGUgdHlwZSkgewotCWlmICh0eXBlID09IHRoaXMpIHsKLQkgICAgcmV0dXJuIDA7Ci0JfQotCWVsc2UgaWYgKHR5cGUgPT0gVHlwZS5JbnQpIHsKLQkgICAgcmV0dXJuIDE7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4gSW50ZWdlci5NQVhfVkFMVUU7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZWFsIGludG8gYW4gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uIFRoZQotICAgICAqIHRyYW5zbGF0aW9uIHRvIGludCBpcyB1bmRlZmluZWQgc2luY2UgcmVhbHMgYXJlIG5ldmVyIGNvbnZlcnRlZCB0byBpbnRzLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBUeXBlIHR5cGUpIHsKLQlpZiAodHlwZSA9PSBUeXBlLlN0cmluZykgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoU3RyaW5nVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgaWYgKHR5cGUgPT0gVHlwZS5Cb29sZWFuKSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChCb29sZWFuVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgaWYgKHR5cGUgPT0gVHlwZS5SZWZlcmVuY2UpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlZmVyZW5jZVR5cGUpIHR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuSW50KSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChJbnRUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsJCS8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgcmVhbCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBpdHMgc3RyaW5nIHZhbHVlIGJ5IGNhbGxpbmcKLSAgICAgKiA8Y29kZT5Eb3VibGUudG9TdHJpbmcoZG91YmxlIGQpPC9jb2RlPi4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgU3RyaW5nVHlwZSB0eXBlKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCQkgICAgInJlYWxUb1N0cmluZyIsCi0JCQkJCQkgICAgIihEKSIgKyBTVFJJTkdfU0lHKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSByZWFsIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgMCBpZiB0aGF0IG51bWJlciBpcyAwLjAgYW5kCi0gICAgICogYSAxIG90aGVyd2lzZS4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQm9vbGVhblR5cGUgdHlwZSkgewotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQlGbG93TGlzdCBmYWxzZWwgPSB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0JaWwuYXBwZW5kKElDT05TVF8xKTsKLQlmaW5hbCBCcmFuY2hIYW5kbGUgdHJ1ZWMgPSBpbC5hcHBlbmQobmV3IEdPVE8obnVsbCkpOwotCWZhbHNlbC5iYWNrUGF0Y2goaWwuYXBwZW5kKElDT05TVF8wKSk7Ci0JdHJ1ZWMuc2V0VGFyZ2V0KGlsLmFwcGVuZChOT1ApKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgcmVhbCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHRydW5jYXRlZCBpbnRlZ2VyIHZhbHVlCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIEludFR5cGUgdHlwZSkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTVEFUSUMoY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLAotCQkJCQkJICAgICJyZWFsVG9JbnQiLCIoRClJIikpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgcmVhbCBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uIEl0IGRvZXMgbm90IHB1c2ggYSAKLSAgICAgKiAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlIGFwcGVuZGVkIHRvIHRoZSAKLSAgICAgKiBmYWxzZSBsaXN0LiBBIE5hTiBtdXN0IGJlIGNvbnZlcnRlZCB0byAiZmFsc2UiLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCAKLQkJCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCQkJICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JTG9jYWxWYXJpYWJsZUdlbiBsb2NhbDsKLQlmaW5hbCBGbG93TGlzdCBmbG93bGlzdCA9IG5ldyBGbG93TGlzdCgpOwotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQkvLyBTdG9yZSByZWFsIGludG8gYSBsb2NhbCB2YXJpYWJsZQotCWlsLmFwcGVuZChEVVAyKTsKLQlsb2NhbCA9IG1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJyZWFsX3RvX2Jvb2xlYW5fdG1wIiwgCi0JCQkJCSAgIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUuRE9VQkxFLAotCQkJCQkgICBpbC5nZXRFbmQoKSwgbnVsbCk7Ci0JaWwuYXBwZW5kKG5ldyBEU1RPUkUobG9jYWwuZ2V0SW5kZXgoKSkpOwotCi0JLy8gQ29tcGFyZSBpdCB0byAwLjAKLQlpbC5hcHBlbmQoRENPTlNUXzApOwotCWlsLmFwcGVuZChEQ01QRyk7Ci0JZmxvd2xpc3QuYWRkKGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotCi0JLy8hISEgY2FsbCBpc05hTgotCS8vIENvbXBhcmUgaXQgdG8gaXRzZWxmIHRvIHNlZSBpZiBOYU4KLQlpbC5hcHBlbmQobmV3IERMT0FEKGxvY2FsLmdldEluZGV4KCkpKTsKLQlpbC5hcHBlbmQobmV3IERMT0FEKGxvY2FsLmdldEluZGV4KCkpKTsKLQlpbC5hcHBlbmQoRENNUEcpOwotCWZsb3dsaXN0LmFkZChpbC5hcHBlbmQobmV3IElGTkUobnVsbCkpKTsJLy8gTmFOICE9IE5hTgotCXJldHVybiBmbG93bGlzdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHBlY3RzIGEgZG91YmxlIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgYm94ZWQgZG91YmxlLiBCb3hlZCAKLSAgICAgKiBkb3VibGUgYXJlIHJlcHJlc2VudGVkIGJ5IGFuIGluc3RhbmNlIG9mIDxjb2RlPmphdmEubGFuZy5Eb3VibGU8L2NvZGU+LgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWZlcmVuY2VUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhET1VCTEVfQ0xBU1MpKSk7Ci0JaWwuYXBwZW5kKERVUF9YMik7Ci0JaWwuYXBwZW5kKERVUF9YMik7Ci0JaWwuYXBwZW5kKFBPUCk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGNwZy5hZGRNZXRob2RyZWYoRE9VQkxFX0NMQVNTLAotCQkJCQkJICAgICAiPGluaXQ+IiwgIihEKVYiKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZWFsIGludG8gdGhlIEphdmEgdHlwZSBkZW5vdGVkIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPi4gCi0gICAgICogRXhwZWN0cyBhIHJlYWwgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBudW1iZXIgb2YgdGhlIGFwcHJvcHJpYXRlCi0gICAgICogdHlwZSBhZnRlciBjb2VyY2lvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgZmluYWwgQ2xhc3MgY2xhenopIHsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWYgKGNsYXp6ID09IENoYXJhY3Rlci5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChEMkkpOwotCSAgICBpbC5hcHBlbmQoSTJDKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gQnl0ZS5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChEMkkpOwotCSAgICBpbC5hcHBlbmQoSTJCKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gU2hvcnQuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoRDJJKTsKLQkgICAgaWwuYXBwZW5kKEkyUyk7Ci0JfQotCWVsc2UgaWYgKGNsYXp6ID09IEludGVnZXIuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoRDJJKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gTG9uZy5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChEMkwpOwotCX0KLQllbHNlIGlmIChjbGF6eiA9PSBGbG9hdC5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChEMkYpOwotCX0KLQllbHNlIGlmIChjbGF6eiA9PSBEb3VibGUuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoTk9QKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBleHRlcm5hbCAocHJpbWl0aXZlKSBKYXZhIHR5cGUgaW50byBhIHJlYWwuIEV4cGVjdHMgYSBqYXZhIAotICAgICAqIG9iamVjdCBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIHJlYWwgKGkuZS4sIGEgZG91YmxlKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVGcm9tKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICAgIENsYXNzIGNsYXp6KSB7Ci0JSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaWYgKGNsYXp6ID09IENoYXJhY3Rlci5UWVBFIHx8IGNsYXp6ID09IEJ5dGUuVFlQRSB8fAotCSAgICBjbGF6eiA9PSBTaG9ydC5UWVBFIHx8IGNsYXp6ID09IEludGVnZXIuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoSTJEKTsKLQl9Ci0JZWxzZSBpZiAoY2xhenogPT0gTG9uZy5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChMMkQpOwotCX0KLQllbHNlIGlmIChjbGF6eiA9PSBGbG9hdC5UWVBFKSB7Ci0JICAgIGlsLmFwcGVuZChGMkQpOwotCX0KLQllbHNlIGlmIChjbGF6eiA9PSBEb3VibGUuVFlQRSkgewotCSAgICBpbC5hcHBlbmQoTk9QKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5SZWZlcmVuY2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKERPVUJMRV9DTEFTUykpKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoY3BnLmFkZE1ldGhvZHJlZihET1VCTEVfQ0xBU1MsCi0JCQkJCQkgICAgIERPVUJMRV9WQUxVRSwgCi0JCQkJCQkgICAgIERPVUJMRV9WQUxVRV9TSUcpKSk7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIEFERCgpIHsKLQlyZXR1cm4gSW5zdHJ1Y3Rpb25Db25zdGFudHMuREFERDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1VCKCkgewotCXJldHVybiBJbnN0cnVjdGlvbkNvbnN0YW50cy5EU1VCOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBNVUwoKSB7Ci0JcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRNVUw7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIERJVigpIHsKLQlyZXR1cm4gSW5zdHJ1Y3Rpb25Db25zdGFudHMuRERJVjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gUkVNKCkgewotCXJldHVybiBJbnN0cnVjdGlvbkNvbnN0YW50cy5EUkVNOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBORUcoKSB7Ci0JcmV0dXJuIEluc3RydWN0aW9uQ29uc3RhbnRzLkRORUc7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IERMT0FEKHNsb3QpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IERTVE9SRShzbG90KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gUE9QKCkgewotCXJldHVybiBQT1AyOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gQ01QKGJvb2xlYW4gbGVzcykgewotCXJldHVybiBsZXNzID8gSW5zdHJ1Y3Rpb25Db25zdGFudHMuRENNUEcgOiBJbnN0cnVjdGlvbkNvbnN0YW50cy5EQ01QTDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gRFVQKCkgewotCXJldHVybiBEVVAyOwotICAgIH0KLX0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9SZWZlcmVuY2VUeXBlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1JlZmVyZW5jZVR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjU5NjdjNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1JlZmVyZW5jZVR5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0OSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIEVyd2luIEJvbHdpZHQgPGVqYkBrbG9tcC5vcmc+Ci0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlBhcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgUmVmZXJlbmNlVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByb3RlY3RlZCBSZWZlcmVuY2VUeXBlKCkge30KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJyZWZlcmVuY2UiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLQlyZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotCXJldHVybiAiTGphdmEvbGFuZy9PYmplY3Q7IjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLQlyZXR1cm4gZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5PQkpFQ1Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4gCi0gICAgICogVGhlIHRyYW5zbGF0aW9uIHRvIGludCBpcyB1bmRlZmluZWQgc2luY2UgcmVmZXJlbmNlcwotICAgICAqIGFyZSBhbHdheXMgY29udmVydGVkIHRvIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFR5cGUgdHlwZSkgewotCWlmICh0eXBlID09IFR5cGUuU3RyaW5nKSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChTdHJpbmdUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlYWxUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLk5vZGVTZXQpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKE5vZGVTZXRUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLk5vZGUpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKE5vZGVUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsJCS8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIHJlZmVyZW5jZSBpbnRvIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LiAKLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgU3RyaW5nVHlwZSB0eXBlKSB7Ci0JZmluYWwgaW50IGN1cnJlbnQgPSBtZXRob2RHZW4uZ2V0TG9jYWxJbmRleCgiY3VycmVudCIpOwotCUNvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlpbC5hcHBlbmQobmV3IElMT0FEKGN1cnJlbnQpKTsKLQlpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0JZmluYWwgaW50IHN0cmluZ0YgPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsCi0JCQkJCSAgICAgInN0cmluZ0YiLCAKLQkJCQkJICAgICAiKCIKLQkJCQkJICAgICArIE9CSkVDVF9TSUcKLQkJCQkJICAgICArIE5PREVfU0lHCi0JCQkJCSAgICAgKyBET01fSU5URl9TSUcKLQkJCQkJICAgICArICIpIiArIFNUUklOR19TSUcpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKHN0cmluZ0YpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgcmVmZXJlbmNlIGludG8gYW4gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uIAotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWFsVHlwZSB0eXBlKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlsLmFwcGVuZChtZXRob2RHZW4ubG9hZERPTSgpKTsKLQlpbnQgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKEJBU0lTX0xJQlJBUllfQ0xBU1MsICJudW1iZXJGIiwgCi0JCQkJICAgICAiKCIgCi0JCQkJICAgICArIE9CSkVDVF9TSUcKLQkJCQkgICAgICsgRE9NX0lOVEZfU0lHCi0JCQkJICAgICArICIpRCIpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGluZGV4KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3Qgb2YgaW50ZXJuYWwgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4gCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JaW50IGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihCQVNJU19MSUJSQVJZX0NMQVNTLCAiYm9vbGVhbkYiLCAKLQkJCQkgICAgICIoIiAKLQkJCQkgICAgICsgT0JKRUNUX1NJRwotCQkJCSAgICAgKyAiKVoiKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENhc3RzIGEgcmVmZXJlbmNlIGludG8gYSBOb2RlSXRlcmF0b3IuCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIE5vZGVTZXRUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywgInJlZmVyZW5jZVRvTm9kZVNldCIsIAotCQkJCSAgICAgIigiCi0JCQkJICAgICArIE9CSkVDVF9TSUcKLQkJCQkgICAgICsgIikiCi0JCQkJICAgICArIE5PREVfSVRFUkFUT1JfU0lHKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRVNUQVRJQyhpbmRleCkpOwotCQotCS8vIFJlc2V0IHRoaXMgaXRlcmF0b3IKLQlpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoTk9ERV9JVEVSQVRPUiwgUkVTRVQsIFJFU0VUX1NJRyk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDYXN0cyBhIHJlZmVyZW5jZSBpbnRvIGEgTm9kZS4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwKLQkJCSAgICBOb2RlVHlwZSB0eXBlKSB7Ci0JdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLQlUeXBlLk5vZGVTZXQudHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgdHlwZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIHJlZmVyZW5jZSBvbiB0aGUgc3RhY2sgYW5kIHRyYW5zbGF0ZXMgaXQgdG8gYSBub24tc3ludGhlc2l6ZWQKLSAgICAgKiBib29sZWFuLiBJdCBkb2VzIG5vdCBwdXNoIGEgMCBvciBhIDEgYnV0IGluc3RlYWQgcmV0dXJucyBicmFuY2hoYW5kbGUgCi0gICAgICogbGlzdCB0byBiZSBhcHBlbmRlZCB0byB0aGUgZmFsc2UgbGlzdC4KLSAgICAgKgotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkCi0gICAgICovCi0gICAgcHVibGljIEZsb3dMaXN0IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgCi0JCQkJCSAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkJCSAgICAgQm9vbGVhblR5cGUgdHlwZSkgewotCUluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQl0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCB0eXBlKTsKLQlyZXR1cm4gbmV3IEZsb3dMaXN0KGlsLmFwcGVuZChuZXcgSUZFUShudWxsKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovIAotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgdW5ib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVW5Cb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotICAgIH0KLQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IEFMT0FEKHNsb3QpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IEFTVE9SRShzbG90KTsKLSAgICB9Ci19Ci0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvUmVzdWx0VHJlZVR5cGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvUmVzdWx0VHJlZVR5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2JmNWQyNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1Jlc3VsdFRyZWVUeXBlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0NDAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuRmxvd0xpc3Q7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBSZXN1bHRUcmVlVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIF9tZXRob2ROYW1lOwotCi0gICAgcHJvdGVjdGVkIFJlc3VsdFRyZWVUeXBlKCkgewotCV9tZXRob2ROYW1lID0gbnVsbDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgUmVzdWx0VHJlZVR5cGUoU3RyaW5nIG1ldGhvZE5hbWUpIHsKLQlfbWV0aG9kTmFtZSA9IG1ldGhvZE5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gInJlc3VsdC10cmVlIjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpZGVudGljYWxUbyhUeXBlIG90aGVyKSB7Ci0JcmV0dXJuIChvdGhlciBpbnN0YW5jZW9mIFJlc3VsdFRyZWVUeXBlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotCXJldHVybiBET01fSU5URl9TSUc7Ci0gICAgfQotCi0gICAgcHVibGljIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUgdG9KQ1R5cGUoKSB7Ci0JcmV0dXJuIFV0aWwuZ2V0SkNSZWZUeXBlKHRvU2lnbmF0dXJlKCkpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWV0aG9kTmFtZSgpIHsKLQlyZXR1cm4gX21ldGhvZE5hbWU7Ci0gICAgfQotCi0gICAgcHVibGljIGJvb2xlYW4gaW1wbGVtZW50ZWRBc01ldGhvZCgpIHsKLQlyZXR1cm4gX21ldGhvZE5hbWUgIT0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgcmVzdWx0IHRyZWUgdG8gb2JqZWN0IG9mIGludGVybmFsIHR5cGUgPGNvZGU+dHlwZTwvY29kZT4uIAotICAgICAqIFRoZSB0cmFuc2xhdGlvbiB0byBpbnQgaXMgdW5kZWZpbmVkIHNpbmNlIHJlc3VsdCB0cmVlcwotICAgICAqIGFyZSBhbHdheXMgY29udmVydGVkIHRvIHJlYWxzIGluIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQSBCQ0VMIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQSBCQ0VMIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gdHlwZSBBbiBpbnN0YW5jZSBvZiB0aGUgdHlwZSB0byB0cmFuc2xhdGUgdGhlIHJlc3VsdCB0cmVlIHRvCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBUeXBlIHR5cGUpIHsKLQlpZiAodHlwZSA9PSBUeXBlLlN0cmluZykgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoU3RyaW5nVHlwZSl0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKXR5cGUpOwotCX0KLQllbHNlIGlmICh0eXBlID09IFR5cGUuUmVhbCkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVhbFR5cGUpdHlwZSk7Ci0JfQotCWVsc2UgaWYgKHR5cGUgPT0gVHlwZS5Ob2RlU2V0KSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIChOb2RlU2V0VHlwZSl0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSl0eXBlKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsgLy8gdW5kZWZpbmVkCi0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gcmVzdWx0IHRyZWUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBib29sZWFuLgotICAgICAqIFRyYW5zbGF0ZXMgYSByZXN1bHQgdHJlZSB0byBhIGJvb2xlYW4gYnkgZmlyc3QgY29udmVydGluZyBpdCB0byBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQSBCQ0VMIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQSBCQ0VMIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gdHlwZSBBbiBpbnN0YW5jZSBvZiBCb29sZWFuVHlwZSAoYW55KQotICAgICAqIEBzZWUgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQm9vbGVhblR5cGUgdHlwZSkgewotCS8vIEEgcmVzdWx0IHRyZWUgaXMgYWx3YXlzICd0cnVlJyB3aGVuIGNvbnZlcnRlZCB0byBhIGJvb2xlYW4gdmFsdWUsCi0JLy8gc2luY2UgdGhlIHRyZWUgYWx3YXlzIGhhcyBhdCBsZWFzdCBvbmUgbm9kZSAodGhlIHJvb3QpLgotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0JaWwuYXBwZW5kKFBPUCk7ICAgICAgLy8gZG9uJ3QgbmVlZCB0aGUgRE9NIHJlZmVyZW5jZQotCWlsLmFwcGVuZChJQ09OU1RfMSk7IC8vIHB1c2ggJ3RydWUnIG9uIHRoZSBzdGFjawotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gcmVzdWx0IHRyZWUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSBzdHJpbmcuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY2xhc3NHZW4gQSBCQ0VMIGNsYXNzIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSBtZXRob2RHZW4gQSBCQ0VMIG1ldGhvZCBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gdHlwZSBBbiBpbnN0YW5jZSBvZiBTdHJpbmdUeXBlIChhbnkpCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBTdHJpbmdUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCQotCWlmIChfbWV0aG9kTmFtZSA9PSBudWxsKSB7Ci0JICAgIGludCBpbmRleCA9IGNwZy5hZGRJbnRlcmZhY2VNZXRob2RyZWYoRE9NX0lOVEYsCi0JCQkJCQkgICJnZXRTdHJpbmdWYWx1ZSIsIAotCQkJCQkJICAiKCkiK1NUUklOR19TSUcpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMSkpOwotCX0KLQllbHNlIHsKLQkgICAgZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXNzR2VuLmdldENsYXNzTmFtZSgpOwotCSAgICBmaW5hbCBpbnQgY3VycmVudCA9IG1ldGhvZEdlbi5nZXRMb2NhbEluZGV4KCJjdXJyZW50Iik7Ci0JICAgIAotCSAgICAvLyBQdXNoIHJlcXVpcmVkIHBhcmFtZXRlcnMgCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlmIChjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLQkJaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzTmFtZSkpKTsKLQkgICAgfQotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoY2xhc3NOYW1lLCAiX2RvbSIsCi0JCQkJCQkgICBET01fSU5URl9TSUcpKSk7Ci0KLQkgICAgLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGEgU3RyaW5nVmFsdWVIYW5kbGVyCi0JICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoU1RSSU5HX1ZBTFVFX0hBTkRMRVIsICI8aW5pdD4iLCAiKClWIik7Ci0JICAgIGlsLmFwcGVuZChuZXcgTkVXKGNwZy5hZGRDbGFzcyhTVFJJTkdfVkFMVUVfSEFORExFUikpKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVNQRUNJQUwoaW5kZXgpKTsKLQkgICAgCi0JICAgIC8vIFN0b3JlIG5ldyBIYW5kbGVyIGludG8gYSBsb2NhbCB2YXJpYWJsZQotCSAgICBmaW5hbCBMb2NhbFZhcmlhYmxlR2VuIGhhbmRsZXIgPQotCQltZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgicnRfdG9fc3RyaW5nX2hhbmRsZXIiLCAKLQkJCQkJICAgVXRpbC5nZXRKQ1JlZlR5cGUoU1RSSU5HX1ZBTFVFX0hBTkRMRVJfU0lHKSwKLQkJCQkJICAgbnVsbCwgbnVsbCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKGhhbmRsZXIuZ2V0SW5kZXgoKSkpOwotCi0JICAgIC8vIENhbGwgdGhlIG1ldGhvZCB0aGF0IGltcGxlbWVudHMgdGhpcyByZXN1bHQgdHJlZQotCSAgICBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoY2xhc3NOYW1lLCBfbWV0aG9kTmFtZSwKLQkJCQkgICAgICIoIitET01fSU5URl9TSUcrVFJBTlNMRVRfT1VUUFVUX1NJRysiKVYiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0JICAgIAotCSAgICAvLyBSZXN0b3JlIG5ldyBoYW5kbGVyIGFuZCBjYWxsIGdldFZhbHVlKCkKLQkgICAgaWwuYXBwZW5kKG5ldyBBTE9BRChoYW5kbGVyLmdldEluZGV4KCkpKTsKLQkgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19WQUxVRV9IQU5ETEVSLAotCQkJCSAgICAgImdldFZhbHVlIiwKLQkJCQkgICAgICIoKSIgKyBTVFJJTkdfU0lHKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VWSVJUVUFMKGluZGV4KSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYW4gcmVzdWx0IHRyZWUgb24gdGhlIHN0YWNrIGFuZCBwdXNoZXMgYSByZWFsLgotICAgICAqIFRyYW5zbGF0ZXMgYSByZXN1bHQgdHJlZSBpbnRvIGEgcmVhbCBieSBmaXJzdCBjb252ZXJ0aW5nIGl0IHRvIHN0cmluZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBBIEJDRUwgY2xhc3MgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIG1ldGhvZEdlbiBBIEJDRUwgbWV0aG9kIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSB0eXBlIEFuIGluc3RhbmNlIG9mIFJlYWxUeXBlIChhbnkpCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWFsVHlwZSB0eXBlKSB7Ci0JdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5TdHJpbmcpOwotCVR5cGUuU3RyaW5nLnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVhbCk7CQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEV4cGVjdHMgYSByZXN1bHQgdHJlZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIHJlc3VsdCB0cmVlLgotICAgICAqIFJlc3VsdCB0cmVlcyBhcmUgYWxyZWFkeSBib3hlZCBzbyB0aGUgdHJhbnNsYXRpb24gaXMganVzdCBhIE5PUC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBBIEJDRUwgY2xhc3MgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIG1ldGhvZEdlbiBBIEJDRUwgbWV0aG9kIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSB0eXBlIEFuIGluc3RhbmNlIG9mIFJlZmVyZW5jZVR5cGUgKGFueSkKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFJlZmVyZW5jZVR5cGUgdHlwZSkgewotCWZpbmFsIENvbnN0YW50UG9vbEdlbiBjcGcgPSBjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKTsKLQlmaW5hbCBJbnN0cnVjdGlvbkxpc3QgaWwgPSBtZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCk7Ci0KLQlpZiAoX21ldGhvZE5hbWUgPT0gbnVsbCkgewotCSAgICBpbC5hcHBlbmQoTk9QKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIExvY2FsVmFyaWFibGVHZW4gZG9tQnVpbGRlciwgbmV3RG9tOwotCSAgICBmaW5hbCBTdHJpbmcgY2xhc3NOYW1lID0gY2xhc3NHZW4uZ2V0Q2xhc3NOYW1lKCk7Ci0JICAgIGZpbmFsIGludCBjdXJyZW50ID0gbWV0aG9kR2VuLmdldExvY2FsSW5kZXgoImN1cnJlbnQiKTsKLQotCSAgICAvLyBQdXNoIHJlcXVpcmVkIHBhcmFtZXRlcnMgCi0JICAgIGlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7Ci0JICAgIGlmIChjbGFzc0dlbi5pc0V4dGVybmFsKCkpIHsKLQkJaWwuYXBwZW5kKG5ldyBDSEVDS0NBU1QoY3BnLmFkZENsYXNzKGNsYXNzTmFtZSkpKTsKLQkgICAgfQotCSAgICBpbC5hcHBlbmQobWV0aG9kR2VuLmxvYWRET00oKSk7Ci0KLQkgICAgLy8gQ3JlYXRlIG5ldyBpbnN0YW5jZSBvZiBET00gY2xhc3MgKHdpdGggNjQgbm9kZXMpCi0JICAgIGludCBpbmRleCA9IGNwZy5hZGRNZXRob2RyZWYoRE9NX0lNUEwsICI8aW5pdD4iLCAiKEkpViIpOwotCSAgICBpbC5hcHBlbmQobmV3IE5FVyhjcGcuYWRkQ2xhc3MoRE9NX0lNUEwpKSk7Ci0JICAgIGlsLmFwcGVuZChEVVApOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgNjQpKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VTUEVDSUFMKGluZGV4KSk7Ci0JICAgIAotCSAgICAvLyBTdG9yZSBuZXcgRE9NIGludG8gYSBsb2NhbCB2YXJpYWJsZQotCSAgICBuZXdEb20gPSBtZXRob2RHZW4uYWRkTG9jYWxWYXJpYWJsZSgicnRfdG9fcmVmZXJlbmNlX2RvbSIsIAotCQkJCQkJVXRpbC5nZXRKQ1JlZlR5cGUoRE9NX0lOVEZfU0lHKSwKLQkJCQkJCW51bGwsIG51bGwpOwotCSAgICBpbC5hcHBlbmQobmV3IENIRUNLQ0FTVChjcGcuYWRkQ2xhc3MoRE9NX0lOVEZfU0lHKSkpOwotCSAgICBpbC5hcHBlbmQobmV3IEFTVE9SRShuZXdEb20uZ2V0SW5kZXgoKSkpOwotCi0JICAgIC8vIE92ZXJ3cml0ZSBvbGQgaGFuZGxlciB3aXRoIERPTSBoYW5kbGVyCi0JICAgIGluZGV4ID0gY3BnLmFkZE1ldGhvZHJlZihET01fSU1QTCwKLQkJCQkgICAgICJnZXRPdXRwdXREb21CdWlsZGVyIiwgCi0JCQkJICAgICAiKCkiICsgVFJBTlNMRVRfT1VUUFVUX1NJRyk7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotCSAgICBpbC5hcHBlbmQoRFVQKTsKLQkgICAgaWwuYXBwZW5kKERVUCk7Ci0KLQkgICAgLy8gU3RvcmUgRE9NIGhhbmRsZXIgaW4gYSBsb2NhbCBpbiBvcmRlciB0byBjYWxsIGVuZERvY3VtZW50KCkKLQkgICAgZG9tQnVpbGRlciA9Ci0JCW1ldGhvZEdlbi5hZGRMb2NhbFZhcmlhYmxlKCJydF90b19yZWZlcmVuY2VfaGFuZGxlciIsIAotCQkJCQkgICBVdGlsLmdldEpDUmVmVHlwZShUUkFOU0xFVF9PVVRQVVRfU0lHKSwKLQkJCQkJICAgbnVsbCwgbnVsbCk7Ci0JICAgIGlsLmFwcGVuZChuZXcgQVNUT1JFKGRvbUJ1aWxkZXIuZ2V0SW5kZXgoKSkpOwotCi0JICAgIC8vIENhbGwgc3RhcnREb2N1bWVudCBvbiB0aGUgbmV3IGhhbmRsZXIKLQkgICAgaW5kZXggPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKFRSQU5TTEVUX09VVFBVVF9JTlRFUkZBQ0UsIAotCQkJCQkgICAgICAic3RhcnREb2N1bWVudCIsICIoKVYiKTsKLQkgICAgaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaW5kZXgsIDEpKTsKLQotCSAgICAvLyBDYWxsIHRoZSBtZXRob2QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcmVzdWx0IHRyZWUKLQkgICAgaW5kZXggPSBjcGcuYWRkTWV0aG9kcmVmKGNsYXNzTmFtZSwKLQkJCQkgICAgIF9tZXRob2ROYW1lLAotCQkJCSAgICAgIigiCi0JCQkJICAgICArIERPTV9JTlRGX1NJRwotCQkJCSAgICAgKyBUUkFOU0xFVF9PVVRQVVRfU0lHCi0JCQkJICAgICArIilWIik7Ci0JICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChpbmRleCkpOwotCi0JICAgIC8vIENhbGwgZW5kRG9jdW1lbnQgb24gdGhlIERPTSBoYW5kbGVyCi0JICAgIGlsLmFwcGVuZChuZXcgQUxPQUQoZG9tQnVpbGRlci5nZXRJbmRleCgpKSk7Ci0JICAgIGluZGV4ID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihUUkFOU0xFVF9PVVRQVVRfSU5URVJGQUNFLCAKLQkJCQkJICAgICAgImVuZERvY3VtZW50IiwgIigpViIpOwotCSAgICBpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShpbmRleCwgMSkpOwotCi0JICAgIC8vIFB1c2ggdGhlIG5ldyBET00gb24gdGhlIHN0YWNrCi0JICAgIGlsLmFwcGVuZChuZXcgQUxPQUQobmV3RG9tLmdldEluZGV4KCkpKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIHJlc3VsdCB0cmVlIG9uIHRoZSBzdGFjayBhbmQgcHVzaGVzIGEgbm9kZS1zZXQgKGl0ZXJhdG9yKS4KLSAgICAgKiBOb3RlIHRoYXQgdGhlIHByb2R1Y2VkIGl0ZXJhdG9yIGlzIGFuIGl0ZXJhdG9yIGZvciB0aGUgRE9NIHRoYXQKLSAgICAgKiBjb250YWlucyB0aGUgcmVzdWx0IHRyZWUsIGFuZCBub3QgdGhlIERPTSB0aGF0IGlzIGN1cnJlbnRseSBpbiB1c2UuCi0gICAgICogVGhpcyBjb252ZXJzaW9uIGhlcmUgd2lsbCB0aGVyZWZvcmUgbm90IGRpcmVjdGx5IHdvcmsgd2l0aCBlbGVtZW50cwotICAgICAqIHN1Y2ggYXMgPHhzbDphcHBseS10ZW1wbGF0ZXM+IGFuZCA8eHNsOmZvci1lYWNoPiB3aXRob3V0IHRoZSBET00KLSAgICAgKiBwYXJhbWV0ZXIvdmFyaWFibGUgYmVpbmcgdXBkYXRlcyBhcyB3ZWxsLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIEEgQkNFTCBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIEEgQkNFTCBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIHR5cGUgQW4gaW5zdGFuY2Ugb2YgTm9kZVNldFR5cGUgKGFueSkKLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIE5vZGVTZXRUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCi0JLy8gUHV0IGFuIGV4dHJhIGNvcHkgb2YgdGhlIHJlc3VsdCB0cmVlIChET00pIG9uIHRoZSBzdGFjawotCWlsLmFwcGVuZChEVVApOwotCi0JLy8gRE9NIGFkYXB0ZXJzIGNvbnRhaW5pbmcgYSByZXN1bHQgdHJlZSBhcmUgbm90IGluaXRpYWxpc2VkIHdpdGgKLQkvLyB0cmFuc2xldC10eXBlIHRvIERPTS10eXBlIG1hcHBpbmcuIFRoaXMgbXVzdCBiZSBkb25lIG5vdyBmb3IKLQkvLyBYUGF0aCBleHByZXNzaW9ucyBhbmQgcGF0dGVybnMgdG8gd29yayBmb3IgdGhlIGl0ZXJhdG9yIHdlIGNyZWF0ZS4KLQlpbC5hcHBlbmQoY2xhc3NHZW4ubG9hZFRyYW5zbGV0KCkpOyAvLyBnZXQgbmFtZXMgYXJyYXkKLQlpbC5hcHBlbmQobmV3IEdFVEZJRUxEKGNwZy5hZGRGaWVsZHJlZihUUkFOU0xFVF9DTEFTUywKLQkJCQkJICAgICAgIE5BTUVTX0lOREVYLAotCQkJCQkgICAgICAgTkFNRVNfSU5ERVhfU0lHKSkpOwotCWlsLmFwcGVuZChjbGFzc0dlbi5sb2FkVHJhbnNsZXQoKSk7IC8vIGdldCBuYW1lc3BhY2VzIGFycmF5Ci0JaWwuYXBwZW5kKG5ldyBHRVRGSUVMRChjcGcuYWRkRmllbGRyZWYoVFJBTlNMRVRfQ0xBU1MsCi0JCQkJCSAgICAgICBOQU1FU1BBQ0VfSU5ERVgsCi0JCQkJCSAgICAgICBOQU1FU1BBQ0VfSU5ERVhfU0lHKSkpOwotCS8vIFBhc3MgdGhlIHR5cGUgbWFwcGluZ3MgdG8gdGhlIERPTSBhZGFwdGVyCi0JZmluYWwgaW50IG1hcHBpbmcgPSBjcGcuYWRkSW50ZXJmYWNlTWV0aG9kcmVmKERPTV9JTlRGLAotCQkJCQkJICAgICAgInNldHVwTWFwcGluZyIsCi0JCQkJCQkgICAgICAiKFsiK1NUUklOR19TSUcrCi0JCQkJCQkgICAgICAiWyIrU1RSSU5HX1NJRysiKVYiKTsKLQlpbC5hcHBlbmQobmV3IElOVk9LRUlOVEVSRkFDRShtYXBwaW5nLCAzKSk7Ci0JaWwuYXBwZW5kKERVUCk7Ci0KLQkvLyBDcmVhdGUgYW4gaXRlcmF0b3Igd2l0aCBhbGwgdGhlIG5vZGVzIGluIHRoZSBET00gYWRhcHRlcgotCWZpbmFsIGludCBpdGVyID0gY3BnLmFkZEludGVyZmFjZU1ldGhvZHJlZihET01fSU5URiwKLQkJCQkJCSAgICJnZXRDaGlsZHJlbiIsCi0JCQkJCQkgICAiKEkpIitOT0RFX0lURVJBVE9SX1NJRyk7Ci0JaWwuYXBwZW5kKG5ldyBQVVNIKGNwZywgRE9NLlJPT1ROT0RFKSk7Ci0JaWwuYXBwZW5kKG5ldyBJTlZPS0VJTlRFUkZBQ0UoaXRlciwgMikpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSByZXN1bHQgdHJlZSBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uCi0gICAgICogSXQgZG9lcyBub3QgcHVzaCBhIDAgb3IgYSAxIGJ1dCBpbnN0ZWFkIHJldHVybnMgYnJhbmNoaGFuZGxlIGxpc3QKLSAgICAgKiB0byBiZSBhcHBlbmRlZCB0byB0aGUgZmFsc2UgbGlzdC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjbGFzc0dlbiBBIEJDRUwgY2xhc3MgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIG1ldGhvZEdlbiBBIEJDRUwgbWV0aG9kIGdlbmVyYXRvcgotICAgICAqIEBwYXJhbSB0eXBlIEFuIGluc3RhbmNlIG9mIEJvb2xlYW5UeXBlIChhbnkpCi0gICAgICogQHNlZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCAKLQkJCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCQkJICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCXRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuQm9vbGVhbik7Ci0JcmV0dXJuIG5ldyBGbG93TGlzdChpbC5hcHBlbmQobmV3IElGRVEobnVsbCkpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgcmVzdWx0IHRyZWUgdG8gYSBKYXZhIHR5cGUgZGVub3RlZCBieSA8Y29kZT5jbGF6ejwvY29kZT4uIAotICAgICAqIEV4cGVjdHMgYSByZXN1bHQgdHJlZSBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhbiBvYmplY3QKLSAgICAgKiBvZiB0aGUgYXBwcm9wcmlhdGUgdHlwZSBhZnRlciBjb2VyY2lvbi4gUmVzdWx0IHRyZWVzIGFyZSB0cmFuc2xhdGVkCi0gICAgICogdG8gVzNDIE5vZGUgb3IgVzNDIE5vZGVMaXN0IGFuZCB0aGUgdHJhbnNsYXRpb24gaXMgZG9uZQotICAgICAqIHZpYSBub2RlLXNldCB0eXBlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNsYXNzR2VuIEEgQkNFTCBjbGFzcyBnZW5lcmF0b3IKLSAgICAgKiBAcGFyYW0gbWV0aG9kR2VuIEEgQkNFTCBtZXRob2QgZ2VuZXJhdG9yCi0gICAgICogQHBhcmFtIHR5cGUgQW4gcmVmZXJlbmNlIHRvIHRoZSBDbGFzcyB0byB0cmFuc2xhdGUgdG8KLSAgICAgKiBAc2VlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIENsYXNzIGNsYXp6KSB7Ci0JZmluYWwgU3RyaW5nIGNsYXNzTmFtZSA9IGNsYXp6LmdldE5hbWUoKTsKLQlpZiAoY2xhc3NOYW1lLmVxdWFscygib3JnLnczYy5kb20uTm9kZSIpIHx8Ci0JICAgIGNsYXNzTmFtZS5lcXVhbHMoIm9yZy53M2MuZG9tLk5vZGVMaXN0IikpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgVHlwZS5Ob2RlU2V0KTsKLQkgICAgVHlwZS5Ob2RlU2V0LnRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIGNsYXp6KTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsgLy8gdW5kZWZpbmVkCi0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBpdHMgYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovIAotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbikgewotCXRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIFR5cGUuUmVmZXJlbmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIHVuYm94ZWQgcmVwcmVzZW50YXRpb24uCi0gICAgICovIAotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVVuQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQltZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKE5PUCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY2xhc3MgbmFtZSBvZiBhbiBpbnRlcm5hbCB0eXBlJ3MgZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7Ci0JcmV0dXJuKERPTV9JTlRGKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTE9BRChpbnQgc2xvdCkgewotCXJldHVybiBuZXcgQUxPQUQoc2xvdCk7Ci0gICAgfQotCQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBTVE9SRShpbnQgc2xvdCkgewotCXJldHVybiBuZXcgQVNUT1JFKHNsb3QpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvUnRNZXRob2RHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvUnRNZXRob2RHZW5lcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGFkMTY5My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1J0TWV0aG9kR2VuZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuVGVtcGxhdGU7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyB1c2VkIGZvciByZXN1bHQgdHJlZXMgaW1wbGVtZW50ZWQgYXMgbWV0aG9kcy4gVGhlc2UKLSAqIG1ldGhvZHMgdGFrZSBhIHJlZmVyZW5jZSB0byB0aGUgRE9NIGFuZCB0byB0aGUgaGFuZGxlciBvbmx5LgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgUnRNZXRob2RHZW5lcmF0b3IgZXh0ZW5kcyBNZXRob2RHZW5lcmF0b3IgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBIQU5ETEVSX0lOREVYID0gMjsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9hc3RvcmVIYW5kbGVyOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkSGFuZGxlcjsKLQotICAgIHB1YmxpYyBSdE1ldGhvZEdlbmVyYXRvcihpbnQgYWNjZXNzX2ZsYWdzLCBUeXBlIHJldHVybl90eXBlLAotCQkJICAgICBUeXBlW10gYXJnX3R5cGVzLCBTdHJpbmdbXSBhcmdfbmFtZXMsCi0JCQkgICAgIFN0cmluZyBtZXRob2RfbmFtZSwgU3RyaW5nIGNsYXNzX25hbWUsCi0JCQkgICAgIEluc3RydWN0aW9uTGlzdCBpbCwgQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0Jc3VwZXIoYWNjZXNzX2ZsYWdzLCByZXR1cm5fdHlwZSwgYXJnX3R5cGVzLCBhcmdfbmFtZXMsIG1ldGhvZF9uYW1lLCAKLQkgICAgICBjbGFzc19uYW1lLCBpbCwgY3ApOwotCQotCV9hc3RvcmVIYW5kbGVyID0gbmV3IEFTVE9SRShIQU5ETEVSX0lOREVYKTsKLQlfYWxvYWRIYW5kbGVyICA9IG5ldyBBTE9BRChIQU5ETEVSX0lOREVYKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEl0ZXJhdG9ySW5kZXgoKSB7Ci0JcmV0dXJuIElOVkFMSURfSU5ERVg7CQkvLyBub3QgYXZhaWxhYmxlCi0gICAgfQotICAgIAotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBzdG9yZUhhbmRsZXIoKSB7Ci0JcmV0dXJuIF9hc3RvcmVIYW5kbGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCBJbnN0cnVjdGlvbiBsb2FkSGFuZGxlcigpIHsKLQlyZXR1cm4gX2Fsb2FkSGFuZGxlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldExvY2FsSW5kZXgoU3RyaW5nIG5hbWUpIHsKLQlyZXR1cm4gSU5WQUxJRF9JTkRFWDsJCS8vIG5vdCBhdmFpbGFibGUKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1Nsb3RBbGxvY2F0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvU2xvdEFsbG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiN2Y2YzcyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvU2xvdEFsbG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotCi1maW5hbCBjbGFzcyBTbG90QWxsb2NhdG9yIHsKLSAgICBwcml2YXRlIGludCAgIF9maXJzdEF2YWlsYWJsZVNsb3Q7Ci0gICAgcHJpdmF0ZSBpbnQgICBfc2l6ZSA9IDg7Ci0gICAgcHJpdmF0ZSBpbnQgICBfZnJlZSA9IDA7Ci0gICAgcHJpdmF0ZSBpbnRbXSBfc2xvdHNUYWtlbiA9IG5ldyBpbnRbX3NpemVdOwotCi0gICAgLyoKLSAgICBwcml2YXRlIHN0YXRpYyBpbnQgU2VyaWFsID0gMDsKLSAgICBwcml2YXRlIGZpbmFsIGludCBfc2VyaWFsID0gU2VyaWFsKys7Ci0gICAgCi0KLSAgICBwcml2YXRlIHZvaWQgcHJpbnRTdGF0ZShTdHJpbmcgbXNnKSB7Ci0JU3lzdGVtLm91dC5wcmludGxuKCI9PT09PT09PT09PSAiICsgX3NlcmlhbCArICIgPT09PT09PT09PT0gIiArIG1zZyk7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJmaXJzdEF2YWlsYWJsZVNsb3QgPSAiICsgX2ZpcnN0QXZhaWxhYmxlU2xvdCk7Ci0JCi0JZm9yIChpbnQgaSA9IDA7IGkgPCBfZnJlZTsgaSsrKSB7Ci0JICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRzbG90c1Rha2VuID0gIiArIF9zbG90c1Rha2VuW2ldKTsKLQl9Ci0JCi0JU3lzdGVtLm91dC5wcmludGxuKCI9PT09PT09PT09PT09PT09PT09PT09PT0iKTsKLSAgICB9Ci0gICAgKi8KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKExvY2FsVmFyaWFibGVHZW5bXSB2YXJzKSB7Ci0JZmluYWwgaW50IGxlbmd0aCA9IHZhcnMubGVuZ3RoOwotCS8vU3lzdGVtLm91dC5wcmludGxuKF9zZXJpYWwgKyAiIGluaXRpYWxpemUgIiArIGxlbmd0aCk7Ci0JaW50IHNsb3QgPSAwOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImluZGV4ICIgKyB2YXJzW2ldLmdldEluZGV4KCkpOwotCSAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiYWxsICIgKyBhbGxvY2F0ZVNsb3QodmFyc1tpXS5nZXRUeXBlKCkpKTsKLQkgICAgLy9hbGxvY2F0ZVNsb3QodmFyc1tpXS5nZXRUeXBlKCkpOwotCSAgICBzbG90ID0gTWF0aC5tYXgoc2xvdCwKLQkJCSAgICB2YXJzW2ldLmdldEluZGV4KCkgKyB2YXJzW2ldLmdldFR5cGUoKS5nZXRTaXplKCkpOwotCX0KLQlfZmlyc3RBdmFpbGFibGVTbG90ID0gc2xvdDsKLQkvL1N5c3RlbS5vdXQucHJpbnRsbigiZmlyc3RBdmFpbGFibGVTbG90ID0gIiArIF9maXJzdEF2YWlsYWJsZVNsb3QpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgYWxsb2NhdGVTbG90KFR5cGUgdHlwZSkgewotCWZpbmFsIGludCBzaXplID0gdHlwZS5nZXRTaXplKCk7Ci0JZmluYWwgaW50IGxpbWl0ID0gX2ZyZWU7Ci0JaW50IHNsb3QgPSBfZmlyc3RBdmFpbGFibGVTbG90LCB3aGVyZSA9IDA7Ci0KLQkvL3ByaW50U3RhdGUoImFsbG9jYXRpbmciKTsKLQotCWlmIChfZnJlZSArIHNpemUgPiBfc2l6ZSkgewotCSAgICBmaW5hbCBpbnRbXSBhcnJheSA9IG5ldyBpbnRbX3NpemUgKj0gMl07Ci0JICAgIGZvciAoaW50IGogPSAwOyBqIDwgbGltaXQ7IGorKykgewotCQlhcnJheVtqXSA9IF9zbG90c1Rha2VuW2pdOwotCSAgICB9Ci0JICAgIF9zbG90c1Rha2VuID0gYXJyYXk7Ci0JfQotCi0Jd2hpbGUgKHdoZXJlIDwgbGltaXQpIHsKLQkgICAgaWYgKHNsb3QgKyBzaXplIDw9IF9zbG90c1Rha2VuW3doZXJlXSkgewotCQkvLyBpbnNlcnQKLQkJZm9yIChpbnQgaiA9IGxpbWl0IC0gMTsgaiA+PSB3aGVyZTsgai0tKSB7Ci0JCSAgICBfc2xvdHNUYWtlbltqICsgc2l6ZV0gPSBfc2xvdHNUYWtlbltqXTsKLQkJfQotCQlicmVhazsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJc2xvdCA9IF9zbG90c1Rha2VuW3doZXJlKytdICsgMTsKLQkgICAgfQotCX0KLQkKLQlmb3IgKGludCBqID0gMDsgaiA8IHNpemU7IGorKykgewotCSAgICBfc2xvdHNUYWtlblt3aGVyZSArIGpdID0gc2xvdCArIGo7Ci0JfQotCQotCV9mcmVlICs9IHNpemU7Ci0JLy9TeXN0ZW0ub3V0LnByaW50bG4oImFsbG9jYXRlZCBzbG90ICIgKyBzbG90KTsKLQkvL3ByaW50U3RhdGUoImRvbmUiKTsKLQlyZXR1cm4gc2xvdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCByZWxlYXNlU2xvdChMb2NhbFZhcmlhYmxlR2VuIGx2ZykgewotCWZpbmFsIGludCBzaXplID0gbHZnLmdldFR5cGUoKS5nZXRTaXplKCk7Ci0JZmluYWwgaW50IHNsb3QgPSBsdmcuZ2V0SW5kZXgoKTsKLQlmaW5hbCBpbnQgbGltaXQgPSBfZnJlZTsKLQkKLQkvL3ByaW50U3RhdGUoInJlbGVhc2luZyAiICsgc2xvdCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBsaW1pdDsgaSsrKSB7Ci0JICAgIGlmIChfc2xvdHNUYWtlbltpXSA9PSBzbG90KSB7Ci0JCWludCBqID0gaSArIHNpemU7Ci0JCXdoaWxlIChqIDwgbGltaXQpIHsKLQkJICAgIF9zbG90c1Rha2VuW2krK10gPSBfc2xvdHNUYWtlbltqKytdOwotCQl9Ci0JCV9mcmVlIC09IHNpemU7Ci0JCS8vU3lzdGVtLm91dC5wcmludGxuKCJyZWxlYXNlZCBzbG90ICIgKyBzbG90KTsKLQkJCi0JCS8vcHJpbnRTdGF0ZSgiZG9uZSIpOwotCQlyZXR1cm47Ci0JICAgIH0KLQl9Ci0JU3lzdGVtLmVyci5wcmludGxuKCJzaXplID0gIiArIHNpemUpOwotCVN5c3RlbS5lcnIucHJpbnRsbigic2xvdCA9ICIgKyBzbG90KTsKLQlTeXN0ZW0uZXJyLnByaW50bG4oImxpbWl0ID0gIiArIGxpbWl0KTsKLQkvL3ByaW50U3RhdGUoImVycm9yIik7Ci0JdGhyb3cgbmV3IEVycm9yKCJyZWxlYXNlU2xvdCIpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvU3RyaW5nU3RhY2suamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvU3RyaW5nU3RhY2suamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDI0Yjc1NC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1N0cmluZ1N0YWNrLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nU3RhY2sgZXh0ZW5kcyBTdGFjayB7Ci0gICAgcHVibGljIFN0cmluZyBwZWVrU3RyaW5nKCkgewotCXJldHVybiAoU3RyaW5nKSBzdXBlci5wZWVrKCk7Ci0gICAgfQotCQotICAgIHB1YmxpYyBTdHJpbmcgcG9wU3RyaW5nKCkgewotCXJldHVybiAoU3RyaW5nKSBzdXBlci5wb3AoKTsKLSAgICB9Ci0JCi0gICAgcHVibGljIFN0cmluZyBwdXNoU3RyaW5nKFN0cmluZyB2YWwpIHsKLQlyZXR1cm4gKFN0cmluZykgc3VwZXIucHVzaCh2YWwpOwotICAgIH0JCQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9TdHJpbmdUeXBlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1N0cmluZ1R5cGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGYxODZjMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1N0cmluZ1R5cGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlBhcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotCi1wdWJsaWMgY2xhc3MgU3RyaW5nVHlwZSBleHRlbmRzIFR5cGUgewotICAgIHByb3RlY3RlZCBTdHJpbmdUeXBlKCkge30KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JcmV0dXJuICJzdHJpbmciOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLQlyZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotCXJldHVybiAiTGphdmEvbGFuZy9TdHJpbmc7IjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1NpbXBsZSgpIHsKLQlyZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpIHsKLQlyZXR1cm4gZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZS5TVFJJTkc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHN0cmluZyBpbnRvIGFuIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqIFRoZSB0cmFuc2xhdGlvbiB0byBpbnQgaXMgdW5kZWZpbmVkIHNpbmNlIHN0cmluZ3MgYXJlIGFsd2F5cyBjb252ZXJ0ZWQKLSAgICAgKiB0byByZWFscyBpbiBhcml0aG1ldGljIGV4cHJlc3Npb25zLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBUeXBlIHR5cGUpIHsKLQlpZiAodHlwZSA9PSBUeXBlLkJvb2xlYW4pIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKEJvb2xlYW5UeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlYWwpIHsKLQkgICAgdHJhbnNsYXRlVG8oY2xhc3NHZW4sIG1ldGhvZEdlbiwgKFJlYWxUeXBlKSB0eXBlKTsKLQl9Ci0JZWxzZSBpZiAodHlwZSA9PSBUeXBlLlJlZmVyZW5jZSkgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoUmVmZXJlbmNlVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5pbnRlcm5hbEVycm9yKCk7IC8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgc3RyaW5nIGludG8gYSBzeW50aGVzaXplZCBib29sZWFuLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCUZsb3dMaXN0IGZhbHNlbCA9IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuLCB0eXBlKTsKLQlpbC5hcHBlbmQoSUNPTlNUXzEpOwotCWZpbmFsIEJyYW5jaEhhbmRsZSB0cnVlYyA9IGlsLmFwcGVuZChuZXcgR09UTyhudWxsKSk7Ci0JZmFsc2VsLmJhY2tQYXRjaChpbC5hcHBlbmQoSUNPTlNUXzApKTsKLQl0cnVlYy5zZXRUYXJnZXQoaWwuYXBwZW5kKE5PUCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYSBzdHJpbmcgaW50byBhIHJlYWwgYnkgY2FsbGluZyBzdHJpbmdUb1JlYWwoKSBmcm9tIHRoZQotICAgICAqIGJhc2lzIGxpYnJhcnkuCi0gICAgICoKLSAgICAgKiBAc2VlCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbC5UeXBlI3RyYW5zbGF0ZVRvCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIFJlYWxUeXBlIHR5cGUpIHsKLQlmaW5hbCBDb25zdGFudFBvb2xHZW4gY3BnID0gY2xhc3NHZW4uZ2V0Q29uc3RhbnRQb29sKCk7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlsLmFwcGVuZChuZXcgSU5WT0tFU1RBVElDKGNwZy5hZGRNZXRob2RyZWYoQkFTSVNfTElCUkFSWV9DTEFTUywKLQkJCQkJCSAgICBTVFJJTkdfVE9fUkVBTCwKLQkJCQkJCSAgICBTVFJJTkdfVE9fUkVBTF9TSUcpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIHN0cmluZyBpbnRvIGEgbm9uLXN5bnRoZXNpemVkIGJvb2xlYW4uIEl0IGRvZXMgbm90IHB1c2ggYSAKLSAgICAgKiAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlIGFwcGVuZGVkIHRvIHRoZSAKLSAgICAgKiBmYWxzZSBsaXN0LgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgRmxvd0xpc3QgdHJhbnNsYXRlVG9EZXN5bnRoZXNpemVkKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCAKLQkJCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCQkJICAgICBCb29sZWFuVHlwZSB0eXBlKSB7Ci0JZmluYWwgQ29uc3RhbnRQb29sR2VuIGNwZyA9IGNsYXNzR2VuLmdldENvbnN0YW50UG9vbCgpOwotCWZpbmFsIEluc3RydWN0aW9uTGlzdCBpbCA9IG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKTsKLQotCWlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChjcGcuYWRkTWV0aG9kcmVmKFNUUklOR19DTEFTUywKLQkJCQkJCSAgICAgImxlbmd0aCIsICIoKUkiKSkpOwotCXJldHVybiBuZXcgRmxvd0xpc3QoaWwuYXBwZW5kKG5ldyBJRkVRKG51bGwpKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhwZWN0cyBhIHN0cmluZyBvbiB0aGUgc3RhY2sgYW5kIHB1c2hlcyBhIGJveGVkIHN0cmluZy4KLSAgICAgKiBTdHJpbmdzIGFyZSBhbHJlYWR5IGJveGVkIHNvIHRoZSB0cmFuc2xhdGlvbiBpcyBqdXN0IGEgTk9QLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBSZWZlcmVuY2VUeXBlIHR5cGUpIHsKLQltZXRob2RHZW4uZ2V0SW5zdHJ1Y3Rpb25MaXN0KCkuYXBwZW5kKE5PUCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhIGludGVybmFsIHN0cmluZyBpbnRvIGFuIGV4dGVybmFsIChKYXZhKSBzdHJpbmcuIAotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVGcm9tCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlVG8oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgIENsYXNzIGNsYXp6KSB7Ci0JaWYgKGNsYXp6LmdldE5hbWUoKS5lcXVhbHMoImphdmEubGFuZy5TdHJpbmciKSkgewotCSAgICAvLyBzYW1lIGludGVybmFsIHJlcHJlc2VudGF0aW9uCi0JICAgIG1ldGhvZEdlbi5nZXRJbnN0cnVjdGlvbkxpc3QoKS5hcHBlbmQoTk9QKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsKLQl9Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gZXh0ZXJuYWwgKHByaW1pdGl2ZSkgSmF2YSB0eXBlIGludG8gYSBzdHJpbmcuIAotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVGcm9tCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRnJvbShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgICBDbGFzcyBjbGF6eikgewotCXRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIGNsYXp6KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIG9iamVjdCBvZiB0aGlzIHR5cGUgdG8gaXRzIGJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVCb3goQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sCi0JCQkgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4pIHsKLQl0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCBUeXBlLlJlZmVyZW5jZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyB1bmJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpLmFwcGVuZChOT1ApOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGNsYXNzIG5hbWUgb2YgYW4gaW50ZXJuYWwgdHlwZSdzIGV4dGVybmFsIHJlcHJlc2VudGF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgewotCXJldHVybihTVFJJTkdfQ0xBU1MpOwotICAgIH0KLQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIExPQUQoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IEFMT0FEKHNsb3QpOwotICAgIH0KLQkKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gU1RPUkUoaW50IHNsb3QpIHsKLQlyZXR1cm4gbmV3IEFTVE9SRShzbG90KTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1Rlc3RHZW5lcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvVGVzdEdlbmVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZDVkMDQwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvVGVzdEdlbmVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGU7Ci1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlRlbXBsYXRlOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgVGVzdEdlbmVyYXRvciBleHRlbmRzIE1ldGhvZEdlbmVyYXRvciB7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IENPTlRFWFRfTk9ERV9JTkRFWCA9IDE7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IENVUlJFTlRfTk9ERV9JTkRFWCA9IDQ7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgaW50IElURVJBVE9SX0lOREVYID0gNjsKLQotICAgIHByaXZhdGUgSW5zdHJ1Y3Rpb24gX2Fsb2FkRG9tOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2lsb2FkQ3VycmVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9pbG9hZENvbnRleHQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBJbnN0cnVjdGlvbiBfaXN0b3JlQ3VycmVudDsKLSAgICBwcml2YXRlIGZpbmFsIEluc3RydWN0aW9uIF9pc3RvcmVDb250ZXh0OwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2FzdG9yZUl0ZXJhdG9yOwotICAgIHByaXZhdGUgZmluYWwgSW5zdHJ1Y3Rpb24gX2Fsb2FkSXRlcmF0b3I7Ci0KLSAgICBwdWJsaWMgVGVzdEdlbmVyYXRvcihpbnQgYWNjZXNzX2ZsYWdzLCBUeXBlIHJldHVybl90eXBlLAotCQkJIFR5cGVbXSBhcmdfdHlwZXMsIFN0cmluZ1tdIGFyZ19uYW1lcywKLQkJCSBTdHJpbmcgbWV0aG9kX25hbWUsIFN0cmluZyBjbGFzc19uYW1lLAotCQkJIEluc3RydWN0aW9uTGlzdCBpbCwgQ29uc3RhbnRQb29sR2VuIGNwKSB7Ci0Jc3VwZXIoYWNjZXNzX2ZsYWdzLCByZXR1cm5fdHlwZSwgYXJnX3R5cGVzLCBhcmdfbmFtZXMsIG1ldGhvZF9uYW1lLCAKLQkgICAgICBjbGFzc19uYW1lLCBpbCwgY3ApOwotCQotCV9pbG9hZEN1cnJlbnQgID0gbmV3IElMT0FEKENVUlJFTlRfTk9ERV9JTkRFWCk7Ci0JX2lzdG9yZUN1cnJlbnQgPSBuZXcgSVNUT1JFKENVUlJFTlRfTk9ERV9JTkRFWCk7Ci0JX2lsb2FkQ29udGV4dCAgPSBuZXcgSUxPQUQoQ09OVEVYVF9OT0RFX0lOREVYKTsKLQlfaXN0b3JlQ29udGV4dCAgPSBuZXcgSUxPQUQoQ09OVEVYVF9OT0RFX0lOREVYKTsKLQlfYXN0b3JlSXRlcmF0b3IgPSBuZXcgQVNUT1JFKElURVJBVE9SX0lOREVYKTsKLQlfYWxvYWRJdGVyYXRvciAgPSBuZXcgQUxPQUQoSVRFUkFUT1JfSU5ERVgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SGFuZGxlckluZGV4KCkgewotCXJldHVybiBJTlZBTElEX0lOREVYOwkJLy8gbm90IGF2YWlsYWJsZQotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0SXRlcmF0b3JJbmRleCgpIHsKLQlyZXR1cm4gSVRFUkFUT1JfSU5ERVg7CQkvLyBub3QgYXZhaWxhYmxlCi0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9tSW5kZXgoaW50IGRvbUluZGV4KSB7Ci0JX2Fsb2FkRG9tID0gbmV3IEFMT0FEKGRvbUluZGV4KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZERPTSgpIHsKLQlyZXR1cm4gX2Fsb2FkRG9tOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBsb2FkQ3VycmVudE5vZGUoKSB7Ci0JcmV0dXJuIF9pbG9hZEN1cnJlbnQ7Ci0gICAgfQotCi0gICAgLyoqIGJ5IGRlZmF1bHQgY29udGV4dCBub2RlIGlzIHRoZSBzYW1lIGFzIGN1cnJlbnQgbm9kZS4gTUs0MzcgKi8KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gbG9hZENvbnRleHROb2RlKCkgewotCXJldHVybiBfaWxvYWRDb250ZXh0OwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBzdG9yZUNvbnRleHROb2RlKCkgewotCXJldHVybiBfaXN0b3JlQ29udGV4dDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gc3RvcmVDdXJyZW50Tm9kZSgpIHsKLQlyZXR1cm4gX2lzdG9yZUN1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIHN0b3JlSXRlcmF0b3IoKSB7Ci0JcmV0dXJuIF9hc3RvcmVJdGVyYXRvcjsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIEluc3RydWN0aW9uIGxvYWRJdGVyYXRvcigpIHsKLQlyZXR1cm4gX2Fsb2FkSXRlcmF0b3I7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMb2NhbEluZGV4KFN0cmluZyBuYW1lKSB7Ci0JaWYgKG5hbWUuZXF1YWxzKCJjdXJyZW50IikpIHsKLQkgICAgcmV0dXJuIENVUlJFTlRfTk9ERV9JTkRFWDsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJldHVybiBzdXBlci5nZXRMb2NhbEluZGV4KG5hbWUpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1R5cGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvVHlwZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZThiYjU5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwvVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk2ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbDsKLQotaW1wb3J0IGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5QYXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLkZsb3dMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuQ29uc3RhbnRzOwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgVHlwZSBpbXBsZW1lbnRzIENvbnN0YW50cyB7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIEludCAgICAgICAgPSBuZXcgSW50VHlwZSgpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBSZWFsICAgICAgID0gbmV3IFJlYWxUeXBlKCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIEJvb2xlYW4gICAgPSBuZXcgQm9vbGVhblR5cGUoKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgTm9kZVNldCAgICA9IG5ldyBOb2RlU2V0VHlwZSgpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBTdHJpbmcgICAgID0gbmV3IFN0cmluZ1R5cGUoKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgUmVzdWx0VHJlZSA9IG5ldyBSZXN1bHRUcmVlVHlwZSgpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBSZWZlcmVuY2UgID0gbmV3IFJlZmVyZW5jZVR5cGUoKTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgVm9pZCAgICAgICA9IG5ldyBWb2lkVHlwZSgpOwotCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIE5vZGUgICAgICAgPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuQU5PREUpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBSb290ICAgICAgID0gbmV3IE5vZGVUeXBlKE5vZGVUZXN0LlJPT1QpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBFbGVtZW50ICAgID0gbmV3IE5vZGVUeXBlKE5vZGVUZXN0LkVMRU1FTlQpOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBBdHRyaWJ1dGUgID0gbmV3IE5vZGVUeXBlKE5vZGVUZXN0LkFUVFJJQlVURSk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFRleHQgICAgICAgPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuVEVYVCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIENvbW1lbnQgICAgPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuQ09NTUVOVCk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFByb2Nlc3NpbmdfSW5zdHJ1Y3Rpb24gPSBuZXcgTm9kZVR5cGUoTm9kZVRlc3QuUEkpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHR5cGUuCQotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdG9TdHJpbmcoKTsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGFuZCBvdGhlciBhcmUgaWRlbnRpY2FsIHR5cGVzLgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgdHlwZSBpcyBhIG51bWVyaWMgdHlwZS4gUmVkZWZpbmVkIGluIE51bWJlclR5cGUuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNOdW1iZXIoKSB7Ci0JcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHR5cGUgaGFzIG5vIG9iamVjdCByZXByZXNlbnRhaW9uLiBSZWRlZmluZWQgaW4KLSAgICAgKiBSZXN1bHRUcmVlVHlwZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpbXBsZW1lbnRlZEFzTWV0aG9kKCkgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyB0eXBlIGlzIGEgc2ltcGxlIHR5cGUuIFJlZGVmaW5lZCBpbiBOdW1iZXJUeXBlLAotICAgICAqIEJvb2xlYW5UeXBlIGFuZCBTdHJpbmdUeXBlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGlzU2ltcGxlKCkgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYWJzdHJhY3QgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZSB0b0pDVHlwZSgpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28gdHlwZXMuIFRoaXMgbWVhc3VyZSBpcyB1c2VkIHRvIHNlbGVjdAotICAgICAqIG92ZXJsb2FkZWQgZnVuY3Rpb25zL29wZXJhdG9ycy4gVGhpcyBtZXRob2QgaXMgdHlwaWNhbGx5IHJlZGVmaW5lZCBieQotICAgICAqIHRoZSBzdWJjbGFzc2VzLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZGlzdGFuY2VUbyhUeXBlIHR5cGUpIHsKLQlyZXR1cm4gdHlwZSA9PSB0aGlzID8gMCA6IEludGVnZXIuTUFYX1ZBTFVFOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiBhbiBpbnRlcm5hbCB0eXBlJ3MgZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGFic3RyYWN0IFN0cmluZyB0b1NpZ25hdHVyZSgpOwotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGFuIG9iamVjdCBvZiB0eXBlCi0gICAgICogPGNvZGU+dHlwZTwvY29kZT4uIAotICAgICAqIEV4cGVjdHMgYW4gb2JqZWN0IG9mIHRoZSBmb3JtZXIgdHlwZSBhbmQgcHVzaGVzIGFuIG9iamVjdCBvZiB0aGUgbGF0dGVyLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBUeXBlIHR5cGUpIHsKLQljbGFzc0dlbgotCSAgICAuZ2V0UGFyc2VyKCkKLQkgICAgLm5vdFlldEltcGxlbWVudGVkKHRvU3RyaW5nKCkgKyAiIC0+ICIgKyB0eXBlLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgb2JqZWN0IG9mIHRoaXMgdHlwZSB0byBhbiBvYmplY3Qgb2YgdHlwZSA8Y29kZT50eXBlPC9jb2RlPi4gCi0gICAgICogRXhwZWN0cyBhbiBvYmplY3Qgb2YgdGhlIGZvcm1lciB0eXBlIGFuZCBwdXNoZXMgYW4gb2JqZWN0IG9mIHRoZSBsYXR0ZXIKLSAgICAgKiBpZiBub3QgYm9vbGVhbi4gSWYgdHlwZSA8Y29kZT50eXBlPC9jb2RlPiBpcyBib29sZWFuIHRoZW4gYSBicmFuY2hoYW5kbGUKLSAgICAgKiBsaXN0ICh0byBiZSBhcHBlbmRlZCB0byB0aGUgZmFsc2UgbGlzdCkgaXMgcmV0dXJuZWQuCi0gICAgICovCi0gICAgcHVibGljIEZsb3dMaXN0IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgCi0JCQkJCSAgICAgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkJCSAgICAgVHlwZSB0eXBlKSB7Ci0JRmxvd0xpc3QgZmwgPSBudWxsOwotCWlmICh0eXBlID09IFR5cGUuQm9vbGVhbikgewotCSAgICBmbCA9IHRyYW5zbGF0ZVRvRGVzeW50aGVzaXplZChjbGFzc0dlbiwgbWV0aG9kR2VuLAotCQkJCQkgIChCb29sZWFuVHlwZSl0eXBlKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHRyYW5zbGF0ZVRvKGNsYXNzR2VuLCBtZXRob2RHZW4sIHR5cGUpOwotCX0KLQlyZXR1cm4gZmw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGFuIG5vbi1zeW50aGVzaXplZCBib29sZWFuLiBJdAotICAgICAqIGRvZXMgbm90IHB1c2ggYSAwIG9yIGEgMSBidXQgaW5zdGVhZCByZXR1cm5zIGJyYW5jaGhhbmRsZSBsaXN0IHRvIGJlCi0gICAgICogYXBwZW5kZWQgdG8gdGhlIGZhbHNlIGxpc3QuCi0gICAgICovIAotICAgIHB1YmxpYyBGbG93TGlzdCB0cmFuc2xhdGVUb0Rlc3ludGhlc2l6ZWQoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIAotCQkJCQkgICAgIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJCQkgICAgIEJvb2xlYW5UeXBlIHR5cGUpIHsKLQljbGFzc0dlbgotCSAgICAuZ2V0UGFyc2VyKCkKLQkgICAgLm5vdFlldEltcGxlbWVudGVkKHRvU3RyaW5nKCkgKyAiIC0+ICIgKyB0eXBlLnRvU3RyaW5nKCkpOwotCXJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zbGF0ZXMgYW4gb2JqZWN0IG9mIHRoaXMgdHlwZSB0byB0aGUgZXh0ZXJuYWwgKEphdmEpIHR5cGUgZGVub3RlZAotICAgICAqIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPi4gVGhpcyBtZXRob2QgaXMgdXNlZCB0byB0cmFuc2xhdGUgcGFyYW1ldGVycyAKLSAgICAgKiB3aGVuIGV4dGVybmFsIGZ1bmN0aW9ucyBhcmUgY2FsbGVkLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgQ2xhc3MgY2xhenopIHsKLQljbGFzc0dlbi5nZXRQYXJzZXIoKS5ub3RZZXRJbXBsZW1lbnRlZCh0b1N0cmluZygpICsgIiAtPiAiICsKLQkJCQkJICAgICAgIGNsYXp6LmdldENsYXNzKCkudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBleHRlcm5hbCAoSmF2YSkgdHlwZSBkZW5vdGVkIGJ5IDxjb2RlPmNsYXp6PC9jb2RlPiB0byAKLSAgICAgKiBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlLiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHRyYW5zbGF0ZSByZXR1cm4gdmFsdWVzIAotICAgICAqIHdoZW4gZXh0ZXJuYWwgZnVuY3Rpb25zIGFyZSBjYWxsZWQuCi0gICAgICovIAotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZUZyb20oQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIE1ldGhvZEdlbmVyYXRvciBtZXRob2RHZW4sIAotCQkJICAgICAgQ2xhc3MgY2xhenopIHsKLQljbGFzc0dlbgotCSAgICAuZ2V0UGFyc2VyKCkKLQkgICAgLm5vdFlldEltcGxlbWVudGVkKGNsYXp6LmdldENsYXNzKCkudG9TdHJpbmcoKSArICIgLT4gIgotCQkJICAgICAgICsgdG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyBib3hlZCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8gCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlQm94KENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLAotCQkJICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JY2xhc3NHZW4KLQkgICAgLmdldFBhcnNlcigpCi0JICAgIC5ub3RZZXRJbXBsZW1lbnRlZCh0b1N0cmluZygpICsgIiAtPiBib3hlZCAiICsgdG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhbnNsYXRlcyBhbiBvYmplY3Qgb2YgdGhpcyB0eXBlIHRvIGl0cyB1bmJveGVkIHJlcHJlc2VudGF0aW9uLgotICAgICAqLyAKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVVbkJveChDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwKLQkJCSAgICAgICBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuKSB7Ci0JY2xhc3NHZW4KLQkgICAgLmdldFBhcnNlcigpCi0JICAgIC5ub3RZZXRJbXBsZW1lbnRlZCh0b1N0cmluZygpICsgIiAtPiB1bmJveGVkICIgKyB0b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBuYW1lIG9mIGFuIGludGVybmFsIHR5cGUncyBleHRlcm5hbCByZXByZXNlbnRhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLQlyZXR1cm4oRU1QVFlTVFJJTkcpOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBBREQoKSB7Ci0JcmV0dXJuIG51bGw7CQkvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFNVQigpIHsKLQlyZXR1cm4gbnVsbDsJCS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTVVMKCkgewotCXJldHVybiBudWxsOwkJLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBESVYoKSB7Ci0JcmV0dXJuIG51bGw7CQkvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCi0gICAgcHVibGljIEluc3RydWN0aW9uIFJFTSgpIHsKLQlyZXR1cm4gbnVsbDsJCS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gTkVHKCkgewotCXJldHVybiBudWxsOwkJLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBMT0FEKGludCBzbG90KSB7Ci0JcmV0dXJuIG51bGw7CQkvLyBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkCi0gICAgfQotCQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBTVE9SRShpbnQgc2xvdCkgewotCXJldHVybiBudWxsOwkJLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQotICAgIHB1YmxpYyBJbnN0cnVjdGlvbiBQT1AoKSB7Ci0JcmV0dXJuIFBPUDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gR1QoYm9vbGVhbiB0b3plcm8pIHsKLQlyZXR1cm4gbnVsbDsJCS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gR0UoYm9vbGVhbiB0b3plcm8pIHsKLQlyZXR1cm4gbnVsbDsJCS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gTFQoYm9vbGVhbiB0b3plcm8pIHsKLQlyZXR1cm4gbnVsbDsJCS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgQnJhbmNoSW5zdHJ1Y3Rpb24gTEUoYm9vbGVhbiB0b3plcm8pIHsKLQlyZXR1cm4gbnVsbDsJCS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gQ01QKGJvb2xlYW4gbGVzcykgewotCXJldHVybiBudWxsOwkJLy8gc2hvdWxkIG5ldmVyIGJlIGNhbGxlZAotICAgIH0KLQkKLSAgICBwdWJsaWMgSW5zdHJ1Y3Rpb24gRFVQKCkgewotCXJldHVybiBEVVA7CS8vIGRlZmF1bHQKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1R5cGVDaGVja0Vycm9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1R5cGVDaGVja0Vycm9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNkYTM5ZTguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9UeXBlQ2hlY2tFcnJvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlN5bnRheFRyZWVOb2RlOwotCi1wdWJsaWMgY2xhc3MgVHlwZUNoZWNrRXJyb3IgZXh0ZW5kcyBFeGNlcHRpb24gewotICAgIEVycm9yTXNnIF9lcnJvciA9IG51bGw7Ci0gICAgU3ludGF4VHJlZU5vZGUgX25vZGUgPSBudWxsOwotCQotICAgIHB1YmxpYyBUeXBlQ2hlY2tFcnJvcihTeW50YXhUcmVlTm9kZSBub2RlKSB7Ci0Jc3VwZXIoKTsKLQlfbm9kZSA9IG5vZGU7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGVDaGVja0Vycm9yKEVycm9yTXNnIGVycm9yKSB7Ci0Jc3VwZXIoKTsKLQlfZXJyb3IgPSBlcnJvcjsKLSAgICB9Ci0JCi0gICAgcHVibGljIFR5cGVDaGVja0Vycm9yKGludCBjb2RlLCBPYmplY3QgcGFyYW0pIHsKLQlzdXBlcigpOwotCV9lcnJvciA9IG5ldyBFcnJvck1zZyhjb2RlLCBwYXJhbSk7Ci0gICAgfQotCi0gICAgcHVibGljIFR5cGVDaGVja0Vycm9yKGludCBjb2RlLCBPYmplY3QgcGFyYW0xLCBPYmplY3QgcGFyYW0yKSB7Ci0Jc3VwZXIoKTsKLQlfZXJyb3IgPSBuZXcgRXJyb3JNc2coY29kZSwgcGFyYW0xLCBwYXJhbTIpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JU3RyaW5nIHJlc3VsdDsKLQotCWlmIChfZXJyb3IgIT0gbnVsbCkgewotCSAgICByZXN1bHQgPSBfZXJyb3IudG9TdHJpbmcoKTsKLQl9Ci0JZWxzZSBpZiAoX25vZGUgIT0gbnVsbCkgewotCSAgICByZXN1bHQgPSAiVHlwZSBjaGVjayBlcnJvciBpbiAiICsgX25vZGUudG9TdHJpbmcoKSArICIuIjsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJlc3VsdCA9ICJUeXBlIGNoZWNrIGVycm9yIChubyBsaW5lIGluZm9ybWF0aW9uKS4iOwotCX0KLQotCXJldHVybiByZXN1bHQ7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9VdGlsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1V0aWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2U1ZDI3My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1V0aWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE1OSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsOwotCi1pbXBvcnQgZGUuZnViLmJ5dGVjb2RlLmdlbmVyaWMuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgVXRpbCB7Ci0gICAgc3RhdGljIHB1YmxpYyBjaGFyIGZpbGVzZXA7Ci0KLSAgICBzdGF0aWMgewotCVN0cmluZyB0ZW1wID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLnNlcGFyYXRvciIsICIvIik7Ci0JZmlsZXNlcCA9IHRlbXAuY2hhckF0KDApOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vRXh0TmFtZShTdHJpbmcgbmFtZSkgewotCWZpbmFsIGludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTsKLQlyZXR1cm4gbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXggPj0gMCA/IGluZGV4IDogbmFtZS5sZW5ndGgoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VhcmNoIGZvciBib3RoIHNsYXNoZXMgaW4gb3JkZXIgdG8gc3VwcG9ydCBVUkxzIGFuZCAKLSAgICAgKiBmaWxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBiYXNlTmFtZShTdHJpbmcgbmFtZSkgewotCWludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy8nKTsKLQlpZiAoaW5kZXggPCAwKSB7Ci0JICAgIGluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZignXFwnKTsKLQl9Ci0JcmV0dXJuIG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VhcmNoIGZvciBib3RoIHNsYXNoZXMgaW4gb3JkZXIgdG8gc3VwcG9ydCBVUkxzIGFuZCAKLSAgICAgKiBmaWxlcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBwYXRoTmFtZShTdHJpbmcgbmFtZSkgewotCWludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy8nKTsKLQlpZiAoaW5kZXggPCAwKSB7Ci0JICAgIGluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZignXFwnKTsKLQl9Ci0JcmV0dXJuIG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4ICsgMSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVwbGFjZSBhbGwgaWxsZWdhbCBKYXZhIGNoYXJzIGJ5ICdfJy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0phdmFOYW1lKFN0cmluZyBuYW1lKSB7Ci0JZmluYWwgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotCWNoYXIgY2ggPSBuYW1lLmNoYXJBdCgwKTsKLQlyZXN1bHQuYXBwZW5kKENoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyU3RhcnQoY2gpID8gY2ggOiAnXycpOwotCi0JZmluYWwgaW50IG4gPSBuYW1lLmxlbmd0aCgpOwotCWZvciAoaW50IGkgPSAxOyBpIDwgbjsgaSsrKSB7Ci0JICAgIGNoID0gbmFtZS5jaGFyQXQoaSk7Ci0JICAgIHJlc3VsdC5hcHBlbmQoQ2hhcmFjdGVyLmlzSmF2YUlkZW50aWZpZXJQYXJ0KGNoKSAgPyBjaCA6ICdfJyk7Ci0JfQotCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIFR5cGUgZ2V0SkNSZWZUeXBlKFN0cmluZyBzaWduYXR1cmUpIHsKLQlyZXR1cm4gVHlwZS5nZXRUeXBlKHNpZ25hdHVyZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgaW50ZXJuYWxOYW1lKFN0cmluZyBjbmFtZSkgewotCXJldHVybiBjbmFtZS5yZXBsYWNlKCcuJywgZmlsZXNlcCk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50bG4oU3RyaW5nIHMpIHsKLQlpZiAoZmFsc2UpIHsKLQkgICAgU3lzdGVtLm91dC5wcmludGxuKHMpOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnRsbihjaGFyIGNoKSB7Ci0JLyoKLQkgIC8vCWlmIChQYXJzZXIuZGVidWcoKSkgewotCSAgaWYgKGZhbHNlKSB7Ci0JICBTeXN0ZW0ub3V0LnByaW50bG4oY2gpOwotCSAgfQotCSovCi0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIFRSQUNFMSgpIHsKLQlTeXN0ZW0ub3V0LnByaW50bG4oIlRSQUNFMSIpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBUUkFDRTIoKSB7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJUUkFDRTIiKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgVFJBQ0UzKCkgewotCVN5c3RlbS5vdXQucHJpbnRsbigiVFJBQ0UzIik7Ci0gICAgfQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1ZvaWRUeXBlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsL1ZvaWRUeXBlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI3OWMxM2IuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbC9Wb2lkVHlwZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWw7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZTsKLWltcG9ydCBkZS5mdWIuYnl0ZWNvZGUuZ2VuZXJpYy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuUGFyc2VyOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgVm9pZFR5cGUgZXh0ZW5kcyBUeXBlIHsKLSAgICBwcm90ZWN0ZWQgVm9pZFR5cGUoKSB7fQotCi0gICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQlyZXR1cm4gInZvaWQiOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlkZW50aWNhbFRvKFR5cGUgb3RoZXIpIHsKLQlyZXR1cm4gdGhpcyA9PSBvdGhlcjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHRvU2lnbmF0dXJlKCkgewotCXJldHVybiAiViI7Ci0gICAgfQotCi0gICAgcHVibGljIGRlLmZ1Yi5ieXRlY29kZS5nZW5lcmljLlR5cGUgdG9KQ1R5cGUoKSB7Ci0JcmV0dXJuIG51bGw7CS8vIHNob3VsZCBuZXZlciBiZSBjYWxsZWQKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgdm9pZCBpbnRvIGFuIG9iamVjdCBvZiBpbnRlcm5hbCB0eXBlIDxjb2RlPnR5cGU8L2NvZGU+LgotICAgICAqIFRoaXMgdHJhbnNsYXRpb24gaXMgbmVlZGVkIHdoZW4gY2FsbGluZyBleHRlcm5hbCBmdW5jdGlvbnMKLSAgICAgKiB0aGF0IHJldHVybiB2b2lkLgotICAgICAqCi0gICAgICogQHNlZQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLnV0aWwuVHlwZSN0cmFuc2xhdGVUbwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zbGF0ZVRvKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBNZXRob2RHZW5lcmF0b3IgbWV0aG9kR2VuLCAKLQkJCSAgICBUeXBlIHR5cGUpIHsKLQlpZiAodHlwZSA9PSBUeXBlLlN0cmluZykgewotCSAgICB0cmFuc2xhdGVUbyhjbGFzc0dlbiwgbWV0aG9kR2VuLCAoU3RyaW5nVHlwZSkgdHlwZSk7Ci0JfQotCWVsc2UgewotCSAgICBjbGFzc0dlbi5nZXRQYXJzZXIoKS5pbnRlcm5hbEVycm9yKCk7IC8vIHVuZGVmaW5lZAotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGEgdm9pZCBpbnRvIGEgc3RyaW5nIGJ5IHB1c2hpbmcgdGhlIGVtcHR5IHN0cmluZyAnJy4KLSAgICAgKgotICAgICAqIEBzZWUJb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlR5cGUjdHJhbnNsYXRlVG8KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2xhdGVUbyhDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgU3RyaW5nVHlwZSB0eXBlKSB7Ci0JZmluYWwgSW5zdHJ1Y3Rpb25MaXN0IGlsID0gbWV0aG9kR2VuLmdldEluc3RydWN0aW9uTGlzdCgpOwotCWlsLmFwcGVuZChuZXcgUFVTSChjbGFzc0dlbi5nZXRDb25zdGFudFBvb2woKSwgIiIpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmFuc2xhdGVzIGFuIGV4dGVybmFsIChwcmltaXRpdmUpIEphdmEgdHlwZSBpbnRvIGEgdm9pZC4KLSAgICAgKiBPbmx5IGFuIGV4dGVybmFsICJ2b2lkIiBjYW4gYmUgY29udmVydGVkIHRvIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdHJhbnNsYXRlRnJvbShDbGFzc0dlbmVyYXRvciBjbGFzc0dlbiwgTWV0aG9kR2VuZXJhdG9yIG1ldGhvZEdlbiwgCi0JCQkgICAgICBDbGFzcyBjbGF6eikgewotCWlmICghY2xhenouZ2V0TmFtZSgpLmVxdWFscygidm9pZCIpKSB7Ci0JICAgIGNsYXNzR2VuLmdldFBhcnNlcigpLmludGVybmFsRXJyb3IoKTsgLy8gdW5kZWZpbmVkCi0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3hwYXRoLmN1cCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3hwYXRoLmN1cApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGNhMTY5NS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci94cGF0aC5jdXAKKysrIC9kZXYvbnVsbApAQCAtMSw4NjQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogQ29weXJpZ2h0IDIwMDAgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgotICogCi0gKiBUaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wcmlldGFyeSBpbmZvcm1hdGlvbiBvZiBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuICAKLSAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMuCi0gKiAgCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqICAKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLmlvLlN0cmluZ1JlYWRlcjsKLWltcG9ydCBqYXZhX2N1cC5ydW50aW1lLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5BeGlzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5PcGVyYXRvcnM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLkVycm9yTXNnOwotCi1wYXJzZXIgY29kZSB7OgotICAgIC8qKgotICAgICAqIFVzZWQgYnkgZnVuY3Rpb24gY2FsbHMgd2l0aCBubyBhcmdzLgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgZmluYWwgVmVjdG9yIEVtcHR5QXJncyA9IG5ldyBWZWN0b3IoMCk7Ci0KLSAgICAvKioKLSAgICAgKiBSZWZlcmVuY2UgdG8gbm9uLWV4aXN0aW5nIHZhcmlhYmxlLgotICAgICAqLwotICAgIHN0YXRpYyBwdWJsaWMgZmluYWwgVmFyaWFibGVSZWYgRHVtbXlWYXJSZWYgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHRoZSBQYXJzZXIgY2xhc3MuCi0gICAgICovCi0gICAgcHJpdmF0ZSBQYXJzZXIgX3BhcnNlcjsKLSAgICBwcml2YXRlIFhTTFRDICBfeHNsdGM7Ci0KLSAgICAvKioKLSAgICAgKiBMaW5lIG51bWJlciB3aGVyZSB0aGlzIGV4cHJlc3Npb24vcGF0dGVybiB3YXMgZGVjbGFyZWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnQgX2xpbmVOdW1iZXIgPSAwOwotCi0gICAgLyoqCi0gICAgICogUmVmZXJlbmNlIHRvIHRoZSBzeW1ib2wgdGFibGUuCi0gICAgICovCi0gICAgcHVibGljIFN5bWJvbFRhYmxlIF9zeW1ib2xUYWJsZTsKLQotICAgIHB1YmxpYyBYUGF0aFBhcnNlcihQYXJzZXIgcGFyc2VyKSB7Ci0gICAgICAgIF9wYXJzZXIgPSBwYXJzZXI7Ci0JX3hzbHRjID0gcGFyc2VyLmdldFhTTFRDKCk7Ci0gICAgICAgIF9zeW1ib2xUYWJsZSA9IHBhcnNlci5nZXRTeW1ib2xUYWJsZSgpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcigpIHsKLSAgICAgICAgcmV0dXJuIF9saW5lTnVtYmVyOwotICAgIH0KLQotICAgIHB1YmxpYyBRTmFtZSBnZXRRTmFtZShTdHJpbmcgbmFtZSkgewotICAgICAgICAgIHJldHVybiBfcGFyc2VyLmdldFFOYW1lKG5hbWUpOwotICAgIH0gICAgCi0KLSAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aURvY3VtZW50KGJvb2xlYW4gZmxhZykgewotICAgICAgICAgIF94c2x0Yy5zZXRNdWx0aURvY3VtZW50KGZsYWcpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZmluZE5vZGVUeXBlKGludCBheGlzLCBPYmplY3QgdGVzdCkgewotCWlmICh0ZXN0ID09IG51bGwpIHsgIC8vICoKLSAgICAgICAgICAgIHJldHVybiBheGlzID09IEF4aXMuQVRUUklCVVRFCi0gICAgICAgICAgICAgICAgICAgPyBOb2RlVGVzdC5BVFRSSUJVVEUKLSAgICAgICAgICAgICAgICAgICA6IE5vZGVUZXN0LkVMRU1FTlQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAodGVzdCBpbnN0YW5jZW9mIEludGVnZXIpIHsKLSAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpdGVzdCkuaW50VmFsdWUoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLQkgICAgUU5hbWUgbmFtZSA9IChRTmFtZSl0ZXN0OwotICAgICAgICAgICAgaWYgKG5hbWUuZ2V0UHJlZml4KCkgPT0gbnVsbCB8fCBuYW1lLmdldE5hbWVzcGFjZSgpID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9jYWwgPSBuYW1lLmdldExvY2FsUGFydCgpOwotCSAgICAgICAgaWYgKGxvY2FsLmVxdWFscygiKiIpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4oTm9kZVRlc3QuRUxFTUVOVCk7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAobG9jYWwuZXF1YWxzKCJAKiIpKQotICAgICAgICAgICAgICAgICAgICByZXR1cm4oTm9kZVRlc3QuQVRUUklCVVRFKTsKLQkgICAgICAgIGlmIChsb2NhbC5zdGFydHNXaXRoKCJAIikpCi0gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuZXcgUU5hbWUobnVsbCxudWxsLGxvY2FsKTsKLSAgICAgICAgICAgIH0KLQkgICAgcmV0dXJuIGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUKLQkJPyBfeHNsdGMucmVnaXN0ZXJBdHRyaWJ1dGUobmFtZSkKLQkJOiBfeHNsdGMucmVnaXN0ZXJFbGVtZW50KG5hbWUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFyc2UgdGhlIGV4cHJlc3Npb24gcGFzc2VkIHRvIHRoZSBjdXJyZW50IHNjYW5uZXIuIElmIHRoaXMKLSAgICAgKiBleHByZXNzaW9uIGNvbnRhaW5zIHJlZmVyZW5jZXMgdG8gbG9jYWwgdmFyaWFibGVzIGFuZCBpdCB3aWxsIGJlIAotICAgICAqIGNvbXBpbGVkIGluIGFuIGV4dGVybmFsIG1vZHVsZSAobm90IGluIHRoZSBtYWluIGNsYXNzKSByZXF1ZXN0IAotICAgICAqIHRoZSBjdXJyZW50IHRlbXBsYXRlIHRvIGNyZWF0ZSBhIG5ldyB2YXJpYWJsZSBzdGFjayBmcmFtZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsaW5lTnVtYmVyIExpbmUgd2hlcmUgdGhlIGN1cnJlbnQgZXhwcmVzc2lvbiBpcyBkZWZpbmVkLgotICAgICAqIEBwYXJhbSBleHRlcm5hbCAgIFNldCB0byA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgZXhwcmVzc2lvbiBpcwotICAgICAqICAgICAgICAgICAgICAgICAgIGNvbXBpbGVkIGluIGEgc2VwYXJhdGUgbW9kdWxlLgotICAgICAqIAotICAgICAqLwotICAgIHB1YmxpYyBTeW1ib2wgcGFyc2UoaW50IGxpbmVOdW1iZXIpIHRocm93cyBFeGNlcHRpb24gewotICAgICAgICB0cnkgewotCSAgICBfbGluZU51bWJlciA9IGxpbmVOdW1iZXI7Ci0JICAgIHJldHVybiBzdXBlci5wYXJzZSgpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChJbGxlZ2FsQ2hhckV4Y2VwdGlvbiBlKSB7Ci0JICAgIGFkZEVycm9yKG5ldyBFcnJvck1zZygiSWxsZWdhbCBjaGFyYWN0ZXIgJyIgKyBlLmdldE1lc3NhZ2UoKSArCi0JICAgIAkiJyBpbiBYUGF0aCBleHByZXNzaW9uLiIsIGxpbmVOdW1iZXIpKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMb29rdXAgYSB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgaW4gdGhlIHN5bWJvbCB0YWJsZSBnaXZlbiBpdHMgbmFtZS4gCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBzeW1ib2wgYmVpbmcgbG9va2VkIHVwLgotICAgICAqLwotICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIGxvb2t1cE5hbWUoUU5hbWUgbmFtZSkgewotICAgICAgICAvLyBJcyBpdCBhIGxvY2FsIHZhciBvciBwYXJhbSA/Ci0gICAgICAgIGZpbmFsIFN5bnRheFRyZWVOb2RlIHJlc3VsdCA9IF9wYXJzZXIubG9va3VwVmFyaWFibGUobmFtZSk7Ci0JaWYgKHJlc3VsdCAhPSBudWxsKQotICAgICAgICAgICAgcmV0dXJuKHJlc3VsdCk7Ci0gICAgICAgIGVsc2UKLQkgICAgcmV0dXJuKF9zeW1ib2xUYWJsZS5sb29rdXBOYW1lKG5hbWUpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgdm9pZCBhZGRFcnJvcihFcnJvck1zZyBlcnJvcikgewotICAgICAgICAvL19wYXJzZXIuYWRkRXJyb3IoZXJyb3IpOwotCV9wYXJzZXIucmVwb3J0RXJyb3IoQ29uc3RhbnRzLkVSUk9SLCBlcnJvcik7Ci0gICAgfSAKLSAgICAgICAgICAgCi0gICAgcHVibGljIHZvaWQgcmVwb3J0X2Vycm9yKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgaW5mbykgewotICAgICAgICAvLyBlbXB0eQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHJlcG9ydF9mYXRhbF9lcnJvcihTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IGluZm8pIHsKLSAgICAgICAgLy8gZW1wdHkKLSAgICB9Ci06fQotCi10ZXJtaW5hbCBTTEFTSCwgRE9ULCBMQlJBQ0ssIFJCUkFDSywgVkJBUiwgTFBBUkVOLCBSUEFSRU4sIFNUQVIsIENPTU1BOwotdGVybWluYWwgRE9MTEFSLCBBVFNJR047Ci10ZXJtaW5hbCBERE9ULCBEQ09MT04sIERTTEFTSDsKLXRlcm1pbmFsIEVRLCBORTsKLXRlcm1pbmFsIExULCBHVCwgTEUsIEdFOwotdGVybWluYWwgUExVUywgTUlOVVMsIERJViwgTU9EOwotdGVybWluYWwgU3RyaW5nIExpdGVyYWw7Ci10ZXJtaW5hbCBTdHJpbmcgUU5BTUU7Ci10ZXJtaW5hbCBJRCwgS0VZLCBURVhULCBOT0RFLCBPUiwgQU5ELCBDT01NRU5ULCBQSSwgUFJFQ0VESU5HU0lCTElORzsKLXRlcm1pbmFsIFNFTEYsIFBBUkVOVCwgQ0hJTEQsIEFUVFJJQlVURSwgQU5DRVNUT1IsIEFOQ0VTVE9ST1JTRUxGLCBERVNDRU5EQU5UOyAKLXRlcm1pbmFsIERFU0NFTkRBTlRPUlNFTEYsIEZPTExPV0lORywgRk9MTE9XSU5HU0lCTElORywgTkFNRVNQQUNFLCBQUkVDRURJTkc7Ci10ZXJtaW5hbCBEb3VibGUgUkVBTDsKLXRlcm1pbmFsIEludGVnZXIgSU5UOwotdGVybWluYWwgUEFUVEVSTiwgRVhQUkVTU0lPTjsKLQotbm9uIHRlcm1pbmFsIFN5bnRheFRyZWVOb2RlIFRvcExldmVsOwotICAgIAotbm9uIHRlcm1pbmFsIEV4cHJlc3Npb24gRXhwciwgQXJndW1lbnQsIExvY2F0aW9uUGF0aDsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIFByZWRpY2F0ZSwgRmlsdGVyRXhwciwgU3RlcDsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIE9yRXhwciwgQW5kRXhwciwgRXF1YWxpdHlFeHByOwotbm9uIHRlcm1pbmFsIEV4cHJlc3Npb24gUmVsYXRpb25hbEV4cHIsIEFkZGl0aXZlRXhwcjsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIE11bHRpcGxpY2F0aXZlRXhwciwgVW5hcnlFeHByOwotbm9uIHRlcm1pbmFsIEV4cHJlc3Npb24gVmFyaWFibGVSZWZlcmVuY2UsIEZ1bmN0aW9uQ2FsbDsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIFByaW1hcnlFeHByLCBVbmlvbkV4cHIsIFBhdGhFeHByLCBBYmJyZXZpYXRlZFN0ZXA7Ci1ub24gdGVybWluYWwgRXhwcmVzc2lvbiBSZWxhdGl2ZUxvY2F0aW9uUGF0aCwgQWJicmV2aWF0ZWRSZWxhdGl2ZUxvY2F0aW9uUGF0aDsKLW5vbiB0ZXJtaW5hbCBFeHByZXNzaW9uIEFic29sdXRlTG9jYXRpb25QYXRoLCBBYmJyZXZpYXRlZEFic29sdXRlTG9jYXRpb25QYXRoOwotCi1ub24gdGVybWluYWwgT2JqZWN0IE5vZGVUZXN0LCBOYW1lVGVzdDsKLQotbm9uIHRlcm1pbmFsIElkS2V5UGF0dGVybiBJZEtleVBhdHRlcm47Ci1ub24gdGVybWluYWwgUGF0dGVybiBQYXR0ZXJuOwotbm9uIHRlcm1pbmFsIFBhdHRlcm4gTG9jYXRpb25QYXRoUGF0dGVybjsKLW5vbiB0ZXJtaW5hbCBSZWxhdGl2ZVBhdGhQYXR0ZXJuIFJlbGF0aXZlUGF0aFBhdHRlcm47Ci1ub24gdGVybWluYWwgU3RlcFBhdHRlcm4gU3RlcFBhdHRlcm47Ci1ub24gdGVybWluYWwgT2JqZWN0IE5vZGVUZXN0UGF0dGVybiwgTmFtZVRlc3RQYXR0ZXJuOwotCi1ub24gdGVybWluYWwgVmVjdG9yIFByZWRpY2F0ZXMsIE5vbmVtcHR5QXJndW1lbnRMaXN0Owotbm9uIHRlcm1pbmFsIFFOYW1lIFFOYW1lLCBGdW5jdGlvbk5hbWUsIFZhcmlhYmxlTmFtZTsKLW5vbiB0ZXJtaW5hbCBJbnRlZ2VyIEF4aXNOYW1lLCBBeGlzU3BlY2lmaWVyOwotbm9uIHRlcm1pbmFsIEludGVnZXIgQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXI7Ci0KLXByZWNlZGVuY2UgbGVmdCBWQkFSOwotcHJlY2VkZW5jZSBsZWZ0IE9SOwotcHJlY2VkZW5jZSBsZWZ0IEFORDsKLXByZWNlZGVuY2Ugbm9uYXNzb2MgRVEsIE5FOwotcHJlY2VkZW5jZSBsZWZ0IExULCBHVCwgTEUsIEdFOwotICAgIAotcHJlY2VkZW5jZSBsZWZ0IFBMVVMsIE1JTlVTOwotcHJlY2VkZW5jZSBsZWZ0IERJViwgTU9ELCBTVEFSOwotcHJlY2VkZW5jZSBsZWZ0IERPTExBUjsKLXByZWNlZGVuY2UgbGVmdCBBVFNJR047Ci1wcmVjZWRlbmNlIHJpZ2h0IERDT0xPTjsKLQotc3RhcnQgd2l0aCBUb3BMZXZlbDsKLQotVG9wTGV2ZWwgOjo9IFBBVFRFUk4gUGF0dGVybjpwYXR0ZXJuCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBwYXR0ZXJuOyA6fQotCi0gICAgICAgICAgICB8IEVYUFJFU1NJT04gRXhwcjpleHByCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBleHByOyA6fTsKLQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFBhdHRlcm5zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi0KLVBhdHRlcm4gOjo9IExvY2F0aW9uUGF0aFBhdHRlcm46bHBwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBscHA7IDp9Ci0KLSAgICAgICAgICAgIHwgTG9jYXRpb25QYXRoUGF0dGVybjpscHAgVkJBUiBQYXR0ZXJuOnAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBbHRlcm5hdGl2ZVBhdHRlcm4obHBwLCBwKTsgIDp9OwotCi1Mb2NhdGlvblBhdGhQYXR0ZXJuIDo6PSBTTEFTSAotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEFic29sdXRlUGF0aFBhdHRlcm4obnVsbCk7IDp9Ci0KLSAgICAgICAgICAgIHwgU0xBU0ggUmVsYXRpdmVQYXRoUGF0dGVybjpycHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBYnNvbHV0ZVBhdGhQYXR0ZXJuKHJwcCk7IDp9Ci0KLSAgICAgICAgICAgIHwgSWRLZXlQYXR0ZXJuOmlrcAotICAgICAgICAgICAgezogUkVTVUxUID0gaWtwOyA6fQotCi0gICAgICAgICAgICB8IElkS2V5UGF0dGVybjppa3AgU0xBU0ggUmVsYXRpdmVQYXRoUGF0dGVybjpycHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBQYXJlbnRQYXR0ZXJuKGlrcCwgcnBwKTsgOn0KLQotICAgICAgICAgICAgfCBJZEtleVBhdHRlcm46aWtwIERTTEFTSCBSZWxhdGl2ZVBhdGhQYXR0ZXJuOnJwcAotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEFuY2VzdG9yUGF0dGVybihpa3AsIHJwcCk7IDp9Ci0KLSAgICAgICAgICAgIHwgRFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm46cnBwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgQW5jZXN0b3JQYXR0ZXJuKHJwcCk7IDp9Ci0KLSAgICAgICAgICAgIHwgUmVsYXRpdmVQYXRoUGF0dGVybjpycHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IHJwcDsgOn07Ci0KLUlkS2V5UGF0dGVybiA6Oj0gSUQgTFBBUkVOIExpdGVyYWw6bCBSUEFSRU4KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJZFBhdHRlcm4obCk7IDp9Ci0KLSAgICAgICAgICAgIHwgS0VZIExQQVJFTiBMaXRlcmFsOmwxIENPTU1BIExpdGVyYWw6bDIgUlBBUkVOCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgS2V5UGF0dGVybihsMSwgbDIpOyA6fTsKLQotUmVsYXRpdmVQYXRoUGF0dGVybiA6Oj0gU3RlcFBhdHRlcm46c3AKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IHNwOyA6fQotCi0gICAgICAgICAgICB8IFN0ZXBQYXR0ZXJuOnNwIFNMQVNIIFJlbGF0aXZlUGF0aFBhdHRlcm46cnBwCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgUGFyZW50UGF0dGVybihzcCwgcnBwKTsgOn0KLQotICAgICAgICAgICAgfCBTdGVwUGF0dGVybjpzcCBEU0xBU0ggUmVsYXRpdmVQYXRoUGF0dGVybjpycHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBbmNlc3RvclBhdHRlcm4oc3AsIHJwcCk7IDp9OwotCi1TdGVwUGF0dGVybiA6Oj0gTm9kZVRlc3RQYXR0ZXJuOm50Ci0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgU3RlcFBhdHRlcm4oQXhpcy5DSElMRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKEF4aXMuQ0hJTEQsIG50KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIDp9Ci0KLSAgICAgICAgICAgIHwgTm9kZVRlc3RQYXR0ZXJuOm50IFByZWRpY2F0ZXM6cHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBTdGVwUGF0dGVybihBeGlzLkNISUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5maW5kTm9kZVR5cGUoQXhpcy5DSElMRCwgbnQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBwKTsKLSAgICAgICAgICAgIDp9Ci0KLSAgICAgICAgICAgIHwgQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXI6YXhpcyBOb2RlVGVzdFBhdHRlcm46bnQKLSAgICAgICAgICAgIHs6IFJFU1VMVD1uZXcgU3RlcFBhdHRlcm4oYXhpcy5pbnRWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKGF4aXMuaW50VmFsdWUoKSwgbnQpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgICAgIDp9Ci0KLQkgICAgfCBDaGlsZE9yQXR0cmlidXRlQXhpc1NwZWNpZmllcjpheGlzCi0JCSAgTm9kZVRlc3RQYXR0ZXJuOm50IFByZWRpY2F0ZXM6cHAKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBTdGVwUGF0dGVybihheGlzLmludFZhbHVlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLmZpbmROb2RlVHlwZShheGlzLmludFZhbHVlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHApOwotICAgICAgICAgICAgOn07Ci0KLU5vZGVUZXN0UGF0dGVybiA6Oj0gTmFtZVRlc3RQYXR0ZXJuOm50Ci0gICAgICAgICAgICB7OiBSRVNVTFQgPSBudDsgOn0KLQotICAgICAgICAgICAgfCBOT0RFCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5BTk9ERSk7IDp9IAotCi0gICAgICAgICAgICB8IFRFWFQKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LlRFWFQpOyA6fQotCi0gICAgICAgICAgICB8IENPTU1FTlQKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LkNPTU1FTlQpOyA6fQotCi0gICAgICAgICAgICB8IFBJCi0gICAgICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5QSSk7IDp9OwotCi1OYW1lVGVzdFBhdHRlcm4gOjo9IFNUQVIKLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IG51bGw7IDp9Ci0KLSAgICAgICAgICAgIHwgUU5hbWU6cW4KLSAgICAgICAgICAgIHs6IFJFU1VMVCA9IHFuOyA6fTsKLQotQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXIgOjo9IEFUU0lHTgotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5BVFRSSUJVVEUpOyA6fQotCi0gICAgICAgICAgICB8IENISUxEIERDT0xPTgotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5DSElMRCk7IDp9Ci0KLSAgICAgICAgICAgIHwgQVRUUklCVVRFIERDT0xPTgotICAgICAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5BVFRSSUJVVEUpOyA6fTsKLQotUHJlZGljYXRlcyA6Oj0gUHJlZGljYXRlOnAKLSAgICAgICAgICAgIHs6IAotCQlWZWN0b3IgdGVtcCA9IG5ldyBWZWN0b3IoKTsKLQkJdGVtcC5hZGRFbGVtZW50KHApOwotCQlSRVNVTFQgPSB0ZW1wOyAgICAgCi0gICAgICAgICAgICA6fQotCi0gICAgICAgICAgICB8IFByZWRpY2F0ZTpwIFByZWRpY2F0ZXM6cHAKLSAgICAgICAgICAgIHs6IHBwLmluc2VydEVsZW1lbnRBdChwLCAwKTsgUkVTVUxUID0gcHA7IDp9OyAKLQotUHJlZGljYXRlIDo6PSAgTEJSQUNLIEV4cHI6ZSBSQlJBQ0sKLQkgICAgezoKLQkJUkVTVUxUID0gbmV3IFByZWRpY2F0ZShlKTsKLQkgICAgOn07Ci0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeHByZXNzaW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLQotRXhwciA6Oj0gT3JFeHByOmV4Ci0gICAgICAgIHs6IFJFU1VMVCA9IGV4OyA6fTsKLQotT3JFeHByIDo6PSBBbmRFeHByOmFlCi0gICAgICAgIHs6IFJFU1VMVCA9IGFlOyA6fQotCi0gICAgICAgIHwgT3JFeHByOm9lIE9SIEFuZEV4cHI6YWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IExvZ2ljYWxFeHByKExvZ2ljYWxFeHByLk9SLCBvZSwgYWUpOyA6fTsKLQotQW5kRXhwciA6Oj0gRXF1YWxpdHlFeHByOmUKLSAgICAgICAgezogUkVTVUxUID0gZTsgOn0KLQotICAgICAgICB8IEFuZEV4cHI6YWUgQU5EIEVxdWFsaXR5RXhwcjplZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgTG9naWNhbEV4cHIoTG9naWNhbEV4cHIuQU5ELCBhZSwgZWUpOyA6fTsKLSAgICAKLUVxdWFsaXR5RXhwciA6Oj0gUmVsYXRpb25hbEV4cHI6cmUKLSAgICAgICAgezogUkVTVUxUID0gcmU7IDp9Ci0KLSAgICAgICAgfCBFcXVhbGl0eUV4cHI6ZWUgRVEgUmVsYXRpb25hbEV4cHI6cmUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEVxdWFsaXR5RXhwcihPcGVyYXRvcnMuRVEsIGVlLCByZSk7IDp9Ci0KLSAgICAgICAgfCBFcXVhbGl0eUV4cHI6ZWUgTkUgUmVsYXRpb25hbEV4cHI6cmUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEVxdWFsaXR5RXhwcihPcGVyYXRvcnMuTkUsIGVlLCByZSk7IDp9OwotCi1SZWxhdGlvbmFsRXhwciA6Oj0gQWRkaXRpdmVFeHByOmFlCi0gICAgICAgIHs6IFJFU1VMVCA9IGFlOyA6fQotCi0gICAgICAgIHwgUmVsYXRpb25hbEV4cHI6cmUgTFQgQWRkaXRpdmVFeHByOmFlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBSZWxhdGlvbmFsRXhwcihPcGVyYXRvcnMuTFQsIHJlLCBhZSk7IDp9Ci0KLSAgICAgICAgfCBSZWxhdGlvbmFsRXhwcjpyZSBHVCBBZGRpdGl2ZUV4cHI6YWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFJlbGF0aW9uYWxFeHByKE9wZXJhdG9ycy5HVCwgcmUsIGFlKTsgOn0KLQotICAgICAgICB8IFJlbGF0aW9uYWxFeHByOnJlIExFIEFkZGl0aXZlRXhwcjphZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgUmVsYXRpb25hbEV4cHIoT3BlcmF0b3JzLkxFLCByZSwgYWUpOyA6fQotCi0gICAgICAgIHwgUmVsYXRpb25hbEV4cHI6cmUgR0UgQWRkaXRpdmVFeHByOmFlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBSZWxhdGlvbmFsRXhwcihPcGVyYXRvcnMuR0UsIHJlLCBhZSk7IDp9OwotCi1BZGRpdGl2ZUV4cHIgOjo9IE11bHRpcGxpY2F0aXZlRXhwcjptZQotICAgICAgICB7OiBSRVNVTFQgPSBtZTsgOn0KLQotICAgICAgICB8IEFkZGl0aXZlRXhwcjphZSBQTFVTICBNdWx0aXBsaWNhdGl2ZUV4cHI6bWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuUExVUywgYWUsIG1lKTsgOn0KLQotICAgICAgICB8IEFkZGl0aXZlRXhwcjphZSBNSU5VUyBNdWx0aXBsaWNhdGl2ZUV4cHI6bWUKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEJpbk9wRXhwcihCaW5PcEV4cHIuTUlOVVMsIGFlLCBtZSk7IDp9OwotCi1NdWx0aXBsaWNhdGl2ZUV4cHIgOjo9IFVuYXJ5RXhwcjp1ZQotICAgICAgICB7OiBSRVNVTFQgPSB1ZTsgOn0KLQotICAgICAgICB8IE11bHRpcGxpY2F0aXZlRXhwcjptZSBTVEFSIFVuYXJ5RXhwcjp1ZQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgQmluT3BFeHByKEJpbk9wRXhwci5USU1FUywgbWUsIHVlKTsgOn0KLQotICAgICAgICB8IE11bHRpcGxpY2F0aXZlRXhwcjptZSBESVYgVW5hcnlFeHByOnVlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBCaW5PcEV4cHIoQmluT3BFeHByLkRJViwgbWUsIHVlKTsgOn0KLQotICAgICAgICB8IE11bHRpcGxpY2F0aXZlRXhwcjptZSBNT0QgVW5hcnlFeHByOnVlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBCaW5PcEV4cHIoQmluT3BFeHByLk1PRCwgbWUsIHVlKTsgOn07Ci0KLVVuYXJ5RXhwciA6Oj0gVW5pb25FeHByOnVlCi0gICAgICAgIHs6IFJFU1VMVCA9IHVlOyA6fQotCi0gICAgICAgIHwgTUlOVVMgVW5hcnlFeHByOnVlCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBVbmFyeU9wRXhwcih1ZSk7IDp9OwotCi1VbmlvbkV4cHIgOjo9IFBhdGhFeHByOnBlCi0gICAgICAgIHs6IFJFU1VMVCA9IHBlOyA6fQotIAotICAgICAgICB8IFBhdGhFeHByOnBlIFZCQVIgVW5pb25FeHByOnJlc3QKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFVuaW9uUGF0aEV4cHIocGUsIHJlc3QpOyA6fTsKLQotUGF0aEV4cHIgOjo9IExvY2F0aW9uUGF0aDpscAotICAgICAgICB7OiBSRVNVTFQgPSBscDsgOn0KLQotICAgICAgICB8IEZpbHRlckV4cHI6ZmV4cAotICAgICAgICB7OiBSRVNVTFQgPSBmZXhwOyA6fQotCi0gICAgICAgIHwgRmlsdGVyRXhwcjpmZXhwIFNMQVNIIFJlbGF0aXZlTG9jYXRpb25QYXRoOnJscAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgRmlsdGVyUGFyZW50UGF0aChmZXhwLCBybHApOyA6fQotCi0gICAgICAgIHwgRmlsdGVyRXhwcjpmZXhwIERTTEFTSCBSZWxhdGl2ZUxvY2F0aW9uUGF0aDpybHAKLSAgICAgICAgezoKLSAgICAgICAgICAgLy8gRXhwYW5kICcvLycgaW50byAnL2Rlc2NlbmRhbnQtb3Itc2VsZjo6bm9kZSgpLycKLSAgICAgICAgICAgU3RlcCBub2RlU3RlcCA9IG5ldyBTdGVwKEF4aXMuREVTQ0VOREFOVE9SU0VMRiwgCi0JICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVUZXN0LkFOT0RFLCBudWxsKTsgCi0gICAgICAgICAgIFJFU1VMVCA9IG5ldyBGaWx0ZXJQYXJlbnRQYXRoKAotCSAgICAgICAgICAgICAgICBuZXcgRmlsdGVyUGFyZW50UGF0aChmZXhwLCBub2RlU3RlcCksIHJscCk7Ci0gICAgICAgIDp9OwotCi1Mb2NhdGlvblBhdGggOjo9IFJlbGF0aXZlTG9jYXRpb25QYXRoOnJscAotICAgICAgICB7OiBSRVNVTFQgPSBybHA7IDp9Ci0KLSAgICAgICAgfCBBYnNvbHV0ZUxvY2F0aW9uUGF0aDphbHAKLSAgICAgICAgezogUkVTVUxUID0gYWxwOyA6fTsKLQotUmVsYXRpdmVMb2NhdGlvblBhdGggOjo9IFN0ZXA6c3RlcAotICAgICAgICB7OiBSRVNVTFQgPSBzdGVwOyA6fQotCi0gICAgICAgIHwgUmVsYXRpdmVMb2NhdGlvblBhdGg6cmxwIFNMQVNIIFN0ZXA6c3RlcAotICAgICAgICB7OiAgICAgCi0gICAgICAgIGlmIChybHAgaW5zdGFuY2VvZiBTdGVwICYmICgoU3RlcCkgcmxwKS5pc0FiYnJldmlhdGVkRG90KCkpIHsKLSAgICAgICAgICAgICAgUkVTVUxUID0gc3RlcDsgICAgICAgLy8gUmVtb3ZlICcuLycgZnJvbSB0aGUgbWlkZGxlCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoKChTdGVwKSBzdGVwKS5pc0FiYnJldmlhdGVkRG90KCkpIHsKLSAgICAgICAgICAgICAgUkVTVUxUID0gcmxwOyAgICAgICAgLy8gUmVtb3ZlICcvLicgZnJvbSB0aGUgZW5kCi0gICAgICAgIH0KLSAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgUkVTVUxUID0KLSAgICAgICAgICAgICAgICBuZXcgUGFyZW50TG9jYXRpb25QYXRoKChSZWxhdGl2ZUxvY2F0aW9uUGF0aCkgcmxwLCBzdGVwKTsgCi0gICAgICAgICAgIH0KLSAgICAgICAgOn0KLQotICAgICAgICB8IEFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGg6YXJscAotICAgICAgICB7OiBSRVNVTFQgPSBhcmxwOyA6fTsKLQotQWJzb2x1dGVMb2NhdGlvblBhdGggOjo9IFNMQVNICi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBYnNvbHV0ZUxvY2F0aW9uUGF0aCgpOyA6fQotCi0gICAgICAgIHwgU0xBU0ggUmVsYXRpdmVMb2NhdGlvblBhdGg6cmxwCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBBYnNvbHV0ZUxvY2F0aW9uUGF0aChybHApOyA6fQotCi0gICAgICAgIHwgQWJicmV2aWF0ZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aDphYWxwCi0gICAgICAgIHs6IFJFU1VMVCA9IGFhbHA7IDp9OwotCi1BYmJyZXZpYXRlZFJlbGF0aXZlTG9jYXRpb25QYXRoIDo6PSBSZWxhdGl2ZUxvY2F0aW9uUGF0aDpybHAgRFNMQVNIIFN0ZXA6c3RlcAotICAgICAgICB7OiAKLQkgICBTdGVwIG5vZGVTdGVwOwotCSAgIGZpbmFsIFN0ZXAgdGVtcCA9IChTdGVwKSBzdGVwOwotCSAgIGlmICh0ZW1wLmdldEF4aXMoKSA9PSBBeGlzLkNISUxEKSB7Ci0JICAgICAgIC8vIEV4cGFuZCAncmxwLy9jaGlsZDo6RScgaW50byAncmxwL2Rlc2NlbmRhbnQ6OkUnCi0JICAgICAgIG5vZGVTdGVwID0gbmV3IFN0ZXAoQXhpcy5ERVNDRU5EQU5ULCAKLQkJCQkgICB0ZW1wLmdldE5vZGVUeXBlKCksIAotCQkJCSAgIHRlbXAuZ2V0UHJlZGljYXRlcygpKTsKLQotICAgICAgICAgICAgICAgaWYgKHJscCBpbnN0YW5jZW9mIFN0ZXAgJiYgKChTdGVwKSBybHApLmlzQWJicmV2aWF0ZWREb3QoKSkgewotICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbm9kZVN0ZXA7ICAgICAgIC8vIFJlbW92ZSAnLi8vJyBmcm9tIHRoZSBiZWdpbm5pbmcKLSAgICAgICAgICAgICAgIH0KLQkgICAgICAgZWxzZSB7Ci0JICAgICAgICAgIFJFU1VMVCA9IG5ldyBQYXJlbnRMb2NhdGlvblBhdGgoKFJlbGF0aXZlTG9jYXRpb25QYXRoKSBybHAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVTdGVwKTsKLSAgICAgICAgICAgICAgIH0KLQkgICB9Ci0JICAgZWxzZSB7Ci0JICAgICAgIC8vIEV4cGFuZCAncmxwLy9zdGVwJyBpbnRvICdybHAvZGVzY2VuZGFudC1vci1zZWxmOjpub2RlKCkvc3RlcCcKLQkgICAgICAgbm9kZVN0ZXAgPSBuZXcgU3RlcChBeGlzLkRFU0NFTkRBTlRPUlNFTEYsIAotCQkJCQlOb2RlVGVzdC5BTk9ERSwgbnVsbCk7IAotCSAgICAgICBSRVNVTFQgPSBuZXcgUGFyZW50TG9jYXRpb25QYXRoKAotCQkJICAgIG5ldyBQYXJlbnRMb2NhdGlvblBhdGgoKFJlbGF0aXZlTG9jYXRpb25QYXRoKSBybHAsIAotCQkJCQkJICAgbm9kZVN0ZXApLCBzdGVwKTsKLQkgICB9Ci0gICAgICAgIDp9OwotCi0KLUFiYnJldmlhdGVkQWJzb2x1dGVMb2NhdGlvblBhdGggOjo9IERTTEFTSCBSZWxhdGl2ZUxvY2F0aW9uUGF0aDpybHAKLSAgICAgICAgezoKLQotCS8vIEdUTSBidWcgZml4IDI1NTM7IDMzNjAgKGhhbmRsZXMgcHJlZGljYXRlcyBpbiBub2RlU3RlcDIpLiAKLQlBYnNvbHV0ZUxvY2F0aW9uUGF0aCBhYnNMb2NQYXRoID0gbnVsbDsKLQlpZiAocmxwIGluc3RhbmNlb2YgUGFyZW50TG9jYXRpb25QYXRoKSB7Ci0JICAgIC8vIEdUTSwgYnVnIGZpeCAzMzEyICAKLSAgICAgICAgICAgIFN0ZXAgbm9kZVN0ZXAxID0gbmV3IFN0ZXAoQXhpcy5ERVNDRU5EQU5UT1JTRUxGLCAtMSwgbnVsbCk7Ci0JICAgIFBhcmVudExvY2F0aW9uUGF0aCBwYXJMb2NQYXRoID0gbmV3IFBhcmVudExvY2F0aW9uUGF0aChub2RlU3RlcDEsCi0JCXJscCk7Ci0JICAgIGFic0xvY1BhdGggPSBuZXcgQWJzb2x1dGVMb2NhdGlvblBhdGgocGFyTG9jUGF0aCk7Ci0JfQotCWVsc2UgewotCSAgICBpbnQgbm9kZVR5cGUgPSBOb2RlVGVzdC5FTEVNRU5UOwotICAgICAgICAgICAgaW50IGF4aXMgPSBBeGlzLkNISUxEOwotICAgICAgICAgICAgVmVjdG9yIHByZWRpY2F0ZXMgPSBudWxsOwotCi0JICAgIGlmIChybHAgaW5zdGFuY2VvZiBTdGVwKSB7Ci0gICAgICAgICAgICAgICAgbm9kZVR5cGUgPSAoKFN0ZXApcmxwKS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgICAgIGF4aXMgPSAoKFN0ZXApcmxwKS5nZXRBeGlzKCk7Ci0gICAgICAgICAgICAgICAgcHJlZGljYXRlcyA9ICgoU3RlcClybHApLmdldFByZWRpY2F0ZXMoKTsKLQkgICAgfQotIAkgICAgLy8gY3JlYXRlIHRoZSBuZXcgYWJzIGxvY2F0aW9uIHBhdGgKLSAgICAgICAgICAgIFN0ZXAgbm9kZVN0ZXAxID0gbmV3IFN0ZXAoQXhpcy5ERVNDRU5EQU5UT1JTRUxGLCAtMSwgbnVsbCk7Ci0gICAgICAgICAgICBTdGVwIG5vZGVTdGVwMiA9IG5ldyBTdGVwKGF4aXMsIG5vZGVUeXBlLCBwcmVkaWNhdGVzKTsKLQkgICAgYWJzTG9jUGF0aCA9IG5ldyBBYnNvbHV0ZUxvY2F0aW9uUGF0aCgKLSAgICAgICAgICAgICAgICAgICBuZXcgUGFyZW50TG9jYXRpb25QYXRoKG5vZGVTdGVwMSwgbm9kZVN0ZXAyKSk7Ci0JfQotCi0JUkVTVUxUID0gbmV3IEZpbHRlcmVkQWJzb2x1dGVMb2NhdGlvblBhdGgoYWJzTG9jUGF0aCk7CQotCTp9OwotCi0KLQotU3RlcCA6Oj0gTm9kZVRlc3Q6bnRlc3QKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFN0ZXAoQXhpcy5DSElMRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLmZpbmROb2RlVHlwZShBeGlzLkNISUxELCBudGVzdCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotICAgICAgICA6fQotCi0gICAgICAgIHwgTm9kZVRlc3Q6bnRlc3QgUHJlZGljYXRlczpwcAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgU3RlcChBeGlzLkNISUxELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKEF4aXMuQ0hJTEQsIG50ZXN0KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHApOwotICAgICAgICA6fQotCi0gICAgICAgIHwgQXhpc1NwZWNpZmllcjpheGlzIE5vZGVUZXN0Om50ZXN0IFByZWRpY2F0ZXM6cHAKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFN0ZXAoYXhpcy5pbnRWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKGF4aXMuaW50VmFsdWUoKSwgbnRlc3QpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcCk7Ci0gICAgICAgIDp9Ci0KLSAgICAgICAgfCBBeGlzU3BlY2lmaWVyOmF4aXMgTm9kZVRlc3Q6bnRlc3QKLSAgICAgICAgezogUkVTVUxUID0gbmV3IFN0ZXAoYXhpcy5pbnRWYWx1ZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuZmluZE5vZGVUeXBlKGF4aXMuaW50VmFsdWUoKSwgbnRlc3QpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKLSAgICAgICAgOn0KLQotICAgICAgICB8IEFiYnJldmlhdGVkU3RlcDphYmJyZXYKLSAgICAgICAgezogUkVTVUxUID0gYWJicmV2OyA6fTsKLQotQXhpc1NwZWNpZmllciA6Oj0gQXhpc05hbWU6YW4gRENPTE9OCi0gICAgICAgIHs6IFJFU1VMVCA9IGFuOyA6fQotCi0gICAgICAgIHwgQVRTSUdOCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsgOn07Ci0KLUF4aXNOYW1lIDo6PSAgICBBTkNFU1RPUgotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkFOQ0VTVE9SKTsgOn0KLQotICAgICAgICB8IEFOQ0VTVE9ST1JTRUxGCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQU5DRVNUT1JPUlNFTEYpOyA6fQotCi0gICAgICAgIHwgQVRUUklCVVRFCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQVRUUklCVVRFKTsgOn0KLQotICAgICAgICB8IENISUxECi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuQ0hJTEQpOyA6fQotCi0gICAgICAgIHwgREVTQ0VOREFOVAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkRFU0NFTkRBTlQpOyA6fQotCi0gICAgICAgIHwgREVTQ0VOREFOVE9SU0VMRgotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLkRFU0NFTkRBTlRPUlNFTEYpOyA6fQotCi0gICAgICAgIHwgRk9MTE9XSU5HCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuRk9MTE9XSU5HKTsgOn0KLQotICAgICAgICB8IEZPTExPV0lOR1NJQkxJTkcKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5GT0xMT1dJTkdTSUJMSU5HKTsgOn0KLQotICAgICAgICB8IE5BTUVTUEFDRQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihBeGlzLk5BTUVTUEFDRSk7IDp9Ci0KLSAgICAgICAgfCBQQVJFTlQKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5QQVJFTlQpOyA6fQotCi0gICAgICAgIHwgUFJFQ0VESU5HCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKEF4aXMuUFJFQ0VESU5HKTsgOn0KLQotICAgICAgICB8IFBSRUNFRElOR1NJQkxJTkcKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5QUkVDRURJTkdTSUJMSU5HKTsgOn0KLQotICAgICAgICB8IFNFTEYKLSAgICAgICAgezogUkVTVUxUID0gbmV3IEludGVnZXIoQXhpcy5TRUxGKTsgOn07Ci0KLUFiYnJldmlhdGVkU3RlcCA6Oj0gRE9UCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBTdGVwKEF4aXMuU0VMRiwgTm9kZVRlc3QuQU5PREUsIG51bGwpOyA6fQotCi0gICAgICAgIHwgRERPVAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgU3RlcChBeGlzLlBBUkVOVCwgTm9kZVRlc3QuQU5PREUsIG51bGwpOyA6fTsKLQotRmlsdGVyRXhwciA6Oj0gIFByaW1hcnlFeHByOnByaW1hcnkKLSAgICAgICAgezogUkVTVUxUID0gcHJpbWFyeTsgOn0KLQotICAgICAgICB8IFByaW1hcnlFeHByOnByaW1hcnkgUHJlZGljYXRlczpwcAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgRmlsdGVyRXhwcihwcmltYXJ5LCBwcCk7IDp9OwotCi1QcmltYXJ5RXhwciA6Oj0gVmFyaWFibGVSZWZlcmVuY2U6dnIKLSAgICAgICAgezogUkVTVUxUID0gdnI7IDp9Ci0KLSAgICAgICAgfCBMUEFSRU4gRXhwcjpleCBSUEFSRU4KLSAgICAgICAgezogUkVTVUxUID0gZXg7IDp9Ci0KLQl8IExpdGVyYWw6c3RyaW5nCi0JezogCi0JLyoKLQkqIElmIHRoZSBzdHJpbmcgYXBwZWFycyB0byBoYXZlIHRoZSBzeW50YXggb2YgYSBRTmFtZSwgc3RvcmUgCi0JKiBuYW1lc3BhY2UgaW5mbyBpbiB0aGUgbGl0ZXJhbCBleHByZXNzaW9uLiBUaGlzIGlzIHVzZWQgZm9yCi0JKiBlbGVtZW50LWF2YWlsYWJsZSBhbmQgZnVuY3Rpb24tYXZhaWxhYmxlIGZ1bmN0aW9ucy4KLQkqLwotCWZpbmFsIGludCBpbmRleCA9IHN0cmluZy5sYXN0SW5kZXhPZignOicpOwotCWZpbmFsIFN0cmluZyBwcmVmaXggPSBpbmRleCA+PSAwCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBzdHJpbmcuc3Vic3RyaW5nKDAsIGluZGV4KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogQ29uc3RhbnRzLkVNUFRZU1RSSU5HOwotCVN0cmluZyBuYW1lc3BhY2UgPSBwYXJzZXIuX3N5bWJvbFRhYmxlLmxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCVJFU1VMVCA9IG5hbWVzcGFjZSA9PSBudWxsCi0gICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgTGl0ZXJhbEV4cHIoc3RyaW5nKQotICAgICAgICAgICAgICAgICAgICAgICAgIDogbmV3IExpdGVyYWxFeHByKHN0cmluZywgbmFtZXNwYWNlKTsgCi0JOn0KLQotICAgICAgICB8IElOVDpudW0KLSAgICAgICAgezogCi0JICAgIGlmIChudW0uZG91YmxlVmFsdWUoKSA9PSAtMCkKLQkgICAgICAgIFJFU1VMVCA9IG5ldyBSZWFsRXhwcihudW0uZG91YmxlVmFsdWUoKSk7Ci0JICAgIGVsc2UgaWYgKG51bS5pbnRWYWx1ZSgpID09IDApCi0JICAgICAgICBSRVNVTFQgPSBuZXcgSW50RXhwcihudW0uaW50VmFsdWUoKSk7Ci0JICAgIGVsc2UgaWYgKG51bS5kb3VibGVWYWx1ZSgpID09IDAuMCkKLQkgICAgICAgIFJFU1VMVCA9IG5ldyBSZWFsRXhwcihudW0uZG91YmxlVmFsdWUoKSk7Ci0JICAgIGVsc2UKLQkgICAgICAgIFJFU1VMVCA9IG5ldyBJbnRFeHByKG51bS5pbnRWYWx1ZSgpKTsKLSAgICAgICAgOn0KLQotICAgICAgICB8IFJFQUw6bnVtCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBSZWFsRXhwcihudW0uZG91YmxlVmFsdWUoKSk7IDp9Ci0KLSAgICAgICAgfCBGdW5jdGlvbkNhbGw6ZmMKLSAgICAgICAgezogUkVTVUxUID0gZmM7IDp9OwotCi1WYXJpYWJsZVJlZmVyZW5jZSA6Oj0gRE9MTEFSIFZhcmlhYmxlTmFtZTp2YXJOYW1lCi0gICAgICAgIHs6IAotICAgICAgICAgICAgLy8gQW4gZW1wdHkgcW5hbWUgcHJlZml4IGZvciBhIHZhcmlhYmxlIG9yIHBhcmFtZXRlciByZWZlcmVuY2UKLSAgICAgICAgICAgIC8vIHNob3VsZCBtYXAgdG8gdGhlIG51bGwgbmFtZXNwYWNlIGFuZCBub3QgdGhlIGRlZmF1bHQgVVJJLgotICAgICAgICAgICAgU3ludGF4VHJlZU5vZGUgbm9kZSA9IHBhcnNlci5sb29rdXBOYW1lKHZhck5hbWUpOwotCi0gICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBWYXJpYWJsZSkgewotICAgICAgICAgICAgICAgICAgICBSRVNVTFQgPSBuZXcgVmFyaWFibGVSZWYoKFZhcmlhYmxlKW5vZGUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgUGFyYW0pIHsKLSAgICAgICAgICAgICAgICAgICAgUkVTVUxUID0gbmV3IFBhcmFtZXRlclJlZigoUGFyYW0pbm9kZSk7Ci0gICAgICAgICAgICAgICAgfSAKLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgUkVTVUxUID0gcGFyc2VyLkR1bW15VmFyUmVmOwotICAgICAgICAgICAgICAgIHBhcnNlci5hZGRFcnJvcihuZXcgRXJyb3JNc2coRXJyb3JNc2cuVkFSVU5ERUZfRVJSLAotCQkgICAgcGFyc2VyLmdldExpbmVOdW1iZXIoKSwgdmFyTmFtZSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIDp9OwotCi1GdW5jdGlvbkNhbGwgOjo9IEZ1bmN0aW9uTmFtZTpmbmFtZSBMUEFSRU4gUlBBUkVOCi0gICAgICAgIHs6IAotICAgICAgICAgIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImN1cnJlbnQiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEN1cnJlbnRDYWxsKGZuYW1lKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoIm51bWJlciIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTnVtYmVyQ2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJzdHJpbmciKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0cmluZ0NhbGwoZm5hbWUsIHBhcnNlci5FbXB0eUFyZ3MpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgiY29uY2F0IikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBDb25jYXRDYWxsKGZuYW1lLCBwYXJzZXIuRW1wdHlBcmdzKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoInRydWUiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJvb2xlYW5FeHByKHRydWUpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgiZmFsc2UiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJvb2xlYW5FeHByKGZhbHNlKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoIm5hbWUiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE5hbWVDYWxsKGZuYW1lKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImdlbmVyYXRlLWlkIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBHZW5lcmF0ZUlkQ2FsbChmbmFtZSwgcGFyc2VyLkVtcHR5QXJncyk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJzdHJpbmctbGVuZ3RoIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdHJpbmdMZW5ndGhDYWxsKGZuYW1lLCBwYXJzZXIuRW1wdHlBcmdzKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoInBvc2l0aW9uIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBQb3NpdGlvbkNhbGwoZm5hbWUpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgibGFzdCIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTGFzdENhbGwoZm5hbWUpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgibG9jYWwtbmFtZSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgTG9jYWxOYW1lQ2FsbChmbmFtZSk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJuYW1lc3BhY2UtdXJpIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBOYW1lc3BhY2VVcmlDYWxsKGZuYW1lKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBGdW5jdGlvbkNhbGwoZm5hbWUsIHBhcnNlci5FbXB0eUFyZ3MpOwotCSAgfQotICAgICAgICA6fQotCi0gICAgICAgIHwgRnVuY3Rpb25OYW1lOmZuYW1lIExQQVJFTiBOb25lbXB0eUFyZ3VtZW50TGlzdDphcmdsIFJQQVJFTgotICAgICAgICB7OgotICAgICAgICAgIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImNvbmNhdCIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQ29uY2F0Q2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJudW1iZXIiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE51bWJlckNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgiZG9jdW1lbnQiKSkgewotCSAgICBwYXJzZXIuc2V0TXVsdGlEb2N1bWVudCh0cnVlKTsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBEb2N1bWVudENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgic3RyaW5nIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBTdHJpbmdDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImJvb2xlYW4iKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEJvb2xlYW5DYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoIm5hbWUiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE5hbWVDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImdlbmVyYXRlLWlkIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBHZW5lcmF0ZUlkQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJub3QiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE5vdENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgiZm9ybWF0LW51bWJlciIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRm9ybWF0TnVtYmVyQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJ1bnBhcnNlZC1lbnRpdHktdXJpIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBVbnBhcnNlZEVudGl0eVVyaUNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgia2V5IikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBLZXlDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImlkIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBLZXlDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImNlaWxpbmciKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IENlaWxpbmdDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoInJvdW5kIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBSb3VuZENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgiZmxvb3IiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZsb29yQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJjb250YWlucyIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgQ29udGFpbnNDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoInN0cmluZy1sZW5ndGgiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0cmluZ0xlbmd0aENhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgaWYgKGZuYW1lID09IHBhcnNlci5nZXRRTmFtZSgic3RhcnRzLXdpdGgiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IFN0YXJ0c1dpdGhDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImZ1bmN0aW9uLWF2YWlsYWJsZSIpKSB7Ci0gICAgICAgICAgICBSRVNVTFQgPSBuZXcgRnVuY3Rpb25BdmFpbGFibGVDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImVsZW1lbnQtYXZhaWxhYmxlIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBFbGVtZW50QXZhaWxhYmxlQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgICAgICAgZWxzZSBpZiAoZm5hbWUgPT0gcGFyc2VyLmdldFFOYW1lKCJsb2NhbC1uYW1lIikpIHsKLSAgICAgICAgICAgIFJFU1VMVCA9IG5ldyBMb2NhbE5hbWVDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoImxhbmciKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IExhbmdDYWxsKGZuYW1lLCBhcmdsKTsKLQkgIH0KLSAgICAgICAgICBlbHNlIGlmIChmbmFtZSA9PSBwYXJzZXIuZ2V0UU5hbWUoIm5hbWVzcGFjZS11cmkiKSkgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IE5hbWVzcGFjZVVyaUNhbGwoZm5hbWUsIGFyZ2wpOwotCSAgfQotICAgICAgICAgIGVsc2UgewotICAgICAgICAgICAgUkVTVUxUID0gbmV3IEZ1bmN0aW9uQ2FsbChmbmFtZSwgYXJnbCk7Ci0JICB9Ci0gICAgOn07Ci0KLU5vbmVtcHR5QXJndW1lbnRMaXN0IDo6PSBBcmd1bWVudDphcmcKLSAgICAgICAgezogCi0gICAgICAgICAgICBWZWN0b3IgdGVtcCA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgIHRlbXAuYWRkRWxlbWVudChhcmcpOwotICAgICAgICAgICAgUkVTVUxUID0gdGVtcDsKLSAgICAgICAgOn0KLQotICAgICAgICB8IEFyZ3VtZW50OmFyZyBDT01NQSBOb25lbXB0eUFyZ3VtZW50TGlzdDphcmdsCi0gICAgICAgIHs6IGFyZ2wuaW5zZXJ0RWxlbWVudEF0KGFyZywgMCk7IFJFU1VMVCA9IGFyZ2w7IDp9OwotICAgICAgICAvKiBJcyBpbnNlcnRFbGVtZW50IG9rID8gKi8KLQotRnVuY3Rpb25OYW1lIDo6PSBRTmFtZTpmbmFtZQotICAgICAgICB7OgotICAgICAgICAgICAgZm5hbWUuY2xlYXJEZWZhdWx0TmFtZXNwYWNlKCk7Ci0gICAgICAgICAgICBSRVNVTFQgPSBmbmFtZTsgCi0gICAgICAgIDp9OwotCi1WYXJpYWJsZU5hbWUgOjo9IFFOYW1lOnZuYW1lCi0gICAgICAgIHs6Ci0gICAgICAgICAgICB2bmFtZS5jbGVhckRlZmF1bHROYW1lc3BhY2UoKTsKLSAgICAgICAgICAgIFJFU1VMVCA9IHZuYW1lOyAKLSAgICAgICAgOn07Ci0KLUFyZ3VtZW50IDo6PSAgICBFeHByOmV4Ci0gICAgICAgIHs6IFJFU1VMVCA9IGV4OyA6fTsKLQotTm9kZVRlc3QgOjo9IE5hbWVUZXN0Om50Ci0gICAgICAgIHs6IFJFU1VMVCA9IG50OyA6fQotCi0gICAgICAgIHwgTk9ERQotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5BTk9ERSk7IDp9Ci0KLSAgICAgICAgfCBURVhUCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LlRFWFQpOyA6fQotCi0gICAgICAgIHwgQ09NTUVOVAotICAgICAgICB7OiBSRVNVTFQgPSBuZXcgSW50ZWdlcihOb2RlVGVzdC5DT01NRU5UKTsgOn0KLQotICAgICAgICB8IFBJCi0gICAgICAgIHs6IFJFU1VMVCA9IG5ldyBJbnRlZ2VyKE5vZGVUZXN0LlBJKTsgOn07Ci0KLU5hbWVUZXN0IDo6PSBTVEFSCi0gICAgICAgICAgICAgezogUkVTVUxUID0gbnVsbDsgOn0KLQotICAgICAgICAgICAgIHwgUU5hbWU6cW4KLSAgICAgICAgICAgICB7OiBSRVNVTFQgPSBxbjsgOn07Ci0KLVFOYW1lIDo6PSBRTkFNRTpxbmFtZQotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWUocW5hbWUpOyA6fQotCi0gICAgICAgIHwgRElWCi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZSgiZGl2Iik7IDp9Ci0KLSAgICAgICAgfCBNT0QKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lKCJtb2QiKTsgOn0KLQotICAgICAgICB8IEtFWQotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWUoImtleSIpOyA6fQotCi0gICAgICAgIHwgQ0hJTEQKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lKCJjaGlsZCIpOyA6fQotCi0gICAgICAgIHwgUEFSRU5UCi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZSgicGFyZW50Iik7IDp9Ci0KLSAgICAgICAgfCBQUkVDRURJTkcKLSAgICAgICAgezogUkVTVUxUID0gcGFyc2VyLmdldFFOYW1lKCJwcmVjZWRpbmciKTsgOn0KLQotICAgICAgICB8IEFUVFJJQlVURQotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWUoImF0dHJpYnV0ZSIpOyA6fQotCi0gICAgICAgIHwgU0VMRgotICAgICAgICB7OiBSRVNVTFQgPSBwYXJzZXIuZ2V0UU5hbWUoInNlbGYiKTsgOn0KLQotICAgICAgICB8IElECi0gICAgICAgIHs6IFJFU1VMVCA9IHBhcnNlci5nZXRRTmFtZSgiaWQiKTsgOn07Ci0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3hwYXRoLmxleCBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3hwYXRoLmxleApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNThkYjZkNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci94cGF0aC5sZXgKKysrIC9kZXYvbnVsbApAQCAtMSw5MiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBDb3B5cmlnaHQgMjAwMCBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi0gKiAKLSAqIFRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uIG9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gIAotICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcy4KLSAqIAotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcjsKLQotaW1wb3J0IGphdmFfY3VwLnJ1bnRpbWUuU3ltYm9sOwotJSUKLSVjdXAKLSV1bmljb2RlCi0lY2xhc3MgWFBhdGhMZXhlcgotJXl5ZW9mCi0KLSVlb2Z2YWx7Ci1yZXR1cm4gbmV3IFN5bWJvbChzeW0uRU9GKTsKLSVlb2Z2YWx9Ci0KLSV5eWxleHRocm93ewotRXhjZXB0aW9uCi0leXlsZXh0aHJvd30KLQotRGlnaXQ9WzAtOV0KLUxldHRlcj1bQS1aYS16XQotTkNOYW1lQ2hhcj0oe0xldHRlcn18e0RpZ2l0fXwiLiJ8Ii0ifCJfIikKLU5DTmFtZT0oe0xldHRlcn18Il8iKSh7TkNOYW1lQ2hhcn0pKgotJSUKLQotIioiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlNUQVIpOyB9Ci0iLyIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uU0xBU0gpOyB9IAotIisiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlBMVVMpOyB9Ci0iLSIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uTUlOVVMpOyB9Ci0iZGl2IiAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uRElWKTsgfQotIm1vZCIgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLk1PRCk7IH0KLSI6OiIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5EQ09MT04pOyB9Ci0iLCIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uQ09NTUEpOyB9Ci0iQCIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uQVRTSUdOKTsgfQotIi4uIiAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkRET1QpOyB9Ci0ifCIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uVkJBUik7IH0KLSIkIiAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5ET0xMQVIpOyB9Ci0iLy8iICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uRFNMQVNIKTsgfQotIj0iICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkVRKTsgfQotIiE9IiAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLk5FKTsgfQotIjwiICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkxUKTsgfSAKLSI+IiAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5HVCk7IH0KLSI8PSIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5MRSk7IH0KLSI+PSIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5HRSk7IH0KLSJpZCIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5JRCk7IH0KLSJrZXkiICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5LRVkpOyB9Ci0idGV4dCgpIiAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uVEVYVCk7IH0KLSJub2RlKCkiICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5OT0RFKTsgfQotImNvbW1lbnQoKSIgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkNPTU1FTlQpOyB9Ci0icHJvY2Vzc2luZy1pbnN0cnVjdGlvbigpIiB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5QSSk7IH0KLSJvciIgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5PUik7IH0KLSJhbmQiICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5BTkQpOyB9Ci0iY2hpbGQiICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uQ0hJTEQpOyB9Ci0iYXR0cmlidXRlIiAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uQVRUUklCVVRFKTsgfQotImFuY2VzdG9yIiAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkFOQ0VTVE9SKTsgfQotImFuY2VzdG9yLW9yLXNlbGYiICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkFOQ0VTVE9ST1JTRUxGKTsgfQotImRlc2NlbmRhbnQiICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkRFU0NFTkRBTlQpOyB9Ci0iZGVzY2VuZGFudC1vci1zZWxmIiAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uREVTQ0VOREFOVE9SU0VMRik7IH0KLSJmb2xsb3dpbmciICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5GT0xMT1dJTkcpOyB9Ci0iZm9sbG93aW5nLXNpYmxpbmciICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uRk9MTE9XSU5HU0lCTElORyk7IH0KLSJuYW1lc3BhY2UiICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5OQU1FU1BBQ0UpOyB9Ci0icGFyZW50IiAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uUEFSRU5UKTsgfQotInByZWNlZGluZyIgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlBSRUNFRElORyk7IH0KLSJwcmVjZWRpbmctc2libGluZyIgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5QUkVDRURJTkdTSUJMSU5HKTsgfQotInNlbGYiICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlNFTEYpOyB9Ci0iWyIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uTEJSQUNLKTsgfQotIl0iICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlJCUkFDSyk7IH0KLSIoIiAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5MUEFSRU4pOyB9Ci0iKSIgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uUlBBUkVOKTsgfQotIjxQQVRURVJOPiIgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlBBVFRFUk4pOyB9Ci0iPEVYUFJFU1NJT04+IiAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uRVhQUkVTU0lPTik7IH0KLVwiW15cIl0qXCIgICAgICAgICAgICAgICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5MaXRlcmFsLAotCQkJICAgICAgeXl0ZXh0KCkuc3Vic3RyaW5nKDEsIHl5dGV4dCgpLmxlbmd0aCgpIC0gMSkpOyB9Ci1cJ1teXCddKlwnICAgICAgICAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uTGl0ZXJhbCwKLQkJCSAgICAgIHl5dGV4dCgpLnN1YnN0cmluZygxLCB5eXRleHQoKS5sZW5ndGgoKSAtIDEpKTsgfQote0RpZ2l0fSsgICAgICAgICAgICAgICAJIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLklOVCwgbmV3IEludGVnZXIoeXl0ZXh0KCkpKTsgfQote0RpZ2l0fSsoIi4ie0RpZ2l0fSopPyAJIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlJFQUwsIG5ldyBEb3VibGUoeXl0ZXh0KCkpKTsgfQotIi4ie0RpZ2l0fSsgICAgICAgICAgICAJIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlJFQUwsIG5ldyBEb3VibGUoeXl0ZXh0KCkpKTsgfQotIi4iICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLkRPVCk7IH0KLSh7TkNOYW1lfSI6Iik/e05DTmFtZX0gICB7IHJldHVybiBuZXcgU3ltYm9sKHN5bS5RTkFNRSwgeXl0ZXh0KCkpOyB9Ci0oe05DTmFtZX0iOiIpPyIqIiAgICAgICAgeyByZXR1cm4gbmV3IFN5bWJvbChzeW0uUU5BTUUsIHl5dGV4dCgpKTsgfQotKHtOQ05hbWV9IjoiKT8iQCoiICAgICAgIHsgcmV0dXJuIG5ldyBTeW1ib2woc3ltLlFOQU1FLCB5eXRleHQoKSk7IH0KLVsgXHRcclxuXGZdICAgICAgICAgICAgICB7IC8qIGlnbm9yZSB3aGl0ZSBzcGFjZS4gKi8gfQotLiAgICAgICAgICAgICAgICAgICAgICAgIHsgdGhyb3cgbmV3IEV4Y2VwdGlvbih5eXRleHQoKSk7IH0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9BYnNvbHV0ZUl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQWJzb2x1dGVJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwNDJjOWJhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9BYnNvbHV0ZUl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLQotcHVibGljIGZpbmFsIGNsYXNzIEFic29sdXRlSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLSAgICBwcml2YXRlIE5vZGVJdGVyYXRvciBfc291cmNlOwotCQotICAgIHB1YmxpYyBBYnNvbHV0ZUl0ZXJhdG9yKE5vZGVJdGVyYXRvciBzb3VyY2UpIHsKLQlfc291cmNlID0gc291cmNlOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLQkvLyBTaG91bGQgbmV2ZXIgYmUgY2FsbGVkIC0gd2VsbCwgaXQgaXMhISEKLQlyZXR1cm4gX3NvdXJjZS5uZXh0KCk7Ci0gICAgfQotCQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JX3N0YXJ0Tm9kZSA9IERPTS5ST09UTk9ERTsKLQlpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkgICAgcmVzZXRQb3NpdGlvbigpOwotCSAgICByZXR1cm4gX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IERPTS5ST09UTk9ERSk7Ci0JfQotCXJldHVybiByZXNldCgpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQl0cnkgewotCSAgICBmaW5hbCBBYnNvbHV0ZUl0ZXJhdG9yIGNsb25lID0gKEFic29sdXRlSXRlcmF0b3Ipc3VwZXIuY2xvbmUoKTsKLQkgICAgY2xvbmUuX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLQkgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotCSAgICByZXR1cm4gY2xvbmUucmVzZXQoKTsKLQl9Ci0JY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLQkgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcigiSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZC4iKTsgCi0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHJlc2V0KCkgewotCV9zb3VyY2UucmVzZXQoKTsKLQlyZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9zb3VyY2Uuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCV9zb3VyY2UuZ290b01hcmsoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQW55Tm9kZUNvdW50ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9BbnlOb2RlQ291bnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YjI0NDg4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9BbnlOb2RlQ291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBbnlOb2RlQ291bnRlciBleHRlbmRzIE5vZGVDb3VudGVyIHsKLSAgICBwdWJsaWMgQW55Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0JCQkgIERPTSBkb2N1bWVudCwgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0Jc3VwZXIodHJhbnNsZXQsIGRvY3VtZW50LCBpdGVyYXRvcik7Ci0gICAgfQotCQotICAgIHB1YmxpYyBOb2RlQ291bnRlciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlfbm9kZSA9IG5vZGU7Ci0JX25vZGVUeXBlID0gX2RvY3VtZW50LmdldFR5cGUobm9kZSk7Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDb3VudGVyKCkgewotCWludCByZXN1bHQ7Ci0JaWYgKF92YWx1ZSAhPSBJbnRlZ2VyLk1JTl9WQUxVRSkgewotCSAgICByZXN1bHQgPSBfdmFsdWU7Ci0JfQotCWVsc2UgewotCSAgICBpbnQgbmV4dCA9IF9ub2RlOwotCSAgICByZXN1bHQgPSAwOwotCSAgICB3aGlsZSAobmV4dCA+PSAwICYmICFtYXRjaGVzRnJvbShuZXh0KSkgewotCQlpZiAobWF0Y2hlc0NvdW50KG5leHQpKSB7Ci0JCSAgICArK3Jlc3VsdDsJCi0JCX0KLQkJLS1uZXh0OwotCSAgICB9Ci0JfQotCXJldHVybiBmb3JtYXROdW1iZXJzKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBOb2RlQ291bnRlciBnZXREZWZhdWx0Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0JCQkJCQkgICAgRE9NIGRvY3VtZW50LAotCQkJCQkJICAgIE5vZGVJdGVyYXRvciBpdGVyYXRvcikgewotCXJldHVybiBuZXcgRGVmYXVsdEFueU5vZGVDb3VudGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotICAgIH0KLQotICAgIHN0YXRpYyBjbGFzcyBEZWZhdWx0QW55Tm9kZUNvdW50ZXIgZXh0ZW5kcyBBbnlOb2RlQ291bnRlciB7Ci0JcHVibGljIERlZmF1bHRBbnlOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLQkJCQkgICAgIERPTSBkb2N1bWVudCwgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0JICAgIHN1cGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0Q291bnRlcigpIHsKLQkgICAgaW50IHJlc3VsdDsKLQkgICAgaWYgKF92YWx1ZSAhPSBJbnRlZ2VyLk1JTl9WQUxVRSkgewotCQlyZXN1bHQgPSBfdmFsdWU7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWludCBuZXh0ID0gX25vZGU7Ci0JCXJlc3VsdCA9IDA7Ci0JCWZpbmFsIGludCBudHlwZSA9IF9kb2N1bWVudC5nZXRUeXBlKF9ub2RlKTsgCi0JCXdoaWxlIChuZXh0ID49IDApIHsKLQkJICAgIGlmIChudHlwZSA9PSBfZG9jdW1lbnQuZ2V0VHlwZShuZXh0KSkgewotCQkJcmVzdWx0Kys7Ci0JCSAgICB9Ci0JCSAgICBuZXh0LS07Ci0JCX0KLQkgICAgfQotCSAgICByZXR1cm4gZm9ybWF0TnVtYmVycyhyZXN1bHQpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQXhpcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0F4aXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzBhNWQ3ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQXhpcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA0ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi0vKgotICogSU1QT1JUQU5UIE5PVEUgLSB0aGlzIGludGVyZmFjZSB3aWxsIHByb2JhYmx5IGJlIHJlcGxhY2VkIGJ5Ci0gKiBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpcyAodmVyeSBzaW1pbGFyKQotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgQXhpcyB7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1IgICAgICAgICA9ICAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOQ0VTVE9ST1JTRUxGICAgPSAgMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRSSUJVVEUgICAgICAgID0gIDI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hJTEQgICAgICAgICAgICA9ICAzOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFU0NFTkRBTlQgICAgICAgPSAgNDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVNDRU5EQU5UT1JTRUxGID0gIDU7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9MTE9XSU5HICAgICAgICA9ICA2OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPTExPV0lOR1NJQkxJTkcgPSAgNzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU1FU1BBQ0VERUNMUyAgID0gIDg7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFICAgICAgICA9ICA5OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBUkVOVCAgICAgICAgICAgPSAxMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUkVDRURJTkcgICAgICAgID0gMTE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJFQ0VESU5HU0lCTElORyA9IDEyOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFTEYgICAgICAgICAgICAgPSAxMzsKLQkKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG5hbWVzID0gewotCSJhbmNlc3RvciIsCi0JImFuY2VzdG9yLW9yLXNlbGYiLAotCSJhdHRyaWJ1dGUiLAotCSJjaGlsZCIsCi0JImRlc2NlbmRhbnQiLAotCSJkZXNjZW5kYW50LW9yLXNlbGYiLAotCSJmb2xsb3dpbmciLAotCSJmb2xsb3dpbmctc2libGluZyIsCi0JIm5hbWVzcGFjZSIsCi0JIm5hbWVzcGFjZS1kZWNscyIsCi0JInBhcmVudCIsCi0JInByZWNlZGluZyIsCi0JInByZWNlZGluZy1zaWJsaW5nIiwKLQkic2VsZiIKLSAgICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0JpdEFycmF5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQml0QXJyYXkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzc2NDM2Ni4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQml0QXJyYXkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1NCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotCi0KLXB1YmxpYyBjbGFzcyBCaXRBcnJheSB7Ci0KLSAgICBwcml2YXRlIGludFtdIF9iaXRzOwotICAgIHByaXZhdGUgaW50ICAgX2JpdFNpemU7Ci0gICAgcHJpdmF0ZSBpbnQgICBfaW50U2l6ZTsKLSAgICBwcml2YXRlIGludCAgIF9tYXNrOwotCi0gICAgLy8gVGhpcyB0YWJsZSBpcyB1c2VkIHRvIHByZXZlbnQgZXhwZW5zaXZlIHNoaWZ0IG9wZXJhdGlvbnMKLSAgICAvLyAoVGhlc2Ugb3BlcmF0aW9ucyBhcmUgaW5leHBlbnNpdmUgb24gQ1BVcyBidXQgdmVyeSBleHBlbnNpdmUgb24gSlZNcy4pCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBfbWFza3MgPSB7Ci0JMHg4MDAwMDAwMCwgMHg0MDAwMDAwMCwgMHgyMDAwMDAwMCwgMHgxMDAwMDAwMCwKLQkweDA4MDAwMDAwLCAweDA0MDAwMDAwLCAweDAyMDAwMDAwLCAweDAxMDAwMDAwLAotCTB4MDA4MDAwMDAsIDB4MDA0MDAwMDAsIDB4MDAyMDAwMDAsIDB4MDAxMDAwMDAsCi0JMHgwMDA4MDAwMCwgMHgwMDA0MDAwMCwgMHgwMDAyMDAwMCwgMHgwMDAxMDAwMCwKLQkweDAwMDA4MDAwLCAweDAwMDA0MDAwLCAweDAwMDAyMDAwLCAweDAwMDAxMDAwLAotCTB4MDAwMDA4MDAsIDB4MDAwMDA0MDAsIDB4MDAwMDAyMDAsIDB4MDAwMDAxMDAsCi0JMHgwMDAwMDA4MCwgMHgwMDAwMDA0MCwgMHgwMDAwMDAyMCwgMHgwMDAwMDAxMCwKLQkweDAwMDAwMDA4LCAweDAwMDAwMDA0LCAweDAwMDAwMDAyLCAweDAwMDAwMDAxIH07Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3Rvci4gRGVmaW5lcyB0aGUgaW5pdGlhbCBzaXplIG9mIHRoZSBiaXQgYXJyYXkgKGluIGJpdHMpLgotICAgICAqLwotICAgIHB1YmxpYyBCaXRBcnJheShpbnQgc2l6ZSkgewotCWlmIChzaXplIDwgMzIpIHNpemUgPSAzMjsKLQlfYml0U2l6ZSA9IHNpemU7Ci0JX2ludFNpemUgPSAoX2JpdFNpemUgPj4+IDUpICsgMTsKLQlfYml0cyA9IG5ldyBpbnRbX2ludFNpemUgKyAxXTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIG1hc2sgZm9yIHRoaXMgYml0IGFycmF5LiBUaGUgdXBwZXIgOCBiaXRzIG9mIHRoaXMgbWFzawotICAgICAqIGluZGljYXRlIHRoZSBET00gaW4gd2hpY2ggdGhlIG5vZGVzIGluIHRoaXMgYXJyYXkgYmVsb25nLgotICAgICAqLyAgICAKLSAgICBwdWJsaWMgdm9pZCBzZXRNYXNrKGludCBtYXNrKSB7Ci0JX21hc2sgPSBtYXNrOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNlZSBzZXRNYXNrKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE1hc2soKSB7Ci0JcmV0dXJuKF9tYXNrKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoaXMgYml0IGFycmF5IChpbiBiaXRzKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50IHNpemUoKSB7Ci0JcmV0dXJuKF9iaXRTaXplKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGJpdCBpcyBzZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRCaXQoaW50IGJpdCkgewotCXJldHVybigoX2JpdHNbYml0Pj4+NV0gJiBfbWFza3NbYml0JTMyXSkgIT0gMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbmV4dCBzZXQgYml0IGZyb20gYSBnaXZlbiBwb3NpdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TmV4dEJpdChpbnQgc3RhcnRCaXQpIHsKLQlmb3IgKGludCBpID0gKHN0YXJ0Qml0ID4+PiA1KSA7IGk8PV9pbnRTaXplOyBpKyspIHsKLQkgICAgaW50IGJpdHMgPSBfYml0c1tpXTsKLQkgICAgaWYgKGJpdHMgIT0gMCkgewotCQlmb3IgKGludCBiID0gKHN0YXJ0Qml0ICUgMzIpOyBiPDMyOyBiKyspIHsKLQkJICAgIGlmICgoYml0cyAmIF9tYXNrc1tiXSkgIT0gMCkgewotCQkJcmV0dXJuKChpIDw8IDUpICsgYik7Ci0JCSAgICB9Ci0JCX0KLQkgICAgfQotCSAgICBzdGFydEJpdCA9IDA7Ci0JfQotCXJldHVybihOb2RlSXRlcmF0b3IuRU5EKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBOdGggYml0IHRoYXQgaXMgc2V0IGluIHRoZSBiaXQgYXJyYXkuIFRoZQotICAgICAqIGN1cnJlbnQgcG9zaXRpb24gaXMgY2FjaGVkIGluIHRoZSBmb2xsb3dpbmcgNCB2YXJpYWJsZXMgYW5kIHdpbGwKLSAgICAgKiBoZWxwIHNwZWVkIHVwIGEgc2VxdWVuY2Ugb2YgbmV4dCgpIGNhbGwgaW4gYW4gaW5kZXggaXRlcmF0b3IuIFRoaXMKLSAgICAgKiBtZXRob2QgaXMgYSBtZXNzLCBidXQgaXQgaXMgZmFzdCBhbmQgaXQgd29ya3MsIHNvIGRvbid0IGZ1Y2sgd2l0aCBpdC4KLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBfcG9zID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0gICAgcHJpdmF0ZSBpbnQgX25vZGUgPSAwOwotICAgIHByaXZhdGUgaW50IF9pbnQgPSAwOwotICAgIHByaXZhdGUgaW50IF9iaXQgPSAwOwotCi0gICAgcHVibGljIGZpbmFsIGludCBnZXRCaXROdW1iZXIoaW50IHBvcykgewotCi0JLy8gUmV0dXJuIGxhc3Qgbm9kZSBpZiBwb3NpdGlvbiB3ZSdyZSBsb29raW5nIGZvciBpcyB0aGUgc2FtZQotCWlmIChwb3MgPT0gX3BvcykgcmV0dXJuKF9ub2RlKTsKLQkKLQkvLyBTdGFydCBmcm9tIGJlZ2lubmluZyBvZiBwb3NpdGlvbiB3ZSdyZSBsb29raW5nIGZvciBpcyBiZWZvcmUKLQkvLyB0aGUgcG9pbnQgd2hlcmUgd2UgbGVmdCBvZmYgdGhlIGxhc3QgdGltZS4KLQlpZiAocG9zIDwgX3BvcykgewotCSAgICBfaW50ID0gX2JpdCA9IF9wb3MgPSAwOwotCX0KLQotCS8vIFNjYW4gdGhyb3VnaCB0aGUgYml0IGFycmF5IC0gc2tpcCBpbnRlZ2VycyB0aGF0IGhhdmUgbm8gYml0cyBzZXQKLQlmb3IgKCA7IF9pbnQgPD0gX2ludFNpemU7IF9pbnQrKykgewotCSAgICBpbnQgYml0cyA9IF9iaXRzW19pbnRdOwotCSAgICBpZiAoYml0cyAhPSAwKSB7IC8vIEFueSBiaXRzIHNldD8KLQkJZm9yICggOyBfYml0IDwgMzI7IF9iaXQrKykgewotCQkgICAgaWYgKChiaXRzICYgX21hc2tzW19iaXRdKSAhPSAwKSB7Ci0JCQlpZiAoKytfcG9zID09IHBvcykgewotCQkJICAgIF9ub2RlID0gKChfaW50IDw8IDUpICsgX2JpdCkgLSAxOwotCQkJICAgIHJldHVybiAoX25vZGUpOwotCQkJfQotCQkgICAgfQotCQl9Ci0JCV9iaXQgPSAwOwotCSAgICB9Ci0JfQotCXJldHVybigwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBpbnRlZ2VyIGFycmF5IGluIHdoaWNoIHRoZSBiaXQgYXJyYXkgaXMgY29udGFpbmVkCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGludFtdIGRhdGEoKSB7Ci0JcmV0dXJuKF9iaXRzKTsKLSAgICB9Ci0KLSAgICBpbnQgX2ZpcnN0ID0gSW50ZWdlci5NQVhfVkFMVUU7IC8vIFRoZSBpbmRleCB3aGVyZSBmaXJzdCBzZXQgYml0IGlzCi0gICAgaW50IF9sYXN0ICA9IEludGVnZXIuTUlOX1ZBTFVFOyAvLyBUaGUgX0lOVEVHRVIgSU5ERVhfIHdoZXJlIGxhc3Qgc2V0IGJpdCBpcwotCi0gICAgLyoqCi0gICAgICogU2V0cyBhIGdpdmVuIGJpdAotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEJpdChpbnQgYml0KSB7Ci0JaWYgKGJpdCA+PSBfYml0U2l6ZSkgcmV0dXJuOwotCWZpbmFsIGludCBpID0gKGJpdCA+Pj4gNSk7Ci0JaWYgKGkgPCBfZmlyc3QpIF9maXJzdCA9IGk7Ci0JaWYgKGkgPiBfbGFzdCkgX2xhc3QgPSBpOwotCV9iaXRzW2ldIHw9IF9tYXNrc1tiaXQgJSAzMl07Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWVyZ2UgdHdvIGJpdCBhcnJheXMuIFRoaXMgY3VycmVudGx5IG9ubHkgd29ya3MgZm9yIG5vZGVzIGZyb20KLSAgICAgKiBhIHNpbmdsZSBET00gKGJlY2F1c2UgdGhlcmUgaXMgb25seSBvbmUgX21hc2sgcGVyIGFycmF5KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgQml0QXJyYXkgbWVyZ2UoQml0QXJyYXkgb3RoZXIpIHsKLQkvLyBUYWtlIG90aGVyIGFycmF5J3MgYml0cyBpZiB3ZSBoYXZlIG5vZGUgc2V0Ci0JaWYgKF9sYXN0ID09IC0xKSB7Ci0JICAgIF9iaXRzID0gb3RoZXIuX2JpdHM7Ci0JfQotCS8vIE9ubHkgbWVyZ2UgaWYgb3RoZXIgYXJyYXkgaGFzIGFueSBiaXRzIHNldAotCWVsc2UgaWYgKG90aGVyLl9sYXN0ICE9IC0xKSB7Ci0JICAgIGludCBzdGFydCA9IChfZmlyc3QgPCBvdGhlci5fZmlyc3QpID8gX2ZpcnN0IDogb3RoZXIuX2ZpcnN0OwotCSAgICBpbnQgc3RvcCAgPSAoX2xhc3QgPiBvdGhlci5fbGFzdCkgPyBfbGFzdCA6IG90aGVyLl9sYXN0OwotCi0JICAgIC8vIE1lcmdlIHRoZXNlIGJpdHMgaW50byBvdGhlciBhcnJheSBpZiBvdGhlciBhcnJheSBpcyBsYXJnZXIKLQkgICAgaWYgKG90aGVyLl9pbnRTaXplID4gX2ludFNpemUpIHsKLQkJaWYgKHN0b3AgPiBfaW50U2l6ZSkgc3RvcCA9IF9pbnRTaXplOwotCQlmb3IgKGludCBpPXN0YXJ0OyBpPD1zdG9wOyBpKyspCi0JCSAgICBvdGhlci5fYml0c1tpXSB8PSBfYml0c1tpXTsKLQkJX2JpdHMgPSBvdGhlci5fYml0czsKLQkgICAgfQotCSAgICAvLyBNZXJnZSBvdGhlciBiaXRzIGludG8gdGhpcyBhcnJheSBpZiB0aGlzIGFycmFpIGlzIGxhcmdlL2VxdWFsLgotCSAgICBlbHNlIHsKLQkJaWYgKHN0b3AgPiBvdGhlci5faW50U2l6ZSkgc3RvcCA9IG90aGVyLl9pbnRTaXplOwotCQlmb3IgKGludCBpPXN0YXJ0OyBpPD1zdG9wOyBpKyspCi0JCSAgICBfYml0c1tpXSB8PSBvdGhlci5fYml0c1tpXTsKLQkgICAgfQotCX0KLQlyZXR1cm4odGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVzaXplcyB0aGUgYml0IGFycmF5IC0gdHJ5IHRvIGF2b2lkIHVzaW5nIHRoaXMgbWV0aG9kISEhCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcmVzaXplKGludCBuZXdTaXplKSB7Ci0JaWYgKG5ld1NpemUgPiBfYml0U2l6ZSkgewotCSAgICBfaW50U2l6ZSA9IChuZXdTaXplID4+PiA1KSArIDE7Ci0JICAgIGZpbmFsIGludFtdIG5ld0JpdHMgPSBuZXcgaW50W19pbnRTaXplICsgMV07Ci0JICAgIFN5c3RlbS5hcnJheWNvcHkoX2JpdHMsIDAsIG5ld0JpdHMsIDAsIChfYml0U2l6ZT4+PjUpICsgMSk7Ci0JICAgIF9iaXRzID0gbmV3Qml0czsKLQkgICAgX2JpdFNpemUgPSBuZXdTaXplOwotCX0KLSAgICB9Ci0KLQotfQotCi0KLSAgICAKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RGaWx0ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzA4OTVjNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0RmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLQotcHVibGljIGludGVyZmFjZSBDdXJyZW50Tm9kZUxpc3RGaWx0ZXIgewotICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHRlc3QoaW50IG5vZGUsIGludCBwb3NpdGlvbiwgaW50IGxhc3QsIGludCBjdXJyZW50LAotCQkJCSBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0LCBOb2RlSXRlcmF0b3IgaXRlcik7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZjIwMTMyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9DdXJyZW50Tm9kZUxpc3RJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTg5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy51dGlsLkludGVnZXJBcnJheTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLSAgICBwcml2YXRlIE5vZGVJdGVyYXRvciBfc291cmNlOwotICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBfZG9jT3JkZXI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBDdXJyZW50Tm9kZUxpc3RGaWx0ZXIgX2ZpbHRlcjsKLSAgICBwcml2YXRlIEludGVnZXJBcnJheSBfbm9kZXMgPSBuZXcgSW50ZWdlckFycmF5KCk7Ci0JCi0gICAgcHJpdmF0ZSBpbnQgX2N1cnJlbnQ7CS8vIGluZGV4IGluIF9ub2RlcyBvZiB0aGUgbmV4dCBub2RlIHRvIHRyeQotCQotICAgIHByaXZhdGUgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQ7Ci0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX2N1cnJlbnROb2RlOwotICAgIHByaXZhdGUgaW50IF9sYXN0OwkJCi0KLSAgICBwdWJsaWMgQ3VycmVudE5vZGVMaXN0SXRlcmF0b3IoTm9kZUl0ZXJhdG9yIHNvdXJjZSwgCi0JCQkJICAgQ3VycmVudE5vZGVMaXN0RmlsdGVyIGZpbHRlciwKLQkJCQkgICBpbnQgY3VycmVudE5vZGUsCi0JCQkJICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCkgewotCXRoaXMoc291cmNlLCAhc291cmNlLmlzUmV2ZXJzZSgpLCBmaWx0ZXIsIGN1cnJlbnROb2RlLCB0cmFuc2xldCk7Ci0gICAgfQotCi0gICAgcHVibGljIEN1cnJlbnROb2RlTGlzdEl0ZXJhdG9yKE5vZGVJdGVyYXRvciBzb3VyY2UsIGJvb2xlYW4gZG9jT3JkZXIsCi0JCQkJICAgQ3VycmVudE5vZGVMaXN0RmlsdGVyIGZpbHRlciwKLQkJCQkgICBpbnQgY3VycmVudE5vZGUsCi0JCQkJICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCkgewotCV9zb3VyY2UgPSBzb3VyY2U7Ci0JX2ZpbHRlciA9IGZpbHRlcjsKLQlfdHJhbnNsZXQgPSB0cmFuc2xldDsKLQlfZG9jT3JkZXIgPSBkb2NPcmRlcjsKLQlfY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotCXJldHVybiAhX2RvY09yZGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQl0cnkgewotCSAgICBmaW5hbCBDdXJyZW50Tm9kZUxpc3RJdGVyYXRvciBjbG9uZSA9Ci0JCShDdXJyZW50Tm9kZUxpc3RJdGVyYXRvcilzdXBlci5jbG9uZSgpOwotCSAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCSAgICBjbG9uZS5fbm9kZXMgPSAoSW50ZWdlckFycmF5KV9ub2Rlcy5jbG9uZSgpOwotCSAgICByZXR1cm4gY2xvbmUucmVzZXQoKTsKLQl9Ci0JY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLQkgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcigiSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZC4iKTsgCi0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlfY3VycmVudCA9IDA7Ci0JcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0JZmluYWwgYm9vbGVhbiBkb2NPcmRlciA9IF9kb2NPcmRlcjsKLQlmaW5hbCBpbnQgbGFzdCA9IF9ub2Rlcy5jYXJkaW5hbGl0eSgpOwotCWZpbmFsIGludCBjdXJyZW50Tm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotCWZvciAoaW50IGluZGV4ID0gX2N1cnJlbnQ7IGluZGV4IDwgbGFzdDsgKSB7Ci0JICAgIGZpbmFsIGludCBub2RlID0gX25vZGVzLmF0KGluZGV4KyspOyAvLyBub3RlIGluY3JlbWVudAotCSAgICBmaW5hbCBpbnQgcG9zaXRpb24gPSBkb2NPcmRlciA/IGluZGV4IDogbGFzdCAtIGluZGV4ICsgMTsKLQkgICAgaWYgKF9maWx0ZXIudGVzdChub2RlLCBwb3NpdGlvbiwgbGFzdCwgY3VycmVudE5vZGUsIF90cmFuc2xldCwgdGhpcykpIHsKLQkJX2N1cnJlbnQgPSBpbmRleDsKLQkJcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIEVORDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGludCBjb21wdXRlUG9zaXRpb25PZkxhc3QoKSB7Ci0JaW50IGxhc3RQb3NpdGlvbiA9IDA7Ci0JZmluYWwgYm9vbGVhbiBkb2NPcmRlciA9IF9kb2NPcmRlcjsKLSAgICAgICAgZmluYWwgaW50IGxhc3QgPSBfbm9kZXMuY2FyZGluYWxpdHkoKTsKLSAgICAgICAgZmluYWwgaW50IGN1cnJOb2RlID0gX2N1cnJlbnROb2RlOwotCi0JZm9yIChpbnQgaW5kZXggPSBfY3VycmVudDsgaW5kZXggPCBsYXN0OyApIHsKLSAgICAgICAgICAgIGludCBub2RlSW5kZXggPSBfbm9kZXMuYXQoaW5kZXgrKyk7IC8vIG5vdGUgaW5jcmVtZW50Ci0gICAgICAgICAgICBmaW5hbCBpbnQgcG9zID0gZG9jT3JkZXIgPyBpbmRleCA6IGxhc3QgLSBpbmRleCArIDE7Ci0gICAgICAgICAgICBpZiAoX2ZpbHRlci50ZXN0KG5vZGVJbmRleCwgcG9zLCBsYXN0LCBjdXJyTm9kZSwgX3RyYW5zbGV0LCB0aGlzKSkgewotICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbisrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0JcmV0dXJuIGxhc3RQb3NpdGlvbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCU5vZGVJdGVyYXRvciByZXR2YWwgPSB0aGlzOwotCQotCWlmIChfaXNSZXN0YXJ0YWJsZSkgewotCSAgICAvLyBpdGVyYXRvciBpcyBub3QgYSBjbG9uZQotCSAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlID0gbm9kZSk7Ci0JICAgIC8vIGluY2x1ZGluZyBST09UCi0JICAgIF9ub2Rlcy5jbGVhcigpOwotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0JCV9ub2Rlcy5hZGQobm9kZSk7Ci0JICAgIH0KLQkgICAgX2N1cnJlbnQgPSAwOwotCSAgICByZXR2YWwgPSByZXNldFBvc2l0aW9uKCk7Ci0JfQotCS8vIGNvbXB1dGUgcG9zaXRpb24gb2YgX2xhc3QKLSAgCV9sYXN0ID0gY29tcHV0ZVBvc2l0aW9uT2ZMYXN0KCk7CQotCXJldHVybiByZXR2YWw7Ci0gICAgfQotCQotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLQlyZXR1cm4gKCBfbGFzdCA9PSAtMSApID8gY29tcHV0ZVBvc2l0aW9uT2ZMYXN0KCkgOiBfbGFzdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9zb3VyY2Uuc2V0TWFyaygpOwotCV9tYXJrZWROb2RlID0gX2N1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JX3NvdXJjZS5nb3RvTWFyaygpOwotCV9jdXJyZW50ID0gX21hcmtlZE5vZGU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUFkYXB0ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9ET01BZGFwdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA3M2U4ZWYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUFkYXB0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI2MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5TdHJpcEZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0T3V0cHV0SGFuZGxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRE9NQWRhcHRlciBpbXBsZW1lbnRzIERPTSB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBET01JbXBsIF9kb21JbXBsOwotICAgIHByaXZhdGUgc2hvcnRbXSBfbWFwcGluZzsKLSAgICBwcml2YXRlIHNob3J0W10gX3JldmVyc2U7Ci0gICAgcHJpdmF0ZSBzaG9ydFtdIF9OU21hcHBpbmc7Ci0gICAgcHJpdmF0ZSBzaG9ydFtdIF9OU3JldmVyc2U7Ci0KLSAgICBwcml2YXRlIFN0cmlwRmlsdGVyIF9maWx0ZXIgPSBudWxsOwotICAgIAotICAgIHB1YmxpYyBET01BZGFwdGVyKERPTUltcGwgZG9tLAotCQkgICAgICBTdHJpbmdbXSBuYW1lc0FycmF5LAotCQkgICAgICBTdHJpbmdbXSBuYW1lc3BhY2VBcnJheSkgewotCV9kb21JbXBsID0gZG9tOwotCV9tYXBwaW5nID0gZG9tLmdldE1hcHBpbmcobmFtZXNBcnJheSk7Ci0JX3JldmVyc2UgPSBkb20uZ2V0UmV2ZXJzZU1hcHBpbmcobmFtZXNBcnJheSk7Ci0JX05TbWFwcGluZyA9IGRvbS5nZXROYW1lc3BhY2VNYXBwaW5nKG5hbWVzcGFjZUFycmF5KTsKLQlfTlNyZXZlcnNlID0gZG9tLmdldFJldmVyc2VOYW1lc3BhY2VNYXBwaW5nKG5hbWVzcGFjZUFycmF5KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXR1cE1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIG5hbWVzcGFjZXMpIHsKLQlfbWFwcGluZyA9IF9kb21JbXBsLmdldE1hcHBpbmcobmFtZXMpOwotCV9yZXZlcnNlID0gX2RvbUltcGwuZ2V0UmV2ZXJzZU1hcHBpbmcobmFtZXMpOwotCV9OU21hcHBpbmcgPSBfZG9tSW1wbC5nZXROYW1lc3BhY2VNYXBwaW5nKG5hbWVzcGFjZXMpOwotCV9OU3JldmVyc2UgPSBfZG9tSW1wbC5nZXRSZXZlcnNlTmFtZXNwYWNlTWFwcGluZyhuYW1lc3BhY2VzKTsKLSAgICB9Ci0KLSAgICAvKiogcmV0dXJucyBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmcgdGhlIGRvY3VtZW50IHJvb3QgKi8KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldEl0ZXJhdG9yKCkgewotCXJldHVybiBfZG9tSW1wbC5nZXRJdGVyYXRvcigpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCkgewotCXJldHVybiBfZG9tSW1wbC5nZXRTdHJpbmdWYWx1ZSgpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldENoaWxkcmVuKGZpbmFsIGludCBub2RlKSB7Ci0JTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yID0gX2RvbUltcGwuZ2V0Q2hpbGRyZW4obm9kZSk7Ci0JaWYgKF9maWx0ZXIgPT0gbnVsbCkgewotCSAgICByZXR1cm4oaXRlcmF0b3Iuc2V0U3RhcnROb2RlKG5vZGUpKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGl0ZXJhdG9yID0gX2RvbUltcGwuc3RyaXBwaW5nSXRlcmF0b3IoaXRlcmF0b3IsX21hcHBpbmcsX2ZpbHRlcik7Ci0JICAgIHJldHVybihpdGVyYXRvci5zZXRTdGFydE5vZGUobm9kZSkpOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKSB7Ci0JX2ZpbHRlciA9IGZpbHRlcjsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRUeXBlZENoaWxkcmVuKGZpbmFsIGludCB0eXBlKSB7Ci0JTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yID0gX2RvbUltcGwuZ2V0VHlwZWRDaGlsZHJlbihfcmV2ZXJzZVt0eXBlXSk7Ci0JaWYgKChfcmV2ZXJzZVt0eXBlXSA9PSBET00uVEVYVCkgJiYgKF9maWx0ZXIgIT0gbnVsbCkpCi0JICAgIGl0ZXJhdG9yID0gX2RvbUltcGwuc3RyaXBwaW5nSXRlcmF0b3IoaXRlcmF0b3IsX21hcHBpbmcsX2ZpbHRlcik7Ci0JcmV0dXJuKGl0ZXJhdG9yKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldE5hbWVzcGFjZUF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcywgZmluYWwgaW50IG5zKSB7Ci0JcmV0dXJuIF9kb21JbXBsLmdldE5hbWVzcGFjZUF4aXNJdGVyYXRvcihheGlzLF9OU3JldmVyc2VbbnNdKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcykgewotCU5vZGVJdGVyYXRvciBpdGVyYXRvciA9IF9kb21JbXBsLmdldEF4aXNJdGVyYXRvcihheGlzKTsKLQlpZiAoX2ZpbHRlciAhPSBudWxsKQotCSAgICBpdGVyYXRvciA9IF9kb21JbXBsLnN0cmlwcGluZ0l0ZXJhdG9yKGl0ZXJhdG9yLF9tYXBwaW5nLF9maWx0ZXIpOwotCXJldHVybihpdGVyYXRvcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0VHlwZWRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCB0eXBlKSB7Ci0JTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yID0KLQkgICAgX2RvbUltcGwuZ2V0VHlwZWRBeGlzSXRlcmF0b3IoYXhpcywgX3JldmVyc2VbdHlwZV0pOwotCWlmICgoX3JldmVyc2VbdHlwZV0gPT0gRE9NLlRFWFQpICYmIChfZmlsdGVyICE9IG51bGwpKQotCSAgICBpdGVyYXRvciA9IF9kb21JbXBsLnN0cmlwcGluZ0l0ZXJhdG9yKGl0ZXJhdG9yLF9tYXBwaW5nLF9maWx0ZXIpOwotCXJldHVybihpdGVyYXRvcik7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROdGhEZXNjZW5kYW50KGludCBub2RlLCBpbnQgbikgewotCXJldHVybiBfZG9tSW1wbC5nZXROdGhEZXNjZW5kYW50KG5vZGUsIG4pOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0Tm9kZVZhbHVlSXRlcmF0b3IoTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLAotCQkJCQkgICAgIFN0cmluZyB2YWx1ZSwgYm9vbGVhbiBvcCkgewotCXJldHVybiBfZG9tSW1wbC5nZXROb2RlVmFsdWVJdGVyYXRvcihpdGVyYXRvciwgdmFsdWUsIG9wKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIG9yZGVyTm9kZXMoTm9kZUl0ZXJhdG9yIHNvdXJjZSwgaW50IG5vZGUpIHsKLQlyZXR1cm4gX2RvbUltcGwub3JkZXJOb2Rlcyhzb3VyY2UsIG5vZGUpOwotICAgIH0KLSAgICAgICAgCi0gICAgcHVibGljIGludCBnZXRUeXBlKGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9tYXBwaW5nW19kb21JbXBsLmdldFR5cGUobm9kZSldOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlVHlwZShmaW5hbCBpbnQgbm9kZSkgewotCXJldHVybiBfTlNtYXBwaW5nW19kb21JbXBsLmdldE5hbWVzcGFjZVR5cGUobm9kZSldOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgaW50IGdldFBhcmVudChmaW5hbCBpbnQgbm9kZSkgewotCXJldHVybiBfZG9tSW1wbC5nZXRQYXJlbnQobm9kZSk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRUeXBlZFBvc2l0aW9uKE5vZGVJdGVyYXRvciBpdGVyYXRvciwgaW50IHR5cGUsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9kb21JbXBsLmdldFR5cGVkUG9zaXRpb24oaXRlcmF0b3IsIF9yZXZlcnNlW3R5cGVdLCBub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFR5cGVkTGFzdChOb2RlSXRlcmF0b3IgaXRlcmF0b3IsIGludCB0eXBlLCBpbnQgbm9kZSkgewotCXJldHVybiBfZG9tSW1wbC5nZXRUeXBlZExhc3QoaXRlcmF0b3IsIF9yZXZlcnNlW3R5cGVdLCBub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldEF0dHJpYnV0ZU5vZGUoZmluYWwgaW50IHR5cGUsIGZpbmFsIGludCBlbGVtZW50KSB7Ci0JcmV0dXJuIF9kb21JbXBsLmdldEF0dHJpYnV0ZU5vZGUoX3JldmVyc2VbdHlwZV0sIGVsZW1lbnQpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9kb21JbXBsLmdldE5vZGVOYW1lKG5vZGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlTmFtZShmaW5hbCBpbnQgbm9kZSkgewotCXJldHVybiBfZG9tSW1wbC5nZXROYW1lc3BhY2VOYW1lKG5vZGUpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShmaW5hbCBpbnQgbm9kZSkgewotCXJldHVybiBfZG9tSW1wbC5nZXROb2RlVmFsdWUobm9kZSk7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGNvcHkoZmluYWwgaW50IG5vZGUsIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JICAgIF9kb21JbXBsLmNvcHkobm9kZSwgaGFuZGxlcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGNvcHkoTm9kZUl0ZXJhdG9yIG5vZGVzLCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCSAgICBfZG9tSW1wbC5jb3B5KG5vZGVzLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIHNoYWxsb3dDb3B5KGZpbmFsIGludCBub2RlLCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCSAgICByZXR1cm4gX2RvbUltcGwuc2hhbGxvd0NvcHkobm9kZSwgaGFuZGxlcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKSB7Ci0JcmV0dXJuIF9kb21JbXBsLmxlc3NUaGFuKG5vZGUxLCBub2RlMik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoZmluYWwgaW50IHRleHROb2RlLCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCSAgICBfZG9tSW1wbC5jaGFyYWN0ZXJzKHRleHROb2RlLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShpbnQgaW5kZXgpIHsKLQlyZXR1cm4gX2RvbUltcGwubWFrZU5vZGUoaW5kZXgpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKE5vZGVJdGVyYXRvciBpdGVyKSB7Ci0JcmV0dXJuIF9kb21JbXBsLm1ha2VOb2RlKGl0ZXIpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KSB7Ci0JcmV0dXJuIF9kb21JbXBsLm1ha2VOb2RlTGlzdChpbmRleCk7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChOb2RlSXRlcmF0b3IgaXRlcikgewotCXJldHVybiBfZG9tSW1wbC5tYWtlTm9kZUxpc3QoaXRlcik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRMYW5ndWFnZShpbnQgbm9kZSkgewotCXJldHVybiBfZG9tSW1wbC5nZXRMYW5ndWFnZShub2RlKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGdldFNpemUoKSB7Ci0JcmV0dXJuIF9kb21JbXBsLmdldFNpemUoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSSShTdHJpbmcgdXJpKSB7Ci0JX2RvbUltcGwuc2V0RG9jdW1lbnRVUkkodXJpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKCkgewotCXJldHVybihfZG9tSW1wbC5nZXREb2N1bWVudFVSSSgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKGludCBub2RlKSB7Ci0JcmV0dXJuKF9kb21JbXBsLmdldERvY3VtZW50VVJJKCkpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUJ1aWxkZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9ET01CdWlsZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNjNjdhNTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUJ1aWxkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotcHVibGljIGludGVyZmFjZSBET01CdWlsZGVyIGV4dGVuZHMgQ29udGVudEhhbmRsZXIsIExleGljYWxIYW5kbGVyIHsgfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9ET01JbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIxMDk1MTkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RPTUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMxOTUgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLS8qIElzc3VlcyB0byByZXNvbHZlOgotICAgbykgQWxsIHN0YWNrcyBpbiB0aGUgRE9NQnVpbGRlciBjbGFzcyBoYXZlIGhhcmRjb2RlZCBsZW5ndGgKLSAgIG8pIFRoZXJlIGFyZSBubyBuYW1lc3BhY2Ugbm9kZXMgKGJ1dCBuYW1lc3BhY2UgYXJlIGhhbmRsZWQgY29ycmVjdGx5KS4KLSovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBqYXZhLmlvLkV4dGVybmFsaXphYmxlOwotaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXQ7Ci1pbXBvcnQgamF2YS5pby5PYmplY3RPdXRwdXQ7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy51dGlsLkludGVnZXJBcnJheTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5TQVhBZGFwdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5IYXNodGFibGU7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBET01JbXBsIGltcGxlbWVudHMgRE9NLCBFeHRlcm5hbGl6YWJsZSB7Ci0KLSAgICAvLyBlbXB0eSBTdHJpbmcgZm9yIG51bGwgYXR0cmlidXRlIHZhbHVlcwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBFTVBUWVNUUklORyA9ICIiOwotCi0gICAgLy8gZW1wdHkgaXRlcmF0b3IgdG8gYmUgcmV0dXJuZWQgd2hlbiB0aGVyZSBhcmUgbm8gY2hpbGRyZW4KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBOb2RlSXRlcmF0b3IgRU1QVFlJVEVSQVRPUiA9IG5ldyBOb2RlSXRlcmF0b3IoKSB7Ci0JICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgcmVzZXQoKSB7IHJldHVybiB0aGlzOyB9Ci0JICAgIHB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7IHJldHVybiB0aGlzOyB9Ci0JICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsgcmV0dXJuIE5VTEw7IH0KLQkgICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHt9Ci0JICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkge30KLQkgICAgcHVibGljIGludCBnZXRMYXN0KCkgeyByZXR1cm4gMDsgfQotCSAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgeyByZXR1cm4gMDsgfQotCSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7IHJldHVybiB0aGlzOyB9Ci0JICAgIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpIHsgcmV0dXJuIGZhbHNlOyB9Ci0JICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgcmVzZXRPbmNlKCkgeyByZXR1cm4gdGhpczsgfQotCX07Ci0KLSAgICAvLyBDb250YWlucyB0aGUgbnVtYmVyIG9mIG5vZGVzIGFuZCBhdHRyaWJ1dGUgbm9kZXMgaW4gdGhlIHRyZWUKLSAgICBwcml2YXRlIGludCAgICAgICBfdHJlZU5vZGVMaW1pdDsKLSAgICBwcml2YXRlIGludCAgICAgICBfZmlyc3RBdHRyaWJ1dGVOb2RlOwotCi0gICAgLy8gTm9kZS10by10eXBlLCB0eXBlLXRvLW5hbWUsIGFuZCBuYW1lLXRvLXR5cGUgbWFwcGluZ3MKLSAgICBwcml2YXRlIHNob3J0W10gICBfdHlwZTsKLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfdHlwZXMgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nW10gIF9uYW1lc0FycmF5OwotCi0gICAgLy8gVHJlZSBuYXZpZ2F0aW9uIGFycmF5cwotICAgIHByaXZhdGUgaW50W10gICAgIF9wYXJlbnQ7Ci0gICAgcHJpdmF0ZSBpbnRbXSAgICAgX25leHRTaWJsaW5nOwotICAgIHByaXZhdGUgaW50W10gICAgIF9vZmZzZXRPckNoaWxkOyAvLyBTZXJ2ZXMgdHdvIHB1cnBvc2VzICEhIQotICAgIHByaXZhdGUgaW50W10gICAgIF9sZW5ndGhPckF0dHI7ICAvLyBTZXJ2ZXMgdHdvIHB1cnBvc2VzICEhIQotCi0gICAgLy8gSG9sZHMgY29udGVudHMgb2YgdGV4dC9jb21tZW50IG5vZGVzIGFuZCBhdHRyaWJ1dGUgdmFsdWVzCi0gICAgcHJpdmF0ZSBjaGFyW10gICAgX3RleHQ7Ci0KLSAgICAvLyBOYW1lc3BhY2UgcmVsYXRlZCBzdHVmZgotICAgIHByaXZhdGUgU3RyaW5nW10gIF91cmlBcnJheTsKLSAgICBwcml2YXRlIFN0cmluZ1tdICBfcHJlZml4QXJyYXk7Ci0gICAgcHJpdmF0ZSBzaG9ydFtdICAgX25hbWVzcGFjZTsKLSAgICBwcml2YXRlIHNob3J0W10gICBfcHJlZml4OwotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9uc0luZGV4ID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgLy8gVHJhY2tzIHdoaWNoIHRleHRub2RlcyBhcmUgd2hpdGVzcGFjZXMgYW5kIHdoaWNoIGFyZSBub3QKLSAgICBwcml2YXRlIEJpdEFycmF5ICBfd2hpdGVzcGFjZTsgLy8gdGFrZXMgeG1sOnNwYWNlIGludG8gYWNjLgotCi0gICAgLy8gVGhlIFVSSSB0byB0aGlzIGRvY3VtZW50Ci0gICAgcHJpdmF0ZSBTdHJpbmcgICAgX2RvY3VtZW50VVJJOwotCi0gICAgLy8gU3VwcG9ydCBmb3IgYWNjZXNzL25hdmlnYXRpb24gdGhyb3VnaCBvcmcudzNjLmRvbSBBUEkKLSAgICBwcml2YXRlIE5vZGVbXSBfbm9kZXM7Ci0gICAgcHJpdmF0ZSBOb2RlTGlzdFtdIF9ub2RlTGlzdHM7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgTm9kZUxpc3QgRW1wdHlOb2RlTGlzdDsKLSAgICBwcml2YXRlIHN0YXRpYyBOYW1lZE5vZGVNYXAgRW1wdHlOYW1lZE5vZGVNYXA7Ci0KLSAgICAvKioKLSAgICAgKiBEZWZpbmUgdGhlIG9yaWdpbiBvZiB0aGUgZG9jdW1lbnQgZnJvbSB3aGljaCB0aGUgdHJlZSB3YXMgYnVpbHQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudFVSSShTdHJpbmcgdXJpKSB7Ci0JX2RvY3VtZW50VVJJID0gdXJpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG9yaWdpbiBvZiB0aGUgZG9jdW1lbnQgZnJvbSB3aGljaCB0aGUgdHJlZSB3YXMgYnVpbHQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VVJJKCkgewotCXJldHVybihfZG9jdW1lbnRVUkkpOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRVUkkoaW50IG5vZGUpIHsKLQlyZXR1cm4oX2RvY3VtZW50VVJJKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXR1cE1hcHBpbmcoU3RyaW5nW10gbmFtZXMsIFN0cmluZ1tdIG5hbWVzcGFjZXMpIHsKLQkvLyBUaGlzIG1ldGhvZCBvbmx5IGhhcyBhIGZ1bmN0aW9uIGluIERPTSBhZGFwdGVycwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgJ3RydWUnIGlmIGEgc3BlY2lmaWMgbm9kZSBpcyBhbiBlbGVtZW50IChvZiBhbnkgdHlwZSkKLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaXNFbGVtZW50KGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuICgobm9kZSA8IF9maXJzdEF0dHJpYnV0ZU5vZGUpICYmIChfdHlwZVtub2RlXSA+PSBOVFlQRVMpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhlIHRyZWUgKHVzZWQgZm9yIGluZGV4aW5nKQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKLQlyZXR1cm4oX3R5cGUubGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXJ0IG9mIHRoZSBET00gaW50ZXJmYWNlIC0gbm8gZnVuY3Rpb24gaGVyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKSB7IH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIG5vZGUxIGNvbWVzIGJlZm9yZSBub2RlMiBpbiBkb2N1bWVudCBvcmRlcgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGludCBub2RlMSwgaW50IG5vZGUyKSB7Ci0JaWYgKChub2RlMiA8IF90cmVlTm9kZUxpbWl0KSAmJiAobm9kZTEgPCBub2RlMikpCi0JICAgIHJldHVybih0cnVlKTsKLQllbHNlCi0JICAgIHJldHVybihmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIG9yZy53M2MuZG9tLk5vZGUgZnJvbSBhIG5vZGUgaW4gdGhlIHRyZWUKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShpbnQgaW5kZXgpIHsKLQlpZiAoX25vZGVzID09IG51bGwpIHsKLQkgICAgX25vZGVzID0gbmV3IE5vZGVbX3R5cGUubGVuZ3RoXTsKLQl9Ci0JcmV0dXJuIF9ub2Rlc1tpbmRleF0gIT0gbnVsbAotCSAgICA/IF9ub2Rlc1tpbmRleF0KLQkgICAgOiAoX25vZGVzW2luZGV4XSA9IG5ldyBOb2RlSW1wbChpbmRleCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBvcmcudzNjLmRvbS5Ob2RlIGZyb20gYSBub2RlIGluIGFuIGl0ZXJhdG9yCi0gICAgICogVGhlIGl0ZXJhdG9yIG1vc3QgYmUgc3RhcnRlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkCi0gICAgICovCi0gICAgcHVibGljIE5vZGUgbWFrZU5vZGUoTm9kZUl0ZXJhdG9yIGl0ZXIpIHsKLQlyZXR1cm4gbWFrZU5vZGUoaXRlci5uZXh0KCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBvcmcudzNjLmRvbS5Ob2RlTGlzdCBmcm9tIGEgbm9kZSBpbiB0aGUgdHJlZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlTGlzdCBtYWtlTm9kZUxpc3QoaW50IGluZGV4KSB7Ci0JaWYgKF9ub2RlTGlzdHMgPT0gbnVsbCkgewotCSAgICBfbm9kZUxpc3RzID0gbmV3IE5vZGVMaXN0W190eXBlLmxlbmd0aF07Ci0JfQotCXJldHVybiBfbm9kZUxpc3RzW2luZGV4XSAhPSBudWxsCi0JICAgID8gX25vZGVMaXN0c1tpbmRleF0KLQkgICAgOiAoX25vZGVMaXN0c1tpbmRleF0gPSBuZXcgTm9kZUxpc3RJbXBsKGluZGV4KSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIG9yZy53M2MuZG9tLk5vZGVMaXN0IGZyb20gYSBub2RlIGl0ZXJhdG9yCi0gICAgICogVGhlIGl0ZXJhdG9yIG1vc3QgYmUgc3RhcnRlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkCi0gICAgICovCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChOb2RlSXRlcmF0b3IgaXRlcikgewotCXJldHVybiBuZXcgTm9kZUxpc3RJbXBsKGl0ZXIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhbiBlbXB0eSBvcmcudzNjLmRvbS5Ob2RlTGlzdAotICAgICAqLwotICAgIHByaXZhdGUgTm9kZUxpc3QgZ2V0RW1wdHlOb2RlTGlzdCgpIHsKLQlyZXR1cm4gRW1wdHlOb2RlTGlzdCAhPSBudWxsCi0JICAgID8gRW1wdHlOb2RlTGlzdAotCSAgICA6IChFbXB0eU5vZGVMaXN0ID0gbmV3IE5vZGVMaXN0SW1wbChuZXcgaW50WzBdKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGVtcHR5IG9yZy53M2MuZG9tLk5hbWVkTm9kZU1hcAotICAgICAqLwotICAgIHByaXZhdGUgTmFtZWROb2RlTWFwIGdldEVtcHR5TmFtZWROb2RlTWFwKCkgewotCXJldHVybiBFbXB0eU5hbWVkTm9kZU1hcCAhPSBudWxsCi0JICAgID8gRW1wdHlOYW1lZE5vZGVNYXAKLQkgICAgOiAoRW1wdHlOYW1lZE5vZGVNYXAgPSBuZXcgTmFtZWROb2RlTWFwSW1wbChuZXcgaW50WzBdKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRXhjZXB0aW9uIHRocm93biBieSBtZXRob2RzIGluIGlubmVyIGNsYXNzZXMgaW1wbGVtZW50aW5nCi0gICAgICogdmFyaW91cyBvcmcudzNjLmRvbSBpbnRlcmZhY2VzIChiZWxvdykKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBleHRlbmRzIERPTUV4Y2VwdGlvbiB7Ci0JcHVibGljIE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpIHsKLQkgICAgc3VwZXIoTk9UX1NVUFBPUlRFRF9FUlIsICJtb2RpZmljYXRpb24gbm90IHN1cHBvcnRlZCIpOwotCX0KLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJbXBsZW1lbnRhdGlvbiBvZiBvcmcudzNjLmRvbS5Ob2RlTGlzdAotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgTm9kZUxpc3RJbXBsIGltcGxlbWVudHMgTm9kZUxpc3QgewotCXByaXZhdGUgZmluYWwgaW50W10gX25vZGVzOwotCi0JcHVibGljIE5vZGVMaXN0SW1wbChpbnQgbm9kZSkgewotCSAgICBfbm9kZXMgPSBuZXcgaW50WzFdOwotCSAgICBfbm9kZXNbMF0gPSBub2RlOwotCX0KLQotCXB1YmxpYyBOb2RlTGlzdEltcGwoaW50W10gbm9kZXMpIHsKLQkgICAgX25vZGVzID0gbm9kZXM7Ci0JfQotICAgICAgICAgICAgICAgICAgCi0JcHVibGljIE5vZGVMaXN0SW1wbChOb2RlSXRlcmF0b3IgaXRlcikgewotCSAgICBmaW5hbCBJbnRlZ2VyQXJyYXkgbGlzdCA9IG5ldyBJbnRlZ2VyQXJyYXkoKTsKLQkgICAgaW50IG5vZGU7Ci0JICAgIHdoaWxlICgobm9kZSA9IGl0ZXIubmV4dCgpKSAhPSBOb2RlSXRlcmF0b3IuRU5EKSB7Ci0JCWxpc3QuYWRkKG5vZGUpOwotCSAgICB9ICAgICAgICAgCi0JICAgIF9ub2RlcyA9IGxpc3QudG9JbnRBcnJheSgpOyAgICAgICAgIAotCX0KLQotCXB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotCSAgICByZXR1cm4gX25vZGVzLmxlbmd0aDsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCkgewotCSAgICByZXR1cm4gbWFrZU5vZGUoX25vZGVzW2luZGV4XSk7Ci0JfQotICAgIH0KLQotICAgICAgICAgICAgICAgICAgCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSW1wbGVtZW50YXRpb24gb2Ygb3JnLnczYy5kb20uTmFtZWROb2RlTWFwCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBOYW1lZE5vZGVNYXBJbXBsIGltcGxlbWVudHMgTmFtZWROb2RlTWFwIHsKLQotCXByaXZhdGUgZmluYWwgaW50W10gX25vZGVzOwotCQkKLQlwdWJsaWMgTmFtZWROb2RlTWFwSW1wbChpbnRbXSBub2RlcykgewotCSAgICBfbm9kZXMgPSBub2RlczsKLQl9Ci0JCQotCXB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgewotCSAgICByZXR1cm4gX25vZGVzLmxlbmd0aDsKLQl9Ci0JCQotCXB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbShTdHJpbmcgbmFtZSkgewotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IF9ub2Rlcy5sZW5ndGg7IGkrKykgewotCQlpZiAobmFtZS5lcXVhbHMoZ2V0Tm9kZU5hbWUoX25vZGVzW2ldKSkpIHsKLQkJICAgIHJldHVybiBtYWtlTm9kZShfbm9kZXNbaV0pOwotCQl9Ci0JICAgIH0KLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotCQkKLQlwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCkgewotCSAgICByZXR1cm4gbWFrZU5vZGUoX25vZGVzW2luZGV4XSk7Ci0JfQotCQkKLQlwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW0oU3RyaW5nIG5hbWUpIHsKLQkgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOwotCX0KLQkJCi0JcHVibGljIE5vZGUgc2V0TmFtZWRJdGVtKE5vZGUgbm9kZSkgewotCSAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7Ci0JfQotCi0JcHVibGljIE5vZGUgZ2V0TmFtZWRJdGVtTlMoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsKSB7Ci0JICAgIHJldHVybihnZXROYW1lZEl0ZW0odXJpKyc6Jytsb2NhbCkpOwotCX0KLQotCXB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgbm9kZSkgewotCSAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7Ci0JfQotCi0JcHVibGljIE5vZGUgcmVtb3ZlTmFtZWRJdGVtTlMoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsKSB7Ci0JICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKLQl9Ci0KLSAgICB9Ci0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEltcGxlbWVudGF0aW9uIG9mIG9yZy53M2MuZG9tLk5vZGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIE5vZGVJbXBsIGltcGxlbWVudHMgTm9kZSB7Ci0KLQlwcml2YXRlIGZpbmFsIGludCBfaW5kZXg7Ci0KLQlwdWJsaWMgTm9kZUltcGwoaW50IGluZGV4KSB7Ci0JICAgIF9pbmRleCA9IGluZGV4OwotCX0KLQotCXB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZSgpIHsKLQkgICAgc3dpdGNoIChfdHlwZVtfaW5kZXhdKSB7Ci0JICAgIGNhc2UgUk9PVDoKLQkJcmV0dXJuIE5vZGUuRE9DVU1FTlRfTk9ERTsKLQkJCi0JICAgIGNhc2UgVEVYVDoKLQkJcmV0dXJuIE5vZGUuVEVYVF9OT0RFOwotCQkKLQkgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OOgotCQlyZXR1cm4gTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU7Ci0JCQotCSAgICBjYXNlIENPTU1FTlQ6Ci0JCXJldHVybiBOb2RlLkNPTU1FTlRfTk9ERTsKLQkJCi0JICAgIGRlZmF1bHQ6Ci0JCXJldHVybiBfaW5kZXggPCBfZmlyc3RBdHRyaWJ1dGVOb2RlCi0JCSAgICA/IE5vZGUuRUxFTUVOVF9OT0RFIDogTm9kZS5BVFRSSUJVVEVfTk9ERTsKLQkgICAgfQotCX0KLQkJCi0JcHVibGljIE5vZGUgZ2V0UGFyZW50Tm9kZSgpIHsKLQkgICAgZmluYWwgaW50IHBhcmVudCA9IGdldFBhcmVudChfaW5kZXgpOwotCSAgICByZXR1cm4gcGFyZW50ID4gTlVMTCA/IG1ha2VOb2RlKHBhcmVudCkgOiBudWxsOwotCX0KLQkJCi0JcHVibGljIE5vZGUgYXBwZW5kQ2hpbGQoTm9kZSBub2RlKSB0aHJvd3MgRE9NRXhjZXB0aW9uIHsKLQkgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOwotCX0KLQkJCi0JcHVibGljIE5vZGUgY2xvbmVOb2RlKGJvb2xlYW4gZGVlcCkgewotCSAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7Ci0JfQotCQkKLQlwdWJsaWMgTmFtZWROb2RlTWFwIGdldEF0dHJpYnV0ZXMoKSB7Ci0JICAgIGlmIChnZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7Ci0JCWludCBhdHRyaWJ1dGUgPSBfbGVuZ3RoT3JBdHRyW19pbmRleF07Ci0JCWlmIChhdHRyaWJ1dGUgIT0gTlVMTCkgewotCQkgICAgZmluYWwgSW50ZWdlckFycmF5IGF0dHJpYnV0ZXMgPSBuZXcgSW50ZWdlckFycmF5KDQpOwotCQkgICAgZG8gewotCQkJYXR0cmlidXRlcy5hZGQoYXR0cmlidXRlKTsKLQkJICAgIH0KLQkJICAgIHdoaWxlICgoYXR0cmlidXRlID0gX25leHRTaWJsaW5nW2F0dHJpYnV0ZV0pICE9IDApOwotCQkgICAgcmV0dXJuIG5ldyBOYW1lZE5vZGVNYXBJbXBsKGF0dHJpYnV0ZXMudG9JbnRBcnJheSgpKTsKLQkJfQotCQllbHNlIHsKLQkJICAgIHJldHVybiBnZXRFbXB0eU5hbWVkTm9kZU1hcCgpOwotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXJldHVybiBudWxsOwotCSAgICB9Ci0JfQotCi0JcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKSB7Ci0JICAgIGlmIChoYXNDaGlsZE5vZGVzKCkpIHsKLQkJZmluYWwgSW50ZWdlckFycmF5IGNoaWxkcmVuID0gbmV3IEludGVnZXJBcnJheSg4KTsKLQkJaW50IGNoaWxkID0gX29mZnNldE9yQ2hpbGRbX2luZGV4XTsKLQkJZG8gewotCQkgICAgY2hpbGRyZW4uYWRkKGNoaWxkKTsKLQkJfQotCQl3aGlsZSAoKGNoaWxkID0gX25leHRTaWJsaW5nW2NoaWxkXSkgIT0gMCk7Ci0JCXJldHVybiBuZXcgTm9kZUxpc3RJbXBsKGNoaWxkcmVuLnRvSW50QXJyYXkoKSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXJldHVybiBnZXRFbXB0eU5vZGVMaXN0KCk7Ci0JICAgIH0KLQl9Ci0JCQotCXB1YmxpYyBOb2RlIGdldEZpcnN0Q2hpbGQoKSB7Ci0JICAgIHJldHVybiBoYXNDaGlsZE5vZGVzKCkKLQkJPyBtYWtlTm9kZShfb2Zmc2V0T3JDaGlsZFtfaW5kZXhdKQotCQk6IG51bGw7Ci0JfQotCQkKLQlwdWJsaWMgTm9kZSBnZXRMYXN0Q2hpbGQoKSB7Ci0JICAgIHJldHVybiBoYXNDaGlsZE5vZGVzKCkKLQkJPyBtYWtlTm9kZShsYXN0Q2hpbGQoX2luZGV4KSkKLQkJOiBudWxsOwotCX0KLQkJCi0JcHVibGljIE5vZGUgZ2V0TmV4dFNpYmxpbmcoKSB7Ci0JICAgIGZpbmFsIGludCBuZXh0ID0gX25leHRTaWJsaW5nW19pbmRleF07Ci0JICAgIHJldHVybiBuZXh0ICE9IDAgPyBtYWtlTm9kZShuZXh0KSA6IG51bGw7Ci0JfQotCQkKLQlwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lKCkgewotCSAgICBzd2l0Y2ggKF90eXBlW19pbmRleF0pIHsKLQkgICAgY2FzZSBST09UOgotCQlyZXR1cm4gIiNkb2N1bWVudCI7Ci0JICAgIGNhc2UgVEVYVDoKLQkJcmV0dXJuICIjdGV4dCI7Ci0JICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTjoKLQkJcmV0dXJuICIjcGkiOwotCSAgICBjYXNlIENPTU1FTlQ6Ci0JCXJldHVybiAiI2NvbW1lbnQiOwotCSAgICBkZWZhdWx0OgotCQlyZXR1cm4gRE9NSW1wbC50aGlzLmdldE5vZGVOYW1lKF9pbmRleCk7Ci0JICAgIH0KLQl9Ci0JCQotCXB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKCkgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0JICAgIHJldHVybiBET01JbXBsLnRoaXMuZ2V0Tm9kZVZhbHVlKF9pbmRleCk7Ci0JfQotCQkKLQlwdWJsaWMgRG9jdW1lbnQgZ2V0T3duZXJEb2N1bWVudCgpIHsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotCQkKLQkvLz8/PyBob3cgZG9lcyBpdCB3b3JrIHdpdGggYXR0cmlidXRlcwotCXB1YmxpYyBOb2RlIGdldFByZXZpb3VzU2libGluZygpIHsKLQkgICAgaW50IG5vZGUgPSBfcGFyZW50W19pbmRleF07Ci0JICAgIGlmIChub2RlID4gTlVMTCkgewotCQlpbnQgcHJldiA9IC0xOwotCQlub2RlID0gX29mZnNldE9yQ2hpbGRbbm9kZV07Ci0JCXdoaWxlIChub2RlICE9IF9pbmRleCkgewotCQkgICAgbm9kZSA9IF9uZXh0U2libGluZ1twcmV2ID0gbm9kZV07Ci0JCX0KLQkJaWYgKHByZXYgIT0gLTEpIHsKLQkJICAgIHJldHVybiBtYWtlTm9kZShwcmV2KTsKLQkJfQotCSAgICB9Ci0JICAgIHJldHVybiBudWxsOwotCX0KLQkJCi0JcHVibGljIGJvb2xlYW4gaGFzQ2hpbGROb2RlcygpIHsKLQkgICAgc3dpdGNoIChnZXROb2RlVHlwZSgpKSB7Ci0JICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREU6Ci0JICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFOgotCQlyZXR1cm4gX29mZnNldE9yQ2hpbGRbX2luZGV4XSAhPSAwOwotCi0JICAgIGRlZmF1bHQ6Ci0JCXJldHVybiBmYWxzZTsKLQkgICAgfQotCX0KLQkJCi0JcHVibGljIE5vZGUgaW5zZXJ0QmVmb3JlKE5vZGUgbjEsIE5vZGUgbjIpIHRocm93cyBET01FeGNlcHRpb24gewotCSAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7Ci0JfQotCQkKLQlwdWJsaWMgTm9kZSByZW1vdmVDaGlsZChOb2RlIG4pIHRocm93cyBET01FeGNlcHRpb24gewotCSAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCk7Ci0JfQotCQkKLQlwdWJsaWMgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuMSwgTm9kZSBuMikgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0JICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKLQl9Ci0JCQotCXB1YmxpYyB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgcykgdGhyb3dzIERPTUV4Y2VwdGlvbiB7Ci0JICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBub3JtYWxpemUoKSB7Ci0JICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oKTsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pIHsKLQkgICAgcmV0dXJuIGZhbHNlOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkgewotCSAgICByZXR1cm4gX3VyaUFycmF5W19uYW1lc3BhY2VbX3R5cGVbX2luZGV4XSAtIE5UWVBFU11dOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0UHJlZml4KCkgewotCSAgICByZXR1cm4gX3ByZWZpeEFycmF5W19wcmVmaXhbX2luZGV4XV07Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpIHsKLQkgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkgewotCSAgICByZXR1cm4gRE9NSW1wbC50aGlzLmdldExvY2FsTmFtZShfaW5kZXgpOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKSB7Ci0JICAgIHJldHVybiAoX2xlbmd0aE9yQXR0cltfaW5kZXhdICE9IE5VTEwpOwotCX0KLQotICAgIH0KLQotICAgIC8vIEEgc2luZ2xlIGNvcHkgKGNhY2hlKSBvZiBFbGVtZW50RmlsdGVyCi0gICAgcHJpdmF0ZSBGaWx0ZXIgX2VsZW1lbnRGaWx0ZXI7Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZmlsdGVyIHRoYXQgbGV0cyBvbmx5IGVsZW1lbnQgbm9kZXMgdGhyb3VnaAotICAgICAqLwotICAgIHByaXZhdGUgRmlsdGVyIGdldEVsZW1lbnRGaWx0ZXIoKSB7Ci0JaWYgKF9lbGVtZW50RmlsdGVyID09IG51bGwpIHsKLQkgICAgX2VsZW1lbnRGaWx0ZXIgPSBuZXcgRmlsdGVyKCkgewotCQkgICAgcHVibGljIGJvb2xlYW4gdGVzdChpbnQgbm9kZSkgewotCQkJcmV0dXJuIGlzRWxlbWVudChub2RlKTsKLQkJICAgIH0KLQkJfTsKLQl9Ci0JcmV0dXJuIF9lbGVtZW50RmlsdGVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudGF0aW9uIG9mIGEgZmlsdGVyIHRoYXQgb25seSByZXR1cm5zIG5vZGVzIG9mIGEKLSAgICAgKiBjZXJ0YWluIHR5cGUgKGluc3RhbmNpYXRlIHRocm91Z2ggZ2V0VHlwZUZpbHRlcigpKS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgewotCXByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLSAgICAgICAgICAgICAgICAgIAotCXB1YmxpYyBUeXBlRmlsdGVyKGludCB0eXBlKSB7Ci0JICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0JfQotICAgICAgICAgICAgICAgICAgCi0JcHVibGljIGJvb2xlYW4gdGVzdChpbnQgbm9kZSkgewotCSAgICByZXR1cm4gX3R5cGVbbm9kZV0gPT0gX25vZGVUeXBlOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbm9kZSB0eXBlIGZpbHRlciAoaW1wbGVtZW50YXRpb24gb2YgRmlsdGVyKQotICAgICAqLwotICAgIHB1YmxpYyBGaWx0ZXIgZ2V0VHlwZUZpbHRlcihpbnQgdHlwZSkgewotCXJldHVybiBuZXcgVHlwZUZpbHRlcih0eXBlKTsKLSAgICB9Ci0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgY2hpbGRyZW4gb2YgYSBnaXZlbiBub2RlCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBDaGlsZHJlbkl0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0JLy8gY2hpbGQgdG8gcmV0dXJuIG5leHQKLQlwcml2YXRlIGludCBfY3VycmVudENoaWxkOwotICAgICAgICAgCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoZmluYWwgaW50IG5vZGUpIHsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCV9jdXJyZW50Q2hpbGQgPSBoYXNDaGlsZHJlbihub2RlKQotCQkgICAgPyBfb2Zmc2V0T3JDaGlsZFtfc3RhcnROb2RlID0gbm9kZV0gOiBFTkQ7Ci0JCXJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICBmaW5hbCBpbnQgbm9kZSA9IF9jdXJyZW50Q2hpbGQ7Ci0JICAgIF9jdXJyZW50Q2hpbGQgPSBfbmV4dFNpYmxpbmdbbm9kZV07Ci0JICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotCX0KLQotCXB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0JICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnRDaGlsZDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX2N1cnJlbnRDaGlsZCA9IF9tYXJrZWROb2RlOwotCX0KLQotICAgIH0gLy8gZW5kIG9mIENoaWxkcmVuSXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBwYXJlbnQgb2YgYSBnaXZlbiBub2RlCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBQYXJlbnRJdGVyYXRvciBleHRlbmRzIE5vZGVJdGVyYXRvckJhc2UgewotCS8vIGNhbmRpZGF0ZSBwYXJlbnQgbm9kZQotCXByaXZhdGUgaW50IF9ub2RlOwotCXByaXZhdGUgaW50IF9ub2RlVHlwZSA9IC0xOwotICAgICAgICAgCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCV9ub2RlID0gX3BhcmVudFtfc3RhcnROb2RlID0gbm9kZV07Ci0JCXJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotICAgICAgICAgICAgIAotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0Tm9kZVR5cGUoZmluYWwgaW50IHR5cGUpIHsKLQkgICAgX25vZGVUeXBlID0gdHlwZTsKLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICBpbnQgcmVzdWx0ID0gX25vZGU7Ci0JICAgIGlmICgoX25vZGVUeXBlICE9IC0xKSAmJiAoX3R5cGVbX25vZGVdICE9IF9ub2RlVHlwZSkpCi0JCXJlc3VsdCA9IEVORDsKLQkgICAgZWxzZQotCQlyZXN1bHQgPSBfbm9kZTsKLQkgICAgX25vZGUgPSBFTkQ7Ci0JICAgIHJldHVybiByZXR1cm5Ob2RlKHJlc3VsdCk7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQkgICAgX21hcmtlZE5vZGUgPSBfbm9kZTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX25vZGUgPSBfbWFya2VkTm9kZTsKLQl9Ci0gICAgfSAvLyBlbmQgb2YgUGFyZW50SXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGNoaWxkcmVuIG9mIGEgZ2l2ZW4gdHlwZSBmb3IgYSBnaXZlbiBub2RlLgotICAgICAqIFRoZSBmdW5jdGlvbmFsaXR5IGNob3VsZCBiZSBhY2hpZXZlZCBieSBwdXR0aW5nIGEgZmlsdGVyIG9uIHRvcAotICAgICAqIG9mIGEgYmFzaWMgY2hpbGQgaXRlcmF0b3IsIGJ1dCBhIHNwZWNpYWxpc2VkIGl0ZXJhdG9yIGlzIHVzZWQKLSAgICAgKiBmb3IgZWZmaWNpZW5jeSAoYm90aCBzcGVlZCBhbmQgc2l6ZSBvZiB0cmFuc2xldCkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlZENoaWxkcmVuSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQlwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0JLy8gbm9kZSB0byBjb25zaWRlciBuZXh0Ci0JcHJpdmF0ZSBpbnQgX2N1cnJlbnRDaGlsZDsKLSAgICAgICAgIAotCXB1YmxpYyBUeXBlZENoaWxkcmVuSXRlcmF0b3IoaW50IG5vZGVUeXBlKSB7Ci0JICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotCX0KLQotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotCQlfY3VycmVudENoaWxkID0gaGFzQ2hpbGRyZW4obm9kZSkKLQkJICAgID8gX29mZnNldE9yQ2hpbGRbX3N0YXJ0Tm9kZSA9IG5vZGVdIDogRU5EOwotCQlyZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotCSAgICB9Ci0JICAgIHJldHVybiB0aGlzOwotCX0KLQotCXB1YmxpYyBpbnQgbmV4dCgpIHsKLQkgICAgZm9yIChpbnQgbm9kZSA9IF9jdXJyZW50Q2hpbGQ7IG5vZGUgIT0gRU5EOwotCQkgbm9kZSA9IF9uZXh0U2libGluZ1tub2RlXSkgewotCQlpZiAoX3R5cGVbbm9kZV0gPT0gX25vZGVUeXBlKSB7Ci0JCSAgICBfY3VycmVudENoaWxkID0gX25leHRTaWJsaW5nW25vZGVdOwotCQkgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0JCX0KLQkgICAgfQotCSAgICByZXR1cm4gRU5EOwotCX0KLQotCXB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0JICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnRDaGlsZDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX2N1cnJlbnRDaGlsZCA9IF9tYXJrZWROb2RlOwotCX0KLSAgICB9IC8vIGVuZCBvZiBUeXBlZENoaWxkcmVuSXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGNoaWxkcmVuIHdpdGhpbiBhIGdpdmVuIG5hbWVzcGFjZSBmb3IgYQotICAgICAqIGdpdmVuIG5vZGUuIFRoZSBmdW5jdGlvbmFsaXR5IGNob3VsZCBiZSBhY2hpZXZlZCBieSBwdXR0aW5nIGEKLSAgICAgKiBmaWx0ZXIgb24gdG9wIG9mIGEgYmFzaWMgY2hpbGQgaXRlcmF0b3IsIGJ1dCBhIHNwZWNpYWxpc2VkCi0gICAgICogaXRlcmF0b3IgaXMgdXNlZCBmb3IgZWZmaWNpZW5jeSAoYm90aCBzcGVlZCBhbmQgc2l6ZSBvZiB0cmFuc2xldCkuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBOYW1lc3BhY2VDaGlsZHJlbkl0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0JcHJpdmF0ZSBmaW5hbCBpbnQgX25zVHlwZTsKLQlwcml2YXRlIGludCBfY3VycmVudENoaWxkOwotICAgICAgICAgCi0JcHVibGljIE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IoZmluYWwgaW50IHR5cGUpIHsKLQkgICAgX25zVHlwZSA9IHR5cGU7Ci0JfQotCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCV9jdXJyZW50Q2hpbGQgPSBoYXNDaGlsZHJlbihub2RlKQotCQkgICAgPyBfb2Zmc2V0T3JDaGlsZFtfc3RhcnROb2RlID0gbm9kZV0gOiBFTkQ7Ci0JCXJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICBmb3IgKGludCBub2RlID0gX2N1cnJlbnRDaGlsZDsgbm9kZSAhPSBFTkQ7IAotCQkgbm9kZSA9IF9uZXh0U2libGluZ1tub2RlXSkgewotCQlpZiAoZ2V0TmFtZXNwYWNlVHlwZShub2RlKSA9PSBfbnNUeXBlKSB7Ci0JCSAgICBfY3VycmVudENoaWxkID0gX25leHRTaWJsaW5nW25vZGVdOwotCQkgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0JCX0KLQkgICAgfQotCSAgICByZXR1cm4gRU5EOwotCX0KLQotCXB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0JICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnRDaGlsZDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX2N1cnJlbnRDaGlsZCA9IF9tYXJrZWROb2RlOwotCX0KLQotICAgIH0gLy8gZW5kIG9mIFR5cGVkQ2hpbGRyZW5JdGVyYXRvcgotCi0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgYXR0cmlidXRlcyB3aXRoaW4gYSBnaXZlbiBuYW1lc3BhY2UgZm9yIGEgbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0KLQlwcml2YXRlIGZpbmFsIGludCBfbnNUeXBlOwotCXByaXZhdGUgaW50IF9hdHRyaWJ1dGU7Ci0gICAgICAgICAKLQlwdWJsaWMgTmFtZXNwYWNlQXR0cmlidXRlSXRlcmF0b3IoaW50IG5zVHlwZSkgewotCSAgICBzdXBlcigpOwotCSAgICBfbnNUeXBlID0gbnNUeXBlOwotCX0KLSAgICAgICAgICAgICAgICAgIAotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotCQlmb3IgKG5vZGUgPSBfbGVuZ3RoT3JBdHRyW19zdGFydE5vZGUgPSBub2RlXTsKLQkJICAgICBub2RlICE9IE5VTEwgJiYgZ2V0TmFtZXNwYWNlVHlwZShub2RlKSAhPSBfbnNUeXBlOwotCQkgICAgIG5vZGUgPSBfbmV4dFNpYmxpbmdbbm9kZV0pOwotCQlfYXR0cmlidXRlID0gbm9kZTsKLQkJcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQkgICAgfQotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGZpbmFsIGludCBzYXZlID0gX2F0dHJpYnV0ZTsKLQkgICAgaW50IG5vZGUgPSBzYXZlOwotCSAgICBfYXR0cmlidXRlID0gX25leHRTaWJsaW5nW19hdHRyaWJ1dGVdOwotCSAgICBmb3IgKG5vZGUgPSBfbGVuZ3RoT3JBdHRyW19zdGFydE5vZGUgPSBub2RlXTsKLQkJIG5vZGUgIT0gTlVMTCAmJiBnZXROYW1lc3BhY2VUeXBlKG5vZGUpICE9IF9uc1R5cGU7Ci0JCSBub2RlID0gX25leHRTaWJsaW5nW25vZGVdKTsKLQkgICAgX2F0dHJpYnV0ZSA9IG5vZGU7Ci0KLQkgICAgcmV0dXJuIHJldHVybk5vZGUoc2F2ZSk7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQkgICAgX21hcmtlZE5vZGUgPSBfYXR0cmlidXRlOwotCX0KLQotCXB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCSAgICBfYXR0cmlidXRlID0gX21hcmtlZE5vZGU7Ci0JfQotICAgICAgICAgCi0gICAgfSAvLyBlbmQgb2YgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlLgotICAgICAqLwotICAgIHByaXZhdGUgY2xhc3MgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0JcHJpdmF0ZSBpbnQgX25vZGU7Ci0gICAgICAgICAKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCSAgICBpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkJX25vZGUgPSBfc3RhcnROb2RlID0gbm9kZTsKLQkJcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQkgICAgfQotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIHJldHVybiByZXR1cm5Ob2RlKF9ub2RlID0gX25leHRTaWJsaW5nW19ub2RlXSk7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQkgICAgX21hcmtlZE5vZGUgPSBfbm9kZTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX25vZGUgPSBfbWFya2VkTm9kZTsKLQl9Ci0gICAgfSAvLyBlbmQgb2YgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgZm9sbG93aW5nIHNpYmxpbmdzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0JZXh0ZW5kcyBGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IgewotCXByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotCXB1YmxpYyBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcihpbnQgdHlwZSkgewotCSAgICBfbm9kZVR5cGUgPSB0eXBlOwotCX0KLSAgICAgICAgIAotCXB1YmxpYyBpbnQgbmV4dCgpIHsKLQkgICAgaW50IG5vZGU7Ci0JICAgIHdoaWxlICgobm9kZSA9IHN1cGVyLm5leHQoKSkgIT0gTlVMTCkgewotCQlpZiAoX3R5cGVbbm9kZV0gPT0gX25vZGVUeXBlKSByZXR1cm4gbm9kZTsKLQkgICAgfQotCSAgICByZXR1cm4gRU5EOwotCX0KLQotICAgIH0gLy8gZW5kIG9mIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGUgbm9kZXMgKG9mIHdoYXQgbm9kZXM/KQotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgQXR0cmlidXRlSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQlwcml2YXRlIGludCBfYXR0cmlidXRlOwotICAgICAgICAgCi0JLy8gYXNzdW1lcyBjYWxsZXIgd2lsbCBwYXNzIGVsZW1lbnQgbm9kZXMKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCSAgICBpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkJX2F0dHJpYnV0ZSA9IGlzRWxlbWVudChub2RlKQotCQkgICAgPyBfbGVuZ3RoT3JBdHRyW19zdGFydE5vZGUgPSBub2RlXQotCQkgICAgOiBOVUxMOwotCQlyZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotCSAgICB9Ci0JICAgIHJldHVybiB0aGlzOwotCX0KLSAgICAgICAgICAgICAgICAgIAotCXB1YmxpYyBpbnQgbmV4dCgpIHsKLQkgICAgZmluYWwgaW50IG5vZGUgPSBfYXR0cmlidXRlOwotCSAgICBfYXR0cmlidXRlID0gX25leHRTaWJsaW5nW19hdHRyaWJ1dGVdOwotCSAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfbWFya2VkTm9kZSA9IF9hdHRyaWJ1dGU7Ci0JfQotCi0JcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JICAgIF9hdHRyaWJ1dGUgPSBfbWFya2VkTm9kZTsKLQl9Ci0gICAgfSAvLyBlbmQgb2YgQXR0cmlidXRlSXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGF0dHJpYnV0ZSBub2RlcyBvZiBhIGdpdmVuIHR5cGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkQXR0cmlidXRlSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQlwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0JcHJpdmF0ZSBpbnQgX2F0dHJpYnV0ZTsKLSAgICAgICAgIAotCXB1YmxpYyBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yKGludCBub2RlVHlwZSkgewotCSAgICBfbm9kZVR5cGUgPSBub2RlVHlwZTsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQkvLyBhc3N1bWVzIGNhbGxlciB3aWxsIHBhc3MgZWxlbWVudCBub2RlcwotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotCQlmb3IgKG5vZGUgPSBfbGVuZ3RoT3JBdHRyW19zdGFydE5vZGUgPSBub2RlXTsKLQkJICAgICBub2RlICE9IE5VTEwgJiYgX3R5cGVbbm9kZV0gIT0gX25vZGVUeXBlOwotCQkgICAgIG5vZGUgPSBfbmV4dFNpYmxpbmdbbm9kZV0pOwotCQlfYXR0cmlidXRlID0gbm9kZTsKLQkJcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQkgICAgfQotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGZpbmFsIGludCBub2RlID0gX2F0dHJpYnV0ZTsKLQkgICAgX2F0dHJpYnV0ZSA9IE5VTEw7ICAgICAgICAgLy8gc2luZ2xldG9uIGl0ZXJhdG9yCi0JICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotCX0KLQotCXB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0JICAgIF9tYXJrZWROb2RlID0gX2F0dHJpYnV0ZTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX2F0dHJpYnV0ZSA9IF9tYXJrZWROb2RlOwotCX0KLSAgICB9IC8vIGVuZCBvZiBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlCi0gICAgICovCi0gICAgcHJpdmF0ZSBjbGFzcyBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQlwcml2YXRlIGludCBfc3RhcnQ7Ci0JcHJpdmF0ZSBpbnQgX25vZGU7Ci0gICAgICAgICAKLQlwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0JICAgIHJldHVybiB0cnVlOwotCX0KLSAgICAgICAgIAotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotCQlfbm9kZSA9IF9vZmZzZXRPckNoaWxkW19wYXJlbnRbX3N0YXJ0Tm9kZSA9IF9zdGFydCA9IG5vZGVdXTsKLQkJcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQkgICAgfQotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGlmIChfbm9kZSA9PSBfc3RhcnQpIHsKLQkJcmV0dXJuIE5VTEw7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWZpbmFsIGludCBub2RlID0gX25vZGU7Ci0JCV9ub2RlID0gX25leHRTaWJsaW5nW25vZGVdOwotCQlyZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLQkgICAgfQotCX0KLQotCXB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0JICAgIF9tYXJrZWROb2RlID0gX25vZGU7Ci0JfQotCi0JcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JICAgIF9ub2RlID0gX21hcmtlZE5vZGU7Ci0JfQotICAgIH0gLy8gZW5kIG9mIFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcgotCi0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgcHJlY2VkaW5nIHNpYmxpbmdzIG9mIGEgZ2l2ZW4gdHlwZSBmb3IKLSAgICAgKiBhIGdpdmVuIG5vZGUKLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0JZXh0ZW5kcyBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IgewotCXByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotCXB1YmxpYyBUeXBlZFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcihpbnQgdHlwZSkgewotCSAgICBfbm9kZVR5cGUgPSB0eXBlOwotCX0KLSAgICAgICAgIAotCXB1YmxpYyBpbnQgbmV4dCgpIHsKLQkgICAgaW50IG5vZGU7Ci0JICAgIHdoaWxlICgobm9kZSA9IHN1cGVyLm5leHQoKSkgIT0gTlVMTCAmJiBfdHlwZVtub2RlXSAhPSBfbm9kZVR5cGUpIHsKLQkgICAgfQotCSAgICByZXR1cm4gbm9kZTsKLQl9Ci0KLSAgICB9IC8vIGVuZCBvZiBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHByZWNlZGluZyBub2RlcyBvZiBhIGdpdmVuIG5vZGUuCi0gICAgICogVGhpcyBpbmNsdWRlcyB0aGUgbm9kZSBzZXQge3Jvb3QrMSwgc3RhcnQtMX0sIGJ1dCBleGNsdWRlcwotICAgICAqIGFsbCBhbmNlc3RvcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBjbGFzcyBQcmVjZWRpbmdJdGVyYXRvciBleHRlbmRzIE5vZGVJdGVyYXRvckJhc2UgewotCi0JcHJpdmF0ZSBpbnQgX25vZGUgPSAwOwotCXByaXZhdGUgaW50W10gX3N0YWNrID0gbmV3IGludFs4XTsKLQlwcml2YXRlIGludCBfc3AgPSAwOwotCXByaXZhdGUgaW50IF9zcFN0YXJ0ID0gMDsKLQlwcml2YXRlIGludCBfc3BNYXJrID0gMDsKLQotCXB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpIHsKLQkgICAgcmV0dXJuIHRydWU7Ci0JfQotICAgICAgICAgCi0JcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotCSAgICB0cnkgewotCQlfaXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCQlmaW5hbCBQcmVjZWRpbmdJdGVyYXRvciBjbG9uZSA9IAotCQkgICAgKFByZWNlZGluZ0l0ZXJhdG9yKXN1cGVyLmNsb25lKCk7Ci0JCXJldHVybiBjbG9uZS5yZXNldCgpOwotCSAgICB9Ci0JICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JCUJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0JCXJldHVybiBudWxsOwotCSAgICB9Ci0JfQotICAgICAgICAgCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCV9zdGFydE5vZGUgPSBub2RlOwotCQlfbm9kZSA9IFJPT1ROT0RFOwotCQlpbnQgcGFyZW50ID0gbm9kZTsKLQkJd2hpbGUgKChwYXJlbnQgPSBfcGFyZW50W3BhcmVudF0pID4gUk9PVE5PREUpIHsKLQkJICAgIGlmIChfc3AgPT0gX3N0YWNrLmxlbmd0aCkgewotCQkJZmluYWwgaW50W10gc3RhY2sgPSBuZXcgaW50W19zcCArIDRdOwotCQkJU3lzdGVtLmFycmF5Y29weShfc3RhY2ssIDAsIHN0YWNrLCAwLCBfc3ApOwotCQkJX3N0YWNrID0gc3RhY2s7Ci0JCSAgICB9Ci0JCSAgICBfc3RhY2tbX3NwKytdID0gcGFyZW50OwotCQl9Ci0JCV9zcC0tOwotCQlfc3BTdGFydCA9IF9zcDsKLQkJcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQkgICAgfQotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIC8vIEFkdmFuY2Ugbm9kZSBpbmRleCBhbmQgY2hlY2sgaWYgYWxsIG5vZGVzIGhhdmUgYmVlbiByZXR1cm5lZC4KLQkgICAgd2hpbGUgKCsrX25vZGUgPCBfc3RhcnROb2RlKSB7Ci0JCS8vIENoZWNrIGlmIHdlIHJlYWNoZWQgb25lIG9mIHRoZSBiYXNlIG5vZGUncyBhbmNlc3RvcnMKLQkJaWYgKChfc3AgPCAwKSB8fCAoX25vZGUgPCBfc3RhY2tbX3NwXSkpIHJldHVybihfbm9kZSk7Ci0JCS8vIEFudmFuY2UgcGFzdCB0aGUgbmV4dCBhbmNlc3RvciBub2RlCi0JCV9zcC0tOwotCSAgICB9Ci0JICAgIHJldHVybihOVUxMKTsKLQl9Ci0KLQkvLyByZWRlZmluZSBOb2RlSXRlcmF0b3JCYXNlJ3MgcmVzZXQKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHJlc2V0KCkgewotCSAgICBfbm9kZSA9IFJPT1ROT0RFOwotCSAgICBfc3BTdGFydCA9IF9zcDsKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfbWFya2VkTm9kZSA9IF9ub2RlOwotCSAgICBfc3BNYXJrID0gX3NwOwotCX0KLQotCXB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCSAgICBfbm9kZSA9IF9tYXJrZWROb2RlOwotCSAgICBfc3AgPSBfc3BNYXJrOwotCX0KLSAgICB9IC8vIGVuZCBvZiBQcmVjZWRpbmdJdGVyYXRvcgotCi0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgcHJlY2VkaW5nIG5vZGVzIG9mIGFnaXZlbiB0eXBlIGZvciBhCi0gICAgICogZ2l2ZW4gbm9kZS4gVGhpcyBpbmNsdWRlcyB0aGUgbm9kZSBzZXQge3Jvb3QrMSwgc3RhcnQtMX0sIGJ1dAotICAgICAqIGV4Y2x1ZGVzIGFsbCBhbmNlc3RvcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yIGV4dGVuZHMgUHJlY2VkaW5nSXRlcmF0b3IgewotCXByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotCXB1YmxpYyBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yKGludCB0eXBlKSB7Ci0JICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0JfQotICAgICAgICAgCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICBpbnQgbm9kZTsKLQkgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBOVUxMICYmIF90eXBlW25vZGVdICE9IF9ub2RlVHlwZSkgewotCSAgICB9Ci0JICAgIHJldHVybiBub2RlOwotCX0KLQotICAgIH0gLy8gZW5kIG9mIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGZvbGxvd2luZyBub2RlcyBvZiBmb3IgYSBnaXZlbiBub2RlLgotICAgICAqLwotICAgIHByaXZhdGUgY2xhc3MgRm9sbG93aW5nSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQkvLyAgX25vZGUgcHJlY2VkZXMgc2VhcmNoIGZvciBuZXh0Ci0JcHJvdGVjdGVkIGludCBfbm9kZTsKLSAgICAgICAgICAgICAgICAgIAotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotCQlfc3RhcnROb2RlID0gbm9kZTsKLQkJLy8gZmluZCByaWdodG1vc3QgZGVzY2VuZGFudCAob3Igc2VsZikKLQkJaW50IGN1cnJlbnQ7Ci0JCXdoaWxlICgobm9kZSA9IGxhc3RDaGlsZChjdXJyZW50ID0gbm9kZSkpICE9IE5VTEwpIHsKLQkJfQotCQlfbm9kZSA9IGN1cnJlbnQ7Ci0JCS8vIF9ub2RlIHByZWNlZGVzIHBvc3NpYmxlIGZvbGxvd2luZyhub2RlKSBub2RlcwotCQlyZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotCSAgICB9Ci0JICAgIHJldHVybiB0aGlzOwotCX0KLSAgICAgICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGZpbmFsIGludCBub2RlID0gX25vZGUgKyAxOwotCSAgICByZXR1cm4gbm9kZSA8IF90cmVlTm9kZUxpbWl0ID8gcmV0dXJuTm9kZShfbm9kZSA9IG5vZGUpIDogTlVMTDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfbWFya2VkTm9kZSA9IF9ub2RlOwotCX0KLQotCXB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCSAgICBfbm9kZSA9IF9tYXJrZWROb2RlOwotCX0KLSAgICB9IC8vIGVuZCBvZiBGb2xsb3dpbmdJdGVyYXRvcgotCi0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgZm9sbG93aW5nIG5vZGVzIG9mIGEgZ2l2ZW4gdHlwZSBmb3IgYSBnaXZlbiBub2RlLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgVHlwZWRGb2xsb3dpbmdJdGVyYXRvciBleHRlbmRzIEZvbGxvd2luZ0l0ZXJhdG9yIHsKLQlwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLQlwdWJsaWMgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcihpbnQgdHlwZSkgewotCSAgICBfbm9kZVR5cGUgPSB0eXBlOwotCX0KLSAgICAgICAgICAgICAgICAgIAotCXB1YmxpYyBpbnQgbmV4dCgpIHsKLQkgICAgaW50IG5vZGU7Ci0JICAgIHdoaWxlICgobm9kZSA9IHN1cGVyLm5leHQoKSkgIT0gTlVMTCkgewotCQlpZiAoX3R5cGVbbm9kZV0gPT0gX25vZGVUeXBlKSByZXR1cm4gbm9kZTsKLQkgICAgfQotCSAgICByZXR1cm4gRU5EOwotCX0KLSAgICB9IC8vIGVuZCBvZiBUeXBlZEZvbGxvd2luZ0l0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgYW5jZXN0b3JzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICAgKiBUaGUgbm9kZXMgYXJlIHJldHVybmVkIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIsIHNvIHlvdQotICAgICAqIGdldCB0aGUgY29udGV4dCBub2RlIChvciBpdHMgcGFyZW50IG5vZGUpIGZpcnN0LCBhbmQgdGhlCi0gICAgICogcm9vdCBub2RlIGluIHRoZSB2ZXJ5LCB2ZXJ5IGVuZC4KLSAgICAgKi8gICAgICAgICAKLSAgICBwcml2YXRlIGNsYXNzIEFuY2VzdG9ySXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQotCXByb3RlY3RlZCBpbnQgX2luZGV4OwotCi0JcHVibGljIGZpbmFsIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotCSAgICByZXR1cm4gdHJ1ZTsKLQl9Ci0KLQlwdWJsaWMgaW50IGdldExhc3QoKSB7Ci0JICAgIHJldHVybihST09UKTsKLQl9Ci0gICAgICAgICAKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0JICAgIF9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7ICAgICAgICAgLy8gbXVzdCBzZXQgdG8gZmFsc2UgZm9yIGFueSBjbG9uZQotCSAgICB0cnkgewotCQlmaW5hbCBBbmNlc3Rvckl0ZXJhdG9yIGNsb25lID0gKEFuY2VzdG9ySXRlcmF0b3Ipc3VwZXIuY2xvbmUoKTsKLQkJY2xvbmUuX3N0YXJ0Tm9kZSA9IF9zdGFydE5vZGU7Ci0JCXJldHVybiBjbG9uZS5yZXNldCgpOwotCSAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JCUJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0JCXJldHVybiBudWxsOwotCSAgICB9Ci0JfQotICAgICAgICAgICAgICAgICAgCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCWlmIChfaW5jbHVkZVNlbGYpCi0JCSAgICBfc3RhcnROb2RlID0gbm9kZTsKLQkJZWxzZQotCQkgICAgX3N0YXJ0Tm9kZSA9IF9wYXJlbnRbbm9kZV07Ci0JCV9pbmRleCA9IF9zdGFydE5vZGU7Ci0JCXJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCi0JcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQkgICAgX2luZGV4ID0gX3N0YXJ0Tm9kZTsKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGlmIChfaW5kZXggPj0gMCkgewotCQlpbnQgYm9iID0gX2luZGV4OwotCQlpZiAoX2luZGV4ID09IDApCi0JCSAgICBfaW5kZXggPSAtMTsKLQkJZWxzZQotCQkgICAgX2luZGV4ID0gX3BhcmVudFtfaW5kZXhdOwotCQlyZXR1cm4gcmV0dXJuTm9kZShib2IpOwotCSAgICB9Ci0JICAgIHJldHVybihOVUxMKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfbWFya2VkTm9kZSA9IF9pbmRleDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX2luZGV4ID0gX21hcmtlZE5vZGU7Ci0JfQotICAgIH0gLy8gZW5kIG9mIEFuY2VzdG9ySXRlcmF0b3IKLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogVHlwZWQgaXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBhbmNlc3RvcnMgb2YgYSBnaXZlbiBub2RlLgotICAgICAqLyAgICAgICAgICAgICAKLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkQW5jZXN0b3JJdGVyYXRvciBleHRlbmRzIEFuY2VzdG9ySXRlcmF0b3IgewotCi0JcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotICAgICAgICAgICAgICAgICAgCi0JcHVibGljIFR5cGVkQW5jZXN0b3JJdGVyYXRvcihpbnQgdHlwZSkgewotCSAgICBfbm9kZVR5cGUgPSB0eXBlOwotCX0KLQotCXB1YmxpYyBpbnQgbmV4dCgpIHsKLQkgICAgaW50IG5vZGU7Ci0JICAgIHdoaWxlICgobm9kZSA9IHN1cGVyLm5leHQoKSkgIT0gTlVMTCkgewotCQlpZiAoX3R5cGVbbm9kZV0gPT0gX25vZGVUeXBlKQotCQkgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0JICAgIH0KLQkgICAgcmV0dXJuKE5VTEwpOwotCX0KLQotCXB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLQkgICAgaW50IGxhc3QgPSBfaW5kZXg7Ci0JICAgIGludCBjdXJyID0gX2luZGV4OwotCi0JICAgIHdoaWxlIChjdXJyID49IDApIHsKLQkJaWYgKGN1cnIgPT0gMCkKLQkJICAgIGN1cnIgPSAtMTsKLQkJZWxzZQotCQkgICAgY3VyciA9IF9wYXJlbnRbY3Vycl07Ci0JCWlmIChfdHlwZVtjdXJyXSA9PSBfbm9kZVR5cGUpCi0JCSAgICBsYXN0ID0gY3VycjsKLQkgICAgfQotCSAgICByZXR1cm4obGFzdCk7Ci0JfQotCi0gICAgfSAvLyBlbmQgb2YgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgZGVzY2VuZGFudHMgb2YgYSBnaXZlbiBub2RlLgotICAgICAqLyAgICAgICAgICAgICAKLSAgICBwcml2YXRlIGNsYXNzIERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIE5vZGVJdGVyYXRvckJhc2UgewotCS8vICBfbm9kZSBwcmVjZWRlcyBzZWFyY2ggZm9yIG5leHQKLQlwcm90ZWN0ZWQgaW50IF9ub2RlOwotCS8vIGZpcnN0IG5vZGUgb3V0c2lkZSBkZXNjZW5kYW50IHJhbmdlCi0JcHJvdGVjdGVkIGludCBfbGltaXQ7Ci0KLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCSAgICBfc3RhcnROb2RlID0gbm9kZTsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCV9ub2RlID0gX3N0YXJ0Tm9kZSA9IF9pbmNsdWRlU2VsZiA/IG5vZGUgLSAxIDogbm9kZTsKLQkJLy8gbm8gZGVzY2VuZGVudHMgaWYgbm8gY2hpbGRyZW4KLQkJaWYgKGhhc0NoaWxkcmVuKG5vZGUpID09IGZhbHNlKSB7Ci0JCSAgICAvLyBzZXQgX2xpbWl0IHRvIG1hdGNoIG5leHQoKSdzIGNyaXRlcmlhIGZvciBlbmQKLQkJICAgIF9saW1pdCA9IG5vZGUgKyAxOwotCQl9Ci0JCS8vIGZpbmQgbGVmdG1vc3QgZGVzY2VuZGFudCBvZiBuZXh0IHNpYmxpbmcKLQkJZWxzZSBpZiAoKG5vZGUgPSBfbmV4dFNpYmxpbmdbbm9kZV0pID09IDApIHsKLQkJICAgIC8vIG5vIG5leHQgc2libGluZywgYXJyYXkgZW5kIGlzIHRoZSBsaW1pdAotCQkgICAgX2xpbWl0ID0gX3RyZWVOb2RlTGltaXQ7Ci0JCX0KLQkJZWxzZSB7Ci0JCSAgICBfbGltaXQgPSBsZWZ0bW9zdERlc2NlbmRhbnQobm9kZSk7Ci0JCX0KLQkJcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQkgICAgfQotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0KLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGlmICgrK19ub2RlID49IChfbGltaXQpKQotCQlyZXR1cm4oTlVMTCk7Ci0JICAgIGVsc2UKLQkJcmV0dXJuKHJldHVybk5vZGUoX25vZGUpKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfbWFya2VkTm9kZSA9IF9ub2RlOwotCX0KLQotCXB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCSAgICBfbm9kZSA9IF9tYXJrZWROb2RlOwotCX0KLQotICAgIH0gLy8gZW5kIG9mIERlc2NlbmRhbnRJdGVyYXRvcgotCi0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBUeXBlZCBpdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGRlc2NlbmRhbnRzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICAgKi8gICAgICAgICAgICAgCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlZERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIERlc2NlbmRhbnRJdGVyYXRvciB7Ci0JcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotICAgICAgICAgICAgICAgICAgCi0JcHVibGljIFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yKGludCBub2RlVHlwZSkgewotCSAgICBfbm9kZVR5cGUgPSBub2RlVHlwZTsKLQl9Ci0gICAgICAgICAgICAgICAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGZpbmFsIGludCBsaW1pdCA9IF9saW1pdDsKLQkgICAgZmluYWwgaW50IHR5cGUgPSBfbm9kZVR5cGU7Ci0JICAgIGludCBub2RlID0gX25vZGUgKyAxOyAvLyBzdGFydCBzZWFyY2ggdy8gbmV4dAotCSAgICAvLyB3aGlsZSBjb25kaXRpb24gPT0gd2hpY2ggbm9kZXMgdG8gc2tpcAotCSAgICAvLyBpdGVyYXRpb24gc3RvcHMgd2hlbiBhdCBlbmQgb3Igbm9kZSB3LyBkZXNpcmVkIHR5cGUKLQkgICAgd2hpbGUgKG5vZGUgPCBsaW1pdCAmJiBfdHlwZVtub2RlXSAhPSB0eXBlKSB7Ci0JCSsrbm9kZTsKLQkgICAgfQotCSAgICByZXR1cm4gbm9kZSA8IGxpbWl0ID8gcmV0dXJuTm9kZShfbm9kZSA9IG5vZGUpIDogTlVMTDsKLQl9Ci0KLSAgICB9IC8vIGVuZCBvZiBUeXBlZERlc2NlbmRhbnRJdGVyYXRvcgotCi0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGRlc2NlbmRhbnRzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICAgKi8gICAgICAgICAgICAgCi0gICAgcHJpdmF0ZSBjbGFzcyBOdGhEZXNjZW5kYW50SXRlcmF0b3IgZXh0ZW5kcyBEZXNjZW5kYW50SXRlcmF0b3IgewotCi0JaW50IF9wb3M7Ci0KLQlwdWJsaWMgTnRoRGVzY2VuZGFudEl0ZXJhdG9yKGludCBwb3MpIHsKLQkgICAgX3BvcyA9IHBvczsKLQkgICAgX2xpbWl0ID0gX3RyZWVOb2RlTGltaXQ7Ci0JfQotCi0JLy8gVGhlIHN0YXJ0IG5vZGUgb2YgdGhpcyBpdGVyYXRvciBpcyBhbHdheXMgdGhlIHJvb3QhISEKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCSAgICBOb2RlSXRlcmF0b3IgaXRlcmF0b3IgPSBzdXBlci5zZXRTdGFydE5vZGUoMSk7Ci0JICAgIF9saW1pdCA9IF90cmVlTm9kZUxpbWl0OwotCSAgICByZXR1cm4gaXRlcmF0b3I7Ci0JfQotCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICBpbnQgbm9kZTsKLQkgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBFTkQpIHsKLQkJaW50IHBhcmVudCA9IF9wYXJlbnRbbm9kZV07Ci0JCWludCBjaGlsZCA9IF9vZmZzZXRPckNoaWxkW3BhcmVudF07Ci0JCWludCBwb3MgPSAwOwotCi0JCWRvIHsKLQkJICAgIGlmIChpc0VsZW1lbnQoY2hpbGQpKSBwb3MrKzsKLQkJfSB3aGlsZSAoKHBvcyA8IF9wb3MpICYmIChjaGlsZCA9IF9uZXh0U2libGluZ1tjaGlsZF0pICE9IDApOwotCQlpZiAobm9kZSA9PSBjaGlsZCkgcmV0dXJuIG5vZGU7Ci0JICAgIH0KLQkgICAgcmV0dXJuKEVORCk7Ci0JfQotCi0gICAgfSAvLyBlbmQgb2YgTnRoRGVzY2VuZGFudEl0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhIGdpdmVuIG5vZGUgb25seSBpZiBpdCBpcyBvZiBhIGdpdmVuIHR5cGUuCi0gICAgICovICAgICAgICAgICAgIAotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgVHlwZWRTaW5nbGV0b25JdGVyYXRvciBleHRlbmRzIFNpbmdsZXRvbkl0ZXJhdG9yIHsKLQlwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLQlwdWJsaWMgVHlwZWRTaW5nbGV0b25JdGVyYXRvcihpbnQgbm9kZVR5cGUpIHsKLQkgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0JfQotICAgICAgICAgCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICBmaW5hbCBpbnQgcmVzdWx0ID0gc3VwZXIubmV4dCgpOwotCSAgICByZXR1cm4gX3R5cGVbcmVzdWx0XSA9PSBfbm9kZVR5cGUgPyByZXN1bHQgOiBOVUxMOwotCX0KLSAgICB9IC8vIGVuZCBvZiBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yCi0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIEl0ZXJhdG9yIHRvIHB1dCBvbiB0b3Agb2Ygb3RoZXIgaXRlcmF0b3JzLiBJdCB3aWxsIHRha2UgdGhlCi0gICAgICogbm9kZXMgZnJvbSB0aGUgdW5kZXJsYXlpbmcgaXRlcmF0b3IgYW5kIHJldHVybiBhbGwgYnV0Ci0gICAgICogd2hpdGVzcGFjZSB0ZXh0IG5vZGVzLiBUaGUgaXRlcmF0b3IgbmVlZHMgdG8gYmUgYSBzdXBwbGllZAotICAgICAqIHdpdGggYSBmaWx0ZXIgdGhhdCB0ZWxscyBpdCB3aGF0IG5vZGVzIGFyZSBXUyB0ZXh0LgotICAgICAqLyAgICAgICAgICAgICAKLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIFN0cmlwcGluZ0l0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVVNFX1BSRURJQ0FURSAgPSAwOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJJUF9TUEFDRSAgICA9IDE7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBSRVNFUlZFX1NQQUNFID0gMjsKLQotCXByaXZhdGUgU3RyaXBGaWx0ZXIgX2ZpbHRlciA9IG51bGw7Ci0JcHJpdmF0ZSBzaG9ydFtdIF9tYXBwaW5nID0gbnVsbDsKLQlwcml2YXRlIGZpbmFsIE5vZGVJdGVyYXRvciBfc291cmNlOwotCXByaXZhdGUgYm9vbGVhbiBfY2hpbGRyZW4gPSBmYWxzZTsKLQlwcml2YXRlIGludCBfYWN0aW9uID0gVVNFX1BSRURJQ0FURTsKLQlwcml2YXRlIGludCBfbGFzdCA9IC0xOwotCi0JcHVibGljIFN0cmlwcGluZ0l0ZXJhdG9yKE5vZGVJdGVyYXRvciBzb3VyY2UsCi0JCQkJIHNob3J0W10gbWFwcGluZywKLQkJCQkgU3RyaXBGaWx0ZXIgZmlsdGVyKSB7Ci0KLQkgICAgX2ZpbHRlciA9IGZpbHRlcjsKLQkgICAgX21hcHBpbmcgPSBtYXBwaW5nOwotCSAgICBfc291cmNlID0gc291cmNlOwotCi0JICAgIGlmIChfc291cmNlIGluc3RhbmNlb2YgQ2hpbGRyZW5JdGVyYXRvciB8fAotCQlfc291cmNlIGluc3RhbmNlb2YgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yKSB7Ci0JCV9jaGlsZHJlbiA9IHRydWU7Ci0JICAgIH0KLQl9Ci0KLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCSAgICBpZiAoX2NoaWxkcmVuKSB7Ci0JCWlmIChfZmlsdGVyLnN0cmlwU3BhY2UoKERPTSlET01JbXBsLnRoaXMsIG5vZGUsCi0JCQkJICAgICAgIF9tYXBwaW5nW190eXBlW25vZGVdXSkpCi0JCSAgICBfYWN0aW9uID0gU1RSSVBfU1BBQ0U7Ci0JCWVsc2UKLQkJICAgIF9hY3Rpb24gPSBQUkVTRVJWRV9TUEFDRTsKLQkgICAgfQotCi0JICAgIF9zb3VyY2Uuc2V0U3RhcnROb2RlKG5vZGUpOwotCSAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotCX0KLSAgICAKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGludCBub2RlOwotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0JCXN3aXRjaChfYWN0aW9uKSB7Ci0JCWNhc2UgU1RSSVBfU1BBQ0U6Ci0JCSAgICBpZiAoX3doaXRlc3BhY2UuZ2V0Qml0KG5vZGUpKSBjb250aW51ZTsKLQkJICAgIC8vIGZhbGwgdGhyb3VnaC4uLgotCQljYXNlIFBSRVNFUlZFX1NQQUNFOgotCQkgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0JCWNhc2UgVVNFX1BSRURJQ0FURToKLQkJICAgIGlmIChfd2hpdGVzcGFjZS5nZXRCaXQobm9kZSkgJiYKLQkJCV9maWx0ZXIuc3RyaXBTcGFjZSgoRE9NKURPTUltcGwudGhpcywgbm9kZSwKLQkJCQkJICAgX21hcHBpbmdbX3R5cGVbX3BhcmVudFtub2RlXV1dKSkKLQkJCWNvbnRpbnVlOwotCQkgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0JCX0KLQkgICAgfQotCSAgICByZXR1cm4gRU5EOwotCX0KLSAgICAKLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfc291cmNlLnNldE1hcmsoKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgX3NvdXJjZS5nb3RvTWFyaygpOwotCX0KLQotCXB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLQkgICAgLy8gUmV0dXJuIGNoYWNoZWQgdmFsdWUgKGlmIHdlIGhhdmUgaXQpCi0JICAgIGlmIChfbGFzdCAhPSAtMSkgcmV0dXJuIF9sYXN0OwotCi0JICAgIGludCBjb3VudCA9IGdldFBvc2l0aW9uKCk7Ci0JICAgIGludCBub2RlOwotCi0JICAgIF9zb3VyY2Uuc2V0TWFyaygpOwotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0JCXN3aXRjaChfYWN0aW9uKSB7Ci0JCWNhc2UgU1RSSVBfU1BBQ0U6Ci0JCSAgICBpZiAoX3doaXRlc3BhY2UuZ2V0Qml0KG5vZGUpKQotCQkJY29udGludWU7Ci0JCSAgICAvLyBmYWxsIHRocm91Z2guLi4KLQkJY2FzZSBQUkVTRVJWRV9TUEFDRToKLQkJICAgIGNvdW50Kys7Ci0JCSAgICBicmVhazsKLQkJY2FzZSBVU0VfUFJFRElDQVRFOgotCQkgICAgaWYgKF93aGl0ZXNwYWNlLmdldEJpdChub2RlKSAmJgotCQkJX2ZpbHRlci5zdHJpcFNwYWNlKChET00pRE9NSW1wbC50aGlzLCBub2RlLAotCQkJCQkgICBfbWFwcGluZ1tfdHlwZVtfcGFyZW50W25vZGVdXV0pKQotCQkJY29udGludWU7Ci0JCSAgICBlbHNlCi0JCQljb3VudCsrOwotCQl9Ci0JICAgIH0KLQkgICAgX3NvdXJjZS5nb3RvTWFyaygpOwotCSAgICBfbGFzdCA9IGNvdW50OwotCSAgICByZXR1cm4oY291bnQpOwotCX0KLQotICAgIH0gLy8gZW5kIG9mIFN0cmlwcGluZ0l0ZXJhdG9yCi0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHN0cmlwcGluZ0l0ZXJhdG9yKE5vZGVJdGVyYXRvciBpdGVyYXRvciwKLQkJCQkJICBzaG9ydFtdIG1hcHBpbmcsCi0JCQkJCSAgU3RyaXBGaWx0ZXIgZmlsdGVyKSB7Ci0JcmV0dXJuKG5ldyBTdHJpcHBpbmdJdGVyYXRvcihpdGVyYXRvciwgbWFwcGluZywgZmlsdGVyKSk7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogVGhpcyBpcyBhIHNwZWNpYWxpc2VkIGl0ZXJhdG9yIGZvciBwcmVkaWNhdGVzIGNvbXBhcmluZyBub2RlIG9yCi0gICAgICogYXR0cmlidXRlIHZhbHVlcyB0byB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgdmFsdWVzLgotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgTm9kZVZhbHVlSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQotCXByaXZhdGUgTm9kZUl0ZXJhdG9yIF9zb3VyY2U7Ci0JcHJpdmF0ZSBTdHJpbmcgX3ZhbHVlOwotCXByaXZhdGUgYm9vbGVhbiBfb3A7Ci0JcHJpdmF0ZSBmaW5hbCBib29sZWFuIF9pc1JldmVyc2U7Ci0KLQlwdWJsaWMgTm9kZVZhbHVlSXRlcmF0b3IoTm9kZUl0ZXJhdG9yIHNvdXJjZSwKLQkJCQkgU3RyaW5nIHZhbHVlLCBib29sZWFuIG9wKSB7Ci0JICAgIF9zb3VyY2UgPSBzb3VyY2U7Ci0JICAgIF92YWx1ZSA9IHZhbHVlOwotCSAgICBfb3AgPSBvcDsKLQkgICAgX2lzUmV2ZXJzZSA9IHNvdXJjZS5pc1JldmVyc2UoKTsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0JICAgIHJldHVybiBfaXNSZXZlcnNlOwotCX0KLSAgICAKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0JICAgIHRyeSB7Ci0JCU5vZGVWYWx1ZUl0ZXJhdG9yIGNsb25lID0gKE5vZGVWYWx1ZUl0ZXJhdG9yKXN1cGVyLmNsb25lKCk7Ci0JCWNsb25lLl9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0JCWNsb25lLl9zb3VyY2UgPSBfc291cmNlLmNsb25lSXRlcmF0b3IoKTsKLQkJY2xvbmUuX3ZhbHVlID0gX3ZhbHVlOwotCQljbG9uZS5fb3AgPSBfb3A7Ci0JCXJldHVybiBjbG9uZS5yZXNldCgpOwotCSAgICB9Ci0JICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JCUJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7IAotCQlyZXR1cm4gbnVsbDsKLQkgICAgfQotCX0KLSAgICAKLQlwdWJsaWMgTm9kZUl0ZXJhdG9yIHJlc2V0KCkgewotCSAgICBfc291cmNlLnJlc2V0KCk7Ci0JICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JfQotCi0JcHVibGljIGludCBuZXh0KCkgewotCi0JICAgIGludCBub2RlOwotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0JCVN0cmluZyB2YWwgPSBnZXROb2RlVmFsdWUobm9kZSk7Ci0JCWlmIChfdmFsdWUuZXF1YWxzKHZhbCkgPT0gX29wKSB7Ci0JCSAgICByZXR1cm4gX3BhcmVudFtub2RlXTsKLQkJfQotCSAgICB9Ci0JICAgIHJldHVybiBFTkQ7Ci0JfQotCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQkgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKSB7Ci0JCV9zb3VyY2Uuc2V0U3RhcnROb2RlKF9zdGFydE5vZGUgPSBub2RlKTsgCi0JCXJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JICAgIH0KLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQkgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0JfQotCi0JcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JICAgIF9zb3VyY2UuZ290b01hcmsoKTsKLQl9Ci0gICAgfSAgICAgICAgICAgICAgICAgICAgICAgCi0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldE5vZGVWYWx1ZUl0ZXJhdG9yKE5vZGVJdGVyYXRvciBpdGVyYXRvciwKLQkJCQkJICAgICBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gb3ApIHsKLQlyZXR1cm4obmV3IE5vZGVWYWx1ZUl0ZXJhdG9yKGl0ZXJhdG9yLCB2YWx1ZSwgb3ApKTsKLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJdGVyYXRvciB0aGF0IGFzc3VyZWQgdGhhdCBhIHNpbmdsZSBub2RlIGlzIG9ubHkgcmV0dXJuZWQgb25jZQotICAgICAqIGFuZCB0aGF0IHRoZSBub2RlcyBhcmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAgICovICAgICAgICAgICAgIAotICAgIHByaXZhdGUgZmluYWwgY2xhc3MgT3JkZXJlZEl0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0KLQlwcml2YXRlIEJpdEFycmF5ICBfbm9kZXMgPSBudWxsOwotCXByaXZhdGUgaW50ICAgICAgIF9zYXZlID0gMDsKLQlwcml2YXRlIGludCAgICAgICBfbWFyayA9IDA7Ci0JcHJpdmF0ZSBpbnQgICAgICAgX3N0YXJ0ID0gMDsKLQlwcml2YXRlIGludCAgICAgICBfbm9kZSA9IC0xOwotCXByaXZhdGUgaW50ICAgICAgIF9sYXN0ID0gMDsKLQotCXB1YmxpYyBPcmRlcmVkSXRlcmF0b3IoTm9kZUl0ZXJhdG9yIHNvdXJjZSwgaW50IG5vZGUpIHsKLQkgICAgX25vZGVzID0gbmV3IEJpdEFycmF5KF90cmVlTm9kZUxpbWl0KTsKLQkgICAgc291cmNlLnNldFN0YXJ0Tm9kZShub2RlKTsKLQkgICAgd2hpbGUgKChfbm9kZSA9IHNvdXJjZS5uZXh0KCkpICE9IEVORCkgewotCQlpZiAoX3N0YXJ0ID09IC0xKSBfc3RhcnQgPSBfbm9kZTsKLQkJX2xhc3QgPSBfbm9kZTsKLQkJX25vZGVzLnNldEJpdChfbm9kZSk7Ci0JICAgIH0KLQkgICAgX25vZGUgPSAtMTsKLQl9Ci0gCi0JcHVibGljIGludCBuZXh0KCkgewotCSAgICB3aGlsZSAoKF9ub2RlIDwgX3RyZWVOb2RlTGltaXQpICYmICghX25vZGVzLmdldEJpdCgrK19ub2RlKSkpIDsKLQkgICAgaWYgKF9ub2RlID49IF90cmVlTm9kZUxpbWl0KSByZXR1cm4oRU5EKTsKLQkgICAgcmV0dXJuIHJldHVybk5vZGUoX25vZGUpOwotCX0KLQotCXB1YmxpYyBOb2RlSXRlcmF0b3IgcmVzZXQoKSB7Ci0JICAgIF9ub2RlID0gX3N0YXJ0IC0gMTsKLQkgICAgcmV0dXJuKHRoaXMpOwotCX0KLQotCXB1YmxpYyBpbnQgZ2V0TGFzdCgpIHsKLQkgICAgcmV0dXJuKF9sYXN0KTsKLQl9Ci0gICAgICAgICAKLQlwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCSAgICBfc2F2ZSA9IF9ub2RlOwotCX0KLQotCXB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCSAgICBfbm9kZSA9IF9zYXZlOwotCX0KLQotCXB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBzdGFydCkgewotCSAgICBfc3RhcnQgPSBzdGFydDsKLQkgICAgcmV0dXJuKChOb2RlSXRlcmF0b3IpdGhpcyk7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNSZXZlcnNlKCkgewotCSAgICByZXR1cm4oZmFsc2UpOwotCX0KLQotCXB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQkgICAgcmV0dXJuKChOb2RlSXRlcmF0b3IpdGhpcyk7Ci0JfQotCi0gICAgfSAvLyBlbmQgb2YgT3JkZXJlZEl0ZXJhdG9yCi0KLQotICAgIC8qKgotICAgICAqIEVuY2Fwc3VsYXRlcyBhbiBpdGVyYXRvciBpbiBhbiBPcmRlcmVkSXRlcmF0b3IgdG8gZW5zdXJlIG5vZGUgb3JkZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIG9yZGVyTm9kZXMoTm9kZUl0ZXJhdG9yIHNvdXJjZSwgaW50IG5vZGUpIHsKLQlyZXR1cm4gbmV3IE9yZGVyZWRJdGVyYXRvcihzb3VyY2UsIG5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGxlZnRtb3N0IGRlc2NlbmRhbnQgb2YgYSBub2RlIChib3R0b20gbGVmdCBpbiBzdWItdHJlZSkKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBsZWZ0bW9zdERlc2NlbmRhbnQoaW50IG5vZGUpIHsKLQlpbnQgY3VycmVudDsKLQl3aGlsZSAoX3R5cGVbY3VycmVudCA9IG5vZGVdID49IE5UWVBFUyAKLQkgICAgICAgJiYgKG5vZGUgPSBfb2Zmc2V0T3JDaGlsZFtub2RlXSkgIT0gTlVMTCkgewotCX0KLQlyZXR1cm4gY3VycmVudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGluZGV4IG9mIGxhc3QgY2hpbGQgb3IgMCBpZiBubyBjaGlsZHJlbgotICAgICAqLwotICAgIHByaXZhdGUgaW50IGxhc3RDaGlsZChpbnQgbm9kZSkgewotCWlmIChpc0VsZW1lbnQobm9kZSkgfHwgbm9kZSA9PSBST09UTk9ERSkgewotCSAgICBpbnQgY2hpbGQ7Ci0JICAgIGlmICgoY2hpbGQgPSBfb2Zmc2V0T3JDaGlsZFtub2RlXSkgIT0gTlVMTCkgewotCQl3aGlsZSAoKGNoaWxkID0gX25leHRTaWJsaW5nW25vZGUgPSBjaGlsZF0pICE9IE5VTEwpIHsKLQkJfQotCQlyZXR1cm4gbm9kZTsKLQkgICAgfQotCX0KLQlyZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwYXJlbnQgb2YgYSBub2RlCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQYXJlbnQoZmluYWwgaW50IG5vZGUpIHsKLQlyZXR1cm4gX3BhcmVudFtub2RlXTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgbm9kZSdzIHBvc2l0aW9uIGFtb25nc3Qgb3RoZXIgbm9kZXMgb2YgdGhlIHNhbWUgdHlwZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VHlwZWRQb3NpdGlvbihOb2RlSXRlcmF0b3IgaXRlcmF0b3IsIGludCB0eXBlLCBpbnQgbm9kZSkgewotCi0JLy8gSnVzdCByZXR1cm4gdGhlIGJhc2ljIHBvc2l0aW9uIGlmIG5vIHR5cGUgaXMgc3BlY2lmaWVkCi0JaWYgKHR5cGUgPT0gLTEpIHR5cGUgPSBfdHlwZVtub2RlXTsKLQotCWludCBtYXRjaCA9IDE7Ci0JaW50IGN1cnIgID0gMDsKLQlpdGVyYXRvci5yZXNldCgpOwotCi0Jd2hpbGUgKCAoKGN1cnIgPSBpdGVyYXRvci5uZXh0KCkpICE9IE5VTEwpICYmIChjdXJyICE9IG5vZGUpKSB7Ci0JICAgIGlmIChfdHlwZVtjdXJyXSA9PSB0eXBlKSBtYXRjaCsrOwotCX0KLQlyZXR1cm4gbWF0Y2g7ICAgICAgICAgCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBpdGVyYXRvcidzIGxhc3Qgbm9kZSBvZiBhIGdpdmVuIHR5cGUKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldFR5cGVkTGFzdChOb2RlSXRlcmF0b3IgaXRlcmF0b3IsIGludCB0eXBlLCBpbnQgbm9kZSkgewotCS8vIEp1c3QgcmV0dXJuIHRoZSBiYXNpYyBwb3NpdGlvbiBpZiBubyB0eXBlIGlzIHNwZWNpZmllZAotCWlmICh0eXBlID09IC0xKSByZXR1cm4oaXRlcmF0b3IuZ2V0TGFzdCgpKTsKLQotCWludCBtYXRjaCA9IDA7Ci0JaW50IGN1cnIgID0gMDsKLQlpdGVyYXRvci5zZXRNYXJrKCk7Ci0JaXRlcmF0b3IucmVzZXQoKTsKLQotCXdoaWxlICgoY3VyciA9IGl0ZXJhdG9yLm5leHQoKSkgIT0gTlVMTCkgewotCSAgICBpZiAoX3R5cGVbY3Vycl0gPT0gdHlwZSkgbWF0Y2grKzsKLQl9Ci0JaXRlcmF0b3IuZ290b01hcmsoKTsKLQlyZXR1cm4gbWF0Y2g7ICAgICAgICAgCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBzaW5nbGV0b24gaXRlcmF0b3IgY29udGFpbmcgdGhlIGRvY3VtZW50IHJvb3QKLSAgICAgKiBXb3JrcyBmb3IgdGhlbSBtYWluIGRvY3VtZW50IChtYXJrID09IDApCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRJdGVyYXRvcigpIHsKLQlyZXR1cm4gbmV3IFNpbmdsZXRvbkl0ZXJhdG9yKFJPT1ROT0RFKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIGEgc3BlY2lmaWMgbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0VHlwZShmaW5hbCBpbnQgbm9kZSkgewotCWlmIChub2RlID49IF90eXBlLmxlbmd0aCkKLQkgICAgcmV0dXJuKDApOwotCWVsc2UKLQkgICAgcmV0dXJuIF90eXBlW25vZGVdOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgdHlwZSBvZiBhIHNwZWNpZmljIG5vZGUKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldE5hbWVzcGFjZVR5cGUoZmluYWwgaW50IG5vZGUpIHsKLQlmaW5hbCBpbnQgdHlwZSA9IF90eXBlW25vZGVdOwotCWlmICh0eXBlID49IE5UWVBFUykKLQkgICAgcmV0dXJuKF9uYW1lc3BhY2VbdHlwZS1OVFlQRVNdKTsKLQllbHNlCi0JICAgIHJldHVybigwKTsgLy8gZGVmYXVsdCBuYW1lc3BhY2UKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBub2RlLXRvLXR5cGUgbWFwcGluZyBhcnJheQotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydFtdIGdldFR5cGVBcnJheSgpIHsKLQlyZXR1cm4gX3R5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgKFN0cmluZykgdmFsdWUgb2YgYW55IG5vZGUgaW4gdGhlIHRyZWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShmaW5hbCBpbnQgbm9kZSkgewotCWlmIChub2RlID09IE5VTEwpIHJldHVybiBFTVBUWVNUUklORzsKLQlzd2l0Y2goX3R5cGVbbm9kZV0pIHsKLQljYXNlIFJPT1Q6Ci0JICAgIHJldHVybiBnZXROb2RlVmFsdWUoX29mZnNldE9yQ2hpbGRbbm9kZV0pOwotCWNhc2UgVEVYVDoKLQljYXNlIENPTU1FTlQ6Ci0JY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OOgotCSAgICByZXR1cm4gbWFrZVN0cmluZ1ZhbHVlKG5vZGUpOwotCWRlZmF1bHQ6Ci0JICAgIGlmIChub2RlIDwgX2ZpcnN0QXR0cmlidXRlTm9kZSkKLQkJcmV0dXJuIGdldEVsZW1lbnRWYWx1ZShub2RlKTsgLy8gZWxlbWVudCBzdHJpbmcgdmFsdWUKLQkgICAgZWxzZQotCQlyZXR1cm4gbWFrZVN0cmluZ1ZhbHVlKG5vZGUpOyAvLyBhdHRyaWJ1dGUgdmFsdWUKLQl9Ci0gICAgfQotCi0gICAgcHJpdmF0ZSBTdHJpbmcgZ2V0TG9jYWxOYW1lKGludCBub2RlKSB7Ci0JZmluYWwgaW50IHR5cGUgPSBfdHlwZVtub2RlXSAtIE5UWVBFUzsKLQlmaW5hbCBTdHJpbmcgcW5hbWUgPSBfbmFtZXNBcnJheVt0eXBlXTsKLQlmaW5hbCBTdHJpbmcgdXJpID0gX3VyaUFycmF5W19uYW1lc3BhY2VbdHlwZV1dOwotCi0JaWYgKHVyaSAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBsZW4gPSB1cmkubGVuZ3RoKCk7Ci0JICAgIGlmIChsZW4gPiAwKSByZXR1cm4gcW5hbWUuc3Vic3RyaW5nKGxlbisxKTsKLQl9Ci0JcmV0dXJuIHFuYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdXAgYSB0cmFuc2xldC10by1kb20gdHlwZSBtYXBwaW5nIHRhYmxlCi0gICAgICovCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgc2V0dXBNYXBwaW5nKFN0cmluZ1tdIG5hbWVzQXJyYXkpIHsKLQlmaW5hbCBpbnQgbk5hbWVzID0gbmFtZXNBcnJheS5sZW5ndGg7Ci0JZmluYWwgSGFzaHRhYmxlIHR5cGVzID0gbmV3IEhhc2h0YWJsZShuTmFtZXMpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgbk5hbWVzOyBpKyspIHsKLQkgICAgdHlwZXMucHV0KG5hbWVzQXJyYXlbaV0sIG5ldyBJbnRlZ2VyKGkgKyBOVFlQRVMpKTsKLQl9Ci0JcmV0dXJuIHR5cGVzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGludGVybmFsIHR5cGUgYXNzb2NpYXRlZCB3aXRoIGFuIGV4cGFuZWRlZCBRTmFtZQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0R2VuZXJhbGl6ZWRUeXBlKGZpbmFsIFN0cmluZyBuYW1lKSB7Ci0JZmluYWwgSW50ZWdlciB0eXBlID0gKEludGVnZXIpX3R5cGVzLmdldChuYW1lKTsKLQlpZiAodHlwZSA9PSBudWxsKSB7Ci0JICAgIC8vIG1lbW9yaXplIGRlZmF1bHQgdHlwZQotCSAgICBmaW5hbCBpbnQgY29kZSA9IG5hbWUuY2hhckF0KDApID09ICdAJyA/IEFUVFJJQlVURSA6IEVMRU1FTlQ7Ci0JICAgIF90eXBlcy5wdXQobmFtZSwgbmV3IEludGVnZXIoY29kZSkpOwotCSAgICByZXR1cm4gY29kZTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJldHVybiB0eXBlLmludFZhbHVlKCk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBtYXBwaW5nIGZyb20gRE9NIGVsZW1lbnQvYXR0cmlidXRlIHR5cGVzIHRvIGV4dGVybmFsIHR5cGVzCi0gICAgICovCi0gICAgcHVibGljIHNob3J0W10gZ2V0TWFwcGluZyhTdHJpbmdbXSBuYW1lcykgewotCWludCBpOwotCWZpbmFsIGludCBuYW1lc0xlbmd0aCA9IG5hbWVzLmxlbmd0aDsKLQlmaW5hbCBpbnQgbWFwcGluZ0xlbmd0aCA9IF9uYW1lc0FycmF5Lmxlbmd0aCArIE5UWVBFUzsKLQlmaW5hbCBzaG9ydFtdIHJlc3VsdCA9IG5ldyBzaG9ydFttYXBwaW5nTGVuZ3RoXTsKLQotCS8vIHByaW1pdGl2ZSB0eXBlcyBtYXAgdG8gdGhlbXNlbHZlcwotCWZvciAoaSA9IDA7IGkgPCBOVFlQRVM7IGkrKykKLQkgICAgcmVzdWx0W2ldID0gKHNob3J0KWk7Ci0KLQkvLyBleHRlbmRlZCB0eXBlcyBpbml0aWFsaXplZCB0byAiYmV5b25kIGNhbGxlcidzIHR5cGVzIgotCS8vIHVua25vd24gZWxlbWVudCBvciBBdHRyCi0JZm9yIChpID0gTlRZUEVTOyBpIDwgbWFwcGluZ0xlbmd0aDsgaSsrKSB7Ci0JICAgIGZpbmFsIGludCB0eXBlID0gaSAtIE5UWVBFUzsKLQkgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBfbmFtZXNBcnJheVt0eXBlXTsKLQkgICAgZmluYWwgU3RyaW5nIHVyaSA9IF91cmlBcnJheVtfbmFtZXNwYWNlW3R5cGVdXTsKLQkgICAgaW50IGxlbiA9IDA7Ci0JICAgIGlmICh1cmkgIT0gbnVsbCkgewotCQlsZW4gPSB1cmkubGVuZ3RoKCk7Ci0JCWlmIChsZW4gPiAwKSBsZW4rKzsKLQkgICAgfQotCSAgICBpZiAobmFtZS5jaGFyQXQobGVuKSA9PSAnQCcpCi0JCXJlc3VsdFtpXSA9IChzaG9ydClBVFRSSUJVVEU7Ci0JICAgIGVsc2UKLQkJcmVzdWx0W2ldID0gKHNob3J0KUVMRU1FTlQ7Ci0JfQotCi0JLy8gYWN0dWFsIG1hcHBpbmcgb2YgY2FsbGVyIHJlcXVlc3RlZCBuYW1lcwotCWZvciAoaSA9IDA7IGkgPCBuYW1lc0xlbmd0aDsgaSsrKSB7Ci0JICAgIHJlc3VsdFtnZXRHZW5lcmFsaXplZFR5cGUobmFtZXNbaV0pXSA9IChzaG9ydCkoaSArIE5UWVBFUyk7Ci0JfQotICAgICAgICAgICAgIAotCXJldHVybihyZXN1bHQpOwotCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IG1hcHBpbmcgZnJvbSBleHRlcm5hbCBlbGVtZW50L2F0dHJpYnV0ZSB0eXBlcyB0byBET00gdHlwZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgc2hvcnRbXSBnZXRSZXZlcnNlTWFwcGluZyhTdHJpbmdbXSBuYW1lcykgewotCWludCBpOwotCWZpbmFsIHNob3J0W10gcmVzdWx0ID0gbmV3IHNob3J0W25hbWVzLmxlbmd0aCArIE5UWVBFU107Ci0JLy8gcHJpbWl0aXZlIHR5cGVzIG1hcCB0byB0aGVtc2VsdmVzCi0JZm9yIChpID0gMDsgaSA8IE5UWVBFUzsgaSsrKSB7Ci0JICAgIHJlc3VsdFtpXSA9IChzaG9ydClpOwotCX0KLQkvLyBjYWxsZXIncyB0eXBlcyBtYXAgaW50byBhcHByb3ByaWF0ZSBkb20gdHlwZXMKLQlmb3IgKGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHsKLQkgICAgcmVzdWx0W2kgKyBOVFlQRVNdID0gKHNob3J0KWdldEdlbmVyYWxpemVkVHlwZShuYW1lc1tpXSk7Ci0JICAgIGlmIChyZXN1bHRbaSArIE5UWVBFU10gPT0gRUxFTUVOVCkKLQkJcmVzdWx0W2kgKyBOVFlQRVNdID0gTk9fVFlQRTsKLQl9Ci0JcmV0dXJuKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IG1hcHBpbmcgZnJvbSBET00gbmFtZXNwYWNlIHR5cGVzIHRvIGV4dGVybmFsIG5hbWVzcGFjZSB0eXBlcwotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydFtdIGdldE5hbWVzcGFjZU1hcHBpbmcoU3RyaW5nW10gbmFtZXNwYWNlcykgewotCWludCBpOwotCWZpbmFsIGludCBuc0xlbmd0aCA9IG5hbWVzcGFjZXMubGVuZ3RoOwotCWZpbmFsIGludCBtYXBwaW5nTGVuZ3RoID0gX3VyaUFycmF5Lmxlbmd0aDsKLQlmaW5hbCBzaG9ydFtdIHJlc3VsdCA9IG5ldyBzaG9ydFttYXBwaW5nTGVuZ3RoXTsKLQotCS8vIEluaXRpYWxpemUgYWxsIGVudHJpZXMgdG8gLTEKLQlmb3IgKGk9MDsgaTxtYXBwaW5nTGVuZ3RoOyBpKyspCi0JICAgIHJlc3VsdFtpXSA9ICgtMSk7Ci0KLQlmb3IgKGk9MDsgaTxuc0xlbmd0aDsgaSsrKSB7Ci0JICAgIEludGVnZXIgdHlwZSA9IChJbnRlZ2VyKV9uc0luZGV4LmdldChuYW1lc3BhY2VzW2ldKTsKLQkgICAgaWYgKHR5cGUgIT0gbnVsbCkgewotCQlyZXN1bHRbdHlwZS5pbnRWYWx1ZSgpXSA9IChzaG9ydClpOwotCSAgICB9Ci0JfQotCi0JcmV0dXJuKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IG1hcHBpbmcgZnJvbSBleHRlcm5hbCBuYW1lc3BhY2UgdHlwZXMgdG8gRE9NIG5hbWVzcGFjZSB0eXBlcwotICAgICAqLwotICAgIHB1YmxpYyBzaG9ydFtdIGdldFJldmVyc2VOYW1lc3BhY2VNYXBwaW5nKFN0cmluZ1tdIG5hbWVzcGFjZXMpIHsKLQlpbnQgaTsKLQlmaW5hbCBpbnQgbGVuZ3RoID0gbmFtZXNwYWNlcy5sZW5ndGg7Ci0JZmluYWwgc2hvcnRbXSByZXN1bHQgPSBuZXcgc2hvcnRbbGVuZ3RoXTsKLQotCWZvciAoaT0wOyBpPGxlbmd0aDsgaSsrKSB7Ci0JICAgIEludGVnZXIgdHlwZSA9IChJbnRlZ2VyKV9uc0luZGV4LmdldChuYW1lc3BhY2VzW2ldKTsKLQkgICAgaWYgKHR5cGUgPT0gbnVsbCkKLQkJcmVzdWx0W2ldID0gLTE7Ci0JICAgIGVsc2UKLQkJcmVzdWx0W2ldID0gdHlwZS5zaG9ydFZhbHVlKCk7Ci0JfQotCi0JcmV0dXJuKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRHVtcCB0aGUgd2hvbGUgdHJlZSB0byBhIGZpbGUgKHNlcmlhbGl6ZWQpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgd3JpdGVFeHRlcm5hbChPYmplY3RPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCW91dC53cml0ZUludChfdHJlZU5vZGVMaW1pdCk7Ci0Jb3V0LndyaXRlT2JqZWN0KF90eXBlKTsKLQlvdXQud3JpdGVPYmplY3QoX25hbWVzcGFjZSk7Ci0Jb3V0LndyaXRlT2JqZWN0KF9wYXJlbnQpOwotCW91dC53cml0ZU9iamVjdChfbmV4dFNpYmxpbmcpOwotCW91dC53cml0ZU9iamVjdChfb2Zmc2V0T3JDaGlsZCk7Ci0Jb3V0LndyaXRlT2JqZWN0KF9sZW5ndGhPckF0dHIpOwotCW91dC53cml0ZU9iamVjdChfdGV4dCk7Ci0Jb3V0LndyaXRlT2JqZWN0KF9uYW1lc0FycmF5KTsKLQlvdXQud3JpdGVPYmplY3QoX3VyaUFycmF5KTsKLQlvdXQud3JpdGVPYmplY3QoX3doaXRlc3BhY2UpOwotCW91dC53cml0ZU9iamVjdChfcHJlZml4KTsKLQlvdXQuZmx1c2goKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZWFkIHRoZSB3aG9sZSB0cmVlIGZyb20gYSBmaWxlIChzZXJpYWxpemVkKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlYWRFeHRlcm5hbChPYmplY3RJbnB1dCBpbikKLQl0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewotCV90cmVlTm9kZUxpbWl0ID0gaW4ucmVhZEludCgpOwotCV90eXBlICAgICAgICAgID0gKHNob3J0W10paW4ucmVhZE9iamVjdCgpOwotCV9uYW1lc3BhY2UgICAgID0gKHNob3J0W10paW4ucmVhZE9iamVjdCgpOwotCV9wYXJlbnQgICAgICAgID0gKGludFtdKWluLnJlYWRPYmplY3QoKTsKLQlfbmV4dFNpYmxpbmcgICA9IChpbnRbXSlpbi5yZWFkT2JqZWN0KCk7Ci0JX29mZnNldE9yQ2hpbGQgPSAoaW50W10paW4ucmVhZE9iamVjdCgpOwotCV9sZW5ndGhPckF0dHIgID0gKGludFtdKWluLnJlYWRPYmplY3QoKTsKLQlfdGV4dCAgICAgICAgICA9IChjaGFyW10paW4ucmVhZE9iamVjdCgpOwotCV9uYW1lc0FycmF5ICAgID0gKFN0cmluZ1tdKWluLnJlYWRPYmplY3QoKTsKLQlfdXJpQXJyYXkgICAgICA9IChTdHJpbmdbXSlpbi5yZWFkT2JqZWN0KCk7Ci0JX3doaXRlc3BhY2UgICAgPSAoQml0QXJyYXkpaW4ucmVhZE9iamVjdCgpOwotCV9wcmVmaXggICAgICAgID0gKHNob3J0W10paW4ucmVhZE9iamVjdCgpOwotCV90eXBlcyAgICAgICAgID0gc2V0dXBNYXBwaW5nKF9uYW1lc0FycmF5KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciAtIGRlZmF1bHRzIHRvIDMySyBub2RlcwotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsKCkgewotCXRoaXMoMzIqMTAyNCk7Ci0gICAgfQotICAgICAgICAgCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgLSBkZWZpbmVzIGluaXRpYWwgc2l6ZQotICAgICAqLwotICAgIHB1YmxpYyBET01JbXBsKGludCBzaXplKSB7Ci0JX3R5cGUgICAgICAgICAgPSBuZXcgc2hvcnRbc2l6ZV07Ci0JX3BhcmVudCAgICAgICAgPSBuZXcgaW50W3NpemVdOwotCV9uZXh0U2libGluZyAgID0gbmV3IGludFtzaXplXTsKLQlfb2Zmc2V0T3JDaGlsZCA9IG5ldyBpbnRbc2l6ZV07Ci0JX2xlbmd0aE9yQXR0ciAgPSBuZXcgaW50W3NpemVdOwotCV90ZXh0ICAgICAgICAgID0gbmV3IGNoYXJbc2l6ZSAqIDEwXTsKLQlfd2hpdGVzcGFjZSAgICA9IG5ldyBCaXRBcnJheShzaXplKTsKLQlfcHJlZml4ICAgICAgICA9IG5ldyBzaG9ydFtzaXplXTsKLQkvLyBfbmFtZXNBcnJheVtdIGFuZCBfdXJpQXJyYXkgYXJlIGFsbG9jYXRlZCBpbiBlbmREb2N1bWVudAotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50cyB0aGUgd2hvbGUgdHJlZSB0byBzdGFuZGFyZCBvdXRwdXQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludChpbnQgbm9kZSwgaW50IGxldmVsKSB7Ci0Jc3dpdGNoKF90eXBlW25vZGVdKSB7Ci0JY2FzZSBST09UOgotCSAgICBwcmludChfb2Zmc2V0T3JDaGlsZFtub2RlXSwgbGV2ZWwpOwotCSAgICBicmVhazsKLQljYXNlIFRFWFQ6Ci0JY2FzZSBDT01NRU5UOgotCWNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTjoKLQkgICAgU3lzdGVtLm91dC5wcmludChtYWtlU3RyaW5nVmFsdWUobm9kZSkpOwotCSAgICBicmVhazsKLQlkZWZhdWx0OiAgICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQKLQkgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBnZXROb2RlTmFtZShub2RlKTsKLQkgICAgU3lzdGVtLm91dC5wcmludCgiPCIgKyBuYW1lKTsKLQkgICAgZm9yIChpbnQgYSA9IF9sZW5ndGhPckF0dHJbbm9kZV07IGEgIT0gTlVMTDsgYSA9IF9uZXh0U2libGluZ1thXSkgewotCQlTeXN0ZW0ub3V0LnByaW50KCJcbiIgKyBnZXROb2RlTmFtZShhKSArCi0JCQkJICI9XCIiICsgbWFrZVN0cmluZ1ZhbHVlKGEpICsgIlwiIik7Ci0JICAgIH0KLQkgICAgU3lzdGVtLm91dC5wcmludCgnPicpOwotCSAgICBmb3IgKGludCBjaGlsZCA9IF9vZmZzZXRPckNoaWxkW25vZGVdOyBjaGlsZCAhPSBOVUxMOwotCQkgY2hpbGQgPSBfbmV4dFNpYmxpbmdbY2hpbGRdKSB7Ci0JCXByaW50KGNoaWxkLCBsZXZlbCArIDEpOwotCSAgICB9Ci0JICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPC8iICsgbmFtZSArICc+Jyk7Ci0JICAgIGJyZWFrOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIGEgbm9kZSAoYXR0cmlidXRlIG9yIGVsZW1lbnQpLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoZmluYWwgaW50IG5vZGUpIHsKLQkvLyBHZXQgdGhlIG5vZGUgdHlwZSBhbmQgbWFrZSBzdXJlIHRoYXQgaXQgaXMgd2l0aGluIGxpbWl0cwotCWZpbmFsIHNob3J0IHR5cGUgPSBfdHlwZVtub2RlXTsKLQlzd2l0Y2godHlwZSkgewotCWNhc2UgRE9NLlJPT1Q6Ci0JY2FzZSBET00uVEVYVDoKLQljYXNlIERPTS5VTlVTRUQ6Ci0JY2FzZSBET00uRUxFTUVOVDoKLQljYXNlIERPTS5BVFRSSUJVVEU6Ci0JY2FzZSBET00uQ09NTUVOVDoKLQkgICAgcmV0dXJuIEVNUFRZU1RSSU5HOwotCWNhc2UgRE9NLlBST0NFU1NJTkdfSU5TVFJVQ1RJT046Ci0JICAgIHJldHVybiAiYS1waSI7Ci0JZGVmYXVsdDoKLQkgICAgLy8gQ29uc3RydWN0IHRoZSBsb2NhbCBwYXJ0IChvbWl0ICdAJyBmb3IgYXR0cmlidXRlcykKLQkgICAgU3RyaW5nIG5hbWUgID0gZ2V0TG9jYWxOYW1lKG5vZGUpOwotCSAgICBpZiAobm9kZSA+PSBfZmlyc3RBdHRyaWJ1dGVOb2RlKQotCQluYW1lID0gbmFtZS5zdWJzdHJpbmcoMSk7Ci0KLQkgICAgZmluYWwgaW50IHBpID0gX3ByZWZpeFtub2RlXTsKLQkgICAgaWYgKHBpID4gMCkgewotCQlmaW5hbCBTdHJpbmcgcHJlZml4ID0gX3ByZWZpeEFycmF5W3BpXTsKLQkJaWYgKHByZWZpeCAhPSBFTVBUWVNUUklORykKLQkJICAgIG5hbWUgPSBwcmVmaXgrJzonK25hbWU7Ci0JICAgIH0KLQkgICAgcmV0dXJuIG5hbWU7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgdG8gd2hpY2ggYSBub2RlIGJlbG9uZ3MKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU5hbWUoZmluYWwgaW50IG5vZGUpIHsKLQlmaW5hbCBpbnQgdHlwZSA9IGdldE5hbWVzcGFjZVR5cGUobm9kZSk7Ci0JZmluYWwgU3RyaW5nIG5hbWUgPSBfdXJpQXJyYXlbdHlwZV07Ci0JaWYgKG5hbWUgPT0gbnVsbCkKLQkgICAgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLQllbHNlCi0JICAgIHJldHVybihuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgb2YgYSBzaW5nbGUgdGV4dC9jb21tZW50IG5vZGUgb3IKLSAgICAgKiBhdHRyaWJ1dGUgdmFsdWUgKHRoZXkgYXJlIGFsbCBzdG9yZWQgaW4gdGhlIHNhbWUgYXJyYXkpLgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIG1ha2VTdHJpbmdWYWx1ZShmaW5hbCBpbnQgbm9kZSkgewotCXJldHVybiBuZXcgU3RyaW5nKF90ZXh0LCBfb2Zmc2V0T3JDaGlsZFtub2RlXSwgX2xlbmd0aE9yQXR0cltub2RlXSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgYXR0cmlidXRlIG5vZGUgb2YgYSBnaXZlbiB0eXBlIChpZiBhbnkpIGZvciBhbiBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVOb2RlKGZpbmFsIGludCB0eXBlLCBmaW5hbCBpbnQgZWxlbWVudCkgewotCWZvciAoaW50IGF0dHIgPSBfbGVuZ3RoT3JBdHRyW2VsZW1lbnRdOwotCSAgICAgYXR0ciAhPSBOVUxMOwotCSAgICAgYXR0ciA9IF9uZXh0U2libGluZ1thdHRyXSkgewotCSAgICBpZiAoX3R5cGVbYXR0cl0gPT0gdHlwZSkgcmV0dXJuIGF0dHI7Ci0JfQotCXJldHVybiBOVUxMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZ2l2ZW4gYXR0cmlidXRlIHR5cGUgb2YgYSBnaXZlbiBlbGVtZW50Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVWYWx1ZShmaW5hbCBpbnQgdHlwZSwgZmluYWwgaW50IGVsZW1lbnQpIHsKLQlmaW5hbCBpbnQgYXR0ciA9IGdldEF0dHJpYnV0ZU5vZGUodHlwZSwgZWxlbWVudCk7Ci0JaWYgKGF0dHIgIT0gTlVMTCkKLQkgICAgcmV0dXJuIG1ha2VTdHJpbmdWYWx1ZShhdHRyKTsKLQllbHNlCi0JICAgIHJldHVybiBFTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBnaXZlbiBlbGVtZW50IGhhcyBhbiBhdHRyaWJ1dGUgb2YgYSBnaXZlbiB0eXBlCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlKGZpbmFsIGludCB0eXBlLCBmaW5hbCBpbnQgbm9kZSkgewotCWlmIChnZXRBdHRyaWJ1dGVOb2RlKHR5cGUsIG5vZGUpICE9IE5VTEwpCi0JICAgIHJldHVybiB0cnVlOwotCWVsc2UKLQkgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGZvciB0ZXN0aW5nL2RlYnVnZ2luZyBvbmx5Ci0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVWYWx1ZShmaW5hbCBTdHJpbmcgbmFtZSwgZmluYWwgaW50IGVsZW1lbnQpIHsKLQlyZXR1cm4gZ2V0QXR0cmlidXRlVmFsdWUoZ2V0R2VuZXJhbGl6ZWRUeXBlKG5hbWUpLCBlbGVtZW50KTsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyBhbnkgY2hpbGRyZW4KLSAgICAgKi8KLSAgICBwcml2YXRlIGJvb2xlYW4gaGFzQ2hpbGRyZW4oZmluYWwgaW50IG5vZGUpIHsKLQlpZiAobm9kZSA8IF9maXJzdEF0dHJpYnV0ZU5vZGUpIHsKLQkgICAgZmluYWwgaW50IHR5cGUgPSBfdHlwZVtub2RlXTsKLQkgICAgcmV0dXJuKCgodHlwZSA+PSBOVFlQRVMpIHx8ICh0eXBlID09IFJPT1QpKSAmJgotCQkgICAoX29mZnNldE9yQ2hpbGRbbm9kZV0gIT0gMCkpOwotCX0KLQlyZXR1cm4oZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igd2l0aCBhbGwgdGhlIGNoaWxkcmVuIG9mIGEgZ2l2ZW4gbm9kZQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0Q2hpbGRyZW4oZmluYWwgaW50IG5vZGUpIHsKLQlpZiAoaGFzQ2hpbGRyZW4obm9kZSkpCi0JICAgIHJldHVybihuZXcgQ2hpbGRyZW5JdGVyYXRvcigpKTsKLQllbHNlCi0JICAgIHJldHVybihFTVBUWUlURVJBVE9SKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGl0ZXJhdG9yIHdpdGggYWxsIGNoaWxkcmVuIG9mIGEgc3BlY2lmaWMgdHlwZQotICAgICAqIGZvciBhIGdpdmVuIG5vZGUgKGVsZW1lbnQpCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRUeXBlZENoaWxkcmVuKGZpbmFsIGludCB0eXBlKSB7Ci0JcmV0dXJuKG5ldyBUeXBlZENoaWxkcmVuSXRlcmF0b3IodHlwZSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgaXMgYSBzaG9ydGN1dCB0byB0aGUgaXRlcmF0b3JzIHRoYXQgaW1wbGVtZW50IHRoZQotICAgICAqIHN1cHBvcnRlZCBYUGF0aCBheGVzIChvbmx5IG5hbWVzcGFjZTo6KSBpcyBub3Qgc3VwcG9ydGVkLgotICAgICAqIFJldHVybnMgYSBiYXJlLWJvbmVzIGl0ZXJhdG9yIHRoYXQgbXVzdCBiZSBpbml0aWFsaXplZAotICAgICAqIHdpdGggYSBzdGFydCBub2RlICh1c2luZyBpdGVyYXRvci5zZXRTdGFydE5vZGUoKSkuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMpIHsKLQlOb2RlSXRlcmF0b3IgaXRlcmF0b3IgPSBudWxsOwotCi0Jc3dpdGNoIChheGlzKSB7Ci0JY2FzZSBBeGlzLlNFTEY6Ci0JICAgIGl0ZXJhdG9yID0gbmV3IFNpbmdsZXRvbkl0ZXJhdG9yKCk7Ci0JICAgIGJyZWFrOwotCWNhc2UgQXhpcy5DSElMRDoKLQkgICAgaXRlcmF0b3IgPSBuZXcgQ2hpbGRyZW5JdGVyYXRvcigpOwotCSAgICBicmVhazsKLQljYXNlIEF4aXMuUEFSRU5UOgotCSAgICByZXR1cm4obmV3IFBhcmVudEl0ZXJhdG9yKCkpOwotCWNhc2UgQXhpcy5BTkNFU1RPUjoKLQkgICAgcmV0dXJuKG5ldyBBbmNlc3Rvckl0ZXJhdG9yKCkpOwotCWNhc2UgQXhpcy5BTkNFU1RPUk9SU0VMRjoKLQkgICAgcmV0dXJuKChuZXcgQW5jZXN0b3JJdGVyYXRvcigpKS5pbmNsdWRlU2VsZigpKTsKLQljYXNlIEF4aXMuQVRUUklCVVRFOgotCSAgICByZXR1cm4obmV3IEF0dHJpYnV0ZUl0ZXJhdG9yKCkpOwotCWNhc2UgQXhpcy5ERVNDRU5EQU5UOgotCSAgICBpdGVyYXRvciA9IG5ldyBEZXNjZW5kYW50SXRlcmF0b3IoKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEY6Ci0JICAgIGl0ZXJhdG9yID0gKG5ldyBEZXNjZW5kYW50SXRlcmF0b3IoKSkuaW5jbHVkZVNlbGYoKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBBeGlzLkZPTExPV0lORzoKLQkgICAgaXRlcmF0b3IgPSBuZXcgRm9sbG93aW5nSXRlcmF0b3IoKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBBeGlzLlBSRUNFRElORzoKLQkgICAgaXRlcmF0b3IgPSBuZXcgUHJlY2VkaW5nSXRlcmF0b3IoKTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkc6Ci0JICAgIGl0ZXJhdG9yID0gbmV3IEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcigpOwotCSAgICBicmVhazsKLQljYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORzoKLQkgICAgaXRlcmF0b3IgPSBuZXcgUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yKCk7Ci0JICAgIGJyZWFrOwotCWNhc2UgQXhpcy5OQU1FU1BBQ0U6Ci0JICAgIHJldHVybihuZXcgVHlwZWRBdHRyaWJ1dGVJdGVyYXRvcihnZXRHZW5lcmFsaXplZFR5cGUoInhtbG5zIikpKTsKLQlkZWZhdWx0OgotCSAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKCJFcnJvcjogaXRlcmF0b3IgZm9yIGF4aXMgJyIgKyAKLQkJCQkgICAgICBBeGlzLm5hbWVzW2F4aXNdICsgIicgbm90IGltcGxlbWVudGVkIik7Ci0JICAgIFN5c3RlbS5leGl0KDEpOwotCX0KLQlyZXR1cm4oaXRlcmF0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNpbWlsYXIgdG8gZ2V0QXhpc0l0ZXJhdG9yLCBidXQgdGhpcyBvbmUgcmV0dXJucyBhbiBpdGVyYXRvcgotICAgICAqIGNvbnRhaW5pbmcgbm9kZXMgb2YgYSB0eXBlZCBheGlzIChleC46IGNoaWxkOjpmb28pCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRUeXBlZEF4aXNJdGVyYXRvcihpbnQgYXhpcywgaW50IHR5cGUpIHsKLQlOb2RlSXRlcmF0b3IgaXRlcmF0b3IgPSBudWxsOwotCi0JLyogVGhpcyBjYXVzZXMgYW4gZXJyb3Igd2hlbiB1c2luZyBwYXR0ZXJucyBmb3IgZWxlbWVudHMgdGhhdAotCSAgIGRvIG5vdCBleGlzdCBpbiB0aGUgRE9NICh0cmFuc2xldCB0eXBlcyB3aGljaCBkbyBub3QgY29ycmVzcG9uZAotCSAgIHRvIGEgRE9NIHR5cGUgYXJlIG1hcHBlZCB0byB0aGUgRE9NLkVMRU1FTlQgdHlwZSkuCi0JKi8KLQotCWlmICh0eXBlID09IE5PX1RZUEUpIHsKLQkgICAgcmV0dXJuKEVNUFRZSVRFUkFUT1IpOwotCX0KLSAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBFTEVNRU5UKSB7Ci0JICAgIGl0ZXJhdG9yID0gbmV3IEZpbHRlckl0ZXJhdG9yKGdldEF4aXNJdGVyYXRvcihheGlzKSwKLQkJCQkJICBnZXRFbGVtZW50RmlsdGVyKCkpOwotCX0KLQllbHNlIHsKLQkgICAgc3dpdGNoIChheGlzKSB7Ci0JICAgIGNhc2UgQXhpcy5TRUxGOgotCQlpdGVyYXRvciA9IG5ldyBUeXBlZFNpbmdsZXRvbkl0ZXJhdG9yKHR5cGUpOwotCQlicmVhazsKLQkgICAgY2FzZSBBeGlzLkNISUxEOgotCQlpdGVyYXRvciA9IG5ldyBUeXBlZENoaWxkcmVuSXRlcmF0b3IodHlwZSk7Ci0JCWJyZWFrOwotCSAgICBjYXNlIEF4aXMuUEFSRU5UOgotCQlyZXR1cm4obmV3IFBhcmVudEl0ZXJhdG9yKCkuc2V0Tm9kZVR5cGUodHlwZSkpOwotCSAgICBjYXNlIEF4aXMuQU5DRVNUT1I6Ci0JCXJldHVybihuZXcgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yKHR5cGUpKTsKLQkgICAgY2FzZSBBeGlzLkFOQ0VTVE9ST1JTRUxGOgotCQlyZXR1cm4oKG5ldyBUeXBlZEFuY2VzdG9ySXRlcmF0b3IodHlwZSkpLmluY2x1ZGVTZWxmKCkpOwotCSAgICBjYXNlIEF4aXMuQVRUUklCVVRFOgotCQlyZXR1cm4obmV3IFR5cGVkQXR0cmlidXRlSXRlcmF0b3IodHlwZSkpOwotCSAgICBjYXNlIEF4aXMuREVTQ0VOREFOVDoKLQkJaXRlcmF0b3IgPSBuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSk7Ci0JCWJyZWFrOwotCSAgICBjYXNlIEF4aXMuREVTQ0VOREFOVE9SU0VMRjoKLQkJaXRlcmF0b3IgPSAobmV3IFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yKHR5cGUpKS5pbmNsdWRlU2VsZigpOwotCQlicmVhazsKLQkgICAgY2FzZSBBeGlzLkZPTExPV0lORzoKLQkJaXRlcmF0b3IgPSBuZXcgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcih0eXBlKTsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgQXhpcy5QUkVDRURJTkc6Ci0JCWl0ZXJhdG9yID0gbmV3IFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IodHlwZSk7Ci0JCWJyZWFrOwotCSAgICBjYXNlIEF4aXMuRk9MTE9XSU5HU0lCTElORzoKLQkJaXRlcmF0b3IgPSBuZXcgVHlwZWRGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IodHlwZSk7Ci0JCWJyZWFrOwotCSAgICBjYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORzoKLQkJaXRlcmF0b3IgPSBuZXcgVHlwZWRQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IodHlwZSk7Ci0JCWJyZWFrOwotCSAgICBkZWZhdWx0OgotCQlCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKCJFcnJvcjogdHlwZWQgaXRlcmF0b3IgZm9yIGF4aXMgIiArIAotCQkJCQkgIEF4aXMubmFtZXNbYXhpc10rIm5vdCBpbXBsZW1lbnRlZCIpOwotCSAgICB9Ci0JfQotCSAgICByZXR1cm4oaXRlcmF0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvIG5vdCB0aGluZyB0aGF0IHRoaXMgcmV0dXJucyBhbiBpdGVyYXRvciBmb3IgdGhlIG5hbWVzcGFjZSBheGlzLgotICAgICAqIEl0IHJldHVybnMgYW4gaXRlcmF0b3Igd2l0aCBub2RlcyB0aGF0IGJlbG9uZyBpbiBhIGNlcnRhaW4gbmFtZXNwYWNlLAotICAgICAqIHN1Y2ggYXMgd2l0aCA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9ImJsb2IvZm9vOioiLz4KLSAgICAgKiBUaGUgJ2F4aXMnIHNwZWNpZmllcyB0aGUgYXhpcyBmb3IgdGhlIGJhc2UgaXRlcmF0b3IgZnJvbSB3aGljaCB0aGUKLSAgICAgKiBub2RlcyBhcmUgdGFrZW4sIHdoaWxlICducycgc3BlY2lmaWVzIHRoZSBuYW1lc3BhY2UgVVJJIHR5cGUuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoaW50IGF4aXMsIGludCBucykgewotCi0JTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yID0gbnVsbDsKLQotCWlmIChucyA9PSBOT19UWVBFKSB7Ci0JICAgIHJldHVybihFTVBUWUlURVJBVE9SKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHN3aXRjaCAoYXhpcykgewotCSAgICBjYXNlIEF4aXMuQ0hJTEQ6Ci0JCWl0ZXJhdG9yID0gbmV3IE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IobnMpOwotCQlicmVhazsKLQkgICAgY2FzZSBBeGlzLkFUVFJJQlVURToKLQkJaXRlcmF0b3IgPSBuZXcgTmFtZXNwYWNlQXR0cmlidXRlSXRlcmF0b3IobnMpOwotCQlicmVhazsKLQkgICAgZGVmYXVsdDoKLQkJQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcigiRXJyb3I6IHR5cGVkIGl0ZXJhdG9yIGZvciBheGlzICIgKyAKLQkJCQkJICBBeGlzLm5hbWVzW2F4aXNdKyJub3QgaW1wbGVtZW50ZWQiKTsKLQkgICAgfQotCX0KLQlyZXR1cm4oaXRlcmF0b3IpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3Igd2l0aCBhbGwgZGVzY2VuZGFudHMgb2YgYSBub2RlIHRoYXQgYXJlIG9mCi0gICAgICogYSBnaXZlbiB0eXBlLgotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0VHlwZWREZXNjZW5kYW50SXRlcmF0b3IoaW50IHR5cGUpIHsKLQlOb2RlSXRlcmF0b3IgaXRlcmF0b3IgPSBuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSk7Ci0JaXRlcmF0b3Iuc2V0U3RhcnROb2RlKDEpOwotCXJldHVybihpdGVyYXRvcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbnRoIGRlc2NlbmRhbnQgb2YgYSBub2RlICgxID0gcGFyZW50LCAyID0gZ3JhbXBzKQotICAgICAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0TnRoRGVzY2VuZGFudChpbnQgbm9kZSwgaW50IG4pIHsKLQlyZXR1cm4gKG5ldyBOdGhEZXNjZW5kYW50SXRlcmF0b3IobikpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvcHkgdGhlIGNvbnRlbnRzIG9mIGEgdGV4dC1ub2RlIHRvIGFuIG91dHB1dCBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBpbnQgdGV4dE5vZGUsIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JaGFuZGxlci5jaGFyYWN0ZXJzKF90ZXh0LAotCQkJICAgX29mZnNldE9yQ2hpbGRbdGV4dE5vZGVdLAotCQkJICAgX2xlbmd0aE9yQXR0clt0ZXh0Tm9kZV0pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvcHkgYSBub2RlLXNldCB0byBhbiBvdXRwdXQgaGFuZGxlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNvcHkoTm9kZUl0ZXJhdG9yIG5vZGVzLCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCWludCBub2RlOwotCXdoaWxlICgobm9kZSA9IG5vZGVzLm5leHQoKSkgIT0gTlVMTCkgewotCSAgICBjb3B5KG5vZGUsIGhhbmRsZXIpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb3B5IHRoZSB3aG9sZSB0cmVlIHRvIGFuIG91dHB1dCBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29weShUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQljb3B5KFJPT1ROT0RFLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICAvKiogCi0gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgKHJlZi4gWFNMcyBjb3B5LW9mKCkpCi0gICAgICoKLSAgICAgKiBUT0RPOiBDb3B5IG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMuIENhbid0IGJlIGRvbmUgdW50aWwgd2UKLSAgICAgKiAgICAgICBhZGQgbmFtZXNwYWNlIG5vZGVzIGFuZCBrZWVwIHRyYWNrIG9mIE5TIHByZWZpeGVzCi0gICAgICogVE9ETzogQ29weSBjb21tZW50IG5vZGVzCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29weShmaW5hbCBpbnQgbm9kZSwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQotCWZpbmFsIGludCB0eXBlID0gX3R5cGVbbm9kZV07Ci0KLQlzd2l0Y2godHlwZSkgewotCWNhc2UgUk9PVDoKLQkgICAgZm9yIChpbnQgYz1fb2Zmc2V0T3JDaGlsZFtub2RlXTsgYyE9TlVMTDsgYz1fbmV4dFNpYmxpbmdbY10pCi0JCWNvcHkoYywgaGFuZGxlcik7Ci0JICAgIGJyZWFrOwotCWNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTjoKLQkgICAgY29weVBJKG5vZGUsIGhhbmRsZXIpOwotCSAgICBicmVhazsKLQljYXNlIENPTU1FTlQ6Ci0JY2FzZSBURVhUOgotCSAgICBoYW5kbGVyLmNoYXJhY3RlcnMoX3RleHQsCi0JCQkgICAgICAgX29mZnNldE9yQ2hpbGRbbm9kZV0sCi0JCQkgICAgICAgX2xlbmd0aE9yQXR0cltub2RlXSk7Ci0JICAgIGJyZWFrOwotCWNhc2UgQVRUUklCVVRFOgotCSAgICBzaGFsbG93Q29weShub2RlLCBoYW5kbGVyKTsKLQkgICAgYnJlYWs7Ci0JZGVmYXVsdDoKLQkgICAgaWYgKGlzRWxlbWVudChub2RlKSkgewotCQkvLyBTdGFydCBlbGVtZW50IGRlZmluaXRpb24KLQkJZmluYWwgU3RyaW5nIG5hbWUgPSBjb3B5RWxlbWVudChub2RlLCB0eXBlLCBoYW5kbGVyKTsKLQkJLy8gQ29weSBlbGVtZW50IGF0dHJpYnV0ZQotCQlmb3IgKGludCBhPV9sZW5ndGhPckF0dHJbbm9kZV07IGEhPU5VTEw7IGE9X25leHRTaWJsaW5nW2FdKQotCQkgICAgaGFuZGxlci5hdHRyaWJ1dGUoZ2V0Tm9kZU5hbWUoYSksIG1ha2VTdHJpbmdWYWx1ZShhKSk7Ci0JCS8vIENvcHkgZWxlbWVudCBjaGlsZHJlbgotCQlmb3IgKGludCBjPV9vZmZzZXRPckNoaWxkW25vZGVdOyBjIT1OVUxMOyBjPV9uZXh0U2libGluZ1tjXSkKLQkJICAgIGNvcHkoYywgaGFuZGxlcik7Ci0JCS8vIENsb3NlIGVsZW1lbnQgZGVmaW5pdGlvbgotCQloYW5kbGVyLmVuZEVsZW1lbnQobmFtZSk7Ci0JICAgIH0KLQkgICAgLy8gU2hhbGxvdyBjb3B5IG9mIGF0dHJpYnV0ZSB0byBvdXRwdXQgaGFuZGxlcgotCSAgICBlbHNlIHsKLQkJaGFuZGxlci5hdHRyaWJ1dGUoZ2V0Tm9kZU5hbWUobm9kZSksIG1ha2VTdHJpbmdWYWx1ZShub2RlKSk7Ci0JICAgIH0KLQkgICAgYnJlYWs7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvcGllcyBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZSB0byBhbiBvdXRwdXQgaGFuZGxlcgotICAgICAqLyAKLSAgICBwcml2YXRlIHZvaWQgY29weVBJKGZpbmFsIGludCBub2RlLCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCWZpbmFsIGNoYXJbXSB0ZXh0ID0gX3RleHQ7Ci0JZmluYWwgaW50IHN0YXJ0ID0gX29mZnNldE9yQ2hpbGRbbm9kZV07Ci0JZmluYWwgaW50IGxlbmd0aCA9IF9sZW5ndGhPckF0dHJbbm9kZV07Ci0KLQkvLyBUYXJnZXQgYW5kIFZhbHVlIGFyZSBzZXBhcmF0ZWQgYnkgYSB3aGl0ZXNwYWNlIC0gZmluZCBpdCEKLQlpbnQgaSA9IHN0YXJ0OwotCXdoaWxlICh0ZXh0W2ldICE9ICcgJykgaSsrOwotCi0JZmluYWwgaW50IGxlbiA9IGkgLSBzdGFydDsKLQlmaW5hbCBTdHJpbmcgdGFyZ2V0ID0gbmV3IFN0cmluZyh0ZXh0LCBzdGFydCwgbGVuKTsKLQlmaW5hbCBTdHJpbmcgdmFsdWUgID0gbmV3IFN0cmluZyh0ZXh0LCBpICsgMSwgbGVuZ3RoIC0gbGVuKTsKLQotCWhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgdmFsdWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBlcmZvcm1zIGEgc2hhbGxvdyBjb3B5IChyZWYuIFhTTHMgY29weSgpKQotICAgICAqCi0gICAgICogVE9ETzogQ29weSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLiBDYW4ndCBiZSBkb25lIHVudGlsIHdlCi0gICAgICogICAgICAgYWRkIG5hbWVzcGFjZSBub2RlcyBhbmQga2VlcCB0cmFjayBvZiBOUyBwcmVmaXhlcwotICAgICAqIFRPRE86IENvcHkgY29tbWVudCBub2RlcwotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgc2hhbGxvd0NvcHkoZmluYWwgaW50IG5vZGUsIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0KLQlmaW5hbCBpbnQgdHlwZSA9IF90eXBlW25vZGVdOwotCi0Jc3dpdGNoKHR5cGUpIHsKLQljYXNlIFJPT1Q6IC8vIGRvIG5vdGhpbmcKLQkgICAgcmV0dXJuIEVNUFRZU1RSSU5HOwotCWNhc2UgVEVYVDoKLQkgICAgaGFuZGxlci5jaGFyYWN0ZXJzKF90ZXh0LAotCQkJICAgICAgIF9vZmZzZXRPckNoaWxkW25vZGVdLAotCQkJICAgICAgIF9sZW5ndGhPckF0dHJbbm9kZV0pOwotCSAgICByZXR1cm4gbnVsbDsKLQljYXNlIFBST0NFU1NJTkdfSU5TVFJVQ1RJT046Ci0JICAgIGNvcHlQSShub2RlLCBoYW5kbGVyKTsKLQkgICAgcmV0dXJuIG51bGw7Ci0JY2FzZSBDT01NRU5UOgotCSAgICByZXR1cm4gbnVsbDsKLQlkZWZhdWx0OgotCSAgICBpZiAoaXNFbGVtZW50KG5vZGUpKSB7Ci0JCXJldHVybihjb3B5RWxlbWVudChub2RlLCB0eXBlLCBoYW5kbGVyKSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCVN0cmluZyBuYW1lID0gZ2V0Tm9kZU5hbWUobm9kZSk7Ci0JCWZpbmFsIFN0cmluZyB2YWx1ZSA9IG1ha2VTdHJpbmdWYWx1ZShub2RlKTsKLQkJaGFuZGxlci5hdHRyaWJ1dGUobmFtZSwgdmFsdWUpOwotCQlyZXR1cm4gbnVsbDsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyBjb3B5RWxlbWVudChpbnQgbm9kZSwgaW50IHR5cGUsCi0JCQkgICAgICAgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQotCXR5cGUgPSB0eXBlIC0gTlRZUEVTOwotCVN0cmluZyBuYW1lID0gX25hbWVzQXJyYXlbdHlwZV07Ci0JZmluYWwgaW50IHBpID0gX3ByZWZpeFtub2RlXTsKLQlpZiAocGkgPiAwKSB7Ci0JICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBfcHJlZml4QXJyYXlbcGldOwotCSAgICBmaW5hbCBTdHJpbmcgdXJpID0gX3VyaUFycmF5W19uYW1lc3BhY2VbdHlwZV1dOwotCSAgICBmaW5hbCBTdHJpbmcgbG9jYWwgPSBnZXRMb2NhbE5hbWUobm9kZSk7Ci0JICAgIGlmIChwcmVmaXguZXF1YWxzKEVNUFRZU1RSSU5HKSkKLQkJbmFtZSA9IGxvY2FsOwotCSAgICBlbHNlCi0JCW5hbWUgPSBwcmVmaXgrJzonK2xvY2FsOwotCSAgICBoYW5kbGVyLnN0YXJ0RWxlbWVudChuYW1lKTsKLQkgICAgaGFuZGxlci5uYW1lc3BhY2UocHJlZml4LCB1cmkpOwotCX0KLQllbHNlIHsKLQkgICAgaGFuZGxlci5zdGFydEVsZW1lbnQobmFtZSk7Ci0JfQotCXJldHVybiBuYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgZW50aXJlIHRyZWUKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCkgewotCXJldHVybiBnZXRFbGVtZW50VmFsdWUoUk9PVE5PREUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHN0cmluZyB2YWx1ZSBvZiBhbnkgZWxlbWVudAotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudFZhbHVlKGZpbmFsIGludCBlbGVtZW50KSB7Ci0JLy8gb3B0aW1pemF0aW9uOiBvbmx5IGNyZWF0ZSBTdHJpbmdCdWZmZXIgaWYgPiAxIGNoaWxkCi0JZmluYWwgaW50IGNoaWxkID0gX29mZnNldE9yQ2hpbGRbZWxlbWVudF07Ci0JcmV0dXJuIGNoaWxkICE9IE5VTEwKLQkgICAgPyAoX3R5cGVbY2hpbGRdID09IFRFWFQgJiYgX25leHRTaWJsaW5nW2NoaWxkXSA9PSBOVUxMCi0JICAgICAgID8gbWFrZVN0cmluZ1ZhbHVlKGNoaWxkKQotCSAgICAgICA6IHN0cmluZ1ZhbHVlQXV4KG5ldyBTdHJpbmdCdWZmZXIoKSwgZWxlbWVudCkudG9TdHJpbmcoKSkKLQkgICAgOiBFTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBIZWxwZXIgdG8gZ2V0RWxlbWVudFZhbHVlKCkgYWJvdmUKLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBzdHJpbmdWYWx1ZUF1eChTdHJpbmdCdWZmZXIgYnVmZmVyLCBmaW5hbCBpbnQgZWxlbWVudCkgewotCWZvciAoaW50IGNoaWxkID0gX29mZnNldE9yQ2hpbGRbZWxlbWVudF07Ci0JICAgICBjaGlsZCAhPSBOVUxMOwotCSAgICAgY2hpbGQgPSBfbmV4dFNpYmxpbmdbY2hpbGRdKSB7Ci0JICAgIHN3aXRjaCAoX3R5cGVbY2hpbGRdKSB7Ci0JICAgIGNhc2UgVEVYVDoKLQkgICAgY2FzZSBDT01NRU5UOgotCQlidWZmZXIuYXBwZW5kKF90ZXh0LAotCQkJICAgICAgX29mZnNldE9yQ2hpbGRbY2hpbGRdLAotCQkJICAgICAgX2xlbmd0aE9yQXR0cltjaGlsZF0pOwotCQlicmVhazsKLQkgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OOgotCQlicmVhazsKLQkJLy8gISEhIGF0IHRoZSBtb21lbnQgZGVmYXVsdCBjYW4gb25seSBiZSBhbiBlbGVtZW50Pz8/Ci0JICAgIGRlZmF1bHQ6Ci0JCXN0cmluZ1ZhbHVlQXV4KGJ1ZmZlciwgY2hpbGQpOwotCSAgICB9Ci0JfQotCXJldHVybiBidWZmZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhIG5vZGUnIGRlZmluZWQgbGFuZ3VhZ2UgZm9yIGEgbm9kZSAoaWYgYW55KQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGFuZ3VhZ2UoaW50IG5vZGUpIHsKLQlmaW5hbCBJbnRlZ2VyIGxhbmdUeXBlID0gKEludGVnZXIpX3R5cGVzLmdldCgieG1sOkBsYW5nIik7Ci0JaWYgKGxhbmdUeXBlICE9IG51bGwpIHsKLQkgICAgZmluYWwgaW50IHR5cGUgPSBsYW5nVHlwZS5pbnRWYWx1ZSgpOwotCSAgICB3aGlsZSAobm9kZSAhPSBET00uTlVMTCkgewotCQlpbnQgYXR0ciA9IF9sZW5ndGhPckF0dHJbbm9kZV07Ci0JCXdoaWxlIChhdHRyICE9IERPTS5OVUxMKSB7Ci0JCSAgICBpZiAoX3R5cGVbYXR0cl0gPT0gdHlwZSkKLQkJCXJldHVybihnZXROb2RlVmFsdWUoYXR0cikpOwotCQkgICAgYXR0ciA9IF9uZXh0U2libGluZ1thdHRyXTsKLQkJfQotCQlub2RlID0gZ2V0UGFyZW50KG5vZGUpOwotCSAgICB9Ci0JfQotCXJldHVybihudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBET01CdWlsZGVyIGlubmVyIGNsYXNzCi0gICAgICogVGhpcyBjbGFzcyB3aWxsIGNvbnN1bWUgdGhlIGlucHV0IGRvY3VtZW50IHRocm91Z2ggYSBTQVgyCi0gICAgICogaW50ZXJmYWNlIGFuZCBwb3B1bGF0ZSB0aGUgdHJlZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NQnVpbGRlciBnZXRCdWlsZGVyKCkgewotCXJldHVybiBuZXcgRE9NQnVpbGRlckltcGwoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgRE9NQnVpbGRlciBjbGFzcyB3cmFwcGVkIGluIGEgU0FYIGFkYXB0ZXIuCi0gICAgICogSSBhbSBub3Qgc3VyZSBpZiB3ZSBuZWVkIHRoaXMgb25lIGFueW1vcmUgbm93IHRoYXQgdGhlCi0gICAgICogRE9NIGJ1aWxkZXIncyBpbnRlcmZhY2UgaXMgcHVyZSBTQVgyIChtdXN0IGludmVzdGlnYXRlKQotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2xldE91dHB1dEhhbmRsZXIgZ2V0T3V0cHV0RG9tQnVpbGRlcigpIHsKLQlyZXR1cm4gbmV3IFNBWEFkYXB0ZXIoZ2V0QnVpbGRlcigpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBjaGFyYWN0ZXIgaXMgYW4gWE1MIHdoaXRlc3BhY2UgY2hhcmFjdGVyLgotICAgICAqIE9yZGVyIG9mIHRlc3RzIGlzIGltcG9ydGFudCBmb3IgcGVyZm9ybWFuY2UgKFtzcGFjZV0gZmlyc3QpLgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNXaGl0ZXNwYWNlQ2hhcihjaGFyIGMpIHsKLQlyZXR1cm4gYyA9PSAweDIwIHx8IGMgPT0gMHgwQSB8fCBjID09IDB4MEQgfHwgYyA9PSAweDA5OwotICAgIH0KLQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gICAgLyogICAgICAgICAgICAgICBET00gYnVpbGRlciBjbGFzcyBkZWZpbml0aW9uICAgICAgICAgICAgICAgICAgICovCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0gICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBET01CdWlsZGVySW1wbCBpbXBsZW1lbnRzIERPTUJ1aWxkZXIgewotCi0JcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IEFUVFJfQVJSQVlfU0laRSA9IDMyOwotCXByaXZhdGUgZmluYWwgc3RhdGljIGludCBSRVVTQUJMRV9URVhUX1NJWkUgPSAzMjsKLQlwcml2YXRlIEhhc2h0YWJsZSBfc2hvcnRUZXh0cyAgICAgICAgICAgPSBudWxsOwotCi0JcHJpdmF0ZSBIYXNodGFibGUgX25hbWVzICAgICAgICAgICAgICAgID0gbnVsbDsKLQlwcml2YXRlIGludCAgICAgICBfbmV4dE5hbWVDb2RlICAgICAgICAgPSBOVFlQRVM7Ci0JcHJpdmF0ZSBpbnRbXSAgICAgX3BhcmVudFN0YWNrICAgICAgICAgID0gbmV3IGludFs2NF07Ci0JcHJpdmF0ZSBpbnRbXSAgICAgX3ByZXZpb3VzU2libGluZ1N0YWNrID0gbmV3IGludFs2NF07Ci0JcHJpdmF0ZSBpbnQgICAgICAgX3NwOwotCXByaXZhdGUgaW50ICAgICAgIF9iYXNlT2Zmc2V0ICAgICAgICAgICA9IDA7Ci0JcHJpdmF0ZSBpbnQgICAgICAgX2N1cnJlbnRPZmZzZXQgICAgICAgID0gMDsKLQlwcml2YXRlIGludCAgICAgICBfY3VycmVudE5vZGUgICAgICAgICAgPSAwOwotCi0JLy8gVGVtcG9yYXJ5IHN0cnVjdHVyZXMgZm9yIGF0dHJpYnV0ZSBub2RlcwotCXByaXZhdGUgaW50ICAgICAgIF9jdXJyZW50QXR0cmlidXRlTm9kZSA9IDA7Ci0JcHJpdmF0ZSBzaG9ydFtdICAgX3R5cGUyICAgICAgICA9IG5ldyBzaG9ydFtBVFRSX0FSUkFZX1NJWkVdOwotCXByaXZhdGUgc2hvcnRbXSAgIF9wcmVmaXgyICAgICAgPSBuZXcgc2hvcnRbQVRUUl9BUlJBWV9TSVpFXTsKLQlwcml2YXRlIGludFtdICAgICBfcGFyZW50MiAgICAgID0gbmV3IGludFtBVFRSX0FSUkFZX1NJWkVdOwotCXByaXZhdGUgaW50W10gICAgIF9uZXh0U2libGluZzIgPSBuZXcgaW50W0FUVFJfQVJSQVlfU0laRV07Ci0JcHJpdmF0ZSBpbnRbXSAgICAgX29mZnNldCAgICAgICA9IG5ldyBpbnRbQVRUUl9BUlJBWV9TSVpFXTsKLQlwcml2YXRlIGludFtdICAgICBfbGVuZ3RoICAgICAgID0gbmV3IGludFtBVFRSX0FSUkFZX1NJWkVdOwotCi0JLy8gTmFtZXNwYWNlIHByZWZpeC10by11cmkgbWFwcGluZyBzdHVmZgotCXByaXZhdGUgSGFzaHRhYmxlIF9uc1ByZWZpeGVzICAgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JcHJpdmF0ZSBpbnQgICAgICAgX3VyaUNvdW50ICAgICA9IDA7Ci0JcHJpdmF0ZSBpbnQgICAgICAgX3ByZWZpeENvdW50ICA9IDA7Ci0JCi0JLy8gU3RhY2sgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHdoYXQgd2hpdGVzcGFjZSB0ZXh0IG5vZGVzIGFyZSBwcm90ZWN0ZWQKLQkvLyBieSB4bWw6c3BhY2U9InByZXNlcnZlIiBhdHRyaWJ1dGVzIGFuZCB3aGljaCBub2RlcyB0aGF0IGFyZSBub3QuCi0JcHJpdmF0ZSBpbnRbXSAgIF94bWxTcGFjZVN0YWNrID0gbmV3IGludFs2NF07Ci0JcHJpdmF0ZSBpbnQgICAgIF9pZHggPSAxOwotCXByaXZhdGUgYm9vbGVhbiBfcHJlc2VydmUgPSBmYWxzZTsKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfU1RSSU5HID0gInhtbDoiOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxTUEFDRV9TVFJJTkcgPSAieG1sOnNwYWNlIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFU0VSVkVfU1RSSU5HID0gInByZXNlcnZlIjsKLQotCS8qKgotCSAqIERlZmF1bHQgY29uc3RydWN0b3IgZm9yIHRoZSBET01CdWlsZXIgY2xhc3MKLQkgKi8KLQlwdWJsaWMgRE9NQnVpbGRlckltcGwoKSB7Ci0JICAgIF94bWxTcGFjZVN0YWNrWzBdID0gRE9NLlJPT1ROT0RFOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgdGhhdCBhIHByZWZpeCBjdXJyZW50bCBtYXBzIHRvCi0JICovCi0JcHJpdmF0ZSBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKFN0cmluZyBwcmVmaXgpIHsKLQkgICAgLy8gR2V0IHRoZSBzdGFjayBhc3NvY2lhdGVkIHdpdGggdGhpcyBuYW1lc3BhY2UgcHJlZml4Ci0JICAgIGZpbmFsIFN0YWNrIHN0YWNrID0gKFN0YWNrKV9uc1ByZWZpeGVzLmdldChwcmVmaXgpOwotCSAgICBpZiAoKHN0YWNrICE9IG51bGwpICYmICghc3RhY2suZW1wdHkoKSkpIHsKLQkJcmV0dXJuKChTdHJpbmcpc3RhY2sucGVlaygpKTsKLQkgICAgfQotCSAgICBlbHNlCi0JCXJldHVybihFTVBUWVNUUklORyk7Ci0JfQotCi0JLyoqCi0JICogQ2FsbCB0aGlzIHdoZW4gYW4geG1sOnNwYWNlIGF0dHJpYnV0ZSBpcyBlbmNvdW50ZXJlZCB0bwotCSAqIGRlZmluZSB0aGUgd2hpdGVzcGFjZSBzdHJpcC9wcmVzZXJ2ZSBzZXR0aW5ncy4KLQkgKi8KLQlwcml2YXRlIHZvaWQgeG1sU3BhY2VEZWZpbmUoU3RyaW5nIHZhbCwgZmluYWwgaW50IG5vZGUpIHsKLQkgICAgZmluYWwgYm9vbGVhbiBzZXR0aW5nID0gdmFsLmVxdWFscyhQUkVTRVJWRV9TVFJJTkcpOwotCSAgICBpZiAoc2V0dGluZyAhPSBfcHJlc2VydmUpIHsKLQkJX3htbFNwYWNlU3RhY2tbX2lkeCsrXSA9IG5vZGU7Ci0JCV9wcmVzZXJ2ZSA9IHNldHRpbmc7Ci0JICAgIH0KLQl9Ci0KLQkvKioKLQkgKiBDYWxsIHRoaXMgZnJvbSBlbmRFbGVtZW50KCkgdG8gcmV2ZXJ0IHN0cmlwL3ByZXNlcnZlIHNldHRpbmcKLQkgKiB0byB3aGF0ZXZlciBpdCB3YXMgYmVmb3JlIHRoZSBjb3JyZXNwb25kaW5nIHN0YXJ0RWxlbWVudCgpCi0JICovCi0JcHJpdmF0ZSB2b2lkIHhtbFNwYWNlUmV2ZXJ0KGZpbmFsIGludCBub2RlKSB7Ci0JICAgIGlmIChub2RlID09IF94bWxTcGFjZVN0YWNrW19pZHggLSAxXSkgewotCQlfaWR4LS07Ci0JCV9wcmVzZXJ2ZSA9ICFfcHJlc2VydmU7Ci0JICAgIH0KLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBuZXh0IGF2YWlsYWJsZSBub2RlLiBJbmNyZWFzZXMgdGhlIHZhcmlvdXMgYXJyYXlzCi0JICogdGhhdCBjb25zdGl0dXRlIHRoZSBub2RlIGlmIG5lY2Vzc2FyeS4KLQkgKi8KLQlwcml2YXRlIGludCBuZXh0Tm9kZSgpIHsKLQkgICAgZmluYWwgaW50IGluZGV4ID0gX2N1cnJlbnROb2RlKys7Ci0JICAgIGlmIChpbmRleCA9PSBfdHlwZS5sZW5ndGgpIHsKLQkJcmVzaXplQXJyYXlzKF90eXBlLmxlbmd0aCAqIDIsIGluZGV4KTsKLQkgICAgfQotCSAgICByZXR1cm4gaW5kZXg7Ci0JfQotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgbmV4dCBhdmFpbGFibGUgYXR0cmlidXRlIG5vZGUuIEluY3JlYXNlcyB0aGUKLQkgKiB2YXJpb3VzIGFycmF5cyB0aGF0IGNvbnN0aXR1dGUgdGhlIGF0dHJpYnV0ZSBpZiBuZWNlc3NhcnkKLQkgKi8KLQlwcml2YXRlIGludCBuZXh0QXR0cmlidXRlTm9kZSgpIHsKLQkgICAgZmluYWwgaW50IGluZGV4ID0gX2N1cnJlbnRBdHRyaWJ1dGVOb2RlKys7Ci0JICAgIGlmIChpbmRleCA9PSBfdHlwZTIubGVuZ3RoKSB7Ci0JCXJlc2l6ZUFycmF5czIoX3R5cGUyLmxlbmd0aCAqIDIsIGluZGV4KTsKLQkgICAgfQotCSAgICByZXR1cm4gaW5kZXg7Ci0JfQotCi0JLyoqCi0JICogUmVzaXplIHRoZSBjaGFyYWN0ZXIgYXJyYXkgdGhhdCBob2xkcyB0aGUgY29udGVudHMgb2YKLQkgKiBhbGwgdGV4dCBub2RlcywgY29tbWVudHMgYW5kIGF0dHJpYnV0ZSB2YWx1ZXMKLQkgKi8KLQlwcml2YXRlIHZvaWQgcmVzaXplVGV4dEFycmF5KGZpbmFsIGludCBuZXdTaXplKSB7Ci0JICAgIGZpbmFsIGNoYXJbXSBuZXdUZXh0ID0gbmV3IGNoYXJbbmV3U2l6ZV07Ci0JICAgIFN5c3RlbS5hcnJheWNvcHkoX3RleHQsIDAsIG5ld1RleHQsIDAsIF9jdXJyZW50T2Zmc2V0KTsKLQkgICAgX3RleHQgPSBuZXdUZXh0OwotCX0KLQkKLQkvKioKLQkgKiBMaW5rcyB0b2dldGhlciB0aGUgY2hpbGRyZW4gb2YgYSBub2RlLiBDaGlsZCBub2RlcyBhcmUgbGlua2VkCi0JICogdGhyb3VnaCB0aGUgX25leHRTaWJsaW5nIGFycmF5Ci0JICovCi0JcHJpdmF0ZSB2b2lkIGxpbmtDaGlsZHJlbihmaW5hbCBpbnQgbm9kZSkgewotCSAgICBfcGFyZW50W25vZGVdID0gX3BhcmVudFN0YWNrW19zcF07Ci0JICAgIGlmIChfcHJldmlvdXNTaWJsaW5nU3RhY2tbX3NwXSAhPSAwKSB7IC8vIGN1cnJlbnQgbm90IGZpcnN0IGNoaWxkCi0JCV9uZXh0U2libGluZ1tfcHJldmlvdXNTaWJsaW5nU3RhY2tbX3NwXV0gPSBub2RlOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlfb2Zmc2V0T3JDaGlsZFtfcGFyZW50U3RhY2tbX3NwXV0gPSBub2RlOwotCSAgICB9Ci0JICAgIF9wcmV2aW91c1NpYmxpbmdTdGFja1tfc3BdID0gbm9kZTsKLQl9Ci0KLQkvKioKLQkgKiBHZW5lcmF0ZSB0aGUgaW50ZXJuYWwgdHlwZSBmb3IgYW4gZWxlbWVudCdzIGV4cGFuZGVkIFFOYW1lCi0JICovCi0JcHJpdmF0ZSBzaG9ydCBtYWtlRWxlbWVudE5vZGUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsbmFtZSkKLQkgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JICAgIAotCSAgICBmaW5hbCBTdHJpbmcgbmFtZTsKLQkgICAgaWYgKHVyaSAhPSBFTVBUWVNUUklORykKLQkJbmFtZSA9IHVyaSArICc6JyArIGxvY2FsbmFtZTsKLQkgICAgZWxzZQotCQluYW1lID0gbG9jYWxuYW1lOwotCi0JICAgIC8vIFN0dWZmIHRoZSBRTmFtZSBpbnRvIHRoZSBuYW1lcyB2ZWN0b3IgJiBoYXNodGFibGUKLQkgICAgSW50ZWdlciBvYmogPSAoSW50ZWdlcilfbmFtZXMuZ2V0KG5hbWUpOwotCSAgICBpZiAob2JqID09IG51bGwpIHsKLQkJX25hbWVzLnB1dChuYW1lLCBvYmogPSBuZXcgSW50ZWdlcihfbmV4dE5hbWVDb2RlKyspKTsKLQkgICAgfQotCSAgICByZXR1cm4gKHNob3J0KW9iai5pbnRWYWx1ZSgpOwotCX0KLQotCS8qKgotCSAqIEdlbmVyYXRlIHRoZSBpbnRlcm5hbCB0eXBlIGZvciBhbiBlbGVtZW50J3MgZXhwYW5kZWQgUU5hbWUKLQkgKi8KLQlwcml2YXRlIHNob3J0IG1ha2VFbGVtZW50Tm9kZShTdHJpbmcgbmFtZSwgaW50IGNvbCkKLQkgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JICAgIC8vIEV4cGFuZCBwcmVmaXg6bG9jYWxuYW1lIHRvIGZ1bGwgUU5hbWUKLQkgICAgaWYgKGNvbCA+IC0xKSB7Ci0JCWZpbmFsIFN0cmluZyB1cmkgPSBnZXROYW1lc3BhY2VVUkkobmFtZS5zdWJzdHJpbmcoMCwgY29sKSk7Ci0JCW5hbWUgPSB1cmkgKyBuYW1lLnN1YnN0cmluZyhjb2wpOwotCSAgICB9Ci0JICAgIC8vIEFwcGVuZCBkZWZhdWx0IG5hbWVzcGFjZSB3aXRoIHRoZSBuYW1lIGhhcyBubyBwcmVmaXgKLQkgICAgZWxzZSB7Ci0JCWZpbmFsIFN0cmluZyB1cmkgPSBnZXROYW1lc3BhY2VVUkkoRU1QVFlTVFJJTkcpOwotCQlpZiAoIXVyaS5lcXVhbHMoRU1QVFlTVFJJTkcpKSBuYW1lID0gdXJpICsgJzonICsgbmFtZTsKLQkgICAgfQotCi0JICAgIC8vIFN0dWZmIHRoZSBRTmFtZSBpbnRvIHRoZSBuYW1lcyB2ZWN0b3IgJiBoYXNodGFibGUKLQkgICAgSW50ZWdlciBvYmogPSAoSW50ZWdlcilfbmFtZXMuZ2V0KG5hbWUpOwotCSAgICBpZiAob2JqID09IG51bGwpIHsKLQkJX25hbWVzLnB1dChuYW1lLCBvYmogPSBuZXcgSW50ZWdlcihfbmV4dE5hbWVDb2RlKyspKTsKLQkgICAgfQotCSAgICByZXR1cm4gKHNob3J0KW9iai5pbnRWYWx1ZSgpOwotCX0KLQotCS8qKgotCSAqCi0JICovCi0JcHJpdmF0ZSBzaG9ydCByZWdpc3RlclByZWZpeChTdHJpbmcgcHJlZml4KSB7Ci0JICAgIFN0YWNrIHN0YWNrID0gKFN0YWNrKV9uc1ByZWZpeGVzLmdldChwcmVmaXgpOwotCSAgICBpZiAoc3RhY2sgIT0gbnVsbCkgewotCQlJbnRlZ2VyIG9iaiA9IChJbnRlZ2VyKXN0YWNrLmVsZW1lbnRBdCgwKTsKLQkJcmV0dXJuIChzaG9ydClvYmouaW50VmFsdWUoKTsKLQkgICAgfQotCSAgICByZXR1cm4gMDsKLQl9Ci0KLQkvKgotCSAqIFRoaXMgbWV0aG9kIHdpbGwgY2hlY2sgaWYgdGhlIGN1cnJlbnQgdGV4dCBub2RlIGNvbnRhaW5zIHRleHQgdGhhdAotCSAqIGlzIGFscmVhZHkgaW4gdGhlIHRleHQgYXJyYXkuIElmIHRoZSB0ZXh0IGlzIGZvdW5kIGluIHRoZSBhcnJheQotCSAqIHRoZW4gdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgb2Zmc2V0IG9mIHRoZSBwcmV2aW91cyBpbnN0YW5jZSBvZiB0aGUKLQkgKiBzdHJpbmcuIE90aGVyd2lzZSB0aGUgdGV4dCBpcyBpbnNlcnRlZCBpbiB0aGUgYXJyYXksIGFuZCB0aGUKLQkgKiBvZmZzZXQgb2YgdGhlIG5ldyBpbnN0YW5jZSBpcyBpbnNlcnRlZC4KLQkgKiBVcGRhdGVzIHRoZSBnbG9iYWxzIF9iYXNlT2Zmc2V0IGFuZCBfY3VycmVudE9mZnNldAotCSAqLwotCXByaXZhdGUgaW50IG1heWJlUmV1c2VUZXh0KGZpbmFsIGludCBsZW5ndGgpIHsKLQkgICAgZmluYWwgaW50IGJhc2UgPSBfYmFzZU9mZnNldDsKLQkgICAgaWYgKGxlbmd0aCA8PSBSRVVTQUJMRV9URVhUX1NJWkUpIHsKLQkJLy8gVXNlIGEgY2hhciBhcnJheSBpbnN0ZWFkIG9mIHN0cmluZyBmb3IgcGVyZm9ybWFuY2UgYmVuZWZpdAotCQljaGFyW10gY2hhcnMgPSBuZXcgY2hhcltsZW5ndGhdOwotCQlTeXN0ZW0uYXJyYXljb3B5KF90ZXh0LCBiYXNlLCBjaGFycywgMCwgbGVuZ3RoKTsKLQkJZmluYWwgSW50ZWdlciBvZmZzZXRPYmogPSAoSW50ZWdlcilfc2hvcnRUZXh0cy5nZXQoY2hhcnMpOwotCi0JCWlmIChvZmZzZXRPYmogIT0gbnVsbCkgewotCQkgICAgX2N1cnJlbnRPZmZzZXQgPSBiYXNlOyAgICAgICAvLyBzdGVwIGJhY2sgY3VycmVudAotCQkgICAgcmV0dXJuIG9mZnNldE9iai5pbnRWYWx1ZSgpOyAvLyByZXVzZSBwcmV2aW91cyBzdHJpbmcKLQkJfQotCQllbHNlIHsKLQkJICAgIF9zaG9ydFRleHRzLnB1dChjaGFycywgbmV3IEludGVnZXIoYmFzZSkpOwotCQl9Ci0JICAgIH0KLQkgICAgX2Jhc2VPZmZzZXQgPSBfY3VycmVudE9mZnNldDsgLy8gYWR2YW5jZSBiYXNlIHRvIGN1cnJlbnQKLQkgICAgcmV0dXJuIGJhc2U7Ci0JfQotCi0JLyoqCi0JICogTGlua3MgYSB0ZXh0IHJlZmVyZW5jZSAoYW4gb2NjdXJhbmNlIG9mIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycwotCSAqIGluIHRoZSBfdGV4dFtdIGFycmF5KSB0byBhIHNwZWNpZmljIG5vZGUgaW5kZXguCi0JICovCi0JcHJpdmF0ZSB2b2lkIHN0b3JlVGV4dFJlZihmaW5hbCBpbnQgbm9kZSkgewotCSAgICBmaW5hbCBpbnQgbGVuZ3RoID0gX2N1cnJlbnRPZmZzZXQgLSBfYmFzZU9mZnNldDsKLQkgICAgX29mZnNldE9yQ2hpbGRbbm9kZV0gPSBtYXliZVJldXNlVGV4dChsZW5ndGgpOwotCSAgICBfbGVuZ3RoT3JBdHRyW25vZGVdICA9IGxlbmd0aDsKLQl9Ci0JCi0JLyoqCi0JICogQ3JlYXRlcyBhIHRleHQtbm9kZSBhbmQgY2hlY2tzIGlmIGl0IGlzIGEgd2hpdGVzcGFjZSBub2RlLgotCSAqLwotCXByaXZhdGUgaW50IG1ha2VUZXh0Tm9kZShib29sZWFuIGlzV2hpdGVzcGFjZSkgewotCSAgICBpZiAoX2N1cnJlbnRPZmZzZXQgPiBfYmFzZU9mZnNldCkgewotCQlmaW5hbCBpbnQgbm9kZSA9IG5leHROb2RlKCk7Ci0JCWZpbmFsIGludCBsaW1pdCA9IF9jdXJyZW50T2Zmc2V0OwotCQkvLyBUYWcgYXMgd2hpdGVzcGFjZSBub2RlIGlmIHRoZSBwYXJzZXIgdGVsbHMgdXMgdGhhdCBpdCBpcy4uLgotCQlpZiAoaXNXaGl0ZXNwYWNlKSB7Ci0JCSAgICBfd2hpdGVzcGFjZS5zZXRCaXQobm9kZSk7Ci0JCX0KLQkJLy8gLi4ub3RoZXJ3aXNlIHdlIGNoZWNrIGlmIHRoaXMgaXMgYSB3aGl0ZXNwYWNlIG5vZGUsIHVubGVzcwotCQkvLyB0aGUgbm9kZSBpcyBwcm90ZWN0ZWQgYnkgYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgYXR0cmlidXRlLgotCQllbHNlIGlmICghX3ByZXNlcnZlKSB7Ci0JCSAgICBpbnQgaSA9IF9iYXNlT2Zmc2V0OwotCQkgICAgd2hpbGUgKGlzV2hpdGVzcGFjZUNoYXIoX3RleHRbaSsrXSkgJiYgaSA8IGxpbWl0KSA7Ci0JCSAgICBpZiAoKGkgPT0gbGltaXQpICYmIGlzV2hpdGVzcGFjZUNoYXIoX3RleHRbaS0xXSkpIAotCQkJX3doaXRlc3BhY2Uuc2V0Qml0KG5vZGUpOwotCQl9Ci0KLQkJX3R5cGVbbm9kZV0gPSBURVhUOwotCQlsaW5rQ2hpbGRyZW4obm9kZSk7Ci0JCXN0b3JlVGV4dFJlZihub2RlKTsKLQkJcmV0dXJuIG5vZGU7Ci0JICAgIH0KLQkgICAgcmV0dXJuIC0xOwotCX0KLQotCS8qKgotCSAqIExpbmtzIGFuIGF0dHJpYnV0ZSB2YWx1ZSAoYW4gb2NjdXJhbmNlIG9mIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycwotCSAqIGluIHRoZSBfdGV4dFtdIGFycmF5KSB0byBhIHNwZWNpZmljIGF0dHJpYnV0ZSBub2RlIGluZGV4LgotCSAqLwotCXByaXZhdGUgdm9pZCBzdG9yZUF0dHJWYWxSZWYoZmluYWwgaW50IGF0dHJpYnV0ZU5vZGUpIHsKLQkgICAgZmluYWwgaW50IGxlbmd0aCA9IF9jdXJyZW50T2Zmc2V0IC0gX2Jhc2VPZmZzZXQ7Ci0JICAgIF9vZmZzZXRbYXR0cmlidXRlTm9kZV0gPSBtYXliZVJldXNlVGV4dChsZW5ndGgpOwotCSAgICBfbGVuZ3RoW2F0dHJpYnV0ZU5vZGVdID0gbGVuZ3RoOwotCX0KLQotCS8qKgotCSAqIENyZWF0ZXMgYW4gYXR0cmlidXRlIG5vZGUKLQkgKi8KLQlwcml2YXRlIGludCBtYWtlQXR0cmlidXRlTm9kZShpbnQgcGFyZW50LCBBdHRyaWJ1dGVzIGF0dExpc3QsIGludCBpKQotCSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotICAgIAkgICAgZmluYWwgaW50IG5vZGUgPSBuZXh0QXR0cmlidXRlTm9kZSgpOwotCi0JICAgIGZpbmFsIFN0cmluZyBxbmFtZSA9IGF0dExpc3QuZ2V0UU5hbWUoaSk7Ci0JICAgIGZpbmFsIFN0cmluZyBsb2NhbG5hbWUgPSBhdHRMaXN0LmdldExvY2FsTmFtZShpKTsKLQkgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gYXR0TGlzdC5nZXRWYWx1ZShpKTsKLQkgICAgU3RyaW5nQnVmZmVyIG5hbWVidWYgPSBuZXcgU3RyaW5nQnVmZmVyKEVNUFRZU1RSSU5HKTsKLQkgICAgCi0JICAgIC8vIENyZWF0ZSB0aGUgaW50ZXJuYWwgYXR0cmlidXRlIG5vZGUgbmFtZSAodXJpK0ArbG9jYWxuYW1lKQotCSAgICBpZiAocW5hbWUuc3RhcnRzV2l0aChYTUxfU1RSSU5HKSkgewotCQlpZiAocW5hbWUuc3RhcnRzV2l0aChYTUxTUEFDRV9TVFJJTkcpKQotCQkgICAgeG1sU3BhY2VEZWZpbmUoYXR0TGlzdC5nZXRWYWx1ZShpKSwgcGFyZW50KTsKLQkJbmFtZWJ1Zi5hcHBlbmQoInhtbDoiKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJZmluYWwgU3RyaW5nIHVyaSA9IGF0dExpc3QuZ2V0VVJJKGkpOwotCQlpZiAoKHVyaSAhPSBudWxsKSAmJiAoIXVyaS5lcXVhbHMoRU1QVFlTVFJJTkcpKSkgewotCQkgICAgbmFtZWJ1Zi5hcHBlbmQodXJpKTsKLQkJICAgIG5hbWVidWYuYXBwZW5kKCc6Jyk7Ci0JCX0KLQkgICAgfQotCSAgICBuYW1lYnVmLmFwcGVuZCgnQCcpOwotCSAgICBuYW1lYnVmLmFwcGVuZChsb2NhbG5hbWUpOwotCi0JICAgIFN0cmluZyBuYW1lID0gbmFtZWJ1Zi50b1N0cmluZygpOwotCSAgICAKLQkgICAgLy8gR2V0IHRoZSBpbmRleCBvZiB0aGUgYXR0cmlidXRlIG5vZGUgbmFtZSAoY3JlYXRlIG5ldyBpZiBub24tZXgpLgotCSAgICBJbnRlZ2VyIG9iaiA9IChJbnRlZ2VyKV9uYW1lcy5nZXQobmFtZSk7Ci0JICAgIGlmIChvYmogPT0gbnVsbCkgewotCQlfdHlwZTJbbm9kZV0gPSAoc2hvcnQpX25leHROYW1lQ29kZTsKLQkJX25hbWVzLnB1dChuYW1lLCBvYmogPSBuZXcgSW50ZWdlcihfbmV4dE5hbWVDb2RlKyspKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX3R5cGUyW25vZGVdID0gKHNob3J0KW9iai5pbnRWYWx1ZSgpOwotCSAgICB9Ci0KLQkgICAgX3BhcmVudDJbbm9kZV0gPSBwYXJlbnQ7Ci0KLQkgICAgZmluYWwgaW50IGNvbCA9IHFuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0JICAgIGlmIChjb2wgPiAwKSB7Ci0JCV9wcmVmaXgyW25vZGVdID0gcmVnaXN0ZXJQcmVmaXgocW5hbWUuc3Vic3RyaW5nKDAsIGNvbCkpOwotCSAgICB9Ci0KLQkgICAgY2hhcmFjdGVycyhhdHRMaXN0LmdldFZhbHVlKGkpKTsKLQkgICAgc3RvcmVBdHRyVmFsUmVmKG5vZGUpOwotCSAgICByZXR1cm4gbm9kZTsKLQl9Ci0JCi0JLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0JLyogICAgICAgICAgICAgICBTQVggSW50ZXJmYWNlIFN0YXJ0cyBIZXJlICAgICAgICAgICAgICAgICAgICAgICovCi0JLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLQkvKioKLQkgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLQkgKi8KLQlwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0JICAgIGlmIChfY3VycmVudE9mZnNldCArIGxlbmd0aCA+IF90ZXh0Lmxlbmd0aCkgewotCQlyZXNpemVUZXh0QXJyYXkoX3RleHQubGVuZ3RoICogMik7Ci0JICAgIH0KLQkgICAgU3lzdGVtLmFycmF5Y29weShjaCwgc3RhcnQsIF90ZXh0LCBfY3VycmVudE9mZnNldCwgbGVuZ3RoKTsKLQkgICAgX2N1cnJlbnRPZmZzZXQgKz0gbGVuZ3RoOwotCX0KLQotCS8qKgotCSAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYSBkb2N1bWVudC4KLQkgKi8KLQlwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgewotCSAgICBfc2hvcnRUZXh0cyAgICAgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JICAgIF9uYW1lcyAgICAgICAgICA9IG5ldyBIYXNodGFibGUoKTsKLQkgICAgX3NwICAgICAgICAgICAgID0gMDsKLQkgICAgX3BhcmVudFN0YWNrWzBdID0gUk9PVE5PREU7CS8vIHJvb3QKLQkgICAgX2N1cnJlbnROb2RlICAgID0gUk9PVE5PREUgKyAxOwotCSAgICBfY3VycmVudEF0dHJpYnV0ZU5vZGUgPSAwOwotCSAgICBzdGFydFByZWZpeE1hcHBpbmcoRU1QVFlTVFJJTkcsIEVNUFRZU1RSSU5HKTsKLQl9Ci0KLQkvKioKLQkgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGEgZG9jdW1lbnQuCi0JICovCi0JcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB7Ci0JICAgIG1ha2VUZXh0Tm9kZShmYWxzZSk7Ci0KLQkgICAgX3Nob3J0VGV4dHMgPSBudWxsOwotCSAgICBmaW5hbCBpbnQgbmFtZXNTaXplID0gX25leHROYW1lQ29kZSAtIE5UWVBFUzsKLQotCSAgICAvLyBGaWxsIHRoZSBfbmFtZXNBcnJheVtdIGFycmF5Ci0JICAgIF9uYW1lc0FycmF5ID0gbmV3IFN0cmluZ1tuYW1lc1NpemVdOwotCSAgICBFbnVtZXJhdGlvbiBrZXlzID0gX25hbWVzLmtleXMoKTsKLQkgICAgd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJZmluYWwgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKWtleXMubmV4dEVsZW1lbnQoKTsKLQkJZmluYWwgSW50ZWdlciBpZHggPSAoSW50ZWdlcilfbmFtZXMuZ2V0KG5hbWUpOwotCQlfbmFtZXNBcnJheVtpZHguaW50VmFsdWUoKSAtIE5UWVBFU10gPSBuYW1lOwotCSAgICB9Ci0KLQkgICAgX25hbWVzID0gbnVsbDsKLQkgICAgX3R5cGVzID0gc2V0dXBNYXBwaW5nKF9uYW1lc0FycmF5KTsKLQotCSAgICAvLyB0cmltIGFycmF5cycgc2l6ZXMKLQkgICAgcmVzaXplVGV4dEFycmF5KF9jdXJyZW50T2Zmc2V0KTsKLQkgICAgCi0JICAgIF9maXJzdEF0dHJpYnV0ZU5vZGUgPSBfY3VycmVudE5vZGU7Ci0JICAgIHNoaWZ0QXR0cmlidXRlcyhfY3VycmVudE5vZGUpOwotCSAgICByZXNpemVBcnJheXMoX2N1cnJlbnROb2RlICsgX2N1cnJlbnRBdHRyaWJ1dGVOb2RlLCBfY3VycmVudE5vZGUpOwotCSAgICBhcHBlbmRBdHRyaWJ1dGVzKCk7Ci0JICAgIF90cmVlTm9kZUxpbWl0ID0gX2N1cnJlbnROb2RlOwotCi0JICAgIC8vIEZpbGwgdGhlIF9uYW1lc3BhY2VbXSBhbmQgX3VyaUFycmF5W10gYXJyYXkKLQkgICAgX25hbWVzcGFjZSA9IG5ldyBzaG9ydFtuYW1lc1NpemVdOwotCSAgICBfdXJpQXJyYXkgPSBuZXcgU3RyaW5nW191cmlDb3VudF07Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpPG5hbWVzU2l6ZTsgaSsrKSB7Ci0JCWZpbmFsIFN0cmluZyBxbmFtZSA9IF9uYW1lc0FycmF5W2ldOwotCQlmaW5hbCBpbnQgY29sID0gX25hbWVzQXJyYXlbaV0ubGFzdEluZGV4T2YoJzonKTsKLQkJLy8gRWxlbWVudHMvYXR0cmlidXRlcyB3aXRoIHRoZSB4bWwgcHJlZml4IGFyZSBub3QgaW4gYSBOUwotCQlpZiAoKCFxbmFtZS5zdGFydHNXaXRoKFhNTF9TVFJJTkcpKSAmJiAoY29sID4gLTEpKSB7Ci0JCSAgICBmaW5hbCBTdHJpbmcgdXJpID0gX25hbWVzQXJyYXlbaV0uc3Vic3RyaW5nKDAsIGNvbCk7Ci0JCSAgICBmaW5hbCBJbnRlZ2VyIGlkeCA9IChJbnRlZ2VyKV9uc0luZGV4LmdldCh1cmkpOwotCQkgICAgX25hbWVzcGFjZVtpXSA9IGlkeC5zaG9ydFZhbHVlKCk7Ci0JCSAgICBfdXJpQXJyYXlbaWR4LmludFZhbHVlKCldID0gdXJpOwotCQl9Ci0JICAgIH0KLQotCSAgICBfcHJlZml4QXJyYXkgPSBuZXcgU3RyaW5nW19wcmVmaXhDb3VudF07Ci0JICAgIEVudW1lcmF0aW9uIHAgPSBfbnNQcmVmaXhlcy5rZXlzKCk7Ci0JICAgIHdoaWxlIChwLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCWZpbmFsIFN0cmluZyBwcmVmaXggPSAoU3RyaW5nKXAubmV4dEVsZW1lbnQoKTsKLQkJZmluYWwgU3RhY2sgc3RhY2sgPSAoU3RhY2spX25zUHJlZml4ZXMuZ2V0KHByZWZpeCk7Ci0JCWZpbmFsIEludGVnZXIgSSA9IChJbnRlZ2VyKXN0YWNrLmVsZW1lbnRBdCgwKTsKLQkJX3ByZWZpeEFycmF5W0kuc2hvcnRWYWx1ZSgpXSA9IHByZWZpeDsKLQkgICAgfQotCX0KLQkKLQkvKioKLQkgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQuCi0JICovCi0JcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsCi0JCQkJIFN0cmluZyBxbmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQotCSAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotCSAgICBtYWtlVGV4dE5vZGUoZmFsc2UpOwotCi0JICAgIC8vIEdldCBub2RlIGluZGV4IGFuZCBzZXR1cCBwYXJlbnQvY2hpbGQgcmVmZXJlbmNlcwotCSAgICBmaW5hbCBpbnQgbm9kZSA9IG5leHROb2RlKCk7Ci0JICAgIGxpbmtDaGlsZHJlbihub2RlKTsKLQkgICAgX3BhcmVudFN0YWNrWysrX3NwXSA9IG5vZGU7Ci0KLQkgICAgZmluYWwgaW50IGNvdW50ID0gYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsKLQotCSAgICAvLyBQcm9jZXNzIGF0dHJpYnV0ZSBsaXN0IGFuZCBjcmVhdGUgYXR0ciBub2RlcwotCSAgICBpZiAoY291bnQgPiAwKSB7Ci0JCWludCBhdHRyID0gX2N1cnJlbnRBdHRyaWJ1dGVOb2RlICsgMTsKLQkJX2xlbmd0aE9yQXR0cltub2RlXSA9IGF0dHI7Ci0JCWZvciAoaW50IGkgPSAwOyBpPGNvdW50OyBpKyspIHsKLQkJICAgIGF0dHIgPSBtYWtlQXR0cmlidXRlTm9kZShub2RlLCBhdHRyaWJ1dGVzLCBpKTsKLQkJICAgIF9uZXh0U2libGluZzJbYXR0cl0gPSBhdHRyICsgMTsKLQkJfQotCQlfbmV4dFNpYmxpbmcyW2F0dHJdID0gRE9NLk5VTEw7Ci0JICAgIH0KLQkgICAgLy8gVGhlIGVsZW1lbnQgaGFzIG5vIGF0dHJpYnV0ZXMKLQkgICAgZWxzZSB7Ci0JCV9sZW5ndGhPckF0dHJbbm9kZV0gPSBET00uTlVMTDsKLQkgICAgfQkgICAgCi0JICAgIAotCSAgICBmaW5hbCBpbnQgY29sID0gcW5hbWUubGFzdEluZGV4T2YoJzonKTsKLQotCSAgICAvLyBBc3NpZ24gYW4gaW50ZXJuYWwgdHlwZSB0byB0aGlzIGVsZW1lbnQgKG1heSBleGlzdCkKLQkgICAgaWYgKCh1cmkgIT0gbnVsbCkgJiYgKGxvY2FsTmFtZS5sZW5ndGgoKSA+IDApKQotCQlfdHlwZVtub2RlXSA9IG1ha2VFbGVtZW50Tm9kZSh1cmksIGxvY2FsTmFtZSk7Ci0JICAgIGVsc2UKLQkJX3R5cGVbbm9kZV0gPSBtYWtlRWxlbWVudE5vZGUocW5hbWUsIGNvbCk7Ci0KLQkgICAgLy8gQXNzaWduIGFuIGludGVybmFsIHR5cGUgdG8gdGhlIGVsZW1lbnQncyBwcmVmaXggKG1heSBleGlzdCkKLQkgICAgaWYgKGNvbCA+IC0xKSB7Ci0JCV9wcmVmaXhbbm9kZV0gPSByZWdpc3RlclByZWZpeChxbmFtZS5zdWJzdHJpbmcoMCwgY29sKSk7Ci0JICAgIH0KLQl9Ci0JCi0JLyoqCi0JICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotCSAqLwotCXB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwKLQkJCSAgICAgICBTdHJpbmcgcW5hbWUpIHsKLQkgICAgbWFrZVRleHROb2RlKGZhbHNlKTsKLQkgICAgLy8gUmV2ZXJ0IHRvIHN0cmlwL3ByZXNlcnZlLXNwYWNlIHNldHRpbmcgZnJvbSBiZWZvcmUgdGhpcyBlbGVtZW50Ci0JICAgIHhtbFNwYWNlUmV2ZXJ0KF9wYXJlbnRTdGFja1tfc3BdKTsKLQkgICAgX3ByZXZpb3VzU2libGluZ1N0YWNrW19zcC0tXSA9IDA7Ci0JfQotCi0JLyoqCi0JICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotCSAqLwotCXB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLQkgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0KLQkgICAgbWFrZVRleHROb2RlKGZhbHNlKTsKLQotCSAgICBmaW5hbCBpbnQgbm9kZSA9IG5leHROb2RlKCk7Ci0JICAgIF90eXBlW25vZGVdID0gUFJPQ0VTU0lOR19JTlNUUlVDVElPTjsKLQkgICAgbGlua0NoaWxkcmVuKG5vZGUpOwotCSAgICBjaGFyYWN0ZXJzKHRhcmdldCk7Ci0JICAgIGNoYXJhY3RlcnMoIiAiKTsKLQkgICAgY2hhcmFjdGVycyhkYXRhKTsKLQkgICAgc3RvcmVUZXh0UmVmKG5vZGUpOwotCX0KLQotCS8qKgotCSAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQKLQkgKiBjb250ZW50LiBTaW1pbGFyIHRvIGNoYXJhY3RlcnMoY2hhcltdLCBpbnQsIGludCkuCi0JICovCi0JcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgewotCSAgICBpZiAoX2N1cnJlbnRPZmZzZXQgKyBsZW5ndGggPiBfdGV4dC5sZW5ndGgpIHsKLQkJcmVzaXplVGV4dEFycmF5KF90ZXh0Lmxlbmd0aCAqIDIpOwotCSAgICB9Ci0JICAgIFN5c3RlbS5hcnJheWNvcHkoY2gsIHN0YXJ0LCBfdGV4dCwgX2N1cnJlbnRPZmZzZXQsIGxlbmd0aCk7Ci0JICAgIF9jdXJyZW50T2Zmc2V0ICs9IGxlbmd0aDsKLQkgICAgbWFrZVRleHROb2RlKHRydWUpOwotCX0KLQotCS8qKgotCSAqIFNBWDI6IFJlY2VpdmUgYW4gb2JqZWN0IGZvciBsb2NhdGluZyB0aGUgb3JpZ2luIG9mIFNBWCBkb2N1bWVudAotCSAqIGV2ZW50cy4gCi0JICovCi0JcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewotCSAgICAvLyBOb3QgaGFuZGxlZAotCX0KLQotCS8qKgotCSAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0JICovCi0JcHVibGljIHZvaWQgc2tpcHBlZEVudGl0eShTdHJpbmcgbmFtZSkgewotCSAgICAvLyBOb3QgaGFuZGxlZCAKLQl9Ci0KLQkvKioKLQkgKiBTQVgyOiBCZWdpbiB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIE5hbWVzcGFjZSBtYXBwaW5nLgotCSAqLwotCXB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB7Ci0JICAgIC8vIEdldCB0aGUgc3RhY2sgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbmFtZXNwYWNlIHByZWZpeAotCSAgICBTdGFjayBzdGFjayA9IChTdGFjaylfbnNQcmVmaXhlcy5nZXQocHJlZml4KTsKLQkgICAgaWYgKHN0YWNrID09IG51bGwpIHsKLQkJc3RhY2sgPSBuZXcgU3RhY2soKTsKLQkJc3RhY2sucHVzaChuZXcgSW50ZWdlcihfcHJlZml4Q291bnQrKykpOwotCQlfbnNQcmVmaXhlcy5wdXQocHJlZml4LCBzdGFjayk7Ci0JICAgIH0KLQotCSAgICAvLyBDaGVjayBpZiB0aGUgVVJJIGFscmVhZHkgZXhpc3RzIGJlZm9yZSBwdXNoaW5nIG9uIHN0YWNrCi0JICAgIGlmIChfbnNJbmRleC5nZXQodXJpKSA9PSBudWxsKSB7Ci0JCV9uc0luZGV4LnB1dCh1cmksIG5ldyBJbnRlZ2VyKF91cmlDb3VudCsrKSk7Ci0JICAgIH0KLQkgICAgc3RhY2sucHVzaCh1cmkpOwotCX0KLQotCS8qKgotCSAqIFNBWDI6IEVuZCB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIE5hbWVzcGFjZSBtYXBwaW5nLgotCSAqLwotCXB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgewotCSAgICAvLyBHZXQgdGhlIHN0YWNrIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5hbWVzcGFjZSBwcmVmaXgKLQkgICAgZmluYWwgU3RhY2sgc3RhY2sgPSAoU3RhY2spX25zUHJlZml4ZXMuZ2V0KHByZWZpeCk7Ci0JICAgIGlmICgoc3RhY2sgIT0gbnVsbCkgJiYgKCFzdGFjay5lbXB0eSgpKSkgc3RhY2sucG9wKCk7Ci0JfQotCi0JLyoqCi0JICogU0FYMjogUmVwb3J0IGFuIFhNTCBjb21tZW50IGFueXdoZXJlIGluIHRoZSBkb2N1bWVudC4KLQkgKi8KLQlwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0JICAgIG1ha2VUZXh0Tm9kZShmYWxzZSk7Ci0JICAgIGlmIChfY3VycmVudE9mZnNldCArIGxlbmd0aCA+IF90ZXh0Lmxlbmd0aCkgewotCQlyZXNpemVUZXh0QXJyYXkoX3RleHQubGVuZ3RoICogMik7Ci0JICAgIH0KLQkgICAgU3lzdGVtLmFycmF5Y29weShjaCwgc3RhcnQsIF90ZXh0LCBfY3VycmVudE9mZnNldCwgbGVuZ3RoKTsKLQkgICAgX2N1cnJlbnRPZmZzZXQgKz0gbGVuZ3RoOwotCSAgICBmaW5hbCBpbnQgbm9kZSA9IG1ha2VUZXh0Tm9kZShmYWxzZSk7Ci0JICAgIF90eXBlW25vZGVdID0gQ09NTUVOVDsKLQl9Ci0KLQkvKioKLQkgKiBTQVgyOiBJZ25vcmVkIGV2ZW50cwotCSAqLwotCXB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB7fQotCXB1YmxpYyB2b2lkIGVuZENEQVRBKCkge30KLQlwdWJsaWMgdm9pZCBzdGFydERURChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHt9Ci0JcHVibGljIHZvaWQgZW5kRFREKCkge30KLQlwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkge30KLQlwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHt9Ci0KLQkvKioKLQkgKiBTaW1pbGFyIHRvIHRoZSBTQVgyIG1ldGhvZCBjaGFyYWN0ZXIoY2hhcltdLCBpbnQsIGludCksIGJ1dCB0aGlzCi0JICogbWV0aG9kIHRha2VzIGEgc3RyaW5nIGFzIGl0cyBvbmx5IHBhcmFtZXRlci4gVGhlIGVmZmVjdCBpcyB0aGUgc2FtZS4KLQkgKi8KLQlwcml2YXRlIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBTdHJpbmcgc3RyaW5nKSB7Ci0JICAgIGZpbmFsIGludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCk7Ci0JICAgIGlmIChfY3VycmVudE9mZnNldCArIGxlbmd0aCA+IF90ZXh0Lmxlbmd0aCkgewotCQlyZXNpemVUZXh0QXJyYXkoX3RleHQubGVuZ3RoICogMik7Ci0JICAgIH0KLQkgICAgc3RyaW5nLmdldENoYXJzKDAsIGxlbmd0aCwgX3RleHQsIF9jdXJyZW50T2Zmc2V0KTsKLQkgICAgX2N1cnJlbnRPZmZzZXQgKz0gbGVuZ3RoOwotCX0KLQotCXByaXZhdGUgdm9pZCByZXNpemVBcnJheXMoZmluYWwgaW50IG5ld1NpemUsIGZpbmFsIGludCBsZW5ndGgpIHsKLQkgICAgaWYgKG5ld1NpemUgPiBsZW5ndGgpIHsKLQkJLy8gUmVzaXplIHRoZSAnX3R5cGUnIGFycmF5Ci0JCWZpbmFsIHNob3J0W10gbmV3VHlwZSA9IG5ldyBzaG9ydFtuZXdTaXplXTsKLQkJU3lzdGVtLmFycmF5Y29weShfdHlwZSwgMCwgbmV3VHlwZSwgMCwgbGVuZ3RoKTsKLQkJX3R5cGUgPSBuZXdUeXBlOwotCi0JCS8vIFJlc2l6ZSB0aGUgJ19wYXJlbnQnIGFycmF5Ci0JCWZpbmFsIGludFtdIG5ld1BhcmVudCA9IG5ldyBpbnRbbmV3U2l6ZV07Ci0JCVN5c3RlbS5hcnJheWNvcHkoX3BhcmVudCwgMCwgbmV3UGFyZW50LCAwLCBsZW5ndGgpOwotCQlfcGFyZW50ID0gbmV3UGFyZW50OwotCi0JCS8vIFJlc2l6ZSB0aGUgJ19uZXh0U2libGluZycgYXJyYXkKLQkJZmluYWwgaW50W10gbmV3TmV4dFNpYmxpbmcgPSBuZXcgaW50W25ld1NpemVdOwotCQlTeXN0ZW0uYXJyYXljb3B5KF9uZXh0U2libGluZywgMCwgbmV3TmV4dFNpYmxpbmcsIDAsIGxlbmd0aCk7Ci0JCV9uZXh0U2libGluZyA9IG5ld05leHRTaWJsaW5nOwotCi0JCS8vIFJlc2l6ZSB0aGUgJ19vZmZzZXRPckNoaWxkJyBhcnJheQotCQlmaW5hbCBpbnRbXSBuZXdPZmZzZXRPckNoaWxkID0gbmV3IGludFtuZXdTaXplXTsKLQkJU3lzdGVtLmFycmF5Y29weShfb2Zmc2V0T3JDaGlsZCwgMCwgbmV3T2Zmc2V0T3JDaGlsZCwgMCxsZW5ndGgpOwotCQlfb2Zmc2V0T3JDaGlsZCA9IG5ld09mZnNldE9yQ2hpbGQ7Ci0KLQkJLy8gUmVzaXplIHRoZSAnX2xlbmd0aE9yQXR0cicgYXJyYXkKLQkJZmluYWwgaW50W10gbmV3TGVuZ3RoT3JBdHRyID0gbmV3IGludFtuZXdTaXplXTsKLQkJU3lzdGVtLmFycmF5Y29weShfbGVuZ3RoT3JBdHRyLCAwLCBuZXdMZW5ndGhPckF0dHIsIDAsIGxlbmd0aCk7Ci0JCV9sZW5ndGhPckF0dHIgPSBuZXdMZW5ndGhPckF0dHI7Ci0KLQkJLy8gUmVzaXplIHRoZSAnX3doaXRlc3BhY2UnIGFycmF5IChhIEJpdEFycmF5IGluc3RhbmNlKQotCQlfd2hpdGVzcGFjZS5yZXNpemUobmV3U2l6ZSk7Ci0KLQkJLy8gUmVzaXplIHRoZSAnX3ByZWZpeCcgYXJyYXkKLQkJZmluYWwgc2hvcnRbXSBuZXdQcmVmaXggPSBuZXcgc2hvcnRbbmV3U2l6ZV07Ci0JCVN5c3RlbS5hcnJheWNvcHkoX3ByZWZpeCwgMCwgbmV3UHJlZml4LCAwLCBsZW5ndGgpOwotCQlfcHJlZml4ID0gbmV3UHJlZml4OwotCSAgICB9Ci0JfQotCQotCXByaXZhdGUgdm9pZCByZXNpemVBcnJheXMyKGZpbmFsIGludCBuZXdTaXplLCBmaW5hbCBpbnQgbGVuZ3RoKSB7Ci0JICAgIGlmIChuZXdTaXplID4gbGVuZ3RoKSB7Ci0JCS8vIFJlc2l6ZSB0aGUgJ190eXBlMicgYXJyYXkgKGF0dHJpYnV0ZSB0eXBlcykKLQkJZmluYWwgc2hvcnRbXSBuZXdUeXBlID0gbmV3IHNob3J0W25ld1NpemVdOwotCQlTeXN0ZW0uYXJyYXljb3B5KF90eXBlMiwgMCwgbmV3VHlwZSwgMCwgbGVuZ3RoKTsKLQkJX3R5cGUyID0gbmV3VHlwZTsKLQotCQkvLyBSZXNpemUgdGhlICdfcGFyZW50MicgYXJyYXkgKGF0dHJpYnV0ZSBwYXJlbnQgZWxlbWVudHMpCi0JCWZpbmFsIGludFtdIG5ld1BhcmVudCA9IG5ldyBpbnRbbmV3U2l6ZV07Ci0JCVN5c3RlbS5hcnJheWNvcHkoX3BhcmVudDIsIDAsIG5ld1BhcmVudCwgMCwgbGVuZ3RoKTsKLQkJX3BhcmVudDIgPSBuZXdQYXJlbnQ7Ci0KLQkJLy8gUmVzaXplIHRoZSAnX25leHRTaWJsaW5nMicgYXJyYXkgKHlvdSBnZXQgdGhlIGlkZWEuLi4pCi0JCWZpbmFsIGludFtdIG5ld05leHRTaWJsaW5nID0gbmV3IGludFtuZXdTaXplXTsKLQkJU3lzdGVtLmFycmF5Y29weShfbmV4dFNpYmxpbmcyLCAwLCBuZXdOZXh0U2libGluZywgMCwgbGVuZ3RoKTsKLQkJX25leHRTaWJsaW5nMiA9IG5ld05leHRTaWJsaW5nOwotCi0JCS8vIFJlc2l6ZSB0aGUgJ19vZmZzZXQnIGFycmF5IChhdHRyaWJ1dGUgdmFsdWUgc3RhcnQpCi0JCWZpbmFsIGludFtdIG5ld09mZnNldCA9IG5ldyBpbnRbbmV3U2l6ZV07Ci0JCVN5c3RlbS5hcnJheWNvcHkoX29mZnNldCwgMCwgbmV3T2Zmc2V0LCAwLCBsZW5ndGgpOwotCQlfb2Zmc2V0ID0gbmV3T2Zmc2V0OwotCi0JCS8vIFJlc2l6ZSB0aGUgJ2xlbmd0aCcgYXJyYXkgKGF0dHJpYnV0ZSB2YWx1ZSBsZW5ndGgpCi0JCWZpbmFsIGludFtdIG5ld0xlbmd0aCA9IG5ldyBpbnRbbmV3U2l6ZV07Ci0JCVN5c3RlbS5hcnJheWNvcHkoX2xlbmd0aCwgMCwgbmV3TGVuZ3RoLCAwLCBsZW5ndGgpOwotCQlfbGVuZ3RoID0gbmV3TGVuZ3RoOwotCi0JCS8vIFJlc2l6ZSB0aGUgJ19wcmVmaXgyJyBhcnJheQotCQlmaW5hbCBzaG9ydFtdIG5ld1ByZWZpeCA9IG5ldyBzaG9ydFtuZXdTaXplXTsKLQkJU3lzdGVtLmFycmF5Y29weShfcHJlZml4MiwgMCwgbmV3UHJlZml4LCAwLCBsZW5ndGgpOwotCQlfcHJlZml4MiA9IG5ld1ByZWZpeDsKLQkgICAgfQotCX0KLQkKLQlwcml2YXRlIHZvaWQgc2hpZnRBdHRyaWJ1dGVzKGZpbmFsIGludCBzaGlmdCkgewotCSAgICBpbnQgaSA9IDA7Ci0JICAgIGludCBuZXh0ID0gMDsKLQkgICAgZmluYWwgaW50IGxpbWl0ID0gX2N1cnJlbnRBdHRyaWJ1dGVOb2RlOwotCSAgICBpbnQgbGFzdFBhcmVudCA9IC0xOwotCi0JICAgIGZvciAoaSA9IDA7IGkgPCBsaW1pdDsgaSsrKSB7Ci0JCWlmIChfcGFyZW50MltpXSAhPSBsYXN0UGFyZW50KSB7Ci0JCSAgICBsYXN0UGFyZW50ID0gX3BhcmVudDJbaV07Ci0JCSAgICBfbGVuZ3RoT3JBdHRyW2xhc3RQYXJlbnRdID0gaSArIHNoaWZ0OwotCQl9Ci0JCW5leHQgPSBfbmV4dFNpYmxpbmcyW2ldOwotCQlfbmV4dFNpYmxpbmcyW2ldID0gbmV4dCAhPSAwID8gbmV4dCArIHNoaWZ0IDogMDsKLQkgICAgfQotCX0KLQkKLQlwcml2YXRlIHZvaWQgYXBwZW5kQXR0cmlidXRlcygpIHsKLQkgICAgZmluYWwgaW50IGxlbiA9IF9jdXJyZW50QXR0cmlidXRlTm9kZTsKLQkgICAgaWYgKGxlbiA+IDApIHsKLQkJZmluYWwgaW50IGRzdCA9IF9jdXJyZW50Tm9kZTsKLQkJU3lzdGVtLmFycmF5Y29weShfdHlwZTIsICAgICAgICAgMCwgX3R5cGUsICAgICAgICAgIGRzdCwgbGVuKTsKLQkJU3lzdGVtLmFycmF5Y29weShfcHJlZml4MiwgICAgICAgMCwgX3ByZWZpeCwgICAgICAgIGRzdCwgbGVuKTsKLQkJU3lzdGVtLmFycmF5Y29weShfcGFyZW50MiwgICAgICAgMCwgX3BhcmVudCwgICAgICAgIGRzdCwgbGVuKTsKLQkJU3lzdGVtLmFycmF5Y29weShfbmV4dFNpYmxpbmcyLCAgMCwgX25leHRTaWJsaW5nLCAgIGRzdCwgbGVuKTsKLQkJU3lzdGVtLmFycmF5Y29weShfb2Zmc2V0LCAgICAgICAgMCwgX29mZnNldE9yQ2hpbGQsIGRzdCwgbGVuKTsKLQkJU3lzdGVtLmFycmF5Y29weShfbGVuZ3RoLCAgICAgICAgMCwgX2xlbmd0aE9yQXR0ciwgIGRzdCwgbGVuKTsKLQkgICAgfQotCX0KLQotICAgIH0gLy8gZW5kIG9mIERPTUJ1aWxkZXIKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9EVERNb25pdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRFRETW9uaXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5OGJmZjFiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9EVERNb25pdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTcgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRFRESGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5IYXNodGFibGU7Ci0KLWZpbmFsIHB1YmxpYyBjbGFzcyBEVERNb25pdG9yIGltcGxlbWVudHMgRFRESGFuZGxlciwgRGVjbEhhbmRsZXIgewotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICAvLyBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBpbmRleCB1c2VkIGZvciBJRCBhdHRyaWJ1dGVzCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIElEX0lOREVYX05BTUUgPSAiIyNpZCI7Ci0gICAgLy8gU3RvcmVzIHRoZSBuYW1lcyBvZiB0aGUgSUQgYXR0cmlidXRlcyBmb3IgdGhlIHZhcmlvdXMgZWxlbWVudCB0eXBlcwotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9pZEF0dHJpYnV0ZXMgPSBuZXcgSGFzaHRhYmxlKCk7IAotICAgIC8vIFN0b3JlcyBuYW1lcyBvZiBhbGwgdW5wYXJzZWQgZW50aXRpZXMKLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfdW5wYXJzZWRFbnRpdGllcyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAgIC8vIE5hbWUgb2YgRFREIGRlY2xhcmF0aW9uIGhhbmRsZXIgcHJvcGVydHkgb2YgYW4gWE1MUmVhZGVyIG9iamVjdAotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBERUNMX0hBTkRMRVJfUFJPUCA9Ci0JImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2RlY2xhcmF0aW9uLWhhbmRsZXIiOwotCi0gICAgLy8gRXJyb3IgbWVzc2FnZSB1c2VkIHdoZW4gdGhlIFNBWCBwYXJzZXIgZG9lcyBub3QgZ2VuZXJhdGUgRFREIGV2ZW50cwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBOT19EVERfU1VQUE9SVF9TVFIgPQotCSJZb3VyIFNBWCBwYXJzZXIgZG9lcyBub3QgaGFuZGxlIERURCBkZWNsYXJhdGlvbnMiOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgLSBkb2VzIG5vdGhpbmcKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRETW9uaXRvcigpIHsgfQotCi0gICAgLyoqCi0gICAgICogU2V0IGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYXMgdGhlIERURCBkZWNsYXJhdGlvbiBoYW5kbGVyIGZvcgotICAgICAqIGFuIFhNTFJlYWRlciBvYmplY3QgKHVzaW5nIHRoZSBzZXRQcm9wZXJ0eSgpIG1ldGhvZCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaGFuZGxlRFREKFhNTFJlYWRlciByZWFkZXIpIHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICByZWFkZXIuc2V0UHJvcGVydHkoREVDTF9IQU5ETEVSX1BST1AsIHRoaXMpOwotCSAgICByZWFkZXIuc2V0RFRESGFuZGxlcih0aGlzKTsKLQl9Ci0JY2F0Y2ggKFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkgewotCSAgICB0aHJvdyhuZXcgUnVudGltZUV4Y2VwdGlvbihOT19EVERfU1VQUE9SVF9TVFIpKTsKLQl9Ci0JY2F0Y2ggKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93KG5ldyBSdW50aW1lRXhjZXB0aW9uKE5PX0RURF9TVVBQT1JUX1NUUikpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vdGF0aW9uIGRlY2xhcmF0aW9uIGV2ZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbiB7IH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGFuIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbiBldmVudC4KLSAgICAgKiBUaGUgb25seSBtZXRob2QgaGVyZSB0aGF0IGRvZXMgbm90IGhhdmUgdG8gZG8gd2l0aCBJRCBhdHRyaWJ1dGVzLgotICAgICAqIFBhc3NlcyBuYW1lcyBvZiB1bnBhcnNlZCBlbnRpdGllcyB0byB0aGUgdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgdW5wYXJzZWRFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsCi0JCQkJICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb24pCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JaWYgKF91bnBhcnNlZEVudGl0aWVzLmNvbnRhaW5zS2V5KG5hbWUpID09IGZhbHNlKSB7Ci0JICAgIF91bnBhcnNlZEVudGl0aWVzLnB1dChuYW1lLCBzeXN0ZW1JZCk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBIYXNodGFibGUgZ2V0VW5wYXJzZWRFbnRpdHlVUklzKCkgewotCXJldHVybihfdW5wYXJzZWRFbnRpdGllcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU3RvcmVzIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZSBuYW1lIG9mIGFuIElEIGF0dHJpYnV0ZSBhbmQgdGhlCi0gICAgICogbmFtZSBvZiBlbGVtZW50IHRoYXQgbWF5IGNvbnRhaW4gaXQgIFN1Y2ggYW4gYXNzb2NpYXRpb24gd291bGQgYmUKLSAgICAgKiByZXByZXNlbnRlZCBpbiBhIERURCBhcyBpbjoKLSAgICAgKiAgICAgICAgICAgICAgPCFBVFRMSVNUIFBlcnNvbiBTU04gSUQgI1JFUVVJUkVEPgotICAgICAqIHdoZXJlICdQZXJzb24nIHdvdWxkIGJlIGVsZW10TmFtZSBhbmQgJ1NTTicgd291bGQgYmUgdGhlIElEIGF0dHJpYnV0ZQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZURlY2woU3RyaW5nIGVsZW1lbnQsIFN0cmluZyBhdHRyaWJ1dGUsIFN0cmluZyB0eXBlLAotCQkJICAgICAgU3RyaW5nW10gb3B0aW9ucywgU3RyaW5nIGRlZmF1bHRWYWx1ZSwKLQkJCSAgICAgIGJvb2xlYW4gZml4ZWQsIGJvb2xlYW4gcmVxdWlyZWQpIHsKLQlfaWRBdHRyaWJ1dGVzLnB1dChlbGVtZW50LCAiQCIrYXR0cmlidXRlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyIGV4dGVuc2lvbiBoYW5kbGVyIGZvciBEVEQgZGVjbGFyYXRpb24gZXZlbnRzCi0gICAgICogUmVwb3J0IGFuIGF0dHJpYnV0ZSB0eXBlIGRlY2xhcmF0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlRGVjbChTdHJpbmcgZWxlbWVudCwgU3RyaW5nIGF0dHJpYnV0ZSwgCi0JCQkgICAgICBTdHJpbmcgdHlwZSwgU3RyaW5nIGRlZmF1bHRWYWx1ZSwgU3RyaW5nIHZhbHVlKSB7Ci0JLy8gU3RvcmVzIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZSBuYW1lIG9mIGFuIElEIGF0dHJpYnV0ZSBhbmQgdGhlCi0JLy8gbmFtZSBvZiBlbGVtZW50IHRoYXQgbWF5IGNvbnRhaW4gaXQgIFN1Y2ggYW4gYXNzb2NpYXRpb24gd291bGQgYmUKLQkvLyByZXByZXNlbnRlZCBpbiBhIERURCBhcyBpbjoKLQkvLyAgICAgICAgICAgPCFBVFRMSVNUIFBlcnNvbiBTU04gSUQgI1JFUVVJUkVEPgotCS8vIHdoZXJlICdQZXJzb24nIHdvdWxkIGJlIGVsZW10TmFtZSBhbmQgJ1NTTicgd291bGQgYmUgdGhlIElEIGF0dHJpYnV0ZQotCV9pZEF0dHJpYnV0ZXMucHV0KGVsZW1lbnQsICJAIithdHRyaWJ1dGUpOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBTQVgyIGV4dGVuc2lvbiBoYW5kbGVyIGZvciBEVEQgZGVjbGFyYXRpb24gZXZlbnRzCi0gICAgICogUmVwb3J0IGFuIGVsZW1lbnQgdHlwZSBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbGVtZW50RGVjbChTdHJpbmcgZWxlbWVudCwgU3RyaW5nIG1vZGVsKSB7IH0KLSAgICAgICAgICAgICAgICAgCi0gICAgLyoqCi0gICAgICogU0FYMiBleHRlbnNpb24gaGFuZGxlciBmb3IgRFREIGRlY2xhcmF0aW9uIGV2ZW50cwotICAgICAqIFJlcG9ydCBhIHBhcnNlZCBleHRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgcGlkLCBTdHJpbmcgc2lkKSB7IH0KLSAgICAgICAgICAgICAgICAgCi0KLSAgICAvKioKLSAgICAgKiBTQVgyIGV4dGVuc2lvbiBoYW5kbGVyIGZvciBEVEQgZGVjbGFyYXRpb24gZXZlbnRzCi0gICAgICogUmVwb3J0IGFuIGludGVybmFsIGVudGl0eSBkZWNsYXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpbnRlcm5hbEVudGl0eURlY2woU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgeyB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXRyaWV2ZXMgdGhlIG5hbWUgb2YgdGhlIElEIGF0dHJpYnV0ZSBhc3NvY2lhdGVkIHdpdGggYW4gZWxlbWVudCB0eXBlCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZ2V0SWRBdHRyTmFtZShTdHJpbmcgZWxlbXROYW1lKSB7Ci0gICAgICAgIGZpbmFsIFN0cmluZyBpZEF0dHJOYW1lID0gKFN0cmluZylfaWRBdHRyaWJ1dGVzLmdldChlbGVtdE5hbWUpOwotICAgICAgICByZXR1cm4gKChpZEF0dHJOYW1lID09IG51bGwpID8gIiIgOiBpZEF0dHJOYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBMZXZlcmFnZXMgdGhlIEtleSBDbGFzcyB0byBpbXBsZW1lbnQgdGhlIFhTTFQgaWQoKSBmdW5jdGlvbi4KLSAgICAgKiBidWlsZElkSW5kZXggY3JlYXRlcyB0aGUgaW5kZXggKCMjaWQpIHRoYXQgS2V5IENsYXNzIHVzZXMuIAotICAgICAqIFRoZSBpbmRleCBjb250YWlucyB0aGUgbm9kZSBpbmRleCAoaW50KSBhbmQgdGhlIGlkIHZhbHVlIChTdHJpbmcpLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGJ1aWxkSWRJbmRleChET01JbXBsIGRvbSwgaW50IG1hc2ssCi0JCQkJICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCkgewotCi0JLy8gVGhlc2UgdmFyaWFibGVzIGFyZSBwdXQgdXAgaGVyZSBmb3Igc3BlZWQKLQlpbnQgbm9kZSwgYXR0ciwgdHlwZSwgdHlwZUNhY2hlOwotCi0JLy8gRG8gbm90aGluZyBpZiB0aGVyZSB3ZXJlIG5vIElEIGRlY2xhcmF0aW9ucyBpbiB0aGUgRFRECi0JaWYgKChfaWRBdHRyaWJ1dGVzID09IG51bGwpIHx8IChfaWRBdHRyaWJ1dGVzLmlzRW1wdHkoKSkpIHJldHVybjsKLQotCS8vIENvbnZlcnQgdGhlIF9pZEF0dHJpYnV0ZSBIYXNodGFibGUgc28gdGhhdCBpbnN0ZWFkIG9mIGNvbnRhaW5pbmcKLQkvLyBhbiBlbGVtZW50IG5hbWUgKFN0cmluZykgbWFwcGluZyB0byBhbiBJRCBhdHRyaWJ1dGUgbmFtZSAoU3RyaW5nKSwKLQkvLyBpdCBjb250YWlucyBwYWlycyBvZiBlbGVtZW50IHR5cGVzIChJbnRlZ2VyKSBtYXBwaW5nIHRvIElEIGF0dHJpYnV0ZQotCS8vIHR5cGVzIChJbnRlZ2VyKS4gVGhpcyBlbGltaW5hdGVzIHN0cmluZyBjb21wYXJpc29ucywgYW5kIG1ha2VzIGl0Ci0JLy8gcG9zc2libGUgZm9yIHVzIHRvIHRyYXZlcnNlIHRoZSBpbnB1dCBET00ganVzdCBvbmNlLgotCUVudW1lcmF0aW9uIGVsZW1lbnRzID0gX2lkQXR0cmlidXRlcy5rZXlzKCk7Ci0JaWYgKGVsZW1lbnRzLm5leHRFbGVtZW50KCkgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLQkgICAgSGFzaHRhYmxlIG5ld0F0dHJpYnV0ZXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JICAgIGVsZW1lbnRzID0gX2lkQXR0cmlidXRlcy5rZXlzKCk7Ci0JICAgIHdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQlTdHJpbmcgZWxlbWVudCA9IChTdHJpbmcpZWxlbWVudHMubmV4dEVsZW1lbnQoKTsKLQkJU3RyaW5nIGF0dHJpYnV0ZSA9IChTdHJpbmcpX2lkQXR0cmlidXRlcy5nZXQoZWxlbWVudCk7Ci0JCWludCBlbGVtVHlwZSA9IGRvbS5nZXRHZW5lcmFsaXplZFR5cGUoZWxlbWVudCk7Ci0JCWludCBhdHRyVHlwZSA9IGRvbS5nZXRHZW5lcmFsaXplZFR5cGUoYXR0cmlidXRlKTsKLQkJbmV3QXR0cmlidXRlcy5wdXQobmV3IEludGVnZXIoZWxlbVR5cGUpLCBuZXcgSW50ZWdlcihhdHRyVHlwZSkpOwotCSAgICB9Ci0JICAgIF9pZEF0dHJpYnV0ZXMgPSBuZXdBdHRyaWJ1dGVzOwotCX0KLQotCS8vIEdldCBhbGwgbm9kZXMgaW4gdGhlIERPTQotCWZpbmFsIE5vZGVJdGVyYXRvciBpdGVyID0gZG9tLmdldEF4aXNJdGVyYXRvcihBeGlzLkRFU0NFTkRBTlQpOwotCWl0ZXIuc2V0U3RhcnROb2RlKERPTS5ST09UTk9ERSk7Ci0KLQlJbnRlZ2VyIEUgPSBuZXcgSW50ZWdlcih0eXBlQ2FjaGUgPSAwKTsKLQlJbnRlZ2VyIEEgPSBudWxsOwotCi0Jd2hpbGUgKChub2RlID0gaXRlci5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkgICAgLy8gR2V0IHRoZSBub2RlIHR5cGUgb2YgdGhpcyBub2RlCi0JICAgIHR5cGUgPSBkb20uZ2V0VHlwZShub2RlKTsKLQkgICAgaWYgKHR5cGUgIT0gdHlwZUNhY2hlKSB7Ci0JCUUgPSBuZXcgSW50ZWdlcih0eXBlQ2FjaGUgPSB0eXBlKTsKLQkJQSA9IChJbnRlZ2VyKV9pZEF0dHJpYnV0ZXMuZ2V0KEUpOwotCSAgICB9Ci0KLQkgICAgLy8gU2VlIGlmIGl0IGhhcyBhIGRlZmluZWQgSUQgYXR0cmlidXRlIHR5cGUKLQkgICAgaWYgKEEgIT0gbnVsbCkgewotCQkvLyBPbmx5IHN0b3JlIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaWYgdGhlIGVsZW1lbnQgaGFzIHRoaXMgYXR0ci4KLQkJaWYgKChhdHRyID0gZG9tLmdldEF0dHJpYnV0ZU5vZGUoQS5pbnRWYWx1ZSgpLCBub2RlKSkgIT0gMCkgewotCQkgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gZG9tLmdldE5vZGVWYWx1ZShhdHRyKTsKLQkJICAgIHRyYW5zbGV0LmJ1aWxkS2V5SW5kZXgoSURfSU5ERVhfTkFNRSwgbWFza3xub2RlLCB2YWx1ZSk7Ci0JCX0KLQkgICAgfQotCX0KLSAgICB9Ci0KLX0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RvY3VtZW50Q2FjaGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Eb2N1bWVudENhY2hlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRjM2E0MjYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0RvY3VtZW50Q2FjaGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2NCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEubmV0LlVSTERlY29kZXI7Ci1pbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET01DYWNoZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRPTUltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRFRETW9uaXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQ29uc3RhbnRzOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRG9jdW1lbnRDYWNoZSBpbXBsZW1lbnRzIERPTUNhY2hlIHsKLQotICAgIHByaXZhdGUgaW50ICAgICAgIF9zaXplOwotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9yZWZlcmVuY2VzOwotICAgIHByaXZhdGUgU3RyaW5nW10gIF9VUklzOwotICAgIHByaXZhdGUgaW50ICAgICAgIF9jb3VudDsKLSAgICBwcml2YXRlIGludCAgICAgICBfY3VycmVudDsKLSAgICBwcml2YXRlIFNBWFBhcnNlciBfcGFyc2VyOwotICAgIHByaXZhdGUgWE1MUmVhZGVyIF9yZWFkZXI7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkVGUkVTSF9JTlRFUlZBTCA9IDEwMDA7Ci0KLSAgICAvKgotICAgICAqIElubmVyIGNsYXNzIGNvbnRhaW5pbmcgYSBET01JbXBsIG9iamVjdCBhbmQgRFREIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgY2xhc3MgQ2FjaGVkRG9jdW1lbnQgewotCQotCS8vIFN0YXRpc3RpY3MgZGF0YQotCXByaXZhdGUgbG9uZyBfZmlyc3RSZWZlcmVuY2VkOwotCXByaXZhdGUgbG9uZyBfbGFzdFJlZmVyZW5jZWQ7Ci0JcHJpdmF0ZSBsb25nIF9hY2Nlc3NDb3VudDsKLQlwcml2YXRlIGxvbmcgX2xhc3RNb2RpZmllZDsKLQlwcml2YXRlIGxvbmcgX2xhc3RDaGVja2VkOwotCXByaXZhdGUgbG9uZyBfYnVpbGRUaW1lOwotCi0JLy8gRE9NIGFuZCBEVEQgaGFuZGxlciByZWZlcmVuY2VzCi0JcHJpdmF0ZSBET01JbXBsICAgIF9kb20gPSBudWxsOwotCXByaXZhdGUgRFRETW9uaXRvciBfZHRkTW9uaXRvciA9IG51bGw7Ci0JCi0JLyoqCi0JICogQ29uc3RydWN0b3IgLSBsb2FkIGRvY3VtZW50IGFuZCBpbml0aWFsaXNlIHN0YXRpc3RpY3MKLQkgKi8KLQlwdWJsaWMgQ2FjaGVkRG9jdW1lbnQoU3RyaW5nIHVyaSkgewotCSAgICAvLyBJbml0aWFsaXNlIHN0YXRpc3RpY3MgdmFyaWFibGVzCi0JICAgIGZpbmFsIGxvbmcgc3RhbXAgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkgICAgX2ZpcnN0UmVmZXJlbmNlZCA9IHN0YW1wOwotCSAgICBfbGFzdFJlZmVyZW5jZWQgID0gc3RhbXA7Ci0JICAgIF9hY2Nlc3NDb3VudCAgICAgPSAwOwotCSAgICBsb2FkRG9jdW1lbnQodXJpKTsKLQotCSAgICBfYnVpbGRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFtcDsKLQl9Ci0KLQkvKioKLQkgKiBMb2FkcyB0aGUgZG9jdW1lbnQgYW5kIHVwZGF0ZXMgYnVpbGQtdGltZSAobGF0ZW5jeSkgc3RhdGlzdGljcwotCSAqLwotCXB1YmxpYyB2b2lkIGxvYWREb2N1bWVudChTdHJpbmcgdXJpKSB7Ci0KLQkgICAgX2RvbSA9IG5ldyBET01JbXBsKCk7Ci0JICAgIF9kdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLQotCSAgICB0cnkgewotCQlmaW5hbCBsb25nIHN0YW1wID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0KLQkJX3JlYWRlci5zZXRDb250ZW50SGFuZGxlcihfZG9tLmdldEJ1aWxkZXIoKSk7Ci0JCV9kdGRNb25pdG9yLmhhbmRsZURURChfcmVhZGVyKTsKLQkJX3JlYWRlci5wYXJzZSh1cmkpOwotCQlfZG9tLnNldERvY3VtZW50VVJJKHVyaSk7Ci0KLQkJLy8gVGhlIGJ1aWxkIHRpbWUgY2FuIGJlIHVzZWQgZm9yIHN0YXRpc3RpY3MgZm9yIGEgYmV0dGVyCi0JCS8vIHByaW9yaXR5IGFsZ29yaXRobSAoY3VycmVudGx5IHJvdW5kIHJvYmluKS4KLQkJZmluYWwgbG9uZyB0aGlzVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhbXA7Ci0JCWlmIChfYnVpbGRUaW1lID4gMCkKLQkJICAgIF9idWlsZFRpbWUgPSAoX2J1aWxkVGltZSArIHRoaXNUaW1lKSA+Pj4gMTsKLQkJZWxzZQotCQkgICAgX2J1aWxkVGltZSA9IHRoaXNUaW1lOwotCSAgICB9Ci0JICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotCQlfZG9tID0gbnVsbDsKLQkJX2R0ZE1vbml0b3IgPSBudWxsOwotCSAgICB9Ci0JfQotCi0JcHVibGljIERPTUltcGwgZ2V0RG9jdW1lbnQoKSAgICAgICB7IHJldHVybihfZG9tKTsgfQotCi0JcHVibGljIERURE1vbml0b3IgZ2V0RFRETW9uaXRvcigpICB7IHJldHVybihfZHRkTW9uaXRvcik7IH0KLQotCXB1YmxpYyBsb25nIGdldEZpcnN0UmVmZXJlbmNlZCgpICAgeyByZXR1cm4oX2ZpcnN0UmVmZXJlbmNlZCk7IH0KLQotCXB1YmxpYyBsb25nIGdldExhc3RSZWZlcmVuY2VkKCkgICAgeyByZXR1cm4oX2xhc3RSZWZlcmVuY2VkKTsgfQotCi0JcHVibGljIGxvbmcgZ2V0QWNjZXNzQ291bnQoKSAgICAgICB7IHJldHVybihfYWNjZXNzQ291bnQpOyB9Ci0KLQlwdWJsaWMgdm9pZCBpbmNBY2Nlc3NDb3VudCgpICAgICAgIHsgX2FjY2Vzc0NvdW50Kys7IH0KLQotCXB1YmxpYyBsb25nIGdldExhc3RNb2RpZmllZCgpICAgICAgeyByZXR1cm4oX2xhc3RNb2RpZmllZCk7IH0KLQotCXB1YmxpYyB2b2lkIHNldExhc3RNb2RpZmllZChsb25nIHQpeyBfbGFzdE1vZGlmaWVkID0gdDsgfQotCi0JcHVibGljIGxvbmcgZ2V0TGF0ZW5jeSgpICAgICAgICAgICB7IHJldHVybihfYnVpbGRUaW1lKTsgfQotCi0JcHVibGljIGxvbmcgZ2V0TGFzdENoZWNrZWQoKSAgICAgICB7IHJldHVybihfbGFzdENoZWNrZWQpOyB9Ci0JCi0JcHVibGljIHZvaWQgc2V0TGFzdENoZWNrZWQobG9uZyB0KSB7IF9sYXN0Q2hlY2tlZCA9IHQ7IH0KLQotCXB1YmxpYyBsb25nIGdldEVzdGltYXRlZFNpemUoKSB7Ci0JICAgIGlmIChfZG9tICE9IG51bGwpCi0JCXJldHVybihfZG9tLmdldFNpemUoKSA8PCA1KTsgLy8gPz8/Ci0JICAgIGVsc2UKLQkJcmV0dXJuKDApOwotCX0KLQotICAgIH0KLQotICAgIC8qKgotICAgICAqIERvY3VtZW50Q2FjaGUgY29uc3RydWN0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgRG9jdW1lbnRDYWNoZShpbnQgc2l6ZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JX2NvdW50ID0gMDsKLQlfY3VycmVudCA9IDA7Ci0JX3NpemUgID0gc2l6ZTsKLQlfcmVmZXJlbmNlcyA9IG5ldyBIYXNodGFibGUoX3NpemUrMik7Ci0JX1VSSXMgPSBuZXcgU3RyaW5nW19zaXplXTsKLQotCXRyeSB7Ci0JICAgIC8vIENyZWF0ZSBhIFNBWCBwYXJzZXIgYW5kIGdldCB0aGUgWE1MUmVhZGVyIG9iamVjdCBpdCB1c2VzCi0JICAgIGZpbmFsIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQkgICAgdHJ5IHsKLQkJZmFjdG9yeS5zZXRGZWF0dXJlKENvbnN0YW50cy5OQU1FU1BBQ0VfRkVBVFVSRSx0cnVlKTsKLQkgICAgfQotCSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQkgICAgfQotCSAgICBfcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLQkgICAgX3JlYWRlciA9IF9wYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0JfQotCWNhdGNoIChQYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLQkgICAgU3lzdGVtLmVyci5wcmludGxuKCJZb3VyIFNBWCBwYXJzZXIgaXMgbm90IGNvbmZpZ3VyZWQgY29ycmVjdGx5LiIpOwotCSAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHRpbWUtc3RhbXAgZm9yIGEgZG9jdW1lbnQncyBsYXN0IHVwZGF0ZQotICAgICAqLwotICAgIHByaXZhdGUgZmluYWwgbG9uZyBnZXRMYXN0TW9kaWZpZWQoU3RyaW5nIHVyaSkgewotCXRyeSB7Ci0JICAgIFVSTCB1cmwgPSBuZXcgVVJMKHVyaSk7Ci0JICAgIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOwotCSAgICBsb25nIHRpbWVzdGFtcCA9IGNvbm5lY3Rpb24uZ2V0TGFzdE1vZGlmaWVkKCk7Ci0JICAgIC8vIENoZWNrIGZvciBhICJmaWxlOiIgVVJJIChjb3VydGVzeSBvZiBCcmlhbiBFd2lucykKLQkgICAgaWYgKHRpbWVzdGFtcCA9PSAwKXsgLy8gZ2V0IDAgZm9yIGxvY2FsIFVSSQotCSAgICAgICAgaWYgKCJmaWxlIi5lcXVhbHModXJsLmdldFByb3RvY29sKCkpKXsKLQkgICAgICAgICAgICBGaWxlIGxvY2FsZmlsZSA9IG5ldyBGaWxlKFVSTERlY29kZXIuZGVjb2RlKHVybC5nZXRGaWxlKCkpKTsKLQkgICAgICAgICAgICB0aW1lc3RhbXAgPSBsb2NhbGZpbGUubGFzdE1vZGlmaWVkKCk7Ci0JICAgICAgICB9Ci0JICAgIH0KLQkgICAgcmV0dXJuKHRpbWVzdGFtcCk7Ci0JfQotCS8vIEJydXRhbCBoYW5kbGluZyBvZiBhbGwgZXhjZXB0aW9ucwotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICByZXR1cm4oU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKgotICAgICAqLwotICAgIHByaXZhdGUgQ2FjaGVkRG9jdW1lbnQgbG9va3VwRG9jdW1lbnQoU3RyaW5nIHVyaSkgewotCXJldHVybigoQ2FjaGVkRG9jdW1lbnQpX3JlZmVyZW5jZXMuZ2V0KHVyaSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBpbnNlcnREb2N1bWVudChTdHJpbmcgdXJpLCBDYWNoZWREb2N1bWVudCBkb2MpIHsKLQlpZiAoX2NvdW50IDwgX3NpemUpIHsKLQkgICAgLy8gSW5zZXJ0IG91dCBVUkkgaW4gY2lyY3VsYXIgYnVmZmVyCi0JICAgIF9VUklzW19jb3VudCsrXSA9IHVyaTsKLQkgICAgX2N1cnJlbnQgPSAwOwotCX0KLQllbHNlIHsKLQkgICAgLy8gUmVtb3ZlIG9sZGVzdCBVUkkgZnJvbSByZWZlcmVuY2UgSGFzaHRhYmxlCi0JICAgIF9yZWZlcmVuY2VzLnJlbW92ZShfVVJJc1tfY3VycmVudF0pOwotCSAgICAvLyBJbnNlcnQgb3VyIFVSSSBpbiBjaXJjdWxhciBidWZmZXIKLQkgICAgX1VSSXNbX2N1cnJlbnRdID0gdXJpOwotCSAgICBpZiAoKytfY3VycmVudCA+PSBfc2l6ZSkgX2N1cnJlbnQgPSAwOwotCX0KLQlfcmVmZXJlbmNlcy5wdXQodXJpLCBkb2MpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqCi0gICAgICovCi0gICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCByZXBsYWNlRG9jdW1lbnQoU3RyaW5nIHVyaSwgQ2FjaGVkRG9jdW1lbnQgZG9jKSB7Ci0JQ2FjaGVkRG9jdW1lbnQgb2xkID0gKENhY2hlZERvY3VtZW50KV9yZWZlcmVuY2VzLmdldCh1cmkpOwotCWlmIChkb2MgPT0gbnVsbCkKLQkgICAgaW5zZXJ0RG9jdW1lbnQodXJpLCBkb2MpOwotCWVsc2UKLQkgICAgX3JlZmVyZW5jZXMucHV0KHVyaSwgZG9jKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZG9jdW1lbnQgZWl0aGVyIGJ5IGZpbmRpbmcgaXQgaW4gdGhlIGNhY2hlIG9yCi0gICAgICogZG93bmxvYWRpbmcgaXQgYW5kIHB1dHRpbmcgaXQgaW4gdGhlIGNhY2hlLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBET01JbXBsIHJldHJpZXZlRG9jdW1lbnQoU3RyaW5nIHVyaSwgaW50IG1hc2ssIFRyYW5zbGV0IHRycykgewotCUNhY2hlZERvY3VtZW50IGRvYzsKLQotCS8vIFRyeSB0byBnZXQgdGhlIGRvY3VtZW50IGZyb20gdGhlIGNhY2hlIGZpcnN0Ci0JaWYgKChkb2MgPSBsb29rdXBEb2N1bWVudCh1cmkpKSA9PSBudWxsKSB7Ci0JICAgIGRvYyA9IG5ldyBDYWNoZWREb2N1bWVudCh1cmkpOwotCSAgICBpZiAoZG9jID09IG51bGwpIHJldHVybiBudWxsOyAvLyBiZXR0ZXIgZXJyb3IgaGFuZGxpbmcgbmVlZGVkISEhCi0JICAgIGRvYy5zZXRMYXN0TW9kaWZpZWQoZ2V0TGFzdE1vZGlmaWVkKHVyaSkpOwotCSAgICBpbnNlcnREb2N1bWVudCh1cmksIGRvYyk7Ci0JfQotCS8vIElmIHRoZSBkb2N1bWVudCBpcyBpbiB0aGUgY2FjaGUgd2UgbXVzdCBjaGVjayBpZiBpdCBpcyBzdGlsbCB2YWxpZAotCWVsc2UgewotCSAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCSAgICBsb25nIGNoayA9IGRvYy5nZXRMYXN0Q2hlY2tlZCgpOwotCSAgICBkb2Muc2V0TGFzdENoZWNrZWQobm93KTsKLQkgICAgLy8gSGFzIHRoZSBtb2RpZmljYXRpb24gdGltZSBmb3IgdGhpcyBmaWxlIGJlZW4gY2hlY2tlZCBsYXRlbHk/Ci0JICAgIGlmIChub3cgPiAoY2hrICsgUkVGUkVTSF9JTlRFUlZBTCkpIHsKLQkJZG9jLnNldExhc3RDaGVja2VkKG5vdyk7Ci0JCWxvbmcgbGFzdCA9IGdldExhc3RNb2RpZmllZCh1cmkpOwotCQkvLyBSZWxvYWQgZG9jdW1lbnQgaWYgaXQgaGFzIGJlZW4gbW9kaWZpZWQgc2luY2UgbGFzdCBkb3dubG9hZAotCQlpZiAobGFzdCA+IGRvYy5nZXRMYXN0TW9kaWZpZWQoKSkgewotCQkgICAgZG9jID0gbmV3IENhY2hlZERvY3VtZW50KHVyaSk7Ci0JCSAgICBpZiAoZG9jID09IG51bGwpIHJldHVybiBudWxsOwotCQkgICAgZG9jLnNldExhc3RNb2RpZmllZChnZXRMYXN0TW9kaWZpZWQodXJpKSk7Ci0JCSAgICByZXBsYWNlRG9jdW1lbnQodXJpLCBkb2MpOwotCQl9Ci0JICAgIH0KLQkgICAgCi0JfQotCi0JLy8gR2V0IHRoZSByZWZlcmVuY2VzIHRvIHRoZSBhY3R1YWwgRE9NIGFuZCBEVEQgaGFuZGxlcgotCWZpbmFsIERPTUltcGwgICAgZG9tID0gZG9jLmdldERvY3VtZW50KCk7Ci0JZmluYWwgRFRETW9uaXRvciBkdGQgPSBkb2MuZ2V0RFRETW9uaXRvcigpOwotCi0JLy8gVGhlIGRvbSByZWZlcmVuY2UgbWF5IGJlIG51bGwgaWYgdGhlIFVSTCBwb2ludGVkIHRvIGEKLQkvLyBub24tZXhpc3RpbmcgZG9jdW1lbnQKLQlpZiAoZG9tID09IG51bGwpIHJldHVybiBudWxsOwotCi0JZG9jLmluY0FjY2Vzc0NvdW50KCk7IC8vIEZvciBzdGF0aXN0aWNzCi0KLQlmaW5hbCBBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0ID0gKEFic3RyYWN0VHJhbnNsZXQpdHJzOwotCi0JLy8gU2V0IG1pbmltdW0gbmVlZGVkIHNpemUgZm9yIGtleS9pZCBpbmRpY2VzIGluIHRoZSB0cmFuc2xldAotCXRyYW5zbGV0LnNldEluZGV4U2l6ZShkb20uZ2V0U2l6ZSgpKTsKLQkvLyBDcmVhdGUgaW5kZXggZm9yIGFueSBJRCBhdHRyaWJ1dGVzIGRlZmluZWQgaW4gdGhlIGRvY3VtZW50IERURAotCWR0ZC5idWlsZElkSW5kZXgoZG9tLCBtYXNrLCB0cmFuc2xldCk7Ci0JLy8gUGFzcyBhbGwgdW5wYXJzZWQgZW50aXRpZXMgdG8gdGhlIHRyYW5zbGV0Ci0JdHJhbnNsZXQuc2V0VW5wYXJzZWRFbnRpdHlVUklzKGR0ZC5nZXRVbnBhcnNlZEVudGl0eVVSSXMoKSk7Ci0KLQlyZXR1cm4oZG9jLmdldERvY3VtZW50KCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE91dHB1dHMgdGhlIGNhY2hlIHN0YXRpc3RpY3MKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBnZXRTdGF0aXN0aWNzKFByaW50V3JpdGVyIG91dCkgewotCW91dC5wcmludGxuKCI8aDI+RE9NIGNhY2hlIHN0YXRpc3RpY3M8L2gyPjxjZW50ZXI+PHRhYmxlIGJvcmRlcj1cIjJcIj4iKwotCQkgICAgIjx0cj48dGQ+PGI+RG9jdW1lbnQgVVJJPC9iPjwvdGQ+IisKLQkJICAgICI8dGQ+PGNlbnRlcj48Yj5CdWlsZCB0aW1lPC9iPjwvY2VudGVyPjwvdGQ+IisKLQkJICAgICI8dGQ+PGNlbnRlcj48Yj5BY2Nlc3MgY291bnQ8L2I+PC9jZW50ZXI+PC90ZD4iKwotCQkgICAgIjx0ZD48Y2VudGVyPjxiPkxhc3QgYWNjZXNzZWQ8L2I+PC9jZW50ZXI+PC90ZD4iKwotCQkgICAgIjx0ZD48Y2VudGVyPjxiPkxhc3QgbW9kaWZpZWQ8L2I+PC9jZW50ZXI+PC90ZD48L3RyPiIpOwotCi0JZm9yIChpbnQgaT0wOyBpPF9jb3VudDsgaSsrKSB7Ci0JICAgIENhY2hlZERvY3VtZW50IGRvYyA9IChDYWNoZWREb2N1bWVudClfcmVmZXJlbmNlcy5nZXQoX1VSSXNbaV0pOwotCSAgICBvdXQucHJpbnQoIjx0cj48dGQ+PGEgaHJlZj1cIiIrX1VSSXNbaV0rIlwiPiIrCi0JCSAgICAgICI8Zm9udCBzaXplPS0xPiIrX1VSSXNbaV0rIjwvZm9udD48L2E+PC90ZD4iKTsKLQkgICAgb3V0LnByaW50KCI8dGQ+PGNlbnRlcj4iK2RvYy5nZXRMYXRlbmN5KCkrIm1zPC9jZW50ZXI+PC90ZD4iKTsKLQkgICAgb3V0LnByaW50KCI8dGQ+PGNlbnRlcj4iK2RvYy5nZXRBY2Nlc3NDb3VudCgpKyI8L2NlbnRlcj48L3RkPiIpOwotCSAgICBvdXQucHJpbnQoIjx0ZD48Y2VudGVyPiIrKG5ldyBEYXRlKGRvYy5nZXRMYXN0UmVmZXJlbmNlZCgpKSkrCi0JCSAgICAgICI8L2NlbnRlcj48L3RkPiIpOwotCSAgICBvdXQucHJpbnQoIjx0ZD48Y2VudGVyPiIrKG5ldyBEYXRlKGRvYy5nZXRMYXN0TW9kaWZpZWQoKSkpKwotCQkgICAgICAiPC9jZW50ZXI+PC90ZD4iKTsKLQkgICAgb3V0LnByaW50bG4oIjwvdHI+Iik7Ci0JfQotCi0Jb3V0LnByaW50bG4oIjwvdGFibGU+PC9jZW50ZXI+Iik7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0R1cEZpbHRlckl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRHVwRmlsdGVySXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTZhMGE0YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRHVwRmlsdGVySXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4NiArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyIAotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLQotcHVibGljIGZpbmFsIGNsYXNzIER1cEZpbHRlckl0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgSU5JVF9EQVRBX1NJWkUgPSAxNjsKLQotICAgIHByaXZhdGUgZmluYWwgTm9kZUl0ZXJhdG9yIF9zb3VyY2U7IC8vIHRoZSBzb3VyY2UgaXRlcmF0b3IKLSAgICBwcml2YXRlIGludFtdIF9kYXRhID0gbnVsbDsgICAgICAgICAvLyBjYWNoZWQgbm9kZXMgZnJvbSB0aGUgc291cmNlCi0gICAgcHJpdmF0ZSBpbnQgX2xhc3QgPSAwOyAgICAgICAgICAgICAgLy8gdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIGl0ZXJhdG9yCi0gICAgcHJpdmF0ZSBpbnQgX2N1cnJlbnQgPSAwOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyBkdXBsaWNhdGUgZmlsdGVyIGl0ZXJhdG9yIGJhc2VkIG9uIGFuIGV4aXN0aW5nIGl0ZXJhdG9yLgotICAgICAqIFRoaXMgaXRlcmF0b3Igc2hvdWxkIGJlIHVzZWQgd2l0aCB1bmlvbiBleHByZXNzaW9ucyBhbmQgb3RoZXIgY29tcGxleAotICAgICAqIGl0ZXJhdG9yIGNvbWJpbmF0aW9ucyAobGlrZSAnZ2V0IG1lIHRoZSBwYXJlbnRzIG9mIGFsbCBjaGlsZCBub2RlIGluCi0gICAgICogdGhlIGRvbScgc29ydCBvZiB0aGluZykuIFRoZSBpdGVyYXRvciBpcyBhbHNvIHVzZWQgdG8gY2FjaGUgbm9kZS1zZXRzCi0gICAgICogcmV0dXJuZWQgYnkgaWQoKSBhbmQga2V5KCkgaXRlcmF0b3JzLgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGl0ZXJhdG9yIHRoaXMgaXRlcmF0b3Igd2lsbCBnZXQgaXRzIG5vZGVzIGZyb20KLSAgICAgKi8KLSAgICBwdWJsaWMgRHVwRmlsdGVySXRlcmF0b3IoTm9kZUl0ZXJhdG9yIHNvdXJjZSkgewotCS8vIFNhdmUgYSByZWZlcmVuY2UgdG8gdGhlIHNvdXJjZSBpdGVyYXRvcgotCV9zb3VyY2UgPSBzb3VyY2U7Ci0KLQkvLyBDYWNoZSBjb250ZW50cyBvZiBpZCgpIG9yIGtleSgpIGluZGV4IHJpZ2h0IGF3YXkuIE5lY2Vzc2FyeSBmb3IKLQkvLyB1bmlvbiBleHByZXNzaW9ucyBjb250YWluaW5nIG11bHRpcGxlIGNhbGxzIHRvIHRoZSBzYW1lIGluZGV4LCBhbmQKLQkvLyBjb3JyZWN0IGFzIHdlbGwgc2luY2Ugc3RhcnQtbm9kZSBpcyBpcnJlbGV2YW50IGZvciBpZCgpL2tleSgpIGV4cnAuCi0JaWYgKHNvdXJjZSBpbnN0YW5jZW9mIEtleUluZGV4KSBzZXRTdGFydE5vZGUoRE9NLlJPT1ROT0RFKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhpcyBpdGVyYXRvciAtIGV4Y2x1ZGVzIGR1cGxpY2F0ZXMuCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGluIHRoaXMgaXRlcmF0b3IKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0JcmV0dXJuIF9jdXJyZW50IDwgX2xhc3QgPyBfZGF0YVtfY3VycmVudCsrXSA6IEVORDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHN0YXJ0IG5vZGUgZm9yIHRoaXMgaXRlcmF0b3IKLSAgICAgKiBAcGFyYW0gbm9kZSBUaGUgc3RhcnQgbm9kZQotICAgICAqIEByZXR1cm4gQSByZWZlcmVuY2UgdG8gdGhpcyBub2RlIGl0ZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQkvLyBLZXlJbmRleCBpdGVyYXRvcnMgYXJlIGFsd2F5cyByZWxhdGl2ZSB0byB0aGUgcm9vdCBub2RlLCBzbyB0aGVyZQotCS8vIGlzIG5ldmVyIGFueSBwb2ludCBpbiByZS1yZWFkaW5nIHRoZSBpdGVyYXRvciAoYW5kIHdlIFNIT1VMRCBOT1QpLgotCWlmICgoX3NvdXJjZSBpbnN0YW5jZW9mIEtleUluZGV4KSAmJiAoX2RhdGEgIT0gbnVsbCkpIHJldHVybiB0aGlzOwotCi0JLy8gSWYgdGhlIF9kYXRhIGFycmF5IGlzIHBvcHVsYXRlZCwgYW5kIHRoZSBjdXJyZW50IHN0YXJ0IG5vZGUgaXMKLQkvLyBlcXVhbCB0byB0aGUgbmV3IHN0YXJ0IG5vZGUsIHdlIGtub3cgd2UgYWxyZWFkeSBoYXZlIHdoYXQgd2UgbmVlZC4KLQlpZiAoKF9kYXRhID09IG51bGwpIHx8IChub2RlICE9IF9zdGFydE5vZGUpKSB7Ci0KLQkgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0JICAgIF9sYXN0ID0gMDsKLQkgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUobm9kZSk7Ci0JICAgIF9kYXRhID0gbmV3IGludFtJTklUX0RBVEFfU0laRV07Ci0KLQkgICAgLy8gR2F0aGVyIGFsbCBub2RlcyBmcm9tIHRoZSBzb3VyY2UgaXRlcmF0b3IsIGVsaW1pbmF0ZSBkdXBzCi0JICAgIHdoaWxlICgobm9kZSA9IF9zb3VyY2UubmV4dCgpKSAhPSBFTkQpIHsKLQkJaWYgKF9sYXN0ID09IF9kYXRhLmxlbmd0aCkgewotCQkgICAgaW50W10gbmV3QXJyYXkgPSBuZXcgaW50W19kYXRhLmxlbmd0aCAqIDJdOwotCQkgICAgU3lzdGVtLmFycmF5Y29weShfZGF0YSwgMCwgbmV3QXJyYXksIDAsIF9sYXN0KTsKLQkJICAgIF9kYXRhID0gbmV3QXJyYXk7Ci0JCX0KLQkJaWYgKCFpc0R1cChub2RlKSkgX2RhdGFbX2xhc3QrK10gPSBub2RlOwotCSAgICB9Ci0JfQotCi0JX2N1cnJlbnQgPSAwOyAgLy8gc2V0IHRvIGJlZ2lubmluZyAKLQlyZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDaGVjayBpZiBhIG5vZGUgaXMgYWxyZWFkeSBpbiB0aGUgX2RhdGEgYXJyYXkuIFRoZSBub2RlcyBzaG91bGQgYmUgaW4KLSAgICAgKiBkb2N1bWVudCBvcmRlciBvciByZXZlcnNlIGRvY3VtZW50IG9yZGVyLCBzbyB3ZSBtYXkgYmUgYWJsZSB0byB1c2UKLSAgICAgKiBiaW5hcnkgc2VhcmNoIGhlcmUuCi0gICAgICovCi0gICAgcHJpdmF0ZSBib29sZWFuIGlzRHVwKGludCBub2RlKSB7Ci0JYm9vbGVhbiByZXR2YWwgPSBmYWxzZTsKLQlpbnQgc2l6ZSA9IF9kYXRhLmxlbmd0aDsKLQlmb3IgKGludCBpPTA7IGk8c2l6ZTsgaSsrKSB7Ci0JICAgIGlmIChfZGF0YVtpXSA9PSBub2RlKSB7Ci0JCXJldHZhbCA9IHRydWU7IGJyZWFrOwotCSAgICB9Ci0JfQotCXJldHVybiByZXR2YWw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUgaXRlcmF0b3IuIFRoZSBwb3NpdGlvbiBpcyB3aXRoaW4gdGhlCi0gICAgICogbm9kZSBzZXQgY292ZXJlZCBieSB0aGlzIGl0ZXJhdG9yLCBub3Qgd2l0aGluIHRoZSBET00uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLQlyZXR1cm4gKF9jdXJyZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBub2RlIGluIHRoaXMgaXRlcmF0b3IuIFRoZSBpbnRlZ2VyCi0gICAgICogcmV0dXJuZWQgaXMgZXF1aXZhbGVudCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCXJldHVybiBfbGFzdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTYXZlcyB0aGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciAtIHNlZSBnb3RvTWFyaygpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQlfc291cmNlLnNldE1hcmsoKTsKLQlfbWFya2VkTm9kZSA9IF9jdXJyZW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc3RvcmVzIHRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIC0gc2VlIHNldE1hcmsoKQotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCV9zb3VyY2UuZ290b01hcmsoKTsKLQlfY3VycmVudCA9IF9tYXJrZWROb2RlOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0VtcHR5RmlsdGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRW1wdHlGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODg1MTFmMi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRW1wdHlGaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotcHVibGljIGZpbmFsIGNsYXNzIEVtcHR5RmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKLSAgICBwdWJsaWMgYm9vbGVhbiB0ZXN0KGludCBub2RlKSB7Ci0JcmV0dXJuIHRydWU7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0ZpbHRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0ZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OTU0ZTU5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9GaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotcHVibGljIGludGVyZmFjZSBGaWx0ZXIgewotICAgIHB1YmxpYyBib29sZWFuIHRlc3QoaW50IG5vZGUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0ZpbHRlckl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRmlsdGVySXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTQ4ZjcwYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRmlsdGVySXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRmlsdGVySXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLSAgICBwcml2YXRlIE5vZGVJdGVyYXRvciBfc291cmNlOwotICAgIHByaXZhdGUgZmluYWwgRmlsdGVyIF9maWx0ZXI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIF9pc1JldmVyc2U7Ci0JCi0gICAgcHVibGljIEZpbHRlckl0ZXJhdG9yKE5vZGVJdGVyYXRvciBzb3VyY2UsIEZpbHRlciBmaWx0ZXIpIHsKLQlfc291cmNlID0gc291cmNlOwotCV9maWx0ZXIgPSBmaWx0ZXI7Ci0JX2lzUmV2ZXJzZSA9IHNvdXJjZS5pc1JldmVyc2UoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0JcmV0dXJuIF9pc1JldmVyc2U7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQl0cnkgewotCSAgICBmaW5hbCBGaWx0ZXJJdGVyYXRvciBjbG9uZSA9IChGaWx0ZXJJdGVyYXRvcilzdXBlci5jbG9uZSgpOwotCSAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCSAgICBjbG9uZS5fc291cmNlID0gX3NvdXJjZS5jbG9uZUl0ZXJhdG9yKCk7Ci0JICAgIHJldHVybiBjbG9uZS5yZXNldCgpOwotCX0KLQljYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotCSAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKCJJdGVyYXRvciBjbG9uZSBub3Qgc3VwcG9ydGVkLiIpOyAKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHJlc2V0KCkgewotCV9zb3VyY2UucmVzZXQoKTsKLQlyZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0JaW50IG5vZGU7Ci0Jd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotCSAgICBpZiAoX2ZpbHRlci50ZXN0KG5vZGUpKSB7Ci0JCXJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotCSAgICB9Ci0JfQotCXJldHVybiBFTkQ7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkgICAgLy8gaXRlcmF0b3IgaXMgbm90IGEgY2xvbmUKLQkgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOyAKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQlfc291cmNlLnNldE1hcmsoKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQlfc291cmNlLmdvdG9NYXJrKCk7Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0ZpbHRlcmVkU3RlcEl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRmlsdGVyZWRTdGVwSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTNjYzM4NS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vRmlsdGVyZWRTdGVwSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzOCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQmFzaXNMaWJyYXJ5OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgRmlsdGVyZWRTdGVwSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLSAgICBwcml2YXRlIE5vZGVJdGVyYXRvciBfc291cmNlOwotICAgIHByaXZhdGUgTm9kZUl0ZXJhdG9yIF9pdGVyYXRvcjsKLSAgICBwcml2YXRlIGZpbmFsIEZpbHRlciBfZmlsdGVyOwotCQotICAgIHB1YmxpYyBGaWx0ZXJlZFN0ZXBJdGVyYXRvcihOb2RlSXRlcmF0b3Igc291cmNlLAotCQkJCU5vZGVJdGVyYXRvciBpdGVyYXRvciwKLQkJCQlGaWx0ZXIgZmlsdGVyKSB7Ci0JX3NvdXJjZSA9IHNvdXJjZTsKLQlfaXRlcmF0b3IgPSBpdGVyYXRvcjsKLQlfZmlsdGVyID0gZmlsdGVyOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQl0cnkgewotCSAgICBmaW5hbCBGaWx0ZXJlZFN0ZXBJdGVyYXRvciBjbG9uZSA9Ci0JCShGaWx0ZXJlZFN0ZXBJdGVyYXRvcilzdXBlci5jbG9uZSgpOwotCSAgICBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCSAgICBjbG9uZS5fc291cmNlID0gX3NvdXJjZS5jbG9uZUl0ZXJhdG9yKCk7Ci0JICAgIGNsb25lLl9pdGVyYXRvciA9IF9pdGVyYXRvci5jbG9uZUl0ZXJhdG9yKCkKLQkJLnNldFN0YXJ0Tm9kZShfc291cmNlLm5leHQoKSk7Ci0JICAgIHJldHVybiBjbG9uZS5yZXNldFBvc2l0aW9uKCk7Ci0JfQotCWNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkgICAgLy8gaXRlcmF0b3IgaXMgbm90IGEgY2xvbmUKLQkgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOwotCSAgICBfaXRlcmF0b3Iuc2V0U3RhcnROb2RlKF9zb3VyY2UubmV4dCgpKTsKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlfc291cmNlLnJlc2V0KCk7Ci0JX2l0ZXJhdG9yLnNldFN0YXJ0Tm9kZShfc291cmNlLm5leHQoKSk7Ci0JcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGludCBuZXh0KCkgewotCWZvciAoaW50IG5vZGU7OykgewotCSAgICB3aGlsZSAoKG5vZGUgPSBfaXRlcmF0b3IubmV4dCgpKSAhPSBFTkQpCi0JCWlmIChfZmlsdGVyLnRlc3Qobm9kZSkpIHsKLQkJICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotCQl9Ci0JICAgIC8vIGxvY2FsIGl0ZXJhdG9yIHJhbiBvdXQgb2Ygbm9kZXMKLQkgICAgLy8gdHJ5IHRvIGdldCBuZXcgc3RhcnQgbm9kZSBmcm9tIHNvdXJjZQotCSAgICBpZiAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgPT0gRU5EKQotCQlyZXR1cm4gRU5EOwotCSAgICBlbHNlCi0JCV9pdGVyYXRvci5zZXRTdGFydE5vZGUobm9kZSk7Ci0JfQotICAgIH0KLQkJCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQlfc291cmNlLnNldE1hcmsoKTsKLQlfaXRlcmF0b3Iuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCV9zb3VyY2UuZ290b01hcmsoKTsKLQlfaXRlcmF0b3IuZ290b01hcmsoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vS2V5SW5kZXguamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9LZXlJbmRleC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNmVmMzNlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9LZXlJbmRleC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjY1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuSGFzaHRhYmxlOwotCi1wdWJsaWMgY2xhc3MgS2V5SW5kZXggaW1wbGVtZW50cyBOb2RlSXRlcmF0b3IgewotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9pbmRleCA9IG5ldyBIYXNodGFibGUoKTsKLSAgICBwcml2YXRlIEJpdEFycmF5ICBfbm9kZXMgPSBudWxsOwotICAgIHByaXZhdGUgaW50ICAgICAgIF9wb3MgPSAwOwotICAgIHByaXZhdGUgaW50ICAgICAgIF9tYXJrID0gMDsKLSAgICBwcml2YXRlIGludCAgICAgICBfc2F2ZSA9IDA7Ci0gICAgcHJpdmF0ZSBpbnQgICAgICAgX3N0YXJ0ID0gMDsKLSAgICBwcml2YXRlIGludCAgICAgICBfYXJyYXlTaXplID0gMDsKLSAgICBwcml2YXRlIGludCAgICAgICBfbm9kZSA9IC0xOwotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhbiBpbmRleCBmb3IgYSBrZXkgZGVmaW5lZCBieSB4c2w6a2V5Ci0gICAgICovCi0gICAgcHVibGljIEtleUluZGV4KGludCBzaXplKSB7Ci0JX2FycmF5U2l6ZSA9IHNpemU7Ci0gICAgfQotIAotICAgIC8qKgotICAgICAqIEFkZHMgYSBub2RlIHRvIHRoZSBub2RlIGxpc3QgZm9yIGEgZ2l2ZW4gdmFsdWUuCi0gICAgICogVGhlIEJpdEFycmF5IG9iamVjdCBtYWtlcyBzdXJlIGR1cGxpY2F0ZSBub2RlcyBhcmUgZWxpbWluYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGQoT2JqZWN0IHZhbHVlLCBpbnQgbm9kZSkgewotCWlmICgoX25vZGVzID0gKEJpdEFycmF5KV9pbmRleC5nZXQodmFsdWUpKSA9PSBudWxsKSB7Ci0JICAgIF9ub2RlcyA9IG5ldyBCaXRBcnJheShfYXJyYXlTaXplKTsKLQkgICAgX25vZGVzLnNldE1hc2sobm9kZSAmIDB4ZmYwMDAwMDApOwotCSAgICBfaW5kZXgucHV0KHZhbHVlLF9ub2Rlcyk7Ci0JfQotCV9ub2Rlcy5zZXRCaXQobm9kZSAmIDB4MDBmZmZmZmYpOwotCi0JLyoKLQkgKiBUT0RPOiBBIGJpdCBhcnJheSBjYW4gY3VycmVudGx5IG9ubHkgaG9sZCBub2RlcyBmcm9tIG9uZSBET00uCi0JICogQW4gaW5kZXggd2lsbCB0aGVyZWZvcmUgb25seSByZXR1cm4gbm9kZXMgZnJvbSBhIHNpbmdsZSBkb2N1bWVudC4KLQkgKi8KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBNZXJnZSB0aGlzIG5vZGUgc2V0IHdpdGggbm9kZXMgZnJvbSBhbm90aGVyIGluZGV4Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgbWVyZ2UoS2V5SW5kZXggb3RoZXIpIHsKLQkvLyBPbmx5IG1lcmdlIGlmIG90aGVyIG5vZGUgc2V0IGlzIG5vdCBlbXB0eQotCWlmIChvdGhlciAhPSBudWxsKSB7Ci0JICAgIGlmIChvdGhlci5fbm9kZXMgIT0gbnVsbCkgewotCQkvLyBDcmVhdGUgbmV3IFZlY3RvciBmb3Igbm9kZXMgaWYgdGhpcyBzZXQgaXMgZW1wdHkKLQkJaWYgKF9ub2RlcyA9PSBudWxsKQotCQkgICAgX25vZGVzID0gb3RoZXIuX25vZGVzOwotCQllbHNlCi0JCSAgICBfbm9kZXMgPSBfbm9kZXMubWVyZ2Uob3RoZXIuX25vZGVzKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBieSB0aGUgY29kZSBnZW5lcmF0ZWQgYnkgdGhlIGlkKCkgZnVuY3Rpb24KLSAgICAgKiBwcmlvciB0byByZXR1cm5pbmcgdGhlIG5vZGUgaXRlcmF0b3IuIFRoZSBsb29rdXAgY29kZSBmb3Iga2V5KCkgYW5kCi0gICAgICogaWQoKSBkaWZmZXIgaW4gdGhlIHdheSB0aGUgbG9va3VwIHZhbHVlIGNhbiBiZSB3aGl0ZXNwYWNlIHNlcGFyYXRlZAotICAgICAqIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgaWQoKSBmdW5jdGlvbiwgYnV0IGEgc2luZ2xlIHN0cmluZyBmb3IgdGhlCi0gICAgICoga2V5KCkgZnVuY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgbG9va3VwSWQoT2JqZWN0IHZhbHVlKSB7Ci0JaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7Ci0JICAgIGZpbmFsIFN0cmluZyBzdHJpbmcgPSAoU3RyaW5nKXZhbHVlOwotCSAgICBpZiAoc3RyaW5nLmluZGV4T2YoJyAnKSA+IC0xKSB7Ci0JCVN0cmluZ1Rva2VuaXplciB2YWx1ZXMgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHN0cmluZyk7Ci0JCXdoaWxlICh2YWx1ZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJICAgIEJpdEFycmF5IG5vZGVzID0gKEJpdEFycmF5KV9pbmRleC5nZXQodmFsdWVzLm5leHRFbGVtZW50KCkpOwotCQkgICAgaWYgKG5vZGVzICE9IG51bGwpIHsKLQkJCWlmIChfbm9kZXMgPT0gbnVsbCkKLQkJCSAgICBfbm9kZXMgPSBub2RlczsKLQkJCWVsc2UKLQkJCSAgICBfbm9kZXMgPSBfbm9kZXMubWVyZ2Uobm9kZXMpOwotCQkgICAgfQotCQl9Ci0JCXJldHVybjsKLQkgICAgfQotCX0KLQlfbm9kZXMgPSAoQml0QXJyYXkpX2luZGV4LmdldCh2YWx1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYnkgdGhlIGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBrZXkoKSBmdW5jdGlvbgotICAgICAqIHByaW9yIHRvIHJldHVybmluZyB0aGUgbm9kZSBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBsb29rdXBLZXkoT2JqZWN0IHZhbHVlKSB7Ci0JX25vZGVzID0gKEJpdEFycmF5KV9pbmRleC5nZXQodmFsdWUpOwotICAgIH0KLQotICAgIC8qKiAKLSAgICAgKiBDYWxsZXJzIHNob3VsZCBub3QgY2FsbCBuZXh0KCkgYWZ0ZXIgaXQgcmV0dXJucyBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkgewotCWlmIChfbm9kZXMgPT0gbnVsbCkgcmV0dXJuKEVORCk7Ci0JaWYgKChfbm9kZSA9IF9ub2Rlcy5nZXROZXh0Qml0KCsrX25vZGUpKSA9PSBFTkQpIHJldHVybihFTkQpOwotCV9wb3MrKzsKLQlyZXR1cm4oX25vZGUgfCBfbm9kZXMuZ2V0TWFzaygpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGNvbnRhaW5zSUQoaW50IG5vZGUsIE9iamVjdCB2YWx1ZSkgeyAKLQlpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLQkgICAgZmluYWwgU3RyaW5nIHN0cmluZyA9IChTdHJpbmcpdmFsdWU7Ci0JICAgIGlmIChzdHJpbmcuaW5kZXhPZignICcpID4gLTEpIHsKLQkJU3RyaW5nVG9rZW5pemVyIHZhbHVlcyA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoc3RyaW5nKTsKLQkJd2hpbGUgKHZhbHVlcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkgICAgQml0QXJyYXkgbm9kZXMgPSAoQml0QXJyYXkpX2luZGV4LmdldCh2YWx1ZXMubmV4dEVsZW1lbnQoKSk7Ci0JCSAgICBpZiAoKG5vZGVzICE9IG51bGwpICYmIChub2Rlcy5nZXRCaXQobm9kZSkpKSByZXR1cm4oMSk7Ci0JCX0KLQkJcmV0dXJuKDApOwotCSAgICB9Ci0JfQotCi0JQml0QXJyYXkgbm9kZXMgPSAoQml0QXJyYXkpX2luZGV4LmdldCh2YWx1ZSk7Ci0JaWYgKChub2RlcyAhPSBudWxsKSAmJiAobm9kZXMuZ2V0Qml0KG5vZGUpKSkgcmV0dXJuKDEpOwotCXJldHVybigwKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGNvbnRhaW5zS2V5KGludCBub2RlLCBPYmplY3QgdmFsdWUpIHsgCi0JQml0QXJyYXkgbm9kZXMgPSAoQml0QXJyYXkpX2luZGV4LmdldCh2YWx1ZSk7Ci0JaWYgKChub2RlcyAhPSBudWxsKSAmJiAobm9kZXMuZ2V0Qml0KG5vZGUpKSkgcmV0dXJuKDEpOwotCXJldHVybigwKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IHN0YXJ0IG5vZGUuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlfcG9zID0gX3N0YXJ0OwotCV9ub2RlID0gX3N0YXJ0IC0gMTsKLQlyZXR1cm4odGhpcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCWlmIChfbm9kZXMgPT0gbnVsbCkKLQkgICAgcmV0dXJuKDApOwotCWVsc2UKLQkgICAgcmV0dXJuKF9ub2Rlcy5zaXplKCkpOyAvLyBUT0RPOiBjb3VudCBhY3R1YWwgbm9kZXMKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBub2RlIGluIHRoZSBzZXQuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLQlyZXR1cm4oX3Bvcyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVtZW1iZXJzIHRoZSBjdXJyZW50IG5vZGUgZm9yIHRoZSBuZXh0IGNhbGwgdG8gZ290b01hcmsoKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9tYXJrID0gX3BvczsKLQlfc2F2ZSA9IF9ub2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc3RvcmVzIHRoZSBjdXJyZW50IG5vZGUgcmVtZW1iZXJlZCBieSBzZXRNYXJrKCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JX3BvcyA9IF9tYXJrOwotCV9ub2RlID0gX3NhdmU7Ci0gICAgfQotCi0gICAgLyoqIAotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLCAKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IHN0YXJ0KSB7Ci0JaWYgKHN0YXJ0ID09IEVORCkgewotCSAgICBfbm9kZXMgPSBudWxsOwotCX0KLQllbHNlIGlmIChfbm9kZXMgIT0gbnVsbCkgewotCSAgICAvLyBOb2RlIGNvdW50IHN0YXJ0cyB3aXRoIDEsIHdoaWxlIGJpdCBhcnJheXMgY291bnQgZnJvbSAwLiBNdXN0Ci0JICAgIC8vIHN1YnRyYWN0IG9uZSBmcm9tICdzdGFydCcgdG8gaW5pdGlhbGl6ZSBiaXQgYXJyYXkgY29ycmVjdGx5LgotCSAgICBfc3RhcnQgPSBfbm9kZXMuZ2V0Qml0TnVtYmVyKHN0YXJ0LTEpOyAKLQkgICAgX25vZGUgPSBfc3RhcnQgLSAxOwotCX0KLQlyZXR1cm4oKE5vZGVJdGVyYXRvcil0aGlzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0JcmV0dXJuKGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotCXJldHVybigoTm9kZUl0ZXJhdG9yKXRoaXMpOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0xvYWREb2N1bWVudC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL0xvYWREb2N1bWVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNjhlMmI5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Mb2FkRG9jdW1lbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxNyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NQ2FjaGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotCi1wdWJsaWMgZmluYWwgY2xhc3MgTG9hZERvY3VtZW50IHsKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FU1BBQ0VfRkVBVFVSRSA9Ci0JImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIjsKLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYW4gaXRlcmF0b3IgY29udGFpbmluZyBhIHNldCBvZiBub2RlcyBmcm9tIGFuIFhNTCBkb2N1bWVudAotICAgICAqIGxvYWRlZCBieSB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIE5vZGVJdGVyYXRvciBkb2N1bWVudChTdHJpbmcgdXJpLCBTdHJpbmcgYmFzZSwKLQkJCQkJQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwgRE9NIGRvbSkKLQl0aHJvd3MgRXhjZXB0aW9uIHsKLQotCU11bHRpRE9NIG11bHRpcGxleGVyID0gKE11bHRpRE9NKWRvbTsKLQotCS8vIFJldHVybiBhbiBlbXB0eSBpdGVyYXRvciBpZiB0aGUgVVJJIGlzIGNsZWFybHkgaW52YWxpZAotCS8vICh0byBwcmV2ZW50IHNvbWUgdW5uY2Vzc2FyeSBNYWxmb3JtZWRVUkwgZXhjZXB0aW9ucykuCi0JaWYgKCh1cmkgPT0gbnVsbCkgfHwgKHVyaS5lcXVhbHMoIiIpKSkKLQkgICAgcmV0dXJuKG5ldyBTaW5nbGV0b25JdGVyYXRvcihET00uTlVMTCx0cnVlKSk7Ci0KLQkvLyBQcmVwZW5kIFVSSSBiYXNlIHRvIFVSSSAoZnJvbSBjb250ZXh0KQotCWlmICgoYmFzZSAhPSBudWxsKSAmJiAoIWJhc2UuZXF1YWxzKCIiKSkpIHsKLQkgICAgaWYgKCghdXJpLnN0YXJ0c1dpdGgoYmFzZSkpICYmICAgICAvLyB1bmxlc3MgVVJJIGNvbnRhaW5zIGJhc2UKLQkJKCF1cmkuc3RhcnRzV2l0aCgiLyIpKSAmJiAgICAgIC8vIHVubGVzcyBVUkkgaXMgYWJzLiBmaWxlIHBhdGgKLQkJKCF1cmkuc3RhcnRzV2l0aCgiaHR0cDovIikpICYmIC8vIHVubGVzcyBVUkkgaXMgYWJzLiBodHRwIFVSTAotCQkoIXVyaS5zdGFydHNXaXRoKCJmaWxlOi8iKSkpIHsgLy8gdW5sZXNzIFVSSSBpcyBhYnMuIGZpbGUgVVJMCi0JCXVyaSA9IGJhc2UrdXJpOwotCSAgICB9Ci0JfQotCi0JLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGxvY2FsIGZpbGUgbmFtZQotCWZpbmFsIEZpbGUgZmlsZSA9IG5ldyBGaWxlKHVyaSk7Ci0JaWYgKGZpbGUuZXhpc3RzKCkpCi0JICAgIHVyaSA9ICJmaWxlOiIgKyBmaWxlLmdldEFic29sdXRlUGF0aCgpOwotCQotCS8vIENoZWNrIGlmIHRoaXMgRE9NIGhhcyBhbHJlYWR5IGJlZW4gYWRkZWQgdG8gdGhlIG11bHRpcGxleGVyCi0JaW50IG1hc2sgPSBtdWx0aXBsZXhlci5nZXREb2N1bWVudE1hc2sodXJpKTsKLQlpZiAobWFzayAhPSAtMSkgewotCSAgICByZXR1cm4gbmV3IFNpbmdsZXRvbkl0ZXJhdG9yKERPTS5ST09UTk9ERSB8IG1hc2ssIHRydWUpOwotCX0KLQotCS8vIENoZWNrIGlmIHdlIGNhbiBnZXQgdGhlIERPTSBmcm9tIGEgRE9NQ2FjaGUKLQlET01DYWNoZSBjYWNoZSA9IHRyYW5zbGV0LmdldERPTUNhY2hlKCk7Ci0JRE9NSW1wbCBuZXdkb207Ci0KLQltYXNrID0gbXVsdGlwbGV4ZXIubmV4dE1hc2soKTsgLy8gcGVlawotCi0JaWYgKGNhY2hlICE9IG51bGwpIHsKLQkgICAgbmV3ZG9tID0gY2FjaGUucmV0cmlldmVEb2N1bWVudCh1cmksIG1hc2ssIHRyYW5zbGV0KTsKLQl9Ci0JZWxzZSB7Ci0JICAgIC8vIFBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBhbmQgY29uc3RydWN0IERPTSBvYmplY3QKLQkgICAgLy8gQ3JlYXRlIGEgU0FYIHBhcnNlciBhbmQgZ2V0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGl0IHVzZXMKLQkgICAgZmluYWwgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCSAgICB0cnkgewotCQlmYWN0b3J5LnNldEZlYXR1cmUoTkFNRVNQQUNFX0ZFQVRVUkUsdHJ1ZSk7Ci0JICAgIH0KLQkgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCWZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0JICAgIH0KLQkgICAgZmluYWwgU0FYUGFyc2VyIHBhcnNlciA9IGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0JICAgIGZpbmFsIFhNTFJlYWRlciByZWFkZXIgPSBwYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0KLQkgICAgLy8gU2V0IHRoZSBET00ncyBET00gYnVpbGRlciBhcyB0aGUgWE1MUmVhZGVyJ3MgU0FYMiBjb250ZW50IGhhbmRsZXIKLQkgICAgbmV3ZG9tID0gbmV3IERPTUltcGwoKTsKLQkgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKG5ld2RvbS5nZXRCdWlsZGVyKCkpOwotCSAgICAvLyBDcmVhdGUgYSBEVEQgbW9uaXRvciBhbmQgcGFzcyBpdCB0byB0aGUgWE1MUmVhZGVyIG9iamVjdAotCSAgICBEVERNb25pdG9yIGR0ZE1vbml0b3IgPSBuZXcgRFRETW9uaXRvcigpOwotCSAgICBkdGRNb25pdG9yLmhhbmRsZURURChyZWFkZXIpOwotCi0JICAgIG5ld2RvbS5zZXREb2N1bWVudFVSSSh1cmkpOwotCSAgICByZWFkZXIucGFyc2UodXJpKTsKLQotCSAgICAvLyBTZXQgc2l6ZSBvZiBrZXkvaWQgaW5kaWNlcwotCSAgICB0cmFuc2xldC5zZXRJbmRleFNpemUobmV3ZG9tLmdldFNpemUoKSk7Ci0JICAgIC8vIENyZWF0ZSBpbmRleCBmb3IgYW55IElEIGF0dHJpYnV0ZXMgZGVmaW5lZCBpbiB0aGUgZG9jdW1lbnQgRFRECi0JICAgIGR0ZE1vbml0b3IuYnVpbGRJZEluZGV4KG5ld2RvbSwgbWFzaywgdHJhbnNsZXQpOwotCSAgICAvLyBQYXNzIGFueSB1bnBhcnNlZCBVUkkgZWxlbWVudHMgdG8gdGhlIHRyYW5zbGV0Ci0JICAgIHRyYW5zbGV0LnNldFVucGFyc2VkRW50aXR5VVJJcyhkdGRNb25pdG9yLmdldFVucGFyc2VkRW50aXR5VVJJcygpKTsKLQl9Ci0KLQkvLyBXcmFwIHRoZSBET00gb2JqZWN0IGluIGEgRE9NIGFkYXB0ZXIgYW5kIGFkZCB0byBtdWx0aXBsZXhlcgotCWZpbmFsIERPTUFkYXB0ZXIgZG9tQWRhcHRlciA9IHRyYW5zbGV0Lm1ha2VET01BZGFwdGVyKG5ld2RvbSk7Ci0JbWFzayA9IG11bHRpcGxleGVyLmFkZERPTUFkYXB0ZXIoZG9tQWRhcHRlcik7Ci0KLQkvLyBDcmVhdGUgaW5kZXggZm9yIGFueSBrZXkgZWxlbWVudHMKLQl0cmFuc2xldC5idWlsZEtleXMoKERPTSluZXdkb20sIG51bGwsIG51bGwsIERPTS5ST09UTk9ERSB8IG1hc2spOwotCi0JLy8gUmV0dXJuIGEgc2luZ2xldG9uIGl0ZXJhdG9yIGNvbnRhaW5pbmcgdGhlIHJvb3Qgbm9kZQotCXJldHVybiBuZXcgU2luZ2xldG9uSXRlcmF0b3IoRE9NLlJPT1ROT0RFIHwgbWFzaywgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW50ZXJwcmV0cyB0aGUgYXJndW1lbnRzIHBhc3NlZCBmcm9tIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uIChzZWUKLSAgICAgKiBvcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL0RvY3VtZW50Q2FsbC5qYXZhKSBhbmQgcmV0dXJucyBhbgotICAgICAqIGl0ZXJhdG9yIGNvbnRhaW5pbmcgdGhlIHJlcXVlc3RlZCBub2Rlcy4gQnVpbGRzIGEgdW5pb24taXRlcmF0b3IgaWYKLSAgICAgKiBzZXZlcmFsIGRvY3VtZW50cyBhcmUgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgTm9kZUl0ZXJhdG9yIGRvY3VtZW50KE9iamVjdCBhcmcsIFN0cmluZyBjb250ZXh0VVJJLAotCQkJCQlBYnN0cmFjdFRyYW5zbGV0IHRyYW5zbGV0LCBET00gZG9tKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQotCSAgICBTdHJpbmcgYmFzZVVSSSA9ICIiOwotCi0JICAgIC8vIEdldCB0aGUgYmFzZSBvZiB0aGUgY29uZXh0IFVSSSAoaWYgYW55KQotCSAgICBpZiAoY29udGV4dFVSSSAhPSBudWxsKSB7Ci0JCWZpbmFsIGludCBzZXAgPSBjb250ZXh0VVJJLmxhc3RJbmRleE9mKCcvJykgKyAxOwotCQliYXNlVVJJID0gY29udGV4dFVSSS5zdWJzdHJpbmcoMCwgc2VwKTsgLy8gY291bGQgYmUgZW1wdHkgc3RyaW5nCi0JICAgIH0KLQotCSAgICAvLyBJZiB0aGUgYXJndW1lbnQgaXMganVzdCBhIHNpbmdsZSBzdHJpbmcgKGFuIFVSSSkgd2UganVzdCByZXR1cm4KLQkgICAgLy8gdGhlIG5vZGVzIGZyb20gdGhlIG9uZSBkb2N1bWVudCB0aGlzIFVSSSBwb2ludHMgdG8uCi0JICAgIGlmIChhcmcgaW5zdGFuY2VvZiBTdHJpbmcpIHsKLQkJcmV0dXJuIGRvY3VtZW50KChTdHJpbmcpYXJnLCBiYXNlVVJJLCB0cmFuc2xldCwgZG9tKTsKLQkgICAgfQotCSAgICAvLyBPdGhlcndpc2Ugd2UgbXVzdCBjcmVhdGUgYSB1bmlvbiBpdGVyYXRvciwgYWRkIHRoZSBub2RlcyBmcm9tCi0JICAgIC8vIGFsbCB0aGUgRE9NcyB0byB0aGlzIGl0ZXJhdG9yLCBhbmQgcmV0dXJuIHRoZSB1bmlvbiBpbiB0aGUgZW5kLgotCSAgICBlbHNlIHsKLQkJVW5pb25JdGVyYXRvciB1bmlvbiA9IG5ldyBVbmlvbkl0ZXJhdG9yKGRvbSk7Ci0JCU5vZGVJdGVyYXRvciBpdGVyYXRvciA9IChOb2RlSXRlcmF0b3IpYXJnOwotCQlpbnQgbm9kZTsKLQotCQl3aGlsZSAoKG5vZGUgPSBpdGVyYXRvci5uZXh0KCkpICE9IERPTS5OVUxMKSB7Ci0JCSAgICBTdHJpbmcgdXJpID0gZG9tLmdldE5vZGVWYWx1ZShub2RlKTsKLQkJICAgIHVuaW9uLmFkZEl0ZXJhdG9yKGRvY3VtZW50KHVyaSwgYmFzZVVSSSwgdHJhbnNsZXQsIGRvbSkpOwotCQl9Ci0JCXJldHVybih1bmlvbik7Ci0JICAgIH0KLQl9Ci0JY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTWF0Y2hpbmdJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL01hdGNoaW5nSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDZiZDZhMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTWF0Y2hpbmdJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBNYXRjaGluZ0l0ZXJhdG9yIGV4dGVuZHMgTm9kZUl0ZXJhdG9yQmFzZSB7Ci0gICAgcHJpdmF0ZSBOb2RlSXRlcmF0b3IgX3NvdXJjZTsKLSAgICBwcml2YXRlIGZpbmFsIGludCAgICBfbWF0Y2g7Ci0gICAgcHJpdmF0ZSBpbnQgX21hdGNoUG9zLCBfbWF0Y2hMYXN0ID0gLTE7Ci0JCi0gICAgcHVibGljIE1hdGNoaW5nSXRlcmF0b3IoaW50IG1hdGNoLCBOb2RlSXRlcmF0b3Igc291cmNlKSB7Ci0JX3NvdXJjZSA9IHNvdXJjZTsKLQlfbWF0Y2ggPSBtYXRjaDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKSB7Ci0JdHJ5IHsKLQkgICAgZmluYWwgTWF0Y2hpbmdJdGVyYXRvciBjbG9uZSA9IChNYXRjaGluZ0l0ZXJhdG9yKXN1cGVyLmNsb25lKCk7Ci0JICAgIGNsb25lLl9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0JICAgIGNsb25lLl9zb3VyY2UgPSBfc291cmNlLmNsb25lSXRlcmF0b3IoKTsKLQkgICAgcmV0dXJuIGNsb25lOwotCX0KLQljYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewotCSAgICBCYXNpc0xpYnJhcnkucnVuVGltZUVycm9yKCJJdGVyYXRvciBjbG9uZSBub3Qgc3VwcG9ydGVkLiIpOyAKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCWlmIChfaXNSZXN0YXJ0YWJsZSkgewotCSAgICAvLyBpdGVyYXRvciBpcyBub3QgYSBjbG9uZQotCSAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlID0gbm9kZSk7Ci0KLQkgICAgLy8gQ2FsY3VsYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgbm9kZSBpbiB0aGUgc2V0Ci0JICAgIGZpbmFsIGludCBtYXRjaCA9IF9tYXRjaDsKLQkgICAgaW50IGkgPSAxOwotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EICYmIG5vZGUgIT0gbWF0Y2gpIHsKLQkJKytpOwotCSAgICB9Ci0JICAgIF9tYXRjaFBvcyA9IGk7Ci0JICAgIF9tYXRjaExhc3QgPSAtMTsKLQl9Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlyZXR1cm4gdGhpczsJLy8gc2hvdWxkIG5vdCBiZSBjYWxsZWQKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGludCBuZXh0KCkgewotCXJldHVybiBfc291cmNlLm5leHQoKTsKLSAgICB9Ci0JCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCWlmIChfbWF0Y2hMYXN0ID09IC0xKSB7Ci0JICAgIF9zb3VyY2UucmVzZXQoKTsKLQkgICAgaW50IGkgPSAxLCBub2RlOwotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0JCSsraTsKLQkgICAgfQotCSAgICBfbWF0Y2hMYXN0ID0gaSAtIDE7Ci0JfQotCXJldHVybiBfbWF0Y2hMYXN0OwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7Ci0JcmV0dXJuIF9tYXRjaFBvczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9zb3VyY2Uuc2V0TWFyaygpOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCV9zb3VyY2UuZ290b01hcmsoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTXVsdGlET00uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9NdWx0aURPTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZjkxZWQyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9NdWx0aURPTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzU3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRXJ3aW4gQm9sd2lkdCA8ZWpiQGtsb21wLm9yZz4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlN0cmlwRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRPdXRwdXRIYW5kbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkhhc2h0YWJsZTsKLQotcHVibGljIGZpbmFsIGNsYXNzIE11bHRpRE9NIGltcGxlbWVudHMgRE9NIHsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTk9fVFlQRSA9IERPTS5GSVJTVF9UWVBFIC0gMjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9TSVpFID0gNDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0xSID0gMHgwMEZGRkZGRjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0VUID0gMHhGRjAwMDAwMDsKLSAgICAKLSAgICBwcml2YXRlIERPTVtdIF9hZGFwdGVyczsKLSAgICBwcml2YXRlIGludCBfZnJlZTsKLSAgICBwcml2YXRlIGludCBfc2l6ZTsKLQotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9kb2N1bWVudHMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0KLSAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEF4aXNJdGVyYXRvciBpbXBsZW1lbnRzIE5vZGVJdGVyYXRvciB7Ci0JLy8gY29uc3RpdHV0aXZlIGRhdGEKLQlwcml2YXRlIGZpbmFsIGludCBfYXhpczsKLQlwcml2YXRlIGZpbmFsIGludCBfdHlwZTsKLQkvLyBpbXBsZW1lbnRhdGlvbiBtZWNoYW5pc20KLQlwcml2YXRlIE5vZGVJdGVyYXRvciBfc291cmNlOwotCXByaXZhdGUgaW50IF9tYXNrOwotCQotCXB1YmxpYyBBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCB0eXBlKSB7Ci0JICAgIF9heGlzID0gYXhpczsKLQkgICAgX3R5cGUgPSB0eXBlOwotCX0KLQkKLQlwdWJsaWMgaW50IG5leHQoKSB7Ci0JICAgIGlmIChfc291cmNlID09IG51bGwpIHJldHVybihFTkQpOwotCSAgICBpZiAoX21hc2sgPT0gMCkgcmV0dXJuIF9zb3VyY2UubmV4dCgpOwotCSAgICBmaW5hbCBpbnQgbm9kZSA9IF9zb3VyY2UubmV4dCgpOwotCSAgICByZXR1cm4gbm9kZSAhPSBFTkQgPyAobm9kZSB8IF9tYXNrKSA6IEVORDsKLQl9Ci0JCi0JcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoZmluYWwgaW50IG5vZGUpIHsKLQkgICAgX21hc2sgPSBub2RlICYgU0VUOwotCSAgICAvLyBjb25zaWRlciBjYWNoaW5nIHRoZXNlCi0JICAgIGlmICgoX3R5cGUgPT0gTk9fVFlQRSkgfHwgKF90eXBlID09IERPTS5FTEVNRU5UKSkgewotCQlfc291cmNlID0gX2FkYXB0ZXJzW25vZGU+Pj4yNF0uZ2V0QXhpc0l0ZXJhdG9yKF9heGlzKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChfYXhpcyA9PSBBeGlzLkNISUxEKSB7Ci0JCV9zb3VyY2UgPSBfYWRhcHRlcnNbbm9kZT4+PjI0XS5nZXRUeXBlZENoaWxkcmVuKF90eXBlKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX3NvdXJjZSA9IF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldFR5cGVkQXhpc0l0ZXJhdG9yKF9heGlzLF90eXBlKTsKLQkgICAgfQotCSAgICBfc291cmNlLnNldFN0YXJ0Tm9kZShub2RlICYgQ0xSKTsKLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCi0JcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQkgICAgaWYgKF9zb3VyY2UgIT0gbnVsbCkgX3NvdXJjZS5yZXNldCgpOwotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgCi0JcHVibGljIGludCBnZXRMYXN0KCkgewotCSAgICByZXR1cm4gX3NvdXJjZS5nZXRMYXN0KCk7Ci0JfQotICAgIAotCXB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7Ci0JICAgIHJldHVybiBfc291cmNlLmdldFBvc2l0aW9uKCk7Ci0JfQotICAgIAotCXB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpIHsKLQkgICAgaWYgKF9zb3VyY2UgPT0gbnVsbCkKLQkJcmV0dXJuKGZhbHNlKTsKLQkgICAgZWxzZQotCQlyZXR1cm4gX3NvdXJjZS5pc1JldmVyc2UoKTsKLQl9Ci0gICAgCi0JcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQkgICAgX3NvdXJjZS5zZXRNYXJrKCk7Ci0JfQotICAgIAotCXB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCSAgICBfc291cmNlLmdvdG9NYXJrKCk7Ci0JfQotICAgIAotCXB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQkgICAgLy8hISBub3QgZW50aXJlbHkgZ29vZAotCSAgICAvLyEhIG5vdCBjbGVhciB3aGVuIGNsb25pbmcgaXMgcGVyZm9ybWVkCi0JICAgIC8vIGFuZCB3aGF0J3MgdGhlIGRlc2lyZWQgc3RhdGUgb2YgdGhlIG5ldyBjbG9uZQotCSAgICBmaW5hbCBOb2RlSXRlcmF0b3IgY2xvbmUgPSBuZXcgQXhpc0l0ZXJhdG9yKF9heGlzLCBfdHlwZSk7Ci0JICAgIC8vcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0JICAgIHJldHVybiBjbG9uZTsKLQl9Ci0gICAgfSAvLyBlbmQgb2YgQXhpc0l0ZXJhdG9yCi0KLQotICAgIHB1YmxpYyBNdWx0aURPTShET00gbWFpbikgewotCV9zaXplID0gSU5JVElBTF9TSVpFOwotCV9mcmVlID0gMTsKLQlfYWRhcHRlcnMgPSBuZXcgRE9NW0lOSVRJQUxfU0laRV07Ci0JX2FkYXB0ZXJzWzBdID0gbWFpbjsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHRNYXNrKCkgewotCXJldHVybihfZnJlZSA8PCAyNCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0dXBNYXBwaW5nKFN0cmluZ1tdIG5hbWVzLCBTdHJpbmdbXSBuYW1lc3BhY2VzKSB7Ci0JLy8gVGhpcyBtZXRob2Qgb25seSBoYXMgYSBmdW5jdGlvbiBpbiBET00gYWRhcHRlcnMKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGFkZERPTUFkYXB0ZXIoRE9NIGRvbSkgewotCi0JLy8gQWRkIHRoZSBET00gYWRhcHRlciB0byB0aGUgYXJyYXkgb2YgRE9NcwotCWZpbmFsIGludCBkb21ObyA9IF9mcmVlKys7Ci0JaWYgKGRvbU5vID09IF9zaXplKSB7Ci0JICAgIGZpbmFsIERPTUFkYXB0ZXJbXSBuZXdBcnJheSA9IG5ldyBET01BZGFwdGVyW19zaXplICo9IDJdOwotCSAgICBTeXN0ZW0uYXJyYXljb3B5KF9hZGFwdGVycywgMCwgbmV3QXJyYXksIDAsIGRvbU5vKTsKLQkgICAgX2FkYXB0ZXJzID0gbmV3QXJyYXk7Ci0JfQotCV9hZGFwdGVyc1tkb21Ob10gPSBkb207Ci0KLQkvLyBTdG9yZSByZWZlcmVuY2UgdG8gZG9jdW1lbnQgKFVSSSkgaW4gaGFzaHRhYmxlCi0JU3RyaW5nIHVyaSA9IGRvbS5nZXREb2N1bWVudFVSSSgwKTsKLQlfZG9jdW1lbnRzLnB1dCh1cmksbmV3IEludGVnZXIoZG9tTm8pKTsKLQkKLQlyZXR1cm4gZG9tTm8gPDwgMjQ7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnRNYXNrKFN0cmluZyB1cmkpIHsKLQlJbnRlZ2VyIGRvbUlkeCA9IChJbnRlZ2VyKV9kb2N1bWVudHMuZ2V0KHVyaSk7Ci0JaWYgKGRvbUlkeCA9PSBudWxsKQotCSAgICByZXR1cm4oLTEpOwotCWVsc2UKLQkgICAgcmV0dXJuKChkb21JZHguaW50VmFsdWUoKSA8PCAyNCkpOwotICAgIH0KLQotICAgIC8qKiByZXR1cm5zIHNpbmdsZXRvbiBpdGVyYXRvciBjb250YWluZyB0aGUgZG9jdW1lbnQgcm9vdCAqLwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0SXRlcmF0b3IoKSB7Ci0JLy8gbWFpbiBzb3VyY2UgZG9jdW1lbnQgQCAwCi0JcmV0dXJuIF9hZGFwdGVyc1swXS5nZXRJdGVyYXRvcigpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZ1ZhbHVlKCkgewotCXJldHVybiBfYWRhcHRlcnNbMF0uZ2V0U3RyaW5nVmFsdWUoKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXRDaGlsZHJlbihmaW5hbCBpbnQgbm9kZSkgewotCXJldHVybiAobm9kZSAmIFNFVCkgPT0gMAotCSAgICA/IF9hZGFwdGVyc1swXS5nZXRDaGlsZHJlbihub2RlKQotCSAgICA6IGdldEF4aXNJdGVyYXRvcihBeGlzLkNISUxEKS5zZXRTdGFydE5vZGUobm9kZSk7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0VHlwZWRDaGlsZHJlbihmaW5hbCBpbnQgdHlwZSkgewotCXJldHVybiBuZXcgQXhpc0l0ZXJhdG9yKEF4aXMuQ0hJTEQsIHR5cGUpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcykgewotCXJldHVybiBuZXcgQXhpc0l0ZXJhdG9yKGF4aXMsIE5PX1RZUEUpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgdHlwZSkgewotCXJldHVybiBuZXcgQXhpc0l0ZXJhdG9yKGF4aXMsIHR5cGUpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0TnRoRGVzY2VuZGFudChpbnQgbm9kZSwgaW50IG4pIHsKLQlyZXR1cm4gX2FkYXB0ZXJzW25vZGU+Pj4yNF0uZ2V0TnRoRGVzY2VuZGFudChub2RlICYgQ0xSLCBuKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldE5vZGVWYWx1ZUl0ZXJhdG9yKE5vZGVJdGVyYXRvciBpdGVyYXRvciwKLQkJCQkJICAgICBTdHJpbmcgdmFsdWUsIGJvb2xlYW4gb3ApIHsKLQlyZXR1cm4gX2FkYXB0ZXJzWzBdLmdldE5vZGVWYWx1ZUl0ZXJhdG9yKGl0ZXJhdG9yLCB2YWx1ZSwgb3ApOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0TmFtZXNwYWNlQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgbnMpIHsKLQlOb2RlSXRlcmF0b3IgaXRlcmF0b3IgPSBfYWRhcHRlcnNbMF0uZ2V0TmFtZXNwYWNlQXhpc0l0ZXJhdG9yKGF4aXMsbnMpOwotCXJldHVybihpdGVyYXRvcik7CQotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3Igb3JkZXJOb2RlcyhOb2RlSXRlcmF0b3Igc291cmNlLCBpbnQgbm9kZSkgewotCXJldHVybiBfYWRhcHRlcnNbbm9kZT4+PjI0XS5vcmRlck5vZGVzKHNvdXJjZSwgbm9kZSAmIENMUik7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRUeXBlKGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldFR5cGUobm9kZSAmIENMUik7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXROYW1lc3BhY2VUeXBlKGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldE5hbWVzcGFjZVR5cGUobm9kZSAmIENMUik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBpbnQgZ2V0UGFyZW50KGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldFBhcmVudChub2RlICYgQ0xSKSB8IG5vZGUmU0VUOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgaW50IGdldFR5cGVkUG9zaXRpb24oTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBpbnQgdHlwZSwgaW50IG5vZGUpIHsKLQlyZXR1cm4gX2FkYXB0ZXJzW25vZGU+Pj4yNF0uZ2V0VHlwZWRQb3NpdGlvbihpdGVyYXRvciwgdHlwZSwgbm9kZSZDTFIpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0VHlwZWRMYXN0KE5vZGVJdGVyYXRvciBpdGVyYXRvciwgaW50IHR5cGUsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldFR5cGVkTGFzdChpdGVyYXRvciwgdHlwZSwgbm9kZSZDTFIpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShmaW5hbCBpbnQgdHlwZSwgZmluYWwgaW50IGVsKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tlbD4+PjI0XS5nZXRBdHRyaWJ1dGVOb2RlKHR5cGUsIGVsJkNMUikgfCBlbCZTRVQ7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoZmluYWwgaW50IG5vZGUpIHsKLQlyZXR1cm4gX2FkYXB0ZXJzW25vZGU+Pj4yNF0uZ2V0Tm9kZU5hbWUobm9kZSAmIENMUik7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VOYW1lKGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldE5hbWVzcGFjZU5hbWUobm9kZSAmIENMUik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKGZpbmFsIGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldE5vZGVWYWx1ZShub2RlICYgQ0xSKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgY29weShmaW5hbCBpbnQgbm9kZSwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQlfYWRhcHRlcnNbbm9kZT4+PjI0XS5jb3B5KG5vZGUgJiBDTFIsIGhhbmRsZXIpOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgdm9pZCBjb3B5KE5vZGVJdGVyYXRvciBub2RlcywgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQlpbnQgbm9kZTsKLQl3aGlsZSAoKG5vZGUgPSBub2Rlcy5uZXh0KCkpICE9IERPTS5OVUxMKSB7Ci0JICAgIF9hZGFwdGVyc1tub2RlPj4+MjRdLmNvcHkobm9kZSAmIENMUiwgaGFuZGxlcik7Ci0JfQotICAgIH0KLQotCi0gICAgcHVibGljIFN0cmluZyBzaGFsbG93Q29weShmaW5hbCBpbnQgbm9kZSwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQlyZXR1cm4gX2FkYXB0ZXJzW25vZGU+Pj4yNF0uc2hhbGxvd0NvcHkobm9kZSAmIENMUiwgaGFuZGxlcik7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBib29sZWFuIGxlc3NUaGFuKGZpbmFsIGludCBub2RlMSwgZmluYWwgaW50IG5vZGUyKSB7Ci0JZmluYWwgaW50IGRvbTEgPSBub2RlMT4+PjI0OwotCWZpbmFsIGludCBkb20yID0gbm9kZTI+Pj4yNDsKLQlyZXR1cm4gZG9tMSA9PSBkb20yCi0JICAgID8gX2FkYXB0ZXJzW2RvbTFdLmxlc3NUaGFuKG5vZGUxICYgQ0xSLCBub2RlMiAmIENMUikKLQkgICAgOiBkb20xIDwgZG9tMjsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBpbnQgdGV4dE5vZGUsIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JICAgIF9hZGFwdGVyc1t0ZXh0Tm9kZT4+PjI0XS5jaGFyYWN0ZXJzKHRleHROb2RlICYgQ0xSLCBoYW5kbGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoU3RyaXBGaWx0ZXIgZmlsdGVyKSB7Ci0JZm9yIChpbnQgZG9tPTA7IGRvbTxfZnJlZTsgZG9tKyspIHsKLQkgICAgX2FkYXB0ZXJzW2RvbV0uc2V0RmlsdGVyKGZpbHRlcik7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKGludCBpbmRleCkgewotCXJldHVybiBfYWRhcHRlcnNbaW5kZXg+Pj4yNF0ubWFrZU5vZGUoaW5kZXggJiBDTFIpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKE5vZGVJdGVyYXRvciBpdGVyKSB7Ci0JLy8gVE9ETzogZ2F0aGVyIG5vZGVzIGZyb20gYWxsIERPTXMgPwotCXJldHVybiBfYWRhcHRlcnNbMF0ubWFrZU5vZGUoaXRlcik7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChpbnQgaW5kZXgpIHsKLQlyZXR1cm4gX2FkYXB0ZXJzW2luZGV4Pj4+MjRdLm1ha2VOb2RlTGlzdChpbmRleCAmIENMUik7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChOb2RlSXRlcmF0b3IgaXRlcikgewotCS8vIFRPRE86IGdhdGhlciBub2RlcyBmcm9tIGFsbCBET01zID8KLQlyZXR1cm4gX2FkYXB0ZXJzWzBdLm1ha2VOb2RlTGlzdChpdGVyKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldExhbmd1YWdlKGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldExhbmd1YWdlKG5vZGUgJiBDTFIpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKLQlpbnQgc2l6ZSA9IDA7Ci0JZm9yIChpbnQgaT0wOyBpPF9zaXplOyBpKyspCi0JICAgIHNpemUgKz0gX2FkYXB0ZXJzW2ldLmdldFNpemUoKTsKLQlyZXR1cm4oc2l6ZSk7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFVSSShpbnQgbm9kZSkgewotCXJldHVybiBfYWRhcHRlcnNbbm9kZT4+MjRdLmdldERvY3VtZW50VVJJKDApOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9NdWx0aXBsZU5vZGVDb3VudGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTXVsdGlwbGVOb2RlQ291bnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYTY5YTJhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9NdWx0aXBsZU5vZGVDb3VudGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWwuSW50ZWdlckFycmF5OwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTXVsdGlwbGVOb2RlQ291bnRlciBleHRlbmRzIE5vZGVDb3VudGVyIHsKLSAgICBwcml2YXRlIE5vZGVJdGVyYXRvciBfcHJlY1NpYmxpbmdzID0gbnVsbDsKLQotICAgIHB1YmxpYyBNdWx0aXBsZU5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotCQkJICAgICAgIERPTSBkb2N1bWVudCwgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0Jc3VwZXIodHJhbnNsZXQsIGRvY3VtZW50LCBpdGVyYXRvcik7Ci0gICAgfQotCQotICAgIHB1YmxpYyBOb2RlQ291bnRlciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlfbm9kZSA9IG5vZGU7Ci0JX25vZGVUeXBlID0gX2RvY3VtZW50LmdldFR5cGUobm9kZSk7Ci0JX3ByZWNTaWJsaW5ncyA9IF9kb2N1bWVudC5nZXRBeGlzSXRlcmF0b3IoUFJFQ0VESU5HU0lCTElORyk7Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRDb3VudGVyKCkgewotCWlmIChfdmFsdWUgIT0gSW50ZWdlci5NSU5fVkFMVUUpIHsKLQkgICAgcmV0dXJuIGZvcm1hdE51bWJlcnMoX3ZhbHVlKTsKLQl9Ci0KLQlJbnRlZ2VyQXJyYXkgYW5jZXN0b3JzID0gbmV3IEludGVnZXJBcnJheSgpOwotCi0JLy8gR2F0aGVyIGFsbCBhbmNlc3RvcnMgdGhhdCBkbyBub3QgbWF0Y2ggZnJvbSBwYXR0ZXJuCi0JaW50IG5leHQgPSBfbm9kZTsKLQlhbmNlc3RvcnMuYWRkKG5leHQpOwkJLy8gaW5jbHVkZSBzZWxmCi0Jd2hpbGUgKChuZXh0ID0gX2RvY3VtZW50LmdldFBhcmVudChuZXh0KSkgPiBFTkQgJiYgCi0JICAgICAgICFtYXRjaGVzRnJvbShuZXh0KSkgewotCSAgICBhbmNlc3RvcnMuYWRkKG5leHQpOwotCX0KLQotCS8vIENyZWF0ZSBhbiBhcnJheSBvZiBjb3VudGVycwotCWZpbmFsIGludCBuQW5jZXN0b3JzID0gYW5jZXN0b3JzLmNhcmRpbmFsaXR5KCk7Ci0JZmluYWwgaW50W10gY291bnRlcnMgPSBuZXcgaW50W25BbmNlc3RvcnNdOyAKLQlmb3IgKGludCBpID0gMDsgaSA8IG5BbmNlc3RvcnM7IGkrKykgewotCSAgICBjb3VudGVyc1tpXSA9IEludGVnZXIuTUlOX1ZBTFVFOwotCX0KLQotCS8vIEluY3JlbWVudCBhcnJheSBvZiBjb3VudGVycyBhY2NvcmRpbmcgdG8gc2VtYW50aWNzCi0JZm9yIChpbnQgaiA9IDAsIGkgPSBuQW5jZXN0b3JzIC0gMTsgaSA+PSAwIDsgaS0tLCBqKyspIHsKLQkgICAgZmluYWwgaW50IGNvdW50ZXIgPSBjb3VudGVyc1tqXTsKLQkgICAgZmluYWwgaW50IGFuY2VzdG9yID0gYW5jZXN0b3JzLmF0KGkpOwotCi0JICAgIGlmIChtYXRjaGVzQ291bnQoYW5jZXN0b3IpKSB7Ci0JCV9wcmVjU2libGluZ3Muc2V0U3RhcnROb2RlKGFuY2VzdG9yKTsKLQkJd2hpbGUgKChuZXh0ID0gX3ByZWNTaWJsaW5ncy5uZXh0KCkpICE9IEVORCkgewotCQkgICAgaWYgKG1hdGNoZXNDb3VudChuZXh0KSkgewotCQkJY291bnRlcnNbal0gPSAoY291bnRlcnNbal0gPT0gSW50ZWdlci5NSU5fVkFMVUUpID8gMSAKLQkJCSAgICA6IGNvdW50ZXJzW2pdICsgMTsJCQotCQkgICAgfQotCQl9Ci0JCS8vIENvdW50IHRoZSBub2RlIGl0c2VsZgotCQljb3VudGVyc1tqXSA9IGNvdW50ZXJzW2pdID09IEludGVnZXIuTUlOX1ZBTFVFCi0JCSAgICA/IDEgCi0JCSAgICA6IGNvdW50ZXJzW2pdICsgMTsJCi0JICAgIH0KLQl9Ci0JcmV0dXJuIGZvcm1hdE51bWJlcnMoY291bnRlcnMpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgTm9kZUNvdW50ZXIgZ2V0RGVmYXVsdE5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotCQkJCQkJICAgIERPTSBkb2N1bWVudCwKLQkJCQkJCSAgICBOb2RlSXRlcmF0b3IgaXRlcmF0b3IpIHsKLQlyZXR1cm4gbmV3IERlZmF1bHRNdWx0aXBsZU5vZGVDb3VudGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotICAgIH0KLQotICAgIHN0YXRpYyBjbGFzcyBEZWZhdWx0TXVsdGlwbGVOb2RlQ291bnRlciBleHRlbmRzIE11bHRpcGxlTm9kZUNvdW50ZXIgewotCXB1YmxpYyBEZWZhdWx0TXVsdGlwbGVOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLQkJCQkJICBET00gZG9jdW1lbnQsCi0JCQkJCSAgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0JICAgIHN1cGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotCX0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZUNvdW50ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Ob2RlQ291bnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzOTI3MjJiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Ob2RlQ291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQ3ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5BeGlzOwotCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgTm9kZUNvdW50ZXIgaW1wbGVtZW50cyBBeGlzIHsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkQgPSBET00uTlVMTDsKLQotICAgIHByb3RlY3RlZCBpbnQgX25vZGUgPSBFTkQ7Ci0gICAgcHJvdGVjdGVkIGludCBfbm9kZVR5cGUgPSBET00uRklSU1RfVFlQRSAtIDE7Ci0gICAgcHJvdGVjdGVkIGludCBfdmFsdWUgPSBJbnRlZ2VyLk1JTl9WQUxVRTsKLQotICAgIHB1YmxpYyBmaW5hbCBET00gICAgICAgICAgX2RvY3VtZW50OwotICAgIHB1YmxpYyBmaW5hbCBOb2RlSXRlcmF0b3IgX2l0ZXJhdG9yOwotICAgIHB1YmxpYyBmaW5hbCBUcmFuc2xldCAgICAgX3RyYW5zbGV0OwotCi0gICAgcHJvdGVjdGVkIFN0cmluZyBfZm9ybWF0OwotICAgIHByb3RlY3RlZCBTdHJpbmcgX2xhbmc7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBfbGV0dGVyVmFsdWU7Ci0gICAgcHJvdGVjdGVkIFN0cmluZyBfZ3JvdXBTZXA7Ci0gICAgcHJvdGVjdGVkIGludCAgICBfZ3JvdXBTaXplOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gVGhvdXNhbmRzID0gCi0gICAgICAgIHsiIiwgIm0iLCAibW0iLCAibW1tIiB9OwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIEh1bmRyZWRzID0gCi0JeyIiLCAiYyIsICJjYyIsICJjY2MiLCAiY2QiLCAiZCIsICJkYyIsICJkY2MiLCAiZGNjYyIsICJjbSJ9OwotICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIFRlbnMgPSAKLQl7IiIsICJ4IiwgInh4IiwgInh4eCIsICJ4bCIsICJsIiwgImx4IiwgImx4eCIsICJseHh4IiwgInhjIn07Ci0gICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gT25lcyA9IAotCXsiIiwgImkiLCAiaWkiLCAiaWlpIiwgIml2IiwgInYiLCAidmkiLCAidmlpIiwgInZpaWkiLCAiaXgifTsKLQotICAgIHByb3RlY3RlZCBOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLQkJCSAgRE9NIGRvY3VtZW50LCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IpIHsKLQlfdHJhbnNsZXQgPSB0cmFuc2xldDsKLQlfZG9jdW1lbnQgPSBkb2N1bWVudDsKLQlfaXRlcmF0b3IgPSBpdGVyYXRvcjsKLSAgICB9Ci0KLSAgICAvKiogCi0gICAgICogU2V0IHRoZSBzdGFydCBub2RlIGZvciB0aGlzIGNvdW50ZXIuIFRoZSBzYW1lIDx0dD5Ob2RlQ291bnRlcjwvdHQ+Ci0gICAgICogb2JqZWN0IGNhbiBiZSB1c2VkIG11bHRpcGxlIHRpbWVzIGJ5IHJlc2V0dGluZyB0aGUgc3RhcnRpbmcgbm9kZS4KLSAgICAgKi8KLSAgICBhYnN0cmFjdCBwdWJsaWMgTm9kZUNvdW50ZXIgc2V0U3RhcnROb2RlKGludCBub2RlKTsKLQotICAgIC8qKiAKLSAgICAgKiBJZiB0aGUgdXNlciBzcGVjaWZpZWQgYSB2YWx1ZSBhdHRyaWJ1dGUsIHVzZSB0aGlzIGluc3RlYWQgb2YgCi0gICAgICogY291bnRpbmcgbm9kZXMuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVDb3VudGVyIHNldFZhbHVlKGludCB2YWx1ZSkgewotCV92YWx1ZSA9IHZhbHVlOwotCXJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgZm9ybWF0dGluZyBmaWVsZHMgYmVmb3JlIGNhbGxpbmcgZm9ybWF0TnVtYmVycygpLgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldEZvcm1hdHRpbmcoU3RyaW5nIGZvcm1hdCwgU3RyaW5nIGxhbmcsIFN0cmluZyBsZXR0ZXJWYWx1ZSwKLQkJCQkgU3RyaW5nIGdyb3VwU2VwLCBTdHJpbmcgZ3JvdXBTaXplKSB7Ci0JX2xhbmcgPSBsYW5nOwotCV9mb3JtYXQgPSBmb3JtYXQ7Ci0JX2dyb3VwU2VwID0gZ3JvdXBTZXA7Ci0JX2xldHRlclZhbHVlID0gbGV0dGVyVmFsdWU7Ci0KLQl0cnkgewotCSAgICBfZ3JvdXBTaXplID0gSW50ZWdlci5wYXJzZUludChncm91cFNpemUpOwotCX0KLQljYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLQkgICAgX2dyb3VwU2l6ZSA9IDA7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgZm9ybWF0dGluZyBmaWVsZHMgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVDb3VudGVyIHNldERlZmF1bHRGb3JtYXR0aW5nKCkgewotCXNldEZvcm1hdHRpbmcoIjEiLCAiZW4iLCAiYWxwaGFiZXRpYyIsIG51bGwsIG51bGwpOwotCXJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIDx0dD5ub2RlPC90dD4gYWNjb3JkaW5nIHRvIHRoZSBsZXZlbCBhbmQgCi0gICAgICogdGhlIGZyb20gYW5kIGNvdW50IHBhdHRlcm5zLgotICAgICAqLwotICAgIGFic3RyYWN0IHB1YmxpYyBTdHJpbmcgZ2V0Q291bnRlcigpOwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgPHR0Pm5vZGU8L3R0PiBhY2NvcmRpbmcgdG8gdGhlIGxldmVsIGFuZCAKLSAgICAgKiB0aGUgZnJvbSBhbmQgY291bnQgcGF0dGVybnMuIFRoaXMgcG9zaXRpb24gaXMgY29udmVydGVkIGludG8gYQotICAgICAqIHN0cmluZyBiYXNlZCBvbiB0aGUgYXJndW1lbnRzIHBhc3NlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldENvdW50ZXIoU3RyaW5nIGZvcm1hdCwgU3RyaW5nIGxhbmcsIFN0cmluZyBsZXR0ZXJWYWx1ZSwKLQkJCSAgICAgU3RyaW5nIGdyb3VwU2VwLCBTdHJpbmcgZ3JvdXBTaXplKSB7Ci0Jc2V0Rm9ybWF0dGluZyhmb3JtYXQsIGxhbmcsIGxldHRlclZhbHVlLCBncm91cFNlcCwgZ3JvdXBTaXplKTsKLQlyZXR1cm4gZ2V0Q291bnRlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiA8dHQ+bm9kZTwvdHQ+IG1hdGNoZXMgdGhlIGNvdW50IHBhdHRlcm4uIEJ5Ci0gICAgICogZGVmYXVsdCBhIG5vZGUgbWF0Y2hlcyB0aGUgY291bnQgcGF0dGVybnMgaWYgaXQgaXMgb2YgdGhlIAotICAgICAqIHNhbWUgdHlwZSBhcyB0aGUgc3RhcnRpbmcgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzQ291bnQoaW50IG5vZGUpIHsKLQlyZXR1cm4gX25vZGVUeXBlID09IF9kb2N1bWVudC5nZXRUeXBlKG5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdHJ1ZSBpZiA8dHQ+bm9kZTwvdHQ+IG1hdGNoZXMgdGhlIGZyb20gcGF0dGVybi4gQnkgZGVmYXVsdCwgCi0gICAgICogbm8gbm9kZSBtYXRjaGVzIHRoZSBmcm9tIHBhdHRlcm4uCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlc0Zyb20oaW50IG5vZGUpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRm9ybWF0IGEgc2luZ2xlIHZhbHVlIGFjY29yZGluZyB0byB0aGUgZm9ybWF0IHBhcmFtZXRlcnMuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIFN0cmluZyBmb3JtYXROdW1iZXJzKGludCB2YWx1ZSkgewotCXJldHVybiBmb3JtYXROdW1iZXJzKG5ldyBpbnRbXSB7IHZhbHVlIH0pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEZvcm1hdCBhIHNlcXVlbmNlIG9mIHZhbHVlcyBhY2NvcmRpbmcgdG8gdGhlIGZvcm1hdCBwYXJhbWF0ZXJzCi0gICAgICogc2V0IGJ5IGNhbGxpbmcgc2V0Rm9ybWF0dGluZygpLgotICAgICAqLwotICAgIHByb3RlY3RlZCBTdHJpbmcgZm9ybWF0TnVtYmVycyhpbnRbXSB2YWx1ZXMpIHsKLQlmaW5hbCBpbnQgblZhbHVlcyA9IHZhbHVlcy5sZW5ndGg7Ci0JZmluYWwgaW50IGxlbmd0aCA9IF9mb3JtYXQubGVuZ3RoKCk7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBzZXBhclRva3MgPSBuZXcgVmVjdG9yKCk7Ci0gICAgICAgIGZpbmFsIFZlY3RvciBmb3JtYXRUb2tzID0gbmV3IFZlY3RvcigpOwotCi0gICAgICAgIGJvb2xlYW4gaXNGaXJzdCA9IHRydWU7Ci0JYm9vbGVhbiBzZXBhckZpcnN0ID0gdHJ1ZTsKLQlib29sZWFuIGlzRW1wdHkgPSB0cnVlOwotCi0JZm9yIChpbnQgdD0wOyB0PG5WYWx1ZXM7IHQrKykKLQkgICAgaWYgKHZhbHVlc1t0XSAhPSBJbnRlZ2VyLk1JTl9WQUxVRSkgaXNFbXB0eSA9IGZhbHNlOwotCWlmIChpc0VtcHR5KSByZXR1cm4oIiIpOwotCi0JLyogCi0JICogVG9rZW5pemUgdGhlIGZvcm1hdCBzdHJpbmcgaW50byBhbHBoYW51bWVyaWMgYW5kIG5vbi1hbHBoYW51bWVyaWMKLQkgKiB0b2tlbnMgYXMgZGVzY3JpYmVkIGluIE0uIEtheSBwYWdlIDI0MS4KLQkgKi8KLQlmb3IgKGludCBqID0gMCwgaSA9IDA7IGkgPCBsZW5ndGg7KSB7Ci0gICAgICAgICAgICBjaGFyIGMgPSBfZm9ybWF0LmNoYXJBdChpKTsKLSAgICAgICAgICAgIGZvciAoaiA9IGk7IENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoYyk7KSB7Ci0gICAgICAgICAgICAgICAgaWYgKCsraSA9PSBsZW5ndGgpIGJyZWFrOwotCQljID0gX2Zvcm1hdC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoaSA+IGopIHsKLSAgICAgICAgICAgICAgICBpZiAoaXNGaXJzdCkgewotICAgICAgICAgICAgICAgICAgICBzZXBhclRva3MuYWRkRWxlbWVudCgiLiIpOwotICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0ID0gc2VwYXJGaXJzdCA9IGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBmb3JtYXRUb2tzLmFkZEVsZW1lbnQoX2Zvcm1hdC5zdWJzdHJpbmcoaiwgaSkpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoaSA9PSBsZW5ndGgpIGJyZWFrOwotCi0gICAgICAgICAgICBjID0gX2Zvcm1hdC5jaGFyQXQoaSk7Ci0gICAgICAgICAgICBmb3IgKGogPSBpOyAhQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdChjKTspIHsKLSAgICAgICAgICAgICAgICBpZiAoKytpID09IGxlbmd0aCkgYnJlYWs7Ci0gICAgICAgICAgICAgICAgYyA9IF9mb3JtYXQuY2hhckF0KGkpOwotICAgICAgICAgICAgICAgIGlzRmlyc3QgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChpID4gaikgewotICAgICAgICAgICAgICAgIHNlcGFyVG9rcy5hZGRFbGVtZW50KF9mb3JtYXQuc3Vic3RyaW5nKGosIGkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAKLQkvKiAKLQkgKiBGb3JtYXQgdGhlIG91dHB1dCBzdHJpbmcgdXNpbmcgdGhlIHZhbHVlcyBhcnJheSBhbmQgdGhlIHRva2VucwotCSAqIGp1c3QgcGFyc2VkLgotCSAqLwotCWlzRmlyc3QgPSB0cnVlOwotCWludCB0ID0gMCwgbiA9IDA7Ci0JZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotCWlmIChzZXBhckZpcnN0KSB7Ci0JICAgIGJ1ZmZlci5hcHBlbmQoKFN0cmluZykgc2VwYXJUb2tzLmVsZW1lbnRBdCh0KSk7Ci0JfQotCi0Jd2hpbGUgKG4gPCBuVmFsdWVzKSB7Ci0JICAgIGZpbmFsIGludCB2YWx1ZSA9IHZhbHVlc1tuXTsKLQkgICAgaWYgKHZhbHVlICE9IEludGVnZXIuTUlOX1ZBTFVFKSB7Ci0JCWlmICghaXNGaXJzdCkgewotCQkgICAgYnVmZmVyLmFwcGVuZCgoU3RyaW5nKSBzZXBhclRva3MuZWxlbWVudEF0KHQpKTsKLQkJfQotCQlmb3JtYXRWYWx1ZSh2YWx1ZSwgKFN0cmluZykgZm9ybWF0VG9rcy5lbGVtZW50QXQodCsrKSwgYnVmZmVyKTsKLQkJaWYgKHQgPT0gZm9ybWF0VG9rcy5zaXplKCkpIHsKLQkJICAgIHQtLTsKLQkJfQotCQlpc0ZpcnN0ID0gZmFsc2U7Ci0JICAgIH0KLQkgICAgbisrOwotCX0KLQotCWZpbmFsIGludCBuU2VwYXJzID0gc2VwYXJUb2tzLnNpemUoKTsKLQlpZiAoblNlcGFycyA+IGZvcm1hdFRva3Muc2l6ZSgpKSB7Ci0JICAgIGJ1ZmZlci5hcHBlbmQoKFN0cmluZykgc2VwYXJUb2tzLmVsZW1lbnRBdChuU2VwYXJzIC0gMSkpOwotCX0KLQlyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRm9ybWF0IGEgc2luZ2xlIHZhbHVlIGJhc2VkIG9uIHRoZSBhcHByb3ByaWF0ZSBmb3JtYXR0aW5nIHRva2VuLiAKLSAgICAgKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiBzYXhvbiAoTWljaGFlbCBLYXkpIGFuZCBvbmx5IGltcGxlbWVudHMKLSAgICAgKiBsYW5nPSJlbiIuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGZvcm1hdFZhbHVlKGludCB2YWx1ZSwgU3RyaW5nIGZvcm1hdCwgU3RyaW5nQnVmZmVyIGJ1ZmZlcikgewotICAgICAgICBjaGFyIGMgPSBmb3JtYXQuY2hhckF0KDApOwotICAgICAgICBpZiAoQ2hhcmFjdGVyLmlzRGlnaXQoYykpIHsKLSAgICAgICAgICAgIGNoYXIgemVybyA9IChjaGFyKShjIC0gQ2hhcmFjdGVyLmdldE51bWVyaWNWYWx1ZShjKSk7Ci0KLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciB0ZW1wID0gYnVmZmVyOwotICAgICAgICAgICAgaWYgKF9ncm91cFNpemUgPiAwKSB7Ci0gICAgICAgICAgICAgICAgdGVtcCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIFN0cmluZyBzID0gIiI7Ci0gICAgICAgICAgICBpbnQgbiA9IHZhbHVlOwotICAgICAgICAgICAgd2hpbGUgKG4gPiAwKSB7Ci0gICAgICAgICAgICAgICAgcyA9IChjaGFyKSAoKGludCkgemVybyArIChuICUgMTApKSArIHM7Ci0gICAgICAgICAgICAgICAgbiA9IG4gLyAxMDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9ybWF0Lmxlbmd0aCgpIC0gcy5sZW5ndGgoKTsgaSsrKSB7Ci0gICAgICAgICAgICAgICAgdGVtcC5hcHBlbmQoemVybyk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0ZW1wLmFwcGVuZChzKTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgaWYgKF9ncm91cFNpemUgPiAwKSB7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZW1wLmxlbmd0aCgpOyBpKyspIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT0gMCAmJiAoKHRlbXAubGVuZ3RoKCkgLSBpKSAlIF9ncm91cFNpemUpID09IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoX2dyb3VwU2VwKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHRlbXAuY2hhckF0KGkpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0gCi0JZWxzZSBpZiAoYyA9PSAnaScgJiYgIV9sZXR0ZXJWYWx1ZS5lcXVhbHMoImFscGhhYmV0aWMiKSkgewotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChyb21hblZhbHVlKHZhbHVlKSk7Ci0gICAgICAgIH0gCi0JZWxzZSBpZiAoYyA9PSAnSScgJiYgIV9sZXR0ZXJWYWx1ZS5lcXVhbHMoImFscGhhYmV0aWMiKSkgewotICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChyb21hblZhbHVlKHZhbHVlKS50b1VwcGVyQ2FzZSgpKTsKLSAgICAgICAgfSAKLQllbHNlIHsKLSAgICAgICAgICAgIGludCBtaW4gPSAoaW50KSBjOwotICAgICAgICAgICAgaW50IG1heCA9IChpbnQpIGM7Ci0gICAgICAgICAgICB3aGlsZSAoQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdCgoY2hhcikgKG1heCsxKSkpIHsKLQkJbWF4Kys7Ci0JICAgIH0KLSAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoYWxwaGFWYWx1ZSh2YWx1ZSwgbWluLCBtYXgpKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIHByaXZhdGUgU3RyaW5nIGFscGhhVmFsdWUoaW50IHZhbHVlLCBpbnQgbWluLCBpbnQgbWF4KSB7Ci0gICAgICAgIGlmICh2YWx1ZSA8PSAwKSB7Ci0JICAgIHJldHVybiAiIiArIHZhbHVlOwotCX0KLQotICAgICAgICBpbnQgcmFuZ2UgPSBtYXggLSBtaW4gKyAxOwotICAgICAgICBjaGFyIGxhc3QgPSAoY2hhcikoKCh2YWx1ZS0xKSAlIHJhbmdlKSArIG1pbik7Ci0gICAgICAgIGlmICh2YWx1ZSA+IHJhbmdlKSB7Ci0gICAgICAgICAgICByZXR1cm4gYWxwaGFWYWx1ZSgodmFsdWUtMSkgLyByYW5nZSwgbWluLCBtYXgpICsgbGFzdDsKLSAgICAgICAgfSAKLQllbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAiIiArIGxhc3Q7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICBwcml2YXRlIFN0cmluZyByb21hblZhbHVlKGludCBuKSB7Ci0gICAgICAgIGlmIChuIDw9IDAgfHwgbiA+IDQwMDApIHsKLQkgICAgcmV0dXJuICIiICsgbjsKLQl9Ci0gICAgICAgIHJldHVybgotCSAgICBUaG91c2FuZHNbbiAvIDEwMDBdICsKLQkgICAgSHVuZHJlZHNbKG4gLyAxMDApICUgMTBdICsKLQkgICAgVGVuc1sobi8xMCkgJSAxMF0gKwotCSAgICBPbmVzW24gJSAxMF07Ci0gICAgfQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZUl0ZXJhdG9yQmFzZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL05vZGVJdGVyYXRvckJhc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTExZmZjYi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZUl0ZXJhdG9yQmFzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5CYXNpc0xpYnJhcnk7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBOb2RlSXRlcmF0b3JCYXNlIGltcGxlbWVudHMgTm9kZUl0ZXJhdG9yIHsKLSAgICBwcml2YXRlIGludCBfbGFzdCA9IC0xOwotICAgIHByaXZhdGUgaW50IF9wb3NpdGlvbiA9IDA7Ci0KLSAgICBwcm90ZWN0ZWQgaW50IF9tYXJrZWROb2RlOwotICAgIHByb3RlY3RlZCBpbnQgX3N0YXJ0Tm9kZSA9IE5vZGVJdGVyYXRvci5FTkQ7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gX2luY2x1ZGVTZWxmID0gZmFsc2U7Ci0gICAgcHJvdGVjdGVkIGJvb2xlYW4gX2lzUmVzdGFydGFibGUgPSB0cnVlOwotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlmaW5hbCBib29sZWFuIHRlbXAgPSBfaXNSZXN0YXJ0YWJsZTsKLQlfaXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0Jc2V0U3RhcnROb2RlKF9zdGFydE5vZGUpOwotCV9pc1Jlc3RhcnRhYmxlID0gdGVtcDsKLQlyZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGluY2x1ZGVTZWxmKCkgewotCV9pbmNsdWRlU2VsZiA9IHRydWU7Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCWlmIChfbGFzdCA9PSAtMSkgewotCSAgICBmaW5hbCBpbnQgdGVtcCA9IF9wb3NpdGlvbjsKLQkgICAgc2V0TWFyaygpOwotCSAgICByZXNldCgpOwotCSAgICBkbyB7Ci0JCV9sYXN0Kys7Ci0JICAgIH0gd2hpbGUgKG5leHQoKSAhPSBFTkQpOwotCSAgICBnb3RvTWFyaygpOwotCSAgICBfcG9zaXRpb24gPSB0ZW1wOwotCX0KLQlyZXR1cm4gX2xhc3Q7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRQb3NpdGlvbigpIHsKLQlyZXR1cm4gX3Bvc2l0aW9uID09IDAgPyAxIDogX3Bvc2l0aW9uOwotICAgIH0KLQotICAgIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpIHsKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQl0cnkgewotCSAgICBmaW5hbCBOb2RlSXRlcmF0b3JCYXNlIGNsb25lID0gKE5vZGVJdGVyYXRvckJhc2Upc3VwZXIuY2xvbmUoKTsKLQkgICAgY2xvbmUuX2lzUmVzdGFydGFibGUgPSBmYWxzZTsKLQkgICAgcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0JfQotCWNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHJvdGVjdGVkIGZpbmFsIGludCByZXR1cm5Ob2RlKGZpbmFsIGludCBub2RlKSB7Ci0JX3Bvc2l0aW9uKys7Ci0JcmV0dXJuIG5vZGU7Ci0gICAgfQotICAgIAotICAgIHByb3RlY3RlZCBmaW5hbCBOb2RlSXRlcmF0b3IgcmVzZXRQb3NpdGlvbigpIHsKLQlfcG9zaXRpb24gPSAwOwotCXJldHVybiB0aGlzOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL05vZGVTb3J0UmVjb3JkLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTkxZmZmMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTm9kZVNvcnRSZWNvcmQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyNSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOwotaW1wb3J0IGphdmEudGV4dC5Db2xsYXRpb25LZXk7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLQotLyoqCi0gKiBCYXNlIGNsYXNzIGZvciBzb3J0IHJlY29yZHMgY29udGFpbmluZyBhcHBsaWNhdGlvbiBzcGVjaWZpYyBzb3J0IGtleXMgCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBOb2RlU29ydFJlY29yZCB7Ci0gICAgcHVibGljIHN0YXRpYyBpbnQgQ09NUEFSRV9TVFJJTkcgICAgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGludCBDT01QQVJFX05VTUVSSUMgICAgPSAxOwotCi0gICAgcHVibGljIHN0YXRpYyBpbnQgQ09NUEFSRV9BU0NFTkRJTkcgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGludCBDT01QQVJFX0RFU0NFTkRJTkcgPSAxOwotCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBDb2xsYXRvciBfY29sbGF0b3IgPSBDb2xsYXRvci5nZXRJbnN0YW5jZSgpOwotICAgIHByb3RlY3RlZCBzdGF0aWMgaW50W10gX2NvbXBhcmVUeXBlOwotICAgIHByb3RlY3RlZCBzdGF0aWMgaW50W10gX3NvcnRPcmRlcjsKLSAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBfbGV2ZWxzID0gMTsKLQotICAgIHByaXZhdGUgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQgPSBudWxsOwotCi0gICAgcHJpdmF0ZSBET00gICAgX2RvbSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBpbnQgICAgX25vZGU7ICAgICAgICAgICAvLyBUaGUgcG9zaXRpb24gaW4gdGhlIGN1cnJlbnQgaXRlcmF0b3IKLSAgICBwcml2YXRlIGludCAgICBfbGFzdCA9IDA7ICAgICAgIC8vIE51bWJlciBvZiBub2RlcyBpbiB0aGUgY3VycmVudCBpdGVyYXRvcgotICAgIHByaXZhdGUgaW50ICAgIF9zY2FubmVkID0gMDsgICAgLy8gTnVtYmVyIG9mIGtleSBsZXZlbHMgZXh0cmFjdGVkIGZyb20gRE9NCi0KLSAgICBwcml2YXRlIE9iamVjdFtdIF92YWx1ZXM7IC8vIENvbnRhaW5zIGVpdGhlciBDb2xsYXRpb25LZXkgb3IgRG91YmxlCi0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNvbnN0cnVjdG9yIGlzIHJ1biBieSBhIGNhbGwgdG8gQ2xhc3MuZm9yTmFtZSgpIGluIHRoZQotICAgICAqIG1ha2VOb2RlU29ydFJlY29yZCBtZXRob2QgaW4gdGhlIE5vZGVTb3J0UmVjb3JkRmFjdG9yeSBjbGFzcy4gU2luY2Ugd2UKLSAgICAgKiBjYW5ub3QgcGFzcyBhbnkgcGFyYW1ldGVycyB0byB0aGUgY29uc3RydWN0b3IgaW4gdGhhdCBjYXNlIHdlIGp1c3Qgc2V0Ci0gICAgICogdGhlIGRlZmF1bHQgdmFsdWVzIGhlcmUgYW5kIHdhaXQgZm9yIG5ldyB2YWx1ZXMgdGhyb3VnaCBpbml0aWFsaXplKCkuCi0gICAgICovIAotICAgIHB1YmxpYyBOb2RlU29ydFJlY29yZChpbnQgbm9kZSkgewotCV9ub2RlID0gbm9kZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZVNvcnRSZWNvcmQoKSB7Ci0gICAgICAgIHRoaXMoMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgYWxsb3dzIHRoZSBjYWxsZXIgdG8gc2V0IHRoZSB2YWx1ZXMgdGhhdCBjb3VsZCBub3QgYmUgcGFzc2VkCi0gICAgICogdG8gdGhlIGRlZmF1bHQgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgaW5pdGlhbGl6ZShpbnQgbm9kZSwgaW50IGxhc3QsIERPTSBkb20sCi0JCQkJIEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQpIHsKLQlfZG9tID0gZG9tOwotCV9ub2RlID0gbm9kZTsKLQlfbGFzdCA9IGxhc3Q7Ci0JX3RyYW5zbGV0ID0gdHJhbnNsZXQ7Ci0JX3NjYW5uZWQgPSAwOwotCi0JX3ZhbHVlcyA9IG5ldyBPYmplY3RbX2xldmVsc107Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgbm9kZSBmb3IgdGhpcyBzb3J0IG9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Tm9kZSgpIHsKLQlyZXR1cm4gX25vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICoKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgaW50IGNvbXBhcmVEb2NPcmRlcihOb2RlU29ydFJlY29yZCBvdGhlcikgewotCXJldHVybiBfbm9kZSAtIG90aGVyLl9ub2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgc3RyaW5nIG9yIG51bWVyaWMgdmFsdWUgb2YgYSBzcGVjaWZpYyBsZXZlbCBrZXkgZm9yIHRoaXMgc29ydAotICAgICAqIGVsZW1lbnQuIFRoZSB2YWx1ZSBpcyBleHRyYWN0ZWQgZnJvbSB0aGUgRE9NIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGluCi0gICAgICogb3VyIHNvcnQga2V5IHZlY3Rvci4KLSAgICAgKi8KLSAgICBwcml2YXRlIGZpbmFsIENvbGxhdGlvbktleSBzdHJpbmdWYWx1ZShpbnQgbGV2ZWwpIHsKLQkvLyBHZXQgdmFsdWUgZnJvbSBvdXIgYXJyYXkgaWYgcG9zc2libGUKLQlpZiAoX3NjYW5uZWQgPD0gbGV2ZWwpIHsKLQkgICAgLy8gR2V0IHZhbHVlIGZyb20gRE9NIGlmIGFjY2Vzc2VkIGZvciB0aGUgZmlyc3QgdGltZQotCSAgICBmaW5hbCBTdHJpbmcgc3RyID0gZXh0cmFjdFZhbHVlRnJvbURPTShfZG9tLCBfbm9kZSwgbGV2ZWwsCi0JCQkJCQkgICBfdHJhbnNsZXQsIF9sYXN0KTsKLQkgICAgZmluYWwgQ29sbGF0aW9uS2V5IGtleSA9IF9jb2xsYXRvci5nZXRDb2xsYXRpb25LZXkoc3RyKTsKLQkgICAgX3ZhbHVlc1tfc2Nhbm5lZCsrXSA9IGtleTsKLQkgICAgcmV0dXJuKGtleSk7Ci0JfQotCXJldHVybigoQ29sbGF0aW9uS2V5KV92YWx1ZXNbbGV2ZWxdKTsKLSAgICB9Ci0gICAgCi0gICAgcHJpdmF0ZSBmaW5hbCBEb3VibGUgbnVtZXJpY1ZhbHVlKGludCBsZXZlbCkgewotCS8vIEdldCB2YWx1ZSBmcm9tIG91ciB2ZWN0b3IgaWYgcG9zc2libGUKLQlpZiAoX3NjYW5uZWQgPD0gbGV2ZWwpIHsKLQkgICAgLy8gR2V0IHZhbHVlIGZyb20gRE9NIGlmIGFjY2Vzc2VkIGZvciB0aGUgZmlyc3QgdGltZQotCSAgICBmaW5hbCBTdHJpbmcgc3RyID0gZXh0cmFjdFZhbHVlRnJvbURPTShfZG9tLCBfbm9kZSwgbGV2ZWwsCi0JCQkJCQkgICBfdHJhbnNsZXQsIF9sYXN0KTsKLQkgICAgRG91YmxlIG51bTsKLQkgICAgdHJ5IHsKLQkJbnVtID0gbmV3IERvdWJsZShzdHIpOwotCSAgICB9Ci0JICAgIC8vIFRyZWF0IG51bWJlciBhcyBOYU4gaWYgaXQgY2Fubm90IGJlIHBhcnNlZCBhcyBhIGRvdWJsZQotCSAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLQkJbnVtID0gbmV3IERvdWJsZShEb3VibGUuTmFOKTsKLQkgICAgfQotCSAgICBfdmFsdWVzW19zY2FubmVkKytdID0gbnVtOwotCSAgICByZXR1cm4obnVtKTsKLQl9Ci0JcmV0dXJuKChEb3VibGUpX3ZhbHVlc1tsZXZlbF0pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbXBhcmUgdGhpcyBzb3J0IGVsZW1lbnQgdG8gYW5vdGhlci4gVGhlIGZpcnN0IGxldmVsIGlzIGNoZWNrZWQgZmlyc3QsCi0gICAgICogYW5kIHdlIHByb2NlZWQgdG8gdGhlIG5leHQgbGV2ZWwgb25seSBpZiB0aGUgZmlyc3QgbGV2ZWwga2V5cyBhcmUKLSAgICAgKiBpZGVudGljYWwgKGFuZCBzbyB0aGUga2V5IHZhbHVlcyBtYXkgbm90IGV2ZW4gYmUgZXh0cmFjdGVkIGZyb20gdGhlIERPTSkKLSAgICAgKgotICAgICAqICEhISFNVVNUIE9QVElNSVNFIC0gVEhJUyBJUyBSRUFMTFksIFJFQUxMWSBTTE9XISEhIQotICAgICAqLwotICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE5vZGVTb3J0UmVjb3JkIG90aGVyKSB7Ci0JaW50IGNtcCwgbGV2ZWw7Ci0JZm9yIChsZXZlbCA9IDA7IGxldmVsIDwgX2xldmVsczsgbGV2ZWwrKykgewotCSAgICAvLyBDb21wYXJlIHRoZSB0d28gbm9kZXMgZWl0aGVyIGFzIG51bWVyaWMgb3IgdGV4dCB2YWx1ZXMKLQkgICAgaWYgKF9jb21wYXJlVHlwZVtsZXZlbF0gPT0gQ09NUEFSRV9OVU1FUklDKSB7Ci0JCWZpbmFsIERvdWJsZSBvdXIgPSBudW1lcmljVmFsdWUobGV2ZWwpOwotCQlmaW5hbCBEb3VibGUgdGhlaXIgPSBvdGhlci5udW1lcmljVmFsdWUobGV2ZWwpOwotCQljbXAgPSBvdXIuY29tcGFyZVRvKHRoZWlyKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJZmluYWwgQ29sbGF0aW9uS2V5IG91ciA9IHN0cmluZ1ZhbHVlKGxldmVsKTsKLQkJZmluYWwgQ29sbGF0aW9uS2V5IHRoZWlyID0gb3RoZXIuc3RyaW5nVmFsdWUobGV2ZWwpOwotCQljbXAgPSBvdXIuY29tcGFyZVRvKHRoZWlyKTsKLQkgICAgfQotCSAgICAKLQkgICAgLy8gUmV0dXJuIGludmVyc2UgY29tcGFyZSB2YWx1ZSBpZiBpbnZlcnNlIHNvcnQgb3JkZXIKLQkgICAgaWYgKGNtcCAhPSAwKSB7Ci0JCXJldHVybiBfc29ydE9yZGVyW2xldmVsXSA9PSBDT01QQVJFX0RFU0NFTkRJTkcgPyAwIC0gY21wIDogY21wOwotCSAgICB9Ci0JfQotCS8vIENvbXBhcmUgYmFzZWQgb24gZG9jdW1lbnQgb3JkZXIgaWYgYWxsIHNvcnQga2V5cyBhcmUgZXF1YWwKLQlyZXR1cm4oX25vZGUgLSBvdGhlci5fbm9kZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgQ29sbGF0b3IgdXNlZCBmb3IgdGV4dCBjb21wYXJpc29ucyBpbiB0aGlzIG9iamVjdC4KLSAgICAgKiBNYXkgYmUgb3ZlcnJpZGRlbiBieSBpbmhlcml0aW5nIGNsYXNzZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgQ29sbGF0b3IgZ2V0Q29sbGF0b3IoKSB7Ci0JcmV0dXJuIF9jb2xsYXRvcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRyYWN0IHRoZSBzb3J0IHZhbHVlIGZvciBhIGxldmVsIG9mIHRoaXMga2V5LgotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZXh0cmFjdFZhbHVlRnJvbURPTShET00gZG9tLCBpbnQgY3VycmVudCwgaW50IGxldmVsLAotCQkJCQkgICAgICAgQWJzdHJhY3RUcmFuc2xldCB0cmFuc2xldCwKLQkJCQkJICAgICAgIGludCBsYXN0KTsKLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL05vZGVTb3J0UmVjb3JkRmFjdG9yeS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL05vZGVTb3J0UmVjb3JkRmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxM2U1YzQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Ob2RlU29ydFJlY29yZEZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLQotcHVibGljIGNsYXNzIE5vZGVTb3J0UmVjb3JkRmFjdG9yeSB7Ci0gICAgcHJpdmF0ZSBmaW5hbCBET00gICAgICBfZG9tOwotICAgIHByaXZhdGUgZmluYWwgQ2xhc3MgICAgX2NsYXNzOwotICAgIHByaXZhdGUgZmluYWwgU3RyaW5nICAgX2NsYXNzTmFtZTsKLQotICAgIHByaXZhdGUgZmluYWwgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQ7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgTm9kZVNvcnRSZWNvcmQgcHJvZHVjaW5nIG9iamVjdC4gVGhlIERPTSBzcGVjaWZpZXMgd2hpY2ggdHJlZQotICAgICAqIHRvIGdldCB0aGUgbm9kZXMgdG8gc29ydCBmcm9tLCB0aGUgY2xhc3MgbmFtZSBzcGVjaWZpZXMgd2hhdCBhdXhpbGxhcnkKLSAgICAgKiBjbGFzcyB0byB1c2UgdG8gc29ydCB0aGUgbm9kZXMgKHRoaXMgY2xhc3MgaXMgZ2VuZXJhdGVkIGJ5IHRoZSBTb3J0Ci0gICAgICogY2xhc3MpLCBhbmQgdGhlIHRyYW5zbGV0IHBhcmFtZXRlciBpcyBuZWVkZWQgZm9yIG1ldGhvZHMgY2FsbGVkIGJ5Ci0gICAgICogdGhpcyBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVTb3J0UmVjb3JkRmFjdG9yeShET00gZG9tLCBTdHJpbmcgY2xhc3NOYW1lLCBUcmFuc2xldCB0cmFuc2xldCkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCXRyeSB7Ci0JICAgIF9kb20gPSBkb207Ci0JICAgIF9jbGFzc05hbWUgPSBjbGFzc05hbWU7Ci0JICAgIF9jbGFzcyA9IENsYXNzLmZvck5hbWUoY2xhc3NOYW1lKTsKLQkgICAgX3RyYW5zbGV0ID0gKEFic3RyYWN0VHJhbnNsZXQpdHJhbnNsZXQ7Ci0JfQotCWNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKCJDb3VsZCBub3QgZmluZCBjbGFzcyAiICsgY2xhc3NOYW1lKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgc3ViLWNsYXNzIG9mIE5vZGVTb3J0UmVjb3JkLiBUaGUgbmFtZSBvZiB0aGlzCi0gICAgICogc3ViLWNsYXNzIGlzIHBhc3NlZCB0byB1cyBpbiB0aGUgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVTb3J0UmVjb3JkIG1ha2VOb2RlU29ydFJlY29yZChpbnQgbm9kZSwgaW50IGxhc3QpCi0JdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciwKLQkgICAgICAgTGlua2FnZUVycm9yLAotCSAgICAgICBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLAotCSAgICAgICBJbnN0YW50aWF0aW9uRXhjZXB0aW9uLAotCSAgICAgICBTZWN1cml0eUV4Y2VwdGlvbiwKLQkgICAgICAgVHJhbnNsZXRFeGNlcHRpb24gewotCi0JZmluYWwgTm9kZVNvcnRSZWNvcmQgc29ydFJlY29yZCA9Ci0JICAgIChOb2RlU29ydFJlY29yZClfY2xhc3MubmV3SW5zdGFuY2UoKTsKLQlzb3J0UmVjb3JkLmluaXRpYWxpemUobm9kZSwgbGFzdCwgX2RvbSwgX3RyYW5zbGV0KTsKLQlyZXR1cm4gc29ydFJlY29yZDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLQlyZXR1cm4gX2NsYXNzTmFtZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vTnRoSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9OdGhJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjY2RlMTYyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9OdGhJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgTnRoSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLSAgICAvLyAuLi5bTl0KLSAgICBwcml2YXRlIGZpbmFsIGludCBfcG9zaXRpb247Ci0gICAgcHJpdmF0ZSBmaW5hbCBOb2RlSXRlcmF0b3IgX3NvdXJjZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX3JlYWR5OwotCi0gICAgcHVibGljIE50aEl0ZXJhdG9yKE5vZGVJdGVyYXRvciBzb3VyY2UsIGludCBuKSB7Ci0JX3NvdXJjZSA9IHNvdXJjZTsKLQlfcG9zaXRpb24gPSBuOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0JaWYgKF9yZWFkeSAmJiBfcG9zaXRpb24gPiAwKSB7Ci0JICAgIF9yZWFkeSA9IGZhbHNlOwotCSAgICAvLyBza2lwIE4tMSBub2RlcwotCSAgICBmb3IgKGludCBuID0gX3Bvc2l0aW9uIC0gMTsgbi0tID4gMDspIHsKLQkJaWYgKF9zb3VyY2UubmV4dCgpID09IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkJICAgIHJldHVybiBOb2RlSXRlcmF0b3IuRU5EOwotCQl9Ci0JICAgIH0KLQkgICAgcmV0dXJuIF9zb3VyY2UubmV4dCgpOwotCX0KLQlyZXR1cm4gTm9kZUl0ZXJhdG9yLkVORDsKLSAgICB9Ci0JCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoZmluYWwgaW50IG5vZGUpIHsKLQlfc291cmNlLnNldFN0YXJ0Tm9kZShub2RlKTsKLQlfcmVhZHkgPSB0cnVlOwotCXJldHVybiB0aGlzOwotICAgIH0KLQkKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIHJlc2V0KCkgewotCV9zb3VyY2UucmVzZXQoKTsKLQlyZXR1cm4gdGhpczsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCXJldHVybiAxOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgewotCXJldHVybiAxOwotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKSB7Ci0JcmV0dXJuIF9zb3VyY2UuaXNSZXZlcnNlKCk7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKSB7Ci0JX3NvdXJjZS5zZXRNYXJrKCk7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCkgewotCV9zb3VyY2UuZ290b01hcmsoKTsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotCS8vISEgbm90IGNsZWFyIHdoZW4gY2xvbmluZyBpcyBwZXJmb3JtZWQKLQkvLyBhbmQgd2hhdCdzIHRoZSBkZXNpcmVkIHN0YXRlIG9mIHRoZSBuZXcgY2xvbmUKLQlyZXR1cm4gbmV3IE50aEl0ZXJhdG9yKF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpLCBfcG9zaXRpb24pOwotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL1JldmVyc2VJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL1JldmVyc2VJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MGU3MTZiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9SZXZlcnNlSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXRFeGNlcHRpb247Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBSZXZlcnNlSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBJTklUX0RBVEFfU0laRSA9IDE2OwotICAgIHByaXZhdGUgZmluYWwgTm9kZUl0ZXJhdG9yIF9zb3VyY2U7Ci0gICAgcHJpdmF0ZSBpbnRbXSBfZGF0YSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBpbnQgX2xhc3QgPSAwOwotICAgIHByaXZhdGUgaW50IF9jdXJyZW50ID0gMDsKLSAgICBwcml2YXRlIGludCBfc3RhcnQgPSAtMTsKLQotICAgIHB1YmxpYyBSZXZlcnNlSXRlcmF0b3IoTm9kZUl0ZXJhdG9yIHNvdXJjZSkgewotCV9zb3VyY2UgPSBzb3VyY2U7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBuZXh0KCkgewotCXJldHVybiBfY3VycmVudCA+IDAgPyBfZGF0YVstLV9jdXJyZW50XSA6IEVORDsKLSAgICB9Ci0JCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlpZiAoKF9kYXRhID09IG51bGwpIHx8IChub2RlICE9IF9zdGFydCkpIHsKLQkgICAgX3N0YXJ0ID0gbm9kZTsKLQkgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUobm9kZSk7Ci0JICAgIF9kYXRhID0gbmV3IGludFtJTklUX0RBVEFfU0laRV07Ci0JICAgIF9sYXN0ID0gMDsKLQkgICAgLy8gZ2F0aGVyIGFsbCBub2RlcyBmcm9tIHRoZSBzb3VyY2UgaXRlcmF0b3IKLQkgICAgd2hpbGUgKChub2RlID0gX3NvdXJjZS5uZXh0KCkpICE9IEVORCkgewotCQlpZiAoX2xhc3QgPT0gX2RhdGEubGVuZ3RoKSB7Ci0JCSAgICBpbnRbXSBuZXdBcnJheSA9IG5ldyBpbnRbX2RhdGEubGVuZ3RoICogMl07Ci0JCSAgICBTeXN0ZW0uYXJyYXljb3B5KF9kYXRhLCAwLCBuZXdBcnJheSwgMCwgX2xhc3QpOwotCQkgICAgX2RhdGEgPSBuZXdBcnJheTsKLQkJfQotCQlfZGF0YVtfbGFzdCsrXSA9IG5vZGU7Ci0JICAgIH0KLQl9Ci0KLQlfY3VycmVudCA9IF9sYXN0OwotCXJldHVybiB0aGlzOwotICAgIH0KLQkKLSAgICBwdWJsaWMgaW50IGdldFBvc2l0aW9uKCkgewotCXJldHVybiAoX2xhc3QgLSBfY3VycmVudCk7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCXJldHVybiBfbGFzdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9zb3VyY2Uuc2V0TWFyaygpOwotCV9tYXJrZWROb2RlID0gX2N1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JX3NvdXJjZS5nb3RvTWFyaygpOwotCV9jdXJyZW50ID0gX21hcmtlZE5vZGU7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vU2luZ2xlTm9kZUNvdW50ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TaW5nbGVOb2RlQ291bnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYTg2NDNhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TaW5nbGVOb2RlQ291bnRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY0ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTaW5nbGVOb2RlQ291bnRlciBleHRlbmRzIE5vZGVDb3VudGVyIHsKLSAgICBzdGF0aWMgcHJpdmF0ZSBmaW5hbCBpbnRbXSBFbXB0eUFycmF5ID0gbmV3IGludFtdIHsgfTsKLSAgICBOb2RlSXRlcmF0b3IgX2NvdW50U2libGluZ3MgPSBudWxsOwotCi0gICAgcHVibGljIFNpbmdsZU5vZGVDb3VudGVyKFRyYW5zbGV0IHRyYW5zbGV0LAotCQkJICAgICBET00gZG9jdW1lbnQsCi0JCQkgICAgIE5vZGVJdGVyYXRvciBpdGVyYXRvcikgewotCXN1cGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlQ291bnRlciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlfbm9kZSA9IG5vZGU7Ci0JX25vZGVUeXBlID0gX2RvY3VtZW50LmdldFR5cGUobm9kZSk7Ci0JX2NvdW50U2libGluZ3MgPSBfZG9jdW1lbnQuZ2V0QXhpc0l0ZXJhdG9yKFBSRUNFRElOR1NJQkxJTkcpOwotCXJldHVybiB0aGlzOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q291bnRlcigpIHsKLQlpbnQgcmVzdWx0OwotCWlmIChfdmFsdWUgIT0gSW50ZWdlci5NSU5fVkFMVUUpIHsKLQkgICAgcmVzdWx0ID0gX3ZhbHVlOwotCX0KLQllbHNlIHsKLQkgICAgaW50IG5leHQgPSBfbm9kZTsKLQkgICAgcmVzdWx0ID0gMDsKLQkgICAgaWYgKCFtYXRjaGVzQ291bnQobmV4dCkpIHsKLQkJd2hpbGUgKChuZXh0ID0gX2RvY3VtZW50LmdldFBhcmVudChuZXh0KSkgPiBFTkQpIHsKLQkJICAgIGlmIChtYXRjaGVzQ291bnQobmV4dCkpIHsKLQkJCWJyZWFrOwkJLy8gZm91bmQgdGFyZ2V0Ci0JCSAgICB9Ci0JCSAgICBpZiAobWF0Y2hlc0Zyb20obmV4dCkpIHsKLQkJCW5leHQgPSBFTkQ7Ci0JCQlicmVhazsJCS8vIG5vIHRhcmdldCBmb3VuZAotCQkgICAgfQotCQl9Ci0JICAgIH0KLQotCSAgICBpZiAobmV4dCAhPSBFTkQpIHsKLQkJcmVzdWx0Kys7CQkvLyBjb3VudCB0YXJnZXQKLQkJX2NvdW50U2libGluZ3Muc2V0U3RhcnROb2RlKG5leHQpOwotCQl3aGlsZSAoKG5leHQgPSBfY291bnRTaWJsaW5ncy5uZXh0KCkpICE9IEVORCkgewotCQkgICAgaWYgKG1hdGNoZXNDb3VudChuZXh0KSkgewotCQkJcmVzdWx0Kys7Ci0JCSAgICB9Ci0JCX0KLQkgICAgfQotCSAgICAvKgotCSAgICAgIGVsc2UgewotCQkJCS8vIElmIG5vIHRhcmdldCBmb3VuZCB0aGVuIHBhc3MgdGhlIGVtcHR5IGxpc3QKLQkJCQlyZXR1cm4gZm9ybWF0TnVtYmVycyhFbXB0eUFycmF5KTsKLQkJCQl9Ci0JICAgICovCi0JfQotCXJldHVybiBmb3JtYXROdW1iZXJzKHJlc3VsdCk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBOb2RlQ291bnRlciBnZXREZWZhdWx0Tm9kZUNvdW50ZXIoVHJhbnNsZXQgdHJhbnNsZXQsCi0JCQkJCQkgICAgRE9NIGRvY3VtZW50LAotCQkJCQkJICAgIE5vZGVJdGVyYXRvciBpdGVyYXRvcikgewotCXJldHVybiBuZXcgRGVmYXVsdFNpbmdsZU5vZGVDb3VudGVyKHRyYW5zbGV0LCBkb2N1bWVudCwgaXRlcmF0b3IpOwotICAgIH0KLQotICAgIHN0YXRpYyBjbGFzcyBEZWZhdWx0U2luZ2xlTm9kZUNvdW50ZXIgZXh0ZW5kcyBTaW5nbGVOb2RlQ291bnRlciB7Ci0JcHVibGljIERlZmF1bHRTaW5nbGVOb2RlQ291bnRlcihUcmFuc2xldCB0cmFuc2xldCwKLQkJCQkJRE9NIGRvY3VtZW50LCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IpIHsKLQkgICAgc3VwZXIodHJhbnNsZXQsIGRvY3VtZW50LCBpdGVyYXRvcik7Ci0JfQotCi0JcHVibGljIE5vZGVDb3VudGVyIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkgewotCSAgICBfbm9kZSA9IG5vZGU7Ci0JICAgIF9ub2RlVHlwZSA9IF9kb2N1bWVudC5nZXRUeXBlKG5vZGUpOwotCSAgICBfY291bnRTaWJsaW5ncyA9Ci0JCV9kb2N1bWVudC5nZXRUeXBlZEF4aXNJdGVyYXRvcihQUkVDRURJTkdTSUJMSU5HLAotCQkJCQkgICAgICAgX2RvY3VtZW50LmdldFR5cGUobm9kZSkpOwotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldENvdW50ZXIoKSB7Ci0JICAgIGludCByZXN1bHQ7Ci0JICAgIGlmIChfdmFsdWUgIT0gSW50ZWdlci5NSU5fVkFMVUUpIHsKLQkJcmVzdWx0ID0gX3ZhbHVlOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlpbnQgbmV4dDsKLQkJcmVzdWx0ID0gMTsKLQkJX2NvdW50U2libGluZ3Muc2V0U3RhcnROb2RlKF9ub2RlKTsKLQkJd2hpbGUgKChuZXh0ID0gX2NvdW50U2libGluZ3MubmV4dCgpKSAhPSBFTkQpIHsKLQkJICAgIHJlc3VsdCsrOwotCQl9Ci0JICAgIH0KLQkgICAgcmV0dXJuIGZvcm1hdE51bWJlcnMocmVzdWx0KTsKLQl9Ci0gICAgfQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vU2luZ2xldG9uSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TaW5nbGV0b25JdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZjQxZmI5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TaW5nbGV0b25JdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI5ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotCi1wdWJsaWMgY2xhc3MgU2luZ2xldG9uSXRlcmF0b3IgZXh0ZW5kcyBOb2RlSXRlcmF0b3JCYXNlIHsKLSAgICBwcml2YXRlIGludCBfbm9kZTsKLSAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gX2lzQ29uc3RhbnQ7Ci0KLSAgICBwdWJsaWMgU2luZ2xldG9uSXRlcmF0b3IoKSB7Ci0JdGhpcyhJbnRlZ2VyLk1JTl9WQUxVRSwgZmFsc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBTaW5nbGV0b25JdGVyYXRvcihpbnQgbm9kZSkgewotCXRoaXMobm9kZSwgZmFsc2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBTaW5nbGV0b25JdGVyYXRvcihpbnQgbm9kZSwgYm9vbGVhbiBjb25zdGFudCkgewotCV9ub2RlID0gX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0JX2lzQ29uc3RhbnQgPSBjb25zdGFudDsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogT3ZlcnJpZGUgdGhlIHZhbHVlIG9mIDx0dD5fbm9kZTwvdHQ+IG9ubHkgd2hlbiB0aGlzCi0gICAgICogb2JqZWN0IHdhcyBjb25zdHJ1Y3RlZCB1c2luZyB0aGUgZW1wdHkgY29uc3RydWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlpZiAoX2lzQ29uc3RhbnQpIHsKLQkgICAgX25vZGUgPSBfc3RhcnROb2RlOwotCSAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotCX0KLQllbHNlIGlmIChfaXNSZXN0YXJ0YWJsZSkgewotCSAgICBpZiAoX25vZGUgPD0gMCkKLQkJX25vZGUgPSBfc3RhcnROb2RlID0gbm9kZTsKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgcmVzZXQoKSB7Ci0JaWYgKF9pc0NvbnN0YW50KSB7Ci0JICAgIF9ub2RlID0gX3N0YXJ0Tm9kZTsKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIGZpbmFsIGJvb2xlYW4gdGVtcCA9IF9pc1Jlc3RhcnRhYmxlOwotCSAgICBfaXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0JICAgIHNldFN0YXJ0Tm9kZShfc3RhcnROb2RlKTsKLQkgICAgX2lzUmVzdGFydGFibGUgPSB0ZW1wOwotCX0KLQlyZXR1cm4gdGhpczsKLSAgICB9Ci0gICAgCi0gICAgcHVibGljIGludCBuZXh0KCkgewotCWZpbmFsIGludCByZXN1bHQgPSBfbm9kZTsKLQlfbm9kZSA9IE5vZGVJdGVyYXRvci5FTkQ7Ci0JcmV0dXJuIHJldHVybk5vZGUocmVzdWx0KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9tYXJrZWROb2RlID0gX25vZGU7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JX25vZGUgPSBfbWFya2VkTm9kZTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vU29ydGluZ0l0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vU29ydGluZ0l0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlkMTZjMmIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tL1NvcnRpbmdJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTYxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLQotcHVibGljIGZpbmFsIGNsYXNzIFNvcnRpbmdJdGVyYXRvciBleHRlbmRzIE5vZGVJdGVyYXRvckJhc2UgewotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBJTklUX0RBVEFfU0laRSA9IDE2OwotICAgIHByaXZhdGUgZmluYWwgTm9kZUl0ZXJhdG9yIF9zb3VyY2U7Ci0gICAgcHJpdmF0ZSBmaW5hbCBOb2RlU29ydFJlY29yZEZhY3RvcnkgX2ZhY3Rvcnk7Ci0gICAgcHJpdmF0ZSBOb2RlU29ydFJlY29yZFtdIF9kYXRhOwotICAgIHByaXZhdGUgaW50IF9mcmVlID0gMDsKLSAgICBwcml2YXRlIGludCBfY3VycmVudDsJLy8gaW5kZXggaW4gX25vZGVzIG9mIHRoZSBuZXh0IG5vZGUgdG8gdHJ5Ci0KLSAgICBwdWJsaWMgU29ydGluZ0l0ZXJhdG9yKE5vZGVJdGVyYXRvciBzb3VyY2UsIAotCQkJICAgTm9kZVNvcnRSZWNvcmRGYWN0b3J5IGZhY3RvcnkpIHsKLQlfc291cmNlID0gc291cmNlOwotCV9mYWN0b3J5ID0gZmFjdG9yeTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IG5leHQoKSB7Ci0JcmV0dXJuIF9jdXJyZW50IDwgX2ZyZWUgPyBfZGF0YVtfY3VycmVudCsrXS5nZXROb2RlKCkgOiBFTkQ7Ci0gICAgfQotCQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKSB7Ci0JdHJ5IHsKLQkgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOwotCSAgICBfZGF0YSA9IG5ldyBOb2RlU29ydFJlY29yZFtJTklUX0RBVEFfU0laRV07Ci0JICAgIF9mcmVlID0gMDsKLQotCSAgICAvLyBnYXRoZXIgYWxsIG5vZGVzIGZyb20gdGhlIHNvdXJjZSBpdGVyYXRvcgotCSAgICB3aGlsZSAoKG5vZGUgPSBfc291cmNlLm5leHQoKSkgIT0gRU5EKSB7Ci0JCWFkZFJlY29yZChfZmFjdG9yeS5tYWtlTm9kZVNvcnRSZWNvcmQobm9kZSxfZnJlZSkpOwotCSAgICB9Ci0JICAgIC8vIG5vdyBzb3J0IHRoZSByZWNvcmRzCi0JICAgIHF1aWNrc29ydCgwLCBfZnJlZSAtIDEpOwotCi0JICAgIF9jdXJyZW50ID0gMDsKLQkgICAgcmV0dXJuIHRoaXM7Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICByZXR1cm4gdGhpczsKLQl9Ci0gICAgfQotCQotICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKSB7Ci0JcmV0dXJuIF9jdXJyZW50ID09IDAgPyAxIDogX2N1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkgewotCXJldHVybiBfZnJlZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9zb3VyY2Uuc2V0TWFyaygpOwotCV9tYXJrZWROb2RlID0gX2N1cnJlbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JX3NvdXJjZS5nb3RvTWFyaygpOwotCV9jdXJyZW50ID0gX21hcmtlZE5vZGU7Ci0gICAgfQotICAgIAotICAgIHByaXZhdGUgdm9pZCBhZGRSZWNvcmQoTm9kZVNvcnRSZWNvcmQgcmVjb3JkKSB7Ci0JaWYgKF9mcmVlID09IF9kYXRhLmxlbmd0aCkgewotCSAgICBOb2RlU29ydFJlY29yZFtdIG5ld0FycmF5ID0gbmV3IE5vZGVTb3J0UmVjb3JkW19kYXRhLmxlbmd0aCAqIDJdOwotCSAgICBTeXN0ZW0uYXJyYXljb3B5KF9kYXRhLCAwLCBuZXdBcnJheSwgMCwgX2ZyZWUpOwotCSAgICBfZGF0YSA9IG5ld0FycmF5OwotCX0KLQlfZGF0YVtfZnJlZSsrXSA9IHJlY29yZDsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgcXVpY2tzb3J0KGludCBwLCBpbnQgcikgewotCXdoaWxlIChwIDwgcikgewotCSAgICBmaW5hbCBpbnQgcSA9IHBhcnRpdGlvbihwLCByKTsKLQkgICAgcXVpY2tzb3J0KHAsIHEpOwotCSAgICBwID0gcSArIDE7Ci0JfQotICAgIH0KLSAgICAKLSAgICBwcml2YXRlIGludCBwYXJ0aXRpb24oaW50IHAsIGludCByKSB7Ci0JZmluYWwgTm9kZVNvcnRSZWNvcmQgeCA9IF9kYXRhWyhwICsgcikgPj4+IDFdOwotCWludCBpID0gcCAtIDE7Ci0JaW50IGogPSByICsgMTsKLQl3aGlsZSAodHJ1ZSkgewotCSAgICB3aGlsZSAoeC5jb21wYXJlVG8oX2RhdGFbLS1qXSkgPCAwKTsKLQkgICAgd2hpbGUgKHguY29tcGFyZVRvKF9kYXRhWysraV0pID4gMCk7Ci0JICAgIGlmIChpIDwgaikgewotCQlmaW5hbCBOb2RlU29ydFJlY29yZCB0ID0gX2RhdGFbaV07Ci0JCV9kYXRhW2ldID0gX2RhdGFbal07Ci0JCV9kYXRhW2pdID0gdDsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJcmV0dXJuKGopOwotCSAgICB9Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TdGVwSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TdGVwSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGQyYmU5YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vU3RlcEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDAgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLQotcHVibGljIGZpbmFsIGNsYXNzIFN0ZXBJdGVyYXRvciBleHRlbmRzIE5vZGVJdGVyYXRvckJhc2UgewotICAgIHByaXZhdGUgTm9kZUl0ZXJhdG9yIF9zb3VyY2U7Ci0gICAgcHJpdmF0ZSBOb2RlSXRlcmF0b3IgX2l0ZXJhdG9yOwotCi0gICAgcHVibGljIFN0ZXBJdGVyYXRvcihOb2RlSXRlcmF0b3Igc291cmNlLCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IpIHsKLQlfc291cmNlID0gc291cmNlOwotCV9pdGVyYXRvciA9IGl0ZXJhdG9yOwotICAgIH0KLQotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpIHsKLQlfaXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCXRyeSB7Ci0JICAgIGZpbmFsIFN0ZXBJdGVyYXRvciBjbG9uZSA9IChTdGVwSXRlcmF0b3Ipc3VwZXIuY2xvbmUoKTsKLQkgICAgY2xvbmUuX3NvdXJjZSA9IF9zb3VyY2UuY2xvbmVJdGVyYXRvcigpOwotCSAgICBjbG9uZS5faXRlcmF0b3IgPSBfaXRlcmF0b3IuY2xvbmVJdGVyYXRvcigpOwotCSAgICAvLyBTcGVjaWFsIGNhc2UgLT4gX2l0ZXJhdG9yIG11c3QgYmUgcmVzdGFydGFibGUKLQkgICAgaWYgKGNsb25lLl9pdGVyYXRvciBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvckJhc2UpIHsKLQkJKChOb2RlSXRlcmF0b3JCYXNlKShjbG9uZS5faXRlcmF0b3IpKS5faXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0JICAgIH0KLQkgICAgcmV0dXJuIGNsb25lLnJlc2V0KCk7Ci0JfQotCWNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7Ci0JICAgIEJhc2lzTGlicmFyeS5ydW5UaW1lRXJyb3IoIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkgICAgLy8gaXRlcmF0b3IgaXMgbm90IGEgY2xvbmUKLQkgICAgX3NvdXJjZS5zZXRTdGFydE5vZGUoX3N0YXJ0Tm9kZSA9IG5vZGUpOwotCSAgICBfaXRlcmF0b3Iuc2V0U3RhcnROb2RlKF9zb3VyY2UubmV4dCgpKTsKLQkgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLQl9Ci0JcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlfc291cmNlLnNldFN0YXJ0Tm9kZShfc3RhcnROb2RlKTsKLQlfc291cmNlLnJlc2V0KCk7Ci0JaW50IG5vZGUgPSBfc291cmNlLm5leHQoKTsKLQlfaXRlcmF0b3Iuc2V0U3RhcnROb2RlKG5vZGUpOwotCXJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBpbnQgbmV4dCgpIHsKLQlmb3IgKGludCBub2RlOzspIHsKLQkgICAgaWYgKChub2RlID0gX2l0ZXJhdG9yLm5leHQoKSkgIT0gRU5EKSB7Ci0JCXJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotCSAgICB9Ci0JICAgIC8vIGxvY2FsIGl0ZXJhdG9yIHJhbiBvdXQgb2Ygbm9kZXMKLQkgICAgLy8gdHJ5IHRvIGdldCBuZXcgc3RhcnQgbm9kZSBmcm9tIHNvdXJjZQotCSAgICBlbHNlIGlmICgobm9kZSA9IF9zb3VyY2UubmV4dCgpKSA9PSBFTkQpIHsKLQkJcmV0dXJuIEVORDsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX2l0ZXJhdG9yLnNldFN0YXJ0Tm9kZShub2RlKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKCkgewotCV9zb3VyY2Uuc2V0TWFyaygpOwotCV9pdGVyYXRvci5zZXRNYXJrKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKSB7Ci0JX3NvdXJjZS5nb3RvTWFyaygpOwotCV9pdGVyYXRvci5nb3RvTWFyaygpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TdHJpcFdoaXRlc3BhY2VGaWx0ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9TdHJpcFdoaXRlc3BhY2VGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjI0YWY1OS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vU3RyaXBXaGl0ZXNwYWNlRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb207Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLQotcHVibGljIGludGVyZmFjZSBTdHJpcFdoaXRlc3BhY2VGaWx0ZXIgewotICAgIHB1YmxpYyBib29sZWFuIHN0cmlwU3BhY2UoRE9NIGRvbSwgaW50IG5vZGUsIGludCB0eXBlKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Vbmlvbkl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20vVW5pb25JdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2OWNhMzdiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbS9Vbmlvbkl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzIgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ET007Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkJhc2lzTGlicmFyeTsKLQotLyoqCi0gKiBVbmlvbkl0ZXJhdG9yIHRha2VzIGEgc2V0IG9mIE5vZGVJdGVyYXRvcnMgYW5kIHByb2R1Y2VzCi0gKiBhIG1lcmdlZCBOb2RlU2V0IGluIGRvY3VtZW50IG9yZGVyIHdpdGggZHVwbGljYXRlcyByZW1vdmVkCi0gKiBUaGUgaW5kaXZpZHVhbCBpdGVyYXRvcnMgYXJlIHN1cHBvc2VkIHRvIGdlbmVyYXRlIG5vZGVzCi0gKiBpbiBkb2N1bWVudCBvcmRlcgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgVW5pb25JdGVyYXRvciBleHRlbmRzIE5vZGVJdGVyYXRvckJhc2UgewotICAgIC8qKiB3cmFwcGVyIGZvciBOb2RlSXRlcmF0b3JzIHRvIHN1cHBvcnQgaXRlcmF0b3IKLQljb21wYXJpc29uIG9uIHRoZSB2YWx1ZSBvZiB0aGVpciBuZXh0KCkgbWV0aG9kCi0gICAgKi8KLSAgICBmaW5hbCBwcml2YXRlIERPTSBfZG9tOwotCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2xhc3MgTG9va0FoZWFkSXRlcmF0b3IgewotCXB1YmxpYyBpbnQgbm9kZSwgbWFya2VkTm9kZTsKLQlwdWJsaWMgZmluYWwgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yOwotCQkKLQlwdWJsaWMgTG9va0FoZWFkSXRlcmF0b3IoTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yKSB7Ci0JICAgIHRoaXMuaXRlcmF0b3IgPSBpdGVyYXRvcjsKLQl9Ci0JCQotCXB1YmxpYyBpbnQgc3RlcCgpIHsKLQkgICAgbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTsKLQkgICAgcmV0dXJuIG5vZGU7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQkgICAgbWFya2VkTm9kZSA9IG5vZGU7Ci0JICAgIGl0ZXJhdG9yLnNldE1hcmsoKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQkgICAgbm9kZSA9IG1hcmtlZE5vZGU7Ci0JICAgIGl0ZXJhdG9yLmdvdG9NYXJrKCk7Ci0JfQotCi0gICAgfSAvLyBlbmQgb2YgTG9va0FoZWFkSXRlcmF0b3IKLQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJbml0U2l6ZSA9IDg7Ci0gIAotICAgIHByaXZhdGUgaW50ICAgICAgICAgICAgX2hlYXBTaXplID0gMDsKLSAgICBwcml2YXRlIGludCAgICAgICAgICAgIF9zaXplID0gSW5pdFNpemU7Ci0gICAgcHJpdmF0ZSBMb29rQWhlYWRJdGVyYXRvcltdIF9oZWFwID0gbmV3IExvb2tBaGVhZEl0ZXJhdG9yW0luaXRTaXplXTsKLSAgICBwcml2YXRlIGludCAgICAgICAgICAgIF9mcmVlID0gMDsKLSAgCi0gICAgLy8gbGFzdCBub2RlIHJldHVybmVkIGJ5IHRoaXMgVW5pb25JdGVyYXRvciB0byB0aGUgY2FsbGVyIG9mIG5leHQKLSAgICAvLyB1c2VkIHRvIHBydW5lIGR1cGxpY2F0ZXMKLSAgICBwcml2YXRlIGludCBfcmV0dXJuZWRMYXN0OwotCi0gICAgcHVibGljIFVuaW9uSXRlcmF0b3IoRE9NIGRvbSkgewotCV9kb20gPSBkb207Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkgewotCV9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0JZmluYWwgTG9va0FoZWFkSXRlcmF0b3JbXSBoZWFwQ29weSA9IAotCSAgICBuZXcgTG9va0FoZWFkSXRlcmF0b3JbX2hlYXAubGVuZ3RoXTsKLQl0cnkgewotCSAgICBmaW5hbCBVbmlvbkl0ZXJhdG9yIGNsb25lID0gKFVuaW9uSXRlcmF0b3Ipc3VwZXIuY2xvbmUoKTsKLQkgICAgU3lzdGVtLmFycmF5Y29weShfaGVhcCwgMCwgaGVhcENvcHksIDAsIF9oZWFwLmxlbmd0aCk7Ci0JICAgIGNsb25lLl9oZWFwID0gaGVhcENvcHk7Ci0JICAgIHJldHVybiBjbG9uZS5yZXNldCgpOwotCX0gCi0JY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLQkgICAgQmFzaXNMaWJyYXJ5LnJ1blRpbWVFcnJvcigiSXRlcmF0b3IgY2xvbmUgbm90IHN1cHBvcnRlZC4iKTsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLSAgICAKLSAgICBwdWJsaWMgVW5pb25JdGVyYXRvciBhZGRJdGVyYXRvcihOb2RlSXRlcmF0b3IgaXRlcmF0b3IpIHsKLQlpZiAoX2ZyZWUgPT0gX3NpemUpIHsKLQkgICAgTG9va0FoZWFkSXRlcmF0b3JbXSBuZXdBcnJheSA9IG5ldyBMb29rQWhlYWRJdGVyYXRvcltfc2l6ZSAqPSAyXTsKLQkgICAgU3lzdGVtLmFycmF5Y29weShfaGVhcCwgMCwgbmV3QXJyYXksIDAsIF9mcmVlKTsKLQkgICAgX2hlYXAgPSBuZXdBcnJheTsKLQl9Ci0JX2hlYXBTaXplKys7Ci0JX2hlYXBbX2ZyZWUrK10gPSBuZXcgTG9va0FoZWFkSXRlcmF0b3IoaXRlcmF0b3IpOwotCXJldHVybiB0aGlzOwotICAgIH0KLSAgCi0gICAgcHVibGljIGludCBuZXh0KCkgewotCXdoaWxlIChfaGVhcFNpemUgPiAwKSB7Ci0JICAgIGZpbmFsIGludCBzbWFsbGVzdCA9IF9oZWFwWzBdLm5vZGU7Ci0JICAgIGlmIChzbWFsbGVzdCA9PSBFTkQpIHsgLy8gaXRlcmF0b3IgX2hlYXBbMF0gaXMgZG9uZQotCQlpZiAoX2hlYXBTaXplID4gMSkgewotCQkgICAgLy8gcmVwbGFjZSBpdCB3aXRoIGxhc3QKLQkJICAgIF9oZWFwWzBdID0gX2hlYXBbLS1faGVhcFNpemVdOwotCQl9Ci0JCWVsc2UgewotCQkgICAgcmV0dXJuIEVORDsKLQkJfQotCSAgICB9Ci0JICAgIGVsc2UgaWYgKHNtYWxsZXN0ID09IF9yZXR1cm5lZExhc3QpIHsJLy8gZHVwbGljYXRlCi0JCV9oZWFwWzBdLnN0ZXAoKTsgLy8gdmFsdWUgY29uc3VtZWQKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX2hlYXBbMF0uc3RlcCgpOyAvLyB2YWx1ZSBjb25zdW1lZAotCQloZWFwaWZ5KDApOwotCQlyZXR1cm4gcmV0dXJuTm9kZShfcmV0dXJuZWRMYXN0ID0gc21hbGxlc3QpOwotCSAgICB9Ci0JICAgIC8vIGZhbGx0aHJvdWdoIGlmIG5vdCByZXR1cm5lZCBhYm92ZQotCSAgICBoZWFwaWZ5KDApOwotCX0KLQlyZXR1cm4gRU5EOwotICAgIH0KLSAgCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpIHsKLQlpZiAoX2lzUmVzdGFydGFibGUpIHsKLQkgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX2ZyZWU7IGkrKykgewotCQlfaGVhcFtpXS5pdGVyYXRvci5zZXRTdGFydE5vZGUobm9kZSk7Ci0JCV9oZWFwW2ldLnN0ZXAoKTsJLy8gdG8gZ2V0IHRoZSBmaXJzdCBub2RlCi0JICAgIH0KLQkgICAgLy8gYnVpbGQgaGVhcAotCSAgICBmb3IgKGludCBpID0gKF9oZWFwU2l6ZSA9IF9mcmVlKS8yOyBpID49IDA7IGktLSkgewotCQloZWFwaWZ5KGkpOwotCSAgICB9Ci0JICAgIF9yZXR1cm5lZExhc3QgPSBFTkQ7Ci0JICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0JfQotCXJldHVybiB0aGlzOwotICAgIH0KLQkKLSAgICBwcml2YXRlIHZvaWQgaGVhcGlmeShpbnQgaSkgewotCWZvciAoaW50IHIsIGwsIHNtYWxsZXN0OzspIHsKLQkgICAgciA9IChpICsgMSkgPDwgMTsgbCA9IHIgLSAxOwotCSAgICBzbWFsbGVzdCA9IGwgPCBfaGVhcFNpemUgCi0JCSYmIF9kb20ubGVzc1RoYW4oX2hlYXBbbF0ubm9kZSwgX2hlYXBbaV0ubm9kZSkgPyBsIDogaTsKLQkgICAgaWYgKHIgPCBfaGVhcFNpemUgJiYgX2RvbS5sZXNzVGhhbihfaGVhcFtyXS5ub2RlLAotCQkJCQkgICAgICAgX2hlYXBbc21hbGxlc3RdLm5vZGUpKSB7Ci0JCXNtYWxsZXN0ID0gcjsKLQkgICAgfQotCSAgICBpZiAoc21hbGxlc3QgIT0gaSkgewotCQlmaW5hbCBMb29rQWhlYWRJdGVyYXRvciB0ZW1wID0gX2hlYXBbc21hbGxlc3RdOwotCQlfaGVhcFtzbWFsbGVzdF0gPSBfaGVhcFtpXTsKLQkJX2hlYXBbaV0gPSB0ZW1wOwotCQlpID0gc21hbGxlc3Q7Ci0JICAgIH0KLQkgICAgZWxzZQotCQlicmVhazsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0TWFyaygpIHsKLQlmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspIHsKLQkgICAgX2hlYXBbaV0uc2V0TWFyaygpOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBnb3RvTWFyaygpIHsKLQlmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspIHsKLQkgICAgX2hlYXBbaV0uZ290b01hcmsoKTsKLQl9Ci0gICAgfQotCi0gICAgcHVibGljIE5vZGVJdGVyYXRvciByZXNldCgpIHsKLQlzdXBlci5yZXNldCgpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgX2ZyZWU7IGkrKykgewotCSAgICBfaGVhcFtpXS5pdGVyYXRvci5yZXNldCgpOwotCX0KLQlyZXR1cm4odGhpcyk7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmOGIwNzU4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjA2ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBKb2huIEhvd2FyZCwgSm9obkhAc2NoZW1hc29mdC5jb20gCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7Ci1pbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRPTUFkYXB0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NSW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5LZXlJbmRleDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5EVERNb25pdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudXRpbC5JbnRlZ2VyQXJyYXk7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFRyYW5zbGV0IGltcGxlbWVudHMgVHJhbnNsZXQgewotCi0gICAgLy8gVGhlc2UgYXR0cmlidXRlcyBhcmUgZXh0cmFjdGVkIGZyb20gdGhlIHhzbDpvdXRwdXQgZWxlbWVudC4gVGhleSBhbHNvCi0gICAgLy8gYXBwZWFyIGFzIGZpZWxkcyAod2l0aCB0aGUgc2FtZSB0eXBlLCBvbmx5IHB1YmxpYykgaW4gT3V0cHV0LmphdmEKLSAgICBwdWJsaWMgU3RyaW5nICBfdmVyc2lvbiA9ICIxLjAiOwotICAgIHB1YmxpYyBTdHJpbmcgIF9tZXRob2QgPSBudWxsOwotICAgIHB1YmxpYyBTdHJpbmcgIF9lbmNvZGluZyA9ICJ1dGYtOCI7Ci0gICAgcHVibGljIGJvb2xlYW4gX29taXRIZWFkZXIgPSBmYWxzZTsKLSAgICBwdWJsaWMgU3RyaW5nICBfc3RhbmRhbG9uZSA9IG51bGw7Ci0gICAgcHVibGljIFN0cmluZyAgX2RvY3R5cGVQdWJsaWMgPSBudWxsOwotICAgIHB1YmxpYyBTdHJpbmcgIF9kb2N0eXBlU3lzdGVtID0gbnVsbDsKLSAgICBwdWJsaWMgYm9vbGVhbiBfaW5kZW50ID0gZmFsc2U7Ci0gICAgcHVibGljIFN0cmluZyAgX21lZGlhVHlwZSA9IG51bGw7Ci0gICAgcHVibGljIEhhc2h0YWJsZSBfY2RhdGEgPSBudWxsOwotCi0gICAgLy8gRE9NL3RyYW5zbGV0IGhhbmRzaGFraW5nIC0gdGhlIGFycmF5cyBhcmUgc2V0IGJ5IHRoZSBjb21waWxlZCB0cmFuc2xldAotICAgIHByb3RlY3RlZCBTdHJpbmdbXSBuYW1lc0FycmF5OwotICAgIHByb3RlY3RlZCBTdHJpbmdbXSBuYW1lc3BhY2VBcnJheTsKLQotICAgIC8vIFRPRE8gLSB0aGVzZSBzaG91bGQgb25seSBiZSBpbnN0YW5jaWF0ZWQgd2hlbiBuZWVkZWQKLSAgICBwcm90ZWN0ZWQgU3RyaW5nVmFsdWVIYW5kbGVyIHN0cmluZ1ZhbHVlSGFuZGxlciA9IG5ldyBTdHJpbmdWYWx1ZUhhbmRsZXIoKTsKLQotICAgIC8vIFVzZSBvbmUgZW1wdHkgc3RyaW5nIGluc3RlYWQgb2YgY29uc3RhbnRseSBpbnN0YW5jaWF0aW5nIFN0cmluZygiIik7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICAvKioKLSAgICAgKiBXcmFwIHRoZSBpbml0aWFsIGlucHV0IERPTSBpbiBhIGRvbSBhZGFwdGVyLiBUaGlzIGFkYXB0ZXIgaXMgd3JhcHBlZCBpbgotICAgICAqIGEgRE9NIG11bHRpcGxleGVyIGlmIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uIGlzIHVzZWQgKGhhbmRsZWQgYnkgY29tcGlsZWQKLSAgICAgKiBjb2RlIGluIHRoZSB0cmFuc2xldCAtIHNlZSBjb21waWxlci9TdHlsZXNoZWV0LmNvbXBpbGVUcmFuc2Zvcm0oKSkuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIERPTUFkYXB0ZXIgbWFrZURPTUFkYXB0ZXIoRE9NIGRvbSkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCWlmIChkb20gaW5zdGFuY2VvZiBET01JbXBsKSB7Ci0JICAgIHJldHVybiBuZXcgRE9NQWRhcHRlcigoRE9NSW1wbClkb20sIG5hbWVzQXJyYXksIG5hbWVzcGFjZUFycmF5KTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbigid3JvbmcgdHlwZSBvZiBzb3VyY2UgRE9NIik7Ci0JfQotICAgIH0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBWYXJpYWJsZSBhbmQgcGFyYW1ldGVyIGhhbmRsaW5nCi0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgIC8vIFZhcmlhYmxlJ3Mgc3RhY2s6IDx0dD52YmFzZTwvdHQ+IGFuZCA8dHQ+dmZyYW1lPC90dD4gYXJlIHVzZWQgCi0gICAgLy8gdG8gZGVub3RlIHRoZSBjdXJyZW50IHZhcmlhYmxlIGZyYW1lLgotICAgIHByb3RlY3RlZCBpbnQgdmJhc2UgPSAwLCB2ZnJhbWUgPSAwOwotICAgIHByb3RlY3RlZCBWZWN0b3IgdmFyc1N0YWNrID0gbmV3IFZlY3RvcigpOwotCi0gICAgLy8gUGFyYW1ldGVyJ3Mgc3RhY2s6IDx0dD5wYmFzZTwvdHQ+IGFuZCA8dHQ+cGZyYW1lPC90dD4gYXJlIHVzZWQgCi0gICAgLy8gdG8gZGVub3RlIHRoZSBjdXJyZW50IHBhcmFtZXRlciBmcmFtZS4KLSAgICBwcm90ZWN0ZWQgaW50IHBiYXNlID0gMCwgcGZyYW1lID0gMDsKLSAgICBwcm90ZWN0ZWQgVmVjdG9yIHBhcmFtc1N0YWNrID0gbmV3IFZlY3RvcigpOwotCi0gICAgLyoqCi0gICAgICogUHVzaCBhIG5ldyBwYXJhbWV0ZXIgZnJhbWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcHVzaFBhcmFtRnJhbWUoKSB7Ci0JcGFyYW1zU3RhY2suaW5zZXJ0RWxlbWVudEF0KG5ldyBJbnRlZ2VyKHBiYXNlKSwgcGZyYW1lKTsKLQlwYmFzZSA9ICsrcGZyYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBvcCB0aGUgdG9wbW9zdCBwYXJhbWV0ZXIgZnJhbWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcG9wUGFyYW1GcmFtZSgpIHsKLQlpZiAocGJhc2UgPiAwKSB7Ci0JICAgIGludCBib3QgPSBwYmFzZSAtIDE7Ci0JICAgIGludCB0b3AgPSBwZnJhbWUgLSAxOwotCSAgICBwZnJhbWUgPSBwYmFzZSAtIDE7Ci0JICAgIHBiYXNlID0gKChJbnRlZ2VyKSBwYXJhbXNTdGFjay5lbGVtZW50QXQocGZyYW1lKSkuaW50VmFsdWUoKTsKLQkgICAgLy8gYnVnIGZpeCAjMzQyNCwgSm9obiBIb3dhcmQuCi0JICAgIC8vIHJlbW92ZSBvYmplY3RzIHRoYXQgYXJlIGluIHRoZSBzdGFjayBzaW5jZSBvYmplY3RzIGFyZQkKLQkgICAgLy8gYWRkZWQgd2l0aCBpbnNlcnRFbGVtZW50QXQoaW50KSBhbmQgd2lsbCBjYXVzZSBtZW1vcnkgcmV0ZW50aW9uCi0JICAgIGZvciAoaW50IGk9dG9wOyBpPj1ib3Q7IGktLSkgewotCQlwYXJhbXNTdGFjay5yZW1vdmVFbGVtZW50QXQoaSk7Ci0JICAgIH0KLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkIGEgbmV3IGdsb2JhbCBwYXJhbWV0ZXIgaWYgbm90IGFscmVhZHkgaW4gdGhlIGN1cnJlbnQgZnJhbWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIE9iamVjdCBhZGRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgewotCXJldHVybiBhZGRQYXJhbWV0ZXIobmFtZSwgdmFsdWUsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYSBuZXcgZ2xvYmFsIG9yIGxvY2FsIHBhcmFtZXRlciBpZiBub3QgYWxyZWFkeSBpbiB0aGUgY3VycmVudCBmcmFtZS4KLSAgICAgKiBUaGUgJ2lzRGVmYXVsdCcgcGFyYW1ldGVyIGlzIHNldCB0byB0cnVlIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgdGhlCi0gICAgICogZGVmYXVsdCB2YWx1ZSBmcm9tIHRoZSA8eHNsOnBhcmFtZXRlcj4gZWxlbWVudCdzIHNlbGVjdCBhdHRyaWJ1dGUgb3IKLSAgICAgKiBlbGVtZW50IGJvZHkuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIE9iamVjdCBhZGRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSwKLQkJCQkgICAgIGJvb2xlYW4gaXNEZWZhdWx0KSB7Ci0KLQkvLyBMb2NhbCBwYXJhbWV0ZXJzIG5lZWQgdG8gYmUgcmUtZXZhbHVhdGVkIGZvciBlYWNoIGl0ZXJhdGlvbgotCWZvciAoaW50IGkgPSBwZnJhbWUgLSAxOyBpID49IHBiYXNlOyBpLS0pIHsKLQkgICAgZmluYWwgUGFyYW1ldGVyIHBhcmFtID0gKFBhcmFtZXRlcikgcGFyYW1zU3RhY2suZWxlbWVudEF0KGkpOwotCSAgICBpZiAocGFyYW0uX25hbWUuZXF1YWxzKG5hbWUpKSB7Ci0JCS8vIE9ubHkgb3ZlcndyaXRlIGlmIGN1cnJlbnQgdmFsdWUgaXMgdGhlIGRlZmF1bHQgdmFsdWUgYW5kCi0JCS8vIHRoZSBuZXcgdmFsdWUgaXMgX05PVF8gdGhlIGRlZmF1bHQgdmFsdWUuCi0JCWlmICgocGFyYW0uX2lzRGVmYXVsdCA9PSB0cnVlKSB8fCAoIWlzRGVmYXVsdCkpIHsKLQkJICAgIHBhcmFtLl92YWx1ZSA9IHZhbHVlOwotCQkgICAgcGFyYW0uX2lzRGVmYXVsdCA9IGlzRGVmYXVsdDsKLQkJICAgIHJldHVybiB2YWx1ZTsKLQkJfQotCQlyZXR1cm4gcGFyYW0uX3ZhbHVlOwotCSAgICB9Ci0JfQotCi0JLy8gQWRkIG5ldyBwYXJhbWV0ZXIgdG8gcGFyYW1ldGVyIHN0YWNrCi0JZmluYWwgUGFyYW1ldGVyIHBhcmFtID0gbmV3IFBhcmFtZXRlcihuYW1lLCB2YWx1ZSwgaXNEZWZhdWx0KTsKLQlwYXJhbXNTdGFjay5pbnNlcnRFbGVtZW50QXQocGFyYW0sIHBmcmFtZSsrKTsKLQlyZXR1cm4gdmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2xlYXJzIHRoZSBwYXJhbWV0ZXIgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCkgeyAgCi0JcGFyYW1zU3RhY2suY2xlYXIoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgcGFyYW1ldGVyIGZyb20gdGhlIGN1cnJlbnQgZnJhbWUgb3IKLSAgICAgKiA8dHQ+bnVsbDwvdHQ+IGlmIHVuZGVmaW5lZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgT2JqZWN0IGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSkgewotCWZvciAoaW50IGkgPSBwZnJhbWUgLSAxOyBpID49IHBiYXNlOyBpLS0pIHsKLQkgICAgZmluYWwgUGFyYW1ldGVyIHBhcmFtID0gKFBhcmFtZXRlcilwYXJhbXNTdGFjay5lbGVtZW50QXQoaSk7Ci0JICAgIGlmIChwYXJhbS5fbmFtZS5lcXVhbHMobmFtZSkpIHJldHVybiBwYXJhbS5fdmFsdWU7Ci0JfQotCXJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFB1c2ggYSBuZXcgdmFyaWFibGUgZnJhbWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgcHVzaFZhckZyYW1lKGludCBmcmFtZVNpemUpIHsKLQl2YXJzU3RhY2suaW5zZXJ0RWxlbWVudEF0KG5ldyBJbnRlZ2VyKHZiYXNlKSwgdmZyYW1lKTsKLQl2YmFzZSA9ICsrdmZyYW1lOwotCXZmcmFtZSArPSBmcmFtZVNpemU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUG9wIHRoZSB0b3Btb3N0IHZhcmlhYmxlIGZyYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHBvcFZhckZyYW1lKCkgewotCWlmICh2YmFzZSA+IDApIHsKLQkgICAgaW50IGJvdCA9IHZiYXNlIC0gMTsKLQkgICAgaW50IHRvcCA9IHZmcmFtZSAtIDE7Ci0JICAgIHZmcmFtZSA9IHZiYXNlIC0gMTsKLQkgICAgdmJhc2UgPSAoKEludGVnZXIpdmFyc1N0YWNrLmVsZW1lbnRBdCh2ZnJhbWUpKS5pbnRWYWx1ZSgpOwotCSAgICAvLyBidWcgZml4IDM0MjQsIEpvaG4gSG93YXJkCi0JICAgIC8vIHJlbW92ZSBvYmplY3RzIHRoYXQgYXJlIGluIHRoZSBzdGFjayBzaW5jZSBvYmplY3RzIGFyZQkKLQkgICAgLy8gYWRkZWQgd2l0aCBpbnNlcnRFbGVtZW50QXQoaW50KSBhbmQgd2lsbCBjYXVzZSBtZW1vcnkgcmV0ZW50aW9uCi0JICAgIGZvciAoaW50IGk9dG9wOyBpPj1ib3Q7IGktLSkgewotCQl2YXJzU3RhY2sucmVtb3ZlRWxlbWVudEF0KGkpOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZSBnaXZlbiBpdHMgaW5kZXguCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIE9iamVjdCBnZXRWYXJpYWJsZShpbnQgdmluZGV4KSB7Ci0JLy8gYnVnIGZpeCAzNDI0LCBKb2huIEhvd2FyZAotCXJldHVybiB2YXJzU3RhY2suZWxlbWVudEF0KHZiYXNlICsgdmluZGV4KTsKLSAgICB9Ci0JCi0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgdmFyaWFibGUgaW4gdGhlIGN1cnJlbnQgZnJhbWUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgYWRkVmFyaWFibGUoaW50IHZpbmRleCwgT2JqZWN0IHZhbHVlKSB7Ci0JZmluYWwgaW50IGluZGV4ID0gdmJhc2UgKyB2aW5kZXg7Ci0JaWYgKGluZGV4ID4gdmFyc1N0YWNrLnNpemUoKSkgdmFyc1N0YWNrLnNldFNpemUoaW5kZXgpOwotCXZhcnNTdGFjay5pbnNlcnRFbGVtZW50QXQodmFsdWUsIGluZGV4KTsKLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogTWVzc2FnZSBoYW5kbGluZyAtIGltcGxlbWVudGF0aW9uIG9mIDx4c2w6bWVzc2FnZT4KLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotCi0gICAgLy8gSG9sZHMgdGhlIHRyYW5zbGV0J3MgbWVzc2FnZSBoYW5kbGVyIC0gdXNlZCBmb3IgPHhzbDptZXNzYWdlPi4KLSAgICAvLyBUaGUgZGVhdWx0IG1lc3NhZ2UgaGFuZGxlciBkdW1wcyBhIHN0cmluZyBzdGRvdXQsIGJ1dCBhbnl0aGluZyBjYW4gYmUKLSAgICAvLyB1c2VkLCBzdWNoIGFzIGEgZGlhbG9nIGJveCBmb3IgYXBwbGV0cywgZXRjLgotICAgIHByaXZhdGUgTWVzc2FnZUhhbmRsZXIgX21zZ0hhbmRsZXIgPSBudWxsOwotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSB0cmFuc2xldCdzIG1lc3NhZ2UgaGFuZGxlciAtIG11c3QgaW1wbGVtZW50IE1lc3NhZ2VIYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0TWVzc2FnZUhhbmRsZXIoTWVzc2FnZUhhbmRsZXIgaGFuZGxlcikgewotCV9tc2dIYW5kbGVyID0gaGFuZGxlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIGEgbWVzc2FnZSB0byB0aGUgbWVzc2FnZSBoYW5kbGVyIC0gdXNlZCBieSBNZXNzYWdlIGNsYXNzLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGRpc3BsYXlNZXNzYWdlKFN0cmluZyBtc2cpIHsKLQlpZiAoX21zZ0hhbmRsZXIgPT0gbnVsbCkgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKG1zZyk7Ci0JfQotCWVsc2UgewotCSAgICBfbXNnSGFuZGxlci5kaXNwbGF5TWVzc2FnZShtc2cpOwotCX0KLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogRGVjaW1hbCBudW1iZXIgZm9ybWF0IHN5bWJvbCBoYW5kbGluZwotICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvLyBDb250YWlucyBkZWNpbWFsIG51bWJlciBmb3JtYXR0aW5nIHN5bWJvbHMgdXNlZCBieSBGb3JtYXROdW1iZXJDYWxsCi0gICAgcHVibGljIEhhc2h0YWJsZSBfZm9ybWF0U3ltYm9scyA9IG51bGw7Ci0KLSAgICAvKioKLSAgICAgKiBBZGRzIGEgRGVjaW1hbEZvcm1hdCBvYmplY3QgdG8gdGhlIF9mb3JtYXRTeW1ib2xzIGhhc2h0YWJsZS4KLSAgICAgKiBUaGUgZW50cnkgaXMgY3JlYXRlZCB3aXRoIHRoZSBpbnB1dCBEZWNpbWFsRm9ybWF0U3ltYm9scy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGREZWNpbWFsRm9ybWF0KFN0cmluZyBuYW1lLCBEZWNpbWFsRm9ybWF0U3ltYm9scyBzeW1ib2xzKSB7Ci0JLy8gSW5zdGFuY2lhdGUgaGFzaHRhYmxlIGZvciBmb3JtYXR0aW5nIHN5bWJvbHMgaWYgbmVlZGVkCi0JaWYgKF9mb3JtYXRTeW1ib2xzID09IG51bGwpIF9mb3JtYXRTeW1ib2xzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0JLy8gVGhlIG5hbWUgY2Fubm90IGJlIG51bGwgLSB1c2UgZW1wdHkgc3RyaW5nIGluc3RlYWQKLQlpZiAobmFtZSA9PSBudWxsKSBuYW1lID0gRU1QVFlTVFJJTkc7Ci0KLQkvLyBDb25zdHJ1Y3QgYSBEZWNpbWFsRm9ybWF0IG9iamVjdCBjb250YWluaW5nIHRoZSBzeW1ib2xzIHdlIGdvdAotCWZpbmFsIERlY2ltYWxGb3JtYXQgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgpOwotCWlmIChzeW1ib2xzICE9IG51bGwpIHsKLQkgICAgZGYuc2V0RGVjaW1hbEZvcm1hdFN5bWJvbHMoc3ltYm9scyk7Ci0JfQotCV9mb3JtYXRTeW1ib2xzLnB1dChuYW1lLCBkZik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0cmlldmVzIGEgbmFtZWQgRGVjaW1hbEZvcm1hdCBvYmplY3QgZnJvbSBfZm9ybWF0U3ltYm9scyBoYXNodGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIERlY2ltYWxGb3JtYXQgZ2V0RGVjaW1hbEZvcm1hdChTdHJpbmcgbmFtZSkgewotCi0JaWYgKF9mb3JtYXRTeW1ib2xzICE9IG51bGwpIHsKLQkgICAgLy8gVGhlIG5hbWUgY2Fubm90IGJlIG51bGwgLSB1c2UgZW1wdHkgc3RyaW5nIGluc3RlYWQKLQkgICAgaWYgKG5hbWUgPT0gbnVsbCkgbmFtZSA9IEVNUFRZU1RSSU5HOwotCi0JICAgIGZpbmFsIERlY2ltYWxGb3JtYXQgZGYgPSAoRGVjaW1hbEZvcm1hdClfZm9ybWF0U3ltYm9scy5nZXQobmFtZSk7Ci0JICAgIGlmIChkZiAhPSBudWxsKQotCQlyZXR1cm4gZGY7Ci0JICAgIGVsc2UKLQkJcmV0dXJuKChEZWNpbWFsRm9ybWF0KV9mb3JtYXRTeW1ib2xzLmdldChFTVBUWVNUUklORykpOwotCX0KLQlyZXR1cm4obnVsbCk7Ci0gICAgfQotCi0gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICAgICAqIFVucGFyc2VkIGVudGl0eSBVUkkgaGFuZGxpbmcgLSBpbXBsZW1lbnRzIHVucGFyc2VkLWVudGl0eS11cmkoKQotICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvLyBLZWVwcyBhbGwgdW5wYXJzZWQgZW50aXR5IFVSSXMgc3BlY2lmaWVkIGluIHRoZSBYTUwgaW5wdXQKLSAgICBwdWJsaWMgSGFzaHRhYmxlIF91bnBhcnNlZEVudGl0aWVzID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgdmFsdWUgb2YgYW4gdW5wYXJzZWQgZW50aXR5IFVSSS4KLSAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGJ5IHRoZSBjb21waWxlci9VbnBhcnNlZEVudGl0eVVyaUNhbGwgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eShTdHJpbmcgbmFtZSkgewotCWZpbmFsIFN0cmluZyB1cmkgPSAoU3RyaW5nKV91bnBhcnNlZEVudGl0aWVzLmdldChuYW1lKTsKLQlyZXR1cm4gdXJpID09IG51bGwgPyBFTVBUWVNUUklORyA6IHVyaTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQgYW4gdW5wYXJzZWQgZW50aXR5IFVSSS4gVGhlIFVSSS92YWx1ZSBwYWlycyBhcmUgcGFzc2VkIGZyb20gdGhlCi0gICAgICogRE9NIGJ1aWxkZXIgdG8gdGhlIHRyYW5zbGV0LgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFkZFVucGFyc2VkRW50aXR5KFN0cmluZyBuYW1lLCBTdHJpbmcgdXJpKSB7Ci0JaWYgKF91bnBhcnNlZEVudGl0aWVzID09IG51bGwpCi0JICAgIF91bnBhcnNlZEVudGl0aWVzID0gbmV3IEhhc2h0YWJsZSgpOwotCWlmIChfdW5wYXJzZWRFbnRpdGllcy5jb250YWluc0tleShuYW1lKSA9PSBmYWxzZSkKLQkgICAgX3VucGFyc2VkRW50aXRpZXMucHV0KG5hbWUsIHVyaSk7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIEFkZCBhbiB1bnBhcnNlZCBlbnRpdHkgVVJJLiBUaGUgVVJJL3ZhbHVlIHBhaXJzIGFyZSBwYXNzZWQgZnJvbSB0aGUKLSAgICAgKiBET00gYnVpbGRlciB0byB0aGUgdHJhbnNsZXQuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgc2V0VW5wYXJzZWRFbnRpdHlVUklzKEhhc2h0YWJsZSB0YWJsZSkgewotCWlmIChfdW5wYXJzZWRFbnRpdGllcyA9PSBudWxsKQotCSAgICBfdW5wYXJzZWRFbnRpdGllcyA9IHRhYmxlOwotCWVsc2UgewotCSAgICBFbnVtZXJhdGlvbiBrZXlzID0gdGFibGUua2V5cygpOwotCSAgICB3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQlTdHJpbmcgbmFtZSA9IChTdHJpbmcpa2V5cy5uZXh0RWxlbWVudCgpOwotCQlfdW5wYXJzZWRFbnRpdGllcy5wdXQobmFtZSx0YWJsZS5nZXQobmFtZSkpOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSBEVEQgbW9uaXRvciB1c2VkIGJ5IHRoZSBET00gYnVpbGRlciBzY2FucyB0aGUgaW5wdXQgZG9jdW1lbnQgRFRECi0gICAgICogZm9yIHVucGFyc2VkIGVudGl0eSBVUklzLiBUaGVzZSBhcmUgcGFzc2VkIHRvIHRoZSB0cmFuc2xldCB1c2luZwotICAgICAqIHRoaXMgbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldERURE1vbml0b3IoRFRETW9uaXRvciBtb25pdG9yKSB7Ci0Jc2V0VW5wYXJzZWRFbnRpdHlVUklzKG1vbml0b3IuZ2V0VW5wYXJzZWRFbnRpdHlVUklzKCkpOwotICAgIH0KLQotICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAgICAgKiBJbmRleChlcykgZm9yIDx4c2w6a2V5PiAvIGtleSgpIC8gaWQoKQotICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICAvLyBDb250YWluZXIgZm9yIGFsbCBpbmRleGVzIGZvciB4c2w6a2V5IGVsZW1lbnRzCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgX2tleUluZGV4ZXMgPSBudWxsOwotICAgIHByaXZhdGUgS2V5SW5kZXggIF9lbXB0eUtleUluZGV4ID0gbmV3IEtleUluZGV4KDEpOwotICAgIHByaXZhdGUgaW50ICAgICAgIF9pbmRleFNpemUgPSAwOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBwYXNzIHRoZSBsYXJnZXN0IERPTSBzaXplIHRvIHRoZSB0cmFuc2xldC4KLSAgICAgKiBOZWVkZWQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHRyYW5zbGV0IGNhbiBpbmRleCB0aGUgd2hvbGUgRE9NLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGV4U2l6ZShpbnQgc2l6ZSkgewotCWlmIChzaXplID4gX2luZGV4U2l6ZSkgX2luZGV4U2l6ZSA9IHNpemU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIEtleUluZGV4IG9iamVjdCBvZiB0aGUgZGVzaXJlZCBzaXplIC0gZG9uJ3Qgd2FudCB0byByZXNpemUhISEKLSAgICAgKi8KLSAgICBwdWJsaWMgS2V5SW5kZXggY3JlYXRlS2V5SW5kZXgoKSB7Ci0JcmV0dXJuKG5ldyBLZXlJbmRleChfaW5kZXhTaXplKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQWRkcyBhIHZhbHVlIHRvIGEga2V5L2lkIGluZGV4Ci0gICAgICogICBAbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUgaW5kZXggKHRoZSBrZXkgb3IgIyNpZCkKLSAgICAgKiAgIEBub2RlIGlzIHRoZSBub2RlIGlkIG9mIHRoZSBub2RlIHRvIGluc2VydAotICAgICAqICAgQHZhbHVlIGlzIHRoZSB2YWx1ZSB0aGF0IHdpbGwgbG9vayB1cCB0aGUgbm9kZSBpbiB0aGUgZ2l2ZW4gaW5kZXgKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBidWlsZEtleUluZGV4KFN0cmluZyBuYW1lLCBpbnQgbm9kZSwgT2JqZWN0IHZhbHVlKSB7Ci0JaWYgKF9rZXlJbmRleGVzID09IG51bGwpIF9rZXlJbmRleGVzID0gbmV3IEhhc2h0YWJsZSgpOwotCQotCUtleUluZGV4IGluZGV4ID0gKEtleUluZGV4KV9rZXlJbmRleGVzLmdldChuYW1lKTsKLQlpZiAoaW5kZXggPT0gbnVsbCkgewotCSAgICBfa2V5SW5kZXhlcy5wdXQobmFtZSwgaW5kZXggPSBuZXcgS2V5SW5kZXgoX2luZGV4U2l6ZSkpOwotCX0KLQlpbmRleC5hZGQodmFsdWUsIG5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGluZGV4IGZvciBhIGdpdmVuIGtleSAob3IgaWQpLgotICAgICAqIFRoZSBpbmRleCBpbXBsZW1lbnRzIG91ciBpbnRlcm5hbCBpdGVyYXRvciBpbnRlcmZhY2UKLSAgICAgKi8KLSAgICBwdWJsaWMgS2V5SW5kZXggZ2V0S2V5SW5kZXgoU3RyaW5nIG5hbWUpIHsKLQkvLyBSZXR1cm4gYW4gZW1wdHkga2V5IGluZGV4IGl0ZXJhdG9yIGlmIG5vbmUgYXJlIGRlZmluZWQKLQlpZiAoX2tleUluZGV4ZXMgPT0gbnVsbCkgcmV0dXJuKF9lbXB0eUtleUluZGV4KTsKLQotCS8vIExvb2sgdXAgdGhlIHJlcXVlc3RlZCBrZXkgaW5kZXgKLQlmaW5hbCBLZXlJbmRleCBpbmRleCA9IChLZXlJbmRleClfa2V5SW5kZXhlcy5nZXQobmFtZSk7Ci0KLQkvLyBSZXR1cm4gYW4gZW1wdHkga2V5IGluZGV4IGl0ZXJhdG9yIGlmIHRoZSByZXF1ZXN0ZWQgaW5kZXggbm90IGZvdW5kCi0JaWYgKGluZGV4ID09IG51bGwpIHJldHVybihfZW1wdHlLZXlJbmRleCk7Ci0KLQlyZXR1cm4oaW5kZXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGJ1aWxkcyBrZXkgaW5kZXhlcyAtIGl0IGlzIG92ZXJyaWRkZW4gaW4gdGhlIGNvbXBpbGVkCi0gICAgICogdHJhbnNsZXQgaW4gY2FzZXMgd2hlcmUgdGhlIDx4c2w6a2V5PiBlbGVtZW50IGlzIHVzZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBidWlsZEtleXMoRE9NIGRvY3VtZW50LCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IsCi0JCQkgIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyLAotCQkJICBpbnQgcm9vdCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogRE9NIGNhY2hlIGhhbmRsaW5nCi0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgIC8vIEhvbGQgdGhlIERPTSBjYWNoZSAoaWYgYW55KSB1c2VkIHdpdGggdGhpcyB0cmFuc2xldAotICAgIHByaXZhdGUgRE9NQ2FjaGUgX2RvbUNhY2hlID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIERPTSBjYWNoZSB1c2VkIGZvciBhZGRpdGlvbmFsIGRvY3VtZW50cyBsb2FkZWQgdXNpbmcgdGhlCi0gICAgICogZG9jdW1lbnQoKSBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRET01DYWNoZShET01DYWNoZSBjYWNoZSkgewotCV9kb21DYWNoZSA9IGNhY2hlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIERPTSBjYWNoZSB1c2VkIGZvciB0aGlzIHRyYW5zbGV0LiBVc2VkIGJ5IHRoZSBMb2FkRG9jdW1lbnQKLSAgICAgKiBjbGFzcyAoaWYgcHJlc2VudCkgd2hlbiB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbiBpcyB1c2VkLgotICAgICAqLwotICAgIHB1YmxpYyBET01DYWNoZSBnZXRET01DYWNoZSgpIHsKLQlyZXR1cm4oX2RvbUNhY2hlKTsKLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogU3RhcnQgb2YgYW4gaW1wbGVtZW50YXRpb24gb2YgYSBtdWx0aXBsZSBvdXRwdXQgZXh0ZW5zaW9uLgotICAgICAqIFNlZSBjb21waWxlci9UcmFuc2xldE91dHB1dCBmb3IgYWN0dWFsIGltcGxlbWVudGF0aW9uLgotICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLSAgICBwdWJsaWMgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIG9wZW5PdXRwdXRIYW5kbGVyKFN0cmluZyBmaWxlbmFtZSkgCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICAvLyBVc2UgdGhlIGRlZmF1bHQgU0FYIGhhbmRsZXIgdG8gc2VuZCB0aGUgb3V0cHV0IHRvIHRoZSBmaWxlCi0JICAgIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIGhhbmRsZXIgPQotCQluZXcgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIoZmlsZW5hbWUsIF9lbmNvZGluZyk7Ci0KLQkgICAgLy8gQ3JlYXRlIGEgdHJhbnNsZXQgb3V0cHV0IGhhbmRsZXIgYW5kIHBsdWcgaW4gdGhlIFNBWCBoYW5kbGVyCi0JICAgIFRleHRPdXRwdXQgdGV4dCA9IG5ldyBUZXh0T3V0cHV0KGhhbmRsZXIsIGhhbmRsZXIsIF9lbmNvZGluZyk7Ci0JICAgIHRyYW5zZmVyT3V0cHV0U2V0dGluZ3ModGV4dCk7Ci0JICAgIHRleHQuc3RhcnREb2N1bWVudCgpOwotCSAgICByZXR1cm4odGV4dCk7Ci0JfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGNsb3NlT3V0cHV0SGFuZGxlcihUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikgewotCXRyeSB7Ci0JICAgIGhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQkgICAgaGFuZGxlci5jbG9zZSgpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgLy8gd2hhdCBjYW4geW91IGRvPwotCX0KLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogTmF0aXZlIEFQSSB0cmFuc2Zvcm1hdGlvbiBtZXRob2RzIC0gX05PVF8gSkFYUC9UckFYCi0gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLQotICAgIC8qKgotICAgICAqIE1haW4gdHJhbnNmb3JtKCkgbWV0aG9kIC0gdGhpcyBpcyBvdmVycmlkZGVuIGJ5IHRoZSBjb21waWxlZCB0cmFuc2xldAotICAgICAqLwotICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHRyYW5zZm9ybShET00gZG9jdW1lbnQsIE5vZGVJdGVyYXRvciBpdGVyYXRvciwKLQkJCQkgICBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0KLSAgICAvKioKLSAgICAgKiBDYWxscyB0cmFuc2Zvcm0oKSB3aXRoIGEgZ2l2ZW4gb3V0cHV0IGhhbmRsZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgdm9pZCB0cmFuc2Zvcm0oRE9NIGRvY3VtZW50LCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikgCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQl0cmFuc2Zvcm0oZG9jdW1lbnQsIGRvY3VtZW50LmdldEl0ZXJhdG9yKCksIGhhbmRsZXIpOwotICAgIH0KLQkKLSAgICAvKioKLSAgICAgKiBDYWxscyB0cmFuc2Zvcm0oKSB3aXRoIGEgc2V0IG9mIGdpdmVuIG91dHB1dCBoYW5kbGVycwotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHRyYW5zZm9ybShET00gZG9jdW1lbnQsCi0JCQkJVHJhbnNsZXRPdXRwdXRIYW5kbGVyW10gaGFuZGxlcnMpIAotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JdHJhbnNmb3JtKGRvY3VtZW50LCBkb2N1bWVudC5nZXRJdGVyYXRvcigpLCBoYW5kbGVyc1swXSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXNlZCBieSBzb21lIGNvbXBpbGVkIGNvZGUgYXMgYSBzaG9ydGN1dCBmb3IgcGFzc2luZyBzdHJpbmdzIHRvIHRoZQotICAgICAqIG91dHB1dCBoYW5kbGVyCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIHZvaWQgY2hhcmFjdGVycyhmaW5hbCBTdHJpbmcgc3RyaW5nLAotCQkJCSBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikgCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQlmaW5hbCBpbnQgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCgpOwotCWhhbmRsZXIuY2hhcmFjdGVycyhzdHJpbmcudG9DaGFyQXJyYXkoKSwgMCwgbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBBZGQncyBhIG5hbWUgb2YgYW4gZWxlbWVudCB3aG9zZSB0ZXh0IGNvbnRlbnRzIHNob3VsZCBiZSBvdXRwdXQgYXMgQ0RBVEEKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGRDZGF0YUVsZW1lbnQoU3RyaW5nIG5hbWUpIHsKLQlpZiAoX2NkYXRhID09IG51bGwpIF9jZGF0YSA9IG5ldyBIYXNodGFibGUoKTsKLQlfY2RhdGEucHV0KG5hbWUsIG5hbWUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYW5zZmVyIHRoZSBvdXRwdXQgc2V0dGluZ3MgdG8gdGhlIG91dHB1dCBwb3N0LXByb2Nlc3NvcgotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHRyYW5zZmVyT3V0cHV0U2V0dGluZ3MoVHJhbnNsZXRPdXRwdXRIYW5kbGVyIG91dHB1dCkgewotCi0JLy8gSXQgaXMgYW4gZXJyb3IgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIHdpdGggYW55dGhpbmcgZWxzZSB0aGFuCi0JLy8gdGhlIHRyYW5zbGV0IHBvc3QtcHJvY2Vzc29yIChUZXh0T3V0cHV0KQotCWlmICghKG91dHB1dCBpbnN0YW5jZW9mIFRleHRPdXRwdXQpKSByZXR1cm47Ci0KLQlUZXh0T3V0cHV0IGhhbmRsZXIgPSAoVGV4dE91dHB1dClvdXRwdXQ7Ci0KLQkvLyBUcmFuc2ZlciB0aGUgb3V0cHV0IG1ldGhvZCBzZXR0aW5nCi0JaWYgKF9tZXRob2QgIT0gbnVsbCkgewotCSAgICAvLyBUcmFuc2ZlciBhbGwgc2V0dGluZ3MgcmVsZXZhbnQgdG8gWE1MIG91dHB1dAotCSAgICBpZiAoX21ldGhvZC5lcXVhbHMoInhtbCIpKSB7Ci0JCWhhbmRsZXIuc2V0VHlwZShUZXh0T3V0cHV0LlhNTCk7Ci0JCWhhbmRsZXIuc2V0Q2RhdGFFbGVtZW50cyhfY2RhdGEpOwotCQlpZiAoX3ZlcnNpb24gIT0gbnVsbCkgaGFuZGxlci5zZXRWZXJzaW9uKF92ZXJzaW9uKTsKLQkJaWYgKF9zdGFuZGFsb25lICE9IG51bGwpIGhhbmRsZXIuc2V0U3RhbmRhbG9uZShfc3RhbmRhbG9uZSk7Ci0JCWlmIChfb21pdEhlYWRlcikgaGFuZGxlci5vbWl0SGVhZGVyKHRydWUpOwotCQlpZiAoX2luZGVudCkgaGFuZGxlci5zZXRJbmRlbnQoX2luZGVudCk7Ci0JCWlmIChfZG9jdHlwZVN5c3RlbSAhPSBudWxsKQotCQkgICAgaGFuZGxlci5zZXREb2N0eXBlKF9kb2N0eXBlU3lzdGVtLCBfZG9jdHlwZVB1YmxpYyk7Ci0JICAgIH0KLQkgICAgLy8gVHJhbnNmZXIgYWxsIG91dHB1dCBzZXR0aW5ncyByZWxldmFudCB0byBIVE1MIG91dHB1dAotCSAgICBlbHNlIGlmIChfbWV0aG9kLmVxdWFscygiaHRtbCIpKSB7Ci0JCWhhbmRsZXIuc2V0VHlwZShUZXh0T3V0cHV0LkhUTUwpOwotCQlpZiAoX2luZGVudCkKLQkJICAgIGhhbmRsZXIuc2V0SW5kZW50KF9pbmRlbnQpOwotCQllbHNlCi0JCSAgICBoYW5kbGVyLnNldEluZGVudCh0cnVlKTsKLQkJaGFuZGxlci5zZXREb2N0eXBlKF9kb2N0eXBlU3lzdGVtLCBfZG9jdHlwZVB1YmxpYyk7Ci0JCWlmIChfbWVkaWFUeXBlICE9IG51bGwpIGhhbmRsZXIuc2V0TWVkaWFUeXBlKF9tZWRpYVR5cGUpOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKF9tZXRob2QuZXF1YWxzKCJ0ZXh0IikpIHsKLQkJaGFuZGxlci5zZXRUeXBlKFRleHRPdXRwdXQuVEVYVCk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCWhhbmRsZXIuc2V0VHlwZShUZXh0T3V0cHV0LlFOQU1FKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgaGFuZGxlci5zZXRDZGF0YUVsZW1lbnRzKF9jZGF0YSk7Ci0JICAgIGlmIChfdmVyc2lvbiAhPSBudWxsKSBoYW5kbGVyLnNldFZlcnNpb24oX3ZlcnNpb24pOwotCSAgICBpZiAoX3N0YW5kYWxvbmUgIT0gbnVsbCkgaGFuZGxlci5zZXRTdGFuZGFsb25lKF9zdGFuZGFsb25lKTsKLQkgICAgaWYgKF9vbWl0SGVhZGVyKSBoYW5kbGVyLm9taXRIZWFkZXIodHJ1ZSk7Ci0JICAgIGlmIChfaW5kZW50KSBoYW5kbGVyLnNldEluZGVudChfaW5kZW50KTsKLQkgICAgaGFuZGxlci5zZXREb2N0eXBlKF9kb2N0eXBlU3lzdGVtLCBfZG9jdHlwZVB1YmxpYyk7Ci0JfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9BdHRyaWJ1dGVMaXN0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL0F0dHJpYnV0ZUxpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2ViYmViNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL0F0dHJpYnV0ZUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0NCArMCwwIEBACi0vKgotICogJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLXB1YmxpYyBjbGFzcyBBdHRyaWJ1dGVMaXN0IGltcGxlbWVudHMgb3JnLnhtbC5zYXguQXR0cmlidXRlcyB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgRU1QVFlTVFJJTkcgPSAiIjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgQ0RBVEFTVFJJTkcgPSAiQ0RBVEEiOwotCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgX2F0dHJpYnV0ZXM7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgICAgX25hbWVzOwotICAgIHByaXZhdGUgVmVjdG9yICAgIF9xbmFtZXM7Ci0gICAgcHJpdmF0ZSBWZWN0b3IgICAgX3ZhbHVlczsKLSAgICBwcml2YXRlIFZlY3RvciAgICBfdXJpczsKLSAgICBwcml2YXRlIGludCAgICAgICBfbGVuZ3RoOwotCi0gICAgLyoqCi0gICAgICogQXR0cmlidXRlTGlzdCBjb25zdHJ1Y3RvcgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyaWJ1dGVMaXN0KCkgewotCV9hdHRyaWJ1dGVzID0gbmV3IEhhc2h0YWJsZSgpOwotCV9uYW1lcyAgPSBuZXcgVmVjdG9yKCk7Ci0JX3ZhbHVlcyA9IG5ldyBWZWN0b3IoKTsKLQlfcW5hbWVzID0gbmV3IFZlY3RvcigpOwotCV91cmlzICAgPSBuZXcgVmVjdG9yKCk7Ci0JX2xlbmd0aCA9IDA7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQXR0cmlidXRlcyBjbG9uZSBjb25zdHJ1Y3RvcgotICAgICAqLwotICAgIHB1YmxpYyBBdHRyaWJ1dGVMaXN0KG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMgYXR0cmlidXRlcykgewotCXRoaXMoKTsKLQlpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7Ci0JICAgIGZpbmFsIGludCBjb3VudCA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQlhZGQoYXR0cmlidXRlcy5nZXRRTmFtZShpKSxhdHRyaWJ1dGVzLmdldFZhbHVlKGkpKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZXR1cm4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIGluIHRoZSBsaXN0LiAKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKLQlyZXR1cm4oX2xlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyBOYW1lc3BhY2UgVVJJIGJ5IGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKGludCBpbmRleCkgewotCWlmIChpbmRleCA8IF9sZW5ndGgpCi0JICAgIHJldHVybigoU3RyaW5nKV91cmlzLmVsZW1lbnRBdChpbmRleCkpOwotCWVsc2UKLQkgICAgcmV0dXJuKG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgbG9jYWwgbmFtZSBieSBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgaW5kZXgpIHsKLQlpZiAoaW5kZXggPCBfbGVuZ3RoKQotCSAgICByZXR1cm4oKFN0cmluZylfbmFtZXMuZWxlbWVudEF0KGluZGV4KSk7Ci0JZWxzZQotCSAgICByZXR1cm4obnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZSBpbiB0aGlzIGxpc3QgKGJ5IHBvc2l0aW9uKS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFFOYW1lKGludCBwb3MpIHsKLQlpZiAocG9zIDwgX2xlbmd0aCkKLQkgICAgcmV0dXJuKChTdHJpbmcpX3FuYW1lcy5lbGVtZW50QXQocG9zKSk7Ci0JZWxzZQotCSAgICByZXR1cm4obnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IGluZGV4LgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShpbnQgaW5kZXgpIHsKLQlyZXR1cm4oQ0RBVEFTVFJJTkcpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IExvb2sgdXAgdGhlIGluZGV4IG9mIGFuIGF0dHJpYnV0ZSBieSBOYW1lc3BhY2UgbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbFBhcnQpIHsKLQlyZXR1cm4oMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IFhNTCAxLjAgcXVhbGlmaWVkIG5hbWUuCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcW5hbWUpIHsKLQlyZXR1cm4oMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKSB7Ci0JcmV0dXJuKENEQVRBU1RSSU5HKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHR5cGUgYnkgcW5hbWUuCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBxbmFtZSkgewotCXJldHVybihDREFUQVNUUklORyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKGludCBwb3MpIHsKLQlpZiAocG9zIDwgX2xlbmd0aCkKLQkgICAgcmV0dXJuKChTdHJpbmcpX3ZhbHVlcy5lbGVtZW50QXQocG9zKSk7Ci0JZWxzZQotCSAgICByZXR1cm4obnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB2YWx1ZSBieSBxbmFtZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBxbmFtZSkgewotCWZpbmFsIEludGVnZXIgb2JqID0gKEludGVnZXIpX2F0dHJpYnV0ZXMuZ2V0KHFuYW1lKTsKLQlpZiAob2JqID09IG51bGwpIHJldHVybiBudWxsOwotCXJldHVybihnZXRWYWx1ZShvYmouaW50VmFsdWUoKSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdmFsdWUgYnkgTmFtZXNwYWNlIG5hbWUgLSBTTE9XIQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkgewotCXJldHVybihnZXRWYWx1ZSh1cmkrJzonK2xvY2FsTmFtZSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgYW4gYXR0cmlidXRlIHRvIHRoZSBsaXN0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgYWRkKFN0cmluZyBxbmFtZSwgU3RyaW5nIHZhbHVlKSB7Ci0JLy8gU3R1ZmYgdGhlIFFOYW1lIGludG8gdGhlIG5hbWVzIHZlY3RvciAmIGhhc2h0YWJsZQotCUludGVnZXIgb2JqID0gKEludGVnZXIpX2F0dHJpYnV0ZXMuZ2V0KHFuYW1lKTsKLQlpZiAob2JqID09IG51bGwpIHsKLQkgICAgX2F0dHJpYnV0ZXMucHV0KHFuYW1lLCBvYmogPSBuZXcgSW50ZWdlcihfbGVuZ3RoKyspKTsKLQkgICAgX3FuYW1lcy5hZGRFbGVtZW50KHFuYW1lKTsKLQkgICAgX3ZhbHVlcy5hZGRFbGVtZW50KHZhbHVlKTsKLQkgICAgaW50IGNvbCA9IHFuYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0JICAgIGlmIChjb2wgPiAtMSkgewotCQlfdXJpcy5hZGRFbGVtZW50KHFuYW1lLnN1YnN0cmluZygwLGNvbCkpOwotCQlfbmFtZXMuYWRkRWxlbWVudChxbmFtZS5zdWJzdHJpbmcoY29sKzEpKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJX3VyaXMuYWRkRWxlbWVudChFTVBUWVNUUklORyk7Ci0JCV9uYW1lcy5hZGRFbGVtZW50KHFuYW1lKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgZmluYWwgaW50IGluZGV4ID0gb2JqLmludFZhbHVlKCk7Ci0JICAgIF92YWx1ZXMuc2V0KGluZGV4LCB2YWx1ZSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENsZWFycyB0aGUgYXR0cmlidXRlIGxpc3QKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLQlfbGVuZ3RoID0gMDsKLQlfYXR0cmlidXRlcy5jbGVhcigpOwotCV9uYW1lcy5yZW1vdmVBbGxFbGVtZW50cygpOwotCV92YWx1ZXMucmVtb3ZlQWxsRWxlbWVudHMoKTsKLQlfcW5hbWVzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0JX3VyaXMucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICB9Ci0gICAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL0F0dHJpYnV0ZXMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MmMzMzUwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQXR0cmlidXRlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgQXR0cmlidXRlcyBpbXBsZW1lbnRzIEF0dHJpYnV0ZUxpc3QgewotICAgIHByaXZhdGUgaW50IF9lbGVtZW50OwotICAgIHByaXZhdGUgRE9NIF9kb2N1bWVudDsKLQotICAgIHB1YmxpYyBBdHRyaWJ1dGVzKERPTSBkb2N1bWVudCwgaW50IGVsZW1lbnQpIHsKLQlfZWxlbWVudCA9IGVsZW1lbnQ7Ci0JX2RvY3VtZW50ID0gZG9jdW1lbnQ7Ci0gICAgfQotCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7Ci0JcmV0dXJuIDA7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXROYW1lKGludCBpKSB7Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKGludCBpKSB7Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRUeXBlKFN0cmluZyBuYW1lKSB7Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShpbnQgaSkgewotCXJldHVybiBudWxsOwotICAgIH0KLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIG5hbWUpIHsKLQlyZXR1cm4gbnVsbDsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL0Jhc2lzTGlicmFyeS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9CYXNpc0xpYnJhcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmQ3ZTk5Mi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL0Jhc2lzTGlicmFyeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTU1ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBFcndpbiBCb2x3aWR0IDxlamJAa2xvbXAub3JnPgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZTsKLQotLy9pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdDsKLWltcG9ydCBqYXZhLnRleHQuRGVjaW1hbEZvcm1hdFN5bWJvbHM7Ci1pbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVMaXN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuRE9NOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLlNpbmdsZXRvbkl0ZXJhdG9yOwotCi0vKioKLSAqIFN0YW5kYXJkIFhTTFQgZnVuY3Rpb25zLiBBbGwgc3RhbmRhcmQgZnVuY3Rpb25zIGV4cGVjdCB0aGUgY3VycmVudCBub2RlIAotICogYW5kIHRoZSBET00gYXMgdGhlaXIgbGFzdCB0d28gYXJndW1lbnRzLgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQmFzaXNMaWJyYXJ5IGltcGxlbWVudHMgT3BlcmF0b3JzIHsKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBFTVBUWVNUUklORyA9ICIiOwotCi0gICAgLyoqCi0gICAgICogU3RhbmRhcmQgZnVuY3Rpb24gY291bnQobm9kZS1zZXQpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBpbnQgY291bnRGKE5vZGVJdGVyYXRvciBpdGVyYXRvcikgewotCWludCBjb3VudGVyID0gMDsKLQl3aGlsZSAoaXRlcmF0b3IubmV4dCgpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkgICAgKytjb3VudGVyOwotCX0KLQlyZXR1cm4gY291bnRlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN1bShub2RlLXNldCkuIAotICAgICAqIHN0cmluZ1RvRG91YmxlIGlzIGlubGluZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBzdW1GKE5vZGVJdGVyYXRvciBpdGVyYXRvciwgRE9NIGRvbSkgewotCXRyeSB7Ci0JICAgIGRvdWJsZSByZXN1bHQgPSAwLjA7Ci0JICAgIGludCBub2RlOwotCSAgICB3aGlsZSAoKG5vZGUgPSBpdGVyYXRvci5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkJcmVzdWx0ICs9IERvdWJsZS5wYXJzZURvdWJsZShkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpKTsKLQkgICAgfQotCSAgICByZXR1cm4gcmVzdWx0OwotCX0KLQljYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLQkgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gc3RyaW5nKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdHJpbmdGKGludCBub2RlLCBET00gZG9tKSB7Ci0JcmV0dXJuIGRvbS5nZXROb2RlVmFsdWUobm9kZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdHJpbmcodmFsdWUpCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc3RyaW5nRihPYmplY3Qgb2JqLCBET00gZG9tKSB7Ci0JaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikgewotCSAgICByZXR1cm4gZG9tLmdldE5vZGVWYWx1ZSgoKE5vZGVJdGVyYXRvcilvYmopLnJlc2V0KCkubmV4dCgpKTsKLQl9Ci0JZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgTm9kZSkgewotCSAgICByZXR1cm4gZG9tLmdldE5vZGVWYWx1ZSgoKE5vZGUpb2JqKS5ub2RlKTsKLQl9Ci0JZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRE9NKSB7Ci0JICAgIHJldHVybiAoKERPTSlvYmopLmdldFN0cmluZ1ZhbHVlKCk7Ci0JfQotCWVsc2UgewotCSAgICByZXR1cm4gb2JqLnRvU3RyaW5nKCk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gc3RyaW5nKHZhbHVlKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN0cmluZ0YoT2JqZWN0IG9iaiwgaW50IG5vZGUsIERPTSBkb20pIHsKLQlpZiAob2JqIGluc3RhbmNlb2YgTm9kZUl0ZXJhdG9yKSB7Ci0JICAgIHJldHVybiBkb20uZ2V0Tm9kZVZhbHVlKCgoTm9kZUl0ZXJhdG9yKW9iaikucmVzZXQoKS5uZXh0KCkpOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlKSB7Ci0JICAgIHJldHVybiBkb20uZ2V0Tm9kZVZhbHVlKCgoTm9kZSlvYmopLm5vZGUpOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBET00pIHsKLQkgICAgLy8gV2hlbiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYSBET00gd2Ugd2FudCB0aGUgd2hvbGUgZmVja2luZwotCSAgICAvLyBET00gYW5kIG5vdCBqdXN0IGEgc2luZ2xlIG5vZGUgLSB0aGF0IHdvdWxkIG5vdCBtYWtlIHNlbnNlLgotCSAgICAvL3JldHVybiAoKERPTSlvYmopLmdldE5vZGVWYWx1ZShub2RlKTsKLQkgICAgcmV0dXJuICgoRE9NKW9iaikuZ2V0U3RyaW5nVmFsdWUoKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJldHVybiBvYmoudG9TdHJpbmcoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBudW1iZXIoKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG51bWJlckYoaW50IG5vZGUsIERPTSBkb20pIHsKLQlyZXR1cm4gc3RyaW5nVG9SZWFsKGRvbS5nZXROb2RlVmFsdWUobm9kZSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gbnVtYmVyKHZhbHVlKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlIG51bWJlckYoT2JqZWN0IG9iaiwgRE9NIGRvbSkgewotCWlmIChvYmogaW5zdGFuY2VvZiBEb3VibGUpIHsKLQkgICAgcmV0dXJuICgoRG91YmxlKSBvYmopLmRvdWJsZVZhbHVlKCk7Ci0JfQotCWVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIEludGVnZXIpIHsKLQkgICAgcmV0dXJuICgoSW50ZWdlcikgb2JqKS5kb3VibGVWYWx1ZSgpOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0JICAgIHJldHVybiAgKChCb29sZWFuKSBvYmopLmJvb2xlYW5WYWx1ZSgpID8gMS4wIDogMC4wOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBTdHJpbmcpIHsKLQkgICAgcmV0dXJuIHN0cmluZ1RvUmVhbCgoU3RyaW5nKSBvYmopOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlSXRlcmF0b3IpIHsKLQkgICAgTm9kZUl0ZXJhdG9yIGl0ZXIgPSAoTm9kZUl0ZXJhdG9yKSBvYmo7Ci0JICAgIHJldHVybiBzdHJpbmdUb1JlYWwoZG9tLmdldE5vZGVWYWx1ZShpdGVyLnJlc2V0KCkubmV4dCgpKSk7Ci0JfQotCWVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGUpIHsKLQkgICAgcmV0dXJuIHN0cmluZ1RvUmVhbChkb20uZ2V0Tm9kZVZhbHVlKCgoTm9kZSkgb2JqKS5ub2RlKSk7Ci0JfQotCWVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERPTSkgewotCSAgICByZXR1cm4gc3RyaW5nVG9SZWFsKCgoRE9NKSBvYmopLmdldFN0cmluZ1ZhbHVlKCkpOwotCX0KLQllbHNlIHsKLQkgICAgcnVuVGltZUVycm9yKCJJbnZhbGlkIGFyZ3VtZW50IHR5cGUgaW4gY2FsbCB0byBudW1iZXIoKS4iKTsKLQkgICAgcmV0dXJuIDAuMDsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBib29sZWFuKCkKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gYm9vbGVhbkYoT2JqZWN0IG9iaikgewotCWlmIChvYmogaW5zdGFuY2VvZiBEb3VibGUpIHsKLQkgICAgZmluYWwgZG91YmxlIHRlbXAgPSAoKERvdWJsZSkgb2JqKS5kb3VibGVWYWx1ZSgpOwotCSAgICByZXR1cm4gdGVtcCAhPSAwLjAgJiYgIURvdWJsZS5pc05hTih0ZW1wKTsKLQl9Ci0JZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgSW50ZWdlcikgewotCSAgICByZXR1cm4gKChJbnRlZ2VyKSBvYmopLmRvdWJsZVZhbHVlKCkgIT0gMDsKLQl9Ci0JZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgQm9vbGVhbikgewotCSAgICByZXR1cm4gICgoQm9vbGVhbikgb2JqKS5ib29sZWFuVmFsdWUoKTsKLQl9Ci0JZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgU3RyaW5nKSB7Ci0JICAgIHJldHVybiAhKChTdHJpbmcpIG9iaikuZXF1YWxzKEVNUFRZU1RSSU5HKTsKLQl9Ci0JZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgTm9kZUl0ZXJhdG9yKSB7Ci0JICAgIE5vZGVJdGVyYXRvciBpdGVyID0gKE5vZGVJdGVyYXRvcikgb2JqOwotCSAgICByZXR1cm4gaXRlci5yZXNldCgpLm5leHQoKSAhPSBOb2RlSXRlcmF0b3IuRU5EOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlKSB7Ci0JICAgIHJldHVybiB0cnVlOwotCX0KLQllbHNlIGlmIChvYmogaW5zdGFuY2VvZiBET00pIHsKLQkgICAgU3RyaW5nIHRlbXAgPSAoKERPTSkgb2JqKS5nZXRTdHJpbmdWYWx1ZSgpOwotCSAgICByZXR1cm4gIXRlbXAuZXF1YWxzKEVNUFRZU1RSSU5HKTsKLQl9Ci0JZWxzZSB7Ci0JICAgIHJ1blRpbWVFcnJvcigiSW52YWxpZCBhcmd1bWVudCB0eXBlIGluIGNhbGwgdG8gbnVtYmVyKCkuIik7Ci0JfQotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN1YnN0cmluZygpLiBNdXN0IHRha2UgYSBkb3VibGUgYmVjYXVzZSBvZgotICAgICAqIGNvbnZlcnNpb25zIHJlc3VsdGluZyBpbnRvIE5hTnMgYW5kIHJvdW5kaW5nLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN1YnN0cmluZ0YoU3RyaW5nIHZhbHVlLCBkb3VibGUgc3RhcnQpIHsKLQl0cnkgewotCSAgICBmaW5hbCBpbnQgc3RybGVuID0gdmFsdWUubGVuZ3RoKCk7Ci0JICAgIGludCBpc3RhcnQgPSAoaW50KU1hdGgucm91bmQoc3RhcnQpIC0gMTsKLQotCSAgICBpZiAoRG91YmxlLmlzTmFOKHN0YXJ0KSkgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLQkgICAgaWYgKGlzdGFydCA+IHN0cmxlbikgcmV0dXJuKEVNUFRZU1RSSU5HKTsKLSAJICAgIGlmIChpc3RhcnQgPCAxKSBpc3RhcnQgPSAwOwotCi0JICAgIHJldHVybiB2YWx1ZS5zdWJzdHJpbmcoaXN0YXJ0KTsKLQl9Ci0JY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgewotCSAgICBydW5UaW1lSW50ZXJuYWxFcnJvcigpOwotCSAgICByZXR1cm4gbnVsbDsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdWJzdHJpbmcoKS4gTXVzdCB0YWtlIGEgZG91YmxlIGJlY2F1c2Ugb2YKLSAgICAgKiBjb252ZXJzaW9ucyByZXN1bHRpbmcgaW50byBOYU5zIGFuZCByb3VuZGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdWJzdHJpbmdGKFN0cmluZyB2YWx1ZSwgZG91YmxlIHN0YXJ0LCBkb3VibGUgbGVuZ3RoKSB7Ci0JdHJ5IHsKLQkgICAgZmluYWwgaW50IHN0cmxlbiAgPSB2YWx1ZS5sZW5ndGgoKTsKLQkgICAgaW50IGlzdGFydCA9IChpbnQpTWF0aC5yb3VuZChzdGFydCkgLSAxOwotCSAgICBpbnQgaXN1bSAgID0gaXN0YXJ0ICsgKGludClNYXRoLnJvdW5kKGxlbmd0aCk7Ci0KLQkgICAgaWYgKERvdWJsZS5pc05hTihzdGFydCkgfHwgRG91YmxlLmlzTmFOKGxlbmd0aCkpCi0JCXJldHVybihFTVBUWVNUUklORyk7Ci0JICAgIGlmIChpc3RhcnQgPiBzdHJsZW4pIHJldHVybihFTVBUWVNUUklORyk7Ci0JICAgIGlmIChpc3VtIDwgMCkgIHJldHVybihFTVBUWVNUUklORyk7Ci0KLSAJICAgIGlmIChpc3RhcnQgPCAwKSBpc3RhcnQgPSAwOwotCi0JICAgIGlmIChpc3VtID4gc3RybGVuKQotCQlyZXR1cm4gdmFsdWUuc3Vic3RyaW5nKGlzdGFydCk7Ci0JICAgIGVsc2UKLQkJcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhpc3RhcnQsIGlzdW0pOwotCX0KLQljYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7Ci0JICAgIHJ1blRpbWVJbnRlcm5hbEVycm9yKCk7Ci0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN1YnN0cmluZy1hZnRlcigpLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBzdWJzdHJpbmdfYWZ0ZXJGKFN0cmluZyB2YWx1ZSwgU3RyaW5nIHN1YnN0cmluZykgewotCWZpbmFsIGludCBpbmRleCA9IHZhbHVlLmluZGV4T2Yoc3Vic3RyaW5nKTsKLQlpZiAoaW5kZXggPj0gMCkKLQkgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhpbmRleCArIHN1YnN0cmluZy5sZW5ndGgoKSk7Ci0JZWxzZQotCSAgICByZXR1cm4gRU1QVFlTVFJJTkc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBzdWJzdHJpbmctYmVmb3JlKCkuIAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN1YnN0cmluZ19iZWZvcmVGKFN0cmluZyB2YWx1ZSwgU3RyaW5nIHN1YnN0cmluZykgewotCWZpbmFsIGludCBpbmRleCA9IHZhbHVlLmluZGV4T2Yoc3Vic3RyaW5nKTsKLQlpZiAoaW5kZXggPj0gMCkKLQkgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZygwLCBpbmRleCk7Ci0JZWxzZQotCSAgICByZXR1cm4gRU1QVFlTVFJJTkc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiB0cmFuc2xhdGUoKS4gCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdHJhbnNsYXRlRihTdHJpbmcgdmFsdWUsIFN0cmluZyBmcm9tLCBTdHJpbmcgdG8pIHsKLQlmaW5hbCBpbnQgdG9sID0gdG8ubGVuZ3RoKCk7Ci0JZmluYWwgaW50IGZyb21sID0gZnJvbS5sZW5ndGgoKTsKLQlmaW5hbCBpbnQgdmFsdWVsID0gdmFsdWUubGVuZ3RoKCk7Ci0KLQlmaW5hbCBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCWZvciAoaW50IGosIGkgPSAwOyBpIDwgdmFsdWVsOyBpKyspIHsKLQkgICAgZmluYWwgY2hhciBjaCA9IHZhbHVlLmNoYXJBdChpKTsKLQkgICAgZm9yIChqID0gMDsgaiA8IGZyb21sOyBqKyspIHsKLQkJaWYgKGNoID09IGZyb20uY2hhckF0KGopKSB7Ci0JCSAgICBpZiAoaiA8IHRvbCkKLQkJCXJlc3VsdC5hcHBlbmQodG8uY2hhckF0KGopKTsKLQkJICAgIGJyZWFrOwotCQl9Ci0JICAgIH0JCi0JICAgIGlmIChqID09IGZyb21sKQotCQlyZXN1bHQuYXBwZW5kKGNoKTsKLQl9Ci0JcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gbm9ybWFsaXplLXNwYWNlKCkuIAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZV9zcGFjZUYoaW50IG5vZGUsIERPTSBkb20pIHsKLQlyZXR1cm4gbm9ybWFsaXplX3NwYWNlRihkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIG5vcm1hbGl6ZS1zcGFjZShzdHJpbmcpLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBub3JtYWxpemVfc3BhY2VGKFN0cmluZyB2YWx1ZSkgewotCWludCBpID0gMCwgbiA9IHZhbHVlLmxlbmd0aCgpOwotCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLQl3aGlsZSAoaSA8IG4gJiYgaXNXaGl0ZVNwYWNlKHZhbHVlLmNoYXJBdChpKSkpCi0JICAgIGkrKzsKLQotCXdoaWxlICh0cnVlKSB7Ci0JICAgIHdoaWxlIChpIDwgbiAmJiAhaXNXaGl0ZVNwYWNlKHZhbHVlLmNoYXJBdChpKSkpIHsKLQkJcmVzdWx0LmFwcGVuZCh2YWx1ZS5jaGFyQXQoaSsrKSk7Ci0JICAgIH0KLQkgICAgaWYgKGkgPT0gbikKLQkJYnJlYWs7Ci0JICAgIHdoaWxlIChpIDwgbiAmJiBpc1doaXRlU3BhY2UodmFsdWUuY2hhckF0KGkpKSkgewotCQlpKys7Ci0JICAgIH0KLQkgICAgaWYgKGkgPCBuKQotCQlyZXN1bHQuYXBwZW5kKCcgJyk7Ci0JfQotCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIGdlbmVyYXRlLWlkKCkuIAotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdlbmVyYXRlX2lkRihpbnQgbm9kZSkgewotCWlmIChub2RlID4gMCkKLQkgICAgLy8gT25seSBnZW5lcmF0ZSBJRCBpZiBub2RlIGV4aXN0cwotCSAgICByZXR1cm4gIk4iICsgbm9kZTsKLQllbHNlCi0JICAgIC8vIE90aGVyd2lzZSByZXR1cm4gYW4gZW1wdHkgc3RyaW5nCi0JICAgIHJldHVybiBFTVBUWVNUUklORzsKLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogdXRpbGl0eSBmdW5jdGlvbiBmb3IgY2FsbHMgdG8gbG9jYWwtbmFtZSgpLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRMb2NhbE5hbWUoU3RyaW5nIHZhbHVlKSB7Ci0JaW50IGlkeCA9IHZhbHVlLmxhc3RJbmRleE9mKCc6Jyk7Ci0JaWYgKGlkeCA+PSAwKSB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZyhpZHggKyAxKTsKLQlpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZignQCcpOwotCWlmIChpZHggPj0gMCkgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoaWR4ICsgMSk7Ci0JcmV0dXJuKHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBFeHRlcm5hbCBmdW5jdGlvbnMgdGhhdCBjYW5ub3QgYmUgcmVzb2x2ZWQgYXJlIHJlcGxhY2VkIHdpdGggYSBjYWxsCi0gICAgICogdG8gdGhpcyBtZXRob2QuIFRoaXMgbWV0aG9kIHdpbGwgZ2VuZXJhdGUgYSBydW50aW1lIGVycm9ycy4gQSBnb29kCi0gICAgICogc3R5bGVzaGVldCBjaGVja3Mgd2hldGhlciB0aGUgZnVuY3Rpb24gZXhpc3RzIHVzaW5nIGNvbmRpdGlvbmFsCi0gICAgICogY29uc3RydWN0cywgYW5kIG5ldmVyIHJlYWxseSB0cmllcyB0byBjYWxsIGl0IGlmIGl0IGRvZXNuJ3QgZXhpc3QuCi0gICAgICogQnV0IHNpbXBsZSBzdHlsZXNoZWV0cyBtYXkgcmVzdWx0IGluIGEgY2FsbCB0byB0aGlzIG1ldGhvZC4KLSAgICAgKiBUaGUgY29tcGlsZXIgc2hvdWxkIGdlbmVyYXRlIGEgd2FybmluZyBpZiBpdCBlbmNvdW50ZXJzIGEgY2FsbCB0bwotICAgICAqIGFuIHVucmVzb2x2ZWQgZXh0ZXJuYWwgZnVuY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHVucmVzb2x2ZWRfZXh0ZXJuYWxGKFN0cmluZyBuYW1lKSB7Ci0JcnVuVGltZUVycm9yKCJFeHRlcm5hbCBmdW5jdGlvbiAnIituYW1lKyInIG5vdCBzdXBwb3J0ZWQgYnkgWFNMVEMuIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogWFNMVCBTdGFuZGFyZCBmdW5jdGlvbiBuYW1lc3BhY2UtdXJpKG5vZGUtc2V0KS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBuYW1lc3BhY2VfdXJpRihOb2RlSXRlcmF0b3IgaXRlciwgRE9NIGRvbSkgewotCXJldHVybiBuYW1lc3BhY2VfdXJpRihpdGVyLm5leHQoKSwgZG9tKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBYU0xUIFN0YW5kYXJkIGZ1bmN0aW9uIHN5c3RlbS1wcm9wZXJ0eShuYW1lKQotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHN5c3RlbV9wcm9wZXJ0eUYoU3RyaW5nIG5hbWUpIHsKLQlpZiAobmFtZS5lcXVhbHMoInhzbDp2ZXJzaW9uIikpCi0JICAgIHJldHVybigiMS4wIik7Ci0JaWYgKG5hbWUuZXF1YWxzKCJ4c2w6dmVuZG9yIikpCi0JICAgIHJldHVybigiU3VuIE1pY3Jvc3lzdGVtcycgeHNsdGMiKTsKLQlpZiAobmFtZS5lcXVhbHMoInhzbDp2ZW5kb3ItdXJsIikpCi0JICAgIHJldHVybigiaHR0cDovL3d3dy5zdW4uY29tLyIpOwotCQotCXJ1blRpbWVFcnJvcigiSW52YWxpZCBhcmd1bWVudCB0eXBlICciK25hbWUrCi0JCSAgICAgIicgaW4gY2FsbCB0byBzeXN0ZW0tcHJvcGVydHkoKS4iKTsKLQlyZXR1cm4oRU1QVFlTVFJJTkcpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFhTTFQgU3RhbmRhcmQgZnVuY3Rpb24gbmFtZXNwYWNlLXVyaSgpLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBuYW1lc3BhY2VfdXJpRihpbnQgbm9kZSwgRE9NIGRvbSkgewotCWZpbmFsIFN0cmluZyB2YWx1ZSA9IGRvbS5nZXROb2RlTmFtZShub2RlKTsKLQlmaW5hbCBpbnQgY29sb24gPSB2YWx1ZS5sYXN0SW5kZXhPZignOicpOwotCWlmIChjb2xvbiA+PSAwKQotCSAgICByZXR1cm4gdmFsdWUuc3Vic3RyaW5nKDAsIGNvbG9uKTsKLQllbHNlCi0JICAgIHJldHVybiBFTVBUWVNUUklORzsKLSAgICB9Ci0KLSAgICAvLy0tIEJlZ2luIHV0aWxpdHkgZnVuY3Rpb25zCi0KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzV2hpdGVTcGFjZShjaGFyIGNoKSB7Ci0JcmV0dXJuIGNoID09ICcgJyB8fCBjaCA9PSAnXHQnIHx8IGNoID09ICdcbicgfHwgY2ggPT0gJ1xyJzsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFN0cmluZyBsc3RyaW5nLCBTdHJpbmcgcnN0cmluZywKLQkJCQkJICBpbnQgb3AsIERPTSBkb20pIHsKLQlzd2l0Y2ggKG9wKSB7Ci0JY2FzZSBFUToKLQkgICAgcmV0dXJuIGxzdHJpbmcuZXF1YWxzKHJzdHJpbmcpOwotCi0JY2FzZSBORToKLQkgICAgcmV0dXJuICFsc3RyaW5nLmVxdWFscyhyc3RyaW5nKTsKLQotCWNhc2UgR1Q6Ci0JICAgIHJldHVybiBudW1iZXJGKGxzdHJpbmcsIGRvbSkgPiBudW1iZXJGKHJzdHJpbmcsIGRvbSk7Ci0KLQljYXNlIExUOgotCSAgICByZXR1cm4gbnVtYmVyRihsc3RyaW5nLCBkb20pIDwgbnVtYmVyRihyc3RyaW5nLCBkb20pOwotCi0JY2FzZSBHRToKLQkgICAgcmV0dXJuIG51bWJlckYobHN0cmluZywgZG9tKSA+PSBudW1iZXJGKHJzdHJpbmcsIGRvbSk7Ci0KLQljYXNlIExFOgotCSAgICByZXR1cm4gbnVtYmVyRihsc3RyaW5nLCBkb20pIDw9IG51bWJlckYocnN0cmluZywgZG9tKTsKLQotCWRlZmF1bHQ6Ci0JICAgIHJ1blRpbWVJbnRlcm5hbEVycm9yKCk7Ci0JICAgIHJldHVybiBmYWxzZTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogbm9kZS1zZXQvbm9kZS1zZXQgY29tcGFyZS4gCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNvbXBhcmUoTm9kZUl0ZXJhdG9yIGxlZnQsIE5vZGVJdGVyYXRvciByaWdodCwKLQkJCQkgIGludCBvcCwgaW50IG5vZGUsIERPTSBkb20pIHsKLQlpbnQgbG5vZGU7Ci0JbGVmdC5yZXNldCgpOwotCQotCXdoaWxlICgobG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gTm9kZUl0ZXJhdG9yLkVORCkgewotCSAgICBmaW5hbCBTdHJpbmcgbHZhbHVlID0gZG9tLmdldE5vZGVWYWx1ZShsbm9kZSk7Ci0JICAgIAotCSAgICBpbnQgcm5vZGU7Ci0JICAgIHJpZ2h0LnJlc2V0KCk7Ci0JICAgIHdoaWxlICgocm5vZGUgPSByaWdodC5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkJaWYgKGNvbXBhcmVTdHJpbmdzKGx2YWx1ZSwgZG9tLmdldE5vZGVWYWx1ZShybm9kZSksIG9wLCBkb20pKSB7Ci0JCSAgICByZXR1cm4gdHJ1ZTsKLQkJfQotCSAgICB9Ci0JfSAKLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogbm9kZS9ub2RlLXNldCBjb21wYXJlLgotICAgICAqLwotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb21wYXJlKGludCBub2RlLCBOb2RlSXRlcmF0b3Igbm9kZVNldCwKLQkJCQkgIGludCBvcCwgRE9NIGRvbSkgewotCWZpbmFsIFN0cmluZyBsdmFsdWUgPSBkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpOwotCWludCBybm9kZTsKLQlub2RlU2V0LnJlc2V0KCk7Ci0Jd2hpbGUgKChybm9kZSA9IG5vZGVTZXQubmV4dCgpKSAhPSBOb2RlSXRlcmF0b3IuRU5EKSB7Ci0JICAgIGlmIChjb21wYXJlU3RyaW5ncyhsdmFsdWUsIGRvbS5nZXROb2RlVmFsdWUocm5vZGUpLCBvcCwgZG9tKSkgewotCQlyZXR1cm4gdHJ1ZTsKLQkgICAgfQotCX0gCi0JcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb21wYXJlKGludCBub2RlLCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IsCi0JCQkJICBpbnQgb3AsIGludCBkdW1teSwgRE9NIGRvbSkgewotCWl0ZXJhdG9yLnJlc2V0KCk7Ci0KLQlpbnQgcm5vZGU7Ci0JU3RyaW5nIHZhbHVlOwotCi0Jc3dpdGNoKG9wKSB7Ci0JY2FzZSBFUToKLQkgICAgLyogVE9ETzoKLQkgICAgICogVGhpcyBuZWVkcyBmaWd1cmluZyBvdXQ6IFdoYXQgc29ydCBvZiBjb21wYXJpc29uIGlzIGRvbmUgaGVyZT8KLQkgICAgICogQXJlIHdlIGNvbXBhcmluZyBleGFjdCBub2RlIGlkJ3MsIG5vZGUgdHlwZXMsIG9yIG5vZGUgdmFsdWVzPwotCSAgICAgKiBWYWx1ZXMgaXMgdGhlIG9idmlvdXMgZm9yIGF0dHJpYnV0ZXMsIGJ1dCB3aGF0IGFib3V0IGVsZW1lbnRzPwotCSAgICAgKi8KLQkgICAgdmFsdWUgPSBkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpOwotCSAgICB3aGlsZSAoKHJub2RlID0gaXRlcmF0b3IubmV4dCgpKSAhPSBOb2RlSXRlcmF0b3IuRU5EKQotCQlpZiAodmFsdWUuZXF1YWxzKGRvbS5nZXROb2RlVmFsdWUocm5vZGUpKSkgcmV0dXJuIHRydWU7Ci0JICAgIC8vIGlmIChybm9kZSA9PSBub2RlKSByZXR1cm4gdHJ1ZTsgSXQganVzdCBhaW4ndCB0aGF0IGVhc3khISEKLQkgICAgYnJlYWs7Ci0JY2FzZSBORToKLQkgICAgdmFsdWUgPSBkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpOwotCSAgICB3aGlsZSAoKHJub2RlID0gaXRlcmF0b3IubmV4dCgpKSAhPSBOb2RlSXRlcmF0b3IuRU5EKQotCQlpZiAoIXZhbHVlLmVxdWFscyhkb20uZ2V0Tm9kZVZhbHVlKHJub2RlKSkpIHJldHVybiB0cnVlOwotCSAgICAvLyBpZiAocm5vZGUgIT0gbm9kZSkgcmV0dXJuIHRydWU7Ci0JICAgIGJyZWFrOwotCWNhc2UgTFQ6Ci0JICAgIC8vIEFzc3VtZSB3ZSdyZSBjb21wYXJpbmcgZG9jdW1lbnQgb3JkZXIgaGVyZQotCSAgICB3aGlsZSAoKHJub2RlID0gaXRlcmF0b3IubmV4dCgpKSAhPSBOb2RlSXRlcmF0b3IuRU5EKQotCQlpZiAocm5vZGUgPiBub2RlKSByZXR1cm4gdHJ1ZTsKLQkgICAgYnJlYWs7Ci0JY2FzZSBHVDoKLQkgICAgLy8gQXNzdW1lIHdlJ3JlIGNvbXBhcmluZyBkb2N1bWVudCBvcmRlciBoZXJlCi0JICAgIHdoaWxlICgocm5vZGUgPSBpdGVyYXRvci5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpCi0JCWlmIChybm9kZSA8IG5vZGUpIHJldHVybiB0cnVlOwotCSAgICBicmVhazsKLQl9IAotCXJldHVybihmYWxzZSk7Ci0gICAgfQotCi0gICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNvbXBhcmUoTm9kZUl0ZXJhdG9yIGxlZnQsIGZpbmFsIGRvdWJsZSBybnVtYmVyLAotCQkJCSAgZmluYWwgaW50IG9wLCBmaW5hbCBpbnQgbm9kZSwgRE9NIGRvbSkgewotCXJldHVybihjb21wYXJlKGxlZnQscm51bWJlcixvcCxkb20pKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiBub2RlLXNldC9udW1iZXIgY29tcGFyZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29tcGFyZShOb2RlSXRlcmF0b3IgbGVmdCwgZmluYWwgZG91YmxlIHJudW1iZXIsCi0JCQkJICBmaW5hbCBpbnQgb3AsIERPTSBkb20pIHsKLQlpbnQgbm9kZTsKLQlsZWZ0LnJlc2V0KCk7Ci0KLQlzd2l0Y2ggKG9wKSB7Ci0JY2FzZSBFUToKLQkgICAgd2hpbGUgKChub2RlID0gbGVmdC5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkJaWYgKG51bWJlckYoZG9tLmdldE5vZGVWYWx1ZShub2RlKSwgZG9tKSA9PSBybnVtYmVyKQotCQkgICAgcmV0dXJuIHRydWU7Ci0JICAgIH0KLQkgICAgYnJlYWs7Ci0KLQljYXNlIE5FOgotCSAgICB3aGlsZSAoKG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gTm9kZUl0ZXJhdG9yLkVORCkgewotCQlpZiAobnVtYmVyRihkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpLCBkb20pICE9IHJudW1iZXIpCi0JCSAgICByZXR1cm4gdHJ1ZTsKLQkgICAgfQotCSAgICBicmVhazsKLQotCWNhc2UgR1Q6Ci0JICAgIHdoaWxlICgobm9kZSA9IGxlZnQubmV4dCgpKSAhPSBOb2RlSXRlcmF0b3IuRU5EKSB7Ci0JCWlmIChudW1iZXJGKGRvbS5nZXROb2RlVmFsdWUobm9kZSksIGRvbSkgPiBybnVtYmVyKQotCQkgICAgcmV0dXJuIHRydWU7Ci0JICAgIH0KLQkgICAgYnJlYWs7Ci0KLQljYXNlIExUOgotCSAgICB3aGlsZSAoKG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gTm9kZUl0ZXJhdG9yLkVORCkgewotCQlpZiAobnVtYmVyRihkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpLCBkb20pIDwgcm51bWJlcikKLQkJICAgIHJldHVybiB0cnVlOwotCSAgICB9Ci0JICAgIGJyZWFrOwotCi0JY2FzZSBHRToKLQkgICAgd2hpbGUgKChub2RlID0gbGVmdC5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkJaWYgKG51bWJlckYoZG9tLmdldE5vZGVWYWx1ZShub2RlKSwgZG9tKSA+PSBybnVtYmVyKQotCQkgICAgcmV0dXJuIHRydWU7Ci0JICAgIH0KLQkgICAgYnJlYWs7Ci0KLQljYXNlIExFOgotCSAgICB3aGlsZSAoKG5vZGUgPSBsZWZ0Lm5leHQoKSkgIT0gTm9kZUl0ZXJhdG9yLkVORCkgewotCQlpZiAobnVtYmVyRihkb20uZ2V0Tm9kZVZhbHVlKG5vZGUpLCBkb20pIDw9IHJudW1iZXIpCi0JCSAgICByZXR1cm4gdHJ1ZTsKLQkgICAgfQotCSAgICBicmVhazsKLQotCWRlZmF1bHQ6Ci0JICAgIHJ1blRpbWVJbnRlcm5hbEVycm9yKCk7Ci0JfQotCi0JcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IG5vZGUtc2V0L3N0cmluZyBjb21wYXJpc29uLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29tcGFyZShOb2RlSXRlcmF0b3IgbGVmdCwgZmluYWwgU3RyaW5nIHJzdHJpbmcsCi0JCQkJICBpbnQgb3AsIERPTSBkb20pIHsKLQlpbnQgbm9kZTsKLQlsZWZ0LnJlc2V0KCk7Ci0Jd2hpbGUgKChub2RlID0gbGVmdC5uZXh0KCkpICE9IE5vZGVJdGVyYXRvci5FTkQpIHsKLQkgICAgaWYgKGNvbXBhcmVTdHJpbmdzKGRvbS5nZXROb2RlVmFsdWUobm9kZSksIHJzdHJpbmcsIG9wLCBkb20pKSB7Ci0JCXJldHVybiB0cnVlOwotCSAgICB9Ci0JfQotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29tcGFyZShOb2RlSXRlcmF0b3IgbGVmdCwgZmluYWwgU3RyaW5nIHJzdHJpbmcsCi0JCQkJICBpbnQgb3AsIGludCBub2RlLCBET00gZG9tKSB7Ci0JCi0JaWYgKGNvbXBhcmVTdHJpbmdzKGRvbS5nZXROb2RlVmFsdWUobm9kZSksIHJzdHJpbmcsIG9wLCBkb20pKSB7Ci0JICAgIHJldHVybiB0cnVlOwotCX0KLQllbHNlIHsKLQkgICAgcmV0dXJuIGZhbHNlOwotCX0KLSAgICB9Ci0KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gY29tcGFyZShPYmplY3QgbGVmdCwgT2JqZWN0IHJpZ2h0LAotCQkJCSAgaW50IG9wLCBpbnQgbm9kZSwgRE9NIGRvbSkgeyAKLQlib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotCWJvb2xlYW4gaGFzU2ltcGxlQXJncyA9IGhhc1NpbXBsZVR5cGUobGVmdCkgJiYgaGFzU2ltcGxlVHlwZShyaWdodCk7Ci0KLQlpZiAob3AgIT0gRVEgJiYgb3AgIT0gTkUpIHsKLQkgICAgLy8gSWYgbm9kZS1ib29sZWFuIGNvbXBhcmlzb24gLT4gY29udmVydCBub2RlIHRvIGJvb2xlYW4KLQkgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBOb2RlIHx8IHJpZ2h0IGluc3RhbmNlb2YgTm9kZSkgewotCQlpZiAobGVmdCBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLQkJICAgIHJpZ2h0ID0gbmV3IEJvb2xlYW4oYm9vbGVhbkYocmlnaHQpKTsKLQkJICAgIGhhc1NpbXBsZUFyZ3MgPSB0cnVlOwotCQl9Ci0JCWlmIChyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLQkJICAgIGxlZnQgPSBuZXcgQm9vbGVhbihib29sZWFuRihsZWZ0KSk7Ci0JCSAgICBoYXNTaW1wbGVBcmdzID0gdHJ1ZTsKLQkJfQotCSAgICB9Ci0KLQkgICAgaWYgKGhhc1NpbXBsZUFyZ3MpIHsKLQkJc3dpdGNoIChvcCkgewotCQljYXNlIEdUOgotCQkgICAgcmV0dXJuIG51bWJlckYobGVmdCwgZG9tKSA+IG51bWJlckYocmlnaHQsIGRvbSk7Ci0JCSAgICAKLQkJY2FzZSBMVDoKLQkJICAgIHJldHVybiBudW1iZXJGKGxlZnQsIGRvbSkgPCBudW1iZXJGKHJpZ2h0LCBkb20pOwotCQkgICAgCi0JCWNhc2UgR0U6Ci0JCSAgICByZXR1cm4gbnVtYmVyRihsZWZ0LCBkb20pID49IG51bWJlckYocmlnaHQsIGRvbSk7Ci0JCSAgICAKLQkJY2FzZSBMRToKLQkJICAgIHJldHVybiBudW1iZXJGKGxlZnQsIGRvbSkgPD0gbnVtYmVyRihyaWdodCwgZG9tKTsKLQkJICAgIAotCQlkZWZhdWx0OgotCQkgICAgcnVuVGltZUludGVybmFsRXJyb3IoKTsKLQkJfQotCSAgICB9Ci0JICAgIC8vIGZhbGxzIHRocm91Z2gKLQl9Ci0KLQlpZiAoaGFzU2ltcGxlQXJncykgewotCSAgICBpZiAobGVmdCBpbnN0YW5jZW9mIEJvb2xlYW4gfHwgcmlnaHQgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0JCXJlc3VsdCA9IGJvb2xlYW5GKGxlZnQpID09IGJvb2xlYW5GKHJpZ2h0KTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChsZWZ0IGluc3RhbmNlb2YgRG91YmxlIHx8IHJpZ2h0IGluc3RhbmNlb2YgRG91YmxlIHx8Ci0JCSAgICAgbGVmdCBpbnN0YW5jZW9mIEludGVnZXIgfHwgcmlnaHQgaW5zdGFuY2VvZiBJbnRlZ2VyKSB7Ci0JCXJlc3VsdCA9IG51bWJlckYobGVmdCwgZG9tKSA9PSBudW1iZXJGKHJpZ2h0LCBkb20pOwotCSAgICB9Ci0JICAgIGVsc2UgeyAvLyBjb21wYXJlIHRoZW0gYXMgc3RyaW5ncwotCQlyZXN1bHQgPSBzdHJpbmdGKGxlZnQsIGRvbSkuZXF1YWxzKHN0cmluZ0YocmlnaHQsIGRvbSkpOwotCSAgICB9Ci0KLQkgICAgaWYgKG9wID09IE9wZXJhdG9ycy5ORSkgewotCQlyZXN1bHQgPSAhcmVzdWx0OwotCSAgICB9Ci0JfQotCWVsc2UgewotCSAgICBpZiAobGVmdCBpbnN0YW5jZW9mIE5vZGUpIHsKLQkJbGVmdCA9IG5ldyBTaW5nbGV0b25JdGVyYXRvcigoKE5vZGUpbGVmdCkubm9kZSk7Ci0JICAgIH0KLQkgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgTm9kZSkgewotCQlyaWdodCA9IG5ldyBTaW5nbGV0b25JdGVyYXRvcigoKE5vZGUpcmlnaHQpLm5vZGUpOwotCSAgICB9Ci0KLQkgICAgaWYgKGhhc1NpbXBsZVR5cGUobGVmdCkgfHwKLQkJbGVmdCBpbnN0YW5jZW9mIERPTSAmJiByaWdodCBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikgewotCQkvLyBzd2FwIG9wZXJhbmRzCi0JCWZpbmFsIE9iamVjdCB0ZW1wID0gcmlnaHQ7IHJpZ2h0ID0gbGVmdDsgbGVmdCA9IHRlbXA7Ci0JICAgIH0KLQotCSAgICBpZiAobGVmdCBpbnN0YW5jZW9mIERPTSkgewotCQlpZiAocmlnaHQgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0JCSAgICByZXN1bHQgPSAoKEJvb2xlYW4pcmlnaHQpLmJvb2xlYW5WYWx1ZSgpOwotCQkgICAgcmV0dXJuIHJlc3VsdCA9PSAob3AgPT0gT3BlcmF0b3JzLkVRKTsKLQkJfQotCi0JCWZpbmFsIFN0cmluZyBzbGVmdCA9ICgoRE9NKWxlZnQpLmdldFN0cmluZ1ZhbHVlKCk7Ci0KLQkJaWYgKHJpZ2h0IGluc3RhbmNlb2YgTnVtYmVyKSB7Ci0JCSAgICByZXN1bHQgPSAoKE51bWJlcilyaWdodCkuZG91YmxlVmFsdWUoKSA9PQotCQkJc3RyaW5nVG9SZWFsKHNsZWZ0KTsKLQkJfQotCQllbHNlIGlmIChyaWdodCBpbnN0YW5jZW9mIFN0cmluZykgewotCQkgICAgcmVzdWx0ID0gc2xlZnQuZXF1YWxzKChTdHJpbmcpcmlnaHQpOwotCQl9Ci0JCWVsc2UgaWYgKHJpZ2h0IGluc3RhbmNlb2YgRE9NKSB7Ci0JCSAgICByZXN1bHQgPSBzbGVmdC5lcXVhbHMoKChET00pcmlnaHQpLmdldFN0cmluZ1ZhbHVlKCkpOwotCQl9Ci0KLQkJaWYgKG9wID09IE9wZXJhdG9ycy5ORSkgewotCQkgICAgcmVzdWx0ID0gIXJlc3VsdDsKLQkJfQotCQlyZXR1cm4gcmVzdWx0OwotCSAgICB9Ci0KLQkgICAgLy8gTmV4dCwgbm9kZS1zZXQvdCBmb3IgdCBpbiB7cmVhbCwgc3RyaW5nLCBub2RlLXNldCwgcmVzdWx0LXRyZWV9Ci0KLQkgICAgTm9kZUl0ZXJhdG9yIGl0ZXIgPSAoKE5vZGVJdGVyYXRvcilsZWZ0KS5yZXNldCgpOwotCi0JICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikgewotCQlyZXN1bHQgPSBjb21wYXJlKGl0ZXIsIChOb2RlSXRlcmF0b3IpcmlnaHQsIG9wLCBub2RlLCBkb20pOwotCSAgICB9Ci0JICAgIGVsc2UgaWYgKHJpZ2h0IGluc3RhbmNlb2YgU3RyaW5nKSB7Ci0JCS8vcmVzdWx0ID0gY29tcGFyZShpdGVyLCAoU3RyaW5nKXJpZ2h0LCBvcCwgbm9kZSwgZG9tKTsKLQkJcmVzdWx0ID0gY29tcGFyZShpdGVyLCAoU3RyaW5nKXJpZ2h0LCBvcCwgZG9tKTsKLQkgICAgfQkKLQkgICAgZWxzZSBpZiAocmlnaHQgaW5zdGFuY2VvZiBOdW1iZXIpIHsKLQkJZmluYWwgZG91YmxlIHRlbXAgPSAoKE51bWJlcilyaWdodCkuZG91YmxlVmFsdWUoKTsKLQkJcmVzdWx0ID0gY29tcGFyZShpdGVyLCB0ZW1wLCBvcCwgZG9tKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChyaWdodCBpbnN0YW5jZW9mIEJvb2xlYW4pIHsKLQkJYm9vbGVhbiB0ZW1wID0gKChCb29sZWFuKXJpZ2h0KS5ib29sZWFuVmFsdWUoKTsKLQkJcmVzdWx0ID0gKGl0ZXIucmVzZXQoKS5uZXh0KCkgIT0gTm9kZUl0ZXJhdG9yLkVORCkgPT0gdGVtcDsKLQkgICAgfQotCSAgICBlbHNlIGlmIChyaWdodCBpbnN0YW5jZW9mIERPTSkgewotCQlyZXN1bHQgPSBjb21wYXJlKGl0ZXIsICgoRE9NKXJpZ2h0KS5nZXRTdHJpbmdWYWx1ZSgpLAotCQkJCSBvcCwgbm9kZSwgZG9tKTsKLQkgICAgfQotCSAgICBlbHNlIGlmIChyaWdodCA9PSBudWxsKSB7Ci0JCXJldHVybihmYWxzZSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXJ1blRpbWVFcnJvcigiVW5rbm93biBhcmd1bWVudCB0eXBlIGluIGNhbGwgdG8gZXF1YWwuIik7Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIHRvIHRlc3QgY29udGV4dCBub2RlJ3MgbGFuZ3VhZ2UKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gdGVzdExhbmd1YWdlKFN0cmluZyB0ZXN0TGFuZywgRE9NIGRvbSwgaW50IG5vZGUpIHsKLQkvLyBsYW5ndWFnZSBmb3IgY29udGV4dCBub2RlIChpZiBhbnkpCi0JU3RyaW5nIG5vZGVMYW5nID0gZG9tLmdldExhbmd1YWdlKG5vZGUpOwotCWlmIChub2RlTGFuZyA9PSBudWxsKQotCSAgICByZXR1cm4oZmFsc2UpOwotCWVsc2UKLQkgICAgbm9kZUxhbmcgPSBub2RlTGFuZy50b0xvd2VyQ2FzZSgpOwotCi0JLy8gY29tcGFyZSBjb250ZXh0IG5vZGUncyBsYW5ndWFnZSBhZ2FpbnMgdGVzdCBsYW5ndWFnZQotCXRlc3RMYW5nID0gdGVzdExhbmcudG9Mb3dlckNhc2UoKTsKLQlpZiAodGVzdExhbmcubGVuZ3RoKCkgPT0gMikgewotCSAgICByZXR1cm4obm9kZUxhbmcuc3RhcnRzV2l0aCh0ZXN0TGFuZykpOwotCX0KLQllbHNlIHsKLQkgICAgcmV0dXJuKG5vZGVMYW5nLmVxdWFscyh0ZXN0TGFuZykpOwotCX0KLSAgICB9Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGhhc1NpbXBsZVR5cGUoT2JqZWN0IG9iaikgewotCXJldHVybiBvYmogaW5zdGFuY2VvZiBCb29sZWFuIHx8IG9iaiBpbnN0YW5jZW9mIERvdWJsZSB8fAotCSAgICBvYmogaW5zdGFuY2VvZiBJbnRlZ2VyIHx8IG9iaiBpbnN0YW5jZW9mIFN0cmluZyB8fAotCSAgICBvYmogaW5zdGFuY2VvZiBOb2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgZnVuY3Rpb246IHVzZWQgaW4gU3RyaW5nVHlwZSB0byBjb252ZXJ0IGEgc3RyaW5nIHRvIGEgcmVhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSBzdHJpbmdUb1JlYWwoU3RyaW5nIHMpIHsKLQl0cnkgewotCSAgICByZXR1cm4gRG91YmxlLnZhbHVlT2YocykuZG91YmxlVmFsdWUoKTsKLQl9Ci0JY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJldHVybiBEb3VibGUuTmFOOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIGluIFN0cmluZ1R5cGUgdG8gY29udmVydCBhIHN0cmluZyB0byBhbiBpbnQuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBpbnQgc3RyaW5nVG9JbnQoU3RyaW5nIHMpIHsKLQl0cnkgewotCSAgICByZXR1cm4gSW50ZWdlci52YWx1ZU9mKHMpLmludFZhbHVlKCk7Ci0JfQotCWNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotCSAgICByZXR1cm4oLTEpOyAvLyA/Pz8KLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCBpbiBSZWFsVHlwZSB0byBjb252ZXJ0IGEgcmVhbCB0byBhIHN0cmluZy4KLSAgICAgKiBSZW1vdmVzIHRoZSBkZWNpbWFsIGlmIG51bGwuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVhbFRvU3RyaW5nKGRvdWJsZSBkKSB7Ci0JZmluYWwgU3RyaW5nIHJlc3VsdCA9IERvdWJsZS50b1N0cmluZyhkKTsKLQlmaW5hbCBpbnQgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aCgpOwotCWlmIChyZXN1bHQuY2hhckF0KGxlbmd0aC0yKSA9PSAnLicgJiYgcmVzdWx0LmNoYXJBdChsZW5ndGgtMSkgPT0gJzAnKSB7Ci0JICAgIHJldHVybiByZXN1bHQuc3Vic3RyaW5nKDAsIGxlbmd0aC0yKTsKLQl9Ci0JcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIGluIFJlYWxUeXBlIHRvIGNvbnZlcnQgYSByZWFsIHRvIGFuIGludGVnZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGludCByZWFsVG9JbnQoZG91YmxlIGQpIHsKLQlmaW5hbCBEb3VibGUgcmVzdWx0ID0gbmV3IERvdWJsZShkKTsKLQlyZXR1cm4gcmVzdWx0LmludFZhbHVlKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBmdW5jdGlvbjogdXNlZCB0byBmb3JtYXQvYWRqdXN0ICBhIGRvdWJsZSB0byBhIHN0cmluZy4gVGhlIAotICAgICAqIERlY2ltYWxGb3JtYXQgb2JqZWN0IGNvbWVzIGZyb20gdGhlICdmb3JtYXRfc3ltYm9scycgaGFzaHRhYmxlIGluIAotICAgICAqIEFic3RyYWN0VHJhbnNsZXQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBzdGF0aWMgRmllbGRQb3NpdGlvbiBfZmllbGRQb3NpdGlvbiA9IG5ldyBGaWVsZFBvc2l0aW9uKDApOwotCi0gICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9ybWF0TnVtYmVyKGRvdWJsZSBudW1iZXIsIFN0cmluZyBwYXR0ZXJuLAotCQkJCSAgICAgIERlY2ltYWxGb3JtYXQgZm9ybWF0dGVyKSB7Ci0JdHJ5IHsKLQkgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQkgICAgZm9ybWF0dGVyLmFwcGx5TG9jYWxpemVkUGF0dGVybihwYXR0ZXJuKTsKLQkgICAgZm9ybWF0dGVyLmZvcm1hdChudW1iZXIscmVzdWx0LF9maWVsZFBvc2l0aW9uKTsKLQkgICAgcmV0dXJuKHJlc3VsdC50b1N0cmluZygpKTsKLQl9Ci0JY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJ1blRpbWVFcnJvcigiQXR0ZW1wdGluZyB0byBmb3JtYXQgbnVtYmVyICciKyBudW1iZXIgKwotCQkJICInIHVzaW5nIHBhdHRlcm4gJyIgKyBwYXR0ZXJuICsgIicuIik7Ci0JICAgIHJldHVybihFTVBUWVNUUklORyk7Ci0JfQotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIHRvIGNvbnZlcnQgcmVmZXJlbmNlcyB0byBub2RlLXNldHMuIElmIHRoZQotICAgICAqIG9iaiBpcyBhbiBpbnN0YW5jZW9mIE5vZGUgdGhlbiBjcmVhdGUgYSBzaW5nbGV0b24gaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBOb2RlSXRlcmF0b3IgcmVmZXJlbmNlVG9Ob2RlU2V0KE9iamVjdCBvYmopIHsKLQl0cnkgewotCSAgICAvLyBDb252ZXJ0IHZhci9wYXJhbSAtPiBub2RlCi0JICAgIGlmIChvYmogaW5zdGFuY2VvZiBOb2RlKSB7Ci0JCXJldHVybihuZXcgU2luZ2xldG9uSXRlcmF0b3IoKChOb2RlKW9iaikubm9kZSkpOwotCSAgICB9Ci0JICAgIC8vIENvbnZlcnQgdmFyL3BhcmFtIC0+IG5vZGUtc2V0Ci0JICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikgewotCQlyZXR1cm4oKE5vZGVJdGVyYXRvcilvYmopOwotCSAgICB9Ci0JICAgIC8vIENvbnZlcnQgdmFyL3BhcmFtIC0+IHJlc3VsdC10cmVlIGZyYWdtZW50Ci0JICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERPTSkgewotCQlET00gZG9tID0gKERPTSlvYmo7Ci0JCXJldHVybihkb20uZ2V0SXRlcmF0b3IoKSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXJ1blRpbWVUeXBlRXJyb3IoInJlZmVyZW5jZSIsICJub2RlLXNldCIpOwotCQlyZXR1cm4gbnVsbDsKLQkgICAgfQotCX0KLQljYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsKLQkgICAgcnVuVGltZVR5cGVFcnJvcigicmVmZXJlbmNlIiwgIm5vZGUtc2V0Iik7Ci0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIHdpdGggbnRoIHBvc2l0aW9uIGZpbHRlcnMgdG8gY29udmVydCBhIHNlcXVlbmNlCi0gICAgICogb2Ygbm9kZXMgdG8ganVzdCBvbmUgc2luZ2xlIG5vZGUgKHRoZSBvbmUgYXQgcG9zaXRpb24gbikuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyBOb2RlSXRlcmF0b3IgZ2V0U2luZ2xlTm9kZShOb2RlSXRlcmF0b3IgaXRlcmF0b3IpIHsKLQlpbnQgbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTsKLQlyZXR1cm4obmV3IFNpbmdsZXRvbkl0ZXJhdG9yKG5vZGUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uOiB1c2VkIGluIHhzbDpjb3B5LgotICAgICAqLwotICAgIHByaXZhdGUgc3RhdGljIGNoYXJbXSBfY2hhcmFjdGVyQXJyYXkgPSBuZXcgY2hhclszMl07Ci0KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgY29weShPYmplY3Qgb2JqLAotCQkJICAgIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyLAotCQkJICAgIGludCBub2RlLAotCQkJICAgIERPTSBkb20pIHsKLQl0cnkgewotCSAgICBpZiAob2JqIGluc3RhbmNlb2YgTm9kZUl0ZXJhdG9yKSB7Ci0JCU5vZGVJdGVyYXRvciBpdGVyID0gKE5vZGVJdGVyYXRvcikgb2JqOwotCQkvL2RvbS5jb3B5KGl0ZXIucmVzZXQoKSwgaGFuZGxlcik7Ci0JCS8vISEKLQkJU3lzdGVtLmVyci5wcmludGxuKCJub3QgaW1wbGVtZW50ZWQgY29weSBpdGVyIik7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgTm9kZSkgewotCQlkb20uY29weSgoKE5vZGUpIG9iaikubm9kZSwgaGFuZGxlcik7Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRE9NKSB7Ci0JCSgoRE9NKW9iaikuY29weSgxLCBoYW5kbGVyKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJU3RyaW5nIHN0cmluZyA9IG9iai50b1N0cmluZygpOwkJLy8gb3IgY2FsbCBzdHJpbmdGKCkKLQkJZmluYWwgaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsKLQkJaWYgKGxlbmd0aCA+IF9jaGFyYWN0ZXJBcnJheS5sZW5ndGgpCi0JCSAgICBfY2hhcmFjdGVyQXJyYXkgPSBuZXcgY2hhcltsZW5ndGhdOwotCQlzdHJpbmcuZ2V0Q2hhcnMoMCwgbGVuZ3RoLCBfY2hhcmFjdGVyQXJyYXksIDApOwotCQloYW5kbGVyLmNoYXJhY3RlcnMoX2NoYXJhY3RlckFycmF5LCAwLCBsZW5ndGgpOwotCSAgICB9Ci0JfQotCWNhdGNoIChUcmFuc2xldEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJ1blRpbWVFcnJvcigiVHJhbnNsZXRFeGNlcHRpb24gcmFpc2VkIGluIGNvcHkoKS4iKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnQgYSBydW4tdGltZSB0eXBlIGVycm9yIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHJ1blRpbWVUeXBlRXJyb3IoU3RyaW5nIGZyb20sIFN0cmluZyB0bykgewotCXJ1blRpbWVFcnJvcigiSW52YWxpZCBjb252ZXJzaW9uIGZyb20gJyIgKyBmcm9tICsgIicgdG8gJyIgKyB0byArICInLiIpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50IGEgcnVuLXRpbWUgaW50ZXJuYWwgZXJyb3IgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIHZvaWQgcnVuVGltZUludGVybmFsRXJyb3IoKSB7Ci0JcnVuVGltZUVycm9yKCJJbnRlcm5hbCBlcnJvci4iKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCBhIHJ1bi10aW1lIGVycm9yIG1lc3NhZ2UuCi0gICAgICovCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIHJ1blRpbWVFcnJvcihTdHJpbmcgbWVzc2FnZSkgewotCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKG1lc3NhZ2UpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjb25zb2xlT3V0cHV0KFN0cmluZyBtc2cpIHsKLQlTeXN0ZW0ub3V0LnByaW50bG4obXNnKTsKLSAgICB9Ci0KLSAgICAvLy0tIEVuZCB1dGlsaXR5IGZ1bmN0aW9ucwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9Db25zdGFudHMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvQ29uc3RhbnRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRmNzJlMjMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9Db25zdGFudHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg2ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgSmFjZWsgQW1icm96aWFrCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGRlZmluZXMgY29uc3RhbnRzIHVzZWQgYnkgYm90aCB0aGUgY29tcGlsZXIgYW5kIHRoZSAKLSAqIHJ1bnRpbWUgc3lzdGVtLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbnN0YW50cyB7Ci0KLSAgICBmaW5hbCBzdGF0aWMgaW50IEFOWSAgICAgICA9IC0xOwotICAgIGZpbmFsIHN0YXRpYyBpbnQgQVRUUklCVVRFID0gLTI7Ci0gICAgZmluYWwgc3RhdGljIGludCBST09UICAgICAgPSBET00uUk9PVDsKLSAgICBmaW5hbCBzdGF0aWMgaW50IFRFWFQgICAgICA9IERPTS5URVhUOwotICAgIGZpbmFsIHN0YXRpYyBpbnQgRUxFTUVOVCAgID0gRE9NLkVMRU1FTlQ7Ci0gICAgZmluYWwgc3RhdGljIGludCBDT01NRU5UICAgPSBET00uQ09NTUVOVDsKLSAgICBmaW5hbCBzdGF0aWMgaW50IFBST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSBET00uUFJPQ0VTU0lOR19JTlNUUlVDVElPTjsKLQotICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIFhTTFRfVVJJID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRVNQQUNFX0ZFQVRVUkUgPQotCSJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyI7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvRGVmYXVsdFJ1bi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9EZWZhdWx0UnVuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQzZGZkY2UuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9EZWZhdWx0UnVuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NSW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5BeGlzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRURE1vbml0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkNvbnN0YW50czsKLQotZmluYWwgcHVibGljIGNsYXNzIERlZmF1bHRSdW4gewotCi0gICAgcHJpdmF0ZSBUcmFuc2xldE91dHB1dEhhbmRsZXIgX2hhbmRsZXI7Ci0KLSAgICBwcml2YXRlIFN0cmluZyAgX2ZpbGVOYW1lOwotICAgIHByaXZhdGUgU3RyaW5nICBfY2xhc3NOYW1lOwotICAgIHByaXZhdGUgU3RyaW5nICBfamFyRmlsZVNyYzsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2lzSmFyRmlsZVNwZWNpZmllZCA9IGZhbHNlOwotICAgIHByaXZhdGUgVmVjdG9yICBfcGFyYW1zID0gbnVsbDsKLSAgICBwcml2YXRlIGJvb2xlYW4gX3VyaSwgX2RlYnVnOwotCi0gICAgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQ7Ci0KLSAgICBwdWJsaWMgRGVmYXVsdFJ1bihTdHJpbmcgY2xhc3NOYW1lLCBTdHJpbmcgZmlsZU5hbWUsCi0JCSAgICAgIGJvb2xlYW4gdXJpLCBib29sZWFuIGRlYnVnKSB7Ci0JX2ZpbGVOYW1lID0gZmlsZU5hbWU7Ci0JX2NsYXNzTmFtZSA9IGNsYXNzTmFtZTsKLQlfdXJpID0gdXJpOwotCV9kZWJ1ZyA9IGRlYnVnOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcnMoVmVjdG9yIHBhcmFtcykgewotCV9wYXJhbXMgPSBwYXJhbXM7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHNldEphckZpbGVJbnB1dFNyYyhib29sZWFuIGZsYWcsICBTdHJpbmcgamFyRmlsZSkgewotCS8vIFRPRE86IGF0IHRoaXMgdGltZSB3ZSBkbyBub3QgZG8gYW55dGhpbmcgd2l0aCB0aGlzCi0JLy8gaW5mb3JtYXRpb24sIGF0dGVtcHRzIHRvIGFkZCB0aGUgamFyZmlsZSB0byB0aGUgQ0xBU1NQQVRICi0JLy8gd2VyZSBzdWNjZXNzZnVsIHZpYSBTeXN0ZW0uc2V0UHJvcGVydHksIGJ1dCB0aGUgZWZmZWN0cwotCS8vIHdlcmUgbm90IHZpc2libGUgdG8gdGhlIHJ1bm5pbmcgSlZNLiBGb3Igbm93IHdlIGFkZCBqYXJmaWxlCi0JLy8gdG8gQ0xBU1NQQVRIIGluIHRoZSB3cmFwcGVyIHNjcmlwdCB0aGF0IGNhbGxzIHRoaXMgcHJvZ3JhbS4gCi0JX2lzSmFyRmlsZVNwZWNpZmllZCA9IGZsYWc7Ci0JLy8gVE9ETyB2ZXJpZnkgamFyRmlsZSBleGlzdHMuLi4KLQlfamFyRmlsZVNyYyA9IGphckZpbGU7CQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBkb1RyYW5zZm9ybSgpIHsKLQl0cnkgewotCSAgICBmaW5hbCBDbGFzcyBjbGF6eiA9IENsYXNzLmZvck5hbWUoX2NsYXNzTmFtZSk7Ci0JICAgIGZpbmFsIFRyYW5zbGV0IHRyYW5zbGV0ID0gKFRyYW5zbGV0KWNsYXp6Lm5ld0luc3RhbmNlKCk7Ci0KLQkgICAgLy8gQ3JlYXRlIGEgU0FYIHBhcnNlciBhbmQgZ2V0IHRoZSBYTUxSZWFkZXIgb2JqZWN0IGl0IHVzZXMKLQkgICAgZmluYWwgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCSAgICB0cnkgewotCQlmYWN0b3J5LnNldEZlYXR1cmUoQ29uc3RhbnRzLk5BTUVTUEFDRV9GRUFUVVJFLCB0cnVlKTsKLQkgICAgfQotCSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQkgICAgfQotCSAgICBmaW5hbCBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLQkgICAgZmluYWwgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQotCSAgICAvLyBTZXQgdGhlIERPTSdzIERPTSBidWlsZGVyIGFzIHRoZSBYTUxSZWFkZXIncyBTQVgyIGNvbnRlbnQgaGFuZGxlcgotCSAgICBmaW5hbCBET01JbXBsIGRvbSA9IG5ldyBET01JbXBsKCk7Ci0JICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcihkb20uZ2V0QnVpbGRlcigpKTsKLQkgICAgLy8gQ3JlYXRlIGEgRFREIG1vbml0b3IgYW5kIHBhc3MgaXQgdG8gdGhlIFhNTFJlYWRlciBvYmplY3QKLQkgICAgZmluYWwgRFRETW9uaXRvciBkdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLQkgICAgZHRkTW9uaXRvci5oYW5kbGVEVEQocmVhZGVyKTsKLQotCSAgICBfdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldDsKLQkgICAgZG9tLnNldERvY3VtZW50VVJJKF9maWxlTmFtZSk7Ci0JICAgIGlmIChfdXJpKQotCQlyZWFkZXIucGFyc2UoX2ZpbGVOYW1lKTsKLQkgICAgZWxzZQotCQlyZWFkZXIucGFyc2UoImZpbGU6IisobmV3IEZpbGUoX2ZpbGVOYW1lKS5nZXRBYnNvbHV0ZVBhdGgoKSkpOwotCSAgICAKLQkgICAgLy8gU2V0IHNpemUgb2Yga2V5L2lkIGluZGljZXMKLQkgICAgX3RyYW5zbGV0LnNldEluZGV4U2l6ZShkb20uZ2V0U2l6ZSgpKTsKLQkgICAgLy8gSWYgdGhlcmUgYXJlIGFueSBlbGVtZW50cyB3aXRoIElEIGF0dHJpYnV0ZXMsIGJ1aWxkIGFuIGluZGV4Ci0JICAgIGR0ZE1vbml0b3IuYnVpbGRJZEluZGV4KGRvbSwgMCwgX3RyYW5zbGV0KTsKLQotCSAgICBfdHJhbnNsZXQuc2V0RFRETW9uaXRvcihkdGRNb25pdG9yKTsKLQotCSAgICAvLyBQYXNzIGdsb2JhbCBwYXJhbWV0ZXJzCi0JICAgIGludCBuID0gX3BhcmFtcy5zaXplKCk7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCVBhcmFtZXRlciBwYXJhbSA9IChQYXJhbWV0ZXIpIF9wYXJhbXMuZWxlbWVudEF0KGkpOwotCQl0cmFuc2xldC5hZGRQYXJhbWV0ZXIocGFyYW0uX25hbWUsIHBhcmFtLl92YWx1ZSk7Ci0JICAgIH0KLQotCSAgICAvLyBUcmFuc2Zvcm0gdGhlIGRvY3VtZW50Ci0JICAgIFN0cmluZyBlbmNvZGluZyA9IF90cmFuc2xldC5fZW5jb2Rpbmc7Ci0KLQkgICAgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgc2F4SGFuZGxlciA9Ci0JCW5ldyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihTeXN0ZW0ub3V0LCBlbmNvZGluZyk7Ci0JICAgIFRleHRPdXRwdXQgdGV4dE91dHB1dCA9Ci0JCW5ldyBUZXh0T3V0cHV0KChDb250ZW50SGFuZGxlcilzYXhIYW5kbGVyLAotCQkJICAgICAgIChMZXhpY2FsSGFuZGxlcilzYXhIYW5kbGVyLCBlbmNvZGluZyk7Ci0JICAgIHRyYW5zbGV0LnRyYW5zZm9ybShkb20sIHRleHRPdXRwdXQpOwotCi0JICAgIGlmIChfZGVidWcpIHsKLQkJVHJhbnNsZXRPdXRwdXRCYXNlIGhhbmRsZXIgPSBuZXcgVHJhbnNsZXRPdXRwdXRCYXNlKCk7Ci0JCWxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJZmluYWwgaW50IG5UaW1lcyA9IDEwMDsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBuVGltZXM7IGkrKykKLQkJICAgIHRyYW5zbGV0LnRyYW5zZm9ybShkb20sIGRvbS5nZXRJdGVyYXRvcigpLCBoYW5kbGVyKTsKLQkJbG9uZyBlbmQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJU3lzdGVtLm91dC5wcmludGxuKCJ0b3RhbCAiICsgKGVuZCAtIHN0YXJ0KSArICIgbXNlYyBmb3IgIiAKLQkJCQkgICArIG5UaW1lcyArICIgdHJhbnNmb3JtYXRpb25zIik7Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigoKGRvdWJsZSllbmQgLSBzdGFydCkvblRpbWVzICsgIiBtc2VjIGF2ZyIpOwotCSAgICB9Ci0JfQotCWNhdGNoIChUcmFuc2xldEV4Y2VwdGlvbiBlKSB7Ci0JICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXG5UcmFuc2xldCBFcnJvcjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKLQkgICAgaWYgKF9kZWJ1ZykgewotCQlTeXN0ZW0uZXJyLnByaW50bG4oZS50b1N0cmluZygpKTsKLQkJZS5wcmludFN0YWNrVHJhY2UoKTsKLQkgICAgfQotCSAgICBkb1N5c3RlbUV4aXQoMSk7CSAgICAKLQl9Ci0JY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlxuUnVudGltZSBFcnJvcjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKLQkgICAgaWYgKF9kZWJ1ZykgewotCQlTeXN0ZW0uZXJyLnByaW50bG4oZS50b1N0cmluZygpKTsKLQkJZS5wcmludFN0YWNrVHJhY2UoKTsKLQkgICAgfQotCSAgICBkb1N5c3RlbUV4aXQoMSk7Ci0JfQotCWNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBGaWxlIG9yIFVSSSAnIitfZmlsZU5hbWUrIicgbm90IGZvdW5kLiIpOwotCSAgICBkb1N5c3RlbUV4aXQoMSk7Ci0JfQotCWNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBJbnZhbGlkIFVSSSAnIitfZmlsZU5hbWUrIicuIik7Ci0JICAgIGRvU3lzdGVtRXhpdCgxKTsKLQl9Ci0JY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBDYW5ub3QgZmluZCBjbGFzcyAnIitfY2xhc3NOYW1lKyInLiIpOwotCSAgICBkb1N5c3RlbUV4aXQoMSk7Ci0JfQotICAgICAgICBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgewotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBDYW4ndCByZXNvbHZlIFVSSSBzcGVjaWZpY2F0aW9uICciKyAKLQkJCSAgICAgICBfZmlsZU5hbWUrIicuIik7Ci0JICAgIGRvU3lzdGVtRXhpdCgxKTsKLSAgICAgICAgfQotCWNhdGNoIChFeGNlcHRpb24gZSkgewotCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiBpbnRlcm5hbCBlcnJvci4iKTsKLQkgICAgZG9TeXN0ZW1FeGl0KDEpOwotCX0KLSAgICB9Ci0KLSAgICAvKiogSWYgd2Ugc2hvdWxkIGNhbGwgU3lzdGVtLmV4aXQgb3Igbm90ICovCi0gICAgcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGFsbG93U3lzdGVtRXhpdCA9IHRydWU7Ci0KLSAgICAvKiogV29ya2VyIG1ldGhvZCB0byBjYWxsIFN5c3RlbS5leGl0IG9yIG5vdCAqLwotICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCBkb1N5c3RlbUV4aXQoaW50IHJldFZhbCkgewotICAgICAgICBpZiAoYWxsb3dTeXN0ZW1FeGl0KQotICAgICAgICAgICAgU3lzdGVtLmV4aXQocmV0VmFsKTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgVVNBR0VfU1RSSU5HID0KLQkiVXNhZ2U6IFxuIiArCi0JIiAgICAgeHNsdCBbLWogPGphcmZpbGU+XSB7LXUgPGRvY3VtZW50X3VybD4gfCA8ZG9jdW1lbnQ+fSA8Y2xhc3M+XG4iKwotCSIgICAgICAgICAgWzxuYW1lMT49PHZhbHVlMT4gLi4uXVxuXG4iICsKLQkiICAgICAgICAgICA8ZG9jdW1lbnQ+IGlzIHRoZSB4bWwgZG9jdW1lbnQgdG8gYmUgdHJhbnNmb3JtZWQsIG9yXG4iICsKLQkiICAgICAgICAgICA8ZG9jdW1lbnRfdXJsPiBpcyBhIHVybCBmb3IgdGhlIHhtbCBkb2N1bWVudCxcbiIgKwotCSIgICAgICAgICAgIDxjbGFzcz4gaXMgdGhlIHRyYW5zbGV0IGNsYXNzIHdoaWNoIGlzIGVpdGhlciBpblxuIiArCi0JIiAgICAgICAgICAgdXNlcidzIENMQVNTUEFUSCBvciBpbiB0aGUgPGphcmZpbGU+IHNwZWNpZmllZCBcbiIgKwotCSIgICAgICAgICAgIHdpdGggdGhlIC1qIG9wdGlvbi5cbiIgKwotCSIgICAgICAgICAgYWxzbzogWy14XSAoZGVidWcpLCBbLXNdIChkb24ndCBhbGxvdyBTeXN0ZW0uZXhpdCkiOwkKLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludFVzYWdlKCkgewotCVN5c3RlbS5lcnIucHJpbnRsbihVU0FHRV9TVFJJTkcpOwotCVN5c3RlbS5leGl0KDEpOwotICAgIH0KLQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKLQl0cnkgewotCSAgICBpZiAoYXJncy5sZW5ndGggPiAwKSB7Ci0JCWludCBpOwotCQlib29sZWFuIHVyaSA9IGZhbHNlLCBkZWJ1ZyA9IGZhbHNlOwotCQlib29sZWFuIGlzSmFyRmlsZVNwZWNpZmllZCA9IGZhbHNlOwotCQlTdHJpbmcgIGphckZpbGUgPSBudWxsOwotCi0JCS8vIFBhcnNlIG9wdGlvbnMgc3RhcnRpbmcgd2l0aCAnLScKLQkJZm9yIChpID0gMDsgaSA8IGFyZ3MubGVuZ3RoICYmIGFyZ3NbaV0uY2hhckF0KDApID09ICctJzsgaSsrKSB7Ci0JCSAgICBpZiAoYXJnc1tpXS5lcXVhbHMoIi11IikpIHsKLQkJCXVyaSA9IHRydWU7Ci0JCSAgICB9Ci0JCSAgICBlbHNlIGlmIChhcmdzW2ldLmVxdWFscygiLXMiKSl7Ci0JCQlhbGxvd1N5c3RlbUV4aXQgPSBmYWxzZTsKLQkJICAgIH0KLQkJICAgIGVsc2UgaWYgKGFyZ3NbaV0uZXF1YWxzKCIteCIpKSB7Ci0JCQlkZWJ1ZyA9IHRydWU7Ci0JCSAgICB9Ci0JCSAgICBlbHNlIGlmIChhcmdzW2ldLmVxdWFscygiLWoiKSkgewotCQkJaXNKYXJGaWxlU3BlY2lmaWVkID0gdHJ1ZTsJCi0JCQlqYXJGaWxlID0gYXJnc1srK2ldOwotCQkgICAgfQotCQkgICAgZWxzZSB7Ci0JCQlwcmludFVzYWdlKCk7Ci0JCSAgICB9Ci0JCX0KLQotCQkvLyBFbm91Z2ggYXJndW1lbnRzIGxlZnQgPwotCQlpZiAoYXJncy5sZW5ndGggLSBpIDwgMikgewotCQkgICAgcHJpbnRVc2FnZSgpOwotCQl9Ci0KLQkJLy8gR2V0IGRvY3VtZW50IGZpbGUgYW5kIGNsYXNzIG5hbWUKLQkJRGVmYXVsdFJ1biBoYW5kbGVyID0gbmV3IERlZmF1bHRSdW4oYXJnc1tpKzFdLCBhcmdzW2ldLCAKLQkJCQkJCSAgICB1cmksIGRlYnVnKTsKLQkJaGFuZGxlci5zZXRKYXJGaWxlSW5wdXRTcmMoaXNKYXJGaWxlU3BlY2lmaWVkLAlqYXJGaWxlKTsKLQotCQkvLyBQYXJzZSBzdHlsZXNoZWV0IHBhcmFtZXRlcnMKLQkJVmVjdG9yIHBhcmFtcyA9IG5ldyBWZWN0b3IoKTsKLQkJZm9yIChpICs9IDI7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7Ci0JCSAgICBpbnQgZXF1YWwgPSBhcmdzW2ldLmluZGV4T2YoJz0nKTsKLQkJICAgIGlmIChlcXVhbCA+IDApIHsKLQkJCWZpbmFsIFBhcmFtZXRlciBwYXJhbSA9Ci0JCQkgICAgbmV3IFBhcmFtZXRlcihhcmdzW2ldLnN1YnN0cmluZygwLCBlcXVhbCksIAotCQkJCQkgIGFyZ3NbaV0uc3Vic3RyaW5nKGVxdWFsICsgMSwKLQkJCQkJCQkgICAgYXJnc1tpXS5sZW5ndGgoKSkpOwotCQkJcGFyYW1zLmFkZEVsZW1lbnQocGFyYW0pOwotCQkgICAgfQotCQkgICAgZWxzZSB7Ci0JCQlwcmludFVzYWdlKCk7Ci0JCSAgICB9Ci0JCX0KLQotCQlpZiAoaSA9PSBhcmdzLmxlbmd0aCkgewotCQkgICAgaGFuZGxlci5zZXRQYXJhbWV0ZXJzKHBhcmFtcyk7Ci0JCSAgICBoYW5kbGVyLmRvVHJhbnNmb3JtKCk7Ci0JCSAgICBkb1N5c3RlbUV4aXQoMCk7Ci0JCX0KLQkgICAgfWVsc2V7Ci0JICAgICAgIHByaW50VXNhZ2UoKTsKLQkgICAgfQotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLQl9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9EZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9EZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlY2NjNDc1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDU3NyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIgCi0gKiBAYXV0aG9yIFNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotcHVibGljIGNsYXNzIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIGltcGxlbWVudHMgQ29udGVudEhhbmRsZXIsIExleGljYWxIYW5kbGVyIHsKLQotICAgIC8vIFRoZSBvdXRwdXQgd3JpdGVyCi0gICAgcHJpdmF0ZSBXcml0ZXIgX3dyaXRlcjsKLQotICAgIC8vIENvbnRhaW5zIGVuZC10YWdzIGZvciBjbG9zaW5nIGVsZW1lbnRzIChmb3Igc3BlZWRpbmcgdXAgb3V0cHV0KQotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9lbmRUYWdzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIC8vIENvbnRhaW5zIGNvbW1vbmx5IHVzZWQgYXR0cmlidXRlcyAoZm9yIHNwZWVkaW5nIHVwIG91dHB1dCkKLSAgICBwcml2YXRlIEhhc2h0YWJsZSBfYXR0cmlidXRlVGVtcGxhdGVzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIC8vIENvbnRhaW5zIGFsbCBIVE1MIGVsZW1lbnRzIHRoYXQgc2hvdWxkIG5vdCBnZXQgYW4gZW5kIHRhZwotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9lbXB0eUVsZW1lbnRzID0gbmV3IEhhc2h0YWJsZSgpOwotICAgIC8vIENvbnRhaW5zIHRoZSBuYW1lIG9mIHRoZSBsYXN0IG9wZW5lZCBlbGVtZW50IChzZXQgaW4gc3RhcnRFbGVtZW50KCkpCi0gICAgcHJpdmF0ZSBTdHJpbmcgX2VsZW1lbnQgPSBudWxsOwotCi0gICAgLy8gU2V0dGluZ3MgcGFzc2VkIG9uIGZyb20gVGV4dE91dHB1dAotICAgIHByaXZhdGUgaW50CSAgICBfb3V0cHV0VHlwZSA9IFRleHRPdXRwdXQuVU5LTk9XTjsKLSAgICBwcml2YXRlIFN0cmluZyAgX2VuY29kaW5nICAgPSAidXRmLTgiOwotICAgIHByaXZhdGUgU3RyaW5nICBfdmVyc2lvbiAgICA9ICIxLjAiOwotICAgIHByaXZhdGUgU3RyaW5nICBfc3RhbmRhbG9uZSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9pbmRlbnQgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX29taXRIZWFkZXIgPSBmYWxzZTsKLQotICAgIC8vIFRoaXMgdmFyaWFibGUgaXMgc2V0IHRvICd0cnVlJyB3aGVuIGEgc3RhcnQgdGFnIGlzIGxlZnQgb3BlbgotICAgIHByaXZhdGUgYm9vbGVhbiBfc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0KLSAgICAvLyBDb21tb25seSB1c2VkIHN0cmluZ3MgYXJlIHN0b3JlZCBhcyBjaGFyIGFycmF5cyBmb3Igc3BlZWQKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gQkVHUEkgICAgPSAiPD8iLnRvQ2hhckFycmF5KCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEVORFBJICAgID0gIj8+Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBHVF9DUiAgICA9ICI+Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBHVF9MVF9TTCA9ICI+PC8iLnRvQ2hhckFycmF5KCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIFNMX0dUICAgID0gIi8+Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBYTUxOUyAgICA9ICIgeG1sbnMiLnRvQ2hhckFycmF5KCk7Ci0KLSAgICAvLyBBbGwgb2YgdGhlc2UgYXJlIHVzZWQgdG8gY29udHJvbC90cmFjayBvdXRwdXQgaW5kZW50YXRpb24KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gSU5ERU5UID0gIiAgICAgICAgICAgICAgICAgICAgIi50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfSU5ERU5UX0xFVkVMID0gKElOREVOVC5sZW5ndGggPj4gMSk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9JTkRFTlQgICAgICAgPSBJTkRFTlQubGVuZ3RoOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gX2xpbmVGZWVkTmV4dFN0YXJ0VGFnID0gZmFsc2U7Ci0gICAgcHJpdmF0ZSBib29sZWFuIF9saW5lZmVlZE5leHRFbmRUYWcgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gX2luZGVudE5leHRFbmRUYWcgPSBmYWxzZTsKLSAgICBwcml2YXRlIGludCAgICAgX2luZGVudExldmVsID0gMDsKLQotICAgIC8vIFRoaXMgaXMgdXNlZCBmb3IgYWdncmVnYXRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICAgIHByaXZhdGUgQXR0cmlidXRlTGlzdCBfbmFtZXNwYWNlRGVjbGFyYXRpb25zID0gbmV3IEF0dHJpYnV0ZUxpc3QoKTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIC0gc2V0IFdyaXRlciB0byBzZW5kIG91dHB1dCB0byBhbmQgb3V0cHV0IGVuY29kaW5nCi0gICAgICovCi0gICAgcHVibGljIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKFdyaXRlciB3cml0ZXIsIFN0cmluZyBlbmNvZGluZykKLQl0aHJvd3MgSU9FeGNlcHRpb24gewotCV93cml0ZXIgPSB3cml0ZXI7Ci0JX2VuY29kaW5nID0gZW5jb2Rpbmc7Ci0JaW5pdCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIC0gc2ltcGxlLCBpbml0aWFsbHkgZm9yIHVzZSBpbiBzZXJ2bGV0cwotICAgICAqLwotICAgIHB1YmxpYyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihXcml0ZXIgd3JpdGVyKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCXRoaXMod3JpdGVyLCAidXRmLTgiKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciAtIHNldCBvdXRwdXQtc3RyZWFtICYgb3V0cHV0IGVuY29kaW5nLiAKLSAgICAgKi8KLSAgICBwdWJsaWMgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIoT3V0cHV0U3RyZWFtIG91dCwgU3RyaW5nIGVuY29kaW5nKQotCXRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLSAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlcjsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0LCBfZW5jb2RpbmcgPSBlbmNvZGluZyk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dCwgX2VuY29kaW5nID0gInV0Zi04IiApOwotICAgICAgICB9Ci0gICAgICAgIF93cml0ZXIgPSBuZXcgQnVmZmVyZWRXcml0ZXIod3JpdGVyKTsKLQlpbml0KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgLSBzZXQgb3V0cHV0IGZpbGUgYW5kIG91dHB1dCBlbmNvZGluZwotICAgICAqLwotICAgIHB1YmxpYyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcihTdHJpbmcgZmlsZW5hbWUsIFN0cmluZyBlbmNvZGluZykKLQl0aHJvd3MgSU9FeGNlcHRpb24gewotCXRoaXMobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZW5hbWUpLCBlbmNvZGluZyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2Q6IEluaXRpYWxpc2UgdGhlIG91dHB1dCBoYW5kbGVyIAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBpbml0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotCS8vIFRoZXNlIGFyZSBIVE1MIHRhZ3MgdGhhdCBjYW4gb2NjdXIgYXMgZW1wdHkgZWxlbWVudHMgd2l0aAotCS8vIG5vIGNsb3NpbmcgdGFncyAoc3VjaCBhcyA8YnI+IGluc3RlYWRvZiBYSFRNTCdzIDxici8+KS4KLSAgICAgICAgZmluYWwgU3RyaW5nW10gdGFncyA9IHsgImFyZWEiLCAiYmFzZSIsICJiYXNlZm9udCIsICJiciIsCi0JCQkJImNvbCIsICJmcmFtZSIsICJociIsICJpbWciLCAiaW5wdXQiLAotCQkJCSJpc2luZGV4IiwgImxpbmsiLCAibWV0YSIsICJwYXJhbSIgfTsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0YWdzLmxlbmd0aDsgaSsrKQotICAgICAgICAgICAgX2VtcHR5RWxlbWVudHMucHV0KHRhZ3NbaV0sdGFnc1tpXSk7Ci0KLQlfZW5kVGFncy5jbGVhcigpOwotCV9vdXRwdXRUeXBlID0gVGV4dE91dHB1dC5VTktOT1dOOwotCV9pbmRlbnQgPSBmYWxzZTsKLQlfaW5kZW50TmV4dEVuZFRhZyA9IGZhbHNlOwotCV9pbmRlbnRMZXZlbCA9IDA7Ci0JX3N0YXJ0VGFnT3BlbiA9IGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENsb3NlIHRoZSBvdXRwdXQgc3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB7Ci0JdHJ5IHsKLQkgICAgaWYgKF93cml0ZXIgIT0gbnVsbCkgX3dyaXRlci5jbG9zZSgpOwotCX0KLQljYXRjaCAoSU9FeGNlcHRpb24gZSkgewotCSAgICAvLyB3aGF0IGNhbiB5b3UgZG8/Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIC0gb3V0cHV0cyBhbiBYTUwgaGVhZGVyCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGVtaXRIZWFkZXIoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQkvLyBGaXJzdCBjaGVjayBpZiB0aGUgJ29taXQteG1sLWRlY2xhcmF0aW9uJyB3YXMgc2V0IHRvIHllcyBpbiB0aGUKLQkvLyBzdHlsZXNoZWV0J3MgPHhzbDpvdXRwdXQ+IGVsZW1lbnQgKGlmIGFueSkKLQlpZiAoX29taXRIZWFkZXIpIHJldHVybjsKLQotCS8vIElmIG5vdCBnbyBhaGVhZCBhbmQgb3V0cHV0IHRoZSBYTUwgaGVhZGVyCi0JU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQlidWZmZXIuYXBwZW5kKCI8P3htbCB2ZXJzaW9uPVwiIik7Ci0JYnVmZmVyLmFwcGVuZChfdmVyc2lvbik7Ci0JYnVmZmVyLmFwcGVuZCgiXCIgZW5jb2Rpbmc9XCIiKTsKLQlidWZmZXIuYXBwZW5kKF9lbmNvZGluZyk7Ci0JaWYgKF9zdGFuZGFsb25lICE9IG51bGwpIHsKLQkgICAgYnVmZmVyLmFwcGVuZCgiXCIgc3RhbmRhbG9uZT1cIiIpOwotCSAgICBidWZmZXIuYXBwZW5kKF9zdGFuZGFsb25lKTsKLQl9Ci0JYnVmZmVyLmFwcGVuZCgiXCIgPz5cbiIpOwotCWNoYXJhY3RlcnMoYnVmZmVyLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIC0gZGV0ZXJtaW5lIG91dHB1dCB0eXBlOyBYTUwgb3IgSFRNTAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBkZXRlcm1pbmVPdXRwdXRUeXBlKFN0cmluZyBlbGVtZW50KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQkvLyBBc3N1bWUgdGhpcyBpcyBhbiBIVE1MIGRvY3VtZW50IGlmIGZpcnN0IGVsZW1lbnQgaXMgPGh0bWw+Ci0JaWYgKChlbGVtZW50ICE9IG51bGwpICYmIChlbGVtZW50LnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJodG1sIikpKSB7Ci0JICAgIF9vdXRwdXRUeXBlID0gVGV4dE91dHB1dC5IVE1MOwotCX0KLQkvLyBPdGhlcndpc2Ugd2UgYXNzdW1lIHRoaXMgaXMgYW4gWE1MIGRvY3VtZW50Ci0JZWxzZSB7Ci0JICAgIF9vdXRwdXRUeXBlID0gVGV4dE91dHB1dC5YTUw7Ci0JICAgIGVtaXRIZWFkZXIoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiAgeyAKLSAgICAgICAgdHJ5IHsKLQkgICAgX3dyaXRlci5mbHVzaCgpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhbiBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxuYW1lLAotCQkJICAgICBTdHJpbmcgZWxlbWVudE5hbWUsIEF0dHJpYnV0ZXMgYXR0cnMpIHRocm93cwotCVNBWEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQkgICAgLy8gRGV0ZXJtaW5lIHRoZSBvdXRwdXQgZG9jdW1lbnQgdHlwZSBpZiBub3QgYWxyZWFkeSBrbm93bgotCSAgICBpZiAoX291dHB1dFR5cGUgPT0gVGV4dE91dHB1dC5VTktOT1dOKQotCQlkZXRlcm1pbmVPdXRwdXRUeXBlKGVsZW1lbnROYW1lKTsKLQotICAgICAgICAgICAgaWYgKF9zdGFydFRhZ09wZW4pIGNsb3NlU3RhcnRUYWcodHJ1ZSk7IC8vIENsb3NlIGFueSBvcGVuIGVsZW1lbnQuCi0gICAgICAgICAgICBfZWxlbWVudCA9IGVsZW1lbnROYW1lOyAvLyBTYXZlIGVsZW1lbnQgbmFtZQotCi0JICAgIC8vIEhhbmRsZSBpbmRlbnRhdGlvbiAobm90IGEgcmVxdWlyZW1lbnQpCi0gICAgICAgICAgICBpZiAoX2luZGVudCkgewotCQlpZiAoIV9lbXB0eUVsZW1lbnRzLmNvbnRhaW5zS2V5KGVsZW1lbnROYW1lLnRvTG93ZXJDYXNlKCkpKSB7Ci0JCSAgICBpbmRlbnQoX2xpbmVGZWVkTmV4dFN0YXJ0VGFnKTsKLQkJICAgIF9saW5lRmVlZE5leHRTdGFydFRhZyA9IHRydWU7Ci0JCSAgICBfaW5kZW50TmV4dEVuZFRhZyA9IGZhbHNlOwotCQl9Ci0JCV9pbmRlbnRMZXZlbCsrOwotICAgICAgICAgICAgfQotCi0JICAgIC8vIE5vdywgZmluYWxseSwgb3V0cHV0IHRoZSBzdGFydCB0YWcgZm9yIHRoZSBlbGVtZW50LgotCSAgICBfd3JpdGVyLndyaXRlKCc8Jyk7Ci0JICAgIF93cml0ZXIud3JpdGUoZWxlbWVudE5hbWUpOwotCSAgICBfc3RhcnRUYWdPcGVuID0gdHJ1ZTsKLQkgICAgX2luZGVudE5leHRFbmRUYWcgPSBmYWxzZTsKLQotCSAgICAvLyBPdXRwdXQgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBmaXJzdC4uLgotCSAgICBpbnQgZGVjbENvdW50ID0gX25hbWVzcGFjZURlY2xhcmF0aW9ucy5nZXRMZW5ndGgoKTsKLQkgICAgZm9yIChpbnQgaT0wOyBpPGRlY2xDb3VudDsgaSsrKSB7Ci0JCWZpbmFsIFN0cmluZyBwcmVmaXggPSBfbmFtZXNwYWNlRGVjbGFyYXRpb25zLmdldFFOYW1lKGkpOwotCQlfd3JpdGVyLndyaXRlKFhNTE5TKTsKLQkJaWYgKChwcmVmaXggIT0gbnVsbCkgJiYgKHByZWZpeCAhPSBFTVBUWVNUUklORykpIHsKLQkJICAgIF93cml0ZXIud3JpdGUoJzonKTsKLQkJICAgIF93cml0ZXIud3JpdGUocHJlZml4KTsKLQkJfQotCQlfd3JpdGVyLndyaXRlKCc9Jyk7Ci0JCV93cml0ZXIud3JpdGUoJ1wiJyk7Ci0JCV93cml0ZXIud3JpdGUoX25hbWVzcGFjZURlY2xhcmF0aW9ucy5nZXRWYWx1ZShpKSk7Ci0JCV93cml0ZXIud3JpdGUoJ1wiJyk7Ci0gICAgICAgICAgICB9Ci0JICAgIF9uYW1lc3BhY2VEZWNsYXJhdGlvbnMuY2xlYXIoKTsKLQotCSAgICAvLyAuLi50aGVuIG91dHB1dCBhbGwgYXR0cmlidXRlcwotCSAgICBpbnQgYXR0ckNvdW50ID0gYXR0cnMuZ2V0TGVuZ3RoKCk7Ci0JICAgIGZvciAoaW50IGk9MDsgaTxhdHRyQ291bnQ7IGkrKykgewotCQlfd3JpdGVyLndyaXRlKCcgJyk7Ci0JCV93cml0ZXIud3JpdGUoYXR0cnMuZ2V0UU5hbWUoaSkpOwotCQlfd3JpdGVyLndyaXRlKCc9Jyk7Ci0JCV93cml0ZXIud3JpdGUoJ1wiJyk7Ci0JCV93cml0ZXIud3JpdGUoYXR0cnMuZ2V0VmFsdWUoaSkpOwotCQlfd3JpdGVyLndyaXRlKCdcIicpOwotICAgICAgICAgICAgfQotCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxuYW1lLAotCQkJICAgU3RyaW5nIGVsZW1lbnROYW1lKSAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQotICAgICAgICAgICAgaWYgKF9pbmRlbnQpIF9pbmRlbnRMZXZlbC0tOwotCi0gICAgICAgICAgICBpZiAoX3N0YXJ0VGFnT3BlbikgewotICAgICAgICAgICAgICAgIGNsb3NlU3RhcnRUYWcoZmFsc2UpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgaWYgKChfaW5kZW50KSAmJiAoX2luZGVudE5leHRFbmRUYWcpKSB7Ci0JCSAgICBpbmRlbnQoX2luZGVudE5leHRFbmRUYWcpOwotCQkgICAgX2luZGVudE5leHRFbmRUYWcgPSB0cnVlOwotCQl9Ci0gICAgICAgICAgICAgICAgY2hhcltdIGVuZFRhZyA9IChjaGFyW10pX2VuZFRhZ3MuZ2V0KGVsZW1lbnROYW1lKTsKLSAgICAgICAgICAgICAgICBpZiAoZW5kVGFnID09IG51bGwpIHsKLQkJICAgIC8vIFdlIGRvbnQnIHdhbnQgdG8gY29uY2F0ZW5hdGUgU3RyaW5nIG9iamVjdHMhISEhCi0JCSAgICAvLyBlbmRUYWcgPSAoIjwvIitlbGVtZW50TmFtZSsiPiIpLnRvQ2hhckFycmF5KCk7Ci0JCSAgICBmaW5hbCBpbnQgbGVuID0gZWxlbWVudE5hbWUubGVuZ3RoKCk7Ci0JCSAgICBmaW5hbCBjaGFyW10gc3JjID0gZWxlbWVudE5hbWUudG9DaGFyQXJyYXkoKTsKLQkJICAgIGVuZFRhZyA9IG5ldyBjaGFyW2xlbiszXTsKLQkJICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCAwLCBlbmRUYWcsIDIsIGxlbik7Ci0JCSAgICBlbmRUYWdbMF0gPSAnPCc7Ci0JCSAgICBlbmRUYWdbMV0gPSAnLyc7Ci0JCSAgICBlbmRUYWdbbGVuKzJdID0gJz4nOwotICAgICAgICAgICAgICAgICAgICBfZW5kVGFncy5wdXQoZWxlbWVudE5hbWUsZW5kVGFnKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3dyaXRlci53cml0ZShlbmRUYWcpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX2luZGVudE5leHRFbmRUYWcgPSB0cnVlOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2QgLSBwYXNzIGEgc3RyaW5nIHRvIHRoZSBTQVggaGFuZGxlcidzIGNoYXJhY3RlcnMoKSBtZXRob2QKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgY2hhcmFjdGVycyhTdHJpbmcgc3RyKSB0aHJvd3MgU0FYRXhjZXB0aW9uewotCWZpbmFsIGNoYXJbXSBjaCA9IHN0ci50b0NoYXJBcnJheSgpOwotCWNoYXJhY3RlcnMoY2gsIDAsIGNoLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVXRpbGl0eSBtZXRob2QgLSBwYXNzIGEgd2hvbGUgY2hhcmFjdGVyIGFycmF5IHRvIHRoZSBTQVggaGFuZGxlcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCkgdGhyb3dzIFNBWEV4Y2VwdGlvbnsKLQljaGFyYWN0ZXJzKGNoLCAwLCBjaC5sZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLQkgICAgLy8gRGV0ZXJtaW5lIHRoZSBvdXRwdXQgZG9jdW1lbnQgdHlwZSBpZiBub3QgYWxyZWFkeSBrbm93bgotCSAgICBpZiAoX291dHB1dFR5cGUgPT0gVGV4dE91dHB1dC5VTktOT1dOKQotCQlkZXRlcm1pbmVPdXRwdXRUeXBlKG51bGwpOwotCSAgICAKLSAgICAgICAgICAgIGlmIChsZW4gPT0gMCkgcmV0dXJuOwotCi0gICAgICAgICAgICAvLyBDbG9zZSBhbnkgb3BlbiBzdGFydC10YWdzLgotICAgICAgICAgICAgaWYgKF9zdGFydFRhZ09wZW4pIGNsb3NlU3RhcnRUYWcodHJ1ZSk7Ci0KLSAgICAgICAgICAgIC8vIE91dHB1dCB0ZXh0Ci0JICAgIF93cml0ZXIud3JpdGUoY2gsIG9mZiwgbGVuKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLSAgICAgICAgICAgIGlmIChfc3RhcnRUYWdPcGVuKSBjbG9zZVN0YXJ0VGFnKHRydWUpOwotICAgICAgICAgICAgX3dyaXRlci53cml0ZShCRUdQSSk7Ci0gICAgICAgICAgICBfd3JpdGVyLndyaXRlKHRhcmdldCk7Ci0gICAgICAgICAgICBfd3JpdGVyLndyaXRlKCcgJyk7Ci0gICAgICAgICAgICBfd3JpdGVyLndyaXRlKGRhdGEpOwotICAgICAgICAgICAgaWYgKF9vdXRwdXRUeXBlID09IFRleHRPdXRwdXQuSFRNTCkKLSAgICAgICAgICAgICAgICBfd3JpdGVyLndyaXRlKCc+Jyk7Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgX3dyaXRlci53cml0ZShFTkRQSSk7Ci0KLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQgY29udGVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuKSB7IH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IFJlY2VpdmUgYW4gb2JqZWN0IGZvciBsb2NhdGluZyB0aGUgb3JpZ2luIG9mIFNBWCBkb2N1bWVudCBldmVudHMuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgeyB9IAotCi0gICAgLyoqCi0gICAgICogU0FYMjogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBza2lwcGVkIGVudGl0eS4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB7IH0KLQotICAgIC8qKgotICAgICAqIFNBWDI6IEJlZ2luIHRoZSBzY29wZSBvZiBhIHByZWZpeC1VUkkgTmFtZXNwYWNlIG1hcHBpbmcuCi0gICAgICogICAgICAgTmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBhcmUgb3V0cHV0IGluIHN0YXJ0RWxlbWVudCgpCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHsKLQlfbmFtZXNwYWNlRGVjbGFyYXRpb25zLmFkZChwcmVmaXgsdXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTQVgyOiBFbmQgdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHsKLQkvLyBEbyBub3RoaW5nCi0gICAgfQotCi0gICAgLy8gVGhlIGFib3ZlIGFyZSBpZ25vcmVkIG1ldGhvZHMgb2YgdGhlIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBpbnRmLgotICAgIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB7IH0KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHsgfQotICAgIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHsgfQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgeyB9Ci0gICAgcHVibGljIHZvaWQgZW5kRFREKCkgeyB9Ci0gICAgcHVibGljIHZvaWQgZW5kRW50aXR5KFN0cmluZyBuYW1lKSB7IH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIHBhcnQgb2YgdGhlIExleGljYWxIYW5kbGVyIGludGVyZmFjZS4gSXQgaXMgb25seSB1c2VkIHRvCi0gICAgICogcGFzcyBET0NUWVBFIGRlY2xhcmF0aW9ucyAoYmFzZWQgb24gdGhlIGRvY3R5cGUtc3lzdGVtL3B1YmxpYyBhdHRyaWJ1dGVzCi0gICAgICogaW4gdGhlIDx4c2w6b3V0cHV0PiBlbGVtZW50KSB0byB0aGUgb3V0cHV0IGhhbmRsZXIuCi0gICAgICogQHBhcmFtIG5hbWUgICAgIFRoZSBkb2N1bWVudCB0eXBlIG5hbWUgKG5hbWUgb2YgZmlyc3QgZWxlbWVudCkKLSAgICAgKiBAcGFyYW0gcHVibGljSWQgPHhzbDpvdXRwdXQgZG9jdHlwZS1wdWJsaWM9Ii4uLiIvPgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCA8eHNsOm91dHB1dCBkb2N0eXBlLXN5c3RlbT0iLi4uIi8+Ci0gICAgICogQHRocm93cyBTQVhFeGNlcHRpb24gV2hlbmV2ZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydERURChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQkgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIjwhRE9DVFlQRSAiKTsKLQkgICAgYnVmLmFwcGVuZChuYW1lKTsKLQkgICAgaWYgKHB1YmxpY0lkID09IG51bGwpIHsKLQkJYnVmLmFwcGVuZCgiIFNZU1RFTSIpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlidWYuYXBwZW5kKCIgUFVCTElDIFwiIik7Ci0JCWJ1Zi5hcHBlbmQocHVibGljSWQpOwotCQlidWYuYXBwZW5kKCJcIiIpOwotCSAgICB9Ci0JICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKSB7Ci0JCWJ1Zi5hcHBlbmQoIiBcIiIpOwotCQlidWYuYXBwZW5kKHN5c3RlbUlkKTsKLQkJYnVmLmFwcGVuZCgiXCI+XG4iKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJYnVmLmFwcGVuZCgiPlxuIik7Ci0JICAgIH0KLQkgICAgX3dyaXRlci53cml0ZShidWYudG9TdHJpbmcoKSk7Ci0JfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEFkZHMgYSBuZXdsaW5lIGluIHRoZSBvdXRwdXQgc3RyZWFtIGFuZCBpbmRlbnRzIHRvIGNvcnJlY3QgbGV2ZWwKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgaW5kZW50KGJvb2xlYW4gbGluZWZlZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIGlmIChsaW5lZmVlZCkKLSAgICAgICAgICAgIF93cml0ZXIud3JpdGUoJ1xuJyk7Ci0gICAgICAgIGlmIChfaW5kZW50TGV2ZWwgPCBNQVhfSU5ERU5UX0xFVkVMKQotICAgICAgICAgICAgX3dyaXRlci53cml0ZShJTkRFTlQsIDAsIChfaW5kZW50TGV2ZWwrX2luZGVudExldmVsKSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICAgIF93cml0ZXIud3JpdGUoSU5ERU5ULCAwLCBNQVhfSU5ERU5UKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDbG9zZXMgYSBzdGFydCB0YWcgb2YgYW4gZWxlbWVudAotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBjbG9zZVN0YXJ0VGFnKGJvb2xlYW4gY29udGVudCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAvLyBUYWtlIHNwZWNpYWwgY2FyZSB3aGVuIG91dHB1dHRpbmcgZW1wdHkgdGFncyBpbiBIVE1MIGRvY3VtZW50cy4KLSAgICAgICAgICAgIGlmICghY29udGVudCkgewotICAgICAgICAgICAgICAgIGlmIChfb3V0cHV0VHlwZSA9PSBUZXh0T3V0cHV0LkhUTUwpIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gSFRNTDogb3V0cHV0IGVtcHR5IGVsZW1lbnQgYXMgPHRhZz4gb3IgPHRhZz48L3RhZz4KLSAgICAgICAgICAgICAgICAgICAgaWYgKCFfZW1wdHlFbGVtZW50cy5jb250YWluc0tleShfZWxlbWVudC50b0xvd2VyQ2FzZSgpKSl7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfd3JpdGVyLndyaXRlKEdUX0xUX1NMKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF93cml0ZXIud3JpdGUoX2VsZW1lbnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0JCSAgICBlbHNlIHsKLQkJCV93cml0ZXIud3JpdGUoR1RfQ1IpOwotCQkgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gWE1MOiBvdXRwdXQgZW1wdHkgZWxlbWVudCBhcyA8dGFnLz4KLSAgICAgICAgICAgICAgICAgICAgX3dyaXRlci53cml0ZShTTF9HVCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgIF93cml0ZXIud3JpdGUoJz4nKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR1cm5zIG91dHB1dCBpbmRlbnRhdGlvbiBvbi9vZmYgKHVzZWQgd2l0aCBYTUwgYW5kIEhUTUwgb3V0cHV0IG9ubHkpCi0gICAgICogQnJlYWtzIHRoZSBTQVggSGFuZGxlckJhc2UgaW50ZXJmYWNlLCBidXQgVGV4dE91dHB1dCB3aWxsIG9ubHkgY2FsbAotICAgICAqIHRoaXMgbWV0aG9kIG9mIHRoZSBTQVggaGFuZGxlciBpcyBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudChib29sZWFuIGluZGVudCkgewotICAgICAgICBfaW5kZW50ID0gaW5kZW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldHMgdGhlIHZlcnNpb24gbnVtYmVyIHRoYXQgd2lsbCBiZSBvdXRwdXQgaW4gdGhlIFhNTCBoZWFkZXIuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihTdHJpbmcgdmVyc2lvbikgewotCV92ZXJzaW9uID0gdmVyc2lvbjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXRzIHRoZSAnc3RhbmRhbG9uZScgYXR0cmlidXRlIHRoYXQgd2lsbCBiZSBvdXRwdXQgaW4gdGhlIFhNTCBoZWFkZXIuCi0gICAgICogVGhlIGF0dHJpYnV0ZSB3aWxsIGJlIG9taXR0ZWQgdW5sZXNzIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKFN0cmluZyBzdGFuZGFsb25lKSB7Ci0JX3N0YW5kYWxvbmUgPSBzdGFuZGFsb25lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR1cm5zIHhtbCBkZWNsYXJhdGlvbiBnZW5lcmF0aW9uIG9uL29mZiwgZGVwZW5kZW50IG9uIHRoZSBhdHRyaWJ1dGUKLSAgICAgKiBvbWl0LXhtbC1kZWNsYXJhdGlvbiBpbiBhbnkgeHNsOm91dHB1dCBlbGVtZW50LiAKLSAgICAgKiBCcmVha3MgdGhlIFNBWCBIYW5kbGVyQmFzZSBpbnRlcmZhY2UsIGJ1dCBUZXh0T3V0cHV0IHdpbGwgb25seSBjYWxsCi0gICAgICogdGhpcyBtZXRob2Qgb2YgdGhlIFNBWCBoYW5kbGVyIGlzIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgb21pdEhlYWRlcihib29sZWFuIHZhbHVlKSB7Ci0gICAgICAgIF9vbWl0SGVhZGVyID0gdmFsdWU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBvdXRwdXQgdHlwZSAoZWl0aGVyIFRFWFQsIEhUTUwgb3IgWE1MKQotICAgICAqIEJyZWFrcyB0aGUgU0FYIEhhbmRsZXJCYXNlIGludGVyZmFjZSwgYnV0IFRleHRPdXRwdXQgd2lsbCBvbmx5IGNhbGwKLSAgICAgKiB0aGlzIG1ldGhvZCBvZiB0aGUgU0FYIGhhbmRsZXIgaXMgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRPdXRwdXRUeXBlKGludCB0eXBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQlfb3V0cHV0VHlwZSA9IHR5cGU7Ci0JaWYgKF9vdXRwdXRUeXBlID09IFRleHRPdXRwdXQuWE1MICkgewotCSAgICBlbWl0SGVhZGVyKCk7Ci0JfQotICAgIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9IYXNodGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvSGFzaHRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlkNDFmY2IuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9IYXNodGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4MyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLS8qKgotICogSU1QT1JUQU5UIE5PVEU6Ci0gKiBUaGlzIGNvZGUgd2FzIHRha2VuIGZyb20gU3VuJ3MgSmF2YTEuMSBKREsgamF2YS51dGlsLkhhc2hUYWJsZS5qYXZhCi0gKiBBbGwgInN5bmNocm9uaXplZCIga2V5d29yZHMgYW5kIHNvbWUgbWV0aG9kcyB3ZSBkbyBub3QgbmVlZCBoYXZlIGJlZW4gCi0gKiBhbGwgYmVlbiByZW1vdmVkLgotICovCi0KLS8qKgotICogT2JqZWN0IHRoYXQgd3JhcHMgZW50cmllcyBpbiB0aGUgaGFzaC10YWJsZQotICovCi1jbGFzcyBIYXNodGFibGVFbnRyeSB7Ci0gICAgaW50IGhhc2g7Ci0gICAgT2JqZWN0IGtleTsKLSAgICBPYmplY3QgdmFsdWU7Ci0gICAgSGFzaHRhYmxlRW50cnkgbmV4dDsKLQotICAgIHByb3RlY3RlZCBPYmplY3QgY2xvbmUoKSB7Ci0JSGFzaHRhYmxlRW50cnkgZW50cnkgPSBuZXcgSGFzaHRhYmxlRW50cnkoKTsKLQllbnRyeS5oYXNoID0gaGFzaDsKLQllbnRyeS5rZXkgPSBrZXk7Ci0JZW50cnkudmFsdWUgPSB2YWx1ZTsKLQllbnRyeS5uZXh0ID0gKG5leHQgIT0gbnVsbCkgPyAoSGFzaHRhYmxlRW50cnkpbmV4dC5jbG9uZSgpIDogbnVsbDsKLQlyZXR1cm4gZW50cnk7Ci0gICAgfQotfQotCi0vKioKLSAqIFRoZSBtYWluIGhhc2gtdGFibGUgaW1wbGVtZW50YXRpb24KLSAqLwotcHVibGljIGNsYXNzIEhhc2h0YWJsZSB7Ci0KLSAgICBwcml2YXRlIHRyYW5zaWVudCBIYXNodGFibGVFbnRyeSB0YWJsZVtdOyAvLyBoYXNoLXRhYmxlIGVudHJpZXMKLSAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgY291bnQ7ICAgICAgICAgICAgICAvLyBudW1iZXIgb2YgZW50cmllcwotICAgIHByaXZhdGUgaW50IHRocmVzaG9sZDsgICAgICAgICAgICAgICAgICAgIC8vIGN1cnJlbnQgc2l6ZSBvZiBoYXNoLXRhYmtlCi0gICAgcHJpdmF0ZSBmbG9hdCBsb2FkRmFjdG9yOyAgICAgICAgICAgICAgICAgLy8gbG9hZCBmYWN0b3IKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBuZXcsIGVtcHR5IGhhc2h0YWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCAKLSAgICAgKiBjYXBhY2l0eSBhbmQgdGhlIHNwZWNpZmllZCBsb2FkIGZhY3Rvci4gCi0gICAgICovCi0gICAgcHVibGljIEhhc2h0YWJsZShpbnQgaW5pdGlhbENhcGFjaXR5LCBmbG9hdCBsb2FkRmFjdG9yKSB7Ci0JaWYgKGluaXRpYWxDYXBhY2l0eSA8PSAwKSBpbml0aWFsQ2FwYWNpdHkgPSAxMTsKLQlpZiAobG9hZEZhY3RvciA8PSAwLjApIGxvYWRGYWN0b3IgPSAwLjc1ZjsKLQl0aGlzLmxvYWRGYWN0b3IgPSBsb2FkRmFjdG9yOwotCXRhYmxlID0gbmV3IEhhc2h0YWJsZUVudHJ5W2luaXRpYWxDYXBhY2l0eV07Ci0JdGhyZXNob2xkID0gKGludCkoaW5pdGlhbENhcGFjaXR5ICogbG9hZEZhY3Rvcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgaGFzaHRhYmxlIHdpdGggdGhlIHNwZWNpZmllZCBpbml0aWFsIGNhcGFjaXR5Ci0gICAgICogYW5kIGRlZmF1bHQgbG9hZCBmYWN0b3IuCi0gICAgICovCi0gICAgcHVibGljIEhhc2h0YWJsZShpbnQgaW5pdGlhbENhcGFjaXR5KSB7Ci0JdGhpcyhpbml0aWFsQ2FwYWNpdHksIDAuNzVmKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3LCBlbXB0eSBoYXNodGFibGUgd2l0aCBhIGRlZmF1bHQgY2FwYWNpdHkgYW5kIGxvYWQKLSAgICAgKiBmYWN0b3IuIAotICAgICAqLwotICAgIHB1YmxpYyBIYXNodGFibGUoKSB7Ci0JdGhpcygxMDEsIDAuNzVmKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Yga2V5cyBpbiB0aGlzIGhhc2h0YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IHNpemUoKSB7Ci0JcmV0dXJuIGNvdW50OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlc3RzIGlmIHRoaXMgaGFzaHRhYmxlIG1hcHMgbm8ga2V5cyB0byB2YWx1ZXMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKLQlyZXR1cm4gY291bnQgPT0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG9mIHRoZSBrZXlzIGluIHRoaXMgaGFzaHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBrZXlzKCkgewotCXJldHVybiBuZXcgSGFzaHRhYmxlRW51bWVyYXRvcih0YWJsZSwgdHJ1ZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvZiB0aGUgdmFsdWVzIGluIHRoaXMgaGFzaHRhYmxlLgotICAgICAqIFVzZSB0aGUgRW51bWVyYXRpb24gbWV0aG9kcyBvbiB0aGUgcmV0dXJuZWQgb2JqZWN0IHRvIGZldGNoIHRoZSBlbGVtZW50cwotICAgICAqIHNlcXVlbnRpYWxseS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZWxlbWVudHMoKSB7Ci0JcmV0dXJuIG5ldyBIYXNodGFibGVFbnVtZXJhdG9yKHRhYmxlLCBmYWxzZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVzdHMgaWYgc29tZSBrZXkgbWFwcyBpbnRvIHRoZSBzcGVjaWZpZWQgdmFsdWUgaW4gdGhpcyBoYXNodGFibGUuCi0gICAgICogVGhpcyBvcGVyYXRpb24gaXMgbW9yZSBleHBlbnNpdmUgdGhhbiB0aGUgPGNvZGU+Y29udGFpbnNLZXk8L2NvZGU+Ci0gICAgICogbWV0aG9kLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCB2YWx1ZSkgewotCi0JaWYgKHZhbHVlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotCi0JaW50IGk7Ci0JSGFzaHRhYmxlRW50cnkgZTsKLQlIYXNodGFibGVFbnRyeSB0YWJbXSA9IHRhYmxlOwotCi0JZm9yIChpID0gdGFiLmxlbmd0aCA7IGktLSA+IDAgOykgewotCSAgICBmb3IgKGUgPSB0YWJbaV0gOyBlICE9IG51bGwgOyBlID0gZS5uZXh0KSB7Ci0JCWlmIChlLnZhbHVlLmVxdWFscyh2YWx1ZSkpIHsKLQkJICAgIHJldHVybiB0cnVlOwotCQl9Ci0JICAgIH0KLQl9Ci0JcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGEga2V5IGluIHRoaXMgaGFzaHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKLQlIYXNodGFibGVFbnRyeSBlOwotCUhhc2h0YWJsZUVudHJ5IHRhYltdID0gdGFibGU7Ci0JaW50IGhhc2ggPSBrZXkuaGFzaENvZGUoKTsKLQlpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgdGFiLmxlbmd0aDsKLQotCWZvciAoZSA9IHRhYltpbmRleF0gOyBlICE9IG51bGwgOyBlID0gZS5uZXh0KQotCSAgICBpZiAoKGUuaGFzaCA9PSBoYXNoKSAmJiBlLmtleS5lcXVhbHMoa2V5KSkKLQkJcmV0dXJuIHRydWU7Ci0KLQlyZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgdG8gd2hpY2ggdGhlIHNwZWNpZmllZCBrZXkgaXMgbWFwcGVkIGluIHRoaXMgaGFzaHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0KE9iamVjdCBrZXkpIHsKLQlIYXNodGFibGVFbnRyeSBlOwotCUhhc2h0YWJsZUVudHJ5IHRhYltdID0gdGFibGU7Ci0JaW50IGhhc2ggPSBrZXkuaGFzaENvZGUoKTsKLQlpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgdGFiLmxlbmd0aDsKLQotCWZvciAoZSA9IHRhYltpbmRleF0gOyBlICE9IG51bGwgOyBlID0gZS5uZXh0KSAKLQkgICAgaWYgKChlLmhhc2ggPT0gaGFzaCkgJiYgZS5rZXkuZXF1YWxzKGtleSkpIAotCQlyZXR1cm4gZS52YWx1ZTsKLQotCXJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlaGFzaGVzIHRoZSBjb250ZW50cyBvZiB0aGUgaGFzaHRhYmxlIGludG8gYSBoYXNodGFibGUgd2l0aCBhIAotICAgICAqIGxhcmdlciBjYXBhY2l0eS4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgCi0gICAgICogbnVtYmVyIG9mIGtleXMgaW4gdGhlIGhhc2h0YWJsZSBleGNlZWRzIHRoaXMgaGFzaHRhYmxlJ3MgY2FwYWNpdHkgCi0gICAgICogYW5kIGxvYWQgZmFjdG9yLiAKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgdm9pZCByZWhhc2goKSB7Ci0JSGFzaHRhYmxlRW50cnkgZSwgb2xkOwotCWludCBpLCBpbmRleDsKLQlpbnQgb2xkQ2FwYWNpdHkgPSB0YWJsZS5sZW5ndGg7Ci0JSGFzaHRhYmxlRW50cnkgb2xkVGFibGVbXSA9IHRhYmxlOwotCi0JaW50IG5ld0NhcGFjaXR5ID0gb2xkQ2FwYWNpdHkgKiAyICsgMTsKLQlIYXNodGFibGVFbnRyeSBuZXdUYWJsZVtdID0gbmV3IEhhc2h0YWJsZUVudHJ5W25ld0NhcGFjaXR5XTsKLQotCXRocmVzaG9sZCA9IChpbnQpKG5ld0NhcGFjaXR5ICogbG9hZEZhY3Rvcik7Ci0JdGFibGUgPSBuZXdUYWJsZTsKLQotCWZvciAoaSA9IG9sZENhcGFjaXR5IDsgaS0tID4gMCA7KSB7Ci0JICAgIGZvciAob2xkID0gb2xkVGFibGVbaV0gOyBvbGQgIT0gbnVsbCA7ICkgewotCQllID0gb2xkOwotCQlvbGQgPSBvbGQubmV4dDsKLQkJaW5kZXggPSAoZS5oYXNoICYgMHg3RkZGRkZGRikgJSBuZXdDYXBhY2l0eTsKLQkJZS5uZXh0ID0gbmV3VGFibGVbaW5kZXhdOwotCQluZXdUYWJsZVtpbmRleF0gPSBlOwotCSAgICB9Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1hcHMgdGhlIHNwZWNpZmllZCA8Y29kZT5rZXk8L2NvZGU+IHRvIHRoZSBzcGVjaWZpZWQgCi0gICAgICogPGNvZGU+dmFsdWU8L2NvZGU+IGluIHRoaXMgaGFzaHRhYmxlLiBOZWl0aGVyIHRoZSBrZXkgbm9yIHRoZSAKLSAgICAgKiB2YWx1ZSBjYW4gYmUgPGNvZGU+bnVsbDwvY29kZT4uIAotICAgICAqIDxwPgotICAgICAqIFRoZSB2YWx1ZSBjYW4gYmUgcmV0cmlldmVkIGJ5IGNhbGxpbmcgdGhlIDxjb2RlPmdldDwvY29kZT4gbWV0aG9kIAotICAgICAqIHdpdGggYSBrZXkgdGhhdCBpcyBlcXVhbCB0byB0aGUgb3JpZ2luYWwga2V5LiAKLSAgICAgKi8KLSAgICBwdWJsaWMgT2JqZWN0IHB1dChPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKLQkvLyBNYWtlIHN1cmUgdGhlIHZhbHVlIGlzIG5vdCBudWxsCi0JaWYgKHZhbHVlID09IG51bGwpIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotCi0JLy8gTWFrZXMgc3VyZSB0aGUga2V5IGlzIG5vdCBhbHJlYWR5IGluIHRoZSBoYXNodGFibGUuCi0JSGFzaHRhYmxlRW50cnkgZTsKLQlIYXNodGFibGVFbnRyeSB0YWJbXSA9IHRhYmxlOwotCWludCBoYXNoID0ga2V5Lmhhc2hDb2RlKCk7Ci0JaW50IGluZGV4ID0gKGhhc2ggJiAweDdGRkZGRkZGKSAlIHRhYi5sZW5ndGg7Ci0KLQlmb3IgKGUgPSB0YWJbaW5kZXhdIDsgZSAhPSBudWxsIDsgZSA9IGUubmV4dCkgewotCSAgICBpZiAoKGUuaGFzaCA9PSBoYXNoKSAmJiBlLmtleS5lcXVhbHMoa2V5KSkgewotCQlPYmplY3Qgb2xkID0gZS52YWx1ZTsKLQkJZS52YWx1ZSA9IHZhbHVlOwotCQlyZXR1cm4gb2xkOwotCSAgICB9Ci0JfQotCi0JLy8gUmVoYXNoIHRoZSB0YWJsZSBpZiB0aGUgdGhyZXNob2xkIGlzIGV4Y2VlZGVkCi0JaWYgKGNvdW50ID49IHRocmVzaG9sZCkgewotCSAgICByZWhhc2goKTsKLQkgICAgcmV0dXJuIHB1dChrZXksIHZhbHVlKTsKLQl9IAotCi0JLy8gQ3JlYXRlcyB0aGUgbmV3IGVudHJ5LgotCWUgPSBuZXcgSGFzaHRhYmxlRW50cnkoKTsKLQllLmhhc2ggPSBoYXNoOwotCWUua2V5ID0ga2V5OwotCWUudmFsdWUgPSB2YWx1ZTsKLQllLm5leHQgPSB0YWJbaW5kZXhdOwotCXRhYltpbmRleF0gPSBlOwotCWNvdW50Kys7Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmVtb3ZlcyB0aGUga2V5IChhbmQgaXRzIGNvcnJlc3BvbmRpbmcgdmFsdWUpIGZyb20gdGhpcyAKLSAgICAgKiBoYXNodGFibGUuIFRoaXMgbWV0aG9kIGRvZXMgbm90aGluZyBpZiB0aGUga2V5IGlzIG5vdCBpbiB0aGUgaGFzaHRhYmxlLgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgcmVtb3ZlKE9iamVjdCBrZXkpIHsKLQlIYXNodGFibGVFbnRyeSBlLCBwcmV2OwotCUhhc2h0YWJsZUVudHJ5IHRhYltdID0gdGFibGU7Ci0JaW50IGhhc2ggPSBrZXkuaGFzaENvZGUoKTsKLQlpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgdGFiLmxlbmd0aDsKLQlmb3IgKGUgPSB0YWJbaW5kZXhdLCBwcmV2ID0gbnVsbCA7IGUgIT0gbnVsbCA7IHByZXYgPSBlLCBlID0gZS5uZXh0KSB7Ci0JICAgIGlmICgoZS5oYXNoID09IGhhc2gpICYmIGUua2V5LmVxdWFscyhrZXkpKSB7Ci0JCWlmIChwcmV2ICE9IG51bGwpCi0JCSAgICBwcmV2Lm5leHQgPSBlLm5leHQ7Ci0JCWVsc2UKLQkJICAgIHRhYltpbmRleF0gPSBlLm5leHQ7Ci0JCWNvdW50LS07Ci0JCXJldHVybiBlLnZhbHVlOwotCSAgICB9Ci0JfQotCXJldHVybiBudWxsOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENsZWFycyB0aGlzIGhhc2h0YWJsZSBzbyB0aGF0IGl0IGNvbnRhaW5zIG5vIGtleXMuIAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewotCUhhc2h0YWJsZUVudHJ5IHRhYltdID0gdGFibGU7Ci0JZm9yIChpbnQgaW5kZXggPSB0YWIubGVuZ3RoOyAtLWluZGV4ID49IDA7ICkKLQkgICAgdGFiW2luZGV4XSA9IG51bGw7Ci0JY291bnQgPSAwOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSByYXRoZXIgbG9uZyBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBoYXNodGFibGUuCi0gICAgICogSGFuZHkgZm9yIGRlYnVnZ2luZyAtIGxlYXZlIGl0IGhlcmUhISEKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCWludCBpOwotCWludCBtYXggPSBzaXplKCkgLSAxOwotCVN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0JRW51bWVyYXRpb24gayA9IGtleXMoKTsKLQlFbnVtZXJhdGlvbiBlID0gZWxlbWVudHMoKTsKLQlidWYuYXBwZW5kKCJ7Iik7Ci0KLQlmb3IgKGkgPSAwOyBpIDw9IG1heDsgaSsrKSB7Ci0JICAgIFN0cmluZyBzMSA9IGsubmV4dEVsZW1lbnQoKS50b1N0cmluZygpOwotCSAgICBTdHJpbmcgczIgPSBlLm5leHRFbGVtZW50KCkudG9TdHJpbmcoKTsKLQkgICAgYnVmLmFwcGVuZChzMSArICI9IiArIHMyKTsKLQkgICAgaWYgKGkgPCBtYXgpIGJ1Zi5hcHBlbmQoIiwgIik7Ci0JfQotCWJ1Zi5hcHBlbmQoIn0iKTsKLQlyZXR1cm4gYnVmLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQSBoYXNodGFibGUgZW51bWVyYXRvciBjbGFzcy4gIFRoaXMgY2xhc3Mgc2hvdWxkIHJlbWFpbiBvcGFxdWUgCi0gICAgICogdG8gdGhlIGNsaWVudC4gSXQgd2lsbCB1c2UgdGhlIEVudW1lcmF0aW9uIGludGVyZmFjZS4KLSAgICAgKi8KLSAgICBjbGFzcyBIYXNodGFibGVFbnVtZXJhdG9yIGltcGxlbWVudHMgRW51bWVyYXRpb24gewotCWJvb2xlYW4ga2V5czsKLQlpbnQgaW5kZXg7Ci0JSGFzaHRhYmxlRW50cnkgdGFibGVbXTsKLQlIYXNodGFibGVFbnRyeSBlbnRyeTsKLQotCUhhc2h0YWJsZUVudW1lcmF0b3IoSGFzaHRhYmxlRW50cnkgdGFibGVbXSwgYm9vbGVhbiBrZXlzKSB7Ci0JICAgIHRoaXMudGFibGUgPSB0YWJsZTsKLQkgICAgdGhpcy5rZXlzID0ga2V5czsKLQkgICAgdGhpcy5pbmRleCA9IHRhYmxlLmxlbmd0aDsKLQl9Ci0JCi0JcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgewotCSAgICBpZiAoZW50cnkgIT0gbnVsbCkgewotCQlyZXR1cm4gdHJ1ZTsKLQkgICAgfQotCSAgICB3aGlsZSAoaW5kZXgtLSA+IDApIHsKLQkJaWYgKChlbnRyeSA9IHRhYmxlW2luZGV4XSkgIT0gbnVsbCkgewotCQkgICAgcmV0dXJuIHRydWU7Ci0JCX0KLQkgICAgfQotCSAgICByZXR1cm4gZmFsc2U7Ci0JfQotCi0JcHVibGljIE9iamVjdCBuZXh0RWxlbWVudCgpIHsKLQkgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKLQkJd2hpbGUgKChpbmRleC0tID4gMCkgJiYgKChlbnRyeSA9IHRhYmxlW2luZGV4XSkgPT0gbnVsbCkpOwotCSAgICB9Ci0JICAgIGlmIChlbnRyeSAhPSBudWxsKSB7Ci0JCUhhc2h0YWJsZUVudHJ5IGUgPSBlbnRyeTsKLQkJZW50cnkgPSBlLm5leHQ7Ci0JCXJldHVybiBrZXlzID8gZS5rZXkgOiBlLnZhbHVlOwotCSAgICB9Ci0JICAgIHJldHVybiBudWxsOwotCX0KLSAgICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvTWVzc2FnZUhhbmRsZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvTWVzc2FnZUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTIwYzBjYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL01lc3NhZ2VIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWU7Ci0KLXB1YmxpYyBjbGFzcyBNZXNzYWdlSGFuZGxlciB7Ci0gICAgcHVibGljIHZvaWQgZGlzcGxheU1lc3NhZ2UoU3RyaW5nIG1zZykgewotCVN5c3RlbS5lcnIucHJpbnRsbihtc2cpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvTm9kZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9Ob2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk4NjA2ZGEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9Ob2RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgdXNlZCBhcyAid3JhcHBlciIgZm9yIGRvbSBub2Rlcy4gV3JhcHBlcnMgYXJlIG5lZWRlZCB3aGVuCi0gKiBhIG5vZGUgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIGEgdGVtcGxhdGUuCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlIHsKLSAgICBwdWJsaWMgaW50IG5vZGU7Ci0gICAgcHVibGljIGludCB0eXBlOwotCQotICAgIHB1YmxpYyBOb2RlKGludCBuLCBpbnQgdCkgewotCW5vZGUgPSBuOwotCXR5cGUgPSB0OwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvT3BlcmF0b3JzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL09wZXJhdG9ycy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYTcyYzg0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvT3BlcmF0b3JzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NyArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lOwotCi1wdWJsaWMgaW50ZXJmYWNlIE9wZXJhdG9ycyB7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVEgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHVCA9IDI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTFQgPSAzOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdFID0gNDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMRSA9IDU7Ci0JCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBuYW1lcyA9IHsKLQkiPSIsICIhPSIsICI+IiwgIjwiLCAiPj0iLCAiPD0iCi0gICAgfTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvUGFyYW1ldGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1BhcmFtZXRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNTIyOWZmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvUGFyYW1ldGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEphY2VrIEFtYnJvemlhawotICogQGF1dGhvciBTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWU7Ci0KLXB1YmxpYyBjbGFzcyBQYXJhbWV0ZXIgewotCi0gICAgcHVibGljIFN0cmluZyAgX25hbWU7Ci0gICAgcHVibGljIE9iamVjdCAgX3ZhbHVlOwotICAgIHB1YmxpYyBib29sZWFuIF9pc0RlZmF1bHQ7Ci0KLSAgICBwdWJsaWMgUGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsKLQlfbmFtZSA9IG5hbWU7Ci0JX3ZhbHVlID0gdmFsdWU7Ci0JX2lzRGVmYXVsdCA9IHRydWU7Ci0gICAgfQotCi0gICAgcHVibGljIFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlLCBib29sZWFuIGlzRGVmYXVsdCkgewotCV9uYW1lID0gbmFtZTsKLQlfdmFsdWUgPSB2YWx1ZTsKLQlfaXNEZWZhdWx0ID0gaXNEZWZhdWx0OwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvU0FYQWRhcHRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9TQVhBZGFwdGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM0OTYxOGMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9TQVhBZGFwdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODQgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLio7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBTQVhBZGFwdGVyIGltcGxlbWVudHMgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIHsKLQotICAgIHByaXZhdGUgZmluYWwgQ29udGVudEhhbmRsZXIgX3NheEhhbmRsZXI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBBdHRyaWJ1dGVMaXN0ICBfYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGVMaXN0KCk7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfb3BlbkVsZW1lbnROYW1lOwotICAgIAotICAgIHB1YmxpYyBTQVhBZGFwdGVyKENvbnRlbnRIYW5kbGVyIHNheEhhbmRsZXIpIHsKLQlfc2F4SGFuZGxlciA9IHNheEhhbmRsZXI7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIG1heWJlRW1pdFN0YXJ0RWxlbWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewotCWlmIChfb3BlbkVsZW1lbnROYW1lICE9IG51bGwpIHsKLQkgICAgX3NheEhhbmRsZXIuc3RhcnRFbGVtZW50KG51bGwsIG51bGwsIF9vcGVuRWxlbWVudE5hbWUsIF9hdHRyaWJ1dGVzKTsKLQkgICAgX29wZW5FbGVtZW50TmFtZSA9IG51bGw7Ci0JfQotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCXRyeSB7Ci0JICAgIF9zYXhIYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICBfc2F4SGFuZGxlci5lbmREb2N1bWVudCgpOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKGUpOwotCX0KLSAgICB9Ci0gICAgCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCXRyeSB7Ci0JICAgIG1heWJlRW1pdFN0YXJ0RWxlbWVudCgpOwotCSAgICBfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoYXJhY3RlcnMsIG9mZnNldCwgbGVuZ3RoKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChTdHJpbmcgZWxlbWVudE5hbWUpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQkgICAgbWF5YmVFbWl0U3RhcnRFbGVtZW50KCk7Ci0JICAgIF9vcGVuRWxlbWVudE5hbWUgPSBlbGVtZW50TmFtZTsKLQkgICAgX2F0dHJpYnV0ZXMuY2xlYXIoKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCXRyeSB7Ci0JICAgIG1heWJlRW1pdFN0YXJ0RWxlbWVudCgpOwotCSAgICBfc2F4SGFuZGxlci5lbmRFbGVtZW50KG51bGwsIG51bGwsIGVsZW1lbnROYW1lKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIGF0dHJpYnV0ZShTdHJpbmcgYXR0cmlidXRlTmFtZSwgU3RyaW5nIGF0dHJpYnV0ZVZhbHVlKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JaWYgKF9vcGVuRWxlbWVudE5hbWUgIT0gbnVsbCkgewotCSAgICBfYXR0cmlidXRlcy5hZGQoYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpOwotCX0KLQllbHNlIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKCJhdHRyaWJ1dGUgb3V0c2lkZSBvZiBzdGFydCB0YWciKTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JLy8gPz8/Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICBtYXliZUVtaXRTdGFydEVsZW1lbnQoKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCXRyeSB7Ci0JICAgIG1heWJlRW1pdFN0YXJ0RWxlbWVudCgpOwotCSAgICBfc2F4SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotCi0gICAgLy8gVGhlIFNBWCBoYW5kbGVyIGRvZXMgbm90IGhhbmRsZSB0aGVzZToKLSAgICBwdWJsaWMgdm9pZCBzZXRUeXBlKGludCB0eXBlKSB7fQotICAgIHB1YmxpYyB2b2lkIHNldEhlYWRlcihTdHJpbmcgaGVhZGVyKSB7fQotICAgIHB1YmxpYyB2b2lkIHNldEluZGVudChib29sZWFuIGluZGVudCkge30KLSAgICBwdWJsaWMgdm9pZCBvbWl0SGVhZGVyKGJvb2xlYW4gdmFsdWUpIHt9Ci0gICAgcHVibGljIHZvaWQgc2V0Q2RhdGFFbGVtZW50cyhIYXNodGFibGUgZWxlbWVudHMpIHsgfQotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkge30KLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0gICAgICAgIHJldHVybih0cnVlKTsKLSAgICB9Ci0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHVyaSkgeyByZXR1cm4oIiIpOyB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1N0cmluZ1ZhbHVlSGFuZGxlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9TdHJpbmdWYWx1ZUhhbmRsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmU0N2ViNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1N0cmluZ1ZhbHVlSGFuZGxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgU3RyaW5nVmFsdWVIYW5kbGVyIGV4dGVuZHMgVHJhbnNsZXRPdXRwdXRCYXNlIHsKLQotICAgIHByaXZhdGUgY2hhcltdIF9idWZmZXIgPSBuZXcgY2hhclszMl07Ci0gICAgcHJpdmF0ZSBpbnQgX2ZyZWUgPSAwOwotCQotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgb2ZmLCBpbnQgbGVuKSB7Ci0JaWYgKF9mcmVlICsgbGVuID49IF9idWZmZXIubGVuZ3RoKSB7Ci0JICAgIGNoYXJbXSBuZXdCdWZmZXIgPSBuZXcgY2hhcltfZnJlZSArIGxlbiArIDMyXTsKLQkgICAgU3lzdGVtLmFycmF5Y29weShfYnVmZmVyLCAwLCBuZXdCdWZmZXIsIDAsIF9mcmVlKTsKLQkgICAgX2J1ZmZlciA9IG5ld0J1ZmZlcjsKLQl9Ci0JU3lzdGVtLmFycmF5Y29weShjaCwgb2ZmLCBfYnVmZmVyLCBfZnJlZSwgbGVuKTsKLQlfZnJlZSArPSBsZW47Ci0gICAgfQotCi0gICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpIHsKLQlmaW5hbCBpbnQgbGVuZ3RoID0gX2ZyZWU7Ci0JX2ZyZWUgPSAwOwkJLy8gZ2V0VmFsdWUgcmVzZXRzCi0JcmV0dXJuIG5ldyBTdHJpbmcoX2J1ZmZlciwgMCwgbGVuZ3RoKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1RleHRPdXRwdXQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvVGV4dE91dHB1dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MjM4ZmM2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUvVGV4dE91dHB1dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTA4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKiBAYXV0aG9yIFNldGggRm9yZCA8c2V0aC5mb3JkQGZtci5jb20+IAotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZTsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLm5ldC5VUkxFbmNvZGVyOwotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy4qOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgVGV4dE91dHB1dCBpbXBsZW1lbnRzIFRyYW5zbGV0T3V0cHV0SGFuZGxlciB7Ci0KLSAgICAvLyBUaGVzZSBhcmUgdGhlIHZhcmlvdXMgb3V0cHV0IHR5cGVzIHdlIGhhbmRsZQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV04gPSAtMTsgLy8gZGV0ZXJtaW5lIHR5cGUgZnJvbSBvdXRwdXQgY29udGVudHMKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVhUICAgID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBYTUwgICAgID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIVE1MICAgID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBRTkFNRSAgID0gMzsgIC8vIG5vIHNwZWNpYWwgaGFuZGxpbmcKLQotICAgIC8vIFRoZXNlIHBhcmFtZXRlcnMgYXJlIHNldCBieSB0aGUgPHhzbDpvdXRwdXQ+IGVsZW1lbnQsIG9yIGJ5IHRoZQotICAgIC8vIGdldC9zZXRPdXRwdXRQcm9wZXJ0eSgpIG1ldGhvZHMgaW4gVHJBWAotICAgIHByaXZhdGUgaW50CSAgIF9vdXRwdXRUeXBlID0gVU5LTk9XTjsKLSAgICBwcml2YXRlIFN0cmluZyBfZW5jb2Rpbmc7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX21lZGlhVHlwZSA9ICJ0ZXh0L2h0bWwiOwotICAgIHByaXZhdGUgU3RyaW5nIF9kb2N0eXBlU3lzdGVtID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfZG9jdHlwZVB1YmxpYyA9IG51bGw7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gICBfZXNjYXBlQ2hhcnMgPSBmYWxzZTsKLSAgICBwcml2YXRlIGJvb2xlYW4gICBfc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0gICAgcHJpdmF0ZSBib29sZWFuICAgX2hlYWRUYWdPcGVuID0gZmFsc2U7Ci0gICAgcHJpdmF0ZSBib29sZWFuICAgX2NkYXRhVGFnT3BlbiA9IGZhbHNlOwotCi0gICAgLy8gQ29udGFpbnMgYWxsIGVsZW1lbnRzIHRoYXQgc2hvdWxkIGJlIG91dHB1dCBhcyBDREFUQSBzZWN0aW9ucwotICAgIHByaXZhdGUgSGFzaHRhYmxlIF9jZGF0YSA9IG51bGw7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1BSRUZJWCA9ICJ4bWwiOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEFNUCAgICAgID0gIiZhbXA7Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBMVCAgICAgICA9ICImbHQ7Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBHVCAgICAgICA9ICImZ3Q7Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBDUkxGICAgICA9ICImI3hBOyIudG9DaGFyQXJyYXkoKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gUVVPVEUgICAgPSAiJnF1b3Q7Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOQlNQICAgICA9ICImbmJzcDsiLnRvQ2hhckFycmF5KCk7Ci0KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQU1QX2xlbmd0aCAgID0gQU1QLmxlbmd0aDsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTFRfbGVuZ3RoICAgID0gTFQubGVuZ3RoOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHVF9sZW5ndGggICAgPSBHVC5sZW5ndGg7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENSTEZfbGVuZ3RoICA9IENSTEYubGVuZ3RoOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBRVU9URV9sZW5ndGggPSBRVU9URS5sZW5ndGg7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5CU1BfbGVuZ3RoICA9IE5CU1AubGVuZ3RoOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEJFR0NEQVRBID0gIjwhW0NEQVRBWyIudG9DaGFyQXJyYXkoKTsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gRU5EQ0RBVEEgPSAiXV0+Ii50b0NoYXJBcnJheSgpOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBDTlRDREFUQSA9ICJdXV1dPjwhW0NEQVRBWz4iLnRvQ2hhckFycmF5KCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEJFR0NPTU0gID0gIjwhLS0iLnRvQ2hhckFycmF5KCk7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIEVORENPTU0gID0gIi0tPlxuIi50b0NoYXJBcnJheSgpOwotCi0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVNUFRZU1RSSU5HID0gIiI7Ci0KLSAgICBwcml2YXRlIEF0dHJpYnV0ZUxpc3QgX2F0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlTGlzdCgpOwotICAgIHByaXZhdGUgU3RyaW5nICAgICAgICBfZWxlbWVudE5hbWUgPSBudWxsOwotCi0gICAgLy8gRWFjaCBlbnRyeSAocHJlZml4KSBpbiB0aGlzIGhhc2h0YWJsZSBwb2ludHMgdG8gYSBTdGFjayBvZiBVUklzCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgX25hbWVzcGFjZXM7Ci0gICAgLy8gVGhlIHRvcCBvZiB0aGlzIHN0YWNrIGNvbnRhaW5zIGFuIGlkIG9mIHRoZSBlbGVtZW50IHRoYXQgbGFzdCBkZWNsYXJlZAotICAgIC8vIGEgbmFtZXNwYWNlLiBVc2VkIHRvIGVuc3VyZSBwcmVmaXgvdXJpIG1hcCBzY29wZXMgYXJlIGNsb3NlZCBjb3JyZWN0bHkKLSAgICBwcml2YXRlIFN0YWNrICAgICBfbm9kZVN0YWNrOwotICAgIC8vIFRoZSB0b3Agb2YgdGhpcyBzdGFjayBpcyB0aGUgcHJlZml4IHRoYXQgd2FzIGxhc3QgbWFwcGVkIHRvIGFuIFVSSQotICAgIHByaXZhdGUgU3RhY2sgICAgIF9wcmVmaXhTdGFjazsKLQotICAgIC8vIFRoZSB0b3Agb2YgdGhpcyBzdGFjayBjb250YWlucyB0aGUgUU5hbWUgb2YgdGhlIGN1cnJlbnRseSBvcGVuIGVsZW1lbnQKLSAgICBwcml2YXRlIFN0YWNrICAgICBfcW5hbWVTdGFjazsKLQotICAgIC8vIFRoZSB0b3Agb2YgdGhpcyBzdGFjayBjb250YWlucyB0aGUgZWxlbWVudCBpZCBvZiB0aGUgbGFzdCBlbGVtZW50IHdob3NlCi0gICAgLy8gY29udGVudHMgc2hvdWxkIGJlIG91dHB1dCBhcyBDREFUQSBzZWN0aW9ucy4KLSAgICBwcml2YXRlIFN0YWNrICAgICBfY2RhdGFTdGFjazsKLQotICAgIC8vIEhvbGRzIHRoZSBjdXJyZW50IHRyZWUgZGVwdGggKHNlZSBzdGFydEVsZW1lbnQoKSBhbmQgZW5kRWxlbWVudCgpKS4KLSAgICBwcml2YXRlIGludCBfZGVwdGggPSAwOwotCi0gICAgLy8gUmVmZXJlbmNlIHRvIHRoZSBTQVgyIGhhbmRsZXJzIHRoYXQgY29uc3VtZSB0aGlzIGhhbmRsZXIncyBvdXRwdXQKLSAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIF9zYXhIYW5kbGVyOwotICAgIHByaXZhdGUgTGV4aWNhbEhhbmRsZXIgX2xleEhhbmRsZXI7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGVzIGEgbmV3IHRyYW5zbGV0IG91dHB1dCBwb3N0LXByb2Nlc3NvcgotICAgICAqCi0gICAgICogQHBhcmFtIGhhbmRsZXIgQSBTQVgyIGhhbmRsZXIgdG8gY29uc3VtZSB0aGUgZ2VuZXJhdGVkIFNBWCBldmVudHMgCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUZXh0T3V0cHV0KENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0gICAgICAgIF9zYXhIYW5kbGVyID0gaGFuZGxlcjsKLSAgICAgICAgaW5pdCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBuZXcgdHJhbnNsZXQgb3V0cHV0IHBvc3QtcHJvY2Vzc29yCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaGFuZGxlciBBIFNBWDIgaGFuZGxlciB0byBjb25zdW1lIHRoZSBnZW5lcmF0ZWQgU0FYIGV2ZW50cyAKLSAgICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGRlZmF1bHQgZW5jb2RpbmcgdG8gdXNlIChzZXQgaW4gPHhzbDpvdXRwdXQ+KQotICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgVGV4dE91dHB1dChDb250ZW50SGFuZGxlciBoYW5kbGVyLCBTdHJpbmcgZW5jb2RpbmcpCi0JdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgX3NheEhhbmRsZXIgPSBoYW5kbGVyOwotICAgICAgICBpbml0KCk7Ci0JX2VuY29kaW5nID0gZW5jb2Rpbmc7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlcyBhIG5ldyB0cmFuc2xldCBvdXRwdXQgcG9zdC1wcm9jZXNzb3IKLSAgICAgKgotICAgICAqIEBwYXJhbSBoYW5kbGVyIEEgU0FYMiBoYW5kbGVyIHRvIGNvbnN1bWUgdGhlIGdlbmVyYXRlZCBTQVggZXZlbnRzIAotICAgICAqIEBwYXJhbSBlbmNvZGluZyBUaGUgZGVmYXVsdCBlbmNvZGluZyB0byB1c2UgKHNldCBpbiA8eHNsOm91dHB1dD4pCi0gICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUZXh0T3V0cHV0KENvbnRlbnRIYW5kbGVyIHNheCwgTGV4aWNhbEhhbmRsZXIgbGV4LCBTdHJpbmcgZW5jb2RpbmcpCi0JdGhyb3dzIElPRXhjZXB0aW9uIHsKLSAgICAgICAgX3NheEhhbmRsZXIgPSBzYXg7Ci0JX2xleEhhbmRsZXIgPSBsZXg7Ci0gICAgICAgIGluaXQoKTsKLQlfZW5jb2RpbmcgPSBlbmNvZGluZzsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbml0aWFsaXNlIGdsb2JhbCB2YXJpYWJsZXMKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgaW5pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JLy8gUmVzZXQgYWxsIG91dHB1dCBjb25maWd1cmF0aW9uIGZyb20gPHhzbDpvdXRwdXQ+Ci0JX291dHB1dFR5cGUgPSBVTktOT1dOOwotCV9lbmNvZGluZyA9ICJ1dGYtOCI7Ci0JX21lZGlhVHlwZSA9ICJ0ZXh0L2h0bWwiOwotCi0JLy8gUmVzZXQgYWxsIGludGVybmFsIHZhcmlhYmxlcyBhbmQgdGFibGVzCi0JX2VzY2FwZUNoYXJzICA9IGZhbHNlOwotCV9zdGFydFRhZ09wZW4gPSBmYWxzZTsKLQlfY2RhdGFUYWdPcGVuID0gZmFsc2U7Ci0JX3FuYW1lU3RhY2sgPSBuZXcgU3RhY2soKTsKLQlfY2RhdGFTdGFjayA9IG5ldyBTdGFjaygpOwotCV9jZGF0YVN0YWNrLnB1c2gobmV3IEludGVnZXIoLTEpKTsgLy8gcHVzaCBkdW1teSB2YWx1ZQotCi0JLy8gUmVzZXQgb3VyIGludGVybmFsIG5hbWVzcGFjZSBoYW5kbGluZwotCWluaXROYW1lc3BhY2VzKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ2xvc2VzIHRoZSBvdXRwdXQgc3RyZWFtCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xvc2UoKSB7Ci0JaWYgKChfc2F4SGFuZGxlciAhPSBudWxsKSAmJgotCSAgICAoX3NheEhhbmRsZXIgaW5zdGFuY2VvZiBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcikpIHsKLQkgICAgKChEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcilfc2F4SGFuZGxlcikuY2xvc2UoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbnRlcm5hbGx5IHdoZW4gdGhlIG91dHB1dCB0eXBlIHdhcyBpbml0aWFsbHkKLSAgICAgKiB1bmRlZmluZWQgYW5kIHRoZSB0eXBlIGlzIHNldCAoYnkgdGhpcyBoYW5kbGVyKSBiYXNlZCBvbiB0aGUgY29udGVudHMKLSAgICAgKiBvZiB0aGUgb3V0cHV0LiBTZXQgdGhlIGRlZmF1bHQgdmFsdWVzIGZvciBzb21lIG91dHB1dCBwYXJhbXRlcnMuCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHNldFR5cGVJbnRlcm5hbChpbnQgdHlwZSkgewotCWlmICh0eXBlID09IFhNTCkgewotCSAgICBfZXNjYXBlQ2hhcnMgPSB0cnVlOwotCX0KLQllbHNlIGlmICh0eXBlID09IEhUTUwpIHsKLQkgICAgX2VzY2FwZUNoYXJzID0gdHJ1ZTsKLQkgICAgc2V0SW5kZW50KHRydWUpOwotCX0KLQlzZXRUeXBlKHR5cGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEVtaXQgaGVhZGVyIHRocm91Z2ggdGhlIFNBWCBoYW5kbGVyCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGVtaXRIZWFkZXIoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQkvLyBPdXRwdXQgSFRNTCBoZWFkZXIgYXMgTUVUQSBlbGVtZW50Ci0JaWYgKF9vdXRwdXRUeXBlID09IEhUTUwpIHsKLQkgICAgQXR0cmlidXRlTGlzdCBhdHRycyA9IG5ldyBBdHRyaWJ1dGVMaXN0KCk7Ci0JICAgIGF0dHJzLmFkZCgiaHR0cC1lcXVpdiIsICJDb250ZW50LVR5cGUiKTsKLQkgICAgYXR0cnMuYWRkKCJjb250ZW50IiwgX21lZGlhVHlwZSsiOyBjaGFyc2V0PSIrX2VuY29kaW5nKTsKLQkgICAgX3NheEhhbmRsZXIuc3RhcnRFbGVtZW50KG51bGwsIG51bGwsICJtZXRhIiwgYXR0cnMpOwotCSAgICBfc2F4SGFuZGxlci5lbmRFbGVtZW50KG51bGwsIG51bGwsICJtZXRhIik7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIGFsbCB0aGUgZGF0YSBuZWVkZWQgZm9yIGEgY2FsbCB0byB0aGUKLSAgICAgKiBTQVggaGFuZGxlcidzIHN0YXJ0RWxlbWVudCgpIG1ldGhvZCBoYXMgYmVlbiBnYXRoZXJlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjbG9zZVN0YXJ0VGFnKCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICBfc3RhcnRUYWdPcGVuID0gZmFsc2U7Ci0JICAgIAotCSAgICAvLyBGaW5hbCBjaGVjayB0byBhc3N1cmUgdGhhdCB0aGUgZWxlbWVudCBpcyB3aXRoaW4gYSBuYW1lc3BhY2UKLQkgICAgLy8gdGhhdCBoYXMgYmVlbiBkZWNsYXJlZCAoYWxsIGRlY2xhcmF0aW9ucyBmb3IgdGhpcyBlbGVtZW50Ci0JICAgIC8vIHNob3VsZCBoYXZlIGJlZW4gcHJvY2Vzc2VkIGF0IHRoaXMgcG9pbnQpLgotCSAgICBpbnQgY29sID0gX2VsZW1lbnROYW1lLmxhc3RJbmRleE9mKCc6Jyk7Ci0JICAgIGlmIChjb2wgPiAwKSB7Ci0JCWZpbmFsIFN0cmluZyBwcmVmaXggPSBfZWxlbWVudE5hbWUuc3Vic3RyaW5nKDAsY29sKTsKLQkJZmluYWwgU3RyaW5nIGxvY2FsbmFtZSA9IF9lbGVtZW50TmFtZS5zdWJzdHJpbmcoY29sKzEpOwotCQlmaW5hbCBTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0JCWlmICh1cmkgPT0gbnVsbCkgewotCQkgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKCJOYW1lc3BhY2UgZm9yIHByZWZpeCAiKwotCQkJCQkJcHJlZml4KyIgaGFzIG5vdCBiZWVuICIrCi0JCQkJCQkiZGVjbGFyZWQuIik7Ci0JCX0KLQkJaWYgKHVyaS5lcXVhbHMoRU1QVFlTVFJJTkcpKSBfZWxlbWVudE5hbWUgPSBsb2NhbG5hbWU7Ci0JCV9zYXhIYW5kbGVyLnN0YXJ0RWxlbWVudCh1cmksIGxvY2FsbmFtZSwKLQkJCQkJIF9lbGVtZW50TmFtZSwgX2F0dHJpYnV0ZXMpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlmaW5hbCBTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKEVNUFRZU1RSSU5HKTsKLQkJX3NheEhhbmRsZXIuc3RhcnRFbGVtZW50KHVyaSwgX2VsZW1lbnROYW1lLAotCQkJCQkgX2VsZW1lbnROYW1lLCBfYXR0cmlidXRlcyk7Ci0JICAgIH0KLQotCSAgICAvLyBJbnNlcnQgPE1FVEE+IHRhZyBkaXJlY3RseSBhZnRlciA8SEVBRD4gZWxlbWVudCBpbiBIVE1MIG91dHB1dAotCSAgICBpZiAoX2hlYWRUYWdPcGVuKSB7Ci0JCWVtaXRIZWFkZXIoKTsKLQkJX2hlYWRUYWdPcGVuID0gZmFsc2U7Ci0JICAgIH0KLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfSAKLQotICAgIC8qKgotICAgICAqIFR1cm5zIHNwZWNpYWwgY2hhcmFjdGVyIGVzY2FwaW5nIG9uL29mZi4gTm90ZSB0aGF0IGNoYXJhY3RlcnMgd2lsbAotICAgICAqIG5ldmVyLCBldmVuIGlmIHRoaXMgb3B0aW9uIGlzIHNldCB0byAndHJ1ZScsIGJlIGVzY2FwZWQgd2l0aGluCi0gICAgICogQ0RBVEEgc2VjdGlvbnMgaW4gb3V0cHV0IFhNTCBkb2N1bWVudHMuCi0gICAgICovCi0gICAgcHVibGljIGJvb2xlYW4gc2V0RXNjYXBpbmcoYm9vbGVhbiBlc2NhcGUpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JLy8gU2V0IG91dHB1dCB0eXBlIHRvIFhNTCAodGhlIGRlZmF1bHQpIGlmIHN0aWxsIHVua25vd24uCi0JaWYgKF9vdXRwdXRUeXBlID09IFVOS05PV04pIHNldFR5cGVJbnRlcm5hbChYTUwpOwotCi0JLy8gU2F2ZSBvbGQgZXNjYXBpbmcgc2V0dGluZyAoZm9yIHRoZSByZXR1cm4gdmFsdWUpIGFuZCBzZXQgbmV3IHZhbHVlCi0JYm9vbGVhbiBvbGRTZXR0aW5nID0gX2VzY2FwZUNoYXJzOwotCV9lc2NhcGVDaGFycyA9IGVzY2FwZTsKLQotCS8vIENoYXJhY3RlcnMgYXJlIG5ldmVyIGVzY2FwZWQgaW4gb3V0cHV0IG1vZGUgJ3RleHQnCi0JaWYgKF9vdXRwdXRUeXBlID09IFRFWFQpIF9lc2NhcGVDaGFycyA9IGZhbHNlOyAKLQotCXJldHVybihvbGRTZXR0aW5nKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTdGFydHMgdGhlIG91dHB1dCBkb2N1bWVudC4gT3V0cHV0cyB0aGUgZG9jdW1lbnQgaGVhZGVyIGlmIHRoZQotICAgICAqIG91dHB1dCB0eXBlIGlzIHNldCB0byBYTUwuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBfc2F4SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0JICAgIC8vIE91dHB1dCBlc2NhcGluZyBpcyBfQUxXQVlTXyBlbmFibGVkIGZvciBYTUwgb3V0cHV0Ci0gICAgICAgICAgICBpZiAoX291dHB1dFR5cGUgPT0gWE1MKSBfZXNjYXBlQ2hhcnMgPSB0cnVlOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogRW5kcyB0aGUgZG9jdW1lbnQgb3V0cHV0LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIC8vIFNldCBvdXRwdXQgdHlwZSB0byBYTUwgKHRoZSBkZWZhdWx0KSBpZiBzdGlsbCB1bmtub3duLgotICAgICAgICAgICAgaWYgKF9vdXRwdXRUeXBlID09IFVOS05PV04pIHNldFR5cGVJbnRlcm5hbChYTUwpOwotCi0JICAgIC8vIENsb3NlIGFueSBvcGVuIHN0YXJ0IHRhZwotCSAgICBpZiAoX3N0YXJ0VGFnT3BlbikgY2xvc2VTdGFydFRhZygpOwotCSAgICBpZiAoX2NkYXRhVGFnT3BlbikgY2xvc2VDREFUQSgpOwotCi0JICAgIC8vIENsb3NlIG91dHB1dCBkb2N1bWVudAotICAgICAgICAgICAgX3NheEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLSAgICAgICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIC0gcGFzcyBhIHN0cmluZyB0byB0aGUgU0FYIGhhbmRsZXIncyBjaGFyYWN0ZXJzKCkgbWV0aG9kCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNoYXJhY3RlcnMoU3RyaW5nIHN0cikgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JZmluYWwgY2hhcltdIGNoID0gc3RyLnRvQ2hhckFycmF5KCk7Ci0JX3NheEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgMCwgY2gubGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IG1ldGhvZCAtIHBhc3MgYSB3aG9sZSBjaGFyYWN0ZXIgYXJyYXkgdG8gdGhlIFNBWCBoYW5kbGVyCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCAwLCBjaC5sZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFV0aWxpdHkgbWV0aG9kIC0gZXNjYXBlIHNwZWNpYWwgY2hhcmFjdGVycyBhbmQgcGFzcyB0byBTQVggaGFuZGxlcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBlc2NhcGVDaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IG9mZiwgaW50IGxlbikKLQl0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotCWZpbmFsIGludCBsaW1pdCA9IG9mZiArIGxlbjsKLQlpbnQgb2Zmc2V0ID0gb2ZmOwotCi0JLy8gU3RlcCB0aHJvdWdoIGNoYXJhY3RlcnMgYW5kIGVzY2FwZSBhbGwgc3BlY2lhbCBjaGFyYWN0ZXJzCi0JZm9yIChpbnQgaSA9IG9mZjsgaSA8IGxpbWl0OyBpKyspIHsKLQkgICAgc3dpdGNoIChjaFtpXSkgewotCSAgICBjYXNlICcmJzoKLQkJX3NheEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgb2Zmc2V0LCBpIC0gb2Zmc2V0KTsKLQkJX3NheEhhbmRsZXIuY2hhcmFjdGVycyhBTVAsIDAsIEFNUF9sZW5ndGgpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgJyInOgotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKFFVT1RFLCAwLCBRVU9URV9sZW5ndGgpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgJzwnOgotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKExULCAwLCBMVF9sZW5ndGgpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgJz4nOgotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKEdULCAwLCBHVF9sZW5ndGgpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgJ1x1MDBhMCc6Ci0JCV9zYXhIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIG9mZnNldCwgaSAtIG9mZnNldCk7Ci0JCV9zYXhIYW5kbGVyLmNoYXJhY3RlcnMoTkJTUCwgMCwgTkJTUF9sZW5ndGgpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIH0KLQkgICAgLy8gVE9ETyAtIG1vcmUgY2hhcmFjdGVycyBuZWVkIGVzY2FwaW5nISEhCi0JfQotCS8vIE91dHB1dCByZW1haW5pbmcgY2hhcmFjdGVycyAodGhhdCBkbyBub3QgbmVlZCBlc2NhcGluZykuCi0JaWYgKG9mZnNldCA8IGxpbWl0KSBfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGxpbWl0IC0gb2Zmc2V0KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVdGlsaXR5IG1ldGhvZCAtIHBhc3MgYSB3aG9sZSBjaGFyYWN0ZXMgYXMgQ0RBVEEgdG8gU0FYIGhhbmRsZXIKLSAgICAgKi8KLSAgICBwcml2YXRlIHZvaWQgc3RhcnRDREFUQShjaGFyW10gY2gsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBTQVhFeGNlcHRpb24gewotCQotCWZpbmFsIGludCBsaW1pdCA9IG9mZiArIGxlbjsKLQlpbnQgb2Zmc2V0ID0gb2ZmOwotCi0JLy8gT3V0cHV0IHN0YXJ0IGJyYWNrZXQgLSAiPCFbQ0RBVEFbIgotCWNoYXJhY3RlcnMoQkVHQ0RBVEEpOwotCi0JLy8gRGV0ZWN0IGFueSBvY2N1cmVuY2Ugb2YgIl1dPiIgaW4gdGhlIGNoYXJhY3RlciBhcnJheQotCWZvciAoaW50IGkgPSBvZmZzZXQ7IGkgPCBsaW1pdC0yOyBpKyspIHsKLQkgICAgaWYgKGNoW2ldID09ICddJyAmJiBjaFtpKzFdID09ICddJyAmJiBjaFtpKzJdID09ICc+JykgewotCQlfc2F4SGFuZGxlci5jaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQljaGFyYWN0ZXJzKENOVENEQVRBKTsKLQkJb2Zmc2V0ID0gaSszOwotCQlpPWkrMjsgLy8gU2tpcCBuZXh0IGNoYXJzICddJyBhbmQgJz4nLgotCSAgICB9Ci0JfQotCi0JLy8gT3V0cHV0IHRoZSByZW1haW5pbmcgY2hhcmFjdGVycwotCWlmIChvZmZzZXQgPCBsaW1pdCkgX3NheEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgb2Zmc2V0LCBsaW1pdCAtIG9mZnNldCk7Ci0KLQlfY2RhdGFUYWdPcGVuID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBwcml2YXRlIHZvaWQgY2xvc2VDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24gewotCS8vIE91dHB1dCBjbG9zaW5nIGJyYWNrZXQgLSAiXV0+IgotCWNoYXJhY3RlcnMoRU5EQ0RBVEEpOwotCV9jZGF0YVRhZ09wZW4gPSBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZW5kIGNoYXJhY3RlcnMgdG8gdGhlIG91dHB1dCBkb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgb2ZmLCBpbnQgbGVuKQkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotICAgICAgICB0cnkgewotCSAgICAvLyBDbG9zZSBhbnkgb3BlbiBzdGFydCB0YWcKLQkgICAgaWYgKF9zdGFydFRhZ09wZW4pIGNsb3NlU3RhcnRUYWcoKTsKLQkgICAgCi0gICAgICAgICAgICAvLyBTZXQgb3V0cHV0IHR5cGUgdG8gWE1MICh0aGUgZGVmYXVsdCkgaWYgc3RpbGwgdW5rbm93bi4KLSAgICAgICAgICAgIGlmIChfb3V0cHV0VHlwZSA9PSBVTktOT1dOKSBzZXRUeXBlSW50ZXJuYWwoWE1MKTsKLQotICAgICAgICAgICAgLy8gVGFrZSBzcGVjaWFsIHByZWNhdXRpb25zIGlmIHdpdGhpbiBhIENEQVRBIHNlY3Rpb24uIElmIHdlCi0gICAgICAgICAgICAvLyBlbmNvdW50ZXIgdGhlIHNlcXVlbmNlICddXT4nIHdpdGhpbiB0aGUgQ0RBVEEsIHdlIG5lZWQgdG8KLSAgICAgICAgICAgIC8vIGJyZWFrIHRoZSBzZWN0aW9uIGluIHR3byBhbmQgbGVhdmUgdGhlICddXScgYXQgdGhlIGVuZCBvZgotICAgICAgICAgICAgLy8gdGhlIGZpcnN0IENEQVRBIGFuZCAnPicgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dC4gT3RoZXIKLQkgICAgLy8gc3BlY2lhbCBjaGFyYWN0ZXJzL3NlcXVlbmNlcyBhcmUgX05PVF8gZXNjYXBlZCB3aXRoaW4gQ0RBVEEuCi0JICAgIEludGVnZXIgSSA9IChJbnRlZ2VyKV9jZGF0YVN0YWNrLnBlZWsoKTsKLQkgICAgaWYgKChJLmludFZhbHVlKCkgPT0gX2RlcHRoKSAmJiAoIV9jZGF0YVRhZ09wZW4pKSB7Ci0JCXN0YXJ0Q0RBVEEoY2gsIG9mZiwgbGVuKTsKLQkgICAgfQotCSAgICAvLyBPdXRwdXQgZXNjYXBlZCBjaGFyYWN0ZXJzIGlmIHJlcXVpcmVkLiBOb24tQVNDSUkgY2hhcmFjdGVycwotICAgICAgICAgICAgLy8gd2l0aGluIEhUTUwgYXR0cmlidXRlcyBzaG91bGQgX05PVF8gYmUgZXNjYXBlZC4KLQkgICAgZWxzZSBpZiAoX2VzY2FwZUNoYXJzKSB7Ci0JCWlmIChfb3V0cHV0VHlwZSA9PSBIVE1MKSB7Ci0JCSAgICBmaW5hbCBTdHJpbmcgcW5hbWUgPSAoU3RyaW5nKV9xbmFtZVN0YWNrLnBlZWsoKTsKLQkJICAgIGlmICgocW5hbWUuZXF1YWxzKCJzdHlsZSIpKSB8fCAocW5hbWUuZXF1YWxzKCJzY3JpcHQiKSkpIHsKLQkJCV9zYXhIYW5kbGVyLmNoYXJhY3RlcnMoY2gsIG9mZiwgbGVuKTsKLQkJCXJldHVybjsKLQkJICAgIH0KLQkJfQotCQllc2NhcGVDaGFyYWN0ZXJzKGNoLCBvZmYsIGxlbik7Ci0JICAgIH0KLQkgICAgLy8gT3V0cHV0IHRoZSBjaHJhY3RlcnMgYXMgdGhlIGFyZQotCSAgICBlbHNlIHsKLQkJX3NheEhhbmRsZXIuY2hhcmFjdGVycyhjaCwgb2ZmLCBsZW4pOwotCSAgICB9Ci0gICAgICAgIH0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFN0YXJ0IGFuIGVsZW1lbnQgaW4gdGhlIG91dHB1dCBkb2N1bWVudC4gVGhpcyBtaWdodCBiZSBhbiBYTUwKLSAgICAgKiBlbGVtZW50ICg8ZWxlbT5kYXRhPC9lbGVtPiB0eXBlKSBvciBhIENEQVRBIHNlY3Rpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCi0JdHJ5IHsKLQkgICAgLy8gRG8gbm90IG91dHB1dCBlbGVtZW50IHRhZ3MgaWYgb3V0cHV0IG1vZGUgaXMgJ3RleHQnCi0JICAgIGlmIChfb3V0cHV0VHlwZSA9PSBURVhUKSByZXR1cm47IAotCi0JICAgIC8vIENsb3NlIGFueSBvcGVuIHN0YXJ0IHRhZwotCSAgICBpZiAoX3N0YXJ0VGFnT3BlbikgY2xvc2VTdGFydFRhZygpOwotCSAgICBpZiAoX2NkYXRhVGFnT3BlbikgY2xvc2VDREFUQSgpOwotCi0JICAgIC8vIElmIHdlIGRvbid0IGtub3cgdGhlIG91dHB1dCB0eXBlIHlldCB3ZSBuZWVkIHRvIGV4YW1pbmUKLQkgICAgLy8gdGhlIHZlcnkgZmlyc3QgZWxlbWVudCB0byBzZWUgaWYgaXQgaXMgImh0bWwiLgotCSAgICBpZiAoX291dHB1dFR5cGUgPT0gVU5LTk9XTikgewotCQlpZiAoZWxlbWVudE5hbWUudG9Mb3dlckNhc2UoKS5lcXVhbHMoImh0bWwiKSkKLQkJICAgIHNldFR5cGVJbnRlcm5hbChIVE1MKTsKLQkJZWxzZQotCQkgICAgc2V0VHlwZUludGVybmFsKFhNTCk7Ci0JICAgIH0KLQotCSAgICAvLyBIYW5kbGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiAoZm9yIGZpcnN0IGVsZW1lbnQgb25seSkKLQkgICAgaWYgKF9sZXhIYW5kbGVyICE9IG51bGwpIHsKLQkJaWYgKCgoX291dHB1dFR5cGUgPT0gWE1MKSAmJiAoX2RvY3R5cGVTeXN0ZW0gIT0gbnVsbCkpIHx8Ci0JCSAgICAoKF9kb2N0eXBlU3lzdGVtICE9IG51bGwpIHx8IChfZG9jdHlwZVB1YmxpYyAhPSBudWxsKSkpCi0JCSAgICBfbGV4SGFuZGxlci5zdGFydERURChlbGVtZW50TmFtZSwKLQkJCQkJIF9kb2N0eXBlUHVibGljLF9kb2N0eXBlU3lzdGVtKTsKLQkJX2xleEhhbmRsZXIgPSBudWxsOwotCSAgICB9Ci0KLQkgICAgX2RlcHRoKys7Ci0JICAgIF9lbGVtZW50TmFtZSA9IGVsZW1lbnROYW1lOwotCSAgICBfYXR0cmlidXRlcy5jbGVhcigpOwotCSAgICBfc3RhcnRUYWdPcGVuID0gdHJ1ZTsKLQotCSAgICBfcW5hbWVTdGFjay5wdXNoKGVsZW1lbnROYW1lKTsKLQotCSAgICAvLyBidWcgZml4IDI4MDcsIDxzZXRoLmZvcmRAZm1yLmNvbT4KLQkgICAgaWYgKF9jZGF0YSAhPSBudWxsKSB7Ci0JCWlmIChfY2RhdGEuZ2V0KGVsZW1lbnROYW1lKSAhPSBudWxsKSB7Ci0JCSAgICBfY2RhdGFTdGFjay5wdXNoKG5ldyBJbnRlZ2VyKF9kZXB0aCkpOwotCQl9Ci0JICAgIH0KLQotCSAgICAvLyBJbnNlcnQgPE1FVEE+IHRhZyBkaXJlY3RseSBhZnRlciA8SEVBRD4gZWxlbWVudCBpbiBIVE1MIGRvYwotCSAgICBpZiAoX291dHB1dFR5cGUgPT0gSFRNTCkKLQkJaWYgKGVsZW1lbnROYW1lLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJoZWFkIikpCi0JCSAgICBfaGVhZFRhZ09wZW4gPSB0cnVlOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLSAgICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGVzY2FwZXMgc3BlY2lhbCBjaGFyYWN0ZXJzIHVzZWQgaW4gYXR0cmlidXRlIHZhbHVlcwotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGVzY2FwZUNoYXJzKFN0cmluZyB2YWx1ZSkgewotCi0JaW50IGk7Ci0JY2hhcltdIGNoID0gdmFsdWUudG9DaGFyQXJyYXkoKTsKLQlpbnQgbGltaXQgPSBjaC5sZW5ndGg7Ci0JaW50IG9mZnNldCA9IDA7Ci0JU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQkKLQlmb3IgKGkgPSAwOyBpIDwgbGltaXQ7IGkrKykgewotCSAgICBzd2l0Y2ggKGNoW2ldKSB7Ci0JICAgIGNhc2UgJyYnOgotCQlidWYuYXBwZW5kKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQlidWYuYXBwZW5kKEFNUCk7Ci0JCW9mZnNldCA9IGkgKyAxOwotCQlicmVhazsKLQkgICAgY2FzZSAnIic6Ci0JCWJ1Zi5hcHBlbmQoY2gsIG9mZnNldCwgaSAtIG9mZnNldCk7Ci0JCWJ1Zi5hcHBlbmQoUVVPVEUpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIGNhc2UgJzwnOgotCQlidWYuYXBwZW5kKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQlidWYuYXBwZW5kKExUKTsKLQkJb2Zmc2V0ID0gaSArIDE7Ci0JCWJyZWFrOwotCSAgICBjYXNlICc+JzoKLQkJYnVmLmFwcGVuZChjaCwgb2Zmc2V0LCBpIC0gb2Zmc2V0KTsKLQkJYnVmLmFwcGVuZChHVCk7Ci0JCW9mZnNldCA9IGkgKyAxOwotCQlicmVhazsKLQkgICAgY2FzZSAnXG4nOgotCQlidWYuYXBwZW5kKGNoLCBvZmZzZXQsIGkgLSBvZmZzZXQpOwotCQlidWYuYXBwZW5kKENSTEYpOwotCQlvZmZzZXQgPSBpICsgMTsKLQkJYnJlYWs7Ci0JICAgIH0KLQl9Ci0JaWYgKG9mZnNldCA8IGxpbWl0KSB7Ci0JICAgIGJ1Zi5hcHBlbmQoY2gsIG9mZnNldCwgbGltaXQgLSBvZmZzZXQpOwotCX0KLQlyZXR1cm4oYnVmLnRvU3RyaW5nKCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFB1dCBhbiBhdHRyaWJ1dGUgYW5kIGl0cyB2YWx1ZSBpbiB0aGUgc3RhcnQgdGFnIG9mIGFuIGVsZW1lbnQuCi0gICAgICogU2lnbmFsIGFuIGV4Y2VwdGlvbiBpZiB0aGlzIGlzIGF0dGVtcHRlZCBkb25lIG91dHNpZGUgYSBzdGFydCB0YWcuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlKFN0cmluZyBuYW1lLCBmaW5hbCBTdHJpbmcgdmFsdWUpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQkKLQkvLyBEbyBub3Qgb3V0cHV0IGF0dHJpYnV0ZXMgaWYgb3V0cHV0IG1vZGUgaXMgJ3RleHQnCi0JaWYgKF9vdXRwdXRUeXBlID09IFRFWFQpIHJldHVybjsgCi0KLQlpZiAoX3N0YXJ0VGFnT3BlbikgewotCi0JICAgIC8vIFVSTC1lbmNvZGUgaHJlZiBhdHRyaWJ1dGVzIGluIEhUTUwgb3V0cHV0Ci0JICAgIGlmICgoX291dHB1dFR5cGUgPT0gSFRNTCkgJiYgKG5hbWUuZXF1YWxzKCJocmVmIikpKSB7Ci0JCV9hdHRyaWJ1dGVzLmFkZChuYW1lLCBVUkxFbmNvZGVyLmVuY29kZSh2YWx1ZSkpOwotCQlyZXR1cm47Ci0JICAgIH0KLQotCSAgICAvLyBJbnRlcmNlcHQgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBhbmQgaGFuZGxlIHRoZW0gc2VwYXJhdGVseQotCSAgICBpZiAobmFtZS5zdGFydHNXaXRoKCJ4bWxucyIpKSB7Ci0JCWlmIChuYW1lLmxlbmd0aCgpID09IDUpCi0JCSAgICBuYW1lc3BhY2UoRU1QVFlTVFJJTkcsdmFsdWUpOwotCQllbHNlCi0JCSAgICBuYW1lc3BhY2UobmFtZS5zdWJzdHJpbmcoNiksdmFsdWUpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlmaW5hbCBpbnQgY29sID0gbmFtZS5sYXN0SW5kZXhPZignOicpOwotCQlpZiAoY29sID4gMCkgewotCQkgICAgZmluYWwgU3RyaW5nIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsY29sKTsKLQkJICAgIGZpbmFsIFN0cmluZyBsb2NhbG5hbWUgPSBuYW1lLnN1YnN0cmluZyhjb2wrMSk7Ci0JCSAgICBmaW5hbCBTdHJpbmcgdXJpID0gbG9va3VwTmFtZXNwYWNlKHByZWZpeCk7Ci0JCSAgICBpZiAodXJpID09IG51bGwpIHsKLQkJCXRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbigiTmFtZXNwYWNlIGZvciBwcmVmaXggIisKLQkJCQkJCSAgICBwcmVmaXgrIiBoYXMgbm90IGJlZW4gIisKLQkJCQkJCSAgICAiZGVjbGFyZWQuIik7Ci0JCSAgICB9Ci0JCSAgICBpZiAodXJpLmVxdWFscyhFTVBUWVNUUklORykpIG5hbWUgPSBsb2NhbG5hbWU7Ci0JCX0KLQkJaWYgKF9vdXRwdXRUeXBlID09IEhUTUwpCi0JCSAgICBfYXR0cmlidXRlcy5hZGQobmFtZSwgdmFsdWUpOwotCQllbHNlCi0JCSAgICBfYXR0cmlidXRlcy5hZGQobmFtZSwgZXNjYXBlQ2hhcnModmFsdWUpKTsKLQkgICAgfQotCX0KLQllbHNlIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKCJhdHRyaWJ1dGUgJyIrbmFtZSsKLQkJCQkJIicgb3V0c2lkZSBvZiBlbGVtZW50Iik7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEVuZCBhbiBlbGVtZW50IG9yIENEQVRBIHNlY3Rpb24gaW4gdGhlIG91dHB1dCBkb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCQotCS8vIERvIG5vdCBvdXRwdXQgZWxlbWVudCB0YWdzIGlmIG91dHB1dCBtb2RlIGlzICd0ZXh0JwotCWlmIChfb3V0cHV0VHlwZSA9PSBURVhUKSByZXR1cm47Ci0gCi0JdHJ5IHsKLQkgICAgYm9vbGVhbiBjbG9zZUVsZW1lbnQgPSB0cnVlOwotCi0JICAgIC8vIENsb3NlIGFueSBvcGVuIGVsZW1lbnQKLQkgICAgaWYgKF9zdGFydFRhZ09wZW4pIGNsb3NlU3RhcnRUYWcoKTsKLQkgICAgaWYgKF9jZGF0YVRhZ09wZW4pIGNsb3NlQ0RBVEEoKTsKLQotCSAgICBmaW5hbCBTdHJpbmcgcW5hbWUgPSAoU3RyaW5nKShfcW5hbWVTdGFjay5wb3AoKSk7Ci0gICAgICAgICAgICBpZiAoY2xvc2VFbGVtZW50KSBfc2F4SGFuZGxlci5lbmRFbGVtZW50KG51bGwsIG51bGwsIHFuYW1lKTsKLQotICAgICAgICAgICAgcG9wTmFtZXNwYWNlcygpOwotCi0JICAgIEludGVnZXIgSSA9IChJbnRlZ2VyKV9jZGF0YVN0YWNrLnBlZWsoKTsKLQkgICAgaWYgKEkuaW50VmFsdWUoKSA9PSBfZGVwdGgpIF9jZGF0YVN0YWNrLnBvcCgpOwotCi0gICAgICAgICAgICBfZGVwdGgtLTsKLQotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2VuZCBhIEhUTUwtc3R5bGUgY29tbWVudCB0byB0aGUgb3V0cHV0IGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICAvLyBDbG9zZSBhbnkgb3BlbiBlbGVtZW50IGJlZm9yZSBlbWl0dGluZyBjb21tZW50Ci0gICAgICAgICAgICBpZiAoX3N0YXJ0VGFnT3BlbikgY2xvc2VTdGFydFRhZygpOwotCSAgICBpZiAoX2NkYXRhVGFnT3BlbikgY2xvc2VDREFUQSgpOwotCi0gICAgICAgICAgICAvLyBTZXQgb3V0cHV0IHR5cGUgdG8gWE1MICh0aGUgZGVmYXVsdCkgaWYgc3RpbGwgdW5rbm93bi4KLSAgICAgICAgICAgIGlmIChfb3V0cHV0VHlwZSA9PSBVTktOT1dOKSBzZXRUeXBlSW50ZXJuYWwoWE1MKTsKLQotICAgICAgICAgICAgLy8gLi4uYW5kIHRoZW4gb3V0cHV0IHRoZSBjb21tZW50LgotICAgICAgICAgICAgY2hhcmFjdGVycyhCRUdDT01NKTsKLSAgICAgICAgICAgIGNoYXJhY3RlcnMoY29tbWVudCk7Ci0gICAgICAgICAgICBjaGFyYWN0ZXJzKEVORENPTU0pOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKGUpOwotCX0KLSAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogU2VuZCBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdG8gdGhlIG91dHB1dCBkb2N1bWVudAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotICAgICAgICB0cnkgewotCSAgICAvLyBDbG9zZSBhbnkgb3BlbiBlbGVtZW50Ci0JICAgIGlmIChfc3RhcnRUYWdPcGVuKSBjbG9zZVN0YXJ0VGFnKCk7Ci0JICAgIGlmIChfY2RhdGFUYWdPcGVuKSBjbG9zZUNEQVRBKCk7Ci0KLQkgICAgLy8gUGFzcyB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB0byB0aGUgU0FYIGhhbmRsZXIKLSAgICAgICAgICAgIF9zYXhIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsIGRhdGEpOwotICAgICAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotICAgICAgICAgICAgdGhyb3cgbmV3IFRyYW5zbGV0RXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5pdGlhbGl6ZSBuYW1lc3BhY2Ugc3RhY2tzCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIGluaXROYW1lc3BhY2VzKCkgewotCV9uYW1lc3BhY2VzID0gbmV3IEhhc2h0YWJsZSgpOwotCV9ub2RlU3RhY2sgPSBuZXcgU3RhY2soKTsKLQlfcHJlZml4U3RhY2sgPSBuZXcgU3RhY2soKTsKLQotCS8vIERlZmluZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgKGluaXRpYWxseSBtYXBzIHRvICIiIHVyaSkKLQlTdGFjayBzdGFjayA9ICBuZXcgU3RhY2soKTsKLQlfbmFtZXNwYWNlcy5wdXQoRU1QVFlTVFJJTkcsIHN0YWNrKTsKLQlzdGFjay5wdXNoKEVNUFRZU1RSSU5HKTsKLQlfcHJlZml4U3RhY2sucHVzaChFTVBUWVNUUklORyk7Ci0JX25vZGVTdGFjay5wdXNoKG5ldyBJbnRlZ2VyKC0xKSk7Ci0JX2RlcHRoID0gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWNsYXJlIGEgcHJlZml4IHRvIHBvaW50IHRvIGEgbmFtZXNwYWNlIFVSSQotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwdXNoTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpIHRocm93cyBTQVhFeGNlcHRpb24gewotCi0JaWYgKHByZWZpeC5lcXVhbHMoWE1MX1BSRUZJWCkpIHJldHVybjsKLQotCVN0YWNrIHN0YWNrOwotCS8vIEdldCB0aGUgc3RhY2sgdGhhdCBjb250YWlucyBVUklzIGZvciB0aGUgc3BlY2lmaWVkIHByZWZpeAotCWlmICgoc3RhY2sgPSAoU3RhY2spX25hbWVzcGFjZXMuZ2V0KHByZWZpeCkpID09IG51bGwpIHsKLQkgICAgc3RhY2sgPSBuZXcgU3RhY2soKTsKLQkgICAgX25hbWVzcGFjZXMucHV0KHByZWZpeCwgc3RhY2spOwotCX0KLQkvLyBRdWl0IG5vdyBpZiB0aGUgVVJJIHRoZSBwcmVmaXggY3VycmVudGx5IG1hcHMgdG8gaXMgdGhlIHNhbWUgYXMgdGhpcwotCWlmICghc3RhY2suZW1wdHkoKSAmJiB1cmkuZXF1YWxzKHN0YWNrLnBlZWsoKSkpIHJldHVybjsKLQkvLyBQdXQgdGhpcyBVUkkgb24gdG9wIG9mIHRoZSBzdGFjayBmb3IgdGhpcyBwcmVmaXgKLQlzdGFjay5wdXNoKHVyaSk7Ci0KLQlfcHJlZml4U3RhY2sucHVzaChwcmVmaXgpOwotCV9ub2RlU3RhY2sucHVzaChuZXcgSW50ZWdlcihfZGVwdGgpKTsKLQotCWlmICgoIXByZWZpeC5lcXVhbHMoRU1QVFlTVFJJTkcpKSAmJiAodXJpLmVxdWFscyhFTVBUWVNUUklORykpKSByZXR1cm47Ci0JX3NheEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBVbmRlY2xhcmUgdGhlIG5hbWVzcGFjZSB0aGF0IGlzIGN1cnJlbnRseSBwb2ludGVkIHRvIGJ5IGEgZ2l2ZW4gcHJlZml4Ci0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBvcE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQotCWlmIChwcmVmaXguZXF1YWxzKFhNTF9QUkVGSVgpKSByZXR1cm47Ci0KLQlTdGFjayBzdGFjazsKLQlpZiAoKHN0YWNrID0gKFN0YWNrKV9uYW1lc3BhY2VzLmdldChwcmVmaXgpKSAhPSBudWxsKSB7Ci0JICAgIHN0YWNrLnBvcCgpOwotCSAgICBfc2F4SGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKHByZWZpeCk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFBvcCBhbGwgbmFtZXNwYWNlIGRlZmluaXRpb25zIHRoYXQgd2VyZSBkZWxjYXJlZCBieSB0aGUgY3VycmVudCBlbGVtZW50Ci0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBvcE5hbWVzcGFjZXMoKSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24gewotCXRyeSB7Ci0JICAgIHdoaWxlICh0cnVlKSB7Ci0JCWlmIChfbm9kZVN0YWNrLmlzRW1wdHkoKSkgcmV0dXJuOwotCQlJbnRlZ2VyIGkgPSAoSW50ZWdlcikoX25vZGVTdGFjay5wZWVrKCkpOwotCQlpZiAoaS5pbnRWYWx1ZSgpICE9IF9kZXB0aCkgcmV0dXJuOwotCQlfbm9kZVN0YWNrLnBvcCgpOwotCQlwb3BOYW1lc3BhY2UoKFN0cmluZylfcHJlZml4U3RhY2sucG9wKCkpOwotCSAgICB9Ci0JfQotCWNhdGNoIChTQVhFeGNlcHRpb24gZSkgewotCSAgICB0aHJvdyBuZXcgVHJhbnNsZXRFeGNlcHRpb24oZSk7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFVzZSBhIG5hbWVzcGFjZSBwcmVmaXggdG8gbG9va3VwIGEgbmFtZXNwYWNlIFVSSQotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIGxvb2t1cE5hbWVzcGFjZShTdHJpbmcgcHJlZml4KSB7Ci0JZmluYWwgU3RhY2sgc3RhY2sgPSAoU3RhY2spX25hbWVzcGFjZXMuZ2V0KHByZWZpeCk7Ci0JcmV0dXJuIHN0YWNrICE9IG51bGwgJiYgIXN0YWNrLmlzRW1wdHkoKSA/IChTdHJpbmcpc3RhY2sucGVlaygpIDogbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZW5kIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQuIFRoZSBuYW1lc3BhY2UKLSAgICAgKiBkZWNsYXJhdGlvbiB3aWxsIG5vdCBiZSBpbmNsdWRlIGlmIHRoZSBuYW1lc3BhY2UgaXMgYWxyZWFkeSBpbiBzY29wZQotICAgICAqIHdpdGggdGhlIHNhbWUgcHJlZml4LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZShmaW5hbCBTdHJpbmcgcHJlZml4LCBmaW5hbCBTdHJpbmcgdXJpKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQkgICAgaWYgKF9zdGFydFRhZ09wZW4pCi0JCXB1c2hOYW1lc3BhY2UocHJlZml4LCB1cmkpOwotCSAgICBlbHNlCi0JCXRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbigibmFtZXNwYWNlIGRlY2xhcmF0aW9uICciK3ByZWZpeCsKLQkJCQkJICAgICInPSciK3VyaSsiJyBvdXRzaWRlIG9mIGVsZW1lbnQiKTsKLQl9Ci0JY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2xldEV4Y2VwdGlvbihlKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqIAotICAgICAqIFRha2VzIGEgcW5hbWUgYXMgYSBzdHJpbmcgb24gdGhlIGZvcm1hdCBwcmVmaXg6bG9jYWwtbmFtZSBhbmQKLSAgICAgKiByZXR1cm5zIGEgc3RyaWcgd2l0aCB0aGUgZXhwYW5kZWQgUU5hbWUgb24gdGhlIGZvcm1hdCB1cmk6bG9jYWwtbmFtZS4KLSAgICAgKi8KLSAgICBwcml2YXRlIFN0cmluZyBleHBhbmRRTmFtZShTdHJpbmcgd2l0aFByZWZpeCkgewotCWludCBjb2wgPSB3aXRoUHJlZml4Lmxhc3RJbmRleE9mKCc6Jyk7Ci0JaWYgKGNvbCA9PSAtMSkgcmV0dXJuKHdpdGhQcmVmaXgpOwotCi0JZmluYWwgU3RyaW5nIHByZWZpeCA9IHdpdGhQcmVmaXguc3Vic3RyaW5nKDAsY29sKTsKLQlmaW5hbCBTdHJpbmcgbG9jYWwgPSAgd2l0aFByZWZpeC5zdWJzdHJpbmcoY29sKzEsd2l0aFByZWZpeC5sZW5ndGgoKSk7Ci0JZmluYWwgU3RyaW5nIHVyaSA9IGxvb2t1cE5hbWVzcGFjZShwcmVmaXgpOwotCi0JaWYgKHVyaSA9PSBudWxsKQotCSAgICByZXR1cm4obG9jYWwpOwotCWVsc2UgaWYgKHVyaSA9PSBFTVBUWVNUUklORykKLQkgICAgcmV0dXJuKGxvY2FsKTsKLQllbHNlCi0JICAgIHJldHVybih1cmkrIjoiK2xvY2FsKTsKLSAgICB9Ci0KLSAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gICAgICogVGhlIGZvbGxvd2luZyBhcmUgYWxsIG1ldGhvZHMgZm9yIGNvbmZpZ3VyaW5nIHRoZSBvdXRwdXQgc2V0dGluZ3MKLSAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotICAgIC8qKgotICAgICAqIFNldCB0aGUgb3V0cHV0IHR5cGUuIFRoZSB0eXBlIG11c3QgYmUgd2l0aGVyIFRFWFQsIFhNTCBvciBIVE1MLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFR5cGUoaW50IHR5cGUpICB7Ci0JdHJ5IHsKLQkgICAgX291dHB1dFR5cGUgPSB0eXBlOwotCSAgICBpZiAoX2VuY29kaW5nID09IG51bGwpIF9lbmNvZGluZyA9ICJ1dGYtOCI7Ci0JICAgIGlmIChfc2F4SGFuZGxlciBpbnN0YW5jZW9mIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKQotCQkoKERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKV9zYXhIYW5kbGVyKS5zZXRPdXRwdXRUeXBlKHR5cGUpOwotCX0KLQljYXRjaCAoU0FYRXhjZXB0aW9uIGUpIHsgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFR1cm5zIG91dHB1dCBpbmRlbnRhdGlvbiBvbi9vZmYuIFNob3VsZCBvbmx5IGJlIHNldCB0byBvbgotICAgICAqIGlmIHRoZSBvdXRwdXQgdHlwZSBpcyBYTUwgb3IgSFRNTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRJbmRlbnQoYm9vbGVhbiBpbmRlbnQpIHsKLQlpZiAoX3NheEhhbmRsZXIgaW5zdGFuY2VvZiBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcikgewotICAgICAgICAgICAgKChEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcilfc2F4SGFuZGxlcikuc2V0SW5kZW50KGluZGVudCk7Ci0JfQotICAgIH0gCi0KLSAgICAvKioKLSAgICAgKiBEaXJlY3RpdmUgdG8gdHVybiB4bWwgaGVhZGVyIGRlY2xhcmF0aW9uICBvbi9vZmYuIAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG9taXRIZWFkZXIoYm9vbGVhbiB2YWx1ZSkgewotCWlmIChfc2F4SGFuZGxlciBpbnN0YW5jZW9mIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKSB7Ci0gICAgICAgICAgICAoKERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKV9zYXhIYW5kbGVyKS5vbWl0SGVhZGVyKHZhbHVlKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBYTUwgb3V0cHV0IGRvY3VtZW50IHZlcnNpb24gLSBzaG91bGQgYmUgMS4wCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihTdHJpbmcgdmVyc2lvbikgewotCWlmIChfc2F4SGFuZGxlciBpbnN0YW5jZW9mIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKSB7Ci0gICAgICAgICAgICAoKERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKV9zYXhIYW5kbGVyKS5zZXRWZXJzaW9uKHZlcnNpb24pOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIFhNTCBzdGFuZGFsb25lIGF0dHJpYnV0ZSAtIG11c3QgYmUgInllcyIgb3IgIm5vIgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN0YW5kYWxvbmUoU3RyaW5nIHN0YW5kYWxvbmUpIHsKLQlpZiAoX3NheEhhbmRsZXIgaW5zdGFuY2VvZiBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcikgewotICAgICAgICAgICAgKChEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcilfc2F4SGFuZGxlcikuc2V0U3RhbmRhbG9uZShzdGFuZGFsb25lKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBvdXRwdXQgZG9jdW1lbnQgc3lzdGVtL3B1YmxpYyBpZGVudGlmaWVycwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldERvY3R5cGUoU3RyaW5nIHN5c3RlbSwgU3RyaW5nIHB1YikgewotCV9kb2N0eXBlU3lzdGVtID0gc3lzdGVtOwotCV9kb2N0eXBlUHVibGljID0gcHViOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCB0aGUgb3V0cHV0IG1lZGlhIHR5cGUgLSBvbmx5IHJlbGV2YW50IGZvciBIVE1MIG91dHB1dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1lZGlhVHlwZShTdHJpbmcgbWVkaWFUeXBlKSB7Ci0JLy8gVGhpcyB2YWx1ZSBkb2VzIG5vdCBoYXZlIHRvIGJlIHBhc3NlZCB0byB0aGUgU0FYIGhhbmRsZXIuIFRoaXMKLQkvLyBoYW5kbGVyIGNyZWF0ZXMgdGhlIEhUTUwgPG1ldGE+IHRhZyBpbiB3aGljaCB0aGUgbWVkaWEtdHlwZQotCS8vIChNSU1FLXR5cGUpIHdpbGwgYmUgdXNlZC4KLQlfbWVkaWFUeXBlID0gbWVkaWFUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoZSA8eHNsOm91dHB1dCBtZXRob2Q9InhtbCIvPiBpbnN0cnVjdGlvbiBjYW4gc3BlY2lmeSB0aGF0IGNlcnRhaW4KLSAgICAgKiBYTUwgZWxlbWVudHMgc2hvdWxkIGJlIG91dHB1dCBhcyBDREFUQSBzZWN0aW9ucy4gVGhpcyBtZXRob2RzIGFsbG93cwotICAgICAqIHRoZSB0cmFuc2xldCB0byBpbnNlcnQgdGhlc2UgZWxlbWVudHMgaW50byBhIGhhc2h0YWJsZSBvZiBzdHJpbmdzLgotICAgICAqIEV2ZXJ5IG91dHB1dCBlbGVtZW50IGlzIGxvb2tlZCB1cCBpbiB0aGlzIGhhc2h0YWJsZSBiZWZvcmUgaXQgaXMKLSAgICAgKiBvdXRwdXQuCi0gICAgICovIAotICAgIHB1YmxpYyB2b2lkIHNldENkYXRhRWxlbWVudHMoSGFzaHRhYmxlIGVsZW1lbnRzKSB7Ci0JX2NkYXRhID0gZWxlbWVudHM7Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1RyYW5zbGV0T3V0cHV0QmFzZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZS9UcmFuc2xldE91dHB1dEJhc2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzliYzgxYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lL1RyYW5zbGV0T3V0cHV0QmFzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTMgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqIEBhdXRob3IgU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbgotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lOwotCi0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkhhc2h0YWJsZTsKLQotcHVibGljIGNsYXNzIFRyYW5zbGV0T3V0cHV0QmFzZSBpbXBsZW1lbnRzIFRyYW5zbGV0T3V0cHV0SGFuZGxlciB7Ci0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7fQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHt9Ci0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24ge30KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24ge30KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHt9Ci0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBTdHJpbmcgYXR0cmlidXRlVmFsdWUpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHt9Ci0gICAgcHVibGljIHZvaWQgbmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0JdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHt9Ci0gICAgcHVibGljIHZvaWQgY29tbWVudChTdHJpbmcgY29tbWVudCkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uIHt9Ci0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotCXRocm93cyBUcmFuc2xldEV4Y2VwdGlvbiB7fQotICAgIHB1YmxpYyBib29sZWFuIHNldEVzY2FwaW5nKGJvb2xlYW4gZXNjYXBlKSAKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb24geyByZXR1cm4gdHJ1ZTsgfQotICAgIHB1YmxpYyBTdHJpbmcgZXhwYW5kUU5hbWUoU3RyaW5nIHdpdGhQcmVmaXgpIHsgcmV0dXJuKHdpdGhQcmVmaXgpOyB9Ci0gICAgcHVibGljIHZvaWQgc2V0VHlwZShpbnQgdHlwZSkge30KLSAgICBwdWJsaWMgdm9pZCBzZXRJbmRlbnQoYm9vbGVhbiBpbmRlbnQpIHt9Ci0gICAgcHVibGljIHZvaWQgb21pdEhlYWRlcihib29sZWFuIHZhbHVlKSB7fQotICAgIHB1YmxpYyB2b2lkIHNldENkYXRhRWxlbWVudHMoSGFzaHRhYmxlIGVsZW1lbnRzKSB7fQotICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkge30KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvRE9NMlNBWC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheC9ET00yU0FYLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNhZWIwMGQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheC9ET00yU0FYLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjYgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlciAKLSAqCi0gKi8KLQotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5EVERIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uTmFtZWROb2RlTWFwOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20uRW50aXR5OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vdGF0aW9uOwotCi1wdWJsaWMgY2xhc3MgRE9NMlNBWCBpbXBsZW1lbnRzIFhNTFJlYWRlciAsIExvY2F0b3IgewotICAgIHByaXZhdGUgRG9jdW1lbnQgX2RvbSA9IG51bGw7Ci0gICAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciBfY29udGVudEhkbHIgPSBudWxsOwotIAotICAgIHB1YmxpYyBET00yU0FYKE5vZGUgcm9vdCkgewotCV9kb20gPSAoRG9jdW1lbnQpcm9vdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgQ29udGVudEhhbmRsZXIgZ2V0Q29udGVudEhhbmRsZXIoKSB7IAotCXJldHVybiBfY29udGVudEhkbHI7Ci0gICAgfQotICAgIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKSB7IAotCXJldHVybiBudWxsOwotICAgIH0KLSAgICBwdWJsaWMgRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpIHsKLQlyZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sCi0JU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAgewotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgbmFtZSwgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIAotCVNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiAKLSAgICB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcGFyc2UoSW5wdXRTb3VyY2UgdW51c2VkKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNBWEV4Y2VwdGlvbiB7Ci0gICAgICAgIE5vZGUgY3Vyck5vZGUgPSBfZG9tOwotICAgICAgICBwYXJzZShjdXJyTm9kZSk7Ci0gICAgfQotCi0gICAgcHJpdmF0ZSB2b2lkIHBhcnNlKE5vZGUgY3Vyck5vZGUpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKLSAgICAgICAgTm9kZSBmaXJzdCA9IG51bGw7Ci0gCWlmIChjdXJyTm9kZSA9PSBudWxsICkgcmV0dXJuOwotCi0gICAgICAgIHN3aXRjaCAoY3Vyck5vZGUuZ2V0Tm9kZVR5cGUoKSkgewotICAgICAgICAgICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFIDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOgotICAgICAgICAgICAgICAgICAgICBfY29udGVudEhkbHIuc2V0RG9jdW1lbnRMb2NhdG9yKHRoaXMpOwotICAgICAgICAgICAgICAgICAgICBfY29udGVudEhkbHIuc3RhcnREb2N1bWVudCgpOwotICAgICAgICAgICAgICAgICAgICBOb2RlIG5leHQgPSBjdXJyTm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlICggbmV4dCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2UobmV4dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIF9jb250ZW50SGRsci5lbmREb2N1bWVudCgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgOgotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOgotICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVzSW1wbCBhdHRyTGlzdCA9IG5ldyBBdHRyaWJ1dGVzSW1wbCgpOwotICAgICAgICAgICAgICAgICAgICBOYW1lZE5vZGVNYXAgbWFwID0gY3Vyck5vZGUuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKysgKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgYXR0ck5vZGUgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBhdHRyTm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckxpc3QuYWRkQXR0cmlidXRlKGF0dHJOb2RlLmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJOb2RlLmdldExvY2FsTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJOb2RlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Tm9kZVR5cGVGcm9tQ29kZShjb2RlKSwgIC8vIG11c3QgYmUgYmV0dGVyIHdheQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJOb2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBfY29udGVudEhkbHIuc3RhcnRFbGVtZW50KGN1cnJOb2RlLmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgY3Vyck5vZGUuZ2V0TG9jYWxOYW1lKCksIGN1cnJOb2RlLmdldE5vZGVOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICBhdHRyTGlzdCk7Ci0gICAgICAgICAgICAgICAgICAgIG5leHQgPSBjdXJyTm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICAgICAgICAgIHdoaWxlICggbmV4dCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2UobmV4dCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5nZXROZXh0U2libGluZygpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIF9jb250ZW50SGRsci5lbmRFbGVtZW50KGN1cnJOb2RlLmdldE5hbWVzcGFjZVVSSSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgY3Vyck5vZGUuZ2V0TG9jYWxOYW1lKCksIGN1cnJOb2RlLmdldE5vZGVOYW1lKCkpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIC8vRW50aXR5IGVkZWNsID0gKEVudGl0eSljdXJyTm9kZTsKLSAgICAgICAgICAgICAgICAgICAgLy9TdHJpbmcgbmFtZSA9IGVkZWNsLmdldE5vdGF0aW9uTmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAvL2lmICggbmFtZSAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAvLyAgIF9jb250ZW50SGRsci51bnBhcnNlZEVudGl0eURlY2woY3Vyck5vZGUuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgLy8gICAgICBlZGVjbC5nZXRQdWJsaWNJZCgpLCBlZGVjbC5nZXRTeXN0ZW1JZCgpLCBuYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgLy99Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIC8vTm90YXRpb24gbmRlY2wgPSAoTm90YXRpb24pY3Vyck5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIC8vX2NvbnRlbnRIZGxyLm5vdGF0aW9uRGVjbChjdXJyTm9kZS5nZXROb2RlTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgLy8gICBuZGVjbC5nZXRQdWJsaWNJZCgpLCBuZGVjbC5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIF9jb250ZW50SGRsci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oY3Vyck5vZGUuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJOb2RlLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBkYXRhID0gY3Vyck5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGRhdGEubGVuZ3RoKCk7Ci0gICAgICAgICAgICAgICAgICAgIGNoYXJbXSBhcnJheSA9IG5ldyBjaGFyW2xlbmd0aF07Ci0gICAgICAgICAgICAgICAgICAgIGRhdGEuZ2V0Q2hhcnMoMCwgbGVuZ3RoLCBhcnJheSwgMCk7Ci0gICAgICAgICAgICAgICAgICAgIF9jb250ZW50SGRsci5jaGFyYWN0ZXJzKGFycmF5LCAwLCBsZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBwYXJzZShTdHJpbmcgc3lzSWQpIHRocm93cyBJT0V4Y2VwdGlvbiwgU0FYRXhjZXB0aW9uIHsKLQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQuIik7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpIHRocm93cyAKLQlOdWxsUG9pbnRlckV4Y2VwdGlvbiAKLSAgICB7Ci0JaWYgKGhhbmRsZXIgPT0gbnVsbCApIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotCV9jb250ZW50SGRsciA9IGhhbmRsZXI7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldERUREhhbmRsZXIoRFRESGFuZGxlciBoYW5kbGVyKSB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gewotCWlmIChoYW5kbGVyID09IG51bGwgKSAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldEVudGl0eVJlc29sdmVyKEVudGl0eVJlc29sdmVyIHJlc29sdmVyKSB0aHJvd3MgCi0JTnVsbFBvaW50ZXJFeGNlcHRpb24gCi0gICAgewotCWlmIChyZXNvbHZlciA9PSBudWxsICkgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotICAgIH0KLSAgICBwdWJsaWMgRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKSB7Ci0JcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIAotCU51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAgewotCWlmIChoYW5kbGVyID09IG51bGwgKSAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7Ci0gICAgfQotICAgIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHRocm93cwotCVNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24sIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7Ci0gICAgfQotICAgIHB1YmxpYyBPYmplY3QgZ2V0UHJvcGVydHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uLAotCVNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgIHsKLQlyZXR1cm4gbnVsbDsKLSAgICB9Ci0KLSAgICAvLyBMb2NhdG9yIG1ldGhvZHMKLSAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpIHsgcmV0dXJuIDA7IH0KLSAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7IHJldHVybiAwOyB9Ci0gICAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpIHsgcmV0dXJuIG51bGw7IH0KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkKCkgeyByZXR1cm4gbnVsbDsgfQotCi0KLSAgICAvLyBwcml2YXRlIAotICAgIHByaXZhdGUgU3RyaW5nIGdldE5vZGVUeXBlRnJvbUNvZGUoc2hvcnQgY29kZSkgewotCVN0cmluZyByZXR2YWwgPSBudWxsOwotCXN3aXRjaCAoY29kZSkgewotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6IAotCQkgICAgcmV0dmFsID0gIkFUVFJJQlVURV9OT0RFIjsgYnJlYWs7IAotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotCQkgICAgcmV0dmFsID0gIkNEQVRBX1NFQ1RJT05fTk9ERSI7IGJyZWFrOyAKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLQkJICAgIHJldHZhbCA9ICJDT01NRU5UX05PREUiOyBicmVhazsgCi0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotCQkgICAgcmV0dmFsID0gIkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUiOyBicmVhazsgCi0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOgotCQkgICAgcmV0dmFsID0gIkRPQ1VNRU5UX05PREUiOyBicmVhazsgCi0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX1RZUEVfTk9ERSA6Ci0JCSAgICByZXR2YWwgPSAiRE9DVU1FTlRfVFlQRV9OT0RFIjsgYnJlYWs7IAotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOgotCQkgICAgcmV0dmFsID0gIkVMRU1FTlRfTk9ERSI7IGJyZWFrOyAKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRU5USVRZX05PREUgOgotCQkgICAgcmV0dmFsID0gIkVOVElUWV9OT0RFIjsgYnJlYWs7IAotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotCQkgICAgcmV0dmFsID0gIkVOVElUWV9SRUZFUkVOQ0VfTk9ERSI7IGJyZWFrOyAKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuTk9UQVRJT05fTk9ERSA6Ci0JCSAgICByZXR2YWwgPSAiTk9UQVRJT05fTk9ERSI7IGJyZWFrOyAKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLQkJICAgIHJldHZhbCA9ICJQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUiOyBicmVhazsgCi0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLlRFWFRfTk9ERToKLQkJICAgIHJldHZhbCA9ICJURVhUX05PREUiOyBicmVhazsgCi0gICAgICAgIH0KLQlyZXR1cm4gcmV0dmFsOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvT3V0cHV0U2V0dGluZ3MuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvT3V0cHV0U2V0dGluZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2E2NTgwYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L091dHB1dFNldHRpbmdzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0OwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuKjsKLQotaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgT3V0cHV0U2V0dGluZ3MgewotICAgIAotICAgIHByaXZhdGUgU3RyaW5nIF9jZGF0YV9zZWN0aW9uX2VsZW1lbnRzID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyBfZG9jdHlwZV9wdWJsaWMgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9lbmNvZGluZyA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX2luZGVudCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX21lZGlhX3R5cGUgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9tZXRob2QgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF9vbWl0X3htbF9kZWNsYXJhdGlvbiA9IG51bGw7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX3N0YW5kYWxvbmUgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nIF92ZXJzaW9uID0gbnVsbDsKLQotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldFByb3BlcnRpZXMoKSB7Ci0JUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKLQlyZXR1cm4ocHJvcGVydGllcyk7Ci0gICAgfQotCi0gICAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1NBWDJET00uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvU0FYMkRPTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4MmJjZDk1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvU0FYMkRPTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjM4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIgCi0gKgotICovCi0KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uQXR0cjsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLQotcHVibGljIGNsYXNzIFNBWDJET00gaW1wbGVtZW50cyBDb250ZW50SGFuZGxlciB7Ci0KLSAgICBwcml2YXRlIERvY3VtZW50IF9kb2N1bWVudCA9IG51bGw7Ci0gICAgcHJpdmF0ZSBEb2N1bWVudEJ1aWxkZXIgX2J1aWxkZXIgPSBudWxsOwotICAgIHByaXZhdGUgU3RhY2sgX25vZGVTdGsgPSBudWxsOwotIAotICAgIHB1YmxpYyBTQVgyRE9NKCkgdGhyb3dzIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCURvY3VtZW50QnVpbGRlckZhY3RvcnkgZmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQlfYnVpbGRlciA9IGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0JX25vZGVTdGsgPSBuZXcgU3RhY2soKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgTm9kZSBnZXRET00oKSB7Ci0JcmV0dXJuIF9kb2N1bWVudDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0JVGV4dCB0ZXh0ID0gX2RvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpKTsKLQlOb2RlIGxhc3QgPSAoTm9kZSlfbm9kZVN0ay5wZWVrKCk7Ci0JbGFzdC5hcHBlbmRDaGlsZCh0ZXh0KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgewotCV9kb2N1bWVudCA9IF9idWlsZGVyLm5ld0RvY3VtZW50KCk7Ci0JRWxlbWVudCByb290ID0gKEVsZW1lbnQpX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInJvb3QiKTsKLQlfZG9jdW1lbnQuYXBwZW5kQ2hpbGQocm9vdCk7Ci0JX25vZGVTdGsucHVzaChyb290KTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHsKLQkvL3ByaW50RE9NKCk7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSwKLQlBdHRyaWJ1dGVzIGF0dHJzICkgCi0gICAgewotCS8vIGNyZWF0ZSBuZXcgZWxlbWVudAotCUVsZW1lbnQgdG1wID0gKEVsZW1lbnQpX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2UsIHFOYW1lKTsKLQlpbnQgbmF0dHJzID0gYXR0cnMuZ2V0TGVuZ3RoKCk7Ci0JZm9yIChpbnQgaT0wOyBpPG5hdHRyczsgaSsrICkgewotCSAgICBTdHJpbmcgbmFtZXNwYWNldXJpID0gYXR0cnMuZ2V0VVJJKGkpOwotCSAgICBTdHJpbmcgdmFsdWUgPSBhdHRycy5nZXRWYWx1ZShpKTsKLQkgICAgU3RyaW5nIHFuYW1lID0gYXR0cnMuZ2V0UU5hbWUoaSk7Ci0JICAgIGlmICgobmFtZXNwYWNldXJpID09IG51bGwpIHx8IChuYW1lc3BhY2V1cmkuZXF1YWxzKCIiKSkpCi0JCXRtcC5zZXRBdHRyaWJ1dGUocW5hbWUsIHZhbHVlKTsKLQkgICAgZWxzZQotCQl0bXAuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNldXJpLCBxbmFtZSwgdmFsdWUpOwotCX0KLQkvLyBhcHBlbmQgdGhpcyBuZXcgbm9kZSBvbnRvIGN1cnJlbnQgc3RhY2sgbm9kZQotCU5vZGUgbGFzdCA9IChOb2RlKV9ub2RlU3RrLnBlZWsoKTsKLQlsYXN0LmFwcGVuZENoaWxkKHRtcCk7Ci0JLy8gcHVzaCB0aGlzIG5vZGUgb250byBzdGFjawotCV9ub2RlU3RrLnB1c2godG1wKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkgewotCU5vZGUgbGFzdEFjdGl2ZSA9IChOb2RlKV9ub2RlU3RrLnBvcCgpOyAgCi0gICAgfQotCi0KLSAgICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKSB7Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgewotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgewotICAgIH0KLQotCi0gICAgLy8gZm9yIGRlYnVnZ2luZyAtIHdpbGwgYmUgcmVtb3ZlZAotICAgIHByaXZhdGUgdm9pZCBwcmludERPTSgpIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTQVgyRE9NLmphdmE6UHJpbnRpbmcgRE9NLi4uIik7Ci0gICAgICAgIE5vZGUgY3Vyck5vZGUgPSBfZG9jdW1lbnQ7Ci0gICAgICAgIHdoaWxlIChjdXJyTm9kZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICAvLyBzdGFydCBvZiBub2RlIHByb2Nlc3NpbmcKLSAgICAgICAgICAgIHN3aXRjaCAoY3Vyck5vZGUuZ2V0Tm9kZVR5cGUoKSkgewotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9UWVBFX05PREUgOgotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFTEVNVCBOT0RFICIgKyBjdXJyTm9kZS5nZXRMb2NhbE5hbWUoKSArIjoiKTsKLQkJICAgICBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXAgbWFwID0gY3Vyck5vZGUuZ2V0QXR0cmlidXRlcygpOwotICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbWFwLmdldExlbmd0aCgpOwotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKysgKXsKLSAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgYXR0ck5vZGUgPSBtYXAuaXRlbShpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvZGUgPSBhdHRyTm9kZS5nZXROb2RlVHlwZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdGF0dHI6IithdHRyTm9kZS5nZXROYW1lc3BhY2VVUkkoKSsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCIgKyBhdHRyTm9kZS5nZXRMb2NhbE5hbWUoKSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwiICsgYXR0ck5vZGUuZ2V0Tm9kZU5hbWUoKSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIj0iICsgYXR0ck5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5FTlRJVFlfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIG9yZy53M2MuZG9tLkVudGl0eSBlZGVjbCA9IChvcmcudzNjLmRvbS5FbnRpdHkpY3Vyck5vZGU7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZWRlY2wuZ2V0Tm90YXRpb25OYW1lKCk7Ci0gICAgICAgICAgICAgICAgICAgIGlmICggbmFtZSAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFTlQgTk9ERTogIitjdXJyTm9kZS5nZXROb2RlTmFtZSgpKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgIisgZWRlY2wuZ2V0U3lzdGVtSWQoKSsgIiwiICsgbmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5OT1RBVElPTl9OT0RFIDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGF0YSA9IGN1cnJOb2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRFWFQgTk9ERToiICsgZGF0YSk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBtb3ZlIHRvIGZpcnN0IGNoaWxkCi0gICAgICAgICAgICBOb2RlIG5leHQgPSBjdXJyTm9kZS5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgY3Vyck5vZGUgPSBuZXh0OwotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAvLyBubyBjaGlsZCBub2Rlcywgd2FsayB0aGUgdHJlZQotICAgICAgICAgICAgd2hpbGUgKGN1cnJOb2RlICE9IG51bGwpIHsKLSAgICAgICAgICAgICAgICBzd2l0Y2ggKGN1cnJOb2RlLmdldE5vZGVUeXBlKCkpIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBuZXh0ID0gY3Vyck5vZGUuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsICkgewotICAgICAgICAgICAgICAgICAgICBjdXJyTm9kZSA9IG5leHQ7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAvLyBtb3ZlIHVwIGEgbGV2ZWwKLSAgICAgICAgICAgICAgICBjdXJyTm9kZSA9IGN1cnJOb2RlLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RlbXBsYXRlc0hhbmRsZXJJbXBsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RlbXBsYXRlc0hhbmRsZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI5NzAyYWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheC9UZW1wbGF0ZXNIYW5kbGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTc4ICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci0KLS8qKgotICogSW1wbGVtZW50YXRpb24gb2YgYSBKQVhQMS4xIFRlbXBsYXRlc0hhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIFRlbXBsYXRlc0hhbmRsZXJJbXBsIGV4dGVuZHMgUGFyc2VyIGltcGxlbWVudHMgVGVtcGxhdGVzSGFuZGxlciB7Ci0KLSAgICBwcml2YXRlIFN0cmluZyBfZGVmYXVsdFRyYW5zbGV0TmFtZSA9ICJHcmVnb3JTYW1zYSI7Ci0gICAgcHJpdmF0ZSBTdHJpbmcgX3N5c3RlbUlkOwotCi0gICAgLyoqCi0gICAgICogRGVmYXVsdCBjb25zdHJ1Y3RvcgotICAgICAqLwotICAgIHByb3RlY3RlZCBUZW1wbGF0ZXNIYW5kbGVySW1wbCgpIHsKLQlzdXBlcihudWxsKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBpbml0aWFsaXphdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGluaXQoKSB7Ci0JLy8gQ3JlYXRlIGFuZCBpbml0aWFsaXplIGEgc3R5bGVzaGVldCBjb21waWxlcgotCWZpbmFsIFhTTFRDIHhzbHRjID0gbmV3IFhTTFRDKCk7Ci0Jc3VwZXIuc2V0WFNMVEMoeHNsdGMpOwotCXhzbHRjLnNldFBhcnNlcih0aGlzKTsKLQl4c2x0Yy5pbml0KCk7Ci0JeHNsdGMuc2V0T3V0cHV0VHlwZShYU0xUQy5CWVRFQVJSQVlfT1VUUFVUKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRlbXBsYXRlc0hhbmRsZXIuZ2V0U3lzdGVtSWQoKQotICAgICAqIEdldCB0aGUgYmFzZSBJRCAoVVJJIG9yIHN5c3RlbSBJRCkgZnJvbSB3aGVyZSByZWxhdGl2ZSBVUkxzIHdpbGwgYmUKLSAgICAgKiByZXNvbHZlZC4KLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW1JRCB0aGF0IHdhcyBzZXQgd2l0aCBzZXRTeXN0ZW1JZChTdHJpbmcgaWQpCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpIHsKLQlyZXR1cm4gX3N5c3RlbUlkOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVGVtcGxhdGVzSGFuZGxlci5zZXRTeXN0ZW1JZCgpCi0gICAgICogR2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlIFVSTHMgd2lsbCBiZQotICAgICAqIHJlc29sdmVkLgotICAgICAqIEBwYXJhbSBpZCBCYXNlIFVSSSBmb3IgdGhpcyBzdHlsZXNoZWV0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIGlkKSB7Ci0JX3N5c3RlbUlkID0gaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyLmdldFRlbXBsYXRlcygpCi0gICAgICogV2hlbiBhIFRlbXBsYXRlc0hhbmRsZXIgb2JqZWN0IGlzIHVzZWQgYXMgYSBDb250ZW50SGFuZGxlciBvcgotICAgICAqIERvY3VtZW50SGFuZGxlciBmb3IgdGhlIHBhcnNpbmcgb2YgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCBpdAotICAgICAqIGNyZWF0ZXMgYSBUZW1wbGF0ZXMgb2JqZWN0LCB3aGljaCB0aGUgY2FsbGVyIGNhbiBnZXQgb25jZSB0aGUgU0FYCi0gICAgICogZXZlbnRzIGhhdmUgYmVlbiBjb21wbGV0ZWQuCi0gICAgICogQHJldHVybiBUaGUgVGVtcGxhdGVzIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIGR1cmluZyB0aGUgU0FYIGV2ZW50Ci0gICAgICogICAgICAgICBwcm9jZXNzLCBvciBudWxsIGlmIG5vIFRlbXBsYXRlcyBvYmplY3QgaGFzIGJlZW4gY3JlYXRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVGVtcGxhdGVzIGdldFRlbXBsYXRlcygpIHsKLQotCXRyeSB7Ci0JICAgIC8vIENyZWF0ZSBhIHBsYWNlaG9sZGVyIGZvciB0aGUgdHJhbnNsZXQgYnl0ZWNvZGVzCi0JICAgIGJ5dGVbXVtdIGJ5dGVjb2RlcyA9IG51bGw7Ci0KLQkgICAgZmluYWwgWFNMVEMgeHNsdGMgPSBnZXRYU0xUQygpOwotCi0JICAgIC8vIFNldCB0aGUgdHJhbnNsZXQgY2xhc3MgbmFtZSBpZiBub3QgYWxyZWFkeSBzZXQKLQkgICAgU3RyaW5nIHRyYW5zbGV0TmFtZSA9IF9kZWZhdWx0VHJhbnNsZXROYW1lOwotCSAgICBpZiAoX3N5c3RlbUlkICE9IG51bGwpIHRyYW5zbGV0TmFtZSA9IFV0aWwuYmFzZU5hbWUoX3N5c3RlbUlkKTsKLQkgICAgeHNsdGMuc2V0Q2xhc3NOYW1lKHRyYW5zbGV0TmFtZSk7Ci0KLQkgICAgU3R5bGVzaGVldCBzdHlsZXNoZWV0ID0gbnVsbDsKLQkgICAgU3ludGF4VHJlZU5vZGUgcm9vdCA9IGdldERvY3VtZW50Um9vdCgpOwotCi0JICAgIC8vIENvbXBpbGUgdGhlIHRyYW5zbGV0IC0gdGhpcyBpcyB3aGVyZSB0aGUgd29yayBpcyBkb25lIQotCSAgICBpZiAoKCFlcnJvcnNGb3VuZCgpKSAmJiAocm9vdCAhPSBudWxsKSkgewotCQkvLyBDcmVhdGUgYSBTdHlsZXNoZWV0IGVsZW1lbnQgZnJvbSB0aGUgcm9vdCBub2RlCi0JCXN0eWxlc2hlZXQgPSBtYWtlU3R5bGVzaGVldChyb290KTsKLQkJc3R5bGVzaGVldC5zZXRTeXN0ZW1JZChfc3lzdGVtSWQpOwotCQlzdHlsZXNoZWV0LnNldFBhcmVudFN0eWxlc2hlZXQobnVsbCk7Ci0JCXNldEN1cnJlbnRTdHlsZXNoZWV0KHN0eWxlc2hlZXQpOwotCQkvLyBDcmVhdGUgQVNUIHVuZGVyIHRoZSBTdHlsZXNoZWV0IGVsZW1lbnQgKHBhcnNlICYgdHlwZS1jaGVjaykKLQkJY3JlYXRlQVNUKHN0eWxlc2hlZXQpOwotCSAgICB9Ci0KLQkgICAgLy8gR2VuZXJhdGUgdGhlIGJ5dGVjb2RlcyBhbmQgb3V0cHV0IHRoZSB0cmFuc2xldCBjbGFzcyhlcykKLQkgICAgaWYgKCghZXJyb3JzRm91bmQoKSkgJiYgKHN0eWxlc2hlZXQgIT0gbnVsbCkpIHsKLQkJc3R5bGVzaGVldC5zZXRNdWx0aURvY3VtZW50KHhzbHRjLmlzTXVsdGlEb2N1bWVudCgpKTsKLQkJc3R5bGVzaGVldC50cmFuc2xhdGUoKTsKLQkgICAgfQotCi0JICAgIHhzbHRjLnByaW50V2FybmluZ3MoKTsKLQotCSAgICAvLyBDaGVjayB0aGF0IHRoZSB0cmFuc2Zvcm1hdGlvbiB3ZW50IHdlbGwgYmVmb3JlIHJldHVybmluZwotCSAgICBpZiAoYnl0ZWNvZGVzID09IG51bGwpIHsKLQkJeHNsdGMucHJpbnRFcnJvcnMoKTsKLQkJcmV0dXJuIG51bGw7Ci0JICAgIH0KLQotCSAgICByZXR1cm4obmV3IFRlbXBsYXRlc0ltcGwoYnl0ZWNvZGVzLCB0cmFuc2xldE5hbWUpKTsKLQl9Ci0JY2F0Y2ggKENvbXBpbGVyRXhjZXB0aW9uIGUpIHsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLX0KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RlbXBsYXRlc0ltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVGVtcGxhdGVzSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NzQxMmMwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVGVtcGxhdGVzSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIxICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlcgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheDsKLQotaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLio7Ci0KLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLQotcHVibGljIGZpbmFsIGNsYXNzIFRlbXBsYXRlc0ltcGwgaW1wbGVtZW50cyBUZW1wbGF0ZXMsIFNlcmlhbGl6YWJsZSB7Ci0gICAgCi0gICAgLy8gQ29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIG1haW4gdHJhbnNsZXQgY2xhc3MKLSAgICBwcml2YXRlIFN0cmluZyAgIF90cmFuc2xldE5hbWUgPSBudWxsOwotCi0gICAgLy8gQ29udGFpbnMgdGhlIGFjdHVhbCBjbGFzcyBkZWZpbml0aW9uIGZvciB0aGUgdHJhbnNsZXQgY2xhc3MgYW5kCi0gICAgLy8gYW55IGF1eGlsaWFyeSBjbGFzc2VzIChyZXByZXNlbnRpbmcgbm9kZSBzb3J0IHJlY29yZHMsIHByZWRpY2F0ZXMsIGV0Yy4pCi0gICAgcHJpdmF0ZSBieXRlW11bXSBfYnl0ZWNvZGVzID0gbnVsbDsKLQotICAgIC8vIFRoaXMgZXJyb3IgY291bGQgb2NjdXIgd2hlbiBhIGNvbXBpbGF0aW9uIGluc2lkZSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5Ci0gICAgLy8gZmFpbGVkIGFuZCB3aGVuIGEgdGVtcGxhdGUgaGFzIGJlZW4gbG9hZGVkIGZyb20gc3RhYmxlIHN0b3JhZ2UuCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFRSQU5TTEVUX0VSUl9NU0cgPQotCSJUaGlzIHRlbXBsYXRlIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCB0cmFuc2xldCBjbGFzcyBkZWZpbml0aW9uLiI7Ci0gICAgCi0gICAgLy8gT3VyIG93biBwcml2YXRlIGNsYXNzIGxvYWRlciAtIGJ1aWxkcyBDbGFzcyBkZWZpbml0aW9ucyBmcm9tIGJ5dGVjb2RlcwotICAgIHByaXZhdGUgY2xhc3MgVHJhbnNsZXRDbGFzc0xvYWRlciBleHRlbmRzIENsYXNzTG9hZGVyIHsKLQlwdWJsaWMgQ2xhc3MgZGVmaW5lQ2xhc3MoYnl0ZVtdIGIpIHsKLQkgICAgcmV0dXJuIHN1cGVyLmRlZmluZUNsYXNzKG51bGwsIGIsIDAsIGIubGVuZ3RoKTsKLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGhlIG9ubHkgd2F5IHRvIGNyZWF0ZSBhbiBYU0xUQyBlbXBsYXRlIG9iamVjdAotICAgICAqIFRoZSBieXRlY29kZXMgZm9yIHRoZSB0cmFuc2xldCBhbmQgYXV4aWxpYXJ5IGNsYXNzZXMsIHBsdXMgdGhlIG5hbWUgb2YKLSAgICAgKiB0aGUgbWFpbiB0cmFuc2xldCBjbGFzcywgbXVzdCBiZSBzdXBwbGllZAotICAgICAqLwotICAgIHByb3RlY3RlZCBUZW1wbGF0ZXNJbXBsKGJ5dGVbXVtdIGJ5dGVjb2RlcywgU3RyaW5nIHRyYW5zbGV0TmFtZSkgewotCV9ieXRlY29kZXMgPSBieXRlY29kZXM7Ci0JX3RyYW5zbGV0TmFtZSA9IHRyYW5zbGV0TmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgVHJhbnNmb3JtZXJGYWN0b3J5IG11c3QgcGFzcyB1cyB0aGUgdHJhbnNsZXQgYnl0ZWNvZGVzIHVzaW5nIHRoaXMKLSAgICAgKiBtZXRob2QgYmVmb3JlIHdlIGNhbiBjcmVhdGUgYW55IHRyYW5zbGV0IGluc3RhbmNlcwotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFRyYW5zbGV0Qnl0ZWNvZGVzKGJ5dGVbXVtdIGJ5dGVjb2RlcykgewotCV9ieXRlY29kZXMgPSBieXRlY29kZXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHJhbnNsZXQgYnl0ZWNvZGVzIHN0b3JlZCBpbiB0aGlzIHRlbXBsYXRlCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJ5dGVbXVtdIGdldFRyYW5zbGV0Qnl0ZWNvZGVzKCkgewotCXJldHVybihfYnl0ZWNvZGVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgVHJhbnNmb3JtZXJGYWN0b3J5IHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIHRvIHNldCB0aGUgdHJhbnNsZXQgbmFtZQotICAgICAqLwotICAgIHByb3RlY3RlZCB2b2lkIHNldFRyYW5zbGV0TmFtZShTdHJpbmcgbmFtZSkgewotCV90cmFuc2xldE5hbWUgPSBuYW1lOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1haW4gdHJhbnNsZXQgY2xhc3Mgc3RvcmVkIGluIHRoaXMgdGVtcGxhdGUKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldFRyYW5zbGV0TmFtZSgpIHsKLQlyZXR1cm4gX3RyYW5zbGV0TmFtZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBEZWZpbmVzIHRoZSB0cmFuc2xldCBjbGFzcyBhbmQgYXV4aWxpYXJ5IGNsYXNzZXMuCi0gICAgICogUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgQ2xhc3Mgb2JqZWN0IHRoYXQgZGVmaW5lcyB0aGUgbWFpbiBjbGFzcwotICAgICAqLwotICAgIHByaXZhdGUgQ2xhc3MgZGVmaW5lVHJhbnNsZXRDbGFzc2VzKCkgewotCWlmIChfYnl0ZWNvZGVzID09IG51bGwpIHJldHVybiBudWxsOwotCi0JVHJhbnNsZXRDbGFzc0xvYWRlciBsb2FkZXIgPSBuZXcgVHJhbnNsZXRDbGFzc0xvYWRlcigpOwotCi0JdHJ5IHsKLQkgICAgQ2xhc3MgdHJhbnNsZXRDbGFzcyA9IG51bGw7Ci0JICAgIGZpbmFsIGludCBjbGFzc0NvdW50ID0gX2J5dGVjb2Rlcy5sZW5ndGg7Ci0JICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2xhc3NDb3VudDsgaSsrKSB7Ci0JCUNsYXNzIGNsYXp6ID0gbG9hZGVyLmRlZmluZUNsYXNzKF9ieXRlY29kZXNbaV0pOwotCQlpZiAoY2xhenouZ2V0TmFtZSgpLmVxdWFscyhfdHJhbnNsZXROYW1lKSkKLQkJICAgIHRyYW5zbGV0Q2xhc3MgPSBjbGF6ejsKLQkgICAgfQotCSAgICByZXR1cm4gdHJhbnNsZXRDbGFzczsgLy8gQ291bGQgc3RpbGwgYmUgJ251bGwnCi0JfQotCWNhdGNoIChDbGFzc0Zvcm1hdEVycm9yIGUpIHsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyBhbiBpbnN0YW5jZSBvZiB0aGUgdHJhbnNsZXQgY2xhc3MgdGhhdCBpcwotICAgICAqIHdyYXBwZWQgaW5zaWRlIHRoaXMgVGVtcGxhdGUuIFRoZSB0cmFuc2xldCBpbnN0YW5jZSB3aWxsIGxhdGVyCi0gICAgICogYmUgd3JhcHBlZCBpbnNpZGUgYSBUcmFuc2Zvcm1lciBvYmplY3QuCi0gICAgICovCi0gICAgcHJpdmF0ZSBUcmFuc2xldCBnZXRUcmFuc2xldEluc3RhbmNlKCkgewotCWlmIChfdHJhbnNsZXROYW1lID09IG51bGwpIHJldHVybiBudWxsOwotCi0JLy8gRmlyc3QgYXNzdW1lIHRoYXQgdGhlIEpWTSBhbHJlYWR5IGhhZCB0aGUgY2xhc3MgZGVmaW5pdGlvbgotCXRyeSB7Ci0JICAgIENsYXNzIHRyYW5zbGV0Q2xhc3MgPSBDbGFzcy5mb3JOYW1lKF90cmFuc2xldE5hbWUpOwotCSAgICByZXR1cm4oKFRyYW5zbGV0KXRyYW5zbGV0Q2xhc3MubmV3SW5zdGFuY2UoKSk7Ci0JfQotCS8vIElnbm9yZSB0aGVzZSBmb3Igbm93LCB0cnkgdG8gZGVmaW5lIHRyYW5zbGV0IGNsYXNzIGFnYWluCi0JY2F0Y2ggKExpbmthZ2VFcnJvciBlKSB7IH0KLQljYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlKSB7IH0KLQljYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7IH0KLQljYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7IH0KLQotCS8vIENyZWF0ZSB0aGUgY2xhc3MgZGVmaW5pdGlvbiBmcm9tIHRoZSBieXRlY29kZXMgaWYgZmFpbGVkCi0JdHJ5IHsKLQkgICAgQ2xhc3MgdHJhbnNsZXRDbGFzcyA9IGRlZmluZVRyYW5zbGV0Q2xhc3NlcygpOwotCSAgICBpZiAodHJhbnNsZXRDbGFzcyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQkgICAgcmV0dXJuKChUcmFuc2xldCl0cmFuc2xldENsYXNzLm5ld0luc3RhbmNlKCkpOwotCX0KLQljYXRjaCAoTGlua2FnZUVycm9yIGUpIHsgcmV0dXJuKG51bGwpOyB9Ci0JY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeyByZXR1cm4obnVsbCk7IH0KLQljYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7IHJldHVybihudWxsKTsgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRlbXBsYXRlcy5uZXdUcmFuc2Zvcm1lcigpCi0gICAgICoKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpCi0JdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0JVHJhbnNsZXQgdHJhbnNsZXQgPSBnZXRUcmFuc2xldEluc3RhbmNlKCk7Ci0JaWYgKHRyYW5zbGV0ID09IG51bGwpCi0JICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oVFJBTlNMRVRfRVJSX01TRyk7Ci0JVHJhbnNmb3JtZXJJbXBsIHRyYW5zZm9ybWVyID0gbmV3IFRyYW5zZm9ybWVySW1wbCh0cmFuc2xldCk7Ci0gICAgICAgIHJldHVybih0cmFuc2Zvcm1lcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBKQVhQJ3MgVGVtcGxhdGVzLmdldE91dHB1dFByb3BlcnRpZXMoKQotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKSB7IAotCS8vIFdlIG5lZWQgdG8gaW5zdGFuY2lhdGUgYSB0cmFuc2xldCB0byBnZXQgdGhlIG91dHB1dCBzZXR0aW5ncywgc28KLQkvLyB3ZSBtaWdodCBhcyB3ZWxsIGp1c3QgaW5zdGFuY2lhdGUgYSBUcmFuc2Zvcm1lciBhbmQgdXNlIGl0cwotCS8vIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kCi0JdHJ5IHsKLQkgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSBuZXdUcmFuc2Zvcm1lcigpOwotCSAgICByZXR1cm4gdHJhbnNmb3JtZXIuZ2V0T3V0cHV0UHJvcGVydGllcygpOwotCX0KLQljYXRjaCAoVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGUpIHsKLQkgICAgcmV0dXJuIG51bGw7Ci0JfQotICAgIH0KLQotfQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RyQVhGaWx0ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVHJBWEZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNzIxMjA4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVHJBWEZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODEgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBHLiBUb2RkIE1pbGxlciAKLSAqCi0gKi8KLQotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheDsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTEZpbHRlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTEZpbHRlckltcGw7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLQotLyoqCi0gKiBza2VsZXRvbiBleHRlbnNpb24gb2YgWE1MRmlsdGVySW1wbCBmb3Igbm93LiAgCi0gKi8KLXB1YmxpYyBjbGFzcyBUckFYRmlsdGVyIGV4dGVuZHMgWE1MRmlsdGVySW1wbCB7Ci0gICAgcHVibGljIFRyQVhGaWx0ZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykgIHRocm93cyAKLQlUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICB7Ci0JLyogbm90aGluZyB5ZXQgKi8gCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheC9UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDM2ZTM1Mi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDYzNCArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIEcuIFRvZGQgTWlsbGVyIAotICogQGF1dGhvciBNb3J0ZW4gSm9yZ2Vuc2VuCi0gKgotICovCi0KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOwotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4Lio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS4qOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MRmlsdGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlhTTFRDOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuU291cmNlTG9hZGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuQ29tcGlsZXJFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsLlV0aWw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci0KLS8qKgotICogSW1wbGVtZW50YXRpb24gb2YgYSBKQVhQMS4xIFRyYW5zZm9ybWVyRmFjdG9yeSBmb3IgVHJhbnNsZXRzLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbAotICAgIGV4dGVuZHMgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudHMgU291cmNlTG9hZGVyIHsKLQotICAgIC8vIFRoaXMgY29uc3RhbnQgc2hvdWxkIGJlIHJlbW92ZWQgb25jZSBhbGwgYWJzdHJhY3QgbWV0aG9kcyBhcmUgaW1wbCdlZC4KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTllJID0gIk5vdCB5ZXQgaW1wbGVtZW50ZWQiOwotCi0gICAgLy8gVGhpcyBlcnJvciBsaXN0ZW5lciBpcyB1c2VkIG9ubHkgZm9yIHRoaXMgZmFjdG9yeSBhbmQgaXMgbm90IHBhc3NlZCB0bwotICAgIC8vIHRoZSBUZW1wbGF0ZXMgb3IgVHJhbnNmb3JtZXIgb2JqZWN0cyB0aGF0IHdlIGNyZWF0ZSEhIQotICAgIHByaXZhdGUgRXJyb3JMaXN0ZW5lciBfZXJyb3JMaXN0ZW5lciA9IG51bGw7IAotCi0gICAgLy8gVGhpcyBVUklSZXNvbHZlciBpcyBwYXNzZWQgdG8gYWxsIGNyZWF0ZWQgVGVtcGxhdGVzIGFuZCBUcmFuc2Zvcm1lcnMKLSAgICBwcml2YXRlIFVSSVJlc29sdmVyIF91cmlSZXNvbHZlciA9IG51bGw7Ci0KLSAgICAvLyBDYWNoZSBmb3IgdGhlIG5ld1RyYW5zZm9ybWVyKCkgbWV0aG9kIC0gc2VlIG1ldGhvZCBmb3IgZGV0YWlscwotICAgIHByaXZhdGUgU3RyaW5nICAgICAgX2RlZmF1bHRUcmFuc2xldE5hbWUgPSAiR3JlZ29yU2Ftc2EiOwotICAgIHByaXZhdGUgVHJhbnNmb3JtZXIgX2NvcHlUcmFuc2Zvcm1lciA9IG51bGw7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPUFlfVFJBTlNMRVRfQ09ERSA9Ci0JIjx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm1cIj4iKwotCSI8eHNsOnRlbXBsYXRlIG1hdGNoPVwiL1wiPjx4c2w6Y29weS1vZiBzZWxlY3Q9XCIuXCIvPjwveHNsOnRlbXBsYXRlPiIrCi0JIjwveHNsOnN0eWxlc2hlZXQ+IjsKLQotICAgIC8vIEFsbCB1c2VkIGVycm9yIG1lc3NhZ2VzIHNob3VsZCBiZSBsaXN0ZWQgaGVyZQotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9MSVNURU5FUl9OVUxMID0KLQkiQXR0ZW1wdGluZyB0byBzZXQgRXJyb3JMaXN0ZW5lciBmb3IgVHJhbnNmb3JtZXJGYWN0b3J5IHRvIG51bGwiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBVTktOT1dOX1NPVVJDRV9FUlIgPQotCSJPbmx5IFN0cmVhbVNvdXJjZSBhbmQgU0FYU291cmNlIGFyZSBzdXBwb3J0ZWQgYnkgWFNMVEMiOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT19TT1VSQ0VfRVJSID0KLQkiU291cmNlIG9iamVjdCBwYXNzZWQgdG8gbmV3VGVtcGxhdGVzKCkgaGFzIG5vIGNvbnRlbnRzIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fQUNDRVNTX0VSUiA9Ci0JIkNhbm5vdCBhY2Nlc3MgZmlsZSBvciBVUkwgIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NUElMRV9FUlIgPQotCSJDb3VsZCBub3QgY29tcGlsZSBzdHlsZXNoZWV0IjsKLQotICAgIC8vIFRoaXMgSGFzaHRhYmxlIGlzIHVzZWQgdG8gc3RvcmUgcGFyYW1ldGVycyBmb3IgbG9jYXRpbmcKLSAgICAvLyA8P3htbC1zdHlsZXNoZWV0IC4uLj8+IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIGluIFhNTCBkb2N1bWVudHMuCi0gICAgcHJpdmF0ZSBIYXNodGFibGUgX3BpUGFyYW1zID0gbnVsbDsKLQotICAgIC8vIFRoZSBhYm92ZSBoYXNodGFibGUgc3RvcmVzIG9iamVjdHMgb2YgdGhpcyBjbGFzcyBvbmx5OgotICAgIHByaXZhdGUgY2xhc3MgUElQYXJhbVdyYXBwZXIgewotCXB1YmxpYyBTdHJpbmcgX21lZGlhID0gbnVsbDsKLQlwdWJsaWMgU3RyaW5nIF90aXRsZSA9IG51bGw7Ci0JcHVibGljIFN0cmluZyBfY2hhcnNldCA9IG51bGw7Ci0JCi0JcHVibGljIFBJUGFyYW1XcmFwcGVyKFN0cmluZyBtZWRpYSwgU3RyaW5nIHRpdGxlLCBTdHJpbmcgY2hhcnNldCkgewotCSAgICBfbWVkaWEgPSBtZWRpYTsKLQkgICAgX3RpdGxlID0gdGl0bGU7Ci0JICAgIF9jaGFyc2V0ID0gY2hhcnNldDsKLQl9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogQ29udGFpbnMgbm90aGluZyB5ZXQKLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCgpIHsKLQkvLyBEb24ndCBuZWVkIGFueXRoaW5nIGhlcmUgc28gZmFyLi4uCi0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIFNldCB0aGUgZXJyb3IgZXZlbnQgbGlzdGVuZXIgZm9yIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnksIHdoaWNoIGlzIHVzZWQKLSAgICAgKiBmb3IgdGhlIHByb2Nlc3Npbmcgb2YgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCBhbmQgbm90IGZvciB0aGUKLSAgICAgKiB0cmFuc2Zvcm1hdGlvbiBpdHNlbGYuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGlzdGVuZXIgVGhlIGVycm9yIGxpc3RlbmVyIHRvIHVzZSB3aXRoIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikgCi0JdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0JaWYgKGxpc3RlbmVyID09IG51bGwpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEVSUk9SX0xJU1RFTkVSX05VTEwpOwotCV9lcnJvckxpc3RlbmVyID0gbGlzdGVuZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIEdldCB0aGUgZXJyb3IgZXZlbnQgaGFuZGxlciBmb3IgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGVycm9yIGxpc3RlbmVyIHVzZWQgd2l0aCB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5Ci0gICAgICovCi0gICAgcHVibGljIEVycm9yTGlzdGVuZXIgZ2V0RXJyb3JMaXN0ZW5lcigpIHsgCi0JcmV0dXJuIF9lcnJvckxpc3RlbmVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBzZXQgZm9yIGEgVHJhbnNmb3JtZXJGYWN0b3J5IGF0dHJpYnV0ZQotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lCi0gICAgICogQHJldHVybiBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBhdHRyaWJ1dGUgdmFsdWUKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBPYmplY3QgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKSAKLQl0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsgCi0JaWYgKG5hbWUuZXF1YWxzKCJ0cmFuc2xldC1uYW1lIikpCi0JICAgIHJldHVybihfZGVmYXVsdFRyYW5zbGV0TmFtZSk7Ci0JcmV0dXJuKG51bGwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBTZXRzIHRoZSB2YWx1ZSBmb3IgYSBUcmFuc2Zvcm1lckZhY3RvcnkgYXR0cmlidXRlLgotICAgICAqCi0gICAgICogQHBhcmFtIG5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lCi0gICAgICogQHBhcmFtIHZhbHVlIEFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSB2YWx1ZQotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIAotCXRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geyAKLQkvLyBTZXQgdGhlIGRlZmF1bHQgdHJhbnNsZXQgbmFtZSAoaWUuIGNsYXNzIG5hbWUpLCB3aGljaCB3aWxsIGJlIHVzZWQKLQkvLyBmb3IgdHJhbnNsZXRzIHRoYXQgY2Fubm90IGJlIGdpdmVuIGEgbmFtZSBmcm9tIHRoZWlyIHN5c3RlbS1pZC4KLQlpZiAoKG5hbWUuZXF1YWxzKCJ0cmFuc2xldC1uYW1lIikpICYmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykpCi0JICAgIF9kZWZhdWx0VHJhbnNsZXROYW1lID0gKFN0cmluZyl2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogTG9vayB1cCB0aGUgdmFsdWUgb2YgYSBmZWF0dXJlICh0byBzZWUgaWYgaXQgaXMgc3VwcG9ydGVkKS4KLSAgICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIHVwZGF0ZWQgYXMgdGhlIHZhcmlvdXMgbWV0aG9kcyBhbmQgZmVhdHVyZXMgb2YgdGhpcwotICAgICAqIGNsYXNzIGFyZSBpbXBsZW1lbnRlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBmZWF0dXJlIG5hbWUKLSAgICAgKiBAcmV0dXJuICd0cnVlJyBpZiBmZWF0dXJlIGlzIHN1cHBvcnRlZCwgJ2ZhbHNlJyBpZiBub3QKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB7IAotCS8vIEFsbCBzdXBwb3J0ZWQgZmVhdHVyZXMgc2hvdWxkIGJlIGxpc3RlZCBoZXJlCi0JU3RyaW5nW10gZmVhdHVyZXMgPSB7Ci0JICAgIERPTVNvdXJjZS5GRUFUVVJFLAotCSAgICBET01SZXN1bHQuRkVBVFVSRSwKLQkgICAgU0FYU291cmNlLkZFQVRVUkUsCi0JICAgIFNBWFJlc3VsdC5GRUFUVVJFLAotCSAgICBTdHJlYW1Tb3VyY2UuRkVBVFVSRSwKLQkgICAgU3RyZWFtUmVzdWx0LkZFQVRVUkUKLQl9OwotCi0JLy8gSW5lZmZpY2llbnQsIGJ1dCBpdCByZWFsbHkgZG9lcyBub3QgbWF0dGVyIGluIGEgZnVuY3Rpb24gbGlrZSB0aGlzCi0JZm9yIChpbnQgaT0wOyBpPGZlYXR1cmVzLmxlbmd0aDsgaSsrKQotCSAgICBpZiAobmFtZS5lcXVhbHMoZmVhdHVyZXNbaV0pKSByZXR1cm4gdHJ1ZTsKLQotCS8vIEZlYXR1cmUgbm90IHN1cHBvcnRlZAotCXJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IHRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIGJ5IGRlZmF1bHQgZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbiB0bwotICAgICAqIHJlc29sdmUgVVJJcyB1c2VkIGluIGRvY3VtZW50KCksIHhzbDppbXBvcnQsIG9yIHhzbDppbmNsdWRlLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgVVJMUmVzb2x2ZXIgdXNlZCBmb3IgdGhpcyBUcmFuc2Zvcm1lckZhY3RvcnkgYW5kIGFsbAotICAgICAqIFRlbXBsYXRlcyBhbmQgVHJhbnNmb3JtZXIgb2JqZWN0cyBjcmVhdGVkIHVzaW5nIHRoaXMgZmFjdG9yeQotICAgICAqLyAgICAKLSAgICBwdWJsaWMgVVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKSB7Ci0JcmV0dXJuKF91cmlSZXNvbHZlcik7Ci0gICAgfSAKLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBTZXQgdGhlIG9iamVjdCB0aGF0IGlzIHVzZWQgYnkgZGVmYXVsdCBkdXJpbmcgdGhlIHRyYW5zZm9ybWF0aW9uIHRvCi0gICAgICogcmVzb2x2ZSBVUklzIHVzZWQgaW4gZG9jdW1lbnQoKSwgeHNsOmltcG9ydCwgb3IgeHNsOmluY2x1ZGUuIE5vdGUgdGhhdAotICAgICAqIHRoaXMgZG9lcyBub3QgYWZmZWN0IFRlbXBsYXRlcyBhbmQgVHJhbnNmb3JtZXJzIHRoYXQgYXJlIGFscmVhZHkKLSAgICAgKiBjcmVhdGVkIHdpdGggdGhpcyBmYWN0b3J5LgotICAgICAqCi0gICAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBVUkxSZXNvbHZlciB1c2VkIGZvciB0aGlzIFRyYW5zZm9ybWVyRmFjdG9yeSBhbmQgYWxsCi0gICAgICogVGVtcGxhdGVzIGFuZCBUcmFuc2Zvcm1lciBvYmplY3RzIGNyZWF0ZWQgdXNpbmcgdGhpcyBmYWN0b3J5Ci0gICAgICovICAgIAotICAgIHB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKSB7Ci0JX3VyaVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIEdldCB0aGUgc3R5bGVzaGVldCBzcGVjaWZpY2F0aW9uKHMpIGFzc29jaWF0ZWQgdmlhIHRoZSB4bWwtc3R5bGVzaGVldAotICAgICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94bWwtc3R5bGVzaGVldC8pIHdpdGgKLSAgICAgKiB0aGUgZG9jdW1lbnQgZG9jdW1lbnQgc3BlY2lmaWVkIGluIHRoZSBzb3VyY2UgcGFyYW1ldGVyLCBhbmQgdGhhdCBtYXRjaAotICAgICAqIHRoZSBnaXZlbiBjcml0ZXJpYS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzb3VyY2UgVGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQuCi0gICAgICogQHBhcmFtIG1lZGlhIFRoZSBtZWRpYSBhdHRyaWJ1dGUgdG8gYmUgbWF0Y2hlZC4gTWF5IGJlIG51bGwsIGluIHdoaWNoCi0gICAgICogY2FzZSB0aGUgcHJlZmVyZWQgdGVtcGxhdGVzIHdpbGwgYmUgdXNlZCAoaS5lLiBhbHRlcm5hdGUgPSBubykuCi0gICAgICogQHBhcmFtIHRpdGxlIFRoZSB2YWx1ZSBvZiB0aGUgdGl0bGUgYXR0cmlidXRlIHRvIG1hdGNoLiBNYXkgYmUgbnVsbC4KLSAgICAgKiBAcGFyYW0gY2hhcnNldCBUaGUgdmFsdWUgb2YgdGhlIGNoYXJzZXQgYXR0cmlidXRlIHRvIG1hdGNoLiBNYXkgYmUgbnVsbC4KLSAgICAgKiBAcmV0dXJuIEEgU291cmNlIG9iamVjdCBzdWl0YWJsZSBmb3IgcGFzc2luZyB0byB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIFNvdXJjZSBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldChTb3VyY2Ugc291cmNlLCBTdHJpbmcgbWVkaWEsCi0JCQkJCSAgU3RyaW5nIHRpdGxlLCBTdHJpbmcgY2hhcnNldCkKLQl0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQkvLyBGaXJzdCBjcmVhdGUgYSBoYXNodGFibGUgdGhhdCBtYXBzIFNvdXJjZSByZWZzLiB0byBwYXJhbWV0ZXJzCi0JaWYgKF9waVBhcmFtcyA9PSBudWxsKSBfcGlQYXJhbXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JLy8gU3RvcmUgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgU291cmNlIGluIHRoZSBIYXNodGFibGUKLQlfcGlQYXJhbXMucHV0KHNvdXJjZSwgbmV3IFBJUGFyYW1XcmFwcGVyKG1lZGlhLCB0aXRsZSwgY2hhcnNldCkpOwotCS8vIFJldHVybiB0aGUgc2FtZSBTb3VyY2UgLSB3ZSdsbCBsb2NhdGUgdGhlIHN0eWxlc2hlZXQgbGF0ZXIKLQlyZXR1cm4oc291cmNlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogQ3JlYXRlIGEgVHJhbnNmb3JtZXIgb2JqZWN0IHRoYXQgY29waWVzIHRoZSBpbnB1dCBkb2N1bWVudCB0byB0aGUgcmVzdWx0LgotICAgICAqCi0gICAgICogQHJldHVybiBBIFRyYW5zZm9ybWVyIG9iamVjdCB0aGF0IHNpbXBseSBjb3BpZXMgdGhlIHNvdXJjZSB0byB0aGUgcmVzdWx0LgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICovICAgIAotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpCi0JdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7IAotCi0JaWYgKF9jb3B5VHJhbnNmb3JtZXIgIT0gbnVsbCkgewotCSAgICBpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpCi0JCV9jb3B5VHJhbnNmb3JtZXIuc2V0VVJJUmVzb2x2ZXIoX3VyaVJlc29sdmVyKTsKLQkgICAgcmV0dXJuIF9jb3B5VHJhbnNmb3JtZXI7Ci0JfQotCi0JWFNMVEMgeHNsdGMgPSBuZXcgWFNMVEMoKTsKLQl4c2x0Yy5pbml0KCk7Ci0KLQkvLyBDb21waWxlIHRoZSBkZWZhdWx0IGNvcHktc3R5bGVzaGVldAotCWJ5dGVbXSBieXRlcyA9IENPUFlfVFJBTlNMRVRfQ09ERS5nZXRCeXRlcygpOwotCUJ5dGVBcnJheUlucHV0U3RyZWFtIGJ5dGVzdHJlYW0gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMpOwotCUlucHV0U291cmNlIGlucHV0ID0gbmV3IElucHV0U291cmNlKGJ5dGVzdHJlYW0pOwotCWlucHV0LnNldFN5c3RlbUlkKF9kZWZhdWx0VHJhbnNsZXROYW1lKTsKLQlieXRlW11bXSBieXRlY29kZXMgPSB4c2x0Yy5jb21waWxlKF9kZWZhdWx0VHJhbnNsZXROYW1lLCBpbnB1dCk7Ci0KLQkvLyBDaGVjayB0aGF0IHRoZSB0cmFuc2Zvcm1hdGlvbiB3ZW50IHdlbGwgYmVmb3JlIHJldHVybmluZwotCWlmIChieXRlY29kZXMgPT0gbnVsbCkgewotCSAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKENPTVBJTEVfRVJSKTsKLQl9Ci0KLQkvLyBDcmVhdGUgYSBUcmFuc2Zvcm1lciBvYmplY3QgYW5kIHN0b3JlIGZvciBvdGhlciBjYWxscwotCVRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBuZXcgVGVtcGxhdGVzSW1wbChieXRlY29kZXMsX2RlZmF1bHRUcmFuc2xldE5hbWUpOwotCV9jb3B5VHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLQlpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpIF9jb3B5VHJhbnNmb3JtZXIuc2V0VVJJUmVzb2x2ZXIoX3VyaVJlc29sdmVyKTsKLQlyZXR1cm4oX2NvcHlUcmFuc2Zvcm1lcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uLgotICAgICAqIFByb2Nlc3MgdGhlIFNvdXJjZSBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdCwgd2hpY2ggaXMgYSBhIGNvbXBpbGVkCi0gICAgICogcmVwcmVzZW50YXRpb24gb2YgdGhlIHNvdXJjZS4gTm90ZSB0aGF0IHRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUKLSAgICAgKiB1c2VkIHdpdGggWFNMVEMsIGFzIHRoZSB0aW1lLWNvbnN1bWluZyBjb21waWxhdGlvbiBpcyBkb25lIGZvciBlYWNoCi0gICAgICogYW5kIGV2ZXJ5IHRyYW5zZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIFRlbXBsYXRlcyBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgVHJhbnNmb3JtZXJzLgotICAgICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gICAgICovCi0gICAgcHVibGljIFRyYW5zZm9ybWVyIG5ld1RyYW5zZm9ybWVyKFNvdXJjZSBzb3VyY2UpIHRocm93cwotCVRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0JZmluYWwgVGVtcGxhdGVzIHRlbXBsYXRlcyA9IG5ld1RlbXBsYXRlcyhzb3VyY2UpOwotCWZpbmFsIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdGVtcGxhdGVzLm5ld1RyYW5zZm9ybWVyKCk7Ci0JaWYgKF91cmlSZXNvbHZlciAhPSBudWxsKSB0cmFuc2Zvcm1lci5zZXRVUklSZXNvbHZlcihfdXJpUmVzb2x2ZXIpOwotCXJldHVybih0cmFuc2Zvcm1lcik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUGFzcyB3YXJuaW5nIG1lc3NhZ2VzIGZyb20gdGhlIGNvbXBpbGVyIHRvIHRoZSBlcnJvciBsaXN0ZW5lcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwYXNzV2FybmluZ3NUb0xpc3RlbmVyKFZlY3RvciBtZXNzYWdlcykgewotCXRyeSB7Ci0JICAgIC8vIE5vdGhpbmcgdG8gZG8gaWYgdGhlcmUgaXMgbm8gcmVnaXN0ZXJlZCBlcnJvciBsaXN0ZW5lcgotCSAgICBpZiAoX2Vycm9yTGlzdGVuZXIgPT0gbnVsbCkgcmV0dXJuOwotCSAgICAvLyBOb3RoaW5nIHRvIGRvIGlmIHRoZXJlIGFyZSBub3Qgd2FybmluZyBtZXNzYWdlcwotCSAgICBpZiAobWVzc2FnZXMgPT0gbnVsbCkgcmV0dXJuOwotCSAgICAvLyBQYXNzIG1lc3NhZ2VzIHRvIGxpc3RlbmVyLCBvbmUgYnkgb25lCi0JICAgIGZpbmFsIGludCBjb3VudCA9IG1lc3NhZ2VzLnNpemUoKTsKLQkgICAgZm9yIChpbnQgcG9zPTA7IHBvczxjb3VudDsgcG9zKyspIHsKLQkJU3RyaW5nIG1lc3NhZ2UgPSBtZXNzYWdlcy5lbGVtZW50QXQocG9zKS50b1N0cmluZygpOwotCQlfZXJyb3JMaXN0ZW5lci53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtZXNzYWdlKSk7Ci0JICAgIH0KLQl9Ci0JY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLQkgICAgLy8gbmFkYQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQYXNzIGVycm9yIG1lc3NhZ2VzIGZyb20gdGhlIGNvbXBpbGVyIHRvIHRoZSBlcnJvciBsaXN0ZW5lcgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBwYXNzRXJyb3JzVG9MaXN0ZW5lcihWZWN0b3IgbWVzc2FnZXMpIHsKLQl0cnkgewotCSAgICAvLyBOb3RoaW5nIHRvIGRvIGlmIHRoZXJlIGlzIG5vIHJlZ2lzdGVyZWQgZXJyb3IgbGlzdGVuZXIKLQkgICAgaWYgKF9lcnJvckxpc3RlbmVyID09IG51bGwpIHJldHVybjsKLQkgICAgLy8gTm90aGluZyB0byBkbyBpZiB0aGVyZSBhcmUgbm90IHdhcm5pbmcgbWVzc2FnZXMKLQkgICAgaWYgKG1lc3NhZ2VzID09IG51bGwpIHJldHVybjsKLQkgICAgLy8gUGFzcyBtZXNzYWdlcyB0byBsaXN0ZW5lciwgb25lIGJ5IG9uZQotCSAgICBmaW5hbCBpbnQgY291bnQgPSBtZXNzYWdlcy5zaXplKCk7Ci0JICAgIGZvciAoaW50IHBvcz0wOyBwb3M8Y291bnQ7IHBvcysrKSB7Ci0JCVN0cmluZyBtZXNzYWdlID0gbWVzc2FnZXMuZWxlbWVudEF0KHBvcykudG9TdHJpbmcoKTsKLQkJX2Vycm9yTGlzdGVuZXIuZXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKG1lc3NhZ2UpKTsKLQkgICAgfQotCX0KLQljYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkgewotCSAgICAvLyBuYWRhCi0JfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZXMgYSBTQVgyIElucHV0U291cmNlIG9iamVjdCBmcm9tIGEgVHJBWCBTb3VyY2Ugb2JqZWN0Ci0gICAgICovCi0gICAgcHJpdmF0ZSBJbnB1dFNvdXJjZSBnZXRJbnB1dFNvdXJjZShYU0xUQyB4c2x0YywgU291cmNlIHNvdXJjZSkKLQl0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsKLQotCUlucHV0U291cmNlIGlucHV0ID0gbnVsbDsKLQlmaW5hbCBTdHJpbmcgc3lzdGVtSWQgPSBzb3VyY2UuZ2V0U3lzdGVtSWQoKTsKLQotCXRyeSB7Ci0KLQkgICAgLy8gVHJ5IHRvIGdldCBJbnB1dFNvdXJjZSBmcm9tIFNBWFNvdXJjZSBpbnB1dAotCSAgICBpZiAoc291cmNlIGluc3RhbmNlb2YgU0FYU291cmNlKSB7Ci0JCWZpbmFsIFNBWFNvdXJjZSBzYXggPSAoU0FYU291cmNlKXNvdXJjZTsKLQkJaW5wdXQgPSBzYXguZ2V0SW5wdXRTb3VyY2UoKTsKLQkJLy8gUGFzcyB0aGUgU0FYIHBhcnNlciB0byB0aGUgY29tcGlsZXIKLQkJeHNsdGMuc2V0WE1MUmVhZGVyKHNheC5nZXRYTUxSZWFkZXIoKSk7Ci0JICAgIH0KLQkgICAgLy8gaGFuZGxlICBET01Tb3VyY2UgIAotCSAgICBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpIHsKLQkJZmluYWwgRE9NU291cmNlIGRvbXNyYyA9IChET01Tb3VyY2Upc291cmNlOwotCQlmaW5hbCBEb2N1bWVudCBkb20gPSAoRG9jdW1lbnQpZG9tc3JjLmdldE5vZGUoKTsKLQkJZmluYWwgRE9NMlNBWCBkb20yc2F4ID0gbmV3IERPTTJTQVgoZG9tKTsKLQkJeHNsdGMuc2V0WE1MUmVhZGVyKGRvbTJzYXgpOyAgCi0JICAgICAgICAvLyB0cnkgdG8gZ2V0IFNBWCBJbnB1dFNvdXJjZSBmcm9tIERPTSBTb3VyY2UuCi0JCWlucHV0ID0gU0FYU291cmNlLnNvdXJjZVRvSW5wdXRTb3VyY2Uoc291cmNlKTsKLQkgICAgfQotCSAgICAvLyBUcnkgdG8gZ2V0IElucHV0U3RyZWFtIG9yIFJlYWRlciBmcm9tIFN0cmVhbVNvdXJjZQotCSAgICBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBTdHJlYW1Tb3VyY2UpIHsKLQkJZmluYWwgU3RyZWFtU291cmNlIHN0cmVhbSA9IChTdHJlYW1Tb3VyY2Upc291cmNlOwotCQlmaW5hbCBJbnB1dFN0cmVhbSBpc3RyZWFtID0gc3RyZWFtLmdldElucHV0U3RyZWFtKCk7Ci0JCWZpbmFsIFJlYWRlciByZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKCk7Ci0JCS8vIENyZWF0ZSBJbnB1dFNvdXJjZSBmcm9tIFJlYWRlciBvciBJbnB1dFN0cmVhbSBpbiBTb3VyY2UKLQkJaWYgKGlzdHJlYW0gIT0gbnVsbCkKLQkJICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKGlzdHJlYW0pOwotCQllbHNlIGlmIChyZWFkZXIgIT0gbnVsbCkKLQkJICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKHJlYWRlcik7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oVU5LTk9XTl9TT1VSQ0VfRVJSKTsKLQkgICAgfQotCSAgICAvLyBUcnkgdG8gY3JlYXRlIGFuIElucHV0U3RyZWFtIGZyb20gdGhlIFN5c3RlbUlkIGlmIG5vIGlucHV0IHNvIGZhcgotCSAgICBpZiAoaW5wdXQgPT0gbnVsbCkgewotCQlpZiAoKG5ldyBGaWxlKHN5c3RlbUlkKSkuZXhpc3RzKCkpCi0JCSAgICBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZSgiZmlsZTovIitzeXN0ZW1JZCk7Ci0JCWVsc2UKLQkJICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKHN5c3RlbUlkKTsKLQkgICAgfQotCi0JICAgIC8vIFBhc3Mgc3lzdGVtIGlkIHRvIElucHV0U291cmNlIGp1c3QgdG8gYmUgb24gdGhlIHNhZmUgc2lkZQotCSAgICBpbnB1dC5zZXRTeXN0ZW1JZChzeXN0ZW1JZCk7Ci0JfQotCWNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oTk9fU09VUkNFX0VSUik7Ci0JfQotCWNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oTk9fQUNDRVNTX0VSUitzeXN0ZW1JZCk7Ci0JfQotCWZpbmFsbHkgewotCSAgICByZXR1cm4oaW5wdXQpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogUHJvY2VzcyB0aGUgU291cmNlIGludG8gYSBUZW1wbGF0ZXMgb2JqZWN0LCB3aGljaCBpcyBhIGEgY29tcGlsZWQKLSAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgc291cmNlLgotICAgICAqCi0gICAgICogQHBhcmFtIHN0eWxlc2hlZXQgVGhlIGlucHV0IHN0eWxlc2hlZXQgLSBET01Tb3VyY2Ugbm90IHN1cHBvcnRlZCEhIQotICAgICAqIEByZXR1cm4gQSBUZW1wbGF0ZXMgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIFRyYW5zZm9ybWVycy4KLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUZW1wbGF0ZXMgbmV3VGVtcGxhdGVzKFNvdXJjZSBzb3VyY2UpCi0JdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7Ci0KLQkvLyBDcmVhdGUgYW5kIGluaXRpYWxpemUgYSBzdHlsZXNoZWV0IGNvbXBpbGVyCi0JZmluYWwgWFNMVEMgeHNsdGMgPSBuZXcgWFNMVEMoKTsKLQl4c2x0Yy5pbml0KCk7Ci0KLQkvLyBTZXQgYSBkb2N1bWVudCBsb2FkZXIgKGZvciB4c2w6aW5jbHVkZS9pbXBvcnQpIGlmIGRlZmluZWQKLQlpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpIHhzbHRjLnNldFNvdXJjZUxvYWRlcih0aGlzKTsKLQotCS8vIFBhc3MgcGFyYW1ldGVycyB0byB0aGUgUGFyc2VyIHRvIG1ha2Ugc3VyZSBpdCBsb2NhdGVzIHRoZSBjb3JyZWN0Ci0JLy8gPD94bWwtc3R5bGVzaGVldCAuLi4/PiBQSSBpbiBhbiBYTUwgaW5wdXQgZG9jdW1lbnQKLQlpZiAoKF9waVBhcmFtcyAhPSBudWxsKSAmJiAoX3BpUGFyYW1zLmdldChzb3VyY2UpICE9IG51bGwpKSB7Ci0JICAgIC8vIEdldCB0aGUgcGFyYW1ldGVycyBmb3IgdGhpcyBTb3VyY2Ugb2JqZWN0Ci0JICAgIFBJUGFyYW1XcmFwcGVyIHAgPSAoUElQYXJhbVdyYXBwZXIpX3BpUGFyYW1zLmdldChzb3VyY2UpOwotCSAgICAvLyBQYXNzIHRoZW0gb24gdG8gdGhlIGNvbXBpbGVyICh3aGljaCB3aWxsIHBhc3MgdGhlbiB0byB0aGUgcGFyc2VyKQotCSAgICBpZiAocCAhPSBudWxsKSAKLQkJeHNsdGMuc2V0UElQYXJhbWV0ZXJzKHAuX21lZGlhLCBwLl90aXRsZSwgcC5fY2hhcnNldCk7Ci0JfQotCi0JLy8gQ29tcGlsZSB0aGUgc3R5bGVzaGVldAotCWZpbmFsIElucHV0U291cmNlIGlucHV0ID0gZ2V0SW5wdXRTb3VyY2UoeHNsdGMsIHNvdXJjZSk7Ci0JYnl0ZVtdW10gYnl0ZWNvZGVzID0geHNsdGMuY29tcGlsZShudWxsLCBpbnB1dCk7Ci0JZmluYWwgU3RyaW5nIHRyYW5zbGV0TmFtZSA9IHhzbHRjLmdldENsYXNzTmFtZSgpOwotCi0JLy8gUGFzcyBjb21waWxlciB3YXJuaW5ncyB0byB0aGUgZXJyb3IgbGlzdGVuZXIKLQlpZiAoX2Vycm9yTGlzdGVuZXIgIT0gbnVsbCkKLQkgICAgcGFzc1dhcm5pbmdzVG9MaXN0ZW5lcih4c2x0Yy5nZXRXYXJuaW5ncygpKTsKLQllbHNlCi0JICAgIHhzbHRjLnByaW50V2FybmluZ3MoKTsKLQotCS8vIENoZWNrIHRoYXQgdGhlIHRyYW5zZm9ybWF0aW9uIHdlbnQgd2VsbCBiZWZvcmUgcmV0dXJuaW5nCi0JaWYgKGJ5dGVjb2RlcyA9PSBudWxsKSB7Ci0JICAgIC8vIFBhc3MgY29tcGlsZXIgZXJyb3JzIHRvIHRoZSBlcnJvciBsaXN0ZW5lcgotCSAgICBpZiAoX2Vycm9yTGlzdGVuZXIgIT0gbnVsbCkKLQkJcGFzc0Vycm9yc1RvTGlzdGVuZXIoeHNsdGMuZ2V0RXJyb3JzKCkpOwotCSAgICBlbHNlCi0JCXhzbHRjLnByaW50RXJyb3JzKCk7Ci0JICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oQ09NUElMRV9FUlIpOwotCX0KLQlyZXR1cm4obmV3IFRlbXBsYXRlc0ltcGwoYnl0ZWNvZGVzLCB0cmFuc2xldE5hbWUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IGEgVGVtcGxhdGVzSGFuZGxlciBvYmplY3QgdGhhdCBjYW4gcHJvY2VzcyBTQVggQ29udGVudEhhbmRsZXIKLSAgICAgKiBldmVudHMgaW50byBhIFRlbXBsYXRlcyBvYmplY3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgVGVtcGxhdGVzSGFuZGxlciBvYmplY3QgdGhhdCBjYW4gaGFuZGxlIFNBWCBldmVudHMKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUZW1wbGF0ZXNIYW5kbGVyIG5ld1RlbXBsYXRlc0hhbmRsZXIoKSAKLQl0aHJvd3MgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIHsgCi0JcmV0dXJuKG5ldyBUZW1wbGF0ZXNIYW5kbGVySW1wbCgpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IGEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWCBDb250ZW50SGFuZGxlcgotICAgICAqIGV2ZW50cyBpbnRvIGEgUmVzdWx0LiBUaGlzIG1ldGhvZCB3aWxsIHJldHVybiBhIHB1cmUgY29weSB0cmFuc2Zvcm1lci4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lckhhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIGhhbmRsZSBTQVggZXZlbnRzCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcigpIAotCXRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCWZpbmFsIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gbmV3VHJhbnNmb3JtZXIoKTsKLQlmaW5hbCBUcmFuc2Zvcm1lckltcGwgaW50ZXJuYWwgPSAoVHJhbnNmb3JtZXJJbXBsKXRyYW5zZm9ybWVyOwotCXJldHVybihuZXcgVHJhbnNmb3JtZXJIYW5kbGVySW1wbChpbnRlcm5hbCkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBHZXQgYSBUcmFuc2Zvcm1lckhhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIHByb2Nlc3MgU0FYIENvbnRlbnRIYW5kbGVyCi0gICAgICogZXZlbnRzIGludG8gYSBSZXN1bHQsIGJhc2VkIG9uIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMKLSAgICAgKiBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50LgotICAgICAqCi0gICAgICogQHBhcmFtIHNyYyBUaGUgc291cmNlIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuCi0gICAgICogQHJldHVybiBBIFRyYW5zZm9ybWVySGFuZGxlciBvYmplY3QgdGhhdCBjYW4gaGFuZGxlIFNBWCBldmVudHMKLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKFNvdXJjZSBzcmMpIAotCXRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24geyAKLQlmaW5hbCBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IG5ld1RyYW5zZm9ybWVyKHNyYyk7Ci0JZmluYWwgVHJhbnNmb3JtZXJJbXBsIGludGVybmFsID0gKFRyYW5zZm9ybWVySW1wbCl0cmFuc2Zvcm1lcjsKLQlyZXR1cm4obmV3IFRyYW5zZm9ybWVySGFuZGxlckltcGwoaW50ZXJuYWwpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3RvcnkgaW1wbGVtZW50YXRpb24uCi0gICAgICogR2V0IGEgVHJhbnNmb3JtZXJIYW5kbGVyIG9iamVjdCB0aGF0IGNhbiBwcm9jZXNzIFNBWCBDb250ZW50SGFuZGxlcgotICAgICAqIGV2ZW50cyBpbnRvIGEgUmVzdWx0LCBiYXNlZCBvbiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zCi0gICAgICogc3BlY2lmaWVkIGJ5IHRoZSBhcmd1bWVudC4KLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZW1wbGF0ZXMgUmVwcmVzZW50cyBhIHByZS1wcm9jZXNzZWQgc3R5bGVzaGVldAotICAgICAqIEByZXR1cm4gQSBUcmFuc2Zvcm1lckhhbmRsZXIgb2JqZWN0IHRoYXQgY2FuIGhhbmRsZSBTQVggZXZlbnRzCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8gICAgCi0gICAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykgCi0JdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiAgewotCWZpbmFsIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdGVtcGxhdGVzLm5ld1RyYW5zZm9ybWVyKCk7Ci0JZmluYWwgVHJhbnNmb3JtZXJJbXBsIGludGVybmFsID0gKFRyYW5zZm9ybWVySW1wbCl0cmFuc2Zvcm1lcjsKLQlyZXR1cm4obmV3IFRyYW5zZm9ybWVySGFuZGxlckltcGwoaW50ZXJuYWwpKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBDcmVhdGUgYW4gWE1MRmlsdGVyIHRoYXQgdXNlcyB0aGUgZ2l2ZW4gc291cmNlIGFzIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzcmMgVGhlIHNvdXJjZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgICAqIEByZXR1cm4gQW4gWE1MRmlsdGVyIG9iamVjdCwgb3IgbnVsbCBpZiB0aGlzIGZlYXR1cmUgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxGaWx0ZXIgbmV3WE1MRmlsdGVyKFNvdXJjZSBzcmMpIAotCXRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCVRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBuZXdUZW1wbGF0ZXMoc3JjKTsKLQlpZiAodGVtcGxhdGVzID09IG51bGwgKSByZXR1cm4gbnVsbDsgCi0JcmV0dXJuIG5ld1hNTEZpbHRlcih0ZW1wbGF0ZXMpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgKiBDcmVhdGUgYW4gWE1MRmlsdGVyIHRoYXQgdXNlcyB0aGUgZ2l2ZW4gc291cmNlIGFzIHRoZQotICAgICAqIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzcmMgVGhlIHNvdXJjZSBvZiB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLgotICAgICAqIEByZXR1cm4gQW4gWE1MRmlsdGVyIG9iamVjdCwgb3IgbnVsbCBpZiB0aGlzIGZlYXR1cmUgaXMgbm90IHN1cHBvcnRlZC4KLSAgICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBYTUxGaWx0ZXIgbmV3WE1MRmlsdGVyKFRlbXBsYXRlcyB0ZW1wbGF0ZXMpIAotCXRocm93cyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gewotCXRyeSB7Ci0gICAgICAJICAgIHJldHVybiBuZXcgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy50cmF4LlRyQVhGaWx0ZXIodGVtcGxhdGVzKTsKLSAgICAJfQotCWNhdGNoKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlMSkgewotICAgICAgCSAgICBpZihfZXJyb3JMaXN0ZW5lciAhPSBudWxsKSB7Ci0gICAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAJICAgIF9lcnJvckxpc3RlbmVyLmZhdGFsRXJyb3IoZTEpOwotICAgICAgICAgIAkgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIAl9Ci0JCWNhdGNoKCBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlMikgewotICAgICAgICAgIAkgICAgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihlMik7Ci0gICAgICAgIAl9Ci0gICAgICAJICAgIH0KLSAgICAgIAkgICAgdGhyb3cgZTE7Ci0gICAgCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIFhTTFRDJ3MgU291cmNlTG9hZGVyIGludGVyZmFjZS4gSXQgaXMgdXNlZCB0bwotICAgICAqIGdsdWUgYSBUckFYIFVSSVJlc29sdmVyIHRvIHRoZSBYU0xUQyBjb21waWxlcidzIElucHV0IGFuZCBJbXBvcnQgY2xhc3Nlcy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBocmVmIFRoZSBVUkkgb2YgdGhlIGRvY3VtZW50IHRvIGxvYWQKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgVVJJIG9mIHRoZSBjdXJyZW50bHkgbG9hZGVkIGRvY3VtZW50Ci0gICAgICogQHBhcmFtIHhzbHRjIFRoZSBjb21waWxlciB0aGF0IHJlc3Vlc3RzIHRoZSBkb2N1bWVudAotICAgICAqIEByZXR1cm4gQW4gSW5wdXRTb3VyY2Ugd2l0aCB0aGUgbG9hZGVkIGRvY3VtZW50Ci0gICAgICovCi0gICAgcHVibGljIElucHV0U291cmNlIGxvYWRTb3VyY2UoU3RyaW5nIGhyZWYsIFN0cmluZyBjb250ZXh0LCBYU0xUQyB4c2x0YykgewotCXRyeSB7Ci0JICAgIGZpbmFsIFNvdXJjZSBzb3VyY2UgPSBfdXJpUmVzb2x2ZXIucmVzb2x2ZShocmVmLCBjb250ZXh0KTsKLQkgICAgZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgPSBnZXRJbnB1dFNvdXJjZSh4c2x0Yywgc291cmNlKTsKLQkgICAgcmV0dXJuKGlucHV0KTsKLQl9Ci0JY2F0Y2ggKFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0JICAgIHJldHVybiBudWxsOwotCX0KLQljYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gZSkgewotCSAgICByZXR1cm4gbnVsbDsKLQl9Ci0gICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4L1RyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1M2NjMDA3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQzICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICoKLSAqIEBhdXRob3IgTW9ydGVuIEpvcmdlbnNlbgotICoKLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheDsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NSW1wbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5EVERNb25pdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5BYnN0cmFjdFRyYW5zbGV0OwotCi0vKioKLSAqIEltcGxlbWVudGF0aW9uIG9mIGEgSkFYUDEuMSBUcmFuc2Zvcm1lckhhbmRsZXIKLSAqLwotcHVibGljIGNsYXNzIFRyYW5zZm9ybWVySGFuZGxlckltcGwgaW1wbGVtZW50cyBUcmFuc2Zvcm1lckhhbmRsZXIgewotCi0gICAgcHJpdmF0ZSBUcmFuc2Zvcm1lckltcGwgIF90cmFuc2Zvcm1lcjsKLSAgICBwcml2YXRlIEFic3RyYWN0VHJhbnNsZXQgX3RyYW5zbGV0ID0gbnVsbDsKLSAgICBwcml2YXRlIFN0cmluZyAgICAgICAgICAgX3N5c3RlbUlkOwotICAgIHByaXZhdGUgRE9NSW1wbCAgICAgICAgICBfZG9tID0gbnVsbDsKLSAgICBwcml2YXRlIENvbnRlbnRIYW5kbGVyICAgX2hhbmRsZXIgPSBudWxsOwotICAgIHByaXZhdGUgRFRETW9uaXRvciAgICAgICBfZHRkID0gbnVsbDsKLSAgICBwcml2YXRlIFJlc3VsdCAgICAgICAgICAgX3Jlc3VsdCA9IG51bGw7Ci0KLSAgICBwcml2YXRlIGJvb2xlYW4gICAgICAgICAgX2RvbmUgPSBmYWxzZTsgLy8gU2V0IGluIGVuZERvY3VtZW50KCkKLQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBOVUxMX1JFU1VMVF9FUlJPUiA9Ci0JInNldFJlc3VsdCgpIG11c3QgYmUgY2FsbGVkIHByaW9yIHRvIHN0YXJ0RG9jdW1lbnQoKS4iOwotCi0gICAgLyoqCi0gICAgICogQ29zbnRydWN0b3IgLSBwYXNzIGluIHJlZmVyZW5jZSB0byBhIFRyYW5zZm9ybWVySW1wbCBvYmplY3QKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgVHJhbnNmb3JtZXJIYW5kbGVySW1wbChUcmFuc2Zvcm1lckltcGwgdHJhbnNmb3JtZXIpIHsKLQkvLyBTYXZlIHRoZSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zZm9ybWVyCi0JX3RyYW5zZm9ybWVyID0gdHJhbnNmb3JtZXI7Ci0KLQkvLyBDcmVhdGUgYW4gaW50ZXJuYWwgRE9NIChub3QgVzNDKSBhbmQgZ2V0IFNBWDIgaW5wdXQgaGFuZGxlcgotCV9kb20gPSBuZXcgRE9NSW1wbCgpOwotCV9oYW5kbGVyID0gX2RvbS5nZXRCdWlsZGVyKCk7Ci0KLQkvLyBTZXQgdGhpcyBET00gYXMgdGhlIHRyYW5zZm9ybWVyJ3MgRE9NCi0JX3RyYW5zZm9ybWVyLnNldERPTShfZG9tKTsKLQkKLQkvLyBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zbGV0IHdyYXBwZWQgaW5zaWRlIHRoZSB0cmFuc2Zvcm1lcgotCV90cmFuc2xldCA9IF90cmFuc2Zvcm1lci5nZXRUcmFuc2xldCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyLmdldFN5c3RlbUlkKCkKLSAgICAgKiBHZXQgdGhlIGJhc2UgSUQgKFVSSSBvciBzeXN0ZW0gSUQpIGZyb20gd2hlcmUgcmVsYXRpdmUgVVJMcyB3aWxsIGJlCi0gICAgICogcmVzb2x2ZWQuCi0gICAgICogQHJldHVybiBUaGUgc3lzdGVtSUQgdGhhdCB3YXMgc2V0IHdpdGggc2V0U3lzdGVtSWQoU3RyaW5nIGlkKQotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKSB7Ci0JcmV0dXJuIF9zeXN0ZW1JZDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlci5zZXRTeXN0ZW1JZCgpCi0gICAgICogR2V0IHRoZSBiYXNlIElEIChVUkkgb3Igc3lzdGVtIElEKSBmcm9tIHdoZXJlIHJlbGF0aXZlIFVSTHMgd2lsbCBiZQotICAgICAqIHJlc29sdmVkLgotICAgICAqIEBwYXJhbSBpZCBCYXNlIFVSSSBmb3IgdGhpcyBzdHlsZXNoZWV0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0U3lzdGVtSWQoU3RyaW5nIGlkKSB7Ci0JX3N5c3RlbUlkID0gaWQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXIuZ2V0VHJhbnNmb3JtZXIoKQotICAgICAqIEdldCB0aGUgVHJhbnNmb3JtZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaGFuZGxlciwgd2hpY2ggaXMgbmVlZGVkIGluCi0gICAgICogb3JkZXIgdG8gc2V0IHBhcmFtZXRlcnMgYW5kIG91dHB1dCBwcm9wZXJ0aWVzLgotICAgICAqIEByZXR1cm4gVGhlIFRyYW5zZm9ybWVyIG9iamVjdAotICAgICAqLwotICAgIHB1YmxpYyBUcmFuc2Zvcm1lciBnZXRUcmFuc2Zvcm1lcigpIHsKLQlyZXR1cm4obnVsbCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UcmFuc2Zvcm1lckhhbmRsZXIuc2V0UmVzdWx0KCkKLSAgICAgKiBFbmFibGVzIHRoZSB1c2VyIG9mIHRoZSBUcmFuc2Zvcm1lckhhbmRsZXIgdG8gc2V0IHRoZSB0byBzZXQgdGhlIFJlc3VsdAotICAgICAqIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICogQHBhcmFtIHJlc3VsdCBBIFJlc3VsdCBpbnN0YW5jZSwgc2hvdWxkIG5vdCBiZSBudWxsCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcmVzdWx0IGlzIGludmFsaWQgZm9yIHNvbWUgcmVhc29uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UmVzdWx0KFJlc3VsdCByZXN1bHQpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotCV9yZXN1bHQgPSByZXN1bHQ7Ci0KLQkvLyBSdW4gdGhlIHRyYW5zZm9ybWF0aW9uIG5vdywgaWYgbm90IGFscmVhZHkgZG9uZQotCWlmIChfZG9uZSkgewotCSAgICB0cnkgewotCQlfdHJhbnNmb3JtZXIuc2V0RE9NKF9kb20pOwotCQlfdHJhbnNmb3JtZXIudHJhbnNmb3JtKG51bGwsIF9yZXN1bHQpOwotCSAgICB9Ci0JICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0JCS8vIFdoYXQgdGhlIGhlbGwgYXJlIHdlIHN1cHBvc2VkIHRvIGRvIHdpdGggdGhpcz8/PwotCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpKTsKLQkgICAgfQotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGNoYXJhY3RlciBkYXRhLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIAotCXRocm93cyBTQVhFeGNlcHRpb24gewotCV9oYW5kbGVyLmNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGJlZ2lubmluZyBvZiBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQlpZiAoX3Jlc3VsdCA9PSBudWxsKSB7Ci0JICAgIHRocm93IG5ldyBTQVhFeGNlcHRpb24oTlVMTF9SRVNVTFRfRVJST1IpOwotCX0KLQlfaGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JLy8gU2lnbmFsIHRvIHRoZSBET01CdWlsZGVyIHRoYXQgdGhlIGRvY3VtZW50IGlzIGNvbXBsZXRlCi0JX2hhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQkvLyBQYXNzIHVucGFyc2VkIGVudGl0eSBkZWNsYXJhdGlvbnMgKGlmIGFueSkgdG8gdGhlIHRyYW5zbGV0IAotCWlmIChfZHRkICE9IG51bGwpIF90cmFuc2xldC5zZXREVERNb25pdG9yKF9kdGQpOwotCS8vIFJ1biB0aGUgdHJhbnNmb3JtYXRpb24gbm93IGlmIHdlIGhhdmUgYSByZWZlcmVuY2UgdG8gYSBSZXN1bHQgb2JqZWN0Ci0JaWYgKF9yZXN1bHQgIT0gbnVsbCkgewotCSAgICB0cnkgewotCQlfdHJhbnNmb3JtZXIuc2V0RE9NKF9kb20pOwotCQlfdHJhbnNmb3JtZXIudHJhbnNmb3JtKG51bGwsIF9yZXN1bHQpOwotCSAgICB9Ci0JICAgIGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0JCXRocm93IG5ldyBTQVhFeGNlcHRpb24oZSk7Ci0JICAgIH0KLQl9Ci0JLy8gU2lnbmFsIHRoYXQgdGhlIGludGVybmFsIERPTSBpcyBidWlsZCAoc2VlICdzZXRSZXN1bHQoKScpLgotCV9kb25lID0gdHJ1ZTsKLSAgICB9Ci0JCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlci5zdGFydEVsZW1lbnQoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIHRoZSBiZWdpbm5pbmcgb2YgYW4gZWxlbWVudC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwKLQkJCSAgICAgU3RyaW5nIHFuYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JX2hhbmRsZXIuc3RhcnRFbGVtZW50KHVyaSwgbG9jYWxOYW1lLCBxbmFtZSwgYXR0cmlidXRlcyk7Ci0gICAgfQotCQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIuZW5kRWxlbWVudCgpCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFuYW1lKQotCXRocm93cyBTQVhFeGNlcHRpb24gewotCV9oYW5kbGVyLmVuZEVsZW1lbnQobmFtZXNwYWNlVVJJLCBsb2NhbE5hbWUsIHFuYW1lKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbigpCi0gICAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQlfaGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24odGFyZ2V0LCBkYXRhKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGlnbm9yYWJsZSB3aGl0ZXNwYWNlIGluIGVsZW1lbnQKLSAgICAgKiBjb250ZW50LiBTaW1pbGFyIHRvIGNoYXJhY3RlcnMoY2hhcltdLCBpbnQsIGludCkuCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQlfaGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcigpCi0gICAgICogUmVjZWl2ZSBhbiBvYmplY3QgZm9yIGxvY2F0aW5nIHRoZSBvcmlnaW4gb2YgU0FYIGRvY3VtZW50IGV2ZW50cy4gCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKSB7Ci0JLy8gTm90IGhhbmRsZWQgYnkgRE9NQnVpbGRlciAtIGlnbm9yZWQKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLnNraXBwZWRFbnRpdHkoKQotICAgICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgc2tpcHBlZCBlbnRpdHkuCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB7Ci0JLy8gTm90IGhhbmRsZWQgYnkgRE9NQnVpbGRlciAtIGlnbm9yZWQKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZygpCi0gICAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkgCi0JdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JX2hhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwgdXJpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcoKQotICAgICAqIEVuZCB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7Ci0JX2hhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguRFRESGFuZGxlci5ub3RhdGlvbkRlY2woKQotICAgICAqIEVuZCB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgICAqIFdlIGRvIG5vdCBoYW5kbGUgdGhpcyBtZXRob2QsIGFuZCB0aGUgaW5wdXQgaXMgcXVpZXRseSBpZ25vcmVkLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIG5vdGF0aW9uRGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHsKLQkvLyBOb3QgaGFuZGxlZCBieSBEVERNb25pdG9yIC0gaWdub3JlZAotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguRFRESGFuZGxlci51bnBhcnNlZEVudGl0eURlY2woKQotICAgICAqIEVuZCB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLAotCQkJCSAgIFN0cmluZyBzeXN0ZW1JZCwgU3RyaW5nIG5vdGF0aW9uTmFtZSkKLQl0aHJvd3MgU0FYRXhjZXB0aW9uIHsKLQkvLyBDcmVhdGUgbmV3IGNvbnRhaW5lZCBmb3IgdW5wYXJzZWQgZW50aXRpZXMKLQlpZiAoX2R0ZCA9PSBudWxsKSBfZHRkID0gbmV3IERURE1vbml0b3IoKTsKLQlfZHRkLnVucGFyc2VkRW50aXR5RGVjbChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsIG5vdGF0aW9uTmFtZSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIuc3RhcnREVEQoKQotICAgICAqIFdlIGRvIG5vdCBoYW5kbGUgdGhpcyBtZXRob2QsIGFuZCB0aGUgaW5wdXQgaXMgcXVpZXRseSBpZ25vcmVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB7IH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyLmVuZERURCgpCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmREVEQoKSB7IH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyLnN0YXJ0RW50aXR5KCkKLSAgICAgKiBXZSBkbyBub3QgaGFuZGxlIHRoaXMgbWV0aG9kLCBhbmQgdGhlIGlucHV0IGlzIHF1aWV0bHkgaWdub3JlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHN0YXJ0RW50aXR5KFN0cmluZyBuYW1lKSB7IH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyLmVuZEVudGl0eSgpCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHsgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIuc3RhcnRDREFUQSgpCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgeyB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlci5lbmRDREFUQSgpCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpIHsgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIuY29tbWVudCgpCi0gICAgICogV2UgZG8gbm90IGhhbmRsZSB0aGlzIG1ldGhvZCwgYW5kIHRoZSBpbnB1dCBpcyBxdWlldGx5IGlnbm9yZWQKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB7IH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheC9UcmFuc2Zvcm1lckltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgvVHJhbnNmb3JtZXJJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU2YzNmNWUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheC9UcmFuc2Zvcm1lckltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcyNSArMCwwIEBACi0vKgotICogQCgjKSRJZCQKLSAqCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEBhdXRob3IgRy4gVG9kZCBNaWxsZXIKLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnRyYXg7Ci0KLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5Xcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5SZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmEubmV0LlVSTDsKLWltcG9ydCBqYXZhLm5ldC5VUkxDb25uZWN0aW9uOwotaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLm5ldC5Vbmtub3duU2VydmljZUV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi1pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7Ci0KLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC4qOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLkRPTUNhY2hlOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci4qOwotCi1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBUcmFuc2Zvcm1lckltcGwgZXh0ZW5kcyBUcmFuc2Zvcm1lciBpbXBsZW1lbnRzIERPTUNhY2hlIHsKLQotICAgIHByaXZhdGUgQWJzdHJhY3RUcmFuc2xldCBfdHJhbnNsZXQgPSBudWxsOwotICAgIHByaXZhdGUgU3RyaW5nICAgICAgICAgICBfZW5jb2RpbmcgPSBudWxsOwotICAgIHByaXZhdGUgQ29udGVudEhhbmRsZXIgICBfaGFuZGxlciA9IG51bGw7Ci0KLSAgICBwcml2YXRlIEVycm9yTGlzdGVuZXIgX2Vycm9yTGlzdGVuZXIgPSBudWxsOwotICAgIHByaXZhdGUgVVJJUmVzb2x2ZXIgICBfdXJpUmVzb2x2ZXIgPSBudWxsOwotICAgIHByaXZhdGUgUHJvcGVydGllcyAgICBfcHJvcGVydGllcyA9IG51bGw7Ci0KLSAgICAvLyBVc2VkIGZvciBkZWZhdWx0IG91dHB1dCBwcm9wZXJ0eSBzZXR0aW5ncwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBFTVBUWV9TVFJJTkcgPSAiIjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgTk9fU1RSSU5HICAgID0gIm5vIjsKLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWUVTX1NUUklORyAgID0gInllcyI7Ci0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9TVFJJTkcgICA9ICJ4bWwiOwotCi0gICAgLy8gUHJlLXNldCBET01JbXBsIHRvIHVzZSBhcyBpbnB1dCAodXNlZCBvbmx5IHdpdGggVHJhbnNmb3JtZXJIYW5kbGVySW1wbCkKLSAgICBwcml2YXRlIERPTUltcGwgX2RvbSA9IG51bGw7Ci0gICAgCi0gICAgLy8gTGlzdCBhbGwgZXJyb3IgbWVzc2FnZXMgaGVyZQotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBUUkFOU0xFVF9FUlJfTVNHID0gCi0JIlRoZSB0cmFuc2Zvcm1lciBoYXMgbm8gZW5jYXBzdWxhdGVkIHRyYW5zbGV0IG9iamVjdC4iOwotICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBIQU5ETEVSX0VSUl9NU0cgPSAKLQkiTm8gZGVmaW5lZCBvdXRwdXQgaGFuZGxlciBmb3IgdHJhbnNmb3JtYXRpb24gcmVzdWx0LiI7Ci0gICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX0xJU1RFTkVSX05VTEwgPQotCSJBdHRlbXB0aW5nIHRvIHNldCBFcnJvckxpc3RlbmVyIGZvciBUcmFuc2Zvcm1lciB0byBudWxsIjsKLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5QVVRfU09VUkNFX0VNUFRZID0KLQkiVGhlIFNvdXJjZSBvYmplY3QgcGFzc2VkIHRvIHRyYW5zZm9ybSgpIGhhcyBubyBjb250ZW50cy4iOwotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBPVVRQVVRfUkVTVUxUX0VNUFRZID0KLQkiVGhlIFJlc3VsdCBvYmplY3QgcGFzc2VkIHRvIHRyYW5zZm9ybSgpIGlzIGludmFsaWQuIjsKLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyIGNvbnN0cnVjdG9yCi0gICAgICogT3VyIFRyYW5zZm9ybWVyIG9iamVjdHMgYWx3YXlzIG5lZWQgYSB0cmFuc2xldCB0byBkbyB0aGUgYWN0dWFsIHdvcmsKLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgVHJhbnNmb3JtZXJJbXBsKFRyYW5zbGV0IHRyYW5zbGV0KSB7Ci0JX3RyYW5zbGV0ID0gKEFic3RyYWN0VHJhbnNsZXQpdHJhbnNsZXQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgdHJhbnNsZXQgd3JhcHBlZCBpbnNpZGUgdGhpcyBUcmFuc2Zvcm1lcgotICAgICAqLwotICAgIHByb3RlY3RlZCBBYnN0cmFjdFRyYW5zbGV0IGdldFRyYW5zbGV0KCkgewotCXJldHVybihfdHJhbnNsZXQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLnRyYW5zZm9ybSgpCi0gICAgICoKLSAgICAgKiBAcGFyYW0gc291cmNlIENvbnRhaW5zIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQKLSAgICAgKiBAcGFyYW0gcmVzdWx0IFdpbGwgY29udGFpbiB0aGUgb3V0cHV0IGZyb20gdGhlIHRyYW5zZm9ybWF0aW9uCi0gICAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHRyYW5zZm9ybShTb3VyY2Ugc291cmNlLCBSZXN1bHQgcmVzdWx0KQotCXRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0KLQlpZiAoX3RyYW5zbGV0ID09IG51bGwpIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKFRSQU5TTEVUX0VSUl9NU0cpOwotCX0KLQotCV9oYW5kbGVyID0gZ2V0T3V0cHV0SGFuZGxlcihyZXN1bHQpOwotCWlmIChfaGFuZGxlciA9PSBudWxsKSB7IAotCSAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oSEFORExFUl9FUlJfTVNHKTsKLQl9Ci0KLQlpZiAoX3VyaVJlc29sdmVyICE9IG51bGwpIHsKLQkgICAgX3RyYW5zbGV0LnNldERPTUNhY2hlKHRoaXMpOwotCX0KLQotCS8vIFJ1biB0aGUgdHJhbnNmb3JtYXRpb24KLQl0cmFuc2Zvcm0oc291cmNlLCAoQ29udGVudEhhbmRsZXIpX2hhbmRsZXIsIF9lbmNvZGluZyk7Ci0KLQkvLyBJZiBhIERPTVJlc3VsdCwgdGhlbiB3ZSBtdXN0IHNldCB0aGUgRE9NIFRyZWUgc28gaXQgY2FuCi0JLy8gYmUgcmV0cmlldmVkIGxhdGVyIAotCWlmIChyZXN1bHQgaW5zdGFuY2VvZiBET01SZXN1bHQpIHsKLQkgICAgKChET01SZXN1bHQpcmVzdWx0KS5zZXROb2RlKCgoU0FYMkRPTSlfaGFuZGxlcikuZ2V0RE9NKCkpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYW4gb3V0cHV0IGhhbmRsZXIgKFNBWDIgaGFuZGxlcikgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQKLSAgICAgKiBiYXNlZCBvbiB0aGUgdHlwZSBhbmQgY29udGVudHMgb2YgdGhlIFRyQVggUmVzdWx0IG9iamVjdCBwYXNzZWQgdG8KLSAgICAgKiB0aGUgdHJhbnNmb3JtKCkgbWV0aG9kLiBPbmx5IFN0cmVhbVJlc3VsdCBhbmQgU0FYUmVzdWx0IGFyZSBjdXJyZW50bHkKLSAgICAgKiBoYW5kbGVkLgotICAgICAqLwotICAgIHByaXZhdGUgQ29udGVudEhhbmRsZXIgZ2V0T3V0cHV0SGFuZGxlcihSZXN1bHQgcmVzdWx0KSAKLQl0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gewotCS8vIFRyeSB0byBnZXQgdGhlIGVuY29kaW5nIGZyb20gVHJhbnNsZXQgKG1heSBub3QgYmUgc2V0KQotCWlmIChfdHJhbnNsZXQuX2VuY29kaW5nICE9IG51bGwpCi0JICAgIF9lbmNvZGluZyA9IF90cmFuc2xldC5fZW5jb2Rpbmc7Ci0JZWxzZQotCSAgICBfZW5jb2RpbmcgPSAidXRmLTgiOyAvLyBkZWZhdWx0IG91dHB1dCBlbmNvZGluZwotCi0JdHJ5IHsKLQkgICAgU3RyaW5nIHN5c3RlbUlkID0gcmVzdWx0LmdldFN5c3RlbUlkKCk7Ci0KLQkgICAgLy8gSGFuZGxlIFNBWFJlc3VsdCBvdXRwdXQgaGFuZGxlcgotCSAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgU0FYUmVzdWx0KSB7Ci0JCWZpbmFsIFNBWFJlc3VsdCB0YXJnZXQgPSAoU0FYUmVzdWx0KXJlc3VsdDsKLQkJZmluYWwgQ29udGVudEhhbmRsZXIgaGFuZGxlciA9IHRhcmdldC5nZXRIYW5kbGVyKCk7Ci0JCS8vIFNpbXBsZSBhcyBmZWNrLCBqdXN0IHBhc3MgdGhlIFNBWCBoYW5kbGVyIGJhY2suLi4KLQkJaWYgKGhhbmRsZXIgIT0gbnVsbCkgcmV0dXJuIGhhbmRsZXI7Ci0JICAgIH0KLQkgICAgLy8gSGFuZGxlIFN0cmVhbVJlc3VsdCBvdXRwdXQgaGFuZGxlcgotCSAgICBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTdHJlYW1SZXN1bHQpIHsKLQkJZmluYWwgU3RyZWFtUmVzdWx0IHRhcmdldCA9IChTdHJlYW1SZXN1bHQpcmVzdWx0OwotCQlmaW5hbCBPdXRwdXRTdHJlYW0gb3N0cmVhbSA9IHRhcmdldC5nZXRPdXRwdXRTdHJlYW0oKTsKLQkJZmluYWwgV3JpdGVyIHdyaXRlciA9IHRhcmdldC5nZXRXcml0ZXIoKTsKLQotCQlpZiAob3N0cmVhbSAhPSBudWxsKQotCQkgICAgcmV0dXJuIChuZXcgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIob3N0cmVhbSwgX2VuY29kaW5nKSk7Ci0JCWVsc2UgaWYgKHdyaXRlciAhPSBudWxsKQotCQkgICAgcmV0dXJuIChuZXcgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIod3JpdGVyLCBfZW5jb2RpbmcpKTsKLQkgICAgfQotCSAgICAvLyBIYW5kbGUgRE9NUmVzdWx0IG91dHB1dCBoYW5kbGVyCi0JICAgIGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIERPTVJlc3VsdCkgewotCQlyZXR1cm4gKG5ldyBTQVgyRE9NKCkpOwotCSAgICB9Ci0KLQkgICAgLy8gQ29tbW9uLCBmaW5hbCBoYW5kbGluZyBvZiBhbGwgaW5wdXQgc291cmNlcywgb25seSB1c2VkIGlmIHRoZQotCSAgICAvLyBvdGhlciBjb250ZW50cyBvZiB0aGUgUmVzdWx0IG9iamVjdCBjb3VsZCBub3QgYmUgdXNlZAotCSAgICBpZiAoc3lzdGVtSWQgIT0gbnVsbCkgewotCQlpZiAoKG5ldyBGaWxlKHN5c3RlbUlkKSkuZXhpc3RzKCkpCi0JCSAgICBzeXN0ZW1JZCA9ICJmaWxlOi8iK3N5c3RlbUlkOwotCQlmaW5hbCBVUkwgdXJsID0gbmV3IFVSTChzeXN0ZW1JZCk7Ci0JCWZpbmFsIFVSTENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOwotCQlmaW5hbCBPdXRwdXRTdHJlYW0gb3N0cmVhbSA9IGNvbm5lY3Rpb24uZ2V0T3V0cHV0U3RyZWFtKCk7Ci0JCXJldHVybihuZXcgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIob3N0cmVhbSwgX2VuY29kaW5nKSk7Ci0JICAgIH0KLQkgICAgZWxzZSB7Ci0JCXRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihPVVRQVVRfUkVTVUxUX0VNUFRZKTsKLQkgICAgfQotCX0KLQkvLyBJZiB3ZSBjYW5ub3Qgd3JpdGUgdG8gdGhlIGxvY2F0aW9uIHNwZWNpZmllZCBieSB0aGUgU3lzdGVtSWQKLQljYXRjaCAoVW5rbm93blNlcnZpY2VFeGNlcHRpb24gZSkgewotCSAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZSk7Ci0JfQotCS8vIElmIHdlIGNhbm5vdCBjcmVhdGUgYSBTQVgyRE9NIGFkYXB0ZXIKLQljYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0JICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbigKLQkJIlNBWDJET00gYWRhcHRlciBjb3VsZCBub3QgYmUgY3JlYXRlZCwgIiArIGUuZ2V0TWVzc2FnZSgpKTsKLQl9Ci0JLy8gSWYgd2UgY2Fubm90IGNyZWF0ZSB0aGUgZmlsZSBzcGVjaWZpZWQgYnkgdGhlIFN5c3RlbUlkCi0JY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgdGhlIGludGVybmFsIERPTUltcGwgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHRoZSBuZXh0IHRyYW5zZm9ybWF0aW9uCi0gICAgICovCi0gICAgcHJvdGVjdGVkIHZvaWQgc2V0RE9NKERPTUltcGwgZG9tKSB7Ci0JX2RvbSA9IGRvbTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCdWlsZHMgYW4gaW50ZXJuYWwgRE9NIGZyb20gYSBUckFYIFNvdXJjZSBvYmplY3QKLSAgICAgKi8KLSAgICBwcml2YXRlIERPTUltcGwgZ2V0RE9NKFNvdXJjZSBzb3VyY2UsIGludCBtYXNrKQotCXRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB7Ci0JdHJ5IHsKLQkgICAgLy8gVXNlIHRoZSBwcmUtZGVmaW5lZCBET00gaWYgcHJlc2VudAotCSAgICBpZiAoX2RvbSAhPSBudWxsKSB7Ci0JCURPTUltcGwgZG9tID0gX2RvbTsKLQkJX2RvbSA9IG51bGw7IC8vIHVzZSBvbmx5IG9uY2UsIHNvIHJlc2V0IHRvICdudWxsJwotCQlyZXR1cm4oZG9tKTsKLQkgICAgfQotCi0JICAgIC8vIENyZWF0ZSBhbiBpbnRlcm5hbCBET00gKG5vdCBXM0MpIGFuZCBnZXQgU0FYMiBpbnB1dCBoYW5kbGVyCi0JICAgIGZpbmFsIERPTUltcGwgZG9tID0gbmV3IERPTUltcGwoKTsKLQkgICAgZmluYWwgQ29udGVudEhhbmRsZXIgaW5wdXRIYW5kbGVyID0gZG9tLmdldEJ1aWxkZXIoKTsKLQotCSAgICAvLyBDcmVhdGUgYSBEVERNb25pdG9yIHRoYXQgd2lsbCB0cmFjZSBhbGwgdW5wYXJzZWQgZW50aXR5IFVSSXMKLQkgICAgZmluYWwgRFRETW9uaXRvciBkdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLQotCSAgICAvLyBIYW5kbGUgU0FYU291cmNlIGlucHV0Ci0JICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBTQVhTb3VyY2UpIHsKLQkJLy8gR2V0IGFsbCBpbmZvIGZyb20gdGhlIGlucHV0IFNBWFNvdXJjZSBvYmplY3QKLQkJZmluYWwgU0FYU291cmNlICAgc2F4ICAgID0gKFNBWFNvdXJjZSlzb3VyY2U7Ci0JCWZpbmFsIFhNTFJlYWRlciAgIHJlYWRlciA9IHNheC5nZXRYTUxSZWFkZXIoKTsKLQkJZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgID0gc2F4LmdldElucHV0U291cmNlKCk7Ci0JCWZpbmFsIFN0cmluZyAgICAgIHN5c3RlbUlkID0gc2F4LmdldFN5c3RlbUlkKCk7Ci0JCWR0ZE1vbml0b3IuaGFuZGxlRFREKHJlYWRlcik7Ci0JCXJlYWRlci5zZXRDb250ZW50SGFuZGxlcihpbnB1dEhhbmRsZXIpOwotCQlyZWFkZXIucGFyc2UoaW5wdXQpOwotCQlkb20uc2V0RG9jdW1lbnRVUkkoc3lzdGVtSWQpOwotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSBET01Tb3VyY2UgaW5wdXQKLQkgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgRE9NU291cmNlKSB7Ci0JCWZpbmFsIERPTVNvdXJjZSAgIGRvbXNyYyA9IChET01Tb3VyY2Upc291cmNlOwotCQlmaW5hbCBEb2N1bWVudCAgICB0cmVlID0gKERvY3VtZW50KWRvbXNyYy5nZXROb2RlKCk7Ci0JCWZpbmFsIERPTTJTQVggICAgIGRvbTJzYXggPSBuZXcgRE9NMlNBWCh0cmVlKTsKLQkJZmluYWwgSW5wdXRTb3VyY2UgaW5wdXQgPSBudWxsOyAKLQkJZmluYWwgU3RyaW5nICAgICAgc3lzdGVtSWQgPSBkb21zcmMuZ2V0U3lzdGVtSWQoKTsgCi0JCWR0ZE1vbml0b3IuaGFuZGxlRFREKGRvbTJzYXgpOwotCQlkb20yc2F4LnNldENvbnRlbnRIYW5kbGVyKGlucHV0SGFuZGxlcik7Ci0JCWRvbTJzYXgucGFyc2UoaW5wdXQpOyAvLyBuZWVkIHRoaXMgcGFyYW1ldGVyPwotCQlkb20uc2V0RG9jdW1lbnRVUkkoc3lzdGVtSWQpOwotCSAgICB9Ci0JICAgIC8vIEhhbmRsZSBTdHJlYW1Tb3VyY2UgaW5wdXQKLQkgICAgZWxzZSBpZiAoc291cmNlIGluc3RhbmNlb2YgU3RyZWFtU291cmNlKSB7Ci0JCS8vIFdpdGggYSBTdHJlYW1Tb3VyY2Ugd2UgbmVlZCB0byBjcmVhdGUgb3VyIG93biBwYXJzZXIKLQkJZmluYWwgU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0gU0FYUGFyc2VyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCQlmaW5hbCBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLQkJZmluYWwgWE1MUmVhZGVyIHJlYWRlciA9IHBhcnNlci5nZXRYTUxSZWFkZXIoKTsKLQkJZHRkTW9uaXRvci5oYW5kbGVEVEQocmVhZGVyKTsKLQotCQkvLyBHZXQgYWxsIGluZm8gZnJvbSB0aGUgaW5wdXQgU3RyZWFtU291cmNlIG9iamVjdAotCQlmaW5hbCBTdHJlYW1Tb3VyY2Ugc3RyZWFtID0gKFN0cmVhbVNvdXJjZSlzb3VyY2U7Ci0JCWZpbmFsIElucHV0U3RyZWFtICBzdHJlYW1JbnB1dCA9IHN0cmVhbS5nZXRJbnB1dFN0cmVhbSgpOwotCQlmaW5hbCBSZWFkZXIgc3RyZWFtUmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpOwotCQlmaW5hbCBTdHJpbmcgc3lzdGVtSWQgPSBzdHJlYW0uZ2V0U3lzdGVtSWQoKTsKLQotCQlyZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoaW5wdXRIYW5kbGVyKTsKLQkJCi0JCUlucHV0U291cmNlIGlucHV0OwotCQlpZiAoc3RyZWFtSW5wdXQgIT0gbnVsbCkKLQkJICAgIGlucHV0ID0gbmV3IElucHV0U291cmNlKHN0cmVhbUlucHV0KTsKLQkJZWxzZSBpZiAoc3RyZWFtUmVhZGVyICE9IG51bGwpCi0JCSAgICBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShzdHJlYW1SZWFkZXIpOwotCQllbHNlIGlmIChzeXN0ZW1JZCAhPSBudWxsKQotCQkgICAgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2Uoc3lzdGVtSWQpOwotCQllbHNlCi0JCSAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oSU5QVVRfU09VUkNFX0VNUFRZKTsKLQkJcmVhZGVyLnBhcnNlKGlucHV0KTsKLQkJZG9tLnNldERvY3VtZW50VVJJKHN5c3RlbUlkKTsKLQkgICAgfQotCSAgICBlbHNlIHsKLQkJcmV0dXJuIG51bGw7Ci0JICAgIH0KLQotCSAgICAvLyBTZXQgc2l6ZSBvZiBrZXkvaWQgaW5kaWNlcwotCSAgICBfdHJhbnNsZXQuc2V0SW5kZXhTaXplKGRvbS5nZXRTaXplKCkpOwotCSAgICAvLyBJZiB0aGVyZSBhcmUgYW55IGVsZW1lbnRzIHdpdGggSUQgYXR0cmlidXRlcywgYnVpbGQgYW4gaW5kZXgKLQkgICAgZHRkTW9uaXRvci5idWlsZElkSW5kZXgoZG9tLCBtYXNrLCBfdHJhbnNsZXQpOwotCSAgICAvLyBQYXNzIHVucGFyc2VkIGVudGl0eSBVUklzIHRvIHRoZSB0cmFuc2xldAotCSAgICBfdHJhbnNsZXQuc2V0RFRETW9uaXRvcihkdGRNb25pdG9yKTsKLQkgICAgcmV0dXJuIGRvbTsKLQl9Ci0JY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0JICAgIGlmIChfZXJyb3JMaXN0ZW5lciAhPSBudWxsKQotCQlwb3N0RXJyb3JUb0xpc3RlbmVyKCJGaWxlIG5vdCBmb3VuZDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLQljYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKLQkgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0JCXBvc3RFcnJvclRvTGlzdGVuZXIoIk1hbGZvcm1lZCBVUkw6ICIgKyBlLmdldE1lc3NhZ2UoKSk7Ci0JICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLQl9Ci0JY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIGUpIHsKLQkgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0JCXBvc3RFcnJvclRvTGlzdGVuZXIoIkNhbm5vdCByZXNvbHZlIFVSSTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0JCXBvc3RFcnJvclRvTGlzdGVuZXIoIkludGVybmFsIGVycm9yOiAiICsgZS5nZXRNZXNzYWdlKCkpOyAKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLSAgICB9Ci0gCi0gICAgLyoqCi0gICAgICogSW50ZXJuYWwgdHJhbnNmb3JtYXRpb24gbWV0aG9kIC0gdXNlcyB0aGUgaW50ZXJuYWwgQVBJcyBvZiBYU0xUQwotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHNyYywgQ29udGVudEhhbmRsZXIgc2F4LCBTdHJpbmcgZW5jb2RpbmcpCi0JdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHsKLQl0cnkgewotCSAgICAvLyBCdWlsZCBhbiBpdGVybmFsIERPTUltcGwgZnJvbSB0aGUgVHJBWCBTb3VyY2UKLQkgICAgRE9NSW1wbCBkb20gPSBnZXRET00oc3JjLCAwKTsKLQotCSAgICAvLyBQYXNzIG91dHB1dCBwcm9wZXJ0aWVzIHRvIHRoZSB0cmFuc2xldAotCSAgICBzZXRPdXRwdXRQcm9wZXJ0aWVzKF90cmFuc2xldCwgX3Byb3BlcnRpZXMpOwotCSAgICAKLQkgICAgLy8gVGhpcyBoYW5kbGVyIHdpbGwgcG9zdC1wcm9jZXNzIHRoZSB0cmFuc2xldCBvdXRwdXQKLQkgICAgVGV4dE91dHB1dCBoYW5kbGVyOwotCi0JICAgIC8vIENoZWNrIGlmIHRoZSBDb250ZW50SGFuZGxlciBhbHNvIGltcGxlbWVudHMgTGV4aWNhbEhhbmRsZXIKLQkgICAgaWYgKHNheCBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotCQloYW5kbGVyID0gbmV3IFRleHRPdXRwdXQoc2F4LCAoTGV4aWNhbEhhbmRsZXIpc2F4LCBlbmNvZGluZyk7Ci0JICAgIGVsc2UKLQkJaGFuZGxlciA9IG5ldyBUZXh0T3V0cHV0KHNheCwgZW5jb2RpbmcpOwotCSAgICBfdHJhbnNsZXQudHJhbnNmb3JtKGRvbSwgaGFuZGxlcik7Ci0JfQotCWNhdGNoIChUcmFuc2xldEV4Y2VwdGlvbiBlKSB7Ci0JICAgIGlmIChfZXJyb3JMaXN0ZW5lciAhPSBudWxsKQotCQlwb3N0RXJyb3JUb0xpc3RlbmVyKGUuZ2V0TWVzc2FnZSgpKTsKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLQljYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7Ci0JICAgIGlmIChfZXJyb3JMaXN0ZW5lciAhPSBudWxsKQotCQlwb3N0RXJyb3JUb0xpc3RlbmVyKCJSdW50aW1lIEVycm9yOiAiICsgZS5nZXRNZXNzYWdlKCkpOwotCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiAiK2UuZ2V0TWVzc2FnZSgpKTsKLQkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLQljYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0JCXBvc3RFcnJvclRvTGlzdGVuZXIoIkludGVybmFsIGVycm9yOiAiICsgZS5nZXRNZXNzYWdlKCkpOyAKLQkgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGUpOwotCX0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5nZXRFcnJvckxpc3RlbmVyKCkKLSAgICAgKiBHZXQgdGhlIGVycm9yIGV2ZW50IGhhbmRsZXIgaW4gZWZmZWN0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBlcnJvciBldmVudCBoYW5kbGVyIGN1cnJlbnRseSBpbiBlZmZlY3QKLSAgICAgKi8KLSAgICBwdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkgeyAgCi0JcmV0dXJuIF9lcnJvckxpc3RlbmVyOyAKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5zZXRFcnJvckxpc3RlbmVyKCkKLSAgICAgKiBTZXQgdGhlIGVycm9yIGV2ZW50IGxpc3RlbmVyIGluIGVmZmVjdCBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBlcnJvciBldmVudCBsaXN0ZW5lciB0byB1c2UKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikKLQl0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLSAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpCi0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKEVSUk9SX0xJU1RFTkVSX05VTEwpOwotICAgICAgICBfZXJyb3JMaXN0ZW5lciA9IGxpc3RlbmVyOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluZm9ybSBUckFYIGVycm9yIGxpc3RlbmVyIG9mIGFuIGVycm9yCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBvc3RFcnJvclRvTGlzdGVuZXIoU3RyaW5nIG1lc3NhZ2UpIHsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIF9lcnJvckxpc3RlbmVyLmVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtZXNzYWdlKSk7Ci0JfQotCWNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICAgICAvLyBpZ25vcmVkIC0gdHJhbnNmb3JtYXRpb24gY2Fubm90IGJlIGNvbnRpbnVlZAotICAgICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW5mb3JtIFRyQVggZXJyb3IgbGlzdGVuZXIgb2YgYSB3YXJuaW5nCi0gICAgICovCi0gICAgcHJpdmF0ZSB2b2lkIHBvc3RXYXJuaW5nVG9MaXN0ZW5lcihTdHJpbmcgbWVzc2FnZSkgewotICAgICAgICB0cnkgewotICAgICAgICAgICAgX2Vycm9yTGlzdGVuZXIud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obWVzc2FnZSkpOwotICAgICAgICB9Ci0JY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgICAgIC8vIGlnbm9yZWQgLSB0cmFuc2Zvcm1hdGlvbiBjYW5ub3QgYmUgY29udGludWVkCi0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5nZXRPdXRwdXRQcm9wZXJ0aWVzKCkuCi0gICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIG91dHB1dCBwcm9wZXJ0aWVzIGZvciB0aGUgdHJhbnNmb3JtYXRpb24uIE5vdGUgdGhhdAotICAgICAqIHRoaXMgbWV0aG9kIHdpbGwgb25seSByZXR1cm4gcHJvcGVydGllcyB0aGF0IHdlcmUgc2V0IGluIHRoaXMgY2xhc3MuCi0gICAgICogVGhlIG91dHB1dCBzZXR0aW5ncyBkZWZpbmVkIGluIHRoZSBzdHlsZXNoZWV0J3MgPHhzbDpvdXRwdXQ+IGVsZW1lbnQKLSAgICAgKiBhbmQgZGVmYXVsdCBYU0xUIG91dHB1dCBzZXR0aW5ncyB3aWxsIG5vdCBiZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gUHJvcGVydGllcyBleHBsaWNpdGx5IHNldCBmb3IgdGhpcyBUcmFuc2Zvcm1lcgotICAgICAqLwotICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldE91dHB1dFByb3BlcnRpZXMoKSB7Ci0JcmV0dXJuKF9wcm9wZXJ0aWVzKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgdHJhbnNsZXQgc3RvcmVzIGFsbCBDREFUQSBzZWN0aW9ucyBzZXQgaW4gdGhlIDx4c2w6b3V0cHV0PiBlbGVtZW50Ci0gICAgICogaW4gYSBIYXNodGFibGUuIFRoaXMgbWV0aG9kIHdpbGwgcmUtY29uc3RydWN0IHRoZSB3aGl0ZXNwYWNlIHNlcGFyYXRlZAotICAgICAqIGxpc3Qgb2YgZWxlbWVudHMgZ2l2ZW4gaW4gdGhlIDx4c2w6b3V0cHV0PiBlbGVtZW50LgotICAgICAqLwotICAgIHByaXZhdGUgU3RyaW5nIG1ha2VDREFUQVN0cmluZyhIYXNodGFibGUgY2RhdGEpIHsKLQkvLyBSZXR1cm4gYSAnbnVsbCcgc3RyaW5nIGlmIG5vIENEQVRBIHNlY3Rpb24gZWxlbWVudHMgd2VyZSBzcGVjaWZpZWQKLQlpZiAoY2RhdGEgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0KLQlTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0JLy8gR2V0IGFuIGVudW1lcmF0aW9uIG9mIGFsbCB0aGUgZWxlbWVudHMgaW4gdGhlIGhhc2h0YWJsZQotCUVudW1lcmF0aW9uIGVsZW1lbnRzID0gY2RhdGEua2V5cygpOwotCWlmIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICByZXN1bHQuYXBwZW5kKChTdHJpbmcpZWxlbWVudHMubmV4dEVsZW1lbnQoKSk7Ci0JICAgIHdoaWxlIChlbGVtZW50cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQlTdHJpbmcgZWxlbWVudCA9IChTdHJpbmcpZWxlbWVudHMubmV4dEVsZW1lbnQoKTsKLQkJcmVzdWx0LmFwcGVuZCgnICcpOwotCQlyZXN1bHQuYXBwZW5kKGVsZW1lbnQpOwotCSAgICB9Ci0JfQotCQotCXJldHVybihyZXN1bHQudG9TdHJpbmcoKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBKQVhQJ3MgVHJhbnNmb3JtZXIuZ2V0T3V0cHV0UHJvcGVydHkoKS4KLSAgICAgKiBHZXQgYW4gb3V0cHV0IHByb3BlcnR5IHRoYXQgaXMgaW4gZWZmZWN0IGZvciB0aGUgdHJhbnNmb3JtYXRpb24uIFRoZQotICAgICAqIHByb3BlcnR5IHNwZWNpZmllZCBtYXkgYmUgYSBwcm9wZXJ0eSB0aGF0IHdhcyBzZXQgd2l0aCBzZXRPdXRwdXRQcm9wZXJ0eSwKLSAgICAgKiBvciBpdCBtYXkgYmUgYSBwcm9wZXJ0eSBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBBIG5vbi1udWxsIHN0cmluZyB0aGF0IGNvbnRhaW5zIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eQotICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBwcm9wZXJ0eSBuYW1lIGlzIG5vdCBrbm93bgotICAgICAqLwotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0JdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0KLQlTdHJpbmcgdmFsdWUgPSBudWxsOwotCi0JLy8gTGV2ZWwxOiBDaGVjayBpZiB0aGUgcHJvcGVydHkgaXMgb3ZlcnJpZGRlbiBpbiB0aGlzIFRyYW5zZm9ybWVyCi0JaWYgKF9wcm9wZXJ0aWVzICE9IG51bGwpIHZhbHVlID0gX3Byb3BlcnRpZXMuZ2V0UHJvcGVydHkobmFtZSk7Ci0KLQkvLyBMZXZlbDI6IENoZWNrIGlmIHRoZSBwcm9wZXJ0eSB2YWx1ZSBpcyBzZXQgaW4gdGhlIHRyYW5zbGV0Ci0JaWYgKCh2YWx1ZSA9PSBudWxsKSAmJiAoX3RyYW5zbGV0ICE9IG51bGwpKSB7Ci0JICAgIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkVOQ09ESU5HKSkKLQkJdmFsdWUgPSBfdHJhbnNsZXQuX2VuY29kaW5nOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk1FVEhPRCkpCi0JCXZhbHVlID0gX3RyYW5zbGV0Ll9tZXRob2Q7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuSU5ERU5UKSkKLQkJdmFsdWUgPSAobmV3IEJvb2xlYW4oX3RyYW5zbGV0Ll9pbmRlbnQpKS50b1N0cmluZygpOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkRPQ1RZUEVfUFVCTElDKSkKLQkJdmFsdWUgPSBfdHJhbnNsZXQuX2RvY3R5cGVQdWJsaWM7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRE9DVFlQRV9TWVNURU0pKQotCQl2YWx1ZSA9IF90cmFuc2xldC5fZG9jdHlwZVN5c3RlbTsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5DREFUQV9TRUNUSU9OX0VMRU1FTlRTKSkKLQkJdmFsdWUgPSBtYWtlQ0RBVEFTdHJpbmcoX3RyYW5zbGV0Ll9jZGF0YSk7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuTUVESUFfVFlQRSkpCi0JCXZhbHVlID0gX3RyYW5zbGV0Ll9tZWRpYVR5cGU7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuT01JVF9YTUxfREVDTEFSQVRJT04pKQotCQl2YWx1ZSA9IChuZXcgQm9vbGVhbihfdHJhbnNsZXQuX29taXRIZWFkZXIpKS50b1N0cmluZygpOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLlNUQU5EQUxPTkUpKQotCQl2YWx1ZSA9IF90cmFuc2xldC5fc3RhbmRhbG9uZTsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5WRVJTSU9OKSkKLQkJdmFsdWUgPSBfdHJhbnNsZXQuX3ZlcnNpb247Ci0JfQotCi0JLy8gTGV2ZWwzOiBSZXR1cm4gdGhlIGRlZmF1bHQgcHJvcGVydHkgdmFsdWUKLQlpZiAodmFsdWUgPT0gbnVsbCkgewotCSAgICBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5FTkNPRElORykpCi0JCXZhbHVlID0gInV0Zi04IjsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5NRVRIT0QpKQotCQl2YWx1ZSA9IFhNTF9TVFJJTkc7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuSU5ERU5UKSkKLQkJdmFsdWUgPSBOT19TVFJJTkc7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRE9DVFlQRV9QVUJMSUMpKQotCQl2YWx1ZSA9IEVNUFRZX1NUUklORzsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5ET0NUWVBFX1NZU1RFTSkpCi0JCXZhbHVlID0gRU1QVFlfU1RSSU5HOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkNEQVRBX1NFQ1RJT05fRUxFTUVOVFMpKQotCQl2YWx1ZSA9IEVNUFRZX1NUUklORzsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5NRURJQV9UWVBFKSkKLQkJdmFsdWUgPSAidGV4dC94bWwiOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OKSkKLQkJdmFsdWUgPSBOT19TVFJJTkc7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuU1RBTkRBTE9ORSkpCi0JCXZhbHVlID0gTk9fU1RSSU5HOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLlZFUlNJT04pKQotCQl2YWx1ZSA9ICIxLjAiOwotCX0KLQotCXJldHVybiB2YWx1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5zZXRPdXRwdXRQcm9wZXJ0aWVzKCkuCi0gICAgICogU2V0IHRoZSBvdXRwdXQgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGVzZSBwcm9wZXJ0aWVzCi0gICAgICogd2lsbCBvdmVycmlkZSBwcm9wZXJ0aWVzIHNldCBpbiB0aGUgVGVtcGxhdGVzIHdpdGggeHNsOm91dHB1dC4KLSAgICAgKiBVbnJlY29nbmlzZWQgcHJvcGVydGllcyB3aWxsIGJlIHF1aXRlbHkgaWdub3JlZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzIFRoZSBwcm9wZXJ0aWVzIHRvIHVzZSBmb3IgdGhlIFRyYW5zZm9ybWVyCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gTmV2ZXIsIGVycm9ycyBhcmUgaWdub3JlZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE91dHB1dFByb3BlcnRpZXMoUHJvcGVydGllcyBwcm9wZXJ0aWVzKQotCXRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotCV9wcm9wZXJ0aWVzID0gcHJvcGVydGllczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbXBsZW1lbnRzIEpBWFAncyBUcmFuc2Zvcm1lci5zZXRPdXRwdXRQcm9wZXJ0eSgpLgotICAgICAqIEdldCBhbiBvdXRwdXQgcHJvcGVydHkgdGhhdCBpcyBpbiBlZmZlY3QgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4gVGhlCi0gICAgICogcHJvcGVydHkgc3BlY2lmaWVkIG1heSBiZSBhIHByb3BlcnR5IHRoYXQgd2FzIHNldCB3aXRoIAotICAgICAqIHNldE91dHB1dFByb3BlcnR5KCksIG9yIGl0IG1heSBiZSBhIHByb3BlcnR5IHNwZWNpZmllZCBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQKLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbiB0byB0aGUgcHJvcGVydHkKLSAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBOZXZlciwgZXJyb3JzIGFyZSBpZ25vcmVkCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLQl0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKLQlpZiAoX3Byb3BlcnRpZXMgPT0gbnVsbCkgX3Byb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOwotCV9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBJbnRlcm5hbCBtZXRob2QgdG8gcGFzcyBhbnkgcHJvcGVydGllcyB0byB0aGUgdHJhbnNsZXQgcHJpb3IgdG8KLSAgICAgKiBpbml0aWF0aW5nIHRoZSB0cmFuc2Zvcm1hdGlvbgotICAgICAqLwotICAgIHByaXZhdGUgdm9pZCBzZXRPdXRwdXRQcm9wZXJ0aWVzKEFic3RyYWN0VHJhbnNsZXQgdHJhbnNsZXQsCi0JCQkJICAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMpIHsKLQkvLyBSZXR1cm4gcmlnaHQgbm93IGlmIG5vIHByb3BlcnRpZXMgYXJlIHNldAotCWlmIChwcm9wZXJ0aWVzID09IG51bGwpIHJldHVybjsKLQotCS8vIEdldCBhIGxpc3Qgb2YgYWxsIHRoZSBkZWZpbmVkIHByb3BlcnRpZXMKLQlFbnVtZXJhdGlvbiBuYW1lcyA9IHByb3BlcnRpZXMucHJvcGVydHlOYW1lcygpOwotCXdoaWxlIChuYW1lcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCSAgICAvLyBHZXQgdGhlIG5leHQgcHJvcGVydHkgbmFtZSBhbmQgdmFsdWUKLQkgICAgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKW5hbWVzLm5leHRFbGVtZW50KCk7Ci0JICAgIFN0cmluZyB2YWx1ZSA9IHByb3BlcnRpZXMuZ2V0UHJvcGVydHkobmFtZSk7Ci0KLQkgICAgLy8gUGFzcyBwcm9wZXJ0eSB2YWx1ZSB0byB0cmFuc2xldCAtIG92ZXJyaWRlIHByZXZpb3VzIHNldHRpbmcKLQkgICAgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRU5DT0RJTkcpKQotCQl0cmFuc2xldC5fZW5jb2RpbmcgPSB2YWx1ZTsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5NRVRIT0QpKQotCQl0cmFuc2xldC5fbWV0aG9kID0gdmFsdWU7Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuRE9DVFlQRV9QVUJMSUMpKQotCQl0cmFuc2xldC5fZG9jdHlwZVB1YmxpYyA9IHZhbHVlOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLkRPQ1RZUEVfU1lTVEVNKSkKLQkJdHJhbnNsZXQuX2RvY3R5cGVTeXN0ZW0gPSB2YWx1ZTsKLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5NRURJQV9UWVBFKSkKLQkJdHJhbnNsZXQuX21lZGlhVHlwZSA9IHZhbHVlOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLlNUQU5EQUxPTkUpKQotCQl0cmFuc2xldC5fc3RhbmRhbG9uZSA9IHZhbHVlOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLlZFUlNJT04pKQotCQl0cmFuc2xldC5fdmVyc2lvbiA9IHZhbHVlOwotCSAgICBlbHNlIGlmIChuYW1lLmVxdWFscyhPdXRwdXRLZXlzLk9NSVRfWE1MX0RFQ0xBUkFUSU9OKSkgewotCQlpZiAoKHZhbHVlICE9IG51bGwpID09ICh2YWx1ZS50b0xvd2VyQ2FzZSgpLmVxdWFscygidHJ1ZSIpKSkgewotCQkgICAgdHJhbnNsZXQuX29taXRIZWFkZXIgPSB0cnVlOwotCQl9Ci0JICAgIH0KLQkgICAgZWxzZSBpZiAobmFtZS5lcXVhbHMoT3V0cHV0S2V5cy5JTkRFTlQpKSB7Ci0JCWlmICgodmFsdWUgIT0gbnVsbCkgPT0gKHZhbHVlLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ0cnVlIikpKSB7Ci0JCSAgICB0cmFuc2xldC5faW5kZW50ID0gdHJ1ZTsKLQkJfQotCSAgICB9Ci0JICAgIGVsc2UgaWYgKG5hbWUuZXF1YWxzKE91dHB1dEtleXMuQ0RBVEFfU0VDVElPTl9FTEVNRU5UUykpIHsKLQkJdHJhbnNsZXQuX2NkYXRhID0gbnVsbDsgLy8gSW1wb3J0YW50IC0gY2xlYXIgcHJldmlvdXMgc2V0dGluZwotCQlTdHJpbmdUb2tlbml6ZXIgZSA9IG5ldyBTdHJpbmdUb2tlbml6ZXIodmFsdWUpOwotCQl3aGlsZSAoZS5oYXNNb3JlVG9rZW5zKCkpIHsKLQkJICAgIHRyYW5zbGV0LmFkZENkYXRhRWxlbWVudChlLm5leHRUb2tlbigpKTsKLQkJfQotCSAgICB9Ci0KLQl9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBKQVhQJ3MgVHJhbnNmb3JtZXIuc2V0UGFyYW1ldGVyKCkKLSAgICAgKiBBZGQgYSBwYXJhbWV0ZXIgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi4gVGhlIHBhcmFtZXRlciBpcyBzaW1wbHkgcGFzc2VkCi0gICAgICogb24gdG8gdGhlIHRyYW5zbGV0IC0gbm8gdmFsaWRhdGlvbiBpcyBwZXJmb3JtZWQgLSBzbyBhbnkgdW51c2VkCi0gICAgICogcGFyYW1ldGVycyBhcmUgcXVpdGVseSBpZ25vcmVkIGJ5IHRoZSB0cmFuc2xldC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIKLSAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbiB0byB0aGUgcGFyYW1ldGVyCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lLCBPYmplY3QgdmFsdWUpIHsgCi0JX3RyYW5zbGV0LmFkZFBhcmFtZXRlcihuYW1lLCB2YWx1ZSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmNsZWFyUGFyYW1ldGVycygpCi0gICAgICogQ2xlYXIgYWxsIHBhcmFtZXRlcnMgc2V0IHdpdGggc2V0UGFyYW1ldGVyLiBDbGVhcnMgdGhlIHRyYW5zbGV0J3MKLSAgICAgKiBwYXJhbWV0ZXIgc3RhY2suCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCkgeyAgCi0JX3RyYW5zbGV0LmNsZWFyUGFyYW1ldGVycygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmdldFBhcmFtZXRlcigpCi0gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBnaXZlbiBwYXJhbWV0ZXIuIE5vdGUgdGhhdCB0aGUgdHJhbnNsZXQgd2lsbCBub3QKLSAgICAgKiBrZWVwIHZhbHVlcyBmb3IgcGFyYW1ldGVycyB0aGF0IHdlcmUgbm90IGRlZmluZWQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyCi0gICAgICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgdmFsdWUgYXNzaWduZWQgdG8gdGhlIHBhcmFtZXRlcgotICAgICAqLwotICAgIHB1YmxpYyBmaW5hbCBPYmplY3QgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKSB7Ci0JcmV0dXJuKF90cmFuc2xldC5nZXRQYXJhbWV0ZXIobmFtZSkpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEltcGxlbWVudHMgSkFYUCdzIFRyYW5zZm9ybWVyLmdldFVSSVJlc29sdmVyKCkKLSAgICAgKiBTZXQgdGhlIG9iamVjdCBjdXJyZW50bHkgdXNlZCB0byByZXNvbHZlIFVSSXMgdXNlZCBpbiBkb2N1bWVudCgpLgotICAgICAqCi0gICAgICogQHJldHVybnMgVGhlIFVSTFJlc29sdmVyIG9iamVjdCBjdXJyZW50bHkgaW4gdXNlCi0gICAgICovCi0gICAgcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkgewotCXJldHVybiBfdXJpUmVzb2x2ZXI7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogSW1wbGVtZW50cyBKQVhQJ3MgVHJhbnNmb3JtZXIuc2V0VVJJUmVzb2x2ZXIoKQotICAgICAqIFNldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4gZG9jdW1lbnQoKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSByZXNvbHZlciBUaGUgVVJJUmVzb2x2ZXIgdG8gdXNlIGluIGRvY3VtZW50KCkKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcikgeyAKLQlfdXJpUmVzb2x2ZXIgPSByZXNvbHZlcjsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGlzIGNsYXNzIHNob3VsZCBvbmx5IGJlIHVzZWQgYXMgYSBET01DYWNoZSBmb3IgdGhlIHRyYW5zbGV0IGlmIHRoZQotICAgICAqIFVSSVJlc29sdmVyIGhhcyBiZWVuIHNldC4KLSAgICAgKgotICAgICAqIFRoZSBtZXRob2QgaW1wbGVtZW50cyBYU0xUQydzIERPTUNhY2hlIGludGVyZmFjZSwgd2hpY2ggaXMgdXNlZCB0bwotICAgICAqIHBsdWcgaW4gYW4gZXh0ZXJuYWwgZG9jdW1lbnQgbG9hZGVyIGludG8gYSB0cmFuc2xldC4gVGhpcyBtZXRob2QgYWN0cwotICAgICAqIGFzIGFuIGFkYXB0ZXIgYmV0d2VlbiBUckFYJ3MgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlIGFuZCBYU0xUQydzCi0gICAgICogRE9NQ2FjaGUgaW50ZXJmYWNlLiBUaGlzIGFwcHJvYWNoIGlzIHNpbXBsZSwgYnV0IHJlbW92ZXMgdGhlCi0gICAgICogcG9zc2liaWxpdHkgb2YgdXNpbmcgZXh0ZXJuYWwgZG9jdW1lbnQgY2FjaGVzIHdpdGggWFNMVEMuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpICBBbiBVUkkgcG9pbnRpbmcgdG8gdGhlIGRvY3VtZW50IGxvY2F0aW9uCi0gICAgICogQHBhcmFtIG1hc2sgQ29udGFpbnMgYSBkb2N1bWVudCBJRCAocGFzc2VkIGZyb20gdGhlIHRyYW5zbGV0KQotICAgICAqIEBwYXJhbSB0cmFuc2xldCBBIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNsZXQgcmVxdWVzdGluZyB0aGUgZG9jdW1lbnQKLSAgICAgKi8KLSAgICBwdWJsaWMgRE9NSW1wbCByZXRyaWV2ZURvY3VtZW50KFN0cmluZyB1cmksIGludCBtYXNrLCBUcmFuc2xldCB0cmFuc2xldCkgewotCXRyeSB7Ci0JICAgIHJldHVybihnZXRET00oX3VyaVJlc29sdmVyLnJlc29sdmUodXJpLCAiIiksIG1hc2spKTsKLQl9Ci0JY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIGUpIHsKLQkgICAgaWYgKF9lcnJvckxpc3RlbmVyICE9IG51bGwpCi0JCXBvc3RFcnJvclRvTGlzdGVuZXIoIkZpbGUgbm90IGZvdW5kOiAiICsgZS5nZXRNZXNzYWdlKCkpOwotCSAgICByZXR1cm4obnVsbCk7Ci0JfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3V0aWwvSW50ZWdlckFycmF5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy91dGlsL0ludGVnZXJBcnJheS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjM2EyMjk3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3V0aWwvSW50ZWdlckFycmF5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjkgKzAsMCBAQAotLyoKLSAqIEAoIykkSWQkCi0gKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKgotICogQGF1dGhvciBKYWNlayBBbWJyb3ppYWsKLSAqCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWw7Ci0KLXB1YmxpYyBmaW5hbCBjbGFzcyBJbnRlZ2VyQXJyYXkgewotICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJbml0aWFsU2l6ZSA9IDMyOwotICAgIAotICAgIHByaXZhdGUgaW50W10gX2FycmF5OwotICAgIHByaXZhdGUgaW50ICAgX3NpemU7Ci0gICAgcHJpdmF0ZSBpbnQgICBfZnJlZSA9IDA7Ci0gIAotICAgIHB1YmxpYyBJbnRlZ2VyQXJyYXkoKSB7Ci0JdGhpcyhJbml0aWFsU2l6ZSk7Ci0gICAgfQotICAKLSAgICBwdWJsaWMgSW50ZWdlckFycmF5KGludCBzaXplKSB7Ci0JX2FycmF5ID0gbmV3IGludFtfc2l6ZSA9IHNpemVdOwotICAgIH0KLQotICAgIHB1YmxpYyBJbnRlZ2VyQXJyYXkoaW50W10gYXJyYXkpIHsKLQl0aGlzKGFycmF5Lmxlbmd0aCk7Ci0JU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgX2FycmF5LCAwLCBfZnJlZSA9IF9zaXplKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKLQlfZnJlZSA9IDA7Ci0gICAgfQotCi0gICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKLQlyZXR1cm4gbmV3IEludGVnZXJBcnJheShfYXJyYXkpOwotICAgIH0KLQotICAgIHB1YmxpYyBpbnRbXSB0b0ludEFycmF5KCkgewotCWZpbmFsIGludFtdIHJlc3VsdCA9IG5ldyBpbnRbY2FyZGluYWxpdHkoKV07Ci0JU3lzdGVtLmFycmF5Y29weShfYXJyYXksIDAsIHJlc3VsdCwgMCwgY2FyZGluYWxpdHkoKSk7Ci0JcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICBwdWJsaWMgZmluYWwgaW50IGF0KGludCBpbmRleCkgewotCXJldHVybiBfYXJyYXlbaW5kZXhdOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldChpbnQgaW5kZXgsIGludCB2YWx1ZSkgewotCV9hcnJheVtpbmRleF0gPSB2YWx1ZTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGluZGV4T2YoaW50IG4pIHsKLQlmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlOyBpKyspCi0JICAgIGlmIChuID09IF9hcnJheVtpXSkKLQkJcmV0dXJuIGk7Ci0JcmV0dXJuIC0xOwotICAgIH0KLQotICAgIHB1YmxpYyBmaW5hbCB2b2lkIGFkZChpbnQgdmFsdWUpIHsKLQlpZiAoX2ZyZWUgPT0gX3NpemUpCi0JICAgIGdyb3dBcnJheShfc2l6ZSAqIDIpOwotCV9hcnJheVtfZnJlZSsrXSA9IHZhbHVlOwotICAgIH0KLSAgCi0gICAgLyoqIGFkZHMgbmV3IGludCBhdCB0aGUgZW5kIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQgKi8KLSAgICBwdWJsaWMgdm9pZCBhZGROZXcoaW50IHZhbHVlKSB7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBfZnJlZTsgaSsrKQotCSAgICBpZiAoX2FycmF5W2ldID09IHZhbHVlKQkvLyBhbHJlYWR5IGluIGFycmF5Ci0JCXJldHVybjsKLQlhZGQodmFsdWUpOwotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBncm93QXJyYXkoaW50IHNpemUpIHsKLQlmaW5hbCBpbnRbXSBuZXdBcnJheSA9IG5ldyBpbnRbX3NpemUgPSBzaXplXTsKLQlTeXN0ZW0uYXJyYXljb3B5KF9hcnJheSwgMCwgbmV3QXJyYXksIDAsIF9mcmVlKTsKLQlfYXJyYXkgPSBuZXdBcnJheTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IHBvcExhc3QoKSB7Ci0JcmV0dXJuIF9hcnJheVstLV9mcmVlXTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgaW50IGxhc3QoKSB7Ci0JcmV0dXJuIF9hcnJheVtfZnJlZSAtIDFdOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHNldExhc3QoaW50IG4pIHsKLQlfYXJyYXlbX2ZyZWUgLSAxXSA9IG47Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcG9wKCkgewotCV9mcmVlLS07Ci0gICAgfQotCi0gICAgcHVibGljIHZvaWQgcG9wKGludCBuKSB7Ci0JX2ZyZWUgLT0gbjsKLSAgICB9Ci0gIAotICAgIHB1YmxpYyBmaW5hbCBpbnQgY2FyZGluYWxpdHkoKSB7Ci0JcmV0dXJuIF9mcmVlOwotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIHByaW50KGphdmEuaW8uUHJpbnRTdHJlYW0gb3V0KSB7Ci0JaWYgKF9mcmVlID4gMCkgewotCSAgICBmb3IgKGludCBpID0gMDsgaSA8IF9mcmVlIC0gMTsgaSsrKSB7Ci0JCW91dC5wcmludChfYXJyYXlbaV0pOwotCQlvdXQucHJpbnQoJyAnKTsKLQkgICAgfQotCSAgICBvdXQucHJpbnRsbihfYXJyYXlbX2ZyZWUgLSAxXSk7Ci0JfQotCWVsc2UKLQkgICAgb3V0LnByaW50bG4oIkludGVnZXJBcnJheTogZW1wdHkiKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy91dGlsL0phdmFDdXBSZWRpcmVjdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdXRpbC9KYXZhQ3VwUmVkaXJlY3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmY2NzUxNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy91dGlsL0phdmFDdXBSZWRpcmVjdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQwICswLDAgQEAKLS8qCi0gKiBAKCMpJElkJAotICoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy51dGlsOwotCi1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLQotLyoqCi0gKiBVdGlsaXR5IGNsYXNzIHRvIHJlZGlyZWN0IGlucHV0IHRvIEphdmFDdXAgcHJvZ3JhbS4KLSAqCi0gKiBVc2FnZS1jb21tYW5kIGxpbmU6IAotICogPGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWxzLkphdmFDdXBSZWRpcmVjdCBbYXJnc10gLXN0ZGluIGZpbGVuYW1lLmV4dDwvY29kZT4KLSAqCi0gKiBAYXV0aG9yIE1vcnRlbiBKb3JnZW5zZW4KLSAqIEB2ZXJzaW9uICRJZCQKLSAqLwotcHVibGljIGNsYXNzIEphdmFDdXBSZWRpcmVjdCB7Ci0KLSAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgRVJSTVNHID0gCi0JCSAiWW91IG11c3Qgc3VwcGx5IGEgZmlsZW5hbWUgd2l0aCB0aGUgLXN0ZGluIG9wdGlvbi4iOwotCi0gICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZyBhcmdzW10pIHsKLQotCQkgLy8gSWYgd2Ugc2hvdWxkIGNhbGwgU3lzdGVtLmV4aXQgb3Igbm90Ci0gICAgICAgICAvL0B0b2RvIG1ha2UgdGhpcyBzZXR0YWJsZSBmb3IgdXNlIGluc2lkZSBvdGhlciBqYXZhIHByb2dzCi0JCSBib29sZWFuIHN5c3RlbUV4aXRPSyA9IHRydWU7Ci0KLQkJIC8vIFRoaXMgaXMgdGhlIHN0cmVhbSB3ZSdsbCBzZXQgYXMgb3VyIFN5c3RlbS5pbgotCQkgSW5wdXRTdHJlYW0gaW5wdXQgPSBudWxsOwotCi0JCSAvLyBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cwotCQkgZmluYWwgaW50IGFyZ2MgPSBhcmdzLmxlbmd0aDsKLQotCQkgLy8gVGhlIGFyZ3VtZW50cyB3ZSdsbCBwYXNzIHRvIHRoZSByZWFsICdtYWluKCknCi0JCSBTdHJpbmdbXSBuZXdfYXJncyA9IG5ldyBTdHJpbmdbYXJnYyAtIDJdOwotCQkgaW50IG5ld19hcmdjID0gMDsKLQotCQkgLy8gUGFyc2UgYWxsIHBhcmFtZXRlcnMgcGFzc2VkIHRvIHRoaXMgY2xhc3MKLQkJIGZvciAoaW50IGkgPSAwOyBpIDwgYXJnYzsgaSsrKSB7Ci0JCSAgICAgLy8gUGFyc2Ugb3B0aW9uICctc3RkaW4gPGZpbGVuYW1lPicKLQkJICAgICBpZiAoYXJnc1tpXS5lcXVhbHMoIi1zdGRpbiIpKSB7Ci0JCSAJCSAvLyBUaGlzIG9wdGlvbiBtdXN0IGhhdmUgYW4gYXJndW1lbnQKLQkJIAkJIGlmICgoKytpID49IGFyZ2MpIHx8IChhcmdzW2ldLnN0YXJ0c1dpdGgoIi0iKSkpIHsKLQkJIAkJICAgICBTeXN0ZW0uZXJyLnByaW50bG4oRVJSTVNHKTsKLQkJIAkJICAgICBkb1N5c3RlbUV4aXQoc3lzdGVtRXhpdE9LKTsKLQkJIAkJIH0KLQkJIAkJIHRyeSB7Ci0JCSAJCSAgICAgaW5wdXQgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGFyZ3NbaV0pOwotCQkgCQkgfQotCQkgCQkgY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0JCSAJCSAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDb3VsZCBub3Qgb3BlbiBmaWxlICIrYXJnc1tpXSk7Ci0JCSAJCSAgICAgZG9TeXN0ZW1FeGl0KHN5c3RlbUV4aXRPSyk7Ci0JCSAJCSB9Ci0JCSAJCSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgewotCQkgCQkgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiTm8gcGVybWlzc2lvbiB0byBmaWxlICIrYXJnc1tpXSk7Ci0JCSAJCSAgICAgZG9TeXN0ZW1FeGl0KHN5c3RlbUV4aXRPSyk7Ci0JCSAJCSB9Ci0JCSAgICAgfQotCQkgICAgIGVsc2UgewotCQkgCQkgaWYgKG5ld19hcmdjID09IG5ld19hcmdzLmxlbmd0aCkgewotCQkgCQkgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiTWlzc2luZyAtc3RkaW4gb3B0aW9uISIpOwotCQkgCQkgICAgIGRvU3lzdGVtRXhpdChzeXN0ZW1FeGl0T0spOwotCQkgCQkgfQotCQkgCQkgbmV3X2FyZ3NbbmV3X2FyZ2MrK10gPSBhcmdzW2ldOwotCQkgICAgIH0KLQkJIH0KLQotCQkgU3lzdGVtLnNldEluKGlucHV0KTsKLQkJIHRyeSB7Ci0JCSAgICAgamF2YV9jdXAuTWFpbi5tYWluKG5ld19hcmdzKTsKLQkJIH0KLQkJIGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXJyb3IgcnVubmluZyBKYXZhQ1VQOiIpOwotCQkgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0JCSAgICAgZG9TeXN0ZW1FeGl0KHN5c3RlbUV4aXRPSyk7Ci0JCSB9Ci0gICAgfQotICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkb1N5c3RlbUV4aXQgKGJvb2xlYW4gZG9FeGl0KSB7Ci0gICAgICAgIGlmIChkb0V4aXQpCi0gICAgICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0gICAgfQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vQXhpcy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9BeGlzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYzMmY3MWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9BeGlzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtOwotCi0vKioKLSAqIFNwZWNpZmllcyB2YWx1ZXMgcmVsYXRlZCB0byBYUGF0aCBBeGVzLgotICogPHA+VGhlIGFuY2VzdG9yLCBkZXNjZW5kYW50LCBmb2xsb3dpbmcsIHByZWNlZGluZyBhbmQgc2VsZiBheGVzIHBhcnRpdGlvbiBhCi0gKiBkb2N1bWVudCAoaWdub3JpbmcgYXR0cmlidXRlIGFuZCBuYW1lc3BhY2Ugbm9kZXMpOiB0aGV5IGRvIG5vdCBvdmVybGFwCi0gKiBhbmQgdG9nZXRoZXIgdGhleSBjb250YWluIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGRvY3VtZW50LjwvcD4KLSAqLwotcHVibGljIGludGVyZmFjZSBBeGlzCi17Ci0KLSAgLyoqCi0gICAqIFRoZSBhbmNlc3RvciBheGlzIGNvbnRhaW5zIHRoZSBhbmNlc3RvcnMgb2YgdGhlIGNvbnRleHQgbm9kZTsKLSAgICogIHRoZSBhbmNlc3RvcnMgb2YgdGhlIGNvbnRleHQgbm9kZSBjb25zaXN0IG9mIHRoZSBwYXJlbnQgb2YgY29udGV4dAotICAgKiAgbm9kZSBhbmQgdGhlIHBhcmVudCdzIHBhcmVudCBhbmQgc28gb247IHRodXMsIHRoZSBhbmNlc3RvciBheGlzIHdpbGwKLSAgICogIGFsd2F5cyBpbmNsdWRlIHRoZSByb290IG5vZGUsIHVubGVzcyB0aGUgY29udGV4dCBub2RlIGlzIHRoZSByb290IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTkNFU1RPUiA9IDA7Ci0KLSAgLyoqCi0gICAqIHRoZSBhbmNlc3Rvci1vci1zZWxmIGF4aXMgY29udGFpbnMgdGhlIGNvbnRleHQgbm9kZSBhbmQgdGhlIGFuY2VzdG9ycyBvZgotICAgKiAgdGhlIGNvbnRleHQgbm9kZTsgdGh1cywgdGhlIGFuY2VzdG9yIGF4aXMgd2lsbCBhbHdheXMgaW5jbHVkZSB0aGUKLSAgICogIHJvb3Qgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOQ0VTVE9ST1JTRUxGID0gMTsKLQotICAvKioKLSAgICogdGhlIGF0dHJpYnV0ZSBheGlzIGNvbnRhaW5zIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBjb250ZXh0IG5vZGU7IHRoZSBheGlzCi0gICAqICB3aWxsIGJlIGVtcHR5IHVubGVzcyB0aGUgY29udGV4dCBub2RlIGlzIGFuIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBVFRSSUJVVEUgPSAyOwotCi0gIC8qKiBUaGUgY2hpbGQgYXhpcyBjb250YWlucyB0aGUgY2hpbGRyZW4gb2YgdGhlIGNvbnRleHQgbm9kZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hJTEQgPSAzOwotCi0gIC8qKgotICAgKiBUaGUgZGVzY2VuZGFudCBheGlzIGNvbnRhaW5zIHRoZSBkZXNjZW5kYW50cyBvZiB0aGUgY29udGV4dCBub2RlOwotICAgKiAgYSBkZXNjZW5kYW50IGlzIGEgY2hpbGQgb3IgYSBjaGlsZCBvZiBhIGNoaWxkIGFuZCBzbyBvbjsgdGh1cyB0aGUKLSAgICogIGRlc2NlbmRhbnQgYXhpcyBuZXZlciBjb250YWlucyBhdHRyaWJ1dGUgb3IgbmFtZXNwYWNlIG5vZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVTQ0VOREFOVCA9IDQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBkZXNjZW5kYW50LW9yLXNlbGYgYXhpcyBjb250YWlucyB0aGUgY29udGV4dCBub2RlIGFuZCB0aGUKLSAgICogIGRlc2NlbmRhbnRzIG9mIHRoZSBjb250ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVNDRU5EQU5UT1JTRUxGID0gNTsKLQotICAvKioKLSAgICogdGhlIGZvbGxvd2luZyBheGlzIGNvbnRhaW5zIGFsbCBub2RlcyBpbiB0aGUgc2FtZSBkb2N1bWVudCBhcyB0aGUKLSAgICogIGNvbnRleHQgbm9kZSB0aGF0IGFyZSBhZnRlciB0aGUgY29udGV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyLCBleGNsdWRpbmcKLSAgICogIGFueSBkZXNjZW5kYW50cyBhbmQgZXhjbHVkaW5nIGF0dHJpYnV0ZSBub2RlcyBhbmQgbmFtZXNwYWNlIG5vZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9MTE9XSU5HID0gNjsKLQotICAvKioKLSAgICogVGhlIGZvbGxvd2luZy1zaWJsaW5nIGF4aXMgY29udGFpbnMgYWxsIHRoZSBmb2xsb3dpbmcgc2libGluZ3Mgb2YgdGhlCi0gICAqICBjb250ZXh0IG5vZGU7IGlmIHRoZSBjb250ZXh0IG5vZGUgaXMgYW4gYXR0cmlidXRlIG5vZGUgb3IgbmFtZXNwYWNlIG5vZGUsCi0gICAqICB0aGUgZm9sbG93aW5nLXNpYmxpbmcgYXhpcyBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPTExPV0lOR1NJQkxJTkcgPSA3OwotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIGF4aXMgY29udGFpbnMgdGhlIG5hbWVzcGFjZSBub2RlcyBvZiB0aGUgY29udGV4dCBub2RlOyB0aGUKLSAgICogIGF4aXMgd2lsbCBiZSBlbXB0eSB1bmxlc3MgdGhlIGNvbnRleHQgbm9kZSBpcyBhbiBlbGVtZW50LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFREVDTFMgPSA4OwotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIGF4aXMgY29udGFpbnMgdGhlIG5hbWVzcGFjZSBub2RlcyBvZiB0aGUgY29udGV4dCBub2RlOyB0aGUKLSAgICogIGF4aXMgd2lsbCBiZSBlbXB0eSB1bmxlc3MgdGhlIGNvbnRleHQgbm9kZSBpcyBhbiBlbGVtZW50LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFID0gOTsKLQotICAvKioKLSAgICogVGhlIHBhcmVudCBheGlzIGNvbnRhaW5zIHRoZSBwYXJlbnQgb2YgdGhlIGNvbnRleHQgbm9kZSwKLSAgICogIGlmIHRoZXJlIGlzIG9uZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBUkVOVCA9IDEwOwotCi0gIC8qKgotICAgKiBUaGUgcHJlY2VkaW5nIGF4aXMgY29udGFpbnMgYWxsIG5vZGVzIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZSBjb250ZXh0Ci0gICAqICBub2RlIHRoYXQgYXJlIGJlZm9yZSB0aGUgY29udGV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyLCBleGNsdWRpbmcgYW55Ci0gICAqICBhbmNlc3RvcnMgYW5kIGV4Y2x1ZGluZyBhdHRyaWJ1dGUgbm9kZXMgYW5kIG5hbWVzcGFjZSBub2RlcwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJFQ0VESU5HID0gMTE7Ci0KLSAgLyoqCi0gICAqIFRoZSBwcmVjZWRpbmctc2libGluZyBheGlzIGNvbnRhaW5zIGFsbCB0aGUgcHJlY2VkaW5nIHNpYmxpbmdzIG9mIHRoZQotICAgKiAgY29udGV4dCBub2RlOyBpZiB0aGUgY29udGV4dCBub2RlIGlzIGFuIGF0dHJpYnV0ZSBub2RlIG9yIG5hbWVzcGFjZSBub2RlLAotICAgKiAgdGhlIHByZWNlZGluZy1zaWJsaW5nIGF4aXMgaXMgZW1wdHkuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUkVDRURJTkdTSUJMSU5HID0gMTI7Ci0KLSAgLyoqIFRoZSBzZWxmIGF4aXMgY29udGFpbnMganVzdCB0aGUgY29udGV4dCBub2RlIGl0c2VsZi4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VMRiA9IDEzOwotCi0gIC8qKgotICAgKiBBIG5vbi14cGF0aCBheGlzLCB0cmF2ZXJzaW5nIHRoZSBzdWJ0cmVlIGluY2x1ZGluZyB0aGUgc3VidHJlZQotICAgKiAgcm9vdCwgZGVzY2VuZGFudHMsIGF0dHJpYnV0ZXMsIGFuZCBuYW1lc3BhY2Ugbm9kZSBkZWNscy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMTEZST01OT0RFID0gMTQ7Ci0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHRyYXZlcnNpbmcgdGhlIHRoZSBwcmVjZWRpbmcgYW5kIHRoZSBhbmNlc3RvciBub2RlcywgCi0gICAqIG5lZWRlZCBmb3IgaW52ZXJzZWluZyBzZWxlY3QgcGF0dGVybnMgdG8gbWF0Y2ggcGF0dGVybnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUkVDRURJTkdBTkRBTkNFU1RPUiA9IDE1OwotICAKLSAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBBbGwgYXhpcyBwYXN0IHRoaXMgYXJlIGFic29sdXRlLgotICAKLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgYWxsIG5vZGVzIGluIHRoZSB0cmVlIGZyb20gYW5kIGluY2x1ZGluZyB0aGUgCi0gICAqIHJvb3QuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTEwgPSAxNjsKLQotICAvKioKLSAgICogQSBub24teHBhdGggYXhpcywgcmV0dXJucyBhbGwgbm9kZXMgdGhhdCBhcmVuJ3QgbmFtZXNwYWNlcyBvciBhdHRyaWJ1dGVzLCAKLSAgICogZnJvbSBhbmQgaW5jbHVkaW5nIHRoZSByb290LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVTQ0VOREFOVFNGUk9NUk9PVCA9IDE3OwotCi0gIC8qKgotICAgKiBBIG5vbi14cGF0aCBheGlzLCByZXR1cm5zIGFsbCBub2RlcyB0aGF0IGFyZW4ndCBuYW1lc3BhY2VzIG9yIGF0dHJpYnV0ZXMsIAotICAgKiBmcm9tIGFuZCBpbmNsdWRpbmcgdGhlIHJvb3QuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVNDRU5EQU5UU09SU0VMRkZST01ST09UID0gMTg7Ci0KLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgcm9vdCBvbmx5LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9PVCA9IDE5OwotCi0gIC8qKgotICAgKiBBIG5vbi14cGF0aCBheGlzLCBmb3IgZnVuY3Rpb25zLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklMVEVSRURMSVNUID0gMjA7Ci0KLQotICAvKiogVGhlIG5hbWVzIG9mIHRoZSBheGVzIGZvciBkaWFnbm9zdGljIHB1cnBvc2VzLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG5hbWVzID0KLSAgewotICAgICJhbmNlc3RvciIsICAvLyAwCi0gICAgImFuY2VzdG9yLW9yLXNlbGYiLCAgLy8gMQotICAgICJhdHRyaWJ1dGUiLCAgLy8gMgotICAgICJjaGlsZCIsICAvLyAzCi0gICAgImRlc2NlbmRhbnQiLCAgLy8gNAotICAgICJkZXNjZW5kYW50LW9yLXNlbGYiLCAgLy8gNQotICAgICJmb2xsb3dpbmciLCAgLy8gNgotICAgICJmb2xsb3dpbmctc2libGluZyIsICAvLyA3Ci0gICAgIm5hbWVzcGFjZS1kZWNscyIsICAvLyA4Ci0gICAgIm5hbWVzcGFjZSIsICAvLyA5Ci0gICAgInBhcmVudCIsICAvLyAxMAotICAgICJwcmVjZWRpbmciLCAgLy8gMTEKLSAgICAicHJlY2VkaW5nLXNpYmxpbmciLCAgLy8gMTIKLSAgICAic2VsZiIsICAvLyAxMwotICAgICJhbGwtZnJvbS1ub2RlIiwgIC8vIDE0Ci0gICAgInByZWNlZGluZy1hbmQtYW5jZXN0b3IiLCAgLy8gMTUKLSAgICAiYWxsIiwgIC8vIDE2Ci0gICAgImRlc2NlbmRhbnRzLWZyb20tcm9vdCIsICAvLyAxNwotICAgICJkZXNjZW5kYW50cy1vci1zZWxmLWZyb20tcm9vdCIsICAvLyAxOAotICAgICJyb290IiwgIC8vIDE5Ci0gICAgImZpbHRlcmVkLWxpc3QiICAvLyAyMAotICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1ZDg5OTkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotCi0vKioKLSAqIDxjb2RlPkRUTTwvY29kZT4gaXMgYW4gWE1MIGRvY3VtZW50IG1vZGVsIGV4cHJlc3NlZCBhcyBhIHRhYmxlCi0gKiByYXRoZXIgdGhhbiBhbiBvYmplY3QgdHJlZS4gSXQgYXR0ZW1wdHMgdG8gcHJvdmlkZSBhbiBpbnRlcmZhY2UgdG8KLSAqIGEgcGFyc2UgdHJlZSB0aGF0IGhhcyB2ZXJ5IGxpdHRsZSBvYmplY3QgY3JlYXRpb24uIChEVE0KLSAqIGltcGxlbWVudGF0aW9ucyBtYXkgYWxzbyBzdXBwb3J0IGluY3JlbWVudGFsIGNvbnN0cnVjdGlvbiBvZiB0aGUKLSAqIG1vZGVsLCBidXQgdGhhdCdzIGhpZGRlbiBmcm9tIHRoZSBEVE0gQVBJLikKLSAqCi0gKiA8cD5Ob2RlcyBpbiB0aGUgRFRNIGFyZSBpZGVudGlmaWVkIGJ5IGludGVnZXIgImhhbmRsZXMiLiAgQSBoYW5kbGUgbXVzdAotICogYmUgdW5pcXVlIHdpdGhpbiBhIHByb2Nlc3MsIGFuZCBjYXJyaWVzIGJvdGggbm9kZSBpZGVudGlmaWNhdGlvbiBhbmQKLSAqIGRvY3VtZW50IGlkZW50aWZpY2F0aW9uLiAgSXQgbXVzdCBiZSBwb3NzaWJsZSB0byBjb21wYXJlIHR3byBoYW5kbGVzCi0gKiAoYW5kIHRodXMgdGhlaXIgbm9kZXMpIGZvciBpZGVudGl0eSB3aXRoICI9PSIuPC9wPgotICoKLSAqIDxwPk5hbWVzcGFjZSBVUkxzLCBsb2NhbC1uYW1lcywgYW5kIGV4cGFuZGVkLW5hbWVzIGNhbiBhbGwgYmUKLSAqIHJlcHJlc2VudGVkIGJ5IGFuZCB0ZXN0ZWQgYXMgaW50ZWdlciBJRCB2YWx1ZXMuICBBbiBleHBhbmRlZCBuYW1lCi0gKiByZXByZXNlbnRzIChhbmQgbWF5IG9yIG1heSBub3QgZGlyZWN0bHkgY29udGFpbikgYSBjb21iaW5hdGlvbiBvZgotICogdGhlIFVSTCBJRCwgYW5kIHRoZSBsb2NhbC1uYW1lIElELiAgTm90ZSB0aGF0IHRoZSBuYW1lc3BhY2UgVVJMIGlkCi0gKiBjYW4gYmUgMCwgd2hpY2ggc2hvdWxkIGhhdmUgdGhlIG1lYW5pbmcgdGhhdCB0aGUgbmFtZXNwYWNlIGlzIG51bGwuCi0gKiBGb3IgY29uc2lzdGFuY3ksIHplcm8gc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBhIGxvY2FsLW5hbWUgaW5kZXguIDwvcD4KLSAqCi0gKiA8cD5UZXh0IGNvbnRlbnQgb2YgYSBub2RlIGlzIHJlcHJlc2VudGVkIGJ5IGFuIGluZGV4IGFuZCBsZW5ndGgsCi0gKiBwZXJtaXR0aW5nIGVmZmljaWVudCBzdG9yYWdlIHN1Y2ggYXMgYSBzaGFyZWQgRmFzdFN0cmluZ0J1ZmZlci48L3A+Ci0gKgotICogPHA+VGhlIG1vZGVsIG9mIHRoZSB0cmVlLCBhcyB3ZWxsIGFzIHRoZSBnZW5lcmFsIG5hdmlnYXRpb24gbW9kZWwsCi0gKiBpcyB0aGF0IG9mIFhQYXRoIDEuMCwgZm9yIHRoZSBtb21lbnQuICBUaGUgbW9kZWwgd2lsbCBldmVudHVhbGx5IGJlCi0gKiBhZGFwdGVkIHRvIG1hdGNoIHRoZSBYUGF0aCAyLjAgZGF0YSBtb2RlbCwgWE1MIFNjaGVtYSwgYW5kCi0gKiBJbmZvU2V0LjwvcD4KLSAqCi0gKiA8cD5EVE0gZG9lcyBfbm90XyBkaXJlY3RseSBzdXBwb3J0IHRoZSBXM0MncyBEb2N1bWVudCBPYmplY3QKLSAqIE1vZGVsLiBIb3dldmVyLCBpdCBhdHRlbXB0cyB0byBjb21lIGNsb3NlIGVub3VnaCB0aGF0IGFuCi0gKiBpbXBsZW1lbnRhdGlvbiBvZiBEVE0gY2FuIGJlIGNyZWF0ZWQgdGhhdCB3cmFwcyBhIERPTSBhbmQgdmljZQotICogdmVyc2EuPC9wPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTQotewotCi0gIC8qKgotICAgKiBOdWxsIG5vZGUgaGFuZGxlcyBhcmUgcmVwcmVzZW50ZWQgYnkgdGhpcyB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTEwgPSAtMTsKLQotICAvLyBUaGVzZSBub2RlVHlwZSBtbmVtb25pY3MgYW5kIHZhbHVlcyBhcmUgZGVsaWJlcmF0ZWx5IHRoZSBzYW1lIGFzIHRob3NlCi0gIC8vIHVzZWQgYnkgdGhlIERPTSwgZm9yIGNvbnZlbmllbnQgbWFwcGluZwotICAvLwotICAvLyAlUkVWSUVXJSBTaG91bGQgd2UgYWN0dWFsbHkgZGVmaW5lIHRoZXNlIGFzIGluaXRpYWxpemVkIHRvLAotICAvLyBlZy4gb3JnLnczYy5kb20uRG9jdW1lbnQuRUxFTUVOVF9OT0RFPwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhbiA8Y29kZT5FbGVtZW50PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRUxFTUVOVF9OT0RFID0gMTsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYW4gPGNvZGU+QXR0cjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEFUVFJJQlVURV9OT0RFID0gMjsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5UZXh0PC9jb2RlPiBub2RlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBURVhUX05PREUgPSAzOwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IENEQVRBX1NFQ1RJT05fTk9ERSA9IDQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGFuIDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVOVElUWV9SRUZFUkVOQ0VfTk9ERSA9IDU7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGFuIDxjb2RlPkVudGl0eTwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEVOVElUWV9OT0RFID0gNjsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb248L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgPSA3OwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkNvbW1lbnQ8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBDT01NRU5UX05PREUgPSA4OwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBpcyBhIDxjb2RlPkRvY3VtZW50PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfTk9ERSA9IDk7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+RG9jdW1lbnRUeXBlPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRE9DVU1FTlRfVFlQRV9OT0RFID0gMTA7Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGlzIGEgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPSAxMTsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5Ob3RhdGlvbjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVEFUSU9OX05PREUgPSAxMjsKLQotICAvKioKLSAgICogVGhlIG5vZGUgaXMgYSA8Y29kZT5uYW1lc3BhY2Ugbm9kZTwvY29kZT4uIE5vdGUgdGhhdCB0aGlzIGlzIG5vdAotICAgKiBjdXJyZW50bHkgYSBub2RlIHR5cGUgZGVmaW5lZCBieSB0aGUgRE9NIEFQSS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgTkFNRVNQQUNFX05PREUgPSAxMzsKLQotICAvLyA9PT09PT09PT0gRFRNIEltcGxlbWVudGF0aW9uIENvbnRyb2wgRnVuY3Rpb25zLiA9PT09PT09PT09PT09PQotICAvLyAlVEJEJSBSRVRJUkVEIC0tIGRvIHZpYSBzZXRGZWF0dXJlIGlmIG5lZWRlZC4gUmVtb3ZlIGZyb20gaW1wbHMuCi0gIC8vIHB1YmxpYyB2b2lkIHNldFBhcnNlQmxvY2tTaXplKGludCBibG9ja1NpemVTdWdnZXN0aW9uKTsKLQotICAvKioKLSAgICogU2V0IGFuIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCBmZWF0dXJlLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgRG8gd2UgcmVhbGx5IGV4cGVjdCB0byBzZXQgZmVhdHVyZXMgb24gRFRNcz8KLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmVJZCBBIGZlYXR1cmUgVVJMLgotICAgKiBAcGFyYW0gc3RhdGUgdHJ1ZSBpZiB0aGlzIGZlYXR1cmUgc2hvdWxkIGJlIG9uLCBmYWxzZSBvdGhlcndpc2UuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGZWF0dXJlKFN0cmluZyBmZWF0dXJlSWQsIGJvb2xlYW4gc3RhdGUpOwotCi0gIC8qKgotICAgKiBTZXQgYSBydW4gdGltZSBwcm9wZXJ0eSBmb3IgdGhpcyBEVE0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9wZXJ0eSBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSwgT2JqZWN0IHZhbHVlKTsKLQotICAvLyA9PT09PT09PT0gRG9jdW1lbnQgTmF2aWdhdGlvbiBGdW5jdGlvbnMgPT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFRoaXMgcmV0dXJucyBhIHN0YXRlbGVzcyAidHJhdmVyc2VyIiwgdGhhdCBjYW4gbmF2aWdhdGUgb3ZlciBhbgotICAgKiBYUGF0aCBheGlzLCB0aG91Z2ggbm90IGluIGRvY3VtZW50IG9yZGVyLgotICAgKgotICAgKiBAcGFyYW0gYXhpcyBPbmUgb2YgQXhlcy5BTkNFU1RPUk9SU0VMRiwgZXRjLgotICAgKgotICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCBvciBudWxsIGlmIHRoZSBnaXZpbiBheGlzIGlzbid0IHN1cHBvcnRlZC4KLSAgICovCi0gIHB1YmxpYyBEVE1BeGlzVHJhdmVyc2VyIGdldEF4aXNUcmF2ZXJzZXIoZmluYWwgaW50IGF4aXMpOwotCi0gIC8qKgotICAgKiBUaGlzIGlzIGEgc2hvcnRjdXQgdG8gdGhlIGl0ZXJhdG9ycyB0aGF0IGltcGxlbWVudAotICAgKiBYUGF0aCBheGVzLgotICAgKiBSZXR1cm5zIGEgYmFyZS1ib25lcyBpdGVyYXRvciB0aGF0IG11c3QgYmUgaW5pdGlhbGl6ZWQKLSAgICogd2l0aCBhIHN0YXJ0IG5vZGUgKHVzaW5nIGl0ZXJhdG9yLnNldFN0YXJ0Tm9kZSgpKS4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2aW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcyk7Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpdGVyYXRvciB0aGF0IGNhbiBuYXZpZ2F0ZSBvdmVyIGFuIFhQYXRoIEF4aXMsIHByZWRpY2F0ZWQgYnkKLSAgICogdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqCi0gICAqIEBwYXJhbSBheGlzCi0gICAqIEBwYXJhbSB0eXBlIEFuIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIG9yIG51bGwgaWYgdGhlIGdpdmluIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcywgZmluYWwgaW50IHR5cGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCB0ZXN0IGlmIGl0IGhhcyBjaGlsZCBub2Rlcy4KLSAgICogPHA+ICVSRVZJRVclIFRoaXMgaXMgb2J2aW91c2x5IHVzZWZ1bCBhdCB0aGUgRE9NIGxheWVyLCB3aGVyZSBpdAotICAgKiB3b3VsZCBwZXJtaXQgdGVzdGluZyB0aGlzIHdpdGhvdXQgaGF2aW5nIHRvIGNyZWF0ZSBhIHByb3h5Ci0gICAqIG5vZGUuIEl0J3MgbGVzcyB1c2VmdWwgaW4gdGhlIERUTSBBUEksIHdoZXJlCi0gICAqIChkdG0uZ2V0Rmlyc3RDaGlsZChub2RlSGFuZGxlKSE9RFRNLk5VTEwpIGlzIGp1c3QgYXMgZmFzdCBhbmQKLSAgICogYWxtb3N0IGFzIHNlbGYtZXZpZGVudC4gQnV0IGl0J3MgYSBjb252ZW5pZW5jZSwgYW5kIGVhc2VzIHBvcnRpbmcKLSAgICogb2YgRE9NIGNvZGUgdG8gRFRNLiAgPC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCB0cnVlIGlmIHRoZSBnaXZlbiBub2RlIGhhcyBjaGlsZCBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkTm9kZXMoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGhhbmRsZSBvZiB0aGUgbm9kZSdzIGZpcnN0IGNoaWxkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBEVE0gbm9kZS1udW1iZXIgb2YgZmlyc3QgY2hpbGQsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRGaXJzdENoaWxkKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBoYW5kbGUgb2YgdGhlIG5vZGUncyBsYXN0IGNoaWxkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBsYXN0IGNoaWxkLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdENoaWxkKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogUmV0cmlldmVzIGFuIGF0dHJpYnV0ZSBub2RlIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkKLSAgICoKLSAgICogJVRCRCUgTm90ZSB0aGF0IHdlIGN1cnJlbnRseSBoYXZlIG5vIHdheSB0byBzdXBwb3J0Ci0gICAqIHRoZSBET00ncyBvbGQgZ2V0QXR0cmlidXRlKCkgY2FsbCwgd2hpY2ggYWNjZXNzZXMgb25seSB0aGUgcW5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtZW50SGFuZGxlIEhhbmRsZSBvZiB0aGUgbm9kZSB1cG9uIHdoaWNoIHRvIGxvb2sgdXAgdGhpcyBhdHRyaWJ1dGUuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0bwotICAgKiAgIHJldHJpZXZlLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUuCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlIGhhbmRsZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSAoCi0gICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvciA8Y29kZT5EVE0uTlVMTDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAotICAgKiAgIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShpbnQgZWxlbWVudEhhbmRsZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBIYW5kbGUgb2YgZmlyc3QgYXR0cmlidXRlLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3RBdHRyaWJ1dGUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MgZmlyc3QgbmFtZXNwYWNlIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGhhbmRsZSB0byBub2RlLCB3aGljaCBzaG91bGQgcHJvYmFibHkgYmUgYW4gZWxlbWVudAotICAgKiAgICAgICAgICAgICAgICAgICBub2RlLCBidXQgbmVlZCBub3QgYmUuCi0gICAqCi0gICAqIEBwYXJhbSBpblNjb3BlIHRydWUgaWYgYWxsIG5hbWVzcGFjZXMgaW4gc2NvcGUgc2hvdWxkIGJlCi0gICAqICAgICAgICAgICAgICAgICAgIHJldHVybmVkLCBmYWxzZSBpZiBvbmx5IHRoZSBub2RlJ3Mgb3duCi0gICAqICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgc2hvdWxkIGJlIHJldHVybmVkLgotICAgKiBAcmV0dXJuIGhhbmRsZSBvZiBmaXJzdCBuYW1lc3BhY2UsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRGaXJzdE5hbWVzcGFjZU5vZGUoaW50IG5vZGVIYW5kbGUsIGJvb2xlYW4gaW5TY29wZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIG5leHQgc2libGluZy4KLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgTm9kZS1udW1iZXIgb2YgbmV4dCBzaWJsaW5nLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dFNpYmxpbmcoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIGl0cyBwcmVjZWVkaW5nIHNpYmxpbmcuCi0gICAqIFdBUk5JTkc6IERUTSBpbXBsZW1lbnRhdGlvbnMgbWF5IGJlIGFzeW1tZXRyaWM7IGluIHNvbWUsCi0gICAqIHRoaXMgb3BlcmF0aW9uIGhhcyBiZWVuIHJlc29sdmVkIGJ5IHNlYXJjaCwgYW5kIGlzIHJlbGF0aXZlbHkgZXhwZW5zaXZlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIHRoZSBwcmV2aW91cyBzaWIsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcmV2aW91c1NpYmxpbmcoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IGF0dHJpYnV0ZS4gSWYgYW4KLSAgICogZWxlbWVudCwgd2UgYWR2YW5jZSB0byBpdHMgZmlyc3QgYXR0cmlidXRlOyBpZiBhbiBhdHRyLCB3ZSBhZHZhbmNlIHRvCi0gICAqIHRoZSBuZXh0IGF0dHIgb2YgdGhlIHNhbWUgZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIHRoZSByZXNvbHZlZCBhdHRyLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dEF0dHJpYnV0ZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbmFtZXNwYWNlIGhhbmRsZSwgYWR2YW5jZSB0byB0aGUgbmV4dCBuYW1lc3BhY2UgaW4gdGhlIHNhbWUgc2NvcGUKLSAgICogKGxvY2FsIG9yIGxvY2FsLXBsdXMtaW5oZXJpdGVkLCBhcyBzZWxlY3RlZCBieSBnZXRGaXJzdE5hbWVzcGFjZU5vZGUpCi0gICAqCi0gICAqIEBwYXJhbSBiYXNlSGFuZGxlIGhhbmRsZSB0byBvcmlnaW5hbCBub2RlIGZyb20gd2hlcmUgdGhlIGZpcnN0IGNoaWxkCi0gICAqIHdhcyByZWxhdGl2ZSB0byAobmVlZGVkIHRvIHJldHVybiBub2RlcyBpbiBkb2N1bWVudCBvcmRlcikuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VIYW5kbGUgaGFuZGxlIHRvIG5vZGUgd2hpY2ggbXVzdCBiZSBvZiB0eXBlCi0gICAqIE5BTUVTUEFDRV9OT0RFLgotICAgKiBORUVEU0RPQyBAcGFyYW0gaW5TY29wZQotICAgKiBAcmV0dXJuIGhhbmRsZSBvZiBuZXh0IG5hbWVzcGFjZSwKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHROYW1lc3BhY2VOb2RlKGludCBiYXNlSGFuZGxlLCBpbnQgbmFtZXNwYWNlSGFuZGxlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5TY29wZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgaXRzIHBhcmVudCBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUgaGFuZGxlIG9mIHBhcmVudCwKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFBhcmVudChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgdGhlIG93bmluZyBkb2N1bWVudCBub2RlLiBOb3RlIHRoYXQKLSAgICogdGhlIHJlYXNvbiB0aGlzIGNhbid0IGp1c3QgcmV0dXJuIDAgaXMgdGhhdCBpdCBuZWVkcyB0byBpbmNsdWRlIHRoZQotICAgKiBkb2N1bWVudCBudW1iZXIgcG9ydGlvbiBvZiB0aGUgbm9kZSBoYW5kbGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgTm9kZSBoYW5kbGUgb2YgZG9jdW1lbnQsIHdoaWNoIHNob3VsZCBhbHdheXMgYmUgdmFsaWQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldERvY3VtZW50KCk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgdGhlIG93bmluZyBkb2N1bWVudCBub2RlLiAgVGhpcyBoYXMgdGhlIGV4YWN0Ci0gICAqIHNhbWUgc2VtYW50aWNzIGFzIHRoZSBET00gRG9jdW1lbnQgbWV0aG9kIG9mIHRoZSBzYW1lIG5hbWUsIGluIHRoYXQgaWYKLSAgICogdGhlIG5vZGVIYW5kbGUgaXMgYSBkb2N1bWVudCBub2RlLCBpdCB3aWxsIHJldHVybiBOVUxMLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUgaGFuZGxlIG9mIG93bmluZyBkb2N1bWVudCwKLSAgICogb3IgRFRNLk5VTEwgaWYgdGhlIG5vZGVIYW5kbGUgaXMgYSBkb2N1bWVudC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0T3duZXJEb2N1bWVudChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZSBhcyBhIFN0cmluZyBvYmplY3QKLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGdldFN0cmluZ1ZhbHVlKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2V0IG51bWJlciBvZiBjaGFyYWN0ZXIgYXJyYXkgY2h1bmtzIGluCi0gICAqIHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlLgotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqIE5vdGUgdGhhdCBhIHNpbmdsZSB0ZXh0IG5vZGUgbWF5IGhhdmUgbXVsdGlwbGUgdGV4dCBjaHVua3MuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXIgYXJyYXkgY2h1bmtzIGluCi0gICAqICAgICAgICAgdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNoYXJhY3RlciBhcnJheSBjaHVuayBpbiB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKiBOb3RlIHRoYXQgYSBzaW5nbGUgdGV4dCBub2RlIG1heSBoYXZlIG11bHRpcGxlIHRleHQgY2h1bmtzLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNodW5rSW5kZXggV2hpY2ggY2h1bmsgdG8gZ2V0LgotICAgKiBAcGFyYW0gc3RhcnRBbmRMZW4gIEEgdHdvLWludGVnZXIgYXJyYXkgd2hpY2gsIHVwb24gcmV0dXJuLCBXSUxMCi0gICAqIEJFIEZJTExFRCB3aXRoIHZhbHVlcyByZXByZXNlbnRpbmcgdGhlIGNodW5rJ3Mgc3RhcnQgcG9zaXRpb24KLSAgICogd2l0aGluIHRoZSByZXR1cm5lZCBjaGFyYWN0ZXIgYnVmZmVyIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZSBjaHVuay4KLSAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIGFycmF5IGJ1ZmZlciB3aXRoaW4gd2hpY2ggdGhlIGNodW5rIG9jY3VycywKLSAgICogc2V0dGluZyBzdGFydEFuZExlbidzIGNvbnRlbnRzIGFzIGEgc2lkZS1lZmZlY3QuCi0gICAqLwotICBwdWJsaWMgY2hhcltdIGdldFN0cmluZ1ZhbHVlQ2h1bmsoaW50IG5vZGVIYW5kbGUsIGludCBjaHVua0luZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50W10gc3RhcnRBbmRMZW4pOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gYW4gSUQgdGhhdCByZXByZXNlbnRzIHRoZSBub2RlJ3MgZXhwYW5kZWQgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIGhhbmRsZSB0byB0aGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZXhwYW5kZWQtbmFtZSBpZCBvZiB0aGUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHBhbmRlZCBuYW1lLCByZXR1cm4gYW4gSUQuICBJZiB0aGUgZXhwYW5kZWQtbmFtZSBkb2VzIG5vdAotICAgKiBleGlzdCBpbiB0aGUgaW50ZXJuYWwgdGFibGVzLCB0aGUgZW50cnkgd2lsbCBiZSBjcmVhdGVkLCBhbmQgdGhlIElEIHdpbGwKLSAgICogYmUgcmV0dXJuZWQuICBBbnkgYWRkaXRpb25hbCBub2RlcyB0aGF0IGFyZSBjcmVhdGVkIHRoYXQgaGF2ZSB0aGlzCi0gICAqIGV4cGFuZGVkIG5hbWUgd2lsbCB1c2UgdGhpcyBJRC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIGhhbmRsZSB0byB0aGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIG5hbWVzcGFjZQotICAgKiBORUVEU0RPQyBAcGFyYW0gbG9jYWxOYW1lCi0gICAqIE5FRURTRE9DIEBwYXJhbSB0eXBlCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIGludCB0eXBlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHBhbmRlZC1uYW1lIElELCByZXR1cm4gdGhlIG5hbWVzcGFjZSBVUkkgcGFydC4KLSAgICoKLSAgICogQHBhcmFtIEV4cGFuZGVkTmFtZUlEIGFuIElEIHRoYXQgcmVwcmVzZW50cyBhbiBleHBhbmRlZC1uYW1lLgotICAgKiBAcmV0dXJuIFN0cmluZyBVUkkgdmFsdWUgb2YgdGhpcyBub2RlJ3MgbmFtZXNwYWNlLCBvciBudWxsIGlmIG5vCi0gICAqIG5hbWVzcGFjZSB3YXMgcmVzb2x2ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBub2RlIG5hbWUuIFRoaXMgd2lsbAotICAgKiBpbmNsdWRlIG5hbWVzIHN1Y2ggYXMgI3RleHQgb3IgI2RvY3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgKiAlUkVWSUVXJSBEb2N1bWVudCB3aGVuIGVtcHR5IHN0cmluZyBpcyBwb3NzaWJsZS4uLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgWFBhdGggbm9kZSBuYW1lLiAgVGhpcyBzaG91bGQgYmUKLSAgICogdGhlIG5hbWUgYXMgZGVzY3JpYmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsLCBOT1QgdGhlIERPTS1zdHlsZQotICAgKiBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBsb2NhbG5hbWUuCi0gICAqIChBcyBkZWZpbmVkIGluIE5hbWVzcGFjZXMsIHRoaXMgaXMgdGhlIHBvcnRpb24gb2YgdGhlIG5hbWUgYWZ0ZXIgdGhlCi0gICAqIHByZWZpeCwgaWYgcHJlc2VudCwgb3IgdGhlIHdob2xlIG5vZGUgbmFtZSBpZiBubyBwcmVmaXggZXhpc3RzKQotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIExvY2FsIG5hbWUgb2YgdGhpcyBub2RlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHRoYXQgdGhlIG5hbWVzcGFjZSBkZWNsIGlzCi0gICAqIG1hcHBpbmcuCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHVzZWQgdG8gbWFwIHRvIHRoZSBuYW1lc3BhY2UuCi0gICAqIChBcyBkZWZpbmVkIGluIE5hbWVzcGFjZXMsIHRoaXMgaXMgdGhlIHBvcnRpb24gb2YgdGhlIG5hbWUgYmVmb3JlIGFueQotICAgKiBjb2xvbiBjaGFyYWN0ZXIpLgotICAgKiBAcGFyYW0gcG9zdGl0aW9uIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqCi0gICAqIDxwPiAlUkVWSUVXJSBBcmUgeW91IHN1cmUgeW91IHdhbnQgIiIgZm9yIG5vIHByZWZpeD8gIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBwcmVmaXggb2YgdGhpcyBub2RlJ3MgbmFtZSwgb3IgIiIgaWYgbm8gZXhwbGljaXQKLSAgICogbmFtZXNwYWNlIHByZWZpeCB3YXMgZ2l2ZW4uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5hbWVzcGFjZSBVUkkKLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgZGVjbGFyZWQgVVJJIHdoaWNoIHRoaXMgbm9kZSdzCi0gICAqIHByZWZpeCAtLSBvciBkZWZhdWx0IGluIGxpZXUgdGhlcmVvZiAtLSB3YXMgbWFwcGVkIHRvLikKLSAgICogQHBhcmFtIHBvc3RpdGlvbiBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBub2RlIHZhbHVlLiBUaGlzIGlzIG1vc3RseQotICAgKiBhcyBkZWZpbmVkIGJ5IHRoZSBET00sIGJ1dCBtYXkgaWdub3JlIHNvbWUgY29udmVuaWVuY2VzLgotICAgKiA8cD4KLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAqIEByZXR1cm4gU3RyaW5nIFZhbHVlIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBub3QKLSAgICogbWVhbmluZ2Z1bCBmb3IgdGhpcyBub2RlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgdHlwZS4KLSAgICoKLSAgICogPHA+JVJFVklFVyUgR2VuZXJhbGx5LCByZXR1cm5pbmcgc2hvcnQgaXMgZmFsc2UgZWNvbm9teS4gUmV0dXJuIGludD88L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIGludCBOb2RlIHR5cGUsIGFzIHBlciB0aGUgRE9NJ3MgTm9kZS5fTk9ERSBjb25zdGFudHMuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0Tm9kZVR5cGUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSBkZXB0aCBsZXZlbCBvZiB0aGlzIG5vZGUgaW4gdGhlIHRyZWUgKGVxdWFscyAxIGZvcgotICAgKiBhIHBhcmVudGxlc3Mgbm9kZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgYW5jZXN0b3JzLCBwbHVzIG9uZQotICAgKi8KLSAgcHVibGljIHNob3J0IGdldExldmVsKGludCBub2RlSGFuZGxlKTsKLQotICAvLyA9PT09PT09PT09PT09PSBEb2N1bWVudCBxdWVyeSBmdW5jdGlvbnMgPT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciBEVE0gRE9NIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZAotICAgKiB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4KLSAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICogQHBhcmFtIHZlcnNpb24gVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICogICBJZiB0aGUgdmVyc2lvbiBpcyBub3QKLSAgICogICBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUKLSAgICogICBtZXRob2QgdG8gcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGlzCi0gICAqICAgc3VwcG9ydGVkIG9uIHRoaXMgbm9kZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbik7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYmFzZSBVUkkgb2YgdGhlIGRvY3VtZW50IGVudGl0eS4gSWYgaXQgaXMgbm90IGtub3duCi0gICAqIChiZWNhdXNlIHRoZSBkb2N1bWVudCB3YXMgcGFyc2VkIGZyb20gYSBzb2NrZXQgY29ubmVjdGlvbiBvciBmcm9tCi0gICAqIHN0YW5kYXJkIGlucHV0LCBmb3IgZXhhbXBsZSksIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIHVua25vd24uCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IGJhc2UgVVJJIFN0cmluZyBvYmplY3Qgb3IgbnVsbCBpZiB1bmtub3duLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEJhc2VVUkkoKTsKLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gYmFzZVVSSSB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkuIElmCi0gICAqIGl0IGlzIG5vdCBrbm93biwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgbnVsbC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQsIHdoaWNoIGNhbiBiZSBhbnkgdmFsaWQgbm9kZSBoYW5kbGUuCi0gICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3Qgb3IgbnVsbCBpZiB1bmtub3duLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN5c3RlbUlkZW50aWZpZXIoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBzY2hlbWUKLSAgICogICAgICAgIGluIHdoaWNoIHRoZSBkb2N1bWVudCBlbnRpdHkgaXMgZXhwcmVzc2VkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZCwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBub2RlIGhhbmRsZS4KLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgZW5jb2RpbmcgU3RyaW5nIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRFbmNvZGluZyhpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhbiBpbmRpY2F0aW9uIG9mIHRoZSBzdGFuZGFsb25lIHN0YXR1cyBvZiB0aGUgZG9jdW1lbnQsCi0gICAqICAgICAgICBlaXRoZXIgInllcyIgb3IgIm5vIi4gVGhpcyBwcm9wZXJ0eSBpcyBkZXJpdmVkIGZyb20gdGhlIG9wdGlvbmFsCi0gICAqICAgICAgICBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uIGluIHRoZSBYTUwgZGVjbGFyYXRpb24gYXQgdGhlCi0gICAqICAgICAgICBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGhhcyBubyB2YWx1ZSBpZiB0aGVyZSBpcyBubwotICAgKiAgICAgICAgc3RhbmRhbG9uZSBkb2N1bWVudCBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQsIHdoaWNoIGNhbiBiZSBhbnkgdmFsaWQgbm9kZSBoYW5kbGUuCi0gICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IHN0YW5kYWxvbmUgU3RyaW5nIG9iamVjdCwgZWl0aGVyICJ5ZXMiLCAibm8iLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN0YW5kYWxvbmUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQuIFRoaXMKLSAgICogcHJvcGVydHkgaXMgZGVyaXZlZCBmcm9tIHRoZSBYTUwgZGVjbGFyYXRpb24gb3B0aW9uYWxseSBwcmVzZW50IGF0IHRoZQotICAgKiBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGhhcyBubyB2YWx1ZSBpZiB0aGVyZSBpcyBubyBYTUwKLSAgICogZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSB0aGUgZG9jdW1lbnQgaGFuZGxlCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBkb2N1bWVudEhhbmRsZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBkb2N1bWVudCB2ZXJzaW9uIFN0cmluZyBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRWZXJzaW9uKGludCBkb2N1bWVudEhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhbiBpbmRpY2F0aW9uIG9mCi0gICAqIHdoZXRoZXIgdGhlIHByb2Nlc3NvciBoYXMgcmVhZCB0aGUgY29tcGxldGUgRFRELiBJdHMgdmFsdWUgaXMgYQotICAgKiBib29sZWFuLiBJZiBpdCBpcyBmYWxzZSwgdGhlbiBjZXJ0YWluIHByb3BlcnRpZXMgKGluZGljYXRlZCBpbiB0aGVpcgotICAgKiBkZXNjcmlwdGlvbnMgYmVsb3cpIG1heSBiZSB1bmtub3duLiBJZiBpdCBpcyB0cnVlLCB0aG9zZSBwcm9wZXJ0aWVzCi0gICAqIGFyZSBuZXZlciB1bmtub3duLgotICAgKgotICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFsbCBkZWNsYXJhdGlvbnMgd2VyZSBwcm9jZXNzZWQ7Ci0gICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldERvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKCk7Ci0KLSAgLyoqCi0gICAqICAgQSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIGluZm9ybWF0aW9uIGl0ZW0gaGFzIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKLSAgICoKLSAgICogICAgIDEuIFtzeXN0ZW0gaWRlbnRpZmllcl0gVGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQsIGlmCi0gICAqICAgICAgICBpdCBleGlzdHMuIE90aGVyd2lzZSB0aGlzIHByb3BlcnR5IGhhcyBubyB2YWx1ZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgU3RyaW5nIG9iamVjdCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblN5c3RlbUlkZW50aWZpZXIoKTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LAotICAgKiBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBpbiA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcyBbWE1MXS4gSWYgdGhlcmUgaXMKLSAgICogbm8gZXh0ZXJuYWwgc3Vic2V0IG9yIGlmIGl0IGhhcyBubyBwdWJsaWMgaWRlbnRpZmllciwgdGhpcyBwcm9wZXJ0eQotICAgKiBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBoYW5kbGUKLSAgICoKLSAgICogQHJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgU3RyaW5nIG9iamVjdCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblB1YmxpY0lkZW50aWZpZXIoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgPGNvZGU+RWxlbWVudDwvY29kZT4gd2hvc2UgPGNvZGU+SUQ8L2NvZGU+IGlzIGdpdmVuIGJ5Ci0gICAqIDxjb2RlPmVsZW1lbnRJZDwvY29kZT4uIElmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMsIHJldHVybnMKLSAgICogPGNvZGU+RFRNLk5VTEw8L2NvZGU+LiBCZWhhdmlvciBpcyBub3QgZGVmaW5lZCBpZiBtb3JlIHRoYW4gb25lIGVsZW1lbnQKLSAgICogaGFzIHRoaXMgPGNvZGU+SUQ8L2NvZGU+LiBBdHRyaWJ1dGVzIChpbmNsdWRpbmcgdGhvc2UKLSAgICogd2l0aCB0aGUgbmFtZSAiSUQiKSBhcmUgbm90IG9mIHR5cGUgSUQgdW5sZXNzIHNvIGRlZmluZWQgYnkgRFREL1NjaGVtYQotICAgKiBpbmZvcm1hdGlvbiBhdmFpbGFibGUgdG8gdGhlIERUTSBpbXBsZW1lbnRhdGlvbi4KLSAgICogSW1wbGVtZW50YXRpb25zIHRoYXQgZG8gbm90IGtub3cgd2hldGhlciBhdHRyaWJ1dGVzIGFyZSBvZiB0eXBlIElEIG9yCi0gICAqIG5vdCBhcmUgZXhwZWN0ZWQgdG8gcmV0dXJuIDxjb2RlPkRUTS5OVUxMPC9jb2RlPi4KLSAgICoKLSAgICogPHA+JVJFVklFVyUgUHJlc3VtYWJseSBJRHMgYXJlIHN0aWxsIHNjb3BlZCB0byBhIHNpbmdsZSBkb2N1bWVudCwKLSAgICogYW5kIHRoaXMgb3BlcmF0aW9uIHNlYXJjaGVzIG9ubHkgd2l0aGluIGEgc2luZ2xlIGRvY3VtZW50LCByaWdodD8KLSAgICogV291bGRuJ3Qgd2FudCBjb2xsaXNpb25zIGJldHdlZW4gRFRNcyBpbiB0aGUgc2FtZSBwcm9jZXNzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGVsZW1lbnRJZCBUaGUgdW5pcXVlIDxjb2RlPmlkPC9jb2RlPiB2YWx1ZSBmb3IgYW4gZWxlbWVudC4KLSAgICogQHJldHVybiBUaGUgaGFuZGxlIG9mIHRoZSBtYXRjaGluZyBlbGVtZW50LgotICAgKi8KLSAgcHVibGljIGludCBnZXRFbGVtZW50QnlJZChTdHJpbmcgZWxlbWVudElkKTsKLQotICAvKioKLSAgICogVGhlIGdldFVucGFyc2VkRW50aXR5VVJJIGZ1bmN0aW9uIHJldHVybnMgdGhlIFVSSSBvZiB0aGUgdW5wYXJzZWQKLSAgICogZW50aXR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZSBjb250ZXh0Ci0gICAqIG5vZGUgKHNlZSBbMy4zIFVucGFyc2VkIEVudGl0aWVzXSkuIEl0IHJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgKiB0aGVyZSBpcyBubyBzdWNoIGVudGl0eS4KLSAgICogPHA+Ci0gICAqIFhNTCBwcm9jZXNzb3JzIG1heSBjaG9vc2UgdG8gdXNlIHRoZSBTeXN0ZW0gSWRlbnRpZmllciAoaWYgb25lCi0gICAqIGlzIHByb3ZpZGVkKSB0byByZXNvbHZlIHRoZSBlbnRpdHksIHJhdGhlciB0aGFuIHRoZSBVUkkgaW4gdGhlCi0gICAqIFB1YmxpYyBJZGVudGlmaWVyLiBUaGUgZGV0YWlscyBhcmUgZGVwZW5kZW50IG9uIHRoZSBwcm9jZXNzb3IsIGFuZAotICAgKiB3ZSB3b3VsZCBoYXZlIHRvIHN1cHBvcnQgc29tZSBmb3JtIG9mIHBsdWctaW4gcmVzb2x2ZXIgdG8gaGFuZGxlCi0gICAqIHRoaXMgcHJvcGVybHkuIEN1cnJlbnRseSwgd2Ugc2ltcGx5IHJldHVybiB0aGUgU3lzdGVtIElkZW50aWZpZXIgaWYKLSAgICogcHJlc2VudCwgYW5kIGhvcGUgdGhhdCBpdCBhIHVzYWJsZSBVUkkgb3IgdGhhdCBvdXIgY2FsbGVyIGNhbgotICAgKiBtYXAgaXQgdG8gb25lLgotICAgKiAlUkVWSUVXJSBSZXNvbHZlIFB1YmxpYyBJZGVudGlmaWVycy4uLiBvciBjb25zaWRlciBjaGFuZ2luZyBmdW5jdGlvbiBuYW1lLgotICAgKiA8cD4KLSAgICogSWYgd2UgZmluZCBhIHJlbGF0aXZlIFVSSQotICAgKiByZWZlcmVuY2UsIFhNTCBleHBlY3RzIGl0IHRvIGJlIHJlc29sdmVkIGluIHRlcm1zIG9mIHRoZSBiYXNlIFVSSQotICAgKiBvZiB0aGUgZG9jdW1lbnQuIFRoZSBET00gZG9lc24ndCBkbyB0aGF0IGZvciB1cywgYW5kIGl0IGlzbid0Ci0gICAqIGVudGlyZWx5IGNsZWFyIHdoZXRoZXIgdGhhdCBzaG91bGQgYmUgZG9uZSBoZXJlOyBjdXJyZW50bHkgdGhhdCdzCi0gICAqIHB1c2hlZCB1cCB0byBhIGhpZ2hlciBsZXZlbCBvZiBvdXIgYXBwbGljYXRpb24uIChOb3RlIHRoYXQgRE9NIExldmVsCi0gICAqIDEgZGlkbid0IHN0b3JlIHRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLikKLSAgICogJVJFVklFVyUgQ29uc2lkZXIgcmVzb2x2aW5nIFJlbGF0aXZlIFVSSXMuCi0gICAqIDxwPgotICAgKiAoVGhlIERPTSdzIHN0YXRlbWVudCB0aGF0ICJBbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8KLSAgICogY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgaXMgcGFzc2VkCi0gICAqIHRvIHRoZSBET00iIHJlZmVycyBvbmx5IHRvIHBhcnNlZCBlbnRpdGllcywgbm90IHVucGFyc2VkLCBhbmQgaGVuY2UKLSAgICogZG9lc24ndCBhZmZlY3QgdGhpcyBmdW5jdGlvbi4pCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIEVudGl0eSBOYW1lIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIFVSSSBvZiB0aGUgVW5wYXJzZWQgRW50aXR5LCBvciBhbgotICAgKiBlbXB0eSBzdHJpbmcgaWYgbm8gc3VjaCBlbnRpdHkgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eVVSSShTdHJpbmcgbmFtZSk7Ci0KLSAgLy8gPT09PT09PT09PT09PT0gQm9vbGVhbiBtZXRob2RzID09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogUmV0dXJuIHRydWUgaWYgdGhlIHhzbDpzdHJpcC1zcGFjZSBvciB4c2w6cHJlc2VydmUtc3BhY2Ugd2FzIHByb2Nlc3NlZAotICAgKiBkdXJpbmcgY29uc3RydWN0aW9uIG9mIHRoZSBkb2N1bWVudCBjb250YWluZWQgaW4gdGhpcyBEVE0uCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzUHJlU3RyaXBwaW5nKCk7Ci0KLSAgLyoqCi0gICAqIEZpZ3VyZSBvdXQgd2hldGhlciBub2RlSGFuZGxlMiBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBiZWluZyBsYXRlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgdGhhbiBub2RlSGFuZGxlMSwgaW4gRG9jdW1lbnQgT3JkZXIgYXMgZGVmaW5lZAotICAgKiBieSB0aGUgWFBhdGggbW9kZWwuIFRoaXMgbWF5IG5vdCBhZ3JlZSB3aXRoIHRoZSBvcmRlcmluZyBkZWZpbmVkCi0gICAqIGJ5IG90aGVyIFhNTCBhcHBsaWNhdGlvbnMuCi0gICAqIDxwPgotICAgKiBUaGVyZSBhcmUgc29tZSBjYXNlcyB3aGVyZSBvcmRlcmluZyBpc24ndCBkZWZpbmVkLCBhbmQgbmVpdGhlciBhcmUKLSAgICogdGhlIHJlc3VsdHMgb2YgdGhpcyBmdW5jdGlvbiAtLSB0aG91Z2ggd2UnbGwgZ2VuZXJhbGx5IHJldHVybiB0cnVlLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgTWFrZSBzdXJlIHRoaXMgZG9lcyB0aGUgcmlnaHQgdGhpbmcgd2l0aCBhdHRyaWJ1dGUgbm9kZXMhISEKLSAgICogPHA+Ci0gICAqICVSRVZJRVclIENvbnNpZGVyIHJlbmFtaW5nIGZvciBjbGFyaXR5LiBQZXJoYXBzIGlzRG9jdW1lbnRPcmRlcihhLGIpPwotICAgKgotICAgKiBAcGFyYW0gZmlyc3ROb2RlSGFuZGxlIERPTSBOb2RlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbi4KLSAgICogQHBhcmFtIHNlY29uZE5vZGVIYW5kbGUgRE9NIE5vZGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uLgotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlIGlmIHNlY29uZE5vZGUgY29tZXMgYmVmb3JlIGZpcnN0Tm9kZSwgb3RoZXJ3aXNlIHJldHVybiB0cnVlLgotICAgKiBZb3UgY2FuIHRoaW5rIG9mIHRoaXMgYXMKLSAgICogPGNvZGU+KGZpcnN0Tm9kZS5kb2N1bWVudE9yZGVyUG9zaXRpb24gJmx0Oz0gc2Vjb25kTm9kZS5kb2N1bWVudE9yZGVyUG9zaXRpb24pPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTm9kZUFmdGVyKGludCBmaXJzdE5vZGVIYW5kbGUsIGludCBzZWNvbmROb2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogMi4gW2VsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlXSBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGEKLSAgICogdGV4dCBub2RlIHJlcHJlc2VudHMgd2hpdGUgc3BhY2UgYXBwZWFyaW5nIHdpdGhpbiBlbGVtZW50IGNvbnRlbnQKLSAgICogKHNlZSBbWE1MXSwgMi4xMCAiV2hpdGUgU3BhY2UgSGFuZGxpbmciKS4gIE5vdGUgdGhhdCB2YWxpZGF0aW5nCi0gICAqIFhNTCBwcm9jZXNzb3JzIGFyZSByZXF1aXJlZCBieSBYTUwgMS4wIHRvIHByb3ZpZGUgdGhpcwotICAgKiBpbmZvcm1hdGlvbi4uLiBidXQgdGhhdCBET00gTGV2ZWwgMiBkaWQgbm90IHN1cHBvcnQgaXQsIHNpbmNlIGl0Ci0gICAqIGRlcGVuZHMgb24ga25vd2xlZGdlIG9mIHRoZSBEVEQgd2hpY2ggRE9NMiBjb3VsZCBub3QgZ3VhcmFudGVlCi0gICAqIHdvdWxkIGJlIGF2YWlsYWJsZS4KLSAgICogPHA+Ci0gICAqIElmIHRoZXJlIGlzIG5vIGRlY2xhcmF0aW9uIGZvciB0aGUgY29udGFpbmluZyBlbGVtZW50LCBhbiBYTUwKLSAgICogcHJvY2Vzc29yIG11c3QgYXNzdW1lIHRoYXQgdGhlIHdoaXRlc3BhY2UgY291bGQgYmUgbWVhbmluZ2Z1bCBhbmQKLSAgICogcmV0dXJuIGZhbHNlLiBJZiBubyBkZWNsYXJhdGlvbiBoYXMgYmVlbiByZWFkLCBidXQgdGhlIFthbGwKLSAgICogZGVjbGFyYXRpb25zIHByb2Nlc3NlZF0gcHJvcGVydHkgb2YgdGhlIGRvY3VtZW50IGluZm9ybWF0aW9uIGl0ZW0KLSAgICogaXMgZmFsc2UgKHNvIHRoZXJlIG1heSBiZSBhbiB1bnJlYWQgZGVjbGFyYXRpb24pLCB0aGVuIHRoZSB2YWx1ZQotICAgKiBvZiB0aGlzIHByb3BlcnR5IGlzIGluZGV0ZXJtaW5hdGUgZm9yIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMgYW5kCi0gICAqIHNob3VsZCBwcm9iYWJseSBiZSByZXBvcnRlZCBhcyBmYWxzZS4gSXQgaXMgYWx3YXlzIGZhbHNlIGZvciB0ZXh0Ci0gICAqIG5vZGVzIHRoYXQgY29udGFpbiBhbnl0aGluZyBvdGhlciB0aGFuIChvciBpbiBhZGRpdGlvbiB0bykgd2hpdGUKLSAgICogc3BhY2UuCi0gICAqIDxwPgotICAgKiBOb3RlIHRvbyB0aGF0IGl0IGFsd2F5cyByZXR1cm5zIGZhbHNlIGZvciBub24tVGV4dCBub2Rlcy4KLSAgICogPHA+Ci0gICAqICVSRVZJRVclIEpvZSB3YW50cyB0byByZW5hbWUgdGhpcyBpc1doaXRlc3BhY2VJbkVsZW1lbnRDb250ZW50KCkgZm9yIGNsYXJpdHkKLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGUgSUQuCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5vZGUgZGVmaW5pdGVseSByZXByZXNlbnRzIHdoaXRlc3BhY2UgaW4KLSAgICogZWxlbWVudCBjb250ZW50OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNDaGFyYWN0ZXJFbGVtZW50Q29udGVudFdoaXRlc3BhY2UoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiAgICAxMC4gW2FsbCBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBUaGlzIHByb3BlcnR5IGlzIG5vdCBzdHJpY3RseSBzcGVha2luZwotICAgKiAgICAgICAgcGFydCBvZiB0aGUgaW5mb3NldCBvZiB0aGUgZG9jdW1lbnQuIFJhdGhlciBpdCBpcyBhbiBpbmRpY2F0aW9uIG9mCi0gICAqICAgICAgICB3aGV0aGVyIHRoZSBwcm9jZXNzb3IgaGFzIHJlYWQgdGhlIGNvbXBsZXRlIERURC4gSXRzIHZhbHVlIGlzIGEKLSAgICogICAgICAgIGJvb2xlYW4uIElmIGl0IGlzIGZhbHNlLCB0aGVuIGNlcnRhaW4gcHJvcGVydGllcyAoaW5kaWNhdGVkIGluIHRoZWlyCi0gICAqICAgICAgICBkZXNjcmlwdGlvbnMgYmVsb3cpIG1heSBiZSB1bmtub3duLiBJZiBpdCBpcyB0cnVlLCB0aG9zZSBwcm9wZXJ0aWVzCi0gICAqICAgICAgICBhcmUgbmV2ZXIgdW5rbm93bi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHRoZSBkb2N1bWVudCBoYW5kbGUKLSAgICoKLSAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlIEEgbm9kZSBoYW5kbGUgdGhhdCBtdXN0IGlkZW50aWZ5IGEgZG9jdW1lbnQuCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYWxsIGRlY2xhcmF0aW9ucyB3ZXJlIHByb2Nlc3NlZDsKLSAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZChpbnQgZG9jdW1lbnRIYW5kbGUpOwotCi0gIC8qKgotICAgKiAgICAgNS4gW3NwZWNpZmllZF0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSB3YXMgYWN0dWFsbHkKLSAgICogICAgICAgIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQtdGFnIG9mIGl0cyBlbGVtZW50LCBvciB3YXMgZGVmYXVsdGVkIGZyb20gdGhlCi0gICAqICAgICAgICBEVEQgKG9yIHNjaGVtYSkuCi0gICAqCi0gICAqIEBwYXJhbSB0aGUgYXR0cmlidXRlIGhhbmRsZQotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gYXR0cmlidXRlSGFuZGxlCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGF0dHJpYnV0ZSB3YXMgc3BlY2lmaWVkOwotICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCB3YXMgZGVmYXVsdGVkIG9yIHRoZSBoYW5kbGUgZG9lc24ndAotICAgKiAgICAgICAgICAgIHJlZmVyIHRvIGFuIGF0dHJpYnV0ZSBub2RlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaW50IGF0dHJpYnV0ZUhhbmRsZSk7Ci0KLSAgLy8gPT09PT09PT09PSBEaXJlY3QgU0FYIERpc3BhdGNoLCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzID09PT09PT09Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICogQHBhcmFtIG5vcm1hbGl6ZSB0cnVlIGlmIHRoZSBjb250ZW50IHNob3VsZCBiZSBub3JtYWxpemVkIGFjY29yZGluZyB0bwotICAgKiB0aGUgcnVsZXMgZm9yIHRoZSBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNmdW5jdGlvbi1ub3JtYWxpemUtc3BhY2UiPm5vcm1hbGl6ZS1zcGFjZTwvYT4KLSAgICogZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoCi0gICAgaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoLCBib29sZWFuIG5vcm1hbGl6ZSkKLSAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNyZWF0ZSBTQVggcGFyc2VyIGV2ZW50cyByZXByZXNlbnRpbmcgdGhlIFhNTCBjb250ZW50IG9mCi0gICAqIGEgRFRNIHN1YnRyZWUuIFRoaXMgaXMgYSAic2VyaWFsaXplIiBvcGVyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoVG9FdmVudHMoaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhbiBET00gbm9kZSBmb3IgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgbm9kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgRFRNIG5vZGUuCi0gICAqLwotICBwdWJsaWMgb3JnLnczYy5kb20uTm9kZSBnZXROb2RlKGludCBub2RlSGFuZGxlKTsKLQotICAvLyA9PT09IENvbnN0cnVjdGlvbiBtZXRob2RzIChtYXkgbm90IGJlIHN1cHBvcnRlZCBieSBzb21lIGltcGxlbWVudGF0aW9ucyEpID09PT09Ci0gIC8vICVSRVZJRVclIFdoYXQgcmVzcG9uc2Ugb2NjdXJzIGlmIG5vdCBzdXBwb3J0ZWQ/Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZmYgd2UncmUgYnVpbGRpbmcgdGhpcyBtb2RlbCBpbmNyZW1lbnRhbGx5IChlZwotICAgKiB3ZSdyZSBwYXJ0bmVyZWQgd2l0aCBhIENvcm91dGluZVBhcnNlcikgYW5kIHRodXMgcmVxdWlyZSB0aGF0IHRoZQotICAgKiB0cmFuc2Zvcm1hdGlvbiBhbmQgdGhlIHBhcnNlIHJ1biBzaW11bHRhbmVvdXNseS4gR3VpZGFuY2UgdG8gdGhlCi0gICAqIERUTU1hbmFnZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBuZWVkc1R3b1RocmVhZHMoKTsKLQotICAvLyAlUkVWSUVXJSBEbyB0aGVzZSBhcHBlbmRzIG1ha2UgYW55IHNlbnNlLCBzaG91bGQgd2Ugc3VwcG9ydCBhCi0gIC8vIHdpZGVyIHNldCBvZiBtZXRob2RzIChsaWtlIHRoZSAiYXBwZW5kIiBtZXRob2RzIGluIHRoZQotICAvLyBjdXJyZW50IERUTURvY3VtZW50SW1wbCBkcmFmdCksIG9yIHNob3VsZCB3ZSBqdXN0IHN1cHBvcnQgU0FYCi0gIC8vIGxpc3RlbmVyIGludGVyZmFjZXM/ICBTaG91bGQgaXQgYmUgYSBzZXBhcmF0ZSBpbnRlcmZhY2UgdG8KLSAgLy8gbWFrZSB0aGF0IGRpc3RpbmN0aW9uIGV4cGxpY2l0PwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBjb250ZW50IGhhbmRsZXIsIGlmIGl0IGhhcyBvbmUuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIGxleGljYWwgaGFuZGxlciwgaWYgaXQgaGFzIG9uZS4KLSAgICoKLSAgICogJVJFVklFVyUgU2hvdWxkIHRoaXMgcmV0dXJuIG51bGwgaWYgY29uc3RydXRpb24gYWxyZWFkeSBkb25lL2JlZ3VuPwotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gbGV4aWNhbCBTQVggZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBnZXRMZXhpY2FsSGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFbnRpdHlSZXNvbHZlciwgaWYgaXQgaGFzIG9uZS4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBlbnRpdHkgcmVmIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlciBnZXRFbnRpdHlSZXNvbHZlcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBEVERIYW5kbGVyLCBpZiBpdCBoYXMgb25lLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGR0ZCBldmVudHMuCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguRFRESGFuZGxlciBnZXREVERIYW5kbGVyKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIEVycm9ySGFuZGxlciwgaWYgaXQgaGFzIG9uZS4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBlcnJvciBldmVudHMuCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBEZWNsSGFuZGxlciwgaWYgaXQgaGFzIG9uZS4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBEZWNsIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIgZ2V0RGVjbEhhbmRsZXIoKTsKLQotICAvKioKLSAgICogQXBwZW5kIGEgY2hpbGQgdG8gInRoZSBlbmQgb2YgdGhlIGRvY3VtZW50Ii4gUGxlYXNlIG5vdGUgdGhhdAotICAgKiB0aGUgbm9kZSBpcyBhbHdheXMgY2xvbmVkIGluIGEgYmFzZSBEVE0sIHNpbmNlIG91ciBiYXNpYyBiZWhhdmlvcgotICAgKiBpcyBpbW11dGFibGUgc28gbm9kZXMgY2FuJ3QgYmUgcmVtb3ZlZCBmcm9tIHRoZWlyIHByZXZpb3VzCi0gICAqIGxvY2F0aW9uLgotICAgKgotICAgKiA8cD4gJVJFVklFVyUgIERUTSBtYWludGFpbnMgYW4gaW5zZXJ0aW9uIGN1cnNvciB3aGljaAotICAgKiBwZXJmb3JtcyBhIGRlcHRoLWZpcnN0IHRyZWUgd2FsayBhcyBub2RlcyBjb21lIGluLCBhbmQgdGhpcyBvcGVyYXRpb24KLSAgICogaXMgcmVhbGx5IGVxdWl2YWxlbnQgdG86Ci0gICAqICAgIGluc2VydGlvbkN1cnNvci5hcHBlbmRDaGlsZChkb2N1bWVudC5pbXBvcnROb2RlKG5ld0NoaWxkKSkpCi0gICAqIHdoZXJlIHRoZSBpbnNlcnQgcG9pbnQgaXMgdGhlIGxhc3QgZWxlbWVudCB0aGF0IHdhcyBhcHBlbmRlZCAob3IKLSAgICogdGhlIGxhc3Qgb25lIHBvcHBlZCBiYWNrIHRvIGJ5IGFuIGVuZC1lbGVtZW50IG9wZXJhdGlvbikuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgTXVzdCBiZSBhIHZhbGlkIG5ldyBub2RlIGhhbmRsZS4KLSAgICogQHBhcmFtIGNsb25lIHRydWUgaWYgdGhlIGNoaWxkIHNob3VsZCBiZSBjbG9uZWQgaW50byB0aGUgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBjbG9uZURlcHRoIGlmIHRoZSBjbG9uZSBhcmd1bWVudCBpcyB0cnVlLCBzcGVjaWZpZXMgdGhhdCB0aGUKLSAgICogICAgICAgICAgICAgICAgICAgY2xvbmUgc2hvdWxkIGluY2x1ZGUgYWxsIGl0J3MgY2hpbGRyZW4uCi0gICAqLwotICBwdWJsaWMgdm9pZCBhcHBlbmRDaGlsZChpbnQgbmV3Q2hpbGQsIGJvb2xlYW4gY2xvbmUsIGJvb2xlYW4gY2xvbmVEZXB0aCk7Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIHRleHQgbm9kZSBjaGlsZCB0aGF0IHdpbGwgYmUgY29uc3RydWN0ZWQgZnJvbSBhIHN0cmluZywKLSAgICogdG8gdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuIEJlaGF2aW9yIGlzIG90aGVyd2lzZSBsaWtlIGFwcGVuZENoaWxkKCkuCi0gICAqCi0gICAqIEBwYXJhbSBzdHIgTm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVGV4dENoaWxkKFN0cmluZyBzdHIpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxvY2F0aW9uIG9mIGEgbm9kZSBpbiB0aGUgc291cmNlIGRvY3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gYSA8Y29kZT5Tb3VyY2VMb2NhdG9yPC9jb2RlPiB2YWx1ZSBvciBudWxsIGlmIG5vIGxvY2F0aW9uCi0gICAqIGlzIGF2YWlsYWJsZQotICAgKi8KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSk7Ci0KLSAgLyoqCi0gICAqIEFzIHRoZSBEVE0gaXMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBEVE1NYW5hZ2VyLCB0aGlzIG1ldGhvZAotICAgKiB3aWxsIGJlIGNhbGxlZC4gVGhpcyB3aWxsIGdpdmUgdGhlIERUTSBpbXBsZW1lbnRhdGlvbiBhCi0gICAqIGNoYW5jZSB0byBpbml0aWFsaXplIGFueSBzdWJzeXN0ZW1zIHRoYXQgYXJlIHJlcXVpcmVkIHRvCi0gICAqIGJ1aWxkIHRoZSBEVE0KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRvY3VtZW50UmVnaXN0cmF0aW9uKCk7Ci0KLSAgLyoqCi0gICAqIEFzIGRvY3VtZW50cyBhcmUgcmVsZWFzZWQgZnJvbSB0aGUgRFRNTWFuYWdlciwgdGhlIERUTSBpbXBsZW1lbnRhdGlvbgotICAgKiB3aWxsIGJlIG5vdGlmaWVkIG9mIHRoZSBldmVudC4gVGhpcyB3aWxsIGFsbG93IHRoZSBEVE0gaW1wbGVtZW50YXRpb24KLSAgICogdG8gc2h1dGRvd24gYW55IHN1YnN5c3RlbSBhY3Rpdml0eSB0aGF0IG1heSBvZiBiZWVuIGFzc29pYXRlZCB3aXRoCi0gICAqIHRoZSBhY3RpdmUgRFRNIEltcGxlbWVudGF0aW9uLgotICAgKi8KLQotICAgcHVibGljIHZvaWQgZG9jdW1lbnRSZWxlYXNlKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL0RUTUF4aXNJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1BeGlzSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjkxZjNkMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL0RUTUF4aXNJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGl0ZXJhdGVzIG92ZXIgYSBzaW5nbGUgWFBhdGggQXhpcywgYW5kIHJldHVybnMgbm9kZSBoYW5kbGVzLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTUF4aXNJdGVyYXRvciBleHRlbmRzIENsb25lYWJsZQotewotCi0gIC8qKiBTcGVjaWZpZXMgdGhlIGVuZCBvZiB0aGUgaXRlcmF0aW9uLCBhbmQgaXMgdGhlIHNhbWUgYXMgRFRNLk5VTEwuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkQgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHQoKTsKLQotICAvKioKLSAgICogUmVzZXRzIHRoZSBpdGVyYXRvciB0byB0aGUgbGFzdCBzdGFydCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzIAotICAgKiAgICAgICAgIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpOwotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhpcyBpdGVyYXRvci4gIFRoaXMgbWF5IGJlIGFuIGV4cGVuc2l2ZSAKLSAgICogb3BlcmF0aW9uIHdoZW4gY2FsbGVkIHRoZSBmaXJzdCB0aW1lLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0KCk7Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNldCwgYXMgZGVmaW5lZCBieSBYUGF0aC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKTsKLQotICAvKioKLSAgICogUmVtZW1iZXJzIHRoZSBjdXJyZW50IG5vZGUgZm9yIHRoZSBuZXh0IGNhbGwgdG8gZ290b01hcmsoKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1hcmsoKTsKLQotICAvKioKLSAgICogUmVzdG9yZXMgdGhlIGN1cnJlbnQgbm9kZSByZW1lbWJlcmVkIGJ5IHNldE1hcmsoKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGdvdG9NYXJrKCk7Ci0KLSAgLyoqCi0gICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSk7Ci0KLSAgLyoqCi0gICAqIEdldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJvb3Qgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRTdGFydE5vZGUoKTsKLQotICAvKioKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcywgZWxzZSBmYWxzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZSgpOwotCi0gIC8qKgotICAgKiBAcmV0dXJuIGEgZGVlcCBjb3B5IG9mIHRoaXMgaXRlcmF0b3IuIFRoZSBjbG9uZSBzaG91bGQgbm90IGJlIHJlc2V0IAotICAgKiBmcm9tIGl0cyBjdXJyZW50IHBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL0RUTUF4aXNUcmF2ZXJzZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNQXhpc1RyYXZlcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOTA1YjIyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNQXhpc1RyYXZlcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bTsKLQotLyoqCi0gKiBBIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0cmF2ZXJzZXMgRFRNQXhpc1RyYXZlcnNlciBpbnRlcmZhY2UgY2FuIHRyYXZlcnNlCi0gKiBhIHNldCBvZiBub2RlcywgdXN1YWxseSBhcyBkZWZpbmVkIGJ5IGFuIFhQYXRoIGF4aXMuICBJdCBpcyBkaWZmZXJlbnQgZnJvbQotICogYW4gaXRlcmF0b3IsIGJlY2F1c2UgaXQgZG9lcyBub3QgbmVlZCB0byBob2xkIHN0YXRlLCBhbmQsIGluIGZhY3QsIG11c3Qgbm90Ci0gKiBob2xkIGFueSBpdGVyYXRpb24tYmFzZWQgc3RhdGUuICBJdCBpcyBtZWFudCB0byBiZSBpbXBsZW1lbnRlZCBhcyBhbiBpbm5lcgotICogY2xhc3Mgb2YgYSBEVE0sIGFuZCByZXR1cm5lZCBieSB0aGUgZ2V0QXhpc1RyYXZlcnNlcihmaW5hbCBpbnQgYXhpcykKLSAqIGZ1bmN0aW9uLgotICoKLSAqIDxwPkEgRFRNQXhpc1RyYXZlcnNlciBjYW4gcHJvYmFibHkgbm90IHRyYXZlcnNlIGEgcmV2ZXJzZSBheGlzIGluCi0gKiBkb2N1bWVudCBvcmRlci48L3A+Ci0gKgotICogPHA+VHlwaWNhbCB1c2FnZTo8L3A+Ci0gKiA8cHJlPjxjb2RlPgotICogZm9yKGludCBub2RlSGFuZGxlPW15VHJhdmVyc2VyLmZpcnN0KG15Q29udGV4dCk7Ci0gKiAgICAgbm9kZUhhbmRsZSE9RFRNLk5VTEw7Ci0gKiAgICAgbm9kZUhhbmRsZT1teVRyYXZlcnNlci5uZXh0KG15Q29udGV4dCxub2RlSGFuZGxlKSkKLSAqIHsgLi4uIHByb2Nlc3NpbmcgZm9yIG5vZGUgaW5kaWNhdGVkIGJ5IG5vZGVIYW5kbGUgZ29lcyBoZXJlIC4uLiB9Ci0gKiA8L2NvZGU+PC9wcmU+Ci0gKgotICogQGF1dGhvciBTY290dCBCb2FnCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEVE1BeGlzVHJhdmVyc2VyCi17Ci0KLSAgLyoqCi0gICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgU28gdG8gdHJhdmVyc2UgCi0gICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgKgotICAgKiA8cD5UaGlzIG1ldGhvZCBuZWVkcyB0byBiZSBvdmVybG9hZGVkIG9ubHkgYnkgdGhvc2UgYXhpcyB0aGF0IHByb2Nlc3MKLSAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgKiB0aGF0IHRoZSB0cmF2ZXJzYWwgc3RhcnRzIGZyb20uCi0gICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gIHsKLSAgICByZXR1cm4gbmV4dChjb250ZXh0LCBjb250ZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFNvIHRvIHRyYXZlcnNlIAotICAgKiBhbiBheGlzLCB0aGUgZmlyc3QgZnVuY3Rpb24gbXVzdCBiZSB1c2VkIHRvIGdldCB0aGUgZmlyc3Qgbm9kZS4KLSAgICoKLSAgICogPHA+VGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgb3ZlcmxvYWRlZCBvbmx5IGJ5IHRob3NlIGF4aXMgdGhhdCBwcm9jZXNzCi0gICAqIHRoZSBzZWxmIG5vZGUuIDxccD4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4gVGhpcyBpcyB0aGUgcG9pbnQKLSAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICogQHBhcmFtIGV4dGVuZGVkVHlwZUlEIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgKi8KLSAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICB7Ci0gICAgcmV0dXJuIG5leHQoY29udGV4dCwgY29udGV4dCwgZXh0ZW5kZWRUeXBlSUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4gVGhpcyBpcyB0aGUgcG9pbnQKLSAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBsYXN0IGtub3duCi0gICAqIGxvY2F0aW9uIGluIHRoZSB0cmF2ZXJzYWwsIHR5cGljYWxseSB0aGUgbm9kZS1oYW5kbGUgcmV0dXJuZWQgYnkgdGhlCi0gICAqIHByZXZpb3VzIHRyYXZlcnNhbCBzdGVwLiBGb3IgdGhlIGZpcnN0IHRyYXZlcnNhbCBzdGVwLCBjb250ZXh0Ci0gICAqIHNob3VsZCBiZSBzZXQgZXF1YWwgdG8gY3VycmVudC4gTm90ZSB0aGF0IGluIG9yZGVyIHRvIHRlc3Qgd2hldGhlcgotICAgKiBjb250ZXh0IGlzIGluIHRoZSBzZXQsIHlvdSBtdXN0IHVzZSB0aGUgZmlyc3QoKSBtZXRob2QgaW5zdGVhZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgKiBAc2VlIGZpcnN0KGludCkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpOwotCi0gIC8qKgotICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAqIGJ5IHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIGxhc3Qga25vd24KLSAgICogbG9jYXRpb24gaW4gdGhlIHRyYXZlcnNhbCwgdHlwaWNhbGx5IHRoZSBub2RlLWhhbmRsZSByZXR1cm5lZCBieSB0aGUKLSAgICogcHJldmlvdXMgdHJhdmVyc2FsIHN0ZXAuIEZvciB0aGUgZmlyc3QgdHJhdmVyc2FsIHN0ZXAsIGNvbnRleHQKLSAgICogc2hvdWxkIGJlIHNldCBlcXVhbCB0byBjdXJyZW50LiBOb3RlIHRoYXQgaW4gb3JkZXIgdG8gdGVzdCB3aGV0aGVyCi0gICAqIGNvbnRleHQgaXMgaW4gdGhlIHNldCwgeW91IG11c3QgdXNlIHRoZSBmaXJzdCgpIG1ldGhvZCBpbnN0ZWFkLgotICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAqIEBzZWUgZmlyc3QoaW50LGludCkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL0RUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZmQxNTBkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODAgKzAsMCBAQAotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG07Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLS8qKgotICogSW5kaWNhdGVzIGEgc2VyaW91cyBjb25maWd1cmF0aW9uIGVycm9yLgotICovCi1wdWJsaWMgY2xhc3MgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIERUTUV4Y2VwdGlvbiB7Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCBubwotICAgICAqIGRldGFpbCBtZXNhZ2UuCi0gICAgICovCi0gICAgcHVibGljIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oKSB7Ci0gICAgICAgIHN1cGVyKCJDb25maWd1cmF0aW9uIEVycm9yIik7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb248L2NvZGU+IHdpdGgKLSAgICAgKiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT4gc3BlY2lmaWVkIGFzIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbXNnIFRoZSBlcnJvciBtZXNzYWdlIGZvciB0aGUgZXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKLSAgICAgICAgc3VwZXIobXNnKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjwvY29kZT4gd2l0aCBhCi0gICAgICogZ2l2ZW4gPGNvZGU+RXhjZXB0aW9uPC9jb2RlPiBiYXNlIGNhdXNlIG9mIHRoZSBlcnJvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgZW5jYXBzdWxhdGVkIGluIGEKLSAgICAgKiBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKFRocm93YWJsZSBlKSB7Ci0gICAgICAgIHN1cGVyKGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uPC9jb2RlPiB3aXRoIHRoZQotICAgICAqIGdpdmVuIDxjb2RlPkV4Y2VwdGlvbjwvY29kZT4gYmFzZSBjYXVzZSBhbmQgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAgICogRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgICAqIEBwYXJhbSBtc2cgVGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdG8gYmUgd3JhcHBlZCBpbiBhIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbXNnLCBUaHJvd2FibGUgZSkgewotICAgICAgICBzdXBlcihtc2csIGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uIGZyb20gYSBtZXNzYWdlIGFuZCBhIExvY2F0b3IuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNvbnN0cnVjdG9yIGlzIGVzcGVjaWFsbHkgdXNlZnVsIHdoZW4gYW4gYXBwbGljYXRpb24gaXMKLSAgICAgKiBjcmVhdGluZyBpdHMgb3duIGV4Y2VwdGlvbiBmcm9tIHdpdGhpbiBhIERvY3VtZW50SGFuZGxlcgotICAgICAqIGNhbGxiYWNrLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBvciB3YXJuaW5nIG1lc3NhZ2UuCi0gICAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0b3Igb2JqZWN0IGZvciB0aGUgZXJyb3Igb3Igd2FybmluZy4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvcikgewotICAgICAgICBzdXBlcihtZXNzYWdlLCBsb2NhdG9yKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiBpbiBhIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLCBvciBudWxsIHRvCi0gICAgICogICAgICAgICAgICAgICAgdXNlIHRoZSBtZXNzYWdlIGZyb20gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciBvYmplY3QgZm9yIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBlIEFueSBleGNlcHRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJvd2FibGUgZSkgewotICAgICAgICBzdXBlcihtZXNzYWdlLCBsb2NhdG9yLCBlKTsKLSAgICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1ET01FeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNRE9NRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIyMzVjYzAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1ET01FeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBET01FeGNlcHRpb24uCi0gKgotICogJVJFVklFVyUgU2V2ZXJhbCBjbGFzc2VzIHdlcmUgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJuYWxseTsKLSAqIGl0IG1ha2VzIG1vcmUgc2Vuc2UgdG8gaGF2ZSBvbmUgc2hhcmVkIHZlcnNpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBEVE1ET01FeGNlcHRpb24gZXh0ZW5kcyBvcmcudzNjLmRvbS5ET01FeGNlcHRpb24KLXsKLSAgLyoqCi0gICAqIENvbnN0cnVjdHMgYSBET00vRFRNIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGNvZGUKLSAgICogQHBhcmFtIG1lc3NhZ2UKLSAgICovCi0gIHB1YmxpYyBEVE1ET01FeGNlcHRpb24oc2hvcnQgY29kZSwgU3RyaW5nIG1lc3NhZ2UpCi0gIHsKLSAgICBzdXBlcihjb2RlLCBtZXNzYWdlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBEVE1ET01FeGNlcHRpb24KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGNvZGUKLSAgICovCi0gIHB1YmxpYyBEVE1ET01FeGNlcHRpb24oc2hvcnQgY29kZSkKLSAgewotICAgIHN1cGVyKGNvZGUsICIiKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1FeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYyZmVmMWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1FeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM1MSArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bTsKLQotCi1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotaW1wb3J0IGphdmEubGFuZy5JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotCi0vKioKLSAqIFRoaXMgY2xhc3Mgc3BlY2lmaWVzIGFuIGV4Y2VwdGlvbmFsIGNvbmRpdGlvbiB0aGF0IG9jY3VyZWQKLSAqIGluIHRoZSBEVE0gbW9kdWxlLgotICovCi1wdWJsaWMgY2xhc3MgRFRNRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7Ci0KLSAgICAvKiogRmllbGQgbG9jYXRvciBzcGVjaWZpZXMgd2hlcmUgdGhlIGVycm9yIG9jY3VyZWQuCi0gICAgICogIEBzZXJpYWwgKi8KLSAgICBTb3VyY2VMb2NhdG9yIGxvY2F0b3I7Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2QgZ2V0TG9jYXRvciByZXRyaWV2ZXMgYW4gaW5zdGFuY2Ugb2YgYSBTb3VyY2VMb2NhdG9yCi0gICAgICogb2JqZWN0IHRoYXQgc3BlY2lmaWVzIHdoZXJlIGFuIGVycm9yIG9jY3VyZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgU291cmNlTG9jYXRvciBvYmplY3QsIG9yIG51bGwgaWYgbm9uZSB3YXMgc3BlY2lmaWVkLgotICAgICAqLwotICAgIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldExvY2F0b3IoKSB7Ci0gICAgICAgIHJldHVybiBsb2NhdG9yOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIE1ldGhvZCBzZXRMb2NhdG9yIHNldHMgYW4gaW5zdGFuY2Ugb2YgYSBTb3VyY2VMb2NhdG9yCi0gICAgICogb2JqZWN0IHRoYXQgc3BlY2lmaWVzIHdoZXJlIGFuIGVycm9yIG9jY3VyZWQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbG9jYXRpb24gQSBTb3VyY2VMb2NhdG9yIG9iamVjdCwgb3IgbnVsbCB0byBjbGVhciB0aGUgbG9jYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0TG9jYXRvcihTb3VyY2VMb2NhdG9yIGxvY2F0aW9uKSB7Ci0gICAgICAgIGxvY2F0b3IgPSBsb2NhdGlvbjsKLSAgICB9Ci0KLSAgICAvKiogRmllbGQgY29udGFpbmVkRXhjZXB0aW9uIHNwZWNpZmllcyBhIHdyYXBwZWQgZXhjZXB0aW9uLiAgTWF5IGJlIG51bGwuCi0gICAgICogIEBzZXJpYWwgKi8KLSAgICBUaHJvd2FibGUgY29udGFpbmVkRXhjZXB0aW9uOwotCi0gICAgLyoqCi0gICAgICogVGhpcyBtZXRob2QgcmV0cmlldmVzIGFuIGV4Y2VwdGlvbiB0aGF0IHRoaXMgZXhjZXB0aW9uIHdyYXBzLgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBUaHJvd2FibGUgb2JqZWN0LCBvciBudWxsLgotICAgICAqIEBzZWUgI2dldENhdXNlCi0gICAgICovCi0gICAgcHVibGljIFRocm93YWJsZSBnZXRFeGNlcHRpb24oKSB7Ci0gICAgICAgIHJldHVybiBjb250YWluZWRFeGNlcHRpb247Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgY2F1c2Ugb2YgdGhpcyB0aHJvd2FibGUgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCi0gICAgICogY2F1c2UgaXMgbm9uZXhpc3RlbnQgb3IgdW5rbm93bi4gIChUaGUgY2F1c2UgaXMgdGhlIHRocm93YWJsZSB0aGF0Ci0gICAgICogY2F1c2VkIHRoaXMgdGhyb3dhYmxlIHRvIGdldCB0aHJvd24uKQotICAgICAqLwotICAgIHB1YmxpYyBUaHJvd2FibGUgZ2V0Q2F1c2UoKSB7Ci0KLSAgICAgICAgcmV0dXJuICgoY29udGFpbmVkRXhjZXB0aW9uID09IHRoaXMpCi0gICAgICAgICAgICAgICAgPyBudWxsCi0gICAgICAgICAgICAgICAgOiBjb250YWluZWRFeGNlcHRpb24pOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEluaXRpYWxpemVzIHRoZSA8aT5jYXVzZTwvaT4gb2YgdGhpcyB0aHJvd2FibGUgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4KLSAgICAgKiAoVGhlIGNhdXNlIGlzIHRoZSB0aHJvd2FibGUgdGhhdCBjYXVzZWQgdGhpcyB0aHJvd2FibGUgdG8gZ2V0IHRocm93bi4pCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGF0IG1vc3Qgb25jZS4gIEl0IGlzIGdlbmVyYWxseSBjYWxsZWQgZnJvbQotICAgICAqIHdpdGhpbiB0aGUgY29uc3RydWN0b3IsIG9yIGltbWVkaWF0ZWx5IGFmdGVyIGNyZWF0aW5nIHRoZQotICAgICAqIHRocm93YWJsZS4gIElmIHRoaXMgdGhyb3dhYmxlIHdhcyBjcmVhdGVkCi0gICAgICogd2l0aCB7QGxpbmsgI0RUTUV4Y2VwdGlvbihUaHJvd2FibGUpfSBvcgotICAgICAqIHtAbGluayAjRFRNRXhjZXB0aW9uKFN0cmluZyxUaHJvd2FibGUpfSwgdGhpcyBtZXRob2QgY2Fubm90IGJlIGNhbGxlZAotICAgICAqIGV2ZW4gb25jZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSAgY2F1c2UgdGhlIGNhdXNlICh3aGljaCBpcyBzYXZlZCBmb3IgbGF0ZXIgcmV0cmlldmFsIGJ5IHRoZQotICAgICAqICAgICAgICAge0BsaW5rICNnZXRDYXVzZSgpfSBtZXRob2QpLiAgKEEgPHR0Pm51bGw8L3R0PiB2YWx1ZSBpcwotICAgICAqICAgICAgICAgcGVybWl0dGVkLCBhbmQgaW5kaWNhdGVzIHRoYXQgdGhlIGNhdXNlIGlzIG5vbmV4aXN0ZW50IG9yCi0gICAgICogICAgICAgICB1bmtub3duLikKLSAgICAgKiBAcmV0dXJuICBhIHJlZmVyZW5jZSB0byB0aGlzIDxjb2RlPlRocm93YWJsZTwvY29kZT4gaW5zdGFuY2UuCi0gICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+Y2F1c2U8L2NvZGU+IGlzIHRoaXMKLSAgICAgKiAgICAgICAgIHRocm93YWJsZS4gIChBIHRocm93YWJsZSBjYW5ub3QKLSAgICAgKiAgICAgICAgIGJlIGl0cyBvd24gY2F1c2UuKQotICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgdGhyb3dhYmxlIHdhcwotICAgICAqICAgICAgICAgY3JlYXRlZCB3aXRoIHtAbGluayAjRFRNRXhjZXB0aW9uKFRocm93YWJsZSl9IG9yCi0gICAgICogICAgICAgICB7QGxpbmsgI0RUTUV4Y2VwdGlvbihTdHJpbmcsVGhyb3dhYmxlKX0sIG9yIHRoaXMgbWV0aG9kIGhhcyBhbHJlYWR5Ci0gICAgICogICAgICAgICBiZWVuIGNhbGxlZCBvbiB0aGlzIHRocm93YWJsZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3luY2hyb25pemVkIFRocm93YWJsZSBpbml0Q2F1c2UoVGhyb3dhYmxlIGNhdXNlKSB7Ci0KLSAgICAgICAgaWYgKCh0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9PSBudWxsKSAmJiAoY2F1c2UgIT0gbnVsbCkpIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX09WRVJXUklURV9DQVVTRSwgbnVsbCkpOyAvLyJDYW4ndCBvdmVyd3JpdGUgY2F1c2UiKTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmIChjYXVzZSA9PSB0aGlzKSB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1NFTEZfQ0FVU0FUSU9OX05PVF9QRVJNSVRURUQsIG51bGwpKTsgLy8iU2VsZi1jYXVzYXRpb24gbm90IHBlcm1pdHRlZCIpOwotICAgICAgICB9Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBjYXVzZTsKLQotICAgICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBDcmVhdGUgYSBuZXcgRFRNRXhjZXB0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7Ci0KLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBudWxsOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IERUTUV4Y2VwdGlvbiB3cmFwcGluZyBhbiBleGlzdGluZyBleGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRvIGJlIHdyYXBwZWQuCi0gICAgICovCi0gICAgcHVibGljIERUTUV4Y2VwdGlvbihUaHJvd2FibGUgZSkgewotCi0gICAgICAgIHN1cGVyKGUuZ2V0TWVzc2FnZSgpKTsKLQotICAgICAgICB0aGlzLmNvbnRhaW5lZEV4Y2VwdGlvbiA9IGU7Ci0gICAgICAgIHRoaXMubG9jYXRvciAgICAgICAgICAgID0gbnVsbDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBXcmFwIGFuIGV4aXN0aW5nIGV4Y2VwdGlvbiBpbiBhIERUTUV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgaXMgdXNlZCBmb3IgdGhyb3dpbmcgcHJvY2Vzc29yIGV4Y2VwdGlvbnMgYmVmb3JlCi0gICAgICogdGhlIHByb2Nlc3NpbmcgaGFzIHN0YXJ0ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG9yIHdhcm5pbmcgbWVzc2FnZSwgb3IgbnVsbCB0bwotICAgICAqICAgICAgICAgICAgICAgIHVzZSB0aGUgbWVzc2FnZSBmcm9tIHRoZSBlbWJlZGRlZCBleGNlcHRpb24uCi0gICAgICogQHBhcmFtIGUgQW55IGV4Y2VwdGlvbgotICAgICAqLwotICAgIHB1YmxpYyBEVE1FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBlKSB7Ci0KLSAgICAgICAgc3VwZXIoKChtZXNzYWdlID09IG51bGwpIHx8IChtZXNzYWdlLmxlbmd0aCgpID09IDApKQotICAgICAgICAgICAgICA/IGUuZ2V0TWVzc2FnZSgpCi0gICAgICAgICAgICAgIDogbWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IG51bGw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ3JlYXRlIGEgbmV3IERUTUV4Y2VwdGlvbiBmcm9tIGEgbWVzc2FnZSBhbmQgYSBMb2NhdG9yLgotICAgICAqCi0gICAgICogPHA+VGhpcyBjb25zdHJ1Y3RvciBpcyBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGFuIGFwcGxpY2F0aW9uIGlzCi0gICAgICogY3JlYXRpbmcgaXRzIG93biBleGNlcHRpb24gZnJvbSB3aXRoaW4gYSBEb2N1bWVudEhhbmRsZXIKLSAgICAgKiBjYWxsYmFjay48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIG9iamVjdCBmb3IgdGhlIGVycm9yIG9yIHdhcm5pbmcuCi0gICAgICovCi0gICAgcHVibGljIERUTUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgU291cmNlTG9jYXRvciBsb2NhdG9yKSB7Ci0KLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBudWxsOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogV3JhcCBhbiBleGlzdGluZyBleGNlcHRpb24gaW4gYSBEVE1FeGNlcHRpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLCBvciBudWxsIHRvCi0gICAgICogICAgICAgICAgICAgICAgdXNlIHRoZSBtZXNzYWdlIGZyb20gdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbi4KLSAgICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRvciBvYmplY3QgZm9yIHRoZSBlcnJvciBvciB3YXJuaW5nLgotICAgICAqIEBwYXJhbSBlIEFueSBleGNlcHRpb24KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSBlKSB7Ci0KLSAgICAgICAgc3VwZXIobWVzc2FnZSk7Ci0KLSAgICAgICAgdGhpcy5jb250YWluZWRFeGNlcHRpb24gPSBlOwotICAgICAgICB0aGlzLmxvY2F0b3IgICAgICAgICAgICA9IGxvY2F0b3I7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBlcnJvciBtZXNzYWdlIHdpdGggbG9jYXRpb24gaW5mb3JtYXRpb24KLSAgICAgKiBhcHBlbmRlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2VBbmRMb2NhdGlvbigpIHsKLQotICAgICAgICBTdHJpbmdCdWZmZXIgc2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgU3RyaW5nICAgICAgIG1lc3NhZ2UgPSBzdXBlci5nZXRNZXNzYWdlKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gbWVzc2FnZSkgewotICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQobWVzc2FnZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCAhPSBsb2NhdG9yKSB7Ci0gICAgICAgICAgICBTdHJpbmcgc3lzdGVtSUQgPSBsb2NhdG9yLmdldFN5c3RlbUlkKCk7Ci0gICAgICAgICAgICBpbnQgICAgbGluZSAgICAgPSBsb2NhdG9yLmdldExpbmVOdW1iZXIoKTsKLSAgICAgICAgICAgIGludCAgICBjb2x1bW4gICA9IGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCk7Ci0KLSAgICAgICAgICAgIGlmIChudWxsICE9IHN5c3RlbUlEKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgU3lzdGVtSUQ6ICIpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKHN5c3RlbUlEKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKDAgIT0gbGluZSkgewotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKCI7IExpbmUjOiAiKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChsaW5lKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKDAgIT0gY29sdW1uKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgQ29sdW1uIzogIik7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoY29sdW1uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBzYnVmZmVyLnRvU3RyaW5nKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBhcyBhIHN0cmluZy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBzdHJpbmcgd2l0aCBsb2NhdGlvbiBpbmZvLCBvciBudWxsCi0gICAgICogaWYgdGhlcmUgaXMgbm8gbG9jYXRpb24gaW5mb3JtYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIFN0cmluZyBnZXRMb2NhdGlvbkFzU3RyaW5nKCkgewotCi0gICAgICAgIGlmIChudWxsICE9IGxvY2F0b3IpIHsKLSAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBzYnVmZmVyICA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLSAgICAgICAgICAgIFN0cmluZyAgICAgICBzeXN0ZW1JRCA9IGxvY2F0b3IuZ2V0U3lzdGVtSWQoKTsKLSAgICAgICAgICAgIGludCAgICAgICAgICBsaW5lICAgICA9IGxvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICAgICAgICAgICAgaW50ICAgICAgICAgIGNvbHVtbiAgID0gbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKTsKLQotICAgICAgICAgICAgaWYgKG51bGwgIT0gc3lzdGVtSUQpIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBTeXN0ZW1JRDogIik7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoc3lzdGVtSUQpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoMCAhPSBsaW5lKSB7Ci0gICAgICAgICAgICAgICAgc2J1ZmZlci5hcHBlbmQoIjsgTGluZSM6ICIpOwotICAgICAgICAgICAgICAgIHNidWZmZXIuYXBwZW5kKGxpbmUpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAoMCAhPSBjb2x1bW4pIHsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZCgiOyBDb2x1bW4jOiAiKTsKLSAgICAgICAgICAgICAgICBzYnVmZmVyLmFwcGVuZChjb2x1bW4pOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gc2J1ZmZlci50b1N0cmluZygpOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKLSAgICAgKiBvcmlnaW5hdGVkLiAgVGhpcyB3aWxsIHRyYWNlIGFsbCBuZXN0ZWQgZXhjZXB0aW9uCi0gICAgICogb2JqZWN0cywgYXMgd2VsbCBhcyB0aGlzIG9iamVjdC4KLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoKSB7Ci0gICAgICAgIHByaW50U3RhY2tUcmFjZShuZXcgamF2YS5pby5QcmludFdyaXRlcihTeXN0ZW0uZXJyLCB0cnVlKSk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUHJpbnQgdGhlIHRoZSB0cmFjZSBvZiBtZXRob2RzIGZyb20gd2hlcmUgdGhlIGVycm9yCi0gICAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgotICAgICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCi0gICAgICogQHBhcmFtIHMgVGhlIHN0cmVhbSB3aGVyZSB0aGUgZHVtcCB3aWxsIGJlIHNlbnQgdG8uCi0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKGphdmEuaW8uUHJpbnRTdHJlYW0gcykgewotICAgICAgICBwcmludFN0YWNrVHJhY2UobmV3IGphdmEuaW8uUHJpbnRXcml0ZXIocykpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFByaW50IHRoZSB0aGUgdHJhY2Ugb2YgbWV0aG9kcyBmcm9tIHdoZXJlIHRoZSBlcnJvcgotICAgICAqIG9yaWdpbmF0ZWQuICBUaGlzIHdpbGwgdHJhY2UgYWxsIG5lc3RlZCBleGNlcHRpb24KLSAgICAgKiBvYmplY3RzLCBhcyB3ZWxsIGFzIHRoaXMgb2JqZWN0LgotICAgICAqIEBwYXJhbSBzIFRoZSB3cml0ZXIgd2hlcmUgdGhlIGR1bXAgd2lsbCBiZSBzZW50IHRvLgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50V3JpdGVyIHMpIHsKLQotICAgICAgICBpZiAocyA9PSBudWxsKSB7Ci0gICAgICAgICAgICBzID0gbmV3IGphdmEuaW8uUHJpbnRXcml0ZXIoU3lzdGVtLmVyciwgdHJ1ZSk7Ci0gICAgICAgIH0KLQotICAgICAgICB0cnkgewotICAgICAgICAgICAgU3RyaW5nIGxvY0luZm8gPSBnZXRMb2NhdGlvbkFzU3RyaW5nKCk7Ci0KLSAgICAgICAgICAgIGlmIChudWxsICE9IGxvY0luZm8pIHsKLSAgICAgICAgICAgICAgICBzLnByaW50bG4obG9jSW5mbyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHN1cGVyLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHt9Ci0KLSAgICAgICAgVGhyb3dhYmxlIGV4Y2VwdGlvbiA9IGdldEV4Y2VwdGlvbigpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyAoaSA8IDEwKSAmJiAobnVsbCAhPSBleGNlcHRpb24pOyBpKyspIHsKLSAgICAgICAgICAgIHMucHJpbnRsbigiLS0tLS0tLS0tIik7Ci0KLSAgICAgICAgICAgIHRyeSB7Ci0gICAgICAgICAgICAgICAgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIERUTUV4Y2VwdGlvbikgewotICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jSW5mbyA9Ci0gICAgICAgICAgICAgICAgICAgICAgICAoKERUTUV4Y2VwdGlvbikgZXhjZXB0aW9uKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRMb2NhdGlvbkFzU3RyaW5nKCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgIT0gbG9jSW5mbykgewotICAgICAgICAgICAgICAgICAgICAgICAgcy5wcmludGxuKGxvY0luZm8pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgZXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0gICAgICAgICAgICAgICAgcy5wcmludGxuKCJDb3VsZCBub3QgcHJpbnQgc3RhY2sgdHJhY2UuLi4iKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgICBNZXRob2QgbWV0aCA9Ci0gICAgICAgICAgICAgICAgICAgICgoT2JqZWN0KSBleGNlcHRpb24pLmdldENsYXNzKCkuZ2V0TWV0aG9kKCJnZXRFeGNlcHRpb24iLAotICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAobnVsbCAhPSBtZXRoKSB7Ci0gICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSBwcmV2ID0gZXhjZXB0aW9uOwotCi0gICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IChUaHJvd2FibGUpIG1ldGguaW52b2tlKGV4Y2VwdGlvbiwgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaWYgKHByZXYgPT0gZXhjZXB0aW9uKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpdGUpIHsKLSAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpYWUpIHsKLSAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIG5zbWUpIHsKLSAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgfQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNRmlsdGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL0RUTUZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZWZkNGI4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNRmlsdGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtOwotCi0vKioKLSAqIFNpbXBsZSBmaWx0ZXIgZm9yIGRvaW5nIG5vZGUgdGVzdHMuICBOb3RlIHRoZSBzZW1hbnRpY3Mgb2YgdGhpcyBhcmUKLSAqIHNvbWV3aGF0IGRpZmZlcmVudCB0aGF0IHRoZSBET00ncyBOb2RlRmlsdGVyLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTUZpbHRlcgotewotCi0gIC8vIENvbnN0YW50cyBmb3Igd2hhdFRvU2hvdy4gIFRoZXNlIGFyZSB1c2VkIHRvIHNldCB0aGUgbm9kZSB0eXBlIHRoYXQgd2lsbCAKLSAgLy8gYmUgdHJhdmVyc2VkLiBUaGVzZSB2YWx1ZXMgbWF5IGJlIE9SZWQgdG9nZXRoZXIgYmVmb3JlIGJlaW5nIHBhc3NlZCB0bwotICAvLyB0aGUgRFRNSXRlcmF0b3IuCi0KLSAgLyoqCi0gICAqIFNob3cgYWxsIDxjb2RlPk5vZGVzPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfQUxMID0gMHhGRkZGRkZGRjsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5FbGVtZW50PC9jb2RlPiBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRUxFTUVOVCA9IDB4MDAwMDAwMDE7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+QXR0cjwvY29kZT4gbm9kZXMuIFRoaXMgaXMgbWVhbmluZ2Z1bCBvbmx5IHdoZW4gY3JlYXRpbmcgYW4KLSAgICogaXRlcmF0b3Igb3IgdHJlZS13YWxrZXIgd2l0aCBhbiBhdHRyaWJ1dGUgbm9kZSBhcyBpdHMKLSAgICogPGNvZGU+cm9vdDwvY29kZT47IGluIHRoaXMgY2FzZSwgaXQgbWVhbnMgdGhhdCB0aGUgYXR0cmlidXRlIG5vZGUKLSAgICogd2lsbCBhcHBlYXIgaW4gdGhlIGZpcnN0IHBvc2l0aW9uIG9mIHRoZSBpdGVyYXRpb24gb3IgdHJhdmVyc2FsLgotICAgKiBTaW5jZSBhdHRyaWJ1dGVzIGFyZSBuZXZlciBjaGlsZHJlbiBvZiBvdGhlciBub2RlcywgdGhleSBkbyBub3QKLSAgICogYXBwZWFyIHdoZW4gdHJhdmVyc2luZyBvdmVyIHRoZSBtYWluIGRvY3VtZW50IHRyZWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0FUVFJJQlVURSA9IDB4MDAwMDAwMDI7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+VGV4dDwvY29kZT4gbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX1RFWFQgPSAweDAwMDAwMDA0OwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkNEQVRBU2VjdGlvbjwvY29kZT4gbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0NEQVRBX1NFQ1RJT04gPSAweDAwMDAwMDA4OwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkVudGl0eVJlZmVyZW5jZTwvY29kZT4gbm9kZXMuIE5vdGUgdGhhdCBpZiBFbnRpdHkgUmVmZXJlbmNlcwotICAgKiBoYXZlIGJlZW4gZnVsbHkgZXhwYW5kZWQgd2hpbGUgdGhlIHRyZWUgd2FzIGJlaW5nIGNvbnN0cnVjdGVkLCB0aGVzZQotICAgKiBub2RlcyB3aWxsIG5vdCBhcHBlYXIgYW5kIHRoaXMgbWFzayBoYXMgbm8gZWZmZWN0LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19FTlRJVFlfUkVGRVJFTkNFID0gMHgwMDAwMDAxMDsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5FbnRpdHk8L2NvZGU+IG5vZGVzLiBUaGlzIGlzIG1lYW5pbmdmdWwgb25seSB3aGVuIGNyZWF0aW5nCi0gICAqIGFuIGl0ZXJhdG9yIG9yIHRyZWUtd2Fsa2VyIHdpdGggYW48Y29kZT4gRW50aXR5PC9jb2RlPiBub2RlIGFzIGl0cwotICAgKiA8Y29kZT5yb290PC9jb2RlPjsgaW4gdGhpcyBjYXNlLCBpdCBtZWFucyB0aGF0IHRoZSA8Y29kZT5FbnRpdHk8L2NvZGU+Ci0gICAqICBub2RlIHdpbGwgYXBwZWFyIGluIHRoZSBmaXJzdCBwb3NpdGlvbiBvZiB0aGUgdHJhdmVyc2FsLiBTaW5jZQotICAgKiBlbnRpdGllcyBhcmUgbm90IHBhcnQgb2YgdGhlIGRvY3VtZW50IHRyZWUsIHRoZXkgZG8gbm90IGFwcGVhciB3aGVuCi0gICAqIHRyYXZlcnNpbmcgb3ZlciB0aGUgbWFpbiBkb2N1bWVudCB0cmVlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19FTlRJVFkgPSAweDAwMDAwMDIwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPlByb2Nlc3NpbmdJbnN0cnVjdGlvbjwvY29kZT4gbm9kZXMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSAweDAwMDAwMDQwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPkNvbW1lbnQ8L2NvZGU+IG5vZGVzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19DT01NRU5UID0gMHgwMDAwMDA4MDsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5Eb2N1bWVudDwvY29kZT4gbm9kZXMuIChPZiBjb3Vyc2UsIGFzIHdpdGggQXR0cmlidXRlcwotICAgKiBhbmQgc3VjaCwgdGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiB0aGUgaXRlcmF0aW9uIHJvb3QgaXMgdGhlCi0gICAqIERvY3VtZW50IGl0c2VsZiwgc2luY2UgRG9jdW1lbnQgaGFzIG5vIHBhcmVudC4pCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSE9XX0RPQ1VNRU5UID0gMHgwMDAwMDEwMDsKLQotICAvKioKLSAgICogU2hvdyA8Y29kZT5Eb2N1bWVudFR5cGU8L2NvZGU+IG5vZGVzLiAKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRE9DVU1FTlRfVFlQRSA9IDB4MDAwMDAyMDA7Ci0KLSAgLyoqCi0gICAqIFNob3cgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gbm9kZXMuIChPZiBjb3Vyc2UsIGFzIHdpdGgKLSAgICogQXR0cmlidXRlcyBhbmQgc3VjaCwgdGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiB0aGUgaXRlcmF0aW9uCi0gICAqIHJvb3QgaXMgdGhlIERvY3VtZW50IGl0c2VsZiwgc2luY2UgRG9jdW1lbnRGcmFnbWVudCBoYXMgbm8gcGFyZW50LikKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfRE9DVU1FTlRfRlJBR01FTlQgPSAweDAwMDAwNDAwOwotCi0gIC8qKgotICAgKiBTaG93IDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2Rlcy4gVGhpcyBpcyBtZWFuaW5nZnVsIG9ubHkgd2hlbiBjcmVhdGluZwotICAgKiBhbiBpdGVyYXRvciBvciB0cmVlLXdhbGtlciB3aXRoIGEgPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGUgYXMgaXRzCi0gICAqIDxjb2RlPnJvb3Q8L2NvZGU+OyBpbiB0aGlzIGNhc2UsIGl0IG1lYW5zIHRoYXQgdGhlCi0gICAqIDxjb2RlPk5vdGF0aW9uPC9jb2RlPiBub2RlIHdpbGwgYXBwZWFyIGluIHRoZSBmaXJzdCBwb3NpdGlvbiBvZiB0aGUKLSAgICogdHJhdmVyc2FsLiBTaW5jZSBub3RhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIHRoZSBkb2N1bWVudCB0cmVlLCB0aGV5IGRvCi0gICAqIG5vdCBhcHBlYXIgd2hlbiB0cmF2ZXJzaW5nIG92ZXIgdGhlIG1haW4gZG9jdW1lbnQgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfTk9UQVRJT04gPSAweDAwMDAwODAwOwotICAKLSAgLyoqCi0KLSAgICogVGhpcyBiaXQgaW5zdHJ1Y3RzIHRoZSBpdGVyYXRvciB0byBzaG93IG5hbWVzcGFjZSBub2Rlcywgd2hpY2gKLSAgICogYXJlIG1vZGVsZWQgYnkgRFRNIGJ1dCBub3QgYnkgdGhlIERPTS4gIE1ha2Ugc3VyZSB0aGlzIGRvZXMgbm90Ci0gICAqIGNvbmZsaWN0IHdpdGgge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICogPHA+Ci0gICAqICVSRVZJRVclIE1pZ2h0IGJlIHNhZmVyIHRvIHN0YXJ0IGZyb20gaGlnaGVyIGJpdHMgYW5kIHdvcmsgZG93biwKLSAgICogdG8gbGVhdmUgcm9vbSBmb3IgdGhlIERPTSB0byBleHBhbmQgaXRzIHNldCBvZiBjb25zdGFudHMuLi4gT3IsCi0gICAqIHBvc3NpYmx5LCB0byBjcmVhdGUgYSBEVE0tc3BlY2lmaWMgZmllbGQgZm9yIHRoZXNlIGFkZGl0aW9uYWwgYml0cy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfTkFNRVNQQUNFID0gMHgwMDAwMTAwMDsKLQotICAvKioKLSAgICogU3BlY2lhbCBiaXQgZm9yIGZpbHRlcnMgaW1wbGVtZW50aW5nIG1hdGNoIHBhdHRlcm5zIHN0YXJ0aW5nIHdpdGgKLSAgICogYSBmdW5jdGlvbi4gIE1ha2Ugc3VyZSB0aGlzIGRvZXMgbm90IGNvbmZsaWN0IHdpdGgKLSAgICoge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICogPHA+Ci0gICAqICVSRVZJRVclIE1pZ2h0IGJlIHNhZmVyIHRvIHN0YXJ0IGZyb20gaGlnaGVyIGJpdHMgYW5kIHdvcmsgZG93biwKLSAgICogdG8gbGVhdmUgcm9vbSBmb3IgdGhlIERPTSB0byBleHBhbmQgaXRzIHNldCBvZiBjb25zdGFudHMuLi4gT3IsCi0gICAqIHBvc3NpYmx5LCB0byBjcmVhdGUgYSBEVE0tc3BlY2lmaWMgZmllbGQgZm9yIHRoZXNlIGFkZGl0aW9uYWwgYml0cy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1dfQllGVU5DVElPTiA9IDB4MDAwMTAwMDA7Ci0KLSAgLyoqCi0gICAqIFRlc3Qgd2hldGhlciBhIHNwZWNpZmllZCBub2RlIGlzIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgdmlldyBvZiBhCi0gICAqIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4gTm9ybWFsbHksIHRoaXMgZnVuY3Rpb24KLSAgICogd2lsbCBiZSBjYWxsZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPjsgCi0gICAqIGl0IGlzIG5vdCBub3JtYWxseSBjYWxsZWQgZGlyZWN0bHkgZnJvbQotICAgKiB1c2VyIGNvZGUuCi0gICAqIAotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBvbmUgb2YgU0hPV19YWFggdmFsdWVzLgotICAgKiBAcmV0dXJuIG9uZSBvZiBGSUxURVJfQUNDRVBULCBGSUxURVJfUkVKRUNULCBvciBGSUxURVJfU0tJUC4KLSAgICovCi0gIHB1YmxpYyBzaG9ydCBhY2NlcHROb2RlKGludCBub2RlSGFuZGxlLCBpbnQgd2hhdFRvU2hvdyk7Ci0gIAotICAvKioKLSAgICogVGVzdCB3aGV0aGVyIGEgc3BlY2lmaWVkIG5vZGUgaXMgdmlzaWJsZSBpbiB0aGUgbG9naWNhbCB2aWV3IG9mIGEKLSAgICogPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LiBOb3JtYWxseSwgdGhpcyBmdW5jdGlvbgotICAgKiB3aWxsIGJlIGNhbGxlZCBieSB0aGUgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+OyAKLSAgICogaXQgaXMgbm90IG5vcm1hbGx5IGNhbGxlZCBkaXJlY3RseSBmcm9tCi0gICAqIHVzZXIgY29kZS4KLSAgICogPHA+Ci0gICAqIFRPRE86IFNob3VsZCB0aGlzIGJlIHNldE5hbWVNYXRjaChleHBhbmRlZE5hbWUpIGZvbGxvd2VkIGJ5IGFjY2VwdCgpPwotICAgKiBPciB3aWxsIHdlIHJlYWxseSBiZSB0ZXN0aW5nIGEgZGlmZmVyZW50IG5hbWUgYXQgZXZlcnkgaW52b2NhdGlvbj8KLSAgICogCi0gICAqIDxwPiVSRVZJRVclIFVuZGVyIHdoYXQgY2lyY3Vtc3RhbmNlcyB3aWxsIHRoaXMgYmUgdXNlZD8gVGhlIGNhc2VzCi0gICAqIEkndmUgY29uc2lkZXJlZCBhcmUganVzdCBhcyBlYXN5IGFuZCBqdXN0IGFib3V0IGFzIGVmZmljaWVudCBpZgotICAgKiB0aGUgbmFtZSB0ZXN0IGlzIHBlcmZvcm1lZCBpbiB0aGUgRFRNSXRlcmF0b3IuLi4gLS0gSm9lPC9wPgotICAgKiAKLSAgICogPHA+JVJFVklFVyUgU2hvdWxkIHRoYXQgMHhGRkZGIGhhdmUgYSBtbmVtb25pYyBhc3NpZ25lZCB0byBpdD8KLSAgICogQWxzbzogVGhpcyByZXByZXNlbnRhdGlvbiBpcyBhc3N1bWluZyB0aGUgZXhwYW5kZWQgbmFtZSBpcyBpbmRlZWQKLSAgICogc3BsaXQgaW50byBoaWdoL2xvdyAxNi1iaXQgaGFsZndvcmRzLiBJZiB3ZSBldmVyIGNoYW5nZSB0aGUKLSAgICogYmFsYW5jZSBiZXR3ZWVuIG5hbWVzcGFjZSBhbmQgbG9jYWxuYW1lIGJpdHMgKGVnIGJlY2F1c2Ugd2UKLSAgICogZGVjaWRlIHRoZXJlIGFyZSBtYW55IG1vcmUgbG9jYWxuYW1lcyB0aGFuIG5hbWVzcGFjZXMsIHdoaWNoIGlzCi0gICAqIGZhaXJseSBsaWtlbHkpLCB0aGlzIGlzIGdvaW5nIHRvIGJyZWFrLiBJdCBtaWdodCBiZSBzYWZlciB0bwotICAgKiBlbmNhcHN1bGF0ZSB0aGUgZGV0YWlscyB3aXRoIGEgbWFrZUV4cGFuZGVkTmFtZSBtZXRob2QgYW5kIG1ha2UKLSAgICogdGhhdCByZXNwb25zaWJsZSBmb3Igc2V0dGluZyB1cCB0aGUgd2lsZGNhcmQgdmVyc2lvbiBhcyB3ZWxsLjwvcD4KLSAgICogCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IG9uZSBvZiBTSE9XX1hYWCB2YWx1ZXMuCi0gICAqIEBwYXJhbSBleHBhbmRlZE5hbWUgYSB2YWx1ZSBkZWZpbmluZyB0aGUgZXhhbmRlZCBuYW1lIGFzIGRlZmluZWQgaW4gCi0gICAqICAgICAgICAgICAgICAgICAgICAgdGhlIERUTSBpbnRlcmZhY2UuICBXaWxkIGNhcmRzIHdpbGwgYmUgZGVmaW5lZCAKLSAgICogICAgICAgICAgICAgICAgICAgICBieSAweEZGRkYgaW4gdGhlIG5hbWVzcGFjZSBhbmQvb3IgbG9jYWxuYW1lCi0gICAqCQkJIHBvcnRpb24gb2YgdGhlIGV4cGFuZGVkTmFtZS4KLSAgICogQHJldHVybiBvbmUgb2YgRklMVEVSX0FDQ0VQVCwgRklMVEVSX1JFSkVDVCwgb3IgRklMVEVSX1NLSVAuICAqLwotICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShpbnQgbm9kZUhhbmRsZSwgaW50IHdoYXRUb1Nob3csIGludCBleHBhbmRlZE5hbWUpOwotIAotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1JdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1JdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ODYzM2MzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG07Ci0KLS8qKgotCi0gKiA8Y29kZT5EVE1JdGVyYXRvcnM8L2NvZGU+IGFyZSB1c2VkIHRvIHN0ZXAgdGhyb3VnaCBhIChwb3NzaWJseQotICogZmlsdGVyZWQpIHNldCBvZiBub2Rlcy4gIFRoZWlyIEFQSSBpcyBtb2RlbGVkIGxhcmdlbHkgYWZ0ZXIgdGhlIERPTQotICogTm9kZUl0ZXJhdG9yLgotICogCi0gKiA8cD5BIERUTUl0ZXJhdG9yIGlzIGEgc29tZXdoYXQgdW51c3VhbCB0eXBlIG9mIGl0ZXJhdG9yLCBpbiB0aGF0IGl0IAotICogY2FuIHNlcnZlIGJvdGggc2luZ2xlIG5vZGUgaXRlcmF0aW9uIGFuZCByYW5kb20gYWNjZXNzLjwvcD4KLSAqIAotICogPHA+VGhlIERUTUl0ZXJhdG9yJ3MgdHJhdmVyc2FsIHNlbWFudGljcywgaS5lLiBob3cgaXQgd2Fsa3MgdGhlIHRyZWUsCi0gKiBhcmUgc3BlY2lmaWVkIHdoZW4gaXQgaXMgY3JlYXRlZCwgcG9zc2libHkgYW5kIHByb2JhYmx5IGJ5IGFuIFhQYXRoCi0gKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGg+TG9jYXRpb25QYXRoPC9hPiBvciAKLSAqIGEgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LjwvcD4KLSAqIAotICogPHA+QSBEVE1JdGVyYXRvciBpcyBtZWFudCB0byBiZSBjcmVhdGVkIG9uY2UgYXMgYSBtYXN0ZXIgc3RhdGljIG9iamVjdCwgYW5kIAotICogdGhlbiBjbG9uZWQgbWFueSB0aW1lcyBmb3IgcnVudGltZSB1c2UuICBPciB0aGUgbWFzdGVyIG9iamVjdCBpdHNlbGYgbWF5IAotICogYmUgdXNlZCBmb3Igc2ltcGxlciB1c2UgY2FzZXMuPC9wPgotICoKLSAqIDxwPkF0IHRoaXMgdGltZSwgd2UgZG8gbm90IGV4cGVjdCBEVE1JdGVyYXRvciB0byBlbXVsYXRlCi0gKiBOb2RlSXRlcmF0b3IncyAibWFpbnRhaW4gcmVsYXRpdmUgcG9zaXRpb24iIHNlbWFudGljcyB1bmRlcgotICogZG9jdW1lbnQgbXV0YXRpb24uICBJdCdzIGxpa2VseSB0byByZXNwb25kIG1vcmUgbGlrZSB0aGUKLSAqIFRyZWVXYWxrZXIncyAiY3VycmVudCBub2RlIiBzZW1hbnRpY3MuIEhvd2V2ZXIsIHNpbmNlIHRoZSBiYXNlIERUTQotICogaXMgaW1tdXRhYmxlLCB0aGlzIGlzc3VlIGN1cnJlbnRseSBtYWtlcyBubyBwcmFjdGljYWwKLSAqIGRpZmZlcmVuY2UuPC9wPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPiAqLwotcHVibGljIGludGVyZmFjZSBEVE1JdGVyYXRvcgotewotCi0gIC8vIENvbnN0YW50cyByZXR1cm5lZCBieSBhY2NlcHROb2RlLCBib3Jyb3dlZCBmcm9tIHRoZSBET00gVHJhdmVyc2FsIGNoYXB0ZXIKLSAgLy8gJVJFVklFVyUgU2hvdWxkIHdlIGV4cGxpY2l0bHkgaW5pdGlhbGl6ZSB0aGVtIGZyb20sIGVnLAotICAvLyBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlci5GSUxURVJfQUNDRVBUPwotCi0gIC8qKgotICAgKiBBY2NlcHQgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IEZJTFRFUl9BQ0NFUFQgPSAxOwotCi0gIC8qKgotICAgKiBSZWplY3QgdGhlIG5vZGUuIFNhbWUgYmVoYXZpb3IgYXMgRklMVEVSX1NLSVAuIChJbiB0aGUgRE9NIHRoZXNlCi0gICAqIGRpZmZlciB3aGVuIGFwcGxpZWQgdG8gYSBUcmVlV2Fsa2VyIGJ1dCBoYXZlIHRoZSBzYW1lIHJlc3VsdCB3aGVuCi0gICAqIGFwcGxpZWQgdG8gYSBOb2RlSXRlcmF0b3IpLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBGSUxURVJfUkVKRUNUID0gMjsKLQotICAvKioKLSAgICogU2tpcCB0aGlzIHNpbmdsZSBub2RlLiAKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgRklMVEVSX1NLSVAgPSAzOwotICAgIAotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIGEgRFRNIHRoYXQgIm93bnMiIGEgbm9kZSBoYW5kbGUuICBTaW5jZSBhIG5vZGUgCi0gICAqIGl0ZXJhdG9yIG1heSBiZSBwYXNzZWQgd2l0aG91dCBhIERUTU1hbmFnZXIsIHRoaXMgYWxsb3dzIHRoZSAKLSAgICogY2FsbGVyIHRvIGVhc2lseSBnZXQgdGhlIERUTSB1c2luZyBqdXN0IHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGVIYW5kbGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIERUTSBnZXREVE0oaW50IG5vZGVIYW5kbGUpOwotICAKLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiB0aGUgRFRNTWFuYWdlci4gIFNpbmNlIGEgbm9kZSAKLSAgICogaXRlcmF0b3IgbWF5IGJlIHBhc3NlZCB3aXRob3V0IGEgRFRNTWFuYWdlciwgdGhpcyBhbGxvd3MgdGhlIAotICAgKiBjYWxsZXIgdG8gZWFzaWx5IGdldCB0aGUgRFRNTWFuYWdlciB1c2luZyBqdXN0IHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTU1hbmFnZXIgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIERUTU1hbmFnZXIgZ2V0RFRNTWFuYWdlcigpOwotCi0gIC8qKgotICAgKiBUaGUgcm9vdCBub2RlIG9mIHRoZSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4sIGFzIHNwZWNpZmllZCB3aGVuIGl0Ci0gICAqIHdhcyBjcmVhdGVkLiAgTm90ZSB0aGUgcm9vdCBub2RlIGlzIG5vdCB0aGUgcm9vdCBub2RlIG9mIHRoZSAKLSAgICogZG9jdW1lbnQgdHJlZSwgYnV0IHRoZSBjb250ZXh0IG5vZGUgZnJvbSB3aGVyZSB0aGUgaXRlcmF0aW9uIAotICAgKiBiZWdpbnMgYW5kIGVuZHMuCi0gICAqCi0gICAqIEByZXR1cm4gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBjb250ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFJvb3QoKTsKLQotICAvKioKLSAgICogUmVzZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LCBvdmVycmlkaW5nCi0gICAqIHRoZSB2YWx1ZSBzcGVjaWZpZWQgd2hlbiBpdCB3YXMgY3JlYXRlZC4gIE5vdGUgdGhlIHJvb3Qgbm9kZSBpcwotICAgKiBub3QgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgZG9jdW1lbnQgdHJlZSwgYnV0IHRoZSBjb250ZXh0IG5vZGUgZnJvbQotICAgKiB3aGVyZSB0aGUgaXRlcmF0aW9uIGJlZ2lucy4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgY29udGV4dCBub2RlLgotICAgKiBAcGFyYW0gZW52aXJvbm1lbnQgVGhlIGVudmlyb25tZW50IG9iamVjdC4gIAotICAgKiBUaGUgZW52aXJvbm1lbnQgaW4gd2hpY2ggdGhpcyBpdGVyYXRvciBvcGVyYXRlcywgd2hpY2ggc2hvdWxkIHByb3ZpZGU6Ci0gICAqIDx1bD4KLSAgICogPGxpPmEgbm9kZSAodGhlIGNvbnRleHQgbm9kZS4uLiBzYW1lIHZhbHVlIGFzICJyb290IiBkZWZpbmVkIGJlbG93KSA8L2xpPgotICAgKiA8bGk+YSBwYWlyIG9mIG5vbi16ZXJvIHBvc2l0aXZlIGludGVnZXJzICh0aGUgY29udGV4dCBwb3NpdGlvbiBhbmQgdGhlIGNvbnRleHQgc2l6ZSkgPC9saT4KLSAgICogPGxpPmEgc2V0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIDwvbGk+Ci0gICAqIDxsaT5hIGZ1bmN0aW9uIGxpYnJhcnkgPC9saT4KLSAgICogPGxpPnRoZSBzZXQgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBpbiBzY29wZSBmb3IgdGhlIGV4cHJlc3Npb24uPC9saT4KLSAgICogPHVsPgotICAgKiAKLSAgICogPHA+QXQgdGhpcyB0aW1lIHRoZSBleGFjdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGVudmlyb25tZW50IGlzIGFwcGxpY2F0aW9uIAotICAgKiBkZXBlbmRlbnQuICBQcm9iYWJseSBhIHByb3BlciBpbnRlcmZhY2Ugd2lsbCBiZSBjcmVhdGVkIGZhaXJseSBzb29uLjwvcD4KLSAgICogCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCBub2RlSGFuZGxlLCBPYmplY3QgZW52aXJvbm1lbnQpOwotICAKLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBpdGVyYXRvciB0byB0aGUgc3RhcnQuIEFmdGVyIHJlc2V0dGluZywgdGhlIG5leHQgbm9kZSByZXR1cm5lZAotICAgKiB3aWxsIGJlIHRoZSByb290IG5vZGUgLS0gb3IsIGlmIHRoYXQncyBmaWx0ZXJlZCBvdXQsIHRoZSBmaXJzdCBub2RlCi0gICAqIHdpdGhpbiB0aGUgcm9vdCdzIHN1YnRyZWUgd2hpY2ggaXMgX25vdF8gc2tpcHBlZCBieSB0aGUgZmlsdGVycy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLSAgLyoqCi0gICAqIFRoaXMgYXR0cmlidXRlIGRldGVybWluZXMgd2hpY2ggbm9kZSB0eXBlcyBhcmUgcHJlc2VudGVkIHZpYSB0aGUKLSAgICogaXRlcmF0b3IuIFRoZSBhdmFpbGFibGUgc2V0IG9mIGNvbnN0YW50cyBpcyBkZWZpbmVkIGFib3ZlLiAgCi0gICAqIE5vZGVzIG5vdCBhY2NlcHRlZCBieQotICAgKiA8Y29kZT53aGF0VG9TaG93PC9jb2RlPiB3aWxsIGJlIHNraXBwZWQsIGJ1dCB0aGVpciBjaGlsZHJlbiBtYXkgc3RpbGwKLSAgICogYmUgY29uc2lkZXJlZC4KLSAgICoKLSAgICogQHJldHVybiBvbmUgb2YgdGhlIFNIT1dfWFhYIGNvbnN0YW50cywgb3Igc2V2ZXJhbCBPUmVkIHRvZ2V0aGVyLgotICAgKi8KLSAgcHVibGljIGludCBnZXRXaGF0VG9TaG93KCk7Ci0KLSAgLyoqCi0gICAqIDxwPlRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGlsZHJlbiBvZiBlbnRpdHkKLSAgICogcmVmZXJlbmNlIG5vZGVzIGFyZSB2aXNpYmxlIHRvIHRoZSBpdGVyYXRvci4gSWYgZmFsc2UsIHRoZXkgIGFuZAotICAgKiB0aGVpciBkZXNjZW5kYW50cyB3aWxsIGJlIHJlamVjdGVkLiBOb3RlIHRoYXQgdGhpcyByZWplY3Rpb24gdGFrZXMKLSAgICogcHJlY2VkZW5jZSBvdmVyIDxjb2RlPndoYXRUb1Nob3c8L2NvZGU+IGFuZCB0aGUgZmlsdGVyLiA8L3A+Ci0gICAqIAotICAgKiA8cD4gVG8gcHJvZHVjZSBhIHZpZXcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaGFzIGVudGl0eSByZWZlcmVuY2VzCi0gICAqIGV4cGFuZGVkIGFuZCBkb2VzIG5vdCBleHBvc2UgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBpdHNlbGYsIHVzZQotICAgKiB0aGUgPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlCi0gICAqIGFuZCBzZXQgPGNvZGU+ZXhwYW5kRW50aXR5UmVmZXJlbmNlczwvY29kZT4gdG8gdHJ1ZSB3aGVuIGNyZWF0aW5nIHRoZQotICAgKiBpdGVyYXRvci4gVG8gcHJvZHVjZSBhIHZpZXcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaGFzIGVudGl0eSByZWZlcmVuY2UKLSAgICogbm9kZXMgYnV0IG5vIGVudGl0eSBleHBhbnNpb24sIHVzZSB0aGUgPGNvZGU+d2hhdFRvU2hvdzwvY29kZT4gZmxhZ3MKLSAgICogdG8gc2hvdyB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGFuZCBzZXQKLSAgICogPGNvZGU+ZXhwYW5kRW50aXR5UmVmZXJlbmNlczwvY29kZT4gdG8gZmFsc2UuPC9wPgotICAgKgotICAgKiA8cD5OT1RFOiBJbiBYYWxhbidzIHVzZSBvZiBEVE0gd2Ugd2lsbCBnZW5lcmFsbHkgaGF2ZSBmdWxseSBleHBhbmRlZAotICAgKiBlbnRpdHkgcmVmZXJlbmNlcyB3aGVuIHRoZSBkb2N1bWVudCB0cmVlIHdhcyBidWlsdCwgYW5kIHRodXMgdGhpcwotICAgKiBmbGFnIHdpbGwgaGF2ZSBubyBlZmZlY3QuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgZW50aXR5IHJlZmVyZW5jZXMgd2lsbCBiZSBleHBhbmRlZC4gICovCi0gIHB1YmxpYyBib29sZWFuIGdldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gaGFzIHNldFJvb3QgY2FsbGVkLAotICAgKiB0aGUgZmlyc3QgY2FsbCB0byA8Y29kZT5uZXh0Tm9kZSgpPC9jb2RlPiByZXR1cm5zIHRoYXQgcm9vdCBvciAoaWYgaXQKLSAgICogaXMgcmVqZWN0ZWQgYnkgdGhlIGZpbHRlcnMpIHRoZSBmaXJzdCBub2RlIHdpdGhpbiBpdHMgc3VidHJlZSB3aGljaCBpcwotICAgKiBub3QgZmlsdGVyZWQgb3V0LgotICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICAtMSBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBub2RlIGluIHRoZSBzZXQgYW5kIG1vdmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+IGJhY2t3YXJkcyBpbiB0aGUgc2V0LgotICAgKiBAcmV0dXJuIFRoZSBwcmV2aW91cyBub2RlIGhhbmRsZSBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsCi0gICAqICAgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KLSAgICovCi0gIHB1YmxpYyBpbnQgcHJldmlvdXNOb2RlKCk7Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkCi0gICAqIG92ZXIsIHJlbGVhc2luZyBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yCi0gICAqIGluIHRoZSBJTlZBTElEIHN0YXRlLiBBZnRlciA8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsCi0gICAqIGNhbGxzIHRvIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvciA8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwKLSAgICogcmFpc2UgYSBydW50aW1lIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpOwotICAKLSAgLyoqCi0gICAqIFNwZWNpZnkgaWYgaXQncyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhlIGl0ZXJhdG9yIGZvciByZXVzZS4KLSAgICogCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvciAKLSAgICogZm9yIHBvb2xpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhbGxvd0RldGFjaFRvUmVsZWFzZShib29sZWFuIGFsbG93UmVsZWFzZSk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBub2RlIGluIHRoZSBpdGVyYXRvci4gTm90ZSB0aGF0IHRoaXMgZGlmZmVycyBmcm9tCi0gICAqIHRoZSBET00ncyBOb2RlSXRlcmF0b3IsIHdoZXJlIHRoZSBjdXJyZW50IHBvc2l0aW9uIGxpZXMgYmV0d2VlbiB0d28KLSAgICogbm9kZXMgKGFzIHBhcnQgb2YgdGhlIG1haW50YWluLXJlbGF0aXZlLXBvc2l0aW9uIHNlbWFudGljKS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBub2RlIGhhbmRsZSwgb3IgLTEuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEN1cnJlbnROb2RlKCk7Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoaXMgTm9kZVNldERUTSBpcyAiZnJlc2giLCBpbiBvdGhlciB3b3JkcywgaWYKLSAgICogdGhlIGZpcnN0IG5leHROb2RlKCkgdGhhdCBpcyBjYWxsZWQgd2lsbCByZXR1cm4gdGhlCi0gICAqIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpdGVyYXRpb24gb2YgdGhpcyBsaXN0IGhhcyBub3QgeWV0IGJlZ3VuLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNGcmVzaCgpOwotCi0gIC8vPT09PT09PT09IFJhbmRvbSBBY2Nlc3MgPT09PT09PT09PQotCi0gIC8qKgotICAgKiBJZiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGlzIGNhbGxlZCwgdGhlbiBub2RlcyB3aWxsCi0gICAqIGJlIGNhY2hlZCwgZW5hYmxpbmcgcmFuZG9tIGFjY2VzcywgYW5kIGdpdmluZyB0aGUgYWJpbGl0eSB0byBkbyAKLSAgICogc29ydHMgYW5kIHRoZSBsaWtlLiAgVGhleSBhcmUgbm90IGNhY2hlZCBieSBkZWZhdWx0LgotICAgKgotICAgKiAlUkVWSUVXJSBTaG91bGRuJ3QgdGhlIG90aGVyIHJhbmRvbS1hY2Nlc3MgbWV0aG9kcyB0aHJvdyBhbiBleGNlcHRpb24KLSAgICogaWYgdGhleSdyZSBjYWxsZWQgb24gYSBEVE1JdGVyYXRvciB3aXRoIHRoaXMgZmxhZyBzZXQgZmFsc2U/Ci0gICAqCi0gICAqIEBwYXJhbSBiIHRydWUgaWYgdGhlIG5vZGVzIHNob3VsZCBiZSBjYWNoZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaG91bGRDYWNoZU5vZGVzKGJvb2xlYW4gYik7Ci0gIAotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpdGVyYXRvciBjYW4gaGF2ZSBub2RlcyBhZGRlZCB0byBpdCBvciBzZXQgdmlhIAotICAgKiB0aGUgPGNvZGU+c2V0SXRlbShpbnQgbm9kZSwgaW50IGluZGV4KTwvY29kZT4gbWV0aG9kLgotICAgKiAKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlbGlzdCBjYW4gYmUgbXV0YXRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTXV0YWJsZSgpOwotCi0gIC8qKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gd2l0aGluIHRoZSBjYWNoZWQgbGlzdCwgd2hpY2ggaXMgb25lCi0gICAqIGxlc3MgdGhhbiB0aGUgbmV4dCBuZXh0Tm9kZSgpIGNhbGwgd2lsbCByZXRyaWV2ZS4gIGkuZS4gaWYgeW91Ci0gICAqIGNhbGwgZ2V0Q3VycmVudFBvcygpIGFuZCB0aGUgcmV0dXJuIGlzIDAsIHRoZSBuZXh0IGZldGNoIHdpbGwKLSAgICogdGFrZSBwbGFjZSBhdCBpbmRleCAxLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwb3NpdGlvbiBvZiB0aGUgaXRlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50UG9zKCk7Ci0KLSAgLyoqCi0gICAqIElmIGFuIGluZGV4IGlzIHJlcXVlc3RlZCwgTm9kZVNldERUTSB3aWxsIGNhbGwgdGhpcyBtZXRob2QKLSAgICogdG8gcnVuIHRoZSBpdGVyYXRvciB0byB0aGUgaW5kZXguICBCeSBkZWZhdWx0IHRoaXMgc2V0cwotICAgKiBtX25leHQgdG8gdGhlIGluZGV4LiAgSWYgdGhlIGluZGV4IGFyZ3VtZW50IGlzIC0xLCB0aGlzCi0gICAqIHNpZ25hbHMgdGhhdCB0aGUgaXRlcmF0b3Igc2hvdWxkIGJlIHJ1biB0byB0aGUgZW5kIGFuZAotICAgKiBjb21wbGV0ZWx5IGZpbGwgdGhlIGNhY2hlLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHJ1biB0bywgb3IgLTEgaWYgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4KLSAgICogICAgICAgICAgICAgIHRvIHRoZSBlbmQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW5UbyhpbnQgaW5kZXgpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG5vZGUgc2V0LgotICAgKiAKLSAgICogQHBhcmFtIGkgTXVzdCBiZSBhIHZhbGlkIGluZGV4LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudFBvcyhpbnQgaSk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIDxjb2RlPm5vZGUgaGFuZGxlPC9jb2RlPiBvZiBhbiBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLiBJZgotICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4KLSAgICogdGhlIGxpc3QsIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IG9mIHRoZSBpdGVtLgotICAgKiBAcmV0dXJuIFRoZSBub2RlIGhhbmRsZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCi0gICAqICAgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgKiAgIGluZGV4LgotICAgKi8KLSAgcHVibGljIGludCBpdGVtKGludCBpbmRleCk7Ci0gIAotICAvKioKLSAgICogU2V0cyB0aGUgbm9kZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgdmVjdG9yIHRvIGJlIHRoZQotICAgKiBzcGVjaWZpZWQgbm9kZS4gVGhlIHByZXZpb3VzIGNvbXBvbmVudCBhdCB0aGF0IHBvc2l0aW9uIGlzIGRpc2NhcmRlZC4KLSAgICoKLSAgICogPHA+VGhlIGluZGV4IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcwotICAgKiB0aGFuIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHZlY3Rvci4gIAotICAgKiBUaGUgaXRlcmF0b3IgbXVzdCBiZSBpbiBjYWNoZWQgbW9kZS48L3A+Ci0gICAqIAotICAgKiA8cD5NZWFudCB0byBiZSB1c2VkIGZvciBzb3J0ZWQgaXRlcmF0b3JzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBzZXQKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIHNldCB0aGUgbm9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXRlbShpbnQgbm9kZSwgaW50IGluZGV4KTsKLSAgCi0gIC8qKgotICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzCi0gICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4gTm90ZSB0aGF0IHRoaXMgcmVxdWlyZXMgcnVubmluZwotICAgKiB0aGUgaXRlcmF0b3IgdG8gY29tcGxldGlvbiwgYW5kIHByZXN1bWFibHkgZmlsbGluZyB0aGUgY2FjaGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCk7Ci0gICAgCi0gIC8vPT09PT09PT09PT0gQ2xvbmluZyBvcGVyYXRpb25zLiA9PT09PT09PT09PT0KLSAgCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgSXRlcmF0b3IgdGhhdCBpcyByZXNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgaXRlcmF0aW9uIHRoYXQgaGFzIGJlZW4gcmVzZXQuCi0gICAqCi0gICAqIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IGEgY2xvbmUgb2YgdGhpcyBpdGVyYXRvciwgYnV0IGRvbid0IHJlc2V0IHRoZSBpdGVyYXRpb24gaW4gdGhlIAotICAgKiBwcm9jZXNzLCBzbyB0aGF0IGl0IG1heSBiZSB1c2VkIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gQSBjbG9uZSBvZiB0aGlzIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgYWxsIHRoZSBub2RlcyBpbiB0aGUgaXRlcmF0aW9uIHdlbGwgYmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQgCi0gICAqIG9yZGVyLgotICAgKiAKLSAgICogQHJldHVybiB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50IAotICAgKiBvcmRlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jT3JkZXJlZCgpOwotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKiAKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUgCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNTWFuYWdlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1NYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZhMzlhYmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1NYW5hZ2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1ODAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtOwotCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotLyoqCi0gKiBBIERUTU1hbmFnZXIgaW5zdGFuY2UgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIERUTSBhbmQKLSAqIERUTUl0ZXJhdG9yIG9iamVjdHMsIGFuZCBtYW5hZ2UgdGhlIERUTSBvYmplY3RzIGluIHRoZSBzeXN0ZW0uCi0gKgotICogPHA+VGhlIHN5c3RlbSBwcm9wZXJ0eSB0aGF0IGRldGVybWluZXMgd2hpY2ggRmFjdG9yeSBpbXBsZW1lbnRhdGlvbgotICogdG8gY3JlYXRlIGlzIG5hbWVkICJvcmcuYXBhY2hlLnhtbC51dGlscy5EVE1GYWN0b3J5Ii4gVGhpcwotICogcHJvcGVydHkgbmFtZXMgYSBjb25jcmV0ZSBzdWJjbGFzcyBvZiB0aGUgRFRNRmFjdG9yeSBhYnN0cmFjdAotICogIGNsYXNzLiBJZiB0aGUgcHJvcGVydHkgaXMgbm90IGRlZmluZWQsIGEgcGxhdGZvcm0gZGVmYXVsdCBpcyBiZSB1c2VkLjwvcD4KLSAqCi0gKiA8cD5BbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIDxlbXBoPm11c3Q8L2VtcGg+IGJlIHNhZmUgdG8gdXNlIGFjcm9zcwotICogdGhyZWFkIGluc3RhbmNlcy4gIEl0IGlzIGV4cGVjdGVkIHRoYXQgYSBjbGllbnQgd2lsbCBjcmVhdGUgYSBzaW5nbGUgaW5zdGFuY2UKLSAqIG9mIGEgRFRNTWFuYWdlciB0byB1c2UgYWNyb3NzIG11bHRpcGxlIHRocmVhZHMuICBUaGlzIHdpbGwgYWxsb3cgc2hhcmluZwotICogb2YgRFRNcyBhY3Jvc3MgbXVsdGlwbGUgcHJvY2Vzc2VzLjwvcD4KLSAqCi0gKiA8cD5Ob3RlOiB0aGlzIGNsYXNzIGlzIGluY29tcGxldGUgcmlnaHQgbm93LiAgSXQgd2lsbCBiZSBwcmV0dHkgbXVjaAotICogbW9kZWxlZCBhZnRlciBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSBpbiB0ZXJtcyBvZiBpdHMKLSAqIGZhY3Rvcnkgc3VwcG9ydC48L3A+Ci0gKgotICogPHA+U3RhdGU6IEluIHByb2dyZXNzISE8L3A+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEVE1NYW5hZ2VyCi17Ci0KLSAgLyoqIFRoZSBkZWZhdWx0IHByb3BlcnR5IG5hbWUgdG8gbG9hZCB0aGUgbWFuYWdlci4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGRlZmF1bHRQcm9wTmFtZSA9Ci0gICAgIm9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyIjsKLQotICAvKioKLSAgICogRmFjdG9yeSBmb3IgY3JlYXRpbmcgWE1MU3RyaW5nIG9iamVjdHMuCi0gICAqICAlVEJEJSBNYWtlIHRoaXMgc2V0IGJ5IHRoZSBjYWxsZXIuCi0gICAqLwotICBwcm90ZWN0ZWQgWE1MU3RyaW5nRmFjdG9yeSBtX3hzZiA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IgaXMgcHJvdGVjdGVkIG9uIHB1cnBvc2UuCi0gICAqLwotICBwcm90ZWN0ZWQgRFRNTWFuYWdlcigpe30KLQotICAvKioKLSAgICogR2V0IHRoZSBYTUxTdHJpbmdGYWN0b3J5IHVzZWQgZm9yIHRoZSBEVE1zLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIGEgdmFsaWQgWE1MU3RyaW5nRmFjdG9yeSBvYmplY3QsIG9yIG51bGwgaWYgaXQgaGFzbid0IGJlZW4gc2V0IHlldC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmdGYWN0b3J5IGdldFhNTFN0cmluZ0ZhY3RvcnkoKQotICB7Ci0gICAgcmV0dXJuIG1feHNmOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgWE1MU3RyaW5nRmFjdG9yeSB1c2VkIGZvciB0aGUgRFRNcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhzZiBhIHZhbGlkIFhNTFN0cmluZ0ZhY3Rvcnkgb2JqZWN0LCBzaG91bGQgbm90IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRYTUxTdHJpbmdGYWN0b3J5KFhNTFN0cmluZ0ZhY3RvcnkgeHNmKQotICB7Ci0gICAgbV94c2YgPSB4c2Y7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIGEgbmV3IGluc3RhbmNlIG9mIGEgPGNvZGU+RFRNTWFuYWdlcjwvY29kZT4uCi0gICAqIFRoaXMgc3RhdGljIG1ldGhvZCBjcmVhdGVzIGEgbmV3IGZhY3RvcnkgaW5zdGFuY2UKLSAgICogVGhpcyBtZXRob2QgdXNlcyB0aGUgZm9sbG93aW5nIG9yZGVyZWQgbG9va3VwIHByb2NlZHVyZSB0byBkZXRlcm1pbmUKLSAgICogdGhlIDxjb2RlPkRUTU1hbmFnZXI8L2NvZGU+IGltcGxlbWVudGF0aW9uIGNsYXNzIHRvCi0gICAqIGxvYWQ6Ci0gICAqIDx1bD4KLSAgICogPGxpPgotICAgKiBVc2UgdGhlIDxjb2RlPm9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyPC9jb2RlPiBzeXN0ZW0KLSAgICogcHJvcGVydHkuCi0gICAqIDwvbGk+Ci0gICAqIDxsaT4KLSAgICogVXNlIHRoZSBKQVZBX0hPTUUodGhlIHBhcmVudCBkaXJlY3Rvcnkgd2hlcmUgamRrIGlzCi0gICAqIGluc3RhbGxlZCkvbGliL2pheHAucHJvcGVydGllcyBmb3IgYSBwcm9wZXJ0eSBmaWxlIHRoYXQgY29udGFpbnMgdGhlCi0gICAqIG5hbWUgb2YgdGhlIGltcGxlbWVudGF0aW9uIGNsYXNzIGtleWVkIG9uIHRoZSBzYW1lIHZhbHVlIGFzIHRoZQotICAgKiBzeXN0ZW0gcHJvcGVydHkgZGVmaW5lZCBhYm92ZS4KLSAgICogPC9saT4KLSAgICogPGxpPgotICAgKiBVc2UgdGhlIFNlcnZpY2VzIEFQSSAoYXMgZGV0YWlsZWQgaW4gdGhlIEpBUiBzcGVjaWZpY2F0aW9uKSwgaWYKLSAgICogYXZhaWxhYmxlLCB0byBkZXRlcm1pbmUgdGhlIGNsYXNzbmFtZS4gVGhlIFNlcnZpY2VzIEFQSSB3aWxsIGxvb2sKLSAgICogZm9yIGEgY2xhc3NuYW1lIGluIHRoZSBmaWxlCi0gICAqIDxjb2RlPk1FVEEtSU5GL3NlcnZpY2VzL2phdmF4LnhtbC5wYXJzZXJzLkRUTU1hbmFnZXI8L2NvZGU+Ci0gICAqIGluIGphcnMgYXZhaWxhYmxlIHRvIHRoZSBydW50aW1lLgotICAgKiA8L2xpPgotICAgKiA8bGk+Ci0gICAqIFVzZSB0aGUgZGVmYXVsdCA8Y29kZT5EVE1NYW5hZ2VyPC9jb2RlPiBjbGFzc25hbWUsIHdoaWNoIGlzCi0gICAqIDxjb2RlPm9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQ8L2NvZGU+LgotICAgKiA8L2xpPgotICAgKiA8L3VsPgotICAgKgotICAgKiBPbmNlIGFuIGFwcGxpY2F0aW9uIGhhcyBvYnRhaW5lZCBhIHJlZmVyZW5jZSB0byBhIDxjb2RlPgotICAgKiBEVE1NYW5hZ2VyPC9jb2RlPiBpdCBjYW4gdXNlIHRoZSBmYWN0b3J5IHRvIGNvbmZpZ3VyZQotICAgKiBhbmQgb2J0YWluIHBhcnNlciBpbnN0YW5jZXMuCi0gICAqCi0gICAqIEByZXR1cm4gbmV3IERUTU1hbmFnZXIgaW5zdGFuY2UsIG5ldmVyIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICAgKiBpZiB0aGUgaW1wbGVtZW50YXRpb24gaXMgbm90IGF2YWlsYWJsZSBvciBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBEVE1NYW5hZ2VyIG5ld0luc3RhbmNlKFhNTFN0cmluZ0ZhY3RvcnkgeHNmKSAKLSAgICAgICAgICAgdGhyb3dzIERUTUNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGNsYXNzbmFtZSA9IGZpbmRGYWN0b3J5KGRlZmF1bHRQcm9wTmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTWFuYWdlckRlZmF1bHQiKTsKLQotICAgIGlmIChjbGFzc25hbWUgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19ERUZBVUxUX0lNUEwsIG51bGwpKTsgLy8iTm8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3VuZCIpOwotICAgIH0KLQotICAgIERUTU1hbmFnZXIgZmFjdG9yeUltcGw7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBDbGFzcyBjbGF6eiA9IENsYXNzLmZvck5hbWUoY2xhc3NuYW1lKTsKLQotICAgICAgZmFjdG9yeUltcGwgPSAoRFRNTWFuYWdlcikgY2xhenoubmV3SW5zdGFuY2UoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRFRNQ29uZmlndXJhdGlvbkV4Y2VwdGlvbihjbmZlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKGlhZSk7Ci0gICAgfQotICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGllKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBEVE1Db25maWd1cmF0aW9uRXhjZXB0aW9uKGllKTsKLSAgICB9Ci0gICAgZmFjdG9yeUltcGwuc2V0WE1MU3RyaW5nRmFjdG9yeSh4c2YpOwotCi0gICAgcmV0dXJuIGZhY3RvcnlJbXBsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSwgbG9hZGVkIHdpdGggdGhlIGNvbnRlbnQgZnJvbSB0aGUKLSAgICogc3BlY2lmaWVkIHNvdXJjZS4gIElmIHRoZSB1bmlxdWUgZmxhZyBpcyB0cnVlLCBhIG5ldyBpbnN0YW5jZSB3aWxsCi0gICAqIGFsd2F5cyBiZSByZXR1cm5lZC4gIE90aGVyd2lzZSBpdCBpcyB1cCB0byB0aGUgRFRNTWFuYWdlciB0byByZXR1cm4gYQotICAgKiBuZXcgaW5zdGFuY2Ugb3IgYW4gaW5zdGFuY2UgdGhhdCBpdCBhbHJlYWR5IGNyZWF0ZWQgYW5kIG1heSBiZSBiZWluZyB1c2VkCi0gICAqIGJ5IHNvbWVvbmUgZWxzZS4KLSAgICogKEkgdGhpbmsgbW9yZSBwYXJhbWV0ZXJzIHdpbGwgbmVlZCB0byBiZSBhZGRlZCBmb3IgZXJyb3IgaGFuZGxpbmcsIGFuZCBlbnRpdHkKLSAgICogcmVzb2x1dGlvbikuCi0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNwZWNpZmljYXRpb24gb2YgdGhlIHNvdXJjZSBvYmplY3QsIHdoaWNoIG1heSBiZSBudWxsLAotICAgKiAgICAgICAgICAgICAgIGluIHdoaWNoIGNhc2UgaXQgaXMgYXNzdW1lZCB0aGF0IG5vZGUgY29uc3RydWN0aW9uIHdpbGwgdGFrZQotICAgKiAgICAgICAgICAgICAgIGJ5IHNvbWUgb3RoZXIgbWVhbnMuCi0gICAqIEBwYXJhbSB1bmlxdWUgdHJ1ZSBpZiB0aGUgcmV0dXJuZWQgRFRNIG11c3QgYmUgdW5pcXVlLCBwcm9iYWJseSBiZWNhdXNlIGl0Ci0gICAqIGlzIGdvaW5nIHRvIGJlIG11dGF0ZWQuCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIEVuYWJsZXMgZmlsdGVyaW5nIG9mIHdoaXRlc3BhY2Ugbm9kZXMsIGFuZCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIGluY3JlbWVudGFsIHRydWUgaWYgdGhlIERUTSBzaG91bGQgYmUgYnVpbHQgaW5jcmVtZW50YWxseSwgaWYKLSAgICogICAgICAgICAgICAgICAgICAgIHBvc3NpYmxlLgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZSAKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRFRNIGdldERUTShqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdW5pcXVlLCBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGluY3JlbWVudGFsLCBib29sZWFuIGRvSW5kZXhpbmcpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluc3RhbmNlIG9mIERUTSB0aGF0ICJvd25zIiBhIG5vZGUgaGFuZGxlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgbm9kZUhhbmRsZS4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgRFRNIGdldERUTShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgVzNDIERPTSBub2RlLCB0cnkgYW5kIHJldHVybiBhIERUTSBoYW5kbGUuCi0gICAqIE5vdGU6IGNhbGxpbmcgdGhpcyBtYXkgYmUgbm9uLW9wdGltYWwuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vbi1udWxsIHJlZmVyZW5jZSB0byBhIERPTSBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIGEgdmFsaWQgRFRNIGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0RFRNSGFuZGxlRnJvbU5vZGUob3JnLnczYy5kb20uTm9kZSBub2RlKTsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhIERUTSByZXByZXNlbnRpbmcgYW4gZW1wdHkgPGNvZGU+RG9jdW1lbnRGcmFnbWVudDwvY29kZT4gb2JqZWN0LgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBEVE0gY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotCi0gIC8qKgotICAgKiBSZWxlYXNlIGEgRFRNIGVpdGhlciB0byBhIGxydSBwb29sLCBvciBjb21wbGV0ZWx5IHJlbW92ZSByZWZlcmVuY2UuCi0gICAqIERUTXMgd2l0aG91dCBzeXN0ZW0gSURzIGFyZSBhbHdheXMgaGFyZCBkZWxldGVkLgotICAgKiBTdGF0ZTogZXhwZXJpbWVudGFsLgotICAgKgotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gdG8gYmUgcmVsZWFzZWQuCi0gICAqIEBwYXJhbSBzaG91bGRIYXJkRGVsZXRlIFRydWUgaWYgdGhlIERUTSBzaG91bGQgYmUgcmVtb3ZlZCBubyBtYXR0ZXIgd2hhdC4KLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBEVE0gd2FzIHJlbW92ZWQsIGZhbHNlIGlmIGl0IHdhcyBwdXQgYmFjayBpbiBhIGxydSBwb29sLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gcmVsZWFzZShEVE0gZHRtLCBib29sZWFuIHNob3VsZEhhcmREZWxldGUpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+IGJhc2VkIG9uIGFuIFhQYXRoCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULUxvY2F0aW9uUGF0aD5Mb2NhdGlvblBhdGg8L2E+IG9yCi0gICAqIGEgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LgotICAgKgotICAgKiBAcGFyYW0geHBhdGhDb21waWxlciA/Pz8gU29tZWhvdyB3ZSBuZWVkIHRvIHBhc3MgaW4gYSBzdWJwYXJ0IG9mIHRoZQotICAgKiBleHByZXNzaW9uLiAgSSBoYXRlIHRvIGRvIHRoaXMgd2l0aCBzdHJpbmdzLCBzaW5jZSB0aGUgbGFyZ2VyIGV4cHJlc3Npb24KLSAgICogaGFzIGFscmVhZHkgYmVlbiBwYXJzZWQuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGluIHRoZSBleHByZXNzaW9uLgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihPYmplY3QgeHBhdGhDb21waWxlciwKLSAgICAgICAgICBpbnQgcG9zKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBiYXNlZCBvbiBhbiBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGg+TG9jYXRpb25QYXRoPC9hPiBvcgotICAgKiBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULVVuaW9uRXhwciI+VW5pb25FeHByPC9hPi4KLSAgICoKLSAgICogQHBhcmFtIHhwYXRoU3RyaW5nIE11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZXhwcmVzc2luZyBhCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULUxvY2F0aW9uUGF0aD5Mb2NhdGlvblBhdGg8L2E+IG9yCi0gICAqIGEgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LgotICAgKgotICAgKiBAcGFyYW0gcHJlc29sdmVyIEFuIG9iamVjdCB0aGF0IGNhbiByZXNvbHZlIHByZWZpeGVzIHRvIG5hbWVzcGFjZSBVUkxzLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihTdHJpbmcgeHBhdGhTdHJpbmcsCi0gICAgICAgICAgUHJlZml4UmVzb2x2ZXIgcHJlc29sdmVyKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBiYXNlZCBvbmx5IG9uIGEgd2hhdFRvU2hvdwotICAgKiBhbmQgYSBEVE1GaWx0ZXIuICBUaGUgdHJhdmVyc2FsIHNlbWFudGljcyBhcmUgZGVmaW5lZCBhcyB0aGUKLSAgICogZGVzY2VuZGFudCBhY2Nlc3MuCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgRFRNSXRlcmF0b3JzIG1heSBub3QgYmUgYW4gZXhhY3QgbWF0Y2ggdG8gRE9NCi0gICAqIE5vZGVJdGVyYXRvcnMuIFRoZXkgYXJlIGluaXRpYWxpemVkIGFuZCB1c2VkIGluIG11Y2ggdGhlIHNhbWUgd2F5Ci0gICAqIGFzIGEgTm9kZUl0ZXJhdG9yLCBidXQgdGhlaXIgcmVzcG9uc2UgdG8gZG9jdW1lbnQgbXV0YXRpb24gaXMgbm90Ci0gICAqIGN1cnJlbnRseSBkZWZpbmVkLgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBUaGlzIGZsYWcgc3BlY2lmaWVzIHdoaWNoIG5vZGUgdHlwZXMgbWF5IGFwcGVhciBpbgotICAgKiAgIHRoZSBsb2dpY2FsIHZpZXcgb2YgdGhlIHRyZWUgcHJlc2VudGVkIGJ5IHRoZSBpdGVyYXRvci4gU2VlIHRoZQotICAgKiAgIGRlc2NyaXB0aW9uIG9mIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGZvciB0aGUgc2V0IG9mIHBvc3NpYmxlCi0gICAqICAgPGNvZGU+U0hPV188L2NvZGU+IHZhbHVlcy5UaGVzZSBmbGFncyBjYW4gYmUgY29tYmluZWQgdXNpbmcKLSAgICogICA8Y29kZT5PUjwvY29kZT4uCi0gICAqIEBwYXJhbSBmaWx0ZXIgVGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IHRvIGJlIHVzZWQgd2l0aCB0aGlzCi0gICAqICAgPGNvZGU+RFRNRmlsdGVyPC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gdG8gaW5kaWNhdGUgbm8gZmlsdGVyLgotICAgKiBAcGFyYW0gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uIFRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcwotICAgKiAgIHdoZXRoZXIgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBhcmUgZXhwYW5kZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKGludCB3aGF0VG9TaG93LAotICAgICAgICAgIERUTUZpbHRlciBmaWx0ZXIsIGJvb2xlYW4gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiB0aGF0IGhvbGRzIGV4YWN0bHkgb25lIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIGhhbmRsZSB0aGF0IHRoZSBEVE1JdGVyYXRvciB3aWxsIGl0ZXJhdGUgdG8uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKGludCBub2RlKTsKLSAgCi0gIC8qIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIGFuIGluY3JlbWVudGFsIHRyYW5zZm9ybSBpcyBkZXNpcmVkICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtX2luY3JlbWVudGFsID0gZmFsc2U7ICAKLSAgCi0gIC8qKgotICAgKiBTZXQgYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciBhbiBpbmNyZW1lbnRhbCB0cmFuc2Zvcm0gaXMgZGVzaXJlZCAKLSAgICogQHBhcmFtIGluY3JlbWVudGFsIGJvb2xlYW4gdG8gdXNlIHRvIHNldCBtX2luY3JlbWVudGFsLgotICAgKgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBzdGF0aWMgYm9vbGVhbiBnZXRJbmNyZW1lbnRhbCgpCi0gIHsKLSAgICByZXR1cm4gbV9pbmNyZW1lbnRhbDsgIAotICB9Ci0gIAotICAvKioKLSAgICogU2V0IGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYW4gaW5jcmVtZW50YWwgdHJhbnNmb3JtIGlzIGRlc2lyZWQgCi0gICAqIEBwYXJhbSBpbmNyZW1lbnRhbCBib29sZWFuIHRvIHVzZSB0byBzZXQgbV9pbmNyZW1lbnRhbC4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgc3RhdGljIHZvaWQgc2V0SW5jcmVtZW50YWwoYm9vbGVhbiBpbmNyZW1lbnRhbCkKLSAgewotICAgIG1faW5jcmVtZW50YWwgPSBpbmNyZW1lbnRhbDsgIAotICB9Ci0gIAotICAKLQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLSBwcml2YXRlIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAvKioKLSAgICogQXZvaWQgcmVhZGluZyBhbGwgdGhlIGZpbGVzIHdoZW4gdGhlIGZpbmRGYWN0b3J5Ci0gICAqIG1ldGhvZCBpcyBjYWxsZWQgdGhlIHNlY29uZCB0aW1lIChjYWNoZSB0aGUgcmVzdWx0IG9mCi0gICAqIGZpbmRpbmcgdGhlIGRlZmF1bHQgaW1wbCkuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZm91bmRGYWN0b3J5ID0gbnVsbDsKLQotICAvKioKLSAgICogVGVtcCBkZWJ1ZyBjb2RlIC0gdGhpcyB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgd2UgdGVzdCBldmVyeXRoaW5nCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGRlYnVnOwotCi0gIHN0YXRpYwotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgZGVidWcgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImR0bS5kZWJ1ZyIpICE9IG51bGw7Ci0gICAgfQotICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCl7fQotICB9Ci0KLSAgLyoqCi0gICAqIFByaXZhdGUgaW1wbGVtZW50YXRpb24gbWV0aG9kIC0gd2lsbCBmaW5kIHRoZSBpbXBsZW1lbnRhdGlvbgotICAgKiBjbGFzcyBpbiB0aGUgc3BlY2lmaWVkIG9yZGVyLgotICAgKgotICAgKiBAcGFyYW0gZmFjdG9yeUlkICAgTmFtZSBvZiB0aGUgZmFjdG9yeSBpbnRlcmZhY2UuCi0gICAqIEBwYXJhbSB4bWxQcm9wZXJ0aWVzIE5hbWUgb2YgdGhlIHByb3BlcnRpZXMgZmlsZSBiYXNlZCBvbiBKQVZBL2xpYi4KLSAgICogQHBhcmFtIGRlZmF1bHRGYWN0b3J5IERlZmF1bHQgaW1wbGVtZW50YXRpb24sIGlmIG5vdGhpbmcgZWxzZSBpcyBmb3VuZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmFjdG9yeSBjbGFzcyBuYW1lLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZpbmRGYWN0b3J5KFN0cmluZyBmYWN0b3J5SWQsIFN0cmluZyBkZWZhdWx0RmFjdG9yeSkKLSAgewotCi0gICAgLy8gVXNlIHRoZSBzeXN0ZW0gcHJvcGVydHkgZmlyc3QKLSAgICB0cnkKLSAgICB7Ci0gICAgICBTdHJpbmcgc3lzdGVtUHJvcCA9IG51bGw7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBzeXN0ZW1Qcm9wID0gU3lzdGVtLmdldFByb3BlcnR5KGZhY3RvcnlJZCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2Upe30KLQotICAgICAgaWYgKHN5c3RlbVByb3AgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgaWYgKGRlYnVnKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJEVE06IGZvdW5kIHN5c3RlbSBwcm9wZXJ0eSIgKyBzeXN0ZW1Qcm9wKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBzeXN0ZW1Qcm9wOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2Upe30KLQotICAgIGlmIChmb3VuZEZhY3RvcnkgIT0gbnVsbCkKLSAgICB7Ci0gICAgICByZXR1cm4gZm91bmRGYWN0b3J5OwotICAgIH0KLQotICAgIC8vIHRyeSB0byByZWFkIGZyb20gJGphdmEuaG9tZS9saWIvamF4cC5wcm9wZXJ0aWVzCi0gICAgdHJ5Ci0gICAgewotICAgICAgU3RyaW5nIGphdmFoID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmhvbWUiKTsKLSAgICAgIFN0cmluZyBjb25maWdGaWxlID0gamF2YWggKyBGaWxlLnNlcGFyYXRvciArICJsaWIiICsgRmlsZS5zZXBhcmF0b3IKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiamF4cC5wcm9wZXJ0aWVzIjsKLSAgICAgIEZpbGUgZiA9IG5ldyBGaWxlKGNvbmZpZ0ZpbGUpOwotCi0gICAgICBpZiAoZi5leGlzdHMoKSkKLSAgICAgIHsKLSAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0KLSAgICAgICAgcHJvcHMubG9hZChuZXcgRmlsZUlucHV0U3RyZWFtKGYpKTsKLQotICAgICAgICBmb3VuZEZhY3RvcnkgPSBwcm9wcy5nZXRQcm9wZXJ0eShmYWN0b3J5SWQpOwotCi0gICAgICAgIGlmIChkZWJ1ZykKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRFRNOiBmb3VuZCBqYXZhLmhvbWUgcHJvcGVydHkgIiArIGZvdW5kRmFjdG9yeSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoZm91bmRGYWN0b3J5ICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZm91bmRGYWN0b3J5OwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCi0gICAgewotICAgICAgaWYgKGRlYnVnKQotICAgICAgewotICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBTdHJpbmcgc2VydmljZUlkID0gIk1FVEEtSU5GL3NlcnZpY2VzLyIgKyBmYWN0b3J5SWQ7Ci0KLSAgICAvLyB0cnkgdG8gZmluZCBzZXJ2aWNlcyBpbiBDTEFTU1BBVEgKLSAgICB0cnkKLSAgICB7Ci0gICAgICBDbGFzc0xvYWRlciBjbCA9IERUTU1hbmFnZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKLSAgICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKLQotICAgICAgaWYgKGNsID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGlzID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2VBc1N0cmVhbShzZXJ2aWNlSWQpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpcyA9IGNsLmdldFJlc291cmNlQXNTdHJlYW0oc2VydmljZUlkKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGlzICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGlmIChkZWJ1ZykKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRFRNOiBmb3VuZCAgIiArIHNlcnZpY2VJZCk7Ci0gICAgICAgIH0KLQotICAgICAgICBCdWZmZXJlZFJlYWRlciByZCA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMpKTsKLQotICAgICAgICBmb3VuZEZhY3RvcnkgPSByZC5yZWFkTGluZSgpOwotCi0gICAgICAgIHJkLmNsb3NlKCk7Ci0KLSAgICAgICAgaWYgKGRlYnVnKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJEVE06IGxvYWRlZCBmcm9tIHNlcnZpY2VzOiAiICsgZm91bmRGYWN0b3J5KTsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICgoZm91bmRGYWN0b3J5ICE9IG51bGwpICYmISIiLmVxdWFscyhmb3VuZEZhY3RvcnkpKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZvdW5kRmFjdG9yeTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQotICAgIHsKLSAgICAgIGlmIChkZWJ1ZykKLSAgICAgIHsKLSAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGRlZmF1bHRGYWN0b3J5OwotICB9Ci0KLQotICAvKiogVGhpcyB2YWx1ZSwgc2V0IGF0IGNvbXBpbGUgdGltZSwgY29udHJvbHMgaG93IG1hbnkgYml0cyBvZiB0aGUKLSAgICogRFRNIG5vZGUgaWRlbnRpZmllciBudW1iZXJzIGFyZSB1c2VkIHRvIGlkZW50aWZ5IGEgbm9kZSB3aXRoaW4gYQotICAgKiBkb2N1bWVudCwgYW5kIHRodXMgc2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2Ygbm9kZXMgcGVyCi0gICAqIGRvY3VtZW50LiBUaGUgcmVtYWluaW5nIGJpdHMgYXJlIHVzZWQgdG8gaWRlbnRpZnkgdGhlIERUTQotICAgKiBkb2N1bWVudCB3aGljaCBjb250YWlucyB0aGlzIG5vZGUuCi0gICAqCi0gICAqIElmIHlvdSBjaGFuZ2UgSURFTlRfRFRNX05PREVfQklUUywgYmUgc3VyZSB0byByZWJ1aWxkIF9BTExfIHRoZQotICAgKiBmaWxlcyB3aGljaCB1c2UgaXQuLi4gaW5jbHVkaW5nIHRoZSBJREtleSB0ZXN0Y2FzZXMuCi0gICAqCi0gICAqIChGdW5jR2VuZXJhdGVLZXkgY3VycmVudGx5IHVzZXMgdGhlIG5vZGUgaWRlbnRpZmllciBkaXJlY3RseSBhbmQKLSAgICogdGh1cyBpcyBzZW5zaXRpdmUgdG8gaXRzIGZvcm1hdC4gVGhlIElES0VZIHJlc3VsdHMgd2lsbCBzdGlsbCBiZQotICAgKiBfY29ycmVjdF8gKHByZXN1bWluZyBubyBvdGhlciBicmVha2FnZSksIGJ1dCBzaW1wbGUgZXF1YWxpdHkKLSAgICogY29tcGFyaXNvbiBhZ2FpbnN0IHRoZSBwcmV2aW91cyAiZ29sZGVuIiBmaWxlcyB3aWxsIHByb2JhYmx5Ci0gICAqIGNvbXBsYWluLikgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElERU5UX0RUTV9OT0RFX0JJVFMgPSAyMjsKLSAgICAKLQotICAvKiogV2hlbiB0aGlzIGJpdG1hc2sgaXMgQU5EZWQgd2l0aCBhIERUTSBub2RlIGhhbmRsZSBudW1iZXIsIHRoZSByZXN1bHQKLSAgICogaXMgdGhlIG5vZGUncyBpbmRleCBudW1iZXIgd2l0aGluIHRoYXQgRFRNLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSURFTlRfTk9ERV9ERUZBVUxUID0gKDE8PElERU5UX0RUTV9OT0RFX0JJVFMpLTE7Ci0KLQotICAvKiogV2hlbiB0aGlzIGJpdG1hc2sgaXMgQU5EZWQgd2l0aCBhIERUTSBub2RlIGhhbmRsZSBudW1iZXIsIHRoZSByZXN1bHQKLSAgICogaXMgdGhlIERUTSdzIGRvY3VtZW50IGlkZW50aXR5IG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElERU5UX0RUTV9ERUZBVUxUID0gfklERU5UX05PREVfREVGQVVMVDsKLQotICAvKiogVGhpcyBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgRFRNcyBhdmFpbGFibGUuICBUaGUgaGlnaGVzdCBEVE0gaXMKLSAgICAqIG9uZSBsZXNzIHRoYW4gdGhpcy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElERU5UX01BWF9EVE1TID0gKElERU5UX0RUTV9ERUZBVUxUID4+PiBJREVOVF9EVE1fTk9ERV9CSVRTKSArIDE7Ci0KLQotICAvKioKLSAgICogJVRCRCUgRG9jCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBkdG0KLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBnZXREVE1JZGVudGl0eShEVE0gZHRtKTsKLQotICAvKioKLSAgICogJVRCRCUgRG9jCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RFRNSWRlbnRpdHlNYXNrKCkKLSAgewotICAgIHJldHVybiBJREVOVF9EVE1fREVGQVVMVDsKLSAgfQotCi0gIC8qKgotICAgKiAlVEJEJSBEb2MKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGludCBnZXROb2RlSWRlbnRpdHlNYXNrKCkKLSAgewotICAgIHJldHVybiBJREVOVF9OT0RFX0RFRkFVTFQ7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1XU0ZpbHRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9EVE1XU0ZpbHRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NzdlNjU4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vRFRNV1NGaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM2ICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtOwotCi0vKioKLSAqIFRoaXMgaW50ZXJmYWNlIGlzIG1lYW50IHRvIGJlIGltcGxlbWVudGVkIGJ5IGEgY2xpZW50IG9mIHRoZSBEVE0sIGFuZCBhbGxvd3MKLSAqIHN0cmlwcGluZyBvZiB3aGl0ZXNwYWNlIG5vZGVzLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIERUTVdTRmlsdGVyCi17Ci0gIC8qKgotICAgKiBEbyBub3Qgc3RyaXAgd2hpdGVzcGFjZSBjaGlsZCBub2RlcyBvZiB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IE5PVFNUUklQID0gMTsKLQotICAvKioKLSAgICogU3RyaXAgd2hpdGVzcGFjZSBjaGlsZCBub2RlcyBvZiB0aGlzIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFNUUklQID0gMjsKLQotICAvKioKLSAgICogSW5oZXJpdCB3aGl0ZXNwYWNlIHN0cmlwcGluZyBiZWhhdmlvciBvZiB0aGUgcGFyZW50IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IElOSEVSSVQgPSAzOwotCi0gIC8qKgotICAgKiBUZXN0IHdoZXRoZXIgd2hpdGVzcGFjZS1vbmx5IHRleHQgbm9kZXMgYXJlIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgCi0gICAqIHZpZXcgb2YgPGNvZGU+RFRNPC9jb2RlPi4gTm9ybWFsbHksIHRoaXMgZnVuY3Rpb24KLSAgICogd2lsbCBiZSBjYWxsZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPkRUTTwvY29kZT47IAotICAgKiBpdCBpcyBub3Qgbm9ybWFsbHkgY2FsbGVkIGRpcmVjdGx5IGZyb20KLSAgICogdXNlciBjb2RlLgotICAgKiAKLSAgICogQHBhcmFtIGVsZW1lbnRIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgZWxlbWVudC4KLSAgICogQHJldHVybiBvbmUgb2YgTk9UU1RSSVAsIFNUUklQLCBvciBJTkhFUklULgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldFNob3VsZFN0cmlwU3BhY2UoaW50IGVsZW1lbnRIYW5kbGUsIERUTSBkdG0pOwotICAKLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9DaHVua2VkSW50QXJyYXkuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0NodW5rZWRJbnRBcnJheS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNWM3YzI0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0NodW5rZWRJbnRBcnJheS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzQ1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0gCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotLyoqCi0gKiA8Y29kZT5DaHVua2VkSW50QXJyYXk8L2NvZGU+IGlzIGFuIGV4dGVuc2libGUgYXJyYXkgb2YgYmxvY2tzIG9mIGludGVnZXJzLgotICogKEknZCBjb25zaWRlciBWZWN0b3IsIGJ1dCBpdCdzIHVuYWJsZSB0byBoYW5kbGUgaW50ZWdlcnMgZXhjZXB0IGJ5Ci0gKiB0dXJuaW5nIHRoZW0gaW50byBPYmplY3RzLikKLQotICogPHA+TWFraW5nIHRoaXMgYSBzZXBhcmF0ZSBjbGFzcyBtZWFucyBzb21lIGNhbGwtYW5kLXJldHVybiBvdmVyaGVhZC4gQnV0Ci0gKiBkb2luZyBpdCBhbGwgaW5saW5lIHRlbmRzIHRvIGJlIGZyYWdpbGUgYW5kIGV4cGVuc2l2ZSBpbiBjb2RlciB0aW1lLAotICogbm90IHRvIG1lbnRpb24gZHJpdmluZyB1cCBjb2RlIHNpemUuIElmIHlvdSB3YW50IHRvIGlubGluZSBpdCwgZmVlbCBmcmVlLgotICogVGhlIEphdmEgdGV4dCBzdWdnZXN0IHRoYXQgcHJpdmF0ZSBhbmQgRmluYWwgbWV0aG9kcyBtYXkgYmUgaW5saW5lZCwgCi0gKiBhbmQgb25lIGNhbiBhcmd1ZSB0aGF0IHRoaXMgYmVhc3QgbmVlZCBub3QgYmUgbWFkZSBzdWJjbGFzc2FibGUuLi48L3A+Ci0gKgotICogPHA+JVJFVklFVyUgVGhpcyBoYXMgc3Ryb25nIGNvbmNlcHR1YWwgb3ZlcmxhcCB3aXRoIHRoZSBJbnRWZWN0b3IgY2xhc3MuCi0gKiBJdCB3b3VsZCBwcm9iYWJseSBiZSBhIGdvb2QgdGhpbmcgdG8gbWVyZ2UgdGhlIHR3bywgd2hlbiB0aW1lIHBlcm1pdHMuPHA+Ci0gKi8KLWZpbmFsIGNsYXNzIENodW5rZWRJbnRBcnJheQotewotICBmaW5hbCBpbnQgc2xvdHNpemU9NDsgLy8gTG9ja2VkLCBNVVNUIGJlIHBvd2VyIG9mIHR3byBpbiBjdXJyZW50IGNvZGUKLSAgLy8gRGVidWdnaW5nIHRpcDogQ3JhbmtpbmcgbG93Yml0cyBkb3duIHRvIDQgb3Igc28gaXMgYSBnb29kCi0gIC8vIHdheSB0byBwb3VuZCBvbiB0aGUgYXJyYXkgYWRkcmVzc2luZyBjb2RlLgotICBzdGF0aWMgZmluYWwgaW50IGxvd2JpdHM9MTA7IC8vIEhvdyBtYW55IGJpdHMgYWRkcmVzcyB3aXRoaW4gY2h1bmtzCi0gIHN0YXRpYyBmaW5hbCBpbnQgY2h1bmthbGxvYz0xPDxsb3diaXRzOwotICBzdGF0aWMgZmluYWwgaW50IGxvd21hc2s9Y2h1bmthbGxvYy0xOwotICAKLSAgQ2h1bmtzVmVjdG9yIGNodW5rcz1uZXcgQ2h1bmtzVmVjdG9yKCk7Ci0gIGZpbmFsIGludCBmYXN0QXJyYXlbXSA9IG5ldyBpbnRbY2h1bmthbGxvY107Ci0gIGludCBsYXN0VXNlZD0wOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgQ0lBIHdpdGggc3BlY2lmaWVkIHJlY29yZCBzaXplLiBDdXJyZW50bHkgcmVjb3JkIHNpemUgTVVTVAotICAgKiBiZSBhIHBvd2VyIG9mIHR3by4uLiBhbmQgaW4gZmFjdCBpcyBoYXJkY29kZWQgdG8gNC4KLSAgICovCi0gIENodW5rZWRJbnRBcnJheShpbnQgc2xvdHNpemUpCi0gIHsKLSAgICBpZih0aGlzLnNsb3RzaXplPHNsb3RzaXplKQotICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DSFVOS0VESU5UQVJSQVlfTk9UX1NVUFBPUlRFRCwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc2xvdHNpemUpfSkpOyAvLyJDaHVua2VkSW50QXJyYXkoIitzbG90c2l6ZSsiKSBub3QgY3VycmVudGx5IHN1cHBvcnRlZCIpOwotICAgIGVsc2UgaWYgKHRoaXMuc2xvdHNpemU+c2xvdHNpemUpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqV0FSTklORzogQ2h1bmtlZEludEFycmF5KCIrc2xvdHNpemUrIikgd2FzdGluZyAiKyh0aGlzLnNsb3RzaXplLXNsb3RzaXplKSsiIHdvcmRzIHBlciBzbG90Iik7Ci0gICAgY2h1bmtzLmFkZEVsZW1lbnQoZmFzdEFycmF5KTsKLSAgfQotICAvKioKLSAgICogQXBwZW5kIGEgNC1pbnRlZ2VyIHJlY29yZCB0byB0aGUgQ0lBLCBzdGFydGluZyB3aXRoIHJlY29yZCAxLiAoU2luY2UKLSAgICogYXJyYXlzIGFyZSBpbml0aWFsaXplZCB0byBhbGwtMCwgMCBoYXMgYmVlbiByZXNlcnZlZCBhcyB0aGUgInVua25vd24iCi0gICAqIHZhbHVlIGluIERUTS4pCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IGF0IHdoaWNoIHRoaXMgcmVjb3JkIHdhcyBpbnNlcnRlZC4KLSAgICovCi0gIGludCBhcHBlbmRTbG90KGludCB3MCwgaW50IHcxLCBpbnQgdzIsIGludCB3MykKLSAgewotICAgIC8qCi0gICAgdHJ5Ci0gICAgewotICAgICAgaW50IG5ld29mZnNldCA9IChsYXN0VXNlZCsxKSpzbG90c2l6ZTsKLSAgICAgIGZhc3RBcnJheVtuZXdvZmZzZXRdID0gdzA7Ci0gICAgICBmYXN0QXJyYXlbbmV3b2Zmc2V0KzFdID0gdzE7Ci0gICAgICBmYXN0QXJyYXlbbmV3b2Zmc2V0KzJdID0gdzI7Ci0gICAgICBmYXN0QXJyYXlbbmV3b2Zmc2V0KzNdID0gdzM7Ci0gICAgICByZXR1cm4gKytsYXN0VXNlZDsKLSAgICB9Ci0gICAgY2F0Y2goQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGFpb29iZSkKLSAgICAqLwotICAgIHsKLSAgICAgIGZpbmFsIGludCBzbG90c2l6ZT00OwotICAgICAgaW50IG5ld29mZnNldCA9IChsYXN0VXNlZCsxKSpzbG90c2l6ZTsKLSAgICAgIGludCBjaHVua3BvcyA9IG5ld29mZnNldCA+PiBsb3diaXRzOwotICAgICAgaW50IHNsb3Rwb3MgPSAobmV3b2Zmc2V0ICYgbG93bWFzayk7Ci0KLSAgICAgIC8vIEdyb3cgaWYgbmVlZGVkCi0gICAgICBpZiAoY2h1bmtwb3MgPiBjaHVua3Muc2l6ZSgpIC0gMSkKLSAgICAgICAgY2h1bmtzLmFkZEVsZW1lbnQobmV3IGludFtjaHVua2FsbG9jXSk7Ci0gICAgICBpbnRbXSBjaHVuayA9IGNodW5rcy5lbGVtZW50QXQoY2h1bmtwb3MpOwotICAgICAgY2h1bmtbc2xvdHBvc10gPSB3MDsKLSAgICAgIGNodW5rW3Nsb3Rwb3MrMV0gPSB3MTsKLSAgICAgIGNodW5rW3Nsb3Rwb3MrMl0gPSB3MjsKLSAgICAgIGNodW5rW3Nsb3Rwb3MrM10gPSB3MzsKLQotICAgICAgcmV0dXJuICsrbGFzdFVzZWQ7Ci0gICAgfQotICB9Ci0gIC8qKgotICAgKiBSZXRyaWV2ZSBhbiBpbnRlZ2VyIGZyb20gdGhlIENJQSBieSByZWNvcmQgbnVtYmVyIGFuZCBjb2x1bW4gd2l0aGluCi0gICAqIHRoZSByZWNvcmQsIGJvdGggMC1iYXNlZCAodGhvdWdoIHBvc2l0aW9uIDAgaXMgcmVzZXJ2ZWQgZm9yIHNwZWNpYWwKLSAgICogcHVycG9zZXMpLgotICAgKiBAcGFyYW0gcG9zaXRpb24gaW50IFJlY29yZCBudW1iZXIKLSAgICogQHBhcmFtIHNsb3Rwb3MgaW50IENvbHVtbiBudW1iZXIKLSAgICovCi0gIGludCByZWFkRW50cnkoaW50IHBvc2l0aW9uLCBpbnQgb2Zmc2V0KSB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gIHsKLSAgICAvKgotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBmYXN0QXJyYXlbKHBvc2l0aW9uKnNsb3RzaXplKStvZmZzZXRdOwotICAgIH0KLSAgICBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gYWlvb2JlKQotICAgICovCi0gICAgewotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJVc2luZyBzbG93IHJlYWQgKDEpIik7Ci0gICAgICBpZiAob2Zmc2V0Pj1zbG90c2l6ZSkKLSAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwgbnVsbCkpOyAvLyJPZmZzZXQgYmlnZ2VyIHRoYW4gc2xvdCIpOwotICAgICAgcG9zaXRpb24qPXNsb3RzaXplOwotICAgICAgaW50IGNodW5rcG9zID0gcG9zaXRpb24gPj4gbG93Yml0czsKLSAgICAgIGludCBzbG90cG9zID0gcG9zaXRpb24gJiBsb3dtYXNrOwotICAgICAgaW50W10gY2h1bmsgPSBjaHVua3MuZWxlbWVudEF0KGNodW5rcG9zKTsKLSAgICAgIHJldHVybiBjaHVua1tzbG90cG9zICsgb2Zmc2V0XTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8vIENoZWNrIHRoYXQgdGhlIG5vZGUgYXQgaW5kZXggInBvc2l0aW9uIiBpcyBub3QgYW4gYW5jZXN0b3IKLSAgLy8gb2YgdGhlIG5vZGUgYXQgaW5kZXggInN0YXJ0UG9zIi4gSUYgSVQgSVMsIERPIE5PVCBBQ0NFUFQgSVQgQU5ECi0gIC8vIFJFVFVSTiAtMS4gSWYgcG9zaXRpb24gaXMgTk9UIGFuIGFuY2VzdG9yLCByZXR1cm4gcG9zaXRpb24uCi0gIC8vIFNwZWNpYWwgY2FzZTogVGhlIERvY3VtZW50IG5vZGUgKHBvc2l0aW9uPT0wKSBpcyBhY2NlcHRhYmxlLgotICAvLwotICAvLyBUaGlzIHRlc3Qgc3VwcG9ydHMgRFRNLmdldE5leHRQcmVjZWRpbmcuCi0gIGludCBzcGVjaWFsRmluZChpbnQgc3RhcnRQb3MsIGludCBwb3NpdGlvbikKLSAgewotICAgICAgICAgIC8vIFdlIGhhdmUgdG8gbG9vayBhbGwgdGhlIHdheSB1cCB0aGUgYW5jZXN0b3IgY2hhaW4KLSAgICAgICAgICAvLyB0byBtYWtlIHN1cmUgd2UgZG9uJ3QgaGF2ZSBhbiBhbmNlc3Rvci4KLSAgICAgICAgICBpbnQgYW5jZXN0b3IgPSBzdGFydFBvczsKLSAgICAgICAgICB3aGlsZShhbmNlc3RvciA+IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgbm9kZSB3aG9zZSBpbmRleCA9PSBhbmNlc3RvcgotICAgICAgICAgICAgICAgIGFuY2VzdG9yKj1zbG90c2l6ZTsKLSAgICAgICAgICAgICAgICBpbnQgY2h1bmtwb3MgPSBhbmNlc3RvciA+PiBsb3diaXRzOwotICAgICAgICAgICAgICAgIGludCBzbG90cG9zID0gYW5jZXN0b3IgJiBsb3dtYXNrOwotICAgICAgICAgICAgICAgIGludFtdIGNodW5rID0gY2h1bmtzLmVsZW1lbnRBdChjaHVua3Bvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIC8vIEdldCB0aGF0IG5vZGUncyBwYXJlbnQgKE5vdGUgdGhhdCB0aGlzIGFzc3VtZXMgd1sxXQotICAgICAgICAgICAgICAgIC8vIGlzIHRoZSBwYXJlbnQgbm9kZSBpbmRleC4gVGhhdCdzIHJlYWxseSBhIERUTSBmZWF0dXJlCi0gICAgICAgICAgICAgICAgLy8gcmF0aGVyIHRoYW4gYSBDaHVua2VkSW50QXJyYXkgZmVhdHVyZS4pCi0gICAgICAgICAgICAgICAgYW5jZXN0b3IgPSBjaHVua1tzbG90cG9zICsgMV07Ci0KLSAgICAgICAgICAgICAgICBpZihhbmNlc3RvciA9PSBwb3NpdGlvbikKLSAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoYW5jZXN0b3IgPD0gMCkgCi0gICAgICAgICAgewotICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwotICAgICAgICAgIH0KLSAgICAgICAgICByZXR1cm4gLTE7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBAcmV0dXJuIGludCBpbmRleCBvZiBoaWdoZXN0LW51bWJlcmVkIHJlY29yZCBjdXJyZW50bHkgaW4gdXNlCi0gICAqLwotICBpbnQgc2xvdHNVc2VkKCkKLSAgewotICAgIHJldHVybiBsYXN0VXNlZDsKLSAgfQotCi0gIC8qKiBEaXNhcmQgdGhlIGhpZ2hlc3QtbnVtYmVyZWQgcmVjb3JkLiBUaGlzIGlzIHVzZWQgaW4gdGhlIHN0cmluZy1idWZmZXIKLSAgIENJQTsgd2hlbiBvbmx5IGEgc2luZ2xlIGNoYXJhY3RlcnMoKSBjaHVuayBoYXMgYmVlbiByZWNpZXZlZCwgaXRzIGluZGV4Ci0gICBpcyBtb3ZlZCBpbnRvIHRoZSBUZXh0IG5vZGUgcmF0aGVyIHRoYW4gYmVpbmcgcmVmZXJlbmNlZCBieSBpbmRpcmVjdGlvbgotICAgaW50byB0aGUgdGV4dCBhY2N1bXVsYXRvci4KLSAgICovCi0gIHZvaWQgZGlzY2FyZExhc3QoKQotICB7Ci0gICAgLS1sYXN0VXNlZDsKLSAgfQotCi0gIC8qKgotICAgKiBPdmVyd3JpdGUgdGhlIGludGVnZXIgZm91bmQgYXQgYSBzcGVjaWZpYyByZWNvcmQgYW5kIGNvbHVtbi4KLSAgICogVXNlZCB0byBiYWNrLXBhdGNoIGV4aXN0aW5nIHJlY29yZHMsIG1vc3Qgb2Z0ZW4gY2hhbmdpbmcgdGhlaXIKLSAgICogIm5leHQgc2libGluZyIgcmVmZXJlbmNlIGZyb20gMCAodW5rbm93bikgdG8gc29tZXRoaW5nIG1lYW5pbmdmdWwKLSAgICogQHBhcmFtIHBvc2l0aW9uIGludCBSZWNvcmQgbnVtYmVyCi0gICAqIEBwYXJhbSBvZmZzZXQgaW50IENvbHVtbiBudW1iZXIKLSAgICogQHBhcmFtIHZhbHVlIGludCBOZXcgY29udGVudHMKLSAgICovCi0gIHZvaWQgd3JpdGVFbnRyeShpbnQgcG9zaXRpb24sIGludCBvZmZzZXQsIGludCB2YWx1ZSkgdGhyb3dzIEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICB7Ci0gICAgLyoKLSAgICB0cnkKLSAgICB7Ci0gICAgICBmYXN0QXJyYXlbKCBwb3NpdGlvbipzbG90c2l6ZSkrb2Zmc2V0XSA9IHZhbHVlOwotICAgIH0KLSAgICBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gYWlvb2JlKQotICAgICovCi0gICAgewotICAgICAgaWYgKG9mZnNldCA+PSBzbG90c2l6ZSkKLSAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9PRkZTRVRfQklHR0VSX1RIQU5fU0xPVCwgbnVsbCkpOyAvLyJPZmZzZXQgYmlnZ2VyIHRoYW4gc2xvdCIpOwotICAgICAgcG9zaXRpb24qPXNsb3RzaXplOwotICAgICAgaW50IGNodW5rcG9zID0gcG9zaXRpb24gPj4gbG93Yml0czsKLSAgICAgIGludCBzbG90cG9zID0gcG9zaXRpb24gJiBsb3dtYXNrOwotICAgICAgaW50W10gY2h1bmsgPSBjaHVua3MuZWxlbWVudEF0KGNodW5rcG9zKTsKLSAgICAgIGNodW5rW3Nsb3Rwb3MgKyBvZmZzZXRdID0gdmFsdWU7IC8vIEFUT01JQyEKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcndyaXRlIGFuIGVudGlyZSAoNC1pbnRlZ2VyKSByZWNvcmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogTW9zdGx5IHVzZWQgdG8gY3JlYXRlIHJlY29yZCAwLCB0aGUgRG9jdW1lbnQgbm9kZS4KLSAgICogQHBhcmFtIHBvc2l0aW9uIGludGVnZXIgUmVjb3JkIG51bWJlcgotICAgKiBAcGFyYW0gdzAgaW50IAotICAgKiBAcGFyYW0gdzEgaW50Ci0gICAqIEBwYXJhbSB3MiBpbnQKLSAgICogQHBhcmFtIHczIGludAotICAgKi8KLSAgdm9pZCB3cml0ZVNsb3QoaW50IHBvc2l0aW9uLCBpbnQgdzAsIGludCB3MSwgaW50IHcyLCBpbnQgdzMpCi0gIHsKLSAgICAgIHBvc2l0aW9uICo9IHNsb3RzaXplOwotICAgICAgaW50IGNodW5rcG9zID0gcG9zaXRpb24gPj4gbG93Yml0czsKLSAgICAgIGludCBzbG90cG9zID0gKHBvc2l0aW9uICYgbG93bWFzayk7Ci0KLSAgICAvLyBHcm93IGlmIG5lZWRlZAotICAgIGlmIChjaHVua3BvcyA+IGNodW5rcy5zaXplKCkgLSAxKQotICAgICAgY2h1bmtzLmFkZEVsZW1lbnQobmV3IGludFtjaHVua2FsbG9jXSk7Ci0gICAgaW50W10gY2h1bmsgPSBjaHVua3MuZWxlbWVudEF0KGNodW5rcG9zKTsKLSAgICBjaHVua1tzbG90cG9zXSA9IHcwOwotICAgIGNodW5rW3Nsb3Rwb3MgKyAxXSA9IHcxOwotICAgIGNodW5rW3Nsb3Rwb3MgKyAyXSA9IHcyOwotICAgIGNodW5rW3Nsb3Rwb3MgKyAzXSA9IHczOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSBjb250ZW50cyBvZiBhIHJlY29yZCBpbnRvIGEgdXNlci1zdXBwbGllZCBidWZmZXIgYXJyYXkuCi0gICAqIFVzZWQgdG8gcmVkdWNlIGFkZHJlc3Npbmcgb3ZlcmhlYWQgd2hlbiBjb2RlIHdpbGwgYWNjZXNzIHNldmVyYWwKLSAgICogY29sdW1ucyBvZiB0aGUgcmVjb3JkLgotICAgKiBAcGFyYW0gcG9zaXRpb24gaW50IFJlY29yZCBudW1iZXIKLSAgICogQHBhcmFtIGJ1ZmZlciBpbnRbXSBJbnRlZ2VyIGFycmF5IHByb3ZpZGVkIGJ5IHVzZXIsIG11c3QgYmUgbGFyZ2UgZW5vdWdoCi0gICAqIHRvIGhvbGQgYSBjb21wbGV0ZSByZWNvcmQuCi0gICAqLwotICB2b2lkIHJlYWRTbG90KGludCBwb3NpdGlvbiwgaW50W10gYnVmZmVyKQotICB7Ci0gICAgLyoKLSAgICB0cnkKLSAgICB7Ci0gICAgICBTeXN0ZW0uYXJyYXljb3B5KGZhc3RBcnJheSwgcG9zaXRpb24qc2xvdHNpemUsIGJ1ZmZlciwgMCwgc2xvdHNpemUpOwotICAgIH0KLSAgICBjYXRjaChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gYWlvb2JlKQotICAgICovCi0gICAgewotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJVc2luZyBzbG93IHJlYWQgKDIpOiAiK3Bvc2l0aW9uKTsKLSAgICAgIHBvc2l0aW9uICo9IHNsb3RzaXplOwotICAgICAgaW50IGNodW5rcG9zID0gcG9zaXRpb24gPj4gbG93Yml0czsKLSAgICAgIGludCBzbG90cG9zID0gKHBvc2l0aW9uICYgbG93bWFzayk7Ci0KLSAgICAgIC8vIEdyb3cgaWYgbmVlZGVkCi0gICAgICBpZiAoY2h1bmtwb3MgPiBjaHVua3Muc2l6ZSgpIC0gMSkKLSAgICAgICAgY2h1bmtzLmFkZEVsZW1lbnQobmV3IGludFtjaHVua2FsbG9jXSk7Ci0gICAgICBpbnRbXSBjaHVuayA9IGNodW5rcy5lbGVtZW50QXQoY2h1bmtwb3MpOwotICAgICAgU3lzdGVtLmFycmF5Y29weShjaHVuayxzbG90cG9zLGJ1ZmZlciwwLHNsb3RzaXplKTsKLSAgICB9Ci0gIH0KLQotICBjbGFzcyBDaHVua3NWZWN0b3IKLSAgewotICAgIGZpbmFsIGludCBCTE9DS1NJWkUgPSA2NDsKLSAgICBpbnRbXSBtX21hcFtdID0gbmV3IGludFtCTE9DS1NJWkVdW107Ci0gICAgaW50IG1fbWFwU2l6ZSA9IEJMT0NLU0laRTsKLSAgICBpbnQgcG9zID0gMDsKLSAgICAKLSAgICBDaHVua3NWZWN0b3IoKQotICAgIHsKLSAgICB9Ci0gICAgCi0gICAgZmluYWwgaW50IHNpemUoKQotICAgIHsKLSAgICAgIHJldHVybiBwb3M7Ci0gICAgfQotICAgIAotICAgIHZvaWQgYWRkRWxlbWVudChpbnRbXSB2YWx1ZSkKLSAgICB7Ci0gICAgICBpZihwb3MgPj0gbV9tYXBTaXplKQotICAgICAgewotICAgICAgICBpbnQgb3JnTWFwU2l6ZSA9IG1fbWFwU2l6ZTsKLSAgICAgICAgd2hpbGUocG9zID49IG1fbWFwU2l6ZSkKLSAgICAgICAgICBtX21hcFNpemUrPUJMT0NLU0laRTsKLSAgICAgICAgaW50W10gbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBvcmdNYXBTaXplKTsKLSAgICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgICB9Ci0gICAgICAvLyBGb3Igbm93LCBqdXN0IGRvIGEgc2ltcGxlIGFwcGVuZC4gIEEgc29ydGVkIGluc2VydCBvbmx5IAotICAgICAgLy8gbWFrZXMgc2Vuc2UgaWYgd2UncmUgZG9pbmcgYW4gYmluYXJ5IHNlYXJjaCBvciBzb21lIHN1Y2guCi0gICAgICBtX21hcFtwb3NdID0gdmFsdWU7Ci0gICAgICBwb3MrKzsKLSAgICB9Ci0gICAgCi0gICAgZmluYWwgaW50W10gZWxlbWVudEF0KGludCBwb3MpCi0gICAgewotICAgICAgcmV0dXJuIG1fbWFwW3Bvc107Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Db3JvdXRpbmVNYW5hZ2VyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Db3JvdXRpbmVNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYxOTM4YTUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvQ29yb3V0aW5lTWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzgxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogPHA+U3VwcG9ydCB0aGUgY29yb3V0aW5lIGRlc2lnbiBwYXR0ZXJuLjwvcD4KLSAqIAotICogPHA+QSBjb3JvdXRpbmUgc2V0IGlzIGEgdmVyeSBzaW1wbGUgY29vcGVyYXRpdmUgbm9uLXByZWVtcHRpdmUKLSAqIG11bHRpdGFza2luZyBtb2RlbCwgd2hlcmUgdGhlIHN3aXRjaCBmcm9tIG9uZSB0YXNrIHRvIGFub3RoZXIgaXMKLSAqIHBlcmZvcm1lZCB2aWEgYW4gZXhwbGljaXQgcmVxdWVzdC4gQ29yb3V0aW5lcyBpbnRlcmFjdCBhY2NvcmRpbmcgdG8KLSAqIHRoZSBmb2xsb3dpbmcgcnVsZXM6PC9wPgotICoKLSAqIDx1bD4KLSAqIDxsaT5PbmUgY29yb3V0aW5lIGluIHRoZSBzZXQgaGFzIGNvbnRyb2wsIHdoaWNoIGl0IHJldGFpbnMgdW50aWwgaXQKLSAqIGVpdGhlciBleGl0cyBvciByZXN1bWVzIGFub3RoZXIgY29yb3V0aW5lLjwvbGk+Ci0gKiA8bGk+QSBjb3JvdXRpbmUgaXMgYWN0aXZhdGVkIHdoZW4gaXQgaXMgcmVzdW1lZCBieSBzb21lIG90aGVyIGNvcm91dGluZQotICogZm9yIHRoZSBmaXJzdCB0aW1lLjwvbGk+Ci0gKiA8bGk+QW4gYWN0aXZlIGNvcm91dGluZSB0aGF0IGdpdmVzIHVwIGNvbnRyb2wgYnkgcmVzdW1pbmcgYW5vdGhlciBpbgotICogdGhlIHNldCByZXRhaW5zIGl0cyBjb250ZXh0IC0tIGluY2x1ZGluZyBjYWxsIHN0YWNrIGFuZCBsb2NhbCB2YXJpYWJsZXMKLSAqIC0tIHNvIHRoYXQgaWYvd2hlbiBpdCBpcyByZXN1bWVkLCBpdCB3aWxsIHByb2NlZWQgZnJvbSB0aGUgcG9pbnQgYXQgd2hpY2gKLSAqIGl0IGxhc3QgZ2F2ZSB1cCBjb250cm9sLjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIDxwPkNvcm91dGluZXMgY2FuIGJlIHRob3VnaHQgb2YgYXMgZmFsbGluZyBzb21ld2hlcmUgYmV0d2VlbiBwaXBlcyBhbmQKLSAqIHN1YnJvdXRpbmVzLiBMaWtlIGNhbGwvcmV0dXJuLCB0aGVyZSBpcyBhbiBleHBsaWNpdCBmbG93IG9mIGNvbnRyb2wKLSAqIGZyb20gb25lIGNvcm91dGluZSB0byBhbm90aGVyLiBMaWtlIHBpcGVzLCBuZWl0aGVyIGNvcm91dGluZSBpcwotICogYWN0dWFsbHkgImluIGNoYXJnZSIsIGFuZCBuZWl0aGVyIG11c3QgZXhpdCBpbiBvcmRlciB0byB0cmFuc2ZlcgotICogY29udHJvbCB0byB0aGUgb3RoZXIuIDwvcD4KLSAqIAotICogPHA+T25lIGNsYXNzaWMgYXBwbGljYXRpb24gb2YgY29yb3V0aW5lcyBpcyBpbiBjb21waWxlcnMsIHdoZXJlIGJvdGgKLSAqIHRoZSBwYXJzZXIgYW5kIHRoZSBsZXhlciBhcmUgbWFpbnRhaW5pbmcgY29tcGxleCBzdGF0ZQotICogaW5mb3JtYXRpb24uIFRoZSBwYXJzZXIgcmVzdW1lcyB0aGUgbGV4ZXIgdG8gcHJvY2VzcyBpbmNvbWluZwotICogY2hhcmFjdGVycyBpbnRvIGxleGljYWwgdG9rZW5zLCBhbmQgdGhlIGxleGVyIHJlc3VtZXMgdGhlIHBhcnNlcgotICogd2hlbiBpdCBoYXMgcmVhY2hlZCBhIHBvaW50IGF0IHdoaWNoIGl0IGhhcyBhIHJlbGlhYmx5IGludGVycHJldGVkCi0gKiBzZXQgb2YgdG9rZW5zIGF2YWlsYWJsZSBmb3Igc2VtYW50aWMgcHJvY2Vzc2luZy4gU3RydWN0dXJpbmcgdGhpcwotICogYXMgY2FsbC1hbmQtcmV0dXJuIHdvdWxkIHJlcXVpcmUgc2F2aW5nIGFuZCByZXN0b3JpbmcgYQotICogY29uc2lkZXJhYmxlIGFtb3VudCBvZiBzdGF0ZSBlYWNoIHRpbWUuIFN0cnVjdHVyaW5nIGl0IGFzIHR3byB0YXNrcwotICogY29ubmVjdGVkIGJ5IGEgcXVldWUgbWF5IGludm9sdmUgaGlnaGVyIG92ZXJoZWFkIChpbiBzeXN0ZW1zIHdoaWNoCi0gKiBjYW4gb3B0aW1pemUgdGhlIGNvcm91dGluZSBtZXRhcGhvciksIGlzbid0IG5lY2Vzc2FyaWx5IGFzIGNsZWFyIGluCi0gKiBpbnRlbnQsIG1heSBoYXZlIHRyb3VibGUgaGFuZGxpbmcgY2FzZXMgd2hlcmUgZGF0YSBmbG93cyBpbiBib3RoCi0gKiBkaXJlY3Rpb25zLCBhbmQgbWF5IG5vdCBoYW5kbGUgc29tZSBvZiB0aGUgbW9yZSBjb21wbGV4IGNhc2VzIHdoZXJlCi0gKiBtb3JlIHRoYW4gdHdvIGNvcm91dGluZXMgYXJlIGludm9sdmVkLjwvcD4KLSAqIAotICogPHA+TW9zdCBjb3JvdXRpbmUgc3lzdGVtcyBhbHNvIHByb3ZpZGUgYSB3YXkgdG8gcGFzcyBkYXRhIGJldHdlZW4gdGhlCi0gKiBzb3VyY2UgYW5kIHRhcmdldCBvZiBhIHJlc3VtZSBvcGVyYXRpb247IHRoaXMgaXMgc29tZXRpbWVzIHJlZmVycmVkCi0gKiB0byBhcyAieWllbGRpbmciIGEgdmFsdWUuICBPdGhlcnMgcmVseSBvbiB0aGUgZmFjdCB0aGF0LCBzaW5jZSBvbmx5Ci0gKiBvbmUgbWVtYmVyIG9mIGEgY29yb3V0aW5lIHNldCBpcyBydW5uaW5nIGF0IGEgdGltZSBhbmQgZG9lcyBub3QKLSAqIGxvc2UgY29udHJvbCB1bnRpbCBpdCBjaG9vc2VzIHRvIGRvIHNvLCBkYXRhIHN0cnVjdHVyZXMgbWF5IGJlCi0gKiBkaXJlY3RseSBzaGFyZWQgYmV0d2VlbiB0aGVtIHdpdGggb25seSBtaW5pbWFsIHByZWNhdXRpb25zLjwvcD4KLSAqIAotICogPHA+Ik5vdGU6IFRoaXMgc2hvdWxkIG5vdCBiZSB0YWtlbiB0byBtZWFuIHRoYXQgcHJvZHVjZXIvY29uc3VtZXIKLSAqIHByb2JsZW1zIHNob3VsZCBiZSBhbHdheXMgYmUgZG9uZSB3aXRoIGNvcm91dGluZXMuIiBRdWV1ZWluZyBpcwotICogb2Z0ZW4gYSBiZXR0ZXIgc29sdXRpb24gd2hlbiBvbmx5IHR3byB0aHJlYWRzIG9mIGV4ZWN1dGlvbiBhcmUKLSAqIGludm9sdmVkIGFuZCBmdWxsIHR3by13YXkgaGFuZHNoYWtpbmcgaXMgbm90IHJlcXVpcmVkLiBJdCdzIGEgYml0Ci0gKiBkaWZmaWN1bHQgdG8gZmluZCBzaG9ydCBwZWRhZ29naWNhbCBleGFtcGxlcyB0aGF0IHJlcXVpcmUKLSAqIGNvcm91dGluZXMgZm9yIGEgY2xlYXIgc29sdXRpb24uPC9wPgotICogCi0gKiA8cD5UaGUgZmFjdCB0aGF0IG9ubHkgb25lIG9mIGEgZ3JvdXAgb2YgY29yb3V0aW5lcyBpcyBydW5uaW5nIGF0IGEKLSAqIHRpbWUsIGFuZCB0aGUgY29udHJvbCB0cmFuc2ZlciBiZXR3ZWVuIHRoZW0gaXMgZXhwbGljaXQsIHNpbXBsaWZpZXMKLSAqIHRoZWlyIHBvc3NpYmxlIGludGVyYWN0aW9ucywgYW5kIGluIHNvbWUgaW1wbGVtZW50YXRpb25zIHBlcm1pdHMKLSAqIHRoZW0gdG8gYmUgaW1wbGVtZW50ZWQgbW9yZSBlZmZpY2llbnRseSB0aGFuIGdlbmVyYWwgbXVsdGl0YXNraW5nLgotICogSW4gc29tZSBzaXR1YXRpb25zLCBjb3JvdXRpbmVzIGNhbiBiZSBjb21waWxlZCBvdXQgZW50aXJlbHk7Ci0gKiBpbiBvdGhlcnMsIHRoZXkgbWF5IG9ubHkgcmVxdWlyZSBhIGZldyBpbnN0cnVjdGlvbnMgbW9yZSB0aGFuIGEKLSAqIHNpbXBsZSBmdW5jdGlvbiBjYWxsLjwvcD4KLSAqCi0gKiA8cD5UaGlzIHZlcnNpb24gaXMgYnVpbHQgb24gdG9wIG9mIHN0YW5kYXJkIEphdmEgdGhyZWFkaW5nLCBzaW5jZQotICogdGhhdCdzIGFsbCB3ZSBoYXZlIGF2YWlsYWJsZSByaWdodCBub3cuIEl0J3MgYmVlbiBlbmNhcHN1bGF0ZWQgZm9yCi0gKiBjb2RlIGNsYXJpdHkgYW5kIHBvc3NpYmxlIGZ1dHVyZSBvcHRpbWl6YXRpb24uPC9wPgotICogCi0gKiA8cD4oVHdvIHBvc3NpYmxlIGFwcHJvYWNoZXM6IHdhaXQtbm90aWZ5IGJhc2VkIGFuZCBxdWV1ZS1iYXNlZC4gU29tZQotICogZm9sa3MgdGhpbmsgdGhhdCBhIG9uZS1pdGVtIHF1ZXVlIGlzIGEgY2xlYW5lciBzb2x1dGlvbiBiZWNhdXNlIGl0J3MKLSAqIG1vcmUgYWJzdHJhY3QgLS0gYnV0IHNpbmNlIGNvcm91dGluZSBfaXNfIGFuIGFic3RyYWN0aW9uIEknbSBub3QgcmVhbGx5Ci0gKiB3b3JyaWVkIGFib3V0IHRoYXQ7IGZvbGtzIHNob3VsZCBiZSBhYmxlIHRvIHN3aXRjaCB0aGlzIGNvZGUgd2l0aG91dAotICogY29uY2Vybi4pPC9wPgotICogCi0gKiA8cD4lVEJEJSBUSElTIFNIT1VMRCBCRSBBTiBJTlRFUkZBQ0UsIHRvIGZhY2lsaXRhdGUgYnVpbGRpbmcgb3RoZXIKLSAqIGltcGxlbWVudGF0aW9ucy4uLiBwZXJoYXBzIGluY2x1ZGluZyBhIHRydWUgY29yb3V0aW5lIHN5c3RlbQotICogc29tZWRheSwgcmF0aGVyIHRoYW4gY29udHJvbGxlZCB0aHJlYWRpbmcuIEFyZ3VhYmx5IENvcm91dGluZQotICogaXRzZWxmIHNob3VsZCBiZSBhbiBpbnRlcmZhY2UgbXVjaCBsaWtlIFJ1bm5hYmxlLCBidXQgSSB0aGluayB0aGF0Ci0gKiBjYW4gYmUgYnVpbHQgb24gdG9wIG9mIHRoaXMuPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBDb3JvdXRpbmVNYW5hZ2VyCi17Ci0gIC8qKiAiSXMgdGhpcyBjb3JvdXRpbmUgSUQgbnVtYmVyIGFscmVhZHkgaW4gdXNlIiBsb29rdXAgdGFibGUuCi0gICAqIEN1cnJlbnRseSBpbXBsZW1lbnRlZCBhcyBhIGJpdHNldCBhcyBhIGNvbXByb21pc2UgYmV0d2VlbgotICAgKiBjb21wYWN0bmVzcyBhbmQgc3BlZWQgb2YgYWNjZXNzLCBidXQgb2J2aW91c2x5IG90aGVyIHNvbHV0aW9ucwotICAgKiBjb3VsZCBiZSBhcHBsaWVkLgotICAgKiAqLwotICBCaXRTZXQgbV9hY3RpdmVJRHM9bmV3IEJpdFNldCgpOwotCi0gIC8qKiBMaW1pdCBvbiB0aGUgY29yb3V0aW5lIElEIG51bWJlcnMgYWNjZXB0ZWQuIEkgZGlkbid0IHdhbnQgdGhlCi0gICAqIGluLXVzZSB0YWJsZSB0byBncm93IHdpdGhvdXQgYm91bmQuIElmIHdlIHN3aXRjaCB0byBhIG1vcmUgZWZmaWNpZW50Ci0gICAqIHNwYXJzZS1hcnJheSBtZWNoYW5pc20sIGl0IG1heSBiZSBwb3NzaWJsZSB0byByYWlzZSBvciBlbGltaW5hdGUKLSAgICogdGhpcyBib3VuZGFyeS4KLSAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgbV91bnJlYXNvbmFibGVJZD0xMDI0OwotCi0gIC8qKiBJbnRlcm5hbCBmaWVsZCB1c2VkIHRvIGhvbGQgdGhlIGRhdGEgYmVpbmcgZXhwbGljaXRseSBwYXNzZWQKLSAgICogZnJvbSBvbmUgY29yb3V0aW5lIHRvIGFub3RoZXIgZHVyaW5nIGEgY29fcmVzdW1lKCkgb3BlcmF0aW9uLgotICAgKiAoT2YgY291cnNlIGltcGxpY2l0IGRhdGEgc2hhcmluZyBtYXkgYWxzbyBvY2N1cjsgb25lIG9mIHRoZSByZWFzb25zCi0gICAqIGZvciB1c2luZyBjb3JvdXRpbmVzIGlzIHRoYXQgeW91J3JlIGd1YXJhbnRlZWQgdGhhdCBub25lIG9mIHRoZQotICAgKiBvdGhlciBjb3JvdXRpbmVzIGluIHlvdXIgc2V0IGFyZSB1c2luZyBzaGFyZWQgc3RydWN0dXJlcyBhdCB0aGUgdGltZQotICAgKiB5b3UgYWNjZXNzIHRoZW0uKQotICAgKgotICAgKiAlUkVWSUVXJSBJdCdzIGJlZW4gcHJvcG9zZWQgdGhhdCB3ZSBiZSBhYmxlIHRvIHBhc3MgdHlwZXMgb2YgZGF0YQotICAgKiBvdGhlciB0aGFuIE9iamVjdCAtLSBtb3JlIHNwZWNpZmljIG9iamVjdCB0eXBlcywgb3IKLSAgICogbGlnaHRlci13ZWlnaHQgcHJpbWl0aXZlcy4gIFRoaXMgd291bGQgc2VlbSB0byBjcmVhdGUgYSBwb3RlbnRpYWwKLSAgICogZXhwbG9zaW9uIG9mICJwYXNzIHggcmVjaWV2ZSB5IGJhY2siIG1ldGhvZHMgKG9yIHJlcXVpcmUKLSAgICogZnJhY3R1cmluZyByZXN1bWUgaW50byB0d28gY2FsbHMsIHJlc3VtZS1vdGhlciBhbmQKLSAgICogd2FpdC10by1iZS1yZXN1bWVkKSwgYW5kIHRoZSB3ZWlnaHQgaXNzdWUgY291bGQgYmUgbWFuYWdlZCBieQotICAgKiByZXVzaW5nIGEgbXV0YWJsZSBidWZmZXIgb2JqZWN0IHRvIGNvbnRhaW4gdGhlIHByaW1pdGl2ZQotICAgKiAocmVtZW1iZXIgdGhhdCBvbmx5IG9uZSBjb3JvdXRpbmUgcnVucyBhdCBhIHRpbWUsIHNvIG9uY2UgdGhlCi0gICAqIGJ1ZmZlcidzIHNldCBpdCB3b24ndCBiZSB3YWxrZWQgb24pLiBUeXBlY2hlY2tpbmcgb2JqZWN0cyBpcwotICAgKiBpbnRlcmVzdGluZyBmcm9tIGEgY29kZS1yb2J1c3RuZXNzIHBvaW50IG9mIHZpZXcsIGJ1dCBpdCdzCi0gICAqIHVuY2xlYXIgd2hldGhlciBpdCBtYWtlcyBzZW5zZSB0byBlbmNhcHN1bGF0ZSB0aGF0IGluIHRoZQotICAgKiBjb3JvdXRpbmUgY29kZSBvciBsZXQgdGhlIGNhbGxlcnMgZG8gaXQsIHNpbmNlIGl0IGRlcGVuZHMgb24gUlRUSQotICAgKiBlaXRoZXIgd2F5LiBSZXN0cmljdGluZyB0aGUgcGFyYW1ldGVycyB0byBvYmplY3RzIGltcGxlbWVudGluZyBhCi0gICAqIHNwZWNpZmljIENvcm91dGluZVBhcmFtZXRlciBpbnRlcmZhY2UgZG9lcyBfbm90XyBzZWVtIHRvIGJlIGEgbmV0Ci0gICAqIHdpbjsgYXBwbGljYXRpb25zIGNhbiBkbyBzbyBpZiB0aGV5IHdhbnQgdmlhIGZyb250LWVuZCBjb2RlLCBidXQKLSAgICogdGhlcmUgc2VlbSB0byBiZSB0b28gbWFueSB1c2UgY2FzZXMgaW52b2x2aW5nIHBhc3NpbmcgYW4gZXhpc3RpbmcKLSAgICogb2JqZWN0IHR5cGUgdGhhdCB5b3UgbWF5IG5vdCBoYXZlIHRoZSBmcmVlZG9tIHRvIGFsdGVyIGFuZCBtYXkKLSAgICogbm90IHdhbnQgdG8gc3BlbmQgdGltZSB3cmFwcGluZyBhbm90aGVyIG9iamVjdCBhcm91bmQuCi0gICAqICovCi0gIE9iamVjdCBtX3lpZWxkPW51bGw7Ci0KLSAgLy8gRXhwb3NlPz8/Ci0gIGZpbmFsIHN0YXRpYyBpbnQgTk9CT0RZPS0xOwotICBmaW5hbCBzdGF0aWMgaW50IEFOWUJPRFk9LTE7Ci0KLSAgLyoqIEludGVybmFsIGZpZWxkIHVzZWQgdG8gY29uZmlybSB0aGF0IHRoZSBjb3JvdXRpbmUgbm93IHdha2luZyB1cCBpcwotICAgKiBpbiBmYWN0IHRoZSBvbmUgd2UgaW50ZW5kZWQgdG8gcmVzdW1lLiBTb21lIHN1Y2ggc2VsZWN0aW9uIG1lY2hhbmlzbQotICAgKiBpcyBuZWVkZWQgd2hlbiBtb3JlIHRoYXQgdHdvIGNvcm91dGluZXMgYXJlIG9wZXJhdGluZyB3aXRoaW4gdGhlIHNhbWUKLSAgICogZ3JvdXAuCi0gICAqLwotICBpbnQgbV9uZXh0Q29yb3V0aW5lPU5PQk9EWTsKLSAgCi0gIC8qKiA8cD5FYWNoIGNvcm91dGluZSBpbiB0aGUgc2V0IG1hbmFnZWQgYnkgYSBzaW5nbGUKLSAgICogQ29yb3V0aW5lTWFuYWdlciBpcyBpZGVudGlmaWVkIGJ5IGEgc21hbGwgcG9zaXRpdmUgaW50ZWdlci4gVGhpcwotICAgKiBicmluZ3MgdXAgdGhlIHF1ZXN0aW9uIG9mIGhvdyB0byBtYW5hZ2UgdGhvc2UgaW50ZWdlcnMgdG8gYXZvaWQKLSAgICogcmV1c2UuLi4gc2luY2UgaWYgdHdvIGNvcm91dGluZXMgdXNlIHRoZSBzYW1lIElEIG51bWJlciwgcmVzdW1pbmcKLSAgICogdGhhdCBJRCBjb3VsZCByZXN1bWUgZWl0aGVyLiBJIGNhbiBzZWUgYXJndW1lbnRzIGZvciBlaXRoZXIKLSAgICogYWxsb3dpbmcgYXBwbGljYXRpb25zIHRvIHNlbGVjdCB0aGVpciBvd24gbnVtYmVycyAodGhleSBtYXkgd2FudAotICAgKiB0byBkZWNsYXJlIG1uZW1vbmljcyB2aWEgbWFuZWZlc3QgY29uc3RhbnRzKSBvciBnZW5lcmF0aW5nCi0gICAqIG51bWJlcnMgb24gZGVtYW5kLiAgVGhpcyByb3V0aW5lJ3MgaW50ZW5kZWQgdG8gc3VwcG9ydCBib3RoCi0gICAqIGFwcHJvYWNoZXMuPC9wPgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBXZSBjb3VsZCB1c2UgYW4gb2JqZWN0IGFzIHRoZSBpZGVudGlmaWVyLiBOb3Qgc3VyZQotICAgKiBpdCdzIGEgbmV0IGdhaW4sIHRob3VnaCBpdCB3b3VsZCBhbGxvdyB0aGUgdGhyZWFkIHRvIGJlIGl0cyBvd24KLSAgICogSUQuIFBvbmRlci48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjb3JvdXRpbmVJRDogSWYgPj0wLCByZXF1ZXN0cyB0aGF0IHdlIHJlc2VydmUgdGhpcyBudW1iZXIuCi0gICAqIElmIDwwLCByZXF1ZXN0cyB0aGF0IHdlIGZpbmQsIHJlc2VydmUsIGFuZCByZXR1cm4gYW4gYXZhaWxhYmxlIElECi0gICAqIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiBJZiA+PTAsIHRoZSBJRCBudW1iZXIgdG8gYmUgdXNlZCBieSB0aGlzIGNvcm91dGluZS4gSWYgPDAsCi0gICAqIGFuIGVycm9yIG9jY3VycmVkIC0tIHRoZSBJRCByZXF1ZXN0ZWQgd2FzIGFscmVhZHkgaW4gdXNlLCBvciB3ZQotICAgKiBjb3VsZG4ndCBhc3NpZ24gb25lIHdpdGhvdXQgZ29pbmcgb3ZlciB0aGUgInVucmVhc29uYWJsZSB2YWx1ZSIgbWFyawotICAgKiAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIGludCBjb19qb2luQ29yb3V0aW5lU2V0KGludCBjb3JvdXRpbmVJRCkKLSAgewotICAgIGlmKGNvcm91dGluZUlEPj0wKQotICAgICAgewotICAgICAgICBpZihjb3JvdXRpbmVJRD49bV91bnJlYXNvbmFibGVJZCB8fCBtX2FjdGl2ZUlEcy5nZXQoY29yb3V0aW5lSUQpKQotICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgIH0KLSAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIC8vIFdoYXQgSSB3YW50IGlzICJGaW5kIGZpcnN0IGNsZWFyIGJpdCIuIFRoYXQgZG9lc24ndCBleGlzdC4KLSAgICAgICAgLy8gSkRLMS4yIGFkZGVkICJmaW5kIGxhc3Qgc2V0IGJpdCIsIGJ1dCB0aGF0IGRvZXNuJ3QgaGVscCBub3cuCi0gICAgICAgIGNvcm91dGluZUlEPTA7Ci0gICAgICAgIHdoaWxlKGNvcm91dGluZUlEPG1fdW5yZWFzb25hYmxlSWQpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYobV9hY3RpdmVJRHMuZ2V0KGNvcm91dGluZUlEKSkKLSAgICAgICAgICAgICAgKytjb3JvdXRpbmVJRDsKLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotICAgICAgICBpZihjb3JvdXRpbmVJRD49bV91bnJlYXNvbmFibGVJZCkKLSAgICAgICAgICByZXR1cm4gLTE7Ci0gICAgICB9Ci0KLSAgICBtX2FjdGl2ZUlEcy5zZXQoY29yb3V0aW5lSUQpOwotICAgIHJldHVybiBjb3JvdXRpbmVJRDsKLSAgfQotCi0gIC8qKiBJbiB0aGUgc3RhbmRhcmQgY29yb3V0aW5lIGFyY2hpdGVjdHVyZSwgY29yb3V0aW5lcyBhcmUKLSAgICogaWRlbnRpZmllZCBieSB0aGVpciBtZXRob2QgbmFtZXMgYW5kIGFyZSBsYXVuY2hlZCBhbmQgcnVuIHVwIHRvCi0gICAqIHRoZWlyIGZpcnN0IHlpZWxkIGJ5IHNpbXBseSByZXN1bWluZyB0aGVtOyBpdHMncyBwcmVzdW1lZCB0aGF0Ci0gICAqIHRoaXMgcmVjb2duaXplcyB0aGUgbm90LWFscmVhZHktcnVubmluZyBjYXNlIGFuZCBkb2VzIHRoZSByaWdodAotICAgKiB0aGluZy4gV2Ugc2VlbSB0byBuZWVkIGEgd2F5IHRvIGFjaGlldmUgdGhhdCBzYW1lIHRocmVhZHNhZmUKLSAgICogcnVuLXVwLi4uICBlZywgc3RhcnQgdGhlIGNvcm91dGluZSB3aXRoIGEgd2FpdC4KLSAgICoKLSAgICogJVRCRCUgd2hldGhlciB0aGlzIG1ha2VzIGFueSBzZW5zZS4uLgotICAgKgotICAgKiBAcGFyYW0gdGhpc0Nvcm91dGluZSB0aGUgaWRlbnRpZmllciBvZiB0aGlzIGNvcm91dGluZSwgc28gd2UgY2FuCi0gICAqIHJlY29nbml6ZSB3aGVuIHdlIGFyZSBiZWluZyByZXN1bWVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5Ob1N1Y2hNZXRob2RFeGNlcHRpb24gaWYgdGhpc0Nvcm91dGluZSBpc24ndAotICAgKiBhIHJlZ2lzdGVyZWQgbWVtYmVyIG9mIHRoaXMgZ3JvdXAuICVSRVZJRVclIHdoZXRoZXIgdGhpcyBpcyB0aGUKLSAgICogYmVzdCBjaG9pY2UuCi0gICAqICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGNvX2VudHJ5X3BhdXNlKGludCB0aGlzQ29yb3V0aW5lKSB0aHJvd3MgamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoIW1fYWN0aXZlSURzLmdldCh0aGlzQ29yb3V0aW5lKSkKLSAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uKCk7Ci0KLSAgICB3aGlsZShtX25leHRDb3JvdXRpbmUgIT0gdGhpc0Nvcm91dGluZSkKLSAgICAgIHsKLSAgICAgICAgdHJ5IAotICAgICAgICAgIHsKLSAgICAgICAgICAgIHdhaXQoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIGNhdGNoKGphdmEubGFuZy5JbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vICVUQkQlIC0tIERlY2xhcmU/IEVuY2Fwc3VsYXRlPyBJZ25vcmU/IE9yCi0gICAgICAgICAgICAvLyBkYW5jZSB3aWRkZXJzaGlucyBhYm91dCB0aGUgaW5zdHJ1Y3Rpb24gY2FjaGU/Ci0gICAgICAgICAgfQotICAgICAgfQotICAgIAotICAgIHJldHVybiBtX3lpZWxkOwotICB9Ci0KLSAgLyoqIFRyYW5zZmVyIGNvbnRyb2wgdG8gYW5vdGhlciBjb3JvdXRpbmUgd2hpY2ggaGFzIGFscmVhZHkgYmVlbiBzdGFydGVkIGFuZAotICAgKiBpcyB3YWl0aW5nIG9uIHRoaXMgQ29yb3V0aW5lTWFuYWdlci4gV2Ugd29uJ3QgcmV0dXJuIGZyb20gdGhpcyBjYWxsCi0gICAqIHVudGlsIHRoYXQgcm91dGluZSBoYXMgcmVsaW5xdWlzaGVkIGNvbnRyb2wuCi0gICAqCi0gICAqICVUQkQlIFdoYXQgc2hvdWxkIHdlIGRvIGlmIHRvQ29yb3V0aW5lIGlzbid0IHJlZ2lzdGVyZWQ/IEV4Y2VwdGlvbj8KLSAgICoKLSAgICogQHBhcmFtIGFyZ19vYmplY3QgQSB2YWx1ZSB0byBiZSBwYXNzZWQgdG8gdGhlIG90aGVyIGNvcm91dGluZS4KLSAgICogQHBhcmFtIHRoaXNDb3JvdXRpbmUgSW50ZWdlciBpZGVudGlmaWVyIGZvciB0aGlzIGNvcm91dGluZS4gVGhpcyBpcyB0aGUKLSAgICogSUQgd2Ugd2F0Y2ggZm9yIHRvIHNlZSBpZiB3ZSdyZSB0aGUgb25lcyBiZWluZyByZXN1bWVkLgotICAgKiBAcGFyYW0gdG9Db3JvdXRpbmUuIEludGVnZXIgaWRlbnRpZmllciBmb3IgdGhlIGNvcm91dGluZSB3ZSB3aXNoIHRvCi0gICAqIGludm9rZS4gCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBpZiB0b0Nvcm91dGluZSBpc24ndCBhCi0gICAqIHJlZ2lzdGVyZWQgbWVtYmVyIG9mIHRoaXMgZ3JvdXAuICVSRVZJRVclIHdoZXRoZXIgdGhpcyBpcyB0aGUgYmVzdCBjaG9pY2UuCi0gICAqICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGNvX3Jlc3VtZShPYmplY3QgYXJnX29iamVjdCxpbnQgdGhpc0Nvcm91dGluZSxpbnQgdG9Db3JvdXRpbmUpIHRocm93cyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uCi0gIHsKLSAgICBpZighbV9hY3RpdmVJRHMuZ2V0KHRvQ29yb3V0aW5lKSkKLSAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0NPUk9VVElORV9OT1RfQVZBSUwsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKHRvQ29yb3V0aW5lKX0pKTsgLy8iQ29yb3V0aW5lIG5vdCBhdmFpbGFibGUsIGlkPSIrdG9Db3JvdXRpbmUpOwotCi0gICAgLy8gV2UgZXhwZWN0IHRoZXNlIHZhbHVlcyB0byBiZSBvdmVyd3JpdHRlbiBkdXJpbmcgdGhlIG5vdGlmeSgpL3dhaXQoKQotICAgIC8vIHBlcmlvZHMsIGFzIG90aGVyIGNvcm91dGluZXMgaW4gdGhpcyBzZXQgZ2V0IHRoZWlyIG9wcG9ydHVuaXR5IHRvIHJ1bi4KLSAgICBtX3lpZWxkPWFyZ19vYmplY3Q7Ci0gICAgbV9uZXh0Q29yb3V0aW5lPXRvQ29yb3V0aW5lOwotCi0gICAgbm90aWZ5KCk7Ci0gICAgd2hpbGUobV9uZXh0Q29yb3V0aW5lICE9IHRoaXNDb3JvdXRpbmUgfHwgbV9uZXh0Q29yb3V0aW5lPT1BTllCT0RZIHx8IG1fbmV4dENvcm91dGluZT09Tk9CT0RZKQotICAgICAgewotICAgICAgICB0cnkgCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJ3YWl0aW5nLi4uIik7Ci0gICAgICAgICAgICB3YWl0KCk7Ci0gICAgICAgICAgfQotICAgICAgICBjYXRjaChqYXZhLmxhbmcuSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyAlVEJEJSAtLSBEZWNsYXJlPyBFbmNhcHN1bGF0ZT8gSWdub3JlPyBPcgotICAgICAgICAgICAgLy8gZGFuY2UgZGVhc2lsIGFib3V0IHRoZSBwcm9ncmFtIGNvdW50ZXI/Ci0gICAgICAgICAgfQotICAgICAgfQotCi0gICAgaWYobV9uZXh0Q29yb3V0aW5lPT1OT0JPRFkpCi0gICAgICB7Ci0gICAgICAgIC8vIFBhc3MgaXQgYWxvbmcKLSAgICAgICAgY29fZXhpdCh0aGlzQ29yb3V0aW5lKTsKLSAgICAgICAgLy8gQW5kIGluZm9ybSB0aGlzIGNvcm91dGluZSB0aGF0IGl0cyBwYXJ0bmVycyBhcmUgR29pbmcgQXdheQotICAgICAgICAvLyAlUkVWSUVXJSBTaG91bGQgdGhpcyB0aHJvdy9yZXR1cm4gc29tZXRoaW5nIG1vcmUgdXNlZnVsPwotICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1JPVVRJTkVfQ09fRVhJVCwgbnVsbCkpOyAvLyJDb3JvdXRpbmVNYW5hZ2VyIHJlY2lldmVkIGNvX2V4aXQoKSByZXF1ZXN0Iik7Ci0gICAgICB9Ci0gICAgCi0gICAgcmV0dXJuIG1feWllbGQ7Ci0gIH0KLSAgCi0gIC8qKiBUZXJtaW5hdGUgdGhpcyBlbnRpcmUgc2V0IG9mIGNvcm91dGluZXMuIFRoZSBvdGhlcnMgd2lsbCBiZQotICAgKiBkZXJlZ2lzdGVyZWQgYW5kIGhhdmUgZXhjZXB0aW9ucyB0aHJvd24gYXQgdGhlbS4gTm90ZSB0aGF0IHRoaXMKLSAgICogaXMgaW50ZW5kZWQgYXMgYSBwYW5pYy1zaHV0ZG93biBvcGVyYXRpb247IHVuZGVyIG5vcm1hbAotICAgKiBjaXJjdW1zdGFuY2VzIGEgY29yb3V0aW5lIHNob3VsZCBhbHdheXMgZW5kIHdpdGggY29fZXhpdF90bygpIGluCi0gICAqIG9yZGVyIHRvIHBvbGl0ZWx5IGluZm9ybSBhdCBsZWFzdCBvbmUgb2YgaXRzIHBhcnRuZXJzIHRoYXQgaXQgaXMKLSAgICogZ29pbmcgYXdheS4KLSAgICoKLSAgICogJVRCRCUgVGhpcyBtYXkgbmVlZCBzaWduaWZpY2FudGx5IG1vcmUgd29yay4gCi0gICAqCi0gICAqICVUQkQlIFNob3VsZCB0aGlzIGp1c3QgYmUgY29fZXhpdF90bygsLENvcm91dGluZU1hbmFnZXIuUEFOSUMpPwotICAgKgotICAgKiBAcGFyYW0gdGhpc0Nvcm91dGluZSBJbnRlZ2VyIGlkZW50aWZpZXIgZm9yIHRoZSBjb3JvdXRpbmUgcmVxdWVzdGluZyBleGl0LgotICAgKiAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29fZXhpdChpbnQgdGhpc0Nvcm91dGluZSkKLSAgewotICAgIG1fYWN0aXZlSURzLmNsZWFyKHRoaXNDb3JvdXRpbmUpOwotICAgIG1fbmV4dENvcm91dGluZT1OT0JPRFk7IC8vICVSRVZJRVclCi0gICAgbm90aWZ5KCk7Ci0gIH0KLQotICAvKiogTWFrZSB0aGUgSUQgYXZhaWxhYmxlIGZvciByZXVzZSBhbmQgdGVybWluYXRlIHRoaXMgY29yb3V0aW5lLAotICAgKiB0cmFuc2ZlcnJpbmcgY29udHJvbCB0byB0aGUgc3BlY2lmaWVkIGNvcm91dGluZS4gTm90ZSB0aGF0IHRoaXMKLSAgICogcmV0dXJucyBpbW1lZGlhdGVseSByYXRoZXIgdGhhbiB3YWl0aW5nIGZvciBhbnkgZnVydGhlciBjb3JvdXRpbmUKLSAgICogdHJhZmZpYywgc28gdGhlIHRocmVhZCBjYW4gcHJvY2VlZCB3aXRoIG90aGVyIHNodXRkb3duIGFjdGl2aXRpZXMuCi0gICAqCi0gICAqIEBwYXJhbSBhcmdfb2JqZWN0IEEgdmFsdWUgdG8gYmUgcGFzc2VkIHRvIHRoZSBvdGhlciBjb3JvdXRpbmUuCi0gICAqIEBwYXJhbSB0aGlzQ29yb3V0aW5lIEludGVnZXIgaWRlbnRpZmllciBmb3IgdGhlIGNvcm91dGluZSBsZWF2aW5nIHRoZSBzZXQuCi0gICAqIEBwYXJhbSB0b0Nvcm91dGluZS4gSW50ZWdlciBpZGVudGlmaWVyIGZvciB0aGUgY29yb3V0aW5lIHdlIHdpc2ggdG8KLSAgICogaW52b2tlLiAKLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlmIHRvQ29yb3V0aW5lIGlzbid0IGEKLSAgICogcmVnaXN0ZXJlZCBtZW1iZXIgb2YgdGhpcyBncm91cC4gJVJFVklFVyUgd2hldGhlciB0aGlzIGlzIHRoZSBiZXN0IGNob2ljZS4KLSAgICogKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNvX2V4aXRfdG8oT2JqZWN0IGFyZ19vYmplY3QsaW50IHRoaXNDb3JvdXRpbmUsaW50IHRvQ29yb3V0aW5lKSB0aHJvd3MgamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoIW1fYWN0aXZlSURzLmdldCh0b0Nvcm91dGluZSkpCi0gICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1JPVVRJTkVfTk9UX0FWQUlMLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyh0b0Nvcm91dGluZSl9KSk7IC8vIkNvcm91dGluZSBub3QgYXZhaWxhYmxlLCBpZD0iK3RvQ29yb3V0aW5lKTsKLSAgICAKLSAgICAvLyBXZSBleHBlY3QgdGhlc2UgdmFsdWVzIHRvIGJlIG92ZXJ3cml0dGVuIGR1cmluZyB0aGUgbm90aWZ5KCkvd2FpdCgpCi0gICAgLy8gcGVyaW9kcywgYXMgb3RoZXIgY29yb3V0aW5lcyBpbiB0aGlzIHNldCBnZXQgdGhlaXIgb3Bwb3J0dW5pdHkgdG8gcnVuLgotICAgIG1feWllbGQ9YXJnX29iamVjdDsKLSAgICBtX25leHRDb3JvdXRpbmU9dG9Db3JvdXRpbmU7Ci0KLSAgICBtX2FjdGl2ZUlEcy5jbGVhcih0aGlzQ29yb3V0aW5lKTsKLQotICAgIG5vdGlmeSgpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Db3JvdXRpbmVQYXJzZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ODJhMTc5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSwyMDAwIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLQotLyoqIDxwPkNvcm91dGluZVBhcnNlciBpcyBhbiBBUEkgZm9yIHBhcnNlciB0aHJlYWRzIHRoYXQgb3BlcmF0ZSBhcwotICogY29yb3V0aW5lcy4gU2VlIENvcm91dGluZVNBWFBhcnNlciBhbmQgQ29yb3V0aW5lU0FYUGFyc2VyX1hlcmNlcwotICogZm9yIGV4YW1wbGVzLjwvcD4KLSAqCi0gKiA8cD4mbHQ7Z3J1bWJsZSZndDsgSSdkIGxpa2UgdGhlIGludGVyZmFjZSB0byByZXF1aXJlIGEgc3BlY2lmaWMgZm9ybQotICogZm9yIGVpdGhlciB0aGUgYmFzZSBjb25zdHJ1Y3RvciBvciBhIHN0YXRpYyBmYWN0b3J5IG1ldGhvZC4gSmF2YQotICogZG9lc24ndCBhbGxvdyB1cyB0byBzcGVjaWZ5IGVpdGhlciwgc28gSSdsbCBqdXN0IGRvY3VtZW50IHRoZW0KLSAqIGhlcmU6Ci0gKgotICogPHVsPgotICogPGxpPnB1YmxpYyBDb3JvdXRpbmVQYXJzZXIoQ29yb3V0aW5lTWFuYWdlciBjbywgaW50IGFwcENvcm91dGluZSk7PC9saT4KLSAqIDxsaT5wdWJsaWMgQ29yb3V0aW5lUGFyc2VyIGNyZWF0ZUNvcm91dGluZVBhcnNlcihDb3JvdXRpbmVNYW5hZ2VyIGNvLCBpbnQgYXBwQ29yb3V0aW5lKTs8L2xpPgotICogPC91bD4KLSAqCi0gKiAmbHQ7L2dydW1ibGUmZ3Q7PC9wPgotICoKLSAqIEBkZXByZWNhdGVkIFNpbmNlIHRoZSBhYmlsaXR5IHRvIHN0YXJ0IGEgcGFyc2UgdmlhIHRoZQotICogY29yb3V0aW5lIHByb3RvY29sIHdhcyBub3QgYmVpbmcgdXNlZCBhbmQgd2FzIGNvbXBsaWNhdGluZyBkZXNpZ24uCi0gKiBTZWUge0BsaW5rIEluY3JlbWVudGFsU0FYU291cmNlfS4KLSAqICovCi1wdWJsaWMgaW50ZXJmYWNlIENvcm91dGluZVBhcnNlciB7Ci0KLSAgICAvKiogQHJldHVybiB0aGUgY29yb3V0aW5lIElEIG51bWJlciBmb3IgdGhpcyBDb3JvdXRpbmVQYXJzZXIgb2JqZWN0LgotICAgICAqIE5vdGUgdGhhdCB0aGlzIGlzbid0IHVzZWZ1bCB1bmxlc3MgeW91IGtub3cgd2hpY2ggQ29yb3V0aW5lTWFuYWdlcgotICAgICAqIHlvdSdyZSB0YWxraW5nIHRvLiBBbHNvIG5vdGUgdGhhdCB0aGUgZG8uLi4oKSBtZXRob2RzIGVuY2Fwc3VsYXRlCi0gICAgICogdGhlIGNvbW1vbiB0cmFuc2FjdGlvbnMgd2l0aCB0aGUgQ29yb3V0aW5lUGFyc2VyLCBzbyB5b3Ugc2hvdWxkbid0Ci0gICAgICogbmVlZCB0aGlzIGluIG1vc3QgY2FzZXMuCi0gICAgICogKi8KLSAgICBwdWJsaWMgaW50IGdldFBhcnNlckNvcm91dGluZUlEKCk7Ci0KLSAgICAvKiogQHJldHVybiB0aGUgQ29yb3V0aW5lTWFuYWdlciBmb3IgdGhpcyBDb3JvdXRpbmVQYXJzZXIgb2JqZWN0LgotICAgICAqIElmIHlvdSdyZSB1c2luZyB0aGUgZG8uLi4oKSBtZXRob2RzLCBhcHBsaWNhdGlvbnMgc2hvdWxkIG9ubHkKLSAgICAgKiBuZWVkIHRvIHRhbGsgdG8gdGhlIENvcm91dGluZU1hbmFnZXIgb25jZSwgdG8gb2J0YWluIHRoZQotICAgICAqIGFwcGxpY2F0aW9uJ3MgQ29yb3V0aW5lIElELgotICAgICAqICovCi0gICAgcHVibGljIENvcm91dGluZU1hbmFnZXIgZ2V0Q29yb3V0aW5lTWFuYWdlcigpOwotCi0gIC8qKiBSZWdpc3RlciBhIFNBWC1zdHlsZSBjb250ZW50IGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0byAqLwotICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlciBoYW5kbGVyKTsKLQotICAvKiogIFJlZ2lzdGVyIGEgU0FYLXN0eWxlIGxleGljYWwgaGFuZGxlciBmb3IgdXMgdG8gb3V0cHV0IHRvCi0gICAqICBOb3QgYWxsIHBhcnNlcnMgc3VwcG9ydCB0aGlzLi4uCi0gICAqCi0gICAqICVSRVZJRVclIE5vdCBjYWxsZWQgc2V0TGV4aWNhbEhhbmRsZXIgYmVjYXVzZSBYYWxhbiB1c2VzIHRoYXQgbmFtZQotICAgKiBpbnRlcm5hbGx5LCB3aGljaCBjYXVzZXMgc3ViY2xhc3NpbmcgbnVpc2FuY2VzLiAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExleEhhbmRsZXIob3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGhhbmRsZXIpOwotCi0gIC8qIFRoZSBydW4oKSBtZXRob2QgaXMgcmVxdWlyZWQgaW4gQ29yb3V0aW5lUGFyc2VycyB0aGF0IHJ1biBhcwotICAgKiB0aHJlYWRzIChvZiBjb3Vyc2UpLi4uIGJ1dCBpdCBpc24ndCBwYXJ0IG9mIG91ciBBUEksIGFuZAotICAgKiBzaG91bGRuJ3QgYmUgZGVjbGFyZWQgaGVyZS4KLSAgICogKi8KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLyoqIGRvUGFyc2UoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIGNvcm91dGluZSBwYXJzZXIKLSAgICogdG8gYmVnaW4gcmVhZGluZyBmcm9tIGEgZmlsZS4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkIGZyb20gb25lCi0gICAqIG9mIG91ciBwYXJ0bmVyIGNvcm91dGluZXMsIGFuZCBzZXJ2ZXMgYm90aCB0byBlbmNhcHN1bGF0ZSB0aGUKLSAgICogY29tbXVuaWNhdGlvbiBwcm90b2NvbCBhbmQgdG8gYXZvaWQgaGF2aW5nIHRvIGV4cGxpY2l0bHkgdXNlIHRoZQotICAgKiBDb3JvdXRpbmVQYXJzZXIncyBjb3JvdXRpbmUgSUQgbnVtYmVyLgotICAgKgotICAgKiAlUkVWSUVXJSBDYW4vc2hvdWxkIHRoaXMgdW5pZnkgd2l0aCBkb01vcmU/IChpZiBVUkkgaGFzbid0IGNoYW5nZWQsCi0gICAqIHBhcnNlIG1vcmUgZnJvbSBzYW1lIGZpbGUsIGVsc2UgZW5kIGFuZCByZXN0YXJ0IHBhcnNpbmcuLi4/Ci0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIElucHV0U291cmNlIHRvIHBhcnNlIGZyb20uCi0gICAqIEBwYXJhbSBhcHBDb3JvdXRpbmUgVGhlIGNvcm91dGluZSBJRCBudW1iZXIgb2YgdGhlIGNvcm91dGluZSBpbnZva2luZwotICAgKiB0aGlzIG1ldGhvZCwgc28gaXQgY2FuIGJlIHJlc3VtZWQgYWZ0ZXIgdGhlIHBhcnNlciBoYXMgcmVzcG9uZGVkIHRvIHRoZQotICAgKiByZXF1ZXN0LgotICAgKiBAcmV0dXJuIEJvb2xlYW4uVFJVRSBpZiB0aGUgQ29yb3V0aW5lUGFyc2VyIGJlbGlldmVzIG1vcmUgZGF0YSBtYXkgYmUgYXZhaWxhYmxlCi0gICAqIGZvciBmdXJ0aGVyIHBhcnNpbmcuIEJvb2xlYW4uRkFMU0UgaWYgcGFyc2luZyByYW4gdG8gY29tcGxldGlvbi4KLSAgICogRXhjZXB0aW9uIGlmIHRoZSBwYXJzZXIgb2JqZWN0ZWQgZm9yIHNvbWUgcmVhc29uLgotICAgKiAqLwotICBwdWJsaWMgT2JqZWN0IGRvUGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlLCBpbnQgYXBwQ29yb3V0aW5lKTsKLQotICAvKiogZG9Nb3JlKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBjb3JvdXRpbmUgcGFyc2VyCi0gICAqIHRoYXQgd2UgbmVlZCBtb3JlIG5vZGVzLiAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgZnJvbSBvbmUKLSAgICogb2Ygb3VyIHBhcnRuZXIgY29yb3V0aW5lcywgYW5kIHNlcnZlcyBib3RoIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBjb21tdW5pY2F0aW9uIHByb3RvY29sIGFuZCB0byBhdm9pZCBoYXZpbmcgdG8gZXhwbGljaXRseSB1c2UgdGhlCi0gICAqIENvcm91dGluZVBhcnNlcidzIGNvcm91dGluZSBJRCBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBwYXJzZW1vcmUgSWYgdHJ1ZSwgdGVsbHMgdGhlIGluY3JlbWVudGFsIHBhcnNlciB0byBnZW5lcmF0ZQotICAgKiBhbm90aGVyIGNodW5rIG9mIG91dHB1dC4gSWYgZmFsc2UsIHRlbGxzIHRoZSBwYXJzZXIgdGhhdCB3ZSdyZQotICAgKiBzYXRpc2ZpZWQgYW5kIGl0IGNhbiB0ZXJtaW5hdGUgcGFyc2luZyBvZiB0aGlzIGRvY3VtZW50LgotICAgKiBAcGFyYW0gYXBwQ29yb3V0aW5lIFRoZSBjb3JvdXRpbmUgSUQgbnVtYmVyIG9mIHRoZSBjb3JvdXRpbmUgaW52b2tpbmcKLSAgICogdGhpcyBtZXRob2QsIHNvIGl0IGNhbiBiZSByZXN1bWVkIGFmdGVyIHRoZSBwYXJzZXIgaGFzIHJlc3BvbmRlZCB0byB0aGUKLSAgICogcmVxdWVzdC4KLSAgICogQHJldHVybiBCb29sZWFuLlRSVUUgaWYgdGhlIENvcm91dGluZVBhcnNlciBiZWxpZXZlcyBtb3JlIGRhdGEgbWF5IGJlIGF2YWlsYWJsZQotICAgKiBmb3IgZnVydGhlciBwYXJzaW5nLiBCb29sZWFuLkZBTFNFIGlmIHBhcnNpbmcgcmFuIHRvIGNvbXBsZXRpb24uCi0gICAqIEV4Y2VwdGlvbiBpZiB0aGUgcGFyc2VyIG9iamVjdGVkIGZvciBzb21lIHJlYXNvbi4KLSAgICogKi8KLSAgcHVibGljIE9iamVjdCBkb01vcmUgKGJvb2xlYW4gcGFyc2Vtb3JlLCBpbnQgYXBwQ29yb3V0aW5lKTsKLQotICAvKiogZG9UZXJtaW5hdGUoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIGNvcm91dGluZQotICAgKiBwYXJzZXIgdG8gdGVybWluYXRlIGl0c2VsZi4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkIGZyb20KLSAgICogb25lIG9mIG91ciBwYXJ0bmVyIGNvcm91dGluZXMsIGFuZCBzZXJ2ZXMgYm90aCB0byBlbmNhcHN1bGF0ZSB0aGUKLSAgICogY29tbXVuaWNhdGlvbiBwcm90b2NvbCBhbmQgdG8gYXZvaWQgaGF2aW5nIHRvIGV4cGxpY2l0bHkgdXNlIHRoZQotICAgKiBDb3JvdXRpbmVQYXJzZXIncyBjb3JvdXRpbmUgSUQgbnVtYmVyLgotICAgKgotICAgKiBSZXR1cm5zIG9ubHkgYWZ0ZXIgdGhlIENvcm91dGluZVBhcnNlciBoYXMgYWNrbm93bGVkZ2VkIHRoZSByZXF1ZXN0LgotICAgKgotICAgKiBAcGFyYW0gYXBwQ29yb3V0aW5lIFRoZSBjb3JvdXRpbmUgSUQgbnVtYmVyIG9mIHRoZSBjb3JvdXRpbmUgaW52b2tpbmcKLSAgICogdGhpcyBtZXRob2QsIHNvIGl0IGNhbiBiZSByZXN1bWVkIGFmdGVyIHRoZSBwYXJzZXIgaGFzIHJlc3BvbmRlZCB0byB0aGUKLSAgICogcmVxdWVzdC4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgZG9UZXJtaW5hdGUoaW50IGFwcENvcm91dGluZSk7Ci0KLQotICAgIC8qKgotICAgICAqICBJbml0aWFsaXplIHRoZSBjb3JvdXRpbmUgcGFyc2VyLiBTYW1lIHBhcmFtZXRlcnMgY291bGQgYmUgcGFzc2VkCi0gICAgICogIGluIGEgbm9uLWRlZmF1bHQgY29uc3RydWN0b3IsIG9yIGJ5IHVzaW5nIHVzaW5nIENsYXNzLmZvck5hbWUgYW5kCi0gICAgICogIG5ld0luc3RhbmNlIGFuZCB0aGVuIGNhbGxpbmcgaW5pdCgpCi0gICAgICovCi0gIHB1YmxpYyB2b2lkIGluaXQoIENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmVJRCwgWE1MUmVhZGVyIHBhcnNlciApOwotCi19IC8vIGNsYXNzIENvcm91dGluZVBhcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvQ29yb3V0aW5lU0FYRmlsdGVyVGVzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvQ29yb3V0aW5lU0FYRmlsdGVyVGVzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZGMwZDg1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVNBWEZpbHRlclRlc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0OSArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwotCi0vKiogUHJpbWl0aXZlIHVuaXQgdGVzdCBmb3IgQ29yb3V0aW5lU0FYUGFyc2VyIGluIGZpbHRlcmluZyBtb2RlOgotICogQXR0ZW1wdCBjb3JvdXRpbmUgcGFyc2luZyBvZiBkb2N1bWVudHMgaW5kaWNhdGVkIGJ5IGFyZ3VtZW50cyAoYXMKLSAqIFVSSXMpLCByZXBvcnQgcHJvZ3Jlc3MuIElmIGEgVVJJIGlzIGZvbGxvd2VkIGJ5ICIhIiBhcyB0aGUgbmV4dAotICogYXJndW1lbnQsIHdlIGNhbmNlbCB0aGUgcGFyc2UgZWFybHkuCi0gKgotICogVGhpcyB2ZXJzaW9uIHRlc3RzIHRoZSBmaWx0ZXJpbmcgbW9kZSwgd2hlcmUgdGhlIENvcm91dGluZVBhcnNlcgotICogaXMgbWFuYWdpbmcgYSBTQVggc3RyZWFtIGdlbmVyYXRlZCBieSBvdGhlciBjb2RlLiBOb3JtYWxseSB0aGlzCi0gKiB3b3VsZCBiZSB1c2VkIHdoZW4geW91J3ZlIGxhdW5jaGVkIHRoZSBjb25zdW1lciBpbiBhIHNlY29uZGFyeQotICogdGhyZWFkIGFuZCBhcmUgcnVubmluZyB0aGUgU0FYIGV2ZW50IGdlbmVyYXRpb24gaW4gdGhlIHByaW1hcnkKLSAqIHRocmVhZC4gT2YgY291cnNlIGl0IGNvdWxkIGJlIHVzZWQgdGhlIG90aGVyIHdheSByb3VuZCBhcyB3ZWxsLgotICoKLSAqIE5vdGUgdGhhdCB1bmxpa2UgdGhlIGZ1bGx5LWVuY2Fwc3VsYXRlZCB2ZXJzaW9uIChzZWUgdGhlIGlubGluZQotICogdGVzdCBpbiBDb3JvdXRpbmVTQVhQYXJzZXIpLCB0aGlzIHZlcnNpb24gZG9lcyBfbm90XyBoYXZlIGEKLSAqIGRpYWxvZyBmb3Igc3RhcnRpbmcgdGhlIHBhcnNlLCBvciBmb3IgcmVzdGFydGluZyBpdCB3aXRoIGEgbmV3Ci0gKiBmaWxlLgotICogKi8KLWNsYXNzIENvcm91dGluZVNBWEZpbHRlclRlc3QgaW1wbGVtZW50cyBSdW5uYWJsZQotewotICAvLyBTdGF0aWNzIGFyZSBhIHNsb3BweSB3YXkgb2YgcGFzc2luZyBkYXRhIHRvIHRoZSB0ZXN0IHRocmVhZCwKLSAgLy8gYnV0IGZvciB0aGlzIHF1aWNrLWhhY2sgSSBkb24ndCBtdWNoIGNhcmUuCi0gIHN0YXRpYyBib29sZWFuIFRFU1RfRUFSTFlfU1RPUD1mYWxzZTsKLSAgc3RhdGljIGludCBhcHBDb3JvdXRpbmVJRD0tMTsKLSAgc3RhdGljIENvcm91dGluZVNBWFBhcnNlciBmaWx0ZXI7Ci0KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3NbXSkKLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnRpbmcgaW4gRmlsdGVyaW5nIG1vZGUuLi4iKTsKLQotICAgIG9yZy54bWwuc2F4LlhNTFJlYWRlciB0aGVTQVhQYXJzZXI9bnVsbDsKLSAgICB0cnkgewotCVNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeT1TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0JU0FYUGFyc2VyIHBhcnNlcj1mYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotCXRoZVNBWFBhcnNlcj1wYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0gICAgfSBjYXRjaCggRXhjZXB0aW9uIGV4ICkgewotCWV4LnByaW50U3RhY2tUcmFjZSgpOwotCXJldHVybjsKLSAgICB9Ci0gICAgCi0gICAgQ29yb3V0aW5lTWFuYWdlciBjbyA9IG5ldyBDb3JvdXRpbmVNYW5hZ2VyKCk7Ci0KLSAgICBhcHBDb3JvdXRpbmVJRCA9IGNvLmNvX2pvaW5Db3JvdXRpbmVTZXQoYXBwQ29yb3V0aW5lSUQpOwotICAgIGlmIChhcHBDb3JvdXRpbmVJRCA9PSAtMSkKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFUlJPUjogQ291bGRuJ3QgYWxsb2NhdGUgY29yb3V0aW5lIG51bWJlci5cbiIpOwotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAvLyBOb3RlIHRoYXQgdGhpcyBpcyBhIGdsb2JhbCAtLSBzbG9wcHkgY29ubmVjdGlvbiB0byB0aGUgdGhyZWFkLgotICAgIGZpbHRlcj1uZXcgQ29yb3V0aW5lU0FYUGFyc2VyKGNvLCBhcHBDb3JvdXRpbmVJRCk7Ci0KLSAgICAvLyBDb252ZW5pZW5jZSBmdW5jdGlvbi4uLiBTZXQgaGFuZGxlcnMKLSAgICBmaWx0ZXIuc2V0WE1MUmVhZGVyKHRoZVNBWFBhcnNlcik7Ci0gICAgCi0gICAgLy8gVXNlIGEgc2VyaWFsaXplciBhcyBvdXIgc2FtcGxlIG91dHB1dAotICAgIG9yZy5hcGFjaGUueG1sLnNlcmlhbGl6ZS5YTUxTZXJpYWxpemVyIHRyYWNlOwotICAgIHRyYWNlPW5ldyBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuWE1MU2VyaWFsaXplcihTeXN0ZW0ub3V0LG51bGwpOwotICAgIGZpbHRlci5zZXRDb250ZW50SGFuZGxlcih0cmFjZSk7Ci0gICAgZmlsdGVyLnNldExleEhhbmRsZXIodHJhY2UpOwotCi0gICAgLy8gTGF1bmNoIHRoZSBsaXN0ZW5lci4KLSAgICBUaHJlYWQgbGlzdGVuZXI9bmV3IFRocmVhZChuZXcgQ29yb3V0aW5lU0FYRmlsdGVyVGVzdCgpKTsKLSAgICBsaXN0ZW5lci5zZXREYWVtb24oZmFsc2UpOwotICAgIGxpc3RlbmVyLnN0YXJ0KCk7Ci0gICAgCi0gICAgLy8gQ2hlY2sgc3RvcC1lYXJseSBmbGFnCi0gICAgaWYoYXJncy5sZW5ndGg+MSAmJiAiISIuZXF1YWxzKGFyZ3NbMV0pKQotICAgICAgVEVTVF9FQVJMWV9TVE9QPXRydWU7Ci0KLSAgICAvLyBSdW4gdGhlIHBhcnNlcgotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqIFBhcnNlciBzdGFydCAqKioiKTsKLSAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgdGhlU0FYUGFyc2VyLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShhcmdzWzBdKSk7Ci0gICAgICB9Ci0gICAgY2F0Y2goamF2YS5pby5JT0V4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgfQotICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotCi0gICAgICAgIC8vICVSRVZJRVclIFdlJ2xsIHNob3VsZCBwcm9iYWJseSBleHBvc2UgdGhlc2Ugc3BlY2lhbCB0eXBlcywKLSAgICAgICAgLy8gaWYgd2UgbWlnaHQgYmUgdGVzdGluZyB0aGVtIG91dHNpZGUgdGhlIGZpbHRlcmluZyBjb2RlLi4uCi0KLSAgICAgICAgRXhjZXB0aW9uIGVtYmVkZGVkPWUuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICAgIGlmKGVtYmVkZGVkIT1udWxsICYmIGVtYmVkZGVkLmdldENsYXNzKCkuZ2V0TmFtZSgpLmVxdWFscygib3JnLmFwYWNoZS54bWwuZHRtLkNvcm91dGluZVNBWFBhcnNlciRVc2VyUmVxdWVzdGVkU3RvcEV4Y2VwdGlvbiIpKQotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLi4uIE5PUk1BTCByZXNwb25zZSB0byBkb1Rlcm1pbmF0ZSgpLiIpOwotICAgICAgfQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqIFBhcnNlciBlbmQgKioqIik7Ci0gICAgZmlsdGVyLmRvVGVybWluYXRlKGFwcENvcm91dGluZUlEKTsKLSAgfQotICAKLSAgLy8gSXNzdWUgY29yb3V0aW5lIHRyYW5zYWN0aW9ucyB0byBzaW11bGF0ZSBkaWFsb2cgd2l0aCB0aGUgcGFyc2VyCi0gIC8vIGZvciBhIHNpbmdsZSBmaWxlLiAgTm90ZSB0aGF0IHRoZSBzZXF1ZW5jZSBvZiBjYWxscyBoZXJlIGlzCi0gIC8vIGlkZW50aWNhbCB0byB0aGF0IHdoZW4gdGFsa2luZyB0byB0aGUgZnVsbHkgZW5jYXBzdWxhdGVkCi0gIC8vIHBhcnNlci4uLiB0aG91Z2ggZG9QYXJzZSgpIHdpbGwgYmUgYSBuby1vcCBzaW5jZSB0aGUgcGFyc2UKLSAgLy8gaXMgbGF1bmNoZWQgc2VwYXJhdGVseS4KLSAgcHVibGljIHZvaWQgcnVuKCkgewotICB7Ci0gICAgLy8gJVRCRCUgUFJPQkxFTTogUGFyc2VyIGVycm9yIGhhbmdzIHRoaXMgcHJvY2Vzcy4uLgotCi0gICAgT2JqZWN0IHJlc3VsdDsKLSAgICBib29sZWFuIG1vcmU9dHJ1ZTsKLQotICAgIGZvcihyZXN1bHQgPSBmaWx0ZXIuZG9QYXJzZShudWxsLCBhcHBDb3JvdXRpbmVJRCk7Ci0gICAgICAgIChyZXN1bHQgaW5zdGFuY2VvZiBCb29sZWFuICYmICgoQm9vbGVhbilyZXN1bHQpPT1Cb29sZWFuLlRSVUUpOwotICAgICAgICByZXN1bHQgPSBmaWx0ZXIuZG9Nb3JlKG1vcmUsIGFwcENvcm91dGluZUlEKSkKLSAgICAgIHsKLSAgICAgICAgLy8gU3BlY2lhbCB0ZXN0OiBUZXJtaW5hdGUgcGFyc2luZyBlYXJseS4KLSAgICAgICAgaWYoVEVTVF9FQVJMWV9TVE9QKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5Tb21lIHBhcnNpbmcgc3VjY2Vzc2Z1bCwgdHJ5aW5nIHRvIHN0b3AuXG4iKTsKLSAgICAgICAgICAgIG1vcmU9ZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblNvbWUgcGFyc2luZyBzdWNjZXNzZnVsLCB0cnlpbmcgbW9yZS5cbiIpOwotICAgICAgfQotICAgIAotICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBCb29sZWFuICYmICgoQm9vbGVhbilyZXN1bHQpPT1Cb29sZWFuLkZBTFNFKQotICAgICAgewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuZmlsdGVyIGVuZGVkIChFT0Ygb3Igb24gcmVxdWVzdCkuXG4iKTsKLSAgICAgIH0KLSAgICBlbHNlIGlmIChyZXN1bHQgPT0gbnVsbCkgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblVORVhQRUNURUQ6IGZpbHRlciBzYXlzIHNodXQgZG93biBwcmVtYXR1cmVseS5cbiIpOwotICAgIH0KLSAgICBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFeGNlcHRpb24pIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5maWx0ZXIgdGhyZXcgZXhjZXB0aW9uOiIpOwotICAgICAgKChFeGNlcHRpb24pcmVzdWx0KS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICB9Ci0gICAgCi0gIH0KLSAgCi0gIGZpbHRlci5kb1Rlcm1pbmF0ZShhcHBDb3JvdXRpbmVJRCk7Ci0gIH0KLSAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Db3JvdXRpbmVTQVhQYXJzZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVNBWFBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZTBhOTY2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVNBWFBhcnNlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA5NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTksMjAwMCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkNvcm91dGluZU1hbmFnZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqIDxwPkNvcm91dGluZVNBWFBhcnNlciBydW5zIGEgU0FYMiBwYXJzZXIgaW4gYSBjb3JvdXRpbmUgdG8gYWNoaWV2ZQotICogaW5jcmVtZW50YWwgcGFyc2luZy4gT3V0cHV0IGZyb20gdGhlIHBhcnNlciB3aWxsIHN0aWxsIGJlIGlzc3VlZAotICogdmlhIGNhbGxiYWNrcywgd2hpY2ggd2lsbCBuZWVkIHRvIGJlIHJlY2lldmVkIGFuZCBhY3RlZCB1cG9uIGJ5IGFuCi0gKiBhcHBvcHJpYXRlIGhhbmRsZXIuIEJ1dCB0aG9zZSBjYWxsYmFja3Mgd2lsbCBwYXNzIHRocm91Z2ggYQotICogY291bnRpbmcgc3RhZ2Ugd2hpY2ggcGVyaW9kaWNhbGx5IHlpZWxkcyBjb250cm9sIGJhY2sgdG8gdGhlIG90aGVyCi0gKiBjb3JvdXRpbmVzIGluIHRoaXMgc2V0LjwvcD4KLSAqCi0gKiA8cD5Gb3IgYSBicmllZiB1c2FnZSBleGFtcGxlLCBzZWUgdGhlIHVuaXQtdGVzdCBtYWluKCkgbWV0aG9kLjwvcD4KLSAqCi0gKiBAZGVwcmVjYXRlZCBTaW5jZSB0aGUgYWJpbGl0eSB0byBzdGFydCBhIHBhcnNlIHZpYSB0aGUKLSAqIGNvcm91dGluZSBwcm90b2NvbCB3YXMgbm90IGJlaW5nIHVzZWQgYW5kIHdhcyBjb21wbGljYXRpbmcgZGVzaWduLgotICogU2VlIHtAbGluayBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXJ9LgotICogKi8KLXB1YmxpYyBjbGFzcyBDb3JvdXRpbmVTQVhQYXJzZXIKLWltcGxlbWVudHMgQ29yb3V0aW5lUGFyc2VyLCBSdW5uYWJsZSwgQ29udGVudEhhbmRsZXIsIExleGljYWxIYW5kbGVyLCBFcnJvckhhbmRsZXIKLXsKLQotICBib29sZWFuIERFQlVHPWZhbHNlOyAvL0ludGVybmFsIHN0YXR1cyByZXBvcnQKLQotICAvLwotICAvLyBEYXRhCi0gIC8vCi0KLSAgcHJpdmF0ZSBDb3JvdXRpbmVNYW5hZ2VyIGZDb3JvdXRpbmVNYW5hZ2VyID0gbnVsbDsKLSAgcHJpdmF0ZSBpbnQgZkFwcENvcm91dGluZUlEID0gLTE7Ci0gIHByaXZhdGUgaW50IGZQYXJzZXJDb3JvdXRpbmVJRCA9IC0xOwotICBwcml2YXRlIGJvb2xlYW4gZlBhcnNlSW5Qcm9ncmVzcz1mYWxzZTsKLSAgcHJpdmF0ZSBYTUxSZWFkZXIgZlhNTFJlYWRlcj1udWxsOwotICBwcml2YXRlIGJvb2xlYW4gZlJ1bm5pbmdJblRocmVhZD1mYWxzZTsKLSAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciBjbGllbnRDb250ZW50SGFuZGxlcj1udWxsOyAvLyAlUkVWSUVXJSBzdXBwb3J0IG11bHRpcGxlPwotICBwcml2YXRlIExleGljYWxIYW5kbGVyIGNsaWVudExleGljYWxIYW5kbGVyPW51bGw7IC8vICVSRVZJRVclIHN1cHBvcnQgbXVsdGlwbGU/Ci0gIHByaXZhdGUgRXJyb3JIYW5kbGVyIGNsaWVudEVycm9ySGFuZGxlcj1udWxsOyAvLyAlUkVWSUVXJSBzdXBwb3J0IG11bHRpcGxlPwotICBwcml2YXRlIGludCBldmVudGNvdW50ZXI7Ci0gIHByaXZhdGUgaW50IGZyZXF1ZW5jeT01OwotCi0gIC8vIEhvcnJlbmRvdXMga2x1Z2UgdG8gcnVuIGZpbHRlciB0byBjb21wbGV0aW9uLiBTZWUgY29feWllbGQoKSdzCi0gIC8vIGludGVybmFsIGNvbW1lbnRzIGZvciBkZXRhaWxzLiAiSXMgdGhpcyBhbnkgd2F5IHRvIHJ1biBhIHJhaWxyb2FkPyIKLSAgcHJpdmF0ZSBib29sZWFuIGZOZXZlcllpZWxkQWdhaW49ZmFsc2U7Ci0gIAotCi0gIC8vCi0gIC8vIENvbnN0cnVjdG9ycwotICAvLwotCi0gIHB1YmxpYyBDb3JvdXRpbmVTQVhQYXJzZXIoKSB7Ci0gIH0KLSAgCi0gIC8qKiBDcmVhdGUgYSBDb3JvdXRpbmVTQVhQYXJzZXIgd2hpY2ggaXMgbm90IHlldCBib3VuZCB0byBhIHNwZWNpZmljCi0gICAqIFNBWCBldmVudCBzb3VyY2UuCi0gICAqCi0gICAqIFRISVMgVkVSU0lPTiBET0VTIE5PVCBMQVVOQ0ggQSBUSFJFQUQhIEl0IGlzIHByZXN1bWVkIHRoYXQgdGhlCi0gICAqIGFwcGxpY2F0aW9uIGNvcm91dGluZSB3aWxsIGJlIHN0YXJ0ZWQgaW4gYSBzZWNvbmRhcnkgdGhyZWFkIGFuZAotICAgKiB3aWxsIGJlIHdhaXRpbmcgZm9yIG91ciBmaXJzdCB5aWVsZCgpLCBhbmQgdGhhdCB0aGUgcGFyc2VyIHdpbGwKLSAgICogYmUgcnVuIGluIHRoZSBtYWluIHRocmVhZC4KLSAgICogCi0gICAqIFN0YXR1czogRXhwZXJpbWVudGFsCi0gICAqIAotICAgKiBAc2VlIHNldFhNTFJlYWRlcgotICAgKiAqLwotICBwdWJsaWMgQ29yb3V0aW5lU0FYUGFyc2VyKENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmVJRCkKLSAgewotICAgIHRoaXMuaW5pdCggY28sIGFwcENvcm91dGluZUlELCBudWxsICk7Ci0gIH0KLQotICAvKiogV3JhcCBhIFNBWDIgWE1MUmVhZGVyIChwYXJzZXIgb3Igb3RoZXIgZXZlbnQgc291cmNlKQotICAgKiBpbiBhIENvcm91dGluZVNBWFBhcnNlci4gVGhpcyB2ZXJzaW9uIGxhdW5jaGVzIHRoZSBDb3JvdXRpbmVTQVhQYXJzZXIKLSAgICogaW4gYSB0aHJlYWQsIGFuZCBwcmVwYXJlcyBpdCB0byBpbnZva2UgdGhlIHBhcnNlciBmcm9tIHRoYXQgdGhyZWFkCi0gICAqIHVwb24gcmVxdWVzdC4KLSAgICoKLSAgICogQHNlZSBkb1BhcnNlCi0gICAqLwotICBwdWJsaWMgQ29yb3V0aW5lU0FYUGFyc2VyKENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmVJRCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxSZWFkZXIgcGFyc2VyKSB7Ci0gICAgdGhpcy5pbml0KCBjbywgYXBwQ29yb3V0aW5lSUQsIHBhcnNlciApOwotICB9Ci0KLSAgLy8KLSAgLy8gUHVibGljIG1ldGhvZHMKLSAgLy8KLQotICBwdWJsaWMgdm9pZCBpbml0KCBDb3JvdXRpbmVNYW5hZ2VyIGNvLCBpbnQgYXBwQ29yb3V0aW5lSUQsIFhNTFJlYWRlciBwYXJzZXIgKSB7Ci0gICAgZlhNTFJlYWRlcj1udWxsOyAgICAvLyBObyByZWFkZXIgeWV0Ci0KLSAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotCi0gICAgZkNvcm91dGluZU1hbmFnZXIgPSBjbzsKLSAgICBmQXBwQ29yb3V0aW5lSUQgPSBhcHBDb3JvdXRpbmVJRDsKLSAgICBmUGFyc2VyQ29yb3V0aW5lSUQgPSBjby5jb19qb2luQ29yb3V0aW5lU2V0KC0xKTsKLSAgICBpZiAoZlBhcnNlckNvcm91dGluZUlEID09IC0xKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQsIG51bGwpKTsgLy8iY29fam9pbkNvcm91dGluZVNldCgpIGZhaWxlZCIpOwotCi0gICAgZlJ1bm5pbmdJblRocmVhZD1mYWxzZTsgLy8gVW5sZXNzIG92ZXJyaWRkZW4gYnkgdGhlIG90aGVyIGNvbnN0cnVjdG9yCi0KLSAgICBpZiggcGFyc2VyIT1udWxsICkgewotICAgICAgc2V0WE1MUmVhZGVyKHBhcnNlcik7Ci0gICAgCi0gICAgICBmUnVubmluZ0luVGhyZWFkPXRydWU7Ci0gICAgICBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbC5ydW5UcmFuc2Zvcm1UaHJlYWQodGhpcyk7Ci0gICAgICAvL1RocmVhZCB0ID0gbmV3IFRocmVhZCh0aGlzKTsKLSAgICAgIC8vdC5zZXREYWVtb24oZmFsc2UpOwotICAgICAgLy90LnN0YXJ0KCk7Ci0gICAgfQotICAgIAotICAgIC8vIFN5c3RlbS5lcnIucHJpbnRsbihmUnVubmluZ0luVGhyZWFkID8gIi4iIDogIioiKTsgCi0gIH0KLSAgICAKLSAgLyoqIEJpbmQgdG8gdGhlIFhNTFJlYWRlci4gVGhpcyBvcGVyYXRpb24gaXMgaWdub3JlZCBpZiB0aGUgcmVhZGVyIGhhcwotICAgKiBwcmV2aW91c2x5IGJlZW4gc2V0LgotICAgKgotICAgKiBKdXN0IGEgY29udmVuaWVuY2Ugcm91dGluZTsgb2J2aW91c2x5IHlvdSBjYW4gZXhwbGljaXRseSByZWdpc3RlcgotICAgKiB0aGlzIGFzIGEgbGlzdGVuZXIgd2l0aCB0aGUgc2FtZSBlZmZlY3QuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCBpdCB1bmJpbmQgZnJvbSB0aGUgcHJldmlvdXMgcmVhZGVyIGlmIHRoZXJlIGlzIG9uZT8KLSAgICogJVJFVklFVyUgRG8gd2UgcmVhbGx5IG5lZWQgdG8gc2V0IGZYTUxSZWFkZXI/Pz8KLSAgICoKLSAgICogJVRCRCUgVGhpcyBpcyBhIHF1aWNrLWhhY2sgc29sdXRpb24uIEknbSBub3QgY29udmluY2VkIHRoYXQgaXQncwotICAgKiBhZGVxdWF0ZS4gSW4gcGFydGljdWxhciwgc2luY2UgaW4gdGhpcyBtb2RlbCBwYXJzZXIucGFyc2UoKSBpcwotICAgKiBpbnZva2VkIGZyb20gb3V0c2lkZSByYXRoZXIgdGhhbiBmcm9tIG91ciBydW4oKSBsb29wLCBJJ20gbm90Ci0gICAqIHN1cmUgdGhlIGVuZC1vZi1maWxlIHJlc3BvbnNlIGlzIGJlaW5nIGRlbGl2ZXJlZCBwcm9wZXJseS4KLSAgICogKFRoZXJlIHdlcmUgcXVlc3Rpb25zIG9mIGRvdWJsZS15aWVsZHMgaW4gZWFybGllciB2ZXJzaW9ucyBvZiB0aGUgY29kZS4pCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIHNldFhNTFJlYWRlcihYTUxSZWFkZXIgcGFyc2VyKQotICB7Ci0gICAgaWYoZlhNTFJlYWRlciE9bnVsbCkgcmV0dXJuOwotICAgIAotICAgIGZYTUxSZWFkZXI9cGFyc2VyOwotICAgIGZYTUxSZWFkZXIuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgZlhNTFJlYWRlci5zZXRFcnJvckhhbmRsZXIodGhpcyk7IC8vIHRvIHJlcG9ydCBmYXRhbCBlcnJvcnMgaW4gZmlsdGVyaW5nIG1vZGUKLQotICAgIC8vIE5vdCBzdXBwb3J0ZWQgYnkgYWxsIFNBWDIgcGFyc2VyczoKLSAgICB0cnkgCi0gICAgICB7Ci0gICAgICAgIGZYTUxSZWFkZXIuc2V0UHJvcGVydHkoImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzKTsKLSAgICAgIH0KLSAgICBjYXRjaChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIE5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0Ci0gICAgICB9Ci0gICAgY2F0Y2goU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIE5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0Ci0gICAgICB9Ci0KLSAgICAvLyBTaG91bGQgd2UgYWxzbyBiaW5kIGFzIG90aGVyIHZhcmlldGllcyBvZiBoYW5kbGVyPwotICAgIC8vIChEVERIYW5kbGVyIGFuZCBzbyBvbikKLSAgfQotCi0gIC8vIFJlZ2lzdGVyIGEgY29udGVudCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIGNsaWVudENvbnRlbnRIYW5kbGVyPWhhbmRsZXI7Ci0gIH0KLSAgLy8gUmVnaXN0ZXIgYSBsZXhpY2FsIGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0bwotICAvLyBOb3QgYWxsIHBhcnNlcnMgc3VwcG9ydCB0aGlzLi4uCi0gIC8vID8/PyBTaG91bGQgd2UgcmVnaXN0ZXIgZGlyZWN0bHkgb24gdGhlIHBhcnNlcj8KLSAgLy8gTk9URSBOQU1FIC0tIHN1YmNsYXNzaW5nIGlzc3VlIGluIHRoZSBYZXJjZXMgdmVyc2lvbgotICBwdWJsaWMgdm9pZCBzZXRMZXhIYW5kbGVyKExleGljYWxIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICBjbGllbnRMZXhpY2FsSGFuZGxlcj1oYW5kbGVyOwotICB9Ci0gIC8vIFJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIgZm9yIHVzIHRvIG91dHB1dCB0bwotICAvLyBOT1RFIE5BTUUgLS0gc3ViY2xhc3NpbmcgaXNzdWUgaW4gdGhlIFhlcmNlcyB2ZXJzaW9uCi0gIHB1YmxpYyB2b2lkIHNldEVyckhhbmRsZXIoRXJyb3JIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICBjbGllbnRFcnJvckhhbmRsZXI9aGFuZGxlcjsKLSAgfQotCi0gIC8vIFNldCB0aGUgbnVtYmVyIG9mIGV2ZW50cyBiZXR3ZWVuIHJlc3VtZXMgb2Ygb3VyIGNvcm91dGluZQotICAvLyBJbW1lZGlhdGVseSByZXNldHMgbnVtYmVyIG9mIGV2ZW50cyBiZWZvcmUgX25leHRfIHJlc3VtZSBhcyB3ZWxsLgotICBwdWJsaWMgdm9pZCBzZXRSZXR1cm5GcmVxdWVuY3koaW50IGV2ZW50cykKLSAgewotICAgIGlmKGV2ZW50czwxKSBldmVudHM9MTsKLSAgICBmcmVxdWVuY3k9ZXZlbnRjb3VudGVyPWV2ZW50czsKLSAgfQotICAKLSAgLy8KLSAgLy8gQ29udGVudEhhbmRsZXIgbWV0aG9kcwotICAvLyBUaGVzZSAgcGFzcyB0aGUgZGF0YSB0byBvdXIgY2xpZW50IENvbnRlbnRIYW5kbGVyLi4uCi0gIC8vIGJ1dCB0aGV5IGFsc28gY291bnQgdGhlIG51bWJlciBvZiBldmVudHMgcGFzc2luZyB0aHJvdWdoLAotICAvLyBhbmQgcmVzdW1lIG91ciBjb3JvdXRpbmUgZWFjaCB0aW1lIHRoYXQgY291bnRlciBoaXRzIHplcm8gYW5kCi0gIC8vIGlzIHJlc2V0LgotICAvLwotICAvLyBOb3RlIHRoYXQgZm9yIGV2ZXJ5dGhpbmcgZXhjZXB0IGVuZERvY3VtZW50LCB3ZSBkbyB0aGUgY291bnQtYW5kLXlpZWxkCi0gIC8vIEJFRk9SRSBwYXNzaW5nIHRoZSBjYWxsIGFsb25nLiBJJ20gaG9waW5nIHRoYXQgdGhpcyB3aWxsIGVuY291cmFnZSBKSVQKLSAgLy8gY29tcGlsZXJzIHRvIHJlYWxpemUgdGhhdCB0aGVzZSBhcmUgdGFpbC1jYWxscywgcmVkdWNpbmcgdGhlIGV4cGVuc2Ugb2YKLSAgLy8gdGhlIGFkZGl0aW9uYWwgbGF5ZXIgb2YgZGF0YSBmbG93LgotICAvLwotICAvLyAlUkVWSUVXJSBHbGVubiBzdWdnZXN0cyB0aGF0IHBhdXNpbmcgYWZ0ZXIgZW5kRWxlbWVudCwgZW5kRG9jdW1lbnQsCi0gIC8vIGFuZCBjaGFyYWN0ZXJzIG1heSBiZSBzdWZmaWNpZW50LiBJIGFjdHVhbGx5IG1heSBub3Qgd2FudCB0bwotICAvLyBzdG9wIGFmdGVyIGNoYXJhY3RlcnMsIHNpbmNlIGluIG91ciBhcHBsaWNhdGlvbiB0aGVzZSB3aW5kIHVwIGJlaW5nCi0gIC8vIGNvbmNhdGVuYXRlZCBiZWZvcmUgdGhleSdyZSBwcm9jZXNzZWQuLi4gYnV0IHRoYXQgcmlza3MgaHVnZSBibG9ja3Mgb2YKLSAgLy8gdGV4dCBjYXVzaW5nIGdyZWF0ZXIgdGhhbiB1c3VhbCByZWFkYWhlYWQuIChVbmxpa2VseT8gQ29uc2lkZXIgdGhlCi0gIC8vIHBvc3NpYmlsaXR5IG9mIGEgbGFyZ2UgYmFzZS02NCBibG9jayBpbiBhIFNPQVAgc3RyZWFtLikKLSAgLy8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5jaGFyYWN0ZXJzKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBFWENFUFRJT046IEluIHRoaXMgY2FzZSB3ZSBuZWVkIHRvIHJ1biB0aGUgZXZlbnQgQkVGT1JFIHdlIHlpZWxkLgotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuZW5kRG9jdW1lbnQoKTsKLQotICAgIGV2ZW50Y291bnRlcj0wOwkKLSAgICBjb195aWVsZChmYWxzZSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChqYXZhLmxhbmcuU3RyaW5nIG5hbWVzcGFjZVVSSSwgamF2YS5sYW5nLlN0cmluZyBsb2NhbE5hbWUsCi0gICAgICBqYXZhLmxhbmcuU3RyaW5nIHFOYW1lKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5lbmRFbGVtZW50KG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUscU5hbWUpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZyBwcmVmaXgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgfQotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmEubGFuZy5TdHJpbmcgdGFyZ2V0LCBqYXZhLmxhbmcuU3RyaW5nIGRhdGEpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsZGF0YSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhpcyBjYW4gY2F1c2UgYSBoYW5nLiAgLXNiCi0gICAgICAgIC8vIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5za2lwcGVkRW50aXR5KG5hbWUpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcgbmFtZXNwYWNlVVJJLCBqYXZhLmxhbmcuU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKGphdmEubGFuZy5TdHJpbmcgcHJlZml4LCBqYXZhLmxhbmcuU3RyaW5nIHVyaSkgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmkpOwotICB9Ci0KLSAgLy8KLSAgLy8gTGV4aWNhbEhhbmRsZXIgc3VwcG9ydC4gTm90IGFsbCBTQVgyIHBhcnNlcnMgc3VwcG9ydCB0aGVzZSBldmVudHMKLSAgLy8gYnV0IHdlIG1heSB3YW50IHRvIHBhc3MgdGhlbSB0aHJvdWdoIHdoZW4gdGhleSBleGlzdC4uLgotICAvLwotICAvLyAlUkVWSUVXJSBUaGVzZSBkbyBOT1QgY3VycmVudGx5IGFmZmVjdCB0aGUgZXZlbnRjb3VudGVyOyBJJ20gYXNzZXJ0aW5nCi0gIC8vIHRoYXQgdGhleSdyZSByYXJlIGVub3VnaCB0aGF0IGl0IG1ha2VzIGxpdHRsZSBvciBubyBzZW5zZSB0bwotICAvLyBwYXVzZSBhZnRlciB0aGVtLiBBcyBzdWNoLCBpdCBtYXkgbWFrZSBtb3JlIHNlbnNlIGZvciBmb2xrcyB3aG8KLSAgLy8gYWN0dWFsbHkgd2FudCB0byB1c2UgdGhlbSB0byByZWdpc3RlciBkaXJlY3RseSB3aXRoIHRoZSBwYXJzZXIuCi0gIC8vIEJ1dCBJIHdhbnQgJ2VtIGhlcmUgZm9yIG5vdywgdG8gcmVtaW5kIHVzIHRvIHJlY2hlY2sgdGhpcyBhc3NlcnRpb24hCi0gIC8vCi0gIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuY29tbWVudChjaCxzdGFydCxsZW5ndGgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50TGV4aWNhbEhhbmRsZXIpCi0gICAgICBjbGllbnRMZXhpY2FsSGFuZGxlci5lbmRDREFUQSgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZERURCgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuZW5kRFREKCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50TGV4aWNhbEhhbmRsZXIpCi0gICAgICBjbGllbnRMZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuc3RhcnRDREFUQSgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgamF2YS5sYW5nLlN0cmluZyBwdWJsaWNJZCwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgc3lzdGVtSWQpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuIHN0YXJ0RFREKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRMZXhpY2FsSGFuZGxlcikKLSAgICAgIGNsaWVudExleGljYWxIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICB9Ci0KLSAgLy8KLSAgLy8gRXJyb3JIYW5kbGVyIHN1cHBvcnQuCi0gIC8vCi0gIC8vIFBST0JMRU06IFhlcmNlcyBpcyBhcHBhcmVudGx5IF9ub3RfIGNhbGxpbmcgdGhlIEVycm9ySGFuZGxlciBmb3IKLSAgLy8gZXhjZXB0aW9ucyB0aHJvd24gYnkgdGhlIENvbnRlbnRIYW5kbGVyLCB3aGljaCBwcmV2ZW50cyB1cyBmcm9tCi0gIC8vIGhhbmRsaW5nIHRoaXMgcHJvcGVybHkgd2hlbiBydW5uaW5nIGluIGZpbHRlcmluZyBtb2RlIHdpdGggWGVyY2VzCi0gIC8vIGFzIG91ciBldmVudCBzb3VyY2UuICBJdCdzIHVuY2xlYXIgd2hldGhlciB0aGlzIGlzIGEgWGVyY2VzIGJ1ZwotICAvLyBvciBhIFNBWCBkZXNpZ24gZmxhdy4KLSAgLy8gCi0gIC8vICVSRVZJRVclIEN1cnJlbnQgc29sdXRpb246IEluIGZpbHRlcmluZyBtb2RlLCBpdCBpcyBSRVFVSVJFRCB0aGF0Ci0gIC8vIGV2ZW50IHNvdXJjZSBtYWtlIHN1cmUgdGhpcyBtZXRob2QgaXMgaW52b2tlZCBpZiB0aGUgZXZlbnQgc3RyZWFtCi0gIC8vIGFiZW5kcyBiZWZvcmUgZW5kRG9jdW1lbnQgaXMgZGVsaXZlcmVkLiBJZiB0aGF0IG1lYW5zIGV4cGxpY2l0bHkgY2FsbGluZwotICAvLyB1cyBpbiB0aGUgZXhjZXB0aW9uIGhhbmRsaW5nIGNvZGUgYmVjYXVzZSBpdCB3b24ndCBiZSBkZWxpdmVyZWQgYXMgcGFydAotICAvLyBvZiB0aGUgbm9ybWFsIFNBWCBFcnJvckhhbmRsZXIgc3RyZWFtLCB0aGF0J3MgZmluZTsgTm90IE91ciBQcm9ibGVtLgotICAvLwotICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudEVycm9ySGFuZGxlcikKLSAgICAgIGNsaWVudEVycm9ySGFuZGxlci5lcnJvcihleGNlcHRpb24pOwotICB9Ci0gIAotICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gV2hlbiB3ZSdyZSBpbiBmaWx0ZXJpbmcgbW9kZSB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0Ci0gICAgLy8gd2UgdGVybWluYXRlIHRoZSBwYXJzaW5nIGNvcm91dGluZSB0cmFuc2FjdGlvbiAtLSBhbm5vdW5jZQotICAgIC8vIHRoZSBwcm9ibGVtIGFuZCBzaHV0IGRvd24gdGhlIGRpYWxvZy4KLQotICAgIC8vIFBST0JMRU06IFhlcmNlcyBpcyBhcHBhcmVudGx5IF9ub3RfIGNhbGxpbmcgdGhlIEVycm9ySGFuZGxlciBmb3IKLSAgICAvLyBleGNlcHRpb25zIHRocm93biBieSB0aGUgQ29udGVudEhhbmRsZXIuLi4gc3BlY2lmaWNhbGx5LCBkb1Rlcm1pbmF0ZS4KLSAgICAvLyAlVEJEJSBORUVEIEEgU09MVVRJT04hCi0gICAgCi0gICAgaWYoIWZSdW5uaW5nSW5UaHJlYWQpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX2V4aXRfdG8oZXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmUGFyc2VyQ29yb3V0aW5lSUQsZkFwcENvcm91dGluZUlEKTsKLSAgICAgICAgICAgIC8vICVUQkQlIERvIHdlIG5lZWQgdG8gd2FpdCBmb3IgdGVybWluYXRlPwotICAgICAgICAgIH0KLSAgICAgICAgY2F0Y2goTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gU2hvdWxkbid0IGhhcHBlbiB1bmxlc3Mgd2UndmUgbWlzY29kZWQgb3VyIGNvcm91dGluZSBsb2dpYwotICAgICAgICAgICAgLy8gIlNodXQgZG93biB0aGUgZ2FyYmFnZSBzbWFzaGVycyBvbiB0aGUgZGV0ZW50aW9uIGxldmVsISIKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgICAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdChmUGFyc2VyQ29yb3V0aW5lSUQpOwotCi0gICAgICAgICAgICAvLyBObyBuZWVkIHRvIHRocm93IHNodXRkb3duRXhjZXB0aW9uOyB3ZSdyZSBhbHJlYWR5Ci0gICAgICAgICAgICAvLyBpbiB0aGUgcHJvY2VzcyBvZiBtdXJkZXJpbmcgdGhlIHBhcnNlci4KLSAgICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICBpZihudWxsIT1jbGllbnRFcnJvckhhbmRsZXIpCi0gICAgICBjbGllbnRFcnJvckhhbmRsZXIuZXJyb3IoZXhjZXB0aW9uKTsKLSAgfQotICAKLSAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudEVycm9ySGFuZGxlcikKLSAgICAgIGNsaWVudEVycm9ySGFuZGxlci5lcnJvcihleGNlcHRpb24pOwotICB9Ci0gIAotCi0gIC8vCi0gIC8vIGNvcm91dGluZSBzdXBwb3J0Ci0gIC8vCi0KLSAgcHVibGljIGludCBnZXRQYXJzZXJDb3JvdXRpbmVJRCgpIHsKLSAgICByZXR1cm4gZlBhcnNlckNvcm91dGluZUlEOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gdGhlIENvcm91dGluZU1hbmFnZXIgdGhpcyBDb3JvdXRpbmVQYXJzZXIgb2JqZWN0IGlzIGJvdW5kIHRvLgotICAgKiBJZiB5b3UncmUgdXNpbmcgdGhlIGRvLi4uKCkgbWV0aG9kcywgYXBwbGljYXRpb25zIHNob3VsZCBvbmx5Ci0gICAqIG5lZWQgdG8gdGFsayB0byB0aGUgQ29yb3V0aW5lTWFuYWdlciBvbmNlLCB0byBvYnRhaW4gdGhlCi0gICAqIGFwcGxpY2F0aW9uJ3MgQ29yb3V0aW5lIElELgotICAgKiAqLwotICBwdWJsaWMgQ29yb3V0aW5lTWFuYWdlciBnZXRDb3JvdXRpbmVNYW5hZ2VyKCkKLSAgewotICAgIHJldHVybiBmQ29yb3V0aW5lTWFuYWdlcjsKLSAgfQotCi0gIC8qKiA8cD5JbiB0aGUgU0FYIGRlbGVnYXRpb24gY29kZSwgSSd2ZSBpbmxpbmVkIHRoZSBjb3VudC1kb3duIGluCi0gICAqIHRoZSBob3BlIG9mIGVuY291cmFnaW5nIGNvbXBpbGVycyB0byBkZWxpdmVyIGJldHRlcgotICAgKiBwZXJmb3JtYW5jZS4gSG93ZXZlciwgaWYgd2Ugc3ViY2xhc3MgKGVnIHRvIGRpcmVjdGx5IGNvbm5lY3QgdGhlCi0gICAqIG91dHB1dCB0byBhIERUTSBidWlsZGVyKSwgdGhhdCB3b3VsZCByZXF1aXJlIGNhbGxpbmcgc3VwZXIgaW4KLSAgICogb3JkZXIgdG8gcnVuIHRoYXQgbG9naWMuLi4gd2hpY2ggc2VlbXMgaW5lbGVnYW50LiAgSGVuY2UgdGhpcwotICAgKiByb3V0aW5lIGZvciB0aGUgY29udmVuaWVuY2Ugb2Ygc3ViY2xhc3NlczogZXZlcnkgW2ZyZXF1ZW5jeV0KLSAgICogaW52b2NhdGlvbnMsIGlzc3VlIGEgY29feWllbGQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbW9yZUV4ZXBjdGVkIFNob3VsZCBhbHdheXMgYmUgdHJ1ZSB1bmxlc3MgdGhpcyBpcyBiZWluZyBjYWxsZWQKLSAgICogYXQgdGhlIGVuZCBvZiBlbmREb2N1bWVudCgpIGhhbmRsaW5nLgotICAgKiAqLwotICB2b2lkIGNvdW50X2FuZF95aWVsZChib29sZWFuIG1vcmVFeHBlY3RlZCkKLSAgewotICAgIGlmKCFtb3JlRXhwZWN0ZWQpIGV2ZW50Y291bnRlcj0wOwotICAgIAotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgfQotICAKLQotICAvKioKLSAgICogQ29fWWllbGQgaGFuZGxlcyBjb3JvdXRpbmUgaW50ZXJhY3Rpb25zIHdoaWxlIGEgcGFyc2UgaXMgaW4gcHJvZ3Jlc3MuCi0gICAqIEl0IHdpbGwgcmVzdW1lIHdpdGggCi0gICAqICAgY29fcmVzdW1lKEJvb2xlYW4uVFJVRSwgLi4uKSBvbiBzdWNjZXNzIHdpdGggbW9yZSB0byBwYXJzZS4KLSAgICogICBjb19yZXN1bWUoQm9vbGVhbi5GQUxTRSwgLi4uKSBvbiBzdWNjZXNzIGFmdGVyIGVuZERvY3VtZW50LgotICAgKgotICAgKiBXaGVuIGNvbnRyb2wgaXMgcGFzc2VkIGJhY2sgaXQgbWF5IGluZGljYXRlCi0gICAqCi0gICAqICAgICAgbnVsbCAgICAgICAgICAgIHRlcm1pbmF0ZSB0aGlzIGNvcm91dGluZS4KLSAgICogICAgICAgICAgICAgICAgICAgICAgSXNzdWVzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBjb19leGl0X3RvKG51bGwsIC4uLikKLSAgICoJCQkgIGFuZCB0aHJvd3MgVXNlclJlcXVlc3RlZFNodXRkb3duRXhjZXB0aW9uCi0gICAqCi0gICAqICAgICAgQm9vbGVhbi5UUlVFICAgIGluZGljYXRpb24gdG8gY29udGludWUgcGFyc2luZyB0aGUgY3VycmVudCBkb2N1bWVudC4KLSAgICoJCQkgIFJlc3VtZXMgbm9ybWFsIFNBWCBwYXJzaW5nLgotICAgKgotICAgKiAgICAgIEJvb2xlYW4uRkFMU0UgICBpbmRpY2F0aW9uIHRvIGRpc2NvbnRpbnVlIHBhcnNpbmcgYW5kIHJlc2V0LgotICAgKgkJCSAgVGhyb3dzIFVzZXJSZXF1ZXN0ZWRTdG9wRXhjZXB0aW9uCi0gICAqCQkJICB0byByZXR1cm4gY29udHJvbCB0byB0aGUgcnVuKCkgbG9vcC4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBjb195aWVsZChib29sZWFuIG1vcmVSZW1haW5zKQotICB7Ci0gICAgLy8gSG9ycmVuZG91cyBrbHVnZSB0byBydW4gZmlsdGVyIHRvIGNvbXBsZXRpb24uIFNlZSBiZWxvdy4KLSAgICBpZihmTmV2ZXJZaWVsZEFnYWluKQotICAgICAgcmV0dXJuOwotICAgIAotICAgIE9iamVjdCBhcmc9IG1vcmVSZW1haW5zID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICAKLSAgICAvLyAlUkVWSUVXJSBFbmQtb2YtZmlsZSBiZWhhdmlvci4gV2hlbiBtb3JlUmVtYWlucz09ZmFsc2UsIHdlIGhhdmUKLSAgICAvLyBqdXN0IGVuZGVkIHBhcnNpbmcgdGhlIGRvY3VtZW50IGFuZCBhcmUgYWJvdXQgdG8gcmV0dXJuCi0gICAgLy8gZnJvbSB0aGUgcGFyc2VyLgotICAgIC8vCi0gICAgLy8gSWYgd2Ugd2VyZSBpbnZva2VkIGZyb20gdGhlIHJ1bigpIGxvb3AsIHdlIGhhdmUgdG8gcHJvdmlkZQotICAgIC8vIHRoZSBjb3JvdXRpbmUgYXJndW1lbnQgcmV0dXJuZWQgYWJvdmUgYXMgdGhlIG5leHQgY29tbWFuZAotICAgIC8vIHRvIGJlIHByb2Nlc3NlZCBpbiB0aGF0IGxvb3AuCi0gICAgLy8KLSAgICAvLyBDb252ZXJzZWx5LCBpZiB3ZSd2ZSBiZWVuIHJ1bm5pbmcgaW4gcmVzcG9uc2UgdG8KLSAgICAvLyBmWE1MUmVhZGVyLnBhcnNlKCkgaW52b2tlZCBkaXJlY3RseSwgd2Ugd2lsbCBub3QgYmUgcmV0dXJuaW5nCi0gICAgLy8gdG8gdGhhdCBsb29wLiBJbiB0aGF0IGNhc2UsIHRoZSBxdWVzdGlvbiBiZWNvbWVzIG9uZSBvZiB3aGF0IHdlCi0gICAgLy8gc2hvdWxkIGRvIGluc3RlYWQuIFRoZSBzaW1wbGVzdCBhbnN3ZXIgd291bGQgc2VlbSB0byBiZSB0byBkbyBhCi0gICAgLy8gY29fZXhpdF90byBpbW1lZGlhdGVseSwgc2luY2Ugd2UgZG9uJ3QgaGF2ZSBhIGNvbW1hbmQgbG9vcCB0bwotICAgIC8vIGNvbnRpbnVlIHRvIHRhbGsgdG8uCi0gICAgaWYoIW1vcmVSZW1haW5zKQotICAgICAgewotICAgICAgICBpZihmUnVubmluZ0luVGhyZWFkKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIEp1c3QgcmV0dXJuLiBUaGUgY29tbWFuZCBsb29wIGluIHJ1bigpIHdpbGwgc2VuZCB0aGUKLSAgICAgICAgICAgIC8vICJ3ZSdyZSBkb25lIiBhbm5vdW5jZW1lbnQgYW5kIHJlcXVlc3QgdGhlIG5leHQgY29tbWFuZC4KLSAgICAgICAgICAgIHJldHVybjsgLy8gbGV0IHRoZSBwYXJzZXIgdGVybWluYXRlIGl0c2VsZgotICAgICAgICAgIH0KLSAgICAgICAgICAKLSAgICAgICAgZWxzZSB0cnkgCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gRm9yY2VkIFRlcm1pbmF0aW9uIGRpYWxvZy4gU2F5IHdlJ3JlIGRvbmUsIHdhaXQgZm9yIGEKLSAgICAgICAgICAgIC8vIHRlcm1pbmF0aW9uIHJlcXVlc3QgKGRvbid0IGFjY2VwdCBhbnl0aGluZyBlbHNlKSwgYW5kCi0gICAgICAgICAgICAvLyBzaHV0IGRvd24uCi0gICAgICAgICAgICBhcmcgPSBmQ29yb3V0aW5lTWFuYWdlci5jb19yZXN1bWUoQm9vbGVhbi5GQUxTRSwgZlBhcnNlckNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBcHBDb3JvdXRpbmVJRCk7Ci0gICAgICAgICAgICB3aGlsZShhcmchPW51bGwpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBPbiBzaG9ydCBkb2N1bWVudHMsIG91ciB0aW1pbmctd2luZG93IGZpeCBtYXkgbWVhbgotICAgICAgICAgICAgICAgIC8vIGFyZyBpcyBhY3R1YWxseSBUUlVFICh3YWl0aW5nIGZvciBub2RlcykuIEluIHRoYXQgY2FzZQotICAgICAgICAgICAgICAgIC8vIHdlIHdhbnQgdG8gcmV0dXJuIEZBTFNFIChwYXJzaW5nIGNvbXBsZXRlKS4gSWYgd2UgZ2V0IFRSVUUKLSAgICAgICAgICAgICAgICAvLyBhdCBhbnkgb3RoZXIgdGltZSwgaXQncyBhIGRpYWxvZyBlcnJvciwgYnV0IEkgZG9uJ3Qgd2FudAotICAgICAgICAgICAgICAgIC8vIHRvIGRlYWwgd2l0aCBpbnZlbnRpbmcgeWV0IGFub3RoZXIgdmFsdWUgcmlnaHQgbm93LgotICAgICAgICAgICAgICAgIC8vIFJJR0hUIEZJWCB3aWxsIGJlIHRvIHJlZGVzaWduIHRoZSB3aG9sZSBjb3JvdXRpbmUKLSAgICAgICAgICAgICAgICAvLyBjb21tdW5pY2F0aW9ucyBwcm90b2NvbC4KLSAgICAgICAgICAgICAgICBpZihhcmc9PUJvb2xlYW4uVFJVRSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBhcmc9Qm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAgICAgICAgICAgICAgIkZpbHRlcmluZyBDb3JvdXRpbmVTQVhQYXJzZXI6IHVuZXhwZWN0ZWQgcmVzdW1lIHBhcmFtZXRlciwgIgotICAgICAgICAgICAgICAgICAgICArYXJnLmdldENsYXNzKCkrIiB3aXRoIHZhbHVlPVwiIithcmcrJyInKTsKLSAgICAgICAgICAgICAgICAgIC8vIElmIHlvdSBkb24ndCBkbyB0aGlzLCBpdCBjYW4gbG9vcCBmb3JldmVyIHdpdGggdGhlIGFib3ZlCi0gICAgICAgICAgICAgICAgICAvLyBlcnJvciBwcmludGluZyBvdXQuICAtc2IKLSAgICAgICAgICAgICAgICAgIGFyZyA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAiRmlsdGVyaW5nIENvcm91dGluZVNBWFBhcnNlcjogdW5leHBlY3RlZCByZXN1bWUgcGFyYW1ldGVyLCAiCi0gICAgICAgICAgICAgICAgICAgICthcmcuZ2V0Q2xhc3MoKSsiIHdpdGggdmFsdWU9XCIiK2FyZysnIicpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBhcmcgPSBmQ29yb3V0aW5lTWFuYWdlci5jb19yZXN1bWUoYXJnLCBmUGFyc2VyQ29yb3V0aW5lSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBcHBDb3JvdXRpbmVJRCk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIAotICAgICAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdF90byhhcmcsIGZQYXJzZXJDb3JvdXRpbmVJRCwgZkFwcENvcm91dGluZUlEKTsKLSAgICAgICAgICAgIHJldHVybjsgLy8gbGV0IHRoZSBwYXJzZXIgcmV0dXJuCi0gICAgICAgICAgfQotICAgICAgICBjYXRjaChqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gU2hvdWxkbid0IGhhcHBlbiB1bmxlc3Mgd2UndmUgbWlzY29kZWQgb3VyIGNvcm91dGluZSBsb2dpYwotICAgICAgICAgICAgLy8gIlNodXQgZG93biB0aGUgZ2FyYmFnZSBzbWFzaGVycyBvbiB0aGUgZGV0ZW50aW9uIGxldmVsISIKLSAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgICAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdChmUGFyc2VyQ29yb3V0aW5lSUQpOwotICAgICAgICAgICAgdGhyb3cgc2h1dGRvd25FeGNlcHRpb247Ci0gICAgICAgICAgfQotICAgICAgfSAvLyBpZiBtb3JlUmVtYWlucwotCi0KLSAgICBlbHNlIHRyeQotICAgICAgewotICAgICAgICBhcmcgPSBmQ29yb3V0aW5lTWFuYWdlci5jb19yZXN1bWUoYXJnLCBmUGFyc2VyQ29yb3V0aW5lSUQsIGZBcHBDb3JvdXRpbmVJRCk7Ci0KLSAgICAgICAgLy8gJVJFVklFVyUgSSdtIHJlYWxseSBub3QgaGFwcHkgd2l0aCB0aGUgZm9sbG93aW5nOgotICAgICAgICAvLwotICAgICAgICAvLyBJZiB3ZSdyZSBydW5uaW5nIGluIGZpbHRlciBtb2RlLCBkcml2ZW4gYnkgYW4gZXh0ZXJuYWwgU0FYCi0gICAgICAgIC8vIGV2ZW50IHNvdXJjZSwgYW5kIGhhdmUgYmVlbiBiZWVuIHlpZWxkZWQgYmFjayB0byB3aXRoCi0gICAgICAgIC8vIEJvb2xlYW4uRkFMU0UgKGRvTW9yZShmYWxzZSkpIHRoZXJlIGFyZSB0d28gYWRkaXRpb25hbAotICAgICAgICAvLyBwcm9ibGVtcy4KLSAgICAgICAgLy8gCi0gICAgICAgIC8vIEZpcnN0OiBTY290dCB0ZWxscyBtZSB0aGF0IG91ciB0ZWNobmlxdWUgb2YgdGhyb3dpbmcgYW4KLSAgICAgICAgLy8gZXhjZXB0aW9uIGZyb20gdGhlIENvbnRlbnRIYW5kbGVyIHRvIHRlcm1pbmF0ZSBTQVggcGFyc2luZywKLSAgICAgICAgLy8gd2hpbGUgYWxtb3N0IGEgdW5pdmVyc2FsIHByYWN0aWNlIGluIHRoZSBTQVggY29tbXVuaXR5LCBpcyBub3QKLSAgICAgICAgLy8gYWNjZXB0YWJsZSBiZWNhdXNlIHdlIGNhbid0IGZvcmNlIHRoaXMgY29udHJhY3QgdXBvbiB0aGUgZXZlbnQKLSAgICAgICAgLy8gZ2VuZXJhdG9yLiAoVGhvdWdoIGhlIGZlZWxzIHdlIF9jYW5fIGZvcmNlIHRoZW0gdG8gYWNjZXB0IGEKLSAgICAgICAgLy8gY29udHJhY3QgdG8gZXhwbGljaXRseSBzZW5kIHVzIGEgZmF0YWxFcnJvciBldmVudCBpZiBwYXJzaW5nCi0gICAgICAgIC8vIHRlcm1pbmF0ZXMgZHVlIHRvIHNvbWUgb3RoZXIgU0FYRXhjZXB0aW9uLi4uIGJhc2ljYWxseSwgaXQncwotICAgICAgICAvLyB0aGUgb2xkICJ0aGlzIGlzIGEgbm9ybWFsIGNvbmRpdGlvbiBzbyBpdCBzaG91bGRuJ3QgYmUgYW4KLSAgICAgICAgLy8gZXhjZXB0aW9uIiByYXRpb25hbGxlLCB3aGljaCBoYXMgc29tZSB2YWxpZGl0eSB0byBpdC4pCi0gICAgICAgIC8vIEluc3RlYWQsIGFuZCBkZXNwaXRlIHRoZSB3YXN0ZWQgY3ljbGVzLCBoZSB3YW50cyBtZSB0byBzaW1wbHkKLSAgICAgICAgLy8gbGV0IHRoZSBldmVudCBzdHJlYW0gcnVuIHRvIGNvbXBsZXRpb24gd2l0aG91dCBwYXNzaW5nIHRoZQotICAgICAgICAvLyBldmVudHMgYWxvbmcgdG8gb3VyIG93biBjbGllbnQuIFRoYXQgcmVxdWlyZXMgZGlzYWJsaW5nCi0gICAgICAgIC8vIGNvX3llaWxkKCkgYXMgd2VsbC4gSUYgQU5EIFdIRU4gU0FYIEFERFMgQU4gT0ZGSUNJQUwKLSAgICAgICAgLy8gU1RPUC1QQVJTSU5HLUVBUkxZIE9QRVJBVElPTiwgd2UgY2FuIGxldmVyYWdlIHRoYXQuCi0gICAgICAgIC8vCi0gICAgICAgIC8vIFNlY29uZDogVGhlIGN1cnJlbnQgYXJjaGl0ZWN0dXJlIG9mIENvcm91dGluZVNBWFBhcnNlcidzCi0gICAgICAgIC8vIGNvcm91dGluZSB0cmFuc2FjdGlvbnMgYXNzdW1lcyB0aGF0IGRvTW9yZShmYWxzZSkgd2lsbCBiZQotICAgICAgICAvLyBmb2xsb3dlZCBieSBlaXRoZXIgZG9QYXJzZShuZXdJbnB1dFNvdXJjZSksIG9yCi0gICAgICAgIC8vIGRvVGVybWluYXRlKCkuIFdlIG11c3QgY29tcGxldGUgdGhhdCBjb3JvdXRpbmUgZGlhbG9nLgotICAgICAgICAvLyAKLSAgICAgICAgLy8gIkJsYWNrIG1hZ2ljIGlzIGEgbWF0dGVyIG9mIHN5bWJvbGlzbSBhbmQgaW50ZW50LiIKLSAgICAgICAgLy8gLS0gUmFuZGFsbCBHYXJyZXR0Ci0gICAgICAgIC8vCi0gICAgICAgIC8vICVUQkQlIFdlIF9NVVNUXyBnZXQgYXdheSBmcm9tIHRoaXMgYXJjaGl0ZWN0dXJlIGFuZCBzd2l0Y2gKLSAgICAgICAgLy8gdG8gQ29yb3V0aW5lU0FYRmlsdGVyLCBqdXN0IHNvIHdlIGRvbid0IGhhdmUgdG8gZ28gdGhyb3VnaAotICAgICAgICAvLyB0aGlzICJubywgSSBkb24ndCB3YW50IGFub3RoZXIgZmlsZSwgdGhhbmsgeW91IHZlcnkgbXVjaCIKLSAgICAgICAgLy8gdHJhbnNhY3Rpb24uIEluIG91ciBhcHBsaWNhdGlvbiB3ZSBzaG91bGQgbmV2ZXIgbmVlZCBpdCwKLSAgICAgICAgLy8gYW5kIHRoZSBvbmx5IGp1c3RpZmljYXRpb24gZm9yIHJ1bm5pbmcgdGhlIHBhcnNlIHdpdGhpbiBhCi0gICAgICAgIC8vIGNvcm91dGluZSByZXF1ZXN0IC0tIGNhcHR1cmluZyBTQVhFeGNlcHRpb25zIC0tIGNvdWxkIGJlCi0gICAgICAgIC8vIGhhbmRsZWQgcGVyIHRoZSBhYm92ZSBkaXNjdXNzaW9uLgotICAgICAgICAvLyAKLSAgICAgICAgaWYoIWZSdW5uaW5nSW5UaHJlYWQgJiYgYXJnPT1Cb29sZWFuLkZBTFNFKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyPW51bGw7Ci0gICAgICAgICAgICBjbGllbnRMZXhpY2FsSGFuZGxlcj1udWxsOwotICAgICAgICAgICAgLy8gQW55b25lIGVsc2U/Ci0gICAgICAgIAotICAgICAgICAgICAgZk5ldmVyWWllbGRBZ2Fpbj10cnVlOyAvLyBIb3JyZW5kb3VzIGtsdWdlIHBhcnNpbmcgdG8gY29tcGxldGlvbjoKLQotICAgICAgICAgICAgLy8gRm9yY2VkIFRlcm1pbmF0aW9uIGRpYWxvZy4gU2F5IHdlJ3JlIGRvbmUsIHdhaXQgZm9yIGEKLSAgICAgICAgICAgIC8vIHRlcm1pbmF0aW9uIHJlcXVlc3QgKGRvbid0IGFjY2VwdCBhbnl0aGluZyBlbHNlKSwgYW5kCi0gICAgICAgICAgICAvLyBzaHV0IGRvd24uCi0gICAgICAgICAgICBhcmcgPSBmQ29yb3V0aW5lTWFuYWdlci5jb19yZXN1bWUoQm9vbGVhbi5GQUxTRSwgZlBhcnNlckNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBcHBDb3JvdXRpbmVJRCk7Ci0gICAgICAgICAgICB3aGlsZShhcmchPW51bGwpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTdHJpbmcgbXNnPSJGaWx0ZXJpbmcgQ29yb3V0aW5lU0FYUGFyc2VyOiAiKwotICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQgcmVzdW1lIHBhcmFtZXRlciwgIisKLSAgICAgICAgICAgICAgICAgIGFyZy5nZXRDbGFzcygpKyIgd2l0aCB2YWx1ZT1cIiIrYXJnKyciJzsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKLSAgICAgICAgICAgICAgICAvLyBJZiB5b3UgZG9uJ3QgZG8gdGhpcywgaXQgY2FuIGxvb3AgZm9yZXZlciB3aXRoIHRoZSBhYm92ZQotICAgICAgICAgICAgICAgIC8vIGVycm9yIHByaW50aW5nIG91dC4gIC1zYgotICAgICAgICAgICAgICAgIGFyZyA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKG1zZyk7Ci0gICAgICAgICAgICAgICAgYXJnID0gZkNvcm91dGluZU1hbmFnZXIuY29fcmVzdW1lKGFyZywgZlBhcnNlckNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQXBwQ29yb3V0aW5lSUQpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX2V4aXRfdG8oYXJnLCBmUGFyc2VyQ29yb3V0aW5lSUQsIGZBcHBDb3JvdXRpbmVJRCk7Ci0gICAgICAgICAgICByZXR1cm47IC8vIGxldCB0aGUgcGFyc2VyIHJ1biB0byBjb21wbGV0aW9uIGFuZCByZXR1cm4KLSAgICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGFyZyA9PSBudWxsKSB7Ci0gICAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdF90byhhcmcsIGZQYXJzZXJDb3JvdXRpbmVJRCwgZkFwcENvcm91dGluZUlEKTsKLSAgICAgICAgICAvLyAlUkVWSUVXJSBGb3Igc29tZSByZWFzb24gdGhlIChhcmcgPT0gbnVsbCkgY29uZGl0aW9uIGlzIG9jY3VyaW5nLgotICAgICAgICAgIC8vIFlvdSBjYW4gcmVwbGljYXRlIHRoaXMgc29tZXRpbWVzIHdpdGg6Ci0gICAgICAgICAgLy8gdGVzdG8gYXR0cmlic2V0XGF0dHJpYnNldDAxIC1mbGF2b3IgdGggLWVkdW1wCi0gICAgICAgICAgLy8gT3Igd2l0aCBDcmltc29uIHJ1bm5pbmcsIG91dHB1dFxvdXRwdXQwMS4KLSAgICAgICAgICB0aHJvdyBuZXcgVXNlclJlcXVlc3RlZFNodXRkb3duRXhjZXB0aW9uKCk7Ci0gICAgICAgICAgLy8gdGhyb3cgc2h1dGRvd25FeGNlcHRpb247Ci0gICAgICAgIH0KLQotICAgICAgICBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBCb29sZWFuKSB7Ci0gICAgICAgICAgYm9vbGVhbiBrZWVwZ29pbmcgPSAoKEJvb2xlYW4pYXJnKS5ib29sZWFuVmFsdWUoKTsKLSAgICAgICAgICBpZiAoIWtlZXBnb2luZykKLSAgICAgICAgICAgIHRocm93IHN0b3BFeGNlcHRpb247Ci0gICAgICAgICAgfQotCi0gICAgICAgIGVsc2UgLy8gVW5leHBlY3RlZCEKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgICAgICAiQWN0aXZlIENvcm91dGluZVNBWFBhcnNlcjogdW5leHBlY3RlZCByZXN1bWUgcGFyYW1ldGVyLCAiCi0gICAgICAgICAgICAgICAgICArYXJnLmdldENsYXNzCi0gICAgICAgICAgICAgICAgICAoKSsiIHdpdGggdmFsdWU9XCIiK2FyZysnIicpOwotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJcdFN0b3BwaW5nIHBhcnNlciByYXRoZXIgdGhhbiByaXNrIGRlYWRsb2NrIik7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1JPVVRJTkVfUEFSQU0sIG5ldyBPYmplY3RbXXthcmd9KSk7IC8vIkNvcm91dGluZSBwYXJhbWV0ZXIgZXJyb3IgKCIrYXJnKycpJyk7Ci0gICAgICAgICAgfQotCi0gICAgICB9Ci0gICAgY2F0Y2goamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICAvLyBTaG91bGRuJ3QgaGFwcGVuIHVubGVzcyB3ZSd2ZSBtaXNjb2RlZCBvdXIgY29yb3V0aW5lIGxvZ2ljCi0gICAgICAgIC8vICJTaHV0IGRvd24gdGhlIGdhcmJhZ2Ugc21hc2hlcnMgb24gdGhlIGRldGVudGlvbiBsZXZlbCEiCi0gICAgICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgICAgICBmQ29yb3V0aW5lTWFuYWdlci5jb19leGl0KGZQYXJzZXJDb3JvdXRpbmVJRCk7Ci0gICAgICAgIHRocm93IG5ldyBVc2VyUmVxdWVzdGVkU2h1dGRvd25FeGNlcHRpb24oKTsKLSAgICAgICAgLy8gdGhyb3cgc2h1dGRvd25FeGNlcHRpb247Ci0gICAgICB9Ci0gIH0KLQotCi0gIC8qKiBCZXR3ZWVuIHBhcnNlciBleGVjdXRpb25zLCB3YWl0IGZvciBvdXIgcGFydG5lciB0byByZXN1bWUgdXMgYW5kCi0gICAqIHRlbGwgdXMgd2hhdCB0byBkbzoKLSAgICoKLSAgICogICAgICBudWxsICAgICAgICAgICAgdGVybWluYXRlIHRoaXMgY29yb3V0aW5lLgotICAgKiAgICAgICAgICAgICAgICAgICAgICBleGl0cyB3aXRoOgotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29fZXhpdF90byhudWxsLCAuLi4pCi0gICAqICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdHMgbmV4dDoKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGhpbmcsIHdlIGhhdmUgdGVybWluYXRlZCB0aGUgdGhyZWFkLgotICAgKgotICAgKiAgICAgIElucHV0U291cmNlICAgICBzZXR1cCB0byByZWFkIGZyb20gdGhpcyBzb3VyY2UuCi0gICAqICAgICAgICAgICAgICAgICAgICAgIHJlc3VtZXMgd2l0aDoKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGNvX3Jlc3VtZShCb29sZWFuLlRSVUUsIC4uLikgb24gcGFydGlhbCBwYXJzZQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29fcmVzdW1lKEJvb2xlYW4uRkFMU0UsIC4uLikgb24gY29tcGxldGUgcGFyc2UKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGNvX3Jlc3VtZShFeGNlcHRpb24sIC4uLikgb24gZXJyb3IuCi0gICAqCi0gICAqICVSRVZFSVclIFNob3VsZCB0aGlzIGJlIGFibGUgdG8gc2V0IGxpc3RlbmVycz8gUGFydG5lciBjb3JvdXRpbmUgSUQ/Ci0gICAqICovCi0gIHB1YmxpYyB2b2lkIHJ1bigpIHsKLSAgICB0cnkgCi0gICAgICB7Ci0gICAgICAgIGZvcihPYmplY3QgYXJnPWZDb3JvdXRpbmVNYW5hZ2VyLmNvX2VudHJ5X3BhdXNlKGZQYXJzZXJDb3JvdXRpbmVJRCk7Ci0gICAgICAgICAgICB0cnVlOwotICAgICAgICAgICAgYXJnPWZDb3JvdXRpbmVNYW5hZ2VyLmNvX3Jlc3VtZShhcmcsIGZQYXJzZXJDb3JvdXRpbmVJRCwgZkFwcENvcm91dGluZUlEKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vIFNodXQgZG93biByZXF1ZXN0ZWQuCi0gICAgICAgICAgICBpZiAoYXJnID09IG51bGwpIHsKLSAgICAgICAgICAgICAgaWYoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJDb3JvdXRpbmVTQVhQYXJzZXIgYXQtcmVzdCBzaHV0ZG93biByZXF1ZXN0ZWQiKTsKLSAgICAgICAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdF90byhhcmcsIGZQYXJzZXJDb3JvdXRpbmVJRCwgZkFwcENvcm91dGluZUlEKTsKLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vIFN0YXJ0LVBhcnNlIHJlcXVlc3RlZAotICAgICAgICAgICAgLy8gRm9yIHRoZSBkdXJhdGlvbiBvZiB0aGlzIG9wZXJhdGlvbiwgYWxsIGNvcm91dGluZSBoYW5kc2hha2luZwotICAgICAgICAgICAgLy8gd2lsbCBvY2N1ciBpbiB0aGUgY29feWllbGQgbWV0aG9kLiBUaGF0J3MgdGhlIG5pY2UgdGhpbmcgYWJvdXQKLSAgICAgICAgICAgIC8vIGNvcm91dGluZXM7IHRoZXkgZ2l2ZSB1cyBhIHdheSB0byBoYW5kIG9mZiBjb250cm9sIGZyb20gdGhlCi0gICAgICAgICAgICAvLyBtaWRkbGUgb2YgYSBzeW5jaHJvbm91cyBtZXRob2QuCi0gICAgICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgSW5wdXRTb3VyY2UpIHsKLSAgICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgaWYoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJJbmFjdGl2ZSBDb3JvdXRpbmVTQVhQYXJzZXIgbmV3IHBhcnNlICIrYXJnKTsKLSAgICAgICAgICAgICAgICBmWE1MUmVhZGVyLnBhcnNlKChJbnB1dFNvdXJjZSlhcmcpOwotICAgICAgICAgICAgICAgIC8vIFRlbGwgY2FsbGVyIHdlIHJldHVybmVkIGZyb20gcGFyc2luZwotICAgICAgICAgICAgICAgIGFyZz1Cb29sZWFuLkZBTFNFOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgY2F0Y2ggKFNBWEV4Y2VwdGlvbiBleCkgewotICAgICAgICAgICAgICAgIEV4Y2VwdGlvbiBpbm5lcj1leC5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgICAgICBpZihpbm5lciBpbnN0YW5jZW9mIFVzZXJSZXF1ZXN0ZWRTdG9wRXhjZXB0aW9uKXsKLSAgICAgICAgICAgICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiQWN0aXZlIENvcm91dGluZVNBWFBhcnNlciB1c2VyIHN0b3AgZXhjZXB0aW9uIik7Ci0gICAgICAgICAgICAgICAgICBhcmc9Qm9vbGVhbi5GQUxTRTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZihpbm5lciBpbnN0YW5jZW9mIFVzZXJSZXF1ZXN0ZWRTaHV0ZG93bkV4Y2VwdGlvbil7Ci0gICAgICAgICAgICAgICAgICBpZihERUJVRylTeXN0ZW0ub3V0LnByaW50bG4oIkFjdGl2ZSBDb3JvdXRpbmVTQVhQYXJzZXIgdXNlciBzaHV0ZG93biBleGNlcHRpb24iKTsKLSAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiQWN0aXZlIENvcm91dGluZVNBWFBhcnNlciBVTkVYUEVDVEVEIFNBWCBleGNlcHRpb246ICIrZXgpOwotICAgICAgICAgICAgICAgICAgYXJnPWV4OwkJICAKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgY2F0Y2goRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiQWN0aXZlIENvcm91dGluZVNBWFBhcnNlciBub24tU0FYIGV4Y2VwdGlvbjogIitleCk7Ci0gICAgICAgICAgICAgICAgICBhcmcgPSBleDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIAotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBlbHNlIC8vIFVuZXhwZWN0ZWQhCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAgICAgICAgICAiSW5hY3RpdmUgQ29yb3V0aW5lU0FYUGFyc2VyOiB1bmV4cGVjdGVkIHJlc3VtZSBwYXJhbWV0ZXIsICIKLSAgICAgICAgICAgICAgICAgICthcmcuZ2V0Q2xhc3MoKSsiIHdpdGggdmFsdWU9XCIiK2FyZysnIicpOwotICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgLy8gSWYgeW91IGRvbid0IGRvIHRoaXMsIGl0IGNhbiBsb29wIGZvcmV2ZXIgd2l0aCB0aGUgYWJvdmUKLSAgICAgICAgICAgICAgICAvLyBlcnJvciBwcmludGluZyBvdXQuICAtc2IKLSAgICAgICAgICAgICAgICBhcmcgPSBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICAgICJJbmFjdGl2ZSBDb3JvdXRpbmVTQVhQYXJzZXI6IHVuZXhwZWN0ZWQgcmVzdW1lIHBhcmFtZXRlciwgIgotICAgICAgICAgICAgICAgICAgK2FyZy5nZXRDbGFzcygpKyIgd2l0aCB2YWx1ZT1cIiIrYXJnKyciJyk7Ci0gICAgICAgICAgICAgIH0KLQotICAgICAgICAgIH0gLy8gZW5kIHdoaWxlCi0gICAgICB9IC8vIGVuZCB0cnkKLSAgICBjYXRjaChqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIC8vIFNob3VsZG4ndCBoYXBwZW4gdW5sZXNzIHdlJ3ZlIG1pc2NvZGVkIG91ciBjb3JvdXRpbmUgbG9naWMKLSAgICAgICAgLy8gIkNQTywgc2h1dCBkb3duIHRoZSBnYXJiYWdlIHNtYXNoZXJzIG9uIHRoZSBkZXRlbnRpb24gbGV2ZWwhIgotICAgICAgICBlLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKLSAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdChmUGFyc2VyQ29yb3V0aW5lSUQpOwotICAgICAgfQotICB9Ci0KLSAgLyoqIFVzZWQgc28gY29feWllbGQgY2FuIHJldHVybiBjb250cm9sIHRvIHJ1biBmb3IgZWFybHkgcGFyc2UKLSAgICogdGVybWluYXRpb24uICAqLwotICBjbGFzcyBVc2VyUmVxdWVzdGVkU3RvcEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KLSAgewotICB9Ci0gIAotICAvKiogJVJFVklFVyUgU2hvdWxkIGJlIHN0YXRpYywgYnV0IGNhbid0IGJlIGJlY2F1c2UgaW50ZXJuYWwgY2xhc3MgKi8KLSAgZmluYWwgVXNlclJlcXVlc3RlZFN0b3BFeGNlcHRpb24gc3RvcEV4Y2VwdGlvbj1uZXcgVXNlclJlcXVlc3RlZFN0b3BFeGNlcHRpb24oKTsKLQotICAvKiogVXNlZCBzbyBjb195aWVsZCBjYW4gcmV0dXJuIGNvbnRyb2wgdG8gcnVuIGZvciBjb3JvdXRpbmUgdGhyZWFkCi0gICAqIHRlcm1pbmF0aW9uLiAgKi8KLSAgY2xhc3MgVXNlclJlcXVlc3RlZFNodXRkb3duRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgotICB7Ci0gIH0KLQotICAvKiogJVJFVklFVyUgU2hvdWxkIGJlIHN0YXRpYywgYnV0IGNhbid0IGJlIGJlY2F1c2UgaW50ZXJuYWwgY2xhc3MgKi8KLSAgZmluYWwgVXNlclJlcXVlc3RlZFNodXRkb3duRXhjZXB0aW9uIHNodXRkb3duRXhjZXB0aW9uID0gbmV3IFVzZXJSZXF1ZXN0ZWRTaHV0ZG93bkV4Y2VwdGlvbigpOwotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvKiogZG9QYXJzZSgpIGlzIGEgc2ltcGxlIEFQSSB3aGljaCB0ZWxscyB0aGUgY29yb3V0aW5lIHBhcnNlcgotICAgKiB0byBiZWdpbiByZWFkaW5nIGZyb20gYSBmaWxlLiAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgZnJvbSBvbmUKLSAgICogb2Ygb3VyIHBhcnRuZXIgY29yb3V0aW5lcywgYW5kIHNlcnZlcyBib3RoIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBjb21tdW5pY2F0aW9uIHByb3RvY29sIGFuZCB0byBhdm9pZCBoYXZpbmcgdG8gZXhwbGljaXRseSB1c2UgdGhlCi0gICAqIENvcm91dGluZVBhcnNlcidzIGNvcm91dGluZSBJRCBudW1iZXIuCi0gICAqCi0gICAqICVSRVZJRVclOiBJZiB3ZSBhcmUgTk9UIHJ1bm5pbmcgaW4gYSB0aHJlYWQgKGlmIHdlIGJvdW5kIHRvIGFuCi0gICAqIGV4dGVybmFsbHkgaW52b2tlZCBYTUxSZWFkZXIpLCB0aGlzIG9wZXJhdGlvbiBpcyBhIG5vLW9wLiBJIGRvbid0Ci0gICAqIF90aGlua18gaXQgY2FuIHNhZmVseSBzeW5jaHJvbm91c2x5IGludm9rZSB0aGF0IHJlYWRlcidzIHBhcnNlKCkKLSAgICogb3BlcmF0aW9uLCBvciBkb01vcmUoKSwgd2hpY2ggd291bGQgYmUgdGhlIG9idmlvdXMgYWx0ZXJuYXRpdmVzLi4uLgotICAgKgotICAgKiAlUkVWSUVXJSBDYW4vc2hvdWxkIHRoaXMgdW5pZnkgd2l0aCBkb01vcmU/IChpZiBVUkkgaGFzbid0IGNoYW5nZWQsCi0gICAqIHBhcnNlIG1vcmUgZnJvbSBzYW1lIGZpbGUsIGVsc2UgZW5kIGFuZCByZXN0YXJ0IHBhcnNpbmcuLi4/Ci0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIElucHV0U291cmNlIHRvIHBhcnNlIGZyb20uCi0gICAqIEBwYXJhbSBhcHBDb3JvdXRpbmVJRCBUaGUgY29yb3V0aW5lIElEIG51bWJlciBvZiB0aGUgY29yb3V0aW5lIGludm9raW5nCi0gICAqIHRoaXMgbWV0aG9kLCBzbyBpdCBjYW4gYmUgcmVzdW1lZCBhZnRlciB0aGUgcGFyc2VyIGhhcyByZXNwb25kZWQgdG8gdGhlCi0gICAqIHJlcXVlc3QuCi0gICAqIEByZXR1cm4gQm9vbGVhbi5UUlVFIGlmIHRoZSBDb3JvdXRpbmVQYXJzZXIgYmVsaWV2ZXMgbW9yZSBkYXRhIG1heSBiZSBhdmFpbGFibGUKLSAgICogZm9yIGZ1cnRoZXIgcGFyc2luZy4gQm9vbGVhbi5GQUxTRSBpZiBwYXJzaW5nIHJhbiB0byBjb21wbGV0aW9uLgotICAgKiBFeGNlcHRpb24gaWYgdGhlIHBhcnNlciBvYmplY3RlZCBmb3Igc29tZSByZWFzb24uCi0gICAqICovCi0gIHB1YmxpYyBPYmplY3QgZG9QYXJzZShJbnB1dFNvdXJjZSBzb3VyY2UsIGludCBhcHBDb3JvdXRpbmVJRCkKLSAgewotICAgIC8vICVSRVZJRVclIEknbSBub3Qgd2lsZCBhYm91dCB0aGlzIHNvbHV0aW9uLi4uCi0gICAgaWYoIWZSdW5uaW5nSW5UaHJlYWQpCi0gICAgICByZXR1cm4gQm9vbGVhbi5UUlVFOyAvLyAiWWVzLCB3ZSBleHBlY3QgdG8gZGVsaXZlciBldmVudHMuIgotCi0gICAgdHJ5IAotICAgICAgewotICAgICAgICBPYmplY3QgcmVzdWx0PSAgICAKLSAgICAgICAgICBmQ29yb3V0aW5lTWFuYWdlci5jb19yZXN1bWUoc291cmNlLCBhcHBDb3JvdXRpbmVJRCwgZlBhcnNlckNvcm91dGluZUlEKTsKLSAgICAgICAgCi0gICAgICAgIC8vICVSRVZJRVclIEJldHRlciBlcnJvciByZXBvcnRpbmcgbmVlZGVkLi4uIHRob3VnaCBtb3N0IG9mIHRoZXNlCi0gICAgICAgIC8vIHNob3VsZCBuZXZlciBhcmlzZSBkdXJpbmcgbm9ybWFsIG9wZXJhdGlvbi4KLSAgICAgICAgLy8gU2hvdWxkIHRoaXMgcmV0aHJvdyB0aGUgcGFyc2UgZXhjZXB0aW9uPwotICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgaWYocmVzdWx0IGluc3RhbmNlb2YgU0FYRXhjZXB0aW9uKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFNBWEV4Y2VwdGlvbiBzZSA9IChTQVhFeGNlcHRpb24pcmVzdWx0OwotICAgICAgICAgICAgRXhjZXB0aW9uIGUgPSBzZS5nZXRFeGNlcHRpb24oKTsKLSAgICAgICAgICAgIGlmKG51bGwgIT0gZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblBhcnNlciB0aHJldyBleGNlcHRpb246Iik7Ci0gICAgICAgICAgICAgIHNlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblBhcnNlciB0aHJldyBleGNlcHRpb246Iik7Ci0gICAgICAgICAgICAoKEV4Y2VwdGlvbilyZXN1bHQpLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgICB9Ci0KLSAgICAvLyBTSE9VTEQgTkVWRVIgT0NDVVIsIHNpbmNlIHRoZSBjb3JvdXRpbmUgbnVtYmVyIGFuZCBjb3JvdXRpbmUgbWFuYWdlcgotICAgIC8vIGFyZSB0aG9zZSBwcmV2aW91c2x5IGVzdGFibGlzaGVkIGZvciB0aGlzIENvcm91dGluZVNBWFBhcnNlci4uLgotICAgIC8vIFNvIEknbSBqdXN0IGdvaW5nIHRvIHJldHVybiBpdCBhcyBhIHBhcnNpbmcgZXhjZXB0aW9uLCBmb3Igbm93LgotICAgIGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICByZXR1cm4gZTsKLSAgICAgIH0KLSAgfQotICAKLSAgCi0gIC8qKiBkb01vcmUoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIGNvcm91dGluZSBwYXJzZXIKLSAgICogdGhhdCB3ZSBuZWVkIG1vcmUgbm9kZXMuICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZCBmcm9tIG9uZQotICAgKiBvZiBvdXIgcGFydG5lciBjb3JvdXRpbmVzLCBhbmQgc2VydmVzIGJvdGggdG8gZW5jYXBzdWxhdGUgdGhlCi0gICAqIGNvbW11bmljYXRpb24gcHJvdG9jb2wgYW5kIHRvIGF2b2lkIGhhdmluZyB0byBleHBsaWNpdGx5IHVzZSB0aGUKLSAgICogQ29yb3V0aW5lUGFyc2VyJ3MgY29yb3V0aW5lIElEIG51bWJlci4KLSAgICoKLSAgICogQHBhcmFtIHBhcnNlbW9yZSBJZiB0cnVlLCB0ZWxscyB0aGUgaW5jcmVtZW50YWwgcGFyc2VyIHRvIGdlbmVyYXRlCi0gICAqIGFub3RoZXIgY2h1bmsgb2Ygb3V0cHV0LiBJZiBmYWxzZSwgdGVsbHMgdGhlIHBhcnNlciB0aGF0IHdlJ3JlCi0gICAqIHNhdGlzZmllZCBhbmQgaXQgY2FuIHRlcm1pbmF0ZSBwYXJzaW5nIG9mIHRoaXMgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBhcHBDb3JvdXRpbmVJRCBUaGUgY29yb3V0aW5lIElEIG51bWJlciBvZiB0aGUgY29yb3V0aW5lIGludm9raW5nCi0gICAqIHRoaXMgbWV0aG9kLCBzbyBpdCBjYW4gYmUgcmVzdW1lZCBhZnRlciB0aGUgcGFyc2VyIGhhcyByZXNwb25kZWQgdG8gdGhlCi0gICAqIHJlcXVlc3QuCi0gICAqIEByZXR1cm4gQm9vbGVhbi5UUlVFIGlmIHRoZSBDb3JvdXRpbmVQYXJzZXIgYmVsaWV2ZXMgbW9yZSBkYXRhIG1heSBiZSBhdmFpbGFibGUKLSAgICogZm9yIGZ1cnRoZXIgcGFyc2luZy4gQm9vbGVhbi5GQUxTRSBpZiBwYXJzaW5nIHJhbiB0byBjb21wbGV0aW9uLgotICAgKiBFeGNlcHRpb24gaWYgdGhlIHBhcnNlciBvYmplY3RlZCBmb3Igc29tZSByZWFzb24uCi0gICAqICovCi0gIHB1YmxpYyBPYmplY3QgZG9Nb3JlKGJvb2xlYW4gcGFyc2Vtb3JlLCBpbnQgYXBwQ29yb3V0aW5lSUQpCi0gIHsKLSAgICB0cnkgCi0gICAgICB7Ci0gICAgICAgIE9iamVjdCByZXN1bHQgPQotICAgICAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX3Jlc3VtZShwYXJzZW1vcmU/Qm9vbGVhbi5UUlVFOkJvb2xlYW4uRkFMU0UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcENvcm91dGluZUlELCBmUGFyc2VyQ29yb3V0aW5lSUQpOwotICAgICAgICAKLSAgICAgICAgLy8gJVJFVklFVyUgQmV0dGVyIGVycm9yIHJlcG9ydGluZyBuZWVkZWQKLSAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5VTkVYUEVDVEVEOiBQYXJzZXIgZG9Nb3JlIHNheXMgc2h1dCBkb3duIHByZW1hdHVyZWx5LlxuIik7Ci0gICAgICAgICAgfQotICAgICAgICBlbHNlIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFeGNlcHRpb24pIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuUGFyc2VyIHRocmV3IGV4Y2VwdGlvbjoiKTsKLSAgICAgICAgICAoKEV4Y2VwdGlvbilyZXN1bHQpLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgICByZXR1cm4gcmVzdWx0OwotICAgICAgfQotICAKLSAgICAvLyBTSE9VTEQgTkVWRVIgT0NDVVIsIHNpbmNlIHRoZSBjb3JvdXRpbmUgbnVtYmVyIGFuZCBjb3JvdXRpbmUgbWFuYWdlcgotICAgIC8vIGFyZSB0aG9zZSBwcmV2aW91c2x5IGVzdGFibGlzaGVkIGZvciB0aGlzIENvcm91dGluZVNBWFBhcnNlci4uLgotICAgIC8vIFNvIEknbSBqdXN0IGdvaW5nIHRvIHJldHVybiBpdCBhcyBhIHBhcnNpbmcgZXhjZXB0aW9uLCBmb3Igbm93LgotICAgIGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICByZXR1cm4gZTsKLSAgICAgIH0KLSAgfQotICAKLSAgCi0gIC8qKiBkb1Rlcm1pbmF0ZSgpIGlzIGEgc2ltcGxlIEFQSSB3aGljaCB0ZWxscyB0aGUgY29yb3V0aW5lCi0gICAqIHBhcnNlciB0byB0ZXJtaW5hdGUgaXRzZWxmLiAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgZnJvbQotICAgKiBvbmUgb2Ygb3VyIHBhcnRuZXIgY29yb3V0aW5lcywgYW5kIHNlcnZlcyBib3RoIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBjb21tdW5pY2F0aW9uIHByb3RvY29sIGFuZCB0byBhdm9pZCBoYXZpbmcgdG8gZXhwbGljaXRseSB1c2UgdGhlCi0gICAqIENvcm91dGluZVBhcnNlcidzIGNvcm91dGluZSBJRCBudW1iZXIuCi0gICAqCi0gICAqIFJldHVybnMgb25seSBhZnRlciB0aGUgQ29yb3V0aW5lUGFyc2VyIGhhcyBhY2tub3dsZWRnZWQgdGhlIHJlcXVlc3QuCi0gICAqCi0gICAqIEBwYXJhbSBhcHBDb3JvdXRpbmVJRCBUaGUgY29yb3V0aW5lIElEIG51bWJlciBvZiB0aGUgY29yb3V0aW5lIGludm9raW5nCi0gICAqIHRoaXMgbWV0aG9kLCBzbyBpdCBjYW4gYmUgcmVzdW1lZCBhZnRlciB0aGUgcGFyc2VyIGhhcyByZXNwb25kZWQgdG8gdGhlCi0gICAqIHJlcXVlc3QuCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIGRvVGVybWluYXRlKGludCBhcHBDb3JvdXRpbmVJRCkKLSAgewotICAgIHRyeQotICAgICAgewotICAgICAgICBPYmplY3QgcmVzdWx0PUJvb2xlYW4uRkFMU0U7IC8vIER1bW15IGluaXRpYWwgdmFsdWUKLQotICAgICAgICAvLyBUaW1pbmcgcHJvYmxlbSBkaWFnbm9zdGljL2ZvcmNlLXRvLWNvbXBsZXRpb24gY29kZTsgYmV0dGVyIHRvIGZpeCB0aGUgcHJvYmxlbS4KLSAgICAgICAgLy93aGlsZShyZXN1bHQhPW51bGwpCi0gICAgICAgICAgcmVzdWx0ID0gZkNvcm91dGluZU1hbmFnZXIuY29fcmVzdW1lKG51bGwsIGFwcENvcm91dGluZUlELCBmUGFyc2VyQ29yb3V0aW5lSUQpOwotCi0gICAgICAgIC8vIERlYnVnZ2luZzsgc2hvdWxkbid0IGFyaXNlIGluIG5vcm1hbCBvcGVyYXRpb24KLSAgICAgICAgaWYocmVzdWx0IT1udWxsKQotICAgICAgICB7Ci0gICAgICAgICAgUnVudGltZUV4Y2VwdGlvbiByZSA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BBUlNFUl9ET1RFUk1JTkFURV9BTlNXRVJTLCBuZXcgT2JqZWN0W117cmVzdWx0fSkpOyAvLyJcblVORVhQRUNURUQ6IFBhcnNlciBkb1Rlcm1pbmF0ZSBhbnN3ZXJzICIrcmVzdWx0KTsKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlxuVU5FWFBFQ1RFRDogUGFyc2VyIGRvVGVybWluYXRlIGFuc3dlcnMgIityZXN1bHQpOwotICAgICAgICAgIHJlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICAgIC8vIHRocm93IHJlOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgY2F0Y2goamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgICAgewotICAgICAgICAvLyBUaGF0J3MgT0s7IGlmIGl0IGRvZXNuJ3QgZXhpc3QsIHdlIGRvbid0IG5lZWQgdG8gdGVybWluYXRlIGl0Ci0gICAgICB9Ci0gIH0KLQotLy8gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLy8gIC8qKiBTaW1wbGUgdW5pdCB0ZXN0LiBBdHRlbXB0IGNvcm91dGluZSBwYXJzaW5nIG9mIGRvY3VtZW50IGluZGljYXRlZAotLy8gICAqIGJ5IGZpcnN0IGFyZ3VtZW50IChhcyBhIFVSSSksIHJlcG9ydCBwcm9ncmVzcy4KLS8vICAgKi8KLS8vICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJnc1tdKQotLy8gIHsKLS8vICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnRpbmcuLi4iKTsKLS8vCi0vLyAgICBvcmcueG1sLnNheC5YTUxSZWFkZXIgdGhlU0FYUGFyc2VyPQotLy8gICAgICBuZXcgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIoKTsKLS8vICAgIAotLy8gICAgQ29yb3V0aW5lTWFuYWdlciBjbyA9IG5ldyBDb3JvdXRpbmVNYW5hZ2VyKCk7Ci0vLyAgICBpbnQgYXBwQ29yb3V0aW5lSUQgPSBjby5jb19qb2luQ29yb3V0aW5lU2V0KC0xKTsKLS8vICAgIGlmIChhcHBDb3JvdXRpbmVJRCA9PSAtMSkKLS8vICAgICAgewotLy8gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRVJST1I6IENvdWxkbid0IGFsbG9jYXRlIGNvcm91dGluZSBudW1iZXIuXG4iKTsKLS8vICAgICAgICByZXR1cm47Ci0vLyAgICAgIH0KLS8vICAgIENvcm91dGluZVNBWFBhcnNlciBwYXJzZXI9Ci0vLyAgICAgIG5ldyBDb3JvdXRpbmVTQVhQYXJzZXIoY28sIGFwcENvcm91dGluZUlELCB0aGVTQVhQYXJzZXIpOwotLy8gICAgaW50IHBhcnNlckNvcm91dGluZUlEID0gcGFyc2VyLmdldFBhcnNlckNvcm91dGluZUlEKCk7Ci0vLwotLy8gICAgLy8gVXNlIGEgc2VyaWFsaXplciBhcyBvdXIgc2FtcGxlIG91dHB1dAotLy8gICAgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLlhNTFNlcmlhbGl6ZXIgdHJhY2U7Ci0vLyAgICB0cmFjZT1uZXcgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLlhNTFNlcmlhbGl6ZXIoU3lzdGVtLm91dCxudWxsKTsKLS8vICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcih0cmFjZSk7Ci0vLyAgICBwYXJzZXIuc2V0TGV4SGFuZGxlcih0cmFjZSk7Ci0vLwotLy8gICAgLy8gVGVsbCBjb3JvdXRpbmUgdG8gYmVnaW4gcGFyc2luZywgcnVuIHdoaWxlIHBhcnNpbmcgaXMgaW4gcHJvZ3Jlc3MKLS8vICAgIGZvcihpbnQgYXJnPTA7YXJnPGFyZ3MubGVuZ3RoOysrYXJnKQotLy8gICAgICB7Ci0vLyAgICAgICAgSW5wdXRTb3VyY2Ugc291cmNlID0gbmV3IElucHV0U291cmNlKGFyZ3NbYXJnXSk7Ci0vLyAgICAgICAgT2JqZWN0IHJlc3VsdD1udWxsOwotLy8gICAgICAgIGJvb2xlYW4gbW9yZT10cnVlOwotLy8gICAgICAgIGZvcihyZXN1bHQgPSBwYXJzZXIuZG9QYXJzZShzb3VyY2UsIGFwcENvcm91dGluZUlEKTsKLS8vICAgICAgICAgICAgKHJlc3VsdCBpbnN0YW5jZW9mIEJvb2xlYW4gJiYgKChCb29sZWFuKXJlc3VsdCk9PUJvb2xlYW4uVFJVRSk7Ci0vLyAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlci5kb01vcmUobW9yZSwgYXBwQ29yb3V0aW5lSUQpKQotLy8gICAgICAgICAgewotLy8gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuU29tZSBwYXJzaW5nIHN1Y2Nlc3NmdWwsIHRyeWluZyBtb3JlLlxuIik7Ci0vLyAgICAgICAgICAgIAotLy8gICAgICAgICAgICAvLyBTcGVjaWFsIHRlc3Q6IFRlcm1pbmF0ZSBwYXJzaW5nIGVhcmx5LgotLy8gICAgICAgICAgICBpZihhcmcrMTxhcmdzLmxlbmd0aCAmJiAiISIuZXF1YWxzKGFyZ3NbYXJnKzFdKSkKLS8vICAgICAgICAgICAgICB7Ci0vLyAgICAgICAgICAgICAgICArK2FyZzsKLS8vICAgICAgICAgICAgICAgIG1vcmU9ZmFsc2U7Ci0vLyAgICAgICAgICAgICAgfQotLy8gICAgICAgICAgICAKLS8vICAgICAgICAgIH0KLS8vICAgICAgICAKLS8vICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgQm9vbGVhbiAmJiAoKEJvb2xlYW4pcmVzdWx0KT09Qm9vbGVhbi5GQUxTRSkKLS8vICAgICAgICAgIHsKLS8vICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblBhcnNlciBlbmRlZCAoRU9GIG9yIG9uIHJlcXVlc3QpLlxuIik7Ci0vLyAgICAgICAgICB9Ci0vLyAgICAgICAgZWxzZSBpZiAocmVzdWx0ID09IG51bGwpIHsKLS8vICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5VTkVYUEVDVEVEOiBQYXJzZXIgc2F5cyBzaHV0IGRvd24gcHJlbWF0dXJlbHkuXG4iKTsKLS8vICAgICAgICB9Ci0vLyAgICAgICAgZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXhjZXB0aW9uKSB7Ci0vLyAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuUGFyc2VyIHRocmV3IGV4Y2VwdGlvbjoiKTsKLS8vICAgICAgICAgICgoRXhjZXB0aW9uKXJlc3VsdCkucHJpbnRTdGFja1RyYWNlKCk7Ci0vLyAgICAgICAgfQotLy8gICAgICAgIAotLy8gICAgICB9Ci0vLwotLy8gICAgcGFyc2VyLmRvVGVybWluYXRlKGFwcENvcm91dGluZUlEKTsKLS8vICB9Ci0gIAotfSAvLyBjbGFzcyBDb3JvdXRpbmVTQVhQYXJzZXIKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0Nvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzUyZjNlYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Db3JvdXRpbmVTQVhQYXJzZXJfWGVyY2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNDggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LDIwMDAgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vL3BhY2thZ2Ugb3JnLmFwYWNoZS54ZXJjZXMucGFyc2VyczsKLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotLy9pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkNvcm91dGluZU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0KLS8qKiA8cD5Db3JvdXRpbmVTQVhQYXJzZXJfWGVyY2VzIHRha2VzIGFkdmFudGFnZSBvZiB0aGUgZmFjdCB0aGF0IFhlcmNlcwotICogaW5jcmVtZW50YWwgbW9kZSBpcyBhbHJlYWR5IGEgY29yb3V0aW5lIG9mIHNvcnRzLCBhbmQganVzdCB3cmFwcyBvdXIKLSAqIENvcm91dGluZVBhcnNlciBBUEkgYXJvdW5kIGl0LjwvcD4KLSAqCi0gKiBOT1RFIHRoYXQgdGhpcyByZXF1aXJlcyBhY2Nlc3MgdG8gYSBmZXcgZmVhdHVyZXMgd2hpY2ggYXJlIG5vdCB5ZXQKLSAqIHBhcnQgb2YgdGhlIHB1YmxpYyBYZXJjZXMgQVBJLiBHbGVubiBzb2x2ZWQgdGhhdCBieSBtYWtpbmcgdGhpcyBjbGFzcwotICogYSBzdWJjbGFzcyBvZiB4ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIuIEEgYmV0dGVyIHNvbHV0aW9uIG1heSBiZSB0bwotICogbWFrZSBhIHNlcGFyYXRlIHN1YmNsYXNzIHRoZXJlb2Ygd2hpY2ggZXhwb3NlcyB0aGUgcmVsZXZhbnQgbWV0aG9kcyBhcwotICogcHVibGljIC0tIGJvdGggYmVjYXVzZSBpdCBwcm92aWRlcyBtb3JlIGV4cGxpY2l0IGNvbnRyb2wgb3ZlciB3aGF0Ci0gKiBpcyBhbmQgaXNuJ3QgZXhwb3NlZCwgYW5kIGJlY2F1c2UgaXQgaG9sZHMgb3V0IHRoZSBob3BlIG9mIGRyb3BwaW5nIHRoYXQKLSAqIHN1YmNsYXNzIGFuZCBwbHVnZ2luZyBpbiBhIG5vcm1hbCBpbnN0YW5jZSBvZiBYZXJjZXMgaWYvd2hlbiB0aGVzZSBtZXRob2RzCi0gKiBiZWNvbWUgb2ZmaWNpYWwgQVBJIGNhbGxzLgotICoKLSAqIDxwPlVzYWdlIGV4YW1wbGU6IFNlZSBtYWluKCkuPC9wPgotICoKLSAqIEBkZXByZWNhdGVkIFNpbmNlIHRoZSBhYmlsaXR5IHRvIHN0YXJ0IGEgcGFyc2UgdmlhIHRoZQotICogY29yb3V0aW5lIHByb3RvY29sIHdhcyBub3QgYmVpbmcgdXNlZCBhbmQgd2FzIGNvbXBsaWNhdGluZyBkZXNpZ24uCi0gKiBTZWUge0BsaW5rIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlc30uCi0gKiAqLwotcHVibGljIGNsYXNzIENvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMKLS8vIGV4dGVuZHMgb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5TQVhQYXJzZXIKLWltcGxlbWVudHMgQ29yb3V0aW5lUGFyc2VyCi17Ci0gIC8vIEluY3JlbWVudGFsWGVyY2VzU2F4UGFyc2VyIGluY3JlbWVudGFsUGFyc2VyOwotICBTQVhQYXJzZXIgaW5jcmVtZW50YWxQYXJzZXI7Ci0KLSAgICAvLwotICAgIC8vIERhdGEKLSAgICAvLwotCi0gICAgcHJpdmF0ZSBib29sZWFuIGZQYXJzZUluUHJvZ3Jlc3M9ZmFsc2U7Ci0KLSAgICAvLwotICAgIC8vIENvbnN0cnVjdG9ycwotICAgIC8vCi0gICAgcHVibGljIENvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMoKSB7Ci0gICAgfQotICAgIAotICAgIHB1YmxpYyBDb3JvdXRpbmVTQVhQYXJzZXJfWGVyY2VzKENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmVJRCkgewotICAgICAgdGhpcy5pbml0KCBjbyxhcHBDb3JvdXRpbmVJRCwgbnVsbCk7Ci0gICAgfQotCi0gICAgLy8gWFhYIHRoZSBwYXJhbWV0ZXIgb3JkZXIgaXMgY29uZnVzaW5nLCBkaWZmZXJlbnQgZnJvbSBDb3JvdXRpbmVTQVhQYXJzZXIKLSAgICBwdWJsaWMgQ29yb3V0aW5lU0FYUGFyc2VyX1hlcmNlcyhTQVhQYXJzZXIgaXhzcCwgQ29yb3V0aW5lTWFuYWdlciBjbywgaW50IGFwcENvcm91dGluZUlEKSB7Ci0gICAgICB0aGlzLmluaXQoIGNvLCBhcHBDb3JvdXRpbmVJRCwgaXhzcCk7IAotICAgIH0KLQotICAgIHB1YmxpYyB2b2lkIGluaXQoIENvcm91dGluZU1hbmFnZXIgY28sIGludCBhcHBDb3JvdXRpbmVJRCwgWE1MUmVhZGVyIGl4c3AgKSB7Ci0gICAgICBpZihpeHNwIT1udWxsKQotICAgICAgICBpbmNyZW1lbnRhbFBhcnNlcj0oU0FYUGFyc2VyKWl4c3A7Ci0gICAgICBlbHNlCi0gICAgICAgIGluY3JlbWVudGFsUGFyc2VyPW5ldyBTQVhQYXJzZXIoKTsKLSAgICAgIAotICAgICAgLy8gaW5jcmVtZW50YWxQYXJzZXIuaW5pdEhhbmRsZXJzKHRydWUsIGluY3JlbWVudGFsUGFyc2VyLCBpbmNyZW1lbnRhbFBhcnNlcik7Ci0gICAgfQotICAgIAotICAgIC8vCi0gICAgLy8gRmFjdG9yaWVzCi0gICAgLy8KLSAgICBzdGF0aWMgcHVibGljIENvcm91dGluZVBhcnNlciBjcmVhdGVDb3JvdXRpbmVQYXJzZXIoQ29yb3V0aW5lTWFuYWdlciBjbywgaW50IGFwcENvcm91dGluZUlEKSB7Ci0gICAgICByZXR1cm4gbmV3IENvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMoY28sIGFwcENvcm91dGluZUlEKTsKLSAgICB9Ci0KLSAgICAvLwotICAgIC8vIFB1YmxpYyBtZXRob2RzCi0gICAgLy8KLQotICAgIC8vIGNvcm91dGluZSBzdXBwb3J0Ci0KLSAgICBwdWJsaWMgaW50IGdldFBhcnNlckNvcm91dGluZUlEKCkgewotICAgICAgLy8gcmV0dXJuIGZQYXJzZXJDb3JvdXRpbmVJRDsKLSAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgLyoqIEByZXR1cm4gdGhlIENvcm91dGluZU1hbmFnZXIgdGhpcyBDb3JvdXRpbmVQYXJzZXIgb2JqZWN0IGlzIGJvdW5kIHRvLgotICAgKiBJZiB5b3UncmUgdXNpbmcgdGhlIGRvLi4uKCkgbWV0aG9kcywgYXBwbGljYXRpb25zIHNob3VsZCBvbmx5Ci0gICAqIG5lZWQgdG8gdGFsayB0byB0aGUgQ29yb3V0aW5lTWFuYWdlciBvbmNlLCB0byBvYnRhaW4gdGhlCi0gICAqIGFwcGxpY2F0aW9uJ3MgQ29yb3V0aW5lIElELgotICAgKiAqLwotICBwdWJsaWMgQ29yb3V0aW5lTWFuYWdlciBnZXRDb3JvdXRpbmVNYW5hZ2VyKCkKLSAgewotICAgIC8vIHJldHVybiBmQ29yb3V0aW5lTWFuYWdlcjsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8vIFJlZ2lzdGVyIGhhbmRsZXIgZGlyZWN0bHkgd2l0aCB0aGUgaW5jcmVtZW50YWwgcGFyc2VyCi0gIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICBpbmNyZW1lbnRhbFBhcnNlci5zZXRDb250ZW50SGFuZGxlcihoYW5kbGVyKTsKLSAgfQotCi0gIC8vIE5vdGUgbmFtZSwgbmVlZGVkIHRvIGRvZGdlIHRoZSBpbmhlcml0ZWQgWGVyY2VzIHNldExleGljYWxIYW5kbGVyCi0gIC8vIHdoaWNoIGlzbid0IHB1YmxpYy4KLSAgcHVibGljIHZvaWQgc2V0TGV4SGFuZGxlcihvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIC8vIE5vdCBzdXBwb3J0ZWQgYnkgYWxsIFNBWDIgcGFyc2VycyBidXQgc2hvdWxkIHdvcmsgaW4gWGVyY2VzOgotICAgIHRyeSAKLSAgICAgIHsKLSAgICAgICAgaW5jcmVtZW50YWxQYXJzZXIuc2V0UHJvcGVydHkoImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsCi0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIpOwotICAgICAgfQotICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgLy8gTm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQKLSAgICAgIH0KLSAgICBjYXRjaChvcmcueG1sLnNheC5TQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgLy8gTm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQKLSAgICAgIH0KLSAgfQotICAKLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8qKiBkb1BhcnNlKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBjb3JvdXRpbmUgcGFyc2VyCi0gICAqIHRvIGJlZ2luIHJlYWRpbmcgZnJvbSBhIGZpbGUuICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZCBmcm9tIG9uZQotICAgKiBvZiBvdXIgcGFydG5lciBjb3JvdXRpbmVzLCBhbmQgc2VydmVzIGJvdGggdG8gZW5jYXBzdWxhdGUgdGhlCi0gICAqIGNvbW11bmljYXRpb24gcHJvdG9jb2wgYW5kIHRvIGF2b2lkIGhhdmluZyB0byBleHBsaWNpdGx5IHVzZSB0aGUKLSAgICogQ29yb3V0aW5lUGFyc2VyJ3MgY29yb3V0aW5lIElEIG51bWJlci4KLSAgICoKLSAgICogJVJFVklFVyUgQ2FuL3Nob3VsZCB0aGlzIHVuaWZ5IHdpdGggZG9Nb3JlPyAoaWYgVVJJIGhhc24ndCBjaGFuZ2VkLAotICAgKiBwYXJzZSBtb3JlIGZyb20gc2FtZSBmaWxlLCBlbHNlIGVuZCBhbmQgcmVzdGFydCBwYXJzaW5nLi4uPwotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBJbnB1dFNvdXJjZSB0byBwYXJzZSBmcm9tLgotICAgKiBAcGFyYW0gYXBwQ29yb3V0aW5lSUQgVGhlIGNvcm91dGluZSBJRCBudW1iZXIgb2YgdGhlIGNvcm91dGluZSBpbnZva2luZwotICAgKiB0aGlzIG1ldGhvZCwgc28gaXQgY2FuIGJlIHJlc3VtZWQgYWZ0ZXIgdGhlIHBhcnNlciBoYXMgcmVzcG9uZGVkIHRvIHRoZQotICAgKiByZXF1ZXN0LgotICAgKiBAcmV0dXJuIEJvb2xlYW4uVFJVRSBpZiB0aGUgQ29yb3V0aW5lUGFyc2VyIGJlbGlldmVzIG1vcmUgZGF0YSBtYXkgYmUgYXZhaWxhYmxlCi0gICAqIGZvciBmdXJ0aGVyIHBhcnNpbmcuIEJvb2xlYW4uRkFMU0UgaWYgcGFyc2luZyByYW4gdG8gY29tcGxldGlvbi4KLSAgICogRXhjZXB0aW9uIGlmIHRoZSBwYXJzZXIgb2JqZWN0ZWQgZm9yIHNvbWUgcmVhc29uLgotICAgKiAqLwotICBwdWJsaWMgT2JqZWN0IGRvUGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlLCBpbnQgYXBwQ29yb3V0aW5lSUQpCi0gIHsKLSAgICBpZiAoZlBhcnNlSW5Qcm9ncmVzcykgewotICAgICAgLy8gJXJldmlldyUgLS0gV2UgbmV2ZXIgc2V0IHRoaXMgZmxhZyBpbiB0aGUgcHJldmlvdXMgdmVyc2lvbiBvZgotICAgICAgLy8gdGhpcyBjbGFzcywgd2Ugc3RpbGwgZG9uJ3Qgc2V0IGl0IGhlcmUuLi4gRGlzY2FyZCwgb3IgZml4PwotICAgICAgcmV0dXJuIG5ldyBTQVhFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fUEFSU0VfQ0FMTF9XSElMRV9QQVJTSU5HLCBudWxsKSk7IC8vInBhcnNlIG1heSBub3QgYmUgY2FsbGVkIHdoaWxlIHBhcnNpbmcuIik7Ci0gICAgfQotICAgIAotICAgIE9iamVjdCBhcmc7Ci0gICAgdHJ5IHsKLSAgICAgIGJvb2xlYW4gb2sgPSBpbmNyZW1lbnRhbFBhcnNlci5wYXJzZVNvbWVTZXR1cChzb3VyY2UpOwotICAgICAgYXJnID0gb2sgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICBhcmcgPSBleDsKLSAgICB9Ci0gICAgcmV0dXJuIGFyZzsKLSAgfQotCi0gIAotICAvKiogZG9Nb3JlKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBjb3JvdXRpbmUgcGFyc2VyCi0gICAqIHRoYXQgd2UgbmVlZCBtb3JlIG5vZGVzLiAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgZnJvbSBvbmUKLSAgICogb2Ygb3VyIHBhcnRuZXIgY29yb3V0aW5lcywgYW5kIHNlcnZlcyBib3RoIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBjb21tdW5pY2F0aW9uIHByb3RvY29sIGFuZCB0byBhdm9pZCBoYXZpbmcgdG8gZXhwbGljaXRseSB1c2UgdGhlCi0gICAqIENvcm91dGluZVBhcnNlcidzIGNvcm91dGluZSBJRCBudW1iZXIuCi0gICAqCi0gICAqIEBwYXJhbSBwYXJzZW1vcmUgSWYgdHJ1ZSwgdGVsbHMgdGhlIGluY3JlbWVudGFsIHBhcnNlciB0byBnZW5lcmF0ZQotICAgKiBhbm90aGVyIGNodW5rIG9mIG91dHB1dC4gSWYgZmFsc2UsIHRlbGxzIHRoZSBwYXJzZXIgdGhhdCB3ZSdyZQotICAgKiBzYXRpc2ZpZWQgYW5kIGl0IGNhbiB0ZXJtaW5hdGUgcGFyc2luZyBvZiB0aGlzIGRvY3VtZW50LgotICAgKiBAcGFyYW0gYXBwQ29yb3V0aW5lSUQgVGhlIGNvcm91dGluZSBJRCBudW1iZXIgb2YgdGhlIGNvcm91dGluZSBpbnZva2luZwotICAgKiB0aGlzIG1ldGhvZCwgc28gaXQgY2FuIGJlIHJlc3VtZWQgYWZ0ZXIgdGhlIHBhcnNlciBoYXMgcmVzcG9uZGVkIHRvIHRoZQotICAgKiByZXF1ZXN0LgotICAgKiBAcmV0dXJuIEJvb2xlYW4uVFJVRSBpZiB0aGUgQ29yb3V0aW5lUGFyc2VyIGJlbGlldmVzIG1vcmUgZGF0YSBtYXkgYmUgYXZhaWxhYmxlCi0gICAqIGZvciBmdXJ0aGVyIHBhcnNpbmcuIEJvb2xlYW4uRkFMU0UgaWYgcGFyc2luZyByYW4gdG8gY29tcGxldGlvbi4KLSAgICogRXhjZXB0aW9uIGlmIHRoZSBwYXJzZXIgb2JqZWN0ZWQgZm9yIHNvbWUgcmVhc29uLgotICAgKiAqLwotICBwdWJsaWMgT2JqZWN0IGRvTW9yZSAoYm9vbGVhbiBwYXJzZW1vcmUsIGludCBhcHBDb3JvdXRpbmVJRCkKLSAgewotICAgIGlmKCFwYXJzZW1vcmUpCi0gICAgICB7Ci0gICAgICAgIGZQYXJzZUluUHJvZ3Jlc3M9ZmFsc2U7Ci0gICAgICAgIHJldHVybiBCb29sZWFuLkZBTFNFOwotICAgICAgfQotCi0gICAgT2JqZWN0IGFyZzsKLSAgICB0cnkgewotICAgICAgYm9vbGVhbiBrZWVwZ29pbmcgPSBpbmNyZW1lbnRhbFBhcnNlci5wYXJzZVNvbWUoKTsKLSAgICAgIGFyZyA9IGtlZXBnb2luZyA/IEJvb2xlYW4uVFJVRSA6IEJvb2xlYW4uRkFMU0U7Ci0gICAgfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGV4KSB7Ci0gICAgICBhcmcgPSBleDsKLSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewotICAgICAgYXJnID0gZXg7Ci0gICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7Ci0gICAgICBhcmcgPSBuZXcgU0FYRXhjZXB0aW9uKGV4KTsKLSAgICB9Ci0gICAgcmV0dXJuIGFyZzsKLSAgfQotICAKLSAgLyoqIGRvVGVybWluYXRlKCkgaXMgYSBzaW1wbGUgQVBJIHdoaWNoIHRlbGxzIHRoZSBjb3JvdXRpbmUKLSAgICogcGFyc2VyIHRvIHRlcm1pbmF0ZSBpdHNlbGYuICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZCBmcm9tCi0gICAqIG9uZSBvZiBvdXIgcGFydG5lciBjb3JvdXRpbmVzLCBhbmQgc2VydmVzIGJvdGggdG8gZW5jYXBzdWxhdGUgdGhlCi0gICAqIGNvbW11bmljYXRpb24gcHJvdG9jb2wgYW5kIHRvIGF2b2lkIGhhdmluZyB0byBleHBsaWNpdGx5IHVzZSB0aGUKLSAgICogQ29yb3V0aW5lUGFyc2VyJ3MgY29yb3V0aW5lIElEIG51bWJlci4KLSAgICoKLSAgICogUmV0dXJucyBvbmx5IGFmdGVyIHRoZSBDb3JvdXRpbmVQYXJzZXIgaGFzIGFja25vd2xlZGdlZCB0aGUgcmVxdWVzdC4KLSAgICoKLSAgICogQHBhcmFtIGFwcENvcm91dGluZUlEIFRoZSBjb3JvdXRpbmUgSUQgbnVtYmVyIG9mIHRoZSBjb3JvdXRpbmUgaW52b2tpbmcKLSAgICogdGhpcyBtZXRob2QsIHNvIGl0IGNhbiBiZSByZXN1bWVkIGFmdGVyIHRoZSBwYXJzZXIgaGFzIHJlc3BvbmRlZCB0byB0aGUKLSAgICogcmVxdWVzdC4KLSAgICogKi8KLSAgcHVibGljIHZvaWQgZG9UZXJtaW5hdGUoaW50IGFwcENvcm91dGluZUlEKQotICB7Ci0gICAgLy8gTm8tb3AgaW4gSW5jcmVtZW50YWxYZXJjZXM/Ci0KLSAgICAvLyBDb3VsZCByZWxlYXNlIHNvbWUgZGF0YSBzdHJ1Y3R1cmVzIHRvIHByb21vdGUgZ2FyYmFnZSBjb2xsZWN0aW9uLi4uCi0gICAgaW5jcmVtZW50YWxQYXJzZXI9bnVsbDsKLSAgfQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvKiogU2ltcGxlIHVuaXQgdGVzdC4gQXR0ZW1wdCBjb3JvdXRpbmUgcGFyc2luZyBvZiBkb2N1bWVudCBpbmRpY2F0ZWQKLSAgICogYnkgZmlyc3QgYXJndW1lbnQgKGFzIGEgVVJJKSwgcmVwb3J0IHByb2dyZXNzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3NbXSkKLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnRpbmcuLi4iKTsKLQotICAgIENvcm91dGluZU1hbmFnZXIgY28gPSBuZXcgQ29yb3V0aW5lTWFuYWdlcigpOwotICAgIGludCBhcHBDb3JvdXRpbmVJRCA9IGNvLmNvX2pvaW5Db3JvdXRpbmVTZXQoLTEpOwotICAgIGlmIChhcHBDb3JvdXRpbmVJRCA9PSAtMSkKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJFUlJPUjogQ291bGRuJ3QgYWxsb2NhdGUgY29yb3V0aW5lIG51bWJlci5cbiIpOwotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgQ29yb3V0aW5lU0FYUGFyc2VyX1hlcmNlcyBwYXJzZXI9Ci0gICAgICBuZXcgQ29yb3V0aW5lU0FYUGFyc2VyX1hlcmNlcyhjbywgYXBwQ29yb3V0aW5lSUQpOwotICAgIGludCBwYXJzZXJDb3JvdXRpbmVJRCA9IHBhcnNlci5nZXRQYXJzZXJDb3JvdXRpbmVJRCgpOwotCi0gICAgLy8gVXNlIGEgc2VyaWFsaXplciBhcyBvdXIgc2FtcGxlIG91dHB1dAotICAgIG9yZy5hcGFjaGUueG1sLnNlcmlhbGl6ZS5YTUxTZXJpYWxpemVyIHRyYWNlOwotICAgIHRyYWNlPW5ldyBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuWE1MU2VyaWFsaXplcihTeXN0ZW0ub3V0LG51bGwpOwotICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcih0cmFjZSk7Ci0gICAgcGFyc2VyLnNldExleEhhbmRsZXIodHJhY2UpOwotCi0gICAgLy8gVGVsbCBjb3JvdXRpbmUgdG8gYmVnaW4gcGFyc2luZywgcnVuIHdoaWxlIHBhcnNpbmcgaXMgaW4gcHJvZ3Jlc3MKLSAgICBmb3IoaW50IGFyZz0wO2FyZzxhcmdzLmxlbmd0aDsrK2FyZykKLSAgICAgIHsKLSAgICAgICAgSW5wdXRTb3VyY2Ugc291cmNlID0gbmV3IElucHV0U291cmNlKGFyZ3NbYXJnXSk7Ci0gICAgICAgIE9iamVjdCByZXN1bHQ9bnVsbDsKLSAgICAgICAgYm9vbGVhbiBtb3JlPXRydWU7Ci0gICAgICAgIC8qKiAgICAKLSAgICAgICAgICBmb3IocmVzdWx0ID0gY28uY29fcmVzdW1lKHNvdXJjZSwgYXBwQ29yb3V0aW5lSUQsIHBhcnNlckNvcm91dGluZUlEKTsKLSAgICAgICAgICAocmVzdWx0IGluc3RhbmNlb2YgQm9vbGVhbiAmJiAoKEJvb2xlYW4pcmVzdWx0KT09Qm9vbGVhbi5UUlVFKTsKLSAgICAgICAgICByZXN1bHQgPSBjby5jb19yZXN1bWUobW9yZSwgYXBwQ29yb3V0aW5lSUQsIHBhcnNlckNvcm91dGluZUlEKSkKLSAgICAgICAgICAqKi8KLSAgICAgICAgZm9yKHJlc3VsdCA9IHBhcnNlci5kb1BhcnNlKHNvdXJjZSwgYXBwQ29yb3V0aW5lSUQpOwotICAgICAgICAgICAgKHJlc3VsdCBpbnN0YW5jZW9mIEJvb2xlYW4gJiYgKChCb29sZWFuKXJlc3VsdCk9PUJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICByZXN1bHQgPSBwYXJzZXIuZG9Nb3JlKG1vcmUsIGFwcENvcm91dGluZUlEKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuU29tZSBwYXJzaW5nIHN1Y2Nlc3NmdWwsIHRyeWluZyBtb3JlLlxuIik7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vIFNwZWNpYWwgdGVzdDogVGVybWluYXRlIHBhcnNpbmcgZWFybHkuCi0gICAgICAgICAgICBpZihhcmcrMTxhcmdzLmxlbmd0aCAmJiAiISIuZXF1YWxzKGFyZ3NbYXJnKzFdKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICsrYXJnOwotICAgICAgICAgICAgICAgIG1vcmU9ZmFsc2U7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIAotICAgICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBCb29sZWFuICYmICgoQm9vbGVhbilyZXN1bHQpPT1Cb29sZWFuLkZBTFNFKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5QYXJzZXIgZW5kZWQgKEVPRiBvciBvbiByZXF1ZXN0KS5cbiIpOwotICAgICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocmVzdWx0ID09IG51bGwpIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuVU5FWFBFQ1RFRDogUGFyc2VyIHNheXMgc2h1dCBkb3duIHByZW1hdHVyZWx5LlxuIik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKChFeGNlcHRpb24pcmVzdWx0KTsKLS8vICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5QYXJzZXIgdGhyZXcgZXhjZXB0aW9uOiIpOwotLy8gICAgICAgICAgKChFeGNlcHRpb24pcmVzdWx0KS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgICAgfQotICAgICAgICAKLSAgICAgIH0KLQotICAgIHBhcnNlci5kb1Rlcm1pbmF0ZShhcHBDb3JvdXRpbmVJRCk7Ci0gIH0KLSAgCi19IC8vIGNsYXNzIENvcm91dGluZVNBWFBhcnNlcgpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvQ3VzdG9tU3RyaW5nUG9vbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvQ3VzdG9tU3RyaW5nUG9vbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5MjBiOWVkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0N1c3RvbVN0cmluZ1Bvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTksMjAwMCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotCi0vKiogPHA+Q3VzdG9tU3RyaW5nUG9vbCBpcyBhbiBleGFtcGxlIG9mIGFwcGxpY3Rpb24gcHJvdmlkZWQgZGF0YSBzdHJ1Y3R1cmUKLSAqIGZvciBhIERUTSBpbXBsZW1lbnRhdGlvbiB0byBob2xkIHN5bWJvbCByZWZlcmVuY2VzLCBlLmcuIGVsZWxtZW50IG5hbWVzLgotICogSXQgd2lsbCBmb2xsb3cgdGhlIERUTURTdHJpbmdQb29sIGludGVyZmFjZSBhbmQgdXNlIHR3byBzaW1wbGUgbWV0aG9kcwotICogaW5kZXhUb1N0cmluZyhpbnQgaSkgYW5kIHN0cmluZ1RvSW5kZXgoU3JpbmcgcykgdG8gbWFwIGJldHdlZW4gYSBzZXQgb2YKLSAqIHN0cmluZyB2YWx1ZXMgYW5kIGEgc2V0IG9mIGludGVnZXIgaW5kZXggdmFsdWVzLiAgVGhlcmVmb3JlLCBhbiBhcHBsaWNhdGlvbgotICogbWF5IGltcHJvdmUgRFRNIHByb2Nlc3Npbmcgc3BlZWQgYnkgc3Vic3RpdHV0aW5nIHRoZSBEVE0gc3ltYm9sIHJlc29sdXRpb24KLSAqIHRhYmxlcyB3aXRoIGFwcGxpY2F0aW9uIHNwZWNpZmljIHF1aWNrIHN5bWJvbCByZXNvbHV0aW9uIHRhYmxlcy48L3A+Ci0gKgotICogJVJFVklFVyUgVGhlIG9ubHkgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoaXMgYW4gRFRNU3RyaW5nUG9vbCBzZWVtcyB0byBiZSB0aGF0Ci0gKiBpdCB1c2VzIGEgamF2YS5sYW5nLkhhc2h0YWJsZSBmdWxsIG9mIEludGVnZXJzIHJhdGhlciB0aGFuIGltcGxlbWVudGluZyBpdHMKLSAqIG93biBoYXNoaW5nLiBKb2UgZGVsaWJlcmF0ZWx5IGF2b2lkZWQgdGhhdCBhcHByb2FjaCB3aGVuIHdyaXRpbmcKLSAqIERUTVN0cmluZ1Bvb2wsIHNpbmNlIGl0IGlzIGJvdGggbXVjaCBtb3JlIG1lbW9yeS1odW5ncnkgYW5kIHByb2JhYmx5IHNsb3dlcgotICogLS0gZXNwZWNpYWxseSBpbiBKREsgMS4xLngsIHdoZXJlIEhhc2h0YWJsZSBpcyBzeW5jaHJvbml6ZWQuIFdlIG5lZWQgdG8KLSAqIGVpdGhlciBqdXN0aWZ5IHRoaXMgaW1wbGVtZW50YXRpb24gb3IgZGlzY2FyZCBpdC4KLSAqCi0gKiA8cD5TdGF0dXM6IEluIHByb2dyZXNzLCB1bmRlciBkaXNjdXNzaW9uLjwvcD4KLSAqICovCi1wdWJsaWMgY2xhc3MgQ3VzdG9tU3RyaW5nUG9vbCBleHRlbmRzIERUTVN0cmluZ1Bvb2wgewotICAgICAgICAvL2ZpbmFsIFZlY3RvciBtX2ludFRvU3RyaW5nOwotICAgICAgICAvL3N0YXRpYyBmaW5hbCBpbnQgSEFTSFBSSU1FPTEwMTsKLSAgICAgICAgLy9pbnRbXSBtX2hhc2hTdGFydD1uZXcgaW50W0hBU0hQUklNRV07Ci0gICAgICAgIGZpbmFsIEhhc2h0YWJsZSBtX3N0cmluZ1RvSW50ID0gbmV3IEhhc2h0YWJsZSgpOwotICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVUxMPS0xOwotCi0gICAgICAgIHB1YmxpYyBDdXN0b21TdHJpbmdQb29sKCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIHN1cGVyKCk7Ci0gICAgICAgICAgICAgICAgLyptX2ludFRvU3RyaW5nPW5ldyBWZWN0b3IoKTsKLSAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluIGNvbnN0cnVjdG9yIG1faW50VG9TdHJpbmcgaXMgIiArIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKG51bGwgPT0gbV9pbnRUb1N0cmluZykgPyAibnVsbCIgOiAibm90IG51bGwiKSk7Ki8KLSAgICAgICAgICAgICAgICAvL21fc3RyaW5nVG9JbnQ9bmV3IEhhc2h0YWJsZSgpOwotICAgICAgICAgICAgICAgIC8vcmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG1faW50VG9TdHJpbmcucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgICAgICAgICAgICBpZiAobV9zdHJpbmdUb0ludCAhPSBudWxsKSAKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fc3RyaW5nVG9JbnQuY2xlYXIoKTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKiBAcmV0dXJuIHN0cmluZyB3aG9zZSB2YWx1ZSBpcyB1bmlxdWVseSBpZGVudGlmaWVkIGJ5IHRoaXMgaW50ZWdlciBpbmRleC4KLSAgICAgICAgICogQHRocm93cyBqYXZhLmxhbmcuQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCi0gICAgICAgICAqICBpZiBpbmRleCBkb2Vzbid0IG1hcCB0byBhIHN0cmluZy4KLSAgICAgICAgICogKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBpbmRleFRvU3RyaW5nKGludCBpKQotICAgICAgICB0aHJvd3MgamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuKFN0cmluZykgbV9pbnRUb1N0cmluZy5lbGVtZW50QXQoaSk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogQHJldHVybiBpbnRlZ2VyIGluZGV4IHVuaXF1ZWx5IGlkZW50aWZ5aW5nIHRoZSB2YWx1ZSBvZiB0aGlzIHN0cmluZy4gKi8KLSAgICAgICAgcHVibGljIGludCBzdHJpbmdUb0luZGV4KFN0cmluZyBzKQotICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKHM9PW51bGwpIHJldHVybiBOVUxMOwotICAgICAgICAgICAgICAgIEludGVnZXIgaW9iaj0oSW50ZWdlciltX3N0cmluZ1RvSW50LmdldChzKTsKLSAgICAgICAgICAgICAgICBpZiAoaW9iaj09bnVsbCkgewotICAgICAgICAgICAgICAgICAgICAgICAgbV9pbnRUb1N0cmluZy5hZGRFbGVtZW50KHMpOwotICAgICAgICAgICAgICAgICAgICAgICAgaW9iaj1uZXcgSW50ZWdlcihtX2ludFRvU3RyaW5nLnNpemUoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX3N0cmluZ1RvSW50LnB1dChzLGlvYmopOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gaW9iai5pbnRWYWx1ZSgpOwotICAgICAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1BeGlzSXRlcmF0b3JCYXNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1BeGlzSXRlcmF0b3JCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJkMjY2NjUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNQXhpc0l0ZXJhdG9yQmFzZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjkxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHNlcnZlcyBhcyBhIGRlZmF1bHQgYmFzZSBmb3IgaW1wbGVtZW50YXRpb25zIG9mIERUTUF4aXNJdGVyYXRvcnMuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEVE1BeGlzSXRlcmF0b3JCYXNlIGltcGxlbWVudHMgRFRNQXhpc0l0ZXJhdG9yCi17Ci0KLSAgLyoqIFRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBub2RlIHdpdGhpbiB0aGUgaXRlcmF0aW9uLCBhcyBkZWZpbmVkIGJ5IFhQYXRoLgotICAgKiBOb3RlIHRoYXQgdGhpcyBpcyBfbm90XyB0aGUgbm9kZSdzIGhhbmRsZSB3aXRoaW4gdGhlIERUTS4gQWxzbywgZG9uJ3QKLSAgICogY29uZnVzZSBpdCB3aXRoIHRoZSBjdXJyZW50IChtb3N0IHJlY2VudGx5IHJldHVybmVkKSBwb3NpdGlvbi4KLSAgICovCi0gIHByaXZhdGUgaW50IF9sYXN0ID0gLTE7Ci0KLSAgLyoqIFRoZSBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBub2RlIHdpdGhpbiB0aGUgaXRlcmF0aW9uLCBhcyBkZWZpbmVkIGJ5IFhQYXRoLgotICAgKiBOb3RlIHRoYXQgdGhpcyBpcyBfbm90XyB0aGUgbm9kZSdzIGhhbmRsZSB3aXRoaW4gdGhlIERUTSEKLSAgICovCi0gIHByaXZhdGUgaW50IF9wb3NpdGlvbiA9IDA7Ci0KLSAgLyoqIFRoZSBwb3NpdGlvbiBvZiB0aGUgbWFya2VkIG5vZGUgd2l0aGluIHRoZSBpdGVyYXRpb247Ci0gICAqIGEgc2F2ZWQgaXRhcmF0aW9uIHN0YXRlIHRoYXQgd2UgbWF5IHdhbnQgdG8gY29tZSBiYWNrIHRvLgotICAgKiBOb3RlIHRoYXQgb25seSBvbmUgbWFyayBpcyBtYWludGFpbmVkOyB0aGVyZSBpcyBubyBzdGFjay4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX21hcmtlZE5vZGU7Ci0KLSAgLyoqIFRoZSBoYW5kbGUgdG8gdGhlIHN0YXJ0LCBvciByb290LCBvZiB0aGUgaXRlcmF0aW9uLgotICAgKiBTZXQgdGhpcyB0byBFTkQgdG8gY29uc3RydWN0IGFuIGVtcHR5IGl0ZXJhdG9yLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfc3RhcnROb2RlID0gRFRNQXhpc0l0ZXJhdG9yLkVORDsKLQotICAvKiogVHJ1ZSBpZiB0aGUgc3RhcnQgbm9kZSBzaG91bGQgYmUgY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAqIEZhbHNlIHdpbGwgY2F1c2UgaXQgdG8gYmUgc2tpcHBlZC4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIF9pbmNsdWRlU2VsZiA9IGZhbHNlOwotCi0gIC8qKiBUcnVlIGlmIHRoaXMgaXRlcmF0aW9uIGNhbiBiZSByZXN0YXJ0ZWQuIEZhbHNlIG90aGVyd2lzZSAoZWcsIGlmCi0gICAqIHdlIGFyZSBpdGVyYXRpbmcgb3ZlciBhIHN0cmVhbSB0aGF0IGNhbiBub3QgYmUgcmUtc2Nhbm5lZCwgb3IgaWYKLSAgICogdGhlIGl0ZXJhdG9yIHdhcyBwcm9kdWNlZCBieSBjbG9uaW5nIGFub3RoZXIgaXRlcmF0b3IuKQotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gX2lzUmVzdGFydGFibGUgPSB0cnVlOwotICAKLSAgLyoqCi0gICAqIEdldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJvb3Qgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRTdGFydE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIF9zdGFydE5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciB3aGljaCBoYXMgYmVlbiByZXNldCB0byB0aGUgc3RhcnQgbm9kZSwKLSAgICogd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhpcyBpdGVyYXRvci4KLSAgICogKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpCi0gIHsKLQotICAgIGZpbmFsIGJvb2xlYW4gdGVtcCA9IF9pc1Jlc3RhcnRhYmxlOwotCi0gICAgX2lzUmVzdGFydGFibGUgPSB0cnVlOwotCi0gICAgc2V0U3RhcnROb2RlKF9zdGFydE5vZGUpOwotCi0gICAgX2lzUmVzdGFydGFibGUgPSB0ZW1wOwotCi0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBmbGFnIHRvIGluY2x1ZGUgdGhlIHN0YXJ0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4gCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBkZWZhdWx0IG1ldGhvZCByZXR1cm5zIGp1c3QgcmV0dXJucyB0aGlzIERUTUF4aXNJdGVyYXRvciwKLSAgICogYWZ0ZXIgc2V0dGluZyB0aGUgZmxhZy4KLSAgICogKFJldHVybmluZyAidGhpcyIgcGVybWl0cyBDKystc3R5bGUgY2hhaW5pbmcgb2YKLSAgICogbWV0aG9kIGNhbGxzIGludG8gYSBzaW5nbGUgZXhwcmVzc2lvbi4pCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGluY2x1ZGVTZWxmKCkKLSAgewotCi0gICAgX2luY2x1ZGVTZWxmID0gdHJ1ZTsKLQotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIHRoZSBsYXN0IG5vZGUgd2l0aGluIHRoZSBpdGVyYXRpb24sIGFzCi0gICAqIGRlZmluZWQgYnkgWFBhdGguICBJbiBhIGZvcndhcmQgaXRlcmF0b3IsIEkgYmVsaWV2ZSB0aGlzIGVxdWFscyB0aGUgbnVtYmVyIG9mIG5vZGVzIHdoaWNoIHRoaXMKLSAgICogaXRlcmF0b3Igd2lsbCB5aWVsZC4gSW4gYSByZXZlcnNlIGl0ZXJhdG9yLCBJIGJlbGlldmUgaXQgc2hvdWxkIHJldHVybgotICAgKiAxIChzaW5jZSB0aGUgImxhc3QiIGlzIHRoZSBmaXJzdCBwcm9kdWNlZC4pCi0gICAqCi0gICAqIFRoaXMgbWF5IGJlIGFuIGV4cGVuc2l2ZSBvcGVyYXRpb24gd2hlbiBjYWxsZWQgdGhlIGZpcnN0IHRpbWUsIHNpbmNlCi0gICAqIGl0IG1heSBoYXZlIHRvIGl0ZXJhdGUgdGhyb3VnaCBhIGxhcmdlIHBhcnQgb2YgdGhlIGRvY3VtZW50IHRvIHByb2R1Y2UKLSAgICogaXRzIGFuc3dlci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgaXRlcmF0b3IgKGZvcndhcmQpIG9yIDEgKHJldmVyc2UpLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0KCkKLSAgewotCi0gICAgaWYgKF9sYXN0ID09IC0xKQkJLy8gTm90IHByZXZpb3VzbHkgZXN0YWJsaXNoZWQKLSAgICB7Ci0gICAgICAvLyBOb3RlIHRoYXQgd2UncmUgZG9pbmcgYm90aCBzZXRNYXJrKCkgLS0gd2hpY2ggc2F2ZXMgX2N1cnJlbnRDaGlsZAotICAgICAgLy8gLS0gYW5kIGV4cGxpY2l0bHkgc2F2aW5nIG91ciBwb3NpdGlvbiBjb3VudGVyIChudW1iZXIgb2Ygbm9kZXMKLSAgICAgIC8vIHlpZWxkZWQgc28gZmFyKS4KLSAgICAgIC8vCi0gICAgICAvLyAlUkVWSUVXJSBTaG91bGQgcG9zaXRpb24gYWxzbyBiZSBzYXZlZCBieSBzZXRNYXJrKCk/Ci0gICAgICAvLyAoSXQgd2Fzbid0IGluIHRoZSBYU0xUQyB2ZXJzaW9uLCBidXQgSSBkb24ndCB1bmRlcnN0YW5kIHdoeSBub3QuKQotCi0gICAgICBmaW5hbCBpbnQgdGVtcCA9IF9wb3NpdGlvbjsgLy8gU2F2ZSBzdGF0ZQotICAgICAgc2V0TWFyaygpOwotCi0gICAgICByZXNldCgpOwkJCS8vIENvdW50IHRoZSBub2RlcyBmb3VuZCBieSB0aGlzIGl0ZXJhdG9yCi0gICAgICBkbwotICAgICAgewotICAgICAgICBfbGFzdCsrOwotICAgICAgfQotICAgICAgd2hpbGUgKG5leHQoKSAhPSBFTkQpOwotCi0gICAgICBnb3RvTWFyaygpOwkJLy8gUmVzdG9yZSBzYXZlZCBzdGF0ZQotICAgICAgX3Bvc2l0aW9uID0gdGVtcDsKLSAgICB9Ci0KLSAgICByZXR1cm4gX2xhc3Q7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgbm9kZSB3aXRoaW4gdGhlIHNldCwgYXMgZGVmaW5lZCBieQotICAgKiBYUGF0aC4gTm90ZSB0aGF0IHRoaXMgaXMgb25lLWJhc2VkLCBub3QgemVyby1iYXNlZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oKQotICB7Ci0gICAgcmV0dXJuIF9wb3NpdGlvbiA9PSAwID8gMSA6IF9wb3NpdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpdGVyYXRvciBoYXMgYSByZXZlcnNlZCBheGlzLCBlbHNlIGZhbHNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gQ2xvbmVkIGl0ZXJhdG9ycyBtYXkgbm90IGJlCi0gICAqIHJlc3RhcnRhYmxlLiBUaGUgaXRlcmF0b3IgYmVpbmcgY2xvbmVkIG1heSBvciBtYXkgbm90IGJlY29tZQotICAgKiBub24tcmVzdGFydGFibGUgYXMgYSBzaWRlIGVmZmVjdCBvZiB0aGlzIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBhIGRlZXAgY29weSBvZiB0aGlzIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBjbG9uZUl0ZXJhdG9yKCkKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZmluYWwgRFRNQXhpc0l0ZXJhdG9yQmFzZSBjbG9uZSA9IChEVE1BeGlzSXRlcmF0b3JCYXNlKSBzdXBlci5jbG9uZSgpOwotCi0gICAgICAvLyBjbG9uZS5faXNSZXN0YXJ0YWJsZSA9IGZhbHNlOwotCi0gICAgICAvLyByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgIHJldHVybiBjbG9uZTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEbyBhbnkgZmluYWwgY2xlYW51cCB0aGF0IGlzIHJlcXVpcmVkIGJlZm9yZSByZXR1cm5pbmcgdGhlIG5vZGUgdGhhdCB3YXMKLSAgICogcGFzc2VkIGluLCBhbmQgdGhlbiByZXR1cm4gaXQuIFRoZSBpbnRlbmRlZCB1c2UgaXMKLSAgICogPGJyIC8+Ci0gICAqIDxjb2RlPnJldHVybiByZXR1cm5Ob2RlKG5vZGUpOzwvY29kZT4KLSAgICoKLSAgICogJVJFVklFVyUgSWYgd2UncmUgY2FsbGluZyBpdCBwdXJlbHkgZm9yIHNpZGUgZWZmZWN0cywgc2hvdWxkIHdlIHJlYWxseQotICAgKiBiZSBib3RoZXJpbmcgd2l0aCBhIHJldHVybiB2YWx1ZT8gU29tZXRoaW5nIGxpa2UKLSAgICogPGJyIC8+Ci0gICAqIDxjb2RlPiBhY2NlcHQobm9kZSk7IHJldHVybiBub2RlOyA8L2NvZGU+Ci0gICAqIDxiciAvPgotICAgKiB3b3VsZCBwcm9iYWJseSBvcHRpbWl6ZSBqdXN0IGFib3V0IGFzIHdlbGwgYW5kIGF2b2lkIHF1ZXN0aW9ucwotICAgKiBhYm91dCB3aGV0aGVyIHdoYXQncyByZXR1cm5lZCBjb3VsZCBldmVyIGJlIGRpZmZlcmVudCBmcm9tIHdoYXQncwotICAgKiBwYXNzZWQgaW4uCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgaGFuZGxlIHdoaWNoIGl0ZXJhdGlvbiBpcyBhYm91dCB0byB5aWVsZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBoYW5kbGUgcGFzc2VkIGluLiAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIGludCByZXR1cm5Ob2RlKGZpbmFsIGludCBub2RlKQotICB7Ci0gICAgX3Bvc2l0aW9uKys7Ci0KLSAgICByZXR1cm4gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgcG9zaXRpb24gdG8gemVyby4gTk9URSB0aGF0IHRoaXMgZG9lcyBub3QgY2hhbmdlIHRoZSBpdGVyYXRpb24KLSAgICogc3RhdGUsIG9ubHkgdGhlIHBvc2l0aW9uIG51bWJlciBhc3NvY2lhdGVkIHdpdGggdGhhdCBzdGF0ZS4KLSAgICoKLSAgICogJVJFVklFVyUgRG9jdW1lbnQgd2hlbiB0aGlzIHdvdWxkIGJlIHVzZWQ/Ci0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBpbnN0YW5jZS4KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBEVE1BeGlzSXRlcmF0b3IgcmVzZXRQb3NpdGlvbigpCi0gIHsKLQotICAgIF9wb3NpdGlvbiA9IDA7Ci0KLSAgICByZXR1cm4gdGhpczsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudCAKLSAgICogb3JkZXIuCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgYXMgYSBkZWZhdWx0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2NPcmRlcmVkKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqIAotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZSAKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIC0xOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZTQwZTQwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMDM5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3ViYWxsb2NhdGVkSW50VmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN1YmFsbG9jYXRlZEJ5dGVWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuSW50U3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuQm9vbFN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ0J1ZmZlclBvb2w7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlVmVjdG9yOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLQotaW1wb3J0IGphdmEuaW8uKjsgLy8gZm9yIGR1bXBEVE0KLQotLyoqCi0gKiBUaGUgPGNvZGU+RFRNRGVmYXVsdEJhc2U8L2NvZGU+IGNsYXNzIHNlcnZlcyBhcyBhIGhlbHBlciBiYXNlIGZvciBEVE1zLgotICogSXQgc2V0cyB1cCBzdHJ1Y3R1cmVzIGZvciBuYXZpZ2F0aW9uIGFuZCB0eXBlLCB3aGlsZSBsZWF2aW5nIGRhdGEKLSAqIG1hbmFnZW1lbnQgYW5kIGNvbnN0cnVjdGlvbiB0byB0aGUgZGVyaXZlZCBjbGFzc2VzLgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgRFRNRGVmYXVsdEJhc2UgaW1wbGVtZW50cyBEVE0KLXsKLSAgLyoqCi0gICAqIFRoZSBudW1iZXIgb2Ygbm9kZXMsIHdoaWNoIGlzIGFsc28gdXNlZCB0byBkZXRlcm1pbmUgdGhlIG5leHQKLSAgICogIG5vZGUgaW5kZXguCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IG1fc2l6ZSA9IDA7Ci0KLSAgLyoqIFRoZSBleHBhbmRlZCBuYW1lcywgb25lIGFycmF5IGVsZW1lbnQgZm9yIGVhY2ggbm9kZS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2V4cHR5cGU7Ci0KLSAgLyoqIEZpcnN0IGNoaWxkIHZhbHVlcywgb25lIGFycmF5IGVsZW1lbnQgZm9yIGVhY2ggbm9kZS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2ZpcnN0Y2g7Ci0KLSAgLyoqIE5leHQgc2libGluZyB2YWx1ZXMsIG9uZSBhcnJheSBlbGVtZW50IGZvciBlYWNoIG5vZGUuICovCi0gIHByb3RlY3RlZCBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbV9uZXh0c2liOwotCi0gIC8qKiBQcmV2aW91cyBzaWJsaW5nIHZhbHVlcywgb25lIGFycmF5IGVsZW1lbnQgZm9yIGVhY2ggbm9kZS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX3ByZXZzaWI7Ci0KLSAgLyoqIFByZXZpb3VzIHNpYmxpbmcgdmFsdWVzLCBvbmUgYXJyYXkgZWxlbWVudCBmb3IgZWFjaCBub2RlLiAqLwotICBwcm90ZWN0ZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG1fcGFyZW50OwotCi0gIC8qKiBFeHBlcmVtZW50YWwuICAtc2IgKi8KLS8vICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2hhdmVTZWVuTmFtZXNwYWNlID0gZmFsc2U7Ci0KLSAgLyoqIFZlY3RvciBvZiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3JzIG9mIE5TIGRlY2wgc2V0cyAgLWpqayAqLwotICBwcm90ZWN0ZWQgVmVjdG9yIG1fbmFtZXNwYWNlRGVjbFNldHMgPSBudWxsOwotCi0gIC8qKiBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgIG9mIGVsZW1lbnRzIGF0IHdoaWNoIGNvcnJlc3BvbmRpbmcKLSAgICogbmFtZXNwYWNlRGVjbFNldHMgd2VyZSBkZWZpbmVkIC1qamsgKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cyA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIFRoZXNlIGhvbGQgaW5kZXhlcyB0byBlbGVtZW50cyBiYXNlZCBvbiBuYW1lc3BhY2UgYW5kIGxvY2FsIG5hbWUuCi0gICAqIFRoZSBiYXNlIGxvb2t1cCBpcyB0aGUgdGhlIG5hbWVzcGFjZS4gIFRoZSBzZWNvbmQgbG9va3VwIGlzIHRoZSBsb2NhbAotICAgKiBuYW1lLCBhbmQgdGhlIGxhc3QgYXJyYXkgY29udGFpbnMgdGhlIHRoZSBmaXJzdCBmcmVlIGVsZW1lbnQKLSAgICogYXQgdGhlIHN0YXJ0LCBhbmQgdGhlIGxpc3Qgb2YgZWxlbWVudCBoYW5kbGVzIGZvbGxvd2luZy4KLSAgICovCi0gIHByb3RlY3RlZCBpbnRbXVtdW10gbV9lbGVtSW5kZXhlczsKLQotICAvKiogVGhlIGRlZmF1bHQgaW5pdGlhbCBibG9jayBzaXplIG9mIHRoZSBub2RlIGFycmF5cyAqLwotICBwcm90ZWN0ZWQgaW50IG1faW5pdGlhbGJsb2Nrc2l6ZSA9IDUxMjsgIC8vIGZhdm9yIHNtYWxsIGRvY3MuCi0KLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemUgPSAyICogMTAyNDsKLQotICAvKioKLSAgICogVGhlIHZhbHVlIHRvIHVzZSB3aGVuIHRoZSBpbmZvcm1hdGlvbiBoYXMgbm90IGJlZW4gYnVpbHQgeWV0LgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTk9UUFJPQ0VTU0VEID0gRFRNLk5VTEwgLSAxOwotCi0gIC8qKgotICAgKiBUaGUgRFRNIG1hbmFnZXIgd2hvICJvd25zIiB0aGlzIERUTS4KLSAgICovCi0gIHByb3RlY3RlZCBEVE1NYW5hZ2VyIG1fbWdyOwotCi0gIC8qKiBUaGUgZG9jdW1lbnQgaWRlbnRpdHksIHdoaWNoIGlzIE9SJ2Qgd2l0aCBub2RlIGluZGV4ZXMgdG8gbWFrZSBoYW5kbGVzLiAqLwotICBwcm90ZWN0ZWQgaW50IG1fZHRtSWRlbnQ7Ci0KLSAgLyoqIFRoZSBtYXNrIGZvciB0aGUgaWRlbnRpdHkuCi0gICAgICAlUkVWSUVXJSBTaG91bGQgdGhpcyByZWFsbHkgYmUgc2V0IHRvIHRoZSBfREVGQVVMVD8gV2hhdCBpZgotICAgICAgYSBwYXJ0aWN1bGFyIERUTSB3YW50ZWQgdG8gdXNlIGFub3RoZXIgdmFsdWU/ICovCi0gIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgaW50IG1fbWFzayA9IERUTU1hbmFnZXIuSURFTlRfTk9ERV9ERUZBVUxUOwotCi0gIC8qKiBUaGUgYmFzZSBVUkkgZm9yIHRoaXMgZG9jdW1lbnQuICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9kb2N1bWVudEJhc2VVUkk7Ci0KLSAgLyoqCi0gICAqIFRoZSB3aGl0ZXNwYWNlIGZpbHRlciB0aGF0IGVuYWJsZXMgZWxlbWVudHMgdG8gc3RyaXAgd2hpdGVzcGFjZSBvciBub3QuCi0gICAqLwotICBwcm90ZWN0ZWQgRFRNV1NGaWx0ZXIgbV93c2ZpbHRlcjsKLQotICAvKiogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gc3RyaXAgd2hpdGVzcGFjZSBub2RlcyAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX3Nob3VsZFN0cmlwV1MgPSBmYWxzZTsKLQotICAvKiogU3RhY2sgb2YgZmxhZ3MgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHN0cmlwIHdoaXRlc3BhY2Ugbm9kZXMgKi8KLSAgcHJvdGVjdGVkIEJvb2xTdGFjayBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrOwotCi0gIC8qKiBUaGUgWE1MU3RyaW5nIGZhY3RvcnkgZm9yIGNyZWF0aW5nIFhNTFN0cmluZ3MuICovCi0gIHByb3RlY3RlZCBYTUxTdHJpbmdGYWN0b3J5IG1feHN0cmY7Ci0KLSAgLyoqIFRoZSBpZGVudGl0eSBvZiB0aGUgcm9vdCBub2RlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST09UTk9ERSA9IDA7Ci0KLSAgLyoqCi0gICAqIFRoZSB0YWJsZSBmb3IgZXhhbmRlZE5hbWVJRCBsb29rdXBzLiAgVGhpcyBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZQotICAgKiB0YWJsZSBhcyBpcyBjb250YWluZWQgaW4gdGhlIERUTU1hbmFnZXJEZWZhdWx0LgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cGFuZGVkTmFtZVRhYmxlIG1fZXhwYW5kZWROYW1lVGFibGU7Ci0KLSAgLyoqIHRydWUgaWYgaW5kZXhpbmcgaXMgdHVybmVkIG9uLiAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2luZGV4aW5nOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBEVE1EZWZhdWx0QmFzZSBvYmplY3QgZnJvbSBhIERPTSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbWdyIFRoZSBEVE1NYW5hZ2VyIHdobyBvd25zIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gZG9tU291cmNlIHRoZSBET00gc291cmNlIHRoYXQgdGhpcyBEVE0gd2lsbCB3cmFwLgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBvYmplY3QgdGhhdCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIGNvbnN0cnVjdGlvbiBzb3VyY2UuCi0gICAqIEBwYXJhbSBkdG1JZGVudGl0eSBUaGUgRFRNIGlkZW50aXR5IElEIGZvciB0aGlzIERUTS4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgVGhlIHdoaXRlIHNwYWNlIGZpbHRlciBmb3IgdGhpcyBEVE0sIHdoaWNoIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0geHN0cmluZ2ZhY3RvcnkgVGhlIGZhY3RvcnkgdG8gdXNlIGZvciBjcmVhdGluZyBYTUxTdHJpbmdzLgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZQotICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgKi8KLSAgcHVibGljIERUTURlZmF1bHRCYXNlKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLCBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nRmFjdG9yeSB4c3RyaW5nZmFjdG9yeSwgYm9vbGVhbiBkb0luZGV4aW5nKQotICB7Ci0gICAgaWYoZmFsc2UgPT0gZG9JbmRleGluZykKLSAgICB7Ci0gICAgICBtX2luaXRpYWxibG9ja3NpemUgPSA4OwotICAgICAgbV9ibG9ja3NpemUgPSAxNjsKLSAgICB9Ci0KLSAgICBtX2V4cHR5cGUgPSBuZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKG1faW5pdGlhbGJsb2Nrc2l6ZSk7Ci0gICAgbV9maXJzdGNoID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3RvcihtX2luaXRpYWxibG9ja3NpemUpOwotICAgIG1fbmV4dHNpYiA9IG5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IobV9pbml0aWFsYmxvY2tzaXplKTsKLSAgICBtX3ByZXZzaWIgPSBuZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKG1faW5pdGlhbGJsb2Nrc2l6ZSk7Ci0gICAgbV9wYXJlbnQgPSBuZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKG1faW5pdGlhbGJsb2Nrc2l6ZSk7Ci0KLSAgICBtX21nciA9IG1ncjsKLSAgICBtX2RvY3VtZW50QmFzZVVSSSA9IChudWxsICE9IHNvdXJjZSkgPyBzb3VyY2UuZ2V0U3lzdGVtSWQoKSA6IG51bGw7Ci0gICAgbV9kdG1JZGVudCA9IGR0bUlkZW50aXR5OwotICAgIC8vIG1fbWFzayA9IG1nci5nZXROb2RlSWRlbnRpdHlNYXNrKCk7Ci0gICAgbV93c2ZpbHRlciA9IHdoaXRlU3BhY2VGaWx0ZXI7Ci0gICAgbV94c3RyZiA9IHhzdHJpbmdmYWN0b3J5OwotICAgIG1faW5kZXhpbmcgPSBkb0luZGV4aW5nOwotCi0gICAgaWYgKGRvSW5kZXhpbmcpCi0gICAgewotICAgICAgbV9leHBhbmRlZE5hbWVUYWJsZSA9IG5ldyBFeHBhbmRlZE5hbWVUYWJsZSgpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyAlUkVWSUVXJSBJcyB0aGVyZSBhIGJldHRlciB3YXkgdG8gZG8gdGhpcz8KLSAgICAgIERUTU1hbmFnZXJEZWZhdWx0IGRtZCA9IChEVE1NYW5hZ2VyRGVmYXVsdCkgbV9tZ3I7Ci0KLSAgICAgIG1fZXhwYW5kZWROYW1lVGFibGUgPSBkbWQuZ2V0RXhwYW5kZWROYW1lVGFibGUodGhpcyk7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gd2hpdGVTcGFjZUZpbHRlcikKLSAgICB7Ci0gICAgICBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrID0gbmV3IEJvb2xTdGFjaygpOwotCi0gICAgICBwdXNoU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKGZhbHNlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRW5zdXJlIHRoYXQgdGhlIHNpemUgb2YgdGhlIGVsZW1lbnQgaW5kZXhlcyBjYW4gaG9sZCB0aGUgaW5mb3JtYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VJRCBOYW1lc3BhY2UgSUQgaW5kZXguCi0gICAqIEBwYXJhbSBMb2NhbE5hbWVJRCBMb2NhbCBuYW1lIElELgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZW5zdXJlU2l6ZU9mSW5kZXgoaW50IG5hbWVzcGFjZUlELCBpbnQgTG9jYWxOYW1lSUQpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fZWxlbUluZGV4ZXMpCi0gICAgewotICAgICAgbV9lbGVtSW5kZXhlcyA9IG5ldyBpbnRbbmFtZXNwYWNlSUQgKyAyMF1bXVtdOwotICAgIH0KLSAgICBlbHNlIGlmIChtX2VsZW1JbmRleGVzLmxlbmd0aCA8PSBuYW1lc3BhY2VJRCkKLSAgICB7Ci0gICAgICBpbnRbXVtdW10gaW5kZXhlcyA9IG1fZWxlbUluZGV4ZXM7Ci0KLSAgICAgIG1fZWxlbUluZGV4ZXMgPSBuZXcgaW50W25hbWVzcGFjZUlEICsgMjBdW11bXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShpbmRleGVzLCAwLCBtX2VsZW1JbmRleGVzLCAwLCBpbmRleGVzLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgaW50W11bXSBsb2NhbE5hbWVJbmRleCA9IG1fZWxlbUluZGV4ZXNbbmFtZXNwYWNlSURdOwotCi0gICAgaWYgKG51bGwgPT0gbG9jYWxOYW1lSW5kZXgpCi0gICAgewotICAgICAgbG9jYWxOYW1lSW5kZXggPSBuZXcgaW50W0xvY2FsTmFtZUlEICsgMTAwXVtdOwotICAgICAgbV9lbGVtSW5kZXhlc1tuYW1lc3BhY2VJRF0gPSBsb2NhbE5hbWVJbmRleDsKLSAgICB9Ci0gICAgZWxzZSBpZiAobG9jYWxOYW1lSW5kZXgubGVuZ3RoIDw9IExvY2FsTmFtZUlEKQotICAgIHsKLSAgICAgIGludFtdW10gaW5kZXhlcyA9IGxvY2FsTmFtZUluZGV4OwotCi0gICAgICBsb2NhbE5hbWVJbmRleCA9IG5ldyBpbnRbTG9jYWxOYW1lSUQgKyAxMDBdW107Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoaW5kZXhlcywgMCwgbG9jYWxOYW1lSW5kZXgsIDAsIGluZGV4ZXMubGVuZ3RoKTsKLQotICAgICAgbV9lbGVtSW5kZXhlc1tuYW1lc3BhY2VJRF0gPSBsb2NhbE5hbWVJbmRleDsKLSAgICB9Ci0KLSAgICBpbnRbXSBlbGVtSGFuZGxlcyA9IGxvY2FsTmFtZUluZGV4W0xvY2FsTmFtZUlEXTsKLQotICAgIGlmIChudWxsID09IGVsZW1IYW5kbGVzKQotICAgIHsKLSAgICAgIGVsZW1IYW5kbGVzID0gbmV3IGludFsxMjhdOwotICAgICAgbG9jYWxOYW1lSW5kZXhbTG9jYWxOYW1lSURdID0gZWxlbUhhbmRsZXM7Ci0gICAgICBlbGVtSGFuZGxlc1swXSA9IDE7Ci0gICAgfQotICAgIGVsc2UgaWYgKGVsZW1IYW5kbGVzLmxlbmd0aCA8PSBlbGVtSGFuZGxlc1swXSArIDEpCi0gICAgewotICAgICAgaW50W10gaW5kZXhlcyA9IGVsZW1IYW5kbGVzOwotCi0gICAgICBlbGVtSGFuZGxlcyA9IG5ldyBpbnRbZWxlbUhhbmRsZXNbMF0gKyAxMDI0XTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShpbmRleGVzLCAwLCBlbGVtSGFuZGxlcywgMCwgaW5kZXhlcy5sZW5ndGgpOwotCi0gICAgICBsb2NhbE5hbWVJbmRleFtMb2NhbE5hbWVJRF0gPSBlbGVtSGFuZGxlczsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbm9kZSB0byB0aGUgZWxlbWVudCBpbmRleGVzLiBUaGUgbm9kZSB3aWxsIG5vdCBiZSBhZGRlZCB1bmxlc3MKLSAgICogaXQncyBhbiBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gZXhwYW5kZWRUeXBlSUQgVGhlIGV4cGFuZGVkIHR5cGUgSUQgb2YgdGhlIG5vZGUuCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eSBpbmRleC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGluZGV4Tm9kZShpbnQgZXhwYW5kZWRUeXBlSUQsIGludCBpZGVudGl0eSkKLSAgewotCi0gICAgRXhwYW5kZWROYW1lVGFibGUgZW50ID0gbV9leHBhbmRlZE5hbWVUYWJsZTsKLSAgICBzaG9ydCB0eXBlID0gZW50LmdldFR5cGUoZXhwYW5kZWRUeXBlSUQpOwotCi0gICAgaWYgKERUTS5FTEVNRU5UX05PREUgPT0gdHlwZSkKLSAgICB7Ci0gICAgICBpbnQgbmFtZXNwYWNlSUQgPSBlbnQuZ2V0TmFtZXNwYWNlSUQoZXhwYW5kZWRUeXBlSUQpOwotICAgICAgaW50IGxvY2FsTmFtZUlEID0gZW50LmdldExvY2FsTmFtZUlEKGV4cGFuZGVkVHlwZUlEKTsKLQotICAgICAgZW5zdXJlU2l6ZU9mSW5kZXgobmFtZXNwYWNlSUQsIGxvY2FsTmFtZUlEKTsKLQotICAgICAgaW50W10gaW5kZXggPSBtX2VsZW1JbmRleGVzW25hbWVzcGFjZUlEXVtsb2NhbE5hbWVJRF07Ci0KLSAgICAgIGluZGV4W2luZGV4WzBdXSA9IGlkZW50aXR5OwotCi0gICAgICBpbmRleFswXSsrOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIHRoZSBmaXJzdCBpbmRleCB0aGF0IG9jY3VycyBpbiB0aGUgbGlzdCB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvcgotICAgKiBlcXVhbCB0byB0aGUgZ2l2ZW4gdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBsaXN0IEEgbGlzdCBvZiBpbnRlZ2Vycy4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBpbmRleCB0byBiZWdpbiB0aGUgc2VhcmNoLgotICAgKiBAcGFyYW0gbGVuIFRoZSBudW1iZXIgb2YgaXRlbXMgdG8gc2VhcmNoLgotICAgKiBAcGFyYW0gdmFsdWUgRmluZCB0aGUgc2xvdCB0aGF0IGhhcyBhIHZhbHVlIHRoYXQgaXMgZ3JlYXRlciB0aGFuIG9yCi0gICAqIGlkZW50aWNhbCB0byB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCBpbiB0aGUgbGlzdCBvZiB0aGUgc2xvdCB0aGF0IGlzIGhpZ2hlciBvciBpZGVudGljYWwKLSAgICogdG8gdGhlIGlkZW50aXR5IGFyZ3VtZW50LCBvciAtMSBpZiBubyBub2RlIGlzIGhpZ2hlciBvciBlcXVhbC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZmluZEdURShpbnRbXSBsaXN0LCBpbnQgc3RhcnQsIGludCBsZW4sIGludCB2YWx1ZSkKLSAgewotCi0gICAgaW50IGxvdyA9IHN0YXJ0OwotICAgIGludCBoaWdoID0gc3RhcnQgKyAobGVuIC0gMSk7Ci0gICAgaW50IGVuZCA9IGhpZ2g7Ci0KLSAgICB3aGlsZSAobG93IDw9IGhpZ2gpCi0gICAgewotICAgICAgaW50IG1pZCA9IChsb3cgKyBoaWdoKSAvIDI7Ci0gICAgICBpbnQgYyA9IGxpc3RbbWlkXTsKLQotICAgICAgaWYgKGMgPiB2YWx1ZSkKLSAgICAgICAgaGlnaCA9IG1pZCAtIDE7Ci0gICAgICBlbHNlIGlmIChjIDwgdmFsdWUpCi0gICAgICAgIGxvdyA9IG1pZCArIDE7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBtaWQ7Ci0gICAgfQotCi0gICAgcmV0dXJuIChsb3cgPD0gZW5kICYmIGxpc3RbbG93XSA+IHZhbHVlKSA/IGxvdyA6IC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmQgdGhlIGZpcnN0IG1hdGNoaW5nIGVsZW1lbnQgZnJvbSB0aGUgaW5kZXggYXQgb3IgYWZ0ZXIgdGhlCi0gICAqIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBuc0luZGV4IFRoZSBuYW1lc3BhY2UgaW5kZXggbG9va3VwLgotICAgKiBAcGFyYW0gbG5JbmRleCBUaGUgbG9jYWwgbmFtZSBpbmRleCBsb29rdXAuCi0gICAqIEBwYXJhbSBmaXJzdFBvdGVudGlhbCBUaGUgZmlyc3QgcG90ZW50aWFsIG1hdGNoIHRoYXQgaXMgd29ydGggbG9va2luZyBhdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmlyc3Qgbm9kZSB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUKLSAgICogICAgICAgICBmaXJzdFBvdGVudGlhbCBhcmd1bWVudCwgb3IgRFRNLk5PVFBST0NFU1NFRCBpZiBub3QgZm91bmQuCi0gICAqLwotICBpbnQgZmluZEVsZW1lbnRGcm9tSW5kZXgoaW50IG5zSW5kZXgsIGludCBsbkluZGV4LCBpbnQgZmlyc3RQb3RlbnRpYWwpCi0gIHsKLQotICAgIGludFtdW11bXSBpbmRleGVzID0gbV9lbGVtSW5kZXhlczsKLQotICAgIGlmIChudWxsICE9IGluZGV4ZXMgJiYgbnNJbmRleCA8IGluZGV4ZXMubGVuZ3RoKQotICAgIHsKLSAgICAgIGludFtdW10gbG5JbmRleHMgPSBpbmRleGVzW25zSW5kZXhdOwotCi0gICAgICBpZiAobnVsbCAhPSBsbkluZGV4cyAmJiBsbkluZGV4IDwgbG5JbmRleHMubGVuZ3RoKQotICAgICAgewotICAgICAgICBpbnRbXSBlbGVtcyA9IGxuSW5kZXhzW2xuSW5kZXhdOwotCi0gICAgICAgIGlmIChudWxsICE9IGVsZW1zKQotICAgICAgICB7Ci0gICAgICAgICAgaW50IHBvcyA9IGZpbmRHVEUoZWxlbXMsIDEsIGVsZW1zWzBdLCBmaXJzdFBvdGVudGlhbCk7Ci0KLSAgICAgICAgICBpZiAocG9zID4gLTEpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGVsZW1zW3Bvc107Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIE5PVFBST0NFU1NFRDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpZGVudGl0eSB2YWx1ZSBpbiB0aGUgbGlzdCwgYW5kIGNhbGwgdGhlIGl0ZXJhdG9yCi0gICAqIGlmIGl0IGhhc24ndCBiZWVuIGFkZGVkIHlldC4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5IChpbmRleCkuCi0gICAqIEByZXR1cm4gaWRlbnRpdHkrMSwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW50IGdldE5leHROb2RlSWRlbnRpdHkoaW50IGlkZW50aXR5KTsKLQotICAvKioKLSAgICogVGhpcyBtZXRob2Qgc2hvdWxkIHRyeSBhbmQgYnVpbGQgb25lIG9yIG1vcmUgbm9kZXMgaW4gdGhlIHRhYmxlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0cnVlIGlmIGEgbmV4dCBub2RlIGlzIGZvdW5kIG9yIGZhbHNlIGlmCi0gICAqICAgICAgICAgdGhlcmUgYXJlIG5vIG1vcmUgbm9kZXMuCi0gICAqLwotICBwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBuZXh0Tm9kZSgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiBub2RlcyB0aGF0IGhhdmUgYmVlbiBhZGRlZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIG5vZGVzIHRoYXQgaGF2ZSBiZWVuIG1hcHBlZC4KLSAgICovCi0gIHByb3RlY3RlZCBhYnN0cmFjdCBpbnQgZ2V0TnVtYmVyT2ZOb2RlcygpOwotCi0gIC8qKiBTdGF0ZWxlc3MgYXhpcyB0cmF2ZXJzZXJzLCBsYXplbHkgYnVpbHQuICovCi0gIHByb3RlY3RlZCBEVE1BeGlzVHJhdmVyc2VyW10gbV90cmF2ZXJzZXJzOwotCi0vLyAgICAvKioKLS8vICAgICAqIEVuc3VyZSB0aGF0IHRoZSBzaXplIG9mIHRoZSBpbmZvcm1hdGlvbiBhcnJheXMgY2FuIGhvbGQgYW5vdGhlciBlbnRyeQotLy8gICAgICogYXQgdGhlIGdpdmVuIGluZGV4LgotLy8gICAgICoKLS8vICAgICAqIEBwYXJhbSBpbmRleCBPbiBleGl0IGZyb20gdGhpcyBmdW5jdGlvbiwgdGhlIGluZm9ybWF0aW9uIGFycmF5cyBzaXplcyBtdXN0IGJlCi0vLyAgICAgKiBhdCBsZWFzdCBpbmRleCsxLgotLy8gICAgICovCi0vLyAgICBwcm90ZWN0ZWQgdm9pZCBlbnN1cmVTaXplKGludCBpbmRleCkKLS8vICAgIHsKLS8vICAgICAgICAvLyBXZSd2ZSBjdXQgb3ZlciB0byBTdWJhbGxvY2F0ZWQqVmVjdG9yLCB3aGljaCBhcmUgc2VsZi1zaXppbmcuCi0vLyAgICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc2ltcGxlIHR5cGUgSUQgZm9yIHRoZSBnaXZlbiBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHNpbXBsZSB0eXBlIElELCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBzaG9ydCBfdHlwZShpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGludCBpbmZvID0gZ2V0RXhwYW5kZWRUeXBlSUQoaWRlbnRpdHkpOwotCi0gICAgaWYgKE5VTEwgIT0gaW5mbykKLSAgICAgIHJldHVybiBFeHBhbmRlZE5hbWVUYWJsZS5nZXRUeXBlKGluZm8pOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBOVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZXhwYW5kZWQgdHlwZSBJRCBmb3IgdGhlIGdpdmVuIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXhwYW5kZWQgdHlwZSBJRCwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9leHB0eXBlKGludCBpZGVudGl0eSkKLSAgewotICAgIC8vIFJlb3JnYW5pemVkIHRlc3QgYW5kIGxvb3AgaW50byBzaW5nbGUgZmxvdwotICAgIC8vIFRpbnkgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQsIHNhdmVzIGEgZmV3IGJ5dGVzIG9mIGNvZGUsIGNsZWFyZXIuCi0gICAgLy8gJU9QVCUgT3RoZXIgaW50ZXJuYWwgZ2V0dGVycyBjb3VsZCBiZSB0cmVhdGVkIHNpbWxpYXJseQotICAgIHdoaWxlIChpZGVudGl0eT49bV9zaXplKQotICAgIHsKLSAgICAgIGlmICghbmV4dE5vZGUoKSAmJiBpZGVudGl0eSA+PSBtX3NpemUpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgICByZXR1cm4gbV9leHB0eXBlLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxldmVsIGluIHRoZSB0cmVlIGZvciB0aGUgZ2l2ZW4gbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB0cmVlIGxldmVsLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX2xldmVsKGludCBpZGVudGl0eSkKLSAgewotICAgIHdoaWxlIChpZGVudGl0eT49bV9zaXplKQotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNNb3JlID0gbmV4dE5vZGUoKTsKLSAgICAgIGlmICghaXNNb3JlICYmIGlkZW50aXR5ID49IG1fc2l6ZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotCi0gICAgaW50IGk9MDsKLSAgICB3aGlsZShOVUxMICE9IChpZGVudGl0eT1fcGFyZW50KGlkZW50aXR5KSkpCi0gICAgICArK2k7Ci0gICAgcmV0dXJuIGk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBmaXJzdCBjaGlsZCBmb3IgdGhlIGdpdmVuIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmlyc3QgY2hpbGQgaWRlbnRpdHksIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfZmlyc3RjaChpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIC8vIEJvaWxlci1wbGF0ZSBjb2RlIGZvciBlYWNoIG9mIHRoZSBfeHh4IGZ1bmN0aW9ucywgZXhjZXB0IGZvciB0aGUgYXJyYXkuCi0gICAgaW50IGluZm8gPSAoaWRlbnRpdHkgPj0gbV9zaXplKSA/IE5PVFBST0NFU1NFRCA6IG1fZmlyc3RjaC5lbGVtZW50QXQoaWRlbnRpdHkpOwotCi0gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgaGFzIGJlZW4gcHJvY2Vzc2VkLCBhbmQsCi0gICAgLy8gaWYgbm90LCBhZHZhbmNlIHRoZSBpdGVyYXRvciB1bnRpbCB3ZSB0aGUgaW5mb3JtYXRpb24gaGFzIGJlZW4KLSAgICAvLyBwcm9jZXNzZWQuCi0gICAgd2hpbGUgKGluZm8gPT0gTk9UUFJPQ0VTU0VEKQotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNNb3JlID0gbmV4dE5vZGUoKTsKLQotICAgICAgaWYgKGlkZW50aXR5ID49IG1fc2l6ZSAmJiFpc01vcmUpCi0gICAgICAgIHJldHVybiBOVUxMOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpbmZvID0gbV9maXJzdGNoLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgICAgIGlmKGluZm8gPT0gTk9UUFJPQ0VTU0VEICYmICFpc01vcmUpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGluZm87Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IHNpYmxpbmcgZm9yIHRoZSBnaXZlbiBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5leHQgc2libGluZyBpZGVudGl0eSwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IF9uZXh0c2liKGludCBpZGVudGl0eSkKLSAgewotCi0gICAgLy8gQm9pbGVyLXBsYXRlIGNvZGUgZm9yIGVhY2ggb2YgdGhlIF94eHggZnVuY3Rpb25zLCBleGNlcHQgZm9yIHRoZSBhcnJheS4KLSAgICBpbnQgaW5mbyA9IChpZGVudGl0eSA+PSBtX3NpemUpID8gTk9UUFJPQ0VTU0VEIDogbV9uZXh0c2liLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhlIGluZm9ybWF0aW9uIHJlcXVlc3RlZCBoYXMgYmVlbiBwcm9jZXNzZWQsIGFuZCwKLSAgICAvLyBpZiBub3QsIGFkdmFuY2UgdGhlIGl0ZXJhdG9yIHVudGlsIHdlIHRoZSBpbmZvcm1hdGlvbiBoYXMgYmVlbgotICAgIC8vIHByb2Nlc3NlZC4KLSAgICB3aGlsZSAoaW5mbyA9PSBOT1RQUk9DRVNTRUQpCi0gICAgewotICAgICAgYm9vbGVhbiBpc01vcmUgPSBuZXh0Tm9kZSgpOwotCi0gICAgICBpZiAoaWRlbnRpdHkgPj0gbV9zaXplICYmIWlzTW9yZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGluZm8gPSBtX25leHRzaWIuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgICAgICAgaWYoaW5mbyA9PSBOT1RQUk9DRVNTRUQgJiYgIWlzTW9yZSkKLSAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gaW5mbzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByZXZpb3VzIHNpYmxpbmcgZm9yIHRoZSBnaXZlbiBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByZXZpb3VzIHNpYmxpbmcgaWRlbnRpdHksIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfcHJldnNpYihpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGlmIChpZGVudGl0eSA8IG1fc2l6ZSkKLSAgICAgIHJldHVybiBtX3ByZXZzaWIuZWxlbWVudEF0KGlkZW50aXR5KTsKLQotICAgIC8vIENoZWNrIHRvIHNlZSBpZiB0aGUgaW5mb3JtYXRpb24gcmVxdWVzdGVkIGhhcyBiZWVuIHByb2Nlc3NlZCwgYW5kLAotICAgIC8vIGlmIG5vdCwgYWR2YW5jZSB0aGUgaXRlcmF0b3IgdW50aWwgd2UgdGhlIGluZm9ybWF0aW9uIGhhcyBiZWVuCi0gICAgLy8gcHJvY2Vzc2VkLgotICAgIHdoaWxlICh0cnVlKQotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNNb3JlID0gbmV4dE5vZGUoKTsKLQotICAgICAgaWYgKGlkZW50aXR5ID49IG1fc2l6ZSAmJiAhaXNNb3JlKQotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIGVsc2UgaWYgKGlkZW50aXR5IDwgbV9zaXplKQotICAgICAgICByZXR1cm4gbV9wcmV2c2liLmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcGFyZW50IGZvciB0aGUgZ2l2ZW4gbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwYXJlbnQgaWRlbnRpdHksIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBfcGFyZW50KGludCBpZGVudGl0eSkKLSAgewotCi0gICAgaWYgKGlkZW50aXR5IDwgbV9zaXplKQotICAgICAgcmV0dXJuIG1fcGFyZW50LmVsZW1lbnRBdChpZGVudGl0eSk7Ci0KLSAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhlIGluZm9ybWF0aW9uIHJlcXVlc3RlZCBoYXMgYmVlbiBwcm9jZXNzZWQsIGFuZCwKLSAgICAvLyBpZiBub3QsIGFkdmFuY2UgdGhlIGl0ZXJhdG9yIHVudGlsIHdlIHRoZSBpbmZvcm1hdGlvbiBoYXMgYmVlbgotICAgIC8vIHByb2Nlc3NlZC4KLSAgICB3aGlsZSAodHJ1ZSkKLSAgICB7Ci0gICAgICBib29sZWFuIGlzTW9yZSA9IG5leHROb2RlKCk7Ci0KLSAgICAgIGlmIChpZGVudGl0eSA+PSBtX3NpemUgJiYgIWlzTW9yZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICBlbHNlIGlmIChpZGVudGl0eSA8IG1fc2l6ZSkKLSAgICAgICAgcmV0dXJuIG1fcGFyZW50LmVsZW1lbnRBdChpZGVudGl0eSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIERpYWdub3N0aWNzIGZ1bmN0aW9uIHRvIGR1bXAgdGhlIERUTS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGR1bXBEVE0oKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgRmlsZSBmID0gbmV3IEZpbGUoIkRUTUR1bXAiKygoT2JqZWN0KXRoaXMpLmhhc2hDb2RlKCkrIi50eHQiKTsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRHVtcGluZy4uLiAiK2YuZ2V0QWJzb2x1dGVQYXRoKCkpOwotICAgICAgUHJpbnRTdHJlYW0gcHMgPSBuZXcgUHJpbnRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oZikpOwotCi0gICAgICB3aGlsZSAobmV4dE5vZGUoKSl7fQotCi0gICAgICBpbnQgblJlY29yZHMgPSBtX3NpemU7Ci0KLSAgICAgIHBzLnByaW50bG4oIlRvdGFsIG5vZGVzOiAiICsgblJlY29yZHMpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5SZWNvcmRzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHBzLnByaW50bG4oIj09PT09PT09PT09ICIgKyBpICsgIiA9PT09PT09PT09PSIpOwotICAgICAgICBwcy5wcmludGxuKCJOb2RlTmFtZTogIiArIGdldE5vZGVOYW1lKGkpKTsKLSAgICAgICAgcHMucHJpbnRsbigiTm9kZU5hbWVYOiAiICsgZ2V0Tm9kZU5hbWVYKGkpKTsKLSAgICAgICAgcHMucHJpbnRsbigiTG9jYWxOYW1lOiAiICsgZ2V0TG9jYWxOYW1lKGkpKTsKLSAgICAgICAgcHMucHJpbnRsbigiTmFtZXNwYWNlVVJJOiAiICsgZ2V0TmFtZXNwYWNlVVJJKGkpKTsKLSAgICAgICAgcHMucHJpbnRsbigiUHJlZml4OiAiICsgZ2V0UHJlZml4KGkpKTsKLQotICAgICAgICBpbnQgZXhUeXBlSUQgPSBnZXRFeHBhbmRlZFR5cGVJRChpKTsKLQotICAgICAgICBwcy5wcmludGxuKCJFeHBhbmRlZCBUeXBlIElEOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICArIEludGVnZXIudG9IZXhTdHJpbmcoZXhUeXBlSUQpKTsKLQotICAgICAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlKGkpOwotICAgICAgICBTdHJpbmcgdHlwZXN0cmluZzsKLQotICAgICAgICBzd2l0Y2ggKHR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiQVRUUklCVVRFX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiQ0RBVEFfU0VDVElPTl9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkNPTU1FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRE9DVU1FTlRfRlJBR01FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRE9DVU1FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkRPQ1VNRU5UX1RZUEVfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJET0NVTUVOVF9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVMRU1FTlRfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkVOVElUWV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVOVElUWV9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVOVElUWV9SRUZFUkVOQ0VfTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIk5BTUVTUEFDRV9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTk9UQVRJT05fTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJOT1RBVElPTl9OT0RFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTlVMTCA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJOVUxMIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJURVhUX05PREUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBkZWZhdWx0IDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIlVua25vd24hIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIHBzLnByaW50bG4oIlR5cGU6ICIgKyB0eXBlc3RyaW5nKTsKLQotICAgICAgICBpbnQgZmlyc3RDaGlsZCA9IF9maXJzdGNoKGkpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBmaXJzdENoaWxkKQotICAgICAgICAgIHBzLnByaW50bG4oIkZpcnN0IGNoaWxkOiBEVE0uTlVMTCIpOwotICAgICAgICBlbHNlIGlmIChOT1RQUk9DRVNTRUQgPT0gZmlyc3RDaGlsZCkKLSAgICAgICAgICBwcy5wcmludGxuKCJGaXJzdCBjaGlsZDogTk9UUFJPQ0VTU0VEIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcy5wcmludGxuKCJGaXJzdCBjaGlsZDogIiArIGZpcnN0Q2hpbGQpOwotCi0gICAgICAgIGludCBwcmV2U2libGluZyA9IF9wcmV2c2liKGkpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBwcmV2U2libGluZykKLSAgICAgICAgICBwcy5wcmludGxuKCJQcmV2IHNpYmxpbmc6IERUTS5OVUxMIik7Ci0gICAgICAgIGVsc2UgaWYgKE5PVFBST0NFU1NFRCA9PSBwcmV2U2libGluZykKLSAgICAgICAgICBwcy5wcmludGxuKCJQcmV2IHNpYmxpbmc6IE5PVFBST0NFU1NFRCIpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcHMucHJpbnRsbigiUHJldiBzaWJsaW5nOiAiICsgcHJldlNpYmxpbmcpOwotCi0gICAgICAgIGludCBuZXh0U2libGluZyA9IF9uZXh0c2liKGkpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBuZXh0U2libGluZykKLSAgICAgICAgICBwcy5wcmludGxuKCJOZXh0IHNpYmxpbmc6IERUTS5OVUxMIik7Ci0gICAgICAgIGVsc2UgaWYgKE5PVFBST0NFU1NFRCA9PSBuZXh0U2libGluZykKLSAgICAgICAgICBwcy5wcmludGxuKCJOZXh0IHNpYmxpbmc6IE5PVFBST0NFU1NFRCIpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcHMucHJpbnRsbigiTmV4dCBzaWJsaW5nOiAiICsgbmV4dFNpYmxpbmcpOwotCi0gICAgICAgIGludCBwYXJlbnQgPSBfcGFyZW50KGkpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBwYXJlbnQpCi0gICAgICAgICAgcHMucHJpbnRsbigiUGFyZW50OiBEVE0uTlVMTCIpOwotICAgICAgICBlbHNlIGlmIChOT1RQUk9DRVNTRUQgPT0gcGFyZW50KQotICAgICAgICAgIHBzLnByaW50bG4oIlBhcmVudDogTk9UUFJPQ0VTU0VEIik7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBwcy5wcmludGxuKCJQYXJlbnQ6ICIgKyBwYXJlbnQpOwotCi0gICAgICAgIGludCBsZXZlbCA9IF9sZXZlbChpKTsKLQotICAgICAgICBwcy5wcmludGxuKCJMZXZlbDogIiArIGxldmVsKTsKLSAgICAgICAgcHMucHJpbnRsbigiTm9kZSBWYWx1ZTogIiArIGdldE5vZGVWYWx1ZShpKSk7Ci0gICAgICAgIHBzLnByaW50bG4oIlN0cmluZyBWYWx1ZTogIiArIGdldFN0cmluZ1ZhbHVlKGkpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2goSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIGlvZS5wcmludFN0YWNrVHJhY2UoU3lzdGVtLmVycik7Ci0gICAgICBTeXN0ZW0uZXhpdCgtMSk7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogRGlhZ25vc3RpY3MgZnVuY3Rpb24gdG8gZHVtcCBhIHNpbmdsZSBub2RlLgotICAgKiAKLSAgICogJVJFVklFVyUgS05PV04gR0xJVENIOiBJZiB5b3UgcGFzcyBpdCBhIG5vZGUgaW5kZXggcmF0aGVyIHRoYW4gYSAKLSAgICogbm9kZSBoYW5kbGUsIGl0IHdvcmtzIGp1c3QgZmluZS4uLiBidXQgdGhlIGRpc3BsYXllZCBpZGVudGl0eSAKLSAgICogbnVtYmVyIGJlZm9yZSB0aGUgY29sb24gaXMgZGlmZmVyZW50LCB3aGljaCBjb21wbGljYXRlcyBjb21wYXJpbmcKLSAgICogaXQgd2l0aCBub2RlcyBwcmludGVkIHRoZSBvdGhlciB3YXkuIFdlIGNvdWxkIGFsd2F5cyBPUiB0aGUgRFRNIElECi0gICAqIGludG8gdGhlIHZhbHVlLCB0byBzdXBwcmVzcyB0aGF0IGRpc3RpbmN0aW9uLi4uCi0gICAqIAotICAgKiAlUkVWSUVXJSBUaGlzIG1pZ2h0IHdhbnQgdG8gYmUgbW92ZWQgdXAgdG8gRFRNRGVmYXVsdEJhc2UsIG9yIHBvc3NpYmx5Ci0gICAqIERUTSBpdHNlbGYsIHNpbmNlIGl0J3MgYSB1c2VmdWwgZGlhZ25vc3RpYyBhbmQgdXNlcyBvbmx5IERUTSdzIHB1YmxpYwotICAgKiBBUElzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBkdW1wTm9kZShpbnQgbm9kZUhhbmRsZSkKLSAgewkgIAotCSAgaWYobm9kZUhhbmRsZT09RFRNLk5VTEwpCi0JCSAgcmV0dXJuICJbbnVsbF0iOwotCQkgIAotICAgICAgICBTdHJpbmcgdHlwZXN0cmluZzsKLSAgICAgICAgc3dpdGNoIChnZXROb2RlVHlwZShub2RlSGFuZGxlKSkKLSAgICAgICAgewotICAgICAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJBVFRSIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkNEQVRBIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uQ09NTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkNPTU1FTlQiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkRPQ19GUkFHIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJET0MiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5ET0NVTUVOVF9UWVBFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRE9DX1RZUEUiOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiRUxFTUVOVCI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkVOVElUWV9OT0RFIDoKLSAgICAgICAgICB0eXBlc3RyaW5nID0gIkVOVElUWSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJFTlRfUkVGIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTkFNRVNQQUNFX05PREUgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAiTkFNRVNQQUNFIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBEVE0uTk9UQVRJT05fTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJOT1RBVElPTiI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLk5VTEwgOgotICAgICAgICAgIHR5cGVzdHJpbmcgPSAibnVsbCI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJQSSI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJURVhUIjsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgZGVmYXVsdCA6Ci0gICAgICAgICAgdHlwZXN0cmluZyA9ICJVbmtub3duISI7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgU3RyaW5nQnVmZmVyIHNiPW5ldyBTdHJpbmdCdWZmZXIoKTsKLQkgIHNiLmFwcGVuZCgiWyIrbm9kZUhhbmRsZSsiOiAiK3R5cGVzdHJpbmcrCi0JCQkJIigweCIrSW50ZWdlci50b0hleFN0cmluZyhnZXRFeHBhbmRlZFR5cGVJRChub2RlSGFuZGxlKSkrIikgIisKLQkJCQlnZXROb2RlTmFtZVgobm9kZUhhbmRsZSkrIiB7IitnZXROYW1lc3BhY2VVUkkobm9kZUhhbmRsZSkrIn0iKwotCQkJCSI9XCIiKyBnZXROb2RlVmFsdWUobm9kZUhhbmRsZSkrIlwiXSIpOwotCSAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvLyA9PT09PT09PT0gRFRNIEltcGxlbWVudGF0aW9uIENvbnRyb2wgRnVuY3Rpb25zLiA9PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBTZXQgYW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IGZlYXR1cmUuCi0gICAqIDxwPgotICAgKiAlUkVWSUVXJSBEbyB3ZSByZWFsbHkgZXhwZWN0IHRvIHNldCBmZWF0dXJlcyBvbiBEVE1zPwotICAgKgotICAgKiBAcGFyYW0gZmVhdHVyZUlkIEEgZmVhdHVyZSBVUkwuCi0gICAqIEBwYXJhbSBzdGF0ZSB0cnVlIGlmIHRoaXMgZmVhdHVyZSBzaG91bGQgYmUgb24sIGZhbHNlIG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVJZCwgYm9vbGVhbiBzdGF0ZSl7fQotCi0gIC8vID09PT09PT09PSBEb2N1bWVudCBOYXZpZ2F0aW9uIEZ1bmN0aW9ucyA9PT09PT09PT0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgdGVzdCBpZiBpdCBoYXMgY2hpbGQgbm9kZXMuCi0gICAqIDxwPiAlUkVWSUVXJSBUaGlzIGlzIG9idmlvdXNseSB1c2VmdWwgYXQgdGhlIERPTSBsYXllciwgd2hlcmUgaXQKLSAgICogd291bGQgcGVybWl0IHRlc3RpbmcgdGhpcyB3aXRob3V0IGhhdmluZyB0byBjcmVhdGUgYSBwcm94eQotICAgKiBub2RlLiBJdCdzIGxlc3MgdXNlZnVsIGluIHRoZSBEVE0gQVBJLCB3aGVyZQotICAgKiAoZHRtLmdldEZpcnN0Q2hpbGQobm9kZUhhbmRsZSkhPURUTS5OVUxMKSBpcyBqdXN0IGFzIGZhc3QgYW5kCi0gICAqIGFsbW9zdCBhcyBzZWxmLWV2aWRlbnQuIEJ1dCBpdCdzIGEgY29udmVuaWVuY2UsIGFuZCBlYXNlcyBwb3J0aW5nCi0gICAqIG9mIERPTSBjb2RlIHRvIERUTS4gIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBoYXMgY2hpbGQgbm9kZXMuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgaWRlbnRpdHkgPSBub2RlSGFuZGxlICYgbV9tYXNrOwotICAgIGludCBmaXJzdENoaWxkID0gX2ZpcnN0Y2goaWRlbnRpdHkpOwotCi0gICAgcmV0dXJuIGZpcnN0Q2hpbGQgIT0gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBoYW5kbGUgb2YgdGhlIG5vZGUncyBmaXJzdCBjaGlsZC4KLSAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgKiB0cmllcyBhZ2Fpbi4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIGZpcnN0IGNoaWxkLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3RDaGlsZChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IGlkZW50aXR5ID0gbm9kZUhhbmRsZSAmIG1fbWFzazsKLSAgICBpbnQgZmlyc3RDaGlsZCA9IF9maXJzdGNoKGlkZW50aXR5KTsKLQotICAgIHJldHVybiBmaXJzdENoaWxkIHwgbV9kdG1JZGVudDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIGl0cyBsYXN0IGNoaWxkLgotICAgKiBJZiBub3QgeWV0IHJlc29sdmVkLCB3YWl0cyBmb3IgbW9yZSBub2RlcyB0byBiZSBhZGRlZCB0byB0aGUgZG9jdW1lbnQgYW5kCi0gICAqIHRyaWVzIGFnYWluLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBsYXN0IGNoaWxkLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdENoaWxkKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBpbnQgaWRlbnRpdHkgPSBub2RlSGFuZGxlICYgbV9tYXNrOwotICAgIGludCBjaGlsZCA9IF9maXJzdGNoKGlkZW50aXR5KTsKLSAgICBpbnQgbGFzdENoaWxkID0gRFRNLk5VTEw7Ci0KLSAgICB3aGlsZSAoY2hpbGQgIT0gRFRNLk5VTEwpCi0gICAgewotICAgICAgbGFzdENoaWxkID0gY2hpbGQ7Ci0gICAgICBjaGlsZCA9IF9uZXh0c2liKGNoaWxkKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbGFzdENoaWxkIHwgbV9kdG1JZGVudDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5vZGUgYnkgYnkgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUgdXBvbiB3aGljaCB0byBsb29rIHVwIHRoaXMgYXR0cmlidXRlLi4KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICogICByZXRyaWV2ZS4KLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIG5vZGUgaGFuZGxlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lICgKLSAgICogICA8Y29kZT5ub2RlTmFtZTwvY29kZT4pIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBzdWNoCi0gICAqICAgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBnZXRBdHRyaWJ1dGVOb2RlKGludCBub2RlSGFuZGxlLCBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MgZmlyc3QgYXR0cmlidXRlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIEhhbmRsZSBvZiBmaXJzdCBhdHRyaWJ1dGUsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRGaXJzdEF0dHJpYnV0ZShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShub2RlSGFuZGxlKTsKLQotICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotCi0gICAgICAvLyBBc3N1bWUgdGhhdCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2VzIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgZWxlbWVudC4KLSAgICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoaWRlbnRpdHkgPSBnZXROZXh0Tm9kZUlkZW50aXR5KGlkZW50aXR5KSkpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gQXNzdW1lIHRoaXMgY2FuIG5vdCBiZSBudWxsLgotICAgICAgICB0eXBlID0gZ2V0Tm9kZVR5cGUoaWRlbnRpdHkpOwotCi0gICAgICAgIGlmICh0eXBlID09IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBpZGVudGl0eSB8IG1fZHRtSWRlbnQ7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoRFRNLk5BTUVTUEFDRV9OT0RFICE9IHR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIGl0cyBuZXh0IHNpYmxpbmcuCi0gICAqIElmIG5vdCB5ZXQgcmVzb2x2ZWQsIHdhaXRzIGZvciBtb3JlIG5vZGVzIHRvIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhbmQKLSAgICogdHJpZXMgYWdhaW4uCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIG5leHQgc2libGluZywKLSAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHRTaWJsaW5nKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgcmV0dXJuIF9uZXh0c2liKG5vZGVIYW5kbGUgJiBtX21hc2spIHwgbV9kdG1JZGVudDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIGl0cyBwcmVjZWVkaW5nIHNpYmxpbmcuCi0gICAqIFdBUk5JTkc6IERUTSBpcyBhc3ltbWV0cmljOyB0aGlzIG9wZXJhdGlvbiBpcyByZXNvbHZlZCBieSBzZWFyY2gsIGFuZCBpcwotICAgKiByZWxhdGl2ZWx5IGV4cGVuc2l2ZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiB0aGUgcHJldmlvdXMgc2liLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UHJldmlvdXNTaWJsaW5nKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgcmV0dXJuIF9wcmV2c2liKG5vZGVIYW5kbGUgJiBtX21hc2spIHwgbV9kdG1JZGVudDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IGF0dHJpYnV0ZS4KLSAgICogSWYgYW4gYXR0ciwgd2UgYWR2YW5jZSB0bwotICAgKiB0aGUgbmV4dCBhdHRyIG9uIHRoZSBzYW1lIG5vZGUuICBJZiBub3QgYW4gYXR0cmlidXRlLCB3ZSByZXR1cm4gTlVMTC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIHRoZSByZXNvbHZlZCBhdHRyLAotICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmV4dEF0dHJpYnV0ZShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShub2RlSGFuZGxlKTsKLQotICAgIGlmIChEVE0uQVRUUklCVVRFX05PREUgPT0gdHlwZSkKLSAgICB7Ci0gICAgICAvLyBBc3N1bWUgdGhhdCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2Ugbm9kZXMgaW1tZWRpYXRlbHkgZm9sbG93IHRoZSBlbGVtZW50LgotICAgICAgaW50IGlkZW50aXR5ID0gbm9kZUhhbmRsZSAmIG1fbWFzazsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgIHsKLSAgICAgICAgdHlwZSA9IGdldE5vZGVUeXBlKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAodHlwZSA9PSBEVE0uQVRUUklCVVRFX05PREUpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gaWRlbnRpdHkgfCBtX2R0bUlkZW50OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHR5cGUgIT0gRFRNLk5BTUVTUEFDRV9OT0RFKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKiogTGF6aWx5IGNyZWF0ZWQgbmFtZXNwYWNlIGxpc3RzLiAqLwotICBwcml2YXRlIFZlY3RvciBtX25hbWVzcGFjZUxpc3RzID0gbnVsbDsgIC8vIG9uIGRlbWFuZAotCi0KLSAgLyoqIEJ1aWxkIHRhYmxlIG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgKiBsb2NhdGlvbnMgZHVyaW5nIERUTSBjb25zdHJ1Y3Rpb24uIFRhYmxlIGlzIGEgVmVjdG9yIG9mCi0gICAqIFN1YmFsbG9jYXRlZEludFZlY3RvcnMgY29udGFpbmluZyB0aGUgbmFtZXNwYWNlIG5vZGUgSEFORExFUyBkZWNsYXJlZCBhdAotICAgKiB0aGF0IElELCBwbHVzIGFuIFN1YmFsbG9jYXRlZEludFZlY3RvciBvZiB0aGUgZWxlbWVudCBub2RlIElOREVYRVMgYXQgd2hpY2gKLSAgICogdGhlc2UgZGVjbGFyYXRpb25zIGFwcGVhcmVkLgotICAgKgotICAgKiBOT1RFOiBTaW5jZSB0aGlzIG9jY3VycyBkdXJpbmcgbW9kZWwgYnVpbGQsIG5vZGVzIHdpbGwgYmUgZW5jb3VudGVyZWQKLSAgICogaW4gZG91Y21lbnQgb3JkZXIgYW5kIHRodXMgdGhlIHRhYmxlIHdpbGwgYmUgb3JkZXJlZCBieSBlbGVtZW50LAotICAgKiBwZXJtaXR0aW5nIGJpbmFyeS1zZWFyY2ggYXMgYSBwb3NzaWJsZSByZXRyaWV2YWwgb3B0aW1pemF0aW9uLgotICAgKgotICAgKiAlUkVWSUVXJSBEaXJlY3RseSBtYW5hZ2VkIGFycmF5cyByYXRoZXIgdGhhbiB2ZWN0b3JzPwotICAgKiAlUkVWSUVXJSBIYW5kbGVzIG9yIElEcz8gR2l2ZW4gdXNhZ2UsIEkgdGhpbmsgaGFuZGxlcy4KLSAgICogKi8KLSAgcHJvdGVjdGVkIHZvaWQgZGVjbGFyZU5hbWVzcGFjZUluQ29udGV4dChpbnQgZWxlbWVudE5vZGVJbmRleCxpbnQgbmFtZXNwYWNlTm9kZUluZGV4KQotICB7Ci0gICAgU3ViYWxsb2NhdGVkSW50VmVjdG9yIG5zTGlzdD1udWxsOwotICAgIGlmKG1fbmFtZXNwYWNlRGVjbFNldHM9PW51bGwpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gRmlyc3QKLSAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHM9bmV3IFN1YmFsbG9jYXRlZEludFZlY3RvcigpOwotICAgICAgICBtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cy5hZGRFbGVtZW50KGVsZW1lbnROb2RlSW5kZXgpOwotICAgICAgICBtX25hbWVzcGFjZURlY2xTZXRzPW5ldyBWZWN0b3IoKTsKLSAgICAgICAgbnNMaXN0PW5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoKTsKLSAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0cy5hZGRFbGVtZW50KG5zTGlzdCk7Ci0gICAgICB9Ci0gICAgZWxzZQotICAgICAgewotICAgICAgICAvLyBNb3N0IHJlY2VudD8KLSAgICAgICAgLy8gJU9QVCUgSXMgdGhlcmUgYSBsYXN0RWxlbWVudCgpIG1ldGhvZD8gU2hvdWxkIHRoZXJlIGJlPwotICAgICAgICBpbnQgbGFzdD1tX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cy5zaXplKCktMTsKLQotICAgICAgICBpZihlbGVtZW50Tm9kZUluZGV4PT0KLSAgICAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuZWxlbWVudEF0KGxhc3QpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIG5zTGlzdD0oU3ViYWxsb2NhdGVkSW50VmVjdG9yKW1fbmFtZXNwYWNlRGVjbFNldHMuZWxlbWVudEF0KGxhc3QpOwotCi0gICAgICAgICAgfQotICAgICAgfQotICAgIGlmKG5zTGlzdD09bnVsbCkKLSAgICAgIHsKLSAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMuYWRkRWxlbWVudChlbGVtZW50Tm9kZUluZGV4KTsKLSAgICAgICAgbnNMaXN0PW5ldyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoKTsKLSAgICAgICAgbV9uYW1lc3BhY2VEZWNsU2V0cy5hZGRFbGVtZW50KG5zTGlzdCk7Ci0KLSAgICAgICAgU3ViYWxsb2NhdGVkSW50VmVjdG9yIGluaGVyaXRlZD0gZmluZE5hbWVzcGFjZUNvbnRleHQoX3BhcmVudChlbGVtZW50Tm9kZUluZGV4KSk7Ci0KLSAgICAgICAgaWYoaW5oZXJpdGVkIT1udWxsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vICVPUFQlIENvdW50LWRvd24gbWlnaHQgYmUgZmFzdGVyLCBidXQgZGVidWdnYWJpbGl0eSBtYXkKLSAgICAgICAgICAgIC8vIGJlIGJldHRlciB0aGlzIHdheSwgYW5kIGlmIHdlIGV2ZXIgZGVjaWRlIHdlIHdhbnQgdG8KLSAgICAgICAgICAgIC8vIGtlZXAgdGhpcyBvcmRlcmVkIGJ5IGV4cGFuZGVkLXR5cGUuLi4KLSAgICAgICAgICAgIGludCBpc2l6ZT1pbmhlcml0ZWQuc2l6ZSgpOwotICAgICAgICAgICAgZm9yKGludCBpPTA7aTxpc2l6ZTsrK2kpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBuc0xpc3QuYWRkRWxlbWVudChpbmhlcml0ZWQuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgIH0KLQotICAgIC8vIEhhbmRsZSBvdmVyd3JpdGluZyBpbmhlcml0ZWQuCi0gICAgLy8gJU9QVCUgS2VlcCBzb3J0ZWQ/IChCeSBleHBhbmRlZC1uYW1lIHJhdGhlciB0aGFuIGJ5IGRvYyBvcmRlci4uLikKLSAgICAvLyBEb3duc2lkZTogV291bGQgcmVxdWlyZSBpbnNlcnRFbGVtZW50QXQgaWYgbm90IGZvdW5kLAotICAgIC8vIHdoaWNoIGhhcyByZWNvcHlpbmcgY29zdHMuIEJ1dCB0aGVzZSBhcmUgZ2VuZXJhbGx5IHNob3J0IGxpc3RzLi4uCi0gICAgaW50IG5ld0VUeXBlPWdldEV4cGFuZGVkVHlwZUlEKG5hbWVzcGFjZU5vZGVJbmRleCk7Ci0KLSAgICBmb3IoaW50IGk9bnNMaXN0LnNpemUoKS0xO2k+PTA7LS1pKQotICAgICAgewotICAgICAgICBpZihuZXdFVHlwZT09Z2V0RXhwYW5kZWRUeXBlSUQobnNMaXN0LmVsZW1lbnRBdChpKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgbnNMaXN0LnNldEVsZW1lbnRBdChuYW1lc3BhY2VOb2RlSW5kZXggfCBtX2R0bUlkZW50LGkpOwotICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgICBuc0xpc3QuYWRkRWxlbWVudChuYW1lc3BhY2VOb2RlSW5kZXggfCBtX2R0bUlkZW50KTsKLSAgfQotCi0gIC8qKiBSZXRyaWV2ZSBsaXN0IG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBsb2NhdGlvbnMKLSAgICAgKiBhY3RpdmUgYXQgdGhpcyBub2RlLiBMaXN0IGlzIGFuIFN1YmFsbG9jYXRlZEludFZlY3RvciB3aG9zZQotICAgICAqIGVudHJpZXMgYXJlIHRoZSBuYW1lc3BhY2Ugbm9kZSBIQU5ETEVTIGRlY2xhcmVkIGF0IHRoYXQgSUQuCi0gICAgICoKLSAgICAgKiAlUkVWSUVXJSBEaXJlY3RseSBtYW5hZ2VkIGFycmF5cyByYXRoZXIgdGhhbiB2ZWN0b3JzPwotICAgICAqICVSRVZJRVclIEhhbmRsZXMgb3IgSURzPyBHaXZlbiB1c2FnZSwgSSB0aGluayBoYW5kbGVzLgotICAgICAqICovCi0gIHByb3RlY3RlZCBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgZmluZE5hbWVzcGFjZUNvbnRleHQoaW50IGVsZW1lbnROb2RlSW5kZXgpCi0gIHsKLSAgICBpZiAobnVsbCE9bV9uYW1lc3BhY2VEZWNsU2V0RWxlbWVudHMpCi0gICAgICB7Ci0gICAgICAgIC8vICVPUFQlIElzIGJpbmFyeS1zZWFyY2ggcmVhbGx5IHNhdmluZyB1cyBhIGxvdCB2ZXJzdXMgbGluZWFyPwotICAgICAgICAvLyAoLi4uIEl0IG1heSBiZSwgaW4gbGFyZ2UgZG9jcyB3aXRoIG1hbnkgTlMgZGVjbHMuKQotICAgICAgICBpbnQgd291bGRCZUF0PWZpbmRJblNvcnRlZFN1YmFsbG9jYXRlZEludFZlY3RvcihtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE5vZGVJbmRleCk7Ci0gICAgICAgIGlmKHdvdWxkQmVBdD49MCkgLy8gRm91bmQgaXQKLSAgICAgICAgICByZXR1cm4gKFN1YmFsbG9jYXRlZEludFZlY3RvcikgbV9uYW1lc3BhY2VEZWNsU2V0cy5lbGVtZW50QXQod291bGRCZUF0KTsKLSAgICAgICAgaWYod291bGRCZUF0ID09IC0xKSAvLyAtMS13b3VsZGJlYXQgPT0gMAotICAgICAgICAgIHJldHVybiBudWxsOyAvLyBOb3QgYWZ0ZXIgYW55dGhpbmc7IGRlZmluaXRlbHkgbm90IGZvdW5kCi0KLSAgICAgICAgLy8gTm90IGZvdW5kLCBidXQgd2Uga25vdyB3aGVyZSBpdCBzaG91bGQgaGF2ZSBiZWVuLgotICAgICAgICAvLyBTZWFyY2ggYmFjayB1bnRpbCB3ZSBmaW5kIGFuIGFuY2VzdG9yIG9yIHJ1biBvdXQuCi0gICAgICAgIHdvdWxkQmVBdD0tMS13b3VsZEJlQXQ7Ci0KLSAgICAgICAgLy8gRGVjcmVtZW50IHdvdWxkQmVBdCB0byBmaW5kIGxhc3QgcG9zc2libGUgYW5jZXN0b3IKLSAgICAgICAgaW50IGNhbmRpZGF0ZT1tX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cy5lbGVtZW50QXQoLS0gd291bGRCZUF0KTsKLSAgICAgICAgaW50IGFuY2VzdG9yPV9wYXJlbnQoZWxlbWVudE5vZGVJbmRleCk7Ci0gICAgICAgIHdoaWxlKHdvdWxkQmVBdD49MCAmJiBhbmNlc3Rvcj4wKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGNhbmRpZGF0ZT1tX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cy5lbGVtZW50QXQod291bGRCZUF0KTsKLQotICAgICAgICAgICAgaWYoY2FuZGlkYXRlPT1hbmNlc3RvcikgLy8gRm91bmQgYW5jZXN0b3IgaW4gbGlzdAotICAgICAgICAgICAgICAgIHJldHVybiAoU3ViYWxsb2NhdGVkSW50VmVjdG9yKW1fbmFtZXNwYWNlRGVjbFNldHMuZWxlbWVudEF0KHdvdWxkQmVBdCk7Ci0gICAgICAgICAgICBlbHNlIGlmKGNhbmRpZGF0ZTxhbmNlc3RvcikgLy8gVG9vIGRlZXAgaW4gdHJlZQotICAgICAgICAgICAgICAgIGFuY2VzdG9yPV9wYXJlbnQoYW5jZXN0b3IpOwotICAgICAgICAgICAgZWxzZSAvLyBUb28gbGF0ZSBpbiBsaXN0Ci0gICAgICAgICAgICAgIC0td291bGRCZUF0OwotICAgICAgICAgIH0KLSAgICAgIH0KLQotICAgIHJldHVybiBudWxsOyAvLyBObyBuYW1lc3BhY2VzIGtub3duIGF0IHRoaXMgbm9kZQotICB9Ci0KLSAgLyoqCi0gICAgICogU3Vicm91dGluZTogTG9jYXRlIHRoZSBzcGVjaWZpZWQgbm9kZSB3aXRoaW4KLSAgICAgKiBtX25hbWVzcGFjZURlY2xTZXRFbGVtZW50cywgb3IgdGhlIGxhc3QgZWxlbWVudCB3aGljaAotICAgICAqIHByZWNlZWRzIGl0IGluIGRvY3VtZW50IG9yZGVyCi0gICAgICoKLSAgICAgKiAlUkVWSUVXJSBJbmxuZSB0aGlzIGludG8gZmluZE5hbWVzcGFjZUNvbnRleHQ/IENyZWF0ZSBTb3J0ZWRTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgdHlwZT8KLSAgICAgKgotICAgICAqIEBwYXJhbSBlbGVtZW50Tm9kZUluZGV4IEluZGV4IG9mIGEgbm9kZSB0byBsb29rIHVwLgotICAgICAqCi0gICAgICogQHJldHVybiBJZiBwb3NpdGl2ZSBvciB6ZXJvLCB0aGUgaW5kZXggb2YgdGhlIGZvdW5kIGl0ZW0uCi0gICAgICogSWYgbmVnYXRpdmUsIGluZGV4IG9mIHRoZSBwb2ludCBhdCB3aGljaCBpdCB3b3VsZCBoYXZlIGFwcGVhcmVkLAotICAgICAqIGVuY29kZWQgYXMgLTEtaW5kZXggYW5kIGhlbmNlIHJlY29udmVydGFibGUgYnkgc3VidHJhY3RpbmcKLSAgICAgKiBpdCBmcm9tIC0xLiAoRW5jb2RpbmcgYmVjYXVzZSBJIGRvbid0IHdhbnQgdG8gcmVjb21wYXJlIHRoZSBzdHJpbmdzCi0gICAgICogYnV0IGRvbid0IHdhbnQgdG8gYnVybiBieXRlcyBvbiBhIGRhdGF0eXBlIHRvIGhvbGQgYSBmbGFnZ2VkIHZhbHVlLikKLSAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBmaW5kSW5Tb3J0ZWRTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoU3ViYWxsb2NhdGVkSW50VmVjdG9yIHZlY3RvciwgaW50IGxvb2tmb3IpCi0gIHsKLSAgICAvLyBCaW5hcnkgc2VhcmNoCi0gICAgaW50IGkgPSAwOwotICAgIGlmKHZlY3RvciAhPSBudWxsKSB7Ci0gICAgICBpbnQgZmlyc3QgPSAwOwotICAgICAgaW50IGxhc3QgID0gdmVjdG9yLnNpemUoKSAtIDE7Ci0KLSAgICAgIHdoaWxlIChmaXJzdCA8PSBsYXN0KSB7Ci0gICAgICAgIGkgPSAoZmlyc3QgKyBsYXN0KSAvIDI7Ci0gICAgICAgIGludCB0ZXN0ID0gbG9va2Zvci12ZWN0b3IuZWxlbWVudEF0KGkpOwotICAgICAgICBpZih0ZXN0ID09IDApIHsKLSAgICAgICAgICByZXR1cm4gaTsgLy8gTmFtZSBmb3VuZAotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHRlc3QgPCAwKSB7Ci0gICAgICAgICAgbGFzdCA9IGkgLSAxOyAvLyBsb29rZWQgdG9vIGxhdGUKLSAgICAgICAgfQotICAgICAgICBlbHNlIHsKLSAgICAgICAgICBmaXJzdCA9IGkgKyAxOyAvLyBsb29rZWQgb3QgZWFybHkKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoZmlyc3QgPiBpKSB7Ci0gICAgICAgIGkgPSBmaXJzdDsgLy8gQ2xlYW4gdXAgYXQgbG9vcCBlbmQKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gLTEgLSBpOyAvLyBub3QtZm91bmQgaGFzIHRvIGJlIGVuY29kZWQuCi0gIH0KLQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MgZmlyc3QgY2hpbGQuCi0gICAqIElmIG5vdCB5ZXQgcmVzb2x2ZWQsIHdhaXRzIGZvciBtb3JlIG5vZGVzIHRvIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhbmQKLSAgICogdHJpZXMgYWdhaW4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgaGFuZGxlIHRvIG5vZGUsIHdoaWNoIHNob3VsZCBwcm9iYWJseSBiZSBhbiBlbGVtZW50Ci0gICAqICAgICAgICAgICAgICAgICAgIG5vZGUsIGJ1dCBuZWVkIG5vdCBiZS4KLSAgICoKLSAgICogQHBhcmFtIGluU2NvcGUgICAgdHJ1ZSBpZiBhbGwgbmFtZXNwYWNlcyBpbiBzY29wZSBzaG91bGQgYmUgcmV0dXJuZWQsCi0gICAqICAgICAgICAgICAgICAgICAgIGZhbHNlIGlmIG9ubHkgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgc2hvdWxkIGJlCi0gICAqICAgICAgICAgICAgICAgICAgIHJldHVybmVkLgotICAgKiBAcmV0dXJuIGhhbmRsZSBvZiBmaXJzdCBuYW1lc3BhY2UsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRGaXJzdE5hbWVzcGFjZU5vZGUoaW50IG5vZGVIYW5kbGUsIGJvb2xlYW4gaW5TY29wZSkKLSAgewotICAgICAgICBpZihpblNjb3BlKQotICAgICAgICB7Ci0gICAgICAgICAgICBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbnNDb250ZXh0PWZpbmROYW1lc3BhY2VDb250ZXh0KG5vZGVIYW5kbGUgJiBtX21hc2spOwotICAgICAgICAgICAgaWYobnNDb250ZXh0PT1udWxsIHx8IG5zQ29udGV4dC5zaXplKCk8MSkKLSAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgICAgIHJldHVybiBuc0NvbnRleHQuZWxlbWVudEF0KDApIHwgbV9kdG1JZGVudDsKLSAgICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAvLyBBc3N1bWUgdGhhdCBhdHRyaWJ1dGVzIGFuZCBuYW1lc3BhY2VzIGltbWVkaWF0ZWx5Ci0gICAgICAgICAgICAvLyBmb2xsb3cgdGhlIGVsZW1lbnQuCi0gICAgICAgICAgICAvLwotICAgICAgICAgICAgLy8gJU9QVCUgV291bGQgdGhpbmdzIGJlIGZhc3RlciBpZiBhbGwgTlMgbm9kZXMgd2VyZSBidWlsdAotICAgICAgICAgICAgLy8gYmVmb3JlIGFsbCBBdHRyIG5vZGVzPyBTb21lIGNvc3RzIGF0IGJ1aWxkIHRpbWUgZm9yIDJuZAotICAgICAgICAgICAgLy8gcGFzcy4uLgotICAgICAgICAgICAgaW50IGlkZW50aXR5ID0gbm9kZUhhbmRsZSAmIG1fbWFzazsKLSAgICAgICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoaWRlbnRpdHkgPSBnZXROZXh0Tm9kZUlkZW50aXR5KGlkZW50aXR5KSkpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlKGlkZW50aXR5KTsKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBEVE0uTkFNRVNQQUNFX05PREUpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBpZGVudGl0eSB8IG1fZHRtSWRlbnQ7Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoRFRNLkFUVFJJQlVURV9OT0RFICE9IHR5cGUpCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IG5hbWVzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIGJhc2VIYW5kbGUgaGFuZGxlIHRvIG9yaWdpbmFsIG5vZGUgZnJvbSB3aGVyZSB0aGUgZmlyc3QgbmFtZXNwYWNlCi0gICAqIHdhcyByZWxhdGl2ZSB0byAobmVlZGVkIHRvIHJldHVybiBub2RlcyBpbiBkb2N1bWVudCBvcmRlcikuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VIYW5kbGUgaGFuZGxlIHRvIG5vZGUgd2hpY2ggbXVzdCBiZSBvZiB0eXBlCi0gICAqIE5BTUVTUEFDRV9OT0RFLgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBBIG5hbWVzcGFjZSBoYW5kbGUgZm9yIHdoaWNoIHdlIHdpbGwgZmluZCB0aGUgbmV4dCBub2RlLgotICAgKiBAcGFyYW0gaW5TY29wZSB0cnVlIGlmIGFsbCBuYW1lc3BhY2VzIHRoYXQgYXJlIGluIHNjb3BlIHNob3VsZCBiZSBwcm9jZXNzZWQsCi0gICAqIG90aGVyd2lzZSBqdXN0IHByb2Nlc3MgdGhlIG5vZGVzIGluIHRoZSBnaXZlbiBlbGVtZW50IGhhbmRsZS4KLSAgICogQHJldHVybiBoYW5kbGUgb2YgbmV4dCBuYW1lc3BhY2UsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0TmFtZXNwYWNlTm9kZShpbnQgYmFzZUhhbmRsZSwgaW50IG5vZGVIYW5kbGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpblNjb3BlKQotICB7Ci0gICAgICAgIGlmKGluU2NvcGUpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy9TaW5jZSB3ZSd2ZSBiZWVuIGdpdmVuIHRoZSBiYXNlLCB0cnkgZGlyZWN0IGxvb2t1cAotICAgICAgICAgICAgLy8oY291bGQgbG9vayBmcm9tIG5vZGVIYW5kbGUgYnV0IHRoaXMgaXMgYXQgbGVhc3Qgb25lCi0gICAgICAgICAgICAvL2NvbXBhcmlzb24vZ2V0LXBhcmVudCBmYXN0ZXIpCi0gICAgICAgICAgICAvL1N1YmFsbG9jYXRlZEludFZlY3RvciBuc0NvbnRleHQ9ZmluZE5hbWVzcGFjZUNvbnRleHQobm9kZUhhbmRsZSAmIG1fbWFzayk7Ci0KLSAgICAgICAgICAgICAgICBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IgbnNDb250ZXh0PWZpbmROYW1lc3BhY2VDb250ZXh0KGJhc2VIYW5kbGUgJiBtX21hc2spOwotCi0gICAgICAgICAgICBpZihuc0NvbnRleHQ9PW51bGwpCi0gICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICAgICAgaW50IGk9MSArIG5zQ29udGV4dC5pbmRleE9mKG5vZGVIYW5kbGUpOwotICAgICAgICAgICAgaWYoaTw9MCB8fCBpPT1uc0NvbnRleHQuc2l6ZSgpKQotICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgICAgICAgcmV0dXJuIG5zQ29udGV4dC5lbGVtZW50QXQoaSkgfCBtX2R0bUlkZW50OwotICAgICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIEFzc3VtZSB0aGF0IGF0dHJpYnV0ZXMgYW5kIG5hbWVzcGFjZSBub2RlcyBpbW1lZGlhdGVseSBmb2xsb3cgdGhlIGVsZW1lbnQuCi0gICAgICAgICAgICBpbnQgaWRlbnRpdHkgPSBub2RlSGFuZGxlICYgbV9tYXNrOwotICAgICAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChpZGVudGl0eSA9IGdldE5leHROb2RlSWRlbnRpdHkoaWRlbnRpdHkpKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUoaWRlbnRpdHkpOwotICAgICAgICAgICAgICAgIGlmICh0eXBlID09IERUTS5OQU1FU1BBQ0VfTk9ERSkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkZW50aXR5IHwgbV9kdG1JZGVudDsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlICE9IERUTS5BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIGl0cyBwYXJlbnQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBwYXJlbnQsCi0gICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRQYXJlbnQoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPiAwKQotICAgICAgcmV0dXJuIF9wYXJlbnQoaWRlbnRpdHkpIHwgbV9kdG1JZGVudDsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgdGhlIG93bmluZyBkb2N1bWVudCBub2RlLgotICAgKgotICAgKiAgQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiAgQHJldHVybiBpbnQgTm9kZSBoYW5kbGUgb2YgZG9jdW1lbnQsIHdoaWNoIHNob3VsZCBhbHdheXMgYmUgdmFsaWQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldERvY3VtZW50KCkKLSAgewotICAgIHJldHVybiBtX2R0bUlkZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgdGhlIG93bmluZyBkb2N1bWVudCBub2RlLiAgVGhpcyBoYXMgdGhlIGV4YWN0Ci0gICAqIHNhbWUgc2VtYW50aWNzIGFzIHRoZSBET00gRG9jdW1lbnQgbWV0aG9kIG9mIHRoZSBzYW1lIG5hbWUsIGluIHRoYXQgaWYKLSAgICogdGhlIG5vZGVIYW5kbGUgaXMgYSBkb2N1bWVudCBub2RlLCBpdCB3aWxsIHJldHVybiBOVUxMLgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBTaW5jZSB0aGlzIGlzIERPTS1zcGVjaWZpYywgaXQgbWF5IGJlbG9uZyBhdCB0aGUgRE9NCi0gICAqIGJpbmRpbmcgbGF5ZXIuIEluY2x1ZGVkIGhlcmUgYXMgYSBjb252ZW5pZW5jZSBmdW5jdGlvbiBhbmQgdG8KLSAgICogYWlkIHBvcnRpbmcgb2YgRE9NIGNvZGUgdG8gRFRNLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBvd25pbmcgZG9jdW1lbnQsIG9yIC0xIGlmIHRoZSBub2RlSGFuZGxlIGlzCi0gICAqICAgICAgICAgICAgIGEgZG9jdW1lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE93bmVyRG9jdW1lbnQoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0KLSAgICBpZiAoRFRNLkRPQ1VNRU5UX05PREUgPT0gdHlwZSkKLSAgICB7Ci0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgcmV0dXJuIGdldERvY3VtZW50KCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlIGFzIGEgU3RyaW5nIG9iamVjdAotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHZXQgbnVtYmVyIG9mIGNoYXJhY3RlciBhcnJheSBjaHVua3MgaW4KLSAgICogdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUuCi0gICAqIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4KLSAgICogTm90ZSB0aGF0IGEgc2luZ2xlIHRleHQgbm9kZSBtYXkgaGF2ZSBtdWx0aXBsZSB0ZXh0IGNodW5rcy4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtYmVyIG9mIGNoYXJhY3RlciBhcnJheSBjaHVua3MgaW4KLSAgICogICAgICAgICB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0U3RyaW5nVmFsdWVDaHVua0NvdW50KGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyAlVEJEJQotICAgIGVycm9yKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX01FVEhPRF9OT1RfU1VQUE9SVEVELCBudWxsKSk7Ly8oImdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudCBub3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNoYXJhY3RlciBhcnJheSBjaHVuayBpbiB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgKiBOb3RlIHRoYXQgYSBzaW5nbGUgdGV4dCBub2RlIG1heSBoYXZlIG11bHRpcGxlIHRleHQgY2h1bmtzLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNodW5rSW5kZXggV2hpY2ggY2h1bmsgdG8gZ2V0LgotICAgKiBAcGFyYW0gc3RhcnRBbmRMZW4gQW4gYXJyYXkgb2YgMiB3aGVyZSB0aGUgc3RhcnQgcG9zaXRpb24gYW5kIGxlbmd0aCBvZgotICAgKiAgICAgICAgICAgICAgICAgICAgdGhlIGNodW5rIHdpbGwgYmUgcmV0dXJuZWQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNoYXJhY3RlciBhcnJheSByZWZlcmVuY2Ugd2hlcmUgdGhlIGNodW5rIG9jY3Vycy4KLSAgICovCi0gIHB1YmxpYyBjaGFyW10gZ2V0U3RyaW5nVmFsdWVDaHVuayhpbnQgbm9kZUhhbmRsZSwgaW50IGNodW5rSW5kZXgsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRbXSBzdGFydEFuZExlbikKLSAgewotCi0gICAgLy8gJVRCRCUKLSAgICBlcnJvcihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwgbnVsbCkpOy8vImdldFN0cmluZ1ZhbHVlQ2h1bmsgbm90IHlldCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gYW4gSUQgdGhhdCByZXByZXNlbnRzIHRoZSBub2RlJ3MgZXhwYW5kZWQgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIGhhbmRsZSB0byB0aGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZXhwYW5kZWQtbmFtZSBpZCBvZiB0aGUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIHJldHVybiBfZXhwdHlwZShub2RlSGFuZGxlICYgbV9tYXNrKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBleHBhbmRlZCBuYW1lLCByZXR1cm4gYW4gSUQuICBJZiB0aGUgZXhwYW5kZWQtbmFtZSBkb2VzIG5vdAotICAgKiBleGlzdCBpbiB0aGUgaW50ZXJuYWwgdGFibGVzLCB0aGUgZW50cnkgd2lsbCBiZSBjcmVhdGVkLCBhbmQgdGhlIElEIHdpbGwKLSAgICogYmUgcmV0dXJuZWQuICBBbnkgYWRkaXRpb25hbCBub2RlcyB0aGF0IGFyZSBjcmVhdGVkIHRoYXQgaGF2ZSB0aGlzCi0gICAqIGV4cGFuZGVkIG5hbWUgd2lsbCB1c2UgdGhpcyBJRC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIGhhbmRsZSB0byB0aGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICogQHBhcmFtIHR5cGUgVGhlIHNpbXBsZSB0eXBlLCBpLmUuIG9uZSBvZiBFTEVNRU5ULCBBVFRSSUJVVEUsIGV0Yy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIFVSSSwgd2hpY2ggbWF5IGJlIG51bGwsIG1heSBiZSBhbiBlbXB0eQotICAgKiAgICAgICAgICAgICAgICAgIHN0cmluZyAod2hpY2ggd2lsbCBiZSB0aGUgc2FtZSBhcyBudWxsKSwgb3IgbWF5IGJlIGEKLSAgICogICAgICAgICAgICAgICAgICBuYW1lc3BhY2UgVVJJLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lIHN0cmluZywgd2hpY2ggbXVzdCBiZSBhIHZhbGlkCi0gICAqICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC1uYW1lcy8iPk5DTmFtZTwvYT4uCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKFN0cmluZyBuYW1lc3BhY2UsIFN0cmluZyBsb2NhbE5hbWUsIGludCB0eXBlKQotICB7Ci0KLSAgICBFeHBhbmRlZE5hbWVUYWJsZSBlbnQgPSBtX2V4cGFuZGVkTmFtZVRhYmxlOwotCi0gICAgcmV0dXJuIGVudC5nZXRFeHBhbmRlZFR5cGVJRChuYW1lc3BhY2UsIGxvY2FsTmFtZSwgdHlwZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgZXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWROYW1lSUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBwYXJ0LgotICAgKgotICAgKiBAcGFyYW0gRXhwYW5kZWROYW1lSUQgYW4gSUQgdGhhdCByZXByZXNlbnRzIGFuIGV4cGFuZGVkLW5hbWUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRnJvbUV4cGFuZGVkTmFtZUlEKGludCBleHBhbmRlZE5hbWVJRCkKLSAgewotICAgIHJldHVybiBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZShleHBhbmRlZE5hbWVJRCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIHR5cGUgb2YgYSBzcGVjaWZpYyBub2RlCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiB0aGUgSUQgb2YgdGhlIG5hbWVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TmFtZXNwYWNlVHlwZShmaW5hbCBpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgaW50IGlkZW50aXR5ID0gbm9kZUhhbmRsZSAmIG1fbWFzazsKLSAgICBpbnQgZXhwYW5kZWROYW1lSUQgPSBfZXhwdHlwZShpZGVudGl0eSk7Ci0KLSAgICByZXR1cm4gRXhwYW5kZWROYW1lVGFibGUuZ2V0TmFtZXNwYWNlSUQoZXhwYW5kZWROYW1lSUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgbmFtZS4gVGhpcyB3aWxsCi0gICAqIGluY2x1ZGUgbmFtZXMgc3VjaCBhcyAjdGV4dCBvciAjZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcuCi0gICAqICVSRVZJRVclIERvY3VtZW50IHdoZW4gZW1wdHkgc3RyaW5nIGlzIHBvc3NpYmxlLi4uCi0gICAqICVSRVZJRVctQ09NTUVOVCUgSXQgc2hvdWxkIG5ldmVyIGJlIGVtcHR5LCBzaG91bGQgaXQ/Ci0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldE5vZGVOYW1lKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIHRoZSBYUGF0aCBub2RlIG5hbWUuICBUaGlzIHNob3VsZCBiZQotICAgKiB0aGUgbmFtZSBhcyBkZXNjcmliZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwsIE5PVCB0aGUgRE9NLXN0eWxlCi0gICAqIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTmFtZSBvZiB0aGlzIG5vZGUsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVOYW1lWChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgLyoqIEB0b2RvOiBpbXBsZW1lbnQgdGhpcyBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRGVmYXVsdEJhc2UgYWJzdHJhY3QgbWV0aG9kICovCi0gICAgZXJyb3IoWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsIG51bGwpKTsvLyJOb3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgWFBhdGgtc3R5bGUgbG9jYWxuYW1lLgotICAgKiAoQXMgZGVmaW5lZCBpbiBOYW1lc3BhY2VzLCB0aGlzIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSBuYW1lIGFmdGVyIGFueQotICAgKiBjb2xvbiBjaGFyYWN0ZXIpLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIExvY2FsIG5hbWUgb2YgdGhpcyBub2RlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpOwotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHRoYXQgdGhlIG5hbWVzcGFjZSBkZWNsIGlzCi0gICAqIG1hcHBpbmcuCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHVzZWQgdG8gbWFwIHRvIHRoZSBuYW1lc3BhY2UuCi0gICAqCi0gICAqIDxwPiAlUkVWSUVXJSBBcmUgeW91IHN1cmUgeW91IHdhbnQgIiIgZm9yIG5vIHByZWZpeD8gIDwvcD4KLSAgICogPHA+ICVSRVZJRVctQ09NTUVOVCUgSSB0aGluayBzby4uLiBub3QgdG90YWxseSBzdXJlLiAtc2IgIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBwcmVmaXggb2YgdGhpcyBub2RlJ3MgbmFtZSwgb3IgIiIgaWYgbm8gZXhwbGljaXQKLSAgICogbmFtZXNwYWNlIHByZWZpeCB3YXMgZ2l2ZW4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFByZWZpeChpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5hbWVzcGFjZSBVUkkKLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgZGVjbGFyZWQgVVJJIHdoaWNoIHRoaXMgbm9kZSdzCi0gICAqIHByZWZpeCAtLSBvciBkZWZhdWx0IGluIGxpZXUgdGhlcmVvZiAtLSB3YXMgbWFwcGVkIHRvLikKLSAgICoKLSAgICogPHA+JVJFVklFVyUgTnVsbCBvciAiIj8gLXNiPC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBub2RlSGFuZGxlKTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBub2RlIHZhbHVlLiBUaGlzIGlzIG1vc3RseQotICAgKiBhcyBkZWZpbmVkIGJ5IHRoZSBET00sIGJ1dCBtYXkgaWdub3JlIHNvbWUgY29udmVuaWVuY2VzLgotICAgKiA8cD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAqIEByZXR1cm4gU3RyaW5nIFZhbHVlIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBub3QKLSAgICogbWVhbmluZ2Z1bCBmb3IgdGhpcyBub2RlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUhhbmRsZSk7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5vZGUgdHlwZS4KLSAgICogPHA+Ci0gICAqICVSRVZJRVclIEdlbmVyYWxseSwgcmV0dXJuaW5nIHNob3J0IGlzIGZhbHNlIGVjb25vbXkuIFJldHVybiBpbnQ/Ci0gICAqICVSRVZJRVclIE1ha2UgYXNzdW1wdGlvbiB0aGF0IG5vZGUgaGFzIGFscmVhZHkgYXJyaXZlZC4gIElzIE9LPwotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICogQHJldHVybiBpbnQgTm9kZSB0eXBlLCBhcyBwZXIgdGhlIERPTSdzIE5vZGUuX05PREUgY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgcmV0dXJuIChzaG9ydCkoX2V4cHR5cGUobm9kZUhhbmRsZSAmIG1fbWFzaykgPj4gRXhwYW5kZWROYW1lVGFibGUuUk9UQU1PVU5UX1RZUEUpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBHZXQgdGhlIGRlcHRoIGxldmVsIG9mIHRoaXMgbm9kZSBpbiB0aGUgdHJlZSAoZXF1YWxzIDEgZm9yCi0gICAqIGEgcGFyZW50bGVzcyBub2RlKS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBhbmNlc3RvcnMsIHBsdXMgb25lCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0TGV2ZWwoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICAvLyBBcHBhcmVudGx5LCB0aGUgYXhpcyB3YWxrZXIgc3R1ZmYgcmVxdWlyZXMgbGV2ZWxzIHRvIGNvdW50IGZyb20gMS4KLSAgICBpbnQgaWRlbnRpdHkgPSBub2RlSGFuZGxlICYgbV9tYXNrOwotICAgIHJldHVybiAoc2hvcnQpIChfbGV2ZWwoaWRlbnRpdHkpICsgMSk7Ci0gIH0KLQotICAvLyA9PT09PT09PT09PT09PSBEb2N1bWVudCBxdWVyeSBmdW5jdGlvbnMgPT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGVzdHMgd2hldGhlciBEVE0gRE9NIGltcGxlbWVudGF0aW9uIGltcGxlbWVudHMgYSBzcGVjaWZpYyBmZWF0dXJlIGFuZAotICAgKiB0aGF0IGZlYXR1cmUgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmUgVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICogQHBhcmFtIHZlcnNpb25UaGlzIGlzIHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZmVhdHVyZSB0byB0ZXN0LgotICAgKiAgIElmIHRoZSB2ZXJzaW9uIGlzIG5vdAotICAgKiAgIHNwZWNpZmllZCwgc3VwcG9ydGluZyBhbnkgdmVyc2lvbiBvZiB0aGUgZmVhdHVyZSB3aWxsIGNhdXNlIHRoZQotICAgKiAgIG1ldGhvZCB0byByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAqIEBwYXJhbSB2ZXJzaW9uIFRoZSB2ZXJzaW9uIHN0cmluZyBvZiB0aGUgZmVhdHVyZSByZXF1ZXN0ZWQsIG1heSBiZSBudWxsLgotICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGlzCi0gICAqICAgc3VwcG9ydGVkIG9uIHRoaXMgbm9kZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikKLSAgewotCi0gICAgLy8gJVRCRCUKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LiBJZiBpdCBpcyBub3Qga25vd24KLSAgICogKGJlY2F1c2UgdGhlIGRvY3VtZW50IHdhcyBwYXJzZWQgZnJvbSBhIHNvY2tldCBjb25uZWN0aW9uIG9yIGZyb20KLSAgICogc3RhbmRhcmQgaW5wdXQsIGZvciBleGFtcGxlKSwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdW5rbm93bi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50QmFzZVVSSSgpCi0gIHsKLSAgICByZXR1cm4gbV9kb2N1bWVudEJhc2VVUkk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LgotICAgKgotICAgKiBAcGFyYW0gYmFzZVVSSSB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpCi0gIHsKLSAgICBtX2RvY3VtZW50QmFzZVVSSSA9IGJhc2VVUkk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LiBJZgotICAgKiBpdCBpcyBub3Qga25vd24sIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIHVua25vd24uCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0IG9yIG51bGwgaWYgdW5rbm93bi4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTeXN0ZW1JZGVudGlmaWVyKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyAlUkVWSUVXJSAgT0s/IC1zYgotICAgIHJldHVybiBtX2RvY3VtZW50QmFzZVVSSTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBzY2hlbWUKLSAgICogICAgICAgIGluIHdoaWNoIHRoZSBkb2N1bWVudCBlbnRpdHkgaXMgZXhwcmVzc2VkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZCwgd2hpY2ggY2FuIGJlIGFueSB2YWxpZCBub2RlIGhhbmRsZS4KLSAgICogQHJldHVybiB0aGUgZG9jdW1lbnQgZW5jb2RpbmcgU3RyaW5nIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRFbmNvZGluZyhpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgLy8gJVJFVklFVyUgIE9LPz8gIC1zYgotICAgIHJldHVybiAiVVRGLTgiOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhbiBpbmRpY2F0aW9uIG9mIHRoZSBzdGFuZGFsb25lIHN0YXR1cyBvZiB0aGUgZG9jdW1lbnQsCi0gICAqICAgICAgICBlaXRoZXIgInllcyIgb3IgIm5vIi4gVGhpcyBwcm9wZXJ0eSBpcyBkZXJpdmVkIGZyb20gdGhlIG9wdGlvbmFsCi0gICAqICAgICAgICBzdGFuZGFsb25lIGRvY3VtZW50IGRlY2xhcmF0aW9uIGluIHRoZSBYTUwgZGVjbGFyYXRpb24gYXQgdGhlCi0gICAqICAgICAgICBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGhhcyBubyB2YWx1ZSBpZiB0aGVyZSBpcyBubwotICAgKiAgICAgICAgc3RhbmRhbG9uZSBkb2N1bWVudCBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQsIHdoaWNoIGNhbiBiZSBhbnkgdmFsaWQgbm9kZSBoYW5kbGUuCi0gICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IHN0YW5kYWxvbmUgU3RyaW5nIG9iamVjdCwgZWl0aGVyICJ5ZXMiLCAibm8iLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN0YW5kYWxvbmUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQuIFRoaXMKLSAgICogcHJvcGVydHkgaXMgZGVyaXZlZCBmcm9tIHRoZSBYTUwgZGVjbGFyYXRpb24gb3B0aW9uYWxseSBwcmVzZW50IGF0IHRoZQotICAgKiBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGhhcyBubyB2YWx1ZSBpZiB0aGVyZSBpcyBubyBYTUwKLSAgICogZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBkb2N1bWVudEhhbmRsZSBUaGUgZG9jdW1lbnQgaGFuZGxlCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IHZlcnNpb24gU3RyaW5nIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRWZXJzaW9uKGludCBkb2N1bWVudEhhbmRsZSkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhbiBpbmRpY2F0aW9uIG9mCi0gICAqIHdoZXRoZXIgdGhlIHByb2Nlc3NvciBoYXMgcmVhZCB0aGUgY29tcGxldGUgRFRELiBJdHMgdmFsdWUgaXMgYQotICAgKiBib29sZWFuLiBJZiBpdCBpcyBmYWxzZSwgdGhlbiBjZXJ0YWluIHByb3BlcnRpZXMgKGluZGljYXRlZCBpbiB0aGVpcgotICAgKiBkZXNjcmlwdGlvbnMgYmVsb3cpIG1heSBiZSB1bmtub3duLiBJZiBpdCBpcyB0cnVlLCB0aG9zZSBwcm9wZXJ0aWVzCi0gICAqIGFyZSBuZXZlciB1bmtub3duLgotICAgKgotICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFsbCBkZWNsYXJhdGlvbnMgd2VyZSBwcm9jZXNzZWQ7Ci0gICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldERvY3VtZW50QWxsRGVjbGFyYXRpb25zUHJvY2Vzc2VkKCkKLSAgewotCi0gICAgLy8gJVJFVklFVyUgT0s/Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogICBBIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gaW5mb3JtYXRpb24gaXRlbSBoYXMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgotICAgKgotICAgKiAgICAgMS4gW3N5c3RlbSBpZGVudGlmaWVyXSBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIHN1YnNldCwgaWYKLSAgICogICAgICAgIGl0IGV4aXN0cy4gT3RoZXJ3aXNlIHRoaXMgcHJvcGVydHkgaGFzIG5vIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uU3lzdGVtSWRlbnRpZmllcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQsCi0gICAqIG5vcm1hbGl6ZWQgYXMgZGVzY3JpYmVkIGluIDQuMi4yIEV4dGVybmFsIEVudGl0aWVzIFtYTUxdLiBJZiB0aGVyZSBpcwotICAgKiBubyBleHRlcm5hbCBzdWJzZXQgb3IgaWYgaXQgaGFzIG5vIHB1YmxpYyBpZGVudGlmaWVyLCB0aGlzIHByb3BlcnR5Ci0gICAqIGhhcyBubyB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIGhhbmRsZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uUHVibGljSWRlbnRpZmllcigpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpOwotCi0gIC8qKgotICAgKiBUaGUgZ2V0VW5wYXJzZWRFbnRpdHlVUkkgZnVuY3Rpb24gcmV0dXJucyB0aGUgVVJJIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaW4gdGhlIHNhbWUgZG9jdW1lbnQgYXMgdGhlIGNvbnRleHQKLSAgICogbm9kZSAoc2VlIFszLjMgVW5wYXJzZWQgRW50aXRpZXNdKS4gSXQgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqIHRoZXJlIGlzIG5vIHN1Y2ggZW50aXR5LgotICAgKiA8cD4KLSAgICogWE1MIHByb2Nlc3NvcnMgbWF5IGNob29zZSB0byB1c2UgdGhlIFN5c3RlbSBJZGVudGlmaWVyIChpZiBvbmUKLSAgICogaXMgcHJvdmlkZWQpIHRvIHJlc29sdmUgdGhlIGVudGl0eSwgcmF0aGVyIHRoYW4gdGhlIFVSSSBpbiB0aGUKLSAgICogUHVibGljIElkZW50aWZpZXIuIFRoZSBkZXRhaWxzIGFyZSBkZXBlbmRlbnQgb24gdGhlIHByb2Nlc3NvciwgYW5kCi0gICAqIHdlIHdvdWxkIGhhdmUgdG8gc3VwcG9ydCBzb21lIGZvcm0gb2YgcGx1Zy1pbiByZXNvbHZlciB0byBoYW5kbGUKLSAgICogdGhpcyBwcm9wZXJseS4gQ3VycmVudGx5LCB3ZSBzaW1wbHkgcmV0dXJuIHRoZSBTeXN0ZW0gSWRlbnRpZmllciBpZgotICAgKiBwcmVzZW50LCBhbmQgaG9wZSB0aGF0IGl0IGEgdXNhYmxlIFVSSSBvciB0aGF0IG91ciBjYWxsZXIgY2FuCi0gICAqIG1hcCBpdCB0byBvbmUuCi0gICAqIFRPRE86IFJlc29sdmUgUHVibGljIElkZW50aWZpZXJzLi4uIG9yIGNvbnNpZGVyIGNoYW5naW5nIGZ1bmN0aW9uIG5hbWUuCi0gICAqIDxwPgotICAgKiBJZiB3ZSBmaW5kIGEgcmVsYXRpdmUgVVJJCi0gICAqIHJlZmVyZW5jZSwgWE1MIGV4cGVjdHMgaXQgdG8gYmUgcmVzb2x2ZWQgaW4gdGVybXMgb2YgdGhlIGJhc2UgVVJJCi0gICAqIG9mIHRoZSBkb2N1bWVudC4gVGhlIERPTSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLCBhbmQgaXQgaXNuJ3QKLSAgICogZW50aXJlbHkgY2xlYXIgd2hldGhlciB0aGF0IHNob3VsZCBiZSBkb25lIGhlcmU7IGN1cnJlbnRseSB0aGF0J3MKLSAgICogcHVzaGVkIHVwIHRvIGEgaGlnaGVyIGxldmVsIG9mIG91ciBhcHBsaWNhdGlvbi4gKE5vdGUgdGhhdCBET00gTGV2ZWwKLSAgICogMSBkaWRuJ3Qgc3RvcmUgdGhlIGRvY3VtZW50J3MgYmFzZSBVUkkuKQotICAgKiBUT0RPOiBDb25zaWRlciByZXNvbHZpbmcgUmVsYXRpdmUgVVJJcy4KLSAgICogPHA+Ci0gICAqIChUaGUgRE9NJ3Mgc3RhdGVtZW50IHRoYXQgIkFuIFhNTCBwcm9jZXNzb3IgbWF5IGNob29zZSB0bwotICAgKiBjb21wbGV0ZWx5IGV4cGFuZCBlbnRpdGllcyBiZWZvcmUgdGhlIHN0cnVjdHVyZSBtb2RlbCBpcyBwYXNzZWQKLSAgICogdG8gdGhlIERPTSIgcmVmZXJzIG9ubHkgdG8gcGFyc2VkIGVudGl0aWVzLCBub3QgdW5wYXJzZWQsIGFuZCBoZW5jZQotICAgKiBkb2Vzbid0IGFmZmVjdCB0aGlzIGZ1bmN0aW9uLikKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgRW50aXR5IE5hbWUgb2YgdGhlIHVucGFyc2VkCi0gICAqIGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgVVJJIG9mIHRoZSBVbnBhcnNlZCBFbnRpdHksIG9yIGFuCi0gICAqIGVtcHR5IHN0cmluZyBpZiBubyBzdWNoIGVudGl0eSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKTsKLQotICAvLyA9PT09PT09PT09PT09PSBCb29sZWFuIG1ldGhvZHMgPT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgeHNsOnN0cmlwLXNwYWNlIG9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSB3YXMgcHJvY2Vzc2VkCi0gICAqIGR1cmluZyBjb25zdHJ1Y3Rpb24gb2YgdGhlIERUTSBkb2N1bWVudC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgRFRNIHN1cHBvcnRzIHByZXN0cmlwcGluZy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzUHJlU3RyaXBwaW5nKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpZ3VyZSBvdXQgd2hldGhlciBub2RlSGFuZGxlMiBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyBiZWluZyBsYXRlcgotICAgKiBpbiB0aGUgZG9jdW1lbnQgdGhhbiBub2RlSGFuZGxlMSwgaW4gRG9jdW1lbnQgT3JkZXIgYXMgZGVmaW5lZAotICAgKiBieSB0aGUgWFBhdGggbW9kZWwuIFRoaXMgbWF5IG5vdCBhZ3JlZSB3aXRoIHRoZSBvcmRlcmluZyBkZWZpbmVkCi0gICAqIGJ5IG90aGVyIFhNTCBhcHBsaWNhdGlvbnMuCi0gICAqIDxwPgotICAgKiBUaGVyZSBhcmUgc29tZSBjYXNlcyB3aGVyZSBvcmRlcmluZyBpc24ndCBkZWZpbmVkLCBhbmQgbmVpdGhlciBhcmUKLSAgICogdGhlIHJlc3VsdHMgb2YgdGhpcyBmdW5jdGlvbiAtLSB0aG91Z2ggd2UnbGwgZ2VuZXJhbGx5IHJldHVybiB0cnVlLgotICAgKgotICAgKiBUT0RPOiBNYWtlIHN1cmUgdGhpcyBkb2VzIHRoZSByaWdodCB0aGluZyB3aXRoIGF0dHJpYnV0ZSBub2RlcyEhIQotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZTEgTm9kZSBoYW5kbGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uLgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZTIgU2Vjb25kIE5vZGUgaGFuZGxlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbiAuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UgaWYgbm9kZTIgY29tZXMgYmVmb3JlIG5vZGUxLCBvdGhlcndpc2UgcmV0dXJuIHRydWUuCi0gICAqIFlvdSBjYW4gdGhpbmsgb2YgdGhpcyBhcwotICAgKiA8Y29kZT4obm9kZTEuZG9jdW1lbnRPcmRlclBvc2l0aW9uICZsdDs9IG5vZGUyLmRvY3VtZW50T3JkZXJQb3NpdGlvbik8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2RlQWZ0ZXIoaW50IG5vZGVIYW5kbGUxLCBpbnQgbm9kZUhhbmRsZTIpCi0gIHsKLSAgICBpZigobm9kZUhhbmRsZTEgJiB+bV9tYXNrKSAhPSAobm9kZUhhbmRsZTIgJiB+bV9tYXNrKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGludCBpbmRleDEgPSBub2RlSGFuZGxlMSAmIG1fbWFzazsKLSAgICBpbnQgaW5kZXgyID0gbm9kZUhhbmRsZTIgJiBtX21hc2s7Ci0KLSAgICByZXR1cm4gaW5kZXgxIDw9IGluZGV4MjsKLSAgfQotCi0gIC8qKgotICAgKiAgICAgMi4gW2VsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlXSBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZQotICAgKiAgICAgICAgY2hhcmFjdGVyIGlzIHdoaXRlIHNwYWNlIGFwcGVhcmluZyB3aXRoaW4gZWxlbWVudCBjb250ZW50IChzZWUgW1hNTF0sCi0gICAqICAgICAgICAyLjEwICJXaGl0ZSBTcGFjZSBIYW5kbGluZyIpLiBOb3RlIHRoYXQgdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29ycyBhcmUKLSAgICogICAgICAgIHJlcXVpcmVkIGJ5IFhNTCAxLjAgdG8gcHJvdmlkZSB0aGlzIGluZm9ybWF0aW9uLiBJZiB0aGVyZSBpcyBubwotICAgKiAgICAgICAgZGVjbGFyYXRpb24gZm9yIHRoZSBjb250YWluaW5nIGVsZW1lbnQsIHRoaXMgcHJvcGVydHkgaGFzIG5vIHZhbHVlIGZvcgotICAgKiAgICAgICAgd2hpdGUgc3BhY2UgY2hhcmFjdGVycy4gSWYgbm8gZGVjbGFyYXRpb24gaGFzIGJlZW4gcmVhZCwgYnV0IHRoZSBbYWxsCi0gICAqICAgICAgICBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcwotICAgKiAgICAgICAgZmFsc2UgKHNvIHRoZXJlIG1heSBiZSBhbiB1bnJlYWQgZGVjbGFyYXRpb24pLCB0aGVuIHRoZSB2YWx1ZSBvZiB0aGlzCi0gICAqICAgICAgICBwcm9wZXJ0eSBpcyB1bmtub3duIGZvciB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzLiBJdCBpcyBhbHdheXMgZmFsc2UgZm9yCi0gICAqICAgICAgICBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCB3aGl0ZSBzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGUgSUQuCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkYXRhIGlzIHdoaXRlc3BhY2U7Ci0gICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVyRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyAlVEJEJQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiAgICAxMC4gW2FsbCBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBUaGlzIHByb3BlcnR5IGlzIG5vdCBzdHJpY3RseSBzcGVha2luZwotICAgKiAgICAgICAgcGFydCBvZiB0aGUgaW5mb3NldCBvZiB0aGUgZG9jdW1lbnQuIFJhdGhlciBpdCBpcyBhbiBpbmRpY2F0aW9uIG9mCi0gICAqICAgICAgICB3aGV0aGVyIHRoZSBwcm9jZXNzb3IgaGFzIHJlYWQgdGhlIGNvbXBsZXRlIERURC4gSXRzIHZhbHVlIGlzIGEKLSAgICogICAgICAgIGJvb2xlYW4uIElmIGl0IGlzIGZhbHNlLCB0aGVuIGNlcnRhaW4gcHJvcGVydGllcyAoaW5kaWNhdGVkIGluIHRoZWlyCi0gICAqICAgICAgICBkZXNjcmlwdGlvbnMgYmVsb3cpIG1heSBiZSB1bmtub3duLiBJZiBpdCBpcyB0cnVlLCB0aG9zZSBwcm9wZXJ0aWVzCi0gICAqICAgICAgICBhcmUgbmV2ZXIgdW5rbm93bi4KLSAgICoKLSAgICogQHBhcmFtIHRoZSBkb2N1bWVudCBoYW5kbGUKLSAgICoKLSAgICogQHBhcmFtIGRvY3VtZW50SGFuZGxlIEEgbm9kZSBoYW5kbGUgdGhhdCBtdXN0IGlkZW50aWZ5IGEgZG9jdW1lbnQuCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYWxsIGRlY2xhcmF0aW9ucyB3ZXJlIHByb2Nlc3NlZDsKLSAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZChpbnQgZG9jdW1lbnRIYW5kbGUpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiAgICAgNS4gW3NwZWNpZmllZF0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSB3YXMgYWN0dWFsbHkKLSAgICogICAgICAgIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQtdGFnIG9mIGl0cyBlbGVtZW50LCBvciB3YXMgZGVmYXVsdGVkIGZyb20gdGhlCi0gICAqICAgICAgICBEVEQuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVIYW5kbGUgVGhlIGF0dHJpYnV0ZSBoYW5kbGUgaW4gcXVlc3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGF0dHJpYnV0ZSB3YXMgc3BlY2lmaWVkOwotICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCB3YXMgZGVmYXVsdGVkLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaW50IGF0dHJpYnV0ZUhhbmRsZSk7Ci0KLSAgLy8gPT09PT09PT09PSBEaXJlY3QgU0FYIERpc3BhdGNoLCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzID09PT09PT09Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICogQHBhcmFtIG5vcm1hbGl6ZSB0cnVlIGlmIHRoZSBjb250ZW50IHNob3VsZCBiZSBub3JtYWxpemVkIGFjY29yZGluZyB0bwotICAgKiB0aGUgcnVsZXMgZm9yIHRoZSBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNmdW5jdGlvbi1ub3JtYWxpemUtc3BhY2UiPm5vcm1hbGl6ZS1zcGFjZTwvYT4KLSAgICogZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoCi0gICAgaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoLCBib29sZWFuIG5vcm1hbGl6ZSkKLSAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNyZWF0ZSBTQVggcGFyc2VyIGV2ZW50cyBmcm9tIGEgc3VidHJlZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqIEBwYXJhbSBjaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgZGlzcGF0Y2hUb0V2ZW50cygKLSAgICBpbnQgbm9kZUhhbmRsZSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBSZXR1cm4gYW4gRE9NIG5vZGUgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICoKLSAgICogQHJldHVybiBBIG5vZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIERUTSBub2RlLgotICAgKi8KLSAgcHVibGljIG9yZy53M2MuZG9tLk5vZGUgZ2V0Tm9kZShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIHJldHVybiBuZXcgRFRNTm9kZVByb3h5KHRoaXMsIG5vZGVIYW5kbGUpOwotICB9Ci0KLSAgLy8gPT09PSBDb25zdHJ1Y3Rpb24gbWV0aG9kcyAobWF5IG5vdCBiZSBzdXBwb3J0ZWQgYnkgc29tZSBpbXBsZW1lbnRhdGlvbnMhKSA9PT09PQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBjaGlsZCB0byB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4gUGxlYXNlIG5vdGUgdGhhdCB0aGUgbm9kZQotICAgKiBpcyBhbHdheXMgY2xvbmVkIGlmIGl0IGlzIG93bmVkIGJ5IGFub3RoZXIgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPiVSRVZJRVclICJFbmQgb2YgdGhlIGRvY3VtZW50IiBuZWVkcyB0byBiZSBkZWZpbmVkIG1vcmUgY2xlYXJseS4KLSAgICogRG9lcyBpdCBiZWNvbWUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIERvY3VtZW50PyBPZiB0aGUgcm9vdCBlbGVtZW50PzwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIE11c3QgYmUgYSB2YWxpZCBuZXcgbm9kZSBoYW5kbGUuCi0gICAqIEBwYXJhbSBjbG9uZSB0cnVlIGlmIHRoZSBjaGlsZCBzaG91bGQgYmUgY2xvbmVkIGludG8gdGhlIGRvY3VtZW50LgotICAgKiBAcGFyYW0gY2xvbmVEZXB0aCBpZiB0aGUgY2xvbmUgYXJndW1lbnQgaXMgdHJ1ZSwgc3BlY2lmaWVzIHRoYXQgdGhlCi0gICAqICAgICAgICAgICAgICAgICAgIGNsb25lIHNob3VsZCBpbmNsdWRlIGFsbCBpdCdzIGNoaWxkcmVuLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kQ2hpbGQoaW50IG5ld0NoaWxkLCBib29sZWFuIGNsb25lLCBib29sZWFuIGNsb25lRGVwdGgpCi0gIHsKLSAgICBlcnJvcihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwgbnVsbCkpOy8vImFwcGVuZENoaWxkIG5vdCB5ZXQgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIHRleHQgbm9kZSBjaGlsZCB0aGF0IHdpbGwgYmUgY29uc3RydWN0ZWQgZnJvbSBhIHN0cmluZywKLSAgICogdG8gdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPiVSRVZJRVclICJFbmQgb2YgdGhlIGRvY3VtZW50IiBuZWVkcyB0byBiZSBkZWZpbmVkIG1vcmUgY2xlYXJseS4KLSAgICogRG9lcyBpdCBiZWNvbWUgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIERvY3VtZW50PyBPZiB0aGUgcm9vdCBlbGVtZW50PzwvcD4KLSAgICoKLSAgICogQHBhcmFtIHN0ciBOb24tbnVsbCByZXZlcmVuY2UgdG8gYSBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhcHBlbmRUZXh0Q2hpbGQoU3RyaW5nIHN0cikKLSAgewotICAgIGVycm9yKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX01FVEhPRF9OT1RfU1VQUE9SVEVELCBudWxsKSk7Ly8iYXBwZW5kVGV4dENoaWxkIG5vdCB5ZXQgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNpbXBsZSBlcnJvciBmb3IgYXNzZXJ0cyBhbmQgdGhlIGxpa2UuCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgRXJyb3IgbWVzc2FnZSB0byByZXBvcnQuCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlcnJvcihTdHJpbmcgbXNnKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihtc2cpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmQgb3V0IHdoZXRoZXIgb3Igbm90IHRvIHN0cmlwIHdoaXNwYWNlIG5vZGVzLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHdoZXRoZXIgb3Igbm90IHRvIHN0cmlwIHdoaXNwYWNlIG5vZGVzLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX3Nob3VsZFN0cmlwV1M7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHdoZXRoZXIgdG8gc3RyaXAgd2hpdGVzcGFjZXMgYW5kIHB1c2ggaW4gY3VycmVudCB2YWx1ZSBvZgotICAgKiBtX3Nob3VsZFN0cmlwV1MgaW4gbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjay4KLSAgICoKLSAgICogQHBhcmFtIHNob3VsZFN0cmlwIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHN0cmlwIHdoaXRlc3BhY2Ugbm9kZXMKLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHB1c2hTaG91bGRTdHJpcFdoaXRlc3BhY2UoYm9vbGVhbiBzaG91bGRTdHJpcCkKLSAgewotCi0gICAgbV9zaG91bGRTdHJpcFdTID0gc2hvdWxkU3RyaXA7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrKQotICAgICAgbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjay5wdXNoKHNob3VsZFN0cmlwKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgd2hldGhlciB0byBzdHJpcCB3aGl0ZXNwYWNlcyBhdCB0aGlzIHBvaW50IGJ5IHBvcHBpbmcgb3V0Ci0gICAqIG1fc2hvdWxkU3RyaXBXaGl0ZXNwYWNlU3RhY2suCi0gICAqCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBwb3BTaG91bGRTdHJpcFdoaXRlc3BhY2UoKQotICB7Ci0gICAgaWYgKG51bGwgIT0gbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjaykKLSAgICAgIG1fc2hvdWxkU3RyaXBXUyA9IG1fc2hvdWxkU3RyaXBXaGl0ZXNwYWNlU3RhY2sucG9wQW5kVG9wKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHdoZXRoZXIgdG8gc3RyaXAgd2hpdGVzcGFjZXMgYW5kIHNldCB0aGUgdG9wIG9mIHRoZSBzdGFjayB0bwotICAgKiB0aGUgY3VycmVudCB2YWx1ZSBvZiBtX3Nob3VsZFN0cmlwV1MuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzaG91bGRTdHJpcCBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBzdHJpcCB3aGl0ZXNwYWNlIG5vZGVzCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBzZXRTaG91bGRTdHJpcFdoaXRlc3BhY2UoYm9vbGVhbiBzaG91bGRTdHJpcCkKLSAgewotCi0gICAgbV9zaG91bGRTdHJpcFdTID0gc2hvdWxkU3RyaXA7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Nob3VsZFN0cmlwV2hpdGVzcGFjZVN0YWNrKQotICAgICAgbV9zaG91bGRTdHJpcFdoaXRlc3BhY2VTdGFjay5zZXRUb3Aoc2hvdWxkU3RyaXApOwotICB9Ci0KLSAgLyoqCi0gICAqIEEgZHVtbXkgcm91dGluZSB0byBzYXRpc2lmeSB0aGUgYWJzdHJhY3QgaW50ZXJmYWNlLiBJZiB0aGUgRFRNCi0gICAqIGltcGxlbWVtdGF0aW9uIHRoYXQgZXh0ZW5kcyB0aGUgZGVmYXVsdCBiYXNlIHJlcXVpcmVzIG5vdGlmaWNhdGlvbgotICAgKiBvZiByZWdpc3RyYXRpb24sIHRoZXkgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgotICAgKi8KLSAgIHB1YmxpYyB2b2lkIGRvY3VtZW50UmVnaXN0cmF0aW9uKCkKLSAgIHsKLSAgIH0KLQotICAvKioKLSAgICogQSBkdW1teSByb3V0aW5lIHRvIHNhdGlzaWZ5IHRoZSBhYnN0cmFjdCBpbnRlcmZhY2UuIElmIHRoZSBEVE0KLSAgICogaW1wbGVtZW10YXRpb24gdGhhdCBleHRlbmRzIHRoZSBkZWZhdWx0IGJhc2UgcmVxdWlyZXMgbm90aWZpY2F0aW9uCi0gICAqIHdoZW4gdGhlIGRvY3VtZW50IGlzIGJlaW5nIHJlbGVhc2VkLCB0aGV5IGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZAotICAgKi8KLSAgIHB1YmxpYyB2b2lkIGRvY3VtZW50UmVsZWFzZSgpCi0gICB7Ci0gICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlSXRlcmF0b3JzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwYmM2NTgwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlSXRlcmF0b3JzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTE5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgdHJhdmVyc2VycyBmb3IgRFRNRGVmYXVsdEJhc2UuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycyBleHRlbmRzIERUTURlZmF1bHRCYXNlVHJhdmVyc2VycwotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBEVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMgb2JqZWN0IGZyb20gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG1nciBUaGUgRFRNTWFuYWdlciB3aG8gb3ducyB0aGlzIERUTS4KLSAgICogQHBhcmFtIGRvbVNvdXJjZSB0aGUgRE9NIHNvdXJjZSB0aGF0IHRoaXMgRFRNIHdpbGwgd3JhcC4KLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBjb25zdHJ1Y3Rpb24gc291cmNlLgotICAgKiBAcGFyYW0gZHRtSWRlbnRpdHkgVGhlIERUTSBpZGVudGl0eSBJRCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIFRoZSB3aGl0ZSBzcGFjZSBmaWx0ZXIgZm9yIHRoaXMgRFRNLCB3aGljaCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIHhzdHJpbmdmYWN0b3J5IFRoZSBmYWN0b3J5IHRvIHVzZSBmb3IgY3JlYXRpbmcgWE1MU3RyaW5ncy4KLSAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UgCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqLwotICBwdWJsaWMgRFRNRGVmYXVsdEJhc2VJdGVyYXRvcnMoRFRNTWFuYWdlciBtZ3IsIFNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nRmFjdG9yeSB4c3RyaW5nZmFjdG9yeSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotICAgIHN1cGVyKG1nciwgc291cmNlLCBkdG1JZGVudGl0eSwgd2hpdGVTcGFjZUZpbHRlciwgCi0gICAgICAgICAgeHN0cmluZ2ZhY3RvcnksIGRvSW5kZXhpbmcpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpdGVyYXRvciB0aGF0IGNhbiBuYXZpZ2F0ZSBvdmVyIGFuIFhQYXRoIEF4aXMsIHByZWRpY2F0ZWQgYnkKLSAgICogdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqIFJldHVybnMgYW4gaXRlcmF0b3IgdGhhdCBtdXN0IGJlIGluaXRpYWxpemVkCi0gICAqIHdpdGggYSBzdGFydCBub2RlICh1c2luZyBpdGVyYXRvci5zZXRTdGFydE5vZGUoKSkuCi0gICAqCi0gICAqIEBwYXJhbSBheGlzIE9uZSBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqIEBwYXJhbSB0eXBlIEFuIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIG9yIG51bGwgaWYgdGhlIGdpdmVuIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZEF4aXNJdGVyYXRvcihpbnQgYXhpcywgaW50IHR5cGUpCi0gIHsKLQotICAgIERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciA9IG51bGw7Ci0KLSAgICAvKiBUaGlzIGNhdXNlcyBhbiBlcnJvciB3aGVuIHVzaW5nIHBhdHRlcm5zIGZvciBlbGVtZW50cyB0aGF0Ci0gICAgICAgZG8gbm90IGV4aXN0IGluIHRoZSBET00gKHRyYW5zbGV0IHR5cGVzIHdoaWNoIGRvIG5vdCBjb3JyZXNwb25kCi0gICAgICAgdG8gYSBET00gdHlwZSBhcmUgbWFwcGVkIHRvIHRoZSBET00uRUxFTUVOVCB0eXBlKS4KLSAgICAqLwotCi0gICAgLy8gICAgICAgIGlmICh0eXBlID09IE5PX1RZUEUpIHsKLSAgICAvLyAgICAgICAgICAgIHJldHVybihFTVBUWUlURVJBVE9SKTsKLSAgICAvLyAgICAgICAgfQotICAgIC8vICAgICAgICBlbHNlIGlmICh0eXBlID09IEVMRU1FTlQpIHsKLSAgICAvLyAgICAgICAgICAgIGl0ZXJhdG9yID0gbmV3IEZpbHRlckl0ZXJhdG9yKGdldEF4aXNJdGVyYXRvcihheGlzKSwKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEVsZW1lbnRGaWx0ZXIoKSk7Ci0gICAgLy8gICAgICAgIH0KLSAgICAvLyAgICAgICAgZWxzZSAKLSAgICB7Ci0gICAgICBzd2l0Y2ggKGF4aXMpCi0gICAgICB7Ci0gICAgICBjYXNlIEF4aXMuU0VMRiA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkU2luZ2xldG9uSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkNISUxEIDoKLSAgICAgICAgaXRlcmF0b3IgPSBuZXcgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yKHR5cGUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgQXhpcy5QQVJFTlQgOgotICAgICAgICByZXR1cm4gKG5ldyBQYXJlbnRJdGVyYXRvcigpLnNldE5vZGVUeXBlKHR5cGUpKTsKLSAgICAgIGNhc2UgQXhpcy5BTkNFU1RPUiA6Ci0gICAgICAgIHJldHVybiAobmV3IFR5cGVkQW5jZXN0b3JJdGVyYXRvcih0eXBlKSk7Ci0gICAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEYgOgotICAgICAgICByZXR1cm4gKChuZXcgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yKHR5cGUpKS5pbmNsdWRlU2VsZigpKTsKLSAgICAgIGNhc2UgQXhpcy5BVFRSSUJVVEUgOgotICAgICAgICByZXR1cm4gKG5ldyBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yKHR5cGUpKTsKLSAgICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UIDoKLSAgICAgICAgaXRlcmF0b3IgPSBuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEYgOgotICAgICAgICBpdGVyYXRvciA9IChuZXcgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IodHlwZSkpLmluY2x1ZGVTZWxmKCk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkZPTExPV0lORyA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkRm9sbG93aW5nSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLlBSRUNFRElORyA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkcgOgotICAgICAgICBpdGVyYXRvciA9IG5ldyBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcih0eXBlKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORyA6Ci0gICAgICAgIGl0ZXJhdG9yID0gbmV3IFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yKHR5cGUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgQXhpcy5OQU1FU1BBQ0UgOgotICAgICAgICBpdGVyYXRvciA9IG5ldyBUeXBlZE5hbWVzcGFjZUl0ZXJhdG9yKHR5cGUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgQXhpcy5ST09UIDoKLSAgICAgICAgaXRlcmF0b3IgPSBuZXcgVHlwZWRSb290SXRlcmF0b3IodHlwZSk7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfVFlQRURfSVRFUkFUT1JfQVhJU19OT1RfSU1QTEVNRU5URUQsIG5ldyBPYmplY3RbXXtBeGlzLm5hbWVzW2F4aXNdfSkpOyAvLyJFcnJvcjogdHlwZWQgaXRlcmF0b3IgZm9yIGF4aXMgIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBBeGlzLm5hbWVzW2F4aXNdICsgIm5vdCBpbXBsZW1lbnRlZCIpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAoaXRlcmF0b3IpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgYSBzaG9ydGN1dCB0byB0aGUgaXRlcmF0b3JzIHRoYXQgaW1wbGVtZW50IHRoZQotICAgKiBYUGF0aCBheGVzLgotICAgKiBSZXR1cm5zIGEgYmFyZS1ib25lcyBpdGVyYXRvciB0aGF0IG11c3QgYmUgaW5pdGlhbGl6ZWQKLSAgICogd2l0aCBhIHN0YXJ0IG5vZGUgKHVzaW5nIGl0ZXJhdG9yLnNldFN0YXJ0Tm9kZSgpKS4KLSAgICoKLSAgICogQHBhcmFtIGF4aXMgT25lIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4gYXhpcyBpc24ndCBzdXBwb3J0ZWQuCi0gICAqLwotICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGdldEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcykKLSAgewotCi0gICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXJhdG9yID0gbnVsbDsKLQotICAgIHN3aXRjaCAoYXhpcykKLSAgICB7Ci0gICAgY2FzZSBBeGlzLlNFTEYgOgotICAgICAgaXRlcmF0b3IgPSBuZXcgU2luZ2xldG9uSXRlcmF0b3IoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5DSElMRCA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBDaGlsZHJlbkl0ZXJhdG9yKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuUEFSRU5UIDoKLSAgICAgIHJldHVybiAobmV3IFBhcmVudEl0ZXJhdG9yKCkpOwotICAgIGNhc2UgQXhpcy5BTkNFU1RPUiA6Ci0gICAgICByZXR1cm4gKG5ldyBBbmNlc3Rvckl0ZXJhdG9yKCkpOwotICAgIGNhc2UgQXhpcy5BTkNFU1RPUk9SU0VMRiA6Ci0gICAgICByZXR1cm4gKChuZXcgQW5jZXN0b3JJdGVyYXRvcigpKS5pbmNsdWRlU2VsZigpKTsKLSAgICBjYXNlIEF4aXMuQVRUUklCVVRFIDoKLSAgICAgIHJldHVybiAobmV3IEF0dHJpYnV0ZUl0ZXJhdG9yKCkpOwotICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UIDoKLSAgICAgIGl0ZXJhdG9yID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRPUlNFTEYgOgotICAgICAgaXRlcmF0b3IgPSAobmV3IERlc2NlbmRhbnRJdGVyYXRvcigpKS5pbmNsdWRlU2VsZigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkZPTExPV0lORyA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBGb2xsb3dpbmdJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlBSRUNFRElORyA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBQcmVjZWRpbmdJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkZPTExPV0lOR1NJQkxJTkcgOgotICAgICAgaXRlcmF0b3IgPSBuZXcgRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuUFJFQ0VESU5HU0lCTElORyA6Ci0gICAgICBpdGVyYXRvciA9IG5ldyBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5OQU1FU1BBQ0UgOgotICAgICAgaXRlcmF0b3IgPSBuZXcgTmFtZXNwYWNlSXRlcmF0b3IoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5ST09UIDoKLSAgICAgIGl0ZXJhdG9yID0gbmV3IFJvb3RJdGVyYXRvcigpOwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0lURVJBVE9SX0FYSVNfTk9UX0lNUExFTUVOVEVELCBuZXcgT2JqZWN0W117QXhpcy5uYW1lc1theGlzXX0pKTsgLy8iRXJyb3I6IGl0ZXJhdG9yIGZvciBheGlzICciICsgQXhpcy5uYW1lc1theGlzXQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLysgIicgbm90IGltcGxlbWVudGVkIik7Ci0gICAgfQotCi0gICAgcmV0dXJuIChpdGVyYXRvcik7Ci0gIH0KLQotICAvKioKLSAgICogQWJzdHJhY3Qgc3VwZXJjbGFzcyBkZWZpbmluZyBiZWhhdmlvcnMgc2hhcmVkIGJ5IGFsbCBEVE1EZWZhdWx0J3MKLSAgICogaW50ZXJuYWwgaW1wbGVtZW50YXRpb25zIG9mIERUTUF4aXNJdGVyYXRvci4gU3ViY2xhc3MgdGhpcyAoYW5kCi0gICAqIG92ZXJyaWRlLCBpZiBuZWNlc3NhcnkpIHRvIGltcGxlbWVudCB0aGUgc3BlY2lmaWNzIG9mIGFuCi0gICAqIGluZGl2aWR1YWwgYXhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQ3VycmVudGx5IHRoZXJlIGlzbid0IGEgbG90IGhlcmUKLSAgICovCi0gIHByaXZhdGUgYWJzdHJhY3QgY2xhc3MgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlIGV4dGVuZHMgRFRNQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvLyAlUkVWSUVXJSBXZSBjb3VsZCBvcHQgdG8gc2hhcmUgX25vZGVUeXBlIGFuZCBzZXROb2RlVHlwZSgpIGFzCi0gICAgLy8gd2VsbCwgYW5kIHNpbXBseSBpZ25vcmUgdGhlbSBpbiBpdGVyYXRvcnMgd2hpY2ggZG9uJ3QgdXNlIHRoZW0uCi0gICAgLy8gQnV0IFNjb3R0J3Mgd29ycmllZCBhYm91dCB0aGUgb3ZlcmhlYWQgaW52b2x2ZWQgaW4gY2xvbmluZwotICAgIC8vIHRoZXNlLCBhbmQgd2FudHMgdGhlbSB0byBoYXZlIGFzIGZldyBmaWVsZHMgYXMgcG9zc2libGUuIE5vdGUKLSAgICAvLyB0aGF0IHdlIGNhbid0IGNyZWF0ZSBhIFR5cGVkSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlIGJlY2F1c2UKLSAgICAvLyB0aG9zZSBhcmUgb2Z0ZW4gYmFzZWQgb24gdGhlIHVudHlwZWQgdmVyc2lvbnMgYW5kIEphdmEgZG9lc24ndAotICAgIC8vIHN1cHBvcnQgbXVsdGlwbGUgaW5oZXJpdGFuY2UuIDxzaWdoLz4KLQotICAgIC8qKgotICAgICAqIEN1cnJlbnQgaXRlcmF0aW9uIGxvY2F0aW9uLiBVc3VhbGx5IHRoaXMgaXMgdGhlIGxhc3QgbG9jYXRpb24KLSAgICAgKiByZXR1cm5lZCAoc3RhcnRpbmcgcG9pbnQgZm9yIHRoZSBuZXh0KCkgc2VhcmNoKTsgZm9yIHNpbmdsZS1ub2RlCi0gICAgICogaXRlcmF0b3JzIGl0IG1heSBpbnN0ZWFkIGJlIGluaXRpYWxpemVkIHRvIHBvaW50IHRvIHRoYXQgc2luZ2xlIG5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBfY3VycmVudE5vZGU7Ci0KLSAgICAvKioKLSAgICAgKiBSZW1lbWJlcnMgdGhlIGN1cnJlbnQgbm9kZSBmb3IgdGhlIG5leHQgY2FsbCB0byBnb3RvTWFyaygpLgotICAgICAqCi0gICAgICogJVJFVklFVyUgU2hvdWxkIHRoaXMgc2F2ZSBfcG9zaXRpb24gdG9vPwotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldE1hcmsoKQotICAgIHsKLSAgICAgIF9tYXJrZWROb2RlID0gX2N1cnJlbnROb2RlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJlc3RvcmVzIHRoZSBjdXJyZW50IG5vZGUgcmVtZW1iZXJlZCBieSBzZXRNYXJrKCkuCi0gICAgICoKLSAgICAgKiAlUkVWRUlXJSBTaG91bGQgdGhpcyByZXN0b3JlIF9wb3NpdGlvbiB0b28/Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgZ290b01hcmsoKQotICAgIHsKLSAgICAgIF9jdXJyZW50Tm9kZSA9IF9tYXJrZWROb2RlOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZSAKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGFsbCBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgYSBnaXZlbiBub2RlCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGNsYXNzIENoaWxkcmVuSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqCi0gICAgICogU2V0dGluZyBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIElmIHRoZSBpdGVyYXRvciBpcyBub3QgcmVzdGFydGFibGUsIHRoaXMgaGFzIG5vIGVmZmVjdC4KLSAgICAgKiAlUkVWSUVXJSBTaG91bGQgaXQgcmV0dXJuL3Rocm93IHNvbWV0aGluZyBpbiB0aGF0IGNhc2UsCi0gICAgICogb3Igc2V0IGN1cnJlbnQgbm9kZSB0byBFTkQsIHRvIGluZGljYXRlIHJlcXVlc3Qtbm90LWhvbm9yZWQ/Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShmaW5hbCBpbnQgbm9kZSkKLSAgICB7Ci0KLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IE5PVFBST0NFU1NFRDsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQgaWYgbm8gbW9yZQotICAgICAqIGFyZSBhdmFpbGFibGUuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IChOT1RQUk9DRVNTRUQgPT0gX2N1cnJlbnROb2RlKQotICAgICAgICAgICAgICAgICAgICAgPyBnZXRGaXJzdENoaWxkKF9zdGFydE5vZGUpCi0gICAgICAgICAgICAgICAgICAgICA6IGdldE5leHRTaWJsaW5nKF9jdXJyZW50Tm9kZSk7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKF9jdXJyZW50Tm9kZSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgQ2hpbGRyZW5JdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIHBhcmVudCBvZiBhIGdpdmVuIG5vZGUuIE5vdGUgdGhhdAotICAgKiB0aGlzIGRlbGl2ZXJzIG9ubHkgYSBzaW5nbGUgbm9kZTsgaWYgeW91IHdhbnQgYWxsIHRoZSBhbmNlc3RvcnMsCi0gICAqIHNlZSBBbmNlc3Rvckl0ZXJhdG9yLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBQYXJlbnRJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgaW50IF9ub2RlVHlwZSA9IC0xOwotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXRQYXJlbnQobm9kZSk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHRoZSBub2RlIHR5cGUgb2YgdGhlIHBhcmVudCB0aGF0IHdlJ3JlIGxvb2tpbmcgZm9yLgotICAgICAqIE5vdGUgdGhhdCB0aGlzIGRvZXMgX25vdF8gbWVhbiAiZmluZCB0aGUgbmVhcmVzdCBhbmNlc3RvciBvZgotICAgICAqIHRoaXMgdHlwZSIsIGJ1dCAieWllbGQgdGhlIHBhcmVudCBpZiBpdCBpcyBvZiB0aGlzIHR5cGUiLgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHJldHVybiBQYXJlbnRJdGVyYXRvciBjb25maWd1cmVkIHdpdGggdGhlIHR5cGUgZmlsdGVyIHNldC4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldE5vZGVUeXBlKGZpbmFsIGludCB0eXBlKQotICAgIHsKLQotICAgICAgX25vZGVUeXBlID0gdHlwZTsKLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4gSW4gdGhpcyBjYXNlLCB3ZSByZXR1cm4KLSAgICAgKiBvbmx5IHRoZSBpbW1lZGlhdGUgcGFyZW50LCBfaWZfIGl0IG1hdGNoZXMgdGhlIHJlcXVlc3RlZCBub2RlVHlwZS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgcmVzdWx0ID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBpZiAoKF9ub2RlVHlwZSAhPSAtMSkgJiYgKGdldEV4cGFuZGVkVHlwZUlEKF9jdXJyZW50Tm9kZSkgIT0gX25vZGVUeXBlKSkKLSAgICAgICAgcmVzdWx0ID0gRU5EOwotICAgICAgZWxzZQotICAgICAgICByZXN1bHQgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IEVORDsKLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUocmVzdWx0KTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBQYXJlbnRJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgY2hpbGRyZW4gb2YgYSBnaXZlbiB0eXBlIGZvciBhIGdpdmVuIG5vZGUuCi0gICAqIFRoZSBmdW5jdGlvbmFsaXR5IGNob3VsZCBiZSBhY2hpZXZlZCBieSBwdXR0aW5nIGEgZmlsdGVyIG9uIHRvcAotICAgKiBvZiBhIGJhc2ljIGNoaWxkIGl0ZXJhdG9yLCBidXQgYSBzcGVjaWFsaXNlZCBpdGVyYXRvciBpcyB1c2VkCi0gICAqIGZvciBlZmZpY2llbmN5IChib3RoIHNwZWVkIGFuZCBzaXplIG9mIHRyYW5zbGV0KS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgY2xhc3MgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkQ2hpbGRyZW5JdGVyYXRvcihpbnQgbm9kZVR5cGUpCi0gICAgewotICAgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBOT1RQUk9DRVNTRUQ7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmb3IgKGludCBub2RlID0gKE5PVFBST0NFU1NFRCA9PSBfY3VycmVudE5vZGUpCi0gICAgICAgICAgICAgICAgICAgICAgPyBnZXRGaXJzdENoaWxkKF9zdGFydE5vZGUpCi0gICAgICAgICAgICAgICAgICAgICAgOiBnZXROZXh0U2libGluZyhfY3VycmVudE5vZGUpOyBub2RlCi0gICAgICAgICAgICAgICAgICAgICAgICAhPSBFTkQ7IG5vZGUgPSBnZXROZXh0U2libGluZyhub2RlKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpID09IF9ub2RlVHlwZSkKLSAgICAgICAgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICByZXR1cm4gRU5EOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkQ2hpbGRyZW5JdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgY2hpbGRyZW4gd2l0aGluIGEgZ2l2ZW4gbmFtZXNwYWNlIGZvciBhCi0gICAqIGdpdmVuIG5vZGUuIFRoZSBmdW5jdGlvbmFsaXR5IGNob3VsZCBiZSBhY2hpZXZlZCBieSBwdXR0aW5nIGEKLSAgICogZmlsdGVyIG9uIHRvcCBvZiBhIGJhc2ljIGNoaWxkIGl0ZXJhdG9yLCBidXQgYSBzcGVjaWFsaXNlZAotICAgKiBpdGVyYXRvciBpcyB1c2VkIGZvciBlZmZpY2llbmN5IChib3RoIHNwZWVkIGFuZCBzaXplIG9mIHRyYW5zbGV0KS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgY2xhc3MgTmFtZXNwYWNlQ2hpbGRyZW5JdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25zVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIE5hbWVzcGFjZUNoaWxkcmVuSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VDaGlsZHJlbkl0ZXJhdG9yKGZpbmFsIGludCB0eXBlKQotICAgIHsKLSAgICAgIF9uc1R5cGUgPSB0eXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLQotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gTk9UUFJPQ0VTU0VEOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgZm9yIChpbnQgbm9kZSA9IChOT1RQUk9DRVNTRUQgPT0gX2N1cnJlbnROb2RlKQotICAgICAgICAgICAgICAgICAgICAgID8gZ2V0Rmlyc3RDaGlsZChfc3RhcnROb2RlKQotICAgICAgICAgICAgICAgICAgICAgIDogZ2V0TmV4dFNpYmxpbmcoX2N1cnJlbnROb2RlKTsgbm9kZQotICAgICAgICAgICAgICAgICAgICAgICAgIT0gRU5EOyBub2RlID0gZ2V0TmV4dFNpYmxpbmcobm9kZSkpCi0gICAgICB7Ci0gICAgICAgIGlmIChnZXROYW1lc3BhY2VUeXBlKG5vZGUpID09IF9uc1R5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBfY3VycmVudE5vZGUgPSBub2RlOwotCi0gICAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIEVORDsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZENoaWxkcmVuSXRlcmF0b3IKLSAgCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIG5hbWVzcGFjZSBub2RlcyBhcyBkZWZpbmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsIAotICAgKiBmb3IgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBOYW1lc3BhY2VJdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZUl0ZXJhdG9yKCkKLSAgICB7Ci0KLSAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXRGaXJzdE5hbWVzcGFjZU5vZGUobm9kZSwgdHJ1ZSk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgaWYgKERUTS5OVUxMICE9IG5vZGUpCi0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldE5leHROYW1lc3BhY2VOb2RlKF9zdGFydE5vZGUsIG5vZGUsIHRydWUpOwotCi0gICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBOYW1lc3BhY2VJdGVyYXRvcgotICAKLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgbmFtZXNwYWNlIG5vZGVzIGFzIGRlZmluZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwgCi0gICAqIGZvciBhIGdpdmVuIG5vZGUsIGZpbHRlcmVkIGJ5IGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIFR5cGVkTmFtZXNwYWNlSXRlcmF0b3IgZXh0ZW5kcyBOYW1lc3BhY2VJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkQ2hpbGRyZW5JdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZE5hbWVzcGFjZUl0ZXJhdG9yKGludCBub2RlVHlwZSkKLSAgICB7Ci0gICAgICBzdXBlcigpOwotICAgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmb3IgKGludCBub2RlID0gc3VwZXIubmV4dCgpOyBub2RlICE9IEVORDsgbm9kZSA9IHN1cGVyLm5leHQoKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpID09IF9ub2RlVHlwZSkKLSAgICAgICAgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICByZXR1cm4gRU5EOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkTmFtZXNwYWNlSXRlcmF0b3IKLSAgCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIHRoZSByb290IG5vZGUgYXMgZGVmaW5lZCBieSB0aGUgWFBhdGggZGF0YSBtb2RlbCAKLSAgICogZm9yIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgUm9vdEl0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgUm9vdEl0ZXJhdG9yCi0gICAgICovCi0gICAgcHVibGljIFJvb3RJdGVyYXRvcigpCi0gICAgewotCi0gICAgICBzdXBlcigpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLQotICAgICAgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBfc3RhcnROb2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gTlVMTDsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0gICAgICBpZihfc3RhcnROb2RlID09IF9jdXJyZW50Tm9kZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IF9zdGFydE5vZGU7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKF9zdGFydE5vZGUpOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFJvb3RJdGVyYXRvcgotICAKLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgbmFtZXNwYWNlIG5vZGVzIGFzIGRlZmluZWQgYnkgdGhlIFhQYXRoIGRhdGEgbW9kZWwgCi0gICAqIGZvciBhIGdpdmVuIG5vZGUsIGZpbHRlcmVkIGJ5IGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIFR5cGVkUm9vdEl0ZXJhdG9yIGV4dGVuZHMgUm9vdEl0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRSb290SXRlcmF0b3IKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkUm9vdEl0ZXJhdG9yKGludCBub2RlVHlwZSkKLSAgICB7Ci0gICAgICBzdXBlcigpOwotICAgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmb3IgKGludCBub2RlID0gc3VwZXIubmV4dCgpOyBub2RlICE9IEVORDsgbm9kZSA9IHN1cGVyLm5leHQoKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpID09IF9ub2RlVHlwZSkKLSAgICAgICAgewotICAgICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICByZXR1cm4gRU5EOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkUm9vdEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGVzIHdpdGhpbiBhIGdpdmVuIG5hbWVzcGFjZSBmb3IgYSBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBOYW1lc3BhY2VBdHRyaWJ1dGVJdGVyYXRvcgotICAgICAgICAgIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25zVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIE5hbWVzcGFjZUF0dHJpYnV0ZUl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBuc1R5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBOYW1lc3BhY2VBdHRyaWJ1dGVJdGVyYXRvcihpbnQgbnNUeXBlKQotICAgIHsKLQotICAgICAgc3VwZXIoKTsKLQotICAgICAgX25zVHlwZSA9IG5zVHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0KLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldEZpcnN0TmFtZXNwYWNlTm9kZShub2RlLCBmYWxzZSk7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZSA9IF9jdXJyZW50Tm9kZTsKLQotICAgICAgaWYgKERUTS5OVUxMICE9IG5vZGUpCi0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldE5leHROYW1lc3BhY2VOb2RlKF9zdGFydE5vZGUsIG5vZGUsIGZhbHNlKTsKLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRDaGlsZHJlbkl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhbGwgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKF9jdXJyZW50Tm9kZSA9IGdldE5leHRTaWJsaW5nKF9jdXJyZW50Tm9kZSkpOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgYWxsIGZvbGxvd2luZyBzaWJsaW5ncyBvZiBhIGdpdmVuIG5vZGUuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBGb2xsb3dpbmdTaWJsaW5nSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZEZvbGxvd2luZ1NpYmxpbmdJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBOVUxMCi0gICAgICAgICAgICAgJiYgZ2V0RXhwYW5kZWRUeXBlSUQobm9kZSkgIT0gX25vZGVUeXBlKXt9Ci0KLSAgICAgIHJldHVybiBub2RlOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkRm9sbG93aW5nU2libGluZ0l0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGUgbm9kZXMgKG9mIHdoYXQgbm9kZXM/KQotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBBdHRyaWJ1dGVJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvLyBhc3N1bWVzIGNhbGxlciB3aWxsIHBhc3MgZWxlbWVudCBub2RlcwotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBnZXRGaXJzdEF0dHJpYnV0ZShub2RlKTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0KLSAgICAgIGZpbmFsIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBfY3VycmVudE5vZGUgPSBnZXROZXh0QXR0cmlidXRlKG5vZGUpOwotCi0gICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBBdHRyaWJ1dGVJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgYXR0cmlidXRlIG5vZGVzIG9mIGEgZ2l2ZW4gdHlwZQotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yIGV4dGVuZHMgSW50ZXJuYWxBeGlzSXRlcmF0b3JCYXNlCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRBdHRyaWJ1dGVJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZVR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBpcyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkQXR0cmlidXRlSXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8vIGFzc3VtZXMgY2FsbGVyIHdpbGwgcGFzcyBlbGVtZW50IG5vZGVzCi0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0KLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgZm9yIChub2RlID0gZ2V0Rmlyc3RBdHRyaWJ1dGUobm9kZSk7IG5vZGUgIT0gRU5EOwotICAgICAgICAgICAgICAgIG5vZGUgPSBnZXROZXh0QXR0cmlidXRlKG5vZGUpKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpID09IF9ub2RlVHlwZSkKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0KLSAgICAgIGZpbmFsIGludCBub2RlID0gX2N1cnJlbnROb2RlOwotCi0gICAgICAvLyBzaW5nbGV0b24gaXRlcmF0b3IsIHNpbmNlIHRoZXJlIGNhbiBvbmx5IGJlIG9uZSBhdHRyaWJ1dGUgb2YgCi0gICAgICAvLyBhIGdpdmVuIHR5cGUuCi0gICAgICBfY3VycmVudE5vZGUgPSBOVUxMOwotCi0gICAgICByZXR1cm4gcmV0dXJuTm9kZShub2RlKTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZEF0dHJpYnV0ZUl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBwcmVjZWRpbmcgc2libGluZ3Mgb2YgYSBnaXZlbiBub2RlCi0gICAqLwotICBwcml2YXRlIGNsYXNzIFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgaWYobm9kZSA9PSBOVUxMKQotICAgICAgICB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgICB9Ci0gICAgICAgICAgCi0gICAgICAgIGludCB0eXBlID0gZ2V0RXhwYW5kZWRUeXBlSUQobm9kZSkgJiBFeHBhbmRlZE5hbWVUYWJsZS5NQVNLX05PREVUWVBFOwotICAgICAgICBpZihFeHBhbmRlZE5hbWVUYWJsZS5BVFRSSUJVVEUgPT0gdHlwZSAKLSAgICAgICAgICAgfHwgRXhwYW5kZWROYW1lVGFibGUuTkFNRVNQQUNFID09IHR5cGUgKQotICAgICAgICB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gbm9kZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgX2N1cnJlbnROb2RlID0gZ2V0Rmlyc3RDaGlsZChnZXRQYXJlbnQobm9kZSkpOwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaWYgKF9jdXJyZW50Tm9kZSA9PSBfc3RhcnROb2RlKQotICAgICAgewotICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZmluYWwgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IGdldE5leHRTaWJsaW5nKG5vZGUpOwotCi0gICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgfQotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgcHJlY2VkaW5nIHNpYmxpbmdzIG9mIGEgZ2l2ZW4gdHlwZSBmb3IKLSAgICogYSBnaXZlbiBub2RlCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yCi0gICAgICAgICAgZXh0ZW5kcyBQcmVjZWRpbmdTaWJsaW5nSXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgd2FzIHJlcXVlc3RlZC4gKi8KLSAgICBwcml2YXRlIGZpbmFsIGludCBfbm9kZVR5cGU7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RvciBUeXBlZFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkUHJlY2VkaW5nU2libGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBOVUxMCi0gICAgICAgICAgICAgJiYgZ2V0RXhwYW5kZWRUeXBlSUQobm9kZSkgIT0gX25vZGVUeXBlKXt9Ci0KLSAgICAgIHJldHVybiBub2RlOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFByZWNlZGluZ1NpYmxpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgcHJlY2VkaW5nIG5vZGVzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICogVGhpcyBpbmNsdWRlcyB0aGUgbm9kZSBzZXQge3Jvb3QrMSwgc3RhcnQtMX0sIGJ1dCBleGNsdWRlcwotICAgKiBhbGwgYW5jZXN0b3JzLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBQcmVjZWRpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKiogVGhlIG1heCBhbmNlc3RvcnMsIGJ1dCBpdCBjYW4gZ3Jvdy4uLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9tYXhBbmNlc3RvcnMgPSA4OwotCi0gICAgLyoqCi0gICAgICogVGhlIHN0YWNrIG9mIHN0YXJ0IG5vZGUgKyBhbmNlc3RvcnMgdXAgdG8gUk9PVE5PREUsCi0gICAgICogIHdoaWNoIHdlIG11c3QgYXZvaWQuCi0gICAgICovCi0gICAgcHJpdmF0ZSBpbnRbXSBfc3RhY2sgPSBuZXcgaW50W19tYXhBbmNlc3RvcnNdOwotCi0gICAgLyoqIChub3Qgc3VyZSB5ZXQuLi4gLXNiKSAqLwotICAgIHByaXZhdGUgaW50IF9zcCwgX29sZHNwOwotCi0gICAgLyogX2N1cnJlbnROb2RlIHByZWNlZGVzIGNhbmRpZGF0ZXMuICBUaGlzIGlzIHRoZSBpZGVudGl0eSwgbm90IHRoZSBoYW5kbGUhICovCi0KLSAgICAvKioKLSAgICAgKiBUcnVlIGlmIHRoaXMgaXRlcmF0b3IgaGFzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBzaW5jZSB0aGlzIGl0ZXJhdG9yIGlzIGEgcmV2ZXJzZWQgYXhpcy4KLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2UoKQotICAgIHsKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gICBUaGUgY2xvbmVkIGl0ZXJhdG9yIGlzIG5vdCByZXNldC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIGNsb25lSXRlcmF0b3IoKQotICAgIHsKLSAgICAgIF9pc1Jlc3RhcnRhYmxlID0gZmFsc2U7Ci0KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBmaW5hbCBQcmVjZWRpbmdJdGVyYXRvciBjbG9uZSA9IChQcmVjZWRpbmdJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLSAgICAgICAgZmluYWwgaW50W10gc3RhY2tDb3B5ID0gbmV3IGludFtfc3RhY2subGVuZ3RoXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShfc3RhY2ssIDAsIHN0YWNrQ29weSwgMCwgX3N0YWNrLmxlbmd0aCk7Ci0KLSAgICAgICAgY2xvbmUuX3N0YWNrID0gc3RhY2tDb3B5OwotCi0gICAgICAgIC8vIHJldHVybiBjbG9uZS5yZXNldCgpOwotICAgICAgICByZXR1cm4gY2xvbmU7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JVEVSQVRPUl9DTE9ORV9OT1RfU1VQUE9SVEVELCBudWxsKSk7IC8vIkl0ZXJhdG9yIGNsb25lIG5vdCBzdXBwb3J0ZWQuIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIG5vZGUgPSBub2RlICYgbV9tYXNrOwotCi0gICAgICAgIC8vIGl0ZXJhdG9yIGlzIG5vdCBhIGNsb25lCi0gICAgICAgIGludCBwYXJlbnQsIGluZGV4OwotCi0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotICAgICAgICBfY3VycmVudE5vZGUgPSBST09UTk9ERTsgIC8vIFJlbWVtYmVyIGl0J3MgdGhlIGlkZW50aXR5LCBub3QgdGhlIGZ1bGwgaGFuZGxlLgotICAgICAgICBfc3RhY2tbaW5kZXggPSAwXSA9IG5vZGU7Ci0KLSAgICAgICAgaWYgKG5vZGUgPiBST09UTk9ERSkKLSAgICAgICAgewotICAgICAgICAgIHdoaWxlICgocGFyZW50ID0gX3BhcmVudChub2RlKSkgIT0gUk9PVE5PREUpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKCsraW5kZXggPT0gX3N0YWNrLmxlbmd0aCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgZmluYWwgaW50W10gc3RhY2sgPSBuZXcgaW50W2luZGV4ICsgNF07Ci0KLSAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShfc3RhY2ssIDAsIHN0YWNrLCAwLCBpbmRleCk7Ci0KLSAgICAgICAgICAgICAgX3N0YWNrID0gc3RhY2s7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIF9zdGFja1tpbmRleF0gPSBub2RlID0gcGFyZW50OwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIF9vbGRzcCA9IF9zcCA9IGluZGV4OwotCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgZmluYWwgaW50IG5vZGUgPSBfY3VycmVudE5vZGUgKyAxOwotCi0gICAgICBpZiAoKF9zcCA+PSAwKSAmJiAobm9kZSA8IF9zdGFja1tfc3BdKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIHJldHVybk5vZGUoKF9jdXJyZW50Tm9kZSA9IG5vZGUpIHwgbV9kdG1JZGVudCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7ICAvLyBza2lwIGFuY2VzdG9yCi0KLSAgICAgICAgcmV0dXJuIC0tX3NwID49IDAgPyBuZXh0KCkgOiBOVUxMOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIHJlZGVmaW5lIERUTUF4aXNJdGVyYXRvckJhc2UncyByZXNldAotCi0gICAgLyoqCi0gICAgICogUmVzZXRzIHRoZSBpdGVyYXRvciB0byB0aGUgbGFzdCBzdGFydCBub2RlLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhpcwotICAgICAqICAgICAgICAgaXRlcmF0b3IuCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciByZXNldCgpCi0gICAgewotCi0gICAgICBfc3AgPSBfb2xkc3A7Ci0KLSAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgUHJlY2VkaW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHByZWNlZGluZyBub2RlcyBvZiBhZ2l2ZW4gdHlwZSBmb3IgYQotICAgKiBnaXZlbiBub2RlLiBUaGlzIGluY2x1ZGVzIHRoZSBub2RlIHNldCB7cm9vdCsxLCBzdGFydC0xfSwgYnV0Ci0gICAqIGV4Y2x1ZGVzIGFsbCBhbmNlc3RvcnMuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IgZXh0ZW5kcyBQcmVjZWRpbmdJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIHR5cGUgVGhlIGV4dGVuZGVkIHR5cGUgSUQgYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBUeXBlZFByZWNlZGluZ0l0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBOVUxMCi0gICAgICAgICAgICAgJiYgZ2V0RXhwYW5kZWRUeXBlSUQobm9kZSkgIT0gX25vZGVUeXBlKXt9Ci0KLSAgICAgIHJldHVybiBub2RlOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkUHJlY2VkaW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGZvbGxvd2luZyBub2RlcyBvZiBmb3IgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBGb2xsb3dpbmdJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0gICAgRFRNQXhpc1RyYXZlcnNlciBtX3RyYXZlcnNlcjsgLy8gZWFzaWVyIGZvciBub3cKLSAgICAKLSAgICBwdWJsaWMgRm9sbG93aW5nSXRlcmF0b3IoKQotICAgIHsKLSAgICAgIG1fdHJhdmVyc2VyID0gZ2V0QXhpc1RyYXZlcnNlcihBeGlzLkZPTExPV0lORyk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzUmVzdGFydGFibGUpCi0gICAgICB7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgIC8vID8/IC1zYgotICAgICAgICAvLyBmaW5kIHJpZ2h0bW9zdCBkZXNjZW5kYW50IChvciBzZWxmKQotICAgICAgICAvLyBpbnQgY3VycmVudDsKLSAgICAgICAgLy8gd2hpbGUgKChub2RlID0gZ2V0TGFzdENoaWxkKGN1cnJlbnQgPSBub2RlKSkgIT0gTlVMTCl7fQotICAgICAgICAvLyBfY3VycmVudE5vZGUgPSBjdXJyZW50OwotICAgICAgICBfY3VycmVudE5vZGUgPSBtX3RyYXZlcnNlci5maXJzdChub2RlKTsKLQotICAgICAgICAvLyBfY3VycmVudE5vZGUgcHJlY2VkZXMgcG9zc2libGUgZm9sbG93aW5nKG5vZGUpIG5vZGVzCi0gICAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0aGlzOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaW50IG5vZGUgPSBfY3VycmVudE5vZGU7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IG1fdHJhdmVyc2VyLm5leHQoX3N0YXJ0Tm9kZSwgX2N1cnJlbnROb2RlKTsKLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgRm9sbG93aW5nSXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIGZvbGxvd2luZyBub2RlcyBvZiBhIGdpdmVuIHR5cGUgZm9yIGEgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgY2xhc3MgVHlwZWRGb2xsb3dpbmdJdGVyYXRvciBleHRlbmRzIEZvbGxvd2luZ0l0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gdHlwZSBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICovCi0gICAgcHVibGljIFR5cGVkRm9sbG93aW5nSXRlcmF0b3IoaW50IHR5cGUpCi0gICAgewotICAgICAgX25vZGVUeXBlID0gdHlwZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIGhhbmRsZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBFTkQuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KCkKLSAgICB7Ci0KLSAgICAgIGludCBub2RlOwotCi0gICAgICB3aGlsZSAoKG5vZGUgPSBzdXBlci5uZXh0KCkpICE9IE5VTEwKLSAgICAgICAgICAgICAmJiBnZXRFeHBhbmRlZFR5cGVJRChub2RlKSAhPSBfbm9kZVR5cGUpe30KLQotICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgVHlwZWRGb2xsb3dpbmdJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGFuY2VzdG9ycyBvZiBhIGdpdmVuIG5vZGUgaW4gZG9jdW1lbnQKLSAgICogb3JkZXIuICAoTk9URSEgIFRoaXMgd2FzIGNoYW5nZWQgZnJvbSB0aGUgWFNMVEMgY29kZSEpCi0gICAqLwotICBwcml2YXRlIGNsYXNzIEFuY2VzdG9ySXRlcmF0b3IgZXh0ZW5kcyBJbnRlcm5hbEF4aXNJdGVyYXRvckJhc2UKLSAgewotICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLk5vZGVWZWN0b3IgbV9hbmNlc3RvcnMgPSAKLSAgICAgICAgIG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlVmVjdG9yKCk7Ci0gICAgICAgICAKLSAgICBpbnQgbV9hbmNlc3RvcnNQb3M7Ci0gICAgCi0gICAgLyoqIFRoZSByZWFsIHN0YXJ0IG5vZGUgZm9yIHRoaXMgYXhlcywgc2luY2UgX3N0YXJ0Tm9kZSB3aWxsIGJlIGFkanVzdGVkLiAqLwotICAgIGludCBtX3JlYWxTdGFydE5vZGU7Ci0gICAgCi0gICAgLyoqCi0gICAgICogR2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgcm9vdCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRTdGFydE5vZGUoKQotICAgIHsKLSAgICAgIHJldHVybiBtX3JlYWxTdGFydE5vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJ1ZSBpZiB0aGlzIGl0ZXJhdG9yIGhhcyBhIHJldmVyc2VkIGF4aXMuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgc2luY2UgdGhpcyBpdGVyYXRvciBpcyBhIHJldmVyc2VkIGF4aXMuCi0gICAgICovCi0gICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNSZXZlcnNlKCkKLSAgICB7Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhpcyBpbnRlcmF0aW9uLgotICAgICAqCi0gICAgICogJVRCRCUgJUJVRyUgVGhpcyBpcyByZXR1cm5pbmcgYSBub2RlSGFuZGxlIHJhdGhlciB0aGFuIGEgX3Bvc2l0aW9uCi0gICAgICogdmFsdWUuIFRoYXQgY29uZmxpY3RzIHdpdGggd2hhdCBldmVyeW9uZSBlbHNlIGlzIGRvaW5nLiBBbmQgaXQncwotICAgICAqIHRhbGtpbmcgYWJvdXQgdGhlIHN0YXJ0IG5vZGUsIHdoaWNoIGNvbmZsaWN0cyB3aXRoIHNvbWUgb2YgdGhlCi0gICAgICogb3RoZXIgcmV2ZXJzZSBpdGVyYXRvcnMuIERFRklOSVRFIEJVRzsgbmVlZHMgdG8gYmUgcmVjb25jaWxlZC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGxhc3QgZWxlbWVudCBpbiB0aGlzIGludGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMYXN0KCkKLSAgICB7Ci0gICAgICByZXR1cm4gKF9zdGFydE5vZGUpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhpcyBpdGVyYXRvci4gIFRoZSBjbG9uZWQgaXRlcmF0b3IgaXMgbm90IHJlc2V0LgotICAgICAqCi0gICAgICogQHJldHVybiBhIGRlZXAgY29weSBvZiB0aGlzIGl0ZXJhdG9yLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3IgY2xvbmVJdGVyYXRvcigpCi0gICAgewotICAgICAgX2lzUmVzdGFydGFibGUgPSBmYWxzZTsgIC8vIG11c3Qgc2V0IHRvIGZhbHNlIGZvciBhbnkgY2xvbmUKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGZpbmFsIEFuY2VzdG9ySXRlcmF0b3IgY2xvbmUgPSAoQW5jZXN0b3JJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLQotICAgICAgICBjbG9uZS5fc3RhcnROb2RlID0gX3N0YXJ0Tm9kZTsKLQotICAgICAgICAvLyByZXR1cm4gY2xvbmUucmVzZXQoKTsKLSAgICAgICAgcmV0dXJuIGNsb25lOwotICAgICAgfQotICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfSVRFUkFUT1JfQ0xPTkVfTk9UX1NVUFBPUlRFRCwgbnVsbCkpOyAvLyJJdGVyYXRvciBjbG9uZSBub3Qgc3VwcG9ydGVkLiIpOwotICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFNldCBzdGFydCB0byBFTkQgc2hvdWxkICdjbG9zZScgdGhlIGl0ZXJhdG9yLAotICAgICAqIGkuZS4gc3Vic2VxdWVudCBjYWxsIHRvIG5leHQoKSBzaG91bGQgcmV0dXJuIEVORC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFNldHMgdGhlIHJvb3Qgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3Igc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBEVE1BeGlzSXRlcmF0b3Igc2V0U3RhcnROb2RlKGludCBub2RlKQotICAgIHsKLSAgICAgIG1fcmVhbFN0YXJ0Tm9kZSA9IG5vZGU7Ci0KLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgaWYgKF9pbmNsdWRlU2VsZikKLSAgICAgICAgICBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIF9zdGFydE5vZGUgPSBnZXRQYXJlbnQobm9kZSk7Ci0KLSAgICAgICAgX2N1cnJlbnROb2RlID0gZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgCi0gICAgICAgIG5vZGUgPSBfc3RhcnROb2RlOwotICAgICAgICB3aGlsZSAobm9kZSAhPSBFTkQpCi0gICAgICAgIHsKLSAgICAgICAgICBtX2FuY2VzdG9ycy5hZGRFbGVtZW50KG5vZGUpOwotICAgICAgICAgIG5vZGUgPSBnZXRQYXJlbnQobm9kZSk7Ci0gICAgICAgIH0KLSAgICAgICAgbV9hbmNlc3RvcnNQb3MgPSBtX2FuY2VzdG9ycy5zaXplKCktMTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IHN0YXJ0IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzCi0gICAgICogICAgICAgICBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgICB7Ci0KLSAgICAgIF9jdXJyZW50Tm9kZSA9IGdldERvY3VtZW50KCk7Ci0gICAgICAgICAgICAKLSAgICAgIG1fYW5jZXN0b3JzUG9zID0gbV9hbmNlc3RvcnMuc2l6ZSgpLTE7Ci0KLSAgICAgIHJldHVybiByZXNldFBvc2l0aW9uKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbmV4dCA9IF9jdXJyZW50Tm9kZTsKLSAgICAgIAotICAgICAgaW50IHBvcyA9IG1fYW5jZXN0b3JzUG9zLS07Ci0gICAgICBpZihwb3MgPCAwKQotICAgICAgICBfY3VycmVudE5vZGUgPSBEVE0uTlVMTDsKLSAgICAgIGVsc2UKLSAgICAgICAgX2N1cnJlbnROb2RlID0gbV9hbmNlc3RvcnMuZWxlbWVudEF0KHBvcyk7Ci0gICAgICAKLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5leHQpOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIEFuY2VzdG9ySXRlcmF0b3IKLQotICAvKioKLSAgICogVHlwZWQgaXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBhbmNlc3RvcnMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlZEFuY2VzdG9ySXRlcmF0b3IgZXh0ZW5kcyBBbmNlc3Rvckl0ZXJhdG9yCi0gIHsKLQotICAgIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IHdhcyByZXF1ZXN0ZWQuICovCi0gICAgcHJpdmF0ZSBmaW5hbCBpbnQgX25vZGVUeXBlOwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSB0eXBlIFRoZSBleHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZWRBbmNlc3Rvckl0ZXJhdG9yKGludCB0eXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IHR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBOVUxMKQotICAgICAgewotICAgICAgICBpZiAoZ2V0RXhwYW5kZWRUeXBlSUQobm9kZSkgPT0gX25vZGVUeXBlKQotICAgICAgICAgIHJldHVybiByZXR1cm5Ob2RlKG5vZGUpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gKE5VTEwpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGlzIGludGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhpcyBpbnRlcmF0aW9uLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0TGFzdCgpCi0gICAgewotCi0gICAgICBpbnQgbGFzdCA9IE5VTEw7Ci0gICAgICBpbnQgY3VyciA9IF9zdGFydE5vZGU7Ci0KLSAgICAgIHdoaWxlIChjdXJyICE9IE5VTEwpCi0gICAgICB7Ci0gICAgICAgIGlmIChnZXRFeHBhbmRlZFR5cGVJRChjdXJyKSA9PSBfbm9kZVR5cGUpCi0gICAgICAgICAgbGFzdCA9IGN1cnI7Ci0KLSAgICAgICAgY3VyciA9IGdldFBhcmVudChjdXJyKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIChsYXN0KTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZEFuY2VzdG9ySXRlcmF0b3IKLQotICAvKioKLSAgICogSXRlcmF0b3IgdGhhdCByZXR1cm5zIHRoZSBkZXNjZW5kYW50cyBvZiBhIGdpdmVuIG5vZGUuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKioKLSAgICAgKiBTZXQgc3RhcnQgdG8gRU5EIHNob3VsZCAnY2xvc2UnIHRoZSBpdGVyYXRvciwKLSAgICAgKiBpLmUuIHN1YnNlcXVlbnQgY2FsbCB0byBuZXh0KCkgc2hvdWxkIHJldHVybiBFTkQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbm9kZSBTZXRzIHRoZSByb290IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yIHNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHNldFN0YXJ0Tm9kZShpbnQgbm9kZSkKLSAgICB7Ci0KLSAgICAgIGlmIChfaXNSZXN0YXJ0YWJsZSkKLSAgICAgIHsKLSAgICAgICAgbm9kZSA9IG5vZGUgJiBtX21hc2s7Ci0gICAgICAgIF9zdGFydE5vZGUgPSBub2RlOwotCi0gICAgICAgIGlmIChfaW5jbHVkZVNlbGYpCi0gICAgICAgICAgbm9kZS0tOwotCi0gICAgICAgIF9jdXJyZW50Tm9kZSA9IG5vZGU7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGlzIG5vZGUgaWRlbnRpdHkgaXMgYSBkZXNjZW5kYW50LiAgQXNzdW1lcyB0aGF0Ci0gICAgICogdGhlIG5vZGUgaW5mbyBmb3IgdGhlIGVsZW1lbnQgaGFzIGFscmVhZHkgYmVlbiBvYnRhaW5lZC4KLSAgICAgKgotICAgICAqIFRoaXMgb25lLXNpZGVkIHRlc3Qgd29ya3Mgb25seSBpZiB0aGUgcGFyZW50IGhhcyBiZWVuCi0gICAgICogcHJldmlvdXNseSB0ZXN0ZWQgYW5kIGlzIGtub3duIHRvIGJlIGEgZGVzY2VuZGVudC4gSXQgZmFpbHMgaWYKLSAgICAgKiB0aGUgcGFyZW50IGlzIHRoZSBfc3RhcnROb2RlJ3MgbmV4dCBzaWJsaW5nLCBvciBpbmRlZWQgYW55IG5vZGUKLSAgICAgKiB0aGF0IGZvbGxvd3MgX3N0YXJ0Tm9kZSBpbiBkb2N1bWVudCBvcmRlci4gIFRoYXQgbWF5IHN1ZmZpY2UKLSAgICAgKiBmb3IgdGhpcyBpdGVyYXRvciwgYnV0IGl0J3Mgbm90IHJlYWxseSBhbiBpc0Rlc2NlbmRlbnQoKSB0ZXN0LgotICAgICAqICVSRVZJRVclIHJlbmFtZT8KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgaW5kZXggbnVtYmVyIG9mIHRoZSBub2RlIGluIHF1ZXN0aW9uLgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgaW5kZXggaXMgYSBkZXNjZW5kYW50IG9mIF9zdGFydE5vZGUuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNEZXNjZW5kYW50KGludCBpZGVudGl0eSkKLSAgICB7Ci0gICAgICByZXR1cm4gKF9zdGFydE5vZGUgPT0gaWRlbnRpdHkpIHx8IF9wYXJlbnQoaWRlbnRpdHkpID49IF9zdGFydE5vZGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgIHsKLSAgICAgICAgaW50IG5vZGUgPSArK19jdXJyZW50Tm9kZTsKLSAgICAgICAgaW50IHR5cGUgPSBfdHlwZShub2RlKTsKLQotICAgICAgICBpZiAoTlVMTCA9PSB0eXBlIHx8IWlzRGVzY2VuZGFudChub2RlKSkKLSAgICAgICAgICByZXR1cm4gRU5EOwotCi0gICAgICAgIGlmIChBVFRSSUJVVEVfTk9ERSA9PSB0eXBlIHx8IE5BTUVTUEFDRV9OT0RFID09IHR5cGUpCi0gICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgcmV0dXJuIHJldHVybk5vZGUobm9kZSB8IG1fZHRtSWRlbnQpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgICB9Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgRGVzY2VuZGFudEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIFR5cGVkIGl0ZXJhdG9yIHRoYXQgcmV0dXJucyB0aGUgZGVzY2VuZGFudHMgb2YgYSBnaXZlbiBub2RlLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlZERlc2NlbmRhbnRJdGVyYXRvciBleHRlbmRzIERlc2NlbmRhbnRJdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkRGVzY2VuZGFudEl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlVHlwZSBFeHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZWREZXNjZW5kYW50SXRlcmF0b3IoaW50IG5vZGVUeXBlKQotICAgIHsKLSAgICAgIF9ub2RlVHlwZSA9IG5vZGVUeXBlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgaW50IG5vZGU7Ci0KLSAgICAgIHdoaWxlICgobm9kZSA9IHN1cGVyLm5leHQoKSkgIT0gTlVMTAotICAgICAgICAgICAgICYmIGdldEV4cGFuZGVkVHlwZUlEKG5vZGUpICE9IF9ub2RlVHlwZSl7fQotCi0gICAgICByZXR1cm4gbm9kZTsKLSAgICB9Ci0gIH0gIC8vIGVuZCBvZiBUeXBlZERlc2NlbmRhbnRJdGVyYXRvcgotCi0gIC8qKgotICAgKiBJdGVyYXRvciB0aGF0IHJldHVybnMgdGhlIGRlc2NlbmRhbnRzIG9mIGEgZ2l2ZW4gbm9kZS4KLSAgICogSSdtIG5vdCBleGFjdGx5IGNsZWFyIGFib3V0IHRoaXMgb25lLi4uIC1zYgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBOdGhEZXNjZW5kYW50SXRlcmF0b3IgZXh0ZW5kcyBEZXNjZW5kYW50SXRlcmF0b3IKLSAgewotCi0gICAgLyoqIFRoZSBjdXJyZW50IG50aCBwb3NpdGlvbi4gKi8KLSAgICBpbnQgX3BvczsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIE50aERlc2NlbmRhbnRJdGVyYXRvcgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcG9zIFRoZSBudGggcG9zaXRpb24gYmVpbmcgcmVxdWVzdGVkLgotICAgICAqLwotICAgIHB1YmxpYyBOdGhEZXNjZW5kYW50SXRlcmF0b3IoaW50IHBvcykKLSAgICB7Ci0gICAgICBfcG9zID0gcG9zOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBuZXh0IG5vZGUgaGFuZGxlIGluIHRoZSBpdGVyYXRpb24sIG9yIEVORC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoKQotICAgIHsKLQotICAgICAgLy8gSSdtIG5vdCBleGFjdGx5IGNsZWFyIHlldCB3aGF0IHRoaXMgaXMgZG9pbmcuLi4gLXNiCi0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKChub2RlID0gc3VwZXIubmV4dCgpKSAhPSBFTkQpCi0gICAgICB7Ci0gICAgICAgIG5vZGUgPSAobm9kZSAmIG1fbWFzayk7Ci0KLSAgICAgICAgaW50IHBhcmVudCA9IF9wYXJlbnQobm9kZSk7Ci0gICAgICAgIGludCBjaGlsZCA9IF9maXJzdGNoKHBhcmVudCk7Ci0gICAgICAgIGludCBwb3MgPSAwOwotCi0gICAgICAgIGRvCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgdHlwZSA9IF90eXBlKGNoaWxkKTsKLQotICAgICAgICAgIGlmIChFTEVNRU5UX05PREUgPT0gdHlwZSkKLSAgICAgICAgICAgIHBvcysrOwotICAgICAgICB9Ci0gICAgICAgIHdoaWxlICgocG9zIDwgX3BvcykgJiYgKGNoaWxkID0gX25leHRzaWIoY2hpbGQpKSAhPSBFTkQpOwotCi0gICAgICAgIGlmIChub2RlID09IGNoaWxkKQotICAgICAgICAgIHJldHVybiBub2RlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gKEVORCk7Ci0gICAgfQotICB9ICAvLyBlbmQgb2YgTnRoRGVzY2VuZGFudEl0ZXJhdG9yCi0KLSAgLyoqCi0gICAqIENsYXNzIFNpbmdsZXRvbkl0ZXJhdG9yLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBTaW5nbGV0b25JdGVyYXRvciBleHRlbmRzIEludGVybmFsQXhpc0l0ZXJhdG9yQmFzZQotICB7Ci0KLSAgICAvKiogKG5vdCBzdXJlIHlldCB3aGF0IHRoaXMgaXMuICAtc2IpICAoc2MgJiBzYiByZW1vdmUgZmluYWwgdG8gY29tcGlsZSBpbiBKREsgMS4xLjgpICovCi0gICAgcHJpdmF0ZSBib29sZWFuIF9pc0NvbnN0YW50OwotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IgU2luZ2xldG9uSXRlcmF0b3IKLSAgICAgKgotICAgICAqLwotICAgIHB1YmxpYyBTaW5nbGV0b25JdGVyYXRvcigpCi0gICAgewotICAgICAgdGhpcyhJbnRlZ2VyLk1JTl9WQUxVRSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFNpbmdsZXRvbkl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIGhhbmRsZSB0byByZXR1cm4uCi0gICAgICovCi0gICAgcHVibGljIFNpbmdsZXRvbkl0ZXJhdG9yKGludCBub2RlKQotICAgIHsKLSAgICAgIHRoaXMobm9kZSwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFNpbmdsZXRvbkl0ZXJhdG9yCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGhhbmRsZSB0byByZXR1cm4uCi0gICAgICogQHBhcmFtIGNvbnN0YW50IChOb3Qgc3VyZSB3aGF0IHRoaXMgaXMgeWV0LiAgLXNiKQotICAgICAqLwotICAgIHB1YmxpYyBTaW5nbGV0b25JdGVyYXRvcihpbnQgbm9kZSwgYm9vbGVhbiBjb25zdGFudCkKLSAgICB7Ci0gICAgICBfY3VycmVudE5vZGUgPSBfc3RhcnROb2RlID0gbm9kZTsKLSAgICAgIF9pc0NvbnN0YW50ID0gY29uc3RhbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogU2V0IHN0YXJ0IHRvIEVORCBzaG91bGQgJ2Nsb3NlJyB0aGUgaXRlcmF0b3IsCi0gICAgICogaS5lLiBzdWJzZXF1ZW50IGNhbGwgdG8gbmV4dCgpIHNob3VsZCByZXR1cm4gRU5ELgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGUgU2V0cyB0aGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiBBIERUTUF4aXNJdGVyYXRvciBzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICovCi0gICAgcHVibGljIERUTUF4aXNJdGVyYXRvciBzZXRTdGFydE5vZGUoaW50IG5vZGUpCi0gICAgewotCi0gICAgICBpZiAoX2lzQ29uc3RhbnQpCi0gICAgICB7Ci0gICAgICAgIF9jdXJyZW50Tm9kZSA9IF9zdGFydE5vZGU7Ci0KLSAgICAgICAgcmV0dXJuIHJlc2V0UG9zaXRpb24oKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKF9pc1Jlc3RhcnRhYmxlKQotICAgICAgewotICAgICAgICBpZiAoX2N1cnJlbnROb2RlID09IEludGVnZXIuTUlOX1ZBTFVFKQotICAgICAgICB7Ci0gICAgICAgICAgX2N1cnJlbnROb2RlID0gX3N0YXJ0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdGhpczsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXNldHMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IHN0YXJ0IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEEgRFRNQXhpc0l0ZXJhdG9yLCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGlzCi0gICAgICogICAgICAgICBpdGVyYXRvci4KLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNQXhpc0l0ZXJhdG9yIHJlc2V0KCkKLSAgICB7Ci0KLSAgICAgIGlmIChfaXNDb25zdGFudCkKLSAgICAgIHsKLSAgICAgICAgX2N1cnJlbnROb2RlID0gX3N0YXJ0Tm9kZTsKLQotICAgICAgICByZXR1cm4gcmVzZXRQb3NpdGlvbigpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBmaW5hbCBib29sZWFuIHRlbXAgPSBfaXNSZXN0YXJ0YWJsZTsKLQotICAgICAgICBfaXNSZXN0YXJ0YWJsZSA9IHRydWU7Ci0KLSAgICAgICAgc2V0U3RhcnROb2RlKF9zdGFydE5vZGUpOwotCi0gICAgICAgIF9pc1Jlc3RhcnRhYmxlID0gdGVtcDsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHRoaXM7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmaW5hbCBpbnQgcmVzdWx0ID0gX2N1cnJlbnROb2RlOwotCi0gICAgICBfY3VycmVudE5vZGUgPSBFTkQ7Ci0KLSAgICAgIHJldHVybiByZXR1cm5Ob2RlKHJlc3VsdCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEl0ZXJhdG9yIHRoYXQgcmV0dXJucyBhIGdpdmVuIG5vZGUgb25seSBpZiBpdCBpcyBvZiBhIGdpdmVuIHR5cGUuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGNsYXNzIFR5cGVkU2luZ2xldG9uSXRlcmF0b3IgZXh0ZW5kcyBTaW5nbGV0b25JdGVyYXRvcgotICB7Ci0KLSAgICAvKiogVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCB3YXMgcmVxdWVzdGVkLiAqLwotICAgIHByaXZhdGUgZmluYWwgaW50IF9ub2RlVHlwZTsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIFR5cGVkU2luZ2xldG9uSXRlcmF0b3IKLSAgICAgKgotICAgICAqCi0gICAgICogQHBhcmFtIG5vZGVUeXBlIFRoZSBleHRlbmRlZCB0eXBlIElEIGJlaW5nIHJlcXVlc3RlZC4KLSAgICAgKi8KLSAgICBwdWJsaWMgVHlwZWRTaW5nbGV0b25JdGVyYXRvcihpbnQgbm9kZVR5cGUpCi0gICAgewotICAgICAgX25vZGVUeXBlID0gbm9kZVR5cGU7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBoYW5kbGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRU5ELgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dCgpCi0gICAgewotCi0gICAgICBmaW5hbCBpbnQgcmVzdWx0ID0gc3VwZXIubmV4dCgpOwotCi0gICAgICByZXR1cm4gZ2V0RXhwYW5kZWRUeXBlSUQocmVzdWx0KSA9PSBfbm9kZVR5cGUgPyByZXN1bHQgOiBOVUxMOwotICAgIH0KLSAgfSAgLy8gZW5kIG9mIFR5cGVkU2luZ2xldG9uSXRlcmF0b3IKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTURlZmF1bHRCYXNlVHJhdmVyc2Vycy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNRGVmYXVsdEJhc2VUcmF2ZXJzZXJzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmNTc5NjYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNRGVmYXVsdEJhc2VUcmF2ZXJzZXJzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjY5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgdHJhdmVyc2VycyBmb3IgRFRNRGVmYXVsdEJhc2UuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMgZXh0ZW5kcyBEVE1EZWZhdWx0QmFzZQotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBEVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMgb2JqZWN0IGZyb20gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG1nciBUaGUgRFRNTWFuYWdlciB3aG8gb3ducyB0aGlzIERUTS4KLSAgICogQHBhcmFtIGRvbVNvdXJjZSB0aGUgRE9NIHNvdXJjZSB0aGF0IHRoaXMgRFRNIHdpbGwgd3JhcC4KLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBjb25zdHJ1Y3Rpb24gc291cmNlLgotICAgKiBAcGFyYW0gZHRtSWRlbnRpdHkgVGhlIERUTSBpZGVudGl0eSBJRCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIFRoZSB3aGl0ZSBzcGFjZSBmaWx0ZXIgZm9yIHRoaXMgRFRNLCB3aGljaCBtYXkKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgYmUgbnVsbC4KLSAgICogQHBhcmFtIHhzdHJpbmdmYWN0b3J5IFRoZSBmYWN0b3J5IHRvIHVzZSBmb3IgY3JlYXRpbmcgWE1MU3RyaW5ncy4KLSAgICogQHBhcmFtIGRvSW5kZXhpbmcgdHJ1ZSBpZiB0aGUgY2FsbGVyIGNvbnNpZGVycyBpdCB3b3J0aCBpdCB0byB1c2UKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICovCi0gIHB1YmxpYyBEVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMoRFRNTWFuYWdlciBtZ3IsIFNvdXJjZSBzb3VyY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGR0bUlkZW50aXR5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nRmFjdG9yeSB4c3RyaW5nZmFjdG9yeSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcpCi0gIHsKLSAgICBzdXBlcihtZ3IsIHNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsIHhzdHJpbmdmYWN0b3J5LAotICAgICAgICAgIGRvSW5kZXhpbmcpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgcmV0dXJucyBhIHN0YXRlbGVzcyAidHJhdmVyc2VyIiwgdGhhdCBjYW4gbmF2aWdhdGUKLSAgICogb3ZlciBhbiBYUGF0aCBheGlzLCB0aG91Z2ggcGVyaGFwcyBub3QgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAqCi0gICAqIEBwYXJhbSBheGlzIE9uZSBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzVHJhdmVyc2VyLCBvciBudWxsIGlmIHRoZSBnaXZlbiBheGlzIGlzbid0IHN1cHBvcnRlZC4KLSAgICovCi0gIHB1YmxpYyBEVE1BeGlzVHJhdmVyc2VyIGdldEF4aXNUcmF2ZXJzZXIoZmluYWwgaW50IGF4aXMpCi0gIHsKLQotICAgIERUTUF4aXNUcmF2ZXJzZXIgdHJhdmVyc2VyOwotCi0gICAgaWYgKG51bGwgPT0gbV90cmF2ZXJzZXJzKSAgLy8gQ2FjaGUgb2Ygc3RhdGVsZXNzIHRyYXZlcnNlcnMgZm9yIHRoaXMgRFRNCi0gICAgewotICAgICAgbV90cmF2ZXJzZXJzID0gbmV3IERUTUF4aXNUcmF2ZXJzZXJbQXhpcy5uYW1lcy5sZW5ndGhdOwotICAgICAgdHJhdmVyc2VyID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHRyYXZlcnNlciA9IG1fdHJhdmVyc2Vyc1theGlzXTsgIC8vIFNoYXJlL3JldXNlIGV4aXN0aW5nIHRyYXZlcnNlcgotCi0gICAgICBpZiAodHJhdmVyc2VyICE9IG51bGwpCi0gICAgICAgIHJldHVybiB0cmF2ZXJzZXI7Ci0gICAgfQotCi0gICAgc3dpdGNoIChheGlzKSAgLy8gR2VuZXJhdGUgbmV3IHRyYXZlcnNlcgotICAgIHsKLSAgICBjYXNlIEF4aXMuQU5DRVNUT1IgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IEFuY2VzdG9yVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuQU5DRVNUT1JPUlNFTEYgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IEFuY2VzdG9yT3JTZWxmVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuQVRUUklCVVRFIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBBdHRyaWJ1dGVUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5DSElMRCA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgQ2hpbGRUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5ERVNDRU5EQU5UIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBEZXNjZW5kYW50VHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuREVTQ0VOREFOVE9SU0VMRiA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgRGVzY2VuZGFudE9yU2VsZlRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkZPTExPV0lORyA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgRm9sbG93aW5nVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuRk9MTE9XSU5HU0lCTElORyA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgRm9sbG93aW5nU2libGluZ1RyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLk5BTUVTUEFDRSA6Ci0gICAgICB0cmF2ZXJzZXIgPSBuZXcgTmFtZXNwYWNlVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuTkFNRVNQQUNFREVDTFMgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IE5hbWVzcGFjZURlY2xzVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuUEFSRU5UIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBQYXJlbnRUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5QUkVDRURJTkcgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IFByZWNlZGluZ1RyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlBSRUNFRElOR1NJQkxJTkcgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IFByZWNlZGluZ1NpYmxpbmdUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5TRUxGIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBTZWxmVHJhdmVyc2VyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIEF4aXMuQUxMIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBBbGxGcm9tUm9vdFRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkFMTEZST01OT0RFIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBBbGxGcm9tTm9kZVRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlBSRUNFRElOR0FOREFOQ0VTVE9SIDoKLSAgICAgIHRyYXZlcnNlciA9IG5ldyBQcmVjZWRpbmdBbmRBbmNlc3RvclRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRTRlJPTVJPT1QgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IERlc2NlbmRhbnRGcm9tUm9vdFRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLkRFU0NFTkRBTlRTT1JTRUxGRlJPTVJPT1QgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IERlc2NlbmRhbnRPclNlbGZGcm9tUm9vdFRyYXZlcnNlcigpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBBeGlzLlJPT1QgOgotICAgICAgdHJhdmVyc2VyID0gbmV3IFJvb3RUcmF2ZXJzZXIoKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQXhpcy5GSUxURVJFRExJU1QgOgotICAgICAgcmV0dXJuIG51bGw7IC8vIERvbid0IHdhbnQgdG8gdGhyb3cgYW4gZXhjZXB0aW9uIGZvciB0aGlzIG9uZS4KLSAgICBkZWZhdWx0IDoKLSAgICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9BWElTX1RZUEUsIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnRvU3RyaW5nKGF4aXMpfSkpOyAvLyJVbmtub3duIGF4aXMgdHJhdmVyc2FsIHR5cGU6ICIrYXhpcyk7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgPT0gdHJhdmVyc2VyKQotICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbigiQXhpcyB0cmF2ZXJzZXIgbm90IHN1cHBvcnRlZDogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEF4aXMubmFtZXNbYXhpc10pOwotCi0gICAgbV90cmF2ZXJzZXJzW2F4aXNdID0gdHJhdmVyc2VyOwotCi0gICAgcmV0dXJuIHRyYXZlcnNlcjsKLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBBbmNlc3RvclRyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBpZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9wYXJlbnQuZWxlbWVudEF0KGN1cnJlbnQgJiBtX21hc2spIHwgbV9kdG1JZGVudDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIGN1cnJlbnQgPSBjdXJyZW50ICYgbV9tYXNrOwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKGN1cnJlbnQgPSBtX3BhcmVudC5lbGVtZW50QXQoY3VycmVudCkpKQotICAgICAgewotICAgICAgICBpZiAobV9leHB0eXBlLmVsZW1lbnRBdChjdXJyZW50KSA9PSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICByZXR1cm4gY3VycmVudCB8IG1fZHRtSWRlbnQ7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBBbmNlc3Rvck9yU2VsZlRyYXZlcnNlciBleHRlbmRzIEFuY2VzdG9yVHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBUbyBzZWUgaWYKLSAgICAgKiB0aGUgc2VsZiBub2RlIHNob3VsZCBiZSBwcm9jZXNzZWQsIHVzZSB0aGlzIGZ1bmN0aW9uLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0KQotICAgIHsKLSAgICAgIHJldHVybiBjb250ZXh0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBUbyBzZWUgaWYKLSAgICAgKiB0aGUgc2VsZiBub2RlIHNob3VsZCBiZSBwcm9jZXNzZWQsIHVzZSB0aGlzIGZ1bmN0aW9uLiAgSWYgdGhlIGNvbnRleHQKLSAgICAgKiBub2RlIGRvZXMgbm90IG1hdGNoIHRoZSBleHRlbmRlZCB0eXBlIElELCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuCi0gICAgICogZmFsc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLSAgICAgIHJldHVybiAobV9leHB0eXBlLmVsZW1lbnRBdChjb250ZXh0ICYgbV9tYXNrKSA9PSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICAgICA/IGNvbnRleHQgOiBuZXh0KGNvbnRleHQsIGNvbnRleHQsIGV4dGVuZGVkVHlwZUlEKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgQXR0cmlidXRlVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLSAgICAgIHJldHVybiAoY29udGV4dCA9PSBjdXJyZW50KQotICAgICAgICAgICAgID8gZ2V0Rmlyc3RBdHRyaWJ1dGUoY29udGV4dCkgOiBnZXROZXh0QXR0cmlidXRlKGN1cnJlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgY3VycmVudCA9IChjb250ZXh0ID09IGN1cnJlbnQpCi0gICAgICAgICAgICAgICAgPyBnZXRGaXJzdEF0dHJpYnV0ZShjb250ZXh0KSA6IGdldE5leHRBdHRyaWJ1dGUoY3VycmVudCk7Ci0KLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGlmIChtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpID09IGV4dGVuZGVkVHlwZUlEKQotICAgICAgICAgIHJldHVybiBjdXJyZW50OwotICAgICAgfQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChjdXJyZW50ID0gZ2V0TmV4dEF0dHJpYnV0ZShjdXJyZW50KSkpOwotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgQ2hpbGRUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLSAgICAKLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIG5leHQgaW5kZXhlZCBub2RlIHRoYXQgbWF0Y2hlcyB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4gIEJlZm9yZSAKLSAgICAgKiBjYWxsaW5nIHRoaXMgZnVuY3Rpb24sIG9uZSBzaG91bGQgZmlyc3QgY2FsbCAKLSAgICAgKiB7QGxpbmsgI2lzSW5kZXhlZChpbnQpIGlzSW5kZXhlZH0gdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGluZGV4IGNhbiAKLSAgICAgKiBjb250YWluIG5vZGVzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXhpc1Jvb3QgVGhlIHJvb3QgaWRlbnRpdHkgb2YgdGhlIGF4aXMuCi0gICAgICogQHBhcmFtIG5leHRQb3RlbnRpYWwgVGhlIG5vZGUgZm91bmQgbXVzdCBtYXRjaCBvciBvY2N1ciBhZnRlciB0aGlzIG5vZGUuCi0gICAgICogQHBhcmFtIGV4dGVuZGVkVHlwZUlEIFRoZSBleHRlbmRlZCB0eXBlIElEIGZvciB0aGUgcmVxdWVzdC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIG5vZGUgb3IgTlVMTCBpZiBub3QgZm91bmQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXROZXh0SW5kZXhlZChpbnQgYXhpc1Jvb3QsIGludCBuZXh0UG90ZW50aWFsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaW50IG5zSW5kZXggPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZUlEKGV4dGVuZGVkVHlwZUlEKTsKLSAgICAgIGludCBsbkluZGV4ID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWVJRChleHRlbmRlZFR5cGVJRCk7Ci0KLSAgICAgIGZvciAoOyA7ICkgCi0gICAgICB7Ci0gICAgICAgIGludCBuZXh0ID0gZmluZEVsZW1lbnRGcm9tSW5kZXgobnNJbmRleCwgbG5JbmRleCwgbmV4dFBvdGVudGlhbCk7Ci0KLSAgICAgICAgaWYgKE5PVFBST0NFU1NFRCAhPSBuZXh0KQotICAgICAgICB7Ci0gICAgICAgICAgaW50IHBhcmVudCA9IG1fcGFyZW50LmVsZW1lbnRBdChuZXh0KTsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBJcyBpdCBhIGNoaWxkPwotICAgICAgICAgIGlmKHBhcmVudCA9PSBheGlzUm9vdCkKLSAgICAgICAgICAgIHJldHVybiBuZXh0OwotICAgICAgICAgIAotICAgICAgICAgIC8vIElmIHRoZSBwYXJlbnQgb2NjdXJlZCBiZWZvcmUgdGhlIHN1YnRyZWUgcm9vdCwgdGhlbiAKLSAgICAgICAgICAvLyB3ZSBrbm93IGl0IGlzIHBhc3QgdGhlIGNoaWxkIGF4aXMuCi0gICAgICAgICAgaWYocGFyZW50IDwgYXhpc1Jvb3QpCi0gICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICAgIAotICAgICAgICAgIC8vIE90aGVyd2lzZSwgaXQgY291bGQgYmUgYSBkZXNjZW5kYW50IGJlbG93IHRoZSBzdWJ0cmVlIHJvb3QgCi0gICAgICAgICAgLy8gY2hpbGRyZW4sIG9yIGl0IGNvdWxkIGJlIGFmdGVyIHRoZSBzdWJ0cmVlIHJvb3QuICBTbyB3ZSBoYXZlIAotICAgICAgICAgIC8vIHRvIGNsaW1iIHVwIHVudGlsIHRoZSBwYXJlbnQgaXMgbGVzcyB0aGFuIHRoZSBzdWJ0cmVlIHJvb3QsIGluIAotICAgICAgICAgIC8vIHdoaWNoIGNhc2Ugd2UgcmV0dXJuIE5VTEwsIG9yIHVudGlsIGl0IGlzIGVxdWFsIHRvIHRoZSBzdWJ0cmVlIAotICAgICAgICAgIC8vIHJvb3QsIGluIHdoaWNoIGNhc2Ugd2UgY29udGludWUgdG8gbG9vay4KLSAgICAgICAgICBkbwotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBhcmVudCA9IG1fcGFyZW50LmVsZW1lbnRBdChwYXJlbnQpOwotICAgICAgICAgICAgaWYocGFyZW50IDwgYXhpc1Jvb3QpCi0gICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICAgIH0KLSAgICAgICAgICAgIHdoaWxlKHBhcmVudCA+IGF4aXNSb290KTsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkZvdW5kIG5vZGUgdmlhIGluZGV4OiAiK2ZpcnN0KTsKLSAgICAgICAgICBuZXh0UG90ZW50aWFsID0gbmV4dCsxOwotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgbmV4dE5vZGUoKTsKLSAgICAgICAgCi0gICAgICAgIGlmKCEobV9uZXh0c2liLmVsZW1lbnRBdChheGlzUm9vdCkgPT0gTk9UUFJPQ0VTU0VEKSkKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgICAgICAgCi0gICAgLyoqCi0gICAgICogQnkgdGhlIG5hdHVyZSBvZiB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbCwgdGhlIGNvbnRleHQgbm9kZSBjYW4gbm90IGJlCi0gICAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFNvIHRvIHRyYXZlcnNlIAotICAgICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgb3ZlcmxvYWRlZCBvbmx5IGJ5IHRob3NlIGF4aXMgdGhhdCBwcm9jZXNzCi0gICAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4gVGhpcyBpcyB0aGUgcG9pbnQKLSAgICAgKiB0aGF0IHRoZSB0cmF2ZXJzYWwgc3RhcnRzIGZyb20uCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gICAgewotICAgICAgcmV0dXJuIF9maXJzdGNoKGNvbnRleHQgJiBtX21hc2spIHwgbV9kdG1JZGVudDsKLSAgICB9Ci0gIAotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBTbyB0byB0cmF2ZXJzZSAKLSAgICAgKiBhbiBheGlzLCB0aGUgZmlyc3QgZnVuY3Rpb24gbXVzdCBiZSB1c2VkIHRvIGdldCB0aGUgZmlyc3Qgbm9kZS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIG92ZXJsb2FkZWQgb25seSBieSB0aG9zZSBheGlzIHRoYXQgcHJvY2VzcwotICAgICAqIHRoZSBzZWxmIG5vZGUuIDxccD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICBpZih0cnVlKQotICAgICAgewotICAgICAgICBpbnQgaWRlbnRpdHkgPSBjb250ZXh0ICYgbV9tYXNrOwotICAgICAgICAKLSAgICAgICAgaW50IGZpcnN0TWF0Y2ggPSBnZXROZXh0SW5kZXhlZChpZGVudGl0eSwgX2ZpcnN0Y2goaWRlbnRpdHkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kZWRUeXBlSUQpOwotICAgICAgIAotICAgICAgICByZXR1cm4gZmlyc3RNYXRjaCB8IG1fZHRtSWRlbnQ7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGZvciAoaW50IGN1cnJlbnQgPSBfZmlyc3RjaChjb250ZXh0ICYgbV9tYXNrKTsgCi0gICAgICAgICAgICAgRFRNLk5VTEwgIT0gY3VycmVudDsgCi0gICAgICAgICAgICAgY3VycmVudCA9IF9uZXh0c2liKGN1cnJlbnQpKSAKLSAgICAgICAgewotICAgICAgICAgIGlmIChtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpID09IGV4dGVuZGVkVHlwZUlEKQotICAgICAgICAgICAgICByZXR1cm4gY3VycmVudCB8IG1fZHRtSWRlbnQ7Ci0gICAgICAgIH0KLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICAKLSAgICAgIHJldHVybiBfbmV4dHNpYihjdXJyZW50ICYgbV9tYXNrKSB8IG1fZHRtSWRlbnQ7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4dGVuZGVkVHlwZUlEIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXh0ZW5kZWRUeXBlSUQpCi0gICAgewotCi0gICAgICBmb3IgKGN1cnJlbnQgPSBfbmV4dHNpYihjdXJyZW50ICYgbV9tYXNrKTsgCi0gICAgICAgICAgIERUTS5OVUxMICE9IGN1cnJlbnQ7IAotICAgICAgICAgICBjdXJyZW50ID0gX25leHRzaWIoY3VycmVudCkpIAotICAgICAgewotICAgICAgICBpZiAobV9leHB0eXBlLmVsZW1lbnRBdChjdXJyZW50KSA9PSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICAgIHJldHVybiBjdXJyZW50IHwgbV9kdG1JZGVudDsKLSAgICAgIH0KLSAgICAgIAotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFN1cGVyIGNsYXNzIGZvciBkZXJpdmVkIGNsYXNzZXMgdGhhdCB3YW50IGEgY29udmVuaWVudCB3YXkgdG8gYWNjZXNzIAotICAgKiB0aGUgaW5kZXhpbmcgbWVjaGFuaXNtLgotICAgKi8KLSAgcHJpdmF0ZSBhYnN0cmFjdCBjbGFzcyBJbmRleGVkRFRNQXhpc1RyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVGVsbCBpZiB0aGUgaW5kZXhpbmcgaXMgb24gYW5kIHRoZSBnaXZlbiBleHRlbmRlZCB0eXBlIElEIG1hdGNoZXMgCi0gICAgICogd2hhdCBpcyBpbiB0aGUgaW5kZXhlcy4gIERlcml2ZWQgY2xhc3NlcyBzaG91bGQgY2FsbCB0aGlzIGJlZm9yZSAKLSAgICAgKiBjYWxsaW5nIHtAbGluayAjZ2V0TmV4dEluZGV4ZWQoaW50LCBpbnQsIGludCkgZ2V0TmV4dEluZGV4ZWR9IG1ldGhvZC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBiZWluZyByZXF1ZXN0ZWQuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgaXQgaXMgT0sgdG8gY2FsbCB0aGUgCi0gICAgICogICAgICAgICB7QGxpbmsgI2dldE5leHRJbmRleGVkKGludCwgaW50LCBpbnQpIGdldE5leHRJbmRleGVkfSBtZXRob2QuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gaXNJbmRleGVkKGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIHJldHVybiAobV9pbmRleGluZwotICAgICAgICAgICAgICAmJiBFeHBhbmRlZE5hbWVUYWJsZS5FTEVNRU5UCi0gICAgICAgICAgICAgICAgID09IChleHRlbmRlZFR5cGVJRCAmIEV4cGFuZGVkTmFtZVRhYmxlLk1BU0tfTk9ERVRZUEUpKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIGEgbm9kZSBpcyBvdXRzaWRlIHRoZSBheGlzIGJlaW5nIHRyYXZlcnNlZC4gIFRoaXMgbWV0aG9kIG11c3QgYmUgCi0gICAgICogaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzLCBhbmQgbXVzdCBiZSByb2J1c3QgZW5vdWdoIHRvIGhhbmRsZSBhbnkgCi0gICAgICogbm9kZSB0aGF0IG9jY3VycyBhZnRlciB0aGUgYXhpcyByb290LgotICAgICAqCi0gICAgICogQHBhcmFtIGF4aXNSb290IFRoZSByb290IGlkZW50aXR5IG9mIHRoZSBheGlzLgotICAgICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBmYWxscyBvdXRzaWRlIHRoZSBheGlzIGJlaW5nIHRyYXZlcnNlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBpc0FmdGVyQXhpcyhpbnQgYXhpc1Jvb3QsIGludCBpZGVudGl0eSk7Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoZSBheGlzIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCB0byB0ZWxsIGlmIGEgdGhlIHdhaXQgZm9yIAotICAgICAqIGFuIGFycml2aW5nIG5vZGUgc2hvdWxkIHRlcm1pbmF0ZS4gIFRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgCi0gICAgICogYmUgYSBkZXJpdmVkIGNsYXNzLgotICAgICAqCi0gICAgICogQHBhcmFtIGF4aXNSb290IFRoZSByb290IGlkZW50aXR5IG9mIHRoZSBheGlzLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBheGlzIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBheGlzSGFzQmVlblByb2Nlc3NlZChpbnQgYXhpc1Jvb3QpOwotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBuZXh0IGluZGV4ZWQgbm9kZSB0aGF0IG1hdGNoZXMgdGhlIGV4dGVuZGVkIHR5cGUgSUQuICBCZWZvcmUgCi0gICAgICogY2FsbGluZyB0aGlzIGZ1bmN0aW9uLCBvbmUgc2hvdWxkIGZpcnN0IGNhbGwgCi0gICAgICoge0BsaW5rICNpc0luZGV4ZWQoaW50KSBpc0luZGV4ZWR9IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBpbmRleCBjYW4gCi0gICAgICogY29udGFpbiBub2RlcyB0aGF0IG1hdGNoIHRoZSBnaXZlbiBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGF4aXNSb290IFRoZSByb290IGlkZW50aXR5IG9mIHRoZSBheGlzLgotICAgICAqIEBwYXJhbSBuZXh0UG90ZW50aWFsIFRoZSBub2RlIGZvdW5kIG11c3QgbWF0Y2ggb3Igb2NjdXIgYWZ0ZXIgdGhpcyBub2RlLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCBmb3IgdGhlIHJlcXVlc3QuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIG9yIE5VTEwgaWYgbm90IGZvdW5kLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZ2V0TmV4dEluZGV4ZWQoaW50IGF4aXNSb290LCBpbnQgbmV4dFBvdGVudGlhbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIGludCBuc0luZGV4ID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXROYW1lc3BhY2VJRChleHRlbmRlZFR5cGVJRCk7Ci0gICAgICBpbnQgbG5JbmRleCA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TG9jYWxOYW1lSUQoZXh0ZW5kZWRUeXBlSUQpOwotCi0gICAgICB3aGlsZSh0cnVlKQotICAgICAgewotICAgICAgICBpbnQgbmV4dCA9IGZpbmRFbGVtZW50RnJvbUluZGV4KG5zSW5kZXgsIGxuSW5kZXgsIG5leHRQb3RlbnRpYWwpOwotCi0gICAgICAgIGlmIChOT1RQUk9DRVNTRUQgIT0gbmV4dCkKLSAgICAgICAgewotICAgICAgICAgIGlmIChpc0FmdGVyQXhpcyhheGlzUm9vdCwgbmV4dCkpCi0gICAgICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRm91bmQgbm9kZSB2aWEgaW5kZXg6ICIrZmlyc3QpOwotICAgICAgICAgIHJldHVybiBuZXh0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoYXhpc0hhc0JlZW5Qcm9jZXNzZWQoYXhpc1Jvb3QpKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlKCk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgRGVzY2VuZGFudFRyYXZlcnNlciBleHRlbmRzIEluZGV4ZWREVE1BeGlzVHJhdmVyc2VyCi0gIHsKLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGZpcnN0IHBvdGVudGlhbCBpZGVudGl0eSB0aGF0IGNhbiBiZSByZXR1cm5lZC4gIFRoaXMgc2hvdWxkIAotICAgICAqIGJlIG92ZXJyaWRkZWQgYnkgY2xhc3NlcyB0aGF0IG5lZWQgdG8gcmV0dXJuIHRoZSBzZWxmIG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgb2YgdGhlIHJvb3QgY29udGV4dCBvZiB0aGUgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgZmlyc3QgcG90ZW50aWFsIG5vZGUgdGhhdCBjYW4gYmUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldEZpcnN0UG90ZW50aWFsKGludCBpZGVudGl0eSkKLSAgICB7Ci0gICAgICByZXR1cm4gaWRlbnRpdHkgKyAxOwotICAgIH0KLSAgICAKLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoZSBheGlzIGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCB0byB0ZWxsIGlmIGEgdGhlIHdhaXQgZm9yIAotICAgICAqIGFuIGFycml2aW5nIG5vZGUgc2hvdWxkIHRlcm1pbmF0ZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBheGlzUm9vdCBUaGUgcm9vdCBpZGVudGl0eSBvZiB0aGUgYXhpcy4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYXhpcyBoYXMgYmVlbiBmdWxseSBwcm9jZXNzZWQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGJvb2xlYW4gYXhpc0hhc0JlZW5Qcm9jZXNzZWQoaW50IGF4aXNSb290KQotICAgIHsKLSAgICAgIHJldHVybiAhKG1fbmV4dHNpYi5lbGVtZW50QXQoYXhpc1Jvb3QpID09IE5PVFBST0NFU1NFRCk7Ci0gICAgfQotICAgIAotICAgIC8qKgotICAgICAqIEdldCB0aGUgc3VidHJlZSByb290IGlkZW50aXR5IGZyb20gdGhlIGhhbmRsZSB0aGF0IHdhcyBwYXNzZWQgaW4gYnkgCi0gICAgICogdGhlIGNhbGxlci4gIERlcml2ZWQgY2xhc3NlcyBtYXkgb3ZlcnJpZGUgdGhpcyB0byBjaGFuZ2UgdGhlIHJvb3QgCi0gICAgICogY29udGV4dCBvZiB0aGUgdHJhdmVyc2FsLgotICAgICAqIAotICAgICAqIEBwYXJhbSBoYW5kbGUgaGFuZGxlIHRvIHRoZSByb290IGNvbnRleHQuCi0gICAgICogQHJldHVybiBpZGVudGl0eSBvZiB0aGUgcm9vdCBvZiB0aGUgc3VidHJlZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldFN1YnRyZWVSb290KGludCBoYW5kbGUpCi0gICAgewotICAgICAgcmV0dXJuIGhhbmRsZSAmIG1fbWFzazsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUZWxsIGlmIHRoaXMgbm9kZSBpZGVudGl0eSBpcyBhIGRlc2NlbmRhbnQuICBBc3N1bWVzIHRoYXQKLSAgICAgKiB0aGUgbm9kZSBpbmZvIGZvciB0aGUgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIG9idGFpbmVkLgotICAgICAqCi0gICAgICogJVJFVklFVyUgVGhpcyBpcyByZWFsbHkgcGFyZW50Rm9sbG93c1Jvb3RJbkRvY3VtZW50T3JkZXIgLi4uCi0gICAgICogd2hpY2ggZmFpbHMgaWYgdGhlIHBhcmVudCBzdGFydHMgYWZ0ZXIgdGhlIHJvb3QgZW5kcy4KLSAgICAgKiBNYXkgYmUgc3VmZmljaWVudCBmb3IgdGhpcyBjbGFzcydzIGxvZ2ljLCBidXQgbWlzbGVhZGluZ2x5IG5hbWVkIQotICAgICAqCi0gICAgICogQHBhcmFtIHN1YnRyZWVSb290SWRlbnRpdHkgVGhlIHJvb3QgY29udGV4dCBvZiB0aGUgc3VidHJlZSBpbiBxdWVzdGlvbi4KLSAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIGluZGV4IG51bWJlciBvZiB0aGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGluZGV4IGlzIGEgZGVzY2VuZGFudCBvZiBfc3RhcnROb2RlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGlzRGVzY2VuZGFudChpbnQgc3VidHJlZVJvb3RJZGVudGl0eSwgaW50IGlkZW50aXR5KQotICAgIHsKLSAgICAgIHJldHVybiBfcGFyZW50KGlkZW50aXR5KSA+PSBzdWJ0cmVlUm9vdElkZW50aXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRlbGwgaWYgYSBub2RlIGlzIG91dHNpZGUgdGhlIGF4aXMgYmVpbmcgdHJhdmVyc2VkLiAgVGhpcyBtZXRob2QgbXVzdCBiZSAKLSAgICAgKiBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNsYXNzZXMsIGFuZCBtdXN0IGJlIHJvYnVzdCBlbm91Z2ggdG8gaGFuZGxlIGFueSAKLSAgICAgKiBub2RlIHRoYXQgb2NjdXJzIGFmdGVyIHRoZSBheGlzIHJvb3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gYXhpc1Jvb3QgVGhlIHJvb3QgaWRlbnRpdHkgb2YgdGhlIGF4aXMuCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGluIHF1ZXN0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBub2RlIGZhbGxzIG91dHNpZGUgdGhlIGF4aXMgYmVpbmcgdHJhdmVyc2VkLgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGlzQWZ0ZXJBeGlzKGludCBheGlzUm9vdCwgaW50IGlkZW50aXR5KQotICAgIHsgICAKLSAgICAgIC8vICVSRVZJRVclIElzIHRoZXJlICphbnkqIGNoZWFwZXIgd2F5IHRvIGRvIHRoaXM/Ci0gICAgICBkbwotICAgICAgewotICAgICAgICBpZihpZGVudGl0eSA9PSBheGlzUm9vdCkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGlkZW50aXR5ID0gbV9wYXJlbnQuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgICAgIH0KLSAgICAgICAgd2hpbGUoaWRlbnRpdHkgPj0gYXhpc1Jvb3QpOwotICAgICAgICAKLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBTbyB0byB0cmF2ZXJzZQotICAgICAqIGFuIGF4aXMsIHRoZSBmaXJzdCBmdW5jdGlvbiBtdXN0IGJlIHVzZWQgdG8gZ2V0IHRoZSBmaXJzdCBub2RlLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgb3ZlcmxvYWRlZCBvbmx5IGJ5IHRob3NlIGF4aXMgdGhhdCBwcm9jZXNzCi0gICAgICogdGhlIHNlbGYgbm9kZS4gPFxwPgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4gVGhpcyBpcyB0aGUgcG9pbnQKLSAgICAgKiBvZiBvcmlnaW4gZm9yIHRoZSB0cmF2ZXJzYWwgLS0gaXRzICJyb290IG5vZGUiIG9yIHN0YXJ0aW5nIHBvaW50LgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaWYgKGlzSW5kZXhlZChleHRlbmRlZFR5cGVJRCkpCi0gICAgICB7Ci0gICAgICAgIGludCBpZGVudGl0eSA9IGdldFN1YnRyZWVSb290KGNvbnRleHQpOwotICAgICAgICBpbnQgZmlyc3RQb3RlbnRpYWwgPSBnZXRGaXJzdFBvdGVudGlhbChpZGVudGl0eSk7Ci0KLSAgICAgICAgcmV0dXJuIGdldE5leHRJbmRleGVkKGlkZW50aXR5LCBmaXJzdFBvdGVudGlhbCwgZXh0ZW5kZWRUeXBlSUQpfG1fZHRtSWRlbnQ7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBuZXh0KGNvbnRleHQsIGNvbnRleHQsIGV4dGVuZGVkVHlwZUlEKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBnZXRTdWJ0cmVlUm9vdChjb250ZXh0KTsKLQotICAgICAgZm9yIChjdXJyZW50ID0gKGN1cnJlbnQgJiBtX21hc2spICsgMTsgOyBjdXJyZW50KyspCi0gICAgICB7Ci0gICAgICAgIGludCB0eXBlID0gX3R5cGUoY3VycmVudCk7ICAvLyBtYXkgY2FsbCBuZXh0Tm9kZSgpCi0KLSAgICAgICAgaWYgKCFpc0Rlc2NlbmRhbnQoc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCkpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgaWYgKEFUVFJJQlVURV9OT0RFID09IHR5cGUgfHwgTkFNRVNQQUNFX05PREUgPT0gdHlwZSkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBnZXRTdWJ0cmVlUm9vdChjb250ZXh0KTsKLQotICAgICAgY3VycmVudCA9IChjdXJyZW50ICYgbV9tYXNrKSArIDE7Ci0KLSAgICAgIGlmIChpc0luZGV4ZWQoZXh0ZW5kZWRUeXBlSUQpKQotICAgICAgewotICAgICAgICByZXR1cm4gZ2V0TmV4dEluZGV4ZWQoc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCwgZXh0ZW5kZWRUeXBlSUQpfG1fZHRtSWRlbnQ7Ci0gICAgICB9Ci0KLSAgICAgIGZvciAoOyA7IGN1cnJlbnQrKykKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBfZXhwdHlwZShjdXJyZW50KTsgIC8vIG1heSBjYWxsIG5leHROb2RlKCkKLQotICAgICAgICBpZiAoIWlzRGVzY2VuZGFudChzdWJ0cmVlUm9vdElkZW50LCBjdXJyZW50KSkKLSAgICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgICBpZiAoZXhwdHlwZSAhPSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBEZXNjZW5kYW50T3JTZWxmVHJhdmVyc2VyIGV4dGVuZHMgRGVzY2VuZGFudFRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGZpcnN0IHBvdGVudGlhbCBpZGVudGl0eSB0aGF0IGNhbiBiZSByZXR1cm5lZCwgd2hpY2ggaXMgdGhlIAotICAgICAqIGF4aXMgY29udGV4dCwgaW4gdGhpcyBjYXNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5IG9mIHRoZSByb290IGNvbnRleHQgb2YgdGhlIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGF4aXMgY29udGV4dC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldEZpcnN0UG90ZW50aWFsKGludCBpZGVudGl0eSkKLSAgICB7Ci0gICAgICByZXR1cm4gaWRlbnRpdHk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQnkgdGhlIG5hdHVyZSBvZiB0aGUgc3RhdGVsZXNzIHRyYXZlcnNhbCwgdGhlIGNvbnRleHQgbm9kZSBjYW4gbm90IGJlCi0gICAgICogcmV0dXJuZWQgb3IgdGhlIGl0ZXJhdGlvbiB3aWxsIGdvIGludG8gYW4gaW5maW5hdGUgbG9vcC4gIFRvIHNlZSBpZgotICAgICAqIHRoZSBzZWxmIG5vZGUgc2hvdWxkIGJlIHByb2Nlc3NlZCwgdXNlIHRoaXMgZnVuY3Rpb24uCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gICAgewotICAgICAgcmV0dXJuIGNvbnRleHQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBlbnRpcmUgc3VidHJlZSwgaW5jbHVkaW5nIHRoZSByb290IG5vZGUuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIEFsbEZyb21Ob2RlVHJhdmVyc2VyIGV4dGVuZHMgRGVzY2VuZGFudE9yU2VsZlRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBjb250ZXh0ICYgbV9tYXNrOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSAoY3VycmVudCAmIG1fbWFzaykgKyAxOyA7IGN1cnJlbnQrKykKLSAgICAgIHsKLQotICAgICAgICAvLyBUcmlja29sb2dpY2FsIGNvZGU6IF9leHB0eXBlKCkgaGFzIHRoZSBzaWRlLWVmZmVjdCBvZgotICAgICAgICAvLyBydW5uaW5nIG5leHROb2RlIHVudGlsIHRoZSBzcGVjaWZpZWQgbm9kZSBoYXMgYmVlbiBsb2FkZWQsCi0gICAgICAgIC8vIGFuZCB0aHVzIGNhbiBiZSB1c2VkIHRvIGVuc3VyZSB0aGF0IGluY3JlbWVudGFsIGNvbnN0cnVjdGlvbiBvZgotICAgICAgICAvLyB0aGUgRFRNIGhhcyBnb3R0ZW4gdGhpcyBmYXIuIFVzaW5nIGl0IGp1c3QgZm9yIHRoYXQgc2lkZS1lZmZlY3QKLSAgICAgICAgLy8gaXMgYSBiaXQgb2YgYSBrbHVnZS4uLgotICAgICAgICBfZXhwdHlwZShjdXJyZW50KTsgIC8vIG1ha2Ugc3VyZSBpdCdzIGhlcmUuCi0KLSAgICAgICAgaWYgKCFpc0Rlc2NlbmRhbnQoc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCkpCi0gICAgICAgICAgcmV0dXJuIE5VTEw7Ci0KLSAgICAgICAgcmV0dXJuIChjdXJyZW50IHwgbV9kdG1JZGVudCk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIGZvbGxvd2luZyBhY2Nlc3MsIGluIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBGb2xsb3dpbmdUcmF2ZXJzZXIgZXh0ZW5kcyBEZXNjZW5kYW50VHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3Qgb2YgdGhlIGZvbGxvd2luZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogdGhhdCB0aGUgdHJhdmVyc2FsIHN0YXJ0cyBmcm9tLgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0KQotICAgIHsKLQotICAgICAgaW50IGZpcnN0OwotICAgICAgaW50IHR5cGUgPSBfdHlwZShjb250ZXh0KTsKLQotICAgICAgaWYgKChEVE0uQVRUUklCVVRFX05PREUgPT0gdHlwZSkgfHwgKERUTS5OQU1FU1BBQ0VfTk9ERSA9PSB0eXBlKSkKLSAgICAgIHsKLSAgICAgICAgY29udGV4dCA9IGdldFBhcmVudChjb250ZXh0KTsKLSAgICAgICAgZmlyc3QgPSBnZXRGaXJzdENoaWxkKGNvbnRleHQpOwotCi0gICAgICAgIGlmIChOVUxMICE9IGZpcnN0KQotICAgICAgICAgIHJldHVybiBmaXJzdDsKLSAgICAgIH0KLQotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgZmlyc3QgPSBnZXROZXh0U2libGluZyhjb250ZXh0KTsKLQotICAgICAgICBpZiAoTlVMTCA9PSBmaXJzdCkKLSAgICAgICAgICBjb250ZXh0ID0gZ2V0UGFyZW50KGNvbnRleHQpOwotICAgICAgfQotICAgICAgd2hpbGUgKE5VTEwgPT0gZmlyc3QgJiYgTlVMTCAhPSBjb250ZXh0KTsKLQotICAgICAgcmV0dXJuIGZpcnN0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3Qgb2YgdGhlIGZvbGxvd2luZy4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIGludCBmaXJzdDsKLSAgICAgIGludCB0eXBlID0gX3R5cGUoY29udGV4dCk7Ci0KLSAgICAgIGlmICgoRFRNLkFUVFJJQlVURV9OT0RFID09IHR5cGUpIHx8IChEVE0uTkFNRVNQQUNFX05PREUgPT0gdHlwZSkpCi0gICAgICB7Ci0gICAgICAgIGNvbnRleHQgPSBnZXRQYXJlbnQoY29udGV4dCk7Ci0gICAgICAgIGZpcnN0ID0gZ2V0Rmlyc3RDaGlsZChjb250ZXh0KTsKLQotICAgICAgICBpZiAoTlVMTCAhPSBmaXJzdCkKLSAgICAgICAgewotICAgICAgICAgIGlmIChfZXhwdHlwZShmaXJzdCkgPT0gZXh0ZW5kZWRUeXBlSUQpCi0gICAgICAgICAgICByZXR1cm4gZmlyc3Q7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG5leHQoY29udGV4dCwgZmlyc3QsIGV4dGVuZGVkVHlwZUlEKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBkbwotICAgICAgewotICAgICAgICBmaXJzdCA9IGdldE5leHRTaWJsaW5nKGNvbnRleHQpOwotCi0gICAgICAgIGlmIChOVUxMID09IGZpcnN0KQotICAgICAgICAgIGNvbnRleHQgPSBnZXRQYXJlbnQoY29udGV4dCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGlmIChfZXhwdHlwZShmaXJzdCkgPT0gZXh0ZW5kZWRUeXBlSUQpCi0gICAgICAgICAgICByZXR1cm4gZmlyc3Q7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgcmV0dXJuIG5leHQoY29udGV4dCwgZmlyc3QsIGV4dGVuZGVkVHlwZUlEKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgd2hpbGUgKE5VTEwgPT0gZmlyc3QgJiYgTlVMTCAhPSBjb250ZXh0KTsKLQotICAgICAgcmV0dXJuIGZpcnN0OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotCi0gICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgIHsKLSAgICAgICAgY3VycmVudCsrOwotCi0gICAgICAgIGludCB0eXBlID0gX3R5cGUoY3VycmVudCk7ICAvLyBtYXkgY2FsbCBuZXh0Tm9kZSgpCi0KLSAgICAgICAgaWYgKE5VTEwgPT0gdHlwZSkKLSAgICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgICBpZiAoQVRUUklCVVRFX05PREUgPT0gdHlwZSB8fCBOQU1FU1BBQ0VfTk9ERSA9PSB0eXBlKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiAoY3VycmVudCB8IG1fZHRtSWRlbnQpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgICB9Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4dGVuZGVkVHlwZUlEIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXh0ZW5kZWRUeXBlSUQpCi0gICAgewotCi0gICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgIHsKLSAgICAgICAgY3VycmVudCsrOwotCi0gICAgICAgIGludCBldHlwZSA9IF9leHB0eXBlKGN1cnJlbnQpOyAgLy8gbWF5IGNhbGwgbmV4dE5vZGUoKQotCi0gICAgICAgIGlmIChOVUxMID09IGV0eXBlKQotICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgIGlmIChldHlwZSAhPSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBGb2xsb3dpbmdTaWJsaW5nVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLSAgICAgIHJldHVybiBnZXROZXh0U2libGluZyhjdXJyZW50KTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoY3VycmVudCA9IGdldE5leHRTaWJsaW5nKGN1cnJlbnQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCAmIG1fbWFzaykgPT0gZXh0ZW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBOYW1lc3BhY2VEZWNsc1RyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0KLSAgICAgIHJldHVybiAoY29udGV4dCA9PSBjdXJyZW50KQotICAgICAgICAgICAgID8gZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGZhbHNlKQotICAgICAgICAgICAgIDogZ2V0TmV4dE5hbWVzcGFjZU5vZGUoY29udGV4dCwgY3VycmVudCwgZmFsc2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgY3VycmVudCA9IChjb250ZXh0ID09IGN1cnJlbnQpCi0gICAgICAgICAgICAgICAgPyBnZXRGaXJzdE5hbWVzcGFjZU5vZGUoY29udGV4dCwgZmFsc2UpCi0gICAgICAgICAgICAgICAgOiBnZXROZXh0TmFtZXNwYWNlTm9kZShjb250ZXh0LCBjdXJyZW50LCBmYWxzZSk7Ci0KLSAgICAgIGRvCi0gICAgICB7Ci0gICAgICAgIGlmIChtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpID09IGV4dGVuZGVkVHlwZUlEKQotICAgICAgICAgIHJldHVybiBjdXJyZW50OwotICAgICAgfQotICAgICAgd2hpbGUgKERUTS5OVUxMCi0gICAgICAgICAgICAgIT0gKGN1cnJlbnQgPSBnZXROZXh0TmFtZXNwYWNlTm9kZShjb250ZXh0LCBjdXJyZW50LCBmYWxzZSkpKTsKLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBBbmNlc3RvciBhY2Nlc3MsIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIE5hbWVzcGFjZVRyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0KLSAgICAgIHJldHVybiAoY29udGV4dCA9PSBjdXJyZW50KQotICAgICAgICAgICAgID8gZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGNvbnRleHQsIHRydWUpCi0gICAgICAgICAgICAgOiBnZXROZXh0TmFtZXNwYWNlTm9kZShjb250ZXh0LCBjdXJyZW50LCB0cnVlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIGN1cnJlbnQgPSAoY29udGV4dCA9PSBjdXJyZW50KQotICAgICAgICAgICAgICAgID8gZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGNvbnRleHQsIHRydWUpCi0gICAgICAgICAgICAgICAgOiBnZXROZXh0TmFtZXNwYWNlTm9kZShjb250ZXh0LCBjdXJyZW50LCB0cnVlKTsKLQotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCkgPT0gZXh0ZW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICB9Ci0gICAgICB3aGlsZSAoRFRNLk5VTEwKLSAgICAgICAgICAgICAhPSAoY3VycmVudCA9IGdldE5leHROYW1lc3BhY2VOb2RlKGNvbnRleHQsIGN1cnJlbnQsIHRydWUpKSk7Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBQYXJlbnRUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgU28gdG8gdHJhdmVyc2UgCi0gICAgICogYW4gYXhpcywgdGhlIGZpcnN0IGZ1bmN0aW9uIG11c3QgYmUgdXNlZCB0byBnZXQgdGhlIGZpcnN0IG5vZGUuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCBuZWVkcyB0byBiZSBvdmVybG9hZGVkIG9ubHkgYnkgdGhvc2UgYXhpcyB0aGF0IHByb2Nlc3MKLSAgICAgKiB0aGUgc2VsZiBub2RlLiA8XHA+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSBwb2ludAotICAgICAqIHRoYXQgdGhlIHRyYXZlcnNhbCBzdGFydHMgZnJvbS4KLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9wYXJlbnQuZWxlbWVudEF0KGNvbnRleHQgJiBtX21hc2spIHwgbV9kdG1JZGVudDsKLSAgICB9Ci0gIAotICAgIC8qKgotICAgICAqIEJ5IHRoZSBuYXR1cmUgb2YgdGhlIHN0YXRlbGVzcyB0cmF2ZXJzYWwsIHRoZSBjb250ZXh0IG5vZGUgY2FuIG5vdCBiZQotICAgICAqIHJldHVybmVkIG9yIHRoZSBpdGVyYXRpb24gd2lsbCBnbyBpbnRvIGFuIGluZmluYXRlIGxvb3AuICBTbyB0byB0cmF2ZXJzZSAKLSAgICAgKiBhbiBheGlzLCB0aGUgZmlyc3QgZnVuY3Rpb24gbXVzdCBiZSB1c2VkIHRvIGdldCB0aGUgZmlyc3Qgbm9kZS4KLSAgICAgKgotICAgICAqIDxwPlRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIG92ZXJsb2FkZWQgb25seSBieSB0aG9zZSBheGlzIHRoYXQgcHJvY2VzcwotICAgICAqIHRoZSBzZWxmIG5vZGUuIDxccD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuIFRoaXMgaXMgdGhlIHBvaW50Ci0gICAgICogb2Ygb3JpZ2luIGZvciB0aGUgdHJhdmVyc2FsIC0tIGl0cyAicm9vdCBub2RlIiBvciBzdGFydGluZyBwb2ludC4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICBjdXJyZW50ID0gY3VycmVudCAmIG1fbWFzazsKLQotICAgICAgd2hpbGUgKE5VTEwgIT0gKGN1cnJlbnQgPSBtX3BhcmVudC5lbGVtZW50QXQoY3VycmVudCkpKQotICAgICAgewotICAgICAgICBpZiAobV9leHB0eXBlLmVsZW1lbnRBdChjdXJyZW50KSA9PSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICAgIAotCi0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgQW5jZXN0b3IgYWNjZXNzLCBpbiByZXZlcnNlIGRvY3VtZW50IG9yZGVyLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBQcmVjZWRpbmdUcmF2ZXJzZXIgZXh0ZW5kcyBEVE1BeGlzVHJhdmVyc2VyCi0gIHsKLQotICAgIC8qKgotICAgICAqIFRlbGwgaWYgdGhlIGN1cnJlbnQgaWRlbnRpdHkgaXMgYW4gYW5jZXN0b3Igb2YgdGhlIGNvbnRleHQgaWRlbnRpdHkuCi0gICAgICogVGhpcyBpcyBhbiBleHBlbnNpdmUgb3BlcmF0aW9uLCBtYWRlIHdvcnNlIGJ5IHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLgotICAgICAqIEJ1dCB0aGUgcHJlY2VkaW5nIGF4aXMgaXMgdXNlZCBmYWlybHkgaW5mcmVxdWVudGx5LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHRJZGVudCBUaGUgY29udGV4dCBub2RlIG9mIHRoZSBheGlzIHRyYXZlcnNhbC4KLSAgICAgKiBAcGFyYW0gY3VycmVudElkZW50IFRoZSBub2RlIGluIHF1ZXN0aW9uLgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY3VycmVudElkZW50IG5vZGUgaXMgYW4gYW5jZXN0b3Igb2YgY29udGV4dElkZW50LgotICAgICAqLwotICAgIHByb3RlY3RlZCBib29sZWFuIGlzQW5jZXN0b3IoaW50IGNvbnRleHRJZGVudCwgaW50IGN1cnJlbnRJZGVudCkKLSAgICB7Ci0KLSAgICAgIGZvciAoY29udGV4dElkZW50ID0gbV9wYXJlbnQuZWxlbWVudEF0KGNvbnRleHRJZGVudCk7IERUTS5OVUxMICE9IGNvbnRleHRJZGVudDsKLSAgICAgICAgICAgICAgY29udGV4dElkZW50ID0gbV9wYXJlbnQuZWxlbWVudEF0KGNvbnRleHRJZGVudCkpCi0gICAgICB7Ci0gICAgICAgIGlmIChjb250ZXh0SWRlbnQgPT0gY3VycmVudElkZW50KQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0KLSAgICAgIGludCBzdWJ0cmVlUm9vdElkZW50ID0gY29udGV4dCAmIG1fbWFzazsKLQotICAgICAgZm9yIChjdXJyZW50ID0gKGN1cnJlbnQgJiBtX21hc2spIC0gMTsgY3VycmVudCA+PSAwOyBjdXJyZW50LS0pCi0gICAgICB7Ci0gICAgICAgIGludCBleHB0eXBlID0gbV9leHB0eXBlLmVsZW1lbnRBdChjdXJyZW50KTsKLSAgICAgICAgc2hvcnQgdHlwZSA9IEV4cGFuZGVkTmFtZVRhYmxlLmdldFR5cGUoZXhwdHlwZSk7Ci0KLSAgICAgICAgaWYgKEFUVFJJQlVURV9OT0RFID09IHR5cGUgfHwgTkFNRVNQQUNFX05PREUgPT0gdHlwZQotICAgICAgICAgICAgICAgIHx8IGlzQW5jZXN0b3Ioc3VidHJlZVJvb3RJZGVudCwgY3VycmVudCkpCi0gICAgICAgICAgY29udGludWU7Ci0KLSAgICAgICAgcmV0dXJuIChjdXJyZW50IHwgbV9kdG1JZGVudCk7ICAvLyBtYWtlIGhhbmRsZS4KLSAgICAgIH0KLQotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4dGVuZGVkVHlwZUlEIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXh0ZW5kZWRUeXBlSUQpCi0gICAgewotCi0gICAgICBpbnQgc3VidHJlZVJvb3RJZGVudCA9IGNvbnRleHQgJiBtX21hc2s7Ci0KLSAgICAgIGZvciAoY3VycmVudCA9IChjdXJyZW50ICYgbV9tYXNrKSAtIDE7IGN1cnJlbnQgPj0gMDsgY3VycmVudC0tKQotICAgICAgewotICAgICAgICBpbnQgZXhwdHlwZSA9IG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCk7Ci0gICAgICAgIHNob3J0IHR5cGUgPSBFeHBhbmRlZE5hbWVUYWJsZS5nZXRUeXBlKGV4cHR5cGUpOwotCi0gICAgICAgIGlmIChleHB0eXBlICE9IGV4dGVuZGVkVHlwZUlECi0gICAgICAgICAgICAgICAgfHwgaXNBbmNlc3RvcihzdWJ0cmVlUm9vdElkZW50LCBjdXJyZW50KSkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFuZCB0aGUgUHJlY2VkaW5nIGF4aXMsCi0gICAqIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIFByZWNlZGluZ0FuZEFuY2VzdG9yVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50KQotICAgIHsKLQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBjb250ZXh0ICYgbV9tYXNrOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSAoY3VycmVudCAmIG1fbWFzaykgLSAxOyBjdXJyZW50ID49IDA7IGN1cnJlbnQtLSkKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpOwotICAgICAgICBzaG9ydCB0eXBlID0gRXhwYW5kZWROYW1lVGFibGUuZ2V0VHlwZShleHB0eXBlKTsKLQotICAgICAgICBpZiAoQVRUUklCVVRFX05PREUgPT0gdHlwZSB8fCBOQU1FU1BBQ0VfTk9ERSA9PSB0eXBlKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiAoY3VycmVudCB8IG1fZHRtSWRlbnQpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBjb250ZXh0ICYgbV9tYXNrOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSAoY3VycmVudCAmIG1fbWFzaykgLSAxOyBjdXJyZW50ID49IDA7IGN1cnJlbnQtLSkKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBtX2V4cHR5cGUuZWxlbWVudEF0KGN1cnJlbnQpOwotICAgICAgICBzaG9ydCB0eXBlID0gRXhwYW5kZWROYW1lVGFibGUuZ2V0VHlwZShleHB0eXBlKTsKLQotICAgICAgICBpZiAoZXhwdHlwZSAhPSBleHRlbmRlZFR5cGVJRCkKLSAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotCi0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW1wbGVtZW50cyB0cmF2ZXJzYWwgb2YgdGhlIEFuY2VzdG9yIGFjY2VzcywgaW4gcmV2ZXJzZSBkb2N1bWVudCBvcmRlci4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgUHJlY2VkaW5nU2libGluZ1RyYXZlcnNlciBleHRlbmRzIERUTUF4aXNUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICByZXR1cm4gZ2V0UHJldmlvdXNTaWJsaW5nKGN1cnJlbnQpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChjdXJyZW50ID0gZ2V0UHJldmlvdXNTaWJsaW5nKGN1cnJlbnQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZXhwdHlwZS5lbGVtZW50QXQoY3VycmVudCAmIG1fbWFzaykgPT0gZXh0ZW5kZWRUeXBlSUQpCi0gICAgICAgICAgcmV0dXJuIGN1cnJlbnQ7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBOVUxMOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbXBsZW1lbnRzIHRyYXZlcnNhbCBvZiB0aGUgU2VsZiBheGlzLgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBTZWxmVHJhdmVyc2VyIGV4dGVuZHMgRFRNQXhpc1RyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgVG8gc2VlIGlmCi0gICAgICogdGhlIHNlbGYgbm9kZSBzaG91bGQgYmUgcHJvY2Vzc2VkLCB1c2UgdGhpcyBmdW5jdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyB0cmF2ZXJzYWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIGluIHRoZSB0cmF2ZXJzYWwuCi0gICAgICovCi0gICAgcHVibGljIGludCBmaXJzdChpbnQgY29udGV4dCkKLSAgICB7Ci0gICAgICByZXR1cm4gY29udGV4dDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBCeSB0aGUgbmF0dXJlIG9mIHRoZSBzdGF0ZWxlc3MgdHJhdmVyc2FsLCB0aGUgY29udGV4dCBub2RlIGNhbiBub3QgYmUKLSAgICAgKiByZXR1cm5lZCBvciB0aGUgaXRlcmF0aW9uIHdpbGwgZ28gaW50byBhbiBpbmZpbmF0ZSBsb29wLiAgVG8gc2VlIGlmCi0gICAgICogdGhlIHNlbGYgbm9kZSBzaG91bGQgYmUgcHJvY2Vzc2VkLCB1c2UgdGhpcyBmdW5jdGlvbi4gIElmIHRoZSBjb250ZXh0Ci0gICAgICogbm9kZSBkb2VzIG5vdCBtYXRjaCB0aGUgZXh0ZW5kZWQgdHlwZSBJRCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybgotICAgICAqIGZhbHNlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICByZXR1cm4gKG1fZXhwdHlwZS5lbGVtZW50QXQoY29udGV4dCAmIG1fbWFzaykgPT0gZXh0ZW5kZWRUeXBlSUQpID8gY29udGV4dCA6IE5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIEFsd2F5cyByZXR1cm4gTlVMTCBmb3IgdGhpcyBheGlzLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQpCi0gICAgewotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgbWF0Y2hlZAotICAgICAqIGJ5IHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGV4dGVuZGVkVHlwZUlEIFRoZSBleHRlbmRlZCB0eXBlIElEIHRoYXQgbXVzdCBtYXRjaC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLCBvciBEVE0uTlVMTC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IG5leHQoaW50IGNvbnRleHQsIGludCBjdXJyZW50LCBpbnQgZXh0ZW5kZWRUeXBlSUQpCi0gICAgewotICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBBbmNlc3RvciBhY2Nlc3MsIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIEFsbEZyb21Sb290VHJhdmVyc2VyIGV4dGVuZHMgQWxsRnJvbU5vZGVUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSByb290LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0KQotICAgIHsKLSAgICAgIHJldHVybiBnZXREb2N1bWVudCgpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgcm9vdCBpZiBpdCBtYXRjaGVzIHRoZSBleHRlbmRlZCB0eXBlIElELgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICByZXR1cm4gKG1fZXhwdHlwZS5lbGVtZW50QXQoZ2V0RG9jdW1lbnQoKSAmIG1fbWFzaykgPT0gZXh0ZW5kZWRUeXBlSUQpCi0gICAgICAgICAgICAgPyBjb250ZXh0IDogbmV4dChjb250ZXh0LCBjb250ZXh0LCBleHRlbmRlZFR5cGVJRCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogVHJhdmVyc2UgdG8gdGhlIG5leHQgbm9kZSBhZnRlciB0aGUgY3VycmVudCBub2RlLgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgY3VycmVudCBub2RlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0KLSAgICAgIGludCBzdWJ0cmVlUm9vdElkZW50ID0gY29udGV4dCAmIG1fbWFzazsKLQotICAgICAgZm9yIChjdXJyZW50ID0gKGN1cnJlbnQgJiBtX21hc2spICsgMTsgOyBjdXJyZW50KyspCi0gICAgICB7Ci0gICAgICAgIGludCB0eXBlID0gX3R5cGUoY3VycmVudCk7ICAvLyBtYXkgY2FsbCBuZXh0Tm9kZSgpCi0KLSAgICAgICAgaWYgKHR5cGUgPT0gTlVMTCkKLSAgICAgICAgICByZXR1cm4gTlVMTDsKLQotICAgICAgICByZXR1cm4gKGN1cnJlbnQgfCBtX2R0bUlkZW50KTsgIC8vIG1ha2UgaGFuZGxlLgotICAgICAgfQotICAgIH0KLQotICAgIC8qKgotICAgICAqIFRyYXZlcnNlIHRvIHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGN1cnJlbnQgbm9kZSB0aGF0IGlzIG1hdGNoZWQKLSAgICAgKiBieSB0aGUgZXh0ZW5kZWQgdHlwZSBJRC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRpb24uCi0gICAgICogQHBhcmFtIGN1cnJlbnQgVGhlIGN1cnJlbnQgbm9kZSBvZiB0aGUgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBleHRlbmRlZFR5cGVJRCBUaGUgZXh0ZW5kZWQgdHlwZSBJRCB0aGF0IG11c3QgbWF0Y2guCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbiwgb3IgRFRNLk5VTEwuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCwgaW50IGV4dGVuZGVkVHlwZUlEKQotICAgIHsKLQotICAgICAgaW50IHN1YnRyZWVSb290SWRlbnQgPSBjb250ZXh0ICYgbV9tYXNrOwotCi0gICAgICBmb3IgKGN1cnJlbnQgPSAoY3VycmVudCAmIG1fbWFzaykgKyAxOyA7IGN1cnJlbnQrKykKLSAgICAgIHsKLSAgICAgICAgaW50IGV4cHR5cGUgPSBfZXhwdHlwZShjdXJyZW50KTsgIC8vIG1heSBjYWxsIG5leHROb2RlKCkKLQotICAgICAgICBpZiAoZXhwdHlwZSA9PSBOVUxMKQotICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgIGlmIChleHB0eXBlICE9IGV4dGVuZGVkVHlwZUlEKQotICAgICAgICAgIGNvbnRpbnVlOwotCi0gICAgICAgIHJldHVybiAoY3VycmVudCB8IG1fZHRtSWRlbnQpOyAgLy8gbWFrZSBoYW5kbGUuCi0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEltcGxlbWVudHMgdHJhdmVyc2FsIG9mIHRoZSBTZWxmIGF4aXMuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIFJvb3RUcmF2ZXJzZXIgZXh0ZW5kcyBBbGxGcm9tUm9vdFRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQWx3YXlzIHJldHVybiBOVUxMIGZvciB0aGlzIGF4aXMuCi0gICAgICovCi0gICAgcHVibGljIGludCBuZXh0KGludCBjb250ZXh0LCBpbnQgY3VycmVudCkKLSAgICB7Ci0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUcmF2ZXJzZSB0byB0aGUgbmV4dCBub2RlIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyBtYXRjaGVkCi0gICAgICogYnkgdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgaXRlcmF0aW9uLgotICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBjdXJyZW50IG5vZGUgb2YgdGhlIGl0ZXJhdGlvbi4KLSAgICAgKiBAcGFyYW0gZXh0ZW5kZWRUeXBlSUQgVGhlIGV4dGVuZGVkIHR5cGUgSUQgdGhhdCBtdXN0IG1hdGNoLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgbmV4dCBub2RlIGluIHRoZSBpdGVyYXRpb24sIG9yIERUTS5OVUxMLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgbmV4dChpbnQgY29udGV4dCwgaW50IGN1cnJlbnQsIGludCBleHRlbmRlZFR5cGVJRCkKLSAgICB7Ci0gICAgICByZXR1cm4gTlVMTDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQSBub24teHBhdGggYXhpcywgcmV0dXJucyBhbGwgbm9kZXMgdGhhdCBhcmVuJ3QgbmFtZXNwYWNlcyBvciBhdHRyaWJ1dGVzLAotICAgKiBmcm9tIGFuZCBpbmNsdWRpbmcgdGhlIHJvb3QuCi0gICAqLwotICBwcml2YXRlIGNsYXNzIERlc2NlbmRhbnRPclNlbGZGcm9tUm9vdFRyYXZlcnNlciBleHRlbmRzIERlc2NlbmRhbnRUcmF2ZXJzZXIKLSAgewotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBmaXJzdCBwb3RlbnRpYWwgaWRlbnRpdHkgdGhhdCBjYW4gYmUgcmV0dXJuZWQsIHdoaWNoIGlzIHRoZSBheGlzIAotICAgICAqIHJvb3QgY29udGV4dCBpbiB0aGlzIGNhc2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgb2YgdGhlIHJvb3QgY29udGV4dCBvZiB0aGUgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgaWRlbnRpdHkgYXJndW1lbnQuCi0gICAgICovCi0gICAgcHJvdGVjdGVkIGludCBnZXRGaXJzdFBvdGVudGlhbChpbnQgaWRlbnRpdHkpCi0gICAgewotICAgICAgcmV0dXJuIGlkZW50aXR5OwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCB0aGUgZmlyc3QgcG90ZW50aWFsIGlkZW50aXR5IHRoYXQgY2FuIGJlIHJldHVybmVkLgotICAgICAqIEBwYXJhbSBoYW5kbGUgaGFuZGxlIHRvIHRoZSByb290IGNvbnRleHQuCi0gICAgICogQHJldHVybiBpZGVudGl0eSBvZiB0aGUgcm9vdCBvZiB0aGUgc3VidHJlZS4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldFN1YnRyZWVSb290KGludCBoYW5kbGUpCi0gICAgewotICAgICAgcmV0dXJuIGdldERvY3VtZW50KCkgJiBtX21hc2s7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSByb290LgotICAgICAqCi0gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgbm9kZSBvZiB0aGlzIHRyYXZlcnNhbC4KLSAgICAgKgotICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHRyYXZlcnNhbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGZpcnN0KGludCBjb250ZXh0KQotICAgIHsKLSAgICAgIHJldHVybiBnZXREb2N1bWVudCgpOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIEEgbm9uLXhwYXRoIGF4aXMsIHJldHVybnMgYWxsIG5vZGVzIHRoYXQgYXJlbid0IG5hbWVzcGFjZXMgb3IgYXR0cmlidXRlcywKLSAgICogZnJvbSBidXQgbm90IGluY2x1ZGluZyB0aGUgcm9vdC4KLSAgICovCi0gIHByaXZhdGUgY2xhc3MgRGVzY2VuZGFudEZyb21Sb290VHJhdmVyc2VyIGV4dGVuZHMgRGVzY2VuZGFudFRyYXZlcnNlcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGZpcnN0IHBvdGVudGlhbCBpZGVudGl0eSB0aGF0IGNhbiBiZSByZXR1cm5lZCwgd2hpY2ggaXMgdGhlIGF4aXMgCi0gICAgICogcm9vdCBjb250ZXh0IGluIHRoaXMgY2FzZS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgbm9kZSBpZGVudGl0eSBvZiB0aGUgcm9vdCBjb250ZXh0IG9mIHRoZSB0cmF2ZXJzYWwuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBpZGVudGl0eSBhcmd1bWVudC4KLSAgICAgKi8KLSAgICBwcm90ZWN0ZWQgaW50IGdldEZpcnN0UG90ZW50aWFsKGludCBpZGVudGl0eSkKLSAgICB7Ci0gICAgICByZXR1cm4gX2ZpcnN0Y2goMCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBmaXJzdCBwb3RlbnRpYWwgaWRlbnRpdHkgdGhhdCBjYW4gYmUgcmV0dXJuZWQuCi0gICAgICogQHBhcmFtIGhhbmRsZSBoYW5kbGUgdG8gdGhlIHJvb3QgY29udGV4dC4KLSAgICAgKiBAcmV0dXJuIGlkZW50aXR5IG9mIHRoZSByb290IG9mIHRoZSBzdWJ0cmVlLgotICAgICAqLwotICAgIHByb3RlY3RlZCBpbnQgZ2V0U3VidHJlZVJvb3QoaW50IGhhbmRsZSkKLSAgICB7Ci0gICAgICByZXR1cm4gMDsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIHJvb3QuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgdHJhdmVyc2FsLgotICAgICAqCi0gICAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgdHJhdmVyc2FsLgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZmlyc3QoaW50IGNvbnRleHQpCi0gICAgewotICAgICAgcmV0dXJuIF9maXJzdGNoKDApIHwgbV9kdG1JZGVudDsKLSAgICB9Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNRG9jdW1lbnRJbXBsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1Eb2N1bWVudEltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTBjYTViNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1Eb2N1bWVudEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI0MzEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotLy9pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkNodW5rZWRJbnRBcnJheTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmdGYWN0b3J5OwotCi0vKioKLSAqIFRoaXMgaXMgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBEVE0gZG9jdW1lbnQgaW50ZXJmYWNlLiAgSXQgcmVjZWl2ZXMKLSAqIHJlcXVlc3RzIGZyb20gYW4gWE1MIGNvbnRlbnQgaGFuZGxlciBzaW1pbGFyIHRvIHRoYXQgb2YgYW4gWE1MIERPTSBvciBTQVggcGFyc2VyCi0gKiB0byBzdG9yZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSB4bWwgZG9jdW1lbnQgaW4gYW4gYXJyYXkgYmFzZWQKLSAqIGR0bSB0YWJsZSBzdHJ1Y3R1cmUuICBUaGlzIGluZm9ybXRpb24gaXMgdXNlZCBsYXRlciBmb3IgZG9jdW1lbnQgbmF2aWdhdGlvbiwKLSAqIHF1ZXJ5LCBhbmQgU0FYIGV2ZW50IGRpc3BhdGNoIGZ1bmN0aW9ucy4gVGhlIERUTSBjYW4gYWxzbyBiZSB1c2VkIGRpcmVjdGx5IGFzIGEKLSAqIGRvY3VtZW50IGNvbXBvc2l0aW9uIG1vZGVsIGZvciBhbiBhcHBsaWNhdGlvbi4gIFRoZSByZXF1ZXN0cyByZWNlaXZlZCBhcmU6Ci0gKiA8dWw+Ci0gKiA8bGk+aW5pdGlhdGluZyBEVE0gdG8gc2V0IHRoZSBkb2MgaGFuZGxlPC9saT4KLSAqIDxsaT5yZXNldHRpbmcgRFRNIGZvciBkYXRhIHN0cnVjdHVyZSByZXVzZTwvbGk+Ci0gKiA8bGk+aGludGluZyB0aGUgZW5kIG9mIGRvY3VtZW50IHRvIGFkanVzdCB0aGUgZW5kIG9mIGRhdGEgc3RydWN0dXJlIHBvaW50ZXJzPC9saT4KLSAqIDxsaT5jcmVhdGVub2RlcyAoZWxlbWVudCwgY29tbWVudCwgdGV4dCwgYXR0cmlidXRlLCAuLi4uKTwvbGk+Ci0gKiA8bGk+aGludGluZyB0aGUgZW5kIG9mIGFuIGVsZW1lbnQgdG8gcGF0Y2ggcGFyZW50IGFuZCBzaWJsaW5nczxsaT4KLSAqIDxsaT5zZXR0aW5nIGFwcGxpY2F0aW9uIHByb3ZpZGVkIHN5bWJvbCBuYW1lIHN0cmluZ3Bvb2wgZGF0YSBzdHJ1Y3R1cmVzPC9saT4KLSAqIDwvdWw+Ci0gKiA8cD5TdGF0ZTogSW4gcHJvZ3Jlc3MhITwvcD4KLSAqCi0gKiAlUkVWSUVXJSBJIF90aGlua18gdGhlIFNBWCBjb252ZW50aW9uIGlzIHRoYXQgIm5vIG5hbWVzcGFjZSIgaXMgZXhwcmVzc2VkCi0gKiBhcyAiIiByYXRoZXIgdGhhbiBhcyBudWxsICh3aGljaCBpcyB0aGUgRE9NJ3MgY29udmVudGlvbikuIFdoYXQgc2hvdWxkCi0gKiBEVE0gZXhwZWN0PyBXaGF0IHNob3VsZCBpdCBkbyB3aXRoIHRoZSBvdGhlcj8KLSAqCi0gKiA8cD5PcmlnaW46IHRoZSBpbXBsZW1lbnRpb24gaXMgYSBjb21wb3NpdGUgbG9naWMgYmFzZWQgb24gdGhlIERUTSBvZiBYYWxhbkoxIGFuZAotICogICAgIERvY0ltcGwsIERvY3VtZW50SW1wbCwgRWxlbWVudEltcGwsIFRleHRJbXBsLCBldGMuIG9mIFhhbGFuSjI8L3A+Ci0gKi8KLXB1YmxpYyBjbGFzcyBEVE1Eb2N1bWVudEltcGwKLWltcGxlbWVudHMgRFRNLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciwgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyCi17Ci0KLSAgICAgICAgLy8gTnVtYmVyIG9mIGxvd2VyIGJpdHMgdXNlZCB0byByZXByZXNlbnQgbm9kZSBpbmRleC4KLSAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIERPQ0hBTkRMRV9TSElGVCA9IDIyOwotICAgICAgICAvLyBNYXNrcyB0aGUgbG93ZXIgb3JkZXIgb2Ygbm9kZSBoYW5kbGUuCi0gICAgICAgIC8vIFNhbWUgYXMge0BsaW5rIERUTUNvbnN0cnVjdG9yLklERU5UX05PREVfREVGQVVMVH0KLSAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTk9ERUhBTkRMRV9NQVNLID0gKDEgPDwgKERPQ0hBTkRMRV9TSElGVCArIDEpKSAtIDE7Ci0gICAgICAgIC8vIE1hc2tzIHRoZSBoaWdoZXIgb3JkZXIgRG9jdW1lbnQgaGFuZGxlCi0gICAgICAgIC8vIFNhbWUgYXMge0BsaW5rIERUTUNvbnN0cnVjdG9yLklERU5UX0RPQ19ERUZBVUxUfQotICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBET0NIQU5ETEVfTUFTSyA9IC0xIC0gTk9ERUhBTkRMRV9NQVNLOwotCi0gICAgICAgIGludCBtX2RvY0hhbmRsZSA9IE5VTEw7CQkgLy8gbWFza2VkIGRvY3VtZW50IGhhbmRsZSBmb3IgdGhpcyBkdG0gZG9jdW1lbnQKLSAgICAgICAgaW50IG1fZG9jRWxlbWVudCA9IE5VTEw7CSAvLyBub2RlSGFuZGxlIHRvIHRoZSByb290IG9mIHRoZSBhY3R1YWwgZHRtIGRvYyBjb250ZW50Ci0KLSAgICAgICAgLy8gQ29udGV4dCBmb3IgcGFyc2UtYW5kLWFwcGVuZCBvcGVyYXRpb25zCi0gICAgICAgIGludCBjdXJyZW50UGFyZW50ID0gMDsJCQkvLyBjdXJyZW50IHBhcmVudCAtIGRlZmF1bHQgaXMgZG9jdW1lbnQgcm9vdAotICAgICAgICBpbnQgcHJldmlvdXNTaWJsaW5nID0gMDsJCS8vIHByZXZpb3VzIHNpYmxpbmcgLSBubyBwcmV2aW91cyBzaWJsaW5nCi0gICAgICAgIHByb3RlY3RlZCBpbnQgbV9jdXJyZW50Tm9kZSA9IC0xOwkJLy8gY3VycmVudCBub2RlCi0KLSAgICAgICAgLy8gVGhlIHRyZWUgdW5kZXIgY29uc3RydWN0aW9uIGNhbiBpdHNlbGYgYmUgdXNlZCBhcwotICAgICAgICAvLyB0aGUgZWxlbWVudCBzdGFjaywgc28gbV9lbGVtU3RhY2sgaXNuJ3QgbmVlZGVkLgotICAgICAgICAvL3Byb3RlY3RlZCBTdGFjayBtX2VsZW1TdGFjayA9IG5ldyBTdGFjaygpOwkgLy8gZWxlbWVudCBzdGFjawotCi0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSBmYWxzZTsKLSAgICAgICAgLy8gTG9jYWwgY2FjaGUgZm9yIHJlY29yZC1hdC1hLXRpbWUgZmV0Y2gKLSAgICAgICAgaW50IGdvdHNsb3RbXSA9IG5ldyBpbnRbNF07Ci0KLSAgICAgICAgLy8gZW5kRG9jdW1lbnQgcmVjaWV2ZWQ/Ci0gICAgICAgIHByaXZhdGUgYm9vbGVhbiBkb25lID0gZmFsc2U7Ci0gICAgICAgIGJvb2xlYW4gbV9pc0Vycm9yID0gZmFsc2U7Ci0KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgICAgICAgLyoqIFRoZSBkb2N1bWVudCBiYXNlIFVSSS4gKi8KLSAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBtX2RvY3VtZW50QmFzZVVSSTsKLQotICAvKiogSWYgd2UncmUgYnVpbGRpbmcgdGhlIG1vZGVsIGluY3JlbWVudGFsbHkgb24gZGVtYW5kLCB3ZSBuZWVkIHRvCi0gICAqIGJlIGFibGUgdG8gdGVsbCB0aGUgc291cmNlIHdoZW4gdG8gc2VuZCB1cyBtb3JlIGRhdGEuCi0gICAqCi0gICAqIE5vdGUgdGhhdCBpZiB0aGlzIGhhcyBub3QgYmVlbiBzZXQsIGFuZCB5b3UgYXR0ZW1wdCB0byByZWFkIGFoZWFkCi0gICAqIG9mIHRoZSBjdXJyZW50IGJ1aWxkIHBvaW50LCB3ZSdsbCBwcm9iYWJseSB0aHJvdyBhIG51bGwtcG9pbnRlcgotICAgKiBleGNlcHRpb24uIFdlIGNvdWxkIHRyeSB0byB3YWl0LWFuZC1yZXRyeSBpbnN0ZWFkLCBhcyBhIHZlcnkgcG9vcgotICAgKiBmYWxsYmFjaywgYnV0IHRoYXQgaGFzIGFsbCB0aGUga25vd24gcHJvYmxlbXMgd2l0aCBtdWx0aXRocmVhZGluZwotICAgKiBvbiBtdWx0aXByb2Nlc3NvcnMgYW5kIHdlIERvbid0IFdhbnQgdG8gR28gVGhlcmUuCi0gICAqCi0gICAqIEBzZWUgc2V0SW5jcmVtZW50YWxTQVhTb3VyY2UKLSAgICovCi0gIHByaXZhdGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgbV9pbmNyU0FYU291cmNlPW51bGw7Ci0KLQotICAgICAgICAvLyA9PT09PT09PT0gRFRNIGRhdGEgc3RydWN0dXJlIGRlY2xhcmF0aW9ucy4gPT09PT09PT09PT09PT0KLQotICAgICAgICAvLyBub2RlcyBhcnJheTogaW50ZWdlciBhcnJheSBibG9ja3MgdG8gaG9sZCB0aGUgZmlyc3QgbGV2ZWwgcmVmZXJlbmNlIG9mIHRoZSBub2RlcywKLSAgICAgICAgLy8gZWFjaCByZWZlcmVuY2Ugc2xvdCBpcyBhZGRyZXNzZWQgYnkgYSBub2RlSGFuZGxlIGluZGV4IHZhbHVlLgotICAgICAgICAvLyBBc3N1bWVzIGluZGljZXMgYXJlIG5vdCBsYXJnZXIgdGhhbiB7QGxpbmsgTk9ERUhBTkRMRV9NQVNLfQotICAgICAgICAvLyAoe0BsaW5rIERPQ0hBTkRMRV9TSElGVH0gYml0cykuCi0gICAgICAgIENodW5rZWRJbnRBcnJheSBub2RlcyA9IG5ldyBDaHVua2VkSW50QXJyYXkoNCk7Ci0KLSAgICAgICAgLy8gdGV4dC9jb21tZW50IHRhYmxlOiBzdHJpbmcgYnVmZmVyIHRvIGhvbGQgdGhlIHRleHQgc3RyaW5nIHZhbHVlcyBvZiB0aGUgZG9jdW1lbnQsCi0gICAgICAgIC8vIGVhY2ggb2Ygd2hpY2ggaXMgYWRkcmVzc2VkIGJ5IHRoZSBhYnNvbHV0ZSBvZmZzZXQgYW5kIGxlbmd0aCBpbiB0aGUgYnVmZmVyCi0gICAgICAgIHByaXZhdGUgRmFzdFN0cmluZ0J1ZmZlciBtX2NoYXIgPSBuZXcgRmFzdFN0cmluZ0J1ZmZlcigpOwotICAgICAgICAvLyBTdGFydCBvZiBzdHJpbmcgY3VycmVudGx5IGJlaW5nIGFjY3VtdWxhdGVkIGludG8gbV9jaGFyOwotICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB0aGUgc3RyaW5nIG1heSBiZSBhcHBlbmRlZCBpbiBzZXZlcmFsIGNodW5rcy4KLSAgICAgICAgcHJpdmF0ZSBpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQ9MDsKLQotICAgICAgICAvLyAlVEJEJSBJTklUSUFMSVpBVElPTi9TVEFSVFVQIElTU1VFUwotICAgICAgICAvLyAtLSBTaG91bGQgd2UgcmVhbGx5IGJlIGNyZWF0aW5nIHRoZXNlLCBvciBzaG91bGQgdGhleSBiZQotICAgICAgICAvLyBwYXNzZWQgaW4gZnJvbSBvdXRzaWRlPyBTY290dCB3YW50IHRvIGJlIGFibGUgdG8gc2hhcmUKLSAgICAgICAgLy8gcG9vbHMgYWNyb3NzIG11bHRpcGxlIGRvY3VtZW50cywgc28gc2V0dGluZyB0aGVtIGhlcmUgaXMKLSAgICAgICAgLy8gcHJvYmFibHkgbm90IHRoZSByaWdodCBkZWZhdWx0LgotICAgICAgICBwcml2YXRlIERUTVN0cmluZ1Bvb2wgbV9sb2NhbE5hbWVzID0gbmV3IERUTVN0cmluZ1Bvb2woKTsKLSAgICAgICAgcHJpdmF0ZSBEVE1TdHJpbmdQb29sIG1fbnNOYW1lcyA9IG5ldyBEVE1TdHJpbmdQb29sKCk7Ci0gICAgICAgIHByaXZhdGUgRFRNU3RyaW5nUG9vbCBtX3ByZWZpeE5hbWVzID0gbmV3IERUTVN0cmluZ1Bvb2woKTsKLQotICAgICAgICAvLyAlVEJEJSBJZiB3ZSB1c2UgdGhlIGN1cnJlbnQgRXhwYW5kZWROYW1lVGFibGUgbWFwcGVyLCBpdAotICAgICAgICAvLyBuZWVkcyB0byBiZSBib3VuZCB0byB0aGUgTlMgYW5kIGxvY2FsIG5hbWUgcG9vbHMuIFdoaWNoCi0gICAgICAgIC8vIG1lYW5zIGl0IG5lZWRzIHRvIGF0dGFjaCB0byB0aGVtIEFGVEVSIHdlJ3ZlIHJlc29sdmVkIHRoZWlyCi0gICAgICAgIC8vIHN0YXJ0dXAuIE9yIGl0IG5lZWRzIHRvIGF0dGFjaCB0byB0aGlzIGRvY3VtZW50IGFuZAotICAgICAgICAvLyByZXRyaWV2ZSB0aGVtIGVhY2ggdGltZS4gT3IgdGhpcyBuZWVkcyB0byBiZQotICAgICAgICAvLyBhbiBpbnRlcmZhY2UgX2ltcGxlbWVudGVkXyBieSB0aGlzIGNsYXNzLi4uIHdoaWNoIG1pZ2h0IGJlIHNpbXBsZXN0IQotICAgICAgICBwcml2YXRlIEV4cGFuZGVkTmFtZVRhYmxlIG1fZXhwYW5kZWROYW1lcz0KLSAgICAgICAgICAgICAgICBuZXcgRXhwYW5kZWROYW1lVGFibGUobV9sb2NhbE5hbWVzLG1fbnNOYW1lcyk7Ci0KLSAgICAgICAgcHJpdmF0ZSBYTUxTdHJpbmdGYWN0b3J5IG1feHNmOwotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIENvbnN0cnVjdCBhIERUTS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIGRvY3VtZW50TnVtYmVyIHRoZSBJRCBudW1iZXIgYXNzaWduZWQgdG8gdGhpcyBkb2N1bWVudC4KLSAgICAgICAgICogSXQgd2lsbCBiZSBzaGlmdGVkIHVwIGludG8gdGhlIGhpZ2ggYml0cyBhbmQgcmV0dXJuZWQgYXMgcGFydCBvZgotICAgICAgICAgKiBhbGwgbm9kZSBJRCBudW1iZXJzLCBzbyB0aG9zZSBJRHMgaW5kaWNhdGUgd2hpY2ggZG9jdW1lbnQgdGhleQotICAgICAgICAgKiBjYW1lIGZyb20gYXMgd2VsbCBhcyBhIGxvY2F0aW9uIHdpdGhpbiB0aGUgZG9jdW1lbnQuIEl0IGlzIHRoZQotICAgICAgICAgKiBEVE1NYW5hZ2VyJ3MgcmVzcG9uc2liaWxpdHkgdG8gYXNzaWduIGEgdW5pcXVlIG51bWJlciB0byBlYWNoCi0gICAgICAgICAqIGRvY3VtZW50LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIERUTURvY3VtZW50SW1wbChEVE1NYW5hZ2VyIG1nciwgaW50IGRvY3VtZW50TnVtYmVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MU3RyaW5nRmFjdG9yeSB4c3RyaW5nZmFjdG9yeSl7Ci0gICAgICAgICAgICAgICAgaW5pdERvY3VtZW50KGRvY3VtZW50TnVtYmVyKTsJIC8vIGNsZWFyIG5vZGVzIGFuZCBkb2N1bWVudCBoYW5kbGUKLSAgICAgICAgICAgICAgICBtX3hzZiA9IHhzdHJpbmdmYWN0b3J5OwotICAgICAgICB9Ci0KLSAgLyoqIEJpbmQgYSBJbmNyZW1lbnRhbFNBWFNvdXJjZSB0byB0aGlzIERUTS4gSWYgd2UgZGlzY292ZXIgd2UgbmVlZCBub2RlcwotICAgKiB0aGF0IGhhdmUgbm90IHlldCBiZWVuIGJ1aWx0LCB3ZSB3aWxsIGFzayB0aGlzIG9iamVjdCB0byBzZW5kIHVzIG1vcmUKLSAgICogZXZlbnRzLCBhbmQgaXQgd2lsbCBtYW5hZ2UgaW50ZXJhY3Rpb25zIHdpdGggaXRzIGRhdGEgc291cmNlcy4KLSAgICoKLSAgICogTm90ZSB0aGF0IHdlIGRvIG5vdCBhY3R1YWxseSBidWlsZCB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UsIHNpbmNlIHdlIGRvbid0Ci0gICAqIGtub3cgd2hhdCBzb3VyY2UgaXQncyByZWFkaW5nIGZyb20sIHdoYXQgdGhyZWFkIHRoYXQgc291cmNlIHdpbGwgcnVuIGluLAotICAgKiBvciB3aGVuIGl0IHdpbGwgcnVuLgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSB0aGF0IHdlIHdhbnQgdG8gcmVjaWV2ZSBldmVudHMgZnJvbQotICAgKiBvbiBkZW1hbmQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbmNyZW1lbnRhbFNBWFNvdXJjZShJbmNyZW1lbnRhbFNBWFNvdXJjZSBzb3VyY2UpCi0gIHsKLSAgICBtX2luY3JTQVhTb3VyY2U9c291cmNlOwotCi0gICAgLy8gRXN0YWJsaXNoIFNBWC1zdHJlYW0gbGluayBzbyB3ZSBjYW4gcmVjZWl2ZSB0aGUgcmVxdWVzdGVkIGRhdGEKLSAgICBzb3VyY2Uuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgc291cmNlLnNldExleGljYWxIYW5kbGVyKHRoaXMpOwotCi0gICAgLy8gQXJlIHRoZSBmb2xsb3dpbmcgcmVhbGx5IG5lZWRlZD8gSW5jcmVtZW50YWxTQVhTb3VyY2UgZG9lc24ndCB5ZXQKLSAgICAvLyBzdXBwb3J0IHRoZW0sIGFuZCB0aGV5J3JlIG1vc3RseSBuby1vcHMgaGVyZS4uLgotICAgIC8vc291cmNlLnNldEVycm9ySGFuZGxlcih0aGlzKTsKLSAgICAvL3NvdXJjZS5zZXREVERIYW5kbGVyKHRoaXMpOwotICAgIC8vc291cmNlLnNldERlY2xIYW5kbGVyKHRoaXMpOwotICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFdyYXBwZXIgZm9yIENodW5rZWRJbnRBcnJheS5hcHBlbmQsIHRvIGF1dG9tYXRpY2FsbHkgdXBkYXRlIHRoZQotICAgICAgICAgKiBwcmV2aW91cyBzaWJsaW5nJ3MgIm5leHQiIHJlZmVyZW5jZSAoaWYgbmVjZXNzYXJ5KSBhbmQgcGVyaW9kaWNhbGx5Ci0gICAgICAgICAqIHdha2UgYSByZWFkZXIgd2hvIG1heSBoYXZlIGVuY291bnRlcmVkIGluY29tcGxldGUgZGF0YSBhbmQgZW50ZXJlZAotICAgICAgICAgKiBhIHdhaXQgc3RhdGUuCi0gICAgICAgICAqIEBwYXJhbSB3MCBpbnQgQXMgaW4gQ2h1bmtlZEludEFycmF5LmFwcGVuZAotICAgICAgICAgKiBAcGFyYW0gdzEgaW50IEFzIGluIENodW5rZWRJbnRBcnJheS5hcHBlbmQKLSAgICAgICAgICogQHBhcmFtIHcyIGludCBBcyBpbiBDaHVua2VkSW50QXJyYXkuYXBwZW5kCi0gICAgICAgICAqIEBwYXJhbSB3MyBpbnQgQXMgaW4gQ2h1bmtlZEludEFycmF5LmFwcGVuZAotICAgICAgICAgKiBAcmV0dXJuIGludCBBcyBpbiBDaHVua2VkSW50QXJyYXkuYXBwZW5kCi0gICAgICAgICAqIEBzZWUgQ2h1bmtlZEludEFycmF5LmFwcGVuZAotICAgICAgICAgKi8KLSAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgYXBwZW5kTm9kZShpbnQgdzAsIGludCB3MSwgaW50IHcyLCBpbnQgdzMpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBBIGRlY2VudCBjb21waWxlciBtYXkgaW5saW5lIHRoaXMuCi0gICAgICAgICAgICAgICAgaW50IHNsb3RudW1iZXIgPSBub2Rlcy5hcHBlbmRTbG90KHcwLCB3MSwgdzIsIHczKTsKLQotICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKHNsb3RudW1iZXIrIjogIit3MCsiICIrdzErIiAiK3cyKyIgIit3Myk7Ci0KLSAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nV2FzUGFyZW50KQotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMud3JpdGVFbnRyeShwcmV2aW91c1NpYmxpbmcsMixzbG90bnVtYmVyKTsKLQotICAgICAgICAgICAgICAgIHByZXZpb3VzU2libGluZ1dhc1BhcmVudCA9IGZhbHNlOwkvLyBTZXQgdGhlIGRlZmF1bHQ7IGVuZEVsZW1lbnQgb3ZlcnJpZGVzCi0KLSAgICAgICAgICAgICAgICByZXR1cm4gc2xvdG51bWJlcjsKLSAgICAgICAgfQotCi0gICAgICAgIC8vID09PT09PT09PSBEVE0gSW1wbGVtZW50YXRpb24gQ29udHJvbCBGdW5jdGlvbnMuID09PT09PT09PT09PT09Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBhbiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgZmVhdHVyZS4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqICVSRVZJRVclIERvIHdlIHJlYWxseSBleHBlY3QgdG8gc2V0IGZlYXR1cmVzIG9uIERUTXM/Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBmZWF0dXJlSWQgQSBmZWF0dXJlIFVSTC4KLSAgICAgICAgICogQHBhcmFtIHN0YXRlIHRydWUgaWYgdGhpcyBmZWF0dXJlIHNob3VsZCBiZSBvbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgc2V0RmVhdHVyZShTdHJpbmcgZmVhdHVyZUlkLCBib29sZWFuIHN0YXRlKSB7fTsKLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IGEgcmVmZXJlbmNlIHBvaW50ZXIgdG8gdGhlIGVsZW1lbnQgbmFtZSBzeW1ib2wgdGFibGUuCi0gICAgICAgICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJlYWxseSBiZSBQdWJsaWM/IENoYW5naW5nIGl0IHdoaWxlCi0gICAgICAgICAqIERUTSBpcyBpbiB1c2Ugd291bGQgYmUgYSBkaXNhc3Rlci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHBvb2xSZWYgRFRNU3RyaW5nUG9vbCByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YgdGFibGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbE5hbWVUYWJsZShEVE1TdHJpbmdQb29sIHBvb2xSZWYpIHsKLSAgICAgICAgICAgICAgICBtX2xvY2FsTmFtZXMgPSBwb29sUmVmOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBlbGVtZW50IG5hbWUgc3ltYm9sIHRhYmxlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIERUTVN0cmluZ1Bvb2wgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIHRhYmxlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIERUTVN0cmluZ1Bvb2wgZ2V0TG9jYWxOYW1lVGFibGUoKSB7Ci0gICAgICAgICAgICAgICAgIHJldHVybiBtX2xvY2FsTmFtZXM7Ci0gICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBuYW1lc3BhY2UgVVJJIHN5bWJvbCB0YWJsZS4KLSAgICAgICAgICogJVJFVklFVyUgU2hvdWxkIHRoaXMgcmVhbGx5IGJlIFB1YmxpYz8gQ2hhbmdpbmcgaXQgd2hpbGUKLSAgICAgICAgICogRFRNIGlzIGluIHVzZSB3b3VsZCBiZSBhIGRpc2FzdGVyLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gcG9vbFJlZiBEVE1TdHJpbmdQb29sIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiB0YWJsZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyB2b2lkIHNldE5zTmFtZVRhYmxlKERUTVN0cmluZ1Bvb2wgcG9vbFJlZikgewotICAgICAgICAgICAgICAgIG1fbnNOYW1lcyA9IHBvb2xSZWY7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IGEgcmVmZXJlbmNlIHBvaW50ZXIgdG8gdGhlIG5hbWVzcGFjZSBVUkkgc3ltYm9sIHRhYmxlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIERUTVN0cmluZ1Bvb2wgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIHRhYmxlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIERUTVN0cmluZ1Bvb2wgZ2V0TnNOYW1lVGFibGUoKSB7Ci0gICAgICAgICAgICAgICAgIHJldHVybiBtX25zTmFtZXM7Ci0gICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFNldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBwcmVmaXggbmFtZSBzeW1ib2wgdGFibGUuCi0gICAgICAgICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJlYWxseSBiZSBQdWJsaWM/IENoYW5naW5nIGl0IHdoaWxlCi0gICAgICAgICAqIERUTSBpcyBpbiB1c2Ugd291bGQgYmUgYSBkaXNhc3Rlci4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHBvb2xSZWYgRFRNU3RyaW5nUG9vbCByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YgdGFibGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXRQcmVmaXhOYW1lVGFibGUoRFRNU3RyaW5nUG9vbCBwb29sUmVmKSB7Ci0gICAgICAgICAgICAgICAgbV9wcmVmaXhOYW1lcyA9IHBvb2xSZWY7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IGEgcmVmZXJlbmNlIHBvaW50ZXIgdG8gdGhlIHByZWZpeCBuYW1lIHN5bWJvbCB0YWJsZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBEVE1TdHJpbmdQb29sIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiB0YWJsZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBEVE1TdHJpbmdQb29sIGdldFByZWZpeE5hbWVUYWJsZSgpIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbV9wcmVmaXhOYW1lczsKLSAgICAgICAgfQotCi0gICAgICAgICAvKioKLSAgICAgICAgICAqIFNldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBjb250ZW50LXRleHQgcmVwb3NpdG9yeQotICAgICAgICAgICoKLSAgICAgICAgICAqIEBwYXJhbSBidWZmZXJSZWYgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YKLSAgICAgICAgICAqIGJ1ZmZlcgotICAgICAgICAgICovCi0gICAgICAgICB2b2lkIHNldENvbnRlbnRCdWZmZXIoRmFzdFN0cmluZ0J1ZmZlciBidWZmZXIpIHsKLSAgICAgICAgICAgICAgICAgbV9jaGFyID0gYnVmZmVyOwotICAgICAgICAgfQotCi0gICAgICAgICAvKioKLSAgICAgICAgICAqIEdldCBhIHJlZmVyZW5jZSBwb2ludGVyIHRvIHRoZSBjb250ZW50LXRleHQgcmVwb3NpdG9yeQotICAgICAgICAgICoKLSAgICAgICAgICAqIEByZXR1cm4gRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YgYnVmZmVyCi0gICAgICAgICAgKi8KLSAgICAgICAgIEZhc3RTdHJpbmdCdWZmZXIgZ2V0Q29udGVudEJ1ZmZlcigpIHsKLSAgICAgICAgICAgICAgICAgcmV0dXJuIG1fY2hhcjsKLSAgICAgICAgIH0KLQotICAvKiogZ2V0Q29udGVudEhhbmRsZXIgcmV0dXJucyAib3VyIFNBWCBidWlsZGVyIiAtLSB0aGUgdGhpbmcgdGhhdAotICAgKiBzb21lb25lIGVsc2Ugc2hvdWxkIHNlbmQgU0FYIGV2ZW50cyB0byBpbiBvcmRlciB0byBleHRlbmQgdGhpcwotICAgKiBEVE0gbW9kZWwuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXZlbnRzLAotICAgKiAidGhpcyIgaWYgdGhlIERUTSBvYmplY3QgaGFzIGEgYnVpbHQtaW4gU0FYIENvbnRlbnRIYW5kbGVyLAotICAgKiB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgaWYgd2UncmUgYm91bmQgdG8gb25lIGFuZCBzaG91bGQgcmVjZWl2ZQotICAgKiB0aGUgU0FYIHN0cmVhbSB2aWEgaXQgZm9yIGluY3JlbWVudGFsIGJ1aWxkIHB1cnBvc2VzLi4uCi0gICAqICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpCi0gIHsKLSAgICBpZiAobV9pbmNyU0FYU291cmNlIGluc3RhbmNlb2YgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKQotICAgICAgcmV0dXJuIChDb250ZW50SGFuZGxlcikgbV9pbmNyU0FYU291cmNlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIGxleGljYWwgaGFuZGxlci4KLSAgICoKLSAgICogJVJFVklFVyUgU2hvdWxkIHRoaXMgcmV0dXJuIG51bGwgaWYgY29uc3RydXRpb24gYWxyZWFkeSBkb25lL2JlZ3VuPwotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gbGV4aWNhbCBTQVggZXZlbnRzLAotICAgKiAidGhpcyIgaWYgdGhlIERUTSBvYmplY3QgaGFzIGEgYnVpbHQtaW4gU0FYIENvbnRlbnRIYW5kbGVyLAotICAgKiB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgaWYgd2UncmUgYm91bmQgdG8gb25lIGFuZCBzaG91bGQgcmVjZWl2ZQotICAgKiB0aGUgU0FYIHN0cmVhbSB2aWEgaXQgZm9yIGluY3JlbWVudGFsIGJ1aWxkIHB1cnBvc2VzLi4uCi0gICAqLwotICBwdWJsaWMgTGV4aWNhbEhhbmRsZXIgZ2V0TGV4aWNhbEhhbmRsZXIoKQotICB7Ci0KLSAgICBpZiAobV9pbmNyU0FYU291cmNlIGluc3RhbmNlb2YgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKQotICAgICAgcmV0dXJuIChMZXhpY2FsSGFuZGxlcikgbV9pbmNyU0FYU291cmNlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIEVudGl0eVJlc29sdmVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGVudGl0eSByZWYgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkKLSAgewotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRFRESGFuZGxlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBkdGQgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkRUREhhbmRsZXIgZ2V0RFRESGFuZGxlcigpCi0gIHsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIEVycm9ySGFuZGxlci4KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBlcnJvciBldmVudHMuCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyIGdldEVycm9ySGFuZGxlcigpCi0gIHsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERlY2xIYW5kbGVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIERlY2wgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciBnZXREZWNsSGFuZGxlcigpCi0gIHsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqIEByZXR1cm4gdHJ1ZSBpZmYgd2UncmUgYnVpbGRpbmcgdGhpcyBtb2RlbCBpbmNyZW1lbnRhbGx5IChlZwotICAgKiB3ZSdyZSBwYXJ0bmVyZWQgd2l0aCBhIEluY3JlbWVudGFsU0FYU291cmNlKSBhbmQgdGh1cyByZXF1aXJlIHRoYXQgdGhlCi0gICAqIHRyYW5zZm9ybWF0aW9uIGFuZCB0aGUgcGFyc2UgcnVuIHNpbXVsdGFuZW91c2x5LiBHdWlkYW5jZSB0byB0aGUKLSAgICogRFRNTWFuYWdlci4KLSAgICogKi8KLSAgcHVibGljIGJvb2xlYW4gbmVlZHNUd29UaHJlYWRzKCkKLSAgewotICAgIHJldHVybiBudWxsIT1tX2luY3JTQVhTb3VyY2U7Ci0gIH0KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gPT09PT09PT09IFNBWDIgQ29udGVudEhhbmRsZXIgbWV0aG9kcyA9PT09PT09PT0KLSAgLy8gQWNjZXB0IFNBWCBldmVudHMsIHVzZSB0aGVtIHRvIGJ1aWxkL2V4dGVuZCB0aGUgRFRNIHRyZWUuCi0gIC8vIFJlcGxhY2VzIHRoZSBkZXByZWNhdGVkIERvY3VtZW50SGFuZGxlciBpbnRlcmZhY2UuCi0KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBBY3R1YWxseSBjcmVhdGluZyB0aGUgdGV4dCBub2RlIGlzIGhhbmRsZWQgYnkKLSAgICAvLyBwcm9jZXNzQWNjdW11bGF0ZWRUZXh0KCk7IGhlcmUgd2UganVzdCBhY2N1bXVsYXRlIHRoZQotICAgIC8vIGNoYXJhY3RlcnMgaW50byB0aGUgYnVmZmVyLgotICAgIG1fY2hhci5hcHBlbmQoY2gsc3RhcnQsbGVuZ3RoKTsKLSAgfQotCi0gIC8vIEZsdXNoIHN0cmluZyBhY2N1bXVsYXRpb24gaW50byBhIHRleHQgbm9kZQotICBwcml2YXRlIHZvaWQgcHJvY2Vzc0FjY3VtdWxhdGVkVGV4dCgpCi0gIHsKLSAgICBpbnQgbGVuPW1fY2hhci5sZW5ndGgoKTsKLSAgICBpZihsZW4hPW1fY2hhcl9jdXJyZW50X3N0YXJ0KQotICAgICAgewotICAgICAgICAvLyBUaGUgRmFzdFN0cmluZ0J1ZmZlciBoYXMgYmVlbiBwcmV2aW91c2x5IGFncmVlZCB1cG9uCi0gICAgICAgIGFwcGVuZFRleHRDaGlsZChtX2NoYXJfY3VycmVudF9zdGFydCxsZW4tbV9jaGFyX2N1cnJlbnRfc3RhcnQpOwotICAgICAgICBtX2NoYXJfY3VycmVudF9zdGFydD1sZW47Ci0gICAgICB9Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE1heSBuZWVkIHRvIHRlbGwgdGhlIGxvdy1sZXZlbCBidWlsZGVyIGNvZGUgdG8gcG9wIHVwIGEgbGV2ZWwuCi0gICAgLy8gVGhlcmUgX3Nob3VsZCd0XyBiZSBhbnkgc2lnbmlmaWNhbnQgcGVuZGluZyB0ZXh0IGF0IHRoaXMgcG9pbnQuCi0gICAgYXBwZW5kRW5kRG9jdW1lbnQoKTsKLSAgfQotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcgbmFtZXNwYWNlVVJJLCBqYXZhLmxhbmcuU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgcU5hbWUpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgcHJvY2Vzc0FjY3VtdWxhdGVkVGV4dCgpOwotICAgIC8vIE5vIGFyZ3MgYnV0IHdlIGRvIG5lZWQgdG8gdGVsbCB0aGUgbG93LWxldmVsIGJ1aWxkZXIgY29kZSB0bwotICAgIC8vIHBvcCB1cCBhIGxldmVsLgotICAgIGFwcGVuZEVuZEVsZW1lbnQoKTsKLSAgfQotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKGphdmEubGFuZy5TdHJpbmcgcHJlZml4KQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wCi0gIH0KLSAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyAlVEJEJSBJIGJlbGlldmUgaWdub3JhYmxlIHRleHQgaXNuJ3QgcGFydCBvZiB0aGUgRFRNIG1vZGVsLi4uPwotICB9Ci0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihqYXZhLmxhbmcuU3RyaW5nIHRhcmdldCwgamF2YS5sYW5nLlN0cmluZyBkYXRhKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHByb2Nlc3NBY2N1bXVsYXRlZFRleHQoKTsKLSAgICAvLyAlVEJEJSBXaGljaCBwb29scyBkbyB0YXJnZXQgYW5kIGRhdGEgZ28gaW50bz8KLSAgfQotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0gICAgLy8gTm8tb3AgZm9yIERUTQotICB9Ci0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIHByb2Nlc3NBY2N1bXVsYXRlZFRleHQoKTsKLSAgICAvLyVUQkQlCi0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgYXBwZW5kU3RhcnREb2N1bWVudCgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RWxlbWVudChqYXZhLmxhbmcuU3RyaW5nIG5hbWVzcGFjZVVSSSwgamF2YS5sYW5nLlN0cmluZyBsb2NhbE5hbWUsCi0gICAgICBqYXZhLmxhbmcuU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgcHJvY2Vzc0FjY3VtdWxhdGVkVGV4dCgpOwotCi0gICAgLy8gJVRCRCUgU3BsaXQgcHJlZml4IG9mZiBxbmFtZQotICAgIFN0cmluZyBwcmVmaXg9bnVsbDsKLSAgICBpbnQgY29sb249cU5hbWUuaW5kZXhPZignOicpOwotICAgIGlmKGNvbG9uPjApCi0gICAgICBwcmVmaXg9cU5hbWUuc3Vic3RyaW5nKDAsY29sb24pOwotCi0gICAgLy8gJVRCRCUgV2hlcmUgZG8gd2UgcG9vbCBleHBhbmRlZE5hbWUsIG9yIGlzIGl0IGp1c3QgdGhlIHVuaW9uLCBvci4uLgotICAgIC8qKi9TeXN0ZW0ub3V0LnByaW50bG4oIlByZWZpeD0iK3ByZWZpeCsiIGluZGV4PSIrbV9wcmVmaXhOYW1lcy5zdHJpbmdUb0luZGV4KHByZWZpeCkpOwotICAgIGFwcGVuZFN0YXJ0RWxlbWVudChtX25zTmFtZXMuc3RyaW5nVG9JbmRleChuYW1lc3BhY2VVUkkpLAotICAgICAgICAgICAgICAgICAgICAgbV9sb2NhbE5hbWVzLnN0cmluZ1RvSW5kZXgobG9jYWxOYW1lKSwKLSAgICAgICAgICAgICAgICAgICAgIG1fcHJlZml4TmFtZXMuc3RyaW5nVG9JbmRleChwcmVmaXgpKTsgLy8vLy8vLyAlVEJEJQotCi0gICAgLy8gJVRCRCUgSSdtIGFzc3VtaW5nIHRoYXQgRFRNIHdpbGwgcmVxdWlyZSByZXNlcXVlbmNpbmcgb2YKLSAgICAvLyBOUyBkZWNscyBiZWZvcmUgb3RoZXIgYXR0cnMsIGhlbmNlIHR3byBwYXNzZXMgYXJlIHRha2VuLgotICAgIC8vICVUQkQlIElzIHRoZXJlIGFuIGVhc2llciB3YXkgdG8gdGVzdCBmb3IgTlNEZWNsPwotICAgIGludCBuQXR0cz0oYXR0cz09bnVsbCkgPyAwIDogYXR0cy5nZXRMZW5ndGgoKTsKLSAgICAvLyAlVEJEJSBDb3VudGRvd24gaXMgbW9yZSBlZmZpY2llbnQgaWYgbm9ib2R5IGNhcmVzIGFib3V0IHNlcXVlbmNlLgotICAgIGZvcihpbnQgaT1uQXR0cy0xO2k+PTA7LS1pKQotICAgICAgewotICAgICAgICBxTmFtZT1hdHRzLmdldFFOYW1lKGkpOwotICAgICAgICBpZihxTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fCAieG1sbnMiLmVxdWFscyhxTmFtZSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgcHJlZml4PW51bGw7Ci0gICAgICAgICAgICBjb2xvbj1xTmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBpZihjb2xvbj4wKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcHJlZml4PXFOYW1lLnN1YnN0cmluZygwLGNvbG9uKTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gJVJFVkVJVyUgTnVsbCBvciAiIj8KLSAgICAgICAgICAgICAgICBwcmVmaXg9bnVsbDsgLy8gRGVmYXVsdCBwcmVmaXgKLSAgICAgICAgICAgICAgfQotCi0KLSAgICAgICAgICAgIGFwcGVuZE5TRGVjbGFyYXRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3ByZWZpeE5hbWVzLnN0cmluZ1RvSW5kZXgocHJlZml4KSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KGF0dHMuZ2V0VmFsdWUoaSkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRUeXBlKGkpLmVxdWFsc0lnbm9yZUNhc2UoIklEIikpOwotICAgICAgICAgIH0KLSAgICAgIH0KLQotICAgIGZvcihpbnQgaT1uQXR0cy0xO2k+PTA7LS1pKQotICAgICAgewotICAgICAgICBxTmFtZT1hdHRzLmdldFFOYW1lKGkpOwotICAgICAgICBpZighKHFOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8ICJ4bWxucyIuZXF1YWxzKHFOYW1lKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gJVRCRCUgSSBoYXRlIGhhdmluZyB0byBleHRyYWN0IHRoZSBwcmVmaXggaW50byBhIG5ldwotICAgICAgICAgICAgLy8gc3RyaW5nIHdoZW4gd2UgbWF5IG5ldmVyIHVzZSBpdC4gQ29uc2lkZXIgcG9vbGluZyB3aG9sZQotICAgICAgICAgICAgLy8gcU5hbWVzLCB3aGljaCBhcmUgYWxyZWFkeSBzdHJpbmdzPwotICAgICAgICAgICAgcHJlZml4PW51bGw7Ci0gICAgICAgICAgICBjb2xvbj1xTmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICBpZihjb2xvbj4wKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcHJlZml4PXFOYW1lLnN1YnN0cmluZygwLGNvbG9uKTsKLSAgICAgICAgICAgICAgICBsb2NhbE5hbWU9cU5hbWUuc3Vic3RyaW5nKGNvbG9uKzEpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBwcmVmaXg9IiI7IC8vIERlZmF1bHQgcHJlZml4Ci0gICAgICAgICAgICAgICAgbG9jYWxOYW1lPXFOYW1lOwotICAgICAgICAgICAgICB9Ci0KLQotICAgICAgICAgICAgbV9jaGFyLmFwcGVuZChhdHRzLmdldFZhbHVlKGkpKTsgLy8gU2luZ2xlLXN0cmluZyB2YWx1ZQotICAgICAgICAgICAgaW50IGNvbnRlbnRFbmQ9bV9jaGFyLmxlbmd0aCgpOwotCi0gICAgICAgICAgICBpZighKCJ4bWxucyIuZXF1YWxzKHByZWZpeCkgfHwgInhtbG5zIi5lcXVhbHMocU5hbWUpKSkKLSAgICAgICAgICAgICAgYXBwZW5kQXR0cmlidXRlKG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KGF0dHMuZ2V0VVJJKGkpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2FsTmFtZXMuc3RyaW5nVG9JbmRleChsb2NhbE5hbWUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcHJlZml4TmFtZXMuc3RyaW5nVG9JbmRleChwcmVmaXgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VHlwZShpKS5lcXVhbHNJZ25vcmVDYXNlKCJJRCIpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2hhcl9jdXJyZW50X3N0YXJ0LCBjb250ZW50RW5kLW1fY2hhcl9jdXJyZW50X3N0YXJ0KTsKLSAgICAgICAgICAgIG1fY2hhcl9jdXJyZW50X3N0YXJ0PWNvbnRlbnRFbmQ7Ci0gICAgICAgICAgfQotICAgICAgfQotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhqYXZhLmxhbmcuU3RyaW5nIHByZWZpeCwgamF2YS5sYW5nLlN0cmluZyB1cmkpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gTm8tb3AgaW4gRFRNLCBoYW5kbGVkIGR1cmluZyBlbGVtZW50L2F0dHIgcHJvY2Vzc2luZz8KLSAgfQotCi0gIC8vCi0gIC8vIExleGljYWxIYW5kbGVyIHN1cHBvcnQuIE5vdCBhbGwgU0FYMiBwYXJzZXJzIHN1cHBvcnQgdGhlc2UgZXZlbnRzCi0gIC8vIGJ1dCB3ZSBtYXkgd2FudCB0byBwYXNzIHRoZW0gdGhyb3VnaCB3aGVuIHRoZXkgZXhpc3QuLi4KLSAgLy8KLSAgcHVibGljIHZvaWQgY29tbWVudChjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBwcm9jZXNzQWNjdW11bGF0ZWRUZXh0KCk7Ci0KLSAgICBtX2NoYXIuYXBwZW5kKGNoLHN0YXJ0LGxlbmd0aCk7IC8vIFNpbmdsZS1zdHJpbmcgdmFsdWUKLSAgICBhcHBlbmRDb21tZW50KG1fY2hhcl9jdXJyZW50X3N0YXJ0LGxlbmd0aCk7Ci0gICAgbV9jaGFyX2N1cnJlbnRfc3RhcnQrPWxlbmd0aDsKLSAgfQotICBwdWJsaWMgdm9pZCBlbmRDREFUQSgpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gTm8tb3AgaW4gRFRNCi0gIH0KLSAgcHVibGljIHZvaWQgZW5kRFREKCkKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOby1vcCBpbiBEVE0KLSAgfQotICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wIGluIERUTQotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wIGluIERUTQotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgamF2YS5sYW5nLlN0cmluZyBwdWJsaWNJZCwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gTm8tb3AgaW4gRFRNCi0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIE5vLW9wIGluIERUTQotICB9Ci0KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gPT09PT09PT09IERvY3VtZW50IEhhbmRsZXIgRnVuY3Rpb25zID09PT09PT09PQotICAvLyAlUkVWSUVXJSBqamsgLS0gRG9jdW1lbnRIYW5kbGVyIGlzICBTQVggTGV2ZWwgMSwgYW5kIGRlcHJlY2F0ZWQuLi4uCi0gIC8vIGFuZCB0aGlzIHdhc24ndCBhIGZ1bGx5IGNvbXBsaWFudCBvciBkZWNsYXJlZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGF0IEFQSQotICAvLyBpbiBhbnkgY2FzZS4gUGhhc2Ugb3V0IGluIGZhdm9yIG9mIFNBWDIgQ29udGVudEhhbmRsZXIvTGV4aWNhbEhhbmRsZXIKLQotICAgICAgICAvKioKLSAgICAgICAgICogUmVzZXQgYSBkdG0gZG9jdW1lbnQgdG8gaXRzIGluaXRpYWwgKGVtcHR5KSBzdGF0ZS4KLSAgICAgICAgICoKLSAgICAgICAgICogVGhlIERUTU1hbmFnZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgd2hlbiB0aGUgZHRtIGlzIGNyZWF0ZWQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkb2NIYW5kbGUgaW50IHRoZSBoYW5kbGUgZm9yIHRoZSBEVE0gZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICBmaW5hbCB2b2lkIGluaXREb2N1bWVudChpbnQgZG9jdW1lbnROdW1iZXIpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBzYXZlIG1hc2tlZCBEVE0gZG9jdW1lbnQgaGFuZGxlCi0gICAgICAgICAgICAgICAgbV9kb2NIYW5kbGUgPSBkb2N1bWVudE51bWJlcjw8RE9DSEFORExFX1NISUZUOwotCi0gICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgZG9jIC0tIG5vIHBhcmVudCwgbm8gbmV4dC1zaWIKLSAgICAgICAgICAgICAgICBub2Rlcy53cml0ZVNsb3QoMCxET0NVTUVOVF9OT0RFLC0xLC0xLDApOwotICAgICAgICAgICAgICAgIC8vIHdhaXQgZm9yIHRoZSBmaXJzdCBzdGFydEVsZW1lbnQgdG8gY3JlYXRlIHRoZSBkb2Mgcm9vdCBub2RlCi0gICAgICAgICAgICAgICAgZG9uZSA9IGZhbHNlOwotICAgICAgICB9Ci0KLS8vIAkvKioKLS8vIAkgKiBSZWNlaXZlIGhpbnQgb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotLy8gCSAqCi0vLyAJICogPHA+VGhlIGNvbnRlbnQgaGFuZGxlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGFuZCBpdCB3aWxsCi0vLyAJICogYmUgdGhlIGxhc3QgbWV0aG9kIGludm9rZWQgZHVyaW5nIHRoZSBwYXJzZS4gIFRoZSBoYW5kbGVyIHNoYWxsIG5vdAotLy8gCSAqIG5vdCBpbnZva2UgdGhpcyBtZXRob2QgdW50aWwgaXQgaGFzIGVpdGhlciBhYmFuZG9uZWQgcGFyc2luZwotLy8gCSAqIChiZWNhdXNlIG9mIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IpIG9yIHJlYWNoZWQgdGhlIGVuZCBvZgotLy8gCSAqIGlucHV0LjwvcD4KLS8vIAkgKi8KLS8vIAlwdWJsaWMgdm9pZCBkb2N1bWVudEVuZCgpCi0vLyAJewotLy8gCQlkb25lID0gdHJ1ZTsKLS8vIAkJLy8gJVRCRCUgbWF5IG5lZWQgdG8gbm90aWNlIHRoZSBsYXN0IHNsb3QgbnVtYmVyIGFuZCBzbG90IGNvdW50IHRvIGF2b2lkCi0vLyAJCS8vIHJlc2lkdWFsIGRhdGEgZnJvbSBwcm92aW91cyB1c2Ugb2YgdGhpcyBEVE0KLS8vIAl9Ci0KLS8vIAkvKioKLS8vIAkgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgZG9jdW1lbnQuCi0vLyAJICoKLS8vIAkgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGJlZm9yZSBhbnkKLS8vIAkgKiBvdGhlciBtZXRob2RzIGluIHRoaXMgaW50ZXJmYWNlLjwvcD4KLS8vIAkgKi8KLS8vIAlwdWJsaWMgdm9pZCByZXNldCgpCi0vLyAJewotCi0vLyAJCS8vICVUQkQlIHJlc2V0IHNsb3QgMCB0byBpbmRpY2F0ZSBDaHVua2VkSW50QXJyYXkgcmV1c2Ugb3Igd2FpdCBmb3IKLS8vIAkJLy8gICAgICAgdGhlIG5leHQgaW5pdERvY3VtZW50KCkuCi0vLyAJCW1fZG9jRWxlbWVudCA9IE5VTEw7CSAvLyByZXNldCBub2RlSGFuZGxlIHRvIHRoZSByb290IG9mIHRoZSBhY3R1YWwgZHRtIGRvYyBjb250ZW50Ci0vLyAJCWluaXREb2N1bWVudCgwKTsKLS8vIAl9Ci0KLS8vIAkvKioKLS8vIAkgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhbiBFbGVtZW50IG5vZGUgaW4gdGhpcyBkb2N1bWVudC4KLS8vIAkgKgotLy8gCSAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAJICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vIAkgKgotLy8gCSAqIDxwPlRoZSBYTUwgY29udGVudCBoYW5kbGVyIHdpbGwgaW52b2tlIGVuZEVsZW1lbnQoKSBtZXRob2QgYWZ0ZXIgYWxsCi0vLyAJICogb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IGFyZSBwcm9jZXNzZWQgaW4gb3JkZXIgdG8gZ2l2ZSBEVE0gdGhlIGluZGljYXRpb24KLS8vIAkgKiB0byBwcmVwYXJlIGFuZCBwYXRjaCB1cCBwYXJlbnQgYW5kIHNpYmxpbmcgbm9kZSBwb2ludGVycy48L3A+Ci0vLyAJICoKLS8vIAkgKiA8cD5UaGUgZm9sbG93aW5nIGludGVyZmFjZSBmb3IgY3JlYXRlRWxlbWVudCB3aWxsIHVzZSBhbiBpbmRleCB2YWx1ZSBjb3JyZXNwb25kcwotLy8gCSAqIHRvIHRoZSBzeW1ib2wgZW50cnkgaW4gdGhlIERUTURTdHJpbmdQb29sIGJhc2VkIHN5bWJvbCB0YWJsZXMuPC9wPgotLy8gCSAqCi0vLyAJICogQHBhcmFtIG5zSW5kZXggVGhlIG5hbWVzcGFjZSBvZiB0aGUgbm9kZQotLy8gCSAqIEBwYXJhbSBuYW1lSW5kZXggVGhlIGVsZW1lbnQgbmFtZS4KLS8vIAkgKiBAc2VlICNlbmRFbGVtZW50Ci0vLyAJICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0vLyAJICogQHJldHVybiBub2RlSGFuZGxlIGludCBvZiB0aGUgZWxlbWVudCBjcmVhdGVkCi0vLyAJICovCi0vLyAJcHVibGljIGludCBjcmVhdGVFbGVtZW50KGludCBuc0luZGV4LCBpbnQgbmFtZUluZGV4LCBBdHRyaWJ1dGVzIGF0dHMpCi0vLyAJewotLy8gCQkvLyBkbyBkb2N1bWVudCByb290IG5vZGUgY3JlYXRpb24gaGVyZSBvbiB0aGUgZmlyc3QgZWxlbWVudCwgY3JlYXRlIG5vZGVzIGZvcgotLy8gCQkvLyB0aGlzIGVsZW1lbnQgYW5kIGl0cyBhdHRyaWJ1dGVzLCBzdG9yZSB0aGUgZWxlbWVudCwgbmFtZXNwYWNlLCBhbmQgYXR0cml0dXRlCi0vLyAJCS8vIG5hbWUgaW5kZXhlcyB0byB0aGUgbm9kZXMgYXJyYXksIGtlZXAgdHJhY2sgb2YgdGhlIGN1cnJlbnQgbm9kZSBhbmQgcGFyZW50Ci0vLyAJCS8vIGVsZW1lbnQgdXNlZAotCi0vLyAJCS8vIFcwICBIaWdoOiAgTmFtZXNwYWNlICBMb3c6ICBOb2RlIFR5cGUKLS8vIAkJaW50IHcwID0gKG5zSW5kZXggPDwgMTYpIHwgRUxFTUVOVF9OT0RFOwotLy8gCQkvLyBXMTogUGFyZW50Ci0vLyAJCWludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0vLyAJCS8vIFcyOiBOZXh0ICAoaW5pdGlhbGl6ZWQgYXMgMCkKLS8vIAkJaW50IHcyID0gMDsKLS8vIAkJLy8gVzM6IFRhZ25hbWUKLS8vIAkJaW50IHczID0gbmFtZUluZGV4OwotLy8gCQkvL2ludCBvdXJzbG90ID0gbm9kZXMuYXBwZW5kU2xvdCh3MCwgdzEsIHcyLCB3Myk7Ci0vLyAJCWludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0vLyAJCWN1cnJlbnRQYXJlbnQgPSBvdXJzbG90OwotLy8gCQlwcmV2aW91c1NpYmxpbmcgPSAwOwotLy8gCQlzZXRBdHRyaWJ1dGVzKGF0dHMpOwotCi0vLyAJCS8vIHNldCB0aGUgcm9vdCBlbGVtZW50IHBvaW50ZXIgd2hlbiBjcmVhdGluZyB0aGUgZmlyc3QgZWxlbWVudCBub2RlCi0vLyAJCWlmIChtX2RvY0VsZW1lbnQgPT0gTlVMTCkKLS8vIAkJCW1fZG9jRWxlbWVudCA9IG91cnNsb3Q7Ci0vLyAJCXJldHVybiAobV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLS8vIAl9Ci0KLS8vIAkvLyBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgYW4gRWxlbWVudCBub2RlIG5vdCBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBuYW1lIHNwYWNlCi0vLyAJLy8gdXNpbmcgU3RyaW5nIHZhbHVlIHBhcmFtZXRlcnMgcGFzc2VkIGluIGZyb20gYSBjb250ZW50IGhhbmRsZXIgb3IgYXBwbGljYXRpb24KLS8vIAkvKioKLS8vIAkgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhbiBFbGVtZW50IG5vZGUgbm90IGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIG5hbWUgc3BhY2UgaW4gdGhpcyBkb2N1bWVudC4KLS8vIAkgKgotLy8gCSAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAJICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vIAkgKgotLy8gCSAqIDxwPlRoZSBYTUwgY29udGVudCBoYW5kbGVyIG9yIGFwcGxpY2F0aW9uIHdpbGwgaW52b2tlIGVuZEVsZW1lbnQoKSBtZXRob2QgYWZ0ZXIgYWxsCi0vLyAJICogb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IGFyZSBwcm9jZXNzZWQgaW4gb3JkZXIgdG8gZ2l2ZSBEVE0gdGhlIGluZGljYXRpb24KLS8vIAkgKiB0byBwcmVwYXJlIGFuZCBwYXRjaCB1cCBwYXJlbnQgYW5kIHNpYmxpbmcgbm9kZSBwb2ludGVycy48L3A+Ci0vLyAJICoKLS8vIAkgKiA8cD5UaGUgZm9sbG93aW5nIHBhcmFtZXRlcnMgZm9yIGNyZWF0ZUVsZW1lbnQgY29udGFpbnMgcmF3IHN0cmluZyB2YWx1ZXMgZm9yIG5hbWUKLS8vIAkgKiBzeW1ib2xzIHVzZWQgaW4gYW4gRWxlbWVudCBub2RlLjwvcD4KLS8vIAkgKgotLy8gCSAqIEBwYXJhbSBuYW1lIFN0cmluZyB0aGUgZWxlbWVudCBuYW1lLCBpbmNsdWRpbmcgdGhlIHByZWZpeCBpZiBhbnkuCi0vLyAJICogQHBhcmFtIGF0dHMgVGhlIGF0dHJpYnV0ZXMgYXR0YWNoZWQgdG8gdGhlIGVsZW1lbnQsIGlmIGFueS4KLS8vIAkgKiBAc2VlICNlbmRFbGVtZW50Ci0vLyAJICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0vLyAJICovCi0vLyAJcHVibGljIGludCBjcmVhdGVFbGVtZW50KFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCi0vLyAJewotLy8gCQkvLyBUaGlzIG1ldGhvZCB3cmFwcyBhcm91bmQgdGhlIGluZGV4IHZhbHVlZCBpbnRlcmZhY2Ugb2YgdGhlIGNyZWF0ZUVsZW1lbnQgaW50ZXJmYWNlLgotLy8gCQkvLyBUaGUgcmF3IHN0cmluZyB2YWx1ZXMgYXJlIHN0b3JlZCBpbnRvIHRoZSBjdXJyZW50IERUTSBuYW1lIHN5bWJvbCB0YWJsZXMuICBUaGUgbWV0aG9kCi0vLyAJCS8vIG1ldGhvZCB3aWxsIHRoZW4gdXNlIHRoZSBpbmRleCB2YWx1ZXMgcmV0dXJuZWQgdG8gaW52b2tlIHRoZSBvdGhlciBjcmVhdGVFbGVtZW50KCkKLS8vIAkJLy8gb252ZXJ0ZWQgdG8gaW5kZXggdmFsdWVzIG1vZGlmaWVkIHRvIG1hdGNoIGEKLS8vIAkJLy8gbWV0aG9kLgotLy8gCQlpbnQgbnNJbmRleCA9IE5VTEw7Ci0vLyAJCWludCBuYW1lSW5kZXggPSBtX2xvY2FsTmFtZXMuc3RyaW5nVG9JbmRleChuYW1lKTsKLS8vIAkJLy8gbm90ZSAtIHRoZXJlIHNob3VsZCBiZSBubyBwcmVmaXggc2VwYXJhdG9yIGluIHRoZSBuYW1lIGJlY2F1c2UgaXQgaXMgbm90IGFzc29jaWF0ZWQKLS8vIAkJLy8gd2l0aCBhIG5hbWUgc3BhY2UKLQotLy8gCQlyZXR1cm4gY3JlYXRlRWxlbWVudChuc0luZGV4LCBuYW1lSW5kZXgsIGF0dHMpOwotLy8gCX0KLQotLy8gCS8vIEZhY3RvcnkgbWV0aG9kIHRvIGNyZWF0ZSBhbiBFbGVtZW50IG5vZGUgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gbmFtZSBzcGFjZQotLy8gCS8vIHVzaW5nIFN0cmluZyB2YWx1ZSBwYXJhbWV0ZXJzIHBhc3NlZCBpbiBmcm9tIGEgY29udGVudCBoYW5kbGVyIG9yIGFwcGxpY2F0aW9uCi0vLyAJLyoqCi0vLyAJICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYW4gRWxlbWVudCBub2RlIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIG5hbWUgc3BhY2UgaW4gdGhpcyBkb2N1bWVudC4KLS8vIAkgKgotLy8gCSAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAJICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vIAkgKgotLy8gCSAqIDxwPlRoZSBYTUwgY29udGVudCBoYW5kbGVyIG9yIGFwcGxpY2F0aW9uIHdpbGwgaW52b2tlIGVuZEVsZW1lbnQoKSBtZXRob2QgYWZ0ZXIgYWxsCi0vLyAJICogb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IGFyZSBwcm9jZXNzZWQgaW4gb3JkZXIgdG8gZ2l2ZSBEVE0gdGhlIGluZGljYXRpb24KLS8vIAkgKiB0byBwcmVwYXJlIGFuZCBwYXRjaCB1cCBwYXJlbnQgYW5kIHNpYmxpbmcgbm9kZSBwb2ludGVycy48L3A+Ci0vLyAJICoKLS8vIAkgKiA8cD5UaGUgZm9sbG93aW5nIHBhcmFtZXRlcnMgZm9yIGNyZWF0ZUVsZW1lbnROUyBjb250YWlucyByYXcgc3RyaW5nIHZhbHVlcyBmb3IgbmFtZQotLy8gCSAqIHN5bWJvbHMgdXNlZCBpbiBhbiBFbGVtZW50IG5vZGUuPC9wPgotLy8gCSAqCi0vLyAJICogQHBhcmFtIG5zIFN0cmluZyB0aGUgbmFtZXNwYWNlIG9mIHRoZSBub2RlCi0vLyAJICogQHBhcmFtIG5hbWUgU3RyaW5nIHRoZSBlbGVtZW50IG5hbWUsIGluY2x1ZGluZyB0aGUgcHJlZml4IGlmIGFueS4KLS8vIAkgKiBAcGFyYW0gYXR0cyBUaGUgYXR0cmlidXRlcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCwgaWYgYW55LgotLy8gCSAqIEBzZWUgI2VuZEVsZW1lbnQKLS8vIAkgKiBAc2VlIG9yZy54bWwuc2F4LkF0dHJpYnV0ZXMKLS8vIAkgKi8KLS8vIAlwdWJsaWMgaW50IGNyZWF0ZUVsZW1lbnROUyhTdHJpbmcgbnMsIFN0cmluZyBuYW1lLCBBdHRyaWJ1dGVzIGF0dHMpCi0vLyAJewotLy8gCQkvLyBUaGlzIG1ldGhvZCB3cmFwcyBhcm91bmQgdGhlIGluZGV4IHZhbHVlZCBpbnRlcmZhY2Ugb2YgdGhlIGNyZWF0ZUVsZW1lbnQgaW50ZXJmYWNlLgotLy8gCQkvLyBUaGUgcmF3IHN0cmluZyB2YWx1ZXMgYXJlIHN0b3JlZCBpbnRvIHRoZSBjdXJyZW50IERUTSBuYW1lIHN5bWJvbCB0YWJsZXMuICBUaGUgbWV0aG9kCi0vLyAJCS8vIG1ldGhvZCB3aWxsIHRoZW4gdXNlIHRoZSBpbmRleCB2YWx1ZXMgcmV0dXJuZWQgdG8gaW52b2tlIHRoZSBvdGhlciBjcmVhdGVFbGVtZW50KCkKLS8vIAkJLy8gb252ZXJ0ZWQgdG8gaW5kZXggdmFsdWVzIG1vZGlmaWVkIHRvIG1hdGNoIGEKLS8vIAkJLy8gbWV0aG9kLgotLy8gCQlpbnQgbnNJbmRleCA9IG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KG5zKTsKLS8vIAkJaW50IG5hbWVJbmRleCA9IG1fbG9jYWxOYW1lcy5zdHJpbmdUb0luZGV4KG5hbWUpOwotLy8gCQkvLyBUaGUgcHJlZml4SW5kZXggaXMgbm90IG5lZWRlZCBieSB0aGUgaW5kZXhlZCBpbnRlcmZhY2Ugb2YgdGhlIGNyZWF0ZUVsZW1lbnQgbWV0aG9kCi0vLyAJCWludCBwcmVmaXhTZXAgPSBuYW1lLmluZGV4T2YoIjoiKTsKLS8vIAkJaW50IHByZWZpeEluZGV4ID0gbV9wcmVmaXhOYW1lcy5zdHJpbmdUb0luZGV4KG5hbWUuc3Vic3RyaW5nKDAsIHByZWZpeFNlcCkpOwotLy8gCQlyZXR1cm4gY3JlYXRlRWxlbWVudChuc0luZGV4LCBuYW1lSW5kZXgsIGF0dHMpOwotLy8gCX0KLQotLy8gCS8qKgotLy8gCSAqIFJlY2VpdmUgYW4gaW5kaWNhdGlvbiBmb3IgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotLy8gCSAqCi0vLyAJICogPHA+VGhlIFhNTCBjb250ZW50IGhhbmRsZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGVuZCBvZiBldmVyeQotLy8gCSAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudCB0byBnaXZlIGhpbnQgaXRzIHRpbWUgdG8gcG9wIHVwIHRoZSBjdXJyZW50Ci0vLyAJICogZWxlbWVudCBhbmQgcGFyZW50IGFuZCBwYXRjaCB1cCBwYXJlbnQgYW5kIHNpYmxpbmcgcG9pbnRlcnMgaWYgbmVjZXNzYXJ5Ci0vLyAJICoKLS8vIAkgKiA8cD4ldGJkJSBUaGUgZm9sbG93aW5nIGludGVyZmFjZSBtYXkgbmVlZCB0byBiZSBtb2RpZmllZCB0byBtYXRjaCBhCi0vLyAJICogY29vcmRpbmF0ZWQgYWNjZXNzIHRvIHRoZSBEVE1EU3RyaW5nUG9vbCBiYXNlZCBzeW1ib2wgdGFibGVzLjwvcD4KLS8vIAkJICoKLS8vIAkgKiBAcGFyYW0gbnMgdGhlIG5hbWVzcGFjZSBvZiB0aGUgZWxlbWVudAotLy8gCSAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIHBhcnQgb2YgdGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0vLyAJICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgbmFtZQotLy8gCSAqLwotLy8gCXB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIG5zLCBTdHJpbmcgbmFtZSkKLS8vIAl7Ci0vLyAJCS8vIHBvcCB1cCB0aGUgc3RhY2tzCi0KLS8vIAkJLy8KLS8vIAkJaWYgKHByZXZpb3VzU2libGluZ1dhc1BhcmVudCkKLS8vIAkJCW5vZGVzLndyaXRlRW50cnkocHJldmlvdXNTaWJsaW5nLCAyLCBOVUxMKTsKLQotLy8gCQkvLyBQb3AgcGFyZW50YWdlCi0vLyAJCXByZXZpb3VzU2libGluZyA9IGN1cnJlbnRQYXJlbnQ7Ci0vLyAJCW5vZGVzLnJlYWRTbG90KGN1cnJlbnRQYXJlbnQsIGdvdHNsb3QpOwotLy8gCQljdXJyZW50UGFyZW50ID0gZ290c2xvdFsxXSAmIDB4RkZGRjsKLQotLy8gCQkvLyBUaGUgZWxlbWVudCBqdXN0IGJlaW5nIGZpbmlzaGVkIHdpbGwgYmUKLS8vIAkJLy8gdGhlIHByZXZpb3VzIHNpYmxpbmcgZm9yIHRoZSBuZXh0IG9wZXJhdGlvbgotLy8gCQlwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSB0cnVlOwotCi0vLyAJCS8vIFBvcCBhIGxldmVsIG9mIG5hbWVzcGFjZSB0YWJsZQotLy8gCQkvLyBuYW1lc3BhY2VUYWJsZS5yZW1vdmVMYXN0RWxlbSgpOwotLy8gCX0KLQotLy8gCS8qKgotLy8gCSAqIENyZWF0ZXMgYXR0cmlidXRlcyBmb3IgdGhlIGN1cnJlbnQgbm9kZS4KLS8vIAkgKgotLy8gCSAqIEBwYXJhbSBhdHRzIEF0dHJpYnV0ZXMgdG8gYmUgY3JlYXRlZC4KLS8vIAkgKi8KLS8vIAl2b2lkIHNldEF0dHJpYnV0ZXMoQXR0cmlidXRlcyBhdHRzKSB7Ci0vLyAJCWludCBhdExlbmd0aCA9IChudWxsID09IGF0dHMpID8gMCA6IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0vLyAJCWZvciAoaW50IGk9MDsgaSA8IGF0TGVuZ3RoOyBpKyspIHsKLS8vIAkJCVN0cmluZyBxbmFtZSA9IGF0dHMuZ2V0UU5hbWUoaSk7Ci0vLyAJCQljcmVhdGVBdHRyaWJ1dGUoYXR0cy5nZXRRTmFtZShpKSwgYXR0cy5nZXRWYWx1ZShpKSk7Ci0vLyAJCX0KLS8vIAl9Ci0KLS8vIAkvKioKLS8vIAkgKiBBcHBlbmRzIGFuIGF0dHJpYnV0ZSB0byB0aGUgZG9jdW1lbnQuCi0vLyAJICogQHBhcmFtIHFuYW1lIFF1YWxpZmllZCBOYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLS8vIAkgKiBAcGFyYW0gdmFsdWUgVmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQotLy8gCSAqIEByZXR1cm4gSGFuZGxlIG9mIG5vZGUKLS8vIAkgKi8KLS8vIAlwdWJsaWMgaW50IGNyZWF0ZUF0dHJpYnV0ZShTdHJpbmcgcW5hbWUsIFN0cmluZyB2YWx1ZSkgewotLy8gCQlpbnQgY29sb25wb3MgPSBxbmFtZS5pbmRleE9mKCI6Iik7Ci0vLyAJCVN0cmluZyBhdHROYW1lID0gcW5hbWUuc3Vic3RyaW5nKGNvbG9ucG9zKzEpOwotLy8gCQlpbnQgdzAgPSAwOwotLy8gCQlpZiAoY29sb25wb3MgPiAwKSB7Ci0vLyAJCQlTdHJpbmcgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKDAsIGNvbG9ucG9zKTsKLS8vIAkJCWlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkgewotLy8gCQkJCS8vdzAgPSBBVFRSSUJVVEVfTk9ERSB8Ci0vLyAJCQkJLy8JKG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50cy5TX1hNTE5BTUVTUEFDRVVSSSA8PCAxNik7Ci0vLyAJCQl9IGVsc2UgewotLy8gCQkJCS8vdzAgPSBBVFRSSUJVVEVfTk9ERSB8Ci0vLyAJCQl9Ci0vLyAJCX0gZWxzZSB7Ci0vLyAJCQl3MCA9IEFUVFJJQlVURV9OT0RFOwotLy8gCQl9Ci0vLyAJCS8vIFcxOiAgUGFyZW50Ci0vLyAJCWludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0vLyAJCS8vIFcyOiAgTmV4dCAobm90IHlldCByZXNvbHZlZCkKLS8vIAkJaW50IHcyID0gMDsKLS8vIAkJLy8gVzM6ICBUYWcgbmFtZQotLy8gCQlpbnQgdzMgPSBtX2xvY2FsTmFtZXMuc3RyaW5nVG9JbmRleChhdHROYW1lKTsKLS8vIAkJLy8gQWRkIG5vZGUKLS8vIAkJaW50IG91cnNsb3QgPSBhcHBlbmROb2RlKHcwLCB3MSwgdzIsIHczKTsKLS8vIAkJcHJldmlvdXNTaWJsaW5nID0gb3Vyc2xvdDsJLy8gU2hvdWxkIGF0dHJpYnV0ZXMgYmUgcHJldmlvdXMgc2libGluZ3MKLQotLy8gCQkvLyBXMDogTm9kZSBUeXBlCi0vLyAJCXcwID0gVEVYVF9OT0RFOwotLy8gCQkvLyBXMTogUGFyZW50Ci0vLyAJCXcxID0gb3Vyc2xvdDsKLS8vIAkJLy8gVzI6IFN0YXJ0IFBvc2l0aW9uIHdpdGhpbiBidWZmZXIKLS8vIAkJdzIgPSBtX2NoYXIubGVuZ3RoKCk7Ci0vLyAJCW1fY2hhci5hcHBlbmQodmFsdWUpOwotLy8gCQkvLyBXMzogTGVuZ3RoCi0vLyAJCXczID0gbV9jaGFyLmxlbmd0aCgpIC0gdzI7Ci0vLyAJCWFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotLy8gCQljaGFyU3RyaW5nU3RhcnQ9bV9jaGFyLmxlbmd0aCgpOwotLy8gCQljaGFyU3RyaW5nTGVuZ3RoID0gMDsKLS8vIAkJLy9wcmV2aW91c1NpYmxpbmcgPSBvdXJzbG90OwotLy8gCQkvLyBBdHRycyBhcmUgUGFyZW50cwotLy8gCQlwcmV2aW91c1NpYmxpbmdXYXNQYXJlbnQgPSB0cnVlOwotLy8gCQlyZXR1cm4gKG1fZG9jSGFuZGxlIHwgb3Vyc2xvdCk7Ci0vLyAJfQotCi0vLyAJLyoqCi0vLyAJICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYSBUZXh0IG5vZGUgaW4gdGhpcyBkb2N1bWVudC4KLS8vIAkgKgotLy8gCSAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAJICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vIAkgKgotLy8gCSAqIEBwYXJhbSB0ZXh0IFN0cmluZyBUaGUgY2hhcmFjdGVycyB0ZXh0IHN0cmluZyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0vLyAJICogQHJldHVybiBpbnQgRFRNIG5vZGUtbnVtYmVyIG9mIHRoZSB0ZXh0IG5vZGUgY3JlYXRlZAotLy8gCSAqLwotLy8gCXB1YmxpYyBpbnQgY3JlYXRlVGV4dE5vZGUoU3RyaW5nIHRleHQpCi0vLyAJdGhyb3dzIERUTUV4Y2VwdGlvbgotLy8gCXsKLS8vIAkJLy8gd3JhcHMgYXJvdW5kIHRoZSBpbmRleCB2YWx1ZSBiYXNlZCBjcmVhdGVUZXh0Tm9kZSBtZXRob2QKLS8vIAkJcmV0dXJuIGNyZWF0ZVRleHROb2RlKHRleHQudG9DaGFyQXJyYXkoKSwgMCwgdGV4dC5sZW5ndGgoKSk7Ci0vLyAJfQotCi0vLyAJLyoqCi0vLyAJICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYSBUZXh0IG5vZGUgaW4gdGhpcyBkb2N1bWVudC4KLS8vIAkgKgotLy8gCSAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAJICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vIAkgKgotLy8gCSAqICVSRVZJRVclIGZvciB0ZXh0IG5vcm1hbGl6YXRpb24gaXNzdWVzLCB1bmxlc3Mgd2UgYXJlIHdpbGxpbmcgdG8KLS8vIAkgKiBpbnNpc3QgdGhhdCBhbGwgYWRqYWNlbnQgdGV4dCBtdXN0IGJlIG1lcmdlZCBiZWZvcmUgdGhpcyBtZXRob2QKLS8vIAkgKiBpcyBjYWxsZWQuCi0vLyAJICoKLS8vIAkgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotLy8gCSAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotLy8gCSAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0vLyAJICovCi0vLyAJcHVibGljIGludCBjcmVhdGVUZXh0Tm9kZShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLS8vIAl0aHJvd3MgRFRNRXhjZXB0aW9uCi0vLyAJewotLy8gCQltX2NoYXIuYXBwZW5kKGNoLCBzdGFydCwgbGVuZ3RoKTsJCS8vIHN0b3JlIHRoZSBjaHVuayB0byB0aGUgdGV4dC9jb21tZW50IHN0cmluZyB0YWJsZQotCi0vLyAJCS8vIGNyZWF0ZSBhIFRleHQgTm9kZQotLy8gCQkvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotLy8gCQlpbnQgdzAgPSBURVhUX05PREU7Ci0vLyAJCS8vIFcxOiBQYXJlbnQKLS8vIAkJaW50IHcxID0gY3VycmVudFBhcmVudDsKLS8vIAkJLy8gVzI6IFN0YXJ0IHBvc2l0aW9uIHdpdGhpbiBtX2NoYXIKLS8vIAkJaW50IHcyID0gY2hhclN0cmluZ1N0YXJ0OwotLy8gCQkvLyBXMzogTGVuZ3RoIG9mIHRoZSBmdWxsIHN0cmluZwotLy8gCQlpbnQgdzMgPSBsZW5ndGg7Ci0vLyAJCWludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0vLyAJCXByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7Ci0KLS8vIAkJY2hhclN0cmluZ1N0YXJ0PW1fY2hhci5sZW5ndGgoKTsKLS8vIAkJY2hhclN0cmluZ0xlbmd0aCA9IDA7Ci0vLyAJCXJldHVybiAobV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLS8vIAl9Ci0KLS8vIAkvKioKLS8vIAkgKiBGYWN0b3J5IG1ldGhvZDsgY3JlYXRlcyBhIENvbW1lbnQgbm9kZSBpbiB0aGlzIGRvY3VtZW50LgotLy8gCSAqCi0vLyAJICogVGhlIG5vZGUgY3JlYXRlZCB3aWxsIGJlIGNoYWluZWQgYWNjb3JkaW5nIHRvIGl0cyBuYXR1cmFsIG9yZGVyIG9mIHJlcXVlc3QKLS8vIAkgKiByZWNlaXZlZC4gICVUQkQlIEl0IGNhbiBiZSByZWNoYWluZWQgbGF0ZXIgdmlhIHRoZSBvcHRpb25hbCBEVE0gd3JpdGFibGUgaW50ZXJmYWNlLgotLy8gCSAqCi0vLyAJICogQHBhcmFtIHRleHQgU3RyaW5nIFRoZSBjaGFyYWN0ZXJzIHRleHQgc3RyaW5nIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLS8vIAkgKiBAcmV0dXJuIGludCBEVE0gbm9kZS1udW1iZXIgb2YgdGhlIHRleHQgbm9kZSBjcmVhdGVkCi0vLyAJICovCi0vLyAJcHVibGljIGludCBjcmVhdGVDb21tZW50KFN0cmluZyB0ZXh0KQotLy8gCXRocm93cyBEVE1FeGNlcHRpb24KLS8vIAl7Ci0vLyAJCS8vIHdyYXBzIGFyb3VuZCB0aGUgaW5kZXggdmFsdWUgYmFzZWQgY3JlYXRlVGV4dE5vZGUgbWV0aG9kCi0vLyAJCXJldHVybiBjcmVhdGVDb21tZW50KHRleHQudG9DaGFyQXJyYXkoKSwgMCwgdGV4dC5sZW5ndGgoKSk7Ci0vLyAJfQotCi0vLyAJLyoqCi0vLyAJICogRmFjdG9yeSBtZXRob2Q7IGNyZWF0ZXMgYSBDb21tZW50IG5vZGUgaW4gdGhpcyBkb2N1bWVudC4KLS8vIAkgKgotLy8gCSAqIFRoZSBub2RlIGNyZWF0ZWQgd2lsbCBiZSBjaGFpbmVkIGFjY29yZGluZyB0byBpdHMgbmF0dXJhbCBvcmRlciBvZiByZXF1ZXN0Ci0vLyAJICogcmVjZWl2ZWQuICAlVEJEJSBJdCBjYW4gYmUgcmVjaGFpbmVkIGxhdGVyIHZpYSB0aGUgb3B0aW9uYWwgRFRNIHdyaXRhYmxlIGludGVyZmFjZS4KLS8vIAkgKgotLy8gCSAqIEBwYXJhbSBjaCBBbiBhcnJheSBob2xkaW5nIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBjb21tZW50LgotLy8gCSAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotLy8gCSAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZSBhcnJheS4KLS8vIAkgKiBAc2VlIERUTUV4Y2VwdGlvbgotLy8gCSAqLwotLy8gCXB1YmxpYyBpbnQgY3JlYXRlQ29tbWVudChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLS8vIAl0aHJvd3MgRFRNRXhjZXB0aW9uCi0vLyAJewotLy8gCQltX2NoYXIuYXBwZW5kKGNoLCBzdGFydCwgbGVuZ3RoKTsJCS8vIHN0b3JlIHRoZSBjb21tZW50IHN0cmluZyB0byB0aGUgdGV4dC9jb21tZW50IHN0cmluZyB0YWJsZQotCi0vLyAJCS8vIGNyZWF0ZSBhIENvbW1lbnQgTm9kZQotLy8gCQkvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotLy8gCQlpbnQgdzAgPSBDT01NRU5UX05PREU7Ci0vLyAJCS8vIFcxOiBQYXJlbnQKLS8vIAkJaW50IHcxID0gY3VycmVudFBhcmVudDsKLS8vIAkJLy8gVzI6IFN0YXJ0IHBvc2l0aW9uIHdpdGhpbiBtX2NoYXIKLS8vIAkJaW50IHcyID0gY2hhclN0cmluZ1N0YXJ0OwotLy8gCQkvLyBXMzogTGVuZ3RoIG9mIHRoZSBmdWxsIHN0cmluZwotLy8gCQlpbnQgdzMgPSBsZW5ndGg7Ci0vLyAJCWludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0vLyAJCXByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7Ci0KLS8vIAkJY2hhclN0cmluZ1N0YXJ0PW1fY2hhci5sZW5ndGgoKTsKLS8vIAkJY2hhclN0cmluZ0xlbmd0aCA9IDA7Ci0vLyAJCXJldHVybiAobV9kb2NIYW5kbGUgfCBvdXJzbG90KTsKLS8vIAl9Ci0KLS8vIAkvLyBDb3VudGVycyB0byBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IHRleHQgc3RyaW5nIGJlaW5nIGFjY3VtdWxhdGVkIHdpdGggcmVzcGVjdAotLy8gCS8vIHRvIHRoZSB0ZXh0L2NvbW1lbnQgc3RyaW5nIHRhYmxlOiBjaGFyU3RyaW5nU3RhcnQgc2hvdWxkIHBvaW50IHRvIHRoZSBzdGFydGluZwotLy8gCS8vIG9mZnNldCBvZiB0aGUgc3RyaW5nIGluIHRoZSB0YWJsZSBhbmQgY2hhclN0cmluZ0xlbmd0aCB0aGUgYWNjY3VtdWxhdGVkIGxlbmd0aCB3aGVuCi0vLyAJLy8gYXBwZW5kQWNjdW11bGF0ZWRUZXh0IHN0YXJ0cywgYW5kIHJlc2V0IHRvIHRoZSBlbmQgb2YgdGhlIHRhYmxlIGFuZCAwIGF0IHRoZSBlbmQKLS8vIAkvLyBvZiBhcHBlbmRBY2N1bXVsYXRlZFRleHQgZm9yIHRoZSBuZXh0IHNldCBvZiBjaGFyYWN0ZXJzIHJlY2VpdmVzCi0vLyAJaW50IGNoYXJTdHJpbmdTdGFydD0wLGNoYXJTdHJpbmdMZW5ndGg9MDsKLQotICAgICAgICAvLyA9PT09PT09PT0gRG9jdW1lbnQgTmF2aWdhdGlvbiBGdW5jdGlvbnMgPT09PT09PT09Ci0KLSAgICAgICAgLyoqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHRlc3QgaWYgaXQgaGFzIGNoaWxkIG5vZGVzLgotICAgICAgICAgKiA8cD4gJVJFVklFVyUgVGhpcyBpcyBvYnZpb3VzbHkgdXNlZnVsIGF0IHRoZSBET00gbGF5ZXIsIHdoZXJlIGl0Ci0gICAgICAgICAqIHdvdWxkIHBlcm1pdCB0ZXN0aW5nIHRoaXMgd2l0aG91dCBoYXZpbmcgdG8gY3JlYXRlIGEgcHJveHkKLSAgICAgICAgICogbm9kZS4gSXQncyBsZXNzIHVzZWZ1bCBpbiB0aGUgRFRNIEFQSSwgd2hlcmUKLSAgICAgICAgICogKGR0bS5nZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpIT1EVE0uTlVMTCkgaXMganVzdCBhcyBmYXN0IGFuZAotICAgICAgICAgKiBhbG1vc3QgYXMgc2VsZi1ldmlkZW50LiBCdXQgaXQncyBhIGNvbnZlbmllbmNlLCBhbmQgZWFzZXMgcG9ydGluZwotICAgICAgICAgKiBvZiBET00gY29kZSB0byBEVE0uICA8L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IHRydWUgaWYgdGhlIGdpdmVuIG5vZGUgaGFzIGNoaWxkIG5vZGVzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGROb2RlcyhpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIHJldHVybihnZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpICE9IE5VTEwpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGdldCB0aGUgaGFuZGxlIG9mIHRoZSBub2RlJ3MgZmlyc3QgY2hpbGQuCi0gICAgICAgICAqIElmIG5vdCB5ZXQgcmVzb2x2ZWQsIHdhaXRzIGZvciBtb3JlIG5vZGVzIHRvIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhbmQKLSAgICAgICAgICogdHJpZXMgYWdhaW4uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IERUTSBub2RlLW51bWJlciBvZiBmaXJzdCBjaGlsZCwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldEZpcnN0Q2hpbGQoaW50IG5vZGVIYW5kbGUpIHsKLQotICAgICAgICAgICAgICAgIC8vICMjI3NocyB3b3JyeSBhYm91dCB0cmFjaW5nL2RlYnVnIGxhdGVyCi0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgLy8gUmVhZCBub2RlIGludG8gdmFyaWFibGUKLSAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChub2RlSGFuZGxlLCBnb3RzbG90KTsKLQotICAgICAgICAgICAgICAgIC8vIHR5cGUgaXMgdGhlIGxhc3QgaGFsZiBvZiBmaXJzdCBzbG90Ci0gICAgICAgICAgICAgICAgc2hvcnQgdHlwZSA9IChzaG9ydCkgKGdvdHNsb3RbMF0gJiAweEZGRkYpOwotCi0gICAgICAgICAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIEVsZW1lbnQgb3IgRG9jdW1lbnQgbm9kZQotICAgICAgICAgICAgICAgIGlmICgodHlwZSA9PSBFTEVNRU5UX05PREUpIHx8ICh0eXBlID09IERPQ1VNRU5UX05PREUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0eXBlID09IEVOVElUWV9SRUZFUkVOQ0VfTk9ERSkpIHsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW4gY2FzZSB3aGVuIERvY3VtZW50IHJvb3QgaXMgZ2l2ZW4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vCWlmIChub2RlSGFuZGxlID09IDApIG5vZGVIYW5kbGUgPSAxOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gJVRCRCUgUHJvYmFibHkgd2FzIGEgbWlzdGFrZS4KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHNvbWVvbmUgZXhwbGljaXRseSBhc2tzIGZvciBmaXJzdCBjaGlsZAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgRG9jdW1lbnQsIEkgd291bGQgZXhwZWN0IHRoZW0gdG8gd2FudAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCBhbmQgb25seSB0aGF0LgotCi0gICAgICAgICAgICAgICAgICAgICAgICBpbnQga2lkID0gbm9kZUhhbmRsZSArIDE7Ci0gICAgICAgICAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChraWQsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKEFUVFJJQlVURV9OT0RFID09IChnb3RzbG90WzBdICYgMHhGRkZGKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwb2ludHMgdG8gbmV4dCBzaWJsaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpZCA9IGdvdHNsb3RbMl07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldHVybiBOVUxMIGlmIG5vZGUgaGFzIG9ubHkgYXR0cmlidXRlcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2lkID09IE5VTEwpIHJldHVybiBOVUxMOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChraWQsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgcGFyZW50IHNsb3QgbWF0Y2hlcyBnaXZlbiBwYXJlbnQsIHJldHVybiBraWQKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnb3RzbG90WzFdID09IG5vZGVIYW5kbGUpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaXJzdENoaWxkID0ga2lkIHwgbV9kb2NIYW5kbGU7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpcnN0Q2hpbGQ7Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIE5vIGNoaWxkIGZvdW5kCi0KLSAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIGxhc3QgY2hpbGQuCi0gICAgICAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgICAgICAqIHRyaWVzIGFnYWluLgotICAgICAgICAqCi0gICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZS4KLSAgICAgICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBsYXN0IGNoaWxkLAotICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldExhc3RDaGlsZChpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIC8vICMjI3NocyBwdXQgdHJhY2UvZGVidWcgbGF0ZXIKLSAgICAgICAgICAgICAgICBub2RlSGFuZGxlICY9IE5PREVIQU5ETEVfTUFTSzsKLSAgICAgICAgICAgICAgICAvLyBkbyBub3QgbmVlZCB0byB0ZXN0IG5vZGUgdHlwZSBzaW5jZSBnZXRGaXJzdENoaWxkIGRvZXMgdGhhdAotICAgICAgICAgICAgICAgIGludCBsYXN0Q2hpbGQgPSBOVUxMOwotICAgICAgICAgICAgICAgIGZvciAoaW50IG5leHRraWQgPSBnZXRGaXJzdENoaWxkKG5vZGVIYW5kbGUpOyBuZXh0a2lkICE9IE5VTEw7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRraWQgPSBnZXROZXh0U2libGluZyhuZXh0a2lkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbGFzdENoaWxkID0gbmV4dGtpZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RDaGlsZCB8IG1fZG9jSGFuZGxlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHJpZXZlcyBhbiBhdHRyaWJ1dGUgbm9kZSBieSBieSBxdWFsaWZpZWQgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgaW50IEhhbmRsZSBvZiB0aGUgbm9kZSB1cG9uIHdoaWNoIHRvIGxvb2sgdXAgdGhpcyBhdHRyaWJ1dGUuCi0gICAgICAgICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0bwotICAgICAgICAgKiAgIHJldHJpZXZlLCBvciBudWxsLgotICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAgICAgICAqICAgcmV0cmlldmUuCi0gICAgICAgICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlIGhhbmRsZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSAoCi0gICAgICAgICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvciA8Y29kZT5EVE0uTlVMTDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAotICAgICAgICAgKiAgIGF0dHJpYnV0ZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShpbnQgbm9kZUhhbmRsZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIG5hbWUpIHsKLSAgICAgICAgICAgICAgICBpbnQgbnNJbmRleCA9IG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KG5hbWVzcGFjZVVSSSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lSW5kZXggPSBtX2xvY2FsTmFtZXMuc3RyaW5nVG9JbmRleChuYW1lKTsKLSAgICAgICAgICAgICAgICBub2RlSGFuZGxlICY9IE5PREVIQU5ETEVfTUFTSzsKLSAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChub2RlSGFuZGxlLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgLy8gSWYgbm9kZUhhbmRsZSBwb2ludHMgdG8gZWxlbWVudCBuZXh0IHNsb3Qgd291bGQgYmUgZmlyc3QgYXR0cmlidXRlCi0gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gRUxFTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZSsrOwotICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBBdHRyaWJ1dGUgTm9kZXMKLSAgICAgICAgICAgICAgICB3aGlsZSAodHlwZSA9PSBBVFRSSUJVVEVfTk9ERSkgewotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuc0luZGV4ID09IChnb3RzbG90WzBdIDw8IDE2KSkgJiYgKGdvdHNsb3RbM10gPT0gbmFtZUluZGV4KSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVIYW5kbGUgfCBtX2RvY0hhbmRsZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdvdG8gbmV4dCBzaWJsaW5nCi0gICAgICAgICAgICAgICAgICAgICAgICBub2RlSGFuZGxlID0gZ290c2xvdFsyXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBnZXQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MgZmlyc3QgYXR0cmlidXRlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBFbGVtZW50IG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gSGFuZGxlIG9mIGZpcnN0IGF0dHJpYnV0ZSwgb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldEZpcnN0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0KLSAgICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBqams6IEp1c3QgYSBxdWljayBvYnNlcnZhdGlvbjogSWYgeW91J3JlIGdvaW5nIHRvCi0gICAgICAgICAgICAgICAgLy8gY2FsbCByZWFkRW50cnkgcmVwZWF0ZWRseSBvbiB0aGUgc2FtZSBub2RlLCBpdCBtYXkgYmUKLSAgICAgICAgICAgICAgICAvLyBtb3JlIGVmZmljaWVudGx5IHRvIGRvIGEgcmVhZFNsb3QgdG8gZ2V0IHRoZSBkYXRhIGxvY2FsbHksCi0gICAgICAgICAgICAgICAgLy8gcmVkdWNpbmcgdGhlIGFkZHJlc3NpbmcgYW5kIGNhbGwtYW5kLXJldHVybiBvdmVyaGVhZC4KLQotICAgICAgICAgICAgICAgIC8vIFNob3VsZCB3ZSBjaGVjayBpZiBoYW5kbGUgaXMgZWxlbWVudCAoZG8gd2Ugd2FudCBzYW5pdHkgY2hlY2tzPykKLSAgICAgICAgICAgICAgICBpZiAoRUxFTUVOVF9OT0RFICE9IChub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMCkgJiAweEZGRkYpKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgICAgICAgICAgLy8gRmlyc3QgQXR0cmlidXRlIChpZiBhbnkpIHNob3VsZCBiZSBhdCBuZXh0IHBvc2l0aW9uIGluIHRhYmxlCi0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSsrOwotICAgICAgICAgICAgICAgIHJldHVybihBVFRSSUJVVEVfTk9ERSA9PSAobm9kZXMucmVhZEVudHJ5KG5vZGVIYW5kbGUsIDApICYgMHhGRkZGKSkgPwotICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgfCBtX2RvY0hhbmRsZSA6IE5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgZ2V0IHRoZSBpbmRleCBvZiB0aGUgbm9kZSdzIGZpcnN0IGNoaWxkLgotICAgICAgICAgKiBJZiBub3QgeWV0IHJlc29sdmVkLCB3YWl0cyBmb3IgbW9yZSBub2RlcyB0byBiZSBhZGRlZCB0byB0aGUgZG9jdW1lbnQgYW5kCi0gICAgICAgICAqIHRyaWVzIGFnYWluCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIGhhbmRsZSB0byBub2RlLCB3aGljaCBzaG91bGQgcHJvYmFibHkgYmUgYW4gZWxlbWVudAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICBub2RlLCBidXQgbmVlZCBub3QgYmUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBpblNjb3BlICAgIHRydWUgaWYgYWxsIG5hbWVzcGFjZXMgaW4gc2NvcGUgc2hvdWxkIGJlIHJldHVybmVkLAotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICBmYWxzZSBpZiBvbmx5IHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIHNob3VsZCBiZQotICAgICAgICAgKiAgICAgICAgICAgICAgICAgICByZXR1cm5lZC4KLSAgICAgICAgICogQHJldHVybiBoYW5kbGUgb2YgZmlyc3QgbmFtZXNwYWNlLCBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKGludCBub2RlSGFuZGxlLCBib29sZWFuIGluU2NvcGUpIHsKLQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIG5leHQgc2libGluZy4KLSAgICAgICAgICoKLSAgICAgICAgICogJVRCRCUgVGhpcyBjdXJyZW50bHkgdXNlcyB0aGUgRFRNLWludGVybmFsIGRlZmluaXRpb24gb2YKLSAgICAgICAgICogc2libGluZzsgZWcsIHRoZSBsYXN0IGF0dHIncyBuZXh0IHNpYiBpcyB0aGUgZmlyc3QKLSAgICAgICAgICogY2hpbGQuIEluIHRoZSBvbGQgRFRNLCB0aGUgRE9NIHByb3h5IGxheWVyIHByb3ZpZGVkIHRoZQotICAgICAgICAgKiBhZGRpdGlvbmFsIGxvZ2ljIGZvciB0aGUgcHVibGljIHZpZXcuICBJZiB3ZSdyZSByZXdyaXRpbmcKLSAgICAgICAgICogZm9yIFhQYXRoIGVtdWxhdGlvbiwgdGhhdCB0ZXN0IG11c3QgYmUgZG9uZSBoZXJlLgotICAgICAgICAgKgotICAgICAgICAgKiAlVEJEJSBDT0RFIElOVEVSQUNUSU9OIFdJVEggSU5DUkVNRU5UQUwgUEFSU0UgLSBJZiBub3QgeWV0Ci0gICAgICAgICAqIHJlc29sdmVkLCBzaG91bGQgd2FpdCBmb3IgbW9yZSBub2RlcyB0byBiZSBhZGRlZCB0byB0aGUgZG9jdW1lbnQKLSAgICAgICAgICogYW5kIHRyaWVzIGFnYWluLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGludCBOb2RlLW51bWJlciBvZiBuZXh0IHNpYmxpbmcsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKiAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE5leHRTaWJsaW5nKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgLy8gRG9jdW1lbnQgcm9vdCBoYXMgbm8gbmV4dCBzaWJsaW5nCi0gICAgICAgICAgICAgICAgaWYgKG5vZGVIYW5kbGUgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgICAgICAgc2hvcnQgdHlwZSA9IChzaG9ydCkgKG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAwKSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgaWYgKCh0eXBlID09IEVMRU1FTlRfTk9ERSkgfHwgKHR5cGUgPT0gQVRUUklCVVRFX05PREUpIHx8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0eXBlID09IEVOVElUWV9SRUZFUkVOQ0VfTk9ERSkpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXh0U2liID0gbm9kZXMucmVhZEVudHJ5KG5vZGVIYW5kbGUsIDIpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRTaWIgPT0gTlVMTCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFNpYiAhPSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG1fZG9jSGFuZGxlIHwgbmV4dFNpYik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAjIyNzaHMgc2hvdWxkIGN5Y2xlL3dhaXQgaWYgbmV4dFNpYiBpcyAwPyBXb3JraW5nIG9uIHRocmVhZGluZyBuZXh0Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIC8vIE5leHQgU2libGluZyBpcyBpbiB0aGUgbmV4dCBwb3NpdGlvbiBpZiBpdCBzaGFyZXMgdGhlIHNhbWUgcGFyZW50Ci0gICAgICAgICAgICAgICAgaW50IHRoaXNQYXJlbnQgPSBub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAobm9kZXMucmVhZEVudHJ5KCsrbm9kZUhhbmRsZSwgMSkgPT0gdGhpc1BhcmVudCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBub2RlSGFuZGxlKTsKLQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgaXRzIHByZWNlZWRpbmcgc2libGluZy4KLSAgICAgICAgICogV0FSTklORzogRFRNIGlzIGFzeW1tZXRyaWM7IHRoaXMgb3BlcmF0aW9uIGlzIHJlc29sdmVkIGJ5IHNlYXJjaCwgYW5kIGlzCi0gICAgICAgICAqIHJlbGF0aXZlbHkgZXhwZW5zaXZlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIHRoZSBwcmV2aW91cyBzaWIsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXRQcmV2aW91c1NpYmxpbmcoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICBub2RlSGFuZGxlICY9IE5PREVIQU5ETEVfTUFTSzsKLSAgICAgICAgICAgICAgICAvLyBEb2N1bWVudCByb290IGhhcyBubyBwcmV2aW91cyBzaWJsaW5nCi0gICAgICAgICAgICAgICAgaWYgKG5vZGVIYW5kbGUgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotCi0gICAgICAgICAgICAgICAgaW50IHBhcmVudCA9IG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAxKTsKLSAgICAgICAgICAgICAgICBpbnQga2lkID0gTlVMTDsKLSAgICAgICAgICAgICAgICBmb3IgKGludCBuZXh0a2lkID0gZ2V0Rmlyc3RDaGlsZChwYXJlbnQpOyBuZXh0a2lkICE9IG5vZGVIYW5kbGU7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRraWQgPSBnZXROZXh0U2libGluZyhuZXh0a2lkKSkgewotICAgICAgICAgICAgICAgICAgICAgICAga2lkID0gbmV4dGtpZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGtpZCB8IG1fZG9jSGFuZGxlOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gdGhlIG5leHQgYXR0cmlidXRlLiBJZiBhbgotICAgICAgICAgKiBlbGVtZW50LCB3ZSBhZHZhbmNlIHRvIGl0cyBmaXJzdCBhdHRyaWJ1dGU7IGlmIGFuIGF0dHIsIHdlIGFkdmFuY2UgdG8KLSAgICAgICAgICogdGhlIG5leHQgYXR0ciBvbiB0aGUgc2FtZSBub2RlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGludCBEVE0gbm9kZS1udW1iZXIgb2YgdGhlIHJlc29sdmVkIGF0dHIsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXROZXh0QXR0cmlidXRlKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgbm9kZUhhbmRsZSAmPSBOT0RFSEFORExFX01BU0s7Ci0gICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSwgZ290c2xvdCk7Ci0KLSAgICAgICAgICAgICAgICAvLyVSRVZJRVclIFdoeSBhcmUgd2UgdXNpbmcgc2hvcnQgaGVyZT8gVGhlcmUncyBubyBzdG9yYWdlCi0gICAgICAgICAgICAgICAgLy9yZWR1Y3Rpb24gZm9yIGFuIGF1dG9tYXRpYyB2YXJpYWJsZSwgZXNwZWNpYWxseSBvbmUgdXNlZAotICAgICAgICAgICAgICAgIC8vc28gYnJpZWZseSwgYW5kIGl0IHR5cGljYWxseSBjb3N0cyBtb3JlIGN5Y2xlcyB0byBwcm9jZXNzCi0gICAgICAgICAgICAgICAgLy90aGFuIGFuIGludCB3b3VsZC4KLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0KLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBFTEVNRU5UX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRGaXJzdEF0dHJpYnV0ZShub2RlSGFuZGxlKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnb3RzbG90WzJdICE9IE5VTEwpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBnb3RzbG90WzJdKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBuYW1lc3BhY2UgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IG5hbWVzcGFjZS4KLSAgICAgICAgICoKLSAgICAgICAgICogJVRCRCUgVEhJUyBNRVRIT0QgRE9FUyBOT1QgTUFUQ0ggVEhFIENVUlJFTlQgU0lHTkFUVVJFIElOCi0gICAgICAgICAqIFRIRSBEVE0gSU5URVJGQUNFLiAgRklYIElULCBPUiBKVVNUSUZZIENIQU5HSU5HIFRIRSBEVE0KLSAgICAgICAgICogQVBJLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbmFtZXNwYWNlSGFuZGxlIGhhbmRsZSB0byBub2RlIHdoaWNoIG11c3QgYmUgb2YgdHlwZSBOQU1FU1BBQ0VfTk9ERS4KLSAgICAgICAgICogQHJldHVybiBoYW5kbGUgb2YgbmV4dCBuYW1lc3BhY2UsIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXROZXh0TmFtZXNwYWNlTm9kZShpbnQgYmFzZUhhbmRsZSxpbnQgbmFtZXNwYWNlSGFuZGxlLCBib29sZWFuIGluU2NvcGUpIHsKLSAgICAgICAgICAgICAgICAvLyAjIyNzaHMgbmVlZCB0byB3b3JrIG9uIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gaXRzIG5leHQgZGVzY2VuZGFudC4KLSAgICAgICAgICogSWYgbm90IHlldCByZXNvbHZlZCwgd2FpdHMgZm9yIG1vcmUgbm9kZXMgdG8gYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGFuZAotICAgICAgICAgKiB0cmllcyBhZ2Fpbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIHN1YnRyZWVSb290Tm9kZUhhbmRsZQotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIGhhbmRsZSBvZiBuZXh0IGRlc2NlbmRhbnQsCi0gICAgICAgICAqIG9yIERUTS5OVUxMIHRvIGluZGljYXRlIG5vbmUgZXhpc3RzLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGludCBnZXROZXh0RGVzY2VuZGFudChpbnQgc3VidHJlZVJvb3RIYW5kbGUsIGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgc3VidHJlZVJvb3RIYW5kbGUgJj0gTk9ERUhBTkRMRV9NQVNLOwotICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgJj0gTk9ERUhBTkRMRV9NQVNLOwotICAgICAgICAgICAgICAgIC8vIERvY3VtZW50IHJvb3QgW0RvY3VtZW50IE5vZGU/IC0tIGpqa10gLSBubyBuZXh0LXNpYgotICAgICAgICAgICAgICAgIGlmIChub2RlSGFuZGxlID09IDApCi0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgICAgICAgICB3aGlsZSAoIW1faXNFcnJvcikgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9jdW1lbnQgZG9uZSBhbmQgbm9kZSBvdXQgb2YgYm91bmRzCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSAmJiAobm9kZUhhbmRsZSA+IG5vZGVzLnNsb3RzVXNlZCgpKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUhhbmRsZSA+IHN1YnRyZWVSb290SGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUrMSwgZ290c2xvdCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnb3RzbG90WzJdICE9IDApIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gQVRUUklCVVRFX05PREUpIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgKz0yOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmV4dFBhcmVudFBvcyA9IGdvdHNsb3RbMV07Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFBhcmVudFBvcyA+PSBzdWJ0cmVlUm9vdEhhbmRsZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChtX2RvY0hhbmRsZSB8IChub2RlSGFuZGxlKzEpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFkb25lKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWRkIHdhaXQgbG9naWMgaGVyZQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUrKzsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gUHJvYmFibHkgc2hvdWxkIHRocm93IGVycm9yIGhlcmUgbGlrZSBvcmlnaW5hbCBpbnN0ZWFkIG9mIHJldHVybmluZwotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGFkdmFuY2UgdG8gdGhlIG5leHQgbm9kZSBvbiB0aGUgZm9sbG93aW5nIGF4aXMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBheGlzQ29udGV4dEhhbmRsZSB0aGUgc3RhcnQgb2YgdGhlIGF4aXMgdGhhdCBpcyBiZWluZyB0cmF2ZXJzZWQuCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlCi0gICAgICAgICAqIEByZXR1cm4gaGFuZGxlIG9mIG5leHQgc2libGluZywKLSAgICAgICAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE5leHRGb2xsb3dpbmcoaW50IGF4aXNDb250ZXh0SGFuZGxlLCBpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIC8vIyMjc2hzIHN0aWxsIHdvcmtpbmcgb24KLSAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBhZHZhbmNlIHRvIHRoZSBuZXh0IG5vZGUgb24gdGhlIHByZWNlZGluZyBheGlzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gYXhpc0NvbnRleHRIYW5kbGUgdGhlIHN0YXJ0IG9mIHRoZSBheGlzIHRoYXQgaXMgYmVpbmcgdHJhdmVyc2VkLgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIHByZWNlZGluZyBzaWJsaW5nLAotICAgICAgICAgKiBvciBEVE0uTlVMTCB0byBpbmRpY2F0ZSBub25lIGV4aXN0cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0TmV4dFByZWNlZGluZyhpbnQgYXhpc0NvbnRleHRIYW5kbGUsIGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgICAgICAgLy8gIyMjc2hzIGNvcGllZCBmcm9tIFhhbGFuIDEsIHdoYXQgaXMgdGhpcyBzdXBwb3NlIHRvIGRvPwotICAgICAgICAgICAgICAgIG5vZGVIYW5kbGUgJj0gTk9ERUhBTkRMRV9NQVNLOwotICAgICAgICAgICAgICAgIHdoaWxlIChub2RlSGFuZGxlID4gMSkgewotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZS0tOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFUVFJJQlVURV9OT0RFID09IChub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMCkgJiAweEZGRkYpKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgbm9kZUhhbmRsZSBpcyBfbm90XyBhbiBhbmNlc3RvciBvZgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXhpc0NvbnRleHRIYW5kbGUsIHNwZWNpYWxGaW5kIHdpbGwgcmV0dXJuIGl0LgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgaXQgX2lzXyBhbiBhbmNlc3Rvciwgc3BlY2lhbEZpbmQgd2lsbCByZXR1cm4gLTEKLQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gJVJFVklFVyUgdW5jb25kaXRpb25hbCByZXR1cm4gZGVmZWF0cyB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHB1cnBvc2Ugb2YgdGhlIHdoaWxlIGxvb3AgLS0gZG9lcyB0aGlzCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2dpYyBtYWtlIGFueSBzZW5zZT8KLQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChtX2RvY0hhbmRsZSB8IG5vZGVzLnNwZWNpYWxGaW5kKGF4aXNDb250ZXh0SGFuZGxlLCBub2RlSGFuZGxlKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIGZpbmQgaXRzIHBhcmVudCBub2RlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUtbnVtYmVyIG9mIHBhcmVudCwKLSAgICAgICAgICogb3IgRFRNLk5VTEwgdG8gaW5kaWNhdGUgbm9uZSBleGlzdHMuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldFBhcmVudChpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIC8vIFNob3VsZCBjaGVjayB0byBzZWUgd2l0aGluIHJhbmdlPwotCi0gICAgICAgICAgICAgICAgLy8gRG9jdW1lbnQgUm9vdCBzaG91bGQgbm90IGhhdmUgdG8gYmUgaGFuZGxlZCBkaWZmZXJlbnRseQotICAgICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBub2Rlcy5yZWFkRW50cnkobm9kZUhhbmRsZSwgMSkpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybnMgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAqIEByZXR1cm4gbm9kZUhhbmRsZSB0byB0aGUgRG9jdW1lbnQgUm9vdC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0RG9jdW1lbnRSb290KCkgewotICAgICAgICAgICAgICAgIHJldHVybiAobV9kb2NIYW5kbGUgfCBtX2RvY0VsZW1lbnQpOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIHRoZSBvd25pbmcgZG9jdW1lbnQgbm9kZS4KLSAgICAgICAgICAgICAgICAqCi0gICAgICAgICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAgICAgICAgKiBAcmV0dXJuIGludCBOb2RlIGhhbmRsZSBvZiBkb2N1bWVudCwgd2hpY2ggc2hvdWxkIGFsd2F5cyBiZSB2YWxpZC4KLSAgICAgICAgICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldERvY3VtZW50KCkgewotICAgICAgICAgICAgICAgIHJldHVybiBtX2RvY0hhbmRsZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCBmaW5kIHRoZSBvd25pbmcgZG9jdW1lbnQgbm9kZS4gIFRoaXMgaGFzIHRoZSBleGFjdAotICAgICAgICAgKiBzYW1lIHNlbWFudGljcyBhcyB0aGUgRE9NIERvY3VtZW50IG1ldGhvZCBvZiB0aGUgc2FtZSBuYW1lLCBpbiB0aGF0IGlmCi0gICAgICAgICAqIHRoZSBub2RlSGFuZGxlIGlzIGEgZG9jdW1lbnQgbm9kZSwgaXQgd2lsbCByZXR1cm4gTlVMTC4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+JVJFVklFVyUgU2luY2UgdGhpcyBpcyBET00tc3BlY2lmaWMsIGl0IG1heSBiZWxvbmcgYXQgdGhlIERPTQotICAgICAgICAgKiBiaW5kaW5nIGxheWVyLiBJbmNsdWRlZCBoZXJlIGFzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gYW5kIHRvCi0gICAgICAgICAqIGFpZCBwb3J0aW5nIG9mIERPTSBjb2RlIHRvIERUTS48L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBpbnQgTm9kZSBoYW5kbGUgb2Ygb3duaW5nIGRvY3VtZW50LCBvciBOVUxMIGlmIHRoZSBub2RlSGFuZGxlIGlzCi0gICAgICAgICAqICAgICAgICAgICAgIGEgZG9jdW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldE93bmVyRG9jdW1lbnQoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICAvLyBBc3N1bXB0aW9uIHRoYXQgRG9jdW1lbnQgTm9kZSBpcyBhbHdheXMgaW4gMCBzbG90Ci0gICAgICAgICAgICAgICAgaWYgKChub2RlSGFuZGxlICYgTk9ERUhBTkRMRV9NQVNLKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChub2RlSGFuZGxlICYgRE9DSEFORExFX01BU0spOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2V0IHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlIGFzIGEgU3RyaW5nIG9iamVjdAotICAgICAgICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICAgICAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBYTUxTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgLy8gIyMjemFqIC0gcmVzZWFyY2hpbmcKLSAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSwgZ290c2xvdCk7Ci0gICAgICAgIGludCBub2RldHlwZT1nb3RzbG90WzBdICYgMHhGRjsKLSAgICAgICAgU3RyaW5nIHZhbHVlPW51bGw7Ci0KLSAgICAgICAgc3dpdGNoIChub2RldHlwZSkgewotICAgICAgICBjYXNlIFRFWFRfTk9ERToKLSAgICAgICAgY2FzZSBDT01NRU5UX05PREU6Ci0gICAgICAgIGNhc2UgQ0RBVEFfU0VDVElPTl9OT0RFOgotICAgICAgICAgICAgICAgIHZhbHVlPSBtX2NoYXIuZ2V0U3RyaW5nKGdvdHNsb3RbMl0sIGdvdHNsb3RbM10pOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERToKLSAgICAgICAgY2FzZSBBVFRSSUJVVEVfTk9ERToKLSAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6Ci0gICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOgotICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIHJldHVybiBtX3hzZi5uZXdzdHIoIHZhbHVlICk7Ci0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHZXQgbnVtYmVyIG9mIGNoYXJhY3RlciBhcnJheSBjaHVua3MgaW4KLSAgICAgICAgICogdGhlIHN0cmluZy12YWx1ZSBvZiBhIG5vZGUuCi0gICAgICAgICAqIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgICAgICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4KLSAgICAgICAgICogTm90ZSB0aGF0IGEgc2luZ2xlIHRleHQgbm9kZSBtYXkgaGF2ZSBtdWx0aXBsZSB0ZXh0IGNodW5rcy4KLSAgICAgICAgICoKLSAgICAgICAgICogRVhQTEFOQVRJT046IFRoaXMgbWV0aG9kIGlzIGFuIGFydGlmYWN0IG9mIHRoZSBmYWN0IHRoYXQgdGhlCi0gICAgICAgICAqIHVuZGVybHlpbmcgbV9jaGFycyBvYmplY3QgbWF5IG5vdCBzdG9yZSBjaGFyYWN0ZXJzIGluIGEKLSAgICAgICAgICogc2luZ2xlIGNvbnRpZ3VvdXMgYXJyYXkgLS0gZm9yIGV4YW1wbGUsdGhlIGN1cnJlbnQKLSAgICAgICAgICogRmFzdFN0cmluZ0J1ZmZlciBtYXkgc3BsaXQgYSBzaW5nbGUgbm9kZSdzIHRleHQgYWNyb3NzCi0gICAgICAgICAqIG11bHRpcGxlIGFsbG9jYXRpb24gdW5pdHMuICBUaGlzIGNhbGwgdGVsbHMgdXMgaG93IG1hbnkKLSAgICAgICAgICogc2VwYXJhdGUgYWNjZXNzZXMgd2lsbCBiZSByZXF1aXJlZCB0byByZXRyaWV2ZSB0aGUgZW50aXJlCi0gICAgICAgICAqIGNvbnRlbnQuIFBMRUFTRSBOT1RFIHRoYXQgdGhpcyBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoZQotICAgICAgICAgKiBudW1iZXIgb2YgU0FYIGNoYXJhY3RlcnMoKSBldmVudHMgdGhhdCBjYXVzZWQgdGhlIHRleHQgbm9kZQotICAgICAgICAgKiB0byBiZSBidWlsdCBpbiB0aGUgZmlyc3QgcGxhY2UsIHNpbmNlIG1fY2hhcnMgYnVmZmVyaW5nIG1heQotICAgICAgICAgKiBiZSBvbiBkaWZmZXJlbnQgYm91bmRhcmllcyB0aGFuIHRoZSBwYXJzZXIncyBidWZmZXJzLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBudW1iZXIgb2YgY2hhcmFjdGVyIGFycmF5IGNodW5rcyBpbgotICAgICAgICAgKiAgICAgICAgIHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlLgotICAgICAgICAgKiAqLwotICAgICAgICAvLyMjI3phaiAtIHRiZAotICAgICAgICBwdWJsaWMgaW50IGdldFN0cmluZ1ZhbHVlQ2h1bmtDb3VudChpbnQgbm9kZUhhbmRsZSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIC8vIyMjemFqICAgIHJldHVybiB2YWx1ZQotICAgICAgICAgICAgICAgIHJldHVybiAwOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdldCBhIGNoYXJhY3RlciBhcnJheSBjaHVuayBpbiB0aGUgc3RyaW5nLXZhbHVlIG9mIGEgbm9kZS4KLSAgICAgICAgICogKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAgICAgICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLgotICAgICAgICAgKiBOb3RlIHRoYXQgYSBzaW5nbGUgdGV4dCBub2RlIG1heSBoYXZlIG11bHRpcGxlIHRleHQgY2h1bmtzLgotICAgICAgICAgKgotICAgICAgICAgKiBFWFBMQU5BVElPTjogVGhpcyBtZXRob2QgaXMgYW4gYXJ0aWZhY3Qgb2YgdGhlIGZhY3QgdGhhdAotICAgICAgICAgKiB0aGUgdW5kZXJseWluZyBtX2NoYXJzIG9iamVjdCBtYXkgbm90IHN0b3JlIGNoYXJhY3RlcnMgaW4gYQotICAgICAgICAgKiBzaW5nbGUgY29udGlndW91cyBhcnJheSAtLSBmb3IgZXhhbXBsZSx0aGUgY3VycmVudAotICAgICAgICAgKiBGYXN0U3RyaW5nQnVmZmVyIG1heSBzcGxpdCBhIHNpbmdsZSBub2RlJ3MgdGV4dCBhY3Jvc3MKLSAgICAgICAgICogbXVsdGlwbGUgYWxsb2NhdGlvbiB1bml0cy4gIFRoaXMgY2FsbCByZXRyaWV2ZXMgYSBzaW5nbGUKLSAgICAgICAgICogY29udGlndW91cyBwb3J0aW9uIG9mIHRoZSB0ZXh0IC0tIGFzIG11Y2ggYXMgbS1jaGFycyB3YXMKLSAgICAgICAgICogYWJsZSB0byBzdG9yZSBpbiBhIHNpbmdsZSBhbGxvY2F0aW9uIHVuaXQuICBQTEVBU0UgTk9URQotICAgICAgICAgKiB0aGF0IHRoaXMgbWF5IG5vdCBiZSB0aGUgc2FtZSBncmFudWxhcml0eWFzIHRoZSBTQVgKLSAgICAgICAgICogY2hhcmFjdGVycygpIGV2ZW50cyB0aGF0IGNhdXNlZCB0aGUgdGV4dCBub2RlIHRvIGJlIGJ1aWx0Ci0gICAgICAgICAqIGluIHRoZSBmaXJzdCBwbGFjZSwgc2luY2UgbV9jaGFycyBidWZmZXJpbmcgbWF5IGJlIG9uCi0gICAgICAgICAqIGRpZmZlcmVudCBib3VuZGFyaWVzIHRoYW4gdGhlIHBhcnNlcidzIGJ1ZmZlcnMuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgICAgICAgKiBAcGFyYW0gY2h1bmtJbmRleCBXaGljaCBjaHVuayB0byBnZXQuCi0gICAgICAgICAqIEBwYXJhbSBzdGFydEFuZExlbiBBbiBhcnJheSBvZiAyIHdoZXJlIHRoZSBzdGFydCBwb3NpdGlvbiBhbmQgbGVuZ3RoIG9mCi0gICAgICAgICAqICAgICAgICAgICAgICAgICAgICB0aGUgY2h1bmsgd2lsbCBiZSByZXR1cm5lZC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIGFycmF5IHJlZmVyZW5jZSB3aGVyZSB0aGUgY2h1bmsgb2NjdXJzLiAgKi8KLSAgICAgICAgLy8jIyN6YWogLSB0YmQKLSAgICAgICAgcHVibGljIGNoYXJbXSBnZXRTdHJpbmdWYWx1ZUNodW5rKGludCBub2RlSGFuZGxlLCBpbnQgY2h1bmtJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludFtdIHN0YXJ0QW5kTGVuKSB7cmV0dXJuIG5ldyBjaGFyWzBdO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGFuIElEIHRoYXQgcmVwcmVzZW50cyB0aGUgbm9kZSdzIGV4cGFuZGVkIG5hbWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBoYW5kbGUgdG8gdGhlIG5vZGUgaW4gcXVlc3Rpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIGV4cGFuZGVkLW5hbWUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldEV4cGFuZGVkVHlwZUlEKGludCBub2RlSGFuZGxlKSB7Ci0gICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICBTdHJpbmcgcU5hbWUgPSBtX2xvY2FsTmFtZXMuaW5kZXhUb1N0cmluZyhnb3RzbG90WzNdKTsKLSAgICAgICAgICAgLy8gUmVtb3ZlIHByZWZpeCBmcm9tIHFOYW1lCi0gICAgICAgICAgIC8vICVUQkQlIGpqayBUaGlzIGlzIGFzc3VtaW5nIHRoZSBlbGVtZW50TmFtZSBpcyB0aGUgcU5hbWUuCi0gICAgICAgICAgIGludCBjb2xvbnBvcyA9IHFOYW1lLmluZGV4T2YoIjoiKTsKLSAgICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSA9IHFOYW1lLnN1YnN0cmluZyhjb2xvbnBvcysxKTsKLSAgICAgICAgICAgLy8gR2V0IE5TCi0gICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2UgPSBtX25zTmFtZXMuaW5kZXhUb1N0cmluZyhnb3RzbG90WzBdIDw8IDE2KTsKLSAgICAgICAgICAgLy8gQ3JlYXRlIGV4cGFuZGVkIG5hbWUKLSAgICAgICAgICAgU3RyaW5nIGV4cGFuZGVkTmFtZSA9IG5hbWVzcGFjZSArICI6IiArIGxvY2FsTmFtZTsKLSAgICAgICAgICAgaW50IGV4cGFuZGVkTmFtZUlEID0gbV9uc05hbWVzLnN0cmluZ1RvSW5kZXgoZXhwYW5kZWROYW1lKTsKLQotICAgICAgICByZXR1cm4gZXhwYW5kZWROYW1lSUQ7Ci0gICAgICAgIH0KLQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhbiBleHBhbmRlZCBuYW1lLCByZXR1cm4gYW4gSUQuICBJZiB0aGUgZXhwYW5kZWQtbmFtZSBkb2VzIG5vdAotICAgICAgICAgKiBleGlzdCBpbiB0aGUgaW50ZXJuYWwgdGFibGVzLCB0aGUgZW50cnkgd2lsbCBiZSBjcmVhdGVkLCBhbmQgdGhlIElEIHdpbGwKLSAgICAgICAgICogYmUgcmV0dXJuZWQuICBBbnkgYWRkaXRpb25hbCBub2RlcyB0aGF0IGFyZSBjcmVhdGVkIHRoYXQgaGF2ZSB0aGlzCi0gICAgICAgICAqIGV4cGFuZGVkIG5hbWUgd2lsbCB1c2UgdGhpcyBJRC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIGhhbmRsZSB0byB0aGUgbm9kZSBpbiBxdWVzdGlvbi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiB0aGUgZXhwYW5kZWQtbmFtZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBpbnQgZ2V0RXhwYW5kZWRUeXBlSUQoU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIGxvY2FsTmFtZSwgaW50IHR5cGUpIHsKLSAgICAgICAgICAgLy8gQ3JlYXRlIGV4cGFuZGVkIG5hbWUKLSAgICAgICAgICAvLyAlVEJEJSBqamsgRXhwYW5kZWQgbmFtZSBpcyBiaXRmaWVsZC1lbmNvZGVkIGFzCi0gICAgICAgICAgLy8gdHlwZUlEWzZdbnN1cmlJRFsxMF1sb2NhbElEWzE2XS4gU3dpdGNoIHRvIHRoYXQgZm9ybSwgYW5kIHRvCi0gICAgICAgICAgLy8gYWNjZXNzaW5nIHRoZSBucy9sb2NhbCB2aWEgdGhlaXIgdGFibGVzIHJhdGhlciB0aGFuIGNvbmZ1c2luZwotICAgICAgICAgIC8vIG5zbmFtZXMgYW5kIGV4cGFuZGVkbmFtZXMuCi0gICAgICAgICAgIFN0cmluZyBleHBhbmRlZE5hbWUgPSBuYW1lc3BhY2UgKyAiOiIgKyBsb2NhbE5hbWU7Ci0gICAgICAgICAgIGludCBleHBhbmRlZE5hbWVJRCA9IG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KGV4cGFuZGVkTmFtZSk7Ci0KLSAgICAgICAgICAgcmV0dXJuIGV4cGFuZGVkTmFtZUlEOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZUZyb21FeHBhbmRlZE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpIHsKLQotICAgICAgICAgICAvLyBHZXQgZXhwYW5kZWQgbmFtZQotICAgICAgICAgICBTdHJpbmcgZXhwYW5kZWROYW1lID0gbV9sb2NhbE5hbWVzLmluZGV4VG9TdHJpbmcoRXhwYW5kZWROYW1lSUQpOwotICAgICAgICAgICAvLyBSZW1vdmUgcHJlZml4IGZyb20gZXhwYW5kZWQgbmFtZQotICAgICAgICAgICBpbnQgY29sb25wb3MgPSBleHBhbmRlZE5hbWUuaW5kZXhPZigiOiIpOwotICAgICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gZXhwYW5kZWROYW1lLnN1YnN0cmluZyhjb2xvbnBvcysxKTsKLSAgICAgICAgICAgcmV0dXJuIGxvY2FsTmFtZTsKLSAgICAgICAgfQotCi0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBwYXJ0LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gRXhwYW5kZWROYW1lSUQgYW4gSUQgdGhhdCByZXByZXNlbnRzIGFuIGV4cGFuZGVkLW5hbWUuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICAgICAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGcm9tRXhwYW5kZWROYW1lSUQoaW50IEV4cGFuZGVkTmFtZUlEKSB7Ci0KLSAgICAgICAgICAgU3RyaW5nIGV4cGFuZGVkTmFtZSA9IG1fbG9jYWxOYW1lcy5pbmRleFRvU3RyaW5nKEV4cGFuZGVkTmFtZUlEKTsKLSAgICAgICAgICAgLy8gUmVtb3ZlIGxvY2FsIG5hbWUgZnJvbSBleHBhbmRlZCBuYW1lCi0gICAgICAgICAgIGludCBjb2xvbnBvcyA9IGV4cGFuZGVkTmFtZS5pbmRleE9mKCI6Iik7Ci0gICAgICAgICAgIFN0cmluZyBuc05hbWUgPSBleHBhbmRlZE5hbWUuc3Vic3RyaW5nKDAsIGNvbG9ucG9zKTsKLQotICAgICAgICByZXR1cm4gbnNOYW1lOwotICAgICAgICB9Ci0KLQotICAgICAgICAvKioKLSAgICAgICAgICogZml4ZWRuYW1lcwotICAgICAgICAqLwotICAgICAgICBzdGF0aWMgZmluYWwgU3RyaW5nW10gZml4ZWRuYW1lcz0KLSAgICAgICAgewotICAgICAgICAgICAgICAgIG51bGwsbnVsbCwJCQkJCQkJLy8gbm90aGluZywgRWxlbWVudAotICAgICAgICAgICAgICAgIG51bGwsIiN0ZXh0IiwJCQkJCQkvLyBBdHRyLCBUZXh0Ci0gICAgICAgICAgICAgICAgIiNjZGF0YV9zZWN0aW9uIixudWxsLAkvLyBDREFUQSwgRW50aXR5UmVmZXJlbmNlCi0gICAgICAgICAgICAgICAgbnVsbCxudWxsLAkJCQkJCQkvLyBFbnRpdHksIFBJCi0gICAgICAgICAgICAgICAgIiNjb21tZW50IiwiI2RvY3VtZW50IiwJLy8gQ29tbWVudCwgRG9jdW1lbnQKLSAgICAgICAgICAgICAgICBudWxsLCIjZG9jdW1lbnQtZnJhZ21lbnQiLCAvLyBEb2N0eXBlLCBEb2N1bWVudEZyYWdtZW50Ci0gICAgICAgICAgICAgICAgbnVsbH07CQkJCQkJCQkJLy8gTm90YXRpb24KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbm9kZSBuYW1lLiBUaGlzIHdpbGwKLSAgICAgICAgICogaW5jbHVkZSBuYW1lcyBzdWNoIGFzICN0ZXh0IG9yICNkb2N1bWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyBOYW1lIG9mIHRoaXMgbm9kZSwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZy4KLSAgICAgICAgICogJVJFVklFVyUgRG9jdW1lbnQgd2hlbiBlbXB0eSBzdHJpbmcgaXMgcG9zc2libGUuLi4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChub2RlSGFuZGxlLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBmaXhlZG5hbWVzW3R5cGVdOwotICAgICAgICAgICAgICAgIGlmIChudWxsID09IG5hbWUpIHsKLSAgICAgICAgICAgICAgICAgIGludCBpPWdvdHNsb3RbM107Ci0gICAgICAgICAgICAgICAgICAvKiovU3lzdGVtLm91dC5wcmludGxuKCJnb3QgaT0iK2krIiAiKyhpPj4xNikrIi8iKyhpJjB4ZmZmZikpOwotCi0gICAgICAgICAgICAgICAgICBuYW1lPW1fbG9jYWxOYW1lcy5pbmRleFRvU3RyaW5nKGkgJiAweEZGRkYpOwotICAgICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeD1tX3ByZWZpeE5hbWVzLmluZGV4VG9TdHJpbmcoaSA+PjE2KTsKLSAgICAgICAgICAgICAgICAgIGlmKHByZWZpeCE9bnVsbCAmJiBwcmVmaXgubGVuZ3RoKCk+MCkKLSAgICAgICAgICAgICAgICAgICAgbmFtZT1wcmVmaXgrIjoiK25hbWU7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgWFBhdGggbm9kZSBuYW1lLiAgVGhpcyBzaG91bGQgYmUKLSAgICAgICAgICogdGhlIG5hbWUgYXMgZGVzY3JpYmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsLCBOT1QgdGhlIERPTS1zdHlsZQotICAgICAgICAgKiBuYW1lLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoaW50IG5vZGVIYW5kbGUpIHtyZXR1cm4gbnVsbDt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIGxvY2FsbmFtZS4KLSAgICAgICAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgcG9ydGlvbiBvZiB0aGUgbmFtZSBhZnRlciBhbnkKLSAgICAgICAgICogY29sb24gY2hhcmFjdGVyKQotICAgICAgICAgKgotICAgICAgICAgKiAlUkVWSUVXJSBXaGF0J3MgdGhlIGxvY2FsIG5hbWUgb2Ygc29tZXRoaW5nIG90aGVyIHRoYW4gRWxlbWVudC9BdHRyPwotICAgICAgICAgKiBTaG91bGQgdGhpcyBiZSBET00tc3R5bGUgKHVuZGVmaW5lZCB1bmxlc3MgbmFtZXNwYWNlZCksIG9yIG90aGVyPwotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIExvY2FsIG5hbWUgb2YgdGhpcyBub2RlLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChub2RlSGFuZGxlLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSAiIjsKLSAgICAgICAgICAgICAgICBpZiAoKHR5cGU9PUVMRU1FTlRfTk9ERSkgfHwgKHR5cGU9PUFUVFJJQlVURV9OT0RFKSkgewotICAgICAgICAgICAgICAgICAgaW50IGk9Z290c2xvdFszXTsKLSAgICAgICAgICAgICAgICAgIG5hbWU9bV9sb2NhbE5hbWVzLmluZGV4VG9TdHJpbmcoaSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgICBpZihuYW1lPT1udWxsKSBuYW1lPSIiOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHRoYXQgdGhlIG5hbWVzcGFjZSBkZWNsIGlzCi0gICAgICAgICAqIG1hcHBpbmcuCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHVzZWQgdG8gbWFwIHRvIHRoZSBuYW1lc3BhY2UuCi0gICAgICAgICAqCi0gICAgICAgICAqIDxwPiAlUkVWSUVXJSBBcmUgeW91IHN1cmUgeW91IHdhbnQgIiIgZm9yIG5vIHByZWZpeD8gIDwvcD4KLSAgICAgICAgICoKLSAgICAgICAgICogJVJFVklFVyUgIFNob3VsZCB0aGlzIGJlIERPTS1zdHlsZSAodW5kZWZpbmVkIHVubGVzcyBuYW1lc3BhY2VkKSwKLSAgICAgICAgICogb3Igb3RoZXI/Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICAgICAgICogQHJldHVybiBTdHJpbmcgcHJlZml4IG9mIHRoaXMgbm9kZSdzIG5hbWUsIG9yICIiIGlmIG5vIGV4cGxpY2l0Ci0gICAgICAgICAqIG5hbWVzcGFjZSBwcmVmaXggd2FzIGdpdmVuLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IG5vZGVIYW5kbGUpIHsKLSAgICAgICAgICAgICAgICBub2Rlcy5yZWFkU2xvdChub2RlSGFuZGxlLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBzaG9ydCB0eXBlID0gKHNob3J0KSAoZ290c2xvdFswXSAmIDB4RkZGRik7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSAiIjsKLSAgICAgICAgICAgICAgICBpZigodHlwZT09RUxFTUVOVF9OT0RFKSB8fCAodHlwZT09QVRUUklCVVRFX05PREUpKSB7Ci0gICAgICAgICAgICAgICAgICBpbnQgaT1nb3RzbG90WzNdOwotICAgICAgICAgICAgICAgICAgbmFtZT1tX3ByZWZpeE5hbWVzLmluZGV4VG9TdHJpbmcoaSA+PjE2KTsKLSAgICAgICAgICAgICAgICAgIGlmKG5hbWU9PW51bGwpIG5hbWU9IiI7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwotICAgICAgICB9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5hbWVzcGFjZSBVUkkKLSAgICAgICAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgZGVjbGFyZWQgVVJJIHdoaWNoIHRoaXMgbm9kZSdzCi0gICAgICAgICAqIHByZWZpeCAtLSBvciBkZWZhdWx0IGluIGxpZXUgdGhlcmVvZiAtLSB3YXMgbWFwcGVkIHRvLikKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyBVUkkgdmFsdWUgb2YgdGhpcyBub2RlJ3MgbmFtZXNwYWNlLCBvciBudWxsIGlmIG5vCi0gICAgICAgICAqIG5hbWVzcGFjZSB3YXMgcmVzb2x2ZWQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSShpbnQgbm9kZUhhbmRsZSkge3JldHVybiBudWxsO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBub2RlIHZhbHVlLiBUaGlzIGlzIG1vc3RseQotICAgICAgICAgKiBhcyBkZWZpbmVkIGJ5IHRoZSBET00sIGJ1dCBtYXkgaWdub3JlIHNvbWUgY29udmVuaWVuY2VzLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAgICAgICAqIEByZXR1cm4gU3RyaW5nIFZhbHVlIG9mIHRoaXMgbm9kZSwgb3IgbnVsbCBpZiBub3QKLSAgICAgICAgICogbWVhbmluZ2Z1bCBmb3IgdGhpcyBub2RlIHR5cGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZShpbnQgbm9kZUhhbmRsZSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIG5vZGVzLnJlYWRTbG90KG5vZGVIYW5kbGUsIGdvdHNsb3QpOwotICAgICAgICAgICAgICAgIGludCBub2RldHlwZT1nb3RzbG90WzBdICYgMHhGRjsJCS8vICMjI3phaiB1c2UgbWFzayB0byBnZXQgbm9kZSB0eXBlCi0gICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlPW51bGw7Ci0KLSAgICAgICAgICAgICAgICBzd2l0Y2ggKG5vZGV0eXBlKSB7CQkJLy8gIyMjemFqIHRvZG8gLSBkb2N1bWVudCBub2RldHlwZXMKLSAgICAgICAgICAgICAgICBjYXNlIEFUVFJJQlVURV9OT0RFOgotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMucmVhZFNsb3Qobm9kZUhhbmRsZSsxLCBnb3RzbG90KTsKLSAgICAgICAgICAgICAgICBjYXNlIFRFWFRfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKLSAgICAgICAgICAgICAgICBjYXNlIENEQVRBX1NFQ1RJT05fTk9ERToKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPW1fY2hhci5nZXRTdHJpbmcoZ290c2xvdFsyXSwgZ290c2xvdFszXSk7CQkvLyMjI3phagotICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6Ci0gICAgICAgICAgICAgICAgY2FzZSBFTlRJVFlfUkVGRVJFTkNFX05PREU6Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbm9kZSB0eXBlLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogJVJFVklFVyUgR2VuZXJhbGx5LCByZXR1cm5pbmcgc2hvcnQgaXMgZmFsc2UgZWNvbm9teS4gUmV0dXJuIGludD8KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQuCi0gICAgICAgICAqIEByZXR1cm4gaW50IE5vZGUgdHlwZSwgYXMgcGVyIHRoZSBET00ncyBOb2RlLl9OT0RFIGNvbnN0YW50cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzaG9ydCBnZXROb2RlVHlwZShpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIHJldHVybihzaG9ydCkgKG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAwKSAmIDB4RkZGRik7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAgICAgICAqIEdldCB0aGUgZGVwdGggbGV2ZWwgb2YgdGhpcyBub2RlIGluIHRoZSB0cmVlIChlcXVhbHMgMSBmb3IKLSAgICAgICAgICogYSBwYXJlbnRsZXNzIG5vZGUpLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICAgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGFuY2VzdG9ycywgcGx1cyBvbmUKLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzaG9ydCBnZXRMZXZlbChpbnQgbm9kZUhhbmRsZSkgewotICAgICAgICAgICAgICAgIHNob3J0IGNvdW50ID0gMDsKLSAgICAgICAgICAgICAgICB3aGlsZSAobm9kZUhhbmRsZSAhPSAwKSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUhhbmRsZSA9IG5vZGVzLnJlYWRFbnRyeShub2RlSGFuZGxlLCAxKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGNvdW50OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gPT09PT09PT09PT09PT0gRG9jdW1lbnQgcXVlcnkgZnVuY3Rpb25zID09PT09PT09PT09PT09Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRlc3RzIHdoZXRoZXIgRFRNIERPTSBpbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQKLSAgICAgICAgICogdGhhdCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSB0aGlzIG5vZGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBmZWF0dXJlIFRoZSBuYW1lIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuCi0gICAgICAgICAqIEBwYXJhbSB2ZXJzaW9uVGhpcyBpcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4KLSAgICAgICAgICogICBJZiB0aGUgdmVyc2lvbiBpcyBub3QKLSAgICAgICAgICogICBzcGVjaWZpZWQsIHN1cHBvcnRpbmcgYW55IHZlcnNpb24gb2YgdGhlIGZlYXR1cmUgd2lsbCBjYXVzZSB0aGUKLSAgICAgICAgICogICBtZXRob2QgdG8gcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+LgotICAgICAgICAgKiBAcmV0dXJuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNwZWNpZmllZCBmZWF0dXJlIGlzCi0gICAgICAgICAqICAgc3VwcG9ydGVkIG9uIHRoaXMgbm9kZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikge3JldHVybiBmYWxzZTt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgYmFzZSBVUkkgb2YgdGhlIGRvY3VtZW50IGVudGl0eS4gSWYgaXQgaXMgbm90IGtub3duCi0gICAgICAgICAqIChiZWNhdXNlIHRoZSBkb2N1bWVudCB3YXMgcGFyc2VkIGZyb20gYSBzb2NrZXQgY29ubmVjdGlvbiBvciBmcm9tCi0gICAgICAgICAqIHN0YW5kYXJkIGlucHV0LCBmb3IgZXhhbXBsZSksIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIHVua25vd24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IGJhc2UgVVJJIFN0cmluZyBvYmplY3Qgb3IgbnVsbCBpZiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEJhc2VVUkkoKQotICAgICAgICB7Ci0KLSAgICAgICAgICByZXR1cm4gbV9kb2N1bWVudEJhc2VVUkk7Ci0gICAgICAgIH0KLQotICAgICAgICAvKioKLSAgICAgICAgICogU2V0IHRoZSBiYXNlIFVSSSBvZiB0aGUgZG9jdW1lbnQgZW50aXR5LgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gYmFzZVVSSSB0aGUgZG9jdW1lbnQgYmFzZSBVUkkgU3RyaW5nIG9iamVjdCBvciBudWxsIGlmIHVua25vd24uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudEJhc2VVUkkoU3RyaW5nIGJhc2VVUkkpCi0gICAgICAgIHsKLQotICAgICAgICAgIG1fZG9jdW1lbnRCYXNlVVJJID0gYmFzZVVSSTsKLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkuIElmCi0gICAgICAgICAqIGl0IGlzIG5vdCBrbm93biwgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdW5rbm93bi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgaWQsIHdoaWNoIGNhbiBiZSBhbnkgdmFsaWQgbm9kZSBoYW5kbGUuCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3Qgb3IgbnVsbCBpZiB1bmtub3duLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFN5c3RlbUlkZW50aWZpZXIoaW50IG5vZGVIYW5kbGUpIHtyZXR1cm4gbnVsbDt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIHNjaGVtZQotICAgICAgICAgKiAgICAgICAgaW4gd2hpY2ggdGhlIGRvY3VtZW50IGVudGl0eSBpcyBleHByZXNzZWQuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBkb2N1bWVudCBlbmNvZGluZyBTdHJpbmcgb2JqZWN0LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudEVuY29kaW5nKGludCBub2RlSGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gYW4gaW5kaWNhdGlvbiBvZiB0aGUgc3RhbmRhbG9uZSBzdGF0dXMgb2YgdGhlIGRvY3VtZW50LAotICAgICAgICAgKiAgICAgICAgZWl0aGVyICJ5ZXMiIG9yICJubyIuIFRoaXMgcHJvcGVydHkgaXMgZGVyaXZlZCBmcm9tIHRoZSBvcHRpb25hbAotICAgICAgICAgKiAgICAgICAgc3RhbmRhbG9uZSBkb2N1bWVudCBkZWNsYXJhdGlvbiBpbiB0aGUgWE1MIGRlY2xhcmF0aW9uIGF0IHRoZQotICAgICAgICAgKiAgICAgICAgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudCBlbnRpdHksIGFuZCBoYXMgbm8gdmFsdWUgaWYgdGhlcmUgaXMgbm8KLSAgICAgICAgICogICAgICAgIHN0YW5kYWxvbmUgZG9jdW1lbnQgZGVjbGFyYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLCB3aGljaCBjYW4gYmUgYW55IHZhbGlkIG5vZGUgaGFuZGxlLgotICAgICAgICAgKiBAcmV0dXJuIHRoZSBkb2N1bWVudCBzdGFuZGFsb25lIFN0cmluZyBvYmplY3QsIGVpdGhlciAieWVzIiwgIm5vIiwgb3IgbnVsbC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRTdGFuZGFsb25lKGludCBub2RlSGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBYTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQuIFRoaXMKLSAgICAgICAgICogcHJvcGVydHkgaXMgZGVyaXZlZCBmcm9tIHRoZSBYTUwgZGVjbGFyYXRpb24gb3B0aW9uYWxseSBwcmVzZW50IGF0IHRoZQotICAgICAgICAgKiBiZWdpbm5pbmcgb2YgdGhlIGRvY3VtZW50IGVudGl0eSwgYW5kIGhhcyBubyB2YWx1ZSBpZiB0aGVyZSBpcyBubyBYTUwKLSAgICAgICAgICogZGVjbGFyYXRpb24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB0aGUgZG9jdW1lbnQgaGFuZGxlCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIGRvY3VtZW50IHZlcnNpb24gU3RyaW5nIG9iamVjdAotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFZlcnNpb24oaW50IGRvY3VtZW50SGFuZGxlKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gYW4gaW5kaWNhdGlvbiBvZgotICAgICAgICAgKiB3aGV0aGVyIHRoZSBwcm9jZXNzb3IgaGFzIHJlYWQgdGhlIGNvbXBsZXRlIERURC4gSXRzIHZhbHVlIGlzIGEKLSAgICAgICAgICogYm9vbGVhbi4gSWYgaXQgaXMgZmFsc2UsIHRoZW4gY2VydGFpbiBwcm9wZXJ0aWVzIChpbmRpY2F0ZWQgaW4gdGhlaXIKLSAgICAgICAgICogZGVzY3JpcHRpb25zIGJlbG93KSBtYXkgYmUgdW5rbm93bi4gSWYgaXQgaXMgdHJ1ZSwgdGhvc2UgcHJvcGVydGllcwotICAgICAgICAgKiBhcmUgbmV2ZXIgdW5rbm93bi4KLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbGwgZGVjbGFyYXRpb25zIHdlcmUgcHJvY2Vzc2VkIHt9OwotICAgICAgICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXREb2N1bWVudEFsbERlY2xhcmF0aW9uc1Byb2Nlc3NlZCgpIHtyZXR1cm4gZmFsc2U7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiAgIEEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6Ci0gICAgICAgICAqCi0gICAgICAgICAqICAgICAxLiBbc3lzdGVtIGlkZW50aWZpZXJdIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBpZgotICAgICAgICAgKiAgICAgICAgaXQgZXhpc3RzLiBPdGhlcndpc2UgdGhpcyBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCkge3JldHVybiBudWxsO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LAotICAgICAgICAgKiBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBpbiA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcyBbWE1MXS4gSWYgdGhlcmUgaXMKLSAgICAgICAgICogbm8gZXh0ZXJuYWwgc3Vic2V0IG9yIGlmIGl0IGhhcyBubyBwdWJsaWMgaWRlbnRpZmllciwgdGhpcyBwcm9wZXJ0eQotICAgICAgICAgKiBoYXMgbm8gdmFsdWUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBoYW5kbGUKLSAgICAgICAgICoKLSAgICAgICAgICogQHJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgU3RyaW5nIG9iamVjdCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblB1YmxpY0lkZW50aWZpZXIoKSB7cmV0dXJuIG51bGw7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICAgICAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgICAgICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgICAgICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgICAgICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAgICAgICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgICAgICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICAgICAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgICAgICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgICAgICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgICAgICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpIHtyZXR1cm4gMDt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFRoZSBnZXRVbnBhcnNlZEVudGl0eVVSSSBmdW5jdGlvbiByZXR1cm5zIHRoZSBVUkkgb2YgdGhlIHVucGFyc2VkCi0gICAgICAgICAqIGVudGl0eSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBpbiB0aGUgc2FtZSBkb2N1bWVudCBhcyB0aGUgY29udGV4dAotICAgICAgICAgKiBub2RlIChzZWUgWzMuMyBVbnBhcnNlZCBFbnRpdGllc10pLiBJdCByZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICAgICAgICogdGhlcmUgaXMgbm8gc3VjaCBlbnRpdHkuCi0gICAgICAgICAqIDxwPgotICAgICAgICAgKiBYTUwgcHJvY2Vzc29ycyBtYXkgY2hvb3NlIHRvIHVzZSB0aGUgU3lzdGVtIElkZW50aWZpZXIgKGlmIG9uZQotICAgICAgICAgKiBpcyBwcm92aWRlZCkgdG8gcmVzb2x2ZSB0aGUgZW50aXR5LCByYXRoZXIgdGhhbiB0aGUgVVJJIGluIHRoZQotICAgICAgICAgKiBQdWJsaWMgSWRlbnRpZmllci4gVGhlIGRldGFpbHMgYXJlIGRlcGVuZGVudCBvbiB0aGUgcHJvY2Vzc29yLCBhbmQKLSAgICAgICAgICogd2Ugd291bGQgaGF2ZSB0byBzdXBwb3J0IHNvbWUgZm9ybSBvZiBwbHVnLWluIHJlc29sdmVyIHRvIGhhbmRsZQotICAgICAgICAgKiB0aGlzIHByb3Blcmx5LiBDdXJyZW50bHksIHdlIHNpbXBseSByZXR1cm4gdGhlIFN5c3RlbSBJZGVudGlmaWVyIGlmCi0gICAgICAgICAqIHByZXNlbnQsIGFuZCBob3BlIHRoYXQgaXQgYSB1c2FibGUgVVJJIG9yIHRoYXQgb3VyIGNhbGxlciBjYW4KLSAgICAgICAgICogbWFwIGl0IHRvIG9uZS4KLSAgICAgICAgICogVE9ETzogUmVzb2x2ZSBQdWJsaWMgSWRlbnRpZmllcnMuLi4gb3IgY29uc2lkZXIgY2hhbmdpbmcgZnVuY3Rpb24gbmFtZS4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIElmIHdlIGZpbmQgYSByZWxhdGl2ZSBVUkkKLSAgICAgICAgICogcmVmZXJlbmNlLCBYTUwgZXhwZWN0cyBpdCB0byBiZSByZXNvbHZlZCBpbiB0ZXJtcyBvZiB0aGUgYmFzZSBVUkkKLSAgICAgICAgICogb2YgdGhlIGRvY3VtZW50LiBUaGUgRE9NIGRvZXNuJ3QgZG8gdGhhdCBmb3IgdXMsIGFuZCBpdCBpc24ndAotICAgICAgICAgKiBlbnRpcmVseSBjbGVhciB3aGV0aGVyIHRoYXQgc2hvdWxkIGJlIGRvbmUgaGVyZTsgY3VycmVudGx5IHRoYXQncwotICAgICAgICAgKiBwdXNoZWQgdXAgdG8gYSBoaWdoZXIgbGV2ZWwgb2Ygb3VyIGFwcGxpY2F0aW9uLiAoTm90ZSB0aGF0IERPTSBMZXZlbAotICAgICAgICAgKiAxIGRpZG4ndCBzdG9yZSB0aGUgZG9jdW1lbnQncyBiYXNlIFVSSS4pCi0gICAgICAgICAqIFRPRE86IENvbnNpZGVyIHJlc29sdmluZyBSZWxhdGl2ZSBVUklzLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogKFRoZSBET00ncyBzdGF0ZW1lbnQgdGhhdCAiQW4gWE1MIHByb2Nlc3NvciBtYXkgY2hvb3NlIHRvCi0gICAgICAgICAqIGNvbXBsZXRlbHkgZXhwYW5kIGVudGl0aWVzIGJlZm9yZSB0aGUgc3RydWN0dXJlIG1vZGVsIGlzIHBhc3NlZAotICAgICAgICAgKiB0byB0aGUgRE9NIiByZWZlcnMgb25seSB0byBwYXJzZWQgZW50aXRpZXMsIG5vdCB1bnBhcnNlZCwgYW5kIGhlbmNlCi0gICAgICAgICAqIGRvZXNuJ3QgYWZmZWN0IHRoaXMgZnVuY3Rpb24uKQotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbmFtZSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBFbnRpdHkgTmFtZSBvZiB0aGUgdW5wYXJzZWQKLSAgICAgICAgICogZW50aXR5LgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBVUkkgb2YgdGhlIFVucGFyc2VkIEVudGl0eSwgb3IgYW4KLSAgICAgICAgICogZW1wdHkgc3RyaW5nIGlmIG5vIHN1Y2ggZW50aXR5IGV4aXN0cy4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VW5wYXJzZWRFbnRpdHlVUkkoU3RyaW5nIG5hbWUpIHtyZXR1cm4gbnVsbDt9Ci0KLQotICAgICAgICAvLyA9PT09PT09PT09PT09PSBCb29sZWFuIG1ldGhvZHMgPT09PT09PT09PT09PT09PQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgeHNsOnN0cmlwLXNwYWNlIG9yIHhzbDpwcmVzZXJ2ZS1zcGFjZSB3YXMgcHJvY2Vzc2VkCi0gICAgICAgICAqIGR1cmluZyBjb25zdHJ1Y3Rpb24gb2YgdGhlIERUTSBkb2N1bWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+JVJFVkVJVyUgUHJlc3VtZXMgYSAxOjEgbWFwcGluZyBmcm9tIERUTSB0byBEb2N1bWVudCwgc2luY2UKLSAgICAgICAgICogd2UgYXJlbid0IHNheWluZyB3aGljaCBEb2N1bWVudCB0byBxdWVyeS4uLj88L3A+Ci0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgYm9vbGVhbiBzdXBwb3J0c1ByZVN0cmlwcGluZygpIHtyZXR1cm4gZmFsc2U7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBGaWd1cmUgb3V0IHdoZXRoZXIgbm9kZUhhbmRsZTIgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYXMgYmVpbmcgbGF0ZXIKLSAgICAgICAgICogaW4gdGhlIGRvY3VtZW50IHRoYW4gbm9kZUhhbmRsZTEsIGluIERvY3VtZW50IE9yZGVyIGFzIGRlZmluZWQKLSAgICAgICAgICogYnkgdGhlIFhQYXRoIG1vZGVsLiBUaGlzIG1heSBub3QgYWdyZWUgd2l0aCB0aGUgb3JkZXJpbmcgZGVmaW5lZAotICAgICAgICAgKiBieSBvdGhlciBYTUwgYXBwbGljYXRpb25zLgotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogVGhlcmUgYXJlIHNvbWUgY2FzZXMgd2hlcmUgb3JkZXJpbmcgaXNuJ3QgZGVmaW5lZCwgYW5kIG5laXRoZXIgYXJlCi0gICAgICAgICAqIHRoZSByZXN1bHRzIG9mIHRoaXMgZnVuY3Rpb24gLS0gdGhvdWdoIHdlJ2xsIGdlbmVyYWxseSByZXR1cm4gdHJ1ZS4KLSAgICAgICAgICoKLSAgICAgICAgICogVE9ETzogTWFrZSBzdXJlIHRoaXMgZG9lcyB0aGUgcmlnaHQgdGhpbmcgd2l0aCBhdHRyaWJ1dGUgbm9kZXMhISEKLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGUxIERPTSBOb2RlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbi4KLSAgICAgICAgICogQHBhcmFtIG5vZGUyIERPTSBOb2RlIHRvIHBlcmZvcm0gcG9zaXRpb24gY29tcGFyaXNvbiBvbiAuCi0gICAgICAgICAqCi0gICAgICAgICAqIEByZXR1cm4gZmFsc2UgaWYgbm9kZTIgY29tZXMgYmVmb3JlIG5vZGUxLCBvdGhlcndpc2UgcmV0dXJuIHRydWUuCi0gICAgICAgICAqIFlvdSBjYW4gdGhpbmsgb2YgdGhpcyBhcwotICAgICAgICAgKiA8Y29kZT4obm9kZTEuZG9jdW1lbnRPcmRlclBvc2l0aW9uICZsdDs9IG5vZGUyLmRvY3VtZW50T3JkZXJQb3NpdGlvbik8L2NvZGU+LgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOb2RlQWZ0ZXIoaW50IG5vZGVIYW5kbGUxLCBpbnQgbm9kZUhhbmRsZTIpIHtyZXR1cm4gZmFsc2U7fQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiAgICAgMi4gW2VsZW1lbnQgY29udGVudCB3aGl0ZXNwYWNlXSBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZQotICAgICAgICAgKiAgICAgICAgY2hhcmFjdGVyIGlzIHdoaXRlIHNwYWNlIGFwcGVhcmluZyB3aXRoaW4gZWxlbWVudCBjb250ZW50IChzZWUgW1hNTF0sCi0gICAgICAgICAqICAgICAgICAyLjEwICJXaGl0ZSBTcGFjZSBIYW5kbGluZyIpLiBOb3RlIHRoYXQgdmFsaWRhdGluZyBYTUwgcHJvY2Vzc29ycyBhcmUKLSAgICAgICAgICogICAgICAgIHJlcXVpcmVkIGJ5IFhNTCAxLjAgdG8gcHJvdmlkZSB0aGlzIGluZm9ybWF0aW9uLiBJZiB0aGVyZSBpcyBubwotICAgICAgICAgKiAgICAgICAgZGVjbGFyYXRpb24gZm9yIHRoZSBjb250YWluaW5nIGVsZW1lbnQsIHRoaXMgcHJvcGVydHkgaGFzIG5vIHZhbHVlIGZvcgotICAgICAgICAgKiAgICAgICAgd2hpdGUgc3BhY2UgY2hhcmFjdGVycy4gSWYgbm8gZGVjbGFyYXRpb24gaGFzIGJlZW4gcmVhZCwgYnV0IHRoZSBbYWxsCi0gICAgICAgICAqICAgICAgICBkZWNsYXJhdGlvbnMgcHJvY2Vzc2VkXSBwcm9wZXJ0eSBvZiB0aGUgZG9jdW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcwotICAgICAgICAgKiAgICAgICAgZmFsc2UgKHNvIHRoZXJlIG1heSBiZSBhbiB1bnJlYWQgZGVjbGFyYXRpb24pLCB0aGVuIHRoZSB2YWx1ZSBvZiB0aGlzCi0gICAgICAgICAqICAgICAgICBwcm9wZXJ0eSBpcyB1bmtub3duIGZvciB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzLiBJdCBpcyBhbHdheXMgZmFsc2UgZm9yCi0gICAgICAgICAqICAgICAgICBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCB3aGl0ZSBzcGFjZS4KLSAgICAgICAgICoKLSAgICAgICAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGUgSUQuCi0gICAgICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkYXRhIGlzIHdoaXRlc3BhY2U7Ci0gICAgICAgICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ2hhcmFjdGVyRWxlbWVudENvbnRlbnRXaGl0ZXNwYWNlKGludCBub2RlSGFuZGxlKSB7cmV0dXJuIGZhbHNlO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogICAgMTAuIFthbGwgZGVjbGFyYXRpb25zIHByb2Nlc3NlZF0gVGhpcyBwcm9wZXJ0eSBpcyBub3Qgc3RyaWN0bHkgc3BlYWtpbmcKLSAgICAgICAgICogICAgICAgIHBhcnQgb2YgdGhlIGluZm9zZXQgb2YgdGhlIGRvY3VtZW50LiBSYXRoZXIgaXQgaXMgYW4gaW5kaWNhdGlvbiBvZgotICAgICAgICAgKiAgICAgICAgd2hldGhlciB0aGUgcHJvY2Vzc29yIGhhcyByZWFkIHRoZSBjb21wbGV0ZSBEVEQuIEl0cyB2YWx1ZSBpcyBhCi0gICAgICAgICAqICAgICAgICBib29sZWFuLiBJZiBpdCBpcyBmYWxzZSwgdGhlbiBjZXJ0YWluIHByb3BlcnRpZXMgKGluZGljYXRlZCBpbiB0aGVpcgotICAgICAgICAgKiAgICAgICAgZGVzY3JpcHRpb25zIGJlbG93KSBtYXkgYmUgdW5rbm93bi4gSWYgaXQgaXMgdHJ1ZSwgdGhvc2UgcHJvcGVydGllcwotICAgICAgICAgKiAgICAgICAgYXJlIG5ldmVyIHVua25vd24uCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSB0aGUgZG9jdW1lbnQgaGFuZGxlCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBkb2N1bWVudEhhbmRsZSBBIG5vZGUgaGFuZGxlIHRoYXQgbXVzdCBpZGVudGlmeSBhIGRvY3VtZW50LgotICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFsbCBkZWNsYXJhdGlvbnMgd2VyZSBwcm9jZXNzZWQ7Ci0gICAgICAgICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzRG9jdW1lbnRBbGxEZWNsYXJhdGlvbnNQcm9jZXNzZWQoaW50IGRvY3VtZW50SGFuZGxlKSB7cmV0dXJuIGZhbHNlO30KLQotICAgICAgICAvKioKLSAgICAgICAgICogICAgIDUuIFtzcGVjaWZpZWRdIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBhdHRyaWJ1dGUgd2FzIGFjdHVhbGx5Ci0gICAgICAgICAqICAgICAgICBzcGVjaWZpZWQgaW4gdGhlIHN0YXJ0LXRhZyBvZiBpdHMgZWxlbWVudCwgb3Igd2FzIGRlZmF1bHRlZCBmcm9tIHRoZQotICAgICAgICAgKiAgICAgICAgRFRELgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gdGhlIGF0dHJpYnV0ZSBoYW5kbGUKLSAgICAgICAgICoKLSAgICAgICAgICogTkVFRFNET0MgQHBhcmFtIGF0dHJpYnV0ZUhhbmRsZQotICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhdHRyaWJ1dGUgd2FzIHNwZWNpZmllZDsKLSAgICAgICAgICogICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgd2FzIGRlZmF1bHRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBib29sZWFuIGlzQXR0cmlidXRlU3BlY2lmaWVkKGludCBhdHRyaWJ1dGVIYW5kbGUpIHtyZXR1cm4gZmFsc2U7fQotCi0gICAgICAgIC8vID09PT09PT09PT0gRGlyZWN0IFNBWCBEaXNwYXRjaCwgZm9yIG9wdGltaXphdGlvbiBwdXJwb3NlcyA9PT09PT09PQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgICAgICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICAgICAgICogc3RyaW5nLXZhbHVlIG9mIHRoZSBnaXZlbiBub2RlIChzZWUgaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZGF0YS1tb2RlbAotICAgICAgICAgKiBmb3IgdGhlIGRlZmluaXRpb24gb2YgYSBub2RlJ3Mgc3RyaW5nLXZhbHVlKS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAgICAgICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAgICAgICAqIHRoaXMgbWV0aG9kLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICAgICAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCwgYm9vbGVhbiBub3JtYWxpemUpCi0gICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24ge30KLQotICAgICAgICAvKioKLSAgICAgICAgICogRGlyZWN0bHkgY3JlYXRlIFNBWCBwYXJzZXIgZXZlbnRzIGZyb20gYSBzdWJ0cmVlLgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICAgICAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAgICAgICAqCi0gICAgICAgICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAgICAgICAqLwotCi0gICAgICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoVG9FdmVudHMoaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHt9Ci0KLSAgICAgICAgLyoqCi0gICAgICAgICAqIFJldHVybiBhbiBET00gbm9kZSBmb3IgdGhlIGdpdmVuIG5vZGUuCi0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgICAgICAgKgotICAgICAgICAgKiBAcmV0dXJuIEEgbm9kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgRFRNIG5vZGUuCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgb3JnLnczYy5kb20uTm9kZSBnZXROb2RlKGludCBub2RlSGFuZGxlKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyA9PT09IENvbnN0cnVjdGlvbiBtZXRob2RzIChtYXkgbm90IGJlIHN1cHBvcnRlZCBieSBzb21lIGltcGxlbWVudGF0aW9ucyEpID09PT09Ci0gICAgICAgIC8vICVSRVZJRVclIGpqazogVGhlc2UgcHJvYmFibHkgYXJlbid0IHRoZSByaWdodCBBUEkuIEF0IHRoZSB2ZXJ5IGxlYXN0Ci0gICAgICAgIC8vIHRoZXkgbmVlZCB0byBkZWFsIHdpdGggY3VycmVudC1pbnNlcnRpb24tbG9jYXRpb24gYW5kIGVuZC1lbGVtZW50Ci0gICAgICAgIC8vIGlzc3Vlcy4KLQotICAgICAgICAvKioKLSAgICAgICAgICogQXBwZW5kIGEgY2hpbGQgdG8gdGhlIGVuZCBvZiB0aGUgY2hpbGQgbGlzdCBvZiB0aGUgY3VycmVudCBub2RlLiBQbGVhc2Ugbm90ZSB0aGF0IHRoZSBub2RlCi0gICAgICAgICAqIGlzIGFsd2F5cyBjbG9uZWQgaWYgaXQgaXMgb3duZWQgYnkgYW5vdGhlciBkb2N1bWVudC4KLSAgICAgICAgICoKLSAgICAgICAgICogPHA+JVJFVklFVyUgIkVuZCBvZiB0aGUgZG9jdW1lbnQiIG5lZWRzIHRvIGJlIGRlZmluZWQgbW9yZSBjbGVhcmx5LgotICAgICAgICAgKiBEb2VzIGl0IGJlY29tZSB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgRG9jdW1lbnQ/IE9mIHRoZSByb290IGVsZW1lbnQ/PC9wPgotICAgICAgICAgKgotICAgICAgICAgKiBAcGFyYW0gbmV3Q2hpbGQgTXVzdCBiZSBhIHZhbGlkIG5ldyBub2RlIGhhbmRsZS4KLSAgICAgICAgICogQHBhcmFtIGNsb25lIHRydWUgaWYgdGhlIGNoaWxkIHNob3VsZCBiZSBjbG9uZWQgaW50byB0aGUgZG9jdW1lbnQuCi0gICAgICAgICAqIEBwYXJhbSBjbG9uZURlcHRoIGlmIHRoZSBjbG9uZSBhcmd1bWVudCBpcyB0cnVlLCBzcGVjaWZpZXMgdGhhdCB0aGUKLSAgICAgICAgICogICAgICAgICAgICAgICAgICAgY2xvbmUgc2hvdWxkIGluY2x1ZGUgYWxsIGl0J3MgY2hpbGRyZW4uCi0gICAgICAgICAqLwotICAgICAgICBwdWJsaWMgdm9pZCBhcHBlbmRDaGlsZChpbnQgbmV3Q2hpbGQsIGJvb2xlYW4gY2xvbmUsIGJvb2xlYW4gY2xvbmVEZXB0aCkgewotICAgICAgICAgICAgICAgIGJvb2xlYW4gc2FtZURvYyA9ICgobmV3Q2hpbGQgJiBET0NIQU5ETEVfTUFTSykgPT0gbV9kb2NIYW5kbGUpOwotICAgICAgICAgICAgICAgIGlmIChjbG9uZSB8fCAhc2FtZURvYykgewotCi0gICAgICAgICAgICAgICAgfSBlbHNlIHsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIC8qKgotICAgICAgICAgKiBBcHBlbmQgYSB0ZXh0IG5vZGUgY2hpbGQgdGhhdCB3aWxsIGJlIGNvbnN0cnVjdGVkIGZyb20gYSBzdHJpbmcsCi0gICAgICAgICAqIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LgotICAgICAgICAgKgotICAgICAgICAgKiA8cD4lUkVWSUVXJSAiRW5kIG9mIHRoZSBkb2N1bWVudCIgbmVlZHMgdG8gYmUgZGVmaW5lZCBtb3JlIGNsZWFybHkuCi0gICAgICAgICAqIERvZXMgaXQgYmVjb21lIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBEb2N1bWVudD8gT2YgdGhlIHJvb3QgZWxlbWVudD88L3A+Ci0gICAgICAgICAqCi0gICAgICAgICAqIEBwYXJhbSBzdHIgTm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgc3RyaW5nLgotICAgICAgICAgKi8KLSAgICAgICAgcHVibGljIHZvaWQgYXBwZW5kVGV4dENoaWxkKFN0cmluZyBzdHIpIHsKLSAgICAgICAgICAgICAgICAvLyAjIyNzaHMgVGhpbmsgbW9yZSBhYm91dCBob3cgdGhpcyBkaWZmZXJzIGZyb20gY3JlYXRlVGV4dE5vZGUKLSAgICAgICAgICAvLyVUQkQlCi0gICAgICAgIH0KLQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyA9PT09IEJVSUxERVIgbWV0aG9kcyA9PT09Ci0gIC8vICVUQkQlIGpqazogU0hPVUxEIFBST0JBQkxZIEJFIElOTElORUQsIHVubGVzcyB3ZSB3YW50IHRvIHN1cHBvcnQKLSAgLy8gYm90aCBTQVgxIGFuZCBTQVgyIGFuZCBzaGFyZSB0aGlzIGxvZ2ljIGJldHdlZW4gdGhlbS4KLQotICAvKiogQXBwZW5kIGEgdGV4dCBjaGlsZCBhdCB0aGUgY3VycmVudCBpbnNlcnRpb24gcG9pbnQuIEFzc3VtZXMgdGhhdCB0aGUKLSAgICogYWN0dWFsIGNvbnRlbnQgb2YgdGhlIHRleHQgaGFzIHByZXZpb3VzbHkgYmVlbiBhcHBlbmRlZCB0byB0aGUgbV9jaGFyCi0gICAqIGJ1ZmZlciAoc2hhcmVkIHdpdGggdGhlIGJ1aWxkZXIpLgotICAgKgotICAgKiBAcGFyYW0gbV9jaGFyX2N1cnJlbnRfc3RhcnQgaW50IFN0YXJ0aW5nIG9mZnNldCBvZiBub2RlJ3MgY29udGVudCBpbiBtX2NoYXIuCi0gICAqIEBwYXJhbSBjb250ZW50TGVuZ3RoIGludCBMZW5ndGggb2Ygbm9kZSdzIGNvbnRlbnQgaW4gbV9jaGFyLgotICAgKiAqLwotICB2b2lkIGFwcGVuZFRleHRDaGlsZChpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQsaW50IGNvbnRlbnRMZW5ndGgpCi0gIHsKLSAgICAvLyBjcmVhdGUgYSBUZXh0IE5vZGUKLSAgICAvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotICAgIGludCB3MCA9IFRFWFRfTk9ERTsKLSAgICAvLyBXMTogUGFyZW50Ci0gICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLSAgICAvLyBXMjogU3RhcnQgcG9zaXRpb24gd2l0aGluIG1fY2hhcgotICAgIGludCB3MiA9IG1fY2hhcl9jdXJyZW50X3N0YXJ0OwotICAgIC8vIFczOiBMZW5ndGggb2YgdGhlIGZ1bGwgc3RyaW5nCi0gICAgaW50IHczID0gY29udGVudExlbmd0aDsKLQotICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgcHJldmlvdXNTaWJsaW5nID0gb3Vyc2xvdDsKLSAgfQotCi0gIC8qKiBBcHBlbmQgYSBjb21tZW50IGNoaWxkIGF0IHRoZSBjdXJyZW50IGluc2VydGlvbiBwb2ludC4gQXNzdW1lcyB0aGF0IHRoZQotICAgKiBhY3R1YWwgY29udGVudCBvZiB0aGUgY29tbWVudCBoYXMgcHJldmlvdXNseSBiZWVuIGFwcGVuZGVkIHRvIHRoZSBtX2NoYXIKLSAgICogYnVmZmVyIChzaGFyZWQgd2l0aCB0aGUgYnVpbGRlcikuCi0gICAqCi0gICAqIEBwYXJhbSBtX2NoYXJfY3VycmVudF9zdGFydCBpbnQgU3RhcnRpbmcgb2Zmc2V0IG9mIG5vZGUncyBjb250ZW50IGluIG1fY2hhci4KLSAgICogQHBhcmFtIGNvbnRlbnRMZW5ndGggaW50IExlbmd0aCBvZiBub2RlJ3MgY29udGVudCBpbiBtX2NoYXIuCi0gICAqICovCi0gIHZvaWQgYXBwZW5kQ29tbWVudChpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQsaW50IGNvbnRlbnRMZW5ndGgpCi0gIHsKLSAgICAvLyBjcmVhdGUgYSBDb21tZW50IE5vZGUKLSAgICAvLyAlVEJEJSBtYXkgYmUgcG9zc2libGUgdG8gY29tYmluZSB3aXRoIGFwcGVuZE5vZGUoKXRvIHJlcGxhY2UgdGhlIG5leHQgY2h1bmsgb2YgY29kZQotICAgIGludCB3MCA9IENPTU1FTlRfTk9ERTsKLSAgICAvLyBXMTogUGFyZW50Ci0gICAgaW50IHcxID0gY3VycmVudFBhcmVudDsKLSAgICAvLyBXMjogU3RhcnQgcG9zaXRpb24gd2l0aGluIG1fY2hhcgotICAgIGludCB3MiA9IG1fY2hhcl9jdXJyZW50X3N0YXJ0OwotICAgIC8vIFczOiBMZW5ndGggb2YgdGhlIGZ1bGwgc3RyaW5nCi0gICAgaW50IHczID0gY29udGVudExlbmd0aDsKLQotICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgcHJldmlvdXNTaWJsaW5nID0gb3Vyc2xvdDsKLSAgfQotCi0KLSAgLyoqIEFwcGVuZCBhbiBFbGVtZW50IGNoaWxkIGF0IHRoZSBjdXJyZW50IGluc2VydGlvbiBwb2ludC4gVGhpcwotICAgKiBFbGVtZW50IHRoZW4gX2JlY29tZXNfIHRoZSBpbnNlcnRpb24gcG9pbnQ7IHN1YnNlcXVlbnQgYXBwZW5kcwotICAgKiBiZWNvbWUgaXRzIGxhc3RDaGlsZCB1bnRpbCBhbiBhcHBlbmRFbmRFbGVtZW50KCkgY2FsbCBpcyBtYWRlLgotICAgKgotICAgKiBBc3N1bWVzIHRoYXQgdGhlIHN5bWJvbHMgKGxvY2FsIG5hbWUsIG5hbWVzcGFjZSBVUkkgYW5kIHByZWZpeCkKLSAgICogaGF2ZSBhbHJlYWR5IGJlZW4gYWRkZWQgdG8gdGhlIHBvb2xzCi0gICAqCi0gICAqIE5vdGUgdGhhdCB0aGlzIF9vbmx5XyBoYW5kbGVzIHRoZSBFbGVtZW50IG5vZGUgaXRzZWxmLiBBdHRycyBhbmQKLSAgICogbmFtZXNwYWNlIG5vZGVzIGFyZSB1bmJ1bmRsZWQgaW4gdGhlIENvbnRlbnRIYW5kbGVyIGxheWVyCi0gICAqIGFuZCBhcHBlbmRlZCBzZXBhcmF0ZWx5LgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlSW5kZXg6IEluZGV4IHdpdGhpbiB0aGUgbmFtZXNwYWNlVVJJIHN0cmluZyBwb29sCi0gICAqIEBwYXJhbSBsb2NhbE5hbWVJbmRleCBJbmRleCB3aXRoaW4gdGhlIGxvY2FsIG5hbWUgc3RyaW5nIHBvb2wKLSAgICogQHBhcmFtIHByZWZpeEluZGV4OiBJbmRleCB3aXRoaW4gdGhlIHByZWZpeCBzdHJpbmcgcG9vbAotICAgKiAqLwotICB2b2lkIGFwcGVuZFN0YXJ0RWxlbWVudChpbnQgbmFtZXNwYWNlSW5kZXgsaW50IGxvY2FsTmFtZUluZGV4LCBpbnQgcHJlZml4SW5kZXgpCi0gIHsKLSAgICAgICAgICAgICAgICAvLyBkbyBkb2N1bWVudCByb290IG5vZGUgY3JlYXRpb24gaGVyZSBvbiB0aGUgZmlyc3QgZWxlbWVudCwgY3JlYXRlIG5vZGVzIGZvcgotICAgICAgICAgICAgICAgIC8vIHRoaXMgZWxlbWVudCBhbmQgaXRzIGF0dHJpYnV0ZXMsIHN0b3JlIHRoZSBlbGVtZW50LCBuYW1lc3BhY2UsIGFuZCBhdHRyaXR1dGUKLSAgICAgICAgICAgICAgICAvLyBuYW1lIGluZGV4ZXMgdG8gdGhlIG5vZGVzIGFycmF5LCBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IG5vZGUgYW5kIHBhcmVudAotICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgdXNlZAotCi0gICAgICAgICAgICAgICAgLy8gVzAgIEhpZ2g6ICBOYW1lc3BhY2UgIExvdzogIE5vZGUgVHlwZQotICAgICAgICAgICAgICAgIGludCB3MCA9IChuYW1lc3BhY2VJbmRleCA8PCAxNikgfCBFTEVNRU5UX05PREU7Ci0gICAgICAgICAgICAgICAgLy8gVzE6IFBhcmVudAotICAgICAgICAgICAgICAgIGludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0gICAgICAgICAgICAgICAgLy8gVzI6IE5leHQgIChpbml0aWFsaXplZCBhcyAwKQotICAgICAgICAgICAgICAgIGludCB3MiA9IDA7Ci0gICAgICAgICAgICAgICAgLy8gVzM6IFRhZ25hbWUgaGlnaDogcHJlZml4IExvdzogbG9jYWwgbmFtZQotICAgICAgICAgICAgICAgIGludCB3MyA9IGxvY2FsTmFtZUluZGV4IHwgcHJlZml4SW5kZXg8PDE2OwotICAgICAgICAgICAgICAgIC8qKi9TeXN0ZW0ub3V0LnByaW50bG4oInNldCB3Mz0iK3czKyIgIisodzM+PjE2KSsiLyIrKHczJjB4ZmZmZikpOwotCi0gICAgICAgICAgICAgICAgLy9pbnQgb3Vyc2xvdCA9IG5vZGVzLmFwcGVuZFNsb3QodzAsIHcxLCB3MiwgdzMpOwotICAgICAgICAgICAgICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgICAgICAgICAgICAgY3VycmVudFBhcmVudCA9IG91cnNsb3Q7Ci0gICAgICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nID0gMDsKLQotICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgcm9vdCBlbGVtZW50IHBvaW50ZXIgd2hlbiBjcmVhdGluZyB0aGUgZmlyc3QgZWxlbWVudCBub2RlCi0gICAgICAgICAgICAgICAgaWYgKG1fZG9jRWxlbWVudCA9PSBOVUxMKQotICAgICAgICAgICAgICAgICAgICAgICAgbV9kb2NFbGVtZW50ID0gb3Vyc2xvdDsKLSAgfQotCi0gIC8qKiBBcHBlbmQgYSBOYW1lc3BhY2UgRGVjbGFyYXRpb24gY2hpbGQgYXQgdGhlIGN1cnJlbnQgaW5zZXJ0aW9uIHBvaW50LgotICAgKiBBc3N1bWVzIHRoYXQgdGhlIHN5bWJvbHMgKG5hbWVzcGFjZSBVUkkgYW5kIHByZWZpeCkgaGF2ZSBhbHJlYWR5IGJlZW4KLSAgICogYWRkZWQgdG8gdGhlIHBvb2xzCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXhJbmRleDogSW5kZXggd2l0aGluIHRoZSBwcmVmaXggc3RyaW5nIHBvb2wKLSAgICogQHBhcmFtIG5hbWVzcGFjZUluZGV4OiBJbmRleCB3aXRoaW4gdGhlIG5hbWVzcGFjZVVSSSBzdHJpbmcgcG9vbAotICAgKiBAcGFyYW0gaXNJRDogSWYgc29tZW9uZSByZWFsbHkgaW5zaXN0cyBvbiB3cml0aW5nIGEgYmFkIERURCwgaXQgaXMKLSAgICogdGhlb3JldGljYWxseSBwb3NzaWJsZSBmb3IgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gdG8gYWxzbyBiZSBkZWNsYXJlZAotICAgKiBhcyBiZWluZyBhIG5vZGUgSUQuIEkgZG9uJ3QgcmVhbGx5IHdhbnQgdG8gc3VwcG9ydCB0aGF0IHN0dXBpZGl0eSwKLSAgICogYnV0IEknbSBub3Qgc3VyZSB3ZSBjYW4gcmVmdXNlIHRvIGFjY2VwdCBpdC4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmROU0RlY2xhcmF0aW9uKGludCBwcmVmaXhJbmRleCwgaW50IG5hbWVzcGFjZUluZGV4LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0lEKQotICB7Ci0gICAgLy8gJVJFVklFVyUgSSdtIGFzc2lnbmluZyB0aGlzIG5vZGUgdGhlICJuYW1lc3BhY2UgZm9yIG5hbWVzcGFjZXMiCi0gICAgLy8gd2hpY2ggdGhlIERPTSBkZWZpbmVkLiBJdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBOYW1lc3BhY2Ugc3BlYyB3aWxsCi0gICAgLy8gYWRvcHQgdGhpcyBhcyBvZmZpY2lhbC4gSXQgaXNuJ3Qgc3RyaWN0bHkgbmVlZGVkIHNpbmNlIGl0J3MgaW1wbGllZAotICAgIC8vIGJ5IHRoZSBub2RldHlwZSwgYnV0IGZvciBub3cuLi4KLQotICAgIC8vICVSRVZJRVclIFByZWZpeCBuZWVkIG5vdCBiZSByZWNvcmRlZDsgaXQncyBpbXBsaWVkIHRvby4gQnV0Ci0gICAgLy8gcmVjb3JkaW5nIGl0IG1pZ2h0IHNpbXBsaWZ5IHRoZSBkZXNpZ24uCi0KLSAgICAvLyAlVEJEJSBpc0lEIGlzIG5vdCBjdXJyZW50bHkgaG9ub3JlZC4KLQotICAgIGZpbmFsIGludCBuYW1lc3BhY2VGb3JOYW1lc3BhY2VzPW1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIpOwotCi0gICAgLy8gVzAgIEhpZ2g6ICBOYW1lc3BhY2UgIExvdzogIE5vZGUgVHlwZQotICAgIGludCB3MCA9IE5BTUVTUEFDRV9OT0RFIHwgKG1fbnNOYW1lcy5zdHJpbmdUb0luZGV4KCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIpPDwxNik7Ci0KLSAgICAvLyBXMTogIFBhcmVudAotICAgIGludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0gICAgLy8gVzI6ICBDVVJSRU5UTFkgVU5VU0VEIC0tIEl0J3MgbmV4dC1zaWIgaW4gYXR0cnMsIGJ1dCB3ZSBoYXZlIG5vIGtpZHMuCi0gICAgaW50IHcyID0gMDsKLSAgICAvLyBXMzogIG5hbWVzcGFjZSBuYW1lCi0gICAgaW50IHczID0gbmFtZXNwYWNlSW5kZXg7Ci0gICAgLy8gQWRkIG5vZGUKLSAgICBpbnQgb3Vyc2xvdCA9IGFwcGVuZE5vZGUodzAsIHcxLCB3MiwgdzMpOwotICAgIHByZXZpb3VzU2libGluZyA9IG91cnNsb3Q7CS8vIFNob3VsZCBhdHRyaWJ1dGVzIGJlIHByZXZpb3VzIHNpYmxpbmdzCi0gICAgcHJldmlvdXNTaWJsaW5nV2FzUGFyZW50ID0gZmFsc2U7Ci0gICAgcmV0dXJuIDsvLyhtX2RvY0hhbmRsZSB8IG91cnNsb3QpOwotICB9Ci0KLSAgLyoqIEFwcGVuZCBhbiBBdHRyaWJ1dGUgY2hpbGQgYXQgdGhlIGN1cnJlbnQgaW5zZXJ0aW9uCi0gICAqIHBvaW50LiAgQXNzdW1lcyB0aGF0IHRoZSBzeW1ib2xzIChuYW1lc3BhY2UgVVJJLCBsb2NhbCBuYW1lLCBhbmQKLSAgICogcHJlZml4KSBoYXZlIGFscmVhZHkgYmVlbiBhZGRlZCB0byB0aGUgcG9vbHMsIGFuZCB0aGF0IHRoZSBjb250ZW50IGhhcwotICAgKiBhbHJlYWR5IGJlZW4gYXBwZW5kZWQgdG8gbV9jaGFyLiBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSdzIGNvbnRlbnQgaGFzCi0gICAqIGJlZW4gZmxhdHRlbmVkIGludG8gYSBzaW5nbGUgc3RyaW5nOyBEVE0gZG9lcyBfTk9UXyBhdHRlbXB0IHRvIG1vZGVsCi0gICAqIHRoZSBkZXRhaWxzIG9mIGVudGl0eSByZWZlcmVuY2VzIHdpdGhpbiBhdHRyaWJ1dGUgdmFsdWVzLgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlSW5kZXggaW50IEluZGV4IHdpdGhpbiB0aGUgbmFtZXNwYWNlVVJJIHN0cmluZyBwb29sCi0gICAqIEBwYXJhbSBsb2NhbE5hbWVJbmRleCBpbnQgSW5kZXggd2l0aGluIHRoZSBsb2NhbCBuYW1lIHN0cmluZyBwb29sCi0gICAqIEBwYXJhbSBwcmVmaXhJbmRleCBpbnQgSW5kZXggd2l0aGluIHRoZSBwcmVmaXggc3RyaW5nIHBvb2wKLSAgICogQHBhcmFtIGlzSUQgYm9vbGVhbiBUcnVlIGlmIHRoaXMgYXR0cmlidXRlIHdhcyBkZWNsYXJlZCBhcyBhbiBJRAotICAgKiAoZm9yIHVzZSBpbiBzdXBwb3J0aW5nIGdldEVsZW1lbnRCeUlEKS4KLSAgICogQHBhcmFtIG1fY2hhcl9jdXJyZW50X3N0YXJ0IGludCBTdGFydGluZyBvZmZzZXQgb2Ygbm9kZSdzIGNvbnRlbnQgaW4gbV9jaGFyLgotICAgKiBAcGFyYW0gY29udGVudExlbmd0aCBpbnQgTGVuZ3RoIG9mIG5vZGUncyBjb250ZW50IGluIG1fY2hhci4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmRBdHRyaWJ1dGUoaW50IG5hbWVzcGFjZUluZGV4LCBpbnQgbG9jYWxOYW1lSW5kZXgsIGludCBwcmVmaXhJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0lELAotICAgICAgICAgICAgICAgICAgICAgICBpbnQgbV9jaGFyX2N1cnJlbnRfc3RhcnQsIGludCBjb250ZW50TGVuZ3RoKQotICB7Ci0gICAgLy8gJVRCRCUgaXNJRCBpcyBub3QgY3VycmVudGx5IGhvbm9yZWQuCi0KLSAgICAvLyBXMCAgSGlnaDogIE5hbWVzcGFjZSAgTG93OiAgTm9kZSBUeXBlCi0gICAgaW50IHcwID0gQVRUUklCVVRFX05PREUgfCBuYW1lc3BhY2VJbmRleDw8MTY7Ci0KLSAgICAvLyBXMTogIFBhcmVudAotICAgIGludCB3MSA9IGN1cnJlbnRQYXJlbnQ7Ci0gICAgLy8gVzI6ICBOZXh0IChub3QgeWV0IHJlc29sdmVkKQotICAgIGludCB3MiA9IDA7Ci0gICAgLy8gVzM6ICBUYWduYW1lIGhpZ2g6IHByZWZpeCBMb3c6IGxvY2FsIG5hbWUKLSAgICBpbnQgdzMgPSBsb2NhbE5hbWVJbmRleCB8IHByZWZpeEluZGV4PDwxNjsKLSAgICAvKiovU3lzdGVtLm91dC5wcmludGxuKCJzZXQgdzM9Iit3MysiICIrKHczPj4xNikrIi8iKyh3MyYweGZmZmYpKTsKLSAgICAvLyBBZGQgbm9kZQotICAgIGludCBvdXJzbG90ID0gYXBwZW5kTm9kZSh3MCwgdzEsIHcyLCB3Myk7Ci0gICAgcHJldmlvdXNTaWJsaW5nID0gb3Vyc2xvdDsJLy8gU2hvdWxkIGF0dHJpYnV0ZXMgYmUgcHJldmlvdXMgc2libGluZ3MKLQotICAgIC8vIEF0dHJpYnV0ZSdzIGNvbnRlbnQgaXMgY3VycmVudGx5IGFwcGVuZGVkIGFzIGEgVGV4dCBOb2RlCi0KLSAgICAvLyBXMDogTm9kZSBUeXBlCi0gICAgdzAgPSBURVhUX05PREU7Ci0gICAgLy8gVzE6IFBhcmVudAotICAgIHcxID0gb3Vyc2xvdDsKLSAgICAvLyBXMjogU3RhcnQgUG9zaXRpb24gd2l0aGluIGJ1ZmZlcgotICAgIHcyID0gbV9jaGFyX2N1cnJlbnRfc3RhcnQ7Ci0gICAgLy8gVzM6IExlbmd0aAotICAgIHczID0gY29udGVudExlbmd0aDsKLSAgICBhcHBlbmROb2RlKHcwLCB3MSwgdzIsIHczKTsKLQotICAgIC8vIEF0dHJzIGFyZSBQYXJlbnRzCi0gICAgcHJldmlvdXNTaWJsaW5nV2FzUGFyZW50ID0gdHJ1ZTsKLSAgICByZXR1cm4gOy8vKG1fZG9jSGFuZGxlIHwgb3Vyc2xvdCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyByZXR1cm5zIGEgc3RhdGVsZXNzICJ0cmF2ZXJzZXIiLCB0aGF0IGNhbiBuYXZpZ2F0ZSBvdmVyIGFuCi0gICAqIFhQYXRoIGF4aXMsIHRob3VnaCBub3QgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAqCi0gICAqIEBwYXJhbSBheGlzIE9uZSBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIG9yIG51bGwgaWYgdGhlIGdpdmVuIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNUcmF2ZXJzZXIgZ2V0QXhpc1RyYXZlcnNlcihmaW5hbCBpbnQgYXhpcykKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgaXMgYSBzaG9ydGN1dCB0byB0aGUgaXRlcmF0b3JzIHRoYXQgaW1wbGVtZW50IHRoZQotICAgKiBzdXBwb3J0ZWQgWFBhdGggYXhlcyAob25seSBuYW1lc3BhY2U6OikgaXMgbm90IHN1cHBvcnRlZC4KLSAgICogUmV0dXJucyBhIGJhcmUtYm9uZXMgaXRlcmF0b3IgdGhhdCBtdXN0IGJlIGluaXRpYWxpemVkCi0gICAqIHdpdGggYSBzdGFydCBub2RlICh1c2luZyBpdGVyYXRvci5zZXRTdGFydE5vZGUoKSkuCi0gICAqCi0gICAqIEBwYXJhbSBheGlzIE9uZSBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIG9yIG51bGwgaWYgdGhlIGdpdmVuIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMpCi0gIHsKLSAgICAvLyAlVEJEJQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBpdGVyYXRvciB0aGF0IGNhbiBuYXZpZ2F0ZSBvdmVyIGFuIFhQYXRoIEF4aXMsIHByZWRpY2F0ZWQgYnkKLSAgICogdGhlIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBheGlzCi0gICAqIEBwYXJhbSB0eXBlIEFuIGV4dGVuZGVkIHR5cGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBEVE1BeGlzSXRlcmF0b3IsIG9yIG51bGwgaWYgdGhlIGdpdmVuIGF4aXMgaXNuJ3Qgc3VwcG9ydGVkLgotICAgKi8KLSAgcHVibGljIERUTUF4aXNJdGVyYXRvciBnZXRUeXBlZEF4aXNJdGVyYXRvcihmaW5hbCBpbnQgYXhpcywgZmluYWwgaW50IHR5cGUpCi0gIHsKLSAgICAvLyAlVEJEJQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLQotICAvKiogVGVybWluYXRlIHRoZSBlbGVtZW50IGN1cnJlbnRseSBhY3RpbmcgYXMgYW4gaW5zZXJ0aW9uIHBvaW50LiBTdWJzZXF1ZW50Ci0gICAqIGluc2VydGlvbnMgd2lsbCBvY2N1ciBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGlzIGVsZW1lbnQncyBwYXJlbnQuCi0gICAqICovCi0gIHZvaWQgYXBwZW5kRW5kRWxlbWVudCgpCi0gIHsKLSAgICAvLyBwb3AgdXAgdGhlIHN0YWNrcwotCi0gICAgaWYgKHByZXZpb3VzU2libGluZ1dhc1BhcmVudCkKLSAgICAgIG5vZGVzLndyaXRlRW50cnkocHJldmlvdXNTaWJsaW5nLCAyLCBOVUxMKTsKLQotICAgIC8vIFBvcCBwYXJlbnRhZ2UKLSAgICBwcmV2aW91c1NpYmxpbmcgPSBjdXJyZW50UGFyZW50OwotICAgIG5vZGVzLnJlYWRTbG90KGN1cnJlbnRQYXJlbnQsIGdvdHNsb3QpOwotICAgIGN1cnJlbnRQYXJlbnQgPSBnb3RzbG90WzFdICYgMHhGRkZGOwotCi0gICAgLy8gVGhlIGVsZW1lbnQganVzdCBiZWluZyBmaW5pc2hlZCB3aWxsIGJlCi0gICAgLy8gdGhlIHByZXZpb3VzIHNpYmxpbmcgZm9yIHRoZSBuZXh0IG9wZXJhdGlvbgotICAgIHByZXZpb3VzU2libGluZ1dhc1BhcmVudCA9IHRydWU7Ci0KLSAgICAvLyBQb3AgYSBsZXZlbCBvZiBuYW1lc3BhY2UgdGFibGUKLSAgICAvLyBuYW1lc3BhY2VUYWJsZS5yZW1vdmVMYXN0RWxlbSgpOwotICB9Ci0KLSAgLyoqICBTdGFydGluZyBhIG5ldyBkb2N1bWVudC4gUGVyZm9ybSBhbnkgcmVzZXRzL2luaXRpYWxpemF0aW9uCi0gICAqIG5vdCBhbHJlYWR5IGhhbmRsZWQuCi0gICAqICovCi0gIHZvaWQgYXBwZW5kU3RhcnREb2N1bWVudCgpCi0gIHsKLQotICAgIC8vICVUQkQlIHJlc2V0IHNsb3QgMCB0byBpbmRpY2F0ZSBDaHVua2VkSW50QXJyYXkgcmV1c2Ugb3Igd2FpdCBmb3IKLSAgICAvLyAgICAgICB0aGUgbmV4dCBpbml0RG9jdW1lbnQoKS4KLSAgICBtX2RvY0VsZW1lbnQgPSBOVUxMOwkgLy8gcmVzZXQgbm9kZUhhbmRsZSB0byB0aGUgcm9vdCBvZiB0aGUgYWN0dWFsIGR0bSBkb2MgY29udGVudAotICAgIGluaXREb2N1bWVudCgwKTsKLSAgfQotCi0gIC8qKiAgQWxsIGFwcGVuZHMgdG8gdGhpcyBkb2N1bWVudCBoYXZlIGZpbmlzaGVkOyBkbyB3aGF0ZXZlciBmaW5hbAotICAgKiBjbGVhbnVwIGlzIG5lZWRlZC4KLSAgICogKi8KLSAgdm9pZCBhcHBlbmRFbmREb2N1bWVudCgpCi0gIHsKLSAgICBkb25lID0gdHJ1ZTsKLSAgICAvLyAlVEJEJSBtYXkgbmVlZCB0byBub3RpY2UgdGhlIGxhc3Qgc2xvdCBudW1iZXIgYW5kIHNsb3QgY291bnQgdG8gYXZvaWQKLSAgICAvLyByZXNpZHVhbCBkYXRhIGZyb20gcHJvdmlvdXMgdXNlIG9mIHRoaXMgRFRNCi0gIH0KLQotICAvKioKLSAgICogRm9yIHRoZSBtb21lbnQgYWxsIHRoZSBydW4gdGltZSBwcm9wZXJ0aWVzIGFyZSBpZ25vcmVkIGJ5IHRoaXMKLSAgICogY2xhc3MuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9wZXJ0eSBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSwgT2JqZWN0IHZhbHVlKQotICB7Ci0gIH0KLQotICAvKioKLSAgICogU291cmNlIGluZm9ybWF0aW9uIGlzIG5vdCBoYW5kbGVkIHlldCwgc28gcmV0dXJuCi0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGhlcmUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIGFuIDxjb2RlPmludDwvY29kZT4gdmFsdWUKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU291cmNlTG9jYXRvciBnZXRTb3VyY2VMb2NhdG9yRm9yKGludCBub2RlKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBBIGR1bW15IHJvdXRpbmUgdG8gc2F0aXNpZnkgdGhlIGFic3RyYWN0IGludGVyZmFjZS4gSWYgdGhlIERUTQotICAgKiBpbXBsZW1lbXRhdGlvbiB0aGF0IGV4dGVuZHMgdGhlIGRlZmF1bHQgYmFzZSByZXF1aXJlcyBub3RpZmljYXRpb24KLSAgICogb2YgcmVnaXN0cmF0aW9uLCB0aGV5IGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZC4KLSAgICovCi0gICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlZ2lzdHJhdGlvbigpCi0gICB7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIEEgZHVtbXkgcm91dGluZSB0byBzYXRpc2lmeSB0aGUgYWJzdHJhY3QgaW50ZXJmYWNlLiBJZiB0aGUgRFRNCi0gICAqIGltcGxlbWVtdGF0aW9uIHRoYXQgZXh0ZW5kcyB0aGUgZGVmYXVsdCBiYXNlIHJlcXVpcmVzIG5vdGlmaWNhdGlvbgotICAgKiB3aGVuIHRoZSBkb2N1bWVudCBpcyBiZWluZyByZWxlYXNlZCwgdGhleSBjYW4gb3ZlcnJpZGUgdGhpcyBtZXRob2QKLSAgICovCi0gICBwdWJsaWMgdm9pZCBkb2N1bWVudFJlbGVhc2UoKQotICAgewotICAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTU1hbmFnZXJEZWZhdWx0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1NYW5hZ2VyRGVmYXVsdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhOTc1YmRmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTU1hbmFnZXJEZWZhdWx0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MTIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8vIEpBWFAgMS4xCi1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuKjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguU0FYU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLS8vIEFwYWNoZSBYTUwgVXRpbGl0aWVzCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3lzdGVtSURSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLmRvbTJkdG0uRE9NMkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLnNheDJkdG0uU0FYMkRUTTsKLQotLy8gVzNDIERPTQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8vIFNBWDIKLWltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLS8qKgotICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBEVE1NYW5hZ2VyLgotICovCi1wdWJsaWMgY2xhc3MgRFRNTWFuYWdlckRlZmF1bHQgZXh0ZW5kcyBEVE1NYW5hZ2VyCi17Ci0KLSAgLyoqCi0gICAqIFZlY3RvciBvZiBEVE1zIHRoYXQgdGhpcyBtYW5hZ2VyIG1hbmFnZXMuCi0gICAqLwotICBwcm90ZWN0ZWQgRFRNIG1fZHRtc1tdID0gbmV3IERUTVtJREVOVF9NQVhfRFRNU107Ci0KLSAgLyoqCi0gICAqIEFkZCBhIERUTSB0byB0aGUgRFRNIHRhYmxlLgotICAgKgotICAgKiBAcGFyYW0gZHRtIFNob3VsZCBiZSBhIHZhbGlkIHJlZmVyZW5jZSB0byBhIERUTS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZERUTShEVE0gZHRtLCBpbnQgaWQpCi0gIHsKLSAgICBtX2R0bXNbaWRdID0gZHRtOwotICAgIGR0bS5kb2N1bWVudFJlZ2lzdHJhdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZmlyc3QgZnJlZSBEVE0gSUQgYXZhaWxhYmxlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRGaXJzdEZyZWVEVE1JRCgpCi0gIHsKLSAgICBpbnQgbiA9IG1fZHRtcy5sZW5ndGg7Ci0gICAgZm9yIChpbnQgaSA9IDE7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgaWYobnVsbCA9PSBtX2R0bXNbaV0pCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBpOwotICAgICAgfQotICAgIH0KLSAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PX0RUTUlEU19BVkFJTCwgbnVsbCkpOyAvLyJObyBtb3JlIERUTSBJRHMgYXJlIGF2YWlsYWJsZSEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgZGVmYXVsdCB0YWJsZSBmb3IgZXhhbmRlZE5hbWVJRCBsb29rdXBzLgotICAgKi8KLSAgcHJpdmF0ZSBFeHBhbmRlZE5hbWVUYWJsZSBtX2V4cGFuZGVkTmFtZVRhYmxlID0KLSAgICBuZXcgRXhwYW5kZWROYW1lVGFibGUoKTsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRFRNTWFuYWdlckRlZmF1bHQKLSAgICoKLSAgICovCi0gIHB1YmxpYyBEVE1NYW5hZ2VyRGVmYXVsdCgpe30KLQotICAvKiogU2V0IHRoaXMgdG8gdHJ1ZSBpZiB5b3Ugd2FudCBhIGR1bXAgb2YgdGhlIERUTSBhZnRlciBjcmVhdGlvbi4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBEVU1QVFJFRSA9IGZhbHNlOwotCi0gIC8qKiBTZXQgdGhpcyB0byB0cnVlIGlmIHlvdSB3YW50IGEgYmFzaWMgZGlhZ25vc3RpY3MuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIGEgRFRNLCBsb2FkZWQgd2l0aCB0aGUgY29udGVudCBmcm9tIHRoZQotICAgKiBzcGVjaWZpZWQgc291cmNlLiAgSWYgdGhlIHVuaXF1ZSBmbGFnIGlzIHRydWUsIGEgbmV3IGluc3RhbmNlIHdpbGwKLSAgICogYWx3YXlzIGJlIHJldHVybmVkLiAgT3RoZXJ3aXNlIGl0IGlzIHVwIHRvIHRoZSBEVE1NYW5hZ2VyIHRvIHJldHVybiBhCi0gICAqIG5ldyBpbnN0YW5jZSBvciBhbiBpbnN0YW5jZSB0aGF0IGl0IGFscmVhZHkgY3JlYXRlZCBhbmQgbWF5IGJlIGJlaW5nIHVzZWQKLSAgICogYnkgc29tZW9uZSBlbHNlLgotICAgKiAoSSB0aGluayBtb3JlIHBhcmFtZXRlcnMgd2lsbCBuZWVkIHRvIGJlIGFkZGVkIGZvciBlcnJvciBoYW5kbGluZywgYW5kIGVudGl0eQotICAgKiByZXNvbHV0aW9uKS4KLSAgICoKLSAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgc291cmNlIG9iamVjdC4KLSAgICogQHBhcmFtIHVuaXF1ZSB0cnVlIGlmIHRoZSByZXR1cm5lZCBEVE0gbXVzdCBiZSB1bmlxdWUsIHByb2JhYmx5IGJlY2F1c2UgaXQKLSAgICogaXMgZ29pbmcgdG8gYmUgbXV0YXRlZC4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgRW5hYmxlcyBmaWx0ZXJpbmcgb2Ygd2hpdGVzcGFjZSBub2RlcywgYW5kIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0gaW5jcmVtZW50YWwgdHJ1ZSBpZiB0aGUgRFRNIHNob3VsZCBiZSBidWlsdCBpbmNyZW1lbnRhbGx5LCBpZgotICAgKiAgICAgICAgICAgICAgICAgICAgcG9zc2libGUuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlCi0gICAqICAgICAgICAgICAgICAgICAgIGluZGV4aW5nIHNjaGVtZXMuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIERUTSBnZXREVE0oU291cmNlIHNvdXJjZSwgYm9vbGVhbiB1bmlxdWUsCi0gICAgICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsIGJvb2xlYW4gaW5jcmVtZW50YWwsCi0gICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotCi0gICAgaWYoREVCVUcgJiYgbnVsbCAhPSBzb3VyY2UpCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0aW5nIHNvdXJjZTogIitzb3VyY2UuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgWE1MU3RyaW5nRmFjdG9yeSB4c3RyaW5nRmFjdG9yeSA9IG1feHNmOwotICAgIGludCBkdG1Qb3MgPSBnZXRGaXJzdEZyZWVEVE1JRCgpOwotICAgIGludCBkb2N1bWVudElEID0gZHRtUG9zIDw8IElERU5UX0RUTV9OT0RFX0JJVFM7Ci0KLSAgICBpZiAoKG51bGwgIT0gc291cmNlKSAmJiBzb3VyY2UgaW5zdGFuY2VvZiBET01Tb3VyY2UpCi0gICAgewotICAgICAgRE9NMkRUTSBkdG0gPSBuZXcgRE9NMkRUTSh0aGlzLCAoRE9NU291cmNlKSBzb3VyY2UsIGRvY3VtZW50SUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaXRlU3BhY2VGaWx0ZXIsIHhzdHJpbmdGYWN0b3J5LCBkb0luZGV4aW5nKTsKLQotICAgICAgYWRkRFRNKGR0bSwgZHRtUG9zKTsKLQotLy8gICAgICBpZiAoRFVNUFRSRUUpCi0vLyAgICAgIHsKLS8vICAgICAgICBkdG0uZHVtcERUTSgpOwotLy8gICAgICB9Ci0KLSAgICAgIHJldHVybiBkdG07Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBib29sZWFuIGlzU0FYU291cmNlID0gKG51bGwgIT0gc291cmNlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKHNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSkgOiB0cnVlOwotICAgICAgYm9vbGVhbiBpc1N0cmVhbVNvdXJjZSA9IChudWxsICE9IHNvdXJjZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChzb3VyY2UgaW5zdGFuY2VvZiBTdHJlYW1Tb3VyY2UpIDogZmFsc2U7Ci0KLSAgICAgIGlmIChpc1NBWFNvdXJjZSB8fCBpc1N0cmVhbVNvdXJjZSkKLSAgICAgIHsKLSAgICAgICAgWE1MUmVhZGVyIHJlYWRlcjsKLSAgICAgICAgSW5wdXRTb3VyY2UgeG1sU291cmNlOwotCi0gICAgICAgIGlmIChudWxsID09IHNvdXJjZSkKLSAgICAgICAgewotICAgICAgICAgIHhtbFNvdXJjZSA9IG51bGw7Ci0gICAgICAgICAgcmVhZGVyID0gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICByZWFkZXIgPSBnZXRYTUxSZWFkZXIoc291cmNlKTsKLSAgICAgICAgICB4bWxTb3VyY2UgPSBTQVhTb3VyY2Uuc291cmNlVG9JbnB1dFNvdXJjZShzb3VyY2UpOwotCi0gICAgICAgICAgU3RyaW5nIHVybE9mU291cmNlID0geG1sU291cmNlLmdldFN5c3RlbUlkKCk7Ci0KLSAgICAgICAgICBpZiAobnVsbCAhPSB1cmxPZlNvdXJjZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgdXJsT2ZTb3VyY2UgPSBTeXN0ZW1JRFJlc29sdmVyLmdldEFic29sdXRlVVJJKHVybE9mU291cmNlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgICAgICAgIHsKLQotICAgICAgICAgICAgICAvLyAlUkVWSUVXJSBJcyB0aGVyZSBhIGJldHRlciB3YXkgdG8gc2VuZCBhIHdhcm5pbmc/Ci0gICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ2FuIG5vdCBhYnNvbHV0aXplIFVSTDogIiArIHVybE9mU291cmNlKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgeG1sU291cmNlLnNldFN5c3RlbUlkKHVybE9mU291cmNlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBDcmVhdGUgdGhlIGJhc2ljIFNBWDJEVE0uCi0gICAgICAgIFNBWDJEVE0gZHRtID0gbmV3IFNBWDJEVE0odGhpcywgc291cmNlLCBkb2N1bWVudElELCB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzdHJpbmdGYWN0b3J5LCBkb0luZGV4aW5nKTsKLQotICAgICAgICAvLyBHbyBhaGVhZCBhbmQgYWRkIHRoZSBEVE0gdG8gdGhlIGxvb2t1cCB0YWJsZS4gIFRoaXMgbmVlZHMgdG8gYmUKLSAgICAgICAgLy8gZG9uZSBiZWZvcmUgYW55IHBhcnNpbmcgb2NjdXJzLgotICAgICAgICBhZGREVE0oZHRtLCBkdG1Qb3MpOwotCi0gICAgICAgIGJvb2xlYW4gaGF2ZVhlcmNlc1BhcnNlciA9Ci0gICAgICAgICAgKG51bGwgIT0gcmVhZGVyKQotICAgICAgICAgICYmIChyZWFkZXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCkuZXF1YWxzKCJvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlciIpICk7Ci0KLSAgICAgICAgaWYgKGhhdmVYZXJjZXNQYXJzZXIpCi0gICAgICAgICAgaW5jcmVtZW50YWwgPSB0cnVlOyAgLy8gTm8gbWF0dGVyIHdoYXQuICAlUkVWSUVXJQotCi0gICAgICAgIC8vIElmIHRoZSByZWFkZXIgaXMgbnVsbCwgYnV0IHRoZXkgc3RpbGwgcmVxdWVzdGVkIGFuIGluY3JlbWVudGFsIGJ1aWxkLAotICAgICAgICAvLyB0aGVuIHdlIHN0aWxsIHdhbnQgdG8gc2V0IHVwIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBzdHVmZi4KLSAgICAgICAgaWYgKHRoaXMubV9pbmNyZW1lbnRhbCAmJiBpbmNyZW1lbnRhbCAvKiB8fCAoKG51bGwgPT0gcmVhZGVyKSAmJiBpbmNyZW1lbnRhbCkgKi8pCi0gICAgICAgIHsKLSAgICAgICAgICBJbmNyZW1lbnRhbFNBWFNvdXJjZSBjb1BhcnNlcj1udWxsOwotCi0gICAgICAgICAgaWYgKGhhdmVYZXJjZXNQYXJzZXIpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIHRvIGF2b2lkIHRocmVhZGluZy4KLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiVXNpbmcgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIHRvIGF2b2lkIHRocmVhZGluZyIpOwotICAgICAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIG9rLCBpdCdzIGluIHRoZSBzYW1lIHBhY2thZ2UgLSBubyBuZWVkIGZvciB0aHJlYWQgY2xhc3MgbG9hZGVyCi0gICAgICAgICAgICAgIENsYXNzIGM9Q2xhc3MuZm9yTmFtZSggIm9yZy5hcGFjaGUueG1sLmR0bS5yZWYuSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIiApOwotICAgICAgICAgICAgICBjb1BhcnNlcj0oSW5jcmVtZW50YWxTQVhTb3VyY2UpYy5uZXdJbnN0YW5jZSgpOwotICAgICAgICAgICAgfSAgY2F0Y2goIEV4Y2VwdGlvbiBleCApIHsKLSAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgICAgICAgIGNvUGFyc2VyPW51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaWYoIGNvUGFyc2VyPT1udWxsICkgewotICAgICAgICAgICAgLy8gQ3JlYXRlIGEgSW5jcmVtZW50YWxTQVhTb3VyY2UgdGhhdCB3aWxsIHJ1biBvbiB0aGUgc2Vjb25kYXJ5IHRocmVhZC4KLSAgICAgICAgICAgIGlmIChudWxsID09IHJlYWRlcikKLSAgICAgICAgICAgICAgY29QYXJzZXIgPSBuZXcgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKCk7Ci0gICAgICAgICAgICBlbHNlCi0JICAgIHsKLQkgICAgICBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgZmlsdGVyPW5ldyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIoKTsKLQkgICAgICBmaWx0ZXIuc2V0WE1MUmVhZGVyKHJlYWRlcik7Ci0JICAgICAgY29QYXJzZXI9ZmlsdGVyOwotCSAgICB9Ci0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAvLyBIYXZlIHRoZSBEVE0gc2V0IGl0c2VsZiB1cCBhcyB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UncyBsaXN0ZW5lci4KLSAgICAgICAgICBkdG0uc2V0SW5jcmVtZW50YWxTQVhTb3VyY2UoY29QYXJzZXIpOwotCi0gICAgICAgICAgaWYgKG51bGwgPT0geG1sU291cmNlKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gVGhlbiB0aGUgdXNlciB3aWxsIGNvbnN0cnVjdCBpdCB0aGVtc2VsdmVzLgotICAgICAgICAgICAgcmV0dXJuIGR0bTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICByZWFkZXIuc2V0RFRESGFuZGxlcihkdG0pOwotICAgICAgICAgIHJlYWRlci5zZXRFcnJvckhhbmRsZXIoZHRtKTsKLQotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLQotCSAgICAvLyBMYXVuY2ggcGFyc2luZyBjb3JvdXRpbmUuICBMYXVuY2hlcyBhIHNlY29uZCB0aHJlYWQsCi0JICAgIC8vIGlmIHdlJ3JlIHVzaW5nIEluY3JlbWVudGFsU0FYU291cmNlLmZpbHRlcigpLgotICAgICAgICAgICAgY29QYXJzZXIuc3RhcnRQYXJzZSh4bWxTb3VyY2UpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIGR0bS5jbGVhckNvUm91dGluZSgpOwotCi0gICAgICAgICAgICB0aHJvdyByZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgZHRtLmNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgPT0gcmVhZGVyKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gVGhlbiB0aGUgdXNlciB3aWxsIGNvbnN0cnVjdCBpdCB0aGVtc2VsdmVzLgotICAgICAgICAgICAgcmV0dXJuIGR0bTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICAvLyBub3QgaW5jcmVtZW50YWwKLSAgICAgICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoZHRtKTsKLSAgICAgICAgICByZWFkZXIuc2V0RFRESGFuZGxlcihkdG0pOwotICAgICAgICAgIHJlYWRlci5zZXRFcnJvckhhbmRsZXIoZHRtKTsKLQotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgKLSAgICAgICAgICAgICAgImh0dHA6Ly94bWwub3JnL3NheC9wcm9wZXJ0aWVzL2xleGljYWwtaGFuZGxlciIsIGR0bSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uIGUpe30KLSAgICAgICAgICBjYXRjaCAoU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpe30KLQotICAgICAgICAgIHRyeQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJlYWRlci5wYXJzZSh4bWxTb3VyY2UpOwotICAgICAgICAgIH0KLSAgICAgICAgICBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkKLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIGR0bS5jbGVhckNvUm91dGluZSgpOwotCi0gICAgICAgICAgICB0aHJvdyByZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgZHRtLmNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgICAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihlKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoRFVNUFRSRUUpCi0gICAgICAgIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkR1bXBpbmcgU0FYMkRPTSIpOwotICAgICAgICAgIGR0bS5kdW1wRFRNKCk7Ci0gICAgICAgIH0KLQotICAgICAgICByZXR1cm4gZHRtOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIEl0IHNob3VsZCBoYXZlIGJlZW4gaGFuZGxlZCBieSBhIGRlcml2ZWQgY2xhc3Mgb3IgdGhlIGNhbGxlcgotICAgICAgICAvLyBtYWRlIGEgbWlzdGFrZS4KLSAgICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT1RfU1VQUE9SVEVELCBuZXcgT2JqZWN0W117c291cmNlfSkpOyAvLyJOb3Qgc3VwcG9ydGVkOiAiICsgc291cmNlKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBXM0MgRE9NIG5vZGUsIHRyeSBhbmQgcmV0dXJuIGEgRFRNIGhhbmRsZS4KLSAgICogTm90ZTogY2FsbGluZyB0aGlzIG1heSBiZSBub24tb3B0aW1hbCwgYW5kIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0Ci0gICAqIHRoZSBub2RlIHdpbGwgYmUgZm91bmQgaW4gYW55IHBhcnRpY3VsYXIgRFRNLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb24tbnVsbCByZWZlcmVuY2UgdG8gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBhIHZhbGlkIERUTSBoYW5kbGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldERUTUhhbmRsZUZyb21Ob2RlKG9yZy53M2MuZG9tLk5vZGUgbm9kZSkKLSAgewotICAgIGlmKG51bGwgPT0gbm9kZSkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9ERV9OT05fTlVMTCwgbnVsbCkpOyAvLyJub2RlIG11c3QgYmUgbm9uLW51bGwgZm9yIGdldERUTUhhbmRsZUZyb21Ob2RlISIpOwotCi0gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVQcm94eSkKLSAgICAgIHJldHVybiAoKG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZVByb3h5KSBub2RlKS5nZXREVE1Ob2RlTnVtYmVyKCk7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIEZpbmQgdGhlIERPTTJEVE1zIHdyYXBwZWQgYXJvdW5kIHRoaXMgRG9jdW1lbnQgKGlmIGFueSkKLSAgICAgIC8vIGFuZCBjaGVjayB3aGV0aGVyIHRoZXkgY29udGFpbiB0aGUgTm9kZSBpbiBxdWVzdGlvbi4KLSAgICAgIC8vCi0gICAgICAvLyBOT1RFIHRoYXQgc2luY2UgYSBET00yRFRNIG1heSByZXByZXNlbnQgYSBzdWJ0cmVlIHJhdGhlcgotICAgICAgLy8gdGhhbiBhIGZ1bGwgZG9jdW1lbnQsIHdlIGhhdmUgdG8gYmUgcHJlcGFyZWQgdG8gY2hlY2sgbW9yZQotICAgICAgLy8gdGhhbiBvbmUgLS0gYW5kIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHdlIHdpbGwgZmluZAotICAgICAgLy8gb25lIHRoYXQgY29udGFpbnMgYW5jZXN0b3JzIG9yIHNpYmxpbmdzIG9mIHRoZSBub2RlIHdlJ3JlCi0gICAgICAvLyBzZWVraW5nLgotICAgICAgLy8KLSAgICAgIC8vICVSRVZJRVclIFdlIGNvdWxkIHNlYXJjaCBmb3IgdGhlIG9uZSB3aGljaCBjb250YWlucyB0aGlzCi0gICAgICAvLyBub2RlIGF0IHRoZSBkZWVwZXN0IGxldmVsLCBhbmQgdGh1cyBjb3ZlcnMgdGhlIHdpZGVzdAotICAgICAgLy8gc3VidHJlZSwgYnV0IHRoYXQncyBnb2luZyB0byBlbnRhaWwgYWRkaXRpb25hbCB3b3JrCi0gICAgICAvLyBjaGVja2luZyBtb3JlIERUTXMuLi4gYW5kIGdldEhhbmRsZUZyb21Ob2RlIGlzIG5vdCBhCi0gICAgICAvLyBjaGVhcCBvcGVyYXRpb24gaW4gbW9zdCBpbXBsZW1lbnRhdGlvbnMuCi0gICAgICAvLyBbSSBoYWQgdG8gY2hhbmdlIHRoaXMgdG8gbG9vayBmb3J3YXJkLi4uIHNvcnJ5LiAgLXNiXQotICAgICAgaW50IG1heCA9IG1fZHRtcy5sZW5ndGg7Ci0gICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbWF4OyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBEVE0gdGhpc0RUTT1tX2R0bXNbaV07Ci0gICAgICAgICAgaWYoKG51bGwgIT0gdGhpc0RUTSkgJiYgdGhpc0RUTSBpbnN0YW5jZW9mIERPTTJEVE0pCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGhhbmRsZT0oKERPTTJEVE0pdGhpc0RUTSkuZ2V0SGFuZGxlT2ZOb2RlKG5vZGUpOwotICAgICAgICAgICAgaWYoaGFuZGxlIT1EVE0uTlVMTCkgcmV0dXJuIGhhbmRsZTsKLSAgICAgICAgICB9Ci0gICAgICAgICB9Ci0KLSAgICAgIC8vIFNpbmNlIHRoZSByZWFsIHJvb3Qgb2Ygb3VyIHRyZWUgbWF5IGJlIGEgRG9jdW1lbnRGcmFnbWVudCwgd2UgbmVlZCB0bwotICAgICAgLy8gdXNlIGdldFBhcmVudCB0byBmaW5kIHRoZSByb290LCBpbnN0ZWFkIG9mIGdldE93bmVyRG9jdW1lbnQuICBPdGhlcndpc2UKLSAgICAgIC8vIERPTTJEVE0jZ2V0SGFuZGxlT2ZOb2RlIHdpbGwgYmUgdmVyeSB1bmhhcHB5LgotICAgICAgTm9kZSByb290ID0gbm9kZTsKLSAgICAgIGZvciAoTm9kZSBwID0gcm9vdC5nZXRQYXJlbnROb2RlKCk7IHAgIT0gbnVsbDsgcCA9IHAuZ2V0UGFyZW50Tm9kZSgpKQotICAgICAgewotICAgICAgICByb290ID0gcDsKLSAgICAgIH0KLQotICAgICAgRFRNIGR0bSA9IGdldERUTShuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlKHJvb3QpLCBmYWxzZSwKLSAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgdHJ1ZSwgdHJ1ZSk7Ci0KLSAgICAgIGludCBoYW5kbGUgPSAoKERPTTJEVE0pZHRtKS5nZXRIYW5kbGVPZk5vZGUobm9kZSk7Ci0KLSAgICAgIGlmKERUTS5OVUxMID09IGhhbmRsZSkKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ09VTERfTk9UX1JFU09MVkVfTk9ERSwgbnVsbCkpOyAvLyJDb3VsZCBub3QgcmVzb2x2ZSB0aGUgbm9kZSB0byBhIGhhbmRsZSEiKTsKLQotICAgICAgcmV0dXJuIGhhbmRsZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgU0FYMiBwYXJzZXIgdG8gdXNlIHdpdGggdGhlIElucHV0U291cmNlCi0gICAqIG9idGFpbmVkIGZyb20gdGhpcyBVUkkuCi0gICAqIEl0IG1heSByZXR1cm4gbnVsbCBpZiBhbnkgU0FYMi1jb25mb3JtYW50IFhNTCBwYXJzZXIgY2FuIGJlIHVzZWQsCi0gICAqIG9yIGlmIGdldElucHV0U291cmNlKCkgd2lsbCBhbHNvIHJldHVybiBudWxsLiBUaGUgcGFyc2VyIG11c3QKLSAgICogYmUgZnJlZSBmb3IgdXNlIChpLmUuCi0gICAqIG5vdCBjdXJyZW50bHkgaW4gdXNlIGZvciBhbm90aGVyIHBhcnNlKCkuCi0gICAqCi0gICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB0aGUgVVJJUmVzb2x2ZXIuCi0gICAqIEByZXR1cm5zIGEgU0FYMiBYTUxSZWFkZXIgdG8gdXNlIHRvIHJlc29sdmUgdGhlIGlucHV0U291cmNlIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIFhNTFJlYWRlciByZWZlcmVuY2UgcmVhZHkgdG8gcGFyc2UuCi0gICAqLwotICBwdWJsaWMgWE1MUmVhZGVyIGdldFhNTFJlYWRlcihTb3VyY2UgaW5wdXRTb3VyY2UpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFhNTFJlYWRlciByZWFkZXIgPSAoaW5wdXRTb3VyY2UgaW5zdGFuY2VvZiBTQVhTb3VyY2UpCi0gICAgICAgICAgICAgICAgICAgICAgICAgPyAoKFNBWFNvdXJjZSkgaW5wdXRTb3VyY2UpLmdldFhNTFJlYWRlcigpIDogbnVsbDsKLQotICAgICAgYm9vbGVhbiBpc1VzZXJSZWFkZXIgPSAocmVhZGVyICE9IG51bGwpOwotCi0gICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5ID0KLSAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLQotICAgICAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0KLSAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXIgamF4cFBhcnNlciA9IGZhY3RvcnkubmV3U0FYUGFyc2VyKCk7Ci0KLSAgICAgICAgICByZWFkZXIgPSBqYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4KQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleCk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihleDEudG9TdHJpbmcoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEVycm9yIGV4Mil7fQotICAgICAgICBjYXRjaCAoQWJzdHJhY3RNZXRob2RFcnJvciBhbWUpe30KLQotICAgICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICAgICAgcmVhZGVyID0gWE1MUmVhZGVyRmFjdG9yeS5jcmVhdGVYTUxSZWFkZXIoKTsKLSAgICAgIH0KLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIHJlYWRlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlLXByZWZpeGVzIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIHNlKQotICAgICAgewotCi0gICAgICAgIC8vIFdoYXQgY2FuIHdlIGRvPwotICAgICAgICAvLyBUT0RPOiBVc2VyIGRpYWdub3N0aWNzLgotICAgICAgfQotCi0gICAgICAgIC8vIENvbW1lbnRlZCBvdXQgYXMgcGVyIGRpc2N1c3Npb24gd2l0aCBUaG9tYXMyLk1hZXNpbmdAYmdzLWFnLmRlCi0gICAgICAgIC8vIGFib3V0IGJ1ZyAyMTI0LgotLy8gICAgICBpZighaXNVc2VyUmVhZGVyKQotLy8gICAgICB7Ci0vLyAgICAgICAgdHJ5Ci0vLyAgICAgICAgewotLy8gICAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy92YWxpZGF0aW9uL2R5bmFtaWMiLAotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7Ci0vLyAgICAgICAgfQotLy8gICAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0vLyAgICAgICAgewotLy8KLS8vICAgICAgICAgIC8vIFdoYXQgY2FuIHdlIGRvPwotLy8gICAgICAgICAgLy8gVE9ETzogVXNlciBkaWFnbm9zdGljcy4KLS8vICAgICAgICB9Ci0vLyAgICAgIH0KLQotICAgICAgcmV0dXJuIHJlYWRlcjsKLSAgICB9Ci0gICAgY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSwgc2UpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBORUVEU0RPQyBNZXRob2QgZ2V0RFRNCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBub2RlSGFuZGxlCi0gICAqCi0gICAqIE5FRURTRE9DIChnZXREVE0pIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICAvLyBQZXJmb3JtYW5jZSBjcml0aWNhbCBmdW5jdGlvbi4KLSAgICByZXR1cm4gbV9kdG1zW25vZGVIYW5kbGUgPj4+IElERU5UX0RUTV9OT0RFX0JJVFNdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgRFRNLCBmaW5kIGl0J3MgSUQgbnVtYmVyIGluIHRoZSBEVE0gbGlzdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGR0bSBUaGUgRFRNIHJlZmVyZW5jZSBpbiBxdWVzdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgSUQsIG9yIC0xIGlmIG5vdCBmb3VuZCBpbiB0aGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RFRNSWRlbnRpdHkoRFRNIGR0bSkKLSAgewotCi0gICAgLy8gQSBiYWNrd2FyZHMgc2VhcmNoIHNob3VsZCBub3JtYWxseSBiZSB0aGUgZmFzdGVzdC4KLSAgICAvLyBbQnV0IHdlIGNhbid0IGRvIGl0Li4uIHNvcnJ5LiAgLXNiXQotICAgIGludCBuID0gbV9kdG1zLmxlbmd0aDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIERUTSB0ZHRtID0gbV9kdG1zW2ldOwotCi0gICAgICBpZiAodGR0bSA9PSBkdG0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBORUVEU0RPQyBNZXRob2QgcmVsZWFzZQotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZHRtCi0gICAqIE5FRURTRE9DIEBwYXJhbSBzaG91bGRIYXJkRGVsZXRlCi0gICAqCi0gICAqIE5FRURTRE9DIChyZWxlYXNlKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiByZWxlYXNlKERUTSBkdG0sIGJvb2xlYW4gc2hvdWxkSGFyZERlbGV0ZSkKLSAgewotCi0gICAgaWYgKGR0bSBpbnN0YW5jZW9mIFNBWDJEVE0pCi0gICAgewotICAgICAgKChTQVgyRFRNKSBkdG0pLmNsZWFyQ29Sb3V0aW5lKCk7Ci0gICAgfQotCi0gICAgaW50IGkgPSBnZXREVE1JZGVudGl0eShkdG0pOwotCi0gICAgaWYgKGkgPj0gMCkKLSAgICB7Ci0gICAgICBtX2R0bXNbaV0gPSBudWxsOwotICAgIH0KLQotICAgIGR0bS5kb2N1bWVudFJlbGVhc2UoKTsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgY3JlYXRlRG9jdW1lbnRGcmFnbWVudAotICAgKgotICAgKgotICAgKiBORUVEU0RPQyAoY3JlYXRlRG9jdW1lbnRGcmFnbWVudCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIERUTSBjcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkYmYgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLSAgICAgIGRiZi5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLQotICAgICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotICAgICAgRG9jdW1lbnQgZG9jID0gZGIubmV3RG9jdW1lbnQoKTsKLSAgICAgIE5vZGUgZGYgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotCi0gICAgICByZXR1cm4gZ2V0RFRNKG5ldyBET01Tb3VyY2UoZGYpLCB0cnVlLCBudWxsLCBmYWxzZSwgZmFsc2UpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGNyZWF0ZURUTUl0ZXJhdG9yCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB3aGF0VG9TaG93Ci0gICAqIE5FRURTRE9DIEBwYXJhbSBmaWx0ZXIKLSAgICogTkVFRFNET0MgQHBhcmFtIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbgotICAgKgotICAgKiBORUVEU0RPQyAoY3JlYXRlRFRNSXRlcmF0b3IpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgd2hhdFRvU2hvdywgRFRNRmlsdGVyIGZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIE5FRURTRE9DIE1ldGhvZCBjcmVhdGVEVE1JdGVyYXRvcgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0geHBhdGhTdHJpbmcKLSAgICogTkVFRFNET0MgQHBhcmFtIHByZXNvbHZlcgotICAgKgotICAgKiBORUVEU0RPQyAoY3JlYXRlRFRNSXRlcmF0b3IpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihTdHJpbmcgeHBhdGhTdHJpbmcsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVmaXhSZXNvbHZlciBwcmVzb2x2ZXIpCi0gIHsKLQotICAgIC8qKiBAdG9kbzogaW1wbGVtZW50IHRoaXMgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXIgYWJzdHJhY3QgbWV0aG9kICovCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGNyZWF0ZURUTUl0ZXJhdG9yCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBub2RlCi0gICAqCi0gICAqIE5FRURTRE9DIChjcmVhdGVEVE1JdGVyYXRvcikgQHJldHVybgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKGludCBub2RlKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIE5FRURTRE9DIE1ldGhvZCBjcmVhdGVEVE1JdGVyYXRvcgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0geHBhdGhDb21waWxlcgotICAgKiBORUVEU0RPQyBAcGFyYW0gcG9zCi0gICAqCi0gICAqIE5FRURTRE9DIChjcmVhdGVEVE1JdGVyYXRvcikgQHJldHVybgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKE9iamVjdCB4cGF0aENvbXBpbGVyLCBpbnQgcG9zKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyIGFic3RyYWN0IG1ldGhvZCAqLwotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIHJldHVybiB0aGUgZXhwYW5kZWQgbmFtZSB0YWJsZS4KLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIGR0bQotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgRXhwYW5kZWROYW1lVGFibGUgZ2V0RXhwYW5kZWROYW1lVGFibGUoRFRNIGR0bSkKLSAgewotICAgIHJldHVybiBtX2V4cGFuZGVkTmFtZVRhYmxlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTU5hbWVkTm9kZU1hcC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNTmFtZWROb2RlTWFwLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDliYjY1YTkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNTmFtZWROb2RlTWFwLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogRFRNTmFtZWROb2RlTWFwIGlzIGEgcXVpY2tpZSAoYXMgb3Bwb3NlZCB0byBxdWljaykgaW1wbGVtZW50YXRpb24gb2YgdGhlIERPTSdzCi0gKiBOYW1lZE5vZGVNYXAgaW50ZXJmYWNlLCBpbnRlbmRlZCB0byBzdXBwb3J0IERUTVByb3h5J3MgZ2V0QXR0cmlidXRlcygpCi0gKiBjYWxsLgotICogPHA+Ci0gKiAqKioqKiBOb3RlOiB0aGlzIGRvZXMgX25vdF8gY3VycmVudCBhdHRlbXB0IHRvIGNhY2hlIGFueSBvZiB0aGUgZGF0YTsKLSAqIGlmIHlvdSBhc2sgZm9yIGF0dHJpYnV0ZSAyNyBhbmQgdGhlbiAyOCwgeW91J2xsIGhhdmUgdG8gcmVzY2FuIHRoZSBmaXJzdAotICogMjcuIEl0IHNob3VsZCBwcm9iYWJseSBhdCBsZWFzdCBrZWVwIHRyYWNrIG9mIHRoZSBsYXN0IG9uZSByZXRyaWV2ZWQsCi0gKiBhbmQgcG9zc2libHkgYnVmZmVyIHRoZSB3aG9sZSBhcnJheS4KLSAqIDxwPgotICogKioqKiogQWxzbyBub3RlIHRoYXQgdGhlcmUncyBubyBmYXN0cGF0aCBmb3IgdGhlIGJ5LW5hbWUgcXVlcnk7IHdlIHNlYXJjaAotICogbGluZWFybHkgdW50aWwgd2UgZmluZCBpdCBvciBmYWlsIHRvIGZpbmQgaXQuIEFnYWluLCB0aGF0IGNvdWxkIGJlCi0gKiBvcHRpbWl6ZWQgYXQgc29tZSBjb3N0IGluIG9iamVjdCBjcmVhdGlvbi9zdG9yYWdlLgotICovCi1wdWJsaWMgY2xhc3MgRFRNTmFtZWROb2RlTWFwIGltcGxlbWVudHMgTmFtZWROb2RlTWFwCi17Ci0KLSAgLyoqIFRoZSBEVE0gZm9yIHRoaXMgbm9kZS4gKi8KLSAgRFRNIGR0bTsKLQotICAvKiogVGhlIERUTSBlbGVtZW50IGhhbmRsZS4gKi8KLSAgaW50IGVsZW1lbnQ7Ci0KLSAgLyoqIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhpcyBtYXAuICovCi0gIHNob3J0IG1fY291bnQgPSAtMTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgZ2V0QXR0cmlidXRlcyBOYW1lZE5vZGVNYXAgZm9yIGEgZ2l2ZW4gRFRNIGVsZW1lbnQgbm9kZQotICAgKgotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gUmVmZXJlbmNlLCBtdXN0IGJlIG5vbi1udWxsLgotICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgRFRNIGVsZW1lbnQgaGFuZGxlLgotICAgKi8KLSAgRFRNTmFtZWROb2RlTWFwKERUTSBkdG0sIGludCBlbGVtZW50KQotICB7Ci0gICAgdGhpcy5kdG0gPSBkdG07Ci0gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBBdHRyaWJ1dGVzIG9uIHRoaXMgRWxlbWVudAotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhpcyBtYXAuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLQotICAgIGlmIChtX2NvdW50ID09IC0xKQotICAgIHsKLSAgICAgIHNob3J0IGNvdW50ID0gMDsKLQotICAgICAgZm9yIChpbnQgbiA9IGR0bS5nZXRGaXJzdEF0dHJpYnV0ZShlbGVtZW50KTsgbiAhPSAtMTsKLSAgICAgICAgICAgICAgbiA9IGR0bS5nZXROZXh0QXR0cmlidXRlKG4pKQotICAgICAgewotICAgICAgICArK2NvdW50OwotICAgICAgfQotCi0gICAgICBtX2NvdW50ID0gY291bnQ7Ci0gICAgfQotCi0gICAgcmV0dXJuIChpbnQpIG1fY291bnQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmVzIGEgbm9kZSBzcGVjaWZpZWQgYnkgbmFtZS4KLSAgICogQHBhcmFtIG5hbWVUaGUgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IG9mIGEgbm9kZSB0byByZXRyaWV2ZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgaXRlbSBiZWluZyByZXF1ZXN0ZWQuCi0gICAqIEByZXR1cm4gQSA8Y29kZT5Ob2RlPC9jb2RlPiAob2YgYW55IHR5cGUpIHdpdGggdGhlIHNwZWNpZmllZAotICAgKiAgIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgaXQgZG9lcyBub3QgaWRlbnRpZnkKLSAgICogICBhbnkgbm9kZSBpbiB0aGlzIG1hcC4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldE5hbWVkSXRlbShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgZm9yIChpbnQgbiA9IGR0bS5nZXRGaXJzdEF0dHJpYnV0ZShlbGVtZW50KTsgbiAhPSAtMTsKLSAgICAgICAgICAgIG4gPSBkdG0uZ2V0TmV4dEF0dHJpYnV0ZShuKSkKLSAgICB7Ci0gICAgICBpZiAoZHRtLmdldE5vZGVOYW1lKG4pLmVxdWFscyhuYW1lKSkKLSAgICAgICAgcmV0dXJuIGR0bS5nZXROb2RlKG4pOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIGl0ZW0gaW4gdGhlIG1hcC4gSWYgPGNvZGU+aW5kZXg8L2NvZGU+Ci0gICAqIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbWFwLCB0aGlzCi0gICAqIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIEBwYXJhbSBpbmRleEluZGV4IGludG8gdGhpcyBtYXAuCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBpbmRleCBvZiB0aGUgcmVxdWVzdGVkIGl0ZW0uCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZSBtYXAsIG9yCi0gICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZCBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGl0ZW0oaW50IGkpCi0gIHsKLQotICAgIGludCBjb3VudCA9IDA7Ci0KLSAgICBmb3IgKGludCBuID0gZHRtLmdldEZpcnN0QXR0cmlidXRlKGVsZW1lbnQpOyBuICE9IC0xOwotICAgICAgICAgICAgbiA9IGR0bS5nZXROZXh0QXR0cmlidXRlKG4pKQotICAgIHsKLSAgICAgIGlmIChjb3VudCA9PSBpKQotICAgICAgICByZXR1cm4gZHRtLmdldE5vZGUobik7Ci0gICAgICBlbHNlCi0gICAgICAgICsrY291bnQ7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQWRkcyBhIG5vZGUgdXNpbmcgaXRzIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiBhdHRyaWJ1dGUuIElmIGEgbm9kZSB3aXRoCi0gICAqIHRoYXQgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKLSAgICogb25lLgotICAgKiA8YnI+QXMgdGhlIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiBhdHRyaWJ1dGUgaXMgdXNlZCB0byBkZXJpdmUgdGhlIG5hbWUKLSAgICogd2hpY2ggdGhlIG5vZGUgbXVzdCBiZSBzdG9yZWQgdW5kZXIsIG11bHRpcGxlIG5vZGVzIG9mIGNlcnRhaW4gdHlwZXMKLSAgICogKHRob3NlIHRoYXQgaGF2ZSBhICJzcGVjaWFsIiBzdHJpbmcgdmFsdWUpIGNhbm5vdCBiZSBzdG9yZWQgYXMgdGhlCi0gICAqIG5hbWVzIHdvdWxkIGNsYXNoLiBUaGlzIGlzIHNlZW4gYXMgcHJlZmVyYWJsZSB0byBhbGxvd2luZyBub2RlcyB0byBiZQotICAgKiBhbGlhc2VkLgotICAgKiBAcGFyYW0gbmV3Tm9kZSBub2RlIHRvIHN0b3JlIGluIHRoaXMgbWFwLiBUaGUgbm9kZSB3aWxsIGxhdGVyIGJlCi0gICAqICAgYWNjZXNzaWJsZSB1c2luZyB0aGUgdmFsdWUgb2YgaXRzIDxjb2RlPm5vZGVOYW1lPC9jb2RlPiBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEByZXR1cm4gSWYgdGhlIG5ldyA8Y29kZT5Ob2RlPC9jb2RlPiByZXBsYWNlcyBhbiBleGlzdGluZyBub2RlIHRoZQotICAgKiAgIHJlcGxhY2VkIDxjb2RlPk5vZGU8L2NvZGU+IGlzIHJldHVybmVkLCBvdGhlcndpc2UgPGNvZGU+bnVsbDwvY29kZT4KLSAgICogICBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICogICBXUk9OR19ET0NVTUVOVF9FUlI6IFJhaXNlZCBpZiA8Y29kZT5hcmc8L2NvZGU+IHdhcyBjcmVhdGVkIGZyb20gYQotICAgKiAgIGRpZmZlcmVudCBkb2N1bWVudCB0aGFuIHRoZSBvbmUgdGhhdCBjcmVhdGVkIHRoaXMgbWFwLgotICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICogICA8YnI+SU5VU0VfQVRUUklCVVRFX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gaXMgYW4KLSAgICogICA8Y29kZT5BdHRyPC9jb2RlPiB0aGF0IGlzIGFscmVhZHkgYW4gYXR0cmlidXRlIG9mIGFub3RoZXIKLSAgICogICA8Y29kZT5FbGVtZW50PC9jb2RlPiBvYmplY3QuIFRoZSBET00gdXNlciBtdXN0IGV4cGxpY2l0bHkgY2xvbmUKLSAgICogICA8Y29kZT5BdHRyPC9jb2RlPiBub2RlcyB0byByZS11c2UgdGhlbSBpbiBvdGhlciBlbGVtZW50cy4KLSAgICovCi0gIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbShOb2RlIG5ld05vZGUpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKERUTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgYSBub2RlIHNwZWNpZmllZCBieSBuYW1lLiBXaGVuIHRoaXMgbWFwIGNvbnRhaW5zIHRoZSBhdHRyaWJ1dGVzCi0gICAqIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQsIGlmIHRoZSByZW1vdmVkIGF0dHJpYnV0ZSBpcyBrbm93biB0byBoYXZlIGEKLSAgICogZGVmYXVsdCB2YWx1ZSwgYW4gYXR0cmlidXRlIGltbWVkaWF0ZWx5IGFwcGVhcnMgY29udGFpbmluZyB0aGUKLSAgICogZGVmYXVsdCB2YWx1ZSBhcyB3ZWxsIGFzIHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBVUkksIGxvY2FsIG5hbWUsCi0gICAqIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgPGNvZGU+bm9kZU5hbWU8L2NvZGU+IG9mIHRoZSBub2RlIHRvIHJlbW92ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSByZW1vdmVkIGZyb20gdGhpcyBtYXAgaWYgYSBub2RlIHdpdGggc3VjaCBhIG5hbWUKLSAgICogICBleGlzdHMuCi0gICAqIEBleGNlcHRpb24gRE9NRXhjZXB0aW9uCi0gICAqICAgTk9UX0ZPVU5EX0VSUjogUmFpc2VkIGlmIHRoZXJlIGlzIG5vIG5vZGUgbmFtZWQgPGNvZGU+bmFtZTwvY29kZT4gaW4KLSAgICogICB0aGlzIG1hcC4KLSAgICogICA8YnI+Tk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSOiBSYWlzZWQgaWYgdGhpcyBtYXAgaXMgcmVhZG9ubHkuCi0gICAqLwotICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW0oU3RyaW5nIG5hbWUpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKERUTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlcyBhIG5vZGUgc3BlY2lmaWVkIGJ5IGxvY2FsIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuIEhUTUwtb25seQotICAgKiBET00gaW1wbGVtZW50YXRpb25zIGRvIG5vdCBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZC4KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZXRyaWV2ZS4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgbm9kZSB0byByZXRyaWV2ZS4KLSAgICoKLSAgICogQHJldHVybiBBIDxjb2RlPk5vZGU8L2NvZGU+IChvZiBhbnkgdHlwZSkgd2l0aCB0aGUgc3BlY2lmaWVkIGxvY2FsCi0gICAqICAgbmFtZSBhbmQgbmFtZXNwYWNlIFVSSSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhleSBkbyBub3QKLSAgICogICBpZGVudGlmeSBhbnkgbm9kZSBpbiB0aGlzIG1hcC4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXROYW1lZEl0ZW1OUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTUV4Y2VwdGlvbihEVE1FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZHMgYSBub2RlIHVzaW5nIGl0cyA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZAotICAgKiA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+LiBJZiBhIG5vZGUgd2l0aCB0aGF0IG5hbWVzcGFjZSBVUkkgYW5kIHRoYXQKLSAgICogbG9jYWwgbmFtZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gdGhpcyBtYXAsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcKLSAgICogb25lLgotICAgKiA8YnI+SFRNTC1vbmx5IERPTSBpbXBsZW1lbnRhdGlvbnMgZG8gbm90IG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kLgotICAgKiBAcGFyYW0gYXJnIEEgbm9kZSB0byBzdG9yZSBpbiB0aGlzIG1hcC4gVGhlIG5vZGUgd2lsbCBsYXRlciBiZQotICAgKiAgIGFjY2Vzc2libGUgdXNpbmcgdGhlIHZhbHVlIG9mIGl0cyA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZAotICAgKiAgIDxjb2RlPmxvY2FsTmFtZTwvY29kZT4gYXR0cmlidXRlcy4KLSAgICoKLSAgICogQHJldHVybiBJZiB0aGUgbmV3IDxjb2RlPk5vZGU8L2NvZGU+IHJlcGxhY2VzIGFuIGV4aXN0aW5nIG5vZGUgdGhlCi0gICAqICAgcmVwbGFjZWQgPGNvZGU+Tm9kZTwvY29kZT4gaXMgcmV0dXJuZWQsIG90aGVyd2lzZSA8Y29kZT5udWxsPC9jb2RlPgotICAgKiAgIGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIERPTUV4Y2VwdGlvbgotICAgKiAgIFdST05HX0RPQ1VNRU5UX0VSUjogUmFpc2VkIGlmIDxjb2RlPmFyZzwvY29kZT4gd2FzIGNyZWF0ZWQgZnJvbSBhCi0gICAqICAgZGlmZmVyZW50IGRvY3VtZW50IHRoYW4gdGhlIG9uZSB0aGF0IGNyZWF0ZWQgdGhpcyBtYXAuCi0gICAqICAgPGJyPk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUjogUmFpc2VkIGlmIHRoaXMgbWFwIGlzIHJlYWRvbmx5LgotICAgKiAgIDxicj5JTlVTRV9BVFRSSUJVVEVfRVJSOiBSYWlzZWQgaWYgPGNvZGU+YXJnPC9jb2RlPiBpcyBhbgotICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IHRoYXQgaXMgYWxyZWFkeSBhbiBhdHRyaWJ1dGUgb2YgYW5vdGhlcgotICAgKiAgIDxjb2RlPkVsZW1lbnQ8L2NvZGU+IG9iamVjdC4gVGhlIERPTSB1c2VyIG11c3QgZXhwbGljaXRseSBjbG9uZQotICAgKiAgIDxjb2RlPkF0dHI8L2NvZGU+IG5vZGVzIHRvIHJlLXVzZSB0aGVtIGluIG90aGVyIGVsZW1lbnRzLgotICAgKiBAc2luY2UgRE9NIExldmVsIDIKLSAgICovCi0gIHB1YmxpYyBOb2RlIHNldE5hbWVkSXRlbU5TKE5vZGUgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRXhjZXB0aW9uKERUTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgYSBub2RlIHNwZWNpZmllZCBieSBsb2NhbCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLiBBIHJlbW92ZWQKLSAgICogYXR0cmlidXRlIG1heSBiZSBrbm93biB0byBoYXZlIGEgZGVmYXVsdCB2YWx1ZSB3aGVuIHRoaXMgbWFwIGNvbnRhaW5zCi0gICAqIHRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQsIGFzIHJldHVybmVkIGJ5IHRoZSBhdHRyaWJ1dGVzCi0gICAqIGF0dHJpYnV0ZSBvZiB0aGUgPGNvZGU+Tm9kZTwvY29kZT4gaW50ZXJmYWNlLiBJZiBzbywgYW4gYXR0cmlidXRlCi0gICAqIGltbWVkaWF0ZWx5IGFwcGVhcnMgY29udGFpbmluZyB0aGUgZGVmYXVsdCB2YWx1ZSBhcyB3ZWxsIGFzIHRoZQotICAgKiBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBVUkksIGxvY2FsIG5hbWUsIGFuZCBwcmVmaXggd2hlbiBhcHBsaWNhYmxlLgotICAgKiA8YnI+SFRNTC1vbmx5IERPTSBpbXBsZW1lbnRhdGlvbnMgZG8gbm90IG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kLgotICAgKiAKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgbm9kZSB0byByZW1vdmUuCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIG5vZGUgdG8gcmVtb3ZlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHJlbW92ZWQgZnJvbSB0aGlzIG1hcCBpZiBhIG5vZGUgd2l0aCBzdWNoIGEgbG9jYWwKLSAgICogICBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJIGV4aXN0cy4KLSAgICogQGV4Y2VwdGlvbiBET01FeGNlcHRpb24KLSAgICogICBOT1RfRk9VTkRfRVJSOiBSYWlzZWQgaWYgdGhlcmUgaXMgbm8gbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQKLSAgICogICA8Y29kZT5uYW1lc3BhY2VVUkk8L2NvZGU+IGFuZCA8Y29kZT5sb2NhbE5hbWU8L2NvZGU+IGluIHRoaXMgbWFwLgotICAgKiAgIDxicj5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlI6IFJhaXNlZCBpZiB0aGlzIG1hcCBpcyByZWFkb25seS4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgTm9kZSByZW1vdmVOYW1lZEl0ZW1OUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1FeGNlcHRpb24oRFRNRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBET01FeGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgY2xhc3MgRFRNRXhjZXB0aW9uIGV4dGVuZHMgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdHMgYSBET00vRFRNIGV4Y2VwdGlvbi4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb2RlCi0gICAgICogQHBhcmFtIG1lc3NhZ2UKLSAgICAgKi8KLSAgICBwdWJsaWMgRFRNRXhjZXB0aW9uKHNob3J0IGNvZGUsIFN0cmluZyBtZXNzYWdlKQotICAgIHsKLSAgICAgIHN1cGVyKGNvZGUsIG1lc3NhZ2UpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIENvbnN0cnVjdG9yIERUTUV4Y2VwdGlvbgotICAgICAqCi0gICAgICoKLSAgICAgKiBAcGFyYW0gY29kZQotICAgICAqLwotICAgIHB1YmxpYyBEVE1FeGNlcHRpb24oc2hvcnQgY29kZSkKLSAgICB7Ci0gICAgICBzdXBlcihjb2RlLCAiIik7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1Ob2RlSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTU5vZGVJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MWRmYjk4Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTU5vZGVJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjE2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLio7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLio7Ci0KLS8qKgotICogPGNvZGU+RFRNTm9kZUl0ZXJhdG9yPC9jb2RlPiBnaXZlcyB1cyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgCi0gKiBEVE1Ob2RlSXRlcmF0b3Igd2hpY2ggcmV0dXJucyBET00gbm9kZXMuCi0gKgotICogUGxlYXNlIG5vdGUgdGhhdCB0aGlzIGlzIG5vdCBuZWNlc3NhcmlseSBlcXVpdmxhZW50IHRvIGEgRE9NCi0gKiBOb2RlSXRlcmF0b3Igb3BlcmF0aW5nIG92ZXIgdGhlIHNhbWUgZG9jdW1lbnQuIEluIHBhcnRpY3VsYXI6Ci0gKiA8dWw+Ci0gKgotICogPGxpPklmIHRoZXJlIGFyZSBzZXZlcmFsIFRleHQgbm9kZXMgaW4gbG9naWNhbCBzdWNjZXNzaW9uIChpZSwKLSAqIGFjcm9zcyBDREFUQVNlY3Rpb24gYW5kIEVudGl0eVJlZmVyZW5jZSBib3VuZGFyaWVzKSwgd2Ugd2lsbCByZXR1cm4KLSAqIG9ubHkgdGhlIGZpcnN0OyB0aGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBzdGVwcGluZyB0aHJvdWdoCi0gKiB0aGVtLgotICogKCVSRVZJRVclIFByb3ZpZGUgYSBjb252ZW5pZW5jZSByb3V0aW5lIGhlcmUgdG8gYXNzaXN0LCBwZW5kaW5nCi0gKiBwcm9wb3NlZCBET00gTGV2ZWwgMyBnZXRBZGphY2VudFRleHQoKSBvcGVyYXRpb24/KSA8L2xpPgotICoKLSAqIDxsaT5TaW5jZSB0aGUgd2hvbGUgWFBhdGgvWFNMVCBhcmNoaXRlY3R1cmUgYXNzdW1lcyB0aGF0IHRoZSBzb3VyY2UKLSAqIGRvY3VtZW50IGlzIG5vdCBhbHRlcmVkIHdoaWxlIHdlJ3JlIHdvcmtpbmcgd2l0aCBpdCwgd2UgZG8gbm90Ci0gKiBwcm9taXNlIHRvIGltcGxlbWVudCB0aGUgRE9NIE5vZGVJdGVyYXRvcidzICJtYWludGFpbiBjdXJyZW50Ci0gKiBwb3NpdGlvbiIgcmVzcG9uc2UgdG8gZG9jdW1lbnQgbXV0YXRpb24uIDwvbGk+Ci0gKgotICogPGxpPlNpbmNlIG91ciBkZXNpZ24gZm9yIFhQYXRoIE5vZGVJdGVyYXRvcnMgYnVpbGRzIGEgc3RhdGVmdWwKLSAqIGZpbHRlciBkaXJlY3RseSBpbnRvIHRoZSB0cmF2ZXJzYWwgb2JqZWN0LCBnZXROb2RlRmlsdGVyKCkgaXMgbm90Ci0gKiBzdXBwb3J0ZWQuPC9saT4KLSAqCi0gKiA8L3VsPgotICoKLSAqIDxwPlN0YXRlOiBJbiBwcm9ncmVzcyEhPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBEVE1Ob2RlSXRlcmF0b3IgaW1wbGVtZW50cyBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yCi17Ci0gIHByaXZhdGUgRFRNSXRlcmF0b3IgZHRtX2l0ZXI7Ci0gIHByaXZhdGUgYm9vbGVhbiB2YWxpZD10cnVlOwotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBNZXRob2RzIHVuaXF1ZSB0byB0aGlzIGNsYXNzCi0KLSAgLyoqIFB1YmxpYyBjb25zdHJ1Y3RvcjogV3JhcCBhIERUTU5vZGVJdGVyYXRvciBhcm91bmQgYW4gZXhpc3RpbmcKLSAgICogYW5kIHByZWNvbmZpZ3VyZWQgRFRNSXRlcmF0b3IKLSAgICogKi8KLSAgcHVibGljIERUTU5vZGVJdGVyYXRvcihEVE1JdGVyYXRvciBkdG1JdGVyYXRvcikKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZHRtX2l0ZXI9KERUTUl0ZXJhdG9yKWR0bUl0ZXJhdG9yLmNsb25lKCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oY25zZSk7Ci0gICAgICB9Ci0gICAgfQotCi0gIC8qKiBBY2Nlc3MgdGhlIHdyYXBwZWQgRFRNSXRlcmF0b3IuIEknbSBub3Qgc3VyZSB3aGV0aGVyIGFueW9uZSB3aWxsCi0gICAqIG5lZWQgdGhpcyBvciBub3QsIGJ1dCBsZXQncyB3cml0ZSBpdCBhbmQgdGhpbmsgYWJvdXQgaXQuCi0gICAqICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBnZXREVE1JdGVyYXRvcigpCi0gICAgewotICAgICAgcmV0dXJuIGR0bV9pdGVyOwotICAgIH0KLSAgCi0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyIEFQSSBmb2xsb3dzCi0KLSAgLyoqIERldGFjaGVzIHRoZSBOb2RlSXRlcmF0b3IgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsCi0gICAqIHJlbGVhc2luZyBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yIGluCi0gICAqIHRoZSBJTlZBTElEIHN0YXRlLgotICAgKiAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKSAKLSAgICB7Ci0gICAgICAvLyBUaGVvcmV0aWNhbGx5LCB3ZSBjb3VsZCByZWxlYXNlIGR0bV9pdGVyIGF0IHRoaXMgcG9pbnQuIEJ1dAotICAgICAgLy8gc29tZSBvZiB0aGUgb3BlcmF0aW9ucyBtYXkgc3RpbGwgd2FudCB0byBjb25zdWx0IGl0IGV2ZW4gdGhvdWdoCi0gICAgICAvLyBuYXZpZ2F0aW9uIGlzIG5vdyBpbnZhbGlkLgotICAgICAgdmFsaWQ9ZmFsc2U7Ci0gICAgfQotCi0gIC8qKiBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgY2hpbGRyZW4KLSAgICogb2YgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UsIGFsd2F5cyAodGhlIERUTSBtb2RlbCBmbGF0dGVucyBlbnRpdHkgcmVmZXJlbmNlcykKLSAgICogKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgCi0gIC8qKiBSZXR1cm4gYSBoYW5kbGUgdG8gdGhlIGZpbHRlciB1c2VkIHRvIHNjcmVlbiBub2Rlcy4KLSAgICoKLSAgICogVGhpcyBpcyBpbGwtZGVmaW5lZCBpbiBYYWxhbidzIHVzYWdlIG9mIE5vZGVpdGVyYXRvciwgd2hlcmUgd2UgaGF2ZQotICAgKiBidWlsdCBzdGF0ZWZ1bCBYUGF0aC1iYXNlZCBmaWx0ZXJpbmcgZGlyZWN0bHkgaW50byB0aGUgdHJhdmVyc2FsCi0gICAqIG9iamVjdC4gV2UgY291bGQgcmV0dXJuIHNvbWV0aGluZyB3aGljaCBzdXBwb3J0cyB0aGUgTm9kZUZpbHRlciBpbnRlcmZhY2UKLSAgICogYW5kIGFsbG93cyBxdWVyeWluZyB3aGV0aGVyIGEgZ2l2ZW4gbm9kZSB3b3VsZCBiZSBwZXJtaXR0ZWQgaWYgaXQgYXBwZWFyZWQKLSAgICogYXMgb3VyIG5leHQgbm9kZSwgYnV0IGluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIHRoYXQgd291bGQgYmUgdmVyeQotICAgKiBjb21wbGV4IC0tIGFuZCBqdXN0IGlzbid0IGFsbCB0aGF0IHVzZWZ1bC4KLSAgICogCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uIC0tIE5PVF9TVVBQT1JURURfRVJST1IgYmVjYXVzZSBJIGNhbid0IHRoaW5rCi0gICAqIG9mIGFueXRoaW5nIG1vcmUgdXNlZnVsIHRvIGRvIGluIHRoaXMgY2FzZQotICAgKiAqLwotICBwdWJsaWMgTm9kZUZpbHRlciBnZXRGaWx0ZXIoKSAKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gICAgfQotICAKLQotICAvKiogQHJldHVybiBUaGUgcm9vdCBub2RlIG9mIHRoZSBOb2RlSXRlcmF0b3IsIGFzIHNwZWNpZmllZAotICAgKiB3aGVuIGl0IHdhcyBjcmVhdGVkLgotICAgKiAqLwotICBwdWJsaWMgTm9kZSBnZXRSb290KCkKLSAgICB7Ci0gICAgICBpbnQgaGFuZGxlPWR0bV9pdGVyLmdldFJvb3QoKTsKLSAgICAgIHJldHVybiBkdG1faXRlci5nZXREVE0oaGFuZGxlKS5nZXROb2RlKGhhbmRsZSk7Ci0gICAgfQotICAKLQotICAvKiogUmV0dXJuIGEgbWFzayBkZXNjcmliaW5nIHdoaWNoIG5vZGUgdHlwZXMgYXJlIHByZXNlbnRlZCB2aWEgdGhlCi0gICAqIGl0ZXJhdG9yLgotICAgKiovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gICAgewotICAgICAgcmV0dXJuIGR0bV9pdGVyLmdldFdoYXRUb1Nob3coKTsKLSAgICB9Ci0KLSAgLyoqIEByZXR1cm4gdGhlIG5leHQgbm9kZSBpbiB0aGUgc2V0IGFuZCBhZHZhbmNlIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHRocm93IERPTUV4Y2VwdGlvbiAtIElOVkFMSURfU1RBVEVfRVJSIFJhaXNlZCBpZiB0aGlzIG1ldGhvZCBpcwotICAgKiBjYWxsZWQgYWZ0ZXIgdGhlIGRldGFjaCBtZXRob2Qgd2FzIGludm9rZWQuCi0gICAqICAqLwotICBwdWJsaWMgTm9kZSBuZXh0Tm9kZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgICB7Ci0gICAgICBpZighdmFsaWQpCi0gICAgICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSKTsKLSAgICAgIAotICAgICAgaW50IGhhbmRsZT1kdG1faXRlci5uZXh0Tm9kZSgpOwotICAgICAgaWYgKGhhbmRsZT09LTEpCi0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgcmV0dXJuIGR0bV9pdGVyLmdldERUTShoYW5kbGUpLmdldE5vZGUoaGFuZGxlKTsKLSAgICB9Ci0gIAotCi0gIC8qKiBAcmV0dXJuIHRoZSBuZXh0IHByZXZpb3VzIGluIHRoZSBzZXQgYW5kIGFkdmFuY2UgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAdGhyb3cgRE9NRXhjZXB0aW9uIC0gSU5WQUxJRF9TVEFURV9FUlIgUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzCi0gICAqIGNhbGxlZCBhZnRlciB0aGUgZGV0YWNoIG1ldGhvZCB3YXMgaW52b2tlZC4KLSAgICogICovCi0gIHB1YmxpYyBOb2RlIHByZXZpb3VzTm9kZSgpIAotICAgIHsKLSAgICAgIGlmKCF2YWxpZCkKLSAgICAgICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIpOwotICAgICAgCi0gICAgICBpbnQgaGFuZGxlPWR0bV9pdGVyLnByZXZpb3VzTm9kZSgpOwotICAgICAgcmV0dXJuIGR0bV9pdGVyLmdldERUTShoYW5kbGUpLmdldE5vZGUoaGFuZGxlKTsKLSAgICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1Ob2RlTGlzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNTm9kZUxpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDk2ODhlNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1Ob2RlTGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTUzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLio7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLS8qKgotICogPGNvZGU+RFRNTm9kZUxpc3Q8L2NvZGU+IGdpdmVzIHVzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBET00ncwotICogTm9kZUxpc3QgaW50ZXJmYWNlIHdyYXBwZWQgYXJvdW5kIGEgRFRNIEl0ZXJhdG9yLiBUaGUgYXV0aG9yCi0gKiBjb25zaWRlcnMgdGhpcyBzb21ldGhpbmcgb2YgYW4gYWJvbWluYXRpb25zLCBzaW5jZSBOb2RlTGlzdCB3YXMgbm90Ci0gKiBpbnRlbmRlZCB0byBiZSBhIGdlbmVyYWwgcHVycG9zZSAibGlzdCBvZiBub2RlcyIgQVBJIGFuZCBpcwotICogZ2VuZXJhbGx5IGNvbnNpZGVyZWQgYnkgdGhlIERPTSBXRyB0byBoYXZlIGJlIGEgbWlzdGFrZS4uLiBidXQgSSdtCi0gKiB0b2xkIHRoYXQgc29tZSBvZiB0aGUgWFBhdGgvWFNMVCBmb2xrcyBzYXkgdGhleSBtdXN0IGhhdmUgdGhpcwotICogc29sdXRpb24uCi0gKgotICogUGxlYXNlIG5vdGUgdGhhdCB0aGlzIGlzIG5vdCBuZWNlc3NhcmlseSBlcXVpdmxhZW50IHRvIGEgRE9NCi0gKiBOb2RlTGlzdCBvcGVyYXRpbmcgb3ZlciB0aGUgc2FtZSBkb2N1bWVudC4gSW4gcGFydGljdWxhcjoKLSAqIDx1bD4KLSAqCi0gKiA8bGk+SWYgdGhlcmUgYXJlIHNldmVyYWwgVGV4dCBub2RlcyBpbiBsb2dpY2FsIHN1Y2Nlc3Npb24gKGllLAotICogYWNyb3NzIENEQVRBU2VjdGlvbiBhbmQgRW50aXR5UmVmZXJlbmNlIGJvdW5kYXJpZXMpLCB3ZSB3aWxsIHJldHVybgotICogb25seSB0aGUgZmlyc3Q7IHRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIHN0ZXBwaW5nIHRocm91Z2gKLSAqIHRoZW0uCi0gKiAoJVJFVklFVyUgUHJvdmlkZSBhIGNvbnZlbmllbmNlIHJvdXRpbmUgaGVyZSB0byBhc3Npc3QsIHBlbmRpbmcKLSAqIHByb3Bvc2VkIERPTSBMZXZlbCAzIGdldEFkamFjZW50VGV4dCgpIG9wZXJhdGlvbj8pIDwvbGk+Ci0gKgotICogPGxpPlNpbmNlIHRoZSB3aG9sZSBYUGF0aC9YU0xUIGFyY2hpdGVjdHVyZSBhc3N1bWVzIHRoYXQgdGhlIHNvdXJjZQotICogZG9jdW1lbnQgaXMgbm90IGFsdGVyZWQgd2hpbGUgd2UncmUgd29ya2luZyB3aXRoIGl0LCB3ZSBkbyBub3QKLSAqIHByb21pc2UgdG8gaW1wbGVtZW50IHRoZSBET00gTm9kZUxpc3QncyAibGl2ZSB2aWV3IiByZXNwb25zZSB0bwotICogZG9jdW1lbnQgbXV0YXRpb24uIDwvbGk+Ci0gKgotICogPC91bD4KLSAqCi0gKiA8cD5TdGF0ZTogSW4gcHJvZ3Jlc3MhITwvcD4KLSAqICovCi1wdWJsaWMgY2xhc3MgRFRNTm9kZUxpc3QgaW1wbGVtZW50cyBvcmcudzNjLmRvbS5Ob2RlTGlzdAotewotICBwcml2YXRlIERUTUl0ZXJhdG9yIGR0bV9pdGVyOwotICBwcml2YXRlIGJvb2xlYW4gdmFsaWQ9dHJ1ZTsKLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gTWV0aG9kcyB1bmlxdWUgdG8gdGhpcyBjbGFzcwotCi0gIC8qKiBQdWJsaWMgY29uc3RydWN0b3I6IFdyYXAgYSBEVE1Ob2RlTGlzdCBhcm91bmQgYW4gZXhpc3RpbmcKLSAgICogYW5kIHByZWNvbmZpZ3VyZWQgRFRNSXRlcmF0b3IKLSAgICoKLSAgICogV0FSTklORzogVEhJUyBIQVMgVEhFIFNJREUgRUZGRUNUIE9GIElTU1VJTkcgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKQotICAgKiBBR0FJTlNUIFRIRSBEVE1JdGVyYXRvci4KLSAgICogKi8KLSAgcHVibGljIERUTU5vZGVMaXN0KERUTUl0ZXJhdG9yIGR0bUl0ZXJhdG9yKQotICAgIHsKLSAgICAgIGludCBwb3MgPSBkdG1JdGVyYXRvci5nZXRDdXJyZW50UG9zKCk7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZHRtX2l0ZXI9KERUTUl0ZXJhdG9yKWR0bUl0ZXJhdG9yLmNsb25lV2l0aFJlc2V0KCk7Ci0gICAgICB9Ci0gICAgICBjYXRjaChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKSB7fQotICAgICAgZHRtX2l0ZXIuc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKTsKLSAgICAgIGR0bV9pdGVyLnJ1blRvKC0xKTsKLSAgICAgIGR0bV9pdGVyLnNldEN1cnJlbnRQb3MocG9zKTsKLSAgICB9Ci0KLSAgLyoqIEFjY2VzcyB0aGUgd3JhcHBlZCBEVE1JdGVyYXRvci4gSSdtIG5vdCBzdXJlIHdoZXRoZXIgYW55b25lIHdpbGwKLSAgICogbmVlZCB0aGlzIG9yIG5vdCwgYnV0IGxldCdzIHdyaXRlIGl0IGFuZCB0aGluayBhYm91dCBpdC4KLSAgICogKi8KLSAgRFRNSXRlcmF0b3IgZ2V0RFRNSXRlcmF0b3IoKQotICAgIHsKLSAgICAgIHJldHVybiBkdG1faXRlcjsKLSAgICB9Ci0gIAotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBvcmcudzNjLmRvbS5Ob2RlTGlzdCBBUEkgZm9sbG93cwotCi0gICAgLyoqCi0gICAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYgCi0gICAgICogPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIAotICAgICAqIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAgICogQHBhcmFtIGluZGV4SW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBwb3NpdGlvbiBpbiB0aGUgCi0gICAgICogICA8Y29kZT5Ob2RlTGlzdDwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMgbm90IGEgdmFsaWQgCi0gICAgICogICBpbmRleC4KLSAgICAgKi8KLSAgICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCkKLSAgICB7Ci0gICAgICBpbnQgaGFuZGxlPWR0bV9pdGVyLml0ZW0oaW5kZXgpOwotICAgICAgcmV0dXJuIGR0bV9pdGVyLmdldERUTShoYW5kbGUpLmdldE5vZGUoaGFuZGxlKTsKLSAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzIAotICAgICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4gCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMZW5ndGgoKQotICAgIHsKLSAgICAgICAgcmV0dXJuIGR0bV9pdGVyLmdldExlbmd0aCgpOwotICAgIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTU5vZGVQcm94eS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNTm9kZVByb3h5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlkY2E3NmIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNTm9kZVByb3h5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjgzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogPGNvZGU+RFRNTm9kZVByb3h5PC9jb2RlPiBwcmVzZW50cyBhIERPTSBOb2RlIEFQSSBmcm9udC1lbmQgdG8gdGhlIERUTSBtb2RlbC4KLSAqIDxwPgotICogSXQgZG9lcyBfbm90XyBhdHRlbXB0IHRvIGFkZHJlc3MgdGhlICJub2RlIGlkZW50aXR5IiBxdWVzdGlvbjsgbm8gZWZmb3J0Ci0gKiBpcyBtYWRlIHRvIHByZXZlbnQgdGhlIGNyZWF0aW9uIG9mIG11bHRpcGxlIHByb3hpZXMgcmVmZXJyaW5nIHRvIGEgc2luZ2xlCi0gKiBEVE0gbm9kZS4gVXNlcnMgY2FuIGNyZWF0ZSBhIG1lY2hhbmlzbSBmb3IgbWFuYWdpbmcgdGhpcywgb3IgcmVsaW5xdWlzaCB0aGUKLSAqIHVzZSBvZiAiPT0iIGFuZCB1c2UgdGhlIC5zYW1lTm9kZUFzKCkgbWVjaGFuaXNtLCB3aGljaCBpcyB1bmRlcgotICogY29uc2lkZXJhdGlvbiBmb3IgZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBET00uCi0gKiA8cD4KLSAqIERUTU5vZGVQcm94eSBtYXkgYmUgc3ViY2xhc3NlZCBmdXJ0aGVyIHRvIHByZXNlbnQgc3BlY2lmaWMgRE9NIG5vZGUgdHlwZXMuCi0gKgotICogQHNlZSBvcmcudzNjLmRvbQotICovCi1wdWJsaWMgY2xhc3MgRFRNTm9kZVByb3h5Ci0gICAgICAgIGltcGxlbWVudHMgTm9kZSwgRG9jdW1lbnQsIFRleHQsIEVsZW1lbnQsIEF0dHIsCi0gICAgICAgICAgICAgICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uLCBDb21tZW50LCBEb2N1bWVudEZyYWdtZW50Ci17Ci0KLSAgLyoqIFRoZSBEVE0gZm9yIHRoaXMgbm9kZS4gKi8KLSAgcHVibGljIERUTSBkdG07Ci0KLSAgLyoqIFRoZSBEVE0gbm9kZSBoYW5kbGUuICovCi0gIGludCBub2RlOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBEVE1Ob2RlUHJveHkgTm9kZSByZXByZXNlbnRpbmcgYSBzcGVjaWZpYyBOb2RlIGluIGEgRFRNCi0gICAqCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBSZWZlcmVuY2UsIG11c3QgYmUgbm9uLW51bGwuCi0gICAqIEBwYXJhbSBub2RlIFRoZSBEVE0gbm9kZSBoYW5kbGUuCi0gICAqLwotICBEVE1Ob2RlUHJveHkoRFRNIGR0bSwgaW50IG5vZGUpCi0gIHsKLSAgICB0aGlzLmR0bSA9IGR0bTsKLSAgICB0aGlzLm5vZGUgPSBub2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIE5PTi1ET006IFJldHVybiB0aGUgRFRNIG1vZGVsCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIERUTSB0aGF0IHRoaXMgcHJveHkgaXMgYSByZXByZXNlbnRhdGl2ZSBmb3IuCi0gICAqLwotICBwdWJsaWMgZmluYWwgRFRNIGdldERUTSgpCi0gIHsKLSAgICByZXR1cm4gZHRtOwotICB9Ci0KLSAgLyoqCi0gICAqIE5PTi1ET006IFJldHVybiB0aGUgRFRNIG5vZGUgbnVtYmVyCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIERUTSBub2RlIGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0RFRNTm9kZU51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0IGZvciBlcXVhbGl0eSBiYXNlZCBvbiBub2RlIG51bWJlci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgQSBEVE0gbm9kZSBwcm94eSByZWZlcmVuY2UuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBoYXMgdGhlIHNhbWUgaGFuZGxlIGFzIHRoaXMgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGVxdWFscyhOb2RlIG5vZGUpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIERUTU5vZGVQcm94eSBkdG1wID0gKERUTU5vZGVQcm94eSkgbm9kZTsKLQotICAgICAgLy8gcmV0dXJuIChkdG1wLm5vZGUgPT0gdGhpcy5ub2RlKTsKLSAgICAgIC8vIFBhdGNoIGF0dHJpYnV0ZWQgdG8gR2FyeSBMIFBlc2tpbiA8Z2FyeXBAZmlyc3RlY2guY29tPgotICAgICAgcmV0dXJuIChkdG1wLm5vZGUgPT0gdGhpcy5ub2RlKSAmJiAoZHRtcC5kdG0gPT0gdGhpcy5kdG0pOwotICAgIH0KLSAgICBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3QgZm9yIGVxdWFsaXR5IGJhc2VkIG9uIG5vZGUgbnVtYmVyLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBBIERUTSBub2RlIHByb3h5IHJlZmVyZW5jZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBub2RlIGhhcyB0aGUgc2FtZSBoYW5kbGUgYXMgdGhpcyBub2RlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBub2RlKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIERUTU5vZGVQcm94eSBkdG1wID0gKERUTU5vZGVQcm94eSlub2RlOwotICAgICAgLy8gcmV0dXJuIChkdG1wLm5vZGUgPT0gdGhpcy5ub2RlKTsKLSAgICAgIC8vIFBhdGNoIGF0dHJpYnV0ZWQgdG8gR2FyeSBMIFBlc2tpbiA8Z2FyeXBAZmlyc3RlY2guY29tPgotICAgICAgcmV0dXJuIGVxdWFscygoTm9kZSkgbm9kZSk7Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRlVUVVJFIERPTTogVGVzdCBub2RlIGlkZW50aXR5LCBpbiBsaWV1IG9mIE5vZGU9PU5vZGUKLSAgICoKLSAgICogQHBhcmFtIG90aGVyCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbm9kZSBoYXMgdGhlIHNhbWUgaGFuZGxlIGFzIHRoaXMgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIHNhbWVOb2RlQXMoTm9kZSBvdGhlcikKLSAgewotCi0gICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBEVE1Ob2RlUHJveHkpKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgRFRNTm9kZVByb3h5IHRoYXQgPSAoRFRNTm9kZVByb3h5KSBvdGhlcjsKLQotICAgIHJldHVybiB0aGlzLmR0bSA9PSB0aGF0LmR0bSAmJiB0aGlzLm5vZGUgPT0gdGhhdC5ub2RlOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldE5vZGVOYW1lKCkKLSAgewotICAgIHJldHVybiBkdG0uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogQSBQSSdzICJ0YXJnZXQiIHN0YXRlcyB3aGF0IHByb2Nlc3NvciBjaGFubmVsIHRoZSBQSSdzIGRhdGEKLSAgICogc2hvdWxkIGJlIGRpcmVjdGVkIHRvLiBJdCBpcyBkZWZpbmVkIGRpZmZlcmVudGx5IGluIEhUTUwgYW5kIFhNTC4KLSAgICogPHA+Ci0gICAqIEluIFhNTCwgYSBQSSdzICJ0YXJnZXQiIGlzIHRoZSBmaXJzdCAod2hpdGVzcGFjZS1kZWxpbWl0ZWQpIHRva2VuCi0gICAqIGZvbGxvd2luZyB0aGUgIjw/IiB0b2tlbiB0aGF0IGJlZ2lucyB0aGUgUEkuCi0gICAqIDxwPgotICAgKiBJbiBIVE1MLCB0YXJnZXQgaXMgYWx3YXlzIG51bGwuCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgZ2V0Tm9kZU5hbWUgaXMgYWxpYXNlZCB0byBnZXRUYXJnZXQuCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0VGFyZ2V0KCkKLSAgewotICAgIHJldHVybiBkdG0uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0gIH0gIC8vIGdldFRhcmdldCgpOlN0cmluZwotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRMb2NhbE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXRMb2NhbE5hbWUobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogQHJldHVybiBUaGUgcHJlZml4IGZvciB0aGlzIG5vZGUuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRQcmVmaXgoKQotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXRQcmVmaXgobm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIHByZWZpeAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYXMgb2YgRE9NIExldmVsIDIgLS0gRFRNTm9kZVByb3h5IGlzIHJlYWQtb25seQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0UHJlZml4KFN0cmluZyBwcmVmaXgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKCkKLSAgewotICAgIHJldHVybiBkdG0uZ2V0TmFtZXNwYWNlVVJJKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBmZWF0dXJlCi0gICAqIEBwYXJhbSB2ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlIGFzIG9mIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBzdXBwb3J0cyhTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIGZlYXR1cmUKLSAgICogQHBhcmFtIHZlcnNpb24KLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzU3VwcG9ydGVkKFN0cmluZyBmZWF0dXJlLCBTdHJpbmcgdmVyc2lvbikKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXROb2RlVmFsdWUoKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotLy8gICAgLy8gKioqKiogQVNTVU1QVElPTjogQVRUUklCVVRFUyBIQVZFIFNJTkdMRSBURVhULU5PREUgQ0hJTEQuCi0vLyAgICAvLyAoU0lNSUxBUiBBU1NVTVBUSU9OIENVUlJFTlRMWSBNQURFIElOIERUTTsgQkUgU1VSRSBUTwotLy8gICAgLy8gUkVWSVNJVCBUSElTIElGIFRIQVQgQ0hBTkdFUyEpCi0vLyAgICBpZiAoZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkFUVFJJQlVURV9OT0RFKQotLy8gICAgICByZXR1cm4gZHRtLmdldE5vZGVWYWx1ZShub2RlICsgMSk7Ci0KLSAgICByZXR1cm4gZHRtLmdldE5vZGVWYWx1ZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbm9kZVZhbHVlCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXROb2RlVmFsdWUoU3RyaW5nIG5vZGVWYWx1ZSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIHNob3J0IGdldE5vZGVUeXBlKCkKLSAgewotICAgIHJldHVybiAoc2hvcnQpIGR0bS5nZXROb2RlVHlwZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgZ2V0UGFyZW50Tm9kZSgpCi0gIHsKLQotICAgIGlmIChnZXROb2RlVHlwZSgpID09IE5vZGUuQVRUUklCVVRFX05PREUpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIGludCBuZXdub2RlID0gZHRtLmdldFBhcmVudChub2RlKTsKLQotICAgIHJldHVybiAobmV3bm9kZSA9PSAtMSkgPyBudWxsIDogZHRtLmdldE5vZGUobmV3bm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlIGdldE93bmVyTm9kZSgpCi0gIHsKLQotICAgIGludCBuZXdub2RlID0gZHRtLmdldFBhcmVudChub2RlKTsKLQotICAgIHJldHVybiAobmV3bm9kZSA9PSAtMSkgPyBudWxsIDogZHRtLmdldE5vZGUobmV3bm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlTGlzdCBnZXRDaGlsZE5vZGVzKCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgZ2V0Rmlyc3RDaGlsZCgpCi0gIHsKLQotICAgIGludCBuZXdub2RlID0gZHRtLmdldEZpcnN0Q2hpbGQobm9kZSk7Ci0KLSAgICByZXR1cm4gKG5ld25vZGUgPT0gLTEpID8gbnVsbCA6IGR0bS5nZXROb2RlKG5ld25vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBnZXRMYXN0Q2hpbGQoKQotICB7Ci0KLSAgICBpbnQgbmV3bm9kZSA9IGR0bS5nZXRMYXN0Q2hpbGQobm9kZSk7Ci0KLSAgICByZXR1cm4gKG5ld25vZGUgPT0gLTEpID8gbnVsbCA6IGR0bS5nZXROb2RlKG5ld25vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBnZXRQcmV2aW91c1NpYmxpbmcoKQotICB7Ci0KLSAgICBpbnQgbmV3bm9kZSA9IGR0bS5nZXRQcmV2aW91c1NpYmxpbmcobm9kZSk7Ci0KLSAgICByZXR1cm4gKG5ld25vZGUgPT0gLTEpID8gbnVsbCA6IGR0bS5nZXROb2RlKG5ld25vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBnZXROZXh0U2libGluZygpCi0gIHsKLQotICAgIC8vIEF0dHIncyBOZXh0IGlzIGRlZmluZWQgYXQgRFRNIGxldmVsLCBidXQgbm90IGF0IERPTSBsZXZlbC4KLSAgICBpZiAoZHRtLmdldE5vZGVUeXBlKG5vZGUpID09IE5vZGUuQVRUUklCVVRFX05PREUpCi0gICAgICByZXR1cm4gbnVsbDsKLQotICAgIGludCBuZXdub2RlID0gZHRtLmdldE5leHRTaWJsaW5nKG5vZGUpOwotCi0gICAgcmV0dXJuIChuZXdub2RlID09IC0xKSA/IG51bGwgOiBkdG0uZ2V0Tm9kZShuZXdub2RlKTsKLSAgfQotCi0gIC8vIERUTU5hbWVkTm9kZU1hcCBtX2F0dHJzOwotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZQotICAgKi8KLSAgcHVibGljIGZpbmFsIE5hbWVkTm9kZU1hcCBnZXRBdHRyaWJ1dGVzKCkKLSAgewotCi0gICAgcmV0dXJuIG5ldyBEVE1OYW1lZE5vZGVNYXAoZHRtLCBub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgaGFzQXR0cmlidXRlCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lCi0gICAqCi0gICAqIChoYXNBdHRyaWJ1dGUpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotCi0gICAgLy8gcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCBoYXNBdHRyaWJ1dGVOUwotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKiBAcGFyYW0geAotICAgKgotICAgKiAoaGFzQXR0cmlidXRlTlMpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZU5TKFN0cmluZyBuYW1lLCBTdHJpbmcgeCkKLSAgewotCi0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotCi0gICAgLy8gcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgRG9jdW1lbnQgZ2V0T3duZXJEb2N1bWVudCgpCi0gIHsKLSAgICByZXR1cm4gbmV3IERUTU5vZGVQcm94eShkdG0sIGR0bS5nZXREb2N1bWVudCgpKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQKLSAgICogQHBhcmFtIHJlZkNoaWxkCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlIC0tIERUTU5vZGVQcm94eSBpcyByZWFkLW9ubHkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlIGluc2VydEJlZm9yZShOb2RlIG5ld0NoaWxkLCBOb2RlIHJlZkNoaWxkKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkCi0gICAqIEBwYXJhbSBvbGRDaGlsZAotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwgTm9kZSBvbGRDaGlsZCkKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBvbGRDaGlsZAotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSByZW1vdmVDaGlsZChOb2RlIG9sZENoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZAotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uTm9kZSAtLSBEVE1Ob2RlUHJveHkgaXMgcmVhZC1vbmx5Ci0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBhcHBlbmRDaGlsZChOb2RlIG5ld0NoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT19NT0RJRklDQVRJT05fQUxMT1dFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkKLSAgewotICAgIHJldHVybiAoLTEgIT0gZHRtLmdldEZpcnN0Q2hpbGQobm9kZSkpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBkZWVwCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Ob2RlIC0tIERUTU5vZGVQcm94eSBpcyByZWFkLW9ubHkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgRG9jdW1lbnRUeXBlIGdldERvY3R5cGUoKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIEVsZW1lbnQgZ2V0RG9jdW1lbnRFbGVtZW50KCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gdGFnTmFtZQotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBEb2N1bWVudEZyYWdtZW50IGNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBkYXRhCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIFRleHQgY3JlYXRlVGV4dE5vZGUoU3RyaW5nIGRhdGEpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIGRhdGEKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgQ29tbWVudCBjcmVhdGVDb21tZW50KFN0cmluZyBkYXRhKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBkYXRhCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIENEQVRBU2VjdGlvbiBjcmVhdGVDREFUQVNlY3Rpb24oU3RyaW5nIGRhdGEpCi0gICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQKLSAgICogQHBhcmFtIGRhdGEKLSAgICoKLSAgICogQHJldHVybgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgUHJvY2Vzc2luZ0luc3RydWN0aW9uIGNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigKLSAgICAgICAgICBTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIEF0dHIgY3JlYXRlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICoKLSAgICogQHJldHVybgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgRW50aXR5UmVmZXJlbmNlIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIHRhZ25hbWUKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWUoU3RyaW5nIHRhZ25hbWUpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIGltcG9ydGVkTm9kZQotICAgKiBAcGFyYW0gZGVlcAotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQgYXMgb2YgRE9NIExldmVsIDIgLS0gRFRNTm9kZVByb3h5IGlzIHJlYWQtb25seQotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgaW1wb3J0Tm9kZShOb2RlIGltcG9ydGVkTm9kZSwgYm9vbGVhbiBkZWVwKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSQotICAgKiBAcGFyYW0gcXVhbGlmaWVkTmFtZQotICAgKgotICAgKiBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBFbGVtZW50IGNyZWF0ZUVsZW1lbnROUygKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUKLSAgICoKLSAgICogQHJldHVybgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkRvY3VtZW50IGFzIG9mIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgZmluYWwgQXR0ciBjcmVhdGVBdHRyaWJ1dGVOUygKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRG9jdW1lbnQgYXMgb2YgRE9NIExldmVsIDIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudCBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgcHVibGljIGZpbmFsIEVsZW1lbnQgZ2V0RWxlbWVudEJ5SWQoU3RyaW5nIGVsZW1lbnRJZCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0Ci0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5UZXh0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgVGV4dCBzcGxpdFRleHQoaW50IG9mZnNldCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldERhdGEoKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZHRtLmdldE5vZGVWYWx1ZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gZGF0YQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkNoYXJhY3RlckRhdGEKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldERhdGEoU3RyaW5nIGRhdGEpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRMZW5ndGgoKQotICB7Ci0KLSAgICAvLyAlJUZJWDogVGhpcyBzaG91bGQgZG8gc29tZXRoaW5nIHNtYXJ0ZXI/Ci0gICAgcmV0dXJuIGR0bS5nZXROb2RlVmFsdWUobm9kZSkubGVuZ3RoKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG9mZnNldAotICAgKiBAcGFyYW0gY291bnQKLSAgICoKLSAgICogQHJldHVybgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkNoYXJhY3RlckRhdGEKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgc3Vic3RyaW5nRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gYXJnCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgYXBwZW5kRGF0YShTdHJpbmcgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG9mZnNldAotICAgKiBAcGFyYW0gYXJnCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQ2hhcmFjdGVyRGF0YQotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgaW5zZXJ0RGF0YShpbnQgb2Zmc2V0LCBTdHJpbmcgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG9mZnNldAotICAgKiBAcGFyYW0gY291bnQKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBkZWxldGVEYXRhKGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBvZmZzZXQKLSAgICogQHBhcmFtIGNvdW50Ci0gICAqIEBwYXJhbSBhcmcKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5DaGFyYWN0ZXJEYXRhCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCByZXBsYWNlRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQsIFN0cmluZyBhcmcpCi0gICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFRhZ05hbWUoKQotICB7Ci0gICAgcmV0dXJuIGR0bS5nZXROb2RlTmFtZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIERUTU5hbWVkTm9kZU1hcCAgbWFwID0gbmV3IERUTU5hbWVkTm9kZU1hcChkdG0sIG5vZGUpOwotICAgIE5vZGUgbm9kZSA9IG1hcC5nZXROYW1lZEl0ZW0obmFtZSk7Ci0gICAgcmV0dXJuIChudWxsID09IG5vZGUpID8gbnVsbCA6IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHBhcmFtIHZhbHVlCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBBdHRyIGdldEF0dHJpYnV0ZU5vZGUoU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIERUTU5hbWVkTm9kZU1hcCAgbWFwID0gbmV3IERUTU5hbWVkTm9kZU1hcChkdG0sIG5vZGUpOwotICAgIHJldHVybiAoQXR0ciltYXAuZ2V0TmFtZWRJdGVtKG5hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlKEF0dHIgbmV3QXR0cikgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBvbGRBdHRyCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgQXR0ciByZW1vdmVBdHRyaWJ1dGVOb2RlKEF0dHIgb2xkQXR0cikgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudCAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBub3JtYWxpemUoKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBnZXRBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkKLSAgICogQHBhcmFtIHF1YWxpZmllZE5hbWUKLSAgICogQHBhcmFtIHZhbHVlCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqIEBzZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0QXR0cmlidXRlTlMoCi0gICAgICAgICAgU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHF1YWxpZmllZE5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCByZW1vdmVBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBBdHRyIGdldEF0dHJpYnV0ZU5vZGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICogQHNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqLwotICBwdWJsaWMgZmluYWwgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0ciBuZXdBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQHJldHVybgotICAgKiBAc2VlIG9yZy53M2MuZG9tLkF0dHIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gZHRtLmdldE5vZGVOYW1lKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5BdHRyCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRTcGVjaWZpZWQoKQotICB7Ci0KLSAgICAvLyAlJUZJWAotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEByZXR1cm4KLSAgICogQHNlZSBvcmcudzNjLmRvbS5BdHRyCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFZhbHVlKCkKLSAgewotICAgIHJldHVybiBkdG0uZ2V0Tm9kZVZhbHVlKG5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZQotICAgKiBAc2VlIG9yZy53M2MuZG9tLkF0dHIKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFZhbHVlKFN0cmluZyB2YWx1ZSkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG93bmVyIGVsZW1lbnQgb2YgYW4gYXR0cmlidXRlLgotICAgKgotICAgKiBAcmV0dXJuCi0gICAqIEBzZWUgb3JnLnczYy5kb20uQXR0ciBhcyBvZiBET00gTGV2ZWwgMgotICAgKi8KLSAgcHVibGljIGZpbmFsIEVsZW1lbnQgZ2V0T3duZXJFbGVtZW50KCkKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiBORUVEU0RPQyBNZXRob2QgYWRvcHROb2RlIAotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc291cmNlCi0gICAqCi0gICAqIE5FRURTRE9DIChhZG9wdE5vZGUpIEByZXR1cm4KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlIGFkb3B0Tm9kZShOb2RlIHNvdXJjZSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSBlbmNvZGluZwotICAgKiBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkKLSAgewotCi0gICAgdGhyb3cgbmV3IERUTURPTUV4Y2VwdGlvbihET01FeGNlcHRpb24uTk9UX1NVUFBPUlRFRF9FUlIpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB0aGUgZW5jb2RpbmcKLSAgICogb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHVuc3BlY2lmaWVkLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIGVuY29kaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHdoZXRoZXIgdGhpcwotICAgKiBkb2N1bWVudCBpcyBzdGFuZGFsb25lLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0U3RhbmRhbG9uZSgpCi0gIHsKLQotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgd2hldGhlciB0aGlzCi0gICAqIGRvY3VtZW50IGlzIHN0YW5kYWxvbmUuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3RhbmRhbG9uZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3RhbmRhbG9uZShib29sZWFuIHN0YW5kYWxvbmUpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nIHdoZXRoZXIgZXJyb3JzIGNoZWNraW5nIGlzIGVuZm9yY2VkIG9yIG5vdC4KLSAgICogV2hlbiBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgaW1wbGVtZW50YXRpb24gaXMgZnJlZSB0byBub3QKLSAgICogdGVzdCBldmVyeSBwb3NzaWJsZSBlcnJvciBjYXNlIG5vcm1hbGx5IGRlZmluZWQgb24gRE9NIG9wZXJhdGlvbnMsCi0gICAqIGFuZCBub3QgcmFpc2UgYW55IDxjb2RlPkRPTUV4Y2VwdGlvbjwvY29kZT4uIEluIGNhc2Ugb2YgZXJyb3IsIHRoZQotICAgKiBiZWhhdmlvciBpcyB1bmRlZmluZWQuIFRoaXMgYXR0cmlidXRlIGlzIDxjb2RlPnRydWU8L2NvZGU+IGJ5Ci0gICAqIGRlZmF1bHRzLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0U3RyaWN0RXJyb3JDaGVja2luZygpCi0gIHsKLQotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgd2hldGhlciBlcnJvcnMgY2hlY2tpbmcgaXMgZW5mb3JjZWQgb3Igbm90LgotICAgKiBXaGVuIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdAotICAgKiB0ZXN0IGV2ZXJ5IHBvc3NpYmxlIGVycm9yIGNhc2Ugbm9ybWFsbHkgZGVmaW5lZCBvbiBET00gb3BlcmF0aW9ucywKLSAgICogYW5kIG5vdCByYWlzZSBhbnkgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPi4gSW4gY2FzZSBvZiBlcnJvciwgdGhlCi0gICAqIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gVGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gYnkKLSAgICogZGVmYXVsdHMuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3RyaWN0RXJyb3JDaGVja2luZwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3RyaWN0RXJyb3JDaGVja2luZyhib29sZWFuIHN0cmljdEVycm9yQ2hlY2tpbmcpCi0gIHsKLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSB2ZXJzaW9uCi0gICAqIG51bWJlciBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKQotICB7Ci0KLSAgICB0aHJvdyBuZXcgRFRNRE9NRXhjZXB0aW9uKERPTUV4Y2VwdGlvbi5OT1RfU1VQUE9SVEVEX0VSUik7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSB2ZXJzaW9uCi0gICAqIG51bWJlciBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gdmVyc2lvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihTdHJpbmcgdmVyc2lvbikKLSAgewotICAgIHRocm93IG5ldyBEVE1ET01FeGNlcHRpb24oRE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNU2FmZVN0cmluZ1Bvb2wuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTVNhZmVTdHJpbmdQb29sLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk3OWU1MDIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNU2FmZVN0cmluZ1Bvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTksMjAwMCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKiogPHA+TGlrZSBEVE1TdHJpbmdQb29sLCBidXQgdGhyZWFkc2FmZS4gSXQncyBiZWVuIHByb3Bvc2VkIHRoYXQgRFRNcwotICogc2hhcmUgdGhlaXIgc3RyaW5nIHBvb2wocyk7IHRoYXQgcmFpc2VzIHRocmVhZHNhZmV0eSBpc3N1ZXMgd2hpY2gKLSAqIHRoaXMgYWRkcmVzc2VzLiBPZiBjb3Vyc2UgcGVyZm9ybWFuY2UgaXMgaW5mZXJpb3IgdG8gdGhhdCBvZiB0aGUKLSAqIGJhcmUtYm9uZXMgdmVyc2lvbi48L3A+Ci0gKgotICogPHA+U3RhdHVzOiBQYXNzZWQgYmFzaWMgdGVzdCBpbiBtYWluKCkuPC9wPgotICogKi8KLXB1YmxpYyBjbGFzcyBEVE1TYWZlU3RyaW5nUG9vbAotZXh0ZW5kcyBEVE1TdHJpbmdQb29sCi17Ci0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVBbGxFbGVtZW50cygpCi0gICAgewotICAgICAgc3VwZXIucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICB9Ci0KLSAgLyoqIEByZXR1cm4gc3RyaW5nIHdob3NlIHZhbHVlIGlzIHVuaXF1ZWx5IGlkZW50aWZpZWQgYnkgdGhpcyBpbnRlZ2VyIGluZGV4LgotICAgKiBAdGhyb3dzIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICogIGlmIGluZGV4IGRvZXNuJ3QgbWFwIHRvIGEgc3RyaW5nLgotICAgKiAqLyAKLSAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgaW5kZXhUb1N0cmluZyhpbnQgaSkKLSAgICB0aHJvd3MgamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgIHsKLSAgICAgIHJldHVybiBzdXBlci5pbmRleFRvU3RyaW5nKGkpOwotICAgIH0KLQotICAvKiogQHJldHVybiBpbnRlZ2VyIGluZGV4IHVuaXF1ZWx5IGlkZW50aWZ5aW5nIHRoZSB2YWx1ZSBvZiB0aGlzIHN0cmluZy4gKi8gCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHN0cmluZ1RvSW5kZXgoU3RyaW5nIHMpCi0gICAgewotICAgICAgcmV0dXJuIHN1cGVyLnN0cmluZ1RvSW5kZXgocyk7Ci0gICAgfQotCi0gIC8qKiBDb21tYW5kLWxpbmUgdW5pdCB0ZXN0IGRyaXZlci4gVGhpcyB0ZXN0IHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0Ci0gICAqIHRoaXMgdmVyc2lvbiBvZiB0aGUgcG9vbCBhc3NpZ25zIGluZGljZXMgY29uc2VjdXRpdmVseSwgc3RhcnRpbmcKLSAgICogZnJvbSB6ZXJvLCBhcyBuZXcgdW5pcXVlIHN0cmluZ3MgYXJlIGVuY291bnRlcmVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykKLSAgewotICAgIFN0cmluZ1tdIHdvcmQ9ewotICAgICAgIlplcm8iLCJPbmUiLCJUd28iLCJUaHJlZSIsIkZvdXIiLCJGaXZlIiwKLSAgICAgICJTaXgiLCJTZXZlbiIsIkVpZ2h0IiwiTmluZSIsIlRlbiIsCi0gICAgICAiRWxldmVuIiwiVHdlbHZlIiwiVGhpcnRlZW4iLCJGb3VydGVlbiIsIkZpZnRlZW4iLAotICAgICAgIlNpeHRlZW4iLCJTZXZlbnRlZW4iLCJFaWdodGVlbiIsIk5pbmV0ZWVuIiwiVHdlbnR5IiwKLSAgICAgICJUd2VudHktT25lIiwiVHdlbnR5LVR3byIsIlR3ZW50eS1UaHJlZSIsIlR3ZW50eS1Gb3VyIiwKLSAgICAgICJUd2VudHktRml2ZSIsIlR3ZW50eS1TaXgiLCJUd2VudHktU2V2ZW4iLCJUd2VudHktRWlnaHQiLAotICAgICAgIlR3ZW50eS1OaW5lIiwiVGhpcnR5IiwiVGhpcnR5LU9uZSIsIlRoaXJ0eS1Ud28iLAotICAgICAgIlRoaXJ0eS1UaHJlZSIsIlRoaXJ0eS1Gb3VyIiwiVGhpcnR5LUZpdmUiLCJUaGlydHktU2l4IiwKLSAgICAgICJUaGlydHktU2V2ZW4iLCJUaGlydHktRWlnaHQiLCJUaGlydHktTmluZSJ9OwotCi0gICAgRFRNU3RyaW5nUG9vbCBwb29sPW5ldyBEVE1TYWZlU3RyaW5nUG9vbCgpOwotCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJJZiBubyBjb21wbGFpbnRzIGFyZSBwcmludGVkIGJlbG93LCB3ZSBwYXNzZWQgaW5pdGlhbCB0ZXN0LiIpOwotCi0gICAgZm9yKGludCBwYXNzPTA7cGFzczw9MTsrK3Bhc3MpCi0gICAgICB7Ci0gICAgICAgIGludCBpOwotCi0gICAgICAgIGZvcihpPTA7aTx3b3JkLmxlbmd0aDsrK2kpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGo9cG9vbC5zdHJpbmdUb0luZGV4KHdvcmRbaV0pOwotICAgICAgICAgICAgaWYoaiE9aSkKLSAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdE1pc21hdGNoIHBvcHVsYXRpbmcgcG9vbDogYXNzaWduZWQgIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGorIiBmb3IgY3JlYXRlICIraSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgIGZvcihpPTA7aTx3b3JkLmxlbmd0aDsrK2kpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGo9cG9vbC5zdHJpbmdUb0luZGV4KHdvcmRbaV0pOwotICAgICAgICAgICAgaWYoaiE9aSkKLSAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdE1pc21hdGNoIGluIHN0cmluZ1RvSW5kZXg6IHJldHVybmVkICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqKyIgZm9yIGxvb2t1cCAiK2kpOwotICAgICAgICAgIH0KLQotICAgICAgICBmb3IoaT0wO2k8d29yZC5sZW5ndGg7KytpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN0cmluZyB3PXBvb2wuaW5kZXhUb1N0cmluZyhpKTsKLSAgICAgICAgICAgIGlmKCF3b3JkW2ldLmVxdWFscyh3KSkKLSAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcdE1pc21hdGNoIGluIGluZGV4VG9TdHJpbmc6IHJldHVybmVkIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcrIiBmb3IgbG9va3VwICIraSk7Ci0gICAgICAgICAgfQotICAgICAgICAKLSAgICAgICAgcG9vbC5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICAKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblBhc3MgIitwYXNzKyIgY29tcGxldGVcbiIpOwotICAgICAgfSAvLyBlbmQgcGFzcyBsb29wCi0gIH0KLX0gLy8gRFRNU2FmZVN0cmluZ1Bvb2wKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTVN0cmluZ1Bvb2wuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0RUTVN0cmluZ1Bvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWM1NmQ4Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1TdHJpbmdQb29sLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5LDIwMDAgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGVyY2VzIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgSW50ZXJuYXRpb25hbAotICogQnVzaW5lc3MgTWFjaGluZXMsIEluYy4sIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLS8vICVSRVZJRVclIFNob3VsZCB0aGlzIGJlIGJhc2VkIG9uIFN1YmFsbG9jYXRlZEludFZlY3RvciBpbnN0ZWFkPwotLy8gKFVuY2xlYXIuIFBvb2xzIHdpbGwgcmFyZWx5IGJlIGh1Z2UuIEJ1dCBpZiB0aGV5IGV2ZXIgYXJlLi4uKQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkludFZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKiogPHA+RFRNU3RyaW5nUG9vbCBpcyBhbiAiaW50ZXJuaW5nIiBtZWNoYW5pc20gZm9yIHN0cmluZ3MuIEl0IHdpbGwKLSAqIGNyZWF0ZSBhIHN0YWJsZSAxOjEgbWFwcGluZyBiZXR3ZWVuIGEgc2V0IG9mIHN0cmluZyB2YWx1ZXMgYW5kIGEgc2V0IG9mCi0gKiBpbnRlZ2VyIGluZGV4IHZhbHVlcywgc28gdGhlIGludGVnZXJzIGNhbiBiZSB1c2VkIHRvIHJlbGlhYmx5IGFuZAotICogdW5pcXVlbHkgaWRlbnRpZnkgKGFuZCB3aGVuIG5lY2Vzc2FyeSByZXRyaWV2ZSkgdGhlIHN0cmluZ3MuPC9wPgotICoKLSAqIDxwPkRlc2lnbiBQcmlvcml0aWVzOgotICogPHVsPgotICogPGxpPlN0cmluZy10by1pbmRleCBsb29rdXAgc3BlZWQgaXMgY3JpdGljYWwuPC9saT4KLSAqIDxsaT5JbmRleC10by1TdHJpbmcgbG9va3VwIHNwZWVkIGlzIHNsaWdodGx5IGxlc3Mgc28uPC9saT4KLSAqIDxsaT5UaHJlYWRzYWZldHkgaXMgbm90IGd1YXJhbnRlZWQgYXQgdGhpcyBsZXZlbC4KLSAqIEVuZm9yY2UgdGhhdCBpbiB0aGUgYXBwbGljYXRpb24gaWYgbmVlZGVkLjwvbGk+Ci0gKiA8bGk+U3RvcmFnZSBlZmZpY2llbmN5IGlzIGFuIGlzc3VlIGJ1dCBub3QgYSBodWdlIG9uZS4KLSAqIEl0IGlzIGV4cGVjdGVkIHRoYXQgc3RyaW5nIHBvb2xzIHdvbid0IGV4Y2VlZCBhYm91dCAyMDAwIGVudHJpZXMuPC9saT4KLSAqIDwvdWw+Ci0gKiA8L3A+Ci0gKgotICogPHA+SW1wbGVtZW50YXRpb24gZGV0YWlsOiBBIHN0YW5kYXJkIEhhc2h0YWJsZSBpcyByZWxhdGl2ZWx5Ci0gKiBpbmVmZmljaWVudCB3aGVuIGxvb2tpbmcgdXAgcHJpbWl0aXZlIGludCB2YWx1ZXMsIGVzcGVjaWFsbHkgd2hlbgotICogd2UncmUgYWxyZWFkeSBtYWludGFpbmluZyBhbiBpbnQtdG8tc3RyaW5nIHZlY3Rvci4gIFNvIEknbQotICogbWFpbnRhaW5pbmcgYSBzaW1wbGUgaGFzaCBjaGFpbiB3aXRoaW4gdGhpcyBjbGFzcy48L3A+Ci0gKgotICogPHA+Tk9URTogVGhlcmUgaXMgbm90aGluZyBpbiB0aGUgY29kZSB0aGF0IGhhcyBhIHJlYWwgZGVwZW5kZW5jeSB1cG9uCi0gKiBTdHJpbmcuIEl0IHdvdWxkIHdvcmsgd2l0aCBhbnkgb2JqZWN0IHR5cGUgdGhhdCBpbXBsZW1lbnRzIHJlbGlhYmxlCi0gKiAuaGFzaENvZGUoKSBhbmQgLmVxdWFscygpIG9wZXJhdGlvbnMuIFRoZSBBUEkgZW5mb3JjZXMgU3RyaW5ncyBiZWNhdXNlCi0gKiBpdCdzIHNhZmVyIHRoYXQgd2F5LCBidXQgdGhpcyBjb3VsZCB0cml2aWFsbHkgYmUgdHVybmVkIGludG8gYSBnZW5lcmFsCi0gKiBPYmplY3RQb29sIGlmIG9uZSB3YXMgbmVlZGVkLjwvcD4KLSAqCi0gKiA8cD5TdGF0dXM6IFBhc3NlZCBiYXNpYyB0ZXN0IGluIG1haW4oKS48L3A+Ci0gKiAqLwotcHVibGljIGNsYXNzIERUTVN0cmluZ1Bvb2wKLXsKLSAgVmVjdG9yIG1faW50VG9TdHJpbmc7Ci0gIHN0YXRpYyBmaW5hbCBpbnQgSEFTSFBSSU1FPTEwMTsKLSAgaW50W10gbV9oYXNoU3RhcnQ9bmV3IGludFtIQVNIUFJJTUVdOwotICBJbnRWZWN0b3IgbV9oYXNoQ2hhaW47Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5VTEw9LTE7Ci0KLSAgcHVibGljIERUTVN0cmluZ1Bvb2woKQotICAgIHsKLSAgICAgIG1faW50VG9TdHJpbmc9bmV3IFZlY3RvcigpOwotICAgICAgbV9oYXNoQ2hhaW49bmV3IEludFZlY3Rvcig1MTIpOwotICAgICAgcmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgIAotICAgICAgLy8gLXNiIEFkZCB0aGlzIHRvIGZvcmNlIGVtcHR5IHN0cmluZ3MgdG8gYmUgaW5kZXggMC4KLSAgICAgIHN0cmluZ1RvSW5kZXgoIiIpOwotICAgIH0KLSAgCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgICB7Ci0gICAgICBtX2ludFRvU3RyaW5nLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0gICAgICBmb3IoaW50IGk9MDtpPEhBU0hQUklNRTsrK2kpCi0gICAgICAgIG1faGFzaFN0YXJ0W2ldPU5VTEw7Ci0gICAgICBtX2hhc2hDaGFpbi5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgIH0KLQotICAvKiogQHJldHVybiBzdHJpbmcgd2hvc2UgdmFsdWUgaXMgdW5pcXVlbHkgaWRlbnRpZmllZCBieSB0aGlzIGludGVnZXIgaW5kZXguCi0gICAqIEB0aHJvd3MgamF2YS5sYW5nLkFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgotICAgKiAgaWYgaW5kZXggZG9lc24ndCBtYXAgdG8gYSBzdHJpbmcuCi0gICAqICovIAotICBwdWJsaWMgU3RyaW5nIGluZGV4VG9TdHJpbmcoaW50IGkpCi0gICAgdGhyb3dzIGphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KLSAgICB7Ci0gICAgICBpZihpPT1OVUxMKSByZXR1cm4gbnVsbDsKLSAgICAgIHJldHVybiAoU3RyaW5nKSBtX2ludFRvU3RyaW5nLmVsZW1lbnRBdChpKTsKLSAgICB9Ci0KLSAgLyoqIEByZXR1cm4gaW50ZWdlciBpbmRleCB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgdmFsdWUgb2YgdGhpcyBzdHJpbmcuICovIAotICBwdWJsaWMgaW50IHN0cmluZ1RvSW5kZXgoU3RyaW5nIHMpCi0gICAgewotICAgICAgaWYocz09bnVsbCkgcmV0dXJuIE5VTEw7Ci0gICAgICAKLSAgICAgIGludCBoYXNoc2xvdD1zLmhhc2hDb2RlKCklSEFTSFBSSU1FOwotICAgICAgaWYoaGFzaHNsb3Q8MCkgaGFzaHNsb3Q9LWhhc2hzbG90OwotCi0gICAgICAvLyBJcyBpdCBvbmUgd2UgYWxyZWFkeSBrbm93PwotICAgICAgaW50IGhhc2hsYXN0PW1faGFzaFN0YXJ0W2hhc2hzbG90XTsKLSAgICAgIGludCBoYXNoY2FuZGlkYXRlPWhhc2hsYXN0OwotICAgICAgd2hpbGUoaGFzaGNhbmRpZGF0ZSE9TlVMTCkKLSAgICAgICAgewotICAgICAgICAgIGlmKG1faW50VG9TdHJpbmcuZWxlbWVudEF0KGhhc2hjYW5kaWRhdGUpLmVxdWFscyhzKSkKLSAgICAgICAgICAgIHJldHVybiBoYXNoY2FuZGlkYXRlOwotCi0gICAgICAgICAgaGFzaGxhc3Q9aGFzaGNhbmRpZGF0ZTsKLSAgICAgICAgICBoYXNoY2FuZGlkYXRlPW1faGFzaENoYWluLmVsZW1lbnRBdChoYXNoY2FuZGlkYXRlKTsKLSAgICAgICAgfQotICAgICAgCi0gICAgICAvLyBOZXcgdmFsdWUuIEFkZCB0byB0YWJsZXMuCi0gICAgICBpbnQgbmV3SW5kZXg9bV9pbnRUb1N0cmluZy5zaXplKCk7Ci0gICAgICBtX2ludFRvU3RyaW5nLmFkZEVsZW1lbnQocyk7Ci0KLSAgICAgIG1faGFzaENoYWluLmFkZEVsZW1lbnQoTlVMTCk7CS8vIEluaXRpYWxpemUgdG8gbm8tZm9sbG93aW5nLXNhbWUtaGFzaAotICAgICAgaWYoaGFzaGxhc3Q9PU5VTEwpICAvLyBGaXJzdCBmb3IgdGhpcyBoYXNoCi0gICAgICAgIG1faGFzaFN0YXJ0W2hhc2hzbG90XT1uZXdJbmRleDsKLSAgICAgIGVsc2UgLy8gTGluayBmcm9tIHByZXZpb3VzIHdpdGggc2FtZSBoYXNoCi0gICAgICAgIG1faGFzaENoYWluLnNldEVsZW1lbnRBdChuZXdJbmRleCxoYXNobGFzdCk7Ci0KLSAgICAgIHJldHVybiBuZXdJbmRleDsKLSAgICB9Ci0KLSAgLyoqIENvbW1hbmQtbGluZSB1bml0IHRlc3QgZHJpdmVyLiBUaGlzIHRlc3QgcmVsaWVzIG9uIHRoZSBmYWN0IHRoYXQKLSAgICogdGhpcyB2ZXJzaW9uIG9mIHRoZSBwb29sIGFzc2lnbnMgaW5kaWNlcyBjb25zZWN1dGl2ZWx5LCBzdGFydGluZwotICAgKiBmcm9tIHplcm8sIGFzIG5ldyB1bmlxdWUgc3RyaW5ncyBhcmUgZW5jb3VudGVyZWQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQotICB7Ci0gICAgU3RyaW5nW10gd29yZD17Ci0gICAgICAiWmVybyIsIk9uZSIsIlR3byIsIlRocmVlIiwiRm91ciIsIkZpdmUiLAotICAgICAgIlNpeCIsIlNldmVuIiwiRWlnaHQiLCJOaW5lIiwiVGVuIiwKLSAgICAgICJFbGV2ZW4iLCJUd2VsdmUiLCJUaGlydGVlbiIsIkZvdXJ0ZWVuIiwiRmlmdGVlbiIsCi0gICAgICAiU2l4dGVlbiIsIlNldmVudGVlbiIsIkVpZ2h0ZWVuIiwiTmluZXRlZW4iLCJUd2VudHkiLAotICAgICAgIlR3ZW50eS1PbmUiLCJUd2VudHktVHdvIiwiVHdlbnR5LVRocmVlIiwiVHdlbnR5LUZvdXIiLAotICAgICAgIlR3ZW50eS1GaXZlIiwiVHdlbnR5LVNpeCIsIlR3ZW50eS1TZXZlbiIsIlR3ZW50eS1FaWdodCIsCi0gICAgICAiVHdlbnR5LU5pbmUiLCJUaGlydHkiLCJUaGlydHktT25lIiwiVGhpcnR5LVR3byIsCi0gICAgICAiVGhpcnR5LVRocmVlIiwiVGhpcnR5LUZvdXIiLCJUaGlydHktRml2ZSIsIlRoaXJ0eS1TaXgiLAotICAgICAgIlRoaXJ0eS1TZXZlbiIsIlRoaXJ0eS1FaWdodCIsIlRoaXJ0eS1OaW5lIn07Ci0KLSAgICBEVE1TdHJpbmdQb29sIHBvb2w9bmV3IERUTVN0cmluZ1Bvb2woKTsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSWYgbm8gY29tcGxhaW50cyBhcmUgcHJpbnRlZCBiZWxvdywgd2UgcGFzc2VkIGluaXRpYWwgdGVzdC4iKTsKLQotICAgIGZvcihpbnQgcGFzcz0wO3Bhc3M8PTE7KytwYXNzKQotICAgICAgewotICAgICAgICBpbnQgaTsKLQotICAgICAgICBmb3IoaT0wO2k8d29yZC5sZW5ndGg7KytpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBqPXBvb2wuc3RyaW5nVG9JbmRleCh3b3JkW2ldKTsKLSAgICAgICAgICAgIGlmKGohPWkpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRNaXNtYXRjaCBwb3B1bGF0aW5nIHBvb2w6IGFzc2lnbmVkICIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqKyIgZm9yIGNyZWF0ZSAiK2kpOwotICAgICAgICAgIH0KLQotICAgICAgICBmb3IoaT0wO2k8d29yZC5sZW5ndGg7KytpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBqPXBvb2wuc3RyaW5nVG9JbmRleCh3b3JkW2ldKTsKLSAgICAgICAgICAgIGlmKGohPWkpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRNaXNtYXRjaCBpbiBzdHJpbmdUb0luZGV4OiByZXR1cm5lZCAiKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaisiIGZvciBsb29rdXAgIitpKTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgZm9yKGk9MDtpPHdvcmQubGVuZ3RoOysraSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTdHJpbmcgdz1wb29sLmluZGV4VG9TdHJpbmcoaSk7Ci0gICAgICAgICAgICBpZighd29yZFtpXS5lcXVhbHModykpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRNaXNtYXRjaCBpbiBpbmRleFRvU3RyaW5nOiByZXR1cm5lZCIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3KyIgZm9yIGxvb2t1cCAiK2kpOwotICAgICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIHBvb2wucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgICAgICAgCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5QYXNzICIrcGFzcysiIGNvbXBsZXRlXG4iKTsKLSAgICAgIH0gLy8gZW5kIHBhc3MgbG9vcAotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1UcmVlV2Fsa2VyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9EVE1UcmVlV2Fsa2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM0MGU1ZDkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRFRNVHJlZVdhbGtlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQ0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWY7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguKjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlQ29uc3VtZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhpcyBjbGFzcyBkb2VzIGEgcHJlLW9yZGVyIHdhbGsgb2YgdGhlIERUTSB0cmVlLCBjYWxsaW5nIGEgQ29udGVudEhhbmRsZXIKLSAqIGludGVyZmFjZSBhcyBpdCBnb2VzLiBBcyBzdWNoLCBpdCdzIG1vcmUgbGlrZSB0aGUgVmlzaXRvciBkZXNpZ24gcGF0dGVybgotICogdGhhbiBsaWtlIHRoZSBET00ncyBUcmVlV2Fsa2VyLgotICoKLSAqIEkgdGhpbmsgbm9ybWFsbHkgdGhpcyBjbGFzcyBzaG91bGQgbm90IGJlIG5lZWRlZCwgYmVjYXVzZSAKLSAqIG9mIERUTSNkaXNwYXRjaFRvRXZlbnRzLgotICovCi1wdWJsaWMgY2xhc3MgRFRNVHJlZVdhbGtlcgotewotCi0gIC8qKiBMb2NhbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlciAgICAgICAgICAqLwotICBwcml2YXRlIENvbnRlbnRIYW5kbGVyIG1fY29udGVudEhhbmRsZXIgPSBudWxsOwotCi0gIC8qKiBEb21IZWxwZXIgZm9yIHRoaXMgVHJlZVdhbGtlciAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgRFRNIG1fZHRtOwotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgRFRNIHRvIGJlIHRyYXZlcnNlZC4KLSAgICogCi0gICAqIEBwYXJhbSBkdG0gVGhlIERvY3VtZW50IFRhYmxlIE1vZGVsIHRvIGJlIHVzZWQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREVE0oRFRNIGR0bSkKLSAgewotICAgIG1fZHRtID0gZHRtOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHJldHVybiB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2FsawotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldGNvbnRlbnRIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiBtX2NvbnRlbnRIYW5kbGVyOwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IHRoZSBDb250ZW50SGFuZGxlciB1c2VkIGZvciB0aGUgdHJlZSB3YWxrLgotICAgKgotICAgKiBAcGFyYW0gY2ggdGhlIENvbnRlbnRIYW5kbGVyIHRvIGJlIHRoZSByZXN1bHQgb2YgdGhlIHRyZWUgd2Fsay4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldGNvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGNoKQotICB7Ci0gICAgbV9jb250ZW50SGFuZGxlciA9IGNoOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICogQHBhcmFtICAgY29udGVudEhhbmRsZXIgVGhlIGltcGxlbWVudGlvbiBvZiB0aGUKLSAgICogY29udGVudEhhbmRsZXIgb3BlcmF0aW9uICh0b1hNTFN0cmluZywgZGlnZXN0LCAuLi4pCi0gICAqLwotICBwdWJsaWMgRFRNVHJlZVdhbGtlcigpCi0gIHsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yLgotICAgKiBAcGFyYW0gICBjb250ZW50SGFuZGxlciBUaGUgaW1wbGVtZW50aW9uIG9mIHRoZQotICAgKiBjb250ZW50SGFuZGxlciBvcGVyYXRpb24gKHRvWE1MU3RyaW5nLCBkaWdlc3QsIC4uLikKLSAgICovCi0gIHB1YmxpYyBEVE1UcmVlV2Fsa2VyKENvbnRlbnRIYW5kbGVyIGNvbnRlbnRIYW5kbGVyLCBEVE0gZHRtKQotICB7Ci0gICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyID0gY29udGVudEhhbmRsZXI7Ci0gICAgbV9kdG0gPSBkdG07Ci0gIH0KLSAgCi0gIC8qKiBQZXJmb3JtIGEgbm9uLXJlY3Vyc2l2ZSBwcmUtb3JkZXIvcG9zdC1vcmRlciB0cmF2ZXJzYWwsCi0gICAqIG9wZXJhdGluZyBhcyBhIFZpc2l0b3IuIHN0YXJ0Tm9kZSAocHJlb3JkZXIpIGFuZCBlbmROb2RlCi0gICAqIChwb3N0b3JkZXIpIGFyZSBpbnZva2VkIGZvciBlYWNoIG5vZGUgYXMgd2UgdHJhdmVyc2Ugb3ZlciB0aGVtLAotICAgKiB3aXRoIHRoZSByZXN1bHQgdGhhdCB0aGUgbm9kZSBpcyB3cml0dGVuIG91dCB0byBtX2NvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAcGFyYW0gcG9zIE5vZGUgaW4gdGhlIHRyZWUgYXQgd2hpY2ggdG8gc3RhcnQgKGFuZCBlbmQpIHRyYXZlcnNhbCAtLQotICAgKiBpbiBvdGhlciB3b3JkcywgdGhlIHJvb3Qgb2YgdGhlIHN1YnRyZWUgdG8gdHJhdmVyc2Ugb3Zlci4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiAqLwotICBwdWJsaWMgdm9pZCB0cmF2ZXJzZShpbnQgcG9zKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyAlUkVWSUVXJSBXaHkgaXNuJ3QgdGhpcyBqdXN0IHRyYXZlcnNlKHBvcyxwb3MpPwotCi0gICAgaW50IHRvcCA9IHBvczsJCS8vIFJlbWVtYmVyIHRoZSByb290IG9mIHRoaXMgc3VidHJlZQotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IHBvcykKLSAgICB7Ci0gICAgICBzdGFydE5vZGUocG9zKTsKLSAgICAgIGludCBuZXh0Tm9kZSA9IG1fZHRtLmdldEZpcnN0Q2hpbGQocG9zKTsKLSAgICAgIHdoaWxlIChEVE0uTlVMTCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgZW5kTm9kZShwb3MpOwotCi0gICAgICAgIGlmICh0b3AgPT0gcG9zKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlID0gbV9kdG0uZ2V0TmV4dFNpYmxpbmcocG9zKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgPT0gbmV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBwb3MgPSBtX2R0bS5nZXRQYXJlbnQocG9zKTsKLQotICAgICAgICAgIGlmICgoRFRNLk5VTEwgPT0gcG9zKSB8fCAodG9wID09IHBvcykpCi0gICAgICAgICAgewotICAgICAgICAgICAgLy8gJVJFVklFVyUgVGhpcyBjb25kaXRpb24gaXNuJ3QgdGVzdGVkIGluIHRyYXZlcnNlKHBvcyx0b3ApCi0gICAgICAgICAgICAvLyAtLSBidWc/Ci0gICAgICAgICAgICBpZiAoRFRNLk5VTEwgIT0gcG9zKQotICAgICAgICAgICAgICBlbmROb2RlKHBvcyk7Ci0KLSAgICAgICAgICAgIG5leHROb2RlID0gRFRNLk5VTEw7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBwb3MgPSBuZXh0Tm9kZTsKLSAgICB9Ci0gIH0KLQotICAvKiogUGVyZm9ybSBhIG5vbi1yZWN1cnNpdmUgcHJlLW9yZGVyL3Bvc3Qtb3JkZXIgdHJhdmVyc2FsLAotICAgKiBvcGVyYXRpbmcgYXMgYSBWaXNpdG9yLiBzdGFydE5vZGUgKHByZW9yZGVyKSBhbmQgZW5kTm9kZQotICAgKiAocG9zdG9yZGVyKSBhcmUgaW52b2tlZCBmb3IgZWFjaCBub2RlIGFzIHdlIHRyYXZlcnNlIG92ZXIgdGhlbSwKLSAgICogd2l0aCB0aGUgcmVzdWx0IHRoYXQgdGhlIG5vZGUgaXMgd3JpdHRlbiBvdXQgdG8gbV9jb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBOb2RlIGluIHRoZSB0cmVlIHdoZXJlIHRvIHN0YXJ0IHRyYXZlcnNhbAotICAgKiBAcGFyYW0gdG9wIE5vZGUgaW4gdGhlIHRyZWUgd2hlcmUgdG8gZW5kIHRyYXZlcnNhbC4KLSAgICogSWYgdG9wPT1EVE0uTlVMTCwgcnVuIHRocm91Z2ggZW5kIG9mIGRvY3VtZW50LgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB0cmF2ZXJzZShpbnQgcG9zLCBpbnQgdG9wKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICAvLyAlT1BUJSBDYW4gd2Ugc2ltcGxpZnkgdGhlIGxvb3AgY29uZGl0aW9uYWxzIGJ5IGFkZGluZzoKLSAgICAvLwkJaWYodG9wPT1EVE0uTlVMTCkgdG9wPTAKLSAgICAvLyAtLSBvciBieSBzaW1wbHkgaWdub3JpbmcgdGhpcyBjYXNlIGFuZCByZWx5aW5nIG9uIHRoZSBmYWN0IHRoYXQKLSAgICAvLyBwb3Mgd2lsbCBuZXZlciBlcXVhbCBEVE0uTlVMTCB1bnRpbCB3ZSdyZSByZWFkeSB0byBleGl0PwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IHBvcykKLSAgICB7Ci0gICAgICBzdGFydE5vZGUocG9zKTsKLSAgICAgIGludCBuZXh0Tm9kZSA9IG1fZHRtLmdldEZpcnN0Q2hpbGQocG9zKTsKLSAgICAgIHdoaWxlIChEVE0uTlVMTCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgZW5kTm9kZShwb3MpOwotCi0gICAgICAgIGlmICgoRFRNLk5VTEwgIT0gdG9wKSAmJiB0b3AgPT0gcG9zKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlID0gbV9kdG0uZ2V0TmV4dFNpYmxpbmcocG9zKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgPT0gbmV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBwb3MgPSBtX2R0bS5nZXRQYXJlbnQocG9zKTsKLQotICAgICAgICAgIGlmICgoRFRNLk5VTEwgPT0gcG9zKSB8fCAoKERUTS5OVUxMICE9IHRvcCkgJiYgKHRvcCA9PSBwb3MpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBuZXh0Tm9kZSA9IERUTS5OVUxMOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcG9zID0gbmV4dE5vZGU7Ci0gICAgfQotICB9Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIGZvbGxvd2luZyB0ZXh0IHRvIGJlIHByb2Nlc3NlZCBpcyByYXcgdGV4dCAgICAgICAgICAqLwotICBib29sZWFuIG5leHRJc1JhdyA9IGZhbHNlOwotICAKLSAgLyoqCi0gICAqIE9wdGltaXplZCBkaXNwYXRjaCBvZiBjaGFyYWN0ZXJzLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGRpc3BhdGFjaENoYXJzKGludCBub2RlKQotICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBtX2R0bS5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMobm9kZSwgbV9jb250ZW50SGFuZGxlciwgZmFsc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IHByb2Nlc3NpbmcgZ2l2ZW4gbm9kZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHByb2Nlc3MKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHN0YXJ0Tm9kZShpbnQgbm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIE5vZGVDb25zdW1lcikKLSAgICB7Ci0gICAgICAvLyAlVEJEJQotLy8gICAgICAoKE5vZGVDb25zdW1lcikgbV9jb250ZW50SGFuZGxlcikuc2V0T3JpZ2luYXRpbmdOb2RlKG5vZGUpOwotICAgIH0KLQotICAgIHN3aXRjaCAobV9kdG0uZ2V0Tm9kZVR5cGUobm9kZSkpCi0gICAgewotICAgIGNhc2UgRFRNLkNPTU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgWE1MU3RyaW5nIGRhdGEgPSBtX2R0bS5nZXRTdHJpbmdWYWx1ZShub2RlKTsKLQotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgTGV4aWNhbEhhbmRsZXIgbGggPSAoKExleGljYWxIYW5kbGVyKSB0aGlzLm1fY29udGVudEhhbmRsZXIpOwotICAgICAgICBkYXRhLmRpc3BhdGNoQXNDb21tZW50KGxoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0KLSAgICAgIC8vID8/OwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRE9DVU1FTlRfTk9ERSA6Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICAgIERUTSBkdG0gPSBtX2R0bTsgICAgICAgICAgIAotCi0gICAgICBmb3IgKGludCBuc24gPSBkdG0uZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKG5vZGUsIHRydWUpOyBEVE0uTlVMTCAhPSBuc247Ci0gICAgICAgICAgIG5zbiA9IGR0bS5nZXROZXh0TmFtZXNwYWNlTm9kZShub2RlLCBuc24sIHRydWUpKQotICAgICAgewotICAgICAgICAvLyBTdHJpbmcgcHJlZml4ID0gZHRtLmdldFByZWZpeChuc24pOwotICAgICAgICBTdHJpbmcgcHJlZml4ID0gZHRtLmdldE5vZGVOYW1lWChuc24pOwotCi0gICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcocHJlZml4LCBkdG0uZ2V0Tm9kZVZhbHVlKG5zbikpOwotICAgICAgICAKLSAgICAgIH0KLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJtX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKTogIittX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKSk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKG5vZGUpOiAiK21fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKG5vZGUpKTsKLSAgICAgIFN0cmluZyBucyA9IGR0bS5nZXROYW1lc3BhY2VVUkkobm9kZSk7Ci0gICAgICBpZihudWxsID09IG5zKQotICAgICAgICBucyA9ICIiOwotICAgICAgICAKLSAgICAgIC8vICVPUFQlICEhCi0gICAgICBvcmcueG1sLnNheC5oZWxwZXJzLkF0dHJpYnV0ZXNJbXBsIGF0dHJzID0gCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGwoKTsKLSAgICAgICAgICAgICAgCi0gICAgICBmb3IgKGludCBpID0gZHRtLmdldEZpcnN0QXR0cmlidXRlKG5vZGUpOyAKLSAgICAgICAgICAgaSAhPSBEVE0uTlVMTDsgCi0gICAgICAgICAgIGkgPSBkdG0uZ2V0TmV4dEF0dHJpYnV0ZShpKSkgCi0gICAgICB7Ci0gICAgICAgIGF0dHJzLmFkZEF0dHJpYnV0ZShkdG0uZ2V0TmFtZXNwYWNlVVJJKGkpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0bS5nZXRMb2NhbE5hbWUoaSksIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRtLmdldE5vZGVOYW1lKGkpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICJDREFUQSIsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRtLmdldE5vZGVWYWx1ZShpKSk7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgICAgCi0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KG5zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2R0bS5nZXRMb2NhbE5hbWUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtLmdldE5vZGVOYW1lKG5vZGUpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRycyk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lID0gbV9kdG0uZ2V0Tm9kZU5hbWUobm9kZSk7Ci0KLSAgICAgIC8vIFN0cmluZyBkYXRhID0gcGkuZ2V0RGF0YSgpOwotICAgICAgaWYgKG5hbWUuZXF1YWxzKCJ4c2x0LW5leHQtaXMtcmF3IikpCi0gICAgICB7Ci0gICAgICAgIG5leHRJc1JhdyA9IHRydWU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24obmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2R0bS5nZXROb2RlVmFsdWUobm9kZSkpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNMZXhIID0gKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcik7Ci0gICAgICBMZXhpY2FsSGFuZGxlciBsaCA9IGlzTGV4SAotICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcikgOiBudWxsOwotCi0gICAgICBpZiAoaXNMZXhIKQotICAgICAgewotICAgICAgICBsaC5zdGFydENEQVRBKCk7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotCi0gICAgICB7Ci0gICAgICAgIGlmIChpc0xleEgpCi0gICAgICAgIHsKLSAgICAgICAgICBsaC5lbmRDREFUQSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLlRFWFRfTk9ERSA6Ci0gICAgewotICAgICAgaWYgKG5leHRJc1JhdykKLSAgICAgIHsKLSAgICAgICAgbmV4dElzUmF3ID0gZmFsc2U7Ci0KLSAgICAgICAgbV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQuUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgICAgZGlzcGF0YWNoQ2hhcnMobm9kZSk7Ci0gICAgICAgIG1fY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZGlzcGF0YWNoQ2hhcnMobm9kZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSA6Ci0gICAgewotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgKChMZXhpY2FsSGFuZGxlcikgdGhpcy5tX2NvbnRlbnRIYW5kbGVyKS5zdGFydEVudGl0eSgKLSAgICAgICAgICBtX2R0bS5nZXROb2RlTmFtZShub2RlKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gd2FybmluZygiQ2FuIG5vdCBvdXRwdXQgZW50aXR5IHRvIGEgcHVyZSBTQVggQ29udGVudEhhbmRsZXIiKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEVuZCBwcm9jZXNzaW5nIG9mIGdpdmVuIG5vZGUgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgd2UganVzdCBmaW5pc2hlZCBwcm9jZXNzaW5nCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBlbmROb2RlKGludCBub2RlKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHN3aXRjaCAobV9kdG0uZ2V0Tm9kZVR5cGUobm9kZSkpCi0gICAgewotICAgIGNhc2UgRFRNLkRPQ1VNRU5UX05PREUgOgotICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmVuZERvY3VtZW50KCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5FTEVNRU5UX05PREUgOgotICAgICAgU3RyaW5nIG5zID0gbV9kdG0uZ2V0TmFtZXNwYWNlVVJJKG5vZGUpOwotICAgICAgaWYobnVsbCA9PSBucykKLSAgICAgICAgbnMgPSAiIjsKLSAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmRFbGVtZW50KG5zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2R0bS5nZXRMb2NhbE5hbWUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZHRtLmdldE5vZGVOYW1lKG5vZGUpKTsKLQotICAgICAgZm9yIChpbnQgbnNuID0gbV9kdG0uZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlKG5vZGUsIHRydWUpOyBEVE0uTlVMTCAhPSBuc247Ci0gICAgICAgICAgIG5zbiA9IG1fZHRtLmdldE5leHROYW1lc3BhY2VOb2RlKG5vZGUsIG5zbiwgdHJ1ZSkpCi0gICAgICB7Ci0gICAgICAgIC8vIFN0cmluZyBwcmVmaXggPSBtX2R0bS5nZXRQcmVmaXgobnNuKTsKLSAgICAgICAgU3RyaW5nIHByZWZpeCA9IG1fZHRtLmdldE5vZGVOYW1lWChuc24pOwotCi0gICAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKHByZWZpeCk7Ci0gICAgICB9Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICB7Ci0gICAgICBpZiAobV9jb250ZW50SGFuZGxlciBpbnN0YW5jZW9mIExleGljYWxIYW5kbGVyKQotICAgICAgewotICAgICAgICBMZXhpY2FsSGFuZGxlciBsaCA9ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcik7Ci0KLSAgICAgICAgbGguZW5kRW50aXR5KG1fZHRtLmdldE5vZGVOYW1lKG5vZGUpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgfQotICB9Ci19ICAvL1RyZWVXYWxrZXIKLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRXhwYW5kZWROYW1lVGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL0V4cGFuZGVkTmFtZVRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmMTQ2YTQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvRXhwYW5kZWROYW1lVGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIyOCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotLyoqCi0gKiBUaGlzIGlzIGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBhIHRhYmxlIHRoYXQgbWFuYWdlcyBtYXBwaW5ncyBmcm9tCi0gKiBleHBhbmRlZCBuYW1lcyB0byBleHBhbmRlZE5hbWVJRHMuCi0gKgotICogJVJFVklFVyUgTm90ZSB0aGF0IHRoaXMgaXMgbm90IHJlYWxseSBhIHNlcGFyYXRlIHRhYmxlLCBvciBhCi0gKiBzZXBhcmF0ZSBwb29sLiBJbnN0ZWFkLCBpdCdzIGFuIGFjY2VzcyBtZXRob2QgYnVpbGQgb24gdG9wIG9mIHRoZQotICogZXhpc3RpbmcgcG9vbHMsIHVzaW5nIHRocmVlIHBpZWNlcyBvZiBpbmZvcm1hdGlvbjogdGhlIGluZGV4Ci0gKiBudW1iZXJzIGZvciBhIG5vZGUncyBuYW1lc3BhY2VVUkksIGxvY2FsTmFtZSwgYW5kIG5vZGUgdHlwZSwgd2hpY2gKLSAqIGFyZSBjb21iaW5lZCB0byB5aWVsZCBhIGNvbXBvc2l0ZSBpbmRleCBudW1iZXIuCi0gKgotICogJVRCRCUgc3RhcnR1cCBzZXF1ZW5jZSAtLSBob3cgdGhpcyBnZXRzIGFjY2VzcyB0byB0aGUgYXBwcm9wcmlhdGUKLSAqIHN0cmluZyBwb29scyBpbiB0aGUgRFRNRG9jdW1lbnQvc3R5bGVzaGVldC4KLSAqCi0gKiAqLwotcHVibGljIGNsYXNzIEV4cGFuZGVkTmFtZVRhYmxlCi17Ci0KLSAgLyoqIFByb2JhYmx5IGEgcmVmZXJlbmNlIHRvIHN0YXRpYyBwb29sLiAgICAgKi8KLSAgcHJpdmF0ZSBEVE1TdHJpbmdQb29sIG1fbG9jTmFtZXNQb29sOwotCi0gIC8qKiBQcm9iYWJseSBhIHJlZmVyZW5jZSB0byBzdGF0aWMgcG9vbC4gICAqLwotICBwcml2YXRlIERUTVN0cmluZ1Bvb2wgbV9uYW1lc3BhY2VOYW1lczsKLSAgCi0gIHB1YmxpYyBzdGF0aWMgaW50IEJJVFNfUEVSX0xPQ0FMTkFNRSA9IDE2OwotICBwdWJsaWMgc3RhdGljIGludCBCSVRTX1BFUl9OQU1FU1BBQ0UgPSAxMDsKLQotICBwdWJsaWMgc3RhdGljIGludCBNQVNLX0xPQ0FMTkFNRSA9IDB4MDAwMEZGRkY7Ci0gIHB1YmxpYyBzdGF0aWMgaW50IE1BU0tfTkFNRVNQQUNFID0gMHgwM0ZGMDAwMDsKLSAgcHVibGljIHN0YXRpYyBpbnQgTUFTS19OT0RFVFlQRSA9IDB4RkMwMDAwMDA7Ci0gIHB1YmxpYyBzdGF0aWMgaW50IE1BU0tfTk9ERUhBTkRMRSA9IDB4MDAwRkZGRkY7Ci0KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9UQU1PVU5UX1RZUEUgPSAoQklUU19QRVJfTkFNRVNQQUNFK0JJVFNfUEVSX0xPQ0FMTkFNRSk7Ci0gIAotICAvLyBUaGVzZSBhcmUgYWxsIHRoZSB0eXBlcyBwcmVyb3RhdGVkLCBmb3IgY2FsbGVyIGNvbnZlbmllbmNlLgotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTEVNRU5UID0gKChpbnQpRFRNLkVMRU1FTlRfTk9ERSkgPDwgUk9UQU1PVU5UX1RZUEU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFUVFJJQlVURSA9ICgoaW50KURUTS5BVFRSSUJVVEVfTk9ERSkgPDwgUk9UQU1PVU5UX1RZUEU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFWFQgPSAoKGludClEVE0uVEVYVF9OT0RFKSA8PCBST1RBTU9VTlRfVFlQRTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0RBVEFfU0VDVElPTiA9ICgoaW50KURUTS5DREFUQV9TRUNUSU9OX05PREUpIDw8IFJPVEFNT1VOVF9UWVBFOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfUkVGRVJFTkNFID0gKChpbnQpRFRNLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkgPDwgUk9UQU1PVU5UX1RZUEU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVElUWSA9ICgoaW50KURUTS5FTlRJVFlfTk9ERSkgPDwgUk9UQU1PVU5UX1RZUEU7Ci0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSAoKGludClEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKSA8PCBST1RBTU9VTlRfVFlQRTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NTUVOVCA9ICgoaW50KURUTS5DT01NRU5UX05PREUpIDw8IFJPVEFNT1VOVF9UWVBFOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET0NVTUVOVCA9ICgoaW50KURUTS5ET0NVTUVOVF9OT0RFKSA8PCBST1RBTU9VTlRfVFlQRTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9DVU1FTlRfVFlQRSA9ICgoaW50KURUTS5ET0NVTUVOVF9UWVBFX05PREUpIDw8IFJPVEFNT1VOVF9UWVBFOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET0NVTUVOVF9GUkFHTUVOVCA9KChpbnQpRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUpIDw8IFJPVEFNT1VOVF9UWVBFOwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RBVElPTiA9ICgoaW50KURUTS5OT1RBVElPTl9OT0RFKSA8PCBST1RBTU9VTlRfVFlQRTsKLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFID0gKChpbnQpRFRNLk5BTUVTUEFDRV9OT0RFKSA8PCBST1RBTU9VTlRfVFlQRTsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGV4cGFuZGVkIG5hbWUgdGFibGUgdGhhdCB1c2VzIHByaXZhdGUgc3RyaW5nIHBvb2wgbG9va3VwLgotICAgKi8KLSAgcHVibGljIEV4cGFuZGVkTmFtZVRhYmxlKCkKLSAgewotICAgIG1fbG9jTmFtZXNQb29sID0gbmV3IERUTVNhZmVTdHJpbmdQb29sKCk7Ci0gICAgbV9uYW1lc3BhY2VOYW1lcyA9IG5ldyBEVE1TYWZlU3RyaW5nUG9vbCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIEV4cGFuZGVkTmFtZVRhYmxlCi0gICAqCi0gICAqIEBwYXJhbSBsb2NOYW1lc1Bvb2wgTG9jYWwgZWxlbWVudCBuYW1lcyBsb29rdXAuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VOYW1lcyBOYW1lc3BhY2UgdmFsdWVzIGxvb2t1cC4KLSAgICovCi0gIHB1YmxpYyBFeHBhbmRlZE5hbWVUYWJsZShEVE1TdHJpbmdQb29sIGxvY05hbWVzUG9vbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIERUTVN0cmluZ1Bvb2wgbmFtZXNwYWNlTmFtZXMpCi0gIHsKLSAgICBtX2xvY05hbWVzUG9vbCA9IGxvY05hbWVzUG9vbDsKLSAgICBtX25hbWVzcGFjZU5hbWVzID0gbmFtZXNwYWNlTmFtZXM7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQgbmFtZSwgcmV0dXJuIGFuIElELiAgSWYgdGhlIGV4cGFuZGVkLW5hbWUgZG9lcyBub3QKLSAgICogZXhpc3QgaW4gdGhlIGludGVybmFsIHRhYmxlcywgdGhlIGVudHJ5IHdpbGwgYmUgY3JlYXRlZCwgYW5kIHRoZSBJRCB3aWxsCi0gICAqIGJlIHJldHVybmVkLiAgQW55IGFkZGl0aW9uYWwgbm9kZXMgdGhhdCBhcmUgY3JlYXRlZCB0aGF0IGhhdmUgdGhpcwotICAgKiBleHBhbmRlZCBuYW1lIHdpbGwgdXNlIHRoaXMgSUQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBleHBhbmRlZC1uYW1lIGlkIG9mIHRoZSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbG9jYWxOYW1lLCBpbnQgdHlwZSkKLSAgewotICAgIGludCBuc0lEID0gKG51bGwgIT0gbmFtZXNwYWNlKSA/IG1fbmFtZXNwYWNlTmFtZXMuc3RyaW5nVG9JbmRleChuYW1lc3BhY2UpIDogMDsKLSAgICBpbnQgbG5JRCA9IG1fbG9jTmFtZXNQb29sLnN0cmluZ1RvSW5kZXgobG9jYWxOYW1lKTsKLSAgICAKLSAgICBpbnQgZXhwYW5kZWRUeXBlSUQgPSAodHlwZSA8PCAoQklUU19QRVJfTkFNRVNQQUNFK0JJVFNfUEVSX0xPQ0FMTkFNRSkpIAotICAgICAgICAgICAgICAgICAgICAgICB8IChuc0lEIDw8IEJJVFNfUEVSX0xPQ0FMTkFNRSkgfCBsbklEOwotCi0gICAgcmV0dXJuIGV4cGFuZGVkVHlwZUlEOwotICB9Ci0gIAotICAvKioKLSAgICogR2l2ZW4gYSB0eXBlLCByZXR1cm4gYW4gZXhwYW5kZWQgbmFtZSBJRC5BbnkgYWRkaXRpb25hbCBub2RlcyB0aGF0IGFyZSAKLSAgICogY3JlYXRlZCB0aGF0IGhhdmUgdGhpcyBleHBhbmRlZCBuYW1lIHdpbGwgdXNlIHRoaXMgSUQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UKLSAgICogQHBhcmFtIGxvY2FsTmFtZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBleHBhbmRlZC1uYW1lIGlkIG9mIHRoZSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRFeHBhbmRlZFR5cGVJRChpbnQgdHlwZSkKLSAgewotICAgIGludCBleHBhbmRlZFR5cGVJRCA9ICh0eXBlIDw8IChCSVRTX1BFUl9OQU1FU1BBQ0UrQklUU19QRVJfTE9DQUxOQU1FKSk7Ci0KLSAgICByZXR1cm4gZXhwYW5kZWRUeXBlSUQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgdGhlIG5vZGUgaGFzIG5vIG5hbWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgRXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICByZXR1cm4gbV9sb2NOYW1lc1Bvb2wuaW5kZXhUb1N0cmluZyhFeHBhbmRlZE5hbWVJRCAmIE1BU0tfTE9DQUxOQU1FKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbG9jYWwgbmFtZSBJRC4KLSAgICoKLSAgICogQHBhcmFtIEV4cGFuZGVkTmFtZUlEIGFuIElEIHRoYXQgcmVwcmVzZW50cyBhbiBleHBhbmRlZC1uYW1lLgotICAgKiBAcmV0dXJuIFRoZSBpZCBvZiB0aGlzIGxvY2FsIG5hbWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBnZXRMb2NhbE5hbWVJRChpbnQgRXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICByZXR1cm4gKEV4cGFuZGVkTmFtZUlEICYgTUFTS19MT0NBTE5BTUUpOwotICB9Ci0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBuYW1lc3BhY2UgVVJJIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBFeHBhbmRlZE5hbWVJRCBhbiBJRCB0aGF0IHJlcHJlc2VudHMgYW4gZXhwYW5kZWQtbmFtZS4KLSAgICogQHJldHVybiBTdHJpbmcgVVJJIHZhbHVlIG9mIHRoaXMgbm9kZSdzIG5hbWVzcGFjZSwgb3IgbnVsbCBpZiBubwotICAgKiBuYW1lc3BhY2Ugd2FzIHJlc29sdmVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2UoaW50IEV4cGFuZGVkTmFtZUlEKQotICB7Ci0KLSAgICBpbnQgaWQgPSAoRXhwYW5kZWROYW1lSUQgJiBNQVNLX05BTUVTUEFDRSkgPj4gQklUU19QRVJfTE9DQUxOQU1FOwotICAgIHJldHVybiAoMCA9PSBpZCkgPyBudWxsIDogbV9uYW1lc3BhY2VOYW1lcy5pbmRleFRvU3RyaW5nKGlkKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdpdmVuIGFuIGV4cGFuZGVkLW5hbWUgSUQsIHJldHVybiB0aGUgbmFtZXNwYWNlIFVSSSBJRC4KLSAgICoKLSAgICogQHBhcmFtIEV4cGFuZGVkTmFtZUlEIGFuIElEIHRoYXQgcmVwcmVzZW50cyBhbiBleHBhbmRlZC1uYW1lLgotICAgKiBAcmV0dXJuIFRoZSBpZCBvZiB0aGlzIG5hbWVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGdldE5hbWVzcGFjZUlEKGludCBFeHBhbmRlZE5hbWVJRCkKLSAgewotICAgIHJldHVybiAoRXhwYW5kZWROYW1lSUQgJiBNQVNLX05BTUVTUEFDRSkgPj4gQklUU19QRVJfTE9DQUxOQU1FOwotICB9Ci0gIAotICAvKioKLSAgICogR2l2ZW4gYW4gZXhwYW5kZWQtbmFtZSBJRCwgcmV0dXJuIHRoZSBsb2NhbCBuYW1lIElELgotICAgKgotICAgKiBAcGFyYW0gRXhwYW5kZWROYW1lSUQgYW4gSUQgdGhhdCByZXByZXNlbnRzIGFuIGV4cGFuZGVkLW5hbWUuCi0gICAqIEByZXR1cm4gVGhlIGlkIG9mIHRoaXMgbG9jYWwgbmFtZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgZ2V0VHlwZShpbnQgRXhwYW5kZWROYW1lSUQpCi0gIHsKLSAgICByZXR1cm4gKHNob3J0KShFeHBhbmRlZE5hbWVJRCA+PiBST1RBTU9VTlRfVFlQRSk7Ci0gIH0KLSAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGVlYzI3Ni4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSwyMDAwIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhlcmNlcyIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIEludGVybmF0aW9uYWwKLSAqIEJ1c2luZXNzIE1hY2hpbmVzLCBJbmMuLCBodHRwOi8vd3d3LmFwYWNoZS5vcmcuICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci0KLS8qKiA8cD5JbmNyZW1lbnRhbFNBWFNvdXJjZSBpcyBhbiBBUEkgdGhhdCBkZWxpdmVycyBhIHNtYWxsIG51bWJlciBvZgotICogU0FYIGV2ZW50cyBlYWNoIHRpbWUgYSByZXF1ZXN0IGlzIG1hZGUgZnJvbSBhICJjb250cm9sbGVyIgotICogY29yb3V0aW5lLiAgU2VlIEluY3JlbWVudGFsU0FYRmlsdGVyIGFuZCBJbmNyZW1lbnRhbFNBWEZpbHRlcl9YZXJjZXMKLSAqIGZvciBleGFtcGxlcy4KLSAqIAotICogTm90ZSB0aGF0IGludGVyYWN0aW9uIGlzIHZpYSB0aGUgZGVsaXZlck1vcmVOb2RlcwotICogbWV0aG9kLCBhbmQgdGhlcmVmb3JlIGNvcm91dGluZSBzdXBwb3J0IGlzIG5vdCBleHBvc2VkCi0gKiBoZXJlLjwvcD4KLSAqICovCi1wdWJsaWMgaW50ZXJmYWNlIEluY3JlbWVudGFsU0FYU291cmNlCi17Ci0gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAvLyBTQVggT3V0cHV0IEFQSQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotICAvKiogUmVnaXN0ZXIgYSBTQVgtc3R5bGUgY29udGVudCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpOwotCi0gIC8qKiAgUmVnaXN0ZXIgYSBTQVgtc3R5bGUgbGV4aWNhbCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExleGljYWxIYW5kbGVyKG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBoYW5kbGVyKTsKLQotICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgLy8gQ29tbWFuZCBJbnB1dCBBUEkKLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgLyoqIGRlbGl2ZXJNb3JlTm9kZXMoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIHRocmVhZCBpbiB3aGljaCB0aGUKLSAgICogSW5jcmVtZW50YWxTQVhTb3VyY2UgaXMgcnVubmluZyB0byBkZWxpdmVyIG1vcmUgZXZlbnRzICh0cnVlKSwKLSAgICogb3Igc3RvcCBkZWxpdmVyaW5nIGV2ZW50cyBhbmQgY2xvc2Ugb3V0IGl0cyBpbnB1dCAoZmFsc2UpLgotICAgKgotICAgKiBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZCBmcm9tIG9uZSBvZiBvdXIgcGFydG5lciBjb3JvdXRpbmVzLAotICAgKiBhbmQgc2VydmVzIHRvIGVuY2Fwc3VsYXRlIHRoZSBjb3JvdXRpbmUgY29tbXVuaWNhdGlvbiBwcm90b2NvbC4KLSAgICoKLSAgICogQHBhcmFtIHBhcnNlbW9yZSBJZiB0cnVlLCB0ZWxscyB0aGUgaW5jcmVtZW50YWwgU0FYIHN0cmVhbSB0byBkZWxpdmVyCi0gICAqIGFub3RoZXIgY2h1bmsgb2YgZXZlbnRzLiBJZiBmYWxzZSwgZmluaXNoZXMgb3V0IHRoZSBzdHJlYW0uCi0gICAqCi0gICAqIEByZXR1cm4gQm9vbGVhbi5UUlVFIGlmIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBiZWxpZXZlcyBtb3JlIGRhdGEKLSAgICogbWF5IGJlIGF2YWlsYWJsZSBmb3IgZnVydGhlciBwYXJzaW5nLiBCb29sZWFuLkZBTFNFIGlmIHBhcnNpbmcKLSAgICogcmFuIHRvIGNvbXBsZXRpb24sIG9yIHdhcyBlbmRlZCBieSBkZWxpdmVyTW9yZU5vZGVzKGZhbHNlKS4KLSAgICogKi8KLSAgcHVibGljIE9iamVjdCBkZWxpdmVyTW9yZU5vZGVzIChib29sZWFuIHBhcnNlbW9yZSk7Ci0KLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gIC8vIFBhcnNlIFRocmVhZCBDb252ZW5pZW5jZSBBUEkKLSAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLSAgLyoqIExhdW5jaCBhbiBYTUxSZWFkZXIncyBwYXJzaW5nIG9wZXJhdGlvbiwgZmVlZGluZyBldmVudHMgdG8gdGhpcwotICAgKiBJbmNyZW1lbnRhbFNBWFNvdXJjZS4gSW4gc29tZSBpbXBsZW1lbnRhdGlvbnMsIHRoaXMgbWF5IGxhdW5jaCBhCi0gICAqIHRocmVhZCB3aGljaCBydW5zIHRoZSBwcmV2aW91c2x5IHN1cHBsaWVkIFhNTFJlYWRlcidzIHBhcnNlKCkgb3BlcmF0aW9uLgotICAgKiBJbiBvdGhlcnMsIGl0IG1heSBkbyBvdGhlciBmb3JtcyBvZiBpbml0aWFsaXphdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gaXMgcGFyc2UgdGhyZWFkIGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3MKLSAgICogb3IgcGFyc2luZyBjYW4gbm90IGJlIHN0YXJ0ZWQuCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlKSB0aHJvd3MgU0FYRXhjZXB0aW9uOwotICAgIAotfSAvLyBjbGFzcyBJbmNyZW1lbnRhbFNBWFNvdXJjZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmI2NGM0OS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgxMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTksMjAwMCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5TQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQXR0cmlidXRlczsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkluY3JlbWVudGFsU0FYU291cmNlOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0vKiogPHA+SW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyIGltcGxlbWVudHMgSW5jcmVtZW50YWxTQVhTb3VyY2UsIHVzaW5nIGEKLSAqIHN0YW5kYXJkIFNBWDIgZXZlbnQgc291cmNlIGFzIGl0cyBpbnB1dCBhbmQgcGFyY2VsbGluZyBvdXQgdGhvc2UKLSAqIGV2ZW50cyBncmFkdWFsbHkgaW4gcmVwb25zZSB0byBkZWxpdmVyTW9yZU5vZGVzKCkgcmVxdWVzdHMuICBPdXRwdXQgZnJvbSB0aGUKLSAqIGZpbHRlciB3aWxsIGJlIHBhc3NlZCBhbG9uZyB0byBhIFNBWCBoYW5kbGVyIHJlZ2lzdGVyZWQgYXMgb3VyCi0gKiBsaXN0ZW5lciwgYnV0IHRob3NlIGNhbGxiYWNrcyB3aWxsIHBhc3MgdGhyb3VnaCBhIGNvdW50aW5nIHN0YWdlCi0gKiB3aGljaCBwZXJpb2RpY2FsbHkgeWllbGRzIGNvbnRyb2wgYmFjayB0byB0aGUgY29udHJvbGxlciBjb3JvdXRpbmUuCi0gKiA8L3A+Ci0gKgotICogPHA+JVJFVklFVyU6IFRoaXMgZmlsdGVyIGlzIG5vdCBjdXJyZW5seSBpbnRlbmRlZCB0byBiZSByZXVzYWJsZQotICogZm9yIHBhcnNpbmcgYWRkaXRpb25hbCBzdHJlYW1zL2RvY3VtZW50cy4gV2UgbWF5IHdhbnQgdG8gY29uc2lkZXIKLSAqIG1ha2luZyBpdCByZXNldHRhYmxlIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZS4gQnV0IGl0J3MgYSAKLSAqIHNtYWxsIG9iamVjdCwgc28gdGhhdCdkIGJlIG1vc3RseSBhIGNvbnZlbmllbmNlIGlzc3VlOyB0aGUgY29zdAotICogb2YgYWxsb2NhdGluZyBlYWNoIHRpbWUgaXMgdHJpdmlhbCBjb21wYXJlZCB0byB0aGUgY29zdCBvZiBwcm9jZXNzaW5nCi0gKiBhbnkgbm9udHJpdmFsIHN0cmVhbS48L3A+Ci0gKgotICogPHA+Rm9yIGEgYnJpZWYgdXNhZ2UgZXhhbXBsZSwgc2VlIHRoZSB1bml0LXRlc3QgbWFpbigpIG1ldGhvZC48L3A+Ci0gKgotICogPHA+VGhpcyBpcyBhIHNpbXBsaWZpY2F0aW9uIG9mIHRoZSBvbGQgQ29yb3V0aW5lU0FYUGFyc2VyLCBmb2N1c2luZwotICogc3BlY2lmaWNhbGx5IG9uIGZpbHRlcmluZy4gVGhlIHJlc3VsdGluZyBjb250cm9sbGVyIHByb3RvY29sIGlzIF9mYXJfCi0gKiBzaW1wbGVyIGFuZCBsZXNzIGVycm9yLXByb25lOyB0aGUgb25seSBjb250cm9sbGVyIG9wZXJhdGlvbiBpcyBkZWxpdmVyTW9yZU5vZGVzKCksCi0gKiBhbmQgdGhlIG9ubHkgcmVxdWlyZW1lbnQgaXMgdGhhdCBkZWxpdmVyTW9yZU5vZGVzKGZhbHNlKSBiZSBjYWxsZWQgaWYgeW91IHdhbnQgdG8KLSAqIGRpc2NhcmQgdGhlIHJlc3Qgb2YgdGhlIHN0cmVhbSBhbmQgdGhlIHByZXZpb3VzIGRlbGl2ZXJNb3JlTm9kZXMoKSBkaWRuJ3QgcmV0dXJuCi0gKiBmYWxzZS4KLSAqICovCi1wdWJsaWMgY2xhc3MgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyCi1pbXBsZW1lbnRzIEluY3JlbWVudGFsU0FYU291cmNlLCBDb250ZW50SGFuZGxlciwgTGV4aWNhbEhhbmRsZXIsIEVycm9ySGFuZGxlciwgUnVubmFibGUKLXsKLSAgYm9vbGVhbiBERUJVRz1mYWxzZTsgLy9JbnRlcm5hbCBzdGF0dXMgcmVwb3J0Ci0KLSAgLy8KLSAgLy8gRGF0YQotICAvLwotICBwcml2YXRlIENvcm91dGluZU1hbmFnZXIgZkNvcm91dGluZU1hbmFnZXIgPSBudWxsOwotICBwcml2YXRlIGludCBmQ29udHJvbGxlckNvcm91dGluZUlEID0gLTE7Ci0gIHByaXZhdGUgaW50IGZTb3VyY2VDb3JvdXRpbmVJRCA9IC0xOwotCi0gIHByaXZhdGUgQ29udGVudEhhbmRsZXIgY2xpZW50Q29udGVudEhhbmRsZXI9bnVsbDsgLy8gJVJFVklFVyUgc3VwcG9ydCBtdWx0aXBsZT8KLSAgcHJpdmF0ZSBMZXhpY2FsSGFuZGxlciBjbGllbnRMZXhpY2FsSGFuZGxlcj1udWxsOyAvLyAlUkVWSUVXJSBzdXBwb3J0IG11bHRpcGxlPwotICBwcml2YXRlIEVycm9ySGFuZGxlciBjbGllbnRFcnJvckhhbmRsZXI9bnVsbDsgLy8gJVJFVklFVyUgc3VwcG9ydCBtdWx0aXBsZT8KLSAgcHJpdmF0ZSBpbnQgZXZlbnRjb3VudGVyOwotICBwcml2YXRlIGludCBmcmVxdWVuY3k9NTsKLQotICAvLyBGbGFnIGluZGljYXRpbmcgdGhhdCBubyBtb3JlIGV2ZW50cyBzaG91bGQgYmUgZGVsaXZlcmVkIC0tIGVpdGhlcgotICAvLyBiZWNhdXNlIGlucHV0IHN0cmVhbSByYW4gdG8gY29tcGxldGlvbiAoZW5kRG9jdW1lbnQpLCBvciBiZWNhdXNlCi0gIC8vIHRoZSB1c2VyIHJlcXVlc3RlZCBhbiBlYXJseSBzdG9wIHZpYSBkZWxpdmVyTW9yZU5vZGVzKGZhbHNlKS4KLSAgcHJpdmF0ZSBib29sZWFuIGZOb01vcmVFdmVudHM9ZmFsc2U7Ci0KLSAgLy8gU3VwcG9ydCBmb3Igc3RhcnRQYXJzZSgpCi0gIHByaXZhdGUgWE1MUmVhZGVyIGZYTUxSZWFkZXI9bnVsbDsKLSAgcHJpdmF0ZSBJbnB1dFNvdXJjZSBmWE1MUmVhZGVySW5wdXRTb3VyY2U9bnVsbDsKLQotICAvLwotICAvLyBDb25zdHJ1Y3RvcnMKLSAgLy8KLQotICBwdWJsaWMgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKCkgewotICAgIHRoaXMuaW5pdCggbmV3IENvcm91dGluZU1hbmFnZXIoKSwgLTEsIC0xKTsKLSAgfQotICAKLSAgLyoqIENyZWF0ZSBhIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciB3aGljaCBpcyBub3QgeWV0IGJvdW5kIHRvIGEgc3BlY2lmaWMKLSAgICogU0FYIGV2ZW50IHNvdXJjZS4KLSAgICogKi8KLSAgcHVibGljIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcihDb3JvdXRpbmVNYW5hZ2VyIGNvLCBpbnQgY29udHJvbGxlckNvcm91dGluZUlEKQotICB7Ci0gICAgdGhpcy5pbml0KCBjbywgY29udHJvbGxlckNvcm91dGluZUlELCAtMSApOwotICB9Ci0KLSAgLy8KLSAgLy8gRmFjdG9yaWVzCi0gIC8vCi0gIHN0YXRpYyBwdWJsaWMgSW5jcmVtZW50YWxTQVhTb3VyY2UgY3JlYXRlSW5jcmVtZW50YWxTQVhTb3VyY2UoQ29yb3V0aW5lTWFuYWdlciBjbywgaW50IGNvbnRyb2xsZXJDb3JvdXRpbmVJRCkgewotICAgIHJldHVybiBuZXcgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKGNvLCBjb250cm9sbGVyQ29yb3V0aW5lSUQpOwotICB9Ci0KLSAgLy8KLSAgLy8gUHVibGljIG1ldGhvZHMKLSAgLy8KLQotICBwdWJsaWMgdm9pZCBpbml0KCBDb3JvdXRpbmVNYW5hZ2VyIGNvLCBpbnQgY29udHJvbGxlckNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICBpbnQgc291cmNlQ29yb3V0aW5lSUQpCi0gIHsKLSAgICBpZihjbz09bnVsbCkKLSAgICAgIGNvID0gbmV3IENvcm91dGluZU1hbmFnZXIoKTsKLSAgICBmQ29yb3V0aW5lTWFuYWdlciA9IGNvOwotICAgIGZDb250cm9sbGVyQ29yb3V0aW5lSUQgPSBjby5jb19qb2luQ29yb3V0aW5lU2V0KGNvbnRyb2xsZXJDb3JvdXRpbmVJRCk7Ci0gICAgZlNvdXJjZUNvcm91dGluZUlEID0gY28uY29fam9pbkNvcm91dGluZVNldChzb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgaWYgKGZDb250cm9sbGVyQ29yb3V0aW5lSUQgPT0gLTEgfHwgZlNvdXJjZUNvcm91dGluZUlEID09IC0xKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfQ09KT0lOUk9VVElORVNFVF9GQUlMRUQsIG51bGwpKTsgLy8iY29fam9pbkNvcm91dGluZVNldCgpIGZhaWxlZCIpOwotCi0gICAgZk5vTW9yZUV2ZW50cz1mYWxzZTsKLSAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICB9Ci0gICAgCi0gIC8qKiBCaW5kIG91ciBpbnB1dCBzdHJlYW1zIHRvIGFuIFhNTFJlYWRlci4KLSAgICoKLSAgICogSnVzdCBhIGNvbnZlbmllbmNlIHJvdXRpbmU7IG9idmlvdXNseSB5b3UgY2FuIGV4cGxpY2l0bHkgcmVnaXN0ZXIKLSAgICogdGhpcyBhcyBhIGxpc3RlbmVyIHdpdGggdGhlIHNhbWUgZWZmZWN0LgotICAgKiAqLwotICBwdWJsaWMgdm9pZCBzZXRYTUxSZWFkZXIoWE1MUmVhZGVyIGV2ZW50c291cmNlKQotICB7Ci0gICAgZlhNTFJlYWRlcj1ldmVudHNvdXJjZTsKLSAgICBldmVudHNvdXJjZS5zZXRDb250ZW50SGFuZGxlcih0aGlzKTsKLSAgICBldmVudHNvdXJjZS5zZXRFcnJvckhhbmRsZXIodGhpcyk7IC8vIHRvIHJlcG9ydCBmYXRhbCBlcnJvcnMgaW4gZmlsdGVyaW5nIG1vZGUKLQotICAgIC8vIE5vdCBzdXBwb3J0ZWQgYnkgYWxsIFNBWDIgZmlsdGVyczoKLSAgICB0cnkgCi0gICAgewotICAgICAgZXZlbnRzb3VyY2UuCi0gICAgICAgIHNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIiLAotICAgICAgICAgICAgICAgICAgICB0aGlzKTsKLSAgICB9Ci0gICAgY2F0Y2goU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIE5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0Ci0gICAgfQotICAgIGNhdGNoKFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIE5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0Ci0gICAgfQotCi0gICAgLy8gU2hvdWxkIHdlIGFsc28gYmluZCBhcyBvdGhlciB2YXJpZXRpZXMgb2YgaGFuZGxlcj8KLSAgICAvLyAoRFRESGFuZGxlciBhbmQgc28gb24pCi0gIH0KLQotICAvLyBSZWdpc3RlciBhIGNvbnRlbnQgaGFuZGxlciBmb3IgdXMgdG8gb3V0cHV0IHRvCi0gIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKENvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICBjbGllbnRDb250ZW50SGFuZGxlcj1oYW5kbGVyOwotICB9Ci0gIC8vIFJlZ2lzdGVyIGEgbGV4aWNhbCBoYW5kbGVyIGZvciB1cyB0byBvdXRwdXQgdG8KLSAgLy8gTm90IGFsbCBmaWx0ZXJzIHN1cHBvcnQgdGhpcy4uLgotICAvLyA/Pz8gU2hvdWxkIHdlIHJlZ2lzdGVyIGRpcmVjdGx5IG9uIHRoZSBmaWx0ZXI/Ci0gIC8vIE5PVEUgTkFNRSAtLSBzdWJjbGFzc2luZyBpc3N1ZSBpbiB0aGUgWGVyY2VzIHZlcnNpb24KLSAgcHVibGljIHZvaWQgc2V0TGV4aWNhbEhhbmRsZXIoTGV4aWNhbEhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIGNsaWVudExleGljYWxIYW5kbGVyPWhhbmRsZXI7Ci0gIH0KLSAgLy8gUmVnaXN0ZXIgYW4gZXJyb3IgaGFuZGxlciBmb3IgdXMgdG8gb3V0cHV0IHRvCi0gIC8vIE5PVEUgTkFNRSAtLSBzdWJjbGFzc2luZyBpc3N1ZSBpbiB0aGUgWGVyY2VzIHZlcnNpb24KLSAgcHVibGljIHZvaWQgc2V0RXJySGFuZGxlcihFcnJvckhhbmRsZXIgaGFuZGxlcikKLSAgewotICAgIGNsaWVudEVycm9ySGFuZGxlcj1oYW5kbGVyOwotICB9Ci0KLSAgLy8gU2V0IHRoZSBudW1iZXIgb2YgZXZlbnRzIGJldHdlZW4gcmVzdW1lcyBvZiBvdXIgY29yb3V0aW5lCi0gIC8vIEltbWVkaWF0ZWx5IHJlc2V0cyBudW1iZXIgb2YgZXZlbnRzIGJlZm9yZSBfbmV4dF8gcmVzdW1lIGFzIHdlbGwuCi0gIHB1YmxpYyB2b2lkIHNldFJldHVybkZyZXF1ZW5jeShpbnQgZXZlbnRzKQotICB7Ci0gICAgaWYoZXZlbnRzPDEpIGV2ZW50cz0xOwotICAgIGZyZXF1ZW5jeT1ldmVudGNvdW50ZXI9ZXZlbnRzOwotICB9Ci0gIAotICAvLwotICAvLyBDb250ZW50SGFuZGxlciBtZXRob2RzCi0gIC8vIFRoZXNlICBwYXNzIHRoZSBkYXRhIHRvIG91ciBjbGllbnQgQ29udGVudEhhbmRsZXIuLi4KLSAgLy8gYnV0IHRoZXkgYWxzbyBjb3VudCB0aGUgbnVtYmVyIG9mIGV2ZW50cyBwYXNzaW5nIHRocm91Z2gsCi0gIC8vIGFuZCByZXN1bWUgb3VyIGNvcm91dGluZSBlYWNoIHRpbWUgdGhhdCBjb3VudGVyIGhpdHMgemVybyBhbmQKLSAgLy8gaXMgcmVzZXQuCi0gIC8vCi0gIC8vIE5vdGUgdGhhdCBmb3IgZXZlcnl0aGluZyBleGNlcHQgZW5kRG9jdW1lbnQgYW5kIGZhdGFsRXJyb3IsIHdlIGRvIHRoZSBjb3VudC1hbmQteWllbGQKLSAgLy8gQkVGT1JFIHBhc3NpbmcgdGhlIGNhbGwgYWxvbmcuIEknbSBob3BpbmcgdGhhdCB0aGlzIHdpbGwgZW5jb3VyYWdlIEpJVAotICAvLyBjb21waWxlcnMgdG8gcmVhbGl6ZSB0aGF0IHRoZXNlIGFyZSB0YWlsLWNhbGxzLCByZWR1Y2luZyB0aGUgZXhwZW5zZSBvZgotICAvLyB0aGUgYWRkaXRpb25hbCBsYXllciBvZiBkYXRhIGZsb3cuCi0gIC8vCi0gIC8vICVSRVZJRVclIEdsZW5uIHN1Z2dlc3RzIHRoYXQgcGF1c2luZyBhZnRlciBlbmRFbGVtZW50LCBlbmREb2N1bWVudCwKLSAgLy8gYW5kIGNoYXJhY3RlcnMgbWF5IGJlIHN1ZmZpY2llbnQuIEkgYWN0dWFsbHkgbWF5IG5vdCB3YW50IHRvCi0gIC8vIHN0b3AgYWZ0ZXIgY2hhcmFjdGVycywgc2luY2UgaW4gb3VyIGFwcGxpY2F0aW9uIHRoZXNlIHdpbmQgdXAgYmVpbmcKLSAgLy8gY29uY2F0ZW5hdGVkIGJlZm9yZSB0aGV5J3JlIHByb2Nlc3NlZC4uLiBidXQgdGhhdCByaXNrcyBodWdlIGJsb2NrcyBvZgotICAvLyB0ZXh0IGNhdXNpbmcgZ3JlYXRlciB0aGFuIHVzdWFsIHJlYWRhaGVhZC4gKFVubGlrZWx5PyBDb25zaWRlciB0aGUKLSAgLy8gcG9zc2liaWxpdHkgb2YgYSBsYXJnZSBiYXNlLTY0IGJsb2NrIGluIGEgU09BUCBzdHJlYW0uKQotICAvLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLmNoYXJhY3RlcnMoY2gsc3RhcnQsbGVuZ3RoKTsKLSAgfQotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIC8vIEVYQ0VQVElPTjogSW4gdGhpcyBjYXNlIHdlIG5lZWQgdG8gcnVuIHRoZSBldmVudCBCRUZPUkUgd2UgeWllbGQuCi0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotCi0gICAgZXZlbnRjb3VudGVyPTA7ICAgICAKLSAgICBjb195aWVsZChmYWxzZSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChqYXZhLmxhbmcuU3RyaW5nIG5hbWVzcGFjZVVSSSwgamF2YS5sYW5nLlN0cmluZyBsb2NhbE5hbWUsCi0gICAgICBqYXZhLmxhbmcuU3RyaW5nIHFOYW1lKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5lbmRFbGVtZW50KG5hbWVzcGFjZVVSSSxsb2NhbE5hbWUscU5hbWUpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZFByZWZpeE1hcHBpbmcoamF2YS5sYW5nLlN0cmluZyBwcmVmaXgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgfQotICBwdWJsaWMgdm9pZCBpZ25vcmFibGVXaGl0ZXNwYWNlKGNoYXJbXSBjaCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKGNoLHN0YXJ0LGxlbmd0aCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmEubGFuZy5TdHJpbmcgdGFyZ2V0LCBqYXZhLmxhbmcuU3RyaW5nIGRhdGEpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgICBpZihjbGllbnRDb250ZW50SGFuZGxlciE9bnVsbCkKLSAgICAgIGNsaWVudENvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbih0YXJnZXQsZGF0YSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgLy8gVGhpcyBjYW4gY2F1c2UgYSBoYW5nLiAgLXNiCi0gICAgICAgIC8vIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKGxvY2F0b3IpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5za2lwcGVkRW50aXR5KG5hbWUpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBjb19lbnRyeV9wYXVzZSgpOwotCi0gICAgLy8gT3RoZXJ3aXNlLCBiZWdpbiBub3JtYWwgZXZlbnQgZGVsaXZlcnkKLSAgICBpZigtLWV2ZW50Y291bnRlcjw9MCkKLSAgICAgIHsKLSAgICAgICAgY29feWllbGQodHJ1ZSk7Ci0gICAgICAgIGV2ZW50Y291bnRlcj1mcmVxdWVuY3k7Ci0gICAgICB9Ci0gICAgaWYoY2xpZW50Q29udGVudEhhbmRsZXIhPW51bGwpCi0gICAgICBjbGllbnRDb250ZW50SGFuZGxlci5zdGFydERvY3VtZW50KCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcgbmFtZXNwYWNlVVJJLCBqYXZhLmxhbmcuU3RyaW5nIGxvY2FsTmFtZSwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgcU5hbWUsIEF0dHJpYnV0ZXMgYXR0cykgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc3RhcnRFbGVtZW50KG5hbWVzcGFjZVVSSSwgbG9jYWxOYW1lLCBxTmFtZSwgYXR0cyk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKGphdmEubGFuZy5TdHJpbmcgcHJlZml4LCBqYXZhLmxhbmcuU3RyaW5nIHVyaSkgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoLS1ldmVudGNvdW50ZXI8PTApCi0gICAgICB7Ci0gICAgICAgIGNvX3lpZWxkKHRydWUpOwotICAgICAgICBldmVudGNvdW50ZXI9ZnJlcXVlbmN5OwotICAgICAgfQotICAgIGlmKGNsaWVudENvbnRlbnRIYW5kbGVyIT1udWxsKQotICAgICAgY2xpZW50Q29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCx1cmkpOwotICB9Ci0KLSAgLy8KLSAgLy8gTGV4aWNhbEhhbmRsZXIgc3VwcG9ydC4gTm90IGFsbCBTQVgyIGZpbHRlcnMgc3VwcG9ydCB0aGVzZSBldmVudHMKLSAgLy8gYnV0IHdlIG1heSB3YW50IHRvIHBhc3MgdGhlbSB0aHJvdWdoIHdoZW4gdGhleSBleGlzdC4uLgotICAvLwotICAvLyAlUkVWSUVXJSBUaGVzZSBkbyBOT1QgY3VycmVudGx5IGFmZmVjdCB0aGUgZXZlbnRjb3VudGVyOyBJJ20gYXNzZXJ0aW5nCi0gIC8vIHRoYXQgdGhleSdyZSByYXJlIGVub3VnaCB0aGF0IGl0IG1ha2VzIGxpdHRsZSBvciBubyBzZW5zZSB0bwotICAvLyBwYXVzZSBhZnRlciB0aGVtLiBBcyBzdWNoLCBpdCBtYXkgbWFrZSBtb3JlIHNlbnNlIGZvciBmb2xrcyB3aG8KLSAgLy8gYWN0dWFsbHkgd2FudCB0byB1c2UgdGhlbSB0byByZWdpc3RlciBkaXJlY3RseSB3aXRoIHRoZSBmaWx0ZXIuCi0gIC8vIEJ1dCBJIHdhbnQgJ2VtIGhlcmUgZm9yIG5vdywgdG8gcmVtaW5kIHVzIHRvIHJlY2hlY2sgdGhpcyBhc3NlcnRpb24hCi0gIC8vCi0gIHB1YmxpYyB2b2lkIGNvbW1lbnQoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuY29tbWVudChjaCxzdGFydCxsZW5ndGgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50TGV4aWNhbEhhbmRsZXIpCi0gICAgICBjbGllbnRMZXhpY2FsSGFuZGxlci5lbmRDREFUQSgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIGVuZERURCgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuZW5kRFREKCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgZW5kRW50aXR5KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgCi0gICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50TGV4aWNhbEhhbmRsZXIpCi0gICAgICBjbGllbnRMZXhpY2FsSGFuZGxlci5lbmRFbnRpdHkobmFtZSk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuc3RhcnRDREFUQSgpOwotICB9Ci0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgamF2YS5sYW5nLlN0cmluZyBwdWJsaWNJZCwKLSAgICAgIGphdmEubGFuZy5TdHJpbmcgc3lzdGVtSWQpIAotICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudExleGljYWxIYW5kbGVyKQotICAgICAgY2xpZW50TGV4aWNhbEhhbmRsZXIuIHN0YXJ0RFREKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCk7Ci0gIH0KLSAgcHVibGljIHZvaWQgc3RhcnRFbnRpdHkoamF2YS5sYW5nLlN0cmluZyBuYW1lKSAKLSAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihudWxsIT1jbGllbnRMZXhpY2FsSGFuZGxlcikKLSAgICAgIGNsaWVudExleGljYWxIYW5kbGVyLnN0YXJ0RW50aXR5KG5hbWUpOwotICB9Ci0KLSAgLy8KLSAgLy8gRXJyb3JIYW5kbGVyIHN1cHBvcnQuCi0gIC8vCi0gIC8vIFBST0JMRU06IFhlcmNlcyBpcyBhcHBhcmVudGx5IF9ub3RfIGNhbGxpbmcgdGhlIEVycm9ySGFuZGxlciBmb3IKLSAgLy8gZXhjZXB0aW9ucyB0aHJvd24gYnkgdGhlIENvbnRlbnRIYW5kbGVyLCB3aGljaCBwcmV2ZW50cyB1cyBmcm9tCi0gIC8vIGhhbmRsaW5nIHRoaXMgcHJvcGVybHkgd2hlbiBydW5uaW5nIGluIGZpbHRlcmluZyBtb2RlIHdpdGggWGVyY2VzCi0gIC8vIGFzIG91ciBldmVudCBzb3VyY2UuICBJdCdzIHVuY2xlYXIgd2hldGhlciB0aGlzIGlzIGEgWGVyY2VzIGJ1ZwotICAvLyBvciBhIFNBWCBkZXNpZ24gZmxhdy4KLSAgLy8gCi0gIC8vICVSRVZJRVclIEN1cnJlbnQgc29sdXRpb246IEluIGZpbHRlcmluZyBtb2RlLCBpdCBpcyBSRVFVSVJFRCB0aGF0Ci0gIC8vIGV2ZW50IHNvdXJjZSBtYWtlIHN1cmUgdGhpcyBtZXRob2QgaXMgaW52b2tlZCBpZiB0aGUgZXZlbnQgc3RyZWFtCi0gIC8vIGFiZW5kcyBiZWZvcmUgZW5kRG9jdW1lbnQgaXMgZGVsaXZlcmVkLiBJZiB0aGF0IG1lYW5zIGV4cGxpY2l0bHkgY2FsbGluZwotICAvLyB1cyBpbiB0aGUgZXhjZXB0aW9uIGhhbmRsaW5nIGNvZGUgYmVjYXVzZSBpdCB3b24ndCBiZSBkZWxpdmVyZWQgYXMgcGFydAotICAvLyBvZiB0aGUgbm9ybWFsIFNBWCBFcnJvckhhbmRsZXIgc3RyZWFtLCB0aGF0J3MgZmluZTsgTm90IE91ciBQcm9ibGVtLgotICAvLwotICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwhPWNsaWVudEVycm9ySGFuZGxlcikKLSAgICAgIGNsaWVudEVycm9ySGFuZGxlci5lcnJvcihleGNlcHRpb24pOwotICB9Ci0gIAotICBwdWJsaWMgdm9pZCBmYXRhbEVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gRVhDRVBUSU9OOiBJbiB0aGlzIGNhc2Ugd2UgbmVlZCB0byBydW4gdGhlIGV2ZW50IEJFRk9SRSB3ZSB5aWVsZCAtLQotICAgIC8vIGp1c3QgYXMgd2l0aCBlbmREb2N1bWVudCwgdGhpcyB0ZXJtaW5hdGVzIHRoZSBldmVudCBzdHJlYW0uCi0gICAgaWYobnVsbCE9Y2xpZW50RXJyb3JIYW5kbGVyKQotICAgICAgY2xpZW50RXJyb3JIYW5kbGVyLmVycm9yKGV4Y2VwdGlvbik7Ci0KLSAgICBldmVudGNvdW50ZXI9MDsgICAgIAotICAgIGNvX3lpZWxkKGZhbHNlKTsKLQotICB9Ci0gIAotICBwdWJsaWMgdm9pZCB3YXJuaW5nKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobnVsbCE9Y2xpZW50RXJyb3JIYW5kbGVyKQotICAgICAgY2xpZW50RXJyb3JIYW5kbGVyLmVycm9yKGV4Y2VwdGlvbik7Ci0gIH0KLSAgCi0KLSAgLy8KLSAgLy8gY29yb3V0aW5lIHN1cHBvcnQKLSAgLy8KLQotICBwdWJsaWMgaW50IGdldFNvdXJjZUNvcm91dGluZUlEKCkgewotICAgIHJldHVybiBmU291cmNlQ29yb3V0aW5lSUQ7Ci0gIH0KLSAgcHVibGljIGludCBnZXRDb250cm9sbGVyQ29yb3V0aW5lSUQoKSB7Ci0gICAgcmV0dXJuIGZDb250cm9sbGVyQ29yb3V0aW5lSUQ7Ci0gIH0KLQotICAvKiogQHJldHVybiB0aGUgQ29yb3V0aW5lTWFuYWdlciB0aGlzIENvcm91dGluZUZpbHRlciBvYmplY3QgaXMgYm91bmQgdG8uCi0gICAqIElmIHlvdSdyZSB1c2luZyB0aGUgZG8uLi4oKSBtZXRob2RzLCBhcHBsaWNhdGlvbnMgc2hvdWxkIG9ubHkKLSAgICogbmVlZCB0byB0YWxrIHRvIHRoZSBDb3JvdXRpbmVNYW5hZ2VyIG9uY2UsIHRvIG9idGFpbiB0aGUKLSAgICogYXBwbGljYXRpb24ncyBDb3JvdXRpbmUgSUQuCi0gICAqICovCi0gIHB1YmxpYyBDb3JvdXRpbmVNYW5hZ2VyIGdldENvcm91dGluZU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIGZDb3JvdXRpbmVNYW5hZ2VyOwotICB9Ci0KLSAgLyoqIDxwPkluIHRoZSBTQVggZGVsZWdhdGlvbiBjb2RlLCBJJ3ZlIGlubGluZWQgdGhlIGNvdW50LWRvd24gaW4KLSAgICogdGhlIGhvcGUgb2YgZW5jb3VyYWdpbmcgY29tcGlsZXJzIHRvIGRlbGl2ZXIgYmV0dGVyCi0gICAqIHBlcmZvcm1hbmNlLiBIb3dldmVyLCBpZiB3ZSBzdWJjbGFzcyAoZWcgdG8gZGlyZWN0bHkgY29ubmVjdCB0aGUKLSAgICogb3V0cHV0IHRvIGEgRFRNIGJ1aWxkZXIpLCB0aGF0IHdvdWxkIHJlcXVpcmUgY2FsbGluZyBzdXBlciBpbgotICAgKiBvcmRlciB0byBydW4gdGhhdCBsb2dpYy4uLiB3aGljaCBzZWVtcyBpbmVsZWdhbnQuICBIZW5jZSB0aGlzCi0gICAqIHJvdXRpbmUgZm9yIHRoZSBjb252ZW5pZW5jZSBvZiBzdWJjbGFzc2VzOiBldmVyeSBbZnJlcXVlbmN5XQotICAgKiBpbnZvY2F0aW9ucywgaXNzdWUgYSBjb195aWVsZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBtb3JlRXhlcGVjdGVkIFNob3VsZCBhbHdheXMgYmUgdHJ1ZSB1bmxlc3MgdGhpcyBpcyBiZWluZyBjYWxsZWQKLSAgICogYXQgdGhlIGVuZCBvZiBlbmREb2N1bWVudCgpIGhhbmRsaW5nLgotICAgKiAqLwotICBwcm90ZWN0ZWQgdm9pZCBjb3VudF9hbmRfeWllbGQoYm9vbGVhbiBtb3JlRXhwZWN0ZWQpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGlmKCFtb3JlRXhwZWN0ZWQpIGV2ZW50Y291bnRlcj0wOwotICAgIAotICAgIGlmKC0tZXZlbnRjb3VudGVyPD0wKQotICAgICAgewotICAgICAgICBjb195aWVsZCh0cnVlKTsKLSAgICAgICAgZXZlbnRjb3VudGVyPWZyZXF1ZW5jeTsKLSAgICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBjb19lbnRyeV9wYXVzZSBpcyBjYWxsZWQgaW4gc3RhcnREb2N1bWVudCgpIGJlZm9yZSBhbnl0aGluZyBlbHNlCi0gICAqIGhhcHBlbnMuIEl0IGNhdXNlcyB0aGUgZmlsdGVyIHRvIHdhaXQgZm9yIGEgImdvIGFoZWFkIiByZXF1ZXN0Ci0gICAqIGZyb20gdGhlIGNvbnRyb2xsZXIgYmVmb3JlIGRlbGl2ZXJpbmcgYW55IGV2ZW50cy4gTm90ZSB0aGF0Ci0gICAqIHRoZSB2ZXJ5IGZpcnN0IHRoaW5nIHRoZSBjb250cm9sbGVyIHRlbGxzIHVzIG1heSBiZSAiSSBkb24ndAotICAgKiBuZWVkIGV2ZW50cyBhZnRlciBhbGwiIQotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGNvX2VudHJ5X3BhdXNlKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoZkNvcm91dGluZU1hbmFnZXI9PW51bGwpCi0gICAgewotICAgICAgLy8gTm9ib2R5IGNhbGxlZCBpbml0KCk/IERvIGl0IG5vdy4uLgotICAgICAgaW5pdChudWxsLC0xLC0xKTsKLSAgICB9Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBPYmplY3QgYXJnPWZDb3JvdXRpbmVNYW5hZ2VyLmNvX2VudHJ5X3BhdXNlKGZTb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgICBpZihhcmc9PUJvb2xlYW4uRkFMU0UpCi0gICAgICAgIGNvX3lpZWxkKGZhbHNlKTsKLSAgICB9Ci0gICAgY2F0Y2goTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgLy8gQ29yb3V0aW5lIHN5c3RlbSBzYXlzIHdlIGhhdmVuJ3QgcmVnaXN0ZXJlZC4gVGhhdCdzIGFuCi0gICAgICAvLyBhcHBsaWNhdGlvbiBjb2RpbmcgZXJyb3IsIGFuZCBpcyB1bnJlY292ZXJhYmxlLgotICAgICAgaWYoREVCVUcpIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb19ZaWVsZCBoYW5kbGVzIGNvcm91dGluZSBpbnRlcmFjdGlvbnMgd2hpbGUgYSBwYXJzZSBpcyBpbiBwcm9ncmVzcy4KLSAgICoKLSAgICogV2hlbiBtb3JlUmVtYWlucz09dHJ1ZSwgd2UgYXJlIHBhdXNpbmcgYWZ0ZXIgZGVsaXZlcmluZyBldmVudHMsIHRvCi0gICAqIGFzayBpZiBtb3JlIGFyZSBuZWVkZWQuIFdlIHdpbGwgcmVzdW1lIHRoZSBjb250cm9sbGVyIHRocmVhZCB3aXRoIAotICAgKiAgIGNvX3Jlc3VtZShCb29sZWFuLlRSVUUsIC4uLikKLSAgICogV2hlbiBjb250cm9sIGlzIHBhc3NlZCBiYWNrIGl0IG1heSBpbmRpY2F0ZQotICAgKiAgICAgIEJvb2xlYW4uVFJVRSAgICBpbmRpY2F0aW9uIHRvIGNvbnRpbnVlIGRlbGl2ZXJpbmcgZXZlbnRzCi0gICAqICAgICAgQm9vbGVhbi5GQUxTRSAgIGluZGljYXRpb24gdG8gZGlzY29udGludWUgZXZlbnRzIGFuZCBzaHV0IGRvd24uCi0gICAqIAotICAgKiBXaGVuIG1vcmVSZW1haW5zPT1mYWxzZSwgd2Ugc2h1dCBkb3duIGltbWVkaWF0ZWx5IHdpdGhvdXQgYXNraW5nIHRoZQotICAgKiBjb250cm9sbGVyJ3MgcGVybWlzc2lvbi4gTm9ybWFsbHkgdGhpcyBtZWFucyBlbmQgb2YgZG9jdW1lbnQgaGFzIGJlZW4KLSAgICogcmVhY2hlZC4KLSAgICoKLSAgICogU2h1dHRpbmcgZG93biBhIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciByZXF1aXJlcyB0ZXJtaW5hdGluZyB0aGUgaW5jb21pbmcKLSAgICogU0FYIGV2ZW50IHN0cmVhbS4gSWYgd2UgYXJlIGluIGNvbnRyb2wgb2YgdGhhdCBzdHJlYW0gKGlmIGl0IGNhbWUKLSAgICogZnJvbSBhbiBYTUxSZWFkZXIgcGFzc2VkIHRvIG91ciBzdGFydFJlYWRlcigpIG1ldGhvZCksIHdlIGNhbiBkbyBzbwotICAgKiB2ZXJ5IHF1aWNrbHkgYnkgdGhyb3dpbmcgYSByZXNlcnZlZCBleGNlcHRpb24gdG8gaXQuIElmIHRoZSBzdHJlYW0gaXMKLSAgICogY29taW5nIGZyb20gYW5vdGhlciBzb3VyY2UsIHdlIGNhbid0IGRvIHRoYXQgYmVjYXVzZSBpdHMgY2FsbGVyIG1heQotICAgKiBub3QgYmUgcHJlcGFyZWQgZm9yIHRoaXMgIm5vcm1hbCBhYm5vcm1hbCBleGl0IiwgYW5kIGluc3RlYWQgd2UgcHV0Ci0gICAqIG91cnNlbHZlcyBpbiBhICJzcGluIiBtb2RlIHdoZXJlIGV2ZW50cyBhcmUgZGlzY2FyZGVkLgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGNvX3lpZWxkKGJvb2xlYW4gbW9yZVJlbWFpbnMpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8vIEhvcnJlbmRvdXMga2x1Z2UgdG8gcnVuIGZpbHRlciB0byBjb21wbGV0aW9uLiBTZWUgYmVsb3cuCi0gICAgaWYoZk5vTW9yZUV2ZW50cykKLSAgICAgIHJldHVybjsKLQotICAgIHRyeSAvLyBDb3JvdXRpbmUgbWFuYWdlciBtaWdodCB0aHJvdyBuby1zdWNoLgotICAgIHsKLSAgICAgIE9iamVjdCBhcmc9Qm9vbGVhbi5GQUxTRTsKLSAgICAgIGlmKG1vcmVSZW1haW5zKQotICAgICAgewotICAgICAgICAvLyBZaWVsZCBjb250cm9sLCByZXN1bWUgcGFyc2luZyB3aGVuIGRvbmUKLSAgICAgICAgYXJnID0gZkNvcm91dGluZU1hbmFnZXIuY29fcmVzdW1lKEJvb2xlYW4uVFJVRSwgZlNvdXJjZUNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbnRyb2xsZXJDb3JvdXRpbmVJRCk7Ci0gICAgICAgIAotICAgICAgfQotCi0gICAgICAvLyBJZiB3ZSdyZSBhdCBlbmQgb2YgZG9jdW1lbnQgb3Igd2VyZSB0b2xkIHRvIHN0b3AgZWFybHkKLSAgICAgIGlmKGFyZz09Qm9vbGVhbi5GQUxTRSkKLSAgICAgIHsKLSAgICAgICAgZk5vTW9yZUV2ZW50cz10cnVlOwotICAgICAgICAKLSAgICAgICAgaWYoZlhNTFJlYWRlciE9bnVsbCkgICAgLy8gUnVubmluZyB1bmRlciBzdGFydFBhcnNlVGhyZWFkKCkKLSAgICAgICAgICB0aHJvdyBuZXcgU3RvcEV4Y2VwdGlvbigpOyAvLyBXZSdsbCBjb19leGl0IGZyb20gdGhlcmUuCi0gICAgICAgIAotICAgICAgICAvLyBZaWVsZCBjb250cm9sLiBXZSBkbyBOT1QgZXhwZWN0IGFueW9uZSB0byBldmVyIGFzayB1cyBhZ2Fpbi4KLSAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdF90byhCb29sZWFuLkZBTFNFLCBmU291cmNlQ29yb3V0aW5lSUQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkNvbnRyb2xsZXJDb3JvdXRpbmVJRCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIFNob3VsZG4ndCBoYXBwZW4gdW5sZXNzIHdlJ3ZlIG1pc2NvZGVkIG91ciBjb3JvdXRpbmUgbG9naWMKLSAgICAgIC8vICJTaHV0IGRvd24gdGhlIGdhcmJhZ2Ugc21hc2hlcnMgb24gdGhlIGRldGVudGlvbiBsZXZlbCEiCi0gICAgICBmTm9Nb3JlRXZlbnRzPXRydWU7Ci0gICAgICBmQ29yb3V0aW5lTWFuYWdlci5jb19leGl0KGZTb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGUpOwotICAgIH0KLSAgfQotCi0gIC8vCi0gIC8vIENvbnZlbmllbmNlOiBSdW4gYW4gWE1MUmVhZGVyIGluIGEgdGhyZWFkCi0gIC8vCi0KLSAgLyoqIExhdW5jaCBhIHRocmVhZCB0aGF0IHdpbGwgcnVuIGFuIFhNTFJlYWRlcidzIHBhcnNlKCkgb3BlcmF0aW9uIHdpdGhpbgotICAgKiAgYSB0aHJlYWQsIGZlZWRpbmcgZXZlbnRzIHRvIHRoaXMgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLiBNb3N0bHkgYSBjb252ZW5pZW5jZQotICAgKiAgcm91dGluZSwgYnV0IGhhcyB0aGUgYWR2YW50YWdlIHRoYXQgLS0gc2luY2Ugd2UgaW52b2tlZCBwYXJzZSgpIC0tCi0gICAqICB3ZSBjYW4gaGFsdCBwYXJzaW5nIHF1aWNrbHkgdmlhIGEgU3RvcEV4Y2VwdGlvbiByYXRoZXIgdGhhbiB3YWl0aW5nCi0gICAqICBmb3IgdGhlIFNBWCBzdHJlYW0gdG8gZW5kIGJ5IGl0c2VsZi4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gaXMgcGFyc2UgdGhyZWFkIGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3MKLSAgICogb3IgcGFyc2luZyBjYW4gbm90IGJlIHN0YXJ0ZWQuCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihmTm9Nb3JlRXZlbnRzKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTkNSU0FYU1JDRklMVEVSX05PVF9SRVNUQVJUQUJMRSwgbnVsbCkpOyAvLyJJbmNybWVudGFsU0FYU291cmNlX0ZpbHRlciBub3QgY3VycmVudGx5IHJlc3RhcnRhYmxlLiIpOwotICAgIGlmKGZYTUxSZWFkZXI9PW51bGwpCi0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1hNTFJEUl9OT1RfQkVGT1JFX1NUQVJUUEFSU0UsIG51bGwpKTsgLy8iWE1MUmVhZGVyIG5vdCBiZWZvcmUgc3RhcnRQYXJzZSByZXF1ZXN0Iik7Ci0KLSAgICBmWE1MUmVhZGVySW5wdXRTb3VyY2U9c291cmNlOwotICAgIAotICAgIC8vIFhhbGFuIHRocmVhZCBwb29saW5nLi4uCi0gICAgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGwucnVuVHJhbnNmb3JtVGhyZWFkKHRoaXMpOwotICB9Ci0gIAotICAvKiBUaHJlYWQgbG9naWMgdG8gc3VwcG9ydCBzdGFydFBhcnNlVGhyZWFkKCkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1bigpCi0gIHsKLSAgICAvLyBHdWFyZCBhZ2FpbnN0IGRpcmVjdCBpbnZvY2F0aW9uIG9mIHN0YXJ0KCkuCi0gICAgaWYoZlhNTFJlYWRlcj09bnVsbCkgcmV0dXJuOwotCi0gICAgaWYoREVCVUcpU3lzdGVtLm91dC5wcmludGxuKCJJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIgcGFyc2UgdGhyZWFkIGxhdW5jaGVkIik7Ci0KLSAgICAvLyBJbml0aWFsbHkgYXNzdW1lIHdlJ2xsIHJ1biBzdWNjZXNzZnVsbHkuCi0gICAgT2JqZWN0IGFyZz1Cb29sZWFuLkZBTFNFOwotCi0gICAgLy8gRm9yIHRoZSBkdXJhdGlvbiBvZiB0aGlzIG9wZXJhdGlvbiwgYWxsIGNvcm91dGluZSBoYW5kc2hha2luZwotICAgIC8vIHdpbGwgb2NjdXIgaW4gdGhlIGNvX3lpZWxkIG1ldGhvZC4gVGhhdCdzIHRoZSBuaWNlIHRoaW5nIGFib3V0Ci0gICAgLy8gY29yb3V0aW5lczsgdGhleSBnaXZlIHVzIGEgd2F5IHRvIGhhbmQgb2ZmIGNvbnRyb2wgZnJvbSB0aGUKLSAgICAvLyBtaWRkbGUgb2YgYSBzeW5jaHJvbm91cyBtZXRob2QuCi0gICAgdHJ5Ci0gICAgewotICAgICAgZlhNTFJlYWRlci5wYXJzZShmWE1MUmVhZGVySW5wdXRTb3VyY2UpOwotICAgIH0KLSAgICBjYXRjaChJT0V4Y2VwdGlvbiBleCkKLSAgICB7Ci0gICAgICBhcmc9ZXg7Ci0gICAgfQotICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZXgpCi0gICAgewotICAgICAgRXhjZXB0aW9uIGlubmVyPWV4LmdldEV4Y2VwdGlvbigpOwotICAgICAgaWYoaW5uZXIgaW5zdGFuY2VvZiBTdG9wRXhjZXB0aW9uKXsKLSAgICAgICAgLy8gRXhwZWN0ZWQgYW5kIGhhcm1sZXNzCi0gICAgICAgIGlmKERFQlVHKVN5c3RlbS5vdXQucHJpbnRsbigiQWN0aXZlIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBub3JtYWwgc3RvcCBleGNlcHRpb24iKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgLy8gVW5leHBlY3RlZCBtYWxmdW5jdGlvbgotICAgICAgICBpZihERUJVRykKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQWN0aXZlIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBVTkVYUEVDVEVEIFNBWCBleGNlcHRpb246ICIraW5uZXIpOwotICAgICAgICAgIGlubmVyLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9ICAgICAgICAgICAgICAgIAotICAgICAgICBhcmc9ZXg7Ci0gICAgICB9Ci0gICAgfSAvLyBlbmQgcGFyc2UKLSAgICAKLSAgICAvLyBNYXJrIGFzIG5vIGxvbmdlciBydW5uaW5nIGluIHRocmVhZC4KLSAgICBmWE1MUmVhZGVyPW51bGw7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyBNYXJrIGFzIGRvbmUgYW5kIHlpZWxkIGNvbnRyb2wgdG8gdGhlIGNvbnRyb2xsZXIgY29yb3V0aW5lCi0gICAgICBmTm9Nb3JlRXZlbnRzPXRydWU7Ci0gICAgICBmQ29yb3V0aW5lTWFuYWdlci5jb19leGl0X3RvKGFyZywgZlNvdXJjZUNvcm91dGluZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQ29udHJvbGxlckNvcm91dGluZUlEKTsKLSAgICB9Ci0gICAgY2F0Y2goamF2YS5sYW5nLk5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIFNob3VsZG4ndCBoYXBwZW4gdW5sZXNzIHdlJ3ZlIG1pc2NvZGVkIG91ciBjb3JvdXRpbmUgbG9naWMKLSAgICAgIC8vICJDUE8sIHNodXQgZG93biB0aGUgZ2FyYmFnZSBzbWFzaGVycyBvbiB0aGUgZGV0ZW50aW9uIGxldmVsISIKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwotICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fZXhpdChmU291cmNlQ29yb3V0aW5lSUQpOwotICAgIH0KLSAgfQotCi0gIC8qKiBVc2VkIHRvIHF1aWNrbHkgdGVybWluYXRlIHBhcnNlIHdoZW4gcnVubmluZyB1bmRlciBhCi0gICAgICBzdGFydFBhcnNlKCkgdGhyZWFkLiBPbmx5IGl0cyB0eXBlIGlzIGltcG9ydGFudC4gKi8KLSAgY2xhc3MgU3RvcEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KLSAgewotICB9Ci0KLSAgLyoqIGRlbGl2ZXJNb3JlTm9kZXMoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIGNvcm91dGluZQotICAgKiBwYXJzZXIgdGhhdCB3ZSBuZWVkIG1vcmUgbm9kZXMuICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZAotICAgKiBmcm9tIG9uZSBvZiBvdXIgcGFydG5lciByb3V0aW5lcywgYW5kIHNlcnZlcyB0byBlbmNhcHN1bGF0ZSB0aGUKLSAgICogZGV0YWlscyBvZiBob3cgaW5jcmVtZW50YWwgcGFyc2luZyBoYXMgYmVlbiBhY2hpZXZlZC4KLSAgICoKLSAgICogQHBhcmFtIHBhcnNlbW9yZSBJZiB0cnVlLCB0ZWxscyB0aGUgaW5jcmVtZW50YWwgZmlsdGVyIHRvIGdlbmVyYXRlCi0gICAqIGFub3RoZXIgY2h1bmsgb2Ygb3V0cHV0LiBJZiBmYWxzZSwgdGVsbHMgdGhlIGZpbHRlciB0aGF0IHdlJ3JlCi0gICAqIHNhdGlzZmllZCBhbmQgaXQgY2FuIHRlcm1pbmF0ZSBwYXJzaW5nIG9mIHRoaXMgZG9jdW1lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gQm9vbGVhbi5UUlVFIGlmIHRoZXJlIG1heSBiZSBtb3JlIGV2ZW50cyBhdmFpbGFibGUgYnkgaW52b2tpbmcKLSAgICogZGVsaXZlck1vcmVOb2RlcygpIGFnYWluLiBCb29sZWFuLkZBTFNFIGlmIHBhcnNpbmcgaGFzIHJ1biB0byBjb21wbGV0aW9uIChvciBiZWVuCi0gICAqIHRlcm1pbmF0ZWQgYnkgZGVsaXZlck1vcmVOb2RlcyhmYWxzZSkuIE9yIGFuIGV4Y2VwdGlvbiBvYmplY3QgaWYgc29tZXRoaW5nCi0gICAqIG1hbGZ1bmN0aW9uZWQuICVSRVZJRVclIFdlIF9jb3VsZF8gYWN0dWFsbHkgdGhyb3cgdGhlIGV4Y2VwdGlvbiwgYnV0Ci0gICAqIHRoYXQgd291bGQgcmVxdWlyZSBydW5pbm5nIGRlbGl2ZXJNb3JlTm9kZXMoKSBpbiBhIHRyeS9jYXRjaC4uLiBhbmQgZm9yIG1hbnkKLSAgICogYXBwbGljYXRpb25zLCBleGNlcHRpb24gd2lsbCBiZSBzaW1wbHkgYmUgdHJlYXRlZCBhcyAibm90IFRSVUUiIGluCi0gICAqIGFueSBjYXNlLgotICAgKiAqLwotICBwdWJsaWMgT2JqZWN0IGRlbGl2ZXJNb3JlTm9kZXMoYm9vbGVhbiBwYXJzZW1vcmUpCi0gIHsKLSAgICAvLyBJZiBwYXJzaW5nIGlzIGFscmVhZHkgZG9uZSwgd2UgY2FuIGltbWVkaWF0ZWx5IHNheSBzbwotICAgIGlmKGZOb01vcmVFdmVudHMpCi0gICAgICByZXR1cm4gQm9vbGVhbi5GQUxTRTsKLQotICAgIHRyeSAKLSAgICB7Ci0gICAgICBPYmplY3QgcmVzdWx0ID0KLSAgICAgICAgZkNvcm91dGluZU1hbmFnZXIuY29fcmVzdW1lKHBhcnNlbW9yZT9Cb29sZWFuLlRSVUU6Qm9vbGVhbi5GQUxTRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDb250cm9sbGVyQ29yb3V0aW5lSUQsIGZTb3VyY2VDb3JvdXRpbmVJRCk7Ci0gICAgICBpZihyZXN1bHQ9PUJvb2xlYW4uRkFMU0UpCi0gICAgICAgIGZDb3JvdXRpbmVNYW5hZ2VyLmNvX2V4aXQoZkNvbnRyb2xsZXJDb3JvdXRpbmVJRCk7Ci0KLSAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotICAgICAgCi0gICAgLy8gU0hPVUxEIE5FVkVSIE9DQ1VSLCBzaW5jZSB0aGUgY29yb3V0aW5lIG51bWJlciBhbmQgY29yb3V0aW5lIG1hbmFnZXIKLSAgICAvLyBhcmUgdGhvc2UgcHJldmlvdXNseSBlc3RhYmxpc2hlZCBmb3IgdGhpcyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuLi4KLSAgICAvLyBTbyBJJ20ganVzdCBnb2luZyB0byByZXR1cm4gaXQgYXMgYSBwYXJzaW5nIGV4Y2VwdGlvbiwgZm9yIG5vdy4KLSAgICBjYXRjaChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGU7Ci0gICAgICB9Ci0gIH0KLSAgCi0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8qKiBTaW1wbGUgdW5pdCB0ZXN0LiBBdHRlbXB0IGNvcm91dGluZSBwYXJzaW5nIG9mIGRvY3VtZW50IGluZGljYXRlZAotICAgKiBieSBmaXJzdCBhcmd1bWVudCAoYXMgYSBVUkkpLCByZXBvcnQgcHJvZ3Jlc3MuCi0gICAqLwotICAgIC8qCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmdzW10pCi0gIHsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0aW5nLi4uIik7Ci0KLSAgICBvcmcueG1sLnNheC5YTUxSZWFkZXIgdGhlU0FYUGFyc2VyPQotICAgICAgbmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyKCk7Ci0gIAotCi0gICAgZm9yKGludCBhcmc9MDthcmc8YXJncy5sZW5ndGg7KythcmcpCi0gICAgewotICAgICAgLy8gVGhlIGZpbHRlciBpcyBub3QgY3VycmVudGx5IGRlc2lnbmVkIHRvIGJlIHJlc3RhcnRhYmxlCi0gICAgICAvLyBhZnRlciBhIHBhcnNlIGhhcyBlbmRlZC4gR2VuZXJhdGUgYSBuZXcgb25lIGVhY2ggdGltZS4KLSAgICAgIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlciBmaWx0ZXI9Ci0gICAgICAgIG5ldyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIoKTsKLSAgICAgIC8vIFVzZSBhIHNlcmlhbGl6ZXIgYXMgb3VyIHNhbXBsZSBvdXRwdXQKLSAgICAgIG9yZy5hcGFjaGUueG1sLnNlcmlhbGl6ZS5YTUxTZXJpYWxpemVyIHRyYWNlOwotICAgICAgdHJhY2U9bmV3IG9yZy5hcGFjaGUueG1sLnNlcmlhbGl6ZS5YTUxTZXJpYWxpemVyKFN5c3RlbS5vdXQsbnVsbCk7Ci0gICAgICBmaWx0ZXIuc2V0Q29udGVudEhhbmRsZXIodHJhY2UpOwotICAgICAgZmlsdGVyLnNldExleGljYWxIYW5kbGVyKHRyYWNlKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShhcmdzW2FyZ10pOwotICAgICAgICBPYmplY3QgcmVzdWx0PW51bGw7Ci0gICAgICAgIGJvb2xlYW4gbW9yZT10cnVlOwotCi0gICAgICAgIC8vIGluaXQgbm90IGlzc3VlZDsgd2UgX3Nob3VsZF8gYXV0b21hZ2ljYWxseSBEbyBUaGUgUmlnaHQgVGhpbmcKLQotICAgICAgICAvLyBCaW5kIHBhcnNlciwga2ljayBvZmYgcGFyc2luZyBpbiBhIHRocmVhZAotICAgICAgICBmaWx0ZXIuc2V0WE1MUmVhZGVyKHRoZVNBWFBhcnNlcik7Ci0gICAgICAgIGZpbHRlci5zdGFydFBhcnNlKHNvdXJjZSk7Ci0gICAgICAKLSAgICAgICAgZm9yKHJlc3VsdCA9IGZpbHRlci5kZWxpdmVyTW9yZU5vZGVzKG1vcmUpOwotICAgICAgICAgICAgKHJlc3VsdCBpbnN0YW5jZW9mIEJvb2xlYW4gJiYgKChCb29sZWFuKXJlc3VsdCk9PUJvb2xlYW4uVFJVRSk7Ci0gICAgICAgICAgICByZXN1bHQgPSBmaWx0ZXIuZGVsaXZlck1vcmVOb2Rlcyhtb3JlKSkKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5Tb21lIHBhcnNpbmcgc3VjY2Vzc2Z1bCwgdHJ5aW5nIG1vcmUuXG4iKTsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBTcGVjaWFsIHRlc3Q6IFRlcm1pbmF0ZSBwYXJzaW5nIGVhcmx5LgotICAgICAgICAgIGlmKGFyZysxPGFyZ3MubGVuZ3RoICYmICIhIi5lcXVhbHMoYXJnc1thcmcrMV0pKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICsrYXJnOwotICAgICAgICAgICAgbW9yZT1mYWxzZTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgCi0gICAgICAgIH0KLSAgICAgIAotICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgQm9vbGVhbiAmJiAoKEJvb2xlYW4pcmVzdWx0KT09Qm9vbGVhbi5GQUxTRSkKLSAgICAgICAgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5GaWx0ZXIgZW5kZWQgKEVPRiBvciBvbiByZXF1ZXN0KS5cbiIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHJlc3VsdCA9PSBudWxsKSB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblVORVhQRUNURUQ6IEZpbHRlciBzYXlzIHNodXQgZG93biBwcmVtYXR1cmVseS5cbiIpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEV4Y2VwdGlvbikgewotICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5GaWx0ZXIgdGhyZXcgZXhjZXB0aW9uOiIpOwotICAgICAgICAgICgoRXhjZXB0aW9uKXJlc3VsdCkucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICAgIH0KLSAgICAgIAotICAgICAgfQotICAgICAgY2F0Y2goU0FYRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0gICAgfSAvLyBlbmQgZm9yCi0gIH0KLSAgICAqLyAgCi19IC8vIGNsYXNzIEluY3JlbWVudGFsU0FYU291cmNlX0ZpbHRlcgpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmY2MTk1ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9JbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTksMjAwMCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYZXJjZXMiIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBJbnRlcm5hdGlvbmFsCi0gKiBCdXNpbmVzcyBNYWNoaW5lcywgSW5jLiwgaHR0cDovL3d3dy5hcGFjaGUub3JnLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi0KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuU0FYUGFyc2VyOwotaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotCi0vKiogPHA+SW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIHRha2VzIGFkdmFudGFnZSBvZiB0aGUgZmFjdCB0aGF0IFhlcmNlcwotICogaW5jcmVtZW50YWwgbW9kZSBpcyBhbHJlYWR5IGEgY29yb3V0aW5lIG9mIHNvcnRzLCBhbmQganVzdCB3cmFwcyBvdXIKLSAqIEluY3JlbWVudGFsU0FYU291cmNlIEFQSSBhcm91bmQgaXQuPC9wPgotICoKLSAqIDxwPlVzYWdlIGV4YW1wbGU6IFNlZSBtYWluKCkuPC9wPgotICoKLSAqIDxwPlN0YXR1czogUGFzc2VzIHNpbXBsZSBtYWluKCkgdW5pdC10ZXN0LiBORUVEUyBKQVZBRE9DLjwvcD4KLSAqICovCi1wdWJsaWMgY2xhc3MgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzCi0gIGltcGxlbWVudHMgSW5jcmVtZW50YWxTQVhTb3VyY2UKLXsKLSAgU0FYUGFyc2VyIGZJbmNyZW1lbnRhbFBhcnNlcjsKLQotICAvLwotICAvLyBEYXRhCi0gIC8vCi0KLSAgcHJpdmF0ZSBib29sZWFuIGZQYXJzZUluUHJvZ3Jlc3M9ZmFsc2U7Ci0KLSAgLy8KLSAgLy8gQ29uc3RydWN0b3JzCi0gIC8vCi0KLSAgLyoqIENyZWF0ZSBhIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcywgYW5kIGNyZWF0ZSBhIFNBWFBhcnNyZQotICAgKiB0byBnbyB3aXRoIGl0Ci0gICAqICovCi0gIHB1YmxpYyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMoKSB7Ci0gICAgZkluY3JlbWVudGFsUGFyc2VyPW5ldyBTQVhQYXJzZXIoKTsKLSAgfQotCi0gIC8qKiBDcmVhdGUgYSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMgd3JhcHBlZCBhcm91bmQKLSAgICogYW4gZXhpc3RpbmcgU0FYUGFyc2VyCi0gICAqICovCi0gIHB1YmxpYyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMoU0FYUGFyc2VyIHBhcnNlcikgewotICAgIGZJbmNyZW1lbnRhbFBhcnNlcj1wYXJzZXI7Ci0gIH0KLQotICAvLwotICAvLyBGYWN0b3JpZXMKLSAgLy8KLSAgc3RhdGljIHB1YmxpYyBJbmNyZW1lbnRhbFNBWFNvdXJjZSBjcmVhdGVJbmNyZW1lbnRhbFNBWFNvdXJjZSgpIHsKLSAgICByZXR1cm4gbmV3IEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcygpOwotICB9Ci0gIHN0YXRpYyBwdWJsaWMgSW5jcmVtZW50YWxTQVhTb3VyY2UKLSAgY3JlYXRlSW5jcmVtZW50YWxTQVhTb3VyY2UoU0FYUGFyc2VyIHBhcnNlcikgewotICAgIHJldHVybiBuZXcgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzKHBhcnNlcik7Ci0gIH0KLQotICAvLwotICAvLyBQdWJsaWMgbWV0aG9kcwotICAvLwotCi0gIC8vIFJlZ2lzdGVyIGhhbmRsZXIgZGlyZWN0bHkgd2l0aCB0aGUgaW5jcmVtZW50YWwgcGFyc2VyCi0gIHB1YmxpYyB2b2lkIHNldENvbnRlbnRIYW5kbGVyKG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGhhbmRsZXIpCi0gIHsKLSAgICBmSW5jcmVtZW50YWxQYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoaGFuZGxlcik7Ci0gIH0KLQotICAvLyBOb3RlIG5hbWUsIG5lZWRlZCB0byBkb2RnZSB0aGUgaW5oZXJpdGVkIFhlcmNlcyBzZXRMZXhpY2FsSGFuZGxlcgotICAvLyB3aGljaCBpc24ndCBwdWJsaWMuCi0gIHB1YmxpYyB2b2lkIHNldExleGljYWxIYW5kbGVyKG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBoYW5kbGVyKQotICB7Ci0gICAgLy8gTm90IHN1cHBvcnRlZCBieSBhbGwgU0FYMiBwYXJzZXJzIGJ1dCBzaG91bGQgd29yayBpbiBYZXJjZXM6Ci0gICAgdHJ5IAotICAgIHsKLSAgICAgIGZJbmNyZW1lbnRhbFBhcnNlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyKTsKLSAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIE5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0Ci0gICAgfQotICAgIGNhdGNoKG9yZy54bWwuc2F4LlNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIC8vIE5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0Ci0gICAgfQotICB9Ci0gIAotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLyoqIHN0YXJ0UGFyc2UoKSBpcyBhIHNpbXBsZSBBUEkgd2hpY2ggdGVsbHMgdGhlIEluY3JlbWVudGFsU0FYU291cmNlCi0gICAqIHRvIGJlZ2luIHJlYWRpbmcgYSBkb2N1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gaXMgcGFyc2UgdGhyZWFkIGlzIGFscmVhZHkgaW4gcHJvZ3Jlc3MKLSAgICogb3IgcGFyc2luZyBjYW4gbm90IGJlIHN0YXJ0ZWQuCi0gICAqICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0UGFyc2UoSW5wdXRTb3VyY2Ugc291cmNlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoZkluY3JlbWVudGFsUGFyc2VyPT1udWxsKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9TVEFSVFBBUlNFX05FRURTX1NBWFBBUlNFUiwgbnVsbCkpOyAvLyJzdGFydFBhcnNlIG5lZWRzIGEgbm9uLW51bGwgU0FYUGFyc2VyLiIpOwotICAgIGlmIChmUGFyc2VJblByb2dyZXNzKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9TVEFSVFBBUlNFX1dISUxFX1BBUlNJTkcsIG51bGwpKTsgLy8ic3RhcnRQYXJzZSBtYXkgbm90IGJlIGNhbGxlZCB3aGlsZSBwYXJzaW5nLiIpOwotCi0gICAgYm9vbGVhbiBvaz1mYWxzZTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIG9rID0gZkluY3JlbWVudGFsUGFyc2VyLnBhcnNlU29tZVNldHVwKHNvdXJjZSk7Ci0gICAgfQotICAgIGNhdGNoKEV4Y2VwdGlvbiBleCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgU0FYRXhjZXB0aW9uKGV4KTsKLSAgICB9Ci0gICAgCi0gICAgaWYoIW9rKQotICAgICAgdGhyb3cgbmV3IFNBWEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DT1VMRF9OT1RfSU5JVF9QQVJTRVIsIG51bGwpKTsgLy8iY291bGQgbm90IGluaXRpYWxpemUgcGFyc2VyIHdpdGgiKTsKLSAgfQotCi0gIAotICAvKiogZGVsaXZlck1vcmVOb2RlcygpIGlzIGEgc2ltcGxlIEFQSSB3aGljaCB0ZWxscyB0aGUgY29yb3V0aW5lCi0gICAqIHBhcnNlciB0aGF0IHdlIG5lZWQgbW9yZSBub2Rlcy4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkCi0gICAqIGZyb20gb25lIG9mIG91ciBwYXJ0bmVyIHJvdXRpbmVzLCBhbmQgc2VydmVzIHRvIGVuY2Fwc3VsYXRlIHRoZQotICAgKiBkZXRhaWxzIG9mIGhvdyBpbmNyZW1lbnRhbCBwYXJzaW5nIGhhcyBiZWVuIGFjaGlldmVkLgotICAgKgotICAgKiBAcGFyYW0gcGFyc2Vtb3JlIElmIHRydWUsIHRlbGxzIHRoZSBpbmNyZW1lbnRhbCBwYXJzZXIgdG8gZ2VuZXJhdGUKLSAgICogYW5vdGhlciBjaHVuayBvZiBvdXRwdXQuIElmIGZhbHNlLCB0ZWxscyB0aGUgcGFyc2VyIHRoYXQgd2UncmUKLSAgICogc2F0aXNmaWVkIGFuZCBpdCBjYW4gdGVybWluYXRlIHBhcnNpbmcgb2YgdGhpcyBkb2N1bWVudC4KLSAgICogQHJldHVybiBCb29sZWFuLlRSVUUgaWYgdGhlIENvcm91dGluZVBhcnNlciBiZWxpZXZlcyBtb3JlIGRhdGEgbWF5IGJlIGF2YWlsYWJsZQotICAgKiBmb3IgZnVydGhlciBwYXJzaW5nLiBCb29sZWFuLkZBTFNFIGlmIHBhcnNpbmcgcmFuIHRvIGNvbXBsZXRpb24uCi0gICAqIEV4Y2VwdGlvbiBpZiB0aGUgcGFyc2VyIG9iamVjdGVkIGZvciBzb21lIHJlYXNvbi4KLSAgICogKi8KLSAgcHVibGljIE9iamVjdCBkZWxpdmVyTW9yZU5vZGVzIChib29sZWFuIHBhcnNlbW9yZSkKLSAgewotICAgIGlmKCFwYXJzZW1vcmUpCi0gICAgewotICAgICAgZlBhcnNlSW5Qcm9ncmVzcz1mYWxzZTsKLSAgICAgIHJldHVybiBCb29sZWFuLkZBTFNFOwotICAgIH0KLQotICAgIE9iamVjdCBhcmc7Ci0gICAgdHJ5IHsKLSAgICAgIGJvb2xlYW4ga2VlcGdvaW5nID0gZkluY3JlbWVudGFsUGFyc2VyLnBhcnNlU29tZSgpOwotICAgICAgYXJnID0ga2VlcGdvaW5nID8gQm9vbGVhbi5UUlVFIDogQm9vbGVhbi5GQUxTRTsKLSAgICB9IGNhdGNoIChTQVhFeGNlcHRpb24gZXgpIHsKLSAgICAgIGFyZyA9IGV4OwotICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7Ci0gICAgICBhcmcgPSBleDsKLSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKLSAgICAgIGFyZyA9IG5ldyBTQVhFeGNlcHRpb24oZXgpOwotICAgIH0KLSAgICByZXR1cm4gYXJnOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8qKiBTaW1wbGUgdW5pdCB0ZXN0LiBBdHRlbXB0IGNvcm91dGluZSBwYXJzaW5nIG9mIGRvY3VtZW50IGluZGljYXRlZAotICAgKiBieSBmaXJzdCBhcmd1bWVudCAoYXMgYSBVUkkpLCByZXBvcnQgcHJvZ3Jlc3MuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJnc1tdKQotICB7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGFydGluZy4uLiIpOwotCi0gICAgQ29yb3V0aW5lTWFuYWdlciBjbyA9IG5ldyBDb3JvdXRpbmVNYW5hZ2VyKCk7Ci0gICAgaW50IGFwcENvcm91dGluZUlEID0gY28uY29fam9pbkNvcm91dGluZVNldCgtMSk7Ci0gICAgaWYgKGFwcENvcm91dGluZUlEID09IC0xKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRVJST1I6IENvdWxkbid0IGFsbG9jYXRlIGNvcm91dGluZSBudW1iZXIuXG4iKTsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gICAgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIHBhcnNlcj0KLSAgICAgIG5ldyBJbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMoKTsKLQotICAgIC8vIFVzZSBhIHNlcmlhbGl6ZXIgYXMgb3VyIHNhbXBsZSBvdXRwdXQKLSAgICBvcmcuYXBhY2hlLnhtbC5zZXJpYWxpemUuWE1MU2VyaWFsaXplciB0cmFjZTsKLSAgICB0cmFjZT1uZXcgb3JnLmFwYWNoZS54bWwuc2VyaWFsaXplLlhNTFNlcmlhbGl6ZXIoU3lzdGVtLm91dCxudWxsKTsKLSAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIodHJhY2UpOwotICAgIHBhcnNlci5zZXRMZXhpY2FsSGFuZGxlcih0cmFjZSk7Ci0KLSAgICAvLyBUZWxsIGNvcm91dGluZSB0byBiZWdpbiBwYXJzaW5nLCBydW4gd2hpbGUgcGFyc2luZyBpcyBpbiBwcm9ncmVzcwotCi0gICAgZm9yKGludCBhcmc9MDthcmc8YXJncy5sZW5ndGg7KythcmcpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIElucHV0U291cmNlIHNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShhcmdzW2FyZ10pOwotICAgICAgICBPYmplY3QgcmVzdWx0PW51bGw7Ci0gICAgICAgIGJvb2xlYW4gbW9yZT10cnVlOwotICAgICAgICBwYXJzZXIuc3RhcnRQYXJzZShzb3VyY2UpOwotICAgICAgICBmb3IocmVzdWx0ID0gcGFyc2VyLmRlbGl2ZXJNb3JlTm9kZXMobW9yZSk7Ci0gICAgICAgICAgICByZXN1bHQ9PUJvb2xlYW4uVFJVRTsKLSAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlci5kZWxpdmVyTW9yZU5vZGVzKG1vcmUpKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblNvbWUgcGFyc2luZyBzdWNjZXNzZnVsLCB0cnlpbmcgbW9yZS5cbiIpOwotICAgICAgICAgICAgCi0gICAgICAgICAgLy8gU3BlY2lhbCB0ZXN0OiBUZXJtaW5hdGUgcGFyc2luZyBlYXJseS4KLSAgICAgICAgICBpZihhcmcrMTxhcmdzLmxlbmd0aCAmJiAiISIuZXF1YWxzKGFyZ3NbYXJnKzFdKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICArK2FyZzsKLSAgICAgICAgICAgIG1vcmU9ZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICAgICAgCi0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBCb29sZWFuICYmICgoQm9vbGVhbilyZXN1bHQpPT1Cb29sZWFuLkZBTFNFKQotICAgICAgICB7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblBhcnNlciBlbmRlZCAoRU9GIG9yIG9uIHJlcXVlc3QpLlxuIik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocmVzdWx0ID09IG51bGwpIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuVU5FWFBFQ1RFRDogUGFyc2VyIHNheXMgc2h1dCBkb3duIHByZW1hdHVyZWx5LlxuIik7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXhjZXB0aW9uKSB7Ci0gICAgICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKChFeGNlcHRpb24pcmVzdWx0KTsKLSAgICAgICAgICAvLyAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuUGFyc2VyIHRocmV3IGV4Y2VwdGlvbjoiKTsKLSAgICAgICAgICAvLyAgICAgICAgICAoKEV4Y2VwdGlvbilyZXN1bHQpLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgfQotCi0gICAgICBjYXRjaChTQVhFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgCi0gIH0KLQotICAKLX0gLy8gY2xhc3MgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Ob2RlTG9jYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvTm9kZUxvY2F0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzQ0YzkwNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9Ob2RlTG9jYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IE92aWRpdQotICogUHJlZGVzY3UgPG92aWRpdUBjdXAuaHAuY29tPiBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZQotICogRm91bmRhdGlvbiBhbmQgd2FzIG9yaWdpbmFsbHkgZGV2ZWxvcGVkIGF0IEhld2xldHQgUGFja2FyZCBDb21wYW55LgotICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotCi0vKioKLSAqIDxjb2RlPk5vZGVMb2NhdG9yPC9jb2RlPiBtYWludGFpbnMgaW5mb3JtYXRpb24gb24gYW4gWE1MIHNvdXJjZQotICogbm9kZS4KLSAqCi0gKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpvdmlkaXVAY3VwLmhwLmNvbSI+T3ZpZGl1IFByZWRlc2N1PC9hPgotICogQHNpbmNlIE1heSAyMywgMjAwMQotICovCi1wdWJsaWMgY2xhc3MgTm9kZUxvY2F0b3IgaW1wbGVtZW50cyBTb3VyY2VMb2NhdG9yCi17Ci0gIHByb3RlY3RlZCBTdHJpbmcgbV9wdWJsaWNJZDsKLSAgcHJvdGVjdGVkIFN0cmluZyBtX3N5c3RlbUlkOwotICBwcm90ZWN0ZWQgaW50IG1fbGluZU51bWJlcjsKLSAgcHJvdGVjdGVkIGludCBtX2NvbHVtbk51bWJlcjsKLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ob2RlTG9jYXRvcjwvY29kZT4gaW5zdGFuY2UuCi0gICAqCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHN5c3RlbUlkIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKiBAcGFyYW0gbGluZU51bWJlciBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqIEBwYXJhbSBjb2x1bW5OdW1iZXIgYW4gPGNvZGU+aW50PC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIE5vZGVMb2NhdG9yKFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkLAotICAgICAgICAgICAgICAgICAgICAgaW50IGxpbmVOdW1iZXIsIGludCBjb2x1bW5OdW1iZXIpCi0gIHsKLSAgICB0aGlzLm1fcHVibGljSWQgPSBwdWJsaWNJZDsKLSAgICB0aGlzLm1fc3lzdGVtSWQgPSBzeXN0ZW1JZDsKLSAgICB0aGlzLm1fbGluZU51bWJlciA9IGxpbmVOdW1iZXI7Ci0gICAgdGhpcy5tX2NvbHVtbk51bWJlciA9IGNvbHVtbk51bWJlcjsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5nZXRQdWJsaWNJZDwvY29kZT4gcmV0dXJucyB0aGUgcHVibGljIElEIG9mIHRoZSBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpCi0gIHsKLSAgICByZXR1cm4gbV9wdWJsaWNJZDsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5nZXRTeXN0ZW1JZDwvY29kZT4gcmV0dXJucyB0aGUgc3lzdGVtIElEIG9mIHRoZSBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTeXN0ZW1JZCgpCi0gIHsKLSAgICByZXR1cm4gbV9zeXN0ZW1JZDsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5nZXRMaW5lTnVtYmVyPC9jb2RlPiByZXR1cm5zIHRoZSBsaW5lIG51bWJlciBvZiB0aGUgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fbGluZU51bWJlcjsKLSAgfQotCi0gIC8qKgotICAgKiA8Y29kZT5nZXRDb2x1bW5OdW1iZXI8L2NvZGU+IHJldHVybnMgdGhlIGNvbHVtbiBudW1iZXIgb2YgdGhlCi0gICAqIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gYW4gPGNvZGU+aW50PC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fY29sdW1uTnVtYmVyOwotICB9Ci0KLSAgLyoqCi0gICAqIDxjb2RlPnRvU3RyaW5nPC9jb2RlPiByZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMKLSAgICogTm9kZUxvY2F0b3IgaW5zdGFuY2UuCi0gICAqCi0gICAqIEByZXR1cm4gYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHZhbHVlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiZmlsZSAnIiArIG1fc3lzdGVtSWQKLSAgICAgICsgIicsIGxpbmUgIyIgKyBtX2xpbmVOdW1iZXIKLSAgICAgICsgIiwgY29sdW1uICMiICsgbV9jb2x1bW5OdW1iZXI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL1Rlc3REVE0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL1Rlc3REVE0uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2RkNDhjNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9UZXN0RFRNLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTYgKzAsMCBAQAotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Eb2N1bWVudEltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5UZXN0RFRNTm9kZXM7Ci1pbXBvcnQgb3JnLnhtbC5zYXguaGVscGVycy5BdHRyaWJ1dGVzSW1wbDsKLQotLyoqCi0gKiBUZXN0cyB0aGUgRFRNIGJ5IGNyZWF0aW5nCi0gKgotICogUkVXUklUVEVOIHRvIHVzZSBTQVgyIENvbnRlbnRIYW5kbGVyIEFQSXMgLS0gb3JpZ2luYWwgZHJhZnQgdXNlZAotICogYW4gaW5jb21wbGV0ZS9pbmNvcnJlY3QgdmVyc2lvbiBvZiBTQVgxIERvY3VtZW50SGFuZGxlciwgd2hpY2ggaXMKLSAqIGJlaW5nIHBoYXNlZCBvdXQgYXMgcXVpY2tseSBhcyB3ZSBjYW4gcG9zc2libHkgbWFuYWdlIGl0LgotICoKLSAqICVUQkQlIEkgX3RoaW5rXyB0aGUgU0FYIGNvbnZlbnRpb24gaXMgdGhhdCAibm8gbmFtZXNwYWNlIiBpcyBleHByZXNzZWQKLSAqIGFzICIiIHJhdGhlciB0aGFuIGFzIG51bGwgKHdoaWNoIGlzIHRoZSBET00ncyBjb252ZW50aW9uKS4gV2hhdCBzaG91bGQgCi0gKiBEVE0gZXhwZWN0PyBXaGF0IHNob3VsZCBpdCBkbyB3aXRoIHRoZSBvdGhlcj8KLSAqLwotcHVibGljIGNsYXNzIFRlc3REVE0gewotCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHsKLSAgICBTdHJpbmcgdGV4dDsKLQotICAgIC8qICA8P3htbCB2ZXJzaW9uPSIxLjAiPz4KLSAgICAgKiAgPHRvcD4KLSAgICAgKiAgIDxBPgotICAgICAqICAgIDxCIGhhdD0ibmV3IiBjYXI9IkhvbmRhIiBkb2c9IkJveGVyIj5MaWZlIGlzIGdvb2Q8L0I+Ci0gICAgICogICA8L0E+Ci0gICAgICogICA8Qz5NeSBBbmFjb25kYTxELz5Xb3JkczwvQz4KLSAgICAgKiAgPC90b3A+ICovCi0KLSAgICBEVE1Eb2N1bWVudEltcGwgZG9jID0gbmV3IERUTURvY3VtZW50SW1wbChudWxsLCAwLCBudWxsLCAKLSAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhNTFN0cmluZ0ZhY3RvcnlJbXBsLmdldEZhY3RvcnkoKSk7Ci0KLSAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZG9jLnN0YXJ0RG9jdW1lbnQoKTsKLQotICAgICAgICBkb2Muc3RhcnRFbGVtZW50KCIiLCAidG9wIiwgInRvcCIsIG51bGwpOwotCi0gICAgICAgIGRvYy5zdGFydEVsZW1lbnQoIiIsICJBIiwgIkEiLCBudWxsKTsKLQotICAgICAgICBBdHRyaWJ1dGVzSW1wbCBhdHRzID0gbmV3IEF0dHJpYnV0ZXNJbXBsKCk7Ci0gICAgICAgIGF0dHMuYWRkQXR0cmlidXRlKCIiLCAiIiwgImhhdCIsICJDREFUQSIsICJuZXciKTsKLSAgICAgICAgYXR0cy5hZGRBdHRyaWJ1dGUoIiIsICIiLCAiY2FyIiwgIkNEQVRBIiwgIkhvbmRhIik7Ci0gICAgICAgIGF0dHMuYWRkQXR0cmlidXRlKCIiLCAiIiwgImRvZyIsICJDREFUQSIsICJCb3hlciIpOwotICAgICAgICBkb2Muc3RhcnRFbGVtZW50KCIiLCJCIiwiQiIsIGF0dHMpOwotICAgICAgICB0ZXh0PSJMaWZlIGlzIGdvb2QiOwotICAgICAgICBkb2MuY2hhcmFjdGVycyh0ZXh0LnRvQ2hhckFycmF5KCksMCx0ZXh0Lmxlbmd0aCgpKTsKLSAgICAgICAgZG9jLmVuZEVsZW1lbnQoIiIsIkIiLCJCIik7Ci0KLSAgICAgICAgZG9jLmVuZEVsZW1lbnQoIiIsIkEiLCJBIik7Ci0gICAgICAgIGRvYy5zdGFydEVsZW1lbnQoIiIsIkMiLCJDIiwgbnVsbCk7Ci0KLSAgICAgICAgdGV4dD0iTXkgQW5hY29uZGEiOwotICAgICAgICBkb2MuY2hhcmFjdGVycyh0ZXh0LnRvQ2hhckFycmF5KCksMCx0ZXh0Lmxlbmd0aCgpKTsKLSAgICAgICAgZG9jLnN0YXJ0RWxlbWVudCgiIiwiRCIsIkQiLG51bGwpOwotICAgICAgICBkb2MuZW5kRWxlbWVudCgiIiwiRCIsIkQiKTsKLSAgICAgICAgdGV4dD0iV29yZHMiOwotICAgICAgICBkb2MuY2hhcmFjdGVycyh0ZXh0LnRvQ2hhckFycmF5KCksMCx0ZXh0Lmxlbmd0aCgpKTsKLQotICAgICAgICBkb2MuZW5kRWxlbWVudCgiIiwgIkMiLCAiQyIpOwotCi0gICAgICAgIGJvb2xlYW4gQlVJTERQVVJDSEFTRU9SREVSPWZhbHNlOwotICAgICAgICBpZihCVUlMRFBVUkNIQVNFT1JERVIpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IHJvb3QsIGgsIGMxLCBjMiwgYzMsIGM0LCBjMV90ZXh0LCBjMl90ZXh0LCBjM190ZXh0LCBjNF90ZXh0OwotCi0gICAgICAgICAgICBkb2Muc3RhcnRFbGVtZW50KG51bGwsIlB1cmNoYXNlT3JkZXJMaXN0IiwiUHVyY2hhc2VPcmRlckxpc3QiLCBudWxsKTsKLQotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7Ci0KLSAgICAgICAgICAgICAgZG9jLnN0YXJ0RWxlbWVudCgiIiwiUHVyY2hhc2VPcmRlciIsIlB1cmNoYXNlT3JkZXIiLCBudWxsKTsKLQotICAgICAgICAgICAgICBkb2Muc3RhcnRFbGVtZW50KCIiLCJJdGVtIiwiSXRlbSIsIG51bGwpOwotICAgICAgICAgICAgICB0ZXh0PSJCYXNrZXRiYWxsIiArICIgLSAiICsgaTsKLSAgICAgICAgICAgICAgZG9jLmNoYXJhY3RlcnModGV4dC50b0NoYXJBcnJheSgpLDAsdGV4dC5sZW5ndGgoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIGRvYy5lbmRFbGVtZW50KCIiLCAiSXRlbSIsICJJdGVtIik7Ci0KLSAgICAgICAgICAgICAgZG9jLnN0YXJ0RWxlbWVudCgiIiwiRGVzY3JpcHRpb24iLCJEZXNjcmlwdGlvbiIsIG51bGwpOwotICAgICAgICAgICAgICAvLyBjMi5jcmVhdGVBdHRyaWJ1dGUoKTsKLSAgICAgICAgICAgICAgdGV4dD0iUHJvZmVzc2lvbmFsIExlYXRoZXIgTWljaGFlbCBKb3JkYW4gU2lnbmF0dXJlZCBCYXNrZXRiYWxsIjsKLSAgICAgICAgICAgICAgZG9jLmNoYXJhY3RlcnModGV4dC50b0NoYXJBcnJheSgpLDAsdGV4dC5sZW5ndGgoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIGRvYy5lbmRFbGVtZW50KCIiLCAiRGVzY3JpcHRpb24iLCAiRGVzY3JpcHRpb24iKTsKLQotICAgICAgICAgICAgICBkb2Muc3RhcnRFbGVtZW50KCIiLCJVbml0UHJpY2UiLCJVbml0UHJpY2UiLCBudWxsKTsKLSAgICAgICAgICAgICAgdGV4dD0iJDEyLjk5IjsKLSAgICAgICAgICAgICAgZG9jLmNoYXJhY3RlcnModGV4dC50b0NoYXJBcnJheSgpLDAsdGV4dC5sZW5ndGgoKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIGRvYy5lbmRFbGVtZW50KCIiLCAiVW5pdFByaWNlIiwgIlVuaXRQcmljZSIpOwotCi0gICAgICAgICAgICAgIGRvYy5zdGFydEVsZW1lbnQoIiIsIlF1YW50aXR5IiwiUXVhbnRpdHkiLCBudWxsKTsKLSAgICAgICAgICAgICAgdGV4dD0iNTAiOwotICAgICAgICAgICAgICBkb2MuY2hhcmFjdGVycyh0ZXh0LnRvQ2hhckFycmF5KCksMCx0ZXh0Lmxlbmd0aCgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgZG9jLmVuZEVsZW1lbnQoIiIsICJRdWFudGl0eSIsICJRdWFudGl0eSIpOwotCi0gICAgICAgICAgICAgIGRvYy5lbmRFbGVtZW50KCIiLCAiUHVyY2hhc2VPcmRlciIsICJQdXJjaGFzZU9yZGVyIik7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGRvYy5lbmRFbGVtZW50KCIiLCAiUHVyY2hhc2VPcmRlckxpc3QiLCAiUHVyY2hhc2VPcmRlckxpc3QiKTsKLSAgICAgICAgICB9IC8vIGlmKEJVSUxEUFVSQ0hBU0VPUkRFUikKLQotICAgICAgICBkb2MuZW5kRWxlbWVudCgiIiwgInRvcCIsICJ0b3AiKTsKLSAgICAgICAgZG9jLmVuZERvY3VtZW50KCk7Ci0gICAgICB9Ci0gICAgY2F0Y2gob3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB9Ci0gICAgICAgICAgICAgICAgCi0KLSAgICBUZXN0RFRNTm9kZXMucHJpbnROb2RlVGFibGUoZG9jKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvVGVzdERUTU5vZGVzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9UZXN0RFRNTm9kZXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTg0OTM5Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9UZXN0RFRNTm9kZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwuZHRtLnJlZjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuQ2h1bmtlZEludEFycmF5OwotCi0vKiogRGVidWdnaW5nIGR1bXAgcm91dGluZSBmb3IgRFRNRG9jdW1lbnRJbXBsLiBOb3RlIHRoYXQgaXQgZGlyZWN0bHkgYWNjZXNzZXMKLSAqIHRoYXQgY2xhc3MncyBpbnRlcm5hbCBkYXRhLi4uIHdoaWNoIHByb2JhYmx5IHNob3VsZG4ndCBiZSBleHBvc2VkLgotICovCi1wdWJsaWMgY2xhc3MgVGVzdERUTU5vZGVzIHsKLQotICBwdWJsaWMgc3RhdGljIHZvaWQgcHJpbnROb2RlVGFibGUoRFRNRG9jdW1lbnRJbXBsIGRvYykgewotICAgIGludCBsZW5ndGggPSBkb2Mubm9kZXMuc2xvdHNVc2VkKCksIHNsb3RbXSA9IG5ldyBpbnRbNF07Ci0gICAgZm9yIChpbnQgaT0wOyBpIDw9IGxlbmd0aDsgaSsrKSB7Ci0gICAgICBkb2Mubm9kZXMucmVhZFNsb3QoaSwgc2xvdCk7Ci0KLSAgICAgIC8vIFdvcmQwIGlzIHNob3duIGFzIGl0cyB0d28gaGFsZndvcmRzCi0gICAgICBzaG9ydCBoaWdoID0gKHNob3J0KSAoc2xvdFswXSA+PiAxNik7Ci0gICAgICBzaG9ydCBsb3cgPSAoc2hvcnQpIChzbG90WzBdICYgMHhGRkZGKTsKLQotICAgICAgU3lzdGVtLm91dC5wcmludGxuKGkgKyAiOiAoIiArIGhpZ2ggKyAiKSAoIiArIGxvdyArCi0gICAgICAgICAgICAgICAgICAgICAgICAgIikgIiArIHNsb3RbMV0gKyAiICIgKyBzbG90WzJdICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAiICIgK3Nsb3RbM10gKwotICAgICAgICAgICAgICAgICAgICAgICAgICJcblx0TmFtZTogIiArICBkb2MuZ2V0Tm9kZU5hbWUoaSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICIgVmFsdWU6ICIgKyBkb2MuZ2V0Tm9kZVZhbHVlKGkpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAiIFBhcmVudDogIiArIGRvYy5nZXRQYXJlbnQoaSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICIgRmlyc3RBdHRyOiAiICsgZG9jLmdldEZpcnN0QXR0cmlidXRlKGkpICsKLSAgICAgICAgICAgICAgICAgICAgICAgICAiIEZpcnN0Q2hpbGQ6ICIgKyBkb2MuZ2V0Rmlyc3RDaGlsZChpKSArCi0gICAgICAgICAgICAgICAgICAgICAgICAgIiBOZXh0U2liOiAiICsgZG9jLmdldE5leHRTaWJsaW5nKGkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgKTsgCi0gICAgfQotCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL2RvbTJkdG0vRE9NMkRUTS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvZG9tMmR0bS9ET00yRFRNLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzZjM0NzEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvZG9tMmR0bS9ET00yRFRNLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNjUyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuZG9tMmR0bTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdWJhbGxvY2F0ZWRJbnRWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuSW50U3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuQm9vbFN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ0J1ZmZlclBvb2w7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5UcmVlV2Fsa2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXI7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci0KLS8qKiBUaGUgPGNvZGU+RE9NMkRUTTwvY29kZT4gY2xhc3Mgc2VydmVzIHVwIGEgRE9NJ3MgY29udGVudHMgdmlhIHRoZQotICogRFRNIEFQSS4KLSAqCi0gKiBOb3RlIHRoYXQgaXQgZG9lc24ndCBuZWNlc3NhcmlseSByZXByZXNlbnQgYSBmdWxsIERvY3VtZW50Ci0gKiB0cmVlLiBZb3UgY2FuIHdyYXAgYSBET00yRFRNIGFyb3VuZCBhIHNwZWNpZmljIG5vZGUgYW5kIGl0cyBzdWJ0cmVlCi0gKiBhbmQgdGhlIHJpZ2h0IHRoaW5ncyBzaG91bGQgaGFwcGVuLiAoSSBkb24ndCBfdGhpbmtfIHdlIGN1cnJlbnRseQotICogc3VwcG9ydCBEb2N1bWVudEZyZ21lbnQgbm9kZXMgYXMgcm9vdHMsIHRob3VnaCB0aGF0IG1pZ2h0IGJlIHdvcnRoCi0gKiBjb25zaWRlcmluZy4pCi0gKgotICogTm90ZSB0b28gdGhhdCB3ZSBkbyBub3QgY3VycmVudGx5IGF0dGVtcHQgdG8gdHJhY2sgZG9jdW1lbnQKLSAqIG11dGF0aW9uLiBJZiB5b3UgYWx0ZXIgdGhlIERPTSBhZnRlciB3cmFwcGluZyBET00yRFRNIGFyb3VuZCBpdCwKLSAqIGFsbCBiZXRzIGFyZSBvZmYuCi0gKiAqLwotcHVibGljIGNsYXNzIERPTTJEVE0gZXh0ZW5kcyBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycwotewotICBzdGF0aWMgZmluYWwgYm9vbGVhbiBKSktfREVCVUc9ZmFsc2U7Ci0gIAotICAvKiogVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIERPTSB0cmVlLiBMYXN0IG5vZGUgZXhhbWluZWQgZm9yCi0gICAqIHBvc3NpYmxlIGNvcHlpbmcgdG8gRFRNLiAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBOb2RlIG1fcG9zOwotICAvKiogVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIERUTSB0cmVlLiBXaG8gY2hpbGRyZW4gZ2V0IGFwcGVuZGVkIHRvLiAqLwotICBwcml2YXRlIGludCBtX2xhc3RfcGFyZW50PTA7Ci0gIC8qKiBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgRFRNIHRyZWUuIFdobyBjaGlsZHJlbiByZWZlcmVuY2UgYXMgdGhlaXIgCi0gICAqIHByZXZpb3VzIHNpYi4gKi8KLSAgcHJpdmF0ZSBpbnQgbV9sYXN0X2tpZD1OVUxMOwotCi0gIC8qKiBUaGUgdG9wIG9mIHRoZSBzdWJ0cmVlLgotICAgKiAlUkVWSUVXJTogJ21heSBub3QgYmUgdGhlIHNhbWUgYXMgbV9jb250ZXh0IGlmICIvL2ZvbyIgcGF0dGVybi4nCi0gICAqICovCi0gIHRyYW5zaWVudCBwcml2YXRlIE5vZGUgbV9yb290OwotCi0gIC8qKiB0cnVlIGlmIEFMTCB0aGUgbm9kZXMgaW4gdGhlIG1fcm9vdCBzdWJ0cmVlIGhhdmUgYmVlbiBwcm9jZXNzZWQ7Ci0gICAqIGZhbHNlIGlmIG91ciBpbmNyZW1lbnRhbCBidWlsZCBoYXMgbm90IHlldCBmaW5pc2hlZCBzY2FubmluZyB0aGUKLSAgICogRE9NIHRyZWUuICAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBib29sZWFuIG1fbm9kZXNBcmVQcm9jZXNzZWQ7Ci0KLSAgLyoqIFRoZSBub2RlIG9iamVjdHMuICBUaGUgaW5zdGFuY2UgcGFydCBvZiB0aGUgaGFuZGxlIGluZGV4ZXMKLSAgICogZGlyZWN0bHkgaW50byB0aGlzIHZlY3Rvci4gIEVhY2ggRFRNIG5vZGUgbWF5IGFjdHVhbGx5IGJlCi0gICAqIGNvbXBvc2VkIG9mIHNldmVyYWwgRE9NIG5vZGVzIChmb3IgZXhhbXBsZSwgaWYgbG9naWNhbGx5LWFkamFjZW50Ci0gICAqIFRleHQvQ0RBVEFTZWN0aW9uIG5vZGVzIGluIHRoZSBET00gaGF2ZSBiZWVuIGNvYWxlc2NlZCBpbnRvIGEKLSAgICogc2luZ2xlIERUTSBUZXh0IG5vZGUpOyB0aGlzIHRhYmxlIHBvaW50cyBvbmx5IHRvIHRoZSBmaXJzdCBpbgotICAgKiB0aGF0IHNlcXVlbmNlLiAqLwotICBwcm90ZWN0ZWQgVmVjdG9yIG1fbm9kZXMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIERPTTJEVE0gb2JqZWN0IGZyb20gYSBET00gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG1nciBUaGUgRFRNTWFuYWdlciB3aG8gb3ducyB0aGlzIERUTS4KLSAgICogQHBhcmFtIGRvbVNvdXJjZSB0aGUgRE9NIHNvdXJjZSB0aGF0IHRoaXMgRFRNIHdpbGwgd3JhcC4KLSAgICogQHBhcmFtIGR0bUlkZW50aXR5IFRoZSBEVE0gaWRlbnRpdHkgSUQgZm9yIHRoaXMgRFRNLgotICAgKiBAcGFyYW0gd2hpdGVTcGFjZUZpbHRlciBUaGUgd2hpdGUgc3BhY2UgZmlsdGVyIGZvciB0aGlzIERUTSwgd2hpY2ggbWF5IAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0geHN0cmluZ2ZhY3RvcnkgWE1MU3RyaW5nIGZhY3RvcnkgZm9yIGNyZWF0aW5nIGNoYXJhY3RlciBjb250ZW50LgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZSAKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICovCi0gIHB1YmxpYyBET00yRFRNKERUTU1hbmFnZXIgbWdyLCBET01Tb3VyY2UgZG9tU291cmNlLCAKLSAgICAgICAgICAgICAgICAgaW50IGR0bUlkZW50aXR5LCBEVE1XU0ZpbHRlciB3aGl0ZVNwYWNlRmlsdGVyLAotICAgICAgICAgICAgICAgICBYTUxTdHJpbmdGYWN0b3J5IHhzdHJpbmdmYWN0b3J5LAotICAgICAgICAgICAgICAgICBib29sZWFuIGRvSW5kZXhpbmcpCi0gIHsKLSAgICBzdXBlcihtZ3IsIGRvbVNvdXJjZSwgZHRtSWRlbnRpdHksIHdoaXRlU3BhY2VGaWx0ZXIsIAotICAgICAgICAgIHhzdHJpbmdmYWN0b3J5LCBkb0luZGV4aW5nKTsKLQotICAgIC8vIEluaXRpYWxpemUgRE9NIG5hdmlnYXRpb24KLSAgICBtX3Bvcz1tX3Jvb3QgPSBkb21Tb3VyY2UuZ2V0Tm9kZSgpOwotICAgIC8vIEluaXRpYWxpemUgRFRNIG5hdmlnYXRpb24KLSAgICBtX2xhc3RfcGFyZW50PW1fbGFzdF9raWQ9TlVMTDsKLSAgICBtX2xhc3Rfa2lkPWFkZE5vZGUobV9yb290LCBtX2xhc3RfcGFyZW50LG1fbGFzdF9raWQsIE5VTEwpOwotCi0gICAgLy8gQXBwYXJlbnRseSB0aGUgZG9tU291cmNlIHJvb3QgbWF5IG5vdCBhY3R1YWxseSBiZSB0aGUKLSAgICAvLyBEb2N1bWVudCBub2RlLiBJZiBpdCdzIGFuIEVsZW1lbnQgbm9kZSwgd2UgbmVlZCB0byBpbW1lZGlhdGVseQotICAgIC8vIGFkZCBpdHMgYXR0cmlidXRlcy4gQWRhcHRlZCBmcm9tIG5leHROb2RlKCkuCi0gICAgLy8gJVJFVklFVyUgTW92ZSB0aGlzIGxvZ2ljIGludG8gYWRkTm9kZSBhbmQgcmVjdXJzZT8gQ2xlYW5lciEKLSAgICAvLwotICAgIC8vIChJZiBpdCdzIGFuIEVudGl0eVJlZmVyZW5jZSBub2RlLCB3ZSdyZSBwcm9iYWJseSBzY3JvZC4gRm9yIG5vdwotICAgIC8vIEknbSBqdXN0IGhvcGluZyBub2JvZHkgaXMgZXZlciBxdWl0ZSB0aGF0IGZvb2xpc2guLi4gJVJFVklFVyUpCi0gICAgaWYoRUxFTUVOVF9OT0RFID09IG1fcm9vdC5nZXROb2RlVHlwZSgpKQotICAgIHsKLSAgICAgIE5hbWVkTm9kZU1hcCBhdHRycz1tX3Jvb3QuZ2V0QXR0cmlidXRlcygpOwotICAgICAgaW50IGF0dHJzaXplPShhdHRycz09bnVsbCkgPyAwIDogYXR0cnMuZ2V0TGVuZ3RoKCk7Ci0gICAgICBpZihhdHRyc2l6ZT4wKQotICAgICAgewotICAgICAgICBpbnQgYXR0ckluZGV4PU5VTEw7IC8vIHN0YXJ0IHdpdGggbm8gcHJldmlvdXMgc2liCi0gICAgICAgIGZvcihpbnQgaT0wO2k8YXR0cnNpemU7KytpKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gTm8gbmVlZCB0byBmb3JjZSBub2RldHlwZSBpbiB0aGlzIGNhc2U7Ci0gICAgICAgICAgLy8gYWRkTm9kZSgpIHdpbGwgdGFrZSBjYXJlIG9mIHN3aXRjaGluZyBpdCBmcm9tCi0gICAgICAgICAgLy8gQXR0ciB0byBOYW1lc3BhY2UgaWYgbmVjZXNzYXJ5LgotICAgICAgICAgIGF0dHJJbmRleD1hZGROb2RlKGF0dHJzLml0ZW0oaSksMCxhdHRySW5kZXgsTlVMTCk7Ci0gICAgICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChEVE0uTlVMTCxhdHRySW5kZXgpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFRlcm1pbmF0ZSBsaXN0IG9mIGF0dHJzLCBhbmQgbWFrZSBzdXJlIHRoZXkgYXJlbid0Ci0gICAgICAgIC8vIGNvbnNpZGVyZWQgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQKLSAgICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCxhdHRySW5kZXgpOwotCi0gICAgICAgIC8vIElNUE9SVEFOVDogVGhpcyBkb2VzIE5PVCBjaGFuZ2UgbV9sYXN0X3BhcmVudCBvciBtX2xhc3Rfa2lkIQotICAgICAgfSAvLyBpZiBhdHRycyBleGlzdAotICAgIH0gLy9pZihFTEVNRU5UX05PREUpCi0KLSAgICAvLyBJbml0aWFsaXplIERUTS1jb21wbGV0ZWQgc3RhdHVzIAotICAgIG1fbm9kZXNBcmVQcm9jZXNzZWQgPSBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgdGhlIG5vZGUgbWFwIGZyb20gdGhlIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRoYXQgaXMgdG8gYmUgYWRkZWQgdG8gdGhlIERUTS4KLSAgICogQHBhcmFtIHBhcmVudEluZGV4IFRoZSBjdXJyZW50IHBhcmVudCBpbmRleC4KLSAgICogQHBhcmFtIHByZXZpb3VzU2libGluZyBUaGUgcHJldmlvdXMgc2libGluZyBpbmRleC4KLSAgICogQHBhcmFtIGZvcmNlTm9kZVR5cGUgSWYgbm90IERUTS5OVUxMLCBvdmVycmlkZXMgdGhlIERPTSBub2RlIHR5cGUuCi0gICAqCVVzZWQgdG8gZm9yY2Ugbm9kZXMgdG8gVGV4dCByYXRoZXIgdGhhbiBDREFUQVNlY3Rpb24gd2hlbiB0aGVpcgotICAgKgljb2FsZXNjZWQgdmFsdWUgaW5jbHVkZXMgb3JkaW5hcnkgVGV4dCBub2RlcyAoY3VycmVudCBEVE0gYmVoYXZpb3IpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCBpZGVudGl0eSBvZiB0aGUgbm9kZSB0aGF0IHdhcyBhZGRlZC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgYWRkTm9kZShOb2RlIG5vZGUsIGludCBwYXJlbnRJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBwcmV2aW91c1NpYmxpbmcsIGludCBmb3JjZU5vZGVUeXBlKQotICB7Ci0gICAgaW50IG5vZGVJbmRleCA9IG1fbm9kZXMuc2l6ZSgpOwotICAgIG1fc2l6ZSsrOwotICAgIC8vIGVuc3VyZVNpemUobm9kZUluZGV4KTsKLSAgICAKLSAgICBpbnQgdHlwZTsKLSAgICBpZihOVUxMPT1mb3JjZU5vZGVUeXBlKQotICAgICAgICB0eXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwotICAgIGVsc2UKLSAgICAgICAgdHlwZT1mb3JjZU5vZGVUeXBlOwotICAgICAgICAKLSAgICAvLyAlUkVWSUVXJSBUaGUgTmFtZXNwYWNlIFNwZWMgY3VycmVudGx5IHNheXMgdGhhdCBOYW1lc3BhY2VzIGFyZQotICAgIC8vIHByb2Nlc3NlZCBpbiBhIG5vbi1uYW1lc3BhY2UtYXdhcmUgbWFubmVyLCBieSBtYXRjaGluZyB0aGUKLSAgICAvLyBRTmFtZSwgZXZlbiB0aG91Z2ggdGhlcmUgaXMgaW4gZmFjdCBhIG5hbWVzcGFjZSBhc3NpZ25lZCB0bwotICAgIC8vIHRoZXNlIG5vZGVzIGluIHRoZSBET00uIElmIGFuZCB3aGVuIHRoYXQgY2hhbmdlcywgd2Ugd2lsbCBoYXZlCi0gICAgLy8gdG8gY29uc2lkZXIgd2hldGhlciB3ZSBjaGVjayB0aGUgbmFtZXNwYWNlLWZvci1uYW1lc3BhY2VzCi0gICAgLy8gcmF0aGVyIHRoYW4gdGhlIG5vZGUgbmFtZS4KLSAgICAvLwotICAgIC8vICVUQkQlIE5vdGUgdGhhdCB0aGUgRE9NIGRvZXMgbm90IG5lY2Vzc2FyaWx5IGV4cGxpY2l0bHkgZGVjbGFyZQotICAgIC8vIGFsbCB0aGUgbmFtZXNwYWNlcyBpdCB1c2VzLiBET00gTGV2ZWwgMyB3aWxsIGludHJvZHVjZSBhCi0gICAgLy8gbmFtZXNwYWNlLW5vcm1hbGl6YXRpb24gb3BlcmF0aW9uIHdoaWNoIHJlY29uY2lsZXMgdGhhdCwgYW5kIHdlCi0gICAgLy8gY2FuIHJlcXVlc3QgdGhhdCB1c2VycyBpbnZva2UgaXQgb3Igb3RoZXJ3aXNlIGVuc3VyZSB0aGF0IHRoZQotICAgIC8vIHRyZWUgaXMgbmFtZXNwYWNlLXdlbGwtZm9ybWVkIGJlZm9yZSBwYXNzaW5nIHRoZSBET00gdG8gWGFsYW4uCi0gICAgLy8gQnV0IGlmIHRoZXkgZG9uJ3QsIHdoYXQgc2hvdWxkIHdlIGRvIGFib3V0IGl0PyBXZSBwcm9iYWJseQotICAgIC8vIGRvbid0IHdhbnQgdG8gYWx0ZXIgdGhlIHNvdXJjZSBET00gKGFuZCBtYXkgbm90IGJlIGFibGUgdG8gZG8KLSAgICAvLyBzbyBpZiBpdCdzIHJlYWQtb25seSkuIFRoZSBiZXN0IGF2YWlsYWJsZSBhbnN3ZXIgbWlnaHQgYmUgdG8KLSAgICAvLyBzeW50aGVzaXplIGFkZGl0aW9uYWwgRFRNIE5hbWVzcGFjZSBOb2RlcyB0aGF0IGRvbid0IGNvcnJlc3BvbmQKLSAgICAvLyB0byBET00gQXR0ciBOb2Rlcy4KLSAgICBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotCi0gICAgICBpZiAobmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fCBuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgIHsKLSAgICAgICAgdHlwZSA9IERUTS5OQU1FU1BBQ0VfTk9ERTsKLSAgICAgIH0KLSAgICB9Ci0gICAgCi0gICAgbV9ub2Rlcy5hZGRFbGVtZW50KG5vZGUpOwotICAgIAotICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQoTk9UUFJPQ0VTU0VELG5vZGVJbmRleCk7Ci0gICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChOT1RQUk9DRVNTRUQsbm9kZUluZGV4KTsKLSAgICBtX3ByZXZzaWIuc2V0RWxlbWVudEF0KHByZXZpb3VzU2libGluZyxub2RlSW5kZXgpOwotICAgIG1fcGFyZW50LnNldEVsZW1lbnRBdChwYXJlbnRJbmRleCxub2RlSW5kZXgpOwotICAgIAotICAgIGlmKERUTS5OVUxMICE9IHBhcmVudEluZGV4ICYmIAotICAgICAgIHR5cGUgIT0gRFRNLkFUVFJJQlVURV9OT0RFICYmIAotICAgICAgIHR5cGUgIT0gRFRNLk5BTUVTUEFDRV9OT0RFKQotICAgIHsKLSAgICAgIC8vIElmIHRoZSBEVE0gcGFyZW50IGhhZCBubyBjaGlsZHJlbiwgdGhpcyBiZWNvbWVzIGl0cyBmaXJzdCBjaGlsZC4KLSAgICAgIGlmKE5PVFBST0NFU1NFRCA9PSBtX2ZpcnN0Y2guZWxlbWVudEF0KHBhcmVudEluZGV4KSkKLSAgICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChub2RlSW5kZXgscGFyZW50SW5kZXgpOwotICAgIH0KLSAgICAKLSAgICBTdHJpbmcgbnNVUkkgPSBub2RlLmdldE5hbWVzcGFjZVVSSSgpOwotCi0gICAgLy8gRGVhbCB3aXRoIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gTmFtZXNwYWNlIHNwZWMgYW5kIFhTTFQKLSAgICAvLyBkZWZpbml0aW9ucyBvZiBsb2NhbCBuYW1lLiAoVGhlIGZvcm1lciBzYXlzIFBJcyBkb24ndCBoYXZlCi0gICAgLy8gbG9jYWxuYW1lczsgdGhlIGxhdHRlciBzYXlzIHRoZXkgZG8uKQotICAgIFN0cmluZyBsb2NhbE5hbWUgPSAgKHR5cGUgPT0gTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUpID8gCi0gICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5nZXROb2RlTmFtZSgpIDoKLSAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLmdldExvY2FsTmFtZSgpOwotICAgICAgICAgICAgICAgICAgICAgICAgIAotICAgIC8vIEhhY2sgdG8gbWFrZSBET00xIHNvcnQgb2Ygd29yay4uLgotICAgIGlmKCgodHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgfHwgKHR5cGUgPT0gTm9kZS5BVFRSSUJVVEVfTk9ERSkpIAotICAgICAgICAmJiBudWxsID09IGxvY2FsTmFtZSkKLSAgICAgIGxvY2FsTmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsgLy8gLXNiCi0gICAgICAKLSAgICBFeHBhbmRlZE5hbWVUYWJsZSBleG50ID0gbV9leHBhbmRlZE5hbWVUYWJsZTsKLQotICAgIC8vICVUQkQlIE5vZGVzIGNyZWF0ZWQgd2l0aCB0aGUgb2xkIG5vbi1uYW1lc3BhY2UtYXdhcmUgRE9NCi0gICAgLy8gY2FsbHMgY3JlYXRlRWxlbWVudCgpIGFuZCBjcmVhdGVBdHRyaWJ1dGUoKSB3aWxsIG5ldmVyIGhhdmUgYQotICAgIC8vIGxvY2FsbmFtZS4gVGhhdCB3aWxsIGNhdXNlIHRoZWlyIGV4cGFuZGVkTmFtZUlEIHRvIGJlIGp1c3QgdGhlCi0gICAgLy8gbm9kZVR5cGUuLi4gd2hpY2ggd2lsbCBrZWVwIHRoZW0gZnJvbSBiZWluZyBtYXRjaGVkCi0gICAgLy8gc3VjY2Vzc2Z1bGx5IGJ5IG5hbWUuIFNpbmNlIHRoZSBET00gbWFrZXMgbm8gcHJvbWlzZSB0aGF0Ci0gICAgLy8gdGhvc2Ugd2lsbCBwYXJ0aWNpcGF0ZSBpbiBuYW1lc3BhY2UgcHJvY2Vzc2luZywgdGhpcyBpcwotICAgIC8vIG9mZmljaWFsbHkgYWNjZXB0ZWQgYXMgTm90IE91ciBGYXVsdC4gQnV0IGl0IG1pZ2h0IGJlIG5pY2UgdG8KLSAgICAvLyBpc3N1ZSBhIGRpYWdub3N0aWMgbWVzc2FnZSEKLSAgICBpZihub2RlLmdldExvY2FsTmFtZSgpPT1udWxsICYmCi0gICAgICAgKHR5cGU9PU5vZGUuRUxFTUVOVF9OT0RFIHx8IHR5cGU9PU5vZGUuQVRUUklCVVRFX05PREUpKQotICAgICAgewotICAgICAgICAvLyB3YXJuaW5nKCJET00gJ2xldmVsIDEnIG5vZGUgIitub2RlLmdldE5vZGVOYW1lKCkrIiB3b24ndCBiZSBtYXBwZWQgcHJvcGVybHkgaW4gRE9NMkRUTS4iKTsKLSAgICAgIH0KLSAgICAKLSAgICBpbnQgZXhwYW5kZWROYW1lSUQgPSAobnVsbCAhPSBsb2NhbE5hbWUpIAotICAgICAgID8gZXhudC5nZXRFeHBhbmRlZFR5cGVJRChuc1VSSSwgbG9jYWxOYW1lLCB0eXBlKSA6Ci0gICAgICAgICBleG50LmdldEV4cGFuZGVkVHlwZUlEKHR5cGUpOwotCi0gICAgbV9leHB0eXBlLnNldEVsZW1lbnRBdChleHBhbmRlZE5hbWVJRCxub2RlSW5kZXgpOwotICAgIAotICAgIGluZGV4Tm9kZShleHBhbmRlZE5hbWVJRCwgbm9kZUluZGV4KTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBwcmV2aW91c1NpYmxpbmcpCi0gICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KG5vZGVJbmRleCxwcmV2aW91c1NpYmxpbmcpOwotCi0gICAgLy8gVGhpcyBzaG91bGQgYmUgZG9uZSBhZnRlciBtX2V4cHR5cGUgaGFzIGJlZW4gc2V0LCBhbmQgcHJvYmFibHkgc2hvdWxkCi0gICAgLy8gYWx3YXlzIGJlIHRoZSBsYXN0IHRoaW5nIHdlIGRvCi0gICAgaWYgKHR5cGUgPT0gRFRNLk5BTUVTUEFDRV9OT0RFKQotICAgICAgICBkZWNsYXJlTmFtZXNwYWNlSW5Db250ZXh0KHBhcmVudEluZGV4LG5vZGVJbmRleCk7Ci0KLSAgICByZXR1cm4gbm9kZUluZGV4OwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBudW1iZXIgb2Ygbm9kZXMgdGhhdCBoYXZlIGJlZW4gYWRkZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE51bWJlck9mTm9kZXMoKQotICB7Ci0gICAgcmV0dXJuIG1fbm9kZXMuc2l6ZSgpOwotICB9Ci0gIAotIC8qKgotICAgKiBUaGlzIG1ldGhvZCBpdGVyYXRlcyB0byB0aGUgbmV4dCBub2RlIHRoYXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgdGFibGUuCi0gICAqIEVhY2ggY2FsbCB0byB0aGlzIG1ldGhvZCBhZGRzIGEgbmV3IG5vZGUgdG8gdGhlIHRhYmxlLCB1bmxlc3MgdGhlIGVuZAotICAgKiBpcyByZWFjaGVkLCBpbiB3aGljaCBjYXNlIGl0IHJldHVybnMgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdHJ1ZSBpZiBhIG5leHQgbm9kZSBpcyBmb3VuZCBvciBmYWxzZSBpZiAKLSAgICogICAgICAgICB0aGVyZSBhcmUgbm8gbW9yZSBub2Rlcy4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIG5leHROb2RlKCkKLSAgewotICAgIC8vIE5vbi1yZWN1cnNpdmUgb25lLWZldGNoLWF0LWEtdGltZSBkZXB0aC1maXJzdCB0cmF2ZXJzYWwgd2l0aCAKLSAgICAvLyBhdHRyaWJ1dGUvbmFtZXNwYWNlIG5vZGVzIGFuZCB3aGl0ZS1zcGFjZSBzdHJpcHBpbmcuCi0gICAgLy8gTmF2aWdhdGluZyB0aGUgRE9NIGlzIHNpbXBsZSwgbmF2aWdhdGluZyB0aGUgRFRNIGlzIHNpbXBsZTsKLSAgICAvLyBrZWVwaW5nIHRyYWNrIG9mIGJvdGggYXQgb25jZSBpcyBhIHRyaWZsZSBiYXJvcXVlIGJ1dCBhdCBsZWFzdAotICAgIC8vIHdlJ3ZlIGF2b2lkZWQgbW9zdCBvZiB0aGUgc3BlY2lhbCBjYXNlcy4KLSAgICBpZiAobV9ub2Rlc0FyZVByb2Nlc3NlZCkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgCi0gICAgLy8gJVJFVklFVyUgSXMgdGhpcyBsb2NhbCBjb3B5IFJlYWxseSBVc2VmdWwgZnJvbSBhIHBlcmZvcm1hbmNlCi0gICAgLy8gcG9pbnQgb2Ygdmlldz8gIE9yIGlzIHRoaXMgYSBmYWxzZSBtaWNyb29wdGltaXphdGlvbj8KLSAgICBOb2RlIHBvcz1tX3BvczsgCi0gICAgTm9kZSBuZXh0PW51bGw7Ci0gICAgaW50IG5leHR0eXBlPU5VTEw7Ci0KLSAgICAvLyBOYXZpZ2F0ZSBET00gdHJlZQotICAgIGRvCi0gICAgICB7Ci0gICAgICAgIC8vIExvb2sgZG93biB0byBmaXJzdCBjaGlsZC4KLSAgICAgICAgaWYgKHBvcy5oYXNDaGlsZE5vZGVzKCkpIAotICAgICAgICAgIHsKLSAgICAgICAgICAgIG5leHQgPSBwb3MuZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgICAgICAgICAvLyAlUkVWSUVXJSBUaGVyZSdzIHByb2JhYmx5IGEgbW9yZSBlbGVnYW50IHdheSB0byBza2lwCi0gICAgICAgICAgICAvLyB0aGUgZG9jdHlwZS4gKEp1c3QgbGV0IGl0IGdvIGFuZCBTdXBwcmVzcyBpdD8KLSAgICAgICAgICAgIGlmKG5leHQhPW51bGwgJiYgRE9DVU1FTlRfVFlQRV9OT0RFPT1uZXh0LmdldE5vZGVUeXBlKCkpCi0gICAgICAgICAgICAgIG5leHQ9bmV4dC5nZXROZXh0U2libGluZygpOwotCi0gICAgICAgICAgICAvLyBQdXNoIERUTSBjb250ZXh0IC0tIGV4Y2VwdCBmb3IgY2hpbGRyZW4gb2YgRW50aXR5IFJlZmVyZW5jZXMsIAotICAgICAgICAgICAgLy8gd2hpY2ggaGF2ZSBubyBEVE0gZXF1aXZhbGVudCBhbmQgY2F1c2Ugbm8gRFRNIG5hdmlnYXRpb24uCi0gICAgICAgICAgICBpZihFTlRJVFlfUkVGRVJFTkNFX05PREUhPXBvcy5nZXROb2RlVHlwZSgpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9sYXN0X3BhcmVudD1tX2xhc3Rfa2lkOwotICAgICAgICAgICAgICAgIG1fbGFzdF9raWQ9TlVMTDsKLSAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlLWhhbmRsZXIgY29udGV4dCBzdGFja2luZwotICAgICAgICAgICAgICAgIGlmKG51bGwgIT0gbV93c2ZpbHRlcikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBzaG9ydCB3c3YgPQotICAgICAgICAgICAgICAgICAgICBtX3dzZmlsdGVyLmdldFNob3VsZFN0cmlwU3BhY2UobV9sYXN0X3BhcmVudHxtX2R0bUlkZW50LHRoaXMpOwotICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRTdHJpcCA9IChEVE1XU0ZpbHRlci5JTkhFUklUID09IHdzdikgCi0gICAgICAgICAgICAgICAgICAgID8gZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkgCi0gICAgICAgICAgICAgICAgICAgIDogKERUTVdTRmlsdGVyLlNUUklQID09IHdzdik7Ci0gICAgICAgICAgICAgICAgICBwdXNoU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKHNob3VsZFN0cmlwKTsKLSAgICAgICAgICAgICAgICB9IC8vIGlmKG1fd3NmaWx0ZXIpCi0gICAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgLy8gSWYgdGhhdCBmYWlscywgbG9vayB1cCBhbmQgcmlnaHQgKGJ1dCBub3QgcGFzdCByb290ISkKLSAgICAgICAgZWxzZSAKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZihtX2xhc3Rfa2lkIT1OVUxMKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgLy8gTGFzdCBub2RlIHBvc3RlZCBhdCB0aGlzIGxldmVsIGhhZCBubyBtb3JlIGNoaWxkcmVuCi0gICAgICAgICAgICAgICAgLy8gSWYgaXQgaGFzIF9ub18gY2hpbGRyZW4sIHdlIG5lZWQgdG8gcmVjb3JkIHRoYXQuCi0gICAgICAgICAgICAgICAgaWYobV9maXJzdGNoLmVsZW1lbnRBdChtX2xhc3Rfa2lkKT09Tk9UUFJPQ0VTU0VEKQotICAgICAgICAgICAgICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChOVUxMLG1fbGFzdF9raWQpOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgIHdoaWxlKG1fbGFzdF9wYXJlbnQgIT0gTlVMTCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vICVSRVZJRVclIFRoZXJlJ3MgcHJvYmFibHkgYSBtb3JlIGVsZWdhbnQgd2F5IHRvCi0gICAgICAgICAgICAgICAgLy8gc2tpcCB0aGUgZG9jdHlwZS4gKEp1c3QgbGV0IGl0IGdvIGFuZCBTdXBwcmVzcyBpdD8KLSAgICAgICAgICAgICAgICBuZXh0ID0gcG9zLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgaWYobmV4dCE9bnVsbCAmJiBET0NVTUVOVF9UWVBFX05PREU9PW5leHQuZ2V0Tm9kZVR5cGUoKSkKLSAgICAgICAgICAgICAgICAgIG5leHQ9bmV4dC5nZXROZXh0U2libGluZygpOwotCi0gICAgICAgICAgICAgICAgaWYobmV4dCE9bnVsbCkKLSAgICAgICAgICAgICAgICAgIGJyZWFrOyAvLyBGb3VuZCBpdCEKLSAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAvLyBObyBuZXh0LXNpYmxpbmcgZm91bmQuIFBvcCB0aGUgRE9NLgotICAgICAgICAgICAgICAgIHBvcz1wb3MuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgICAgICAgIGlmKHBvcz09bnVsbCkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy8gJVRCRCUgU2hvdWxkIG5ldmVyIGFyaXNlLCBidXQgSSB3YW50IHRvIGJlIHN1cmUgb2YgdGhhdC4uLgotICAgICAgICAgICAgICAgICAgICBpZihKSktfREVCVUcpCi0gICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKiBET00yRFRNIFBvcCBDb250cm9sIEZsb3cgcHJvYmxlbSIpOwotICAgICAgICAgICAgICAgICAgICAgICAgZm9yKDs7KTsgLy8gRnJlZXplIHJpZ2h0IGhlcmUhCi0gICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIC8vIFRoZSBvbmx5IHBhcmVudHMgaW4gdGhlIERUTSBhcmUgRWxlbWVudHMuICBIb3dldmVyLAotICAgICAgICAgICAgICAgIC8vIHRoZSBET00gY291bGQgY29udGFpbiBFbnRpdHlSZWZlcmVuY2VzLiAgSWYgd2UKLSAgICAgICAgICAgICAgICAvLyBlbmNvdW50ZXIgb25lLCBwb3AgaXQgX3dpdGhvdXRfIHBvcHBpbmcgRFRNLgotICAgICAgICAgICAgICAgIGlmKHBvcyE9bnVsbCAmJiBFTlRJVFlfUkVGRVJFTkNFX05PREUgPT0gcG9zLmdldE5vZGVUeXBlKCkpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgbmVlZHMgZG9pbmcKLSAgICAgICAgICAgICAgICAgICAgaWYoSkpLX0RFQlVHKQotICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKiogRE9NMkRUTSBwb3BwaW5nIEVudFJlZiIpOwotICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcG9wU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCk7Ci0gICAgICAgICAgICAgICAgICAgIC8vIEZpeCBhbmQgcG9wIERUTQotICAgICAgICAgICAgICAgICAgICBpZihtX2xhc3Rfa2lkPT1OVUxMKQotICAgICAgICAgICAgICAgICAgICAgIG1fZmlyc3RjaC5zZXRFbGVtZW50QXQoTlVMTCxtX2xhc3RfcGFyZW50KTsgLy8gUG9wcGluZyBmcm9tIGFuIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQoTlVMTCxtX2xhc3Rfa2lkKTsgLy8gUG9wcGluZyBmcm9tIGFueXRoaW5nIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgbV9sYXN0X3BhcmVudD1tX3BhcmVudC5lbGVtZW50QXQobV9sYXN0X2tpZD1tX2xhc3RfcGFyZW50KTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYobV9sYXN0X3BhcmVudD09TlVMTCkKLSAgICAgICAgICAgICAgbmV4dD1udWxsOwotICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAKLSAgICAgICAgaWYobmV4dCE9bnVsbCkKLSAgICAgICAgICBuZXh0dHlwZT1uZXh0LmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgIC8vIElmIGl0J3MgYW4gZW50aXR5IHJlZiwgYWR2YW5jZSBwYXN0IGl0LgotICAgICAgICAvLwotICAgICAgICAvLyAlUkVWSUVXJSBTaG91bGQgd2UgbGV0IHRoaXMgb3V0IHRoZSBkb29yIGFuZCBqdXN0IHN1cHByZXNzIGl0PwotICAgICAgICAvLyBNb3JlIHdvcmssIGJ1dCBzaW1wbGVyIGNvZGUsIG1vcmUgbGlrZWx5IHRvIGJlIGNvcnJlY3QsIGFuZAotICAgICAgICAvLyBpdCBkb2Vzbid0IGhhcHBlbiB2ZXJ5IG9mdGVuLiBXZSdkIGdldCByaWQgb2YgdGhlIGxvb3AgdG9vLgotICAgICAgICBpZiAoRU5USVRZX1JFRkVSRU5DRV9OT0RFID09IG5leHR0eXBlKQotICAgICAgICAgIHBvcz1uZXh0OwotICAgICAgfQotICAgIHdoaWxlIChFTlRJVFlfUkVGRVJFTkNFX05PREUgPT0gbmV4dHR5cGUpOyAKLSAgICAgICAgCi0gICAgLy8gRGlkIHdlIHJ1biBvdXQgb2YgdGhlIHRyZWU/Ci0gICAgaWYobmV4dD09bnVsbCkKLSAgICAgIHsKLSAgICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChOVUxMLDApOwotICAgICAgICBtX25vZGVzQXJlUHJvY2Vzc2VkID0gdHJ1ZTsKLSAgICAgICAgbV9wb3M9bnVsbDsKLSAgICAgICAgICAgICAgICAKLSAgICAgICAgaWYoSkpLX0RFQlVHKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiKioqKiogRE9NMkRUTSBDcm9zc2NoZWNrOiIpOwotICAgICAgICAgICAgZm9yKGludCBpPTA7aTxtX25vZGVzLnNpemUoKTsrK2kpCi0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihpKyI6XHQiK21fZmlyc3RjaC5lbGVtZW50QXQoaSkrIlx0IittX25leHRzaWIuZWxlbWVudEF0KGkpKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotICAgIC8vIFRleHQgbmVlZHMgc29tZSBzcGVjaWFsIGhhbmRsaW5nOgotICAgIC8vCi0gICAgLy8gRFRNIG1heSBza2lwIHdoaXRlc3BhY2UuIFRoaXMgaXMgaGFuZGxlZCBieSB0aGUgc3VwcHJlc3NOb2RlIGZsYWcsIHdoaWNoCi0gICAgLy8gd2hlbiB0cnVlIHdpbGwga2VlcCB0aGUgRFRNIG5vZGUgZnJvbSBiZWluZyBjcmVhdGVkLgotICAgIC8vCi0gICAgLy8gRFRNIG9ubHkgZGlyZWN0bHkgcmVjb3JkcyB0aGUgZmlyc3QgRE9NIG5vZGUgb2YgYW55IGxvZ2ljYWxseS1jb250aWd1b3VzCi0gICAgLy8gc2VxdWVuY2UuIFRoZSBsYXN0VGV4dE5vZGUgdmFsdWUgd2lsbCBiZSBzZXQgdG8gdGhlIGxhc3Qgbm9kZSBpbiB0aGUgCi0gICAgLy8gY29udGlndW91cyBzZXF1ZW5jZSwgYW5kIC0tIEFGVEVSIHRoZSBEVE0gYWRkTm9kZSAtLSBjYW4gYmUgdXNlZCB0byAKLSAgICAvLyBhZHZhbmNlIG5leHQgb3ZlciB0aGlzIHdob2xlIGJsb2NrLiBTaG91bGQgYmUgc2ltcGxlciB0aGFuIHNwZWNpYWwtY2FzaW5nCi0gICAgLy8gdGhlIGFib3ZlIGxvb3AgZm9yICJXYXMgdGhlIGxvZ2ljYWxseS1wcmVjZWVkaW5nIHNpYmxpbmcgYSB0ZXh0IG5vZGUiLgotICAgIC8vIAotICAgIC8vIEZpbmFsbHksIGEgRFRNIG5vZGUgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYSBDREFUQVNlY3Rpb24gb25seSBpZiBhbGwgdGhlCi0gICAgLy8gY29udGlndW91cyB0ZXh0IGl0IGNvdmVycyBpcyBDREFUQVNlY3Rpb25zLiBUaGUgZmlyc3QgVGV4dCBzaG91bGQKLSAgICAvLyBmb3JjZSBEVE0gdG8gVGV4dC4KLSAgICAgICAgCi0gICAgYm9vbGVhbiBzdXBwcmVzc05vZGU9ZmFsc2U7Ci0gICAgTm9kZSBsYXN0VGV4dE5vZGU9bnVsbDsKLQotICAgIG5leHR0eXBlPW5leHQuZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgCi0gICAgLy8gbmV4dHR5cGU9cG9zLmdldE5vZGVUeXBlKCk7Ci0gICAgaWYoVEVYVF9OT0RFID09IG5leHR0eXBlIHx8IENEQVRBX1NFQ1RJT05fTk9ERSA9PSBuZXh0dHlwZSkKLSAgICAgIHsKLSAgICAgICAgLy8gSWYgZmlsdGVyaW5nLCBpbml0aWFsbHkgYXNzdW1lIHdlJ3JlIGdvaW5nIHRvIHN1cHByZXNzIHRoZSBub2RlCi0gICAgICAgIHN1cHByZXNzTm9kZT0oKG51bGwgIT0gbV93c2ZpbHRlcikgJiYgZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkpOwotCi0gICAgICAgIC8vIFNjYW4gbG9naWNhbGx5IGNvbnRpZ3VvdXMgdGV4dCAoc2libGluZ3MsIHBsdXMgImZsYXR0ZW5pbmciCi0gICAgICAgIC8vIG9mIGVudGl0eSByZWZlcmVuY2UgYm91bmRhcmllcykuCi0gICAgICAgIE5vZGUgbj1uZXh0OwotICAgICAgICB3aGlsZShuIT1udWxsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGxhc3RUZXh0Tm9kZT1uOwotICAgICAgICAgICAgLy8gQW55IFRleHQgbm9kZSBtZWFucyBEVE0gY29uc2lkZXJzIGl0IGFsbCBUZXh0Ci0gICAgICAgICAgICBpZihURVhUX05PREUgPT0gbi5nZXROb2RlVHlwZSgpKQotICAgICAgICAgICAgICBuZXh0dHlwZT1URVhUX05PREU7Ci0gICAgICAgICAgICAvLyBBbnkgbm9uLXdoaXRlc3BhY2UgaW4gdGhpcyBzZXF1ZW5jZSBibG9ja3Mgd2hpdGVzcGFjZQotICAgICAgICAgICAgLy8gc3VwcHJlc3Npb24KLSAgICAgICAgICAgIHN1cHByZXNzTm9kZSAmPQotICAgICAgICAgICAgICBYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZShuLmdldE5vZGVWYWx1ZSgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgbj1sb2dpY2FsTmV4dERPTVRleHROb2RlKG4pOwotICAgICAgICAgIH0KLSAgICAgIH0KLSAgICAgICAgCi0gICAgLy8gU3BlY2lhbCBoYW5kbGluZyBmb3IgUElzOiBTb21lIERPTXMgcmVwcmVzZW50IHRoZSBYTUwKLSAgICAvLyBEZWNsYXJhdGlvbiBhcyBhIFBJLiBUaGlzIGlzIG9mZmljaWFsbHkgaW5jb3JyZWN0LCBwZXIgdGhlIERPTQotICAgIC8vIHNwZWMsIGJ1dCBpcyBjb25zaWRlcmVkIGEgIndyb25nIGJ1dCB0b2xlcmFibGUiIHRlbXBvcmFyeQotICAgIC8vIHdvcmthcm91bmQgcGVuZGluZyBwcm9wZXIgaGFuZGxpbmcgb2YgdGhlc2UgZmllbGRzIGluIERPTSBMZXZlbAotICAgIC8vIDMuIFdlIHdhbnQgdG8gcmVjb2duaXplIGFuZCByZWplY3QgdGhhdCBjYXNlLgotICAgIGVsc2UgaWYoUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFPT1uZXh0dHlwZSkKLSAgICAgIHsKLSAgICAgICAgc3VwcHJlc3NOb2RlID0gKHBvcy5nZXROb2RlTmFtZSgpLnRvTG93ZXJDYXNlKCkuZXF1YWxzKCJ4bWwiKSk7Ci0gICAgICB9Ci0gICAgICAgIAotICAgICAgICAKLSAgICBpZighc3VwcHJlc3NOb2RlKQotICAgICAgewotICAgICAgICAvLyBJbnNlcnRpbmcgbmV4dC4gTk9URSB0aGF0IHdlIGZvcmNlIHRoZSBub2RlIHR5cGU7IGZvcgotICAgICAgICAvLyBjb2FsZXNjZWQgVGV4dCwgdGhpcyByZWNvcmRzIENEQVRBU2VjdGlvbnMgYWRqYWNlbnQgdG8KLSAgICAgICAgLy8gb3JkaW5hcnkgVGV4dCBhcyBUZXh0LgotCWludCBuZXh0aW5kZXg9YWRkTm9kZShuZXh0LG1fbGFzdF9wYXJlbnQsbV9sYXN0X2tpZCwKLQkJCSAgICAgIG5leHR0eXBlKTsKLQkKLSAgICAgICAgbV9sYXN0X2tpZD1uZXh0aW5kZXg7Ci0KLSAgICAgICAgaWYoRUxFTUVOVF9OT0RFID09IG5leHR0eXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIFByb2Nlc3MgYXR0cmlidXRlcyBfbm93XywgcmF0aGVyIHRoYW4gd2FpdGluZy4KLSAgICAgICAgICAgIC8vIFNpbXBsZXIgY29udHJvbCBmbG93LCBtYWtlcyBOUyBjYWNoZSBhdmFpbGFibGUgaW1tZWRpYXRlbHkuCi0gICAgICAgICAgICBOYW1lZE5vZGVNYXAgYXR0cnM9bmV4dC5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICAgICAgICBpbnQgYXR0cnNpemU9KGF0dHJzPT1udWxsKSA/IDAgOiBhdHRycy5nZXRMZW5ndGgoKTsKLSAgICAgICAgICAgIGlmKGF0dHJzaXplPjApCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpbnQgYXR0ckluZGV4PU5VTEw7IC8vIHN0YXJ0IHdpdGggbm8gcHJldmlvdXMgc2liCi0gICAgICAgICAgICAgICAgZm9yKGludCBpPTA7aTxhdHRyc2l6ZTsrK2kpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gZm9yY2Ugbm9kZXR5cGUgaW4gdGhpcyBjYXNlOwotICAgICAgICAgICAgICAgICAgICAvLyBhZGROb2RlKCkgd2lsbCB0YWtlIGNhcmUgb2Ygc3dpdGNoaW5nIGl0IGZyb20KLSAgICAgICAgICAgICAgICAgICAgLy8gQXR0ciB0byBOYW1lc3BhY2UgaWYgbmVjZXNzYXJ5LgotICAgICAgICAgICAgICAgICAgICBhdHRySW5kZXg9YWRkTm9kZShhdHRycy5pdGVtKGkpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0aW5kZXgsYXR0ckluZGV4LE5VTEwpOwotICAgICAgICAgICAgICAgICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KERUTS5OVUxMLGF0dHJJbmRleCk7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgLy8gVGVybWluYXRlIGxpc3Qgb2YgYXR0cnMsIGFuZCBtYWtlIHN1cmUgdGhleSBhcmVuJ3QKLSAgICAgICAgICAgICAgICAvLyBjb25zaWRlcmVkIGNoaWxkcmVuIG9mIHRoZSBlbGVtZW50Ci0gICAgICAgICAgICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCxhdHRySW5kZXgpOwotICAgICAgICAgICAgICB9IC8vIGlmIGF0dHJzIGV4aXN0Ci0gICAgICAgICAgfSAvL2lmKEVMRU1FTlRfTk9ERSkKLSAgICAgIH0gLy8gKGlmICFzdXBwcmVzc05vZGUpCi0KLSAgICAvLyBUZXh0IHBvc3Rwcm9jZXNzaW5nOiBBY3Qgb24gdmFsdWVzIHN0b3JlZCBhYm92ZQotICAgIGlmKFRFWFRfTk9ERSA9PSBuZXh0dHlwZSB8fCBDREFUQV9TRUNUSU9OX05PREUgPT0gbmV4dHR5cGUpCi0gICAgICB7Ci0gICAgICAgIC8vICVUQkQlIElmIG5leHR0eXBlIHdhcyBmb3JjZWQgdG8gVEVYVCwgcGF0Y2ggdGhlIERUTSBub2RlCi0gICAgICAgICAgICAgICAgCi0gICAgICAgIG5leHQ9bGFzdFRleHROb2RlOyAgICAgIC8vIEFkdmFuY2UgdGhlIERPTSBjdXJzb3Igb3ZlciBjb250aWd1b3VzIHRleHQKLSAgICAgIH0KLSAgICAgICAgCi0gICAgLy8gUmVtZW1iZXIgd2hlcmUgd2UgbGVmdCBvZmYuCi0gICAgbV9wb3M9bmV4dDsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfSAgCi0KLQotICAvKioKLSAgICogUmV0dXJuIGFuIERPTSBub2RlIGZvciB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgVGhlIG5vZGUgSUQuCi0gICAqCi0gICAqIEByZXR1cm4gQSBub2RlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBEVE0gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldE5vZGUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0KLSAgICByZXR1cm4gKE5vZGUpIG1fbm9kZXMuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBOb2RlIGZyb20gYW4gaWRlbnRpdHkgaW5kZXguCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBub2RlSWRlbnRpdHkKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKi8KLSAgcHJvdGVjdGVkIE5vZGUgbG9va3VwTm9kZShpbnQgbm9kZUlkZW50aXR5KQotICB7Ci0gICAgcmV0dXJuIChOb2RlKSBtX25vZGVzLmVsZW1lbnRBdChub2RlSWRlbnRpdHkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGlkZW50aXR5IHZhbHVlIGluIHRoZSBsaXN0LCBhbmQgY2FsbCB0aGUgaXRlcmF0b3IKLSAgICogaWYgaXQgaGFzbid0IGJlZW4gYWRkZWQgeWV0LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgKGluZGV4KS4KLSAgICogQHJldHVybiBpZGVudGl0eSsxLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGVJZGVudGl0eShpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGlkZW50aXR5ICs9IDE7Ci0KLSAgICBpZiAoaWRlbnRpdHkgPj0gbV9ub2Rlcy5zaXplKCkpCi0gICAgewotICAgICAgaWYgKCFuZXh0Tm9kZSgpKQotICAgICAgICBpZGVudGl0eSA9IERUTS5OVUxMOwotICAgIH0KLQotICAgIHJldHVybiBpZGVudGl0eTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGhhbmRsZSBmcm9tIGEgTm9kZS4KLSAgICogPHA+JU9QVCUgVGhpcyB3aWxsIGJlIHByZXR0eSBzbG93LjwvcD4KLSAgICoKLSAgICogPHA+JU9QVCUgQW4gWFBhdGgtbGlrZSBzZWFyY2ggKHdhbGsgdXAgRE9NIHRvIHJvb3QsIHRyYWNraW5nIHBhdGg7Ci0gICAqIHdhbGsgZG93biBEVE0gcmVjb25zdHJ1Y3RpbmcgcGF0aCkgbWlnaHQgYmUgY29uc2lkZXJhYmx5IGZhc3RlcgotICAgKiBvbiBsYXRlciBub2RlcyBpbiBsYXJnZSBkb2N1bWVudHMuIFRoYXQgbWlnaHQgYWxzbyBpbXBseSBpbXByb3ZpbmcKLSAgICogdGhpcyBjYWxsIHRvIGhhbmRsZSBub2RlcyB3aGljaCB3b3VsZCBiZSBpbiB0aGlzIERUTSBidXQKLSAgICogaGF2ZSBub3QgeWV0IGJlZW4gYnVpbHQsIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCBiZSBhIEdvb2QgVGhpbmcuPC9wPgotICAgKiAKLSAgICogJVJFVklFVyUgVGhpcyByZWxpZXMgb24gYmVpbmcgYWJsZSB0byB0ZXN0IG5vZGUtaWRlbnRpdHkgdmlhCi0gICAqIG9iamVjdC1pZGVudGl0eS4gRFRNMkRPTSBwcm94eWluZyBpcyBhIGdyZWF0IGV4YW1wbGUgb2YgYSBjYXNlIHdoZXJlCi0gICAqIHRoYXQgZG9lc24ndCB3b3JrLiBET00gTGV2ZWwgMyB3aWxsIHByb3ZpZGUgdGhlIGlzU2FtZU5vZGUoKSBtZXRob2QKLSAgICogdG8gZml4IHRoYXQsIGJ1dCB1bnRpbCB0aGVuIHRoaXMgaXMgZ29pbmcgdG8gYmUgZmxha3kuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIEEgbm9kZSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgaGFuZGxlIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPi4KLSAgICovCi0gIHByaXZhdGUgaW50IGdldEhhbmRsZUZyb21Ob2RlKE5vZGUgbm9kZSkKLSAgewotICAgIGlmIChudWxsICE9IG5vZGUpCi0gICAgewotICAgICAgaW50IGxlbiA9IG1fbm9kZXMuc2l6ZSgpOyAgICAgICAgCi0gICAgICBib29sZWFuIGlzTW9yZTsKLSAgICAgIGludCBpID0gMDsKLSAgICAgIGRvCi0gICAgICB7ICAgICAgICAgIAotICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG1fbm9kZXMuZWxlbWVudEF0KGkpID09IG5vZGUpCi0gICAgICAgICAgICByZXR1cm4gaSB8IG1fZHRtSWRlbnQ7ICAgICAgICAgCi0gICAgICAgIH0KLQotICAgICAgICBpc01vcmUgPSBuZXh0Tm9kZSgpOwotICAKLSAgICAgICAgbGVuID0gbV9ub2Rlcy5zaXplKCk7Ci0gICAgICAgICAgICAKLSAgICAgIH0gCi0gICAgICB3aGlsZShpc01vcmUgfHwgaSA8IGxlbik7Ci0gICAgfQotICAgIAotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKiBHZXQgdGhlIGhhbmRsZSBmcm9tIGEgTm9kZS4gVGhpcyBpcyBhIG1vcmUgcm9idXN0IHZlcnNpb24gb2YKLSAgICogZ2V0SGFuZGxlRnJvbU5vZGUsIGludGVuZGVkIHRvIGJlIHVzYWJsZSBieSB0aGUgcHVibGljLgotICAgKgotICAgKiA8cD4lT1BUJSBUaGlzIHdpbGwgYmUgcHJldHR5IHNsb3cuPC9wPgotICAgKiAKLSAgICogJVJFVklFVyUgVGhpcyByZWxpZXMgb24gYmVpbmcgYWJsZSB0byB0ZXN0IG5vZGUtaWRlbnRpdHkgdmlhCi0gICAqIG9iamVjdC1pZGVudGl0eS4gRFRNMkRPTSBwcm94eWluZyBpcyBhIGdyZWF0IGV4YW1wbGUgb2YgYSBjYXNlIHdoZXJlCi0gICAqIHRoYXQgZG9lc24ndCB3b3JrLiBET00gTGV2ZWwgMyB3aWxsIHByb3ZpZGUgdGhlIGlzU2FtZU5vZGUoKSBtZXRob2QKLSAgICogdG8gZml4IHRoYXQsIGJ1dCB1bnRpbCB0aGVuIHRoaXMgaXMgZ29pbmcgdG8gYmUgZmxha3kuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIEEgbm9kZSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgaGFuZGxlIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPi4gICovCi0gIHB1YmxpYyBpbnQgZ2V0SGFuZGxlT2ZOb2RlKE5vZGUgbm9kZSkKLSAgewotICAgIGlmIChudWxsICE9IG5vZGUpCi0gICAgewotICAgICAgLy8gSXMgTm9kZSBhY3R1YWxseSB3aXRoaW4gdGhlIHNhbWUgZG9jdW1lbnQ/IElmIG5vdCwgZG9uJ3Qgc2VhcmNoIQotICAgICAgLy8gVGhpcyB3b3VsZCBiZSBlYXNpZXIgaWYgbV9yb290IHdhcyBhbHdheXMgdGhlIERvY3VtZW50IG5vZGUsIGJ1dAotICAgICAgLy8gd2UgZGVjaWRlZCB0byBhbGxvdyB3cmFwcGluZyBhIERUTSBhcm91bmQgYSBzdWJ0cmVlLgotICAgICAgaWYoKG1fcm9vdD09bm9kZSkgfHwKLSAgICAgICAgIChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKT09RE9DVU1FTlRfTk9ERSAmJgotICAgICAgICAgIG1fcm9vdD09bm9kZS5nZXRPd25lckRvY3VtZW50KCkpIHx8Ci0gICAgICAgICAobV9yb290LmdldE5vZGVUeXBlKCkhPURPQ1VNRU5UX05PREUgJiYKLSAgICAgICAgICBtX3Jvb3QuZ2V0T3duZXJEb2N1bWVudCgpPT1ub2RlLmdldE93bmVyRG9jdW1lbnQoKSkKLSAgICAgICAgICkKLSAgICAgICAgewotICAgICAgICAgIC8vIElmIG5vZGUgX2lzXyBpbiBtX3Jvb3QncyB0cmVlLCBmaW5kIGl0cyBoYW5kbGUKLSAgICAgICAgICAvLwotICAgICAgICAgIC8vICVPUFQlIFRoaXMgY2hlY2sgbWF5IGJlIGltcHJvdmVkIHNpZ25pZmljYW50bHkgd2hlbiBET00KLSAgICAgICAgICAvLyBMZXZlbCAzIG5vZGVLZXkgYW5kIHJlbGF0aXZlLW9yZGVyIHRlc3RzIGJlY29tZQotICAgICAgICAgIC8vIGF2YWlsYWJsZSEKLSAgICAgICAgICBmb3IoTm9kZSBjdXJzb3I9bm9kZTsKLSAgICAgICAgICAgICAgY3Vyc29yIT1udWxsOwotICAgICAgICAgICAgICBjdXJzb3I9Ci0gICAgICAgICAgICAgICAgKGN1cnNvci5nZXROb2RlVHlwZSgpIT1BVFRSSUJVVEVfTk9ERSkKLSAgICAgICAgICAgICAgICA/IGN1cnNvci5nZXRQYXJlbnROb2RlKCkKLSAgICAgICAgICAgICAgICA6ICgob3JnLnczYy5kb20uQXR0ciljdXJzb3IpLmdldE93bmVyRWxlbWVudCgpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZihjdXJzb3I9PW1fcm9vdCkKLSAgICAgICAgICAgICAgICAvLyBXZSBrbm93IHRoaXMgbm9kZTsgZmluZCBpdHMgaGFuZGxlLgotICAgICAgICAgICAgICAgIHJldHVybiBnZXRIYW5kbGVGcm9tTm9kZShub2RlKTsgCi0gICAgICAgICAgICB9IC8vIGZvciBhbmNlc3RvcnMgb2Ygbm9kZQotICAgICAgICB9IC8vIGlmIG5vZGUgYW5kIG1fcm9vdCBpbiBzYW1lIERvY3VtZW50Ci0gICAgfSAvLyBpZiBub2RlIT1udWxsCi0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmVzIGFuIGF0dHJpYnV0ZSBub2RlIGJ5IGJ5IHF1YWxpZmllZCBuYW1lIGFuZCBuYW1lc3BhY2UgVVJJLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBpbnQgSGFuZGxlIG9mIHRoZSBub2RlIHVwb24gd2hpY2ggdG8gbG9vayB1cCB0aGlzIGF0dHJpYnV0ZS4uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIGF0dHJpYnV0ZSB0bwotICAgKiAgIHJldHJpZXZlLCBvciBudWxsLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUuCi0gICAqIEByZXR1cm4gVGhlIGF0dHJpYnV0ZSBub2RlIGhhbmRsZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSAoCi0gICAqICAgPGNvZGU+bm9kZU5hbWU8L2NvZGU+KSBvciA8Y29kZT5EVE0uTlVMTDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc3VjaAotICAgKiAgIGF0dHJpYnV0ZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXR0cmlidXRlTm9kZShpbnQgbm9kZUhhbmRsZSwgU3RyaW5nIG5hbWVzcGFjZVVSSSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICAvLyAlT1BUJSBUaGlzIGlzIHByb2JhYmx5IHNsb3dlciB0aGFuIGl0IG5lZWRzIHRvIGJlLgotICAgIGlmIChudWxsID09IG5hbWVzcGFjZVVSSSkKLSAgICAgIG5hbWVzcGFjZVVSSSA9ICIiOwotCi0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShub2RlSGFuZGxlKTsKLQotICAgIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotCi0gICAgICAvLyBBc3N1bWUgdGhhdCBhdHRyaWJ1dGVzIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgZWxlbWVudC4KLSAgICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAoaWRlbnRpdHkgPSBnZXROZXh0Tm9kZUlkZW50aXR5KGlkZW50aXR5KSkpCi0gICAgICB7Ci0gICAgICAgIC8vIEFzc3VtZSB0aGlzIGNhbiBub3QgYmUgbnVsbC4KLSAgICAgICAgdHlwZSA9IGdldE5vZGVUeXBlKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAodHlwZSA9PSBEVE0uQVRUUklCVVRFX05PREUpCi0gICAgICAgIHsKLSAgICAgICAgICBOb2RlIG5vZGUgPSBsb29rdXBOb2RlKGlkZW50aXR5KTsKLSAgICAgICAgICBTdHJpbmcgbm9kZXVyaSA9IG5vZGUuZ2V0TmFtZXNwYWNlVVJJKCk7Ci0KLSAgICAgICAgICBpZiAobnVsbCA9PSBub2RldXJpKQotICAgICAgICAgICAgbm9kZXVyaSA9ICIiOwotCi0gICAgICAgICAgU3RyaW5nIG5vZGVsb2NhbG5hbWUgPSBub2RlLmdldExvY2FsTmFtZSgpOwotCi0gICAgICAgICAgaWYgKG5vZGV1cmkuZXF1YWxzKG5hbWVzcGFjZVVSSSkgJiYgbmFtZS5lcXVhbHMobm9kZWxvY2FsbmFtZSkpCi0gICAgICAgICAgICByZXR1cm4gaWRlbnRpdHkgfCBtX2R0bUlkZW50OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKERUTS5OQU1FU1BBQ0VfTk9ERSAhPSB0eXBlKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlIGFzIGEgU3RyaW5nIG9iamVjdAotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0gICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLSAgICAvLyAlVEJEJSBJZiBhbiBlbGVtZW50IG9ubHkgaGFzIG9uZSB0ZXh0IG5vZGUsIHdlIHNob3VsZCBqdXN0IHVzZSBpdCAKLSAgICAvLyBkaXJlY3RseS4KLSAgICBpZihEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUgfHwgRFRNLkRPQ1VNRU5UX05PREUgPT0gdHlwZSAKLSAgICB8fCBEVE0uRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLSAgICAgIFN0cmluZyBzOwotICAKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBnZXROb2RlRGF0YShub2RlLCBidWYpOwotICAKLSAgICAgICAgcyA9IChidWYubGVuZ3RoKCkgPiAwKSA/IGJ1Zi50b1N0cmluZygpIDogIiI7Ci0gICAgICB9Ci0gICAgICBmaW5hbGx5Ci0gICAgICB7Ci0gICAgICAgIFN0cmluZ0J1ZmZlclBvb2wuZnJlZShidWYpOwotICAgICAgfQotICAKLSAgICAgIHJldHVybiBtX3hzdHJmLm5ld3N0ciggcyApOwotICAgIH0KLSAgICBlbHNlIGlmKFRFWFRfTk9ERSA9PSB0eXBlIHx8IENEQVRBX1NFQ1RJT05fTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIC8vIElmIHRoaXMgaXMgYSBEVE0gdGV4dCBub2RlLCBpdCBtYXkgYmUgbWFkZSBvZiBtdWx0aXBsZSBET00gdGV4dAotICAgICAgLy8gbm9kZXMgLS0gaW5jbHVkaW5nIG5hdmlnYXRpbmcgaW50byBFbnRpdHkgUmVmZXJlbmNlcy4gRE9NMkRUTQotICAgICAgLy8gcmVjb3JkcyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2VxdWVuY2UgYW5kIHJlcXVpcmVzIHRoYXQgd2UKLSAgICAgIC8vIHBpY2sgdXAgdGhlIG90aGVycyB3aGVuIHdlIHJldHJpZXZlIHRoZSBEVE0gbm9kZSdzIHZhbHVlLgotICAgICAgLy8KLSAgICAgIC8vICVSRVZJRVclIERPTSBMZXZlbCAzIGlzIGV4cGVjdGVkIHRvIGFkZCBhICJ3aG9sZSB0ZXh0IgotICAgICAgLy8gcmV0cmlldmFsIG1ldGhvZCB3aGljaCBwZXJmb3JtcyB0aGlzIGZ1bmN0aW9uIGZvciB1cy4KLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLSAgICAgIHdoaWxlKG5vZGUhPW51bGwpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQobm9kZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgIG5vZGU9bG9naWNhbE5leHRET01UZXh0Tm9kZShub2RlKTsKLSAgICAgIH0KLSAgICAgIFN0cmluZyBzPShidWYubGVuZ3RoKCkgPiAwKSA/IGJ1Zi50b1N0cmluZygpIDogIiI7Ci0gICAgICBTdHJpbmdCdWZmZXJQb29sLmZyZWUoYnVmKTsKLSAgICAgIHJldHVybiBtX3hzdHJmLm5ld3N0ciggcyApOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV94c3RyZi5uZXdzdHIoIG5vZGUuZ2V0Tm9kZVZhbHVlKCkgKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYSBET00gc3VidHJlZSwgYXBwZW5kaW5nIGl0IGludG8gYQotICAgKiB1c2VyLXN1cHBsaWVkIEZhc3RTdHJpbmdCdWZmZXIgb2JqZWN0LiBOb3RlIHRoYXQgYXR0cmlidXRlcyBhcmUKLSAgICogbm90IGNvbnNpZGVyZWQgcGFydCBvZiB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50LgotICAgKiA8cD4KLSAgICogVGhlcmUgYXJlIG9wZW4gcXVlc3Rpb25zIHJlZ2FyZGluZyB3aGl0ZXNwYWNlIHN0cmlwcGluZy4gCi0gICAqIEN1cnJlbnRseSB3ZSBtYWtlIG5vIHNwZWNpYWwgZWZmb3J0IGluIHRoYXQgcmVnYXJkLCBzaW5jZSB0aGUgc3RhbmRhcmQKLSAgICogRE9NIGRvZXNuJ3QgeWV0IHByb3ZpZGUgRFRELWJhc2VkIGluZm9ybWF0aW9uIHRvIGRpc3Rpbmd1aXNoCi0gICAqIHdoaXRlc3BhY2UtaW4tZWxlbWVudC1jb250ZXh0IGZyb20gZ2VudWluZSAjUENEQVRBLiBOb3RlIHRoYXQgd2UKLSAgICogc2hvdWxkIHByb2JhYmx5IGFsc28gY29uc2lkZXIgeG1sOnNwYWNlIGlmL3doZW4gd2UgYWRkcmVzcyB0aGlzLgotICAgKiBET00gTGV2ZWwgMyBtYXkgc29sdmUgdGhlIHByb2JsZW0gZm9yIHVzLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgQWN0dWFsbHksIHNpbmNlIHRoaXMgbWV0aG9kIG9wZXJhdGVzIG9uIHRoZSBET00gc2lkZSBvZiB0aGUKLSAgICogZmVuY2UgcmF0aGVyIHRoYW4gdGhlIERUTSBzaWRlLCBpdCBTSE9VTEROJ1QgZG8KLSAgICogYW55IHNwZWNpYWwgaGFuZGxpbmcuIFRoZSBET00gZG9lcyB3aGF0IHRoZSBET00gZG9lczsgaWYgeW91IHdhbnQKLSAgICogRFRNLWxldmVsIGFic3RyYWN0aW9ucywgdXNlIERUTS1sZXZlbCBtZXRob2RzLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdob3NlIHN1YnRyZWUgaXMgdG8gYmUgd2Fsa2VkLCBnYXRoZXJpbmcgdGhlCi0gICAqIGNvbnRlbnRzIG9mIGFsbCBUZXh0IG9yIENEQVRBU2VjdGlvbiBub2Rlcy4KLSAgICogQHBhcmFtIGJ1ZiBGYXN0U3RyaW5nQnVmZmVyIGludG8gd2hpY2ggdGhlIGNvbnRlbnRzIG9mIHRoZSB0ZXh0Ci0gICAqIG5vZGVzIGFyZSB0byBiZSBjb25jYXRlbmF0ZWQuCi0gICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgZ2V0Tm9kZURhdGEoTm9kZSBub2RlLCBGYXN0U3RyaW5nQnVmZmVyIGJ1ZikKLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgZm9yIChOb2RlIGNoaWxkID0gbm9kZS5nZXRGaXJzdENoaWxkKCk7IG51bGwgIT0gY2hpbGQ7Ci0gICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKSkKLSAgICAgIHsKLSAgICAgICAgZ2V0Tm9kZURhdGEoY2hpbGQsIGJ1Zik7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIGNhc2UgTm9kZS5BVFRSSUJVVEVfTk9ERSA6CS8vIE5ldmVyIGEgY2hpbGQgYnV0IG1pZ2h0IGJlIG91ciBzdGFydGluZyBub2RlCi0gICAgICBidWYuYXBwZW5kKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgICAvLyB3YXJuaW5nKFhQQVRIRXJyb3JSZXNvdXJjZXMuV0dfUEFSU0lOR19BTkRfUFJFUEFSSU5HKTsgICAgICAgIAotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICAvLyBpZ25vcmUKLSAgICAgIGJyZWFrOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIERPTS1zdHlsZSBub2RlIG5hbWUuIFRoaXMgd2lsbAotICAgKiBpbmNsdWRlIG5hbWVzIHN1Y2ggYXMgI3RleHQgb3IgI2RvY3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgKiAlUkVWSUVXJSBEb2N1bWVudCB3aGVuIGVtcHR5IHN0cmluZyBpcyBwb3NzaWJsZS4uLgotICAgKiAlUkVWSUVXLUNPTU1FTlQlIEl0IHNob3VsZCBuZXZlciBiZSBlbXB0eSwgc2hvdWxkIGl0PwotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLQotICAgIC8vIEFzc3VtZSBub24tbnVsbC4KLSAgICByZXR1cm4gbm9kZS5nZXROb2RlTmFtZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgWFBhdGggbm9kZSBuYW1lLiAgVGhpcyBzaG91bGQgYmUKLSAgICogdGhlIG5hbWUgYXMgZGVzY3JpYmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsLCBOT1QgdGhlIERPTS1zdHlsZQotICAgKiBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIFN0cmluZyBuYW1lOwotICAgIHNob3J0IHR5cGUgPSBnZXROb2RlVHlwZShub2RlSGFuZGxlKTsKLQotICAgIHN3aXRjaCAodHlwZSkKLSAgICB7Ci0gICAgY2FzZSBEVE0uTkFNRVNQQUNFX05PREUgOgotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0KLSAgICAgIC8vIGFzc3VtZSBub3QgbnVsbC4KLSAgICAgIG5hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7Ci0gICAgICBpZihuYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKQotICAgICAgewotICAgICAgICBuYW1lID0gUU5hbWUuZ2V0TG9jYWxQYXJ0KG5hbWUpOwotICAgICAgfQotICAgICAgZWxzZSBpZihuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgIHsKLSAgICAgICAgbmFtZSA9ICIiOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICBjYXNlIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgIGNhc2UgRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgewotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLQotICAgICAgLy8gYXNzdW1lIG5vdCBudWxsLgotICAgICAgbmFtZSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKTsKLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBuYW1lID0gIiI7Ci0gICAgfQotCi0gICAgcmV0dXJuIG5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBYUGF0aC1zdHlsZSBsb2NhbG5hbWUuCi0gICAqIChBcyBkZWZpbmVkIGluIE5hbWVzcGFjZXMsIHRoaXMgaXMgdGhlIHBvcnRpb24gb2YgdGhlIG5hbWUgYWZ0ZXIgYW55Ci0gICAqIGNvbG9uIGNoYXJhY3RlcikuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgTG9jYWwgbmFtZSBvZiB0aGlzIG5vZGUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExvY2FsTmFtZShpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgU3RyaW5nIG5hbWU7Ci0gICAgc2hvcnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLSAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICBjYXNlIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0KLSAgICAgIC8vIGFzc3VtZSBub3QgbnVsbC4KLSAgICAgIG5hbWUgPSBub2RlLmdldExvY2FsTmFtZSgpOwotCi0gICAgICBpZiAobnVsbCA9PSBuYW1lKQotICAgICAgewotICAgICAgICBTdHJpbmcgcW5hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7Ci0gICAgICAgIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgICAgICBuYW1lID0gKGluZGV4IDwgMCkgPyBxbmFtZSA6IHFuYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOwotICAgICAgfQotICAgIH0KLSAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIG5hbWUgPSAiIjsKLSAgICB9Ci0KLSAgICByZXR1cm4gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHRoYXQgdGhlIG5hbWVzcGFjZSBkZWNsIGlzCi0gICAqIG1hcHBpbmcuCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgcHJlZml4IHVzZWQgdG8gbWFwIHRvIHRoZSBuYW1lc3BhY2UuCi0gICAqCi0gICAqIDxwPiAlUkVWSUVXJSBBcmUgeW91IHN1cmUgeW91IHdhbnQgIiIgZm9yIG5vIHByZWZpeD8gIDwvcD4KLSAgICogPHA+ICVSRVZJRVctQ09NTUVOVCUgSSB0aGluayBzby4uLiBub3QgdG90YWxseSBzdXJlLiAtc2IgIDwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBwcmVmaXggb2YgdGhpcyBub2RlJ3MgbmFtZSwgb3IgIiIgaWYgbm8gZXhwbGljaXQKLSAgICogbmFtZXNwYWNlIHByZWZpeCB3YXMgZ2l2ZW4uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeChpbnQgbm9kZUhhbmRsZSkKLSAgewotCi0gICAgU3RyaW5nIHByZWZpeDsKLSAgICBzaG9ydCB0eXBlID0gZ2V0Tm9kZVR5cGUobm9kZUhhbmRsZSk7Ci0KLSAgICBzd2l0Y2ggKHR5cGUpCi0gICAgewotICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBnZXROb2RlKG5vZGVIYW5kbGUpOwotCi0gICAgICAvLyBhc3N1bWUgbm90IG51bGwuCi0gICAgICBTdHJpbmcgcW5hbWUgPSBub2RlLmdldE5vZGVOYW1lKCk7Ci0gICAgICBpbnQgaW5kZXggPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgIHByZWZpeCA9IChpbmRleCA8IDApID8gIiIgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgY2FzZSBEVE0uQVRUUklCVVRFX05PREUgOgotICAgIGNhc2UgRFRNLkVMRU1FTlRfTk9ERSA6Ci0gICAgewotICAgICAgTm9kZSBub2RlID0gZ2V0Tm9kZShub2RlSGFuZGxlKTsKLQotICAgICAgLy8gYXNzdW1lIG5vdCBudWxsLgotICAgICAgU3RyaW5nIHFuYW1lID0gbm9kZS5nZXROb2RlTmFtZSgpOwotICAgICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgICBwcmVmaXggPSAoaW5kZXggPCAwKSA/ICIiIDogcW5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBwcmVmaXggPSAiIjsKLSAgICB9Ci0KLSAgICByZXR1cm4gcHJlZml4OwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgRE9NLXN0eWxlIG5hbWVzcGFjZSBVUkkKLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgZGVjbGFyZWQgVVJJIHdoaWNoIHRoaXMgbm9kZSdzCi0gICAqIHByZWZpeCAtLSBvciBkZWZhdWx0IGluIGxpZXUgdGhlcmVvZiAtLSB3YXMgbWFwcGVkIHRvLikKLSAgICoKLSAgICogPHA+JVJFVklFVyUgTnVsbCBvciAiIj8gLXNiPC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIFVSSSB2YWx1ZSBvZiB0aGlzIG5vZGUncyBuYW1lc3BhY2UsIG9yIG51bGwgaWYgbm8KLSAgICogbmFtZXNwYWNlIHdhcyByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlVVJJKGludCBub2RlSGFuZGxlKQotICB7Ci0KLSAgICBTdHJpbmcgbnN1cmk7Ci0gICAgc2hvcnQgdHlwZSA9IGdldE5vZGVUeXBlKG5vZGVIYW5kbGUpOwotCi0gICAgc3dpdGNoICh0eXBlKQotICAgIHsKLSAgICBjYXNlIERUTS5BVFRSSUJVVEVfTk9ERSA6Ci0gICAgY2FzZSBEVE0uRUxFTUVOVF9OT0RFIDoKLSAgICBjYXNlIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgIGNhc2UgRFRNLk5BTUVTUEFDRV9OT0RFIDoKLSAgICBjYXNlIERUTS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0KLSAgICAgIC8vIGFzc3VtZSBub3QgbnVsbC4KLSAgICAgIG5zdXJpID0gbm9kZS5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgLy8gJVRCRCUgSGFuZGxlIERPTTE/Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgbnN1cmkgPSBudWxsOwotICAgIH0KLQotICAgIHJldHVybiBuc3VyaTsKLSAgfQotICAKLSAgLyoqIFV0aWxpdHkgZnVuY3Rpb246IEdpdmVuIGEgRE9NIFRleHQgbm9kZSwgZGV0ZXJtaW5lIHdoZXRoZXIgaXQgaXMKLSAgICogbG9naWNhbGx5IGZvbGxvd2VkIGJ5IGFub3RoZXIgVGV4dCBvciBDREFUQVNlY3Rpb24gbm9kZS4gVGhpcyBtYXkKLSAgICogaW52b2x2ZSB0cmF2ZXJzaW5nIGludG8gRW50aXR5IFJlZmVyZW5jZXMuCi0gICAqIAotICAgKiAlUkVWSUVXJSBET00gTGV2ZWwgMyBpcyBleHBlY3RlZCB0byBhZGQgZnVuY3Rpb25hbGl0eSB3aGljaCBtYXkgCi0gICAqIGFsbG93IHVzIHRvIHJldGlyZSB0aGlzLgotICAgKi8KLSAgcHJpdmF0ZSBOb2RlIGxvZ2ljYWxOZXh0RE9NVGV4dE5vZGUoTm9kZSBuKQotICB7Ci0gICAgICAgIE5vZGUgcD1uLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgIGlmKHA9PW51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBXYWxrIG91dCBvZiBhbnkgRW50aXR5UmVmZXJlbmNlTm9kZXMgdGhhdCBlbmRlZCB3aXRoIHRleHQKLSAgICAgICAgICAgICAgICBmb3Iobj1uLmdldFBhcmVudE5vZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG4hPW51bGwgJiYgRU5USVRZX1JFRkVSRU5DRV9OT0RFID09IG4uZ2V0Tm9kZVR5cGUoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG49bi5nZXRQYXJlbnROb2RlKCkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcD1uLmdldE5leHRTaWJsaW5nKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZihwIT1udWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgbj1wOwotICAgICAgICB3aGlsZShuIT1udWxsICYmIEVOVElUWV9SRUZFUkVOQ0VfTk9ERSA9PSBuLmdldE5vZGVUeXBlKCkpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBXYWxrIGludG8gYW55IEVudGl0eVJlZmVyZW5jZU5vZGVzIHRoYXQgc3RhcnQgd2l0aCB0ZXh0Ci0gICAgICAgICAgICAgICAgaWYobi5oYXNDaGlsZE5vZGVzKCkpCi0gICAgICAgICAgICAgICAgICAgICAgICBuPW4uZ2V0Rmlyc3RDaGlsZCgpOwotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgICAgIG49bi5nZXROZXh0U2libGluZygpOwotICAgICAgICB9Ci0gICAgICAgIGlmKG4hPW51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICAgICAgICAvLyBGb3VuZCBhIGxvZ2ljYWwgbmV4dCBzaWJsaW5nLiBJcyBpdCB0ZXh0PwotICAgICAgICAgICAgICAgIGludCBudHlwZT1uLmdldE5vZGVUeXBlKCk7Ci0gICAgICAgICAgICAgICAgaWYoVEVYVF9OT0RFICE9IG50eXBlICYmIENEQVRBX1NFQ1RJT05fTk9ERSAhPSBudHlwZSkKLSAgICAgICAgICAgICAgICAgICAgICAgIG49bnVsbDsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIG5vZGUgdmFsdWUuIFRoaXMgaXMgbW9zdGx5Ci0gICAqIGFzIGRlZmluZWQgYnkgdGhlIERPTSwgYnV0IG1heSBpZ25vcmUgc29tZSBjb252ZW5pZW5jZXMuCi0gICAqIDxwPgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBpZC4KLSAgICogQHJldHVybiBTdHJpbmcgVmFsdWUgb2YgdGhpcyBub2RlLCBvciBudWxsIGlmIG5vdAotICAgKiBtZWFuaW5nZnVsIGZvciB0aGlzIG5vZGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgaW50IHR5cGU9X3R5cGUobm9kZUhhbmRsZSk7Ci0gICAgaWYoVEVYVF9OT0RFIT10eXBlICYmIENEQVRBX1NFQ1RJT05fTk9ERSE9dHlwZSkKLSAgICAgIHJldHVybiBnZXROb2RlKG5vZGVIYW5kbGUpLmdldE5vZGVWYWx1ZSgpOwotICAgIAotICAgIC8vIElmIHRoaXMgaXMgYSBEVE0gdGV4dCBub2RlLCBpdCBtYXkgYmUgbWFkZSBvZiBtdWx0aXBsZSBET00gdGV4dAotICAgIC8vIG5vZGVzIC0tIGluY2x1ZGluZyBuYXZpZ2F0aW5nIGludG8gRW50aXR5IFJlZmVyZW5jZXMuIERPTTJEVE0KLSAgICAvLyByZWNvcmRzIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXF1ZW5jZSBhbmQgcmVxdWlyZXMgdGhhdCB3ZQotICAgIC8vIHBpY2sgdXAgdGhlIG90aGVycyB3aGVuIHdlIHJldHJpZXZlIHRoZSBEVE0gbm9kZSdzIHZhbHVlLgotICAgIC8vCi0gICAgLy8gJVJFVklFVyUgRE9NIExldmVsIDMgaXMgZXhwZWN0ZWQgdG8gYWRkIGEgIndob2xlIHRleHQiCi0gICAgLy8gcmV0cmlldmFsIG1ldGhvZCB3aGljaCBwZXJmb3JtcyB0aGlzIGZ1bmN0aW9uIGZvciB1cy4KLSAgICBOb2RlIG5vZGUgPSBnZXROb2RlKG5vZGVIYW5kbGUpOwotICAgIE5vZGUgbj1sb2dpY2FsTmV4dERPTVRleHROb2RlKG5vZGUpOwotICAgIGlmKG49PW51bGwpCi0gICAgICByZXR1cm4gbm9kZS5nZXROb2RlVmFsdWUoKTsKLSAgICAKLSAgICBGYXN0U3RyaW5nQnVmZmVyIGJ1ZiA9IFN0cmluZ0J1ZmZlclBvb2wuZ2V0KCk7Ci0gICAgICAgIGJ1Zi5hcHBlbmQobm9kZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgd2hpbGUobiE9bnVsbCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKG4uZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgbj1sb2dpY2FsTmV4dERPTVRleHROb2RlKG4pOwotICAgIH0KLSAgICBTdHJpbmcgcyA9IChidWYubGVuZ3RoKCkgPiAwKSA/IGJ1Zi50b1N0cmluZygpIDogIiI7Ci0gICAgU3RyaW5nQnVmZmVyUG9vbC5mcmVlKGJ1Zik7Ci0gICAgcmV0dXJuIHM7Ci0gIH0KLQotICAvKioKLSAgICogICBBIGRvY3VtZW50IHR5cGUgZGVjbGFyYXRpb24gaW5mb3JtYXRpb24gaXRlbSBoYXMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgotICAgKgotICAgKiAgICAgMS4gW3N5c3RlbSBpZGVudGlmaWVyXSBUaGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGV4dGVybmFsIHN1YnNldCwgaWYKLSAgICogICAgICAgIGl0IGV4aXN0cy4gT3RoZXJ3aXNlIHRoaXMgcHJvcGVydHkgaGFzIG5vIHZhbHVlLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uU3lzdGVtSWRlbnRpZmllcigpCi0gIHsKLQotICAgIERvY3VtZW50IGRvYzsKLQotICAgIGlmIChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICBkb2MgPSAoRG9jdW1lbnQpIG1fcm9vdDsKLSAgICBlbHNlCi0gICAgICBkb2MgPSBtX3Jvb3QuZ2V0T3duZXJEb2N1bWVudCgpOwotCi0gICAgaWYgKG51bGwgIT0gZG9jKQotICAgIHsKLSAgICAgIERvY3VtZW50VHlwZSBkdGQgPSBkb2MuZ2V0RG9jdHlwZSgpOwotCi0gICAgICBpZiAobnVsbCAhPSBkdGQpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBkdGQuZ2V0U3lzdGVtSWQoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBleHRlcm5hbCBzdWJzZXQsCi0gICAqIG5vcm1hbGl6ZWQgYXMgZGVzY3JpYmVkIGluIDQuMi4yIEV4dGVybmFsIEVudGl0aWVzIFtYTUxdLiBJZiB0aGVyZSBpcwotICAgKiBubyBleHRlcm5hbCBzdWJzZXQgb3IgaWYgaXQgaGFzIG5vIHB1YmxpYyBpZGVudGlmaWVyLCB0aGlzIHByb3BlcnR5Ci0gICAqIGhhcyBubyB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIHRoZSBkb2N1bWVudCB0eXBlIGRlY2xhcmF0aW9uIGhhbmRsZQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBTdHJpbmcgb2JqZWN0LCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldERvY3VtZW50VHlwZURlY2xhcmF0aW9uUHVibGljSWRlbnRpZmllcigpCi0gIHsKLQotICAgIERvY3VtZW50IGRvYzsKLQotICAgIGlmIChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpCi0gICAgICBkb2MgPSAoRG9jdW1lbnQpIG1fcm9vdDsKLSAgICBlbHNlCi0gICAgICBkb2MgPSBtX3Jvb3QuZ2V0T3duZXJEb2N1bWVudCgpOwotCi0gICAgaWYgKG51bGwgIT0gZG9jKQotICAgIHsKLSAgICAgIERvY3VtZW50VHlwZSBkdGQgPSBkb2MuZ2V0RG9jdHlwZSgpOwotCi0gICAgICBpZiAobnVsbCAhPSBkdGQpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBkdGQuZ2V0UHVibGljSWQoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpCi0gIHsKLQotICAgIERvY3VtZW50IGRvYyA9IChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpIAotICAgICAgICA/IChEb2N1bWVudCkgbV9yb290IDogbV9yb290LmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgCi0gICAgaWYobnVsbCAhPSBkb2MpCi0gICAgewotICAgICAgTm9kZSBlbGVtID0gZG9jLmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7Ci0gICAgICBpZihudWxsICE9IGVsZW0pCi0gICAgICB7Ci0gICAgICAgIGludCBlbGVtSGFuZGxlID0gZ2V0SGFuZGxlRnJvbU5vZGUoZWxlbSk7Ci0gICAgICAgIAotICAgICAgICBpZihEVE0uTlVMTCA9PSBlbGVtSGFuZGxlKQotICAgICAgICB7Ci0gICAgICAgICAgaW50IGlkZW50aXR5ID0gbV9ub2Rlcy5zaXplKCktMTsKLSAgICAgICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKGlkZW50aXR5ID0gZ2V0TmV4dE5vZGVJZGVudGl0eShpZGVudGl0eSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUoaWRlbnRpdHkpOwotICAgICAgICAgICAgaWYobm9kZSA9PSBlbGVtKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBlbGVtSGFuZGxlID0gZ2V0SGFuZGxlRnJvbU5vZGUoZWxlbSk7Ci0gICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgfQotICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgCi0gICAgICAgIHJldHVybiBlbGVtSGFuZGxlOwotICAgICAgfQotICAgIAotICAgIH0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGdldFVucGFyc2VkRW50aXR5VVJJIGZ1bmN0aW9uIHJldHVybnMgdGhlIFVSSSBvZiB0aGUgdW5wYXJzZWQKLSAgICogZW50aXR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZSBjb250ZXh0Ci0gICAqIG5vZGUgKHNlZSBbMy4zIFVucGFyc2VkIEVudGl0aWVzXSkuIEl0IHJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgKiB0aGVyZSBpcyBubyBzdWNoIGVudGl0eS4KLSAgICogPHA+Ci0gICAqIFhNTCBwcm9jZXNzb3JzIG1heSBjaG9vc2UgdG8gdXNlIHRoZSBTeXN0ZW0gSWRlbnRpZmllciAoaWYgb25lCi0gICAqIGlzIHByb3ZpZGVkKSB0byByZXNvbHZlIHRoZSBlbnRpdHksIHJhdGhlciB0aGFuIHRoZSBVUkkgaW4gdGhlCi0gICAqIFB1YmxpYyBJZGVudGlmaWVyLiBUaGUgZGV0YWlscyBhcmUgZGVwZW5kZW50IG9uIHRoZSBwcm9jZXNzb3IsIGFuZAotICAgKiB3ZSB3b3VsZCBoYXZlIHRvIHN1cHBvcnQgc29tZSBmb3JtIG9mIHBsdWctaW4gcmVzb2x2ZXIgdG8gaGFuZGxlCi0gICAqIHRoaXMgcHJvcGVybHkuIEN1cnJlbnRseSwgd2Ugc2ltcGx5IHJldHVybiB0aGUgU3lzdGVtIElkZW50aWZpZXIgaWYKLSAgICogcHJlc2VudCwgYW5kIGhvcGUgdGhhdCBpdCBhIHVzYWJsZSBVUkkgb3IgdGhhdCBvdXIgY2FsbGVyIGNhbgotICAgKiBtYXAgaXQgdG8gb25lLgotICAgKiBUT0RPOiBSZXNvbHZlIFB1YmxpYyBJZGVudGlmaWVycy4uLiBvciBjb25zaWRlciBjaGFuZ2luZyBmdW5jdGlvbiBuYW1lLgotICAgKiA8cD4KLSAgICogSWYgd2UgZmluZCBhIHJlbGF0aXZlIFVSSQotICAgKiByZWZlcmVuY2UsIFhNTCBleHBlY3RzIGl0IHRvIGJlIHJlc29sdmVkIGluIHRlcm1zIG9mIHRoZSBiYXNlIFVSSQotICAgKiBvZiB0aGUgZG9jdW1lbnQuIFRoZSBET00gZG9lc24ndCBkbyB0aGF0IGZvciB1cywgYW5kIGl0IGlzbid0Ci0gICAqIGVudGlyZWx5IGNsZWFyIHdoZXRoZXIgdGhhdCBzaG91bGQgYmUgZG9uZSBoZXJlOyBjdXJyZW50bHkgdGhhdCdzCi0gICAqIHB1c2hlZCB1cCB0byBhIGhpZ2hlciBsZXZlbCBvZiBvdXIgYXBwbGljYXRpb24uIChOb3RlIHRoYXQgRE9NIExldmVsCi0gICAqIDEgZGlkbid0IHN0b3JlIHRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLikKLSAgICogVE9ETzogQ29uc2lkZXIgcmVzb2x2aW5nIFJlbGF0aXZlIFVSSXMuCi0gICAqIDxwPgotICAgKiAoVGhlIERPTSdzIHN0YXRlbWVudCB0aGF0ICJBbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8KLSAgICogY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgaXMgcGFzc2VkCi0gICAqIHRvIHRoZSBET00iIHJlZmVycyBvbmx5IHRvIHBhcnNlZCBlbnRpdGllcywgbm90IHVucGFyc2VkLCBhbmQgaGVuY2UKLSAgICogZG9lc24ndCBhZmZlY3QgdGhpcyBmdW5jdGlvbi4pCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIEVudGl0eSBOYW1lIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIFVSSSBvZiB0aGUgVW5wYXJzZWQgRW50aXR5LCBvciBhbgotICAgKiBlbXB0eSBzdHJpbmcgaWYgbm8gc3VjaCBlbnRpdHkgZXhpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVbnBhcnNlZEVudGl0eVVSSShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgU3RyaW5nIHVybCA9ICIiOwotICAgIERvY3VtZW50IGRvYyA9IChtX3Jvb3QuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpIAotICAgICAgICA/IChEb2N1bWVudCkgbV9yb290IDogbV9yb290LmdldE93bmVyRG9jdW1lbnQoKTsKLQotICAgIGlmIChudWxsICE9IGRvYykKLSAgICB7Ci0gICAgICBEb2N1bWVudFR5cGUgZG9jdHlwZSA9IGRvYy5nZXREb2N0eXBlKCk7Ci0gIAotICAgICAgaWYgKG51bGwgIT0gZG9jdHlwZSkKLSAgICAgIHsKLSAgICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzID0gZG9jdHlwZS5nZXRFbnRpdGllcygpOwotICAgICAgICBpZihudWxsID09IGVudGl0aWVzKQotICAgICAgICAgIHJldHVybiB1cmw7Ci0gICAgICAgIEVudGl0eSBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW0obmFtZSk7Ci0gICAgICAgIGlmKG51bGwgPT0gZW50aXR5KQotICAgICAgICAgIHJldHVybiB1cmw7Ci0gICAgICAgIAotICAgICAgICBTdHJpbmcgbm90YXRpb25OYW1lID0gZW50aXR5LmdldE5vdGF0aW9uTmFtZSgpOwotICAKLSAgICAgICAgaWYgKG51bGwgIT0gbm90YXRpb25OYW1lKSAgLy8gdGhlbiBpdCdzIHVucGFyc2VkCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBUaGUgZHJhZnQgc2F5czogIlRoZSBYU0xUIHByb2Nlc3NvciBtYXkgdXNlIHRoZSBwdWJsaWMgCi0gICAgICAgICAgLy8gaWRlbnRpZmllciB0byBnZW5lcmF0ZSBhIFVSSSBmb3IgdGhlIGVudGl0eSBpbnN0ZWFkIG9mIHRoZSBVUkkgCi0gICAgICAgICAgLy8gc3BlY2lmaWVkIGluIHRoZSBzeXN0ZW0gaWRlbnRpZmllci4gSWYgdGhlIFhTTFQgcHJvY2Vzc29yIGRvZXMgCi0gICAgICAgICAgLy8gbm90IHVzZSB0aGUgcHVibGljIGlkZW50aWZpZXIgdG8gZ2VuZXJhdGUgdGhlIFVSSSwgaXQgbXVzdCB1c2UgCi0gICAgICAgICAgLy8gdGhlIHN5c3RlbSBpZGVudGlmaWVyOyBpZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSByZWxhdGl2ZSAKLSAgICAgICAgICAvLyBVUkksIGl0IG11c3QgYmUgcmVzb2x2ZWQgaW50byBhbiBhYnNvbHV0ZSBVUkkgdXNpbmcgdGhlIFVSSSBvZiAKLSAgICAgICAgICAvLyB0aGUgcmVzb3VyY2UgY29udGFpbmluZyB0aGUgZW50aXR5IGRlY2xhcmF0aW9uIGFzIHRoZSBiYXNlIAotICAgICAgICAgIC8vIFVSSSBbUkZDMjM5Nl0uIgotICAgICAgICAgIC8vIFNvIEknbSBmYWxsaW5nIGEgYml0IHNob3J0IGhlcmUuCi0gICAgICAgICAgdXJsID0gZW50aXR5LmdldFN5c3RlbUlkKCk7Ci0gIAotICAgICAgICAgIGlmIChudWxsID09IHVybCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB1cmwgPSBlbnRpdHkuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIHJlc29sdmVkIHRvIGFuIGFic29sdXRlIFVSTCwgYnV0IHRoYXQncyBoYXJkIAotICAgICAgICAgICAgLy8gdG8gZG8gZnJvbSBoZXJlLgotICAgICAgICAgIH0gICAgICAgIAotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHVybDsKLSAgfQotCi0gIC8qKgotICAgKiAgICAgNS4gW3NwZWNpZmllZF0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIGF0dHJpYnV0ZSB3YXMgYWN0dWFsbHkKLSAgICogICAgICAgIHNwZWNpZmllZCBpbiB0aGUgc3RhcnQtdGFnIG9mIGl0cyBlbGVtZW50LCBvciB3YXMgZGVmYXVsdGVkIGZyb20gdGhlCi0gICAqICAgICAgICBEVEQuCi0gICAqCi0gICAqIEBwYXJhbSB0aGUgYXR0cmlidXRlIGhhbmRsZQotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gYXR0cmlidXRlSGFuZGxlCi0gICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGF0dHJpYnV0ZSB3YXMgc3BlY2lmaWVkOwotICAgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCB3YXMgZGVmYXVsdGVkLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNBdHRyaWJ1dGVTcGVjaWZpZWQoaW50IGF0dHJpYnV0ZUhhbmRsZSkKLSAgewotICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGUoYXR0cmlidXRlSGFuZGxlKTsKLQotICAgIGlmIChEVE0uQVRUUklCVVRFX05PREUgPT0gdHlwZSkKLSAgICB7Ci0gICAgICBBdHRyIGF0dHIgPSAoQXR0cilnZXROb2RlKGF0dHJpYnV0ZUhhbmRsZSk7Ci0gICAgICByZXR1cm4gYXR0ci5nZXRTcGVjaWZpZWQoKTsKLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqIEJpbmQgYW4gSW5jcmVtZW50YWxTQVhTb3VyY2UgdG8gdGhpcyBEVE0uIE5PVCBSRUxFVkFOVCBmb3IgRE9NMkRUTSwgc2luY2UKLSAgICogd2UncmUgd3JhcHBlZCBhcm91bmQgYW4gZXhpc3RpbmcgRE9NLgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSB0aGF0IHdlIHdhbnQgdG8gcmVjaWV2ZSBldmVudHMgZnJvbQotICAgKiBvbiBkZW1hbmQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbmNyZW1lbnRhbFNBWFNvdXJjZShJbmNyZW1lbnRhbFNBWFNvdXJjZSBzb3VyY2UpCi0gIHsKLSAgfQotICAKLSAgLyoqIGdldENvbnRlbnRIYW5kbGVyIHJldHVybnMgIm91ciBTQVggYnVpbGRlciIgLS0gdGhlIHRoaW5nIHRoYXQKLSAgICogc29tZW9uZSBlbHNlIHNob3VsZCBzZW5kIFNBWCBldmVudHMgdG8gaW4gb3JkZXIgdG8gZXh0ZW5kIHRoaXMKLSAgICogRFRNIG1vZGVsLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGV2ZW50cywKLSAgICogInRoaXMiIGlmIHRoZSBEVE0gb2JqZWN0IGhhcyBhIGJ1aWx0LWluIFNBWCBDb250ZW50SGFuZGxlciwKLSAgICogdGhlIEluY3JtZW50YWxTQVhTb3VyY2UgaWYgd2UncmUgYm91bmQgdG8gb25lIGFuZCBzaG91bGQgcmVjZWl2ZQotICAgKiB0aGUgU0FYIHN0cmVhbSB2aWEgaXQgZm9yIGluY3JlbWVudGFsIGJ1aWxkIHB1cnBvc2VzLi4uCi0gICAqICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpCi0gIHsKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgbGV4aWNhbCBoYW5kbGVyLgotICAgKgotICAgKiAlUkVWSUVXJSBTaG91bGQgdGhpcyByZXR1cm4gbnVsbCBpZiBjb25zdHJ1dGlvbiBhbHJlYWR5IGRvbmUvYmVndW4/Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBsZXhpY2FsIFNBWCBldmVudHMsCi0gICAqICJ0aGlzIiBpZiB0aGUgRFRNIG9iamVjdCBoYXMgYSBidWlsdC1pbiBTQVggQ29udGVudEhhbmRsZXIsCi0gICAqIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBpZiB3ZSdyZSBib3VuZCB0byBvbmUgYW5kIHNob3VsZCByZWNlaXZlCi0gICAqIHRoZSBTQVggc3RyZWFtIHZpYSBpdCBmb3IgaW5jcmVtZW50YWwgYnVpbGQgcHVycG9zZXMuLi4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgZ2V0TGV4aWNhbEhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIAotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRW50aXR5UmVzb2x2ZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZW50aXR5IHJlZiBldmVudHMuCi0gICAqLwotICBwdWJsaWMgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIgZ2V0RW50aXR5UmVzb2x2ZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERUREhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZHRkIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBvcmcueG1sLnNheC5EVERIYW5kbGVyIGdldERUREhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBFcnJvckhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZXJyb3IgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciBnZXRFcnJvckhhbmRsZXIoKQotICB7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERlY2xIYW5kbGVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIERlY2wgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciBnZXREZWNsSGFuZGxlcigpCi0gIHsKLQotICAgIHJldHVybiBudWxsOwotICB9ICAKLQotICAvKiogQHJldHVybiB0cnVlIGlmZiB3ZSdyZSBidWlsZGluZyB0aGlzIG1vZGVsIGluY3JlbWVudGFsbHkgKGVnCi0gICAqIHdlJ3JlIHBhcnRuZXJlZCB3aXRoIGEgSW5jcmVtZW50YWxTQVhTb3VyY2UpIGFuZCB0aHVzIHJlcXVpcmUgdGhhdCB0aGUKLSAgICogdHJhbnNmb3JtYXRpb24gYW5kIHRoZSBwYXJzZSBydW4gc2ltdWx0YW5lb3VzbHkuIEd1aWRhbmNlIHRvIHRoZQotICAgKiBEVE1NYW5hZ2VyLgotICAgKiAqLwotICBwdWJsaWMgYm9vbGVhbiBuZWVkc1R3b1RocmVhZHMoKQotICB7Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLy8gPT09PT09PT09PSBEaXJlY3QgU0FYIERpc3BhdGNoLCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzID09PT09PT09Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgPHZhcj5jaDwvdmFyPiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uCi0gICAqIG9mIHdoaXRlc3BhY2UuICBSZWZlciB0byA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy14bWwtMTk5ODAyMTAjTlQtUyI+Ci0gICAqIHRoZSBkZWZpbml0aW9uIG9mIDxDT0RFPlM8L0NPREU+PC9BPiBmb3IgZGV0YWlscy4KLSAgICogQHBhcmFtICAgY2ggICAgICBDaGFyYWN0ZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gICAgICAgICAgPXRydWUgaWYgPHZhcj5jaDwvdmFyPiBpcyBYTUwgd2hpdGVzcGFjZTsgb3RoZXJ3aXNlID1mYWxzZS4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShjaGFyIGNoKQotICB7Ci0gICAgcmV0dXJuIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoKTsgIC8vIFRha2UgdGhlIGVhc3kgd2F5IG91dCBmb3Igbm93LgotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cygKLSAgICAgICAgICBpbnQgbm9kZUhhbmRsZSwgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsIAotICAgICAgICAgIGJvb2xlYW4gbm9ybWFsaXplKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYobm9ybWFsaXplKQotICAgIHsKLSAgICAgIFhNTFN0cmluZyBzdHIgPSBnZXRTdHJpbmdWYWx1ZShub2RlSGFuZGxlKTsKLSAgICAgIHN0ciA9IHN0ci5maXhXaGl0ZVNwYWNlKHRydWUsIHRydWUsIGZhbHNlKTsKLSAgICAgIHN0ci5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoY2gpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShub2RlSGFuZGxlKTsKLSAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0gICAgICBkaXNwYXRjaE5vZGVEYXRhKG5vZGUsIGNoLCAwKTsKLSAgICAgICAgICAvLyBUZXh0IGNvYWxpdGlvbiAtLSBhIERUTSB0ZXh0IG5vZGUgbWF5IHJlcHJlc2VudCBtdWx0aXBsZQotICAgICAgICAgIC8vIERPTSBub2Rlcy4KLSAgICAgICAgICBpZihURVhUX05PREUgPT0gdHlwZSB8fCBDREFUQV9TRUNUSU9OX05PREUgPT0gdHlwZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICB3aGlsZSggbnVsbCAhPSAobm9kZT1sb2dpY2FsTmV4dERPTVRleHROb2RlKG5vZGUpKSApCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hOb2RlRGF0YShub2RlLCBjaCwgMCk7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYSBET00gc3VidHJlZSwgYXBwZW5kaW5nIGl0IGludG8gYQotICAgKiB1c2VyLXN1cHBsaWVkIEZhc3RTdHJpbmdCdWZmZXIgb2JqZWN0LiBOb3RlIHRoYXQgYXR0cmlidXRlcyBhcmUKLSAgICogbm90IGNvbnNpZGVyZWQgcGFydCBvZiB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50LgotICAgKiA8cD4KLSAgICogVGhlcmUgYXJlIG9wZW4gcXVlc3Rpb25zIHJlZ2FyZGluZyB3aGl0ZXNwYWNlIHN0cmlwcGluZy4gCi0gICAqIEN1cnJlbnRseSB3ZSBtYWtlIG5vIHNwZWNpYWwgZWZmb3J0IGluIHRoYXQgcmVnYXJkLCBzaW5jZSB0aGUgc3RhbmRhcmQKLSAgICogRE9NIGRvZXNuJ3QgeWV0IHByb3ZpZGUgRFRELWJhc2VkIGluZm9ybWF0aW9uIHRvIGRpc3Rpbmd1aXNoCi0gICAqIHdoaXRlc3BhY2UtaW4tZWxlbWVudC1jb250ZXh0IGZyb20gZ2VudWluZSAjUENEQVRBLiBOb3RlIHRoYXQgd2UKLSAgICogc2hvdWxkIHByb2JhYmx5IGFsc28gY29uc2lkZXIgeG1sOnNwYWNlIGlmL3doZW4gd2UgYWRkcmVzcyB0aGlzLgotICAgKiBET00gTGV2ZWwgMyBtYXkgc29sdmUgdGhlIHByb2JsZW0gZm9yIHVzLgotICAgKiA8cD4KLSAgICogJVJFVklFVyUgTm90ZSB0aGF0IGFzIGEgRE9NLWxldmVsIG9wZXJhdGlvbiwgaXQgY2FuIGJlIGFyZ3VlZCB0aGF0IHRoaXMKLSAgICogcm91dGluZSBfc2hvdWxkbid0XyBwZXJmb3JtIGFueSBwcm9jZXNzaW5nIGJleW9uZCB3aGF0IHRoZSBET00gYWxyZWFkeQotICAgKiBkb2VzLCBhbmQgdGhhdCB3aGl0ZXNwYWNlIHN0cmlwcGluZyBhbmQgc28gb24gYmVsb25nIGF0IHRoZSBEVE0gbGV2ZWwuCi0gICAqIElmIHlvdSB3YW50IGEgc3RyaXBwZWQgRE9NIHZpZXcsIHdyYXAgRFRNMkRPTSBhcm91bmQgRE9NMkRUTS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB3aG9zZSBzdWJ0cmVlIGlzIHRvIGJlIHdhbGtlZCwgZ2F0aGVyaW5nIHRoZQotICAgKiBjb250ZW50cyBvZiBhbGwgVGV4dCBvciBDREFUQVNlY3Rpb24gbm9kZXMuCi0gICAqIEBwYXJhbSBidWYgRmFzdFN0cmluZ0J1ZmZlciBpbnRvIHdoaWNoIHRoZSBjb250ZW50cyBvZiB0aGUgdGV4dAotICAgKiBub2RlcyBhcmUgdG8gYmUgY29uY2F0ZW5hdGVkLgotICAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGRpc3BhdGNoTm9kZURhdGEoTm9kZSBub2RlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVwdGgpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHN3aXRjaCAobm9kZS5nZXROb2RlVHlwZSgpKQotICAgIHsKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREUgOgotICAgIGNhc2UgTm9kZS5FTEVNRU5UX05PREUgOgotICAgIHsKLSAgICAgIGZvciAoTm9kZSBjaGlsZCA9IG5vZGUuZ2V0Rmlyc3RDaGlsZCgpOyBudWxsICE9IGNoaWxkOwotICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmdldE5leHRTaWJsaW5nKCkpCi0gICAgICB7Ci0gICAgICAgIGRpc3BhdGNoTm9kZURhdGEoY2hpbGQsIGNoLCBkZXB0aCsxKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6IC8vICVSRVZJRVclCi0gICAgY2FzZSBOb2RlLkNPTU1FTlRfTk9ERSA6Ci0gICAgICBpZigwICE9IGRlcHRoKQotICAgICAgICBicmVhazsKLSAgICAgICAgLy8gTk9URTogQmVjYXVzZSB0aGlzIG9wZXJhdGlvbiB3b3JrcyBpbiB0aGUgRE9NIHNwYWNlLCBpdCBkb2VzIF9ub3RfIGF0dGVtcHQKLSAgICAgICAgLy8gdG8gcGVyZm9ybSBUZXh0IENvYWxpdGlvbi4gVGhhdCBzaG91bGQgb25seSBiZSBkb25lIGluIERUTSBzcGFjZS4gCi0gICAgY2FzZSBOb2RlLlRFWFRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFIDoKLSAgICAgIFN0cmluZyBzdHIgPSBub2RlLmdldE5vZGVWYWx1ZSgpOwotICAgICAgaWYoY2ggaW5zdGFuY2VvZiBDaGFyYWN0ZXJOb2RlSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgKChDaGFyYWN0ZXJOb2RlSGFuZGxlciljaCkuY2hhcmFjdGVycyhub2RlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgY2guY2hhcmFjdGVycyhzdHIudG9DaGFyQXJyYXkoKSwgMCwgc3RyLmxlbmd0aCgpKTsKLSAgICAgIH0KLSAgICAgIGJyZWFrOwotLy8gICAgLyogY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0vLyAgICAgIC8vIHdhcm5pbmcoWFBBVEhFcnJvclJlc291cmNlcy5XR19QQVJTSU5HX0FORF9QUkVQQVJJTkcpOyAgICAgICAgCi0vLyAgICAgIGJyZWFrOyAqLwotICAgIGRlZmF1bHQgOgotICAgICAgLy8gaWdub3JlCi0gICAgICBicmVhazsKLSAgICB9Ci0gIH0KLSAgCi0gIFRyZWVXYWxrZXIgbV93YWxrZXIgPSBuZXcgVHJlZVdhbGtlcihudWxsKTsKLSAgCi0gIC8qKgotICAgKiBEaXJlY3RseSBjcmVhdGUgU0FYIHBhcnNlciBldmVudHMgZnJvbSBhIHN1YnRyZWUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoVG9FdmVudHMoaW50IG5vZGVIYW5kbGUsIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIFRyZWVXYWxrZXIgdHJlZVdhbGtlciA9IG1fd2Fsa2VyOwotICAgIENvbnRlbnRIYW5kbGVyIHByZXZDSCA9IHRyZWVXYWxrZXIuZ2V0Q29udGVudEhhbmRsZXIoKTsKLSAgICAKLSAgICBpZihudWxsICE9IHByZXZDSCkKLSAgICB7Ci0gICAgICB0cmVlV2Fsa2VyID0gbmV3IFRyZWVXYWxrZXIobnVsbCk7Ci0gICAgfQotICAgIHRyZWVXYWxrZXIuc2V0Q29udGVudEhhbmRsZXIoY2gpOwotICAgIAotICAgIHRyeQotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IGdldE5vZGUobm9kZUhhbmRsZSk7Ci0gICAgICB0cmVlV2Fsa2VyLnRyYXZlcnNlKG5vZGUpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgdHJlZVdhbGtlci5zZXRDb250ZW50SGFuZGxlcihudWxsKTsKLSAgICB9Ci0gIH0KLSAgCi0gIHB1YmxpYyBpbnRlcmZhY2UgQ2hhcmFjdGVyTm9kZUhhbmRsZXIKLSAgewotICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoTm9kZSBub2RlKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBGb3IgdGhlIG1vbWVudCBhbGwgdGhlIHJ1biB0aW1lIHByb3BlcnRpZXMgYXJlIGlnbm9yZWQgYnkgdGhpcwotICAgKiBjbGFzcy4KLSAgICoKLSAgICogQHBhcmFtIHByb3BlcnR5IGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZQotICAgKiBAcGFyYW0gdmFsdWUgYW4gPGNvZGU+T2JqZWN0PC9jb2RlPiB2YWx1ZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5LCBPYmplY3QgdmFsdWUpCi0gIHsKLSAgfQotICAKLSAgLyoqCi0gICAqIE5vIHNvdXJjZSBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgZm9yIERPTTJEVE0sIHNvIHJldHVybgotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBoZXJlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBhbiA8Y29kZT5pbnQ8L2NvZGU+IHZhbHVlCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9zYXgyZHRtL1NBWDJEVE0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL3NheDJkdG0vU0FYMkRUTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZWM5YWRiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL3NheDJkdG0vU0FYMkRUTS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjIzMCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLnNheDJkdG07Ci0KLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuWGFsYW5Qcm9wZXJ0aWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTFRFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuKjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5TdHJpbmdWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuSW50VmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuSW50U3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3ViYWxsb2NhdGVkSW50VmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN5c3RlbUlEUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIERUTSB0aGF0IHRlbmRzIHRvIGJlIG9wdGltaXplZCBtb3JlIGZvciBzcGVlZCB0aGFuCi0gKiBmb3IgY29tcGFjdG5lc3MsIHRoYXQgaXMgY29uc3RydWN0ZWQgdmlhIFNBWDIgQ29udGVudEhhbmRsZXIgZXZlbnRzLgotICovCi1wdWJsaWMgY2xhc3MgU0FYMkRUTSBleHRlbmRzIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzCi0gICAgICAgIGltcGxlbWVudHMgRW50aXR5UmVzb2x2ZXIsIERUREhhbmRsZXIsIENvbnRlbnRIYW5kbGVyLCBFcnJvckhhbmRsZXIsCi0gICAgICAgICAgICAgICAgICAgRGVjbEhhbmRsZXIsIExleGljYWxIYW5kbGVyCi17Ci0gIC8qKiBzaW1wbGUgREVCVUcgZmxhZywgZm9yIGR1bXBpbmcgZGlhZ25vc3RpY3MgaW5mby4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwotCi0gIC8qKgotICAgKiBJZiB3ZSdyZSBidWlsZGluZyB0aGUgbW9kZWwgaW5jcmVtZW50YWxseSBvbiBkZW1hbmQsIHdlIG5lZWQgdG8KLSAgICogYmUgYWJsZSB0byB0ZWxsIHRoZSBzb3VyY2Ugd2hlbiB0byBzZW5kIHVzIG1vcmUgZGF0YS4KLSAgICoKLSAgICogTm90ZSB0aGF0IGlmIHRoaXMgaGFzIG5vdCBiZWVuIHNldCwgYW5kIHlvdSBhdHRlbXB0IHRvIHJlYWQgYWhlYWQKLSAgICogb2YgdGhlIGN1cnJlbnQgYnVpbGQgcG9pbnQsIHdlJ2xsIHByb2JhYmx5IHRocm93IGEgbnVsbC1wb2ludGVyCi0gICAqIGV4Y2VwdGlvbi4gV2UgY291bGQgdHJ5IHRvIHdhaXQtYW5kLXJldHJ5IGluc3RlYWQsIGFzIGEgdmVyeSBwb29yCi0gICAqIGZhbGxiYWNrLCBidXQgdGhhdCBoYXMgYWxsIHRoZSBrbm93biBwcm9ibGVtcyB3aXRoIG11bHRpdGhyZWFkaW5nCi0gICAqIG9uIG11bHRpcHJvY2Vzc29ycyBhbmQgd2UgRG9uJ3QgV2FudCB0byBHbyBUaGVyZS4KLSAgICoKLSAgICogQHNlZSBzZXRJbmNyZW1lbnRhbFNBWFNvdXJjZQotICAgKi8KLSAgcHJpdmF0ZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBtX2luY3JlbWVudGFsU0FYU291cmNlID0gbnVsbDsKLQotICAvKioKLSAgICogQWxsIHRoZSBjaGFyYWN0ZXIgY29udGVudCwgaW5jbHVkaW5nIGF0dHJpYnV0ZSB2YWx1ZXMsIGFyZSBzdG9yZWQgaW4KLSAgICogdGhpcyBidWZmZXIuCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIGhhdmUgYW4gb3B0aW9uIG9mIGJlaW5nIHNoYXJlZD8KLSAgICovCi0gIHByaXZhdGUgRmFzdFN0cmluZ0J1ZmZlciBtX2NoYXJzID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIoMTMsIDEzKTsKLQotICAvKiogVGhpcyB2ZWN0b3IgaG9sZHMgb2Zmc2V0IGFuZCBsZW5ndGggZGF0YS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2RhdGE7Ci0KLSAgLyoqIFRoZSBwYXJlbnQgc3RhY2ssIG5lZWRlZCBvbmx5IGZvciBjb25zdHJ1Y3Rpb24uICovCi0gIHRyYW5zaWVudCBwcml2YXRlIEludFN0YWNrIG1fcGFyZW50cyA9IG5ldyBJbnRTdGFjaygpOwotCi0gIC8qKiBUaGUgY3VycmVudCBwcmV2aW91cyBub2RlLCBuZWVkZWQgb25seSBmb3IgY29uc3RydWN0aW9uIHRpbWUuICovCi0gIHRyYW5zaWVudCBwcml2YXRlIGludCBtX3ByZXZpb3VzID0gMDsKLQotICAvKiogTmFtZXNwYWNlIHN1cHBvcnQsIG9ubHkgcmVsZXZlbnQgYXQgY29uc3RydWN0aW9uIHRpbWUuICovCi0gIHRyYW5zaWVudCBwcml2YXRlIGphdmEudXRpbC5WZWN0b3IgbV9wcmVmaXhNYXBwaW5ncyA9Ci0gICAgbmV3IGphdmEudXRpbC5WZWN0b3IoKTsKLQotICAvKiogTmFtZXNwYWNlIHN1cHBvcnQsIG9ubHkgcmVsZXZlbnQgYXQgY29uc3RydWN0aW9uIHRpbWUuICovCi0gIHRyYW5zaWVudCBwcml2YXRlIEludFN0YWNrIG1fY29udGV4dEluZGV4ZXMgPSBuZXcgSW50U3RhY2soKTsKLQotICAvKiogVHlwZSBvZiBuZXh0IGNoYXJhY3RlcnMoKSBldmVudCB3aXRoaW4gdGV4dCBibG9jayBpbiBwcmdyZXNzLiAqLwotICB0cmFuc2llbnQgcHJpdmF0ZSBpbnQgbV90ZXh0VHlwZSA9IERUTS5URVhUX05PREU7Ci0KLSAgLyoqCi0gICAqIFR5cGUgb2YgY29hbGVzY2VkIHRleHQgYmxvY2suIFNlZSBsb2dpYyBpbiB0aGUgY2hhcmFjdGVycygpCi0gICAqIG1ldGhvZC4KLSAgICovCi0gIHRyYW5zaWVudCBwcml2YXRlIGludCBtX2NvYWxlc2NlZFRleHRUeXBlID0gRFRNLlRFWFRfTk9ERTsKLQotICAvKiogVGhlIFNBWCBEb2N1bWVudCBsb2NhdG9yICovCi0gIHRyYW5zaWVudCBwcml2YXRlIExvY2F0b3IgbV9sb2NhdG9yID0gbnVsbDsKLQotICAvKiogV2UgYXJlIGluc2lkZSB0aGUgRFRELiAgVGhpcyBpcyB1c2VkIGZvciBpZ25vcmluZyBjb21tZW50cy4gICovCi0gIHRyYW5zaWVudCBwcml2YXRlIGJvb2xlYW4gbV9pbnNpZGVEVEQgPSBmYWxzZTsKLQotICAvKiogVHJlZSBXYWxrZXIgZm9yIGRpc3BhdGNoVG9FdmVudHMuICovCi0gIHByb3RlY3RlZCBEVE1UcmVlV2Fsa2VyIG1fd2Fsa2VyID0gbmV3IERUTVRyZWVXYWxrZXIoKTsKLQotICAvKiogcG9vbCBvZiBzdHJpbmcgdmFsdWVzIHRoYXQgY29tZSBhcyBzdHJpbmdzLiAqLwotICBwcml2YXRlIERUTVN0cmluZ1Bvb2wgbV92YWx1ZXNPclByZWZpeGVzID0gbmV3IERUTVN0cmluZ1Bvb2woKTsKLQotICAvKiogRW5kIGRvY3VtZW50IGhhcyBiZWVuIHJlYWNoZWQuICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2VuZERvY3VtZW50T2NjdXJlZCA9IGZhbHNlOwotCi0gIC8qKiBEYXRhIG9yIHF1YWxpZmllZCBuYW1lIHZhbHVlcywgb25lIGFycmF5IGVsZW1lbnQgZm9yIGVhY2ggbm9kZS4gKi8KLSAgcHJvdGVjdGVkIFN1YmFsbG9jYXRlZEludFZlY3RvciBtX2RhdGFPclFOYW1lOwotCi0gIC8qKgotICAgKiBUaGlzIHRhYmxlIGhvbGRzIHRoZSBJRCBzdHJpbmcgdG8gbm9kZSBhc3NvY2lhdGlvbnMsIGZvcgotICAgKiBYTUwgSURzLgotICAgKi8KLSAgcHJvdGVjdGVkIEhhc2h0YWJsZSBtX2lkQXR0cmlidXRlcyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAvKioKLSAgICogZml4ZWQgZG9tLXN0eWxlIG5hbWVzLgotICAgKi8KLSAgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG1fZml4ZWRuYW1lcyA9IHsgbnVsbCwgbnVsbCwgIC8vIG5vdGhpbmcsIEVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgIiN0ZXh0IiwgIC8vIEF0dHIsIFRleHQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNjZGF0YV9zZWN0aW9uIiwgbnVsbCwgIC8vIENEQVRBLCBFbnRpdHlSZWZlcmVuY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgIC8vIEVudGl0eSwgUEkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNjb21tZW50IiwgIiNkb2N1bWVudCIsICAvLyBDb21tZW50LCBEb2N1bWVudAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCAiI2RvY3VtZW50LWZyYWdtZW50IiwgIC8vIERvY3R5cGUsIERvY3VtZW50RnJhZ21lbnQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCB9OyAgLy8gTm90YXRpb24KLQotICAvKioKLSAgICogVmVjdG9yIG9mIGVudGl0aWVzLiAgRWFjaCByZWNvcmQgaXMgY29tcG9zZWQgb2YgZm91ciBTdHJpbmdzOgotICAgKiAgcHVibGljSWQsIHN5c3RlbUlELCBub3RhdGlvbk5hbWUsIGFuZCBuYW1lLgotICAgKi8KLSAgcHJpdmF0ZSBWZWN0b3IgbV9lbnRpdGllcyA9IG51bGw7Ci0KLSAgLyoqIG1fZW50aXRpZXMgcHVibGljIElEIG9mZnNldC4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRF9QVUJMSUNJRCA9IDA7Ci0KLSAgLyoqIG1fZW50aXRpZXMgc3lzdGVtIElEIG9mZnNldC4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRF9TWVNURU1JRCA9IDE7Ci0KLSAgLyoqIG1fZW50aXRpZXMgbm90YXRpb24gbmFtZSBvZmZzZXQuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERfTk9UQVRJT05OQU1FID0gMjsKLQotICAvKiogbV9lbnRpdGllcyBuYW1lIG9mZnNldC4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRF9OQU1FID0gMzsKLQotICAvKiogTnVtYmVyIG9mIGVudHJpZXMgcGVyIHJlY29yZCBmb3IgbV9lbnRpdGllcy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRFNfUEVSID0gNDsKLQotICAvKioKLSAgICogVGhlIHN0YXJ0aW5nIG9mZnNldCB3aXRoaW4gbV9jaGFycyBmb3IgdGhlIHRleHQgb3IKLSAgICogQ0RBVEFfU0VDVElPTiBub2RlIGN1cnJlbnRseSBiZWluZyBhY3VtdWxhdGVkLAotICAgKiBvciAtMSBpZiB0aGVyZSBpcyBubyB0ZXh0IG5vZGUgaW4gcHJvZ3Jlc3MKLSAgICovCi0gIHByaXZhdGUgaW50IG1fdGV4dFBlbmRpbmdTdGFydCA9IC0xOwotCi0gIC8qKgotICAgKiBEZXNjcmliZXMgd2hldGhlciBpbmZvcm1hdGlvbiBhYm91dCBkb2N1bWVudCBzb3VyY2UgbG9jYXRpb24KLSAgICogc2hvdWxkIGJlIG1haW50YWluZWQgb3Igbm90LgotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fdXNlU291cmNlTG9jYXRpb25Qcm9wZXJ0eSA9IGZhbHNlOwotCi0gIHByaXZhdGUgU3RyaW5nVmVjdG9yIG1fc291cmNlU3lzdGVtSWQ7Ci0gIHByaXZhdGUgSW50VmVjdG9yIG1fc291cmNlTGluZTsKLSAgcHJpdmF0ZSBJbnRWZWN0b3IgbV9zb3VyY2VDb2x1bW47Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0IGEgU0FYMkRUTSBvYmplY3QgcmVhZHkgdG8gYmUgY29uc3RydWN0ZWQgZnJvbSBTQVgyCi0gICAqIENvbnRlbnRIYW5kbGVyIGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIG1nciBUaGUgRFRNTWFuYWdlciB3aG8gb3ducyB0aGlzIERUTS4KLSAgICogQHBhcmFtIHNvdXJjZSB0aGUgSkFYUCAxLjEgU291cmNlIG9iamVjdCBmb3IgdGhpcyBEVE0uCi0gICAqIEBwYXJhbSBkdG1JZGVudGl0eSBUaGUgRFRNIGlkZW50aXR5IElEIGZvciB0aGlzIERUTS4KLSAgICogQHBhcmFtIHdoaXRlU3BhY2VGaWx0ZXIgVGhlIHdoaXRlIHNwYWNlIGZpbHRlciBmb3IgdGhpcyBEVE0sIHdoaWNoIG1heQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSBudWxsLgotICAgKiBAcGFyYW0geHN0cmluZ2ZhY3RvcnkgWE1MU3RyaW5nIGZhY3RvcnkgZm9yIGNyZWF0aW5nIGNoYXJhY3RlciBjb250ZW50LgotICAgKiBAcGFyYW0gZG9JbmRleGluZyB0cnVlIGlmIHRoZSBjYWxsZXIgY29uc2lkZXJzIGl0IHdvcnRoIGl0IHRvIHVzZSAKLSAgICogICAgICAgICAgICAgICAgICAgaW5kZXhpbmcgc2NoZW1lcy4KLSAgICovCi0gIHB1YmxpYyBTQVgyRFRNKERUTU1hbmFnZXIgbWdyLCBTb3VyY2Ugc291cmNlLCBpbnQgZHRtSWRlbnRpdHksCi0gICAgICAgICAgICAgICAgIERUTVdTRmlsdGVyIHdoaXRlU3BhY2VGaWx0ZXIsCi0gICAgICAgICAgICAgICAgIFhNTFN0cmluZ0ZhY3RvcnkgeHN0cmluZ2ZhY3RvcnksCi0gICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JbmRleGluZykKLSAgewotCi0gICAgc3VwZXIobWdyLCBzb3VyY2UsIGR0bUlkZW50aXR5LCB3aGl0ZVNwYWNlRmlsdGVyLCAKLSAgICAgICAgICB4c3RyaW5nZmFjdG9yeSwgZG9JbmRleGluZyk7Ci0gICAgICAgICAgCi0gICAgbV9kYXRhID0gbmV3IFN1YmFsbG9jYXRlZEludFZlY3Rvcihkb0luZGV4aW5nID8gKDEwMjQqMikgOiA1MTIsIDEwMjQpOwotICAgIG1fZGF0YS5hZGRFbGVtZW50KDApOyAgIC8vIE5lZWQgcGxhY2Vob2xkZXIgaW4gY2FzZSBpbmRleCBpbnRvIGhlcmUgbXVzdCBiZSA8MC4KLQotICAgIG1fZGF0YU9yUU5hbWUgPSBuZXcgU3ViYWxsb2NhdGVkSW50VmVjdG9yKG1faW5pdGlhbGJsb2Nrc2l6ZSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBkYXRhIG9yIHF1YWxpZmllZCBuYW1lIGZvciB0aGUgZ2l2ZW4gbm9kZSBpZGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBub2RlIGlkZW50aXR5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkYXRhIG9yIHF1YWxpZmllZCBuYW1lLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgX2RhdGFPclFOYW1lKGludCBpZGVudGl0eSkKLSAgewotCi0gICAgaWYgKGlkZW50aXR5IDwgbV9zaXplKQotICAgICAgcmV0dXJuIG1fZGF0YU9yUU5hbWUuZWxlbWVudEF0KGlkZW50aXR5KTsKLQotICAgIC8vIENoZWNrIHRvIHNlZSBpZiB0aGUgaW5mb3JtYXRpb24gcmVxdWVzdGVkIGhhcyBiZWVuIHByb2Nlc3NlZCwgYW5kLCAKLSAgICAvLyBpZiBub3QsIGFkdmFuY2UgdGhlIGl0ZXJhdG9yIHVudGlsIHdlIHRoZSBpbmZvcm1hdGlvbiBoYXMgYmVlbiAKLSAgICAvLyBwcm9jZXNzZWQuCi0gICAgd2hpbGUgKHRydWUpCi0gICAgewotICAgICAgYm9vbGVhbiBpc01vcmUgPSBuZXh0Tm9kZSgpOwotCi0gICAgICBpZiAoIWlzTW9yZSkKLSAgICAgICAgcmV0dXJuIE5VTEw7Ci0gICAgICBlbHNlIGlmIChpZGVudGl0eSA8IG1fc2l6ZSkKLSAgICAgICAgcmV0dXJuIG1fZGF0YU9yUU5hbWUuZWxlbWVudEF0KGlkZW50aXR5KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQXNrIHRoZSBDb1JvdXRpbmUgcGFyc2VyIHRvIGRvVGVybWluYXRlIGFuZCBjbGVhciB0aGUgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2xlYXJDb1JvdXRpbmUoKQotICB7Ci0gICAgY2xlYXJDb1JvdXRpbmUodHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQXNrIHRoZSBDb1JvdXRpbmUgcGFyc2VyIHRvIGRvVGVybWluYXRlIGFuZCBjbGVhciB0aGUgcmVmZXJlbmNlLiBJZgotICAgKiB0aGUgQ29Sb3V0aW5lIHBhcnNlciBoYXMgYWxyZWFkeSBiZWVuIGNsZWFyZWQsIHRoaXMgd2lsbCBoYXZlIG5vIGVmZmVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNhbGxEb1Rlcm1pbmF0ZSB0cnVlIG9mIGRvVGVybWluYXRlIHNob3VsZCBiZSBjYWxsZWQgb24gdGhlCi0gICAqIGNvUm91dGluZSBwYXJzZXIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjbGVhckNvUm91dGluZShib29sZWFuIGNhbGxEb1Rlcm1pbmF0ZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9pbmNyZW1lbnRhbFNBWFNvdXJjZSkKLSAgICB7Ci0gICAgICBpZiAoY2FsbERvVGVybWluYXRlKQotICAgICAgICBtX2luY3JlbWVudGFsU0FYU291cmNlLmRlbGl2ZXJNb3JlTm9kZXMoZmFsc2UpOwotCi0gICAgICBtX2luY3JlbWVudGFsU0FYU291cmNlID0gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQmluZCBhIEluY3JlbWVudGFsU0FYU291cmNlIHRvIHRoaXMgRFRNLiBJZiB3ZSBkaXNjb3ZlciB3ZSBuZWVkIG5vZGVzCi0gICAqIHRoYXQgaGF2ZSBub3QgeWV0IGJlZW4gYnVpbHQsIHdlIHdpbGwgYXNrIHRoaXMgb2JqZWN0IHRvIHNlbmQgdXMgbW9yZQotICAgKiBldmVudHMsIGFuZCBpdCB3aWxsIG1hbmFnZSBpbnRlcmFjdGlvbnMgd2l0aCBpdHMgZGF0YSBzb3VyY2VzLgotICAgKgotICAgKiBOb3RlIHRoYXQgd2UgZG8gbm90IGFjdHVhbGx5IGJ1aWxkIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSwgc2luY2Ugd2UgZG9uJ3QKLSAgICoga25vdyB3aGF0IHNvdXJjZSBpdCdzIHJlYWRpbmcgZnJvbSwgd2hhdCB0aHJlYWQgdGhhdCBzb3VyY2Ugd2lsbCBydW4gaW4sCi0gICAqIG9yIHdoZW4gaXQgd2lsbCBydW4uCi0gICAqCi0gICAqIEBwYXJhbSBpbmNyZW1lbnRhbFNBWFNvdXJjZSBUaGUgcGFyc2VyIHRoYXQgd2Ugd2FudCB0byByZWNpZXZlIGV2ZW50cyBmcm9tCi0gICAqIG9uIGRlbWFuZC4KLSAgICogQHBhcmFtIGFwcENvUklEIFRoZSBDb1JvdXRpbmUgSUQgZm9yIHRoZSBhcHBsaWNhdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEluY3JlbWVudGFsU0FYU291cmNlKEluY3JlbWVudGFsU0FYU291cmNlIGluY3JlbWVudGFsU0FYU291cmNlKQotICB7Ci0KLSAgICAvLyBFc3RhYmxpc2ggY29yb3V0aW5lIGxpbmsgc28gd2UgY2FuIHJlcXVlc3QgbW9yZSBkYXRhCi0gICAgLy8KLSAgICAvLyBOb3RlOiBJdCdzIHBvc3NpYmxlIHRoYXQgc29tZSB2ZXJzaW9ucyBvZiBJbmNyZW1lbnRhbFNBWFNvdXJjZSBtYXkKLSAgICAvLyBub3QgYWN0dWFsbHkgdXNlIGEgQ29yb3V0aW5lTWFuYWdlciwgYW5kIGhlbmNlIG1heSBub3QgcmVxdWlyZQotICAgIC8vIHRoYXQgd2Ugb2J0YWluIGFuIEFwcGxpY2F0aW9uIENvcm91dGluZSBJRC4gKFRoaXMgcmVsaWVzIG9uIHRoZQotICAgIC8vIGNvcm91dGluZSB0cmFuc2FjdGlvbiBkZXRhaWxzIGhhdmluZyBiZWVuIGVuY2Fwc3VsYXRlZCBpbiB0aGUKLSAgICAvLyBJbmNyZW1lbnRhbFNBWFNvdXJjZS5kby4uLigpIG1ldGhvZHMuKQotICAgIG1faW5jcmVtZW50YWxTQVhTb3VyY2UgPSBpbmNyZW1lbnRhbFNBWFNvdXJjZTsKLQotICAgIC8vIEVzdGFibGlzaCBTQVgtc3RyZWFtIGxpbmsgc28gd2UgY2FuIHJlY2VpdmUgdGhlIHJlcXVlc3RlZCBkYXRhCi0gICAgaW5jcmVtZW50YWxTQVhTb3VyY2Uuc2V0Q29udGVudEhhbmRsZXIodGhpcyk7Ci0gICAgaW5jcmVtZW50YWxTQVhTb3VyY2Uuc2V0TGV4aWNhbEhhbmRsZXIodGhpcyk7Ci0KLSAgICAvLyBBcmUgdGhlIGZvbGxvd2luZyByZWFsbHkgbmVlZGVkPyBpbmNyZW1lbnRhbFNBWFNvdXJjZSBkb2Vzbid0IHlldAotICAgIC8vIHN1cHBvcnQgdGhlbSwgYW5kIHRoZXkncmUgbW9zdGx5IG5vLW9wcyBoZXJlLi4uCi0gICAgLy9pbmNyZW1lbnRhbFNBWFNvdXJjZS5zZXRFcnJvckhhbmRsZXIodGhpcyk7Ci0gICAgLy9pbmNyZW1lbnRhbFNBWFNvdXJjZS5zZXREVERIYW5kbGVyKHRoaXMpOwotICAgIC8vaW5jcmVtZW50YWxTQVhTb3VyY2Uuc2V0RGVjbEhhbmRsZXIodGhpcyk7Ci0gIH0KLQotICAvKioKLSAgICogZ2V0Q29udGVudEhhbmRsZXIgcmV0dXJucyAib3VyIFNBWCBidWlsZGVyIiAtLSB0aGUgdGhpbmcgdGhhdAotICAgKiBzb21lb25lIGVsc2Ugc2hvdWxkIHNlbmQgU0FYIGV2ZW50cyB0byBpbiBvcmRlciB0byBleHRlbmQgdGhpcwotICAgKiBEVE0gbW9kZWwuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJldHVybiBudWxsIGlmIGNvbnN0cnV0aW9uIGFscmVhZHkgZG9uZS9iZWd1bj8KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIFNBWCBldmVudHMsCi0gICAqICJ0aGlzIiBpZiB0aGUgRFRNIG9iamVjdCBoYXMgYSBidWlsdC1pbiBTQVggQ29udGVudEhhbmRsZXIsCi0gICAqIHRoZSBJbmNyZW1lbnRhbFNBWFNvdXJjZSBpZiB3ZSdyZSBib3VuZCB0byBvbmUgYW5kIHNob3VsZCByZWNlaXZlCi0gICAqIHRoZSBTQVggc3RyZWFtIHZpYSBpdCBmb3IgaW5jcmVtZW50YWwgYnVpbGQgcHVycG9zZXMuLi4KLSAgICovCi0gIHB1YmxpYyBDb250ZW50SGFuZGxlciBnZXRDb250ZW50SGFuZGxlcigpCi0gIHsKLQotICAgIGlmIChtX2luY3JlbWVudGFsU0FYU291cmNlIGluc3RhbmNlb2YgSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyKQotICAgICAgcmV0dXJuIChDb250ZW50SGFuZGxlcikgbV9pbmNyZW1lbnRhbFNBWFNvdXJjZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gdGhpczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhpcyBEVE0ncyBsZXhpY2FsIGhhbmRsZXIuCi0gICAqCi0gICAqICVSRVZJRVclIFNob3VsZCB0aGlzIHJldHVybiBudWxsIGlmIGNvbnN0cnV0aW9uIGFscmVhZHkgZG9uZS9iZWd1bj8KLSAgICoKLSAgICogQHJldHVybiBudWxsIGlmIHRoaXMgbW9kZWwgZG9lc24ndCByZXNwb25kIHRvIGxleGljYWwgU0FYIGV2ZW50cywKLSAgICogInRoaXMiIGlmIHRoZSBEVE0gb2JqZWN0IGhhcyBhIGJ1aWx0LWluIFNBWCBDb250ZW50SGFuZGxlciwKLSAgICogdGhlIEluY3JlbWVudGFsU0FYU291cmNlIGlmIHdlJ3JlIGJvdW5kIHRvIG9uZSBhbmQgc2hvdWxkIHJlY2VpdmUKLSAgICogdGhlIFNBWCBzdHJlYW0gdmlhIGl0IGZvciBpbmNyZW1lbnRhbCBidWlsZCBwdXJwb3Nlcy4uLgotICAgKi8KLSAgcHVibGljIExleGljYWxIYW5kbGVyIGdldExleGljYWxIYW5kbGVyKCkKLSAgewotCi0gICAgaWYgKG1faW5jcmVtZW50YWxTQVhTb3VyY2UgaW5zdGFuY2VvZiBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIpCi0gICAgICByZXR1cm4gKExleGljYWxIYW5kbGVyKSBtX2luY3JlbWVudGFsU0FYU291cmNlOwotICAgIGVsc2UKLSAgICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIEVudGl0eVJlc29sdmVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGVudGl0eSByZWYgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIEVudGl0eVJlc29sdmVyIGdldEVudGl0eVJlc29sdmVyKCkKLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERUREhhbmRsZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCBpZiB0aGlzIG1vZGVsIGRvZXNuJ3QgcmVzcG9uZCB0byBTQVggZHRkIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBEVERIYW5kbGVyIGdldERUREhhbmRsZXIoKQotICB7Ci0gICAgcmV0dXJuIHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoaXMgRFRNJ3MgRXJyb3JIYW5kbGVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIGVycm9yIGV2ZW50cy4KLSAgICovCi0gIHB1YmxpYyBFcnJvckhhbmRsZXIgZ2V0RXJyb3JIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGlzIERUTSdzIERlY2xIYW5kbGVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwgaWYgdGhpcyBtb2RlbCBkb2Vzbid0IHJlc3BvbmQgdG8gU0FYIERlY2wgZXZlbnRzLgotICAgKi8KLSAgcHVibGljIERlY2xIYW5kbGVyIGdldERlY2xIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZmYgd2UncmUgYnVpbGRpbmcgdGhpcyBtb2RlbCBpbmNyZW1lbnRhbGx5IChlZwotICAgKiB3ZSdyZSBwYXJ0bmVyZWQgd2l0aCBhIEluY3JlbWVudGFsU0FYU291cmNlKSBhbmQgdGh1cyByZXF1aXJlIHRoYXQgdGhlCi0gICAqIHRyYW5zZm9ybWF0aW9uIGFuZCB0aGUgcGFyc2UgcnVuIHNpbXVsdGFuZW91c2x5LiBHdWlkYW5jZSB0byB0aGUKLSAgICogRFRNTWFuYWdlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIG5lZWRzVHdvVGhyZWFkcygpCi0gIHsKLSAgICByZXR1cm4gbnVsbCAhPSBtX2luY3JlbWVudGFsU0FYU291cmNlOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgKHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsCi0gICAqIGZvciB0aGUgZGVmaW5pdGlvbiBvZiBhIG5vZGUncyBzdHJpbmctdmFsdWUpLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICogQHBhcmFtIG5vcm1hbGl6ZSB0cnVlIGlmIHRoZSBjb250ZW50IHNob3VsZCBiZSBub3JtYWxpemVkIGFjY29yZGluZyB0byAKLSAgICogdGhlIHJ1bGVzIGZvciB0aGUgWFBhdGgKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjZnVuY3Rpb24tbm9ybWFsaXplLXNwYWNlIj5ub3JtYWxpemUtc3BhY2U8L2E+Ci0gICAqIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKGludCBub2RlSGFuZGxlLCBDb250ZW50SGFuZGxlciBjaCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIG5vcm1hbGl6ZSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0gICAgaW50IHR5cGUgPSBfdHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoaXNUZXh0VHlwZSh0eXBlKSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhT3JRTmFtZS5lbGVtZW50QXQoaWRlbnRpdHkpOwotICAgICAgaW50IG9mZnNldCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4KTsKLSAgICAgIGludCBsZW5ndGggPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCArIDEpOwotICAgICAgCi0gICAgICBpZihub3JtYWxpemUpCi0gICAgICAgIG1fY2hhcnMuc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICBlbHNlCi0gICAgICAgIG1fY2hhcnMuc2VuZFNBWGNoYXJhY3RlcnMoY2gsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBmaXJzdENoaWxkID0gX2ZpcnN0Y2goaWRlbnRpdHkpOwotCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gZmlyc3RDaGlsZCkKLSAgICAgIHsKLSAgICAgICAgaW50IG9mZnNldCA9IC0xOwotICAgICAgICBpbnQgbGVuZ3RoID0gMDsKLSAgICAgICAgaW50IGxldmVsID0gX2xldmVsKGlkZW50aXR5KTsKLQotICAgICAgICBpZGVudGl0eSA9IGZpcnN0Q2hpbGQ7Ci0KLSAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IGlkZW50aXR5ICYmIChfbGV2ZWwoaWRlbnRpdHkpID4gbGV2ZWwpKQotICAgICAgICB7Ci0gICAgICAgICAgdHlwZSA9IGdldE5vZGVUeXBlKGlkZW50aXR5KTsKLQotICAgICAgICAgIGlmIChpc1RleHRUeXBlKHR5cGUpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBkYXRhSW5kZXggPSBfZGF0YU9yUU5hbWUoaWRlbnRpdHkpOwotCi0gICAgICAgICAgICBpZiAoLTEgPT0gb2Zmc2V0KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGxlbmd0aCArPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCArIDEpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlkZW50aXR5ID0gZ2V0TmV4dE5vZGVJZGVudGl0eShpZGVudGl0eSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobGVuZ3RoID4gMCkKLSAgICAgICAgewotICAgICAgICAgIGlmKG5vcm1hbGl6ZSkKLSAgICAgICAgICAgIG1fY2hhcnMuc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKGNoLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgbV9jaGFycy5zZW5kU0FYY2hhcmFjdGVycyhjaCwgb2Zmc2V0LCBsZW5ndGgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKHR5cGUgIT0gRFRNLkVMRU1FTlRfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgaW50IGRhdGFJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0KLSAgICAgICAgaWYgKGRhdGFJbmRleCA8IDApCi0gICAgICAgIHsKLSAgICAgICAgICBkYXRhSW5kZXggPSAtZGF0YUluZGV4OwotICAgICAgICAgIGRhdGFJbmRleCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgc3RyID0gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcoZGF0YUluZGV4KTsKLQotICAgICAgICAgIGlmKG5vcm1hbGl6ZSkKLSAgICAgICAgICAgIEZhc3RTdHJpbmdCdWZmZXIuc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKHN0ci50b0NoYXJBcnJheSgpLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIHN0ci5sZW5ndGgoKSwgY2gpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGNoLmNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksIDAsIHN0ci5sZW5ndGgoKSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbm9kZSBuYW1lLiBUaGlzIHdpbGwKLSAgICogaW5jbHVkZSBuYW1lcyBzdWNoIGFzICN0ZXh0IG9yICNkb2N1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBOYW1lIG9mIHRoaXMgbm9kZSwgd2hpY2ggbWF5IGJlIGFuIGVtcHR5IHN0cmluZy4KLSAgICogJVJFVklFVyUgRG9jdW1lbnQgd2hlbiBlbXB0eSBzdHJpbmcgaXMgcG9zc2libGUuLi4KLSAgICogJVJFVklFVy1DT01NRU5UJSBJdCBzaG91bGQgbmV2ZXIgYmUgZW1wdHksIHNob3VsZCBpdD8KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBleHBhbmRlZFR5cGVJRCA9IGdldEV4cGFuZGVkVHlwZUlEKG5vZGVIYW5kbGUpOwotICAgIC8vIElmIGp1c3QgdGVzdGluZyBub256ZXJvLCBubyBuZWVkIHRvIHNoaWZ0Li4uCi0gICAgLy9pbnQgbmFtZXNwYWNlSUQgPSAoZXhwYW5kZWRUeXBlSUQgJiBFeHBhbmRlZE5hbWVUYWJsZS5NQVNLX05BTUVTUEFDRSkKLSAgICAvLyAgICAgICAgICAgICAgICAgID4+IEV4cGFuZGVkTmFtZVRhYmxlLkJJVFNfUEVSX0xPQ0FMTkFNRTsKLSAgICBpbnQgbmFtZXNwYWNlSUQgPSAoZXhwYW5kZWRUeXBlSUQgJiBFeHBhbmRlZE5hbWVUYWJsZS5NQVNLX05BTUVTUEFDRSk7Ci0KLSAgICBpZiAoMCA9PSBuYW1lc3BhY2VJRCkKLSAgICB7Ci0gICAgICAvLyBEb24ndCByZXRyaWV2ZSBuYW1lIHVudGlsL3VubGVzcyBuZWVkZWQKLSAgICAgIC8vIFN0cmluZyBuYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWRUeXBlSUQpOwotICAgICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShub2RlSGFuZGxlKTsKLQotICAgICAgaWYgKHR5cGUgPT0gRFRNLk5BTUVTUEFDRV9OT0RFKQotICAgICAgewotICAgICAgICBpZiAobnVsbCA9PSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldExvY2FsTmFtZShleHBhbmRlZFR5cGVJRCkpCi0gICAgICAgICAgcmV0dXJuICJ4bWxucyI7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gInhtbG5zOiIgKyBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldExvY2FsTmFtZShleHBhbmRlZFR5cGVJRCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICgwID09IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TG9jYWxOYW1lSUQoZXhwYW5kZWRUeXBlSUQpKQotICAgICAgewotICAgICAgICByZXR1cm4gbV9maXhlZG5hbWVzW3R5cGVdOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICByZXR1cm4gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWRUeXBlSUQpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHFuYW1lSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChub2RlSGFuZGxlICYgbV9tYXNrKTsKLQotICAgICAgaWYgKHFuYW1lSW5kZXggPCAwKQotICAgICAgewotICAgICAgICBxbmFtZUluZGV4ID0gLXFuYW1lSW5kZXg7Ci0gICAgICAgIHFuYW1lSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KHFuYW1lSW5kZXgpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocW5hbWVJbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiB0aGUgWFBhdGggbm9kZSBuYW1lLiAgVGhpcyBzaG91bGQgYmUKLSAgICogdGhlIG5hbWUgYXMgZGVzY3JpYmVkIGJ5IHRoZSBYUGF0aCBkYXRhIG1vZGVsLCBOT1QgdGhlIERPTS1zdHlsZQotICAgKiBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgaWQgb2YgdGhlIG5vZGUuCi0gICAqIEByZXR1cm4gU3RyaW5nIE5hbWUgb2YgdGhpcyBub2RlLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlTmFtZVgoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBleHBhbmRlZFR5cGVJRCA9IGdldEV4cGFuZGVkVHlwZUlEKG5vZGVIYW5kbGUpOwotICAgIGludCBuYW1lc3BhY2VJRCA9IChleHBhbmRlZFR5cGVJRCAmIEV4cGFuZGVkTmFtZVRhYmxlLk1BU0tfTkFNRVNQQUNFKQotICAgICAgICAgICAgICAgICAgICAgID4+IEV4cGFuZGVkTmFtZVRhYmxlLkJJVFNfUEVSX0xPQ0FMTkFNRTsKLQotICAgIGlmICgwID09IG5hbWVzcGFjZUlEKQotICAgIHsKLSAgICAgIFN0cmluZyBuYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRMb2NhbE5hbWUoZXhwYW5kZWRUeXBlSUQpOwotCi0gICAgICBpZiAobmFtZSA9PSBudWxsKQotICAgICAgICByZXR1cm4gIiI7Ci0gICAgICBlbHNlCi0gICAgICAgIHJldHVybiBuYW1lOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IHFuYW1lSW5kZXggPSBtX2RhdGFPclFOYW1lLmVsZW1lbnRBdChub2RlSGFuZGxlICYgbV9tYXNrKTsKLQotICAgICAgaWYgKHFuYW1lSW5kZXggPCAwKQotICAgICAgewotICAgICAgICBxbmFtZUluZGV4ID0gLXFuYW1lSW5kZXg7Ci0gICAgICAgIHFuYW1lSW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KHFuYW1lSW5kZXgpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocW5hbWVJbmRleCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICAgICA1LiBbc3BlY2lmaWVkXSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgYXR0cmlidXRlIHdhcyBhY3R1YWxseQotICAgKiAgICAgICAgc3BlY2lmaWVkIGluIHRoZSBzdGFydC10YWcgb2YgaXRzIGVsZW1lbnQsIG9yIHdhcyBkZWZhdWx0ZWQgZnJvbSB0aGUKLSAgICogICAgICAgIERURC4KLSAgICoKLSAgICogQHBhcmFtIHRoZSBhdHRyaWJ1dGUgaGFuZGxlCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVIYW5kbGUgTXVzdCBiZSBhIHZhbGlkIGhhbmRsZSB0byBhbiBhdHRyaWJ1dGUgbm9kZS4KLSAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXR0cmlidXRlIHdhcyBzcGVjaWZpZWQ7Ci0gICAqICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIGl0IHdhcyBkZWZhdWx0ZWQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0F0dHJpYnV0ZVNwZWNpZmllZChpbnQgYXR0cmlidXRlSGFuZGxlKQotICB7Ci0KLSAgICAvLyBJJ20gbm90IHN1cmUgaWYgSSB3YW50IHRvIGRvIGFueXRoaW5nIHdpdGggdGhpcy4uLgotICAgIHJldHVybiB0cnVlOyAgLy8gPz8KLSAgfQotCi0gIC8qKgotICAgKiAgIEEgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBpbmZvcm1hdGlvbiBpdGVtIGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6Ci0gICAqCi0gICAqICAgICAxLiBbc3lzdGVtIGlkZW50aWZpZXJdIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LCBpZgotICAgKiAgICAgICAgaXQgZXhpc3RzLiBPdGhlcndpc2UgdGhpcyBwcm9wZXJ0eSBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIFN0cmluZyBvYmplY3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RG9jdW1lbnRUeXBlRGVjbGFyYXRpb25TeXN0ZW1JZGVudGlmaWVyKCkKLSAgewotCi0gICAgLyoqIEB0b2RvOiBpbXBsZW1lbnQgdGhpcyBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRGVmYXVsdEJhc2UgYWJzdHJhY3QgbWV0aG9kICovCi0gICAgZXJyb3IoWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTUVUSE9EX05PVF9TVVBQT1JURUQsIG51bGwpKTsvLyJOb3QgeWV0IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGlkZW50aXR5IHZhbHVlIGluIHRoZSBsaXN0LCBhbmQgY2FsbCB0aGUgaXRlcmF0b3IKLSAgICogaWYgaXQgaGFzbid0IGJlZW4gYWRkZWQgeWV0LgotICAgKgotICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIG5vZGUgaWRlbnRpdHkgKGluZGV4KS4KLSAgICogQHJldHVybiBpZGVudGl0eSsxLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGVJZGVudGl0eShpbnQgaWRlbnRpdHkpCi0gIHsKLQotICAgIGlkZW50aXR5ICs9IDE7Ci0KLSAgICB3aGlsZSAoaWRlbnRpdHkgPj0gbV9zaXplKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1faW5jcmVtZW50YWxTQVhTb3VyY2UpCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgICAgbmV4dE5vZGUoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gaWRlbnRpdHk7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY3JlYXRlIFNBWCBwYXJzZXIgZXZlbnRzIGZyb20gYSBzdWJ0cmVlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSBUaGUgbm9kZSBJRC4KLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaFRvRXZlbnRzKGludCBub2RlSGFuZGxlLCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTVRyZWVXYWxrZXIgdHJlZVdhbGtlciA9IG1fd2Fsa2VyOwotICAgIENvbnRlbnRIYW5kbGVyIHByZXZDSCA9IHRyZWVXYWxrZXIuZ2V0Y29udGVudEhhbmRsZXIoKTsKLQotICAgIGlmIChudWxsICE9IHByZXZDSCkKLSAgICB7Ci0gICAgICB0cmVlV2Fsa2VyID0gbmV3IERUTVRyZWVXYWxrZXIoKTsKLSAgICB9Ci0KLSAgICB0cmVlV2Fsa2VyLnNldGNvbnRlbnRIYW5kbGVyKGNoKTsKLSAgICB0cmVlV2Fsa2VyLnNldERUTSh0aGlzKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyZWVXYWxrZXIudHJhdmVyc2Uobm9kZUhhbmRsZSk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB0cmVlV2Fsa2VyLnNldGNvbnRlbnRIYW5kbGVyKG51bGwpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiBub2RlcyB0aGF0IGhhdmUgYmVlbiBhZGRlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRoYXQgYXJlIGN1cnJlbnRseSBpbiB0aGUgdHJlZS4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TnVtYmVyT2ZOb2RlcygpCi0gIHsKLSAgICByZXR1cm4gbV9zaXplOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgbWV0aG9kIHNob3VsZCB0cnkgYW5kIGJ1aWxkIG9uZSBvciBtb3JlIG5vZGVzIGluIHRoZSB0YWJsZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdHJ1ZSBpZiBhIG5leHQgbm9kZSBpcyBmb3VuZCBvciBmYWxzZSBpZgotICAgKiAgICAgICAgIHRoZXJlIGFyZSBubyBtb3JlIG5vZGVzLgotICAgKi8KLSAgcHJvdGVjdGVkIGJvb2xlYW4gbmV4dE5vZGUoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2luY3JlbWVudGFsU0FYU291cmNlKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgaWYgKG1fZW5kRG9jdW1lbnRPY2N1cmVkKQotICAgIHsKLSAgICAgIGNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBPYmplY3QgZ290TW9yZSA9IG1faW5jcmVtZW50YWxTQVhTb3VyY2UuZGVsaXZlck1vcmVOb2Rlcyh0cnVlKTsKLQotICAgIC8vIGdvdE1vcmUgbWF5IGJlIGEgQm9vbGVhbiAoVFJVRSBpZiBzdGlsbCBwYXJzaW5nLCBGQUxTRSBpZgotICAgIC8vIEVPRikgb3IgYW4gZXhjZXB0aW9uIGlmIEluY3JlbWVudGFsU0FYU291cmNlIG1hbGZ1bmN0aW9uZWQKLSAgICAvLyAoY29kZSBlcnJvciByYXRoZXIgdGhhbiB1c2VyIGVycm9yKS4KLSAgICAvLwotICAgIC8vICVSRVZJRVclIEN1cnJlbnRseSB0aGUgRXJyb3JIYW5kbGVycyBza2V0Y2hlZCBoZXJlaW4gYXJlCi0gICAgLy8gbm8tb3BzLCBzbyBJJ20gZ29pbmcgdG8gaW5pdGlhbGx5IGxlYXZlIHRoaXMgYWxzbyBhcyBhCi0gICAgLy8gbm8tb3AuCi0gICAgaWYgKCEoZ290TW9yZSBpbnN0YW5jZW9mIEJvb2xlYW4pKQotICAgIHsKLSAgICAgIGlmKGdvdE1vcmUgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbilnb3RNb3JlOwotICAgICAgfQotICAgICAgZWxzZSBpZihnb3RNb3JlIGluc3RhbmNlb2YgRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oKEV4Y2VwdGlvbilnb3RNb3JlKTsKLSAgICAgIH0KLSAgICAgIC8vIGZvciBub3cuLi4KLSAgICAgIGNsZWFyQ29Sb3V0aW5lKCk7Ci0KLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgLy8gJVRCRCUgCi0gICAgfQotCi0gICAgaWYgKGdvdE1vcmUgIT0gQm9vbGVhbi5UUlVFKQotICAgIHsKLQotICAgICAgLy8gRU9GIHJlYWNoZWQgd2l0aG91dCBzYXRpc2Z5aW5nIHRoZSByZXF1ZXN0Ci0gICAgICBjbGVhckNvUm91dGluZSgpOyAgLy8gRHJvcCBjb25uZWN0aW9uLCBzdG9wIHRyeWluZwotCi0gICAgICAvLyAlVEJEJSBkZXJlZ2lzdGVyIGFzIGl0cyBsaXN0ZW5lcj8KLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIGRldGVybWluYXRpb24gb2YgdGV4dCB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gdHlwZSBvbmVvZiBEVE0uWFhYX05PREUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgdGV4dCBvciBjZGF0YSBzZWN0aW9uLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGlzVGV4dFR5cGUoaW50IHR5cGUpCi0gIHsKLSAgICByZXR1cm4gKERUTS5URVhUX05PREUgPT0gdHlwZSB8fCBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFID09IHR5cGUpOwotICB9Ci0KLS8vICAgIC8qKgotLy8gICAgICogRW5zdXJlIHRoYXQgdGhlIHNpemUgb2YgdGhlIGluZm9ybWF0aW9uIGFycmF5cyBjYW4gaG9sZCBhbm90aGVyIGVudHJ5Ci0vLyAgICAgKiBhdCB0aGUgZ2l2ZW4gaW5kZXguCi0vLyAgICAgKgotLy8gICAgICogQHBhcmFtIG9uIGV4aXQgZnJvbSB0aGlzIGZ1bmN0aW9uLCB0aGUgaW5mb3JtYXRpb24gYXJyYXlzIHNpemVzIG11c3QgYmUKLS8vICAgICAqIGF0IGxlYXN0IGluZGV4KzEuCi0vLyAgICAgKgotLy8gICAgICogTkVFRFNET0MgQHBhcmFtIGluZGV4Ci0vLyAgICAgKi8KLS8vICAgIHByb3RlY3RlZCB2b2lkIGVuc3VyZVNpemUoaW50IGluZGV4KQotLy8gICAgewotLy8gICAgICAgICAgLy8gZGF0YU9yUU5hbWUgaXMgYW4gU3ViYWxsb2NhdGVkSW50VmVjdG9yIGFuZCBoZW5jZSBzZWxmLXNpemluZy4KLS8vICAgICAgICAgIC8vIEJ1dCBEVE1EZWZhdWx0QmFzZSBtYXkgbmVlZCBmaXh1cC4KLS8vICAgICAgICBzdXBlci5lbnN1cmVTaXplKGluZGV4KTsKLS8vICAgIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IHRoZSBub2RlIG1hcCBmcm9tIHRoZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gdHlwZSByYXcgdHlwZSBJRCwgb25lIG9mIERUTS5YWFhfTk9ERS4KLSAgICogQHBhcmFtIGV4cGFuZGVkVHlwZUlEIFRoZSBleHBlbmRlZCB0eXBlIElELgotICAgKiBAcGFyYW0gcGFyZW50SW5kZXggVGhlIGN1cnJlbnQgcGFyZW50IGluZGV4LgotICAgKiBAcGFyYW0gcHJldmlvdXNTaWJsaW5nIFRoZSBwcmV2aW91cyBzaWJsaW5nIGluZGV4LgotICAgKiBAcGFyYW0gZGF0YU9yUHJlZml4IGluZGV4IGludG8gbV9kYXRhIHRhYmxlLCBvciBzdHJpbmcgaGFuZGxlLgotICAgKiBAcGFyYW0gY2FuSGF2ZUZpcnN0Q2hpbGQgdHJ1ZSBpZiB0aGUgbm9kZSBjYW4gaGF2ZSBhIGZpcnN0IGNoaWxkLCBmYWxzZQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgaXQgaXMgYXRvbWljLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCBpZGVudGl0eSBvZiB0aGUgbm9kZSB0aGF0IHdhcyBhZGRlZC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgYWRkTm9kZShpbnQgdHlwZSwgaW50IGV4cGFuZGVkVHlwZUlELAotICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBhcmVudEluZGV4LCBpbnQgcHJldmlvdXNTaWJsaW5nLAotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRhdGFPclByZWZpeCwgYm9vbGVhbiBjYW5IYXZlRmlyc3RDaGlsZCkKLSAgewotCi0gICAgLy8gQ29tbW9uIHRvIGFsbCBub2RlczoKLSAgICBpbnQgbm9kZUluZGV4ID0gbV9zaXplKys7Ci0gICAgbV9maXJzdGNoLmFkZEVsZW1lbnQoY2FuSGF2ZUZpcnN0Q2hpbGQgPyBOT1RQUk9DRVNTRUQgOiBEVE0uTlVMTCk7Ci0gICAgbV9uZXh0c2liLmFkZEVsZW1lbnQoTk9UUFJPQ0VTU0VEKTsKLSAgICBtX3ByZXZzaWIuYWRkRWxlbWVudChwcmV2aW91c1NpYmxpbmcpOwotICAgIG1fcGFyZW50LmFkZEVsZW1lbnQocGFyZW50SW5kZXgpOwotICAgIG1fZXhwdHlwZS5hZGRFbGVtZW50KGV4cGFuZGVkVHlwZUlEKTsKLSAgICBtX2RhdGFPclFOYW1lLmFkZEVsZW1lbnQoZGF0YU9yUHJlZml4KTsgICAgCi0KLSAgICBpZiAoRFRNLk5VTEwgIT0gcHJldmlvdXNTaWJsaW5nKQotICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChub2RlSW5kZXgscHJldmlvdXNTaWJsaW5nKTsKLQotICAgIC8vIE5vdGUgdGhhdCBuZXh0U2libGluZyBpcyBub3QgcHJvY2Vzc2VkIHVudGlsIGNoYXJhY3RlcnNGbHVzaCgpCi0gICAgLy8gaXMgY2FsbGVkLCB0byBoYW5kbGUgc3VjY2Vzc2l2ZSBjaGFyYWN0ZXJzKCkgZXZlbnRzLgotCi0gICAgLy8gU3BlY2lhbCBoYW5kbGluZyBieSB0eXBlOiBEZWNsYXJlIG5hbWVzcGFjZXMsIGF0dGFjaCBmaXJzdCBjaGlsZAotICAgIHN3aXRjaCh0eXBlKQotICAgIHsKLSAgICBjYXNlIERUTS5OQU1FU1BBQ0VfTk9ERToKLSAgICAgIGRlY2xhcmVOYW1lc3BhY2VJbkNvbnRleHQocGFyZW50SW5kZXgsbm9kZUluZGV4KTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNLkFUVFJJQlVURV9OT0RFOgotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdDoKLSAgICAgIGlmIChEVE0uTlVMTCAhPSBwYXJlbnRJbmRleCAmJgotCSAgTk9UUFJPQ0VTU0VEID09IG1fZmlyc3RjaC5lbGVtZW50QXQocGFyZW50SW5kZXgpKQotICAgICAgICBtX2ZpcnN0Y2guc2V0RWxlbWVudEF0KG5vZGVJbmRleCxwYXJlbnRJbmRleCk7Ci0gICAgICBicmVhazsKLSAgICB9Ci0KLSAgICByZXR1cm4gbm9kZUluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbm9kZSBoYW5kbGUsIHJldHVybiBpdHMgbm9kZSB2YWx1ZS4gVGhpcyBpcyBtb3N0bHkKLSAgICogYXMgZGVmaW5lZCBieSB0aGUgRE9NLCBidXQgbWF5IGlnbm9yZSBzb21lIGNvbnZlbmllbmNlcy4KLSAgICogPHA+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIGlkLgotICAgKiBAcmV0dXJuIFN0cmluZyBWYWx1ZSBvZiB0aGlzIG5vZGUsIG9yIG51bGwgaWYgbm90Ci0gICAqIG1lYW5pbmdmdWwgZm9yIHRoaXMgbm9kZSB0eXBlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROb2RlVmFsdWUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoaXNUZXh0VHlwZSh0eXBlKSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLSAgICAgIGludCBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICBpbnQgbGVuZ3RoID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLQotICAgICAgLy8gJU9QVCUgV2Ugc2hvdWxkIGNhY2hlIHRoaXMsIEkgZ3Vlc3MuCi0gICAgICByZXR1cm4gbV9jaGFycy5nZXRTdHJpbmcob2Zmc2V0LCBsZW5ndGgpOwotICAgIH0KLSAgICBlbHNlIGlmIChEVE0uRUxFTUVOVF9OT0RFID09IHR5cGUgfHwgRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPT0gdHlwZQotICAgICAgICAgICAgIHx8IERUTS5ET0NVTUVOVF9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLQotICAgICAgaWYgKGRhdGFJbmRleCA8IDApCi0gICAgICB7Ci0gICAgICAgIGRhdGFJbmRleCA9IC1kYXRhSW5kZXg7Ci0gICAgICAgIGRhdGFJbmRleCA9IG1fZGF0YS5lbGVtZW50QXQoZGF0YUluZGV4ICsgMSk7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiBtX3ZhbHVlc09yUHJlZml4ZXMuaW5kZXhUb1N0cmluZyhkYXRhSW5kZXgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gaXRzIFhQYXRoLXN0eWxlIGxvY2FsbmFtZS4KLSAgICogKEFzIGRlZmluZWQgaW4gTmFtZXNwYWNlcywgdGhpcyBpcyB0aGUgcG9ydGlvbiBvZiB0aGUgbmFtZSBhZnRlciBhbnkKLSAgICogY29sb24gY2hhcmFjdGVyKS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIGlkIG9mIHRoZSBub2RlLgotICAgKiBAcmV0dXJuIFN0cmluZyBMb2NhbCBuYW1lIG9mIHRoaXMgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgcmV0dXJuIG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0TG9jYWxOYW1lKF9leHB0eXBlKG5vZGVIYW5kbGUgJiBtX21hc2spKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgZ2V0VW5wYXJzZWRFbnRpdHlVUkkgZnVuY3Rpb24gcmV0dXJucyB0aGUgVVJJIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaW4gdGhlIHNhbWUgZG9jdW1lbnQgYXMgdGhlIGNvbnRleHQKLSAgICogbm9kZSAoc2VlIFszLjMgVW5wYXJzZWQgRW50aXRpZXNdKS4gSXQgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqIHRoZXJlIGlzIG5vIHN1Y2ggZW50aXR5LgotICAgKiA8cD4KLSAgICogWE1MIHByb2Nlc3NvcnMgbWF5IGNob29zZSB0byB1c2UgdGhlIFN5c3RlbSBJZGVudGlmaWVyIChpZiBvbmUKLSAgICogaXMgcHJvdmlkZWQpIHRvIHJlc29sdmUgdGhlIGVudGl0eSwgcmF0aGVyIHRoYW4gdGhlIFVSSSBpbiB0aGUKLSAgICogUHVibGljIElkZW50aWZpZXIuIFRoZSBkZXRhaWxzIGFyZSBkZXBlbmRlbnQgb24gdGhlIHByb2Nlc3NvciwgYW5kCi0gICAqIHdlIHdvdWxkIGhhdmUgdG8gc3VwcG9ydCBzb21lIGZvcm0gb2YgcGx1Zy1pbiByZXNvbHZlciB0byBoYW5kbGUKLSAgICogdGhpcyBwcm9wZXJseS4gQ3VycmVudGx5LCB3ZSBzaW1wbHkgcmV0dXJuIHRoZSBTeXN0ZW0gSWRlbnRpZmllciBpZgotICAgKiBwcmVzZW50LCBhbmQgaG9wZSB0aGF0IGl0IGEgdXNhYmxlIFVSSSBvciB0aGF0IG91ciBjYWxsZXIgY2FuCi0gICAqIG1hcCBpdCB0byBvbmUuCi0gICAqIFRPRE86IFJlc29sdmUgUHVibGljIElkZW50aWZpZXJzLi4uIG9yIGNvbnNpZGVyIGNoYW5naW5nIGZ1bmN0aW9uIG5hbWUuCi0gICAqIDxwPgotICAgKiBJZiB3ZSBmaW5kIGEgcmVsYXRpdmUgVVJJCi0gICAqIHJlZmVyZW5jZSwgWE1MIGV4cGVjdHMgaXQgdG8gYmUgcmVzb2x2ZWQgaW4gdGVybXMgb2YgdGhlIGJhc2UgVVJJCi0gICAqIG9mIHRoZSBkb2N1bWVudC4gVGhlIERPTSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLCBhbmQgaXQgaXNuJ3QKLSAgICogZW50aXJlbHkgY2xlYXIgd2hldGhlciB0aGF0IHNob3VsZCBiZSBkb25lIGhlcmU7IGN1cnJlbnRseSB0aGF0J3MKLSAgICogcHVzaGVkIHVwIHRvIGEgaGlnaGVyIGxldmVsIG9mIG91ciBhcHBsaWNhdGlvbi4gKE5vdGUgdGhhdCBET00gTGV2ZWwKLSAgICogMSBkaWRuJ3Qgc3RvcmUgdGhlIGRvY3VtZW50J3MgYmFzZSBVUkkuKQotICAgKiBUT0RPOiBDb25zaWRlciByZXNvbHZpbmcgUmVsYXRpdmUgVVJJcy4KLSAgICogPHA+Ci0gICAqIChUaGUgRE9NJ3Mgc3RhdGVtZW50IHRoYXQgIkFuIFhNTCBwcm9jZXNzb3IgbWF5IGNob29zZSB0bwotICAgKiBjb21wbGV0ZWx5IGV4cGFuZCBlbnRpdGllcyBiZWZvcmUgdGhlIHN0cnVjdHVyZSBtb2RlbCBpcyBwYXNzZWQKLSAgICogdG8gdGhlIERPTSIgcmVmZXJzIG9ubHkgdG8gcGFyc2VkIGVudGl0aWVzLCBub3QgdW5wYXJzZWQsIGFuZCBoZW5jZQotICAgKiBkb2Vzbid0IGFmZmVjdCB0aGlzIGZ1bmN0aW9uLikKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgRW50aXR5IE5hbWUgb2YgdGhlIHVucGFyc2VkCi0gICAqIGVudGl0eS4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgY29udGFpbmluZyB0aGUgVVJJIG9mIHRoZSBVbnBhcnNlZCBFbnRpdHksIG9yIGFuCi0gICAqIGVtcHR5IHN0cmluZyBpZiBubyBzdWNoIGVudGl0eSBleGlzdHMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFVucGFyc2VkRW50aXR5VVJJKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBTdHJpbmcgdXJsID0gIiI7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2VudGl0aWVzKQotICAgICAgcmV0dXJuIHVybDsKLQotICAgIGludCBuID0gbV9lbnRpdGllcy5zaXplKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkgKz0gRU5USVRZX0ZJRUxEU19QRVIpCi0gICAgewotICAgICAgU3RyaW5nIGVuYW1lID0gKFN0cmluZykgbV9lbnRpdGllcy5lbGVtZW50QXQoaSArIEVOVElUWV9GSUVMRF9OQU1FKTsKLQotICAgICAgaWYgKG51bGwgIT0gZW5hbWUgJiYgZW5hbWUuZXF1YWxzKG5hbWUpKQotICAgICAgewotICAgICAgICBTdHJpbmcgbm5hbWUgPSAoU3RyaW5nKSBtX2VudGl0aWVzLmVsZW1lbnRBdChpCi0gICAgICAgICAgICAgICAgICAgICAgICAgKyBFTlRJVFlfRklFTERfTk9UQVRJT05OQU1FKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBubmFtZSkKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gVGhlIGRyYWZ0IHNheXM6ICJUaGUgWFNMVCBwcm9jZXNzb3IgbWF5IHVzZSB0aGUgcHVibGljIAotICAgICAgICAgIC8vIGlkZW50aWZpZXIgdG8gZ2VuZXJhdGUgYSBVUkkgZm9yIHRoZSBlbnRpdHkgaW5zdGVhZCBvZiB0aGUgVVJJIAotICAgICAgICAgIC8vIHNwZWNpZmllZCBpbiB0aGUgc3lzdGVtIGlkZW50aWZpZXIuIElmIHRoZSBYU0xUIHByb2Nlc3NvciBkb2VzIAotICAgICAgICAgIC8vIG5vdCB1c2UgdGhlIHB1YmxpYyBpZGVudGlmaWVyIHRvIGdlbmVyYXRlIHRoZSBVUkksIGl0IG11c3QgdXNlIAotICAgICAgICAgIC8vIHRoZSBzeXN0ZW0gaWRlbnRpZmllcjsgaWYgdGhlIHN5c3RlbSBpZGVudGlmaWVyIGlzIGEgcmVsYXRpdmUgCi0gICAgICAgICAgLy8gVVJJLCBpdCBtdXN0IGJlIHJlc29sdmVkIGludG8gYW4gYWJzb2x1dGUgVVJJIHVzaW5nIHRoZSBVUkkgb2YgCi0gICAgICAgICAgLy8gdGhlIHJlc291cmNlIGNvbnRhaW5pbmcgdGhlIGVudGl0eSBkZWNsYXJhdGlvbiBhcyB0aGUgYmFzZSAKLSAgICAgICAgICAvLyBVUkkgW1JGQzIzOTZdLiIKLSAgICAgICAgICAvLyBTbyBJJ20gZmFsbGluZyBhIGJpdCBzaG9ydCBoZXJlLgotICAgICAgICAgIHVybCA9IChTdHJpbmcpIG1fZW50aXRpZXMuZWxlbWVudEF0KGkgKyBFTlRJVFlfRklFTERfU1lTVEVNSUQpOwotCi0gICAgICAgICAgaWYgKG51bGwgPT0gdXJsKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHVybCA9IChTdHJpbmcpIG1fZW50aXRpZXMuZWxlbWVudEF0KGkgKyBFTlRJVFlfRklFTERfUFVCTElDSUQpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB1cmw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UgaGFuZGxlLCByZXR1cm4gdGhlIHByZWZpeCB0aGF0IHRoZSBuYW1lc3BhY2UgZGVjbCBpcwotICAgKiBtYXBwaW5nLgotICAgKiBHaXZlbiBhIG5vZGUgaGFuZGxlLCByZXR1cm4gdGhlIHByZWZpeCB1c2VkIHRvIG1hcCB0byB0aGUgbmFtZXNwYWNlLgotICAgKgotICAgKiA8cD4gJVJFVklFVyUgQXJlIHlvdSBzdXJlIHlvdSB3YW50ICIiIGZvciBubyBwcmVmaXg/ICA8L3A+Ci0gICAqIDxwPiAlUkVWSUVXLUNPTU1FTlQlIEkgdGhpbmsgc28uLi4gbm90IHRvdGFsbHkgc3VyZS4gLXNiICA8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgcHJlZml4IG9mIHRoaXMgbm9kZSdzIG5hbWUsIG9yICIiIGlmIG5vIGV4cGxpY2l0Ci0gICAqIG5hbWVzcGFjZSBwcmVmaXggd2FzIGdpdmVuLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSB0eXBlKQotICAgIHsKLSAgICAgIGludCBwcmVmaXhJbmRleCA9IF9kYXRhT3JRTmFtZShpZGVudGl0eSk7Ci0KLSAgICAgIGlmICgwID09IHByZWZpeEluZGV4KQotICAgICAgICByZXR1cm4gIiI7Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBxbmFtZSA9IG1fdmFsdWVzT3JQcmVmaXhlcy5pbmRleFRvU3RyaW5nKHByZWZpeEluZGV4KTsKLQotICAgICAgICByZXR1cm4gZ2V0UHJlZml4KHFuYW1lLCBudWxsKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAoRFRNLkFUVFJJQlVURV9OT0RFID09IHR5cGUpCi0gICAgewotICAgICAgaW50IHByZWZpeEluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLQotICAgICAgaWYgKHByZWZpeEluZGV4IDwgMCkKLSAgICAgIHsKLSAgICAgICAgcHJlZml4SW5kZXggPSBtX2RhdGEuZWxlbWVudEF0KC1wcmVmaXhJbmRleCk7Ci0KLSAgICAgICAgU3RyaW5nIHFuYW1lID0gbV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcocHJlZml4SW5kZXgpOwotCi0gICAgICAgIHJldHVybiBnZXRQcmVmaXgocW5hbWUsIG51bGwpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXRyaWV2ZXMgYW4gYXR0cmlidXRlIG5vZGUgYnkgYnkgcXVhbGlmaWVkIG5hbWUgYW5kIG5hbWVzcGFjZSBVUkkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIGludCBIYW5kbGUgb2YgdGhlIG5vZGUgdXBvbiB3aGljaCB0byBsb29rIHVwIHRoaXMgYXR0cmlidXRlLi4KLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlIHRvCi0gICAqICAgcmV0cmlldmUsIG9yIG51bGwuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgdG8KLSAgICogICByZXRyaWV2ZS4KLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlIG5vZGUgaGFuZGxlIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lICgKLSAgICogICA8Y29kZT5ub2RlTmFtZTwvY29kZT4pIG9yIDxjb2RlPkRUTS5OVUxMPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBzdWNoCi0gICAqICAgYXR0cmlidXRlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBdHRyaWJ1dGVOb2RlKGludCBub2RlSGFuZGxlLCBTdHJpbmcgbmFtZXNwYWNlVVJJLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIGZvciAoaW50IGF0dHJIID0gZ2V0Rmlyc3RBdHRyaWJ1dGUobm9kZUhhbmRsZSk7IERUTS5OVUxMICE9IGF0dHJIOwotICAgICAgICAgICAgYXR0ckggPSBnZXROZXh0QXR0cmlidXRlKGF0dHJIKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0ck5TID0gZ2V0TmFtZXNwYWNlVVJJKGF0dHJIKTsKLSAgICAgIFN0cmluZyBhdHRyTmFtZSA9IGdldExvY2FsTmFtZShhdHRySCk7Ci0gICAgICBib29sZWFuIG5zTWF0Y2ggPSBuYW1lc3BhY2VVUkkgPT0gYXR0ck5TCi0gICAgICAgICAgICAgICAgICAgICAgICB8fCAobmFtZXNwYWNlVVJJICE9IG51bGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBuYW1lc3BhY2VVUkkuZXF1YWxzKGF0dHJOUykpOwotCi0gICAgICBpZiAobnNNYXRjaCAmJiBuYW1lLmVxdWFscyhhdHRyTmFtZSkpCi0gICAgICAgIHJldHVybiBhdHRySDsKLSAgICB9Ci0KLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBvZiB0aGUgZXh0ZXJuYWwgc3Vic2V0LAotICAgKiBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBpbiA0LjIuMiBFeHRlcm5hbCBFbnRpdGllcyBbWE1MXS4gSWYgdGhlcmUgaXMKLSAgICogbm8gZXh0ZXJuYWwgc3Vic2V0IG9yIGlmIGl0IGhhcyBubyBwdWJsaWMgaWRlbnRpZmllciwgdGhpcyBwcm9wZXJ0eQotICAgKiBoYXMgbm8gdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSB0aGUgZG9jdW1lbnQgdHlwZSBkZWNsYXJhdGlvbiBoYW5kbGUKLSAgICoKLSAgICogQHJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgU3RyaW5nIG9iamVjdCwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEZWNsYXJhdGlvblB1YmxpY0lkZW50aWZpZXIoKQotICB7Ci0KLSAgICAvKiogQHRvZG86IGltcGxlbWVudCB0aGlzIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1EZWZhdWx0QmFzZSBhYnN0cmFjdCBtZXRob2QgKi8KLSAgICBlcnJvcihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9NRVRIT0RfTk9UX1NVUFBPUlRFRCwgbnVsbCkpOy8vIk5vdCB5ZXQgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBub2RlIGhhbmRsZSwgcmV0dXJuIGl0cyBET00tc3R5bGUgbmFtZXNwYWNlIFVSSQotICAgKiAoQXMgZGVmaW5lZCBpbiBOYW1lc3BhY2VzLCB0aGlzIGlzIHRoZSBkZWNsYXJlZCBVUkkgd2hpY2ggdGhpcyBub2RlJ3MKLSAgICogcHJlZml4IC0tIG9yIGRlZmF1bHQgaW4gbGlldSB0aGVyZW9mIC0tIHdhcyBtYXBwZWQgdG8uKQotICAgKgotICAgKiA8cD4lUkVWSUVXJSBOdWxsIG9yICIiPyAtc2I8L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBpZCBvZiB0aGUgbm9kZS4KLSAgICogQHJldHVybiBTdHJpbmcgVVJJIHZhbHVlIG9mIHRoaXMgbm9kZSdzIG5hbWVzcGFjZSwgb3IgbnVsbCBpZiBubwotICAgKiBuYW1lc3BhY2Ugd2FzIHJlc29sdmVkLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VVUkkoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIHJldHVybiBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldE5hbWVzcGFjZShfZXhwdHlwZShub2RlSGFuZGxlICYgbV9tYXNrKSk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzdHJpbmctdmFsdWUgb2YgYSBub2RlIGFzIGEgU3RyaW5nIG9iamVjdAotICAgKiAoc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2RhdGEtbW9kZWwKLSAgICogZm9yIHRoZSBkZWZpbml0aW9uIG9mIGEgbm9kZSdzIHN0cmluZy12YWx1ZSkuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIFRoZSBub2RlIElELgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZy12YWx1ZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZ2V0U3RyaW5nVmFsdWUoaW50IG5vZGVIYW5kbGUpCi0gIHsKLQotICAgIGludCBpZGVudGl0eSA9IG5vZGVIYW5kbGUgJiBtX21hc2s7Ci0gICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZShpZGVudGl0eSk7Ci0KLSAgICBpZiAoaXNUZXh0VHlwZSh0eXBlKSkKLSAgICB7Ci0gICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLSAgICAgIGludCBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICBpbnQgbGVuZ3RoID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLQotICAgICAgcmV0dXJuIG1feHN0cmYubmV3c3RyKG1fY2hhcnMsIG9mZnNldCwgbGVuZ3RoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBmaXJzdENoaWxkID0gX2ZpcnN0Y2goaWRlbnRpdHkpOwotCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gZmlyc3RDaGlsZCkKLSAgICAgIHsKLSAgICAgICAgaW50IG9mZnNldCA9IC0xOwotICAgICAgICBpbnQgbGVuZ3RoID0gMDsKLSAgICAgICAgaW50IGxldmVsID0gX2xldmVsKGlkZW50aXR5KTsKLQotICAgICAgICBpZGVudGl0eSA9IGZpcnN0Q2hpbGQ7Ci0KLSAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IGlkZW50aXR5ICYmIChfbGV2ZWwoaWRlbnRpdHkpID4gbGV2ZWwpKQotICAgICAgICB7Ci0gICAgICAgICAgdHlwZSA9IGdldE5vZGVUeXBlKGlkZW50aXR5KTsKLQotICAgICAgICAgIGlmIChpc1RleHRUeXBlKHR5cGUpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGludCBkYXRhSW5kZXggPSBfZGF0YU9yUU5hbWUoaWRlbnRpdHkpOwotCi0gICAgICAgICAgICBpZiAoLTEgPT0gb2Zmc2V0KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBvZmZzZXQgPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGxlbmd0aCArPSBtX2RhdGEuZWxlbWVudEF0KGRhdGFJbmRleCArIDEpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlkZW50aXR5ID0gZ2V0TmV4dE5vZGVJZGVudGl0eShpZGVudGl0eSk7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobGVuZ3RoID4gMCkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBtX3hzdHJmLm5ld3N0cihtX2NoYXJzLCBvZmZzZXQsIGxlbmd0aCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UgaWYodHlwZSAhPSBEVE0uRUxFTUVOVF9OT0RFKQotICAgICAgewotICAgICAgICBpbnQgZGF0YUluZGV4ID0gX2RhdGFPclFOYW1lKGlkZW50aXR5KTsKLQotICAgICAgICBpZiAoZGF0YUluZGV4IDwgMCkKLSAgICAgICAgewotICAgICAgICAgIGRhdGFJbmRleCA9IC1kYXRhSW5kZXg7Ci0gICAgICAgICAgZGF0YUluZGV4ID0gbV9kYXRhLmVsZW1lbnRBdChkYXRhSW5kZXggKyAxKTsKLSAgICAgICAgfQotICAgICAgICByZXR1cm4gbV94c3RyZi5uZXdzdHIobV92YWx1ZXNPclByZWZpeGVzLmluZGV4VG9TdHJpbmcoZGF0YUluZGV4KSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG1feHN0cmYuZW1wdHlzdHIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5FbGVtZW50PC9jb2RlPiB3aG9zZSA8Y29kZT5JRDwvY29kZT4gaXMgZ2l2ZW4gYnkKLSAgICogPGNvZGU+ZWxlbWVudElkPC9jb2RlPi4gSWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0cywgcmV0dXJucwotICAgKiA8Y29kZT5EVE0uTlVMTDwvY29kZT4uIEJlaGF2aW9yIGlzIG5vdCBkZWZpbmVkIGlmIG1vcmUgdGhhbiBvbmUgZWxlbWVudAotICAgKiBoYXMgdGhpcyA8Y29kZT5JRDwvY29kZT4uIEF0dHJpYnV0ZXMgKGluY2x1ZGluZyB0aG9zZQotICAgKiB3aXRoIHRoZSBuYW1lICJJRCIpIGFyZSBub3Qgb2YgdHlwZSBJRCB1bmxlc3Mgc28gZGVmaW5lZCBieSBEVEQvU2NoZW1hCi0gICAqIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB0byB0aGUgRFRNIGltcGxlbWVudGF0aW9uLgotICAgKiBJbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3Qga25vdyB3aGV0aGVyIGF0dHJpYnV0ZXMgYXJlIG9mIHR5cGUgSUQgb3IKLSAgICogbm90IGFyZSBleHBlY3RlZCB0byByZXR1cm4gPGNvZGU+RFRNLk5VTEw8L2NvZGU+LgotICAgKgotICAgKiA8cD4lUkVWSUVXJSBQcmVzdW1hYmx5IElEcyBhcmUgc3RpbGwgc2NvcGVkIHRvIGEgc2luZ2xlIGRvY3VtZW50LAotICAgKiBhbmQgdGhpcyBvcGVyYXRpb24gc2VhcmNoZXMgb25seSB3aXRoaW4gYSBzaW5nbGUgZG9jdW1lbnQsIHJpZ2h0PwotICAgKiBXb3VsZG4ndCB3YW50IGNvbGxpc2lvbnMgYmV0d2VlbiBEVE1zIGluIHRoZSBzYW1lIHByb2Nlc3MuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIFRoZSB1bmlxdWUgPGNvZGU+aWQ8L2NvZGU+IHZhbHVlIGZvciBhbiBlbGVtZW50LgotICAgKiBAcmV0dXJuIFRoZSBoYW5kbGUgb2YgdGhlIG1hdGNoaW5nIGVsZW1lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpCi0gIHsKLQotICAgIEludGVnZXIgaW50T2JqOwotICAgIGJvb2xlYW4gaXNNb3JlID0gdHJ1ZTsKLQotICAgIGRvCi0gICAgewotICAgICAgaW50T2JqID0gKEludGVnZXIpIG1faWRBdHRyaWJ1dGVzLmdldChlbGVtZW50SWQpOwotCi0gICAgICBpZiAobnVsbCAhPSBpbnRPYmopCi0gICAgICAgIHJldHVybiBpbnRPYmouaW50VmFsdWUoKSB8IG1fZHRtSWRlbnQ7Ci0KLSAgICAgIGlmICghaXNNb3JlIHx8IG1fZW5kRG9jdW1lbnRPY2N1cmVkKQotICAgICAgICBicmVhazsKLQotICAgICAgaXNNb3JlID0gbmV4dE5vZGUoKTsKLSAgICB9Ci0gICAgd2hpbGUgKG51bGwgPT0gaW50T2JqKTsKLQotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBwcmVmaXggZWl0aGVyIGZyb20gdGhlIHFuYW1lIG9yIGZyb20gdGhlIHVyaSBtYXBwaW5nLCBvciBqdXN0IG1ha2UKLSAgICogb25lIHVwIQotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgVGhlIHF1YWxpZmllZCBuYW1lLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIHVyaSBUaGUgbmFtZXNwYWNlIFVSSSwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByZWZpeCBpZiB0aGVyZSBpcyBvbmUsIG9yIG51bGwuCi0gICAqLwotICBwcml2YXRlIFN0cmluZyBnZXRQcmVmaXgoU3RyaW5nIHFuYW1lLCBTdHJpbmcgdXJpKQotICB7Ci0KLSAgICBTdHJpbmcgcHJlZml4OwotICAgIGludCB1cmlJbmRleCA9IC0xOwotCi0gICAgaWYgKG51bGwgIT0gdXJpICYmIHVyaS5sZW5ndGgoKSA+IDApCi0gICAgewotCi0gICAgICBkbwotICAgICAgewotICAgICAgICB1cmlJbmRleCA9IG1fcHJlZml4TWFwcGluZ3MuaW5kZXhPZih1cmksICsrdXJpSW5kZXgpOwotICAgICAgfSB3aGlsZSAoICh1cmlJbmRleCAmIDB4MDEpID09IDApOwotCi0gICAgICBpZiAodXJpSW5kZXggPj0gMCkKLSAgICAgIHsKLSAgICAgICAgcHJlZml4ID0gKFN0cmluZykgbV9wcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQodXJpSW5kZXggLSAxKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKG51bGwgIT0gcW5hbWUpCi0gICAgICB7Ci0gICAgICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgICAgaWYgKHFuYW1lLmVxdWFscygieG1sbnMiKSkKLSAgICAgICAgICBwcmVmaXggPSAiIjsKLSAgICAgICAgZWxzZSBpZiAocW5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpCi0gICAgICAgICAgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKGluZGV4T2ZOU1NlcCArIDEpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgcHJlZml4ID0gKGluZGV4T2ZOU1NlcCA+IDApCi0gICAgICAgICAgICAgICAgICAgPyBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKSA6IG51bGw7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHByZWZpeCA9IG51bGw7ICAvLyA/PwotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChudWxsICE9IHFuYW1lKQotICAgIHsKLSAgICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICAgIGlmIChxbmFtZS5lcXVhbHMoInhtbG5zIikpCi0gICAgICAgIHByZWZpeCA9ICIiOwotICAgICAgZWxzZSBpZiAocW5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikpCi0gICAgICAgIHByZWZpeCA9IHFuYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLSAgICAgIGVsc2UKLSAgICAgICAgcHJlZml4ID0gKGluZGV4T2ZOU1NlcCA+IDApID8gcW5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCkgOiBudWxsOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcHJlZml4ID0gbnVsbDsKLSAgICB9Ci0KLSAgICByZXR1cm4gcHJlZml4OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBJRCBzdHJpbmcgdG8gbm9kZSBhc3NvY2lhdGlvbiBpbiB0aGUgSUQgdGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBpZCBUaGUgSUQgc3RyaW5nLgotICAgKiBAcGFyYW0gZWxlbSBUaGUgYXNzb2NpYXRlZCBlbGVtZW50IGhhbmRsZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElEQXR0cmlidXRlKFN0cmluZyBpZCwgaW50IGVsZW0pCi0gIHsKLSAgICBtX2lkQXR0cmlidXRlcy5wdXQoaWQsIG5ldyBJbnRlZ2VyKGVsZW0pKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB3aGV0aGVyIGFjY3VtdWxhdGVkIHRleHQgc2hvdWxkIGJlIHN0cmlwcGVkOyBpZiBub3QsCi0gICAqIGFwcGVuZCB0aGUgYXBwcm9wcmlhdGUgZmxhdm9yIG9mIHRleHQvY2RhdGEgbm9kZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNoYXJhY3RlcnNGbHVzaCgpCi0gIHsKLQotICAgIGlmIChtX3RleHRQZW5kaW5nU3RhcnQgPj0gMCkgIC8vIC0xIGluZGljYXRlcyBuby10ZXh0LWluLXByb2dyZXNzCi0gICAgewotICAgICAgaW50IGxlbmd0aCA9IG1fY2hhcnMuc2l6ZSgpIC0gbV90ZXh0UGVuZGluZ1N0YXJ0OwotICAgICAgYm9vbGVhbiBkb1N0cmlwID0gZmFsc2U7Ci0KLSAgICAgIGlmIChnZXRTaG91bGRTdHJpcFdoaXRlc3BhY2UoKSkKLSAgICAgIHsKLSAgICAgICAgZG9TdHJpcCA9IG1fY2hhcnMuaXNXaGl0ZXNwYWNlKG1fdGV4dFBlbmRpbmdTdGFydCwgbGVuZ3RoKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGRvU3RyaXApCi0gICAgICAgIG1fY2hhcnMuc2V0TGVuZ3RoKG1fdGV4dFBlbmRpbmdTdGFydCk7ICAvLyBEaXNjYXJkIGFjY3VtdWxhdGVkIHRleHQKLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IGV4TmFtZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQoRFRNLlRFWFRfTk9ERSk7Ci0gICAgICAgIGludCBkYXRhSW5kZXggPSBtX2RhdGEuc2l6ZSgpOwotCi0gICAgICAgIG1fcHJldmlvdXMgPSBhZGROb2RlKG1fY29hbGVzY2VkVGV4dFR5cGUsIGV4TmFtZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXJlbnRzLnBlZWsoKSwgbV9wcmV2aW91cywgZGF0YUluZGV4LCBmYWxzZSk7Ci0KLSAgICAgICAgbV9kYXRhLmFkZEVsZW1lbnQobV90ZXh0UGVuZGluZ1N0YXJ0KTsKLSAgICAgICAgbV9kYXRhLmFkZEVsZW1lbnQobGVuZ3RoKTsKLSAgICAgIH0KLQotICAgICAgLy8gUmVzZXQgZm9yIG5leHQgdGV4dCBibG9jawotICAgICAgbV90ZXh0UGVuZGluZ1N0YXJ0ID0gLTE7Ci0gICAgICBtX3RleHRUeXBlID0gbV9jb2FsZXNjZWRUZXh0VHlwZSA9IERUTS5URVhUX05PREU7Ci0gICAgfQotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIEVudGl0eVJlc29sdmVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVzb2x2ZSBhbiBleHRlcm5hbCBlbnRpdHkuCi0gICAqCi0gICAqIDxwPkFsd2F5cyByZXR1cm4gbnVsbCwgc28gdGhhdCB0aGUgcGFyc2VyIHdpbGwgdXNlIHRoZSBzeXN0ZW0KLSAgICogaWRlbnRpZmllciBwcm92aWRlZCBpbiB0aGUgWE1MIGRvY3VtZW50LiAgVGhpcyBtZXRob2QgaW1wbGVtZW50cwotICAgKiB0aGUgU0FYIGRlZmF1bHQgYmVoYXZpb3VyOiBhcHBsaWNhdGlvbiB3cml0ZXJzIGNhbiBvdmVycmlkZSBpdAotICAgKiBpbiBhIHN1YmNsYXNzIHRvIGRvIHNwZWNpYWwgdHJhbnNsYXRpb25zIHN1Y2ggYXMgY2F0YWxvZyBsb29rdXBzCi0gICAqIG9yIFVSSSByZWRpcmVjdGlvbi48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgcHVibGljIGlkZW50aWZlciwgb3IgbnVsbCBpZiBub25lIGlzCi0gICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgc3lzdGVtIGlkZW50aWZpZXIgcHJvdmlkZWQgaW4gdGhlIFhNTAotICAgKiAgICAgICAgICAgICAgICAgZG9jdW1lbnQuCi0gICAqIEByZXR1cm4gVGhlIG5ldyBpbnB1dCBzb3VyY2UsIG9yIG51bGwgdG8gcmVxdWlyZSB0aGUKLSAgICogICAgICAgICBkZWZhdWx0IGJlaGF2aW91ci4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXIjcmVzb2x2ZUVudGl0eQotICAgKgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCi0gICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBJbXBsZW1lbnRhdGlvbiBvZiBEVERIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub3RhdGlvbiBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgaWYgdGhleSB3aXNoIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG5vdGF0aW9ucwotICAgKiBkZWNsYXJlZCBpbiBhIGRvY3VtZW50LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5vdGF0aW9uIG5hbWUuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbm90YXRpb24gcHVibGljIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgbm90Ci0gICAqICAgICAgICAgICAgICAgICBhdmFpbGFibGUuCi0gICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbm90YXRpb24gc3lzdGVtIGlkZW50aWZpZXIuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkRUREhhbmRsZXIjbm90YXRpb25EZWNsCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBub3RhdGlvbkRlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8gb3AKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhbiB1bnBhcnNlZCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHVucGFyc2VkIGVudGl0aWVzCi0gICAqIGRlY2xhcmVkIGluIGEgZG9jdW1lbnQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZW50aXR5IG5hbWUuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZW50aXR5IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIGlmIG5vdAotICAgKiAgICAgICAgICAgICAgICAgYXZhaWxhYmxlLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGVudGl0eSBzeXN0ZW0gaWRlbnRpZmllci4KLSAgICogQHBhcmFtIG5vdGF0aW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBub3RhdGlvbi4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbCgKLSAgICAgICAgICBTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQsIFN0cmluZyBub3RhdGlvbk5hbWUpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fZW50aXRpZXMpCi0gICAgewotICAgICAgbV9lbnRpdGllcyA9IG5ldyBWZWN0b3IoKTsKLSAgICB9Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBzeXN0ZW1JZCA9IFN5c3RlbUlEUmVzb2x2ZXIuZ2V0QWJzb2x1dGVVUkkoc3lzdGVtSWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RG9jdW1lbnRCYXNlVVJJKCkpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbihlKTsKLSAgICB9Ci0KLSAgICAvLyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVOVElUWV9GSUVMRF9QVUJMSUNJRCA9IDA7Ci0gICAgbV9lbnRpdGllcy5hZGRFbGVtZW50KHB1YmxpY0lkKTsKLQotICAgIC8vICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZX0ZJRUxEX1NZU1RFTUlEID0gMTsKLSAgICBtX2VudGl0aWVzLmFkZEVsZW1lbnQoc3lzdGVtSWQpOwotCi0gICAgLy8gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFTlRJVFlfRklFTERfTk9UQVRJT05OQU1FID0gMjsKLSAgICBtX2VudGl0aWVzLmFkZEVsZW1lbnQobm90YXRpb25OYW1lKTsKLQotICAgIC8vICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRU5USVRZX0ZJRUxEX05BTUUgPSAzOwotICAgIG1fZW50aXRpZXMuYWRkRWxlbWVudChuYW1lKTsKLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIENvbnRlbnRIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVjZWl2ZSBhIExvY2F0b3Igb2JqZWN0IGZvciBkb2N1bWVudCBldmVudHMuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIGlmIHRoZXkgd2lzaCB0byBzdG9yZSB0aGUgbG9jYXRvciBmb3IgdXNlCi0gICAqIHdpdGggb3RoZXIgZG9jdW1lbnQgZXZlbnRzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0b3IgQSBsb2NhdG9yIGZvciBhbGwgU0FYIGRvY3VtZW50IGV2ZW50cy4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNzZXREb2N1bWVudExvY2F0b3IKLSAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREb2N1bWVudExvY2F0b3IoTG9jYXRvciBsb2NhdG9yKQotICB7Ci0gICAgbV9sb2NhdG9yID0gbG9jYXRvcjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBiZWdpbm5pbmcKLSAgICogb2YgYSBkb2N1bWVudCAoc3VjaCBhcyBhbGxvY2F0aW5nIHRoZSByb290IG5vZGUgb2YgYSB0cmVlIG9yCi0gICAqIGNyZWF0aW5nIGFuIG91dHB1dCBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI3N0YXJ0RG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RG9jdW1lbnQoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgZG9jID0gYWRkTm9kZShEVE0uRE9DVU1FTlRfTk9ERSwKLSAgICAgICAgICAgICAgICAgICAgICBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKERUTS5ET0NVTUVOVF9OT0RFKSwKLSAgICAgICAgICAgICAgICAgICAgICBEVE0uTlVMTCwgRFRNLk5VTEwsIDAsIHRydWUpOwotCi0gICAgbV9wYXJlbnRzLnB1c2goZG9jKTsKLQotICAgIG1fcHJldmlvdXMgPSBEVE0uTlVMTDsKLQotICAgIG1fY29udGV4dEluZGV4ZXMucHVzaChtX3ByZWZpeE1hcHBpbmdzLnNpemUoKSk7ICAvLyBmb3IgdGhlIG5leHQgZWxlbWVudC4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBlbmQKLSAgICogb2YgYSBkb2N1bWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBvciBjbG9zaW5nIGFuIG91dHB1dAotICAgKiBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyI2VuZERvY3VtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChOVUxMLDApOwotCi0gICAgaWYgKG1fZmlyc3RjaC5lbGVtZW50QXQoMCkgPT0gTk9UUFJPQ0VTU0VEKQotICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChOVUxMLDApOwotCi0gICAgaWYgKERUTS5OVUxMICE9IG1fcHJldmlvdXMpCi0gICAgICBtX25leHRzaWIuc2V0RWxlbWVudEF0KERUTS5OVUxMLG1fcHJldmlvdXMpOwotCi0gICAgbV9wYXJlbnRzID0gbnVsbDsKLSAgICBtX3ByZWZpeE1hcHBpbmdzID0gbnVsbDsKLSAgICBtX2NvbnRleHRJbmRleGVzID0gbnVsbDsKLQotICAgIG1fZW5kRG9jdW1lbnRPY2N1cmVkID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgc3RhcnQgb2YgYSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGF0IHRoZSBzdGFydCBvZgotICAgKiBlYWNoIE5hbWVzcGFjZSBwcmVmaXggc2NvcGUgKHN1Y2ggYXMgc3RvcmluZyB0aGUgcHJlZml4IG1hcHBpbmcpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSBtYXBwZWQgdG8gdGhlIHByZWZpeC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRQcmVmaXhNYXBwaW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydFByZWZpeE1hcHBpbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIHVyaSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnRQcmVmaXhNYXBwaW5nOiBwcmVmaXg6ICIgKyBwcmVmaXggKyAiLCB1cmk6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICArIHVyaSk7Ci0KLSAgICBpZihudWxsID09IHByZWZpeCkKLSAgICAgIHByZWZpeCA9ICIiOwotICAgIG1fcHJlZml4TWFwcGluZ3MuYWRkRWxlbWVudChwcmVmaXgpOyAgLy8gSkRLIDEuMS54IGNvbXBhdCAtc2MKLSAgICBtX3ByZWZpeE1hcHBpbmdzLmFkZEVsZW1lbnQodXJpKTsgIC8vIEpESyAxLjEueCBjb21wYXQgLXNjCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIE5hbWVzcGFjZSBtYXBwaW5nLgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgYXQgdGhlIGVuZCBvZgotICAgKiBlYWNoIHByZWZpeCBtYXBwaW5nLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgTmFtZXNwYWNlIHByZWZpeCBiZWluZyBkZWNsYXJlZC4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjZW5kUHJlZml4TWFwcGluZwotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChERUJVRykKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kUHJlZml4TWFwcGluZzogcHJlZml4OiAiICsgcHJlZml4KTsKLQotICAgIGlmKG51bGwgPT0gcHJlZml4KQotICAgICAgcHJlZml4ID0gIiI7Ci0KLSAgICBpbnQgaW5kZXggPSBtX2NvbnRleHRJbmRleGVzLnBlZWsoKSAtIDE7Ci0KLSAgICBkbwotICAgIHsKLSAgICAgIGluZGV4ID0gbV9wcmVmaXhNYXBwaW5ncy5pbmRleE9mKHByZWZpeCwgKytpbmRleCk7Ci0gICAgfSB3aGlsZSAoIChpbmRleCA+PSAwKSAmJiAoKGluZGV4ICYgMHgwMSkgPT0gMHgwMSkgKTsKLQotCi0gICAgaWYgKGluZGV4ID4gLTEpCi0gICAgewotICAgICAgbV9wcmVmaXhNYXBwaW5ncy5zZXRFbGVtZW50QXQoIiVAJCNeQCMiLCBpbmRleCk7Ci0gICAgICBtX3ByZWZpeE1hcHBpbmdzLnNldEVsZW1lbnRBdCgiJUAkI15AIyIsIGluZGV4ICsgMSk7Ci0gICAgfQotCi0gICAgLy8gbm8gb3AKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayBpZiBhIGRlY2xhcmF0aW9uIGhhcyBhbHJlYWR5IGJlZW4gbWFkZSBmb3IgYSBnaXZlbiBwcmVmaXguCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggbm9uLW51bGwgcHJlZml4IHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBkZWNsYXJhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIGRlY2xhcmVkIGluIHRoZQotICAgKiAgICAgICAgIGN1cnJlbnQgY29udGV4dC4KLSAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIGRlY2xBbHJlYWR5RGVjbGFyZWQoU3RyaW5nIHByZWZpeCkKLSAgewotCi0gICAgaW50IHN0YXJ0RGVjbHMgPSBtX2NvbnRleHRJbmRleGVzLnBlZWsoKTsKLSAgICBqYXZhLnV0aWwuVmVjdG9yIHByZWZpeE1hcHBpbmdzID0gbV9wcmVmaXhNYXBwaW5nczsKLSAgICBpbnQgbkRlY2xzID0gcHJlZml4TWFwcGluZ3Muc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IHN0YXJ0RGVjbHM7IGkgPCBuRGVjbHM7IGkgKz0gMikKLSAgICB7Ci0gICAgICBTdHJpbmcgcHJlZml4RGVjbCA9IChTdHJpbmcpIHByZWZpeE1hcHBpbmdzLmVsZW1lbnRBdChpKTsKLQotICAgICAgaWYgKHByZWZpeERlY2wgPT0gbnVsbCkKLSAgICAgICAgY29udGludWU7Ci0KLSAgICAgIGlmIChwcmVmaXhEZWNsLmVxdWFscyhwcmVmaXgpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YKLSAgICogZWFjaCBlbGVtZW50IChzdWNoIGFzIGFsbG9jYXRpbmcgYSBuZXcgdHJlZSBub2RlIG9yIHdyaXRpbmcKLSAgICogb3V0cHV0IHRvIGEgZmlsZSkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBuYW1lICh3aXRoIHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIHNwZWNpZmllZCBvciBkZWZhdWx0ZWQgYXR0cmlidXRlcy4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjc3RhcnRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSwgU3RyaW5nIHFOYW1lLCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpCi0gICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBjaGFyYWN0ZXJzRmx1c2goKTsKLQotICAgIGludCBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKHVyaSwgbG9jYWxOYW1lLCBEVE0uRUxFTUVOVF9OT0RFKTsKLSAgICBTdHJpbmcgcHJlZml4ID0gZ2V0UHJlZml4KHFOYW1lLCB1cmkpOwotICAgIGludCBwcmVmaXhJbmRleCA9IChudWxsICE9IHByZWZpeCkKLSAgICAgICAgICAgICAgICAgICAgICA/IG1fdmFsdWVzT3JQcmVmaXhlcy5zdHJpbmdUb0luZGV4KHFOYW1lKSA6IDA7Ci0gICAgaW50IGVsZW1Ob2RlID0gYWRkTm9kZShEVE0uRUxFTUVOVF9OT0RFLCBleE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBtX3BhcmVudHMucGVlaygpLCBtX3ByZXZpb3VzLCBwcmVmaXhJbmRleCwgdHJ1ZSk7Ci0KLSAgICBpbmRleE5vZGUoZXhOYW1lLCBlbGVtTm9kZSk7Ci0gICAgCi0gICAgbV9wYXJlbnRzLnB1c2goZWxlbU5vZGUpOwotCi0gICAgaW50IHN0YXJ0RGVjbHMgPSBtX2NvbnRleHRJbmRleGVzLnBlZWsoKTsKLSAgICBpbnQgbkRlY2xzID0gbV9wcmVmaXhNYXBwaW5ncy5zaXplKCk7Ci0gICAgaW50IHByZXYgPSBEVE0uTlVMTDsKLQotICAgIGZvciAoaW50IGkgPSBzdGFydERlY2xzOyBpIDwgbkRlY2xzOyBpICs9IDIpCi0gICAgewotICAgICAgcHJlZml4ID0gKFN0cmluZykgbV9wcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQoaSk7Ci0KLSAgICAgIGlmIChwcmVmaXggPT0gbnVsbCkKLSAgICAgICAgY29udGludWU7Ci0KLSAgICAgIFN0cmluZyBkZWNsVVJMID0gKFN0cmluZykgbV9wcmVmaXhNYXBwaW5ncy5lbGVtZW50QXQoaSArIDEpOwotCi0gICAgICBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKG51bGwsIHByZWZpeCwgRFRNLk5BTUVTUEFDRV9OT0RFKTsKLQotICAgICAgaW50IHZhbCA9IG1fdmFsdWVzT3JQcmVmaXhlcy5zdHJpbmdUb0luZGV4KGRlY2xVUkwpOwotCi0gICAgICBwcmV2ID0gYWRkTm9kZShEVE0uTkFNRVNQQUNFX05PREUsIGV4TmFtZSwgZWxlbU5vZGUsCi0gICAgICAgICAgICAgICAgICAgICBwcmV2LCB2YWwsIGZhbHNlKTsKLSAgICB9Ci0KLSAgICBpbnQgbiA9IGF0dHJpYnV0ZXMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0clVyaSA9IGF0dHJpYnV0ZXMuZ2V0VVJJKGkpOwotICAgICAgU3RyaW5nIGF0dHJRTmFtZSA9IGF0dHJpYnV0ZXMuZ2V0UU5hbWUoaSk7Ci0gICAgICBTdHJpbmcgdmFsU3RyaW5nID0gYXR0cmlidXRlcy5nZXRWYWx1ZShpKTsKLQotICAgICAgcHJlZml4ID0gZ2V0UHJlZml4KGF0dHJRTmFtZSwgYXR0clVyaSk7Ci0KLSAgICAgIGludCBub2RlVHlwZTsKLQotICAgICAgaWYgKChudWxsICE9IGF0dHJRTmFtZSkKLSAgICAgICAgICAgICAgJiYgKGF0dHJRTmFtZS5lcXVhbHMoInhtbG5zIikKLSAgICAgICAgICAgICAgICAgIHx8IGF0dHJRTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkpCi0gICAgICB7Ci0gICAgICAgIGlmIChkZWNsQWxyZWFkeURlY2xhcmVkKHByZWZpeCkpCi0gICAgICAgICAgY29udGludWU7ICAvLyBnbyB0byB0aGUgbmV4dCBhdHRyaWJ1dGUuCi0KLSAgICAgICAgbm9kZVR5cGUgPSBEVE0uTkFNRVNQQUNFX05PREU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG5vZGVUeXBlID0gRFRNLkFUVFJJQlVURV9OT0RFOwotCi0gICAgICAgIGlmIChhdHRyaWJ1dGVzLmdldFR5cGUoaSkuZXF1YWxzSWdub3JlQ2FzZSgiSUQiKSkKLSAgICAgICAgICBzZXRJREF0dHJpYnV0ZSh2YWxTdHJpbmcsIGVsZW1Ob2RlKTsKLSAgICAgIH0KLSAgICAgIAotICAgICAgLy8gQml0IG9mIGEgaGFjay4uLiBpZiBzb21laG93IHZhbFN0cmluZyBpcyBudWxsLCBzdHJpbmdUb0luZGV4IHdpbGwgCi0gICAgICAvLyByZXR1cm4gLTEsIHdoaWNoIHdpbGwgbWFrZSB0aGluZ3MgdmVyeSB1bmhhcHB5LgotICAgICAgaWYobnVsbCA9PSB2YWxTdHJpbmcpCi0gICAgICAgIHZhbFN0cmluZyA9ICIiOwotCi0gICAgICBpbnQgdmFsID0gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgodmFsU3RyaW5nKTsKLSAgICAgIFN0cmluZyBhdHRyTG9jYWxOYW1lID0gYXR0cmlidXRlcy5nZXRMb2NhbE5hbWUoaSk7Ci0KLSAgICAgIGlmIChudWxsICE9IHByZWZpeCkKLSAgICAgIHsKLSAgICAgICAgCi0gICAgICAgIHByZWZpeEluZGV4ID0gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgoYXR0clFOYW1lKTsKLQotICAgICAgICBpbnQgZGF0YUluZGV4ID0gbV9kYXRhLnNpemUoKTsKLQotICAgICAgICBtX2RhdGEuYWRkRWxlbWVudChwcmVmaXhJbmRleCk7Ci0gICAgICAgIG1fZGF0YS5hZGRFbGVtZW50KHZhbCk7Ci0KLSAgICAgICAgdmFsID0gLWRhdGFJbmRleDsKLSAgICAgIH0KLQotICAgICAgZXhOYW1lID0gbV9leHBhbmRlZE5hbWVUYWJsZS5nZXRFeHBhbmRlZFR5cGVJRChhdHRyVXJpLCBhdHRyTG9jYWxOYW1lLCBub2RlVHlwZSk7Ci0gICAgICBwcmV2ID0gYWRkTm9kZShub2RlVHlwZSwgZXhOYW1lLCBlbGVtTm9kZSwgcHJldiwgdmFsLAotICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotICAgIH0KLQotICAgIGlmIChEVE0uTlVMTCAhPSBwcmV2KQotICAgICAgbV9uZXh0c2liLnNldEVsZW1lbnRBdChEVE0uTlVMTCxwcmV2KTsKLQotICAgIGlmIChudWxsICE9IG1fd3NmaWx0ZXIpCi0gICAgewotICAgICAgc2hvcnQgd3N2ID0gbV93c2ZpbHRlci5nZXRTaG91bGRTdHJpcFNwYWNlKGVsZW1Ob2RlIHwgbV9kdG1JZGVudCwgdGhpcyk7Ci0gICAgICBib29sZWFuIHNob3VsZFN0cmlwID0gKERUTVdTRmlsdGVyLklOSEVSSVQgPT0gd3N2KQotICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZ2V0U2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChEVE1XU0ZpbHRlci5TVFJJUCA9PSB3c3YpOwotCi0gICAgICBwdXNoU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKHNob3VsZFN0cmlwKTsKLSAgICB9Ci0KLSAgICBtX3ByZXZpb3VzID0gRFRNLk5VTEw7Ci0KLSAgICBtX2NvbnRleHRJbmRleGVzLnB1c2gobV9wcmVmaXhNYXBwaW5ncy5zaXplKCkpOyAgLy8gZm9yIHRoZSBjaGlsZHJlbi4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgZW5kIG9mIGFuIGVsZW1lbnQuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucyBhdCB0aGUgZW5kIG9mCi0gICAqIGVhY2ggZWxlbWVudCAoc3VjaCBhcyBmaW5hbGlzaW5nIGEgdHJlZSBub2RlIG9yIHdyaXRpbmcKLSAgICogb3V0cHV0IHRvIGEgZmlsZSkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgZWxlbWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBzcGVjaWZpZWQgb3IgZGVmYXVsdGVkIGF0dHJpYnV0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgdGhlCi0gICAqICAgICAgICBlbGVtZW50IGhhcyBubyBOYW1lc3BhY2UgVVJJIG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lICh3aXRob3V0IHByZWZpeCksIG9yIHRoZQotICAgKiAgICAgICAgZW1wdHkgc3RyaW5nIGlmIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZwotICAgKiAgICAgICAgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCBYTUwgMS4wIG5hbWUgKHdpdGggcHJlZml4KSwgb3IgdGhlCi0gICAqICAgICAgICBlbXB0eSBzdHJpbmcgaWYgcXVhbGlmaWVkIG5hbWVzIGFyZSBub3QgYXZhaWxhYmxlLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNlbmRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgLy8gSWYgbm8gb25lIG5vdGljZWQsIHN0YXJ0UHJlZml4TWFwcGluZyBpcyBhIGRyYWcuCi0gICAgLy8gUG9wIHRoZSBjb250ZXh0IGZvciB0aGUgbGFzdCBjaGlsZCAodGhlIG9uZSBwdXNoZWQgYnkgc3RhcnRFbGVtZW50KQotICAgIG1fcHJlZml4TWFwcGluZ3Muc2V0U2l6ZShtX2NvbnRleHRJbmRleGVzLnBvcCgpKTsKLQotICAgIC8vIERvIGl0IGFnYWluIGZvciB0aGlzIG9uZSAodGhlIG9uZSBwdXNoZWQgYnkgdGhlIGxhc3QgZW5kRWxlbWVudCkuCi0gICAgbV9wcmVmaXhNYXBwaW5ncy5zZXRTaXplKG1fY29udGV4dEluZGV4ZXMucG9wKCkpOwotICAgIG1fY29udGV4dEluZGV4ZXMucHVzaChtX3ByZWZpeE1hcHBpbmdzLnNpemUoKSk7ICAvLyBmb3IgdGhlIG5leHQgZWxlbWVudC4KLQotICAgIGludCBsYXN0Tm9kZSA9IG1fcHJldmlvdXM7Ci0KLSAgICBtX3ByZXZpb3VzID0gbV9wYXJlbnRzLnBvcCgpOwotCi0gICAgaWYgKE5PVFBST0NFU1NFRCA9PSBtX2ZpcnN0Y2guZWxlbWVudEF0KG1fcHJldmlvdXMpKQotICAgICAgbV9maXJzdGNoLnNldEVsZW1lbnRBdChEVE0uTlVMTCxtX3ByZXZpb3VzKTsKLSAgICBlbHNlIGlmIChEVE0uTlVMTCAhPSBsYXN0Tm9kZSkKLSAgICAgIG1fbmV4dHNpYi5zZXRFbGVtZW50QXQoRFRNLk5VTEwsbGFzdE5vZGUpOwotCi0gICAgcG9wU2hvdWxkU3RyaXBXaGl0ZXNwYWNlKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2hhcmFjdGVyIGRhdGEgaW5zaWRlIGFuIGVsZW1lbnQuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2ggY2h1bmsgb2YgY2hhcmFjdGVyIGRhdGEKLSAgICogKHN1Y2ggYXMgYWRkaW5nIHRoZSBkYXRhIHRvIGEgbm9kZSBvciBidWZmZXIsIG9yIHByaW50aW5nIGl0IHRvCi0gICAqIGEgZmlsZSkuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gdXNlIGZyb20gdGhlCi0gICAqICAgICAgICAgICAgICAgY2hhcmFjdGVyIGFycmF5LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNjaGFyYWN0ZXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX3RleHRQZW5kaW5nU3RhcnQgPT0gLTEpICAvLyBGaXJzdCBvbmUgaW4gdGhpcyBibG9jawotICAgIHsKLSAgICAgIG1fdGV4dFBlbmRpbmdTdGFydCA9IG1fY2hhcnMuc2l6ZSgpOwotICAgICAgbV9jb2FsZXNjZWRUZXh0VHlwZSA9IG1fdGV4dFR5cGU7Ci0gICAgfQotCi0gICAgbV9jaGFycy5hcHBlbmQoY2gsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgLy8gVHlwZSBsb2dpYzogSWYgYWxsIGFkamFjZW50IHRleHQgaXMgQ0RBVEFTZWN0aW9ucywgdGhlCi0gICAgLy8gY29uY2F0ZW50YXRlZCB0ZXh0IGlzIHRyZWF0ZWQgYXMgYSBzaW5nbGUgQ0RBVEFTZWN0aW9uIChzZWUKLSAgICAvLyBpbml0aWFsaXphdGlvbiBhYm92ZSkuICBJZiBhbnkgd2VyZSBvcmRpbmFyeSBUZXh0LCB0aGUgd2hvbGUKLSAgICAvLyB0aGluZyBpcyB0cmVhdGVkIGFzIFRleHQuIFRoaXMgbWF5IGJlIHdvcnRoICVSRVZJRVclaW5nLgotICAgIGlmIChtX3RleHRUeXBlID09IERUTS5URVhUX05PREUpCi0gICAgICBtX2NvYWxlc2NlZFRleHRUeXBlID0gRFRNLlRFWFRfTk9ERTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPkJ5IGRlZmF1bHQsIGRvIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzIG1heSBvdmVycmlkZSB0aGlzCi0gICAqIG1ldGhvZCB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2ggY2h1bmsgb2YgaWdub3JhYmxlCi0gICAqIHdoaXRlc3BhY2UgKHN1Y2ggYXMgYWRkaW5nIGRhdGEgdG8gYSBub2RlIG9yIGJ1ZmZlciwgb3IgcHJpbnRpbmcKLSAgICogaXQgdG8gYSBmaWxlKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBjaGFyYWN0ZXIgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHVzZSBmcm9tIHRoZQotICAgKiAgICAgICAgICAgICAgIGNoYXJhY3RlciBhcnJheS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgKi8KLSAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vICVPUFQlIFdlIGNhbiBwcm9iYWJseSB0YWtlIGFkdmFudGFnZSBvZiB0aGUgZmFjdCB0aGF0IHdlIGtub3cgdGhpcyAKLSAgICAvLyBpcyB3aGl0ZXNwYWNlLgotICAgIGNoYXJhY3RlcnMoY2gsIHN0YXJ0LCBsZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi4KLSAgICoKLSAgICogPHA+QnkgZGVmYXVsdCwgZG8gbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMgbWF5IG92ZXJyaWRlIHRoaXMKLSAgICogbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoCi0gICAqIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24sIHN1Y2ggYXMgc2V0dGluZyBzdGF0dXMgdmFyaWFibGVzIG9yCi0gICAqIGludm9raW5nIG90aGVyIG1ldGhvZHMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIHRhcmdldC4KLSAgICogQHBhcmFtIGRhdGEgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gZGF0YSwgb3IgbnVsbCBpZgotICAgKiAgICAgICAgICAgICBub25lIGlzIHN1cHBsaWVkLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIGNoYXJhY3RlcnNGbHVzaCgpOwotCi0gICAgaW50IGV4TmFtZSA9IG1fZXhwYW5kZWROYW1lVGFibGUuZ2V0RXhwYW5kZWRUeXBlSUQobnVsbCwgdGFyZ2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFKTsKLSAgICBpbnQgZGF0YUluZGV4ID0gbV92YWx1ZXNPclByZWZpeGVzLnN0cmluZ1RvSW5kZXgoZGF0YSk7Ci0KLSAgICBtX3ByZXZpb3VzID0gYWRkTm9kZShEVE0uUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFLCBleE5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXJlbnRzLnBlZWsoKSwgbV9wcmV2aW91cywKLSAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXgsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHNraXBwZWQgZW50aXR5LgotICAgKgotICAgKiA8cD5CeSBkZWZhdWx0LCBkbyBub3RoaW5nLiAgQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcwotICAgKiBtZXRob2QgaW4gYSBzdWJjbGFzcyB0byB0YWtlIHNwZWNpZmljIGFjdGlvbnMgZm9yIGVhY2gKLSAgICogcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgc3VjaCBhcyBzZXR0aW5nIHN0YXR1cyB2YXJpYWJsZXMgb3IKLSAgICogaW52b2tpbmcgb3RoZXIgbWV0aG9kcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBza2lwcGVkIGVudGl0eS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjcHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBza2lwcGVkRW50aXR5KFN0cmluZyBuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vICVSRVZJRVclIFdoYXQgc2hvdWxkIGJlIGRvbmUgaGVyZT8KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIEVycm9ySGFuZGxlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcGFyc2VyIHdhcm5pbmcuCi0gICAqCi0gICAqIDxwPlRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4gIEFwcGxpY2F0aW9uIHdyaXRlcnMKLSAgICogbWF5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGluIGEgc3ViY2xhc3MgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zCi0gICAqIGZvciBlYWNoIHdhcm5pbmcsIHN1Y2ggYXMgaW5zZXJ0aW5nIHRoZSBtZXNzYWdlIGluIGEgbG9nIGZpbGUgb3IKLSAgICogcHJpbnRpbmcgaXQgdG8gdGhlIGNvbnNvbGUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZSBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNvZGVkIGFzIGFuIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRXJyb3JIYW5kbGVyI3dhcm5pbmcKLSAgICogQHNlZSBvcmcueG1sLnNheC5TQVhQYXJzZUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vICVSRVZJRVclIElzIHRoZXJlIGFueXdheSB0byBnZXQgdGhlIEpBWFAgZXJyb3IgbGlzdGVuZXIgaGVyZT8KLSAgICBTeXN0ZW0uZXJyLnByaW50bG4oZS5nZXRNZXNzYWdlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGEgcmVjb3ZlcmFibGUgcGFyc2VyIGVycm9yLgotICAgKgotICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuICBBcHBsaWNhdGlvbiB3cml0ZXJzCi0gICAqIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBhIHN1YmNsYXNzIHRvIHRha2Ugc3BlY2lmaWMgYWN0aW9ucwotICAgKiBmb3IgZWFjaCBlcnJvciwgc3VjaCBhcyBpbnNlcnRpbmcgdGhlIG1lc3NhZ2UgaW4gYSBsb2cgZmlsZSBvcgotICAgKiBwcmludGluZyBpdCB0byB0aGUgY29uc29sZS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBlIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY29kZWQgYXMgYW4gZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBvcmcueG1sLnNheC5FcnJvckhhbmRsZXIjd2FybmluZwotICAgKiBAc2VlIG9yZy54bWwuc2F4LlNBWFBhcnNlRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBlKSB0aHJvd3MgU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhIGZhdGFsIFhNTCBwYXJzaW5nIGVycm9yLgotICAgKgotICAgKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3MgYSBTQVhQYXJzZUV4Y2VwdGlvbi4KLSAgICogQXBwbGljYXRpb24gd3JpdGVycyBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaW4gYSBzdWJjbGFzcyBpZgotICAgKiB0aGV5IG5lZWQgdG8gdGFrZSBzcGVjaWZpYyBhY3Rpb25zIGZvciBlYWNoIGZhdGFsIGVycm9yIChzdWNoIGFzCi0gICAqIGNvbGxlY3RpbmcgYWxsIG9mIHRoZSBlcnJvcnMgaW50byBhIHNpbmdsZSByZXBvcnQpOiBpbiBhbnkgY2FzZSwKLSAgICogdGhlIGFwcGxpY2F0aW9uIG11c3Qgc3RvcCBhbGwgcmVndWxhciBwcm9jZXNzaW5nIHdoZW4gdGhpcwotICAgKiBtZXRob2QgaXMgaW52b2tlZCwgc2luY2UgdGhlIGRvY3VtZW50IGlzIG5vIGxvbmdlciByZWxpYWJsZSwgYW5kCi0gICAqIHRoZSBwYXJzZXIgbWF5IG5vIGxvbmdlciByZXBvcnQgcGFyc2luZyBldmVudHMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZSBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jb2RlZCBhcyBhbiBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkVycm9ySGFuZGxlciNmYXRhbEVycm9yCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZhdGFsRXJyb3IoU0FYUGFyc2VFeGNlcHRpb24gZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgZTsKLSAgfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBEZWNsSGFuZGxlciBpbnRlcmZhY2UuCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBlbGVtZW50IHR5cGUgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPlRoZSBjb250ZW50IG1vZGVsIHdpbGwgY29uc2lzdCBvZiB0aGUgc3RyaW5nICJFTVBUWSIsIHRoZQotICAgKiBzdHJpbmcgIkFOWSIsIG9yIGEgcGFyZW50aGVzaXNlZCBncm91cCwgb3B0aW9uYWxseSBmb2xsb3dlZAotICAgKiBieSBhbiBvY2N1cnJlbmNlIGluZGljYXRvci4gIFRoZSBtb2RlbCB3aWxsIGJlIG5vcm1hbGl6ZWQgc28KLSAgICogdGhhdCBhbGwgd2hpdGVzcGFjZSBpcyByZW1vdmVkLGFuZCB3aWxsIGluY2x1ZGUgdGhlIGVuY2xvc2luZwotICAgKiBwYXJlbnRoZXNlcy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IHR5cGUgbmFtZS4KLSAgICogQHBhcmFtIG1vZGVsIFRoZSBjb250ZW50IG1vZGVsIGFzIGEgbm9ybWFsaXplZCBzdHJpbmcuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZWxlbWVudERlY2woU3RyaW5nIG5hbWUsIFN0cmluZyBtb2RlbCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBhdHRyaWJ1dGUgdHlwZSBkZWNsYXJhdGlvbi4KLSAgICoKLSAgICogPHA+T25seSB0aGUgZWZmZWN0aXZlIChmaXJzdCkgZGVjbGFyYXRpb24gZm9yIGFuIGF0dHJpYnV0ZSB3aWxsCi0gICAqIGJlIHJlcG9ydGVkLiAgVGhlIHR5cGUgd2lsbCBiZSBvbmUgb2YgdGhlIHN0cmluZ3MgIkNEQVRBIiwKLSAgICogIklEIiwgIklEUkVGIiwgIklEUkVGUyIsICJOTVRPS0VOIiwgIk5NVE9LRU5TIiwgIkVOVElUWSIsCi0gICAqICJFTlRJVElFUyIsIG9yICJOT1RBVElPTiIsIG9yIGEgcGFyZW50aGVzaXplZCB0b2tlbiBncm91cCB3aXRoCi0gICAqIHRoZSBzZXBhcmF0b3IgInwiIGFuZCBhbGwgd2hpdGVzcGFjZSByZW1vdmVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBhTmFtZSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKiBAcGFyYW0gdHlwZSBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGF0dHJpYnV0ZSB0eXBlLgotICAgKiBAcGFyYW0gdmFsdWVEZWZhdWx0IEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlIGRlZmF1bHQKLSAgICogICAgICAgICgiI0lNUExJRUQiLCAiI1JFUVVJUkVEIiwgb3IgIiNGSVhFRCIpIG9yIG51bGwgaWYKLSAgICogICAgICAgIG5vbmUgb2YgdGhlc2UgYXBwbGllcy4KLSAgICogQHBhcmFtIHZhbHVlIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYXR0cmlidXRlJ3MgZGVmYXVsdCB2YWx1ZSwKLSAgICogICAgICAgIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKAotICAgICAgICAgIFN0cmluZyBlTmFtZSwgU3RyaW5nIGFOYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlRGVmYXVsdCwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBpbnRlcm5hbCBlbnRpdHkgZGVjbGFyYXRpb24uCi0gICAqCi0gICAqIDxwPk9ubHkgdGhlIGVmZmVjdGl2ZSAoZmlyc3QpIGRlY2xhcmF0aW9uIGZvciBlYWNoIGVudGl0eQotICAgKiB3aWxsIGJlIHJlcG9ydGVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwbGFjZW1lbnQgdGV4dCBvZiB0aGUgZW50aXR5LgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBUaGUgYXBwbGljYXRpb24gbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbi4KLSAgICogQHNlZSAjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguRFRESGFuZGxlciN1bnBhcnNlZEVudGl0eURlY2wKLSAgICovCi0gIHB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8gb3AKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgYSBwYXJzZWQgZXh0ZXJuYWwgZW50aXR5IGRlY2xhcmF0aW9uLgotICAgKgotICAgKiA8cD5Pbmx5IHRoZSBlZmZlY3RpdmUgKGZpcnN0KSBkZWNsYXJhdGlvbiBmb3IgZWFjaCBlbnRpdHkKLSAgICogd2lsbCBiZSByZXBvcnRlZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkuICBJZiBpdCBpcyBhIHBhcmFtZXRlcgotICAgKiAgICAgICAgZW50aXR5LCB0aGUgbmFtZSB3aWxsIGJlZ2luIHdpdGggJyUnLgotICAgKiBAcGFyYW0gcHVibGljSWQgVGhlIGRlY2xhcmVkIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHksIG9yCi0gICAqICAgICAgICBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIG9mIHRoZSBlbnRpdHkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNpbnRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5EVERIYW5kbGVyI3VucGFyc2VkRW50aXR5RGVjbAotICAgKi8KLSAgcHVibGljIHZvaWQgZXh0ZXJuYWxFbnRpdHlEZWNsKAotICAgICAgICAgIFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgLy8gSW1wbGVtZW50YXRpb24gb2YgdGhlIExleGljYWxIYW5kbGVyIGludGVyZmFjZS4KLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBEVEQgZGVjbGFyYXRpb25zLCBpZiBhbnkuCi0gICAqCi0gICAqIDxwPkFueSBkZWNsYXJhdGlvbnMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gdGhlIGludGVybmFsIHN1YnNldAotICAgKiB1bmxlc3Mgb3RoZXJ3aXNlIGluZGljYXRlZCBieSBhIHtAbGluayAjc3RhcnRFbnRpdHkgc3RhcnRFbnRpdHl9Ci0gICAqIGV2ZW50LjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHRoZSBzdGFydC9lbmREVEQgZXZlbnRzIHdpbGwgYXBwZWFyIHdpdGhpbgotICAgKiB0aGUgc3RhcnQvZW5kRG9jdW1lbnQgZXZlbnRzIGZyb20gQ29udGVudEhhbmRsZXIgYW5kCi0gICAqIGJlZm9yZSB0aGUgZmlyc3Qgc3RhcnRFbGVtZW50IGV2ZW50LjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGRvY3VtZW50IHR5cGUgbmFtZS4KLSAgICogQHBhcmFtIHB1YmxpY0lkIFRoZSBkZWNsYXJlZCBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlCi0gICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gc3lzdGVtSWQgVGhlIGRlY2xhcmVkIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUKLSAgICogICAgICAgIGV4dGVybmFsIERURCBzdWJzZXQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZGVjbGFyZWQuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4KLSAgICogICAgICAgICAgICBleGNlcHRpb24uCi0gICAqIEBzZWUgI2VuZERURAotICAgKiBAc2VlICNzdGFydEVudGl0eQotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKQotICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgbV9pbnNpZGVEVEQgPSB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgZW5kIG9mIERURCBkZWNsYXJhdGlvbnMuCi0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNzdGFydERURAotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBtX2luc2lkZURURCA9IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgYmVnaW5uaW5nIG9mIGFuIGVudGl0eSBpbiBjb250ZW50LgotICAgKgotICAgKiA8cD48c3Ryb25nPk5PVEU6PC9lbnRpdHk+IGVudGl0eSByZWZlcmVuY2VzIGluIGF0dHJpYnV0ZQotICAgKiB2YWx1ZXMgLS0gYW5kIHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBkb2N1bWVudCBlbnRpdHkgLS0KLSAgICogYXJlIG5ldmVyIHJlcG9ydGVkLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGV4dGVybmFsIERURCBzdWJzZXQgYXJlIHJlcG9ydGVkCi0gICAqIHVzaW5nIHRoZSBwc2V1ZG8tbmFtZSAiW2R0ZF0iLiAgQWxsIG90aGVyIGV2ZW50cyBtdXN0IGJlCi0gICAqIHByb3Blcmx5IG5lc3RlZCB3aXRoaW4gc3RhcnQvZW5kIGVudGl0eSBldmVudHMuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc2tpcHBlZCBlbnRpdGllcyB3aWxsIGJlIHJlcG9ydGVkIHRocm91Z2ggdGhlCi0gICAqIHtAbGluayBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciNza2lwcGVkRW50aXR5IHNraXBwZWRFbnRpdHl9Ci0gICAqIGV2ZW50LCB3aGljaCBpcyBwYXJ0IG9mIHRoZSBDb250ZW50SGFuZGxlciBpbnRlcmZhY2UuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZW50aXR5LiAgSWYgaXQgaXMgYSBwYXJhbWV0ZXIKLSAgICogICAgICAgIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI2VuZEVudGl0eQotICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNpbnRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBubyBvcAotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgZW5kIG9mIGFuIGVudGl0eS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eSB0aGF0IGlzIGVuZGluZy4KLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8gb3AKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIHN0YXJ0IG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICoKLSAgICogPHA+VGhlIGNvbnRlbnRzIG9mIHRoZSBDREFUQSBzZWN0aW9uIHdpbGwgYmUgcmVwb3J0ZWQgdGhyb3VnaAotICAgKiB0aGUgcmVndWxhciB7QGxpbmsgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIjY2hhcmFjdGVycwotICAgKiBjaGFyYWN0ZXJzfSBldmVudC48L3A+Ci0gICAqCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKiBAc2VlICNlbmRDREFUQQotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRDREFUQSgpIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIG1fdGV4dFR5cGUgPSBEVE0uQ0RBVEFfU0VDVElPTl9OT0RFOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgZW5kIG9mIGEgQ0RBVEEgc2VjdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBTQVhFeGNlcHRpb24gVGhlIGFwcGxpY2F0aW9uIG1heSByYWlzZSBhbiBleGNlcHRpb24uCi0gICAqIEBzZWUgI3N0YXJ0Q0RBVEEKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbV90ZXh0VHlwZSA9IERUTS5URVhUX05PREU7Ci0gIH0KLQotICAvKioKLSAgICogUmVwb3J0IGFuIFhNTCBjb21tZW50IGFueXdoZXJlIGluIHRoZSBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+VGhpcyBjYWxsYmFjayB3aWxsIGJlIHVzZWQgZm9yIGNvbW1lbnRzIGluc2lkZSBvciBvdXRzaWRlIHRoZQotICAgKiBkb2N1bWVudCBlbGVtZW50LCBpbmNsdWRpbmcgY29tbWVudHMgaW4gdGhlIGV4dGVybmFsIERURAotICAgKiBzdWJzZXQgKGlmIHJlYWQpLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIFRoZSBhcHBsaWNhdGlvbiBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgY29tbWVudChjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobV9pbnNpZGVEVEQpICAgICAgLy8gaWdub3JlIGNvbW1lbnRzIGlmIHdlJ3JlIGluc2lkZSB0aGUgRFRECi0gICAgICByZXR1cm47Ci0KLSAgICBjaGFyYWN0ZXJzRmx1c2goKTsKLQotICAgIGludCBleE5hbWUgPSBtX2V4cGFuZGVkTmFtZVRhYmxlLmdldEV4cGFuZGVkVHlwZUlEKERUTS5DT01NRU5UX05PREUpOwotCi0gICAgLy8gRm9yIG5vdywgdHJlYXQgY29tbWVudHMgYXMgc3RyaW5ncy4uLiAgSSBndWVzcyB3ZSBzaG91bGQgZG8gYSAKLSAgICAvLyBzZXBlcmF0ZSBGU0IgYnVmZmVyIGluc3RlYWQuCi0gICAgaW50IGRhdGFJbmRleCA9IG1fdmFsdWVzT3JQcmVmaXhlcy5zdHJpbmdUb0luZGV4KG5ldyBTdHJpbmcoY2gsIHN0YXJ0LAotICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCkpOwotCi0gICAgbV9wcmV2aW91cyA9IGFkZE5vZGUoRFRNLkNPTU1FTlRfTk9ERSwgZXhOYW1lLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICBtX3BhcmVudHMucGVlaygpLCBtX3ByZXZpb3VzLCBkYXRhSW5kZXgsIGZhbHNlKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYSBydW4gdGltZSBwcm9wZXJ0eSBmb3IgdGhpcyBEVE0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEBwYXJhbSBwcm9wZXJ0eSBhIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUKLSAgICogQHBhcmFtIHZhbHVlIGFuIDxjb2RlPk9iamVjdDwvY29kZT4gdmFsdWUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByb3BlcnR5KFN0cmluZyBwcm9wZXJ0eSwgT2JqZWN0IHZhbHVlKQotICB7Ci0gICAgaWYgKHByb3BlcnR5LmVxdWFscyhYYWxhblByb3BlcnRpZXMuU09VUkNFX0xPQ0FUSU9OKSkgewotICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSkKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUFJPUEVSVFlfVkFMVUVfQk9PTEVBTiwgbmV3IE9iamVjdFtde1hhbGFuUHJvcGVydGllcy5TT1VSQ0VfTE9DQVRJT059KSk7IC8vIlZhbHVlIGZvciBwcm9wZXJ0eSAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKyBYYWxhblByb3BlcnRpZXMuU09VUkNFX0xPQ0FUSU9OCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKyAiIHNob3VsZCBiZSBhIEJvb2xlYW4gaW5zdGFuY2UiKTsKLSAgICAgIG1fdXNlU291cmNlTG9jYXRpb25Qcm9wZXJ0eSA9ICgoQm9vbGVhbil2YWx1ZSkuYm9vbGVhblZhbHVlKCk7Ci0gICAgICBtX3NvdXJjZVN5c3RlbUlkID0gbmV3IFN0cmluZ1ZlY3RvcigpOwotICAgICAgbV9zb3VyY2VMaW5lID0gbmV3IEludFZlY3RvcigpOwotICAgICAgbV9zb3VyY2VDb2x1bW4gPSBuZXcgSW50VmVjdG9yKCk7Ci0gICAgfQotICB9Ci0KLSAgcHVibGljIFNvdXJjZUxvY2F0b3IgZ2V0U291cmNlTG9jYXRvckZvcihpbnQgbm9kZSkKLSAgewotICAgIGlmIChtX3VzZVNvdXJjZUxvY2F0aW9uUHJvcGVydHkpCi0gICAgewotICAgICAgbm9kZSA9IG5vZGUgJiBFeHBhbmRlZE5hbWVUYWJsZS5NQVNLX05PREVIQU5ETEU7Ci0gICAgICAKLSAgICAgIHJldHVybiBuZXcgTm9kZUxvY2F0b3IobnVsbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9zb3VyY2VTeXN0ZW1JZC5lbGVtZW50QXQobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fc291cmNlTGluZS5lbGVtZW50QXQobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fc291cmNlQ29sdW1uLmVsZW1lbnRBdChub2RlKSk7Ci0gICAgfQotICAgIHJldHVybiBudWxsOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvQXR0TGlzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL0F0dExpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTRkMTYyYi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvQXR0TGlzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkRPTUhlbHBlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkRPTTJIZWxwZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBXcmFwcyBhIERPTSBhdHRyaWJ1dGUgbGlzdCBpbiBhIFNBWCBBdHRyaWJ1dGVzLgotICovCi1wdWJsaWMgY2xhc3MgQXR0TGlzdCBpbXBsZW1lbnRzIEF0dHJpYnV0ZXMKLXsKLQotICAvKiogTGlzdCBvZiBhdHRyaWJ1dGUgbm9kZXMgICAgICAgICAgKi8KLSAgTmFtZWROb2RlTWFwIG1fYXR0cnM7Ci0KLSAgLyoqIEluZGV4IG9mIGxhc3QgYXR0cmlidXRlIG5vZGUgICAgICAgICAgKi8KLSAgaW50IG1fbGFzdEluZGV4OwotCi0gIC8vIEFSR0hIISEgIEpBWFAgVXNlcyBYZXJjZXMgd2l0aG91dCBzZXR0aW5nIHRoZSBuYW1lc3BhY2UgcHJvY2Vzc2luZyB0byBPTiEKLSAgLy8gRE9NMkhlbHBlciBtX2RoID0gbmV3IERPTTJIZWxwZXIoKTsKLQotICAvKiogTG9jYWwgcmVmZXJlbmNlIHRvIERPTUhlbHBlciAgICAgICAgICAqLwotICBET01IZWxwZXIgbV9kaDsKLQotLy8gIC8qKgotLy8gICAqIENvbnN0cnVjdG9yIEF0dExpc3QKLS8vICAgKgotLy8gICAqCi0vLyAgICogQHBhcmFtIGF0dHJzIExpc3Qgb2YgYXR0cmlidXRlcyB0aGlzIHdpbGwgY29udGFpbgotLy8gICAqLwotLy8gIHB1YmxpYyBBdHRMaXN0KE5hbWVkTm9kZU1hcCBhdHRycykKLS8vICB7Ci0vLwotLy8gICAgbV9hdHRycyA9IGF0dHJzOwotLy8gICAgbV9sYXN0SW5kZXggPSBtX2F0dHJzLmdldExlbmd0aCgpIC0gMTsKLS8vICAgIG1fZGggPSBuZXcgRE9NMkhlbHBlcigpOwotLy8gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgQXR0TGlzdAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXR0cnMgTGlzdCBvZiBhdHRyaWJ1dGVzIHRoaXMgd2lsbCBjb250YWluCi0gICAqIEBwYXJhbSBkaCBET01IZWxwZXIgCi0gICAqLwotICBwdWJsaWMgQXR0TGlzdChOYW1lZE5vZGVNYXAgYXR0cnMsIERPTUhlbHBlciBkaCkKLSAgewotCi0gICAgbV9hdHRycyA9IGF0dHJzOwotICAgIG1fbGFzdEluZGV4ID0gbV9hdHRycy5nZXRMZW5ndGgoKSAtIDE7Ci0gICAgbV9kaCA9IGRoOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIGF0dHJpYnV0ZSBub2RlcyBpbiB0aGUgbGlzdCAKLSAgICoKLSAgICoKLSAgICogQHJldHVybiBudW1iZXIgb2YgYXR0cmlidXRlIG5vZGVzCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gbV9hdHRycy5nZXRMZW5ndGgoKTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIE5hbWVzcGFjZSBVUkkgYnkgaW5kZXguCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICogQHJldHVybiBUaGUgTmFtZXNwYWNlIFVSSSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBub25lCi0gICAqICAgICAgICAgaXMgYXZhaWxhYmxlLCBvciBudWxsIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YKLSAgICogICAgICAgICByYW5nZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VVJJKGludCBpbmRleCkKLSAgewotICAgIFN0cmluZyBucyA9IG1fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKCgoQXR0cikgbV9hdHRycy5pdGVtKGluZGV4KSkpOwotICAgIGlmKG51bGwgPT0gbnMpCi0gICAgICBucyA9ICIiOwotICAgIHJldHVybiBuczsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIGxvY2FsIG5hbWUgYnkgaW5kZXguCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICogQHJldHVybiBUaGUgbG9jYWwgbmFtZSwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBOYW1lc3BhY2UKLSAgICogICAgICAgICBwcm9jZXNzaW5nIGlzIG5vdCBiZWluZyBwZXJmb3JtZWQsIG9yIG51bGwKLSAgICogICAgICAgICBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoaW50IGluZGV4KQotICB7Ci0gICAgcmV0dXJuIG1fZGguZ2V0TG9jYWxOYW1lT2ZOb2RlKCgoQXR0cikgbV9hdHRycy5pdGVtKGluZGV4KSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgcXVhbGlmaWVkIG5hbWUgYnkgaW5kZXguCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXR0cmlidXRlJ3MgcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UU5hbWUoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gKChBdHRyKSBtX2F0dHJzLml0ZW0oaSkpLmdldE5hbWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGF0dHJpYnV0ZSdzIG5vZGUgdHlwZSBieSBpbmRleAotICAgKgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggVGhlIGF0dHJpYnV0ZSBpbmRleCAoemVyby1iYXNlZCkKLSAgICoKLSAgICogQHJldHVybiB0aGUgYXR0cmlidXRlJ3Mgbm9kZSB0eXBlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gIkNEQVRBIjsgIC8vIGZvciB0aGUgbW9tZW50Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBhdHRyaWJ1dGUncyBub2RlIHZhbHVlIGJ5IGluZGV4Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgYXR0cmlidXRlIGluZGV4ICh6ZXJvLWJhc2VkKQotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhdHRyaWJ1dGUncyBub2RlIHZhbHVlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKGludCBpKQotICB7Ci0gICAgcmV0dXJuICgoQXR0cikgbV9hdHRycy5pdGVtKGkpKS5nZXRWYWx1ZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXR0cmlidXRlJ3Mgbm9kZSB0eXBlIGJ5IG5hbWUKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQXR0cmlidXRlIG5hbWUKLSAgICoKLSAgICogQHJldHVybiB0aGUgYXR0cmlidXRlJ3Mgbm9kZSB0eXBlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoU3RyaW5nIG5hbWUpCi0gIHsKLSAgICByZXR1cm4gIkNEQVRBIjsgIC8vIGZvciB0aGUgbW9tZW50Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCBhbiBhdHRyaWJ1dGUncyB0eXBlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgU3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdHlwZSBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiB0aGUKLSAgICogICAgICAgICBhdHRyaWJ1dGUgaXMgbm90IGluIHRoZSBsaXN0IG9yIGlmIE5hbWVzcGFjZQotICAgKiAgICAgICAgIHByb2Nlc3NpbmcgaXMgbm90IGJlaW5nIHBlcmZvcm1lZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lKQotICB7Ci0gICAgcmV0dXJuICJDREFUQSI7ICAvLyBmb3IgdGhlIG1vbWVudAotICB9Ci0KLSAgLyoqCi0gICAqIExvb2sgdXAgYW4gYXR0cmlidXRlJ3MgdmFsdWUgYnkgbmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIGF0dHJpYnV0ZSBub2RlJ3MgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgbm9kZSdzIHZhbHVlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBuYW1lKQotICB7Ci0gICAgQXR0ciBhdHRyID0gKChBdHRyKSBtX2F0dHJzLmdldE5hbWVkSXRlbShuYW1lKSk7Ci0gICAgcmV0dXJuIChudWxsICE9IGF0dHIpIAotICAgICAgICAgID8gYXR0ci5nZXRWYWx1ZSgpIDogbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIGFuIGF0dHJpYnV0ZSdzIHZhbHVlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgU3RyaW5nIGlmIHRoZQotICAgKiAgICAgICAgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLgotICAgKiBAcmV0dXJuIFRoZSBhdHRyaWJ1dGUgdmFsdWUgYXMgYSBzdHJpbmcsIG9yIG51bGwgaWYgdGhlCi0gICAqICAgICAgICAgYXR0cmlidXRlIGlzIG5vdCBpbiB0aGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIHVyaSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotICAgIHJldHVybiAoKEF0dHIpIG1fYXR0cnMuZ2V0TmFtZWRJdGVtKGxvY2FsTmFtZSkpLmdldFZhbHVlKCk7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayB1cCB0aGUgaW5kZXggb2YgYW4gYXR0cmlidXRlIGJ5IE5hbWVzcGFjZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqICAgICAgICB0aGUgbmFtZSBoYXMgbm8gTmFtZXNwYWNlIFVSSS4KLSAgICogQHBhcmFtIGxvY2FsUGFydCBUaGUgYXR0cmlidXRlJ3MgbG9jYWwgbmFtZS4KLSAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIGF0dHJpYnV0ZSwgb3IgLTEgaWYgaXQgZG9lcyBub3QKLSAgICogICAgICAgICBhcHBlYXIgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEluZGV4KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbFBhcnQpCi0gIHsKLSAgICByZXR1cm4gMDsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIHVwIHRoZSBpbmRleCBvZiBhbiBhdHRyaWJ1dGUgYnkgcmF3IFhNTCAxLjAgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHJhd05hbWUgVGhlIHJhdyAocHJlZml4ZWQpIG5hbWUuCi0gICAqIEByZXR1cm4gVGhlIGluZGV4IG9mIHRoZSBhdHRyaWJ1dGUsIG9yIC0xIGlmIGl0IGRvZXMgbm90Ci0gICAqICAgICAgICAgYXBwZWFyIGluIHRoZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRJbmRleChTdHJpbmcgcmF3TmFtZSkKLSAgewotICAgIHJldHVybiAwOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvQm9vbFN0YWNrLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvQm9vbFN0YWNrLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNhNzU0ZTcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL0Jvb2xTdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjMwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkVtcHR5U3RhY2tFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBTaW1wbGUgc3RhY2sgZm9yIGJvb2xlYW4gdmFsdWVzLgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgQm9vbFN0YWNrIGltcGxlbWVudHMgQ2xvbmVhYmxlCi17Ci0KLSAgLyoqIEFycmF5IG9mIGJvb2xlYW4gdmFsdWVzICAgICAgICAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX3ZhbHVlc1tdOwotCi0gIC8qKiBBcnJheSBzaXplIGFsbG9jYXRlZCAgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9hbGxvY2F0ZWRTaXplOwotCi0gIC8qKiBJbmRleCBpbnRvIHRoZSBhcnJheSBvZiBib29sZWFucyAgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2luZGV4OwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIEJvb2xTdGFjaygpCi0gIHsKLSAgICB0aGlzKDMyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gc2l6ZSBhcnJheSBzaXplIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgQm9vbFN0YWNrKGludCBzaXplKQotICB7Ci0KLSAgICBtX2FsbG9jYXRlZFNpemUgPSBzaXplOwotICAgIG1fdmFsdWVzID0gbmV3IGJvb2xlYW5bc2l6ZV07Ci0gICAgbV9pbmRleCA9IC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIEN1cnJlbnQgbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1faW5kZXggKyAxOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2hlcyBhbiBpdGVtIG9udG8gdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gdmFsIHRoZSBib29sZWFuIHRvIGJlIHB1c2hlZCBvbnRvIHRoaXMgc3RhY2suCi0gICAqIEByZXR1cm4gIHRoZSA8Y29kZT5pdGVtPC9jb2RlPiBhcmd1bWVudC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIHB1c2goYm9vbGVhbiB2YWwpCi0gIHsKLQotICAgIGlmIChtX2luZGV4ID09IG1fYWxsb2NhdGVkU2l6ZSAtIDEpCi0gICAgICBncm93KCk7Ci0KLSAgICByZXR1cm4gKG1fdmFsdWVzWysrbV9pbmRleF0gPSB2YWwpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgYW5kIHJldHVybnMgdGhhdAotICAgKiBvYmplY3QgYXMgdGhlIHZhbHVlIG9mIHRoaXMgZnVuY3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gICAgIFRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKiBAdGhyb3dzICBFbXB0eVN0YWNrRXhjZXB0aW9uICBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcG9wKCkKLSAgewotICAgIHJldHVybiBtX3ZhbHVlc1ttX2luZGV4LS1dOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgYW5kIHJldHVybnMgdGhlCi0gICAqIG5leHQgb2JqZWN0IGF0IHRoZSB0b3AgYXMgdGhlIHZhbHVlIG9mIHRoaXMgZnVuY3Rpb24uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gTmV4dCBvYmplY3QgdG8gdGhlIHRvcCBvciBmYWxzZSBpZiBub25lIHRoZXJlCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwb3BBbmRUb3AoKQotICB7Ci0KLSAgICBtX2luZGV4LS07Ci0KLSAgICByZXR1cm4gKG1faW5kZXggPj0gMCkgPyBtX3ZhbHVlc1ttX2luZGV4XSA6IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgaXRlbSBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYiBPYmplY3QgdG8gc2V0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjawotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VG9wKGJvb2xlYW4gYikKLSAgewotICAgIG1fdmFsdWVzW21faW5kZXhdID0gYjsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAqIGZyb20gdGhlIHN0YWNrLgotICAgKgotICAgKiBAcmV0dXJuICAgICB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjay4KLSAgICogQHRocm93cyAgRW1wdHlTdGFja0V4Y2VwdGlvbiAgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIHBlZWsoKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsdWVzW21faW5kZXhdOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2tzIGF0IHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIHdpdGhvdXQgcmVtb3ZpbmcgaXQKLSAgICogZnJvbSB0aGUgc3RhY2suICBJZiB0aGUgc3RhY2sgaXMgZW1wdHksIGl0IHJldHVybnMgZmFsc2UuCi0gICAqCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcGVla09yRmFsc2UoKQotICB7Ci0gICAgcmV0dXJuIChtX2luZGV4ID4gLTEpID8gbV92YWx1ZXNbbV9pbmRleF0gOiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rcyBhdCB0aGUgb2JqZWN0IGF0IHRoZSB0b3Agb2YgdGhpcyBzdGFjayB3aXRob3V0IHJlbW92aW5nIGl0Ci0gICAqIGZyb20gdGhlIHN0YWNrLiAgSWYgdGhlIHN0YWNrIGlzIGVtcHR5LCBpdCByZXR1cm5zIHRydWUuCi0gICAqCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcGVla09yVHJ1ZSgpCi0gIHsKLSAgICByZXR1cm4gKG1faW5kZXggPiAtMSkgPyBtX3ZhbHVlc1ttX2luZGV4XSA6IHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdGFjayBpcyBlbXB0eS4KLSAgICoKLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBzdGFjayBpcyBlbXB0eTsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKQotICB7Ci0gICAgcmV0dXJuIChtX2luZGV4ID09IC0xKTsKLSAgfQotCi0gIC8qKgotICAgKiBHcm93cyB0aGUgc2l6ZSBvZiB0aGUgc3RhY2sKLSAgICoKLSAgICovCi0gIHByaXZhdGUgdm9pZCBncm93KCkKLSAgewotCi0gICAgbV9hbGxvY2F0ZWRTaXplICo9IDI7Ci0KLSAgICBib29sZWFuIG5ld1ZlY3RvcltdID0gbmV3IGJvb2xlYW5bbV9hbGxvY2F0ZWRTaXplXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkobV92YWx1ZXMsIDAsIG5ld1ZlY3RvciwgMCwgbV9pbmRleCArIDEpOwotCi0gICAgbV92YWx1ZXMgPSBuZXdWZWN0b3I7Ci0gIH0KLSAgCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSAKLSAgICB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9DaGFyS2V5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvQ2hhcktleS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODM5ZjhhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9DaGFyS2V5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2NiArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogU2ltcGxlIGNsYXNzIGZvciBmYXN0IGxvb2t1cCBvZiBjaGFyIHZhbHVlcywgd2hlbiB1c2VkIHdpdGgKLSAqIGhhc2h0YWJsZXMuICBZb3UgY2FuIHNldCB0aGUgY2hhciwgdGhlbiB1c2UgaXQgYXMgYSBrZXkuCi0gKi8KLXB1YmxpYyBjbGFzcyBDaGFyS2V5IGV4dGVuZHMgT2JqZWN0Ci17Ci0KLSAgLyoqIFN0cmluZyB2YWx1ZSAgICAgICAgICAqLwotICBwcml2YXRlIGNoYXIgbV9jaGFyOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBDaGFyS2V5Ci0gICAqCi0gICAqIEBwYXJhbSBrZXkgY2hhciB2YWx1ZSBvZiB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBDaGFyS2V5KGNoYXIga2V5KQotICB7Ci0gICAgbV9jaGFyID0ga2V5OwotICB9Ci0gIAotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciBmb3IgYSBDaGFyS2V5LgotICAgKgotICAgKiBAcGFyYW0ga2V5IGNoYXIgdmFsdWUgb2YgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ2hhcktleSgpCi0gIHsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgaGFzaCB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyLiAgCi0gICAqCi0gICAqIEByZXR1cm4gaGFzaCB2YWx1ZSBvZiB0aGUgY2hhcmFjdGVyLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q2hhcihjaGFyIGMpCi0gIHsKLSAgICBtX2NoYXIgPSBjOwotICB9Ci0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGhhc2ggdmFsdWUgb2YgdGhlIGNoYXJhY3Rlci4gIAotICAgKgotICAgKiBAcmV0dXJuIGhhc2ggdmFsdWUgb2YgdGhlIGNoYXJhY3Rlci4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgaGFzaENvZGUoKQotICB7Ci0gICAgcmV0dXJuIChpbnQpbV9jaGFyOwotICB9Ci0KLSAgLyoqCi0gICAqIE92ZXJyaWRlIG9mIGVxdWFscygpIGZvciB0aGlzIG9iamVjdCAKLSAgICoKLSAgICogQHBhcmFtIG9iaiB0byBjb21wYXJlIHRvCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIG9iamVjdCBlcXVhbHMgdGhpcyBzdHJpbmcgdmFsdWUgCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikKLSAgewotICAgIHJldHVybiAoKENoYXJLZXkpb2JqKS5tX2NoYXIgPT0gbV9jaGFyOwotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL0RPTUJ1aWxkZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9ET01CdWlsZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUwZjc2NDUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL0RPTUJ1aWxkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc1NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTm9kZVZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5BdHRyaWJ1dGVzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsgIC8vIHdlIHByZXR0eSBtdWNoIHVzZSBldmVyeXRoaW5nIGluIHRoZSBET00gaGVyZS4KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyB0YWtlcyBTQVggZXZlbnRzIChpbiBhZGRpdGlvbiB0byBzb21lIGV4dHJhIGV2ZW50cwotICogdGhhdCBTQVggZG9lc24ndCBoYW5kbGUgeWV0KSBhbmQgYWRkcyB0aGUgcmVzdWx0IHRvIGEgZG9jdW1lbnQKLSAqIG9yIGRvY3VtZW50IGZyYWdtZW50LgotICovCi1wdWJsaWMgY2xhc3MgRE9NQnVpbGRlcgotICAgICAgICBpbXBsZW1lbnRzIENvbnRlbnRIYW5kbGVyLCBMZXhpY2FsSGFuZGxlcgotewotCi0gIC8qKiBSb290IGRvY3VtZW50ICAgICAgICAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBtX2RvYzsKLQotICAvKiogQ3VycmVudCBub2RlICAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgTm9kZSBtX2N1cnJlbnROb2RlID0gbnVsbDsKLQotICAvKiogRmlyc3Qgbm9kZSBvZiBkb2N1bWVudCBmcmFnbWVudCBvciBudWxsIGlmIG5vdCBhIERvY3VtZW50RnJhZ21lbnQgICAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IG1fZG9jRnJhZyA9IG51bGw7Ci0KLSAgLyoqIFZlY3RvciBvZiBlbGVtZW50IG5vZGVzICAgICAgICAgICovCi0gIHByb3RlY3RlZCBTdGFjayBtX2VsZW1TdGFjayA9IG5ldyBTdGFjaygpOwotCi0gIC8qKgotICAgKiBET01CdWlsZGVyIGluc3RhbmNlIGNvbnN0cnVjdG9yLi4uIGl0IHdpbGwgYWRkIHRoZSBET00gbm9kZXMKLSAgICogdG8gdGhlIGRvY3VtZW50IGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gZG9jIFJvb3QgZG9jdW1lbnQKLSAgICogQHBhcmFtIG5vZGUgQ3VycmVudCBub2RlCi0gICAqLwotICBwdWJsaWMgRE9NQnVpbGRlcihEb2N1bWVudCBkb2MsIE5vZGUgbm9kZSkKLSAgewotICAgIG1fZG9jID0gZG9jOwotICAgIG1fY3VycmVudE5vZGUgPSBub2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIERPTUJ1aWxkZXIgaW5zdGFuY2UgY29uc3RydWN0b3IuLi4gaXQgd2lsbCBhZGQgdGhlIERPTSBub2RlcwotICAgKiB0byB0aGUgZG9jdW1lbnQgZnJhZ21lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBkb2MgUm9vdCBkb2N1bWVudAotICAgKiBAcGFyYW0gZG9jRnJhZyBEb2N1bWVudCBmcmFnbWVudAotICAgKi8KLSAgcHVibGljIERPTUJ1aWxkZXIoRG9jdW1lbnQgZG9jLCBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWcpCi0gIHsKLSAgICBtX2RvYyA9IGRvYzsKLSAgICBtX2RvY0ZyYWcgPSBkb2NGcmFnOwotICB9Ci0KLSAgLyoqCi0gICAqIERPTUJ1aWxkZXIgaW5zdGFuY2UgY29uc3RydWN0b3IuLi4gaXQgd2lsbCBhZGQgdGhlIERPTSBub2RlcwotICAgKiB0byB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBkb2MgUm9vdCBkb2N1bWVudAotICAgKi8KLSAgcHVibGljIERPTUJ1aWxkZXIoRG9jdW1lbnQgZG9jKQotICB7Ci0gICAgbV9kb2MgPSBkb2M7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSByb290IG5vZGUgb2YgdGhlIERPTSBiZWluZyBjcmVhdGVkLiAgVGhpcwotICAgKiBpcyBlaXRoZXIgYSBEb2N1bWVudCBvciBhIERvY3VtZW50RnJhZ21lbnQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJvb3QgZG9jdW1lbnQgb3IgZG9jdW1lbnQgZnJhZ21lbnQgaWYgbm90IG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldFJvb3ROb2RlKCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX2RvY0ZyYWcpID8gKE5vZGUpIG1fZG9jRnJhZyA6IChOb2RlKSBtX2RvYzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5vZGUgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY3VycmVudCBub2RlIGJlaW5nIHByb2Nlc3NlZAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Q3VycmVudE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fY3VycmVudE5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIG51bGwgc2luY2UgdGhlcmUgaXMgbm8gV3JpdGVyIGZvciB0aGlzIGNsYXNzLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBqYXZhLmlvLldyaXRlciBnZXRXcml0ZXIoKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgbm9kZSB0byB0aGUgY3VycmVudCBjb250YWluZXIuCi0gICAqCi0gICAqIEBwYXJhbSBuZXdOb2RlIE5ldyBub2RlIHRvIGFwcGVuZAotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgYXBwZW5kKE5vZGUgbmV3Tm9kZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlIGN1cnJlbnROb2RlID0gbV9jdXJyZW50Tm9kZTsKLQotICAgIGlmIChudWxsICE9IGN1cnJlbnROb2RlKQotICAgIHsKLSAgICAgIGN1cnJlbnROb2RlLmFwcGVuZENoaWxkKG5ld05vZGUpOwotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4obmV3Tm9kZS5nZXROb2RlTmFtZSgpKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAobnVsbCAhPSBtX2RvY0ZyYWcpCi0gICAgewotICAgICAgbV9kb2NGcmFnLmFwcGVuZENoaWxkKG5ld05vZGUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgYm9vbGVhbiBvayA9IHRydWU7Ci0gICAgICBzaG9ydCB0eXBlID0gbmV3Tm9kZS5nZXROb2RlVHlwZSgpOwotCi0gICAgICBpZiAodHlwZSA9PSBOb2RlLlRFWFRfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIGRhdGEgPSBuZXdOb2RlLmdldE5vZGVWYWx1ZSgpOwotCi0gICAgICAgIGlmICgobnVsbCAhPSBkYXRhKSAmJiAoZGF0YS50cmltKCkubGVuZ3RoKCkgPiAwKSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oCi0gICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9PVVRQVVRfVEVYVF9CRUZPUkVfRE9DLCBudWxsKSk7ICAvLyJXYXJuaW5nOiBjYW4ndCBvdXRwdXQgdGV4dCBiZWZvcmUgZG9jdW1lbnQgZWxlbWVudCEgIElnbm9yaW5nLi4uIik7Ci0gICAgICAgIH0KLQotICAgICAgICBvayA9IGZhbHNlOwotICAgICAgfQotICAgICAgZWxzZSBpZiAodHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG1fZG9jLmdldERvY3VtZW50RWxlbWVudCgpICE9IG51bGwpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKAotICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QsIG51bGwpKTsgIC8vIkNhbid0IGhhdmUgbW9yZSB0aGFuIG9uZSByb290IG9uIGEgRE9NISIpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChvaykKLSAgICAgICAgbV9kb2MuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJlY2VpdmUgYW4gb2JqZWN0IGZvciBsb2NhdGluZyB0aGUgb3JpZ2luIG9mIFNBWCBkb2N1bWVudCBldmVudHMuCi0gICAqCi0gICAqIDxwPlNBWCBwYXJzZXJzIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkICh0aG91Z2ggbm90IGFic29sdXRlbHkKLSAgICogcmVxdWlyZWQpIHRvIHN1cHBseSBhIGxvY2F0b3I6IGlmIGl0IGRvZXMgc28sIGl0IG11c3Qgc3VwcGx5Ci0gICAqIHRoZSBsb2NhdG9yIHRvIHRoZSBhcHBsaWNhdGlvbiBieSBpbnZva2luZyB0aGlzIG1ldGhvZCBiZWZvcmUKLSAgICogaW52b2tpbmcgYW55IG9mIHRoZSBvdGhlciBtZXRob2RzIGluIHRoZSBDb250ZW50SGFuZGxlcgotICAgKiBpbnRlcmZhY2UuPC9wPgotICAgKgotICAgKiA8cD5UaGUgbG9jYXRvciBhbGxvd3MgdGhlIGFwcGxpY2F0aW9uIHRvIGRldGVybWluZSB0aGUgZW5kCi0gICAqIHBvc2l0aW9uIG9mIGFueSBkb2N1bWVudC1yZWxhdGVkIGV2ZW50LCBldmVuIGlmIHRoZSBwYXJzZXIgaXMKLSAgICogbm90IHJlcG9ydGluZyBhbiBlcnJvci4gIFR5cGljYWxseSwgdGhlIGFwcGxpY2F0aW9uIHdpbGwKLSAgICogdXNlIHRoaXMgaW5mb3JtYXRpb24gZm9yIHJlcG9ydGluZyBpdHMgb3duIGVycm9ycyAoc3VjaCBhcwotICAgKiBjaGFyYWN0ZXIgY29udGVudCB0aGF0IGRvZXMgbm90IG1hdGNoIGFuIGFwcGxpY2F0aW9uJ3MKLSAgICogYnVzaW5lc3MgcnVsZXMpLiAgVGhlIGluZm9ybWF0aW9uIHJldHVybmVkIGJ5IHRoZSBsb2NhdG9yCi0gICAqIGlzIHByb2JhYmx5IG5vdCBzdWZmaWNpZW50IGZvciB1c2Ugd2l0aCBhIHNlYXJjaCBlbmdpbmUuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgdGhlIGxvY2F0b3Igd2lsbCByZXR1cm4gY29ycmVjdCBpbmZvcm1hdGlvbiBvbmx5Ci0gICAqIGR1cmluZyB0aGUgaW52b2NhdGlvbiBvZiB0aGUgZXZlbnRzIGluIHRoaXMgaW50ZXJmYWNlLiAgVGhlCi0gICAqIGFwcGxpY2F0aW9uIHNob3VsZCBub3QgYXR0ZW1wdCB0byB1c2UgaXQgYXQgYW55IG90aGVyIHRpbWUuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRvciBBbiBvYmplY3QgdGhhdCBjYW4gcmV0dXJuIHRoZSBsb2NhdGlvbiBvZgotICAgKiAgICAgICAgICAgICAgICBhbnkgU0FYIGRvY3VtZW50IGV2ZW50LgotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvY3VtZW50TG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLQotICAgIC8vIE5vIGFjdGlvbiBmb3IgdGhlIG1vbWVudC4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGEgZG9jdW1lbnQuCi0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9ubHkgb25jZSwgYmVmb3JlIGFueQotICAgKiBvdGhlciBtZXRob2RzIGluIHRoaXMgaW50ZXJmYWNlIG9yIGluIERUREhhbmRsZXIgKGV4Y2VwdCBmb3IKLSAgICogc2V0RG9jdW1lbnRMb2NhdG9yKS48L3A+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydERvY3VtZW50KCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBObyBhY3Rpb24gZm9yIHRoZSBtb21lbnQuCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhIGRvY3VtZW50LgotICAgKgotICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBvbmx5IG9uY2UsIGFuZCBpdCB3aWxsCi0gICAqIGJlIHRoZSBsYXN0IG1ldGhvZCBpbnZva2VkIGR1cmluZyB0aGUgcGFyc2UuICBUaGUgcGFyc2VyIHNoYWxsCi0gICAqIG5vdCBpbnZva2UgdGhpcyBtZXRob2QgdW50aWwgaXQgaGFzIGVpdGhlciBhYmFuZG9uZWQgcGFyc2luZwotICAgKiAoYmVjYXVzZSBvZiBhbiB1bnJlY292ZXJhYmxlIGVycm9yKSBvciByZWFjaGVkIHRoZSBlbmQgb2YKLSAgICogaW5wdXQuPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIE5vIGFjdGlvbiBmb3IgdGhlIG1vbWVudC4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiB0aGUgYmVnaW5uaW5nIG9mIGFuIGVsZW1lbnQuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2QgYXQgdGhlIGJlZ2lubmluZyBvZiBldmVyeQotICAgKiBlbGVtZW50IGluIHRoZSBYTUwgZG9jdW1lbnQ7IHRoZXJlIHdpbGwgYmUgYSBjb3JyZXNwb25kaW5nCi0gICAqIGVuZEVsZW1lbnQoKSBldmVudCBmb3IgZXZlcnkgc3RhcnRFbGVtZW50KCkgZXZlbnQgKGV2ZW4gd2hlbiB0aGUKLSAgICogZWxlbWVudCBpcyBlbXB0eSkuIEFsbCBvZiB0aGUgZWxlbWVudCdzIGNvbnRlbnQgd2lsbCBiZQotICAgKiByZXBvcnRlZCwgaW4gb3JkZXIsIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50KCkKLSAgICogZXZlbnQuPC9wPgotICAgKgotICAgKiA8cD5JZiB0aGUgZWxlbWVudCBuYW1lIGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXggd2lsbAotICAgKiBzdGlsbCBiZSBhdHRhY2hlZC4gIE5vdGUgdGhhdCB0aGUgYXR0cmlidXRlIGxpc3QgcHJvdmlkZWQgd2lsbAotICAgKiBjb250YWluIG9ubHkgYXR0cmlidXRlcyB3aXRoIGV4cGxpY2l0IHZhbHVlcyAoc3BlY2lmaWVkIG9yCi0gICAqIGRlZmF1bHRlZCk6ICNJTVBMSUVEIGF0dHJpYnV0ZXMgd2lsbCBiZSBvbWl0dGVkLjwvcD4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5zIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIG5vZGUKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBlbGVtZW50IG5hbWUuCi0gICAqIEBwYXJhbSBhdHRzIFRoZSBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50LCBpZiBhbnkuCi0gICAqIEBzZWUgI2VuZEVsZW1lbnQKLSAgICogQHNlZSBvcmcueG1sLnNheC5BdHRyaWJ1dGVzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCi0gICAgICAgICAgU3RyaW5nIG5zLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgbmFtZSwgQXR0cmlidXRlcyBhdHRzKQotICAgICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBFbGVtZW50IGVsZW07Ci0KLSAgICBpZiAoKG51bGwgPT0gbnMpIHx8IChucy5sZW5ndGgoKSA9PSAwKSkKLSAgICAgIGVsZW0gPSBtX2RvYy5jcmVhdGVFbGVtZW50KG5hbWUpOwotICAgIGVsc2UKLSAgICAgIGVsZW0gPSBtX2RvYy5jcmVhdGVFbGVtZW50TlMobnMsIG5hbWUpOwotCi0gICAgYXBwZW5kKGVsZW0pOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaW50IG5BdHRzID0gYXR0cy5nZXRMZW5ndGgoKTsKLSAgCi0gICAgICBpZiAoMCAhPSBuQXR0cykKLSAgICAgIHsKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0czsgaSsrKQotICAgICAgICB7Ci0gIAotICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJ0eXBlICIgKyBhdHRzLmdldFR5cGUoaSkgKyAiIG5hbWUgIiArIGF0dHMuZ2V0TG9jYWxOYW1lKGkpICk7Ci0gICAgICAgICAgLy8gRmlyc3QgaGFuZGxlIGEgcG9zc2libGUgSUQgYXR0cmlidXRlCi0gICAgICAgICAgaWYgKGF0dHMuZ2V0VHlwZShpKS5lcXVhbHNJZ25vcmVDYXNlKCJJRCIpKQotICAgICAgICAgICAgc2V0SURBdHRyaWJ1dGUoYXR0cy5nZXRWYWx1ZShpKSwgZWxlbSk7Ci0gIAotICAgICAgICAgIFN0cmluZyBhdHRyTlMgPSBhdHRzLmdldFVSSShpKTsKLSAgICAgICAgICAKLSAgICAgICAgICBpZihhdHRyTlMgPT0gbnVsbCkKLSAgICAgICAgICAgIGF0dHJOUyA9ICIiOyAvLyBkZWZlbnNpdmUsIHNob3VsZG4ndCBoYXZlIHRvIGRvIHRoaXMuCi0gIAotICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYXR0ck5TOiAiK2F0dHJOUysiLCBsb2NhbE5hbWU6ICIrYXR0cy5nZXRRTmFtZShpKQotICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICsiLCBxbmFtZTogIithdHRzLmdldFFOYW1lKGkpKyIsIHZhbHVlOiAiK2F0dHMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgIC8vIENyaW1zb24gd29uJ3QgbGV0IHVzIHNldCBhbiB4bWxuczogYXR0cmlidXRlIG9uIHRoZSBET00uCi0gICAgICAgICAgU3RyaW5nIGF0dHJRTmFtZSA9IGF0dHMuZ2V0UU5hbWUoaSk7Ci0gICAgICAgICAgaWYgKChhdHRyTlMubGVuZ3RoKCkgPT0gMCkgLyogfHwgYXR0clFOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpIHx8IGF0dHJRTmFtZS5lcXVhbHMoInhtbG5zIikgKi8pCi0gICAgICAgICAgICBlbGVtLnNldEF0dHJpYnV0ZShhdHRyUU5hbWUsIGF0dHMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gIAotICAgICAgICAgICAgLy8gZWxlbS5zZXRBdHRyaWJ1dGVOUyhhdHRzLmdldFVSSShpKSwgYXR0cy5nZXRMb2NhbE5hbWUoaSksIGF0dHMuZ2V0VmFsdWUoaSkpOwotICAgICAgICAgICAgZWxlbS5zZXRBdHRyaWJ1dGVOUyhhdHRyTlMsIGF0dHJRTmFtZSwgYXR0cy5nZXRWYWx1ZShpKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIC8vIGFwcGVuZChlbGVtKTsKLSAgCi0gICAgICBtX2VsZW1TdGFjay5wdXNoKGVsZW0pOwotICAKLSAgICAgIG1fY3VycmVudE5vZGUgPSBlbGVtOwotICAgICAgCi0gICAgICAvLyBhcHBlbmQoZWxlbSk7Ci0gICAgfQotICAgIGNhdGNoKGphdmEubGFuZy5FeGNlcHRpb24gZGUpCi0gICAgewotICAgICAgLy8gZGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB0aHJvdyBuZXcgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uKGRlKTsKLSAgICB9Ci0gICAgCi0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgdGhlIGVuZCBvZiBhbiBlbGVtZW50LgotICAgKgotICAgKiA8cD5UaGUgU0FYIHBhcnNlciB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBhdCB0aGUgZW5kIG9mIGV2ZXJ5Ci0gICAqIGVsZW1lbnQgaW4gdGhlIFhNTCBkb2N1bWVudDsgdGhlcmUgd2lsbCBiZSBhIGNvcnJlc3BvbmRpbmcKLSAgICogc3RhcnRFbGVtZW50KCkgZXZlbnQgZm9yIGV2ZXJ5IGVuZEVsZW1lbnQoKSBldmVudCAoZXZlbiB3aGVuIHRoZQotICAgKiBlbGVtZW50IGlzIGVtcHR5KS48L3A+Ci0gICAqCi0gICAqIDxwPklmIHRoZSBlbGVtZW50IG5hbWUgaGFzIGEgbmFtZXNwYWNlIHByZWZpeCwgdGhlIHByZWZpeCB3aWxsCi0gICAqIHN0aWxsIGJlIGF0dGFjaGVkIHRvIHRoZSBuYW1lLjwvcD4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5zIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGVsZW1lbnQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBUaGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVsZW1lbnQKLSAgICogQHBhcmFtIG5hbWUgVGhlIGVsZW1lbnQgbmFtZQotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRWxlbWVudChTdHJpbmcgbnMsIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBuYW1lKQotICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotICAgIG1fZWxlbVN0YWNrLnBvcCgpOwotICAgIG1fY3VycmVudE5vZGUgPSBtX2VsZW1TdGFjay5pc0VtcHR5KCkgPyBudWxsIDogKE5vZGUpbV9lbGVtU3RhY2sucGVlaygpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBJRCBzdHJpbmcgdG8gbm9kZSBhc3NvY2lhdGlvbiBpbiB0aGUgSUQgdGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBpZCBUaGUgSUQgc3RyaW5nLgotICAgKiBAcGFyYW0gZWxlbSBUaGUgYXNzb2NpYXRlZCBJRC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldElEQXR0cmlidXRlKFN0cmluZyBpZCwgRWxlbWVudCBlbGVtKQotICB7Ci0KLSAgICAvLyBEbyBub3RoaW5nLiBUaGlzIG1ldGhvZCBpcyBtZWFudCB0byBiZSBvdmVyaWRlbi4KLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBjaGFyYWN0ZXIgZGF0YS4KLSAgICoKLSAgICogPHA+VGhlIFBhcnNlciB3aWxsIGNhbGwgdGhpcyBtZXRob2QgdG8gcmVwb3J0IGVhY2ggY2h1bmsgb2YKLSAgICogY2hhcmFjdGVyIGRhdGEuICBTQVggcGFyc2VycyBtYXkgcmV0dXJuIGFsbCBjb250aWd1b3VzIGNoYXJhY3RlcgotICAgKiBkYXRhIGluIGEgc2luZ2xlIGNodW5rLCBvciB0aGV5IG1heSBzcGxpdCBpdCBpbnRvIHNldmVyYWwKLSAgICogY2h1bmtzOyBob3dldmVyLCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gYW55IHNpbmdsZSBldmVudAotICAgKiBtdXN0IGNvbWUgZnJvbSB0aGUgc2FtZSBleHRlcm5hbCBlbnRpdHksIHNvIHRoYXQgdGhlIExvY2F0b3IKLSAgICogcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3Qgbm90IGF0dGVtcHQgdG8gcmVhZCBmcm9tIHRoZSBhcnJheQotICAgKiBvdXRzaWRlIG9mIHRoZSBzcGVjaWZpZWQgcmFuZ2UuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc29tZSBwYXJzZXJzIHdpbGwgcmVwb3J0IHdoaXRlc3BhY2UgdXNpbmcgdGhlCi0gICAqIGlnbm9yYWJsZVdoaXRlc3BhY2UoKSBtZXRob2QgcmF0aGVyIHRoYW4gdGhpcyBvbmUgKHZhbGlkYXRpbmcKLSAgICogcGFyc2VycyBtdXN0IGRvIHNvKS48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBjaCBUaGUgY2hhcmFjdGVycyBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKiBAc2VlICNpZ25vcmFibGVXaGl0ZXNwYWNlCi0gICAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvcgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoaXNPdXRzaWRlRG9jRWxlbSgpCi0gICAgICAgJiYgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoY2gsIHN0YXJ0LCBsZW5ndGgpKQotICAgICAgcmV0dXJuOyAgLy8gYXZvaWQgRE9NMDA2IEhpZXJhcmNoeSByZXF1ZXN0IGVycm9yCi0KLSAgICBpZiAobV9pbkNEYXRhKQotICAgIHsKLSAgICAgIGNkYXRhKGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIFN0cmluZyBzID0gbmV3IFN0cmluZyhjaCwgc3RhcnQsIGxlbmd0aCk7Ci0gICAgVGV4dCB0ZXh0ID0gbV9kb2MuY3JlYXRlVGV4dE5vZGUocyk7Ci0KLSAgICBhcHBlbmQodGV4dCk7Ci0gIH0KLQotICAvKioKLSAgICogSWYgYXZhaWxhYmxlLCB3aGVuIHRoZSBkaXNhYmxlLW91dHB1dC1lc2NhcGluZyBhdHRyaWJ1dGUgaXMgdXNlZCwKLSAgICogb3V0cHV0IHJhdyB0ZXh0IHdpdGhvdXQgZXNjYXBpbmcuICBBIFBJIHdpbGwgYmUgaW5zZXJ0ZWQgaW4gZnJvbnQKLSAgICogb2YgdGhlIG5vZGUgd2l0aCB0aGUgbmFtZSAibG90dXN4c2wtbmV4dC1pcy1yYXciIGFuZCBhIHZhbHVlIG9mCi0gICAqICJmb3JtYXR0ZXItdG8tZG9tIi4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFycmF5IGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtIHN0YXJ0IEluZGV4IHRvIHN0YXJ0IG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5Ci0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5IAotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVyc1JhdyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihpc091dHNpZGVEb2NFbGVtKCkgIAotICAgICAgICYmIG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKSkKLSAgICAgIHJldHVybjsgIC8vIGF2b2lkIERPTTAwNiBIaWVyYXJjaHkgcmVxdWVzdCBlcnJvcgotCi0KLSAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgYXBwZW5kKG1fZG9jLmNyZWF0ZVByb2Nlc3NpbmdJbnN0cnVjdGlvbigieHNsdC1uZXh0LWlzLXJhdyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0dGVyLXRvLWRvbSIpKTsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlVGV4dE5vZGUocykpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgYmVnaW5uaW5nIG9mIGFuIGVudGl0eS4KLSAgICoKLSAgICogVGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGRvY3VtZW50IGVudGl0eSBhcmUgbm90IHJlcG9ydGVkLgotICAgKiBUaGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgZXh0ZXJuYWwgRFREIHN1YnNldCBhcmUgcmVwb3J0ZWQKLSAgICogdXNpbmcgdGhlIHBzZXVkby1uYW1lICJbZHRkXSIuICBBbGwgb3RoZXIgZXZlbnRzIG11c3QgYmUKLSAgICogcHJvcGVybHkgbmVzdGVkIHdpdGhpbiBzdGFydC9lbmQgZW50aXR5IGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGVudGl0eS4gIElmIGl0IGlzIGEgcGFyYW1ldGVyCi0gICAqICAgICAgICBlbnRpdHksIHRoZSBuYW1lIHdpbGwgYmVnaW4gd2l0aCAnJScuCi0gICAqIEBzZWUgI2VuZEVudGl0eQotICAgKiBAc2VlIG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlciNpbnRlcm5hbEVudGl0eURlY2wKLSAgICogQHNlZSBvcmcueG1sLnNheC5leHQuRGVjbEhhbmRsZXIjZXh0ZXJuYWxFbnRpdHlEZWNsCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBBbG1vc3QgY2VydGFpbmx5IHRoZSB3cm9uZyBiZWhhdmlvci4uLgotICAgIC8vIGVudGl0eVJlZmVyZW5jZShuYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhbiBlbnRpdHkuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgdGhhdCBpcyBlbmRpbmcuCi0gICAqIEBzZWUgI3N0YXJ0RW50aXR5Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb257fQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGl2aWNhdGlvbiBvZiBhIGVudGl0eVJlZmVyZW5jZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZW50aXR5IHJlZmVyZW5jZQotICAgKi8KLSAgcHVibGljIHZvaWQgZW50aXR5UmVmZXJlbmNlKFN0cmluZyBuYW1lKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlRW50aXR5UmVmZXJlbmNlKG5hbWUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSBpbiBlbGVtZW50IGNvbnRlbnQuCi0gICAqCi0gICAqIDxwPlZhbGlkYXRpbmcgUGFyc2VycyBtdXN0IHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgZWFjaCBjaHVuawotICAgKiBvZiBpZ25vcmFibGUgd2hpdGVzcGFjZSAoc2VlIHRoZSBXM0MgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiwKLSAgICogc2VjdGlvbiAyLjEwKTogbm9uLXZhbGlkYXRpbmcgcGFyc2VycyBtYXkgYWxzbyB1c2UgdGhpcyBtZXRob2QKLSAgICogaWYgdGhleSBhcmUgY2FwYWJsZSBvZiBwYXJzaW5nIGFuZCB1c2luZyBjb250ZW50IG1vZGVscy48L3A+Ci0gICAqCi0gICAqIDxwPlNBWCBwYXJzZXJzIG1heSByZXR1cm4gYWxsIGNvbnRpZ3VvdXMgd2hpdGVzcGFjZSBpbiBhIHNpbmdsZQotICAgKiBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsIGNodW5rczsgaG93ZXZlciwgYWxsIG9mCi0gICAqIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQgbXVzdCBjb21lIGZyb20gdGhlIHNhbWUKLSAgICogZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yIHByb3ZpZGVzIHVzZWZ1bAotICAgKiBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGNoIFRoZSBjaGFyYWN0ZXJzIGZyb20gdGhlIFhNTCBkb2N1bWVudC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqIEBzZWUgI2NoYXJhY3RlcnMKLSAgICovCi0gIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgaWYoaXNPdXRzaWRlRG9jRWxlbSgpKQotICAgICAgcmV0dXJuOyAgLy8gYXZvaWQgRE9NMDA2IEhpZXJhcmNoeSByZXF1ZXN0IGVycm9yCi0KLSAgICBTdHJpbmcgcyA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LCBsZW5ndGgpOwotCi0gICAgYXBwZW5kKG1fZG9jLmNyZWF0ZVRleHROb2RlKHMpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGN1cnJlbnQgbm9kZSBpcyBvdXRzaWRlIHRoZSBkb2N1bWVudCBlbGVtZW50LgotICAgKiAKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjdXJyZW50IG5vZGUgaXMgb3V0c2lkZSB0aGUgZG9jdW1lbnQgZWxlbWVudC4KLSAgICovCi0gICBwcml2YXRlIGJvb2xlYW4gaXNPdXRzaWRlRG9jRWxlbSgpCi0gICB7Ci0gICAgICByZXR1cm4gKG51bGwgPT0gbV9kb2NGcmFnKSAmJiBtX2VsZW1TdGFjay5zaXplKCkgPT0gMCAmJiAobnVsbCA9PSBtX2N1cnJlbnROb2RlIHx8IG1fY3VycmVudE5vZGUuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkRPQ1VNRU5UX05PREUpOwotICAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24uCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBpbnZva2UgdGhpcyBtZXRob2Qgb25jZSBmb3IgZWFjaCBwcm9jZXNzaW5nCi0gICAqIGluc3RydWN0aW9uIGZvdW5kOiBub3RlIHRoYXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgbWF5IG9jY3VyCi0gICAqIGJlZm9yZSBvciBhZnRlciB0aGUgbWFpbiBkb2N1bWVudCBlbGVtZW50LjwvcD4KLSAgICoKLSAgICogPHA+QSBTQVggcGFyc2VyIHNob3VsZCBuZXZlciByZXBvcnQgYW4gWE1MIGRlY2xhcmF0aW9uIChYTUwgMS4wLAotICAgKiBzZWN0aW9uIDIuOCkgb3IgYSB0ZXh0IGRlY2xhcmF0aW9uIChYTUwgMS4wLCBzZWN0aW9uIDQuMy4xKQotICAgKiB1c2luZyB0aGlzIG1ldGhvZC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB0YXJnZXQgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGFyZ2V0LgotICAgKiBAcGFyYW0gZGF0YSBUaGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkYXRhLCBvciBudWxsIGlmCi0gICAqICAgICAgICBub25lIHdhcyBzdXBwbGllZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByb2Nlc3NpbmdJbnN0cnVjdGlvbihTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgZGF0YSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCBhbiBYTUwgY29tbWVudCBhbnl3aGVyZSBpbiB0aGUgZG9jdW1lbnQuCi0gICAqCi0gICAqIFRoaXMgY2FsbGJhY2sgd2lsbCBiZSB1c2VkIGZvciBjb21tZW50cyBpbnNpZGUgb3Igb3V0c2lkZSB0aGUKLSAgICogZG9jdW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGNvbW1lbnRzIGluIHRoZSBleHRlcm5hbCBEVEQKLSAgICogc3Vic2V0IChpZiByZWFkKS4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFuIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGNvbW1lbnQuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB1c2UgZnJvbSB0aGUgYXJyYXkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjb21tZW50KGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBhcHBlbmQobV9kb2MuY3JlYXRlQ29tbWVudChuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKSkpOwotICB9Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB0aGF0IHdlIGFyZSBwcm9jZXNzaW5nIGEgQ0RhdGEgc2VjdGlvbiAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2luQ0RhdGEgPSBmYWxzZTsKLQotICAvKioKLSAgICogUmVwb3J0IHRoZSBzdGFydCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIEBzZWUgI2VuZENEQVRBCi0gICAqLwotICBwdWJsaWMgdm9pZCBzdGFydENEQVRBKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbV9pbkNEYXRhID0gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBhIENEQVRBIHNlY3Rpb24uCi0gICAqCi0gICAqIEBzZWUgI3N0YXJ0Q0RBVEEKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgbV9pbkNEYXRhID0gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgY2RhdGEuCi0gICAqCi0gICAqIDxwPlRoZSBQYXJzZXIgd2lsbCBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBlYWNoIGNodW5rIG9mCi0gICAqIGNoYXJhY3RlciBkYXRhLiAgU0FYIHBhcnNlcnMgbWF5IHJldHVybiBhbGwgY29udGlndW91cyBjaGFyYWN0ZXIKLSAgICogZGF0YSBpbiBhIHNpbmdsZSBjaHVuaywgb3IgdGhleSBtYXkgc3BsaXQgaXQgaW50byBzZXZlcmFsCi0gICAqIGNodW5rczsgaG93ZXZlciwgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGFueSBzaW5nbGUgZXZlbnQKLSAgICogbXVzdCBjb21lIGZyb20gdGhlIHNhbWUgZXh0ZXJuYWwgZW50aXR5LCBzbyB0aGF0IHRoZSBMb2NhdG9yCi0gICAqIHByb3ZpZGVzIHVzZWZ1bCBpbmZvcm1hdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IG5vdCBhdHRlbXB0IHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkKLSAgICogb3V0c2lkZSBvZiB0aGUgc3BlY2lmaWVkIHJhbmdlLjwvcD4KLSAgICoKLSAgICogPHA+Tm90ZSB0aGF0IHNvbWUgcGFyc2VycyB3aWxsIHJlcG9ydCB3aGl0ZXNwYWNlIHVzaW5nIHRoZQotICAgKiBpZ25vcmFibGVXaGl0ZXNwYWNlKCkgbWV0aG9kIHJhdGhlciB0aGFuIHRoaXMgb25lICh2YWxpZGF0aW5nCi0gICAqIHBhcnNlcnMgbXVzdCBkbyBzbykuPC9wPgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICogQHNlZSAjaWdub3JhYmxlV2hpdGVzcGFjZQotICAgKiBAc2VlIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGNkYXRhKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihpc091dHNpZGVEb2NFbGVtKCkgIAotICAgICAgICYmIG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoLCBzdGFydCwgbGVuZ3RoKSkKLSAgICAgIHJldHVybjsgIC8vIGF2b2lkIERPTTAwNiBIaWVyYXJjaHkgcmVxdWVzdCBlcnJvcgotCi0gICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGNoLCBzdGFydCwgbGVuZ3RoKTsKLQotICAgIGFwcGVuZChtX2RvYy5jcmVhdGVDREFUQVNlY3Rpb24ocykpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlcG9ydCB0aGUgc3RhcnQgb2YgRFREIGRlY2xhcmF0aW9ucywgaWYgYW55LgotICAgKgotICAgKiBBbnkgZGVjbGFyYXRpb25zIGFyZSBhc3N1bWVkIHRvIGJlIGluIHRoZSBpbnRlcm5hbCBzdWJzZXQKLSAgICogdW5sZXNzIG90aGVyd2lzZSBpbmRpY2F0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBkb2N1bWVudCB0eXBlIG5hbWUuCi0gICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgZGVjbGFyZWQgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZQotICAgKiAgICAgICAgZXh0ZXJuYWwgRFREIHN1YnNldCwgb3IgbnVsbCBpZiBub25lIHdhcyBkZWNsYXJlZC4KLSAgICogQHBhcmFtIHN5c3RlbUlkIFRoZSBkZWNsYXJlZCBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlCi0gICAqICAgICAgICBleHRlcm5hbCBEVEQgc3Vic2V0LCBvciBudWxsIGlmIG5vbmUgd2FzIGRlY2xhcmVkLgotICAgKiBAc2VlICNlbmREVEQKLSAgICogQHNlZSAjc3RhcnRFbnRpdHkKLSAgICovCi0gIHB1YmxpYyB2b2lkIHN0YXJ0RFREKFN0cmluZyBuYW1lLCBTdHJpbmcgcHVibGljSWQsIFN0cmluZyBzeXN0ZW1JZCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIERvIG5vdGhpbmcgZm9yIG5vdy4KLSAgfQotCi0gIC8qKgotICAgKiBSZXBvcnQgdGhlIGVuZCBvZiBEVEQgZGVjbGFyYXRpb25zLgotICAgKgotICAgKiBAc2VlICNzdGFydERURAotICAgKi8KLSAgcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBEbyBub3RoaW5nIGZvciBub3cuCi0gIH0KLQotICAvKioKLSAgICogQmVnaW4gdGhlIHNjb3BlIG9mIGEgcHJlZml4LVVSSSBOYW1lc3BhY2UgbWFwcGluZy4KLSAgICoKLSAgICogPHA+VGhlIGluZm9ybWF0aW9uIGZyb20gdGhpcyBldmVudCBpcyBub3QgbmVjZXNzYXJ5IGZvcgotICAgKiBub3JtYWwgTmFtZXNwYWNlIHByb2Nlc3Npbmc6IHRoZSBTQVggWE1MIHJlYWRlciB3aWxsCi0gICAqIGF1dG9tYXRpY2FsbHkgcmVwbGFjZSBwcmVmaXhlcyBmb3IgZWxlbWVudCBhbmQgYXR0cmlidXRlCi0gICAqIG5hbWVzIHdoZW4gdGhlIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzCi0gICAqIGZlYXR1cmUgaXMgdHJ1ZSAodGhlIGRlZmF1bHQpLjwvcD4KLSAgICoKLSAgICogPHA+VGhlcmUgYXJlIGNhc2VzLCBob3dldmVyLCB3aGVuIGFwcGxpY2F0aW9ucyBuZWVkIHRvCi0gICAqIHVzZSBwcmVmaXhlcyBpbiBjaGFyYWN0ZXIgZGF0YSBvciBpbiBhdHRyaWJ1dGUgdmFsdWVzLAotICAgKiB3aGVyZSB0aGV5IGNhbm5vdCBzYWZlbHkgYmUgZXhwYW5kZWQgYXV0b21hdGljYWxseTsgdGhlCi0gICAqIHN0YXJ0L2VuZFByZWZpeE1hcHBpbmcgZXZlbnQgc3VwcGxpZXMgdGhlIGluZm9ybWF0aW9uCi0gICAqIHRvIHRoZSBhcHBsaWNhdGlvbiB0byBleHBhbmQgcHJlZml4ZXMgaW4gdGhvc2UgY29udGV4dHMKLSAgICogaXRzZWxmLCBpZiBuZWNlc3NhcnkuPC9wPgotICAgKgotICAgKiA8cD5Ob3RlIHRoYXQgc3RhcnQvZW5kUHJlZml4TWFwcGluZyBldmVudHMgYXJlIG5vdAotICAgKiBndWFyYW50ZWVkIHRvIGJlIHByb3Blcmx5IG5lc3RlZCByZWxhdGl2ZSB0byBlYWNoLW90aGVyOgotICAgKiBhbGwgc3RhcnRQcmVmaXhNYXBwaW5nIGV2ZW50cyB3aWxsIG9jY3VyIGJlZm9yZSB0aGUKLSAgICogY29ycmVzcG9uZGluZyBzdGFydEVsZW1lbnQgZXZlbnQsIGFuZCBhbGwgZW5kUHJlZml4TWFwcGluZwotICAgKiBldmVudHMgd2lsbCBvY2N1ciBhZnRlciB0aGUgY29ycmVzcG9uZGluZyBlbmRFbGVtZW50IGV2ZW50LAotICAgKiBidXQgdGhlaXIgb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFRoZSBOYW1lc3BhY2UgcHJlZml4IGJlaW5nIGRlY2xhcmVkLgotICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJIHRoZSBwcmVmaXggaXMgbWFwcGVkIHRvLgotICAgKiBAc2VlICNlbmRQcmVmaXhNYXBwaW5nCi0gICAqIEBzZWUgI3N0YXJ0RWxlbWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc3RhcnRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICAvKgotICAgIC8vIE5vdCBzdXJlIGlmIHRoaXMgaXMgbmVlZGVkIG9yIHdhbnRlZAotICAgIC8vIEFsc28sIGl0IGZhaWxzIGluIHRoZSBzdHJlZS4KLSAgICBpZigobnVsbCAhPSBtX2N1cnJlbnROb2RlKQotICAgICAgICYmIChtX2N1cnJlbnROb2RlLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpKQotICAgIHsKLSAgICAgIFN0cmluZyBxbmFtZTsKLSAgICAgIGlmKCgobnVsbCAhPSBwcmVmaXgpICYmIChwcmVmaXgubGVuZ3RoKCkgPT0gMCkpCi0gICAgICAgICB8fCAobnVsbCA9PSBwcmVmaXgpKQotICAgICAgICBxbmFtZSA9ICJ4bWxucyI7Ci0gICAgICBlbHNlCi0gICAgICAgIHFuYW1lID0gInhtbG5zOiIrcHJlZml4OwotCi0gICAgICBFbGVtZW50IGVsZW0gPSAoRWxlbWVudCltX2N1cnJlbnROb2RlOwotICAgICAgU3RyaW5nIHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlKHFuYW1lKTsKLSAgICAgIGlmKHZhbCA9PSBudWxsKQotICAgICAgewotICAgICAgICBlbGVtLnNldEF0dHJpYnV0ZU5TKCJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lLCB1cmkpOwotICAgICAgfQotICAgIH0KLSAgICAqLwotICB9Ci0KLSAgLyoqCi0gICAqIEVuZCB0aGUgc2NvcGUgb2YgYSBwcmVmaXgtVVJJIG1hcHBpbmcuCi0gICAqCi0gICAqIDxwPlNlZSBzdGFydFByZWZpeE1hcHBpbmcgZm9yIGRldGFpbHMuICBUaGlzIGV2ZW50IHdpbGwKLSAgICogYWx3YXlzIG9jY3VyIGFmdGVyIHRoZSBjb3JyZXNwb25kaW5nIGVuZEVsZW1lbnQgZXZlbnQsCi0gICAqIGJ1dCB0aGUgb3JkZXIgb2YgZW5kUHJlZml4TWFwcGluZyBldmVudHMgaXMgbm90IG90aGVyd2lzZQotICAgKiBndWFyYW50ZWVkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRoYXQgd2FzIGJlaW5nIG1hcHBpbmcuCi0gICAqIEBzZWUgI3N0YXJ0UHJlZml4TWFwcGluZwotICAgKiBAc2VlICNlbmRFbGVtZW50Ci0gICAqLwotICBwdWJsaWMgdm9pZCBlbmRQcmVmaXhNYXBwaW5nKFN0cmluZyBwcmVmaXgpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb257fQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHNraXBwZWQgZW50aXR5LgotICAgKgotICAgKiA8cD5UaGUgUGFyc2VyIHdpbGwgaW52b2tlIHRoaXMgbWV0aG9kIG9uY2UgZm9yIGVhY2ggZW50aXR5Ci0gICAqIHNraXBwZWQuICBOb24tdmFsaWRhdGluZyBwcm9jZXNzb3JzIG1heSBza2lwIGVudGl0aWVzIGlmIHRoZXkKLSAgICogaGF2ZSBub3Qgc2VlbiB0aGUgZGVjbGFyYXRpb25zIChiZWNhdXNlLCBmb3IgZXhhbXBsZSwgdGhlCi0gICAqIGVudGl0eSB3YXMgZGVjbGFyZWQgaW4gYW4gZXh0ZXJuYWwgRFREIHN1YnNldCkuICBBbGwgcHJvY2Vzc29ycwotICAgKiBtYXkgc2tpcCBleHRlcm5hbCBlbnRpdGllcywgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZXMgb2YgdGhlCi0gICAqIGh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9leHRlcm5hbC1nZW5lcmFsLWVudGl0aWVzIGFuZCB0aGUKLSAgICogaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL2V4dGVybmFsLXBhcmFtZXRlci1lbnRpdGllcwotICAgKiBwcm9wZXJ0aWVzLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHNraXBwZWQgZW50aXR5LiAgSWYgaXQgaXMgYQotICAgKiAgICAgICAgcGFyYW1ldGVyIGVudGl0eSwgdGhlIG5hbWUgd2lsbCBiZWdpbiB3aXRoICclJy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb257fQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL0RlZmF1bHRFcnJvckhhbmRsZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9EZWZhdWx0RXJyb3JIYW5kbGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM2Y2FhYWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL0RlZmF1bHRFcnJvckhhbmRsZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IG9yZy54bWwuc2F4Lio7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5FcnJvckxpc3RlbmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7Ci1pbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKLQotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBJbXBsZW1lbnQgU0FYIGVycm9yIGhhbmRsZXIgZm9yIGRlZmF1bHQgcmVwb3J0aW5nLgotICovCi1wdWJsaWMgY2xhc3MgRGVmYXVsdEVycm9ySGFuZGxlciBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciwgRXJyb3JMaXN0ZW5lcgotewotICBQcmludFdyaXRlciBtX3B3OwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBEZWZhdWx0RXJyb3JIYW5kbGVyCi0gICAqLwotICBwdWJsaWMgRGVmYXVsdEVycm9ySGFuZGxlcihQcmludFdyaXRlciBwdykKLSAgewotICAgIG1fcHcgPSBwdzsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIERlZmF1bHRFcnJvckhhbmRsZXIKLSAgICovCi0gIHB1YmxpYyBEZWZhdWx0RXJyb3JIYW5kbGVyKFByaW50U3RyZWFtIHB3KQotICB7Ci0gICAgbV9wdyA9IG5ldyBQcmludFdyaXRlcihwdywgdHJ1ZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBEZWZhdWx0RXJyb3JIYW5kbGVyCi0gICAqLwotICBwdWJsaWMgRGVmYXVsdEVycm9ySGFuZGxlcigpCi0gIHsKLSAgICBtX3B3ID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpOwotICB9Ci0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSB3YXJuaW5nLgotICAgKgotICAgKiA8cD5TQVggcGFyc2VycyB3aWxsIHVzZSB0aGlzIG1ldGhvZCB0byByZXBvcnQgY29uZGl0aW9ucyB0aGF0Ci0gICAqIGFyZSBub3QgZXJyb3JzIG9yIGZhdGFsIGVycm9ycyBhcyBkZWZpbmVkIGJ5IHRoZSBYTUwgMS4wCi0gICAqIHJlY29tbWVuZGF0aW9uLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHRha2Ugbm8gYWN0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgbXVzdCBjb250aW51ZSB0byBwcm92aWRlIG5vcm1hbCBwYXJzaW5nIGV2ZW50cwotICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgd2FybmluZyBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybmluZyhTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIHByaW50TG9jYXRpb24obV9wdywgZXhjZXB0aW9uKTsKLSAgICBtX3B3LnByaW50bG4oIlBhcnNlciB3YXJuaW5nOiAiICsgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSByZWNvdmVyYWJsZSBlcnJvci4KLSAgICoKLSAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZXJyb3IiIGluIHNlY3Rpb24gMS4yCi0gICAqIG9mIHRoZSBXM0MgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbi4gIEZvciBleGFtcGxlLCBhIHZhbGlkYXRpbmcKLSAgICogcGFyc2VyIHdvdWxkIHVzZSB0aGlzIGNhbGxiYWNrIHRvIHJlcG9ydCB0aGUgdmlvbGF0aW9uIG9mIGEKLSAgICogdmFsaWRpdHkgY29uc3RyYWludC4gIFRoZSBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byB0YWtlIG5vCi0gICAqIGFjdGlvbi48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBTQVggcGFyc2VyIG11c3QgY29udGludWUgdG8gcHJvdmlkZSBub3JtYWwgcGFyc2luZyBldmVudHMKLSAgICogYWZ0ZXIgaW52b2tpbmcgdGhpcyBtZXRob2Q6IGl0IHNob3VsZCBzdGlsbCBiZSBwb3NzaWJsZSBmb3IgdGhlCi0gICAqIGFwcGxpY2F0aW9uIHRvIHByb2Nlc3MgdGhlIGRvY3VtZW50IHRocm91Z2ggdG8gdGhlIGVuZC4gIElmIHRoZQotICAgKiBhcHBsaWNhdGlvbiBjYW5ub3QgZG8gc28sIHRoZW4gdGhlIHBhcnNlciBzaG91bGQgcmVwb3J0IGEgZmF0YWwKLSAgICogZXJyb3IgZXZlbiBpZiB0aGUgWE1MIDEuMCByZWNvbW1lbmRhdGlvbiBkb2VzIG5vdCByZXF1aXJlIGl0IHRvCi0gICAqIGRvIHNvLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIFNBWEV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKFNBWFBhcnNlRXhjZXB0aW9uIGV4Y2VwdGlvbikgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICB7Ci0gICAgLy8gcHJpbnRMb2NhdGlvbihleGNlcHRpb24pOwotICAgIC8vIG1fcHcucHJpbnRsbihleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLQotICAgIHRocm93IGV4Y2VwdGlvbjsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIG5vbi1yZWNvdmVyYWJsZSBlcnJvci4KLSAgICoKLSAgICogPHA+VGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZGVmaW5pdGlvbiBvZiAiZmF0YWwgZXJyb3IiIGluCi0gICAqIHNlY3Rpb24gMS4yIG9mIHRoZSBXM0MgWE1MIDEuMCBSZWNvbW1lbmRhdGlvbi4gIEZvciBleGFtcGxlLCBhCi0gICAqIHBhcnNlciB3b3VsZCB1c2UgdGhpcyBjYWxsYmFjayB0byByZXBvcnQgdGhlIHZpb2xhdGlvbiBvZiBhCi0gICAqIHdlbGwtZm9ybWVkbmVzcyBjb25zdHJhaW50LjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIG11c3QgYXNzdW1lIHRoYXQgdGhlIGRvY3VtZW50IGlzIHVudXNhYmxlCi0gICAqIGFmdGVyIHRoZSBwYXJzZXIgaGFzIGludm9rZWQgdGhpcyBtZXRob2QsIGFuZCBzaG91bGQgY29udGludWUKLSAgICogKGlmIGF0IGFsbCkgb25seSBmb3IgdGhlIHNha2Ugb2YgY29sbGVjdGluZyBhZGRpdGlvbiBlcnJvcgotICAgKiBtZXNzYWdlczogaW4gZmFjdCwgU0FYIHBhcnNlcnMgYXJlIGZyZWUgdG8gc3RvcCByZXBvcnRpbmcgYW55Ci0gICAqIG90aGVyIGV2ZW50cyBvbmNlIHRoaXMgbWV0aG9kIGhhcyBiZWVuIGludm9rZWQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBTQVhFeGNlcHRpb24KLSAgewotICAgIC8vIHByaW50TG9jYXRpb24oZXhjZXB0aW9uKTsKLSAgICAvLyBtX3B3LnByaW50bG4oZXhjZXB0aW9uLmdldE1lc3NhZ2UoKSk7Ci0KLSAgICB0aHJvdyBleGNlcHRpb247Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHdhcm5pbmcuCi0gICAqCi0gICAqIDxwPlNBWCBwYXJzZXJzIHdpbGwgdXNlIHRoaXMgbWV0aG9kIHRvIHJlcG9ydCBjb25kaXRpb25zIHRoYXQKLSAgICogYXJlIG5vdCBlcnJvcnMgb3IgZmF0YWwgZXJyb3JzIGFzIGRlZmluZWQgYnkgdGhlIFhNTCAxLjAKLSAgICogcmVjb21tZW5kYXRpb24uICBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gdGFrZSBubyBhY3Rpb24uPC9wPgotICAgKgotICAgKiA8cD5UaGUgU0FYIHBhcnNlciBtdXN0IGNvbnRpbnVlIHRvIHByb3ZpZGUgbm9ybWFsIHBhcnNpbmcgZXZlbnRzCi0gICAqIGFmdGVyIGludm9raW5nIHRoaXMgbWV0aG9kOiBpdCBzaG91bGQgc3RpbGwgYmUgcG9zc2libGUgZm9yIHRoZQotICAgKiBhcHBsaWNhdGlvbiB0byBwcm9jZXNzIHRoZSBkb2N1bWVudCB0aHJvdWdoIHRvIHRoZSBlbmQuPC9wPgotICAgKgotICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSB3YXJuaW5nIGluZm9ybWF0aW9uIGVuY2Fwc3VsYXRlZCBpbiBhCi0gICAqICAgICAgICAgICAgICAgICAgU0FYIHBhcnNlIGV4Y2VwdGlvbi4KLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKiBAc2VlIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHdhcm5pbmcoVHJhbnNmb3JtZXJFeGNlcHRpb24gZXhjZXB0aW9uKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHByaW50TG9jYXRpb24obV9wdywgZXhjZXB0aW9uKTsKLQotICAgIG1fcHcucHJpbnRsbihleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZWNlaXZlIG5vdGlmaWNhdGlvbiBvZiBhIHJlY292ZXJhYmxlIGVycm9yLgotICAgKgotICAgKiA8cD5UaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBkZWZpbml0aW9uIG9mICJlcnJvciIgaW4gc2VjdGlvbiAxLjIKLSAgICogb2YgdGhlIFczQyBYTUwgMS4wIFJlY29tbWVuZGF0aW9uLiAgRm9yIGV4YW1wbGUsIGEgdmFsaWRhdGluZwotICAgKiBwYXJzZXIgd291bGQgdXNlIHRoaXMgY2FsbGJhY2sgdG8gcmVwb3J0IHRoZSB2aW9sYXRpb24gb2YgYQotICAgKiB2YWxpZGl0eSBjb25zdHJhaW50LiAgVGhlIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHRha2Ugbm8KLSAgICogYWN0aW9uLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIFNBWCBwYXJzZXIgbXVzdCBjb250aW51ZSB0byBwcm92aWRlIG5vcm1hbCBwYXJzaW5nIGV2ZW50cwotICAgKiBhZnRlciBpbnZva2luZyB0aGlzIG1ldGhvZDogaXQgc2hvdWxkIHN0aWxsIGJlIHBvc3NpYmxlIGZvciB0aGUKLSAgICogYXBwbGljYXRpb24gdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQgdGhyb3VnaCB0byB0aGUgZW5kLiAgSWYgdGhlCi0gICAqIGFwcGxpY2F0aW9uIGNhbm5vdCBkbyBzbywgdGhlbiB0aGUgcGFyc2VyIHNob3VsZCByZXBvcnQgYSBmYXRhbAotICAgKiBlcnJvciBldmVuIGlmIHRoZSBYTUwgMS4wIHJlY29tbWVuZGF0aW9uIGRvZXMgbm90IHJlcXVpcmUgaXQgdG8KLSAgICogZG8gc28uPC9wPgotICAgKgotICAgKiBAcGFyYW0gZXhjZXB0aW9uIFRoZSBlcnJvciBpbmZvcm1hdGlvbiBlbmNhcHN1bGF0ZWQgaW4gYQotICAgKiAgICAgICAgICAgICAgICAgIFNBWCBwYXJzZSBleGNlcHRpb24uCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBBbnkgU0FYIGV4Y2VwdGlvbiwgcG9zc2libHkKLSAgICogICAgICAgICAgICB3cmFwcGluZyBhbm90aGVyIGV4Y2VwdGlvbi4KLSAgICogQHNlZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBlcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgLy8gcHJpbnRMb2NhdGlvbihleGNlcHRpb24pOwotICAgIC8vIGVuc3VyZUxvY2F0aW9uU2V0KGV4Y2VwdGlvbik7Ci0KLSAgICB0aHJvdyBleGNlcHRpb247Ci0gIH0KLQotICAvKioKLSAgICogUmVjZWl2ZSBub3RpZmljYXRpb24gb2YgYSBub24tcmVjb3ZlcmFibGUgZXJyb3IuCi0gICAqCi0gICAqIDxwPlRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGRlZmluaXRpb24gb2YgImZhdGFsIGVycm9yIiBpbgotICAgKiBzZWN0aW9uIDEuMiBvZiB0aGUgVzNDIFhNTCAxLjAgUmVjb21tZW5kYXRpb24uICBGb3IgZXhhbXBsZSwgYQotICAgKiBwYXJzZXIgd291bGQgdXNlIHRoaXMgY2FsbGJhY2sgdG8gcmVwb3J0IHRoZSB2aW9sYXRpb24gb2YgYQotICAgKiB3ZWxsLWZvcm1lZG5lc3MgY29uc3RyYWludC48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSBhcHBsaWNhdGlvbiBtdXN0IGFzc3VtZSB0aGF0IHRoZSBkb2N1bWVudCBpcyB1bnVzYWJsZQotICAgKiBhZnRlciB0aGUgcGFyc2VyIGhhcyBpbnZva2VkIHRoaXMgbWV0aG9kLCBhbmQgc2hvdWxkIGNvbnRpbnVlCi0gICAqIChpZiBhdCBhbGwpIG9ubHkgZm9yIHRoZSBzYWtlIG9mIGNvbGxlY3RpbmcgYWRkaXRpb24gZXJyb3IKLSAgICogbWVzc2FnZXM6IGluIGZhY3QsIFNBWCBwYXJzZXJzIGFyZSBmcmVlIHRvIHN0b3AgcmVwb3J0aW5nIGFueQotICAgKiBvdGhlciBldmVudHMgb25jZSB0aGlzIG1ldGhvZCBoYXMgYmVlbiBpbnZva2VkLjwvcD4KLSAgICoKLSAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXJyb3IgaW5mb3JtYXRpb24gZW5jYXBzdWxhdGVkIGluIGEKLSAgICogICAgICAgICAgICAgICAgICBTQVggcGFyc2UgZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gQW55IFNBWCBleGNlcHRpb24sIHBvc3NpYmx5Ci0gICAqICAgICAgICAgICAgd3JhcHBpbmcgYW5vdGhlciBleGNlcHRpb24uCi0gICAqIEBzZWUgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZmF0YWxFcnJvcihUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgLy8gcHJpbnRMb2NhdGlvbihleGNlcHRpb24pOwotICAgIC8vIGVuc3VyZUxvY2F0aW9uU2V0KGV4Y2VwdGlvbik7Ci0KLSAgICB0aHJvdyBleGNlcHRpb247Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBlbnN1cmVMb2NhdGlvblNldChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pCi0gIHsKLSAgICAvLyBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSBleGNlcHRpb24uZ2V0TG9jYXRvcigpOwotICAgIFNvdXJjZUxvY2F0b3IgbG9jYXRvciA9IG51bGw7Ci0gICAgVGhyb3dhYmxlIGNhdXNlID0gZXhjZXB0aW9uOwotICAgIAotICAgIC8vIFRyeSB0byBmaW5kIHRoZSBsb2NhdG9yIGNsb3Nlc3QgdG8gdGhlIGNhdXNlLgotICAgIGRvCi0gICAgewotICAgICAgaWYoY2F1c2UgaW5zdGFuY2VvZiBTQVhQYXJzZUV4Y2VwdGlvbikKLSAgICAgIHsKLSAgICAgICAgbG9jYXRvciA9IG5ldyBTQVhTb3VyY2VMb2NhdG9yKChTQVhQYXJzZUV4Y2VwdGlvbiljYXVzZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChjYXVzZSBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBTb3VyY2VMb2NhdG9yIGNhdXNlTG9jYXRvciA9ICgoVHJhbnNmb3JtZXJFeGNlcHRpb24pY2F1c2UpLmdldExvY2F0b3IoKTsKLSAgICAgICAgaWYobnVsbCAhPSBjYXVzZUxvY2F0b3IpCi0gICAgICAgICAgbG9jYXRvciA9IGNhdXNlTG9jYXRvcjsKLSAgICAgIH0KLSAgICAgIAotICAgICAgaWYoY2F1c2UgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFRyYW5zZm9ybWVyRXhjZXB0aW9uKWNhdXNlKS5nZXRDYXVzZSgpOwotICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFNBWEV4Y2VwdGlvbiljYXVzZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNhdXNlID0gbnVsbDsKLSAgICB9Ci0gICAgd2hpbGUobnVsbCAhPSBjYXVzZSk7Ci0gICAgCi0gICAgZXhjZXB0aW9uLnNldExvY2F0b3IobG9jYXRvcik7Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludExvY2F0aW9uKFByaW50U3RyZWFtIHB3LCBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleGNlcHRpb24pCi0gIHsKLSAgICBwcmludExvY2F0aW9uKG5ldyBQcmludFdyaXRlcihwdyksIGV4Y2VwdGlvbik7Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludExvY2F0aW9uKFByaW50V3JpdGVyIHB3LCBUaHJvd2FibGUgZXhjZXB0aW9uKQotICB7Ci0gICAgU291cmNlTG9jYXRvciBsb2NhdG9yID0gbnVsbDsKLSAgICBUaHJvd2FibGUgY2F1c2UgPSBleGNlcHRpb247Ci0gICAgCi0gICAgLy8gVHJ5IHRvIGZpbmQgdGhlIGxvY2F0b3IgY2xvc2VzdCB0byB0aGUgY2F1c2UuCi0gICAgZG8KLSAgICB7Ci0gICAgICBpZihjYXVzZSBpbnN0YW5jZW9mIFNBWFBhcnNlRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBsb2NhdG9yID0gbmV3IFNBWFNvdXJjZUxvY2F0b3IoKFNBWFBhcnNlRXhjZXB0aW9uKWNhdXNlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKGNhdXNlIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIFNvdXJjZUxvY2F0b3IgY2F1c2VMb2NhdG9yID0gKChUcmFuc2Zvcm1lckV4Y2VwdGlvbiljYXVzZSkuZ2V0TG9jYXRvcigpOwotICAgICAgICBpZihudWxsICE9IGNhdXNlTG9jYXRvcikKLSAgICAgICAgICBsb2NhdG9yID0gY2F1c2VMb2NhdG9yOwotICAgICAgfQotICAgICAgaWYoY2F1c2UgaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFRyYW5zZm9ybWVyRXhjZXB0aW9uKWNhdXNlKS5nZXRDYXVzZSgpOwotICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKQotICAgICAgICBjYXVzZSA9ICgoV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pY2F1c2UpLmdldEV4Y2VwdGlvbigpOwotICAgICAgZWxzZSBpZihjYXVzZSBpbnN0YW5jZW9mIFNBWEV4Y2VwdGlvbikKLSAgICAgICAgY2F1c2UgPSAoKFNBWEV4Y2VwdGlvbiljYXVzZSkuZ2V0RXhjZXB0aW9uKCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNhdXNlID0gbnVsbDsKLSAgICB9Ci0gICAgd2hpbGUobnVsbCAhPSBjYXVzZSk7Ci0gICAgICAgIAotICAgIGlmKG51bGwgIT0gbG9jYXRvcikKLSAgICB7Ci0gICAgICAvLyBtX3B3LnByaW50bG4oIlBhcnNlciBmYXRhbCBlcnJvcjogIitleGNlcHRpb24uZ2V0TWVzc2FnZSgpKTsKLSAgICAgIFN0cmluZyBpZCA9IChsb2NhdG9yLmdldFB1YmxpY0lkKCkgIT0gbG9jYXRvci5nZXRQdWJsaWNJZCgpKQotICAgICAgICAgICAgICAgICAgPyBsb2NhdG9yLmdldFB1YmxpY0lkKCkKLSAgICAgICAgICAgICAgICAgICAgOiAobnVsbCAhPSBsb2NhdG9yLmdldFN5c3RlbUlkKCkpCi0gICAgICAgICAgICAgICAgICAgICAgPyBsb2NhdG9yLmdldFN5c3RlbUlkKCkgOiAiU3lzdGVtSWQgVW5rbm93biI7Ci0KLSAgICAgIHB3LnByaW50KGlkICsgIjsgTGluZSAiICsgbG9jYXRvci5nZXRMaW5lTnVtYmVyKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICArICI7IENvbHVtbiAiICsgbG9jYXRvci5nZXRDb2x1bW5OdW1iZXIoKSsiOyAiKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcHcucHJpbnQoIihMb2NhdGlvbiBvZiBlcnJvciB1bmtub3duKSIpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvRWxlbURlc2MuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9FbGVtRGVzYy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZDJhM2ZlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9FbGVtRGVzYy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjI1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgaXMgaW4gc3VwcG9ydCBvZiBTZXJpYWxpemVyVG9IVE1MLCBhbmQgYWN0cyBhcyBhIHNvcnQKLSAqIG9mIGVsZW1lbnQgcmVwcmVzZW50YXRpdmUgZm9yIEhUTUwgZWxlbWVudHMuCi0gKi8KLWNsYXNzIEVsZW1EZXNjCi17Ci0KLSAgLyoqIFRhYmxlIG9mIGF0dHJpYnV0ZXMgZm9yIHRoZSBlbGVtZW50ICovCi0gIEhhc2h0YWJsZSBtX2F0dHJzID0gbnVsbDsKLQotICAvKiogRWxlbWVudCdzIGZsYWdzLCBkZXNjcmliaW5nIHRoZSByb2xlIHRoaXMgZWxlbWVudCBwbGF5cyBkdXJpbmcKLSAgICogZm9ybWF0dGluZyBvZiB0aGUgZG9jdW1lbnQuIFRoaXMgaXMgdXNlZCBhcyBhIGJpdHZlY3RvcjsgbW9yZSB0aGFuIG9uZSBmbGFnCi0gICAqIG1heSBiZSBzZXQgYXQgYSB0aW1lLCBiaXR3aXNlLU9SZWQgdG9nZXRoZXIuIE1uZW1vbmljIGFuZCBiaXRzCi0gICAqIGhhdmUgYmVlbiBhc3NpZ25lZCB0byB0aGUgZmxhZyB2YWx1ZXMuIE5PVEU6IFNvbWUgYml0cyBhcmUKLSAgICogY3VycmVudGx5IGFzc2lnbmVkIG11bHRpcGxlIG1uZW1vbmljczsgaXQgaXMgdGhlIGNhbGxlcidzCi0gICAqIHJlc3BvbnNpYmlsaXR5IHRvIGRpc2FtYmlndWF0ZSB0aGVzZSBpZiBuZWNlc3NhcnkuICovCi0gIGludCBtX2ZsYWdzOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBFTVBUWSBmbGFnICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgRU1QVFkgPSAoMSA8PCAxKTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgRkxPVyBmbGFnICAqLwotICBzdGF0aWMgZmluYWwgaW50IEZMT1cgPSAoMSA8PCAyKTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgQkxPQ0sgZmxhZyAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEJMT0NLID0gKDEgPDwgMyk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEJMT0NLRk9STSAgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tGT1JNID0gKDEgPDwgNCk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEJMT0NLRk9STUZJRUxEU0VUIGZsYWcgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBCTE9DS0ZPUk1GSUVMRFNFVCA9ICgxIDw8IDUpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBDREFUQSBmbGFnICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBDREFUQSA9ICgxIDw8IDYpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBQQ0RBVEEgZmxhZyAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IFBDREFUQSA9ICgxIDw8IDcpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBSQVcgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgUkFXID0gKDEgPDwgOCk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIElOTElORSBmbGFnICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgSU5MSU5FID0gKDEgPDwgOSk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIElOTElORUEgZmxhZyAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IElOTElORUEgPSAoMSA8PCAxMCk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIElOTElORUxBQkVMIGZsYWcgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBJTkxJTkVMQUJFTCA9ICgxIDw8IDExKTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgRk9OVFNUWUxFIGZsYWcgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBGT05UU1RZTEUgPSAoMSA8PCAxMik7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIFBIUkFTRSBmbGFnICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgUEhSQVNFID0gKDEgPDwgMTMpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBGT1JNQ1RSTCBmbGFnICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBGT1JNQ1RSTCA9ICgxIDw8IDE0KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgU1BFQ0lBTCBmbGFnICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBTUEVDSUFMID0gKDEgPDwgMTUpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBBU1BFQ0lBTCBmbGFnICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBBU1BFQ0lBTCA9ICgxIDw8IDE2KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgSEVBRE1JU0MgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgSEVBRE1JU0MgPSAoMSA8PCAxNyk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEhFQUQgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgSEVBRCA9ICgxIDw8IDE4KTsKLQotICAvKiogRGVmaW5lcyBtbmVtb25pYyBhbmQgYml0LXZhbHVlIGZvciB0aGUgTElTVCBmbGFnICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludCBMSVNUID0gKDEgPDwgMTkpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBQUkVGT1JNQVRURUQgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgUFJFRk9STUFUVEVEID0gKDEgPDwgMjApOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBXSElURVNQQUNFU0VOU0lUSVZFIGZsYWcgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IFdISVRFU1BBQ0VTRU5TSVRJVkUgPSAoMSA8PCAyMSk7Ci0KLSAgLyoqIERlZmluZXMgbW5lbW9uaWMgYW5kIGJpdC12YWx1ZSBmb3IgdGhlIEFUVFJVUkwgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQVRUUlVSTCA9ICgxIDw8IDEpOwotCi0gIC8qKiBEZWZpbmVzIG1uZW1vbmljIGFuZCBiaXQtdmFsdWUgZm9yIHRoZSBBVFRSRU1QVFkgZmxhZyAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgQVRUUkVNUFRZID0gKDEgPDwgMik7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBFbGVtZW50RGVzY3JpcHRpb24gd2l0aCBhbiBpbml0aWFsIHNldCBvZiBmbGFncy4KLSAgICoKLSAgICogQHBhcmFtIGZsYWdzIEVsZW1lbnQgZmxhZ3MKLSAgICogQHNlZSBtX2ZsYWdzCi0gICAqLwotICBFbGVtRGVzYyhpbnQgZmxhZ3MpCi0gIHsKLSAgICBtX2ZsYWdzID0gZmxhZ3M7Ci0gIH0KLQotICAvKioKLSAgICogImlzICh0aGlzIGVsZW1lbnQgZGVzY3JpYmVkIGJ5IHRoZXNlIGZsYWdzKSIuCi0gICAqIAotICAgKiBUaGlzIG1pZ2h0IG1vcmUgcHJvcGVybHkgYmUgY2FsbGVkIGFyZUZsYWdzU2V0KCkuIEl0IGFjY2VwdHMgYW4KLSAgICogaW50ZWdlciAoYmVpbmcgdXNlZCBhcyBhIGJpdHZlY3RvcikgYW5kIGNoZWNrcyB3aGV0aGVyIGFsbCB0aGUgCi0gICAqIGNvcnJlc3BvbmRpbmcgYml0cyBhcmUgc2V0IGluIG91ciBpbnRlcm5hbCBmbGFncy4gTm90ZSB0aGF0IHRoaXMKLSAgICogdGVzdCBpcyBwZXJmb3JtZWQgYXMgYSBiaXR3aXNlIEFORCwgbm90IGFuIGVxdWFsaXR5IHRlc3QsIHNvIGEKLSAgICogMCBiaXQgaW4gdGhlIGlucHV0IG1lYW5zICJkb24ndCB0ZXN0Iiwgbm90ICJtdXN0IGJlIHNldCBmYWxzZSIuCi0gICAqCi0gICAqIEBwYXJhbSBmbGFncyBWZWN0b3Igb2YgZmxhZ3MgdG8gY29tcGFyZSBhZ2FpbnN0IHRoaXMgZWxlbWVudCdzIGZsYWdzCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmxhZ3Mgc2V0IGluIHRoZSBwYXJhbWV0ZXIgYXJlIGFsc28gc2V0IGluIHRoZQotICAgKiBlbGVtZW50J3Mgc3RvcmVkIGZsYWdzLgotICAgKiAKLSAgICogQHNlZSBtX2ZsYWdzCi0gICAqIEBzZWUgaXNBdHRyRmxhZ1NldAotICAgKi8KLSAgYm9vbGVhbiBpcyhpbnQgZmxhZ3MpCi0gIHsKLSAgICAvLyBpbnQgd2hpY2ggPSAobV9mbGFncyAmIGZsYWdzKTsKLSAgICByZXR1cm4gKG1fZmxhZ3MgJiBmbGFncykgIT0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYSBuZXcgYXR0cmlidXRlIGZvciB0aGlzIGVsZW1lbnQgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBuYW1lCi0gICAqIEBwYXJhbSBmbGFncyBBdHRpYnV0ZSBmbGFncwotICAgKi8KLSAgdm9pZCBzZXRBdHRyKFN0cmluZyBuYW1lLCBpbnQgZmxhZ3MpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fYXR0cnMpCi0gICAgICBtX2F0dHJzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gICAgbV9hdHRycy5wdXQobmFtZSwgbmV3IEludGVnZXIoZmxhZ3MpKTsKLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIG91dCBpZiBhIGZsYWcgaXMgc2V0IGluIGEgZ2l2ZW4gYXR0cmlidXRlIG9mIHRoaXMgZWxlbWVudCAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUgQXR0cmlidXRlIG5hbWUKLSAgICogQHBhcmFtIGZsYWdzIEZsYWcgdG8gY2hlY2sKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBmbGFnIGlzIHNldCBpbiB0aGUgYXR0cmlidXRlLiBSZXR1cm5zIGZhbHNlCi0gICAqIGlmIHRoZSBhdHRyaWJ1dGUgaXMgbm90IGZvdW5kIAotICAgKiBAc2VlIG1fZmxhZ3MKLSAgICovCi0gIGJvb2xlYW4gaXNBdHRyRmxhZ1NldChTdHJpbmcgbmFtZSwgaW50IGZsYWdzKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2F0dHJzKQotICAgIHsKLSAgICAgIEludGVnZXIgX2ZsYWdzID0gKEludGVnZXIpIG1fYXR0cnMuZ2V0KG5hbWUpOwotCi0gICAgICBpZiAobnVsbCAhPSBfZmxhZ3MpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiAoX2ZsYWdzLmludFZhbHVlKCkgJiBmbGFncykgIT0gMDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9GYXN0U3RyaW5nQnVmZmVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvRmFzdFN0cmluZ0J1ZmZlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMTBhOTNlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9GYXN0U3RyaW5nQnVmZmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjA2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi0vKioKLSAqIEJhcmUtYm9uZXMsIHVuc2FmZSwgZmFzdCBzdHJpbmcgYnVmZmVyLiBObyB0aHJlYWQtc2FmZXR5LCBubwotICogcGFyYW1ldGVyIHJhbmdlIGNoZWNraW5nLCBleHBvc2VkIGZpZWxkcy4gTm90ZSB0aGF0IGluIHR5cGljYWwKLSAqIGFwcGxpY2F0aW9ucywgdGhyZWFkLXNhZmV0eSBvZiBhIFN0cmluZ0J1ZmZlciBpcyBhIHNvbWV3aGF0Ci0gKiBkdWJpb3VzIGNvbmNlcHQgaW4gYW55IGNhc2UuCi0gKiA8cD4KLSAqIE5vdGUgdGhhdCBTdHJlZSBpcyB1c2luZyBhIHNpbmdsZSBGYXN0U3RyaW5nQnVmZmVyIGFzIGEgc3RyaW5nIHBvb2wsCi0gKiBieSByZWNvcmRpbmcgc3RhcnQgYW5kIGxlbmd0aCBpbmRpY2VzIHdpdGhpbiBhIHNpbmdsZSBidWZmZXIuIFRoaXMKLSAqIG1pbmltaXplcyBoZWFwIG92ZXJoZWFkLCBidXQgb2YgY291cnNlIHJlcXVpcmVzIG1vcmUgd29yayB3aGVuIHJldHJpZXZpbmcKLSAqIHRoZSBkYXRhLgotICogPHA+Ci0gKiBUaGlzIGhhcyBiZWVuIHJlY29kZWQgdG8gb3BlcmF0ZSBhcyBhICJjaHVua2VkIGJ1ZmZlciIuIERvaW5nIHNvCi0gKiByZWR1Y2VzIHRoZSBuZWVkIHRvIHJlY29weSBleGlzdGluZyBpbmZvcm1hdGlvbiB3aGVuIGFuIGFwcGVuZAotICogZXhjZWVkcyB0aGUgc3BhY2UgYXZhaWxhYmxlOyB3ZSBqdXN0IGFsbG9jYXRlIGFub3RoZXIgY2h1bmsgYW5kCi0gKiBmbG93IGFjcm9zcyB0byBpdC4gKFRoZSBhcnJheSBvZiBjaHVua3MgbWF5IG5lZWQgdG8gZ3JvdywKLSAqIGFkbWl0dGVkbHksIGJ1dCB0aGF0J3MgYSBtdWNoIHNtYWxsZXIgb2JqZWN0LikgU29tZSBleGNlc3MKLSAqIHJlY29weWluZyBtYXkgYXJpc2Ugd2hlbiB3ZSBleHRyYWN0IFN0cmluZ3Mgd2hpY2ggY3Jvc3MgY2h1bmsKLSAqIGJvdW5kYXJpZXM7IGxhcmdlciBjaHVua3MgbWFrZSB0aGF0IGxlc3MgZnJlcXVlbnQuCi0gKiA8cD4KLSAqIFRoZSBzaXplIHZhbHVlcyBhcmUgcGFyYW1ldGVyaXplZCwgdG8gYWxsb3cgdHVuaW5nIHRoaXMgY29kZS4gSW4KLSAqIHRoZW9yeSwgUlRGcyBtaWdodCB3YW50IHRvIGJlIHR1bmVkIGRpZmZlcmVudGx5IGZyb20gdGhlIG1haW4KLSAqIGRvY3VtZW50J3MgdGV4dC4KLSAqIDxwPgotICovCi1wdWJsaWMgY2xhc3MgRmFzdFN0cmluZ0J1ZmZlcgotewotICAvLyBJZiBub256ZXJvLCBmb3JjZXMgdGhlIGluaWFsIGNodW5rIHNpemUuCi0gIC8qKi9zdGF0aWMgZmluYWwgaW50IERFQlVHX0ZPUkNFX0lOSVRfQklUUz0wOwotCi0gIC8qKgotICAgKiBGaWVsZCBtX2NodW5rQml0cyBzZXRzIG91ciBjaHVua2luZyBzdHJhdGVneSwgYnkgc2F5aW5nIGhvdyBtYW55Ci0gICAqIGJpdHMgb2YgaW5kZXggY2FuIGJlIHVzZWQgd2l0aGluIGEgc2luZ2xlIGNodW5rIGJlZm9yZSBmbG93aW5nIG92ZXIKLSAgICogdG8gdGhlIG5leHQgY2h1bmsuIEZvciBleGFtcGxlLCBpZiBtX2NodW5rYml0cyBpcyBzZXQgdG8gMTUsIGVhY2gKLSAgICogY2h1bmsgY2FuIGNvbnRhaW4gdXAgdG8gMl4xNSAoMzJLKSBjaGFyYWN0ZXJzICAKLSAgICovCi0gIGludCBtX2NodW5rQml0cyA9IDE1OwotCi0gIC8qKgotICAgKiBGaWVsZCBtX21heENodW5rQml0cyBhZmZlY3RzIG91ciBjaHVuay1ncm93dGggc3RyYXRlZ3ksIGJ5IHNheWluZyB3aGF0Ci0gICAqIHRoZSBsYXJnZXN0IHBlcm1pc3NpYmxlIGNodW5rIHNpemUgaXMgaW4gdGhpcyBwYXJ0aWN1bGFyIEZhc3RTdHJpbmdCdWZmZXIKLSAgICogaGllcmFyY2h5LiAKLSAgICovCi0gIGludCBtX21heENodW5rQml0cyA9IDE1OwotCi0gIC8qKgotICAgKiBGaWVsZCBtX3JlY2h1bmtCaXRzIGFmZmVjdHMgb3VyIGNodW5rLWdyb3d0aCBzdHJhdGVneSwgYnkgc2F5aW5nIGhvdwotICAgKiBtYW55IGNodW5rcyBzaG91bGQgYmUgYWxsb2NhdGVkIGF0IG9uZSBzaXplIGJlZm9yZSB3ZSBlbmNhcHN1bGF0ZSB0aGVtCi0gICAqIGludG8gdGhlIGZpcnN0IGNodW5rIG9mIHRoZSBuZXh0IHNpemUgdXAuIEZvciBleGFtcGxlLCBpZiBtX3JlY2h1bmtCaXRzCi0gICAqIGlzIHNldCB0byAzLCB0aGVuIGFmdGVyIDggY2h1bmtzIGF0IGEgZ2l2ZW4gc2l6ZSB3ZSB3aWxsIHJlYnVuZGxlCi0gICAqIHRoZW0gYXMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYSBGYXN0U3RyaW5nQnVmZmVyIHVzaW5nIGEgY2h1bmsgc2l6ZQotICAgKiA4IHRpbWVzIGxhcmdlciAoY2h1bmtCaXRzIHNoaWZ0ZWQgbGVmdCB0aHJlZSBiaXRzKS4KLSAgICovCi0gIGludCBtX3JlYnVuZGxlQml0cyA9IDI7Ci0KLSAgLyoqCi0gICAqIEZpZWxkIG1fY2h1bmtTaXplIGVzdGFibGlzaGVzIHRoZSBtYXhpbXVtIHNpemUgb2Ygb25lIGNodW5rIG9mIHRoZSBhcnJheQotICAgKiBhcyAyKipjaHVua2JpdHMgY2hhcmFjdGVycy4KLSAgICogKFdoaWNoIG1heSBhbHNvIGJlIHRoZSBtaW5pbXVtIHNpemUgaWYgd2UgYXJlbid0IHR1bmluZyBmb3Igc3RvcmFnZSkgCi0gICAqLwotICBpbnQgbV9jaHVua1NpemU7ICAvLyA9MTw8KG1fY2h1bmtCaXRzLTEpOwotCi0gIC8qKgotICAgKiBGaWVsZCBtX2NodW5rTWFzayBpcyBtX2NodW5rU2l6ZS0xIC0tIGluIG90aGVyIHdvcmRzLCBtX2NodW5rQml0cwotICAgKiB3b3J0aCBvZiBsb3ctb3JkZXIgJzEnIGJpdHMsIHVzZWZ1bCBmb3Igc2hpZnQtYW5kLW1hc2sgYWRkcmVzc2luZwotICAgKiB3aXRoaW4gdGhlIGNodW5rcy4gCi0gICAqLwotICBpbnQgbV9jaHVua01hc2s7ICAvLyA9bV9jaHVua1NpemUtMTsKLQotICAvKioKLSAgICogRmllbGQgbV9hcnJheSBob2xkcyB0aGUgc3RyaW5nIGJ1ZmZlcidzIHRleHQgY29udGVudHMsIHVzaW5nIGFuCi0gICAqIGFycmF5LW9mLWFycmF5cy4gTm90ZSB0aGF0IHRoaXMgYXJyYXksIGFuZCB0aGUgYXJyYXlzIGl0IGNvbnRhaW5zLCBtYXkgYmUKLSAgICogcmVhbGxvY2F0ZWQgd2hlbiBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gYWxsb3cgdGhlIGJ1ZmZlciB0byBncm93OwotICAgKiByZWZlcmVuY2VzIHRvIHRoZW0gc2hvdWxkIGJlIGNvbnNpZGVyZWQgdG8gYmUgaW52YWxpZGF0ZWQgYWZ0ZXIgYW55Ci0gICAqIGFwcGVuZC4gSG93ZXZlciwgdGhlIG9ubHkgdGltZSB0aGVzZSBhcnJheXMgYXJlIGRpcmVjdGx5IGV4cG9zZWQKLSAgICogaXMgaW4gdGhlIHNlbmRTQVhjaGFyYWN0ZXJzIGNhbGwuCi0gICAqLwotICBjaGFyW11bXSBtX2FycmF5OwotCi0gIC8qKgotICAgKiBGaWVsZCBtX2xhc3RDaHVuayBpcyBhbiBpbmRleCBpbnRvIG1fYXJyYXlbXSwgcG9pbnRpbmcgdG8gdGhlIGxhc3QKLSAgICogY2h1bmsgb2YgdGhlIENodW5rZWQgQXJyYXkgY3VycmVudGx5IGluIHVzZS4gTm90ZSB0aGF0IGFkZGl0aW9uYWwKLSAgICogY2h1bmtzIG1heSBhY3R1YWxseSBiZSBhbGxvY2F0ZWQsIGVnIGlmIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGhhZAotICAgKiBwcmV2aW91c2x5IGJlZW4gdHJ1bmNhdGVkIG9yIGlmIHNvbWVvbmUgaXNzdWVkIGFuIGVuc3VyZVNwYWNlIHJlcXVlc3QuCi0gICAqIDxwPgotICAgKiBUaGUgaW5zZXJ0aW9uIHBvaW50IGZvciBhcHBlbmQgb3BlcmF0aW9ucyBpcyBhZGRyZXNzZWQgYnkgdGhlIGNvbWJpbmF0aW9uCi0gICAqIG9mIG1fbGFzdENodW5rIGFuZCBtX2ZpcnN0RnJlZS4KLSAgICovCi0gIGludCBtX2xhc3RDaHVuayA9IDA7Ci0KLSAgLyoqCi0gICAqIEZpZWxkIG1fZmlyc3RGcmVlIGlzIGFuIGluZGV4IGludG8gbV9hcnJheVttX2xhc3RDaHVua11bXSwgcG9pbnRpbmcgdG8KLSAgICogdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgQ2h1bmtlZCBBcnJheSB3aGljaCBpcyBub3QgcGFydCBvZiB0aGUKLSAgICogRmFzdFN0cmluZ0J1ZmZlcidzIGN1cnJlbnQgY29udGVudC4gU2luY2UgbV9hcnJheVtdW10gaXMgemVyby1iYXNlZCwKLSAgICogdGhlIGxlbmd0aCBvZiB0aGF0IGNvbnRlbnQgY2FuIGJlIGNhbGN1bGF0ZWQgYXMKLSAgICogKG1fbGFzdENodW5rPDxtX2NodW5rQml0cykgKyBtX2ZpcnN0RnJlZSAKLSAgICovCi0gIGludCBtX2ZpcnN0RnJlZSA9IDA7Ci0KLSAgLyoqCi0gICAqIEZpZWxkIG1faW5uZXJGU0IsIHdoZW4gbm9uLW51bGwsIGlzIGEgRmFzdFN0cmluZ0J1ZmZlciB3aG9zZSB0b3RhbAotICAgKiBsZW5ndGggZXF1YWxzIG1fY2h1bmtTaXplLCBhbmQgd2hpY2ggcmVwbGFjZXMgbV9hcnJheVswXS4gVGhpcyBhbGxvd3MKLSAgICogYnVpbGRpbmcgYSBoaWVyYXJjaHkgb2YgRmFzdFN0cmluZ0J1ZmZlcnMsIHdoZXJlIGVhcmx5IGFwcGVuZHMgdXNlCi0gICAqIGEgc21hbGxlciBjaHVua1NpemUgKGZvciBsZXNzIHdhc3RlZCBtZW1vcnkgb3ZlcmhlYWQpIGJ1dCBsYXRlcgotICAgKiBvbmVzIHVzZSBhIGxhcmdlciBjaHVua1NpemUgKGZvciBsZXNzIGhlYXAgYWN0aXZpdHkgb3ZlcmhlYWQpLgotICAgKi8KLSAgRmFzdFN0cmluZ0J1ZmZlciBtX2lubmVyRlNCID0gbnVsbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRmFzdFN0cmluZ0J1ZmZlciwgd2l0aCBhbGxvY2F0aW9uIHBvbGljeSBhcyBwZXIgcGFyYW1ldGVycy4KLSAgICogPHA+Ci0gICAqIEZvciBjb2RpbmcgY29udmVuaWVuY2UsIEkndmUgZXhwcmVzc2VkIGJvdGggYWxsb2NhdGlvbiBzaXplcyBpbiB0ZXJtcyBvZgotICAgKiBhIG51bWJlciBvZiBiaXRzLiBUaGF0J3MgbmVlZGVkIGZvciB0aGUgZmluYWwgc2l6ZSBvZiBhIGNodW5rLAotICAgKiB0byBwZXJtaXQgZmFzdCBhbmQgZWZmaWNpZW50IHNoaWZ0LWFuZC1tYXNrIGFkZHJlc3NpbmcuIEl0J3MgbGVzcyBjcml0aWNhbAotICAgKiBmb3IgdGhlIGluaXRhbCBzaXplLCBhbmQgbWF5IGJlIHJlY29uc2lkZXJlZC4KLSAgICogPHA+Ci0gICAqIEFuIGFsdGVybmF0aXZlIHdvdWxkIGJlIHRvIGFjY2VwdCBpbnRlZ2VyIHNpemVzIGFuZCByb3VuZCB0byBwb3dlcnMgb2YgdHdvOwotICAgKiB0aGF0IHJlYWxseSBkb2Vzbid0IHNlZW0gdG8gYnV5IHVzIG11Y2gsIGlmIGFueXRoaW5nLgotICAgKgotICAgKiBAcGFyYW0gaW5pdENodW5rQml0cyBMZW5ndGggaW4gY2hhcmFjdGVycyBvZiB0aGUgaW5pdGlhbCBhbGxvY2F0aW9uCi0gICAqIG9mIGEgY2h1bmssIGV4cHJlc3NlZCBpbiBsb2ctYmFzZS0yLiAoVGhhdCBpcywgMTAgbWVhbnMgYWxsb2NhdGUgMTAyNAotICAgKiBjaGFyYWN0ZXJzLikgTGF0ZXIgY2h1bmtzIHdpbGwgdXNlIGxhcmdlciBhbGxvY2F0aW9uIHVuaXRzLCB0byB0cmFkZSBvZmYKLSAgICogYWxsb2NhdGlvbiBzcGVlZCBvZiBsYXJnZSBkb2N1bWVudCBhZ2FpbnN0IHN0b3JhZ2UgZWZmaWNpZW5jeSBvZiBzbWFsbAotICAgKiBvbmVzLgotICAgKiBAcGFyYW0gbWF4Q2h1bmtCaXRzIE51bWJlciBvZiBjaGFyYWN0ZXItb2Zmc2V0IGJpdHMgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IKLSAgICogYWRkcmVzc2luZyB3aXRoaW4gYSBjaHVuay4gTWF4aW11bSBsZW5ndGggb2YgYSBjaHVuayBpcyAyXmNodW5rQml0cwotICAgKiBjaGFyYWN0ZXJzLgotICAgKiBAcGFyYW0gcmVidW5kbGVCaXRzIE51bWJlciBvZiBjaGFyYWN0ZXItb2Zmc2V0IGJpdHMgdGhhdCBhZGRyZXNzaW5nIHNob3VsZAotICAgKiBhZHZhbmNlIGJlZm9yZSB3ZSBhdHRlbXB0IHRvIHRha2UgYSBzdGVwIGZyb20gaW5pdENodW5rQml0cyB0byBtYXhDaHVua0JpdHMKLSAgICovCi0gIHB1YmxpYyBGYXN0U3RyaW5nQnVmZmVyKGludCBpbml0Q2h1bmtCaXRzLCBpbnQgbWF4Q2h1bmtCaXRzLAotICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVidW5kbGVCaXRzKQotICB7Ci0gICAgaWYoREVCVUdfRk9SQ0VfSU5JVF9CSVRTIT0wKSBpbml0Q2h1bmtCaXRzPURFQlVHX0ZPUkNFX0lOSVRfQklUUzsKLQotICAgIG1fYXJyYXkgPSBuZXcgY2hhclsxNl1bXTsKLQotICAgIC8vIERvbid0IGJpdGUgb2ZmIG1vcmUgdGhhbiB3ZSdyZSBwcmVwYXJlZCB0byBzd2FsbG93IQotICAgIGlmIChpbml0Q2h1bmtCaXRzID4gbWF4Q2h1bmtCaXRzKQotICAgICAgaW5pdENodW5rQml0cyA9IG1heENodW5rQml0czsKLQotICAgIG1fY2h1bmtCaXRzID0gaW5pdENodW5rQml0czsKLSAgICBtX21heENodW5rQml0cyA9IG1heENodW5rQml0czsKLSAgICBtX3JlYnVuZGxlQml0cyA9IHJlYnVuZGxlQml0czsKLSAgICBtX2NodW5rU2l6ZSA9IDEgPDwgKGluaXRDaHVua0JpdHMpOwotICAgIG1fY2h1bmtNYXNrID0gbV9jaHVua1NpemUgLSAxOwotICAgIG1fYXJyYXlbMF0gPSBuZXcgY2hhclttX2NodW5rU2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRmFzdFN0cmluZ0J1ZmZlciwgdXNpbmcgYSBkZWZhdWx0IHJlYnVuZGxlQml0cyB2YWx1ZS4KLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIGluaXRDaHVua0JpdHMKLSAgICogTkVFRFNET0MgQHBhcmFtIG1heENodW5rQml0cwotICAgKi8KLSAgcHVibGljIEZhc3RTdHJpbmdCdWZmZXIoaW50IGluaXRDaHVua0JpdHMsIGludCBtYXhDaHVua0JpdHMpCi0gIHsKLSAgICB0aGlzKGluaXRDaHVua0JpdHMsIG1heENodW5rQml0cywgMik7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgRmFzdFN0cmluZ0J1ZmZlciwgdXNpbmcgZGVmYXVsdCBtYXhDaHVua0JpdHMgYW5kCi0gICAqIHJlYnVuZGxlQml0cyB2YWx1ZXMuCi0gICAqIDxwPgotICAgKiBJU1NVRTogU2hvdWxkIHRoaXMgY2FsbCBhc3NlcnQgaW5pdGlhbCBzaXplLCBvciBmaXhlZCBzaXplPwotICAgKiBOb3cgY29uZmlndXJlZCBhcyBpbml0aWFsLCB3aXRoIGEgZGVmYXVsdCBmb3IgZml4ZWQuCi0gICAqCi0gICAqIEBwYXJhbQotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gaW5pdENodW5rQml0cwotICAgKi8KLSAgcHVibGljIEZhc3RTdHJpbmdCdWZmZXIoaW50IGluaXRDaHVua0JpdHMpCi0gIHsKLSAgICB0aGlzKGluaXRDaHVua0JpdHMsIDE1LCAyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBGYXN0U3RyaW5nQnVmZmVyLCB1c2luZyBhIGRlZmF1bHQgYWxsb2NhdGlvbiBwb2xpY3kuCi0gICAqLwotICBwdWJsaWMgRmFzdFN0cmluZ0J1ZmZlcigpCi0gIHsKLQotICAgIC8vIDEwIGJpdHMgaXMgMUsuIDE1IGJpdHMgaXMgMzJLLiBSZW1lbWJlciB0aGF0IHRoZXNlIGFyZSBjaGFyYWN0ZXIKLSAgICAvLyBjb3VudHMsIHNvIGFjdHVhbCBtZW1vcnkgYWxsb2NhdGlvbiB1bml0IGlzIGRvdWJsZWQgZm9yIFVURi0xNiBjaGFycy4KLSAgICAvLwotICAgIC8vIEZvciByZWZlcmVuY2U6IEluIHRoZSBvcmlnaW5hbCBGYXN0U3RyaW5nQnVmZmVyLCB3ZSBzaW1wbHkKLSAgICAvLyBvdmVyYWxsb2NhdGVkIGJ5IGJsb2Nrc2l6ZSAoZGVmYXVsdCAxS0IpIG9uIGVhY2ggYnVmZmVyLWdyb3d0aC4KLSAgICB0aGlzKDEwLCAxNSwgMik7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuIFN5bm9ueW0gZm9yIGxlbmd0aCgpLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgRmFzdFN0cmluZ0J1ZmZlcidzIGNvbnRlbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIChtX2xhc3RDaHVuayA8PCBtX2NodW5rQml0cykgKyBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4gU3lub255bSBmb3Igc2l6ZSgpLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgRmFzdFN0cmluZ0J1ZmZlcidzIGNvbnRlbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGxlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gKG1fbGFzdENodW5rIDw8IG1fY2h1bmtCaXRzKSArIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERpc2NhcmQgdGhlIGNvbnRlbnQgb2YgdGhlIEZhc3RTdHJpbmdCdWZmZXIsIGFuZCBtb3N0IG9mIHRoZSBtZW1vcnkKLSAgICogdGhhdCB3YXMgYWxsb2NhdGVkIGJ5IGl0LCByZXN0b3JpbmcgdGhlIGluaXRpYWwgc3RhdGUuIE5vdGUgdGhhdCB0aGlzCi0gICAqIG1heSBldmVudHVhbGx5IGJlIGRpZmZlcmVudCBmcm9tIHNldExlbmd0aCgwKSwgd2hpY2ggc2VlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVzZXQoKQotICB7Ci0KLSAgICBtX2xhc3RDaHVuayA9IDA7Ci0gICAgbV9maXJzdEZyZWUgPSAwOwotCi0gICAgLy8gUmVjb3ZlciB0aGUgb3JpZ2luYWwgY2h1bmsgc2l6ZQotICAgIEZhc3RTdHJpbmdCdWZmZXIgaW5uZXJtb3N0ID0gdGhpczsKLQotICAgIHdoaWxlIChpbm5lcm1vc3QubV9pbm5lckZTQiAhPSBudWxsKQotICAgIHsKLSAgICAgIGlubmVybW9zdCA9IGlubmVybW9zdC5tX2lubmVyRlNCOwotICAgIH0KLQotICAgIG1fY2h1bmtCaXRzID0gaW5uZXJtb3N0Lm1fY2h1bmtCaXRzOwotICAgIG1fY2h1bmtTaXplID0gaW5uZXJtb3N0Lm1fY2h1bmtTaXplOwotICAgIG1fY2h1bmtNYXNrID0gaW5uZXJtb3N0Lm1fY2h1bmtNYXNrOwotCi0gICAgLy8gRGlzY2FyZCB0aGUgaGllcmFyY2h5Ci0gICAgbV9pbm5lckZTQiA9IG51bGw7Ci0gICAgbV9hcnJheSA9IG5ldyBjaGFyWzE2XVswXTsKLSAgICBtX2FycmF5WzBdID0gbmV3IGNoYXJbbV9jaHVua1NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IHNldCBob3cgbXVjaCBvZiB0aGUgRmFzdFN0cmluZ0J1ZmZlcidzIHN0b3JhZ2UgaXMgdG8gYmUKLSAgICogY29uc2lkZXJlZCBwYXJ0IG9mIGl0cyBjb250ZW50LiBUaGlzIGlzIGEgZmFzdCBidXQgaGF6YXJkb3VzCi0gICAqIG9wZXJhdGlvbi4gSXQgaXMgbm90IHByb3RlY3RlZCBhZ2FpbnN0IG5lZ2F0aXZlIHZhbHVlcywgb3IgdmFsdWVzCi0gICAqIGdyZWF0ZXIgdGhhbiB0aGUgYW1vdW50IG9mIHN0b3JhZ2UgY3VycmVudGx5IGF2YWlsYWJsZS4uLiBhbmQgZXZlbgotICAgKiBpZiBhZGRpdGlvbmFsIHN0b3JhZ2UgZG9lcyBleGlzdCwgaXRzIGNvbnRlbnRzIGFyZSB1bnByZWRpY3RhYmxlLgotICAgKiBUaGUgb25seSBzYWZlIHVzZSBmb3Igb3VyIHNldExlbmd0aCgpIGlzIHRvIHRydW5jYXRlIHRoZSBGYXN0U3RyaW5nQnVmZmVyCi0gICAqIHRvIGEgc2hvcnRlciBzdHJpbmcuCi0gICAqIDxwPgotICAgKiBUT0RPOiAlUkVWRUlXJSBDdXJyZW50IHNldExlbmd0aCBjb2RlIGlzIHByb2JhYmx5IG5vdCB0aGUgYmVzdCBzb2x1dGlvbi4KLSAgICogSXQgcmVsZWFzZXMgbWVtb3J5IHRoYXQgaW4gdGhlb3J5IHdlIHNob3VsZG4gcmV0YWluIGFuZAotICAgKiByZXVzZS4gSG9sZGluZyBvbnRvIHRoYXQgd291bGQgcmVxdWlyZSByZWN1cnNpdmUgdHJ1bmNhdGlvbiBvZgotICAgKiB0aGUgaW5uZXIgRlNCLCBhbmQgZXh0ZW5kaW5nIHRoZSBhcHBlbmQgb3BlcmF0aW9ucyB0byByZWN1cnNlCi0gICAqIGludG8gdGhlIGlubmVyIEZTQiB3aGVuIHNwYWNlIGV4aXN0cyB3aXRoaW4gdGhlbS4gQ291bGQgYmUgZG9uZSwKLSAgICogYnV0IG5vbnRyaXZpYWwgY2hhbmdlIGFuZCBhZGRzIHNvbWUgb3ZlcmhlYWQgdG8gdGhlIGFwcGVuZAotICAgKiBvcGVyYXRpb24uIENvbnNpZGVyIGFsdGVybmF0aXZlcy4gCi0gICAqCi0gICAqIEBwYXJhbSBsIE5ldyBsZW5ndGguIElmIGw8MCBvciBsPj1nZXRMZW5ndGgoKSwgdGhpcyBvcGVyYXRpb24gd2lsbAotICAgKiBub3QgcmVwb3J0IGFuIGVycm9yIGJ1dCBmdXR1cmUgb3BlcmF0aW9ucyB3aWxsIGFsbW9zdCBjZXJ0YWlubHkgZmFpbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldExlbmd0aChpbnQgbCkKLSAgewotCi0gICAgbV9sYXN0Q2h1bmsgPSBsID4+PiBtX2NodW5rQml0czsKLQotICAgIGlmIChtX2xhc3RDaHVuayA9PSAwICYmIG1faW5uZXJGU0IgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX2lubmVyRlNCLnNldExlbmd0aChsLCB0aGlzKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fZmlyc3RGcmVlID0gbCAmIG1fY2h1bmtNYXNrOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBTdWJyb3V0aW5lIGZvciB0aGUgcHVibGljIHNldExlbmd0aCgpIG1ldGhvZC4gRGVhbHMgd2l0aCB0aGUgZmFjdAotICAgKiB0aGF0IHRydW5jYXRpb24gbWF5IHJlcXVpcmUgcmVzdG9yaW5nIG9uZSBvZiB0aGUgaW5uZXJGU0JzCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBsCi0gICAqIE5FRURTRE9DIEBwYXJhbSByb290RlNCCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgc2V0TGVuZ3RoKGludCBsLCBGYXN0U3RyaW5nQnVmZmVyIHJvb3RGU0IpCi0gIHsKLQotICAgIG1fbGFzdENodW5rID0gbCA+Pj4gbV9jaHVua0JpdHM7Ci0KLSAgICBpZiAobV9sYXN0Q2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgewotICAgICAgbV9pbm5lckZTQi5zZXRMZW5ndGgobCwgcm9vdEZTQik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIFVuZG8gZW5jYXBzdWxhdGlvbiAtLSBwb3AgdGhlIGlubmVyRlNCIGRhdGEgYmFjayB1cCB0byByb290LgotICAgICAgcm9vdEZTQi5tX2NodW5rQml0cyA9IG1fY2h1bmtCaXRzOwotICAgICAgcm9vdEZTQi5tX21heENodW5rQml0cyA9IG1fbWF4Q2h1bmtCaXRzOwotICAgICAgcm9vdEZTQi5tX3JlYnVuZGxlQml0cyA9IG1fcmVidW5kbGVCaXRzOwotICAgICAgcm9vdEZTQi5tX2NodW5rU2l6ZSA9IG1fY2h1bmtTaXplOwotICAgICAgcm9vdEZTQi5tX2NodW5rTWFzayA9IG1fY2h1bmtNYXNrOwotICAgICAgcm9vdEZTQi5tX2FycmF5ID0gbV9hcnJheTsKLSAgICAgIHJvb3RGU0IubV9pbm5lckZTQiA9IG1faW5uZXJGU0I7Ci0gICAgICByb290RlNCLm1fbGFzdENodW5rID0gbV9sYXN0Q2h1bms7Ci0KLSAgICAgIC8vIEZpbmFsbHksIHRydW5jYXRlIHRoaXMgc3Vja2VyLgotICAgICAgcm9vdEZTQi5tX2ZpcnN0RnJlZSA9IGwgJiBtX2NodW5rTWFzazsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTm90ZSB0aGF0IHRoaXMgb3BlcmF0aW9uIGhhcyBiZWVuIHNvbWV3aGF0IGRlb3B0aW1pemVkIGJ5IHRoZSBzaGlmdCB0byBhCi0gICAqIGNodW5rZWQgYXJyYXksIGFzIHRoZXJlIGlzIG5vIGZhY3RvcnkgbWV0aG9kIHRvIHByb2R1Y2UgYSBTdHJpbmcgb2JqZWN0Ci0gICAqIGRpcmVjdGx5IGZyb20gYW4gYXJyYXkgb2YgYXJyYXlzIGFuZCBoZW5jZSBhIGRvdWJsZSBjb3B5IGlzIG5lZWRlZC4KLSAgICogQnkgdXNpbmcgZW5zdXJlQ2FwYWNpdHkgd2UgaG9wZSB0byBtaW5pbWl6ZSB0aGUgaGVhcCBvdmVyaGVhZCBvZiBidWlsZGluZwotICAgKiB0aGUgaW50ZXJtZWRpYXRlIFN0cmluZ0J1ZmZlci4KLSAgICogPHA+Ci0gICAqIChJdCByZWFsbHkgaXMgYSBwaXR5IHRoYXQgSmF2YSBkaWRuJ3QgZGVzaWduIFN0cmluZyBhcyBhIGZpbmFsIHN1YmNsYXNzCi0gICAqIG9mIE11dGFibGVTdHJpbmcsIHJhdGhlciB0aGFuIGhhdmluZyBTdHJpbmdCdWZmZXIgYmUgYSBzZXBhcmF0ZSBoaWVyYXJjaHkuCi0gICAqIFdlJ2QgYXZvaWQgYSA8c3Ryb25nPmxvdDwvc3Ryb25nPiBvZiBkb3VibGUtYnVmZmVyaW5nLikKLSAgICoKLSAgICogQHJldHVybiB0aGUgY29udGVudHMgb2YgdGhlIEZhc3RTdHJpbmdCdWZmZXIgYXMgYSBzdGFuZGFyZCBKYXZhIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgdG9TdHJpbmcoKQotICB7Ci0KLSAgICBpbnQgbGVuZ3RoID0gKG1fbGFzdENodW5rIDw8IG1fY2h1bmtCaXRzKSArIG1fZmlyc3RGcmVlOwotCi0gICAgcmV0dXJuIGdldFN0cmluZyhuZXcgU3RyaW5nQnVmZmVyKGxlbmd0aCksIDAsIDAsIGxlbmd0aCkudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBzaW5nbGUgY2hhcmFjdGVyIG9udG8gdGhlIEZhc3RTdHJpbmdCdWZmZXIsIGdyb3dpbmcgdGhlCi0gICAqIHN0b3JhZ2UgaWYgbmVjZXNzYXJ5LgotICAgKiA8cD4KLSAgICogTk9URSBUSEFUIGFmdGVyIGNhbGxpbmcgYXBwZW5kKCksIHByZXZpb3VzbHkgb2J0YWluZWQKLSAgICogcmVmZXJlbmNlcyB0byBtX2FycmF5W11bXSBtYXkgbm8gbG9uZ2VyIGJlIHZhbGlkLi4uLgotICAgKiB0aG91Z2ggaW4gZmFjdCB0aGV5IHNob3VsZCBiZSBpbiB0aGlzIGluc3RhbmNlLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgY2hhcmFjdGVyIHRvIGJlIGFwcGVuZGVkLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgYXBwZW5kKGNoYXIgdmFsdWUpCi0gIHsKLQotICAgIGNoYXJbXSBjaHVuazsKLQotICAgIC8vIFdlIG1heSBoYXZlIHByZWFsbG9jYXRlZCBjaHVua3MuIElmIHNvLCBhbGwgYnV0IGxhc3Qgc2hvdWxkCi0gICAgLy8gYmUgYXQgZnVsbCBzaXplLgotICAgIGJvb2xlYW4gbGFzdGNodW5rID0gKG1fbGFzdENodW5rICsgMSA9PSBtX2FycmF5Lmxlbmd0aCk7Ci0KLSAgICBpZiAobV9maXJzdEZyZWUgPCBtX2NodW5rU2l6ZSkgIC8vIFNpbXBsaWZpZWQgdGVzdCBzaW5nbGUtY2hhcmFjdGVyLWZpdHMKLSAgICAgIGNodW5rID0gbV9hcnJheVttX2xhc3RDaHVua107Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gRXh0ZW5kIGFycmF5PwotICAgICAgaW50IGkgPSBtX2FycmF5Lmxlbmd0aDsKLQotICAgICAgaWYgKG1fbGFzdENodW5rICsgMSA9PSBpKQotICAgICAgewotICAgICAgICBjaGFyW11bXSBuZXdhcnJheSA9IG5ldyBjaGFyW2kgKyAxNl1bXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fYXJyYXksIDAsIG5ld2FycmF5LCAwLCBpKTsKLQotICAgICAgICBtX2FycmF5ID0gbmV3YXJyYXk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIEFkdmFuY2Ugb25lIGNodW5rCi0gICAgICBjaHVuayA9IG1fYXJyYXlbKyttX2xhc3RDaHVua107Ci0KLSAgICAgIGlmIChjaHVuayA9PSBudWxsKQotICAgICAgewotCi0gICAgICAgIC8vIEhpZXJhcmNoaWNhbCBlbmNhcHN1bGF0aW9uCi0gICAgICAgIGlmIChtX2xhc3RDaHVuayA9PSAxIDw8IG1fcmVidW5kbGVCaXRzCi0gICAgICAgICAgICAgICAgJiYgbV9jaHVua0JpdHMgPCBtX21heENodW5rQml0cykKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gU2hvdWxkIGRvIGFsbCB0aGUgd29yayBvZiBib3RoIGVuY2Fwc3VsYXRpbmcKLSAgICAgICAgICAvLyBleGlzdGluZyBkYXRhIGFuZCBlc3RhYmxpc2hpbmcgbmV3IHNpemVzL29mZnNldHMKLSAgICAgICAgICBtX2lubmVyRlNCID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIodGhpcyk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBZGQgYSBjaHVuay4KLSAgICAgICAgY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXSA9IG5ldyBjaGFyW21fY2h1bmtTaXplXTsKLSAgICAgIH0KLQotICAgICAgbV9maXJzdEZyZWUgPSAwOwotICAgIH0KLQotICAgIC8vIFNwYWNlIGV4aXN0cyBpbiB0aGUgY2h1bmsuIEFwcGVuZCB0aGUgY2hhcmFjdGVyLgotICAgIGNodW5rW21fZmlyc3RGcmVlKytdID0gdmFsdWU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHRoZSBjb250ZW50cyBvZiBhIFN0cmluZyBvbnRvIHRoZSBGYXN0U3RyaW5nQnVmZmVyLAotICAgKiBncm93aW5nIHRoZSBzdG9yYWdlIGlmIG5lY2Vzc2FyeS4KLSAgICogPHA+Ci0gICAqIE5PVEUgVEhBVCBhZnRlciBjYWxsaW5nIGFwcGVuZCgpLCBwcmV2aW91c2x5IG9idGFpbmVkCi0gICAqIHJlZmVyZW5jZXMgdG8gbV9hcnJheVtdIG1heSBubyBsb25nZXIgYmUgdmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBTdHJpbmcgd2hvc2UgY29udGVudHMgYXJlIHRvIGJlIGFwcGVuZGVkLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgYXBwZW5kKFN0cmluZyB2YWx1ZSkKLSAgewotCi0gICAgaW50IHN0cmxlbiA9IHZhbHVlLmxlbmd0aCgpOwotCi0gICAgaWYgKDAgPT0gc3RybGVuKQotICAgICAgcmV0dXJuOwotCi0gICAgaW50IGNvcHlmcm9tID0gMDsKLSAgICBjaGFyW10gY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXTsKLSAgICBpbnQgYXZhaWxhYmxlID0gbV9jaHVua1NpemUgLSBtX2ZpcnN0RnJlZTsKLQotICAgIC8vIFJlcGVhdCB3aGlsZSBkYXRhIHJlbWFpbnMgdG8gYmUgY29waWVkCi0gICAgd2hpbGUgKHN0cmxlbiA+IDApCi0gICAgewotCi0gICAgICAvLyBDb3B5IHdoYXQgZml0cwotICAgICAgaWYgKGF2YWlsYWJsZSA+IHN0cmxlbikKLSAgICAgICAgYXZhaWxhYmxlID0gc3RybGVuOwotCi0gICAgICB2YWx1ZS5nZXRDaGFycyhjb3B5ZnJvbSwgY29weWZyb20gKyBhdmFpbGFibGUsIG1fYXJyYXlbbV9sYXN0Q2h1bmtdLAotICAgICAgICAgICAgICAgICAgICAgbV9maXJzdEZyZWUpOwotCi0gICAgICBzdHJsZW4gLT0gYXZhaWxhYmxlOwotICAgICAgY29weWZyb20gKz0gYXZhaWxhYmxlOwotCi0gICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgbGVmdCwgYWxsb2NhdGUgYW5vdGhlciBjaHVuayBhbmQgY29udGludWUKLSAgICAgIGlmIChzdHJsZW4gPiAwKQotICAgICAgewotCi0gICAgICAgIC8vIEV4dGVuZCBhcnJheT8KLSAgICAgICAgaW50IGkgPSBtX2FycmF5Lmxlbmd0aDsKLQotICAgICAgICBpZiAobV9sYXN0Q2h1bmsgKyAxID09IGkpCi0gICAgICAgIHsKLSAgICAgICAgICBjaGFyW11bXSBuZXdhcnJheSA9IG5ldyBjaGFyW2kgKyAxNl1bXTsKLQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hcnJheSwgMCwgbmV3YXJyYXksIDAsIGkpOwotCi0gICAgICAgICAgbV9hcnJheSA9IG5ld2FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWR2YW5jZSBvbmUgY2h1bmsKLSAgICAgICAgY2h1bmsgPSBtX2FycmF5WysrbV9sYXN0Q2h1bmtdOwotCi0gICAgICAgIGlmIChjaHVuayA9PSBudWxsKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBIaWVyYXJjaGljYWwgZW5jYXBzdWxhdGlvbgotICAgICAgICAgIGlmIChtX2xhc3RDaHVuayA9PSAxIDw8IG1fcmVidW5kbGVCaXRzCi0gICAgICAgICAgICAgICAgICAmJiBtX2NodW5rQml0cyA8IG1fbWF4Q2h1bmtCaXRzKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gU2hvdWxkIGRvIGFsbCB0aGUgd29yayBvZiBib3RoIGVuY2Fwc3VsYXRpbmcKLSAgICAgICAgICAgIC8vIGV4aXN0aW5nIGRhdGEgYW5kIGVzdGFibGlzaGluZyBuZXcgc2l6ZXMvb2Zmc2V0cwotICAgICAgICAgICAgbV9pbm5lckZTQiA9IG5ldyBGYXN0U3RyaW5nQnVmZmVyKHRoaXMpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIEFkZCBhIGNodW5rLiAKLSAgICAgICAgICBjaHVuayA9IG1fYXJyYXlbbV9sYXN0Q2h1bmtdID0gbmV3IGNoYXJbbV9jaHVua1NpemVdOwotICAgICAgICB9Ci0KLSAgICAgICAgYXZhaWxhYmxlID0gbV9jaHVua1NpemU7Ci0gICAgICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBBZGp1c3QgdGhlIGluc2VydCBwb2ludCBpbiB0aGUgbGFzdCBjaHVuaywgd2hlbiB3ZSd2ZSByZWFjaGVkIGl0LgotICAgIG1fZmlyc3RGcmVlICs9IGF2YWlsYWJsZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgdGhlIGNvbnRlbnRzIG9mIGEgU3RyaW5nQnVmZmVyIG9udG8gdGhlIEZhc3RTdHJpbmdCdWZmZXIsCi0gICAqIGdyb3dpbmcgdGhlIHN0b3JhZ2UgaWYgbmVjZXNzYXJ5LgotICAgKiA8cD4KLSAgICogTk9URSBUSEFUIGFmdGVyIGNhbGxpbmcgYXBwZW5kKCksIHByZXZpb3VzbHkgb2J0YWluZWQKLSAgICogcmVmZXJlbmNlcyB0byBtX2FycmF5W10gbWF5IG5vIGxvbmdlciBiZSB2YWxpZC4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIFN0cmluZ0J1ZmZlciB3aG9zZSBjb250ZW50cyBhcmUgdG8gYmUgYXBwZW5kZWQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhcHBlbmQoU3RyaW5nQnVmZmVyIHZhbHVlKQotICB7Ci0KLSAgICBpbnQgc3RybGVuID0gdmFsdWUubGVuZ3RoKCk7Ci0KLSAgICBpZiAoMCA9PSBzdHJsZW4pCi0gICAgICByZXR1cm47Ci0KLSAgICBpbnQgY29weWZyb20gPSAwOwotICAgIGNoYXJbXSBjaHVuayA9IG1fYXJyYXlbbV9sYXN0Q2h1bmtdOwotICAgIGludCBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZSAtIG1fZmlyc3RGcmVlOwotCi0gICAgLy8gUmVwZWF0IHdoaWxlIGRhdGEgcmVtYWlucyB0byBiZSBjb3BpZWQKLSAgICB3aGlsZSAoc3RybGVuID4gMCkKLSAgICB7Ci0KLSAgICAgIC8vIENvcHkgd2hhdCBmaXRzCi0gICAgICBpZiAoYXZhaWxhYmxlID4gc3RybGVuKQotICAgICAgICBhdmFpbGFibGUgPSBzdHJsZW47Ci0KLSAgICAgIHZhbHVlLmdldENoYXJzKGNvcHlmcm9tLCBjb3B5ZnJvbSArIGF2YWlsYWJsZSwgbV9hcnJheVttX2xhc3RDaHVua10sCi0gICAgICAgICAgICAgICAgICAgICBtX2ZpcnN0RnJlZSk7Ci0KLSAgICAgIHN0cmxlbiAtPSBhdmFpbGFibGU7Ci0gICAgICBjb3B5ZnJvbSArPSBhdmFpbGFibGU7Ci0KLSAgICAgIC8vIElmIHRoZXJlJ3MgbW9yZSBsZWZ0LCBhbGxvY2F0ZSBhbm90aGVyIGNodW5rIGFuZCBjb250aW51ZQotICAgICAgaWYgKHN0cmxlbiA+IDApCi0gICAgICB7Ci0KLSAgICAgICAgLy8gRXh0ZW5kIGFycmF5PwotICAgICAgICBpbnQgaSA9IG1fYXJyYXkubGVuZ3RoOwotCi0gICAgICAgIGlmIChtX2xhc3RDaHVuayArIDEgPT0gaSkKLSAgICAgICAgewotICAgICAgICAgIGNoYXJbXVtdIG5ld2FycmF5ID0gbmV3IGNoYXJbaSArIDE2XVtdOwotCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX2FycmF5LCAwLCBuZXdhcnJheSwgMCwgaSk7Ci0KLSAgICAgICAgICBtX2FycmF5ID0gbmV3YXJyYXk7Ci0gICAgICAgIH0KLQotICAgICAgICAvLyBBZHZhbmNlIG9uZSBjaHVuawotICAgICAgICBjaHVuayA9IG1fYXJyYXlbKyttX2xhc3RDaHVua107Ci0KLSAgICAgICAgaWYgKGNodW5rID09IG51bGwpCi0gICAgICAgIHsKLQotICAgICAgICAgIC8vIEhpZXJhcmNoaWNhbCBlbmNhcHN1bGF0aW9uCi0gICAgICAgICAgaWYgKG1fbGFzdENodW5rID09IDEgPDwgbV9yZWJ1bmRsZUJpdHMKLSAgICAgICAgICAgICAgICAgICYmIG1fY2h1bmtCaXRzIDwgbV9tYXhDaHVua0JpdHMpCi0gICAgICAgICAgewotCi0gICAgICAgICAgICAvLyBTaG91bGQgZG8gYWxsIHRoZSB3b3JrIG9mIGJvdGggZW5jYXBzdWxhdGluZwotICAgICAgICAgICAgLy8gZXhpc3RpbmcgZGF0YSBhbmQgZXN0YWJsaXNoaW5nIG5ldyBzaXplcy9vZmZzZXRzCi0gICAgICAgICAgICBtX2lubmVyRlNCID0gbmV3IEZhc3RTdHJpbmdCdWZmZXIodGhpcyk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgLy8gQWRkIGEgY2h1bmsuCi0gICAgICAgICAgY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXSA9IG5ldyBjaGFyW21fY2h1bmtTaXplXTsKLSAgICAgICAgfQotCi0gICAgICAgIGF2YWlsYWJsZSA9IG1fY2h1bmtTaXplOwotICAgICAgICBtX2ZpcnN0RnJlZSA9IDA7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gQWRqdXN0IHRoZSBpbnNlcnQgcG9pbnQgaW4gdGhlIGxhc3QgY2h1bmssIHdoZW4gd2UndmUgcmVhY2hlZCBpdC4KLSAgICBtX2ZpcnN0RnJlZSArPSBhdmFpbGFibGU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHBhcnQgb2YgdGhlIGNvbnRlbnRzIG9mIGEgQ2hhcmFjdGVyIEFycmF5IG9udG8gdGhlCi0gICAqIEZhc3RTdHJpbmdCdWZmZXIsICBncm93aW5nIHRoZSBzdG9yYWdlIGlmIG5lY2Vzc2FyeS4KLSAgICogPHA+Ci0gICAqIE5PVEUgVEhBVCBhZnRlciBjYWxsaW5nIGFwcGVuZCgpLCBwcmV2aW91c2x5IG9idGFpbmVkCi0gICAqIHJlZmVyZW5jZXMgdG8gbV9hcnJheVtdIG1heSBubyBsb25nZXIgYmUgdmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSBjaGFycyBjaGFyYWN0ZXIgYXJyYXkgZnJvbSB3aGljaCBkYXRhIGlzIHRvIGJlIGNvcGllZAotICAgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IGluIGNoYXJzIG9mIGZpcnN0IGNoYXJhY3RlciB0byBiZSBjb3BpZWQsCi0gICAqIHplcm8tYmFzZWQuCi0gICAqIEBwYXJhbSBsZW5ndGggbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgY29waWVkCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhcHBlbmQoY2hhcltdIGNoYXJzLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gIHsKLQotICAgIGludCBzdHJsZW4gPSBsZW5ndGg7Ci0KLSAgICBpZiAoMCA9PSBzdHJsZW4pCi0gICAgICByZXR1cm47Ci0KLSAgICBpbnQgY29weWZyb20gPSBzdGFydDsKLSAgICBjaGFyW10gY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXTsKLSAgICBpbnQgYXZhaWxhYmxlID0gbV9jaHVua1NpemUgLSBtX2ZpcnN0RnJlZTsKLQotICAgIC8vIFJlcGVhdCB3aGlsZSBkYXRhIHJlbWFpbnMgdG8gYmUgY29waWVkCi0gICAgd2hpbGUgKHN0cmxlbiA+IDApCi0gICAgewotCi0gICAgICAvLyBDb3B5IHdoYXQgZml0cwotICAgICAgaWYgKGF2YWlsYWJsZSA+IHN0cmxlbikKLSAgICAgICAgYXZhaWxhYmxlID0gc3RybGVuOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KGNoYXJzLCBjb3B5ZnJvbSwgbV9hcnJheVttX2xhc3RDaHVua10sIG1fZmlyc3RGcmVlLAotICAgICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUpOwotCi0gICAgICBzdHJsZW4gLT0gYXZhaWxhYmxlOwotICAgICAgY29weWZyb20gKz0gYXZhaWxhYmxlOwotCi0gICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgbGVmdCwgYWxsb2NhdGUgYW5vdGhlciBjaHVuayBhbmQgY29udGludWUKLSAgICAgIGlmIChzdHJsZW4gPiAwKQotICAgICAgewotCi0gICAgICAgIC8vIEV4dGVuZCBhcnJheT8KLSAgICAgICAgaW50IGkgPSBtX2FycmF5Lmxlbmd0aDsKLQotICAgICAgICBpZiAobV9sYXN0Q2h1bmsgKyAxID09IGkpCi0gICAgICAgIHsKLSAgICAgICAgICBjaGFyW11bXSBuZXdhcnJheSA9IG5ldyBjaGFyW2kgKyAxNl1bXTsKLQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hcnJheSwgMCwgbmV3YXJyYXksIDAsIGkpOwotCi0gICAgICAgICAgbV9hcnJheSA9IG5ld2FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWR2YW5jZSBvbmUgY2h1bmsKLSAgICAgICAgY2h1bmsgPSBtX2FycmF5WysrbV9sYXN0Q2h1bmtdOwotCi0gICAgICAgIGlmIChjaHVuayA9PSBudWxsKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBIaWVyYXJjaGljYWwgZW5jYXBzdWxhdGlvbgotICAgICAgICAgIGlmIChtX2xhc3RDaHVuayA9PSAxIDw8IG1fcmVidW5kbGVCaXRzCi0gICAgICAgICAgICAgICAgICAmJiBtX2NodW5rQml0cyA8IG1fbWF4Q2h1bmtCaXRzKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gU2hvdWxkIGRvIGFsbCB0aGUgd29yayBvZiBib3RoIGVuY2Fwc3VsYXRpbmcKLSAgICAgICAgICAgIC8vIGV4aXN0aW5nIGRhdGEgYW5kIGVzdGFibGlzaGluZyBuZXcgc2l6ZXMvb2Zmc2V0cwotICAgICAgICAgICAgbV9pbm5lckZTQiA9IG5ldyBGYXN0U3RyaW5nQnVmZmVyKHRoaXMpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIEFkZCBhIGNodW5rLgotICAgICAgICAgIGNodW5rID0gbV9hcnJheVttX2xhc3RDaHVua10gPSBuZXcgY2hhclttX2NodW5rU2l6ZV07Ci0gICAgICAgIH0KLQotICAgICAgICBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZTsKLSAgICAgICAgbV9maXJzdEZyZWUgPSAwOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIEFkanVzdCB0aGUgaW5zZXJ0IHBvaW50IGluIHRoZSBsYXN0IGNodW5rLCB3aGVuIHdlJ3ZlIHJlYWNoZWQgaXQuCi0gICAgbV9maXJzdEZyZWUgKz0gYXZhaWxhYmxlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0aGUgY29udGVudHMgb2YgYW5vdGhlciBGYXN0U3RyaW5nQnVmZmVyIG9udG8KLSAgICogdGhpcyBGYXN0U3RyaW5nQnVmZmVyLCBncm93aW5nIHRoZSBzdG9yYWdlIGlmIG5lY2Vzc2FyeS4KLSAgICogPHA+Ci0gICAqIE5PVEUgVEhBVCBhZnRlciBjYWxsaW5nIGFwcGVuZCgpLCBwcmV2aW91c2x5IG9idGFpbmVkCi0gICAqIHJlZmVyZW5jZXMgdG8gbV9hcnJheVtdIG1heSBubyBsb25nZXIgYmUgdmFsaWQuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBGYXN0U3RyaW5nQnVmZmVyIHdob3NlIGNvbnRlbnRzIGFyZQotICAgKiB0byBiZSBhcHBlbmRlZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFwcGVuZChGYXN0U3RyaW5nQnVmZmVyIHZhbHVlKQotICB7Ci0KLSAgICAvLyBDb21wbGljYXRpbmcgZmFjdG9yIGhlcmUgaXMgdGhhdCB0aGUgdHdvIGJ1ZmZlcnMgbWF5IHVzZQotICAgIC8vIGRpZmZlcmVudCBjaHVuayBzaXplcywgYW5kIGV2ZW4gaWYgdGhleSdyZSB0aGUgc2FtZSB3ZSdyZQotICAgIC8vIHByb2JhYmx5IG9uIGEgZGlmZmVyZW50IGFsaWdubWVudCBkdWUgdG8gcHJldmlvdXNseSBhcHBlbmRlZAotICAgIC8vIGRhdGEuIFdlIGhhdmUgdG8gd29yayB0aHJvdWdoIHRoZSBzb3VyY2UgaW4gYml0ZS1zaXplZCBjaHVua3MuCi0gICAgaW50IHN0cmxlbiA9IHZhbHVlLmxlbmd0aCgpOwotCi0gICAgaWYgKDAgPT0gc3RybGVuKQotICAgICAgcmV0dXJuOwotCi0gICAgaW50IGNvcHlmcm9tID0gMDsKLSAgICBjaGFyW10gY2h1bmsgPSBtX2FycmF5W21fbGFzdENodW5rXTsKLSAgICBpbnQgYXZhaWxhYmxlID0gbV9jaHVua1NpemUgLSBtX2ZpcnN0RnJlZTsKLQotICAgIC8vIFJlcGVhdCB3aGlsZSBkYXRhIHJlbWFpbnMgdG8gYmUgY29waWVkCi0gICAgd2hpbGUgKHN0cmxlbiA+IDApCi0gICAgewotCi0gICAgICAvLyBDb3B5IHdoYXQgZml0cwotICAgICAgaWYgKGF2YWlsYWJsZSA+IHN0cmxlbikKLSAgICAgICAgYXZhaWxhYmxlID0gc3RybGVuOwotCi0gICAgICBpbnQgc291cmNlY2h1bmsgPSAoY29weWZyb20gKyB2YWx1ZS5tX2NodW5rU2l6ZSAtIDEpCi0gICAgICAgICAgICAgICAgICAgICAgICA+Pj4gdmFsdWUubV9jaHVua0JpdHM7Ci0gICAgICBpbnQgc291cmNlY29sdW1uID0gY29weWZyb20gJiB2YWx1ZS5tX2NodW5rTWFzazsKLSAgICAgIGludCBydW5sZW5ndGggPSB2YWx1ZS5tX2NodW5rU2l6ZSAtIHNvdXJjZWNvbHVtbjsKLQotICAgICAgaWYgKHJ1bmxlbmd0aCA+IGF2YWlsYWJsZSkKLSAgICAgICAgcnVubGVuZ3RoID0gYXZhaWxhYmxlOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLm1fYXJyYXlbc291cmNlY2h1bmtdLCBzb3VyY2Vjb2x1bW4sCi0gICAgICAgICAgICAgICAgICAgICAgIG1fYXJyYXlbbV9sYXN0Q2h1bmtdLCBtX2ZpcnN0RnJlZSwgcnVubGVuZ3RoKTsKLQotICAgICAgaWYgKHJ1bmxlbmd0aCAhPSBhdmFpbGFibGUpCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsdWUubV9hcnJheVtzb3VyY2VjaHVuayArIDFdLCAwLAotICAgICAgICAgICAgICAgICAgICAgICAgIG1fYXJyYXlbbV9sYXN0Q2h1bmtdLCBtX2ZpcnN0RnJlZSArIHJ1bmxlbmd0aCwKLSAgICAgICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGUgLSBydW5sZW5ndGgpOwotCi0gICAgICBzdHJsZW4gLT0gYXZhaWxhYmxlOwotICAgICAgY29weWZyb20gKz0gYXZhaWxhYmxlOwotCi0gICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgbGVmdCwgYWxsb2NhdGUgYW5vdGhlciBjaHVuayBhbmQgY29udGludWUKLSAgICAgIGlmIChzdHJsZW4gPiAwKQotICAgICAgewotCi0gICAgICAgIC8vIEV4dGVuZCBhcnJheT8KLSAgICAgICAgaW50IGkgPSBtX2FycmF5Lmxlbmd0aDsKLQotICAgICAgICBpZiAobV9sYXN0Q2h1bmsgKyAxID09IGkpCi0gICAgICAgIHsKLSAgICAgICAgICBjaGFyW11bXSBuZXdhcnJheSA9IG5ldyBjaGFyW2kgKyAxNl1bXTsKLQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9hcnJheSwgMCwgbmV3YXJyYXksIDAsIGkpOwotCi0gICAgICAgICAgbV9hcnJheSA9IG5ld2FycmF5OwotICAgICAgICB9Ci0KLSAgICAgICAgLy8gQWR2YW5jZSBvbmUgY2h1bmsKLSAgICAgICAgY2h1bmsgPSBtX2FycmF5WysrbV9sYXN0Q2h1bmtdOwotCi0gICAgICAgIGlmIChjaHVuayA9PSBudWxsKQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBIaWVyYXJjaGljYWwgZW5jYXBzdWxhdGlvbgotICAgICAgICAgIGlmIChtX2xhc3RDaHVuayA9PSAxIDw8IG1fcmVidW5kbGVCaXRzCi0gICAgICAgICAgICAgICAgICAmJiBtX2NodW5rQml0cyA8IG1fbWF4Q2h1bmtCaXRzKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gU2hvdWxkIGRvIGFsbCB0aGUgd29yayBvZiBib3RoIGVuY2Fwc3VsYXRpbmcKLSAgICAgICAgICAgIC8vIGV4aXN0aW5nIGRhdGEgYW5kIGVzdGFibGlzaGluZyBuZXcgc2l6ZXMvb2Zmc2V0cwotICAgICAgICAgICAgbV9pbm5lckZTQiA9IG5ldyBGYXN0U3RyaW5nQnVmZmVyKHRoaXMpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIEFkZCBhIGNodW5rLiAKLSAgICAgICAgICBjaHVuayA9IG1fYXJyYXlbbV9sYXN0Q2h1bmtdID0gbmV3IGNoYXJbbV9jaHVua1NpemVdOwotICAgICAgICB9Ci0KLSAgICAgICAgYXZhaWxhYmxlID0gbV9jaHVua1NpemU7Ci0gICAgICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBBZGp1c3QgdGhlIGluc2VydCBwb2ludCBpbiB0aGUgbGFzdCBjaHVuaywgd2hlbiB3ZSd2ZSByZWFjaGVkIGl0LgotICAgIG1fZmlyc3RGcmVlICs9IGF2YWlsYWJsZTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCByYW5nZSBvZiBjaGFyYWN0ZXJzIGFyZSBhbGwgd2hpdGVzcGFjZSwKLSAgICogYXMgZGVmaW5lZCBieSBYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLgotICAgKiA8cD4KLSAgICogQ1VSUkVOVExZIERPRVMgTk9UIENIRUNLIEZPUiBPVVQtT0YtUkFOR0UuCi0gICAqCi0gICAqIEBwYXJhbSBzdGFydCBPZmZzZXQgb2YgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZS4KLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzZW5kLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNXaGl0ZXNwYWNlKGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotCi0gICAgaW50IHNvdXJjZWNodW5rID0gc3RhcnQgPj4+IG1fY2h1bmtCaXRzOwotICAgIGludCBzb3VyY2Vjb2x1bW4gPSBzdGFydCAmIG1fY2h1bmtNYXNrOwotICAgIGludCBhdmFpbGFibGUgPSBtX2NodW5rU2l6ZSAtIHNvdXJjZWNvbHVtbjsKLSAgICBib29sZWFuIGNodW5rT0s7Ci0KLSAgICB3aGlsZSAobGVuZ3RoID4gMCkKLSAgICB7Ci0gICAgICBpbnQgcnVubGVuZ3RoID0gKGxlbmd0aCA8PSBhdmFpbGFibGUpID8gbGVuZ3RoIDogYXZhaWxhYmxlOwotCi0gICAgICBpZiAoc291cmNlY2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICAgIGNodW5rT0sgPSBtX2lubmVyRlNCLmlzV2hpdGVzcGFjZShzb3VyY2Vjb2x1bW4sIHJ1bmxlbmd0aCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNodW5rT0sgPSBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZSgKLSAgICAgICAgICBtX2FycmF5W3NvdXJjZWNodW5rXSwgc291cmNlY29sdW1uLCBydW5sZW5ndGgpOwotCi0gICAgICBpZiAoIWNodW5rT0spCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgbGVuZ3RoIC09IHJ1bmxlbmd0aDsKLQotICAgICAgKytzb3VyY2VjaHVuazsKLQotICAgICAgc291cmNlY29sdW1uID0gMDsKLSAgICAgIGF2YWlsYWJsZSA9IG1fY2h1bmtTaXplOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzdGFydCBPZmZzZXQgb2YgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZS4KLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzZW5kLgotICAgKiBAcmV0dXJuIGEgbmV3IFN0cmluZyBvYmplY3QgaW5pdGlhbGl6ZWQgZnJvbSB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mCi0gICAqIGNoYXJhY3RlcnMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN0cmluZyhpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gIHsKLSAgICByZXR1cm4gZ2V0U3RyaW5nKG5ldyBTdHJpbmdCdWZmZXIobGVuZ3RoKSwgc3RhcnQgPj4+IG1fY2h1bmtCaXRzLAotICAgICAgICAgICAgICAgICAgICAgc3RhcnQgJiBtX2NodW5rTWFzaywgbGVuZ3RoKS50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEBwYXJhbSBzYiBTdHJpbmdCdWZmZXIgdG8gYmUgYXBwZW5kZWQgdG8KLSAgICogQHBhcmFtIHN0YXJ0IE9mZnNldCBvZiBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHJhbmdlLgotICAgKiBAcGFyYW0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNlbmQuCi0gICAqIEByZXR1cm4gc2Igd2l0aCB0aGUgcmVxdWVzdGVkIHRleHQgYXBwZW5kZWQgdG8gaXQKLSAgICovCi0gIFN0cmluZ0J1ZmZlciBnZXRTdHJpbmcoU3RyaW5nQnVmZmVyIHNiLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gIHsKLSAgICByZXR1cm4gZ2V0U3RyaW5nKHNiLCBzdGFydCA+Pj4gbV9jaHVua0JpdHMsIHN0YXJ0ICYgbV9jaHVua01hc2ssIGxlbmd0aCk7Ci0gIH0KLQotICAvKioKLSAgICogSW50ZXJuYWwgc3VwcG9ydCBmb3IgdG9TdHJpbmcoKSBhbmQgZ2V0U3RyaW5nKCkuCi0gICAqIFBMRUFTRSBOT1RFIFNJR05BVFVSRSBDSEFOR0UgZnJvbSBlYXJsaWVyIHZlcnNpb25zOyBpdCBub3cgYXBwZW5kcyBpbnRvCi0gICAqIGFuZCByZXR1cm5zIGEgU3RyaW5nQnVmZmVyIHN1cHBsaWVkIGJ5IHRoZSBjYWxsZXIuIFRoaXMgc2ltcGxpZmllcwotICAgKiBtX2lubmVyRlNCIHN1cHBvcnQuCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgdGhpcyBvcGVyYXRpb24gaGFzIGJlZW4gc29tZXdoYXQgZGVvcHRpbWl6ZWQgYnkgdGhlIHNoaWZ0IHRvIGEKLSAgICogY2h1bmtlZCBhcnJheSwgYXMgdGhlcmUgaXMgbm8gZmFjdG9yeSBtZXRob2QgdG8gcHJvZHVjZSBhIFN0cmluZyBvYmplY3QKLSAgICogZGlyZWN0bHkgZnJvbSBhbiBhcnJheSBvZiBhcnJheXMgYW5kIGhlbmNlIGEgZG91YmxlIGNvcHkgaXMgbmVlZGVkLgotICAgKiBCeSBwcmVzZXR0aW5nIGxlbmd0aCB3ZSBob3BlIHRvIG1pbmltaXplIHRoZSBoZWFwIG92ZXJoZWFkIG9mIGJ1aWxkaW5nCi0gICAqIHRoZSBpbnRlcm1lZGlhdGUgU3RyaW5nQnVmZmVyLgotICAgKiA8cD4KLSAgICogKEl0IHJlYWxseSBpcyBhIHBpdHkgdGhhdCBKYXZhIGRpZG4ndCBkZXNpZ24gU3RyaW5nIGFzIGEgZmluYWwgc3ViY2xhc3MKLSAgICogb2YgTXV0YWJsZVN0cmluZywgcmF0aGVyIHRoYW4gaGF2aW5nIFN0cmluZ0J1ZmZlciBiZSBhIHNlcGFyYXRlIGhpZXJhcmNoeS4KLSAgICogV2UnZCBhdm9pZCBhIDxzdHJvbmc+bG90PC9zdHJvbmc+IG9mIGRvdWJsZS1idWZmZXJpbmcuKQotICAgKgotICAgKgotICAgKiBAcGFyYW0gc2IKLSAgICogQHBhcmFtIHN0YXJ0Q2h1bmsKLSAgICogQHBhcmFtIHN0YXJ0Q29sdW1uCi0gICAqIEBwYXJhbSBsZW5ndGgKLSAgICogCi0gICAqIEByZXR1cm4gdGhlIGNvbnRlbnRzIG9mIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGFzIGEgc3RhbmRhcmQgSmF2YSBzdHJpbmcuCi0gICAqLwotICBTdHJpbmdCdWZmZXIgZ2V0U3RyaW5nKFN0cmluZ0J1ZmZlciBzYiwgaW50IHN0YXJ0Q2h1bmssIGludCBzdGFydENvbHVtbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoKQotICB7Ci0KLSAgICBpbnQgc3RvcCA9IChzdGFydENodW5rIDw8IG1fY2h1bmtCaXRzKSArIHN0YXJ0Q29sdW1uICsgbGVuZ3RoOwotICAgIGludCBzdG9wQ2h1bmsgPSBzdG9wID4+PiBtX2NodW5rQml0czsKLSAgICBpbnQgc3RvcENvbHVtbiA9IHN0b3AgJiBtX2NodW5rTWFzazsKLQotICAgIC8vIEZhY3RvcmVkIG91dAotICAgIC8vU3RyaW5nQnVmZmVyIHNiPW5ldyBTdHJpbmdCdWZmZXIobGVuZ3RoKTsKLSAgICBmb3IgKGludCBpID0gc3RhcnRDaHVuazsgaSA8IHN0b3BDaHVuazsgKytpKQotICAgIHsKLSAgICAgIGlmIChpID09IDAgJiYgbV9pbm5lckZTQiAhPSBudWxsKQotICAgICAgICBtX2lubmVyRlNCLmdldFN0cmluZyhzYiwgc3RhcnRDb2x1bW4sIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotICAgICAgZWxzZQotICAgICAgICBzYi5hcHBlbmQobV9hcnJheVtpXSwgc3RhcnRDb2x1bW4sIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotCi0gICAgICBzdGFydENvbHVtbiA9IDA7ICAvLyBhZnRlciBmaXJzdCBjaHVuawotICAgIH0KLQotICAgIGlmIChzdG9wQ2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICBtX2lubmVyRlNCLmdldFN0cmluZyhzYiwgc3RhcnRDb2x1bW4sIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0gICAgZWxzZSBpZiAoc3RvcENvbHVtbiA+IHN0YXJ0Q29sdW1uKQotICAgICAgc2IuYXBwZW5kKG1fYXJyYXlbc3RvcENodW5rXSwgc3RhcnRDb2x1bW4sIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0KLSAgICByZXR1cm4gc2I7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgc2luZ2xlIGNoYXJhY3RlciBmcm9tIHRoZSBzdHJpbmcgYnVmZmVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcG9zIGNoYXJhY3RlciBwb3NpdGlvbiByZXF1ZXN0ZWQuCi0gICAqIEByZXR1cm4gQSBjaGFyYWN0ZXIgZnJvbSB0aGUgcmVxdWVzdGVkIHBvc2l0aW9uLgotICAgKi8KLSAgcHVibGljIGNoYXIgY2hhckF0KGludCBwb3MpCi0gIHsKLSAgICBpbnQgc3RhcnRDaHVuayA9IHBvcyA+Pj4gbV9jaHVua0JpdHM7Ci0KLSAgICBpZiAoc3RhcnRDaHVuayA9PSAwICYmIG1faW5uZXJGU0IgIT0gbnVsbCkKLSAgICAgIHJldHVybiBtX2lubmVyRlNCLmNoYXJBdChwb3MgJiBtX2NodW5rTWFzayk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG1fYXJyYXlbc3RhcnRDaHVua11bcG9zICYgbV9jaHVua01hc2tdOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlbmRzIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgY2hhcmFjdGVycyBhcyBvbmUgb3IgbW9yZSBTQVggY2hhcmFjdGVycygpCi0gICAqIGV2ZW50cy4KLSAgICogTm90ZSB0aGF0IHRoZSBidWZmZXIgcmVmZXJlbmNlIHBhc3NlZCB0byB0aGUgQ29udGVudEhhbmRsZXIgbWF5IGJlCi0gICAqIGludmFsaWRhdGVkIGlmIHRoZSBGYXN0U3RyaW5nQnVmZmVyIGlzIGVkaXRlZDsgaXQncyB0aGUgdXNlcidzCi0gICAqIHJlc3BvbnNpYmlsaXR5IHRvIG1hbmFnZSBhY2Nlc3MgdG8gdGhlIEZhc3RTdHJpbmdCdWZmZXIgdG8gcHJldmVudCB0aGlzCi0gICAqIHByb2JsZW0gZnJvbSBhcmlzaW5nLgotICAgKiA8cD4KLSAgICogTm90ZSB0b28gdGhhdCB0aGVyZSBpcyBubyBwcm9taXNlIHRoYXQgdGhlIG91dHB1dCB3aWxsIGJlIHNlbnQgYXMgYQotICAgKiBzaW5nbGUgY2FsbC4gQXMgaXMgYWx3YXlzIHRydWUgaW4gU0FYLCBvbmUgbG9naWNhbCBzdHJpbmcgbWF5IGJlIHNwbGl0Ci0gICAqIGFjcm9zcyBtdWx0aXBsZSBibG9ja3Mgb2YgbWVtb3J5IGFuZCBoZW5jZSBkZWxpdmVyZWQgYXMgc2V2ZXJhbAotICAgKiBzdWNjZXNzaXZlIGV2ZW50cy4KLSAgICoKLSAgICogQHBhcmFtIGNoIFNBWCBDb250ZW50SGFuZGxlciBvYmplY3QgdG8gcmVjZWl2ZSB0aGUgZXZlbnQuCi0gICAqIEBwYXJhbSBzdGFydCBPZmZzZXQgb2YgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZS4KLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzZW5kLgotICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGJ5IGhhbmRsZXIncwotICAgKiBjaGFyYWN0ZXJzKCkgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2VuZFNBWGNoYXJhY3RlcnMoCi0gICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHN0b3AgPSBzdGFydCArIGxlbmd0aDsKLSAgICBpbnQgc3RhcnRDaHVuayA9IHN0YXJ0ID4+PiBtX2NodW5rQml0czsKLSAgICBpbnQgc3RhcnRDb2x1bW4gPSBzdGFydCAmIG1fY2h1bmtNYXNrOwotICAgIGludCBzdG9wQ2h1bmsgPSBzdG9wID4+PiBtX2NodW5rQml0czsKLSAgICBpbnQgc3RvcENvbHVtbiA9IHN0b3AgJiBtX2NodW5rTWFzazsKLQotICAgIGZvciAoaW50IGkgPSBzdGFydENodW5rOyBpIDwgc3RvcENodW5rOyArK2kpCi0gICAgewotICAgICAgaWYgKGkgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICAgIG1faW5uZXJGU0Iuc2VuZFNBWGNoYXJhY3RlcnMoY2gsIHN0YXJ0Q29sdW1uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4pOwotICAgICAgZWxzZQotICAgICAgICBjaC5jaGFyYWN0ZXJzKG1fYXJyYXlbaV0sIHN0YXJ0Q29sdW1uLCBtX2NodW5rU2l6ZSAtIHN0YXJ0Q29sdW1uKTsKLQotICAgICAgc3RhcnRDb2x1bW4gPSAwOyAgLy8gYWZ0ZXIgZmlyc3QgY2h1bmsKLSAgICB9Ci0KLSAgICAvLyBMYXN0LCBvciBvbmx5LCBjaHVuawotICAgIGlmIChzdG9wQ2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICBtX2lubmVyRlNCLnNlbmRTQVhjaGFyYWN0ZXJzKGNoLCBzdGFydENvbHVtbiwgc3RvcENvbHVtbiAtIHN0YXJ0Q29sdW1uKTsKLSAgICBlbHNlIGlmIChzdG9wQ29sdW1uID4gc3RhcnRDb2x1bW4pCi0gICAgICBjaC5jaGFyYWN0ZXJzKG1fYXJyYXlbc3RvcENodW5rXSwgc3RhcnRDb2x1bW4sCi0gICAgICAgICAgICAgICAgICAgIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZW5kcyB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIGNoYXJhY3RlcnMgYXMgb25lIG9yIG1vcmUgU0FYIGNoYXJhY3RlcnMoKQotICAgKiBldmVudHMsIG5vcm1hbGl6aW5nIHRoZSBjaGFyYWN0ZXJzIGFjY29yZGluZyB0byBYU0xUIHJ1bGVzLgotICAgKgotICAgKiBAcGFyYW0gY2ggU0FYIENvbnRlbnRIYW5kbGVyIG9iamVjdCB0byByZWNlaXZlIHRoZSBldmVudC4KLSAgICogQHBhcmFtIHN0YXJ0IE9mZnNldCBvZiBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHJhbmdlLgotICAgKiBAcGFyYW0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNlbmQuCi0gICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIG1heSBiZSB0aHJvd24gYnkgaGFuZGxlcidzCi0gICAqIGNoYXJhY3RlcnMoKSBtZXRob2QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZW5kTm9ybWFsaXplZFNBWGNoYXJhY3RlcnMoCi0gICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICAgICAgICAgIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHN0b3AgPSBzdGFydCArIGxlbmd0aDsKLSAgICBpbnQgc3RhcnRDaHVuayA9IHN0YXJ0ID4+PiBtX2NodW5rQml0czsKLSAgICBpbnQgc3RhcnRDb2x1bW4gPSBzdGFydCAmIG1fY2h1bmtNYXNrOwotICAgIGludCBzdG9wQ2h1bmsgPSBzdG9wID4+PiBtX2NodW5rQml0czsKLSAgICBpbnQgc3RvcENvbHVtbiA9IHN0b3AgJiBtX2NodW5rTWFzazsKLQotICAgIGZvciAoaW50IGkgPSBzdGFydENodW5rOyBpIDwgc3RvcENodW5rOyArK2kpCi0gICAgewotICAgICAgaWYgKGkgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICAgIG1faW5uZXJGU0Iuc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKGNoLCBzdGFydENvbHVtbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2NodW5rU2l6ZSAtIHN0YXJ0Q29sdW1uKTsKLSAgICAgIGVsc2UKLSAgICAgICAgc2VuZE5vcm1hbGl6ZWRTQVhjaGFyYWN0ZXJzKG1fYXJyYXlbaV0sIHN0YXJ0Q29sdW1uLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2h1bmtTaXplIC0gc3RhcnRDb2x1bW4sIGNoKTsKLQotICAgICAgc3RhcnRDb2x1bW4gPSAwOyAgLy8gYWZ0ZXIgZmlyc3QgY2h1bmsKLSAgICB9Ci0KLSAgICAvLyBMYXN0LCBvciBvbmx5LCBjaHVuawotICAgIGlmIChzdG9wQ2h1bmsgPT0gMCAmJiBtX2lubmVyRlNCICE9IG51bGwpCi0gICAgICBtX2lubmVyRlNCLnNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhjaCwgc3RhcnRDb2x1bW4sIHN0b3BDb2x1bW4gLSBzdGFydENvbHVtbik7Ci0gICAgZWxzZSBpZiAoc3RvcENvbHVtbiA+IHN0YXJ0Q29sdW1uKQotICAgIHsKLSAgICAgIHNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhtX2FycmF5W3N0b3BDaHVua10sIHN0YXJ0Q29sdW1uLAotICAgICAgICAgICAgICAgICAgICBzdG9wQ29sdW1uIC0gc3RhcnRDb2x1bW4sIGNoKTsKLSAgICB9Ci0gIH0KLSAgCi0gIHN0YXRpYyBjaGFyW10gbV9vbmVDaGFyID0geycgJ307Ci0gIAotICAvKioKLSAgICogRGlyZWN0bHkgbm9ybWFsaXplIGFuZCBkaXNwYXRjaCB0aGUgY2hhcmFjdGVyIGFycmF5LgotICAgKgotICAgKiBAcGFyYW0gY2ggVGhlIGNoYXJhY3RlcnMgZnJvbSB0aGUgWE1MIGRvY3VtZW50LgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICogCi0gICAqIEBleGNlcHRpb24gb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uIEFueSBTQVggZXhjZXB0aW9uLCBwb3NzaWJseQotICAgKiAgICAgICAgICAgIHdyYXBwaW5nIGFub3RoZXIgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIHNlbmROb3JtYWxpemVkU0FYY2hhcmFjdGVycyhjaGFyIGNoW10sIAotICAgICAgICAgICAgIGludCBzdGFydCwgaW50IGxlbmd0aCwgCi0gICAgICAgICAgICAgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpbnQgZW5kID0gbGVuZ3RoICsgc3RhcnQ7Ci0gICAgaW50IHM7Ci0gICAgZm9yIChzID0gc3RhcnQ7IHMgPCBlbmQ7IHMrKykKLSAgICB7Ci0gICAgICBjaGFyIGMgPSBjaFtzXTsKLSAgICAgIGlmKCFYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZShjKSkKLSAgICAgICAgYnJlYWs7Ci0gICAgfQotCi0gICAgYm9vbGVhbiB3aGl0ZVNwYWNlRm91bmQgPSBmYWxzZTsKLSAgICBib29sZWFuIG5lZWRUb0ZsdXNoU3BhY2UgPSBmYWxzZTsKLSAgICBpbnQgZCA9IHM7Ci0gICAgZm9yICg7IHMgPCBlbmQ7IHMrKykKLSAgICB7Ci0gICAgICBjaGFyIGMgPSBjaFtzXTsKLQotICAgICAgaWYgKFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGMpKQotICAgICAgewotICAgICAgICBpZiAoIXdoaXRlU3BhY2VGb3VuZCkKLSAgICAgICAgewotICAgICAgICAgIHdoaXRlU3BhY2VGb3VuZCA9IHRydWU7Ci0gICAgICAgICAgaWYoYyAhPSAnICcpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IGxlbiA9IChzLWQpOwotICAgICAgICAgICAgaWYoIGxlbiA+IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmKG5lZWRUb0ZsdXNoU3BhY2UpCi0gICAgICAgICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKG1fb25lQ2hhciwgMCwgMSk7Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIGhhbmRsZXIuY2hhcmFjdGVycyhjaCwgZCwgbGVuKTsKLSAgICAgICAgICAgICAgbmVlZFRvRmx1c2hTcGFjZSA9IHRydWU7Ci0gICAgICAgICAgICAgIC8vIGhhbmRsZXIuY2hhcmFjdGVycyhtX29uZUNoYXIsIDAsIDEpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZCA9IHMrMTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaW50IHo7Ci0gICAgICAgICAgZm9yICh6ID0gcysxOyB6IDwgZW5kOyB6KyspCi0gICAgICAgICAgewotICAgICAgICAgICAgYyA9IGNoW3pdOwotICAgICAgICAgICAgaWYoIVhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGMpKQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpbnQgbGVuID0gKHMtZCk7Ci0KLSAgICAgICAgICBpZih6ID09IGVuZCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBlbmQgPSBzOwotICAgICAgICAgICAgYnJlYWs7IC8vIExldCB0aGUgZmx1c2ggYXQgdGhlIGVuZCBoYW5kbGUgaXQuCi0gICAgICAgICAgfQotICAgICAgICAgIGlmKGxlbiA+IDApCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYobmVlZFRvRmx1c2hTcGFjZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKG1fb25lQ2hhciwgMCwgMSk7Ci0gICAgICAgICAgICAgIG5lZWRUb0ZsdXNoU3BhY2UgPSBmYWxzZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgCi0gICAgICAgICAgICBoYW5kbGVyLmNoYXJhY3RlcnMoY2gsIGQsIGxlbik7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgd2hpdGVTcGFjZUZvdW5kID0gZmFsc2U7Ci0gICAgICAgICAgZCA9IHMgPSB6OwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHdoaXRlU3BhY2VGb3VuZCA9IGZhbHNlOwotICAgICAgfQotICAgIH0KLQotICAgIGlmICh3aGl0ZVNwYWNlRm91bmQpCi0gICAgICBzLS07Ci0gICAgCi0gICAgaW50IGxlbiA9IChzLWQpOwotICAgIAotICAgIGlmKGxlbiA+IDApCi0gICAgewotICAgICAgaWYobmVlZFRvRmx1c2hTcGFjZSkKLSAgICAgICAgaGFuZGxlci5jaGFyYWN0ZXJzKG1fb25lQ2hhciwgMCwgMSk7Ci0gICAgICBoYW5kbGVyLmNoYXJhY3RlcnMoY2gsIGQsIGxlbik7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogU2VuZHMgdGhlIHNwZWNpZmllZCByYW5nZSBvZiBjaGFyYWN0ZXJzIGFzIHNheCBDb21tZW50LgotICAgKiA8cD4KLSAgICogTm90ZSB0aGF0LCB1bmxpa2Ugc2VuZFNBWGNoYXJhY3RlcnMsIHRoaXMgaGFzIHRvIGJlIGRvbmUgYXMgYSBzaW5nbGUgCi0gICAqIGNhbGwgdG8gTGV4aWNhbEhhbmRsZXIjY29tbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGNoIFNBWCBMZXhpY2FsSGFuZGxlciBvYmplY3QgdG8gcmVjZWl2ZSB0aGUgZXZlbnQuCi0gICAqIEBwYXJhbSBzdGFydCBPZmZzZXQgb2YgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZS4KLSAgICogQHBhcmFtIGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzZW5kLgotICAgKiBAZXhjZXB0aW9uIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGJ5IGhhbmRsZXIncwotICAgKiBjaGFyYWN0ZXJzKCkgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2VuZFNBWENvbW1lbnQoCi0gICAgICAgICAgb3JnLnhtbC5zYXguZXh0LkxleGljYWxIYW5kbGVyIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gICAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vICVPUFQlIERvIGl0IHRoaXMgd2F5IGZvciBub3cuLi4KLSAgICBTdHJpbmcgY29tbWVudCA9IGdldFN0cmluZyhzdGFydCwgbGVuZ3RoKTsKLSAgICBjaC5jb21tZW50KGNvbW1lbnQudG9DaGFyQXJyYXkoKSwgMCwgbGVuZ3RoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3BpZXMgY2hhcmFjdGVycyBmcm9tIHRoaXMgc3RyaW5nIGludG8gdGhlIGRlc3RpbmF0aW9uIGNoYXJhY3RlcgotICAgKiBhcnJheS4KLSAgICoKLSAgICogQHBhcmFtICAgICAgc3JjQmVnaW4gICBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICB0byBjb3B5LgotICAgKiBAcGFyYW0gICAgICBzcmNFbmQgICAgIGluZGV4IGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgZHN0ICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkuCi0gICAqIEBwYXJhbSAgICAgIGRzdEJlZ2luICAgdGhlIHN0YXJ0IG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gYXJyYXkuCi0gICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBJZiBhbnkgb2YgdGhlIGZvbGxvd2luZwotICAgKiAgICAgICAgICAgIGlzIHRydWU6Ci0gICAqICAgICAgICAgICAgPHVsPjxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUuCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPnNyY0JlZ2luPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gPGNvZGU+c3JjRW5kPC9jb2RlPgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNFbmQ8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgICAgICAgc3RyaW5nCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPmRzdEJlZ2luPC9jb2RlPiBpcyBuZWdhdGl2ZQotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbisoc3JjRW5kLXNyY0JlZ2luKTwvY29kZT4gaXMgbGFyZ2VyIHRoYW4KLSAgICogICAgICAgICAgICAgICAgPGNvZGU+ZHN0Lmxlbmd0aDwvY29kZT48L3VsPgotICAgKiBAZXhjZXB0aW9uIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmRzdDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBnZXRDaGFycyhpbnQgc3JjQmVnaW4sIGludCBzcmNFbmQsIGNoYXIgZHN0W10sIGludCBkc3RCZWdpbikKLSAgewotICAgIC8vICVUQkQlIEpvZSBuZWVkcyB0byB3cml0ZSB0aGlzIGZ1bmN0aW9uLiAgTWFrZSBwdWJsaWMgd2hlbiBpbXBsZW1lbnRlZC4KLSAgfQotCi0gIC8qKgotICAgKiBFbmNhcHN1bGF0aW9uIGMndG9yLiBBZnRlciB0aGlzIGlzIGNhbGxlZCwgdGhlIHNvdXJjZSBGYXN0U3RyaW5nQnVmZmVyCi0gICAqIHdpbGwgYmUgcmVzZXQgdG8gdXNlIHRoZSBuZXcgb2JqZWN0IGFzIGl0cyBtX2lubmVyRlNCLCBhbmQgd2lsbCBoYXZlCi0gICAqIGhhZCBpdHMgY2h1bmsgc2l6ZSByZXNldCBhcHByb3ByaWF0ZWx5LiBJVCBTSE9VTEQgTkVWRVIgQkUgQ0FMTEVECi0gICAqIEVYQ0VQVCBXSEVOIHNvdXJjZS5sZW5ndGgoKT09MTw8KHNvdXJjZS5tX2NodW5rQml0cytzb3VyY2UubV9yZWJ1bmRsZUJpdHMpCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBzb3VyY2UKLSAgICovCi0gIHByaXZhdGUgRmFzdFN0cmluZ0J1ZmZlcihGYXN0U3RyaW5nQnVmZmVyIHNvdXJjZSkKLSAgewotCi0gICAgLy8gQ29weSBleGlzdGluZyBpbmZvcm1hdGlvbiBpbnRvIG5ldyBlbmNhcHN1bGF0aW9uCi0gICAgbV9jaHVua0JpdHMgPSBzb3VyY2UubV9jaHVua0JpdHM7Ci0gICAgbV9tYXhDaHVua0JpdHMgPSBzb3VyY2UubV9tYXhDaHVua0JpdHM7Ci0gICAgbV9yZWJ1bmRsZUJpdHMgPSBzb3VyY2UubV9yZWJ1bmRsZUJpdHM7Ci0gICAgbV9jaHVua1NpemUgPSBzb3VyY2UubV9jaHVua1NpemU7Ci0gICAgbV9jaHVua01hc2sgPSBzb3VyY2UubV9jaHVua01hc2s7Ci0gICAgbV9hcnJheSA9IHNvdXJjZS5tX2FycmF5OwotICAgIG1faW5uZXJGU0IgPSBzb3VyY2UubV9pbm5lckZTQjsKLQotICAgIC8vIFRoZXNlIGhhdmUgdG8gYmUgYWRqdXN0ZWQgYmVjYXVzZSB3ZSdyZSBjYWxsaW5nIGp1c3QgYXQgdGhlIHRpbWUKLSAgICAvLyB3aGVuIHdlIHdvdWxkIGJlIGFib3V0IHRvIGFsbG9jYXRlIGFub3RoZXIgY2h1bmsKLSAgICBtX2xhc3RDaHVuayA9IHNvdXJjZS5tX2xhc3RDaHVuayAtIDE7Ci0gICAgbV9maXJzdEZyZWUgPSBzb3VyY2UubV9jaHVua1NpemU7Ci0KLSAgICAvLyBFc3RhYmxpc2ggY2Fwc3VsZSBhcyB0aGUgSW5uZXIgRlNCLCByZXNldCBjaHVuayBzaXplcy9hZGRyZXNzaW5nCi0gICAgc291cmNlLm1fYXJyYXkgPSBuZXcgY2hhclsxNl1bXTsKLSAgICBzb3VyY2UubV9pbm5lckZTQiA9IHRoaXM7Ci0KLSAgICAvLyBTaW5jZSB3ZSBlbmNhcHN1bGF0ZWQganVzdCBhcyB3ZSB3ZXJlIGFib3V0IHRvIGFwcGVuZCBhbm90aGVyCi0gICAgLy8gY2h1bmssIHJldHVybiByZWFkeSB0byBjcmVhdGUgdGhlIGNodW5rIGFmdGVyIHRoZSBpbm5lckZTQgotICAgIC8vIC0tIDEsIG5vdCAwLgotICAgIHNvdXJjZS5tX2xhc3RDaHVuayA9IDE7Ci0gICAgc291cmNlLm1fZmlyc3RGcmVlID0gMDsKLSAgICBzb3VyY2UubV9jaHVua0JpdHMgKz0gbV9yZWJ1bmRsZUJpdHM7Ci0gICAgc291cmNlLm1fY2h1bmtTaXplID0gMSA8PCAoc291cmNlLm1fY2h1bmtCaXRzKTsKLSAgICBzb3VyY2UubV9jaHVua01hc2sgPSBzb3VyY2UubV9jaHVua1NpemUgLSAxOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvSW50U3RhY2suamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9JbnRTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MjA1OTM0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9JbnRTdGFjay5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkVtcHR5U3RhY2tFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBJbXBsZW1lbnQgYSBzdGFjayBvZiBzaW1wbGUgaW50ZWdlcnMuCi0gKgotICogJU9QVCUKLSAqIFRoaXMgaXMgY3VycmVudGx5IGJhc2VkIG9uIEludFZlY3Rvciwgd2hpY2ggcGVybWl0cyBmYXN0IGFjZXNzIGJ1dCBwYXlzIGEKLSAqIGhlYXZ5IHJlY29weWluZyBwZW5hbHR5IGlmL3doZW4gaXRzIHNpemUgaXMgaW5jcmVhc2VkLiBJZiB3ZSBleHBlY3QgZGVlcAotICogc3RhY2tzLCB3ZSBzaG91bGQgY29uc2lkZXIgYSB2ZXJzaW9uIGJhc2VkIG9uIENodW5rZWRJbnRWZWN0b3IuCi0gKi8KLXB1YmxpYyBjbGFzcyBJbnRTdGFjayBleHRlbmRzIEludFZlY3RvcgotewotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIEludFN0YWNrKCkKLSAgewotICAgIHN1cGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgSW50VmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgSW50U3RhY2soaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIHN1cGVyKGJsb2Nrc2l6ZSk7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaGVzIGFuIGl0ZW0gb250byB0aGUgdG9wIG9mIHRoaXMgc3RhY2suCi0gICAqCi0gICAqIEBwYXJhbSAgIGkgICB0aGUgaW50IHRvIGJlIHB1c2hlZCBvbnRvIHRoaXMgc3RhY2suCi0gICAqIEByZXR1cm4gIHRoZSA8Y29kZT5pdGVtPC9jb2RlPiBhcmd1bWVudC4KLSAgICovCi0gIHB1YmxpYyBpbnQgcHVzaChpbnQgaSkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBpOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLQotICAgIHJldHVybiBpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIG9iamVjdCBhdCB0aGUgdG9wIG9mIHRoaXMgc3RhY2sgYW5kIHJldHVybnMgdGhhdAotICAgKiBvYmplY3QgYXMgdGhlIHZhbHVlIG9mIHRoaXMgZnVuY3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gICAgIFRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGludCBwb3AoKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwWy0tbV9maXJzdEZyZWVdOwotICB9Ci0KLSAgLyoqCi0gICAqIFF1aWNrbHkgcG9wcyBhIG51bWJlciBvZiBpdGVtcyBmcm9tIHRoZSBzdGFjay4KLSAgICovCi0KLSAgcHVibGljIHZvaWQgcXVpY2tQb3AoaW50IG4pCi0gIHsKLSAgICBtX2ZpcnN0RnJlZSAtPSBuOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2tzIGF0IHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrIHdpdGhvdXQgcmVtb3ZpbmcgaXQKLSAgICogZnJvbSB0aGUgc3RhY2suCi0gICAqCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgdGhlIHRvcCBvZiB0aGlzIHN0YWNrLgotICAgKiBAdGhyb3dzICBFbXB0eVN0YWNrRXhjZXB0aW9uICBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKi8KLSAgcHVibGljIGludCBwZWVrKCkKLSAgewotICAgIHJldHVybiBtX21hcFttX2ZpcnN0RnJlZSAtIDFdOwotICB9Ci0KLSAgLyoqCi0gICAqIExvb2tzIGF0IHRoZSBvYmplY3QgYXQgdGhlIHBvc2l0aW9uIHRoZSBzdGFjayBjb3VudGluZyBkb3duIG4gaXRlbXMuCi0gICAqCi0gICAqIEBwYXJhbSBuIFRoZSBudW1iZXIgb2YgaXRlbXMgZG93biwgaW5kZXhlZCBmcm9tIHplcm8uCi0gICAqIEByZXR1cm4gICAgIHRoZSBvYmplY3QgYXQgbiBpdGVtcyBkb3duLgotICAgKiBAdGhyb3dzICBFbXB0eVN0YWNrRXhjZXB0aW9uICBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKi8KLSAgcHVibGljIGludCBwZWVrKGludCBuKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlLSgxK24pXTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXRzIGFuIG9iamVjdCBhdCBhIHRoZSB0b3Agb2YgdGhlIHN0YXRjawotICAgKgotICAgKgotICAgKiBAcGFyYW0gdmFsIG9iamVjdCB0byBzZXQgYXQgdGhlIHRvcAotICAgKiBAdGhyb3dzICBFbXB0eVN0YWNrRXhjZXB0aW9uICBpZiB0aGlzIHN0YWNrIGlzIGVtcHR5LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VG9wKGludCB2YWwpCi0gIHsKLSAgICBtX21hcFttX2ZpcnN0RnJlZSAtIDFdID0gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RhY2sgaXMgZW1wdHkuCi0gICAqCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgc3RhY2sgaXMgZW1wdHk7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzaW5jZSAgIEpESzEuMAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZW1wdHkoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlID09IDA7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB3aGVyZSBhbiBvYmplY3QgaXMgb24gdGhpcyBzdGFjay4KLSAgICoKLSAgICogQHBhcmFtICAgbyAgIHRoZSBkZXNpcmVkIG9iamVjdC4KLSAgICogQHJldHVybiAgdGhlIGRpc3RhbmNlIGZyb20gdGhlIHRvcCBvZiB0aGUgc3RhY2sgd2hlcmUgdGhlIG9iamVjdCBpc10KLSAgICogICAgICAgICAgbG9jYXRlZDsgdGhlIHJldHVybiB2YWx1ZSA8Y29kZT4tMTwvY29kZT4gaW5kaWNhdGVzIHRoYXQgdGhlCi0gICAqICAgICAgICAgIG9iamVjdCBpcyBub3Qgb24gdGhlIHN0YWNrLgotICAgKiBAc2luY2UgICBKREsxLjAKLSAgICovCi0gIHB1YmxpYyBpbnQgc2VhcmNoKGludCBvKQotICB7Ci0KLSAgICBpbnQgaSA9IGxhc3RJbmRleE9mKG8pOwotCi0gICAgaWYgKGkgPj0gMCkKLSAgICB7Ci0gICAgICByZXR1cm4gc2l6ZSgpIC0gaTsKLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9JbnRWZWN0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9JbnRWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzM3YmNlNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvSW50VmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MzAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBpbnQuCi0gKgotICogVGhpcyB2ZXJzaW9uIGlzIGJhc2VkIG9uIGEgInJlYWxsb2MiIHN0cmF0ZWd5IC0tIGEgc2ltbGUgYXJyYXkgaXMKLSAqIHVzZWQsIGFuZCB3aGVuIG1vcmUgc3RvcmFnZSBpcyBuZWVkZWQsIGEgbGFyZ2VyIGFycmF5IGlzIG9idGFpbmVkCi0gKiBhbmQgYWxsIGV4aXN0aW5nIGRhdGEgaXMgcmVjb3BpZWQgaW50byBpdC4gQXMgYSByZXN1bHQsIHJlYWQvd3JpdGUKLSAqIGFjY2VzcyB0byBleGlzdGluZyBub2RlcyBpcyBPKDEpIGZhc3QgYnV0IGFwcGVuZGluZyBtYXkgYmUgTyhOKioyKQotICogc2xvdy4gU2VlIGFsc28gU3ViYWxsb2NhdGVkSW50VmVjdG9yLgotICovCi1wdWJsaWMgY2xhc3MgSW50VmVjdG9yCi17Ci0KLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIGludHMgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX21hcFtdOyAvLyBJbnRTdGFjayBpcyB0cnlpbmcgdG8gc2VlIHRoaXMgZGlyZWN0bHkKLQotICAvKiogTnVtYmVyIG9mIGludHMgaW4gYXJyYXkgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2ZpcnN0RnJlZSA9IDA7Ci0KLSAgLyoqIFNpemUgb2YgYXJyYXkgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX21hcFNpemU7Ci0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IuICBOb3RlIHRoYXQgdGhlIGRlZmF1bHQKLSAgICogYmxvY2sgc2l6ZSBpcyB2ZXJ5IHNtYWxsLCBmb3Igc21hbGwgbGlzdHMuCi0gICAqLwotICBwdWJsaWMgSW50VmVjdG9yKCkKLSAgewotCi0gICAgbV9ibG9ja3NpemUgPSAzMjsKLSAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEludFZlY3RvciwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9jayB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIEludFZlY3RvcihpbnQgYmxvY2tzaXplKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcFNpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgaW50W2Jsb2Nrc2l6ZV07Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBJbnRWZWN0b3IoaW50IGJsb2Nrc2l6ZSwgaW50IGluY3JlYXNlU2l6ZSkKLSAgewotCi0gICAgbV9ibG9ja3NpemUgPSBpbmNyZWFzZVNpemU7Ci0gICAgbV9tYXBTaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwID0gbmV3IGludFtibG9ja3NpemVdOwotICB9Ci0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gbGVuZ3RoIG9mIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTaXplKGludCBzeikKLSAgewotICAgIG1fZmlyc3RGcmVlID0gc3o7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBpbnQgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgSW50IHRvIGFkZCB0byB0aGUgbGlzdCAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVsZW1lbnQoaW50IHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgaW50IG5ld01hcFtdID0gbmV3IGludFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotICAKLSAgLyoqCi0gICAqIEFwcGVuZCBzZXZlcmFsIGludCB2YWx1ZXMgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgSW50IHRvIGFkZCB0byB0aGUgbGlzdCAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVsZW1lbnRzKGludCB2YWx1ZSwgaW50IG51bWJlck9mRWxlbWVudHMpCi0gIHsKLQotICAgIGlmICgobV9maXJzdEZyZWUgKyBudW1iZXJPZkVsZW1lbnRzKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IChtX2Jsb2Nrc2l6ZStudW1iZXJPZkVsZW1lbnRzKTsKLQotICAgICAgaW50IG5ld01hcFtdID0gbmV3IGludFttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtYmVyT2ZFbGVtZW50czsgaSsrKSAKLSAgICB7Ci0gICAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLSAgICAgIG1fZmlyc3RGcmVlKys7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogQXBwZW5kIHNldmVyYWwgc2xvdHMgb250byB0aGUgdmVjdG9yLCBidXQgZG8gbm90IHNldCB0aGUgdmFsdWVzLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgSW50IHRvIGFkZCB0byB0aGUgbGlzdCAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGFkZEVsZW1lbnRzKGludCBudW1iZXJPZkVsZW1lbnRzKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgbnVtYmVyT2ZFbGVtZW50cykgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSAobV9ibG9ja3NpemUrbnVtYmVyT2ZFbGVtZW50cyk7Ci0KLSAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0gICAgCi0gICAgbV9maXJzdEZyZWUgKz0gbnVtYmVyT2ZFbGVtZW50czsKLSAgfQotICAKLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEludCB0byBpbnNlcnQKLSAgICogQHBhcmFtIGF0IEluZGV4IG9mIHdoZXJlIHRvIGluc2VydCAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIGluc2VydEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBpZiAoYXQgPD0gKG1fZmlyc3RGcmVlIC0gMSkpCi0gICAgewotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgYXQsIG1fbWFwLCBhdCArIDEsIG1fZmlyc3RGcmVlIC0gYXQpOwotICAgIH0KLQotICAgIG1fbWFwW2F0XSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbm9kZSBpbiB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiBFYWNoIGNvbXBvbmVudCBpbiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8KLSAgICogdGhlIHNwZWNpZmllZCBpbmRleCBpcyBzaGlmdGVkIHVwd2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBncmVhdGVyCi0gICAqIHRoYW4gdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlQWxsRWxlbWVudHMoKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgbV9tYXBbaV0gPSBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gICAgfQotCi0gICAgbV9maXJzdEZyZWUgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGZyb20gdGhpcyB2ZWN0b3IuCi0gICAqIElmIHRoZSBvYmplY3QgaXMgZm91bmQgaW4gdGhpcyB2ZWN0b3IsIGVhY2ggY29tcG9uZW50IGluIHRoZSB2ZWN0b3IKLSAgICogd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBvYmplY3QncyBpbmRleCBpcyBzaGlmdGVkCi0gICAqIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbiB0aGUgdmFsdWUgaXQgaGFkCi0gICAqIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBzIEludCB0byByZW1vdmUgZnJvbSBhcnJheQotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGludCB3YXMgcmVtb3ZlZCwgZmFsc2UgaWYgaXQgd2FzIG5vdCBmb3VuZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gcmVtb3ZlRWxlbWVudChpbnQgcykKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXSA9PSBzKQotICAgICAgewotICAgICAgICBpZiAoKGkgKyAxKSA8IG1fZmlyc3RGcmVlKQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGkgKyAxLCBtX21hcCwgaSAtIDEsIG1fZmlyc3RGcmVlIC0gaSk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBtX21hcFtpXSA9IGphdmEubGFuZy5JbnRlZ2VyLk1JTl9WQUxVRTsKLQotICAgICAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWxldGVzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gRWFjaCBjb21wb25lbnQgaW4KLSAgICogdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXggaXMgc2hpZnRlZCBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4KLSAgICogdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBvZiB3aGVyZSB0byByZW1vdmUgYW5kIGludAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVtb3ZlRWxlbWVudEF0KGludCBpKQotICB7Ci0KLSAgICBpZiAoaSA+IG1fZmlyc3RGcmVlKQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDEsIG1fbWFwLCBpLCBtX2ZpcnN0RnJlZSk7Ci0gICAgZWxzZQotICAgICAgbV9tYXBbaV0gPSBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgdmVjdG9yIHRvIGJlIHRoZQotICAgKiBzcGVjaWZpZWQgb2JqZWN0LiBUaGUgcHJldmlvdXMgY29tcG9uZW50IGF0IHRoYXQgcG9zaXRpb24gaXMgZGlzY2FyZGVkLgotICAgKgotICAgKiBUaGUgaW5kZXggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzCi0gICAqIHRoYW4gdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBvYmplY3QgdG8gc2V0Ci0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzZXQgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0RWxlbWVudEF0KGludCB2YWx1ZSwgaW50IGluZGV4KQotICB7Ci0gICAgbV9tYXBbaW5kZXhdID0gdmFsdWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgaW5kZXggb2Ygb2JqZWN0IHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIG9iamVjdCBhdCBnaXZlbiBpbmRleAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBlbGVtZW50QXQoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIG9iamVjdCB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29udGFpbnMoaW50IHMpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0gPT0gcykKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gb2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBiZWdpbiBzZWFyY2gKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBpbmRleE9mKGludCBlbGVtLCBpbnQgaW5kZXgpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSBpbmRleDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBvYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBpbmRleE9mKGludCBlbGVtKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiBqYXZhLmxhbmcuSW50ZWdlci5NSU5fVkFMVUU7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBPYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBsYXN0SW5kZXhPZihpbnQgZWxlbSkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IChtX2ZpcnN0RnJlZSAtIDEpOyBpID49IDA7IGktLSkKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0gPT0gZWxlbSkKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGphdmEubGFuZy5JbnRlZ2VyLk1JTl9WQUxVRTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL011dGFibGVBdHRyTGlzdEltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9NdXRhYmxlQXR0ckxpc3RJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVlMDk1ODAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL011dGFibGVBdHRyTGlzdEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ1ZlY3RvcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuQXR0cmlidXRlc0ltcGw7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBNdXRhYmxlIHZlcnNpb24gb2YgQXR0cmlidXRlc0ltcGwuCi0gKi8KLXB1YmxpYyBjbGFzcyBNdXRhYmxlQXR0ckxpc3RJbXBsIGV4dGVuZHMgQXR0cmlidXRlc0ltcGwKLSAgICAgICAgaW1wbGVtZW50cyBTZXJpYWxpemFibGUKLXsKLQotLyoqCi0gKiBDb25zdHJ1Y3QgYSBuZXcsIGVtcHR5IEF0dHJpYnV0ZXNJbXBsIG9iamVjdC4KLSAqLwotCi1wdWJsaWMgTXV0YWJsZUF0dHJMaXN0SW1wbCgpCi0gIHsKLSAgICBzdXBlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgYW4gZXhpc3RpbmcgQXR0cmlidXRlcyBvYmplY3QuCi0gICAqCi0gICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgZXNwZWNpYWxseSB1c2VmdWwgaW5zaWRlIGEgc3RhcnQKLSAgICogZWxlbWVudCBldmVudC48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBhdHRzIFRoZSBleGlzdGluZyBBdHRyaWJ1dGVzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBNdXRhYmxlQXR0ckxpc3RJbXBsKEF0dHJpYnV0ZXMgYXR0cykKLSAgewotICAgIHN1cGVyKGF0dHMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBhdHRyaWJ1dGUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogPHA+Rm9yIHRoZSBzYWtlIG9mIHNwZWVkLCB0aGlzIG1ldGhvZCBkb2VzIG5vIGNoZWNraW5nCi0gICAqIHRvIHNlZSBpZiB0aGUgYXR0cmlidXRlIGlzIGFscmVhZHkgaW4gdGhlIGxpc3Q6IHRoYXQgaXMKLSAgICogdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkksIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYKLSAgICogICAgICAgIG5vbmUgaXMgYXZhaWxhYmxlIG9yIE5hbWVzcGFjZSBwcm9jZXNzaW5nIGlzIG5vdAotICAgKiAgICAgICAgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmCi0gICAqICAgICAgICBOYW1lc3BhY2UgcHJvY2Vzc2luZyBpcyBub3QgYmVpbmcgcGVyZm9ybWVkLgotICAgKiBAcGFyYW0gcU5hbWUgVGhlIHF1YWxpZmllZCAocHJlZml4ZWQpIG5hbWUsIG9yIHRoZSBlbXB0eSBzdHJpbmcKLSAgICogICAgICAgIGlmIHF1YWxpZmllZCBuYW1lcyBhcmUgbm90IGF2YWlsYWJsZS4KLSAgICogQHBhcmFtIHR5cGUgVGhlIGF0dHJpYnV0ZSB0eXBlIGFzIGEgc3RyaW5nLgotICAgKiBAcGFyYW0gdmFsdWUgVGhlIGF0dHJpYnV0ZSB2YWx1ZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgdXJpLCBTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgcU5hbWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHlwZSwgU3RyaW5nIHZhbHVlKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSB1cmkpCi0gICAgICB1cmkgPSAiIjsKLQotICAgIC8vIGdldEluZGV4KHFOYW1lKSBzZWVtcyB0byBiZSBtb3JlIHJlbGlhYmxlIHRoYW4gZ2V0SW5kZXgodXJpLCBsb2NhbE5hbWUpLCAKLSAgICAvLyBpbiB0aGUgY2FzZSBvZiB0aGUgeG1sbnMgYXR0cmlidXRlIGFueXdheS4KLSAgICBpbnQgaW5kZXggPSB0aGlzLmdldEluZGV4KHFOYW1lKTsKLSAgICAvLyBpbnQgaW5kZXggPSB0aGlzLmdldEluZGV4KHVyaSwgbG9jYWxOYW1lKTsKLSAgIAotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiTXV0YWJsZUF0dHJMaXN0SW1wbCNhZGRBdHRyaWJ1dGU6ICIrdXJpKyI6Iitsb2NhbE5hbWUrIiwgIitpbmRleCsiLCAiK3FOYW1lKyIsICIrdGhpcyk7Ci0KLSAgICBpZiAoaW5kZXggPj0gMCkKLSAgICAgIHRoaXMuc2V0QXR0cmlidXRlKGluZGV4LCB1cmksIGxvY2FsTmFtZSwgcU5hbWUsIHR5cGUsIHZhbHVlKTsKLSAgICBlbHNlCi0gICAgICBzdXBlci5hZGRBdHRyaWJ1dGUodXJpLCBsb2NhbE5hbWUsIHFOYW1lLCB0eXBlLCB2YWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIHRoZSBjb250ZW50cyBvZiB0aGUgYXR0cmlidXRlIGxpc3QgdG8gdGhpcyBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gYXR0cyBMaXN0IG9mIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkQXR0cmlidXRlcyhBdHRyaWJ1dGVzIGF0dHMpCi0gIHsKLQotICAgIGludCBuQXR0cyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BdHRzOyBpKyspCi0gICAgewotICAgICAgU3RyaW5nIHVyaSA9IGF0dHMuZ2V0VVJJKGkpOwotCi0gICAgICBpZiAobnVsbCA9PSB1cmkpCi0gICAgICAgIHVyaSA9ICIiOwotCi0gICAgICBTdHJpbmcgbG9jYWxOYW1lID0gYXR0cy5nZXRMb2NhbE5hbWUoaSk7Ci0gICAgICBTdHJpbmcgcW5hbWUgPSBhdHRzLmdldFFOYW1lKGkpOwotICAgICAgaW50IGluZGV4ID0gdGhpcy5nZXRJbmRleCh1cmksIGxvY2FsTmFtZSk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIk11dGFibGVBdHRyTGlzdEltcGwjYWRkQXR0cmlidXRlczogIit1cmkrIjoiK2xvY2FsTmFtZSsiLCAiK2luZGV4KyIsICIrYXR0cy5nZXRRTmFtZShpKSsiLCAiK3RoaXMpOwotICAgICAgaWYgKGluZGV4ID49IDApCi0gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKGluZGV4LCB1cmksIGxvY2FsTmFtZSwgcW5hbWUsIGF0dHMuZ2V0VHlwZShpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cy5nZXRWYWx1ZShpKSk7Ci0gICAgICBlbHNlCi0gICAgICAgIGFkZEF0dHJpYnV0ZSh1cmksIGxvY2FsTmFtZSwgcW5hbWUsIGF0dHMuZ2V0VHlwZShpKSwKLSAgICAgICAgICAgICAgICAgICAgIGF0dHMuZ2V0VmFsdWUoaSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdHJ1ZSBpZiBsaXN0IGNvbnRhaW5zIHRoZSBnaXZlbiAocmF3KSBhdHRyaWJ1dGUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWUgUmF3IG5hbWUgb2YgYXR0cmlidXRlIHRvIGxvb2sgZm9yIAotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgYW4gYXR0cmlidXRlIGlzIGZvdW5kIHdpdGggdGhpcyBuYW1lCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhTdHJpbmcgbmFtZSkKLSAgewotICAgIHJldHVybiBnZXRWYWx1ZShuYW1lKSAhPSBudWxsOwotICB9Ci19Ci0KLS8vIGVuZCBvZiBNdXRhYmxlQXR0ckxpc3RJbXBsLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9OU0luZm8uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9OU0luZm8uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2Q0ZjFiNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvTlNJbmZvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGNsYXNzIGhvbGRzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBuYW1lc3BhY2UgaW5mbwotICogb2YgYSBub2RlLiAgSXQgaXMgdXNlZCB0byBvcHRpbWl6ZSBuYW1lc3BhY2UgbG9va3VwIGluCi0gKiBhIGdlbmVyaWMgRE9NLgotICovCi1wdWJsaWMgY2xhc3MgTlNJbmZvCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE5TSW5mbwotICAgKgotICAgKgotICAgKiBAcGFyYW0gaGFzUHJvY2Vzc2VkTlMgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgbmFtZXNwYWNlcwotICAgKiBoYXZlIGJlZW4gcHJvY2Vzc2VkIGZvciB0aGlzIG5vZGUgCi0gICAqIEBwYXJhbSBoYXNYTUxOU0F0dHJzIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoaXMgbm9kZQotICAgKiBoYXMgWE1MTlMgYXR0cmlidXRlcy4gCi0gICAqLwotICBwdWJsaWMgTlNJbmZvKGJvb2xlYW4gaGFzUHJvY2Vzc2VkTlMsIGJvb2xlYW4gaGFzWE1MTlNBdHRycykKLSAgewotCi0gICAgbV9oYXNQcm9jZXNzZWROUyA9IGhhc1Byb2Nlc3NlZE5TOwotICAgIG1faGFzWE1MTlNBdHRycyA9IGhhc1hNTE5TQXR0cnM7Ci0gICAgbV9uYW1lc3BhY2UgPSBudWxsOwotICAgIG1fYW5jZXN0b3JIYXNYTUxOU0F0dHJzID0gQU5DRVNUT1JYTUxOU1VOUFJPQ0VTU0VEOwotICB9Ci0KLSAgLy8gVW51c2VkIGF0IHRoZSBtb21lbnQKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgTlNJbmZvCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBoYXNQcm9jZXNzZWROUyBGbGFnIGluZGljYXRpbmcgd2hldGhlciBuYW1lc3BhY2VzCi0gICAqIGhhdmUgYmVlbiBwcm9jZXNzZWQgZm9yIHRoaXMgbm9kZSAKLSAgICogQHBhcmFtIGhhc1hNTE5TQXR0cnMgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBub2RlCi0gICAqIGhhcyBYTUxOUyBhdHRyaWJ1dGVzLiAKLSAgICogQHBhcmFtIGhhc1hNTE5TQXR0cnMgRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgb25lIG9mIHRoaXMgbm9kZSdzCi0gICAqIGFuY2VzdG9yIGhhcyBYTUxOUyBhdHRyaWJ1dGVzLgotICAgKi8KLSAgcHVibGljIE5TSW5mbyhib29sZWFuIGhhc1Byb2Nlc3NlZE5TLCBib29sZWFuIGhhc1hNTE5TQXR0cnMsCi0gICAgICAgICAgICAgICAgaW50IGFuY2VzdG9ySGFzWE1MTlNBdHRycykKLSAgewotCi0gICAgbV9oYXNQcm9jZXNzZWROUyA9IGhhc1Byb2Nlc3NlZE5TOwotICAgIG1faGFzWE1MTlNBdHRycyA9IGhhc1hNTE5TQXR0cnM7Ci0gICAgbV9hbmNlc3Rvckhhc1hNTE5TQXR0cnMgPSBhbmNlc3Rvckhhc1hNTE5TQXR0cnM7Ci0gICAgbV9uYW1lc3BhY2UgPSBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE5TSW5mbwotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgVVJJIAotICAgKiBAcGFyYW0gaGFzWE1MTlNBdHRycyBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIG5vZGUKLSAgICogaGFzIFhNTE5TIGF0dHJpYnV0ZXMuCi0gICAqLwotICBwdWJsaWMgTlNJbmZvKFN0cmluZyBuYW1lc3BhY2UsIGJvb2xlYW4gaGFzWE1MTlNBdHRycykKLSAgewotCi0gICAgbV9oYXNQcm9jZXNzZWROUyA9IHRydWU7Ci0gICAgbV9oYXNYTUxOU0F0dHJzID0gaGFzWE1MTlNBdHRyczsKLSAgICBtX25hbWVzcGFjZSA9IG5hbWVzcGFjZTsKLSAgICBtX2FuY2VzdG9ySGFzWE1MTlNBdHRycyA9IEFOQ0VTVE9SWE1MTlNVTlBST0NFU1NFRDsKLSAgfQotCi0gIC8qKiBUaGUgbmFtZXNwYWNlIFVSSSAgICAgICAgICAqLwotICBwdWJsaWMgU3RyaW5nIG1fbmFtZXNwYWNlOwotCi0gIC8qKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGlzIG5vZGUgaGFzIGFuIFhNTE5TIGF0dHJpYnV0ZSAgICAgICAgICAqLwotICBwdWJsaWMgYm9vbGVhbiBtX2hhc1hNTE5TQXR0cnM7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG5hbWVzcGFjZXMgaGF2ZSBiZWVuIHByb2Nlc3NlZCBmb3IgdGhpcyBub2RlICovCi0gIHB1YmxpYyBib29sZWFuIG1faGFzUHJvY2Vzc2VkTlM7Ci0KLSAgLyoqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIG9uZSBvZiB0aGlzIG5vZGUncyBhbmNlc3RvciBoYXMgYW4gWE1MTlMgYXR0cmlidXRlICAgICAgICAgICovCi0gIHB1YmxpYyBpbnQgbV9hbmNlc3Rvckhhc1hNTE5TQXR0cnM7Ci0KLSAgLyoqIENvbnN0YW50IGZvciBhbmNlc3RvcnMgWE1MTlMgYXRyaWJ1dGVzIG5vdCBwcm9jZXNzZWQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5DRVNUT1JYTUxOU1VOUFJPQ0VTU0VEID0gMDsKLQotICAvKiogQ29uc3RhbnQgaW5kaWNhdGluZyBhbiBhbmNlc3RvciBoYXMgYW4gWE1MTlMgYXR0cmlidXRlICAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTkNFU1RPUkhBU1hNTE5TID0gMTsKLQotICAvKiogQ29uc3RhbnQgaW5kaWNhdGluZyBhbmNlc3RvcnMgZG9uJ3QgaGF2ZSBhbiBYTUxOUyBhdHRyaWJ1dGUgICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOQ0VTVE9STk9YTUxOUyA9IDI7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvTmFtZVNwYWNlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvTmFtZVNwYWNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDEwMzkxZTcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL05hbWVTcGFjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEEgcmVwcmVzZW50YXRpb24gb2YgYSBuYW1lc3BhY2UuICBPbmUgb2YgdGhlc2Ugd2lsbAotICogYmUgcHVzaGVkIG9uIHRoZSBuYW1lc3BhY2Ugc3RhY2sgZm9yIGVhY2gKLSAqIGVsZW1lbnQuCi0gKi8KLXB1YmxpYyBjbGFzcyBOYW1lU3BhY2UgaW1wbGVtZW50cyBTZXJpYWxpemFibGUKLXsKLQotICAvKiogTmV4dCBOYW1lU3BhY2UgZWxlbWVudCBvbiB0aGUgc3RhY2suCi0gICAqICBAc2VyaWFsICAgICAgICAgICAgICovCi0gIHB1YmxpYyBOYW1lU3BhY2UgbV9uZXh0ID0gbnVsbDsKLQotICAvKiogUHJlZml4IG9mIHRoaXMgTmFtZVNwYWNlIGVsZW1lbnQuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHB1YmxpYyBTdHJpbmcgbV9wcmVmaXg7Ci0KLSAgLyoqIE5hbWVzcGFjZSBVUkkgb2YgdGhpcyBOYW1lU3BhY2UgZWxlbWVudC4KLSAgICogIEBzZXJpYWwgICAgICAgICAgICovCi0gIHB1YmxpYyBTdHJpbmcgbV91cmk7ICAvLyBpZiBudWxsLCB0aGVuIEVsZW1lbnQgbmFtZXNwYWNlIGlzIGVtcHR5LgotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuYW1lc3BhY2UgZm9yIHBsYWNlbWVudCBvbiB0aGUKLSAgICogcmVzdWx0IHRyZWUgbmFtZXNwYWNlIHN0YWNrLgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFByZWZpeCBvZiB0aGlzIGVsZW1lbnQKLSAgICogQHBhcmFtIHVyaSBVUkkgb2YgIHRoaXMgZWxlbWVudAotICAgKi8KLSAgcHVibGljIE5hbWVTcGFjZShTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICB7Ci0gICAgbV9wcmVmaXggPSBwcmVmaXg7Ci0gICAgbV91cmkgPSB1cmk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9OYW1lc3BhY2VTdXBwb3J0Mi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL05hbWVzcGFjZVN1cHBvcnQyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZhOTE2Y2QuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL05hbWVzcGFjZVN1cHBvcnQyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3ODUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRW1wdHlTdGFja0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vKioKLSAqIEVuY2Fwc3VsYXRlIE5hbWVzcGFjZSB0cmFja2luZyBsb2dpYyBmb3IgdXNlIGJ5IFNBWCBkcml2ZXJzLgotICoKLSAqIDxwPlRoaXMgY2xhc3MgaXMgYW4gYXR0ZW1wdCB0byByZXdyaXRlIHRoZSBTQVggTmFtZXNwYWNlU3VwcG9ydAotICogImhlbHBlciIgY2xhc3MgZm9yIGltcHJvdmVkIGVmZmljaWVuY3kuIEl0IGNhbiBiZSB1c2VkIHRvIHRyYWNrIHRoZQotICogbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBjdXJyZW50bHkgaW4gc2NvcGUsIHByb3ZpZGluZyBsb29rdXAKLSAqIHJvdXRpbmVzIHRvIG1hcCBwcmVmaXhlcyB0byBVUklzIGFuZCB2aWNlIHZlcnNhLjwvcD4KLSAqCi0gKiA8cD5JU1NVRTogRm9yIHRlc3RpbmcgcHVycG9zZXMsIEkndmUgZXh0ZW5kZWQgTmFtZXNwYWNlU3VwcG9ydCBldmVuCi0gKiB0aG91Z2ggSSdtIGNvbXBsZXRlbHkgcmVhc3NlcnRpbmcgYWxsIGJlaGF2aW9ycyBhbmQgZmllbGRzLgotICogV2FzdGVmdWwuLi4uIEJ1dCBTQVggZGlkIG5vdCBwdXQgYW4gaW50ZXJmYWNlIHVuZGVyIHRoYXQgb2JqZWN0IGFuZAotICogd2Ugc2VlbSB0byBoYXZlIHdyaXR0ZW4gdGhhdCBTQVggY2xhc3MgaW50byBvdXIgQVBJcy4uLiBhbmQgSSBkb24ndAotICogd2FudCB0byBhcmd1ZSB3aXRoIGl0IHJpZ2h0IG5vdy4gPC9wPgotICoKLSAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0Ci0gKiAqLwotcHVibGljIGNsYXNzIE5hbWVzcGFjZVN1cHBvcnQyCi0gICAgZXh0ZW5kcyBvcmcueG1sLnNheC5oZWxwZXJzLk5hbWVzcGFjZVN1cHBvcnQKLXsKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIHN0YXRlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLSAgICBwcml2YXRlIENvbnRleHQyIGN1cnJlbnRDb250ZXh0OyAvLyBDdXJyZW50IHBvaW50IG9uIHRoZSBkb3VibGUtbGlua2VkIHN0YWNrCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gQ29uc3RhbnRzLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIFRoZSBYTUwgTmFtZXNwYWNlIGFzIGEgY29uc3RhbnQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGlzIHRoZSBOYW1lc3BhY2UgVVJJIHRoYXQgaXMgYXV0b21hdGljYWxseSBtYXBwZWQKLSAgICAgKiB0byB0aGUgInhtbCIgcHJlZml4LjwvcD4KLSAgICAgKi8KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBYTUxOUyA9Ci0gICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiOwotCi0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIENvbnN0cnVjdG9yLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBOYW1lc3BhY2Ugc3VwcG9ydCBvYmplY3QuCi0gICAgICovCi0gICAgcHVibGljIE5hbWVzcGFjZVN1cHBvcnQyICgpCi0gICAgewotICAgICAgICByZXNldCgpOwotICAgIH0KLQotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBDb250ZXh0IG1hbmFnZW1lbnQuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCi0gICAgLyoqCi0gICAgICogUmVzZXQgdGhpcyBOYW1lc3BhY2Ugc3VwcG9ydCBvYmplY3QgZm9yIHJldXNlLgotICAgICAqCi0gICAgICogPHA+SXQgaXMgbmVjZXNzYXJ5IHRvIGludm9rZSB0aGlzIG1ldGhvZCBiZWZvcmUgcmV1c2luZyB0aGUKLSAgICAgKiBOYW1lc3BhY2Ugc3VwcG9ydCBvYmplY3QgZm9yIGEgbmV3IHNlc3Npb24uPC9wPgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHJlc2V0ICgpCi0gICAgewotICAgICAgICAvLyBKSks6IERpc2NhcmRpbmcgdGhlIHdob2xlIHN0YWNrIGRvZXNuJ3Qgc2F2ZSB1cyBhIGxvdCB2ZXJzdXMKLSAgICAgICAgLy8gY3JlYXRpbmcgYSBuZXcgTmFtZXNwYWNlU3VwcG9ydC4gRG8gd2UgY2FyZSwgb3Igc2hvdWxkIHdlCi0gICAgICAgIC8vIGNoYW5nZSB0aGlzIHRvIGp1c3QgcmVzZXQgdGhlIHJvb3QgY29udGV4dD8KLSAgICAgICAgY3VycmVudENvbnRleHQgPSBuZXcgQ29udGV4dDIobnVsbCk7Ci0gICAgICAgIGN1cnJlbnRDb250ZXh0LmRlY2xhcmVQcmVmaXgoInhtbCIsIFhNTE5TKTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFN0YXJ0IGEgbmV3IE5hbWVzcGFjZSBjb250ZXh0LgotICAgICAqCi0gICAgICogPHA+Tm9ybWFsbHksIHlvdSBzaG91bGQgcHVzaCBhIG5ldyBjb250ZXh0IGF0IHRoZSBiZWdpbm5pbmcKLSAgICAgKiBvZiBlYWNoIFhNTCBlbGVtZW50OiB0aGUgbmV3IGNvbnRleHQgd2lsbCBhdXRvbWF0aWNhbGx5IGluaGVyaXQKLSAgICAgKiB0aGUgZGVjbGFyYXRpb25zIG9mIGl0cyBwYXJlbnQgY29udGV4dCwgYnV0IGl0IHdpbGwgYWxzbyBrZWVwCi0gICAgICogdHJhY2sgb2Ygd2hpY2ggZGVjbGFyYXRpb25zIHdlcmUgbWFkZSB3aXRoaW4gdGhpcyBjb250ZXh0LjwvcD4KLSAgICAgKgotICAgICAqIDxwPlRoZSBOYW1lc3BhY2Ugc3VwcG9ydCBvYmplY3QgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgYmFzZSBjb250ZXh0Ci0gICAgICogYWxyZWFkeSBpbiBmb3JjZTogaW4gdGhpcyBjb250ZXh0LCBvbmx5IHRoZSAieG1sIiBwcmVmaXggaXMKLSAgICAgKiBkZWNsYXJlZC48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICNwb3BDb250ZXh0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgcHVzaENvbnRleHQgKCkKLSAgICB7Ci0gICAgICAgIC8vIEpKSzogQ29udGV4dCBoYXMgYSBwYXJlbnQgcG9pbnRlci4KLSAgICAgICAgLy8gVGhhdCBtZWFucyB3ZSBkb24ndCBuZWVkIGEgc3RhY2sgdG8gcG9wLgotICAgICAgICAvLyBXZSBtYXkgd2FudCB0byByZXRhaW4gZm9yIHJldXNlLCBidXQgdGhhdCBjYW4gYmUgZG9uZSB2aWEKLSAgICAgICAgLy8gYSBjaGlsZCBwb2ludGVyLgotCi0gICAgICAgIENvbnRleHQyIHBhcmVudENvbnRleHQ9Y3VycmVudENvbnRleHQ7Ci0gICAgICAgIGN1cnJlbnRDb250ZXh0ID0gcGFyZW50Q29udGV4dC5nZXRDaGlsZCgpOwotICAgICAgICBpZiAoY3VycmVudENvbnRleHQgPT0gbnVsbCl7Ci0gICAgICAgICAgICAgICAgY3VycmVudENvbnRleHQgPSBuZXcgQ29udGV4dDIocGFyZW50Q29udGV4dCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIGVsc2V7Ci0gICAgICAgICAgICAvLyBKSks6IFRoaXMgd2lsbCB3aXBlIG91dCBhbnkgbGVmdG92ZXIgZGF0YQotICAgICAgICAgICAgLy8gaWYgd2UncmUgcmV1c2luZyBhIHByZXZpb3VzbHkgYWxsb2NhdGVkIENvbnRleHQuCi0gICAgICAgICAgICBjdXJyZW50Q29udGV4dC5zZXRQYXJlbnQocGFyZW50Q29udGV4dCk7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldmVydCB0byB0aGUgcHJldmlvdXMgTmFtZXNwYWNlIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiA8cD5Ob3JtYWxseSwgeW91IHNob3VsZCBwb3AgdGhlIGNvbnRleHQgYXQgdGhlIGVuZCBvZiBlYWNoCi0gICAgICogWE1MIGVsZW1lbnQuICBBZnRlciBwb3BwaW5nIHRoZSBjb250ZXh0LCBhbGwgTmFtZXNwYWNlIHByZWZpeAotICAgICAqIG1hcHBpbmdzIHRoYXQgd2VyZSBwcmV2aW91c2x5IGluIGZvcmNlIGFyZSByZXN0b3JlZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Zb3UgbXVzdCBub3QgYXR0ZW1wdCB0byBkZWNsYXJlIGFkZGl0aW9uYWwgTmFtZXNwYWNlCi0gICAgICogcHJlZml4ZXMgYWZ0ZXIgcG9wcGluZyBhIGNvbnRleHQsIHVubGVzcyB5b3UgcHVzaCBhbm90aGVyCi0gICAgICogY29udGV4dCBmaXJzdC48L3A+Ci0gICAgICoKLSAgICAgKiBAc2VlICNwdXNoQ29udGV4dAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHBvcENvbnRleHQgKCkKLSAgICB7Ci0gICAgICAgIENvbnRleHQyIHBhcmVudENvbnRleHQ9Y3VycmVudENvbnRleHQuZ2V0UGFyZW50KCk7Ci0gICAgICAgIGlmKHBhcmVudENvbnRleHQ9PW51bGwpCi0gICAgICAgICAgICB0aHJvdyBuZXcgRW1wdHlTdGFja0V4Y2VwdGlvbigpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgICBjdXJyZW50Q29udGV4dCA9IHBhcmVudENvbnRleHQ7Ci0gICAgfQotCi0KLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gT3BlcmF0aW9ucyB3aXRoaW4gYSBjb250ZXh0LgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQotICAgIC8qKgotICAgICAqIERlY2xhcmUgYSBOYW1lc3BhY2UgcHJlZml4LgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgZGVjbGFyZXMgYSBwcmVmaXggaW4gdGhlIGN1cnJlbnQgTmFtZXNwYWNlCi0gICAgICogY29udGV4dDsgdGhlIHByZWZpeCB3aWxsIHJlbWFpbiBpbiBmb3JjZSB1bnRpbCB0aGlzIGNvbnRleHQKLSAgICAgKiBpcyBwb3BwZWQsIHVubGVzcyBpdCBpcyBzaGFkb3dlZCBpbiBhIGRlc2NlbmRhbnQgY29udGV4dC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5UbyBkZWNsYXJlIGEgZGVmYXVsdCBOYW1lc3BhY2UsIHVzZSB0aGUgZW1wdHkgc3RyaW5nLiAgVGhlCi0gICAgICogcHJlZml4IG11c3Qgbm90IGJlICJ4bWwiIG9yICJ4bWxucyIuPC9wPgotICAgICAqCi0gICAgICogPHA+Tm90ZSB0aGF0IHlvdSBtdXN0IDxlbT5ub3Q8L2VtPiBkZWNsYXJlIGEgcHJlZml4IGFmdGVyCi0gICAgICogeW91J3ZlIHB1c2hlZCBhbmQgcG9wcGVkIGFub3RoZXIgTmFtZXNwYWNlLjwvcD4KLSAgICAgKgotICAgICAqIDxwPk5vdGUgdGhhdCB0aGVyZSBpcyBhbiBhc3ltbWV0cnkgaW4gdGhpcyBsaWJyYXJ5OiB3aGlsZSB7QGxpbmsKLSAgICAgKiAjZ2V0UHJlZml4IGdldFByZWZpeH0gd2lsbCBub3QgcmV0dXJuIHRoZSBkZWZhdWx0ICIiIHByZWZpeCwKLSAgICAgKiBldmVuIGlmIHlvdSBoYXZlIGRlY2xhcmVkIG9uZTsgdG8gY2hlY2sgZm9yIGEgZGVmYXVsdCBwcmVmaXgsCi0gICAgICogeW91IGhhdmUgdG8gbG9vayBpdCB1cCBleHBsaWNpdGx5IHVzaW5nIHtAbGluayAjZ2V0VVJJIGdldFVSSX0uCi0gICAgICogVGhpcyBhc3ltbWV0cnkgZXhpc3RzIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGxvb2sgdXAgcHJlZml4ZXMKLSAgICAgKiBmb3IgYXR0cmlidXRlIG5hbWVzLCB3aGVyZSB0aGUgZGVmYXVsdCBwcmVmaXggaXMgbm90IGFsbG93ZWQuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGRlY2xhcmUsIG9yIG51bGwgZm9yIHRoZSBlbXB0eQotICAgICAqICAgICAgICBzdHJpbmcuCi0gICAgICogQHBhcmFtIHVyaSBUaGUgTmFtZXNwYWNlIFVSSSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgcHJlZml4LgotICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcHJlZml4IHdhcyBsZWdhbCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAgICogQHNlZSAjcHJvY2Vzc05hbWUKLSAgICAgKiBAc2VlICNnZXRVUkkKLSAgICAgKiBAc2VlICNnZXRQcmVmaXgKLSAgICAgKi8KLSAgICBwdWJsaWMgYm9vbGVhbiBkZWNsYXJlUHJlZml4IChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgIHsKLSAgICAgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpIHx8IHByZWZpeC5lcXVhbHMoInhtbG5zIikpIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIGN1cnJlbnRDb250ZXh0LmRlY2xhcmVQcmVmaXgocHJlZml4LCB1cmkpOwotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFByb2Nlc3MgYSByYXcgWE1MIDEuMCBuYW1lLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgcHJvY2Vzc2VzIGEgcmF3IFhNTCAxLjAgbmFtZSBpbiB0aGUgY3VycmVudAotICAgICAqIGNvbnRleHQgYnkgcmVtb3ZpbmcgdGhlIHByZWZpeCBhbmQgbG9va2luZyBpdCB1cCBhbW9uZyB0aGUKLSAgICAgKiBwcmVmaXhlcyBjdXJyZW50bHkgZGVjbGFyZWQuICBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgYmUgdGhlCi0gICAgICogYXJyYXkgc3VwcGxpZWQgYnkgdGhlIGNhbGxlciwgZmlsbGVkIGluIGFzIGZvbGxvd3M6PC9wPgotICAgICAqCi0gICAgICogPGRsPgotICAgICAqIDxkdD5wYXJ0c1swXTwvZHQ+Ci0gICAgICogPGRkPlRoZSBOYW1lc3BhY2UgVVJJLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm9uZSBpcwotICAgICAqICBpbiB1c2UuPC9kZD4KLSAgICAgKiA8ZHQ+cGFydHNbMV08L2R0PgotICAgICAqIDxkZD5UaGUgbG9jYWwgbmFtZSAod2l0aG91dCBwcmVmaXgpLjwvZGQ+Ci0gICAgICogPGR0PnBhcnRzWzJdPC9kdD4KLSAgICAgKiA8ZGQ+VGhlIG9yaWdpbmFsIHJhdyBuYW1lLjwvZGQ+Ci0gICAgICogPC9kbD4KLSAgICAgKgotICAgICAqIDxwPkFsbCBvZiB0aGUgc3RyaW5ncyBpbiB0aGUgYXJyYXkgd2lsbCBiZSBpbnRlcm5hbGl6ZWQuICBJZgotICAgICAqIHRoZSByYXcgbmFtZSBoYXMgYSBwcmVmaXggdGhhdCBoYXMgbm90IGJlZW4gZGVjbGFyZWQsIHRoZW4KLSAgICAgKiB0aGUgcmV0dXJuIHZhbHVlIHdpbGwgYmUgbnVsbC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD5Ob3RlIHRoYXQgYXR0cmlidXRlIG5hbWVzIGFyZSBwcm9jZXNzZWQgZGlmZmVyZW50bHkgdGhhbgotICAgICAqIGVsZW1lbnQgbmFtZXM6IGFuIHVucHJlZml4ZWQgZWxlbWVudCBuYW1lIHdpbGwgcmVjZWl2ZWQgdGhlCi0gICAgICogZGVmYXVsdCBOYW1lc3BhY2UgKGlmIGFueSksIHdoaWxlIGFuIHVucHJlZml4ZWQgZWxlbWVudCBuYW1lCi0gICAgICogd2lsbCBub3QuPC9wPgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lIHRvIGJlIHByb2Nlc3NlZC4KLSAgICAgKiBAcGFyYW0gcGFydHMgQSBzdHJpbmcgYXJyYXkgc3VwcGxpZWQgYnkgdGhlIGNhbGxlciwgY2FwYWJsZSBvZgotICAgICAqICAgICAgICBob2xkaW5nIGF0IGxlYXN0IHRocmVlIG1lbWJlcnMuCi0gICAgICogQHBhcmFtIGlzQXR0cmlidXRlIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBpcyBhbgotICAgICAqICAgICAgICBhdHRyaWJ1dGUgbmFtZSAodHJ1ZSkgb3IgYW4gZWxlbWVudCBuYW1lIChmYWxzZSkuCi0gICAgICogQHJldHVybiBUaGUgc3VwcGxpZWQgYXJyYXkgaG9sZGluZyB0aHJlZSBpbnRlcm5hbGl6ZWQgc3RyaW5ncyAKLSAgICAgKiAgICAgICAgcmVwcmVzZW50aW5nIHRoZSBOYW1lc3BhY2UgVVJJIChvciBlbXB0eSBzdHJpbmcpLCB0aGUKLSAgICAgKiAgICAgICAgbG9jYWwgbmFtZSwgYW5kIHRoZSByYXcgWE1MIDEuMCBuYW1lOyBvciBudWxsIGlmIHRoZXJlCi0gICAgICogICAgICAgIGlzIGFuIHVuZGVjbGFyZWQgcHJlZml4LgotICAgICAqIEBzZWUgI2RlY2xhcmVQcmVmaXgKLSAgICAgKiBAc2VlIGphdmEubGFuZy5TdHJpbmcjaW50ZXJuICovCi0gICAgcHVibGljIFN0cmluZyBbXSBwcm9jZXNzTmFtZSAoU3RyaW5nIHFOYW1lLCBTdHJpbmdbXSBwYXJ0cywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzQXR0cmlidXRlKQotICAgIHsKLSAgICAgICAgU3RyaW5nW10gbmFtZT1jdXJyZW50Q29udGV4dC5wcm9jZXNzTmFtZShxTmFtZSwgaXNBdHRyaWJ1dGUpOwotICAgICAgICBpZihuYW1lPT1udWxsKQotICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICAgICAgLy8gSkpLOiBUaGlzIHJlY29weWluZyBpcyByZXF1aXJlZCBiZWNhdXNlIHByb2Nlc3NOYW1lIG1heSByZXR1cm4KLSAgICAgICAgLy8gYSBjYWNoZWQgcmVzdWx0LiBJIERvbid0IExpa2UgSXQuICoqKioqCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobmFtZSwwLHBhcnRzLDAsMyk7Ci0gICAgICAgIHJldHVybiBwYXJ0czsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgYSBwcmVmaXggYW5kIGdldCB0aGUgY3VycmVudGx5LW1hcHBlZCBOYW1lc3BhY2UgVVJJLgotICAgICAqCi0gICAgICogPHA+VGhpcyBtZXRob2QgbG9va3MgdXAgdGhlIHByZWZpeCBpbiB0aGUgY3VycmVudCBjb250ZXh0LgotICAgICAqIFVzZSB0aGUgZW1wdHkgc3RyaW5nICgiIikgZm9yIHRoZSBkZWZhdWx0IE5hbWVzcGFjZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggdG8gbG9vayB1cC4KLSAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgdGhlIHByZWZpeAotICAgICAqICAgICAgICAgaXMgdW5kZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAgICogQHNlZSAjZ2V0UHJlZml4Ci0gICAgICogQHNlZSAjZ2V0UHJlZml4ZXMKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFVSSSAoU3RyaW5nIHByZWZpeCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dC5nZXRVUkkocHJlZml4KTsKLSAgICB9Ci0KLQotICAgIC8qKgotICAgICAqIFJldHVybiBhbiBlbnVtZXJhdGlvbiBvZiBhbGwgcHJlZml4ZXMgY3VycmVudGx5IGRlY2xhcmVkLgotICAgICAqCi0gICAgICogPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBpZiB0aGVyZSBpcyBhIGRlZmF1bHQgcHJlZml4LCBpdCB3aWxsIG5vdCBiZQotICAgICAqIHJldHVybmVkIGluIHRoaXMgZW51bWVyYXRpb247IGNoZWNrIGZvciB0aGUgZGVmYXVsdCBwcmVmaXgKLSAgICAgKiB1c2luZyB0aGUge0BsaW5rICNnZXRVUkkgZ2V0VVJJfSB3aXRoIGFuIGFyZ3VtZW50IG9mICIiLjwvcD4KLSAgICAgKgotICAgICAqIEByZXR1cm4gQW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGRlY2xhcmVkIGluIHRoZQotICAgICAqICAgICAgICAgY3VycmVudCBjb250ZXh0IGV4Y2VwdCBmb3IgdGhlIGVtcHR5IChkZWZhdWx0KQotICAgICAqICAgICAgICAgcHJlZml4LgotICAgICAqIEBzZWUgI2dldERlY2xhcmVkUHJlZml4ZXMKLSAgICAgKiBAc2VlICNnZXRVUkkKLSAgICAgKi8KLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0UHJlZml4ZXMgKCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dC5nZXRQcmVmaXhlcygpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIG9uZSBvZiB0aGUgcHJlZml4ZXMgbWFwcGVkIHRvIGEgTmFtZXNwYWNlIFVSSS4KLSAgICAgKgotICAgICAqIDxwPklmIG1vcmUgdGhhbiBvbmUgcHJlZml4IGlzIGN1cnJlbnRseSBtYXBwZWQgdG8gdGhlIHNhbWUKLSAgICAgKiBVUkksIHRoaXMgbWV0aG9kIHdpbGwgbWFrZSBhbiBhcmJpdHJhcnkgc2VsZWN0aW9uOyBpZiB5b3UKLSAgICAgKiB3YW50IGFsbCBvZiB0aGUgcHJlZml4ZXMsIHVzZSB0aGUge0BsaW5rICNnZXRQcmVmaXhlc30KLSAgICAgKiBtZXRob2QgaW5zdGVhZC48L3A+Ci0gICAgICoKLSAgICAgKiA8cD48c3Ryb25nPk5vdGU6PC9zdHJvbmc+IHRoaXMgd2lsbCBuZXZlciByZXR1cm4gdGhlIGVtcHR5Ci0gICAgICogKGRlZmF1bHQpIHByZWZpeDsgdG8gY2hlY2sgZm9yIGEgZGVmYXVsdCBwcmVmaXgsIHVzZSB0aGUge0BsaW5rCi0gICAgICogI2dldFVSSSBnZXRVUkl9IG1ldGhvZCB3aXRoIGFuIGFyZ3VtZW50IG9mICIiLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSB1cmkgVGhlIE5hbWVzcGFjZSBVUkkuCi0gICAgICogQHJldHVybiBPbmUgb2YgdGhlIHByZWZpeGVzIGN1cnJlbnRseSBtYXBwZWQgdG8gdGhlIFVSSSBzdXBwbGllZCwKLSAgICAgKiAgICAgICAgIG9yIG51bGwgaWYgbm9uZSBpcyBtYXBwZWQgb3IgaWYgdGhlIFVSSSBpcyBhc3NpZ25lZCB0bwotICAgICAqICAgICAgICAgdGhlIGRlZmF1bHQgTmFtZXNwYWNlLgotICAgICAqIEBzZWUgI2dldFByZWZpeGVzKGphdmEubGFuZy5TdHJpbmcpCi0gICAgICogQHNlZSAjZ2V0VVJJICovCi0gICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXggKFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICByZXR1cm4gY3VycmVudENvbnRleHQuZ2V0UHJlZml4KHVyaSk7Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGN1cnJlbnRseSBkZWNsYXJlZCBmb3IgYSBVUkkuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIG1ldGhvZCByZXR1cm5zIHByZWZpeGVzIG1hcHBlZCB0byBhIHNwZWNpZmljIE5hbWVzcGFjZQotICAgICAqIFVSSS4gIFRoZSB4bWw6IHByZWZpeCB3aWxsIGJlIGluY2x1ZGVkLiAgSWYgeW91IHdhbnQgb25seSBvbmUKLSAgICAgKiBwcmVmaXggdGhhdCdzIG1hcHBlZCB0byB0aGUgTmFtZXNwYWNlIFVSSSwgYW5kIHlvdSBkb24ndCBjYXJlIAotICAgICAqIHdoaWNoIG9uZSB5b3UgZ2V0LCB1c2UgdGhlIHtAbGluayAjZ2V0UHJlZml4IGdldFByZWZpeH0KLSAgICAgKiAgbWV0aG9kIGluc3RlYWQuPC9wPgotICAgICAqCi0gICAgICogPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiB0aGUgZW1wdHkgKGRlZmF1bHQpIHByZWZpeCBpcwotICAgICAqIDxlbT5uZXZlcjwvZW0+IGluY2x1ZGVkIGluIHRoaXMgZW51bWVyYXRpb247IHRvIGNoZWNrIGZvciB0aGUKLSAgICAgKiBwcmVzZW5jZSBvZiBhIGRlZmF1bHQgTmFtZXNwYWNlLCB1c2UgdGhlIHtAbGluayAjZ2V0VVJJIGdldFVSSX0KLSAgICAgKiBtZXRob2Qgd2l0aCBhbiBhcmd1bWVudCBvZiAiIi48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBOYW1lc3BhY2UgVVJJLgotICAgICAqIEByZXR1cm4gQW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGRlY2xhcmVkIGluIHRoZQotICAgICAqICAgICAgICAgY3VycmVudCBjb250ZXh0LgotICAgICAqIEBzZWUgI2dldFByZWZpeAotICAgICAqIEBzZWUgI2dldERlY2xhcmVkUHJlZml4ZXMKLSAgICAgKiBAc2VlICNnZXRVUkkgKi8KLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0UHJlZml4ZXMgKFN0cmluZyB1cmkpCi0gICAgewotICAgICAgICAvLyBKSks6IFRoZSBvbGQgY29kZSBpbnZvbHZlZCBjcmVhdGluZyBhIHZlY3RvciwgZmlsbGluZyBpdAotICAgICAgICAvLyB3aXRoIGFsbCB0aGUgbWF0Y2hpbmcgcHJlZml4ZXMsIGFuZCB0aGVuIGdldHRpbmcgaXRzCi0gICAgICAgIC8vIGVsZW1lbnRzIGVudW1lcmF0b3IuIFdhc3RlcyBzdG9yYWdlLCB3YXN0ZXMgY3ljbGVzIGlmIHdlCi0gICAgICAgIC8vIGRvbid0IGFjdHVhbGx5IG5lZWQgdGhlbSBhbGwuIEJldHRlciB0byBlaXRoZXIgaW1wbGVtZW50Ci0gICAgICAgIC8vIGEgc3BlY2lmaWMgZW51bWVyYXRvciBmb3IgdGhlc2UgcHJlZml4ZXMuLi4gb3IgYSBmaWx0ZXIKLSAgICAgICAgLy8gYXJvdW5kIHRoZSBhbGwtcHJlZml4ZXMgZW51bWVyYXRvciwgd2hpY2ggY29tZXMgb3V0IHRvCi0gICAgICAgIC8vIHJvdWdobHkgdGhlIHNhbWUgdGhpbmcuCi0gICAgICAgIC8vCi0gICAgICAgIC8vICoqKiogQ3VycmVudGx5IGEgZmlsdGVyLiBUaGF0IG1heSBub3QgYmUgbW9zdCBlZmZpY2llbnQKLSAgICAgICAgLy8gd2hlbiBJJ20gZG9uZSByZXN0cnVjdHVyaW5nIHN0b3JhZ2UhCi0gICAgICAgIHJldHVybiBuZXcgUHJlZml4Rm9yVXJpRW51bWVyYXRvcih0aGlzLHVyaSxnZXRQcmVmaXhlcygpKTsgICAgICAgCi0gICAgfQotICAgIAotCi0gICAgLyoqCi0gICAgICogUmV0dXJuIGFuIGVudW1lcmF0aW9uIG9mIGFsbCBwcmVmaXhlcyBkZWNsYXJlZCBpbiB0aGlzIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiA8cD5UaGUgZW1wdHkgKGRlZmF1bHQpIHByZWZpeCB3aWxsIGJlIGluY2x1ZGVkIGluIHRoaXMgCi0gICAgICogZW51bWVyYXRpb247IG5vdGUgdGhhdCB0aGlzIGJlaGF2aW91ciBkaWZmZXJzIGZyb20gdGhhdCBvZgotICAgICAqIHtAbGluayAjZ2V0UHJlZml4fSBhbmQge0BsaW5rICNnZXRQcmVmaXhlc30uPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBhbGwgcHJlZml4ZXMgZGVjbGFyZWQgaW4gdGhpcwotICAgICAqICAgICAgICAgY29udGV4dC4KLSAgICAgKiBAc2VlICNnZXRQcmVmaXhlcwotICAgICAqIEBzZWUgI2dldFVSSQotICAgICAqLwotICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXREZWNsYXJlZFByZWZpeGVzICgpCi0gICAgewotICAgICAgICByZXR1cm4gY3VycmVudENvbnRleHQuZ2V0RGVjbGFyZWRQcmVmaXhlcygpOwotICAgIH0KLQotCi0KLX0KLQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIExvY2FsIGNsYXNzZXMuCi0vLyBUaGVzZSB3ZXJlIF9pbnRlcm5hbF8gY2xhc3Nlcy4uLiBidXQgaW4gZmFjdCB0aGV5IGRvbid0IGhhdmUgdG8gYmUsCi0vLyBhbmQgbWF5IGJlIG1vcmUgZWZmaWNpZW50IGlmIHRoZXkgYXJlbid0LiAKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLS8qKgotICogSW1wbGVtZW50YXRpb24gb2YgRW51bWVyYXRpb24gZmlsdGVyLCB3cmFwcGVkCi0gKiBhcm91bmcgdGhlIGdldC1hbGwtcHJlZml4ZXMgdmVyc2lvbiBvZiB0aGUgb3BlcmF0aW9uLiBUaGlzIGlzIE5PVAotICogbmVjZXNzYXJpbHkgdGhlIG1vc3QgZWZmaWNpZW50IGFwcHJvYWNoOyBmaW5kaW5nIHRoZSBVUkkgYW5kIHRoZW4gYXNraW5nCi0gKiB3aGF0IHByZWZpeGVzIGFwcGx5IHRvIGl0IG1pZ2h0IG1ha2UgbXVjaCBtb3JlIHNlbnNlLgotICovCi1jbGFzcyBQcmVmaXhGb3JVcmlFbnVtZXJhdG9yIGltcGxlbWVudHMgRW51bWVyYXRpb24KLXsKLSAgICBwcml2YXRlIEVudW1lcmF0aW9uIGFsbFByZWZpeGVzOwotICAgIHByaXZhdGUgU3RyaW5nIHVyaTsKLSAgICBwcml2YXRlIFN0cmluZyBsb29rYWhlYWQ9bnVsbDsKLSAgICBwcml2YXRlIE5hbWVzcGFjZVN1cHBvcnQyIG5zdXA7Ci0gICAgIAotICAgIC8vIEtsdWdlOiBTaW5jZSBvbmUgY2FuJ3QgZG8gYSBjb25zdHJ1Y3RvciBvbiBhbgotICAgIC8vIGFub255bW91cyBjbGFzcyAoYXMgZmFyIGFzIEkga25vdykuLi4KLSAgICBQcmVmaXhGb3JVcmlFbnVtZXJhdG9yKE5hbWVzcGFjZVN1cHBvcnQyIG5zdXAsU3RyaW5nIHVyaSwgRW51bWVyYXRpb24gYWxsUHJlZml4ZXMpCi0gICAgewotCXRoaXMubnN1cD1uc3VwOwotICAgICAgICB0aGlzLnVyaT11cmk7Ci0gICAgICAgIHRoaXMuYWxsUHJlZml4ZXM9YWxsUHJlZml4ZXM7Ci0gICAgfQotICAgICAgICAKLSAgICBwdWJsaWMgYm9vbGVhbiBoYXNNb3JlRWxlbWVudHMoKQotICAgIHsKLSAgICAgICAgaWYobG9va2FoZWFkIT1udWxsKQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgICAKLSAgICAgICAgd2hpbGUoYWxsUHJlZml4ZXMuaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHByZWZpeD0oU3RyaW5nKWFsbFByZWZpeGVzLm5leHRFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgaWYodXJpLmVxdWFscyhuc3VwLmdldFVSSShwcmVmaXgpKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgbG9va2FoZWFkPXByZWZpeDsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gICAgICAgIAotICAgIHB1YmxpYyBPYmplY3QgbmV4dEVsZW1lbnQoKQotICAgIHsKLSAgICAgICAgaWYoaGFzTW9yZUVsZW1lbnRzKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU3RyaW5nIHRtcD1sb29rYWhlYWQ7Ci0gICAgICAgICAgICAgICAgbG9va2FoZWFkPW51bGw7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIHRtcDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7Ci0gICAgfQotfQotCi0vKioKLSAqIEludGVybmFsIGNsYXNzIGZvciBhIHNpbmdsZSBOYW1lc3BhY2UgY29udGV4dC4KLSAqCi0gKiA8cD5UaGlzIG1vZHVsZSBjYWNoZXMgYW5kIHJldXNlcyBOYW1lc3BhY2UgY29udGV4dHMsIHNvIHRoZSBudW1iZXIgYWxsb2NhdGVkCi0gKiB3aWxsIGJlIGVxdWFsIHRvIHRoZSBlbGVtZW50IGRlcHRoIG9mIHRoZSBkb2N1bWVudCwgbm90IHRvIHRoZSB0b3RhbAotICogbnVtYmVyIG9mIGVsZW1lbnRzIChpLmUuIDUtMTAgcmF0aGVyIHRoYW4gdGVucyBvZiB0aG91c2FuZHMpLjwvcD4KLSAqLwotZmluYWwgY2xhc3MgQ29udGV4dDIgewotCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIE1hbmVmZXN0IENvbnN0YW50cwotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAgICAgCi0gICAgLyoqCi0gICAgICogQW4gZW1wdHkgZW51bWVyYXRpb24uCi0gICAgICovCi0gICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgRW51bWVyYXRpb24gRU1QVFlfRU5VTUVSQVRJT04gPQotICAgICAgICBuZXcgVmVjdG9yKCkuZWxlbWVudHMoKTsKLQotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICAvLyBQcm90ZWN0ZWQgc3RhdGUuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgICAgICAKLSAgICBIYXNodGFibGUgcHJlZml4VGFibGU7Ci0gICAgSGFzaHRhYmxlIHVyaVRhYmxlOwotICAgIEhhc2h0YWJsZSBlbGVtZW50TmFtZVRhYmxlOwotICAgIEhhc2h0YWJsZSBhdHRyaWJ1dGVOYW1lVGFibGU7Ci0gICAgU3RyaW5nIGRlZmF1bHROUyA9IG51bGw7Ci0KLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgLy8gSW50ZXJuYWwgc3RhdGUuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgICAgICAKLSAgICBwcml2YXRlIFZlY3RvciBkZWNsYXJhdGlvbnMgPSBudWxsOwotICAgIHByaXZhdGUgYm9vbGVhbiB0YWJsZXNEaXJ0eSA9IGZhbHNlOwotICAgIHByaXZhdGUgQ29udGV4dDIgcGFyZW50ID0gbnVsbDsKLSAgICBwcml2YXRlIENvbnRleHQyIGNoaWxkID0gbnVsbDsKLQotICAgIC8qKgotICAgICAqIENyZWF0ZSBhIG5ldyBOYW1lc3BhY2UgY29udGV4dC4KLSAgICAgKi8KLSAgICBDb250ZXh0MiAoQ29udGV4dDIgcGFyZW50KQotICAgIHsKLSAgICAgICAgaWYocGFyZW50PT1udWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHByZWZpeFRhYmxlID0gbmV3IEhhc2h0YWJsZSgpOwotICAgICAgICAgICAgICAgIHVyaVRhYmxlID0gbmV3IEhhc2h0YWJsZSgpOwotICAgICAgICAgICAgICAgIGVsZW1lbnROYW1lVGFibGU9bnVsbDsgCi0gICAgICAgICAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlPW51bGw7IAotICAgICAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgICBzZXRQYXJlbnQocGFyZW50KTsKLSAgICB9Ci0KLSAgICAgICAgCi0gICAgLyoqCi0gICAgICogQHJldHVybnMgVGhlIGNoaWxkIE5hbWVzcGFjZSBjb250ZXh0IG9iamVjdCwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogaXMgdGhlIGxhc3QgY3VycmVudGx5IG9uIHRoZSBjaGFpbi4KLSAgICAgKi8KLSAgICBDb250ZXh0MiBnZXRDaGlsZCgpCi0gICAgewotICAgICAgICByZXR1cm4gY2hpbGQ7Ci0gICAgfQotICAgICAgICAKLSAgICAvKioKLSAgICAgKiBAcmV0dXJucyBUaGUgcGFyZW50IE5hbWVzcGFjZSBjb250ZXh0IG9iamVjdCwgb3IgbnVsbCBpZiB0aGlzCi0gICAgICogaXMgdGhlIHJvb3QuCi0gICAgICovCi0gICAgQ29udGV4dDIgZ2V0UGFyZW50KCkKLSAgICB7Ci0gICAgICAgIHJldHVybiBwYXJlbnQ7Ci0gICAgfQotICAgICAgICAKLSAgICAvKioKLSAgICAgKiAoUmUpc2V0IHRoZSBwYXJlbnQgb2YgdGhpcyBOYW1lc3BhY2UgY29udGV4dC4KLSAgICAgKiBUaGlzIGlzIHNlcGFyYXRlIGZyb20gdGhlIGMndG9yIGJlY2F1c2UgaXQncyByZS1hcHBsaWVkCi0gICAgICogd2hlbiBhIENvbnRleHQyIGlzIHJldXNlZCBieSBwdXNoLWFmdGVyLXBvcC4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBwYXJlbnQgTmFtZXNwYWNlIGNvbnRleHQgb2JqZWN0LgotICAgICAqLwotICAgIHZvaWQgc2V0UGFyZW50IChDb250ZXh0MiBwYXJlbnQpCi0gICAgewotICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKLSAgICAgICAgcGFyZW50LmNoaWxkID0gdGhpczsgICAgICAgIC8vIEpKSzogRG91Ymx5LWxpbmtlZAotICAgICAgICBkZWNsYXJhdGlvbnMgPSBudWxsOwotICAgICAgICBwcmVmaXhUYWJsZSA9IHBhcmVudC5wcmVmaXhUYWJsZTsKLSAgICAgICAgdXJpVGFibGUgPSBwYXJlbnQudXJpVGFibGU7Ci0gICAgICAgIGVsZW1lbnROYW1lVGFibGUgPSBwYXJlbnQuZWxlbWVudE5hbWVUYWJsZTsKLSAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlID0gcGFyZW50LmF0dHJpYnV0ZU5hbWVUYWJsZTsKLSAgICAgICAgZGVmYXVsdE5TID0gcGFyZW50LmRlZmF1bHROUzsKLSAgICAgICAgdGFibGVzRGlydHkgPSBmYWxzZTsKLSAgICB9Ci0gICAgICAgIAotICAgICAgICAKLSAgICAvKioKLSAgICAgKiBEZWNsYXJlIGEgTmFtZXNwYWNlIHByZWZpeCBmb3IgdGhpcyBjb250ZXh0LgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGRlY2xhcmUuCi0gICAgICogQHBhcmFtIHVyaSBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0MiNkZWNsYXJlUHJlZml4Ci0gICAgICovCi0gICAgdm9pZCBkZWNsYXJlUHJlZml4IChTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKQotICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGF6eSBwcm9jZXNzaW5nLi4uCi0gICAgICAgIGlmICghdGFibGVzRGlydHkpIHsKLSAgICAgICAgICAgIGNvcHlUYWJsZXMoKTsKLSAgICAgICAgfQotICAgICAgICBpZiAoZGVjbGFyYXRpb25zID09IG51bGwpIHsKLSAgICAgICAgICAgIGRlY2xhcmF0aW9ucyA9IG5ldyBWZWN0b3IoKTsKLSAgICAgICAgfQotICAgICAgICAgICAgCi0gICAgICAgIHByZWZpeCA9IHByZWZpeC5pbnRlcm4oKTsKLSAgICAgICAgdXJpID0gdXJpLmludGVybigpOwotICAgICAgICBpZiAoIiIuZXF1YWxzKHByZWZpeCkpIHsKLSAgICAgICAgICAgIGlmICgiIi5lcXVhbHModXJpKSkgewotICAgICAgICAgICAgICAgIGRlZmF1bHROUyA9IG51bGw7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIGRlZmF1bHROUyA9IHVyaTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHByZWZpeFRhYmxlLnB1dChwcmVmaXgsIHVyaSk7Ci0gICAgICAgICAgICB1cmlUYWJsZS5wdXQodXJpLCBwcmVmaXgpOyAvLyBtYXkgd2lwZSBvdXQgYW5vdGhlciBwcmVmaXgKLSAgICAgICAgfQotICAgICAgICBkZWNsYXJhdGlvbnMuYWRkRWxlbWVudChwcmVmaXgpOwotICAgIH0KLQotCi0gICAgLyoqCi0gICAgICogUHJvY2VzcyBhIHJhdyBYTUwgMS4wIG5hbWUgaW4gdGhpcyBjb250ZXh0LgotICAgICAqCi0gICAgICogQHBhcmFtIHFOYW1lIFRoZSByYXcgWE1MIDEuMCBuYW1lLgotICAgICAqIEBwYXJhbSBpc0F0dHJpYnV0ZSB0cnVlIGlmIHRoaXMgaXMgYW4gYXR0cmlidXRlIG5hbWUuCi0gICAgICogQHJldHVybiBBbiBhcnJheSBvZiB0aHJlZSBzdHJpbmdzIGNvbnRhaW5pbmcgdGhlCi0gICAgICogICAgICAgICBVUkkgcGFydCAob3IgZW1wdHkgc3RyaW5nKSwgdGhlIGxvY2FsIHBhcnQsCi0gICAgICogICAgICAgICBhbmQgdGhlIHJhdyBuYW1lLCBhbGwgaW50ZXJuYWxpemVkLCBvciBudWxsCi0gICAgICogICAgICAgICBpZiB0aGVyZSBpcyBhbiB1bmRlY2xhcmVkIHByZWZpeC4KLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDIjcHJvY2Vzc05hbWUKLSAgICAgKi8KLSAgICBTdHJpbmcgW10gcHJvY2Vzc05hbWUgKFN0cmluZyBxTmFtZSwgYm9vbGVhbiBpc0F0dHJpYnV0ZSkKLSAgICB7Ci0gICAgICAgIFN0cmluZyBuYW1lW107Ci0gICAgICAgIEhhc2h0YWJsZSB0YWJsZTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGFwcHJvcHJpYXRlIHRhYmxlLgotICAgICAgICBpZiAoaXNBdHRyaWJ1dGUpIHsKLSAgICAgICAgICAgIGlmKGVsZW1lbnROYW1lVGFibGU9PW51bGwpCi0gICAgICAgICAgICAgICAgZWxlbWVudE5hbWVUYWJsZT1uZXcgSGFzaHRhYmxlKCk7Ci0gICAgICAgICAgICB0YWJsZSA9IGVsZW1lbnROYW1lVGFibGU7Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICBpZihhdHRyaWJ1dGVOYW1lVGFibGU9PW51bGwpCi0gICAgICAgICAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlPW5ldyBIYXNodGFibGUoKTsKLSAgICAgICAgICAgIHRhYmxlID0gYXR0cmlidXRlTmFtZVRhYmxlOwotICAgICAgICB9Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnQgYnkgbG9va2luZyBpbiB0aGUgY2FjaGUsIGFuZAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm4gaW1tZWRpYXRlbHkgaWYgdGhlIG5hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXMgYWxyZWFkeSBrbm93biBpbiB0aGlzIGNvbnRlbnQKLSAgICAgICAgbmFtZSA9IChTdHJpbmdbXSl0YWJsZS5nZXQocU5hbWUpOwotICAgICAgICBpZiAobmFtZSAhPSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbmFtZTsKLSAgICAgICAgfQotICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmVuJ3Qgc2VlbiB0aGlzIG5hbWUgaW4gdGhpcwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250ZXh0IGJlZm9yZS4KLSAgICAgICAgbmFtZSA9IG5ldyBTdHJpbmdbM107Ci0gICAgICAgIGludCBpbmRleCA9IHFOYW1lLmluZGV4T2YoJzonKTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIHByZWZpeC4KLSAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7Ci0gICAgICAgICAgICBpZiAoaXNBdHRyaWJ1dGUgfHwgZGVmYXVsdE5TID09IG51bGwpIHsKLSAgICAgICAgICAgICAgICBuYW1lWzBdID0gIiI7Ci0gICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgIG5hbWVbMF0gPSBkZWZhdWx0TlM7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBuYW1lWzFdID0gcU5hbWUuaW50ZXJuKCk7Ci0gICAgICAgICAgICBuYW1lWzJdID0gbmFtZVsxXTsKLSAgICAgICAgfQotICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByZWZpeAotICAgICAgICBlbHNlIHsKLSAgICAgICAgICAgIFN0cmluZyBwcmVmaXggPSBxTmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotICAgICAgICAgICAgU3RyaW5nIGxvY2FsID0gcU5hbWUuc3Vic3RyaW5nKGluZGV4KzEpOwotICAgICAgICAgICAgU3RyaW5nIHVyaTsKLSAgICAgICAgICAgIGlmICgiIi5lcXVhbHMocHJlZml4KSkgewotICAgICAgICAgICAgICAgIHVyaSA9IGRlZmF1bHROUzsKLSAgICAgICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICAgICAgdXJpID0gKFN0cmluZylwcmVmaXhUYWJsZS5nZXQocHJlZml4KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCkgewotICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgbmFtZVswXSA9IHVyaTsKLSAgICAgICAgICAgIG5hbWVbMV0gPSBsb2NhbC5pbnRlcm4oKTsKLSAgICAgICAgICAgIG5hbWVbMl0gPSBxTmFtZS5pbnRlcm4oKTsKLSAgICAgICAgfQotICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhdmUgaW4gdGhlIGNhY2hlIGZvciBmdXR1cmUgdXNlLgotICAgICAgICB0YWJsZS5wdXQobmFtZVsyXSwgbmFtZSk7Ci0gICAgICAgIHRhYmxlc0RpcnR5ID0gdHJ1ZTsKLSAgICAgICAgcmV0dXJuIG5hbWU7Ci0gICAgfQotICAgICAgICAKLQotICAgIC8qKgotICAgICAqIExvb2sgdXAgdGhlIFVSSSBhc3NvY2lhdGVkIHdpdGggYSBwcmVmaXggaW4gdGhpcyBjb250ZXh0LgotICAgICAqCi0gICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgdXAuCi0gICAgICogQHJldHVybiBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJLCBvciBudWxsIGlmIG5vbmUgaXMKLSAgICAgKiAgICAgICAgIGRlY2xhcmVkLiAgICAKLSAgICAgKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDIjZ2V0VVJJCi0gICAgICovCi0gICAgU3RyaW5nIGdldFVSSSAoU3RyaW5nIHByZWZpeCkKLSAgICB7Ci0gICAgICAgIGlmICgiIi5lcXVhbHMocHJlZml4KSkgewotICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHROUzsKLSAgICAgICAgfSBlbHNlIGlmIChwcmVmaXhUYWJsZSA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfSBlbHNlIHsKLSAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKXByZWZpeFRhYmxlLmdldChwcmVmaXgpOwotICAgICAgICB9Ci0gICAgfQotCi0KLSAgICAvKioKLSAgICAgKiBMb29rIHVwIG9uZSBvZiB0aGUgcHJlZml4ZXMgYXNzb2NpYXRlZCB3aXRoIGEgVVJJIGluIHRoaXMgY29udGV4dC4KLSAgICAgKgotICAgICAqIDxwPlNpbmNlIG1hbnkgcHJlZml4ZXMgbWF5IGJlIG1hcHBlZCB0byB0aGUgc2FtZSBVUkksCi0gICAgICogdGhlIHJldHVybiB2YWx1ZSBtYXkgYmUgdW5yZWxpYWJsZS48L3A+Ci0gICAgICoKLSAgICAgKiBAcGFyYW0gdXJpIFRoZSBVUkkgdG8gbG9vayB1cC4KLSAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIHByZWZpeCwgb3IgbnVsbCBpZiBub25lIGlzIGRlY2xhcmVkLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0MiNnZXRQcmVmaXgKLSAgICAgKi8KLSAgICBTdHJpbmcgZ2V0UHJlZml4IChTdHJpbmcgdXJpKQotICAgIHsKLSAgICAgICAgaWYgKHVyaVRhYmxlID09IG51bGwpIHsKLSAgICAgICAgICAgIHJldHVybiBudWxsOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIChTdHJpbmcpdXJpVGFibGUuZ2V0KHVyaSk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgICAgIAotICAgICAgICAKLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgcHJlZml4ZXMgZGVjbGFyZWQgaW4gdGhpcyBjb250ZXh0LgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAocG9zc2libHkgZW1wdHkpLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0MiNnZXREZWNsYXJlZFByZWZpeGVzCi0gICAgICovCi0gICAgRW51bWVyYXRpb24gZ2V0RGVjbGFyZWRQcmVmaXhlcyAoKQotICAgIHsKLSAgICAgICAgaWYgKGRlY2xhcmF0aW9ucyA9PSBudWxsKSB7Ci0gICAgICAgICAgICByZXR1cm4gRU1QVFlfRU5VTUVSQVRJT047Ci0gICAgICAgIH0gZWxzZSB7Ci0gICAgICAgICAgICByZXR1cm4gZGVjbGFyYXRpb25zLmVsZW1lbnRzKCk7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgICAgIAotICAgICAgICAKLSAgICAvKioKLSAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgYWxsIHByZWZpeGVzIGN1cnJlbnRseSBpbiBmb3JjZS4KLSAgICAgKgotICAgICAqIDxwPlRoZSBkZWZhdWx0IHByZWZpeCwgaWYgaW4gZm9yY2UsIGlzIDxlbT5ub3Q8L2VtPgotICAgICAqIHJldHVybmVkLCBhbmQgd2lsbCBoYXZlIHRvIGJlIGNoZWNrZWQgZm9yIHNlcGFyYXRlbHkuPC9wPgotICAgICAqCi0gICAgICogQHJldHVybiBBbiBlbnVtZXJhdGlvbiBvZiBwcmVmaXhlcyAobmV2ZXIgZW1wdHkpLgotICAgICAqIEBzZWUgb3JnLnhtbC5zYXguaGVscGVycy5OYW1lc3BhY2VTdXBwb3J0MiNnZXRQcmVmaXhlcwotICAgICAqLwotICAgIEVudW1lcmF0aW9uIGdldFByZWZpeGVzICgpCi0gICAgewotICAgICAgICBpZiAocHJlZml4VGFibGUgPT0gbnVsbCkgewotICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0VOVU1FUkFUSU9OOwotICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgcmV0dXJuIHByZWZpeFRhYmxlLmtleXMoKTsKLSAgICAgICAgfQotICAgIH0KLSAgICAgICAgCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIG1ldGhvZHMuCi0gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0gICAgLyoqCi0gICAgICogQ29weSBvbiB3cml0ZSBmb3IgdGhlIGludGVybmFsIHRhYmxlcyBpbiB0aGlzIGNvbnRleHQuCi0gICAgICoKLSAgICAgKiA8cD5UaGlzIGNsYXNzIGlzIG9wdGltaXplZCBmb3IgdGhlIG5vcm1hbCBjYXNlIHdoZXJlIG1vc3QKLSAgICAgKiBlbGVtZW50cyBkbyBub3QgY29udGFpbiBOYW1lc3BhY2UgZGVjbGFyYXRpb25zLiBJbiB0aGF0IGNhc2UsCi0gICAgICogdGhlIENvbnRleHQyIHdpbGwgc2hhcmUgZGF0YSBzdHJ1Y3R1cmVzIHdpdGggaXRzIHBhcmVudC4KLSAgICAgKiBOZXcgdGFibGVzIGFyZSBvYnRhaW5lZCBvbmx5IHdoZW4gbmV3IGRlY2xhcmF0aW9ucyBhcmUgaXNzdWVkLAotICAgICAqIHNvIHRoZXkgY2FuIGJlIHBvcHBlZCBvZmYgdGhlIHN0YWNrLjwvcD4KLSAgICAgKgotICAgICAqIDxwPiBKSks6ICoqKiogQWx0ZXJuYXRpdmU6IGVhY2ggQ29udGV4dDIgbWlnaHQgZGVjbGFyZQotICAgICAqICBfb25seV8gaXRzIGxvY2FsIGJpbmRpbmdzLCBhbmQgZGVsZWdhdGUgdXB3YXJkIGlmIG5vdCBmb3VuZC48L3A+Ci0gICAgICovICAgICAKLSAgICBwcml2YXRlIHZvaWQgY29weVRhYmxlcyAoKQotICAgIHsKLSAgICAgICAgLy8gU3RhcnQgYnkgY29weWluZyBvdXIgcGFyZW50J3MgYmluZGluZ3MKLSAgICAgICAgcHJlZml4VGFibGUgPSAoSGFzaHRhYmxlKXByZWZpeFRhYmxlLmNsb25lKCk7Ci0gICAgICAgIHVyaVRhYmxlID0gKEhhc2h0YWJsZSl1cmlUYWJsZS5jbG9uZSgpOwotCi0gICAgICAgIC8vIFJlcGxhY2UgdGhlIGNhY2hlcyB3aXRoIGVtcHR5IG9uZXMsIHJhdGhlciB0aGFuCi0gICAgICAgIC8vIHRyeWluZyB0byBkZXRlcm1pbmUgd2hpY2ggYmluZGluZ3Mgc2hvdWxkIGJlIGZsdXNoZWQuCi0gICAgICAgIC8vIEFzIGZhciBhcyBJIGNhbiB0ZWxsLCB0aGVzZSBjYWNoZXMgYXJlIG5ldmVyIGFjdHVhbGx5Ci0gICAgICAgIC8vIHVzZWQgaW4gWGFsYW4uLi4gTW9yZSBlZmZpY2llbnQgdG8gcmVtb3ZlIHRoZSB3aG9sZQotICAgICAgICAvLyBjYWNoZSBzeXN0ZW0/ICoqKioKLSAgICAgICAgaWYoZWxlbWVudE5hbWVUYWJsZSE9bnVsbCkKLSAgICAgICAgICAgIGVsZW1lbnROYW1lVGFibGU9bmV3IEhhc2h0YWJsZSgpOyAKLSAgICAgICAgaWYoYXR0cmlidXRlTmFtZVRhYmxlIT1udWxsKQotICAgICAgICAgICAgYXR0cmlidXRlTmFtZVRhYmxlPW5ldyBIYXNodGFibGUoKTsgCi0gICAgICAgIHRhYmxlc0RpcnR5ID0gdHJ1ZTsKLSAgICB9Ci0KLX0KLQotCi0vLyBlbmQgb2YgTmFtZXNwYWNlU3VwcG9ydDIuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL05vZGVDb25zdW1lci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL05vZGVDb25zdW1lci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZTI1ODhiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9Ob2RlQ29uc3VtZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlIHRyZWUgd2Fsa2VyIHdpbGwgdGVzdCBmb3IgdGhpcyBpbnRlcmZhY2UsIGFuZCBjYWxsCi0gKiBzZXRPcmlnaW5hdGluZ05vZGUgYmVmb3JlIGNhbGxpbmcgdGhlIFNBWCBldmVudC4gIEZvciBjcmVhdGluZwotICogRE9NIGJhY2twb2ludGVycyBmb3IgdGhpbmdzIHRoYXQgYXJlIG5vcm1hbGx5IGNyZWF0ZWQgdmlhCi0gKiBTQVggZXZlbnRzLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIE5vZGVDb25zdW1lcgotewotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5vZGUgdGhhdCBpcyBvcmlnaW5hdGluZyB0aGUgU0FYIGV2ZW50LgotICAgKgotICAgKiBAcGFyYW0gbiBSZWZlcmVuY2UgdG8gbm9kZSB0aGF0IG9yaWdpbmF0ZWQgdGhlIGN1cnJlbnQgZXZlbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRPcmlnaW5hdGluZ05vZGUoTm9kZSBuKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9Ob2RlVmVjdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvTm9kZVZlY3Rvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjY2YwZmJjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9Ob2RlVmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NzUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBOb2Rlcy4KLSAqLwotcHVibGljIGNsYXNzIE5vZGVWZWN0b3IgaW1wbGVtZW50cyBTZXJpYWxpemFibGUsIENsb25lYWJsZQotewotCi0gIC8qKgotICAgKiBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZS4KLSAgICogIEBzZXJpYWwgICAgICAgICAgCi0gICAqLwotICBwcml2YXRlIGludCBtX2Jsb2Nrc2l6ZTsKLQotICAvKioKLSAgICogQXJyYXkgb2Ygbm9kZXMgdGhpcyBwb2ludHMgdG8uCi0gICAqICBAc2VyaWFsICAgICAgICAgIAotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBbXTsKLQotICAvKioKLSAgICogTnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgTm9kZVZlY3Rvci4KLSAgICogIEBzZXJpYWwgICAgICAgICAgCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKioKLSAgICogU2l6ZSBvZiB0aGUgYXJyYXkgdGhpcyBwb2ludHMgdG8uCi0gICAqICBAc2VyaWFsICAgICAgICAgICAKLSAgICovCi0gIHByaXZhdGUgaW50IG1fbWFwU2l6ZTsgIC8vIGxhenkgaW5pdGlhbGl6YXRpb24KLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KLSAgICovCi0gIHB1YmxpYyBOb2RlVmVjdG9yKCkKLSAgewotICAgIG1fYmxvY2tzaXplID0gMzI7Ci0gICAgbV9tYXBTaXplID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBOb2RlVmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIE5vZGVWZWN0b3IoaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMKLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlVmVjdG9yIGNsb25lID0gKE5vZGVWZWN0b3IpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICBpZiAoKG51bGwgIT0gdGhpcy5tX21hcCkgJiYgKHRoaXMubV9tYXAgPT0gY2xvbmUubV9tYXApKQotICAgIHsKLSAgICAgIGNsb25lLm1fbWFwID0gbmV3IGludFt0aGlzLm1fbWFwLmxlbmd0aF07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5tX21hcCwgMCwgY2xvbmUubV9tYXAsIDAsIHRoaXMubV9tYXAubGVuZ3RoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgTm9kZVZlY3RvcgotICAgKi8KLSAgcHVibGljIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBOb2RlIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gYWRkIHRvIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEVsZW1lbnQoaW50IHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgewotICAgICAgICBtX21hcCA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gdmFsdWU7Ci0KLSAgICBtX2ZpcnN0RnJlZSsrOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIE5vZGUgb250byB0aGUgdmVjdG9yLgotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgTm9kZSB0byBhZGQgdG8gdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaChpbnQgdmFsdWUpCi0gIHsKLQotICAgIGludCBmZiA9IG1fZmlyc3RGcmVlOwotCi0gICAgaWYgKChmZiArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHsKLSAgICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBmZiArIDEpOwotCi0gICAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgICAgfQotICAgIH0KLQotICAgIG1fbWFwW2ZmXSA9IHZhbHVlOwotCi0gICAgZmYrKzsKLQotICAgIG1fZmlyc3RGcmVlID0gZmY7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIGEgbm9kZSBmcm9tIHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3IgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcG9wKCkKLSAgewotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIGludCBuID0gbV9tYXBbbV9maXJzdEZyZWVdOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBub2RlIGZyb20gdGhlIHRhaWwgb2YgdGhlIHZlY3RvciBhbmQgcmV0dXJuIHRoZQotICAgKiB0b3Agb2YgdGhlIHN0YWNrIGFmdGVyIHRoZSBwb3AuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRvcCBvZiB0aGUgc3RhY2sgYWZ0ZXIgaXQncyBiZWVuIHBvcHBlZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBwb3BBbmRUb3AoKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gKG1fZmlyc3RGcmVlID09IDApID8gRFRNLk5VTEwgOiBtX21hcFttX2ZpcnN0RnJlZSAtIDFdOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCBhIG5vZGUgZnJvbSB0aGUgdGFpbCBvZiB0aGUgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wUXVpY2soKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0b3Agb2YgdGhlIHN0YWNrIHdpdGhvdXQgcG9wcGluZyB0aGUgc3RhY2suCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgb3IgbnVsbCBpZiBzdGFjayBpcyBlbXB0eS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcGVlcE9yTnVsbCgpCi0gIHsKLSAgICByZXR1cm4gKChudWxsICE9IG1fbWFwKSAmJiAobV9maXJzdEZyZWUgPiAwKSkKLSAgICAgICAgICAgPyBtX21hcFttX2ZpcnN0RnJlZSAtIDFdIDogRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogUHVzaCBhIHBhaXIgb2Ygbm9kZXMgaW50byB0aGUgc3RhY2suCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gdjEgRmlyc3Qgbm9kZSB0byBhZGQgdG8gdmVjdG9yCi0gICAqIEBwYXJhbSB2MiBTZWNvbmQgbm9kZSB0byBhZGQgdG8gdmVjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoUGFpcihpbnQgdjEsIGludCB2MikKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKChtX2ZpcnN0RnJlZSArIDIpID49IG1fbWFwU2l6ZSkKLSAgICAgIHsKLSAgICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICAgIGludCBuZXdNYXBbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlKTsKLQotICAgICAgICBtX21hcCA9IG5ld01hcDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2MTsKLSAgICBtX21hcFttX2ZpcnN0RnJlZSArIDFdID0gdjI7Ci0gICAgbV9maXJzdEZyZWUgKz0gMjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBwYWlyIG9mIG5vZGVzIGZyb20gdGhlIHRhaWwgb2YgdGhlIHN0YWNrLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcFBhaXIoKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZSAtPSAyOwotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IERUTS5OVUxMOwotICAgIG1fbWFwW21fZmlyc3RGcmVlICsgMV0gPSBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHRhaWwgb2YgdGhlIHN0YWNrIHRvIHRoZSBnaXZlbiBub2RlLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBzZXQgYXQgdGhlIHRhaWwgb2YgdmVjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRUYWlsKGludCBuKQotICB7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgLSAxXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBnaXZlbiBub2RlIG9uZSBwb3NpdGlvbiBmcm9tIHRoZSB0YWlsLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBzZXQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFRhaWxTdWIxKGludCBuKQotICB7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgLSAyXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3Igd2l0aG91dCBwb3BwaW5nCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgdGhlIHRhaWwgb2YgdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBwZWVwVGFpbCgpCi0gIHsKLSAgICByZXR1cm4gbV9tYXBbbV9maXJzdEZyZWUgLSAxXTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgb25lIHBvc2l0aW9uIGZyb20gdGhlIHRhaWwgd2l0aG91dCBwb3BwaW5nLgotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICoKLSAgICogQHJldHVybiBOb2RlIG9uZSBhd2F5IGZyb20gdGhlIHRhaWwKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgcGVlcFRhaWxTdWIxKCkKLSAgewotICAgIHJldHVybiBtX21hcFttX2ZpcnN0RnJlZSAtIDJdOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhIG5vZGUgaW4gb3JkZXIgaW4gdGhlIGxpc3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBOb2RlIHRvIGluc2VydAotICAgKi8KLSAgcHVibGljIHZvaWQgaW5zZXJ0SW5PcmRlcihpbnQgdmFsdWUpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAodmFsdWUgPCBtX21hcFtpXSkKLSAgICAgIHsKLSAgICAgICAgaW5zZXJ0RWxlbWVudEF0KHZhbHVlLCBpKTsKLQotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0gICAgfQotCi0gICAgYWRkRWxlbWVudCh2YWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBQb3NpdGlvbiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLSAgICBlbHNlIGlmICgobV9maXJzdEZyZWUgKyAxKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgaWYgKGF0IDw9IChtX2ZpcnN0RnJlZSAtIDEpKQotICAgIHsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGF0LCBtX21hcCwgYXQgKyAxLCBtX2ZpcnN0RnJlZSAtIGF0KTsKLSAgICB9Ci0KLSAgICBtX21hcFthdF0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHRoZSBub2RlcyB0byB0aGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVzIE5vZGVWZWN0b3IgdG8gYXBwZW5kIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kTm9kZXMoTm9kZVZlY3RvciBub2RlcykKLSAgewotCi0gICAgaW50IG5Ob2RlcyA9IG5vZGVzLnNpemUoKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSA9IG5Ob2RlcyArIG1fYmxvY2tzaXplOwotICAgICAgbV9tYXAgPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0gICAgfQotICAgIGVsc2UgaWYgKChtX2ZpcnN0RnJlZSArIG5Ob2RlcykgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSAobk5vZGVzICsgbV9ibG9ja3NpemUpOwotCi0gICAgICBpbnQgbmV3TWFwW10gPSBuZXcgaW50W21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyBuTm9kZXMpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KG5vZGVzLm1fbWFwLCAwLCBtX21hcCwgbV9maXJzdEZyZWUsIG5Ob2Rlcyk7Ci0KLSAgICBtX2ZpcnN0RnJlZSArPSBuTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm47Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgbV9tYXBbaV0gPSBEVE0uTlVMTDsKLSAgICB9Ci0KLSAgICBtX2ZpcnN0RnJlZSA9IDA7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGxlbmd0aCB0byB6ZXJvLCBidXQgZG9uJ3QgY2xlYXIgdGhlIGFycmF5LgotICAgKi8KLSAgcHVibGljIHZvaWQgUmVtb3ZlQWxsTm9DbGVhcigpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuOwotCi0gICAgbV9maXJzdEZyZWUgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGZyb20gdGhpcyB2ZWN0b3IuCi0gICAqIElmIHRoZSBvYmplY3QgaXMgZm91bmQgaW4gdGhpcyB2ZWN0b3IsIGVhY2ggY29tcG9uZW50IGluIHRoZSB2ZWN0b3IKLSAgICogd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBvYmplY3QncyBpbmRleCBpcyBzaGlmdGVkCi0gICAqIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbiB0aGUgdmFsdWUgaXQgaGFkCi0gICAqIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBzIE5vZGUgdG8gcmVtb3ZlIGZyb20gdGhlIGxpc3QKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gcmVtb3ZlRWxlbWVudChpbnQgcykKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaW50IG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKG5vZGUgPT0gcykKLSAgICAgIHsKLSAgICAgICAgaWYgKGkgPiBtX2ZpcnN0RnJlZSkKLSAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCBpICsgMSwgbV9tYXAsIGkgLSAxLCBtX2ZpcnN0RnJlZSAtIGkpOwotICAgICAgICBlbHNlCi0gICAgICAgICAgbV9tYXBbaV0gPSBEVE0uTlVMTDsKLQotICAgICAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWxldGVzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gRWFjaCBjb21wb25lbnQgaW4KLSAgICogdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXggaXMgc2hpZnRlZCBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4KLSAgICogdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBub2RlIHRvIHJlbW92ZQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlRWxlbWVudEF0KGludCBpKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybjsKLQotICAgIGlmIChpID4gbV9maXJzdEZyZWUpCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCBpICsgMSwgbV9tYXAsIGkgLSAxLCBtX2ZpcnN0RnJlZSAtIGkpOwotICAgIGVsc2UKLSAgICAgIG1fbWFwW2ldID0gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gc2V0Ci0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzZXQgdGhlIG5vZGUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVsZW1lbnRBdChpbnQgbm9kZSwgaW50IGluZGV4KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICB7Ci0gICAgICBtX21hcCA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgfQotCi0gICAgbV9tYXBbaW5kZXhdID0gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBub2RlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgc3BlY2lmaWVkIGluZGV4Ci0gICAqLwotICBwdWJsaWMgaW50IGVsZW1lbnRBdChpbnQgaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIE5vZGUgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiBub2RlIHdhcyBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGludCBzKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpbnQgbm9kZSA9IG1fbWFwW2ldOwotCi0gICAgICBpZiAobm9kZSA9PSBzKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBOb2RlIHRvIGxvb2sgZm9yCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzdGFydCB0aGUgc2VhcmNoCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgZWxlbSwgaW50IGluZGV4KQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiAtMTsKLQotICAgIGZvciAoaW50IGkgPSBpbmRleDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgaW50IG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKG5vZGUgPT0gZWxlbSkKLSAgICAgICAgcmV0dXJuIGk7Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gTm9kZSB0byBsb29rIGZvcgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0Ci0gICAqIGFyZ3VtZW50IGluIHRoaXMgdmVjdG9yIGF0IHBvc2l0aW9uIGluZGV4IG9yIGxhdGVyIGluIHRoZQotICAgKiB2ZWN0b3I7IHJldHVybnMgLTEgaWYgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGVsZW0pCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIC0xOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGludCBub2RlID0gbV9tYXBbaV07Ci0KLSAgICAgIGlmIChub2RlID09IGVsZW0pCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBTb3J0IGFuIGFycmF5IHVzaW5nIGEgcXVpY2tzb3J0IGFsZ29yaXRobS4KLSAgICoKLSAgICogQHBhcmFtIGEgVGhlIGFycmF5IHRvIGJlIHNvcnRlZC4KLSAgICogQHBhcmFtIGxvMCAgVGhlIGxvdyBpbmRleC4KLSAgICogQHBhcmFtIGhpMCAgVGhlIGhpZ2ggaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzb3J0KGludCBhW10sIGludCBsbzAsIGludCBoaTApIHRocm93cyBFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGxvID0gbG8wOwotICAgIGludCBoaSA9IGhpMDsKLQotICAgIC8vIHBhdXNlKGxvLCBoaSk7Ci0gICAgaWYgKGxvID49IGhpKQotICAgIHsKLSAgICAgIHJldHVybjsKLSAgICB9Ci0gICAgZWxzZSBpZiAobG8gPT0gaGkgLSAxKQotICAgIHsKLQotICAgICAgLyoKLSAgICAgICAqICBzb3J0IGEgdHdvIGVsZW1lbnQgbGlzdCBieSBzd2FwcGluZyBpZiBuZWNlc3NhcnkKLSAgICAgICAqLwotICAgICAgaWYgKGFbbG9dID4gYVtoaV0pCi0gICAgICB7Ci0gICAgICAgIGludCBUID0gYVtsb107Ci0KLSAgICAgICAgYVtsb10gPSBhW2hpXTsKLSAgICAgICAgYVtoaV0gPSBUOwotICAgICAgfQotCi0gICAgICByZXR1cm47Ci0gICAgfQotCi0gICAgLyoKLSAgICAgKiAgUGljayBhIHBpdm90IGFuZCBtb3ZlIGl0IG91dCBvZiB0aGUgd2F5Ci0gICAgICovCi0gICAgaW50IHBpdm90ID0gYVsobG8gKyBoaSkgLyAyXTsKLQotICAgIGFbKGxvICsgaGkpIC8gMl0gPSBhW2hpXTsKLSAgICBhW2hpXSA9IHBpdm90OwotCi0gICAgd2hpbGUgKGxvIDwgaGkpCi0gICAgewotCi0gICAgICAvKgotICAgICAgICogIFNlYXJjaCBmb3J3YXJkIGZyb20gYVtsb10gdW50aWwgYW4gZWxlbWVudCBpcyBmb3VuZCB0aGF0Ci0gICAgICAgKiAgaXMgZ3JlYXRlciB0aGFuIHRoZSBwaXZvdCBvciBsbyA+PSBoaQotICAgICAgICovCi0gICAgICB3aGlsZSAoYVtsb10gPD0gcGl2b3QgJiYgbG8gPCBoaSkKLSAgICAgIHsKLSAgICAgICAgbG8rKzsKLSAgICAgIH0KLQotICAgICAgLyoKLSAgICAgICAqICBTZWFyY2ggYmFja3dhcmQgZnJvbSBhW2hpXSB1bnRpbCBlbGVtZW50IGlzIGZvdW5kIHRoYXQKLSAgICAgICAqICBpcyBsZXNzIHRoYW4gdGhlIHBpdm90LCBvciBsbyA+PSBoaQotICAgICAgICovCi0gICAgICB3aGlsZSAocGl2b3QgPD0gYVtoaV0gJiYgbG8gPCBoaSkKLSAgICAgIHsKLSAgICAgICAgaGktLTsKLSAgICAgIH0KLQotICAgICAgLyoKLSAgICAgICAqICBTd2FwIGVsZW1lbnRzIGFbbG9dIGFuZCBhW2hpXQotICAgICAgICovCi0gICAgICBpZiAobG8gPCBoaSkKLSAgICAgIHsKLSAgICAgICAgaW50IFQgPSBhW2xvXTsKLQotICAgICAgICBhW2xvXSA9IGFbaGldOwotICAgICAgICBhW2hpXSA9IFQ7Ci0KLSAgICAgICAgLy8gcGF1c2UoKTsKLSAgICAgIH0KLQotICAgICAgLy8gaWYgKHN0b3BSZXF1ZXN0ZWQpIHsKLSAgICAgIC8vICAgIHJldHVybjsKLSAgICAgIC8vIH0KLSAgICB9Ci0KLSAgICAvKgotICAgICAqICBQdXQgdGhlIG1lZGlhbiBpbiB0aGUgImNlbnRlciIgb2YgdGhlIGxpc3QKLSAgICAgKi8KLSAgICBhW2hpMF0gPSBhW2hpXTsKLSAgICBhW2hpXSA9IHBpdm90OwotCi0gICAgLyoKLSAgICAgKiAgUmVjdXJzaXZlIGNhbGxzLCBlbGVtZW50cyBhW2xvMF0gdG8gYVtsby0xXSBhcmUgbGVzcyB0aGFuIG9yCi0gICAgICogIGVxdWFsIHRvIHBpdm90LCBlbGVtZW50cyBhW2hpKzFdIHRvIGFbaGkwXSBhcmUgZ3JlYXRlciB0aGFuCi0gICAgICogIHBpdm90LgotICAgICAqLwotICAgIHNvcnQoYSwgbG8wLCBsbyAtIDEpOwotICAgIHNvcnQoYSwgaGkgKyAxLCBoaTApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNvcnQgYW4gYXJyYXkgdXNpbmcgYSBxdWlja3NvcnQgYWxnb3JpdGhtLgotICAgKgotICAgKiBAcGFyYW0gYSBUaGUgYXJyYXkgdG8gYmUgc29ydGVkLgotICAgKiBAcGFyYW0gbG8wICBUaGUgbG93IGluZGV4LgotICAgKiBAcGFyYW0gaGkwICBUaGUgaGlnaCBpbmRleC4KLSAgICoKLSAgICogQHRocm93cyBFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNvcnQoKSB0aHJvd3MgRXhjZXB0aW9uCi0gIHsKLSAgICBzb3J0KG1fbWFwLCAwLCBtX2ZpcnN0RnJlZSAtIDEpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvT2JqZWN0UG9vbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL09iamVjdFBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTZlMTkzMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvT2JqZWN0UG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjEzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFBvb2wgb2Ygb2JqZWN0IG9mIGEgZ2l2ZW4gdHlwZSB0byBwaWNrIGZyb20gdG8gaGVscCBtZW1vcnkgdXNhZ2UKLSAqLwotcHVibGljIGNsYXNzIE9iamVjdFBvb2wgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZQotewotCi0gIC8qKiBUeXBlIG9mIG9iamVjdHMgaW4gdGhpcyBwb29sLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIGZpbmFsIENsYXNzIG9iamVjdFR5cGU7Ci0KLSAgLyoqIFZlY3RvciBvZiBnaXZlbiBvYmplY3RzIHRoaXMgcG9pbnRzIHRvLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIGZpbmFsIFZlY3RvciBmcmVlU3RhY2s7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE9iamVjdFBvb2wKLSAgICoKLSAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBvYmplY3RzIGZvciB0aGlzIHBvb2wKLSAgICovCi0gIHB1YmxpYyBPYmplY3RQb29sKENsYXNzIHR5cGUpCi0gIHsKLSAgICBvYmplY3RUeXBlID0gdHlwZTsKLSAgICBmcmVlU3RhY2sgPSBuZXcgVmVjdG9yKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBPYmplY3RQb29sCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc05hbWUgRnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgb2Ygb2JqZWN0cyBmb3IgdGhpcyBwb29sLgotICAgKi8KLSAgcHVibGljIE9iamVjdFBvb2woU3RyaW5nIGNsYXNzTmFtZSkKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIG9iamVjdFR5cGUgPSBDbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSk7Ci0gICAgfQotICAgIGNhdGNoKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oY25mZSk7Ci0gICAgfQotICAgIGZyZWVTdGFjayA9IG5ldyBWZWN0b3IoKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIE9iamVjdFBvb2wKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBvYmplY3RzIGZvciB0aGlzIHBvb2wKLSAgICogQHBhcmFtIHNpemUgU2l6ZSBvZiB2ZWN0b3IgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBPYmplY3RQb29sKENsYXNzIHR5cGUsIGludCBzaXplKQotICB7Ci0gICAgb2JqZWN0VHlwZSA9IHR5cGU7Ci0gICAgZnJlZVN0YWNrID0gbmV3IFZlY3RvcihzaXplKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBPYmplY3RQb29sCi0gICAqCi0gICAqLwotICBwdWJsaWMgT2JqZWN0UG9vbCgpCi0gIHsKLSAgICBvYmplY3RUeXBlID0gbnVsbDsKLSAgICBmcmVlU3RhY2sgPSBuZXcgVmVjdG9yKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QgaW4gdGhpcyBwb29sIGlmIGF2YWlsYWJsZQotICAgKgotICAgKgotICAgKiBAcmV0dXJuIGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QgaWYgYXZhaWxhYmxlIG9yIG51bGwKLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGdldEluc3RhbmNlSWZGcmVlKCkKLSAgewotCi0gICAgLy8gQ2hlY2sgaWYgdGhlIHBvb2wgaXMgZW1wdHkuCi0gICAgaWYgKCFmcmVlU3RhY2suaXNFbXB0eSgpKQotICAgIHsKLQotICAgICAgLy8gUmVtb3ZlIG9iamVjdCBmcm9tIGVuZCBvZiBmcmVlIHBvb2wuCi0gICAgICBPYmplY3QgcmVzdWx0ID0gZnJlZVN0YWNrLmxhc3RFbGVtZW50KCk7Ci0KLSAgICAgIGZyZWVTdGFjay5zZXRTaXplKGZyZWVTdGFjay5zaXplKCkgLSAxKTsKLQotICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdCBpbiB0aGlzIHBvb2wgCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIG9iamVjdAotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0SW5zdGFuY2UoKQotICB7Ci0KLSAgICAvLyBDaGVjayBpZiB0aGUgcG9vbCBpcyBlbXB0eS4KLSAgICBpZiAoZnJlZVN0YWNrLmlzRW1wdHkoKSkKLSAgICB7Ci0KLSAgICAgIC8vIENyZWF0ZSBhIG5ldyBvYmplY3QgaWYgc28uCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG9iamVjdFR5cGUubmV3SW5zdGFuY2UoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGV4KXt9Ci0gICAgICBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCl7fQotCi0gICAgICAvLyBUaHJvdyB1bmNoZWNrZWQgZXhjZXB0aW9uIGZvciBlcnJvciBpbiBwb29sIGNvbmZpZ3VyYXRpb24uCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9FWENFUFRJT05fQ1JFQVRJTkdfUE9PTCwgbnVsbCkpOyAvLyJleGNlcHRpb24gY3JlYXRpbmcgbmV3IGluc3RhbmNlIGZvciBwb29sIik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIFJlbW92ZSBvYmplY3QgZnJvbSBlbmQgb2YgZnJlZSBwb29sLgotICAgICAgT2JqZWN0IHJlc3VsdCA9IGZyZWVTdGFjay5sYXN0RWxlbWVudCgpOwotCi0gICAgICBmcmVlU3RhY2suc2V0U2l6ZShmcmVlU3RhY2suc2l6ZSgpIC0gMSk7Ci0KLSAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gb2JqZWN0IHRvIHRoZSBwb29sICAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iaiBPYmplY3QgdG8gYWRkLgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZyZWVJbnN0YW5jZShPYmplY3Qgb2JqKQotICB7Ci0KLSAgICAvLyBNYWtlIHN1cmUgdGhlIG9iamVjdCBpcyBvZiB0aGUgY29ycmVjdCB0eXBlLgotICAgIC8vIFJlbW92ZSBzYWZldHkuICAtc2IKLSAgICAvLyBpZiAob2JqZWN0VHlwZS5pc0luc3RhbmNlKG9iaikpCi0gICAgLy8gewotICAgIGZyZWVTdGFjay5hZGRFbGVtZW50KG9iaik7Ci0gICAgLy8gfQotICAgIC8vIGVsc2UKLSAgICAvLyB7Ci0gICAgLy8gIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImFyZ3VtZW50IHR5cGUgaW52YWxpZCBmb3IgcG9vbCIpOwotICAgIC8vIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1ByZWZpeFJlc29sdmVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvUHJlZml4UmVzb2x2ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmY2MTJkYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvUHJlZml4UmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoZSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgY2FuIHJlc29sdmUgcHJlZml4ZXMgdG8KLSAqIG5hbWVzcGFjZXMuIEV4YW1wbGVzIHdvdWxkIGluY2x1ZGUgcmVzb2x2aW5nIHRoZSBtZWFuaW5nIG9mIGEKLSAqIHByZWZpeCBhdCBhIHBhcnRpY3VsYXIgcG9pbnQgaW4gYSBkb2N1bWVudCwgb3IgbWFwcGluZyB0aGUgcHJlZml4ZXMKLSAqIHVzZWQgaW4gYW4gWFBhdGggZXhwcmVzc2lvbi4KLSAqLwotcHVibGljIGludGVyZmFjZSBQcmVmaXhSZXNvbHZlcgotewotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSwgZ2V0IHRoZSBjb3JyaXNwb25kaW5nIHByZWZpeC4gIFRoaXMgYXNzdW1lcyB0aGF0Ci0gICAqIHRoZSBQcmVmaXhSZXNvbHZlciBob2xkcyBpdHMgb3duIG5hbWVzcGFjZSBjb250ZXh0LCBvciBpcyBhIG5hbWVzcGFjZQotICAgKiBjb250ZXh0IGl0c2VsZi4KLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IHRvIGxvb2sgdXAsIHdoaWNoIG1heSBiZSBhbiBlbXB0eSBzdHJpbmcgKCIiKSBmb3IgdGhlIGRlZmF1bHQgTmFtZXNwYWNlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIE5hbWVzcGFjZSBVUkksIG9yIG51bGwgaWYgdGhlIHByZWZpeAotICAgKiAgICAgICAgIGlzIHVuZGVjbGFyZWQgaW4gdGhpcyBjb250ZXh0LgotICAgKi8KLSAgU3RyaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeChTdHJpbmcgcHJlZml4KTsKLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UsIGdldCB0aGUgY29ycmVzcG9uZGluZyBwcmVmaXgsIGJhc2VkIG9uIHRoZSBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCB0byBsb29rIHVwLCB3aGljaCBtYXkgYmUgYW4gZW1wdHkgc3RyaW5nICgiIikgZm9yIHRoZSBkZWZhdWx0IE5hbWVzcGFjZS4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIG5vZGUgY29udGV4dCBmcm9tIHdoaWNoIHRvIGxvb2sgdXAgdGhlIFVSSS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRlZCBOYW1lc3BhY2UgVVJJIGFzIGEgc3RyaW5nLCBvciBudWxsIGlmIHRoZSBwcmVmaXgKLSAgICogICAgICAgICBpcyB1bmRlY2xhcmVkIGluIHRoaXMgY29udGV4dC4KLSAgICovCi0gIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCwgb3JnLnczYy5kb20uTm9kZSBjb250ZXh0KTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBiYXNlIGlkZW50aWZpZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGJhc2UgaWRlbnRpZmllciBmcm9tIHdoZXJlIHJlbGF0aXZlIFVSSXMgc2hvdWxkIGJlIGFic29sdXRpemVkLCBvciBudWxsIAotICAgKiBpZiB0aGUgYmFzZSBJRCBpcyB1bmtub3duLgotICAgKiA8cD4KLSAgICogQ0FWRUFUOiBOb3RlIHRoYXQgdGhlIGJhc2UgVVJJIGluIGFuIFhNTCBkb2N1bWVudCBtYXkgdmFyeSB3aXRoIHdoZXJlCi0gICAqIHlvdSBhcmUgaW4gdGhlIGRvY3VtZW50LCBpZiBwYXJ0IG9mIHRoZSBkb2MncyBjb250ZW50cyB3ZXJlIGJyb3VnaHQgaW4KLSAgICogdmlhIGFuIGV4dGVybmFsIGVudGl0eSByZWZlcmVuY2Ugb3IgaWYgbWVjaGFuaXNtcyBzdWNoIGFzIHhtbDpiYXNlIGhhdmUKLSAgICogYmVlbiB1c2VkLiBVbmxlc3MgdGhpcyBQcmVmaXhSZXNvbHZlciBpcyBib3VuZCB0byBhIHNwZWNpZmljIHBvcnRpb24gb2YKLSAgICogdGhlIGRvY3VtZW50LCBvciBoYXMgYmVlbiBrZXB0IHVwIHRvIGRhdGUgdmlhIHNvbWUgb3RoZXIgbWVjaGFuaXNtLCBpdAotICAgKiBtYXkgbm90IGFjY3VyYXRlbHkgcmVmbGVjdCB0aGF0IGNvbnRleHQgaW5mb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEJhc2VJZGVudGlmaWVyKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvUHJlZml4UmVzb2x2ZXJEZWZhdWx0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvUHJlZml4UmVzb2x2ZXJEZWZhdWx0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRiMmM4NDcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1ByZWZpeFJlc29sdmVyRGVmYXVsdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGdlbmVyaWMgUHJlZml4UmVzb2x2ZXIgdGhhdAotICogY2FuIGJlIHVzZWQgdG8gcGVyZm9ybSBwcmVmaXgtdG8tbmFtZXNwYWNlIGxvb2t1cAotICogZm9yIHRoZSBYUGF0aCBvYmplY3QuCi0gKi8KLXB1YmxpYyBjbGFzcyBQcmVmaXhSZXNvbHZlckRlZmF1bHQgaW1wbGVtZW50cyBQcmVmaXhSZXNvbHZlcgotewotCi0gIC8qKgotICAgKiBUaGUgY29udGV4dCB0byByZXNvbHZlIHRoZSBwcmVmaXggZnJvbSwgaWYgdGhlIGNvbnRleHQKLSAgICogaXMgbm90IGdpdmVuLgotICAgKi8KLSAgTm9kZSBtX2NvbnRleHQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBVUkkgZm9yIHRoZSBYTUwgbmFtZXNwYWNlLgotICAgKiAoRHVwbGljYXRlIG9mIHRoYXQgZm91bmQgaW4gb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQpLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU19YTUxOQU1FU1BBQ0VVUkkgPQotICAgICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBQcmVmaXhSZXNvbHZlckRlZmF1bHQgb2JqZWN0LgotICAgKiBAcGFyYW0geHBhdGhFeHByZXNzaW9uQ29udGV4dCBUaGUgY29udGV4dCBmcm9tCi0gICAqIHdoaWNoIFhQYXRoIGV4cHJlc3Npb24gcHJlZml4ZXMgd2lsbCBiZSByZXNvbHZlZC4KLSAgICogV2FybmluZzogVGhpcyB3aWxsIG5vdCB3b3JrIGNvcnJlY3RseSBpZiB4cGF0aEV4cHJlc3Npb25Db250ZXh0Ci0gICAqIGlzIGFuIGF0dHJpYnV0ZSBub2RlLgotICAgKiBAcGFyYW0geHBhdGhFeHByZXNzaW9uQ29udGV4dCBOb2RlIGZyb20gd2hpY2ggdG8gc3RhcnQgc2VhcmNoaW5nIGZvciBhCi0gICAqIHhtbG5zIGF0dHJpYnV0ZSB0aGF0IGJpbmRzIGEgcHJlZml4IHRvIGEgbmFtZXNwYWNlICh3aGVuIHRoZSBuYW1lc3BhY2UKLSAgICogY29udGV4dCBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBnZXROYW1lc3BhY2VGb3JQcmVmaXggY2FsbCkuCi0gICAqLwotICBwdWJsaWMgUHJlZml4UmVzb2x2ZXJEZWZhdWx0KE5vZGUgeHBhdGhFeHByZXNzaW9uQ29udGV4dCkKLSAgewotICAgIG1fY29udGV4dCA9IHhwYXRoRXhwcmVzc2lvbkNvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBuYW1lc3BhY2UsIGdldCB0aGUgY29ycmlzcG9uZGluZyBwcmVmaXguICBUaGlzIGFzc3VtZXMgdGhhdAotICAgKiB0aGUgUHJldml4UmVzb2x2ZXIgaG9sZCdzIGl0J3Mgb3duIG5hbWVzcGFjZSBjb250ZXh0LCBvciBpcyBhIG5hbWVzcGFjZQotICAgKiBjb250ZXh0IGl0c2VsZi4KLSAgICogQHBhcmFtIHByZWZpeCBQcmVmaXggdG8gcmVzb2x2ZS4KLSAgICogQHJldHVybiBOYW1lc3BhY2UgdGhhdCBwcmVmaXggcmVzb2x2ZXMgdG8sIG9yIG51bGwgaWYgcHJlZml4Ci0gICAqIGlzIG5vdCBib3VuZC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlRm9yUHJlZml4KFN0cmluZyBwcmVmaXgpCi0gIHsKLSAgICByZXR1cm4gZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCwgbV9jb250ZXh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIG5hbWVzcGFjZSwgZ2V0IHRoZSBjb3JyaXNwb25kaW5nIHByZWZpeC4KLSAgICogV2FybmluZzogVGhpcyB3aWxsIG5vdCB3b3JrIGNvcnJlY3RseSBpZiBuYW1lc3BhY2VDb250ZXh0Ci0gICAqIGlzIGFuIGF0dHJpYnV0ZSBub2RlLgotICAgKiBAcGFyYW0gcHJlZml4IFByZWZpeCB0byByZXNvbHZlLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBOb2RlIGZyb20gd2hpY2ggdG8gc3RhcnQgc2VhcmNoaW5nIGZvciBhCi0gICAqIHhtbG5zIGF0dHJpYnV0ZSB0aGF0IGJpbmRzIGEgcHJlZml4IHRvIGEgbmFtZXNwYWNlLgotICAgKiBAcmV0dXJuIE5hbWVzcGFjZSB0aGF0IHByZWZpeCByZXNvbHZlcyB0bywgb3IgbnVsbCBpZiBwcmVmaXgKLSAgICogaXMgbm90IGJvdW5kLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VGb3JQcmVmaXgoU3RyaW5nIHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLnczYy5kb20uTm9kZSBuYW1lc3BhY2VDb250ZXh0KQotICB7Ci0KLSAgICBOb2RlIHBhcmVudCA9IG5hbWVzcGFjZUNvbnRleHQ7Ci0gICAgU3RyaW5nIG5hbWVzcGFjZSA9IG51bGw7Ci0KLSAgICBpZiAocHJlZml4LmVxdWFscygieG1sIikpCi0gICAgewotICAgICAgbmFtZXNwYWNlID0gU19YTUxOQU1FU1BBQ0VVUkk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgdHlwZTsKLQotICAgICAgd2hpbGUgKChudWxsICE9IHBhcmVudCkgJiYgKG51bGwgPT0gbmFtZXNwYWNlKQotICAgICAgICAgICAgICYmICgoKHR5cGUgPSBwYXJlbnQuZ2V0Tm9kZVR5cGUoKSkgPT0gTm9kZS5FTEVNRU5UX05PREUpCi0gICAgICAgICAgICAgICAgIHx8ICh0eXBlID09IE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFKSkpCi0gICAgICB7Ci0gICAgICAgIGlmICh0eXBlID09IE5vZGUuRUxFTUVOVF9OT0RFKQotICAgICAgICB7Ci0gICAgICAgICAgTmFtZWROb2RlTWFwIG5ubSA9IHBhcmVudC5nZXRBdHRyaWJ1dGVzKCk7Ci0KLSAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5ubS5nZXRMZW5ndGgoKTsgaSsrKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIE5vZGUgYXR0ciA9IG5ubS5pdGVtKGkpOwotICAgICAgICAgICAgU3RyaW5nIGFuYW1lID0gYXR0ci5nZXROb2RlTmFtZSgpOwotICAgICAgICAgICAgYm9vbGVhbiBpc1ByZWZpeCA9IGFuYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpOwotCi0gICAgICAgICAgICBpZiAoaXNQcmVmaXggfHwgYW5hbWUuZXF1YWxzKCJ4bWxucyIpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpbnQgaW5kZXggPSBhbmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgICAgICAgICAgIFN0cmluZyBwID0gaXNQcmVmaXggPyBhbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKSA6ICIiOwotCi0gICAgICAgICAgICAgIGlmIChwLmVxdWFscyhwcmVmaXgpKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gYXR0ci5nZXROb2RlVmFsdWUoKTsKLQotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgcGFyZW50ID0gcGFyZW50LmdldFBhcmVudE5vZGUoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmFtZXNwYWNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgYmFzZSBpZGVudGlmaWVyLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZUlkZW50aWZpZXIoKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9RTmFtZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1FOYW1lLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE3ODIxZDYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1FOYW1lLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NjggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBDbGFzcyB0byByZXByZXNlbnQgYSBxdWFsaWZpZWQgbmFtZTogIlRoZSBuYW1lIG9mIGFuIGludGVybmFsIFhTTFQgb2JqZWN0LAotICogc3BlY2lmaWNhbGx5IGEgbmFtZWQgdGVtcGxhdGUgKHNlZSBbNyBOYW1lZCBUZW1wbGF0ZXNdKSwgYSBtb2RlIChzZWUgWzYuNyBNb2Rlc10pLAotICogYW4gYXR0cmlidXRlIHNldCAoc2VlIFs4LjEuNCBOYW1lZCBBdHRyaWJ1dGUgU2V0c10pLCBhIGtleSAoc2VlIFsxNC4yIEtleXNdKSwKLSAqIGEgbG9jYWxlIChzZWUgWzE0LjMgTnVtYmVyIEZvcm1hdHRpbmddKSwgYSB2YXJpYWJsZSBvciBhIHBhcmFtZXRlciAoc2VlCi0gKiBbMTIgVmFyaWFibGVzIGFuZCBQYXJhbWV0ZXJzXSkgaXMgc3BlY2lmaWVkIGFzIGEgUU5hbWUuIElmIGl0IGhhcyBhIHByZWZpeCwKLSAqIHRoZW4gdGhlIHByZWZpeCBpcyBleHBhbmRlZCBpbnRvIGEgVVJJIHJlZmVyZW5jZSB1c2luZyB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucwotICogaW4gZWZmZWN0IG9uIHRoZSBhdHRyaWJ1dGUgaW4gd2hpY2ggdGhlIG5hbWUgb2NjdXJzLiBUaGUgZXhwYW5kZWQgbmFtZQotICogY29uc2lzdGluZyBvZiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgbmFtZSBhbmQgdGhlIHBvc3NpYmx5IG51bGwgVVJJIHJlZmVyZW5jZQotICogaXMgdXNlZCBhcyB0aGUgbmFtZSBvZiB0aGUgb2JqZWN0LiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgaXMgbm90IHVzZWQgZm9yCi0gKiB1bnByZWZpeGVkIG5hbWVzLiIKLSAqLwotcHVibGljIGNsYXNzIFFOYW1lIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUKLXsKLQotICAvKioKLSAgICogVGhlIGxvY2FsIG5hbWUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgX2xvY2FsTmFtZTsKLQotICAvKioKLSAgICogVGhlIG5hbWVzcGFjZSBVUkkuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgX25hbWVzcGFjZVVSSTsKLQotICAvKioKLSAgICogVGhlIG5hbWVzcGFjZSBwcmVmaXguCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgX3ByZWZpeDsKLQotICAvKioKLSAgICogVGhlIFhNTCBuYW1lc3BhY2UuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTX1hNTE5BTUVTUEFDRVVSSSA9Ci0gICAgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSI7Ci0KLSAgLyoqCi0gICAqIFRoZSBjYWNoZWQgaGFzaGNvZGUsIHdoaWNoIGlzIGNhbGN1bGF0ZWQgYXQgY29uc3RydWN0aW9uIHRpbWUuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgaW50IG1faGFzaENvZGU7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgUU5hbWUuCi0gICAqIDIwMDAxMDE5OiBUcnkgbWFraW5nIHRoaXMgcHVibGljLCB0byBzdXBwb3J0IFNlcmlhbGl6YWJsZT8gLS0gSktFU1MKLSAgICovCi0gIHB1YmxpYyBRTmFtZSgpe30KLQotICAvKioKLSAgICogQ29uc3RydWN0cyBhIG5ldyBRTmFtZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZXNwYWNlIFVSSSBhbmQKLSAgICogbG9jYWwgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBUaGUgbmFtZXNwYWNlIFVSSSBpZiBrbm93biwgb3IgbnVsbAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lCi0gICAqLwotICBwdWJsaWMgUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotCi0gICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19MT0NBTE5BTUVfTlVMTCwgbnVsbCkpOyAvLyJBcmd1bWVudCAnbG9jYWxOYW1lJyBpcyBudWxsIik7Ci0KLSAgICBfbmFtZXNwYWNlVVJJID0gbmFtZXNwYWNlVVJJOwotICAgIF9sb2NhbE5hbWUgPSBsb2NhbE5hbWU7Ci0gICAgbV9oYXNoQ29kZSA9IHRvU3RyaW5nKCkuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFFOYW1lIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lc3BhY2UgVVJJLCBwcmVmaXgKLSAgICogYW5kIGxvY2FsIG5hbWUuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgVGhlIG5hbWVzcGFjZSBVUkkgaWYga25vd24sIG9yIG51bGwKLSAgICogQHBhcmFtIHByZWZpeCBUaGUgbmFtZXNwYWNlIHByZWZpeCBpcyBrbm93biwgb3IgbnVsbAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIFRoZSBsb2NhbCBuYW1lCi0gICAqLwotICBwdWJsaWMgUU5hbWUoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotCi0gICAgaWYgKGxvY2FsTmFtZSA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0FSR19MT0NBTE5BTUVfTlVMTCwgbnVsbCkpOyAvLyJBcmd1bWVudCAnbG9jYWxOYW1lJyBpcyBudWxsIik7Ci0KLSAgICBfbmFtZXNwYWNlVVJJID0gbmFtZXNwYWNlVVJJOwotICAgIF9wcmVmaXggPSBwcmVmaXg7Ci0gICAgX2xvY2FsTmFtZSA9IGxvY2FsTmFtZTsKLSAgICBtX2hhc2hDb2RlID0gdG9TdHJpbmcoKS5oYXNoQ29kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFFOYW1lIGZyb20gYSBzdHJpbmcsIHdpdGhvdXQgbmFtZXNwYWNlIHJlc29sdXRpb24uICBHb29kCi0gICAqIGZvciBhIGZldyBvZGQgY2FzZXMuCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbE5hbWUgTG9jYWwgcGFydCBvZiBxdWFsaWZpZWQgbmFtZQotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLQotICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9BUkdfTE9DQUxOQU1FX05VTEwsIG51bGwpKTsgLy8iQXJndW1lbnQgJ2xvY2FsTmFtZScgaXMgbnVsbCIpOwotCi0gICAgX25hbWVzcGFjZVVSSSA9IG51bGw7Ci0gICAgX2xvY2FsTmFtZSA9IGxvY2FsTmFtZTsKLSAgICBtX2hhc2hDb2RlID0gdG9TdHJpbmcoKS5oYXNoQ29kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFFOYW1lIGZyb20gYSBzdHJpbmcsIHJlc29sdmluZyB0aGUgcHJlZml4Ci0gICAqIHVzaW5nIHRoZSBnaXZlbiBuYW1lc3BhY2Ugc3RhY2suIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpcwotICAgKiBub3QgcmVzb2x2ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBxbmFtZSBRdWFsaWZpZWQgbmFtZSB0byByZXNvbHZlCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VzIE5hbWVzcGFjZSBzdGFjayB0byB1c2UgdG8gcmVzb2x2ZSBuYW1lc3BhY2UKLSAgICovCi0gIHB1YmxpYyBRTmFtZShTdHJpbmcgcW5hbWUsIFN0YWNrIG5hbWVzcGFjZXMpCi0gIHsKLQotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBudWxsOwotICAgIFN0cmluZyBwcmVmaXggPSBudWxsOwotICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICBpZiAoaW5kZXhPZk5TU2VwID4gMCkKLSAgICB7Ci0gICAgICBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKTsKLQotICAgICAgaWYgKHByZWZpeC5lcXVhbHMoInhtbCIpKQotICAgICAgewotICAgICAgICBuYW1lc3BhY2UgPSBTX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHByZWZpeC5lcXVhbHMoInhtbG5zIikpCi0gICAgICB7Ci0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IGRlcHRoID0gbmFtZXNwYWNlcy5zaXplKCk7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IGRlcHRoIC0gMTsgaSA+PSAwOyBpLS0pCi0gICAgICAgIHsKLSAgICAgICAgICBOYW1lU3BhY2UgbnMgPSAoTmFtZVNwYWNlKSBuYW1lc3BhY2VzLmVsZW1lbnRBdChpKTsKLQotICAgICAgICAgIHdoaWxlIChudWxsICE9IG5zKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmICgobnVsbCAhPSBucy5tX3ByZWZpeCkgJiYgcHJlZml4LmVxdWFscyhucy5tX3ByZWZpeCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIG5hbWVzcGFjZSA9IG5zLm1fdXJpOwotICAgICAgICAgICAgICBpID0gLTE7Ci0KLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG5zID0gbnMubV9uZXh0OwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcHJlZml4IH0pKTsgIC8vIlByZWZpeCBtdXN0IHJlc29sdmUgdG8gYSBuYW1lc3BhY2U6ICIrcHJlZml4KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBfbG9jYWxOYW1lID0gKGluZGV4T2ZOU1NlcCA8IDApCi0gICAgICAgICAgICAgICAgID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXhPZk5TU2VwICsgMSk7Ci0gICAgX25hbWVzcGFjZVVSSSA9IG5hbWVzcGFjZTsKLSAgICBfcHJlZml4ID0gcHJlZml4OwotICAgIG1faGFzaENvZGUgPSB0b1N0cmluZygpLmhhc2hDb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgUU5hbWUgZnJvbSBhIHN0cmluZywgcmVzb2x2aW5nIHRoZSBwcmVmaXgKLSAgICogdXNpbmcgdGhlIGdpdmVuIG5hbWVzcGFjZSBjb250ZXh0IGFuZCBwcmVmaXggcmVzb2x2ZXIuIAotICAgKiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgaXMgbm90IHJlc29sdmVkLgotICAgKiAKLSAgICogQHBhcmFtIHFuYW1lIFF1YWxpZmllZCBuYW1lIHRvIHJlc29sdmUKLSAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgTmFtZXNwYWNlIENvbnRleHQgdG8gdXNlCi0gICAqIEBwYXJhbSByZXNvbHZlciBQcmVmaXggcmVzb2x2ZXIgZm9yIHRoaXMgY29udGV4dAotICAgKi8KLSAgcHVibGljIFFOYW1lKFN0cmluZyBxbmFtZSwgRWxlbWVudCBuYW1lc3BhY2VDb250ZXh0LAotICAgICAgICAgICAgICAgUHJlZml4UmVzb2x2ZXIgcmVzb2x2ZXIpCi0gIHsKLQotICAgIF9uYW1lc3BhY2VVUkkgPSBudWxsOwotCi0gICAgaW50IGluZGV4T2ZOU1NlcCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgIGlmIChpbmRleE9mTlNTZXAgPiAwKQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG5hbWVzcGFjZUNvbnRleHQpCi0gICAgICB7Ci0gICAgICAgIFN0cmluZyBwcmVmaXggPSBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKTsKLQotICAgICAgICBfcHJlZml4ID0gcHJlZml4OwotCi0gICAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICAgICAgewotICAgICAgICAgIF9uYW1lc3BhY2VVUkkgPSBTX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBfbmFtZXNwYWNlVVJJID0gcmVzb2x2ZXIuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCwKLSAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZUNvbnRleHQpOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gX25hbWVzcGFjZVVSSSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcHJlZml4IH0pKTsgIC8vIlByZWZpeCBtdXN0IHJlc29sdmUgdG8gYSBuYW1lc3BhY2U6ICIrcHJlZml4KTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIFRPRE86IGVycm9yIG9yIHdhcm5pbmcuLi4KLSAgICAgIH0KLSAgICB9Ci0KLSAgICBfbG9jYWxOYW1lID0gKGluZGV4T2ZOU1NlcCA8IDApCi0gICAgICAgICAgICAgICAgID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXhPZk5TU2VwICsgMSk7Ci0gICAgbV9oYXNoQ29kZSA9IHRvU3RyaW5nKCkuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBRTmFtZSBmcm9tIGEgc3RyaW5nLCByZXNvbHZpbmcgdGhlIHByZWZpeAotICAgKiB1c2luZyB0aGUgZ2l2ZW4gbmFtZXNwYWNlIHN0YWNrLiBUaGUgZGVmYXVsdCBuYW1lc3BhY2UgaXMKLSAgICogbm90IHJlc29sdmVkLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgUXVhbGlmaWVkIG5hbWUgdG8gcmVzb2x2ZQotICAgKiBAcGFyYW0gcmVzb2x2ZXIgUHJlZml4IHJlc29sdmVyIGZvciB0aGlzIGNvbnRleHQKLSAgICovCi0gIHB1YmxpYyBRTmFtZShTdHJpbmcgcW5hbWUsIFByZWZpeFJlc29sdmVyIHJlc29sdmVyKQotICB7Ci0KLSAgICBfbmFtZXNwYWNlVVJJID0gbnVsbDsKLQotICAgIGludCBpbmRleE9mTlNTZXAgPSBxbmFtZS5pbmRleE9mKCc6Jyk7Ci0KLSAgICBpZiAoaW5kZXhPZk5TU2VwID4gMCkKLSAgICB7Ci0gICAgICBTdHJpbmcgcHJlZml4ID0gcW5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCk7Ci0KLSAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICAgIHsKLSAgICAgICAgX25hbWVzcGFjZVVSSSA9IFNfWE1MTkFNRVNQQUNFVVJJOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBfbmFtZXNwYWNlVVJJID0gcmVzb2x2ZXIuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChudWxsID09IF9uYW1lc3BhY2VVUkkpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfUFJFRklYX01VU1RfUkVTT0xWRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcHJlZml4IH0pKTsgIC8vIlByZWZpeCBtdXN0IHJlc29sdmUgdG8gYSBuYW1lc3BhY2U6ICIrcHJlZml4KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBfbG9jYWxOYW1lID0gKGluZGV4T2ZOU1NlcCA8IDApCi0gICAgICAgICAgICAgICAgID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXhPZk5TU2VwICsgMSk7Ci0gICAgbV9oYXNoQ29kZSA9IHRvU3RyaW5nKCkuaGFzaENvZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJLiBSZXR1cm5zIG51bGwgaWYgdGhlIG5hbWVzcGFjZSBVUkkKLSAgICogaXMgbm90IGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2UgVVJJLCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpCi0gIHsKLSAgICByZXR1cm4gX25hbWVzcGFjZVVSSTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgcHJlZml4LiBSZXR1cm5zIG51bGwgaWYgdGhlIG5hbWVzcGFjZQotICAgKiBwcmVmaXggaXMgbm90IGtub3duLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2UgcHJlZml4LCBvciBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpCi0gIHsKLSAgICByZXR1cm4gX3ByZWZpeDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkKLSAgewotICAgIHJldHVybiBfbG9jYWxOYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBxdWFsaWZpZWQgbmFtZSwgdXNpbmcgdGhlIAotICAgKiBwcmVmaXggaWYgYXZhaWxhYmxlLCBvciB0aGUgJ3tuc31mb28nIG5vdGF0aW9uIGlmIG5vdC4gUGVyZm9ybXMKLSAgICogc3RyaW5nIGNvbmNhdGVuYXRpb24sIHNvIGJld2FyZSBvZiBwZXJmb3JtYW5jZSBpc3N1ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbmFtZXNwYWNlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotCi0gICAgcmV0dXJuIF9wcmVmaXggIT0gbnVsbAotICAgICAgICAgICA/IChfcHJlZml4ICsgIjoiICsgX2xvY2FsTmFtZSkKLSAgICAgICAgICAgOiAoX25hbWVzcGFjZVVSSSAhPSBudWxsCi0gICAgICAgICAgICAgID8gKCJ7IitfbmFtZXNwYWNlVVJJICsgIn0iICsgX2xvY2FsTmFtZSkgOiBfbG9jYWxOYW1lKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBxdWFsaWZpZWQgbmFtZSB1c2luZyB0aGUgCi0gICAqIHRoZSAne25zfWZvbycgbm90YXRpb24uIFBlcmZvcm1zCi0gICAqIHN0cmluZyBjb25jYXRlbmF0aW9uLCBzbyBiZXdhcmUgb2YgcGVyZm9ybWFuY2UgaXNzdWVzLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG5hbWVzcGFjZQotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b05hbWVzcGFjZWRTdHJpbmcoKQotICB7Ci0KLSAgICByZXR1cm4gKF9uYW1lc3BhY2VVUkkgIT0gbnVsbAotICAgICAgICAgICAgICA/ICgieyIrX25hbWVzcGFjZVVSSSArICJ9IiArIF9sb2NhbE5hbWUpIDogX2xvY2FsTmFtZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhlIHF1YWxpZmllZCBuYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZSgpCi0gIHsKLSAgICByZXR1cm4gZ2V0TmFtZXNwYWNlVVJJKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBxdWFsaWZpZWQgbmFtZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxQYXJ0KCkKLSAgewotICAgIHJldHVybiBnZXRMb2NhbE5hbWUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGNhY2hlZCBoYXNoY29kZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGNhY2hlZCBoYXNoY29kZSBvZiB0aGUgcXVhbGlmaWVkIG5hbWUKLSAgICovCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKQotICB7Ci0gICAgcmV0dXJuIG1faGFzaENvZGU7Ci0gIH0KLQotICAvKioKLSAgICogT3ZlcnJpZGUgZXF1YWxzIGFuZCBhZ3JlZSB0aGF0IHdlJ3JlIGVxdWFsIGlmCi0gICAqIHRoZSBwYXNzZWQgb2JqZWN0IGlzIGEgc3RyaW5nIGFuZCBpdCBtYXRjaGVzCi0gICAqIHRoZSBuYW1lIG9mIHRoZSBhcmcuCi0gICAqCi0gICAqIEBwYXJhbSBucyBOYW1lc3BhY2UgVVJJIHRvIGNvbXBhcmUgdG8KLSAgICogQHBhcmFtIGxvY2FsUGFydCBMb2NhbCBwYXJ0IG9mIHF1YWxpZmllZCBuYW1lIHRvIGNvbXBhcmUgdG8gCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbG9jYWwgbmFtZSBhbmQgdXJpIG1hdGNoIAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBucywgU3RyaW5nIGxvY2FsUGFydCkKLSAgewotCi0gICAgU3RyaW5nIHRoaXNuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2VVUkkoKTsKLQotICAgIHJldHVybiBnZXRMb2NhbE5hbWUoKS5lcXVhbHMobG9jYWxQYXJ0KQotICAgICAgICAgICAmJiAoKChudWxsICE9IHRoaXNuYW1lc3BhY2UpICYmIChudWxsICE9IG5zKSkKLSAgICAgICAgICAgICAgID8gdGhpc25hbWVzcGFjZS5lcXVhbHMobnMpCi0gICAgICAgICAgICAgICA6ICgobnVsbCA9PSB0aGlzbmFtZXNwYWNlKSAmJiAobnVsbCA9PSBucykpKTsKLSAgfQotCi0gIC8qKgotICAgKiBPdmVycmlkZSBlcXVhbHMgYW5kIGFncmVlIHRoYXQgd2UncmUgZXF1YWwgaWYKLSAgICogdGhlIHBhc3NlZCBvYmplY3QgaXMgYSBRTmFtZSBhbmQgaXQgbWF0Y2hlcwotICAgKiB0aGUgbmFtZSBvZiB0aGUgYXJnLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgUXVhbGlmaWVkIG5hbWUgdG8gY29tcGFyZSB0byAKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBxdWFsaWZpZWQgbmFtZXMgYXJlIGVxdWFsCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkKLSAgewotCi0gICAgaWYgKG9iamVjdCA9PSB0aGlzKQotICAgICAgcmV0dXJuIHRydWU7Ci0KLSAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgUU5hbWUpIHsKLSAgICAgIFFOYW1lIHFuYW1lID0gKFFOYW1lKSBvYmplY3Q7Ci0gICAgICBTdHJpbmcgdGhpc25hbWVzcGFjZSA9IGdldE5hbWVzcGFjZVVSSSgpOwotICAgICAgU3RyaW5nIHRoYXRuYW1lc3BhY2UgPSBxbmFtZS5nZXROYW1lc3BhY2VVUkkoKTsKLQotICAgICAgcmV0dXJuIGdldExvY2FsTmFtZSgpLmVxdWFscyhxbmFtZS5nZXRMb2NhbE5hbWUoKSkKLSAgICAgICAgICAgICAmJiAoKChudWxsICE9IHRoaXNuYW1lc3BhY2UpICYmIChudWxsICE9IHRoYXRuYW1lc3BhY2UpKQotICAgICAgICAgICAgICAgICA/IHRoaXNuYW1lc3BhY2UuZXF1YWxzKHRoYXRuYW1lc3BhY2UpCi0gICAgICAgICAgICAgICAgIDogKChudWxsID09IHRoaXNuYW1lc3BhY2UpICYmIChudWxsID09IHRoYXRuYW1lc3BhY2UpKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHN0cmluZywgY3JlYXRlIGFuZCByZXR1cm4gYSBRTmFtZSBvYmplY3QgIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBTdHJpbmcgdG8gdXNlIHRvIGNyZWF0ZSBRTmFtZQotICAgKgotICAgKiBAcmV0dXJuIGEgUU5hbWUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIFFOYW1lIGdldFFOYW1lRnJvbVN0cmluZyhTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobmFtZSwgInt9IiwgZmFsc2UpOwotICAgIFFOYW1lIHFuYW1lOwotICAgIFN0cmluZyBzMSA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKLSAgICBTdHJpbmcgczIgPSB0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpID8gdG9rZW5pemVyLm5leHRUb2tlbigpIDogbnVsbDsKLQotICAgIGlmIChudWxsID09IHMyKQotICAgICAgcW5hbWUgPSBuZXcgUU5hbWUobnVsbCwgczEpOwotICAgIGVsc2UKLSAgICAgIHFuYW1lID0gbmV3IFFOYW1lKHMxLCBzMik7Ci0KLSAgICByZXR1cm4gcW5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiB0ZWxscyBpZiBhIHJhdyBhdHRyaWJ1dGUgbmFtZSBpcyBhCi0gICAqIHhtbG5zIGF0dHJpYnV0ZS4KLSAgICoKLSAgICogQHBhcmFtIGF0dFJhd05hbWUgUmF3IG5hbWUgb2YgYXR0cmlidXRlCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgYXR0cmlidXRlIHN0YXJ0cyB3aXRoIG9yIGlzIGVxdWFsIHRvIHhtbG5zIAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzWE1MTlNEZWNsKFN0cmluZyBhdHRSYXdOYW1lKQotICB7Ci0KLSAgICByZXR1cm4gKGF0dFJhd05hbWUuc3RhcnRzV2l0aCgieG1sbnMiKQotICAgICAgICAgICAgJiYgKGF0dFJhd05hbWUuZXF1YWxzKCJ4bWxucyIpCi0gICAgICAgICAgICAgICAgfHwgYXR0UmF3TmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gdGVsbHMgaWYgYSByYXcgYXR0cmlidXRlIG5hbWUgaXMgYQotICAgKiB4bWxucyBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRSYXdOYW1lIFJhdyBuYW1lIG9mIGF0dHJpYnV0ZQotICAgKgotICAgKiBAcmV0dXJuIFByZWZpeCBvZiBhdHRyaWJ1dGUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFByZWZpeEZyb21YTUxOU0RlY2woU3RyaW5nIGF0dFJhd05hbWUpCi0gIHsKLQotICAgIGludCBpbmRleCA9IGF0dFJhd05hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA+PSAwKSA/IGF0dFJhd05hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSkgOiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgSW5wdXQgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIExvY2FsIHBhcnQgb2YgdGhlIG5hbWUgaWYgcHJlZml4ZWQsIG9yIHRoZSBnaXZlbiBuYW1lIGlmIG5vdAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxQYXJ0KFN0cmluZyBxbmFtZSkKLSAgewotCi0gICAgaW50IGluZGV4ID0gcW5hbWUuaW5kZXhPZignOicpOwotCi0gICAgcmV0dXJuIChpbmRleCA8IDApID8gcW5hbWUgOiBxbmFtZS5zdWJzdHJpbmcoaW5kZXggKyAxKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBsb2NhbCBuYW1lIG9mIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgSW5wdXQgbmFtZSAKLSAgICoKLSAgICogQHJldHVybiBQcmVmaXggb2YgbmFtZSBvciBlbXB0eSBzdHJpbmcgaWYgbm9uZSB0aGVyZSAgIAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UHJlZml4UGFydChTdHJpbmcgcW5hbWUpCi0gIHsKLQotICAgIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgIHJldHVybiAoaW5kZXggPj0gMCkgPyBxbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpIDogIiI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9SYXdDaGFyYWN0ZXJIYW5kbGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvUmF3Q2hhcmFjdGVySGFuZGxlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyZjQxOTc5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9SYXdDaGFyYWN0ZXJIYW5kbGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEFuIGludGVyZmFjZSB0aGF0IGEgU2VyaWFsaXplci9Db250ZW50SGFuZGxlci9Db250ZW50SGFuZGxlciBtdXN0Ci0gKiBpbXBsZW1lbnQgaW4gb3JkZXIgZm9yIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIHRvIHdvcmsuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgUmF3Q2hhcmFjdGVySGFuZGxlcgotewotCi0gIC8qKgotICAgKiBTZXJpYWxpemUgdGhlIGNoYXJhY3RlcnMgd2l0aG91dCBlc2NhcGluZy4KLSAgICoKLSAgICogQHBhcmFtIGNoIEFycmF5IG9mIGNoYXJhY3RlcnMKLSAgICogQHBhcmFtIHN0YXJ0IFN0YXJ0IGluZGV4IG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5Ci0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5Ci0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hhcmFjdGVyc1JhdyhjaGFyIGNoW10sIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TQVhTb3VyY2VMb2NhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvU0FYU291cmNlTG9jYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYTc5OGVkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TQVhTb3VyY2VMb2NhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYUGFyc2VFeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLQotLyoqCi0gKiBDbGFzcyBTQVhTb3VyY2VMb2NhdG9yIGV4dGVuZHMgb3JnLnhtbC5zYXguaGVscGVycy5Mb2NhdG9ySW1wbAotICogZm9yIHRoZSBwdXJwb3NlIG9mIGltcGxlbWVudGluZyB0aGUgU291cmNlTG9jYXRvciBpbnRlcmZhY2UsIAotICogYW5kIHRodXMgY2FuIGJlIGJvdGggYSBTb3VyY2VMb2NhdG9yIGFuZCBhIFNBWCBMb2NhdG9yLgotICovCi1wdWJsaWMgY2xhc3MgU0FYU291cmNlTG9jYXRvciBleHRlbmRzIExvY2F0b3JJbXBsCi0gICAgICAgIGltcGxlbWVudHMgU291cmNlTG9jYXRvciwgU2VyaWFsaXphYmxlCi17Ci0gIC8qKiBUaGUgU0FYIExvY2F0b3Igb2JqZWN0LgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgTG9jYXRvciBtX2xvY2F0b3I7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFNBWFNvdXJjZUxvY2F0b3IKLSAgICoKLSAgICovCi0gIHB1YmxpYyBTQVhTb3VyY2VMb2NhdG9yKCl7fQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBTQVhTb3VyY2VMb2NhdG9yCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhdG9yIFNvdXJjZSBsb2NhdG9yCi0gICAqLwotICBwdWJsaWMgU0FYU291cmNlTG9jYXRvcihMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLSAgICBtX2xvY2F0b3IgPSBsb2NhdG9yOwotICAgIHRoaXMuc2V0Q29sdW1uTnVtYmVyKGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIHRoaXMuc2V0TGluZU51bWJlcihsb2NhdG9yLmdldExpbmVOdW1iZXIoKSk7Ci0gICAgdGhpcy5zZXRQdWJsaWNJZChsb2NhdG9yLmdldFB1YmxpY0lkKCkpOwotICAgIHRoaXMuc2V0U3lzdGVtSWQobG9jYXRvci5nZXRTeXN0ZW1JZCgpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFNBWFNvdXJjZUxvY2F0b3IKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHNwZSBTQVhQYXJzZUV4Y2VwdGlvbiBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgU0FYU291cmNlTG9jYXRvcihTQVhQYXJzZUV4Y2VwdGlvbiBzcGUpCi0gIHsKLSAgICB0aGlzLnNldExpbmVOdW1iZXIoIHNwZS5nZXRMaW5lTnVtYmVyKCkgKTsKLSAgICB0aGlzLnNldENvbHVtbk51bWJlciggc3BlLmdldENvbHVtbk51bWJlcigpICk7Ci0gICAgdGhpcy5zZXRQdWJsaWNJZCggc3BlLmdldFB1YmxpY0lkKCkgKTsKLSAgICB0aGlzLnNldFN5c3RlbUlkKCBzcGUuZ2V0U3lzdGVtSWQoKSApOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgZXZlbnQuCi0gICAqCi0gICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHB1YmxpYyBpZGVudGlmaWVyIG9mIHRoZSBkb2N1bWVudAotICAgKiBlbnRpdHkgb3Igb2YgdGhlIGV4dGVybmFsIHBhcnNlZCBlbnRpdHkgaW4gd2hpY2ggdGhlIG1hcmt1cAotICAgKiB0cmlnZ2VyaW5nIHRoZSBldmVudCBhcHBlYXJzLjwvcD4KLSAgICoKLSAgICogQHJldHVybiBBIHN0cmluZyBjb250YWluaW5nIHRoZSBwdWJsaWMgaWRlbnRpZmllciwgb3IKLSAgICogICAgICAgICBudWxsIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAc2VlICNnZXRTeXN0ZW1JZAotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRQdWJsaWNJZCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9sb2NhdG9yKSA/IHN1cGVyLmdldFB1YmxpY0lkKCkgOiBtX2xvY2F0b3IuZ2V0UHVibGljSWQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudC4KLSAgICoKLSAgICogPHA+VGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc3lzdGVtIGlkZW50aWZpZXIgb2YgdGhlIGRvY3VtZW50Ci0gICAqIGVudGl0eSBvciBvZiB0aGUgZXh0ZXJuYWwgcGFyc2VkIGVudGl0eSBpbiB3aGljaCB0aGUgbWFya3VwCi0gICAqIHRyaWdnZXJpbmcgdGhlIGV2ZW50IGFwcGVhcnMuPC9wPgotICAgKgotICAgKiA8cD5JZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSBVUkwsIHRoZSBwYXJzZXIgbXVzdCByZXNvbHZlIGl0Ci0gICAqIGZ1bGx5IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZSBhcHBsaWNhdGlvbi48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgc3lzdGVtIGlkZW50aWZpZXIsIG9yIG51bGwKLSAgICogICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHNlZSAjZ2V0UHVibGljSWQKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U3lzdGVtSWQoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fbG9jYXRvcikgPyBzdXBlci5nZXRTeXN0ZW1JZCgpIDogbV9sb2NhdG9yLmdldFN5c3RlbUlkKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGxpbmUgbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGRvY3VtZW50IGV2ZW50IGVuZHMuCi0gICAqCi0gICAqIDxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBtZXRob2QKLSAgICogaXMgaW50ZW5kZWQgb25seSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FrZSBvZiBlcnJvcgotICAgKiByZXBvcnRpbmc7IGl0IGlzIG5vdCBpbnRlbmRlZCB0byBwcm92aWRlIHN1ZmZpY2llbnQgaW5mb3JtYXRpb24KLSAgICogdG8gZWRpdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgb2YgdGhlIG9yaWdpbmFsIFhNTCBkb2N1bWVudC48L3A+Ci0gICAqCi0gICAqIDxwPlRoZSByZXR1cm4gdmFsdWUgaXMgYW4gYXBwcm94aW1hdGlvbiBvZiB0aGUgbGluZSBudW1iZXIKLSAgICogaW4gdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBwYXJzZWQgZW50aXR5IHdoZXJlIHRoZQotICAgKiBtYXJrdXAgdHJpZ2dlcmluZyB0aGUgZXZlbnQgYXBwZWFycy48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIGxpbmUgbnVtYmVyLCBvciAtMSBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICogQHNlZSAjZ2V0Q29sdW1uTnVtYmVyCi0gICAqLwotICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fbG9jYXRvcikgPyBzdXBlci5nZXRMaW5lTnVtYmVyKCkgOiBtX2xvY2F0b3IuZ2V0TGluZU51bWJlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgY29sdW1uIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBkb2N1bWVudCBldmVudCBlbmRzLgotICAgKgotICAgKiA8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbWV0aG9kCi0gICAqIGlzIGludGVuZGVkIG9ubHkgYXMgYW4gYXBwcm94aW1hdGlvbiBmb3IgdGhlIHNha2Ugb2YgZXJyb3IKLSAgICogcmVwb3J0aW5nOyBpdCBpcyBub3QgaW50ZW5kZWQgdG8gcHJvdmlkZSBzdWZmaWNpZW50IGluZm9ybWF0aW9uCi0gICAqIHRvIGVkaXQgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoZSBvcmlnaW5hbCBYTUwgZG9jdW1lbnQuPC9wPgotICAgKgotICAgKiA8cD5UaGUgcmV0dXJuIHZhbHVlIGlzIGFuIGFwcHJveGltYXRpb24gb2YgdGhlIGNvbHVtbiBudW1iZXIKLSAgICogaW4gdGhlIGRvY3VtZW50IGVudGl0eSBvciBleHRlcm5hbCBwYXJzZWQgZW50aXR5IHdoZXJlIHRoZQotICAgKiBtYXJrdXAgdHJpZ2dlcmluZyB0aGUgZXZlbnQgYXBwZWFycy48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNvbHVtbiBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgKiBAc2VlICNnZXRMaW5lTnVtYmVyCi0gICAqLwotICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9sb2NhdG9yKSA/IHN1cGVyLmdldENvbHVtbk51bWJlcigpIDogbV9sb2NhdG9yLmdldENvbHVtbk51bWJlcigpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvU2VyaWFsaXphYmxlTG9jYXRvckltcGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TZXJpYWxpemFibGVMb2NhdG9ySW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlY2Y2MGYxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TZXJpYWxpemFibGVMb2NhdG9ySW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjYxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi0KLS8qKgotICogVGhlIHN0YW5kYXJkIFNBWCBpbXBsZW1lbnRhdGlvbiBvZiBMb2NhdG9ySW1wbCBpcyBub3Qgc2VyaWFsaXphYmxlLAotICogbGltaXRpbmcgaXRzIHV0aWxpdHkgYXMgImEgcGVyc2lzdGVudCBzbmFwc2hvdCBvZiBhIGxvY2F0b3IiLgotICogVGhpcyBpcyBhIHF1aWNrIGhhY2sgdG8gbWFrZSBpdCBzby4gTm90ZSB0aGF0IGl0IG1ha2VzIG1vcmUgc2Vuc2UKLSAqIGluIG1hbnkgY2FzZXMgdG8gc2V0IHVwIGZpZWxkcyB0byBob2xkIHRoaXMgZGF0YSByYXRoZXIgdGhhbiBwb2ludGluZwotICogYXQgYW5vdGhlciBvYmplY3QuLi4gYnV0IHRoYXQgZGVjaXNpb24gc2hvdWxkIGJlIG1hZGUgb24gYXJjaGl0ZWN0dXJhbAotICogZ3JvdW5kcyByYXRoZXIgdGhhbiBzZXJpYWxpemFiaWxpdHkuCi0gKjxwPgotICogSXQgaXNuJ3QgY2xlYXIgd2hldGhlciBzdWJjbGFzc2luZyBMb2NhdG9ySW1wbCBhbmQgYWRkaW5nIHNlcmlhbGl6YXRpb24KLSAqIG1ldGhvZHMgbWFrZXMgbW9yZSBzZW5zZSB0aGFuIGNvcHlpbmcgaXQgYW5kIGp1c3QgYWRkaW5nIFNlcmlhbGl6YWJsZQotICogdG8gaXRzIGludGVyZmFjZS4gU2luY2UgaXQncyBzbyBzaW1wbGUsIEkndmUgdGFrZW4gdGhlIGxhdHRlciBhcHByb2FjaAotICogZm9yIG5vdy4KLSAqCi0gKiBAc2VlIG9yZy54bWwuc2F4LmhlbHBlcnMuTG9jYXRvckltcGwKLSAqIEBzZWUgb3JnLnhtbC5zYXguTG9jYXRvciBMb2NhdG9yCi0gKiBAc2luY2UgWGFsYW5KMgotICogQGF1dGhvciBKb2UgS2Vzc2VsbWFuCi0gKiBAdmVyc2lvbiAxLjAKLSAqLwotcHVibGljIGNsYXNzIFNlcmlhbGl6YWJsZUxvY2F0b3JJbXBsCi1pbXBsZW1lbnRzIG9yZy54bWwuc2F4LkxvY2F0b3IsIGphdmEuaW8uU2VyaWFsaXphYmxlCi0KLXsKLSAgICAvKioKLSAgICAgKiBaZXJvLWFyZ3VtZW50IGNvbnN0cnVjdG9yLgotICAgICAqCi0gICAgICogPHA+U0FYIHNheXMgIlRoaXMgd2lsbCBub3Qgbm9ybWFsbHkgYmUgdXNlZnVsLCBzaW5jZSB0aGUgbWFpbiBwdXJwb3NlCi0gICAgICogb2YgdGhpcyBjbGFzcyBpcyB0byBtYWtlIGEgc25hcHNob3Qgb2YgYW4gZXhpc3RpbmcgTG9jYXRvci4iIEluIGZhY3QsCi0gICAgICogaXQgX2lzXyBzb21ldGltZXMgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gY29uc3RydWN0IGEgbmV3IExvY2F0b3IKLSAgICAgKiBwb2ludGluZyB0byBhIHNwZWNpZmljIGxvY2F0aW9uLi4uIHdoaWNoLCBhZnRlciBhbGwsIGlzIHdoeSB0aGUKLSAgICAgKiBzZXR0ZXIgbWV0aG9kcyBhcmUgcHJvdmlkZWQuCi0gICAgICogPC9wPgotICAgICAqLwotICAgIHB1YmxpYyBTZXJpYWxpemFibGVMb2NhdG9ySW1wbCAoKQotICAgIHsKLSAgICB9Ci0gICAgCi0gICAgCi0gICAgLyoqCi0gICAgICogQ29weSBjb25zdHJ1Y3Rvci4KLSAgICAgKgotICAgICAqIDxwPkNyZWF0ZSBhIHBlcnNpc3RlbnQgY29weSBvZiB0aGUgY3VycmVudCBzdGF0ZSBvZiBhIGxvY2F0b3IuCi0gICAgICogV2hlbiB0aGUgb3JpZ2luYWwgbG9jYXRvciBjaGFuZ2VzLCB0aGlzIGNvcHkgd2lsbCBzdGlsbCBrZWVwCi0gICAgICogdGhlIG9yaWdpbmFsIHZhbHVlcyAoYW5kIGl0IGNhbiBiZSB1c2VkIG91dHNpZGUgdGhlIHNjb3BlIG9mCi0gICAgICogRG9jdW1lbnRIYW5kbGVyIG1ldGhvZHMpLjwvcD4KLSAgICAgKgotICAgICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdG9yIHRvIGNvcHkuCi0gICAgICovCi0gICAgcHVibGljIFNlcmlhbGl6YWJsZUxvY2F0b3JJbXBsIChvcmcueG1sLnNheC5Mb2NhdG9yIGxvY2F0b3IpCi0gICAgewotICAgICAgICBzZXRQdWJsaWNJZChsb2NhdG9yLmdldFB1YmxpY0lkKCkpOwotICAgICAgICBzZXRTeXN0ZW1JZChsb2NhdG9yLmdldFN5c3RlbUlkKCkpOwotICAgICAgICBzZXRMaW5lTnVtYmVyKGxvY2F0b3IuZ2V0TGluZU51bWJlcigpKTsKLSAgICAgICAgc2V0Q29sdW1uTnVtYmVyKGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIH0KLSAgICAKLSAgICAKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIG9yZy54bWwuc2F4LkxvY2F0b3IKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc2F2ZWQgcHVibGljIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBwdWJsaWMgaWRlbnRpZmllciBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFB1YmxpY0lkCi0gICAgICogQHNlZSAjc2V0UHVibGljSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFB1YmxpY0lkICgpCi0gICAgewotICAgICAgICByZXR1cm4gcHVibGljSWQ7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc2F2ZWQgc3lzdGVtIGlkZW50aWZpZXIuCi0gICAgICoKLSAgICAgKiBAcmV0dXJuIFRoZSBzeXN0ZW0gaWRlbnRpZmllciBhcyBhIHN0cmluZywgb3IgbnVsbCBpZiBub25lCi0gICAgICogICAgICAgICBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldFN5c3RlbUlkCi0gICAgICogQHNlZSAjc2V0U3lzdGVtSWQKLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIGdldFN5c3RlbUlkICgpCi0gICAgewotICAgICAgICByZXR1cm4gc3lzdGVtSWQ7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFJldHVybiB0aGUgc2F2ZWQgbGluZSBudW1iZXIgKDEtYmFzZWQpLgotICAgICAqCi0gICAgICogQHJldHVybiBUaGUgbGluZSBudW1iZXIgYXMgYW4gaW50ZWdlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldExpbmVOdW1iZXIKLSAgICAgKiBAc2VlICNzZXRMaW5lTnVtYmVyCi0gICAgICovCi0gICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyICgpCi0gICAgewotICAgICAgICByZXR1cm4gbGluZU51bWJlcjsKLSAgICB9Ci0gICAgCi0gICAgCi0gICAgLyoqCi0gICAgICogUmV0dXJuIHRoZSBzYXZlZCBjb2x1bW4gbnVtYmVyICgxLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEByZXR1cm4gVGhlIGNvbHVtbiBudW1iZXIgYXMgYW4gaW50ZWdlciwgb3IgLTEgaWYgbm9uZSBpcyBhdmFpbGFibGUuCi0gICAgICogQHNlZSBvcmcueG1sLnNheC5Mb2NhdG9yI2dldENvbHVtbk51bWJlcgotICAgICAqIEBzZWUgI3NldENvbHVtbk51bWJlcgotICAgICAqLwotICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyICgpCi0gICAgewotICAgICAgICByZXR1cm4gY29sdW1uTnVtYmVyOwotICAgIH0KLSAgICAKLSAgICAKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIFNldHRlcnMgZm9yIHRoZSBwcm9wZXJ0aWVzIChub3QgaW4gb3JnLnhtbC5zYXguTG9jYXRvcikKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFNldCB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoaXMgbG9jYXRvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBwdWJsaWNJZCBUaGUgbmV3IHB1YmxpYyBpZGVudGlmaWVyLCBvciBudWxsIAotICAgICAqICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRQdWJsaWNJZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFB1YmxpY0lkIChTdHJpbmcgcHVibGljSWQpCi0gICAgewotICAgICAgICB0aGlzLnB1YmxpY0lkID0gcHVibGljSWQ7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFNldCB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoaXMgbG9jYXRvci4KLSAgICAgKgotICAgICAqIEBwYXJhbSBzeXN0ZW1JZCBUaGUgbmV3IHN5c3RlbSBpZGVudGlmaWVyLCBvciBudWxsIAotICAgICAqICAgICAgICBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAgICAgKiBAc2VlICNnZXRTeXN0ZW1JZAotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldFN5c3RlbUlkIChTdHJpbmcgc3lzdGVtSWQpCi0gICAgewotICAgICAgICB0aGlzLnN5c3RlbUlkID0gc3lzdGVtSWQ7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFNldCB0aGUgbGluZSBudW1iZXIgZm9yIHRoaXMgbG9jYXRvciAoMS1iYXNlZCkuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gbGluZU51bWJlciBUaGUgbGluZSBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldExpbmVOdW1iZXIKLSAgICAgKi8KLSAgICBwdWJsaWMgdm9pZCBzZXRMaW5lTnVtYmVyIChpbnQgbGluZU51bWJlcikKLSAgICB7Ci0gICAgICAgIHRoaXMubGluZU51bWJlciA9IGxpbmVOdW1iZXI7Ci0gICAgfQotICAgIAotICAgIAotICAgIC8qKgotICAgICAqIFNldCB0aGUgY29sdW1uIG51bWJlciBmb3IgdGhpcyBsb2NhdG9yICgxLWJhc2VkKS4KLSAgICAgKgotICAgICAqIEBwYXJhbSBjb2x1bW5OdW1iZXIgVGhlIGNvbHVtbiBudW1iZXIsIG9yIC0xIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgotICAgICAqIEBzZWUgI2dldENvbHVtbk51bWJlcgotICAgICAqLwotICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbk51bWJlciAoaW50IGNvbHVtbk51bWJlcikKLSAgICB7Ci0gICAgICAgIHRoaXMuY29sdW1uTnVtYmVyID0gY29sdW1uTnVtYmVyOwotICAgIH0KLSAgICAKLSAgICAKLSAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAgIC8vIEludGVybmFsIHN0YXRlLgotICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gICAgCi0gICAgLyoqCi0gICAgICogVGhlIHB1YmxpYyBJRC4KLSAgICAgKiBAc2VyaWFsCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgcHVibGljSWQ7Ci0gICAgCi0gICAgLyoqCi0gICAgICogVGhlIHN5c3RlbSBJRC4KLSAgICAgKiBAc2VyaWFsCi0gICAgICovCi0gICAgcHJpdmF0ZSBTdHJpbmcgc3lzdGVtSWQ7Ci0gICAgCi0gICAgLyoqCi0gICAgICogVGhlIGxpbmUgbnVtYmVyLgotICAgICAqIEBzZXJpYWwKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBsaW5lTnVtYmVyOwotICAgIAotICAgIC8qKgotICAgICAqIFRoZSBjb2x1bW4gbnVtYmVyLgotICAgICAqIEBzZXJpYWwKLSAgICAgKi8KLSAgICBwcml2YXRlIGludCBjb2x1bW5OdW1iZXI7Ci0gICAgCi19Ci0KLS8vIGVuZCBvZiBMb2NhdG9ySW1wbC5qYXZhCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvU3RyaW5nQnVmZmVyUG9vbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ0J1ZmZlclBvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjBhZGQ1MS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvU3RyaW5nQnVmZmVyUG9vbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGNsYXNzIHBvb2xzIHN0cmluZyBidWZmZXJzLCBzaW5jZSB0aGV5IGFyZSByZXVzZWQgc28gb2Z0ZW4uCi0gKiBTdHJpbmcgYnVmZmVycyBhcmUgZ29vZCBjYW5kaWRhdGVzIGZvciBwb29saW5nLCBiZWNhdXNlIG9mIAotICogdGhlaXIgc3VwcG9ydGluZyBjaGFyYWN0ZXIgYXJyYXlzLgotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nQnVmZmVyUG9vbAotewotCi0gIC8qKiBUaGUgZ2xvYmFsIHBvb2wgb2Ygc3RyaW5nIGJ1ZmZlcnMuICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0UG9vbCBtX3N0cmluZ0J1ZlBvb2wgPQotICAgIG5ldyBPYmplY3RQb29sKG9yZy5hcGFjaGUueG1sLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXIuY2xhc3MpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZpcnN0IGZyZWUgaW5zdGFuY2Ugb2YgYSBzdHJpbmcgYnVmZmVyLCBvciBjcmVhdGUgb25lIAotICAgKiBpZiB0aGVyZSBhcmUgbm8gZnJlZSBpbnN0YW5jZXMuCi0gICAqCi0gICAqIEByZXR1cm4gQSBzdHJpbmcgYnVmZmVyIHJlYWR5IGZvciB1c2UuCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIHN0YXRpYyBGYXN0U3RyaW5nQnVmZmVyIGdldCgpCi0gIHsKLSAgICByZXR1cm4gKEZhc3RTdHJpbmdCdWZmZXIpIG1fc3RyaW5nQnVmUG9vbC5nZXRJbnN0YW5jZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHN0cmluZyBidWZmZXIgYmFjayB0byB0aGUgcG9vbC4KLSAgICoKLSAgICogQHBhcmFtIHNiIE11c3QgYmUgYSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBzdHJpbmcgYnVmZmVyLgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCBzdGF0aWMgdm9pZCBmcmVlKEZhc3RTdHJpbmdCdWZmZXIgc2IpCi0gIHsKLSAgICAvLyBTaW5jZSB0aGlzIGlzbid0IHN5bmNocm9uaXplZCwgc2V0TGVuZ3RoIG11c3QgYmUgCi0gICAgLy8gZG9uZSBiZWZvcmUgdGhlIGluc3RhbmNlIGlzIGZyZWVkLgotICAgIC8vIEZpeCBhdHRyaWJ1dGVkIHRvIFBldGVyIFNwZWNrIDxzcGVja0BydWMuZGs+LgotICAgIHNiLnNldExlbmd0aCgwKTsKLSAgICBtX3N0cmluZ0J1ZlBvb2wuZnJlZUluc3RhbmNlKHNiKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ1RvSW50VGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdHJpbmdUb0ludFRhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE2ODg4YzEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ1RvSW50VGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxMiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgdmVyeSBzaW1wbGUgbG9va3VwIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBzdHJpbmdzLCB0aGUgZXZlbgotICogbnVtYmVyIHN0cmluZ3MgYmVpbmcga2V5cywgYW5kIHRoZSBvZGQgbnVtYmVyIHN0cmluZ3MgYmVpbmcgdmFsdWVzLgotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nVG9JbnRUYWJsZQotewotCi0gIC8qKiBCbG9jayBzaXplIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fYmxvY2tzaXplOwotCi0gIC8qKiBBcnJheSBvZiBzdHJpbmdzIHRoaXMgdGFibGUgcG9pbnRzIHRvLiBBc3NvY2lhdGVkIHdpdGggaW50cwotICAgKiBpbiBtX3ZhbHVlcyAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbWFwW107Ci0KLSAgLyoqIEFycmF5IG9mIGludHMgdGhpcyB0YWJsZSBwb2ludHMuIEFzc29jaWF0ZWQgd2l0aCBzdHJpbmdzIGZyb20KLSAgICogbV9tYXAuICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV92YWx1ZXNbXTsKLQotICAvKiogTnVtYmVyIG9mIGludHMgaW4gdGhlIHRhYmxlICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiB0aGlzIHRhYmxlICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBTaXplOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1RvSW50VGFibGUoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDg7Ci0gICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW21fYmxvY2tzaXplXTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFN0cmluZ1RvSW50VGFibGUsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmdUb0ludFRhYmxlKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBTdHJpbmdbYmxvY2tzaXplXTsKLSAgICBtX3ZhbHVlcyA9IG5ldyBpbnRbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxpc3QgCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldExlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgc3RyaW5nIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gYXBwZW5kCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW50IHZhbHVlIG9mIHRoZSBzdHJpbmcKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1dChTdHJpbmcga2V5LCBpbnQgdmFsdWUpCi0gIHsKLQotICAgIGlmICgobV9maXJzdEZyZWUgKyAxKSA+PSBtX21hcFNpemUpCi0gICAgewotICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICBTdHJpbmcgbmV3TWFwW10gPSBuZXcgU3RyaW5nW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0KLSAgICAgIGludCBuZXdWYWx1ZXNbXSA9IG5ldyBpbnRbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX3ZhbHVlcywgMCwgbmV3VmFsdWVzLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX3ZhbHVlcyA9IG5ld1ZhbHVlczsKLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBrZXk7Ci0gICAgbV92YWx1ZXNbbV9maXJzdEZyZWVdID0gdmFsdWU7Ci0KLSAgICBtX2ZpcnN0RnJlZSsrOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgU3RyaW5nIHRvIGxvb2sgZm9yCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFN0cmluZydzIGludCB2YWx1ZSBvciBhIGJvZ3VzIHZhbHVlIGlmIG5vdCBmb3VuZCAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0KFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKGtleSkpCi0gICAgICAgIHJldHVybiBtX3ZhbHVlc1tpXTsKLSAgICB9Ci0KLSAgICByZXR1cm4gLTEwMDAwOyAgLy8gQm9ndXMgdmFsdWUsIG5lZWRzIHRvIHRocm93IGV4Y2VwdGlvbi4KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLiBJZ25vcmUgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nJ3MgaW50IHZhbHVlLCBvciBhIGJvZ3VzIHZhbHVlIGlmIG5vdCBmb3VuZAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRJZ25vcmVDYXNlKFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGlmIChudWxsID09IGtleSkKLSAgICAgIHJldHVybiAtMTAwMDA7ICAvLyBCb2d1cyB2YWx1ZSwgbmVlZHMgdG8gdGhyb3cgZXhjZXB0aW9uLgotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXS5lcXVhbHNJZ25vcmVDYXNlKGtleSkpCi0gICAgICAgIHJldHVybiBtX3ZhbHVlc1tpXTsKLSAgICB9Ci0KLSAgICByZXR1cm4gLTEwMDAwOyAgLy8gQm9ndXMgdmFsdWUsIG5lZWRzIHRvIHRocm93IGV4Y2VwdGlvbi4KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHN0cmluZyBpcyBpbiB0aGUgdGFibGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKGtleSkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdHJpbmdUb1N0cmluZ1RhYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZmMWEzNWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgdmVyeSBzaW1wbGUgbG9va3VwIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBzdHJpbmdzLCB0aGUgZXZlbgotICogbnVtYmVyIHN0cmluZ3MgYmVpbmcga2V5cywgYW5kIHRoZSBvZGQgbnVtYmVyIHN0cmluZ3MgYmVpbmcgdmFsdWVzLgotICovCi1wdWJsaWMgY2xhc3MgU3RyaW5nVG9TdHJpbmdUYWJsZQotewotCi0gIC8qKiBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZSAgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2Jsb2Nrc2l6ZTsKLQotICAvKiogQXJyYXkgb2Ygc3RyaW5ncyB0aGlzIGNvbnRhaW5zICAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fbWFwW107Ci0KLSAgLyoqIE51bWJlciBvZiBzdHJpbmdzIHRoaXMgY29udGFpbnMgICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogU2l6ZSBvZiB0aGlzIHRhYmxlICAgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX21hcFNpemU7Ci0KLSAgLyoqCi0gICAqIERlZmF1bHQgY29uc3RydWN0b3IuICBOb3RlIHRoYXQgdGhlIGRlZmF1bHQKLSAgICogYmxvY2sgc2l6ZSBpcyB2ZXJ5IHNtYWxsLCBmb3Igc21hbGwgbGlzdHMuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nVG9TdHJpbmdUYWJsZSgpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gMTY7Ci0gICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW21fYmxvY2tzaXplXTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBTdHJpbmdUb1N0cmluZ1RhYmxlLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZSAKLSAgICovCi0gIHB1YmxpYyBTdHJpbmdUb1N0cmluZ1RhYmxlKGludCBibG9ja3NpemUpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwU2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBTdHJpbmdbYmxvY2tzaXplXTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBOdW1iZXIgb2Ygc3RyaW5ncyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRMZW5ndGgoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIHN0cmluZyBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqIFRoZSBzdHJpbmdzIGdvIHRvIHRoZSBldmVuIGxvY2F0aW9ucyBpbiB0aGUgYXJyYXkgCi0gICAqIGFuZCB0aGUgdmFsdWVzIGluIHRoZSBvZGQuIAotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byBhZGQgdG8gdGhlIGxpc3QgCi0gICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSBvZiB0aGUgc3RyaW5nCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXQoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMikgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgU3RyaW5nIG5ld01hcFtdID0gbmV3IFN0cmluZ1ttX21hcFNpemVdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fZmlyc3RGcmVlICsgMSk7Ci0KLSAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IGtleTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHN0cmluZyBvciBudWxsIGlmIG5vdCBmb3VuZC4gCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldChTdHJpbmcga2V5KQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpICs9IDIpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyhrZXkpKQotICAgICAgICByZXR1cm4gbV9tYXBbaSArIDFdOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZSB0aGUgZ2l2ZW4gc3RyaW5nIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGlzIHRhYmxlLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFN0cmluZyB0byByZW1vdmUgZnJvbSB0aGUgdGFibGUKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHJlbW92ZShTdHJpbmcga2V5KQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpICs9IDIpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyhrZXkpKQotICAgICAgewotICAgICAgICBpZiAoKGkgKyAyKSA8IG1fZmlyc3RGcmVlKQotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGkgKyAyLCBtX21hcCwgaSwgbV9maXJzdEZyZWUgLSAoaSArIDIpKTsKLQotICAgICAgICBtX2ZpcnN0RnJlZSAtPSAyOwotICAgICAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBudWxsOwotICAgICAgICBtX21hcFttX2ZpcnN0RnJlZSArIDFdID0gbnVsbDsKLQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy4gSWdub3JlIGNhc2UKLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgc3RyaW5nIG9yIG51bGwgaWYgbm90IGZvdW5kCi0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldElnbm9yZUNhc2UoU3RyaW5nIGtleSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0ga2V5KQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpICs9IDIpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFsc0lnbm9yZUNhc2Uoa2V5KSkKLSAgICAgICAgcmV0dXJuIG1fbWFwW2kgKyAxXTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nIGluIHRoZSB2YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBWYWx1ZSBvZiB0aGUgc3RyaW5nIHRvIGxvb2sgdXAKLSAgICoKLSAgICogQHJldHVybiB0aGUgc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWUgb3IgbnVsbCBpZiBub3QgZm91bmQKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0QnlWYWx1ZShTdHJpbmcgdmFsKQotICB7Ci0KLSAgICBmb3IgKGludCBpID0gMTsgaSA8IG1fZmlyc3RGcmVlOyBpICs9IDIpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmVxdWFscyh2YWwpKQotICAgICAgICByZXR1cm4gbV9tYXBbaSAtIDFdOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnRoIGVsZW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBpIGluZGV4IG9mIHRoZSBzdHJpbmcgdG8gbG9vayB1cC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgU3RyaW5nIHRvIGxvb2sgdXAKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiBzdHJpbmcgaXMgaW4gdGhpcyB0YWJsZSAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkgKz0gMikKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKGtleSkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gdmFsIHZhbHVlIHRvIGxvb2sgdXAKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBpbiB0aGUgdGFibGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjb250YWluc1ZhbHVlKFN0cmluZyB2YWwpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbV9maXJzdEZyZWU7IGkgKz0gMikKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKHZhbCkpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdHJpbmdUb1N0cmluZ1RhYmxlVmVjdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQzYjZlZWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzNSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgdmVyeSBzaW1wbGUgdGFibGUgdGhhdCBzdG9yZXMgYSBsaXN0IG9mIFN0cmluZ1RvU3RyaW5nVGFibGVzLCBvcHRpbWl6ZWQKLSAqIGZvciBzbWFsbCBsaXN0cy4KLSAqLwotcHVibGljIGNsYXNzIFN0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IKLXsKLQotICAvKiogU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgICAgICAgICAqLwotICBwcml2YXRlIGludCBtX2Jsb2Nrc2l6ZTsKLQotICAvKiogQXJyYXkgb2YgU3RyaW5nVG9TdHJpbmdUYWJsZSBvYmplY3RzICAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nVG9TdHJpbmdUYWJsZSBtX21hcFtdOwotCi0gIC8qKiBOdW1iZXIgb2YgU3RyaW5nVG9TdHJpbmdUYWJsZSBvYmplY3RzIGluIHRoaXMgYXJyYXkgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9maXJzdEZyZWUgPSAwOwotCi0gIC8qKiBTaXplIG9mIHRoaXMgYXJyYXkgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9tYXBTaXplOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1RvU3RyaW5nVGFibGVWZWN0b3IoKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IDg7Ci0gICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nVG9TdHJpbmdUYWJsZVttX2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgU3RyaW5nVG9TdHJpbmdUYWJsZVZlY3RvciwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgCi0gICAqLwotICBwdWJsaWMgU3RyaW5nVG9TdHJpbmdUYWJsZVZlY3RvcihpbnQgYmxvY2tzaXplKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcFNpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nVG9TdHJpbmdUYWJsZVtibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIE51bWJlciBvZiBTdHJpbmdUb1N0cmluZ1RhYmxlIG9iamVjdHMgaW4gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBOdW1iZXIgb2YgU3RyaW5nVG9TdHJpbmdUYWJsZSBvYmplY3RzIGluIHRoZSBsaXN0Ci0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IHNpemUoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RGcmVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCBhIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0IG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIFN0cmluZ1RvU3RyaW5nVGFibGUgb2JqZWN0IHRvIGFkZAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgYWRkRWxlbWVudChTdHJpbmdUb1N0cmluZ1RhYmxlIHZhbHVlKQotICB7Ci0KLSAgICBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgU3RyaW5nVG9TdHJpbmdUYWJsZSBuZXdNYXBbXSA9IG5ldyBTdHJpbmdUb1N0cmluZ1RhYmxlW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gdmFsdWU7Ci0KLSAgICBtX2ZpcnN0RnJlZSsrOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgc3RyaW5nLCBmaW5kIHRoZSBsYXN0IGFkZGVkIG9jY3VyYW5jZSB2YWx1ZQotICAgKiB0aGF0IG1hdGNoZXMgdGhlIGtleS4KLSAgICoKLSAgICogQHBhcmFtIGtleSBTdHJpbmcgdG8gbG9vayB1cAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsYXN0IGFkZGVkIG9jY3VyYW5jZSB2YWx1ZSB0aGF0IG1hdGNoZXMgdGhlIGtleQotICAgKiBvciBudWxsIGlmIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZ2V0KFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSBtX2ZpcnN0RnJlZSAtIDE7IGkgPj0gMDsgLS1pKQotICAgIHsKLSAgICAgIFN0cmluZyBuc3VyaSA9IG1fbWFwW2ldLmdldChrZXkpOwotCi0gICAgICBpZiAobnN1cmkgIT0gbnVsbCkKLSAgICAgICAgcmV0dXJuIG5zdXJpOwotICAgIH0KLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgc3RyaW5nLCBmaW5kIG91dCBpZiB0aGVyZSBpcyBhIHZhbHVlIGluIHRoaXMgdGFibGUKLSAgICogdGhhdCBtYXRjaGVzIHRoZSBrZXkuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgU3RyaW5nIHRvIGxvb2sgZm9yICAKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBzdHJpbmcgd2FzIGZvdW5kIGluIHRhYmxlLCBudWxsIGlmIG5vdAotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gY29udGFpbnNLZXkoU3RyaW5nIGtleSkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IG1fZmlyc3RGcmVlIC0gMTsgaSA+PSAwOyAtLWkpCi0gICAgewotICAgICAgaWYgKG1fbWFwW2ldLmdldChrZXkpICE9IG51bGwpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmUgdGhlIGxhc3QgZWxlbWVudC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHJlbW92ZUxhc3RFbGVtKCkKLSAgewotCi0gICAgaWYgKG1fZmlyc3RGcmVlID4gMCkKLSAgICB7Ci0gICAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBudWxsOwotCi0gICAgICBtX2ZpcnN0RnJlZS0tOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBlbGVtZW50IHRvIGZpbmQKLSAgICoKLSAgICogQHJldHVybiBUaGUgU3RyaW5nVG9TdHJpbmdUYWJsZSBvYmplY3QgYXQgdGhlIGdpdmVuIGluZGV4Ci0gICAqLwotICBwdWJsaWMgZmluYWwgU3RyaW5nVG9TdHJpbmdUYWJsZSBlbGVtZW50QXQoaW50IGkpCi0gIHsKLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIFN0cmluZ1RvU3RyaW5nVGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIFRoZSBTdHJpbmdUb1N0cmluZ1RhYmxlIHRvIGZpbmQKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBTdHJpbmdUb1N0cmluZ1RhYmxlIGlzIGZvdW5kCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBjb250YWlucyhTdHJpbmdUb1N0cmluZ1RhYmxlIHMpCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzKHMpKQotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdHJpbmdWZWN0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdHJpbmdWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGY0YjRmMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvU3RyaW5nVmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBzdHJpbmdzLCBvcHRpbWl6ZWQKLSAqIGZvciBzbWFsbCBsaXN0cy4KLSAqLwotcHVibGljIGNsYXNzIFN0cmluZ1ZlY3RvciBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlCi17Ci0KLSAgLyoqIEBzZXJpYWwgU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEBzZXJpYWwgQXJyYXkgb2Ygc3RyaW5ncyB0aGlzIGNvbnRhaW5zICAgICAgICAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9tYXBbXTsKLQotICAvKiogQHNlcmlhbCBOdW1iZXIgb2Ygc3RyaW5ncyB0aGlzIGNvbnRhaW5zICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9maXJzdEZyZWUgPSAwOwotCi0gIC8qKiBAc2VyaWFsIFNpemUgb2YgdGhlIGFycmF5ICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9tYXBTaXplOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN0cmluZ1ZlY3RvcigpCi0gIHsKLQotICAgIG1fYmxvY2tzaXplID0gODsKLSAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICBtX21hcCA9IG5ldyBTdHJpbmdbbV9ibG9ja3NpemVdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFN0cmluZ1ZlY3RvciwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiB0aGUgYmxvY2tzIHRvIGFsbG9jYXRlIAotICAgKi8KLSAgcHVibGljIFN0cmluZ1ZlY3RvcihpbnQgYmxvY2tzaXplKQotICB7Ci0KLSAgICBtX2Jsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZTsKLSAgICBtX21hcFNpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXAgPSBuZXcgU3RyaW5nW2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIHN0cmluZ3MgaW4gdGhlIGxpc3QgCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gTnVtYmVyIG9mIHN0cmluZ3MgaW4gdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgc3RyaW5nIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIFN0aW5nIHRvIGFkZCB0byB0aGUgdmVjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBhZGRFbGVtZW50KFN0cmluZyB2YWx1ZSkKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIFN0cmluZyBuZXdNYXBbXSA9IG5ldyBTdHJpbmdbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgSW5kZXggb2Ygc3RyaW5nIHRvIGZpbmQKLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgYXQgZ2l2ZW4gaW5kZXgKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBTdHJpbmcgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW2ldOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBzIFN0cmluZyB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHN0cmluZyBpcyBpbiB0aGlzIHRhYmxlICAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBzKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBzKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIGlmIChtX21hcFtpXS5lcXVhbHMocykpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLiBJZ25vcmUgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtIHMgU3RyaW5nIHRvIGZpbmQKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBTdHJpbmcgaXMgaW4gdGhpcyB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBib29sZWFuIGNvbnRhaW5zSWdub3JlQ2FzZShTdHJpbmcgcykKLSAgewotCi0gICAgaWYgKG51bGwgPT0gcykKLSAgICAgIHJldHVybiBmYWxzZTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBpZiAobV9tYXBbaV0uZXF1YWxzSWdub3JlQ2FzZShzKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIHRhYmxlIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBzIFN0cmluZyB0byBwdXNoIGludG8gdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaChTdHJpbmcgcykKLSAgewotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgIFN0cmluZyBuZXdNYXBbXSA9IG5ldyBTdHJpbmdbbV9tYXBTaXplXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBzOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIHRhaWwgb2YgdGhpcyB2ZWN0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIFN0cmluZyBsYXN0IGFkZGVkIHRvIHRoaXMgdmVjdG9yIG9yIG51bGwgbm90IGZvdW5kLgotICAgKiBUaGUgc3RyaW5nIGlzIHJlbW92ZWQgZnJvbSB0aGUgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBwb3AoKQotICB7Ci0KLSAgICBpZiAobV9maXJzdEZyZWUgPD0gMCkKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIFN0cmluZyBzID0gbV9tYXBbbV9maXJzdEZyZWVdOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gbnVsbDsKLQotICAgIHJldHVybiBzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nIGF0IHRoZSB0YWlsIG9mIHRoaXMgdmVjdG9yIHdpdGhvdXQgcG9wcGluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIGF0IHRoZSB0YWlsIG9mIHRoaXMgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFN0cmluZyBwZWVrKCkKLSAgewotICAgIHJldHVybiAobV9maXJzdEZyZWUgPD0gMCkgPyBudWxsIDogbV9tYXBbbV9maXJzdEZyZWUgLSAxXTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N1YmFsbG9jYXRlZEJ5dGVWZWN0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdWJhbGxvY2F0ZWRCeXRlVmVjdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI5MTBlMWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N1YmFsbG9jYXRlZEJ5dGVWZWN0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDUzNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgdmVyeSBzaW1wbGUgdGFibGUgdGhhdCBzdG9yZXMgYSBsaXN0IG9mIGJ5dGUuIFZlcnkgc2ltaWxhciBBUEkgdG8gb3VyCi0gKiBJbnRWZWN0b3IgY2xhc3MgKHNhbWUgQVBJKTsgZGlmZmVyZW50IGludGVybmFsIHN0b3JhZ2UuCi0gKiAKLSAqIFRoaXMgdmVyc2lvbiB1c2VzIGFuIGFycmF5LW9mLWFycmF5cyBzb2x1dGlvbi4gUmVhZC93cml0ZSBhY2Nlc3MgaXMgdGh1cwotICogYSBiaXQgc2xvd2VyIHRoYW4gdGhlIHNpbXBsZSBJbnRWZWN0b3IsIGFuZCBiYXNpYyBzdG9yYWdlIGlzIGEgdHJpZmxlCi0gKiBoaWdoZXIgZHVlIHRvIHRoZSB0b3AtbGV2ZWwgYXJyYXkgLS0gYnV0IGFwcGVuZGluZyBpcyBPKDEpIGZhc3QgcmF0aGVyCi0gKiB0aGFuIE8oTioqMikgc2xvdywgd2hpY2ggd2lsbCBzd2FtcCB0aG9zZSBjb3N0cyBpbiBzaXR1YXRpb25zIHdoZXJlCi0gKiBsb25nIHZlY3RvcnMgYXJlIGJlaW5nIGJ1aWx0IHVwLgotICogCi0gKiBLbm93biBpc3N1ZXM6Ci0gKiAKLSAqIFNvbWUgbWV0aG9kcyBhcmUgcHJpdmF0ZSBiZWNhdXNlIHRoZXkgaGF2ZW4ndCB5ZXQgYmVlbiB0ZXN0ZWQgcHJvcGVybHkuCi0gKiAKLSAqIElmIGFuIGVsZW1lbnQgaGFzIG5vdCBiZWVuIHNldCAoYmVjYXVzZSB3ZSBza2lwcGVkIGl0KSwgaXRzIHZhbHVlIHdpbGwKLSAqIGluaXRpYWxseSBiZSAwLiBTaG9ydGVuaW5nIHRoZSB2ZWN0b3IgZG9lcyBub3QgY2xlYXIgb2xkIHN0b3JhZ2U7IGlmIHlvdQotICogdGhlbiBza2lwIHZhbHVlcyBhbmQgc2V0RWxlbWVudEF0IGEgaGlnaGVyIGluZGV4IGFnYWluLCB5b3UgbWF5IHNlZSBvbGQgZGF0YQotICogcmVhcHBlYXIgaW4gdGhlIHRydW5jYXRlZC1hbmQtcmVzdG9yZWQgc2VjdGlvbi4gRG9pbmcgYW55dGhpbmcgZWxzZSB3b3VsZAotICogaGF2ZSBwZXJmb3JtYW5jZSBjb3N0cy4KLSAqLwotcHVibGljIGNsYXNzIFN1YmFsbG9jYXRlZEJ5dGVWZWN0b3IKLXsKLSAgLyoqIFNpemUgb2YgYmxvY2tzIHRvIGFsbG9jYXRlICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9ibG9ja3NpemU7Ci0gIAotICAvKiogTnVtYmVyIG9mIGJsb2NrcyB0byAob3ZlcilhbGxvY2F0ZSBieSAqLwotICBwcm90ZWN0ZWQgIGludCBtX251bWJsb2Nrcz0zMjsKLSAgCi0gIC8qKiBBcnJheSBvZiBhcnJheXMgb2YgYnl0ZXMgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGJ5dGUgbV9tYXBbXVtdOwotCi0gIC8qKiBOdW1iZXIgb2YgYnl0ZXMgaW4gYXJyYXkgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2ZpcnN0RnJlZSA9IDA7Ci0KLSAgLyoqICJTaG9ydGN1dCIgaGFuZGxlIHRvIG1fbWFwWzBdICovCi0gIHByb3RlY3RlZCBieXRlIG1fbWFwMFtdOwotCi0gIC8qKgotICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiAgTm90ZSB0aGF0IHRoZSBkZWZhdWx0Ci0gICAqIGJsb2NrIHNpemUgaXMgdmVyeSBzbWFsbCwgZm9yIHNtYWxsIGxpc3RzLgotICAgKi8KLSAgcHVibGljIFN1YmFsbG9jYXRlZEJ5dGVWZWN0b3IoKQotICB7Ci0gICAgdGhpcygyMDQ4KTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBCeXRlVmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgU3ViYWxsb2NhdGVkQnl0ZVZlY3RvcihpbnQgYmxvY2tzaXplKQotICB7Ci0gICAgbV9ibG9ja3NpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXAwPW5ldyBieXRlW2Jsb2Nrc2l6ZV07Ci0gICAgbV9tYXAgPSBuZXcgYnl0ZVttX251bWJsb2Nrc11bXTsKLSAgICBtX21hcFswXT1tX21hcDA7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBCeXRlVmVjdG9yLCB1c2luZyB0aGUgZ2l2ZW4gYmxvY2sgc2l6ZS4KLSAgICoKLSAgICogQHBhcmFtIGJsb2Nrc2l6ZSBTaXplIG9mIGJsb2NrIHRvIGFsbG9jYXRlCi0gICAqLwotICBwdWJsaWMgU3ViYWxsb2NhdGVkQnl0ZVZlY3RvcihpbnQgYmxvY2tzaXplLCBpbnQgaW5jcmVhc2VTaXplKQotICB7Ci0gICAgLy8gaW5jcmVhc2VTaXplIG5vdCBjdXJyZW50bHkgdXNlZC4KLSAgICB0aGlzKGJsb2Nrc2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHByaXZhdGUgIHZvaWQgc2V0U2l6ZShpbnQgc3opCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZTxzeikKLSAgICAgIG1fZmlyc3RGcmVlID0gc3o7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgYnl0ZSBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBCeXRlIHRvIGFkZCB0byB0aGUgbGlzdCAKLSAgICovCi0gIHB1YmxpYyAgdm9pZCBhZGRFbGVtZW50KGJ5dGUgdmFsdWUpCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZTxtX2Jsb2Nrc2l6ZSkKLSAgICAgIG1fbWFwMFttX2ZpcnN0RnJlZSsrXT12YWx1ZTsKLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PW1fZmlyc3RGcmVlL21fYmxvY2tzaXplOwotICAgICAgaW50IG9mZnNldD1tX2ZpcnN0RnJlZSVtX2Jsb2Nrc2l6ZTsKLSAgICAgICsrbV9maXJzdEZyZWU7Ci0KLSAgICAgIGlmKGluZGV4Pj1tX21hcC5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotICAgICAgICBieXRlW11bXSBuZXdNYXA9bmV3IGJ5dGVbbmV3c2l6ZV1bXTsKLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcC5sZW5ndGgpOwotICAgICAgICBtX21hcD1uZXdNYXA7Ci0gICAgICB9Ci0gICAgICBieXRlW10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgYnl0ZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIEFwcGVuZCBzZXZlcmFsIGJ5dGUgdmFsdWVzIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEJ5dGUgdG8gYWRkIHRvIHRoZSBsaXN0IAotICAgKi8KLSAgcHJpdmF0ZSAgdm9pZCBhZGRFbGVtZW50cyhieXRlIHZhbHVlLCBpbnQgbnVtYmVyT2ZFbGVtZW50cykKLSAgewotICAgIGlmKG1fZmlyc3RGcmVlK251bWJlck9mRWxlbWVudHM8bV9ibG9ja3NpemUpCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlck9mRWxlbWVudHM7IGkrKykgCi0gICAgICB7Ci0gICAgICAgIG1fbWFwMFttX2ZpcnN0RnJlZSsrXT12YWx1ZTsKLSAgICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PW1fZmlyc3RGcmVlL21fYmxvY2tzaXplOwotICAgICAgaW50IG9mZnNldD1tX2ZpcnN0RnJlZSVtX2Jsb2Nrc2l6ZTsKLSAgICAgIG1fZmlyc3RGcmVlKz1udW1iZXJPZkVsZW1lbnRzOwotICAgICAgd2hpbGUoIG51bWJlck9mRWxlbWVudHM+MCkKLSAgICAgIHsKLSAgICAgICAgaWYoaW5kZXg+PW1fbWFwLmxlbmd0aCkKLSAgICAgICAgewotICAgICAgICAgIGludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotICAgICAgICAgIGJ5dGVbXVtdIG5ld01hcD1uZXcgYnl0ZVtuZXdzaXplXVtdOwotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9tYXAubGVuZ3RoKTsKLSAgICAgICAgICBtX21hcD1uZXdNYXA7Ci0gICAgICAgIH0KLSAgICAgICAgYnl0ZVtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBieXRlW21fYmxvY2tzaXplXTsKLSAgICAgICAgaW50IGNvcGllZD0obV9ibG9ja3NpemUtb2Zmc2V0IDwgbnVtYmVyT2ZFbGVtZW50cykKLSAgICAgICAgICA/IG1fYmxvY2tzaXplLW9mZnNldCA6IG51bWJlck9mRWxlbWVudHM7Ci0gICAgICAgIG51bWJlck9mRWxlbWVudHMtPWNvcGllZDsKLSAgICAgICAgd2hpbGUoY29waWVkLS0gPiAwKQotICAgICAgICAgIGJsb2NrW29mZnNldCsrXT12YWx1ZTsKLQotICAgICAgICArK2luZGV4O29mZnNldD0wOwotICAgICAgfQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIEFwcGVuZCBzZXZlcmFsIHNsb3RzIG9udG8gdGhlIHZlY3RvciwgYnV0IGRvIG5vdCBzZXQgdGhlIHZhbHVlcy4KLSAgICogTm90ZTogIk5vdCBTZXQiIG1lYW5zIHRoZSB2YWx1ZSBpcyB1bnNwZWNpZmllZC4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEJ5dGUgdG8gYWRkIHRvIHRoZSBsaXN0IAotICAgKi8KLSAgcHJpdmF0ZSAgdm9pZCBhZGRFbGVtZW50cyhpbnQgbnVtYmVyT2ZFbGVtZW50cykKLSAgewotICAgIGludCBuZXdsZW49bV9maXJzdEZyZWUrbnVtYmVyT2ZFbGVtZW50czsKLSAgICBpZihuZXdsZW4+bV9ibG9ja3NpemUpCi0gICAgewotICAgICAgaW50IGluZGV4PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotICAgICAgaW50IG5ld2luZGV4PShtX2ZpcnN0RnJlZStudW1iZXJPZkVsZW1lbnRzKSVtX2Jsb2Nrc2l6ZTsKLSAgICAgIGZvcihpbnQgaT1pbmRleCsxO2k8PW5ld2luZGV4OysraSkKLSAgICAgICAgbV9tYXBbaV09bmV3IGJ5dGVbbV9ibG9ja3NpemVdOwotICAgIH0KLSAgICBtX2ZpcnN0RnJlZT1uZXdsZW47Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbm9kZSBpbiB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiBFYWNoIGNvbXBvbmVudCBpbiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8KLSAgICogdGhlIHNwZWNpZmllZCBpbmRleCBpcyBzaGlmdGVkIHVwd2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBncmVhdGVyCi0gICAqIHRoYW4gdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBJbnNlcnRpb24gbWF5IGJlIGFuIEVYUEVOU0lWRSBvcGVyYXRpb24hCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBCeXRlIHRvIGluc2VydAotICAgKiBAcGFyYW0gYXQgSW5kZXggb2Ygd2hlcmUgdG8gaW5zZXJ0IAotICAgKi8KLSAgcHJpdmF0ZSAgdm9pZCBpbnNlcnRFbGVtZW50QXQoYnl0ZSB2YWx1ZSwgaW50IGF0KQotICB7Ci0gICAgaWYoYXQ9PW1fZmlyc3RGcmVlKQotICAgICAgYWRkRWxlbWVudCh2YWx1ZSk7Ci0gICAgZWxzZSBpZiAoYXQ+bV9maXJzdEZyZWUpCi0gICAgewotICAgICAgaW50IGluZGV4PWF0L21fYmxvY2tzaXplOwotICAgICAgaWYoaW5kZXg+PW1fbWFwLmxlbmd0aCkKLSAgICAgIHsKLSAgICAgICAgaW50IG5ld3NpemU9aW5kZXgrbV9udW1ibG9ja3M7Ci0gICAgICAgIGJ5dGVbXVtdIG5ld01hcD1uZXcgYnl0ZVtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fbWFwLmxlbmd0aCk7Ci0gICAgICAgIG1fbWFwPW5ld01hcDsKLSAgICAgIH0KLSAgICAgIGJ5dGVbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBieXRlW21fYmxvY2tzaXplXTsKLSAgICAgIGludCBvZmZzZXQ9YXQlbV9ibG9ja3NpemU7Ci0gICAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotICAgICAgbV9maXJzdEZyZWU9b2Zmc2V0KzE7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9YXQvbV9ibG9ja3NpemU7Ci0gICAgICBpbnQgbWF4aW5kZXg9bV9maXJzdEZyZWUrMS9tX2Jsb2Nrc2l6ZTsKLSAgICAgICsrbV9maXJzdEZyZWU7Ci0gICAgICBpbnQgb2Zmc2V0PWF0JW1fYmxvY2tzaXplOwotICAgICAgYnl0ZSBwdXNoOwotICAgICAgCi0gICAgICAvLyAqKioqKiBFYXNpZXIgdG8gd29yayBkb3duIGZyb20gdG9wPwotICAgICAgd2hpbGUoaW5kZXg8PW1heGluZGV4KQotICAgICAgewotICAgICAgICBpbnQgY29weWxlbj1tX2Jsb2Nrc2l6ZS1vZmZzZXQtMTsKLSAgICAgICAgYnl0ZVtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgIHsKLSAgICAgICAgICBwdXNoPTA7Ci0gICAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBieXRlW21fYmxvY2tzaXplXTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBwdXNoPWJsb2NrW21fYmxvY2tzaXplLTFdOwotICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYmxvY2ssIG9mZnNldCAsIGJsb2NrLCBvZmZzZXQrMSwgY29weWxlbik7Ci0gICAgICAgIH0KLSAgICAgICAgYmxvY2tbb2Zmc2V0XT12YWx1ZTsKLSAgICAgICAgdmFsdWU9cHVzaDsKLSAgICAgICAgb2Zmc2V0PTA7Ci0gICAgICAgICsraW5kZXg7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFdpcGUgaXQgb3V0LiAKLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBmcm9tIHRoaXMgdmVjdG9yLgotICAgKiBJZiB0aGUgb2JqZWN0IGlzIGZvdW5kIGluIHRoaXMgdmVjdG9yLCBlYWNoIGNvbXBvbmVudCBpbiB0aGUgdmVjdG9yCi0gICAqIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgb2JqZWN0J3MgaW5kZXggaXMgc2hpZnRlZAotICAgKiBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4gdGhlIHZhbHVlIGl0IGhhZAotICAgKiBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gcyBCeXRlIHRvIHJlbW92ZSBmcm9tIGFycmF5Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgYnl0ZSB3YXMgcmVtb3ZlZCwgZmFsc2UgaWYgaXQgd2FzIG5vdCBmb3VuZAotICAgKi8KLSAgcHJpdmF0ZSAgYm9vbGVhbiByZW1vdmVFbGVtZW50KGJ5dGUgcykKLSAgewotICAgIGludCBhdD1pbmRleE9mKHMsMCk7Ci0gICAgaWYoYXQ8MCkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICByZW1vdmVFbGVtZW50QXQoYXQpOwotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIERlbGV0ZXMgdGhlIGNvbXBvbmVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBFYWNoIGNvbXBvbmVudCBpbgotICAgKiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8gdGhlIHNwZWNpZmllZAotICAgKiBpbmRleCBpcyBzaGlmdGVkIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbgotICAgKiB0aGUgdmFsdWUgaXQgaGFkIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBhdCBpbmRleCBvZiB3aGVyZSB0byByZW1vdmUgYSBieXRlCi0gICAqLwotICBwcml2YXRlICB2b2lkIHJlbW92ZUVsZW1lbnRBdChpbnQgYXQpCi0gIHsKLSAgICAvLyBObyBwb2ludCBpbiByZW1vdmluZyBlbGVtZW50cyB0aGF0ICJkb24ndCBleGlzdCIuLi4gIAotICAgIGlmKGF0PG1fZmlyc3RGcmVlKQotICAgIHsKLSAgICAgIGludCBpbmRleD1hdC9tX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBtYXhpbmRleD1tX2ZpcnN0RnJlZS9tX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBvZmZzZXQ9YXQlbV9ibG9ja3NpemU7Ci0gICAgICAKLSAgICAgIHdoaWxlKGluZGV4PD1tYXhpbmRleCkKLSAgICAgIHsKLSAgICAgICAgaW50IGNvcHlsZW49bV9ibG9ja3NpemUtb2Zmc2V0LTE7Ci0gICAgICAgIGJ5dGVbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgYnl0ZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJsb2NrLCBvZmZzZXQrMSwgYmxvY2ssIG9mZnNldCwgY29weWxlbik7Ci0gICAgICAgIGlmKGluZGV4PG1heGluZGV4KQotICAgICAgICB7Ci0gICAgICAgICAgYnl0ZVtdIG5leHQ9bV9tYXBbaW5kZXgrMV07Ci0gICAgICAgICAgaWYobmV4dCE9bnVsbCkKLSAgICAgICAgICAgIGJsb2NrW21fYmxvY2tzaXplLTFdPShuZXh0IT1udWxsKSA/IG5leHRbMF0gOiAwOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBibG9ja1ttX2Jsb2Nrc2l6ZS0xXT0wOwotICAgICAgICBvZmZzZXQ9MDsKLSAgICAgICAgKytpbmRleDsKLSAgICAgIH0KLSAgICB9Ci0gICAgLS1tX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXRzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHZlY3RvciB0byBiZSB0aGUKLSAgICogc3BlY2lmaWVkIG9iamVjdC4gVGhlIHByZXZpb3VzIGNvbXBvbmVudCBhdCB0aGF0IHBvc2l0aW9uIGlzIGRpc2NhcmRlZC4KLSAgICoKLSAgICogVGhlIGluZGV4IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcwotICAgKiB0aGFuIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgb2JqZWN0IHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVsZW1lbnRBdChieXRlIHZhbHVlLCBpbnQgYXQpCi0gIHsKLSAgICBpZihhdDxtX2Jsb2Nrc2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcDBbYXRdPXZhbHVlOwotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIGludCBpbmRleD1hdC9tX2Jsb2Nrc2l6ZTsKLSAgICBpbnQgb2Zmc2V0PWF0JW1fYmxvY2tzaXplOwotICAgICAgICAKLSAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgIHsKLSAgICAgIGludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotICAgICAgYnl0ZVtdW10gbmV3TWFwPW5ldyBieXRlW25ld3NpemVdW107Ci0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fbWFwLmxlbmd0aCk7Ci0gICAgICBtX21hcD1uZXdNYXA7Ci0gICAgfQotCi0gICAgYnl0ZVtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICBpZihudWxsPT1ibG9jaykKLSAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgYnl0ZVttX2Jsb2Nrc2l6ZV07Ci0gICAgYmxvY2tbb2Zmc2V0XT12YWx1ZTsKLQotICAgIGlmKGF0Pj1tX2ZpcnN0RnJlZSkKLSAgICAgIG1fZmlyc3RGcmVlPWF0KzE7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4gVGhpcyBpcyBvZnRlbiBhdCB0aGUgaW5uZXJtb3N0IGxvb3Agb2YgYW4KLSAgICogYXBwbGljYXRpb24sIHNvIHBlcmZvcm1hbmNlIGlzIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBvZiB2YWx1ZSB0byBnZXQKLSAgICoKLSAgICogQHJldHVybiB2YWx1ZSBhdCBnaXZlbiBpbmRleC4gSWYgdGhhdCB2YWx1ZSB3YXNuJ3QgcHJldmlvdXNseSBzZXQsCi0gICAqIHRoZSByZXN1bHQgaXMgdW5kZWZpbmVkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLiBJdCBtYXkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uIChzZWUgYmVsb3cpLCBtYXkgcmV0dXJuIHplcm8sIG9yIChpZiBzZXRTaXplIGhhcyBwcmV2aW91c2x5Ci0gICAqIGJlZW4gdXNlZCkgbWF5IHJldHVybiBzdGFsZSBkYXRhLgotICAgKgotICAgKiBAdGhyb3cgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHRoZSBpbmRleCB3YXMgX2NsZWFybHlfCi0gICAqIHVucmVhc29uYWJsZSAobmVnYXRpdmUsIG9yIHBhc3QgdGhlIGhpZ2hlc3QgYmxvY2spLgotICAgKgotICAgKiBAdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGluZGV4IHBvaW50cyB0byBhIGJsb2NrIHRoYXQgY291bGQKLSAgICogaGF2ZSBleGlzdGVkIChiYXNlZCBvbiB0aGUgaGlnaGVzdCBpbmRleCB1c2VkKSBidXQgaGFzIG5ldmVyIGhhZCBhbnl0aGluZwotICAgKiBzZXQgaW50byBpdC4KLSAgICogJVJFVklFVyUgQ291bGQgYWRkIGEgY2F0Y2ggdG8gY3JlYXRlIHRoZSBibG9jayBpbiB0aGF0IGNhc2UsIG9yIHJldHVybiAwLgotICAgKiBUcnkvQ2F0Y2ggaXMgX3N1cHBvc2VkXyB0byBiZSBuZWFybHkgZnJlZSB3aGVuIG5vdCB0aHJvd24gdG8uIERvIHdlCi0gICAqIGJlbGlldmUgdGhhdD8gU2hvdWxkIHdlIGhhdmUgYSBzZXBhcmF0ZSBzYWZlRWxlbWVudEF0PwotICAgKi8KLSAgcHVibGljIGJ5dGUgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgLy8gJU9QVCUgRG9lcyB0aGlzIHJlYWxseSBidXkgdXMgYW55dGhpbmc/IFRlc3QgdmVyc3VzIGRpdmlzaW9uIGZvciBzbWFsbCwKLSAgICAvLyB0ZXN0IF9wbHVzXyBkaXZpc2lvbiBmb3IgYmlnIGRvY3MuCi0gICAgaWYoaTxtX2Jsb2Nrc2l6ZSkKLSAgICAgIHJldHVybiBtX21hcDBbaV07Ci0KLSAgICByZXR1cm4gbV9tYXBbaS9tX2Jsb2Nrc2l6ZV1baSVtX2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIG9iamVjdCB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHJpdmF0ZSAgYm9vbGVhbiBjb250YWlucyhieXRlIHMpCi0gIHsKLSAgICByZXR1cm4gKGluZGV4T2YocywwKSA+PSAwKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIG9iamVjdCB0byBsb29rIGZvcgotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gYmVnaW4gc2VhcmNoCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihieXRlIGVsZW0sIGludCBpbmRleCkKLSAgewotICAgIGlmKGluZGV4Pj1tX2ZpcnN0RnJlZSkKLSAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAKLSAgICBpbnQgYmluZGV4PWluZGV4L21fYmxvY2tzaXplOwotICAgIGludCBib2Zmc2V0PWluZGV4JW1fYmxvY2tzaXplOwotICAgIGludCBtYXhpbmRleD1tX2ZpcnN0RnJlZS9tX2Jsb2Nrc2l6ZTsKLSAgICBieXRlW10gYmxvY2s7Ci0gICAgCi0gICAgZm9yKDtiaW5kZXg8bWF4aW5kZXg7KytiaW5kZXgpCi0gICAgewotICAgICAgYmxvY2s9bV9tYXBbYmluZGV4XTsKLSAgICAgIGlmKGJsb2NrIT1udWxsKQotICAgICAgICBmb3IoaW50IG9mZnNldD1ib2Zmc2V0O29mZnNldDxtX2Jsb2Nrc2l6ZTsrK29mZnNldCkKLSAgICAgICAgICBpZihibG9ja1tvZmZzZXRdPT1lbGVtKQotICAgICAgICAgICAgcmV0dXJuIG9mZnNldCtiaW5kZXgqbV9ibG9ja3NpemU7Ci0gICAgICBib2Zmc2V0PTA7IC8vIGFmdGVyIGZpcnN0Ci0gICAgfQotICAgIC8vIExhc3QgYmxvY2sgbWF5IG5lZWQgdG8gc3RvcCBiZWZvcmUgZW5kCi0gICAgaW50IG1heG9mZnNldD1tX2ZpcnN0RnJlZSVtX2Jsb2Nrc2l6ZTsKLSAgICBibG9jaz1tX21hcFttYXhpbmRleF07Ci0gICAgZm9yKGludCBvZmZzZXQ9Ym9mZnNldDtvZmZzZXQ8bWF4b2Zmc2V0Oysrb2Zmc2V0KQotICAgICAgaWYoYmxvY2tbb2Zmc2V0XT09ZWxlbSkKLSAgICAgICAgcmV0dXJuIG9mZnNldCttYXhpbmRleCptX2Jsb2Nrc2l6ZTsKLQotICAgIHJldHVybiAtMTsgICAgCi0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBvYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGJ5dGUgZWxlbSkKLSAgewotICAgIHJldHVybiBpbmRleE9mKGVsZW0sMCk7Ci0gIH0KLQotICAvKioKLSAgICogU2VhcmNoZXMgZm9yIHRoZSBmaXJzdCBvY2N1cmVuY2Ugb2YgdGhlIGdpdmVuIGFyZ3VtZW50LAotICAgKiBiZWdpbm5pbmcgdGhlIHNlYXJjaCBhdCBpbmRleCwgYW5kIHRlc3RpbmcgZm9yIGVxdWFsaXR5Ci0gICAqIHVzaW5nIHRoZSBlcXVhbHMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBPYmplY3QgdG8gbG9vayBmb3IKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHJpdmF0ZSAgaW50IGxhc3RJbmRleE9mKGJ5dGUgZWxlbSkKLSAgewotICAgIGludCBib2Zmc2V0PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotICAgIGZvcihpbnQgaW5kZXg9bV9maXJzdEZyZWUvbV9ibG9ja3NpemU7Ci0gICAgICAgIGluZGV4Pj0wOwotICAgICAgICAtLWluZGV4KQotICAgIHsKLSAgICAgIGJ5dGVbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICBpZihibG9jayE9bnVsbCkKLSAgICAgICAgZm9yKGludCBvZmZzZXQ9Ym9mZnNldDsgb2Zmc2V0Pj0wOyAtLW9mZnNldCkKLSAgICAgICAgICBpZihibG9ja1tvZmZzZXRdPT1lbGVtKQotICAgICAgICAgICAgcmV0dXJuIG9mZnNldCtpbmRleCptX2Jsb2Nrc2l6ZTsKLSAgICAgIGJvZmZzZXQ9MDsgLy8gYWZ0ZXIgZmlyc3QKLSAgICB9Ci0gICAgcmV0dXJuIC0xOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdWJhbGxvY2F0ZWRJbnRWZWN0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TdWJhbGxvY2F0ZWRJbnRWZWN0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2Q3MjU2YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvU3ViYWxsb2NhdGVkSW50VmVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NDcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBBIHZlcnkgc2ltcGxlIHRhYmxlIHRoYXQgc3RvcmVzIGEgbGlzdCBvZiBpbnQuIFZlcnkgc2ltaWxhciBBUEkgdG8gb3VyCi0gKiBJbnRWZWN0b3IgY2xhc3MgKHNhbWUgQVBJKTsgZGlmZmVyZW50IGludGVybmFsIHN0b3JhZ2UuCi0gKiAKLSAqIFRoaXMgdmVyc2lvbiB1c2VzIGFuIGFycmF5LW9mLWFycmF5cyBzb2x1dGlvbi4gUmVhZC93cml0ZSBhY2Nlc3MgaXMgdGh1cwotICogYSBiaXQgc2xvd2VyIHRoYW4gdGhlIHNpbXBsZSBJbnRWZWN0b3IsIGFuZCBiYXNpYyBzdG9yYWdlIGlzIGEgdHJpZmxlCi0gKiBoaWdoZXIgZHVlIHRvIHRoZSB0b3AtbGV2ZWwgYXJyYXkgLS0gYnV0IGFwcGVuZGluZyBpcyBPKDEpIGZhc3QgcmF0aGVyCi0gKiB0aGFuIE8oTioqMikgc2xvdywgd2hpY2ggd2lsbCBzd2FtcCB0aG9zZSBjb3N0cyBpbiBzaXR1YXRpb25zIHdoZXJlCi0gKiBsb25nIHZlY3RvcnMgYXJlIGJlaW5nIGJ1aWx0IHVwLgotICogCi0gKiBLbm93biBpc3N1ZXM6Ci0gKgotICogQ3VycmVudCBjaHVua2luZyBpcyBiYXNlZCBvbiAvJS4gU2hpZnQvbWFzayBfc2hvdWxkXyBiZSBmYXN0ZXIsIGlmCi0gKiBwb3dlci1vZi10d28gY2h1bmtzaXplcyBhcmUgYWNjZXB0YWJsZS4gKFdvdWxkIGJlIGluIGEgcmVhbCBsYW5ndWFnZSwKLSAqIGFueXdheS4uLikgU29tZSBjb21waWxlcnMgX21heV8gYmUgc21hcnQgZW5vdWdoIHRvIGNvbnZlcnQgdGhlIGZvcm1lcgotICogdG8gdGhlIGxhdHRlciBpZiB0aGUgYmxvY2sgc2l6ZSBpcyBhIGNvbnN0YW50IHBvd2VyIG9mIHR3by4uLiBzbyB3ZSBoYXZlCi0gKiBvdXIgY2hvaWNlIG9mIGxvY2tpbmcgaW4gYSBzcGVjaWZpYyBzaXplLCBvciBjb252ZXJ0aW5nIHRvIHNoaWZ0L21hc2ssCi0gKiBvciBib3RoLi4uCi0gKiAKLSAqIFNvbWUgbWV0aG9kcyBhcmUgcHJpdmF0ZSBiZWNhdXNlIHRoZXkgaGF2ZW4ndCB5ZXQgYmVlbiB0ZXN0ZWQgcHJvcGVybHkuCi0gKgotICogUmV0cmlldmFsIHBlcmZvcm1hbmNlIGlzIGNyaXRpY2FsLCBzaW5jZSB0aGlzIGlzIHVzZWQgYXQgdGhlIGNvcmUKLSAqIG9mIHRoZSBEVE0gbW9kZWwuIChDb25zdHJ1Y3Rpb24gcGVyZm9ybWFuY2UgaXMgYWxtb3N0IGFzCi0gKiBpbXBvcnRhbnQuKSBUaGF0J3MgcHVzaGluZyBtZSB0b3dhcmQganVzdCBsZXR0aW5nIHJlYWRzIG9mIHVuc2V0Ci0gKiBpbmRpY2VzIHRocm93IGV4Y2VwdGlvbnMgb3IgcmV0dXJuIHN0YWxlIGRhdGE7IHNhZmVyIGJlaGF2aW9yIHdvdWxkCi0gKiBoYXZlIHBlcmZvcm1hbmNlIGNvc3RzLiAqLwotcHVibGljIGNsYXNzIFN1YmFsbG9jYXRlZEludFZlY3RvcgotewotICAvKiogU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2Jsb2Nrc2l6ZTsKLSAgCi0gIC8qKiBOdW1iZXIgb2YgYmxvY2tzIHRvIChvdmVyKWFsbG9jYXRlIGJ5ICovCi0gIHByb3RlY3RlZCAgaW50IG1fbnVtYmxvY2tzPTMyOwotICAKLSAgLyoqIEFycmF5IG9mIGFycmF5cyBvZiBpbnRzICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9tYXBbXVtdOwotCi0gIC8qKiBOdW1iZXIgb2YgaW50cyBpbiBhcnJheSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgaW50IG1fZmlyc3RGcmVlID0gMDsKLQotICAvKiogIlNob3J0Y3V0IiBoYW5kbGUgdG8gbV9tYXBbMF0gKi8KLSAgcHJvdGVjdGVkIGludCBtX21hcDBbXTsKLQotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gIE5vdGUgdGhhdCB0aGUgZGVmYXVsdAotICAgKiBibG9jayBzaXplIGlzIHZlcnkgc21hbGwsIGZvciBzbWFsbCBsaXN0cy4KLSAgICovCi0gIHB1YmxpYyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoKQotICB7Ci0gICAgdGhpcygyMDQ4KTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBJbnRWZWN0b3IsIHVzaW5nIHRoZSBnaXZlbiBibG9jayBzaXplLgotICAgKgotICAgKiBAcGFyYW0gYmxvY2tzaXplIFNpemUgb2YgYmxvY2sgdG8gYWxsb2NhdGUKLSAgICovCi0gIHB1YmxpYyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IoaW50IGJsb2Nrc2l6ZSkKLSAgewotICAgIG1fYmxvY2tzaXplID0gYmxvY2tzaXplOwotICAgIG1fbWFwMD1uZXcgaW50W2Jsb2Nrc2l6ZV07Ci0gICAgbV9tYXAgPSBuZXcgaW50W21fbnVtYmxvY2tzXVtdOwotICAgIG1fbWFwWzBdPW1fbWFwMDsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEludFZlY3RvciwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9jayB0byBhbGxvY2F0ZQotICAgKi8KLSAgcHVibGljIFN1YmFsbG9jYXRlZEludFZlY3RvcihpbnQgYmxvY2tzaXplLCBpbnQgaW5jcmVhc2VTaXplKQotICB7Ci0gICAgLy8gaW5jcmVhc2VTaXplIG5vdCBjdXJyZW50bHkgdXNlZC4KLSAgICB0aGlzKGJsb2Nrc2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBsZW5ndGggb2YgdGhlIGxpc3QKLSAgICovCi0gIHByaXZhdGUgIHZvaWQgc2V0U2l6ZShpbnQgc3opCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZTxzeikKLSAgICAgIG1fZmlyc3RGcmVlID0gc3o7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgaW50IG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEludCB0byBhZGQgdG8gdGhlIGxpc3QgCi0gICAqLwotICBwdWJsaWMgIHZvaWQgYWRkRWxlbWVudChpbnQgdmFsdWUpCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZTxtX2Jsb2Nrc2l6ZSkKLSAgICAgIG1fbWFwMFttX2ZpcnN0RnJlZSsrXT12YWx1ZTsKLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gR3Jvd2luZyB0aGUgb3V0ZXIgYXJyYXkgc2hvdWxkIGJlIHJhcmUuIFdlIGluaXRpYWxpemUgdG8gYQotICAgICAgLy8gdG90YWwgb2YgbV9ibG9ja3NpemUgc3F1YXJlZCBlbGVtZW50cywgd2hpY2ggYXQgdGhlIGRlZmF1bHQKLSAgICAgIC8vIHNpemUgaXMgNE0gaW50ZWdlcnMuLi4gYW5kIHdlIGdyb3cgYnkgYXQgbGVhc3QgdGhhdCBtdWNoIGVhY2gKLSAgICAgIC8vIHRpbWUuICBIb3dldmVyLCBhdHRlbXB0cyB0byBtaWNyb29wdGltaXplIGZvciB0aGlzIChhc3N1bWUKLSAgICAgIC8vIGxvbmcgZW5vdWdoIGFuZCBjYXRjaCBleGNlcHRpb25zKSB5aWVsZCBubyBub3RpY2FibGUKLSAgICAgIC8vIGltcHJvdmVtZW50LgotCi0gICAgICBpbnQgaW5kZXg9bV9maXJzdEZyZWUvbV9ibG9ja3NpemU7Ci0gICAgICBpbnQgb2Zmc2V0PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotCi0gICAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgICAgewotCWludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotCWludFtdW10gbmV3TWFwPW5ldyBpbnRbbmV3c2l6ZV1bXTsKLQlTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fbWFwLmxlbmd0aCk7Ci0JbV9tYXA9bmV3TWFwOwotICAgICAgfQotICAgICAgaW50W10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgaWYobnVsbD09YmxvY2spCi0JYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgYmxvY2tbb2Zmc2V0XT12YWx1ZTsKLQotICAgICAgKyttX2ZpcnN0RnJlZTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBBcHBlbmQgc2V2ZXJhbCBpbnQgdmFsdWVzIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEludCB0byBhZGQgdG8gdGhlIGxpc3QgCi0gICAqLwotICBwcml2YXRlICB2b2lkIGFkZEVsZW1lbnRzKGludCB2YWx1ZSwgaW50IG51bWJlck9mRWxlbWVudHMpCi0gIHsKLSAgICBpZihtX2ZpcnN0RnJlZStudW1iZXJPZkVsZW1lbnRzPG1fYmxvY2tzaXplKQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1iZXJPZkVsZW1lbnRzOyBpKyspIAotICAgICAgewotICAgICAgICBtX21hcDBbbV9maXJzdEZyZWUrK109dmFsdWU7Ci0gICAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBpbmRleD1tX2ZpcnN0RnJlZS9tX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBvZmZzZXQ9bV9maXJzdEZyZWUlbV9ibG9ja3NpemU7Ci0gICAgICBtX2ZpcnN0RnJlZSs9bnVtYmVyT2ZFbGVtZW50czsKLSAgICAgIHdoaWxlKCBudW1iZXJPZkVsZW1lbnRzPjApCi0gICAgICB7Ci0gICAgICAgIGlmKGluZGV4Pj1tX21hcC5sZW5ndGgpCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgbmV3c2l6ZT1pbmRleCttX251bWJsb2NrczsKLSAgICAgICAgICBpbnRbXVtdIG5ld01hcD1uZXcgaW50W25ld3NpemVdW107Ci0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX21hcC5sZW5ndGgpOwotICAgICAgICAgIG1fbWFwPW5ld01hcDsKLSAgICAgICAgfQotICAgICAgICBpbnRbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgICAgIGJsb2NrPW1fbWFwW2luZGV4XT1uZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICAgICAgaW50IGNvcGllZD0obV9ibG9ja3NpemUtb2Zmc2V0IDwgbnVtYmVyT2ZFbGVtZW50cykKLSAgICAgICAgICA/IG1fYmxvY2tzaXplLW9mZnNldCA6IG51bWJlck9mRWxlbWVudHM7Ci0gICAgICAgIG51bWJlck9mRWxlbWVudHMtPWNvcGllZDsKLSAgICAgICAgd2hpbGUoY29waWVkLS0gPiAwKQotICAgICAgICAgIGJsb2NrW29mZnNldCsrXT12YWx1ZTsKLQotICAgICAgICArK2luZGV4O29mZnNldD0wOwotICAgICAgfQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIEFwcGVuZCBzZXZlcmFsIHNsb3RzIG9udG8gdGhlIHZlY3RvciwgYnV0IGRvIG5vdCBzZXQgdGhlIHZhbHVlcy4KLSAgICogTm90ZTogIk5vdCBTZXQiIG1lYW5zIHRoZSB2YWx1ZSBpcyB1bnNwZWNpZmllZC4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIEludCB0byBhZGQgdG8gdGhlIGxpc3QgCi0gICAqLwotICBwcml2YXRlICB2b2lkIGFkZEVsZW1lbnRzKGludCBudW1iZXJPZkVsZW1lbnRzKQotICB7Ci0gICAgaW50IG5ld2xlbj1tX2ZpcnN0RnJlZStudW1iZXJPZkVsZW1lbnRzOwotICAgIGlmKG5ld2xlbj5tX2Jsb2Nrc2l6ZSkKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9bV9maXJzdEZyZWUlbV9ibG9ja3NpemU7Ci0gICAgICBpbnQgbmV3aW5kZXg9KG1fZmlyc3RGcmVlK251bWJlck9mRWxlbWVudHMpJW1fYmxvY2tzaXplOwotICAgICAgZm9yKGludCBpPWluZGV4KzE7aTw9bmV3aW5kZXg7KytpKQotICAgICAgICBtX21hcFtpXT1uZXcgaW50W21fYmxvY2tzaXplXTsKLSAgICB9Ci0gICAgbV9maXJzdEZyZWU9bmV3bGVuOwotICB9Ci0gIAotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogSW5zZXJ0aW9uIG1heSBiZSBhbiBFWFBFTlNJVkUgb3BlcmF0aW9uIQotICAgKgotICAgKiBAcGFyYW0gdmFsdWUgSW50IHRvIGluc2VydAotICAgKiBAcGFyYW0gYXQgSW5kZXggb2Ygd2hlcmUgdG8gaW5zZXJ0IAotICAgKi8KLSAgcHJpdmF0ZSAgdm9pZCBpbnNlcnRFbGVtZW50QXQoaW50IHZhbHVlLCBpbnQgYXQpCi0gIHsKLSAgICBpZihhdD09bV9maXJzdEZyZWUpCi0gICAgICBhZGRFbGVtZW50KHZhbHVlKTsKLSAgICBlbHNlIGlmIChhdD5tX2ZpcnN0RnJlZSkKLSAgICB7Ci0gICAgICBpbnQgaW5kZXg9YXQvbV9ibG9ja3NpemU7Ci0gICAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgICAgewotICAgICAgICBpbnQgbmV3c2l6ZT1pbmRleCttX251bWJsb2NrczsKLSAgICAgICAgaW50W11bXSBuZXdNYXA9bmV3IGludFtuZXdzaXplXVtdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fbWFwLmxlbmd0aCk7Ci0gICAgICAgIG1fbWFwPW5ld01hcDsKLSAgICAgIH0KLSAgICAgIGludFtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgIGlmKG51bGw9PWJsb2NrKQotICAgICAgICBibG9jaz1tX21hcFtpbmRleF09bmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0gICAgICBpbnQgb2Zmc2V0PWF0JW1fYmxvY2tzaXplOwotICAgICAgICAgIGJsb2NrW29mZnNldF09dmFsdWU7Ci0gICAgICAgICAgbV9maXJzdEZyZWU9b2Zmc2V0KzE7Ci0gICAgICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PWF0L21fYmxvY2tzaXplOwotICAgICAgaW50IG1heGluZGV4PW1fZmlyc3RGcmVlL21fYmxvY2tzaXplOyAvLyAlUkVWSUVXJSAobV9maXJzdEZyZWUrMT8pCi0gICAgICArK21fZmlyc3RGcmVlOwotICAgICAgaW50IG9mZnNldD1hdCVtX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBwdXNoOwotICAgICAgCi0gICAgICAvLyAqKioqKiBFYXNpZXIgdG8gd29yayBkb3duIGZyb20gdG9wPwotICAgICAgd2hpbGUoaW5kZXg8PW1heGluZGV4KQotICAgICAgewotICAgICAgICBpbnQgY29weWxlbj1tX2Jsb2Nrc2l6ZS1vZmZzZXQtMTsKLSAgICAgICAgaW50W10gYmxvY2s9bV9tYXBbaW5kZXhdOwotICAgICAgICBpZihudWxsPT1ibG9jaykKLSAgICAgICAgewotICAgICAgICAgIHB1c2g9MDsKLSAgICAgICAgICBibG9jaz1tX21hcFtpbmRleF09bmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgcHVzaD1ibG9ja1ttX2Jsb2Nrc2l6ZS0xXTsKLSAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJsb2NrLCBvZmZzZXQgLCBibG9jaywgb2Zmc2V0KzEsIGNvcHlsZW4pOwotICAgICAgICB9Ci0gICAgICAgIGJsb2NrW29mZnNldF09dmFsdWU7Ci0gICAgICAgIHZhbHVlPXB1c2g7Ci0gICAgICAgIG9mZnNldD0wOwotICAgICAgICArK2luZGV4OwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBXaXBlIGl0IG91dC4gQ3VycmVudGx5IGRlZmluZWQgYXMgZXF1aXZhbGVudCB0byBzZXRTaXplKDApLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlQWxsRWxlbWVudHMoKQotICB7Ci0gICAgbV9maXJzdEZyZWUgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGZyb20gdGhpcyB2ZWN0b3IuCi0gICAqIElmIHRoZSBvYmplY3QgaXMgZm91bmQgaW4gdGhpcyB2ZWN0b3IsIGVhY2ggY29tcG9uZW50IGluIHRoZSB2ZWN0b3IKLSAgICogd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBvYmplY3QncyBpbmRleCBpcyBzaGlmdGVkCi0gICAqIGRvd253YXJkIHRvIGhhdmUgYW4gaW5kZXggb25lIHNtYWxsZXIgdGhhbiB0aGUgdmFsdWUgaXQgaGFkCi0gICAqIHByZXZpb3VzbHkuCi0gICAqCi0gICAqIEBwYXJhbSBzIEludCB0byByZW1vdmUgZnJvbSBhcnJheQotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGludCB3YXMgcmVtb3ZlZCwgZmFsc2UgaWYgaXQgd2FzIG5vdCBmb3VuZAotICAgKi8KLSAgcHJpdmF0ZSAgYm9vbGVhbiByZW1vdmVFbGVtZW50KGludCBzKQotICB7Ci0gICAgaW50IGF0PWluZGV4T2YocywwKTsKLSAgICBpZihhdDwwKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIHJlbW92ZUVsZW1lbnRBdChhdCk7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogRGVsZXRlcyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEVhY2ggY29tcG9uZW50IGluCi0gICAqIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkCi0gICAqIGluZGV4IGlzIHNoaWZ0ZWQgZG93bndhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgc21hbGxlciB0aGFuCi0gICAqIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIGkgaW5kZXggb2Ygd2hlcmUgdG8gcmVtb3ZlIGFuZCBpbnQKLSAgICovCi0gIHByaXZhdGUgIHZvaWQgcmVtb3ZlRWxlbWVudEF0KGludCBhdCkKLSAgewotICAgICAgICAvLyBObyBwb2ludCBpbiByZW1vdmluZyBlbGVtZW50cyB0aGF0ICJkb24ndCBleGlzdCIuLi4gIAotICAgIGlmKGF0PG1fZmlyc3RGcmVlKQotICAgIHsKLSAgICAgIGludCBpbmRleD1hdC9tX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBtYXhpbmRleD1tX2ZpcnN0RnJlZS9tX2Jsb2Nrc2l6ZTsKLSAgICAgIGludCBvZmZzZXQ9YXQlbV9ibG9ja3NpemU7Ci0gICAgICAKLSAgICAgIHdoaWxlKGluZGV4PD1tYXhpbmRleCkKLSAgICAgIHsKLSAgICAgICAgaW50IGNvcHlsZW49bV9ibG9ja3NpemUtb2Zmc2V0LTE7Ci0gICAgICAgIGludFtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgICAgaWYobnVsbD09YmxvY2spCi0gICAgICAgICAgYmxvY2s9bV9tYXBbaW5kZXhdPW5ldyBpbnRbbV9ibG9ja3NpemVdOwotICAgICAgICBlbHNlCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShibG9jaywgb2Zmc2V0KzEsIGJsb2NrLCBvZmZzZXQsIGNvcHlsZW4pOwotICAgICAgICBpZihpbmRleDxtYXhpbmRleCkKLSAgICAgICAgewotICAgICAgICAgIGludFtdIG5leHQ9bV9tYXBbaW5kZXgrMV07Ci0gICAgICAgICAgaWYobmV4dCE9bnVsbCkKLSAgICAgICAgICAgIGJsb2NrW21fYmxvY2tzaXplLTFdPShuZXh0IT1udWxsKSA/IG5leHRbMF0gOiAwOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBibG9ja1ttX2Jsb2Nrc2l6ZS0xXT0wOwotICAgICAgICBvZmZzZXQ9MDsKLSAgICAgICAgKytpbmRleDsKLSAgICAgIH0KLSAgICB9Ci0gICAgLS1tX2ZpcnN0RnJlZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXRzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHZlY3RvciB0byBiZSB0aGUKLSAgICogc3BlY2lmaWVkIG9iamVjdC4gVGhlIHByZXZpb3VzIGNvbXBvbmVudCBhdCB0aGF0IHBvc2l0aW9uIGlzIGRpc2NhcmRlZC4KLSAgICoKLSAgICogVGhlIGluZGV4IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcwotICAgKiB0aGFuIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgb2JqZWN0IHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVsZW1lbnRBdChpbnQgdmFsdWUsIGludCBhdCkKLSAgewotICAgIGlmKGF0PG1fYmxvY2tzaXplKQotICAgICAgbV9tYXAwW2F0XT12YWx1ZTsKLSAgICBlbHNlCi0gICAgewotICAgICAgaW50IGluZGV4PWF0L21fYmxvY2tzaXplOwotICAgICAgaW50IG9mZnNldD1hdCVtX2Jsb2Nrc2l6ZTsKLSAgICAgICAgCi0gICAgICBpZihpbmRleD49bV9tYXAubGVuZ3RoKQotICAgICAgewotCWludCBuZXdzaXplPWluZGV4K21fbnVtYmxvY2tzOwotCWludFtdW10gbmV3TWFwPW5ldyBpbnRbbmV3c2l6ZV1bXTsKLQlTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIG1fbWFwLmxlbmd0aCk7Ci0JbV9tYXA9bmV3TWFwOwotICAgICAgfQotCi0gICAgICBpbnRbXSBibG9jaz1tX21hcFtpbmRleF07Ci0gICAgICBpZihudWxsPT1ibG9jaykKLQlibG9jaz1tX21hcFtpbmRleF09bmV3IGludFttX2Jsb2Nrc2l6ZV07Ci0gICAgICBibG9ja1tvZmZzZXRdPXZhbHVlOwotICAgIH0KLQotICAgIGlmKGF0Pj1tX2ZpcnN0RnJlZSkKLSAgICAgIG1fZmlyc3RGcmVlPWF0KzE7Ci0gIH0KLSAgCi0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnRoIGVsZW1lbnQuIFRoaXMgaXMgb2Z0ZW4gYXQgdGhlIGlubmVybW9zdCBsb29wIG9mIGFuCi0gICAqIGFwcGxpY2F0aW9uLCBzbyBwZXJmb3JtYW5jZSBpcyBjcml0aWNhbC4KLSAgICoKLSAgICogQHBhcmFtIGkgaW5kZXggb2YgdmFsdWUgdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4gdmFsdWUgYXQgZ2l2ZW4gaW5kZXguIElmIHRoYXQgdmFsdWUgd2Fzbid0IHByZXZpb3VzbHkgc2V0LAotICAgKiB0aGUgcmVzdWx0IGlzIHVuZGVmaW5lZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucy4gSXQgbWF5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbiAoc2VlIGJlbG93KSwgbWF5IHJldHVybiB6ZXJvLCBvciAoaWYgc2V0U2l6ZSBoYXMgcHJldmlvdXNseQotICAgKiBiZWVuIHVzZWQpIG1heSByZXR1cm4gc3RhbGUgZGF0YS4KLSAgICoKLSAgICogQHRocm93IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgaW5kZXggd2FzIF9jbGVhcmx5XwotICAgKiB1bnJlYXNvbmFibGUgKG5lZ2F0aXZlLCBvciBwYXN0IHRoZSBoaWdoZXN0IGJsb2NrKS4KLSAgICoKLSAgICogQHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBpbmRleCBwb2ludHMgdG8gYSBibG9jayB0aGF0IGNvdWxkCi0gICAqIGhhdmUgZXhpc3RlZCAoYmFzZWQgb24gdGhlIGhpZ2hlc3QgaW5kZXggdXNlZCkgYnV0IGhhcyBuZXZlciBoYWQgYW55dGhpbmcKLSAgICogc2V0IGludG8gaXQuCi0gICAqICVSRVZJRVclIENvdWxkIGFkZCBhIGNhdGNoIHRvIGNyZWF0ZSB0aGUgYmxvY2sgaW4gdGhhdCBjYXNlLCBvciByZXR1cm4gMC4KLSAgICogVHJ5L0NhdGNoIGlzIF9zdXBwb3NlZF8gdG8gYmUgbmVhcmx5IGZyZWUgd2hlbiBub3QgdGhyb3duIHRvLiBEbyB3ZQotICAgKiBiZWxpZXZlIHRoYXQ/IFNob3VsZCB3ZSBoYXZlIGEgc2VwYXJhdGUgc2FmZUVsZW1lbnRBdD8KLSAgICovCi0gIHB1YmxpYyBpbnQgZWxlbWVudEF0KGludCBpKQotICB7Ci0gICAgLy8gJU9QVCUgU2VlbXMgdG8gYnV5IHVzIHNvbWUgdmVyeSBzbGlnaHQgcGVyZm9ybWFuY2UgZ2FpbnMuCi0gICAgaWYoaTxtX2Jsb2Nrc2l6ZSkKLSAgICAgIHJldHVybiBtX21hcDBbaV07Ci0KLSAgICByZXR1cm4gbV9tYXBbaS9tX2Jsb2Nrc2l6ZV1baSVtX2Jsb2Nrc2l6ZV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIG9iamVjdCB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCBpcyBpbiB0aGUgbGlzdAotICAgKi8KLSAgcHJpdmF0ZSAgYm9vbGVhbiBjb250YWlucyhpbnQgcykKLSAgewotICAgIHJldHVybiAoaW5kZXhPZihzLDApID49IDApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gb2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBiZWdpbiBzZWFyY2gKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGludCBlbGVtLCBpbnQgaW5kZXgpCi0gIHsKLSAgICAgICAgaWYoaW5kZXg+PW1fZmlyc3RGcmVlKQotICAgICAgICAgICAgICAgIHJldHVybiAtMTsKLSAgICAgICAgICAKLSAgICBpbnQgYmluZGV4PWluZGV4L21fYmxvY2tzaXplOwotICAgIGludCBib2Zmc2V0PWluZGV4JW1fYmxvY2tzaXplOwotICAgIGludCBtYXhpbmRleD1tX2ZpcnN0RnJlZS9tX2Jsb2Nrc2l6ZTsKLSAgICBpbnRbXSBibG9jazsKLSAgICAKLSAgICBmb3IoO2JpbmRleDxtYXhpbmRleDsrK2JpbmRleCkKLSAgICB7Ci0gICAgICBibG9jaz1tX21hcFtiaW5kZXhdOwotICAgICAgaWYoYmxvY2shPW51bGwpCi0gICAgICAgIGZvcihpbnQgb2Zmc2V0PWJvZmZzZXQ7b2Zmc2V0PG1fYmxvY2tzaXplOysrb2Zmc2V0KQotICAgICAgICAgIGlmKGJsb2NrW29mZnNldF09PWVsZW0pCi0gICAgICAgICAgICByZXR1cm4gb2Zmc2V0K2JpbmRleCptX2Jsb2Nrc2l6ZTsKLSAgICAgIGJvZmZzZXQ9MDsgLy8gYWZ0ZXIgZmlyc3QKLSAgICB9Ci0gICAgLy8gTGFzdCBibG9jayBtYXkgbmVlZCB0byBzdG9wIGJlZm9yZSBlbmQKLSAgICBpbnQgbWF4b2Zmc2V0PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotICAgIGJsb2NrPW1fbWFwW21heGluZGV4XTsKLSAgICBmb3IoaW50IG9mZnNldD1ib2Zmc2V0O29mZnNldDxtYXhvZmZzZXQ7KytvZmZzZXQpCi0gICAgICBpZihibG9ja1tvZmZzZXRdPT1lbGVtKQotICAgICAgICByZXR1cm4gb2Zmc2V0K21heGluZGV4Km1fYmxvY2tzaXplOwotCi0gICAgcmV0dXJuIC0xOyAgICAKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIG9iamVjdCB0byBsb29rIGZvcgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgb2JqZWN0Ci0gICAqIGFyZ3VtZW50IGluIHRoaXMgdmVjdG9yIGF0IHBvc2l0aW9uIGluZGV4IG9yIGxhdGVyIGluIHRoZQotICAgKiB2ZWN0b3I7IHJldHVybnMgLTEgaWYgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCi0gICAqLwotICBwdWJsaWMgaW50IGluZGV4T2YoaW50IGVsZW0pCi0gIHsKLSAgICByZXR1cm4gaW5kZXhPZihlbGVtLDApOwotICB9Ci0KLSAgLyoqCi0gICAqIFNlYXJjaGVzIGZvciB0aGUgZmlyc3Qgb2NjdXJlbmNlIG9mIHRoZSBnaXZlbiBhcmd1bWVudCwKLSAgICogYmVnaW5uaW5nIHRoZSBzZWFyY2ggYXQgaW5kZXgsIGFuZCB0ZXN0aW5nIGZvciBlcXVhbGl0eQotICAgKiB1c2luZyB0aGUgZXF1YWxzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gT2JqZWN0IHRvIGxvb2sgZm9yCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHByaXZhdGUgIGludCBsYXN0SW5kZXhPZihpbnQgZWxlbSkKLSAgewotICAgIGludCBib2Zmc2V0PW1fZmlyc3RGcmVlJW1fYmxvY2tzaXplOwotICAgIGZvcihpbnQgaW5kZXg9bV9maXJzdEZyZWUvbV9ibG9ja3NpemU7Ci0gICAgICAgIGluZGV4Pj0wOwotICAgICAgICAtLWluZGV4KQotICAgIHsKLSAgICAgIGludFtdIGJsb2NrPW1fbWFwW2luZGV4XTsKLSAgICAgIGlmKGJsb2NrIT1udWxsKQotICAgICAgICBmb3IoaW50IG9mZnNldD1ib2Zmc2V0OyBvZmZzZXQ+PTA7IC0tb2Zmc2V0KQotICAgICAgICAgIGlmKGJsb2NrW29mZnNldF09PWVsZW0pCi0gICAgICAgICAgICByZXR1cm4gb2Zmc2V0K2luZGV4Km1fYmxvY2tzaXplOwotICAgICAgYm9mZnNldD0wOyAvLyBhZnRlciBmaXJzdAotICAgIH0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N5c3RlbUlEUmVzb2x2ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9TeXN0ZW1JRFJlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdhMGJmNjQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1N5c3RlbUlEUmVzb2x2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxOCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5VUkk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuVVJJLk1hbGZvcm1lZFVSSUV4Y2VwdGlvbjsKLQotaW1wb3J0IGphdmEuaW8uKjsKLQotaW1wb3J0IGphdmEubGFuZy5TdHJpbmdCdWZmZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBVUklzIGFuZCBTeXN0ZW1JRCAKLSAqIHN0cmluZ3MgaW50byBhYnNvbHV0ZSBVUklzLgotICovCi1wdWJsaWMgY2xhc3MgU3lzdGVtSURSZXNvbHZlcgotewotCi0gIC8qKgotICAgKiBHZXQgYWJzb2x1dGUgVVJJIGZyb20gYSBnaXZlbiByZWxhdGl2ZSBVUkkuIAotICAgKiBUaGUgVVJJIGlzIHJlc29sdmVkIHJlbGF0aXZlIHRvIHRoZSBzeXN0ZW0gcHJvcGVydHkgInVzZXIuZGlyIgotICAgKgotICAgKgotICAgKiBAcGFyYW0gdXJpIFJlbGF0aXZlIFVSSSB0byByZXNvbHZlCi0gICAqCi0gICAqIEByZXR1cm4gUmVzb2x2ZWQgYWJzb2x1dGUgVVJJIG9yIHRoZSBpbnB1dCByZWxhdGl2ZSBVUkkgaWYgCi0gICAqIGl0IGNvdWxkIG5vdCBiZSByZXNvbHZlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFic29sdXRlVVJJRnJvbVJlbGF0aXZlKFN0cmluZyB1cmkpCi0gIHsKLQotICAgIFN0cmluZyBjdXJkaXIgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuZGlyIik7Ci0KLSAgICBpZiAobnVsbCAhPSBjdXJkaXIpCi0gICAgewotICAgICAgU3RyaW5nIGJhc2U7Ci0gICAgICBpZiAoY3VyZGlyLnN0YXJ0c1dpdGgoRmlsZS5zZXBhcmF0b3IpKQotICAgICAgICBiYXNlID0gImZpbGU6Ly8iICsgY3VyZGlyOwotICAgICAgZWxzZQotICAgICAgICBiYXNlID0gImZpbGU6Ly8vIiArIGN1cmRpcjsKLSAgICAgIGlmICh1cmkgIT0gbnVsbCkKLSAgICAgICAgdXJpID0gYmFzZSArIFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKSArIHVyaTsKLSAgICAgIGVsc2UKLSAgICAgICAgdXJpID0gYmFzZSArIFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKTsKLSAgICB9Ci0KLSAgICBpZiAobnVsbCAhPSB1cmkgJiYgKHVyaS5pbmRleE9mKCdcXCcpID4gLTEpKQotICAgICAgdXJpID0gdXJpLnJlcGxhY2UoJ1xcJywgJy8nKTsKLQotICAgIHJldHVybiB1cmk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUYWtlIGEgU3lzdGVtSUQgc3RyaW5nIGFuZCB0cnkgYW5kIHR1cm4gaXQgaW50byBhIGdvb2QgYWJzb2x1dGUgVVJMLgotICAgKgotICAgKiBAcGFyYW0gdXJsU3RyaW5nIHVybCBBIFVSTCBzdHJpbmcsIHdoaWNoIG1heSBiZSByZWxhdGl2ZSBvciBhYnNvbHV0ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzb2x2ZWQgYWJzb2x1dGUgVVJJCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBzdHJpbmcgY2FuJ3QgYmUgdHVybmVkIGludG8gYSBVUkwuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRBYnNvbHV0ZVVSSShTdHJpbmcgdXJsKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKHVybC5zdGFydHNXaXRoKCIuLiIpKQotICAgICAgdXJsID0gbmV3IEZpbGUodXJsKS5nZXRBYnNvbHV0ZVBhdGgoKTsKLSAgICBpZiAodXJsLnN0YXJ0c1dpdGgoRmlsZS5zZXBhcmF0b3IpKQotICAgICAgdXJsID0gImZpbGU6Ly8iICsgdXJsOwotICAgIGVsc2UgaWYgKHVybC5pbmRleE9mKCc6JykgPCAwKQotICAgIHsKLSAgICAgIHVybCA9IGdldEFic29sdXRlVVJJRnJvbVJlbGF0aXZlKHVybCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHVybC5zdGFydHNXaXRoKCJmaWxlOiIpICYmIHVybC5jaGFyQXQoNSkgIT0gJy8nKSAKLSAgICB7Ci0gICAgICB1cmwgPSBnZXRBYnNvbHV0ZVVSSUZyb21SZWxhdGl2ZSh1cmwuc3Vic3RyaW5nKDUpKTsKLSAgICB9Ci0gICAgcmV0dXJuIHVybDsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRha2UgYSBTeXN0ZW1JRCBzdHJpbmcgYW5kIHRyeSBhbmQgdHVybiBpdCBpbnRvIGEgZ29vZCBhYnNvbHV0ZSBVUkwuCi0gICAqCi0gICAqIEBwYXJhbSB1cmxTdHJpbmcgU3lzdGVtSUQgc3RyaW5nCi0gICAqIEBwYXJhbSBiYXNlIEJhc2UgVVJJIHRvIHVzZSB0byByZXNvbHZlIHRoZSBnaXZlbiBzeXN0ZW1JRAotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXNvbHZlZCBhYnNvbHV0ZSBVUkkKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIHN0cmluZyBjYW4ndCBiZSB0dXJuZWQgaW50byBhIFVSTC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFic29sdXRlVVJJKFN0cmluZyB1cmxTdHJpbmcsIFN0cmluZyBiYXNlKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgYm9vbGVhbiBpc0Fic291dGVVcmwgPSBmYWxzZTsKLSAgICBib29sZWFuIG5lZWRUb1Jlc29sdmUgPSBmYWxzZTsgICAgCi0gCi0gICAgaWYodXJsU3RyaW5nLnN0YXJ0c1dpdGgoImZpbGU6IikgJiYgdXJsU3RyaW5nLmNoYXJBdCg1KSAhPSAnLycpIAotICAgIHsKLSAgICAgIG5lZWRUb1Jlc29sdmUgPSB0cnVlOwotICAgIH0KLSAgICBlbHNlIGlmICh1cmxTdHJpbmcuaW5kZXhPZignOicpID4gMCkKLSAgICAgIGlzQWJzb3V0ZVVybCA9IHRydWU7Ci0gICAgZWxzZSBpZiAodXJsU3RyaW5nLnN0YXJ0c1dpdGgoRmlsZS5zZXBhcmF0b3IpKQotICAgIHsKLSAgICAgIHVybFN0cmluZyA9ICJmaWxlOi8vIiArIHVybFN0cmluZzsKLSAgICAgIGlzQWJzb3V0ZVVybCA9IHRydWU7Ci0gICAgfQotCi0gICAgaWYgKCghaXNBYnNvdXRlVXJsKSAmJiAoKG51bGwgPT0gYmFzZSkKLSAgICAgICAgICAgIHx8IChiYXNlLmluZGV4T2YoJzonKSA8IDApKSkKLSAgICB7Ci0gICAgICBpZiAoYmFzZSAhPSBudWxsICYmIGJhc2Uuc3RhcnRzV2l0aChGaWxlLnNlcGFyYXRvcikpCi0gICAgICAgIGJhc2UgPSAiZmlsZTovLyIgKyBiYXNlOwotICAgICAgZWxzZQotICAgICAgICBiYXNlID0gZ2V0QWJzb2x1dGVVUklGcm9tUmVsYXRpdmUoYmFzZSk7Ci0gICAgfQotCi0gICAgLy8gYml0IG9mIGEgaGFjayBoZXJlLiAgTmVlZCB0byB0YWxrIHRvIFVSSSBwZXJzb24gdG8gc2VlIGlmIHRoaXMgY2FuIGJlIGZpeGVkLgotICAgIGlmICgobnVsbCAhPSBiYXNlKSAmJiBuZWVkVG9SZXNvbHZlKSAKLSAgICAgICAgIAotICAgIHsKLSAgICAgIGlmKGJhc2UuZXF1YWxzKHVybFN0cmluZykpCi0gICAgICB7Ci0gICAgICAgIGJhc2UgPSAiIjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgdXJsU3RyaW5nID0gdXJsU3RyaW5nLnN1YnN0cmluZyg1KTsKLSAgICAgICAgaXNBYnNvdXRlVXJsID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgfSAgIAotCi0gICAgLy8gVGhpcyBpcyBwcm9iYWJseSBhIGJhZCBpZGVhLCB3ZSBzaG91bGQgYXQgbGVhc3QgY2hlY2sgZm9yIHF1b3Rlcy4uLgotICAgIGlmIChudWxsICE9IGJhc2UgJiYgKGJhc2UuaW5kZXhPZignXFwnKSA+IC0xKSkKLSAgICAgIGJhc2UgPSBiYXNlLnJlcGxhY2UoJ1xcJywgJy8nKTsKLQotICAgIGlmIChudWxsICE9IHVybFN0cmluZyAmJiAodXJsU3RyaW5nLmluZGV4T2YoJ1xcJykgPiAtMSkpCi0gICAgICB1cmxTdHJpbmcgPSB1cmxTdHJpbmcucmVwbGFjZSgnXFwnLCAnLycpOwotCi0gICAgVVJJIHVyaTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmICgobnVsbCA9PSBiYXNlKSB8fCAoYmFzZS5sZW5ndGgoKSA9PSAwKSB8fCAoaXNBYnNvdXRlVXJsKSkKLSAgICAgIHsKLSAgICAgICAgdXJpID0gbmV3IFVSSSh1cmxTdHJpbmcpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBVUkkgYmFzZVVSSSA9IG5ldyBVUkkoYmFzZSk7Ci0KLSAgICAgICAgdXJpID0gbmV3IFVSSShiYXNlVVJJLCB1cmxTdHJpbmcpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoTWFsZm9ybWVkVVJJRXhjZXB0aW9uIG11ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obXVlKTsKLSAgICB9Ci0KLSAgICBTdHJpbmcgdXJpU3RyID0gdXJpLnRvU3RyaW5nKCk7Ci0gICAgcmV0dXJuIHVyaVN0cjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1RyZWVXYWxrZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9UcmVlV2Fsa2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ4NTQ4OTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1RyZWVXYWxrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLWltcG9ydCBvcmcueG1sLnNheC4qOwotaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5ET00ySGVscGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRE9NSGVscGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5vZGVDb25zdW1lcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgZG9lcyBhIHByZS1vcmRlciB3YWxrIG9mIHRoZSBET00gdHJlZSwgY2FsbGluZyBhIENvbnRlbnRIYW5kbGVyCi0gKiBpbnRlcmZhY2UgYXMgaXQgZ29lcy4KLSAqLwotcHVibGljIGNsYXNzIFRyZWVXYWxrZXIKLXsKLQotICAvKiogTG9jYWwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBDb250ZW50SGFuZGxlciBtX2NvbnRlbnRIYW5kbGVyID0gbnVsbDsKLQotICAvLyBBUkdISCEhICBKQVhQIFVzZXMgWGVyY2VzIHdpdGhvdXQgc2V0dGluZyB0aGUgbmFtZXNwYWNlIHByb2Nlc3NpbmcgdG8gT04hCi0gIC8vIERPTTJIZWxwZXIgbV9kaCA9IG5ldyBET00ySGVscGVyKCk7Ci0KLSAgLyoqIERvbUhlbHBlciBmb3IgdGhpcyBUcmVlV2Fsa2VyICAgICAgICAgICovCi0gIHByb3RlY3RlZCBET01IZWxwZXIgbV9kaDsKLSAgICAgICAgCi0gICAgICAgIC8qKiBMb2NhdG9yIG9iamVjdCBmb3IgdGhpcyBUcmVlV2Fsa2VyICAgICAgICAgICovCi0gICAgICAgIHByaXZhdGUgTG9jYXRvckltcGwgbV9sb2NhdG9yID0gbmV3IExvY2F0b3JJbXBsKCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHJldHVybiB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2FsawotICAgKi8KLSAgcHVibGljIENvbnRlbnRIYW5kbGVyIGdldENvbnRlbnRIYW5kbGVyKCkKLSAgewotICAgIHJldHVybiBtX2NvbnRlbnRIYW5kbGVyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2Fsay4KLSAgICoKLSAgICogQHJldHVybiB0aGUgQ29udGVudEhhbmRsZXIgdXNlZCBmb3IgdGhlIHRyZWUgd2FsawotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIgY2gpCi0gIHsKLSAgICBtX2NvbnRlbnRIYW5kbGVyID0gY2g7Ci0gIH0KLSAgICAgICAgCi0gICAgICAgIC8qKgotICAgKiBDb25zdHJ1Y3Rvci4KLSAgICogQHBhcmFtICAgY29udGVudEhhbmRsZXIgVGhlIGltcGxlbWVudGlvbiBvZiB0aGUKLSAgICogQHBhcmFtICAgc3lzdGVtSWQgU3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBkb2N1bWVudC4KLSAgICogY29udGVudEhhbmRsZXIgb3BlcmF0aW9uICh0b1hNTFN0cmluZywgZGlnZXN0LCAuLi4pCi0gICAqLwotICBwdWJsaWMgVHJlZVdhbGtlcihDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlciwgRE9NSGVscGVyIGRoLCBTdHJpbmcgc3lzdGVtSWQpCi0gIHsKLSAgICB0aGlzLm1fY29udGVudEhhbmRsZXIgPSBjb250ZW50SGFuZGxlcjsKLSAgICAgICAgICAgICAgICBtX2NvbnRlbnRIYW5kbGVyLnNldERvY3VtZW50TG9jYXRvcihtX2xvY2F0b3IpOwotICAgICAgICAgICAgICAgIGlmIChzeXN0ZW1JZCAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldFN5c3RlbUlkKHN5c3RlbUlkKTsKLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0U3lzdGVtSWQoU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpKTsKLSAgICBtX2RoID0gZGg7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0b3IuCi0gICAqIEBwYXJhbSAgIGNvbnRlbnRIYW5kbGVyIFRoZSBpbXBsZW1lbnRpb24gb2YgdGhlCi0gICAqIGNvbnRlbnRIYW5kbGVyIG9wZXJhdGlvbiAodG9YTUxTdHJpbmcsIGRpZ2VzdCwgLi4uKQotICAgKi8KLSAgcHVibGljIFRyZWVXYWxrZXIoQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIsIERPTUhlbHBlciBkaCkKLSAgewotICAgIHRoaXMubV9jb250ZW50SGFuZGxlciA9IGNvbnRlbnRIYW5kbGVyOwotICAgICAgICAgICAgICAgIG1fY29udGVudEhhbmRsZXIuc2V0RG9jdW1lbnRMb2NhdG9yKG1fbG9jYXRvcik7Ci0gICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldFN5c3RlbUlkKFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5kaXIiKSk7Ci0gICAgbV9kaCA9IGRoOwotICB9Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0b3IuCi0gICAqIEBwYXJhbSAgIGNvbnRlbnRIYW5kbGVyIFRoZSBpbXBsZW1lbnRpb24gb2YgdGhlCi0gICAqIGNvbnRlbnRIYW5kbGVyIG9wZXJhdGlvbiAodG9YTUxTdHJpbmcsIGRpZ2VzdCwgLi4uKQotICAgKi8KLSAgcHVibGljIFRyZWVXYWxrZXIoQ29udGVudEhhbmRsZXIgY29udGVudEhhbmRsZXIpCi0gIHsKLSAgICB0aGlzLm1fY29udGVudEhhbmRsZXIgPSBjb250ZW50SGFuZGxlcjsKLSAgICAgICAgICAgICAgICBpZiAobV9jb250ZW50SGFuZGxlciAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICAgICAgbV9jb250ZW50SGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IobV9sb2NhdG9yKTsKLSAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0U3lzdGVtSWQoU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpKTsKLSAgICBtX2RoID0gbmV3IG9yZy5hcGFjaGUueHBhdGguRE9NMkhlbHBlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFBlcmZvcm0gYSBwcmUtb3JkZXIgdHJhdmVyc2FsIG5vbi1yZWN1cnNpdmUgc3R5bGUuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgTm9kZSBpbiB0aGUgdHJlZSB3aGVyZSB0byBzdGFydCB0cmF2ZXJzYWwKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhdmVyc2UoTm9kZSBwb3MpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgTm9kZSB0b3AgPSBwb3M7Ci0KLSAgICB3aGlsZSAobnVsbCAhPSBwb3MpCi0gICAgewotICAgICAgc3RhcnROb2RlKHBvcyk7Ci0KLSAgICAgIE5vZGUgbmV4dE5vZGUgPSBwb3MuZ2V0Rmlyc3RDaGlsZCgpOwotCi0gICAgICB3aGlsZSAobnVsbCA9PSBuZXh0Tm9kZSkKLSAgICAgIHsKLSAgICAgICAgZW5kTm9kZShwb3MpOwotCi0gICAgICAgIGlmICh0b3AuZXF1YWxzKHBvcykpCi0gICAgICAgICAgYnJlYWs7Ci0KLSAgICAgICAgbmV4dE5vZGUgPSBwb3MuZ2V0TmV4dFNpYmxpbmcoKTsKLQotICAgICAgICBpZiAobnVsbCA9PSBuZXh0Tm9kZSkKLSAgICAgICAgewotICAgICAgICAgIHBvcyA9IHBvcy5nZXRQYXJlbnROb2RlKCk7Ci0KLSAgICAgICAgICBpZiAoKG51bGwgPT0gcG9zKSB8fCAodG9wLmVxdWFscyhwb3MpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCAhPSBwb3MpCi0gICAgICAgICAgICAgIGVuZE5vZGUocG9zKTsKLQotICAgICAgICAgICAgbmV4dE5vZGUgPSBudWxsOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcG9zID0gbmV4dE5vZGU7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFBlcmZvcm0gYSBwcmUtb3JkZXIgdHJhdmVyc2FsIG5vbi1yZWN1cnNpdmUgc3R5bGUuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgTm9kZSBpbiB0aGUgdHJlZSB3aGVyZSB0byBzdGFydCB0cmF2ZXJzYWwKLSAgICogQHBhcmFtIHRvcCBOb2RlIGluIHRoZSB0cmVlIHdoZXJlIHRvIGVuZCB0cmF2ZXJzYWwKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgdHJhdmVyc2UoTm9kZSBwb3MsIE5vZGUgdG9wKSB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIHdoaWxlIChudWxsICE9IHBvcykKLSAgICB7Ci0gICAgICBzdGFydE5vZGUocG9zKTsKLQotICAgICAgTm9kZSBuZXh0Tm9kZSA9IHBvcy5nZXRGaXJzdENoaWxkKCk7Ci0KLSAgICAgIHdoaWxlIChudWxsID09IG5leHROb2RlKQotICAgICAgewotICAgICAgICBlbmROb2RlKHBvcyk7Ci0KLSAgICAgICAgaWYgKChudWxsICE9IHRvcCkgJiYgdG9wLmVxdWFscyhwb3MpKQotICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgIG5leHROb2RlID0gcG9zLmdldE5leHRTaWJsaW5nKCk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gbmV4dE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBwb3MgPSBwb3MuZ2V0UGFyZW50Tm9kZSgpOwotCi0gICAgICAgICAgaWYgKChudWxsID09IHBvcykgfHwgKChudWxsICE9IHRvcCkgJiYgdG9wLmVxdWFscyhwb3MpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBuZXh0Tm9kZSA9IG51bGw7Ci0KLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBwb3MgPSBuZXh0Tm9kZTsKLSAgICB9Ci0gIH0KLQotICAvKiogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgZm9sbG93aW5nIHRleHQgdG8gYmUgcHJvY2Vzc2VkIGlzIHJhdyB0ZXh0ICAgICAgICAgICovCi0gIGJvb2xlYW4gbmV4dElzUmF3ID0gZmFsc2U7Ci0gIAotICAvKioKLSAgICogT3B0aW1pemVkIGRpc3BhdGNoIG9mIGNoYXJhY3RlcnMuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgZGlzcGF0YWNoQ2hhcnMoTm9kZSBub2RlKQotICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5kb20yZHRtLkRPTTJEVE0uQ2hhcmFjdGVyTm9kZUhhbmRsZXIpCi0gICAgewotICAgICAgKChvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLmRvbTJkdG0uRE9NMkRUTS5DaGFyYWN0ZXJOb2RlSGFuZGxlciltX2NvbnRlbnRIYW5kbGVyKS5jaGFyYWN0ZXJzKG5vZGUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgU3RyaW5nIGRhdGEgPSAoKFRleHQpIG5vZGUpLmdldERhdGEoKTsKLSAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5jaGFyYWN0ZXJzKGRhdGEudG9DaGFyQXJyYXkoKSwgMCwgZGF0YS5sZW5ndGgoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXJ0IHByb2Nlc3NpbmcgZ2l2ZW4gbm9kZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHByb2Nlc3MKLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHN0YXJ0Tm9kZShOb2RlIG5vZGUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBOb2RlQ29uc3VtZXIpCi0gICAgewotICAgICAgKChOb2RlQ29uc3VtZXIpIG1fY29udGVudEhhbmRsZXIpLnNldE9yaWdpbmF0aW5nTm9kZShub2RlKTsKLSAgICB9Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBMb2NhdG9yKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIExvY2F0b3IgbG9jID0gKExvY2F0b3Ipbm9kZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbG9jYXRvci5zZXRDb2x1bW5OdW1iZXIobG9jLmdldENvbHVtbk51bWJlcigpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbG9jYXRvci5zZXRMaW5lTnVtYmVyKGxvYy5nZXRMaW5lTnVtYmVyKCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgbV9sb2NhdG9yLnNldFB1YmxpY0lkKGxvYy5nZXRQdWJsaWNJZCgpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIG1fbG9jYXRvci5zZXRTeXN0ZW1JZChsb2MuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBtX2xvY2F0b3Iuc2V0Q29sdW1uTnVtYmVyKDApOwotICAgICAgbV9sb2NhdG9yLnNldExpbmVOdW1iZXIoMCk7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5DT01NRU5UX05PREUgOgotICAgIHsKLSAgICAgIFN0cmluZyBkYXRhID0gKChDb21tZW50KSBub2RlKS5nZXREYXRhKCk7Ci0KLSAgICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgIExleGljYWxIYW5kbGVyIGxoID0gKChMZXhpY2FsSGFuZGxlcikgdGhpcy5tX2NvbnRlbnRIYW5kbGVyKTsKLQotICAgICAgICBsaC5jb21tZW50KGRhdGEudG9DaGFyQXJyYXkoKSwgMCwgZGF0YS5sZW5ndGgoKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFIDoKLQotICAgICAgLy8gPz87Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuRE9DVU1FTlRfTk9ERSA6Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCgpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgICBOYW1lZE5vZGVNYXAgYXR0cyA9ICgoRWxlbWVudCkgbm9kZSkuZ2V0QXR0cmlidXRlcygpOwotICAgICAgaW50IG5BdHRycyA9IGF0dHMuZ2V0TGVuZ3RoKCk7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlRyZWVXYWxrZXIjc3RhcnROb2RlOiAiK25vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkF0dHJzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIE5vZGUgYXR0ciA9IGF0dHMuaXRlbShpKTsKLSAgICAgICAgU3RyaW5nIGF0dHJOYW1lID0gYXR0ci5nZXROb2RlTmFtZSgpOwotCi0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiVHJlZVdhbGtlciNzdGFydE5vZGU6IGF0dHJbIitpKyJdID0gIithdHRyTmFtZSsiLCAiK2F0dHIuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICBpZiAoYXR0ck5hbWUuZXF1YWxzKCJ4bWxucyIpIHx8IGF0dHJOYW1lLnN0YXJ0c1dpdGgoInhtbG5zOiIpKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJUcmVlV2Fsa2VyI3N0YXJ0Tm9kZTogYXR0clsiK2krIl0gPSAiK2F0dHJOYW1lKyIsICIrYXR0ci5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICAgICAgaW50IGluZGV4OwotICAgICAgICAgIC8vIFVzZSAiIiBpbnN0ZWFkIG9mIG51bGwsIGFzIFhlcmNlcyBsaWtlcyAiIiBmb3IgdGhlIAotICAgICAgICAgIC8vIG5hbWUgb2YgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLiAgRml4IGF0dHJpYnV0ZWQgCi0gICAgICAgICAgLy8gdG8gIlN0ZXZlbiBNdXJyYXkiIDxzbXVycmF5QGVidC5jb20+LgotICAgICAgICAgIFN0cmluZyBwcmVmaXggPSAoaW5kZXggPSBhdHRyTmFtZS5pbmRleE9mKCI6IikpIDwgMAotICAgICAgICAgICAgICAgICAgICAgICAgICA/ICIiIDogYXR0ck5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0KLSAgICAgICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKHByZWZpeCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgICB9Ci0gICAgICAgIAotICAgICAgfQotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKG5vZGUpOiAiK21fZGguZ2V0TmFtZXNwYWNlT2ZOb2RlKG5vZGUpKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSk6ICIrbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSkpOwotICAgICAgU3RyaW5nIG5zID0gbV9kaC5nZXROYW1lc3BhY2VPZk5vZGUobm9kZSk7Ci0gICAgICBpZihudWxsID09IG5zKQotICAgICAgICBucyA9ICIiOwotICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLnN0YXJ0RWxlbWVudChucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZU5hbWUoKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEF0dExpc3QoYXR0cywgbV9kaCkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSA6Ci0gICAgewotICAgICAgUHJvY2Vzc2luZ0luc3RydWN0aW9uIHBpID0gKFByb2Nlc3NpbmdJbnN0cnVjdGlvbikgbm9kZTsKLSAgICAgIFN0cmluZyBuYW1lID0gcGkuZ2V0Tm9kZU5hbWUoKTsKLQotICAgICAgLy8gU3RyaW5nIGRhdGEgPSBwaS5nZXREYXRhKCk7Ci0gICAgICBpZiAobmFtZS5lcXVhbHMoInhzbHQtbmV4dC1pcy1yYXciKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dElzUmF3ID0gdHJ1ZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbihwaS5nZXROb2RlTmFtZSgpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpLmdldERhdGEoKSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREUgOgotICAgIHsKLSAgICAgIGJvb2xlYW4gaXNMZXhIID0gKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcik7Ci0gICAgICBMZXhpY2FsSGFuZGxlciBsaCA9IGlzTGV4SAotICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoTGV4aWNhbEhhbmRsZXIpIHRoaXMubV9jb250ZW50SGFuZGxlcikgOiBudWxsOwotCi0gICAgICBpZiAoaXNMZXhIKQotICAgICAgewotICAgICAgICBsaC5zdGFydENEQVRBKCk7Ci0gICAgICB9Ci0gICAgICAKLSAgICAgIGRpc3BhdGFjaENoYXJzKG5vZGUpOwotCi0gICAgICB7Ci0gICAgICAgIGlmIChpc0xleEgpCi0gICAgICAgIHsKLSAgICAgICAgICBsaC5lbmRDREFUQSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5URVhUX05PREUgOgotICAgIHsKLSAgICAgIC8vU3RyaW5nIGRhdGEgPSAoKFRleHQpIG5vZGUpLmdldERhdGEoKTsKLQotICAgICAgaWYgKG5leHRJc1JhdykKLSAgICAgIHsKLSAgICAgICAgbmV4dElzUmF3ID0gZmFsc2U7Ci0KLSAgICAgICAgbV9jb250ZW50SGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQuUElfRElTQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgICAgZGlzcGF0YWNoQ2hhcnMobm9kZSk7Ci0gICAgICAgIG1fY29udGVudEhhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0LlBJX0VOQUJMRV9PVVRQVVRfRVNDQVBJTkcsICIiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZGlzcGF0YWNoQ2hhcnMobm9kZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGNhc2UgTm9kZS5FTlRJVFlfUkVGRVJFTkNFX05PREUgOgotICAgIHsKLSAgICAgIEVudGl0eVJlZmVyZW5jZSBlcmVmID0gKEVudGl0eVJlZmVyZW5jZSkgbm9kZTsKLQotICAgICAgaWYgKG1fY29udGVudEhhbmRsZXIgaW5zdGFuY2VvZiBMZXhpY2FsSGFuZGxlcikKLSAgICAgIHsKLSAgICAgICAgKChMZXhpY2FsSGFuZGxlcikgdGhpcy5tX2NvbnRlbnRIYW5kbGVyKS5zdGFydEVudGl0eSgKLSAgICAgICAgICBlcmVmLmdldE5vZGVOYW1lKCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIHdhcm5pbmcoIkNhbiBub3Qgb3V0cHV0IGVudGl0eSB0byBhIHB1cmUgU0FYIENvbnRlbnRIYW5kbGVyIik7Ci0gICAgICB9Ci0gICAgfQotICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBFbmQgcHJvY2Vzc2luZyBvZiBnaXZlbiBub2RlIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHdlIGp1c3QgZmluaXNoZWQgcHJvY2Vzc2luZwotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZW5kTm9kZShOb2RlIG5vZGUpIHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgewotCi0gICAgc3dpdGNoIChub2RlLmdldE5vZGVUeXBlKCkpCi0gICAgewotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLSAgICAgIHRoaXMubV9jb250ZW50SGFuZGxlci5lbmREb2N1bWVudCgpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERSA6Ci0gICAgICBTdHJpbmcgbnMgPSBtX2RoLmdldE5hbWVzcGFjZU9mTm9kZShub2RlKTsKLSAgICAgIGlmKG51bGwgPT0gbnMpCi0gICAgICAgIG5zID0gIiI7Ci0gICAgICB0aGlzLm1fY29udGVudEhhbmRsZXIuZW5kRWxlbWVudChucywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9kaC5nZXRMb2NhbE5hbWVPZk5vZGUobm9kZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZ2V0Tm9kZU5hbWUoKSk7Ci0KLSAgICAgIE5hbWVkTm9kZU1hcCBhdHRzID0gKChFbGVtZW50KSBub2RlKS5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICBpbnQgbkF0dHJzID0gYXR0cy5nZXRMZW5ndGgoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQXR0cnM7IGkrKykKLSAgICAgIHsKLSAgICAgICAgTm9kZSBhdHRyID0gYXR0cy5pdGVtKGkpOwotICAgICAgICBTdHJpbmcgYXR0ck5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgaWYgKGF0dHJOYW1lLmVxdWFscygieG1sbnMiKSB8fCBhdHRyTmFtZS5zdGFydHNXaXRoKCJ4bWxuczoiKSkKLSAgICAgICAgewotICAgICAgICAgIGludCBpbmRleDsKLSAgICAgICAgICAvLyBVc2UgIiIgaW5zdGVhZCBvZiBudWxsLCBhcyBYZXJjZXMgbGlrZXMgIiIgZm9yIHRoZSAKLSAgICAgICAgICAvLyBuYW1lIG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZS4gIEZpeCBhdHRyaWJ1dGVkIAotICAgICAgICAgIC8vIHRvICJTdGV2ZW4gTXVycmF5IiA8c211cnJheUBlYnQuY29tPi4KLSAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gKGluZGV4ID0gYXR0ck5hbWUuaW5kZXhPZigiOiIpKSA8IDAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiIiA6IGF0dHJOYW1lLnN1YnN0cmluZyhpbmRleCArIDEpOwotCi0gICAgICAgICAgdGhpcy5tX2NvbnRlbnRIYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFIDoKLSAgICB7Ci0gICAgICBFbnRpdHlSZWZlcmVuY2UgZXJlZiA9IChFbnRpdHlSZWZlcmVuY2UpIG5vZGU7Ci0KLSAgICAgIGlmIChtX2NvbnRlbnRIYW5kbGVyIGluc3RhbmNlb2YgTGV4aWNhbEhhbmRsZXIpCi0gICAgICB7Ci0gICAgICAgIExleGljYWxIYW5kbGVyIGxoID0gKChMZXhpY2FsSGFuZGxlcikgdGhpcy5tX2NvbnRlbnRIYW5kbGVyKTsKLQotICAgICAgICBsaC5lbmRFbnRpdHkoZXJlZi5nZXROb2RlTmFtZSgpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgfQotICB9Ci19ICAvL1RyZWVXYWxrZXIKLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1RyaWUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9UcmllLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNkZTNlNDAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1RyaWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE4MSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgZGlnaXRhbCBzZWFyY2ggdHJpZSBmb3IgNy1iaXQgQVNDSUkgdGV4dAotICogVGhlIEFQSSBpcyBhIHN1YnNldCBvZiBqYXZhLnV0aWwuSGFzaHRhYmxlCi0gKiBUaGUga2V5IG11c3QgYmUgYSA3LWJpdCBBU0NJSSBzdHJpbmcKLSAqIFRoZSB2YWx1ZSBtYXkgYmUgYW55IEphdmEgT2JqZWN0Ci0gKi8KLXB1YmxpYyBjbGFzcyBUcmllCi17Ci0KLSAgLyoqIFNpemUgb2YgdGhlIG1fbmV4dENoYXIgYXJyYXkuICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTFBIQV9TSVpFID0gMTI4OwotCi0gIC8qKiBUaGUgcm9vdCBub2RlIG9mIHRoZSB0cmVlLiAgICAqLwotICBOb2RlIG1fUm9vdDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IHRoZSB0cmllLgotICAgKi8KLSAgcHVibGljIFRyaWUoKQotICB7Ci0gICAgbV9Sb290ID0gbmV3IE5vZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXQgYW4gb2JqZWN0IGludG8gdGhlIHRyaWUgZm9yIGxvb2t1cC4KLSAgICoKLSAgICogQHBhcmFtIGtleSBtdXN0IGJlIGEgNy1iaXQgQVNDSUkgc3RyaW5nCi0gICAqIEBwYXJhbSB2YWx1ZSBhbnkgamF2YSBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9sZCBvYmplY3QgdGhhdCBtYXRjaGVkIGtleSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgcHV0KFN0cmluZyBrZXksIE9iamVjdCB2YWx1ZSkKLSAgewotCi0gICAgZmluYWwgaW50IGxlbiA9IGtleS5sZW5ndGgoKTsKLSAgICBOb2RlIG5vZGUgPSBtX1Jvb3Q7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbmV4dE5vZGUgPSBub2RlLm1fbmV4dENoYXJbQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGtleS5jaGFyQXQoaSkpXTsKLQotICAgICAgaWYgKG5leHROb2RlICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIG5vZGUgPSBuZXh0Tm9kZTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZm9yICg7IGkgPCBsZW47IGkrKykKLSAgICAgICAgewotICAgICAgICAgIE5vZGUgbmV3Tm9kZSA9IG5ldyBOb2RlKCk7Ci0KLSAgICAgICAgICBub2RlLm1fbmV4dENoYXJbQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGtleS5jaGFyQXQoaSkpXSA9IG5ld05vZGU7Ci0gICAgICAgICAgbm9kZSA9IG5ld05vZGU7Ci0gICAgICAgIH0KLQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBPYmplY3QgcmV0ID0gbm9kZS5tX1ZhbHVlOwotCi0gICAgbm9kZS5tX1ZhbHVlID0gdmFsdWU7Ci0KLSAgICByZXR1cm4gcmV0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhbiBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBrZXkuCi0gICAqCi0gICAqIEBwYXJhbSBrZXkgbXVzdCBiZSBhIDctYml0IEFTQ0lJIHN0cmluZwotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QgdGhhdCBtYXRjaGVzIHRoZSBrZXksIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldChTdHJpbmcga2V5KQotICB7Ci0KLSAgICBmaW5hbCBpbnQgbGVuID0ga2V5Lmxlbmd0aCgpOwotICAgIE5vZGUgbm9kZSA9IG1fUm9vdDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIG5vZGUgPSBub2RlLm1fbmV4dENoYXJbQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGtleS5jaGFyQXQoaSkpXTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkKLSAgICAgIHsKLQotICAgICAgICAvLyB0aGUga2V5IGlzIG5vdCA3LWJpdCBBU0NJSSBzbyB3ZSB3b24ndCBmaW5kIGl0IGhlcmUKLSAgICAgICAgbm9kZSA9IG51bGw7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChub2RlID09IG51bGwpCi0gICAgICAgIHJldHVybiBudWxsOwotICAgIH0KLQotICAgIHJldHVybiBub2RlLm1fVmFsdWU7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFRoZSBub2RlIHJlcHJlc2VudGF0aW9uIGZvciB0aGUgdHJpZS4KLSAgICovCi0gIGNsYXNzIE5vZGUKLSAgewotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0b3IsIGNyZWF0ZXMgYSBOb2RlW0FMUEhBX1NJWkVdLgotICAgICAqLwotICAgIE5vZGUoKQotICAgIHsKLSAgICAgIG1fbmV4dENoYXIgPSBuZXcgTm9kZVtBTFBIQV9TSVpFXTsKLSAgICAgIG1fVmFsdWUgPSBudWxsOwotICAgIH0KLQotICAgIC8qKiBUaGUgbmV4dCBub2Rlcy4gICAqLwotICAgIE5vZGUgbV9uZXh0Q2hhcltdOwotCi0gICAgLyoqIFRoZSB2YWx1ZS4gICAqLwotICAgIE9iamVjdCBtX1ZhbHVlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvVVJJLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvVVJJLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMwYjE0MmYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1VSSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY5MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlsczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLS8qKgotICogQSBjbGFzcyB0byByZXByZXNlbnQgYSBVbmlmb3JtIFJlc291cmNlIElkZW50aWZpZXIgKFVSSSkuIFRoaXMgY2xhc3MKLSAqIGlzIGRlc2lnbmVkIHRvIGhhbmRsZSB0aGUgcGFyc2luZyBvZiBVUklzIGFuZCBwcm92aWRlIGFjY2VzcyB0bwotICogdGhlIHZhcmlvdXMgY29tcG9uZW50cyAoc2NoZW1lLCBob3N0LCBwb3J0LCB1c2VyaW5mbywgcGF0aCwgcXVlcnkKLSAqIHN0cmluZyBhbmQgZnJhZ21lbnQpIHRoYXQgbWF5IGNvbnN0aXR1dGUgYSBVUkkuCi0gKiA8cD4KLSAqIFBhcnNpbmcgb2YgYSBVUkkgc3BlY2lmaWNhdGlvbiBpcyBkb25lIGFjY29yZGluZyB0byB0aGUgVVJJCi0gKiBzeW50YXggZGVzY3JpYmVkIGluIFJGQyAyMzk2Ci0gKiA8aHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQ/bnVtYmVyPTIzOTY+LiBFdmVyeSBVUkkgY29uc2lzdHMKLSAqIG9mIGEgc2NoZW1lLCBmb2xsb3dlZCBieSBhIGNvbG9uICgnOicpLCBmb2xsb3dlZCBieSBhIHNjaGVtZS1zcGVjaWZpYwotICogcGFydC4gRm9yIFVSSXMgdGhhdCBmb2xsb3cgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4LCB0aGUgc2NoZW1lLQotICogc3BlY2lmaWMgcGFydCBiZWdpbnMgd2l0aCB0d28gc2xhc2hlcyAoIi8vIikgYW5kIG1heSBiZSBmb2xsb3dlZAotICogYnkgYW4gYXV0aG9yaXR5IHNlZ21lbnQgKGNvbXByaXNlZCBvZiB1c2VyIGluZm9ybWF0aW9uLCBob3N0LCBhbmQKLSAqIHBvcnQpLCBwYXRoIHNlZ21lbnQsIHF1ZXJ5IHNlZ21lbnQgYW5kIGZyYWdtZW50LiBOb3RlIHRoYXQgUkZDIDIzOTYKLSAqIG5vIGxvbmdlciBzcGVjaWZpZXMgdGhlIHVzZSBvZiB0aGUgcGFyYW1ldGVycyBzZWdtZW50IGFuZCBleGNsdWRlcwotICogdGhlICJ1c2VyOnBhc3N3b3JkIiBzeW50YXggYXMgcGFydCBvZiB0aGUgYXV0aG9yaXR5IHNlZ21lbnQuIElmCi0gKiAidXNlcjpwYXNzd29yZCIgYXBwZWFycyBpbiBhIFVSSSwgdGhlIGVudGlyZSB1c2VyL3Bhc3N3b3JkIHN0cmluZwotICogaXMgc3RvcmVkIGFzIHVzZXJpbmZvLgotICogPHA+Ci0gKiBGb3IgVVJJcyB0aGF0IGRvIG5vdCBmb2xsb3cgdGhlICJnZW5lcmljIFVSSSIgc3ludGF4IChlLmcuIG1haWx0byksCi0gKiB0aGUgZW50aXJlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IGlzIHRyZWF0ZWQgYXMgdGhlICJwYXRoIiBwb3J0aW9uCi0gKiBvZiB0aGUgVVJJLgotICogPHA+Ci0gKiBOb3RlIHRoYXQsIHVubGlrZSB0aGUgamF2YS5uZXQuVVJMIGNsYXNzLCB0aGlzIGNsYXNzIGRvZXMgbm90IHByb3ZpZGUKLSAqIGFueSBidWlsdC1pbiBuZXR3b3JrIGFjY2VzcyBmdW5jdGlvbmFsaXR5IG5vciBkb2VzIGl0IHByb3ZpZGUgYW55Ci0gKiBzY2hlbWUtc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSAoZm9yIGV4YW1wbGUsIGl0IGRvZXMgbm90IGtub3cgYQotICogZGVmYXVsdCBwb3J0IGZvciBhIHNwZWNpZmljIHNjaGVtZSkuIFJhdGhlciwgaXQgb25seSBrbm93cyB0aGUKLSAqIGdyYW1tYXIgYW5kIGJhc2ljIHNldCBvZiBvcGVyYXRpb25zIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gYSBVUkkuCi0gKgotICogQHZlcnNpb24gICRJZCQKLSAqCi0gKi8KLXB1YmxpYyBjbGFzcyBVUkkgaW1wbGVtZW50cyBTZXJpYWxpemFibGUKLXsKLQotICAvKioKLSAgICogTWFsZm9ybWVkVVJJRXhjZXB0aW9ucyBhcmUgdGhyb3duIGluIHRoZSBwcm9jZXNzIG9mIGJ1aWxkaW5nIGEgVVJJCi0gICAqIG9yIHNldHRpbmcgZmllbGRzIG9uIGEgVVJJIHdoZW4gYW4gb3BlcmF0aW9uIHdvdWxkIHJlc3VsdCBpbiBhbgotICAgKiBpbnZhbGlkIFVSSSBzcGVjaWZpY2F0aW9uLgotICAgKgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBjbGFzcyBNYWxmb3JtZWRVUklFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBDb25zdHJ1Y3RzIGEgPGNvZGU+TWFsZm9ybWVkVVJJRXhjZXB0aW9uPC9jb2RlPiB3aXRoIG5vIHNwZWNpZmllZAotICAgICAqIGRldGFpbCBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBNYWxmb3JtZWRVUklFeGNlcHRpb24oKQotICAgIHsKLSAgICAgIHN1cGVyKCk7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogQ29uc3RydWN0cyBhIDxjb2RlPk1hbGZvcm1lZFVSSUV4Y2VwdGlvbjwvY29kZT4gd2l0aCB0aGUKLSAgICAgKiBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCi0gICAgICoKLSAgICAgKiBAcGFyYW0gcF9tc2cgdGhlIGRldGFpbCBtZXNzYWdlLgotICAgICAqLwotICAgIHB1YmxpYyBNYWxmb3JtZWRVUklFeGNlcHRpb24oU3RyaW5nIHBfbXNnKQotICAgIHsKLSAgICAgIHN1cGVyKHBfbXNnKTsKLSAgICB9Ci0gIH0KLQotICAvKiogcmVzZXJ2ZWQgY2hhcmFjdGVycyAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTRVJWRURfQ0hBUkFDVEVSUyA9ICI7Lz86QCY9KyQsIjsKLQotICAvKioKLSAgICogVVJJIHB1bmN0dWF0aW9uIG1hcmsgY2hhcmFjdGVycyAtIHRoZXNlLCBjb21iaW5lZCB3aXRoCi0gICAqICAgYWxwaGFudW1lcmljcywgY29uc3RpdHV0ZSB0aGUgInVucmVzZXJ2ZWQiIGNoYXJhY3RlcnMgCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFSS19DSEFSQUNURVJTID0gIi1fLiF+KicoKSAiOwotCi0gIC8qKiBzY2hlbWUgY2FuIGJlIGNvbXBvc2VkIG9mIGFscGhhbnVtZXJpY3MgYW5kIHRoZXNlIGNoYXJhY3RlcnMgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNRV9DSEFSQUNURVJTID0gIistLiI7Ci0KLSAgLyoqCi0gICAqIHVzZXJpbmZvIGNhbiBiZSBjb21wb3NlZCBvZiB1bnJlc2VydmVkLCBlc2NhcGVkIGFuZCB0aGVzZQotICAgKiAgIGNoYXJhY3RlcnMgCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVNFUklORk9fQ0hBUkFDVEVSUyA9ICI7OiY9KyQsIjsKLQotICAvKiogU3RvcmVzIHRoZSBzY2hlbWUgKHVzdWFsbHkgdGhlIHByb3RvY29sKSBmb3IgdGhpcyBVUkkuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fc2NoZW1lID0gbnVsbDsKLQotICAvKiogSWYgc3BlY2lmaWVkLCBzdG9yZXMgdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fdXNlcmluZm8gPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgaG9zdCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSBudWxsLgotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIFN0cmluZyBtX2hvc3QgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgcG9ydCBmb3IgdGhpcyBVUkk7IG90aGVyd2lzZSAtMS4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJpdmF0ZSBpbnQgbV9wb3J0ID0gLTE7Ci0KLSAgLyoqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBwYXRoIGZvciB0aGlzIFVSSTsgb3RoZXJ3aXNlIG51bGwuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcGF0aCA9IG51bGw7Ci0KLSAgLyoqCi0gICAqIElmIHNwZWNpZmllZCwgc3RvcmVzIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UKLSAgICogICBudWxsLiAKLSAgICogQHNlcmlhbCAKLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIG1fcXVlcnlTdHJpbmcgPSBudWxsOwotCi0gIC8qKiBJZiBzcGVjaWZpZWQsIHN0b3JlcyB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJOyBvdGhlcndpc2UgbnVsbC4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9mcmFnbWVudCA9IG51bGw7Ci0KLSAgLyoqIEluZGljYXRlIHdoZXRoZXIgaW4gREVCVUcgbW9kZSAgICAgICAgICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBhbmQgdW5pbml0aWFsaXplZCBVUkkuCi0gICAqLwotICBwdWJsaWMgVVJJKCl7fQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIGZyb20gYW5vdGhlciBVUkkuIEFsbCBmaWVsZHMgZm9yIHRoaXMgVVJJIGFyZQotICAgKiBzZXQgZXF1YWwgdG8gdGhlIGZpZWxkcyBvZiB0aGUgVVJJIHBhc3NlZCBpbi4KLSAgICoKLSAgICogQHBhcmFtIHBfb3RoZXIgdGhlIFVSSSB0byBjb3B5IChjYW5ub3QgYmUgbnVsbCkKLSAgICovCi0gIHB1YmxpYyBVUkkoVVJJIHBfb3RoZXIpCi0gIHsKLSAgICBpbml0aWFsaXplKHBfb3RoZXIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgZnJvbSBhIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZy4gSWYgdGhlCi0gICAqIHNwZWNpZmljYXRpb24gZm9sbG93cyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsICh0d28gc2xhc2hlcwotICAgKiBmb2xsb3dpbmcgdGhlIGZpcnN0IGNvbG9uKSwgdGhlIHNwZWNpZmljYXRpb24gd2lsbCBiZSBwYXJzZWQKLSAgICogYWNjb3JkaW5nbHkgLSBzZXR0aW5nIHRoZSBzY2hlbWUsIHVzZXJpbmZvLCBob3N0LHBvcnQsIHBhdGgsIHF1ZXJ5Ci0gICAqIHN0cmluZyBhbmQgZnJhZ21lbnQgZmllbGRzIGFzIG5lY2Vzc2FyeS4gSWYgdGhlIHNwZWNpZmljYXRpb24gZG9lcwotICAgKiBub3QgZm9sbG93IHRoZSAiZ2VuZXJpYyBVUkkiIHN5bnRheCwgdGhlIHNwZWNpZmljYXRpb24gaXMgcGFyc2VkCi0gICAqIGludG8gYSBzY2hlbWUgYW5kIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IChzdG9yZWQgYXMgdGhlIHBhdGgpIG9ubHkuCi0gICAqCi0gICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjaWZpY2F0aW9uIHN0cmluZyAoY2Fubm90IGJlIG51bGwgb3IKLSAgICogICAgICAgICAgICAgICAgICBlbXB0eSkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF91cmlTcGVjIHZpb2xhdGVzIGFueSBzeW50YXgKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzCi0gICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3VyaVNwZWMpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotICAgIHRoaXMoKFVSSSkgbnVsbCwgcF91cmlTcGVjKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIGZyb20gYSBiYXNlIFVSSSBhbmQgYSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcuCi0gICAqIFRoZSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcgbWF5IGJlIGEgcmVsYXRpdmUgVVJJLgotICAgKgotICAgKiBAcGFyYW0gcF9iYXNlIHRoZSBiYXNlIFVSSSAoY2Fubm90IGJlIG51bGwgaWYgcF91cmlTcGVjIGlzIG51bGwgb3IKLSAgICogICAgICAgICAgICAgICBlbXB0eSkKLSAgICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gc3RyaW5nIChjYW5ub3QgYmUgbnVsbCBvcgotICAgKiAgICAgICAgICAgICAgICAgIGVtcHR5IGlmIHBfYmFzZSBpcyBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3VyaVNwZWMgdmlvbGF0ZXMgYW55IHN5bnRheAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWxlcwotICAgKi8KLSAgcHVibGljIFVSSShVUkkgcF9iYXNlLCBTdHJpbmcgcF91cmlTcGVjKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLSAgICBpbml0aWFsaXplKHBfYmFzZSwgcF91cmlTcGVjKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuZXcgVVJJIHRoYXQgZG9lcyBub3QgZm9sbG93IHRoZSBnZW5lcmljIFVSSSBzeW50YXguCi0gICAqIE9ubHkgdGhlIHNjaGVtZSBhbmQgc2NoZW1lLXNwZWNpZmljIHBhcnQgKHN0b3JlZCBhcyB0aGUgcGF0aCkgYXJlCi0gICAqIGluaXRpYWxpemVkLgotICAgKgotICAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIFVSSSBzY2hlbWUgKGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5KQotICAgKiBAcGFyYW0gcF9zY2hlbWVTcGVjaWZpY1BhcnQgdGhlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IChjYW5ub3QgYmUKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwgb3IgZW1wdHkpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfc2NoZW1lIHZpb2xhdGVzIGFueQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW50YXggcnVsZXMKLSAgICovCi0gIHB1YmxpYyBVUkkoU3RyaW5nIHBfc2NoZW1lLCBTdHJpbmcgcF9zY2hlbWVTcGVjaWZpY1BhcnQpCi0gICAgICAgICAgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9zY2hlbWUgPT0gbnVsbCB8fCBwX3NjaGVtZS50cmltKCkubGVuZ3RoKCkgPT0gMCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiQ2Fubm90IGNvbnN0cnVjdCBVUkkgd2l0aCBudWxsL2VtcHR5IHNjaGVtZSEiKTsKLSAgICB9Ci0KLSAgICBpZiAocF9zY2hlbWVTcGVjaWZpY1BhcnQgPT0gbnVsbAotICAgICAgICAgICAgfHwgcF9zY2hlbWVTcGVjaWZpY1BhcnQudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgIkNhbm5vdCBjb25zdHJ1Y3QgVVJJIHdpdGggbnVsbC9lbXB0eSBzY2hlbWUtc3BlY2lmaWMgcGFydCEiKTsKLSAgICB9Ci0KLSAgICBzZXRTY2hlbWUocF9zY2hlbWUpOwotICAgIHNldFBhdGgocF9zY2hlbWVTcGVjaWZpY1BhcnQpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgdGhhdCBmb2xsb3dzIHRoZSBnZW5lcmljIFVSSSBzeW50YXggZnJvbSBpdHMKLSAgICogY29tcG9uZW50IHBhcnRzLiBFYWNoIGNvbXBvbmVudCBpcyB2YWxpZGF0ZWQgZm9yIHN5bnRheCBhbmQgc29tZQotICAgKiBiYXNpYyBzZW1hbnRpYyBjaGVja3MgYXJlIHBlcmZvcm1lZCBhcyB3ZWxsLiAgU2VlIHRoZSBpbmRpdmlkdWFsCi0gICAqIHNldHRlciBtZXRob2RzIGZvciBzcGVjaWZpY3MuCi0gICAqCi0gICAqIEBwYXJhbSBwX3NjaGVtZSB0aGUgVVJJIHNjaGVtZSAoY2Fubm90IGJlIG51bGwgb3IgZW1wdHkpCi0gICAqIEBwYXJhbSBwX2hvc3QgdGhlIGhvc3RuYW1lIG9yIElQdjQgYWRkcmVzcyBmb3IgdGhlIFVSSQotICAgKiBAcGFyYW0gcF9wYXRoIHRoZSBVUkkgcGF0aCAtIGlmIHRoZSBwYXRoIGNvbnRhaW5zICc/JyBvciAnIycsCi0gICAqICAgICAgICAgICAgICAgdGhlbiB0aGUgcXVlcnkgc3RyaW5nIGFuZC9vciBmcmFnbWVudCB3aWxsIGJlCi0gICAqICAgICAgICAgICAgICAgc2V0IGZyb20gdGhlIHBhdGg7IGhvd2V2ZXIsIGlmIHRoZSBxdWVyeSBhbmQKLSAgICogICAgICAgICAgICAgICBmcmFnbWVudCBhcmUgc3BlY2lmaWVkIGJvdGggaW4gdGhlIHBhdGggYW5kIGFzCi0gICAqICAgICAgICAgICAgICAgc2VwYXJhdGUgcGFyYW1ldGVycywgYW4gZXhjZXB0aW9uIGlzIHRocm93bgotICAgKiBAcGFyYW0gcF9xdWVyeVN0cmluZyB0aGUgVVJJIHF1ZXJ5IHN0cmluZyAoY2Fubm90IGJlIHNwZWNpZmllZAotICAgKiAgICAgICAgICAgICAgICAgICAgICBpZiBwYXRoIGlzIG51bGwpCi0gICAqIEBwYXJhbSBwX2ZyYWdtZW50IHRoZSBVUkkgZnJhZ21lbnQgKGNhbm5vdCBiZSBzcGVjaWZpZWQgaWYgcGF0aAotICAgKiAgICAgICAgICAgICAgICAgICBpcyBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBhbnkgb2YgdGhlIHBhcmFtZXRlcnMgdmlvbGF0ZXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4IHJ1bGVzIG9yIHNlbWFudGljIHJ1bGVzCi0gICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3NjaGVtZSwgU3RyaW5nIHBfaG9zdCwgU3RyaW5nIHBfcGF0aCwgU3RyaW5nIHBfcXVlcnlTdHJpbmcsIFN0cmluZyBwX2ZyYWdtZW50KQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotICAgIHRoaXMocF9zY2hlbWUsIG51bGwsIHBfaG9zdCwgLTEsIHBfcGF0aCwgcF9xdWVyeVN0cmluZywgcF9mcmFnbWVudCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgbmV3IFVSSSB0aGF0IGZvbGxvd3MgdGhlIGdlbmVyaWMgVVJJIHN5bnRheCBmcm9tIGl0cwotICAgKiBjb21wb25lbnQgcGFydHMuIEVhY2ggY29tcG9uZW50IGlzIHZhbGlkYXRlZCBmb3Igc3ludGF4IGFuZCBzb21lCi0gICAqIGJhc2ljIHNlbWFudGljIGNoZWNrcyBhcmUgcGVyZm9ybWVkIGFzIHdlbGwuICBTZWUgdGhlIGluZGl2aWR1YWwKLSAgICogc2V0dGVyIG1ldGhvZHMgZm9yIHNwZWNpZmljcy4KLSAgICoKLSAgICogQHBhcmFtIHBfc2NoZW1lIHRoZSBVUkkgc2NoZW1lIChjYW5ub3QgYmUgbnVsbCBvciBlbXB0eSkKLSAgICogQHBhcmFtIHBfdXNlcmluZm8gdGhlIFVSSSB1c2VyaW5mbyAoY2Fubm90IGJlIHNwZWNpZmllZCBpZiBob3N0Ci0gICAqICAgICAgICAgICAgICAgICAgIGlzIG51bGwpCi0gICAqIEBwYXJhbSBwX2hvc3QgdGhlIGhvc3RuYW1lIG9yIElQdjQgYWRkcmVzcyBmb3IgdGhlIFVSSQotICAgKiBAcGFyYW0gcF9wb3J0IHRoZSBVUkkgcG9ydCAobWF5IGJlIC0xIGZvciAidW5zcGVjaWZpZWQiOyBjYW5ub3QKLSAgICogICAgICAgICAgICAgICBiZSBzcGVjaWZpZWQgaWYgaG9zdCBpcyBudWxsKQotICAgKiBAcGFyYW0gcF9wYXRoIHRoZSBVUkkgcGF0aCAtIGlmIHRoZSBwYXRoIGNvbnRhaW5zICc/JyBvciAnIycsCi0gICAqICAgICAgICAgICAgICAgdGhlbiB0aGUgcXVlcnkgc3RyaW5nIGFuZC9vciBmcmFnbWVudCB3aWxsIGJlCi0gICAqICAgICAgICAgICAgICAgc2V0IGZyb20gdGhlIHBhdGg7IGhvd2V2ZXIsIGlmIHRoZSBxdWVyeSBhbmQKLSAgICogICAgICAgICAgICAgICBmcmFnbWVudCBhcmUgc3BlY2lmaWVkIGJvdGggaW4gdGhlIHBhdGggYW5kIGFzCi0gICAqICAgICAgICAgICAgICAgc2VwYXJhdGUgcGFyYW1ldGVycywgYW4gZXhjZXB0aW9uIGlzIHRocm93bgotICAgKiBAcGFyYW0gcF9xdWVyeVN0cmluZyB0aGUgVVJJIHF1ZXJ5IHN0cmluZyAoY2Fubm90IGJlIHNwZWNpZmllZAotICAgKiAgICAgICAgICAgICAgICAgICAgICBpZiBwYXRoIGlzIG51bGwpCi0gICAqIEBwYXJhbSBwX2ZyYWdtZW50IHRoZSBVUkkgZnJhZ21lbnQgKGNhbm5vdCBiZSBzcGVjaWZpZWQgaWYgcGF0aAotICAgKiAgICAgICAgICAgICAgICAgICBpcyBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBhbnkgb2YgdGhlIHBhcmFtZXRlcnMgdmlvbGF0ZXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4IHJ1bGVzIG9yIHNlbWFudGljIHJ1bGVzCi0gICAqLwotICBwdWJsaWMgVVJJKFN0cmluZyBwX3NjaGVtZSwgU3RyaW5nIHBfdXNlcmluZm8sIFN0cmluZyBwX2hvc3QsIGludCBwX3BvcnQsIFN0cmluZyBwX3BhdGgsIFN0cmluZyBwX3F1ZXJ5U3RyaW5nLCBTdHJpbmcgcF9mcmFnbWVudCkKLSAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3NjaGVtZSA9PSBudWxsIHx8IHBfc2NoZW1lLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfU0NIRU1FX1JFUVVJUkVELCBudWxsKSk7IC8vIlNjaGVtZSBpcyByZXF1aXJlZCEiKTsKLSAgICB9Ci0KLSAgICBpZiAocF9ob3N0ID09IG51bGwpCi0gICAgewotICAgICAgaWYgKHBfdXNlcmluZm8gIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19VU0VSSU5GT19JRl9OT19IT1NULCBudWxsKSk7IC8vIlVzZXJpbmZvIG1heSBub3QgYmUgc3BlY2lmaWVkIGlmIGhvc3QgaXMgbm90IHNwZWNpZmllZCEiKTsKLSAgICAgIH0KLQotICAgICAgaWYgKHBfcG9ydCAhPSAtMSkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19QT1JUX0lGX05PX0hPU1QsIG51bGwpKTsgLy8iUG9ydCBtYXkgbm90IGJlIHNwZWNpZmllZCBpZiBob3N0IGlzIG5vdCBzcGVjaWZpZWQhIik7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKHBfcGF0aCAhPSBudWxsKQotICAgIHsKLSAgICAgIGlmIChwX3BhdGguaW5kZXhPZignPycpICE9IC0xICYmIHBfcXVlcnlTdHJpbmcgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19RVUVSWV9TVFJJTkdfSU5fUEFUSCwgbnVsbCkpOyAvLyJRdWVyeSBzdHJpbmcgY2Fubm90IGJlIHNwZWNpZmllZCBpbiBwYXRoIGFuZCBxdWVyeSBzdHJpbmchIik7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChwX3BhdGguaW5kZXhPZignIycpICE9IC0xICYmIHBfZnJhZ21lbnQgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9OT19GUkFHTUVOVF9TVFJJTkdfSU5fUEFUSCwgbnVsbCkpOyAvLyJGcmFnbWVudCBjYW5ub3QgYmUgc3BlY2lmaWVkIGluIGJvdGggdGhlIHBhdGggYW5kIGZyYWdtZW50ISIpOwotICAgICAgfQotICAgIH0KLQotICAgIHNldFNjaGVtZShwX3NjaGVtZSk7Ci0gICAgc2V0SG9zdChwX2hvc3QpOwotICAgIHNldFBvcnQocF9wb3J0KTsKLSAgICBzZXRVc2VyaW5mbyhwX3VzZXJpbmZvKTsKLSAgICBzZXRQYXRoKHBfcGF0aCk7Ci0gICAgc2V0UXVlcnlTdHJpbmcocF9xdWVyeVN0cmluZyk7Ci0gICAgc2V0RnJhZ21lbnQocF9mcmFnbWVudCk7Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSBhbGwgZmllbGRzIG9mIHRoaXMgVVJJIGZyb20gYW5vdGhlciBVUkkuCi0gICAqCi0gICAqIEBwYXJhbSBwX290aGVyIHRoZSBVUkkgdG8gY29weSAoY2Fubm90IGJlIG51bGwpCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZShVUkkgcF9vdGhlcikKLSAgewotCi0gICAgbV9zY2hlbWUgPSBwX290aGVyLmdldFNjaGVtZSgpOwotICAgIG1fdXNlcmluZm8gPSBwX290aGVyLmdldFVzZXJpbmZvKCk7Ci0gICAgbV9ob3N0ID0gcF9vdGhlci5nZXRIb3N0KCk7Ci0gICAgbV9wb3J0ID0gcF9vdGhlci5nZXRQb3J0KCk7Ci0gICAgbV9wYXRoID0gcF9vdGhlci5nZXRQYXRoKCk7Ci0gICAgbV9xdWVyeVN0cmluZyA9IHBfb3RoZXIuZ2V0UXVlcnlTdHJpbmcoKTsKLSAgICBtX2ZyYWdtZW50ID0gcF9vdGhlci5nZXRGcmFnbWVudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemVzIHRoaXMgVVJJIGZyb20gYSBiYXNlIFVSSSBhbmQgYSBVUkkgc3BlY2lmaWNhdGlvbiBzdHJpbmcuCi0gICAqIFNlZSBSRkMgMjM5NiBTZWN0aW9uIDQgYW5kIEFwcGVuZGl4IEIgZm9yIHNwZWNpZmljYXRpb25zIG9uIHBhcnNpbmcKLSAgICogdGhlIFVSSSBhbmQgU2VjdGlvbiA1IGZvciBzcGVjaWZpY2F0aW9ucyBvbiByZXNvbHZpbmcgcmVsYXRpdmUgVVJJcwotICAgKiBhbmQgcmVsYXRpdmUgcGF0aHMuCi0gICAqCi0gICAqIEBwYXJhbSBwX2Jhc2UgdGhlIGJhc2UgVVJJIChtYXkgYmUgbnVsbCBpZiBwX3VyaVNwZWMgaXMgYW4gYWJzb2x1dGUKLSAgICogICAgICAgICAgICAgICBVUkkpCi0gICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjIHN0cmluZyB3aGljaCBtYXkgYmUgYW4gYWJzb2x1dGUgb3IKLSAgICogICAgICAgICAgICAgICAgICByZWxhdGl2ZSBVUkkgKGNhbiBvbmx5IGJlIG51bGwvZW1wdHkgaWYgcF9iYXNlCi0gICAqICAgICAgICAgICAgICAgICAgaXMgbm90IG51bGwpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfYmFzZSBpcyBudWxsIGFuZCBwX3VyaVNwZWMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgbm90IGFuIGFic29sdXRlIFVSSSBvciBpZgotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwX3VyaVNwZWMgdmlvbGF0ZXMgc3ludGF4IHJ1bGVzCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZShVUkkgcF9iYXNlLCBTdHJpbmcgcF91cmlTcGVjKQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfYmFzZSA9PSBudWxsCi0gICAgICAgICAgICAmJiAocF91cmlTcGVjID09IG51bGwgfHwgcF91cmlTcGVjLnRyaW0oKS5sZW5ndGgoKSA9PSAwKSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9DQU5OT1RfSU5JVF9VUklfRU1QVFlfUEFSTVMsIG51bGwpKTsgLy8iQ2Fubm90IGluaXRpYWxpemUgVVJJIHdpdGggZW1wdHkgcGFyYW1ldGVycy4iKTsKLSAgICB9Ci0KLSAgICAvLyBqdXN0IG1ha2UgYSBjb3B5IG9mIHRoZSBiYXNlIGlmIHNwZWMgaXMgZW1wdHkKLSAgICBpZiAocF91cmlTcGVjID09IG51bGwgfHwgcF91cmlTcGVjLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIGluaXRpYWxpemUocF9iYXNlKTsKLQotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIFN0cmluZyB1cmlTcGVjID0gcF91cmlTcGVjLnRyaW0oKTsKLSAgICBpbnQgdXJpU3BlY0xlbiA9IHVyaVNwZWMubGVuZ3RoKCk7Ci0gICAgaW50IGluZGV4ID0gMDsKLQotICAgIC8vIGNoZWNrIGZvciBzY2hlbWUKLSAgICBpZiAodXJpU3BlYy5pbmRleE9mKCc6JykgPT0gLTEpCi0gICAgewotICAgICAgaWYgKHBfYmFzZSA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX05PX1NDSEVNRV9JTl9VUkksIG5ldyBPYmplY3RbXXt1cmlTcGVjfSkpOyAvLyJObyBzY2hlbWUgZm91bmQgaW4gVVJJOiAiK3VyaVNwZWMpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW5pdGlhbGl6ZVNjaGVtZSh1cmlTcGVjKTsKLQotICAgICAgaW5kZXggPSBtX3NjaGVtZS5sZW5ndGgoKSArIDE7Ci0gICAgfQotCi0gICAgLy8gdHdvIHNsYXNoZXMgbWVhbnMgZ2VuZXJpYyBVUkkgc3ludGF4LCBzbyB3ZSBnZXQgdGhlIGF1dGhvcml0eQotICAgIGlmICgoKGluZGV4ICsgMSkgPCB1cmlTcGVjTGVuKQotICAgICAgICAgICAgJiYgKHVyaVNwZWMuc3Vic3RyaW5nKGluZGV4KS5zdGFydHNXaXRoKCIvLyIpKSkKLSAgICB7Ci0gICAgICBpbmRleCArPSAyOwotCi0gICAgICBpbnQgc3RhcnRQb3MgPSBpbmRleDsKLQotICAgICAgLy8gZ2V0IGF1dGhvcml0eSAtIGV2ZXJ5dGhpbmcgdXAgdG8gcGF0aCwgcXVlcnkgb3IgZnJhZ21lbnQKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgICB3aGlsZSAoaW5kZXggPCB1cmlTcGVjTGVuKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHVyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJy8nIHx8IHRlc3RDaGFyID09ICc/JyB8fCB0ZXN0Q2hhciA9PSAnIycpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIC8vIGlmIHdlIGZvdW5kIGF1dGhvcml0eSwgcGFyc2UgaXQgb3V0LCBvdGhlcndpc2Ugd2Ugc2V0IHRoZQotICAgICAgLy8gaG9zdCB0byBlbXB0eSBzdHJpbmcKLSAgICAgIGlmIChpbmRleCA+IHN0YXJ0UG9zKQotICAgICAgewotICAgICAgICBpbml0aWFsaXplQXV0aG9yaXR5KHVyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0UG9zLCBpbmRleCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX2hvc3QgPSAiIjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpbml0aWFsaXplUGF0aCh1cmlTcGVjLnN1YnN0cmluZyhpbmRleCkpOwotCi0gICAgLy8gUmVzb2x2ZSByZWxhdGl2ZSBVUkkgdG8gYmFzZSBVUkkgLSBzZWUgUkZDIDIzOTYgU2VjdGlvbiA1LjIKLSAgICAvLyBJbiBzb21lIGNhc2VzLCBpdCBtaWdodCBtYWtlIG1vcmUgc2Vuc2UgdG8gdGhyb3cgYW4gZXhjZXB0aW9uCi0gICAgLy8gKHdoZW4gc2NoZW1lIGlzIHNwZWNpZmllZCBpcyB0aGUgc3RyaW5nIHNwZWMgYW5kIHRoZSBiYXNlIFVSSQotICAgIC8vIGlzIGFsc28gc3BlY2lmaWVkLCBmb3IgZXhhbXBsZSksIGJ1dCB3ZSdyZSBqdXN0IGZvbGxvd2luZyB0aGUKLSAgICAvLyBSRkMgc3BlY2lmaWNhdGlvbnMgCi0gICAgaWYgKHBfYmFzZSAhPSBudWxsKQotICAgIHsKLQotICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIHRoaXMgaXMgdGhlIGN1cnJlbnQgZG9jIC0gUkZDIDIzOTYgNS4yICMyCi0gICAgICAvLyBub3RlIHRoYXQgdGhpcyBpcyBzbGlnaHRseSBkaWZmZXJlbnQgZnJvbSB0aGUgUkZDIHNwZWMgaW4gdGhhdAotICAgICAgLy8gd2UgZG9uJ3QgaW5jbHVkZSB0aGUgY2hlY2sgZm9yIHF1ZXJ5IHN0cmluZyBiZWluZyBudWxsCi0gICAgICAvLyAtIHRoaXMgaGFuZGxlcyBjYXNlcyB3aGVyZSB0aGUgdXJpc3BlYyBpcyBqdXN0IGEgcXVlcnkKLSAgICAgIC8vIHN0cmluZyBvciBhIGZyYWdtZW50IChlLmcuICI/eSIgb3IgIiNzIikgLSAKLSAgICAgIC8vIHNlZSA8aHR0cDovL3d3dy5pY3MudWNpLmVkdS9+ZmllbGRpbmcvdXJsL3Rlc3QxLmh0bWw+IHdoaWNoCi0gICAgICAvLyBpZGVudGlmaWVkIHRoaXMgYXMgYSBidWcgaW4gdGhlIFJGQwotICAgICAgaWYgKG1fcGF0aC5sZW5ndGgoKSA9PSAwICYmIG1fc2NoZW1lID09IG51bGwgJiYgbV9ob3N0ID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIG1fc2NoZW1lID0gcF9iYXNlLmdldFNjaGVtZSgpOwotICAgICAgICBtX3VzZXJpbmZvID0gcF9iYXNlLmdldFVzZXJpbmZvKCk7Ci0gICAgICAgIG1faG9zdCA9IHBfYmFzZS5nZXRIb3N0KCk7Ci0gICAgICAgIG1fcG9ydCA9IHBfYmFzZS5nZXRQb3J0KCk7Ci0gICAgICAgIG1fcGF0aCA9IHBfYmFzZS5nZXRQYXRoKCk7Ci0KLSAgICAgICAgaWYgKG1fcXVlcnlTdHJpbmcgPT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgIG1fcXVlcnlTdHJpbmcgPSBwX2Jhc2UuZ2V0UXVlcnlTdHJpbmcoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybjsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIHNjaGVtZSAtIFJGQyAyMzk2IDUuMiAjMwotICAgICAgLy8gaWYgd2UgZm91bmQgYSBzY2hlbWUsIGl0IG1lYW5zIGFic29sdXRlIFVSSSwgc28gd2UncmUgZG9uZQotICAgICAgaWYgKG1fc2NoZW1lID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIG1fc2NoZW1lID0gcF9iYXNlLmdldFNjaGVtZSgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIC8vIGNoZWNrIGZvciBhdXRob3JpdHkgLSBSRkMgMjM5NiA1LjIgIzQKLSAgICAgIC8vIGlmIHdlIGZvdW5kIGEgaG9zdCwgdGhlbiB3ZSd2ZSBnb3QgYSBuZXR3b3JrIHBhdGgsIHNvIHdlJ3JlIGRvbmUKLSAgICAgIGlmIChtX2hvc3QgPT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgbV91c2VyaW5mbyA9IHBfYmFzZS5nZXRVc2VyaW5mbygpOwotICAgICAgICBtX2hvc3QgPSBwX2Jhc2UuZ2V0SG9zdCgpOwotICAgICAgICBtX3BvcnQgPSBwX2Jhc2UuZ2V0UG9ydCgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIC8vIGNoZWNrIGZvciBhYnNvbHV0ZSBwYXRoIC0gUkZDIDIzOTYgNS4yICM1Ci0gICAgICBpZiAobV9wYXRoLmxlbmd0aCgpID4gMCAmJiBtX3BhdGguc3RhcnRzV2l0aCgiLyIpKQotICAgICAgewotICAgICAgICByZXR1cm47Ci0gICAgICB9Ci0KLSAgICAgIC8vIGlmIHdlIGdldCB0byB0aGlzIHBvaW50LCB3ZSBuZWVkIHRvIHJlc29sdmUgcmVsYXRpdmUgcGF0aAotICAgICAgLy8gUkZDIDIzOTYgNS4yICM2Ci0gICAgICBTdHJpbmcgcGF0aCA9IG5ldyBTdHJpbmcoKTsKLSAgICAgIFN0cmluZyBiYXNlUGF0aCA9IHBfYmFzZS5nZXRQYXRoKCk7Ci0KLSAgICAgIC8vIDZhIC0gZ2V0IGFsbCBidXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgYmFzZSBVUkkgcGF0aAotICAgICAgaWYgKGJhc2VQYXRoICE9IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGludCBsYXN0U2xhc2ggPSBiYXNlUGF0aC5sYXN0SW5kZXhPZignLycpOwotCi0gICAgICAgIGlmIChsYXN0U2xhc2ggIT0gLTEpCi0gICAgICAgIHsKLSAgICAgICAgICBwYXRoID0gYmFzZVBhdGguc3Vic3RyaW5nKDAsIGxhc3RTbGFzaCArIDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZiIC0gYXBwZW5kIHRoZSByZWxhdGl2ZSBVUkkgcGF0aAotICAgICAgcGF0aCA9IHBhdGguY29uY2F0KG1fcGF0aCk7Ci0KLSAgICAgIC8vIDZjIC0gcmVtb3ZlIGFsbCAiLi8iIHdoZXJlICIuIiBpcyBhIGNvbXBsZXRlIHBhdGggc2VnbWVudAotICAgICAgaW5kZXggPSAtMTsKLQotICAgICAgd2hpbGUgKChpbmRleCA9IHBhdGguaW5kZXhPZigiLy4vIikpICE9IC0xKQotICAgICAgewotICAgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMCwgaW5kZXggKyAxKS5jb25jYXQocGF0aC5zdWJzdHJpbmcoaW5kZXggKyAzKSk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZkIC0gcmVtb3ZlICIuIiBpZiBwYXRoIGVuZHMgd2l0aCAiLiIgYXMgYSBjb21wbGV0ZSBwYXRoIHNlZ21lbnQKLSAgICAgIGlmIChwYXRoLmVuZHNXaXRoKCIvLiIpKQotICAgICAgewotICAgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMCwgcGF0aC5sZW5ndGgoKSAtIDEpOwotICAgICAgfQotCi0gICAgICAvLyA2ZSAtIHJlbW92ZSBhbGwgIjxzZWdtZW50Pi8uLi8iIHdoZXJlICI8c2VnbWVudD4iIGlzIGEgY29tcGxldGUgCi0gICAgICAvLyBwYXRoIHNlZ21lbnQgbm90IGVxdWFsIHRvICIuLiIKLSAgICAgIGluZGV4ID0gLTE7Ci0KLSAgICAgIGludCBzZWdJbmRleCA9IC0xOwotICAgICAgU3RyaW5nIHRlbXBTdHJpbmcgPSBudWxsOwotCi0gICAgICB3aGlsZSAoKGluZGV4ID0gcGF0aC5pbmRleE9mKCIvLi4vIikpID4gMCkKLSAgICAgIHsKLSAgICAgICAgdGVtcFN0cmluZyA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGguaW5kZXhPZigiLy4uLyIpKTsKLSAgICAgICAgc2VnSW5kZXggPSB0ZW1wU3RyaW5nLmxhc3RJbmRleE9mKCcvJyk7Ci0KLSAgICAgICAgaWYgKHNlZ0luZGV4ICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCF0ZW1wU3RyaW5nLnN1YnN0cmluZyhzZWdJbmRleCsrKS5lcXVhbHMoIi4uIikpCi0gICAgICAgICAgewotICAgICAgICAgICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHNlZ0luZGV4KS5jb25jYXQocGF0aC5zdWJzdHJpbmcoaW5kZXgKLSAgICAgICAgICAgICAgICAgICAgKyA0KSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIDZmIC0gcmVtb3ZlIGVuZGluZyAiPHNlZ21lbnQ+Ly4uIiB3aGVyZSAiPHNlZ21lbnQ+IiBpcyBhIAotICAgICAgLy8gY29tcGxldGUgcGF0aCBzZWdtZW50Ci0gICAgICBpZiAocGF0aC5lbmRzV2l0aCgiLy4uIikpCi0gICAgICB7Ci0gICAgICAgIHRlbXBTdHJpbmcgPSBwYXRoLnN1YnN0cmluZygwLCBwYXRoLmxlbmd0aCgpIC0gMyk7Ci0gICAgICAgIHNlZ0luZGV4ID0gdGVtcFN0cmluZy5sYXN0SW5kZXhPZignLycpOwotCi0gICAgICAgIGlmIChzZWdJbmRleCAhPSAtMSkKLSAgICAgICAgewotICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZygwLCBzZWdJbmRleCArIDEpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIG1fcGF0aCA9IHBhdGg7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkgZnJvbSBhIFVSSSBzdHJpbmcgc3BlYy4KLSAgICoKLSAgICogQHBhcmFtIHBfdXJpU3BlYyB0aGUgVVJJIHNwZWNpZmljYXRpb24gKGNhbm5vdCBiZSBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBVUkkgZG9lcyBub3QgaGF2ZSBhIGNvbmZvcm1hbnQKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1lCi0gICAqLwotICBwcml2YXRlIHZvaWQgaW5pdGlhbGl6ZVNjaGVtZShTdHJpbmcgcF91cmlTcGVjKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCB1cmlTcGVjTGVuID0gcF91cmlTcGVjLmxlbmd0aCgpOwotICAgIGludCBpbmRleCA9IDA7Ci0gICAgU3RyaW5nIHNjaGVtZSA9IG51bGw7Ci0gICAgY2hhciB0ZXN0Q2hhciA9ICdcMCc7Ci0KLSAgICB3aGlsZSAoaW5kZXggPCB1cmlTcGVjTGVuKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgIGlmICh0ZXN0Q2hhciA9PSAnOicgfHwgdGVzdENoYXIgPT0gJy8nIHx8IHRlc3RDaGFyID09ICc/JwotICAgICAgICAgICAgICB8fCB0ZXN0Q2hhciA9PSAnIycpCi0gICAgICB7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotCi0gICAgICBpbmRleCsrOwotICAgIH0KLQotICAgIHNjaGVtZSA9IHBfdXJpU3BlYy5zdWJzdHJpbmcoMCwgaW5kZXgpOwotCi0gICAgaWYgKHNjaGVtZS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfTk9fU0NIRU1FX0lOVVJJLCBudWxsKSk7IC8vIk5vIHNjaGVtZSBmb3VuZCBpbiBVUkkuIik7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBzZXRTY2hlbWUoc2NoZW1lKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgYXV0aG9yaXR5ICh1c2VyaW5mbywgaG9zdCBhbmQgcG9ydCkgZm9yIHRoaXMKLSAgICogVVJJIGZyb20gYSBVUkkgc3RyaW5nIHNwZWMuCi0gICAqCi0gICAqIEBwYXJhbSBwX3VyaVNwZWMgdGhlIFVSSSBzcGVjaWZpY2F0aW9uIChjYW5ub3QgYmUgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF91cmlTcGVjIHZpb2xhdGVzIHN5bnRheCBydWxlcwotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemVBdXRob3JpdHkoU3RyaW5nIHBfdXJpU3BlYykKLSAgICAgICAgICB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBpbmRleCA9IDA7Ci0gICAgaW50IHN0YXJ0ID0gMDsKLSAgICBpbnQgZW5kID0gcF91cmlTcGVjLmxlbmd0aCgpOwotICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotICAgIFN0cmluZyB1c2VyaW5mbyA9IG51bGw7Ci0KLSAgICAvLyB1c2VyaW5mbyBpcyBldmVyeXRoaW5nIHVwIEAKLSAgICBpZiAocF91cmlTcGVjLmluZGV4T2YoJ0AnLCBzdGFydCkgIT0gLTEpCi0gICAgewotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnQCcpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGluZGV4Kys7Ci0gICAgICB9Ci0KLSAgICAgIHVzZXJpbmZvID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotCi0gICAgICBpbmRleCsrOwotICAgIH0KLQotICAgIC8vIGhvc3QgaXMgZXZlcnl0aGluZyB1cCB0byAnOicKLSAgICBTdHJpbmcgaG9zdCA9IG51bGw7Ci0KLSAgICBzdGFydCA9IGluZGV4OwotCi0gICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgIGlmICh0ZXN0Q2hhciA9PSAnOicpCi0gICAgICB7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotCi0gICAgICBpbmRleCsrOwotICAgIH0KLQotICAgIGhvc3QgPSBwX3VyaVNwZWMuc3Vic3RyaW5nKHN0YXJ0LCBpbmRleCk7Ci0KLSAgICBpbnQgcG9ydCA9IC0xOwotCi0gICAgaWYgKGhvc3QubGVuZ3RoKCkgPiAwKQotICAgIHsKLQotICAgICAgLy8gcG9ydAotICAgICAgaWYgKHRlc3RDaGFyID09ICc6JykKLSAgICAgIHsKLSAgICAgICAgaW5kZXgrKzsKLQotICAgICAgICBzdGFydCA9IGluZGV4OwotCi0gICAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkKLSAgICAgICAgewotICAgICAgICAgIGluZGV4Kys7Ci0gICAgICAgIH0KLQotICAgICAgICBTdHJpbmcgcG9ydFN0ciA9IHBfdXJpU3BlYy5zdWJzdHJpbmcoc3RhcnQsIGluZGV4KTsKLQotICAgICAgICBpZiAocG9ydFN0ci5sZW5ndGgoKSA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBvcnRTdHIubGVuZ3RoKCk7IGkrKykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoIWlzRGlnaXQocG9ydFN0ci5jaGFyQXQoaSkpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAgIHBvcnRTdHIgKyAiIGlzIGludmFsaWQuIFBvcnQgc2hvdWxkIG9ubHkgY29udGFpbiBkaWdpdHMhIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgdHJ5Ci0gICAgICAgICAgewotICAgICAgICAgICAgcG9ydCA9IEludGVnZXIucGFyc2VJbnQocG9ydFN0cik7Ci0gICAgICAgICAgfQotICAgICAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gY2FuJ3QgaGFwcGVuCi0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgc2V0SG9zdChob3N0KTsKLSAgICBzZXRQb3J0KHBvcnQpOwotICAgIHNldFVzZXJpbmZvKHVzZXJpbmZvKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBwYXRoIGZvciB0aGlzIFVSSSBmcm9tIGEgVVJJIHN0cmluZyBzcGVjLgotICAgKgotICAgKiBAcGFyYW0gcF91cmlTcGVjIHRoZSBVUkkgc3BlY2lmaWNhdGlvbiAoY2Fubm90IGJlIG51bGwpCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXJpU3BlYyB2aW9sYXRlcyBzeW50YXggcnVsZXMKLSAgICovCi0gIHByaXZhdGUgdm9pZCBpbml0aWFsaXplUGF0aChTdHJpbmcgcF91cmlTcGVjKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3VyaVNwZWMgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiQ2Fubm90IGluaXRpYWxpemUgcGF0aCBmcm9tIG51bGwgc3RyaW5nISIpOwotICAgIH0KLQotICAgIGludCBpbmRleCA9IDA7Ci0gICAgaW50IHN0YXJ0ID0gMDsKLSAgICBpbnQgZW5kID0gcF91cmlTcGVjLmxlbmd0aCgpOwotICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgLy8gcGF0aCAtIGV2ZXJ5dGhpbmcgdXAgdG8gcXVlcnkgc3RyaW5nIG9yIGZyYWdtZW50Ci0gICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF91cmlTcGVjLmNoYXJBdChpbmRleCk7Ci0KLSAgICAgIGlmICh0ZXN0Q2hhciA9PSAnPycgfHwgdGVzdENoYXIgPT0gJyMnKQotICAgICAgewotICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkIGVzY2FwZSBzZXF1ZW5jZQotICAgICAgaWYgKHRlc3RDaGFyID09ICclJykKLSAgICAgIHsKLSAgICAgICAgaWYgKGluZGV4ICsgMiA+PSBlbmQgfHwhaXNIZXgocF91cmlTcGVjLmNoYXJBdChpbmRleCArIDEpKQotICAgICAgICAgICAgICAgIHx8IWlzSGV4KHBfdXJpU3BlYy5jaGFyQXQoaW5kZXggKyAyKSkpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUEFUSF9DT05UQUlOU19JTlZBTElEX0VTQ0FQRV9TRVFVRU5DRSwgbnVsbCkpOyAvLyJQYXRoIGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICghaXNSZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikKLSAgICAgICAgICAgICAgICYmIWlzVW5yZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikpCi0gICAgICB7Ci0gICAgICAgIGlmICgnXFwnICE9IHRlc3RDaGFyKQotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUEFUSF9JTlZBTElEX0NIQVIsIG5ldyBPYmplY3RbXXtTdHJpbmcudmFsdWVPZih0ZXN0Q2hhcil9KSk7IC8vIlBhdGggY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXI6ICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyB0ZXN0Q2hhcik7Ci0gICAgICB9Ci0KLSAgICAgIGluZGV4Kys7Ci0gICAgfQotCi0gICAgbV9wYXRoID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotCi0gICAgLy8gcXVlcnkgLSBzdGFydHMgd2l0aCA/IGFuZCB1cCB0byBmcmFnbWVudCBvciBlbmQKLSAgICBpZiAodGVzdENoYXIgPT0gJz8nKQotICAgIHsKLSAgICAgIGluZGV4Kys7Ci0KLSAgICAgIHN0YXJ0ID0gaW5kZXg7Ci0KLSAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkKLSAgICAgIHsKLSAgICAgICAgdGVzdENoYXIgPSBwX3VyaVNwZWMuY2hhckF0KGluZGV4KTsKLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJyMnKQotICAgICAgICB7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAodGVzdENoYXIgPT0gJyUnKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKGluZGV4ICsgMiA+PSBlbmQgfHwhaXNIZXgocF91cmlTcGVjLmNoYXJBdChpbmRleCArIDEpKQotICAgICAgICAgICAgICAgICAgfHwhaXNIZXgocF91cmlTcGVjLmNoYXJBdChpbmRleCArIDIpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgICAiUXVlcnkgc3RyaW5nIGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNSZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikKLSAgICAgICAgICAgICAgICAgJiYhaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAiUXVlcnkgc3RyaW5nIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyOiIgKyB0ZXN0Q2hhcik7Ci0gICAgICAgIH0KLQotICAgICAgICBpbmRleCsrOwotICAgICAgfQotCi0gICAgICBtX3F1ZXJ5U3RyaW5nID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotICAgIH0KLQotICAgIC8vIGZyYWdtZW50IC0gc3RhcnRzIHdpdGggIwotICAgIGlmICh0ZXN0Q2hhciA9PSAnIycpCi0gICAgewotICAgICAgaW5kZXgrKzsKLQotICAgICAgc3RhcnQgPSBpbmRleDsKLQotICAgICAgd2hpbGUgKGluZGV4IDwgZW5kKQotICAgICAgewotICAgICAgICB0ZXN0Q2hhciA9IHBfdXJpU3BlYy5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaW5kZXggKyAyID49IGVuZCB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMSkpCi0gICAgICAgICAgICAgICAgICB8fCFpc0hleChwX3VyaVNwZWMuY2hhckF0KGluZGV4ICsgMikpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICAgICAgICJGcmFnbWVudCBjb250YWlucyBpbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSEiKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoIWlzUmVzZXJ2ZWRDaGFyYWN0ZXIodGVzdENoYXIpCi0gICAgICAgICAgICAgICAgICYmIWlzVW5yZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikpCi0gICAgICAgIHsKLSAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICAgIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyOiIgKyB0ZXN0Q2hhcik7Ci0gICAgICAgIH0KLQotICAgICAgICBpbmRleCsrOwotICAgICAgfQotCi0gICAgICBtX2ZyYWdtZW50ID0gcF91cmlTcGVjLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1lKCkKLSAgewotICAgIHJldHVybiBtX3NjaGVtZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHNjaGVtZS1zcGVjaWZpYyBwYXJ0IGZvciB0aGlzIFVSSSAoZXZlcnl0aGluZyBmb2xsb3dpbmcgdGhlCi0gICAqIHNjaGVtZSBhbmQgdGhlIGZpcnN0IGNvbG9uKS4gU2VlIFJGQyAyMzk2IFNlY3Rpb24gNS4yIGZvciBzcGVjLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzY2hlbWUtc3BlY2lmaWMgcGFydCBmb3IgdGhpcyBVUkkKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCkKLSAgewotCi0gICAgU3RyaW5nQnVmZmVyIHNjaGVtZXNwZWMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICBpZiAobV91c2VyaW5mbyAhPSBudWxsIHx8IG1faG9zdCAhPSBudWxsIHx8IG1fcG9ydCAhPSAtMSkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgiLy8iKTsKLSAgICB9Ci0KLSAgICBpZiAobV91c2VyaW5mbyAhPSBudWxsKQotICAgIHsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKG1fdXNlcmluZm8pOwotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQoJ0AnKTsKLSAgICB9Ci0KLSAgICBpZiAobV9ob3N0ICE9IG51bGwpCi0gICAgewotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQobV9ob3N0KTsKLSAgICB9Ci0KLSAgICBpZiAobV9wb3J0ICE9IC0xKQotICAgIHsKLSAgICAgIHNjaGVtZXNwZWMuYXBwZW5kKCc6Jyk7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZChtX3BvcnQpOwotICAgIH0KLQotICAgIGlmIChtX3BhdGggIT0gbnVsbCkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgobV9wYXRoKSk7Ci0gICAgfQotCi0gICAgaWYgKG1fcXVlcnlTdHJpbmcgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgnPycpOwotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQobV9xdWVyeVN0cmluZyk7Ci0gICAgfQotCi0gICAgaWYgKG1fZnJhZ21lbnQgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBzY2hlbWVzcGVjLmFwcGVuZCgnIycpOwotICAgICAgc2NoZW1lc3BlYy5hcHBlbmQobV9mcmFnbWVudCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHNjaGVtZXNwZWMudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHVzZXJpbmZvIGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJIChudWxsIGlmIG5vdCBzcGVjaWZpZWQpLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRVc2VyaW5mbygpCi0gIHsKLSAgICByZXR1cm4gbV91c2VyaW5mbzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGhvc3QgZm9yIHRoaXMgVVJJLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBob3N0IGZvciB0aGlzIFVSSSAobnVsbCBpZiBub3Qgc3BlY2lmaWVkKS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0SG9zdCgpCi0gIHsKLSAgICByZXR1cm4gbV9ob3N0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcG9ydCBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBvcnQgZm9yIHRoaXMgVVJJICgtMSBpZiBub3Qgc3BlY2lmaWVkKS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0UG9ydCgpCi0gIHsKLSAgICByZXR1cm4gbV9wb3J0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcGF0aCBmb3IgdGhpcyBVUkkgKG9wdGlvbmFsbHkgd2l0aCB0aGUgcXVlcnkgc3RyaW5nIGFuZAotICAgKiBmcmFnbWVudCkuCi0gICAqCi0gICAqIEBwYXJhbSBwX2luY2x1ZGVRdWVyeVN0cmluZyBpZiB0cnVlIChhbmQgcXVlcnkgc3RyaW5nIGlzIG5vdCBudWxsKSwKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gYSAiPyIgZm9sbG93ZWQgYnkgdGhlIHF1ZXJ5IHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBhcHBlbmRlZAotICAgKiBAcGFyYW0gcF9pbmNsdWRlRnJhZ21lbnQgaWYgdHJ1ZSAoYW5kIGZyYWdtZW50IGlzIG5vdCBudWxsKSwKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gYSAiIyIgZm9sbG93ZWQgYnkgdGhlIGZyYWdtZW50Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIGFwcGVuZGVkCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBhdGggZm9yIHRoaXMgVVJJIHBvc3NpYmx5IGluY2x1ZGluZyB0aGUgcXVlcnkgc3RyaW5nCi0gICAqICAgICAgICAgYW5kIGZyYWdtZW50Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoYm9vbGVhbiBwX2luY2x1ZGVRdWVyeVN0cmluZywKLSAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcF9pbmNsdWRlRnJhZ21lbnQpCi0gIHsKLQotICAgIFN0cmluZ0J1ZmZlciBwYXRoU3RyaW5nID0gbmV3IFN0cmluZ0J1ZmZlcihtX3BhdGgpOwotCi0gICAgaWYgKHBfaW5jbHVkZVF1ZXJ5U3RyaW5nICYmIG1fcXVlcnlTdHJpbmcgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnPycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9xdWVyeVN0cmluZyk7Ci0gICAgfQotCi0gICAgaWYgKHBfaW5jbHVkZUZyYWdtZW50ICYmIG1fZnJhZ21lbnQgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBwYXRoU3RyaW5nLmFwcGVuZCgnIycpOwotICAgICAgcGF0aFN0cmluZy5hcHBlbmQobV9mcmFnbWVudCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHBhdGhTdHJpbmcudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBhdGggZm9yIHRoaXMgVVJJLiBOb3RlIHRoYXQgdGhlIHZhbHVlIHJldHVybmVkIGlzIHRoZSBwYXRoCi0gICAqIG9ubHkgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGhlIHF1ZXJ5IHN0cmluZyBvciBmcmFnbWVudC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcGF0aCBmb3IgdGhpcyBVUkkuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdGgoKQotICB7Ci0gICAgcmV0dXJuIG1fcGF0aDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkuIE51bGwgaXMgcmV0dXJuZWQgaWYgdGhlcmUKLSAgICogICAgICAgICB3YXMgbm8gIj8iIGluIHRoZSBVUkkgc3BlYywgZW1wdHkgc3RyaW5nIGlmIHRoZXJlIHdhcyBhCi0gICAqICAgICAgICAgIj8iIGJ1dCBubyBxdWVyeSBzdHJpbmcgZm9sbG93aW5nIGl0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRRdWVyeVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV9xdWVyeVN0cmluZzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZyYWdtZW50IGZvciB0aGlzIFVSSS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBOdWxsIGlzIHJldHVybmVkIGlmIHRoZXJlCi0gICAqICAgICAgICAgd2FzIG5vICIjIiBpbiB0aGUgVVJJIHNwZWMsIGVtcHR5IHN0cmluZyBpZiB0aGVyZSB3YXMgYQotICAgKiAgICAgICAgICIjIiBidXQgbm8gZnJhZ21lbnQgZm9sbG93aW5nIGl0LgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRGcmFnbWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9mcmFnbWVudDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkuIFRoZSBzY2hlbWUgaXMgY29udmVydGVkIHRvIGxvd2VyY2FzZQotICAgKiBiZWZvcmUgaXQgaXMgc2V0LgotICAgKgotICAgKiBAcGFyYW0gcF9zY2hlbWUgdGhlIHNjaGVtZSBmb3IgdGhpcyBVUkkgKGNhbm5vdCBiZSBudWxsKQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3NjaGVtZSBpcyBub3QgYSBjb25mb3JtYW50Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtZSBuYW1lCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTY2hlbWUoU3RyaW5nIHBfc2NoZW1lKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3NjaGVtZSA9PSBudWxsKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfU0NIRU1FX0ZST01fTlVMTF9TVFJJTkcsIG51bGwpKTsgLy8iQ2Fubm90IHNldCBzY2hlbWUgZnJvbSBudWxsIHN0cmluZyEiKTsKLSAgICB9Ci0KLSAgICBpZiAoIWlzQ29uZm9ybWFudFNjaGVtZU5hbWUocF9zY2hlbWUpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfU0NIRU1FX05PVF9DT05GT1JNQU5ULCBudWxsKSk7IC8vIlRoZSBzY2hlbWUgaXMgbm90IGNvbmZvcm1hbnQuIik7Ci0gICAgfQotCi0gICAgbV9zY2hlbWUgPSBwX3NjaGVtZS50b0xvd2VyQ2FzZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJLiBJZiBhIG5vbi1udWxsIHZhbHVlIGlzIHBhc3NlZCBpbiBhbmQKLSAgICogdGhlIGhvc3QgdmFsdWUgaXMgbnVsbCwgdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgotICAgKgotICAgKiBAcGFyYW0gcF91c2VyaW5mbyB0aGUgdXNlcmluZm8gZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfdXNlcmluZm8gY29udGFpbnMgaW52YWxpZAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRVc2VyaW5mbyhTdHJpbmcgcF91c2VyaW5mbykgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF91c2VyaW5mbyA9PSBudWxsKQotICAgIHsKLSAgICAgIG1fdXNlcmluZm8gPSBudWxsOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgICJVc2VyaW5mbyBjYW5ub3QgYmUgc2V0IHdoZW4gaG9zdCBpcyBudWxsISIpOwotICAgICAgfQotCi0gICAgICAvLyB1c2VyaW5mbyBjYW4gY29udGFpbiBhbHBoYW51bWVyaWNzLCBtYXJrIGNoYXJhY3RlcnMsIGVzY2FwZWQKLSAgICAgIC8vIGFuZCAnOycsJzonLCcmJywnPScsJysnLCckJywnLCcKLSAgICAgIGludCBpbmRleCA9IDA7Ci0gICAgICBpbnQgZW5kID0gcF91c2VyaW5mby5sZW5ndGgoKTsKLSAgICAgIGNoYXIgdGVzdENoYXIgPSAnXDAnOwotCi0gICAgICB3aGlsZSAoaW5kZXggPCBlbmQpCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gcF91c2VyaW5mby5jaGFyQXQoaW5kZXgpOwotCi0gICAgICAgIGlmICh0ZXN0Q2hhciA9PSAnJScpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoaW5kZXggKyAyID49IGVuZCB8fCFpc0hleChwX3VzZXJpbmZvLmNoYXJBdChpbmRleCArIDEpKQotICAgICAgICAgICAgICAgICAgfHwhaXNIZXgocF91c2VyaW5mby5jaGFyQXQoaW5kZXggKyAyKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgIlVzZXJpbmZvIGNvbnRhaW5zIGludmFsaWQgZXNjYXBlIHNlcXVlbmNlISIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKQotICAgICAgICAgICAgICAgICAmJiBVU0VSSU5GT19DSEFSQUNURVJTLmluZGV4T2YodGVzdENoYXIpID09IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgICAgICJVc2VyaW5mbyBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcjoiICsgdGVzdENoYXIpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW5kZXgrKzsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBtX3VzZXJpbmZvID0gcF91c2VyaW5mbzsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGhvc3QgZm9yIHRoaXMgVVJJLiBJZiBudWxsIGlzIHBhc3NlZCBpbiwgdGhlIHVzZXJpbmZvCi0gICAqIGZpZWxkIGlzIGFsc28gc2V0IHRvIG51bGwgYW5kIHRoZSBwb3J0IGlzIHNldCB0byAtMS4KLSAgICoKLSAgICogQHBhcmFtIHBfaG9zdCB0aGUgaG9zdCBmb3IgdGhpcyBVUkkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9ob3N0IGlzIG5vdCBhIHZhbGlkIElQCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3Mgb3IgRE5TIGhvc3RuYW1lLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SG9zdChTdHJpbmcgcF9ob3N0KSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX2hvc3QgPT0gbnVsbCB8fCBwX2hvc3QudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgbV9ob3N0ID0gcF9ob3N0OwotICAgICAgbV91c2VyaW5mbyA9IG51bGw7Ci0gICAgICBtX3BvcnQgPSAtMTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzV2VsbEZvcm1lZEFkZHJlc3MocF9ob3N0KSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0hPU1RfQUREUkVTU19OT1RfV0VMTEZPUk1FRCwgbnVsbCkpOyAvLyJIb3N0IGlzIG5vdCBhIHdlbGwgZm9ybWVkIGFkZHJlc3MhIik7Ci0gICAgfQotCi0gICAgbV9ob3N0ID0gcF9ob3N0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcG9ydCBmb3IgdGhpcyBVUkkuIC0xIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcG9ydCBpcwotICAgKiBub3Qgc3BlY2lmaWVkLCBvdGhlcndpc2UgdmFsaWQgcG9ydCBudW1iZXJzIGFyZSAgYmV0d2VlbiAwIGFuZCA2NTUzNS4KLSAgICogSWYgYSB2YWxpZCBwb3J0IG51bWJlciBpcyBwYXNzZWQgaW4gYW5kIHRoZSBob3N0IGZpZWxkIGlzIG51bGwsCi0gICAqIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCi0gICAqCi0gICAqIEBwYXJhbSBwX3BvcnQgdGhlIHBvcnQgbnVtYmVyIGZvciB0aGlzIFVSSQotICAgKgotICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbiBpZiBwX3BvcnQgaXMgbm90IC0xIGFuZCBub3QgYQotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCBwb3J0IG51bWJlcgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UG9ydChpbnQgcF9wb3J0KSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3BvcnQgPj0gMCAmJiBwX3BvcnQgPD0gNjU1MzUpCi0gICAgewotICAgICAgaWYgKG1faG9zdCA9PSBudWxsKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAgIFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX1BPUlRfV0hFTl9IT1NUX05VTEwsIG51bGwpKTsgLy8iUG9ydCBjYW5ub3QgYmUgc2V0IHdoZW4gaG9zdCBpcyBudWxsISIpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChwX3BvcnQgIT0gLTEpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9JTlZBTElEX1BPUlQsIG51bGwpKTsgLy8iSW52YWxpZCBwb3J0IG51bWJlciEiKTsKLSAgICB9Ci0KLSAgICBtX3BvcnQgPSBwX3BvcnQ7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBwYXRoIGZvciB0aGlzIFVSSS4gSWYgdGhlIHN1cHBsaWVkIHBhdGggaXMgbnVsbCwgdGhlbiB0aGUKLSAgICogcXVlcnkgc3RyaW5nIGFuZCBmcmFnbWVudCBhcmUgc2V0IHRvIG51bGwgYXMgd2VsbC4gSWYgdGhlIHN1cHBsaWVkCi0gICAqIHBhdGggaW5jbHVkZXMgYSBxdWVyeSBzdHJpbmcgYW5kL29yIGZyYWdtZW50LCB0aGVzZSBmaWVsZHMgd2lsbCBiZQotICAgKiBwYXJzZWQgYW5kIHNldCBhcyB3ZWxsLiBOb3RlIHRoYXQsIGZvciBVUklzIGZvbGxvd2luZyB0aGUgImdlbmVyaWMKLSAgICogVVJJIiBzeW50YXgsIHRoZSBwYXRoIHNwZWNpZmllZCBzaG91bGQgc3RhcnQgd2l0aCBhIHNsYXNoLgotICAgKiBGb3IgVVJJcyB0aGF0IGRvIG5vdCBmb2xsb3cgdGhlIGdlbmVyaWMgVVJJIHN5bnRheCwgdGhpcyBtZXRob2QKLSAgICogc2V0cyB0aGUgc2NoZW1lLXNwZWNpZmljIHBhcnQuCi0gICAqCi0gICAqIEBwYXJhbSBwX3BhdGggdGhlIHBhdGggZm9yIHRoaXMgVVJJIChtYXkgYmUgbnVsbCkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9wYXRoIGNvbnRhaW5zIGludmFsaWQKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycwotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGF0aChTdHJpbmcgcF9wYXRoKSB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChwX3BhdGggPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX3BhdGggPSBudWxsOwotICAgICAgbV9xdWVyeVN0cmluZyA9IG51bGw7Ci0gICAgICBtX2ZyYWdtZW50ID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGluaXRpYWxpemVQYXRoKHBfcGF0aCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGVuZCB0byB0aGUgZW5kIG9mIHRoZSBwYXRoIG9mIHRoaXMgVVJJLiBJZiB0aGUgY3VycmVudCBwYXRoIGRvZXMKLSAgICogbm90IGVuZCBpbiBhIHNsYXNoIGFuZCB0aGUgcGF0aCB0byBiZSBhcHBlbmRlZCBkb2VzIG5vdCBiZWdpbiB3aXRoCi0gICAqIGEgc2xhc2gsIGEgc2xhc2ggd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgY3VycmVudCBwYXRoIGJlZm9yZSB0aGUKLSAgICogbmV3IHNlZ21lbnQgaXMgYWRkZWQuIEFsc28sIGlmIHRoZSBjdXJyZW50IHBhdGggZW5kcyBpbiBhIHNsYXNoCi0gICAqIGFuZCB0aGUgbmV3IHNlZ21lbnQgYmVnaW5zIHdpdGggYSBzbGFzaCwgdGhlIGV4dHJhIHNsYXNoIHdpbGwgYmUKLSAgICogcmVtb3ZlZCBiZWZvcmUgdGhlIG5ldyBzZWdtZW50IGlzIGFwcGVuZGVkLgotICAgKgotICAgKiBAcGFyYW0gcF9hZGRUb1BhdGggdGhlIG5ldyBzZWdtZW50IHRvIGJlIGFkZGVkIHRvIHRoZSBjdXJyZW50IHBhdGgKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9hZGRUb1BhdGggY29udGFpbnMgc3ludGF4Ci0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycwotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kUGF0aChTdHJpbmcgcF9hZGRUb1BhdGgpIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfYWRkVG9QYXRoID09IG51bGwgfHwgcF9hZGRUb1BhdGgudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgcmV0dXJuOwotICAgIH0KLQotICAgIGlmICghaXNVUklTdHJpbmcocF9hZGRUb1BhdGgpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfUEFUSF9JTlZBTElEX0NIQVIsIG5ldyBPYmplY3RbXXtwX2FkZFRvUGF0aH0pKTsgLy8iUGF0aCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciEiKTsKLSAgICB9Ci0KLSAgICBpZiAobV9wYXRoID09IG51bGwgfHwgbV9wYXRoLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQotICAgIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0aCA9IHBfYWRkVG9QYXRoOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSAiLyIgKyBwX2FkZFRvUGF0aDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAobV9wYXRoLmVuZHNXaXRoKCIvIikpCi0gICAgewotICAgICAgaWYgKHBfYWRkVG9QYXRoLnN0YXJ0c1dpdGgoIi8iKSkKLSAgICAgIHsKLSAgICAgICAgbV9wYXRoID0gbV9wYXRoLmNvbmNhdChwX2FkZFRvUGF0aC5zdWJzdHJpbmcoMSkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGlmIChwX2FkZFRvUGF0aC5zdGFydHNXaXRoKCIvIikpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0aCA9IG1fcGF0aC5jb25jYXQocF9hZGRUb1BhdGgpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3BhdGggPSBtX3BhdGguY29uY2F0KCIvIiArIHBfYWRkVG9QYXRoKTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgICogaWYgdGhpcyBpcyBhbiBVUkkgY29uZm9ybWluZyB0byB0aGUgZ2VuZXJpYyBVUkkgc3ludGF4IGFuZAotICAgKiB0aGUgcGF0aCB2YWx1ZSBpcyBub3QgbnVsbC4KLSAgICoKLSAgICogQHBhcmFtIHBfcXVlcnlTdHJpbmcgdGhlIHF1ZXJ5IHN0cmluZyBmb3IgdGhpcyBVUkkKLSAgICoKLSAgICogQHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24gaWYgcF9xdWVyeVN0cmluZyBpcyBub3QgbnVsbCBhbmQgdGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgZG9lcyBub3QgY29uZm9ybSB0byB0aGUgZ2VuZXJpYwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgc3ludGF4IG9yIGlmIHRoZSBwYXRoIGlzIG51bGwKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFF1ZXJ5U3RyaW5nKFN0cmluZyBwX3F1ZXJ5U3RyaW5nKQotICAgICAgICAgIHRocm93cyBNYWxmb3JtZWRVUklFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHBfcXVlcnlTdHJpbmcgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBtX3F1ZXJ5U3RyaW5nID0gbnVsbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAoIWlzR2VuZXJpY1VSSSgpKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUklFeGNlcHRpb24oCi0gICAgICAgICJRdWVyeSBzdHJpbmcgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChnZXRQYXRoKCkgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNhbm5vdCBiZSBzZXQgd2hlbiBwYXRoIGlzIG51bGwhIik7Ci0gICAgfQotICAgIGVsc2UgaWYgKCFpc1VSSVN0cmluZyhwX3F1ZXJ5U3RyaW5nKSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICAiUXVlcnkgc3RyaW5nIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9xdWVyeVN0cmluZyA9IHBfcXVlcnlTdHJpbmc7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJLiBBIG5vbi1udWxsIHZhbHVlIGlzIHZhbGlkIG9ubHkKLSAgICogaWYgdGhpcyBpcyBhIFVSSSBjb25mb3JtaW5nIHRvIHRoZSBnZW5lcmljIFVSSSBzeW50YXggYW5kCi0gICAqIHRoZSBwYXRoIHZhbHVlIGlzIG5vdCBudWxsLgotICAgKgotICAgKiBAcGFyYW0gcF9mcmFnbWVudCB0aGUgZnJhZ21lbnQgZm9yIHRoaXMgVVJJCi0gICAqCi0gICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJJRXhjZXB0aW9uIGlmIHBfZnJhZ21lbnQgaXMgbm90IG51bGwgYW5kIHRoaXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIGRvZXMgbm90IGNvbmZvcm0gdG8gdGhlIGdlbmVyaWMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIHN5bnRheCBvciBpZiB0aGUgcGF0aCBpcyBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRGcmFnbWVudChTdHJpbmcgcF9mcmFnbWVudCkgdGhyb3dzIE1hbGZvcm1lZFVSSUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocF9mcmFnbWVudCA9PSBudWxsKQotICAgIHsKLSAgICAgIG1fZnJhZ21lbnQgPSBudWxsOwotICAgIH0KLSAgICBlbHNlIGlmICghaXNHZW5lcmljVVJJKCkpCi0gICAgewotICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVSSUV4Y2VwdGlvbigKLSAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlJBR19GT1JfR0VORVJJQ19VUkksIG51bGwpKTsgLy8iRnJhZ21lbnQgY2FuIG9ubHkgYmUgc2V0IGZvciBhIGdlbmVyaWMgVVJJISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChnZXRQYXRoKCkgPT0gbnVsbCkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKAotICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKFhTTFRFcnJvclJlc291cmNlcy5FUl9GUkFHX1dIRU5fUEFUSF9OVUxMLCBudWxsKSk7IC8vIkZyYWdtZW50IGNhbm5vdCBiZSBzZXQgd2hlbiBwYXRoIGlzIG51bGwhIik7Ci0gICAgfQotICAgIGVsc2UgaWYgKCFpc1VSSVN0cmluZyhwX2ZyYWdtZW50KSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJJRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZU1lc3NhZ2UoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZSQUdfSU5WQUxJRF9DSEFSLCBudWxsKSk7IC8vIkZyYWdtZW50IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyISIpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9mcmFnbWVudCA9IHBfZnJhZ21lbnQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgaWYgdGhlIHBhc3NlZC1pbiBPYmplY3QgaXMgZXF1aXZhbGVudCB0byB0aGlzIFVSSS4KLSAgICoKLSAgICogQHBhcmFtIHBfdGVzdCB0aGUgT2JqZWN0IHRvIHRlc3QgZm9yIGVxdWFsaXR5LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgcF90ZXN0IGlzIGEgVVJJIHdpdGggYWxsIHZhbHVlcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgVVJJLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgcF90ZXN0KQotICB7Ci0KLSAgICBpZiAocF90ZXN0IGluc3RhbmNlb2YgVVJJKQotICAgIHsKLSAgICAgIFVSSSB0ZXN0VVJJID0gKFVSSSkgcF90ZXN0OwotCi0gICAgICBpZiAoKChtX3NjaGVtZSA9PSBudWxsICYmIHRlc3RVUkkubV9zY2hlbWUgPT0gbnVsbCkgfHwgKG1fc2NoZW1lICE9IG51bGwgJiYgdGVzdFVSSS5tX3NjaGVtZSAhPSBudWxsICYmIG1fc2NoZW1lLmVxdWFscygKLSAgICAgICAgICAgICAgdGVzdFVSSS5tX3NjaGVtZSkpKSAmJiAoKG1fdXNlcmluZm8gPT0gbnVsbCAmJiB0ZXN0VVJJLm1fdXNlcmluZm8gPT0gbnVsbCkgfHwgKG1fdXNlcmluZm8gIT0gbnVsbCAmJiB0ZXN0VVJJLm1fdXNlcmluZm8gIT0gbnVsbCAmJiBtX3VzZXJpbmZvLmVxdWFscygKLSAgICAgICAgICAgICAgdGVzdFVSSS5tX3VzZXJpbmZvKSkpICYmICgobV9ob3N0ID09IG51bGwgJiYgdGVzdFVSSS5tX2hvc3QgPT0gbnVsbCkgfHwgKG1faG9zdCAhPSBudWxsICYmIHRlc3RVUkkubV9ob3N0ICE9IG51bGwgJiYgbV9ob3N0LmVxdWFscygKLSAgICAgICAgICAgICAgdGVzdFVSSS5tX2hvc3QpKSkgJiYgbV9wb3J0ID09IHRlc3RVUkkubV9wb3J0ICYmICgobV9wYXRoID09IG51bGwgJiYgdGVzdFVSSS5tX3BhdGggPT0gbnVsbCkgfHwgKG1fcGF0aCAhPSBudWxsICYmIHRlc3RVUkkubV9wYXRoICE9IG51bGwgJiYgbV9wYXRoLmVxdWFscygKLSAgICAgICAgICAgICAgdGVzdFVSSS5tX3BhdGgpKSkgJiYgKChtX3F1ZXJ5U3RyaW5nID09IG51bGwgJiYgdGVzdFVSSS5tX3F1ZXJ5U3RyaW5nID09IG51bGwpIHx8IChtX3F1ZXJ5U3RyaW5nICE9IG51bGwgJiYgdGVzdFVSSS5tX3F1ZXJ5U3RyaW5nICE9IG51bGwgJiYgbV9xdWVyeVN0cmluZy5lcXVhbHMoCi0gICAgICAgICAgICAgIHRlc3RVUkkubV9xdWVyeVN0cmluZykpKSAmJiAoKG1fZnJhZ21lbnQgPT0gbnVsbCAmJiB0ZXN0VVJJLm1fZnJhZ21lbnQgPT0gbnVsbCkgfHwgKG1fZnJhZ21lbnQgIT0gbnVsbCAmJiB0ZXN0VVJJLm1fZnJhZ21lbnQgIT0gbnVsbCAmJiBtX2ZyYWdtZW50LmVxdWFscygKLSAgICAgICAgICAgICAgdGVzdFVSSS5tX2ZyYWdtZW50KSkpKQotICAgICAgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBVUkkgYXMgYSBzdHJpbmcgc3BlY2lmaWNhdGlvbi4gU2VlIFJGQyAyMzk2IFNlY3Rpb24gNS4yLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBVUkkgc3RyaW5nIHNwZWNpZmljYXRpb24KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQotICB7Ci0KLSAgICBTdHJpbmdCdWZmZXIgdXJpU3BlY1N0cmluZyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGlmIChtX3NjaGVtZSAhPSBudWxsKQotICAgIHsKLSAgICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKG1fc2NoZW1lKTsKLSAgICAgIHVyaVNwZWNTdHJpbmcuYXBwZW5kKCc6Jyk7Ci0gICAgfQotCi0gICAgdXJpU3BlY1N0cmluZy5hcHBlbmQoZ2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCkpOwotCi0gICAgcmV0dXJuIHVyaVNwZWNTdHJpbmcudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluZGljYXRvciBhcyB0byB3aGV0aGVyIHRoaXMgVVJJIHVzZXMgdGhlICJnZW5lcmljIFVSSSIKLSAgICogc3ludGF4LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBVUkkgdXNlcyB0aGUgImdlbmVyaWMgVVJJIiBzeW50YXgsIGZhbHNlCi0gICAqICAgICAgICAgb3RoZXJ3aXNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0dlbmVyaWNVUkkoKQotICB7Ci0KLSAgICAvLyBwcmVzZW5jZSBvZiB0aGUgaG9zdCAod2hldGhlciB2YWxpZCBvciBlbXB0eSkgbWVhbnMgCi0gICAgLy8gZG91YmxlLXNsYXNoZXMgd2hpY2ggbWVhbnMgZ2VuZXJpYyB1cmkKLSAgICByZXR1cm4gKG1faG9zdCAhPSBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIHNjaGVtZSBjb25mb3JtcyB0byB0aGUgcnVsZXMgZm9yIGEgc2NoZW1lIG5hbWUuCi0gICAqIEEgc2NoZW1lIGlzIGNvbmZvcm1hbnQgaWYgaXQgc3RhcnRzIHdpdGggYW4gYWxwaGFudW1lcmljLCBhbmQKLSAgICogY29udGFpbnMgb25seSBhbHBoYW51bWVyaWNzLCAnKycsJy0nIGFuZCAnLicuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX3NjaGVtZSBUaGUgc2hlbWUgbmFtZSB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNjaGVtZSBpcyBjb25mb3JtYW50LCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbmZvcm1hbnRTY2hlbWVOYW1lKFN0cmluZyBwX3NjaGVtZSkKLSAgewotCi0gICAgaWYgKHBfc2NoZW1lID09IG51bGwgfHwgcF9zY2hlbWUudHJpbSgpLmxlbmd0aCgpID09IDApCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIGlmICghaXNBbHBoYShwX3NjaGVtZS5jaGFyQXQoMCkpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICBjaGFyIHRlc3RDaGFyOwotCi0gICAgZm9yIChpbnQgaSA9IDE7IGkgPCBwX3NjaGVtZS5sZW5ndGgoKTsgaSsrKQotICAgIHsKLSAgICAgIHRlc3RDaGFyID0gcF9zY2hlbWUuY2hhckF0KGkpOwotCi0gICAgICBpZiAoIWlzQWxwaGFudW0odGVzdENoYXIpICYmIFNDSEVNRV9DSEFSQUNURVJTLmluZGV4T2YodGVzdENoYXIpID09IC0xKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBzdHJpbmcgaXMgc3ludGFjdGljYWxseSBjYXBhYmxlIG9mIHJlcHJlc2VudGluZwotICAgKiBhIHZhbGlkIElQdjQgYWRkcmVzcyBvciB0aGUgZG9tYWluIG5hbWUgb2YgYSBuZXR3b3JrIGhvc3QuIEEgdmFsaWQKLSAgICogSVB2NCBhZGRyZXNzIGNvbnNpc3RzIG9mIGZvdXIgZGVjaW1hbCBkaWdpdCBncm91cHMgc2VwYXJhdGVkIGJ5IGEKLSAgICogJy4nLiBBIGhvc3RuYW1lIGNvbnNpc3RzIG9mIGRvbWFpbiBsYWJlbHMgKGVhY2ggb2Ygd2hpY2ggbXVzdAotICAgKiBiZWdpbiBhbmQgZW5kIHdpdGggYW4gYWxwaGFudW1lcmljIGJ1dCBtYXkgY29udGFpbiAnLScpIHNlcGFyYXRlZAotICAgKiAmIGJ5IGEgJy4nLiBTZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfYWRkcmVzcyBUaGUgYWRkcmVzcyBzdHJpbmcgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgaXMgYSBzeW50YWN0aWNhbGx5IHZhbGlkIElQdjQgYWRkcmVzcwotICAgKiAgICAgICAgICAgICAgb3IgaG9zdG5hbWUKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1dlbGxGb3JtZWRBZGRyZXNzKFN0cmluZyBwX2FkZHJlc3MpCi0gIHsKLQotICAgIGlmIChwX2FkZHJlc3MgPT0gbnVsbCkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgU3RyaW5nIGFkZHJlc3MgPSBwX2FkZHJlc3MudHJpbSgpOwotICAgIGludCBhZGRyTGVuZ3RoID0gYWRkcmVzcy5sZW5ndGgoKTsKLQotICAgIGlmIChhZGRyTGVuZ3RoID09IDAgfHwgYWRkckxlbmd0aCA+IDI1NSkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgiLiIpIHx8IGFkZHJlc3Muc3RhcnRzV2l0aCgiLSIpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICAvLyByaWdodG1vc3QgZG9tYWluIGxhYmVsIHN0YXJ0aW5nIHdpdGggZGlnaXQgaW5kaWNhdGVzIElQIGFkZHJlc3MKLSAgICAvLyBzaW5jZSB0b3AgbGV2ZWwgZG9tYWluIGxhYmVsIGNhbiBvbmx5IHN0YXJ0IHdpdGggYW4gYWxwaGEKLSAgICAvLyBzZWUgUkZDIDIzOTYgU2VjdGlvbiAzLjIuMgotICAgIGludCBpbmRleCA9IGFkZHJlc3MubGFzdEluZGV4T2YoJy4nKTsKLQotICAgIGlmIChhZGRyZXNzLmVuZHNXaXRoKCIuIikpCi0gICAgewotICAgICAgaW5kZXggPSBhZGRyZXNzLnN1YnN0cmluZygwLCBpbmRleCkubGFzdEluZGV4T2YoJy4nKTsKLSAgICB9Ci0KLSAgICBpZiAoaW5kZXggKyAxIDwgYWRkckxlbmd0aCAmJiBpc0RpZ2l0KHBfYWRkcmVzcy5jaGFyQXQoaW5kZXggKyAxKSkpCi0gICAgewotICAgICAgY2hhciB0ZXN0Q2hhcjsKLSAgICAgIGludCBudW1Eb3RzID0gMDsKLQotICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgMSkgd2Ugc2VlIG9ubHkgZGlnaXRzIGFuZCBkb3Qgc2VwYXJhdG9ycywgMikgdGhhdAotICAgICAgLy8gYW55IGRvdCBzZXBhcmF0b3IgaXMgcHJlY2VkZWQgYW5kIGZvbGxvd2VkIGJ5IGEgZGlnaXQgYW5kIAotICAgICAgLy8gMykgdGhhdCB3ZSBmaW5kIDMgZG90cwotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyTGVuZ3RoOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gYWRkcmVzcy5jaGFyQXQoaSk7Ci0KLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICcuJykKLSAgICAgICAgewotICAgICAgICAgIGlmICghaXNEaWdpdChhZGRyZXNzLmNoYXJBdChpIC0gMSkpCi0gICAgICAgICAgICAgICAgICB8fCAoaSArIDEgPCBhZGRyTGVuZ3RoICYmIWlzRGlnaXQoYWRkcmVzcy5jaGFyQXQoaSArIDEpKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLQotICAgICAgICAgIG51bURvdHMrKzsKLSAgICAgICAgfQotICAgICAgICBlbHNlIGlmICghaXNEaWdpdCh0ZXN0Q2hhcikpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKG51bURvdHMgIT0gMykKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyBkb21haW4gbGFiZWxzIGNhbiBjb250YWluIGFscGhhbnVtZXJpY3MgYW5kICctIgotICAgICAgLy8gYnV0IG11c3Qgc3RhcnQgYW5kIGVuZCB3aXRoIGFuIGFscGhhbnVtZXJpYwotICAgICAgY2hhciB0ZXN0Q2hhcjsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyTGVuZ3RoOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHRlc3RDaGFyID0gYWRkcmVzcy5jaGFyQXQoaSk7Ci0KLSAgICAgICAgaWYgKHRlc3RDaGFyID09ICcuJykKLSAgICAgICAgewotICAgICAgICAgIGlmICghaXNBbHBoYW51bShhZGRyZXNzLmNoYXJBdChpIC0gMSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoaSArIDEgPCBhZGRyTGVuZ3RoICYmIWlzQWxwaGFudW0oYWRkcmVzcy5jaGFyQXQoaSArIDEpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFpc0FscGhhbnVtKHRlc3RDaGFyKSAmJiB0ZXN0Q2hhciAhPSAnLScpCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYSBkaWdpdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBfY2hhciB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhciBpcyBiZXR3ZWVlbiAnMCcgYW5kICc5JywgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzRGlnaXQoY2hhciBwX2NoYXIpCi0gIHsKLSAgICByZXR1cm4gcF9jaGFyID49ICcwJyAmJiBwX2NoYXIgPD0gJzknOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhcmFjdGVyIGlzIGEgaGV4YWRlY2ltYWwgY2hhcmFjdGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIGJldHdlZWVuICcwJyBhbmQgJzknLCAnYScgYW5kICdmJwotICAgKiAgICAgICAgIG9yICdBJyBhbmQgJ0YnLCBmYWxzZSBvdGhlcndpc2UKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNIZXgoY2hhciBwX2NoYXIpCi0gIHsKLSAgICByZXR1cm4gKGlzRGlnaXQocF9jaGFyKSB8fCAocF9jaGFyID49ICdhJyAmJiBwX2NoYXIgPD0gJ2YnKQotICAgICAgICAgICAgfHwgKHBfY2hhciA+PSAnQScgJiYgcF9jaGFyIDw9ICdGJykpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhciBpcyBhbiBhbHBoYWJldGljIGNoYXJhY3RlcjogYS16IG9yIEEtWgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIGFscGhhYmV0aWMsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0FscGhhKGNoYXIgcF9jaGFyKQotICB7Ci0gICAgcmV0dXJuICgocF9jaGFyID49ICdhJyAmJiBwX2NoYXIgPD0gJ3onKQotICAgICAgICAgICAgfHwgKHBfY2hhciA+PSAnQScgJiYgcF9jaGFyIDw9ICdaJykpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhciBpcyBhbiBhbHBoYW51bWVyaWM6IDAtOSwgYS16IG9yIEEtWgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyIGlzIGFscGhhbnVtZXJpYywgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQWxwaGFudW0oY2hhciBwX2NoYXIpCi0gIHsKLSAgICByZXR1cm4gKGlzQWxwaGEocF9jaGFyKSB8fCBpc0RpZ2l0KHBfY2hhcikpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgY2hhcmFjdGVyIGlzIGEgcmVzZXJ2ZWQgY2hhcmFjdGVyOgotICAgKiAnOycsICcvJywgJz8nLCAnOicsICdAJywgJyYnLCAnPScsICcrJywgJyQnIG9yICcsJwotICAgKgotICAgKgotICAgKiBAcGFyYW0gcF9jaGFyIHRoZSBjaGFyYWN0ZXIgdG8gY2hlY2sKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgY29udGFpbnMgYW55IHJlc2VydmVkIGNoYXJhY3RlcnMKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNSZXNlcnZlZENoYXJhY3RlcihjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiBSRVNFUlZFRF9DSEFSQUNURVJTLmluZGV4T2YocF9jaGFyKSAhPSAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmUgd2hldGhlciBhIGNoYXIgaXMgYW4gdW5yZXNlcnZlZCBjaGFyYWN0ZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX2NoYXIgdGhlIGNoYXJhY3RlciB0byBjaGVjawotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNoYXIgaXMgdW5yZXNlcnZlZCwgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVW5yZXNlcnZlZENoYXJhY3RlcihjaGFyIHBfY2hhcikKLSAgewotICAgIHJldHVybiAoaXNBbHBoYW51bShwX2NoYXIpIHx8IE1BUktfQ0hBUkFDVEVSUy5pbmRleE9mKHBfY2hhcikgIT0gLTEpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZSB3aGV0aGVyIGEgZ2l2ZW4gc3RyaW5nIGNvbnRhaW5zIG9ubHkgVVJJIGNoYXJhY3RlcnMgKGFsc28KLSAgICogY2FsbGVkICJ1cmljIiBpbiBSRkMgMjM5NikuIHVyaWMgY29uc2lzdCBvZiBhbGwgcmVzZXJ2ZWQKLSAgICogY2hhcmFjdGVycywgdW5yZXNlcnZlZCBjaGFyYWN0ZXJzIGFuZCBlc2NhcGVkIGNoYXJhY3RlcnMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwX3VyaWMgVVJJIHN0cmluZwotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0cmluZyBpcyBjb21wcmlzZWQgb2YgdXJpYywgZmFsc2Ugb3RoZXJ3aXNlCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVVJJU3RyaW5nKFN0cmluZyBwX3VyaWMpCi0gIHsKLQotICAgIGlmIChwX3VyaWMgPT0gbnVsbCkKLSAgICB7Ci0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgaW50IGVuZCA9IHBfdXJpYy5sZW5ndGgoKTsKLSAgICBjaGFyIHRlc3RDaGFyID0gJ1wwJzsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW5kOyBpKyspCi0gICAgewotICAgICAgdGVzdENoYXIgPSBwX3VyaWMuY2hhckF0KGkpOwotCi0gICAgICBpZiAodGVzdENoYXIgPT0gJyUnKQotICAgICAgewotICAgICAgICBpZiAoaSArIDIgPj0gZW5kIHx8IWlzSGV4KHBfdXJpYy5jaGFyQXQoaSArIDEpKQotICAgICAgICAgICAgICAgIHx8IWlzSGV4KHBfdXJpYy5jaGFyQXQoaSArIDIpKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBpICs9IDI7Ci0KLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoaXNSZXNlcnZlZENoYXJhY3Rlcih0ZXN0Q2hhcikgfHwgaXNVbnJlc2VydmVkQ2hhcmFjdGVyKHRlc3RDaGFyKSkKLSAgICAgIHsKLSAgICAgICAgY29udGludWU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1VuSW1wbE5vZGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9VbkltcGxOb2RlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQxODhkNmUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1VuSW1wbE5vZGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMDUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMVEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVG8gYmUgc3ViY2xhc3NlZCBieSBjbGFzc2VzIHRoYXQgd2lzaCB0byBmYWtlIGJlaW5nIG5vZGVzLgotICovCi1wdWJsaWMgY2xhc3MgVW5JbXBsTm9kZSBpbXBsZW1lbnRzIE5vZGUsIEVsZW1lbnQsIE5vZGVMaXN0LCBEb2N1bWVudAotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBVbkltcGxOb2RlCi0gICAqCi0gICAqLwotICBwdWJsaWMgVW5JbXBsTm9kZSgpe30KLQotICAvKioKLSAgICogVGhyb3cgYW4gZXJyb3IuCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgTWVzc2FnZSBjb2RlIGZvciB0aGUgZXJyb3IKLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKGludCBtc2cpCi0gIHsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRE9NIEVSUk9SISBjbGFzczogIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOwotCi0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZShtc2csIG51bGwpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaHJvdyBhbiBlcnJvci4KLSAgICoKLSAgICogQHBhcmFtIG1zZyBNZXNzYWdlIGNvZGUgZm9yIHRoZSBlcnJvcgotICAgKiBAcGFyYW0gYXJncyBBcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgdXNlZCBpbiB0aGUgZXJyb3IgbWVzc2FnZQotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoaW50IG1zZywgT2JqZWN0W10gYXJncykKLSAgewotCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJET00gRVJST1IhIGNsYXNzOiAiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0KLSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVNZXNzYWdlKG1zZywgYXJncykpOyAgLy8iVW5JbXBsTm9kZSBlcnJvcjogIittc2cpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBuZXdDaGlsZCBOZXcgbm9kZSB0byBhcHBlbmQgdG8gdGhlIGxpc3Qgb2YgdGhpcyBub2RlJ3MgY2hpbGRyZW4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZSBhcHBlbmRDaGlsZChOb2RlIG5ld0NoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImFwcGVuZENoaWxkIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZE5vZGVzKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iaGFzQ2hpbGROb2RlcyBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gMAotICAgKi8KLSAgcHVibGljIHNob3J0IGdldE5vZGVUeXBlKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0Tm9kZVR5cGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0UGFyZW50Tm9kZSgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldFBhcmVudE5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IGdldENoaWxkTm9kZXMoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRDaGlsZE5vZGVzIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldEZpcnN0Q2hpbGQoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRGaXJzdENoaWxkIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldExhc3RDaGlsZCgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldExhc3RDaGlsZCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXROZXh0U2libGluZygpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldE5leHRTaWJsaW5nIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZUxpc3QKLSAgICoKLSAgICogQHJldHVybiAwCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldExlbmd0aCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIDA7Ci0gIH0gIC8vIGdldExlbmd0aCgpOmludAotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZUxpc3QKLSAgICoKLSAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIGEgY2hpbGQgb2YgdGhpcyBub2RlIGluIGl0cyBsaXN0IG9mIGNoaWxkcmVuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgaXRlbShpbnQgaW5kZXgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vIml0ZW0gbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9ICAvLyBpdGVtKGludCk6Tm9kZQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBnZXRPd25lckRvY3VtZW50KCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0T3duZXJEb2N1bWVudCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRUYWdOYW1lIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0Tm9kZU5hbWUoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXROb2RlTmFtZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKiogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUgKi8KLSAgcHVibGljIHZvaWQgbm9ybWFsaXplKCkKLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vIm5vcm1hbGl6ZSBub3Qgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIGVsZW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTm9kZUxpc3QgZ2V0RWxlbWVudHNCeVRhZ05hbWUoU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEVsZW1lbnRzQnlUYWdOYW1lIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKgotICAgKiBAcGFyYW0gb2xkQXR0ciBBdHRyaWJ1dGUgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgbm9kZSdzIGxpc3Qgb2YgYXR0cmlidXRlcwotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBBdHRyIHJlbW92ZUF0dHJpYnV0ZU5vZGUoQXR0ciBvbGRBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInJlbW92ZUF0dHJpYnV0ZU5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyIEF0dHJpYnV0ZSBub2RlIHRvIGJlIGFkZGVkIHRvIHRoaXMgbm9kZSdzIGxpc3Qgb2YgYXR0cmlidXRlcwotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBBdHRyIHNldEF0dHJpYnV0ZU5vZGUoQXR0ciBuZXdBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldEF0dHJpYnV0ZU5vZGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgYW4gYXR0cmlidXRlCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZShTdHJpbmcgbmFtZSkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iaGFzQXR0cmlidXRlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHBhcmFtIHgKLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzQXR0cmlidXRlTlMoU3RyaW5nIG5hbWUsIFN0cmluZyB4KQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJoYXNBdHRyaWJ1dGVOUyBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBub2RlIG5hbWUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgQXR0ciBnZXRBdHRyaWJ1dGVOb2RlKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRBdHRyaWJ1dGVOb2RlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZSBBdHRyaWJ1dGUgbm9kZSBuYW1lIHRvIHJlbW92ZSBmcm9tIGxpc3Qgb2YgYXR0cmlidXRlcwotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJyZW1vdmVBdHRyaWJ1dGUgbm90IHN1cHBvcnRlZCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRWxlbWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIGF0dHJpYnV0ZSB0byBzZXQKLSAgICogQHBhcmFtIHZhbHVlIFZhbHVlIG9mIGF0dHJpYnV0ZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldEF0dHJpYnV0ZSBub3Qgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgYXR0cmlidXRlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRBdHRyaWJ1dGUgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIEludHJvZHVjZWQgaW4gRE9NIExldmVsIDIuCi0gICAqCi0gICAqIEByZXR1cm4gZmFsc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGhhc0F0dHJpYnV0ZXMoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJoYXNBdHRyaWJ1dGVzIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBsb2NhbE5hbWUgTG9jYWwgcGFydCBvZiBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZWxlbWVudAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEVsZW1lbnRzQnlUYWdOYW1lTlMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuZXdBdHRyIEF0dHJpYnV0ZSB0byBzZXQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQXR0ciBzZXRBdHRyaWJ1dGVOb2RlTlMoQXR0ciBuZXdBdHRyKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldEF0dHJpYnV0ZU5vZGVOUyBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2UgVVJJIG9mIGF0dHJpYnV0ZSBub2RlIHRvIGdldAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcXVhbGlmaWVkIG5hbWUgb2YgYXR0cmlidXRlIG5vZGUgdG8gZ2V0Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIEF0dHIgZ2V0QXR0cmlidXRlTm9kZU5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBsb2NhbE5hbWUpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldEF0dHJpYnV0ZU5vZGVOUyBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2UgVVJJIG9mIGF0dHJpYnV0ZSBub2RlIHRvIHJlbW92ZQotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcXVhbGlmaWVkIG5hbWUgb2YgYXR0cmlidXRlIG5vZGUgdG8gcmVtb3ZlCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgbG9jYWxOYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInJlbW92ZUF0dHJpYnV0ZU5TIG5vdCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkVsZW1lbnQKLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZVVSSSBOYW1lc3BhY2UgVVJJIG9mIGF0dHJpYnV0ZSBub2RlIHRvIHNldAotICAgKiBAcGFyYW0gbG9jYWxOYW1lIExvY2FsIHBhcnQgb2YgcXVhbGlmaWVkIG5hbWUgb2YgYXR0cmlidXRlIG5vZGUgdG8gc2V0Ci0gICAqIE5FRURTRE9DIEBwYXJhbSBxdWFsaWZpZWROYW1lCi0gICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSBvZiBhdHRyaWJ1dGUKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZU5TKAotICAgICAgICAgIFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lLCBTdHJpbmcgdmFsdWUpCi0gICAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJzZXRBdHRyaWJ1dGVOUyBub3Qgc3VwcG9ydGVkISIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5FbGVtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSSBvZiBhdHRyaWJ1dGUgbm9kZSB0byBnZXQKLSAgICogQHBhcmFtIGxvY2FsTmFtZSBMb2NhbCBwYXJ0IG9mIHF1YWxpZmllZCBuYW1lIG9mIGF0dHJpYnV0ZSBub2RlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0QXR0cmlidXRlTlMoU3RyaW5nIG5hbWVzcGFjZVVSSSwgU3RyaW5nIGxvY2FsTmFtZSkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0QXR0cmlidXRlTlMgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0UHJldmlvdXNTaWJsaW5nKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0UHJldmlvdXNTaWJsaW5nIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcGFyYW0gZGVlcCBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBjbG9uZSBkZWVwIChjbG9uZSBtZW1iZXIgdmFyaWFibGVzKQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBOb2RlIGNsb25lTm9kZShib29sZWFuIGRlZXApCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImNsb25lTm9kZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5vZGVWYWx1ZSgpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0Tm9kZVZhbHVlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcGFyYW0gbm9kZVZhbHVlIFZhbHVlIHRvIHNldCB0aGlzIG5vZGUgdG8KLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE5vZGVWYWx1ZShTdHJpbmcgbm9kZVZhbHVlKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJzZXROb2RlVmFsdWUgbm90IHN1cHBvcnRlZCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gdmFsdWUKLSAgICogQHJldHVybiB2YWx1ZSBOb2RlIHZhbHVlCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotCi0gIC8vIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUgKCkKLSAgLy8geyAgICAgIAotICAvLyAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAvLyJnZXRWYWx1ZSBub3Qgc3VwcG9ydGVkISIpOwotICAvLyAgcmV0dXJuIG51bGw7Ci0gIC8vIH0gCi0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSB0byBzZXQgdGhpcyBub2RlIHRvCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcgdmFsdWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldFZhbHVlIG5vdCBzdXBwb3J0ZWQhIik7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBhdHRyaWJ1dGUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhpcyBhdHRyaWJ1dGUuCi0gICAqLwotCi0gIC8vIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpCi0gIC8vIHsKLSAgLy8gIHJldHVybiB0aGlzLmdldE5vZGVOYW1lKCk7Ci0gIC8vIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRWxlbWVudCBnZXRPd25lckVsZW1lbnQoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRPd25lckVsZW1lbnQgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEByZXR1cm4gRmFsc2UKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFNwZWNpZmllZCgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vInNldFZhbHVlIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgTmFtZWROb2RlTWFwIGdldEF0dHJpYnV0ZXMoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJnZXRBdHRyaWJ1dGVzIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcGFyYW0gbmV3Q2hpbGQgTmV3IGNoaWxkIG5vZGUgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSByZWZDaGlsZCBJbnNlcnQgaW4gZnJvbnQgb2YgdGhpcyBjaGlsZAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlIGluc2VydEJlZm9yZShOb2RlIG5ld0NoaWxkLCBOb2RlIHJlZkNoaWxkKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImluc2VydEJlZm9yZSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHBhcmFtIG5ld0NoaWxkIFJlcGxhY2UgZXhpc3RpbmcgY2hpbGQgd2l0aCB0aGlzIG9uZQotICAgKiBAcGFyYW0gb2xkQ2hpbGQgRXhpc3RpbmcgY2hpbGQgdG8gYmUgcmVwbGFjZWQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZSByZXBsYWNlQ2hpbGQoTm9kZSBuZXdDaGlsZCwgTm9kZSBvbGRDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJyZXBsYWNlQ2hpbGQgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Ob2RlCi0gICAqCi0gICAqIEBwYXJhbSBvbGRDaGlsZCBDaGlsZCB0byBiZSByZW1vdmVkCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGUgcmVtb3ZlQ2hpbGQoTm9kZSBvbGRDaGlsZCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJyZXBsYWNlQ2hpbGQgbm90IHN1cHBvcnRlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIHdoZXRoZXIgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBpbXBsZW1lbnRzIGEgc3BlY2lmaWMgZmVhdHVyZSBhbmQKLSAgICogdGhhdCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSB0aGlzIG5vZGUuCi0gICAqIEBwYXJhbSBmZWF0dXJlVGhlIG5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gdGVzdC4gVGhpcyBpcyB0aGUgc2FtZSBuYW1lCi0gICAqICAgd2hpY2ggY2FuIGJlIHBhc3NlZCB0byB0aGUgbWV0aG9kIDxjb2RlPmhhc0ZlYXR1cmU8L2NvZGU+IG9uCi0gICAqICAgPGNvZGU+RE9NSW1wbGVtZW50YXRpb248L2NvZGU+LgotICAgKiBAcGFyYW0gdmVyc2lvblRoaXMgaXMgdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmZWF0dXJlIHRvIHRlc3QuIEluCi0gICAqICAgTGV2ZWwgMiwgdmVyc2lvbiAxLCB0aGlzIGlzIHRoZSBzdHJpbmcgIjIuMCIuIElmIHRoZSB2ZXJzaW9uIGlzIG5vdAotICAgKiAgIHNwZWNpZmllZCwgc3VwcG9ydGluZyBhbnkgdmVyc2lvbiBvZiB0aGUgZmVhdHVyZSB3aWxsIGNhdXNlIHRoZQotICAgKiAgIG1ldGhvZCB0byByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4uCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBmZWF0dXJlCi0gICAqIE5FRURTRE9DIEBwYXJhbSB2ZXJzaW9uCi0gICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT5mYWxzZTwvY29kZT4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAyCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1N1cHBvcnRlZChTdHJpbmcgZmVhdHVyZSwgU3RyaW5nIHZlcnNpb24pCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZVVSSSgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldE5hbWVzcGFjZVVSSSBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFByZWZpeCgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsgIC8vImdldFByZWZpeCBub3Qgc3VwcG9ydGVkISIpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLk5vZGUKLSAgICoKLSAgICogQHBhcmFtIHByZWZpeCBQcmVmaXggdG8gc2V0IGZvciB0aGlzIG5vZGUKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZWZpeChTdHJpbmcgcHJlZml4KSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7ICAvLyJzZXRQcmVmaXggbm90IHN1cHBvcnRlZCEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uTm9kZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOyAgLy8iZ2V0TG9jYWxOYW1lIG5vdCBzdXBwb3J0ZWQhIik7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRUeXBlIGdldERvY3R5cGUoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRE9NSW1wbGVtZW50YXRpb24gZ2V0SW1wbGVtZW50YXRpb24oKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRWxlbWVudCBnZXREb2N1bWVudEVsZW1lbnQoKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIHRhZ05hbWUgRWxlbWVudCB0YWcgbmFtZQotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFbGVtZW50IGNyZWF0ZUVsZW1lbnQoU3RyaW5nIHRhZ05hbWUpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIERvY3VtZW50RnJhZ21lbnQgY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gZGF0YSBEYXRhIGZvciB0ZXh0IG5vZGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgVGV4dCBjcmVhdGVUZXh0Tm9kZShTdHJpbmcgZGF0YSkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBkYXRhIERhdGEgZm9yIGNvbW1lbnQKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgQ29tbWVudCBjcmVhdGVDb21tZW50KFN0cmluZyBkYXRhKQotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLiBTZWUgb3JnLnczYy5kb20uRG9jdW1lbnQKLSAgICoKLSAgICogQHBhcmFtIGRhdGEgRGF0YSBmb3IgQ0RBVEEgc2VjdGlvbgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBDREFUQVNlY3Rpb24gY3JlYXRlQ0RBVEFTZWN0aW9uKFN0cmluZyBkYXRhKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gdGFyZ2V0IFRhcmdldCBmb3IgUHJvY2Vzc2luZyBpbnN0cnVjdGlvbgotICAgKiBAcGFyYW0gZGF0YSBEYXRhIGZvciBQcm9jZXNzaW5nIGluc3RydWN0aW9uCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFByb2Nlc3NpbmdJbnN0cnVjdGlvbiBjcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCi0gICAgICAgICAgU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEF0dHJpYnV0ZSBuYW1lCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEF0dHIgY3JlYXRlQXR0cmlidXRlKFN0cmluZyBuYW1lKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZSBFbnRpdHkgUmVmZXJlbmNlIG5hbWUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRW50aXR5UmVmZXJlbmNlIGNyZWF0ZUVudGl0eVJlZmVyZW5jZShTdHJpbmcgbmFtZSkKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gaW1wb3J0ZWROb2RlVGhlIG5vZGUgdG8gaW1wb3J0LgotICAgKiBAcGFyYW0gZGVlcElmIDxjb2RlPnRydWU8L2NvZGU+LCByZWN1cnNpdmVseSBpbXBvcnQgdGhlIHN1YnRyZWUgdW5kZXIKLSAgICogICB0aGUgc3BlY2lmaWVkIG5vZGU7IGlmIDxjb2RlPmZhbHNlPC9jb2RlPiwgaW1wb3J0IG9ubHkgdGhlIG5vZGUKLSAgICogICBpdHNlbGYsIGFzIGV4cGxhaW5lZCBhYm92ZS4gVGhpcyBoYXMgbm8gZWZmZWN0IG9uIDxjb2RlPkF0dHI8L2NvZGU+Ci0gICAqICAgLCA8Y29kZT5FbnRpdHlSZWZlcmVuY2U8L2NvZGU+LCBhbmQgPGNvZGU+Tm90YXRpb248L2NvZGU+IG5vZGVzLgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gaW1wb3J0ZWROb2RlCi0gICAqIE5FRURTRE9DIEBwYXJhbSBkZWVwCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGUgaW1wb3J0Tm9kZShOb2RlIGltcG9ydGVkTm9kZSwgYm9vbGVhbiBkZWVwKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gbmFtZXNwYWNlVVJJIE5hbWVzcGFjZSBVUkkgZm9yIHRoZSBlbGVtZW50Ci0gICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFF1YWxpZmllZCBuYW1lIG9mIHRoZSBlbGVtZW50Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIEVsZW1lbnQgY3JlYXRlRWxlbWVudE5TKFN0cmluZyBuYW1lc3BhY2VVUkksIFN0cmluZyBxdWFsaWZpZWROYW1lKQotICAgICAgICAgIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4gU2VlIG9yZy53M2MuZG9tLkRvY3VtZW50Ci0gICAqCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VVUkkgTmFtZXNwYWNlIFVSSSBvZiB0aGUgYXR0cmlidXRlCi0gICAqIEBwYXJhbSBxdWFsaWZpZWROYW1lIFF1YWxpZmllZCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQXR0ciBjcmVhdGVBdHRyaWJ1dGVOUyhTdHJpbmcgbmFtZXNwYWNlVVJJLCBTdHJpbmcgcXVhbGlmaWVkTmFtZSkKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuIFNlZSBvcmcudzNjLmRvbS5Eb2N1bWVudAotICAgKgotICAgKiBAcGFyYW0gZWxlbWVudElkIElEIG9mIHRoZSBlbGVtZW50IHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBFbGVtZW50IGdldEVsZW1lbnRCeUlkKFN0cmluZyBlbGVtZW50SWQpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBOb2RlIGRhdGEKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGRhdGEgZGF0YSB0byBzZXQgZm9yIHRoaXMgbm9kZQotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RGF0YShTdHJpbmcgZGF0YSkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBvZmZzZXQgU3RhcnQgb2Zmc2V0IG9mIHN1YnN0cmluZyB0byBleHRyYWN0LgotICAgKiBAcGFyYW0gY291bnQgVGhlIGxlbmd0aCBvZiB0aGUgc3Vic3RyaW5nIHRvIGV4dHJhY3QuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdWJzdHJpbmdEYXRhKGludCBvZmZzZXQsIGludCBjb3VudCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0KLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLgotICAgKgotICAgKiBAcGFyYW0gYXJnIFN0cmluZyBkYXRhIHRvIGFwcGVuZAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kRGF0YShTdHJpbmcgYXJnKSB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4KLSAgICoKLSAgICogQHBhcmFtIG9mZnNldCBTdGFydCBvZmZzZXQgb2Ygc3Vic3RyaW5nIHRvIGluc2VydC4KLSAgICogQHBhcmFtIGNvdW50IFRoZSBsZW5ndGggb2YgdGhlIHN1YnN0cmluZyB0byBpbnNlcnQuCi0gICAqIE5FRURTRE9DIEBwYXJhbSBhcmcKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydERhdGEoaW50IG9mZnNldCwgU3RyaW5nIGFyZykgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFVuaW1wbGVtZW50ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBvZmZzZXQgU3RhcnQgb2Zmc2V0IG9mIHN1YnN0cmluZyB0byBkZWxldGUuCi0gICAqIEBwYXJhbSBjb3VudCBUaGUgbGVuZ3RoIG9mIHRoZSBzdWJzdHJpbmcgdG8gZGVsZXRlLgotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGVsZXRlRGF0YShpbnQgb2Zmc2V0LCBpbnQgY291bnQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiBVbmltcGxlbWVudGVkLgotICAgKgotICAgKiBAcGFyYW0gb2Zmc2V0IFN0YXJ0IG9mZnNldCBvZiBzdWJzdHJpbmcgdG8gcmVwbGFjZS4KLSAgICogQHBhcmFtIGNvdW50IFRoZSBsZW5ndGggb2YgdGhlIHN1YnN0cmluZyB0byByZXBsYWNlLgotICAgKiBAcGFyYW0gYXJnIHN1YnN0cmluZyB0byByZXBsYWNlIHdpdGgKLSAgICoKLSAgICogQHRocm93cyBET01FeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlcGxhY2VEYXRhKGludCBvZmZzZXQsIGludCBjb3VudCwgU3RyaW5nIGFyZykKLSAgICAgICAgICB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0gIH0KLQotICAvKioKLSAgICogVW5pbXBsZW1lbnRlZC4KLSAgICoKLSAgICogQHBhcmFtIG9mZnNldCBPZmZzZXQgaW50byB0ZXh0IHRvIHNwbGl0Ci0gICAqCi0gICAqIEByZXR1cm4gbnVsbCwgdW5pbXBsZW1lbnRlZAotICAgKgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFRleHQgc3BsaXRUZXh0KGludCBvZmZzZXQpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGFkb3B0Tm9kZSAKLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHNvdXJjZQotICAgKgotICAgKiBORUVEU0RPQyAoYWRvcHROb2RlKSBAcmV0dXJuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZSBhZG9wdE5vZGUoTm9kZSBzb3VyY2UpIHRocm93cyBET01FeGNlcHRpb24KLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSBlbmNvZGluZwotICAgKiBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPHA+RVhQRVJJTUVOVEFMISBCYXNlZCBvbiB0aGUgPGEKLSAgICogaHJlZj0naHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9XRC1ET00tTGV2ZWwtMy1Db3JlLTIwMDEwNjA1Jz5Eb2N1bWVudAotICAgKiBPYmplY3QgTW9kZWwgKERPTSkgTGV2ZWwgMyBDb3JlIFdvcmtpbmcgRHJhZnQgb2YgNSBKdW5lIDIwMDEuPC9hPi4KLSAgICogPHA+Ci0gICAqIEFuIGF0dHJpYnV0ZSBzcGVjaWZ5aW5nLCBhcyBwYXJ0IG9mIHRoZSBYTUwgZGVjbGFyYXRpb24sIHRoZSBlbmNvZGluZwotICAgKiBvZiB0aGlzIGRvY3VtZW50LiBUaGlzIGlzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdW5zcGVjaWZpZWQuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZW5jb2RpbmcKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBlbmNvZGluZykKLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgd2hldGhlciB0aGlzCi0gICAqIGRvY3VtZW50IGlzIHN0YW5kYWxvbmUuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTdGFuZGFsb25lKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB3aGV0aGVyIHRoaXMKLSAgICogZG9jdW1lbnQgaXMgc3RhbmRhbG9uZS4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBzdGFuZGFsb25lCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdGFuZGFsb25lKGJvb2xlYW4gc3RhbmRhbG9uZSkKLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcgd2hldGhlciBlcnJvcnMgY2hlY2tpbmcgaXMgZW5mb3JjZWQgb3Igbm90LgotICAgKiBXaGVuIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4sIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIG5vdAotICAgKiB0ZXN0IGV2ZXJ5IHBvc3NpYmxlIGVycm9yIGNhc2Ugbm9ybWFsbHkgZGVmaW5lZCBvbiBET00gb3BlcmF0aW9ucywKLSAgICogYW5kIG5vdCByYWlzZSBhbnkgPGNvZGU+RE9NRXhjZXB0aW9uPC9jb2RlPi4gSW4gY2FzZSBvZiBlcnJvciwgdGhlCi0gICAqIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gVGhpcyBhdHRyaWJ1dGUgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gYnkKLSAgICogZGVmYXVsdHMuCi0gICAqIEBzaW5jZSBET00gTGV2ZWwgMwotICAgKgotICAgKiBORUVEU0RPQyAoJG9iamVjdE5hbWUkKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRTdHJpY3RFcnJvckNoZWNraW5nKCkKLSAgewotCi0gICAgZXJyb3IoWFNMVEVycm9yUmVzb3VyY2VzLkVSX0ZVTkNUSU9OX05PVF9TVVBQT1JURUQpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB3aGV0aGVyIGVycm9ycyBjaGVja2luZyBpcyBlbmZvcmNlZCBvciBub3QuCi0gICAqIFdoZW4gc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiwgdGhlIGltcGxlbWVudGF0aW9uIGlzIGZyZWUgdG8gbm90Ci0gICAqIHRlc3QgZXZlcnkgcG9zc2libGUgZXJyb3IgY2FzZSBub3JtYWxseSBkZWZpbmVkIG9uIERPTSBvcGVyYXRpb25zLAotICAgKiBhbmQgbm90IHJhaXNlIGFueSA8Y29kZT5ET01FeGNlcHRpb248L2NvZGU+LiBJbiBjYXNlIG9mIGVycm9yLCB0aGUKLSAgICogYmVoYXZpb3IgaXMgdW5kZWZpbmVkLiBUaGlzIGF0dHJpYnV0ZSBpcyA8Y29kZT50cnVlPC9jb2RlPiBieQotICAgKiBkZWZhdWx0cy4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBzdHJpY3RFcnJvckNoZWNraW5nCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTdHJpY3RFcnJvckNoZWNraW5nKGJvb2xlYW4gc3RyaWN0RXJyb3JDaGVja2luZykKLSAgewotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5FWFBFUklNRU5UQUwhIEJhc2VkIG9uIHRoZSA8YQotICAgKiBocmVmPSdodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1dELURPTS1MZXZlbC0zLUNvcmUtMjAwMTA2MDUnPkRvY3VtZW50Ci0gICAqIE9iamVjdCBNb2RlbCAoRE9NKSBMZXZlbCAzIENvcmUgV29ya2luZyBEcmFmdCBvZiA1IEp1bmUgMjAwMS48L2E+LgotICAgKiA8cD4KLSAgICogQW4gYXR0cmlidXRlIHNwZWNpZnlpbmcsIGFzIHBhcnQgb2YgdGhlIFhNTCBkZWNsYXJhdGlvbiwgdGhlIHZlcnNpb24KLSAgICogbnVtYmVyIG9mIHRoaXMgZG9jdW1lbnQuIFRoaXMgaXMgPGNvZGU+bnVsbDwvY29kZT4gd2hlbiB1bnNwZWNpZmllZC4KLSAgICogQHNpbmNlIERPTSBMZXZlbCAzCi0gICAqCi0gICAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpCi0gIHsKLQotICAgIGVycm9yKFhTTFRFcnJvclJlc291cmNlcy5FUl9GVU5DVElPTl9OT1RfU1VQUE9SVEVEKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIDxwPkVYUEVSSU1FTlRBTCEgQmFzZWQgb24gdGhlIDxhCi0gICAqIGhyZWY9J2h0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvV0QtRE9NLUxldmVsLTMtQ29yZS0yMDAxMDYwNSc+RG9jdW1lbnQKLSAgICogT2JqZWN0IE1vZGVsIChET00pIExldmVsIDMgQ29yZSBXb3JraW5nIERyYWZ0IG9mIDUgSnVuZSAyMDAxLjwvYT4uCi0gICAqIDxwPgotICAgKiBBbiBhdHRyaWJ1dGUgc3BlY2lmeWluZywgYXMgcGFydCBvZiB0aGUgWE1MIGRlY2xhcmF0aW9uLCB0aGUgdmVyc2lvbgotICAgKiBudW1iZXIgb2YgdGhpcyBkb2N1bWVudC4gVGhpcyBpcyA8Y29kZT5udWxsPC9jb2RlPiB3aGVuIHVuc3BlY2lmaWVkLgotICAgKiBAc2luY2UgRE9NIExldmVsIDMKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHZlcnNpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFZlcnNpb24oU3RyaW5nIHZlcnNpb24pCi0gIHsKLSAgICBlcnJvcihYU0xURXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fTk9UX1NVUFBPUlRFRCk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9XcmFwcGVkUnVudGltZUV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1dyYXBwZWRSdW50aW1lRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNkMDU3YTUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1dyYXBwZWRSdW50aW1lRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBmb3IgdGhyb3dpbmcgaW1wb3J0YW50IGNoZWNrZWQgZXhjZXB0aW9ucwotICogb3ZlciBub24tY2hlY2tlZCBtZXRob2RzLiAgSXQgc2hvdWxkIGJlIHVzZWQgd2l0aCBjYXJlLAotICogYW5kIGluIGxpbWl0ZWQgY2lyY3Vtc3RhbmNlcy4KLSAqLwotcHVibGljIGNsYXNzIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbgotewotCi0gIC8qKiBQcmltYXJ5IGNoZWNrZWQgZXhjZXB0aW9uLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIEV4Y2VwdGlvbiBtX2V4Y2VwdGlvbjsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24gZnJvbSBhCi0gICAqIGNoZWNrZWQgZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gZSBQcmltYXJ5IGNoZWNrZWQgZXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oRXhjZXB0aW9uIGUpCi0gIHsKLQotICAgIHN1cGVyKGUuZ2V0TWVzc2FnZSgpKTsKLQotICAgIG1fZXhjZXB0aW9uID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbXNnIEV4Y2VwdGlvbiBpbmZvcm1hdGlvbi4KLSAgICogQHBhcmFtIGUgUHJpbWFyeSBjaGVja2VkIGV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKFN0cmluZyBtc2csIEV4Y2VwdGlvbiBlKQotICB7Ci0KLSAgICBzdXBlcihtc2cpOwotCi0gICAgbV9leGNlcHRpb24gPSBlOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBjaGVja2VkIGV4Y2VwdGlvbiB0aGF0IHRoaXMgcnVudGltZSBleGNlcHRpb24gd3JhcHMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByaW1hcnkgY2hlY2tlZCBleGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBFeGNlcHRpb24gZ2V0RXhjZXB0aW9uKCkKLSAgewotICAgIHJldHVybiBtX2V4Y2VwdGlvbjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1dyb25nUGFyc2VyRXhjZXB0aW9uLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvV3JvbmdQYXJzZXJFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMThjNzk2Ni4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvV3JvbmdQYXJzZXJFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBDZXJ0YWluIGZ1bmN0aW9ucyBtYXkgdGhyb3cgdGhpcyBlcnJvciBpZiB0aGV5IGFyZSBwYWlyZWQgd2l0aAotICogdGhlIGluY29ycmVjdCBwYXJzZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBXcm9uZ1BhcnNlckV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgV3JvbmdQYXJzZXJFeGNlcHRpb24gb2JqZWN0LgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZSB0aGF0IHNob3VsZCBiZSByZXBvcnRlZCB0byB0aGUgdXNlci4KLSAgICovCi0gIHB1YmxpYyBXcm9uZ1BhcnNlckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkKLSAgewotICAgIHN1cGVyKG1lc3NhZ2UpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvWE1MQ2hhcmFjdGVyUmVjb2duaXplci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1hNTENoYXJhY3RlclJlY29nbml6ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGFkZmE4Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvWE1MQ2hhcmFjdGVyUmVjb2duaXplci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgdXNlZCB0byB2ZXJpZnkgd2hldGhlciB0aGUgc3BlY2lmaWVkIDx2YXI+Y2g8L3Zhcj4gCi0gKiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uIG9mIHdoaXRlc3BhY2UuIAotICovCi1wdWJsaWMgY2xhc3MgWE1MQ2hhcmFjdGVyUmVjb2duaXplcgotewotCi0gIC8qKgotICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCA8dmFyPmNoPC92YXI+IGNvbmZvcm1zIHRvIHRoZSBYTUwgMS4wIGRlZmluaXRpb24KLSAgICogb2Ygd2hpdGVzcGFjZS4gIFJlZmVyIHRvIDxBIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTgvUkVDLXhtbC0xOTk4MDIxMCNOVC1TIj4KLSAgICogdGhlIGRlZmluaXRpb24gb2YgPENPREU+UzwvQ09ERT48L0E+IGZvciBkZXRhaWxzLgotICAgKiBAcGFyYW0gY2ggQ2hhcmFjdGVyIHRvIGNoZWNrIGFzIFhNTCB3aGl0ZXNwYWNlLgotICAgKiBAcmV0dXJuID10cnVlIGlmIDx2YXI+Y2g8L3Zhcj4gaXMgWE1MIHdoaXRlc3BhY2U7IG90aGVyd2lzZSA9ZmFsc2UuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKGNoYXIgY2gpCi0gIHsKLSAgICByZXR1cm4gKGNoID09IDB4MjApIHx8IChjaCA9PSAweDA5KSB8fCAoY2ggPT0gMHhEKSB8fCAoY2ggPT0gMHhBKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBzdHJpbmcgaXMgd2hpdGVzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIGNoIENoYXJhY3RlciBhcnJheSB0byBjaGVjayBhcyBYTUwgd2hpdGVzcGFjZS4KLSAgICogQHBhcmFtIHN0YXJ0IFN0YXJ0IGluZGV4IG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5Ci0gICAqIEBwYXJhbSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5IAotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGFycmF5IGFyZSAKLSAgICogWE1MIHdoaXRlc3BhY2U7IG90aGVyd2lzZSwgZmFsc2UuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNXaGl0ZVNwYWNlKGNoYXIgY2hbXSwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0KLSAgICBpbnQgZW5kID0gc3RhcnQgKyBsZW5ndGg7Ci0KLSAgICBmb3IgKGludCBzID0gc3RhcnQ7IHMgPCBlbmQ7IHMrKykKLSAgICB7Ci0gICAgICBpZiAoIWlzV2hpdGVTcGFjZShjaFtzXSkpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBzdHJpbmcgaXMgd2hpdGVzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIGJ1ZiBTdHJpbmdCdWZmZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBjaGFyYWN0ZXJzIGluIGJ1ZmZlciBhcmUgWE1MIHdoaXRlc3BhY2UsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzV2hpdGVTcGFjZShTdHJpbmdCdWZmZXIgYnVmKQotICB7Ci0KLSAgICBpbnQgbiA9IGJ1Zi5sZW5ndGgoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIGlmICghaXNXaGl0ZVNwYWNlKGJ1Zi5jaGFyQXQoaSkpKQotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBzdHJpbmcgaXMgd2hpdGVzcGFjZS4KLSAgICoKLSAgICogQHBhcmFtIGJ1ZiBTdHJpbmdCdWZmZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiBjaGFyYWN0ZXJzIGluIGJ1ZmZlciBhcmUgWE1MIHdoaXRlc3BhY2UsIGZhbHNlIG90aGVyd2lzZQotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzV2hpdGVTcGFjZShTdHJpbmcgcykKLSAgewotCi0gICAgaWYobnVsbCAhPSBzKQotICAgIHsKLSAgICAgIGludCBuID0gcy5sZW5ndGgoKTsKLSAgCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYgKCFpc1doaXRlU3BhY2Uocy5jaGFyQXQoaSkpKQotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvWE1MU3RyaW5nLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvWE1MU3RyaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU5MWJhOTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1hNTFN0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzExICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIG1lYW50IHRvIGJlIGFuIGludGVyZmFjZSB0byBjaGFyYWN0ZXIgc3RyaW5ncywgd2hldGhlciB0aGV5Ci0gKiBiZSBqYXZhIFN0cmluZ3Mgb3IgPGNvZGU+b3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjwvY29kZT5zLCBvcgotICogb3RoZXIgY2hhcmFjdGVyIGRhdGEuICBCeSB1c2luZyBYTUxTdHJpbmcsIGNoYXJhY3RlciBjb3BpZXMgY2FuIGJlIHJlZHVjZWQKLSAqIGluIHRoZSBYTUwgcGlwZWxpbmUuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWE1MU3RyaW5nCi17Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY29tbWVudCBtZXRob2Qgb24gdGhlIHBhc3NlZCBMZXhpY2FsSGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGxoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaEFzQ29tbWVudChvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgbGgpCi0gICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbjsKLSAgICAKLSAgLyoqCi0gICAqIENvbmRpdGlvbmFsbHkgdHJpbSBhbGwgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBpbiB0aGUgc3BlY2lmaWVkIFN0cmluZy4KLSAgICogQWxsIHN0cmluZ3Mgb2Ygd2hpdGUgc3BhY2UgYXJlCi0gICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIHNwYWNlIGNoYXJhY3RlciAoI3gyMCksIGV4Y2VwdCBzcGFjZXMgYWZ0ZXIgcHVuY3R1YXRpb24gd2hpY2gKLSAgICogcmVjZWl2ZSBkb3VibGUgc3BhY2VzIGlmIGRvdWJsZVB1bmN0dWF0aW9uU3BhY2VzIGlzIHRydWUuCi0gICAqIFRoaXMgZnVuY3Rpb24gbWF5IGJlIHVzZWZ1bCB0byBhIGZvcm1hdHRlciwgYnV0IHRvIGdldCBmaXJzdCBjbGFzcwotICAgKiByZXN1bHRzLCB0aGUgZm9ybWF0dGVyIHNob3VsZCBwcm9iYWJseSBkbyBpdCdzIG93biB3aGl0ZSBzcGFjZSBoYW5kbGluZwotICAgKiBiYXNlZCBvbiB0aGUgc2VtYW50aWNzIG9mIHRoZSBmb3JtYXR0aW5nIG9iamVjdC4KLSAgICogCi0gICAqIEBwYXJhbSAgIHRyaW1IZWFkICAgIFRyaW0gbGVhZGluZyB3aGl0ZXNwYWNlPwotICAgKiBAcGFyYW0gICB0cmltVGFpbCAgICBUcmltIHRyYWlsaW5nIHdoaXRlc3BhY2U/Ci0gICAqIEBwYXJhbSAgIGRvdWJsZVB1bmN0dWF0aW9uU3BhY2VzICAgIFVzZSBkb3VibGUgc3BhY2VzIGZvciBwdW5jdHVhdGlvbj8KLSAgICogQHJldHVybiAgICAgICAgICAgICAgVGhlIHRyaW1tZWQgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBmaXhXaGl0ZVNwYWNlKGJvb2xlYW4gdHJpbUhlYWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHRyaW1UYWlsLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb3VibGVQdW5jdHVhdGlvblNwYWNlcyk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIGxlbmd0aCBvZiB0aGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGVuZ3RoKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBBbiBpbmRleCByYW5nZXMKLSAgICogZnJvbSA8Y29kZT4wPC9jb2RlPiB0byA8Y29kZT5sZW5ndGgoKSAtIDE8L2NvZGU+LiBUaGUgZmlyc3QgY2hhcmFjdGVyCi0gICAqIG9mIHRoZSBzZXF1ZW5jZSBpcyBhdCBpbmRleCA8Y29kZT4wPC9jb2RlPiwgdGhlIG5leHQgYXQgaW5kZXgKLSAgICogPGNvZGU+MTwvY29kZT4sIGFuZCBzbyBvbiwgYXMgZm9yIGFycmF5IGluZGV4aW5nLgotICAgKgotICAgKiBAcGFyYW0gICAgICBpbmRleCAgIHRoZSBpbmRleCBvZiB0aGUgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICAgICB0aGUgY2hhcmFjdGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyBzdHJpbmcuCi0gICAqICAgICAgICAgICAgIFRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgYXQgaW5kZXggPGNvZGU+MDwvY29kZT4uCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmIHRoZSA8Y29kZT5pbmRleDwvY29kZT4KLSAgICogICAgICAgICAgICAgYXJndW1lbnQgaXMgbmVnYXRpdmUgb3Igbm90IGxlc3MgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgICAgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGNoYXIgY2hhckF0KGludCBpbmRleCk7Ci0KLSAgLyoqCi0gICAqIENvcGllcyBjaGFyYWN0ZXJzIGZyb20gdGhpcyBzdHJpbmcgaW50byB0aGUgZGVzdGluYXRpb24gY2hhcmFjdGVyCi0gICAqIGFycmF5LgotICAgKgotICAgKiBAcGFyYW0gICAgICBzcmNCZWdpbiAgIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIHNyY0VuZCAgICAgaW5kZXggYWZ0ZXIgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICB0byBjb3B5LgotICAgKiBAcGFyYW0gICAgICBkc3QgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KLSAgICogQHBhcmFtICAgICAgZHN0QmVnaW4gICB0aGUgc3RhcnQgb2Zmc2V0IGluIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KLSAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIElmIGFueSBvZiB0aGUgZm9sbG93aW5nCi0gICAqICAgICAgICAgICAgaXMgdHJ1ZToKLSAgICogICAgICAgICAgICA8dWw+PGxpPjxjb2RlPnNyY0JlZ2luPC9jb2RlPiBpcyBuZWdhdGl2ZS4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiA8Y29kZT5zcmNFbmQ8L2NvZGU+Ci0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPnNyY0VuZDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICAgICAgICBzdHJpbmcKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPmRzdEJlZ2luKyhzcmNFbmQtc3JjQmVnaW4pPC9jb2RlPiBpcyBsYXJnZXIgdGhhbgotICAgKiAgICAgICAgICAgICAgICA8Y29kZT5kc3QubGVuZ3RoPC9jb2RlPjwvdWw+Ci0gICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+ZHN0PC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgZ2V0Q2hhcnMoaW50IHNyY0JlZ2luLCBpbnQgc3JjRW5kLCBjaGFyIGRzdFtdLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZHN0QmVnaW4pOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgc3RyaW5nIHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFuT2JqZWN0ICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICAgICAgICAgICAgIGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPmFyZSBlcXVhbDsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNjb21wYXJlVG8oamF2YS5sYW5nLlN0cmluZykKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNlcXVhbHNJZ25vcmVDYXNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBlcXVhbHMoWE1MU3RyaW5nIGFuT2JqZWN0KTsKLQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICBhbk9iamVjdCAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZXF1YWxzKE9iamVjdCBhbk9iamVjdCk7Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBhbm90aGVyIDxjb2RlPlN0cmluZzwvY29kZT4sCi0gICAqIGlnbm9yaW5nIGNhc2UgY29uc2lkZXJhdGlvbnMuICBUd28gc3RyaW5ncyBhcmUgY29uc2lkZXJlZCBlcXVhbAotICAgKiBpZ25vcmluZyBjYXNlIGlmIHRoZXkgYXJlIG9mIHRoZSBzYW1lIGxlbmd0aCwgYW5kIGNvcnJlc3BvbmRpbmcKLSAgICogY2hhcmFjdGVycyBpbiB0aGUgdHdvIHN0cmluZ3MgYXJlIGVxdWFsIGlnbm9yaW5nIGNhc2UuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFub3RoZXJTdHJpbmcgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBjb21wYXJlIHRoaXMKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gYWdhaW5zdC4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGFyZ3VtZW50IGlzIG5vdCA8Y29kZT5udWxsPC9jb2RlPgotICAgKiAgICAgICAgICBhbmQgdGhlIDxjb2RlPlN0cmluZzwvY29kZT5zIGFyZSBlcXVhbCwKLSAgICogICAgICAgICAgaWdub3JpbmcgY2FzZTsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgI2VxdWFscyhPYmplY3QpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSBqYXZhLmxhbmcuQ2hhcmFjdGVyI3RvVXBwZXJDYXNlKGNoYXIpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBlcXVhbHNJZ25vcmVDYXNlKFN0cmluZyBhbm90aGVyU3RyaW5nKTsKLQotICAvKioKLSAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MgbGV4aWNvZ3JhcGhpY2FsbHkuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFub3RoZXJTdHJpbmcgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBiZSBjb21wYXJlZC4KLSAgICogQHJldHVybiAgdGhlIHZhbHVlIDxjb2RlPjA8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBzdHJpbmcgaXMgZXF1YWwgdG8KLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IGEgdmFsdWUgbGVzcyB0aGFuIDxjb2RlPjA8L2NvZGU+IGlmIHRoaXMgc3RyaW5nCi0gICAqICAgICAgICAgIGlzIGxleGljb2dyYXBoaWNhbGx5IGxlc3MgdGhhbiB0aGUgc3RyaW5nIGFyZ3VtZW50OyBhbmQgYQotICAgKiAgICAgICAgICB2YWx1ZSBncmVhdGVyIHRoYW4gPGNvZGU+MDwvY29kZT4gaWYgdGhpcyBzdHJpbmcgaXMKLSAgICogICAgICAgICAgbGV4aWNvZ3JhcGhpY2FsbHkgZ3JlYXRlciB0aGFuIHRoZSBzdHJpbmcgYXJndW1lbnQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmFub3RoZXJTdHJpbmc8L2NvZGU+Ci0gICAqICAgICAgICAgIGlzIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBjb21wYXJlVG8oWE1MU3RyaW5nIGFub3RoZXJTdHJpbmcpOwotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0d28gc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseSwgaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4KLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBpbnRlZ2VyIHdob3NlIHNpZ24gaXMgdGhhdCBvZgotICAgKiA8Y29kZT50aGlzLnRvVXBwZXJDYXNlKCkudG9Mb3dlckNhc2UoKS5jb21wYXJlVG8oCi0gICAqIHN0ci50b1VwcGVyQ2FzZSgpLnRvTG93ZXJDYXNlKCkpPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIDxlbT5ub3Q8L2VtPiB0YWtlIGxvY2FsZSBpbnRvIGFjY291bnQsCi0gICAqIGFuZCB3aWxsIHJlc3VsdCBpbiBhbiB1bnNhdGlzZmFjdG9yeSBvcmRlcmluZyBmb3IgY2VydGFpbiBsb2NhbGVzLgotICAgKiBUaGUgamF2YS50ZXh0IHBhY2thZ2UgcHJvdmlkZXMgPGVtPmNvbGxhdG9yczwvZW0+IHRvIGFsbG93Ci0gICAqIGxvY2FsZS1zZW5zaXRpdmUgb3JkZXJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKiBAcmV0dXJuICBhIG5lZ2F0aXZlIGludGVnZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBhcyB0aGUKLSAgICogICAgICAgICAgdGhlIHNwZWNpZmllZCBTdHJpbmcgaXMgZ3JlYXRlciB0aGFuLCBlcXVhbCB0bywgb3IgbGVzcwotICAgKiAgICAgICAgICB0aGFuIHRoaXMgU3RyaW5nLCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBAc2VlICAgICBqYXZhLnRleHQuQ29sbGF0b3IjY29tcGFyZShTdHJpbmcsIFN0cmluZykKLSAgICogQHNpbmNlICAgMS4yCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGNvbXBhcmVUb0lnbm9yZUNhc2UoWE1MU3RyaW5nIHN0cik7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4IGJlZ2lubmluZwotICAgKiBhIHNwZWNpZmllZCBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtICAgcHJlZml4ICAgIHRoZSBwcmVmaXguCi0gICAqIEBwYXJhbSAgIHRvZmZzZXQgICB3aGVyZSB0byBiZWdpbiBsb29raW5nIGluIHRoZSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBvYmplY3Qgc3RhcnRpbmcKLSAgICogICAgICAgICAgYXQgaW5kZXggPGNvZGU+dG9mZnNldDwvY29kZT47IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIFRoZSByZXN1bHQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIDxjb2RlPnRvZmZzZXQ8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3Q7IG90aGVyd2lzZSB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lCi0gICAqICAgICAgICAgIGFzIHRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24KLSAgICogICAgICAgICAgPHByZT4KLSAgICogICAgICAgICAgdGhpcy5zdWJTdHJpbmcodG9mZnNldCkuc3RhcnRzV2l0aChwcmVmaXgpCi0gICAqICAgICAgICAgIDwvcHJlPgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc3RhcnRzV2l0aChTdHJpbmcgcHJlZml4LCBpbnQgdG9mZnNldCk7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4IGJlZ2lubmluZwotICAgKiBhIHNwZWNpZmllZCBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtICAgcHJlZml4ICAgIHRoZSBwcmVmaXguCi0gICAqIEBwYXJhbSAgIHRvZmZzZXQgICB3aGVyZSB0byBiZWdpbiBsb29raW5nIGluIHRoZSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBvYmplY3Qgc3RhcnRpbmcKLSAgICogICAgICAgICAgYXQgaW5kZXggPGNvZGU+dG9mZnNldDwvY29kZT47IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIFRoZSByZXN1bHQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIDxjb2RlPnRvZmZzZXQ8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3Q7IG90aGVyd2lzZSB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lCi0gICAqICAgICAgICAgIGFzIHRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24KLSAgICogICAgICAgICAgPHByZT4KLSAgICogICAgICAgICAgdGhpcy5zdWJTdHJpbmcodG9mZnNldCkuc3RhcnRzV2l0aChwcmVmaXgpCi0gICAqICAgICAgICAgIDwvcHJlPgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc3RhcnRzV2l0aChYTUxTdHJpbmcgcHJlZml4LCBpbnQgdG9mZnNldCk7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIEBzaW5jZSAgIEpESzEuIDAKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHN0YXJ0c1dpdGgoU3RyaW5nIHByZWZpeCk7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIEBzaW5jZSAgIEpESzEuIDAKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCk7Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIGVuZHMgd2l0aCB0aGUgc3BlY2lmaWVkIHN1ZmZpeC4KLSAgICoKLSAgICogQHBhcmFtICAgc3VmZml4ICAgdGhlIHN1ZmZpeC4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYSBzdWZmaXggb2YgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieQotICAgKiAgICAgICAgICB0aGlzIG9iamVjdDsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4gTm90ZSB0aGF0IHRoZQotICAgKiAgICAgICAgICByZXN1bHQgd2lsbCBiZSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgaXMgdGhlCi0gICAqICAgICAgICAgIGVtcHR5IHN0cmluZyBvciBpcyBlcXVhbCB0byB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0Ci0gICAqICAgICAgICAgIGFzIGRldGVybWluZWQgYnkgdGhlIHtAbGluayAjZXF1YWxzKE9iamVjdCl9IG1ldGhvZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3VmZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGVuZHNXaXRoKFN0cmluZyBzdWZmaXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgc3RyaW5nLiBUaGUgaGFzaGNvZGUgZm9yIGEKLSAgICogPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgaXMgY29tcHV0ZWQgYXMKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogc1swXSozMV4obi0xKSArIHNbMV0qMzFeKG4tMikgKyAuLi4gKyBzW24tMV0KLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiB1c2luZyA8Y29kZT5pbnQ8L2NvZGU+IGFyaXRobWV0aWMsIHdoZXJlIDxjb2RlPnNbaV08L2NvZGU+IGlzIHRoZQotICAgKiA8aT5pPC9pPnRoIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nLCA8Y29kZT5uPC9jb2RlPiBpcyB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoZSBzdHJpbmcsIGFuZCA8Y29kZT5ePC9jb2RlPiBpbmRpY2F0ZXMgZXhwb25lbnRpYXRpb24uCi0gICAqIChUaGUgaGFzaCB2YWx1ZSBvZiB0aGUgZW1wdHkgc3RyaW5nIGlzIHplcm8uKQotICAgKgotICAgKiBAcmV0dXJuICBhIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGhhc2hDb2RlKCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlci4gSWYgYSBjaGFyYWN0ZXIgd2l0aCB2YWx1ZSA8Y29kZT5jaDwvY29kZT4gb2NjdXJzCi0gICAqIGluIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+Ci0gICAqIG9iamVjdCwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHN1Y2ggb2NjdXJyZW5jZSBpcyByZXR1cm5lZCAtLQotICAgKiB0aGF0IGlzLCB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLmNoYXJBdCg8aT5rPC9pPikgPT0gY2gKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4gSWYgbm8gc3VjaCBjaGFyYWN0ZXIgb2NjdXJzIGluIHRoaXMgc3RyaW5nLAotICAgKiB0aGVuIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICoKLSAgICogQHBhcmFtICAgY2ggICBhIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCwgb3IKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgZG9lcyBub3Qgb2NjdXIuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGluZGV4T2YoaW50IGNoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLCBzdGFydGluZyB0aGUgc2VhcmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIDxwPgotICAgKiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMgaW4gdGhlIGNoYXJhY3RlcgotICAgKiBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGF0IGFuIGluZGV4Ci0gICAqIG5vIHNtYWxsZXIgdGhhbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QKLSAgICogc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkLS10aGF0IGlzLCB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4KLSAgICogc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAodGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoKSAmJiAoPGk+azwvaT4gPj0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuIElmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZyBhdCBvciBhZnRlcgotICAgKiBwb3NpdGlvbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGlzIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZiBpdAotICAgKiBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIHplcm86IHRoaXMgZW50aXJlCi0gICAqIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZgotICAgKiB0aGlzIHN0cmluZzogPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgICAgICAgICBhIGNoYXJhY3Rlci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB0aGF0IGlzIGdyZWF0ZXIKLSAgICogICAgICAgICAgdGhhbiBvciBlcXVhbCB0byA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4KLSAgICogICAgICAgICAgaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgaW5kZXhPZihpbnQgY2gsIGludCBmcm9tSW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlci4gVGhhdCBpcywgdGhlIGluZGV4IHJldHVybmVkIGlzIHRoZSBsYXJnZXN0Ci0gICAqIHZhbHVlIDxpPms8L2k+IHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4KLSAgICogVGhlIFN0cmluZyBpcyBzZWFyY2hlZCBiYWNrd2FyZHMgc3RhcnRpbmcgYXQgdGhlIGxhc3QgY2hhcmFjdGVyLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgIGEgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY2hhcmFjdGVyIGluIHRoZQotICAgKiAgICAgICAgICBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QsIG9yCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBsYXN0SW5kZXhPZihpbnQgY2gpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlciwgc2VhcmNoaW5nIGJhY2t3YXJkIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXguIFRoYXQgaXMsIHRoZSBpbmRleCByZXR1cm5lZCBpcyB0aGUgbGFyZ2VzdCB2YWx1ZSA8aT5rPC9pPgotICAgKiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KGspID09IGNoKSAmJiAoayA8PSBmcm9tSW5kZXgpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4KLSAgICoKLSAgICogQHBhcmFtICAgY2ggICAgICAgICAgYSBjaGFyYWN0ZXIuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIFRoZXJlIGlzIG5vCi0gICAqICAgICAgICAgIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZiBpdCBpcwotICAgKiAgICAgICAgICBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZywgaXQgaGFzCi0gICAqICAgICAgICAgIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIGVxdWFsIHRvIG9uZSBsZXNzIHRoYW4gdGhlCi0gICAqICAgICAgICAgIGxlbmd0aCBvZiB0aGlzIHN0cmluZzogdGhpcyBlbnRpcmUgc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4KLSAgICogICAgICAgICAgSWYgaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSAtMToKLSAgICogICAgICAgICAgLTEgaXMgcmV0dXJuZWQuCi0gICAqIEByZXR1cm4gIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB0aGF0IGlzIGxlc3MKLSAgICogICAgICAgICAgdGhhbiBvciBlcXVhbCB0byA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4KLSAgICogICAgICAgICAgaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ciBiZWZvcmUgdGhhdCBwb2ludC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGFzdEluZGV4T2YoaW50IGNoLCBpbnQgZnJvbUluZGV4KTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgc3Vic3RyaW5nLiBUaGUgaW50ZWdlciByZXR1cm5lZCBpcyB0aGUgc21hbGxlc3QgdmFsdWUKLSAgICogPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCA8aT5rPC9pPikKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgYW55IHN0cmluZy4KLSAgICogQHJldHVybiAgaWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgYXMgYSBzdWJzdHJpbmcgd2l0aGluIHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBmaXJzdAotICAgKiAgICAgICAgICBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZDsgaWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMgYQotICAgKiAgICAgICAgICBzdWJzdHJpbmcsIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgaW5kZXhPZihTdHJpbmcgc3RyKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgc3Vic3RyaW5nLiBUaGUgaW50ZWdlciByZXR1cm5lZCBpcyB0aGUgc21hbGxlc3QgdmFsdWUKLSAgICogPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCA8aT5rPC9pPikKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgYW55IHN0cmluZy4KLSAgICogQHJldHVybiAgaWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgYXMgYSBzdWJzdHJpbmcgd2l0aGluIHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBmaXJzdAotICAgKiAgICAgICAgICBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZDsgaWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMgYQotICAgKiAgICAgICAgICBzdWJzdHJpbmcsIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBpbnQgaW5kZXhPZihYTUxTdHJpbmcgc3RyKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgc3Vic3RyaW5nLCBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBUaGUgaW50ZWdlcgotICAgKiByZXR1cm5lZCBpcyB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCA8aT5rPC9pPikgJiYgKDxpPms8L2k+ID49IGZyb21JbmRleCkKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGlzIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZgotICAgKiBpdCBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIHplcm86IHRoaXMgZW50aXJlCi0gICAqIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZgotICAgKiB0aGlzIHN0cmluZzogPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICAgICAgICB0aGUgc3Vic3RyaW5nIHRvIHNlYXJjaCBmb3IuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uCi0gICAqIEByZXR1cm4gIElmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIGFzIGEgc3Vic3RyaW5nIHdpdGhpbiB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdCBhdCBhIHN0YXJ0aW5nIGluZGV4IG5vIHNtYWxsZXIgdGhhbgotICAgKiAgICAgICAgICA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyCi0gICAqICAgICAgICAgIG9mIHRoZSBmaXJzdCBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZC4gSWYgaXQgZG9lcyBub3Qgb2NjdXIKLSAgICogICAgICAgICAgYXMgYSBzdWJzdHJpbmcgc3RhcnRpbmcgYXQgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiBvciBiZXlvbmQsCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBpbmRleE9mKFN0cmluZyBzdHIsIGludCBmcm9tSW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIHJpZ2h0bW9zdCBvY2N1cnJlbmNlCi0gICAqIG9mIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLiAgVGhlIHJpZ2h0bW9zdCBlbXB0eSBzdHJpbmcgIiIgaXMKLSAgICogY29uc2lkZXJlZCB0byBvY2N1ciBhdCB0aGUgaW5kZXggdmFsdWUgPGNvZGU+dGhpcy5sZW5ndGgoKTwvY29kZT4uCi0gICAqIFRoZSByZXR1cm5lZCBpbmRleCBpcyB0aGUgbGFyZ2VzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5zdGFydHNXaXRoKHN0ciwgaykKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICB0aGUgc3Vic3RyaW5nIHRvIHNlYXJjaCBmb3IuCi0gICAqIEByZXR1cm4gIGlmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIG9uZSBvciBtb3JlIHRpbWVzIGFzIGEgc3Vic3RyaW5nCi0gICAqICAgICAgICAgIHdpdGhpbiB0aGlzIG9iamVjdCwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgotICAgKiAgICAgICAgICB0aGUgbGFzdCBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZC4gSWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMKLSAgICogICAgICAgICAgYSBzdWJzdHJpbmcsIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdHIpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZgotICAgKiB0aGUgc3BlY2lmaWVkIHN1YnN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgICAgICAgdGhlIHN1YnN0cmluZyB0byBzZWFyY2ggZm9yLgotICAgKiBAcGFyYW0gICBmcm9tSW5kZXggICB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLiBUaGVyZSBpcyBubwotICAgKiAgICAgICAgICByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgZnJvbUluZGV4LiBJZiBpdCBpcyBncmVhdGVyIHRoYW4KLSAgICogICAgICAgICAgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZywgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdAotICAgKiAgICAgICAgICB3ZXJlIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmc6IHRoaXMgZW50aXJlIHN0cmluZwotICAgKiAgICAgICAgICBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIG5lZ2F0aXZlLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0Ci0gICAqICAgICAgICAgIGFzIGlmIGl0IHdlcmUgLTE6IC0xIGlzIHJldHVybmVkLgotICAgKiBAcmV0dXJuICBJZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBvbmUgb3IgbW9yZSB0aW1lcyBhcyBhIHN1YnN0cmluZwotICAgKiAgICAgICAgICB3aXRoaW4gdGhpcyBvYmplY3QgYXQgYSBzdGFydGluZyBpbmRleCBubyBncmVhdGVyIHRoYW4KLSAgICogICAgICAgICAgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiwgdGhlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZgotICAgKiAgICAgICAgICB0aGUgbGFzdCBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZC4gSWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMgYQotICAgKiAgICAgICAgICBzdWJzdHJpbmcgc3RhcnRpbmcgYXQgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiBvciBlYXJsaWVyLAotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzdHIsIGludCBmcm9tSW5kZXgpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB0aGF0IGlzIGEgc3Vic3RyaW5nIG9mIHRoaXMgc3RyaW5nLiBUaGUKLSAgICogc3Vic3RyaW5nIGJlZ2lucyB3aXRoIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBhbmQKLSAgICogZXh0ZW5kcyB0byB0aGUgZW5kIG9mIHRoaXMgc3RyaW5nLiA8cD4KLSAgICogRXhhbXBsZXM6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqICJ1bmhhcHB5Ii5zdWJzdHJpbmcoMikgcmV0dXJucyAiaGFwcHkiCi0gICAqICJIYXJiaXNvbiIuc3Vic3RyaW5nKDMpIHJldHVybnMgImJpc29uIgotICAgKiAiZW1wdGluZXNzIi5zdWJzdHJpbmcoOSkgcmV0dXJucyAiIiAoYW4gZW1wdHkgc3RyaW5nKQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqCi0gICAqIEBwYXJhbSAgICAgIGJlZ2luSW5kZXggICB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmUuCi0gICAqIEByZXR1cm4gICAgIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZgotICAgKiAgICAgICAgICAgICA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBpcyBuZWdhdGl2ZSBvciBsYXJnZXIgdGhhbiB0aGUKLSAgICogICAgICAgICAgICAgbGVuZ3RoIG9mIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCk7Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHRoYXQgaXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcuIFRoZQotICAgKiBzdWJzdHJpbmcgYmVnaW5zIGF0IHRoZSBzcGVjaWZpZWQgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gYW5kCi0gICAqIGV4dGVuZHMgdG8gdGhlIGNoYXJhY3RlciBhdCBpbmRleCA8Y29kZT5lbmRJbmRleCAtIDE8L2NvZGU+LgotICAgKiBUaHVzIHRoZSBsZW5ndGggb2YgdGhlIHN1YnN0cmluZyBpcyA8Y29kZT5lbmRJbmRleC1iZWdpbkluZGV4PC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtICAgICAgYmVnaW5JbmRleCAgIHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZS4KLSAgICogQHBhcmFtICAgICAgZW5kSW5kZXggICAgIHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZS4KLSAgICogQHJldHVybiAgICAgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmIHRoZQotICAgKiAgICAgICAgICAgICA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBpcyBuZWdhdGl2ZSwgb3IKLSAgICogICAgICAgICAgICAgPGNvZGU+ZW5kSW5kZXg8L2NvZGU+IGlzIGxhcmdlciB0aGFuIHRoZSBsZW5ndGggb2YKLSAgICogICAgICAgICAgICAgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCwgb3IKLSAgICogICAgICAgICAgICAgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gaXMgbGFyZ2VyIHRoYW4KLSAgICogICAgICAgICAgICAgPGNvZGU+ZW5kSW5kZXg8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyBzdWJzdHJpbmcoaW50IGJlZ2luSW5kZXgsIGludCBlbmRJbmRleCk7Ci0KLSAgLyoqCi0gICAqIENvbmNhdGVuYXRlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGUgZW5kIG9mIHRoaXMgc3RyaW5nLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0aGF0IGlzIGNvbmNhdGVuYXRlZCB0byB0aGUgZW5kCi0gICAqICAgICAgICAgICAgICAgIG9mIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPi4KLSAgICogQHJldHVybiAgYSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoaXMgb2JqZWN0J3MKLSAgICogICAgICAgICAgY2hhcmFjdGVycyBmb2xsb3dlZCBieSB0aGUgc3RyaW5nIGFyZ3VtZW50J3MgY2hhcmFjdGVycy4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgY29uY2F0KFN0cmluZyBzdHIpOwotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGxvd2VyCi0gICAqIGNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSBnaXZlbiA8Y29kZT5Mb2NhbGU8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gbG9jYWxlIHVzZSB0aGUgY2FzZSB0cmFuc2Zvcm1hdGlvbiBydWxlcyBmb3IgdGhpcyBsb2NhbGUKLSAgICogQHJldHVybiB0aGUgU3RyaW5nLCBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlLgotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuQ2hhcmFjdGVyI3RvTG93ZXJDYXNlKGNoYXIpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjdG9VcHBlckNhc2UoTG9jYWxlKQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyB0b0xvd2VyQ2FzZShMb2NhbGUgbG9jYWxlKTsKLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBsb3dlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZGVmYXVsdCBsb2NhbGUsIHdoaWNoIGlzIHJldHVybmVkCi0gICAqIGJ5IDxjb2RlPkxvY2FsZS5nZXREZWZhdWx0PC9jb2RlPi4KLSAgICogPHA+Ci0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBzdHJpbmcsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9Mb3dlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b0xvd2VyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIHRvTG93ZXJDYXNlKCk7Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gdXBwZXIKLSAgICogY2FzZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIGdpdmVuIGxvY2FsZS4KLSAgICogQHBhcmFtIGxvY2FsZSB1c2UgdGhlIGNhc2UgdHJhbnNmb3JtYXRpb24gcnVsZXMgZm9yIHRoaXMgbG9jYWxlCi0gICAqIEByZXR1cm4gdGhlIFN0cmluZywgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvTG93ZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgdG9VcHBlckNhc2UoTG9jYWxlIGxvY2FsZSk7Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gdXBwZXIKLSAgICogY2FzZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLCB3aGljaCBpcyByZXR1cm5lZAotICAgKiBieSA8Y29kZT5Mb2NhbGUuZ2V0RGVmYXVsdDwvY29kZT4uCi0gICAqCi0gICAqIDxwPgotICAgKiBJZiBubyBjaGFyYWN0ZXIgaW4gdGhpcyBzdHJpbmcgaGFzIGEgZGlmZmVyZW50IHVwcGVyY2FzZSB2ZXJzaW9uLAotICAgKiBiYXNlZCBvbiBjYWxsaW5nIHRoZSA8Y29kZT50b1VwcGVyQ2FzZTwvY29kZT4gbWV0aG9kIGRlZmluZWQgYnkKLSAgICogPGNvZGU+Q2hhcmFjdGVyPC9jb2RlPiwgdGhlbiB0aGUgb3JpZ2luYWwgc3RyaW5nIGlzIHJldHVybmVkLgotICAgKiA8cD4KLSAgICogT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgbmV3IDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0Ci0gICAqIHJlcHJlc2VudGluZyBhIGNoYXJhY3RlciBzZXF1ZW5jZSBpZGVudGljYWwgaW4gbGVuZ3RoIHRvIHRoZQotICAgKiBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhbmQKLSAgICogd2l0aCBldmVyeSBjaGFyYWN0ZXIgZXF1YWwgdG8gdGhlIHJlc3VsdCBvZiBhcHBseWluZyB0aGUgbWV0aG9kCi0gICAqIDxjb2RlPkNoYXJhY3Rlci50b1VwcGVyQ2FzZTwvY29kZT4gdG8gdGhlIGNvcnJlc3BvbmRpbmcgY2hhcmFjdGVyIG9mCi0gICAqIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QuIDxwPgotICAgKiBFeGFtcGxlczoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogIkZhaHJ2ZXJnbvxnZW4iLnRvVXBwZXJDYXNlKCkgcmV0dXJucyAiRkFIUlZFUkdO3EdFTiIKLSAgICogIlZpc2l0IExqdWJpbmplISIudG9VcHBlckNhc2UoKSByZXR1cm5zICJWSVNJVCBMSlVCSU5KRSEiCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZywgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvVXBwZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgdG9VcHBlckNhc2UoKTsKLQotICAvKioKLSAgICogUmVtb3ZlcyB3aGl0ZSBzcGFjZSBmcm9tIGJvdGggZW5kcyBvZiB0aGlzIHN0cmluZy4KLSAgICogPHA+Ci0gICAqIElmIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50cyBhbiBlbXB0eSBjaGFyYWN0ZXIKLSAgICogc2VxdWVuY2UsIG9yIHRoZSBmaXJzdCBhbmQgbGFzdCBjaGFyYWN0ZXJzIG9mIGNoYXJhY3RlciBzZXF1ZW5jZQotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGJvdGggaGF2ZSBjb2RlcwotICAgKiBncmVhdGVyIHRoYW4gPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPiAodGhlIHNwYWNlIGNoYXJhY3RlciksIHRoZW4gYQotICAgKiByZWZlcmVuY2UgdG8gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIE90aGVyd2lzZSwgaWYgdGhlcmUgaXMgbm8gY2hhcmFjdGVyIHdpdGggYSBjb2RlIGdyZWF0ZXIgdGhhbgotICAgKiA8Y29kZT4nJiM5Mjt1MDAyMCc8L2NvZGU+IGluIHRoZSBzdHJpbmcsIHRoZW4gYSBuZXcKLSAgICogPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgcmVwcmVzZW50aW5nIGFuIGVtcHR5IHN0cmluZyBpcyBjcmVhdGVkCi0gICAqIGFuZCByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIE90aGVyd2lzZSwgbGV0IDxpPms8L2k+IGJlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZQotICAgKiBzdHJpbmcgd2hvc2UgY29kZSBpcyBncmVhdGVyIHRoYW4gPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPiwgYW5kIGxldAotICAgKiA8aT5tPC9pPiBiZSB0aGUgaW5kZXggb2YgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgd2hvc2UgY29kZQotICAgKiBpcyBncmVhdGVyIHRoYW4gPGNvZGU+JyYjOTI7dTAwMjAnPC9jb2RlPi4gQSBuZXcgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiBvYmplY3QgaXMgY3JlYXRlZCwgcmVwcmVzZW50aW5nIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcgdGhhdAotICAgKiBiZWdpbnMgd2l0aCB0aGUgY2hhcmFjdGVyIGF0IGluZGV4IDxpPms8L2k+IGFuZCBlbmRzIHdpdGggdGhlCi0gICAqIGNoYXJhY3RlciBhdCBpbmRleCA8aT5tPC9pPi10aGF0IGlzLCB0aGUgcmVzdWx0IG9mCi0gICAqIDxjb2RlPnRoaXMuc3Vic3RyaW5nKDxpPms8L2k+LCZuYnNwOzxpPm08L2k+KzEpPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIFRoaXMgbWV0aG9kIG1heSBiZSB1c2VkIHRvIHRyaW0KLSAgICoge0BsaW5rIENoYXJhY3RlciNpc1NwYWNlKGNoYXIpIHdoaXRlc3BhY2V9IGZyb20gdGhlIGJlZ2lubmluZyBhbmQgZW5kCi0gICAqIG9mIGEgc3RyaW5nOyBpbiBmYWN0LCBpdCB0cmltcyBhbGwgQVNDSUkgY29udHJvbCBjaGFyYWN0ZXJzIGFzIHdlbGwuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoaXMgc3RyaW5nLCB3aXRoIHdoaXRlIHNwYWNlIHJlbW92ZWQgZnJvbSB0aGUgZnJvbnQgYW5kIGVuZC4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYTUxTdHJpbmcgdHJpbSgpOwotCi0gIC8qKgotICAgKiBUaGlzIG9iamVjdCAod2hpY2ggaXMgYWxyZWFkeSBhIHN0cmluZyEpIGlzIGl0c2VsZiByZXR1cm5lZC4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZyBpdHNlbGYuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHRvU3RyaW5nKCk7Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIG9iamVjdCBjb250YWlucyBhIGphdmEgU3RyaW5nIG9iamVjdC4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIFhNTFN0cmluZyBjYW4gcmV0dXJuIGEgc3RyaW5nIHdpdGhvdXQgY3JlYXRpbmcgb25lLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gaGFzU3RyaW5nKCk7Ci0gIAotICAvKioKLSAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGRvdWJsZSAtLSBBbGxvd2VkIGlucHV0IGlzIGluIGZpeGVkCi0gICAqIG5vdGF0aW9uIGRkZC5mZmYuCi0gICAqCi0gICAqIEByZXR1cm4gQSBkb3VibGUgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZywgb3IgcmV0dXJuIERvdWJsZS5OYU4gCi0gICAqIGlmIHRoZSBzdHJpbmcgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIHRvRG91YmxlKCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvWE1MU3RyaW5nRmFjdG9yeS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL1hNTFN0cmluZ0ZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODY3NTU5Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvWE1MU3RyaW5nRmFjdG9yeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzOwotCi0vKioKLSAqIEEgY29uY3JldGUgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoaXMgaW50ZXJmYWNlIGNyZWF0ZXMgWE1MU3RyaW5nIG9iamVjdHMuCi0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBYTUxTdHJpbmdGYWN0b3J5Ci17Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBYTUxTdHJpbmcgZnJvbSBhIEphdmEgc3RyaW5nLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gc3RyaW5nIEphdmEgU3RyaW5nIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBBbiBYTUxTdHJpbmcgb2JqZWN0IHRoYXQgd3JhcHMgdGhlIFN0cmluZyByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIG5ld3N0cihTdHJpbmcgc3RyaW5nKTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgWE1MU3RyaW5nIGZyb20gYSBGYXN0U3RyaW5nQnVmZmVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gc3RyaW5nIEZhc3RTdHJpbmdCdWZmZXIgcmVmZXJlbmNlLCB3aGljaCBtdXN0IGJlIG5vbi1udWxsLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiBBbiBYTUxTdHJpbmcgb2JqZWN0IHRoYXQgd3JhcHMgdGhlIEZhc3RTdHJpbmdCdWZmZXIgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyBuZXdzdHIoRmFzdFN0cmluZ0J1ZmZlciBzdHJpbmcsIGludCBzdGFydCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGgpOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBYTUxTdHJpbmcgZnJvbSBhIEZhc3RTdHJpbmdCdWZmZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzdHJpbmcgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UsIHdoaWNoIG11c3QgYmUgbm9uLW51bGwuCi0gICAqIEBwYXJhbSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24gaW4gdGhlIGFycmF5LgotICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkIGZyb20gdGhlIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIEFuIFhNTFN0cmluZyBvYmplY3QgdGhhdCB3cmFwcyB0aGUgRmFzdFN0cmluZ0J1ZmZlciByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgWE1MU3RyaW5nIG5ld3N0cihjaGFyW10gc3RyaW5nLCBpbnQgc3RhcnQsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gIC8qKgotICAgKiBHZXQgYSBjaGVhcCByZXByZXNlbnRhdGlvbiBvZiBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIAotICAgKiBAcmV0dXJuIEFuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhbiBYTUxTdHJpbmcgdGhhdCByZXByZXNlbnRzICIiLgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IFhNTFN0cmluZyBlbXB0eXN0cigpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNjNWZlNjkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDkgKzAsMCBAQAotPGh0bWw+Ci0gIDx0aXRsZT5YYWxhbiB1dGlsaXRpZXMuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gdXRpbGl0eSBjbGFzc2VzLiAgVGhpcyBwYWNrYWdlIGlzIGFsc28gc2hhcmVkIGJ5IFhQYXRoLgotICAgICAgIFRoZXJlICpzaG91bGQqIGJlIG5vIG91dHdhcmQgZGVwZW5kZW5jaWVzIHRvIFhQYXRoIG9yIFhhbGFuIGJ5IGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZUJ1bmRsZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VCdW5kbGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTRkN2QzYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZUJ1bmRsZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTgwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGVCYXNlOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGUgZGVmYXVsdCAoZW5nbGlzaCkgcmVzb3VyY2UgYnVuZGxlLgotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlQnVuZGxlIGV4dGVuZHMgTGlzdFJlc291cmNlQnVuZGxlCi17Ci0KLSAgLyoqIEVycm9yIHJlc291cmNlIGNvbnN0YW50cyAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xURXJyb3JSZXNvdXJjZXMiLCBYU0xUX1JFU09VUkNFID0KLSAgICAib3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZSIsIExBTkdfQlVORExFX05BTUUgPQotICAgICJvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlcyIsIE1VTFRfT1JERVIgPQotICAgICJtdWx0aXBsaWVyT3JkZXIiLCBNVUxUX1BSRUNFREVTID0gInByZWNlZGVzIiwgTVVMVF9GT0xMT1dTID0KLSAgICAiZm9sbG93cyIsIExBTkdfT1JJRU5UQVRJT04gPSAib3JpZW50YXRpb24iLCBMQU5HX1JJR0hUVE9MRUZUID0KLSAgICAicmlnaHRUb0xlZnQiLCBMQU5HX0xFRlRUT1JJR0hUID0gImxlZnRUb1JpZ2h0IiwgTEFOR19OVU1CRVJJTkcgPQotICAgICJudW1iZXJpbmciLCBMQU5HX0FERElUSVZFID0gImFkZGl0aXZlIiwgTEFOR19NVUxUX0FERCA9Ci0gICAgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiwgTEFOR19NVUxUSVBMSUVSID0KLSAgICAibXVsdGlwbGllciIsIExBTkdfTVVMVElQTElFUl9DSEFSID0KLSAgICAibXVsdGlwbGllckNoYXIiLCBMQU5HX05VTUJFUkdST1VQUyA9ICJudW1iZXJHcm91cHMiLCBMQU5HX05VTV9UQUJMRVMgPQotICAgICJ0YWJsZXMiLCBMQU5HX0FMUEhBQkVUID0gImFscGhhYmV0IiwgTEFOR19UUkFEX0FMUEhBQkVUID0gInRyYWRBbHBoYWJldCI7Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIG5hbWVkIFJlc291cmNlQnVuZGxlIGZvciBhIHBhcnRpY3VsYXIgbG9jYWxlLiAgVGhpcyBtZXRob2QgbWltaWNzIHRoZSBiZWhhdmlvcgotICAgKiBvZiBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoKS4KLSAgICoKLSAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIGxvY2FsLXNwZWNpZmljIHN1YmNsYXNzLgotICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUgdG8gcHJlZmVyIHdoZW4gc2VhcmNoaW5nIGZvciB0aGUgYnVuZGxlCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhSZXNvdXJjZUJ1bmRsZSBsb2FkUmVzb3VyY2VCdW5kbGUoCi0gICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSwgTG9jYWxlIGxvY2FsZSkgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgc3VmZml4ID0gZ2V0UmVzb3VyY2VTdWZmaXgobG9jYWxlKTsKLQotICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJyZXNvdXJjZSAiICsgY2xhc3NOYW1lICsgc3VmZml4KTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICAKLSAgICAgIC8vIGZpcnN0IHRyeSB3aXRoIHRoZSBnaXZlbiBsb2NhbGUKLSAgICAgIFN0cmluZyByZXNvdXJjZU5hbWUgPSBjbGFzc05hbWUgKyBzdWZmaXg7Ci0gICAgICByZXR1cm4gKFhSZXNvdXJjZUJ1bmRsZSkgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKHJlc291cmNlTmFtZSwgbG9jYWxlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHRyeSAgLy8gdHJ5IHRvIGZhbGwgYmFjayB0byBlbl9VUyBpZiB3ZSBjYW4ndCBsb2FkCi0gICAgICB7Ci0KLSAgICAgICAgLy8gU2luY2Ugd2UgY2FuJ3QgZmluZCB0aGUgbG9jYWxpemVkIHByb3BlcnR5IGZpbGUsCi0gICAgICAgIC8vIGZhbGwgYmFjayB0byBlbl9VUy4KLSAgICAgICAgcmV0dXJuIChYUmVzb3VyY2VCdW5kbGUpIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZSgKLSAgICAgICAgICBYU0xUX1JFU09VUkNFLCBuZXcgTG9jYWxlKCJlbiIsICJVUyIpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZTIpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gTm93IHdlIGFyZSByZWFsbHkgaW4gdHJvdWJsZS4KLSAgICAgICAgLy8gdmVyeSBiYWQsIGRlZmluaXRlbHkgdmVyeSBiYWQuLi5ub3QgZ29pbmcgdG8gZ2V0IHZlcnkgZmFyCi0gICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24oCi0gICAgICAgICAgIkNvdWxkIG5vdCBsb2FkIGFueSByZXNvdXJjZSBidW5kbGVzLiIsIGNsYXNzTmFtZSwgIiIpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHJlc291cmNlIGZpbGUgc3VmZmljIGZvciB0aGUgaW5kaWNhdGVkIGxvY2FsZQotICAgKiBGb3IgbW9zdCBsb2NhbGVzLCB0aGlzIHdpbGwgYmUgYmFzZWQgdGhlIGxhbmd1YWdlIGNvZGUuICBIb3dldmVyCi0gICAqIGZvciBDaGluZXNlLCB3ZSBkbyBkaXN0aW5ndWlzaCBiZXR3ZWVuIFRhaXdhbiBhbmQgUFJDCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZQotICAgKiBAcmV0dXJuIGFuIFN0cmluZyBzdWZmaXggd2hpY2ggY2FuYmUgYXBwZW5kZWQgdG8gYSByZXNvdXJjZSBuYW1lCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0UmVzb3VyY2VTdWZmaXgoTG9jYWxlIGxvY2FsZSkKLSAgewotCi0gICAgU3RyaW5nIGxhbmcgPSBsb2NhbGUuZ2V0TGFuZ3VhZ2UoKTsKLSAgICBTdHJpbmcgY291bnRyeSA9IGxvY2FsZS5nZXRDb3VudHJ5KCk7Ci0gICAgU3RyaW5nIHZhcmlhbnQgPSBsb2NhbGUuZ2V0VmFyaWFudCgpOwotICAgIFN0cmluZyBzdWZmaXggPSAiXyIgKyBsb2NhbGUuZ2V0TGFuZ3VhZ2UoKTsKLQotICAgIGlmIChsYW5nLmVxdWFscygiemgiKSkKLSAgICAgIHN1ZmZpeCArPSAiXyIgKyBjb3VudHJ5OwotCi0gICAgaWYgKGNvdW50cnkuZXF1YWxzKCJKUCIpKQotICAgICAgc3VmZml4ICs9ICJfIiArIGNvdW50cnkgKyAiXyIgKyB2YXJpYW50OwotCi0gICAgcmV0dXJuIHN1ZmZpeDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICByZXR1cm4gY29udGVudHM7Ci0gIH0KLQotICAvKiogVGhlIGFzc29jaWF0aW9uIGxpc3QuICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJsYW5ndWFnZSIsICJlbiIgfSwKLSAgICB7ICJhbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlcmluZyIsICJhZGRpdGl2ZSIgfSwKLSAgfTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlQnVuZGxlQmFzZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VCdW5kbGVCYXNlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJhZDQ2YzYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VCdW5kbGVCYXNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhpcyBpcyBhbiBpbnRlcmZhY2UgZm9yIGVycm9yIG1lc3NhZ2VzLiAgVGhpcyBjbGFzcyBpcyBtaXNuYW1lZCwKLSAqIGFuZCBzaG91bGQgYmUgY2FsbGVkIFhhbGFuUmVzb3VyY2VCdW5kbGUsIG9yIHNvbWUgc3VjaC4KLSAqLwotYWJzdHJhY3QgcHVibGljIGNsYXNzIFhSZXNvdXJjZUJ1bmRsZUJhc2UgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBlcnJvciBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBlcnJvciBjb2RlCi0gICAqCi0gICAqIEBwYXJhbSBlcnJvckNvZGUgRXJyb3IgY29kZQotICAgKgotICAgKiBAcmV0dXJuIGVycm9yIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGVycm9yIGNvZGUKLSAgICovCi0gIGFic3RyYWN0IHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZUtleShpbnQgZXJyb3JDb2RlKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB3YXJuaW5nIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGVycm9yIGNvZGUKLSAgICoKLSAgICogQHBhcmFtIGVycm9yQ29kZSBFcnJvciBjb2RlCi0gICAqIAotICAgKiBAcmV0dXJuIHdhcm5pbmcgc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgY29kZQotICAgKi8KLSAgYWJzdHJhY3QgcHVibGljIFN0cmluZyBnZXRXYXJuaW5nS2V5KGludCBlcnJvckNvZGUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2N5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfY3kuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjYzNzA4YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfY3kuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLQotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhlIEN5cmlsbGljIHJlc291cmNlIGJ1bmRsZS4KLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfY3kgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIGNvbnRlbnRzOwotICB9Ci0KLSAvKiogVGhlIGFzc29jaWF0aW9uIGxpc3QuICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImN5IiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImN5IiB9LCB7ICJsYW5ndWFnZSIsICJjeSIgfSwKLSAgICB7ICJhbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAweDA0MzAsIDB4MDQzMiwgMHgwNDMzLCAweDA0MzQsIDB4MDQzNSwgMHgwNDM3LCAweDA0MzgsCi0gICAgICAgICAgICAgICAgICAweDA0MzksIDB4MDRBOSwgMHgwNDU3LCAweDA0M0EsIDB4MDQzQiwgMHgwNDNDLCAweDA0M0QsCi0gICAgICAgICAgICAgICAgICAweDA0NkYsIDB4MDQzRSwgMHgwNDNGLCAweDA0NDcsIDB4MDQ0MCwgMHgwNDQxLCAweDA0NDIsCi0gICAgICAgICAgICAgICAgICAweDA0NDMsIDB4MDQ0NCwgMHgwNDQ1LCAweDA0NzAsIDB4MDQ2MCwgMHgwNDQ2IH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAKLSAgICAvL3sibnVtYmVyaW5nIiwgImFkZGl0aXZlIn0sCi0gICAgeyAibnVtYmVyaW5nIiwgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiB9LAotICAgIHsgIm11bHRpcGxpZXJPcmRlciIsICJwcmVjZWRlcyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgaW50W117IDEwMCwgMTAsIDEgfSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBpbnRbXXsgMTAwMCB9IH0sCi0gICAgeyAibXVsdGlwbGllckNoYXIiLCBuZXcgY2hhcltdeyAweDAzRDkgfSB9LAotCi0gICAgLy8gY2hpbmVzZSBvbmx5Pz8KLSAgICB7ICJ6ZXJvIiwgbmV3IGNoYXJbMF0gfSwKLQotICAgIC8veyJkaWdpdHMiLCBuZXcgY2hhcltdeydhJywnYicsJ2MnLCdkJywnZScsJ2YnLCdnJywnaCcsJ2knfX0sCi0gICAgeyAiZGlnaXRzIiwKLSAgICAgIG5ldyBjaGFyW117IDB4MDQzMCwgMHgwNDMyLCAweDA0MzMsIDB4MDQzNCwgMHgwNDM1LCAweDA0MzcsIDB4MDQzOCwKLSAgICAgICAgICAgICAgICAgIDB4MDQzOSwgMHgwNEE5IH0gfSwKLSAgICB7ICJ0ZW5zIiwKLSAgICAgIG5ldyBjaGFyW117IDB4MDQ1NywgMHgwNDNBLCAweDA0M0IsIDB4MDQzQywgMHgwNDNELCAweDA0NkYsIDB4MDQzRSwKLSAgICAgICAgICAgICAgICAgIDB4MDQzRiwgMHgwNDQ3IH0gfSwKLSAgICB7ICJodW5kcmVkcyIsCi0gICAgICBuZXcgY2hhcltdeyAweDA0NDAsIDB4MDQ0MSwgMHgwNDQyLCAweDA0NDMsIDB4MDQ0NCwgMHgwNDQ1LCAweDA0NzAsCi0gICAgICAgICAgICAgICAgICAweDA0NjAsIDB4MDQ0NiB9IH0sCi0gICAgeyAidGFibGVzIiwgbmV3IFN0cmluZ1tdeyAiaHVuZHJlZHMiLCAidGVucyIsICJkaWdpdHMiIH0gfQotICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2VsLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfZWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmNjYTYwMi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfZWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19lbi5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhlIEdyZWVrIHJlc291cmNlIGJ1bmRsZS4KLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfZWwgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIGNvbnRlbnRzOwotICB9Ci0KLSAgLyoqIFRoZSBhc3NvY2lhdGlvbiBsaXN0LiAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9Ci0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJlbCIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJlbCIgfSwgeyAibGFuZ3VhZ2UiLCAiZWwiIH0sCi0gICAgeyAiYWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgMHgwM2IxLCAweDAzYjIsIDB4MDNiMywgMHgwM2I0LCAweDAzYjUsIDB4MDNiNiwgMHgwM2I3LAotICAgICAgICAgICAgICAgICAgMHgwM2I4LCAweDAzYjksIDB4MDNiYSwgMHgwM2JiLCAweDAzYmMsIDB4MDNiZCwgMHgwM2JlLAotICAgICAgICAgICAgICAgICAgMHgwM2JmLCAweDAzYzAsIDB4MDNjMSwgMHgwM2MyLCAweDAzYzMsIDB4MDNjNCwgMHgwM2M1LAotICAgICAgICAgICAgICAgICAgMHgwM2M2LCAweDAzYzcsIDB4MDNjOCwgMHgwM2M5IH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAKLSAgICAvL3sibnVtYmVyaW5nIiwgImFkZGl0aXZlIn0sCi0gICAgeyAibnVtYmVyaW5nIiwgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiB9LAotICAgIHsgIm11bHRpcGxpZXJPcmRlciIsICJwcmVjZWRlcyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nICAgCi0gICAgeyAibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdeyAxMDAsIDEwLCAxIH0gfSwKLQotICAgIC8vVGhlc2Ugb25seSB1c2VkIGZvciBtdXRpcGxpY2F0aXZlLWFkZGl0aXZlIG51bWJlcmluZwotICAgIHsgIm11bHRpcGxpZXIiLCBuZXcgaW50W117IDEwMDAgfSB9LAotICAgIHsgIm11bHRpcGxpZXJDaGFyIiwgbmV3IGNoYXJbXXsgMHgwM2Q5IH0gfSwKLQotICAgIC8vIGNoaW5lc2Ugb25seT8/Ci0gICAgeyAiemVybyIsIG5ldyBjaGFyWzBdIH0sCi0KLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywnZycsJ2gnLCdpJ319LAotICAgIHsgImRpZ2l0cyIsCi0gICAgICBuZXcgY2hhcltdeyAweDAzYjEsIDB4MDNiMiwgMHgwM2IzLCAweDAzYjQsIDB4MDNiNSwgMHgwM2RiLCAweDAzYjYsCi0gICAgICAgICAgICAgICAgICAweDAzYjcsIDB4MDNiOCB9IH0sCi0gICAgeyAidGVucyIsCi0gICAgICBuZXcgY2hhcltdeyAweDAzYjksIDB4MDNiYSwgMHgwM2JiLCAweDAzYmMsIDB4MDNiZCwgMHgwM2JlLCAweDAzYmYsCi0gICAgICAgICAgICAgICAgICAweDAzYzAsIDB4MDNkZiB9IH0sCi0gICAgeyAiaHVuZHJlZHMiLAotICAgICAgbmV3IGNoYXJbXXsgMHgwM2MxLCAweDAzYzIsIDB4MDNjNCwgMHgwM2M1LCAweDAzYzYsIDB4MDNjNywgMHgwM2M4LAotICAgICAgICAgICAgICAgICAgMHgwM2M5LCAweDAzZTEgfSB9LAotCi0gICAgLy97InRob3VzYW5kcyIsIG5ldyBjaGFyW117MHgxMEQ5LDB4MTBEQSwweDEwREIsMHgxMERDLDB4MTBERCwweDEwREUsMHgxMERGLDB4MTBFMCwweDEwRTF9fSwgIAotICAgIC8vaHVuZHJlZHMsIGV0Yy4uLgotICAgIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdbXXsgImh1bmRyZWRzIiwgInRlbnMiLCAiZGlnaXRzIiB9IH0KLSAgfTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19lbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE2Y2QzNTIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2VuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTYgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHMucmVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZTsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vLwotLy8gIExhbmdSZXNvdXJjZXNfZW4ucHJvcGVydGllcwotLy8KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoZSBFbmdsaXNoIHJlc291cmNlIGJ1bmRsZS4KLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfZW4gZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIGNvbnRlbnRzOwotICB9Ci0KLSAgLyoqIFRoZSBhc3NvY2lhdGlvbiBsaXN0LiAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJsYW5ndWFnZSIsICJlbiIgfSwKLSAgICB7ICJhbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlcmluZyIsICJhZGRpdGl2ZSIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nICAgCi0gICAgLy97Im51bWJlckdyb3VwcyIsIG5ldyBpbnRbXXsxMCwxfX0sCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy97Im11bHRpcGxpZXIiLCAiMTAifSwKLSAgICAvL3sibXVsdGlwbGllckNoYXIiLCAiTSJ9LCAKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywnZycsJ2gnLCdpJ319LAotICAgIC8veyJkaWdpdHMiLCBuZXcgY2hhcltdezB4MTBEMCwweDEwRDEsMHgxMEQyLDB4MTBEMywweDEwRDQsMHgxMEQ1LDB4MTBENiwweDEwRDcsMHgxMEQ4fX0sCi0gICAgLy97InRlbnMiLCBuZXcgY2hhcltdezB4MTBEOSwweDEwREEsMHgxMERCLDB4MTBEQywweDEwREQsMHgxMERFLDB4MTBERiwweDEwRTAsMHgxMEUxfX0sICAKLSAgICAvL2h1bmRyZWRzLCBldGMuLi4KLSAgICAvL3sidGFibGVzIiwgbmV3IFN0cmluZ1tdeyJ0ZW5zIiwgImRpZ2l0cyJ9fQotICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2hlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfaGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTRlOTY0Mi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfaGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19lbi5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhlIEhlYnJldyByZXNvdXJjZSBidW5kbGUuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX2hlIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotCi0gIC8qKiBUaGUgYXNzb2NpYXRpb24gbGlzdC4gICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPQotICB7Ci0gICAgeyAidWlfbGFuZ3VhZ2UiLCAiaGUiIH0sIHsgImhlbHBfbGFuZ3VhZ2UiLCAiaGUiIH0sIHsgImxhbmd1YWdlIiwgImhlIiB9LAotICAgIHsgImFscGhhYmV0IiwKLSAgICAgIG5ldyBjaGFyW117IDB4MDVEMCwgMHgwNUQxLCAweDA1RDIsIDB4MDVEMywgMHgwNUQ0LCAweDA1RDUsIDB4MDVENiwKLSAgICAgICAgICAgICAgICAgIDB4MDVENywgMHgwNUQ4LCAweDA1RDksIDB4MDVEQSwgMHgwNURCLCAweDA1REMsIDB4MDVERCwKLSAgICAgICAgICAgICAgICAgIDB4MDVERSwgMHgwNURGLCAweDA1RTAsIDB4MDVFMSB9IH0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSB9LAotCi0gICAgLy9sYW5ndWFnZSBvcmllbnRhdGlvbgotICAgIHsgIm9yaWVudGF0aW9uIiwgIlJpZ2h0VG9MZWZ0IiB9LAotCi0gICAgLy9sYW5ndWFnZSBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJpbmciLCAiYWRkaXRpdmUiIH0sCi0KLSAgICAvLyBsYXJnZXN0IG51bWVyaWNhbCB2YWx1ZQotICAgIC8veyJNYXhOdW1lcmljYWxWYWx1ZSIsIG5ldyBJbnRlZ2VyKCl9LAotICAgIC8vVGhlc2Ugd291bGQgbm90IGJlIHVzZWQgZm9yIEVOLiBPbmx5IHVzZWQgZm9yIHRyYWRpdGlvbmFsIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlckdyb3VwcyIsIG5ldyBpbnRbXXsgMTAsIDEgfSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy97Im11bHRpcGxpZXIiLCAiMTAifSwKLSAgICAvL3sibXVsdGlwbGllckNoYXIiLCAiTSJ9LCAKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywnZycsJ2gnLCdpJ319LAotICAgIHsgImRpZ2l0cyIsCi0gICAgICBuZXcgY2hhcltdeyAweDA1RDAsIDB4MDVEMSwgMHgwNUQyLCAweDA1RDMsIDB4MDVENCwgMHgwNUQ1LCAweDA1RDYsCi0gICAgICAgICAgICAgICAgICAweDA1RDcsIDB4MDVEOCB9IH0sCi0gICAgeyAidGVucyIsCi0gICAgICBuZXcgY2hhcltdeyAweDA1RDksIDB4MDVEQSwgMHgwNURCLCAweDA1REMsIDB4MDVERCwgMHgwNURFLCAweDA1REYsCi0gICAgICAgICAgICAgICAgICAweDA1RTAsIDB4MDVFMSB9IH0sCi0KLSAgICAvL2h1bmRyZWRzLCBldGMuLi4KLSAgICB7ICJ0YWJsZXMiLCBuZXcgU3RyaW5nW117ICJ0ZW5zIiwgImRpZ2l0cyIgfSB9Ci0gIH07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfaHkuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19oeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYmI0MDYzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19oeS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGUgQXJtZW5pYW4gcmVzb3VyY2UgYnVuZGxlLgotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19oeSBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICByZXR1cm4gY29udGVudHM7Ci0gIH0KLQotICAvKiogVGhlIGFzc29jaWF0aW9uIGxpc3QuICAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImh5IiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImh5IiB9LCB7ICJsYW5ndWFnZSIsICJoeSIgfSwKLSAgICB7ICJhbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAweDA1NjEsIDB4MDU2MiwgMHgwNTYzLCAweDA1NjQsIDB4MDU2NSwgMHgwNTY2LCAweDA1NjcsCi0gICAgICAgICAgICAgICAgICAweDA1NjgsIDB4MDU2OSwgMHgwNTZBLCAweDA1NkIsIDB4MDU2QywgMHgwNTZELCAweDA1NkUsCi0gICAgICAgICAgICAgICAgICAweDA1NkYsIDB4MDU2NywgMHgwNTY4LCAweDA1NzIsIDB4MDU3MywgMHgwNTc0LCAweDA1NzUsCi0gICAgICAgICAgICAgICAgICAweDA1NzYsIDB4MDU3NywgMHgwNTc4LCAweDA1NzksIDB4MDU3QSwgMHgwNTdCLCAweDA1N0MsCi0gICAgICAgICAgICAgICAgICAweDA1N0QsIDB4MDU3RSwgMHgwNTdGLCAweDA1ODAsIDB4MDU4MSwgMHgwNTgyLCAweDA1ODMsCi0gICAgICAgICAgICAgICAgICAweDA1ODQgfSB9LAotICAgIHsgInRyYWRBbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0gfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nICAgCi0gICAgeyAibnVtYmVyaW5nIiwgImFkZGl0aXZlIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUKLSAgICAvL3siTWF4TnVtZXJpY2FsVmFsdWUiLCBuZXcgSW50ZWdlcigpfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgaW50W117IDEwMDAsIDEwMCwgMTAsIDEgfSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgLy97Im11bHRpcGxpZXIiLCAiMTAifSwKLSAgICAvL3sibXVsdGlwbGllckNoYXIiLCAiTSJ9LCAKLSAgICAvL3siZGlnaXRzIiwgbmV3IGNoYXJbXXsnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywnZycsJ2gnLCdpJ319LAotICAgIHsgImRpZ2l0cyIsCi0gICAgICBuZXcgY2hhcltdeyAweDA1NjEsIDB4MDU2MiwgMHgwNTYzLCAweDA1NjQsIDB4MDU2NSwgMHgwNTY2LCAweDA1NjcsCi0gICAgICAgICAgICAgICAgICAweDA1NjgsIDB4MDU2OSB9IH0sCi0gICAgeyAidGVucyIsCi0gICAgICBuZXcgY2hhcltdeyAweDA1NkEsIDB4MDU2QiwgMHgwNTZDLCAweDA1NkQsIDB4MDU2RSwgMHgwNTZGLCAweDA1NjcsCi0gICAgICAgICAgICAgICAgICAweDA1NjgsIDB4MDU3MiB9IH0sCi0gICAgeyAiaHVuZHJlZHMiLAotICAgICAgbmV3IGNoYXJbXXsgMHgwNTczLCAweDA1NzQsIDB4MDU3NSwgMHgwNTc2LCAweDA1NzcsIDB4MDU3OCwgMHgwNTc5LAotICAgICAgICAgICAgICAgICAgMHgwNTdBLCAweDA1N0IgfSB9LAotICAgIHsgInRob3VzYW5kcyIsCi0gICAgICBuZXcgY2hhcltdeyAweDA1N0MsIDB4MDU3RCwgMHgwNTdFLCAweDA1N0YsIDB4MDU4MCwgMHgwNTgxLCAweDA1ODIsCi0gICAgICAgICAgICAgICAgICAweDA1ODMsIDB4MDU4NCB9IH0sCi0gICAgeyAidGFibGVzIiwgbmV3IFN0cmluZ1tdeyAidGhvdXNhbmRzIiwgImh1bmRyZWRzIiwgInRlbnMiLCAiZGlnaXRzIiB9IH0KLSAgfTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19qYV9KUF9BLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfQS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOWIxN2E3Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19qYV9KUF9BLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHMucmVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZTsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vLwotLy8gIExhbmdSZXNvdXJjZXNfZW4ucHJvcGVydGllcwotLy8KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoZSBKYXBhbmVzZSAoS2F0YWthbmEpIHJlc291cmNlIGJ1bmRsZS4KLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfamFfSlBfQSBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFzc29jaWF0aW9uIGxpc3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICByZXR1cm4gY29udGVudHM7Ci0gIH0KLQotICAvKiogVGhlIGFzc29jaWF0aW9uIGxpc3QuICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPQotICB7Ci0gICAgeyAidWlfbGFuZ3VhZ2UiLCAiamEiIH0sIHsgImhlbHBfbGFuZ3VhZ2UiLCAiamEiIH0sIHsgImxhbmd1YWdlIiwgImphIiB9LAotICAgIHsgImFscGhhYmV0IiwKLSAgICAgIG5ldyBjaGFyW117IDB4MzBhMiwgMHgzMGE0LCAweDMwYTYsIDB4MzBhOCwgMHgzMGFhLCAweDMwYWIsIDB4MzBhZCwKLSAgICAgICAgICAgICAgICAgIDB4MzBhZiwgMHgzMGIxLCAweDMwYjMsIDB4MzBiNSwgMHgzMGI3LCAweDMwYjksIDB4MzBiYiwKLSAgICAgICAgICAgICAgICAgIDB4MzBiZCwgMHgzMGJmLCAweDMwYzEsIDB4MzBjNCwgMHgzMGM2LCAweDMwYzgsIDB4MzBjYSwKLSAgICAgICAgICAgICAgICAgIDB4MzBjYiwgMHgzMGNjLCAweDMwY2QsIDB4MzBjZSwgMHgzMGNmLCAweDMwZDIsIDB4MzBkNSwKLSAgICAgICAgICAgICAgICAgIDB4MzBkOCwgMHgzMGRiLCAweDMwZGUsIDB4MzBkZiwgMHgzMGUwLCAweDMwZTEsIDB4MzBlMiwKLSAgICAgICAgICAgICAgICAgIDB4MzBlNCwgMHgzMGU2LCAweDMwZTgsIDB4MzBlOSwgMHgzMGVhLCAweDMwZWIsIDB4MzBlYywKLSAgICAgICAgICAgICAgICAgIDB4MzBlZCwgMHgzMGVmLCAweDMwZjAsIDB4MzBmMSwgMHgzMGYyLCAweDMwZjMgfSB9LAotICAgIHsgInRyYWRBbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0gfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24gCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlcmluZyIsICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIgfSwKLSAgICB7ICJtdWx0aXBsaWVyT3JkZXIiLCAiZm9sbG93cyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgaW50W117IDEgfSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsCi0gICAgICBuZXcgaW50W117IDEwMDAwMDAwMDAsIDEwMDAwMDAwMCwgMTAwMDAsIDEwMDAsIDEwMCwgMTAgfSB9LAotICAgIHsgIm11bHRpcGxpZXJDaGFyIiwKLSAgICAgIG5ldyBjaGFyW117IDB4NEVBQywgMHg1MTQ2LCAweDUxMDQsIDB4NEUwNywgMHg1MzQzLCAweDc2N2UsIDB4NTM0MSB9IH0sCi0KLSAgICAvLyBjaGluZXNlIG9ubHk/IAotICAgIHsgInplcm8iLCBuZXcgY2hhclswXSB9LAotICAgIHsgImRpZ2l0cyIsCi0gICAgICBuZXcgY2hhcltdeyAweDRFMDAsIDB4NEU4QywgMHg0RTA5LCAweDU2REIsIDB4NEU5NCwgMHg1MTZELCAweDRFMDMsCi0gICAgICAgICAgICAgICAgICAweDUxNkIsIDB4NEU1RCB9IH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdbXXsgImRpZ2l0cyIgfSB9Ci0gIH07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSEEuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19qYV9KUF9IQS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MjBjYWVlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc19qYV9KUF9IQS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGUgSmFwYW5lc2UgKEhpcmFnYW5hKSByZXNvdXJjZSBidW5kbGUuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX2phX0pQX0hBIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotCi0gIC8qKiBUaGUgYXNzb2NpYXRpb24gbGlzdC4gICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImphIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImphIiB9LCB7ICJsYW5ndWFnZSIsICJqYSIgfSwKLSAgICB7ICJhbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAweDMwNDIsIDB4MzA0NCwgMHgzMDQ2LCAweDMwNDgsIDB4MzA0YSwgMHgzMDRiLCAweDMwNGQsCi0gICAgICAgICAgICAgICAgICAweDMwNGYsIDB4MzA1MSwgMHgzMDUzLCAweDMwNTUsIDB4MzA1NywgMHgzMDU5LCAweDMwNWIsCi0gICAgICAgICAgICAgICAgICAweDMwNWQsIDB4MzA1ZiwgMHgzMDYxLCAweDMwNjQsIDB4MzA2NiwgMHgzMDY4LCAweDMwNmEsCi0gICAgICAgICAgICAgICAgICAweDMwNmIsIDB4MzA2YywgMHgzMDZkLCAweDMwNmUsIDB4MzA2ZiwgMHgzMDcyLCAweDMwNzUsCi0gICAgICAgICAgICAgICAgICAweDMwNzgsIDB4MzA3YiwgMHgzMDdlLCAweDMwN2YsIDB4MzA4MCwgMHgzMDgxLCAweDMwODIsCi0gICAgICAgICAgICAgICAgICAweDMwODQsIDB4MzA4NiwgMHgzMDg4LCAweDMwODksIDB4MzA4YSwgMHgzMDhiLCAweDMwOGMsCi0gICAgICAgICAgICAgICAgICAweDMwOGQsIDB4MzA4ZiwgMHgzMDkwLCAweDMwOTEsIDB4MzA5MiwgMHgzMDkzIH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uIAotICAgIHsgIm9yaWVudGF0aW9uIiwgIkxlZnRUb1JpZ2h0IiB9LAotCi0gICAgLy9sYW5ndWFnZSBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJpbmciLCAibXVsdGlwbGljYXRpdmUtYWRkaXRpdmUiIH0sCi0gICAgeyAibXVsdGlwbGllck9yZGVyIiwgImZvbGxvd3MiIH0sCi0KLSAgICAvLyBsYXJnZXN0IG51bWVyaWNhbCB2YWx1ZQotICAgIC8veyJNYXhOdW1lcmljYWxWYWx1ZSIsIG5ldyBJbnRlZ2VyKDEwMDAwMDAwMDAwKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nICAgCi0gICAgeyAibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdeyAxIH0gfSwKLQotICAgIC8vVGhlc2Ugb25seSB1c2VkIGZvciBtdXRpcGxpY2F0aXZlLWFkZGl0aXZlIG51bWJlcmluZwotICAgIHsgIm11bHRpcGxpZXIiLAotICAgICAgbmV3IGludFtdeyAxMDAwMDAwMDAwLCAxMDAwMDAwMDAsIDEwMDAwLCAxMDAwLCAxMDAsIDEwIH0gfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsCi0gICAgICBuZXcgY2hhcltdeyAweDRFQUMsIDB4NTE0NiwgMHg1MTA0LCAweDRFMDcsIDB4NTM0MywgMHg3NjdlLCAweDUzNDEgfSB9LAotCi0gICAgLy8gY2hpbmVzZSBvbmx5PyAKLSAgICB7ICJ6ZXJvIiwgbmV3IGNoYXJbMF0gfSwKLSAgICB7ICJkaWdpdHMiLAotICAgICAgbmV3IGNoYXJbXXsgMHg0RTAwLCAweDRFOEMsIDB4NEUwOSwgMHg1NkRCLCAweDRFOTQsIDB4NTE2RCwgMHg0RTAzLAotICAgICAgICAgICAgICAgICAgMHg1MTZCLCAweDRFNUQgfSB9LCB7ICJ0YWJsZXMiLCBuZXcgU3RyaW5nW117ICJkaWdpdHMiIH0gfQotICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0hJLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSEkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTRhNTY1Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSEkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19lbi5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhlIEphcGFuZXNlIChIaXJhZ2FuYSkgcmVzb3VyY2UgYnVuZGxlLgotICovCi1wdWJsaWMgY2xhc3MgWFJlc291cmNlc19qYV9KUF9ISSBleHRlbmRzIFhSZXNvdXJjZUJ1bmRsZQotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIGFzc29jaWF0aW9uIHRhYmxlIGZvciB0aGlzIHJlc291cmNlLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhc3NvY2lhdGlvbiB0YWJsZSBmb3IgdGhpcyByZXNvdXJjZS4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotCi0gIC8qKiBUaGUgYXNzb2NpYXRpb24gdGFibGUgZm9yIHRoaXMgcmVzb3VyY2UuICAqLwotICBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9Ci0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJqYSIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJqYSIgfSwgeyAibGFuZ3VhZ2UiLCAiamEiIH0sCi0gICAgeyAiYWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgMHgzMDQ0LCAweDMwOGQsIDB4MzA2ZiwgMHgzMDZiLCAweDMwN2IsIDB4MzA3OCwgMHgzMDY4LAotICAgICAgICAgICAgICAgICAgMHgzMDYxLCAweDMwOGEsIDB4MzA2YywgMHgzMDhiLCAweDMwOTIsIDB4MzA4ZiwgMHgzMDRiLAotICAgICAgICAgICAgICAgICAgMHgzMDg4LCAweDMwNWYsIDB4MzA4YywgMHgzMDVkLCAweDMwNjQsIDB4MzA2ZCwgMHgzMDZhLAotICAgICAgICAgICAgICAgICAgMHgzMDg5LCAweDMwODAsIDB4MzA0NiwgMHgzMDkwLCAweDMwNmUsIDB4MzA0YSwgMHgzMDRmLAotICAgICAgICAgICAgICAgICAgMHgzMDg0LCAweDMwN2UsIDB4MzA1MSwgMHgzMDc1LCAweDMwNTMsIDB4MzA0OCwgMHgzMDY2LAotICAgICAgICAgICAgICAgICAgMHgzMDQyLCAweDMwNTUsIDB4MzA0ZCwgMHgzMDg2LCAweDMwODEsIDB4MzA3ZiwgMHgzMDU3LAotICAgICAgICAgICAgICAgICAgMHgzMDkxLCAweDMwNzIsIDB4MzA4MiwgMHgzMDViLCAweDMwNTkgfSB9LAotICAgIHsgInRyYWRBbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnLCAnRycsICdIJywgJ0knLCAnSicsICdLJywgJ0wnLAotICAgICAgICAgICAgICAgICAgJ00nLCAnTicsICdPJywgJ1AnLCAnUScsICdSJywgJ1MnLCAnVCcsICdVJywgJ1YnLCAnVycsICdYJywKLSAgICAgICAgICAgICAgICAgICdZJywgJ1onIH0gfSwKLQotICAgIC8vbGFuZ3VhZ2Ugb3JpZW50YXRpb24KLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nICAgCi0gICAgeyAibnVtYmVyaW5nIiwgIm11bHRpcGxpY2F0aXZlLWFkZGl0aXZlIiB9LAotICAgIHsgIm11bHRpcGxpZXJPcmRlciIsICJmb2xsb3dzIiB9LAotCi0gICAgLy8gbGFyZ2VzdCBudW1lcmljYWwgdmFsdWUgCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgaW50W117IDEgfSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsCi0gICAgICBuZXcgaW50W117IDEwMDAwMDAwMDAsIDEwMDAwMDAwMCwgMTAwMDAsIDEwMDAsIDEwMCwgMTAgfSB9LAotICAgIHsgIm11bHRpcGxpZXJDaGFyIiwKLSAgICAgIG5ldyBjaGFyW117IDB4NEVBQywgMHg1MTQ2LCAweDUxMDQsIDB4NEUwNywgMHg1MzQzLCAweDc2N2UsIDB4NTM0MSB9IH0sCi0KLSAgICAvLyBjaGluZXNlIG9ubHk/PwotICAgIHsgInplcm8iLCBuZXcgY2hhclswXSB9LAotICAgIHsgImRpZ2l0cyIsCi0gICAgICBuZXcgY2hhcltdeyAweDRFMDAsIDB4NEU4QywgMHg0RTA5LCAweDU2REIsIDB4NEU5NCwgMHg1MTZELCAweDRFMDMsCi0gICAgICAgICAgICAgICAgICAweDUxNkIsIDB4NEU1RCB9IH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdbXXsgImRpZ2l0cyIgfSB9Ci0gIH07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2phX0pQX0kuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTBlOTM3NC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfamFfSlBfSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGUgSmFwYW5lc2UgKEthdGFrYW5hKSByZXNvdXJjZSBidW5kbGUuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX2phX0pQX0kgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiB0YWJsZSBmb3IgdGhpcyByZXNvdXJjZS4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0aGUgYXNzb2NpYXRpb24gdGFibGUgZm9yIHRoaXMgcmVzb3VyY2UuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W11bXSBnZXRDb250ZW50cygpCi0gIHsKLSAgICByZXR1cm4gY29udGVudHM7Ci0gIH0KLQotICAvKiogVGhlIGFzc29jaWF0aW9uIHRhYmxlIGZvciB0aGlzIHJlc291cmNlLiAgKi8KLSAgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPQotICB7Ci0gICAgeyAidWlfbGFuZ3VhZ2UiLCAiamEiIH0sIHsgImhlbHBfbGFuZ3VhZ2UiLCAiamEiIH0sIHsgImxhbmd1YWdlIiwgImphIiB9LAotICAgIHsgImFscGhhYmV0IiwKLSAgICAgIG5ldyBjaGFyW117IDB4MzBhNCwgMHgzMGVkLCAweDMwY2YsIDB4MzBjYiwgMHgzMGRiLCAweDMwZDgsIDB4MzBjOCwKLSAgICAgICAgICAgICAgICAgIDB4MzBjMSwgMHgzMGVhLCAweDMwY2MsIDB4MzBlYiwgMHgzMGYyLCAweDMwZWYsIDB4MzBhYiwKLSAgICAgICAgICAgICAgICAgIDB4MzBlOCwgMHgzMGJmLCAweDMwZWMsIDB4MzBiZCwgMHgzMGM0LCAweDMwY2QsIDB4MzBjYSwKLSAgICAgICAgICAgICAgICAgIDB4MzBlOSwgMHgzMGUwLCAweDMwYTYsIDB4MzBmMCwgMHgzMGNlLCAweDMwYWEsIDB4MzBhZiwKLSAgICAgICAgICAgICAgICAgIDB4MzBlNCwgMHgzMGRlLCAweDMwYjEsIDB4MzBkNSwgMHgzMGIzLCAweDMwYTgsIDB4MzBjNiwKLSAgICAgICAgICAgICAgICAgIDB4MzBhMiwgMHgzMGI1LCAweDMwYWQsIDB4MzBlNiwgMHgzMGUxLCAweDMwZGYsIDB4MzBiNywKLSAgICAgICAgICAgICAgICAgIDB4MzBmMSwgMHgzMGQyLCAweDMwZTIsIDB4MzBiYiwgMHgzMGI5IH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlcmluZyIsICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIgfSwKLSAgICB7ICJtdWx0aXBsaWVyT3JkZXIiLCAiZm9sbG93cyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlIAotICAgIC8veyJNYXhOdW1lcmljYWxWYWx1ZSIsIG5ldyBJbnRlZ2VyKDEwMDAwMDAwMDAwKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nICAgCi0gICAgeyAibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdeyAxIH0gfSwKLQotICAgIC8vVGhlc2Ugb25seSB1c2VkIGZvciBtdXRpcGxpY2F0aXZlLWFkZGl0aXZlIG51bWJlcmluZwotICAgIHsgIm11bHRpcGxpZXIiLAotICAgICAgbmV3IGludFtdeyAxMDAwMDAwMDAwLCAxMDAwMDAwMDAsIDEwMDAwLCAxMDAwLCAxMDAsIDEwIH0gfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsCi0gICAgICBuZXcgY2hhcltdeyAweDRFQUMsIDB4NTE0NiwgMHg1MTA0LCAweDRFMDcsIDB4NTM0MywgMHg3NjdlLCAweDUzNDEgfSB9LAotCi0gICAgLy8gY2hpbmVzZSBvbmx5Pz8KLSAgICB7ICJ6ZXJvIiwgbmV3IGNoYXJbMF0gfSwKLSAgICB7ICJkaWdpdHMiLAotICAgICAgbmV3IGNoYXJbXXsgMHg0RTAwLCAweDRFOEMsIDB4NEUwOSwgMHg1NkRCLCAweDRFOTQsIDB4NTE2RCwgMHg0RTAzLAotICAgICAgICAgICAgICAgICAgMHg1MTZCLCAweDRFNUQgfSB9LCB7ICJ0YWJsZXMiLCBuZXcgU3RyaW5nW117ICJkaWdpdHMiIH0gfQotICB9OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3Jlcy9YUmVzb3VyY2VzX2thLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfa2EuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzc2ZWUyYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfa2EuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyNiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5yZXMuWFJlc291cmNlQnVuZGxlOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8vCi0vLyAgTGFuZ1Jlc291cmNlc19lbi5wcm9wZXJ0aWVzCi0vLwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogVGhlIEdlb3JnaWFuIHJlc291cmNlIGJ1bmRsZS4KLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfa2EgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIGNvbnRlbnRzOwotICB9Ci0KLSAgLyoqIFRoZSBhc3NvY2lhdGlvbiBsaXN0LiAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgT2JqZWN0W11bXSBjb250ZW50cyA9Ci0gIHsKLSAgICB7ICJ1aV9sYW5ndWFnZSIsICJrYSIgfSwgeyAiaGVscF9sYW5ndWFnZSIsICJrYSIgfSwgeyAibGFuZ3VhZ2UiLCAia2EiIH0sCi0gICAgeyAiYWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgMHgxMEQwLCAweDEwRDEsIDB4MTBEMiwgMHgxMEQzLCAweDEwRDQsIDB4MTBENSwgMHgxMEQ2LAotICAgICAgICAgICAgICAgICAgMHgxMGYxLCAweDEwRDcsIDB4MTBEOCwgMHgxMEQ5LCAweDEwREEsIDB4MTBEQiwgMHgxMERDLAotICAgICAgICAgICAgICAgICAgMHgxMGYyLCAweDEwREQsIDB4MTBERSwgMHgxMERGLCAweDEwRTAsIDB4MTBFMSwgMHgxMEUyLAotICAgICAgICAgICAgICAgICAgMHgxMEUzLCAweDEwRTQsIDB4MTBFNSwgMHgxMEU2LCAweDEwRTcsIDB4MTBFOCwgMHgxMEU5LAotICAgICAgICAgICAgICAgICAgMHgxMEVBLCAweDEwRUIsIDB4MTBFQywgMHgxMEVELCAweDEwRUUsIDB4MTBGNCwgMHgxMEVGLAotICAgICAgICAgICAgICAgICAgMHgxMEYwIH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uCi0gICAgeyAib3JpZW50YXRpb24iLCAiTGVmdFRvUmlnaHQiIH0sCi0KLSAgICAvL2xhbmd1YWdlIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlcmluZyIsICJhZGRpdGl2ZSIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwMDApfSwKLSAgICAvL1RoZXNlIHdvdWxkIG5vdCBiZSB1c2VkIGZvciBFTi4gT25seSB1c2VkIGZvciB0cmFkaXRpb25hbCBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJHcm91cHMiLCBuZXcgaW50W117IDEwMDAsIDEwMCwgMTAsIDEgfSB9LAotCi0gICAgLy9UaGVzZSB1c2VkIGZvciBhZGRpdGl2ZSBudW1iZXJpbmcKLSAgICB7ICJkaWdpdHMiLAotICAgICAgbmV3IGNoYXJbXXsgMHgxMEQwLCAweDEwRDEsIDB4MTBEMiwgMHgxMEQzLCAweDEwRDQsIDB4MTBENSwgMHgxMEQ2LAotICAgICAgICAgICAgICAgICAgMHgxMGYxLCAweDEwRDcgfSB9LAotICAgIHsgInRlbnMiLAotICAgICAgbmV3IGNoYXJbXXsgMHgxMEQ4LCAweDEwRDksIDB4MTBEQSwgMHgxMERCLCAweDEwREMsIDB4MTBmMiwgMHgxMERELAotICAgICAgICAgICAgICAgICAgMHgxMERFLCAweDEwREYgfSB9LAotICAgIHsgImh1bmRyZWRzIiwKLSAgICAgIG5ldyBjaGFyW117IDB4MTBFMCwgMHgxMEUxLCAweDEwRTIsIDB4MTBFMywgMHgxMEU0LCAweDEwRTUsIDB4MTBFNiwKLSAgICAgICAgICAgICAgICAgIDB4MTBFNywgMHgxMEU4IH0gfSwKLSAgICB7ICJ0aG91c2FuZHMiLAotICAgICAgbmV3IGNoYXJbXXsgMHgxMEU5LCAweDEwRUEsIDB4MTBFQiwgMHgxMEVDLCAweDEwRUQsIDB4MTBFRSwgMHgxMEY0LAotICAgICAgICAgICAgICAgICAgMHgxMEVGLCAweDEwRjAgfSB9LAotICAgIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdbXXsgInRob3VzYW5kcyIsICJodW5kcmVkcyIsICJ0ZW5zIiwgImRpZ2l0cyIgfSB9Ci0gIH07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfemhfQ04uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc196aF9DTi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZWE1OTEwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc196aF9DTi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGUgQ2hpbmVzZSByZXNvdXJjZSBidW5kbGUuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUmVzb3VyY2VzX3poX0NOIGV4dGVuZHMgWFJlc291cmNlQnVuZGxlCi17Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotCi0gIC8qKiBUaGUgYXNzb2NpYXRpb24gbGlzdC4gICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPQotICB7Ci0gICAgeyAidWlfbGFuZ3VhZ2UiLCAiemgiIH0sIHsgImhlbHBfbGFuZ3VhZ2UiLCAiemgiIH0sIHsgImxhbmd1YWdlIiwgInpoIiB9LAotICAgIHsgImFscGhhYmV0IiwKLSAgICAgIG5ldyBjaGFyW117IDB4ZmYyMSwgMHhmZjIyLCAweGZmMjMsIDB4ZmYyNCwgMHhmZjI1LCAweGZmMjYsIDB4ZmYyNywKLSAgICAgICAgICAgICAgICAgIDB4ZmYyOCwgMHhmZjI5LCAweGZmMmEsIDB4ZmYyYiwgMHhmZjJjLCAweGZmMmQsIDB4ZmYyZSwKLSAgICAgICAgICAgICAgICAgIDB4ZmYyZiwgMHhmZjMwLCAweGZmMzEsIDB4ZmYzMiwgMHhmZjMzLCAweGZmMzQsIDB4ZmYzNSwKLSAgICAgICAgICAgICAgICAgIDB4ZmYzNiwgMHhmZjM3LCAweGZmMzgsIDB4ZmYzOSwgMHhmZjNhIH0gfSwKLSAgICB7ICJ0cmFkQWxwaGFiZXQiLAotICAgICAgbmV3IGNoYXJbXXsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJywgJ0cnLCAnSCcsICdJJywgJ0onLCAnSycsICdMJywKLSAgICAgICAgICAgICAgICAgICdNJywgJ04nLCAnTycsICdQJywgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsCi0gICAgICAgICAgICAgICAgICAnWScsICdaJyB9IH0sCi0KLSAgICAvL2xhbmd1YWdlIG9yaWVudGF0aW9uIAotICAgIHsgIm9yaWVudGF0aW9uIiwgIkxlZnRUb1JpZ2h0IiB9LAotCi0gICAgLy9sYW5ndWFnZSBudW1iZXJpbmcgICAKLSAgICB7ICJudW1iZXJpbmciLCAibXVsdGlwbGljYXRpdmUtYWRkaXRpdmUiIH0sCi0gICAgeyAibXVsdGlwbGllck9yZGVyIiwgImZvbGxvd3MiIH0sCi0KLSAgICAvLyBsYXJnZXN0IG51bWVyaWNhbCB2YWx1ZQotICAgIC8veyJNYXhOdW1lcmljYWxWYWx1ZSIsIG5ldyBJbnRlZ2VyKDEwMDAwMDAwMCl9LAotICAgIC8vVGhlc2Ugd291bGQgbm90IGJlIHVzZWQgZm9yIEVOLiBPbmx5IHVzZWQgZm9yIHRyYWRpdGlvbmFsIG51bWJlcmluZyAgIAotICAgIHsgIm51bWJlckdyb3VwcyIsIG5ldyBpbnRbXXsgMSB9IH0sCi0KLSAgICAvLyBzaW1wbGlmaWVkIGNoaW5lc2UgIAotICAgIHsgInplcm8iLCBuZXcgY2hhcltdeyAweDk2ZjYgfSB9LAotCi0gICAgLy9UaGVzZSBvbmx5IHVzZWQgZm9yIG11dGlwbGljYXRpdmUtYWRkaXRpdmUgbnVtYmVyaW5nCi0gICAgeyAibXVsdGlwbGllciIsIG5ldyBpbnRbXXsgMTAwMDAwMDAwLCAxMDAwMCwgMTAwMCwgMTAwLCAxMCB9IH0sCi0gICAgeyAibXVsdGlwbGllckNoYXIiLAotICAgICAgbmV3IGNoYXJbXXsgMHg0ZWJmLCAweDRlMDcsIDB4NTM0MywgMHg3NjdlLCAweDUzNDEgfSB9LAotICAgIHsgImRpZ2l0cyIsCi0gICAgICBuZXcgY2hhcltdeyAweDRlMDAsIDB4NGU4YywgMHg0ZTA5LCAweDU2ZGIsIDB4NGU5NCwgMHg1MTZkLCAweDRlMDMsCi0gICAgICAgICAgICAgICAgICAweDUxNmIsIDB4NGU1ZCB9IH0sIHsgInRhYmxlcyIsIG5ldyBTdHJpbmdbXXsgImRpZ2l0cyIgfSB9Ci0gIH07Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvcmVzL1hSZXNvdXJjZXNfemhfVFcuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc196aF9UVy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkOGQwZDM0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9yZXMvWFJlc291cmNlc196aF9UVy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnJlcy5YUmVzb3VyY2VCdW5kbGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLy8KLS8vICBMYW5nUmVzb3VyY2VzX2VuLnByb3BlcnRpZXMKLS8vCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGUgQ2hpbmVzZShUYWl3YW4pIHJlc291cmNlIGJ1bmRsZS4KLSAqLwotcHVibGljIGNsYXNzIFhSZXNvdXJjZXNfemhfVFcgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIGNvbnRlbnRzOwotICB9Ci0KLSAgLyoqIFRoZSBhc3NvY2lhdGlvbiBsaXN0LiAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgInpoIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgInpoIiB9LCB7ICJsYW5ndWFnZSIsICJ6aCIgfSwKLSAgICB7ICJhbHBoYWJldCIsCi0gICAgICBuZXcgY2hhcltdeyAweGZmMjEsIDB4ZmYyMiwgMHhmZjIzLCAweGZmMjQsIDB4ZmYyNSwgMHhmZjI2LCAweGZmMjcsCi0gICAgICAgICAgICAgICAgICAweGZmMjgsIDB4ZmYyOSwgMHhmZjJhLCAweGZmMmIsIDB4ZmYyYywgMHhmZjJkLCAweGZmMmUsCi0gICAgICAgICAgICAgICAgICAweGZmMmYsIDB4ZmYzMCwgMHhmZjMxLCAweGZmMzIsIDB4ZmYzMywgMHhmZjM0LCAweGZmMzUsCi0gICAgICAgICAgICAgICAgICAweGZmMzYsIDB4ZmYzNywgMHhmZjM4LCAweGZmMzksIDB4ZmYzYSB9IH0sCi0gICAgeyAidHJhZEFscGhhYmV0IiwKLSAgICAgIG5ldyBjaGFyW117ICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLCAnSScsICdKJywgJ0snLCAnTCcsCi0gICAgICAgICAgICAgICAgICAnTScsICdOJywgJ08nLCAnUCcsICdRJywgJ1InLCAnUycsICdUJywgJ1UnLCAnVicsICdXJywgJ1gnLAotICAgICAgICAgICAgICAgICAgJ1knLCAnWicgfSB9LAotCi0gICAgLy9sYW5ndWFnZSBvcmllbnRhdGlvbiAKLSAgICB7ICJvcmllbnRhdGlvbiIsICJMZWZ0VG9SaWdodCIgfSwKLQotICAgIC8vbGFuZ3VhZ2UgbnVtYmVyaW5nICAgIAotICAgIHsgIm51bWJlcmluZyIsICJtdWx0aXBsaWNhdGl2ZS1hZGRpdGl2ZSIgfSwKLSAgICB7ICJtdWx0aXBsaWVyT3JkZXIiLCAiZm9sbG93cyIgfSwKLQotICAgIC8vIGxhcmdlc3QgbnVtZXJpY2FsIHZhbHVlCi0gICAgLy97Ik1heE51bWVyaWNhbFZhbHVlIiwgbmV3IEludGVnZXIoMTAwMDAwMDAwKX0sCi0gICAgLy9UaGVzZSB3b3VsZCBub3QgYmUgdXNlZCBmb3IgRU4uIE9ubHkgdXNlZCBmb3IgdHJhZGl0aW9uYWwgbnVtYmVyaW5nICAgCi0gICAgeyAibnVtYmVyR3JvdXBzIiwgbmV3IGludFtdeyAxIH0gfSwKLQotICAgIC8vIHNpbXBsaWZpZWQgY2hpbmVzZSAKLSAgICB7ICJ6ZXJvIiwgbmV3IGNoYXJbXXsgMHg5NmY2IH0gfSwKLQotICAgIC8vVGhlc2Ugb25seSB1c2VkIGZvciBtdXRpcGxpY2F0aXZlLWFkZGl0aXZlIG51bWJlcmluZyAKLSAgICB7ICJtdWx0aXBsaWVyIiwgbmV3IGludFtdeyAxMDAwMDAwMDAsIDEwMDAwLCAxMDAwLCAxMDAsIDEwIH0gfSwKLSAgICB7ICJtdWx0aXBsaWVyQ2hhciIsCi0gICAgICBuZXcgY2hhcltdeyAweDUxMDQsIDB4ODQyYywgMHg0ZWRmLCAweDRmNzAsIDB4NjJmZSB9IH0sCi0gICAgeyAiZGlnaXRzIiwKLSAgICAgIG5ldyBjaGFyW117IDB4NThmOSwgMHg4Y2IzLCAweDUzYzMsIDB4ODA4NiwgMHg0ZjBkLCAweDk2NzgsIDB4NjdkMiwKLSAgICAgICAgICAgICAgICAgIDB4NjM0YywgMHg3Mzk2IH0gfSwgeyAidGFibGVzIiwgbmV3IFN0cmluZ1tdeyAiZGlnaXRzIiB9IH0KLSAgfTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvQ2xhc3MuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvQ2xhc3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjFlNjgxZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL0NsYXNzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTgxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYzsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5TeW50aGVzaXNFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb24uQ29uc3RydWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb24uTWV0aG9kOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5yZWZsZWN0aW9uLkZpZWxkOwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7Ci0KLS8qIFdPUksgTkVFREVEOgotICAgIEZhY3Rvcmllcy9MaWJyYXJpZXM6IFdlIGN1cnJlbnRseSBoYXZlIGZvckNsYXNzIGFuZAotICAgIGZvck5hbWUocmVxdWVzdCByZWlmaWVkLCBjb21wbGFpbiBpZiBubyByZWFsIGNsYXNzKSwKLSAgICBhbmQgZGVjbGFyZUNsYXNzIChyZXF1ZXN0IHVucmVpZmllZCwgY3JlYXRlIHVucmVpZmllZAotICAgIGlmIGl0IGRvZXNuJ3QgZXhpc3QpLiBXaGF0IGFib3V0IHRoZXIgdXNlciBleHBlY3RhdGlvbnMKLSAgICAtLSBzaG91bGQgd2UgaGF2ZSBhIGZ1bGwgbWF0cml4LCByYXRoZXIgdGhhbiBhc2tpbmcKLSAgICB1c2VycyB0byB3cml0ZSB3cmFwcGVycz8KLQotICAgIFJlZmxlY3Rpb24gZG9lc24ndCB0ZWxsIHVzIGFib3V0IGRlcHJlY2F0aW9uLiBJZiB3ZSB3YW50Ci0gICAgdGhhdCBpbmZvLCBNRkMgYWR2aXNlcyBtb3VzaW5nIG91ciB3YXkgaW50byB0aGUgYnl0ZWNvZGVzLgotICAgIChVZ2gpLiBTaG91bGQgd2UgYXQgbGVhc3QgbW9kZWwgdGhhdCBmb3Igc3ludGhldGljcz8KLSovCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgaXMgYSBtdXRhYmxlIGVxdWl2YWxlbnQgb2YgamF2YS5sYW5nLkNsYXNzLgotICogSW5zdGFuY2VzIHJlcHJlc2VudCBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIGluIGEgcnVubmluZyBKYXZhCi0gKiBhcHBsaWNhdGlvbiwgb3IgY2xhc3MgZGVzY3JpcHRpb25zIHVuZGVyIGNvbnN0cnVjdGlvbi4gSW4gdGhlCi0gKiBmb3JtZXIgY2FzZSwgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIG9wZXJhdGVzIGFzIGEgcHJveHkgZm9yIHRoZQotICogInJlYWwiIGphdmEubGFuZy5DbGFzcyBvYmplY3Q7IGluIHRoZSBsYXR0ZXIsIGl0IGNvbnN1bHRzCi0gKiBkYXRhIHN0cnVjdHVyZXMgZGVmaW5lZCBpbiB0aGUgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb24uKiBwYWNrYWdlLgotICogPHA+Ci0gKiBVbmxpa2UgamF2YS5sYW5nLkNsYXNzLCBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgaGFzIGEgcGFpciBvZiBmYWN0b3JpZXMKLSAqIChmcm9tTmFtZSBhbmQgZnJvbUNsYXNzKS4gSXQgY2FuIGFsc28gYmUgc3dpdGNoZWQgZnJvbSBzeW50aGV0aWMKLSAqIHRvIHByb3h5IG9wZXJhdGlvbiBhZnRlciBjb25zdHJ1Y3Rpb24sIGJ5IHNldHRpbmcgdGhlIHJlYWxDbGFzcwotICogcHJvcGVydHk7IHRoaXMgaXMgaW50ZW5kZWQgdG8gYWxsb3cgdGhlc2UgZGVmaW5pdGlvbnMgdG8gYmUKLSAqICJjb21waWxlZCBpbiBwbGFjZSIuCi0gKiA8cD4KLSAqIEZvciBjb252ZW5pZW50IHVzZSwgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGltcGxlbWVudHMgYW4gZXh0ZW5kZWQKLSAqIHZlcnNpb24gb2YgdGhlIGphdmEubGFuZy5DbGFzcyBBUEkgLS0gYnV0IGlzIG5vdCBhIHN1YmNsYXNzCi0gKiB0aGVyZW9mLCBzaW5jZSBqYXZhLmxhbmcuQ2xhc3MgaXMgRmluYWwgKHByZXN1bWFibHkgZm9yCi0gKiBzZWN1cml0eSByZWFzb25zKS4KLSAqIDxwPgotICogREVWRUxPUE1FTlQgTk9URTogTWV0aG9kcyBub3QgeWV0IGltcGxlbWVudGVkIHdpbGwgdGhyb3cKLSAqIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotICogPHA+Ci0gKiAgIEkndmUgYWRkZWQgY29kZSB0byBjb252ZXJ0IHByaW1pdGl2ZSBuYW1lcyBpbnRvIHRoZWlyIFRZUEVzLAotICogICB0byBhY2NlcHQgZm9vW10gYXMgYSBzeW5vbnltIGZvciBbTGZvbywgYW5kIHRvIGdlbmVyYXRlCi0gKiAgIHRoZSByaWdodCB0aGluZyBvbiBvdXRwdXQgKGdldEphdmFbU2hvcnRdTmFtZSkuCi0gKiAgIFVzZWZ1bCBleHRlbnNpb24gZm9yIGNvZGUgZ2VuZXJhdGlvbiBmcm9tIEphdmEtbGlrZQotICogICBzb3VyY2UuIFdlIG1heSB3YW50IHRvIGZhY3RvciB0aGVzZSBhbmQgdG9Tb3VyY2Ugb3V0LCBtYWtpbmcKLSAqICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGFkZGVzcyBvbmx5IHRoZSBKVk0gbGV2ZWwgYW5kIHByb3ZpZGluZwotICogICBzdWJjbGFzc2VzIG9yIGFjY2VzcyB0b29scyB0aGF0IGhhbmRsZSBsYW5ndWFnZSBzeW50YXgKLSAqICAgKEphdmEgc291cmNlLCBOZXRSZXh4IHNvdXJjZSwgZXRjLikKLSAqCi0gKiBAc2luY2UgIDIwMDAvMi8xMAotICovCi1wdWJsaWMgY2xhc3MgQ2xhc3MgZXh0ZW5kcyBPYmplY3QgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZQotewotCi0gIC8qKiBDbGFzcyBkZXNjcmlwdGlvbnMgY3VycmVudGx5IGV4aXN0aW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBqYXZhLnV0aWwuSGFzaHRhYmxlIGdsb2JhbF9jbGFzc3RhYmxlID0KLSAgICBuZXcgamF2YS51dGlsLkhhc2h0YWJsZSgpOwotCi0gIC8qKiBmdWxseS1xdWFsaWZpZWQgcGF0aC5jbGFzc25hbWUuCi0gICAqICBAc2VyaWFsICovCi0gIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwotCi0gIC8qKgotICAgKiBBY3R1YWwgSmF2YSBjbGFzcyBvYmplY3QuIFdoZW4gcHJlc2VudCwgYWxsIGludGVyYWN0aW9ucwotICAgKiBhcmUgcmVkaXJlY3RlZCB0byBpdC4gQWxsb3dzIG91ciBDbGFzcyB0byBmdW5jdGlvbiBhcyBhCi0gICAqIHdyYXBwZXIgZm9yIHRoZSBKYXZhIHZlcnNpb24gKGluIGxpZXUgb2Ygc3ViY2xhc3Npbmcgb3IKLSAgICogYSBzaGFyZWQgSW50ZXJmYWNlKSwgYW5kIGFsbG93cyAiaW4tcGxhY2UgY29tcGlsYXRpb24iCi0gICAqIHRvIHJlcGxhY2UgYSBnZW5lcmF0ZWQgZGVzY3JpcHRpb24gd2l0aCBhbgotICAgKiBkaXJlY3RseSBydW5uYWJsZSBjbGFzcy4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBqYXZhLmxhbmcuQ2xhc3MgcmVhbGNsYXNzID0gbnVsbDsKLQotICAvKiogRmllbGQgbW9kaWZpZXJzOiBKYXZhIGxhbmd1YWdlIG1vZGlmaWVycyBmb3IgdGhpcyBjbGFzcyAKLSAgICogb3IgaW50ZXJmYWNlLCBlbmNvZGVkIGluIGFuIGludGVnZXIuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByaXZhdGUgaW50IG1vZGlmaWVyczsKLQotICAvKiogRmllbGQgaXNJbnRlcmZhY2U6IFRydWUgaWYgdGhlIENsYXNzIG9iamVjdCByZXByZXNlbnRzCi0gICAqICBhbiBpbnRlcmZhY2UgdHlwZS4KLSAgICogQHNlcmlhbCAqLwotICBwcml2YXRlIGJvb2xlYW4gaXNJbnRlcmZhY2UgPSBmYWxzZTsKLQotICAvKiogRmllbGQgc3VwZXJjbGFzczogIElmIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMgdGhlIGNsYXNzCi0gICAqIE9iamVjdCwgdGhpcyBpcyBudWxsLiBPdGhlcndpc2UsIHRoZSBDbGFzcyBvYmplY3QgdGhhdCAKLSAgICogcmVwcmVzZW50cyB0aGUgc3VwZXJjbGFzcyBvZiB0aGF0IGNsYXNzLiBJbiBwcm94eSBtb2RlIHRoaXMKLSAgICogaXMgZGV0ZXJtaW5lZCB3aGVuIG5lZWRlZC4gSW4gc3ludGhlc2lzIG1vZGUgaXQncyBleHBsaWNpdGx5Ci0gICAqIHNldCBieSB0aGUgdXNlciwgYW5kIGlmIG51bGwgdGhlIHN1cGVyY2xhc3Mgd2lsbCBiZSBhc3N1bWVkCi0gICAqIHRvIGJlIE9iamVjdC4KLSAgICogQHNlcmlhbCAqLwotICBwcml2YXRlIENsYXNzIHN1cGVyY2xhc3MgPSBudWxsOwotCi0gIC8qKiBGaWVsZCBkZWNsYXJpbmdjbGFzczogSWYgdGhpcyBvYmplY3QgcmVwcmVzZW50cyBhbiBpbm5lciBjbGFzcywKLSAgICogdGhlIENsYXNzIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGNsYXNzIHRoYXQgZGVjbGFyZWQgaXQuCi0gICAqIE90aGVyd2lzZSBudWxsLgotICAgKiBAc2VyaWFsCi0gICAqICovCi0gIHByaXZhdGUgQ2xhc3MgZGVjbGFyaW5nY2xhc3MgPSBudWxsOwotCi0gIC8qKiBGaWVsZCBpbnRlcmZhY2VzOiBBIGxpc3Qgb2YgYWxsIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgdGhlIGNsYXNzIAotICAgKiBvciBpbnRlcmZhY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QuCi0gICAqIEBzZXJpYWwKLSAgICogICovCi0gIHByaXZhdGUgQ2xhc3NbXSBpbnRlcmZhY2VzID0gbmV3IENsYXNzWzBdOwotCi0gIC8qKiBGaWVsZCBhbGxjbGFzc2VzOiAgYW4gYXJyYXkgY29udGFpbmluZyBDbGFzcyBvYmplY3RzIHJlcHJlc2VudGluZyBhbGwgCi0gICAqIHRoZSBwdWJsaWMgY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyB0aGF0IGFyZSBtZW1iZXJzIG9mIHRoZSBjbGFzcyAKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuIAotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIENsYXNzW10gYWxsY2xhc3NlcyA9IG5ldyBDbGFzc1swXTsKLQotICAvKiogRmllbGQgZGVjbGFyZWRjbGFzc2VzOiBhbiBhcnJheSBvZiBDbGFzcyBvYmplY3RzIHJlZmxlY3RpbmcgYWxsIHRoZSAKLSAgICogY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyBkZWNsYXJlZCBhcyBtZW1iZXJzIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCAKLSAgICogYnkgdGhpcyBDbGFzcyBvYmplY3QuIEV4Y2x1ZGVzIGluaGVyaXRlZCBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIENsYXNzW10gZGVjbGFyZWRjbGFzc2VzID0gbmV3IENsYXNzWzBdOwotCi0gIC8qKiBGaWVsZCBhbGxjb25zdHJ1Y3RvcnM6IGFuIGFycmF5IGNvbnRhaW5pbmcgQ29uc3RydWN0b3Igb2JqZWN0cwotICAgKiByZWZsZWN0aW5nIGFsbCB0aGUgY29uc3RydWN0b3JzIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZCAKLSAgICogYnkgdGhpcyBDbGFzcyBvYmplY3QuIEFuIGFycmF5IG9mIGxlbmd0aCAwIGlzIHJldHVybmVkIGlmIHRoZQotICAgKiBjbGFzcyBoYXMgbm8gcHVibGljIGNvbnN0cnVjdG9ycy4gSW4gcHJveHkgbW9kZSBvbmx5IHB1YmxpYwotICAgKiBjb25zdHJ1Y3RvcnMgd2lsbCBiZSBkaXNwbGF5ZWQ7IGluIHN5bnRoZXNpcyBtb2RlLCBhbGwgZGVjbGFyZWQKLSAgICogY29uc3RydWN0b3JzIHdpbGwgYmUgZGlzcGxheWVkLgotICAgKiBAc2VyaWFsCi0gICAqICovCi0gIHByaXZhdGUgQ29uc3RydWN0b3JbXSBhbGxjb25zdHJ1Y3RvcnMgPSBuZXcgQ29uc3RydWN0b3JbMF07Ci0KLSAgLyoqIEZpZWxkIGRlY2xhcmVkY29uc3RydWN0b3JzOiBhbiBhcnJheSBvZiBDb25zdHJ1Y3RvciBvYmplY3RzIAotICAgKiByZWZsZWN0aW5nIGFsbCB0aGUgY29uc3RydWN0b3JzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcyAKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuIEluY2x1ZGVzIG5vbi1wdWJsaWMKLSAgICogY29uc3RydWN0b3JzLCBidXQgZXhjbHVkZXMgaW5oZXJpdGVkIG9uZXMuCi0gICAqIEBzZXJpYWwKLSAgICogICovCi0gIHByaXZhdGUgQ29uc3RydWN0b3JbXSBkZWNsYXJlZGNvbnN0cnVjdG9ycyA9IG5ldyBDb25zdHJ1Y3RvclswXTsKLQotICAvKiogRmllbGQgYWxsbWV0aG9kcy4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBNZXRob2RbXSBhbGxtZXRob2RzID0gbmV3IE1ldGhvZFswXTsKLQotICAvKiogRmllbGQgZGVjbGFyZWRtZXRob2RzLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIE1ldGhvZFtdIGRlY2xhcmVkbWV0aG9kcyA9IG5ldyBNZXRob2RbMF07Ci0KLSAgLyoqIEZpZWxkIGFsbGZpZWxkcy4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBGaWVsZFtdIGFsbGZpZWxkcyA9IG5ldyBGaWVsZFswXTsKLQotICAvKiogRmllbGQgZGVjbGFyZWRmaWVsZHMuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByaXZhdGUgRmllbGRbXSBkZWNsYXJlZGZpZWxkcyA9IG5ldyBGaWVsZFswXTsKLQotICAvKiogRmllbGQgaW5uZXJjbGFzc2VzLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIENsYXNzW10gaW5uZXJjbGFzc2VzID0gbmV3IENsYXNzWzBdOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBzeW50aGV0aWMgY2xhc3MgYXMgcHJveHkvd3JhcHBlciBmb3IgYW4gZXhpc3RpbmcKLSAgICogSmF2YSBDbGFzcy4gTm9uLXB1YmxpYzsgbW9zdCBmb2xrcyBzaG91bGQgdXNlCi0gICAqIC5mb3JOYW1lIGFuZCAuZm9yQ2xhc3MgdG8gcmVxdWVzdCB0aGVzZSB3cmFwcGVycywgc28gdGhleQotICAgKiBnZXQgdGhlIHNoYXJlZCBpbnN0YW5jZXMuCi0gICAqIDxwPgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjUtOTkgMTI6MTY6MTUgUE0pCi0gICAqIEBwYXJhbSByZWFsY2xhc3MgamF2YS5sYW5nLkNsYXNzCi0gICAqLwotICBDbGFzcyhqYXZhLmxhbmcuQ2xhc3MgcmVhbGNsYXNzKQotICB7Ci0KLSAgICB0aGlzKHJlYWxjbGFzcy5nZXROYW1lKCkpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgc2V0UmVhbENsYXNzKHJlYWxjbGFzcyk7Ci0gICAgfQotICAgIGNhdGNoIChTeW50aGVzaXNFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBuYW1lZC1idXQtZW1wdHkgc3ludGhldGljIENsYXNzIG9iamVjdC4KLSAgICogTm9uLXB1YmxpYzsgbW9zdCBmb2xrcyBzaG91bGQgdXNlCi0gICAqIC5mb3JOYW1lIGFuZCAuZm9yQ2xhc3MgdG8gcmVxdWVzdCB0aGVzZSB3cmFwcGVycywgc28gdGhleQotICAgKiBnZXQgdGhlIHNoYXJlZCBpbnN0YW5jZXMuCi0gICAqIDxwPgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjUtOTkgMTI6MTU6MjMgUE0pCi0gICAqCi0gICAqIEBwYXJhbSBmdWxsbmFtZSBmdWxsIG5hbWUgb2YgdGhlIGNsYXNzIHRoYXQgaXMgc3ludGhldGl6ZWQuCi0gICAqLwotICBDbGFzcyhTdHJpbmcgZnVsbG5hbWUpCi0gIHsKLQotICAgIHRoaXMubmFtZSA9IGZ1bGxuYW1lOwotCi0gICAgZ2xvYmFsX2NsYXNzdGFibGUucHV0KGZ1bGxuYW1lLCB0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBzeW50aGV0aWMgQ2xhc3Mgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgInJlYWwiCi0gICAqIGNsYXNzIHNwZWNpZmllZCwgY3JlYXRpbmcgb25lIGlmIGl0IGRpZG4ndCBhbHJlYWR5IGV4aXN0LgotICAgKiA8cD4KLSAgICogRm9yIGV4YW1wbGUsIHRoZSBmb2xsb3dpbmcgY29kZSBmcmFnbWVudCByZXR1cm5zCi0gICAqIHRoZSBydW50aW1lIENsYXNzIGRlc2NyaXB0b3IgZm9yIHRoZSBjbGFzcyBuYW1lZAotICAgKiBteXBhY2thZ2UuTXlDbGFzcy4KLSAgICogPGNvZGU+Ci0gICAqIENsYXNzIHQgPQotICAgKiBDbGFzcy5mb3JOYW1lKGphdmEubGFuZy5DbGFzcy5mb3JOYW1lKCJteXBhY2thZ2UuTXlDbGFzcyIpKQotICAgKiA8L2NvZGU+Ci0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgaWYgdGhlIHVzZXIgaGFzIG1hbnVhbGx5IGNyZWF0ZWQgYSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MKLSAgICogd2l0aCB0aGUgc2FtZSBuYW1lIGJlZm9yZSB0aGlzIGNhbGwgaXMgaXNzdWVkLCB0aGF0IG9iamVjdAotICAgKiB3aWxsIGJlIGZvdW5kIGluc3RlYWQuIFNlZSBhbHNvIHRoZSBkZWNsYXJlQ2xhc3MgY2FsbC4KLSAgICogPHA+Ci0gICAqICBXZSBuZWVkIGEgYmV0dGVyIHdheSB0byBkZWNsYXJlL2RlZmluZSBhcnJheSBjbGFzc2VzLAotICAgKiBnaXZlbiBhIGNsYXNzIG9iamVjdCAoc3ludGhldGljIG9yIG5vdCkuCi0gICAqCi0gICAqIEBwYXJhbSBjbHMgdGhlIGRlc2lyZWQgSmF2YSBjbGFzcy4KLSAgICogQHJldHVybiB0aGUgc3ludGhldGljIENsYXNzIGRlc2NyaXB0b3IgZm9yIHRoZSBzcGVjaWZpZWQgY2xhc3MuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIENsYXNzIGZvckNsYXNzKGphdmEubGFuZy5DbGFzcyBjbHMpCi0gIHsKLQotICAgIGlmIChjbHMgPT0gbnVsbCkKLSAgICAgIHJldHVybiBudWxsOwotCi0gICAgQ2xhc3MgcmV0ID0gKENsYXNzKSAoZ2xvYmFsX2NsYXNzdGFibGUuZ2V0KGNscy5nZXROYW1lKCkpKTsKLQotICAgIGlmIChudWxsID09IHJldCkKLSAgICAgIHJldCA9IG5ldyBDbGFzcyhjbHMpOwotCi0gICAgcmV0dXJuIHJldDsKLSAgfQotCi0gIC8qKgotICAgKiBMaWtlIGZvck5hbWUsIGJ1dCBpZiB0aGUgY2xhc3NuYW1lIGRvZXNuJ3QgaGF2ZSBhIHBhY2thZ2UKLSAgICogcHJlZml4IHdlIGZpcnN0IGF0dGVtcHQgdG8gbG9vayBpdCB1cCBhcyBvbmUgb2Ygb3VyIG93bgotICAgKiBpbm5lciBjbGFzZXMuIEFzIHdpdGggZm9yTmFtZSwgaWYgdGhpcyBjYW4gbm90IGJlIHJlc29sdmVkCi0gICAqIHdlIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGNsYXNzbmFtZSB0aGUgZnVsbCBvciBwYXJ0aWFsIGNsYXNzIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIENsYXNzIG5hbWUgdGhhdCBtYXRjaGVzIHRoZSBhcmd1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgQ2xhc3MgZm9yTmFtZUluQ29udGV4dChTdHJpbmcgY2xhc3NuYW1lKQotICAgICAgICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCi0gIHsKLQotICAgIGZvciAoaW50IGkgPSBpbm5lcmNsYXNzZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpCi0gICAgewotICAgICAgaWYgKGNsYXNzbmFtZS5lcXVhbHMoaW5uZXJjbGFzc2VzW2ldLmdldFNob3J0TmFtZSgpKSkKLSAgICAgICAgcmV0dXJuIGlubmVyY2xhc3Nlc1tpXTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZm9yTmFtZShjbGFzc25hbWUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIHN5bnRoZXRpYyBDbGFzcyBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBjbGFzcwotICAgKiB3aXRoIHRoZSBnaXZlbiBmdWxseS1xdWFsaWZpZWQgbmFtZS4gSWYgdGhlcmUgaXNuJ3Qgb25lLCB0aGlzCi0gICAqIG1ldGhvZCBhdHRlbXB0cyB0byBsb2NhdGUsIGxvYWQgYW5kIGxpbmsgdGhlIHN0YW5kYXJkIGphdmEgQ2xhc3MuCi0gICAqIElmIGl0IHN1Y2NlZWRzLCBpdCByZXR1cm5zIGEgd3JhcHBlZCB2ZXJzaW9uIG9mIHRoZSBDbGFzcyBvYmplY3QKLSAgICogcmVwcmVzZW50aW5nIHRoZSBjbGFzcy4gSWYgaXQgZmFpbHMsIHRoZSBtZXRob2QgdGhyb3dzIGEKLSAgICogQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbi4KLSAgICogPHA+Ci0gICAqIEZvciBleGFtcGxlLCB0aGUgZm9sbG93aW5nIGNvZGUgZnJhZ21lbnQgcmV0dXJucwotICAgKiB0aGUgcnVudGltZSBDbGFzcyBkZXNjcmlwdG9yIGZvciB0aGUgY2xhc3MgbmFtZWQKLSAgICogbXlwYWNrYWdlLk15Q2xhc3MgLS0gZWl0aGVyIGFzIGEgc3ludGhldGljIG9yIGFzCi0gICAqIGEgc3RhbmRhcmQgSmF2YSBjbGFzcy4KLSAgICogPGNvZGU+Ci0gICAqIENsYXNzIHQgPQotICAgKiBDbGFzcy5mb3JOYW1lKCJteXBhY2thZ2UuTXlDbGFzcyIpCi0gICAqIDwvY29kZT4KLSAgICogPHA+Ci0gICAqICBJJ3ZlIGFkZGVkIHN1cHBvcnQgZm9yIGFycmF5cyAtLSBhc3N1bWluZyBhbnkgbmFtZQotICAgKiB0aGF0IGVuZHMgd2l0aCAnXScgaXMgYW4gYXJyYXkuIEl0IHByb2JhYmx5IG5lZWRzIHRvIGJlCi0gICAqIG1hZGUgc21hcnRlciwgcG9zc2libHkgdmlhIGEgc3ViY2xhc3Mgb2Ygb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzLgotICAgKgotICAgKiBAcGFyYW0gY2xhc3NOYW1lIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZGVzaXJlZCBjbGFzcy4KLSAgICogQHJldHVybiB0aGUgc3ludGhldGljIENsYXNzIGRlc2NyaXB0b3IgZm9yIHRoZSBjbGFzcyB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS4KLSAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBjb3VsZCBub3QgYmUgZm91bmQuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIENsYXNzIGZvck5hbWUoU3RyaW5nIGNsYXNzTmFtZSkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgewotCi0gICAgLy8gKioqKiogRXhwZXJpbWVudGFsIHN1cHBvcnQgZm9yIGFycmF5IHN5bnRheCBleHByZXNzZWQKLSAgICAvLyBwZXIgSmF2YSBzb3VyY2UgcmF0aGVyIHRoYW4gcGVyIEpWTSB0eXBlIGZvcm1hbGlzbS4KLSAgICAvLyBTaW1wbGVtaW5kZWQsIGFzc3N1bWVzIGJhbGFuY2VkIFtdJ3MuCi0gICAgaWYgKGNsYXNzTmFtZS5lbmRzV2l0aCgiXSIpKQotICAgIHsKLSAgICAgIFN0cmluZ0J1ZmZlciBhcnJheW5hbWUgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSBjbGFzc05hbWUuaW5kZXhPZignWycpOyBpICE9IC0xOwotICAgICAgICAgICAgICBpID0gY2xhc3NOYW1lLmluZGV4T2YoJ1snLCBpICsgMSkpCi0gICAgICB7Ci0gICAgICAgIGFycmF5bmFtZS5hcHBlbmQoJ1snKTsKLSAgICAgIH0KLQotICAgICAgLy8gQ29udmVydCB0aGUgY2xhc3NuYW1lIHRvIGFycmF5LWZvcm1hbGlzbQotICAgICAgLy8gUHJpbWl0aXZlcyBoYXZlIGxldHRlcnM7IG9iamVjdHMgYXJlIExuYW1lOwotICAgICAgLy8gKERvbid0IGFzayB3aHkgbG9uZyBpcyBzcGVsbGVkIHdpdGggYSBKIGFuZAotICAgICAgLy8gb2JqZWN0IGlzIHNwZWxsZWQgd2l0aCBhbiBMLi4uKQotICAgICAgU3RyaW5nIGNsYXNzbmFtZSA9IGNsYXNzTmFtZS5zdWJzdHJpbmcoMCwgY2xhc3NOYW1lLmluZGV4T2YoJ1snKSk7Ci0KLSAgICAgIGlmICgiYnl0ZSIuZXF1YWxzKGNsYXNzbmFtZSkpCi0gICAgICAgIGFycmF5bmFtZS5hcHBlbmQoJ0InKTsKLSAgICAgIGVsc2UgaWYgKCJjaGFyIi5lcXVhbHMoY2xhc3NuYW1lKSkKLSAgICAgICAgYXJyYXluYW1lLmFwcGVuZCgnQycpOwotICAgICAgZWxzZSBpZiAoImRvdWJsZSIuZXF1YWxzKGNsYXNzbmFtZSkpCi0gICAgICAgIGFycmF5bmFtZS5hcHBlbmQoJ0QnKTsKLSAgICAgIGVsc2UgaWYgKCJmbG9hdCIuZXF1YWxzKGNsYXNzbmFtZSkpCi0gICAgICAgIGFycmF5bmFtZS5hcHBlbmQoJ0YnKTsKLSAgICAgIGVsc2UgaWYgKCJpbnQiLmVxdWFscyhjbGFzc25hbWUpKQotICAgICAgICBhcnJheW5hbWUuYXBwZW5kKCdJJyk7Ci0gICAgICBlbHNlIGlmICgibG9uZyIuZXF1YWxzKGNsYXNzbmFtZSkpCi0gICAgICAgIGFycmF5bmFtZS5hcHBlbmQoJ0onKTsKLSAgICAgIGVsc2UgaWYgKCJzaG9ydCIuZXF1YWxzKGNsYXNzbmFtZSkpCi0gICAgICAgIGFycmF5bmFtZS5hcHBlbmQoJ1MnKTsKLSAgICAgIGVsc2UgaWYgKCJib29sZWFuIi5lcXVhbHMoY2xhc3NuYW1lKSkKLSAgICAgICAgYXJyYXluYW1lLmFwcGVuZCgnWicpOwotICAgICAgZWxzZQotICAgICAgICBhcnJheW5hbWUuYXBwZW5kKCdMJykuYXBwZW5kKGNsYXNzbmFtZSkuYXBwZW5kKCc7Jyk7Ci0KLSAgICAgIC8vIFRhaWwtY2FsbC4KLSAgICAgIHJldHVybiBmb3JOYW1lKGFycmF5bmFtZS50b1N0cmluZygpKTsKLSAgICB9Ci0KLSAgICBDbGFzcyByZXQgPSAoQ2xhc3MpIChnbG9iYWxfY2xhc3N0YWJsZS5nZXQoY2xhc3NOYW1lKSk7Ci0KLSAgICBpZiAobnVsbCA9PSByZXQpCi0gICAgewotCi0gICAgICAvLyAqKioqKiBFeHBlcmltZW50YWwgc3VwcG9ydCBmb3IgSmF2YSBwcmltaXRpdmVzCi0gICAgICAvLyBTZWVtcyB0byBtZSB0aGF0IG1hcHBpbmcgdGhlbSBpbnRvIHRoZSAiVHlwZSIgaXMKLSAgICAgIC8vIHByb2JhYmx5IG1vc3QgdXNlZnVsCi0gICAgICBpZiAoImJvb2xlYW4iLmVxdWFscyhjbGFzc05hbWUpKQotICAgICAgewotICAgICAgICByZXQgPSBuZXcgQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgcmV0LnJlYWxjbGFzcyA9IGphdmEubGFuZy5Cb29sZWFuLlRZUEU7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICgiYnl0ZSIuZXF1YWxzKGNsYXNzTmFtZSkpCi0gICAgICB7Ci0gICAgICAgIHJldCA9IG5ldyBDbGFzcyhjbGFzc05hbWUpOwotICAgICAgICByZXQucmVhbGNsYXNzID0gamF2YS5sYW5nLkJ5dGUuVFlQRTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCJjaGFyIi5lcXVhbHMoY2xhc3NOYW1lKSkKLSAgICAgIHsKLSAgICAgICAgcmV0ID0gbmV3IENsYXNzKGNsYXNzTmFtZSk7Ci0gICAgICAgIHJldC5yZWFsY2xhc3MgPSBqYXZhLmxhbmcuQ2hhcmFjdGVyLlRZUEU7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICgic2hvcnQiLmVxdWFscyhjbGFzc05hbWUpKQotICAgICAgewotICAgICAgICByZXQgPSBuZXcgQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgcmV0LnJlYWxjbGFzcyA9IGphdmEubGFuZy5TaG9ydC5UWVBFOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoImludCIuZXF1YWxzKGNsYXNzTmFtZSkpCi0gICAgICB7Ci0gICAgICAgIHJldCA9IG5ldyBDbGFzcyhjbGFzc05hbWUpOwotICAgICAgICByZXQucmVhbGNsYXNzID0gamF2YS5sYW5nLkludGVnZXIuVFlQRTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCJsb25nIi5lcXVhbHMoY2xhc3NOYW1lKSkKLSAgICAgIHsKLSAgICAgICAgcmV0ID0gbmV3IENsYXNzKGNsYXNzTmFtZSk7Ci0gICAgICAgIHJldC5yZWFsY2xhc3MgPSBqYXZhLmxhbmcuTG9uZy5UWVBFOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoImZsb2F0Ii5lcXVhbHMoY2xhc3NOYW1lKSkKLSAgICAgIHsKLSAgICAgICAgcmV0ID0gbmV3IENsYXNzKGNsYXNzTmFtZSk7Ci0gICAgICAgIHJldC5yZWFsY2xhc3MgPSBqYXZhLmxhbmcuRmxvYXQuVFlQRTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCJkb3VibGUiLmVxdWFscyhjbGFzc05hbWUpKQotICAgICAgewotICAgICAgICByZXQgPSBuZXcgQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgcmV0LnJlYWxjbGFzcyA9IGphdmEubGFuZy5Eb3VibGUuVFlQRTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKCJ2b2lkIi5lcXVhbHMoY2xhc3NOYW1lKSkKLSAgICAgIHsKLQotICAgICAgICAvLyAqKioqKiBWb2lkIGlzIGFuICJhYnNlbmNlIG9mIHR5cGUiLiBXZSBtaWdodCB3YW50IHRvIGNyZWF0ZQotICAgICAgICAvLyBhIHNwZWNpYWwgb2JqZWN0IHRvIHJlcHJlc2VudCBpdC4gVGhpcyBpcyBhIHBsYWNlaG9sZGVyLgotICAgICAgICByZXQgPSBuZXcgQ2xhc3MoY2xhc3NOYW1lKTsKLSAgICAgICAgcmV0LnJlYWxjbGFzcyA9IGphdmEubGFuZy5DbGFzcy5mb3JOYW1lKCJqYXZhLmxhbmcuT2JqZWN0Iik7Ci0gICAgICB9Ci0KLSAgICAgIC8vIE90aGVyIGNsYXNzZXMgYXJlIGp1c3Qgd3JhcHBlcmVkLiBVbmtub3duIGNsYXNzZXMgdGhyb3cgYQotICAgICAgLy8gQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbjsgdGhlIHVzZXIgY2FuIHN3aXRjaCB0byBkZWNsYXJlQ2xhc3MoKQotICAgICAgLy8gaWYgdGhleSdyZSBzdXJlIHRoYXQgYW4gdW5yZWlmaWVkIGNsYXNzIGlzIE9LLiAKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0ID0gbmV3IENsYXNzKGphdmEubGFuZy5DbGFzcy5mb3JOYW1lKGNsYXNzTmFtZSkpOwotICAgIH0KLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgdG8gY3JlYXRlIGEgc3ludGhldGljIENsYXNzIHdpdGggdGhlIGdpdmVuIGZ1bGx5LXF1YWxpZmllZAotICAgKiBuYW1lLiAgSWYgYSBDbGFzcyBieSB0aGF0IG5hbWUgYWxyZWFkeSBleGlzdHMsIGFuZCBpdCBpcyBub3QKLSAgICogcmVpZmllZCwgaXQgd2lsbCBiZSByZXR1cm5lZCBpbnN0ZWFkLiBJZiBhIHJlaWZpZWQgQ2xhc3MgX2RvZXNfCi0gICAqIGV4aXN0LCB3ZSB0aHJvdyBhIHN5bnRoZXNpcyBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc05hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBkZXNpcmVkIGNsYXNzLgotICAgKiBAcmV0dXJuIHRoZSBzeW50aGV0aWMgQ2xhc3MgZGVzY3JpcHRvciBmb3IgdGhlIGNsYXNzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbiBpZiB0aGUgY2xhc3MgaGFzIGJlZW4gcmVpZmllZC4gIAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBDbGFzcyBkZWNsYXJlQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBDbGFzcyByZXQgPSAoQ2xhc3MpIChnbG9iYWxfY2xhc3N0YWJsZS5nZXQoY2xhc3NOYW1lKSk7Ci0KLSAgICBpZiAobnVsbCA9PSByZXQpCi0gICAgICByZXQgPSBuZXcgQ2xhc3MoY2xhc3NOYW1lKTsKLQotICAgIGlmIChyZXQucmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICAvKioKLSAgICogU3RhcnQgdG8gY3JlYXRlIGEgc3ludGhldGljIENsYXNzIHdpdGggdGhlIGdpdmVuIGZ1bGx5LXF1YWxpZmllZAotICAgKiBuYW1lLiAgSWYgYSBDbGFzcyBieSB0aGF0IG5hbWUgYWxyZWFkeSBleGlzdHMsd2hldGhlciByZWlmaWVkIG9yCi0gICAqIG5vdCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIHRhYmxlIGFuZCByZXBsYWNlZCBieSB0aGUgbmV3IHN5bnRoZXNpcy4KLSAgICoKLSAgICogIE5PVEUgVEhBVCB0aGUgcmVwbGFjZW1lbnQgd2lsbCBub3QgYWZmZWN0IGNsYXNzZXMgd2hpY2gKLSAgICogaGF2ZSBhbHJlYWR5IHJlZmVybmNlZCB0aGUgb2xkIHZlcnNpb24uIFdlIGNvdWxkIGNoYW5nZSB0aGF0IGJ5Ci0gICAqIGhhdmluZyBldmVyeW9uZSByZWZlcmVuY2UgZXZlcnlvbmUgZWxzZSB2aWEgYW4gaW5kaXJlY3Rpb24gdGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc05hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBkZXNpcmVkIGNsYXNzLgotICAgKiBAcmV0dXJuIHRoZSBzeW50aGV0aWMgQ2xhc3MgZGVzY3JpcHRvciBmb3IgdGhlIGNsYXNzIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBDbGFzcyByZWFsbHlEZWNsYXJlQ2xhc3MoU3RyaW5nIGNsYXNzTmFtZSkKLSAgewotCi0gICAgQ2xhc3MgcmV0ID0gKENsYXNzKSAoZ2xvYmFsX2NsYXNzdGFibGUuZ2V0KGNsYXNzTmFtZSkpOwotCi0gICAgaWYgKG51bGwgIT0gcmV0KQotICAgICAgZ2xvYmFsX2NsYXNzdGFibGUucmVtb3ZlKHJldCk7Ci0KLSAgICByZXQgPSBuZXcgQ2xhc3MoY2xhc3NOYW1lKTsKLQotICAgIHJldHVybiByZXQ7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIENsYXNzIG9iamVjdHMKLSAgICogcmVwcmVzZW50aW5nIGFsbCB0aGUgcHVibGljIGNsYXNzZXMgYW5kIGludGVyZmFjZXMKLSAgICogdGhhdCBhcmUgbWVtYmVycyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBDbGFzcyBvYmplY3QuIFRoaXMgaW5jbHVkZXMgcHVibGljIGNsYXNzIGFuZAotICAgKiBpbnRlcmZhY2UgbWVtYmVycyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMgYW5kCi0gICAqIHB1YmxpYyBjbGFzcyBhbmQgaW50ZXJmYWNlIG1lbWJlcnMgZGVjbGFyZWQgYnkgdGhlCi0gICAqIGNsYXNzLiBSZXR1cm5zIGFuIGFycmF5IG9mIGxlbmd0aCAwIGlmIHRoZSBjbGFzcyBoYXMKLSAgICogbm8gcHVibGljIG1lbWJlciBjbGFzc2VzIG9yIGludGVyZmFjZXMsIG9yIGlmIHRoaXMKLSAgICogQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZS4KLSAgICogPHA+Ci0gICAqIE5PVEU6IEluIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9mIGV4aXN0aW5nIEphdmEgZW52aXJvbm1lbnRzLAotICAgKiB0aGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQgYnkgdGhlIG9mZmljaWFsIENsYXNzIG9iamVjdAotICAgKiBhbmQgYWx3YXlzIHJldHVybnMgYW4gZW1wdHkgYXJyYXkuIFNvIGlmIHlvdSBkb24ndCBnZXQgYW55Ci0gICAqIHVzZWZ1bCBpbmZvcm1hdGlvbiBmcm9tIGEgcHJveGllZCBqYXZhLmxhbmcuQ2xhc3MsIGRvbid0Ci0gICAqIGJlIHN1cnByaXNlZC4gSSdtIG5vdCBzdXJlIGlmIHNvbWVvbmUgZGVjaWRlZCBpdCB3YXMgYQotICAgKiBwb3RlbnRpYWwgc2VjdXJpdHkgaXNzdWUsIG9yIGlmIFN1biB3YXMgbGF6eSBhbmQgZXZlcnlvbmUKLSAgICogZWxzZSBmb2xsb3dlZCBzdWl0LgotICAgKiA8cD4KLSAgICogQUxTTyBOT1RFOiBUaGUgYWJvdmUgc3BlYywgYXMgdGFrZW4gZnJvbSBqYXZhLmxhbmcuQ2xhc3MsCi0gICAqIGRvZXNuJ3QgcHJvdmlkZSBhbnkgZ29vZCB3YXkgdG8gZGlzdGluZ3Vpc2ggdGhlIGltbWVkaWF0ZQotICAgKiBzdXBlcmNsYXNzIGZyb20gYWxsIG90aGVyIHN1cGVyY2xhc3Nlcy4gVGhhdCBtYWtlcyBpdCBvbmx5Ci0gICAqIG1hcmdpbmFsbHkgdXNlZnVsLCB3aGljaCBpcyBubyBkb3VidCBvbmUgb2YgdGhlIHJlYXNvbnMgZm9sa3MKLSAgICogaGF2ZSBkZWNsaW5lZCB0byBpbXBsZW1lbnQgaXQuCi0gICAqCi0gICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgY2xhc3Nlcy4KLSAgICovCi0gIHB1YmxpYyBDbGFzc1tdIGdldENsYXNzZXMoKQotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwgJiYgYWxsY2xhc3NlcyA9PSBudWxsKQotICAgIHsKLSAgICAgIGphdmEubGFuZy5DbGFzc1tdIHJlYWxERSA9IHJlYWxjbGFzcy5nZXRDbGFzc2VzKCk7Ci0KLSAgICAgIGFsbGNsYXNzZXMgPSBuZXcgQ2xhc3NbcmVhbERFLmxlbmd0aF07Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVhbERFLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBhbGxjbGFzc2VzW2ldID0gZm9yQ2xhc3MocmVhbERFW2ldKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWxsY2xhc3NlczsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmVzIHRoZSBjbGFzcyBsb2FkZXIgZm9yIHRoZSBjbGFzcy4KLSAgICoKLSAgICogdGhlIGNsYXNzIGxvYWRlciB0aGF0IGNyZWF0ZWQgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCwgb3IgbnVsbAotICAgKiBpZiB0aGUgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIHdhcyBub3QgY3JlYXRlZCBieSBhIGNsYXNzIGxvYWRlci4KLSAgICovCi0gIHB1YmxpYyBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcigpCi0gIHsKLSAgICByZXR1cm4gKHJlYWxjbGFzcyA9PSBudWxsKSA/IG51bGwgOiByZWFsY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiB0aGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gYXJyYXkgdHlwZSwgcmV0dXJucyB0aGUKLSAgICogQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29tcG9uZW50IHR5cGUgb2YKLSAgICogdGhlIGFycmF5OyBvdGhlcndpc2UgcmV0dXJucyBudWxsLgotICAgKiA8cD4KLSAgICogTk9URTogU2luY2Ugb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGRvZXNuJ3QgeWV0IGF0dGVtcHQgdG8gbW9kZWwgYXJyYXkKLSAgICogdHlwZXMsIHRoaXMgd2lsbCBjdXJyZW50bHkgcmV0dXJuIGZhbHNlIHVubGVzcyB3ZSBhcmUKLSAgICogcHJveHlpbmcgc3VjaCBhIHR5cGUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIENsYXNzIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGNvbXBvbmVudCB0eXBlIG9mCi0gICAqIHRoZSBhcnJheSwgb3RoZXJ3aXNlIHJldHVybnMgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBDbGFzcyBnZXRDb21wb25lbnRUeXBlKCkKLSAgewotICAgIHJldHVybiByZWFsY2xhc3MgPT0gbnVsbCA/IG51bGwgOiBuZXcgQ2xhc3MocmVhbGNsYXNzLmdldENvbXBvbmVudFR5cGUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIENvbnN0cnVjdG9yIG9iamVjdCB0aGF0IHJlZmxlY3RzIHRoZQotICAgKiBzcGVjaWZpZWQgcHVibGljIGNvbnN0cnVjdG9yIG9mIHRoZSBjbGFzcwotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdC4gVGhlCi0gICAqIHBhcmFtZXRlclR5cGVzIHBhcmFtZXRlciBpcyBhbiBhcnJheSBvZiBDbGFzcwotICAgKiBvYmplY3RzIHRoYXQgaWRlbnRpZnkgdGhlIGNvbnN0cnVjdG9yJ3MgZm9ybWFsCi0gICAqIHBhcmFtZXRlciB0eXBlcywgaW4gZGVjbGFyZWQgb3JkZXIuCi0gICAqIDxwPgotICAgKiBUaGUgY29uc3RydWN0b3IgdG8gcmVmbGVjdCBpcyBsb2NhdGVkIGJ5IHNlYXJjaGluZwotICAgKiBhbGwgdGhlIGNvbnN0cnVjdG9ycyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBDbGFzcyBvYmplY3QgZm9yIGEgcHVibGljIGNvbnN0cnVjdG9yIHdpdGggdGhlCi0gICAqIGV4YWN0bHkgdGhlIHNhbWUgZm9ybWFsIHBhcmFtZXRlciB0eXBlcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBhcmFtZXRlclR5cGVzIGFycmF5IG9mIENsYXNzCi0gICAqIG9iamVjdHMgdGhhdCBpZGVudGlmeSB0aGUgY29uc3RydWN0b3IncyBmb3JtYWwKLSAgICogcGFyYW1ldGVyIHR5cGVzLCBpbiBkZWNsYXJlZCBvcmRlci4KLSAgICoKLSAgICogQHJldHVybiBhIENvbnN0cnVjdG9yIG9iamVjdCB0aGF0IHJlZmxlY3RzIHRoZQotICAgKiBzcGVjaWZpZWQgcHVibGljIGNvbnN0cnVjdG9yIG9mIHRoZSBjbGFzcwotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdC4KLSAgICogCi0gICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uCi0gICAqIGlmIGEgbWF0Y2hpbmcgbWV0aG9kIGlzIG5vdCBmb3VuZC4KLSAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgotICAgKiBpZiBhY2Nlc3MgdG8gdGhlIGluZm9ybWF0aW9uIGlzIGRlbmllZC4KLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBDb25zdHJ1Y3RvciBnZXRDb25zdHJ1Y3RvcihDbGFzcyBwYXJhbWV0ZXJUeXBlc1tdKQotICAgICAgICAgIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24sIFNlY3VyaXR5RXhjZXB0aW9uLCBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyA9PSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uVU5SRUlGSUVEKTsKLQotICAgIGphdmEubGFuZy5DbGFzc1tdIHJlYWwgPSBuZXcgamF2YS5sYW5nLkNsYXNzW3BhcmFtZXRlclR5cGVzLmxlbmd0aF07Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtZXRlclR5cGVzLmxlbmd0aDsgKytpKQotICAgIHsKLSAgICAgIGlmICgocmVhbFtpXSA9IHBhcmFtZXRlclR5cGVzW2ldLmdldFJlYWxDbGFzcygpKSA9PSBudWxsKQotICAgICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5VTlJFSUZJRUQpOwotICAgIH0KLQotICAgIHJldHVybiBuZXcgQ29uc3RydWN0b3IocmVhbGNsYXNzLmdldENvbnN0cnVjdG9yKHJlYWwpLCB0aGlzKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgQ29uc3RydWN0b3Igb2JqZWN0cwotICAgKiByZWZsZWN0aW5nIGFsbCB0aGUgcHVibGljIGNvbnN0cnVjdG9ycyBvZiB0aGUgY2xhc3MKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuIEFuIGFycmF5IG9mIGxlbmd0aAotICAgKiAwIGlzIHJldHVybmVkIGlmIHRoZSBjbGFzcyBoYXMgbm8gcHVibGljCi0gICAqIGNvbnN0cnVjdG9ycy4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIENvbnN0cnVjdG9yIG9iamVjdHMKLSAgICogcmVmbGVjdGluZyBhbGwgdGhlIHB1YmxpYyBjb25zdHJ1Y3RvcnMgb2YgdGhlIGNsYXNzCi0gICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0LgotICAgKiAKLSAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgotICAgKiBpZiBhY2Nlc3MgdG8gdGhlIGluZm9ybWF0aW9uIGlzIGRlbmllZC4KLSAgICovCi0gIHB1YmxpYyBDb25zdHJ1Y3RvcltdIGdldENvbnN0cnVjdG9ycygpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwgJiYgYWxsY29uc3RydWN0b3JzID09IG51bGwpCi0gICAgewotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3JbXSByZWFsREMgPSByZWFsY2xhc3MuZ2V0Q29uc3RydWN0b3JzKCk7Ci0KLSAgICAgIGFsbGNvbnN0cnVjdG9ycyA9IG5ldyBDb25zdHJ1Y3RvcltyZWFsREMubGVuZ3RoXTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWFsREMubGVuZ3RoOyArK2kpCi0gICAgICB7Ci0gICAgICAgIGFsbGNvbnN0cnVjdG9yc1tpXSA9IG5ldyBDb25zdHJ1Y3RvcihyZWFsRENbaV0sIHRoaXMpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBhbGxjb25zdHJ1Y3RvcnM7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGluIFZBSkFWQSAzLjAKLSAgICogPHA+Ci0gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgQ2xhc3Mgb2JqZWN0cyByZWZsZWN0aW5nIGFsbCB0aGUKLSAgICogY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyBkZWNsYXJlZCBhcyBtZW1iZXJzIG9mIHRoZQotICAgKiBjbGFzcyByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdC4gVGhpcwotICAgKiBpbmNsdWRlcyBwdWJsaWMsIHByb3RlY3RlZCwgZGVmYXVsdCAocGFja2FnZSkKLSAgICogYWNjZXNzLCBhbmQgcHJpdmF0ZSBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzIGRlY2xhcmVkCi0gICAqIGJ5IHRoZSBjbGFzcywgYnV0IGV4Y2x1ZGVzIGluaGVyaXRlZCBjbGFzc2VzIGFuZAotICAgKiBpbnRlcmZhY2VzLiBSZXR1cm5zIGFuIGFycmF5IG9mIGxlbmd0aCAwIGlmIHRoZSBjbGFzcwotICAgKiBkZWNsYXJlcyBubyBjbGFzc2VzIG9yIGludGVyZmFjZXMgYXMgbWVtYmVycywgb3IgaWYKLSAgICogdGhpcyBDbGFzcyBvYmplY3QgcmVwcmVzZW50cyBhIHByaW1pdGl2ZSB0eXBlLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIENsYXNzIG9iamVjdHMgcmVmbGVjdGluZyBhbGwgdGhlCi0gICAqIGNsYXNzZXMgYW5kIGludGVyZmFjZXMgZGVjbGFyZWQgYXMgbWVtYmVycyBvZiB0aGUKLSAgICogY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuCi0gICAqIAotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIENsYXNzW10gZ2V0RGVjbGFyZWRDbGFzc2VzKCkgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gIHsKLQotICAgIC8vICoqKioqIFRoaXMgc2hvdWxkIHJlYWxseSBiZSBhIHNpbmdsZSBjbGFzcyBwbHVzIGRlY2xhcmVkIGludGVyZmFjZXMuCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsICYmIGRlY2xhcmVkY2xhc3NlcyA9PSBudWxsKQotICAgIHsKLSAgICAgIGphdmEubGFuZy5DbGFzc1tdIHJlYWxERSA9IHJlYWxjbGFzcy5nZXREZWNsYXJlZENsYXNzZXMoKTsKLQotICAgICAgZGVjbGFyZWRjbGFzc2VzID0gbmV3IENsYXNzW3JlYWxERS5sZW5ndGhdOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlYWxERS5sZW5ndGg7ICsraSkKLSAgICAgIHsKLSAgICAgICAgZGVjbGFyZWRjbGFzc2VzW2ldID0gZm9yQ2xhc3MocmVhbERFW2ldKTsKLQotICAgICAgICBpZiAoIXJlYWxERVtpXS5pc0ludGVyZmFjZSgpKQotICAgICAgICAgIHN1cGVyY2xhc3MgPSBkZWNsYXJlZGNsYXNzZXNbaV07Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGRlY2xhcmVkY2xhc3NlczsKLSAgfQotCi0gIC8qKgotICAgKiBBZGRzIGFuICJleHRlbmRzIiBkZXNjcmlwdGlvbiBmb3IgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdAotICAgKgotICAgKiBAcGFyYW0gbmV3Y2xhc3MgVGhlIGNsYXNzIHRoYXQgdGhpcyBjbGFzcyBleHRlbmRzLgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgY2xhc3MgaGFzIGJlZW4gcmVpZmllZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEV4dGVuZHMoQ2xhc3MgbmV3Y2xhc3MpIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uUkVJRklFRCk7Ci0KLSAgICBDbGFzc1tdIHNjcmF0Y2ggPSBuZXcgQ2xhc3NbZGVjbGFyZWRjbGFzc2VzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShkZWNsYXJlZGNsYXNzZXMsIDAsIHNjcmF0Y2gsIDAsIGRlY2xhcmVkY2xhc3Nlcy5sZW5ndGgpOwotCi0gICAgc2NyYXRjaFtkZWNsYXJlZGNsYXNzZXMubGVuZ3RoXSA9IG5ld2NsYXNzOwotICAgIGRlY2xhcmVkY2xhc3NlcyA9IHNjcmF0Y2g7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhIENvbnN0cnVjdG9yIG9iamVjdCB0aGF0IHJlZmxlY3RzIHRoZQotICAgKiBzcGVjaWZpZWQgZGVjbGFyZWQgY29uc3RydWN0b3Igb2YgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdC4gVGhlCi0gICAqIHBhcmFtZXRlclR5cGVzIHBhcmFtZXRlciBpcyBhbiBhcnJheSBvZiBDbGFzcwotICAgKiBvYmplY3RzIHRoYXQgaWRlbnRpZnkgdGhlIGNvbnN0cnVjdG9yJ3MgZm9ybWFsCi0gICAqIHBhcmFtZXRlciB0eXBlcywgaW4gZGVjbGFyZWQgb3JkZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwYXJhbWV0ZXJUeXBlcyBhcnJheSBvZiBDbGFzcwotICAgKiBvYmplY3RzIHRoYXQgaWRlbnRpZnkgdGhlIGNvbnN0cnVjdG9yJ3MgZm9ybWFsCi0gICAqIHBhcmFtZXRlciB0eXBlcywgaW4gZGVjbGFyZWQgb3JkZXIuCi0gICAqCi0gICAqIEByZXR1cm4gYSBDb25zdHJ1Y3RvciBvYmplY3QgdGhhdCByZWZsZWN0cyB0aGUKLSAgICogc3BlY2lmaWVkIGRlY2xhcmVkIGNvbnN0cnVjdG9yIG9mIHRoZSBjbGFzcyBvcgotICAgKiBpbnRlcmZhY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuCi0gICAqIAotICAgKiBAdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbgotICAgKiBpZiBhIG1hdGNoaW5nIG1ldGhvZCBpcyBub3QgZm91bmQuCi0gICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KLSAgICogaWYgYWNjZXNzIHRvIHRoZSBpbmZvcm1hdGlvbiBpcyBkZW5pZWQuCi0gICAqLwotICBwdWJsaWMgQ29uc3RydWN0b3IgZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcihDbGFzcyBwYXJhbWV0ZXJUeXBlc1tdKQotICAgICAgICAgIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24sIFNlY3VyaXR5RXhjZXB0aW9uCi0gIHsKLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZHMgYSBDb25zdHJ1Y3RvciBkZXNjcmlwdGlvbiBmb3IgIHRoZSBjbGFzcyBvcgotICAgKiBpbnRlcmZhY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QKLSAgICoKLSAgICogQHJldHVybiBUaGUgY29uc3RydWN0b3Igb2JqZWN0LgotICAgKiAKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICogaWYgdGhlIGNsYXNzIGhhcyBiZWVuIHJlaWZpZWQuCi0gICAqLwotICBwdWJsaWMgQ29uc3RydWN0b3IgZGVjbGFyZUNvbnN0cnVjdG9yKCkgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIENvbnN0cnVjdG9yIG5ld2N0b3IgPSBuZXcgQ29uc3RydWN0b3IodGhpcyk7Ci0gICAgQ29uc3RydWN0b3JbXSBzY3JhdGNoID0gbmV3IENvbnN0cnVjdG9yW2RlY2xhcmVkY29uc3RydWN0b3JzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShkZWNsYXJlZGNvbnN0cnVjdG9ycywgMCwgc2NyYXRjaCwgMCwKLSAgICAgICAgICAgICAgICAgICAgIGRlY2xhcmVkY29uc3RydWN0b3JzLmxlbmd0aCk7Ci0KLSAgICBzY3JhdGNoW2RlY2xhcmVkY29uc3RydWN0b3JzLmxlbmd0aF0gPSBuZXdjdG9yOwotICAgIGRlY2xhcmVkY29uc3RydWN0b3JzID0gc2NyYXRjaDsKLSAgICBzY3JhdGNoID0gbmV3IENvbnN0cnVjdG9yW2FsbGNvbnN0cnVjdG9ycy5sZW5ndGggKyAxXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkoYWxsY29uc3RydWN0b3JzLCAwLCBzY3JhdGNoLCAwLCBhbGxjb25zdHJ1Y3RvcnMubGVuZ3RoKTsKLQotICAgIHNjcmF0Y2hbYWxsY29uc3RydWN0b3JzLmxlbmd0aF0gPSBuZXdjdG9yOwotICAgIGFsbGNvbnN0cnVjdG9ycyA9IHNjcmF0Y2g7Ci0KLSAgICByZXR1cm4gbmV3Y3RvcjsKLSAgfQotCi0gIC8qKgotICAgKiBTdGF0ZSB0aGF0IHRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIHNwZWNpZmllZCBpbnRlcmZhY2UuCi0gICAqIFRoaXMgZG9lcyBub3QgeWV0IHVwZGF0ZSBhbGxNZXRob2RzIG9yIG90aGVyd2lzZQotICAgKiBhdHRlbXB0IHRvIGluaGVyaXQgZGF0YS4KLSAgICoKLSAgICogQHBhcmFtIG5ld2lmY2Ugb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIHJlcHJlc2VudGluZyB0aGUgaW50ZXJmYWNlIHdlIHdhbnQgdG8gYWRkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXcgaW50ZXJmYWNlIGNsYXNzLgotICAgKiAKLSAgICogQHRocm93cyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuU3ludGhlc2lzRXhjZXB0aW9uIGlmIHRoZSBDbGFzcyBpc24ndCBhbiBpbnRlcmZhY2UKLSAgICovCi0gIHB1YmxpYyBDbGFzcyBkZWNsYXJlSW50ZXJmYWNlKENsYXNzIG5ld2lmY2UpIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uUkVJRklFRCk7Ci0KLSAgICBpZiAoIW5ld2lmY2UuaXNJbnRlcmZhY2UoKSkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlNZTlRBWCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3aWZjZS5nZXROYW1lKCkgKyAiIGlzbid0IGFuIGludGVyZmFjZSIpOwotCi0gICAgQ2xhc3NbXSBzY3JhdGNoID0gbmV3IENsYXNzW2ludGVyZmFjZXMubGVuZ3RoICsgMV07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGludGVyZmFjZXMsIDAsIHNjcmF0Y2gsIDAsIGludGVyZmFjZXMubGVuZ3RoKTsKLQotICAgIHNjcmF0Y2hbaW50ZXJmYWNlcy5sZW5ndGhdID0gbmV3aWZjZTsKLSAgICBpbnRlcmZhY2VzID0gc2NyYXRjaDsKLSAgICBzY3JhdGNoID0gbmV3IENsYXNzW2FsbGNsYXNzZXMubGVuZ3RoICsgMV07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGFsbGNsYXNzZXMsIDAsIHNjcmF0Y2gsIDAsIGFsbGNsYXNzZXMubGVuZ3RoKTsKLQotICAgIHNjcmF0Y2hbYWxsY2xhc3Nlcy5sZW5ndGhdID0gbmV3aWZjZTsKLSAgICBhbGxjbGFzc2VzID0gc2NyYXRjaDsKLQotICAgIHJldHVybiBuZXdpZmNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgQ29uc3RydWN0b3Igb2JqZWN0cyByZWZsZWN0aW5nCi0gICAqIGFsbCB0aGUgY29uc3RydWN0b3JzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcwotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdC4gVGhlc2UgYXJlIHB1YmxpYywKLSAgICogcHJvdGVjdGVkLCBkZWZhdWx0IChwYWNrYWdlKSBhY2Nlc3MsIGFuZCBwcml2YXRlCi0gICAqIGNvbnN0cnVjdG9ycy4gUmV0dXJucyBhbiBhcnJheSBvZiBsZW5ndGggMCBpZiB0aGlzCi0gICAqIENsYXNzIG9iamVjdCByZXByZXNlbnRzIGFuIGludGVyZmFjZSBvciBhIHByaW1pdGl2ZQotICAgKiB0eXBlLgotICAgKiA8cD4KLSAgICogU2VlIFRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sIHNlY3Rpb24gOC4yLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIENvbnN0cnVjdG9yIG9iamVjdHMgcmVmbGVjdGluZwotICAgKiBhbGwgdGhlIGNvbnN0cnVjdG9ycyBkZWNsYXJlZCBieSB0aGUgY2xhc3MKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuCi0gICAqIAotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIENvbnN0cnVjdG9yW10gZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcnMoKSB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsICYmIGRlY2xhcmVkY29uc3RydWN0b3JzID09IG51bGwpCi0gICAgewotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3JbXSByZWFsREMgPQotICAgICAgICByZWFsY2xhc3MuZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcnMoKTsKLQotICAgICAgZGVjbGFyZWRjb25zdHJ1Y3RvcnMgPSBuZXcgQ29uc3RydWN0b3JbcmVhbERDLmxlbmd0aF07Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVhbERDLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBkZWNsYXJlZGNvbnN0cnVjdG9yc1tpXSA9IG5ldyBDb25zdHJ1Y3RvcihyZWFsRENbaV0sIHRoaXMpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBkZWNsYXJlZGNvbnN0cnVjdG9yczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgRmllbGQgb2JqZWN0IHRoYXQgcmVmbGVjdHMgdGhlIHNwZWNpZmllZAotICAgKiBkZWNsYXJlZCBmaWVsZCBvZiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIHJlcHJlc2VudGVkCi0gICAqIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0LiBUaGUgbmFtZSBwYXJhbWV0ZXIgaXMgYQotICAgKiBTdHJpbmcgdGhhdCBzcGVjaWZpZXMgdGhlIHNpbXBsZSBuYW1lIG9mIHRoZSBkZXNpcmVkCi0gICAqIGZpZWxkLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBTdHJpbmcgdGhhdCBzcGVjaWZpZXMgdGhlIHNpbXBsZSBuYW1lIG9mIHRoZSBkZXNpcmVkCi0gICAqIGZpZWxkLgotICAgKgotICAgKiBAcmV0dXJuIGEgRmllbGQgb2JqZWN0IHRoYXQgcmVmbGVjdHMgdGhlIHNwZWNpZmllZAotICAgKiBkZWNsYXJlZCBmaWVsZCBvZiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIHJlcHJlc2VudGVkCi0gICAqIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0LgotICAgKiAKLSAgICogQHRocm93cyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbgotICAgKiBpZiBhIGZpZWxkIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGlzIG5vdCBmb3VuZC4KLSAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgotICAgKiBpZiBhY2Nlc3MgdG8gdGhlIGluZm9ybWF0aW9uIGlzIGRlbmllZC4KLSAgICovCi0gIHB1YmxpYyBGaWVsZCBnZXREZWNsYXJlZEZpZWxkKFN0cmluZyBuYW1lKQotICAgICAgICAgIHRocm93cyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbiwgU2VjdXJpdHlFeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogQWRkcyBhIEZpZWxkIGRlc2NyaXB0aW9uIGZvciAgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdAotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmllbGQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGZpZWxkIGRlc2NyaXB0aW9uLgotICAgKiAKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICogaWYgdGhlIGNsYXNzIGhhcyBiZWVuIHJlaWZpZWQuCi0gICAqLwotICBwdWJsaWMgRmllbGQgZGVjbGFyZUZpZWxkKFN0cmluZyBuYW1lKSB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgRmllbGQgbmV3ZmllbGQgPSBuZXcgRmllbGQobmFtZSwgdGhpcyk7Ci0gICAgRmllbGRbXSBzY3JhdGNoID0gbmV3IEZpZWxkW2RlY2xhcmVkZmllbGRzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShkZWNsYXJlZGZpZWxkcywgMCwgc2NyYXRjaCwgMCwgZGVjbGFyZWRmaWVsZHMubGVuZ3RoKTsKLQotICAgIHNjcmF0Y2hbZGVjbGFyZWRmaWVsZHMubGVuZ3RoXSA9IG5ld2ZpZWxkOwotICAgIGRlY2xhcmVkZmllbGRzID0gc2NyYXRjaDsKLSAgICBzY3JhdGNoID0gbmV3IEZpZWxkW2FsbGZpZWxkcy5sZW5ndGggKyAxXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkoYWxsZmllbGRzLCAwLCBzY3JhdGNoLCAwLCBhbGxmaWVsZHMubGVuZ3RoKTsKLQotICAgIHNjcmF0Y2hbYWxsZmllbGRzLmxlbmd0aF0gPSBuZXdmaWVsZDsKLSAgICBhbGxmaWVsZHMgPSBzY3JhdGNoOwotCi0gICAgcmV0dXJuIG5ld2ZpZWxkOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgRmllbGQgb2JqZWN0cyByZWZsZWN0aW5nIGFsbCB0aGUKLSAgICogZmllbGRzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgcmVwcmVzZW50ZWQKLSAgICogYnkgdGhpcyBDbGFzcyBvYmplY3QuIFRoaXMgaW5jbHVkZXMgcHVibGljLAotICAgKiBwcm90ZWN0ZWQsIGRlZmF1bHQgKHBhY2thZ2UpIGFjY2VzcywgYW5kIHByaXZhdGUKLSAgICogZmllbGRzLCBidXQgZXhjbHVkZXMgaW5oZXJpdGVkIGZpZWxkcy4gUmV0dXJucyBhbgotICAgKiBhcnJheSBvZiBsZW5ndGggMCBpZiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIGRlY2xhcmVzCi0gICAqIG5vIGZpZWxkcywgb3IgaWYgdGhpcyBDbGFzcyBvYmplY3QgcmVwcmVzZW50cyBhCi0gICAqIHByaW1pdGl2ZSB0eXBlLiBTZWUgVGhlIEphdmEgTGFuZ3VhZ2UKLSAgICogU3BlY2lmaWNhdGlvbiwgc2VjdGlvbnMgOC4yIGFuZCA4LjMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gYXJyYXkgb2YgRmllbGQgb2JqZWN0cyByZWZsZWN0aW5nIGFsbCB0aGUKLSAgICogZmllbGRzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgcmVwcmVzZW50ZWQKLSAgICogYnkgdGhpcyBDbGFzcyBvYmplY3QuCi0gICAqIAotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIEZpZWxkW10gZ2V0RGVjbGFyZWRGaWVsZHMoKSB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsICYmIGRlY2xhcmVkZmllbGRzID09IG51bGwpCi0gICAgewotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuRmllbGRbXSByZWFsREYgPSByZWFsY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZHMoKTsKLQotICAgICAgZGVjbGFyZWRmaWVsZHMgPSBuZXcgRmllbGRbcmVhbERGLmxlbmd0aF07Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVhbERGLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBkZWNsYXJlZGZpZWxkc1tpXSA9IG5ldyBGaWVsZChyZWFsREZbaV0sIHRoaXMpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBkZWNsYXJlZGZpZWxkczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgTWV0aG9kIG9iamVjdCB0aGF0IHJlZmxlY3RzIHRoZSBzcGVjaWZpZWQKLSAgICogZGVjbGFyZWQgbWV0aG9kIG9mIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuIFRoZSBuYW1lCi0gICAqIHBhcmFtZXRlciBpcyBhIFN0cmluZyB0aGF0IHNwZWNpZmllcyB0aGUgc2ltcGxlCi0gICAqIG5hbWUgb2YgdGhlIGRlc2lyZWQgbWV0aG9kLCBhbmQgdGhlCi0gICAqIHBhcmFtZXRlclR5cGVzIHBhcmFtZXRlciBpcyBhbiBhcnJheSBvZiBDbGFzcwotICAgKiBvYmplY3RzIHRoYXQgaWRlbnRpZnkgdGhlIG1ldGhvZCdzIGZvcm1hbCBwYXJhbWV0ZXIKLSAgICogdHlwZXMsIGluIGRlY2xhcmVkIG9yZGVyLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBTdHJpbmcgdGhhdCBzcGVjaWZpZXMgdGhlIHNpbXBsZQotICAgKiBuYW1lIG9mIHRoZSBkZXNpcmVkIG1ldGhvZC4KLSAgICogCi0gICAqIEBwYXJhbSBwYXJhbWV0ZXJUeXBlcyBhcnJheSBvZiBDbGFzcwotICAgKiBvYmplY3RzIHRoYXQgaWRlbnRpZnkgdGhlIG1ldGhvZCdzIGZvcm1hbCBwYXJhbWV0ZXIKLSAgICogdHlwZXMsIGluIGRlY2xhcmVkIG9yZGVyLgotICAgKgotICAgKiBAcmV0dXJuIE1ldGhvZCBvYmplY3QgdGhhdCByZWZsZWN0cyB0aGUgc3BlY2lmaWVkCi0gICAqIGRlY2xhcmVkIG1ldGhvZCBvZiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlCi0gICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0LgotICAgKiAKLSAgICogQHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24KLSAgICogaWYgYSBtYXRjaGluZyBtZXRob2QgaXMgbm90IGZvdW5kLgotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIE1ldGhvZCBnZXREZWNsYXJlZE1ldGhvZChTdHJpbmcgbmFtZSwgQ2xhc3MgcGFyYW1ldGVyVHlwZXNbXSkKLSAgICAgICAgICB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uLCBTZWN1cml0eUV4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGRzIGEgTWV0aG9kIGRlc2NyaXB0aW9uIGZvciAgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdAotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIG1ldGhvZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbWV0aG9kIG9iamVjdC4KLSAgICogCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqIGlmIHRoZSBjbGFzcyBoYXMgYmVlbiByZWlmaWVkLgotICAgKi8KLSAgcHVibGljIE1ldGhvZCBkZWNsYXJlTWV0aG9kKFN0cmluZyBuYW1lKSB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgTWV0aG9kIG5ld01ldGhvZCA9IG5ldyBNZXRob2QobmFtZSwgdGhpcyk7Ci0gICAgTWV0aG9kW10gc2NyYXRjaCA9IG5ldyBNZXRob2RbZGVjbGFyZWRtZXRob2RzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShkZWNsYXJlZG1ldGhvZHMsIDAsIHNjcmF0Y2gsIDAsIGRlY2xhcmVkbWV0aG9kcy5sZW5ndGgpOwotCi0gICAgc2NyYXRjaFtkZWNsYXJlZG1ldGhvZHMubGVuZ3RoXSA9IG5ld01ldGhvZDsKLSAgICBkZWNsYXJlZG1ldGhvZHMgPSBzY3JhdGNoOwotICAgIHNjcmF0Y2ggPSBuZXcgTWV0aG9kW2FsbG1ldGhvZHMubGVuZ3RoICsgMV07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGFsbG1ldGhvZHMsIDAsIHNjcmF0Y2gsIDAsIGFsbG1ldGhvZHMubGVuZ3RoKTsKLQotICAgIHNjcmF0Y2hbYWxsbWV0aG9kcy5sZW5ndGhdID0gbmV3TWV0aG9kOwotICAgIGFsbG1ldGhvZHMgPSBzY3JhdGNoOwotCi0gICAgcmV0dXJuIG5ld01ldGhvZDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIE1ldGhvZCBvYmplY3RzIHJlZmxlY3RpbmcgYWxsCi0gICAqIHRoZSBtZXRob2RzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuIFRoaXMgaW5jbHVkZXMKLSAgICogcHVibGljLCBwcm90ZWN0ZWQsIGRlZmF1bHQgKHBhY2thZ2UpIGFjY2VzcywgYW5kCi0gICAqIHByaXZhdGUgbWV0aG9kcywgYnV0IGV4Y2x1ZGVzIGluaGVyaXRlZCBtZXRob2RzLgotICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxlbmd0aCAwIGlmIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogZGVjbGFyZXMgbm8gbWV0aG9kcywgb3IgaWYgdGhpcyBDbGFzcyBvYmplY3QKLSAgICogcmVwcmVzZW50cyBhIHByaW1pdGl2ZSB0eXBlLgotICAgKiA8cD4KLSAgICogU2VlIFRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sIHNlY3Rpb24gOC4yLgotICAgKgotICAgKiBAcmV0dXJuIGFycmF5IG9mIE1ldGhvZCBvYmplY3RzIHJlZmxlY3RpbmcgYWxsCi0gICAqIHRoZSBtZXRob2RzIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuCi0gICAqIAotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIE1ldGhvZFtdIGdldERlY2xhcmVkTWV0aG9kcygpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwgJiYgZGVjbGFyZWRtZXRob2RzID09IG51bGwpCi0gICAgewotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kW10gcmVhbERNID0gcmVhbGNsYXNzLmdldERlY2xhcmVkTWV0aG9kcygpOwotCi0gICAgICBkZWNsYXJlZG1ldGhvZHMgPSBuZXcgTWV0aG9kW3JlYWxETS5sZW5ndGhdOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlYWxETS5sZW5ndGg7ICsraSkKLSAgICAgIHsKLSAgICAgICAgZGVjbGFyZWRtZXRob2RzW2ldID0gbmV3IE1ldGhvZChyZWFsRE1baV0sIHRoaXMpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBkZWNsYXJlZG1ldGhvZHM7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGluIFZBSmF2YSAzLjAKLSAgICogPHA+Ci0gICAqIElmIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcwotICAgKiBvYmplY3QgaXMgYSBtZW1iZXIgb2YgYW5vdGhlciBjbGFzcywgcmV0dXJucyB0aGUKLSAgICogQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY2xhc3Mgb2Ygd2hpY2ggaXQgaXMgYQotICAgKiBtZW1iZXIgKGl0cyBkZWNsYXJpbmcgY2xhc3MpLiBSZXR1cm5zIG51bGwgaWYgdGhpcwotICAgKiBjbGFzcyBvciBpbnRlcmZhY2UgaXMgbm90IGEgbWVtYmVyIG9mIGFueSBvdGhlcgotICAgKiBjbGFzcy4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBDbGFzcyBnZXREZWNsYXJpbmdDbGFzcygpCi0gIHsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCAmJiBkZWNsYXJpbmdjbGFzcyA9PSBudWxsKQotICAgIHsKLSAgICAgIGphdmEubGFuZy5DbGFzcyBkYyA9IHJlYWxjbGFzcy5nZXREZWNsYXJpbmdDbGFzcygpOwotCi0gICAgICBpZiAoZGMgPT0gbnVsbCkKLSAgICAgICAgZGVjbGFyaW5nY2xhc3MgPSBudWxsOwotICAgICAgZWxzZQotICAgICAgICBkZWNsYXJpbmdjbGFzcyA9IGZvckNsYXNzKGRjKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZGVjbGFyaW5nY2xhc3M7Ci0gIH0KLQotICAvKioKLSAgICogRGVjbGFyZSB0aGF0IHRoaXMgY2xhc3MgaXMgYW4gaW5uZXIgY2xhc3Mgb2YgYW5vdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG5ld2NsYXNzCi0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgYWRkSW5uZXJDbGFzcyhDbGFzcyBuZXdjbGFzcykgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIGlmIChuZXdjbGFzcy5nZXREZWNsYXJpbmdDbGFzcygpICE9IHRoaXMpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5XUk9OR19PV05FUik7Ci0KLSAgICBDbGFzc1tdIHNjcmF0Y2ggPSBuZXcgQ2xhc3NbaW5uZXJjbGFzc2VzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShpbm5lcmNsYXNzZXMsIDAsIHNjcmF0Y2gsIDAsIGlubmVyY2xhc3Nlcy5sZW5ndGgpOwotCi0gICAgc2NyYXRjaFtpbm5lcmNsYXNzZXMubGVuZ3RoXSA9IG5ld2NsYXNzOwotICAgIGlubmVyY2xhc3NlcyA9IHNjcmF0Y2g7Ci0gIH0KLQotICAvKioKLSAgICogRGVjbGFyZSBhIGNsYXNzIGNvbnRhaW5lZCB3aXRoaW4gdGhpcyBjbGFzcy4gVGhpcyBkb2Vzbid0Ci0gICAqIGFkZHJlc3MgYW5vbnltb3VzIGNsYXNzZXMgKHRob3NlIGdvIGluc2lkZSBtZXRob2QgYm9kaWVzCi0gICAqIGFuZCBzaW1pbGFyIGNvZGUpLCBqdXN0IGxvY2FsIGNsYXNzZXMuCi0gICAqIDxwPgotICAgKiAqKioqKiBUaGlzIHJlcXVpcmVzIGxvb2t1cCBtZXRob2RzIHRoYXQgb3BlcmF0ZSBpbiB0aGUKLSAgICogY29udGV4dCBvZiBhIHNwZWNpZmljIGNsYXNzLCBhbmQgcGVyLWNsYXNzIHJlZ2lzdHJpZXMhCi0gICAqCi0gICAqIEBwYXJhbSBjbGFzc05hbWUgTG9jYWwgbmFtZSBvZiBpbm5lciBjbGFzcyB0byBjcmVhdGUuIFRoaXMgc2hvdWxkIF9ub3RfIGJlIGEKLSAgICogcXVhbGlmaWVkIG5hbWUsIHVubGlrZSB0aGUgbm9ybWFsIGZvck5hbWUoKSBjYWxsLiBJdHMKLSAgICogaGllcmFyY2h5IGlzIGVzdGFibGlzaGVkIGJ5IHRoZSBjbGFzcyB3aXRoaW4gd2hpY2ggaXQgaXMKLSAgICogY3JlYXRlZC4KLSAgICogQHJldHVybiBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3Mgb2JqZWN0IGZvciB0aGUgY29udGFpbmVkIGNsYXNzLgotICAgKiBAdGhyb3dzIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5TeW50aGVzaXNFeGNlcHRpb24gaWYgY2xhc3MgY291bGQgbm90IGJlIGNyZWF0ZWQuCi0gICAqIEBzaW5jZSAyLzIwMDAKLSAgICoKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBDbGFzcyBkZWNsYXJlSW5uZXJDbGFzcyhTdHJpbmcgY2xhc3NOYW1lKSB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgU3RyaW5nIHJlbGF0aXZlTmFtZSA9IGdldE5hbWUoKSArICIkIiArIGNsYXNzTmFtZTsKLSAgICBDbGFzcyBuZXdjbGFzcyA9IChDbGFzcykgKGdsb2JhbF9jbGFzc3RhYmxlLmdldChyZWxhdGl2ZU5hbWUpKTsKLQotICAgIGlmIChuZXdjbGFzcyAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uU1lOVEFYLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW5uZXIgY2xhc3MgIiArIG5hbWUgKyAiIGFscmVhZHkgZXhpc3RzIik7Ci0KLSAgICBuZXdjbGFzcyA9IG5ldyBDbGFzcyhjbGFzc05hbWUpOwotICAgIG5ld2NsYXNzLmRlY2xhcmluZ2NsYXNzID0gdGhpczsKLQotICAgIENsYXNzW10gc2NyYXRjaCA9IG5ldyBDbGFzc1tpbm5lcmNsYXNzZXMubGVuZ3RoICsgMV07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGlubmVyY2xhc3NlcywgMCwgc2NyYXRjaCwgMCwgaW5uZXJjbGFzc2VzLmxlbmd0aCk7Ci0KLSAgICBzY3JhdGNoW2lubmVyY2xhc3Nlcy5sZW5ndGhdID0gbmV3Y2xhc3M7Ci0gICAgaW5uZXJjbGFzc2VzID0gc2NyYXRjaDsKLQotICAgIHJldHVybiBuZXdjbGFzczsKLSAgfQotCi0gIC8qKgotICAgKiBGZXRjaCBhIGxpc3Qgb2YgY2xhc3NlcyBjb250YWluZWQgd2l0aGluIHRoaXMgY2xhc3MuCi0gICAqIFRoaXMgZG9lc24ndCBhZGRyZXNzIGFub255bW91cyBjbGFzc2VzICh0aG9zZSBnbwotICAgKiBpbnNpZGUgbWV0aG9kIGJvZGllcyBhbmQgc2ltaWxhciBjb2RlKSwganVzdCBsb2NhbCBjbGFzc2VzLgotICAgKgotICAgKiBAcmV0dXJuIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzc1tdIG9iamVjdCBmb3IgdGhlIGNvbnRhaW5lZCBjbGFzc2VzLgotICAgKiBUaGlzIG1heSBiZSBlbXB0eSBpZiBub25lIHN1Y2ggZXhpc3QsIG9yIGlmIHRoZSBjbGFzcyBpcwotICAgKiByZWlmaWVkIChzaW5jZSByZWZsZWN0aW9uIGRvZXNuJ3QgcmVwb3J0IHRoaXMgaW5mb3JtYXRpb24pLgotICAgKiBAc2luY2UgMy8yMDAwCi0gICAqLwotICBwdWJsaWMgQ2xhc3NbXSBnZXRJbm5lckNsYXNzZXMoKQotICB7Ci0gICAgcmV0dXJuIGlubmVyY2xhc3NlczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgRmllbGQgb2JqZWN0IHRoYXQgcmVmbGVjdHMgdGhlIHNwZWNpZmllZAotICAgKiBwdWJsaWMgbWVtYmVyIGZpZWxkIG9mIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QuIFRoZSBuYW1lCi0gICAqIHBhcmFtZXRlciBpcyBhIFN0cmluZyBzcGVjaWZ5aW5nIHRoZSBzaW1wbGUgbmFtZSBvZgotICAgKiB0aGUgZGVzaXJlZCBmaWVsZC4KLSAgICogPHA+Ci0gICAqIFRoZSBmaWVsZCB0byBiZSByZWZsZWN0ZWQgaXMgbG9jYXRlZCBieSBzZWFyY2hpbmcgYWxsCi0gICAqIHRoZSBtZW1iZXIgZmllbGRzIG9mIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QgZm9yIGEgcHVibGljIGZpZWxkCi0gICAqIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLgotICAgKiA8cD4KLSAgICogU2VlIFRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sIHNlY3Rpb25zIDguMgotICAgKiBhbmQgOC4zLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKgotICAgKiBAdGhyb3dzIE5vU3VjaEZpZWxkRXhjZXB0aW9uCi0gICAqIGlmIGEgZmllbGQgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgaXMgbm90Ci0gICAqIGZvdW5kLgotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIEZpZWxkIGdldEZpZWxkKFN0cmluZyBuYW1lKQotICAgICAgICAgIHRocm93cyBOb1N1Y2hGaWVsZEV4Y2VwdGlvbiwgU2VjdXJpdHlFeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIEZpZWxkIG9iamVjdHMKLSAgICogcmVmbGVjdGluZyBhbGwgdGhlIGFjY2Vzc2libGUgcHVibGljIGZpZWxkcyBvZiB0aGUKLSAgICogY2xhc3Mgb3IgaW50ZXJmYWNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0LgotICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxlbmd0aCAwIGlmIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogaGFzIG5vIGFjY2Vzc2libGUgcHVibGljIGZpZWxkcywgb3IgaWYgaXQgcmVwcmVzZW50cwotICAgKiBhbiBhcnJheSB0eXBlIG9yIGEgcHJpbWl0aXZlIHR5cGUuCi0gICAqIDxwPgotICAgKiBTcGVjaWZpY2FsbHksIGlmIHRoaXMgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMgYSBjbGFzcywKLSAgICogcmV0dXJucyB0aGUgcHVibGljIGZpZWxkcyBvZiB0aGlzIGNsYXNzIGFuZCBvZiBhbGwgaXRzCi0gICAqIHN1cGVyY2xhc3Nlcy4gSWYgdGhpcyBDbGFzcyBvYmplY3QgcmVwcmVzZW50cyBhbgotICAgKiBpbnRlcmZhY2UsIHJldHVybnMgdGhlIGZpZWxkcyBvZiB0aGlzIGludGVyZmFjZSBhbmQgb2YKLSAgICogYWxsIGl0cyBzdXBlcmludGVyZmFjZXMuIElmIHRoaXMgQ2xhc3Mgb2JqZWN0Ci0gICAqIHJlcHJlc2VudHMgYW4gYXJyYXkgdHlwZSBvciBhIHByaW1pdGl2ZSB0eXBlLCByZXR1cm5zCi0gICAqIGFuIGFycmF5IG9mIGxlbmd0aCAwLgotICAgKiA8cD4KLSAgICogVGhlIGltcGxpY2l0IGxlbmd0aCBmaWVsZCBmb3IgYXJyYXkgdHlwZXMgaXMgbm90Ci0gICAqIHJlZmxlY3RlZCBieSB0aGlzIG1ldGhvZC4gVXNlciBjb2RlIHNob3VsZCB1c2UgdGhlCi0gICAqIG1ldGhvZHMgb2YgY2xhc3MgQXJyYXkgdG8gbWFuaXB1bGF0ZSBhcnJheXMuCi0gICAqIDxwPgotICAgKiBTZWUgVGhlIEphdmEgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbiwgc2VjdGlvbnMgOC4yCi0gICAqIGFuZCA4LjMuCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KLSAgICogaWYgYWNjZXNzIHRvIHRoZSBpbmZvcm1hdGlvbiBpcyBkZW5pZWQuCi0gICAqLwotICBwdWJsaWMgRmllbGRbXSBnZXRGaWVsZHMoKSB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsICYmIGFsbGZpZWxkcyA9PSBudWxsKQotICAgIHsKLSAgICAgIGphdmEubGFuZy5yZWZsZWN0LkZpZWxkW10gcmVhbERGID0gcmVhbGNsYXNzLmdldEZpZWxkcygpOwotCi0gICAgICBhbGxmaWVsZHMgPSBuZXcgRmllbGRbcmVhbERGLmxlbmd0aF07Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVhbERGLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBhbGxmaWVsZHNbaV0gPSBuZXcgRmllbGQocmVhbERGW2ldLCB0aGlzKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWxsZmllbGRzOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgdGhlIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgdGhlCi0gICAqIGNsYXNzIG9yIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdC4KLSAgICogPHA+Ci0gICAqIElmIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMgYSBjbGFzcywgdGhlIHJldHVybiB2YWx1ZSBpcwotICAgKiBhbiBhcnJheSBjb250YWluaW5nIG9iamVjdHMgcmVwcmVzZW50aW5nIGFsbAotICAgKiBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IHRoZSBjbGFzcy4gVGhlIG9yZGVyIG9mCi0gICAqIHRoZSBpbnRlcmZhY2Ugb2JqZWN0cyBpbiB0aGUgYXJyYXkgY29ycmVzcG9uZHMgdG8gdGhlCi0gICAqIG9yZGVyIG9mIHRoZSBpbnRlcmZhY2UgbmFtZXMgaW4gdGhlIGltcGxlbWVudHMKLSAgICogY2xhdXNlIG9mIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkKLSAgICogdGhpcyBvYmplY3QuCi0gICAqIDxwPgotICAgKiBJZiB0aGlzIG9iamVjdCByZXByZXNlbnRzIGFuIGludGVyZmFjZSwgdGhlIGFycmF5Ci0gICAqIGNvbnRhaW5zIG9iamVjdHMgcmVwcmVzZW50aW5nIGFsbCBpbnRlcmZhY2VzCi0gICAqIGV4dGVuZGVkIGJ5IHRoZSBpbnRlcmZhY2UuIFRoZSBvcmRlciBvZiB0aGUKLSAgICogaW50ZXJmYWNlIG9iamVjdHMgaW4gdGhlIGFycmF5IGNvcnJlc3BvbmRzIHRvIHRoZQotICAgKiBvcmRlciBvZiB0aGUgaW50ZXJmYWNlIG5hbWVzIGluIHRoZSBleHRlbmRzIGNsYXVzZQotICAgKiBvZiB0aGUgZGVjbGFyYXRpb24gb2YgdGhlIGludGVyZmFjZSByZXByZXNlbnRlZCBieQotICAgKiB0aGlzIG9iamVjdC4KLSAgICogPHA+Ci0gICAqIElmIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgaW1wbGVtZW50cyBubyBpbnRlcmZhY2VzLAotICAgKiB0aGUgbWV0aG9kIHJldHVybnMgYW4gYXJyYXkgb2YgbGVuZ3RoIDAuCi0gICAqCi0gICAqIGFuIGFycmF5IG9mIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgdGhpcwotICAgKiBjbGFzcy4KLSAgICovCi0gIHB1YmxpYyBDbGFzc1tdIGdldEludGVyZmFjZXMoKQotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwgJiYgaW50ZXJmYWNlcyA9PSBudWxsKQotICAgIHsKLSAgICAgIGphdmEubGFuZy5DbGFzc1tdIHJlYWxJID0gcmVhbGNsYXNzLmdldEludGVyZmFjZXMoKTsKLQotICAgICAgaW50ZXJmYWNlcyA9IG5ldyBDbGFzc1tyZWFsSS5sZW5ndGhdOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlYWxJLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBpbnRlcmZhY2VzW2ldID0gZm9yQ2xhc3MocmVhbElbaV0pOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBpbnRlcmZhY2VzOwotICB9Ci0KLSAgLyoqCi0gICAqIEFkZHMgYW4gImltcGxlbWVudHMiIGRlc2NyaXB0aW9uIGZvciB0aGUgY2xhc3Mgb3IKLSAgICogaW50ZXJmYWNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0Ci0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuZXdjbGFzcwotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgY2xhc3MgaGFzIGJlZW4gcmVpZmllZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEltcGxlbWVudHMoQ2xhc3MgbmV3Y2xhc3MpIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uUkVJRklFRCk7Ci0KLSAgICBDbGFzc1tdIHNjcmF0Y2ggPSBuZXcgQ2xhc3NbaW50ZXJmYWNlcy5sZW5ndGggKyAxXTsKLQotICAgIFN5c3RlbS5hcnJheWNvcHkoaW50ZXJmYWNlcywgMCwgc2NyYXRjaCwgMCwgaW50ZXJmYWNlcy5sZW5ndGgpOwotCi0gICAgc2NyYXRjaFtpbnRlcmZhY2VzLmxlbmd0aF0gPSBuZXdjbGFzczsKLSAgICBpbnRlcmZhY2VzID0gc2NyYXRjaDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgTWV0aG9kIG9iamVjdCB0aGF0IHJlZmxlY3RzIHRoZSBzcGVjaWZpZWQKLSAgICogcHVibGljIG1lbWJlciBtZXRob2Qgb2YgdGhlIGNsYXNzIG9yIGludGVyZmFjZQotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdC4gVGhlIG5hbWUKLSAgICogcGFyYW1ldGVyIGlzIGEgU3RyaW5nIHNwZWNpZnlpbmcgdGhlIHNpbXBsZSBuYW1lCi0gICAqIHRoZSBkZXNpcmVkIG1ldGhvZCwgYW5kIHRoZSBwYXJhbWV0ZXJUeXBlcwotICAgKiBwYXJhbWV0ZXIgaXMgYW4gYXJyYXkgb2YgQ2xhc3Mgb2JqZWN0cyB0aGF0IGlkZW50aWZ5Ci0gICAqIHRoZSBtZXRob2QncyBmb3JtYWwgcGFyYW1ldGVyIHR5cGVzLCBpbiBkZWNsYXJlZAotICAgKiBvcmRlci4KLSAgICogPHA+Ci0gICAqIFRoZSBtZXRob2QgdG8gcmVmbGVjdCBpcyBsb2NhdGVkIGJ5IHNlYXJjaGluZyBhbGwKLSAgICogdGhlIG1lbWJlciBtZXRob2RzIG9mIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBDbGFzcyBvYmplY3QgZm9yIGEgcHVibGljCi0gICAqIG1ldGhvZCB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBhbmQgZXhhY3RseSB0aGUKLSAgICogc2FtZSBmb3JtYWwgcGFyYW1ldGVyIHR5cGVzLgotICAgKiA8cD4KLSAgICogU2VlIFRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sIHNlY3Rpb25zIDguMgotICAgKiBhbmQgOC40LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKiBAcGFyYW0gcGFyYW1ldGVyVHlwZXMKLSAgICoKLSAgICogQHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24KLSAgICogaWYgYSBtYXRjaGluZyBtZXRob2QgaXMgbm90IGZvdW5kLgotICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uCi0gICAqIGlmIGFjY2VzcyB0byB0aGUgaW5mb3JtYXRpb24gaXMgZGVuaWVkLgotICAgKi8KLSAgcHVibGljIE1ldGhvZCBnZXRNZXRob2QoU3RyaW5nIG5hbWUsIENsYXNzIHBhcmFtZXRlclR5cGVzW10pCi0gICAgICAgICAgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiwgU2VjdXJpdHlFeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIE1ldGhvZCBvYmplY3RzCi0gICAqIHJlZmxlY3RpbmcgYWxsIHRoZSBwdWJsaWMgbWVtYmVyIG1ldGhvZHMgb2YgdGhlCi0gICAqIGNsYXNzIG9yIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGlzIENsYXNzIG9iamVjdCwKLSAgICogaW5jbHVkaW5nIHRob3NlIGRlY2xhcmVkIGJ5IHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKLSAgICogYW5kIGFuZCB0aG9zZSBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMgYW5kCi0gICAqIHN1cGVyaW50ZXJmYWNlcy4gUmV0dXJucyBhbiBhcnJheSBvZiBsZW5ndGggMCBpZiB0aGUKLSAgICogY2xhc3Mgb3IgaW50ZXJmYWNlIGhhcyBubyBwdWJsaWMgbWVtYmVyIG1ldGhvZHMuCi0gICAqIDxwPgotICAgKiBTZWUgVGhlIEphdmEgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbiwgc2VjdGlvbnMgOC4yCi0gICAqIGFuZCA4LjQuCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24KLSAgICogaWYgYWNjZXNzIHRvIHRoZSBpbmZvcm1hdGlvbiBpcyBkZW5pZWQuCi0gICAqLwotICBwdWJsaWMgTWV0aG9kW10gZ2V0TWV0aG9kcygpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwgJiYgYWxsbWV0aG9kcyA9PSBudWxsKQotICAgIHsKLSAgICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZFtdIHJlYWxETSA9IHJlYWxjbGFzcy5nZXRNZXRob2RzKCk7Ci0KLSAgICAgIGFsbG1ldGhvZHMgPSBuZXcgTWV0aG9kW3JlYWxETS5sZW5ndGhdOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlYWxETS5sZW5ndGg7ICsraSkKLSAgICAgIHsKLSAgICAgICAgYWxsbWV0aG9kc1tpXSA9IG5ldyBNZXRob2QocmVhbERNW2ldLCB0aGlzKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWxsbWV0aG9kczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBKYXZhIGxhbmd1YWdlIG1vZGlmaWVycyBmb3IgdGhpcyBjbGFzcwotICAgKiBvciBpbnRlcmZhY2UsIGVuY29kZWQgaW4gYW4gaW50ZWdlci4gVGhlIG1vZGlmaWVycwotICAgKiBjb25zaXN0IG9mIHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSdzIGNvbnN0YW50cyBmb3IKLSAgICogcHVibGljLCBwcm90ZWN0ZWQsIHByaXZhdGUsIGZpbmFsLCBhbmQgaW50ZXJmYWNlOyB0aGV5Ci0gICAqIHNob3VsZCBiZSBkZWNvZGVkIHVzaW5nIHRoZSBtZXRob2RzIG9mIGNsYXNzCi0gICAqIE1vZGlmaWVyLgotICAgKgotICAgKiBUaGUgbW9kaWZpZXIgZW5jb2RpbmdzIGFyZSBkZWZpbmVkIGluIFRoZSBKYXZhCi0gICAqIFZpcnR1YWwgTWFjaGluZSBTcGVjaWZpY2F0aW9uLCB0YWJsZSA0LjEuCi0gICAqCi0gICAqIFNlZSBBbHNvOgotICAgKiBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcgotICAgKgotICAgKi8KLSAgcHVibGljIGludCBnZXRNb2RpZmllcnMoKQotICB7Ci0gICAgcmV0dXJuIG1vZGlmaWVyczsKLSAgfQotCi0gIC8qKgotICAgKiAgIFNldCB0aGUgSmF2YSBsYW5ndWFnZSBtb2RpZmllcnMgZm9yIHRoaXMgY2xhc3MKLSAgICogICBvciBpbnRlcmZhY2UsIGVuY29kZWQgaW4gYW4gaW50ZWdlci4gVGhlIG1vZGlmaWVycwotICAgKiAgIGNvbnNpc3Qgb2YgdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lJ3MgY29uc3RhbnRzIGZvcgotICAgKiAgIHB1YmxpYywgcHJvdGVjdGVkLCBwcml2YXRlLCBmaW5hbCwgYW5kIGludGVyZmFjZTsgdGhleQotICAgKiAgIHNob3VsZCBiZSBkZWNvZGVkIHVzaW5nIHRoZSBtZXRob2RzIG9mIGNsYXNzCi0gICAqICAgTW9kaWZpZXIuCi0gICAqCi0gICAqICAgVGhlIG1vZGlmaWVyIGVuY29kaW5ncyBhcmUgZGVmaW5lZCBpbiBUaGUgSmF2YQotICAgKiAgIFZpcnR1YWwgTWFjaGluZSBTcGVjaWZpY2F0aW9uLCB0YWJsZSA0LjEuCi0gICAqCi0gICAqICAgU2VlIEFsc286Ci0gICAqICAgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXIKLSAgICoKLSAgICogQHBhcmFtIG1vZGlmaWVycwotICAgKgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TW9kaWZpZXJzKGludCBtb2RpZmllcnMpIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHRoaXMucmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIHRoaXMubW9kaWZpZXJzID0gbW9kaWZpZXJzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSBmdWxseS1xdWFsaWZpZWQgY2xhc3NuYW1lLiBJZiBpdCdzIGFuIGFycmF5LAotICAgKiBpdCB3aWxsIGJlIHJldHVybmVkIGluIEpWTSBzeW50YXgsIG5vdCBKYXZhIHN5bnRheC4KLSAgICoKLSAgICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCi0gICAqIEBzaW5jZSAxMi85NQotICAgKi8KLSAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpCi0gIHsKLSAgICByZXR1cm4gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBMaWtlIGdldE5hbWUsIGJ1dCBiYWNrLWNvbnZlcnQgYXJyYXkgbm90YXRpb24gZXNjYXBlcy4KLSAgICogKioqKiogRE9FU04nVCBZRVQgSEFORExFIEFSUkFZUyBPRiBQUklNSVRJVkVTIQotICAgKgotICAgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKLSAgICogQHNpbmNlIDMvMjAwMAotICAgKi8KLSAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SmF2YU5hbWUoKQotICB7Ci0KLSAgICBpZiAobmFtZS5jaGFyQXQoMCkgIT0gJ1snKQotICAgICAgcmV0dXJuIG5hbWU7Ci0KLSAgICAvLyBPYmplY3QgYXJyYXkgc3ludGF4IGlzIFtMdHlwZW5hbWU7IAotICAgIC8vIGFkZCBhbm90aGVyIFsgZm9yIGVhY2ggbGV2ZWwgb2YgYXJyYXkKLSAgICBpbnQgY291bnQgPSBuYW1lLmxhc3RJbmRleE9mKCdbJyk7Ci0gICAgU3RyaW5nQnVmZmVyIGpuYW1lID0gbmV3IFN0cmluZ0J1ZmZlcihuYW1lLnN1YnN0cmluZyhjb3VudCArIDIpKTsKLQotICAgIC8vIFRyaW0gdGhlIHRyYWlsaW5nICc7JwotICAgIGpuYW1lLnNldExlbmd0aChqbmFtZS5sZW5ndGgoKSAtIDEpOwotCi0gICAgd2hpbGUgKGNvdW50LS0gPj0gMCkKLSAgICB7Ci0gICAgICBqbmFtZS5hcHBlbmQoIltdIik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGpuYW1lLnRvU3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogRXh0cmFjdCBqdXN0IHRoZSBsb2NhbCBuYW1lIG9mIHRoaXMgY2xhc3MsIG1pbnVzIHRoZSBwYWNrYWdlCi0gICAqIHByZWZpeC4KLSAgICoKLSAgICogKioqKiogSSBkb24ndCB0aGluayB0aGlzIGhhbmRsZXMgYXJyYXkgdHlwZXMgcHJvcGVybHkgeWV0LgotICAgKgotICAgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKLSAgICogQHNpbmNlIDEyLzk5Ci0gICAqLwotICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTaG9ydE5hbWUoKQotICB7Ci0KLSAgICBpbnQgc3RhcnQgPSBuYW1lLmxhc3RJbmRleE9mKCIuIik7Ci0KLSAgICBpZiAoc3RhcnQgIT0gMCB8fCBuYW1lLmNoYXJBdCgwKSA9PSAnLicpCi0gICAgICArK3N0YXJ0OwotCi0gICAgaWYgKGRlY2xhcmluZ2NsYXNzICE9IG51bGwpCi0gICAgewotICAgICAgaW50IGQgPSBuYW1lLmxhc3RJbmRleE9mKCckJywgc3RhcnQpOwotCi0gICAgICBpZiAoZCAhPSAwKQotICAgICAgICBzdGFydCA9IGQgKyAxOwotICAgIH0KLQotICAgIHJldHVybiBuYW1lLnN1YnN0cmluZyhzdGFydCk7Ci0gIH0KLQotICAvKioKLSAgICogTGlrZSBnZXRTaG9ydE5hbWUsIGJ1dCBiYWNrLWNvbnZlcnQgYXJyYXkgbm90YXRpb24gZXNjYXBlcy4KLSAgICogKioqKiogRE9FU04nVCBZRVQgSEFORExFIEFSUkFZUyBPRiBQUklNSVRJVkVTIQotICAgKgotICAgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKLSAgICogQHNpbmNlIDMvMjAwMAotICAgKi8KLSAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SmF2YVNob3J0TmFtZSgpCi0gIHsKLQotICAgIFN0cmluZyBzaG9ydG5hbWUgPSBnZXRTaG9ydE5hbWUoKTsKLQotICAgIGlmIChzaG9ydG5hbWUuY2hhckF0KDApICE9ICdbJykKLSAgICAgIHJldHVybiBzaG9ydG5hbWU7Ci0KLSAgICAvLyBPYmplY3QgYXJyYXkgc3ludGF4IGlzIFtMdHlwZW5hbWU7IAotICAgIC8vIGFkZCBhbm90aGVyIFsgZm9yIGVhY2ggbGV2ZWwgb2YgYXJyYXkKLSAgICBpbnQgY291bnQgPSBzaG9ydG5hbWUubGFzdEluZGV4T2YoJ1snKTsKLSAgICBTdHJpbmdCdWZmZXIgam5hbWUgPSBuZXcgU3RyaW5nQnVmZmVyKHNob3J0bmFtZS5zdWJzdHJpbmcoY291bnQgKyAyKSk7Ci0KLSAgICAvLyBUcmltIHRoZSB0cmFpbGluZyAnOycKLSAgICBqbmFtZS5zZXRMZW5ndGgoam5hbWUubGVuZ3RoKCkgLSAxKTsKLQotICAgIHdoaWxlIChjb3VudC0tID49IDApCi0gICAgewotICAgICAgam5hbWUuYXBwZW5kKCJbXSIpOwotICAgIH0KLQotICAgIHJldHVybiBqbmFtZS50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4dHJhY3QgdGhlIHBhY2thZ2UgbmFtZSBmb3IgdGhpcyBjbGFzcy4KLSAgICogKioqKiogSSBkb24ndCB0aGluayB0aGlzIGhhbmRsZXMgYXJyYXkgY2xhc3NlcyBwcm9wZXJseSB5ZXQuCi0gICAqCi0gICAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwotICAgKiBAc2luY2UgMTIvOTUKLSAgICovCi0gIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhY2thZ2VOYW1lKCkKLSAgewotCi0gICAgaW50IHN0YXJ0ID0gbmFtZS5sYXN0SW5kZXhPZigiLiIpOwotCi0gICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKDAsIHN0YXJ0KTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiB0aGlzIHN5bnRoZXRpYyBjbGFzcyBpcyBhIHdyYXBwZXIgZm9yIGEgInJlYWwiCi0gICAqIGphdmEubGFuZy5DbGFzcyAtLSBlaXRoZXIgYmVjYXVzZSBpdCB3YXMgaW5zdGFudGlhdGVkIGFzIHN1Y2gKLSAgICogb3IgYmVjYXVzZSBpdCBoYXMgYmVlbiBjb21waWxlZCAtLSB0aGlzIG1ldGhvZCB3aWxsIHJldHVybgotICAgKiB0aGF0IGNsYXNzLiBPdGhlcndpc2UgaXQgcmV0dXJucyBudWxsLgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjUtOTkgMTI6MjY6MDEgUE0pCi0gICAqIEByZXR1cm4gb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzCi0gICAqLwotICBwdWJsaWMgamF2YS5sYW5nLkNsYXNzIGdldFJlYWxDbGFzcygpCi0gIHsKLSAgICByZXR1cm4gcmVhbGNsYXNzOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoaXMgY2FsbCBpcyBpbnRlbmRlZCB0byBhbGxvdyBhbiBleGlzdGluZyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MKLSAgICogdG8gYmUgc3dpdGNoZWQgZnJvbSBwdXJlbHkgZGVzY3JpcHRpdmUgbW9kZSB0byBwcm94eSBtb2RlCi0gICAqICgicmVpZmllZCIpLgotICAgKiBUaGUgcHJpbWFyeSBpbnRlbnQgaXMgdG8gYWxsb3cgYSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgdG8gYmUKLSAgICogImNvbXBpbGVkIGluIHBsYWNlIgotICAgKiA8cD4KLSAgICogVGhpcyBzaG91bGQgaGF2ZSB0aGUgc2lkZS1lZmZlY3Qgb2YgbGltaXRpbmcgZnVydGhlciBtdXRhdGlvbgotICAgKiBvZiB0aGUgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIHRvIHRoaW5ncyB3aGljaCBjYW4gbm90IGJlIG9idGFpbmVkCi0gICAqIGZyb20gdGhlIHJlYWwgQ2xhc3Mgb2JqZWN0LCB0byBhdm9pZCAibHlpbmciIHRvIHRoZSB1c2VyCi0gICAqIDxwPgotICAgKiBOT1RFOiBOb3QgYWxsIGluZm9ybWF0aW9uIGRlZmluZWQgYnkgdGhlIEphdmEgbGlicmFyaWVzIGlzCi0gICAqIGluIGZhY3QgYXZhaWxhYmxlIGluIGFsbCBKYXZhIGVudmlyb25tZW50cy4gV2UgYXNzdW1lIHRoZQotICAgKiBjYWxscyB3aWxsIHdvcms7IGlmIHRoZXkgcmV0dXJuIG51bGwgb3IgZW1wdHkgbGlzdHMsIHRoZXJlJ3MKLSAgICogbm90aGluZyB3ZSBjYW4gZG8gYWJvdXQgaXQuIE5vdGUgdGhhdCB0aGlzIG1heSBtZWFuIHRoYXQgYQotICAgKiByZWlmaWVkIGNsYXNzIHRlbGxzIHVzIGxlc3MgYWJvdXQgaXRzZWxmIHRoYW4gdGhlCi0gICAqIHN5bnRoZXRpYyBkZXNjcmlwdGlvbiB1c2VkIHRvIGdlbmVyYXRlIGl0LgotICAgKiA8cD4KLSAgICogQ3JlYXRpb24gZGF0ZTogKDEyLTI1LTk5IDEyOjI2OjAxIFBNKQotICAgKiBAcGFyYW0gamF2YS5sYW5nLmNsYXNzIHJlYWxjbGFzcyBub25zeW50aGV0aWMgQ2xhc3Mgb2JqZWN0IHRvIHByb3h5Ci0gICAqCi0gICAqIEBwYXJhbSByZWFsY2xhc3MKLSAgICoKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJlYWxDbGFzcyhqYXZhLmxhbmcuQ2xhc3MgcmVhbGNsYXNzKQotICAgICAgICAgIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHRoaXMucmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIHRoaXMucmVhbGNsYXNzID0gcmVhbGNsYXNzOwotICAgIHRoaXMubW9kaWZpZXJzID0gcmVhbGNsYXNzLmdldE1vZGlmaWVycygpOwotICAgIHRoaXMuaXNJbnRlcmZhY2UgPSByZWFsY2xhc3MuaXNJbnRlcmZhY2UoKTsKLQotICAgIC8vIERFRkVSUkVEIC0tIHNldCB0aGVtIG51bGwgbm93LCByZWNvbnN0cnVjdCB3aGVuIHJlcXVlc3RlZAotICAgIHRoaXMuZGVjbGFyaW5nY2xhc3MgPSBudWxsOwotICAgIHRoaXMuaW50ZXJmYWNlcyA9IG51bGw7Ci0gICAgdGhpcy5kZWNsYXJlZGNvbnN0cnVjdG9ycyA9IG51bGw7Ci0gICAgdGhpcy5hbGxjb25zdHJ1Y3RvcnMgPSBudWxsOwotICAgIHRoaXMuZGVjbGFyZWRtZXRob2RzID0gbnVsbDsKLSAgICB0aGlzLmFsbG1ldGhvZHMgPSBudWxsOwotICAgIHRoaXMuZGVjbGFyZWRmaWVsZHMgPSBudWxsOwotICAgIHRoaXMuYWxsZmllbGRzID0gbnVsbDsKLSAgICB0aGlzLmRlY2xhcmVkY2xhc3NlcyA9IG51bGw7Ci0gICAgdGhpcy5hbGxjbGFzc2VzID0gbnVsbDsKLSAgICB0aGlzLnN1cGVyY2xhc3MgPSBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgc3VwZXJjbGFzcyBmb3IgdGhpcyBzeW50aGV0aWMgY2xhc3MuCi0gICAqIE9iamVjdCBpcyBlcXVpdmFsZW50IHRvIE51bGwuCi0gICAqIENyZWF0aW9uIGRhdGU6ICgxMi0yNS05OSAxMjoyNjowMSBQTSkKLSAgICoKLSAgICogQHBhcmFtIHN1cGVyY2xhc3MKLSAgICogQHJldHVybiBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MKLSAgICoKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN1cGVyQ2xhc3MoQ2xhc3Mgc3VwZXJjbGFzcykgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIHRoaXMuc3VwZXJjbGFzcyA9IHN1cGVyY2xhc3M7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBzdXBlcmNsYXNzIGZvciB0aGlzIHN5bnRoZXRpYyBjbGFzcy4KLSAgICogQ3JlYXRpb24gZGF0ZTogKDEyLTI1LTk5IDEyOjI2OjAxIFBNKQotICAgKgotICAgKiBAcGFyYW0gc3VwZXJjbGFzcwotICAgKiBAcmV0dXJuIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcwotICAgKgotICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFN1cGVyQ2xhc3MoamF2YS5sYW5nLkNsYXNzIHN1cGVyY2xhc3MpCi0gICAgICAgICAgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIHRoaXMuc3VwZXJjbGFzcyA9IENsYXNzLmZvckNsYXNzKHN1cGVyY2xhc3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmRzIGEgcmVzb3VyY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuIFRoZQotICAgKiBydWxlcyBmb3Igc2VhcmNoaW5nIGZvciByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIGEKLSAgICogZ2l2ZW4gY2xhc3MgYXJlIGltcGxlbWVudGVkIGJ5IHRoZSBjbGFzcyBsb2FkZXIgb2YKLSAgICogdGhlIGNsYXNzLgotICAgKiA8cD4KLSAgICogVGhlIENsYXNzIG1ldGhvZHMgZGVsZWdhdGUgdG8gQ2xhc3NMb2FkZXIKLSAgICogbWV0aG9kcywgYWZ0ZXIgYXBwbHlpbmcgYSBuYW1pbmcgY29udmVudGlvbjogaWYKLSAgICogdGhlIHJlc291cmNlIG5hbWUgc3RhcnRzIHdpdGggIi8iLCBpdCBpcyB1c2VkIGFzIGlzLgotICAgKiBPdGhlcndpc2UsIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIGlzIHByZXBlbmRlZCwKLSAgICogYWZ0ZXIgY29udmVydGluZyAiLiIgdG8gIi8iLgotICAgKgotICAgKiBAcGFyYW0KLSAgICogbmFtZSAtIHRoZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSByZXNvdXJjZSB0bwotICAgKiBiZSBmb3VuZC4KLSAgICogdGhlIFVSTCBvYmplY3QgaGF2aW5nIHRoZSBzcGVjaWZpZWQgbmFtZSwgb3IKLSAgICogbnVsbCBpZiBubyByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZQotICAgKiBpcyBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBqYXZhLm5ldC5VUkwgZ2V0UmVzb3VyY2UoU3RyaW5nIG5hbWUpCi0gIHsKLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEZpbmRzIGEgcmVzb3VyY2Ugd2l0aCBhIGdpdmVuIG5hbWUuIFdpbGwgcmV0dXJuCi0gICAqIG51bGwgaWYgbm8gcmVzb3VyY2Ugd2l0aCB0aGlzIG5hbWUgaXMgZm91bmQuIFRoZQotICAgKiBydWxlcyBmb3Igc2VhcmNoaW5nIGEgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCBhCi0gICAqIGdpdmVuIGNsYXNzIGFyZSBpbXBsZW1lbnRlZCBieSB0aGUgQ2xhc3NMb2FkZXIgb2YKLSAgICogdGhlIGNsYXNzLgotICAgKiA8cD4KLSAgICogVGhlIENsYXNzIG1ldGhvZHMgZGVsZWdhdGUgdG8gQ2xhc3NMb2FkZXIKLSAgICogbWV0aG9kcywgYWZ0ZXIgYXBwbHlpbmcgYSBuYW1pbmcgY29udmVudGlvbjogaWYKLSAgICogdGhlIHJlc291cmNlIG5hbWUgc3RhcnRzIHdpdGggIi8iLCBpdCBpcyB1c2VkIGFzIGlzLgotICAgKiBPdGhlcndpc2UsIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIGlzIHByZXBlbmRlZCwKLSAgICogYWZ0ZXIgY29udmVydGluZyAiLiIgdG8gIi8iLgotICAgKgotICAgKiBAcGFyYW0KLSAgICogbmFtZSAtIHRoZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSByZXNvdXJjZSB0bwotICAgKiBiZSBmb3VuZAotICAgKiB0aGUgSW5wdXRTdHJlYW0gb2JqZWN0IGhhdmluZyB0aGUKLSAgICogc3BlY2lmaWVkIG5hbWUsIG9yIG51bGwgaWYgbm8gcmVzb3VyY2Ugd2l0aAotICAgKiB0aGUgc3BlY2lmaWVkIG5hbWUgaXMgZm91bmQuCi0gICAqLwotICBwdWJsaWMgamF2YS5pby5JbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKFN0cmluZyBuYW1lKQotICB7Ci0gICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHNpZ25lcnMgb2YgdGhpcyBjbGFzcy4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXSBnZXRTaWduZXJzKCkKLSAgewotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogSWYgdGhpcyBvYmplY3QgcmVwcmVzZW50cyBhbnkgY2xhc3Mgb3RoZXIgdGhhbiB0aGUKLSAgICogY2xhc3MgT2JqZWN0LCB0aGVuIHRoZSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZQotICAgKiBzdXBlcmNsYXNzIG9mIHRoYXQgY2xhc3MgaXMgcmV0dXJuZWQuCi0gICAqIDxwPgotICAgKiBJZiB0aGlzIG9iamVjdCBpcyB0aGUgb25lIHRoYXQgcmVwcmVzZW50cyB0aGUgY2xhc3MKLSAgICogT2JqZWN0IG9yIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMgYW4gaW50ZXJmYWNlLCBudWxsIGlzCi0gICAqIHJldHVybmVkLgotICAgKgotICAgKiB0aGUgc3VwZXJjbGFzcyBvZiB0aGUgY2xhc3MgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgQ2xhc3MgZ2V0U3VwZXJjbGFzcygpCi0gIHsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCAmJiBzdXBlcmNsYXNzID09IG51bGwpCi0gICAgewotICAgICAgc3VwZXJjbGFzcyA9IGZvckNsYXNzKHJlYWxjbGFzcy5nZXRTdXBlcmNsYXNzKCkpOwotCi0gICAgICAvLyBnZXREZWNsYXJlZENsYXNzZXMoKTsgLy8gU2V0cyBzdXBlcmNsYXNzIGFzIGEgc2lkZS1lZmZlY3QKLSAgICB9Ci0KLSAgICBpZiAoc3VwZXJjbGFzcyA9PSBudWxsKQotICAgICAgc3VwZXJjbGFzcyA9IGZvckNsYXNzKE9iamVjdC5jbGFzcyk7Ci0KLSAgICByZXR1cm4gc3VwZXJjbGFzczsKLSAgfQotCi0gIC8qKgotICAgKiBJZiB0aGlzIENsYXNzIG9iamVjdCByZXByZXNlbnRzIGFuIGFycmF5IHR5cGUsIHJldHVybnMKLSAgICogdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybnMgZmFsc2UuCi0gICAqCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0FycmF5KCkKLSAgewotICAgIHJldHVybiByZWFsY2xhc3MgIT0gbnVsbCAmJiByZWFsY2xhc3MuaXNBcnJheSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgaWYgdGhlIGNsYXNzIG9yIGludGVyZmFjZSByZXByZXNlbnRlZCBieQotICAgKiB0aGlzIENsYXNzIG9iamVjdCBpcyBlaXRoZXIgdGhlIHNhbWUgYXMsIG9yIGlzIGEKLSAgICogc3VwZXJjbGFzcyBvciBzdXBlcmludGVyZmFjZSBvZiwgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGUgc3BlY2lmaWVkIENsYXNzCi0gICAqIHBhcmFtZXRlci4gSXQgcmV0dXJucyB0cnVlIGlmIHNvLCBmYWxzZSBvdGhlcndpc2UuIElmCi0gICAqIHRoaXMgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZSwKLSAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgQ2xhc3MgcGFyYW1ldGVyIGlzCi0gICAqIGV4YWN0bHkgdGhpcyBDbGFzcyBvYmplY3QsIGZhbHNlIG90aGVyd2lzZS4KLSAgICogPHA+Ci0gICAqIFNwZWNpZmljYWxseSwgdGhpcyBtZXRob2QgdGVzdHMgd2hldGhlciB0aGUgdHlwZQotICAgKiByZXByZXNlbnRlZCBieSB0aGUgc3BlY2lmaWVkIENsYXNzIHBhcmFtZXRlciBjYW4KLSAgICogYmUgY29udmVydGVkIHRvIHRoZSB0eXBlIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3MKLSAgICogb2JqZWN0IHZpYSBhbiBpZGVudGl0eSBjb252ZXJzaW9uIG9yIHZpYSBhIHdpZGVuaW5nCi0gICAqIHJlZmVyZW5jZSBjb252ZXJzaW9uLiBTZWUgVGhlIEphdmEgTGFuZ3VhZ2UKLSAgICogU3BlY2lmaWNhdGlvbiwgc2VjdGlvbnMgNS4xLjEgYW5kIDUuMS40ICwgZm9yIGRldGFpbHMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBjbHMKLSAgICoKLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIENsYXNzIHBhcmFtZXRlciBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNBc3NpZ25hYmxlRnJvbShDbGFzcyBjbHMpCi0gIHsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCAmJiBjbHMucmVhbGNsYXNzICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGNsYXNzLmlzQXNzaWduYWJsZUZyb20oY2xzLnJlYWxjbGFzcyk7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgaWYgdGhlIGNsYXNzIG9yIGludGVyZmFjZSByZXByZXNlbnRlZCBieQotICAgKiB0aGlzIENsYXNzIG9iamVjdCBpcyBlaXRoZXIgdGhlIHNhbWUgYXMsIG9yIGlzIGEKLSAgICogc3VwZXJjbGFzcyBvciBzdXBlcmludGVyZmFjZSBvZiwgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSByZXByZXNlbnRlZCBieSB0aGUgc3BlY2lmaWVkIENsYXNzCi0gICAqIHBhcmFtZXRlci4gSXQgcmV0dXJucyB0cnVlIGlmIHNvLCBmYWxzZSBvdGhlcndpc2UuIElmCi0gICAqIHRoaXMgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZSwKLSAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgQ2xhc3MgcGFyYW1ldGVyIGlzCi0gICAqIGV4YWN0bHkgdGhpcyBDbGFzcyBvYmplY3QsIGZhbHNlIG90aGVyd2lzZS4KLSAgICogPHA+Ci0gICAqIFNwZWNpZmljYWxseSwgdGhpcyBtZXRob2QgdGVzdHMgd2hldGhlciB0aGUgdHlwZQotICAgKiByZXByZXNlbnRlZCBieSB0aGUgc3BlY2lmaWVkIENsYXNzIHBhcmFtZXRlciBjYW4KLSAgICogYmUgY29udmVydGVkIHRvIHRoZSB0eXBlIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3MKLSAgICogb2JqZWN0IHZpYSBhbiBpZGVudGl0eSBjb252ZXJzaW9uIG9yIHZpYSBhIHdpZGVuaW5nCi0gICAqIHJlZmVyZW5jZSBjb252ZXJzaW9uLiBTZWUgVGhlIEphdmEgTGFuZ3VhZ2UKLSAgICogU3BlY2lmaWNhdGlvbiwgc2VjdGlvbnMgNS4xLjEgYW5kIDUuMS40ICwgZm9yIGRldGFpbHMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBjbHMKLSAgICoKLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgc3BlY2lmaWVkIENsYXNzIHBhcmFtZXRlciBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNBc3NpZ25hYmxlRnJvbShqYXZhLmxhbmcuQ2xhc3MgY2xzKQotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGNsYXNzLmlzQXNzaWduYWJsZUZyb20oKGphdmEubGFuZy5DbGFzcykgY2xzKTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgaXMgdGhlIGR5bmFtaWMgZXF1aXZhbGVudCBvZiB0aGUgSmF2YQotICAgKiBsYW5ndWFnZSBpbnN0YW5jZW9mIG9wZXJhdG9yLiBUaGUgbWV0aG9kCi0gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIE9iamVjdCBhcmd1bWVudCBpcwotICAgKiBub24tbnVsbCBhbmQgY2FuIGJlIGNhc3QgdG8gdGhlIHJlZmVyZW5jZSB0eXBlCi0gICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ2xhc3Mgb2JqZWN0IHdpdGhvdXQgcmFpc2luZyBhCi0gICAqIENsYXNzQ2FzdEV4Y2VwdGlvbi4gSXQgcmV0dXJucyBmYWxzZSBvdGhlcndpc2UuCi0gICAqIDxwPgotICAgKiBTcGVjaWZpY2FsbHksIGlmIHRoaXMgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMgYQotICAgKiBkZWNsYXJlZCBjbGFzcywgcmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgT2JqZWN0Ci0gICAqIGFyZ3VtZW50IGlzIGFuIGluc3RhbmNlIG9mIHRoZSByZXByZXNlbnRlZCBjbGFzcyAob3IKLSAgICogb2YgYW55IG9mIGl0cyBzdWJjbGFzc2VzKTsgZmFsc2Ugb3RoZXJ3aXNlLiBJZiB0aGlzCi0gICAqIENsYXNzIG9iamVjdCByZXByZXNlbnRzIGFuIGFycmF5IGNsYXNzLCByZXR1cm5zIHRydWUKLSAgICogaWYgdGhlIHNwZWNpZmllZCBPYmplY3QgYXJndW1lbnQgY2FuIGJlIGNvbnZlcnRlZAotICAgKiB0byBhbiBvYmplY3Qgb2YgdGhlIGFycmF5IHR5cGUgYnkgYW4gaWRlbnRpdHkKLSAgICogY29udmVyc2lvbiBvciBieSBhIHdpZGVuaW5nIHJlZmVyZW5jZSBjb252ZXJzaW9uOwotICAgKiBmYWxzZSBvdGhlcndpc2UuIElmIHRoaXMgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMgYW4KLSAgICogaW50ZXJmYWNlLCByZXR1cm5zIHRydWUgaWYgdGhlIGNsYXNzIG9yIGFueSBzdXBlcmNsYXNzCi0gICAqIG9mIHRoZSBzcGVjaWZpZWQgT2JqZWN0IGFyZ3VtZW50IGltcGxlbWVudHMgdGhpcwotICAgKiBpbnRlcmZhY2U7IGZhbHNlIG90aGVyd2lzZS4gSWYgdGhpcyBDbGFzcyBvYmplY3QKLSAgICogcmVwcmVzZW50cyBhIHByaW1pdGl2ZSB0eXBlLCByZXR1cm5zIGZhbHNlLgotICAgKgotICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3QgdG8gY2hlY2sKLSAgICoKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzSW5zdGFuY2UoT2JqZWN0IG9iaikKLSAgewotCi0gICAgaWYgKHJlYWxjbGFzcyAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxjbGFzcy5pc0luc3RhbmNlKG9iaik7Ci0KLSAgICAvLyBTY2FuIGluaGVyaXRhbmNlcz8gKHJlbGlhYmxlKS4KLSAgICAvLyBDaGVjayBuYW1lPyAobm90IHJlbGlhYmxlKS4KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGVybWluZXMgaWYgdGhlIHNwZWNpZmllZCBDbGFzcyBvYmplY3QgcmVwcmVzZW50cwotICAgKiBhbiBpbnRlcmZhY2UgdHlwZS4KLSAgICoKLSAgICogdHJ1ZSBpZiB0aGlzIG9iamVjdCByZXByZXNlbnRzIGFuIGludGVyZmFjZTsKLSAgICogZmFsc2Ugb3RoZXJ3aXNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNJbnRlcmZhY2UoKQotICB7Ci0gICAgcmV0dXJuIChyZWFsY2xhc3MgIT0gbnVsbCkgPyByZWFsY2xhc3MuaXNJbnRlcmZhY2UoKSA6IGlzSW50ZXJmYWNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFzc2VydCB0aGF0IHRoZSBzcGVjaWZpZWQgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMKLSAgICogYW4gaW50ZXJmYWNlIHR5cGUuIENhbid0IGJlIGNoYW5nZWQgYWZ0ZXIgcmVhbCBjbGFzcyBsb2FkZWQuCi0gICAqCi0gICAqIEBwYXJhbQotICAgKiB0cnVlIGlmIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMgYW4gaW50ZXJmYWNlOwotICAgKiBmYWxzZSBvdGhlcndpc2UuCi0gICAqCi0gICAqIEBwYXJhbSBpc0ludGVyZmFjZQotICAgKgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaXNJbnRlcmZhY2UoYm9vbGVhbiBpc0ludGVyZmFjZSkgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzID09IG51bGwpCi0gICAgICB0aGlzLmlzSW50ZXJmYWNlID0gaXNJbnRlcmZhY2U7Ci0gICAgZWxzZSBpZiAocmVhbGNsYXNzLmlzSW50ZXJmYWNlKCkgIT0gaXNJbnRlcmZhY2UpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLSAgfQotCi0gIC8qKgotICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBzcGVjaWZpZWQgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudHMKLSAgICogYSBwcmltaXRpdmUgSmF2YSB0eXBlLgotICAgKiA8cD4KLSAgICogVGhlcmUgYXJlIG5pbmUgcHJlZGVmaW5lZCBDbGFzcyBvYmplY3RzIHRvCi0gICAqIHJlcHJlc2VudCB0aGUgZWlnaHQgcHJpbWl0aXZlIEphdmEgdHlwZXMgYW5kIHZvaWQuCi0gICAqIFRoZXNlIGFyZSBjcmVhdGVkIGJ5IHRoZSBKYXZhIFZpcnR1YWwgTWFjaGluZSwgYW5kCi0gICAqIGhhdmUgdGhlIHNhbWUgbmFtZXMgYXMgdGhlIHByaW1pdGl2ZSB0eXBlcyB0aGF0Ci0gICAqIHRoZXkgcmVwcmVzZW50LCBuYW1lbHkgYm9vbGVhbiwgYnl0ZSwgY2hhciwgc2hvcnQsCi0gICAqIGludCwgbG9uZywgZmxvYXQsIGFuZCBkb3VibGUsIGFuZCB2b2lkLgotICAgKiA8cD4KLSAgICogVGhlc2Ugb2JqZWN0cyBtYXkgb25seSBiZSBhY2Nlc3NlZCB2aWEgdGhlCi0gICAqIGZvbGxvd2luZyBwdWJsaWMgc3RhdGljIGZpbmFsIHZhcmlhYmxlcywgYW5kIGFyZSB0aGUKLSAgICogb25seSBDbGFzcyBvYmplY3RzIGZvciB3aGljaCB0aGlzIG1ldGhvZCByZXR1cm5zCi0gICAqIHRydWUuCi0gICAqCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1ByaW1pdGl2ZSgpCi0gIHsKLSAgICByZXR1cm4gcmVhbGNsYXNzICE9IG51bGwgJiYgcmVhbGNsYXNzLmlzUHJpbWl0aXZlKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIGNsYXNzLgotICAgKgotICAgKiBhIG5ld2x5IGFsbG9jYXRlZCBpbnN0YW5jZSBvZiB0aGUgY2xhc3MKLSAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QuIFRoaXMgaXMgZG9uZQotICAgKiBleGFjdGx5IGFzIGlmIGJ5IGEgbmV3IGV4cHJlc3Npb24gd2l0aCBhbgotICAgKiBlbXB0eSBhcmd1bWVudCBsaXN0LgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIGNsYXNzIG9yIGluaXRpYWxpemVyIGlzIG5vdCBhY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24KLSAgICogaWYgYW4gYXBwbGljYXRpb24gdHJpZXMgdG8gaW5zdGFudGlhdGUgYW4KLSAgICogYWJzdHJhY3QgY2xhc3Mgb3IgYW4gaW50ZXJmYWNlLCBvciBpZiB0aGUKLSAgICogaW5zdGFudGlhdGlvbiBmYWlscyBmb3Igc29tZSBvdGhlciByZWFzb24uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IG5ld0luc3RhbmNlKCkKLSAgICAgICAgICB0aHJvd3MgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICB7Ci0gICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0cyB0aGUgb2JqZWN0IHRvIGEgc3RyaW5nLiBUaGUgc3RyaW5nCi0gICAqIHJlcHJlc2VudGF0aW9uIGlzIHRoZSBzdHJpbmcgImNsYXNzIiBvcgotICAgKiAiaW50ZXJmYWNlIiBmb2xsb3dlZCBieSBhIHNwYWNlIGFuZCB0aGVuIHRoZQotICAgKiBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgY2xhc3MuIElmIHRoaXMgQ2xhc3MKLSAgICogb2JqZWN0IHJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZSwgcmV0dXJucyB0aGUKLSAgICogbmFtZSBvZiB0aGUgcHJpbWl0aXZlIHR5cGUuCi0gICAqIDxwPgotICAgKiAgU2hvdWxkIHRoaXMgc2F5ICJzeW50aGV0aWMiIGFzIHdlbGwgYXMgImNsYXNzIiBvcgotICAgKiAiaW50ZXJmYWNlIj8gT3Igc2hvdWxkIHRoYXQgYmUgZ2F0ZWQgb24gd2hldGhlciB3ZSdyZSBwcm94eQotICAgKiB0byBhIHJlYWxjbGFzcz8KLSAgICoKLSAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNsYXNzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQotICB7Ci0KLSAgICBpZiAocmVhbGNsYXNzICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGNsYXNzLnRvU3RyaW5nKCk7Ci0gICAgZWxzZSBpZiAoaXNJbnRlcmZhY2UoKSkKLSAgICAgIHJldHVybiAiaW50ZXJmYWNlICIgKyBuYW1lOwotICAgIGVsc2UKLSAgICAgIHJldHVybiAiY2xhc3MgIiArIG5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVuaWVuY2UgZm9yIHdyaXRpbmcgdG8sIGVnLCBTeXN0ZW0ub3V0IAotICAgKgotICAgKiBAcGFyYW0gb3V0Ci0gICAqIEBwYXJhbSBkZXB0aAotICAgKi8KLSAgcHVibGljIHZvaWQgdG9Tb3VyY2UoamF2YS5pby5PdXRwdXRTdHJlYW0gb3V0LCBpbnQgZGVwdGgpCi0gIHsKLQotICAgIGphdmEuaW8uUHJpbnRXcml0ZXIgd3JpdGVyID0gbmV3IGphdmEuaW8uUHJpbnRXcml0ZXIob3V0KTsKLQotICAgIHRvU291cmNlKHdyaXRlciwgZGVwdGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIHRoZSBvYmplY3QgdG8gYSBKYXZhIGNvZGUgc3RyZWFtLiBUaGUgc3RyaW5nCi0gICAqIHJlcHJlc2VudGF0aW9uIGlzIGFzIGZ1bGwgYSBKYXZhIGRlZmluaXRpb24gb2YgdGhlIGNsYXNzCi0gICAqIGFzIHdlIGFyZSBhYmxlIHRvIGFjaGlldmUuIElmIHRoaXMgQ2xhc3MKLSAgICogb2JqZWN0IHJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZSwgcmV0dXJucyB0aGUKLSAgICogbmFtZSBvZiB0aGUgcHJpbWl0aXZlIHR5cGUuCi0gICAqCi0gICAqIEBwYXJhbSBvdXQKLSAgICogQHBhcmFtIGRlcHRoCi0gICAqLwotICBwdWJsaWMgdm9pZCB0b1NvdXJjZShqYXZhLmlvLlByaW50V3JpdGVyIG91dCwgaW50IGRlcHRoKQotICB7Ci0KLSAgICBTdHJpbmcgdGFiID0gdGFic2V0KGRlcHRoKTsKLQotICAgIGlmIChyZWFsY2xhc3MgIT0gbnVsbCkKLSAgICAgIG91dC5wcmludGxuKAotICAgICAgICB0YWIKLSAgICAgICAgKyAiLyoqIENvZGUgYmFjay1nZW5lcmF0ZWQgZnJvbSBhIFwicmVhbFwiIENsYXNzOyBhY2N1cmFjeSBsaW1pdGVkIGJ5IHJlZmxlY3Rpb24gQVBJcy4gKi8iKTsKLSAgICBlbHNlCi0gICAgICBvdXQucHJpbnRsbigKLSAgICAgICAgdGFiCi0gICAgICAgICsgIi8qKiBDb2RlIGdlbmVyYXRlZCB2aWEgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzICovIik7Ci0KLSAgICAvKiBQYWNrYWdlIHNob3VsZCBub3QgYmUgcHJpbnRlZCBmb3IgaW5uZXIgY2xhc3NlcyAqLwotICAgIGlmIChnZXREZWNsYXJpbmdDbGFzcygpID09IG51bGwpCi0gICAgICBvdXQucHJpbnRsbih0YWIgKyAicGFja2FnZSAiICsgZ2V0UGFja2FnZU5hbWUoKSArICI7Iik7Ci0KLSAgICBvdXQucHJpbnQodGFiICsgTW9kaWZpZXIudG9TdHJpbmcoZ2V0TW9kaWZpZXJzKCkpKTsKLQotICAgIGlmIChpc0ludGVyZmFjZSgpKQotICAgICAgb3V0LnByaW50KCIgaW50ZXJmYWNlICIpOwotICAgIGVsc2UKLSAgICAgIG91dC5wcmludCgiIGNsYXNzICIpOwotCi0gICAgb3V0LnByaW50bG4oZ2V0SmF2YVNob3J0TmFtZSgpKTsKLQotICAgIGlmIChzdXBlcmNsYXNzICE9IG51bGwpCi0gICAgewotICAgICAgb3V0LnByaW50KCdcbicgKyB0YWIgKyAiIGV4dGVuZHMgIiArIHN1cGVyY2xhc3MuZ2V0SmF2YU5hbWUoKSk7Ci0gICAgfQotCi0gICAgQ2xhc3NbXSBleHQgPSBnZXRJbnRlcmZhY2VzKCk7Ci0KLSAgICBpZiAoZXh0ICE9IG51bGwgJiBleHQubGVuZ3RoID4gMCkKLSAgICB7Ci0KLSAgICAgIC8vIEludGVyZmFjZXMgZXh0ZW5kIG90aGVyIGludGVyZmFjZXMsCi0gICAgICAvLyBDbGFzc2VzIGltcGxlbWVudCBpbnRlcmZhY2VzLgotICAgICAgb3V0LnByaW50KCdcbicgKyB0YWIgKyAoaXNJbnRlcmZhY2UgPyAiIGV4dGVuZHMgIiA6ICIgaW1wbGVtZW50cyAiKQotICAgICAgICAgICAgICAgICsgZXh0WzBdLmdldE5hbWUoKSk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZXh0Lmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBvdXQucHJpbnQoIiwgIiArIGV4dFtpXS5nZXRKYXZhTmFtZSgpKTsKLSAgICAgIH0KLQotICAgICAgb3V0LnByaW50KCJcbiIpOwotICAgIH0KLQotICAgIG91dC5wcmludCh0YWIgKyAie1xuIik7Ci0KLSAgICB0YWIgPSB0YWJzZXQoKytkZXB0aCk7Ci0KLSAgICAvLyBGaWVsZHMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIEZpZWxkW10gZmllbGRzID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGZpZWxkcyA9IGdldERlY2xhcmVkRmllbGRzKCk7Ci0gICAgfQotICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIG91dC5wcmludGxuKHRhYiArICIvL1NlY3VyaXR5RXhjZXB0aW9uIHJldHJpZXZpbmcgZmllbGRzIik7Ci0gICAgfQotCi0gICAgaWYgKGZpZWxkcyAhPSBudWxsKQotICAgIHsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBvdXQucHJpbnRsbih0YWIgKyBmaWVsZHNbaV0udG9Tb3VyY2UoKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gQ29uc3RydWN0b3JzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLSAgICBDb25zdHJ1Y3RvcltdIGN0b3JzID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGN0b3JzID0gZ2V0RGVjbGFyZWRDb25zdHJ1Y3RvcnMoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgb3V0LnByaW50bG4odGFiICsgIi8vU2VjdXJpdHlFeGNlcHRpb24gcmV0cmlldmluZyBjdG9ycyIpOwotICAgIH0KLQotICAgIGlmIChjdG9ycyAhPSBudWxsKQotICAgIHsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3RvcnMubGVuZ3RoOyArK2kpCi0gICAgICB7Ci0gICAgICAgIG91dC5wcmludChjdG9yc1tpXS50b1NvdXJjZSh0YWIpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBNZXRob2RzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIE1ldGhvZFtdIG1ldGhvZHMgPSBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgbWV0aG9kcyA9IGdldERlY2xhcmVkTWV0aG9kcygpOwotICAgIH0KLSAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBvdXQucHJpbnRsbih0YWIgKyAiLy9TZWN1cml0eUV4Y2VwdGlvbiByZXRyaWV2aW5nIG1ldGhvZHMiKTsKLSAgICB9Ci0KLSAgICBpZiAobWV0aG9kcyAhPSBudWxsKQotICAgIHsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7ICsraSkKLSAgICAgIHsKLSAgICAgICAgb3V0LnByaW50KCdcbicpOwotICAgICAgICBvdXQucHJpbnQobWV0aG9kc1tpXS50b1NvdXJjZSh0YWIpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBJbm5lciBjbGFzc2VzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0gICAgQ2xhc3NbXSBpbm5lcnMgPSBnZXRJbm5lckNsYXNzZXMoKTsKLQotICAgIGlmIChpbm5lcnMgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlubmVycy5sZW5ndGg7ICsraSkKLSAgICAgIHsKLSAgICAgICAgb3V0LnByaW50KCdcbicpOwotICAgICAgICBpbm5lcnNbaV0udG9Tb3VyY2Uob3V0LCBkZXB0aCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gRG9uZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotICAgIHRhYiA9IHRhYnNldCgtLWRlcHRoKTsKLQotICAgIG91dC5wcmludCh0YWIgKyAifVxuIik7Ci0gICAgb3V0LmZsdXNoKCk7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIHRhYnNldCAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGRlcHRoCi0gICAqCi0gICAqICh0YWJzZXQpIEByZXR1cm4KLSAgICovCi0gIHByaXZhdGUgU3RyaW5nIHRhYnNldChpbnQgZGVwdGgpCi0gIHsKLQotICAgIFN0cmluZ0J1ZmZlciB0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCi0gICAgd2hpbGUgKGRlcHRoLS0gPiAwKQotICAgIHsKLSAgICAgIHQuYXBwZW5kKCIgICAgIik7Ci0gICAgfQotCi0gICAgcmV0dXJuIHQudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8vIElnbm9yZXMgYW55IGtleXdvcmRzIHdlIGRvbid0IHJlY29nbml6ZQotCi0gIC8qKiBGaWVsZCB2YWwgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIGludFtdIHZhbCA9IHsgTW9kaWZpZXIuQUJTVFJBQ1QsIE1vZGlmaWVyLkZJTkFMLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllci5JTlRFUkZBQ0UsIE1vZGlmaWVyLk5BVElWRSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZXIuUFJJVkFURSwgTW9kaWZpZXIuUFJPVEVDVEVELAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllci5QVUJMSUMsIE1vZGlmaWVyLlNUQVRJQywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZXIuU1lOQ0hST05JWkVELCBNb2RpZmllci5UUkFOU0lFTlQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1vZGlmaWVyLlZPTEFUSUxFIH07Ci0KLSAgLyoqIEZpZWxkIGt3ZCAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgU3RyaW5nW10ga3dkID0geyAiYWJzdHJhY3QiLCAiZmluYWwiLCAiaW50ZXJmYWNlIiwgIm5hdGl2ZSIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcml2YXRlIiwgInByb3RlY3RlZCIsICJwdWJsaWMiLCAic3RhdGljIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN5bmNocm9uaXplZCIsICJ0cmFuc2llbnQiLCAidm9sYXRpbGUiIH07Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCBtb2RpZmllckZyb21TdHJpbmcgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB0Ci0gICAqCi0gICAqIChtb2RpZmllckZyb21TdHJpbmcpIEByZXR1cm4KLSAgICovCi0gIHN0YXRpYyBwdWJsaWMgaW50IG1vZGlmaWVyRnJvbVN0cmluZyhTdHJpbmcgdCkKLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrd2QubGVuZ3RoOyArK2kpCi0gICAgewotICAgICAgaWYgKGt3ZFtpXS5lcXVhbHModCkpCi0gICAgICAgIHJldHVybiB2YWxbaV07Ci0gICAgfQotCi0gICAgcmV0dXJuIDA7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIG1vZGlmaWVyc0Zyb21TdHJpbmcgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzCi0gICAqCi0gICAqIChtb2RpZmllcnNGcm9tU3RyaW5nKSBAcmV0dXJuCi0gICAqLwotICBzdGF0aWMgcHVibGljIGludCBtb2RpZmllcnNGcm9tU3RyaW5nKFN0cmluZyBzKQotICB7Ci0KLSAgICBpbnQgbW9kcyA9IDA7Ci0gICAgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplciBwYXJ0cyA9IG5ldyBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyKHMpOwotCi0gICAgd2hpbGUgKHBhcnRzLmhhc01vcmVUb2tlbnMoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgdCA9IHBhcnRzLm5leHRUb2tlbigpOwotCi0gICAgICBtb2RzIHw9IG1vZGlmaWVyRnJvbVN0cmluZyh0KTsKLSAgICB9Ci0KLSAgICByZXR1cm4gbW9kczsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9KYXZhVXRpbHMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvSmF2YVV0aWxzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGIzOTc0NTQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9KYXZhVXRpbHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIzMSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMSAKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uIAotICoKLSAqICRJZCQgCi0gKi8KLQotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWM7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi0vKiogCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3Mgc3VwcG9ydHMgaW52b2tpbmcgSmF2YSBjb21waWxhdGlvbiBmcm9tIHdpdGhpbgotICogYSBKYXZhIHByb2dyYW0uIFJlY2VudCB2ZXJzaW9ucyBvZiB0aGUgSmF2YSBlbnZpcm9ubWVudCBoYXZlCi0gKiBwcm92aWRlZCBzdWNoIGFuIEFQSSAoaW4gdG9vbHMuamFyKS4gQnV0IHRoYXQgaXNuJ3QgYXZhaWxhYmxlCi0gKiBvbiBhbGwgcGxhdGZvcm1zLCBhbmQgYSBmYWxsYmFjayB0byB0aGUgY29tbWFuZCBsaW5lIG1heSBiZSBuZWVkZWQKLSAqICh0aG91Z2ggdGhpcyB0b28gbWF5IG5vdCBhbHdheXMgYmUgYXZhaWxhYmxlLCBlZy4gZm9yIHNlY3VyaXR5Ci0gKiByZWFzb25zKS4KLSAqIDxwPgotICogVGhlcmUncyBhbiBhZGRpdGlvbmFsIGNvbXBsaWNhdGlvbiBpbiBzb21lIGVudmlyb25tZW50cyAtLQotICogc3VjaCBhcyBNaWNyb3NvZnQncyBWSisrIC0tIHdoZXJlIHRoZSBjbGFzc3BhdGggYXMgc2VlbiBpbgotICogdGhlIFN5c3RlbSBQcm9wZXJ0aWVzIG1heSBub3QgYmUgdGhlIG9uZSB0aGUgdXNlciBleHBlY3RzLgotICogVGhlIGNvZGUgaGVyZSBpcyBwYXJhbWV0ZXJpemVkIHRvIHRyeSB0byBkZWFsIHdpdGggdGhhdC4KLSAqLwotcHVibGljIGNsYXNzIEphdmFVdGlscwotewotICAgICAgICAvLyBPbmUtdGltZSBmbGFnIGZvciB3aGV0aGVyIHdlIGNvdWxkIGR5bmFtaWNhbGx5IGxvYWQgY29tcGlsZXIgQVBJCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gY2FudExvYWRDb21waWxlcj1mYWxzZTsgCi0KLSAgICAgICAgLy8gRGVidWcgZmxhZyAtIGdlbmVyYXRlcyBkZWJ1ZyBzdHVmZiBpZiB0cnVlLgotICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7Ci0gIAotICAgICAgICAvKiogQ29udHJvbCB3aGV0aGVyIGNvbXBpbGF0aW9uIG9jY3VycyB3aXRoIHRoZSAtZyBvcHRpb24KLSAgICAgICAgICogKGRlYnVnZ2luZyBpbmZvcm1hdGlvbiBpbmNsdWRlZCBpbiBnZW5lcmF0ZWQgY2xhc3NmaWxlKS4KLSAgICAgICAgICogVGhpcyBpcyBhbiBhdHRyaWJ1dGUsIHJhdGhlciB0aGFuIGEgcGFyYW1ldGVyIG9uIHRoZSBjb21waWxlCi0gICAgICAgICAqIG1ldGhvZCwgbGFyZ2VseSBiZWNhdXNlIGl0IHRlbmRzIHRvIGJlIGFuIGFsbC1vci1ub3RoaW5nIGRlY2lzaW9uOyAKLSAgICAgICAgICogZ2VuZXJhbGx5IHlvdSdyZSBlaXRoZXIgZG9pbmcgcHJvZ3JhbSBkZXZlbG9wbWVudCBhbmQgd2FudCBpdCwKLSAgICAgICAgICogb3IgcnVubmluZyBpbiBwcm9kdWN0aW9uIG1vZGUgYW5kIGRvbid0LiBCdXQgdGhhdCBtYXkgbm90IG1hdGNoCi0gICAgICAgICAqIHRoZSBuZWVkcyBvZiBmdXR1cmUgdXNlcnMuLi4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIFRPRE86IENvbnNpZGVyIHdoZXRoZXIgZGVidWcgc2hvdWxkIGJlIGEgcGFyYW1ldGVyLgotICAgICAgICAgKiAKLSAgICAgICAgICogQHBhcmFtIGJvb2xlYW4gbmV3RGVidWcgVHJ1ZSB0byByZXF1ZXN0IGRlYnVnZ2luZyBkYXRhLAotICAgICAgICAgKiBmYWxzZSB0byByZXF1ZXN0IG9wdGltaXplZCBvdXRwdXQuIChJdCdzIHVuY29tbW9uIHRvCi0gICAgICAgICAqIHdhbnQgYm90aCBvciBuZWl0aGVyISkKLSAgICAgICAgICovIAotICAgICAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0RGVidWcoYm9vbGVhbiBuZXdEZWJ1ZykKLSAgICAgICAgewotICAgICAgICAgICAgZGVidWc9bmV3RGVidWc7Ci0gICAgICAgIH0KLQotICAgICAgICAvKiogVHJ5IHRvIGNvbXBpbGUgYSAuamF2YSBmaWxlIG9uIGRpc2suIFRoaXMgd2lsbCBmaXJzdCBhdHRlbXB0IHRvCi0gICAgICAgICAqIHVzZSB0aGUgc3VuLmphdmEudG9vbHMuamF2YWMoKSBtZXRob2QsIHRoZW4gKGlmIHRoYXQgaXMgdW5hdmFpbGFibGUpCi0gICAgICAgICAqIGZhbGwgYmFjayB1cG9uIHNoZWxsaW5nIG91dCB0byBhIGNvbW1hbmQgbGluZSBhbmQgcnVubmluZyBqYXZhYwotICAgICAgICAgKiB0aGVyZS4KLSAgICAgICAgICogPHA+Ci0gICAgICAgICAqIE5PVEU6IFRoaXMgbXVzdCBiZSBfY29tcGlsZWRfIHdpdGggc3VuLmphdmEudG9vbHMuKiAodG9vbHMuamFyKQotICAgICAgICAgKiBhdmFpbGFibGUuIFdlIGNvdWxkIGNoYW5nZSB0aGF0IHRvIHVzZSByZWZsZWN0aW9uIGluc3RlYWQsIGlmIHdlCi0gICAgICAgICAqIGFjY2VwdCBzb21lIG92ZXJoZWFkLi4uIG1pbm9yIGNvbXBhcmVkIHRvIHRoZSBjb3N0IG9mIHJ1bm5pbmcgdGhlCi0gICAgICAgICAqIGNvbXBpbGVyIQotICAgICAgICAgKiA8cD4KLSAgICAgICAgICogVGhpcyBoYXMgY29tcGxpY2F0aW9ucyBvbiBzb21lIHBsYXRmb3Jtcy4gRm9yIGV4YW1wbGUsIHVuZGVyIAotICAgICAgICAgKiBNaWNyb3NvZnQgVmlzdWFsIEphdmEgKysgKGF0IGxlYXN0LCBhcyBpbnN0YWxsZWQgb24gbXkgdGVzdCBzeXN0ZW0pLAotICAgICAgICAgKiBJIGZvdW5kIHRoYXQgSSBoYWQgdG8gc3BlY2lmeSBwYXRocyB0byBib3RoIGphdmFjIGFuZCB4ZXJjZXMuamFyCi0gICAgICAgICAqIHJhdGhlciB0aGFuIGNvdW50aW5nIG9uIHRoZSBzaGVsbCdzIHBhdGggYW5kIGNsYXNzcGF0aCBoYXZpbmcKLSAgICAgICAgICogYmVlbiBzZXQgdG8gcmVhY2ggdGhlc2UuIEZvciB0aGF0IHJlYXNvbiBJJ3ZlIHBhcmFtZXRlcml6ZWQgdGhpcwotICAgICAgICAgKiBtZXRob2Qgd2l0aCBhIGZldyBzeXN0ZW0gcHJvcGVydGllcywgc28geW91IGNhbiBhZGFwdCBpdCB0byB5b3VyCi0gICAgICAgICAqIG93biBzeXN0ZW0ncyBuZWVkcyB3aXRob3V0IG1vZGlmeWluZyB0aGUgY29kZToKLSAgICAgICAgICogPGRsPgotICAgICAgICAgKiA8ZHQ+b3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLmphdmFjCi0gICAgICAgICAqIDxkZD5Db21tYW5kIGxpbmUgaXNzdWVkIHRvIGludm9rZSB0aGUgY29tcGlsZXIuIERlZmF1bHRzIHRvICJqYXZhYyIsCi0gICAgICAgICAqIHdoaWNoIHNob3VsZCB3b3JrIGluIG1vc3Qgc3lzdGVtcy4gSW4gVkorKywgdHJ5IHNldHRpbmcgaXQgdG8KLSAgICAgICAgICogImNtZCAvYyAlSkFWQV9IT01FJVxcYmluXGphdmFjLmV4ZSIKLSAgICAgICAgICogPGR0Pm9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5tb3JlY2xhc3NwYXRoCi0gICAgICAgICAqIDxkZD5BZGRpdGlvbmFsIGNsYXNzcGF0aCwgdG8gYmUgcHJlcGVuZGVkIHRvIHRoZSBvbmUgcmV0cmlldmVkIGZyb20KLSAgICAgICAgICogamF2YS5jbGFzcy5wYXRoLiBEZWZhdWx0cyB0byAiIiAoZW1wdHkpLiBJbiBWSisrLCB0cnkgc2V0dGluZyBpdCB0bwotICAgICAgICAgKiBwb2ludCB0byB5b3VyIGNvcHkgb2YgeGVyY2VzLmphciwgd2hpY2ggbWF5IG5vdCBiZSBmb3VuZCBvdGhlcndpc2UuCi0gICAgICAgICAqIFRPRE86IFJlY29uc2lkZXIgcHJlcGVuZCB2ZXJzdXMgYXBwZW5kIQotICAgICAgICAgKiA8L2RsPgotICAgICAgICAgKiAKLSAgICAgICAgICogQHBhcmFtIFN0cmluZyBmaWxlTmFtZSBXaGljaCAuamF2YSBmaWxlIHRvIGNvbXBpbGUuIE5vdGUgdGhhdCB0aGlzIG1heQotICAgICAgICAgKiBiZSByZWxhdGl2ZSB0byB0aGUgImN1cnJlbnQgZGlyZWN0b3J5Ii4KLSAgICAgICAgICogQHBhcmFtIFN0cmluZyBjbGFzc1BhdGggQWRkaXRpb25hbCBwbGFjZXMgdG8gbG9vayBmb3IgY2xhc3NlcyB0aGF0Ci0gICAgICAgICAqIHRoaXMgLmphdmEgZmlsZSBkZXBlbmRzIHVwb24uIEJlY29tZXMgdGhlIGphdmFjIGNvbW1hbmQncwotICAgICAgICAgKiAtY2xhc3NwYXRoIHBhcmFtZXRlciB2YWx1ZS4KLSAgICAgICAgICogQHJldHVybiBib29sZWFuIFRydWUgaWZmIGNvbXBpbGF0aW9uIHN1Y2NlZWRlZC4KLSAgICAgICAgICovCi0gICAgICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBKREtjb21waWxlKFN0cmluZyBmaWxlTmFtZSwgU3RyaW5nIGNsYXNzUGF0aCkKLSAgICAgICAgewotICAgICAgICAgICAgICAgIFN0cmluZyBtb3JlQ2xhc3NQYXRoPQotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KCJvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMubW9yZWNsYXNzcGF0aCIsIiIpCi0gICAgICAgICAgICAgICAgICAgICAgICAudHJpbSgpOwotICAgICAgICAgICAgICAgIGlmKG1vcmVDbGFzc1BhdGgubGVuZ3RoKCk+MCkKLSAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzUGF0aD1tb3JlQ2xhc3NQYXRoKyc7JytjbGFzc1BhdGg7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIGlmIChkZWJ1ZykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4gKCJKYXZhRW5naW5lOiBDb21waWxpbmcgIiArIGZpbGVOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbiAoIkphdmFFbmdpbmU6IENsYXNzcGF0aCBpcyAiICsgY2xhc3NQYXRoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgCi0gICAgICAgICAgICAgICAgU3RyaW5nIGNvZGVfb3B0aW9uID0gZGVidWcgPyAiLWciIDogIi1PIjsKLQotICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGJ5IHRyeWluZyBTdW4ncyBjb21waWxlciBBUEkKLSAgICAgICAgICAgIGlmKCFjYW50TG9hZENvbXBpbGVyKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhcmdzW10gPSB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVfb3B0aW9uLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICItY2xhc3NwYXRoIiwgY2xhc3NQYXRoLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZQotICAgICAgICAgICAgICAgICAgICAgICAgfTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICB0cnkKLS8vIAkJCSAgICB7Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgc3VuLnRvb2xzLmphdmFjLk1haW4oU3lzdGVtLmVyciwgImphdmFjIikuY29tcGlsZShhcmdzKTsKLS8vICAgICAgICAgICAgICAgICAgICAgICAgIH0KLS8vICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChUaHJvd2FibGUgdGgpCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiSU5GT1JNQVRJT05BTDogVW5hYmxlIHRvIGxvYWQgSmF2YSBjb21waWxlciBBUEkgKGVnIHRvb2xzLmphcikuIik7Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXHRTd2l0Y2hpbmcgdG8gY29tbWFuZC1saW5lIGludm9jYXRpb24uIik7Ci0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbnRMb2FkQ29tcGlsZXI9dHJ1ZTsKLS8vICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgCi0gICAgICAgICAgICAgICAgLy8gRkFMTFRIUlU6Ci0gICAgICAgICAgICAgICAgLy8gQ2FuJ3QgbG9hZCBqYXZhYygpIG1ldGhvZDsgdHJ5IHNoZWxsaW5nIG91dCB0byB0aGUgY29tbWFuZAotICAgICAgICAgICAgICAgIC8vIGxpbmUgYW5kIGludm9raW5nIGl0IHZpYSBleGVjKCkuIAotICAgICAgICAgICAgICAgIFN0cmluZyBqYXZhY19jb21tYW5kPQotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KCJvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuamF2YWMiLCJqYXZhYyIpOwotICAgICAgICAgICAgU3RyaW5nIGFyZ3NbXSA9IHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGphdmFjX2NvbW1hbmQsCi0gICAgICAgICAgICAgICAgICAgICAgICBjb2RlX29wdGlvbiwKLSAgICAgICAgICAgICAgICAgICAgICAgICItY2xhc3NwYXRoIiwgY2xhc3NQYXRoLAotICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWUKLSAgICAgICAgICAgICAgICAgICAgICAgIH07Ci0gICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgUHJvY2VzcyBwPWphdmEubGFuZy5SdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKGFyZ3MpOwotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvbXBpbGVPSz13YWl0SGFyZEZvcihwKTsgLy8gcGF1c2UgZm9yIGRlYnVnZ2luZy4uLgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBpbGVPSz09MDsgLy8wID09IG5vIGVycm9yIHJlcG9ydGVkCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoKElPRXhjZXB0aW9uIGUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJFUlJPUjogSU8gZXhjZXB0aW9uIGR1cmluZyBleGVjKGphdmFjKS4iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2goU2VjdXJpdHlFeGNlcHRpb24gZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVSUk9SOiBVbmFibGUgdG8gY3JlYXRlIHN1YnByb2Nlc3MgdG8gZXhlYyhqYXZhYykuIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIC8vIEZBTExUSFJVOiBBbGwgYXR0ZW1wdHMgZmFpbGVkLgotICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gIC8qKiBTdWJyb3V0aW5lOiBMaWtlIHAud2FpdEZvciwgYnV0IGRpc2NhcmRzIHRoZSBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgotICAgKiBhbmQgZ29lcyByaWdodCBiYWNrIGludG8gYSB3YWl0LiBJIGRvbid0IHdhbnQgdG8gcmVwb3J0IGNvbXBpbGVyCi0gICAqIHN1Y2Nlc3Mgb3IgZmFpbHVyZSB1bnRpbCBpdCByZWFsbHkgaGFzIHN1Y2NlZWRlZCBvciBmYWlsZWQuLi4gSSB0aGluay4KLSAgICogQHBhcmFtIFByb2Nlc3MgcCB0byBiZSB3YWl0ZWQgZm9yCi0gICAqIEByZXR1cm4gdGhlIGV4aXRWYWx1ZSgpIG9mIHRoZSBwcm9jZXNzLgotICAgKi8KLSAgc3RhdGljIGludCB3YWl0SGFyZEZvcihqYXZhLmxhbmcuUHJvY2VzcyBwKQotICB7Ci0gICAgYm9vbGVhbiBkb25lPWZhbHNlOwotICAgIHdoaWxlKCFkb25lKQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgICAgcC53YWl0Rm9yKCk7Ci0gICAgICAgICAgICBkb25lPXRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIoQ29tcGlsZXIgcHJvY2VzcyB3YWl0IGludGVycnVwdGVkIGFuZCByZXN1bWVkKSIpOwotICAgICAgICB9Ci0gICAgIGludCBldj1wLmV4aXRWYWx1ZSgpOyAgLy8gUGF1c2UgZm9yIGRlYnVnZ2luZy4uLgotICAgICByZXR1cm4gZXY7Ci0gIH0KLSAgICAgICAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL1N5bnRoZXNpc0V4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9TeW50aGVzaXNFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjM1NWNhMy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL1N5bnRoZXNpc0V4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIENsYXNzIFN5bnRoZXNpc0V4Y2VwdGlvbiA8bmVlZHMtY29tbWVudC8+Ci0gKi8KLXB1YmxpYyBjbGFzcyBTeW50aGVzaXNFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24KLXsKLQotICAvKiogRmllbGQgY29kZS4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgaW50IGNvZGU7Ci0KLSAgLy8gTWFuZWZlc3QgY29uc3RhbnRzCi0KLSAgLyoqIEZpZWxkIFNZTlRBWCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTWU5UQVggPSAwOwotCi0gIC8qKiBGaWVsZCBVTlNVUFBPUlRFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlNVUFBPUlRFRCA9IDE7Ci0KLSAgLyoqIEZpZWxkIFJFSUZJRUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVJRklFRCA9IDI7Ci0KLSAgLyoqIEZpZWxkIFVOUkVJRklFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlJFSUZJRUQgPSAzOwotCi0gIC8qKiBGaWVsZCBXUk9OR19PV05FUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXUk9OR19PV05FUiA9IDQ7Ci0KLSAgLyoqIEZpZWxkIGVyclRvU3RyaW5nICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nW10gZXJyVG9TdHJpbmcgPSB7Ci0gICAgIihTeW50YXggZXJyb3I7IHNwZWNpZmljIG1lc3NhZ2Ugc2hvdWxkIGJlIHBhc3NlZCBpbikiLAotICAgICJGZWF0dXJlIG5vdCB5ZXQgc3VwcG9ydGVkIiwKLSAgICAiQ2FuJ3QgY2hhbmdlIGZlYXR1cmVzIG9mICdyZWFsJyBjbGFzcyIsCi0gICAgIkNhbid0IHlldCBpbnN0YW50aWF0ZS9pbnZva2Ugd2l0aG91dCAncmVhbCcgY2xhc3MiLAotICAgICJDYW4ndCBhZGQgTWVtYmVyIHRvIGFuIG9iamVjdCBvdGhlciB0aGFuIGl0cyBkZWNsYXJlciIsIH07Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKgotICAgKgotICAgKiBAcGFyYW0gY29kZQotICAgKi8KLSAgcHVibGljIFN5bnRoZXNpc0V4Y2VwdGlvbihpbnQgY29kZSkKLSAgewotCi0gICAgc3VwZXIoZXJyVG9TdHJpbmdbY29kZV0pOwotCi0gICAgdGhpcy5jb2RlID0gY29kZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3RvciBTeW50aGVzaXNFeGNlcHRpb24KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGNvZGUKLSAgICogQHBhcmFtIG1zZwotICAgKi8KLSAgcHVibGljIFN5bnRoZXNpc0V4Y2VwdGlvbihpbnQgY29kZSwgU3RyaW5nIG1zZykKLSAgewotCi0gICAgc3VwZXIobXNnKTsKLQotICAgIHRoaXMuY29kZSA9IGNvZGU7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIGdldENvZGUgCi0gICAqCi0gICAqCi0gICAqLwotICBpbnQgZ2V0Q29kZSgpCi0gIHsKLSAgICByZXR1cm4gY29kZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9UZXN0RHJpdmVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL1Rlc3REcml2ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzNlNmQ1Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL1Rlc3REcml2ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotCi0vKioKLSAqIFRlc3QgZHJpdmVyIGZvciBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgYW5kIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5yZWZsZWN0aW9uLgotICogICA8cD4KLSAqICAgdG9Tb3VyY2Ugc2hvdWxkIHByb2JhYmx5IGJlIGZhY3RvcmVkIG91dCBpbnRvIGEgc2VwYXJhdGUKLSAqICAgamF2YSBnZW5lcmF0b3IgY2xhc3MsIHNvIHdlIGNvdWxkIGdlbmVyYXRlIG90aGVyIGxhbmd1YWdlcyBhcyB3ZWxsLgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYzsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMucmVmbGVjdGlvbi4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgVGVzdERyaXZlciA8bmVlZHMtY29tbWVudC8+Ci0gKi8KLXB1YmxpYyBjbGFzcyBUZXN0RHJpdmVyCi17Ci0KLSAgLyoqIEZpZWxkIHNhbXBsZUZpZWxkICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgaW50IHNhbXBsZUZpZWxkID0gMzI7Ci0KLSAgLyoqIEZpZWxkIGluVGVzdCAgICAgICAgICAqLwotICBwcml2YXRlIGJvb2xlYW4gaW5UZXN0ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCBtYWluIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXJncwotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykKLSAgewotCi0gICAgLy8gUHJveHkgYSBjbGFzcwotICAgIHRyeQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUHJveHlpbmcgamF2YS5hd3QuRnJhbWUuLi4iKTsKLQotICAgICAgQ2xhc3MgbXlDID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5hd3QuRnJhbWUiKTsKLQotICAgICAgbXlDLnRvU291cmNlKFN5c3RlbS5vdXQsIDApOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKAotICAgICAgICAiXG5Qcm94eWluZyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuVGVzdERyaXZlci4uLiIpOwotCi0gICAgICBteUMgPQotICAgICAgICBDbGFzcy5mb3JOYW1lKCJjb20uaWJtLm9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5UZXN0RHJpdmVyIik7Ci0KLSAgICAgIG15Qy50b1NvdXJjZShTeXN0ZW0ub3V0LCAwKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNvdWxkbid0IHByb3h5OiAiKTsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgfQotCi0gICAgLy8gU3RhcnQgZ2V0dGluZyBzZXJpb3VzCi0gICAgdHJ5Ci0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbkJ1aWxkIGEgbmV3IGJlYXN0Li4uIik7Ci0KLSAgICAgIENsYXNzIG15QyA9IENsYXNzLmRlY2xhcmVDbGFzcygKLSAgICAgICAgImNvbS5pYm0ub3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkJ1aWxkTWUiKTsKLSAgICAgIENsYXNzIGlubmVyID0gbXlDLmRlY2xhcmVJbm5lckNsYXNzKCJpc2xhbmQiKTsKLQotICAgICAgaW5uZXIuYWRkRXh0ZW5kcyhDbGFzcy5mb3JOYW1lKCJqYXZhLmxhbmcuU3RyaW5nIikpOwotCi0gICAgICBNZXRob2QgbSA9IGlubmVyLmRlY2xhcmVNZXRob2QoImdldFZhbHVlIik7Ci0KLSAgICAgIG0uc2V0UmV0dXJuVHlwZShDbGFzcy5mb3JOYW1lKCJqYXZhLmxhbmcuU3RyaW5nIikpOwotICAgICAgbS5nZXRCb2R5KCkuYXBwZW5kKCJyZXR1cm4gdG9TdHJpbmcoKTsiKTsKLSAgICAgIG15Qy50b1NvdXJjZShTeXN0ZW0ub3V0LCAwKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgIH0KLSAgICBjYXRjaCAoU3ludGhlc2lzRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVW53cml0dGVuIGZ1bmN0aW9uOiAiICsgZSk7Ci0gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgZHVtcENsYXNzIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gQwotICAgKi8KLSAgcHVibGljIHN0YXRpYyB2b2lkIGR1bXBDbGFzcyhDbGFzcyBDKQotICB7Ci0KLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRvU3RyaW5nKCk6ICIgKyBDKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0aXNQcmltaXRpdmUoKTogIiArIEMuaXNQcmltaXRpdmUoKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcdGlzSW50ZXJmYWNlKCk6ICIgKyBDLmlzSW50ZXJmYWNlKCkpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHRpc0luc3RhbmNlKFwiZm9vXCIpOiAiICsgQy5pc0luc3RhbmNlKCJmb28iKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCJcdGlzQXJyYXkoKTogIiArIEMuaXNBcnJheSgpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0Z2V0UmVhbENsYXNzKCk6ICIgKyBDLmdldFJlYWxDbGFzcygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgcXVpY2tjaGVjayAKLSAgICoKLSAgICovCi0gIHB1YmxpYyB2b2lkIHF1aWNrY2hlY2soKQotICB7Ci0KLSAgICBJbm5lciBhID0gbmV3IElubmVyKCk7Ci0KLSAgICBhLnNldFRlc3QoIWEuZ2V0VGVzdCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogQ2xhc3MgSW5uZXIgPG5lZWRzLWNvbW1lbnQvPgotICAgKi8KLSAgcHJpdmF0ZSBjbGFzcyBJbm5lcgotICB7Ci0KLSAgICAvKioKLSAgICAgKiBNZXRob2QgZ2V0VGVzdCAKLSAgICAgKgotICAgICAqCi0gICAgICogQHJldHVybgotICAgICAqLwotICAgIHB1YmxpYyBib29sZWFuIGdldFRlc3QoKQotICAgIHsKLSAgICAgIHJldHVybiBpblRlc3Q7Ci0gICAgfQotCi0gICAgLyoqCi0gICAgICogTWV0aG9kIHNldFRlc3QgCi0gICAgICoKLSAgICAgKgotICAgICAqIEBwYXJhbSB0ZXN0Ci0gICAgICovCi0gICAgcHVibGljIHZvaWQgc2V0VGVzdChib29sZWFuIHRlc3QpCi0gICAgewotICAgICAgaW5UZXN0ID0gdGVzdDsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9Db25zdHJ1Y3Rvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9yZWZsZWN0aW9uL0NvbnN0cnVjdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQzYzE1ODAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9yZWZsZWN0aW9uL0NvbnN0cnVjdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNDQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb247Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLlN5bnRoZXNpc0V4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIENvbnN0cnVjdG9yIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0LCBhbmQgYWNjZXNzIHRvLCBhCi0gKiBzaW5nbGUgY29uc3RydWN0b3IgZm9yIGEgY2xhc3MuCi0gKgotICogQ29uc3RydWN0b3IgcGVybWl0cyB3aWRlbmluZyBjb252ZXJzaW9ucyB0byBvY2N1ciB3aGVuCi0gKiBtYXRjaGluZyB0aGUgYWN0dWFsIHBhcmFtZXRlcnMgdG8gbmV3SW5zdGFuY2UoKSB3aXRoCi0gKiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvcidzIGZvcm1hbCBwYXJhbWV0ZXJzLCBidXQKLSAqIHRocm93cyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYSBuYXJyb3dpbmcKLSAqIGNvbnZlcnNpb24gd291bGQgb2NjdXIuCi0gKgotICovCi1wdWJsaWMgY2xhc3MgQ29uc3RydWN0b3IgZXh0ZW5kcyBFbnRyeVBvaW50IGltcGxlbWVudHMgTWVtYmVyCi17Ci0KLSAgLyoqCi0gICAqIEFjdHVhbCBKYXZhIGNsYXNzIG9iamVjdC4gV2hlbiBwcmVzZW50LCBhbGwgaW50ZXJhY3Rpb25zCi0gICAqIGFyZSByZWRpcmVjdGVkIHRvIGl0LiBBbGxvd3Mgb3VyIENsYXNzIHRvIGZ1bmN0aW9uIGFzIGEKLSAgICogd3JhcHBlciBmb3IgdGhlIEphdmEgdmVyc2lvbiAoaW4gbGlldSBvZiBzdWJjbGFzc2luZyBvcgotICAgKiBhIHNoYXJlZCBJbnRlcmZhY2UpLCBhbmQgYWxsb3dzICJpbi1wbGFjZSBjb21waWxhdGlvbiIKLSAgICogdG8gcmVwbGFjZSBhIGdlbmVyYXRlZCBkZXNjcmlwdGlvbiB3aXRoIGFuCi0gICAqIGRpcmVjdGx5IHJ1bm5hYmxlIGNsYXNzLgotICAgKi8KLSAgcHJpdmF0ZSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nY2xhc3MgPSBudWxsOwotCi0gIC8qKiBGaWVsZCByZWFsY29uc3RydWN0b3IgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvciByZWFsY29uc3RydWN0b3IgPSBudWxsOwotCi0gIC8qKiBGaWVsZCBwYXJhbWV0ZXJ0eXBlcyAgICAgICAgICAqLwotICBwcml2YXRlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzc1tdIHBhcmFtZXRlcnR5cGVzOwotCi0gIC8qKiBGaWVsZCBwYXJhbWV0ZXJuYW1lcyAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZ1tdIHBhcmFtZXRlcm5hbWVzOwotCi0gIC8qKiBGaWVsZCBleGNlcHRpb250eXBlcyAgICAgICAgICAqLwotICBwcml2YXRlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzc1tdIGV4Y2VwdGlvbnR5cGVzOwotCi0gIC8qKiBGaWVsZCBtb2RpZmllcnMgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbW9kaWZpZXJzOwotCi0gIC8qKgotICAgKiBJbnNlcnQgdGhlIG1ldGhvZCdzIGRlc2NyaXB0aW9uIGhlcmUuCi0gICAqIDxwPgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjctOTkgMjozMTozOSBQTSkKLSAgICogQHBhcmFtIHJlYWxDb25zdHJ1Y3RvciBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcgotICAgKgotICAgKiBAcGFyYW0gZGVjbGFyaW5nY2xhc3MKLSAgICovCi0gIHB1YmxpYyBDb25zdHJ1Y3RvcihvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nY2xhc3MpCi0gIHsKLSAgICBzdXBlcihkZWNsYXJpbmdjbGFzcyk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IHRoZSBtZXRob2QncyBkZXNjcmlwdGlvbiBoZXJlLgotICAgKiA8cD4KLSAgICogQ3JlYXRpb24gZGF0ZTogKDEyLTI3LTk5IDI6MzE6MzkgUE0pCi0gICAqIEBwYXJhbSByZWFsQ29uc3RydWN0b3IgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IKLSAgICoKLSAgICogQHBhcmFtIGN0b3IKLSAgICogQHBhcmFtIGRlY2xhcmluZ2NsYXNzCi0gICAqLwotICBwdWJsaWMgQ29uc3RydWN0b3IoamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IgY3RvciwKLSAgICAgICAgICAgICAgICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyBkZWNsYXJpbmdjbGFzcykKLSAgewotICAgIHN1cGVyKGN0b3IsIGRlY2xhcmluZ2NsYXNzKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgdGhlIG1ldGhvZCdzIGRlc2NyaXB0aW9uIGhlcmUuCi0gICAqIDxwPgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjctOTkgMjozMTozOSBQTSkKLSAgICogQHBhcmFtIHJlYWxDb25zdHJ1Y3RvciBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcgotICAgKgotICAgKiBAcGFyYW0gcmVhbGNvbnN0cnVjdG9yCi0gICAqLwotICBwdWJsaWMgQ29uc3RydWN0b3IoamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IgcmVhbGNvbnN0cnVjdG9yKQotICB7Ci0gICAgc3VwZXIocmVhbGNvbnN0cnVjdG9yKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgQ29uc3RydWN0b3IuIFRoZQotICAgKiBoYXNoY29kZSBpcyB0aGUgc2FtZSBhcyB0aGUgaGFzaGNvZGUgZm9yIHRoZQotICAgKiB1bmRlcmx5aW5nIGNvbnN0cnVjdG9yJ3MgZGVjbGFyaW5nIGNsYXNzIG5hbWUuCi0gICAqCi0gICAqICgkb2JqZWN0TmFtZSQpIEByZXR1cm4KLSAgICovCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKQotICB7Ci0gICAgcmV0dXJuIGdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpLmhhc2hDb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogVXNlcyB0aGUgY29uc3RydWN0b3IgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBDb25zdHJ1Y3RvciBvYmplY3QgdG8gY3JlYXRlIGFuZCBpbml0aWFsaXplIGEgbmV3Ci0gICAqIGluc3RhbmNlIG9mIHRoZSBjb25zdHJ1Y3RvcidzIGRlY2xhcmluZyBjbGFzcywgd2l0aAotICAgKiB0aGUgc3BlY2lmaWVkIGluaXRpYWxpemF0aW9uIHBhcmFtZXRlcnMuIEluZGl2aWR1YWwKLSAgICogcGFyYW1ldGVycyBhcmUgYXV0b21hdGljYWxseSB1bndyYXBwZWQgdG8gbWF0Y2gKLSAgICogcHJpbWl0aXZlIGZvcm1hbCBwYXJhbWV0ZXJzLCBhbmQgYm90aCBwcmltaXRpdmUKLSAgICogYW5kIHJlZmVyZW5jZSBwYXJhbWV0ZXJzIGFyZSBzdWJqZWN0IHRvIHdpZGVuaW5nCi0gICAqIGNvbnZlcnNpb25zIGFzIG5lY2Vzc2FyeS4gUmV0dXJucyB0aGUgbmV3bHkKLSAgICogY3JlYXRlZCBhbmQgaW5pdGlhbGl6ZWQgb2JqZWN0LgotICAgKiA8cD4KLSAgICogQ3JlYXRpb24gcHJvY2VlZHMgd2l0aCB0aGUgZm9sbG93aW5nIHN0ZXBzLCBpbgotICAgKiBvcmRlcjoKLSAgICogPHA+Ci0gICAqIElmIHRoZSBjbGFzcyB0aGF0IGRlY2xhcmVzIHRoZSB1bmRlcmx5aW5nIGNvbnN0cnVjdG9yCi0gICAqIHJlcHJlc2VudHMgYW4gYWJzdHJhY3QgY2xhc3MsIHRoZSBjcmVhdGlvbiB0aHJvd3MgYW4KLSAgICogSW5zdGFudGlhdGlvbkV4Y2VwdGlvbi4KLSAgICogPHA+Ci0gICAqIElmIHRoaXMgQ29uc3RydWN0b3Igb2JqZWN0IGVuZm9yY2VzIEphdmEgbGFuZ3VhZ2UKLSAgICogYWNjZXNzIGNvbnRyb2wgYW5kIHRoZSB1bmRlcmx5aW5nIGNvbnN0cnVjdG9yIGlzCi0gICAqIGluYWNjZXNzaWJsZSwgdGhlIGNyZWF0aW9uIHRocm93cyBhbgotICAgKiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLgotICAgKiA8cD4KLSAgICogSWYgdGhlIG51bWJlciBvZiBhY3R1YWwgcGFyYW1ldGVycyBzdXBwbGllZCB2aWEKLSAgICogaW5pdGFyZ3MgaXMgZGlmZmVyZW50IGZyb20gdGhlIG51bWJlciBvZiBmb3JtYWwKLSAgICogcGFyYW1ldGVycyByZXF1aXJlZCBieSB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciwKLSAgICogdGhlIGNyZWF0aW9uIHRocm93cyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uCi0gICAqIDxwPgotICAgKiBBIG5ldyBpbnN0YW5jZSBvZiB0aGUgY29uc3RydWN0b3IncyBkZWNsYXJpbmcgY2xhc3MKLSAgICogaXMgY3JlYXRlZCwgYW5kIGl0cyBmaWVsZHMgYXJlIGluaXRpYWxpemVkIHRvIHRoZWlyCi0gICAqIGRlZmF1bHQgaW5pdGlhbCB2YWx1ZXMuCi0gICAqIDxwPgotICAgKiBGb3IgZWFjaCBhY3R1YWwgcGFyYW1ldGVyIGluIHRoZSBzdXBwbGllZCBpbml0YXJncwotICAgKiBhcnJheToKLSAgICogPHA+Ci0gICAqIElmIHRoZSBjb3JyZXNwb25kaW5nIGZvcm1hbCBwYXJhbWV0ZXIgaGFzIGEKLSAgICogcHJpbWl0aXZlIHR5cGUsIGFuIHVud3JhcHBpbmcgY29udmVyc2lvbiBpcwotICAgKiBhdHRlbXB0ZWQgdG8gY29udmVydCB0aGUgb2JqZWN0IHZhbHVlIHRvIGEgdmFsdWUgb2YKLSAgICogdGhlIHByaW1pdGl2ZSB0eXBlLiBJZiB0aGlzIGF0dGVtcHQgZmFpbHMsIHRoZQotICAgKiBjcmVhdGlvbiB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLgotICAgKiA8cD4KLSAgICoKLSAgICogSWYsIGFmdGVyIHBvc3NpYmxlIHVud3JhcHBpbmcsIHRoZSBwYXJhbWV0ZXIgdmFsdWUKLSAgICogY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUgY29ycmVzcG9uZGluZyBmb3JtYWwKLSAgICogcGFyYW1ldGVyIHR5cGUgYnkgYW4gaWRlbnRpdHkgb3Igd2lkZW5pbmcKLSAgICogY29udmVyc2lvbiwgdGhlIGNyZWF0aW9uIHRocm93cyBhbgotICAgKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uCi0gICAqIDxwPgotICAgKiBDb250cm9sIHRyYW5zZmVycyB0byB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciB0bwotICAgKiBpbml0aWFsaXplIHRoZSBuZXcgaW5zdGFuY2UuIElmIHRoZSBjb25zdHJ1Y3RvcgotICAgKiBjb21wbGV0ZXMgYWJydXB0bHkgYnkgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLCB0aGUKLSAgICogZXhjZXB0aW9uIGlzIHBsYWNlZCBpbiBhbgotICAgKiBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGFuZCB0aHJvd24gaW4gdHVybiB0bwotICAgKiB0aGUgY2FsbGVyIG9mIG5ld0luc3RhbmNlLgotICAgKiA8cD4KLSAgICogSWYgdGhlIGNvbnN0cnVjdG9yIGNvbXBsZXRlcyBub3JtYWxseSwgcmV0dXJucyB0aGUKLSAgICogbmV3bHkgY3JlYXRlZCBhbmQgaW5pdGlhbGl6ZWQgaW5zdGFuY2UuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpbml0YXJncyBpbml0aWFsaXphdGlvbiBhcmd1bWVudHMuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ldyBpbnN0YW5jZS4KLSAgICogQHRocm93cyAgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgbnVtYmVyIG9mIGFjdHVhbCBhbmQgZm9ybWFsCi0gICAqIHBhcmFtZXRlcnMgZGlmZmVyLCBvciBpZiBhbiB1bndyYXBwaW5nCi0gICAqIGNvbnZlcnNpb24gZmFpbHMuCi0gICAqIEB0aHJvd3MgIEluc3RhbnRpYXRpb25FeGNlcHRpb24KLSAgICogaWYgdGhlIGNsYXNzIHRoYXQgZGVjbGFyZXMgdGhlIHVuZGVybHlpbmcKLSAgICogY29uc3RydWN0b3IgcmVwcmVzZW50cyBhbiBhYnN0cmFjdCBjbGFzcy4KLSAgICogQHRocm93cyAgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciB0aHJvd3MgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKiBAdGhyb3dzIGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgbmV3SW5zdGFuY2UoT2JqZWN0IGluaXRhcmdzW10pCi0gICAgICAgICAgdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCi0gICAgICAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwKLSAgICAgICAgICAgICAgICAgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGVwICE9IG51bGwpCi0gICAgICByZXR1cm4gKChqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcikgcmVhbGVwKS5uZXdJbnN0YW5jZShpbml0YXJncyk7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IEluc3RhbnRpYXRpb25FeGNlcHRpb24oCi0gICAgICAgICJVbi1yZWlmaWVkIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyBkb2Vzbid0IHlldCBzdXBwb3J0IGludm9jYXRpb24iKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9yZWZsZWN0aW9uL0VudHJ5UG9pbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9FbnRyeVBvaW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhMTA5MmQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9yZWZsZWN0aW9uL0VudHJ5UG9pbnQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY1MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMucmVmbGVjdGlvbjsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuU3ludGhlc2lzRXhjZXB0aW9uOwotCi0vKgotICogT1BFTiBJU1NVRVM6Ci0gKiAgIFJlZmxlY3Rpb24gZG9lc24ndCB0ZWxsIHVzIGFib3V0IGRlcHJlY2F0aW9uOyBpZiB3ZSB3YW50Ci0gKiAgIHRoYXQgaW5mbywgTUZDIGFkdmlzZXMgbW91c2luZyBvdXIgd2F5IGludG8gdGhlIGNsYXNzICh1Z2gpLgotICogICBTaG91bGQgd2UgYXQgbGVhc3QgbW9kZWwgdGhhdCBmb3Igc3ludGhldGljcz8KLSAqLwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQVBJL2JlaGF2aW9ycyBzaGFyZWQgYmV0d2VlbiBDb25zdHJ1Y3RvcnMgYW5kIE1ldGhvZHMuCi0gKiBUaGV5J3JlIG1vc3RseSBzaW1pbGFyLCBleGNlcHQgZm9yIHdoYXQgdGhleSBwcm94eSBhbmQKLSAqIGEgZmV3IHNwZWNpZmljIGNhbGxzIChuYW1lLCBpbnZva2UvZ2V0SW5zdGFuY2UpLgotICovCi1hYnN0cmFjdCBwdWJsaWMgY2xhc3MgRW50cnlQb2ludCBpbXBsZW1lbnRzIE1lbWJlcgotewotCi0gIC8qKiBGaWVsZCByZWFsZXAgICAgICAgICAgKi8KLSAgcHJvdGVjdGVkIE9iamVjdCByZWFsZXA7Ci0KLSAgLyoqIEZpZWxkIGRlY2xhcmluZ2NsYXNzICAgICAgICAgICovCi0gIHByaXZhdGUgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGRlY2xhcmluZ2NsYXNzID0gbnVsbDsKLQotICAvKiogRmllbGQgcmV0dXJudHlwZSAgICAgICAgICAqLwotICBwcm90ZWN0ZWQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIHJldHVybnR5cGUgPSBudWxsOwotCi0gIC8qKiBGaWVsZCBwYXJhbWV0ZXJuYW1lcyAgICAgICAgICAqLwotICBwcml2YXRlIFN0cmluZ1tdIHBhcmFtZXRlcm5hbWVzID0gbmV3IFN0cmluZ1swXTsKLQotICAvKiogRmllbGQgcGFyYW1ldGVydHlwZXMgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbXSBwYXJhbWV0ZXJ0eXBlcyA9Ci0gICAgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzc1swXTsKLQotICAvKiogRmllbGQgZXhjZXB0aW9udHlwZXMgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbXSBleGNlcHRpb250eXBlcyA9Ci0gICAgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzc1swXTsKLSAgOwotCi0gIC8qKiBGaWVsZCBtb2RpZmllcnMgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbW9kaWZpZXJzOwotCi0gIC8qKiBGaWVsZCBuYW1lICAgICAgICAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbmFtZSA9IG51bGw7ICAvLyBmb3IgTWV0aG9kcwotCi0gIC8vIEZvciBzeW50aGVzaXM6Ci0KLSAgLyoqIEZpZWxkIGJvZHkgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgYm9keSA9IG51bGw7Ci0KLSAgLyoqIEZpZWxkIGxhbmd1YWdlICAgICAgICAgICovCi0gIHByaXZhdGUgU3RyaW5nIGxhbmd1YWdlID0gbnVsbDsKLQotICAvLyBGb3IgcmVpZnlpbmc6Ci0KLSAgLyoqIEZpZWxkIHJlYWxFLCByZWFsUCAgICAgICAgICAqLwotICBDbGFzc1tdIHJlYWxFLCByZWFsUDsKLQotICAvKioKLSAgICogSW5zZXJ0IHRoZSBtZXRob2QncyBkZXNjcmlwdGlvbiBoZXJlLgotICAgKiA8cD4KLSAgICogQ3JlYXRpb24gZGF0ZTogKDEyLTI3LTk5IDI6MzE6MzkgUE0pCi0gICAqIEBwYXJhbSByZWFsQ29uc3RydWN0b3IgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IKLSAgICoKLSAgICogQHBhcmFtIGRlY2xhcmluZ2NsYXNzCi0gICAqLwotICBwdWJsaWMgRW50cnlQb2ludChvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nY2xhc3MpCi0gIHsKLSAgICB0aGlzLmRlY2xhcmluZ2NsYXNzID0gZGVjbGFyaW5nY2xhc3M7Ci0gIH0KLQotICAvKioKLSAgICogTm9ucHVibGljIGNvbnN0cnVjdG9yLiBXcmFwIHRoaXMgdG8gYXBwcm9wcmlhdGUgInJlYWwiIHR5cGUgCi0gICAqCi0gICAqIEBwYXJhbSBlcAotICAgKiBAcGFyYW0gZGVjbGFyaW5nY2xhc3MKLSAgICoKLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBFbnRyeVBvaW50KAotICAgICAgICAgIE9iamVjdCBlcCwgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGRlY2xhcmluZ2NsYXNzKQotICAgICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0KLSAgICByZWFsZXAgPSBlcDsKLSAgICB0aGlzLmRlY2xhcmluZ2NsYXNzID0gZGVjbGFyaW5nY2xhc3M7Ci0KLSAgICBpZiAoZXAgaW5zdGFuY2VvZiBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QpCi0gICAgewotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG0gPSAoamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kKSBlcDsKLQotICAgICAgaWYgKGRlY2xhcmluZ2NsYXNzID09IG51bGwpCi0gICAgICB7Ci0gICAgICAgIGRlY2xhcmluZ2NsYXNzID0gb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzLmZvckNsYXNzKAotICAgICAgICAgIG0uZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7Ci0gICAgICB9Ci0KLSAgICAgIG5hbWUgPSBtLmdldE5hbWUoKTsKLSAgICAgIG1vZGlmaWVycyA9IG0uZ2V0TW9kaWZpZXJzKCk7Ci0gICAgICByZXR1cm50eXBlID0KLSAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzLmZvckNsYXNzKG0uZ2V0UmV0dXJuVHlwZSgpKTsKLSAgICAgIHJlYWxQID0gbS5nZXRQYXJhbWV0ZXJUeXBlcygpOwotICAgICAgcmVhbEUgPSBtLmdldEV4Y2VwdGlvblR5cGVzKCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKGVwIGluc3RhbmNlb2YgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IpCi0gICAgewotICAgICAgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IgYyA9IChqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcikgZXA7Ci0KLSAgICAgIGlmIChkZWNsYXJpbmdjbGFzcyA9PSBudWxsKQotICAgICAgewotICAgICAgICBkZWNsYXJpbmdjbGFzcyA9IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcy5mb3JDbGFzcygKLSAgICAgICAgICBjLmdldERlY2xhcmluZ0NsYXNzKCkpOwotICAgICAgfQotCi0gICAgICBuYW1lID0gZGVjbGFyaW5nY2xhc3MuZ2V0U2hvcnROYW1lKCk7Ci0gICAgICBtb2RpZmllcnMgPSBjLmdldE1vZGlmaWVycygpOwotICAgICAgcmV0dXJudHlwZSA9IGRlY2xhcmluZ2NsYXNzOwotICAgICAgcmVhbFAgPSBjLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0gICAgICByZWFsRSA9IGMuZ2V0RXhjZXB0aW9uVHlwZXMoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIE5vbnB1YmxpYyBjb25zdHJ1Y3Rvci4gV3JhcCB0aGlzIHRvIGFwcHJvcHJpYXRlICJyZWFsIiB0eXBlIAotICAgKgotICAgKiBAcGFyYW0gZXAKLSAgICoKLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBFbnRyeVBvaW50KE9iamVjdCBlcCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0gICAgdGhpcyhlcCwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBhZ2FpbnN0IHRoZSBzcGVjaWZpZWQKLSAgICogb2JqZWN0LiBSZXR1cm5zIHRydWUgaWYgdGhlIG9iamVjdHMgYXJlIHRoZSBzYW1lLgotICAgKiBUd28gRW50cnlQb2ludHMgYXJlIHRoZSBzYW1lIGlmIHRoZXkgd2VyZQotICAgKiBkZWNsYXJlZCBieSB0aGUgc2FtZSBjbGFzcywgaGF2ZSB0aGUgc2FtZSBuYW1lCi0gICAqIChvciBhcmUgYm90aCBjdG9ycykgYW5kIGhhdmUgdGhlIHNhbWUKLSAgICogZm9ybWFsIHBhcmFtZXRlciB0eXBlcy4KLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopCi0gIHsKLQotICAgIEVudHJ5UG9pbnQgb3RoZXJlcCA9IG51bGw7Ci0KLSAgICBpZiAob2JqIGluc3RhbmNlb2YgRW50cnlQb2ludCkKLSAgICAgIG90aGVyZXAgPSAoRW50cnlQb2ludCkgb2JqOwotICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yCi0gICAgICAgICAgICAgfHwgb2JqIGluc3RhbmNlb2YgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kKQotICAgICAgb3RoZXJlcCA9IChFbnRyeVBvaW50KSBvYmo7Ci0KLSAgICByZXR1cm4gKG90aGVyZXAgIT0gbnVsbCAmJiAoKHRoaXMgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvciAmJiBvdGhlcmVwIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpIHx8ICh0aGlzIGluc3RhbmNlb2YgTWV0aG9kICYmIG90aGVyZXAgaW5zdGFuY2VvZiBNZXRob2QgJiYgdGhpcy5nZXROYW1lKCkuZXF1YWxzKAotICAgICAgb3RoZXJlcC5nZXROYW1lKCkpKSkgJiYgb3RoZXJlcC5nZXREZWNsYXJpbmdDbGFzcygpLmVxdWFscygKLSAgICAgICAgZGVjbGFyaW5nY2xhc3MpICYmIG90aGVyZXAuZ2V0UGFyYW1ldGVyVHlwZXMoKS5lcXVhbHMoCi0gICAgICAgIHBhcmFtZXRlcnR5cGVzKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY2xhc3MgdGhhdAotICAgKiBkZWNsYXJlcyB0aGUgY29uc3RydWN0b3IgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBDb25zdHJ1Y3RvciBvYmplY3QuCi0gICAqCi0gICAqLwotICBwdWJsaWMgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGdldERlY2xhcmluZ0NsYXNzKCkKLSAgewotICAgIHJldHVybiBkZWNsYXJpbmdjbGFzczsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBDbGFzcyBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjbGFzcyB0aGF0Ci0gICAqIHdpbGwgYmUgcmV0dXJuZWQgYnkgdGhpcyBFbnRyeVBvaW50LiBOZWVkZWQgYnkgdGhlIE1ldGhvZAotICAgKiBBUEksIGJ1dCBtYWRlIG1lYW5pbmdmdWwgZm9yIENvbnN0cnVjdG9ycyBhcyB3ZWxsLgotICAgKgotICAgKi8KLSAgcHVibGljIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyBnZXRSZXR1cm5UeXBlKCkKLSAgewotICAgIHJldHVybiByZXR1cm50eXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgQ2xhc3Mgb2JqZWN0cyB0aGF0IHJlcHJlc2VudCB0aGUKLSAgICogdHlwZXMgb2YgdGhlIGNoZWNrZWQgZXhjZXB0aW9ucyB0aHJvd24gYnkgdGhlCi0gICAqIHVuZGVybHlpbmcgY29uc3RydWN0b3IgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBDb25zdHJ1Y3RvciBvYmplY3QuIFJldHVybnMgYW4gYXJyYXkgb2YgbGVuZ3RoIDAgaWYKLSAgICogdGhlIGNvbnN0cnVjdG9yIHRocm93cyBubyBjaGVja2VkIGV4Y2VwdGlvbnMuCi0gICAqCi0gICAqLwotICBwdWJsaWMgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzW10gZ2V0RXhjZXB0aW9uVHlwZXMoKQotICB7Ci0KLSAgICBpZiAocmVhbGVwICE9IG51bGwgJiYgZXhjZXB0aW9udHlwZXMgPT0gbnVsbCkKLSAgICB7Ci0gICAgICBleGNlcHRpb250eXBlcyA9Ci0gICAgICAgIG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbcmVhbEUubGVuZ3RoXTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWFsRS5sZW5ndGg7ICsraSkKLSAgICAgIHsKLSAgICAgICAgZXhjZXB0aW9udHlwZXNbaV0gPQotICAgICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcy5mb3JDbGFzcyhyZWFsRVtpXSk7Ci0gICAgICB9Ci0KLSAgICAgIHJlYWxFID0gbnVsbDsKLSAgICB9Ci0KLSAgICByZXR1cm4gZXhjZXB0aW9udHlwZXM7Ci0gIH0KLQotICAvKioKLSAgICogTWV0aG9kIGFkZEV4Y2VwdGlvblR5cGUgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBleGNlcHRpb24KLSAgICoKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEV4Y2VwdGlvblR5cGUoCi0gICAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGV4Y2VwdGlvbikKLSAgICAgICAgICAgIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxlcCAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uUkVJRklFRCk7Ci0KLSAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbXSBlID0KLSAgICAgIG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbZXhjZXB0aW9udHlwZXMubGVuZ3RoICsgMV07Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KGV4Y2VwdGlvbnR5cGVzLCAwLCBlLCAwLCBleGNlcHRpb250eXBlcy5sZW5ndGgpOwotCi0gICAgZVtleGNlcHRpb250eXBlcy5sZW5ndGhdID0gZXhjZXB0aW9uOwotICAgIGV4Y2VwdGlvbnR5cGVzID0gZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBKYXZhIGxhbmd1YWdlIG1vZGlmaWVycyBmb3IgdGhlCi0gICAqIGNvbnN0cnVjdG9yIHJlcHJlc2VudGVkIGJ5IHRoaXMgQ29uc3RydWN0b3Igb2JqZWN0LAotICAgKiBhcyBhbiBpbnRlZ2VyLiBUaGUgTW9kaWZpZXIgY2xhc3Mgc2hvdWxkIGJlIHVzZWQgdG8KLSAgICogZGVjb2RlIHRoZSBtb2RpZmllcnMuCi0gICAqCi0gICAqLwotICBwdWJsaWMgaW50IGdldE1vZGlmaWVycygpCi0gIHsKLSAgICByZXR1cm4gbW9kaWZpZXJzOwotICB9Ci0KLSAgLyoqCi0gICAqIE1lbWJlciBtZXRob2QuIEMndG9yJ3MgbmFtZSBpcyBhbHdheXMgdGhhdCBvZiB0aGUgZGVmaW5pbmcgY2xhc3MuCi0gICAqIE1ldGhvZHMgaGF2ZSBhICJyZWFsIiBuYW1lLgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjUtOTkgMTozMjowNiBQTSkKLSAgICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCi0gICAqLwotICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkKLSAgewotCi0gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikKLSAgICAgIHJldHVybiBkZWNsYXJpbmdjbGFzcy5nZXRTaG9ydE5hbWUoKTsKLQotICAgIHJldHVybiBuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIE1lbWJlciBtZXRob2QuIEMndG9yJ3MgbmFtZSBpcyBhbHdheXMgdGhhdCBvZiB0aGUgZGVmaW5pbmcgY2xhc3MuCi0gICAqIE1ldGhvZHMgaGF2ZSBhICJyZWFsIiBuYW1lLgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjUtOTkgMTozMjowNiBQTSkKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCi0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKSB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZXAgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgdGhpcy5uYW1lID0gbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIENsYXNzIG9iamVjdHMgdGhhdCByZXByZXNlbnQgdGhlCi0gICAqIGZvcm1hbCBwYXJhbWV0ZXIgdHlwZXMsIGluIGRlY2xhcmF0aW9uIG9yZGVyLCBvZiB0aGUKLSAgICogY29uc3RydWN0b3IgcmVwcmVzZW50ZWQgYnkgdGhpcyBDb25zdHJ1Y3RvciBvYmplY3QuCi0gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbGVuZ3RoIDAgaWYgdGhlIHVuZGVybHlpbmcKLSAgICogY29uc3RydWN0b3IgdGFrZXMgbm8gcGFyYW1ldGVycy4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbXSBnZXRQYXJhbWV0ZXJUeXBlcygpCi0gIHsKLQotICAgIGlmIChyZWFsZXAgIT0gbnVsbCAmJiBwYXJhbWV0ZXJ0eXBlcyA9PSBudWxsKQotICAgIHsKLSAgICAgIHBhcmFtZXRlcnR5cGVzID0KLSAgICAgICAgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzc1tyZWFsUC5sZW5ndGhdOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlYWxQLmxlbmd0aDsgKytpKQotICAgICAgewotICAgICAgICBwYXJhbWV0ZXJ0eXBlc1tpXSA9Ci0gICAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzLmZvckNsYXNzKHJlYWxQW2ldKTsKLSAgICAgIH0KLQotICAgICAgcmVhbFAgPSBudWxsOwotICAgIH0KLQotICAgIHJldHVybiBwYXJhbWV0ZXJ0eXBlczsKLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgZ2V0UGFyYW1ldGVyTmFtZXMgCi0gICAqCi0gICAqCi0gICAqIChnZXRQYXJhbWV0ZXJOYW1lcykgQHJldHVybgotICAgKi8KLSAgcHVibGljIFN0cmluZ1tdIGdldFBhcmFtZXRlck5hbWVzKCkKLSAgewotICAgIHJldHVybiBwYXJhbWV0ZXJuYW1lczsKLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2QgYWRkUGFyYW1ldGVyIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gdHlwZQotICAgKiBAcGFyYW0gbmFtZQotICAgKgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkUGFyYW1ldGVyKAotICAgICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyB0eXBlLCBTdHJpbmcgbmFtZSkKLSAgICAgICAgICAgIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxlcCAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uUkVJRklFRCk7Ci0KLSAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3NbXSB0eXBlcyA9Ci0gICAgICBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzW3BhcmFtZXRlcnR5cGVzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShwYXJhbWV0ZXJ0eXBlcywgMCwgdHlwZXMsIDAsIHBhcmFtZXRlcnR5cGVzLmxlbmd0aCk7Ci0KLSAgICB0eXBlc1twYXJhbWV0ZXJ0eXBlcy5sZW5ndGhdID0gdHlwZTsKLSAgICBwYXJhbWV0ZXJ0eXBlcyA9IHR5cGVzOwotCi0gICAgU3RyaW5nW10gbmFtZXMgPSBuZXcgU3RyaW5nW3BhcmFtZXRlcm5hbWVzLmxlbmd0aCArIDFdOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShwYXJhbWV0ZXJuYW1lcywgMCwgbmFtZXMsIDAsIHBhcmFtZXRlcm5hbWVzLmxlbmd0aCk7Ci0KLSAgICBuYW1lc1twYXJhbWV0ZXJuYW1lcy5sZW5ndGhdID0gbmFtZTsKLSAgICBwYXJhbWV0ZXJuYW1lcyA9IG5hbWVzOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBoYXNoY29kZSBmb3IgdGhpcyBDb25zdHJ1Y3Rvci4gVGhlCi0gICAqIGhhc2hjb2RlIGlzIHRoZSBzYW1lIGFzIHRoZSBoYXNoY29kZSBmb3IgdGhlCi0gICAqIHVuZGVybHlpbmcgY29uc3RydWN0b3IncyBkZWNsYXJpbmcgY2xhc3MgbmFtZSwKLSAgICogeG9yJ2VkIChmb3IgTWV0aG9kcykgd2l0aCB0aGUgbWV0aG9kIG5hbWUuCi0gICAqIChJbXBsZW1lbnRlZCBpbiB0aGUgc3ViY2xhc3NlcyByYXRoZXIgdGhhbiBoZXJlLikKLSAgICoKLSAgICovCi0gIGFic3RyYWN0IHB1YmxpYyBpbnQgaGFzaENvZGUoKTsKLQotICAvKioKLSAgICogQXNzZXJ0IHRoZSBDbGFzcyBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjbGFzcyB0aGF0Ci0gICAqIGRlY2xhcmVzIHRoZSBjb25zdHJ1Y3RvciByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqIENvbnN0cnVjdG9yIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGRlY2xhcmluZ0NsYXNzCi0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXREZWNsYXJpbmdDbGFzcygKLSAgICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nQ2xhc3MpCi0gICAgICAgICAgICB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZXAgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgdGhpcy5kZWNsYXJpbmdjbGFzcyA9IGRlY2xhcmluZ0NsYXNzOwotICB9Ci0KLSAgLyoqCi0gICAqIFNob3VsZCBvbmx5IGJlIGFjY2VwdGVkIGJlZm9yZSBhICJyZWFsIiBlbnRyeXBvaW50IGlzIGJvdW5kLgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjUtOTkgMToyODoyOCBQTSkKLSAgICogQHJldHVybiBpbnQKLSAgICogQHBhcmFtIG1vZGlmaWVycyBpbnQKLSAgICoKLSAgICogQHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldE1vZGlmaWVycyhpbnQgbW9kaWZpZXJzKSB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZXAgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgdGhpcy5tb2RpZmllcnMgPSBtb2RpZmllcnM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGEgc3RyaW5nIGRlc2NyaWJpbmcgdGhpcyBDb25zdHJ1Y3Rvci4gVGhlCi0gICAqIHN0cmluZyBpcyBmb3JtYXR0ZWQgYXMgdGhlIGNvbnN0cnVjdG9yIGFjY2VzcwotICAgKiBtb2RpZmllcnMsIGlmIGFueSwgZm9sbG93ZWQgYnkgdGhlIGZ1bGx5LXF1YWxpZmllZAotICAgKiBuYW1lIG9mIHRoZSBkZWNsYXJpbmcgY2xhc3MsIGZvbGxvd2VkIGJ5IGEKLSAgICogcGFyZW50aGVzaXplZCwgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgdGhlCi0gICAqIGNvbnN0cnVjdG9yJ3MgZm9ybWFsIHBhcmFtZXRlciB0eXBlcy4gRm9yIGV4YW1wbGU6Ci0gICAqIDxjb2RlPgotICAgKiBwdWJsaWMgamF2YS51dGlsLkhhc2h0YWJsZShpbnQsZmxvYXQpCi0gICAqIDwvY29kZT4KLSAgICogPHA+Ci0gICAqIFRoZSBvbmx5IHBvc3NpYmxlIG1vZGlmaWVycyBmb3IgY29uc3RydWN0b3JzIGFyZQotICAgKiB0aGUgYWNjZXNzIG1vZGlmaWVycyBwdWJsaWMsIHByb3RlY3RlZCBvcgotICAgKiBwcml2YXRlLiBPbmx5IG9uZSBvZiB0aGVzZSBtYXkgYXBwZWFyLCBvciBub25lCi0gICAqIGlmIHRoZSBjb25zdHJ1Y3RvciBoYXMgZGVmYXVsdCAocGFja2FnZSkgYWNjZXNzLgotICAgKiA8cD4KLSAgICogTWV0aG9kcyB3aWxsIGFsc28gZGlzcGxheSB0aGVpciBjaGVja2VkIGV4Y2VwdGlvbnMuCi0gICAqCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotCi0gICAgU3RyaW5nQnVmZmVyIHNiID0KLSAgICAgIG5ldyBTdHJpbmdCdWZmZXIoamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXIudG9TdHJpbmcoZ2V0TW9kaWZpZXJzKCkpKTsKLQotICAgIGlmICh0aGlzIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb24uTWV0aG9kKQotICAgICAgc2IuYXBwZW5kKCcgJykuYXBwZW5kKGdldFJldHVyblR5cGUoKSkuYXBwZW5kKAotICAgICAgICBnZXREZWNsYXJpbmdDbGFzcygpLmdldE5hbWUoKSkuYXBwZW5kKCcuJykuYXBwZW5kKGdldE5hbWUoKSk7Ci0gICAgZWxzZQotICAgICAgc2IuYXBwZW5kKGdldERlY2xhcmluZ0NsYXNzKCkuZ2V0TmFtZSgpKTsKLQotICAgIHNiLmFwcGVuZCgnKCcpOwotCi0gICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzW10gcCA9IGdldFBhcmFtZXRlclR5cGVzKCk7Ci0KLSAgICBpZiAocCAhPSBudWxsICYmIHAubGVuZ3RoID4gMCkKLSAgICB7Ci0gICAgICBzYi5hcHBlbmQocFswXS5nZXROYW1lKCkpOwotCi0gICAgICBmb3IgKGludCBpID0gMTsgaSA8IHAubGVuZ3RoOyArK2kpCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZCgnLCcpLmFwcGVuZChwW2ldLmdldE5hbWUoKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgc2IuYXBwZW5kKCcpJyk7Ci0KLSAgICBpZiAodGhpcyBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5yZWZsZWN0aW9uLk1ldGhvZCkKLSAgICB7Ci0gICAgICBwID0gZ2V0RXhjZXB0aW9uVHlwZXMoKTsKLQotICAgICAgaWYgKHAgIT0gbnVsbCAmJiBwLmxlbmd0aCA+IDApCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZCgiIHRocm93cyAiKS5hcHBlbmQocFswXS5nZXROYW1lKCkpOwotCi0gICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgcC5sZW5ndGg7ICsraSkKLSAgICAgICAgewotICAgICAgICAgIHNiLmFwcGVuZCgnLCcpLmFwcGVuZChwW2ldLmdldE5hbWUoKSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKgotICAgKiBFeHRlbnNpb246IEZvciBzeW50aGVzaXMsIHdlIG5lZWQgYSBwbGFjZSB0byBoYW5nIGEKLSAgICogbWV0aG9kIGJvZHkuCi0gICAqCi0gICAqIEBwYXJhbSBsYW5ndWFnZQotICAgKiBAcGFyYW0gYm9keQotICAgKgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Qm9keShTdHJpbmcgbGFuZ3VhZ2UsIFN0cmluZ0J1ZmZlciBib2R5KQotICAgICAgICAgIHRocm93cyBTeW50aGVzaXNFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxlcCAhPSBudWxsKQotICAgICAgdGhyb3cgbmV3IFN5bnRoZXNpc0V4Y2VwdGlvbihTeW50aGVzaXNFeGNlcHRpb24uUkVJRklFRCk7Ci0KLSAgICB0aGlzLmxhbmd1YWdlID0gbGFuZ3VhZ2U7Ci0gICAgdGhpcy5ib2R5ID0gYm9keTsKLSAgfQotCi0gIC8qKgotICAgKiBFeHRlbnNpb246IEZvciBzeW50aGVzaXMsIHdlIG5lZWQgYSBwbGFjZSB0byBoYW5nIGEKLSAgICogbWV0aG9kIGJvZHkuIE5vdGUgdGhhdCB0aGlzIHJldHVybnMgYSBtdXRhYmxlIG9iamVjdCwKLSAgICogZm9yIGVkaXRpbmcgZXRjLiBTbGlnaHRseSBzbG9wcHkgZmlyc3QgY3V0LgotICAgKgotICAgKi8KLSAgcHVibGljIFN0cmluZ0J1ZmZlciBnZXRCb2R5KCkKLSAgewotCi0gICAgaWYgKGJvZHkgPT0gbnVsbCkKLSAgICAgIGJvZHkgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICByZXR1cm4gYm9keTsKLSAgfQotCi0gIC8qKgotICAgKiBFeHRlbnNpb246IEZvciBzeW50aGVzaXMsIHdlIG5lZWQgYSBwbGFjZSB0byBoYW5nIGEKLSAgICogbWV0aG9kIGJvZHkuCi0gICAqCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldExhbmd1YWdlKCkKLSAgewotICAgIHJldHVybiBsYW5ndWFnZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZW5lcmF0ZSBKYXZhIGNvZGUKLSAgICoKLSAgICogQHBhcmFtIGJhc2V0YWIKLSAgICoKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgdG9Tb3VyY2UoU3RyaW5nIGJhc2V0YWIpCi0gIHsKLQotICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIHNiLmFwcGVuZChiYXNldGFiKS5hcHBlbmQoCi0gICAgICBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllci50b1N0cmluZyhnZXRNb2RpZmllcnMoKSkpOwotCi0gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMucmVmbGVjdGlvbi5NZXRob2QpCi0gICAgewotICAgICAgaWYgKHJldHVybnR5cGUgIT0gbnVsbCkKLSAgICAgICAgc2IuYXBwZW5kKCIgIikuYXBwZW5kKGdldFJldHVyblR5cGUoKS5nZXRKYXZhTmFtZSgpKTsKLSAgICAgIGVsc2UKLSAgICAgICAgc2IuYXBwZW5kKCIgdm9pZCIpOwotICAgIH0KLQotICAgIHNiLmFwcGVuZCgiICIpLmFwcGVuZChnZXROYW1lKCkpLmFwcGVuZCgiKCIpOwotCi0gICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzW10gdHlwZXMgPSBnZXRQYXJhbWV0ZXJUeXBlcygpOwotCi0gICAgaWYgKHR5cGVzICE9IG51bGwgJiB0eXBlcy5sZW5ndGggPiAwKQotICAgIHsKLSAgICAgIHNiLmFwcGVuZCh0eXBlc1swXS5nZXRKYXZhTmFtZSgpKTsKLQotICAgICAgaWYgKHBhcmFtZXRlcm5hbWVzICE9IG51bGwpCi0gICAgICAgIHNiLmFwcGVuZCgnICcpLmFwcGVuZChwYXJhbWV0ZXJuYW1lc1swXSk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgdHlwZXMubGVuZ3RoOyArK2kpCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZCgnLCcpLmFwcGVuZCh0eXBlc1tpXS5nZXRKYXZhTmFtZSgpKTsKLQotICAgICAgICBpZiAocGFyYW1ldGVybmFtZXMgIT0gbnVsbCkKLSAgICAgICAgICBzYi5hcHBlbmQoJyAnKS5hcHBlbmQocGFyYW1ldGVybmFtZXNbaV0pOwotICAgICAgfQotICAgIH0KLQotICAgIHNiLmFwcGVuZCgnKScpOwotCi0gICAgdHlwZXMgPSBnZXRFeGNlcHRpb25UeXBlcygpOwotCi0gICAgaWYgKHR5cGVzICE9IG51bGwgJiB0eXBlcy5sZW5ndGggPiAwKQotICAgIHsKLSAgICAgIHNiLmFwcGVuZCgiIHRocm93cyAiKS5hcHBlbmQodHlwZXNbMF0uZ2V0SmF2YU5hbWUoKSk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgdHlwZXMubGVuZ3RoOyArK2kpCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZCgnLCcpLmFwcGVuZCh0eXBlc1tpXS5nZXRKYXZhTmFtZSgpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoYm9keSA9PSBudWxsKQotICAgICAgc2IuYXBwZW5kKCI7IC8vIE5vIG1ldGhvZCBib2R5IGF2YWlsYWJsZVxuIik7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHNiLmFwcGVuZCgiXG4iICsgYmFzZXRhYiArICJ7XG4iKTsKLQotICAgICAgaWYgKGxhbmd1YWdlID09IG51bGwgfHwgImphdmEiLmVxdWFscyhsYW5ndWFnZSkpCi0gICAgICB7Ci0gICAgICAgIHNiLmFwcGVuZChiYXNldGFiICsgIi8vICoqKioqIFNob3VsZCBwcmV0dHlwcmludCB0aGlzIGNvZGUuLi5cbiIpOwotICAgICAgICBzYi5hcHBlbmQoYmFzZXRhYiArIGJvZHkgKyAiXG4iKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgc2IuYXBwZW5kKGJhc2V0YWIgKyAiLy8gKioqKiogR2VuZXJhdGUgQlNGIGludm9jYXRpb24hP1xuIik7Ci0gICAgICB9Ci0KLSAgICAgIHNiLmFwcGVuZChiYXNldGFiICsgIn1cbiIpOwotICAgIH0KLQotICAgIHJldHVybiBzYi50b1N0cmluZygpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL3JlZmxlY3Rpb24vRmllbGQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9GaWVsZC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNTcxM2NmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9GaWVsZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODM0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5yZWZsZWN0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5TeW50aGVzaXNFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBBIEZpZWxkIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0LCBhbmQgZHluYW1pYyBhY2Nlc3MKLSAqIHRvLCBhIHNpbmdsZSBmaWVsZCBvZiBhIGNsYXNzIG9yIGFuIGludGVyZmFjZS4gVGhlIHJlZmxlY3RlZAotICogZmllbGQgbWF5IGJlIGEgY2xhc3MgKHN0YXRpYykgZmllbGQgb3IgYW4gaW5zdGFuY2UgZmllbGQuCi0gKiA8cD4KLSAqIEEgRmllbGQgcGVybWl0cyB3aWRlbmluZyBjb252ZXJzaW9ucyB0byBvY2N1ciBkdXJpbmcgYQotICogZ2V0IG9yIHNldCBhY2Nlc3Mgb3BlcmF0aW9uLCBidXQgdGhyb3dzIGFuCi0gKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYSBuYXJyb3dpbmcgY29udmVyc2lvbgotICogd291bGQgb2NjdXIuCi0gKgotICovCi1wdWJsaWMgY2xhc3MgRmllbGQgZXh0ZW5kcyBPYmplY3QgaW1wbGVtZW50cyBNZW1iZXIKLXsKLQotICAvKiogRmllbGQgbmFtZSwgaW5pdGlhbGl6ZXIgICAgICAgICAgKi8KLSAgcHVibGljIFN0cmluZyBuYW1lLCBpbml0aWFsaXplciA9IG51bGw7Ci0KLSAgLyoqIEZpZWxkIG1vZGlmaWVycyAgICAgICAgICAqLwotICBpbnQgbW9kaWZpZXJzOwotCi0gIC8qKiBGaWVsZCByZWFsZmllbGQgICAgICAgICAgKi8KLSAgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQgcmVhbGZpZWxkID0gbnVsbDsKLQotICAvKiogRmllbGQgZGVjbGFyaW5nQ2xhc3MsIHR5cGUgICAgICAgICAgKi8KLSAgQ2xhc3MgZGVjbGFyaW5nQ2xhc3MsIHR5cGU7Ci0KLSAgLyoqCi0gICAqIFByb3h5IGNvbnN0cnVjdG9yIAotICAgKgotICAgKiBAcGFyYW0gcmVhbGZpZWxkCi0gICAqIEBwYXJhbSBkZWNsYXJpbmdDbGFzcwotICAgKi8KLSAgcHVibGljIEZpZWxkKGphdmEubGFuZy5yZWZsZWN0LkZpZWxkIHJlYWxmaWVsZCwKLSAgICAgICAgICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyBkZWNsYXJpbmdDbGFzcykKLSAgewotCi0gICAgdGhpcyhyZWFsZmllbGQuZ2V0TmFtZSgpLCBkZWNsYXJpbmdDbGFzcyk7Ci0KLSAgICB0aGlzLnJlYWxmaWVsZCA9IHJlYWxmaWVsZDsKLSAgICB0aGlzLnR5cGUgPQotICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzLmZvckNsYXNzKHJlYWxmaWVsZC5nZXRUeXBlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFN5bnRoZXNpcyBjb25zdHJ1Y3RvciAKLSAgICoKLSAgICogQHBhcmFtIG5hbWUKLSAgICogQHBhcmFtIGRlY2xhcmluZ0NsYXNzCi0gICAqLwotICBwdWJsaWMgRmllbGQoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nQ2xhc3MpCi0gIHsKLSAgICB0aGlzLm5hbWUgPSBuYW1lOwotICAgIHRoaXMuZGVjbGFyaW5nQ2xhc3MgPSBkZWNsYXJpbmdDbGFzczsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIEZpZWxkIGFnYWluc3QgdGhlIHNwZWNpZmllZCBvYmplY3QuCi0gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgb2JqZWN0cyBhcmUgdGhlIHNhbWUuIFR3bwotICAgKiBGaWVsZHMgYXJlIHRoZSBzYW1lIGlmIHRoZXkgd2VyZSBkZWNsYXJlZCBieSB0aGUKLSAgICogc2FtZSBjbGFzcyBhbmQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCB0eXBlLgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikKLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC5lcXVhbHMob2JqKTsKLSAgICBlbHNlIGlmIChvYmogaW5zdGFuY2VvZiBGaWVsZCkKLSAgICB7Ci0gICAgICBGaWVsZCBvYmpmID0gKEZpZWxkKSBvYmo7Ci0KLSAgICAgIHJldHVybiAoZGVjbGFyaW5nQ2xhc3MuZXF1YWxzKG9iamYuZGVjbGFyaW5nQ2xhc3MpCi0gICAgICAgICAgICAgICYmIG5hbWUuZXF1YWxzKG9iamYubmFtZSkgJiYgdHlwZS5lcXVhbHMob2JqZi50eXBlKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgcmVwcmVzZW50ZWQgYnkgdGhpcwotICAgKiBGaWVsZCwgb24gdGhlIHNwZWNpZmllZCBvYmplY3QuIFRoZSB2YWx1ZSBpcwotICAgKiBhdXRvbWF0aWNhbGx5IHdyYXBwZWQgaW4gYW4gb2JqZWN0IGlmIGl0IGhhcyBhCi0gICAqIHByaW1pdGl2ZSB0eXBlLgotICAgKiA8cD4KLSAgICogVGhlIHVuZGVybHlpbmcgZmllbGQncyB2YWx1ZSBpcyBvYnRhaW5lZCBhcyBmb2xsb3dzOgotICAgKiA8cD4KLSAgICogSWYgdGhlIHVuZGVybHlpbmcgZmllbGQgaXMgYSBzdGF0aWMgZmllbGQsIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaXMgaWdub3JlZDsgaXQgbWF5IGJlIG51bGwuCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIHRoZSB1bmRlcmx5aW5nIGZpZWxkIGlzIGFuIGluc3RhbmNlCi0gICAqIGZpZWxkLiBJZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcmd1bWVudCBpcyBudWxsLCB0aGUKLSAgICogbWV0aG9kIHRocm93cyBhIE51bGxQb2ludGVyRXhjZXB0aW9uLiBJZiB0aGUKLSAgICogc3BlY2lmaWVkIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlIHVuZGVybHlpbmcgZmllbGQsIHRoZQotICAgKiBtZXRob2QgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4KLSAgICogPHA+Ci0gICAqIElmIHRoaXMgRmllbGQgb2JqZWN0IGVuZm9yY2VzIEphdmEgbGFuZ3VhZ2UgYWNjZXNzCi0gICAqIGNvbnRyb2wsIGFuZCB0aGUgdW5kZXJseWluZyBmaWVsZCBpcyBpbmFjY2Vzc2libGUsCi0gICAqIHRoZSBtZXRob2QgdGhyb3dzIGFuIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24uCi0gICAqIDxwPgotICAgKiBPdGhlcndpc2UsIHRoZSB2YWx1ZSBpcyByZXRyaWV2ZWQgZnJvbSB0aGUKLSAgICogdW5kZXJseWluZyBpbnN0YW5jZSBvciBzdGF0aWMgZmllbGQuIElmIHRoZSBmaWVsZCBoYXMgYQotICAgKiBwcmltaXRpdmUgdHlwZSwgdGhlIHZhbHVlIGlzIHdyYXBwZWQgaW4gYW4gb2JqZWN0Ci0gICAqIGJlZm9yZSBiZWluZyByZXR1cm5lZCwgb3RoZXJ3aXNlIGl0IGlzIHJldHVybmVkIGFzCi0gICAqIGlzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZgotICAgKiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIGRlY2xhcmluZyB0aGUKLSAgICogdW5kZXJseWluZyBmaWVsZC4KLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgKiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXQoT2JqZWN0IG9iaikKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHJldHVybiByZWFsZmllbGQuZ2V0KG9iaik7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIGJvb2xlYW4gb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgZmllbGQgdmFsdWUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUKLSAgICogcmV0dXJuIHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihPYmplY3Qgb2JqKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC5nZXRCb29sZWFuKG9iaik7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIGJ5dGUgb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgZmllbGQgdmFsdWUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUKLSAgICogcmV0dXJuIHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uLgotICAgKi8KLSAgcHVibGljIGJ5dGUgZ2V0Qnl0ZShPYmplY3Qgb2JqKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC5nZXRCeXRlKG9iaik7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIGNoYXIgb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgZmllbGQgdmFsdWUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUKLSAgICogcmV0dXJuIHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uLgotICAgKi8KLSAgcHVibGljIGNoYXIgZ2V0Q2hhcihPYmplY3Qgb2JqKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC5nZXRDaGFyKG9iaik7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIENsYXNzIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGNsYXNzIG9yCi0gICAqIGludGVyZmFjZSB0aGF0IGRlY2xhcmVzIHRoZSBmaWVsZCByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqIEZpZWxkIG9iamVjdC4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZ2V0RGVjbGFyaW5nQ2xhc3MoKQotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZXR1cm4gb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzLmZvckNsYXNzKAotICAgICAgICByZWFsZmllbGQuZ2V0RGVjbGFyaW5nQ2xhc3MoKSk7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIGRvdWJsZSBvbiBzcGVjaWZpZWQKLSAgICogb2JqZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBmaWVsZCB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZQotICAgKiByZXR1cm4gdHlwZSBieSBhIHdpZGVuaW5nIGNvbnZlcnNpb24uCi0gICAqLwotICBwdWJsaWMgZG91YmxlIGdldERvdWJsZShPYmplY3Qgb2JqKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC5nZXREb3VibGUob2JqKTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGFzIGEgZmxvYXQgb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgZmllbGQgdmFsdWUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUKLSAgICogcmV0dXJuIHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uLgotICAgKi8KLSAgcHVibGljIGZsb2F0IGdldEZsb2F0KE9iamVjdCBvYmopCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGZpZWxkLmdldEZsb2F0KG9iaik7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIGludCBvbiBzcGVjaWZpZWQgb2JqZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBmaWVsZCB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZQotICAgKiByZXR1cm4gdHlwZSBieSBhIHdpZGVuaW5nIGNvbnZlcnNpb24uCi0gICAqLwotICBwdWJsaWMgaW50IGdldEludChPYmplY3Qgb2JqKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC5nZXRJbnQob2JqKTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGFzIGEgbG9uZyBvbiBzcGVjaWZpZWQKLSAgICogb2JqZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBmaWVsZCB2YWx1ZSBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZQotICAgKiByZXR1cm4gdHlwZSBieSBhIHdpZGVuaW5nIGNvbnZlcnNpb24uCi0gICAqLwotICBwdWJsaWMgbG9uZyBnZXRMb25nKE9iamVjdCBvYmopCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGZpZWxkLmdldExvbmcob2JqKTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgSmF2YSBsYW5ndWFnZSBtb2RpZmllcnMgZm9yIHRoZSBmaWVsZAotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIEZpZWxkIG9iamVjdCwgYXMgYW4gaW50ZWdlci4gVGhlCi0gICAqIE1vZGlmaWVyIGNsYXNzIHNob3VsZCBiZSB1c2VkIHRvIGRlY29kZSB0aGUKLSAgICogbW9kaWZpZXJzLgotICAgKgotICAgKi8KLSAgcHVibGljIGludCBnZXRNb2RpZmllcnMoKQotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICBtb2RpZmllcnMgPSByZWFsZmllbGQuZ2V0TW9kaWZpZXJzKCk7Ci0KLSAgICByZXR1cm4gbW9kaWZpZXJzOwotICB9Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCBnZXRJbml0aWFsaXplciAKLSAgICoKLSAgICoKLSAgICogKGdldEluaXRpYWxpemVyKSBAcmV0dXJuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEluaXRpYWxpemVyKCkKLSAgewotICAgIHJldHVybiBpbml0aWFsaXplcjsKLSAgfQotCi0gIC8qKgotICAgKiBNZXRob2Qgc2V0SW5pdGlhbGl6ZXIgCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpCi0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJbml0aWFsaXplcihTdHJpbmcgaSkgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIGluaXRpYWxpemVyID0gaTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgdGhlIG1ldGhvZCdzIGRlc2NyaXB0aW9uIGhlcmUuCi0gICAqIENyZWF0aW9uIGRhdGU6ICgxMi0yNS05OSAyOjAyOjI2IFBNKQotICAgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKLSAgICovCi0gIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGFzIGEgc2hvcnQgb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgZmllbGQgdmFsdWUgY2Fubm90IGJlIGNvbnZlcnRlZCB0byB0aGUKLSAgICogcmV0dXJuIHR5cGUgYnkgYSB3aWRlbmluZyBjb252ZXJzaW9uLgotICAgKi8KLSAgcHVibGljIHNob3J0IGdldFNob3J0KE9iamVjdCBvYmopCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGZpZWxkLmdldFNob3J0KG9iaik7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBDbGFzcyBvYmplY3QgdGhhdCBpZGVudGlmaWVzIHRoZSBkZWNsYXJlZAotICAgKiB0eXBlIGZvciB0aGUgZmllbGQgcmVwcmVzZW50ZWQgYnkgdGhpcyBGaWVsZCBvYmplY3QuCi0gICAqCi0gICAqLwotICBwdWJsaWMgQ2xhc3MgZ2V0VHlwZSgpCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHR5cGUgPSBDbGFzcy5mb3JDbGFzcyhyZWFsZmllbGQuZ2V0VHlwZSgpKTsKLQotICAgIHJldHVybiB0eXBlOwotICB9Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCBzZXRUeXBlIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gdHlwZQotICAgKgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VHlwZShvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgdHlwZSkKLSAgICAgICAgICB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgdGhpcy50eXBlID0gdHlwZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgRmllbGQuIFRoaXMgaXMKLSAgICogY29tcHV0ZWQgYXMgdGhlIGV4Y2x1c2l2ZS1vciBvZiB0aGUgaGFzaGNvZGVzIGZvcgotICAgKiB0aGUgdW5kZXJseWluZyBmaWVsZCdzIGRlY2xhcmluZyBjbGFzcyBuYW1lIGFuZCBpdHMKLSAgICogbmFtZS4KLSAgICoKLSAgICovCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKQotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZXR1cm4gcmVhbGZpZWxkLmhhc2hDb2RlKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIGRlY2xhcmluZ0NsYXNzLmdldE5hbWUoKS5oYXNoQ29kZSgpIF4gbmFtZS5oYXNoQ29kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldHMgdGhlIGZpZWxkIHJlcHJlc2VudGVkIGJ5IHRoaXMgRmllbGQgb2JqZWN0IG9uCi0gICAqIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGFyZ3VtZW50IHRvIHRoZSBzcGVjaWZpZWQgbmV3Ci0gICAqIHZhbHVlLiBUaGUgbmV3IHZhbHVlIGlzIGF1dG9tYXRpY2FsbHkgdW53cmFwcGVkCi0gICAqIGlmIHRoZSB1bmRlcmx5aW5nIGZpZWxkIGhhcyBhIHByaW1pdGl2ZSB0eXBlLgotICAgKgotICAgKiBUaGUgb3BlcmF0aW9uIHByb2NlZWRzIGFzIGZvbGxvd3M6Ci0gICAqCi0gICAqIElmIHRoZSB1bmRlcmx5aW5nIGZpZWxkIGlzIHN0YXRpYywgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpcyBpZ25vcmVkOyBpdCBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogT3RoZXJ3aXNlIHRoZSB1bmRlcmx5aW5nIGZpZWxkIGlzIGFuIGluc3RhbmNlIGZpZWxkLgotICAgKiBJZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcmd1bWVudCBpcyBudWxsLCB0aGUKLSAgICogbWV0aG9kIHRocm93cyBhIE51bGxQb2ludGVyRXhjZXB0aW9uLiBJZiB0aGUKLSAgICogc3BlY2lmaWVkIG9iamVjdCBhcmd1bWVudCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdGhlCi0gICAqIGNsYXNzIG9yIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlIHVuZGVybHlpbmcgZmllbGQsCi0gICAqIHRoZSBtZXRob2QgdGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi4KLSAgICoKLSAgICogSWYgdGhpcyBGaWVsZCBvYmplY3QgZW5mb3JjZXMgSmF2YSBsYW5ndWFnZSBhY2Nlc3MKLSAgICogY29udHJvbCwgYW5kIHRoZSB1bmRlcmx5aW5nIGZpZWxkIGlzIGluYWNjZXNzaWJsZSwKLSAgICogdGhlIG1ldGhvZCB0aHJvd3MgYW4gSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbi4KLSAgICoKLSAgICogSWYgdGhlIHVuZGVybHlpbmcgZmllbGQgaXMgZmluYWwsIHRoZSBtZXRob2QgdGhyb3dzCi0gICAqIGFuIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24uCi0gICAqCi0gICAqIElmIHRoZSB1bmRlcmx5aW5nIGZpZWxkIGlzIG9mIGEgcHJpbWl0aXZlIHR5cGUsIGFuCi0gICAqIHVud3JhcHBpbmcgY29udmVyc2lvbiBpcyBhdHRlbXB0ZWQgdG8gY29udmVydCB0aGUKLSAgICogbmV3IHZhbHVlIHRvIGEgdmFsdWUgb2YgYSBwcmltaXRpdmUgdHlwZS4gSWYgdGhpcwotICAgKiBhdHRlbXB0IGZhaWxzLCB0aGUgbWV0aG9kIHRocm93cyBhbgotICAgKiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uCi0gICAqCi0gICAqIElmLCBhZnRlciBwb3NzaWJsZSB1bndyYXBwaW5nLCB0aGUgbmV3IHZhbHVlCi0gICAqIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gdGhlIHR5cGUgb2YgdGhlIHVuZGVybHlpbmcKLSAgICogZmllbGQgYnkgYW4gaWRlbnRpdHkgb3Igd2lkZW5pbmcgY29udmVyc2lvbiwgdGhlCi0gICAqIG1ldGhvZCB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLgotICAgKgotICAgKiBUaGUgZmllbGQgaXMgc2V0IHRvIHRoZSBwb3NzaWJseSB1bndyYXBwZWQgYW5kCi0gICAqIHdpZGVuZWQgbmV3IHZhbHVlLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqIEBwYXJhbSB2YWx1ZQotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YKLSAgICogdGhlIGNsYXNzIG9yIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlCi0gICAqIHVuZGVybHlpbmcgZmllbGQsIG9yIGlmIGFuIHVud3JhcHBpbmcKLSAgICogY29udmVyc2lvbiBmYWlscy4KLSAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotICAgKiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0KE9iamVjdCBvYmosIE9iamVjdCB2YWx1ZSkKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHJlYWxmaWVsZC5zZXQob2JqLCB2YWx1ZSk7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIGJvb2xlYW4gb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKiBAcGFyYW0gegotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YKLSAgICogdGhlIGNsYXNzIG9yIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlCi0gICAqIHVuZGVybHlpbmcgZmllbGQsIG9yIGlmIGFuIHVud3JhcHBpbmcKLSAgICogY29udmVyc2lvbiBmYWlscy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEJvb2xlYW4oT2JqZWN0IG9iaiwgYm9vbGVhbiB6KQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmVhbGZpZWxkLnNldEJvb2xlYW4ob2JqLCB6KTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGFzIGEgYnl0ZSBvbiBzcGVjaWZpZWQKLSAgICogb2JqZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqIEBwYXJhbSBiCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZgotICAgKiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIGRlY2xhcmluZyB0aGUKLSAgICogdW5kZXJseWluZyBmaWVsZCwgb3IgaWYgYW4gdW53cmFwcGluZwotICAgKiBjb252ZXJzaW9uIGZhaWxzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Qnl0ZShPYmplY3Qgb2JqLCBieXRlIGIpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZWFsZmllbGQuc2V0Qnl0ZShvYmosIGIpOwotCi0gICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmllbGQgYXMgYSBjaGFyIG9uIHNwZWNpZmllZAotICAgKiBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBvYmoKLSAgICogQHBhcmFtIGMKLSAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gICAqIGlmIHRoZSB1bmRlcmx5aW5nIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICogaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mCi0gICAqIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgZGVjbGFyaW5nIHRoZQotICAgKiB1bmRlcmx5aW5nIGZpZWxkLCBvciBpZiBhbiB1bndyYXBwaW5nCi0gICAqIGNvbnZlcnNpb24gZmFpbHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDaGFyKE9iamVjdCBvYmosIGNoYXIgYykKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHJlYWxmaWVsZC5zZXRDaGFyKG9iaiwgYyk7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIENsYXNzIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGNsYXNzIHRoYXQKLSAgICogZGVjbGFyZXMgdGhlIGNvbnN0cnVjdG9yIHJlcHJlc2VudGVkIGJ5IHRoaXMKLSAgICogQ29uc3RydWN0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gZGVjbGFyaW5nQ2xhc3MKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERlY2xhcmluZ0NsYXNzKAotICAgICAgICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyBkZWNsYXJpbmdDbGFzcykKLSAgewotICAgIHRoaXMuZGVjbGFyaW5nQ2xhc3MgPSBkZWNsYXJpbmdDbGFzczsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmllbGQgYXMgYSBkb3VibGUgb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKiBAcGFyYW0gZAotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YKLSAgICogdGhlIGNsYXNzIG9yIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlCi0gICAqIHVuZGVybHlpbmcgZmllbGQsIG9yIGlmIGFuIHVud3JhcHBpbmcKLSAgICogY29udmVyc2lvbiBmYWlscy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldERvdWJsZShPYmplY3Qgb2JqLCBkb3VibGUgZCkKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHJlYWxmaWVsZC5zZXREb3VibGUob2JqLCBkKTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGFzIGEgZmxvYXQgb24gc3BlY2lmaWVkCi0gICAqIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iagotICAgKiBAcGFyYW0gZgotICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgICogaWYgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgotICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICAgKiBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YKLSAgICogdGhlIGNsYXNzIG9yIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlCi0gICAqIHVuZGVybHlpbmcgZmllbGQsIG9yIGlmIGFuIHVud3JhcHBpbmcKLSAgICogY29udmVyc2lvbiBmYWlscy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEZsb2F0KE9iamVjdCBvYmosIGZsb2F0IGYpCi0gICAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICByZWFsZmllbGQuc2V0RmxvYXQob2JqLCBmKTsKLQotICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGFzIGFuIGludCBvbiBzcGVjaWZpZWQKLSAgICogb2JqZWN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gb2JqCi0gICAqIEBwYXJhbSBpCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgotICAgKiBpZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIG5vdCBhbiBpbnN0YW5jZSBvZgotICAgKiB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIGRlY2xhcmluZyB0aGUKLSAgICogdW5kZXJseWluZyBmaWVsZCwgb3IgaWYgYW4gdW53cmFwcGluZwotICAgKiBjb252ZXJzaW9uIGZhaWxzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SW50KE9iamVjdCBvYmosIGludCBpKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmVhbGZpZWxkLnNldEludChvYmosIGkpOwotCi0gICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZmllbGQgYXMgYSBsb25nIG9uIHNwZWNpZmllZAotICAgKiBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBvYmoKLSAgICogQHBhcmFtIGwKLSAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gICAqIGlmIHRoZSB1bmRlcmx5aW5nIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICogaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mCi0gICAqIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgZGVjbGFyaW5nIHRoZQotICAgKiB1bmRlcmx5aW5nIGZpZWxkLCBvciBpZiBhbiB1bndyYXBwaW5nCi0gICAqIGNvbnZlcnNpb24gZmFpbHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMb25nKE9iamVjdCBvYmosIGxvbmcgbCkKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZmllbGQgIT0gbnVsbCkKLSAgICAgIHJlYWxmaWVsZC5zZXRMb25nKG9iaiwgbCk7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCB0aGUgbWV0aG9kJ3MgZGVzY3JpcHRpb24gaGVyZS4KLSAgICogQ3JlYXRpb24gZGF0ZTogKDEyLTI1LTk5IDE6Mjg6MjggUE0pCi0gICAqIEByZXR1cm4gaW50Ci0gICAqIEBwYXJhbSBtb2RpZmllcnMgaW50Ci0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRNb2RpZmllcnMoaW50IG1vZGlmaWVycykgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAocmVhbGZpZWxkICE9IG51bGwpCi0gICAgICB0aHJvdyBuZXcgU3ludGhlc2lzRXhjZXB0aW9uKFN5bnRoZXNpc0V4Y2VwdGlvbi5SRUlGSUVEKTsKLQotICAgIHRoaXMubW9kaWZpZXJzID0gbW9kaWZpZXJzOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgdmFsdWUgb2YgYSBmaWVsZCBhcyBhIHNob3J0IG9uIHNwZWNpZmllZAotICAgKiBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBvYmoKLSAgICogQHBhcmFtIHMKLSAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gICAqIGlmIHRoZSB1bmRlcmx5aW5nIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KLSAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLSAgICogaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgbm90IGFuIGluc3RhbmNlIG9mCi0gICAqIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgZGVjbGFyaW5nIHRoZQotICAgKiB1bmRlcmx5aW5nIGZpZWxkLCBvciBpZiBhbiB1bndyYXBwaW5nCi0gICAqIGNvbnZlcnNpb24gZmFpbHMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaG9ydChPYmplY3Qgb2JqLCBzaG9ydCBzKQotICAgICAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmVhbGZpZWxkLnNldFNob3J0KG9iaiwgcyk7Ci0KLSAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiBhIHN0cmluZyBkZXNjcmliaW5nIHRoaXMgRmllbGQuIFRoZSBmb3JtYXQgaXMKLSAgICogdGhlIGFjY2VzcyBtb2RpZmllcnMgZm9yIHRoZSBmaWVsZCwgaWYgYW55LCBmb2xsb3dlZAotICAgKiBieSB0aGUgZmllbGQgdHlwZSwgZm9sbG93ZWQgYnkgYSBzcGFjZSwgZm9sbG93ZWQgYnkKLSAgICogdGhlIGZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoZSBjbGFzcyBkZWNsYXJpbmcgdGhlCi0gICAqIGZpZWxkLCBmb2xsb3dlZCBieSBhIHBlcmlvZCwgZm9sbG93ZWQgYnkgdGhlIG5hbWUKLSAgICogb2YgdGhlIGZpZWxkLiBGb3IgZXhhbXBsZToKLSAgICogPGNvZGU+Ci0gICAqIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGphdmEubGFuZy5UaHJlYWQuTUlOX1BSSU9SSVRZCi0gICAqIHByaXZhdGUgaW50IGphdmEuaW8uRmlsZURlc2NyaXB0b3IuZmQKLSAgICogPC9jb2RlPgotICAgKgotICAgKiBUaGUgbW9kaWZpZXJzIGFyZSBwbGFjZWQgaW4gY2Fub25pY2FsIG9yZGVyIGFzCi0gICAqIHNwZWNpZmllZCBieSAiVGhlIEphdmEgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbiIuCi0gICAqIFRoaXMgaXMgcHVibGljLCBwcm90ZWN0ZWQgb3IgcHJpdmF0ZSBmaXJzdCwKLSAgICogYW5kIHRoZW4gb3RoZXIgbW9kaWZpZXJzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6Ci0gICAqIHN0YXRpYywgZmluYWwsIHRyYW5zaWVudCwgdm9sYXRpbGUuCi0gICAqCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotCi0gICAgaWYgKHJlYWxmaWVsZCAhPSBudWxsKQotICAgICAgcmV0dXJuIHJlYWxmaWVsZC50b1N0cmluZygpOwotCi0gICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKLSAgfQotCi0gIC8qKgotICAgKiBPdXRwdXQgdGhlIEZpZWxkIGFzIEphdmEgc291cmNlY29kZQotICAgKgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1NvdXJjZSgpCi0gIHsKLQotICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoCi0gICAgICBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllci50b1N0cmluZyhnZXRNb2RpZmllcnMoKSkpLmFwcGVuZCgnICcpLmFwcGVuZCgKLSAgICAgIGdldFR5cGUoKS5nZXRKYXZhTmFtZSgpKS5hcHBlbmQoJyAnKS5hcHBlbmQoZ2V0TmFtZSgpKTsKLSAgICBTdHJpbmcgaSA9IGdldEluaXRpYWxpemVyKCk7Ci0KLSAgICBpZiAoaSAhPSBudWxsICYmIGkubGVuZ3RoKCkgPiAwKQotICAgICAgc2IuYXBwZW5kKCc9JykuYXBwZW5kKGkpOwotCi0gICAgc2IuYXBwZW5kKCc7Jyk7Ci0KLSAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9yZWZsZWN0aW9uL01lbWJlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYy9yZWZsZWN0aW9uL01lbWJlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMzhjODUzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9NZW1iZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMucmVmbGVjdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5TeW50aGVzaXNFeGNlcHRpb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBNZW1iZXIgaXMgYW4gaW50ZXJmYWNlIHRoYXQgcmVmbGVjdHMgaWRlbnRpZnlpbmcKLSAqIGluZm9ybWF0aW9uIGFib3V0IGEgc2luZ2xlIG1lbWJlciAoYSBmaWVsZCBvciBhIG1ldGhvZCkKLSAqIG9yIGEgY29uc3RydWN0b3IuCi0gKiA8cD4KLSAqIE5vdGUgdGhhdCB0aGlzIGlzIDxzdHJvbmc+bm90PC9zdHJvbmc+IGN1cnJlbnRseSBkZXJpdmVkIGZyb20KLSAqIGphdmEubGFuZy5yZWZsZWN0Lk1lbWJlciwgZHVlIHRvIHF1ZXN0aW9ucyBhYm91dCBob3cgdG8gaGFuZGxlCi0gKiBkZWNsYXJpZ25DbGFzcy4KLSAqCi0gKiBAc2VlIG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcwotICovCi1wdWJsaWMgaW50ZXJmYWNlIE1lbWJlcgotewotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBDbGFzcyBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjbGFzcyBvcgotICAgKiBpbnRlcmZhY2UgdGhhdCBkZWNsYXJlcyB0aGUgbWVtYmVyIG9yIGNvbnN0cnVjdG9yCi0gICAqIHJlcHJlc2VudGVkIGJ5IHRoaXMgTWVtYmVyLgotICAgKgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IG9yZy5hcGFjaGUueG1sLnV0aWxzLnN5bnRoZXRpYy5DbGFzcyBnZXREZWNsYXJpbmdDbGFzcygpOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBKYXZhIGxhbmd1YWdlIG1vZGlmaWVycyBmb3IgdGhlCi0gICAqIG1lbWJlciBvciBjb25zdHJ1Y3RvciByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqIE1lbWJlciwgYXMgYW4gaW50ZWdlci4gVGhlIE1vZGlmaWVyIGNsYXNzIHNob3VsZAotICAgKiBiZSB1c2VkIHRvIGRlY29kZSB0aGUgbW9kaWZpZXJzIGluIHRoZSBpbnRlZ2VyLgotICAgKgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBnZXRNb2RpZmllcnMoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgQ2xhc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY2xhc3Mgb3IKLSAgICogaW50ZXJmYWNlIHRoYXQgZGVjbGFyZXMgdGhlIG1lbWJlciBvciBjb25zdHJ1Y3RvcgotICAgKiByZXByZXNlbnRlZCBieSB0aGlzIE1lbWJlci4KLSAgICoKLSAgICogQHBhcmFtIGRlY2xhcmluZ0NsYXNzCi0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREZWNsYXJpbmdDbGFzcygKLSAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nQ2xhc3MpCi0gICAgICB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBKYXZhIGxhbmd1YWdlIG1vZGlmaWVycyBmb3IgdGhlCi0gICAqIG1lbWJlciBvciBjb25zdHJ1Y3RvciByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqIE1lbWJlciwgYXMgYW4gaW50ZWdlci4gVGhlIE1vZGlmaWVyIGNsYXNzIHNob3VsZAotICAgKiBiZSB1c2VkIHRvIGRlY29kZSB0aGUgbW9kaWZpZXJzIGluIHRoZSBpbnRlZ2VyLgotICAgKgotICAgKiBAcGFyYW0gbW9kaWZpZXJzCi0gICAqCi0gICAqIEB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRNb2RpZmllcnMoaW50IG1vZGlmaWVycykgdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9NZXRob2QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscy9zeW50aGV0aWMvcmVmbGVjdGlvbi9NZXRob2QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTk2OTc4YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMvc3ludGhldGljL3JlZmxlY3Rpb24vTWV0aG9kLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb247Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLlN5bnRoZXNpc0V4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIEEgTWV0aG9kIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0LCBhbmQgYWNjZXNzIHRvLCBhCi0gKiBzaW5nbGUgbWV0aG9kIG9uIGEgY2xhc3Mgb3IgaW50ZXJmYWNlLiBUaGUgcmVmbGVjdGVkCi0gKiBtZXRob2QgbWF5IGJlIGEgY2xhc3MgbWV0aG9kIG9yIGFuIGluc3RhbmNlIG1ldGhvZAotICogKGluY2x1ZGluZyBhbiBhYnN0cmFjdCBtZXRob2QpLgotICogPHA+Ci0gKiBBIE1ldGhvZCBwZXJtaXRzIHdpZGVuaW5nIGNvbnZlcnNpb25zIHRvIG9jY3VyIHdoZW4KLSAqIG1hdGNoaW5nIHRoZSBhY3R1YWwgcGFyYW1ldGVycyB0byBpbnZva2V3aXRoIHRoZQotICogdW5kZXJseWluZyBtZXRob2QncyBmb3JtYWwgcGFyYW1ldGVycywgYnV0IGl0IHRocm93cyBhbgotICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgbmFycm93aW5nIGNvbnZlcnNpb24KLSAqIHdvdWxkIG9jY3VyLgotICogPHA+Ci0gKiAgTmVlZCB0byBhZGQgbWV0aG9kIGJvZHksIGEgbGEgTWF0dCdzIGNvZGVidWZmZXIuCi0gKiBUaGF0IG1heSBvciBtYXkgbm90IGltcGx5IHJldGFpbmluZyB0aGUgZmluYWwgcmV0dXJuIHZhbHVlCi0gKiBzZXBhcmF0ZWx5IGFuZCBwYXNzaW5nIGluIGEgaG93LXRvLXVzZS1pdCBtZWNoYW5pc20uLi4/Ci0gKgotICovCi1wdWJsaWMgY2xhc3MgTWV0aG9kIGV4dGVuZHMgRW50cnlQb2ludCBpbXBsZW1lbnRzIE1lbWJlcgotewotCi0gIC8qKgotICAgKiBJbnNlcnQgdGhlIG1ldGhvZCdzIGRlc2NyaXB0aW9uIGhlcmUuCi0gICAqIDxwPgotICAgKiBDcmVhdGlvbiBkYXRlOiAoMTItMjctOTkgMjozMTozOSBQTSkKLSAgICogQHBhcmFtIHJlYWxDb25zdHJ1Y3RvciBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcgotICAgKgotICAgKiBAcGFyYW0gbmFtZQotICAgKiBAcGFyYW0gZGVjbGFyaW5nY2xhc3MKLSAgICovCi0gIHB1YmxpYyBNZXRob2QoU3RyaW5nIG5hbWUsCi0gICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGRlY2xhcmluZ2NsYXNzKQotICB7Ci0KLSAgICBzdXBlcihkZWNsYXJpbmdjbGFzcyk7Ci0KLSAgICB0aGlzLm5hbWUgPSBuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCB0aGUgbWV0aG9kJ3MgZGVzY3JpcHRpb24gaGVyZS4KLSAgICogPHA+Ci0gICAqIENyZWF0aW9uIGRhdGU6ICgxMi0yNy05OSAyOjMxOjM5IFBNKQotICAgKiBAcGFyYW0gcmVhbENvbnN0cnVjdG9yIGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yCi0gICAqCi0gICAqIEBwYXJhbSBjdG9yCi0gICAqIEBwYXJhbSBkZWNsYXJpbmdjbGFzcwotICAgKi8KLSAgcHVibGljIE1ldGhvZChqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgY3RvciwKLSAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgZGVjbGFyaW5nY2xhc3MpCi0gIHsKLSAgICBzdXBlcihjdG9yLCBkZWNsYXJpbmdjbGFzcyk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IHRoZSBtZXRob2QncyBkZXNjcmlwdGlvbiBoZXJlLgotICAgKiA8cD4KLSAgICogQ3JlYXRpb24gZGF0ZTogKDEyLTI3LTk5IDI6MzE6MzkgUE0pCi0gICAqIEBwYXJhbSByZWFsQ29uc3RydWN0b3IgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3IKLSAgICoKLSAgICogQHBhcmFtIHJlYWxtZXRob2QKLSAgICovCi0gIHB1YmxpYyBNZXRob2QoamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIHJlYWxtZXRob2QpCi0gIHsKLSAgICBzdXBlcihyZWFsbWV0aG9kKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgTWV0aG9kLiBUaGUgaGFzaGNvZGUKLSAgICogaXMgY29tcHV0ZWQgYXMgdGhlIGV4Y2x1c2l2ZS1vciBvZiB0aGUgaGFzaGNvZGVzCi0gICAqIGZvciB0aGUgdW5kZXJseWluZyBtZXRob2QncyBkZWNsYXJpbmcgY2xhc3MgbmFtZQotICAgKiBhbmQgdGhlIG1ldGhvZCdzIG5hbWUuCi0gICAqCi0gICAqLwotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgQ29uc3RydWN0b3IuIFRoZQotICAgKiBoYXNoY29kZSBmb3IgYSBNZXRob2QgaXMgdGhlIGhhc2hjb2RlIGZvciB0aGUKLSAgICogdW5kZXJseWluZyBjb25zdHJ1Y3RvcidzIGRlY2xhcmluZyBjbGFzcyBuYW1lLAotICAgKiBYT1JlZCB3aXRoIHRoZSBuYW1lIG9mIHRoaXMgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIGludCBoYXNoQ29kZSgpCi0gIHsKLSAgICByZXR1cm4gZ2V0RGVjbGFyaW5nQ2xhc3MoKS5nZXROYW1lKCkuaGFzaENvZGUoKSBeIGdldE5hbWUoKS5oYXNoQ29kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEludm9rZXMgdGhlIHVuZGVybHlpbmcgbWV0aG9kIHJlcHJlc2VudGVkIGJ5IHRoaXMKLSAgICogTWV0aG9kIG9iamVjdCwgb24gdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGUKLSAgICogc3BlY2lmaWVkIHBhcmFtZXRlcnMuIEluZGl2aWR1YWwgcGFyYW1ldGVycyBhcmUKLSAgICogYXV0b21hdGljYWxseSB1bndyYXBwZWQgdG8gbWF0Y2ggcHJpbWl0aXZlCi0gICAqIGZvcm1hbCBwYXJhbWV0ZXJzLCBhbmQgYm90aCBwcmltaXRpdmUgYW5kCi0gICAqIHJlZmVyZW5jZSBwYXJhbWV0ZXJzIGFyZSBzdWJqZWN0IHRvIHdpZGVuaW5nCi0gICAqIGNvbnZlcnNpb25zIGFzIG5lY2Vzc2FyeS4gVGhlIHZhbHVlIHJldHVybmVkIGJ5Ci0gICAqIHRoZSB1bmRlcmx5aW5nIG1ldGhvZCBpcyBhdXRvbWF0aWNhbGx5IHdyYXBwZWQKLSAgICogaW4gYW4gb2JqZWN0IGlmIGl0IGhhcyBhIHByaW1pdGl2ZSB0eXBlLgotICAgKgotICAgKiBNZXRob2QgaW52b2NhdGlvbiBwcm9jZWVkcyB3aXRoIHRoZSBmb2xsb3dpbmcKLSAgICogc3RlcHMsIGluIG9yZGVyOgotICAgKgotICAgKiBJZiB0aGUgdW5kZXJseWluZyBtZXRob2QgaXMgc3RhdGljLCB0aGVuIHRoZQotICAgKiBzcGVjaWZpZWQgb2JqZWN0IGFyZ3VtZW50IGlzIGlnbm9yZWQuIEl0IG1heSBiZQotICAgKiBudWxsLgotICAgKgotICAgKiBPdGhlcndpc2UsIHRoZSBtZXRob2QgaXMgYW4gaW5zdGFuY2UgbWV0aG9kLiBJZgotICAgKiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcmd1bWVudCBpcyBudWxsLCB0aGUKLSAgICogaW52b2NhdGlvbiB0aHJvd3MgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbi4KLSAgICogT3RoZXJ3aXNlLCBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBhcmd1bWVudCBpcyBub3QKLSAgICogYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIG9yIGludGVyZmFjZSBkZWNsYXJpbmcgdGhlCi0gICAqIHVuZGVybHlpbmcgbWV0aG9kLCB0aGUgaW52b2NhdGlvbiB0aHJvd3MgYW4KLSAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLgotICAgKgotICAgKiBJZiB0aGlzIE1ldGhvZCBvYmplY3QgZW5mb3JjZXMgSmF2YSBsYW5ndWFnZSBhY2Nlc3MKLSAgICogY29udHJvbCBhbmQgdGhlIHVuZGVybHlpbmcgbWV0aG9kIGlzIGluYWNjZXNzaWJsZSwKLSAgICogdGhlIGludm9jYXRpb24gdGhyb3dzIGFuIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24uCi0gICAqCi0gICAqIElmIHRoZSBudW1iZXIgb2YgYWN0dWFsIHBhcmFtZXRlcnMgc3VwcGxpZWQgdmlhCi0gICAqIGFyZ3MgaXMgZGlmZmVyZW50IGZyb20gdGhlIG51bWJlciBvZiBmb3JtYWwKLSAgICogcGFyYW1ldGVycyByZXF1aXJlZCBieSB0aGUgdW5kZXJseWluZyBtZXRob2QsIHRoZQotICAgKiBpbnZvY2F0aW9uIHRocm93cyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uCi0gICAqCi0gICAqIEZvciBlYWNoIGFjdHVhbCBwYXJhbWV0ZXIgaW4gdGhlIHN1cHBsaWVkIGFyZ3MKLSAgICogYXJyYXk6Ci0gICAqCi0gICAqIElmIHRoZSBjb3JyZXNwb25kaW5nIGZvcm1hbCBwYXJhbWV0ZXIgaGFzIGEKLSAgICogcHJpbWl0aXZlIHR5cGUsIGFuIHVud3JhcHBpbmcgY29udmVyc2lvbiBpcwotICAgKiBhdHRlbXB0ZWQgdG8gY29udmVydCB0aGUgb2JqZWN0IHZhbHVlIHRvIGEgdmFsdWUgb2YKLSAgICogYSBwcmltaXRpdmUgdHlwZS4gSWYgdGhpcyBhdHRlbXB0IGZhaWxzLCB0aGUKLSAgICogaW52b2NhdGlvbiB0aHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLgotICAgKgotICAgKiBJZiwgYWZ0ZXIgcG9zc2libGUgdW53cmFwcGluZywgdGhlIHBhcmFtZXRlciB2YWx1ZQotICAgKiBjYW5ub3QgYmUgY29udmVydGVkIHRvIHRoZSBjb3JyZXNwb25kaW5nIGZvcm1hbAotICAgKiBwYXJhbWV0ZXIgdHlwZSBieSBhbiBpZGVudGl0eSBvciB3aWRlbmluZwotICAgKiBjb252ZXJzaW9uLCB0aGUgaW52b2NhdGlvbiB0aHJvd3MgYW4KLSAgICogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLgotICAgKgotICAgKiBJZiB0aGUgdW5kZXJseWluZyBtZXRob2QgaXMgYW4gaW5zdGFuY2UgbWV0aG9kLCBpdAotICAgKiBpcyBpbnZva2VkIHVzaW5nIGR5bmFtaWMgbWV0aG9kIGxvb2t1cCBhcwotICAgKiBkb2N1bWVudGVkIGluIFRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sCi0gICAqIHNlY3Rpb24gMTUuMTEuNC40OyBpbiBwYXJ0aWN1bGFyLCBvdmVycmlkaW5nIGJhc2VkCi0gICAqIG9uIHRoZSBydW50aW1lIHR5cGUgb2YgdGhlIHRhcmdldCBvYmplY3Qgd2lsbCBvY2N1ci4KLSAgICoKLSAgICogSWYgdGhlIHVuZGVybHlpbmcgbWV0aG9kIGlzIHN0YXRpYywgaXQgaXMgaW52b2tlZCBhcwotICAgKiBleGFjdGx5IHRoZSBtZXRob2Qgb24gdGhlIGRlY2xhcmluZyBjbGFzcy4KLSAgICoKLSAgICogQ29udHJvbCB0cmFuc2ZlcnMgdG8gdGhlIHVuZGVybHlpbmcgbWV0aG9kLiBJZiB0aGUKLSAgICogbWV0aG9kIGNvbXBsZXRlcyBhYnJ1cHRseSBieSB0aHJvd2luZyBhbgotICAgKiBleGNlcHRpb24sIHRoZSBleGNlcHRpb24gaXMgcGxhY2VkIGluIGFuCi0gICAqIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gYW5kIHRocm93biBpbiB0dXJuIHRvCi0gICAqIHRoZSBjYWxsZXIgb2YgaW52b2tlLgotICAgKgotICAgKiBJZiB0aGUgbWV0aG9kIGNvbXBsZXRlcyBub3JtYWxseSwgdGhlIHZhbHVlIGl0Ci0gICAqIHJldHVybnMgaXMgcmV0dXJuZWQgdG8gdGhlIGNhbGxlciBvZiBpbnZva2U7IGlmIHRoZQotICAgKiB2YWx1ZSBoYXMgYSBwcmltaXRpdmUgdHlwZSwgaXQgaXMgZmlyc3QgYXBwcm9wcmlhdGVseQotICAgKiB3cmFwcGVkIGluIGFuIG9iamVjdC4gSWYgdGhlIHVuZGVybHlpbmcgbWV0aG9kCi0gICAqIHJldHVybiB0eXBlIGlzIHZvaWQsIHRoZSBpbnZvY2F0aW9uIHJldHVybnMgbnVsbC4KLSAgICoKLSAgICogVGhyb3dzOiBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gICAqIGlmIHRoZSB1bmRlcmx5aW5nIG1ldGhvZCBpcyBpbmFjY2Vzc2libGUuCi0gICAqIFRocm93czogSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIGlmIHRoZSBudW1iZXIgb2YgYWN0dWFsIGFuZCBmb3JtYWwKLSAgICogcGFyYW1ldGVycyBkaWZmZXIsIG9yIGlmIGFuIHVud3JhcHBpbmcKLSAgICogY29udmVyc2lvbiBmYWlscy4KLSAgICogVGhyb3dzOiBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCi0gICAqIGlmIHRoZSB1bmRlcmx5aW5nIG1ldGhvZCB0aHJvd3MgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKiBUaHJvd3M6IE51bGxQb2ludGVyRXhjZXB0aW9uCi0gICAqIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIG51bGwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoKLSAgICogQHBhcmFtIGFyZ3MKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBpbnZva2UoT2JqZWN0IG9iaiwgT2JqZWN0IGFyZ3NbXSkKLSAgICAgICAgICB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZXAgIT0gbnVsbCkKLSAgICAgIHJldHVybiAoKGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCkgcmVhbGVwKS5pbnZva2Uob2JqLCBhcmdzKTsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbigKLSAgICAgICAgIlVuLXJlaWZpZWQgb3JnLmFwYWNoZS54bWwudXRpbHMuc3ludGhldGljLkNsYXNzIGRvZXNuJ3QgeWV0IHN1cHBvcnQgaW52b2NhdGlvbiIpOwotICB9Ci0KLSAgLyoqCi0gICAqIE1ldGhvZCBzZXRSZXR1cm5UeXBlIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gcmV0dXJudHlwZQotICAgKgotICAgKiBAdGhyb3dzIFN5bnRoZXNpc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmV0dXJuVHlwZShvcmcuYXBhY2hlLnhtbC51dGlscy5zeW50aGV0aWMuQ2xhc3MgcmV0dXJudHlwZSkKLSAgICAgICAgICB0aHJvd3MgU3ludGhlc2lzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChyZWFsZXAgIT0gbnVsbCkKLSAgICAgIHRocm93IG5ldyBTeW50aGVzaXNFeGNlcHRpb24oU3ludGhlc2lzRXhjZXB0aW9uLlJFSUZJRUQpOwotCi0gICAgdGhpcy5yZXR1cm50eXBlID0gcmV0dXJudHlwZTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvQXJnLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9BcmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTE4MTg0YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9BcmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gKiBUaGlzIGNsYXNzIGhvbGRzIGFuIGluc3RhbmNlIG9mIGFuIGFyZ3VtZW50IG9uCi0gKiB0aGUgc3RhY2suIFRoZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnQgY2FuIGJlIGVpdGhlciBhbgotICogWE9iamVjdCBvciBhIFN0cmluZyBjb250YWluaW5nIGFuIGV4cHJlc3Npb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBBcmcKLXsKLQotICAvKiogRmllbGQgbV9xbmFtZTogVGhlIG5hbWUgb2YgdGhpcyBhcmd1bWVudCwgZXhwcmVzc2VkIGFzIGEgUU5hbWUKLSAgICogKFF1YWxpZmllZCBOYW1lKSBvYmplY3QuCi0gICAqIEBzZWUgZ2V0UU5hbWUKLSAgICogQHNlZSBzZXRRTmFtZQotICAgKiAgKi8KLSAgcHJpdmF0ZSBRTmFtZSBtX3FuYW1lOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHF1YWxpZmllZCBuYW1lIGZvciB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFFOYW1lIG9iamVjdCBjb250YWluaW5nIHRoZSBxdWFsaWZpZWQgbmFtZQotICAgKi8KLSAgcHVibGljIGZpbmFsIFFOYW1lIGdldFFOYW1lKCkKLSAgewotICAgIHJldHVybiBtX3FuYW1lOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcXVhbGlmaWVkIG5hbWUgZm9yIHRoaXMgYXJndW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIFFOYW1lIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIG5ldyBRdWFsaWZpZWQgTmFtZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFFOYW1lKFFOYW1lIG5hbWUpCi0gIHsKLSAgICBtX3FuYW1lID0gbmFtZTsKLSAgfQotCi0gIC8qKiBGaWVsZCBtX3ZhbDogU3RvcmVkIFhPYmplY3QgdmFsdWUgb2YgdGhpcyBhcmd1bWVudAotICAgKiBAc2VlICNnZXRWYWwoKQotICAgKiBAc2VlICNzZXRWYWwoKQotICAgKi8KLSAgcHJpdmF0ZSBYT2JqZWN0IG1fdmFsOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBhcmd1bWVudCdzIHN0b3JlZCBYT2JqZWN0IHZhbHVlLgotICAgKiBAc2VlICNzZXRWYWwoWE9iamVjdCkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBYT2JqZWN0IGdldFZhbCgpCi0gIHsKLSAgICByZXR1cm4gbV92YWw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB2YWx1ZSBvZiB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcGFyYW0gdmFsIGFuIFhPYmplY3QgcmVwcmVzZW50aW5nIHRoZSBhcmd1bWVudHMncyB2YWx1ZS4KLSAgICogQHNlZSAjZ2V0VmFsKCkKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldFZhbChYT2JqZWN0IHZhbCkKLSAgewotICAgIG1fdmFsID0gdmFsOwotICB9Ci0gIAotICAvKioKLSAgICogSGF2ZSB0aGUgb2JqZWN0IHJlbGVhc2UgaXQncyByZXNvdXJjZXMuCi0gICAqIENhbGwgb25seSB3aGVuIHRoZSB2YXJpYWJsZSBvciBhcmd1bWVudCBpcyBnb2luZyBvdXQgb2Ygc2NvcGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKQotICB7Ci0gICAgaWYobnVsbCAhPSBtX3ZhbCkKLSAgICB7Ci0gICAgICBtX3ZhbC5hbGxvd0RldGFjaFRvUmVsZWFzZSh0cnVlKTsKLSAgICAgIG1fdmFsLmRldGFjaCgpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqIEZpZWxkIG1fZXhwcmVzc2lvbjogU3RvcmVkIGV4cHJlc3Npb24gdmFsdWUgb2YgdGhpcyBhcmd1bWVudC4KLSAgICogQHNlZSAjc2V0RXhwcmVzc2lvbgotICAgKiBAc2VlICNnZXRFeHByZXNzaW9uCi0gICAqICovCi0gIHByaXZhdGUgU3RyaW5nIG1fZXhwcmVzc2lvbjsKLQotICAvKioKLSAgICogR2V0IHRoZSB2YWx1ZSBleHByZXNzaW9uIGZvciB0aGlzIGFyZ3VtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBleHByZXNzaW9uIHByZXZpb3VzbHkgc3RvcmVkIGludG8gdGhpcwotICAgKiBhcmd1bWVudAotICAgKiBAc2VlICNzZXRFeHByZXNzaW9uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEV4cHJlc3Npb24oKQotICB7Ci0gICAgcmV0dXJuIG1fZXhwcmVzc2lvbjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIHZhbHVlIGV4cHJlc3Npb24gZm9yIHRoaXMgYXJndW1lbnQuCi0gICAqCi0gICAqIEBwYXJhbSBleHByIFN0cmluZyBjb250YWluaW5nIHRoZSBleHByZXNzaW9uIHRvIGJlIHN0b3JlZCBhcyB0aGlzCi0gICAqIGFyZ3VtZW50J3MgdmFsdWUuCi0gICAqIEBzZWUgI2dldEV4cHJlc3Npb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEV4cHJlc3Npb24oU3RyaW5nIGV4cHIpCi0gIHsKLSAgICBtX2V4cHJlc3Npb24gPSBleHByOwotICB9Ci0KLSAgLyoqIAotICAgKiBUcnVlIGlmIHRoaXMgdmFyaWFibGUgd2FzIGFkZGVkIHdpdGggYW4geHNsOndpdGgtcGFyYW0gb3IKLSAgICogaXMgYWRkZWQgdmlhIHNldFBhcmFtZXRlci4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzRnJvbVdpdGhQYXJhbTsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIHZhcmlhYmxlIGlzIGEgcGFyYW1ldGVyIHBhc3NlZCB3aXRoIGEgd2l0aC1wYXJhbSBvciBhcyAKLSAgICogYSB0b3AtbGV2ZWwgcGFyYW1ldGVyLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGlzRnJvbVdpdGhQYXJhbSgpCi0gICB7Ci0gICAgcmV0dXJuIG1faXNGcm9tV2l0aFBhcmFtOwotICAgfQotCi0gIC8qKiAKLSAgICogVHJ1ZSBpZiB0aGlzIHZhcmlhYmxlIGlzIGN1cnJlbnRseSB2aXNpYmxlLiAgVG8gYmUgdmlzaWJsZSwKLSAgICogYSB2YXJpYWJsZSBuZWVkcyB0byBjb21lIGVpdGhlciBmcm9tIHhzbDp2YXJpYWJsZSBvciBiZSAKLSAgICogYSAicmVjZWl2ZWQiIHBhcmFtZXRlciwgaWUgb25lIGZvciB3aGljaCBhbiB4c2w6cGFyYW0gaGFzCi0gICAqIGJlZW4gZW5jb3VudGVyZWQuCi0gICAqIFNldCBhdCB0aGUgdGltZSB0aGUgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGFuZCB1cGRhdGVkIGFzIG5lZWRlZC4KLSAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2lzVmlzaWJsZTsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIHZhcmlhYmxlIGlzIGN1cnJlbnRseSB2aXNpYmxlLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGlzVmlzaWJsZSgpCi0gICB7Ci0gICAgcmV0dXJuIG1faXNWaXNpYmxlOwotICAgfQotICAgCi0gIC8qKgotICAgKiBVcGRhdGUgdmlzaWJpbGl0eSBzdGF0dXMgb2YgdGhpcyB2YXJpYWJsZS4KLSAgICovCi0gICBwdWJsaWMgdm9pZCBzZXRJc1Zpc2libGUoYm9vbGVhbiBiKQotICAgewotICAgIG1faXNWaXNpYmxlID0gYjsKLSAgIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgZHVtbXkgcGFyYW1ldGVyIGFyZ3VtZW50LCB3aXRoIG5vIFFOYW1lIGFuZCBubwotICAgKiB2YWx1ZSAoZWl0aGVyIGV4cHJlc3Npb24gc3RyaW5nIG9yIHZhbHVlIFhPYmplY3QpLiBpc1Zpc2libGUKLSAgICogZGVmYXVsdHMgdG8gdHJ1ZS4KLSAgICovCi0gIHB1YmxpYyBBcmcoKQotICB7Ci0KLSAgICBtX3FuYW1lID0gbmV3IFFOYW1lKCIiKTsKLSAgICA7ICAvLyBzbyB0aGF0IHN0cmluZyBjb21wYXJlcyBjYW4gYmUgZG9uZS4KLSAgICBtX3ZhbCA9IG51bGw7Ci0gICAgbV9leHByZXNzaW9uID0gbnVsbDsKLSAgICBtX2lzVmlzaWJsZSA9IHRydWU7Ci0gICAgbV9pc0Zyb21XaXRoUGFyYW0gPSBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBwYXJhbWV0ZXIgYXJndW1lbnQgdGhhdCBjb250YWlucyBhbiBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgTmFtZSBvZiB0aGUgYXJndW1lbnQsIGV4cHJlc3NlZCBhcyBhIFFOYW1lIG9iamVjdC4KLSAgICogQHBhcmFtIGV4cHJlc3Npb24gU3RyaW5nIHRvIGJlIHN0b3JlZCBhcyB0aGlzIGFyZ3VtZW50J3MgdmFsdWUgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIGlzRnJvbVdpdGhQYXJhbSBUcnVlIGlmIHRoaXMgaXMgYSBwYXJhbWV0ZXIgdmFyaWFibGUuCi0gICAqLwotICBwdWJsaWMgQXJnKFFOYW1lIHFuYW1lLCBTdHJpbmcgZXhwcmVzc2lvbiwgYm9vbGVhbiBpc0Zyb21XaXRoUGFyYW0pCi0gIHsKLQotICAgIG1fcW5hbWUgPSBxbmFtZTsKLSAgICBtX3ZhbCA9IG51bGw7Ci0gICAgbV9leHByZXNzaW9uID0gZXhwcmVzc2lvbjsKLSAgICBtX2lzRnJvbVdpdGhQYXJhbSA9IGlzRnJvbVdpdGhQYXJhbTsKLSAgICBtX2lzVmlzaWJsZSA9ICFpc0Zyb21XaXRoUGFyYW07Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgcGFyYW1ldGVyIGFyZ3VtZW50IHdoaWNoIGhhcyBhbiBYT2JqZWN0IHZhbHVlLgotICAgKiBpc1Zpc2libGUgZGVmYXVsdHMgdG8gdHJ1ZS4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIE5hbWUgb2YgdGhlIGFyZ3VtZW50LCBleHByZXNzZWQgYXMgYSBRTmFtZSBvYmplY3QuCi0gICAqIEBwYXJhbSB2YWwgVmFsdWUgb2YgdGhlIGFyZ3VtZW50LCBleHByZXNzZWQgYXMgYW4gWE9iamVjdAotICAgKi8KLSAgcHVibGljIEFyZyhRTmFtZSBxbmFtZSwgWE9iamVjdCB2YWwpCi0gIHsKLQotICAgIG1fcW5hbWUgPSBxbmFtZTsKLSAgICBtX3ZhbCA9IHZhbDsKLSAgICBtX2lzVmlzaWJsZSA9IHRydWU7Ci0gICAgbV9pc0Zyb21XaXRoUGFyYW0gPSBmYWxzZTsKLSAgICBtX2V4cHJlc3Npb24gPSBudWxsOwotICB9Ci0gIAotICAvKioKLSAgICogRXF1YWxpdHkgZnVuY3Rpb24gc3BlY2lhbGl6ZWQgZm9yIHRoZSB2YXJpYWJsZSBuYW1lLiAgSWYgdGhlIGFyZ3VtZW50IAotICAgKiBpcyBub3QgYSBxbmFtZSwgaXQgd2lsbCBkZWxpZ2F0ZSB0byB0aGUgc3VwZXIgY2xhc3MuCi0gICAqIAotICAgKiBAcGFyYW0gICBvYmogICB0aGUgcmVmZXJlbmNlIG9iamVjdCB3aXRoIHdoaWNoIHRvIGNvbXBhcmUuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgb2JqZWN0IGlzIHRoZSBzYW1lIGFzIHRoZSBvYmoKLSAgICogICAgICAgICAgYXJndW1lbnQ7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgCi0gIHsKLSAgICBpZihvYmogaW5zdGFuY2VvZiBRTmFtZSkKLSAgICB7Ci0gICAgICByZXR1cm4gbV9xbmFtZS5lcXVhbHMob2JqKTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIHBhcmFtZXRlciBhcmd1bWVudC4KLSAgICoKLSAgICogQHBhcmFtIHFuYW1lIE5hbWUgb2YgdGhlIGFyZ3VtZW50LCBleHByZXNzZWQgYXMgYSBRTmFtZSBvYmplY3QuCi0gICAqIEBwYXJhbSB2YWwgVmFsdWUgb2YgdGhlIGFyZ3VtZW50LCBleHByZXNzZWQgYXMgYW4gWE9iamVjdAotICAgKiBAcGFyYW0gaXNGcm9tV2l0aFBhcmFtIFRydWUgaWYgdGhpcyBpcyBhIHBhcmFtZXRlciB2YXJpYWJsZS4KLSAgICovCi0gIHB1YmxpYyBBcmcoUU5hbWUgcW5hbWUsIFhPYmplY3QgdmFsLCBib29sZWFuIGlzRnJvbVdpdGhQYXJhbSkKLSAgewotCi0gICAgbV9xbmFtZSA9IHFuYW1lOwotICAgIG1fdmFsID0gdmFsOwotICAgIG1faXNGcm9tV2l0aFBhcmFtID0gaXNGcm9tV2l0aFBhcmFtOwotICAgIG1faXNWaXNpYmxlID0gIWlzRnJvbVdpdGhQYXJhbTsKLSAgICBtX2V4cHJlc3Npb24gPSBudWxsOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9ET00ySGVscGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9ET00ySGVscGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI5YmQwNDYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvRE9NMkhlbHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzU2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGg7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5ET01IZWxwZXI7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKLWltcG9ydCBvcmcudzNjLmRvbS5BdHRyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LlBhcnNlcjsKLQotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLio7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIEBkZXByZWNhdGVkIFNpbmNlIHRoZSBpbnRyb2R1Y3Rpb24gb2YgdGhlIERUTSwgdGhpcyBjbGFzcyB3aWxsIGJlIHJlbW92ZWQuCi0gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgRE9NIGxldmVsIDIgImhlbHBlciIsIHdoaWNoIHByb3ZpZGVzIHNlcnZpY2VzIGN1cnJlbnRseSAKLSAqIG5vdCBwcm92aWRlZCBiZSB0aGUgRE9NIHN0YW5kYXJkLgotICovCi1wdWJsaWMgY2xhc3MgRE9NMkhlbHBlciBleHRlbmRzIERPTUhlbHBlcgotewotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gaW5zdGFuY2UuCi0gICAqLwotICBwdWJsaWMgRE9NMkhlbHBlcigpe30KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIENoZWNrIG5vZGUgdG8gc2VlIGlmIGl0IHdhcyBjcmVhdGVkIGJ5IGEgRE9NIGltcGxlbWVudGF0aW9uCi0gICAqIHRoYXQgdGhpcyBoZWxwZXIgaXMgaW50ZW5kZWQgdG8gc3VwcG9ydC4gVGhpcyBpcyBjdXJyZW50bHkKLSAgICogZGlzYWJsZWQsIGFuZCBhc3N1bWVzIGFsbCBub2RlcyBhcmUgYWNjZXB0YWJsZSByYXRoZXIgdGhhbiBjaGVja2luZwotICAgKiB0aGF0IHRoZXkgaW1wbGVtZW50IG9yZy5hcGFjaGUueGVyY2VzLmRvbS5Ob2RlSW1wbC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBub2RlIGlzIG5vdCBvbmUgd2hpY2ggdGhpcwotICAgKiBET00ySGVscGVyIGNhbiBzdXBwb3J0LiBJZiB3ZSByZXR1cm4gd2l0aG91dCB0aHJvd2luZyB0aGUgZXhjZXB0aW9uLAotICAgKiB0aGUgbm9kZSBpcyBjb21wYXRhYmxlLgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOb2RlKE5vZGUgbm9kZSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIGlmKCEobm9kZSBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueGVyY2VzLmRvbS5Ob2RlSW1wbCkpCi0gICAgLy8gIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUywgbmV3IE9iamVjdFtdeygoT2JqZWN0KW5vZGUpLmdldENsYXNzKCl9KSk7IC8vIkRPTTJIZWxwZXIgY2FuIG5vdCBoYW5kbGUgbm9kZXMgb2YgdHlwZSIKLSAgICAvLysoKE9iamVjdClub2RlKS5nZXRDbGFzcygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIERPTSBpbXBsZW1lbnRhdGlvbiBoYW5kbGVkIGJ5IHRoaXMgaGVscGVyCi0gICAqIHN1cHBvcnRzIHRoZSBTQVggQ29udGVudEhhbmRsZXIgaW50ZXJmYWNlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgKHNpbmNlIFhlcmNlcyBkb2VzKS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzU0FYKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqIEZpZWxkIG1fZG9jOiBEb2N1bWVudCBOb2RlIGZvciB0aGUgZG9jdW1lbnQgdGhpcyBoZWxwZXIgaXMgY3VycmVudGx5Ci0gICAqIGFjY2Vzc2luZyBvciBidWlsZGluZwotICAgKiBAc2VlICNzZXREb2N1bWVudAotICAgKiBAc2VlICNnZXREb2N1bWVudAotICAgKiAgKi8KLSAgcHJpdmF0ZSBEb2N1bWVudCBtX2RvYzsKLQotICAvKioKLSAgICogU3BlY2lmeSB3aGljaCBkb2N1bWVudCB0aGlzIGhlbHBlciBpcyBjdXJyZW50bHkgb3BlcmF0aW5nIG9uLgotICAgKiAJCi0gICAqIEBwYXJhbSBkb2MgVGhlIERPTSBEb2N1bWVudCBub2RlIGZvciB0aGlzIGRvY3VtZW50LgotICAgKiBAc2VlICNnZXREb2N1bWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnQoRG9jdW1lbnQgZG9jKQotICB7Ci0gICAgbV9kb2MgPSBkb2M7Ci0gIH0KLQotICAvKioKLSAgICogUXVlcnkgd2hpY2ggZG9jdW1lbnQgdGhpcyBoZWxwZXIgaXMgY3VycmVudGx5IG9wZXJhdGluZyBvbi4KLSAgICogCQotICAgKiBAcmV0dXJuIFRoZSBET00gRG9jdW1lbnQgbm9kZSBmb3IgdGhpcyBkb2N1bWVudC4KLSAgICogQHNlZSAjc2V0RG9jdW1lbnQKLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBnZXREb2N1bWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9kb2M7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFBhcnNlIGFuIFhNTCBkb2N1bWVudC4KLSAgICoKLSAgICogPHA+UmlnaHQgbm93IHRoZSBYZXJjZXMgRE9NUGFyc2VyIGNsYXNzIGlzIHVzZWQuICBUaGlzIG5lZWRzCi0gICAqIGZpeGluZywgZWl0aGVyIHZpYSBqYXhwLCBvciB2aWEgc29tZSBvdGhlciwgc3RhbmRhcmQgbWV0aG9kLjwvcD4KLSAgICoKLSAgICogPHA+VGhlIGFwcGxpY2F0aW9uIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gaW5zdHJ1Y3QgdGhlIFNBWCBwYXJzZXIKLSAgICogdG8gYmVnaW4gcGFyc2luZyBhbiBYTUwgZG9jdW1lbnQgZnJvbSBhbnkgdmFsaWQgaW5wdXQKLSAgICogc291cmNlIChhIGNoYXJhY3RlciBzdHJlYW0sIGEgYnl0ZSBzdHJlYW0sIG9yIGEgVVJJKS48L3A+Ci0gICAqCi0gICAqIDxwPkFwcGxpY2F0aW9ucyBtYXkgbm90IGludm9rZSB0aGlzIG1ldGhvZCB3aGlsZSBhIHBhcnNlIGlzIGluCi0gICAqIHByb2dyZXNzICh0aGV5IHNob3VsZCBjcmVhdGUgYSBuZXcgUGFyc2VyIGluc3RlYWQgZm9yIGVhY2gKLSAgICogYWRkaXRpb25hbCBYTUwgZG9jdW1lbnQpLiAgT25jZSBhIHBhcnNlIGlzIGNvbXBsZXRlLCBhbgotICAgKiBhcHBsaWNhdGlvbiBtYXkgcmV1c2UgdGhlIHNhbWUgUGFyc2VyIG9iamVjdCwgcG9zc2libHkgd2l0aCBhCi0gICAqIGRpZmZlcmVudCBpbnB1dCBzb3VyY2UuPC9wPgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzb3VyY2UgZm9yIHRoZSB0b3AtbGV2ZWwgb2YgdGhlCi0gICAqICAgICAgICBYTUwgZG9jdW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYW55IGNoZWNrZWQgZXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHBhcnNlKElucHV0U291cmNlIHNvdXJjZSkgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsKLQotICAgICAgLy8gSSBndWVzcyBJIHNob3VsZCB1c2UgSkFYUCBmYWN0b3J5IGhlcmUuLi4gd2hlbiBpdCdzIGxlZ2FsLgotICAgICAgLy8gb3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5ET01QYXJzZXIgcGFyc2VyIAotICAgICAgLy8gID0gbmV3IG9yZy5hcGFjaGUueGVyY2VzLnBhcnNlcnMuRE9NUGFyc2VyKCk7Ci0gICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGJ1aWxkZXJGYWN0b3J5ID0KLSAgICAgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICBidWlsZGVyRmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgIGJ1aWxkZXJGYWN0b3J5LnNldFZhbGlkYXRpbmcodHJ1ZSk7Ci0KLSAgICAgIERvY3VtZW50QnVpbGRlciBwYXJzZXIgPSBidWlsZGVyRmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKLQotICAgICAgLyoKLSAgICAgIC8vIGRvbVBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvZG9tL2NyZWF0ZS1lbnRpdHktcmVmLW5vZGVzIiwgZ2V0U2hvdWxkRXhwYW5kRW50aXR5UmVmcygpPyBmYWxzZSA6IHRydWUpOwotICAgICAgaWYobV91c2VET00yZ2V0TmFtZXNwYWNlVVJJKQotICAgICAgewotICAgICAgcGFyc2VyLnNldEZlYXR1cmUoImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9kb20vZGVmZXItbm9kZS1leHBhbnNpb24iLCB0cnVlKTsKLSAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8veG1sLm9yZy9zYXgvZmVhdHVyZXMvbmFtZXNwYWNlcyIsIHRydWUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgcGFyc2VyLnNldEZlYXR1cmUoImh0dHA6Ly9hcGFjaGUub3JnL3htbC9mZWF0dXJlcy9kb20vZGVmZXItbm9kZS1leHBhbnNpb24iLCBmYWxzZSk7Ci0gICAgICB9Ci0KLSAgICAgIHBhcnNlci5zZXRGZWF0dXJlKCJodHRwOi8vYXBhY2hlLm9yZy94bWwvZmVhdHVyZXMvYWxsb3ctamF2YS1lbmNvZGluZ3MiLCB0cnVlKTsKLSAgICAgICovCi0KLSAgICAgIHBhcnNlci5zZXRFcnJvckhhbmRsZXIoCi0gICAgICAgIG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyKCkpOwotCi0gICAgICAvLyBpZihudWxsICE9IG1fZW50aXR5UmVzb2x2ZXIpCi0gICAgICAvLyB7Ci0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIlNldHRpbmcgdGhlIGVudGl0eSByZXNvbHZlci4iKTsKLSAgICAgIC8vICBwYXJzZXIuc2V0RW50aXR5UmVzb2x2ZXIobV9lbnRpdHlSZXNvbHZlcik7Ci0gICAgICAvLyB9Ci0gICAgICBzZXREb2N1bWVudChwYXJzZXIucGFyc2Uoc291cmNlKSk7Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihwY2UpOwotICAgIH0KLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihpb2UpOwotICAgIH0KLQotICAgIC8vIHNldERvY3VtZW50KCgob3JnLmFwYWNoZS54ZXJjZXMucGFyc2Vycy5ET01QYXJzZXIpcGFyc2VyKS5nZXREb2N1bWVudCgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhbiBYTUwgSUQsIHJldHVybiB0aGUgZWxlbWVudC4gVGhpcyByZXF1aXJlcyBhc3Npc3RhbmNlIGZyb20gdGhlCi0gICAqIERPTSBhbmQgcGFyc2VyLCBhbmQgaXMgbWVhbmluZ2Z1bCBvbmx5IGluIHRoZSBjb250ZXh0IG9mIGEgRFREIAotICAgKiBvciBzY2hlbWEgd2hpY2ggZGVjbGFyZXMgYXR0cmlidXRlcyBhcyBiZWluZyBvZiB0eXBlIElELiBUaGlzCi0gICAqIGluZm9ybWF0aW9uIG1heSBvciBtYXkgbm90IGJlIGF2YWlsYWJsZSBpbiBhbGwgcGFyc2VycywgbWF5IG9yCi0gICAqIG1heSBub3QgYmUgYXZhaWxhYmxlIGZvciBzcGVjaWZpYyBkb2N1bWVudHMsIGFuZCBtYXkgb3IgbWF5IG5vdAotICAgKiBiZSBhdmFpbGFibGUgd2hlbiB2YWxpZGF0aW9uIGlzIG5vdCB0dXJuZWQgb24uCi0gICAqCi0gICAqIEBwYXJhbSBpZCBUaGUgSUQgdG8gc2VhcmNoIGZvciwgYXMgYSBTdHJpbmcuCi0gICAqIEBwYXJhbSBkb2MgVGhlIGRvY3VtZW50IHRvIHNlYXJjaCB3aXRoaW4sIGFzIGEgRE9NIERvY3VtZW50IG5vZGUuCi0gICAqIEByZXR1cm4gRE9NIEVsZW1lbnQgbm9kZSB3aXRoIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIElEIHdob3NlIHZhbHVlCi0gICAqIHVuaXF1ZWx5IG1hdGNoZXMgdGhlIHJlcXVlc3RlZCBpZCBzdHJpbmcsIG9yIG51bGwgaWYgdGhlcmUgaXNuJ3QKLSAgICogc3VjaCBhbiBlbGVtZW50IG9yIGlmIHRoZSBET00gY2FuJ3QgYW5zd2VyIHRoZSBxdWVzdGlvbiBmb3Igb3RoZXIKLSAgICogcmVhc29ucy4KLSAgICovCi0gIHB1YmxpYyBFbGVtZW50IGdldEVsZW1lbnRCeUlEKFN0cmluZyBpZCwgRG9jdW1lbnQgZG9jKQotICB7Ci0gICAgcmV0dXJuIGRvYy5nZXRFbGVtZW50QnlJZChpZCk7Ci0gIH0KLQotICAvKioKLSAgICogRmlndXJlIG91dCB3aGV0aGVyIG5vZGUyIHNob3VsZCBiZSBjb25zaWRlcmVkIGFzIGJlaW5nIGxhdGVyCi0gICAqIGluIHRoZSBkb2N1bWVudCB0aGFuIG5vZGUxLCBpbiBEb2N1bWVudCBPcmRlciBhcyBkZWZpbmVkCi0gICAqIGJ5IHRoZSBYUGF0aCBtb2RlbC4gVGhpcyBtYXkgbm90IGFncmVlIHdpdGggdGhlIG9yZGVyaW5nIGRlZmluZWQKLSAgICogYnkgb3RoZXIgWE1MIGFwcGxpY2F0aW9ucy4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGFyZSBzb21lIGNhc2VzIHdoZXJlIG9yZGVyaW5nIGlzbid0IGRlZmluZWQsIGFuZCBuZWl0aGVyIGFyZQotICAgKiB0aGUgcmVzdWx0cyBvZiB0aGlzIGZ1bmN0aW9uIC0tIHRob3VnaCB3ZSdsbCBnZW5lcmFsbHkgcmV0dXJuIHRydWUuCi0gICAqIDxwPgotICAgKiBUT0RPOiBNYWtlIHN1cmUgdGhpcyBkb2VzIHRoZSByaWdodCB0aGluZyB3aXRoIGF0dHJpYnV0ZSBub2RlcyEhIQotICAgKgotICAgKiBAcGFyYW0gbm9kZTEgRE9NIE5vZGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uLgotICAgKiBAcGFyYW0gbm9kZTIgRE9NIE5vZGUgdG8gcGVyZm9ybSBwb3NpdGlvbiBjb21wYXJpc29uIG9uIC4KLSAgICogCi0gICAqIEByZXR1cm4gZmFsc2UgaWYgbm9kZTIgY29tZXMgYmVmb3JlIG5vZGUxLCBvdGhlcndpc2UgcmV0dXJuIHRydWUuCi0gICAqIFlvdSBjYW4gdGhpbmsgb2YgdGhpcyBhcyAKLSAgICogPGNvZGU+KG5vZGUxLmRvY3VtZW50T3JkZXJQb3NpdGlvbiAmbHQ7PSBub2RlMi5kb2N1bWVudE9yZGVyUG9zaXRpb24pPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc05vZGVBZnRlcihOb2RlIG5vZGUxLCBOb2RlIG5vZGUyKQotICB7Ci0KLSAgICAvLyBBc3N1bWUgZmlyc3QgdGhhdCB0aGUgbm9kZXMgYXJlIERUTSBub2Rlcywgc2luY2UgZGlzY292ZXJpbmcgbm9kZSAKLSAgICAvLyBvcmRlciBpcyBtYXNzaXZseSBmYXN0ZXIgZm9yIHRoZSBEVE0uCi0gICAgaWYobm9kZTEgaW5zdGFuY2VvZiBET01PcmRlciAmJiBub2RlMiBpbnN0YW5jZW9mIERPTU9yZGVyKQotICAgIHsKLSAgICAgIGludCBpbmRleDEgPSAoKERPTU9yZGVyKSBub2RlMSkuZ2V0VWlkKCk7Ci0gICAgICBpbnQgaW5kZXgyID0gKChET01PcmRlcikgbm9kZTIpLmdldFVpZCgpOwotCi0gICAgICByZXR1cm4gaW5kZXgxIDw9IGluZGV4MjsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gaXNOb2RlQWZ0ZXIgd2lsbCByZXR1cm4gdHJ1ZSBpZiBub2RlIGlzIGFmdGVyIGNvdW50ZWROb2RlIAotICAgICAgLy8gaW4gZG9jdW1lbnQgb3JkZXIuIFRoZSBiYXNlIGlzTm9kZUFmdGVyIGlzIHNsb29vb3cgKHJlbGF0aXZlbHkpLgotICAgICAgcmV0dXJuIERPTUhlbHBlci5pc05vZGVBZnRlcihub2RlMSwgbm9kZTIpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhQYXRoLW1vZGVsIHBhcmVudCBvZiBhIG5vZGUuICBUaGlzIHZlcnNpb24gdGFrZXMgYWR2YW50YWdlCi0gICAqIG9mIHRoZSBET00gTGV2ZWwgMiBBdHRyLm93bmVyRWxlbWVudCgpIG1ldGhvZDsgdGhlIGJhc2UgdmVyc2lvbiB3ZQotICAgKiB3b3VsZCBvdGhlcndpc2UgaW5oZXJpdCBpcyBwcmVwYXJlZCB0byBmYWxsIGJhY2sgb24gZXhoYXVzdGl2ZWx5Ci0gICAqIHdhbGtpbmcgdGhlIGRvY3VtZW50IHRvIGZpbmQgYW4gQXR0cidzIHBhcmVudC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIHRoZSBET00gcGFyZW50IG9mIHRoZSBpbnB1dCBub2RlLCBpZiB0aGVyZSBpcyBvbmUsIG9yIHRoZQotICAgKiBvd25lckVsZW1lbnQgaWYgdGhlIGlucHV0IG5vZGUgaXMgYW4gQXR0ciwgb3IgbnVsbCBpZiB0aGUgbm9kZSBpcwotICAgKiBhIERvY3VtZW50LCBhIERvY3VtZW50RnJhZ21lbnQsIG9yIGFuIG9ycGhhbi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBnZXRQYXJlbnRPZk5vZGUoTm9kZSBub2RlKQotICB7Ci0gICAgICAgICAgTm9kZSBwYXJlbnQ9bm9kZS5nZXRQYXJlbnROb2RlKCk7Ci0gICAgICAgICAgaWYocGFyZW50PT1udWxsICYmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IG5vZGUuZ2V0Tm9kZVR5cGUoKSkgKQotICAgICAgICAgICBwYXJlbnQ9KChBdHRyKSBub2RlKS5nZXRPd25lckVsZW1lbnQoKTsKLSAgICAgICAgICByZXR1cm4gcGFyZW50OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGdpdmVuIG5vZGUsIGFzIGRlZmluZWQgYnkgdGhlCi0gICAqIFhNTCBOYW1lc3BhY2VzIHNwZWNpZmljYXRpb24uIFRoaXMgaXMgcHJlcGFyZWQgdG8gaGFuZGxlIGRvY3VtZW50cwotICAgKiBidWlsdCB1c2luZyBET00gTGV2ZWwgMSBtZXRob2RzIGJ5IGZhbGxpbmcgYmFjayB1cG9uIGV4cGxpY2l0bHkKLSAgICogcGFyc2luZyB0aGUgbm9kZSBuYW1lLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGV4YW1pbmVkCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGxvY2FsIG5hbWUsIG9yIG51bGwgaWYgdGhlIG5vZGUKLSAgICogd2FzIG5vdCBhc3NpZ25lZCBhIE5hbWVzcGFjZS4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lT2ZOb2RlKE5vZGUgbikKLSAgewotCi0gICAgU3RyaW5nIG5hbWUgPSBuLmdldExvY2FsTmFtZSgpOwotCi0gICAgcmV0dXJuIChudWxsID09IG5hbWUpID8gc3VwZXIuZ2V0TG9jYWxOYW1lT2ZOb2RlKG4pIDogbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBOYW1lc3BhY2UgTmFtZSAoTmFtZXNwYWNlIFVSSSkgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKiBJbiBhIExldmVsIDIgRE9NLCB5b3UgY2FuIGFzayB0aGUgbm9kZSBpdHNlbGYuIE5vdGUsIGhvd2V2ZXIsIHRoYXQKLSAgICogZG9pbmcgc28gY29uZmxpY3RzIHdpdGggb3VyIGRlY2lzaW9uIGluIGdldExvY2FsTmFtZU9mTm9kZSBub3QKLSAgICogdG8gdHJ1c3QgdGhlIHRoYXQgdGhlIERPTSB3YXMgaW5kZWVkIGNyZWF0ZWQgdXNpbmcgdGhlIExldmVsIDIKLSAgICogbWV0aG9kcy4gSWYgTGV2ZWwgMSBtZXRob2RzIHdlcmUgdXNlZCwgdGhlc2UgdHdvIGZ1bmN0aW9ucyB3aWxsCi0gICAqIGRpc2FncmVlIHdpdGggZWFjaCBvdGhlci4KLSAgICogPHA+Ci0gICAqIFRPRE86IFJlY29uY2lsZSB3aXRoIGdldExvY2FsTmFtZU9mTm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBOYW1lc3BhY2UgVVJJIGJvdW5kIHRvIHRoaXMgRE9NIG5vZGUKLSAgICogYXQgdGhlIHRpbWUgdGhlIE5vZGUgd2FzIGNyZWF0ZWQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZU9mTm9kZShOb2RlIG4pCi0gIHsKLSAgICByZXR1cm4gbi5nZXROYW1lc3BhY2VVUkkoKTsKLSAgfQotCi0gIC8qKiBGaWVsZCBtX3VzZURPTTJnZXROYW1lc3BhY2VVUkkgaXMgYSBjb21waWxlLXRpbWUgZmxhZyB3aGljaAotICAgKiAgZ2F0ZXMgc29tZSBvZiB0aGUgcGFyc2VyIG9wdGlvbnMgdXNlZCB0byBidWlsZCBhIERPTSAtLSBidXQgCi0gICAqIHRoYXQgY29kZSBpcyBjb21tZW50ZWQgb3V0IGF0IHRoaXMgdGltZSBhbmQgbm9ib2R5IGVsc2UKLSAgICogcmVmZXJlbmNlcyBpdCwgc28gSSd2ZSBjb21tZW50ZWQgdGhpcyBvdXQgYXMgd2VsbC4gKi8KLSAgLy9wcml2YXRlIGJvb2xlYW4gbV91c2VET00yZ2V0TmFtZXNwYWNlVVJJID0gZmFsc2U7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9ET01IZWxwZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL0RPTUhlbHBlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhZDVlYjI5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL0RPTUhlbHBlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMyNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLnczYy5kb20uKjsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5OU0luZm87Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU3RyaW5nQnVmZmVyUG9vbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8vIEltcG9ydGVkIEpBVkEgQVBJIGZvciBYTUwgUGFyc2luZyAxLjAgY2xhc3NlcwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKLWltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci0KLS8qKgotICogQGRlcHJlY2F0ZWQgU2luY2UgdGhlIGludHJvZHVjdGlvbiBvZiB0aGUgRFRNLCB0aGlzIGNsYXNzIHdpbGwgYmUgcmVtb3ZlZC4KLSAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBmcm9udC1lbmQgdG8gRE9NIGltcGxlbWVudGF0aW9ucywgcHJvdmlkaW5nCi0gKiBhIG51bWJlciBvZiB1dGlsaXR5IGZ1bmN0aW9ucyB0aGF0IGVpdGhlciBhcmVuJ3QgeWV0IHN0YW5kYXJkaXplZAotICogYnkgdGhlIERPTSBzcGVjIG9yIHRoYXQgYXJlIGRlZmluZWQgaW4gb3B0aW9uYWwgRE9NIG1vZHVsZXMgYW5kCi0gKiBoZW5jZSBtYXkgbm90IGJlIHByZXNlbnQgaW4gYWxsIERPTXMuCi0gKi8KLXB1YmxpYyBjbGFzcyBET01IZWxwZXIKLXsKLQotICAvKioKLSAgICogRE9NIExldmVsIDEgZGlkIG5vdCBoYXZlIGEgc3RhbmRhcmQgbWVjaGFuaXNtIGZvciBjcmVhdGluZyBhIG5ldwotICAgKiBEb2N1bWVudCBvYmplY3QuIFRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgYSBET00taW1wbGVtZW50YXRpb24taW5kZXBlbmRlbnQKLSAgICogYWJzdHJhY3Rpb24gZm9yIHRoYXQgZm9yIHRoYXQgY29uY2VwdC4gSXQncyB0eXBpY2FsbHkgdXNlZCB3aGVuIAotICAgKiBvdXRwdXR0aW5nIGEgbmV3IERPTSBhcyB0aGUgcmVzdWx0IG9mIGFuIG9wZXJhdGlvbi4KLSAgICogPHA+Ci0gICAqIFRPRE86IFRoaXMgaXNuJ3QgZGlyZWN0bHkgY29tcGF0YWJsZSB3aXRoIERPTSBMZXZlbCAyLiAKLSAgICogVGhlIExldmVsIDIgY3JlYXRlRG9jdW1lbnQgY2FsbCBhbHNvIGNyZWF0ZXMgdGhlIHJvb3QgCi0gICAqIGVsZW1lbnQsIGFuZCB0aHVzIHJlcXVpcmVzIHRoYXQgeW91IGtub3cgd2hhdCB0aGF0IGVsZW1lbnQgd2lsbCBiZQotICAgKiBiZWZvcmUgY3JlYXRpbmcgdGhlIERvY3VtZW50LiBXZSBzaG91bGQgdGhpbmsgYWJvdXQgd2hldGhlciB3ZSB3YW50Ci0gICAqIHRvIGNoYW5nZSB0aGlzIGNvZGUsIGFuZCB0aGUgY2FsbGVycywgc28gd2UgY2FuIHVzZSB0aGUgRE9NJ3Mgb3duIAotICAgKiBtZXRob2QuIChJdCdzIGFsc28gcG9zc2libGUgdGhhdCBET00gTGV2ZWwgMyBtYXkgcmVsYXggdGhpcwotICAgKiBzZXF1ZW5jZSwgYnV0IHlvdSBtYXkgZ2l2ZSB1cCBzb21lIGludGVsbGlnZW5jZSBpbiB0aGUgRE9NIGJ5Ci0gICAqIGRvaW5nIHNvOyB0aGUgaW50ZW50IHdhcyB0aGF0IGtub3dpbmcgdGhlIGRvY3VtZW50IHR5cGUgYW5kIHJvb3QKLSAgICogZWxlbWVudCBtaWdodCBsZXQgdGhlIERPTSBhdXRvbWF0aWNhbGx5IHN3aXRjaCB0byBhIHNwZWNpYWxpemVkCi0gICAqIHN1YmNsYXNzIGZvciBwYXJ0aWN1bGFyIGtpbmRzIG9mIGRvY3VtZW50cy4pCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgRE9NIERvY3VtZW50IG9iamVjdCwgd2l0aCBubyBjaGlsZHJlbiwgb3IKLSAgICogbnVsbCBpZiB3ZSBjYW4ndCBmaW5kIGEgRE9NIGltcGxlbWVudGF0aW9uIHRoYXQgcGVybWl0cyBjcmVhdGluZwotICAgKiBuZXcgZW1wdHkgRG9jdW1lbnRzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBEb2N1bWVudCBjcmVhdGVEb2N1bWVudCgpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLQotICAgICAgLy8gVXNlIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBKQVZBIEFQSSBmb3IgWE1MIFBhcnNpbmcgMS4wIHRvCi0gICAgICAvLyBjcmVhdGUgYSBET00gRG9jdW1lbnQgbm9kZSB0byBjb250YWluIHRoZSByZXN1bHQuCi0gICAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRmYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotCi0gICAgICBkZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTsKLSAgICAgIGRmYWN0b3J5LnNldFZhbGlkYXRpbmcodHJ1ZSk7Ci0KLSAgICAgIERvY3VtZW50QnVpbGRlciBkb2NCdWlsZGVyID0gZGZhY3RvcnkubmV3RG9jdW1lbnRCdWlsZGVyKCk7Ci0gICAgICBEb2N1bWVudCBvdXROb2RlID0gZG9jQnVpbGRlci5uZXdEb2N1bWVudCgpOwotCi0gICAgICByZXR1cm4gb3V0Tm9kZTsKLSAgICB9Ci0gICAgY2F0Y2ggKFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24gcGNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVELCBudWxsKSk7ICAvLyJjcmVhdGVEb2N1bWVudCgpIG5vdCBzdXBwb3J0ZWQgaW4gWFBhdGhDb250ZXh0ISIpOwotCi0gICAgICAvLyByZXR1cm4gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRlbGxzLCB0aHJvdWdoIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgZGVmYXVsdC1zcGFjZSBhdHRyaWJ1dGUKLSAgICogb24geHNsOnN0eWxlc2hlZXQsIHhzbDpzdHJpcC1zcGFjZSwgeHNsOnByZXNlcnZlLXNwYWNlLCBhbmQgdGhlCi0gICAqIHhtbDpzcGFjZSBhdHRyaWJ1dGUsIHdoZXRoZXIgb3Igbm90IGV4dHJhIHdoaXRlc3BhY2Ugc2hvdWxkIGJlIHN0cmlwcGVkCi0gICAqIGZyb20gdGhlIG5vZGUuICBMaXRlcmFsIGVsZW1lbnRzIGZyb20gdGVtcGxhdGUgZWxlbWVudHMgc2hvdWxkCi0gICAqIDxlbT5ub3Q8L2VtPiBiZSB0ZXN0ZWQgd2l0aCB0aGlzIGZ1bmN0aW9uLgotICAgKiBAcGFyYW0gdGV4dE5vZGUgQSB0ZXh0IG5vZGUgZnJvbSB0aGUgc291cmNlIHRyZWUuCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdGV4dCBub2RlIHNob3VsZCBiZSBzdHJpcHBlZCBvZiBleHRyYSB3aGl0ZXNwYWNlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHNob3VsZFN0cmlwU291cmNlTm9kZShOb2RlIHRleHROb2RlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIHJldHVybiAobnVsbCA9PSBtX2VudlN1cHBvcnQpID8gZmFsc2UgOiBtX2VudlN1cHBvcnQuc2hvdWxkU3RyaXBTb3VyY2VOb2RlKHRleHROb2RlKTsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU3VwcG9ydHMgdGhlIFhQYXRoIGZ1bmN0aW9uIEdlbmVyYXRlSUQgYnkgcmV0dXJuaW5nIGEgdW5pcXVlCi0gICAqIGlkZW50aWZpZXIgc3RyaW5nIGZvciBhbnkgZ2l2ZW4gRE9NIE5vZGUuCi0gICAqIDxwPgotICAgKiBXYXJuaW5nOiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSBOb2RlIG9iamVjdCdzIGhhc2hDb2RlKCksCi0gICAqIHdoaWNoIGlzIE5PVCBndWFyYW50ZWVkIHRvIGJlIHVuaXF1ZS4gSWYgdGhhdCBtZXRob2QgaGFzbid0IGJlZW4KLSAgICogb3ZlcnJpZGRlbiBpbiB0aGlzIERPTSBpcG1sZW1lbnRhdGlvbiwgbW9zdCBKYXZhIGltcGxlbWVudGlvbnMgd2lsbAotICAgKiBkZXJpdmUgaXQgZnJvbSB0aGUgb2JqZWN0J3MgYWRkcmVzcyBhbmQgc2hvdWxkIGJlIE9LLi4uIGJ1dCBpZgotICAgKiB5b3VyIERPTSB1c2VzIGEgZGlmZmVyZW50IGRlZmluaXRpb24gb2YgaGFzaENvZGUgKGVnIGhhc2hpbmcgdGhlCi0gICAqIGNvbnRlbnRzIG9mIHRoZSBzdWJ0cmVlKSwgb3IgaWYgeW91ciBET00gbWF5IGhhdmUgbXVsdGlwbGUgb2JqZWN0cwotICAgKiB0aGF0IHJlcHJlc2VudCBhIHNpbmdsZSBOb2RlIGluIHRoZSBkYXRhIHN0cnVjdHVyZSAoZWcgdmlhIHByb3h5aW5nKSwKLSAgICogeW91IG1heSBuZWVkIHRvIGZpbmQgYW5vdGhlciB3YXkgdG8gYXNzaWduIGEgdW5pcXVlIGlkZW50aWZpZXIuCi0gICAqIDxwPgotICAgKiBBbHNvLCBiZSBhd2FyZSB0aGF0IGlmIG5vZGVzIGFyZSBkZXN0cm95ZWQgYW5kIHJlY3JlYXRlZCwgdGhlcmUgaXMKLSAgICogYW4gb3BlbiBpc3N1ZSByZWdhcmRpbmcgd2hldGhlciBhbiBJRCBtYXkgYmUgcmV1c2VkLiBDdXJyZW50bHkKLSAgICogd2UncmUgYXNzdW1pbmcgdGhhdCB0aGUgaW5wdXQgZG9jdW1lbnQgaXMgc3RhYmxlIGZvciB0aGUgZHVyYXRpb24KLSAgICogb2YgdGhlIFhQYXRoL1hTTFQgb3BlcmF0aW9uLCBzbyB0aGlzIHNob3VsZG4ndCBhcmlzZSBpbiB0aGlzIGNvbnRleHQuCi0gICAqIDxwPgotICAgKiAoRE9NIExldmVsIDMgaXMgaW52ZXN0aWdhdGluZyBwcm92aWRpbmcgYSB1bmlxdWUgbm9kZSAia2V5IiwgYnV0Ci0gICAqIHRoYXQgd29uJ3QgaGVscCBMZXZlbCAxIGFuZCBMZXZlbCAyIGltcGxlbWVudGF0aW9ucy4pCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIHdob3NlIGlkZW50aWZpZXIgeW91IHdhbnQgdG8gb2J0YWluCi0gICAqCi0gICAqIEByZXR1cm4gYSBzdHJpbmcgd2hpY2ggc2hvdWxkIGJlIGRpZmZlcmVudCBmb3IgZXZlcnkgTm9kZSBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFVuaXF1ZUlEKE5vZGUgbm9kZSkKLSAgewotICAgIHJldHVybiAiTiIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKG5vZGUuaGFzaENvZGUoKSkudG9VcHBlckNhc2UoKTsKLSAgfQotCi0gIC8qKgotICAgKiBGaWd1cmUgb3V0IHdoZXRoZXIgbm9kZTIgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYXMgYmVpbmcgbGF0ZXIKLSAgICogaW4gdGhlIGRvY3VtZW50IHRoYW4gbm9kZTEsIGluIERvY3VtZW50IE9yZGVyIGFzIGRlZmluZWQKLSAgICogYnkgdGhlIFhQYXRoIG1vZGVsLiBUaGlzIG1heSBub3QgYWdyZWUgd2l0aCB0aGUgb3JkZXJpbmcgZGVmaW5lZAotICAgKiBieSBvdGhlciBYTUwgYXBwbGljYXRpb25zLgotICAgKiA8cD4KLSAgICogVGhlcmUgYXJlIHNvbWUgY2FzZXMgd2hlcmUgb3JkZXJpbmcgaXNuJ3QgZGVmaW5lZCwgYW5kIG5laXRoZXIgYXJlCi0gICAqIHRoZSByZXN1bHRzIG9mIHRoaXMgZnVuY3Rpb24gLS0gdGhvdWdoIHdlJ2xsIGdlbmVyYWxseSByZXR1cm4gdHJ1ZS4KLSAgICogCi0gICAqIFRPRE86IE1ha2Ugc3VyZSB0aGlzIGRvZXMgdGhlIHJpZ2h0IHRoaW5nIHdpdGggYXR0cmlidXRlIG5vZGVzISEhCi0gICAqCi0gICAqIEBwYXJhbSBub2RlMSBET00gTm9kZSB0byBwZXJmb3JtIHBvc2l0aW9uIGNvbXBhcmlzb24gb24uCi0gICAqIEBwYXJhbSBub2RlMiBET00gTm9kZSB0byBwZXJmb3JtIHBvc2l0aW9uIGNvbXBhcmlzb24gb24gLgotICAgKiAKLSAgICogQHJldHVybiBmYWxzZSBpZiBub2RlMiBjb21lcyBiZWZvcmUgbm9kZTEsIG90aGVyd2lzZSByZXR1cm4gdHJ1ZS4KLSAgICogWW91IGNhbiB0aGluayBvZiB0aGlzIGFzIAotICAgKiA8Y29kZT4obm9kZTEuZG9jdW1lbnRPcmRlclBvc2l0aW9uICZsdDs9IG5vZGUyLmRvY3VtZW50T3JkZXJQb3NpdGlvbik8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTm9kZUFmdGVyKE5vZGUgbm9kZTEsIE5vZGUgbm9kZTIpCi0gIHsKLSAgICBpZiAobm9kZTEgPT0gbm9kZTIpCi0gICAgICByZXR1cm4gdHJ1ZTsKLQotICAgICAgICAvLyBEZWZhdWx0IHJldHVybiB2YWx1ZSwgaWYgdGhlcmUgaXMgbm8gZGVmaW5lZCBvcmRlcmluZwotICAgIGJvb2xlYW4gaXNOb2RlQWZ0ZXIgPSB0cnVlOwotICAgICAgICAKLSAgICBOb2RlIHBhcmVudDEgPSBnZXRQYXJlbnRPZk5vZGUobm9kZTEpOwotICAgIE5vZGUgcGFyZW50MiA9IGdldFBhcmVudE9mTm9kZShub2RlMik7Ci0KLSAgICAvLyBPcHRpbWl6ZSBmb3IgbW9zdCBjb21tb24gY2FzZQotICAgIGlmIChwYXJlbnQxID09IHBhcmVudDIpICAvLyB0aGVuIHdlIGtub3cgdGhleSBhcmUgc2libGluZ3MKLSAgICB7Ci0gICAgICBpZiAobnVsbCAhPSBwYXJlbnQxKQotICAgICAgICBpc05vZGVBZnRlciA9IGlzTm9kZUFmdGVyU2libGluZyhwYXJlbnQxLCBub2RlMSwgbm9kZTIpOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICAgICAgICAgICAgLy8gSWYgYm90aCBwYXJlbnRzIGFyZSBudWxsLCBvcmRlcmluZyBpcyBub3QgZGVmaW5lZC4KLSAgICAgICAgICAgICAgICAgIC8vIFdlJ3JlIHJldHVybmluZyBhIHZhbHVlIGluIGxpZXUgb2YgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLgotICAgICAgICAgICAgICAgICAgLy8gTm90IGEgY2FzZSB3ZSBleHBlY3QgdG8gYXJpc2UgaW4gWFBhdGgsIGJ1dCBiZXdhcmUgaWYgeW91Ci0gICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gcmV1c2UgdGhpcyBtZXRob2QuCi0gICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgIC8vIFdlIGNhbiBqdXN0IGZhbGwgdGhyb3VnaCBpbiB0aGlzIGNhc2UsIHdoaWNoIGFsbG93cyB1cwotICAgICAgICAgICAgICAgICAgLy8gdG8gaGl0IHRoZSBkZWJ1Z2dpbmcgY29kZSBhdCB0aGUgZW5kIG9mIHRoZSBmdW5jdGlvbi4KLSAgICAgICAgICAvL3JldHVybiBpc05vZGVBZnRlcjsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gR2VuZXJhbCBzdHJhdGVneTogRmlndXJlIG91dCB0aGUgbGVuZ3RocyBvZiB0aGUgdHdvIAotICAgICAgLy8gYW5jZXN0b3IgY2hhaW5zLCByZWNvbmNpbGUgdGhlIGxlbmd0aHMsIGFuZCBsb29rIGZvcgotICAgICAgICAgIC8vIHRoZSBsb3dlc3QgY29tbW9uIGFuY2VzdG9yLiBJZiB0aGF0IGFuY2VzdG9yIGlzIG9uZSBvZgotICAgICAgICAgIC8vIHRoZSBub2RlcyBiZWluZyBjb21wYXJlZCwgaXQgY29tZXMgYmVmb3JlIHRoZSBvdGhlci4KLSAgICAgIC8vIE90aGVyd2lzZSBwZXJmb3JtIGEgc2libGluZyBjb21wYXJlLiAKLSAgICAgICAgICAgICAgICAvLwotICAgICAgICAgICAgICAgIC8vIE5PVEU6IElmIG5vIGNvbW1vbiBhbmNlc3RvciBpcyBmb3VuZCwgb3JkZXJpbmcgaXMgdW5kZWZpbmVkCi0gICAgICAgICAgICAgICAgLy8gYW5kIHdlIHJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBpc05vZGVBZnRlci4KLSAgICAgICAgICAgICAgICAKLSAgICAgIC8vIENvdW50IHBhcmVudHMgaW4gZWFjaCBhbmNlc3RvciBjaGFpbgotICAgICAgaW50IG5QYXJlbnRzMSA9IDIsIG5QYXJlbnRzMiA9IDI7ICAvLyBpbmNsdWRlIG5vZGUgJiBwYXJlbnQgb2J0YWluZWQgYWJvdmUKLQotICAgICAgd2hpbGUgKHBhcmVudDEgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgblBhcmVudHMxKys7Ci0KLSAgICAgICAgcGFyZW50MSA9IGdldFBhcmVudE9mTm9kZShwYXJlbnQxKTsKLSAgICAgIH0KLQotICAgICAgd2hpbGUgKHBhcmVudDIgIT0gbnVsbCkKLSAgICAgIHsKLSAgICAgICAgblBhcmVudHMyKys7Ci0KLSAgICAgICAgcGFyZW50MiA9IGdldFBhcmVudE9mTm9kZShwYXJlbnQyKTsKLSAgICAgIH0KLQotICAgICAgICAgIC8vIEluaXRpYWxseSBhc3N1bWUgc2NhbiBmb3IgY29tbW9uIGFuY2VzdG9yIHN0YXJ0cyB3aXRoCi0gICAgICAgICAgLy8gdGhlIGlucHV0IG5vZGVzLgotICAgICAgTm9kZSBzdGFydE5vZGUxID0gbm9kZTEsIHN0YXJ0Tm9kZTIgPSBub2RlMjsKLQotICAgICAgLy8gSWYgb25lIGFuY2VzdG9yIGNoYWluIGlzIGxvbmdlciwgYWRqdXN0IGl0cyBzdGFydCBwb2ludAotICAgICAgICAgIC8vIHNvIHdlJ3JlIGNvbXBhcmluZyBhdCB0aGUgc2FtZSBkZXB0aHMKLSAgICAgIGlmIChuUGFyZW50czEgPCBuUGFyZW50czIpCi0gICAgICB7Ci0gICAgICAgIC8vIEFkanVzdCBzdGFydE5vZGUyIHRvIGRlcHRoIG9mIHN0YXJ0Tm9kZTEKLSAgICAgICAgaW50IGFkanVzdCA9IG5QYXJlbnRzMiAtIG5QYXJlbnRzMTsKLQotICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFkanVzdDsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgc3RhcnROb2RlMiA9IGdldFBhcmVudE9mTm9kZShzdGFydE5vZGUyKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZSBpZiAoblBhcmVudHMxID4gblBhcmVudHMyKQotICAgICAgewotICAgICAgICAvLyBhZGp1c3Qgc3RhcnROb2RlMSB0byBkZXB0aCBvZiBzdGFydE5vZGUyCi0gICAgICAgIGludCBhZGp1c3QgPSBuUGFyZW50czEgLSBuUGFyZW50czI7Ci0KLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGp1c3Q7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIHN0YXJ0Tm9kZTEgPSBnZXRQYXJlbnRPZk5vZGUoc3RhcnROb2RlMSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgTm9kZSBwcmV2Q2hpbGQxID0gbnVsbCwgcHJldkNoaWxkMiA9IG51bGw7ICAvLyBzbyB3ZSBjYW4gImJhY2sgdXAiCi0KLSAgICAgIC8vIExvb3AgdXAgdGhlIGFuY2VzdG9yIGNoYWluIGxvb2tpbmcgZm9yIGNvbW1vbiBwYXJlbnQKLSAgICAgIHdoaWxlIChudWxsICE9IHN0YXJ0Tm9kZTEpCi0gICAgICB7Ci0gICAgICAgIGlmIChzdGFydE5vZGUxID09IHN0YXJ0Tm9kZTIpICAvLyBjb21tb24gcGFyZW50PwotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG51bGwgPT0gcHJldkNoaWxkMSkgIC8vIGZpcnN0IHRpbWUgaW4gbG9vcD8KLSAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIC8vIEVkZ2UgY29uZGl0aW9uOiBvbmUgaXMgdGhlIGFuY2VzdG9yIG9mIHRoZSBvdGhlci4KLSAgICAgICAgICAgIGlzTm9kZUFmdGVyID0gKG5QYXJlbnRzMSA8IG5QYXJlbnRzMikgPyB0cnVlIDogZmFsc2U7Ci0KLSAgICAgICAgICAgIGJyZWFrOyAgLy8gZnJvbSB3aGlsZSBsb29wCi0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UgCi0gICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tcGFyZSBhbmNlc3RvcnMgYmVsb3cgbG93ZXN0LWNvbW1vbiBhcyBzaWJsaW5ncwotICAgICAgICAgICAgaXNOb2RlQWZ0ZXIgPSBpc05vZGVBZnRlclNpYmxpbmcoc3RhcnROb2RlMSwgcHJldkNoaWxkMSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZDaGlsZDIpOwotCi0gICAgICAgICAgICBicmVhazsgIC8vIGZyb20gd2hpbGUgbG9vcAotICAgICAgICAgIH0KLSAgICAgICAgfSAgLy8gZW5kIGlmKHN0YXJ0Tm9kZTEgPT0gc3RhcnROb2RlMikKLQotICAgICAgICAgICAgICAgIC8vIE1vdmUgdXAgb25lIGxldmVsIGFuZCB0cnkgYWdhaW4KLSAgICAgICAgcHJldkNoaWxkMSA9IHN0YXJ0Tm9kZTE7Ci0gICAgICAgIHN0YXJ0Tm9kZTEgPSBnZXRQYXJlbnRPZk5vZGUoc3RhcnROb2RlMSk7Ci0gICAgICAgIHByZXZDaGlsZDIgPSBzdGFydE5vZGUyOwotICAgICAgICBzdGFydE5vZGUyID0gZ2V0UGFyZW50T2ZOb2RlKHN0YXJ0Tm9kZTIpOwotICAgICAgfSAgLy8gZW5kIHdoaWxlKHBhcmVudHMgZXhpc3QgdG8gZXhhbWluZSkKLSAgICB9ICAvLyBlbmQgYmlnIGVsc2UgKG5vdCBpbW1lZGlhdGUgc2libGluZ3MpCi0gICAgICAgIAotICAgICAgICAvLyBXQVJOSU5HOiBUaGUgZm9sbG93aW5nIGRpYWdub3N0aWMgd29uJ3QgcmVwb3J0IHRoZSBlYXJseQotICAgICAgICAvLyAic2FtZSBub2RlIiBjYXNlLiBGaXggaWYvd2hlbiBuZWVkZWQuCi0gICAgICAgIAotICAgIC8qIC0tIHBsZWFzZSBkbyBub3QgcmVtb3ZlLi4uIHZlcnkgdXNlZnVsIGZvciBkaWFnbm9zdGljcyAtLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigibm9kZTEgPSAiK25vZGUxLmdldE5vZGVOYW1lKCkrIigiK25vZGUxLmdldE5vZGVUeXBlKCkrIikiKwotICAgICIsIG5vZGUyID0gIitub2RlMi5nZXROb2RlTmFtZSgpCi0gICAgKyIoIitub2RlMi5nZXROb2RlVHlwZSgpKyIpIisKLSAgICAiLCBpc05vZGVBZnRlciA9ICIraXNOb2RlQWZ0ZXIpOyAqLwotICAgIHJldHVybiBpc05vZGVBZnRlcjsKLSAgfSAgLy8gZW5kIGlzTm9kZUFmdGVyKE5vZGUgbm9kZTEsIE5vZGUgbm9kZTIpCi0KLSAgLyoqCi0gICAqIEZpZ3VyZSBvdXQgaWYgY2hpbGQyIGlzIGFmdGVyIGNoaWxkMSBpbiBkb2N1bWVudCBvcmRlci4KLSAgICogPHA+Ci0gICAqIFdhcm5pbmc6IFNvbWUgYXNwZWN0cyBvZiAiZG9jdW1lbnQgb3JkZXIiIGFyZSBub3Qgd2VsbCBkZWZpbmVkLgotICAgKiBGb3IgZXhhbXBsZSwgdGhlIG9yZGVyIG9mIGF0dHJpYnV0ZXMgaXMgY29uc2lkZXJlZAotICAgKiBtZWFuaW5nbGVzcyBpbiBYTUwsIGFuZCB0aGUgb3JkZXIgcmVwb3J0ZWQgYnkgb3VyIG1vZGVsIHdpbGwKLSAgICogYmUgY29uc2lzdGFudCBmb3IgYSBnaXZlbiBpbnZvY2F0aW9uIGJ1dCBtYXkgbm90IAotICAgKiBtYXRjaCB0aGF0IG9mIGVpdGhlciB0aGUgc291cmNlIGZpbGUgb3IgdGhlIHNlcmlhbGl6ZWQgb3V0cHV0LgotICAgKiAKLSAgICogQHBhcmFtIHBhcmVudCBNdXN0IGJlIHRoZSBwYXJlbnQgb2YgYm90aCBjaGlsZDEgYW5kIGNoaWxkMi4KLSAgICogQHBhcmFtIGNoaWxkMSBNdXN0IGJlIHRoZSBjaGlsZCBvZiBwYXJlbnQgYW5kIG5vdCBlcXVhbCB0byBjaGlsZDIuCi0gICAqIEBwYXJhbSBjaGlsZDIgTXVzdCBiZSB0aGUgY2hpbGQgb2YgcGFyZW50IGFuZCBub3QgZXF1YWwgdG8gY2hpbGQxLgotICAgKiBAcmV0dXJuIHRydWUgaWYgY2hpbGQgMiBpcyBhZnRlciBjaGlsZDEgaW4gZG9jdW1lbnQgb3JkZXIuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTm9kZUFmdGVyU2libGluZyhOb2RlIHBhcmVudCwgTm9kZSBjaGlsZDEsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQyKQotICB7Ci0KLSAgICBib29sZWFuIGlzTm9kZUFmdGVyU2libGluZyA9IGZhbHNlOwotICAgIHNob3J0IGNoaWxkMXR5cGUgPSBjaGlsZDEuZ2V0Tm9kZVR5cGUoKTsKLSAgICBzaG9ydCBjaGlsZDJ0eXBlID0gY2hpbGQyLmdldE5vZGVUeXBlKCk7Ci0KLSAgICBpZiAoKE5vZGUuQVRUUklCVVRFX05PREUgIT0gY2hpbGQxdHlwZSkKLSAgICAgICAgICAgICYmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IGNoaWxkMnR5cGUpKQotICAgIHsKLQotICAgICAgLy8gYWx3YXlzIHNvcnQgYXR0cmlidXRlcyBiZWZvcmUgbm9uLWF0dHJpYnV0ZXMuCi0gICAgICBpc05vZGVBZnRlclNpYmxpbmcgPSBmYWxzZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoKE5vZGUuQVRUUklCVVRFX05PREUgPT0gY2hpbGQxdHlwZSkKLSAgICAgICAgICAgICAmJiAoTm9kZS5BVFRSSUJVVEVfTk9ERSAhPSBjaGlsZDJ0eXBlKSkKLSAgICB7Ci0KLSAgICAgIC8vIGFsd2F5cyBzb3J0IGF0dHJpYnV0ZXMgYmVmb3JlIG5vbi1hdHRyaWJ1dGVzLgotICAgICAgaXNOb2RlQWZ0ZXJTaWJsaW5nID0gdHJ1ZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSBjaGlsZDF0eXBlKQotICAgIHsKLSAgICAgIE5hbWVkTm9kZU1hcCBjaGlsZHJlbiA9IHBhcmVudC5nZXRBdHRyaWJ1dGVzKCk7Ci0gICAgICBpbnQgbk5vZGVzID0gY2hpbGRyZW4uZ2V0TGVuZ3RoKCk7Ci0gICAgICBib29sZWFuIGZvdW5kMSA9IGZhbHNlLCBmb3VuZDIgPSBmYWxzZTsKLQotICAgICAgICAgIC8vIENvdW50IGZyb20gdGhlIHN0YXJ0IHVudGlsIHdlIGZpbmQgb25lIG9yIHRoZSBvdGhlci4KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbk5vZGVzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIE5vZGUgY2hpbGQgPSBjaGlsZHJlbi5pdGVtKGkpOwotCi0gICAgICAgIGlmIChjaGlsZDEgPT0gY2hpbGQpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoZm91bmQyKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlzTm9kZUFmdGVyU2libGluZyA9IGZhbHNlOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBmb3VuZDEgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNoaWxkMiA9PSBjaGlsZCkKLSAgICAgICAgewotICAgICAgICAgIGlmIChmb3VuZDEpCi0gICAgICAgICAgewotICAgICAgICAgICAgaXNOb2RlQWZ0ZXJTaWJsaW5nID0gdHJ1ZTsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgZm91bmQyID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgICAgICAgICAgIC8vIFRPRE86IENoZWNrIHBlcmZvcm1hbmNlIG9mIGFsdGVybmF0ZSBzb2x1dGlvbjoKLSAgICAgICAgICAgICAgICAvLyBUaGVyZSBhcmUgdHdvIGNob2ljZXMgaGVyZTogQ291bnQgZnJvbSB0aGUgc3RhcnQgb2YKLSAgICAgICAgICAgICAgICAvLyB0aGUgZG9jdW1lbnQgdW50aWwgd2UgZmluZCBvbmUgb3IgdGhlIG90aGVyLCBvciBjb3VudAotICAgICAgICAgICAgICAgIC8vIGZyb20gb25lIHVudGlsIHdlIGZpbmQgb3IgZmFpbCB0byBmaW5kIHRoZSBvdGhlci4KLSAgICAgICAgICAgICAgICAvLyBFaXRoZXIgY2FuIHdpbmQgdXAgc2Nhbm5pbmcgYWxsIHRoZSBzaWJsaW5ncyBpbiB0aGUgd29yc3QKLSAgICAgICAgICAgICAgICAvLyBjYXNlLCB3aGljaCBvbiBhIHdpZGUgZG9jdW1lbnQgY2FuIGJlIGEgbG90IG9mIHdvcmsgYnV0Ci0gICAgICAgICAgICAgICAgLy8gaXMgbW9yZSB0eXBpY2FsbHkgaXMgYSBzaG9ydCBsaXN0LiAKLSAgICAgICAgICAgICAgICAvLyBTY2FubmluZyBmcm9tIHRoZSBzdGFydCBpbnZvbHZlcyB0d28gdGVzdHMgcGVyIGl0ZXJhdGlvbiwKLSAgICAgICAgICAgICAgICAvLyBidXQgaXQgaXNuJ3QgY2xlYXIgdGhhdCBzY2FubmluZyBmcm9tIHRoZSBtaWRkbGUgZG9lc24ndAotICAgICAgICAgICAgICAgIC8vIHlpZWxkIG1vcmUgaXRlcmF0aW9ucyBvbiBhdmVyYWdlLiAKLSAgICAgICAgICAgICAgICAvLyBXZSBzaG91bGQgcnVuIHNvbWUgdGVzdGNhc2VzLgotICAgICAgTm9kZSBjaGlsZCA9IHBhcmVudC5nZXRGaXJzdENoaWxkKCk7Ci0gICAgICBib29sZWFuIGZvdW5kMSA9IGZhbHNlLCBmb3VuZDIgPSBmYWxzZTsKLQotICAgICAgd2hpbGUgKG51bGwgIT0gY2hpbGQpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gTm9kZSBjaGlsZCA9IGNoaWxkcmVuLml0ZW0oaSk7Ci0gICAgICAgIGlmIChjaGlsZDEgPT0gY2hpbGQpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoZm91bmQyKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlzTm9kZUFmdGVyU2libGluZyA9IGZhbHNlOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBmb3VuZDEgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGNoaWxkMiA9PSBjaGlsZCkKLSAgICAgICAgewotICAgICAgICAgIGlmIChmb3VuZDEpCi0gICAgICAgICAgewotICAgICAgICAgICAgaXNOb2RlQWZ0ZXJTaWJsaW5nID0gdHJ1ZTsKLQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgZm91bmQyID0gdHJ1ZTsKLSAgICAgICAgfQotCi0gICAgICAgIGNoaWxkID0gY2hpbGQuZ2V0TmV4dFNpYmxpbmcoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gaXNOb2RlQWZ0ZXJTaWJsaW5nOwotICB9ICAvLyBlbmQgaXNOb2RlQWZ0ZXJTaWJsaW5nKE5vZGUgcGFyZW50LCBOb2RlIGNoaWxkMSwgTm9kZSBjaGlsZDIpCi0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIFNFQ1RJT046IE5hbWVzcGFjZSByZXNvbHV0aW9uCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSBkZXB0aCBsZXZlbCBvZiB0aGlzIG5vZGUgaW4gdGhlIHRyZWUgKGVxdWFscyAxIGZvcgotICAgKiBhIHBhcmVudGxlc3Mgbm9kZSkuCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgZXhhbWluZWQuCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBhbmNlc3RvcnMsIHBsdXMgb25lCi0gICAqLwotICBwdWJsaWMgc2hvcnQgZ2V0TGV2ZWwoTm9kZSBuKQotICB7Ci0KLSAgICBzaG9ydCBsZXZlbCA9IDE7Ci0KLSAgICB3aGlsZSAobnVsbCAhPSAobiA9IGdldFBhcmVudE9mTm9kZShuKSkpCi0gICAgewotICAgICAgbGV2ZWwrKzsKLSAgICB9Ci0KLSAgICByZXR1cm4gbGV2ZWw7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gWE1MIE5hbWVzcGFjZSBwcmVmaXggYW5kIGEgY29udGV4dCBpbiB3aGljaCB0aGUgcHJlZml4Ci0gICAqIGlzIHRvIGJlIGV2YWx1YXRlZCwgcmV0dXJuIHRoZSBOYW1lc3BhY2UgTmFtZSB0aGlzIHByZWZpeCB3YXMgCi0gICAqIGJvdW5kIHRvLiBOb3RlIHRoYXQgRE9NIExldmVsIDMgaXMgZXhwZWN0ZWQgdG8gcHJvdmlkZSBhIHZlcnNpb24gb2YKLSAgICogdGhpcyB3aGljaCBkZWFscyB3aXRoIHRoZSBET00ncyAiZWFybHkgYmluZGluZyIgYmVoYXZpb3IuCi0gICAqIAotICAgKiBEZWZhdWx0IGhhbmRsaW5nOgotICAgKgotICAgKiBAcGFyYW0gcHJlZml4IFN0cmluZyBjb250YWluaW5nIG5hbWVzcGFjZSBwcmVmaXggdG8gYmUgcmVzb2x2ZWQsIAotICAgKiB3aXRob3V0IHRoZSAnOicgd2hpY2ggc2VwYXJhdGVzIGl0IGZyb20gdGhlIGxvY2FsbmFtZSB3aGVuIHVzZWQgCi0gICAqIGluIGEgTm9kZSBOYW1lLiBUaGUgZW1wdHkgc3Rpbmcgc2lnbmlmaWVzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQotICAgKiBhdCB0aGlzIHBvaW50IGluIHRoZSBkb2N1bWVudC4KLSAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgRWxlbWVudCB3aGljaCBwcm92aWRlcyBjb250ZXh0IGZvciByZXNvbHV0aW9uLgotICAgKiAoV2UgY291bGQgZXh0ZW5kIHRoaXMgdG8gd29yayBmb3Igb3RoZXIgbm9kZXMgYnkgZmlyc3Qgc2Vla2luZyB0aGVpcgotICAgKiBuZWFyZXN0IEVsZW1lbnQgYW5jZXN0b3IuKQotICAgKgotICAgKiBAcmV0dXJuIGEgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIE5hbWVzcGFjZSBVUkkgd2hpY2ggdGhpcyBwcmVmaXgKLSAgICogcmVwcmVzZW50cyBpbiB0aGUgc3BlY2lmaWVkIGNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeChTdHJpbmcgcHJlZml4LCBFbGVtZW50IG5hbWVzcGFjZUNvbnRleHQpCi0gIHsKLQotICAgIGludCB0eXBlOwotICAgIE5vZGUgcGFyZW50ID0gbmFtZXNwYWNlQ29udGV4dDsKLSAgICBTdHJpbmcgbmFtZXNwYWNlID0gbnVsbDsKLQotICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICB7Ci0gICAgICBuYW1lc3BhY2UgPSBRTmFtZS5TX1hNTE5BTUVTUEFDRVVSSTsgLy8gSGFyZGNvZGVkLCBwZXIgTmFtZXNwYWNlIHNwZWMKLSAgICB9Ci0gICAgICAgIGVsc2UgaWYocHJlZml4LmVxdWFscygieG1sbnMiKSkKLSAgICB7Ci0gICAgICAgICAgLy8gSGFyZGNvZGVkIGluIHRoZSBET00gc3BlYywgZXhwZWN0ZWQgdG8gYmUgYWRvcHRlZCBieQotICAgICAgICAgIC8vIE5hbWVzcGFjZSBzcGVjLiBOT1RFOiBOYW1lc3BhY2UgZGVjbGFyYXRpb25zIF9tdXN0XyB1c2UKLSAgICAgICAgICAvLyB0aGUgeG1sbnM6IHByZWZpeDsgb3RoZXIgcHJlZml4ZXMgZGVjbGFyZWQgYXMgYmVsb25naW5nCi0gICAgICAgICAgLy8gdG8gdGhpcyBuYW1lc3BhY2Ugd2lsbCBub3QgYmUgcmVjb2duaXplZCBhbmQgc2hvdWxkCi0gICAgICAgICAgLy8gcHJvYmFibHkgYmUgcmVqZWN0ZWQgYnkgcGFyc2VycyBhcyBlcnJvbmVvdXMgZGVjbGFyYXRpb25zLgotICAgICAgbmFtZXNwYWNlID0gImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIjsgCi0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAgICAgLy8gQXR0cmlidXRlIG5hbWUgZm9yIHRoaXMgcHJlZml4J3MgZGVjbGFyYXRpb24KLSAgICAgICAgICBTdHJpbmcgZGVjbG5hbWU9KHByZWZpeD09IiIpCi0gICAgICAgICAgICAgICAgICAgICAgICA/ICJ4bWxucyIKLSAgICAgICAgICAgICAgICAgICAgICAgIDogInhtbG5zOiIrcHJlZml4OwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgIC8vIFNjYW4gdW50aWwgd2UgcnVuIG91dCBvZiBFbGVtZW50cyBvciBoYXZlIHJlc29sdmVkIHRoZSBuYW1lc3BhY2UKLSAgICAgIHdoaWxlICgobnVsbCAhPSBwYXJlbnQpICYmIChudWxsID09IG5hbWVzcGFjZSkKLSAgICAgICAgICAgICAmJiAoKCh0eXBlID0gcGFyZW50LmdldE5vZGVUeXBlKCkpID09IE5vZGUuRUxFTUVOVF9OT0RFKQotICAgICAgICAgICAgICAgICB8fCAodHlwZSA9PSBOb2RlLkVOVElUWV9SRUZFUkVOQ0VfTk9ERSkpKQotICAgICAgewotICAgICAgICBpZiAodHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkKLSAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyBMb29rIGZvciB0aGUgYXBwcm9wcmlhdGUgTmFtZXNwYWNlIERlY2xhcmF0aW9uIGF0dHJpYnV0ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVpdGhlciAieG1sbnM6cHJlZml4IiBvciAoaWYgcHJlZml4IGlzICIiKSAieG1sbnMiLgotICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogVGhpcyBkb2VzIG5vdCBoYW5kbGUgImltcGxpY2l0IGRlY2xhcmF0aW9ucyIKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIG1heSBiZSBjcmVhdGVkIHdoZW4gdGhlIERPTSBpcyBlZGl0ZWQuIERPTSBMZXZlbAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gMyB3aWxsIGRlZmluZSBob3cgdGhvc2Ugc2hvdWxkIGJlIGludGVycHJldGVkLiBCdXQKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXNzdWUgd29uJ3QgYXJpc2UgaW4gZnJlc2hseS1wYXJzZWQgRE9Ncy4KLSAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIC8vIE5PVEU6IGRlY2xuYW1lIGlzIHNldCBlYXJsaWVyLCBvdXRzaWRlIHRoZSBsb29wLgotICAgICAgICAgICAgICAgICAgICAgICAgQXR0ciBhdHRyPSgoRWxlbWVudClwYXJlbnQpLmdldEF0dHJpYnV0ZU5vZGUoZGVjbG5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgaWYoYXR0ciE9bnVsbCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICBwYXJlbnQgPSBnZXRQYXJlbnRPZk5vZGUocGFyZW50KTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmFtZXNwYWNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFuIGV4cGVyaW1lbnQgZm9yIHRoZSBtb21lbnQuCi0gICAqLwotICBIYXNodGFibGUgbV9OU0luZm9zID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBub3QgYmVlbiAKLSAgICogIHByb2Nlc3NlZCwgYnV0IGhhcyB4bWxucyBuYW1lc3BhY2UgZGVjbHMuICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIE5TSW5mbyBtX05TSW5mb1VuUHJvY1dpdGhYTUxOUyA9IG5ldyBOU0luZm8oZmFsc2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLQotICAvKiogT2JqZWN0IHRvIHB1dCBpbnRvIHRoZSBtX05TSW5mb3MgdGFibGUgdGhhdCB0ZWxscyB0aGF0IGEgbm9kZSBoYXMgbm90IGJlZW4gCi0gICAqICBwcm9jZXNzZWQsIGJ1dCBoYXMgbm8geG1sbnMgbmFtZXNwYWNlIGRlY2xzLiAgKi8KLSAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBOU0luZm8gbV9OU0luZm9VblByb2NXaXRob3V0WE1MTlMgPSBuZXcgTlNJbmZvKGZhbHNlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBub3QgYmVlbiAKLSAgICogIHByb2Nlc3NlZCwgYW5kIGhhcyBubyB4bWxucyBuYW1lc3BhY2UgZGVjbHMsIGFuZCBoYXMgbm8gYW5jZXN0b3IgZGVjbHMuICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIE5TSW5mbyBtX05TSW5mb1VuUHJvY05vQW5jZXN0b3JYTUxOUyA9Ci0gICAgbmV3IE5TSW5mbyhmYWxzZSwgZmFsc2UsIE5TSW5mby5BTkNFU1RPUk5PWE1MTlMpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBiZWVuIAotICAgKiAgcHJvY2Vzc2VkLCBhbmQgaGFzIHhtbG5zIG5hbWVzcGFjZSBkZWNscy4gICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTlNJbmZvIG1fTlNJbmZvTnVsbFdpdGhYTUxOUyA9IG5ldyBOU0luZm8odHJ1ZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLQotICAvKiogT2JqZWN0IHRvIHB1dCBpbnRvIHRoZSBtX05TSW5mb3MgdGFibGUgdGhhdCB0ZWxscyB0aGF0IGEgbm9kZSBoYXMgYmVlbiAKLSAgICogIHByb2Nlc3NlZCwgYW5kIGhhcyBubyB4bWxucyBuYW1lc3BhY2UgZGVjbHMuICAqLwotICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIE5TSW5mbyBtX05TSW5mb051bGxXaXRob3V0WE1MTlMgPSBuZXcgTlNJbmZvKHRydWUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwotCi0gIC8qKiBPYmplY3QgdG8gcHV0IGludG8gdGhlIG1fTlNJbmZvcyB0YWJsZSB0aGF0IHRlbGxzIHRoYXQgYSBub2RlIGhhcyBiZWVuIAotICAgKiAgcHJvY2Vzc2VkLCBhbmQgaGFzIG5vIHhtbG5zIG5hbWVzcGFjZSBkZWNscy4gYW5kIGhhcyBubyBhbmNlc3RvciBkZWNscy4gICovCi0gIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTlNJbmZvIG1fTlNJbmZvTnVsbE5vQW5jZXN0b3JYTUxOUyA9Ci0gICAgbmV3IE5TSW5mbyh0cnVlLCBmYWxzZSwgTlNJbmZvLkFOQ0VTVE9STk9YTUxOUyk7Ci0KLSAgLyoqIFZlY3RvciBvZiBub2RlIChvZGQgaW5kZXhlcykgYW5kIE5TSW5mb3MgKGV2ZW4gaW5kZXhlcykgdGhhdCB0ZWxsIGlmIAotICAgKiAgdGhlIGdpdmVuIG5vZGUgaXMgYSBjYW5kaWRhdGUgZm9yIGFuY2VzdG9yIG5hbWVzcGFjZSBwcm9jZXNzaW5nLiAgKi8KLSAgcHJvdGVjdGVkIFZlY3RvciBtX2NhbmRpZGF0ZU5vQW5jZXN0b3JYTUxOUyA9IG5ldyBWZWN0b3IoKTsKLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIG9mIHRoZSBnaXZlbiBub2RlLiBEaWZmZXJzIGZyb20gc2ltcGx5IGdldHRpbmcKLSAgICogdGhlIG5vZGUncyBwcmVmaXggYW5kIHVzaW5nIGdldE5hbWVzcGFjZUZvclByZWZpeCBpbiB0aGF0IGl0IGF0dGVtcHRzCi0gICAqIHRvIGNhY2hlIHNvbWUgb2YgdGhlIGRhdGEgaW4gTlNJTkZPIG9iamVjdHMsIHRvIGF2b2lkIHJlcGVhdGVkIGxvb2t1cC4KLSAgICogVE9ETzogU2hvdWxkIHdlIGNvbnNpZGVyIG1vdmluZyB0aGF0IGxvZ2ljIGludG8gZ2V0TmFtZXNwYWNlRm9yUHJlZml4PwotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGV4YW1pbmVkLgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBOYW1lc3BhY2UgTmFtZSAodXJpKSBmb3IgdGhpcyBub2RlLgotICAgKiBOb3RlIHRoYXQgdGhpcyBpcyB1bmRlZmluZWQgZm9yIGFueSBub2RlcyBvdGhlciB0aGFuIEVsZW1lbnRzIGFuZAotICAgKiBBdHRyaWJ1dGVzLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VPZk5vZGUoTm9kZSBuKQotICB7Ci0KLSAgICBTdHJpbmcgbmFtZXNwYWNlT2ZQcmVmaXg7Ci0gICAgYm9vbGVhbiBoYXNQcm9jZXNzZWROUzsKLSAgICBOU0luZm8gbnNJbmZvOwotICAgIHNob3J0IG50eXBlID0gbi5nZXROb2RlVHlwZSgpOwotCi0gICAgaWYgKE5vZGUuQVRUUklCVVRFX05PREUgIT0gbnR5cGUpCi0gICAgewotICAgICAgT2JqZWN0IG5zT2JqID0gbV9OU0luZm9zLmdldChuKTsgIC8vIHJldHVybiB2YWx1ZQotCi0gICAgICBuc0luZm8gPSAobnNPYmogPT0gbnVsbCkgPyBudWxsIDogKE5TSW5mbykgbnNPYmo7Ci0gICAgICBoYXNQcm9jZXNzZWROUyA9IChuc0luZm8gPT0gbnVsbCkgPyBmYWxzZSA6IG5zSW5mby5tX2hhc1Byb2Nlc3NlZE5TOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaGFzUHJvY2Vzc2VkTlMgPSBmYWxzZTsKLSAgICAgIG5zSW5mbyA9IG51bGw7Ci0gICAgfQotCi0gICAgaWYgKGhhc1Byb2Nlc3NlZE5TKQotICAgIHsKLSAgICAgIG5hbWVzcGFjZU9mUHJlZml4ID0gbnNJbmZvLm1fbmFtZXNwYWNlOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbmFtZXNwYWNlT2ZQcmVmaXggPSBudWxsOwotCi0gICAgICBTdHJpbmcgbm9kZU5hbWUgPSBuLmdldE5vZGVOYW1lKCk7Ci0gICAgICBpbnQgaW5kZXhPZk5TU2VwID0gbm9kZU5hbWUuaW5kZXhPZignOicpOwotICAgICAgU3RyaW5nIHByZWZpeDsKLQotICAgICAgaWYgKE5vZGUuQVRUUklCVVRFX05PREUgPT0gbnR5cGUpCi0gICAgICB7Ci0gICAgICAgIGlmIChpbmRleE9mTlNTZXAgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgcHJlZml4ID0gbm9kZU5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyBBdHRyaWJ1dGVzIGRvbid0IHVzZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UsIHNvIGlmIAotICAgICAgICAgIC8vIHRoZXJlIGlzbid0IGEgcHJlZml4LCB3ZSdyZSBkb25lLgotICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VPZlByZWZpeDsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBwcmVmaXggPSAoaW5kZXhPZk5TU2VwID49IDApCi0gICAgICAgICAgICAgICAgID8gbm9kZU5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCkgOiAiIjsKLSAgICAgIH0KLQotICAgICAgYm9vbGVhbiBhbmNlc3RvcnNIYXZlWE1MTlMgPSBmYWxzZTsKLSAgICAgIGJvb2xlYW4gbkhhc1hNTE5TID0gZmFsc2U7Ci0KLSAgICAgIGlmIChwcmVmaXguZXF1YWxzKCJ4bWwiKSkKLSAgICAgIHsKLSAgICAgICAgbmFtZXNwYWNlT2ZQcmVmaXggPSBRTmFtZS5TX1hNTE5BTUVTUEFDRVVSSTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaW50IHBhcmVudFR5cGU7Ci0gICAgICAgIE5vZGUgcGFyZW50ID0gbjsKLQotICAgICAgICB3aGlsZSAoKG51bGwgIT0gcGFyZW50KSAmJiAobnVsbCA9PSBuYW1lc3BhY2VPZlByZWZpeCkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoKG51bGwgIT0gbnNJbmZvKQotICAgICAgICAgICAgICAgICAgJiYgKG5zSW5mby5tX2FuY2VzdG9ySGFzWE1MTlNBdHRycwotICAgICAgICAgICAgICAgICAgICAgID09IG5zSW5mby5BTkNFU1RPUk5PWE1MTlMpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLQotICAgICAgICAgIHBhcmVudFR5cGUgPSBwYXJlbnQuZ2V0Tm9kZVR5cGUoKTsKLQotICAgICAgICAgIGlmICgobnVsbCA9PSBuc0luZm8pIHx8IG5zSW5mby5tX2hhc1hNTE5TQXR0cnMpCi0gICAgICAgICAgewotICAgICAgICAgICAgYm9vbGVhbiBlbGVtZW50SGFzWE1MTlMgPSBmYWxzZTsKLQotICAgICAgICAgICAgaWYgKHBhcmVudFR5cGUgPT0gTm9kZS5FTEVNRU5UX05PREUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIE5hbWVkTm9kZU1hcCBubm0gPSBwYXJlbnQuZ2V0QXR0cmlidXRlcygpOwotCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm5tLmdldExlbmd0aCgpOyBpKyspCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBOb2RlIGF0dHIgPSBubm0uaXRlbShpKTsKLSAgICAgICAgICAgICAgICBTdHJpbmcgYW5hbWUgPSBhdHRyLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoYW5hbWUuY2hhckF0KDApID09ICd4JykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBib29sZWFuIGlzUHJlZml4ID0gYW5hbWUuc3RhcnRzV2l0aCgieG1sbnM6Iik7Ci0KLSAgICAgICAgICAgICAgICAgIGlmIChhbmFtZS5lcXVhbHMoInhtbG5zIikgfHwgaXNQcmVmaXgpCi0gICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmIChuID09IHBhcmVudCkKLSAgICAgICAgICAgICAgICAgICAgICBuSGFzWE1MTlMgPSB0cnVlOwotCi0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRIYXNYTUxOUyA9IHRydWU7Ci0gICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yc0hhdmVYTUxOUyA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHAgPSBpc1ByZWZpeCA/IGFuYW1lLnN1YnN0cmluZyg2KSA6ICIiOwotCi0gICAgICAgICAgICAgICAgICAgIGlmIChwLmVxdWFscyhwcmVmaXgpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlT2ZQcmVmaXggPSBhdHRyLmdldE5vZGVWYWx1ZSgpOwotCi0gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaWYgKChOb2RlLkFUVFJJQlVURV9OT0RFICE9IHBhcmVudFR5cGUpICYmIChudWxsID09IG5zSW5mbykKLSAgICAgICAgICAgICAgICAgICAgJiYgKG4gIT0gcGFyZW50KSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgbnNJbmZvID0gZWxlbWVudEhhc1hNTE5TCi0gICAgICAgICAgICAgICAgICAgICAgID8gbV9OU0luZm9VblByb2NXaXRoWE1MTlMgOiBtX05TSW5mb1VuUHJvY1dpdGhvdXRYTUxOUzsKLQotICAgICAgICAgICAgICBtX05TSW5mb3MucHV0KHBhcmVudCwgbnNJbmZvKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSBwYXJlbnRUeXBlKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBhcmVudCA9IGdldFBhcmVudE9mTm9kZShwYXJlbnQpOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuYWRkRWxlbWVudChwYXJlbnQpOwotICAgICAgICAgICAgbV9jYW5kaWRhdGVOb0FuY2VzdG9yWE1MTlMuYWRkRWxlbWVudChuc0luZm8pOwotCi0gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQuZ2V0UGFyZW50Tm9kZSgpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlmIChudWxsICE9IHBhcmVudCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBPYmplY3QgbnNPYmogPSBtX05TSW5mb3MuZ2V0KHBhcmVudCk7ICAvLyByZXR1cm4gdmFsdWUKLQotICAgICAgICAgICAgbnNJbmZvID0gKG5zT2JqID09IG51bGwpID8gbnVsbCA6IChOU0luZm8pIG5zT2JqOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGludCBuQ2FuZGlkYXRlcyA9IG1fY2FuZGlkYXRlTm9BbmNlc3RvclhNTE5TLnNpemUoKTsKLQotICAgICAgICBpZiAobkNhbmRpZGF0ZXMgPiAwKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKChmYWxzZSA9PSBhbmNlc3RvcnNIYXZlWE1MTlMpICYmIChudWxsID09IHBhcmVudCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQ2FuZGlkYXRlczsgaSArPSAyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBPYmplY3QgY2FuZGlkYXRlSW5mbyA9IG1fY2FuZGlkYXRlTm9BbmNlc3RvclhNTE5TLmVsZW1lbnRBdChpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDEpOwotCi0gICAgICAgICAgICAgIGlmIChjYW5kaWRhdGVJbmZvID09IG1fTlNJbmZvVW5Qcm9jV2l0aG91dFhNTE5TKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgbV9OU0luZm9zLnB1dChtX2NhbmRpZGF0ZU5vQW5jZXN0b3JYTUxOUy5lbGVtZW50QXQoaSksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX05TSW5mb1VuUHJvY05vQW5jZXN0b3JYTUxOUyk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgZWxzZSBpZiAoY2FuZGlkYXRlSW5mbyA9PSBtX05TSW5mb051bGxXaXRob3V0WE1MTlMpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtX05TSW5mb3MucHV0KG1fY2FuZGlkYXRlTm9BbmNlc3RvclhNTE5TLmVsZW1lbnRBdChpKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fTlNJbmZvTnVsbE5vQW5jZXN0b3JYTUxOUyk7Ci0gICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBtX2NhbmRpZGF0ZU5vQW5jZXN0b3JYTUxOUy5yZW1vdmVBbGxFbGVtZW50cygpOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChOb2RlLkFUVFJJQlVURV9OT0RFICE9IG50eXBlKQotICAgICAgewotICAgICAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VPZlByZWZpeCkKLSAgICAgICAgewotICAgICAgICAgIGlmIChhbmNlc3RvcnNIYXZlWE1MTlMpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKG5IYXNYTUxOUykKLSAgICAgICAgICAgICAgbV9OU0luZm9zLnB1dChuLCBtX05TSW5mb051bGxXaXRoWE1MTlMpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICBtX05TSW5mb3MucHV0KG4sIG1fTlNJbmZvTnVsbFdpdGhvdXRYTUxOUyk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX05TSW5mb3MucHV0KG4sIG1fTlNJbmZvTnVsbE5vQW5jZXN0b3JYTUxOUyk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG1fTlNJbmZvcy5wdXQobiwgbmV3IE5TSW5mbyhuYW1lc3BhY2VPZlByZWZpeCwgbkhhc1hNTE5TKSk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmFtZXNwYWNlT2ZQcmVmaXg7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZ2l2ZW4gbm9kZS4gSWYgdGhlIG5vZGUncyBuYW1lIGJlZ2lucwotICAgKiB3aXRoIGEgbmFtZXNwYWNlIHByZWZpeCwgdGhpcyBpcyB0aGUgcGFydCBhZnRlciB0aGUgY29sb247IG90aGVyd2lzZQotICAgKiBpdCdzIHRoZSBmdWxsIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG4gdGhlIG5vZGUgdG8gYmUgZXhhbWluZWQuCi0gICAqCi0gICAqIEByZXR1cm4gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIExvY2FsIE5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxOYW1lT2ZOb2RlKE5vZGUgbikKLSAgewotCi0gICAgU3RyaW5nIHFuYW1lID0gbi5nZXROb2RlTmFtZSgpOwotICAgIGludCBpbmRleCA9IHFuYW1lLmluZGV4T2YoJzonKTsKLQotICAgIHJldHVybiAoaW5kZXggPCAwKSA/IHFuYW1lIDogcW5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgZWxlbWVudCBuYW1lIHdpdGggdGhlIG5hbWVzcGFjZSBwcmVmaXggKGlmIGFueSkgcmVwbGFjZWQKLSAgICogYnkgdGhlIE5hbWVzcGFjZSBVUkkgaXQgd2FzIGJvdW5kIHRvLiBUaGlzIGlzIG5vdCBhIHN0YW5kYXJkIAotICAgKiByZXByZXNlbnRhdGlvbiBvZiBhIG5vZGUgbmFtZSwgYnV0IGl0IGFsbG93cyBjb252ZW5pZW50IAotICAgKiBzaW5nbGUtc3RyaW5nIGNvbXBhcmlzb24gb2YgdGhlICJ1bml2ZXJzYWwiIG5hbWVzIG9mIHR3byBub2Rlcy4KLSAgICoKLSAgICogQHBhcmFtIGVsZW0gRWxlbWVudCB0byBiZSBleGFtaW5lZC4KLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgaW4gdGhlIGZvcm0gIm5hbWVzcGFjZVVSSTpsb2NhbG5hbWUiIGlmIHRoZSBub2RlCi0gICAqIGJlbG9uZ3MgdG8gYSBuYW1lc3BhY2UsIG9yIHNpbXBseSAibG9jYWxuYW1lIiBpZiBpdCBkb2Vzbid0LgotICAgKiBAc2VlICNnZXRFeHBhbmRlZEF0dHJpYnV0ZU5hbWUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0RXhwYW5kZWRFbGVtZW50TmFtZShFbGVtZW50IGVsZW0pCi0gIHsKLQotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2VPZk5vZGUoZWxlbSk7Ci0KLSAgICByZXR1cm4gKG51bGwgIT0gbmFtZXNwYWNlKQotICAgICAgICAgICA/IG5hbWVzcGFjZSArICI6IiArIGdldExvY2FsTmFtZU9mTm9kZShlbGVtKQotICAgICAgICAgICA6IGdldExvY2FsTmFtZU9mTm9kZShlbGVtKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgbmFtZSB3aXRoIHRoZSBuYW1lc3BhY2UgcHJlZml4IChpZiBhbnkpIHJlcGxhY2VkCi0gICAqIGJ5IHRoZSBOYW1lc3BhY2UgVVJJIGl0IHdhcyBib3VuZCB0by4gVGhpcyBpcyBub3QgYSBzdGFuZGFyZCAKLSAgICogcmVwcmVzZW50YXRpb24gb2YgYSBub2RlIG5hbWUsIGJ1dCBpdCBhbGxvd3MgY29udmVuaWVudCAKLSAgICogc2luZ2xlLXN0cmluZyBjb21wYXJpc29uIG9mIHRoZSAidW5pdmVyc2FsIiBuYW1lcyBvZiB0d28gbm9kZXMuCi0gICAqCi0gICAqIEBwYXJhbSBhdHRyIEF0dHIgdG8gYmUgZXhhbWluZWQKLSAgICoKLSAgICogQHJldHVybiBTdHJpbmcgaW4gdGhlIGZvcm0gIm5hbWVzcGFjZVVSSTpsb2NhbG5hbWUiIGlmIHRoZSBub2RlCi0gICAqIGJlbG9uZ3MgdG8gYSBuYW1lc3BhY2UsIG9yIHNpbXBseSAibG9jYWxuYW1lIiBpZiBpdCBkb2Vzbid0LgotICAgKiBAc2VlICNnZXRFeHBhbmRlZEVsZW1lbnROYW1lCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldEV4cGFuZGVkQXR0cmlidXRlTmFtZShBdHRyIGF0dHIpCi0gIHsKLQotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2VPZk5vZGUoYXR0cik7Ci0KLSAgICByZXR1cm4gKG51bGwgIT0gbmFtZXNwYWNlKQotICAgICAgICAgICA/IG5hbWVzcGFjZSArICI6IiArIGdldExvY2FsTmFtZU9mTm9kZShhdHRyKQotICAgICAgICAgICA6IGdldExvY2FsTmFtZU9mTm9kZShhdHRyKTsKLSAgfQotCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAvLyBTRUNUSU9OOiBET00gSGVscGVyIEZ1bmN0aW9ucwotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgbm9kZSBpcyBpZ25vcmFibGUgd2hpdGVzcGFjZS4gTm90ZSB0aGF0IHRoaXMgY2FuCi0gICAqIGJlIGRldGVybWluZWQgb25seSBpbiB0aGUgY29udGV4dCBvZiBhIERURCBvciBvdGhlciBTY2hlbWEsCi0gICAqIGFuZCB0aGF0IERPTSBMZXZlbCAyIGhhcyBub3N0YW5kYXJkaXplZCBET00gQVBJIHdoaWNoIGNhbgotICAgKiByZXR1cm4gdGhhdCBpbmZvcm1hdGlvbi4KLSAgICogQGRlcHJlY2F0ZWQKLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBiZSBleGFtaW5lZAotICAgKgotICAgKiBAcmV0dXJuIENVUlJFTlRMWSBIQVJEQ09ERUQgVE8gRkFMU0UsIGJ1dCBzaG91bGQgcmV0dXJuIHRydWUgaWYKLSAgICogYW5kIG9ubHkgaWYgdGhlIG5vZGUgaXMgb2YgdHlwZSBUZXh0LCBjb250YWlucyBvbmx5IHdoaXRlc3BhY2UsCi0gICAqIGFuZCBkb2VzIG5vdCBhcHBlYXIgYXMgcGFydCBvZiB0aGUgI1BDREFUQSBjb250ZW50IG9mIGFuIGVsZW1lbnQuCi0gICAqIChOb3RlIHRoYXQgZGV0ZXJtaW5pbmcgdGhpcyBsYXN0IG1heSByZXF1aXJlIGFsbG93aW5nIGZvciAKLSAgICogRW50aXR5IFJlZmVyZW5jZXMuKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNJZ25vcmFibGVXaGl0ZXNwYWNlKFRleHQgbm9kZSkKLSAgewotCi0gICAgYm9vbGVhbiBpc0lnbm9yYWJsZSA9IGZhbHNlOyAgLy8gcmV0dXJuIHZhbHVlCi0KLSAgICAvLyBUT0RPOiBJIGNhbiBwcm9iYWJseSBkbyBzb21ldGhpbmcgdG8gZmlndXJlIG91dCBpZiB0aGlzIAotICAgIC8vIHNwYWNlIGlzIGlnbm9yYWJsZSBmcm9tIGp1c3QgdGhlIGluZm9ybWF0aW9uIGluCi0gICAgLy8gdGhlIERPTSB0cmVlLgotICAgICAgICAvLyAtLSBZb3UgbmVlZCB0byBiZSBhYmxlIHRvIGRpc3Rpbmd1aXNoIHdoaXRlc3BhY2UKLSAgICAgICAgLy8gdGhhdCBpcyAjUENEQVRBIGZyb20gd2hpdGVzcGFjZSB0aGF0IGlzbid0LiAgVGhhdCByZXF1aXJlcwotICAgICAgICAvLyBEVEQgc3VwcG9ydCwgd2hpY2ggd29uJ3QgYmUgc3RhbmRhcmRpemVkIHVudGlsIERPTSBMZXZlbCAzLgotICAgIHJldHVybiBpc0lnbm9yYWJsZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZpcnN0IHVucGFyZW50ZWQgbm9kZSBpbiB0aGUgYW5jZXN0b3IgY2hhaW4uCi0gICAqIEBkZXByZWNhdGVkCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFN0YXJ0aW5nIG5vZGUsIHRvIHNwZWNpZnkgd2hpY2ggY2hhaW4gdG8gY2hhc2UKLSAgICoKLSAgICogQHJldHVybiB0aGUgdG9wbW9zdCBhbmNlc3Rvci4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldFJvb3QoTm9kZSBub2RlKQotICB7Ci0KLSAgICBOb2RlIHJvb3QgPSBudWxsOwotCi0gICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkKLSAgICB7Ci0gICAgICByb290ID0gbm9kZTsKLSAgICAgIG5vZGUgPSBnZXRQYXJlbnRPZk5vZGUobm9kZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJvb3Q7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSByb290IG5vZGUgb2YgdGhlIGRvY3VtZW50IHRyZWUsIHJlZ2FyZGxlc3Mgb2YKLSAgICogd2hldGhlciBvciBub3QgdGhlIG5vZGUgcGFzc2VkIGluIGlzIGEgZG9jdW1lbnQgbm9kZS4KLSAgICogPHA+Ci0gICAqIFRPRE86IFRoaXMgZG9lc24ndCBoYW5kbGUgRG9jdW1lbnRGcmFnbWVudHMgb3IgIm9ycGhhbmVkIiBzdWJ0cmVlcwotICAgKiAtLSBpdCdzIGN1cnJlbnRseSByZXR1cm5pbmcgb3duZXJEb2N1bWVudCBldmVuIHdoZW4gdGhlIHRyZWUgaXMKLSAgICogbm90IGFjdHVhbGx5IHBhcnQgb2YgdGhlIG1haW4gRG9jdW1lbnQgdHJlZS4gV2Ugc2hvdWxkIGVpdGhlcgotICAgKiByZXdyaXRlIHRoZSBkZXNjcmlwdGlvbiB0byBzYXkgdGhhdCBpdCBmaW5kcyB0aGUgRG9jdW1lbnQgbm9kZSwKLSAgICogb3IgY2hhbmdlIHRoZSBjb2RlIHRvIHdhbGsgdXAgdGhlIGFuY2VzdG9yIGNoYWluLgotCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgZXhhbWluZWQKLSAgICoKLSAgICogQHJldHVybiB0aGUgRG9jdW1lbnQgbm9kZS4gTm90ZSB0aGF0IHRoaXMgaXMgbm90IHRoZSBjb3JyZWN0IGFuc3dlcgotICAgKiBpZiBuIHdhcyAob3Igd2FzIGEgY2hpbGQgb2YpIGEgRG9jdW1lbnRGcmFnbWVudCBvciBhbiBvcnBoYW5lZCBub2RlLAotICAgKiBhcyBjYW4gYXJpc2UgaWYgdGhlIERPTSBoYXMgYmVlbiBlZGl0ZWQgcmF0aGVyIHRoYW4gYmVpbmcgZ2VuZXJhdGVkCi0gICAqIGJ5IGEgcGFyc2VyLgotICAgKi8KLSAgcHVibGljIE5vZGUgZ2V0Um9vdE5vZGUoTm9kZSBuKQotICB7Ci0gICAgaW50IG50ID0gbi5nZXROb2RlVHlwZSgpOwotICAgIHJldHVybiAoIChOb2RlLkRPQ1VNRU5UX05PREUgPT0gbnQpIHx8IChOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPT0gbnQpICkgCi0gICAgICAgICAgID8gbiA6IG4uZ2V0T3duZXJEb2N1bWVudCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3Qgd2hldGhlciB0aGUgZ2l2ZW4gbm9kZSBpcyBhIG5hbWVzcGFjZSBkZWNsIG5vZGUuIEluIERPTSBMZXZlbCAyCi0gICAqIHRoaXMgY2FuIGJlIGRvbmUgaW4gYSBuYW1lc3BhY2UtYXdhcmUgbWFubmVyLCBidXQgaW4gTGV2ZWwgMSBET01zCi0gICAqIGl0IGhhcyB0byBiZSBkb25lIGJ5IHRlc3RpbmcgdGhlIG5vZGUgbmFtZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBleGFtaW5lZC4KLSAgICoKLSAgICogQHJldHVybiBib29sZWFuIC0tIHRydWUgaWZmIHRoZSBub2RlIGlzIGFuIEF0dHIgd2hvc2UgbmFtZSBpcyAKLSAgICogInhtbG5zIiBvciBoYXMgdGhlICJ4bWxuczoiIHByZWZpeC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlTm9kZShOb2RlIG4pCi0gIHsKLQotICAgIGlmIChOb2RlLkFUVFJJQlVURV9OT0RFID09IG4uZ2V0Tm9kZVR5cGUoKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgYXR0ck5hbWUgPSBuLmdldE5vZGVOYW1lKCk7Ci0KLSAgICAgIHJldHVybiAoYXR0ck5hbWUuc3RhcnRzV2l0aCgieG1sbnM6IikgfHwgYXR0ck5hbWUuZXF1YWxzKCJ4bWxucyIpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIHRoZSBYUGF0aC1tb2RlbCBwYXJlbnQgb2YgYSBET00gbm9kZSAtLSBvd25lckVsZW1lbnQgZm9yIEF0dHJzLAotICAgKiBwYXJlbnQgZm9yIG90aGVyIG5vZGVzLiAKLSAgICogPHA+Ci0gICAqIEJhY2tncm91bmQ6IFRoZSBET00gYmVsaWV2ZXMgdGhhdCB5b3UgbXVzdCBiZSB5b3VyIFBhcmVudCdzCi0gICAqIENoaWxkLCBhbmQgdGh1cyBBdHRycyBkb24ndCBoYXZlIHBhcmVudHMuIFhQYXRoIHNhaWQgdGhhdCBBdHRycwotICAgKiBkbyBoYXZlIHRoZWlyIG93bmluZyBFbGVtZW50IGFzIHRoZWlyIHBhcmVudC4gVGhpcyBmdW5jdGlvbgotICAgKiBicmlkZ2VzIHRoZSBkaWZmZXJlbmNlLCBlaXRoZXIgYnkgdXNpbmcgdGhlIERPTSBMZXZlbCAyIG93bmVyRWxlbWVudAotICAgKiBmdW5jdGlvbiBvciBieSB1c2luZyBhICJzaWxseSBhbmQgZXhwZW5zaXZlIGZ1bmN0aW9uIiBpbiBMZXZlbCAxCi0gICAqIERPTXMuCi0gICAqIDxwPgotICAgKiAoVGhlcmUncyBzb21lIGRpc2N1c3Npb24gb2YgZnV0dXJlIERPTXMgZ2VuZXJhbGl6aW5nIG93bmVyRWxlbWVudCAKLSAgICogaW50byBvd25lck5vZGUgYW5kIG1ha2luZyBpdCB3b3JrIG9uIGFsbCB0eXBlcyBvZiBub2Rlcy4gVGhpcwotICAgKiBzdGlsbCB3b3VsZG4ndCBoZWxwIHRoZSB1c2VycyBvZiBMZXZlbCAxIG9yIExldmVsIDIgRE9NcykKLSAgICogPHA+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgd2hvc2UgWFBhdGggcGFyZW50IHdlIHdhbnQgdG8gb2J0YWluCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBhcmVudCBvZiB0aGUgbm9kZSwgb3IgdGhlIG93bmVyRWxlbWVudCBpZiBpdCdzIGFuCi0gICAqIEF0dHIgbm9kZSwgb3IgbnVsbCBpZiB0aGUgbm9kZSBpcyBhbiBvcnBoYW4uCi0gICAqCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiB0aGUgRG9jdW1lbnQgaGFzIG5vIHJvb3QgZWxlbWVudC4KLSAgICogVGhpcyBjYW4ndCBhcmlzZSBpZiB0aGUgRG9jdW1lbnQgd2FzIGNyZWF0ZWQKLSAgICogdmlhIHRoZSBET00gTGV2ZWwgMiBmYWN0b3J5IG1ldGhvZHMsIGJ1dCBpcyBwb3NzaWJsZSBpZiBvdGhlcgotICAgKiBtZWNoYW5pc21zIHdlcmUgdXNlZCB0byBvYnRhaW4gaXQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBnZXRQYXJlbnRPZk5vZGUoTm9kZSBub2RlKSB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbgotICB7Ci0gICAgTm9kZSBwYXJlbnQ7Ci0gICAgc2hvcnQgbm9kZVR5cGUgPSBub2RlLmdldE5vZGVUeXBlKCk7Ci0KLSAgICBpZiAoTm9kZS5BVFRSSUJVVEVfTk9ERSA9PSBub2RlVHlwZSkKLSAgICB7Ci0gICAgICBEb2N1bWVudCBkb2MgPSBub2RlLmdldE93bmVyRG9jdW1lbnQoKTsKLSAgICAgICAgICAvKgotICAgICAgVEJEOgotICAgICAgaWYobnVsbCA9PSBkb2MpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCwgbnVsbCkpOy8vIkF0dHJpYnV0ZSBjaGlsZCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISIpOwotICAgICAgfQotICAgICAgKi8KLQotICAgICAgICAgIC8vIEdpdmVuIGhvdyBleHBlbnNpdmUgdGhlIHRyZWUgd2FsayBtYXkgYmUsIHdlIHNob3VsZCBmaXJzdCBhc2sgCi0gICAgICAgICAgLy8gd2hldGhlciB0aGlzIERPTSBjYW4gYW5zd2VyIHRoZSBxdWVzdGlvbiBmb3IgdXMuIFRoZSBhZGRpdGlvbmFsCi0gICAgICAgICAgLy8gdGVzdCBkb2VzIHNsb3cgZG93biBMZXZlbCAxIERPTXMgc2xpZ2h0bHkuIERPTUhlbHBlcjIsIHdoaWNoCi0gICAgICAgICAgLy8gaXMgY3VycmVudGx5IHNwZWNpYWxpemVkIGZvciBYZXJjZXMsIGFzc3VtZXMgaXQgY2FuIHVzZSB0aGUKLSAgICAgICAgICAvLyBMZXZlbCAyIHNvbHV0aW9uLiBXZSBtaWdodCB3YW50IHRvIGhhdmUgYW4gaW50ZXJtZWRpYXRlIHN0YWdlLAotICAgICAgICAgIC8vIHdoaWNoIHdvdWxkIGFzc3VtZSBET00gTGV2ZWwgMiBidXQgbm90IGFzc3VtZSBYZXJjZXMuCi0gICAgICAgICAgLy8KLSAgICAgICAgICAvLyAoU2hvdWxkbid0IGhhdmUgdG8gY2hlY2sgd2hldGhlciBpbXBsIGlzIG51bGwgaW4gYSBjb21wbGlhbnQgRE9NLAotICAgICAgICAgIC8vIGJ1dCBsZXQncyBiZSBwYXJhbm9pZCBmb3IgYSBtb21lbnQuLi4pCi0gICAgICAgICAgRE9NSW1wbGVtZW50YXRpb24gaW1wbD1kb2MuZ2V0SW1wbGVtZW50YXRpb24oKTsKLSAgICAgICAgICBpZihpbXBsIT1udWxsICYmIGltcGwuaGFzRmVhdHVyZSgiQ29yZSIsIjIuMCIpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHBhcmVudD0oKEF0dHIpbm9kZSkuZ2V0T3duZXJFbGVtZW50KCk7Ci0gICAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50OwotICAgICAgICAgIH0KLQotICAgICAgICAgIC8vIERPTSBMZXZlbCAxIHNvbHV0aW9uLCBhcyBmYWxsYmFjay4gSHVnZWx5IGV4cGVuc2l2ZS4gCi0KLSAgICAgIEVsZW1lbnQgcm9vdEVsZW0gPSBkb2MuZ2V0RG9jdW1lbnRFbGVtZW50KCk7Ci0KLSAgICAgIGlmIChudWxsID09IHJvb3RFbGVtKQotICAgICAgewotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5ULAotICAgICAgICAgICAgbnVsbCkpOyAgLy8iQXR0cmlidXRlIGNoaWxkIGRvZXMgbm90IGhhdmUgYW4gb3duZXIgZG9jdW1lbnQgZWxlbWVudCEiKTsKLSAgICAgIH0KLQotICAgICAgcGFyZW50ID0gbG9jYXRlQXR0clBhcmVudChyb290RWxlbSwgbm9kZSk7Ci0KLSAgICAgICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBwYXJlbnQgPSBub2RlLmdldFBhcmVudE5vZGUoKTsKLQotICAgICAgLy8gaWYoKE5vZGUuRE9DVU1FTlRfTk9ERSAhPSBub2RlVHlwZSkgJiYgKG51bGwgPT0gcGFyZW50KSkKLSAgICAgIC8vIHsKLSAgICAgIC8vICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkNoaWxkIGRvZXMgbm90IGhhdmUgcGFyZW50ISIpOwotICAgICAgLy8gfQotICAgIH0KLQotICAgIHJldHVybiBwYXJlbnQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gSUQsIHJldHVybiB0aGUgZWxlbWVudC4gVGhpcyBjYW4gd29yayBvbmx5IGlmIHRoZSBkb2N1bWVudAotICAgKiBpcyBpbnRlcnByZXRlZCBpbiB0aGUgY29udGV4dCBvZiBhIERURCBvciBTY2hlbWEsIHNpbmNlIG90aGVyd2lzZQotICAgKiB3ZSBkb24ndCBrbm93IHdoaWNoIGF0dHJpYnV0ZXMgYXJlIG9yIGFyZW4ndCBJRHMuCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgRE9NIExldmVsIDEgaGFkIG5vIGFiaWxpdHkgdG8gcmV0cmlldmUgdGhpcyBpbmZvcm1hdGlvbi4KLSAgICogRE9NIExldmVsIDIgaW50cm9kdWNlZCBpdCBidXQgZG9lcyBub3QgcHJvbWlzZSB0aGF0IGl0IHdpbGwgYmUKLSAgICogc3VwcG9ydGVkIGluIGFsbCBET01zOyB0aG9zZSB3aGljaCBjYW4ndCBzdXBwb3J0IGl0IHdpbGwgYWx3YXlzCi0gICAqIHJldHVybiBudWxsLgotICAgKiA8cD4KLSAgICogVE9ETzogZ2V0RWxlbWVudEJ5SUQgaXMgY3VycmVudGx5IHVuaW1wbGVtZW50ZWQuIFN1cHBvcnQgRE9NIExldmVsIDI/Ci0gICAqCi0gICAqIEBwYXJhbSBpZCBUaGUgdW5pcXVlIGlkZW50aWZpZXIgdG8gYmUgc2VhcmNoZWQgZm9yLgotICAgKiBAcGFyYW0gZG9jIFRoZSBkb2N1bWVudCB0byBzZWFyY2ggd2l0aGluLgotICAgKiBAcmV0dXJuIENVUlJFTlRMWSBIQVJEQ09ERUQgVE8gTlVMTCwgYnV0IGl0IHNob3VsZCBiZToKLSAgICogVGhlIG5vZGUgd2hpY2ggaGFzIHRoaXMgdW5pcXVlIGlkZW50aWZpZXIsIG9yIG51bGwgaWYgdGhlcmUKLSAgICogaXMgbm8gc3VjaCBub2RlIG9yIHRoaXMgRE9NIGNhbid0IHJlbGlhYmx5IHJlY29nbml6ZSBpdC4KLSAgICovCi0gIHB1YmxpYyBFbGVtZW50IGdldEVsZW1lbnRCeUlEKFN0cmluZyBpZCwgRG9jdW1lbnQgZG9jKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGdldFVucGFyc2VkRW50aXR5VVJJIGZ1bmN0aW9uIHJldHVybnMgdGhlIFVSSSBvZiB0aGUgdW5wYXJzZWQKLSAgICogZW50aXR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGluIHRoZSBzYW1lIGRvY3VtZW50IGFzIHRoZSBjb250ZXh0Ci0gICAqIG5vZGUgKHNlZSBbMy4zIFVucGFyc2VkIEVudGl0aWVzXSkuIEl0IHJldHVybnMgdGhlIGVtcHR5IHN0cmluZyBpZgotICAgKiB0aGVyZSBpcyBubyBzdWNoIGVudGl0eS4KLSAgICogPHA+Ci0gICAqIFhNTCBwcm9jZXNzb3JzIG1heSBjaG9vc2UgdG8gdXNlIHRoZSBTeXN0ZW0gSWRlbnRpZmllciAoaWYgb25lCi0gICAqIGlzIHByb3ZpZGVkKSB0byByZXNvbHZlIHRoZSBlbnRpdHksIHJhdGhlciB0aGFuIHRoZSBVUkkgaW4gdGhlCi0gICAqIFB1YmxpYyBJZGVudGlmaWVyLiBUaGUgZGV0YWlscyBhcmUgZGVwZW5kZW50IG9uIHRoZSBwcm9jZXNzb3IsIGFuZAotICAgKiB3ZSB3b3VsZCBoYXZlIHRvIHN1cHBvcnQgc29tZSBmb3JtIG9mIHBsdWctaW4gcmVzb2x2ZXIgdG8gaGFuZGxlCi0gICAqIHRoaXMgcHJvcGVybHkuIEN1cnJlbnRseSwgd2Ugc2ltcGx5IHJldHVybiB0aGUgU3lzdGVtIElkZW50aWZpZXIgaWYKLSAgICogcHJlc2VudCwgYW5kIGhvcGUgdGhhdCBpdCBhIHVzYWJsZSBVUkkgb3IgdGhhdCBvdXIgY2FsbGVyIGNhbgotICAgKiBtYXAgaXQgdG8gb25lLgotICAgKiBUT0RPOiBSZXNvbHZlIFB1YmxpYyBJZGVudGlmaWVycy4uLiBvciBjb25zaWRlciBjaGFuZ2luZyBmdW5jdGlvbiBuYW1lLgotICAgKiA8cD4KLSAgICogSWYgd2UgZmluZCBhIHJlbGF0aXZlIFVSSSAKLSAgICogcmVmZXJlbmNlLCBYTUwgZXhwZWN0cyBpdCB0byBiZSByZXNvbHZlZCBpbiB0ZXJtcyBvZiB0aGUgYmFzZSBVUkkgCi0gICAqIG9mIHRoZSBkb2N1bWVudC4gVGhlIERPTSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLCBhbmQgaXQgaXNuJ3QgCi0gICAqIGVudGlyZWx5IGNsZWFyIHdoZXRoZXIgdGhhdCBzaG91bGQgYmUgZG9uZSBoZXJlOyBjdXJyZW50bHkgdGhhdCdzCi0gICAqIHB1c2hlZCB1cCB0byBhIGhpZ2hlciBsZXZlbG9mIG91ciBhcHBsaWNhdGlvbi4gKE5vdGUgdGhhdCBET00gTGV2ZWwgCi0gICAqIDEgZGlkbid0IHN0b3JlIHRoZSBkb2N1bWVudCdzIGJhc2UgVVJJLikKLSAgICogVE9ETzogQ29uc2lkZXIgcmVzb2x2aW5nIFJlbGF0aXZlIFVSSXMuCi0gICAqIDxwPgotICAgKiAoVGhlIERPTSdzIHN0YXRlbWVudCB0aGF0ICJBbiBYTUwgcHJvY2Vzc29yIG1heSBjaG9vc2UgdG8KLSAgICogY29tcGxldGVseSBleHBhbmQgZW50aXRpZXMgYmVmb3JlIHRoZSBzdHJ1Y3R1cmUgbW9kZWwgaXMgcGFzc2VkCi0gICAqIHRvIHRoZSBET00iIHJlZmVycyBvbmx5IHRvIHBhcnNlZCBlbnRpdGllcywgbm90IHVucGFyc2VkLCBhbmQgaGVuY2UKLSAgICogZG9lc24ndCBhZmZlY3QgdGhpcyBmdW5jdGlvbi4pCi0gICAqCi0gICAqIEBwYXJhbSBuYW1lIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIEVudGl0eSBOYW1lIG9mIHRoZSB1bnBhcnNlZAotICAgKiBlbnRpdHkuCi0gICAqIEBwYXJhbSBkb2MgRG9jdW1lbnQgbm9kZSBmb3IgdGhlIGRvY3VtZW50IHRvIGJlIHNlYXJjaGVkLgotICAgKgotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIHRoZSBVUkkgb2YgdGhlIFVucGFyc2VkIEVudGl0eSwgb3IgYW4KLSAgICogZW1wdHkgc3RyaW5nIGlmIG5vIHN1Y2ggZW50aXR5IGV4aXN0cy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VW5wYXJzZWRFbnRpdHlVUkkoU3RyaW5nIG5hbWUsIERvY3VtZW50IGRvYykKLSAgewotCi0gICAgU3RyaW5nIHVybCA9ICIiOwotICAgIERvY3VtZW50VHlwZSBkb2N0eXBlID0gZG9jLmdldERvY3R5cGUoKTsKLQotICAgIGlmIChudWxsICE9IGRvY3R5cGUpCi0gICAgewotICAgICAgTmFtZWROb2RlTWFwIGVudGl0aWVzID0gZG9jdHlwZS5nZXRFbnRpdGllcygpOwotICAgICAgaWYobnVsbCA9PSBlbnRpdGllcykKLSAgICAgICAgcmV0dXJuIHVybDsKLSAgICAgIEVudGl0eSBlbnRpdHkgPSAoRW50aXR5KSBlbnRpdGllcy5nZXROYW1lZEl0ZW0obmFtZSk7Ci0gICAgICBpZihudWxsID09IGVudGl0eSkKLSAgICAgICAgcmV0dXJuIHVybDsKLSAgICAgIAotICAgICAgU3RyaW5nIG5vdGF0aW9uTmFtZSA9IGVudGl0eS5nZXROb3RhdGlvbk5hbWUoKTsKLQotICAgICAgaWYgKG51bGwgIT0gbm90YXRpb25OYW1lKSAgLy8gdGhlbiBpdCdzIHVucGFyc2VkCi0gICAgICB7Ci0gICAgICAgIC8vIFRoZSBkcmFmdCBzYXlzOiAiVGhlIFhTTFQgcHJvY2Vzc29yIG1heSB1c2UgdGhlIHB1YmxpYyAKLSAgICAgICAgLy8gaWRlbnRpZmllciB0byBnZW5lcmF0ZSBhIFVSSSBmb3IgdGhlIGVudGl0eSBpbnN0ZWFkIG9mIHRoZSBVUkkgCi0gICAgICAgIC8vIHNwZWNpZmllZCBpbiB0aGUgc3lzdGVtIGlkZW50aWZpZXIuIElmIHRoZSBYU0xUIHByb2Nlc3NvciBkb2VzIAotICAgICAgICAvLyBub3QgdXNlIHRoZSBwdWJsaWMgaWRlbnRpZmllciB0byBnZW5lcmF0ZSB0aGUgVVJJLCBpdCBtdXN0IHVzZSAKLSAgICAgICAgLy8gdGhlIHN5c3RlbSBpZGVudGlmaWVyOyBpZiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgaXMgYSByZWxhdGl2ZSAKLSAgICAgICAgLy8gVVJJLCBpdCBtdXN0IGJlIHJlc29sdmVkIGludG8gYW4gYWJzb2x1dGUgVVJJIHVzaW5nIHRoZSBVUkkgb2YgCi0gICAgICAgIC8vIHRoZSByZXNvdXJjZSBjb250YWluaW5nIHRoZSBlbnRpdHkgZGVjbGFyYXRpb24gYXMgdGhlIGJhc2UgCi0gICAgICAgIC8vIFVSSSBbUkZDMjM5Nl0uIgotICAgICAgICAvLyBTbyBJJ20gZmFsbGluZyBhIGJpdCBzaG9ydCBoZXJlLgotICAgICAgICB1cmwgPSBlbnRpdHkuZ2V0U3lzdGVtSWQoKTsKLQotICAgICAgICBpZiAobnVsbCA9PSB1cmwpCi0gICAgICAgIHsKLSAgICAgICAgICB1cmwgPSBlbnRpdHkuZ2V0UHVibGljSWQoKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAvLyBUaGlzIHNob3VsZCBiZSByZXNvbHZlZCB0byBhbiBhYnNvbHV0ZSBVUkwsIGJ1dCB0aGF0J3MgaGFyZCAKLSAgICAgICAgICAvLyB0byBkbyBmcm9tIGhlcmUuCi0gICAgICAgIH0gICAgICAgIAotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiB1cmw7Ci0gIH0KLQotICAvKioKLSAgICogU3VwcG9ydCBmb3IgZ2V0UGFyZW50T2ZOb2RlOyB3YWxrcyBhIERPTSB0cmVlIHVudGlsIGl0IGZpbmRzCi0gICAqIHRoZSBFbGVtZW50IHdoaWNoIG93bnMgdGhlIEF0dHIuIFRoaXMgaXMgaHVnZWx5IGV4cGVuc2l2ZSwgYW5kCi0gICAqIGlmIGF0IGFsbCBwb3NzaWJsZSB5b3Ugc2hvdWxkIHVzZSB0aGUgRE9NIExldmVsIDIgQXR0ci5vd25lckVsZW1lbnQoKQotICAgKiBtZXRob2QgaW5zdGVhZC4KLSAgICogIDxwPgotICAgKiBUaGUgRE9NIExldmVsIDEgZGV2ZWxvcGVycyBleHBlY3RlZCB0aGF0IGZvbGtzIHdvdWxkIGtlZXAgdHJhY2sKLSAgICogb2YgdGhlIGxhc3QgRWxlbWVudCB0aGV5J2Qgc2VlbiBhbmQgY291bGQgcmVjb3ZlciB0aGUgaW5mbyBmcm9tCi0gICAqIHRoYXQgc291cmNlLiBPYnZpb3VzbHkgdGhhdCBkb2Vzbid0IHdvcmsgdmVyeSB3ZWxsIGlmIHRoZSBvbmx5Ci0gICAqIGluZm9ybWF0aW9uIHlvdSd2ZSBiZWVuIHByZXNlbnRlZCB3aXRoIGlzIHRoZSBBdHRyLiBUaGUgRE9NIExldmVsIDIKLSAgICogZ2V0T3duZXJFbGVtZW50KCkgbWV0aG9kIGZpeGVzIHRoYXQsIGJ1dCBvbmx5IGZvciBMZXZlbCAyIGFuZAotICAgKiBsYXRlciBET01zLgotICAgKgotICAgKiBAcGFyYW0gZWxlbSBFbGVtZW50IHdob3NlIHN1YnRyZWUgaXMgdG8gYmUgc2VhcmNoZWQgZm9yIHRoaXMgQXR0cgotICAgKiBAcGFyYW0gYXR0ciBBdHRyIHdob3NlIG93bmVyIGlzIHRvIGJlIGxvY2F0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGZpcnN0IEVsZW1lbnQgd2hvc2UgYXR0cmlidXRlIGxpc3QgaW5jbHVkZXMgdGhlIHByb3ZpZGVkCi0gICAqIGF0dHIuIEluIG1vZGVybiBET01zLCB0aGlzIHdpbGwgYWxzbyBiZSB0aGUgb25seSBzdWNoIEVsZW1lbnQuIChFYXJseQotICAgKiBET01zIGhhZCBzb21lIGhvcGUgdGhhdCBBdHRycyBtaWdodCBiZSBzaGFyYWJsZSwgYnV0IHRoaXMgaWRlYSBoYXMKLSAgICogYmVlbiBhYmFuZG9uZWQuKQotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgTm9kZSBsb2NhdGVBdHRyUGFyZW50KEVsZW1lbnQgZWxlbSwgTm9kZSBhdHRyKQotICB7Ci0KLSAgICBOb2RlIHBhcmVudCA9IG51bGw7Ci0KLSAgICAgICAgLy8gVGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgZm9yIExldmVsIDEgRE9Ncywgc28gd2UgZG9uJ3QgaGF2ZSB0bwotICAgICAgICAvLyB3b3JyeSBhYm91dCBuYW1lc3BhY2UgaXNzdWVzLiBJbiBsYXRlciBsZXZlbHMsIGl0J3MgcG9zc2libGUKLSAgICAgICAgLy8gZm9yIGEgRE9NIHRvIGhhdmUgdHdvIEF0dHJzIHdpdGggdGhlIHNhbWUgTm9kZU5hbWUgYnV0Ci0gICAgICAgIC8vIGRpZmZlcmVudCBuYW1lc3BhY2VzLCBhbmQgd2UnZCBuZWVkIHRvIGdldCBnZXRBdHRyaWJ1dGVOb2RlTlMuLi4KLSAgICAgICAgLy8gYnV0IGxhdGVyIGxldmVscyBhbHNvIGhhdmUgQXR0ci5nZXRPd25lckVsZW1lbnQuCi0gICAgICAgIEF0dHIgY2hlY2s9ZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKGF0dHIuZ2V0Tm9kZU5hbWUoKSk7Ci0gICAgICAgIGlmKGNoZWNrPT1hdHRyKQotICAgICAgICAgICAgICAgIHBhcmVudCA9IGVsZW07Ci0KLSAgICBpZiAobnVsbCA9PSBwYXJlbnQpCi0gICAgewotICAgICAgZm9yIChOb2RlIG5vZGUgPSBlbGVtLmdldEZpcnN0Q2hpbGQoKTsgbnVsbCAhPSBub2RlOwotICAgICAgICAgICAgICBub2RlID0gbm9kZS5nZXROZXh0U2libGluZygpKQotICAgICAgewotICAgICAgICBpZiAoTm9kZS5FTEVNRU5UX05PREUgPT0gbm9kZS5nZXROb2RlVHlwZSgpKQotICAgICAgICB7Ci0gICAgICAgICAgcGFyZW50ID0gbG9jYXRlQXR0clBhcmVudCgoRWxlbWVudCkgbm9kZSwgYXR0cik7Ci0KLSAgICAgICAgICBpZiAobnVsbCAhPSBwYXJlbnQpCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBwYXJlbnQ7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGZhY3Rvcnkgb2JqZWN0IHVzZWQgZm9yIGNyZWF0aW5nIG5vZGVzCi0gICAqIGluIHRoZSByZXN1bHQgdHJlZS4KLSAgICovCi0gIHByb3RlY3RlZCBEb2N1bWVudCBtX0RPTUZhY3RvcnkgPSBudWxsOwotCi0gIC8qKgotICAgKiBTdG9yZSB0aGUgZmFjdG9yeSBvYmplY3QgcmVxdWlyZWQgdG8gY3JlYXRlIERPTSBub2RlcwotICAgKiBpbiB0aGUgcmVzdWx0IHRyZWUuIEluIGZhY3QsIHRoYXQncyBqdXN0IHRoZSByZXN1bHQgdHJlZSdzCi0gICAqIERvY3VtZW50IG5vZGUuLi4KLSAgICoKLSAgICogQHBhcmFtIGRvbUZhY3RvcnkgVGhlIERPTSBEb2N1bWVudCBOb2RlIHdpdGhpbiB3aG9zZSBjb250ZXh0Ci0gICAqIHRoZSByZXN1bHQgdHJlZSB3aWxsIGJlIGJ1aWx0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RE9NRmFjdG9yeShEb2N1bWVudCBkb21GYWN0b3J5KQotICB7Ci0gICAgdGhpcy5tX0RPTUZhY3RvcnkgPSBkb21GYWN0b3J5OwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSBmYWN0b3J5IG9iamVjdCByZXF1aXJlZCB0byBjcmVhdGUgRE9NIG5vZGVzCi0gICAqIGluIHRoZSByZXN1bHQgdHJlZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IHRyZWUncyBET00gRG9jdW1lbnQgTm9kZS4KLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudCBnZXRET01GYWN0b3J5KCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gdGhpcy5tX0RPTUZhY3RvcnkpCi0gICAgewotICAgICAgdGhpcy5tX0RPTUZhY3RvcnkgPSBjcmVhdGVEb2N1bWVudCgpOwotICAgIH0KLQotICAgIHJldHVybiB0aGlzLm1fRE9NRmFjdG9yeTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHRleHR1YWwgY29udGVudHMgb2YgdGhlIG5vZGUuIFNlZQotICAgKiBnZXROb2RlRGF0YShOb2RlLEZhc3RTdHJpbmdCdWZmZXIpIGZvciBkaXNjdXNzaW9uIG9mIGhvdwotICAgKiB3aGl0ZXNwYWNlIG5vZGVzIGFyZSBoYW5kbGVkLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBET00gTm9kZSB0byBiZSBleGFtaW5lZAotICAgKiBAcmV0dXJuIFN0cmluZyBjb250YWluaW5nIGEgY29uY2F0ZW5hdGlvbiBvZiBhbGwgdGhlIAotICAgKiB0ZXh0dWFsIGNvbnRlbnQgd2l0aGluIHRoYXQgbm9kZS4gCi0gICAqIEBzZWUgI2dldE5vZGVEYXRhKE5vZGUsRmFzdFN0cmluZ0J1ZmZlcikKLSAgICogCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXROb2RlRGF0YShOb2RlIG5vZGUpCi0gIHsKLQotICAgIEZhc3RTdHJpbmdCdWZmZXIgYnVmID0gU3RyaW5nQnVmZmVyUG9vbC5nZXQoKTsKLSAgICBTdHJpbmcgczsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGdldE5vZGVEYXRhKG5vZGUsIGJ1Zik7Ci0KLSAgICAgIHMgPSAoYnVmLmxlbmd0aCgpID4gMCkgPyBidWYudG9TdHJpbmcoKSA6ICIiOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgU3RyaW5nQnVmZmVyUG9vbC5mcmVlKGJ1Zik7Ci0gICAgfQotCi0gICAgcmV0dXJuIHM7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmUgdGhlIHRleHQgY29udGVudCBvZiBhIERPTSBzdWJ0cmVlLCBhcHBlbmRpbmcgaXQgaW50byBhCi0gICAqIHVzZXItc3VwcGxpZWQgRmFzdFN0cmluZ0J1ZmZlciBvYmplY3QuIE5vdGUgdGhhdCBhdHRyaWJ1dGVzIGFyZQotICAgKiBub3QgY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQuCi0gICAqIDxwPgotICAgKiBUaGVyZSBhcmUgb3BlbiBxdWVzdGlvbnMgcmVnYXJkaW5nIHdoaXRlc3BhY2Ugc3RyaXBwaW5nLiAKLSAgICogQ3VycmVudGx5IHdlIG1ha2Ugbm8gc3BlY2lhbCBlZmZvcnQgaW4gdGhhdCByZWdhcmQsIHNpbmNlIHRoZSBzdGFuZGFyZAotICAgKiBET00gZG9lc24ndCB5ZXQgcHJvdmlkZSBEVEQtYmFzZWQgaW5mb3JtYXRpb24gdG8gZGlzdGluZ3Vpc2gKLSAgICogd2hpdGVzcGFjZS1pbi1lbGVtZW50LWNvbnRleHQgZnJvbSBnZW51aW5lICNQQ0RBVEEuIE5vdGUgdGhhdCB3ZQotICAgKiBzaG91bGQgcHJvYmFibHkgYWxzbyBjb25zaWRlciB4bWw6c3BhY2UgaWYvd2hlbiB3ZSBhZGRyZXNzIHRoaXMuCi0gICAqIERPTSBMZXZlbCAzIG1heSBzb2x2ZSB0aGUgcHJvYmxlbSBmb3IgdXMuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgd2hvc2Ugc3VidHJlZSBpcyB0byBiZSB3YWxrZWQsIGdhdGhlcmluZyB0aGUKLSAgICogY29udGVudHMgb2YgYWxsIFRleHQgb3IgQ0RBVEFTZWN0aW9uIG5vZGVzLgotICAgKiBAcGFyYW0gYnVmIEZhc3RTdHJpbmdCdWZmZXIgaW50byB3aGljaCB0aGUgY29udGVudHMgb2YgdGhlIHRleHQKLSAgICogbm9kZXMgYXJlIHRvIGJlIGNvbmNhdGVuYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgdm9pZCBnZXROb2RlRGF0YShOb2RlIG5vZGUsIEZhc3RTdHJpbmdCdWZmZXIgYnVmKQotICB7Ci0KLSAgICBzd2l0Y2ggKG5vZGUuZ2V0Tm9kZVR5cGUoKSkKLSAgICB7Ci0gICAgY2FzZSBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgOgotICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9OT0RFIDoKLSAgICBjYXNlIE5vZGUuRUxFTUVOVF9OT0RFIDoKLSAgICB7Ci0gICAgICBmb3IgKE5vZGUgY2hpbGQgPSBub2RlLmdldEZpcnN0Q2hpbGQoKTsgbnVsbCAhPSBjaGlsZDsKLSAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5nZXROZXh0U2libGluZygpKQotICAgICAgewotICAgICAgICBnZXROb2RlRGF0YShjaGlsZCwgYnVmKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLlRFWFRfTk9ERSA6Ci0gICAgY2FzZSBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERSA6Ci0gICAgICBidWYuYXBwZW5kKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBOb2RlLkFUVFJJQlVURV9OT0RFIDoKLSAgICAgIGJ1Zi5hcHBlbmQobm9kZS5nZXROb2RlVmFsdWUoKSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFIDoKLSAgICAgIC8vIHdhcm5pbmcoWFBBVEhFcnJvclJlc291cmNlcy5XR19QQVJTSU5HX0FORF9QUkVQQVJJTkcpOyAgICAgICAgCi0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIC8vIGlnbm9yZQotICAgICAgYnJlYWs7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9ET01PcmRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvRE9NT3JkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmJkODMyOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9ET01PcmRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aDsKLQotLyoqCi0gKiBAZGVwcmVjYXRlZCBTaW5jZSB0aGUgaW50cm9kdWN0aW9uIG9mIHRoZSBEVE0sIHRoaXMgY2xhc3Mgd2lsbCBiZSByZW1vdmVkLgotICogTm9kZXMgdGhhdCBpbXBsZW1lbnQgdGhpcyBpbmRleCBjYW4gcmV0dXJuIGEgZG9jdW1lbnQgb3JkZXIgaW5kZXguCi0gKiBFdmVudHVhbGx5LCB0aGlzIHdpbGwgYmUgcmVwbGFjZWQgYnkgRE9NIDMgbWV0aG9kcy4gCi0gKiAoY29tcGFyZURvY3VtZW50T3JkZXIgYW5kL29yIGNvbXBhcmVUcmVlUG9zaXRpb24uKQotICovCi1wdWJsaWMgaW50ZXJmYWNlIERPTU9yZGVyCi17Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgVUlEIChkb2N1bWVudCBvcmRlciBpbmRleCkuCi0gICAqCi0gICAqIEByZXR1cm4gaW50ZWdlciB3aG9zZSByZWxhdGl2ZSB2YWx1ZSBjb3JyZXNwb25kcyB0byBkb2N1bWVudCBvcmRlcgotICAgKiAtLSB0aGF0IGlzLCBpZiBub2RlMS5nZXRVaWQoKTxub2RlMi5nZXRVaWQoKSwgbm9kZTEgY29tZXMgYmVmb3JlCi0gICAqIG5vZGUyLCBhbmQgaWYgdGhleSdyZSBlcXVhbCBub2RlMSBhbmQgbm9kZTIgYXJlIHRoZSBzYW1lIG5vZGUuIE5vCi0gICAqIHByb21pc2VzIGFyZSBtYWRlIGJleW9uZCB0aGF0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRVaWQoKTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL0V4cHJlc3Npb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL0V4cHJlc3Npb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjFhYjM3ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9FeHByZXNzaW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MTcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aDsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlNBWFNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLQotLyoqCi0gKiBUaGlzIGFic3RyYWN0IGNsYXNzIHNlcnZlcyBhcyB0aGUgYmFzZSBmb3IgYWxsIGV4cHJlc3Npb24gb2JqZWN0cy4gIEFuCi0gKiBFeHByZXNzaW9uIGNhbiBiZSBleGVjdXRlZCB0byByZXR1cm4gYSB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3R9LAotICogbm9ybWFsbHkgaGFzIGEgbG9jYXRpb24gd2l0aGluIGEgZG9jdW1lbnQgb3IgRE9NLCBjYW4gc2VuZCBlcnJvciBhbmQgd2FybmluZwotICogZXZlbnRzLCBhbmQgbm9ybWFsbHkgZG8gbm90IGhvbGQgc3RhdGUgYW5kIGFyZSBtZWFudCB0byBiZSBpbW11dGFibGUgb25jZQotICogY29uc3RydWN0aW9uIGhhcyBjb21wbGV0ZWQuICBBbiBleGNlcHRpb24gdG8gdGhlIGltbXV0aWJpbGl0eSBydWxlIGlzIGl0ZXJhdG9ycwotICogYW5kIHdhbGtlcnMsIHdoaWNoIG11c3QgYmUgY2xvbmVkIGluIG9yZGVyIHRvIGJlIHVzZWQgLS0gdGhlIG9yaWdpbmFsIG11c3QKLSAqIHN0aWxsIGJlIGltbXV0YWJsZS4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEV4cHJlc3Npb24gaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZQotewotCi0gIC8qKgotICAgKiBUaGUgbG9jYXRpb24gd2hlcmUgdGhpcyBleHByZXNzaW9uIHdhcyBidWlsdCBmcm9tLiAgTmVlZCBmb3IgZGlhZ25vc3RpYwotICAgKiAgbWVzc2FnZXMuIE1heSBiZSBudWxsLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgcHJvdGVjdGVkIFNvdXJjZUxvY2F0b3IgbV9zbG9jYXRvcjsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZQotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsb2NhdGlvbiB3aGVyZSB0aGlzIGV4cHJlc3Npb24gd2FzIGJ1aWx0IGZyb20uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhdG9yIHRoZSBsb2NhdGlvbiB3aGVyZSB0aGlzIGV4cHJlc3Npb24gd2FzIGJ1aWx0IGZyb20sIG1heSBiZQotICAgKiAgICAgICAgICAgICAgICBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U291cmNlTG9jYXRvcihTb3VyY2VMb2NhdG9yIGxvY2F0b3IpCi0gIHsKLSAgICBtX3Nsb2NhdG9yID0gbG9jYXRvcjsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGFuIGV4cHJlc3Npb24gaW4gdGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCwgYW5kIHJldHVybiB0aGUKLSAgICogcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIGN1cnJlbnROb2RlIFRoZSBjdXJyZW50Tm9kZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uIGluIHRoZSBmb3JtIG9mIGEgPGNvZGU+WE9iamVjdDwvY29kZT4uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIHJ1bnRpbWUgZXhjZXB0aW9uCi0gICAqICAgICAgICAgb2NjdXJzLgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQsIGludCBjdXJyZW50Tm9kZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBGb3Igbm93LCB0aGUgY3VycmVudCBub2RlIGlzIGFscmVhZHkgcHVzaGVkLgotICAgIHJldHVybiBleGVjdXRlKHhjdHh0KTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGFuIGV4cHJlc3Npb24gaW4gdGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCwgYW5kIHJldHVybiB0aGUKLSAgICogcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIGN1cnJlbnROb2RlIFRoZSBjdXJyZW50Tm9kZS4KLSAgICogQHBhcmFtIGR0bSBUaGUgRFRNIG9mIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqIEBwYXJhbSBleHBUeXBlIFRoZSBleHBhbmRlZCB0eXBlIElEIG9mIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgZm9ybSBvZiBhIDxjb2RlPlhPYmplY3Q8L2NvZGU+LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBydW50aW1lIGV4Y2VwdGlvbgotICAgKiAgICAgICAgIG9jY3Vycy4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY3VycmVudE5vZGUsIERUTSBkdG0sIGludCBleHBUeXBlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gRm9yIG5vdywgdGhlIGN1cnJlbnQgbm9kZSBpcyBhbHJlYWR5IHB1c2hlZC4KLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhbiBleHByZXNzaW9uIGluIHRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQsIGFuZCByZXR1cm4gdGhlCi0gICAqIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgZm9ybSBvZiBhIDxjb2RlPlhPYmplY3Q8L2NvZGU+LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBydW50aW1lIGV4Y2VwdGlvbgotICAgKiAgICAgICAgIG9jY3Vycy4KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBFdmFsdWF0ZSBleHByZXNzaW9uIHRvIGEgbnVtYmVyLgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0geGN0eHQKLSAgICogQHJldHVybiAwLjAKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBleGVjdXRlKHhjdHh0KS5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBFdmFsdWF0ZSBleHByZXNzaW9uIHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIHhjdHh0Ci0gICAqIEByZXR1cm4gZmFsc2UKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQpLmJvb2woKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB4Y3R4dAotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdGhpcyB3cmFwcyBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG51bGwKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHhzdHIoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCkueHN0cigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBub2Rlc2V0IGV4cHJlc3Npb24uICBJbiBvdGhlciB3b3JkcywgdGVsbAotICAgKiBpZiB5b3UgY2FuIGV4ZWN1dGUge0BsaW5rIGFzTm9kZSgpIGFzTm9kZX0gd2l0aG91dCBhbiBleGNlcHRpb24uCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZXhwcmVzc2lvbiBjYW4gYmUgcmVwcmVzZW50ZWQgYXMgYSBub2Rlc2V0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2Rlc2V0RXhwcigpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgaWYgdGhpcyBleHByZXNzaW9uIGlzCi0gICAqIGEgbm9kZXNldCBleHByZXNzaW9uLgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIG9yIERUTS5OVUxMLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBpbnQgYXNOb2RlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGV4ZWN1dGUoeGN0eHQpLml0ZXIoKS5uZXh0Tm9kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJleHBlcmltZW50YWwiLz4KLSAgICogR2l2ZW4gYW4gc2VsZWN0IGV4cHJlc3Npb24gYW5kIGEgY29udGV4dCwgZXZhbHVhdGUgdGhlIFhQYXRoCi0gICAqIGFuZCByZXR1cm4gdGhlIHJlc3VsdGluZyBpdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRoYXQgIi4iIGV4cHJlc3Nlcy4KLSAgICoKLSAgICoKLSAgICogTkVFRFNET0MgKCRvYmplY3ROYW1lJCkgQHJldHVybgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBkZWNpZGVzCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGFzSXRlcmF0b3IoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dE5vZGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbihjb250ZXh0Tm9kZSwgY29udGV4dE5vZGUpOwotCi0gICAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCkuaXRlcigpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYW4gZXhwcmVzc2lvbiBpbiB0aGUgWFBhdGggcnVudGltZSBjb250ZXh0LCBhbmQgcmV0dXJuIHRoZQotICAgKiByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBORUVEU0RPQyBAcGFyYW0gaGFuZGxlcgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGZvcm0gb2YgYSA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgcnVudGltZSBleGNlcHRpb24KLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlQ2hhcnNUb0NvbnRlbnRIYW5kbGVyKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uLAotICAgICAgICAgICAgICAgICAgIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IG9iaiA9IGV4ZWN1dGUoeGN0eHQpOwotCi0gICAgb2JqLmRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhoYW5kbGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiByZXR1cm5zIGEgc3RhYmxlIG51bWJlciB0aGF0IHdpbGwgbm90IGNoYW5nZSBkdXJpbmcgCi0gICAqIGl0ZXJhdGlvbnMgd2l0aGluIHRoZSBleHByZXNzaW9uLiAgVGhpcyBpcyB1c2VkIHRvIGRldGVybWluZSBpZiBhIHByb3hpbWl0eSAKLSAgICogcG9zaXRpb24gcHJlZGljYXRlIGNhbiBpbmRpY2F0ZSB0aGF0IG5vIG1vcmUgc2VhcmNoaW5nIGhhcyB0byBvY2N1ci4KLSAgICogCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZXhwcmVzc2lvbiByZXByZXNlbnRzIGEgc3RhYmxlIG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3RhYmxlTnVtYmVyKCkKLSAgewotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0Ci0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0Ci0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbgotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqIE5FRURTRE9DIEBwYXJhbSBnbG9iYWxzU2l6ZQotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpOwotCi0gIC8qKgotICAgKiBXYXJuIHRoZSB1c2VyIG9mIGFuIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gbXNnIEFuIGVycm9yIG51bWJlciB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgbnVtYmVycyBmb3VuZAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoCi0gICAqICAgICAgICAgICAgIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IEVycm9yTGlzdG9uZXIgZGV0ZXJtaW5lcyB0bwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCB3YXJuKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IG1zZywgT2JqZWN0W10gYXJncykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBqYXZhLmxhbmcuU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSFdhcm5pbmcobXNnLCBhcmdzKTsKLQotICAgIGlmIChudWxsICE9IHhjdHh0KQotICAgIHsKLSAgICAgIEVycm9yTGlzdGVuZXIgZWggPSB4Y3R4dC5nZXRFcnJvckxpc3RlbmVyKCk7Ci0KLSAgICAgIC8vIFRPIERPOiBOZWVkIHRvIGdldCBzdHlsZXNoZWV0IExvY2F0b3IgZnJvbSBoZXJlLgotICAgICAgZWgud2FybmluZyhuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oZm1zZywgeGN0eHQuZ2V0U0FYTG9jYXRvcigpKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gYXNzZXJ0aW9uIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gYiAgSWYgZmFsc2UsIGEgcnVudGltZSBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCi0gICAqIEBwYXJhbSBtc2cgVGhlIGFzc2VydGlvbiBtZXNzYWdlLCB3aGljaCBzaG91bGQgYmUgaW5mb3JtYXRpdmUuCi0gICAqCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiB0aGUgYiBhcmd1bWVudCBpcyBmYWxzZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBhc3NlcnRpb24oYm9vbGVhbiBiLCBqYXZhLmxhbmcuU3RyaW5nIG1zZykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoIWIpCi0gICAgewotICAgICAgamF2YS5sYW5nLlN0cmluZyBmTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSk7Ci0KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIG1zZyBBbiBlcnJvciBudW1iZXIgdGhhdCBjb3JyZXNwb25kcyB0byBvbmUgb2YgdGhlIG51bWJlcnMgZm91bmQKLSAgICogICAgICAgICAgICBpbiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlc30sIHdoaWNoIGlzCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8KLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZXJyb3IoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgbXNnLCBPYmplY3RbXSBhcmdzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGphdmEubGFuZy5TdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotCi0gICAgaWYgKG51bGwgIT0geGN0eHQpCi0gICAgewotICAgICAgRXJyb3JMaXN0ZW5lciBlaCA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlID0gbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fc2xvY2F0b3IpOwotCi0gICAgICBlaC5mYXRhbEVycm9yKHRlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL0ZvdW5kSW5kZXguamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL0ZvdW5kSW5kZXguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTU4ODE1MC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9Gb3VuZEluZGV4LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgdG8gbGV0IHVzIGtub3cgd2hlbiBpdCdzIHRpbWUgdG8gZG8KLSAqIGEgc2VhcmNoIGZyb20gdGhlIHBhcmVudCBiZWNhdXNlIG9mIGluZGV4aW5nLgotICovCi1wdWJsaWMgY2xhc3MgRm91bmRJbmRleCBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24KLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgRm91bmRJbmRleAotICAgKgotICAgKi8KLSAgcHVibGljIEZvdW5kSW5kZXgoKXt9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9Ob2RlU2V0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9Ob2RlU2V0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDY2ZGJjYWIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvTm9kZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQwOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcjsKLWltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5Ob2RlVmVjdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Db250ZXh0Tm9kZUxpc3Q7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiA8cD5UaGUgTm9kZVNldCBjbGFzcyBjYW4gYWN0IGFzIGVpdGhlciBhIE5vZGVWZWN0b3IsCi0gKiBOb2RlTGlzdCwgb3IgTm9kZUl0ZXJhdG9yLiAgSG93ZXZlciwgaW4gb3JkZXIgZm9yIGl0IHRvCi0gKiBhY3QgYXMgYSBOb2RlVmVjdG9yIG9yIE5vZGVMaXN0LCBpdCdzIHJlcXVpcmVkIHRoYXQKLSAqIHNldFNob3VsZENhY2hlTm9kZXModHJ1ZSkgYmUgY2FsbGVkIGJlZm9yZSB0aGUgZmlyc3QKLSAqIG5leHROb2RlKCkgaXMgY2FsbGVkLCBpbiBvcmRlciB0aGF0IG5vZGVzIGNhbiBiZSBhZGRlZAotICogYXMgdGhleSBhcmUgZmV0Y2hlZC4gIERlcml2ZWQgY2xhc3NlcyB0aGF0IGltcGxlbWVudCBpdGVyYXRvcnMKLSAqIG11c3Qgb3ZlcnJpZGUgcnVuVG8oaW50IGluZGV4KSwgaW4gb3JkZXIgdGhhdCB0aGV5IG1heQotICogcnVuIHRoZSBpdGVyYXRpb24gdG8gdGhlIGdpdmVuIGluZGV4LiA8L3A+Ci0gKiAKLSAqIDxwPk5vdGUgdGhhdCB3ZSBkaXJlY3RseSBpbXBsZW1lbnQgdGhlIERPTSdzIE5vZGVJdGVyYXRvcgotICogaW50ZXJmYWNlLiBXZSBkbyBub3QgZW11bGF0ZSBhbGwgdGhlIGJlaGF2aW9yIG9mIHRoZQotICogc3RhbmRhcmQgTm9kZUl0ZXJhdG9yLiBJbiBwYXJ0aWN1bGFyLCB3ZSBkbyBub3QgZ3VhcmFudGVlCi0gKiB0byBwcmVzZW50IGEgImxpdmUgdmlldyIgb2YgdGhlIGRvY3VtZW50IC4uLiBidXQgaW4gWFNMVCwKLSAqIHRoZSBzb3VyY2UgZG9jdW1lbnQgc2hvdWxkIG5ldmVyIGJlIG11dGF0ZWQsIHNvIHRoaXMgc2hvdWxkCi0gKiBuZXZlciBiZSBhbiBpc3N1ZS48L3A+Ci0gKiAKLSAqIDxwPlRob3VnaHQ6IFNob3VsZCBOb2RlU2V0IHJlYWxseSBpbXBsZW1lbnQgTm9kZUxpc3QgYW5kIE5vZGVJdGVyYXRvciwKLSAqIG9yIHNob3VsZCB0aGVyZSBiZSBzcGVjaWZpYyBzdWJjbGFzc2VzIG9mIGl0IHdoaWNoIGRvIHNvPyBUaGUKLSAqIGFkdmFudGFnZSBvZiBkb2luZyBpdCBhbGwgaGVyZSBpcyB0aGF0IGFsbCBOb2RlU2V0cyB3aWxsIHJlc3BvbmQKLSAqIHRvIHRoZSBzYW1lIGNhbGxzOyB0aGUgZGlzYWR2YW50YWdlIGlzIHRoYXQgc29tZSBvZiB0aGVtIG1heSByZXR1cm4KLSAqIGxlc3MtdGhhbi1lbmxpZ2h0ZW5pbmcgcmVzdWx0cyB3aGVuIHlvdSBkbyBzby48L3A+Ci0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlU2V0Ci0gICAgICAgIGltcGxlbWVudHMgTm9kZUxpc3QsIE5vZGVJdGVyYXRvciwgQ2xvbmVhYmxlLCBDb250ZXh0Tm9kZUxpc3QKLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGVtcHR5IG5vZGVsaXN0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXQoKQotICB7Ci0gICAgbV9ibG9ja3NpemUgPSAzMjsKLSAgICBtX21hcFNpemUgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBlbXB0eSwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgCi0gICAqLwotICBwdWJsaWMgTm9kZVNldChpbnQgYmxvY2tzaXplKQotICB7Ci0gICAgbV9ibG9ja3NpemUgPSBibG9ja3NpemU7Ci0gICAgbV9tYXBTaXplID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBOb2RlU2V0LCBhbmQgY29weSB0aGUgbWVtYmVycyBvZiB0aGUKLSAgICogZ2l2ZW4gbm9kZWxpc3QgaW50byBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVsaXN0IExpc3Qgb2YgTm9kZXMgdG8gYmUgbWFkZSBtZW1iZXJzIG9mIHRoZSBuZXcgc2V0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXQoTm9kZUxpc3Qgbm9kZWxpc3QpCi0gIHsKLQotICAgIHRoaXMoMzIpOwotCi0gICAgYWRkTm9kZXMobm9kZWxpc3QpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE5vZGVTZXQsIGFuZCBjb3B5IHRoZSBtZW1iZXJzIG9mIHRoZQotICAgKiBnaXZlbiBOb2RlU2V0IGludG8gaXQuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlbGlzdCBTZXQgb2YgTm9kZXMgdG8gYmUgbWFkZSBtZW1iZXJzIG9mIHRoZSBuZXcgc2V0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXQoTm9kZVNldCBub2RlbGlzdCkKLSAgewotCi0gICAgdGhpcygzMik7Ci0KLSAgICBhZGROb2RlcygoTm9kZUl0ZXJhdG9yKSBub2RlbGlzdCk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldCwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0gICAqIGdpdmVuIE5vZGVJdGVyYXRvciBpbnRvIGl0LgotICAgKgotICAgKiBAcGFyYW0gbmkgSXRlcmF0b3Igd2hpY2ggeWllbGRzIE5vZGVzIHRvIGJlIG1hZGUgbWVtYmVycyBvZiB0aGUgbmV3IHNldC4KLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0KE5vZGVJdGVyYXRvciBuaSkKLSAgewotCi0gICAgdGhpcygzMik7Ci0KLSAgICBhZGROb2RlcyhuaSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldCB3aGljaCBjb250YWlucyB0aGUgZ2l2ZW4gTm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgU2luZ2xlIG5vZGUgdG8gYmUgYWRkZWQgdG8gdGhlIG5ldyBzZXQuCi0gICAqLwotICBwdWJsaWMgTm9kZVNldChOb2RlIG5vZGUpCi0gIHsKLQotICAgIHRoaXMoMzIpOwotCi0gICAgYWRkTm9kZShub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiBAcmV0dXJuIFRoZSByb290IG5vZGUgb2YgdGhlIEl0ZXJhdG9yLCBhcyBzcGVjaWZpZWQgd2hlbiBpdCB3YXMgY3JlYXRlZC4KLSAgICogRm9yIG5vbi1JdGVyYXRvciBOb2RlU2V0cywgdGhpcyB3aWxsIGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRSb290KCkKLSAgewotICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciwgYW5kIHJlc2V0IGl0cyBzdGF0ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZQotICAgKiBpdGVyYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gYSBuZXcgTm9kZVNldCBvZiB0aGUgc2FtZSB0eXBlLCBoYXZpbmcgdGhlIHNhbWUgc3RhdGUuLi4KLSAgICogZXhjZXB0IHRoYXQgdGhlIHJlc2V0KCkgb3BlcmF0aW9uIGhhcyBiZWVuIGNhbGxlZC4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBpZiB0aGlzIHN1YmNsYXNzIG9mIE5vZGVTZXQKLSAgICogZG9lcyBub3Qgc3VwcG9ydCB0aGUgY2xvbmUoKSBvcGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGNsb25lV2l0aFJlc2V0KCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIE5vZGVTZXQgY2xvbmUgPSAoTm9kZVNldCkgY2xvbmUoKTsKLQotICAgIGNsb25lLnJlc2V0KCk7Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogUmVzZXQgdGhlIGl0ZXJhdG9yLiBNYXkgaGF2ZSBubyBlZmZlY3Qgb24gbm9uLWl0ZXJhdG9yIE5vZGVzZXRzLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgbV9uZXh0ID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBwcmVzZW50ZWQgdmlhIHRoZQotICAgKiBpdGVyYXRvci4gVGhlIGF2YWlsYWJsZSBzZXQgb2YgY29uc3RhbnRzIGlzIGRlZmluZWQgaW4gdGhlCi0gICAqIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGludGVyZmFjZS4gRm9yIE5vZGVTZXRzLCB0aGUgbWFzayBoYXMgYmVlbgotICAgKiBoYXJkY29kZWQgdG8gc2hvdyBhbGwgbm9kZXMgZXhjZXB0IEVudGl0eVJlZmVyZW5jZSBub2Rlcywgd2hpY2ggaGF2ZQotICAgKiBubyBlcXVpdmFsZW50IGluIHRoZSBYUGF0aCBkYXRhIG1vZGVsLgotICAgKgotICAgKiBAcmV0dXJuIGludGVnZXIgdXNlZCBhcyBhIGJpdC1hcnJheSwgY29udGFpbmluZyBmbGFncyBkZWZpbmVkIGluCi0gICAqIHRoZSBET00ncyBOb2RlRmlsdGVyIGNsYXNzLiBUaGUgdmFsdWUgd2lsbCBiZSAKLSAgICogPGNvZGU+U0hPV19BTEwgJiB+U0hPV19FTlRJVFlfUkVGRVJFTkNFPC9jb2RlPiwgbWVhbmluZyB0aGF0Ci0gICAqIG9ubHkgZW50aXR5IHJlZmVyZW5jZXMgYXJlIHN1cHByZXNzZWQuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coKQotICB7Ci0gICAgcmV0dXJuIE5vZGVGaWx0ZXIuU0hPV19BTEwgJiB+Tm9kZUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGZpbHRlciBvYmplY3QgdXNlZCB0byBzY3JlZW4gbm9kZXMuIEZpbHRlcnMgYXJlIGFwcGxpZWQgdG8KLSAgICogZnVydGhlciByZWR1Y2UgKGFuZCByZXN0cnVjdHVyZSkgdGhlIE5vZGVJdGVyYXRvcidzIHZpZXcgb2YgdGhlCi0gICAqIGRvY3VtZW50LiBJbiBvdXIgY2FzZSwgd2Ugd2lsbCBiZSB1c2luZyBoYXJkY29kZWQgZmlsdGVycyBidWlsdAotICAgKiBpbnRvIG91ciBpdGVyYXRvcnMuLi4gYnV0IGdldEZpbHRlcigpIGlzIHBhcnQgb2YgdGhlIERPTSdzIAotICAgKiBOb2RlSXRlcmF0b3IgaW50ZXJmYWNlLCBzbyB3ZSBoYXZlIHRvIHN1cHBvcnQgaXQuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbCwgd2hpY2ggaXMgc2xpZ2h0bHkgbWlzbGVhZGluZy4gVHJ1ZSwgdGhlcmUgaXMgbm8KLSAgICogdXNlci13cml0dGVuIGZpbHRlciBvYmplY3QsIGJ1dCBpbiBmYWN0IHdlIGFyZSBkb2luZyBzb21lIHZlcnkKLSAgICogc29waGlzdGljYXRlZCBjdXN0b20gZmlsdGVyaW5nLiBBIERPTSBwdXJpc3QgbWlnaHQgc3VnZ2VzdAotICAgKiByZXR1cm5pbmcgYSBwbGFjZWhvbGRlciBvYmplY3QganVzdCB0byBpbmRpY2F0ZSB0aGF0IHRoaXMgaXMKLSAgICogbm90IGdvaW5nIHRvIHJldHVybiBhbGwgbm9kZXMgc2VsZWN0ZWQgYnkgd2hhdFRvU2hvdy4KLSAgICovCi0gIHB1YmxpYyBOb2RlRmlsdGVyIGdldEZpbHRlcigpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhlIHZhbHVlIG9mIHRoaXMgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNoaWxkcmVuIG9mIGVudGl0eQotICAgKiByZWZlcmVuY2Ugbm9kZXMgYXJlIHZpc2libGUgdG8gdGhlIGl0ZXJhdG9yLiBJZiBmYWxzZSwgdGhleSB3aWxsIGJlCi0gICAqIHNraXBwZWQgb3Zlci4KLSAgICogPGJyPiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZXMKLSAgICogZXhwYW5kZWQgYW5kIGRvZXMgbm90IGV4cG9zZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGl0c2VsZiwgdXNlIHRoZQotICAgKiB3aGF0VG9TaG93IGZsYWdzIHRvIGhpZGUgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBhbmQgc2V0Ci0gICAqIGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgdG8gdHJ1ZSB3aGVuIGNyZWF0aW5nIHRoZSBpdGVyYXRvci4gVG8gcHJvZHVjZQotICAgKiBhIHZpZXcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaGFzIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYnV0IG5vIGVudGl0eQotICAgKiBleHBhbnNpb24sIHVzZSB0aGUgd2hhdFRvU2hvdyBmbGFncyB0byBzaG93IHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUKLSAgICogYW5kIHNldCBleHBhbmRFbnRpdHlSZWZlcmVuY2VzIHRvIGZhbHNlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgZm9yIGFsbCBpdGVyYXRvcnMgYmFzZWQgb24gTm9kZVNldCwgbWVhbmluZyB0aGF0IHRoZQotICAgKiBjb250ZW50cyBvZiBFbnRpdHlSZWZyZW5jZSBub2RlcyBtYXkgYmUgcmV0dXJuZWQgKHRob3VnaCB3aGF0VG9TaG93Ci0gICAqIHNheXMgdGhhdCB0aGUgRW50aXR5UmVmZXJlbmNlcyB0aGVtc2VsdmVzIGFyZSBub3Qgc2hvd24uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiAgICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciB0aGUKLSAgICogICA8Y29kZT5kZXRhY2g8L2NvZGU+IG1ldGhvZCB3YXMgaW52b2tlZC4KLSAgICovCi0gIHB1YmxpYyBOb2RlIG5leHROb2RlKCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoKG1fbmV4dCkgPCB0aGlzLnNpemUoKSkKLSAgICB7Ci0gICAgICBOb2RlIG5leHQgPSB0aGlzLmVsZW1lbnRBdChtX25leHQpOwotCi0gICAgICBtX25leHQrKzsKLQotICAgICAgcmV0dXJuIG5leHQ7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBwcmV2aW91cyBub2RlIGluIHRoZSBzZXQgYW5kIG1vdmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgYmFja3dhcmRzIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBwcmV2aW91cyA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsCi0gICAqICAgb3I8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKiBAdGhyb3dzIERPTUV4Y2VwdGlvbgotICAgKiAgICBJTlZBTElEX1NUQVRFX0VSUjogUmFpc2VkIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciB0aGUKLSAgICogICA8Y29kZT5kZXRhY2g8L2NvZGU+IG1ldGhvZCB3YXMgaW52b2tlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIGNhY2hlZCB0eXBlLCBhbmQgaGVuY2UgZG9lc24ndCBrbm93IHdoYXQgdGhlIHByZXZpb3VzIG5vZGUgd2FzLgotICAgKi8KLSAgcHVibGljIE5vZGUgcHJldmlvdXNOb2RlKCkgdGhyb3dzIERPTUV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAoIW1fY2FjaGVOb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiVGhpcyBOb2RlU2V0IGNhbiBub3QgaXRlcmF0ZSB0byBhIHByZXZpb3VzIG5vZGUhIik7Ci0KLSAgICBpZiAoKG1fbmV4dCAtIDEpID4gMCkKLSAgICB7Ci0gICAgICBtX25leHQtLTsKLQotICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudEF0KG1fbmV4dCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSBpdGVyYXRvciBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQgb3ZlciwgcmVsZWFzaW5nCi0gICAqIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IgaW4gdGhlIElOVkFMSUQKLSAgICogc3RhdGUuIEFmdGVyPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLCBjYWxscyB0bwotICAgKiA8Y29kZT5uZXh0Tm9kZTwvY29kZT4gb3I8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwgcmFpc2UgdGhlCi0gICAqIGV4Y2VwdGlvbiBJTlZBTElEX1NUQVRFX0VSUi4KLSAgICogPHA+Ci0gICAqIFRoaXMgb3BlcmF0aW9uIGlzIGEgbm8tb3AgaW4gTm9kZVNldCwgYW5kIHdpbGwgbm90IGNhdXNlIAotICAgKiBJTlZBTElEX1NUQVRFX0VSUiB0byBiZSByYWlzZWQgYnkgbGF0ZXIgb3BlcmF0aW9ucy4KLSAgICogPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCl7fQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIE5vZGVTZXQgaXMgImZyZXNoIiwgaW4gb3RoZXIgd29yZHMsIGlmCi0gICAqIHRoZSBmaXJzdCBuZXh0Tm9kZSgpIHRoYXQgaXMgY2FsbGVkIHdpbGwgcmV0dXJuIHRoZQotICAgKiBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuZXh0Tm9kZSgpIHdvdWxkIHJldHVybiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LAotICAgKiBmYWxzZSBpZiBpdCB3b3VsZCByZXR1cm4gYSBsYXRlciBvbmUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0ZyZXNoKCkKLSAgewotICAgIHJldHVybiAobV9uZXh0ID09IDApOwotICB9Ci0KLSAgLyoqCi0gICAqIElmIGFuIGluZGV4IGlzIHJlcXVlc3RlZCwgTm9kZVNldCB3aWxsIGNhbGwgdGhpcyBtZXRob2QKLSAgICogdG8gcnVuIHRoZSBpdGVyYXRvciB0byB0aGUgaW5kZXguICBCeSBkZWZhdWx0IHRoaXMgc2V0cwotICAgKiBtX25leHQgdG8gdGhlIGluZGV4LiAgSWYgdGhlIGluZGV4IGFyZ3VtZW50IGlzIC0xLCB0aGlzCi0gICAqIHNpZ25hbHMgdGhhdCB0aGUgaXRlcmF0b3Igc2hvdWxkIGJlIHJ1biB0byB0aGUgZW5kLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggUG9zaXRpb24gdG8gYWR2YW5jZSAob3IgcmV0cmVhdCkgdG8sIHdpdGgKLSAgICogMCByZXF1ZXN0aW5nIHRoZSByZXNldCAoImZyZXNoIikgcG9zaXRpb24gYW5kIC0xIChvciBpbmRlZWQKLSAgICogYW55IG91dC1vZi1ib3VuZHMgdmFsdWUpIHJlcXVlc3RpbmcgdGhlIGZpbmFsIHBvc2l0aW9uLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3QKLSAgICogb25lIG9mIHRoZSB0eXBlcyB3aGljaCBzdXBwb3J0cyBpbmRleGluZy9jb3VudGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1blRvKGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKCFtX2NhY2hlTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgIlRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEiKTsKLQotICAgIGlmICgoaW5kZXggPj0gMCkgJiYgKG1fbmV4dCA8IG1fZmlyc3RGcmVlKSkKLSAgICAgIG1fbmV4dCA9IGluZGV4OwotICAgIGVsc2UKLSAgICAgIG1fbmV4dCA9IG1fZmlyc3RGcmVlIC0gMTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5pbmRleDwvY29kZT50aCBpdGVtIGluIHRoZSBjb2xsZWN0aW9uLiBJZgotICAgKiA8Y29kZT5pbmRleDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBudW1iZXIgb2Ygbm9kZXMgaW4KLSAgICogdGhlIGxpc3QsIHRoaXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICogCi0gICAqIFRPRE86IFdoYXQgaGFwcGVucyBpZiBpbmRleCBpcyBvdXQgb2YgcmFuZ2U/Ci0gICAqIAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggaW50byB0aGUgY29sbGVjdGlvbi4KLSAgICogQHJldHVybiBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggcG9zaXRpb24gaW4gdGhlCi0gICAqICAgPGNvZGU+Tm9kZUxpc3Q8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0IGlzIG5vdCBhIHZhbGlkCi0gICAqICAgaW5kZXguCi0gICAqLwotICBwdWJsaWMgTm9kZSBpdGVtKGludCBpbmRleCkKLSAgewotCi0gICAgcnVuVG8oaW5kZXgpOwotCi0gICAgcmV0dXJuIChOb2RlKSB0aGlzLmVsZW1lbnRBdChpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcyBpcwotICAgKiAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuIE5vdGUgdGhhdCB0aGlzIG9wZXJhdGlvbiByZXF1aXJlcwotICAgKiBmaW5kaW5nIGFsbCB0aGUgbWF0Y2hpbmcgbm9kZXMsIHdoaWNoIG1heSBkZWZlYXQgYXR0ZW1wdHMgdG8gZGVmZXIKLSAgICogdGhhdCB3b3JrLgotICAgKgotICAgKiBAcmV0dXJuIGludGVnZXIgaW5kaWNhdGluZyBob3cgbWFueSBub2RlcyBhcmUgcmVwcmVzZW50ZWQgYnkgdGhpcyBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRMZW5ndGgoKQotICB7Ci0KLSAgICBydW5UbygtMSk7Ci0KLSAgICByZXR1cm4gdGhpcy5zaXplKCk7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgbm9kZSB0byB0aGUgTm9kZVNldC4gTm90IGFsbCB0eXBlcyBvZiBOb2RlU2V0cyBzdXBwb3J0IHRoaXMKLSAgICogb3BlcmF0aW9uCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgYWRkZWQKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE5vZGUoTm9kZSBuKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgdGhpcy5hZGRFbGVtZW50KG4pOwotICB9Ci0KLSAgLyoqCi0gICAqIEluc2VydCBhIG5vZGUgYXQgYSBnaXZlbiBwb3NpdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBhZGRlZAotICAgKiBAcGFyYW0gcG9zIE9mZnNldCBhdCB3aGljaCB0aGUgbm9kZSBpcyB0byBiZSBpbnNlcnRlZCwKLSAgICogd2l0aCAwIGJlaW5nIHRoZSBmaXJzdCBwb3NpdGlvbi4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydE5vZGUoTm9kZSBuLCBpbnQgcG9zKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaW5zZXJ0RWxlbWVudEF0KG4sIHBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGEgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBhZGRlZAotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlTm9kZShOb2RlIG4pCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICB0aGlzLnJlbW92ZUVsZW1lbnQobik7Ci0gIH0KLQotICAvKioKLSAgICogQ29weSBOb2RlTGlzdCBtZW1iZXJzIGludG8gdGhpcyBub2RlbGlzdCwgYWRkaW5nIGluCi0gICAqIGRvY3VtZW50IG9yZGVyLiAgSWYgYSBub2RlIGlzIG51bGwsIGRvbid0IGFkZCBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVsaXN0IExpc3Qgb2Ygbm9kZXMgd2hpY2ggc2hvdWxkIG5vdyBiZSByZWZlcmVuY2VkIGJ5Ci0gICAqIHRoaXMgTm9kZVNldC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE5vZGVzKE5vZGVMaXN0IG5vZGVsaXN0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaWYgKG51bGwgIT0gbm9kZWxpc3QpICAvLyBkZWZlbnNpdmUgdG8gZml4IGEgYnVnIHRoYXQgU2Fuaml2YSByZXBvcnRlZC4KLSAgICB7Ci0gICAgICBpbnQgbkNoaWxkcmVuID0gbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkNoaWxkcmVuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIE5vZGUgb2JqID0gbm9kZWxpc3QuaXRlbShpKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBvYmopCi0gICAgICAgIHsKLSAgICAgICAgICBhZGRFbGVtZW50KG9iaik7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiA8cD5Db3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuICBPbmx5IGdlbnVpbmUgbm9kZSByZWZlcmVuY2VzIHdpbGwgYmUgY29waWVkOwotICAgKiBudWxscyBhcHBlYXJpbmcgaW4gdGhlIHNvdXJjZSBOb2RlU2V0IHdpbGwKLSAgICogbm90IGJlIGFkZGVkIHRvIHRoaXMgb25lLiA8L3A+Ci0gICAqIAotICAgKiA8cD4gSW4gY2FzZSB5b3UncmUgd29uZGVyaW5nIHdoeSB0aGlzIGZ1bmN0aW9uIGlzIG5lZWRlZDogTm9kZVNldAotICAgKiBpbXBsZW1lbnRzIGJvdGggTm9kZUl0ZXJhdG9yIGFuZCBOb2RlTGlzdC4gSWYgdGhpcyBtZXRob2QgaXNuJ3QKLSAgICogcHJvdmlkZWQsIEphdmEgY2FuJ3QgZGVjaWRlIHdoaWNoIG9mIHRob3NlIHRvIHVzZSB3aGVuIGFkZE5vZGVzKCkKLSAgICogaXMgaW52b2tlZC4gUHJvdmlkaW5nIHRoZSBtb3JlLWV4cGxpY2l0IG1hdGNoIGF2b2lkcyB0aGF0Ci0gICAqIGFtYmlndWl0eS4pPC9wPgotICAgKgotICAgKiBAcGFyYW0gbnMgTm9kZVNldCB3aG9zZSBtZW1iZXJzIHNob3VsZCBiZSBtZXJnZWQgaW50byB0aGlzIE5vZGVTZXQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2RlcyhOb2RlU2V0IG5zKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgYWRkTm9kZXMoKE5vZGVJdGVyYXRvcikgbnMpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotICAgKiBkb2N1bWVudCBvcmRlci4gIE51bGwgcmVmZXJlbmNlcyBhcmUgbm90IGFkZGVkLgotICAgKgotICAgKiBAcGFyYW0gaXRlcmF0b3IgTm9kZUl0ZXJhdG9yIHdoaWNoIHlpZWxkcyB0aGUgbm9kZXMgdG8gYmUgYWRkZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2RlcyhOb2RlSXRlcmF0b3IgaXRlcmF0b3IpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpZiAobnVsbCAhPSBpdGVyYXRvcikgIC8vIGRlZmVuc2l2ZSB0byBmaXggYSBidWcgdGhhdCBTYW5qaXZhIHJlcG9ydGVkLgotICAgIHsKLSAgICAgIE5vZGUgb2JqOwotCi0gICAgICB3aGlsZSAobnVsbCAhPSAob2JqID0gaXRlcmF0b3IubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGFkZEVsZW1lbnQob2JqKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuICBJZiBhIG5vZGUgaXMgbnVsbCwgZG9uJ3QgYWRkIGl0LgotICAgKgotICAgKiBAcGFyYW0gbm9kZWxpc3QgTGlzdCBvZiBub2RlcyB0byBiZSBhZGRlZAotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTm9kZXNJbkRvY09yZGVyKE5vZGVMaXN0IG5vZGVsaXN0LCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGludCBuQ2hpbGRyZW4gPSBub2RlbGlzdC5nZXRMZW5ndGgoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkNoaWxkcmVuOyBpKyspCi0gICAgewotICAgICAgTm9kZSBub2RlID0gbm9kZWxpc3QuaXRlbShpKTsKLQotICAgICAgaWYgKG51bGwgIT0gbm9kZSkKLSAgICAgIHsKLSAgICAgICAgYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgc3VwcG9ydCk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotICAgKiBkb2N1bWVudCBvcmRlci4gIElmIGEgbm9kZSBpcyBudWxsLCBkb24ndCBhZGQgaXQuCi0gICAqCi0gICAqIEBwYXJhbSBpdGVyYXRvciBOb2RlSXRlcmF0b3Igd2hpY2ggeWllbGRzIHRoZSBub2RlcyB0byBiZSBhZGRlZC4KLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZE5vZGVzSW5Eb2NPcmRlcihOb2RlSXRlcmF0b3IgaXRlcmF0b3IsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgTm9kZSBub2RlOwotCi0gICAgd2hpbGUgKG51bGwgIT0gKG5vZGUgPSBpdGVyYXRvci5uZXh0Tm9kZSgpKSkKLSAgICB7Ci0gICAgICBhZGROb2RlSW5Eb2NPcmRlcihub2RlLCBzdXBwb3J0KTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIHRoZSBub2RlIGxpc3QgdG8gdGhpcyBub2RlIHNldCBpbiBkb2N1bWVudCBvcmRlci4KLSAgICoKLSAgICogQHBhcmFtIHN0YXJ0IGluZGV4LgotICAgKiBAcGFyYW0gZW5kIGluZGV4LgotICAgKiBAcGFyYW0gdGVzdEluZGV4IGluZGV4LgotICAgKiBAcGFyYW0gbm9kZWxpc3QgVGhlIG5vZGVsaXN0IHRvIGFkZC4KLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZSBhbHdheXMuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gYWRkTm9kZXNJbkRvY09yZGVyKGludCBzdGFydCwgaW50IGVuZCwgaW50IHRlc3RJbmRleCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlTGlzdCBub2RlbGlzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVF9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXQgaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBib29sZWFuIGZvdW5kaXQgPSBmYWxzZTsKLSAgICBpbnQgaTsKLSAgICBOb2RlIG5vZGUgPSBub2RlbGlzdC5pdGVtKHRlc3RJbmRleCk7Ci0KLSAgICBmb3IgKGkgPSBlbmQ7IGkgPj0gc3RhcnQ7IGktLSkKLSAgICB7Ci0gICAgICBOb2RlIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRBdChpKTsKLQotICAgICAgaWYgKGNoaWxkID09IG5vZGUpCi0gICAgICB7Ci0gICAgICAgIGkgPSAtMjsgIC8vIER1cGxpY2F0ZSwgc3VwcHJlc3MgaW5zZXJ0Ci0KLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0KLSAgICAgIGlmICghRE9NMkhlbHBlci5pc05vZGVBZnRlcihub2RlLCBjaGlsZCkpCi0gICAgICB7Ci0gICAgICAgIGluc2VydEVsZW1lbnRBdChub2RlLCBpICsgMSk7Ci0KLSAgICAgICAgdGVzdEluZGV4LS07Ci0KLSAgICAgICAgaWYgKHRlc3RJbmRleCA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICBib29sZWFuIGZvdW5kUHJldiA9IGFkZE5vZGVzSW5Eb2NPcmRlcigwLCBpLCB0ZXN0SW5kZXgsIG5vZGVsaXN0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnQpOwotCi0gICAgICAgICAgaWYgKCFmb3VuZFByZXYpCi0gICAgICAgICAgewotICAgICAgICAgICAgYWRkTm9kZXNJbkRvY09yZGVyKGksIHNpemUoKSAtIDEsIHRlc3RJbmRleCwgbm9kZWxpc3QsIHN1cHBvcnQpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChpID09IC0xKQotICAgIHsKLSAgICAgIGluc2VydEVsZW1lbnRBdChub2RlLCAwKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZm91bmRpdDsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgdGhlIG5vZGUgaW50byBhIHZlY3RvciBvZiBub2RlcyB3aGVyZSBpdCBzaG91bGQgb2NjdXIgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuCi0gICAqIEBwYXJhbSB2IFZlY3RvciBvZiBub2RlcywgcHJlc3VtYWJseSBjb250YWluaW5nIE5vZGVzCi0gICAqIEBwYXJhbSBvYmogTm9kZSBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gdGVzdCB0cnVlIGlmIHdlIHNob3VsZCB0ZXN0IGZvciBkb2Mgb3JkZXIKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiBpbnNlcnRJbmRleC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgYWRkTm9kZUluRG9jT3JkZXIoTm9kZSBub2RlLCBib29sZWFuIHRlc3QsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy9YU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGludCBpbnNlcnRJbmRleCA9IC0xOwotCi0gICAgaWYgKHRlc3QpCi0gICAgewotCi0gICAgICAvLyBUaGlzIG5lZWRzIHRvIGRvIGEgYmluYXJ5IHNlYXJjaCwgYnV0IGEgYmluYXJ5IHNlYXJjaCAKLSAgICAgIC8vIGlzIHNvbWV3aGF0IHRvdWdoIGJlY2F1c2UgdGhlIHNlcXVlbmNlIHRlc3QgaW52b2x2ZXMgCi0gICAgICAvLyB0d28gbm9kZXMuCi0gICAgICBpbnQgc2l6ZSA9IHNpemUoKSwgaTsKLQotICAgICAgZm9yIChpID0gc2l6ZSAtIDE7IGkgPj0gMDsgaS0tKQotICAgICAgewotICAgICAgICBOb2RlIGNoaWxkID0gKE5vZGUpIGVsZW1lbnRBdChpKTsKLQotICAgICAgICBpZiAoY2hpbGQgPT0gbm9kZSkKLSAgICAgICAgewotICAgICAgICAgIGkgPSAtMjsgIC8vIER1cGxpY2F0ZSwgc3VwcHJlc3MgaW5zZXJ0Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotCi0gICAgICAgIGlmICghRE9NMkhlbHBlci5pc05vZGVBZnRlcihub2RlLCBjaGlsZCkpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoaSAhPSAtMikKLSAgICAgIHsKLSAgICAgICAgaW5zZXJ0SW5kZXggPSBpICsgMTsKLQotICAgICAgICBpbnNlcnRFbGVtZW50QXQobm9kZSwgaW5zZXJ0SW5kZXgpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW5zZXJ0SW5kZXggPSB0aGlzLnNpemUoKTsKLQotICAgICAgYm9vbGVhbiBmb3VuZGl0ID0gZmFsc2U7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5zZXJ0SW5kZXg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYgKHRoaXMuaXRlbShpKS5lcXVhbHMobm9kZSkpCi0gICAgICAgIHsKLSAgICAgICAgICBmb3VuZGl0ID0gdHJ1ZTsKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmICghZm91bmRpdCkKLSAgICAgICAgYWRkRWxlbWVudChub2RlKTsKLSAgICB9Ci0KLSAgICAvLyBjaGVja0R1cHMoKTsKLSAgICByZXR1cm4gaW5zZXJ0SW5kZXg7Ci0gIH0gIC8vIGVuZCBhZGROb2RlSW5Eb2NPcmRlcihWZWN0b3IgdiwgT2JqZWN0IG9iaikKLQotICAvKioKLSAgICogQWRkIHRoZSBub2RlIGludG8gYSB2ZWN0b3Igb2Ygbm9kZXMgd2hlcmUgaXQgc2hvdWxkIG9jY3VyIGluCi0gICAqIGRvY3VtZW50IG9yZGVyLgotICAgKiBAcGFyYW0gdiBWZWN0b3Igb2Ygbm9kZXMsIHByZXN1bWFibHkgY29udGFpbmluZyBOb2RlcwotICAgKiBAcGFyYW0gb2JqIE5vZGUgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0byBiZSBhZGRlZC4KLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgaW5kZXggd2hlcmUgaXQgd2FzIGluc2VydGVkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldCBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIGludCBhZGROb2RlSW5Eb2NPcmRlcihOb2RlIG5vZGUsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgcmV0dXJuIGFkZE5vZGVJbkRvY09yZGVyKG5vZGUsIHRydWUsIHN1cHBvcnQpOwotICB9ICAvLyBlbmQgYWRkTm9kZUluRG9jT3JkZXIoVmVjdG9yIHYsIE9iamVjdCBvYmopCi0KLQotICAvKiogSWYgdGhpcyBub2RlIGlzIGJlaW5nIHVzZWQgYXMgYW4gaXRlcmF0b3IsIHRoZSBuZXh0IGluZGV4IHRoYXQgbmV4dE5vZGUoKQotICAgKiAgd2lsbCByZXR1cm4uICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX25leHQgPSAwOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdoaWNoIGlzIG9uZSBsZXNzIHRoYW4KLSAgICogdGhlIG5leHQgbmV4dE5vZGUoKSBjYWxsIHdpbGwgcmV0cmlldmUuICBpLmUuIGlmCi0gICAqIHlvdSBjYWxsIGdldEN1cnJlbnRQb3MoKSBhbmQgdGhlIHJldHVybiBpcyAwLCB0aGUgbmV4dAotICAgKiBmZXRjaCB3aWxsIHRha2UgcGxhY2UgYXQgaW5kZXggMS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW5kZXguCi0gICAqLwotICBwdWJsaWMgaW50IGdldEN1cnJlbnRQb3MoKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG5vZGUgc2V0LgotICAgKiBAcGFyYW0gaSBNdXN0IGJlIGEgdmFsaWQgaW5kZXguCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0IGlzIG5vdCBvZiAKLSAgICogYSBjYWNoZWQgdHlwZSwgYW5kIHRodXMgZG9lc24ndCBwZXJtaXQgaW5kZXhlZCBhY2Nlc3MuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50UG9zKGludCBpKQotICB7Ci0KLSAgICBpZiAoIW1fY2FjaGVOb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiVGhpcyBOb2RlU2V0IGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgbV9uZXh0ID0gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGxhc3QgZmV0Y2hlZCBub2RlLiAgTmVlZGVkIHRvIHN1cHBvcnQgdGhlIFVuaW9uUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsYXN0IGZldGNoZWQgbm9kZS4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXQgaXMgbm90IG9mIAotICAgKiBhIGNhY2hlZCB0eXBlLCBhbmQgdGh1cyBkb2Vzbid0IHBlcm1pdCBpbmRleGVkIGFjY2Vzcy4KLSAgICovCi0gIHB1YmxpYyBOb2RlIGdldEN1cnJlbnROb2RlKCkKLSAgewotCi0gICAgaWYgKCFtX2NhY2hlTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgIlRoaXMgTm9kZVNldCBjYW4gbm90IGRvIGluZGV4aW5nIG9yIGNvdW50aW5nIGZ1bmN0aW9ucyEiKTsKLQotICAgIGludCBzYXZlZCA9IG1fbmV4dDsKLSAgICBOb2RlIG4gPSAobV9uZXh0IDwgbV9maXJzdEZyZWUpID8gZWxlbWVudEF0KG1fbmV4dCkgOiBudWxsOwotICAgIG1fbmV4dCA9IHNhdmVkOyAvLyBIQUNLOiBJIHRoaW5rIHRoaXMgaXMgYSBiaXQgb2YgYSBoYWNrLiAgLXNiCi0gICAgcmV0dXJuIG47Ci0gIH0KLQotICAvKiogVHJ1ZSBpZiB0aGlzIGxpc3QgY2FuIGJlIG11dGF0ZWQuICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGJvb2xlYW4gbV9tdXRhYmxlID0gdHJ1ZTsKLQotICAvKiogVHJ1ZSBpZiB0aGlzIGxpc3QgaXMgY2FjaGVkLgotICAgKiAgQHNlcmlhbCAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBib29sZWFuIG1fY2FjaGVOb2RlcyA9IHRydWU7Ci0KLSAgLyoqCi0gICAqIEdldCB3aGV0aGVyIG9yIG5vdCB0aGlzIGlzIGEgY2FjaGVkIG5vZGUgc2V0LgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBsaXN0IGlzIGNhY2hlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFNob3VsZENhY2hlTm9kZXMoKQotICB7Ci0gICAgcmV0dXJuIG1fY2FjaGVOb2RlczsKLSAgfQotCi0gIC8qKgotICAgKiBJZiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGlzIGNhbGxlZCwgdGhlbiBub2RlcyB3aWxsCi0gICAqIGJlIGNhY2hlZC4gIFRoZXkgYXJlIG5vdCBjYWNoZWQgYnkgZGVmYXVsdC4gVGhpcyBzd2l0Y2ggbXVzdAotICAgKiBiZSBzZXQgYmVmb3JlIHRoZSBmaXJzdCBjYWxsIHRvIG5leHROb2RlIGlzIG1hZGUsIHRvIGVuc3VyZQotICAgKiB0aGF0IGFsbCBub2RlcyBhcmUgY2FjaGVkLgotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoaXMgbm9kZSBzZXQgc2hvdWxkIGJlIGNhY2hlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8KLSAgICogcmVxdWVzdCBjYWNoaW5nIGFmdGVyIHdlJ3ZlIGFscmVhZHkgYmVndW4gc3RlcHBpbmcgdGhyb3VnaCB0aGUKLSAgICogbm9kZXMgaW4gdGhpcyBzZXQuCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldFNob3VsZENhY2hlTm9kZXMoYm9vbGVhbiBiKQotICB7Ci0KLSAgICBpZiAoIWlzRnJlc2goKSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiQ2FuIG5vdCBjYWxsIHNldFNob3VsZENhY2hlTm9kZXMgYWZ0ZXIgbmV4dE5vZGUgaGFzIGJlZW4gY2FsbGVkISIpOwotCi0gICAgbV9jYWNoZU5vZGVzID0gYjsKLSAgICBtX211dGFibGUgPSB0cnVlOwotICB9Ci0gIAotICAKLSAgdHJhbnNpZW50IHByaXZhdGUgaW50IG1fbGFzdCA9IDA7Ci0gIAotICBwdWJsaWMgaW50IGdldExhc3QoKQotICB7Ci0gICAgcmV0dXJuIG1fbGFzdDsKLSAgfQotICAKLSAgcHVibGljIHZvaWQgc2V0TGFzdChpbnQgbGFzdCkKLSAgewotICAgIG1fbGFzdCA9IGxhc3Q7Ci0gIH0KLSAgCi0gIC8qKiBTaXplIG9mIGJsb2NrcyB0byBhbGxvY2F0ZS4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9ibG9ja3NpemU7Ci0KLSAgLyoqIEFycmF5IG9mIG5vZGVzIHRoaXMgcG9pbnRzIHRvLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBOb2RlIG1fbWFwW107Ci0KLSAgLyoqIE51bWJlciBvZiBub2RlcyBpbiB0aGlzIE5vZGVWZWN0b3IuCi0gICAqICBAc2VyaWFsICAgICAgICAgICovCi0gIHByb3RlY3RlZCBpbnQgbV9maXJzdEZyZWUgPSAwOwotCi0gIC8qKiBTaXplIG9mIHRoZSBhcnJheSB0aGlzIHBvaW50cyB0by4KLSAgICogIEBzZXJpYWwgICAgICAgICAgICovCi0gIHByaXZhdGUgaW50IG1fbWFwU2l6ZTsgIC8vIGxhenkgaW5pdGlhbGl6YXRpb24KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIExvY1BhdGhJdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMKLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlU2V0IGNsb25lID0gKE5vZGVTZXQpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICBpZiAoKG51bGwgIT0gdGhpcy5tX21hcCkgJiYgKHRoaXMubV9tYXAgPT0gY2xvbmUubV9tYXApKQotICAgIHsKLSAgICAgIGNsb25lLm1fbWFwID0gbmV3IE5vZGVbdGhpcy5tX21hcC5sZW5ndGhdOwotCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMubV9tYXAsIDAsIGNsb25lLm1fbWFwLCAwLCB0aGlzLm1fbWFwLmxlbmd0aCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIE51bWJlciBvZiBub2RlcyBpbiB0aGlzIE5vZGVWZWN0b3IKLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gbV9maXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgTm9kZSBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBOb2RlIHRvIGFkZCB0byB0aGUgdmVjdG9yCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGRFbGVtZW50KE5vZGUgdmFsdWUpCi0gIHsKLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaWYgKChtX2ZpcnN0RnJlZSArIDEpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHsKLSAgICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX21hcFNpemUgKz0gbV9ibG9ja3NpemU7Ci0KLSAgICAgICAgTm9kZSBuZXdNYXBbXSA9IG5ldyBOb2RlW21fbWFwU2l6ZV07Ci0KLSAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgMCwgbmV3TWFwLCAwLCBtX2ZpcnN0RnJlZSArIDEpOwotCi0gICAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgICAgfQotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHZhbHVlOwotCi0gICAgbV9maXJzdEZyZWUrKzsKLSAgfQotCi0gIC8qKgotICAgKiBBcHBlbmQgYSBOb2RlIG9udG8gdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gYWRkIHRvIHRoZSB2ZWN0b3IKLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2goTm9kZSB2YWx1ZSkKLSAgewotCi0gICAgaW50IGZmID0gbV9maXJzdEZyZWU7Ci0KLSAgICBpZiAoKGZmICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgewotICAgICAgICBtX21hcCA9IG5ldyBOb2RlW21fYmxvY2tzaXplXTsKLSAgICAgICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgICBOb2RlIG5ld01hcFtdID0gbmV3IE5vZGVbbV9tYXBTaXplXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCAwLCBuZXdNYXAsIDAsIGZmICsgMSk7Ci0KLSAgICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgbV9tYXBbZmZdID0gdmFsdWU7Ci0KLSAgICBmZisrOwotCi0gICAgbV9maXJzdEZyZWUgPSBmZjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBub2RlIGZyb20gdGhlIHRhaWwgb2YgdGhlIHZlY3RvciBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG5vZGUgYXQgdGhlIHRhaWwgb2YgdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgcG9wKCkKLSAgewotCi0gICAgbV9maXJzdEZyZWUtLTsKLQotICAgIE5vZGUgbiA9IG1fbWFwW21fZmlyc3RGcmVlXTsKLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0KLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgYSBub2RlIGZyb20gdGhlIHRhaWwgb2YgdGhlIHZlY3RvciBhbmQgcmV0dXJuIHRoZQotICAgKiB0b3Agb2YgdGhlIHN0YWNrIGFmdGVyIHRoZSBwb3AuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRvcCBvZiB0aGUgc3RhY2sgYWZ0ZXIgaXQncyBiZWVuIHBvcHBlZCAKLSAgICovCi0gIHB1YmxpYyBmaW5hbCBOb2RlIHBvcEFuZFRvcCgpCi0gIHsKLQotICAgIG1fZmlyc3RGcmVlLS07Ci0KLSAgICBtX21hcFttX2ZpcnN0RnJlZV0gPSBudWxsOwotCi0gICAgcmV0dXJuIChtX2ZpcnN0RnJlZSA9PSAwKSA/IG51bGwgOiBtX21hcFttX2ZpcnN0RnJlZSAtIDFdOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCBhIG5vZGUgZnJvbSB0aGUgdGFpbCBvZiB0aGUgdmVjdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wUXVpY2soKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgbV9tYXBbbV9maXJzdEZyZWVdID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIG5vZGUgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgd2l0aG91dCBwb3BwaW5nIHRoZSBzdGFjay4KLSAgICogU3BlY2lhbCBwdXJwb3NlIG1ldGhvZCBmb3IgVHJhbnNmb3JtZXJJbXBsLCBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICogUGVyZm9ybWFuY2UgY3JpdGljYWwuCi0gICAqCi0gICAqIEByZXR1cm4gTm9kZSBhdCB0aGUgdG9wIG9mIHRoZSBzdGFjayBvciBudWxsIGlmIHN0YWNrIGlzIGVtcHR5LiAgCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBwZWVwT3JOdWxsKCkKLSAgewotICAgIHJldHVybiAoKG51bGwgIT0gbV9tYXApICYmIChtX2ZpcnN0RnJlZSA+IDApKQotICAgICAgICAgICA/IG1fbWFwW21fZmlyc3RGcmVlIC0gMV0gOiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIFB1c2ggYSBwYWlyIG9mIG5vZGVzIGludG8gdGhlIHN0YWNrLiAgCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gdjEgRmlyc3Qgbm9kZSB0byBhZGQgdG8gdmVjdG9yCi0gICAqIEBwYXJhbSB2MiBTZWNvbmQgbm9kZSB0byBhZGQgdG8gdmVjdG9yCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoUGFpcihOb2RlIHYxLCBOb2RlIHYyKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICB7Ci0gICAgICBtX21hcCA9IG5ldyBOb2RlW21fYmxvY2tzaXplXTsKLSAgICAgIG1fbWFwU2l6ZSA9IG1fYmxvY2tzaXplOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKChtX2ZpcnN0RnJlZSArIDIpID49IG1fbWFwU2l6ZSkKLSAgICAgIHsKLSAgICAgICAgbV9tYXBTaXplICs9IG1fYmxvY2tzaXplOwotCi0gICAgICAgIE5vZGUgbmV3TWFwW10gPSBuZXcgTm9kZVttX21hcFNpemVdOwotCi0gICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUpOwotCi0gICAgICAgIG1fbWFwID0gbmV3TWFwOwotICAgICAgfQotICAgIH0KLQotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IHYxOwotICAgIG1fbWFwW21fZmlyc3RGcmVlICsgMV0gPSB2MjsKLSAgICBtX2ZpcnN0RnJlZSArPSAyOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCBhIHBhaXIgb2Ygbm9kZXMgZnJvbSB0aGUgdGFpbCBvZiB0aGUgc3RhY2suIAotICAgKiBTcGVjaWFsIHB1cnBvc2UgbWV0aG9kIGZvciBUcmFuc2Zvcm1lckltcGwsIHB1c2hFbGVtVGVtcGxhdGVFbGVtZW50LgotICAgKiBQZXJmb3JtYW5jZSBjcml0aWNhbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcFBhaXIoKQotICB7Ci0KLSAgICBtX2ZpcnN0RnJlZSAtPSAyOwotICAgIG1fbWFwW21fZmlyc3RGcmVlXSA9IG51bGw7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgKyAxXSA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSB0YWlsIG9mIHRoZSBzdGFjayB0byB0aGUgZ2l2ZW4gbm9kZS4KLSAgICogU3BlY2lhbCBwdXJwb3NlIG1ldGhvZCBmb3IgVHJhbnNmb3JtZXJJbXBsLCBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICogUGVyZm9ybWFuY2UgY3JpdGljYWwuCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gc2V0IGF0IHRoZSB0YWlsIG9mIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGFpbChOb2RlIG4pCi0gIHsKLSAgICBtX21hcFttX2ZpcnN0RnJlZSAtIDFdID0gbjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGdpdmVuIG5vZGUgb25lIHBvc2l0aW9uIGZyb20gdGhlIHRhaWwuCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIHNldAotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VGFpbFN1YjEoTm9kZSBuKQotICB7Ci0gICAgbV9tYXBbbV9maXJzdEZyZWUgLSAyXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIGF0IHRoZSB0YWlsIG9mIHRoZSB2ZWN0b3Igd2l0aG91dCBwb3BwaW5nCi0gICAqIFNwZWNpYWwgcHVycG9zZSBtZXRob2QgZm9yIFRyYW5zZm9ybWVySW1wbCwgcHVzaEVsZW1UZW1wbGF0ZUVsZW1lbnQuCi0gICAqIFBlcmZvcm1hbmNlIGNyaXRpY2FsLgotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgdGhlIHRhaWwgb2YgdGhlIHZlY3RvcgotICAgKi8KLSAgcHVibGljIGZpbmFsIE5vZGUgcGVlcFRhaWwoKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlIC0gMV07Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBub2RlIG9uZSBwb3NpdGlvbiBmcm9tIHRoZSB0YWlsIHdpdGhvdXQgcG9wcGluZy4KLSAgICogU3BlY2lhbCBwdXJwb3NlIG1ldGhvZCBmb3IgVHJhbnNmb3JtZXJJbXBsLCBwdXNoRWxlbVRlbXBsYXRlRWxlbWVudC4KLSAgICogUGVyZm9ybWFuY2UgY3JpdGljYWwuCi0gICAqCi0gICAqIEByZXR1cm4gTm9kZSBvbmUgYXdheSBmcm9tIHRoZSB0YWlsCi0gICAqLwotICBwdWJsaWMgZmluYWwgTm9kZSBwZWVwVGFpbFN1YjEoKQotICB7Ci0gICAgcmV0dXJuIG1fbWFwW21fZmlyc3RGcmVlIC0gMl07Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIE5vZGUgdG8gaW5zZXJ0Ci0gICAqIEBwYXJhbSBhdCBQb3NpdGlvbiB3aGVyZSB0byBpbnNlcnQKLSAgICovCi0gIHB1YmxpYyB2b2lkIGluc2VydEVsZW1lbnRBdChOb2RlIHZhbHVlLCBpbnQgYXQpCi0gIHsKLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVRfTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgewotICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX2Jsb2Nrc2l6ZV07Ci0gICAgICBtX21hcFNpemUgPSBtX2Jsb2Nrc2l6ZTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoKG1fZmlyc3RGcmVlICsgMSkgPj0gbV9tYXBTaXplKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSArPSBtX2Jsb2Nrc2l6ZTsKLQotICAgICAgTm9kZSBuZXdNYXBbXSA9IG5ldyBOb2RlW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyAxKTsKLQotICAgICAgbV9tYXAgPSBuZXdNYXA7Ci0gICAgfQotCi0gICAgaWYgKGF0IDw9IChtX2ZpcnN0RnJlZSAtIDEpKQotICAgIHsKLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIGF0LCBtX21hcCwgYXQgKyAxLCBtX2ZpcnN0RnJlZSAtIGF0KTsKLSAgICB9Ci0KLSAgICBtX21hcFthdF0gPSB2YWx1ZTsKLQotICAgIG1fZmlyc3RGcmVlKys7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHRoZSBub2RlcyB0byB0aGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVzIE5vZGVWZWN0b3IgdG8gYXBwZW5kIHRvIHRoaXMgbGlzdAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kTm9kZXMoTm9kZVNldCBub2RlcykKLSAgewotCi0gICAgaW50IG5Ob2RlcyA9IG5vZGVzLnNpemUoKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgIHsKLSAgICAgIG1fbWFwU2l6ZSA9IG5Ob2RlcyArIG1fYmxvY2tzaXplOwotICAgICAgbV9tYXAgPSBuZXcgTm9kZVttX21hcFNpemVdOwotICAgIH0KLSAgICBlbHNlIGlmICgobV9maXJzdEZyZWUgKyBuTm9kZXMpID49IG1fbWFwU2l6ZSkKLSAgICB7Ci0gICAgICBtX21hcFNpemUgKz0gKG5Ob2RlcyArIG1fYmxvY2tzaXplKTsKLQotICAgICAgTm9kZSBuZXdNYXBbXSA9IG5ldyBOb2RlW21fbWFwU2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkobV9tYXAsIDAsIG5ld01hcCwgMCwgbV9maXJzdEZyZWUgKyBuTm9kZXMpOwotCi0gICAgICBtX21hcCA9IG5ld01hcDsKLSAgICB9Ci0KLSAgICBTeXN0ZW0uYXJyYXljb3B5KG5vZGVzLm1fbWFwLCAwLCBtX21hcCwgbV9maXJzdEZyZWUsIG5Ob2Rlcyk7Ci0KLSAgICBtX2ZpcnN0RnJlZSArPSBuTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlbW92ZUFsbEVsZW1lbnRzKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm47Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fZmlyc3RGcmVlOyBpKyspCi0gICAgewotICAgICAgbV9tYXBbaV0gPSBudWxsOwotICAgIH0KLQotICAgIG1fZmlyc3RGcmVlID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBmcm9tIHRoaXMgdmVjdG9yLgotICAgKiBJZiB0aGUgb2JqZWN0IGlzIGZvdW5kIGluIHRoaXMgdmVjdG9yLCBlYWNoIGNvbXBvbmVudCBpbiB0aGUgdmVjdG9yCi0gICAqIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgb2JqZWN0J3MgaW5kZXggaXMgc2hpZnRlZAotICAgKiBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4gdGhlIHZhbHVlIGl0IGhhZAotICAgKiBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gcyBOb2RlIHRvIHJlbW92ZSBmcm9tIHRoZSBsaXN0Ci0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbm9kZSB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHJlbW92ZUVsZW1lbnQoTm9kZSBzKQotICB7Ci0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IG1fbWFwW2ldOwotCi0gICAgICBpZiAoKG51bGwgIT0gbm9kZSkgJiYgbm9kZS5lcXVhbHMocykpCi0gICAgICB7Ci0gICAgICAgIGlmIChpID4gbV9maXJzdEZyZWUpCi0gICAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX21hcCwgaSArIDEsIG1fbWFwLCBpIC0gMSwgbV9maXJzdEZyZWUgLSBpKTsKLSAgICAgICAgZWxzZQotICAgICAgICAgIG1fbWFwW2ldID0gbnVsbDsKLQotICAgICAgICBtX2ZpcnN0RnJlZS0tOwotCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBEZWxldGVzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gRWFjaCBjb21wb25lbnQgaW4KLSAgICogdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQKLSAgICogaW5kZXggaXMgc2hpZnRlZCBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4KLSAgICogdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBub2RlIHRvIHJlbW92ZQotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlRWxlbWVudEF0KGludCBpKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybjsKLQotICAgIGlmIChpID4gbV9maXJzdEZyZWUpCi0gICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fbWFwLCBpICsgMSwgbV9tYXAsIGkgLSAxLCBtX2ZpcnN0RnJlZSAtIGkpOwotICAgIGVsc2UKLSAgICAgIG1fbWFwW2ldID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXRzIHRoZSBjb21wb25lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHZlY3RvciB0byBiZSB0aGUKLSAgICogc3BlY2lmaWVkIG9iamVjdC4gVGhlIHByZXZpb3VzIGNvbXBvbmVudCBhdCB0aGF0IHBvc2l0aW9uIGlzIGRpc2NhcmRlZC4KLSAgICoKLSAgICogVGhlIGluZGV4IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcwotICAgKiB0aGFuIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgTm9kZSB0byBzZXQKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIHNldCB0aGUgbm9kZQotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RWxlbWVudEF0KE5vZGUgbm9kZSwgaW50IGluZGV4KQotICB7Ci0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VUX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgIHsKLSAgICAgIG1fbWFwID0gbmV3IE5vZGVbbV9ibG9ja3NpemVdOwotICAgICAgbV9tYXBTaXplID0gbV9ibG9ja3NpemU7Ci0gICAgfQotCi0gICAgbV9tYXBbaW5kZXhdID0gbm9kZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG50aCBlbGVtZW50LgotICAgKgotICAgKiBAcGFyYW0gaSBJbmRleCBvZiBub2RlIHRvIGdldAotICAgKgotICAgKiBAcmV0dXJuIE5vZGUgYXQgc3BlY2lmaWVkIGluZGV4Ci0gICAqLwotICBwdWJsaWMgTm9kZSBlbGVtZW50QXQoaW50IGkpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIG51bGw7Ci0KLSAgICByZXR1cm4gbV9tYXBbaV07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0aGUgdGFibGUgY29udGFpbnMgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBzIE5vZGUgdG8gbG9vayBmb3IKLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBnaXZlbiBub2RlIHdhcyBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE5vZGUgcykKLSAgewotICAgIHJ1blRvKC0xKTsKLQotICAgIGlmIChudWxsID09IG1fbWFwKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IG1fbWFwW2ldOwotCi0gICAgICBpZiAoKG51bGwgIT0gbm9kZSkgJiYgbm9kZS5lcXVhbHMocykpCi0gICAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIE5vZGUgdG8gbG9vayBmb3IKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSBzZWFyY2gKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKE5vZGUgZWxlbSwgaW50IGluZGV4KQotICB7Ci0gICAgcnVuVG8oLTEpOwotCi0gICAgaWYgKG51bGwgPT0gbV9tYXApCi0gICAgICByZXR1cm4gLTE7Ci0KLSAgICBmb3IgKGludCBpID0gaW5kZXg7IGkgPCBtX2ZpcnN0RnJlZTsgaSsrKQotICAgIHsKLSAgICAgIE5vZGUgbm9kZSA9IG1fbWFwW2ldOwotCi0gICAgICBpZiAoKG51bGwgIT0gbm9kZSkgJiYgbm9kZS5lcXVhbHMoZWxlbSkpCi0gICAgICAgIHJldHVybiBpOwotICAgIH0KLQotICAgIHJldHVybiAtMTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIE5vZGUgdG8gbG9vayBmb3IgCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihOb2RlIGVsZW0pCi0gIHsKLSAgICBydW5UbygtMSk7Ci0KLSAgICBpZiAobnVsbCA9PSBtX21hcCkKLSAgICAgIHJldHVybiAtMTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9maXJzdEZyZWU7IGkrKykKLSAgICB7Ci0gICAgICBOb2RlIG5vZGUgPSBtX21hcFtpXTsKLQotICAgICAgaWYgKChudWxsICE9IG5vZGUpICYmIG5vZGUuZXF1YWxzKGVsZW0pKQotICAgICAgICByZXR1cm4gaTsKLSAgICB9Ci0KLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvTm9kZVNldERUTS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvTm9kZVNldERUTS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiOGU2MjRlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL05vZGVTZXREVE0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOTAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5OYW1lZE5vZGVNYXA7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotLy9pbXBvcnQgb3JnLnczYy5kb20uRE9NRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNTWFuYWdlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk5vZGVWZWN0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkNvbnRleHROb2RlTGlzdDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci0KLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIDxwPlRoZSBOb2RlU2V0RFRNIGNsYXNzIGNhbiBhY3QgYXMgZWl0aGVyIGEgTm9kZVZlY3RvciwKLSAqIE5vZGVMaXN0LCBvciBOb2RlSXRlcmF0b3IuICBIb3dldmVyLCBpbiBvcmRlciBmb3IgaXQgdG8KLSAqIGFjdCBhcyBhIE5vZGVWZWN0b3Igb3IgTm9kZUxpc3QsIGl0J3MgcmVxdWlyZWQgdGhhdAotICogc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKSBiZSBjYWxsZWQgYmVmb3JlIHRoZSBmaXJzdAotICogbmV4dE5vZGUoKSBpcyBjYWxsZWQsIGluIG9yZGVyIHRoYXQgbm9kZXMgY2FuIGJlIGFkZGVkCi0gKiBhcyB0aGV5IGFyZSBmZXRjaGVkLiAgRGVyaXZlZCBjbGFzc2VzIHRoYXQgaW1wbGVtZW50IGl0ZXJhdG9ycwotICogbXVzdCBvdmVycmlkZSBydW5UbyhpbnQgaW5kZXgpLCBpbiBvcmRlciB0aGF0IHRoZXkgbWF5Ci0gKiBydW4gdGhlIGl0ZXJhdGlvbiB0byB0aGUgZ2l2ZW4gaW5kZXguIDwvcD4KLSAqIAotICogPHA+Tm90ZSB0aGF0IHdlIGRpcmVjdGx5IGltcGxlbWVudCB0aGUgRE9NJ3MgTm9kZUl0ZXJhdG9yCi0gKiBpbnRlcmZhY2UuIFdlIGRvIG5vdCBlbXVsYXRlIGFsbCB0aGUgYmVoYXZpb3Igb2YgdGhlCi0gKiBzdGFuZGFyZCBOb2RlSXRlcmF0b3IuIEluIHBhcnRpY3VsYXIsIHdlIGRvIG5vdCBndWFyYW50ZWUKLSAqIHRvIHByZXNlbnQgYSAibGl2ZSB2aWV3IiBvZiB0aGUgZG9jdW1lbnQgLi4uIGJ1dCBpbiBYU0xULAotICogdGhlIHNvdXJjZSBkb2N1bWVudCBzaG91bGQgbmV2ZXIgYmUgbXV0YXRlZCwgc28gdGhpcyBzaG91bGQKLSAqIG5ldmVyIGJlIGFuIGlzc3VlLjwvcD4KLSAqIAotICogPHA+VGhvdWdodDogU2hvdWxkIE5vZGVTZXREVE0gcmVhbGx5IGltcGxlbWVudCBOb2RlTGlzdCBhbmQgTm9kZUl0ZXJhdG9yLAotICogb3Igc2hvdWxkIHRoZXJlIGJlIHNwZWNpZmljIHN1YmNsYXNzZXMgb2YgaXQgd2hpY2ggZG8gc28/IFRoZQotICogYWR2YW50YWdlIG9mIGRvaW5nIGl0IGFsbCBoZXJlIGlzIHRoYXQgYWxsIE5vZGVTZXREVE1zIHdpbGwgcmVzcG9uZAotICogdG8gdGhlIHNhbWUgY2FsbHM7IHRoZSBkaXNhZHZhbnRhZ2UgaXMgdGhhdCBzb21lIG9mIHRoZW0gbWF5IHJldHVybgotICogbGVzcy10aGFuLWVubGlnaHRlbmluZyByZXN1bHRzIHdoZW4geW91IGRvIHNvLjwvcD4KLSAqLwotcHVibGljIGNsYXNzIE5vZGVTZXREVE0gZXh0ZW5kcyBOb2RlVmVjdG9yCi0gICAgICAgIGltcGxlbWVudHMgLyogTm9kZUxpc3QsIE5vZGVJdGVyYXRvciwgKi8gRFRNSXRlcmF0b3IsIAotICAgICAgICBDbG9uZWFibGUKLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIGVtcHR5IG5vZGVsaXN0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0oRFRNTWFuYWdlciBkdG1NYW5hZ2VyKQotICB7Ci0gICAgc3VwZXIoKTsKLSAgICBtX21hbmFnZXIgPSBkdG1NYW5hZ2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBlbXB0eSwgdXNpbmcgdGhlIGdpdmVuIGJsb2NrIHNpemUuCi0gICAqCi0gICAqIEBwYXJhbSBibG9ja3NpemUgU2l6ZSBvZiBibG9ja3MgdG8gYWxsb2NhdGUgCi0gICAqIEBwYXJhbSBkdW1teSBwYXNzIHplcm8gZm9yIHJpZ2h0IG5vdy4uLgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0oaW50IGJsb2Nrc2l6ZSwgaW50IGR1bW15LCBEVE1NYW5hZ2VyIGR0bU1hbmFnZXIpCi0gIHsKLSAgICBzdXBlcihibG9ja3NpemUpOwotICAgIG1fbWFuYWdlciA9IGR0bU1hbmFnZXI7Ci0gIH0KLQotICAvLyAlVEJEJQotLy8gIC8qKgotLy8gICAqIENyZWF0ZSBhIE5vZGVTZXREVE0sIGFuZCBjb3B5IHRoZSBtZW1iZXJzIG9mIHRoZQotLy8gICAqIGdpdmVuIG5vZGVsaXN0IGludG8gaXQuCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gbm9kZWxpc3QgTGlzdCBvZiBOb2RlcyB0byBiZSBtYWRlIG1lbWJlcnMgb2YgdGhlIG5ldyBzZXQuCi0vLyAgICovCi0vLyAgcHVibGljIE5vZGVTZXREVE0oTm9kZUxpc3Qgbm9kZWxpc3QpCi0vLyAgewotLy8KLS8vICAgIHN1cGVyKCk7Ci0vLwotLy8gICAgYWRkTm9kZXMobm9kZWxpc3QpOwotLy8gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldERUTSwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0gICAqIGdpdmVuIE5vZGVTZXREVE0gaW50byBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVsaXN0IFNldCBvZiBOb2RlcyB0byBiZSBtYWRlIG1lbWJlcnMgb2YgdGhlIG5ldyBzZXQuCi0gICAqLwotICBwdWJsaWMgTm9kZVNldERUTShOb2RlU2V0RFRNIG5vZGVsaXN0KQotICB7Ci0KLSAgICBzdXBlcigpOwotICAgIG1fbWFuYWdlciA9IG5vZGVsaXN0LmdldERUTU1hbmFnZXIoKTsKLSAgICBtX3Jvb3QgPSBub2RlbGlzdC5nZXRSb290KCk7Ci0KLSAgICBhZGROb2RlcygoRFRNSXRlcmF0b3IpIG5vZGVsaXN0KTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBOb2RlU2V0RFRNLCBhbmQgY29weSB0aGUgbWVtYmVycyBvZiB0aGUKLSAgICogZ2l2ZW4gRFRNSXRlcmF0b3IgaW50byBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5pIEl0ZXJhdG9yIHdoaWNoIHlpZWxkcyBOb2RlcyB0byBiZSBtYWRlIG1lbWJlcnMgb2YgdGhlIG5ldyBzZXQuCi0gICAqLwotICBwdWJsaWMgTm9kZVNldERUTShEVE1JdGVyYXRvciBuaSkKLSAgewotCi0gICAgc3VwZXIoKTsKLQotICAgIG1fbWFuYWdlciA9IG5pLmdldERUTU1hbmFnZXIoKTsKLSAgICBtX3Jvb3QgPSBuaS5nZXRSb290KCk7Ci0gICAgYWRkTm9kZXMobmkpOwotICB9Ci0gIAotICAvKioKLSAgICogQ3JlYXRlIGEgTm9kZVNldERUTSwgYW5kIGNvcHkgdGhlIG1lbWJlcnMgb2YgdGhlCi0gICAqIGdpdmVuIERUTUl0ZXJhdG9yIGludG8gaXQuCi0gICAqCi0gICAqIEBwYXJhbSBuaSBJdGVyYXRvciB3aGljaCB5aWVsZHMgTm9kZXMgdG8gYmUgbWFkZSBtZW1iZXJzIG9mIHRoZSBuZXcgc2V0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0oTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBOb2RlIG5vZGU7Ci0gICAgbV9tYW5hZ2VyID0geGN0eHQuZ2V0RFRNTWFuYWdlcigpOwotCi0gICAgd2hpbGUgKG51bGwgIT0gKG5vZGUgPSBpdGVyYXRvci5uZXh0Tm9kZSgpKSkKLSAgICB7Ci0gICAgICBpbnQgaGFuZGxlID0geGN0eHQuZ2V0RFRNSGFuZGxlRnJvbU5vZGUobm9kZSk7Ci0gICAgICBhZGROb2RlSW5Eb2NPcmRlcihoYW5kbGUsIHhjdHh0KTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDcmVhdGUgYSBOb2RlU2V0RFRNLCBhbmQgY29weSB0aGUgbWVtYmVycyBvZiB0aGUKLSAgICogZ2l2ZW4gRFRNSXRlcmF0b3IgaW50byBpdC4KLSAgICoKLSAgICogQHBhcmFtIG5pIEl0ZXJhdG9yIHdoaWNoIHlpZWxkcyBOb2RlcyB0byBiZSBtYWRlIG1lbWJlcnMgb2YgdGhlIG5ldyBzZXQuCi0gICAqLwotICBwdWJsaWMgTm9kZVNldERUTShOb2RlTGlzdCBub2RlTGlzdCwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0KLSAgICBzdXBlcigpOwotCi0gICAgbV9tYW5hZ2VyID0geGN0eHQuZ2V0RFRNTWFuYWdlcigpOwotCi0gICAgaW50IG4gPSBub2RlTGlzdC5nZXRMZW5ndGgoKTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgCi0gICAgewotICAgICAgTm9kZSBub2RlID0gbm9kZUxpc3QuaXRlbShpKTsKLSAgICAgIGludCBoYW5kbGUgPSB4Y3R4dC5nZXREVE1IYW5kbGVGcm9tTm9kZShub2RlKTsKLSAgICAgIGFkZE5vZGVJbkRvY09yZGVyKGhhbmRsZSwgeGN0eHQpOwotICAgIH0KLSAgfQotCi0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE5vZGVTZXREVE0gd2hpY2ggY29udGFpbnMgdGhlIGdpdmVuIE5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFNpbmdsZSBub2RlIHRvIGJlIGFkZGVkIHRvIHRoZSBuZXcgc2V0LgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0oaW50IG5vZGUsIERUTU1hbmFnZXIgZHRtTWFuYWdlcikKLSAgewotCi0gICAgc3VwZXIoKTsKLSAgICBtX21hbmFnZXIgPSBkdG1NYW5hZ2VyOwotCi0gICAgYWRkTm9kZShub2RlKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgZW52aXJvbm1lbnQgaW4gd2hpY2ggdGhpcyBpdGVyYXRvciBvcGVyYXRlcywgd2hpY2ggc2hvdWxkIHByb3ZpZGU6Ci0gICAqIGEgbm9kZSAodGhlIGNvbnRleHQgbm9kZS4uLiBzYW1lIHZhbHVlIGFzICJyb290IiBkZWZpbmVkIGJlbG93KSAKLSAgICogYSBwYWlyIG9mIG5vbi16ZXJvIHBvc2l0aXZlIGludGVnZXJzICh0aGUgY29udGV4dCBwb3NpdGlvbiBhbmQgdGhlIGNvbnRleHQgc2l6ZSkgCi0gICAqIGEgc2V0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIAotICAgKiBhIGZ1bmN0aW9uIGxpYnJhcnkgCi0gICAqIHRoZSBzZXQgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBpbiBzY29wZSBmb3IgdGhlIGV4cHJlc3Npb24uCi0gICAqIAotICAgKiA8cD5BdCB0aGlzIHRpbWUgdGhlIGV4YWN0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZW52aXJvbm1lbnQgaXMgYXBwbGljYXRpb24gCi0gICAqIGRlcGVuZGVudC4gIFByb2JhYmx5IGEgcHJvcGVyIGludGVyZmFjZSB3aWxsIGJlIGNyZWF0ZWQgZmFpcmx5IHNvb24uPC9wPgotICAgKiAKLSAgICogQHBhcmFtIGVudmlyb25tZW50IFRoZSBlbnZpcm9ubWVudCBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbnZpcm9ubWVudChPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLSAgICAvLyBuby1vcAotICB9Ci0KLQotICAvKioKLSAgICogQHJldHVybiBUaGUgcm9vdCBub2RlIG9mIHRoZSBJdGVyYXRvciwgYXMgc3BlY2lmaWVkIHdoZW4gaXQgd2FzIGNyZWF0ZWQuCi0gICAqIEZvciBub24tSXRlcmF0b3IgTm9kZVNldERUTXMsIHRoaXMgd2lsbCBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIGludCBnZXRSb290KCkKLSAgewotICAgIGlmKERUTS5OVUxMID09IG1fcm9vdCkKLSAgICB7Ci0gICAgICBpZihzaXplKCkgPiAwKQotICAgICAgICByZXR1cm4gaXRlbSgwKTsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9yb290OwotICB9Ci0gIAotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBleGVjQ29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgLy8gbm8tb3AsIEkgZ3Vlc3MuLi4gICgtc2IpCi0gIH0KLQotICAvKioKLSAgICogQ2xvbmUgdGhpcyBOb2RlU2V0RFRNLgotICAgKiBBdCB0aGlzIHRpbWUsIHdlIG9ubHkgZXhwZWN0IHRoaXMgdG8gYmUgdXNlZCB3aXRoIExvY1BhdGhJdGVyYXRvcnM7Ci0gICAqIGl0IG1heSBub3Qgd29yayB3aXRoIG90aGVyIGtpbmRzIG9mIE5vZGVTZXREVE1zLgotICAgKgotICAgKiBAcmV0dXJuIGEgbmV3IE5vZGVTZXREVE0gb2YgdGhlIHNhbWUgdHlwZSwgaGF2aW5nIHRoZSBzYW1lIHN0YXRlLi4uCi0gICAqIHRob3VnaCB1bmxlc3Mgb3ZlcnJpZGRlbiBpbiB0aGUgc3ViY2xhc3NlcywgaXQgbWF5IG5vdCBjb3B5IGFsbAotICAgKiB0aGUgc3RhdGUgaW5mb3JtYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gaWYgdGhpcyBzdWJjbGFzcyBvZiBOb2RlU2V0RFRNCi0gICAqIGRvZXMgbm90IHN1cHBvcnQgdGhlIGNsb25lKCkgb3BlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlU2V0RFRNIGNsb25lID0gKE5vZGVTZXREVE0pIHN1cGVyLmNsb25lKCk7Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIEl0ZXJhdG9yLCBhbmQgcmVzZXQgaXRzIHN0YXRlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlCi0gICAqIGl0ZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBhIG5ldyBOb2RlU2V0RFRNIG9mIHRoZSBzYW1lIHR5cGUsIGhhdmluZyB0aGUgc2FtZSBzdGF0ZS4uLgotICAgKiBleGNlcHQgdGhhdCB0aGUgcmVzZXQoKSBvcGVyYXRpb24gaGFzIGJlZW4gY2FsbGVkLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGlmIHRoaXMgc3ViY2xhc3Mgb2YgTm9kZVNldERUTQotICAgKiBkb2VzIG5vdCBzdXBwb3J0IHRoZSBjbG9uZSgpIG9wZXJhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBOb2RlU2V0RFRNIGNsb25lID0gKE5vZGVTZXREVE0pIGNsb25lKCk7Ci0KLSAgICBjbG9uZS5yZXNldCgpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBpdGVyYXRvci4gTWF5IGhhdmUgbm8gZWZmZWN0IG9uIG5vbi1pdGVyYXRvciBOb2Rlc2V0cy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCkKLSAgewotICAgIG1fbmV4dCA9IDA7Ci0gIH0KLQotICAvKioKLSAgICogIFRoaXMgYXR0cmlidXRlIGRldGVybWluZXMgd2hpY2ggbm9kZSB0eXBlcyBhcmUgcHJlc2VudGVkIHZpYSB0aGUKLSAgICogaXRlcmF0b3IuIFRoZSBhdmFpbGFibGUgc2V0IG9mIGNvbnN0YW50cyBpcyBkZWZpbmVkIGluIHRoZQotICAgKiA8Y29kZT5EVE1GaWx0ZXI8L2NvZGU+IGludGVyZmFjZS4gRm9yIE5vZGVTZXREVE1zLCB0aGUgbWFzayBoYXMgYmVlbgotICAgKiBoYXJkY29kZWQgdG8gc2hvdyBhbGwgbm9kZXMgZXhjZXB0IEVudGl0eVJlZmVyZW5jZSBub2Rlcywgd2hpY2ggaGF2ZQotICAgKiBubyBlcXVpdmFsZW50IGluIHRoZSBYUGF0aCBkYXRhIG1vZGVsLgotICAgKgotICAgKiBAcmV0dXJuIGludGVnZXIgdXNlZCBhcyBhIGJpdC1hcnJheSwgY29udGFpbmluZyBmbGFncyBkZWZpbmVkIGluCi0gICAqIHRoZSBET00ncyBEVE1GaWx0ZXIgY2xhc3MuIFRoZSB2YWx1ZSB3aWxsIGJlIAotICAgKiA8Y29kZT5TSE9XX0FMTCAmIH5TSE9XX0VOVElUWV9SRUZFUkVOQ0U8L2NvZGU+LCBtZWFuaW5nIHRoYXQKLSAgICogb25seSBlbnRpdHkgcmVmZXJlbmNlcyBhcmUgc3VwcHJlc3NlZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gIHsKLSAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMICYgfkRUTUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0U7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIGZpbHRlciBvYmplY3QgdXNlZCB0byBzY3JlZW4gbm9kZXMuIEZpbHRlcnMgYXJlIGFwcGxpZWQgdG8KLSAgICogZnVydGhlciByZWR1Y2UgKGFuZCByZXN0cnVjdHVyZSkgdGhlIERUTUl0ZXJhdG9yJ3MgdmlldyBvZiB0aGUKLSAgICogZG9jdW1lbnQuIEluIG91ciBjYXNlLCB3ZSB3aWxsIGJlIHVzaW5nIGhhcmRjb2RlZCBmaWx0ZXJzIGJ1aWx0Ci0gICAqIGludG8gb3VyIGl0ZXJhdG9ycy4uLiBidXQgZ2V0RmlsdGVyKCkgaXMgcGFydCBvZiB0aGUgRE9NJ3MgCi0gICAqIERUTUl0ZXJhdG9yIGludGVyZmFjZSwgc28gd2UgaGF2ZSB0byBzdXBwb3J0IGl0LgotICAgKgotICAgKiBAcmV0dXJuIG51bGwsIHdoaWNoIGlzIHNsaWdodGx5IG1pc2xlYWRpbmcuIFRydWUsIHRoZXJlIGlzIG5vCi0gICAqIHVzZXItd3JpdHRlbiBmaWx0ZXIgb2JqZWN0LCBidXQgaW4gZmFjdCB3ZSBhcmUgZG9pbmcgc29tZSB2ZXJ5Ci0gICAqIHNvcGhpc3RpY2F0ZWQgY3VzdG9tIGZpbHRlcmluZy4gQSBET00gcHVyaXN0IG1pZ2h0IHN1Z2dlc3QKLSAgICogcmV0dXJuaW5nIGEgcGxhY2Vob2xkZXIgb2JqZWN0IGp1c3QgdG8gaW5kaWNhdGUgdGhhdCB0aGlzIGlzCi0gICAqIG5vdCBnb2luZyB0byByZXR1cm4gYWxsIG5vZGVzIHNlbGVjdGVkIGJ5IHdoYXRUb1Nob3cuCi0gICAqLwotICBwdWJsaWMgRFRNRmlsdGVyIGdldEZpbHRlcigpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhlIHZhbHVlIG9mIHRoaXMgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNoaWxkcmVuIG9mIGVudGl0eQotICAgKiByZWZlcmVuY2Ugbm9kZXMgYXJlIHZpc2libGUgdG8gdGhlIGl0ZXJhdG9yLiBJZiBmYWxzZSwgdGhleSB3aWxsIGJlCi0gICAqIHNraXBwZWQgb3Zlci4KLSAgICogPGJyPiBUbyBwcm9kdWNlIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZXMKLSAgICogZXhwYW5kZWQgYW5kIGRvZXMgbm90IGV4cG9zZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGl0c2VsZiwgdXNlIHRoZQotICAgKiB3aGF0VG9TaG93IGZsYWdzIHRvIGhpZGUgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBhbmQgc2V0Ci0gICAqIGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgdG8gdHJ1ZSB3aGVuIGNyZWF0aW5nIHRoZSBpdGVyYXRvci4gVG8gcHJvZHVjZQotICAgKiBhIHZpZXcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaGFzIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYnV0IG5vIGVudGl0eQotICAgKiBleHBhbnNpb24sIHVzZSB0aGUgd2hhdFRvU2hvdyBmbGFncyB0byBzaG93IHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUKLSAgICogYW5kIHNldCBleHBhbmRFbnRpdHlSZWZlcmVuY2VzIHRvIGZhbHNlLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgZm9yIGFsbCBpdGVyYXRvcnMgYmFzZWQgb24gTm9kZVNldERUTSwgbWVhbmluZyB0aGF0IHRoZQotICAgKiBjb250ZW50cyBvZiBFbnRpdHlSZWZyZW5jZSBub2RlcyBtYXkgYmUgcmV0dXJuZWQgKHRob3VnaCB3aGF0VG9TaG93Ci0gICAqIHNheXMgdGhhdCB0aGUgRW50aXR5UmVmZXJlbmNlcyB0aGVtc2VsdmVzIGFyZSBub3Qgc2hvd24uKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSB0aGF0ICJvd25zIiBhIG5vZGUgaGFuZGxlLiAgU2luY2UgYSBub2RlIAotICAgKiBpdGVyYXRvciBtYXkgYmUgcGFzc2VkIHdpdGhvdXQgYSBEVE1NYW5hZ2VyLCB0aGlzIGFsbG93cyB0aGUgCi0gICAqIGNhbGxlciB0byBlYXNpbHkgZ2V0IHRoZSBEVE0gdXNpbmcganVzdCB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBub2RlSGFuZGxlLgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgCi0gICAgcmV0dXJuIG1fbWFuYWdlci5nZXREVE0obm9kZUhhbmRsZSk7Ci0gIH0KLSAgCi0gIC8qIEFuIGluc3RhbmNlIG9mIHRoZSBEVE1NYW5hZ2VyLiAqLwotICBEVE1NYW5hZ2VyIG1fbWFuYWdlcjsKLSAgCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIERUTU1hbmFnZXIuICBTaW5jZSBhIG5vZGUgCi0gICAqIGl0ZXJhdG9yIG1heSBiZSBwYXNzZWQgd2l0aG91dCBhIERUTU1hbmFnZXIsIHRoaXMgYWxsb3dzIHRoZSAKLSAgICogY2FsbGVyIHRvIGVhc2lseSBnZXQgdGhlIERUTU1hbmFnZXIgdXNpbmcganVzdCB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE1NYW5hZ2VyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE1NYW5hZ2VyIGdldERUTU1hbmFnZXIoKQotICB7Ci0gICAgCi0gICAgcmV0dXJuIG1fbWFuYWdlcjsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBEVE1JdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLQotICAgIGlmICgobV9uZXh0KSA8IHRoaXMuc2l6ZSgpKQotICAgIHsKLSAgICAgIGludCBuZXh0ID0gdGhpcy5lbGVtZW50QXQobV9uZXh0KTsKLQotICAgICAgbV9uZXh0Kys7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIHByZXZpb3VzIG5vZGUgaW4gdGhlIHNldCBhbmQgbW92ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBiYWNrd2FyZHMgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIHByZXZpb3VzIDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3ZlciwKLSAgICogICBvcjxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgY2FjaGVkIHR5cGUsIGFuZCBoZW5jZSBkb2Vzbid0IGtub3cgd2hhdCB0aGUgcHJldmlvdXMgbm9kZSB3YXMuCi0gICAqLwotICBwdWJsaWMgaW50IHByZXZpb3VzTm9kZSgpCi0gIHsKLQotICAgIGlmICghbV9jYWNoZU5vZGVzKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICJUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEiKTsKLQotICAgIGlmICgobV9uZXh0IC0gMSkgPiAwKQotICAgIHsKLSAgICAgIG1fbmV4dC0tOwotCi0gICAgICByZXR1cm4gdGhpcy5lbGVtZW50QXQobV9uZXh0KTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSBpdGVyYXRvciBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQgb3ZlciwgcmVsZWFzaW5nCi0gICAqIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IgaW4gdGhlIElOVkFMSUQKLSAgICogc3RhdGUuIEFmdGVyPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLCBjYWxscyB0bwotICAgKiA8Y29kZT5uZXh0Tm9kZTwvY29kZT4gb3I8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwgcmFpc2UgdGhlCi0gICAqIGV4Y2VwdGlvbiBJTlZBTElEX1NUQVRFX0VSUi4KLSAgICogPHA+Ci0gICAqIFRoaXMgb3BlcmF0aW9uIGlzIGEgbm8tb3AgaW4gTm9kZVNldERUTSwgYW5kIHdpbGwgbm90IGNhdXNlIAotICAgKiBJTlZBTElEX1NUQVRFX0VSUiB0byBiZSByYWlzZWQgYnkgbGF0ZXIgb3BlcmF0aW9ucy4KLSAgICogPC9wPgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCl7fQotICAKLSAgLyoqCi0gICAqIFNwZWNpZnkgaWYgaXQncyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhlIGl0ZXJhdG9yIGZvciByZXVzZS4KLSAgICogCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvciAKLSAgICogZm9yIHBvb2xpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhbGxvd0RldGFjaFRvUmVsZWFzZShib29sZWFuIGFsbG93UmVsZWFzZSkKLSAgewotICAgIC8vIG5vIGFjdGlvbiBmb3IgcmlnaHQgbm93LgotICB9Ci0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBOb2RlU2V0RFRNIGlzICJmcmVzaCIsIGluIG90aGVyIHdvcmRzLCBpZgotICAgKiB0aGUgZmlyc3QgbmV4dE5vZGUoKSB0aGF0IGlzIGNhbGxlZCB3aWxsIHJldHVybiB0aGUKLSAgICogZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbmV4dE5vZGUoKSB3b3VsZCByZXR1cm4gdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldCwKLSAgICogZmFsc2UgaWYgaXQgd291bGQgcmV0dXJuIGEgbGF0ZXIgb25lLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNGcmVzaCgpCi0gIHsKLSAgICByZXR1cm4gKG1fbmV4dCA9PSAwKTsKLSAgfQotCi0gIC8qKgotICAgKiBJZiBhbiBpbmRleCBpcyByZXF1ZXN0ZWQsIE5vZGVTZXREVE0gd2lsbCBjYWxsIHRoaXMgbWV0aG9kCi0gICAqIHRvIHJ1biB0aGUgaXRlcmF0b3IgdG8gdGhlIGluZGV4LiAgQnkgZGVmYXVsdCB0aGlzIHNldHMKLSAgICogbV9uZXh0IHRvIHRoZSBpbmRleC4gIElmIHRoZSBpbmRleCBhcmd1bWVudCBpcyAtMSwgdGhpcwotICAgKiBzaWduYWxzIHRoYXQgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4gdG8gdGhlIGVuZC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFBvc2l0aW9uIHRvIGFkdmFuY2UgKG9yIHJldHJlYXQpIHRvLCB3aXRoCi0gICAqIDAgcmVxdWVzdGluZyB0aGUgcmVzZXQgKCJmcmVzaCIpIHBvc2l0aW9uIGFuZCAtMSAob3IgaW5kZWVkCi0gICAqIGFueSBvdXQtb2YtYm91bmRzIHZhbHVlKSByZXF1ZXN0aW5nIHRoZSBmaW5hbCBwb3NpdGlvbi4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90Ci0gICAqIG9uZSBvZiB0aGUgdHlwZXMgd2hpY2ggc3VwcG9ydHMgaW5kZXhpbmcvY291bnRpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW5UbyhpbnQgaW5kZXgpCi0gIHsKLQotICAgIGlmICghbV9jYWNoZU5vZGVzKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICJUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBkbyBpbmRleGluZyBvciBjb3VudGluZyBmdW5jdGlvbnMhIik7Ci0KLSAgICBpZiAoKGluZGV4ID49IDApICYmIChtX25leHQgPCBtX2ZpcnN0RnJlZSkpCi0gICAgICBtX25leHQgPSBpbmRleDsKLSAgICBlbHNlCi0gICAgICBtX25leHQgPSBtX2ZpcnN0RnJlZSAtIDE7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+dGggaXRlbSBpbiB0aGUgY29sbGVjdGlvbi4gSWYKLSAgICogPGNvZGU+aW5kZXg8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vZGVzIGluCi0gICAqIHRoZSBsaXN0LCB0aGlzIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIAotICAgKiBUT0RPOiBXaGF0IGhhcHBlbnMgaWYgaW5kZXggaXMgb3V0IG9mIHJhbmdlPwotICAgKiAKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IGludG8gdGhlIGNvbGxlY3Rpb24uCi0gICAqIEByZXR1cm4gVGhlIG5vZGUgYXQgdGhlIDxjb2RlPmluZGV4PC9jb2RlPnRoIHBvc2l0aW9uIGluIHRoZQotICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhhdCBpcyBub3QgYSB2YWxpZAotICAgKiAgIGluZGV4LgotICAgKi8KLSAgcHVibGljIGludCBpdGVtKGludCBpbmRleCkKLSAgewotCi0gICAgcnVuVG8oaW5kZXgpOwotCi0gICAgcmV0dXJuIHRoaXMuZWxlbWVudEF0KGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzIGlzCi0gICAqIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4gTm90ZSB0aGF0IHRoaXMgb3BlcmF0aW9uIHJlcXVpcmVzCi0gICAqIGZpbmRpbmcgYWxsIHRoZSBtYXRjaGluZyBub2Rlcywgd2hpY2ggbWF5IGRlZmVhdCBhdHRlbXB0cyB0byBkZWZlcgotICAgKiB0aGF0IHdvcmsuCi0gICAqCi0gICAqIEByZXR1cm4gaW50ZWdlciBpbmRpY2F0aW5nIGhvdyBtYW55IG5vZGVzIGFyZSByZXByZXNlbnRlZCBieSB0aGlzIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExlbmd0aCgpCi0gIHsKLQotICAgIHJ1blRvKC0xKTsKLQotICAgIHJldHVybiB0aGlzLnNpemUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBBZGQgYSBub2RlIHRvIHRoZSBOb2RlU2V0RFRNLiBOb3QgYWxsIHR5cGVzIG9mIE5vZGVTZXREVE1zIHN1cHBvcnQgdGhpcwotICAgKiBvcGVyYXRpb24KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBhZGRlZAotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTm9kZShpbnQgbikKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHRoaXMuYWRkRWxlbWVudChuKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgYSBub2RlIGF0IGEgZ2l2ZW4gcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBuIE5vZGUgdG8gYmUgYWRkZWQKLSAgICogQHBhcmFtIHBvcyBPZmZzZXQgYXQgd2hpY2ggdGhlIG5vZGUgaXMgdG8gYmUgaW5zZXJ0ZWQsCi0gICAqIHdpdGggMCBiZWluZyB0aGUgZmlyc3QgcG9zaXRpb24uCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbnNlcnROb2RlKGludCBuLCBpbnQgcG9zKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgaW5zZXJ0RWxlbWVudEF0KG4sIHBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogUmVtb3ZlIGEgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBhZGRlZAotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlTm9kZShpbnQgbikKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHRoaXMucmVtb3ZlRWxlbWVudChuKTsKLSAgfQotCi0gIC8vICVUQkQlCi0vLyAgLyoqCi0vLyAgICogQ29weSBOb2RlTGlzdCBtZW1iZXJzIGludG8gdGhpcyBub2RlbGlzdCwgYWRkaW5nIGluCi0vLyAgICogZG9jdW1lbnQgb3JkZXIuICBJZiBhIG5vZGUgaXMgbnVsbCwgZG9uJ3QgYWRkIGl0LgotLy8gICAqCi0vLyAgICogQHBhcmFtIG5vZGVsaXN0IExpc3Qgb2Ygbm9kZXMgd2hpY2ggc2hvdWxkIG5vdyBiZSByZWZlcmVuY2VkIGJ5Ci0vLyAgICogdGhpcyBOb2RlU2V0RFRNLgotLy8gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLS8vICAgKiBhIG11dGFibGUgdHlwZS4KLS8vICAgKi8KLS8vICBwdWJsaWMgdm9pZCBhZGROb2RlcyhOb2RlTGlzdCBub2RlbGlzdCkKLS8vICB7Ci0vLwotLy8gICAgaWYgKCFtX211dGFibGUpCi0vLyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0vLwotLy8gICAgaWYgKG51bGwgIT0gbm9kZWxpc3QpICAvLyBkZWZlbnNpdmUgdG8gZml4IGEgYnVnIHRoYXQgU2Fuaml2YSByZXBvcnRlZC4KLS8vICAgIHsKLS8vICAgICAgaW50IG5DaGlsZHJlbiA9IG5vZGVsaXN0LmdldExlbmd0aCgpOwotLy8KLS8vICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuQ2hpbGRyZW47IGkrKykKLS8vICAgICAgewotLy8gICAgICAgIGludCBvYmogPSBub2RlbGlzdC5pdGVtKGkpOwotLy8KLS8vICAgICAgICBpZiAobnVsbCAhPSBvYmopCi0vLyAgICAgICAgewotLy8gICAgICAgICAgYWRkRWxlbWVudChvYmopOwotLy8gICAgICAgIH0KLS8vICAgICAgfQotLy8gICAgfQotLy8KLS8vICAgIC8vIGNoZWNrRHVwcygpOwotLy8gIH0KLQotICAvLyAlVEJEJQotLy8gIC8qKgotLy8gICAqIDxwPkNvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotLy8gICAqIGRvY3VtZW50IG9yZGVyLiAgT25seSBnZW51aW5lIG5vZGUgcmVmZXJlbmNlcyB3aWxsIGJlIGNvcGllZDsKLS8vICAgKiBudWxscyBhcHBlYXJpbmcgaW4gdGhlIHNvdXJjZSBOb2RlU2V0RFRNIHdpbGwKLS8vICAgKiBub3QgYmUgYWRkZWQgdG8gdGhpcyBvbmUuIDwvcD4KLS8vICAgKiAKLS8vICAgKiA8cD4gSW4gY2FzZSB5b3UncmUgd29uZGVyaW5nIHdoeSB0aGlzIGZ1bmN0aW9uIGlzIG5lZWRlZDogTm9kZVNldERUTQotLy8gICAqIGltcGxlbWVudHMgYm90aCBEVE1JdGVyYXRvciBhbmQgTm9kZUxpc3QuIElmIHRoaXMgbWV0aG9kIGlzbid0Ci0vLyAgICogcHJvdmlkZWQsIEphdmEgY2FuJ3QgZGVjaWRlIHdoaWNoIG9mIHRob3NlIHRvIHVzZSB3aGVuIGFkZE5vZGVzKCkKLS8vICAgKiBpcyBpbnZva2VkLiBQcm92aWRpbmcgdGhlIG1vcmUtZXhwbGljaXQgbWF0Y2ggYXZvaWRzIHRoYXQKLS8vICAgKiBhbWJpZ3VpdHkuKTwvcD4KLS8vICAgKgotLy8gICAqIEBwYXJhbSBucyBOb2RlU2V0RFRNIHdob3NlIG1lbWJlcnMgc2hvdWxkIGJlIG1lcmdlZCBpbnRvIHRoaXMgTm9kZVNldERUTS4KLS8vICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0vLyAgICogYSBtdXRhYmxlIHR5cGUuCi0vLyAgICovCi0vLyAgcHVibGljIHZvaWQgYWRkTm9kZXMoTm9kZVNldERUTSBucykKLS8vICB7Ci0vLwotLy8gICAgaWYgKCFtX211dGFibGUpCi0vLyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0vLwotLy8gICAgYWRkTm9kZXMoKERUTUl0ZXJhdG9yKSBucyk7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBDb3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuICBOdWxsIHJlZmVyZW5jZXMgYXJlIG5vdCBhZGRlZC4KLSAgICoKLSAgICogQHBhcmFtIGl0ZXJhdG9yIERUTUl0ZXJhdG9yIHdoaWNoIHlpZWxkcyB0aGUgbm9kZXMgdG8gYmUgYWRkZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhZGROb2RlcyhEVE1JdGVyYXRvciBpdGVyYXRvcikKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGlmIChudWxsICE9IGl0ZXJhdG9yKSAgLy8gZGVmZW5zaXZlIHRvIGZpeCBhIGJ1ZyB0aGF0IFNhbmppdmEgcmVwb3J0ZWQuCi0gICAgewotICAgICAgaW50IG9iajsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChvYmogPSBpdGVyYXRvci5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgYWRkRWxlbWVudChvYmopOwotICAgICAgfQotICAgIH0KLQotICAgIC8vIGNoZWNrRHVwcygpOwotICB9Ci0KLSAgLy8gJVRCRCUKLS8vICAvKioKLS8vICAgKiBDb3B5IE5vZGVMaXN0IG1lbWJlcnMgaW50byB0aGlzIG5vZGVsaXN0LCBhZGRpbmcgaW4KLS8vICAgKiBkb2N1bWVudCBvcmRlci4gIElmIGEgbm9kZSBpcyBudWxsLCBkb24ndCBhZGQgaXQuCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gbm9kZWxpc3QgTGlzdCBvZiBub2RlcyB0byBiZSBhZGRlZAotLy8gICAqIEBwYXJhbSBzdXBwb3J0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0vLyAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mIAotLy8gICAqIGEgbXV0YWJsZSB0eXBlLgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIGFkZE5vZGVzSW5Eb2NPcmRlcihOb2RlTGlzdCBub2RlbGlzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0vLyAgewotLy8KLS8vICAgIGlmICghbV9tdXRhYmxlKQotLy8gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotLy8KLS8vICAgIGludCBuQ2hpbGRyZW4gPSBub2RlbGlzdC5nZXRMZW5ndGgoKTsKLS8vCi0vLyAgICBmb3IgKGludCBpID0gMDsgaSA8IG5DaGlsZHJlbjsgaSsrKQotLy8gICAgewotLy8gICAgICBpbnQgbm9kZSA9IG5vZGVsaXN0Lml0ZW0oaSk7Ci0vLwotLy8gICAgICBpZiAobnVsbCAhPSBub2RlKQotLy8gICAgICB7Ci0vLyAgICAgICAgYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgc3VwcG9ydCk7Ci0vLyAgICAgIH0KLS8vICAgIH0KLS8vICB9Ci0KLSAgLyoqCi0gICAqIENvcHkgTm9kZUxpc3QgbWVtYmVycyBpbnRvIHRoaXMgbm9kZWxpc3QsIGFkZGluZyBpbgotICAgKiBkb2N1bWVudCBvcmRlci4gIElmIGEgbm9kZSBpcyBudWxsLCBkb24ndCBhZGQgaXQuCi0gICAqCi0gICAqIEBwYXJhbSBpdGVyYXRvciBEVE1JdGVyYXRvciB3aGljaCB5aWVsZHMgdGhlIG5vZGVzIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkTm9kZXNJbkRvY09yZGVyKERUTUl0ZXJhdG9yIGl0ZXJhdG9yLCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIGludCBub2RlOwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IChub2RlID0gaXRlcmF0b3IubmV4dE5vZGUoKSkpCi0gICAgewotICAgICAgYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgc3VwcG9ydCk7Ci0gICAgfQotICB9Ci0KLSAgLy8gJVRCRCUKLS8vICAvKioKLS8vICAgKiBBZGQgdGhlIG5vZGUgbGlzdCB0byB0aGlzIG5vZGUgc2V0IGluIGRvY3VtZW50IG9yZGVyLgotLy8gICAqCi0vLyAgICogQHBhcmFtIHN0YXJ0IGluZGV4LgotLy8gICAqIEBwYXJhbSBlbmQgaW5kZXguCi0vLyAgICogQHBhcmFtIHRlc3RJbmRleCBpbmRleC4KLS8vICAgKiBAcGFyYW0gbm9kZWxpc3QgVGhlIG5vZGVsaXN0IHRvIGFkZC4KLS8vICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotLy8gICAqCi0vLyAgICogQHJldHVybiBmYWxzZSBhbHdheXMuCi0vLyAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mIAotLy8gICAqIGEgbXV0YWJsZSB0eXBlLgotLy8gICAqLwotLy8gIHByaXZhdGUgYm9vbGVhbiBhZGROb2Rlc0luRG9jT3JkZXIoaW50IHN0YXJ0LCBpbnQgZW5kLCBpbnQgdGVzdEluZGV4LAotLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZUxpc3Qgbm9kZWxpc3QsIFhQYXRoQ29udGV4dCBzdXBwb3J0KQotLy8gIHsKLS8vCi0vLyAgICBpZiAoIW1fbXV0YWJsZSkKLS8vICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLS8vCi0vLyAgICBib29sZWFuIGZvdW5kaXQgPSBmYWxzZTsKLS8vICAgIGludCBpOwotLy8gICAgaW50IG5vZGUgPSBub2RlbGlzdC5pdGVtKHRlc3RJbmRleCk7Ci0vLwotLy8gICAgZm9yIChpID0gZW5kOyBpID49IHN0YXJ0OyBpLS0pCi0vLyAgICB7Ci0vLyAgICAgIGludCBjaGlsZCA9IGVsZW1lbnRBdChpKTsKLS8vCi0vLyAgICAgIGlmIChjaGlsZCA9PSBub2RlKQotLy8gICAgICB7Ci0vLyAgICAgICAgaSA9IC0yOyAgLy8gRHVwbGljYXRlLCBzdXBwcmVzcyBpbnNlcnQKLS8vCi0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIH0KLS8vCi0vLyAgICAgIGlmICghc3VwcG9ydC5nZXRET01IZWxwZXIoKS5pc05vZGVBZnRlcihub2RlLCBjaGlsZCkpCi0vLyAgICAgIHsKLS8vICAgICAgICBpbnNlcnRFbGVtZW50QXQobm9kZSwgaSArIDEpOwotLy8KLS8vICAgICAgICB0ZXN0SW5kZXgtLTsKLS8vCi0vLyAgICAgICAgaWYgKHRlc3RJbmRleCA+IDApCi0vLyAgICAgICAgewotLy8gICAgICAgICAgYm9vbGVhbiBmb3VuZFByZXYgPSBhZGROb2Rlc0luRG9jT3JkZXIoMCwgaSwgdGVzdEluZGV4LCBub2RlbGlzdCwKLS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnQpOwotLy8KLS8vICAgICAgICAgIGlmICghZm91bmRQcmV2KQotLy8gICAgICAgICAgewotLy8gICAgICAgICAgICBhZGROb2Rlc0luRG9jT3JkZXIoaSwgc2l6ZSgpIC0gMSwgdGVzdEluZGV4LCBub2RlbGlzdCwgc3VwcG9ydCk7Ci0vLyAgICAgICAgICB9Ci0vLyAgICAgICAgfQotLy8KLS8vICAgICAgICBicmVhazsKLS8vICAgICAgfQotLy8gICAgfQotLy8KLS8vICAgIGlmIChpID09IC0xKQotLy8gICAgewotLy8gICAgICBpbnNlcnRFbGVtZW50QXQobm9kZSwgMCk7Ci0vLyAgICB9Ci0vLwotLy8gICAgcmV0dXJuIGZvdW5kaXQ7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBBZGQgdGhlIG5vZGUgaW50byBhIHZlY3RvciBvZiBub2RlcyB3aGVyZSBpdCBzaG91bGQgb2NjdXIgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuCi0gICAqIEBwYXJhbSB2IFZlY3RvciBvZiBub2RlcywgcHJlc3VtYWJseSBjb250YWluaW5nIE5vZGVzCi0gICAqIEBwYXJhbSBvYmogTm9kZSBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gdGVzdCB0cnVlIGlmIHdlIHNob3VsZCB0ZXN0IGZvciBkb2Mgb3JkZXIKLSAgICogQHBhcmFtIHN1cHBvcnQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiBpbnNlcnRJbmRleC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgYWRkTm9kZUluRG9jT3JkZXIoaW50IG5vZGUsIGJvb2xlYW4gdGVzdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBpbnQgaW5zZXJ0SW5kZXggPSAtMTsKLQotICAgIGlmICh0ZXN0KQotICAgIHsKLQotICAgICAgLy8gVGhpcyBuZWVkcyB0byBkbyBhIGJpbmFyeSBzZWFyY2gsIGJ1dCBhIGJpbmFyeSBzZWFyY2ggCi0gICAgICAvLyBpcyBzb21ld2hhdCB0b3VnaCBiZWNhdXNlIHRoZSBzZXF1ZW5jZSB0ZXN0IGludm9sdmVzIAotICAgICAgLy8gdHdvIG5vZGVzLgotICAgICAgaW50IHNpemUgPSBzaXplKCksIGk7Ci0KLSAgICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID49IDA7IGktLSkKLSAgICAgIHsKLSAgICAgICAgaW50IGNoaWxkID0gZWxlbWVudEF0KGkpOwotCi0gICAgICAgIGlmIChjaGlsZCA9PSBub2RlKQotICAgICAgICB7Ci0gICAgICAgICAgaSA9IC0yOyAgLy8gRHVwbGljYXRlLCBzdXBwcmVzcyBpbnNlcnQKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0KLSAgICAgICAgRFRNIGR0bSA9IHN1cHBvcnQuZ2V0RFRNKG5vZGUpOwotICAgICAgICBpZiAoIWR0bS5pc05vZGVBZnRlcihub2RlLCBjaGlsZCkpCi0gICAgICAgIHsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBpZiAoaSAhPSAtMikKLSAgICAgIHsKLSAgICAgICAgaW5zZXJ0SW5kZXggPSBpICsgMTsKLQotICAgICAgICBpbnNlcnRFbGVtZW50QXQobm9kZSwgaW5zZXJ0SW5kZXgpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaW5zZXJ0SW5kZXggPSB0aGlzLnNpemUoKTsKLQotICAgICAgYm9vbGVhbiBmb3VuZGl0ID0gZmFsc2U7Ci0KLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5zZXJ0SW5kZXg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgaWYgKGkgPT0gbm9kZSkKLSAgICAgICAgewotICAgICAgICAgIGZvdW5kaXQgPSB0cnVlOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgaWYgKCFmb3VuZGl0KQotICAgICAgICBhZGRFbGVtZW50KG5vZGUpOwotICAgIH0KLQotICAgIC8vIGNoZWNrRHVwcygpOwotICAgIHJldHVybiBpbnNlcnRJbmRleDsKLSAgfSAgLy8gZW5kIGFkZE5vZGVJbkRvY09yZGVyKFZlY3RvciB2LCBPYmplY3Qgb2JqKQotCi0gIC8qKgotICAgKiBBZGQgdGhlIG5vZGUgaW50byBhIHZlY3RvciBvZiBub2RlcyB3aGVyZSBpdCBzaG91bGQgb2NjdXIgaW4KLSAgICogZG9jdW1lbnQgb3JkZXIuCi0gICAqIEBwYXJhbSB2IFZlY3RvciBvZiBub2RlcywgcHJlc3VtYWJseSBjb250YWluaW5nIE5vZGVzCi0gICAqIEBwYXJhbSBvYmogTm9kZSBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBpbmRleCB3aGVyZSBpdCB3YXMgaW5zZXJ0ZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgaW50IGFkZE5vZGVJbkRvY09yZGVyKGludCBub2RlLCBYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHJldHVybiBhZGROb2RlSW5Eb2NPcmRlcihub2RlLCB0cnVlLCBzdXBwb3J0KTsKLSAgfSAgLy8gZW5kIGFkZE5vZGVJbkRvY09yZGVyKFZlY3RvciB2LCBPYmplY3Qgb2JqKQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc2l6ZSBvZiB0aGlzIG5vZGUgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBzaXplKCkKLSAgewotICAgIHJldHVybiBzdXBlci5zaXplKCk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIGEgTm9kZSBvbnRvIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSB2YWx1ZSBUaGUgbm9kZSB0byBiZSBhZGRlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFkZEVsZW1lbnQoaW50IHZhbHVlKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgc3VwZXIuYWRkRWxlbWVudCh2YWx1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0cyB0aGUgc3BlY2lmaWVkIG5vZGUgaW4gdGhpcyB2ZWN0b3IgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KLSAgICogRWFjaCBjb21wb25lbnQgaW4gdGhpcyB2ZWN0b3Igd2l0aCBhbiBpbmRleCBncmVhdGVyIG9yIGVxdWFsIHRvCi0gICAqIHRoZSBzcGVjaWZpZWQgaW5kZXggaXMgc2hpZnRlZCB1cHdhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgZ3JlYXRlcgotICAgKiB0aGFuIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIHZhbHVlIFRoZSBub2RlIHRvIGJlIGluc2VydGVkLgotICAgKiBAcGFyYW0gYXQgVGhlIGluZGV4IHdoZXJlIHRoZSBpbnNlcnQgc2hvdWxkIG9jY3VyLgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5zZXJ0RWxlbWVudEF0KGludCB2YWx1ZSwgaW50IGF0KQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgc3VwZXIuaW5zZXJ0RWxlbWVudEF0KHZhbHVlLCBhdCk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwZW5kIHRoZSBub2RlcyB0byB0aGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVzIFRoZSBub2RlcyB0byBiZSBhcHBlbmRlZCB0byB0aGlzIG5vZGUgc2V0LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kTm9kZXMoTm9kZVZlY3RvciBub2RlcykKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHN1cGVyLmFwcGVuZE5vZGVzKG5vZGVzKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnRzIHRoZSBzcGVjaWZpZWQgbm9kZSBpbiB0aGlzIHZlY3RvciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgotICAgKiBFYWNoIGNvbXBvbmVudCBpbiB0aGlzIHZlY3RvciB3aXRoIGFuIGluZGV4IGdyZWF0ZXIgb3IgZXF1YWwgdG8KLSAgICogdGhlIHNwZWNpZmllZCBpbmRleCBpcyBzaGlmdGVkIHVwd2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBncmVhdGVyCi0gICAqIHRoYW4gdGhlIHZhbHVlIGl0IGhhZCBwcmV2aW91c2x5LgotICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gdGhyb3duIGlmIHRoaXMgTm9kZVNldERUTSBpcyBub3Qgb2YgCi0gICAqIGEgbXV0YWJsZSB0eXBlLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVtb3ZlQWxsRWxlbWVudHMoKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgc3VwZXIucmVtb3ZlQWxsRWxlbWVudHMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBmcm9tIHRoaXMgdmVjdG9yLgotICAgKiBJZiB0aGUgb2JqZWN0IGlzIGZvdW5kIGluIHRoaXMgdmVjdG9yLCBlYWNoIGNvbXBvbmVudCBpbiB0aGUgdmVjdG9yCi0gICAqIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgb2JqZWN0J3MgaW5kZXggaXMgc2hpZnRlZAotICAgKiBkb3dud2FyZCB0byBoYXZlIGFuIGluZGV4IG9uZSBzbWFsbGVyIHRoYW4gdGhlIHZhbHVlIGl0IGhhZAotICAgKiBwcmV2aW91c2x5LgotICAgKgotICAgKiBAcGFyYW0gcyBUaGUgbm9kZSB0byBiZSByZW1vdmVkLgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIG5vZGUgd2FzIHN1Y2Nlc3NmdWxseSByZW1vdmVkCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiByZW1vdmVFbGVtZW50KGludCBzKQotICB7Ci0KLSAgICBpZiAoIW1fbXV0YWJsZSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05PREVTRVREVE1fTk9UX01VVEFCTEUsIG51bGwpKTsgLy8iVGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBtdXRhYmxlISIpOwotCi0gICAgcmV0dXJuIHN1cGVyLnJlbW92ZUVsZW1lbnQocyk7Ci0gIH0KLQotICAvKioKLSAgICogRGVsZXRlcyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIEVhY2ggY29tcG9uZW50IGluCi0gICAqIHRoaXMgdmVjdG9yIHdpdGggYW4gaW5kZXggZ3JlYXRlciBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkCi0gICAqIGluZGV4IGlzIHNoaWZ0ZWQgZG93bndhcmQgdG8gaGF2ZSBhbiBpbmRleCBvbmUgc21hbGxlciB0aGFuCi0gICAqIHRoZSB2YWx1ZSBpdCBoYWQgcHJldmlvdXNseS4KLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSBub2RlIHRvIGJlIHJlbW92ZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZW1vdmVFbGVtZW50QXQoaW50IGkpCi0gIHsKLQotICAgIGlmICghbV9tdXRhYmxlKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSwgbnVsbCkpOyAvLyJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUhIik7Ci0KLSAgICBzdXBlci5yZW1vdmVFbGVtZW50QXQoaSk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0cyB0aGUgY29tcG9uZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBvYmplY3QuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIFRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlICBUaGUgbm9kZSB0byBiZSBzZXQuCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG5vZGUgdG8gYmUgcmVwbGFjZWQuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBtdXRhYmxlIHR5cGUuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbGVtZW50QXQoaW50IG5vZGUsIGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHN1cGVyLnNldEVsZW1lbnRBdChub2RlLCBpbmRleCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTYW1lIGFzIHNldEVsZW1lbnRBdC4KLSAgICoKLSAgICogQHBhcmFtIG5vZGUgIFRoZSBub2RlIHRvIGJlIHNldC4KLSAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBiZSByZXBsYWNlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mIAotICAgKiBhIG11dGFibGUgdHlwZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEl0ZW0oaW50IG5vZGUsIGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKCFtX211dGFibGUpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OT0RFU0VURFRNX05PVF9NVVRBQkxFLCBudWxsKSk7IC8vIlRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSEiKTsKLQotICAgIHN1cGVyLnNldEVsZW1lbnRBdChub2RlLCBpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBudGggZWxlbWVudC4KLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IG9mIHRoZSByZXF1ZXN0ZWQgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiBOb2RlIGF0IHNwZWNpZmllZCBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZWxlbWVudEF0KGludCBpKQotICB7Ci0KLSAgICBydW5UbyhpKTsKLQotICAgIHJldHVybiBzdXBlci5lbGVtZW50QXQoaSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHMgTm9kZSB0byBsb29rIGZvcgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGdpdmVuIG5vZGUgd2FzIGZvdW5kLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoaW50IHMpCi0gIHsKLQotICAgIHJ1blRvKC0xKTsKLQotICAgIHJldHVybiBzdXBlci5jb250YWlucyhzKTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIE5vZGUgdG8gbG9vayBmb3IKLSAgICogQHBhcmFtIGluZGV4IEluZGV4IG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSBzZWFyY2gKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIG9iamVjdAotICAgKiBhcmd1bWVudCBpbiB0aGlzIHZlY3RvciBhdCBwb3NpdGlvbiBpbmRleCBvciBsYXRlciBpbiB0aGUKLSAgICogdmVjdG9yOyByZXR1cm5zIC0xIGlmIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKGludCBlbGVtLCBpbnQgaW5kZXgpCi0gIHsKLQotICAgIHJ1blRvKC0xKTsKLQotICAgIHJldHVybiBzdXBlci5pbmRleE9mKGVsZW0sIGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBTZWFyY2hlcyBmb3IgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiB0aGUgZ2l2ZW4gYXJndW1lbnQsCi0gICAqIGJlZ2lubmluZyB0aGUgc2VhcmNoIGF0IGluZGV4LCBhbmQgdGVzdGluZyBmb3IgZXF1YWxpdHkKLSAgICogdXNpbmcgdGhlIGVxdWFscyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBlbGVtIE5vZGUgdG8gbG9vayBmb3IgCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBvYmplY3QKLSAgICogYXJndW1lbnQgaW4gdGhpcyB2ZWN0b3IgYXQgcG9zaXRpb24gaW5kZXggb3IgbGF0ZXIgaW4gdGhlCi0gICAqIHZlY3RvcjsgcmV0dXJucyAtMSBpZiB0aGUgb2JqZWN0IGlzIG5vdCBmb3VuZC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgZWxlbSkKLSAgewotCi0gICAgcnVuVG8oLTEpOwotCi0gICAgcmV0dXJuIHN1cGVyLmluZGV4T2YoZWxlbSk7Ci0gIH0KLQotICAvKiogSWYgdGhpcyBub2RlIGlzIGJlaW5nIHVzZWQgYXMgYW4gaXRlcmF0b3IsIHRoZSBuZXh0IGluZGV4IHRoYXQgbmV4dE5vZGUoKQotICAgKiAgd2lsbCByZXR1cm4uICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX25leHQgPSAwOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdoaWNoIGlzIG9uZSBsZXNzIHRoYW4KLSAgICogdGhlIG5leHQgbmV4dE5vZGUoKSBjYWxsIHdpbGwgcmV0cmlldmUuICBpLmUuIGlmCi0gICAqIHlvdSBjYWxsIGdldEN1cnJlbnRQb3MoKSBhbmQgdGhlIHJldHVybiBpcyAwLCB0aGUgbmV4dAotICAgKiBmZXRjaCB3aWxsIHRha2UgcGxhY2UgYXQgaW5kZXggMS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW5kZXguCi0gICAqLwotICBwdWJsaWMgaW50IGdldEN1cnJlbnRQb3MoKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dDsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG5vZGUgc2V0LgotICAgKiBAcGFyYW0gaSBNdXN0IGJlIGEgdmFsaWQgaW5kZXguCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiB0aHJvd24gaWYgdGhpcyBOb2RlU2V0RFRNIGlzIG5vdCBvZiAKLSAgICogYSBjYWNoZWQgdHlwZSwgYW5kIHRodXMgZG9lc24ndCBwZXJtaXQgaW5kZXhlZCBhY2Nlc3MuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50UG9zKGludCBpKQotICB7Ci0KLSAgICBpZiAoIW1fY2FjaGVOb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgbV9uZXh0ID0gaTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGxhc3QgZmV0Y2hlZCBub2RlLiAgTmVlZGVkIHRvIHN1cHBvcnQgdGhlIFVuaW9uUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsYXN0IGZldGNoZWQgbm9kZS4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiB0aGlzIE5vZGVTZXREVE0gaXMgbm90IG9mIAotICAgKiBhIGNhY2hlZCB0eXBlLCBhbmQgdGh1cyBkb2Vzbid0IHBlcm1pdCBpbmRleGVkIGFjY2Vzcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q3VycmVudE5vZGUoKQotICB7Ci0KLSAgICBpZiAoIW1fY2FjaGVOb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgaW50IHNhdmVkID0gbV9uZXh0OwotICAgIGludCBuID0gKG1fbmV4dCA8IG1fZmlyc3RGcmVlKSA/IGVsZW1lbnRBdChtX25leHQpIDogRFRNLk5VTEw7Ci0gICAgbV9uZXh0ID0gc2F2ZWQ7IC8vIEhBQ0s6IEkgdGhpbmsgdGhpcyBpcyBhIGJpdCBvZiBhIGhhY2suICAtc2IKLSAgICByZXR1cm4gbjsKLSAgfQotCi0gIC8qKiBUcnVlIGlmIHRoaXMgbGlzdCBjYW4gYmUgbXV0YXRlZC4gICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgYm9vbGVhbiBtX211dGFibGUgPSB0cnVlOwotCi0gIC8qKiBUcnVlIGlmIHRoaXMgbGlzdCBpcyBjYWNoZWQuCi0gICAqICBAc2VyaWFsICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGJvb2xlYW4gbV9jYWNoZU5vZGVzID0gdHJ1ZTsKLSAgCi0gIC8qKiBUaGUgcm9vdCBvZiB0aGUgaXRlcmF0aW9uLCBpZiBhdmFpbGFibGUuICovCi0gIHByb3RlY3RlZCBpbnQgbV9yb290ID0gRFRNLk5VTEw7Ci0KLSAgLyoqCi0gICAqIEdldCB3aGV0aGVyIG9yIG5vdCB0aGlzIGlzIGEgY2FjaGVkIG5vZGUgc2V0LgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBsaXN0IGlzIGNhY2hlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldFNob3VsZENhY2hlTm9kZXMoKQotICB7Ci0gICAgcmV0dXJuIG1fY2FjaGVOb2RlczsKLSAgfQotCi0gIC8qKgotICAgKiBJZiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGlzIGNhbGxlZCwgdGhlbiBub2RlcyB3aWxsCi0gICAqIGJlIGNhY2hlZC4gIFRoZXkgYXJlIG5vdCBjYWNoZWQgYnkgZGVmYXVsdC4gVGhpcyBzd2l0Y2ggbXVzdAotICAgKiBiZSBzZXQgYmVmb3JlIHRoZSBmaXJzdCBjYWxsIHRvIG5leHROb2RlIGlzIG1hZGUsIHRvIGVuc3VyZQotICAgKiB0aGF0IGFsbCBub2RlcyBhcmUgY2FjaGVkLgotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoaXMgbm9kZSBzZXQgc2hvdWxkIGJlIGNhY2hlZC4KLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIHRocm93biBpZiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8KLSAgICogcmVxdWVzdCBjYWNoaW5nIGFmdGVyIHdlJ3ZlIGFscmVhZHkgYmVndW4gc3RlcHBpbmcgdGhyb3VnaCB0aGUKLSAgICogbm9kZXMgaW4gdGhpcyBzZXQuCi0gICovCi0gIHB1YmxpYyB2b2lkIHNldFNob3VsZENhY2hlTm9kZXMoYm9vbGVhbiBiKQotICB7Ci0KLSAgICBpZiAoIWlzRnJlc2goKSkKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiQ2FuIG5vdCBjYWxsIHNldFNob3VsZENhY2hlTm9kZXMgYWZ0ZXIgbmV4dE5vZGUgaGFzIGJlZW4gY2FsbGVkISIpOwotCi0gICAgbV9jYWNoZU5vZGVzID0gYjsKLSAgICBtX211dGFibGUgPSB0cnVlOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpdGVyYXRvciBjYW4gaGF2ZSBub2RlcyBhZGRlZCB0byBpdCBvciBzZXQgdmlhIAotICAgKiB0aGUgPGNvZGU+c2V0SXRlbShpbnQgbm9kZSwgaW50IGluZGV4KTwvY29kZT4gbWV0aG9kLgotICAgKiAKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlbGlzdCBjYW4gYmUgbXV0YXRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTXV0YWJsZSgpCi0gIHsKLSAgICByZXR1cm4gbV9tdXRhYmxlOwotICB9Ci0gIAotICB0cmFuc2llbnQgcHJpdmF0ZSBpbnQgbV9sYXN0ID0gMDsKLSAgCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdCgpCi0gIHsKLSAgICByZXR1cm4gbV9sYXN0OwotICB9Ci0gIAotICBwdWJsaWMgdm9pZCBzZXRMYXN0KGludCBsYXN0KQotICB7Ci0gICAgbV9sYXN0ID0gbGFzdDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudCAKLSAgICogb3JkZXIuCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgYXMgYSBkZWZhdWx0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2NPcmRlcmVkKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqIAotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZSAKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIC0xOwotICB9Ci0gIAotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9Tb3VyY2VUcmVlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9Tb3VyY2VUcmVlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmMDQ2MjkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvU291cmNlVHJlZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aDsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgb2JqZWN0IHJlcHJlc2VudHMgYSBTb3VyY2UgVHJlZSwgYW5kIGFueSBhc3NvY2lhdGVkCi0gKiBpbmZvcm1hdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIFNvdXJjZVRyZWUKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgU291cmNlVHJlZQotICAgKgotICAgKgotICAgKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIGEgCi0gICAqIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0gbm9kZS4KLSAgICogQHBhcmFtIHVybCBUaGUgVVJJIG9mIHRoZSBzb3VyY2UgdHJlZS4KLSAgICovCi0gIHB1YmxpYyBTb3VyY2VUcmVlKGludCByb290LCBTdHJpbmcgdXJsKQotICB7Ci0gICAgbV9yb290ID0gcm9vdDsKLSAgICBtX3VybCA9IHVybDsKLSAgfQotCi0gIC8qKiBUaGUgVVJJIG9mIHRoZSBzb3VyY2UgdHJlZS4gICAqLwotICBwdWJsaWMgU3RyaW5nIG1fdXJsOwotCi0gIC8qKiBUaGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIGEgCi0gICAqIHtAbGluayBvcmcudzNjLmRvbS5Eb2N1bWVudH0gbm9kZS4gICovCi0gIHB1YmxpYyBpbnQgbV9yb290OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvU291cmNlVHJlZU1hbmFnZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1NvdXJjZVRyZWVNYW5hZ2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE5N2I2MWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvU291cmNlVHJlZU1hbmFnZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotCi1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LmhlbHBlcnMuWE1MUmVhZGVyRmFjdG9yeTsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRW50aXR5UmVzb2x2ZXI7Ci0KLS8vIGltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN5c3RlbUlEUmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU0FYU291cmNlTG9jYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLS8qKgotICogVGhpcyBjbGFzcyBib3R0bGVuZWNrcyBhbGwgbWFuYWdlbWVudCBvZiBzb3VyY2UgdHJlZXMuICBUaGUgbWV0aG9kcwotICogaW4gdGhpcyBjbGFzcyBzaG91bGQgYWxsb3cgZWFzeSBnYXJiYWdlIGNvbGxlY3Rpb24gb2Ygc291cmNlCi0gKiB0cmVlcyAobm90IHlldCEpLCBhbmQgc2hvdWxkIGNlbnRyYWxpemUgcGFyc2luZyBmb3IgdGhvc2Ugc291cmNlIHRyZWVzLgotICovCi1wdWJsaWMgY2xhc3MgU291cmNlVHJlZU1hbmFnZXIKLXsKLQotICAvKiogVmVjdG9yIG9mIFNvdXJjZVRyZWUgb2JqZWN0cyB0aGF0IHRoaXMgbWFuYWdlciBtYW5hZ2VzLiAqLwotICBwcml2YXRlIFZlY3RvciBtX3NvdXJjZVRyZWUgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBsaXN0IG9mIFNvdXJjZVRyZWUgb2JqZWN0cyB0aGF0IHRoaXMgbWFuYWdlciBtYW5hZ2VzLgotICAgKgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0gICAgbV9zb3VyY2VUcmVlID0gbmV3IFZlY3RvcigpOwotICB9Ci0KLSAgLyoqIFRoZSBUckFYIFVSSSByZXNvbHZlciB1c2VkIHRvIG9idGFpbiBzb3VyY2UgdHJlZXMuICovCi0gIFVSSVJlc29sdmVyIG1fdXJpUmVzb2x2ZXI7Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogZG9jdW1lbnQoKSwgZXRjLgotICAgKiBAcGFyYW0gcmVzb2x2ZXIgQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgVVJJUmVzb2x2ZXIgaW50ZXJmYWNlLAotICAgKiBvciBudWxsLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpCi0gIHsKLSAgICBtX3VyaVJlc29sdmVyID0gcmVzb2x2ZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBvYmplY3QgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVzb2x2ZSBVUklzIHVzZWQgaW4KLSAgICogZG9jdW1lbnQoKSwgZXRjLgotICAgKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIFVSSVJlc29sdmVyIGludGVyZmFjZSwKLSAgICogb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBVUklSZXNvbHZlciBnZXRVUklSZXNvbHZlcigpCi0gIHsKLSAgICByZXR1cm4gbV91cmlSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIGRvY3VtZW50LCBmaW5kIHRoZSBVUkwgYXNzb2NpYXRlZCB3aXRoIHRoYXQgZG9jdW1lbnQuCi0gICAqIEBwYXJhbSBvd25lciBEb2N1bWVudCB0aGF0IHdhcyBwcmV2aW91c2x5IHByb2Nlc3NlZCBieSB0aGlzIGxpYWlzb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGJhc2UgVVJJIG9mIHRoZSBvd25lciBhcmd1bWVudC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZmluZFVSSUZyb21Eb2MoaW50IG93bmVyKQotICB7Ci0gICAgaW50IG4gPSBtX3NvdXJjZVRyZWUuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgU291cmNlVHJlZSBzVHJlZSA9IChTb3VyY2VUcmVlKSBtX3NvdXJjZVRyZWUuZWxlbWVudEF0KGkpOwotCi0gICAgICBpZiAob3duZXIgPT0gc1RyZWUubV9yb290KQotICAgICAgICByZXR1cm4gc1RyZWUubV91cmw7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyB3aWxsIGJlIGNhbGxlZCBieSB0aGUgcHJvY2Vzc29yIHdoZW4gaXQgZW5jb3VudGVycwotICAgKiBhbiB4c2w6aW5jbHVkZSwgeHNsOmltcG9ydCwgb3IgZG9jdW1lbnQoKSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGJhc2UgVGhlIGJhc2UgVVJJIHRoYXQgc2hvdWxkIGJlIHVzZWQuCi0gICAqIEBwYXJhbSB1cmxTdHJpbmcgVmFsdWUgZnJvbSBhbiB4c2w6aW1wb3J0IG9yIHhzbDppbmNsdWRlJ3MgaHJlZiBhdHRyaWJ1dGUsCi0gICAqIG9yIGEgVVJJIHNwZWNpZmllZCBpbiB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbi4KLSAgICogCi0gICAqIEByZXR1cm4gYSBTb3VyY2UgdGhhdCBjYW4gYmUgdXNlZCB0byBwcm9jZXNzIHRoZSByZXNvdXJjZS4KLSAgICoKLSAgICogQHRocm93cyBJT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU291cmNlIHJlc29sdmVVUkkoCi0gICAgICAgICAgU3RyaW5nIGJhc2UsIFN0cmluZyB1cmxTdHJpbmcsIFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KLSAgewotCi0gICAgU291cmNlIHNvdXJjZSA9IG51bGw7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3VyaVJlc29sdmVyKQotICAgIHsKLSAgICAgIHNvdXJjZSA9IG1fdXJpUmVzb2x2ZXIucmVzb2x2ZSh1cmxTdHJpbmcsIGJhc2UpOwotICAgIH0KLQotICAgIGlmIChudWxsID09IHNvdXJjZSkKLSAgICB7Ci0gICAgICBTdHJpbmcgdXJpID0gU3lzdGVtSURSZXNvbHZlci5nZXRBYnNvbHV0ZVVSSSh1cmxTdHJpbmcsIGJhc2UpOwotCi0gICAgICBzb3VyY2UgPSBuZXcgU3RyZWFtU291cmNlKHVyaSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHNvdXJjZTsKLSAgfQotCi0gIC8qKgotICAgKiBQdXQgdGhlIHNvdXJjZSB0cmVlIHJvb3Qgbm9kZSBpbiB0aGUgZG9jdW1lbnQgY2FjaGUuCi0gICAqIFRPRE86IFRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgYSBMT1QgbW9yZSBzb3BoaXN0aWNhdGVkLgotICAgKgotICAgKiBAcGFyYW0gbiBUaGUgbm9kZSB0byBjYWNoZS4KLSAgICogQHBhcmFtIHNvdXJjZSBUaGUgU291cmNlIG9iamVjdCB0byBjYWNoZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHB1dERvY3VtZW50SW5DYWNoZShpbnQgbiwgU291cmNlIHNvdXJjZSkKLSAgewotCi0gICAgaW50IGNhY2hlZE5vZGUgPSBnZXROb2RlKHNvdXJjZSk7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gY2FjaGVkTm9kZSkKLSAgICB7Ci0gICAgICBpZiAoIShjYWNoZWROb2RlID09IG4pKQotICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgICAiUHJvZ3JhbW1lcidzIEVycm9yISAgIgotICAgICAgICAgICsgInB1dERvY3VtZW50SW5DYWNoZSBmb3VuZCByZXBhcnNlIG9mIGRvYzogIgotICAgICAgICAgICsgc291cmNlLmdldFN5c3RlbUlkKCkpOwotICAgICAgcmV0dXJuOwotICAgIH0KLSAgICBpZiAobnVsbCAhPSBzb3VyY2UuZ2V0U3lzdGVtSWQoKSkKLSAgICB7Ci0gICAgICBtX3NvdXJjZVRyZWUuYWRkRWxlbWVudChuZXcgU291cmNlVHJlZShuLCBzb3VyY2UuZ2V0U3lzdGVtSWQoKSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIFNvdXJjZSBvYmplY3QsIGZpbmQgdGhlIG5vZGUgYXNzb2NpYXRlZCB3aXRoIGl0LgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBTb3VyY2Ugb2JqZWN0IHRvIGFjdCBhcyB0aGUga2V5LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBTb3VyY2UsIG9yIG51bGwgaWYgbm90IGZvdW5kLgotICAgKi8KLSAgcHVibGljIGludCBnZXROb2RlKFNvdXJjZSBzb3VyY2UpCi0gIHsKLQotLy8gICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIERPTVNvdXJjZSkKLS8vICAgICAgcmV0dXJuICgoRE9NU291cmNlKSBzb3VyY2UpLmdldE5vZGUoKTsKLQotICAgIC8vIFRPRE86IE5vdCBzdXJlIGlmIHRoZSBCYXNlSUQgaXMgcmVhbGx5IHRoZSBzYW1lIHRoaW5nIGFzIHRoZSBJRC4KLSAgICBTdHJpbmcgdXJsID0gc291cmNlLmdldFN5c3RlbUlkKCk7Ci0KLSAgICBpZiAobnVsbCA9PSB1cmwpCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0KLSAgICBpbnQgbiA9IG1fc291cmNlVHJlZS5zaXplKCk7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5vZGU6ICIrbik7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgU291cmNlVHJlZSBzVHJlZSA9IChTb3VyY2VUcmVlKSBtX3NvdXJjZVRyZWUuZWxlbWVudEF0KGkpOwotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldE5vZGUgLSAgICAgICAgIHVybDogIit1cmwpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXROb2RlIC0gc1RyZWUubV91cmw6ICIrc1RyZWUubV91cmwpOwotICAgICAgaWYgKHVybC5lcXVhbHMoc1RyZWUubV91cmwpKQotICAgICAgICByZXR1cm4gc1RyZWUubV9yb290OwotICAgIH0KLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0Tm9kZSAtIHJldHVybmluZzogIitub2RlKTsKLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzb3VyY2UgdHJlZSBmcm9tIHRoZSBhIGJhc2UgVVJMIGFuZCBhIFVSTCBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBiYXNlIFRoZSBiYXNlIFVSSSB0byB1c2UgaWYgdGhlIHVybFN0cmluZyBpcyByZWxhdGl2ZS4KLSAgICogQHBhcmFtIHVybFN0cmluZyBBbiBhYnNvbHV0ZSBvciByZWxhdGl2ZSBVUkwgc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2YgdGhlIGNhbGxlciwgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gc2hvdWxkIGJlIGEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBub2RlIGlkZW50aWZpZWQgYnkgdGhlIAotICAgKiBiYXNlIGFuZCB1cmxTdHJpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gSWYgdGhlIFVSTCBjYW4gbm90IHJlc29sdmUgdG8gYSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRTb3VyY2VUcmVlKAotICAgICAgICAgIFN0cmluZyBiYXNlLCBTdHJpbmcgdXJsU3RyaW5nLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsIFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImdldFNvdXJjZVRyZWUiKTsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBTb3VyY2Ugc291cmNlID0gdGhpcy5yZXNvbHZlVVJJKGJhc2UsIHVybFN0cmluZywgbG9jYXRvcik7Ci0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U291cmNlVHJlZSAtIGJhc2U6ICIrYmFzZSsiLCB1cmxTdHJpbmc6ICIrdXJsU3RyaW5nKyIsIHNvdXJjZTogIitzb3VyY2UuZ2V0U3lzdGVtSWQoKSk7Ci0gICAgICByZXR1cm4gZ2V0U291cmNlVHJlZShzb3VyY2UsIGxvY2F0b3IsIHhjdHh0KTsKLSAgICB9Ci0gICAgY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oaW9lLmdldE1lc3NhZ2UoKSwgbG9jYXRvciwgaW9lKTsKLSAgICB9Ci0KLSAgICAvKiBjYXRjaCAoVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgIHsKLSAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24odGUuZ2V0TWVzc2FnZSgpLCBsb2NhdG9yLCB0ZSk7Ci0gICAgIH0qLwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc291cmNlIHRyZWUgZnJvbSB0aGUgaW5wdXQgc291cmNlLgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIFRoZSBTb3VyY2Ugb2JqZWN0IHRoYXQgc2hvdWxkIGlkZW50aWZ5IHRoZSBkZXNpcmVkIG5vZGUuCi0gICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdGlvbiBvZiB0aGUgY2FsbGVyLCBmb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBub2RlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBTb3VyY2UgYXJndW1lbnQgY2FuJ3QgYmUgcmVzb2x2ZWQgdG8gCi0gICAqICAgICAgICAgYSBub2RlLgotICAgKi8KLSAgcHVibGljIGludCBnZXRTb3VyY2VUcmVlKFNvdXJjZSBzb3VyY2UsIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwgWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgbiA9IGdldE5vZGUoc291cmNlKTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSBuKQotICAgICAgcmV0dXJuIG47Ci0KLSAgICBuID0gcGFyc2VUb05vZGUoc291cmNlLCBsb2NhdG9yLCB4Y3R4dCk7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gbikKLSAgICAgIHB1dERvY3VtZW50SW5DYWNoZShuLCBzb3VyY2UpOwotCi0gICAgcmV0dXJuIG47Ci0gIH0KLQotICAvKioKLSAgICogVHJ5IHRvIGNyZWF0ZSBhIERPTSBzb3VyY2UgdHJlZSBmcm9tIHRoZSBpbnB1dCBzb3VyY2UuCi0gICAqCi0gICAqIEBwYXJhbSBzb3VyY2UgVGhlIFNvdXJjZSBvYmplY3QgdGhhdCBpZGVudGlmaWVzIHRoZSBzb3VyY2Ugbm9kZS4KLSAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0aW9uIG9mIHRoZSBjYWxsZXIsIGZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBub2RlIGlkZW50aWZpZWQgYnkgdGhlIHNvdXJjZSBhcmd1bWVudC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgc291cmNlIGFyZ3VtZW50IGNhbiBub3QgYmUgcmVzb2x2ZWQgCi0gICAqICAgICAgICAgdG8gYSBzb3VyY2Ugbm9kZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgcGFyc2VUb05vZGUoU291cmNlIHNvdXJjZSwgU291cmNlTG9jYXRvciBsb2NhdG9yLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHRyeQotICAgIHsgICAgICAKLSAgICAgIE9iamVjdCB4b3duZXIgPSB4Y3R4dC5nZXRPd25lck9iamVjdCgpOwotICAgICAgRFRNIGR0bTsKLSAgICAgIGlmKG51bGwgIT0geG93bmVyICYmIHhvd25lciBpbnN0YW5jZW9mIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1XU0ZpbHRlcikKLSAgICAgIHsKLSAgICAgICAgZHRtID0geGN0eHQuZ2V0RFRNKHNvdXJjZSwgZmFsc2UsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAob3JnLmFwYWNoZS54bWwuZHRtLkRUTVdTRmlsdGVyKXhvd25lciwgZmFsc2UsIHRydWUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBkdG0gPSB4Y3R4dC5nZXREVE0oc291cmNlLCBmYWxzZSwgbnVsbCwgZmFsc2UsIHRydWUpOwotICAgICAgfQotICAgICAgcmV0dXJuIGR0bS5nZXREb2N1bWVudCgpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKLSAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgbG9jYXRvciwgZSk7Ci0gICAgfQotCi0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgU0FYMiBwYXJzZXIgdG8gdXNlIHdpdGggdGhlIElucHV0U291cmNlCi0gICAqIG9idGFpbmVkIGZyb20gdGhpcyBVUkkuCi0gICAqIEl0IG1heSByZXR1cm4gbnVsbCBpZiBhbnkgU0FYMi1jb25mb3JtYW50IFhNTCBwYXJzZXIgY2FuIGJlIHVzZWQsCi0gICAqIG9yIGlmIGdldElucHV0U291cmNlKCkgd2lsbCBhbHNvIHJldHVybiBudWxsLiBUaGUgcGFyc2VyIG11c3QKLSAgICogYmUgZnJlZSBmb3IgdXNlIChpLmUuCi0gICAqIG5vdCBjdXJyZW50bHkgaW4gdXNlIGZvciBhbm90aGVyIHBhcnNlKCkuCi0gICAqCi0gICAqIEBwYXJhbSBpbnB1dFNvdXJjZSBUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSB0aGUgVVJJUmVzb2x2ZXIuCi0gICAqIEByZXR1cm5zIGEgU0FYMiBYTUxSZWFkZXIgdG8gdXNlIHRvIHJlc29sdmUgdGhlIGlucHV0U291cmNlIGFyZ3VtZW50LgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2YgdGhlIG9yaWdpbmFsIGNhbGxlciwgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgWE1MUmVhZGVyIHJlZmVyZW5jZSByZWFkeSB0byBwYXJzZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgcmVhZGVyIGNhbiBub3QgYmUgY3JlYXRlZC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE1MUmVhZGVyIGdldFhNTFJlYWRlcihTb3VyY2UgaW5wdXRTb3VyY2UsIFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgWE1MUmVhZGVyIHJlYWRlciA9IChpbnB1dFNvdXJjZSBpbnN0YW5jZW9mIFNBWFNvdXJjZSkKLSAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoU0FYU291cmNlKSBpbnB1dFNvdXJjZSkuZ2V0WE1MUmVhZGVyKCkgOiBudWxsOwotICAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgYm9vbGVhbiBpc1VzZXJSZWFkZXIgPSAocmVhZGVyICE9IG51bGwpOwotCi0gICAgICBpZiAobnVsbCA9PSByZWFkZXIpCi0gICAgICB7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeSBmYWN0b3J5PQotICAgICAgICAgICAgICBqYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICAgICAgZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSggdHJ1ZSApOwotICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciBqYXhwUGFyc2VyPQotICAgICAgICAgICAgICBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgICAgIHJlYWRlcj1qYXhwUGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgICAgIAotICAgICAgICB9IGNhdGNoKCBqYXZheC54bWwucGFyc2Vycy5QYXJzZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uIGV4ICkgewotICAgICAgICAgIHRocm93IG5ldyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24oIGV4ICk7Ci0gICAgICAgIH0gY2F0Y2goIGphdmF4LnhtbC5wYXJzZXJzLkZhY3RvcnlDb25maWd1cmF0aW9uRXJyb3IgZXgxICkgewotICAgICAgICAgICAgdGhyb3cgbmV3IG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiggZXgxLnRvU3RyaW5nKCkgKTsKLSAgICAgICAgfSBjYXRjaCggTm9TdWNoTWV0aG9kRXJyb3IgZXgyICkgewotICAgICAgICB9Ci0gICAgICAgIGNhdGNoIChBYnN0cmFjdE1ldGhvZEVycm9yIGFtZSl7fQotICAgICAgICBpZihudWxsID09IHJlYWRlcikKLSAgICAgICAgICByZWFkZXIgPSBYTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgICAgfQotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgcmVhZGVyLnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2UtcHJlZml4ZXMiLAotICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgICAgLy8gQ29tbWVudGVkIG91dCBhcyBwZXIgZGlzY3Vzc2lvbiB3aXRoIFRob21hczIuTWFlc2luZ0BiZ3MtYWcuZGUgCi0gICAgICAgIC8vIGFib3V0IGJ1ZyAyMTI0LgotLy8gICAgICAgIGlmKCFpc1VzZXJSZWFkZXIpCi0vLyAgICAgICAgICByZWFkZXIuc2V0RmVhdHVyZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL3ZhbGlkYXRpb24vZHluYW1pYyIsCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gV2hhdCBjYW4gd2UgZG8/Ci0gICAgICAgIC8vIFRPRE86IFVzZXIgZGlhZ25vc3RpY3MuCi0gICAgICB9Ci0KLSAgICAgIHJldHVybiByZWFkZXI7Ci0gICAgfQotICAgIGNhdGNoIChvcmcueG1sLnNheC5TQVhFeGNlcHRpb24gc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSwgbG9jYXRvciwgc2UpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvVmFyaWFibGVTdGFjay5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvVmFyaWFibGVTdGFjay5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxMjk3ZDliLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1ZhcmlhYmxlU3RhY2suamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ3NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogRGVmaW5lcyBhIGNsYXNzIHRvIGtlZXAgdHJhY2sgb2YgYSBzdGFjayBmb3IKLSAqIHRlbXBsYXRlIGFyZ3VtZW50cyBhbmQgdmFyaWFibGVzLgotICoKLSAqIDxwPlRoaXMgaGFzIGJlZW4gY2hhbmdlZCBmcm9tIHRoZSBwcmV2aW91cyBpbmNhcm5hdGlvbnMgb2YgdGhpcwotICogY2xhc3MgdG8gYmUgZmFpcmx5IGxvdyBsZXZlbC48L3A+Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBWYXJpYWJsZVN0YWNrIGltcGxlbWVudHMgQ2xvbmVhYmxlCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIGZvciBhIHZhcmlhYmxlIHN0YWNrLgotICAgKi8KLSAgcHVibGljIFZhcmlhYmxlU3RhY2soKQotICB7Ci0gICAgcmVzZXQoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhpcyB2YXJpYWJsZSBzdGFjay4KLSAgICoKLSAgICogQHJldHVybiAgYSBjbG9uZSBvZiB0aGlzIHZhcmlhYmxlIHN0YWNrLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBWYXJpYWJsZVN0YWNrIHZzID0gKFZhcmlhYmxlU3RhY2spIHN1cGVyLmNsb25lKCk7Ci0KLSAgICAvLyBJICp0aGluayogSSBjYW4gZ2V0IGF3YXkgd2l0aCBhIHNoYWxsb3cgY2xvbmUgaGVyZT8KLSAgICB2cy5fc2YgPSAoWE9iamVjdFtdKSBfc2YuY2xvbmUoKTsKLSAgICB2cy5fbGlua3MgPSAoaW50W10pIF9saW5rcy5jbG9uZSgpOwotCi0gICAgcmV0dXJuIHZzOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBzdGFjayBmcmFtZSB3aGVyZSBhbGwgdmFyaWFibGVzIGFuZCBwYXJhbXMgd2lsbCBiZSBrZXB0LgotICAgKiBAc2VyaWFsCi0gICAqLwotICBYT2JqZWN0W10gX3NmID0gbmV3IFhPYmplY3RbWFBhdGhDb250ZXh0LlJFQ1VSU0lPTkxJTUlUICogMl07Ci0KLSAgLyoqCi0gICAqIFRoZSB0b3Agb2YgdGhlIHN0YWNrIGZyYW1lICg8Y29kZT5fc2Y8L2NvZGU+KS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgaW50IF90b3A7Ci0KLSAgLyoqCi0gICAqIFRoZSBib3R0b20gaW5kZXggb2YgdGhlIGN1cnJlbnQgZnJhbWUgKHJlbGF0aXZlIHRvIDxjb2RlPl9zZjwvY29kZT4pLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcml2YXRlIGludCBfY2ZiOwotCi0gIC8qKgotICAgKiBUaGUgc3RhY2sgb2YgZnJhbWUgcG9zaXRpb25zLiAgSSBjYWxsICdlbSBsaW5rcyBiZWNhdXNlIG9mIGRpc3RhbnQKLSAgICogPGEgaHJlZj0iaHR0cDovL21hdGgubWlsbGlraW4uZWR1L21wcm9nZXJzL0NvdXJzZXMvY3VycmVudENvdXJzZXMvQ1M0ODEtQ29tcHV0ZXJBcmNoaXRlY3R1cmUvY3M0ODEuTW90b3JvbGE2ODAwMC5odG1sIj4KLSAgICogTW90b3JvbGEgNjgwMDAgYXNzZW1ibGVyPC9hPiBtZW1vcmllcy4gIDotKQotICAgKiBAc2VyaWFsCi0gICAqLwotICBpbnRbXSBfbGlua3MgPSBuZXcgaW50W1hQYXRoQ29udGV4dC5SRUNVUlNJT05MSU1JVF07Ci0KLSAgLyoqCi0gICAqIFRoZSB0b3Agb2YgdGhlIGxpbmtzIHN0YWNrLgotICAgKi8KLSAgaW50IF9saW5rc1RvcDsKLQotICAvKioKLSAgICogR2V0IHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleCwgcmVnYXJkbGVzcyBvZiBzdGFja2ZyYW1lLgotICAgKgotICAgKiBAcGFyYW0gaSBpbmRleCBmcm9tIHplcm8uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGl0ZW0gYXQgdGhlIGdpdmVuIGluZGV4LgotICAgKi8KLSAgcHVibGljIGZpbmFsIFhPYmplY3QgZWxlbWVudEF0KGZpbmFsIGludCBpKQotICB7Ci0gICAgcmV0dXJuIF9zZltpXTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgc2l6ZSBvZiB0aGUgc3RhY2suCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHRvdGFsIHNpemUgb2YgdGhlIGV4ZWN1dGlvbiBzdGFjay4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgc2l6ZSgpCi0gIHsKLSAgICByZXR1cm4gX3RvcDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgc3RhY2sgdG8gYSBzdGFydCBwb3NpdGlvbi4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdG90YWwgc2l6ZSBvZiB0aGUgZXhlY3V0aW9uIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcmVzZXQoKQotICB7Ci0KLSAgICBfdG9wID0gMDsKLSAgICBfbGlua3NUb3AgPSAwOwotCi0gICAgLy8gQWRkaW5nIG9uZSBoZXJlIHRvIHRoZSBzdGFjayBvZiBmcmFtZSBwb3NpdGlvbnMgd2lsbCBhbGxvdyB1cyBhbHdheXMgCi0gICAgLy8gdG8gbG9vayBvbmUgdW5kZXIgd2l0aG91dCBoYXZpbmcgdG8gY2hlY2sgaWYgd2UncmUgYXQgemVyby4KLSAgICAvLyAoQXMgbG9uZyBhcyB0aGUgY2FsbGVyIGRvZXNuJ3Qgc2NyZXcgdXAgbGluay91bmxpbmsuKQotICAgIF9saW5rc1tfbGlua3NUb3ArK10gPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICogQHBhcmFtIHNmIFRoZSBuZXcgc3RhY2sgZnJhbWUgcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRTdGFja0ZyYW1lKGludCBzZikKLSAgewotICAgIF9jZmIgPSBzZjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvc2l0aW9uIGZyb20gd2hlcmUgdGhlIHNlYXJjaCBzaG91bGQgc3RhcnQsCi0gICAqIHdoaWNoIGlzIGVpdGhlciB0aGUgc2VhcmNoU3RhcnQgcHJvcGVydHksIG9yIHRoZSB0b3AKLSAgICogb2YgdGhlIHN0YWNrIGlmIHRoYXQgdmFsdWUgaXMgLTEuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUgcG9zaXRpb24uCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldFN0YWNrRnJhbWUoKQotICB7Ci0gICAgcmV0dXJuIF9jZmI7Ci0gIH0KLQotICAvKioKLSAgICogQWxsb2NhdGVzIG1lbW9yeSAoY2FsbGVkIGEgc3RhY2tmcmFtZSkgb24gdGhlIHN0YWNrOyB1c2VkIHRvIHN0b3JlCi0gICAqIGxvY2FsIHZhcmlhYmxlcyBhbmQgcGFyYW1ldGVyIGFyZ3VtZW50cy4KLSAgICoKLSAgICogPHA+SSB1c2UgdGhlIGxpbmsvdW5saW5rIGNvbmNlcHQgYmVjYXVzZSBvZiBkaXN0YW50Ci0gICAqIDxhIGhyZWY9Imh0dHA6Ly9tYXRoLm1pbGxpa2luLmVkdS9tcHJvZ2Vycy9Db3Vyc2VzL2N1cnJlbnRDb3Vyc2VzL0NTNDgxLUNvbXB1dGVyQXJjaGl0ZWN0dXJlL2NzNDgxLk1vdG9yb2xhNjgwMDAuaHRtbCI+Ci0gICAqIE1vdG9yb2xhIDY4MDAwIGFzc2VtYmxlcjwvYT4gbWVtb3JpZXMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gc2l6ZSBUaGUgc2l6ZSBvZiB0aGUgc3RhY2sgZnJhbWUgYWxsb2NhdGlvbi4gIFRoaXMgYW1tb3VudCBzaG91bGQKLSAgICogbm9ybWFsbHkgYmUgdGhlIG1heGltdW0gbnVtYmVyIG9mIHZhcmlhYmxlcyB0aGF0IHlvdSBjYW4gaGF2ZSBhbGxvY2F0ZWQKLSAgICogYXQgb25lIHRpbWUgaW4gdGhlIG5ldyBzdGFjayBmcmFtZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYm90dG9tIG9mIHRoZSBzdGFjayBmcmFtZSwgZnJvbSB3aGVyZSBsb2NhbCB2YXJpYWJsZSBhZGRyZXNzaW5nCi0gICAqIHNob3VsZCBzdGFydCBmcm9tLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBsaW5rKGZpbmFsIGludCBzaXplKQotICB7Ci0KLSAgICBfY2ZiID0gX3RvcDsKLSAgICBfdG9wICs9IHNpemU7Ci0KLSAgICBpZiAoX3RvcCA+PSBfc2YubGVuZ3RoKQotICAgIHsKLSAgICAgIFhPYmplY3QgbmV3c2ZbXSA9IG5ldyBYT2JqZWN0W19zZi5sZW5ndGggKyAoMTAyNCAqIDQpICsgc2l6ZV07Ci0KLSAgICAgIFN5c3RlbS5hcnJheWNvcHkoX3NmLCAwLCBuZXdzZiwgMCwgX3NmLmxlbmd0aCk7Ci0KLSAgICAgIF9zZiA9IG5ld3NmOwotICAgIH0KLQotICAgIGlmIChfbGlua3NUb3AgKyAxID49IF9saW5rcy5sZW5ndGgpCi0gICAgewotICAgICAgaW50IG5ld2xpbmtzW10gPSBuZXcgaW50W19saW5rcy5sZW5ndGggKyAoMTAyNCAqIDIpXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShfbGlua3MsIDAsIG5ld2xpbmtzLCAwLCBfbGlua3MubGVuZ3RoKTsKLQotICAgICAgX2xpbmtzID0gbmV3bGlua3M7Ci0gICAgfQotCi0gICAgX2xpbmtzW19saW5rc1RvcCsrXSA9IF9jZmI7Ci0KLSAgICByZXR1cm4gX2NmYjsKLSAgfQotCi0gIC8qKgotICAgKiBGcmVlIHVwIHRoZSBzdGFjayBmcmFtZSB0aGF0IHdhcyBsYXN0IGFsbG9jYXRlZCB3aXRoCi0gICAqIHtAbGluayBsaW5rKGludCBzaXplKX0uCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCB1bmxpbmsoKQotICB7Ci0gICAgX3RvcCA9IF9saW5rc1stLV9saW5rc1RvcF07Ci0gICAgX2NmYiA9IF9saW5rc1tfbGlua3NUb3AgLSAxXTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgYSBsb2NhbCB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgaW4gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBMb2NhbCB2YXJpYWJsZSBpbmRleCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBzdGFjawotICAgKiBmcmFtZSBib3R0b20uCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgVGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0aGF0IGlzIGJlaW5nIHNldC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldExvY2FsVmFyaWFibGUoaW50IGluZGV4LCBYT2JqZWN0IHZhbCkKLSAgewotICAgIF9zZltpbmRleCArIF9jZmJdID0gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhIGxvY2FsIHZhcmlhYmxlIG9yIHBhcmFtZXRlciBpbiB0aGUgc3BlY2lmaWVkIHN0YWNrIGZyYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgc3RhY2sKLSAgICogZnJhbWUgYm90dG9tLgotICAgKiBORUVEU0RPQyBAcGFyYW0gc3RhY2tGcmFtZQotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdGhhdCBpcyBiZWluZyBzZXQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRMb2NhbFZhcmlhYmxlKGludCBpbmRleCwgWE9iamVjdCB2YWwsIGludCBzdGFja0ZyYW1lKQotICB7Ci0gICAgX3NmW2luZGV4ICsgc3RhY2tGcmFtZV0gPSB2YWw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgbG9jYWwgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGluIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIGNvbnRleHQsIHdoaWNoIG11c3QgYmUgcGFzc2VkIGluIG9yZGVyIHRvCi0gICAqIGxhenkgZXZhbHVhdGUgdmFyaWFibGVzLgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgc3RhY2sKLSAgICogZnJhbWUgYm90dG9tLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBYT2JqZWN0IGdldExvY2FsVmFyaWFibGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgaW5kZXgpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGluZGV4ICs9IF9jZmI7Ci0KLSAgICBYT2JqZWN0IHZhbCA9IF9zZltpbmRleF07Ci0gICAgCi0gICAgaWYobnVsbCA9PSB2YWwpCi0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24oIlZhcmlhYmxlIGFjY2Vzc2VkIGJlZm9yZSBpdCBpcyBib3VuZCEiLCB4Y3R4dC5nZXRTQVhMb2NhdG9yKCkpOwotCi0gICAgLy8gTGF6eSBleGVjdXRpb24gb2YgdmFyaWFibGVzLgotICAgIGlmICh2YWwuZ2V0VHlwZSgpID09IFhPYmplY3QuQ0xBU1NfVU5SRVNPTFZFRFZBUklBQkxFKQotICAgICAgcmV0dXJuIChfc2ZbaW5kZXhdID0gdmFsLmV4ZWN1dGUoeGN0eHQpKTsKLQotICAgIHJldHVybiB2YWw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgbG9jYWwgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGluIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGdpdmVuCi0gICAqIGZyYW1lIGJvdHRvbS4KLSAgICogTkVFRFNET0MgQHBhcmFtIGZyYW1lCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIFhPYmplY3QgZ2V0TG9jYWxWYXJpYWJsZShpbnQgaW5kZXgsIGludCBmcmFtZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW5kZXggKz0gZnJhbWU7Ci0KLSAgICBYT2JqZWN0IHZhbCA9IF9zZltpbmRleF07Ci0KLSAgICByZXR1cm4gdmFsOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgYSBsb2NhbCB2YXJpYWJsZSBoYXMgYmVlbiBzZXQgb3Igbm90LgotICAgKgotICAgKiBAcGFyYW0gaW5kZXggTG9jYWwgdmFyaWFibGUgaW5kZXggcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgc3RhY2sKLSAgICogZnJhbWUgYm90dG9tLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIGF0IHRoZSBpbmRleCBpcyBub3QgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNMb2NhbFNldChpbnQgaW5kZXgpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChfc2ZbaW5kZXggKyBfY2ZiXSAhPSBudWxsKTsKLSAgfQotCi0gIC8qKiBORUVEU0RPQyBGaWVsZCBtX251bGxzICAgICAgICAgICovCi0gIHByaXZhdGUgc3RhdGljIFhPYmplY3RbXSBtX251bGxzID0gbmV3IFhPYmplY3RbMTAyNF07Ci0KLSAgLyoqCi0gICAqIFVzZSB0aGlzIHRvIGNsZWFyIHRoZSB2YXJpYWJsZXMgaW4gYSBzZWN0aW9uIG9mIHRoZSBzdGFjay4gIFRoaXMgaXMKLSAgICogdXNlZCB0byBjbGVhciB0aGUgcGFyYW1ldGVyIHNlY3Rpb24gb2YgdGhlIHN0YWNrLCBzbyB0aGF0IGRlZmF1bHQgcGFyYW0KLSAgICogdmFsdWVzIGNhbiB0ZWxsIGlmIHRoZXkndmUgYWxyZWFkeSBiZWVuIHNldC4gIEl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQKLSAgICogdGhpcyBmdW5jdGlvbiBoYXMgYSAxSyBsaW1pdGF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uLCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBsb2NhbCBzdGFjayBmcmFtZS4KLSAgICogQHBhcmFtIGxlbiBUaGUgbnVtYmVyIG9mIHNsb3RzIHRvIGJlIGNsZWFyZWQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBjbGVhckxvY2FsU2xvdHMoaW50IHN0YXJ0LCBpbnQgbGVuKQotICB7Ci0KLSAgICBzdGFydCArPSBfY2ZiOwotCi0gICAgU3lzdGVtLmFycmF5Y29weShtX251bGxzLCAwLCBfc2YsIHN0YXJ0LCBsZW4pOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhIGdsb2JhbCB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgaW4gdGhlIGdsb2JhbCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGluZGV4IExvY2FsIHZhcmlhYmxlIGluZGV4IHJlbGF0aXZlIHRvIHRoZSBnbG9iYWwgc3RhY2sgZnJhbWUKLSAgICogYm90dG9tLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdGhhdCBpcyBiZWluZyBzZXQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRHbG9iYWxWYXJpYWJsZShmaW5hbCBpbnQgaW5kZXgsIGZpbmFsIFhPYmplY3QgdmFsKQotICB7Ci0gICAgX3NmW2luZGV4XSA9IHZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBnbG9iYWwgdmFyaWFibGUgb3IgcGFyYW1ldGVyIGZyb20gdGhlIGdsb2JhbCBzdGFjayBmcmFtZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBjb250ZXh0LCB3aGljaCBtdXN0IGJlIHBhc3NlZCBpbiBvcmRlciB0bwotICAgKiBsYXp5IGV2YWx1YXRlIHZhcmlhYmxlcy4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IEdsb2JhbCB2YXJpYWJsZSBpbmRleCByZWxhdGl2ZSB0byB0aGUgZ2xvYmFsIHN0YWNrCi0gICAqIGZyYW1lIGJvdHRvbS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgWE9iamVjdCBnZXRHbG9iYWxWYXJpYWJsZShYUGF0aENvbnRleHQgeGN0eHQsIGZpbmFsIGludCBpbmRleCkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWE9iamVjdCB2YWwgPSBfc2ZbaW5kZXhdOwotCi0gICAgLy8gTGF6eSBleGVjdXRpb24gb2YgdmFyaWFibGVzLgotICAgIGlmICh2YWwuZ2V0VHlwZSgpID09IFhPYmplY3QuQ0xBU1NfVU5SRVNPTFZFRFZBUklBQkxFKQotICAgICAgcmV0dXJuIChfc2ZbaW5kZXhdID0gdmFsLmV4ZWN1dGUoeGN0eHQpKTsKLQotICAgIHJldHVybiB2YWw7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgdmFyaWFibGUgYmFzZWQgb24gaXQncyBxdWFsaWZpZWQgbmFtZS4KLSAgICogVGhpcyBpcyBmb3IgZXh0ZXJuYWwgdXNlIG9ubHkuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggY29udGV4dCwgd2hpY2ggbXVzdCBiZSBwYXNzZWQgaW4gb3JkZXIgdG8KLSAgICogbGF6eSBldmFsdWF0ZSB2YXJpYWJsZXMuCi0gICAqIAotICAgKiBAcGFyYW0gcW5hbWUgVGhlIHF1YWxpZmllZCBuYW1lIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXZhbHVhdGVkIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZmluYWwgWE9iamVjdCBnZXRWYXJpYWJsZU9yUGFyYW0oCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZSBxbmFtZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyIHByZWZpeFJlc29sdmVyID0KLSAgICAgIHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgIC8vIEdldCB0aGUgY3VycmVudCBFbGVtVGVtcGxhdGVFbGVtZW50LCB3aGljaCBtdXN0IGJlIHB1c2hlZCBpbiBhcyB0aGUgCi0gICAgLy8gcHJlZml4IHJlc29sdmVyLCBhbmQgdGhlbiB3YWxrIGJhY2t3YXJkcyBpbiBkb2N1bWVudCBvcmRlciwgc2VhcmNoaW5nIAotICAgIC8vIGZvciBhbiB4c2w6cGFyYW0gZWxlbWVudCBvciB4c2w6dmFyaWFibGUgZWxlbWVudCB0aGF0IG1hdGNoZXMgb3VyIAotICAgIC8vIHFuYW1lLiAgSWYgd2UgcmVhY2ggdGhlIHRvcCBsZXZlbCwgdXNlIHRoZSBTdHlsZXNoZWV0Um9vdCdzIGNvbXBvc2VkCi0gICAgLy8gbGlzdCBvZiB0b3AgbGV2ZWwgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzLgotCi0gICAgaWYgKHByZWZpeFJlc29sdmVyIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudCkKLSAgICB7Ci0gICAgICAKLSAgICAgIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1WYXJpYWJsZSB2dmFyOwotCi0gICAgICBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50IHByZXYgPQotICAgICAgICAob3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudCkgcHJlZml4UmVzb2x2ZXI7Ci0KLSAgICAgIGlmICghKHByZXYgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0KSkKLSAgICAgIHsKLSAgICAgICAgd2hpbGUgKCAhKHByZXYuZ2V0UGFyZW50Tm9kZSgpIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuU3R5bGVzaGVldCkgKQotICAgICAgICB7Ci0gICAgICAgICAgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudCBzYXZlZHByZXYgPSBwcmV2OwotCi0gICAgICAgICAgd2hpbGUgKG51bGwgIT0gKHByZXYgPSBwcmV2LmdldFByZXZpb3VzU2libGluZ0VsZW0oKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKHByZXYgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHZ2YXIgPSAob3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlKSBwcmV2OwotCi0gICAgICAgICAgICAgIGlmICh2dmFyLmdldE5hbWUoKS5lcXVhbHMocW5hbWUpKQotICAgICAgICAgICAgICAgIHJldHVybiBnZXRMb2NhbFZhcmlhYmxlKHhjdHh0LCB2dmFyLmdldEluZGV4KCkpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBwcmV2ID0gc2F2ZWRwcmV2LmdldFBhcmVudEVsZW0oKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICB2dmFyID0gcHJldi5nZXRTdHlsZXNoZWV0Um9vdCgpLmdldFZhcmlhYmxlT3JQYXJhbUNvbXBvc2VkKHFuYW1lKTsKLSAgICAgIGlmIChudWxsICE9IHZ2YXIpCi0gICAgICAgIHJldHVybiBnZXRHbG9iYWxWYXJpYWJsZSh4Y3R4dCwgdnZhci5nZXRJbmRleCgpKTsKLSAgICB9Ci0KLSAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9WQVJfTk9UX1JFU09MVkFCTEUsIG5ldyBPYmplY3RbXXtxbmFtZS50b1N0cmluZygpfSkpOyAvLyJWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogIiArIHFuYW1lKTsKLSAgfQotfSAgLy8gZW5kIFZhcmlhYmxlU3RhY2sKLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvV2hpdGVzcGFjZVN0cmlwcGluZ0VsZW1lbnRNYXRjaGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9XaGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudE1hdGNoZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2ViNTZlMS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9XaGl0ZXNwYWNlU3RyaXBwaW5nRWxlbWVudE1hdGNoZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMzICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiBBIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBjYW4gdGVsbCBpZiBhIGdpdmVuIGVsZW1lbnQgc2hvdWxkIAotICogc3RyaXAgd2hpdGVzcGFjZSBub2RlcyBmcm9tIGl0J3MgY2hpbGRyZW4uCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgV2hpdGVzcGFjZVN0cmlwcGluZ0VsZW1lbnRNYXRjaGVyCi17Ci0gIC8qKgotICAgKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBvciBub3QgYW4gZWxlbWVudCBzaG91bGQgc3RyaXAgd2hpdGVzcGFjZS4KLSAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I3N0cmlwIj5zdHJpcCBpbiBYU0xUIFNwZWNpZmljYXRpb248L2E+Ci0gICAqCi0gICAqIEBwYXJhbSBzdXBwb3J0IFRoZSBYUGF0aCBydW50aW1lIHN0YXRlLgotICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBFbGVtZW50IHRvIGNoZWNrCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgd2hpdGVzcGFjZSBzaG91bGQgYmUgc3RyaXBwZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHNob3VsZFN0cmlwV2hpdGVTcGFjZSgKLSAgICAgICAgICBYUGF0aENvbnRleHQgc3VwcG9ydCwgRWxlbWVudCB0YXJnZXRFbGVtZW50KSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0gIAotICAvKioKLSAgICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgb3Igbm90IHdoaXRlc3BhY2UgY2FuIGJlIHN0cmlwcGVkLgotICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc3RyaXAiPnN0cmlwIGluIFhTTFQgU3BlY2lmaWNhdGlvbjwvYT4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB3aGl0ZXNwYWNlIGNhbiBiZSBzdHJpcHBlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblN0cmlwV2hpdGVTcGFjZSgpOwotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1hQYXRoLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYTE3OWYxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1hQYXRoLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2MDggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aDsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50OwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKLWltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uOwotCi0vLyBpbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuRnVuY0xvYWRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuWFBhdGhQYXJzZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5PcE1hcDsgIC8vIHRlbXAKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLk9wQ29kZXM7ICAvLyB0ZW1wCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Qc3VlZG9OYW1lczsgIC8vIHRlbXAKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkZ1bmN0aW9uVGFibGU7ICAvLyB0ZW1wCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLio7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU0FYU291cmNlTG9jYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhlIFhQYXRoIGNsYXNzIHdyYXBzIGFuIGV4cHJlc3Npb24gb2JqZWN0IGFuZCBwcm92aWRlcyBnZW5lcmFsIHNlcnZpY2VzIAotICogZm9yIGV4ZWN1dGlvbiBvZiB0aGF0IGV4cHJlc3Npb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aCBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZQotewotCi0gIC8qKiBUaGUgdG9wIG9mIHRoZSBleHByZXNzaW9uIHRyZWUuIAotICAgKiAgQHNlcmlhbCAqLwotICBwcml2YXRlIEV4cHJlc3Npb24gbV9tYWluRXhwOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHJhdyBFeHByZXNzaW9uIG9iamVjdCB0aGF0IHRoaXMgY2xhc3Mgd3JhcHMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJhdyBFeHByZXNzaW9uIG9iamVjdCwgd2hpY2ggc2hvdWxkIG5vdCBub3JtYWxseSBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpCi0gIHsKLSAgICByZXR1cm4gbV9tYWluRXhwOwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZSAKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QgCi0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0IAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZSAKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uIAotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkIAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBtX21haW5FeHAuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcmF3IGV4cHJlc3Npb24gb2JqZWN0IGZvciB0aGlzIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGV4cCB0aGUgcmF3IEV4cHJlc3Npb24gb2JqZWN0LCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFeHByZXNzaW9uKEV4cHJlc3Npb24gZXhwKQotICB7Ci0gICAgbV9tYWluRXhwID0gZXhwOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgU291cmNlTG9jYXRvciBvbiB0aGUgZXhwcmVzc2lvbiBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFNvdXJjZUxvY2F0b3Igb24gdGhlIGV4cHJlc3Npb24gb2JqZWN0LCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldExvY2F0b3IoKQotICB7Ci0gICAgcmV0dXJuIG1fbWFpbkV4cC5tX3Nsb2NhdG9yOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgU291cmNlTG9jYXRvciBvbiB0aGUgZXhwcmVzc2lvbiBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsIHRoZSBTb3VyY2VMb2NhdG9yIG9uIHRoZSBleHByZXNzaW9uIG9iamVjdCwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMb2NhdG9yKFNvdXJjZUxvY2F0b3IgbCkKLSAgewotICAgIC8vIE5vdGUgcG90ZW50aWFsIGhhemFyZHMgLS0gbCBtYXkgbm90IGJlIHNlcmlhbGl6YWJsZSwgb3IgbWF5IGJlIGNoYW5nZWQKLSAgICAgIC8vIGFmdGVyIGJlaW5nIGFzc2lnbmVkIGhlcmUuCi0gICAgbV9tYWluRXhwLnNldFNvdXJjZUxvY2F0b3IobCk7Ci0gIH0KLQotICAvKiogVGhlIHBhdHRlcm4gc3RyaW5nLCBtYWlubHkga2VwdCBhcm91bmQgZm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqICBAc2VyaWFsICAqLwotICBTdHJpbmcgbV9wYXR0ZXJuU3RyaW5nOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIFhQYXRoIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIFhQYXRoIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFBhdHRlcm5TdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fcGF0dGVyblN0cmluZzsKLSAgfQotCi0gIC8qKiBSZXByZXNlbnRzIGEgc2VsZWN0IHR5cGUgZXhwcmVzc2lvbi4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VMRUNUID0gMDsKLQotICAvKiogUmVwcmVzZW50cyBhIG1hdGNoIHR5cGUgZXhwcmVzc2lvbi4gICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BVENIID0gMTsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIFhQYXRoIG9iamVjdC4gIFRoZSBvYmplY3QgbXVzdCBiZSBpbml0aWFsaXplZCBieSB0aGUKLSAgICogWFBhdGhQYXJzZXIuaW5pdFhQYXRoIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGV4cHJTdHJpbmcgVGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBsb2NhdG9yIFRoZSBsb2NhdGlvbiBvZiB0aGUgZXhwcmVzc2lvbiwgbWF5IGJlIG51bGwuCi0gICAqIEBwYXJhbSBwcmVmaXhSZXNvbHZlciBBIHByZWZpeCByZXNvbHZlciB0byB1c2UgdG8gcmVzb2x2ZSBwcmVmaXhlcyB0byAKLSAgICogICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSBVUklzLgotICAgKiBAcGFyYW0gdHlwZSBvbmUgb2Yge0BsaW5rICNTRUxFQ1R9IG9yIHtAbGluayAjTUFUQ0h9LgotICAgKiBAcGFyYW0gZXJyb3JMaXN0ZW5lciBUaGUgZXJyb3IgbGlzdGVuZXIsIG9yIG51bGwgaWYgZGVmYXVsdCBzaG91bGQgYmUgdXNlZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICovCi0gIHB1YmxpYyBYUGF0aCgKLSAgICAgICAgICBTdHJpbmcgZXhwclN0cmluZywgU291cmNlTG9jYXRvciBsb2NhdG9yLCBQcmVmaXhSZXNvbHZlciBwcmVmaXhSZXNvbHZlciwgaW50IHR5cGUsCi0gICAgICAgICAgRXJyb3JMaXN0ZW5lciBlcnJvckxpc3RlbmVyKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgeyAgICAgIAotICAgIGlmKG51bGwgPT0gZXJyb3JMaXN0ZW5lcikKLSAgICAgIGVycm9yTGlzdGVuZXIgPSBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuRGVmYXVsdEVycm9ySGFuZGxlcigpOwotICAgIAotICAgIG1fcGF0dGVyblN0cmluZyA9IGV4cHJTdHJpbmc7Ci0KLSAgICBYUGF0aFBhcnNlciBwYXJzZXIgPSBuZXcgWFBhdGhQYXJzZXIoZXJyb3JMaXN0ZW5lciwgbG9jYXRvcik7Ci0gICAgQ29tcGlsZXIgY29tcGlsZXIgPSBuZXcgQ29tcGlsZXIoZXJyb3JMaXN0ZW5lciwgbG9jYXRvcik7Ci0KLSAgICBpZiAoU0VMRUNUID09IHR5cGUpCi0gICAgICBwYXJzZXIuaW5pdFhQYXRoKGNvbXBpbGVyLCBleHByU3RyaW5nLCBwcmVmaXhSZXNvbHZlcik7Ci0gICAgZWxzZSBpZiAoTUFUQ0ggPT0gdHlwZSkKLSAgICAgIHBhcnNlci5pbml0TWF0Y2hQYXR0ZXJuKGNvbXBpbGVyLCBleHByU3RyaW5nLCBwcmVmaXhSZXNvbHZlcik7Ci0gICAgZWxzZQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOTk9UX0RFQUxfWFBBVEhfVFlQRSwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcodHlwZSl9KSk7IC8vIkNhbiBub3QgZGVhbCB3aXRoIFhQYXRoIHR5cGU6ICIgKyB0eXBlKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLSIpOwotICAgIEV4cHJlc3Npb24gZXhwciA9IGNvbXBpbGVyLmNvbXBpbGUoMCk7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImV4cHI6ICIrZXhwcik7Ci0gICAgdGhpcy5zZXRFeHByZXNzaW9uKGV4cHIpOwotCi0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gWFBhdGggb2JqZWN0LiAgVGhlIG9iamVjdCBtdXN0IGJlIGluaXRpYWxpemVkIGJ5IHRoZQotICAgKiBYUGF0aFBhcnNlci5pbml0WFBhdGggbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gZXhwclN0cmluZyBUaGUgWFBhdGggZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIGxvY2F0b3IgVGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uLCBtYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIHByZWZpeFJlc29sdmVyIEEgcHJlZml4IHJlc29sdmVyIHRvIHVzZSB0byByZXNvbHZlIHByZWZpeGVzIHRvIAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlIFVSSXMuCi0gICAqIEBwYXJhbSB0eXBlIG9uZSBvZiB7QGxpbmsgI1NFTEVDVH0gb3Ige0BsaW5rICNNQVRDSH0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBzeW50YXggb3Igb3RoZXIgZXJyb3IuCi0gICAqLwotICBwdWJsaWMgWFBhdGgoCi0gICAgICAgICAgU3RyaW5nIGV4cHJTdHJpbmcsIFNvdXJjZUxvY2F0b3IgbG9jYXRvciwgUHJlZml4UmVzb2x2ZXIgcHJlZml4UmVzb2x2ZXIsIGludCB0eXBlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgeyAgCi0gICAgdGhpcyhleHByU3RyaW5nLCBsb2NhdG9yLCBwcmVmaXhSZXNvbHZlciwgdHlwZSwgbnVsbCk7ICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBYUGF0aCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBleHByIFRoZSBFeHByZXNzaW9uIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHN5bnRheCBvciBvdGhlciBlcnJvci4KLSAgICovCi0gIHB1YmxpYyBYUGF0aChFeHByZXNzaW9uIGV4cHIpCi0gIHsgIAotICAgIHRoaXMuc2V0RXhwcmVzc2lvbihleHByKTsgICAKLSAgfQotICAKLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJleHBlcmltZW50YWwiLz4KLSAgICogR2l2ZW4gYW4gZXhwcmVzc2lvbiBhbmQgYSBjb250ZXh0LCBldmFsdWF0ZSB0aGUgWFBhdGgKLSAgICogYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKiAKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRoYXQgIi4iIGV4cHJlc3Nlcy4KLSAgICogQHBhcmFtIG5hbWVzcGFjZUNvbnRleHQgVGhlIGNvbnRleHQgaW4gd2hpY2ggbmFtZXNwYWNlcyBpbiB0aGUKLSAgICogWFBhdGggYXJlIHN1cHBvc2VkIHRvIGJlIGV4cGFuZGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIFhQYXRoIG9yIG51bGwgaWYgY2FsbGJhY2tzIGFyZSB1c2VkLgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRocm93biBpZgotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBvcmcudzNjLmRvbS5Ob2RlIGNvbnRleHROb2RlLCAKLSAgICAgICAgICBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBleGVjdXRlKAotICAgICAgICAgIHhjdHh0LCB4Y3R4dC5nZXREVE1IYW5kbGVGcm9tTm9kZShjb250ZXh0Tm9kZSksIAotICAgICAgICAgIG5hbWVzcGFjZUNvbnRleHQpOwotICB9Ci0gIAotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZXhwZXJpbWVudGFsIi8+Ci0gICAqIEdpdmVuIGFuIGV4cHJlc3Npb24gYW5kIGEgY29udGV4dCwgZXZhbHVhdGUgdGhlIFhQYXRoCi0gICAqIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICogCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0aGF0ICIuIiBleHByZXNzZXMuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IFRoZSBjb250ZXh0IGluIHdoaWNoIG5hbWVzcGFjZXMgaW4gdGhlCi0gICAqIFhQYXRoIGFyZSBzdXBwb3NlZCB0byBiZSBleHBhbmRlZC4KLSAgICogCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGRlY2lkZXMKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHROb2RlLCBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgeGN0eHQucHVzaE5hbWVzcGFjZUNvbnRleHQobmFtZXNwYWNlQ29udGV4dCk7Ci0KLSAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKGNvbnRleHROb2RlLCBjb250ZXh0Tm9kZSk7Ci0KLSAgICBYT2JqZWN0IHhvYmogPSBudWxsOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgeG9iaiA9IG1fbWFpbkV4cC5leGVjdXRlKHhjdHh0KTsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRlLnNldExvY2F0b3IodGhpcy5nZXRMb2NhdG9yKCkpOwotICAgICAgRXJyb3JMaXN0ZW5lciBlbCA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICAgIGlmKG51bGwgIT0gZWwpIC8vIGRlZmVuc2l2ZSwgc2hvdWxkIG5ldmVyIGhhcHBlbi4KLSAgICAgIHsKLSAgICAgICAgZWwuZXJyb3IodGUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICB0aHJvdyB0ZTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHdoaWxlIChlIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIGUgPSAoKG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKSBlKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgIH0KLSAgICAgIC8vIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0KLSAgICAgIFN0cmluZyBtc2cgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICAgIG1zZyA9IChtc2cgPT0gbnVsbCB8fCBtc2cubGVuZ3RoKCk9PSAwKT8gIlVua25vd24gZXJyb3IgaW4gWFBhdGgiIDogbXNnOwotICAgICAgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUgPSBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obXNnLAotICAgICAgICAgICAgICBnZXRMb2NhdG9yKCksIGUpOwotICAgICAgRXJyb3JMaXN0ZW5lciBlbCA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICAgIC8vIHRlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgaWYobnVsbCAhPSBlbCkgLy8gZGVmZW5zaXZlLCBzaG91bGQgbmV2ZXIgaGFwcGVuLgotICAgICAgewotICAgICAgICBlbC5mYXRhbEVycm9yKHRlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgdGhyb3cgdGU7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BOYW1lc3BhY2VDb250ZXh0KCk7Ci0KLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbigpOwotICAgIH0KLQotICAgIHJldHVybiB4b2JqOwotICB9Ci0gIAotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImV4cGVyaW1lbnRhbCIvPgotICAgKiBHaXZlbiBhbiBleHByZXNzaW9uIGFuZCBhIGNvbnRleHQsIGV2YWx1YXRlIHRoZSBYUGF0aAotICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqIAotICAgKiBAcGFyYW0geGN0eHQgVGhlIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCBuYW1lc3BhY2VzIGluIHRoZQotICAgKiBYUGF0aCBhcmUgc3VwcG9zZWQgdG8gYmUgZXhwYW5kZWQuCi0gICAqIAotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBkZWNpZGVzCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIGludCBjb250ZXh0Tm9kZSwgUHJlZml4UmVzb2x2ZXIgbmFtZXNwYWNlQ29udGV4dCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHhjdHh0LnB1c2hOYW1lc3BhY2VDb250ZXh0KG5hbWVzcGFjZUNvbnRleHQpOwotCi0gICAgeGN0eHQucHVzaEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbihjb250ZXh0Tm9kZSwgY29udGV4dE5vZGUpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgcmV0dXJuIG1fbWFpbkV4cC5ib29sKHhjdHh0KTsKLSAgICB9Ci0gICAgY2F0Y2ggKFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRlLnNldExvY2F0b3IodGhpcy5nZXRMb2NhdG9yKCkpOwotICAgICAgRXJyb3JMaXN0ZW5lciBlbCA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICAgIGlmKG51bGwgIT0gZWwpIC8vIGRlZmVuc2l2ZSwgc2hvdWxkIG5ldmVyIGhhcHBlbi4KLSAgICAgIHsKLSAgICAgICAgZWwuZXJyb3IodGUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICB0aHJvdyB0ZTsKLSAgICB9Ci0gICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHdoaWxlIChlIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIGUgPSAoKG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKSBlKS5nZXRFeGNlcHRpb24oKTsKLSAgICAgIH0KLSAgICAgIC8vIGUucHJpbnRTdGFja1RyYWNlKCk7Ci0KLSAgICAgIFN0cmluZyBtc2cgPSBlLmdldE1lc3NhZ2UoKTsKLSAgICAgIG1zZyA9IChtc2cgPT0gbnVsbCB8fCBtc2cubGVuZ3RoKCk9PSAwKT8gIlVua25vd24gZXJyb3IgaW4gWFBhdGgiIDogbXNnOwotICAgICAgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUgPSBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obXNnLAotICAgICAgICAgICAgICBnZXRMb2NhdG9yKCksIGUpOwotICAgICAgRXJyb3JMaXN0ZW5lciBlbCA9IHhjdHh0LmdldEVycm9yTGlzdGVuZXIoKTsKLSAgICAgIC8vIHRlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgaWYobnVsbCAhPSBlbCkgLy8gZGVmZW5zaXZlLCBzaG91bGQgbmV2ZXIgaGFwcGVuLgotICAgICAgewotICAgICAgICBlbC5mYXRhbEVycm9yKHRlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgdGhyb3cgdGU7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BOYW1lc3BhY2VDb250ZXh0KCk7Ci0KLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbigpOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKiBTZXQgdG8gdHJ1ZSB0byBnZXQgZGlhZ25vc3RpYyBtZXNzYWdlcyBhYm91dCB0aGUgcmVzdWx0IG9mIAotICAgKiAgbWF0Y2ggcGF0dGVybiB0ZXN0aW5nLiAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19NQVRDSEVTID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbWF0Y2ggc2NvcmUgb2YgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjdXJyZW50IHNvdXJjZSB0cmVlIGNvbnRleHQgbm9kZS4KLSAgICogCi0gICAqIEByZXR1cm4gc2NvcmUsIG9uZSBvZiB7QGxpbmsgI01BVENIX1NDT1JFX05PREVURVNUfSwKLSAgICoge0BsaW5rICNNQVRDSF9TQ09SRV9OT05FfSwge0BsaW5rICNNQVRDSF9TQ09SRV9PVEhFUn0sIAotICAgKiBvciB7QGxpbmsgI01BVENIX1NDT1JFX1FOQU1FfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZG91YmxlIGdldE1hdGNoU2NvcmUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY29udGV4dCk7Ci0gICAgeGN0eHQucHVzaEN1cnJlbnRFeHByZXNzaW9uTm9kZShjb250ZXh0KTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFhPYmplY3Qgc2NvcmUgPSBtX21haW5FeHAuZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgIGlmIChERUJVR19NQVRDSEVTKQotICAgICAgewotICAgICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNjb3JlOiAiICsgc2NvcmUubnVtKCkgKyAiIGZvciAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICArIGR0bS5nZXROb2RlTmFtZShjb250ZXh0KSArICIgZm9yIHhwYXRoICIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdGhpcy5nZXRQYXR0ZXJuU3RyaW5nKCkpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gc2NvcmUubnVtKCk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgeGN0eHQucG9wQ3VycmVudEV4cHJlc3Npb25Ob2RlKCk7Ci0gICAgfQotCi0gICAgLy8gcmV0dXJuIFhQYXRoLk1BVENIX1NDT1JFX05PTkU7Ci0gIH0KLQotICAvKioKLSAgICogSW5zdGFsbCBhIGJ1aWx0LWluIGZ1bmN0aW9uLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgZnVuY3Rpb24uCi0gICAqIEBwYXJhbSBmdW5jSW5kZXggVGhlIGluZGV4IG9mIHRoZSBmdW5jdGlvbiBpbiB0aGUgdGFibGUuCi0gICAqIEBwYXJhbSBmdW5jIEEgSW1wbGVtZW50YXRpb24gb2YgYW4gWFBhdGggRnVuY3Rpb24gb2JqZWN0LgotICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgZnVuY3Rpb24gaW4gdGhlIGludGVybmFsIGluZGV4LgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5zdGFsbEZ1bmN0aW9uKFN0cmluZyBuYW1lLCBpbnQgZnVuY0luZGV4LCBGdW5jdGlvbiBmdW5jKQotICB7Ci0gICAgRnVuY3Rpb25UYWJsZS5pbnN0YWxsRnVuY3Rpb24oZnVuYywgZnVuY0luZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBXYXJuIHRoZSB1c2VyIG9mIGFuIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gc291cmNlTm9kZSBOb3QgdXNlZC4KLSAgICogQHBhcmFtIG1zZyBBbiBlcnJvciBudW1iZXIgdGhhdCBjb3JyZXNwb25kcyB0byBvbmUgb2YgdGhlIG51bWJlcnMgZm91bmQgCi0gICAqICAgICAgICAgICAgaW4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXN9LCB3aGljaCBpcyAKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoIAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8gCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybigKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIGludCBzb3VyY2VOb2RlLCBpbnQgbXNnLCBPYmplY3RbXSBhcmdzKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSFdhcm5pbmcobXNnLCBhcmdzKTsKLSAgICBFcnJvckxpc3RlbmVyIGVoYW5kbGVyID0geGN0eHQuZ2V0RXJyb3JMaXN0ZW5lcigpOwotCi0gICAgaWYgKG51bGwgIT0gZWhhbmRsZXIpCi0gICAgewotCi0gICAgICAvLyBUTyBETzogTmVlZCB0byBnZXQgc3R5bGVzaGVldCBMb2NhdG9yIGZyb20gaGVyZS4KLSAgICAgIGVoYW5kbGVyLndhcm5pbmcobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIChTQVhTb3VyY2VMb2NhdG9yKXhjdHh0LmdldFNBWExvY2F0b3IoKSkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGFzc2VydGlvbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGIgIElmIGZhbHNlLCBhIHJ1bnRpbWUgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgotICAgKiBAcGFyYW0gbXNnIFRoZSBhc3NlcnRpb24gbWVzc2FnZSwgd2hpY2ggc2hvdWxkIGJlIGluZm9ybWF0aXZlLgotICAgKiAKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIHRoZSBiIGFyZ3VtZW50IGlzIGZhbHNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXNzZXJ0aW9uKGJvb2xlYW4gYiwgU3RyaW5nIG1zZykKLSAgewotCi0gICAgaWYgKCFiKQotICAgIHsKLSAgICAgIFN0cmluZyBmTXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKAotICAgICAgICBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiwKLSAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSk7Ci0KLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGZNc2cpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHBhcmFtIHNvdXJjZU5vZGUgTm90IHVzZWQuCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbnVtYmVyIHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBudW1iZXJzIGZvdW5kIAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMgCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaCAKLSAgICogICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgRXJyb3JMaXN0b25lciBkZXRlcm1pbmVzIHRvIAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IHNvdXJjZU5vZGUsIGludCBtc2csIE9iamVjdFtdIGFyZ3MpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotICAgIEVycm9yTGlzdGVuZXIgZWhhbmRsZXIgPSB4Y3R4dC5nZXRFcnJvckxpc3RlbmVyKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBlaGFuZGxlcikKLSAgICB7Ci0gICAgICBlaGFuZGxlci5mYXRhbEVycm9yKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNBWFNvdXJjZUxvY2F0b3IpeGN0eHQuZ2V0U0FYTG9jYXRvcigpKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBTb3VyY2VMb2NhdG9yIHNsb2NhdG9yID0geGN0eHQuZ2V0U0FYTG9jYXRvcigpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKGZtc2cgKyAiOyBmaWxlICIgKyBzbG9jYXRvci5nZXRTeXN0ZW1JZCgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgKyAiOyBsaW5lICIgKyBzbG9jYXRvci5nZXRMaW5lTnVtYmVyKCkgKyAiOyBjb2x1bW4gIgotICAgICAgICAgICAgICAgICAgICAgICAgICsgc2xvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIG5vIG1hdGNoIGlzIG1hZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBNQVRDSF9TQ09SRV9OT05FID0gRG91YmxlLk5FR0FUSVZFX0lORklOSVRZOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGhhcyB0aGUgZm9ybQotICAgKiBvZiBhIFFOYW1lIG9wdGlvbmFsbHkgcHJlY2VkZWQgYnkgYW4gQCBjaGFyYWN0ZXIuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBNQVRDSF9TQ09SRV9RTkFNRSA9IDAuMDsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiB0aGUgcGF0dGVybiBwYXR0ZXJuIGhhcyB0aGUgZm9ybSBOQ05hbWU6Ki4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE1BVENIX1NDT1JFX05TV0lMRCA9IC0wLjI1OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGNvbnNpc3RzIG9mIGp1c3QgYSBOb2RlVGVzdC4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgZG91YmxlIE1BVENIX1NDT1JFX05PREVURVNUID0gLTAuNTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiB0aGUgcGF0dGVybiBjb25zaXN0cyBvZiBzb21ldGhpbmcKLSAgICogb3RoZXIgdGhhbiBqdXN0IGEgTm9kZVRlc3Qgb3IganVzdCBhIHFuYW1lLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUgTUFUQ0hfU0NPUkVfT1RIRVIgPSAwLjU7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aEFQSS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvWFBhdGhBUEkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNWY4YzM1OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aEFQSS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzIwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGg7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLlhQYXRoUGFyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyRGVmYXVsdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1NYW5hZ2VyRGVmYXVsdDsKLQotLyoqCi0gKiBUaGUgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGFyZSBjb252ZW5pZW5jZSBtZXRob2RzIGludG8gdGhlCi0gKiBsb3ctbGV2ZWwgWFBhdGggQVBJLgotICogVGhlc2UgZnVuY3Rpb25zIHRlbmQgdG8gYmUgYSBsaXR0bGUgc2xvdywgc2luY2UgYSBudW1iZXIgb2Ygb2JqZWN0cyBtdXN0IGJlCi0gKiBjcmVhdGVkIGZvciBlYWNoIGV2YWx1YXRpb24uICBBIGZhc3RlciB3YXkgaXMgdG8gcHJlY29tcGlsZSB0aGUKLSAqIFhQYXRocyB1c2luZyB0aGUgbG93LWxldmVsIEFQSSwgYW5kIHRoZW4ganVzdCB1c2UgdGhlIFhQYXRocwotICogb3ZlciBhbmQgb3Zlci4KLSAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgiPlhQYXRoIFNwZWNpZmljYXRpb248L2E+Ci0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aEFQSQotewotCi0gIC8qKgotICAgKiBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIHNpbmdsZSBub2RlLiBYUGF0aCBuYW1lc3BhY2UKLSAgICogcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIGNvbnRleHQgbm9kZSwgd2hpY2ggbWF5IG5vdAotICAgKiBiZSB3aGF0IHlvdSB3YW50IChzZWUgdGhlIG5leHQgbWV0aG9kKS4KLSAgICoKLSAgICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiBAcGFyYW0gc3RyIEEgdmFsaWQgWFBhdGggc3RyaW5nLgotICAgKiBAcmV0dXJuIFRoZSBmaXJzdCBub2RlIGZvdW5kIHRoYXQgbWF0Y2hlcyB0aGUgWFBhdGgsIG9yIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgTm9kZSBzZWxlY3RTaW5nbGVOb2RlKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gc2VsZWN0U2luZ2xlTm9kZShjb250ZXh0Tm9kZSwgc3RyLCBjb250ZXh0Tm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogVXNlIGFuIFhQYXRoIHN0cmluZyB0byBzZWxlY3QgYSBzaW5nbGUgbm9kZS4KLSAgICogWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uCi0gICAqIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogQHJldHVybiBUaGUgZmlyc3Qgbm9kZSBmb3VuZCB0aGF0IG1hdGNoZXMgdGhlIFhQYXRoLCBvciBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGUgc2VsZWN0U2luZ2xlTm9kZSgKLSAgICAgICAgICBOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyLCBOb2RlIG5hbWVzcGFjZU5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSGF2ZSB0aGUgWE9iamVjdCByZXR1cm4gaXRzIHJlc3VsdCBhcyBhIE5vZGVTZXREVE0uCi0gICAgTm9kZUl0ZXJhdG9yIG5sID0gc2VsZWN0Tm9kZUl0ZXJhdG9yKGNvbnRleHROb2RlLCBzdHIsIG5hbWVzcGFjZU5vZGUpOwotCi0gICAgLy8gUmV0dXJuIHRoZSBmaXJzdCBub2RlLCBvciBudWxsCi0gICAgcmV0dXJuIG5sLm5leHROb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogIFVzZSBhbiBYUGF0aCBzdHJpbmcgdG8gc2VsZWN0IGEgbm9kZWxpc3QuCi0gICAqICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIGNvbnRleHROb2RlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEByZXR1cm4gQSBOb2RlSXRlcmF0b3IsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVJdGVyYXRvciBzZWxlY3ROb2RlSXRlcmF0b3IoTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0cikKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBzZWxlY3ROb2RlSXRlcmF0b3IoY29udGV4dE5vZGUsIHN0ciwgY29udGV4dE5vZGUpOwotICB9Ci0KLSAgLyoqCi0gICAqICBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIG5vZGVsaXN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogIEByZXR1cm4gQSBOb2RlSXRlcmF0b3IsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIE5vZGVJdGVyYXRvciBzZWxlY3ROb2RlSXRlcmF0b3IoCi0gICAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0ciwgTm9kZSBuYW1lc3BhY2VOb2RlKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEV4ZWN1dGUgdGhlIFhQYXRoLCBhbmQgaGF2ZSBpdCByZXR1cm4gdGhlIHJlc3VsdAotICAgIFhPYmplY3QgbGlzdCA9IGV2YWwoY29udGV4dE5vZGUsIHN0ciwgbmFtZXNwYWNlTm9kZSk7Ci0KLSAgICAvLyBIYXZlIHRoZSBYT2JqZWN0IHJldHVybiBpdHMgcmVzdWx0IGFzIGEgTm9kZVNldERUTS4gICAgICAgICAgICAgICAgCi0gICAgcmV0dXJuIGxpc3Qubm9kZXNldCgpOwotICB9Ci0KLSAgLyoqCi0gICAqICBVc2UgYW4gWFBhdGggc3RyaW5nIHRvIHNlbGVjdCBhIG5vZGVsaXN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBjb250ZXh0Tm9kZS4KLSAgICoKLSAgICogIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICBAcmV0dXJuIEEgTm9kZUl0ZXJhdG9yLCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBzZWxlY3ROb2RlTGlzdChOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIHNlbGVjdE5vZGVMaXN0KGNvbnRleHROb2RlLCBzdHIsIGNvbnRleHROb2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiAgVXNlIGFuIFhQYXRoIHN0cmluZyB0byBzZWxlY3QgYSBub2RlbGlzdC4KLSAgICogIFhQYXRoIG5hbWVzcGFjZSBwcmVmaXhlcyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGUgbmFtZXNwYWNlTm9kZS4KLSAgICoKLSAgICogIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS4KLSAgICogIEBwYXJhbSBzdHIgQSB2YWxpZCBYUGF0aCBzdHJpbmcuCi0gICAqICBAcGFyYW0gbmFtZXNwYWNlTm9kZSBUaGUgbm9kZSBmcm9tIHdoaWNoIHByZWZpeGVzIGluIHRoZSBYUGF0aCB3aWxsIGJlIHJlc29sdmVkIHRvIG5hbWVzcGFjZXMuCi0gICAqICBAcmV0dXJuIEEgTm9kZUl0ZXJhdG9yLCBzaG91bGQgbmV2ZXIgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBOb2RlTGlzdCBzZWxlY3ROb2RlTGlzdCgKLSAgICAgICAgICBOb2RlIGNvbnRleHROb2RlLCBTdHJpbmcgc3RyLCBOb2RlIG5hbWVzcGFjZU5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gRXhlY3V0ZSB0aGUgWFBhdGgsIGFuZCBoYXZlIGl0IHJldHVybiB0aGUgcmVzdWx0Ci0gICAgWE9iamVjdCBsaXN0ID0gZXZhbChjb250ZXh0Tm9kZSwgc3RyLCBuYW1lc3BhY2VOb2RlKTsKLQotICAgIC8vIFJldHVybiBhIE5vZGVMaXN0LgotICAgIHJldHVybiBsaXN0Lm5vZGVsaXN0KCk7Ci0gIH0KLQotICAvKioKLSAgICogIEV2YWx1YXRlIFhQYXRoIHN0cmluZyB0byBhbiBYT2JqZWN0LiAgVXNpbmcgdGhpcyBtZXRob2QsCi0gICAqICBYUGF0aCBuYW1lc3BhY2UgcHJlZml4ZXMgd2lsbCBiZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogIEByZXR1cm4gQW4gWE9iamVjdCwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gb2J0YWluIGEgc3RyaW5nLCBudW1iZXIsIG5vZGVsaXN0LCBldGMsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKiAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdAotICAgKiAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bGwKLSAgICogIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuCi0gICAqICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyCi0gICAqICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nCi0gICAqICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE9iamVjdCBldmFsKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXZhbChjb250ZXh0Tm9kZSwgc3RyLCBjb250ZXh0Tm9kZSk7Ci0gIH0KLQotICAvKioKLSAgICogIEV2YWx1YXRlIFhQYXRoIHN0cmluZyB0byBhbiBYT2JqZWN0LgotICAgKiAgWFBhdGggbmFtZXNwYWNlIHByZWZpeGVzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBuYW1lc3BhY2VOb2RlLgotICAgKiAgVGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgaXMgYSBsaXR0bGUgc2xvdywgc2luY2UgaXQgY3JlYXRlcwotICAgKiAgYSBudW1iZXIgb2Ygb2JqZWN0cyBlYWNoIHRpbWUgaXQgaXMgY2FsbGVkLiAgVGhpcyBjb3VsZCBiZSBvcHRpbWl6ZWQKLSAgICogIHRvIGtlZXAgdGhlIHNhbWUgb2JqZWN0cyBhcm91bmQsIGJ1dCB0aGVuIHRocmVhZC1zYWZldHkgaXNzdWVzIHdvdWxkIGFyaXNlLgotICAgKgotICAgKiAgQHBhcmFtIGNvbnRleHROb2RlIFRoZSBub2RlIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLgotICAgKiAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogIEBwYXJhbSBuYW1lc3BhY2VOb2RlIFRoZSBub2RlIGZyb20gd2hpY2ggcHJlZml4ZXMgaW4gdGhlIFhQYXRoIHdpbGwgYmUgcmVzb2x2ZWQgdG8gbmFtZXNwYWNlcy4KLSAgICogIEByZXR1cm4gQW4gWE9iamVjdCwgd2hpY2ggY2FuIGJlIHVzZWQgdG8gb2J0YWluIGEgc3RyaW5nLCBudW1iZXIsIG5vZGVsaXN0LCBldGMsIHNob3VsZCBuZXZlciBiZSBudWxsLgotICAgKiAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdAotICAgKiAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bGwKLSAgICogIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuCi0gICAqICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyCi0gICAqICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nCi0gICAqICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YUlRyZWVGcmFnCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWE9iamVjdCBldmFsKE5vZGUgY29udGV4dE5vZGUsIFN0cmluZyBzdHIsIE5vZGUgbmFtZXNwYWNlTm9kZSkKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU2luY2Ugd2UgZG9uJ3QgaGF2ZSBhIFhNTCBQYXJzZXIgaW52b2x2ZWQgaGVyZSwgaW5zdGFsbCBzb21lIGRlZmF1bHQgc3VwcG9ydAotICAgIC8vIGZvciB0aGluZ3MgbGlrZSBuYW1lc3BhY2VzLCBldGMuCi0gICAgLy8gKENoYW5nZWQgZnJvbTogWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICAvLyAgICBiZWNhdXNlIFhQYXRoQ29udGV4dCBpcyB3ZWFrIGluIGEgbnVtYmVyIG9mIGFyZWFzLi4uIHBlcmhhcHMKLSAgICAvLyAgICBYUGF0aENvbnRleHQgc2hvdWxkIGJlIGRvbmUgYXdheSB3aXRoLikKLSAgICBYUGF0aENvbnRleHQgeHBhdGhTdXBwb3J0ID0gbmV3IFhQYXRoQ29udGV4dCgpOwotCi0gICAgLy8gQ3JlYXRlIGFuIG9iamVjdCB0byByZXNvbHZlIG5hbWVzcGFjZSBwcmVmaXhlcy4KLSAgICAvLyBYUGF0aCBuYW1lc3BhY2VzIGFyZSByZXNvbHZlZCBmcm9tIHRoZSBpbnB1dCBjb250ZXh0IG5vZGUncyBkb2N1bWVudCBlbGVtZW50Ci0gICAgLy8gaWYgaXQgaXMgYSByb290IG5vZGUsIG9yIGVsc2UgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIChmb3IgbGFjayBvZiBhIGJldHRlcgotICAgIC8vIHJlc29sdXRpb24gc3BhY2UsIGdpdmVuIHRoZSBzaW1wbGljaXR5IG9mIHRoaXMgc2FtcGxlIGNvZGUpLgotICAgIFByZWZpeFJlc29sdmVyRGVmYXVsdCBwcmVmaXhSZXNvbHZlciA9IG5ldyBQcmVmaXhSZXNvbHZlckRlZmF1bHQoCi0gICAgICAobmFtZXNwYWNlTm9kZS5nZXROb2RlVHlwZSgpID09IE5vZGUuRE9DVU1FTlRfTk9ERSkKLSAgICAgID8gKChEb2N1bWVudCkgbmFtZXNwYWNlTm9kZSkuZ2V0RG9jdW1lbnRFbGVtZW50KCkgOiBuYW1lc3BhY2VOb2RlKTsKLQotICAgIC8vIENyZWF0ZSB0aGUgWFBhdGggb2JqZWN0LgotICAgIFhQYXRoIHhwYXRoID0gbmV3IFhQYXRoKHN0ciwgbnVsbCwgcHJlZml4UmVzb2x2ZXIsIFhQYXRoLlNFTEVDVCwgbnVsbCk7Ci0KLSAgICAvLyBFeGVjdXRlIHRoZSBYUGF0aCwgYW5kIGhhdmUgaXQgcmV0dXJuIHRoZSByZXN1bHQKLSAgICAvLyByZXR1cm4geHBhdGguZXhlY3V0ZSh4cGF0aFN1cHBvcnQsIGNvbnRleHROb2RlLCBwcmVmaXhSZXNvbHZlcik7Ci0gICAgaW50IGN0eHROb2RlID0geHBhdGhTdXBwb3J0LmdldERUTUhhbmRsZUZyb21Ob2RlKGNvbnRleHROb2RlKTsKLQotICAgIHJldHVybiB4cGF0aC5leGVjdXRlKHhwYXRoU3VwcG9ydCwgY3R4dE5vZGUsIHByZWZpeFJlc29sdmVyKTsKLSAgfQotCi0gIC8qKgotICAgKiAgIEV2YWx1YXRlIFhQYXRoIHN0cmluZyB0byBhbiBYT2JqZWN0LgotICAgKiAgIFhQYXRoIG5hbWVzcGFjZSBwcmVmaXhlcyBhcmUgcmVzb2x2ZWQgZnJvbSB0aGUgbmFtZXNwYWNlTm9kZS4KLSAgICogICBUaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpcyBhIGxpdHRsZSBzbG93LCBzaW5jZSBpdCBjcmVhdGVzCi0gICAqICAgYSBudW1iZXIgb2Ygb2JqZWN0cyBlYWNoIHRpbWUgaXQgaXMgY2FsbGVkLiAgVGhpcyBjb3VsZCBiZSBvcHRpbWl6ZWQKLSAgICogICB0byBrZWVwIHRoZSBzYW1lIG9iamVjdHMgYXJvdW5kLCBidXQgdGhlbiB0aHJlYWQtc2FmZXR5IGlzc3VlcyB3b3VsZCBhcmlzZS4KLSAgICoKLSAgICogICBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uCi0gICAqICAgQHBhcmFtIHN0ciBBIHZhbGlkIFhQYXRoIHN0cmluZy4KLSAgICogICBAcGFyYW0gbmFtZXNwYWNlTm9kZSBUaGUgbm9kZSBmcm9tIHdoaWNoIHByZWZpeGVzIGluIHRoZSBYUGF0aCB3aWxsIGJlIHJlc29sdmVkIHRvIG5hbWVzcGFjZXMuCi0gICAqICAgQHBhcmFtIHByZWZpeFJlc29sdmVyIFdpbGwgYmUgY2FsbGVkIGlmIHRoZSBwYXJzZXIgZW5jb3VudGVycyBuYW1lc3BhY2UKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ZXMsIHRvIHJlc29sdmUgdGhlIHByZWZpeGVzIHRvIFVSTHMuCi0gICAqICAgQHJldHVybiBBbiBYT2JqZWN0LCB3aGljaCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gYSBzdHJpbmcsIG51bWJlciwgbm9kZWxpc3QsIGV0Yywgc2hvdWxkIG5ldmVyIGJlIG51bGwuCi0gICAqICAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdAotICAgKiAgIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdWxsCi0gICAqICAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW4KLSAgICogICBAc2VlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyCi0gICAqICAgQHNlZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZwotICAgKiAgIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhSVHJlZUZyYWcKLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBYT2JqZWN0IGV2YWwoCi0gICAgICAgICAgTm9kZSBjb250ZXh0Tm9kZSwgU3RyaW5nIHN0ciwgUHJlZml4UmVzb2x2ZXIgcHJlZml4UmVzb2x2ZXIpCi0gICAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gU2luY2Ugd2UgZG9uJ3QgaGF2ZSBhIFhNTCBQYXJzZXIgaW52b2x2ZWQgaGVyZSwgaW5zdGFsbCBzb21lIGRlZmF1bHQgc3VwcG9ydAotICAgIC8vIGZvciB0aGluZ3MgbGlrZSBuYW1lc3BhY2VzLCBldGMuCi0gICAgLy8gKENoYW5nZWQgZnJvbTogWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICAvLyAgICBiZWNhdXNlIFhQYXRoQ29udGV4dCBpcyB3ZWFrIGluIGEgbnVtYmVyIG9mIGFyZWFzLi4uIHBlcmhhcHMKLSAgICAvLyAgICBYUGF0aENvbnRleHQgc2hvdWxkIGJlIGRvbmUgYXdheSB3aXRoLikKLSAgICAvLyBDcmVhdGUgdGhlIFhQYXRoIG9iamVjdC4KLSAgICBYUGF0aCB4cGF0aCA9IG5ldyBYUGF0aChzdHIsIG51bGwsIHByZWZpeFJlc29sdmVyLCBYUGF0aC5TRUxFQ1QsIG51bGwpOwotCi0gICAgLy8gRXhlY3V0ZSB0aGUgWFBhdGgsIGFuZCBoYXZlIGl0IHJldHVybiB0aGUgcmVzdWx0Ci0gICAgWFBhdGhDb250ZXh0IHhwYXRoU3VwcG9ydCA9IG5ldyBYUGF0aENvbnRleHQoKTsKLSAgICBpbnQgY3R4dE5vZGUgPSB4cGF0aFN1cHBvcnQuZ2V0RFRNSGFuZGxlRnJvbU5vZGUoY29udGV4dE5vZGUpOwotCi0gICAgcmV0dXJuIHhwYXRoLmV4ZWN1dGUoeHBhdGhTdXBwb3J0LCBjdHh0Tm9kZSwgcHJlZml4UmVzb2x2ZXIpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aENvbnRleHQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1hQYXRoQ29udGV4dC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OGE0YzQ1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1hQYXRoQ29udGV4dC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE1MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoOwotCi0vLyBKYXZhIGxpYiBpbXBvcnRzCi1pbXBvcnQgamF2YS5pby5GaWxlOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci0KLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7Ci0KLS8vIFhhbGFuIGltcG9ydHMKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5JbnRTdGFjazsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5OU0luZm87Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuTm9kZVZlY3RvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Db250ZXh0Tm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLlN1YkNvbnRleHRMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5FeHByZXNzaW9uQ29udGV4dDsKLQotLy8gU0FYMiBpbXBvcnRzCi1pbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7Ci1pbXBvcnQgb3JnLnhtbC5zYXguWE1MUmVhZGVyOwotLy8gaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci0KLS8vIFRSYVggaW1wb3J0cwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVVJJUmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOwotCi0vLyBUZW1wb3JhcnkhISEKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuRXh0ZW5zaW9uc1RhYmxlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uRXJyb3JMaXN0ZW5lcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTVdTRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vLyBVdGlsaXR5IGltcG9ydHMuCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuU0FYU291cmNlTG9jYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5EZXNjZW5kYW50SXRlcmF0b3I7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBEZWZhdWx0IGNsYXNzIGZvciB0aGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dCBmb3IgWFBhdGguCi0gKiAKLSAqIDxwPlRoaXMgY2xhc3MgZXh0ZW5kcyBEVE1NYW5hZ2VyIGJ1dCBkb2VzIG5vdCBkaXJlY3RseSBpbXBsZW1lbnQgaXQuPC9wPgotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhDb250ZXh0IGV4dGVuZHMgRFRNTWFuYWdlciAvLyBpbXBsZW1lbnRzIEV4cHJlc3Npb25Db250ZXh0Ci17Ci0gIC8qKgotICAgKiBUaG91Z2ggWFBhdGhDb250ZXh0IGNvbnRleHQgZXh0ZW5kcyAKLSAgICogdGhlIERUTU1hbmFnZXIsIGl0IHJlYWxseSBpcyBhIHByb3h5IGZvciB0aGlzIG9iamVjdCwgd2hpY2ggCi0gICAqIGlzIHRoZSByZWFsIERUTU1hbmFnZXIuCi0gICAqLwotICBwcml2YXRlIERUTU1hbmFnZXIgbV9kdG1NYW5hZ2VyID0gRFRNTWFuYWdlci5uZXdJbnN0YW5jZSgKLSAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE1MU3RyaW5nRmFjdG9yeUltcGwuZ2V0RmFjdG9yeSgpKTsKLSAgCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIERUTU1hbmFnZXIgb2JqZWN0LiAgVGhvdWdoIFhQYXRoQ29udGV4dCBjb250ZXh0IGV4dGVuZHMgCi0gICAqIHRoZSBEVE1NYW5hZ2VyLCBpdCByZWFsbHkgaXMgYSBwcm94eSBmb3IgdGhlIHJlYWwgRFRNTWFuYWdlci4gIElmIGEgCi0gICAqIGNhbGxlciBuZWVkcyB0byBtYWtlIGEgbG90IG9mIGNhbGxzIHRvIHRoZSBEVE1NYW5hZ2VyLCBpdCBpcyBmYXN0ZXIgCi0gICAqIGlmIGl0IGdldHMgdGhlIHJlYWwgb25lIGZyb20gdGhpcyBmdW5jdGlvbi4KLSAgICovCi0gICBwdWJsaWMgRFRNTWFuYWdlciBnZXREVE1NYW5hZ2VyKCkKLSAgIHsKLSAgICAgcmV0dXJuIG1fZHRtTWFuYWdlcjsKLSAgIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgYSBEVE0sIGxvYWRlZCB3aXRoIHRoZSBjb250ZW50IGZyb20gdGhlCi0gICAqIHNwZWNpZmllZCBzb3VyY2UuICBJZiB0aGUgdW5pcXVlIGZsYWcgaXMgdHJ1ZSwgYSBuZXcgaW5zdGFuY2Ugd2lsbAotICAgKiBhbHdheXMgYmUgcmV0dXJuZWQuICBPdGhlcndpc2UgaXQgaXMgdXAgdG8gdGhlIERUTU1hbmFnZXIgdG8gcmV0dXJuIGEKLSAgICogbmV3IGluc3RhbmNlIG9yIGFuIGluc3RhbmNlIHRoYXQgaXQgYWxyZWFkeSBjcmVhdGVkIGFuZCBtYXkgYmUgYmVpbmcgdXNlZAotICAgKiBieSBzb21lb25lIGVsc2UuCi0gICAqIChJIHRoaW5rIG1vcmUgcGFyYW1ldGVycyB3aWxsIG5lZWQgdG8gYmUgYWRkZWQgZm9yIGVycm9yIGhhbmRsaW5nLCBhbmQgZW50aXR5Ci0gICAqIHJlc29sdXRpb24pLgotICAgKgotICAgKiBAcGFyYW0gc291cmNlIHRoZSBzcGVjaWZpY2F0aW9uIG9mIHRoZSBzb3VyY2Ugb2JqZWN0LCB3aGljaCBtYXkgYmUgbnVsbCwgCi0gICAqICAgICAgICAgICAgICAgaW4gd2hpY2ggY2FzZSBpdCBpcyBhc3N1bWVkIHRoYXQgbm9kZSBjb25zdHJ1Y3Rpb24gd2lsbCB0YWtlIAotICAgKiAgICAgICAgICAgICAgIGJ5IHNvbWUgb3RoZXIgbWVhbnMuCi0gICAqIEBwYXJhbSB1bmlxdWUgdHJ1ZSBpZiB0aGUgcmV0dXJuZWQgRFRNIG11c3QgYmUgdW5pcXVlLCBwcm9iYWJseSBiZWNhdXNlIGl0Ci0gICAqIGlzIGdvaW5nIHRvIGJlIG11dGF0ZWQuCi0gICAqIEBwYXJhbSB3aGl0ZVNwYWNlRmlsdGVyIEVuYWJsZXMgZmlsdGVyaW5nIG9mIHdoaXRlc3BhY2Ugbm9kZXMsIGFuZCBtYXkgCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgIGJlIG51bGwuCi0gICAqIEBwYXJhbSBpbmNyZW1lbnRhbCB0cnVlIGlmIHRoZSBjb25zdHJ1Y3Rpb24gc2hvdWxkIHRyeSBhbmQgYmUgaW5jcmVtZW50YWwuCi0gICAqIEBwYXJhbSBkb0luZGV4aW5nIHRydWUgaWYgdGhlIGNhbGxlciBjb25zaWRlcnMgaXQgd29ydGggaXQgdG8gdXNlIAotICAgKiAgICAgICAgICAgICAgICAgICBpbmRleGluZyBzY2hlbWVzLgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlIHNvdXJjZSwgYm9vbGVhbiB1bmlxdWUsIAotICAgICAgICAgICAgICAgICAgICBEVE1XU0ZpbHRlciB3c2ZpbHRlciwKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpbmNyZW1lbnRhbCwKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb0luZGV4aW5nKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWFuYWdlci5nZXREVE0oc291cmNlLCB1bmlxdWUsIHdzZmlsdGVyLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNyZW1lbnRhbCwgZG9JbmRleGluZyk7Ci0gIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgYSBEVE0gdGhhdCAib3ducyIgYSBub2RlIGhhbmRsZS4KLSAgICoKLSAgICogQHBhcmFtIG5vZGVIYW5kbGUgdGhlIG5vZGVIYW5kbGUuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE0gcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIERUTSBnZXREVE0oaW50IG5vZGVIYW5kbGUpCi0gIHsKLSAgICByZXR1cm4gbV9kdG1NYW5hZ2VyLmdldERUTShub2RlSGFuZGxlKTsKLSAgfQotLy8gIAotICAvKioKLSAgICogR2l2ZW4gYSBXM0MgRE9NIG5vZGUsIHRyeSBhbmQgcmV0dXJuIGEgRFRNIGhhbmRsZS4KLSAgICogTm90ZTogY2FsbGluZyB0aGlzIG1heSBiZSBub24tb3B0aW1hbC4KLSAgICogCi0gICAqIEBwYXJhbSBub2RlIE5vbi1udWxsIHJlZmVyZW5jZSB0byBhIERPTSBub2RlLgotICAgKiAKLSAgICogQHJldHVybiBhIHZhbGlkIERUTSBoYW5kbGUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldERUTUhhbmRsZUZyb21Ob2RlKG9yZy53M2MuZG9tLk5vZGUgbm9kZSkKLSAgewotICAgIHJldHVybiBtX2R0bU1hbmFnZXIuZ2V0RFRNSGFuZGxlRnJvbU5vZGUobm9kZSk7Ci0gIH0KLS8vCi0vLyAgCi0gIC8qKgotICAgKiAlVEJEJSBEb2MKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0RFRNSWRlbnRpdHkoRFRNIGR0bSkKLSAgewotICAgIHJldHVybiBtX2R0bU1hbmFnZXIuZ2V0RFRNSWRlbnRpdHkoZHRtKTsKLSAgfQotLy8gIAotICAvKioKLSAgICogQ3JlYXRlcyBhbiBlbXB0eSA8Y29kZT5Eb2N1bWVudEZyYWdtZW50PC9jb2RlPiBvYmplY3QuIAotICAgKiBAcmV0dXJuIEEgbmV3IDxjb2RlPkRvY3VtZW50RnJhZ21lbnQgaGFuZGxlPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBEVE0gY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCi0gIHsKLSAgICByZXR1cm4gbV9kdG1NYW5hZ2VyLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLSAgfQotLy8gIAotICAvKioKLSAgICogUmVsZWFzZSBhIERUTSBlaXRoZXIgdG8gYSBscnUgcG9vbCwgb3IgY29tcGxldGVseSByZW1vdmUgcmVmZXJlbmNlLgotICAgKiBEVE1zIHdpdGhvdXQgc3lzdGVtIElEcyBhcmUgYWx3YXlzIGhhcmQgZGVsZXRlZC4KLSAgICogU3RhdGU6IGV4cGVyaW1lbnRhbC4KLSAgICogCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSB0byBiZSByZWxlYXNlZC4KLSAgICogQHBhcmFtIHNob3VsZEhhcmREZWxldGUgVHJ1ZSBpZiB0aGUgRFRNIHNob3VsZCBiZSByZW1vdmVkIG5vIG1hdHRlciB3aGF0LgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIERUTSB3YXMgcmVtb3ZlZCwgZmFsc2UgaWYgaXQgd2FzIHB1dCBiYWNrIGluIGEgbHJ1IHBvb2wuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiByZWxlYXNlKERUTSBkdG0sIGJvb2xlYW4gc2hvdWxkSGFyZERlbGV0ZSkKLSAgewotICAgIHJldHVybiBtX2R0bU1hbmFnZXIucmVsZWFzZShkdG0sIHNob3VsZEhhcmREZWxldGUpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gYmFzZWQgb24gYW4gWFBhdGgKLSAgICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTG9jYXRpb25QYXRoPkxvY2F0aW9uUGF0aDwvYT4gb3IKLSAgICogYSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1VbmlvbkV4cHIiPlVuaW9uRXhwcjwvYT4uCi0gICAqCi0gICAqIEBwYXJhbSB4cGF0aENvbXBpbGVyID8/PyBTb21laG93IHdlIG5lZWQgdG8gcGFzcyBpbiBhIHN1YnBhcnQgb2YgdGhlCi0gICAqIGV4cHJlc3Npb24uICBJIGhhdGUgdG8gZG8gdGhpcyB3aXRoIHN0cmluZ3MsIHNpbmNlIHRoZSBsYXJnZXIgZXhwcmVzc2lvbgotICAgKiBoYXMgYWxyZWFkeSBiZWVuIHBhcnNlZC4KLSAgICoKLSAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gaW4gdGhlIGV4cHJlc3Npb24uCi0gICAqIEByZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgPGNvZGU+RFRNSXRlcmF0b3I8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKE9iamVjdCB4cGF0aENvbXBpbGVyLCBpbnQgcG9zKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWFuYWdlci5jcmVhdGVEVE1JdGVyYXRvcih4cGF0aENvbXBpbGVyLCBwb3MpOwotICB9Ci0vLwotICAvKioKLSAgICogQ3JlYXRlIGEgbmV3IDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBiYXNlZCBvbiBhbiBYUGF0aAotICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1Mb2NhdGlvblBhdGg+TG9jYXRpb25QYXRoPC9hPiBvcgotICAgKiBhIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULVVuaW9uRXhwciI+VW5pb25FeHByPC9hPi4KLSAgICoKLSAgICogQHBhcmFtIHhwYXRoU3RyaW5nIE11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZXhwcmVzc2luZyBhCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULUxvY2F0aW9uUGF0aD5Mb2NhdGlvblBhdGg8L2E+IG9yCi0gICAqIGEgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LgotICAgKgotICAgKiBAcGFyYW0gcHJlc29sdmVyIEFuIG9iamVjdCB0aGF0IGNhbiByZXNvbHZlIHByZWZpeGVzIHRvIG5hbWVzcGFjZSBVUkxzLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihTdHJpbmcgeHBhdGhTdHJpbmcsCi0gICAgICAgICAgUHJlZml4UmVzb2x2ZXIgcHJlc29sdmVyKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWFuYWdlci5jcmVhdGVEVE1JdGVyYXRvcih4cGF0aFN0cmluZywgcHJlc29sdmVyKTsKLSAgfQotLy8KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gYmFzZWQgb25seSBvbiBhIHdoYXRUb1Nob3cgYW5kCi0gICAqIGEgRFRNRmlsdGVyLiAgVGhlIHRyYXZlcnNhbCBzZW1hbnRpY3MgYXJlIGRlZmluZWQgYXMgdGhlIGRlc2NlbmRhbnQKLSAgICogYWNjZXNzLgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBUaGlzIGZsYWcgc3BlY2lmaWVzIHdoaWNoIG5vZGUgdHlwZXMgbWF5IGFwcGVhciBpbgotICAgKiAgIHRoZSBsb2dpY2FsIHZpZXcgb2YgdGhlIHRyZWUgcHJlc2VudGVkIGJ5IHRoZSBpdGVyYXRvci4gU2VlIHRoZQotICAgKiAgIGRlc2NyaXB0aW9uIG9mIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGZvciB0aGUgc2V0IG9mIHBvc3NpYmxlCi0gICAqICAgPGNvZGU+U0hPV188L2NvZGU+IHZhbHVlcy5UaGVzZSBmbGFncyBjYW4gYmUgY29tYmluZWQgdXNpbmcKLSAgICogICA8Y29kZT5PUjwvY29kZT4uCi0gICAqIEBwYXJhbSBmaWx0ZXIgVGhlIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IHRvIGJlIHVzZWQgd2l0aCB0aGlzCi0gICAqICAgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IHRvIGluZGljYXRlIG5vIGZpbHRlci4KLSAgICogQHBhcmFtIGVudGl0eVJlZmVyZW5jZUV4cGFuc2lvbiBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMKLSAgICogICB3aGV0aGVyIGVudGl0eSByZWZlcmVuY2Ugbm9kZXMgYXJlIGV4cGFuZGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY3JlYXRlRFRNSXRlcmF0b3IoaW50IHdoYXRUb1Nob3csCi0gICAgICAgICAgRFRNRmlsdGVyIGZpbHRlciwgYm9vbGVhbiBlbnRpdHlSZWZlcmVuY2VFeHBhbnNpb24pCi0gIHsKLSAgICByZXR1cm4gbV9kdG1NYW5hZ2VyLmNyZWF0ZURUTUl0ZXJhdG9yKHdoYXRUb1Nob3csIGZpbHRlciwgZW50aXR5UmVmZXJlbmNlRXhwYW5zaW9uKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gdGhhdCBob2xkcyBleGFjdGx5IG9uZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSBoYW5kbGUgdGhhdCB0aGUgRFRNSXRlcmF0b3Igd2lsbCBpdGVyYXRlIHRvLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBEVE1JdGVyYXRvciBjcmVhdGVEVE1JdGVyYXRvcihpbnQgbm9kZSkKLSAgewotICAgIC8vIERlc2NlbmRhbnRJdGVyYXRvciBpdGVyID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcigpOwotICAgIERUTUl0ZXJhdG9yIGl0ZXIgPSBuZXcgb3JnLmFwYWNoZS54cGF0aC5heGVzLk9uZVN0ZXBJdGVyYXRvckZvcndhcmQoQXhpcy5TRUxGKTsKLSAgICBpdGVyLnNldFJvb3Qobm9kZSwgdGhpcyk7Ci0gICAgcmV0dXJuIGl0ZXI7Ci0gICAgLy8gcmV0dXJuIG1fZHRtTWFuYWdlci5jcmVhdGVEVE1JdGVyYXRvcihub2RlKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWFBhdGhDb250ZXh0IGluc3RhbmNlLgotICAgKi8KLSAgcHVibGljIFhQYXRoQ29udGV4dCgpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVyc1ttX3ByZWZpeFJlc29sdmVyc1RvcCsrXSA9IG51bGw7Ci0gICAgbV9jdXJyZW50Tm9kZXNbbV9jdXJyZW50Tm9kZXNGaXJzdEZyZWUrK10gPSBEVE0uTlVMTDsKLSAgICBtX2N1cnJlbnROb2Rlc1ttX2N1cnJlbnRFeHByZXNzaW9uTm9kZXNGaXJzdEZyZWUrK10gPSBEVE0uTlVMTDsKLSAgICBtX3NheExvY2F0aW9uc1ttX3NheExvY2F0aW9uc1RvcCsrXSA9IG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoQ29udGV4dCBpbnN0YW5jZS4KLSAgICogQHBhcmFtIG93bmVyIFZhbHVlIHRoYXQgY2FuIGJlIHJldHJpZXZlZCB2aWEgdGhlIGdldE93bmVyT2JqZWN0KCkgbWV0aG9kLgotICAgKiBAc2VlICNnZXRPd25lck9iamVjdAotICAgKi8KLSAgcHVibGljIFhQYXRoQ29udGV4dChPYmplY3Qgb3duZXIpCi0gIHsKLSAgICBtX293bmVyID0gb3duZXI7Ci0gICAgdHJ5IHsKLSAgICAgIG1fb3duZXJHZXRFcnJvckxpc3RlbmVyID0gbV9vd25lci5nZXRDbGFzcygpLmdldE1ldGhvZCgiZ2V0RXJyb3JMaXN0ZW5lciIsIG5ldyBDbGFzc1tdIHt9KTsKLSAgICB9Ci0gICAgY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBuc21lKSB7fQotICAgIG1fcHJlZml4UmVzb2x2ZXJzW21fcHJlZml4UmVzb2x2ZXJzVG9wKytdID0gbnVsbDsKLSAgICBtX2N1cnJlbnROb2Rlc1ttX2N1cnJlbnROb2Rlc0ZpcnN0RnJlZSsrXSA9IERUTS5OVUxMOwotICAgIG1fY3VycmVudE5vZGVzW21fY3VycmVudEV4cHJlc3Npb25Ob2Rlc0ZpcnN0RnJlZSsrXSA9IERUTS5OVUxMOwotICAgIG1fc2F4TG9jYXRpb25zW21fc2F4TG9jYXRpb25zVG9wKytdID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXNldCBmb3IgbmV3IHJ1bi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCkKLSAgewotICAgIG1fZHRtTWFuYWdlciA9IERUTU1hbmFnZXIubmV3SW5zdGFuY2UoCi0gICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhNTFN0cmluZ0ZhY3RvcnlJbXBsLmdldEZhY3RvcnkoKSk7Ci0gIH0KLQotICAvKiogVGhlIGN1cnJlbnQgc3R5bGVzaGVldCBsb2NhdG9yLiAqLwotICBTb3VyY2VMb2NhdG9yW10gbV9zYXhMb2NhdGlvbnMgPSBuZXcgU291cmNlTG9jYXRvcltSRUNVUlNJT05MSU1JVF07Ci0gIGludCBtX3NheExvY2F0aW9uc1RvcCA9IDA7Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBsb2NhdGVyIGluIHRoZSBzdHlsZXNoZWV0LgotICAgKgotICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIGxvY2F0aW9uIHdpdGhpbiB0aGUgc3R5bGVzaGVldC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNBWExvY2F0b3IoU291cmNlTG9jYXRvciBsb2NhdGlvbikKLSAgewotICAgIG1fc2F4TG9jYXRpb25zW21fc2F4TG9jYXRpb25zVG9wLTFdID0gbG9jYXRpb247Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgbG9jYXRlciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSBsb2NhdGlvbiB3aXRoaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBwdXNoU0FYTG9jYXRvcihTb3VyY2VMb2NhdG9yIGxvY2F0aW9uKQotICB7Ci0gICAgbV9zYXhMb2NhdGlvbnNbbV9zYXhMb2NhdGlvbnNUb3ArK10gPSBsb2NhdGlvbjsKLSAgfQotICAKLSAgLyoqCi0gICAqIFB1c2ggYSBzbG90IG9uIHRoZSBsb2NhdGlvbnMgc3RhY2sgc28gdGhhdCBzZXRTQVhMb2NhdG9yIGNhbiBiZSAKLSAgICogcmVwZWF0ZWRseSBjYWxsZWQuCi0gICAqCi0gICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgbG9jYXRpb24gd2l0aGluIHRoZSBzdHlsZXNoZWV0LgotICAgKi8KLSAgcHVibGljIHZvaWQgcHVzaFNBWExvY2F0b3JOdWxsKCkKLSAgewotICAgIG1fc2F4TG9jYXRpb25zVG9wKys7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgbG9jYXRlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHBvcFNBWExvY2F0b3IoKQotICB7Ci0gICAgbV9zYXhMb2NhdGlvbnNUb3AtLTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgbG9jYXRlciBpbiB0aGUgc3R5bGVzaGVldC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbG9jYXRpb24gd2l0aGluIHRoZSBzdHlsZXNoZWV0LCBvciBudWxsIGlmIG5vdCBrbm93bi4KLSAgICovCi0gIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldFNBWExvY2F0b3IoKQotICB7Ci0gICAgcmV0dXJuIG1fc2F4TG9jYXRpb25zW21fc2F4TG9jYXRpb25zVG9wLTFdOwotICB9Ci0KLSAgLyoqIFRoZSBvd25lciBjb250ZXh0IG9mIHRoaXMgWFBhdGhDb250ZXh0LiAgSW4gdGhlIGNhc2Ugb2YgWFNMVCwgdGhpcyB3aWxsIGJlIGEKLSAgICogIFRyYW5zZm9ybWVyIG9iamVjdC4KLSAgICovCi0gIHByaXZhdGUgT2JqZWN0IG1fb3duZXI7Ci0KLSAgLyoqIFRoZSBvd25lciBjb250ZXh0IG9mIHRoaXMgWFBhdGhDb250ZXh0LiAgSW4gdGhlIGNhc2Ugb2YgWFNMVCwgdGhpcyB3aWxsIGJlIGEKLSAgICogIFRyYW5zZm9ybWVyIG9iamVjdC4KLSAgICovCi0gIHByaXZhdGUgTWV0aG9kIG1fb3duZXJHZXRFcnJvckxpc3RlbmVyOwotCi0gIC8qKgotICAgKiBHZXQgdGhlICJvd25lciIgY29udGV4dCBvZiB0aGlzIGNvbnRleHQsIHdoaWNoIHNob3VsZCBiZSwKLSAgICogaW4gdGhlIGNhc2Ugb2YgWFNMVCwgdGhlIFRyYW5zZm9ybWVyIG9iamVjdC4gIFRoaXMgaXMgbmVlZGVkCi0gICAqIHNvIHRoYXQgWFNMVCBmdW5jdGlvbnMgY2FuIGdldCB0aGUgVHJhbnNmb3JtZXIuCi0gICAqIEByZXR1cm4gVGhlIG93bmVyIG9iamVjdCBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGdldE93bmVyT2JqZWN0KCkKLSAgewotICAgIHJldHVybiBtX293bmVyOwotICB9Ci0KLSAgLy8gPT09PT09PT09PT09PT09PSBleHRlbnNpb25zVGFibGUgPT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBUaGUgdGFibGUgb2YgRXh0ZW5zaW9uIEhhbmRsZXJzLgotICAgKi8KLSAgcHJpdmF0ZSBFeHRlbnNpb25zVGFibGUgbV9leHRlbnNpb25zVGFibGUgPSBuZXcgRXh0ZW5zaW9uc1RhYmxlKCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZXh0ZW5zaW9ucyB0YWJsZSBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGV4dGVuc2lvbnMgdGFibGUuCi0gICAqLwotICBwdWJsaWMgRXh0ZW5zaW9uc1RhYmxlIGdldEV4dGVuc2lvbnNUYWJsZSgpCi0gIHsKLSAgICByZXR1cm4gbV9leHRlbnNpb25zVGFibGU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBleHRlbnNpb25zIHRhYmxlIG9iamVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHRhYmxlIFRoZSBleHRlbnNpb25zIHRhYmxlIG9iamVjdC4KLSAgICovCi0gIHZvaWQgc2V0RXh0ZW5zaW9uc1RhYmxlKEV4dGVuc2lvbnNUYWJsZSB0YWJsZSkKLSAgewotICAgIG1fZXh0ZW5zaW9uc1RhYmxlID0gdGFibGU7Ci0gIH0KLQotICAvLyA9PT09PT09PT09PT09PT09IFZhclN0YWNrID09PT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogVGhlIHN0YWNrIG9mIFZhcmlhYmxlIHN0YWNrcy4gIEEgVmFyaWFibGVTdGFjayB3aWxsIGJlCi0gICAqIHB1c2hlZCBvbnRvIHRoaXMgc3RhY2sgZm9yIGVhY2ggdGVtcGxhdGUgaW52b2NhdGlvbi4KLSAgICovCi0gIHByaXZhdGUgVmFyaWFibGVTdGFjayBtX3ZhcmlhYmxlU3RhY2tzID0gbmV3IFZhcmlhYmxlU3RhY2soKTsKLQotICAvKioKLSAgICogR2V0IHRoZSB2YXJpYWJsZSBzdGFjaywgd2hpY2ggaXMgaW4gY2hhcmdlIG9mIHZhcmlhYmxlcyBhbmQKLSAgICogcGFyYW1ldGVycy4KLSAgICoKLSAgICogQHJldHVybiB0aGUgdmFyaWFibGUgc3RhY2ssIHdoaWNoIHNob3VsZCBub3QgYmUgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBWYXJpYWJsZVN0YWNrIGdldFZhclN0YWNrKCkKLSAgewotICAgIHJldHVybiBtX3ZhcmlhYmxlU3RhY2tzOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgdmFyaWFibGUgc3RhY2ssIHdoaWNoIGlzIGluIGNoYXJnZSBvZiB2YXJpYWJsZXMgYW5kCi0gICAqIHBhcmFtZXRlcnMuCi0gICAqCi0gICAqIEBwYXJhbSB2YXJTdGFjayBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHZhcmlhYmxlIHN0YWNrLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgc2V0VmFyU3RhY2soVmFyaWFibGVTdGFjayB2YXJTdGFjaykKLSAgewotICAgIG1fdmFyaWFibGVTdGFja3MgPSB2YXJTdGFjazsKLSAgfQotCi0gIC8vID09PT09PT09PT09PT09PT0gU291cmNlVHJlZU1hbmFnZXIgPT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBUaGUgc291cmNlIHRyZWUgbWFuYWdlciwgd2hpY2ggYXNzb2NpYXRlcyBTb3VyY2Ugb2JqZWN0cyB0byBzb3VyY2UgCi0gICAqICB0cmVlIG5vZGVzLiAqLwotICBwcml2YXRlIFNvdXJjZVRyZWVNYW5hZ2VyIG1fc291cmNlVHJlZU1hbmFnZXIgPSBuZXcgU291cmNlVHJlZU1hbmFnZXIoKTsKLQotICAvKioKLSAgICogR2V0IHRoZSBTb3VyY2VUcmVlTWFuYWdlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgU291cmNlVHJlZU1hbmFnZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgU291cmNlVHJlZU1hbmFnZXIgZ2V0U291cmNlVHJlZU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fc291cmNlVHJlZU1hbmFnZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBTb3VyY2VUcmVlTWFuYWdlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHBhcmFtIG1nciB0aGUgU291cmNlVHJlZU1hbmFnZXIgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgCi0gICAqICAgICAgICBleGVjdXRpb24gY29udGV4dC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNvdXJjZVRyZWVNYW5hZ2VyKFNvdXJjZVRyZWVNYW5hZ2VyIG1ncikKLSAgewotICAgIG1fc291cmNlVHJlZU1hbmFnZXIgPSBtZ3I7Ci0gIH0KLSAgCi0gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogVGhlIEVycm9yTGlzdGVuZXIgd2hlcmUgZXJyb3JzIGFuZCB3YXJuaW5ncyBhcmUgdG8gYmUgcmVwb3J0ZWQuICAgKi8KLSAgcHJpdmF0ZSBFcnJvckxpc3RlbmVyIG1fZXJyb3JMaXN0ZW5lcjsKLQotICAvKiogQSBkZWZhdWx0IEVycm9yTGlzdGVuZXIgaW4gY2FzZSBvdXIgbV9lcnJvckxpc3RlbmVyIHdhcyBub3Qgc3BlY2lmaWVkIGFuZCBvdXIKLSAgICogIG93bmVyIGVpdGhlciBkb2VzIG5vdCBoYXZlIGFuIEVycm9yTGlzdGVuZXIgb3IgaGFzIGEgbnVsbCBvbmUuCi0gICAqLwotICBwcml2YXRlIEVycm9yTGlzdGVuZXIgbV9kZWZhdWx0RXJyb3JMaXN0ZW5lcjsKLQotICAvKioKLSAgICogR2V0IHRoZSBFcnJvckxpc3RlbmVyIHdoZXJlIGVycm9ycyBhbmQgd2FybmluZ3MgYXJlIHRvIGJlIHJlcG9ydGVkLgotICAgKgotICAgKiBAcmV0dXJuIEEgbm9uLW51bGwgRXJyb3JMaXN0ZW5lciByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgZmluYWwgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9lcnJvckxpc3RlbmVyKQotICAgICAgICByZXR1cm4gbV9lcnJvckxpc3RlbmVyOwotCi0gICAgRXJyb3JMaXN0ZW5lciByZXR2YWwgPSBudWxsOwotCi0gICAgdHJ5IHsKLSAgICAgIGlmIChudWxsICE9IG1fb3duZXJHZXRFcnJvckxpc3RlbmVyKQotICAgICAgICByZXR2YWwgPSAoRXJyb3JMaXN0ZW5lcikgbV9vd25lckdldEVycm9yTGlzdGVuZXIuaW52b2tlKG1fb3duZXIsIG5ldyBPYmplY3RbXSB7fSk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkge30KLQotICAgIGlmIChudWxsID09IHJldHZhbCkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX2RlZmF1bHRFcnJvckxpc3RlbmVyKSAKLSAgICAgICAgbV9kZWZhdWx0RXJyb3JMaXN0ZW5lciA9IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5EZWZhdWx0RXJyb3JIYW5kbGVyKCk7Ci0gICAgICByZXR2YWwgPSBtX2RlZmF1bHRFcnJvckxpc3RlbmVyOwotICAgIH0KLQotICAgIHJldHVybiByZXR2YWw7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBFcnJvckxpc3RlbmVyIHdoZXJlIGVycm9ycyBhbmQgd2FybmluZ3MgYXJlIHRvIGJlIHJlcG9ydGVkLgotICAgKgotICAgKiBAcGFyYW0gbGlzdGVuZXIgQSBub24tbnVsbCBFcnJvckxpc3RlbmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcikgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGxpc3RlbmVyID09IG51bGwpIAotICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9OVUxMX0VSUk9SX0hBTkRMRVIsIG51bGwpKTsgLy8iTnVsbCBlcnJvciBoYW5kbGVyIik7Ci0gICAgbV9lcnJvckxpc3RlbmVyID0gbGlzdGVuZXI7Ci0gIH0KLQotCi0gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogVGhlIFRyQVggVVJJIFJlc29sdmVyIGZvciByZXNvbHZpbmcgVVJJcyBmcm9tIHRoZSBkb2N1bWVudCguLi4pCi0gICAqICBmdW5jdGlvbiB0byBzb3VyY2UgdHJlZSBub2Rlcy4gICovCi0gIHByaXZhdGUgVVJJUmVzb2x2ZXIgbV91cmlSZXNvbHZlcjsKLQotICAvKioKLSAgICogR2V0IHRoZSBVUklSZXNvbHZlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBhIFVSSSByZXNvbHZlciwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgZmluYWwgVVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fdXJpUmVzb2x2ZXI7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBVUklSZXNvbHZlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHBhcmFtIHJlc29sdmVyIHRoZSBVUklSZXNvbHZlciB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcyAKLSAgICogICAgICAgIGV4ZWN1dGlvbiBjb250ZXh0LCBtYXkgYmUgbnVsbCB0byBjbGVhciBhbiBhbHJlYWR5IHNldCByZXNvbHZlci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKQotICB7Ci0gICAgbV91cmlSZXNvbHZlciA9IHJlc29sdmVyOwotICB9Ci0KLSAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKiBUaGUgcmVhZGVyIG9mIHRoZSBwcmltYXJ5IHNvdXJjZSB0cmVlLiAgICAqLwotICBwdWJsaWMgWE1MUmVhZGVyIG1fcHJpbWFyeVJlYWRlcjsKLQotICAvKioKLSAgICogR2V0IHByaW1hcnkgWE1MUmVhZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZWFkZXIgb2YgdGhlIHByaW1hcnkgc291cmNlIHRyZWUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgWE1MUmVhZGVyIGdldFByaW1hcnlSZWFkZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJpbWFyeVJlYWRlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgcHJpbWFyeSBYTUxSZWFkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEBwYXJhbSByZWFkZXIgVGhlIHJlYWRlciBvZiB0aGUgcHJpbWFyeSBzb3VyY2UgdHJlZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByaW1hcnlSZWFkZXIoWE1MUmVhZGVyIHJlYWRlcikKLSAgewotICAgIG1fcHJpbWFyeVJlYWRlciA9IHJlYWRlcjsKLSAgfQotCi0gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotCi0gIC8qKiBNaXNuYW1lZCBzdHJpbmcgbWFuYWdlciBmb3IgWFBhdGggbWVzc2FnZXMuICAqLwotICBwcml2YXRlIHN0YXRpYyBYU0xNZXNzYWdlcyBtX1hTTE1lc3NhZ2VzID0gbmV3IFhTTE1lc3NhZ2VzKCk7Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gYXNzZXJ0aW9uIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gYiAgSWYgZmFsc2UsIGEgVHJhbnNmb3JtZXJFeGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCi0gICAqIEBwYXJhbSBtc2cgVGhlIGFzc2VydGlvbiBtZXNzYWdlLCB3aGljaCBzaG91bGQgYmUgaW5mb3JtYXRpdmUuCi0gICAqIAotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYiBpcyBmYWxzZS4KLSAgICovCi0gIHByaXZhdGUgdm9pZCBhc3NlcnRpb24oYm9vbGVhbiBiLCBTdHJpbmcgbXNnKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBFcnJvckxpc3RlbmVyIGVycm9ySGFuZGxlciA9IGdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIGlmIChlcnJvckhhbmRsZXIgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBlcnJvckhhbmRsZXIuZmF0YWxFcnJvcigKLSAgICAgICAgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKAotICAgICAgICAgIG1fWFNMTWVzc2FnZXMuY3JlYXRlTWVzc2FnZSgKLSAgICAgICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBtc2cgfSksIChTQVhTb3VyY2VMb2NhdG9yKXRoaXMuZ2V0U0FYTG9jYXRvcigpKSk7Ci0gICAgfQotICB9Ci0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIFNFQ1RJT046IEV4ZWN1dGlvbiBjb250ZXh0IHN0YXRlIHRyYWNraW5nCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAKLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHJpdmF0ZSBTdGFjayBtX2NvbnRleHROb2RlTGlzdHMgPSBuZXcgU3RhY2soKTsKLSAgCi0gIHB1YmxpYyBTdGFjayBnZXRDb250ZXh0Tm9kZUxpc3RzU3RhY2soKSB7IHJldHVybiBtX2NvbnRleHROb2RlTGlzdHM7IH0KLSAgcHVibGljIHZvaWQgc2V0Q29udGV4dE5vZGVMaXN0c1N0YWNrKFN0YWNrIHMpIHsgbV9jb250ZXh0Tm9kZUxpc3RzID0gczsgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZS1saXN0Ij5jdXJyZW50IG5vZGUgbGlzdDwvYT4sCi0gICAqIGFsc28gcmVmZXJlZCB0byBoZXJlIGFzIGEgPHRlcm0+Y29udGV4dCBub2RlIGxpc3Q8L3Rlcm0+LgotICAgKi8KLSAgcHVibGljIGZpbmFsIERUTUl0ZXJhdG9yIGdldENvbnRleHROb2RlTGlzdCgpCi0gIHsKLQotICAgIGlmIChtX2NvbnRleHROb2RlTGlzdHMuc2l6ZSgpID4gMCkKLSAgICAgIHJldHVybiAoRFRNSXRlcmF0b3IpIG1fY29udGV4dE5vZGVMaXN0cy5wZWVrKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIFNldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgbGlzdC4KLSAgICoKLSAgICogQHBhcmFtIG5sIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZS1saXN0Ij5jdXJyZW50IG5vZGUgbGlzdDwvYT4sCi0gICAqIGFsc28gcmVmZXJlZCB0byBoZXJlIGFzIGEgPHRlcm0+Y29udGV4dCBub2RlIGxpc3Q8L3Rlcm0+LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcHVzaENvbnRleHROb2RlTGlzdChEVE1JdGVyYXRvciBubCkKLSAgewotICAgIG1fY29udGV4dE5vZGVMaXN0cy5wdXNoKG5sKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogUG9wIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wQ29udGV4dE5vZGVMaXN0KCkKLSAgewotICAgIG1fY29udGV4dE5vZGVMaXN0cy5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgYW1tb3VudCB0byB1c2UgZm9yIHN0YWNrcyB0aGF0IHJlY29yZCBpbmZvcm1hdGlvbiBkdXJpbmcgdGhlIAotICAgKiByZWN1cnNpdmUgZXhlY3V0aW9uLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVDVVJTSU9OTElNSVQgPSAoMTAyNCo0KTsKLQotICAvKiogVGhlIHN0YWNrIG9mIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+IG9iamVjdHMuCi0gICAqICBOb3QgdG8gYmUgY29uZnVzZWQgd2l0aCB0aGUgY3VycmVudCBub2RlIGxpc3QuICAlUkVWSUVXJSBOb3RlIHRoYXQgdGhlcmUgCi0gICAqICBhcmUgbm8gYm91bmRzIGNoZWNrIGFuZCByZXNpemUgZm9yIHRoaXMgc3RhY2ssIHNvIGlmIGl0IGlzIGJsb3duLCBpdCdzIGFsbCAKLSAgICogIG92ZXIuICAqLwotICBwcml2YXRlIGludCBtX2N1cnJlbnROb2Rlc1tdID0gbmV3IGludFtSRUNVUlNJT05MSU1JVF07Ci0gIHByb3RlY3RlZCBpbnQgbV9jdXJyZW50Tm9kZXNGaXJzdEZyZWUgPSAwOwotICAgCi0vLyAgcHJpdmF0ZSBOb2RlVmVjdG9yIG1fY3VycmVudE5vZGVzID0gbmV3IE5vZGVWZWN0b3IoKTsKLSAgCi0gIHB1YmxpYyBpbnRbXSBnZXRDdXJyZW50Tm9kZVN0YWNrKCkge3JldHVybiBtX2N1cnJlbnROb2RlczsgfQotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50Tm9kZVN0YWNrKGludFtdIG52KSB7IG1fY3VycmVudE5vZGVzID0gbnY7IH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUiPmN1cnJlbnQgbm9kZTwvYT4uCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEN1cnJlbnROb2RlKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnROb2Rlc1ttX2N1cnJlbnROb2Rlc0ZpcnN0RnJlZS0xXTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgYW5kIGV4cHJlc3Npb24gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIGNuIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBub2RlPC9hPi4KLSAgICogQHBhcmFtIGVuIHRoZSBzdWItZXhwcmVzc2lvbiBjb250ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKGludCBjbiwgaW50IGVuKQotICB7Ci0gICAgbV9jdXJyZW50Tm9kZXNbbV9jdXJyZW50Tm9kZXNGaXJzdEZyZWUrK10gPSBjbjsKLSAgICBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXNbbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzRmlyc3RGcmVlKytdID0gY247Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbigpCi0gIHsKLSAgICBtX2N1cnJlbnROb2Rlc0ZpcnN0RnJlZS0tOwotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlc0ZpcnN0RnJlZS0tOwotICB9Ci0gIAotICAvKioKLSAgICogUHVzaCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUsIGV4cHJlc3Npb24gbm9kZSwgYW5kIHByZWZpeCByZXNvbHZlci4KLSAgICoKLSAgICogQHBhcmFtIGNuIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBub2RlPC9hPi4KLSAgICogQHBhcmFtIGVuIHRoZSBzdWItZXhwcmVzc2lvbiBjb250ZXh0IG5vZGUuCi0gICAqIEBwYXJhbSBuYyB0aGUgbmFtZXNwYWNlIGNvbnRleHQgKHByZWZpeCByZXNvbHZlci4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hFeHByZXNzaW9uU3RhdGUoaW50IGNuLCBpbnQgZW4sIFByZWZpeFJlc29sdmVyIG5jKQotICB7Ci0gICAgbV9jdXJyZW50Tm9kZXNbbV9jdXJyZW50Tm9kZXNGaXJzdEZyZWUrK10gPSBjbjsKLSAgICBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXNbbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzRmlyc3RGcmVlKytdID0gY247Ci0gICAgbV9wcmVmaXhSZXNvbHZlcnNbbV9wcmVmaXhSZXNvbHZlcnNUb3ArK10gPSBuYzsKLSAgfQotICAKLSAgLyoqCi0gICAqIFBvcCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUsIGV4cHJlc3Npb24gbm9kZSwgYW5kIHByZWZpeCByZXNvbHZlci4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcEV4cHJlc3Npb25TdGF0ZSgpCi0gIHsKLSAgICBtX2N1cnJlbnROb2Rlc0ZpcnN0RnJlZS0tOwotICAgIG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlc0ZpcnN0RnJlZS0tOwotICAgIG1fcHJlZml4UmVzb2x2ZXJzVG9wLS07Ci0gIH0KLQotCi0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBuIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZSI+Y3VycmVudCBub2RlPC9hPi4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hDdXJyZW50Tm9kZShpbnQgbikKLSAgewotICAgIG1fY3VycmVudE5vZGVzW21fY3VycmVudE5vZGVzRmlyc3RGcmVlKytdID0gbjsKLSAgfQotICAKLSAgcHVibGljIGludCBnZXRDdXJyZW50Tm9kZUZpcnN0RnJlZSgpCi0gIHsKLSAgICByZXR1cm4gbV9jdXJyZW50Tm9kZXNGaXJzdEZyZWU7Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHBvcEN1cnJlbnROb2RlKCkKLSAgewotICAgIG1fY3VycmVudE5vZGVzRmlyc3RGcmVlLS07Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgcHJlZGljYXRlIHJvb3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoUHJlZGljYXRlUm9vdChpbnQgbikKLSAgewotICAgIG1fcHJlZGljYXRlUm9vdHMucHVzaChuKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgcHJlZGljYXRlIHJvb3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwb3BQcmVkaWNhdGVSb290KCkKLSAgewotICAgIG1fcHJlZGljYXRlUm9vdHMucG9wUXVpY2soKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgcHJlZGljYXRlIHJvb3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldFByZWRpY2F0ZVJvb3QoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZGljYXRlUm9vdHMucGVlcE9yTnVsbCgpOwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IGxvY2F0aW9uIHBhdGggaXRlcmF0b3Igcm9vdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hJdGVyYXRvclJvb3QoaW50IG4pCi0gIHsKLSAgICBtX2l0ZXJhdG9yUm9vdHMucHVzaChuKTsKLSAgfQotCi0gIC8qKgotICAgKiBQb3AgdGhlIGN1cnJlbnQgbG9jYXRpb24gcGF0aCBpdGVyYXRvciByb290LgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wSXRlcmF0b3JSb290KCkKLSAgewotICAgIG1faXRlcmF0b3JSb290cy5wb3BRdWljaygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yIHJvb3QuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEl0ZXJhdG9yUm9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9pdGVyYXRvclJvb3RzLnBlZXBPck51bGwoKTsKLSAgfQotICAKLSAgLyoqIEEgc3RhY2sgb2YgdGhlIGN1cnJlbnQgc3ViLWV4cHJlc3Npb24gbm9kZXMuICAqLwotICBwcml2YXRlIE5vZGVWZWN0b3IgbV9pdGVyYXRvclJvb3RzID0gbmV3IE5vZGVWZWN0b3IoKTsKLQotICAKLSAgLyoqIEEgc3RhY2sgb2YgdGhlIGN1cnJlbnQgc3ViLWV4cHJlc3Npb24gbm9kZXMuICAqLwotICBwcml2YXRlIE5vZGVWZWN0b3IgbV9wcmVkaWNhdGVSb290cyA9IG5ldyBOb2RlVmVjdG9yKCk7Ci0KLSAgLyoqIEEgc3RhY2sgb2YgdGhlIGN1cnJlbnQgc3ViLWV4cHJlc3Npb24gbm9kZXMuICAqLwotICBwcml2YXRlIGludCBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXNbXSA9IG5ldyBpbnRbUkVDVVJTSU9OTElNSVRdOwotICBwcm90ZWN0ZWQgaW50IG1fY3VycmVudEV4cHJlc3Npb25Ob2Rlc0ZpcnN0RnJlZSA9IDA7Ci0gICAgIAotICBwdWJsaWMgaW50W10gZ2V0Q3VycmVudEV4cHJlc3Npb25Ob2RlU3RhY2soKSB7IHJldHVybiBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXM7IH0KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudEV4cHJlc3Npb25Ob2RlU3RhY2soaW50W10gbnYpIHsgbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzID0gbnY7IH0KLSAgcHVibGljIGludCBnZXRDdXJyZW50RXhwcmVzc2lvbk5vZGVzRmlyc3RGcmVlKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXNGaXJzdEZyZWU7Ci0gIH0KLQotICAKLSAgcHJpdmF0ZSBJbnRTdGFjayBtX3ByZWRpY2F0ZVBvcyA9IG5ldyBJbnRTdGFjaygpOwotICAKLSAgcHVibGljIGZpbmFsIGludCBnZXRQcmVkaWNhdGVQb3MoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZGljYXRlUG9zLnBlZWsoKTsKLSAgfQotCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hQcmVkaWNhdGVQb3MoaW50IG4pCi0gIHsKLSAgICBtX3ByZWRpY2F0ZVBvcy5wdXNoKG4pOwotICB9Ci0KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wUHJlZGljYXRlUG9zKCkKLSAgewotICAgIG1fcHJlZGljYXRlUG9zLnBvcCgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgdGhlIGV4cHJlc3Npb24ncyBjb250ZXh0IChpLmUuIGZvciBjdXJyZW50KCkgc3VwcG9ydCkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc3ViLWV4cHJlc3Npb24gbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Q3VycmVudEV4cHJlc3Npb25Ob2RlKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnRFeHByZXNzaW9uTm9kZXNbbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzRmlyc3RGcmVlLTFdOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBub2RlIHRoYXQgaXMgdGhlIGV4cHJlc3Npb24ncyBjb250ZXh0IChpLmUuIGZvciBjdXJyZW50KCkgc3VwcG9ydCkuCi0gICAqCi0gICAqIEBwYXJhbSBuIFRoZSBzdWItZXhwcmVzc2lvbiBub2RlIHRvIGJlIGN1cnJlbnQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoQ3VycmVudEV4cHJlc3Npb25Ob2RlKGludCBuKQotICB7Ci0gICAgbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzW21fY3VycmVudEV4cHJlc3Npb25Ob2Rlc0ZpcnN0RnJlZSsrXSA9IG47Ci0gIH0KLQotICAvKioKLSAgICogUG9wIHRoZSBjdXJyZW50IG5vZGUgdGhhdCBpcyB0aGUgZXhwcmVzc2lvbidzIGNvbnRleHQgCi0gICAqIChpLmUuIGZvciBjdXJyZW50KCkgc3VwcG9ydCkuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwb3BDdXJyZW50RXhwcmVzc2lvbk5vZGUoKQotICB7Ci0gICAgbV9jdXJyZW50RXhwcmVzc2lvbk5vZGVzRmlyc3RGcmVlLS07Ci0gIH0KLSAgCi0gIHByaXZhdGUgUHJlZml4UmVzb2x2ZXJbXSBtX3ByZWZpeFJlc29sdmVycyAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgUHJlZml4UmVzb2x2ZXJbUkVDVVJTSU9OTElNSVRdOwotICBwcml2YXRlIGludCBtX3ByZWZpeFJlc29sdmVyc1RvcCA9IDA7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhlIHhwYXRoLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHByZWZpeCByZXNvbHZlciBmb3IgcmVzb2x2aW5nIHByZWZpeGVzIHRvIAotICAgKiAgICAgICAgIG5hbWVzcGFjZSBVUkxzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIFByZWZpeFJlc29sdmVyIGdldE5hbWVzcGFjZUNvbnRleHQoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZml4UmVzb2x2ZXJzW21fcHJlZml4UmVzb2x2ZXJzVG9wLTFdOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhlIHhwYXRoLgotICAgKgotICAgKiBAcGFyYW0gcHIgdGhlIHByZWZpeCByZXNvbHZlciB0byBiZSB1c2VkIGZvciByZXNvbHZpbmcgcHJlZml4ZXMgdG8gCi0gICAqICAgICAgICAgbmFtZXNwYWNlIFVSTHMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXROYW1lc3BhY2VDb250ZXh0KFByZWZpeFJlc29sdmVyIHByKQotICB7Ci0gICAgbV9wcmVmaXhSZXNvbHZlcnNbbV9wcmVmaXhSZXNvbHZlcnNUb3AtMV0gPSBwcjsKLSAgfQotCi0gIC8qKgotICAgKiBQdXNoIGEgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhlIHhwYXRoLgotICAgKgotICAgKiBAcGFyYW0gcHIgdGhlIHByZWZpeCByZXNvbHZlciB0byBiZSB1c2VkIGZvciByZXNvbHZpbmcgcHJlZml4ZXMgdG8gCi0gICAqICAgICAgICAgbmFtZXNwYWNlIFVSTHMuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoTmFtZXNwYWNlQ29udGV4dChQcmVmaXhSZXNvbHZlciBwcikKLSAgewotICAgIG1fcHJlZml4UmVzb2x2ZXJzW21fcHJlZml4UmVzb2x2ZXJzVG9wKytdID0gcHI7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBKdXN0IGluY3JlbWVudCB0aGUgbmFtZXNwYWNlIGNvbnRlc3Qgc3RhY2ssIHNvIHRoYXQgc2V0TmFtZXNwYWNlQ29udGV4dAotICAgKiBjYW4gYmUgdXNlZCBvbiB0aGUgc2xvdC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHB1c2hOYW1lc3BhY2VDb250ZXh0TnVsbCgpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVyc1RvcCsrOwotICB9Ci0KLSAgLyoqCi0gICAqIFBvcCB0aGUgY3VycmVudCBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhlIHhwYXRoLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wTmFtZXNwYWNlQ29udGV4dCgpCi0gIHsKLSAgICBtX3ByZWZpeFJlc29sdmVyc1RvcC0tOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gIC8vIFNFQ1RJT046IEN1cnJlbnQgVHJlZVdhbGtlciBjb250ZXh0cyAoZm9yIGludGVybmFsIHVzZSkKLSAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFN0YWNrIG9mIEF4ZXNJdGVyYXRvcnMuCi0gICAqLwotICBwcml2YXRlIFN0YWNrIG1fYXhlc0l0ZXJhdG9yU3RhY2sgPSBuZXcgU3RhY2soKTsKLSAgCi0gIHB1YmxpYyBTdGFjayBnZXRBeGVzSXRlcmF0b3JTdGFja1N0YWNrcygpIHsgcmV0dXJuIG1fYXhlc0l0ZXJhdG9yU3RhY2s7IH0KLSAgcHVibGljIHZvaWQgc2V0QXhlc0l0ZXJhdG9yU3RhY2tTdGFja3MoU3RhY2sgcykgeyBtX2F4ZXNJdGVyYXRvclN0YWNrID0gczsgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogUHVzaCBhIFRyZWVXYWxrZXIgb24gdGhlIHN0YWNrLgotICAgKgotICAgKiBAcGFyYW0gaXRlciBBIHN1Yi1jb250ZXh0IEF4ZXNXYWxrZXIuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBwdXNoU3ViQ29udGV4dExpc3QoU3ViQ29udGV4dExpc3QgaXRlcikKLSAgewotICAgIG1fYXhlc0l0ZXJhdG9yU3RhY2sucHVzaChpdGVyKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogUG9wIHRoZSBsYXN0IHB1c2hlZCBheGVzIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgcG9wU3ViQ29udGV4dExpc3QoKQotICB7Ci0gICAgbV9heGVzSXRlcmF0b3JTdGFjay5wb3AoKTsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAgICogR2V0IHRoZSBjdXJyZW50IGF4ZXMgaXRlcmF0b3IsIG9yIHJldHVybiBudWxsIGlmIG5vbmUuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN1Yi1jb250ZXh0IG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBTdWJDb250ZXh0TGlzdCBnZXRTdWJDb250ZXh0TGlzdCgpCi0gIHsKLSAgICByZXR1cm4gbV9heGVzSXRlcmF0b3JTdGFjay5pc0VtcHR5KCkKLSAgICAgICAgICAgPyBudWxsIDogKFN1YkNvbnRleHRMaXN0KSBtX2F4ZXNJdGVyYXRvclN0YWNrLnBlZWsoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBHZXQgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlLWxpc3QiPmN1cnJlbnQgbm9kZSBsaXN0PC9hPiAKLSAgICogYXMgZGVmaW5lZCBieSB0aGUgWFNMVCBzcGVjLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2R0LWN1cnJlbnQtbm9kZS1saXN0Ij5jdXJyZW50IG5vZGUgbGlzdDwvYT4uCi0gICAqLwotICBwdWJsaWMgb3JnLmFwYWNoZS54cGF0aC5heGVzLkxvY1BhdGhJdGVyYXRvciBnZXRDdXJyZW50Tm9kZUxpc3QoKQotICB7Ci0gICAgZm9yIChpbnQgaSA9IG1fYXhlc0l0ZXJhdG9yU3RhY2suc2l6ZSgpLTE7IGkgPj0gMDsgaS0tKSAKLSAgICB7Ci0gICAgICBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuUHJlZGljYXRlZE5vZGVUZXN0IGl0ZXIgCi0gICAgICAgPSAob3JnLmFwYWNoZS54cGF0aC5heGVzLlByZWRpY2F0ZWROb2RlVGVzdCltX2F4ZXNJdGVyYXRvclN0YWNrLmVsZW1lbnRBdChpKTsKLSAgICAgIG9yZy5hcGFjaGUueHBhdGguYXhlcy5Mb2NQYXRoSXRlcmF0b3IgbHBpID0gaXRlci5nZXRMb2NQYXRoSXRlcmF0b3IoKTsKLSAgICAgIGlmKGxwaS5nZXRJc1RvcExldmVsKCkpCi0gICAgICAgIHJldHVybiBscGk7Ci0gICAgfQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLQotICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgLy8gU0VDVElPTjogSW1wbGVtZW50YXRpb24gb2YgRXhwcmVzc2lvbkNvbnRleHQgaW50ZXJmYWNlCi0gIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Q29udGV4dE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIHRoaXMuZ2V0Q3VycmVudE5vZGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAqIEByZXR1cm4gQW4gaXRlcmF0b3IgZm9yIHRoZSBjdXJyZW50IGNvbnRleHQgbGlzdCwgYXMKLSAgICogZGVmaW5lZCBpbiBYU0xULgotICAgKi8KLSAgcHVibGljIGZpbmFsIERUTUl0ZXJhdG9yIGdldENvbnRleHROb2RlcygpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIERUTUl0ZXJhdG9yIGNubCA9IGdldENvbnRleHROb2RlTGlzdCgpOwotCi0gICAgICBpZiAobnVsbCAhPSBjbmwpCi0gICAgICAgIHJldHVybiBjbmwuY2xvbmVXaXRoUmVzZXQoKTsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIG51bGw7ICAvLyBmb3Igbm93Li4uIHRoaXMgbWlnaHQgb3VnaHQgdG8gYmUgYW4gZW1wdHkgaXRlcmF0b3IuCi0gICAgfQotICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBjbnNlKQotICAgIHsKLSAgICAgIHJldHVybiBudWxsOyAgLy8gZXJyb3IgcmVwb3J0aW5nPwotICAgIH0KLSAgfQotICAKLSAgWFBhdGhFeHByZXNzaW9uQ29udGV4dCBleHByZXNzaW9uQ29udGV4dCA9IG5ldyBYUGF0aEV4cHJlc3Npb25Db250ZXh0KCk7Ci0gIAotICAvKioKLSAgICogVGhlIHRoZSBleHByZXNzaW9uIGNvbnRleHQgZm9yIGV4dGVuc2lvbnMgZm9yIHRoaXMgY29udGV4dC4KLSAgICogCi0gICAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgRXhwcmVzc2lvbkNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbkNvbnRleHQgZ2V0RXhwcmVzc2lvbkNvbnRleHQoKQotICB7Ci0gICAgcmV0dXJuIGV4cHJlc3Npb25Db250ZXh0OwotICB9Ci0gIAotICBwdWJsaWMgY2xhc3MgWFBhdGhFeHByZXNzaW9uQ29udGV4dCBpbXBsZW1lbnRzIEV4cHJlc3Npb25Db250ZXh0Ci0gIHsKLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIFhQYXRoQ29udGV4dCBhc3NvY2lhdGVkIHdpdGggdGhpcyBYUGF0aEV4cHJlc3Npb25Db250ZXh0LgotICAgICAqIEV4dGVuc2lvbnMgc2hvdWxkIHVzZSB0aGlzIGp1ZGljaW91c2x5IGFuZCBvbmx5IHdoZW4gc3BlY2lhbCBwcm9jZXNzaW5nCi0gICAgICogcmVxdWlyZW1lbnRzIGNhbm5vdCBiZSBtZXQgYW5vdGhlciB3YXkuICBDb25zaWRlciByZXF1ZXN0aW5nIGFuIGVuaGFuY2VtZW50Ci0gICAgICogdG8gdGhlIEV4cHJlc3Npb25Db250ZXh0IGludGVyZmFjZSB0byBhdm9pZCBoYXZpbmcgdG8gY2FsbCB0aGlzIG1ldGhvZC4KLSAgICAgKiBAcmV0dXJuIHRoZSBYUGF0aENvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgWFBhdGhFeHByZXNzaW9uQ29udGV4dC4KLSAgICAgKi8KLSAgICAgcHVibGljIFhQYXRoQ29udGV4dCBnZXRYUGF0aENvbnRleHQoKQotICAgICB7Ci0gICAgICAgcmV0dXJuIFhQYXRoQ29udGV4dC50aGlzOwotICAgICB9Ci0KLSAgICAvKioKLSAgICAgKiBSZXR1cm4gdGhlIERUTU1hbmFnZXIgb2JqZWN0LiAgVGhvdWdoIFhQYXRoQ29udGV4dCBjb250ZXh0IGV4dGVuZHMgCi0gICAgICogdGhlIERUTU1hbmFnZXIsIGl0IHJlYWxseSBpcyBhIHByb3h5IGZvciB0aGUgcmVhbCBEVE1NYW5hZ2VyLiAgSWYgYSAKLSAgICAgKiBjYWxsZXIgbmVlZHMgdG8gbWFrZSBhIGxvdCBvZiBjYWxscyB0byB0aGUgRFRNTWFuYWdlciwgaXQgaXMgZmFzdGVyIAotICAgICAqIGlmIGl0IGdldHMgdGhlIHJlYWwgb25lIGZyb20gdGhpcyBmdW5jdGlvbi4KLSAgICAgKi8KLSAgICAgcHVibGljIERUTU1hbmFnZXIgZ2V0RFRNTWFuYWdlcigpCi0gICAgIHsKLSAgICAgICByZXR1cm4gbV9kdG1NYW5hZ2VyOwotICAgICB9Ci0gICAgCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICAgKi8KLSAgICBwdWJsaWMgb3JnLnczYy5kb20uTm9kZSBnZXRDb250ZXh0Tm9kZSgpCi0gICAgewotICAgICAgaW50IGNvbnRleHQgPSBnZXRDdXJyZW50Tm9kZSgpOwotICAgICAgCi0gICAgICByZXR1cm4gZ2V0RFRNKGNvbnRleHQpLmdldE5vZGUoY29udGV4dCk7Ci0gICAgfQotICAKLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGxpc3QuCi0gICAgICogQHJldHVybiBBbiBpdGVyYXRvciBmb3IgdGhlIGN1cnJlbnQgY29udGV4dCBsaXN0LCBhcwotICAgICAqIGRlZmluZWQgaW4gWFNMVC4KLSAgICAgKi8KLSAgICBwdWJsaWMgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvciBnZXRDb250ZXh0Tm9kZXMoKQotICAgIHsKLSAgICAgIHJldHVybiBuZXcgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Ob2RlSXRlcmF0b3IoZ2V0Q29udGV4dE5vZGVMaXN0KCkpOwotICAgIH0KLSAgCi0gICAgLyoqCi0gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIG5vZGUgYXMgYSBudW1iZXIuCi0gICAgICogQHBhcmFtIG4gTm9kZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSBudW1iZXIuICBNYXkgYmUgbnVsbC4KLSAgICAgKiBAcmV0dXJuIHZhbHVlIG9mIG4gYXMgYSBudW1iZXIuCi0gICAgICovCi0gICAgcHVibGljIGRvdWJsZSB0b051bWJlcihvcmcudzNjLmRvbS5Ob2RlIG4pCi0gICAgewotICAgICAgLy8gJVJFVklFVyUgWW91IGNhbid0IGdldCBtdWNoIHVnbGllciB0aGFuIHRoaXMuLi4KLSAgICAgIGludCBub2RlSGFuZGxlID0gZ2V0RFRNSGFuZGxlRnJvbU5vZGUobik7Ci0gICAgICBEVE0gZHRtID0gZ2V0RFRNKG5vZGVIYW5kbGUpOwotICAgICAgWFN0cmluZyB4b2JqID0gKFhTdHJpbmcpZHRtLmdldFN0cmluZ1ZhbHVlKG5vZGVIYW5kbGUpOwotICAgICAgcmV0dXJuIHhvYmoubnVtKCk7Ci0gICAgfQotICAKLSAgICAvKioKLSAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIGEgbm9kZSBhcyBhIHN0cmluZy4KLSAgICAgKiBAcGFyYW0gbiBOb2RlIHRvIGJlIGNvbnZlcnRlZCB0byBhIHN0cmluZy4gIE1heSBiZSBudWxsLgotICAgICAqIEByZXR1cm4gdmFsdWUgb2YgbiBhcyBhIHN0cmluZywgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG4gaXMgbnVsbC4KLSAgICAgKi8KLSAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKG9yZy53M2MuZG9tLk5vZGUgbikKLSAgICB7Ci0gICAgICAvLyAlUkVWSUVXJSBZb3UgY2FuJ3QgZ2V0IG11Y2ggdWdsaWVyIHRoYW4gdGhpcy4uLgotICAgICAgaW50IG5vZGVIYW5kbGUgPSBnZXREVE1IYW5kbGVGcm9tTm9kZShuKTsKLSAgICAgIERUTSBkdG0gPSBnZXREVE0obm9kZUhhbmRsZSk7Ci0gICAgICBYTUxTdHJpbmcgc3RyVmFsID0gZHRtLmdldFN0cmluZ1ZhbHVlKG5vZGVIYW5kbGUpOwotICAgICAgcmV0dXJuIHN0clZhbC50b1N0cmluZygpOwotICAgIH0KLQotICAgIC8qKgotICAgICAqIEdldCBhIHZhcmlhYmxlIGJhc2VkIG9uIGl0J3MgcXVhbGlmaWVkIG5hbWUuCi0gICAgICogQHBhcmFtIHFuYW1lIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAgICogQHJldHVybiBUaGUgZXZhbHVhdGVkIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KLSAgICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICAgKi8KLQotICAgIHB1YmxpYyBmaW5hbCBYT2JqZWN0IGdldFZhcmlhYmxlT3JQYXJhbShvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZSBxbmFtZSkKLSAgICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICB7Ci0gICAgICByZXR1cm4gbV92YXJpYWJsZVN0YWNrcy5nZXRWYXJpYWJsZU9yUGFyYW0oWFBhdGhDb250ZXh0LnRoaXMsIHFuYW1lKTsKLSAgICB9Ci0KLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aEV4Y2VwdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvWFBhdGhFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2RhYjM1MS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aEV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjkzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGg7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIGV4Y2VwdGlvbiBvYmplY3QgdGhhdCBhbGwKLSAqIFhQYXRoIGNsYXNzZXMgd2lsbCB0aHJvdyBpbiBjYXNlIG9mIGFuIGVycm9yLiAgVGhpcyBjbGFzcwotICogZXh0ZW5kcyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiwgYW5kIG1heSBob2xkIG90aGVyIGV4Y2VwdGlvbnMuIEluIHRoZQotICogY2FzZSBvZiBuZXN0ZWQgZXhjZXB0aW9ucywgcHJpbnRTdGFja1RyYWNlIHdpbGwgZHVtcAotICogYWxsIHRoZSB0cmFjZXMgb2YgdGhlIG5lc3RlZCBleGNlcHRpb25zLCBub3QganVzdCB0aGUgdHJhY2UKLSAqIG9mIHRoaXMgb2JqZWN0LgotICovCi1wdWJsaWMgY2xhc3MgWFBhdGhFeGNlcHRpb24gZXh0ZW5kcyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotewotCi0gIC8qKiBUaGUgaG9tZSBvZiB0aGUgZXhwcmVzc2lvbiB0aGF0IGNhdXNlZCB0aGUgZXJyb3IuCi0gICAqICBAc2VyaWFsICAqLwotICBPYmplY3QgbV9zdHlsZU5vZGUgPSBudWxsOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIHN0eWxlc2hlZXQgbm9kZSBmcm9tIHdoZXJlIHRoaXMgZXJyb3Igb3JpZ2luYXRlZC4KLSAgICogQHJldHVybiBUaGUgc3R5bGVzaGVldCBub2RlIGZyb20gd2hlcmUgdGhpcyBlcnJvciBvcmlnaW5hdGVkLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRTdHlsZXNoZWV0Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9zdHlsZU5vZGU7Ci0gIH0KLQotICAvKiogQSBuZXN0ZWQgZXhjZXB0aW9uLgotICAgKiAgQHNlcmlhbCAgICovCi0gIHByb3RlY3RlZCBFeGNlcHRpb24gbV9leGNlcHRpb247Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aEV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcwotICAgKiBhbiBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS4KLSAgICovCi0gIHB1YmxpYyBYUGF0aEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkKLSAgewotICAgIHN1cGVyKG1lc3NhZ2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aEV4Y2VwdGlvbiBvYmplY3QgdGhhdCBob2xkcwotICAgKiBhbiBlcnJvciBtZXNzYWdlIGFuZCB0aGUgc3R5bGVzaGVldCBub2RlIHRoYXQKLSAgICogdGhlIGVycm9yIG9yaWdpbmF0ZWQgZnJvbS4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBzdHlsZU5vZGUgVGhlIHN0eWxlc2hlZXQgbm9kZSB0aGF0IHRoZSBlcnJvciBvcmlnaW5hdGVkIGZyb20uCi0gICAqLwotICBwdWJsaWMgWFBhdGhFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBzdHlsZU5vZGUpCi0gIHsKLQotICAgIHN1cGVyKG1lc3NhZ2UpOwotCi0gICAgbV9zdHlsZU5vZGUgPSBzdHlsZU5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoRXhjZXB0aW9uIG9iamVjdCB0aGF0IGhvbGRzCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UsIHRoZSBzdHlsZXNoZWV0IG5vZGUgdGhhdAotICAgKiB0aGUgZXJyb3Igb3JpZ2luYXRlZCBmcm9tLCBhbmQgYW5vdGhlciBleGNlcHRpb24KLSAgICogdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgKiBAcGFyYW0gc3R5bGVOb2RlIFRoZSBzdHlsZXNoZWV0IG5vZGUgdGhhdCB0aGUgZXJyb3Igb3JpZ2luYXRlZCBmcm9tLgotICAgKiBAcGFyYW0gZSBUaGUgZXhjZXB0aW9uIHRoYXQgY2F1c2VkIHRoaXMgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIFhQYXRoRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBOb2RlIHN0eWxlTm9kZSwgRXhjZXB0aW9uIGUpCi0gIHsKLQotICAgIHN1cGVyKG1lc3NhZ2UpOwotCi0gICAgbV9zdHlsZU5vZGUgPSBzdHlsZU5vZGU7Ci0gICAgdGhpcy5tX2V4Y2VwdGlvbiA9IGU7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoRXhjZXB0aW9uIG9iamVjdCB0aGF0IGhvbGRzCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UsIGFuZCBhbm90aGVyIGV4Y2VwdGlvbgotICAgKiB0aGF0IGNhdXNlZCB0aGlzIGV4Y2VwdGlvbi4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgWFBhdGhFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKQotICB7Ci0KLSAgICBzdXBlcihtZXNzYWdlKTsKLQotICAgIHRoaXMubV9leGNlcHRpb24gPSBlOwotICB9Ci0KLSAgLyoqCi0gICAqIFByaW50IHRoZSB0aGUgdHJhY2Ugb2YgbWV0aG9kcyBmcm9tIHdoZXJlIHRoZSBlcnJvcgotICAgKiBvcmlnaW5hdGVkLiAgVGhpcyB3aWxsIHRyYWNlIGFsbCBuZXN0ZWQgZXhjZXB0aW9uCi0gICAqIG9iamVjdHMsIGFzIHdlbGwgYXMgdGhpcyBvYmplY3QuCi0gICAqIEBwYXJhbSBzIFRoZSBzdHJlYW0gd2hlcmUgdGhlIGR1bXAgd2lsbCBiZSBzZW50IHRvLgotICAgKi8KLSAgcHVibGljIHZvaWQgcHJpbnRTdGFja1RyYWNlKGphdmEuaW8uUHJpbnRTdHJlYW0gcykKLSAgewotCi0gICAgaWYgKHMgPT0gbnVsbCkKLSAgICAgIHMgPSBTeXN0ZW0uZXJyOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgc3VwZXIucHJpbnRTdGFja1RyYWNlKHMpOwotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpe30KLQotICAgIFRocm93YWJsZSBleGNlcHRpb24gPSBtX2V4Y2VwdGlvbjsKLQotICAgIGZvciAoaW50IGkgPSAwOyAoaSA8IDEwKSAmJiAobnVsbCAhPSBleGNlcHRpb24pOyBpKyspCi0gICAgewotICAgICAgcy5wcmludGxuKCItLS0tLS0tLS0iKTsKLSAgICAgIGV4Y2VwdGlvbi5wcmludFN0YWNrVHJhY2Uocyk7Ci0KLSAgICAgIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBUcmFuc2Zvcm1lckV4Y2VwdGlvbikKLSAgICAgIHsKLSAgICAgICAgVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UgPSAoVHJhbnNmb3JtZXJFeGNlcHRpb24pIGV4Y2VwdGlvbjsKLSAgICAgICAgVGhyb3dhYmxlIHByZXYgPSBleGNlcHRpb247Ci0KLSAgICAgICAgZXhjZXB0aW9uID0gc2UuZ2V0RXhjZXB0aW9uKCk7Ci0KLSAgICAgICAgaWYgKHByZXYgPT0gZXhjZXB0aW9uKQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBleGNlcHRpb24gPSBudWxsOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBGaW5kIHRoZSBtb3N0IGNvbnRhaW5lZCBtZXNzYWdlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBlcnJvciBtZXNzYWdlIG9mIHRoZSBvcmlnaW5hdGluZyBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKQotICB7Ci0KLSAgICBTdHJpbmcgbGFzdE1lc3NhZ2UgPSBzdXBlci5nZXRNZXNzYWdlKCk7Ci0gICAgVGhyb3dhYmxlIGV4Y2VwdGlvbiA9IG1fZXhjZXB0aW9uOwotCi0gICAgd2hpbGUgKG51bGwgIT0gZXhjZXB0aW9uKQotICAgIHsKLSAgICAgIFN0cmluZyBuZXh0TWVzc2FnZSA9IGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCk7Ci0KLSAgICAgIGlmIChudWxsICE9IG5leHRNZXNzYWdlKQotICAgICAgICBsYXN0TWVzc2FnZSA9IG5leHRNZXNzYWdlOwotCi0gICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJFeGNlcHRpb24pCi0gICAgICB7Ci0gICAgICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlID0gKFRyYW5zZm9ybWVyRXhjZXB0aW9uKSBleGNlcHRpb247Ci0gICAgICAgIFRocm93YWJsZSBwcmV2ID0gZXhjZXB0aW9uOwotCi0gICAgICAgIGV4Y2VwdGlvbiA9IHNlLmdldEV4Y2VwdGlvbigpOwotCi0gICAgICAgIGlmIChwcmV2ID09IGV4Y2VwdGlvbikKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gKG51bGwgIT0gbGFzdE1lc3NhZ2UpID8gbGFzdE1lc3NhZ2UgOiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBQcmludCB0aGUgdGhlIHRyYWNlIG9mIG1ldGhvZHMgZnJvbSB3aGVyZSB0aGUgZXJyb3IKLSAgICogb3JpZ2luYXRlZC4gIFRoaXMgd2lsbCB0cmFjZSBhbGwgbmVzdGVkIGV4Y2VwdGlvbgotICAgKiBvYmplY3RzLCBhcyB3ZWxsIGFzIHRoaXMgb2JqZWN0LgotICAgKiBAcGFyYW0gcyBUaGUgd3JpdGVyIHdoZXJlIHRoZSBkdW1wIHdpbGwgYmUgc2VudCB0by4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHByaW50U3RhY2tUcmFjZShqYXZhLmlvLlByaW50V3JpdGVyIHMpCi0gIHsKLQotICAgIGlmIChzID09IG51bGwpCi0gICAgICBzID0gbmV3IGphdmEuaW8uUHJpbnRXcml0ZXIoU3lzdGVtLmVycik7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBzdXBlci5wcmludFN0YWNrVHJhY2Uocyk7Ci0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSl7fQotCi0gICAgVGhyb3dhYmxlIGV4Y2VwdGlvbiA9IG1fZXhjZXB0aW9uOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IChpIDwgMTApICYmIChudWxsICE9IGV4Y2VwdGlvbik7IGkrKykKLSAgICB7Ci0gICAgICBzLnByaW50bG4oIi0tLS0tLS0tLSIpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgZXhjZXB0aW9uLnByaW50U3RhY2tUcmFjZShzKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgcy5wcmludGxuKCJDb3VsZCBub3QgcHJpbnQgc3RhY2sgdHJhY2UuLi4iKTsKLSAgICAgIH0KLQotICAgICAgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFRyYW5zZm9ybWVyRXhjZXB0aW9uKQotICAgICAgewotICAgICAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSA9IChUcmFuc2Zvcm1lckV4Y2VwdGlvbikgZXhjZXB0aW9uOwotICAgICAgICBUaHJvd2FibGUgcHJldiA9IGV4Y2VwdGlvbjsKLQotICAgICAgICBleGNlcHRpb24gPSBzZS5nZXRFeGNlcHRpb24oKTsKLQotICAgICAgICBpZiAocHJldiA9PSBleGNlcHRpb24pCi0gICAgICAgIHsKLSAgICAgICAgICBleGNlcHRpb24gPSBudWxsOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgZXhjZXB0aW9uID0gbnVsbDsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybiB0aGUgZW1iZWRkZWQgZXhjZXB0aW9uLCBpZiBhbnkuCi0gICAqICBPdmVycmlkZXMgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbi5nZXRFeGNlcHRpb24oKS4KLSAgICogCi0gICAqICBAcmV0dXJuIFRoZSBlbWJlZGRlZCBleGNlcHRpb24sIG9yIG51bGwgaWYgdGhlcmUgaXMgbm9uZS4KLSAgICovCi0gIHB1YmxpYyBUaHJvd2FibGUgZ2V0RXhjZXB0aW9uKCkKLSAgewotICAgIHJldHVybiBtX2V4Y2VwdGlvbjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvWFBhdGhGYWN0b3J5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aEZhY3RvcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTExOTg2OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9YUGF0aEZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGg7Ci0KLS8vIGltcG9ydCBvcmcueG1sLnNheC5Mb2NhdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZUxvY2F0b3I7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBGYWN0b3J5IGNsYXNzIGZvciBjcmVhdGluZyBhbiBYUGF0aC4gIEltcGxlbWVudG9ycyBvZiBYUGF0aCBkZXJpdmF0aXZlcwotICogd2lsbCBuZWVkIHRvIG1ha2UgYSBkZXJpdmVkIGNsYXNzIG9mIHRoaXMuCi0gKi8KLXB1YmxpYyBpbnRlcmZhY2UgWFBhdGhGYWN0b3J5Ci17Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYUGF0aC4KLSAgICoKLSAgICogQHBhcmFtIGV4cHJTdHJpbmcgVGhlIFhQYXRoIGV4cHJlc3Npb24gc3RyaW5nLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2YgdGhlIGV4cHJlc3Npb24gc3RyaW5nLCBtYWlubHkgZm9yIGRpYWdub3N0aWMKLSAgICogICAgICAgICAgICAgICAgcHVycG9zZXMuCi0gICAqIEBwYXJhbSBwcmVmaXhSZXNvbHZlciBUaGlzIHdpbGwgYmUgY2FsbGVkIGluIG9yZGVyIHRvIHJlc29sdmUgcHJlZml4ZXMgCi0gICAqICAgICAgICB0byBuYW1lc3BhY2UgVVJJcy4KLSAgICogQHBhcmFtIHR5cGUgT25lIG9mIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoI1NFTEVDVH0gb3IgCi0gICAqICAgICAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoI01BVENIfS4KLSAgICoKLSAgICogQHJldHVybiBhbiBYUGF0aCByZWFkeSBmb3IgZXhlY3V0aW9uLgotICAgKi8KLSAgWFBhdGggY3JlYXRlKFN0cmluZyBleHByU3RyaW5nLCBTb3VyY2VMb2NhdG9yIGxvY2F0b3IsCi0gICAgICAgICAgICAgICBQcmVmaXhSZXNvbHZlciBwcmVmaXhSZXNvbHZlciwgaW50IHR5cGUpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvWFBhdGhQcm9jZXNzb3JFeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL1hQYXRoUHJvY2Vzc29yRXhjZXB0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDIzNTU0ODQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvWFBhdGhQcm9jZXNzb3JFeGNlcHRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGg7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIERlcml2ZWQgZnJvbSBYUGF0aEV4Y2VwdGlvbiBpbiBvcmRlciB0aGF0IFhQYXRoIHByb2Nlc3NvcgotICogZXhjZXB0aW9ucyBtYXkgYmUgc3BlY2lmaWNhbGx5IGNhdWdodC4KLSAqLwotcHVibGljIGNsYXNzIFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uIGV4dGVuZHMgWFBhdGhFeGNlcHRpb24KLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uIG9iamVjdCB0aGF0IGhvbGRzCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLgotICAgKi8KLSAgcHVibGljIFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKQotICB7Ci0gICAgc3VwZXIobWVzc2FnZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGFuIFhQYXRoUHJvY2Vzc29yRXhjZXB0aW9uIG9iamVjdCB0aGF0IGhvbGRzCi0gICAqIGFuIGVycm9yIG1lc3NhZ2UsIGFuZCBhbm90aGVyIGV4Y2VwdGlvbgotICAgKiB0aGF0IGNhdXNlZCB0aGlzIGV4Y2VwdGlvbi4KLSAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGVycm9yIG1lc3NhZ2UuCi0gICAqIEBwYXJhbSBlIFRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uCi0gICAqLwotICBwdWJsaWMgWFBhdGhQcm9jZXNzb3JFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKQotICB7Ci0gICAgc3VwZXIobWVzc2FnZSwgZSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQXR0cmlidXRlSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQXR0cmlidXRlSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2M3ZDI2ZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL0F0dHJpYnV0ZUl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5heGVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYW4gb3B0aW1pemVkIGl0ZXJhdG9yIGZvcgotICogYXR0cmlidXRlIGF4ZXMgcGF0dGVybnMuCi0gKiBAc2VlIG9yZy5hcGFjaGUueHBhdGguYXhlcy5XYWxrZXJGYWN0b3J5I25ld0xvY1BhdGhJdGVyYXRvcgotICovCi1wdWJsaWMgY2xhc3MgQXR0cmlidXRlSXRlcmF0b3IgZXh0ZW5kcyBDaGlsZFRlc3RJdGVyYXRvcgotewotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBBdHRyaWJ1dGVJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBBdHRyaWJ1dGVJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgdmlhIGdldEZpcnN0QXR0cmlidXRlICYmIGdldE5leHRBdHRyaWJ1dGUuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIG1fbGFzdEZldGNoZWQgPSAoRFRNLk5VTEwgPT0gbV9sYXN0RmV0Y2hlZCkKLSAgICAgICAgICAgICAgICAgICAgID8gbV9jZHRtLmdldEZpcnN0QXR0cmlidXRlKG1fY29udGV4dCkKLSAgICAgICAgICAgICAgICAgICAgIDogbV9jZHRtLmdldE5leHRBdHRyaWJ1dGUobV9sYXN0RmV0Y2hlZCk7Ci0gICAgcmV0dXJuIG1fbGFzdEZldGNoZWQ7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICogCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlIAotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gb3JnLmFwYWNoZS54bWwuZHRtLkF4aXMuQVRUUklCVVRFOwotICB9Ci0KLQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL0F4ZXNXYWxrZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQXhlc1dhbGtlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzRmM2U5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQXhlc1dhbGtlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTU4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguYXhlczsKLQotaW1wb3J0IGphdmEudXRpbC5TdGFjazsKLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi0vLyBYYWxhbiBpbXBvcnRzCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkxvY1BhdGhJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuU3ViQ29udGV4dExpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLk9wQ29kZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3RGaWx0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNQXhpc1RyYXZlcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLQotLyoqCi0gKiBTZXJ2ZXMgYXMgY29tbW9uIGludGVyZmFjZSBmb3IgYXhlcyBXYWxrZXJzLCBhbmQgc3RvcmVzIGNvbW1vbgotICogc3RhdGUgdmFyaWFibGVzLgotICovCi1wdWJsaWMgY2xhc3MgQXhlc1dhbGtlciBleHRlbmRzIFByZWRpY2F0ZWROb2RlVGVzdAotICAgICAgICBpbXBsZW1lbnRzIENsb25lYWJsZQotewotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBBeGVzV2Fsa2VyIHVzaW5nIGEgTG9jUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbG9jUGF0aEl0ZXJhdG9yIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgcGFyZW50IGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIEF4ZXNXYWxrZXIoTG9jUGF0aEl0ZXJhdG9yIGxvY1BhdGhJdGVyYXRvciwgaW50IGF4aXMpCi0gIHsKLSAgICBzdXBlciggbG9jUGF0aEl0ZXJhdG9yICk7Ci0gICAgbV9heGlzID0gYXhpczsKLSAgfQotICAKLSAgcHVibGljIGZpbmFsIFdhbGtpbmdJdGVyYXRvciB3aSgpCi0gIHsKLSAgICByZXR1cm4gKFdhbGtpbmdJdGVyYXRvciltX2xwaTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIGFuIEF4ZXNXYWxrZXIgZHVyaW5nIHRoZSBwYXJzZSBvZiB0aGUgWFBhdGggZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciBvYmplY3QgdGhhdCBoYXMgaW5mb3JtYXRpb24gYWJvdXQgdGhpcyAKLSAgICogICAgICAgICAgICAgICAgIHdhbGtlciBpbiB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIG9wIGNvZGUgcG9zaXRpb24gb2YgdGhpcyBsb2NhdGlvbiBzdGVwLgotICAgKiBAcGFyYW0gc3RlcFR5cGUgIFRoZSB0eXBlIG9mIGxvY2F0aW9uIHN0ZXAuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5pdChDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgc3RlcFR5cGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW5pdFByZWRpY2F0ZUluZm8oY29tcGlsZXIsIG9wUG9zKTsKLQotICAgIC8vIGludCB0ZXN0VHlwZSA9IGNvbXBpbGVyLmdldE9wKG5vZGVUZXN0T3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBBeGVzV2Fsa2VyLgotICAgKgotICAgKiBAcmV0dXJuIEEgbmV3IEF4ZXNXYWxrZXIgdGhhdCBjYW4gYmUgdXNlZCB3aXRob3V0IG11dGF0aW5nIHRoaXMgb25lLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBEbyBub3QgYWNjZXNzIHRoZSBsb2NhdGlvbiBwYXRoIGl0dGVyYXRvciBkdXJpbmcgdGhpcyBvcGVyYXRpb24hCi0gICAgCi0gICAgQXhlc1dhbGtlciBjbG9uZSA9IChBeGVzV2Fsa2VyKSBzdXBlci5jbG9uZSgpOwotCi0gICAgLy9jbG9uZS5zZXRDdXJyZW50Tm9kZShjbG9uZS5tX3Jvb3QpOwotCi0gICAgLy8gY2xvbmUubV9pc0ZyZXNoID0gdHJ1ZTsKLQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIERvIGEgZGVlcCBjbG9uZSBvZiB0aGlzIHdhbGtlciwgaW5jbHVkaW5nIG5leHQgYW5kIHByZXZpb3VzIHdhbGtlcnMuCi0gICAqIElmIHRoZSB0aGlzIEF4ZXNXYWxrZXIgaXMgb24gdGhlIGNsb25lIGxpc3QsIGRvbid0IGNsb25lIGJ1dCAKLSAgICogcmV0dXJuIHRoZSBhbHJlYWR5IGNsb25lZCB2ZXJzaW9uLgotICAgKiAKLSAgICogQHBhcmFtIGNsb25lT3duZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBjbG9uZWQgbG9jYXRpb24gcGF0aCAKLSAgICogICAgICAgICAgICAgICAgICAgaXRlcmF0b3IgdG8gd2hpY2ggdGhpcyBjbG9uZSB3aWxsIGJlIGFkZGVkLgotICAgKiBAcGFyYW0gY2xvbmVMaXN0IG5vbi1udWxsIHZlY3RvciBvZiBzb3VyY2VzIGluIG9kZCBlbGVtZW50cywgYW5kIHRoZSAKLSAgICogICAgICAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIGNsb25lcyBpbiBldmVuIHZlY3RvcnMuCi0gICAqIAotICAgKiBAcmV0dXJuIG5vbi1udWxsIGNsb25lLCB3aGljaCBtYXkgYmUgYSBuZXcgY2xvbmUsIG9yIG1heSBiZSBhIGNsb25lIAotICAgKiAgICAgICAgIGNvbnRhaW5lZCBvbiB0aGUgY2xvbmVMaXN0LgotICAgKi8KLSAgQXhlc1dhbGtlciBjbG9uZURlZXAoV2Fsa2luZ0l0ZXJhdG9yIGNsb25lT3duZXIsIFZlY3RvciBjbG9uZUxpc3QpCi0gICAgIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0gICAgQXhlc1dhbGtlciBjbG9uZSA9IGZpbmRDbG9uZSh0aGlzLCBjbG9uZUxpc3QpOwotICAgIGlmKG51bGwgIT0gY2xvbmUpCi0gICAgICByZXR1cm4gY2xvbmU7Ci0gICAgY2xvbmUgPSAoQXhlc1dhbGtlcil0aGlzLmNsb25lKCk7Ci0gICAgY2xvbmUuc2V0TG9jUGF0aEl0ZXJhdG9yKGNsb25lT3duZXIpOwotICAgIGlmKG51bGwgIT0gY2xvbmVMaXN0KQotICAgIHsKLSAgICAgIGNsb25lTGlzdC5hZGRFbGVtZW50KHRoaXMpOwotICAgICAgY2xvbmVMaXN0LmFkZEVsZW1lbnQoY2xvbmUpOwotICAgIH0KLSAgICAKLSAgICBpZih3aSgpLm1fbGFzdFVzZWRXYWxrZXIgPT0gdGhpcykKLSAgICAgIGNsb25lT3duZXIubV9sYXN0VXNlZFdhbGtlciA9IGNsb25lOwotICAgICAgCi0gICAgaWYobnVsbCAhPSBtX25leHRXYWxrZXIpCi0gICAgICBjbG9uZS5tX25leHRXYWxrZXIgPSBtX25leHRXYWxrZXIuY2xvbmVEZWVwKGNsb25lT3duZXIsIGNsb25lTGlzdCk7Ci0gICAgICAKLSAgICAvLyBJZiB5b3UgZG9uJ3QgY2hlY2sgZm9yIHRoZSBjbG9uZUxpc3QgaGVyZSwgeW91J2xsIGdvIGludG8gYW4gCi0gICAgLy8gcmVjdXJzaXZlIGluZmluYXRlIGxvb3AuICAKLSAgICBpZihudWxsICE9IGNsb25lTGlzdCkKLSAgICB7Ci0gICAgICBpZihudWxsICE9IG1fcHJldldhbGtlcikKLSAgICAgICAgY2xvbmUubV9wcmV2V2Fsa2VyID0gbV9wcmV2V2Fsa2VyLmNsb25lRGVlcChjbG9uZU93bmVyLCBjbG9uZUxpc3QpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYobnVsbCAhPSBtX25leHRXYWxrZXIpCi0gICAgICAgIGNsb25lLm1fbmV4dFdhbGtlci5tX3ByZXZXYWxrZXIgPSBjbG9uZTsKLSAgICB9Ci0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0gIAotICAvKioKLSAgICogRmluZCBhIGNsb25lIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGtleSBhcmd1bWVudC4KLSAgICogCi0gICAqIEBwYXJhbSBrZXkgVGhlIG9yaWdpbmFsIEF4ZXNXYWxrZXIgZm9yIHdoaWNoIHRoZXJlIG1heSBiZSBhIGNsb25lLgotICAgKiBAcGFyYW0gY2xvbmVMaXN0IHZlY3RvciBvZiBzb3VyY2VzIGluIG9kZCBlbGVtZW50cywgYW5kIHRoZSAKLSAgICogICAgICAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIGNsb25lcyBpbiBldmVuIHZlY3RvcnMsIG1heSBiZSBudWxsLgotICAgKiAKLSAgICogQHJldHVybiBBIGNsb25lIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGtleSwgb3IgbnVsbCBpZiBrZXkgbm90IGZvdW5kLgotICAgKi8KLSAgc3RhdGljIEF4ZXNXYWxrZXIgZmluZENsb25lKEF4ZXNXYWxrZXIga2V5LCBWZWN0b3IgY2xvbmVMaXN0KQotICB7Ci0gICAgaWYobnVsbCAhPSBjbG9uZUxpc3QpCi0gICAgewotICAgICAgLy8gRmlyc3QsIGxvb2sgZm9yIGNsb25lIG9uIGxpc3QuCi0gICAgICBpbnQgbiA9IGNsb25lTGlzdC5zaXplKCk7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrPTIpIAotICAgICAgewotICAgICAgICBpZihrZXkgPT0gY2xvbmVMaXN0LmVsZW1lbnRBdChpKSkKLSAgICAgICAgICByZXR1cm4gKEF4ZXNXYWxrZXIpY2xvbmVMaXN0LmVsZW1lbnRBdChpKzEpOwotICAgICAgfQotICAgIH0KLSAgICByZXR1cm4gbnVsbDsgICAgCi0gIH0KLSAgCi0gIC8vPT09PT09PT09PT09PT09IFRyZWVXYWxrZXIgSW1wbGVtZW50YXRpb24gPT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqIFRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIsIGFzIHNwZWNpZmllZCBpbiBzZXRSb290KGludCByb290KS4KLSAgICogTm90ZSB0aGF0IHRoaXMgbWF5IGFjdHVhbGx5IGJlIGJlbG93IHRoZSBjdXJyZW50IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNvbnRleHQgbm9kZSBvZiB0aGUgc3RlcC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9yb290OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcm9vdCBub2RlIG9mIHRoZSBUcmVlV2Fsa2VyLgotICAgKiAoTm90IHBhcnQgb2YgdGhlIERPTTIgVHJlZVdhbGtlciBpbnRlcmZhY2UpLgotICAgKgotICAgKiBAcGFyYW0gcm9vdCBUaGUgY29udGV4dCBub2RlIG9mIHRoaXMgc3RlcC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IHJvb3QpCi0gIHsKLSAgICAvLyAlT1BUJSBHZXQgdGhpcyBkaXJlY3RseSBmcm9tIHRoZSBscGkuCi0gICAgbV9kdG0gPSB3aSgpLmdldFhQYXRoQ29udGV4dCgpLmdldERUTShyb290KTsKLSAgICBtX3RyYXZlcnNlciA9IG1fZHRtLmdldEF4aXNUcmF2ZXJzZXIobV9heGlzKTsKLSAgICBtX2lzRnJlc2ggPSB0cnVlOwotICAgIG1fZm91bmRMYXN0ID0gZmFsc2U7Ci0gICAgbV9yb290ID0gcm9vdDsKLSAgICBtX2N1cnJlbnROb2RlID0gcm9vdDsKLQotICAgIGlmIChEVE0uTlVMTCA9PSByb290KQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiXG4gISEhISBFcnJvciEgU2V0dGluZyB0aGUgcm9vdCBvZiBhIHdhbGtlciB0byBudWxsISEhIik7Ci0gICAgfQotCi0gICAgcmVzZXRQcm94aW1pdHlQb3NpdGlvbnMoKTsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBhdCB3aGljaCB0aGUgVHJlZVdhbGtlciBpcyBjdXJyZW50bHkgcG9zaXRpb25lZC4KLSAgICogPGJyPiBUaGUgdmFsdWUgbXVzdCBub3QgYmUgbnVsbC4gQWx0ZXJhdGlvbnMgdG8gdGhlIERPTSB0cmVlIG1heSBjYXVzZQotICAgKiB0aGUgY3VycmVudCBub2RlIHRvIG5vIGxvbmdlciBiZSBhY2NlcHRlZCBieSB0aGUgVHJlZVdhbGtlcidzCi0gICAqIGFzc29jaWF0ZWQgZmlsdGVyLiBjdXJyZW50Tm9kZSBtYXkgYWxzbyBiZSBleHBsaWNpdGx5IHNldCB0byBhbnkgbm9kZSwKLSAgICogd2hldGhlciBvciBub3QgaXQgaXMgd2l0aGluIHRoZSBzdWJ0cmVlIHNwZWNpZmllZCBieSB0aGUgcm9vdCBub2RlIG9yCi0gICAqIHdvdWxkIGJlIGFjY2VwdGVkIGJ5IHRoZSBmaWx0ZXIgYW5kIHdoYXRUb1Nob3cgZmxhZ3MuIEZ1cnRoZXIKLSAgICogdHJhdmVyc2FsIG9jY3VycyByZWxhdGl2ZSB0byBjdXJyZW50Tm9kZSBldmVuIGlmIGl0IGlzIG5vdCBwYXJ0IG9mIHRoZQotICAgKiBjdXJyZW50IHZpZXcgYnkgYXBwbHlpbmcgdGhlIGZpbHRlcnMgaW4gdGhlIHJlcXVlc3RlZCBkaXJlY3Rpb24gKG5vdAotICAgKiBjaGFuZ2luZyBjdXJyZW50Tm9kZSB3aGVyZSBubyB0cmF2ZXJzYWwgaXMgcG9zc2libGUpLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIGF0IHdoaWNoIHRoZSBUcmVlV2Fsa2VyIGlzIGN1cnJlbnRseSBwb3NpdGlvbmVkLCBvbmx5IG51bGwgCi0gICAqIGlmIHNldFJvb3QgaGFzIG5vdCB5ZXQgYmVlbiBjYWxsZWQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgaW50IGdldEN1cnJlbnROb2RlKCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbmV4dCB3YWxrZXIgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3YWxrZXIgUmVmZXJlbmNlIHRvIEF4ZXNXYWxrZXIgZGVyaXZhdGl2ZSwgb3IgbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROZXh0V2Fsa2VyKEF4ZXNXYWxrZXIgd2Fsa2VyKQotICB7Ci0gICAgbV9uZXh0V2Fsa2VyID0gd2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCB3YWxrZXIgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gUmVmZXJlbmNlIHRvIEF4ZXNXYWxrZXIgZGVyaXZhdGl2ZSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBBeGVzV2Fsa2VyIGdldE5leHRXYWxrZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dFdhbGtlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgb3IgY2xlYXIgdGhlIHByZXZpb3VzIHdhbGtlciByZWZlcmVuY2UgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3YWxrZXIgUmVmZXJlbmNlIHRvIHByZXZpb3VzIHdhbGtlciByZWZlcmVuY2UgaW4gdGhlIGxvY2F0aW9uIAotICAgKiAgICAgICAgICAgICAgIHN0ZXAgY2hhaW4sIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRQcmV2V2Fsa2VyKEF4ZXNXYWxrZXIgd2Fsa2VyKQotICB7Ci0gICAgbV9wcmV2V2Fsa2VyID0gd2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgcHJldmlvdXMgd2Fsa2VyIHJlZmVyZW5jZSBpbiB0aGUgbG9jYXRpb24gc3RlcCBjaGFpbi4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBSZWZlcmVuY2UgdG8gcHJldmlvdXMgd2Fsa2VyIHJlZmVyZW5jZSBpbiB0aGUgbG9jYXRpb24gCi0gICAqICAgICAgICAgICAgICAgc3RlcCBjaGFpbiwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBBeGVzV2Fsa2VyIGdldFByZXZXYWxrZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJldldhbGtlcjsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGlzIHNpbXBseSBhIHdheSB0byBib3R0bGUtbmVjayB0aGUgcmV0dXJuIG9mIHRoZSBuZXh0IG5vZGUsIGZvciAKLSAgICogZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byByZXR1cm4sIG9yIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGFyZ3VtZW50LgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgcmV0dXJuTmV4dE5vZGUoaW50IG4pCi0gIHsKLQotICAgIHJldHVybiBuOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyIG9uIHRoZSBheGVzLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIgb24gdGhlIGF4ZXMsIG9yIG51bGwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIGlmIChtX2ZvdW5kTGFzdCkKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIGlmIChtX2lzRnJlc2gpCi0gICAgewotICAgICAgbV9jdXJyZW50Tm9kZSA9IG1fdHJhdmVyc2VyLmZpcnN0KG1fcm9vdCk7Ci0gICAgICBtX2lzRnJlc2ggPSBmYWxzZTsKLSAgICB9Ci0gICAgLy8gSSBzaG91bGRuJ3QgaGF2ZSB0byBkbyB0aGlzIHRoZSBjaGVjayBmb3IgY3VycmVudCBub2RlLCBJIHRoaW5rLgotICAgIC8vIG51bWJlcmluZ1xudW1iZXJpbmcyNC54c2wgZmFpbHMgaWYgSSBkb24ndCBkbyB0aGlzLiAgSSB0aGluayAKLSAgICAvLyBpdCBvY2N1cnMgYXMgdGhlIHdhbGtlcnMgYXJlIGJhY2tpbmcgdXAuIC1zYgotICAgIGVsc2UgaWYoRFRNLk5VTEwgIT0gbV9jdXJyZW50Tm9kZSkgCi0gICAgewotICAgICAgbV9jdXJyZW50Tm9kZSA9IG1fdHJhdmVyc2VyLm5leHQobV9yb290LCBtX2N1cnJlbnROb2RlKTsKLSAgICB9Ci0KLSAgICBpZiAoRFRNLk5VTEwgPT0gbV9jdXJyZW50Tm9kZSkKLSAgICAgIHRoaXMubV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgcmV0dXJuIG1fY3VycmVudE5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogIE1vdmVzIHRoZSA8Y29kZT5UcmVlV2Fsa2VyPC9jb2RlPiB0byB0aGUgbmV4dCB2aXNpYmxlIG5vZGUgaW4gZG9jdW1lbnQKLSAgICogb3JkZXIgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgbm9kZSwgYW5kIHJldHVybnMgdGhlIG5ldyBub2RlLiBJZiB0aGUKLSAgICogY3VycmVudCBub2RlIGhhcyBubyBuZXh0IG5vZGUsICBvciBpZiB0aGUgc2VhcmNoIGZvciBuZXh0Tm9kZSBhdHRlbXB0cwotICAgKiB0byBzdGVwIHVwd2FyZCBmcm9tIHRoZSBUcmVlV2Fsa2VyJ3Mgcm9vdCBub2RlLCByZXR1cm5zCi0gICAqIDxjb2RlPm51bGw8L2NvZGU+ICwgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICogQHJldHVybiAgVGhlIG5ldyBub2RlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgY3VycmVudCBub2RlIGhhcyBubwotICAgKiAgIG5leHQgbm9kZSAgaW4gdGhlIFRyZWVXYWxrZXIncyBsb2dpY2FsIHZpZXcuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotICAgIGludCBuZXh0Tm9kZSA9IERUTS5OVUxMOwotICAgIEF4ZXNXYWxrZXIgd2Fsa2VyID0gd2koKS5nZXRMYXN0VXNlZFdhbGtlcigpOwotCi0gICAgd2hpbGUgKHRydWUpCi0gICAgewotICAgICAgaWYgKG51bGwgPT0gd2Fsa2VyKQotICAgICAgICBicmVhazsKLQotICAgICAgbmV4dE5vZGUgPSB3YWxrZXIuZ2V0TmV4dE5vZGUoKTsKLQotICAgICAgaWYgKERUTS5OVUxMID09IG5leHROb2RlKQotICAgICAgewotCi0gICAgICAgIHdhbGtlciA9IHdhbGtlci5tX3ByZXZXYWxrZXI7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmICh3YWxrZXIuYWNjZXB0Tm9kZShuZXh0Tm9kZSkgIT0gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVCkKLSAgICAgICAgewotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gd2Fsa2VyLm1fbmV4dFdhbGtlcikKLSAgICAgICAgewotICAgICAgICAgIHdpKCkuc2V0TGFzdFVzZWRXYWxrZXIod2Fsa2VyKTsKLQotICAgICAgICAgIC8vIHJldHVybiB3YWxrZXIucmV0dXJuTmV4dE5vZGUobmV4dE5vZGUpOwotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIEF4ZXNXYWxrZXIgcHJldiA9IHdhbGtlcjsKLQotICAgICAgICAgIHdhbGtlciA9IHdhbGtlci5tX25leHRXYWxrZXI7Ci0KLSAgICAgICAgICB3YWxrZXIuc2V0Um9vdChuZXh0Tm9kZSk7Ci0KLSAgICAgICAgICB3YWxrZXIubV9wcmV2V2Fsa2VyID0gcHJldjsKLQotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0gICAgICB9ICAvLyBpZihudWxsICE9IG5leHROb2RlKQotICAgIH0gIC8vIHdoaWxlKG51bGwgIT0gd2Fsa2VyKQotCi0gICAgcmV0dXJuIG5leHROb2RlOwotICB9Ci0KLSAgLy89PT09PT09PT09PT09IEVuZCBUcmVlV2Fsa2VyIEltcGxlbWVudGF0aW9uID09PT09PT09PT09PT0KLQotICAvKioKLSAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0KLSAgICBpbnQgcG9zID0gZ2V0UHJveGltaXR5UG9zaXRpb24oKTsKLSAgICAKLSAgICBBeGVzV2Fsa2VyIHdhbGtlcjsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHdhbGtlciA9IChBeGVzV2Fsa2VyKSBjbG9uZSgpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0gICAgICByZXR1cm4gLTE7Ci0gICAgfQotCi0gICAgd2Fsa2VyLnNldFByZWRpY2F0ZUNvdW50KHdhbGtlci5nZXRQcmVkaWNhdGVDb3VudCgpIC0gMSk7Ci0gICAgd2Fsa2VyLnNldE5leHRXYWxrZXIobnVsbCk7Ci0gICAgd2Fsa2VyLnNldFByZXZXYWxrZXIobnVsbCk7Ci0KLSAgICBXYWxraW5nSXRlcmF0b3IgbHBpID0gd2koKTsKLSAgICBBeGVzV2Fsa2VyIHNhdmVkV2Fsa2VyID0gbHBpLmdldExhc3RVc2VkV2Fsa2VyKCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBscGkuc2V0TGFzdFVzZWRXYWxrZXIod2Fsa2VyKTsKLQotICAgICAgaW50IG5leHQ7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobmV4dCA9IHdhbGtlci5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgcG9zKys7Ci0gICAgICB9Ci0KLSAgICAgIC8vIFRPRE86IFNob3VsZCBwcm9iYWJseSBzYXZlIHRoaXMgaW4gdGhlIGl0ZXJhdG9yLgotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgbHBpLnNldExhc3RVc2VkV2Fsa2VyKHNhdmVkV2Fsa2VyKTsKLSAgICB9Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInBvczogIitwb3MpOwotICAgIHJldHVybiBwb3M7Ci0gIH0KLSAgCi0gIC8vPT09PT09PT09PT09PSBTdGF0ZSBEYXRhID09PT09PT09PT09PT0KLSAgCi0gIC8qKgotICAgKiBUaGUgRFRNIGZvciB0aGUgcm9vdC4gIFRoaXMgY2FuIG5vdCBiZSB1c2VkLCBvciBtdXN0IGJlIGNoYW5nZWQsIAotICAgKiBmb3IgdGhlIGZpbHRlciB3YWxrZXIsIG9yIGFueSB3YWxrZXIgdGhhdCBjYW4gaGF2ZSBub2RlcyAKLSAgICogZnJvbSBtdWx0aXBsZSBkb2N1bWVudHMuCi0gICAqIE5ldmVyLCBldmVyLCBhY2Nlc3MgdGhpcyB2YWx1ZSB3aXRob3V0IGdvaW5nIHRocm91Z2ggZ2V0RFRNKGludCBub2RlKS4KLSAgICovCi0gIHByaXZhdGUgRFRNIG1fZHRtOwotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgRFRNIGZvciB0aGlzIHdhbGtlci4KLSAgICogCi0gICAqIEBwYXJhbSBkdG0gTm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgRFRNLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RGVmYXVsdERUTShEVE0gZHRtKQotICB7Ci0gICAgbV9kdG0gPSBkdG07Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIERUTSBmb3IgdGhpcyB3YWxrZXIuCi0gICAqIAotICAgKiBAcmV0dXJuIE5vbi1udWxsIHJlZmVyZW5jZSB0byBhIERUTS4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKGludCBub2RlKQotICB7Ci0gICAgLy8KLSAgICByZXR1cm4gd2koKS5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0obm9kZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgYWxsIHRoZSBub2RlcyBpbiB0aGUgaXRlcmF0aW9uIHdlbGwgYmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQgCi0gICAqIG9yZGVyLgotICAgKiBXYXJuaW5nOiBUaGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBhZnRlciBzZXRSb290IGhhcyBiZWVuIGNhbGxlZCEKLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBhcyBhIGRlZmF1bHQuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0RvY09yZGVyZWQoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICogCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlIAotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gbV9heGlzOwotICB9Ci0KLQotICAvKioKLSAgICogIFRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIsIGFzIHNwZWNpZmllZCB3aGVuIGl0IHdhcyBjcmVhdGVkLgotICAgKi8KLSAgdHJhbnNpZW50IGludCBtX3Jvb3QgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogIFRoZSBub2RlIGF0IHdoaWNoIHRoZSBUcmVlV2Fsa2VyIGlzIGN1cnJlbnRseSBwb3NpdGlvbmVkLgotICAgKi8KLSAgcHJpdmF0ZSB0cmFuc2llbnQgaW50IG1fY3VycmVudE5vZGUgPSBEVE0uTlVMTDsKLSAgCi0gIC8qKiBUcnVlIGlmIGFuIGl0dGVyYXRpb24gaGFzIG5vdCBiZWd1bi4gICovCi0gIHRyYW5zaWVudCBib29sZWFuIG1faXNGcmVzaDsKLQotICAvKiogVGhlIG5leHQgd2Fsa2VyIGluIHRoZSBsb2NhdGlvbiBzdGVwIGNoYWluLgotICAgKiAgQHNlcmlhbCAgKi8KLSAgcHJvdGVjdGVkIEF4ZXNXYWxrZXIgbV9uZXh0V2Fsa2VyOwotICAKLSAgLyoqIFRoZSBwcmV2aW91cyB3YWxrZXIgaW4gdGhlIGxvY2F0aW9uIHN0ZXAgY2hhaW4sIG9yIG51bGwuCi0gICAqICBAc2VyaWFsICAgKi8KLSAgQXhlc1dhbGtlciBtX3ByZXZXYWxrZXI7Ci0gIAotICAvKiogVGhlIHRyYXZlcnNhbCBheGlzIGZyb20gd2hlcmUgdGhlIG5vZGVzIHdpbGwgYmUgZmlsdGVyZWQuICovCi0gIHByb3RlY3RlZCBpbnQgbV9heGlzID0gLTE7Ci0KLSAgLyoqIFRoZSBEVE0gaW5uZXIgdHJhdmVyc2FsIGNsYXNzLCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBzdXBlciBheGlzLiAqLwotICBwcm90ZWN0ZWQgRFRNQXhpc1RyYXZlcnNlciBtX3RyYXZlcnNlcjsgICAKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQ2hpbGRJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9DaGlsZEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzNWQzNzEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9DaGlsZEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5heGVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBvcHRpbWl6ZWQgaXRlcmF0b3IgZm9yCi0gKiAibm9kZSgpIiBwYXR0ZXJucywgdGhhdCBpcywgYW55IGNoaWxkcmVuIG9mIHRoZQotICogY29udGV4dCBub2RlLgotICogQHNlZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuV2Fsa2VyRmFjdG9yeSNuZXdMb2NQYXRoSXRlcmF0b3IKLSAqLwotcHVibGljIGNsYXNzIENoaWxkSXRlcmF0b3IgZXh0ZW5kcyBMb2NQYXRoSXRlcmF0b3IKLXsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgQ2hpbGRJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICogQHBhcmFtIGFuYWx5c2lzIEFuYWx5c2lzIGJpdHMgb2YgdGhlIGVudGlyZSBwYXR0ZXJuLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIENoaWxkSXRlcmF0b3IoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzLCBmYWxzZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBpZiB0aGlzIGV4cHJlc3Npb24gaXMgCi0gICAqIGEgbm9kZXNldCBleHByZXNzaW9uLiAgVGhpcyBpcyB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgCi0gICAqIG5vZGVzZXRzLgotICAgKiA8cD5XQVJOSU5HOiBEbyBub3QgbXV0YXRlIHRoaXMgY2xhc3MgZnJvbSB0aGlzIGZ1bmN0aW9uITwvcD4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHB1YmxpYyBpbnQgYXNOb2RlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgaW50IGN1cnJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIAotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY3VycmVudCk7Ci0gICAgCi0gICAgcmV0dXJuIGR0bS5nZXRGaXJzdENoaWxkKGN1cnJlbnQpOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotCi0gICAgLy8gSWYgdGhlIGNhY2hlIGlzIG9uLCBhbmQgdGhlIG5vZGUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdGhlbiAKLSAgICAvLyBqdXN0IHJldHVybiBmcm9tIHRoZSBsaXN0LgotICAgIC8vIElmIHRoZSBjYWNoZSBpcyBvbiwgYW5kIHRoZSBub2RlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHRoZW4gCi0gICAgLy8ganVzdCByZXR1cm4gZnJvbSB0aGUgbGlzdC4KLSAgICBpZiAoKG51bGwgIT0gbV9jYWNoZWROb2RlcykKLSAgICAgICAgICAgICYmIChtX25leHQgPCBtX2NhY2hlZE5vZGVzLnNpemUoKSkpCi0gICAgewotICAgICAgaW50IG5leHQgPSBtX2NhY2hlZE5vZGVzLmVsZW1lbnRBdChtX25leHQpOwotICAgIAotICAgICAgaW5jcmVtZW50TmV4dFBvc2l0aW9uKCk7Ci0gICAgICBtX2N1cnJlbnRDb250ZXh0Tm9kZSA9IG5leHQ7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLQotICAgIGlmIChtX2ZvdW5kTGFzdCkKLSAgICB7Ci0gICAgICBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgaW50IG5leHQ7Ci0KLSAgICBtX2xhc3RGZXRjaGVkID0gbmV4dCA9IChEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtX2NkdG0uZ2V0Rmlyc3RDaGlsZChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICA6IG1fY2R0bS5nZXROZXh0U2libGluZyhtX2xhc3RGZXRjaGVkKTsKLQotICAgIC8vIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChtX2xhc3RGZXRjaGVkKTsKLQotICAgICAgbV9uZXh0Kys7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqIAotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZSAKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzLkNISUxEOwotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9DaGlsZFRlc3RJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9DaGlsZFRlc3RJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmNDFjNjJmLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQ2hpbGRUZXN0SXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNQXhpc1RyYXZlcnNlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBvcHRpbWl6ZWQgaXRlcmF0b3IgZm9yCi0gKiBjaGlsZHJlbiBwYXR0ZXJucyB0aGF0IGhhdmUgYSBub2RlIHRlc3QsIGFuZCBwb3NzaWJseSBhIHByZWRpY2F0ZS4KLSAqIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5heGVzLldhbGtlckZhY3RvcnkjbmV3TG9jUGF0aEl0ZXJhdG9yCi0gKi8KLXB1YmxpYyBjbGFzcyBDaGlsZFRlc3RJdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotICAvKiogVGhlIHRyYXZlcnNlciB0byB1c2UgdG8gbmF2aWdhdGUgb3ZlciB0aGUgZGVzY2VuZGFudHMuICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgRFRNQXhpc1RyYXZlcnNlciBtX3RyYXZlcnNlcjsKLSAgCi0gIC8qKiBUaGUgZXh0ZW5kZWQgdHlwZSBJRCwgbm90IHNldCB1bnRpbCBzZXRSb290LiAqLwotLy8gIHByb3RlY3RlZCBpbnQgbV9leHRlbmRlZFR5cGVJRDsKLQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBDaGlsZFRlc3RJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBDaGlsZFRlc3RJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgZmFsc2UpOwotCi0gICAgaW50IGZpcnN0U3RlcFBvcyA9IGNvbXBpbGVyLmdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotICAgIGludCB3aGF0VG9TaG93ID0gY29tcGlsZXIuZ2V0V2hhdFRvU2hvdyhmaXJzdFN0ZXBQb3MpOwotCi0gICAgaWYgKCgwID09ICh3aGF0VG9TaG93Ci0gICAgICAgICAgICAgICAmIChEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUgCi0gICAgICAgICAgICAgICB8IERUTUZpbHRlci5TSE9XX05BTUVTUEFDRSAKLSAgICAgICAgICAgICAgIHwgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVAotICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKSkpIAotICAgICAgICAgICAgICAgfHwgKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQUxMKSkKLSAgICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgICBlbHNlCi0gICAgewotICAgICAgaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3csIGNvbXBpbGVyLmdldFN0ZXBOUyhmaXJzdFN0ZXBQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGlsZXIuZ2V0U3RlcExvY2FsTmFtZShmaXJzdFN0ZXBQb3MpKTsKLSAgICB9Ci0gICAgaW5pdFByZWRpY2F0ZUluZm8oY29tcGlsZXIsIGZpcnN0U3RlcFBvcyk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDcmVhdGUgYSBDaGlsZFRlc3RJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBDaGlsZFRlc3RJdGVyYXRvcihEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlcikKLSAgewotCi0gICAgc3VwZXIobnVsbCk7Ci0KLSAgICBtX3RyYXZlcnNlciA9IHRyYXZlcnNlcjsKLSAgfQotCi0gIAotICAvKioKLSAgICogIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcKLSAgICogIG9mIHRoZSBxdWVyeS4KLSAgICogCi0gICAqICBAcmV0dXJuIEEgY2xvbmVkIE5vZGVJdGVyYXRvciBzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeS4KLSAgICogCi0gICAqICBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgY2xvbmVXaXRoUmVzZXQoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgQ2hpbGRUZXN0SXRlcmF0b3IgY2xvbmUgPSAoQ2hpbGRUZXN0SXRlcmF0b3IpIHN1cGVyLmNsb25lV2l0aFJlc2V0KCk7Ci0KLSAgICBjbG9uZS5yZXNldFByb3hpbWl0eVBvc2l0aW9ucygpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgdmlhIGdldE5leHRYWFguICBCb3R0bGVuZWNrZWQgZm9yIGRlcml2ZWQgY2xhc3Mgb3ZlcnJpZGUuCi0gICAqIEByZXR1cm4gVGhlIG5leHQgbm9kZSBvbiB0aGUgYXhpcywgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgeyAgICAgICAgICAgICAgICAgICAgIAotICAgIGlmKHRydWUgLyogMCA9PSBtX2V4dGVuZGVkVHlwZUlEICovKQotICAgIHsKLSAgICAgIG1fbGFzdEZldGNoZWQgPSAoRFRNLk5VTEwgPT0gbV9sYXN0RmV0Y2hlZCkKLSAgICAgICAgICAgICAgICAgICA/IG1fdHJhdmVyc2VyLmZpcnN0KG1fY29udGV4dCkKLSAgICAgICAgICAgICAgICAgICA6IG1fdHJhdmVyc2VyLm5leHQobV9jb250ZXh0LCBtX2xhc3RGZXRjaGVkKTsKLSAgICB9Ci0vLyAgICBlbHNlCi0vLyAgICB7Ci0vLyAgICAgIG1fbGFzdEZldGNoZWQgPSAoRFRNLk5VTEwgPT0gbV9sYXN0RmV0Y2hlZCkKLS8vICAgICAgICAgICAgICAgICAgID8gbV90cmF2ZXJzZXIuZmlyc3QobV9jb250ZXh0LCBtX2V4dGVuZGVkVHlwZUlEKQotLy8gICAgICAgICAgICAgICAgICAgOiBtX3RyYXZlcnNlci5uZXh0KG1fY29udGV4dCwgbV9sYXN0RmV0Y2hlZCwgCi0vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9leHRlbmRlZFR5cGVJRCk7Ci0vLyAgICB9Ci0KLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLQotICAgIC8vIElmIHRoZSBjYWNoZSBpcyBvbiwgYW5kIHRoZSBub2RlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHRoZW4gCi0gICAgLy8ganVzdCByZXR1cm4gZnJvbSB0aGUgbGlzdC4KLSAgICAvLyBJZiB0aGUgY2FjaGUgaXMgb24sIGFuZCB0aGUgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIGZvdW5kLCB0aGVuIAotICAgIC8vIGp1c3QgcmV0dXJuIGZyb20gdGhlIGxpc3QuCi0gICAgaWYgKChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgICAgICAgICAmJiAobV9uZXh0IDwgbV9jYWNoZWROb2Rlcy5zaXplKCkpKQotICAgIHsKLSAgICAgIGludCBuZXh0ID0gbV9jYWNoZWROb2Rlcy5lbGVtZW50QXQobV9uZXh0KTsKLSAgICAKLSAgICAgIGluY3JlbWVudE5leHRQb3NpdGlvbigpOwotICAgICAgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBuZXh0OwotCi0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0KLSAgICBpZiAobV9mb3VuZExhc3QpCi0gICAgewotICAgICAgbV9sYXN0RmV0Y2hlZCA9IERUTS5OVUxMOwotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgICAgIAotICAgIGlmKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgewotICAgICAgcmVzZXRQcm94aW1pdHlQb3NpdGlvbnMoKTsKLSAgICB9Ci0KLSAgICBpbnQgbmV4dDsKLSAgICAKLSAgICBvcmcuYXBhY2hlLnhwYXRoLlZhcmlhYmxlU3RhY2sgdmFyczsKLSAgICBpbnQgc2F2ZWRTdGFydDsKLSAgICBpZiAoLTEgIT0gbV9zdGFja0ZyYW1lKQotICAgIHsKLSAgICAgIHZhcnMgPSBtX2V4ZWNDb250ZXh0LmdldFZhclN0YWNrKCk7Ci0KLSAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICBzYXZlZFN0YXJ0ID0gdmFycy5nZXRTdGFja0ZyYW1lKCk7Ci0KLSAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShtX3N0YWNrRnJhbWUpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gWXVjay4gIEp1c3QgdG8gc2h1dCB1cCB0aGUgY29tcGlsZXIhCi0gICAgICB2YXJzID0gbnVsbDsKLSAgICAgIHNhdmVkU3RhcnQgPSAwOwotICAgIH0KLSAgICAKLSAgICB0cnkKLSAgICB7Ci0gICAgICBkbwotICAgICAgewotICAgICAgICBuZXh0ID0gZ2V0TmV4dE5vZGUoKTsKLSAgCi0gICAgICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgICAgICB7Ci0gICAgICAgICAgaWYoRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVCA9PSBhY2NlcHROb2RlKG5leHQpKQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgd2hpbGUgKG5leHQgIT0gRFRNLk5VTEwpOwotICAKLSAgICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgICAgewotICAgICAgICBpZiAobnVsbCAhPSBtX2NhY2hlZE5vZGVzKQotICAgICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChtX2xhc3RGZXRjaGVkKTsKLSAgCi0gICAgICAgIG1fbmV4dCsrOwotICAKLSAgICAgICAgcmV0dXJuIG5leHQ7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fZm91bmRMYXN0ID0gdHJ1ZTsKLSAgCi0gICAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICAgIH0KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGlmICgtMSAhPSBtX3N0YWNrRnJhbWUpCi0gICAgICB7Ci0gICAgICAgIC8vIFRoZXNlIHR3byBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgICAgICB2YXJzLnNldFN0YWNrRnJhbWUoc2F2ZWRTdGFydCk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBleGVjQ29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0gICAgbV90cmF2ZXJzZXIgPSBtX2NkdG0uZ2V0QXhpc1RyYXZlcnNlcihBeGlzLkNISUxEKTsKLSAgICAKLS8vICAgIFN0cmluZyBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUoKTsKLS8vICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoKTsKLS8vICAgIGludCB3aGF0ID0gbV93aGF0VG9TaG93OwotLy8gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJ3aGF0OiAiKTsKLS8vICAgIC8vIE5vZGVUZXN0LmRlYnVnV2hhdFRvU2hvdyh3aGF0KTsKLS8vICAgIGlmKERUTUZpbHRlci5TSE9XX0FMTCA9PSB3aGF0IHx8Ci0vLyAgICAgICAoKERUTUZpbHRlci5TSE9XX0VMRU1FTlQgJiB3aGF0KSA9PSAwKQotLy8gICAgICAgfHwgbG9jYWxOYW1lID09IE5vZGVUZXN0LldJTEQKLS8vICAgICAgIHx8IG5hbWVzcGFjZSA9PSBOb2RlVGVzdC5XSUxEKQotLy8gICAgewotLy8gICAgICBtX2V4dGVuZGVkVHlwZUlEID0gMDsKLS8vICAgIH0KLS8vICAgIGVsc2UKLS8vICAgIHsKLS8vICAgICAgaW50IHR5cGUgPSBnZXROb2RlVHlwZVRlc3Qod2hhdCk7Ci0vLyAgICAgIG1fZXh0ZW5kZWRUeXBlSUQgPSBtX2NkdG0uZ2V0RXhwYW5kZWRUeXBlSUQobmFtZXNwYWNlLCBsb2NhbE5hbWUsIHR5cGUpOwotLy8gICAgfQotICAgIAotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqIAotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZSAKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzLkNISUxEOwotICB9Ci0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9Db250ZXh0Tm9kZUxpc3QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQ29udGV4dE5vZGVMaXN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwZTk0YTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9Db250ZXh0Tm9kZUxpc3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE3MiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBDbGFzc2VzIHdobyBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgY2FuIGJlIGEKLSAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlLWxpc3QiPmN1cnJlbnQgbm9kZSBsaXN0PC9hPiwKLSAqIGFsc28gcmVmZXJlZCB0byBoZXJlIGFzIGEgPHRlcm0+Y29udGV4dCBub2RlIGxpc3Q8L3Rlcm0+LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbnRleHROb2RlTGlzdAotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+LgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IG5vZGUsIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgTm9kZSBnZXRDdXJyZW50Tm9kZSgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIHdoaWNoIGlzIG9uZSBsZXNzIHRoYW4KLSAgICogdGhlIG5leHQgbmV4dE5vZGUoKSBjYWxsIHdpbGwgcmV0cmlldmUuICBpLmUuIGlmCi0gICAqIHlvdSBjYWxsIGdldEN1cnJlbnRQb3MoKSBhbmQgdGhlIHJldHVybiBpcyAwLCB0aGUgbmV4dAotICAgKiBmZXRjaCB3aWxsIHRha2UgcGxhY2UgYXQgaW5kZXggMS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjZHQtY3VycmVudC1ub2RlIj5jdXJyZW50IG5vZGU8L2E+Ci0gICAqIGluIHRoZSAgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdC1jdXJyZW50LW5vZGUtbGlzdCI+Y3VycmVudCBub2RlIGxpc3Q8L2E+LgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50UG9zKCk7Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCk7Ci0KLSAgLyoqCi0gICAqIElmIHNldFNob3VsZENhY2hlTm9kZXModHJ1ZSkgaXMgY2FsbGVkLCB0aGVuIG5vZGVzIHdpbGwKLSAgICogYmUgY2FjaGVkLiAgVGhleSBhcmUgbm90IGNhY2hlZCBieSBkZWZhdWx0LgotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoZSBub2RlcyBzaG91bGQgYmUgY2FjaGVkLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U2hvdWxkQ2FjaGVOb2Rlcyhib29sZWFuIGIpOwotCi0gIC8qKgotICAgKiBJZiBhbiBpbmRleCBpcyByZXF1ZXN0ZWQsIE5vZGVTZXREVE0gd2lsbCBjYWxsIHRoaXMgbWV0aG9kCi0gICAqIHRvIHJ1biB0aGUgaXRlcmF0b3IgdG8gdGhlIGluZGV4LiAgQnkgZGVmYXVsdCB0aGlzIHNldHMKLSAgICogbV9uZXh0IHRvIHRoZSBpbmRleC4gIElmIHRoZSBpbmRleCBhcmd1bWVudCBpcyAtMSwgdGhpcwotICAgKiBzaWduYWxzIHRoYXQgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4gdG8gdGhlIGVuZC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBydW4gdG8sIG9yIC0xIGlmIHRoZSBpdGVyYXRvciBzaG91bGQgYmUgcnVuCi0gICAqICAgICAgICAgICAgICB0byB0aGUgZW5kLgotICAgKi8KLSAgcHVibGljIHZvaWQgcnVuVG8oaW50IGluZGV4KTsKLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBub2RlIHNldC4KLSAgICogQHBhcmFtIGkgTXVzdCBiZSBhIHZhbGlkIGluZGV4LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudFBvcyhpbnQgaSk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2Ygbm9kZXMgaW4gdGhpcyBub2RlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IHNpemUoKTsKLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBOb2RlU2V0RFRNIGlzICJmcmVzaCIsIGluIG90aGVyIHdvcmRzLCBpZgotICAgKiB0aGUgZmlyc3QgbmV4dE5vZGUoKSB0aGF0IGlzIGNhbGxlZCB3aWxsIHJldHVybiB0aGUKLSAgICogZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGl0ZXJhdGlvbiBvZiB0aGlzIGxpc3QgaGFzIG5vdCB5ZXQgYmVndW4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0ZyZXNoKCk7Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgaXRlcmF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIEEgY2xvbmUgb2YgdGhpcyBpdGVyYXRpb24gdGhhdCBoYXMgYmVlbiByZXNldC4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVJdGVyYXRvciBjbG9uZVdpdGhSZXNldCgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKLQotICAvKioKLSAgICogR2V0IGEgY2xvbmUgb2YgdGhpcyBpdGVyYXRvci4gIEJlIGF3YXJlIHRoYXQgdGhpcyBvcGVyYXRpb24gbWF5IGJlCi0gICAqIHNvbWV3aGF0IGV4cGVuc2l2ZS4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgaW4gdGhpcyBsaXN0LgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoaXMgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdCgpOwotCi0gIC8qKgotICAgKiBTZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgaW4gdGhpcyBsaXN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGFzdCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSBpbiB0aGlzIGxpc3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMYXN0KGludCBsYXN0KTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvRGVzY2VuZGFudEl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL0Rlc2NlbmRhbnRJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NTZkYzZjLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvRGVzY2VuZGFudEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw0MjcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5heGVzOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLk9wQ29kZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1BeGlzVHJhdmVyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIG9wdGltaXplZCBpdGVyYXRvciBmb3IKLSAqIGRlc2NlbmRhbnQsIGRlc2NlbmRhbnQtb3Itc2VsZiwgb3IgIi8vZm9vIiBwYXR0ZXJucy4KLSAqIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5heGVzLldhbGtlckZhY3RvcnkjbmV3TG9jUGF0aEl0ZXJhdG9yCi0gKi8KLXB1YmxpYyBjbGFzcyBEZXNjZW5kYW50SXRlcmF0b3IgZXh0ZW5kcyBMb2NQYXRoSXRlcmF0b3IKLXsKLSAgLyoqCi0gICAqIENyZWF0ZSBhIERlc2NlbmRhbnRJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBEZXNjZW5kYW50SXRlcmF0b3IoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMsIGZhbHNlKTsKLQotICAgIGludCBvcHNbXSA9IGNvbXBpbGVyLmdldE9wTWFwKCk7Ci0gICAgaW50IGZpcnN0U3RlcFBvcyA9IGNvbXBpbGVyLmdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotICAgIGludCBzdGVwVHlwZSA9IG9wc1tmaXJzdFN0ZXBQb3NdOwotCi0gICAgYm9vbGVhbiBvclNlbGYgPSAoT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTX09SX1NFTEYgPT0gc3RlcFR5cGUpOwotICAgIGJvb2xlYW4gZnJvbVJvb3QgPSBmYWxzZTsKLSAgICBpZiAoT3BDb2Rlcy5GUk9NX1NFTEYgPT0gc3RlcFR5cGUpCi0gICAgewotICAgICAgb3JTZWxmID0gdHJ1ZTsKLSAgICAgIC8vIGZpcnN0U3RlcFBvcyArPSA4OwotICAgIH0KLSAgICBlbHNlIGlmKE9wQ29kZXMuRlJPTV9ST09UID09IHN0ZXBUeXBlKQotICAgIHsKLSAgICAgIGZyb21Sb290ID0gdHJ1ZTsKLSAgICAgIC8vIFVnbHkgY29kZS4uLiB3aWxsIGdvIGF3YXkgd2hlbiBBU1Qgd29yayBpcyBkb25lLgotICAgICAgaW50IG5leHRTdGVwUG9zID0gY29tcGlsZXIuZ2V0TmV4dFN0ZXBQb3MoZmlyc3RTdGVwUG9zKTsKLSAgICAgIGlmKG9wc1tuZXh0U3RlcFBvc10gPT0gT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTX09SX1NFTEYpCi0gICAgICAgIG9yU2VsZiA9IHRydWU7Ci0gICAgICAvLyBmaXJzdFN0ZXBQb3MgKz0gODsKLSAgICB9Ci0gICAgCi0gICAgLy8gRmluZCB0aGUgcG9zaXRpb24gb2YgdGhlIGxhc3Qgc3RlcC4KLSAgICBpbnQgbmV4dFN0ZXBQb3MgPSBmaXJzdFN0ZXBQb3M7Ci0gICAgd2hpbGUodHJ1ZSkKLSAgICB7Ci0gICAgICBuZXh0U3RlcFBvcyA9IGNvbXBpbGVyLmdldE5leHRTdGVwUG9zKG5leHRTdGVwUG9zKTsKLSAgICAgIGlmKG5leHRTdGVwUG9zID4gMCkKLSAgICAgIHsKLSAgICAgICAgaW50IHN0ZXBPcCA9IGNvbXBpbGVyLmdldE9wKG5leHRTdGVwUG9zKTsKLSAgICAgICAgaWYoT3BDb2Rlcy5FTkRPUCAhPSBzdGVwT3ApCi0gICAgICAgICAgZmlyc3RTdGVwUG9zID0gbmV4dFN0ZXBQb3M7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgYnJlYWs7Ci0gICAgICAKLSAgICB9Ci0gICAgCi0gICAgLy8gRml4IGZvciBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTEzMzYKLSAgICBpZigoYW5hbHlzaXMgJiBXYWxrZXJGYWN0b3J5LkJJVF9DSElMRCkgIT0gMCkKLSAgICAgIG9yU2VsZiA9IGZhbHNlOwotICAgICAgCi0gICAgaWYoZnJvbVJvb3QpCi0gICAgewotICAgICAgaWYob3JTZWxmKQotICAgICAgICBtX2F4aXMgPSBBeGlzLkRFU0NFTkRBTlRTT1JTRUxGRlJPTVJPT1Q7Ci0gICAgICBlbHNlCi0gICAgICAgIG1fYXhpcyA9IEF4aXMuREVTQ0VOREFOVFNGUk9NUk9PVDsKLSAgICB9Ci0gICAgZWxzZSBpZihvclNlbGYpCi0gICAgICBtX2F4aXMgPSBBeGlzLkRFU0NFTkRBTlRPUlNFTEY7Ci0gICAgZWxzZQotICAgICAgbV9heGlzID0gQXhpcy5ERVNDRU5EQU5UOwotCi0gICAgaW50IHdoYXRUb1Nob3cgPSBjb21waWxlci5nZXRXaGF0VG9TaG93KGZpcnN0U3RlcFBvcyk7Ci0KLSAgICBpZiAoKDAgPT0gKHdoYXRUb1Nob3cKLSAgICAgICAgICAgICAgICYgKERUTUZpbHRlci5TSE9XX0FUVFJJQlVURSB8IERUTUZpbHRlci5TSE9XX0VMRU1FTlQKLSAgICAgICAgICAgICAgICAgIHwgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikpKSB8fCAKLSAgICAgICAgICAgICAgICAgICAod2hhdFRvU2hvdyA9PSBEVE1GaWx0ZXIuU0hPV19BTEwpKQotICAgICAgaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3cpOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbml0Tm9kZVRlc3Qod2hhdFRvU2hvdywgY29tcGlsZXIuZ2V0U3RlcE5TKGZpcnN0U3RlcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlci5nZXRTdGVwTG9jYWxOYW1lKGZpcnN0U3RlcFBvcykpOwotICAgIH0KLSAgICBpbml0UHJlZGljYXRlSW5mbyhjb21waWxlciwgZmlyc3RTdGVwUG9zKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhIERlc2NlbmRhbnRJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRGVzY2VuZGFudEl0ZXJhdG9yKCkKLSAgewotICAgIHN1cGVyKG51bGwpOwotICAgIG1fYXhpcyA9IEF4aXMuREVTQ0VOREFOVFNPUlNFTEZGUk9NUk9PVDsKLSAgICBpbnQgd2hhdFRvU2hvdyA9IERUTUZpbHRlci5TSE9XX0FMTDsKLSAgICBpbml0Tm9kZVRlc3Qod2hhdFRvU2hvdyk7Ci0gIH0KLQotICAKLSAgLyoqCi0gICAqICBHZXQgYSBjbG9uZWQgSXRlcmF0b3IgdGhhdCBpcyByZXNldCB0byB0aGUgYmVnaW5uaW5nCi0gICAqICBvZiB0aGUgcXVlcnkuCi0gICAqIAotICAgKiAgQHJldHVybiBBIGNsb25lZCBOb2RlSXRlcmF0b3Igc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgcXVlcnkuCi0gICAqIAotICAgKiAgQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNsb25lV2l0aFJlc2V0KCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIERlc2NlbmRhbnRJdGVyYXRvciBjbG9uZSA9IChEZXNjZW5kYW50SXRlcmF0b3IpIHN1cGVyLmNsb25lV2l0aFJlc2V0KCk7Ci0KLSAgICBjbG9uZS5yZXNldFByb3hpbWl0eVBvc2l0aW9ucygpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqCi0gICAqIEB0aHJvd3MgRE9NRXhjZXB0aW9uCi0gICAqICAgIElOVkFMSURfU1RBVEVfRVJSOiBSYWlzZWQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyIHRoZQotICAgKiAgIDxjb2RlPmRldGFjaDwvY29kZT4gbWV0aG9kIHdhcyBpbnZva2VkLgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLSAgICAvLyBJZiB0aGUgY2FjaGUgaXMgb24sIGFuZCB0aGUgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIGZvdW5kLCB0aGVuIAotICAgIC8vIGp1c3QgcmV0dXJuIGZyb20gdGhlIGxpc3QuCi0gICAgLy8gSWYgdGhlIGNhY2hlIGlzIG9uLCBhbmQgdGhlIG5vZGUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdGhlbiAKLSAgICAvLyBqdXN0IHJldHVybiBmcm9tIHRoZSBsaXN0LgotICAgIGlmICgobnVsbCAhPSBtX2NhY2hlZE5vZGVzKQotICAgICAgICAgICAgJiYgKG1fbmV4dCA8IG1fY2FjaGVkTm9kZXMuc2l6ZSgpKSkKLSAgICB7Ci0gICAgICBpbnQgbmV4dCA9IG1fY2FjaGVkTm9kZXMuZWxlbWVudEF0KG1fbmV4dCk7Ci0gICAgCi0gICAgICBpbmNyZW1lbnROZXh0UG9zaXRpb24oKTsKLSAgICAgIG1fY3VycmVudENvbnRleHROb2RlID0gbmV4dDsKLQotICAgICAgcmV0dXJuIG5leHQ7Ci0gICAgfQotCi0gICAgaWYgKG1fZm91bmRMYXN0KQotICAgIHsKLSAgICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLSAgICB9Ci0gICAgICAKLSAgICBpZihEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgIHsKLSAgICAgIHJlc2V0UHJveGltaXR5UG9zaXRpb25zKCk7Ci0gICAgfQotCi0gICAgaW50IG5leHQ7Ci0gICAgCi0gICAgb3JnLmFwYWNoZS54cGF0aC5WYXJpYWJsZVN0YWNrIHZhcnM7Ci0gICAgaW50IHNhdmVkU3RhcnQ7Ci0gICAgaWYgKC0xICE9IG1fc3RhY2tGcmFtZSkKLSAgICB7Ci0gICAgICB2YXJzID0gbV9leGVjQ29udGV4dC5nZXRWYXJTdGFjaygpOwotCi0gICAgICAvLyBUaGVzZSB0aHJlZSBzdGF0ZW1lbnRzIG5lZWQgdG8gYmUgY29tYmluZWQgaW50byBvbmUgb3BlcmF0aW9uLgotICAgICAgc2F2ZWRTdGFydCA9IHZhcnMuZ2V0U3RhY2tGcmFtZSgpOwotCi0gICAgICB2YXJzLnNldFN0YWNrRnJhbWUobV9zdGFja0ZyYW1lKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIFl1Y2suICBKdXN0IHRvIHNodXQgdXAgdGhlIGNvbXBpbGVyIQotICAgICAgdmFycyA9IG51bGw7Ci0gICAgICBzYXZlZFN0YXJ0ID0gMDsKLSAgICB9Ci0gICAgCi0gICAgdHJ5Ci0gICAgewotICAgICAgZG8KLSAgICAgIHsKLSAgICAgICAgaWYoMCA9PSBtX2V4dGVuZGVkVHlwZUlEKQotICAgICAgICB7Ci0gICAgICAgICAgbmV4dCA9IG1fbGFzdEZldGNoZWQgPSAoRFRNLk5VTEwgPT0gbV9sYXN0RmV0Y2hlZCkKLSAgICAgICAgICAgICAgICAgICAgICAgPyBtX3RyYXZlcnNlci5maXJzdChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICAgIDogbV90cmF2ZXJzZXIubmV4dChtX2NvbnRleHQsIG1fbGFzdEZldGNoZWQpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG5leHQgPSBtX2xhc3RGZXRjaGVkID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgICAgICAgICAgICAgICAgICAgID8gbV90cmF2ZXJzZXIuZmlyc3QobV9jb250ZXh0LCBtX2V4dGVuZGVkVHlwZUlEKQotICAgICAgICAgICAgICAgICAgICAgICA6IG1fdHJhdmVyc2VyLm5leHQobV9jb250ZXh0LCBtX2xhc3RGZXRjaGVkLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZXh0ZW5kZWRUeXBlSUQpOwotICAgICAgICB9Ci0gIAotICAgICAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dCkKLSAgICAgICAgewotICAgICAgICAgIGlmKERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQgPT0gYWNjZXB0Tm9kZShuZXh0KSkKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICAgIHdoaWxlIChuZXh0ICE9IERUTS5OVUxMKTsKLSAgCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dCkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgIT0gbV9jYWNoZWROb2RlcykKLSAgICAgICAgICBtX2NhY2hlZE5vZGVzLmFkZEVsZW1lbnQobV9sYXN0RmV0Y2hlZCk7Ci0gIAotICAgICAgICBtX25leHQrKzsKLSAgCi0gICAgICAgIHJldHVybiBuZXh0OwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7Ci0gIAotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICB9Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBpZiAoLTEgIT0gbV9zdGFja0ZyYW1lKQotICAgICAgewotICAgICAgICAvLyBUaGVzZSB0d28gc3RhdGVtZW50cyBuZWVkIHRvIGJlIGNvbWJpbmVkIGludG8gb25lIG9wZXJhdGlvbi4KLSAgICAgICAgdmFycy5zZXRTdGFja0ZyYW1lKHNhdmVkU3RhcnQpOwotICAgICAgfQotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvbnRleHQgdmFsdWVzIGZvciB0aGlzIGV4cHJlc3Npb24KLSAgICogYWZ0ZXIgaXQgaXMgY2xvbmVkLgotICAgKgotICAgKiBAcGFyYW0gZXhlY0NvbnRleHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCBmb3IgdGhpcwotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IGNvbnRleHQsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotICAgIHN1cGVyLnNldFJvb3QoY29udGV4dCwgZW52aXJvbm1lbnQpOwotICAgIG1fdHJhdmVyc2VyID0gbV9jZHRtLmdldEF4aXNUcmF2ZXJzZXIobV9heGlzKTsKLSAgICAKLSAgICBTdHJpbmcgbG9jYWxOYW1lID0gZ2V0TG9jYWxOYW1lKCk7Ci0gICAgU3RyaW5nIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSgpOwotICAgIGludCB3aGF0ID0gbV93aGF0VG9TaG93OwotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigid2hhdDogIik7Ci0gICAgLy8gTm9kZVRlc3QuZGVidWdXaGF0VG9TaG93KHdoYXQpOwotICAgIGlmKERUTUZpbHRlci5TSE9XX0FMTCA9PSB3aGF0Ci0gICAgICAgfHwgbG9jYWxOYW1lID09IE5vZGVUZXN0LldJTEQKLSAgICAgICB8fCBuYW1lc3BhY2UgPT0gTm9kZVRlc3QuV0lMRCkKLSAgICB7Ci0gICAgICBtX2V4dGVuZGVkVHlwZUlEID0gMDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGVUZXN0KHdoYXQpOwotICAgICAgbV9leHRlbmRlZFR5cGVJRCA9IG1fY2R0bS5nZXRFeHBhbmRlZFR5cGVJRChuYW1lc3BhY2UsIGxvY2FsTmFtZSwgdHlwZSk7Ci0gICAgfQotICAgIAotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgaWYgdGhpcyBleHByZXNzaW9uIGlzIAotICAgKiBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIAotICAgKiBub2Rlc2V0cy4KLSAgICogPHA+V0FSTklORzogRG8gbm90IG11dGF0ZSB0aGlzIGNsYXNzIGZyb20gdGhpcyBmdW5jdGlvbiE8L3A+Ci0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwdWJsaWMgaW50IGFzTm9kZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmKGdldFByZWRpY2F0ZUNvdW50KCkgPiAwKQotICAgICAgcmV0dXJuIHN1cGVyLmFzTm9kZSh4Y3R4dCk7Ci0KLSAgICBpbnQgY3VycmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgCi0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjdXJyZW50KTsKLSAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKG1fYXhpcyk7Ci0gICAgCi0gICAgU3RyaW5nIGxvY2FsTmFtZSA9IGdldExvY2FsTmFtZSgpOwotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoKTsKLSAgICBpbnQgd2hhdCA9IG1fd2hhdFRvU2hvdzsKLSAgICAKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50KCIgKERlc2NlbmRhbnRJdGVyYXRvcikgIik7Ci0gICAgCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJ3aGF0OiAiKTsKLSAgICAvLyBOb2RlVGVzdC5kZWJ1Z1doYXRUb1Nob3cod2hhdCk7Ci0gICAgaWYoRFRNRmlsdGVyLlNIT1dfQUxMID09IHdoYXQKLSAgICAgICB8fCBsb2NhbE5hbWUgPT0gTm9kZVRlc3QuV0lMRAotICAgICAgIHx8IG5hbWVzcGFjZSA9PSBOb2RlVGVzdC5XSUxEKQotICAgIHsKLSAgICAgIHJldHVybiB0cmF2ZXJzZXIuZmlyc3QoY3VycmVudCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgdHlwZSA9IGdldE5vZGVUeXBlVGVzdCh3aGF0KTsKLSAgICAgIGludCBleHRlbmRlZFR5cGUgPSBkdG0uZ2V0RXhwYW5kZWRUeXBlSUQobmFtZXNwYWNlLCBsb2NhbE5hbWUsIHR5cGUpOwotICAgICAgcmV0dXJuIHRyYXZlcnNlci5maXJzdChjdXJyZW50LCBleHRlbmRlZFR5cGUpOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqICBEZXRhY2hlcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkIG92ZXIsIHJlbGVhc2luZwotICAgKiBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yIGluIHRoZSBJTlZBTElECi0gICAqIHN0YXRlLiBBZnRlcjxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwgY2FsbHMgdG8KLSAgICogPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yPGNvZGU+cHJldmlvdXNOb2RlPC9jb2RlPiB3aWxsIHJhaXNlIHRoZQotICAgKiBleGNlcHRpb24gSU5WQUxJRF9TVEFURV9FUlIuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKQotICB7ICAgIAotICAgIG1fdHJhdmVyc2VyID0gbnVsbDsgICAgCi0gICAgbV9leHRlbmRlZFR5cGVJRCA9IDA7Ci0gICAgCi0gICAgLy8gQWx3YXlzIGNhbGwgdGhlIHN1cGVyY2xhc3MgZGV0YWNoIGxhc3QhCi0gICAgc3VwZXIuZGV0YWNoKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICogCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlIAotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gbV9heGlzOwotICB9Ci0KLSAgCi0gIC8qKiBUaGUgdHJhdmVyc2VyIHRvIHVzZSB0byBuYXZpZ2F0ZSBvdmVyIHRoZSBkZXNjZW5kYW50cy4gKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBEVE1BeGlzVHJhdmVyc2VyIG1fdHJhdmVyc2VyOwotICAKLSAgLyoqIFRoZSBheGlzIHRoYXQgd2UgYXJlIHRyYXZlcnNpbmcuICovCi0gIHByb3RlY3RlZCBpbnQgbV9heGlzOwotICAKLSAgLyoqIFRoZSBleHRlbmRlZCB0eXBlIElELCBub3Qgc2V0IHVudGlsIHNldFJvb3QuICovCi0gIHByb3RlY3RlZCBpbnQgbV9leHRlbmRlZFR5cGVJRDsKLSAgCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL0ZpbHRlckV4cHJXYWxrZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvRmlsdGVyRXhwcldhbGtlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNjczMzViLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvRmlsdGVyRXhwcldhbGtlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzA2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguYXhlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Mb2NQYXRoSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5WYXJpYWJsZVN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5PcENvZGVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3RGaWx0ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpczsKLQotLyoqCi0gKiBXYWxrZXIgZm9yIHRoZSBPUF9WQVJJQUJMRSwgb3IgT1BfRVhURlVOQ1RJT04sIG9yIE9QX0ZVTkNUSU9OLCBvciBPUF9HUk9VUCwKLSAqIG9wIGNvZGVzLgotICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNOVC1GaWx0ZXJFeHByIj5YUGF0aCBGaWx0ZXJFeHByIGRlc2NyaXB0aW9uczwvYT4KLSAqLwotcHVibGljIGNsYXNzIEZpbHRlckV4cHJXYWxrZXIgZXh0ZW5kcyBBeGVzV2Fsa2VyCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEZpbHRlckV4cHJXYWxrZXIgdXNpbmcgYSBMb2NQYXRoSXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBsb2NQYXRoSXRlcmF0b3Igbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBwYXJlbnQgaXRlcmF0b3IuCi0gICAqLwotICBGaWx0ZXJFeHByV2Fsa2VyKFdhbGtpbmdJdGVyYXRvciBsb2NQYXRoSXRlcmF0b3IpCi0gIHsKLSAgICBzdXBlcihsb2NQYXRoSXRlcmF0b3IsIEF4aXMuRklMVEVSRURMSVNUKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0IGEgRmlsdGVyRXhwcldhbGtlci4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBpcyBjb25zdHJ1Y3RpbmcuCi0gICAqIEBwYXJhbSBvcFBvcyBwb3NpdGl2ZSBvcGNvZGUgcG9zaXRpb24gZm9yIHRoaXMgc3RlcC4KLSAgICogQHBhcmFtIHN0ZXBUeXBlIFRoZSB0eXBlIG9mIHN0ZXAuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5pdChDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgc3RlcFR5cGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIuaW5pdChjb21waWxlciwgb3BQb3MsIHN0ZXBUeXBlKTsKLQotICAgIC8vIFNtb290aCBvdmVyIGFuIGFub21pbHkgaW4gdGhlIG9wY29kZSBtYXAuLi4KLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgbV9leHByID0gY29tcGlsZXIuY29tcGlsZShvcFBvcyk7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIG1fZXhwciA9IGNvbXBpbGVyLmNvbXBpbGUob3BQb3MgKyAyKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogIFNldCB0aGUgcm9vdCBub2RlIG9mIHRoZSBUcmVlV2Fsa2VyLgotICAgKgotICAgKiBAcGFyYW0gcm9vdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QsIG9yIHN0YXJ0aW5nIHBvaW50IG9mIAotICAgKiAgICAgICAgdGhlIHF1ZXJ5LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgcm9vdCkKLSAgewotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJyb290OiAiK3Jvb3QpOwotICAgIFhQYXRoQ29udGV4dCB4Y3R4dCA9IG1fbHBpLmdldFhQYXRoQ29udGV4dCgpOwotICAgIFByZWZpeFJlc29sdmVyIHNhdmVkUmVzb2x2ZXIgPSB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUocm9vdCk7Ci0gICAgICB4Y3R4dC5zZXROYW1lc3BhY2VDb250ZXh0KG1fbHBpLmdldFByZWZpeFJlc29sdmVyKCkpOwotICAgICAgCi0gICAgICAvLyBUaGUgc2V0Um9vdCBvcGVyYXRpb24gY2FuIHRha2UgcGxhY2Ugd2l0aCBhIHJlc2V0IG9wZXJhdGlvbiwgCi0gICAgICAvLyBhbmQgc28gd2UgbWF5IG5vdCBiZSBpbiB0aGUgY29udGV4dCBvZiBMb2NQYXRoSXRlcmF0b3IjbmV4dE5vZGUsIAotICAgICAgLy8gc28gd2UgaGF2ZSB0byBzZXQgdXAgdGhlIHZhcmlhYmxlIGNvbnRleHQsIGV4ZWN1dGUgdGhlIGV4cHJlc3Npb24sIAotICAgICAgLy8gYW5kIHRoZW4gcmVzdG9yZSB0aGUgdmFyaWFibGUgY29udGV4dC4KLQotICAgICAgaWYobV9scGkuZ2V0SXNUb3BMZXZlbCgpKQotICAgICAgewotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImNhbGxpbmcgbV9leHByLmV4ZWN1dGUobV9scGkuZ2V0WFBhdGhDb250ZXh0KCkpIik7Ci0gICAgICAgIFZhcmlhYmxlU3RhY2sgdmFycyA9IG1fbHBpLm1fZXhlY0NvbnRleHQuZ2V0VmFyU3RhY2soKTsKLSAgICAgICAgCi0gICAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICAgIGludCBzYXZlZFN0YXJ0ID0gdmFycy5nZXRTdGFja0ZyYW1lKCk7Ci0gICAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShtX2xwaS5tX3N0YWNrRnJhbWUpOwotICAgICAgICAKLSAgICAgICAgbV9ub2RlU2V0ID0gbV9leHByLmFzSXRlcmF0b3IoeGN0eHQsIHJvb3QpOwotICAgICAgICAKLSAgICAgICAgLy8gVGhlc2UgdHdvIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICAgIHZhcnMuc2V0U3RhY2tGcmFtZShzYXZlZFN0YXJ0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgbV9ub2RlU2V0ID0gbV9leHByLmFzSXRlcmF0b3IoeGN0eHQsIHJvb3QpOwotICAgICAgICAgICAgCi0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gVE9ETzogRml4Li4uCi0gICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oc2UpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIHhjdHh0LnNldE5hbWVzcGFjZUNvbnRleHQoc2F2ZWRSZXNvbHZlcik7Ci0gICAgfQotCi0gICAgc3VwZXIuc2V0Um9vdChyb290KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgRmlsdGVyRXhwcldhbGtlci4KLSAgICoKLSAgICogQHJldHVybiBBIG5ldyBGaWx0ZXJFeHByV2Fsa2VyIHRoYXQgY2FuIGJlIHVzZWQgd2l0aG91dCBtdXRhdGluZyB0aGlzIG9uZS4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICB7Ci0KLSAgICBGaWx0ZXJFeHByV2Fsa2VyIGNsb25lID0gKEZpbHRlckV4cHJXYWxrZXIpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICAvLyBjbG9uZS5tX2V4cHIgPSAoRXhwcmVzc2lvbikoKEV4cHJlc3Npb24pbV9leHByKS5jbG9uZSgpOwotICAgIGlmIChudWxsICE9IG1fbm9kZVNldCkKLSAgICAgIGNsb25lLm1fbm9kZVNldCA9IChEVE1JdGVyYXRvcikgbV9ub2RlU2V0LmNsb25lKCk7Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBtZXRob2QgbmVlZHMgdG8gb3ZlcnJpZGUgQXhlc1dhbGtlci5hY2NlcHROb2RlIGJlY2F1c2UgRmlsdGVyRXhwcldhbGtlcnMKLSAgICogZG9uJ3QgbmVlZCB0bywgYW5kIHNob3VsZG4ndCwgZG8gYSBub2RlIHRlc3QuCi0gICAqIEBwYXJhbSBuICBUaGUgbm9kZSB0byBjaGVjayB0byBzZWUgaWYgaXQgcGFzc2VzIHRoZSBmaWx0ZXIgb3Igbm90LgotICAgKiBAcmV0dXJuICBhIGNvbnN0YW50IHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBub2RlIGlzIGFjY2VwdGVkLAotICAgKiAgIHJlamVjdGVkLCBvciBza2lwcGVkLCBhcyBkZWZpbmVkICBhYm92ZSAuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShpbnQgbikKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaWYgKGdldFByZWRpY2F0ZUNvdW50KCkgPiAwKQotICAgICAgewotICAgICAgICBjb3VudFByb3hpbWl0eVBvc2l0aW9uKDApOwotCi0gICAgICAgIGlmICghZXhlY3V0ZVByZWRpY2F0ZXMobiwgbV9scGkuZ2V0WFBhdGhDb250ZXh0KCkpKQotICAgICAgICAgIHJldHVybiBEVE1JdGVyYXRvci5GSUxURVJfU0tJUDsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQ7Ci0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqICBNb3ZlcyB0aGUgPGNvZGU+VHJlZVdhbGtlcjwvY29kZT4gdG8gdGhlIG5leHQgdmlzaWJsZSBub2RlIGluIGRvY3VtZW50Ci0gICAqIG9yZGVyIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IG5vZGUsIGFuZCByZXR1cm5zIHRoZSBuZXcgbm9kZS4gSWYgdGhlCi0gICAqIGN1cnJlbnQgbm9kZSBoYXMgbm8gbmV4dCBub2RlLCAgb3IgaWYgdGhlIHNlYXJjaCBmb3IgbmV4dE5vZGUgYXR0ZW1wdHMKLSAgICogdG8gc3RlcCB1cHdhcmQgZnJvbSB0aGUgVHJlZVdhbGtlcidzIHJvb3Qgbm9kZSwgcmV0dXJucwotICAgKiA8Y29kZT5udWxsPC9jb2RlPiAsIGFuZCByZXRhaW5zIHRoZSBjdXJyZW50IG5vZGUuCi0gICAqIEByZXR1cm4gIFRoZSBuZXcgbm9kZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgbm8KLSAgICogICBuZXh0IG5vZGUgIGluIHRoZSBUcmVlV2Fsa2VyJ3MgbG9naWNhbCB2aWV3LgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0Tm9kZSgpCi0gIHsKLQotICAgIGlmIChudWxsICE9IG1fbm9kZVNldCkKLSAgICAgICByZXR1cm4gbV9ub2RlU2V0Lm5leHROb2RlKCk7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgcmV0dXJuIG1fbm9kZVNldC5nZXRMZW5ndGgoKTsKLSAgfQotICAKLSAgLyoqIFRoZSBjb250YWluZWQgZXhwcmVzc2lvbi4gU2hvdWxkIGJlIG5vbi1udWxsLgotICAgKiAgQHNlcmlhbCAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbiBtX2V4cHI7Ci0KLSAgLyoqIFRoZSByZXN1bHQgb2YgZXhlY3V0aW5nIG1fZXhwci4gIE5lZWRzIHRvIGJlIGRlZXAgY2xvbmVkIG9uIGNsb25lIG9wLiAgKi8KLSAgdHJhbnNpZW50IHByaXZhdGUgRFRNSXRlcmF0b3IgbV9ub2RlU2V0OwotCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBtX2V4cHIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50IAotICAgKiBvcmRlci4KLSAgICogV2FybmluZzogVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgc2V0Um9vdCBoYXMgYmVlbiBjYWxsZWQhCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgYXMgYSBkZWZhdWx0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2NPcmRlcmVkKCkKLSAgewotICAgIHJldHVybiBtX25vZGVTZXQuaXNEb2NPcmRlcmVkKCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBheGlzIGJlaW5nIGl0ZXJhdGVkLCBpZiBpdCBpcyBrbm93bi4KLSAgICogCi0gICAqIEByZXR1cm4gQXhpcy5DSElMRCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgbm90IGtub3duIG9yIGlzIG9mIG11bHRpcGxlIAotICAgKiB0eXBlcy4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXhpcygpCi0gIHsKLSAgICByZXR1cm4gbV9ub2RlU2V0LmdldEF4aXMoKTsKLSAgfQotCi0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9JdGVyYXRvclBvb2wuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvSXRlcmF0b3JQb29sLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM0YTc1YWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9JdGVyYXRvclBvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDc2ICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5heGVzOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogUG9vbCBvZiBvYmplY3Qgb2YgYSBnaXZlbiB0eXBlIHRvIHBpY2sgZnJvbSB0byBoZWxwIG1lbW9yeSB1c2FnZQotICovCi1wdWJsaWMgY2xhc3MgSXRlcmF0b3JQb29sIGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUKLXsKLQotICAvKiogVHlwZSBvZiBvYmplY3RzIGluIHRoaXMgcG9vbC4KLSAgICogIEBzZXJpYWwgICAgICAgICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBEVE1JdGVyYXRvciBtX29yaWc7Ci0KLSAgLyoqIFZlY3RvciBvZiBnaXZlbiBvYmplY3RzIHRoaXMgcG9pbnRzIHRvLgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBwcml2YXRlIGZpbmFsIFZlY3RvciBtX2ZyZWVTdGFjazsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgSXRlcmF0b3JQb29sCi0gICAqCi0gICAqIEBwYXJhbSBvcmlnaW5hbCBUaGUgb3JpZ2luYWwgaXRlcmF0b3IgZnJvbSB3aGljaCBhbGwgb3RoZXJzIHdpbGwgYmUgY2xvbmVkLgotICAgKi8KLSAgcHVibGljIEl0ZXJhdG9yUG9vbChEVE1JdGVyYXRvciBvcmlnaW5hbCkKLSAgewotICAgIG1fb3JpZyA9IG9yaWdpbmFsOwotICAgIG1fZnJlZVN0YWNrID0gbmV3IFZlY3RvcigpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QgaW4gdGhpcyBwb29sIAotICAgKgotICAgKiBAcmV0dXJuIEFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBzeW5jaHJvbml6ZWQgRFRNSXRlcmF0b3IgZ2V0SW5zdGFuY2UoKQotICB7Ci0KLSAgICAvLyBDaGVjayBpZiB0aGUgcG9vbCBpcyBlbXB0eS4KLSAgICBpZiAobV9mcmVlU3RhY2suaXNFbXB0eSgpKQotICAgIHsKLQotICAgICAgLy8gQ3JlYXRlIGEgbmV3IG9iamVjdCBpZiBzby4KLSAgICAgIHRyeQotICAgICAgewotICAgICAgICByZXR1cm4gKERUTUl0ZXJhdG9yKW1fb3JpZy5jbG9uZSgpOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IFdyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGV4KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIFJlbW92ZSBvYmplY3QgZnJvbSBlbmQgb2YgZnJlZSBwb29sLgotICAgICAgRFRNSXRlcmF0b3IgcmVzdWx0ID0gKERUTUl0ZXJhdG9yKW1fZnJlZVN0YWNrLmxhc3RFbGVtZW50KCk7Ci0KLSAgICAgIG1fZnJlZVN0YWNrLnNldFNpemUobV9mcmVlU3RhY2suc2l6ZSgpIC0gMSk7Ci0KLSAgICAgIHJldHVybiByZXN1bHQ7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEFkZCBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gb2JqZWN0IHRvIHRoZSBwb29sICAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG9iaiBPYmplY3QgdG8gYWRkLgotICAgKi8KLSAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZyZWVJbnN0YW5jZShEVE1JdGVyYXRvciBvYmopCi0gIHsKLSAgICBtX2ZyZWVTdGFjay5hZGRFbGVtZW50KG9iaik7Ci0gIH0KLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL0xvY1BhdGhJdGVyYXRvci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9Mb2NQYXRoSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmQxYTEyYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL0xvY1BhdGhJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA4NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLS8vIEphdmEgbGlicmFyeSBpbXBvcnRzCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBqYXZhLnV0aWwuU3RhY2s7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotCi0vLyBYYWxhbiBpbXBvcnRzCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuT3BNYXA7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLk9wQ29kZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Qc3VlZG9OYW1lczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLk5vZGVTZXREVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkludFN0YWNrOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk9iamVjdFBvb2w7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5BeGVzV2Fsa2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguVmFyaWFibGVTdGFjazsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBOb2RlU2V0RFRNLCB3aGljaCBpbXBsZW1lbnRzIE5vZGVJdGVyYXRvciwKLSAqIGFuZCBmZXRjaGVzIG5vZGVzIG9uZSBhdCBhIHRpbWUgaW4gZG9jdW1lbnQgb3JkZXIgYmFzZWQgb24gYSBYUGF0aAotICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTG9jYXRpb25QYXRoPkxvY2F0aW9uUGF0aDwvYT4uCi0gKgotICogPHA+SWYgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKSBpcyBjYWxsZWQsCi0gKiBhcyBlYWNoIG5vZGUgaXMgaXRlcmF0ZWQgdmlhIG5leHROb2RlKCksIHRoZSBub2RlIGlzIGFsc28gc3RvcmVkCi0gKiBpbiB0aGUgTm9kZVZlY3Rvciwgc28gdGhhdCBwcmV2aW91c05vZGUoKSBjYW4gZWFzaWx5IGJlIGRvbmUsIGV4Y2VwdCBpbgotICogdGhlIGNhc2Ugd2hlcmUgdGhlIExvY1BhdGhJdGVyYXRvciBpcyAib3duZWQiIGJ5IGEgVW5pb25QYXRoSXRlcmF0b3IsCi0gKiBpbiB3aGljaCBjYXNlIHRoZSBVbmlvblBhdGhJdGVyYXRvciB3aWxsIGNhY2hlIHRoZSBub2Rlcy48L3A+Ci0gKi8KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMb2NQYXRoSXRlcmF0b3IgZXh0ZW5kcyBQcmVkaWNhdGVkTm9kZVRlc3QKLSAgICAgICAgaW1wbGVtZW50cyBDbG9uZWFibGUsIERUTUl0ZXJhdG9yLCBqYXZhLmlvLlNlcmlhbGl6YWJsZQotewotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBMb2NQYXRoSXRlcmF0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gbnNjb250ZXh0IFRoZSBuYW1lc3BhY2UgY29udGV4dCBmb3IgdGhpcyBpdGVyYXRvciwKLSAgICogc2hvdWxkIGJlIE9LIGlmIG51bGwuCi0gICAqLwotICBwcm90ZWN0ZWQgTG9jUGF0aEl0ZXJhdG9yKFByZWZpeFJlc29sdmVyIG5zY29udGV4dCkKLSAgewotCi0gICAgc2V0TG9jUGF0aEl0ZXJhdG9yKHRoaXMpOwotCi0gICAgdGhpcy5tX3ByZWZpeFJlc29sdmVyID0gbnNjb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QsIGluY2x1ZGluZyBjcmVhdGlvbgotICAgKiBvZiBzdGVwIHdhbGtlcnMgZnJvbSB0aGUgb3Bjb2RlIGxpc3QsIGFuZCBjYWxsIGJhY2sKLSAgICogaW50byB0aGUgQ29tcGlsZXIgdG8gY3JlYXRlIHByZWRpY2F0ZSBleHByZXNzaW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciB3aGljaCBpcyBjcmVhdGluZwotICAgKiB0aGlzIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciBpbiB0aGUKLSAgICogb3Bjb2RlIGxpc3QgZnJvbSB0aGUgY29tcGlsZXIuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIExvY1BhdGhJdGVyYXRvcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHRoaXMoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgTG9jUGF0aEl0ZXJhdG9yIG9iamVjdCwgaW5jbHVkaW5nIGNyZWF0aW9uCi0gICAqIG9mIHN0ZXAgd2Fsa2VycyBmcm9tIHRoZSBvcGNvZGUgbGlzdCwgYW5kIGNhbGwgYmFjawotICAgKiBpbnRvIHRoZSBDb21waWxlciB0byBjcmVhdGUgcHJlZGljYXRlIGV4cHJlc3Npb25zLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZQotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICogQHBhcmFtIHNob3VsZExvYWRXYWxrZXJzIFRydWUgaWYgd2Fsa2VycyBzaG91bGQgYmUKLSAgICogbG9hZGVkLCBvciBmYWxzZSBpZiB0aGlzIGlzIGEgZGVyaXZlZCBpdGVyYXRvciBhbmQKLSAgICogaXQgZG9lc24ndCB3aXNoIHRvIGxvYWQgY2hpbGQgd2Fsa2Vycy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgTG9jUGF0aEl0ZXJhdG9yKAotICAgICAgICAgIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBhbmFseXNpcywgYm9vbGVhbiBzaG91bGRMb2FkV2Fsa2VycykKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzZXRMb2NQYXRoSXRlcmF0b3IodGhpcyk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZWFkIHRoZSBvYmplY3QgZnJvbSBhIHNlcmlhbGl6YXRpb24gc3RyZWFtLgotICAgKgotICAgKiBAcGFyYW0gc3RyZWFtIElucHV0IHN0cmVhbSB0byByZWFkIGZyb20KLSAgICoKLSAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbSBzdHJlYW0pCi0gICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24sIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIHN0cmVhbS5kZWZhdWx0UmVhZE9iamVjdCgpOwotICAgICAgbV9jbG9uZXMgPSAgbmV3IEl0ZXJhdG9yUG9vbCh0aGlzKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihjbmZlKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGVudmlyb25tZW50IGluIHdoaWNoIHRoaXMgaXRlcmF0b3Igb3BlcmF0ZXMsIHdoaWNoIHNob3VsZCBwcm92aWRlOgotICAgKiBhIG5vZGUgKHRoZSBjb250ZXh0IG5vZGUuLi4gc2FtZSB2YWx1ZSBhcyAicm9vdCIgZGVmaW5lZCBiZWxvdykgCi0gICAqIGEgcGFpciBvZiBub24temVybyBwb3NpdGl2ZSBpbnRlZ2VycyAodGhlIGNvbnRleHQgcG9zaXRpb24gYW5kIHRoZSBjb250ZXh0IHNpemUpIAotICAgKiBhIHNldCBvZiB2YXJpYWJsZSBiaW5kaW5ncyAKLSAgICogYSBmdW5jdGlvbiBsaWJyYXJ5IAotICAgKiB0aGUgc2V0IG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4gc2NvcGUgZm9yIHRoZSBleHByZXNzaW9uLgotICAgKiAKLSAgICogPHA+QXQgdGhpcyB0aW1lIHRoZSBleGFjdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGVudmlyb25tZW50IGlzIGFwcGxpY2F0aW9uIAotICAgKiBkZXBlbmRlbnQuICBQcm9iYWJseSBhIHByb3BlciBpbnRlcmZhY2Ugd2lsbCBiZSBjcmVhdGVkIGZhaXJseSBzb29uLjwvcD4KLSAgICogCi0gICAqIEBwYXJhbSBlbnZpcm9ubWVudCBUaGUgZW52aXJvbm1lbnQgb2JqZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0RW52aXJvbm1lbnQoT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgLy8gbm8tb3AgZm9yIG5vdy4KLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCBhbiBpbnN0YW5jZSBvZiBhIERUTSB0aGF0ICJvd25zIiBhIG5vZGUgaGFuZGxlLiAgU2luY2UgYSBub2RlIAotICAgKiBpdGVyYXRvciBtYXkgYmUgcGFzc2VkIHdpdGhvdXQgYSBEVE1NYW5hZ2VyLCB0aGlzIGFsbG93cyB0aGUgCi0gICAqIGNhbGxlciB0byBlYXNpbHkgZ2V0IHRoZSBEVE0gdXNpbmcganVzdCB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBub2RlSGFuZGxlIHRoZSBub2RlSGFuZGxlLgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE0gZ2V0RFRNKGludCBub2RlSGFuZGxlKQotICB7Ci0gICAgLy8gJU9QVCUKLSAgICByZXR1cm4gbV9leGVjQ29udGV4dC5nZXREVE0obm9kZUhhbmRsZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIERUTU1hbmFnZXIuICBTaW5jZSBhIG5vZGUgCi0gICAqIGl0ZXJhdG9yIG1heSBiZSBwYXNzZWQgd2l0aG91dCBhIERUTU1hbmFnZXIsIHRoaXMgYWxsb3dzIHRoZSAKLSAgICogY2FsbGVyIHRvIGVhc2lseSBnZXQgdGhlIERUTU1hbmFnZXIgdXNpbmcganVzdCB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gYSBub24tbnVsbCBEVE1NYW5hZ2VyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBEVE1NYW5hZ2VyIGdldERUTU1hbmFnZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fZXhlY0NvbnRleHQuZ2V0RFRNTWFuYWdlcigpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhpcyBpdGVyYXRvciwgbWVhbmluZyBjcmVhdGUgYSBjbG9uZSB0aGF0IGNhbgotICAgKiBzdG9yZSBzdGF0ZSwgYW5kIGluaXRpYWxpemUgaXQgZm9yIGZhc3QgZXhlY3V0aW9uIGZyb20KLSAgICogdGhlIGN1cnJlbnQgcnVudGltZSBzdGF0ZS4gIFdoZW4gdGhpcyBpcyBjYWxsZWQsIG5vIGFjdHVhbAotICAgKiBxdWVyeSBmcm9tIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBpcyBwZXJmb3JtZWQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE5vZGVTZXQgcmVmZXJlbmNlIHRoYXQgaG9sZHMgdGhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBMb2NQYXRoSXRlcmF0b3IgY2xvbmUgPSAoTG9jUGF0aEl0ZXJhdG9yKW1fY2xvbmVzLmdldEluc3RhbmNlKCk7Ci0KLSAgICBpbnQgY3VycmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgY2xvbmUuc2V0Um9vdChjdXJyZW50LCB4Y3R4dCk7Ci0KLSAgICByZXR1cm4gbmV3IFhOb2RlU2V0KGNsb25lKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJleHBlcmltZW50YWwiLz4KLSAgICogR2l2ZW4gYW4gc2VsZWN0IGV4cHJlc3Npb24gYW5kIGEgY29udGV4dCwgZXZhbHVhdGUgdGhlIFhQYXRoCi0gICAqIGFuZCByZXR1cm4gdGhlIHJlc3VsdGluZyBpdGVyYXRvci4KLSAgICogCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB0aGF0ICIuIiBleHByZXNzZXMuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IFRoZSBjb250ZXh0IGluIHdoaWNoIG5hbWVzcGFjZXMgaW4gdGhlCi0gICAqIFhQYXRoIGFyZSBzdXBwb3NlZCB0byBiZSBleHBhbmRlZC4KLSAgICogCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGRlY2lkZXMKLSAgICogdGhlIGVycm9yIGNvbmRpdGlvbiBpcyBzZXZlcmUgZW5vdWdoIHRvIGhhbHQgcHJvY2Vzc2luZy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgYXNJdGVyYXRvcigKLSAgICAgICAgICBYUGF0aENvbnRleHQgeGN0eHQsIGludCBjb250ZXh0Tm9kZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBMb2NQYXRoSXRlcmF0b3IgY2xvbmUgPSAoTG9jUGF0aEl0ZXJhdG9yKW1fY2xvbmVzLmdldEluc3RhbmNlKCk7Ci0gICAgY2xvbmUuc2V0Um9vdChjb250ZXh0Tm9kZSwgeGN0eHQpOwotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIEluIG90aGVyIHdvcmRzLCB0ZWxsIAotICAgKiBpZiB5b3UgY2FuIGV4ZWN1dGUge0BsaW5rIGFzTm9kZSgpIGFzTm9kZX0gd2l0aG91dCBhbiBleGNlcHRpb24uCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZXhwcmVzc2lvbiBjYW4gYmUgcmVwcmVzZW50ZWQgYXMgYSBub2Rlc2V0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNOb2Rlc2V0RXhwcigpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIGlmIHRoaXMgZXhwcmVzc2lvbiBpcyAKLSAgICogYSBub2Rlc2V0IGV4cHJlc3Npb24uICBUaGlzIGlzIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciAKLSAgICogbm9kZXNldHMuICBEZXJpdmVkIGNsYXNzZXMgc2hvdWxkIHRyeSBhbmQgb3ZlcnJpZGUgdGhpcyBhbmQgcmV0dXJuIGEgCi0gICAqIHZhbHVlIHdpdGhvdXQgaGF2aW5nIHRvIGRvIGEgY2xvbmUgb3BlcmF0aW9uLgotICAgKiBAcGFyYW0geGN0eHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICogQHJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIG9yIERUTS5OVUxMLgotICAgKi8KLSAgcHVibGljIGludCBhc05vZGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBEVE1JdGVyYXRvciBpdGVyID0gKERUTUl0ZXJhdG9yKW1fY2xvbmVzLmdldEluc3RhbmNlKCk7Ci0KLSAgICBpbnQgY3VycmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgCi0gICAgaXRlci5zZXRSb290KGN1cnJlbnQsIHhjdHh0KTsKLQotICAgIGludCBuZXh0ID0gaXRlci5uZXh0Tm9kZSgpOwotICAgIC8vIG1fY2xvbmVzLmZyZWVJbnN0YW5jZShpdGVyKTsKLSAgICBpdGVyLmRldGFjaCgpOwotICAgIHJldHVybiBuZXh0OwotICB9Ci0gIAotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChhc05vZGUoeGN0eHQpICE9IERUTS5OVUxMKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBTZXQgaWYgdGhpcyBpcyBhbiBpdGVyYXRvciBhdCB0aGUgdXBwZXIgbGV2ZWwgb2YKLSAgICogdGhlIFhQYXRoLgotICAgKgotICAgKiBAcGFyYW0gYiB0cnVlIGlmIHRoaXMgbG9jYXRpb24gcGF0aCBpcyBhdCB0aGUgdG9wIGxldmVsIG9mIHRoZQotICAgKiAgICAgICAgICBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0SXNUb3BMZXZlbChib29sZWFuIGIpCi0gIHsKLSAgICBtX2lzVG9wTGV2ZWwgPSBiOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBHZXQgaWYgdGhpcyBpcyBhbiBpdGVyYXRvciBhdCB0aGUgdXBwZXIgbGV2ZWwgb2YKLSAgICogdGhlIFhQYXRoLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBsb2NhdGlvbiBwYXRoIGlzIGF0IHRoZSB0b3AgbGV2ZWwgb2YgdGhlCi0gICAqICAgICAgICAgIGV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBnZXRJc1RvcExldmVsKCkKLSAgewotICAgIHJldHVybiBtX2lzVG9wTGV2ZWw7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBjb250ZXh0IHZhbHVlcyBmb3IgdGhpcyBleHByZXNzaW9uCi0gICAqIGFmdGVyIGl0IGlzIGNsb25lZC4KLSAgICoKLSAgICogQHBhcmFtIGV4ZWNDb250ZXh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQgZm9yIHRoaXMKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRSb290KGludCBjb250ZXh0LCBPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLQotICAgIG1fY29udGV4dCA9IGNvbnRleHQ7Ci0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gKFhQYXRoQ29udGV4dCllbnZpcm9ubWVudDsKLSAgICBtX2V4ZWNDb250ZXh0ID0geGN0eHQ7Ci0gICAgbV9jZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotICAgIG1fY3VycmVudENvbnRleHROb2RlID0gY29udGV4dDsKLSAgICBtX3ByZWZpeFJlc29sdmVyID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpOwotICAgICAgICAKLS8vICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLS8vICAgIG1fY3VycmVudENvbnRleHROb2RlID0gRFRNLk5VTEw7Ci0vLyAgICBtX2ZvdW5kTGFzdCA9IGZhbHNlOwotLy8gICAgbV9sYXN0ID0gMDsKLS8vICAgIG1fbmV4dCA9IDA7Ci0KLSAgICBpZiAobV9pc1RvcExldmVsKQotICAgICAgdGhpcy5tX3N0YWNrRnJhbWUgPSB4Y3R4dC5nZXRWYXJTdGFjaygpLmdldFN0YWNrRnJhbWUoKTsKLSAgICAgIAotICAgIHJlc2V0KCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBuZXh0IHBvc2l0aW9uIGluZGV4IG9mIHRoaXMgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBuZXh0IEEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHplcm8gdGhhdCBpbmRpY2F0ZXMgdGhlIG5leHQKLSAgICogbm9kZSBwb3NpdGlvbiB0byBmZXRjaC4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIHNldE5leHRQb3NpdGlvbihpbnQgbmV4dCkKLSAgewotICAgIG1fbmV4dCA9IG5leHQ7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uLCB3aGljaCBpcyBvbmUgbGVzcyB0aGFuCi0gICAqIHRoZSBuZXh0IG5leHROb2RlKCkgY2FsbCB3aWxsIHJldHJpZXZlLiAgaS5lLiBpZgotICAgKiB5b3UgY2FsbCBnZXRDdXJyZW50UG9zKCkgYW5kIHRoZSByZXR1cm4gaXMgMCwgdGhlIG5leHQKLSAgICogZmV0Y2ggd2lsbCB0YWtlIHBsYWNlIGF0IGluZGV4IDEuCi0gICAqCi0gICAqIEByZXR1cm4gQSB2YWx1ZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gemVybyB0aGF0IGluZGljYXRlcyB0aGUgbmV4dAotICAgKiBub2RlIHBvc2l0aW9uIHRvIGZldGNoLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRDdXJyZW50UG9zKCkKLSAgewotICAgIHJldHVybiBtX25leHQ7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIG9uZSB0byB0aGUgY3VycmVudCBub2RlIGluZGV4LgotICAgKi8KLSAgdm9pZCBpbmNyZW1lbnROZXh0UG9zaXRpb24oKQotICB7Ci0gICAgbV9uZXh0Kys7Ci0gIH0KLQotICAvKioKLSAgICogSWYgc2V0U2hvdWxkQ2FjaGVOb2Rlcyh0cnVlKSBpcyBjYWxsZWQsIHRoZW4gbm9kZXMgd2lsbAotICAgKiBiZSBjYWNoZWQuICBUaGV5IGFyZSBub3QgY2FjaGVkIGJ5IGRlZmF1bHQuCi0gICAqCi0gICAqIEBwYXJhbSBiIFRydWUgaWYgdGhpcyBpdGVyYXRvciBzaG91bGQgY2FjaGUgbm9kZXMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRTaG91bGRDYWNoZU5vZGVzKGJvb2xlYW4gYikKLSAgewotCi0gICAgaWYgKGIpCi0gICAgewotICAgICAgaWYobnVsbCA9PSBtX2NhY2hlZE5vZGVzKQotICAgICAgewotICAgICAgICBtX2NhY2hlZE5vZGVzID0gbmV3IE5vZGVTZXREVE0oZ2V0RFRNTWFuYWdlcigpKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgICAgbV9jYWNoZWROb2RlcyA9IG51bGw7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxscyBpZiB0aGlzIGl0ZXJhdG9yIGNhbiBoYXZlIG5vZGVzIGFkZGVkIHRvIGl0IG9yIHNldCB2aWEgCi0gICAqIHRoZSA8Y29kZT5zZXRJdGVtKGludCBub2RlLCBpbnQgaW5kZXgpPC9jb2RlPiBtZXRob2QuCi0gICAqIAotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIG5vZGVsaXN0IGNhbiBiZSBtdXRhdGVkLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNNdXRhYmxlKCkKLSAgewotICAgIHJldHVybiAobV9jYWNoZWROb2RlcyAhPSBudWxsKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIEdldCBjYWNoZWQgbm9kZXMuCi0gICAqCi0gICAqIEByZXR1cm4gQ2FjaGVkIG5vZGVzLgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0gZ2V0Q2FjaGVkTm9kZXMoKQotICB7Ci0gICAgcmV0dXJuIG1fY2FjaGVkTm9kZXM7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBub2RlIHNldC4KLSAgICoKLSAgICogQHBhcmFtIGkgTXVzdCBiZSBhIHZhbGlkIGluZGV4IGdyZWF0ZXIKLSAgICogdGhhbiBvciBlcXVhbCB0byB6ZXJvIGFuZCBsZXNzIHRoYW4gbV9jYWNoZWROb2Rlcy5zaXplKCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50UG9zKGludCBpKQotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInNldEN1cnJlbnRQb3M6ICIraSk7Ci0gICAgaWYgKG51bGwgPT0gbV9jYWNoZWROb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgc2V0TmV4dFBvc2l0aW9uKGkpOwotICAgIG1fY2FjaGVkTm9kZXMuc2V0Q3VycmVudFBvcyhpKTsKLQotICAgIC8vIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJXaG8ncyByZXNldHRpbmcgdGhpcyB0aGluZz8iKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgY2FjaGVkIG5vZGVzLgotICAgKgotICAgKiA8cD5Ob3RlOiBmb3IgdGhlIG1vbWVudCBhdCBsZWFzdCwgdGhpcyBvbmx5IHJldHVybnMKLSAgICogdGhlIHNpemUgb2YgdGhlIG5vZGVzIHRoYXQgaGF2ZSBiZWVuIGZldGNoZWQgdG8gZGF0ZSwKLSAgICogaXQgZG9lc24ndCBhdHRlbXB0IHRvIHJ1biB0byB0aGUgZW5kIHRvIG1ha2Ugc3VyZSB3ZQotICAgKiBoYXZlIGZvdW5kIGV2ZXJ5dGhpbmcuICBUaGlzIHNob3VsZCBiZSByZXZpZXdlZC48L3A+Ci0gICAqCi0gICAqIEByZXR1cm4gVGhlIHNpemUgb2YgdGhlIGN1cnJlbnQgY2FjaGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgc2l6ZSgpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fY2FjaGVkTm9kZXMpCi0gICAgICByZXR1cm4gMDsKLQotICAgIHJldHVybiBtX2NhY2hlZE5vZGVzLnNpemUoKTsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+IHRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIElmCi0gICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub2RlcyBpbgotICAgKiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IC4KLSAgICogQHBhcmFtIGluZGV4ICBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgKiBAcmV0dXJuICBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+IHRoIHBvc2l0aW9uIGluIHRoZQotICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiAsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMgbm90IGEgdmFsaWQKLSAgICogICBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaXRlbShpbnQgaW5kZXgpCi0gIHsKLQotICAgIC8vIHJlc2V0VG9DYWNoZWRMaXN0KCk7Ci0KLSAgICByZXR1cm4gbV9jYWNoZWROb2Rlcy5pdGVtKGluZGV4KTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldHMgdGhlIG5vZGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBvZiB0aGlzIHZlY3RvciB0byBiZSB0aGUKLSAgICogc3BlY2lmaWVkIG5vZGUuIFRoZSBwcmV2aW91cyBjb21wb25lbnQgYXQgdGhhdCBwb3NpdGlvbiBpcyBkaXNjYXJkZWQuCi0gICAqCi0gICAqIDxwPlRoZSBpbmRleCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MKLSAgICogdGhhbiB0aGUgY3VycmVudCBzaXplIG9mIHRoZSB2ZWN0b3IuICAKLSAgICogVGhlIGl0ZXJhdG9yIG11c3QgYmUgaW4gY2FjaGVkIG1vZGUuPC9wPgotICAgKiAKLSAgICogPHA+TWVhbnQgdG8gYmUgdXNlZCBmb3Igc29ydGVkIGl0ZXJhdG9ycy48L3A+Ci0gICAqCi0gICAqIEBwYXJhbSBub2RlIE5vZGUgdG8gc2V0Ci0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB3aGVyZSB0byBzZXQgdGhlIG5vZGUKLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEl0ZW0oaW50IG5vZGUsIGludCBpbmRleCkKLSAgewotICAgIG1fY2FjaGVkTm9kZXMuc2V0RWxlbWVudEF0KG5vZGUsIGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdC4gVGhlIHJhbmdlIG9mIHZhbGlkIGNoaWxkIG5vZGUgaW5kaWNlcwotICAgKiBpcyAwIHRvIDxjb2RlPmxlbmd0aC0xPC9jb2RlPiBpbmNsdXNpdmUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbGlzdCwgYWx3YXlzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gemVyby4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkKLSAgewotCi0gICAgLy8gcmVzZXRUb0NhY2hlZExpc3QoKTsKLSAgICBpZihtX2xhc3QgPiAwKQotICAgICAgcmV0dXJuIG1fbGFzdDsKLSAgICBlbHNlIGlmKG51bGwgPT0gbV9jYWNoZWROb2RlcyB8fCAhbV9mb3VuZExhc3QpCi0gICAgewotICAgICAgbV9sYXN0ID0gZ2V0TGFzdFBvcyhtX2V4ZWNDb250ZXh0KTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fbGFzdCA9IG1fY2FjaGVkTm9kZXMuZ2V0TGVuZ3RoKCk7Ci0gICAgfQotICAgIHJldHVybiBtX2xhc3Q7Ci0gIH0KLQotICAvKioKLSAgICogSW4gb3JkZXIgdG8gaW1wbGVtZW50IE5vZGVMaXN0IChmb3IgZXh0ZW5zaW9ucyksIHRyeSB0byByZXNldAotICAgKiB0byBhIGNhY2hlZCBsaXN0IGZvciByYW5kb20gYWNjZXNzLgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIHJlc2V0VG9DYWNoZWRMaXN0KCkKLSAgewotICAgIC8vICVSRVZJRVclID8gVGhpcyBkb2Vzbid0IHNlZW0gdG8gd29yayBzbyB3ZWxsLi4uCi0gICAgaW50IHBvcyA9IHRoaXMuZ2V0Q3VycmVudFBvcygpOwotCi0gICAgaWYgKChudWxsID09IG1fY2FjaGVkTm9kZXMpIHx8IChwb3MgIT0gMCkpCi0gICAgICB0aGlzLnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0KLSAgICBydW5UbygtMSk7Ci0gICAgdGhpcy5zZXRDdXJyZW50UG9zKHBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBOb2RlU2V0RFRNIGlzICJmcmVzaCIsIGluIG90aGVyIHdvcmRzLCBpZgotICAgKiB0aGUgZmlyc3QgbmV4dE5vZGUoKSB0aGF0IGlzIGNhbGxlZCB3aWxsIHJldHVybiB0aGUKLSAgICogZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgb2YgbmV4dE5vZGUgaGFzIG5vdCBiZWVuIGNhbGxlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRnJlc2goKQotICB7Ci0gICAgcmV0dXJuIChtX25leHQgPT0gMCk7Ci0gIH0KLQotICAvKioKLSAgICogIFJldHVybnMgdGhlIHByZXZpb3VzIG5vZGUgaW4gdGhlIHNldCBhbmQgbW92ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBiYWNrd2FyZHMgaW4gdGhlIHNldC4KLSAgICogQHJldHVybiAgVGhlIHByZXZpb3VzIDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3ZlciwKLSAgICogICBvcjxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IHByZXZpb3VzTm9kZSgpCi0gIHsKLQotICAgIGlmIChudWxsID09IG1fY2FjaGVkTm9kZXMpCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgIlRoaXMgTm9kZVNldERUTSBjYW4gbm90IGl0ZXJhdGUgdG8gYSBwcmV2aW91cyBub2RlISIpOwotCi0gICAgcmV0dXJuIG1fY2FjaGVkTm9kZXMucHJldmlvdXNOb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBwcmVzZW50ZWQgdmlhIHRoZQotICAgKiBpdGVyYXRvci4gVGhlIGF2YWlsYWJsZSBzZXQgb2YgY29uc3RhbnRzIGlzIGRlZmluZWQgaW4gdGhlCi0gICAqIDxjb2RlPk5vZGVGaWx0ZXI8L2NvZGU+IGludGVyZmFjZS4KLSAgICoKLSAgICogPHA+VGhpcyBpcyBzb21ld2hhdCB1c2VsZXNzIGF0IHRoaXMgdGltZSwgc2luY2UgaXQgZG9lc24ndAotICAgKiByZWFsbHkgcmV0dXJuIGluZm9ybWF0aW9uIHRoYXQgdGVsbHMgd2hhdCB0aGlzIGl0ZXJhdG9yIHdpbGwKLSAgICogc2hvdy4gIEl0IGlzIGhlcmUgb25seSB0byBmdWxsZmlsbCB0aGUgRE9NIE5vZGVJdGVyYXRvcgotICAgKiBpbnRlcmZhY2UuPC9wPgotICAgKgotICAgKiBAcmV0dXJuIEZvciBub3csIGFsd2F5cyBOb2RlRmlsdGVyLlNIT1dfQUxMICYgfk5vZGVGaWx0ZXIuU0hPV19FTlRJVFlfUkVGRVJFTkNFLgotICAgKiBAc2VlIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gIHsKLQotICAgIC8vIFRPRE86ID8/Ci0gICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX0FMTCAmIH5EVE1GaWx0ZXIuU0hPV19FTlRJVFlfUkVGRVJFTkNFOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgZmlsdGVyIHVzZWQgdG8gc2NyZWVuIG5vZGVzLiAgTm90IHVzZWQgYXQgdGhpcyB0aW1lLAotICAgKiB0aGlzIGlzIGhlcmUgb25seSB0byBmdWxsZmlsbCB0aGUgRE9NIE5vZGVJdGVyYXRvcgotICAgKiBpbnRlcmZhY2UuCi0gICAqCi0gICAqIEByZXR1cm4gQWx3YXlzIG51bGwuCi0gICAqIEBzZWUgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcgotICAgKi8KLSAgcHVibGljIERUTUZpbHRlciBnZXRGaWx0ZXIoKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHJvb3Qgbm9kZSBvZiB0aGUgSXRlcmF0b3IsIGFzIHNwZWNpZmllZCB3aGVuIGl0IHdhcyBjcmVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSAicm9vdCIgb2YgdGhpcyBpdGVyYXRvciwgd2hpY2gsIGluIFhQYXRoIHRlcm1zLAotICAgKiBpcyB0aGUgbm9kZSBjb250ZXh0IGZvciB0aGlzIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIGludCBnZXRSb290KCkKLSAgewotICAgIHJldHVybiBtX2NvbnRleHQ7Ci0gIH0KLQotICAvKioKLSAgICogIFRoZSB2YWx1ZSBvZiB0aGlzIGZsYWcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGlsZHJlbiBvZiBlbnRpdHkKLSAgICogcmVmZXJlbmNlIG5vZGVzIGFyZSB2aXNpYmxlIHRvIHRoZSBpdGVyYXRvci4gSWYgZmFsc2UsIHRoZXkgd2lsbCBiZQotICAgKiBza2lwcGVkIG92ZXIuCi0gICAqIDxicj4gVG8gcHJvZHVjZSBhIHZpZXcgb2YgdGhlIGRvY3VtZW50IHRoYXQgaGFzIGVudGl0eSByZWZlcmVuY2VzCi0gICAqIGV4cGFuZGVkIGFuZCBkb2VzIG5vdCBleHBvc2UgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZSBpdHNlbGYsIHVzZSB0aGUKLSAgICogd2hhdFRvU2hvdyBmbGFncyB0byBoaWRlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgYW5kIHNldAotICAgKiBleHBhbmRFbnRpdHlSZWZlcmVuY2VzIHRvIHRydWUgd2hlbiBjcmVhdGluZyB0aGUgaXRlcmF0b3IuIFRvIHByb2R1Y2UKLSAgICogYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcyBlbnRpdHkgcmVmZXJlbmNlIG5vZGVzIGJ1dCBubyBlbnRpdHkKLSAgICogZXhwYW5zaW9uLCB1c2UgdGhlIHdoYXRUb1Nob3cgZmxhZ3MgdG8gc2hvdyB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlCi0gICAqIGFuZCBzZXQgZXhwYW5kRW50aXR5UmVmZXJlbmNlcyB0byBmYWxzZS4KLSAgICoKLSAgICogQHJldHVybiBBbHdheXMgdHJ1ZSwgc2luY2UgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBhcmUgbm90Ci0gICAqIHZpc2libGUgaW4gdGhlIFhQYXRoIG1vZGVsLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ2V0RXhwYW5kRW50aXR5UmVmZXJlbmNlcygpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotICAKLSAgLyoqIENvbnRyb2wgb3ZlciB3aGV0aGVyIGl0IGlzIE9LIGZvciBkZXRhY2ggdG8gcmVzZXQgdGhlIGl0ZXJhdG9yLiAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9hbGxvd0RldGFjaCA9IHRydWU7Ci0gIAotICAvKioKLSAgICogU3BlY2lmeSBpZiBpdCdzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGUgaXRlcmF0b3IgZm9yIHJldXNlLgotICAgKiAKLSAgICogQHBhcmFtIGFsbG93UmVsZWFzZSB0cnVlIGlmIGl0IGlzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGlzIGl0ZXJhdG9yIAotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKQotICB7Ci0gICAgbV9hbGxvd0RldGFjaCA9IGFsbG93UmVsZWFzZTsKLSAgfQotCi0gIC8qKgotICAgKiAgRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgeyAgICAKLSAgICBpZihtX2FsbG93RGV0YWNoKQotICAgIHsKLSAgICAgIG1fY2FjaGVkTm9kZXMgPSBudWxsOwotICAgICAgbV9leGVjQ29udGV4dCA9IG51bGw7Ci0gICAgICBtX3ByZWZpeFJlc29sdmVyID0gbnVsbDsKLSAgICAgIG1fY2R0bSA9IG51bGw7Ci0gICAgICAKLSAgICAgIG1fY2xvbmVzLmZyZWVJbnN0YW5jZSh0aGlzKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLQotICAgIC8vIHN1cGVyLnJlc2V0KCk7Ci0gICAgbV9mb3VuZExhc3QgPSBmYWxzZTsKLSAgICBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0gICAgbV9uZXh0ID0gMDsKLSAgICBtX2xhc3QgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcKLSAgICogb2YgdGhlIHF1ZXJ5LgotICAgKgotICAgKiBAcmV0dXJuIEEgY2xvbmVkIE5vZGVJdGVyYXRvciBzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNsb25lV2l0aFJlc2V0KCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIExvY1BhdGhJdGVyYXRvciBjbG9uZSA9IChMb2NQYXRoSXRlcmF0b3IpIGNsb25lKCk7Ci0KLSAgICBjbG9uZS5yZXNldCgpOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLS8vICAvKioKLS8vICAgKiBHZXQgYSBjbG9uZWQgTG9jUGF0aEl0ZXJhdG9yIHRoYXQgaG9sZHMgdGhlIHNhbWUKLS8vICAgKiBwb3NpdGlvbiBhcyB0aGlzIGl0ZXJhdG9yLgotLy8gICAqCi0vLyAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgaXRlcmF0b3IgdGhhdCBob2xkcyB0aGUgc2FtZSBub2RlIHBvc2l0aW9uLgotLy8gICAqCi0vLyAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotLy8gICAqLwotLy8gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLS8vICB7Ci0vLwotLy8gICAgTG9jUGF0aEl0ZXJhdG9yIGNsb25lID0gKExvY1BhdGhJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLS8vCi0vLyAgICByZXR1cm4gY2xvbmU7Ci0vLyAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGFic3RyYWN0IGludCBuZXh0Tm9kZSgpOwotCi0gIC8qKgotICAgKiBCb3R0bGVuZWNrIHRoZSByZXR1cm4gb2YgYSBuZXh0IG5vZGUsIHRvIG1ha2UgcmV0dXJucwotICAgKiBlYXNpZXIgZnJvbSBuZXh0Tm9kZSgpLgotICAgKgotICAgKiBAcGFyYW0gbmV4dE5vZGUgVGhlIG5leHQgbm9kZSBmb3VuZCwgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHNhbWUgbm9kZSB0aGF0IHdhcyBwYXNzZWQgYXMgYW4gYXJndW1lbnQuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IHJldHVybk5leHROb2RlKGludCBuZXh0Tm9kZSkKLSAgewotCi0gICAgaWYgKERUTS5OVUxMICE9IG5leHROb2RlKQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChuZXh0Tm9kZSk7Ci0KLSAgICAgIHRoaXMuaW5jcmVtZW50TmV4dFBvc2l0aW9uKCk7Ci0gICAgfQotCi0gICAgbV9sYXN0RmV0Y2hlZCA9IG5leHROb2RlOwotCi0gICAgaWYgKERUTS5OVUxMID09IG5leHROb2RlKQotICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgcmV0dXJuIG5leHROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbGFzdCBmZXRjaGVkIG5vZGUuICBOZWVkZWQgdG8gc3VwcG9ydCB0aGUgVW5pb25QYXRoSXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGxhc3QgZmV0Y2hlZCBub2RlLCBvciBudWxsIGlmIHRoZSBsYXN0IGZldGNoIHdhcyBudWxsLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotCi0gIC8qKgotICAgKiBJZiBhbiBpbmRleCBpcyByZXF1ZXN0ZWQsIE5vZGVTZXREVE0gd2lsbCBjYWxsIHRoaXMgbWV0aG9kCi0gICAqIHRvIHJ1biB0aGUgaXRlcmF0b3IgdG8gdGhlIGluZGV4LiAgQnkgZGVmYXVsdCB0aGlzIHNldHMKLSAgICogbV9uZXh0IHRvIHRoZSBpbmRleC4gIElmIHRoZSBpbmRleCBhcmd1bWVudCBpcyAtMSwgdGhpcwotICAgKiBzaWduYWxzIHRoYXQgdGhlIGl0ZXJhdG9yIHNob3VsZCBiZSBydW4gdG8gdGhlIGVuZC4KLSAgICoKLSAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBydW4gdG8sIG9yIC0xIGlmIHRoZSBpdGVyYXRvcgotICAgKiBzaG91bGQgcnVuIHRvIHRoZSBlbmQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBydW5UbyhpbnQgaW5kZXgpCi0gIHsKLQotICAgIGlmIChtX2ZvdW5kTGFzdCB8fCAoKGluZGV4ID49IDApICYmIChpbmRleCA8PSBnZXRDdXJyZW50UG9zKCkpKSkKLSAgICAgIHJldHVybjsKLQotICAgIGludCBuOwotCi0gICAgaWYgKC0xID09IGluZGV4KQotICAgIHsKLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobiA9IG5leHROb2RlKCkpKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobiA9IG5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBpZiAoZ2V0Q3VycmVudFBvcygpID49IGluZGV4KQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxscyBpZiB3ZSd2ZSBmb3VuZCB0aGUgbGFzdCBub2RlIHlldC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBsYXN0IG5leHROb2RlIHJldHVybmVkIG51bGwuCi0gICAqLwotICBwdWJsaWMgZmluYWwgYm9vbGVhbiBnZXRGb3VuZExhc3QoKQotICB7Ci0gICAgcmV0dXJuIG1fZm91bmRMYXN0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBYUGF0aCBleGVjdXRpb24gY29udGV4dCB3ZSBhcmUgb3BlcmF0aW5nIG9uLgotICAgKgotICAgKiBAcmV0dXJuIFhQYXRoIGV4ZWN1dGlvbiBjb250ZXh0IHRoaXMgaXRlcmF0b3IgaXMgb3BlcmF0aW5nIG9uLAotICAgKiBvciBudWxsIGlmIHNldFJvb3QgaGFzIG5vdCBiZWVuIGNhbGxlZC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBYUGF0aENvbnRleHQgZ2V0WFBhdGhDb250ZXh0KCkKLSAgewotICAgIHJldHVybiBtX2V4ZWNDb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGNvbnRleHQgZm9yIHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBjb250ZXh0LCBzYW1lIGFzIGdldFJvb3QoKS4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCBpbnQgZ2V0Q29udGV4dCgpCi0gIHsKLSAgICByZXR1cm4gbV9jb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBub2RlIGNvbnRleHQgZnJvbSB3aGVyZSB0aGUgZXhwcmVzc2lvbiBpcyBiZWluZwotICAgKiBleGVjdXRlZCBmcm9tIChpLmUuIGZvciBjdXJyZW50KCkgc3VwcG9ydCkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRvcC1sZXZlbCBub2RlIGNvbnRleHQgb2YgdGhlIGVudGlyZSBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRDdXJyZW50Q29udGV4dE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fY3VycmVudENvbnRleHROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUgZm9yIHRoaXMgaXRlcmF0b3IuCi0gICAqCi0gICAqIEBwYXJhbSBuIE11c3QgYmUgYSBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIG5vZGUgY29udGV4dC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldEN1cnJlbnRDb250ZXh0Tm9kZShpbnQgbikKLSAgewotICAgIG1fY3VycmVudENvbnRleHROb2RlID0gbjsKLSAgfQotICAKLS8vICAvKioKLS8vICAgKiBTZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGZvciB0aGlzIGl0ZXJhdG9yLgotLy8gICAqCi0vLyAgICogQHBhcmFtIG4gTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgbm9kZSBjb250ZXh0LgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IG4pCi0vLyAgewotLy8gICAgbV9jb250ZXh0ID0gbjsKLS8vICAgIG1fY2R0bSA9IG1fZXhlY0NvbnRleHQuZ2V0RFRNKG4pOwotLy8gIH0KLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBzYXZlZCByZWZlcmVuY2UgdG8gdGhlIHByZWZpeCByZXNvbHZlciB0aGF0Ci0gICAqIHdhcyBpbiBlZmZlY3Qgd2hlbiB0aGlzIGl0ZXJhdG9yIHdhcyBjcmVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBwcmVmaXggcmVzb2x2ZXIgb3IgdGhpcyBpdGVyYXRvciwgd2hpY2ggbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgZmluYWwgUHJlZml4UmVzb2x2ZXIgZ2V0UHJlZml4UmVzb2x2ZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZml4UmVzb2x2ZXI7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgaW4gdGhlIGl0ZXJhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdCgpCi0gIHsKLSAgICByZXR1cm4gZ2V0TGVuZ3RoKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsYXN0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoZSBpdGVyYXRpb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMYXN0KGludCBsYXN0KQotICB7Ci0gICAgbV9sYXN0ID0gbGFzdDsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gYmUgaXR0ZXJhdGVkIHRvLgotICAgKiBUaGlzIHByb2JhYmx5IHdpbGwgbmVlZCB0byBiZSBvdmVycmlkZGVkIGJ5IGRlcml2ZWQgY2xhc3Nlcy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgaW50IHNhdmVkUG9zOwotICAgIGlmKG51bGwgIT0gbV9jYWNoZWROb2RlcykKLSAgICAgIHNhdmVkUG9zID0gbV9jYWNoZWROb2Rlcy5nZXRDdXJyZW50UG9zKCk7Ci0gICAgZWxzZSAKLSAgICAgIHNhdmVkUG9zID0gLTE7Ci0gICAgICAKLSAgICBpbnQgcG9zID0gKG1fcHJlZGljYXRlSW5kZXggPj0gMCkgPyBnZXRQcm94aW1pdHlQb3NpdGlvbigpIDogCi0gICAgICAgICAgICAgICgobnVsbCAhPSBtX2NhY2hlZE5vZGVzKSA/IG1fY2FjaGVkTm9kZXMuZ2V0Q3VycmVudFBvcygpIDogbV9uZXh0KTsKLSAgICAgICAgICAgICAgCi0gICAgTG9jUGF0aEl0ZXJhdG9yIGNsb25lOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgLy8gJVJFVklFVyUgJU9QVCUKLSAgICAgIGlmKDAgPT0gcG9zICYmIG1fY3VycmVudENvbnRleHROb2RlICE9IERUTS5OVUxMKQotICAgICAgICBjbG9uZSA9IChMb2NQYXRoSXRlcmF0b3IpIGNsb25lV2l0aFJlc2V0KCk7Ci0gICAgICBlbHNlCi0gICAgICAgIGNsb25lID0gKExvY1BhdGhJdGVyYXRvcikgY2xvbmUoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgewotICAgICAgcmV0dXJuIC0xOwotICAgIH0KLSAgICAvLyAlUkVWSUVXJSBDb21tZW50ZWQgdGhpcyBvdXQsIGFzIGl0IHdhcyBtZXNzaW5nIHVwIHBvczY4IHRlc3QuIGNvdW50LTE/Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJjbG9uZS5nZXRQcmVkaWNhdGVDb3VudCgpOiAiK2Nsb25lLmdldFByZWRpY2F0ZUNvdW50KCkpOwotICAgIC8vIGNsb25lLnNldFByZWRpY2F0ZUNvdW50KGNsb25lLmdldFByZWRpY2F0ZUNvdW50KCkgLSAxKTsKLQotICAgIGludCBuZXh0OwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IChuZXh0ID0gY2xvbmUubmV4dE5vZGUoKSkpCi0gICAgewotICAgICAgcG9zKys7Ci0gICAgfQotICAgIAotICAgIGlmKC0xICE9IHNhdmVkUG9zKQotICAgICAgbV9jYWNoZWROb2Rlcy5zZXRDdXJyZW50UG9zKHNhdmVkUG9zKTsKLQotICAgIHJldHVybiBwb3M7Ci0gIH0KLSAgCi0vLyAgLyoqCi0vLyAgICogR2V0IHRoZSBhbmFseXNpcyBwYXR0ZXJuIGJ1aWx0IGJ5IHRoZSBXYWxrZXJGYWN0b3J5LgotLy8gICAqCi0vLyAgICogQHJldHVybiBUaGUgYW5hbHlzaXMgcGF0dGVybiBidWlsdCBieSB0aGUgV2Fsa2VyRmFjdG9yeS4KLS8vICAgKi8KLS8vICBpbnQgZ2V0QW5hbHlzaXMoKQotLy8gIHsKLS8vICAgIHJldHVybiBtX2FuYWx5c2lzOwotLy8gIH0KLQotLy8gIC8qKgotLy8gICAqIFNldCB0aGUgYW5hbHlzaXMgcGF0dGVybiBidWlsdCBieSB0aGUgV2Fsa2VyRmFjdG9yeS4KLS8vICAgKgotLy8gICAqIEBwYXJhbSBhIFRoZSBhbmFseXNpcyBwYXR0ZXJuIGJ1aWx0IGJ5IHRoZSBXYWxrZXJGYWN0b3J5LgotLy8gICAqLwotLy8gIHZvaWQgc2V0QW5hbHlzaXMoaW50IGEpCi0vLyAgewotLy8gICAgbV9hbmFseXNpcyA9IGE7Ci0vLyAgfQotICAKLSAgLy89PT09PT09PT09PT09IFN0YXRlIERhdGEgPT09PT09PT09PT09PQotICAKLSAgLyoqIAotICAgKiBUaGUgcG9vbCBmb3IgY2xvbmVkIGl0ZXJhdG9ycy4gIEl0ZXJhdG9ycyBuZWVkIHRvIGJlIGNsb25lZAotICAgKiBiZWNhdXNlIHRoZSBob2xkIHJ1bm5pbmcgc3RhdGUsIGFuZCB0aHVzIHRoZSBvcmlnaW5hbCBpdGVyYXRvcgotICAgKiBleHByZXNzaW9uIGZyb20gdGhlIHN0eWxlc2hlZXQgcG9vbCBjYW4gbm90IGJlIHVzZWQuICAgICAgICAgIAotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBJdGVyYXRvclBvb2wgbV9jbG9uZXMgPSBuZXcgSXRlcmF0b3JQb29sKHRoaXMpOwotICAKLSAgLyoqIAotICAgKiBUaGUgZHRtIG9mIHRoZSBjb250ZXh0IG5vZGUuICBDYXJlZnVsIGFib3V0IHVzaW5nIHRoaXMuLi4gaXQgbWF5IG5vdCAKLSAgICogYmUgdGhlIGR0bSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBEVE0gbV9jZHRtOwotICAKLSAgLyoqCi0gICAqIFRoZSBzdGFjayBmcmFtZSBpbmRleCBmb3IgdGhpcyBpdGVyYXRvci4KLSAgICovCi0gIHRyYW5zaWVudCBpbnQgbV9zdGFja0ZyYW1lID0gLTE7Ci0KLSAgLyoqCi0gICAqIFZhbHVlIGRldGVybWluZWQgYXQgY29tcGlsZSB0aW1lLCBpbmRpY2F0ZXMgdGhhdCB0aGlzIGlzIGFuCi0gICAqIGl0ZXJhdG9yIGF0IHRoZSB0b3AgbGV2ZWwgb2YgdGhlIGV4cHJlc3Npb24sIHJhdGhlciB0aGFuIGluc2lkZQotICAgKiBhIHByZWRpY2F0ZS4KLSAgICogQHNlcmlhbAotICAgKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1faXNUb3BMZXZlbCA9IGZhbHNlOwotCi0gIC8qKiBUaGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSBpbiB0aGUgaXRlcmF0aW9uLiAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX2xhc3QgPSAwOwotICAKLSAgLyoqIFRoZSBsYXN0IG5vZGUgdGhhdCB3YXMgZmV0Y2hlZCwgdXN1YWxseSBieSBuZXh0Tm9kZS4gKi8KLSAgdHJhbnNpZW50IHB1YmxpYyBpbnQgbV9sYXN0RmV0Y2hlZCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiBJZiB0aGlzIGl0ZXJhdG9yIG5lZWRzIHRvIGNhY2hlIG5vZGVzIHRoYXQgYXJlIGZldGNoZWQsIHRoZXkKLSAgICogYXJlIHN0b3JlZCBoZXJlLgotICAgKi8KLSAgdHJhbnNpZW50IE5vZGVTZXREVE0gbV9jYWNoZWROb2RlczsKLQotICAvKioKLSAgICogVGhlIGNvbnRleHQgbm9kZSBmb3IgdGhpcyBpdGVyYXRvciwgd2hpY2ggZG9lc24ndCBjaGFuZ2UgdGhyb3VnaAotICAgKiB0aGUgY291cnNlIG9mIHRoZSBpdGVyYXRpb24uCi0gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX2NvbnRleHQgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogVGhlIG5vZGUgY29udGV4dCBmcm9tIHdoZXJlIHRoZSBleHByZXNzaW9uIGlzIGJlaW5nCi0gICAqIGV4ZWN1dGVkIGZyb20gKGkuZS4gZm9yIGN1cnJlbnQoKSBzdXBwb3J0KS4gIERpZmZlcmVudAotICAgKiBmcm9tIG1fY29udGV4dCBpbiB0aGF0IHRoaXMgaXMgdGhlIGNvbnRleHQgZm9yIHRoZSBlbnRpcmUKLSAgICogZXhwcmVzc2lvbiwgcmF0aGVyIHRoYW4gdGhlIGNvbnRleHQgZm9yIHRoZSBzdWJleHByZXNzaW9uLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBpbnQgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBEVE0uTlVMTDsKLQotICAvKioKLSAgICogRmFzdCBhY2Nlc3MgdG8gdGhlIGN1cnJlbnQgcHJlZml4IHJlc29sdmVyLiAgSXQgaXNuJ3QgcmVhbGx5Ci0gICAqIGNsZWFyIHRoYXQgdGhpcyBpcyBuZWVkZWQuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIHByb3RlY3RlZCBQcmVmaXhSZXNvbHZlciBtX3ByZWZpeFJlc29sdmVyOwotCi0gIC8qKgotICAgKiBUaGUgWFBhdGhDb250ZXh0IHJlZmVyZW5jZSwgbmVlZGVkIGZvciBleGVjdXRpb24gb2YgbWFueQotICAgKiBvcGVyYXRpb25zLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBYUGF0aENvbnRleHQgbV9leGVjQ29udGV4dDsKLQotICAvKioKLSAgICogVGhlIGluZGV4IG9mIHRoZSBuZXh0IG5vZGUgdG8gYmUgZmV0Y2hlZC4gIFVzZWZ1bCBpZiB0aGlzCi0gICAqIGlzIGEgY2FjaGVkIGl0ZXJhdG9yLCBhbmQgaXMgYmVpbmcgdXNlZCBhcyByYW5kb20gYWNjZXNzCi0gICAqIE5vZGVMaXN0LgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBpbnQgbV9uZXh0OwotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdHJ1ZSBpZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBpdGVyYXRpb24gd2VsbCBiZSByZXR1cm5lZCBpbiBkb2N1bWVudCAKLSAgICogb3JkZXIuCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgYXMgYSBkZWZhdWx0LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2NPcmRlcmVkKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqIAotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZSAKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIC0xOwotICB9Ci0KLQotLy8gIC8qKgotLy8gICAqIFRoZSBhbmFseXNpcyBwYXR0ZXJuIGJ1aWx0IGJ5IHRoZSBXYWxrZXJGYWN0b3J5LgotLy8gICAqIFRPRE86IE1vdmUgdG8gTG9jUGF0aEl0ZXJhdG9yLgotLy8gICAqIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5heGVzLldhbGtlckZhY3RvcnkKLS8vICAgKiBAc2VyaWFsCi0vLyAgICovCi0vLyAgcHJvdGVjdGVkIGludCBtX2FuYWx5c2lzID0gMHgwMDAwMDAwMDsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvTWF0Y2hQYXR0ZXJuSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvTWF0Y2hQYXR0ZXJuSXRlcmF0b3IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYzAxMzhhNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL01hdGNoUGF0dGVybkl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzNzcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5heGVzOwotCi1pbXBvcnQgamF2YS51dGlsLlN0YWNrOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5TdWJDb250ZXh0TGlzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLlBzdWVkb05hbWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5TdGVwUGF0dGVybjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlZhcmlhYmxlU3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1NYW5hZ2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1BeGlzVHJhdmVyc2VyOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgdHJlYXRzIGEgCi0gKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNsb2NhdGlvbi1wYXRocyI+TG9jYXRpb25QYXRoPC9hPiBhcyBhIAotICogZmlsdGVyZWQgaXRlcmF0aW9uIG92ZXIgdGhlIHRyZWUsIGV2YWx1YXRpbmcgZWFjaCBub2RlIGluIGEgc3VwZXIgYXhpcyAKLSAqIHRyYXZlcnNhbCBhZ2FpbnN0IHRoZSBMb2NhdGlvblBhdGggaW50ZXJwcmV0ZWQgYXMgYSBtYXRjaCBwYXR0ZXJuLiAgVGhpcyAKLSAqIGNsYXNzIGlzIHVzZWZ1bCB0byBmaW5kIG5vZGVzIGluIGRvY3VtZW50IG9yZGVyIHRoYXQgYXJlIGNvbXBsZXggcGF0aHMgCi0gKiB3aG9zZSBzdGVwcyBwcm9iYWJseSBjcmlzcy1jcm9zcyBlYWNoIG90aGVyLgotICovCi1wdWJsaWMgY2xhc3MgTWF0Y2hQYXR0ZXJuSXRlcmF0b3IgZXh0ZW5kcyBMb2NQYXRoSXRlcmF0b3IKLXsKLQotICAvKiogVGhpcyBpcyB0aGUgc2VsZWN0IHBhdHRlcm4sIHRyYW5zbGF0ZWQgaW50byBhIG1hdGNoIHBhdHRlcm4uICovCi0gIHByb3RlY3RlZCBTdGVwUGF0dGVybiBtX3BhdHRlcm47Ci0KLSAgLyoqIFRoZSB0cmF2ZXJzYWwgYXhpcyBmcm9tIHdoZXJlIHRoZSBub2RlcyB3aWxsIGJlIGZpbHRlcmVkLiAqLwotICBwcm90ZWN0ZWQgaW50IG1fc3VwZXJBeGlzID0gLTE7Ci0KLSAgLyoqIFRoZSBEVE0gaW5uZXIgdHJhdmVyc2FsIGNsYXNzLCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBzdXBlciBheGlzLiAqLwotICBwcm90ZWN0ZWQgRFRNQXhpc1RyYXZlcnNlciBtX3RyYXZlcnNlcjsKLSAgCi0gIC8qKiBERUJVRyBmbGFnIGZvciBkaWFnbm9zdGljIGR1bXBzLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7Ci0gIAotLy8gIHByb3RlY3RlZCBpbnQgbV9uc0VsZW1CYXNlID0gRFRNLk5VTEw7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIExvY1BhdGhJdGVyYXRvciBvYmplY3QsIGluY2x1ZGluZyBjcmVhdGlvbgotICAgKiBvZiBzdGVwIHdhbGtlcnMgZnJvbSB0aGUgb3Bjb2RlIGxpc3QsIGFuZCBjYWxsIGJhY2sKLSAgICogaW50byB0aGUgQ29tcGlsZXIgdG8gY3JlYXRlIHByZWRpY2F0ZSBleHByZXNzaW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciB3aGljaCBpcyBjcmVhdGluZwotICAgKiB0aGlzIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciBpbiB0aGUKLSAgICogb3Bjb2RlIGxpc3QgZnJvbSB0aGUgY29tcGlsZXIuCi0gICAqIEBwYXJhbSBhbmFseXNpcyBBbmFseXNpcyBiaXRzIHRoYXQgZ2l2ZSBnZW5lcmFsIGluZm9ybWF0aW9uIGFib3V0IHRoZSAKLSAgICogTG9jYXRpb25QYXRoLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIE1hdGNoUGF0dGVybkl0ZXJhdG9yKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBhbmFseXNpcykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBzdXBlcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzLCBmYWxzZSk7Ci0KLSAgICBpbnQgZmlyc3RTdGVwUG9zID0gY29tcGlsZXIuZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICBtX3BhdHRlcm4gPSBXYWxrZXJGYWN0b3J5LmxvYWRTdGVwcyh0aGlzLCBjb21waWxlciwgZmlyc3RTdGVwUG9zLCAwKTsgCi0KLSAgICBib29sZWFuIGZyb21Sb290ID0gZmFsc2U7Ci0gICAgYm9vbGVhbiB3YWxrQmFjayA9IGZhbHNlOwotICAgIGJvb2xlYW4gd2Fsa0Rlc2NlbmRhbnRzID0gZmFsc2U7Ci0gICAgYm9vbGVhbiB3YWxrQXR0cmlidXRlcyA9IGZhbHNlOwotCi0gICAgaWYgKDAgIT0gKGFuYWx5c2lzICYgKFdhbGtlckZhY3RvcnkuQklUX1JPT1QgfCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgV2Fsa2VyRmFjdG9yeS5CSVRfQU5ZX0RFU0NFTkRBTlRfRlJPTV9ST09UKSkpCi0gICAgICBmcm9tUm9vdCA9IHRydWU7Ci0gICAgICAKLSAgICBpZiAoMCAhPSAoYW5hbHlzaXMKLSAgICAgICAgICAgICAgJiAoV2Fsa2VyRmFjdG9yeS5CSVRfQU5DRVNUT1IKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9BTkNFU1RPUl9PUl9TRUxGCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfUFJFQ0VESU5HCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfUFJFQ0VESU5HX1NJQkxJTkcgCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfRk9MTE9XSU5HCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfRk9MTE9XSU5HX1NJQkxJTkcKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9QQVJFTlQgfCBXYWxrZXJGYWN0b3J5LkJJVF9GSUxURVIpKSkKLSAgICAgIHdhbGtCYWNrID0gdHJ1ZTsKLQotICAgIGlmICgwICE9IChhbmFseXNpcwotICAgICAgICAgICAgICAmIChXYWxrZXJGYWN0b3J5LkJJVF9ERVNDRU5EQU5UX09SX1NFTEYKLSAgICAgICAgICAgICAgICAgfCBXYWxrZXJGYWN0b3J5LkJJVF9ERVNDRU5EQU5UCi0gICAgICAgICAgICAgICAgIHwgV2Fsa2VyRmFjdG9yeS5CSVRfQ0hJTEQpKSkKLSAgICAgIHdhbGtEZXNjZW5kYW50cyA9IHRydWU7Ci0KLSAgICBpZiAoMCAhPSAoYW5hbHlzaXMKLSAgICAgICAgICAgICAgJiAoV2Fsa2VyRmFjdG9yeS5CSVRfQVRUUklCVVRFIHwgV2Fsa2VyRmFjdG9yeS5CSVRfTkFNRVNQQUNFKSkpCi0gICAgICB3YWxrQXR0cmlidXRlcyA9IHRydWU7Ci0gICAgICAKLSAgICBpZihmYWxzZSB8fCBERUJVRykKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJhbmFseXNpczogIitJbnRlZ2VyLnRvQmluYXJ5U3RyaW5nKGFuYWx5c2lzKSk7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiwgIitXYWxrZXJGYWN0b3J5LmdldEFuYWx5c2lzU3RyaW5nKGFuYWx5c2lzKSk7Ci0gICAgfQotICAgICAgCi0gICAgaWYoZnJvbVJvb3QgfHwgd2Fsa0JhY2spCi0gICAgewotICAgICAgaWYod2Fsa0F0dHJpYnV0ZXMpCi0gICAgICB7Ci0gICAgICAgIG1fc3VwZXJBeGlzID0gQXhpcy5BTEw7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIG1fc3VwZXJBeGlzID0gQXhpcy5ERVNDRU5EQU5UU0ZST01ST09UOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmKHdhbGtEZXNjZW5kYW50cykKLSAgICB7Ci0gICAgICBpZih3YWxrQXR0cmlidXRlcykKLSAgICAgIHsKLSAgICAgICAgbV9zdXBlckF4aXMgPSBBeGlzLkFMTEZST01OT0RFOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX3N1cGVyQXhpcyA9IEF4aXMuREVTQ0VOREFOVE9SU0VMRjsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fc3VwZXJBeGlzID0gQXhpcy5BTEw7Ci0gICAgfQotICAgIGlmKGZhbHNlIHx8IERFQlVHKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiYXhpczogIitBeGlzLm5hbWVzW21fc3VwZXJBeGlzXSk7Ci0gICAgfQotICAgIAotICB9Ci0gIAotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBleGVjQ29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0gICAgbV90cmF2ZXJzZXIgPSBtX2NkdG0uZ2V0QXhpc1RyYXZlcnNlcihtX3N1cGVyQXhpcyk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgbm9kZSB2aWEgZ2V0TmV4dFhYWC4gIEJvdHRsZW5lY2tlZCBmb3IgZGVyaXZlZCBjbGFzcyBvdmVycmlkZS4KLSAgICogQHJldHVybiBUaGUgbmV4dCBub2RlIG9uIHRoZSBheGlzLCBvciBEVE0uTlVMTC4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGUoKQotICB7Ci0gICAgbV9sYXN0RmV0Y2hlZCA9IChEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgICAgICAgICAgICAgICAgICAgPyBtX3RyYXZlcnNlci5maXJzdChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICA6IG1fdHJhdmVyc2VyLm5leHQobV9jb250ZXh0LCBtX2xhc3RGZXRjaGVkKTsKLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLQotICAgIC8vIElmIHRoZSBjYWNoZSBpcyBvbiwgYW5kIHRoZSBub2RlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHRoZW4gCi0gICAgLy8ganVzdCByZXR1cm4gZnJvbSB0aGUgbGlzdC4KLSAgICAvLyBJZiB0aGUgY2FjaGUgaXMgb24sIGFuZCB0aGUgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIGZvdW5kLCB0aGVuIAotICAgIC8vIGp1c3QgcmV0dXJuIGZyb20gdGhlIGxpc3QuCi0gICAgaWYgKChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgICAgICAgICAmJiAobV9uZXh0IDwgbV9jYWNoZWROb2Rlcy5zaXplKCkpKQotICAgIHsKLSAgICAgIGludCBuZXh0ID0gbV9jYWNoZWROb2Rlcy5lbGVtZW50QXQobV9uZXh0KTsKLSAgICAKLSAgICAgIGluY3JlbWVudE5leHRQb3NpdGlvbigpOwotICAgICAgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBuZXh0OwotCi0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0KLSAgICBpZiAobV9mb3VuZExhc3QpCi0gICAgewotICAgICAgbV9sYXN0RmV0Y2hlZCA9IERUTS5OVUxMOwotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLSAgICAgIAotICAgIGludCBuZXh0OwotICAgIAotICAgIG9yZy5hcGFjaGUueHBhdGguVmFyaWFibGVTdGFjayB2YXJzOwotICAgIGludCBzYXZlZFN0YXJ0OwotICAgIGlmICgtMSAhPSBtX3N0YWNrRnJhbWUpCi0gICAgewotICAgICAgdmFycyA9IG1fZXhlY0NvbnRleHQuZ2V0VmFyU3RhY2soKTsKLQotICAgICAgLy8gVGhlc2UgdGhyZWUgc3RhdGVtZW50cyBuZWVkIHRvIGJlIGNvbWJpbmVkIGludG8gb25lIG9wZXJhdGlvbi4KLSAgICAgIHNhdmVkU3RhcnQgPSB2YXJzLmdldFN0YWNrRnJhbWUoKTsKLQotICAgICAgdmFycy5zZXRTdGFja0ZyYW1lKG1fc3RhY2tGcmFtZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICAvLyBZdWNrLiAgSnVzdCB0byBzaHV0IHVwIHRoZSBjb21waWxlciEKLSAgICAgIHZhcnMgPSBudWxsOwotICAgICAgc2F2ZWRTdGFydCA9IDA7Ci0gICAgfQotICAgIAotICAgIHRyeQotICAgIHsKLSAgICAgIGlmKERFQlVHKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm1fcGF0dGVybiIrbV9wYXR0ZXJuLnRvU3RyaW5nKCkpOwotCi0gICAgICBkbwotICAgICAgewotICAgICAgICBuZXh0ID0gZ2V0TmV4dE5vZGUoKTsKLSAgCi0gICAgICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgICAgICB7Ci0gICAgICAgICAgaWYoRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVCA9PSBhY2NlcHROb2RlKG5leHQsIG1fZXhlY0NvbnRleHQpKQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgd2hpbGUgKG5leHQgIT0gRFRNLk5VTEwpOwotICAgICAgCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gbmV4dCkKLSAgICAgIHsKLSAgICAgICAgaWYoREVCVUcpCi0gICAgICAgIHsKLSAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5leHQ6ICIrbmV4dCk7Ci0gICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJuYW1lOiAiK21fY2R0bS5nZXROb2RlTmFtZShuZXh0KSk7Ci0gICAgICAgIH0KLSAgICAgICAgaWYgKG51bGwgIT0gbV9jYWNoZWROb2RlcykKLSAgICAgICAgICBtX2NhY2hlZE5vZGVzLmFkZEVsZW1lbnQobV9sYXN0RmV0Y2hlZCk7Ci0gIAotICAgICAgICBtX25leHQrKzsKLSAgCi0gICAgICAgIHJldHVybiBuZXh0OwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7Ci0gIAotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICB9Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICBpZiAoLTEgIT0gbV9zdGFja0ZyYW1lKQotICAgICAgewotICAgICAgICAvLyBUaGVzZSB0d28gc3RhdGVtZW50cyBuZWVkIHRvIGJlIGNvbWJpbmVkIGludG8gb25lIG9wZXJhdGlvbi4KLSAgICAgICAgdmFycy5zZXRTdGFja0ZyYW1lKHNhdmVkU3RhcnQpOwotICAgICAgfQotICAgIH0KLQotICB9Ci0gIAotICAvKioKLSAgICogIFRlc3Qgd2hldGhlciBhIHNwZWNpZmllZCBub2RlIGlzIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgdmlldyBvZiBhCi0gICAqIFRyZWVXYWxrZXIgb3IgTm9kZUl0ZXJhdG9yLiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZQotICAgKiBpbXBsZW1lbnRhdGlvbiBvZiBUcmVlV2Fsa2VyIGFuZCBOb2RlSXRlcmF0b3I7IGl0IGlzIG5vdCBpbnRlbmRlZCB0bwotICAgKiBiZSBjYWxsZWQgZGlyZWN0bHkgZnJvbSB1c2VyIGNvZGUuCi0gICAqIEBwYXJhbSBuICBUaGUgbm9kZSB0byBjaGVjayB0byBzZWUgaWYgaXQgcGFzc2VzIHRoZSBmaWx0ZXIgb3Igbm90LgotICAgKiBAcmV0dXJuICBhIGNvbnN0YW50IHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBub2RlIGlzIGFjY2VwdGVkLAotICAgKiAgIHJlamVjdGVkLCBvciBza2lwcGVkLCBhcyBkZWZpbmVkICBhYm92ZSAuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShpbnQgbiwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUobik7Ci0gICAgICB4Y3R4dC5wdXNoSXRlcmF0b3JSb290KG1fY29udGV4dCk7Ci0gICAgICBpZihERUJVRykKLSAgICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0cmF2ZXJzZXI6ICIrbV90cmF2ZXJzZXIpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCJub2RlOiAiK24pOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiwgIittX2NkdG0uZ2V0Tm9kZU5hbWUobikpOwotICAgICAgICAvLyBpZihtX2NkdG0uZ2V0Tm9kZU5hbWUobikuZXF1YWxzKCJuZWFyLWVhc3QiKSkKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwYXR0ZXJuOiAiK21fcGF0dGVybi50b1N0cmluZygpKTsKLSAgICAgICAgbV9wYXR0ZXJuLmRlYnVnV2hhdFRvU2hvdyhtX3BhdHRlcm4uZ2V0V2hhdFRvU2hvdygpKTsKLSAgICAgIH0KLSAgICAgIAotICAgICAgWE9iamVjdCBzY29yZSA9IG1fcGF0dGVybi5leGVjdXRlKHhjdHh0KTsKLSAgICAgIAotICAgICAgaWYoREVCVUcpCi0gICAgICB7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYW5hbHlzaXM6ICIrSW50ZWdlci50b0JpbmFyeVN0cmluZyhtX2FuYWx5c2lzKSk7Ci0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigic2NvcmU6ICIrc2NvcmUpOwotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInNraXA6ICIrKHNjb3JlID09IE5vZGVUZXN0LlNDT1JFX05PTkUpKTsKLSAgICAgIH0KLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJcbjo6YWNjZXB0Tm9kZSAtIHNjb3JlOiAiK3Njb3JlLm51bSgpKyI6OiIpOwotICAgICAgcmV0dXJuIChzY29yZSA9PSBOb2RlVGVzdC5TQ09SRV9OT05FKSA/IERUTUl0ZXJhdG9yLkZJTFRFUl9TS0lQIAotICAgICAgICAgICAgICAgICAgICA6IERUTUl0ZXJhdG9yLkZJTFRFUl9BQ0NFUFQ7Ci0gICAgfQotICAgIGNhdGNoIChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHNlKQotICAgIHsKLQotICAgICAgLy8gVE9ETzogRml4IHRoaXMuCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihzZS5nZXRNZXNzYWdlKCkpOwotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIHhjdHh0LnBvcEl0ZXJhdG9yUm9vdCgpOwotICAgIH0KLQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvT25lU3RlcEl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL09uZVN0ZXBJdGVyYXRvci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4NmRkMDIxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvT25lU3RlcEl0ZXJhdG9yLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjggKzAsMCBAQAotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgZ2VuZXJhbCBpdGVyYXRvciBmb3IKLSAqIHRob3NlIExvY2F0aW9uU3RlcHMgd2l0aCBvbmx5IG9uZSBzdGVwLCBhbmQgcGVyaGFwcyBhIHByZWRpY2F0ZS4KLSAqIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5heGVzLldhbGtlckZhY3RvcnkjbmV3TG9jUGF0aEl0ZXJhdG9yCi0gKi8KLXB1YmxpYyBjbGFzcyBPbmVTdGVwSXRlcmF0b3IgZXh0ZW5kcyBDaGlsZFRlc3RJdGVyYXRvcgotewotICAvKiogVGhlIHRyYXZlcnNhbCBheGlzIGZyb20gd2hlcmUgdGhlIG5vZGVzIHdpbGwgYmUgZmlsdGVyZWQuICovCi0gIHByb3RlY3RlZCBpbnQgbV9heGlzID0gLTE7Ci0KLSAgLyoqIFRoZSBEVE0gaW5uZXIgdHJhdmVyc2FsIGNsYXNzLCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBzdXBlciBheGlzLiAqLwotICBwcm90ZWN0ZWQgRFRNQXhpc0l0ZXJhdG9yIG1faXRlcmF0b3I7Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIE9uZVN0ZXBJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBBIHJlZmVyZW5jZSB0byB0aGUgQ29tcGlsZXIgdGhhdCBjb250YWlucyB0aGUgb3AgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgb3AgbWFwLCB3aGljaCBjb250YWlucyB0aGUKLSAgICogbG9jYXRpb24gcGF0aCBleHByZXNzaW9uIGZvciB0aGlzIGl0dGVyYXRvci4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBPbmVTdGVwSXRlcmF0b3IoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICBpbnQgZmlyc3RTdGVwUG9zID0gY29tcGlsZXIuZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0gICAgCi0gICAgbV9heGlzID0gV2Fsa2VyRmFjdG9yeS5nZXRBeGlzRnJvbVN0ZXAoY29tcGlsZXIsIGZpcnN0U3RlcFBvcyk7Ci0gICAgCi0gIH0KLSAgCi0gIC8qKgotICAgKiBDcmVhdGUgYSBPbmVTdGVwSXRlcmF0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gaXRlcmF0b3IgVGhlIERUTSBpdGVyYXRvciB3aGljaCB0aGlzIGl0ZXJhdG9yIHdpbGwgdXNlLgotICAgKiBAcGFyYW0gYXhpcyBPbmUgb2YgQXhpcy5DaGlsZCwgZXRjLiwgb3IgLTEgaWYgdGhlIGF4aXMgaXMgdW5rbm93bi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT25lU3RlcEl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBpdGVyYXRvciwgaW50IGF4aXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKG51bGwpOwotICAgIAotICAgIG1faXRlcmF0b3IgPSBpdGVyYXRvcjsKLSAgICBtX2F4aXMgPSBheGlzOwotICAgIGludCB3aGF0VG9TaG93ID0gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEluaXRpYWxpemUgdGhlIGNvbnRleHQgdmFsdWVzIGZvciB0aGlzIGV4cHJlc3Npb24KLSAgICogYWZ0ZXIgaXQgaXMgY2xvbmVkLgotICAgKgotICAgKiBAcGFyYW0gZXhlY0NvbnRleHQgVGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCBmb3IgdGhpcwotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IGNvbnRleHQsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotICAgIHN1cGVyLnNldFJvb3QoY29udGV4dCwgZW52aXJvbm1lbnQpOwotICAgIGlmKG1fYXhpcyA+IC0xKQotICAgICAgbV9pdGVyYXRvciA9IG1fY2R0bS5nZXRBeGlzSXRlcmF0b3IobV9heGlzKTsKLSAgICBtX2l0ZXJhdG9yLnNldFN0YXJ0Tm9kZShtX2NvbnRleHQpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBuZXh0IG5vZGUgdmlhIGdldEZpcnN0QXR0cmlidXRlICYmIGdldE5leHRBdHRyaWJ1dGUuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIHJldHVybiBtX2xhc3RGZXRjaGVkID0gbV9pdGVyYXRvci5uZXh0KCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gQSBuZXcgaXRlcmF0b3IgdGhhdCBjYW4gYmUgdXNlZCB3aXRob3V0IG11dGF0aW5nIHRoaXMgb25lLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBEbyBub3QgYWNjZXNzIHRoZSBsb2NhdGlvbiBwYXRoIGl0dGVyYXRvciBkdXJpbmcgdGhpcyBvcGVyYXRpb24hCi0gICAgCi0gICAgT25lU3RlcEl0ZXJhdG9yIGNsb25lID0gKE9uZVN0ZXBJdGVyYXRvcikgc3VwZXIuY2xvbmUoKTsKLQotICAgIGlmKG1faXRlcmF0b3IgIT0gbnVsbCkKLSAgICB7Ci0gICAgICBjbG9uZS5tX2l0ZXJhdG9yID0gbV9pdGVyYXRvci5jbG9uZUl0ZXJhdG9yKCk7Ci0gICAgfQotICAgIHJldHVybiBjbG9uZTsKLSAgfQotCi0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoaXMgaXMgYSByZXZlcnNlIGF4ZXMuICBPdmVycmlkZXMgQXhlc1dhbGtlciNpc1JldmVyc2VBeGVzLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgZm9yIHRoaXMgY2xhc3MuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2VBeGVzKCkKLSAgewotICAgIHJldHVybiBtX2l0ZXJhdG9yLmlzUmV2ZXJzZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdWItY29udGV4dCBwb3NpdGlvbi4gIEluIG9yZGVyIHRvIGRvIHRoZQotICAgKiByZXZlcnNlIGF4ZXMgY291bnQsIGZvciB0aGUgbW9tZW50IHRoaXMgcmUtc2VhcmNoZXMgdGhlIGF4ZXMKLSAgICogdXAgdG8gdGhlIHByZWRpY2F0ZS4gIEFuIG9wdGltaXphdGlvbiBvbiB0aGlzIGlzIHRvIGNhY2hlCi0gICAqIHRoZSBub2RlcyBzZWFyY2hlZCwgYnV0LCBmb3IgdGhlIG1vbWVudCwgdGhpcyBjYXNlIGlzIHByb2JhYmx5Ci0gICAqIHJhcmUgZW5vdWdoIHRoYXQgdGhlIGFkZGVkIGNvbXBsZXhpdHkgaXNuJ3Qgd29ydGggaXQuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVkaWNhdGVJbmRleCBUaGUgcHJlZGljYXRlIGluZGV4IG9mIHRoZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByaWRpY2F0ZSBpbmRleCwgb3IgLTEuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKGludCBwcmVkaWNhdGVJbmRleCkKLSAgewotICAgIGlmKCFpc1JldmVyc2VBeGVzKCkpCi0gICAgICByZXR1cm4gc3VwZXIuZ2V0UHJveGltaXR5UG9zaXRpb24ocHJlZGljYXRlSW5kZXgpOwotICAgICAgCi0gICAgLy8gQSBuZWdhdGl2ZSBwcmVkaWNhdGUgaW5kZXggc2VlbXMgdG8gb2NjdXIgd2l0aAotICAgIC8vIChwcmVjZWRpbmctc2libGluZzo6Knxmb2xsb3dpbmctc2libGluZzo6KikvYW5jZXN0b3I6OipbcG9zaXRpb24oKV0vKltwb3NpdGlvbigpXQotICAgIC8vIC1zYgotICAgIGlmKHByZWRpY2F0ZUluZGV4IDwgMCkKLSAgICAgIHJldHVybiAtMTsKLSAgICAgIAotICAgIGlmIChtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF0gPD0gMCkKLSAgICB7Ci0gICAgICBYUGF0aENvbnRleHQgeGN0eHQgPSBnZXRYUGF0aENvbnRleHQoKTsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICBPbmVTdGVwSXRlcmF0b3IgY2xvbmUgPSAoT25lU3RlcEl0ZXJhdG9yKSB0aGlzLmNsb25lKCk7Ci0gICAgICAgIAotICAgICAgICBpbnQgcm9vdCA9IGdldFJvb3QoKTsKLSAgICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKHJvb3QpOwotICAgICAgICBjbG9uZS5zZXRSb290KHJvb3QsIHhjdHh0KTsKLQotICAgICAgICBjbG9uZS5zZXRQcmVkaWNhdGVDb3VudChwcmVkaWNhdGVJbmRleCk7Ci0KLSAgICAgICAgLy8gQ291bnQgJ2VtIGFsbAotICAgICAgICBpbnQgY291bnQgPSAxOwotICAgICAgICBpbnQgbmV4dDsKLQotICAgICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5leHQgPSBjbG9uZS5uZXh0Tm9kZSgpKSkKLSAgICAgICAgewotICAgICAgICAgIGNvdW50Kys7Ci0gICAgICAgIH0KLQotICAgICAgICBtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF0gKz0gY291bnQ7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICAgIHsKLQotICAgICAgICAvLyBjYW4ndCBoYXBwZW4KLSAgICAgIH0KLSAgICAgIGZpbmFsbHkKLSAgICAgIHsKLSAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbV9wcm94aW1pdHlQb3NpdGlvbnNbcHJlZGljYXRlSW5kZXhdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvdW50IGJhY2t3YXJkcyBvbmUgcHJveGltaXR5IHBvc2l0aW9uLgotICAgKgotICAgKiBAcGFyYW0gaSBUaGUgcHJlZGljYXRlIGluZGV4LgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgY291bnRQcm94aW1pdHlQb3NpdGlvbihpbnQgaSkKLSAgewotICAgIGlmKCFpc1JldmVyc2VBeGVzKCkpCi0gICAgICBzdXBlci5jb3VudFByb3hpbWl0eVBvc2l0aW9uKGkpOwotICAgIGVsc2UgaWYgKGkgPCBtX3Byb3hpbWl0eVBvc2l0aW9ucy5sZW5ndGgpCi0gICAgICBtX3Byb3hpbWl0eVBvc2l0aW9uc1tpXS0tOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbm9kZSBsaXN0LiAgVGhlIGZ1bmN0aW9uIGlzIHByb2JhYmx5IGlsbAotICAgKiBuYW1lZD8KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICBpZighaXNSZXZlcnNlQXhlcygpKQotICAgICAgcmV0dXJuIHN1cGVyLmdldExhc3RQb3MoeGN0eHQpOwotCi0gICAgaW50IGNvdW50ID0gMDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIE9uZVN0ZXBJdGVyYXRvciBjbG9uZSA9IChPbmVTdGVwSXRlcmF0b3IpIHRoaXMuY2xvbmUoKTsKLQotICAgICAgaW50IHJvb3QgPSBnZXRSb290KCk7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUocm9vdCk7Ci0gICAgICBjbG9uZS5zZXRSb290KHJvb3QsIHhjdHh0KTsKLQotICAgICAgY2xvbmUuc2V0UHJlZGljYXRlQ291bnQodGhpcy5nZXRQcmVkaWNhdGVDb3VudCgpIC0gMSk7Ci0KLSAgICAgIC8vIENvdW50ICdlbSBhbGwKLSAgICAgIC8vIGNvdW50ID0gMTsKLSAgICAgIGludCBuZXh0OwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5leHQgPSBjbG9uZS5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgY291bnQrKzsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgewotCi0gICAgICAvLyBjYW4ndCBoYXBwZW4KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgfQotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJnZXRMYXN0UG9zIC0gcG9zOiAiK2NvdW50KTsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInBvcyAoUmV2ZXJzZUF4ZXNXYWxrZXIpOiAiK2NvdW50KTsKLSAgICByZXR1cm4gY291bnQ7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLQotICAgIHN1cGVyLnJlc2V0KCk7Ci0gICAgaWYobnVsbCAhPSBtX2l0ZXJhdG9yKQotICAgICAgbV9pdGVyYXRvci5yZXNldCgpOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0aGUgYXhpcyBiZWluZyBpdGVyYXRlZCwgaWYgaXQgaXMga25vd24uCi0gICAqIAotICAgKiBAcmV0dXJuIEF4aXMuQ0hJTEQsIGV0Yy4sIG9yIC0xIGlmIHRoZSBheGlzIGlzIG5vdCBrbm93biBvciBpcyBvZiBtdWx0aXBsZSAKLSAgICogdHlwZXMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG1fYXhpczsKLSAgfQotCi0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvT25lU3RlcEl0ZXJhdG9yRm9yd2FyZC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9PbmVTdGVwSXRlcmF0b3JGb3J3YXJkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVkZmU1OTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9PbmVTdGVwSXRlcmF0b3JGb3J3YXJkLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNDQgKzAsMCBAQAotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uQXhpczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNQXhpc1RyYXZlcnNlcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGdlbmVyYWwgaXRlcmF0b3IgZm9yCi0gKiB0aG9zZSBMb2NhdGlvblN0ZXBzIHdpdGggb25seSBvbmUgc3RlcCwgYW5kIHBlcmhhcHMgYSBwcmVkaWNhdGUsIAotICogdGhhdCBvbmx5IGdvIGZvcndhcmQgKGkuZS4gaXQgY2FuIG5vdCBiZSB1c2VkIHdpdGggYW5jZXN0b3JzLCAKLSAqIHByZWNlZGluZywgZXRjLikKLSAqIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5heGVzLldhbGtlckZhY3RvcnkjbmV3TG9jUGF0aEl0ZXJhdG9yCi0gKi8KLXB1YmxpYyBjbGFzcyBPbmVTdGVwSXRlcmF0b3JGb3J3YXJkIGV4dGVuZHMgQ2hpbGRUZXN0SXRlcmF0b3IKLXsKLSAgLyoqIFRoZSB0cmF2ZXJzYWwgYXhpcyBmcm9tIHdoZXJlIHRoZSBub2RlcyB3aWxsIGJlIGZpbHRlcmVkLiAqLwotICBwcm90ZWN0ZWQgaW50IG1fYXhpcyA9IC0xOwotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBPbmVTdGVwSXRlcmF0b3Igb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgQSByZWZlcmVuY2UgdG8gdGhlIENvbXBpbGVyIHRoYXQgY29udGFpbnMgdGhlIG9wIG1hcC4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiB3aXRoaW4gdGhlIG9wIG1hcCwgd2hpY2ggY29udGFpbnMgdGhlCi0gICAqIGxvY2F0aW9uIHBhdGggZXhwcmVzc2lvbiBmb3IgdGhpcyBpdHRlcmF0b3IuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgT25lU3RlcEl0ZXJhdG9yRm9yd2FyZChDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBjb21waWxlci5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLSAgICAKLSAgICBtX2F4aXMgPSBXYWxrZXJGYWN0b3J5LmdldEF4aXNGcm9tU3RlcChjb21waWxlciwgZmlyc3RTdGVwUG9zKTsKLSAgICAKLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhIE9uZVN0ZXBJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGp1c3QgdHJhdmVyc2UgdGhlIHNlbGYgYXhlcy4KLSAgICogCi0gICAqIEBwYXJhbSBheGlzIE9uZSBvZiB0aGUgb3JnLmFwYWNoZS54bWwuZHRtLkF4aXMgaW50ZWdlcnMuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE9uZVN0ZXBJdGVyYXRvckZvcndhcmQoaW50IGF4aXMpCi0gIHsKLSAgICBzdXBlcihudWxsKTsKLSAgICAKLSAgICBtX2F4aXMgPSBheGlzOwotICAgIGludCB3aGF0VG9TaG93ID0gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgfQotCi0gIAotCi0gIAotICAvKioKLSAgICogSW5pdGlhbGl6ZSB0aGUgY29udGV4dCB2YWx1ZXMgZm9yIHRoaXMgZXhwcmVzc2lvbgotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBleGVjQ29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzCi0gICAqIHRyYW5zZm9ybWF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0gICAgc3VwZXIuc2V0Um9vdChjb250ZXh0LCBlbnZpcm9ubWVudCk7Ci0gICAgbV90cmF2ZXJzZXIgPSBtX2NkdG0uZ2V0QXhpc1RyYXZlcnNlcihtX2F4aXMpOwotICAgIAotICB9Ci0gIAotLy8gIC8qKgotLy8gICAqIFJldHVybiB0aGUgZmlyc3Qgbm9kZSBvdXQgb2YgdGhlIG5vZGVzZXQsIGlmIHRoaXMgZXhwcmVzc2lvbiBpcyAKLS8vICAgKiBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIAotLy8gICAqIG5vZGVzZXRzLgotLy8gICAqIDxwPldBUk5JTkc6IERvIG5vdCBtdXRhdGUgdGhpcyBjbGFzcyBmcm9tIHRoaXMgZnVuY3Rpb24hPC9wPgotLy8gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotLy8gICAqIEByZXR1cm4gdGhlIGZpcnN0IG5vZGUgb3V0IG9mIHRoZSBub2Rlc2V0LCBvciBEVE0uTlVMTC4KLS8vICAgKi8KLS8vICBwdWJsaWMgaW50IGFzTm9kZShYUGF0aENvbnRleHQgeGN0eHQpCi0vLyAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotLy8gIHsKLS8vICAgIGlmKGdldFByZWRpY2F0ZUNvdW50KCkgPiAwKQotLy8gICAgICByZXR1cm4gc3VwZXIuYXNOb2RlKHhjdHh0KTsKLS8vICAgICAgCi0vLyAgICBpbnQgY3VycmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0vLyAgICAKLS8vICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY3VycmVudCk7Ci0vLyAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKG1fYXhpcyk7Ci0vLyAgICAKLS8vICAgIFN0cmluZyBsb2NhbE5hbWUgPSBnZXRMb2NhbE5hbWUoKTsKLS8vICAgIFN0cmluZyBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoKTsKLS8vICAgIGludCB3aGF0ID0gbV93aGF0VG9TaG93OwotLy8gICAgCi0vLyAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIndoYXQ6ICIpOwotLy8gICAgLy8gTm9kZVRlc3QuZGVidWdXaGF0VG9TaG93KHdoYXQpOwotLy8gICAgaWYoRFRNRmlsdGVyLlNIT1dfQUxMID09IHdoYXQKLS8vICAgICAgIHx8ICgoRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCAmIHdoYXQpID09IDApCi0vLyAgICAgICB8fCBsb2NhbE5hbWUgPT0gTm9kZVRlc3QuV0lMRAotLy8gICAgICAgfHwgbmFtZXNwYWNlID09IE5vZGVUZXN0LldJTEQpCi0vLyAgICB7Ci0vLyAgICAgIHJldHVybiB0cmF2ZXJzZXIuZmlyc3QoY3VycmVudCk7Ci0vLyAgICB9Ci0vLyAgICBlbHNlCi0vLyAgICB7Ci0vLyAgICAgIGludCB0eXBlID0gZ2V0Tm9kZVR5cGVUZXN0KHdoYXQpOwotLy8gICAgICBpbnQgZXh0ZW5kZWRUeXBlID0gZHRtLmdldEV4cGFuZGVkVHlwZUlEKG5hbWVzcGFjZSwgbG9jYWxOYW1lLCB0eXBlKTsKLS8vICAgICAgcmV0dXJuIHRyYXZlcnNlci5maXJzdChjdXJyZW50LCBleHRlbmRlZFR5cGUpOwotLy8gICAgfQotLy8gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIG5leHQgbm9kZSB2aWEgZ2V0Rmlyc3RBdHRyaWJ1dGUgJiYgZ2V0TmV4dEF0dHJpYnV0ZS4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0TmV4dE5vZGUoKQotICB7Ci0gICAgbV9sYXN0RmV0Y2hlZCA9IChEVE0uTlVMTCA9PSBtX2xhc3RGZXRjaGVkKQotICAgICAgICAgICAgICAgICAgICAgPyBtX3RyYXZlcnNlci5maXJzdChtX2NvbnRleHQpCi0gICAgICAgICAgICAgICAgICAgICA6IG1fdHJhdmVyc2VyLm5leHQobV9jb250ZXh0LCBtX2xhc3RGZXRjaGVkKTsKLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKiAKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUgCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCkKLSAgewotICAgIHJldHVybiBtX2F4aXM7Ci0gIH0KLQotICAKLX0KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL1ByZWRpY2F0ZWROb2RlVGVzdC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9QcmVkaWNhdGVkTm9kZVRlc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWI0NmMzOC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL1ByZWRpY2F0ZWROb2RlVGVzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTI1ICswLDAgQEAKLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5heGVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuU3ViQ29udGV4dExpc3Q7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBQcmVkaWNhdGVkTm9kZVRlc3QgZXh0ZW5kcyBOb2RlVGVzdCBpbXBsZW1lbnRzIFN1YkNvbnRleHRMaXN0Ci17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBBeGVzV2Fsa2VyIHVzaW5nIGEgTG9jUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbG9jUGF0aEl0ZXJhdG9yIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgcGFyZW50IGl0ZXJhdG9yLgotICAgKi8KLSAgUHJlZGljYXRlZE5vZGVUZXN0KExvY1BhdGhJdGVyYXRvciBsb2NQYXRoSXRlcmF0b3IpCi0gIHsKLSAgICBtX2xwaSA9IGxvY1BhdGhJdGVyYXRvcjsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBBeGVzV2Fsa2VyLiAgVGhlIGxvY2F0aW9uIHBhdGggaXRlcmF0b3Igd2lsbCBoYXZlIHRvIGJlIHNldAotICAgKiBiZWZvcmUgdXNlLgotICAgKi8KLSAgUHJlZGljYXRlZE5vZGVUZXN0KCkKLSAgewotICB9Ci0gIAotICAvKioKLSAgICogUmVhZCB0aGUgb2JqZWN0IGZyb20gYSBzZXJpYWxpemF0aW9uIHN0cmVhbS4KLSAgICoKLSAgICogQHBhcmFtIHN0cmVhbSBJbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKQotICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKLSAgICAgIG1fcHJlZGljYXRlSW5kZXggPSAtMTsKLSAgICAgIHJlc2V0UHJveGltaXR5UG9zaXRpb25zKCk7Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oY25mZSk7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIFByZGljYXRlZE5vZGVUZXN0LgotICAgKgotICAgKiBAcmV0dXJuIEEgbmV3IFByZWRpY2F0ZWROb2RlVGVzdCB0aGF0IGNhbiBiZSB1c2VkIHdpdGhvdXQgbXV0YXRpbmcgdGhpcyBvbmUuCi0gICAqCi0gICAqIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotICAgIC8vIERvIG5vdCBhY2Nlc3MgdGhlIGxvY2F0aW9uIHBhdGggaXR0ZXJhdG9yIGR1cmluZyB0aGlzIG9wZXJhdGlvbiEKLSAgICAKLSAgICBQcmVkaWNhdGVkTm9kZVRlc3QgY2xvbmUgPSAoUHJlZGljYXRlZE5vZGVUZXN0KSBzdXBlci5jbG9uZSgpOwotCi0gICAgaWYgKChudWxsICE9IHRoaXMubV9wcm94aW1pdHlQb3NpdGlvbnMpCi0gICAgICAgICAgICAmJiAodGhpcy5tX3Byb3hpbWl0eVBvc2l0aW9ucyA9PSBjbG9uZS5tX3Byb3hpbWl0eVBvc2l0aW9ucykpCi0gICAgewotICAgICAgY2xvbmUubV9wcm94aW1pdHlQb3NpdGlvbnMgPSBuZXcgaW50W3RoaXMubV9wcm94aW1pdHlQb3NpdGlvbnMubGVuZ3RoXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weSh0aGlzLm1fcHJveGltaXR5UG9zaXRpb25zLCAwLAotICAgICAgICAgICAgICAgICAgICAgICBjbG9uZS5tX3Byb3hpbWl0eVBvc2l0aW9ucywgMCwKLSAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tX3Byb3hpbWl0eVBvc2l0aW9ucy5sZW5ndGgpOwotICAgIH0KLSAgICAKLSAgICBpZihjbG9uZS5tX2xwaSA9PSB0aGlzKQotICAgICAgY2xvbmUubV9scGkgPSAoTG9jUGF0aEl0ZXJhdG9yKWNsb25lOwotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIHByZWRpY2F0ZXMgdGhhdCB0aGlzIHdhbGtlciBoYXMuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIHRoYXQgdGhpcyB3YWxrZXIgaGFzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcmVkaWNhdGVDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9wcmVkaWNhdGVzKSA/IDAgOiBtX3ByZWRpY2F0ZXMubGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbnVtYmVyIG9mIHByZWRpY2F0ZXMgdGhhdCB0aGlzIHdhbGtlciBoYXMuICBUaGlzIGRvZXMgbW9yZSAKLSAgICogdGhhdCBvbmUgd291bGQgdGhpbmssIGFzIGl0IGNyZWF0ZXMgYSBuZXcgcHJlZGljYXRlIGFycmF5IG9mIHRoZSAKLSAgICogc2l6ZSBvZiB0aGUgY291bnQgYXJndW1lbnQsIGFuZCBjb3BpZXMgY291bnQgcHJlZGljYXRlcyBpbnRvIHRoZSBuZXcgCi0gICAqIG9uZSBmcm9tIHRoZSBvbGQsIGFuZCB0aGVuIHJlYXNzaWducyB0aGUgcHJlZGljYXRlcyB2YWx1ZS4gIEFsbCB0aGlzIAotICAgKiB0byBrZWVwIGZyb20gaGF2aW5nIHRvIGhhdmUgYSBwcmVkaWNhdGUgY291bnQgdmFsdWUuCi0gICAqCi0gICAqIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIHByZWRpY2F0ZXMsIHdoaWNoIG11c3QgYmUgZXF1YWwgb3IgbGVzcyAKLSAgICogICAgICAgICAgICAgICB0aGFuIHRoZSBleGlzdGluZyBjb3VudC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZWRpY2F0ZUNvdW50KGludCBjb3VudCkKLSAgewotICAgIGlmKGNvdW50ID4gMCkKLSAgICB7Ci0gICAgICBFeHByZXNzaW9uW10gbmV3UHJlZGljYXRlcyA9IG5ldyBFeHByZXNzaW9uW2NvdW50XTsKLSAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgCi0gICAgICB7Ci0gICAgICAgIG5ld1ByZWRpY2F0ZXNbaV0gPSBtX3ByZWRpY2F0ZXNbaV07Ci0gICAgICB9Ci0gICAgICBtX3ByZWRpY2F0ZXMgPSBuZXdQcmVkaWNhdGVzOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBtX3ByZWRpY2F0ZXMgPSBudWxsOwotICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIEluaXQgcHJlZGljYXRlIGluZm8uCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgCi0gICAqICAgICAgICAgICAgICAgICB3YWxrZXIgaW4gdGhlIG9wIG1hcC4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBvcCBjb2RlIHBvc2l0aW9uIG9mIHRoaXMgbG9jYXRpb24gc3RlcC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBpbml0UHJlZGljYXRlSW5mbyhDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBwb3MgPSBjb21waWxlci5nZXRGaXJzdFByZWRpY2F0ZU9wUG9zKG9wUG9zKTsKLQotICAgIGlmKHBvcyA+IDApCi0gICAgICBtX3ByZWRpY2F0ZXMgPSBjb21waWxlci5nZXRDb21waWxlZFByZWRpY2F0ZXMocG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSBwcmVkaWNhdGUgZXhwcmVzc2lvbiBhdCB0aGUgZ2l2ZW4gaW5kZXguCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBJbmRleCBvZiB0aGUgcHJlZGljYXRlLgotICAgKgotICAgKiBAcmV0dXJuIEEgcHJlZGljYXRlIGV4cHJlc3Npb24uCi0gICAqLwotICBFeHByZXNzaW9uIGdldFByZWRpY2F0ZShpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gbV9wcmVkaWNhdGVzW2luZGV4XTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdWItY29udGV4dCBwb3NpdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbm9kZSBwb3NpdGlvbiBvZiB0aGlzIHdhbGtlciBpbiB0aGUgc3ViLWNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcm94aW1pdHlQb3NpdGlvbigpCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0UHJveGltaXR5UG9zaXRpb24gLSBtX3ByZWRpY2F0ZUluZGV4OiAiK21fcHJlZGljYXRlSW5kZXgpOwotICAgIHJldHVybiBnZXRQcm94aW1pdHlQb3NpdGlvbihtX3ByZWRpY2F0ZUluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGN1cnJlbnQgc3ViLWNvbnRleHQgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHBvc2l0aW9uIG9mIHRoaXMgd2Fsa2VyIGluIHRoZSBzdWItY29udGV4dCBub2RlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotICAgIHJldHVybiBnZXRQcm94aW1pdHlQb3NpdGlvbigpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqLwotICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KTsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IHN1Yi1jb250ZXh0IHBvc2l0aW9uLgotICAgKgotICAgKiBAcGFyYW0gcHJlZGljYXRlSW5kZXggVGhlIGluZGV4IG9mIHRoZSBwcmVkaWNhdGUgd2hlcmUgdGhlIHByb3hpbWl0eSAKLSAgICogICAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBiZSB0YWtlbiBmcm9tLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2RlIHBvc2l0aW9uIG9mIHRoaXMgd2Fsa2VyIGluIHRoZSBzdWItY29udGV4dCBub2RlIGxpc3QuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKGludCBwcmVkaWNhdGVJbmRleCkKLSAgewotICAgIHJldHVybiAocHJlZGljYXRlSW5kZXggPj0gMCkgPyBtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF0gOiAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBwcm94aW1pdHkgcG9zaXRpb25zIGNvdW50cy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0UHJveGltaXR5UG9zaXRpb25zKCkKLSAgewotICAgIGludCBuUHJlZGljYXRlcyA9IGdldFByZWRpY2F0ZUNvdW50KCk7Ci0gICAgaWYgKG5QcmVkaWNhdGVzID4gMCkKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX3Byb3hpbWl0eVBvc2l0aW9ucykKLSAgICAgICAgbV9wcm94aW1pdHlQb3NpdGlvbnMgPSBuZXcgaW50W25QcmVkaWNhdGVzXTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuUHJlZGljYXRlczsgaSsrKQotICAgICAgewotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIGluaXRQcm94aW1pdHlQb3NpdGlvbihpKTsKLSAgICAgICAgfQotICAgICAgICBjYXRjaChFeGNlcHRpb24gZSkKLSAgICAgICAgewotICAgICAgICAgIC8vIFRPRE86IEZpeCB0aGlzLi4uCi0gICAgICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGUpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEluaXQgdGhlIHByb3hpbWl0eSBwb3NpdGlvbiB0byB6ZXJvIGZvciBhIGZvcndhcmQgYXhlcy4KLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IGludG8gdGhlIG1fcHJveGltaXR5UG9zaXRpb25zIGFycmF5LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXRQcm94aW1pdHlQb3NpdGlvbihpbnQgaSkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIG1fcHJveGltaXR5UG9zaXRpb25zW2ldID0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb3VudCBmb3J3YXJkIG9uZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBpbmRleCBpbnRvIHRoZSBtX3Byb3hpbWl0eVBvc2l0aW9ucyBhcnJheSwgd2hlcmUgdGhlIGluY3JlbWVudCAKLSAgICogICAgICAgICAgd2lsbCBvY2N1ci4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNvdW50UHJveGltaXR5UG9zaXRpb24oaW50IGkpCi0gIHsKLSAgICBpZiAoaSA8IG1fcHJveGltaXR5UG9zaXRpb25zLmxlbmd0aCkKLSAgICAgIG1fcHJveGltaXR5UG9zaXRpb25zW2ldKys7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpcyBhIHJldmVyc2UgYXhlcy4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZSwgdW5sZXNzIGEgZGVyaXZlZCBjbGFzcyBvdmVycmlkZXMuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1JldmVyc2VBeGVzKCkKLSAgewotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgd2hpY2ggcHJlZGljYXRlIGlzIGV4ZWN1dGluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgY3VycmVudCBwcmVkaWNhdGUgaW5kZXgsIG9yIC0xIGlmIG5vIHByZWRpY2F0ZSBpcyBleGVjdXRpbmcuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFByZWRpY2F0ZUluZGV4KCkKLSAgewotICAgIHJldHVybiBtX3ByZWRpY2F0ZUluZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIFByb2Nlc3MgdGhlIHByZWRpY2F0ZXMuCi0gICAqCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBleGVjdXRpbmcgdGhlIHByZWRpY2F0ZSBleHByZXNzaW9ucy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBib29sZWFuIGV4ZWN1dGVQcmVkaWNhdGVzKGludCBjb250ZXh0LCBYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIAotICAgIGludCBuUHJlZGljYXRlcyA9IGdldFByZWRpY2F0ZUNvdW50KCk7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJuUHJlZGljYXRlczogIituUHJlZGljYXRlcyk7Ci0gICAgaWYgKG5QcmVkaWNhdGVzID09IDApCi0gICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIFByZWZpeFJlc29sdmVyIHNhdmVkUmVzb2x2ZXIgPSB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBtX3ByZWRpY2F0ZUluZGV4ID0gMDsKLSAgICAgIHhjdHh0LnB1c2hTdWJDb250ZXh0TGlzdCh0aGlzKTsKLSAgICAgIHhjdHh0LnB1c2hOYW1lc3BhY2VDb250ZXh0KG1fbHBpLmdldFByZWZpeFJlc29sdmVyKCkpOwotICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNvbnRleHQpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5QcmVkaWNhdGVzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRXhlY3V0aW5nIHByZWRpY2F0ZSBleHByZXNzaW9uIC0gd2FpdGluZyBjb3VudDogIittX2xwaS5nZXRXYWl0aW5nQ291bnQoKSk7Ci0gICAgICAgIFhPYmplY3QgcHJlZCA9IG1fcHJlZGljYXRlc1tpXS5leGVjdXRlKHhjdHh0KTsKLSAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJcbkJhY2sgZnJvbSBleGVjdXRpbmcgcHJlZGljYXRlIGV4cHJlc3Npb24gLSB3YWl0aW5nIGNvdW50OiAiK21fbHBpLmdldFdhaXRpbmdDb3VudCgpKTsKLSAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJwcmVkLmdldFR5cGUoKTogIitwcmVkLmdldFR5cGUoKSk7Ci0gICAgICAgIGlmIChYT2JqZWN0LkNMQVNTX05VTUJFUiA9PSBwcmVkLmdldFR5cGUoKSkKLSAgICAgICAgewotICAgICAgICAgIGlmIChERUJVR19QUkVESUNBVEVDT1VOVElORykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LmZsdXNoKCk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuPT09PT0gc3RhcnQgcHJlZGljYXRlIGNvdW50ID09PT09PT09Iik7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm1fcHJlZGljYXRlSW5kZXg6ICIgKyBtX3ByZWRpY2F0ZUluZGV4KTsKLSAgICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0UHJveGltaXR5UG9zaXRpb24obV9wcmVkaWNhdGVJbmRleCk6ICIKLSAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICsgZ2V0UHJveGltaXR5UG9zaXRpb24obV9wcmVkaWNhdGVJbmRleCkpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwcmVkLm51bSgpOiAiICsgcHJlZC5udW0oKSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgaW50IHByb3hQb3MgPSB0aGlzLmdldFByb3hpbWl0eVBvc2l0aW9uKG1fcHJlZGljYXRlSW5kZXgpOwotICAgICAgICAgIGlmIChwcm94UG9zICE9IChpbnQpIHByZWQubnVtKCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaWYgKERFQlVHX1BSRURJQ0FURUNPVU5USU5HKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxubm9kZSBjb250ZXh0OiAiK25vZGVUb1N0cmluZyhjb250ZXh0KSk7Ci0gICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiaW5kZXggcHJlZGljYXRlIGlzIGZhbHNlOiAiK3Byb3hQb3MpOwotICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuPT09PT0gZW5kIHByZWRpY2F0ZSBjb3VudCA9PT09PT09PSIpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlIGlmIChERUJVR19QUkVESUNBVEVDT1VOVElORykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxubm9kZSBjb250ZXh0OiAiK25vZGVUb1N0cmluZyhjb250ZXh0KSk7Ci0gICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImluZGV4IHByZWRpY2F0ZSBpcyB0cnVlOiAiK3Byb3hQb3MpOwotICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbj09PT09IGVuZCBwcmVkaWNhdGUgY291bnQgPT09PT09PT0iKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgCi0gICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSBwcm94aW1pdHkgaW5kZXggdGhhdCB3aWxsIG5vdCBjaGFuZ2UgZHVyaW5nIHRoZSAKLSAgICAgICAgICAvLyBjb3Vyc2Ugb2YgaXR0ZXJhdGlvbiwgdGhlbiB3ZSBrbm93IHRoZXJlIGNhbiBiZSBubyBtb3JlIHRydWUgCi0gICAgICAgICAgLy8gb2NjdXJhbmNlcyBvZiB0aGlzIHByZWRpY2F0ZSwgc28gZmxhZyB0aGF0IHdlJ3JlIGRvbmUgYWZ0ZXIgCi0gICAgICAgICAgLy8gdGhpcy4KLSAgICAgICAgICBpZihtX3ByZWRpY2F0ZXNbaV0uaXNTdGFibGVOdW1iZXIoKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCFwcmVkLmJvb2woKSkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0KLSAgICAgICAgY291bnRQcm94aW1pdHlQb3NpdGlvbigrK21fcHJlZGljYXRlSW5kZXgpOwotICAgICAgfQotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgIHhjdHh0LnBvcE5hbWVzcGFjZUNvbnRleHQoKTsKLSAgICAgIHhjdHh0LnBvcFN1YkNvbnRleHRMaXN0KCk7Ci0gICAgICBtX3ByZWRpY2F0ZUluZGV4ID0gLTE7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLQotICAgIGludCBuUHJlZGljYXRlcyA9IGdldFByZWRpY2F0ZUNvdW50KCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5QcmVkaWNhdGVzOyBpKyspCi0gICAgewotICAgICAgbV9wcmVkaWNhdGVzW2ldLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICB9Ci0gIH0KLQotICAKLSAgLyoqCi0gICAqIERpYWdub3N0aWNzLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGdpdmUgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBhYm91dCwgb3IgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBJbmZvcm1hdGl2ZSBzdHJpbmcgYWJvdXQgdGhlIGFyZ3VtZW50LgotICAgKi8KLSAgcHJvdGVjdGVkIFN0cmluZyBub2RlVG9TdHJpbmcoaW50IG4pCi0gIHsKLSAgICBpZihEVE0uTlVMTCAhPSBuKQotICAgIHsKLSAgICAgIERUTSBkdG0gPSBtX2xwaS5nZXRYUGF0aENvbnRleHQoKS5nZXREVE0obik7Ci0gICAgICByZXR1cm4gZHRtLmdldE5vZGVOYW1lKG4pICsgInsiICsgKG4rMSkgKyAifSI7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXR1cm4gIm51bGwiOwotICAgIH0KLSAgfQotICAKLSAgLy89PT09PT09PT09PT09PT0gTm9kZUZpbHRlciBJbXBsZW1lbnRhdGlvbiA9PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICogIFRlc3Qgd2hldGhlciBhIHNwZWNpZmllZCBub2RlIGlzIHZpc2libGUgaW4gdGhlIGxvZ2ljYWwgdmlldyBvZiBhCi0gICAqIFRyZWVXYWxrZXIgb3IgTm9kZUl0ZXJhdG9yLiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZQotICAgKiBpbXBsZW1lbnRhdGlvbiBvZiBUcmVlV2Fsa2VyIGFuZCBOb2RlSXRlcmF0b3I7IGl0IGlzIG5vdCBpbnRlbmRlZCB0bwotICAgKiBiZSBjYWxsZWQgZGlyZWN0bHkgZnJvbSB1c2VyIGNvZGUuCi0gICAqIEBwYXJhbSBuICBUaGUgbm9kZSB0byBjaGVjayB0byBzZWUgaWYgaXQgcGFzc2VzIHRoZSBmaWx0ZXIgb3Igbm90LgotICAgKiBAcmV0dXJuICBhIGNvbnN0YW50IHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBub2RlIGlzIGFjY2VwdGVkLAotICAgKiAgIHJlamVjdGVkLCBvciBza2lwcGVkLCBhcyBkZWZpbmVkICBhYm92ZSAuCi0gICAqLwotICBwdWJsaWMgc2hvcnQgYWNjZXB0Tm9kZShpbnQgbikKLSAgewotCi0gICAgWFBhdGhDb250ZXh0IHhjdHh0ID0gbV9scGkuZ2V0WFBhdGhDb250ZXh0KCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUobik7Ci0KLSAgICAgIFhPYmplY3Qgc2NvcmUgPSBleGVjdXRlKHhjdHh0LCBuKTsKLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJcbjo6YWNjZXB0Tm9kZSAtIHNjb3JlOiAiK3Njb3JlLm51bSgpKyI6OiIpOwotICAgICAgaWYgKHNjb3JlICE9IE5vZGVUZXN0LlNDT1JFX05PTkUpCi0gICAgICB7Ci0gICAgICAgIGlmIChnZXRQcmVkaWNhdGVDb3VudCgpID4gMCkKLSAgICAgICAgewotICAgICAgICAgIGNvdW50UHJveGltaXR5UG9zaXRpb24oMCk7Ci0KLSAgICAgICAgICBpZiAoIWV4ZWN1dGVQcmVkaWNhdGVzKG4sIHhjdHh0KSkKLSAgICAgICAgICAgIHJldHVybiBEVE1JdGVyYXRvci5GSUxURVJfU0tJUDsKLSAgICAgICAgfQotCi0gICAgICAgIHJldHVybiBEVE1JdGVyYXRvci5GSUxURVJfQUNDRVBUOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0KLSAgICAgIC8vIFRPRE86IEZpeCB0aGlzLgotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIERUTUl0ZXJhdG9yLkZJTFRFUl9TS0lQOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIG93bmluZyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBvd25pbmcgbG9jYXRpb24gcGF0aCBpdGVyYXRvciwgd2hpY2ggc2hvdWxkIG5vdCBiZSBudWxsLgotICAgKi8KLSAgcHVibGljIExvY1BhdGhJdGVyYXRvciBnZXRMb2NQYXRoSXRlcmF0b3IoKQotICB7Ci0gICAgcmV0dXJuIG1fbHBpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgbG9jYXRpb24gcGF0aCBpdGVyYXRvciBvd25lciBmb3IgdGhpcyB3YWxrZXIuICBCZXNpZGVzIAotICAgKiBpbml0aWFsaXphdGlvbiwgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZHVyaW5nIGNsb25pbmcgb3BlcmF0aW9ucy4KLSAgICoKLSAgICogQHBhcmFtIGxpIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgb3duaW5nIGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMb2NQYXRoSXRlcmF0b3IoTG9jUGF0aEl0ZXJhdG9yIGxpKQotICB7Ci0gICAgbV9scGkgPSBsaTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUgCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqIAotICAgKiBAcmV0dXJuIHRydWUgaWYgdHJhdmVyc2FsIG91dHNpZGUgdGhlIGNvbnRleHQgbm9kZSdzIHN1YnRyZWUgY2FuIG9jY3VyLgotICAgKi8KLSAgIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICAgewotICAgIGludCBuID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgCi0gICAgewotICAgICAgaWYoZ2V0UHJlZGljYXRlKGkpLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICAgIHJldHVybiBmYWxzZTsKLSAgIH0KLSAgIAotICAvKiogVGhpcyBpcyB0cnVlIGlmIG5leHROb2RlIHJldHVybnMgbnVsbC4gKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBib29sZWFuIG1fZm91bmRMYXN0ID0gZmFsc2U7Ci0gICAgCi0gIC8qKiBUaGUgb3duaW5nIGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqICBAc2VyaWFsICovCi0gIHByb3RlY3RlZCBMb2NQYXRoSXRlcmF0b3IgbV9scGk7Ci0gIAotICAvKioKLSAgICogV2hpY2ggcHJlZGljYXRlIHdlIGFyZSBleGVjdXRpbmcuCi0gICAqLwotICB0cmFuc2llbnQgaW50IG1fcHJlZGljYXRlSW5kZXggPSAtMTsKLSAgCi0gIC8qKiBUaGUgbGlzdCBvZiBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuIElzIHN0YXRpYyBhbmQgZG9lcyBub3QgbmVlZCAKLSAgICogIHRvIGJlIGRlZXAgY2xvbmVkLgotICAgKiAgQHNlcmlhbCAKLSAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbltdIG1fcHJlZGljYXRlczsKLQotICAvKioKLSAgICogQW4gYXJyYXkgb2YgY291bnRzIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgbnVtYmVyCi0gICAqIG9mIHByZWRpY2F0ZXMgdGhlIHN0ZXAgY29udGFpbnMuCi0gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludFtdIG1fcHJveGltaXR5UG9zaXRpb25zOwotCi0gIC8qKiBJZiB0cnVlLCBkaWFnbm9zdGljIG1lc3NhZ2VzIGFib3V0IHByZWRpY2F0ZSBleGVjdXRpb24gd2lsbCBiZSBwb3N0ZWQuICAqLwotICBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVR19QUkVESUNBVEVDT1VOVElORyA9IGZhbHNlOwotCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9SZXZlcnNlQXhlc1dhbGtlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9SZXZlcnNlQXhlc1dhbGtlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZmU2ODg1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvUmV2ZXJzZUF4ZXNXYWxrZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI4MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkxvY1BhdGhJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuT3BDb2RlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNQXhpc0l0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vKioKLSAqIFdhbGtlciBmb3IgYSByZXZlcnNlIGF4ZXMuCi0gKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI3ByZWRpY2F0ZXMiPlhQYXRoIDIuNCBQcmVkaWNhdGVzPC9hPgotICovCi1wdWJsaWMgY2xhc3MgUmV2ZXJzZUF4ZXNXYWxrZXIgZXh0ZW5kcyBBeGVzV2Fsa2VyCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBBeGVzV2Fsa2VyIHVzaW5nIGEgTG9jUGF0aEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbG9jUGF0aEl0ZXJhdG9yIFRoZSBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yIHRoYXQgJ293bnMnIHRoaXMgd2Fsa2VyLgotICAgKi8KLSAgUmV2ZXJzZUF4ZXNXYWxrZXIoTG9jUGF0aEl0ZXJhdG9yIGxvY1BhdGhJdGVyYXRvciwgaW50IGF4aXMpCi0gIHsKLSAgICBzdXBlcihsb2NQYXRoSXRlcmF0b3IsIGF4aXMpOwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IHRoZSByb290IG5vZGUgb2YgdGhlIFRyZWVXYWxrZXIuCi0gICAqIChOb3QgcGFydCBvZiB0aGUgRE9NMiBUcmVlV2Fsa2VyIGludGVyZmFjZSkuCi0gICAqCi0gICAqIEBwYXJhbSByb290IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBzdGVwLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgcm9vdCkKLSAgewotICAgIHN1cGVyLnNldFJvb3Qocm9vdCk7Ci0gICAgbV9pdGVyYXRvciA9IGdldERUTShyb290KS5nZXRBeGlzSXRlcmF0b3IobV9heGlzKTsKLSAgICBtX2l0ZXJhdG9yLnNldFN0YXJ0Tm9kZShyb290KTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgbmV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyIG9uIHRoZSBheGVzLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBuZXh0IG5vZGUgaW4gZG9jdW1lbnQgb3JkZXIgb24gdGhlIGF4ZXMsIG9yIG51bGwuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldE5leHROb2RlKCkKLSAgewotICAgIGlmIChtX2ZvdW5kTGFzdCkKLSAgICAgIHJldHVybiBEVE0uTlVMTDsKLQotICAgIGludCBuZXh0ID0gbV9pdGVyYXRvci5uZXh0KCk7Ci0gICAgCi0gICAgaWYgKG1faXNGcmVzaCkKLSAgICAgIG1faXNGcmVzaCA9IGZhbHNlOwotCi0gICAgaWYgKERUTS5OVUxMID09IG5leHQpCi0gICAgICB0aGlzLm1fZm91bmRMYXN0ID0gdHJ1ZTsKLQotICAgIHJldHVybiBuZXh0OwotICB9Ci0KLQotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpcyBhIHJldmVyc2UgYXhlcy4gIE92ZXJyaWRlcyBBeGVzV2Fsa2VyI2lzUmV2ZXJzZUF4ZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBmb3IgdGhpcyBjbGFzcy4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzUmV2ZXJzZUF4ZXMoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotLy8gIC8qKgotLy8gICAqICBTZXQgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgVHJlZVdhbGtlci4KLS8vICAgKgotLy8gICAqIEBwYXJhbSByb290IFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBzdGVwLgotLy8gICAqLwotLy8gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IHJvb3QpCi0vLyAgewotLy8gICAgc3VwZXIuc2V0Um9vdChyb290KTsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdWItY29udGV4dCBwb3NpdGlvbi4gIEluIG9yZGVyIHRvIGRvIHRoZQotICAgKiByZXZlcnNlIGF4ZXMgY291bnQsIGZvciB0aGUgbW9tZW50IHRoaXMgcmUtc2VhcmNoZXMgdGhlIGF4ZXMKLSAgICogdXAgdG8gdGhlIHByZWRpY2F0ZS4gIEFuIG9wdGltaXphdGlvbiBvbiB0aGlzIGlzIHRvIGNhY2hlCi0gICAqIHRoZSBub2RlcyBzZWFyY2hlZCwgYnV0LCBmb3IgdGhlIG1vbWVudCwgdGhpcyBjYXNlIGlzIHByb2JhYmx5Ci0gICAqIHJhcmUgZW5vdWdoIHRoYXQgdGhlIGFkZGVkIGNvbXBsZXhpdHkgaXNuJ3Qgd29ydGggaXQuCi0gICAqCi0gICAqIEBwYXJhbSBwcmVkaWNhdGVJbmRleCBUaGUgcHJlZGljYXRlIGluZGV4IG9mIHRoZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHByaWRpY2F0ZSBpbmRleCwgb3IgLTEuCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKGludCBwcmVkaWNhdGVJbmRleCkKLSAgewotICAgIC8vIEEgbmVnYXRpdmUgcHJlZGljYXRlIGluZGV4IHNlZW1zIHRvIG9jY3VyIHdpdGgKLSAgICAvLyAocHJlY2VkaW5nLXNpYmxpbmc6Oip8Zm9sbG93aW5nLXNpYmxpbmc6OiopL2FuY2VzdG9yOjoqW3Bvc2l0aW9uKCldLypbcG9zaXRpb24oKV0KLSAgICAvLyAtc2IKLSAgICBpZihwcmVkaWNhdGVJbmRleCA8IDApCi0gICAgICByZXR1cm4gLTE7Ci0gICAgICAKLSAgICBpZiAobV9wcm94aW1pdHlQb3NpdGlvbnNbcHJlZGljYXRlSW5kZXhdIDw9IDApCi0gICAgewotICAgICAgQXhlc1dhbGtlciBzYXZlZFdhbGtlciA9IHdpKCkuZ2V0TGFzdFVzZWRXYWxrZXIoKTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIFJldmVyc2VBeGVzV2Fsa2VyIGNsb25lID0gKFJldmVyc2VBeGVzV2Fsa2VyKSB0aGlzLmNsb25lKCk7Ci0KLSAgICAgICAgY2xvbmUuc2V0Um9vdCh0aGlzLmdldFJvb3QoKSk7Ci0KLSAgICAgICAgY2xvbmUuc2V0UHJlZGljYXRlQ291bnQocHJlZGljYXRlSW5kZXgpOwotCi0gICAgICAgIGNsb25lLnNldFByZXZXYWxrZXIobnVsbCk7Ci0gICAgICAgIGNsb25lLnNldE5leHRXYWxrZXIobnVsbCk7Ci0gICAgICAgIHdpKCkuc2V0TGFzdFVzZWRXYWxrZXIoY2xvbmUpOwotCi0gICAgICAgIC8vIENvdW50ICdlbSBhbGwKLSAgICAgICAgaW50IGNvdW50ID0gMTsKLSAgICAgICAgaW50IG5leHQ7Ci0KLSAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuZXh0ID0gY2xvbmUubmV4dE5vZGUoKSkpCi0gICAgICAgIHsKLSAgICAgICAgICBjb3VudCsrOwotICAgICAgICB9Ci0KLSAgICAgICAgbV9wcm94aW1pdHlQb3NpdGlvbnNbcHJlZGljYXRlSW5kZXhdICs9IGNvdW50OwotICAgICAgfQotICAgICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgICB7Ci0KLSAgICAgICAgLy8gY2FuJ3QgaGFwcGVuCi0gICAgICB9Ci0gICAgICBmaW5hbGx5Ci0gICAgICB7Ci0gICAgICAgIHdpKCkuc2V0TGFzdFVzZWRXYWxrZXIoc2F2ZWRXYWxrZXIpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBtX3Byb3hpbWl0eVBvc2l0aW9uc1twcmVkaWNhdGVJbmRleF07Ci0gIH0KLQotICAvKioKLSAgICogQ291bnQgYmFja3dhcmRzIG9uZSBwcm94aW1pdHkgcG9zaXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBpIFRoZSBwcmVkaWNhdGUgaW5kZXguCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBjb3VudFByb3hpbWl0eVBvc2l0aW9uKGludCBpKQotICB7Ci0gICAgaWYgKGkgPCBtX3Byb3hpbWl0eVBvc2l0aW9ucy5sZW5ndGgpCi0gICAgICBtX3Byb3hpbWl0eVBvc2l0aW9uc1tpXS0tOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoaXMgbm9kZSBsaXN0LiAgVGhlIGZ1bmN0aW9uIGlzIHByb2JhYmx5IGlsbAotICAgKiBuYW1lZD8KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGlzIG5vZGUgbGlzdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLQotICAgIGludCBjb3VudCA9IDA7Ci0gICAgQXhlc1dhbGtlciBzYXZlZFdhbGtlciA9IHdpKCkuZ2V0TGFzdFVzZWRXYWxrZXIoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIFJldmVyc2VBeGVzV2Fsa2VyIGNsb25lID0gKFJldmVyc2VBeGVzV2Fsa2VyKSB0aGlzLmNsb25lKCk7Ci0KLSAgICAgIGNsb25lLnNldFJvb3QodGhpcy5nZXRSb290KCkpOwotCi0gICAgICBjbG9uZS5zZXRQcmVkaWNhdGVDb3VudCh0aGlzLmdldFByZWRpY2F0ZUNvdW50KCkgLSAxKTsKLQotICAgICAgY2xvbmUuc2V0UHJldldhbGtlcihudWxsKTsKLSAgICAgIGNsb25lLnNldE5leHRXYWxrZXIobnVsbCk7Ci0gICAgICB3aSgpLnNldExhc3RVc2VkV2Fsa2VyKGNsb25lKTsKLQotICAgICAgLy8gQ291bnQgJ2VtIGFsbAotICAgICAgLy8gY291bnQgPSAxOwotICAgICAgaW50IG5leHQ7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobmV4dCA9IGNsb25lLm5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBjb3VudCsrOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0KLSAgICAgIC8vIGNhbid0IGhhcHBlbgotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgd2koKS5zZXRMYXN0VXNlZFdhbGtlcihzYXZlZFdhbGtlcik7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNvdW50OwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJucyB0cnVlIGlmIGFsbCB0aGUgbm9kZXMgaW4gdGhlIGl0ZXJhdGlvbiB3ZWxsIGJlIHJldHVybmVkIGluIGRvY3VtZW50IAotICAgKiBvcmRlci4KLSAgICogV2FybmluZzogVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgc2V0Um9vdCBoYXMgYmVlbiBjYWxsZWQhCi0gICAqIAotICAgKiBAcmV0dXJuIGZhbHNlLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaXNEb2NPcmRlcmVkKCkKLSAgewotICAgIHJldHVybiBmYWxzZTsgIC8vIEkgdGhpbmsuCi0gIH0KLSAgCi0gIC8qKiBUaGUgRFRNIGlubmVyIHRyYXZlcnNhbCBjbGFzcywgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgc3VwZXIgYXhpcy4gKi8KLSAgcHJvdGVjdGVkIERUTUF4aXNJdGVyYXRvciBtX2l0ZXJhdG9yOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9TZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9TZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzVjZjMxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0MSArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguYXhlczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5ET01FeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhbiBvcHRpbWl6ZWQgaXRlcmF0b3IgZm9yCi0gKiAiLiIgcGF0dGVybnMsIHRoYXQgaXMsIHRoZSBzZWxmIGF4ZXMgd2l0aG91dCBhbnkgcHJlZGljYXRlcy4gIAotICogQHNlZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuV2Fsa2VyRmFjdG9yeSNuZXdMb2NQYXRoSXRlcmF0b3IKLSAqLwotcHVibGljIGNsYXNzIFNlbGZJdGVyYXRvck5vUHJlZGljYXRlIGV4dGVuZHMgTG9jUGF0aEl0ZXJhdG9yCi17Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFNlbGZJdGVyYXRvck5vUHJlZGljYXRlIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIEEgcmVmZXJlbmNlIHRvIHRoZSBDb21waWxlciB0aGF0IGNvbnRhaW5zIHRoZSBvcCBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gd2l0aGluIHRoZSBvcCBtYXAsIHdoaWNoIGNvbnRhaW5zIHRoZQotICAgKiBsb2NhdGlvbiBwYXRoIGV4cHJlc3Npb24gZm9yIHRoaXMgaXR0ZXJhdG9yLgotICAgKiBAcGFyYW0gYW5hbHlzaXMgQW5hbHlzaXMgYml0cy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBTZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZShDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHN1cGVyKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMsIGZhbHNlKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhIFNlbGZJdGVyYXRvck5vUHJlZGljYXRlIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIEEgcmVmZXJlbmNlIHRvIHRoZSBDb21waWxlciB0aGF0IGNvbnRhaW5zIHRoZSBvcCBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gd2l0aGluIHRoZSBvcCBtYXAsIHdoaWNoIGNvbnRhaW5zIHRoZQotICAgKiBsb2NhdGlvbiBwYXRoIGV4cHJlc3Npb24gZm9yIHRoaXMgaXR0ZXJhdG9yLgotICAgKiBAcGFyYW0gYW5hbHlzaXMgQW5hbHlzaXMgYml0cy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgU2VsZkl0ZXJhdG9yTm9QcmVkaWNhdGUoKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBzdXBlcihudWxsKTsKLSAgfQotCi0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIE5vZGVJdGVyYXRvciBpcyBjcmVhdGVkLCB0aGUgZmlyc3QgY2FsbAotICAgKiB0byBuZXh0Tm9kZSgpIHJldHVybnMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiAgVGhlIG5leHQgPGNvZGU+Tm9kZTwvY29kZT4gaW4gdGhlIHNldCBiZWluZyBpdGVyYXRlZCBvdmVyLCBvcgotICAgKiAgIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBubyBtb3JlIG1lbWJlcnMgaW4gdGhhdCBzZXQuCi0gICAqLwotICBwdWJsaWMgaW50IG5leHROb2RlKCkKLSAgewotCi0gICAgLy8gSWYgdGhlIGNhY2hlIGlzIG9uLCBhbmQgdGhlIG5vZGUgaGFzIGFscmVhZHkgYmVlbiBmb3VuZCwgdGhlbiAKLSAgICAvLyBqdXN0IHJldHVybiBmcm9tIHRoZSBsaXN0LgotICAgIC8vIElmIHRoZSBjYWNoZSBpcyBvbiwgYW5kIHRoZSBub2RlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHRoZW4gCi0gICAgLy8ganVzdCByZXR1cm4gZnJvbSB0aGUgbGlzdC4KLSAgICBpZiAoKG51bGwgIT0gbV9jYWNoZWROb2RlcykKLSAgICAgICAgICAgICYmIChtX25leHQgPCBtX2NhY2hlZE5vZGVzLnNpemUoKSkpCi0gICAgewotICAgICAgaW50IG5leHQgPSBtX2NhY2hlZE5vZGVzLmVsZW1lbnRBdChtX25leHQpOwotICAgIAotICAgICAgaW5jcmVtZW50TmV4dFBvc2l0aW9uKCk7Ci0gICAgICBtX2N1cnJlbnRDb250ZXh0Tm9kZSA9IG5leHQ7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLQotICAgIGlmIChtX2ZvdW5kTGFzdCkKLSAgICB7Ci0gICAgICBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotCi0gICAgaW50IG5leHQ7Ci0gICAgRFRNIGR0bSA9IG1fY2R0bTsKLQotICAgIG1fbGFzdEZldGNoZWQgPSBuZXh0ID0gKERUTS5OVUxMID09IG1fbGFzdEZldGNoZWQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICA/IG1fY29udGV4dAotICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBEVE0uTlVMTDsKLQotICAgIC8vIG1fbGFzdEZldGNoZWQgPSBuZXh0OwotICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0KQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChtX2xhc3RGZXRjaGVkKTsKLQotICAgICAgbV9uZXh0Kys7Ci0KLSAgICAgIHJldHVybiBuZXh0OwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9mb3VuZExhc3QgPSB0cnVlOwotCi0gICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgaWYgdGhpcyBleHByZXNzaW9uIGlzIAotICAgKiBhIG5vZGVzZXQgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIAotICAgKiBub2Rlc2V0cy4gIERlcml2ZWQgY2xhc3NlcyBzaG91bGQgdHJ5IGFuZCBvdmVycmlkZSB0aGlzIGFuZCByZXR1cm4gYSAKLSAgICogdmFsdWUgd2l0aG91dCBoYXZpbmcgdG8gZG8gYSBjbG9uZSBvcGVyYXRpb24uCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBub2RlIG91dCBvZiB0aGUgbm9kZXNldCwgb3IgRFRNLk5VTEwuCi0gICAqLwotICBwdWJsaWMgaW50IGFzTm9kZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICB9Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICogVGhpcyBwcm9iYWJseSB3aWxsIG5lZWQgdG8gYmUgb3ZlcnJpZGRlZCBieSBkZXJpdmVkIGNsYXNzZXMuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gYmUgaXR0ZXJhdGVkIHRvLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0UG9zKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotICAgIHJldHVybiAxOwotICB9Ci0KLQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvU3ViQ29udGV4dExpc3QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvU3ViQ29udGV4dExpc3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTU5YmYzYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL1N1YkNvbnRleHRMaXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLSAKLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBBIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZSBpcyBhIHN1YiBjb250ZXh0IG5vZGUgbGlzdCwgbWVhbmluZyBpdAotICogaXMgYSBub2RlIGxpc3QgZm9yIGEgbG9jYXRpb24gcGF0aCBzdGVwIGZvciBhIHByZWRpY2F0ZS4KLSAqLwotcHVibGljIGludGVyZmFjZSBTdWJDb250ZXh0TGlzdAotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbm9kZSBsaXN0LCB3aGljaCwgaW4gdGhlIFhTTFQgMSBiYXNlZCAKLSAgICogY291bnRpbmcgc3lzdGVtLCBpcyB0aGUgbGFzdCBpbmRleCBwb3NpdGlvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgbm9kZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRMYXN0UG9zKFhQYXRoQ29udGV4dCB4Y3R4dCk7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBzdWItY29udGV4dCBwb3NpdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIGxpc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFByb3hpbWl0eVBvc2l0aW9uKFhQYXRoQ29udGV4dCB4Y3R4dCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL1VuaW9uUGF0aEl0ZXJhdG9yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzL1VuaW9uUGF0aEl0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU3NzBlMWMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9VbmlvblBhdGhJdGVyYXRvci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLk9wQ29kZXM7Ci0KLS8vIERPTSBJbXBvcnRzCi0vL2ltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkRPTUV4Y2VwdGlvbjsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi0vLyBYYWxhbiBJbXBvcnRzCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLk9iamVjdFBvb2w7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBUaGlzIGNsYXNzIGV4dGVuZHMgTm9kZVNldERUTSwgd2hpY2ggaW1wbGVtZW50cyBEVE1JdGVyYXRvciwKLSAqIGFuZCBmZXRjaGVzIG5vZGVzIG9uZSBhdCBhIHRpbWUgaW4gZG9jdW1lbnQgb3JkZXIgYmFzZWQgb24gYSBYUGF0aAotICogPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtVW5pb25FeHByIj5VbmlvbkV4cHI8L2E+LgotICogQXMgZWFjaCBub2RlIGlzIGl0ZXJhdGVkIHZpYSBuZXh0Tm9kZSgpLCB0aGUgbm9kZSBpcyBhbHNvIHN0b3JlZAotICogaW4gdGhlIE5vZGVWZWN0b3IsIHNvIHRoYXQgcHJldmlvdXNOb2RlKCkgY2FuIGVhc2lseSBiZSBkb25lLgotICovCi1wdWJsaWMgY2xhc3MgVW5pb25QYXRoSXRlcmF0b3IgZXh0ZW5kcyBFeHByZXNzaW9uCi0gICAgICAgIGltcGxlbWVudHMgQ2xvbmVhYmxlLCBEVE1JdGVyYXRvciwgamF2YS5pby5TZXJpYWxpemFibGUKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0b3IgdG8gY3JlYXRlIGFuIGluc3RhbmNlIHdoaWNoIHlvdSBjYW4gYWRkIGxvY2F0aW9uIHBhdGhzIHRvLgotICAgKi8KLSAgcHVibGljIFVuaW9uUGF0aEl0ZXJhdG9yKCkKLSAgewotCi0gICAgc3VwZXIoKTsKLQotICAgIC8vIG1fbXV0YWJsZSA9IGZhbHNlOwotICAgIC8vIG1fY2FjaGVOb2RlcyA9IGZhbHNlOwotICAgIG1faXRlcmF0b3JzID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBjb250ZXh0IHZhbHVlcyBmb3IgdGhpcyBleHByZXNzaW9uIAotICAgKiBhZnRlciBpdCBpcyBjbG9uZWQuCi0gICAqCi0gICAqIEBwYXJhbSBleGVjQ29udGV4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0IGZvciB0aGlzIAotICAgKiB0cmFuc2Zvcm1hdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJvb3QoaW50IGNvbnRleHQsIE9iamVjdCBlbnZpcm9ubWVudCkKLSAgewotICAgIHRoaXMubV9leGVjQ29udGV4dCA9IChYUGF0aENvbnRleHQpZW52aXJvbm1lbnQ7Ci0gICAgdGhpcy5tX2N1cnJlbnRDb250ZXh0Tm9kZSA9IGNvbnRleHQ7Ci0gICAgdGhpcy5tX2NvbnRleHQgPSBjb250ZXh0OwotICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICBtX25leHQgPSAwOwotICAgIG1fbGFzdCA9IDA7Ci0gICAgbV9mb3VuZExhc3QgPSBmYWxzZTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1faXRlcmF0b3JzKQotICAgICAgewotICAgICAgICBpbnQgbiA9IG1faXRlcmF0b3JzLmxlbmd0aDsKLSAgCi0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgICAgICB7Ci0gICAgICAgICAgbV9pdGVyYXRvcnNbaV0gPSAoKExvY1BhdGhJdGVyYXRvciltX2l0ZXJhdG9yc1tpXSkuYXNJdGVyYXRvcihtX2V4ZWNDb250ZXh0LCBjb250ZXh0KTsKLSAgICAgICAgICBtX2l0ZXJhdG9yc1tpXS5zZXRSb290KGNvbnRleHQsIGVudmlyb25tZW50KTsKLSAgICAgICAgICBtX2l0ZXJhdG9yc1tpXS5uZXh0Tm9kZSgpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotICAgIGNhdGNoKEV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKiBDb250cm9sIG92ZXIgd2hldGhlciBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlc2V0IHRoZSBpdGVyYXRvci4gKi8KLSAgcHJpdmF0ZSBib29sZWFuIG1fYWxsb3dEZXRhY2ggPSB0cnVlOwotICAKLSAgLyoqCi0gICAqIFNwZWNpZnkgaWYgaXQncyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhlIGl0ZXJhdG9yIGZvciByZXVzZS4KLSAgICogCi0gICAqIEBwYXJhbSBhbGxvd1JlbGVhc2UgdHJ1ZSBpZiBpdCBpcyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhpcyBpdGVyYXRvciAKLSAgICogZm9yIHBvb2xpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBhbGxvd0RldGFjaFRvUmVsZWFzZShib29sZWFuIGFsbG93UmVsZWFzZSkKLSAgewotICAgIG1fYWxsb3dEZXRhY2ggPSBhbGxvd1JlbGVhc2U7Ci0gIH0KLQotICAvKioKLSAgICogIERldGFjaGVzIHRoZSBpdGVyYXRvciBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQgb3ZlciwgcmVsZWFzaW5nCi0gICAqIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IgaW4gdGhlIElOVkFMSUQKLSAgICogc3RhdGUuIEFmdGVyPGNvZGU+ZGV0YWNoPC9jb2RlPiBoYXMgYmVlbiBpbnZva2VkLCBjYWxscyB0bwotICAgKiA8Y29kZT5uZXh0Tm9kZTwvY29kZT4gb3I8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwgcmFpc2UgdGhlCi0gICAqIGV4Y2VwdGlvbiBJTlZBTElEX1NUQVRFX0VSUi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLQotICAgIGlmKG1fYWxsb3dEZXRhY2gpCi0gICAgewotICAgICAgbV9jYWNoZWROb2RlcyA9IG51bGw7Ci0gICAgICBtX2V4ZWNDb250ZXh0ID0gbnVsbDsKLSAgICAgIC8vIG1fcHJlZml4UmVzb2x2ZXIgPSBudWxsOwotICAgICAgLy8gbV9jZHRtID0gbnVsbDsKLSAgICAgIAotICAgICAgaWYgKG51bGwgIT0gbV9pdGVyYXRvcnMpCi0gICAgICB7Ci0gICAgICAgIGludCBuID0gbV9pdGVyYXRvcnMubGVuZ3RoOwotICAKLSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBtX2l0ZXJhdG9yc1tpXS5kZXRhY2goKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gIAotICAvLyAgICBpbnQgbiA9IG1faXRlcmF0b3JzLmxlbmd0aDsKLSAgLy8KLSAgLy8gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gIC8vICAgIHsKLSAgLy8gICAgICBtX2l0ZXJhdG9yc1tpXS5kZXRhY2goKTsKLSAgLy8gICAgfQotICAKLSAgICAgIG1fY2xvbmVzLmZyZWVJbnN0YW5jZSh0aGlzKTsKLSAgICB9Ci0gIH0KLQotICAvKiogUG9vbCBvZiBVbmlvblBhdGhJdGVyYXRvcnMuICAoVGhlIG5lZWQgZm9yIHRoaXMgaGFzIHRvIGJlIHJlLWV2YWx1YXRlZC4gIC1zYikgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBJdGVyYXRvclBvb2wgbV9jbG9uZXMgPSBuZXcgSXRlcmF0b3JQb29sKHRoaXMpOwotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoaXMgaXRlcmF0b3IsIG1lYW5pbmcgY3JlYXRlIGEgY2xvbmUgdGhhdCBjYW4gIAotICAgKiBzdG9yZSBzdGF0ZSwgYW5kIGluaXRpYWxpemUgaXQgZm9yIGZhc3QgZXhlY3V0aW9uIGZyb20gCi0gICAqIHRoZSBjdXJyZW50IHJ1bnRpbWUgc3RhdGUuICBXaGVuIHRoaXMgaXMgY2FsbGVkLCBubyBhY3R1YWwgCi0gICAqIHF1ZXJ5IGZyb20gdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGlzIHBlcmZvcm1lZC4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBBbiBYTm9kZVNldCByZWZlcmVuY2UgdGhhdCBob2xkcyB0aGlzIGl0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBVbmlvblBhdGhJdGVyYXRvciBjbG9uZSA9Ci0gICAgICAoVW5pb25QYXRoSXRlcmF0b3IpIG1fY2xvbmVzLmdldEluc3RhbmNlKCk7Ci0KLSAgICBpbnQgY3VycmVudCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgY2xvbmUuc2V0Um9vdChjdXJyZW50LCB4Y3R4dCk7Ci0KLSAgICByZXR1cm4gbmV3IFhOb2RlU2V0KGNsb25lKTsKLSAgfQotCi0gIC8qKiBJZiB0aGlzIGl0ZXJhdG9yIG5lZWRzIHRvIGNhY2hlIG5vZGVzIHRoYXQgYXJlIGZldGNoZWQsIHRoZXkKLSAgICogYXJlIHN0b3JlZCBoZXJlLiAgICovCi0gIHRyYW5zaWVudCBOb2RlU2V0RFRNIG1fY2FjaGVkTm9kZXMgPSBudWxsOwotCi0gIC8qKiBUaGUgaW5kZXggb2YgdGhlIG5leHQgbm9kZSB0byBiZSBmZXRjaGVkLiAgVXNlZnVsIGlmIHRoaXMgCi0gICAqIGlzIGEgY2FjaGVkIGl0ZXJhdG9yLCBhbmQgaXMgYmVpbmcgdXNlZCBhcyByYW5kb20gYWNjZXNzIAotICAgKiBOb2RlTGlzdC4gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIGludCBtX25leHQgPSAwOwotCi0gIC8qKgotICAgKiBJZiBzZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpIGlzIGNhbGxlZCwgdGhlbiBub2RlcyB3aWxsCi0gICAqIGJlIGNhY2hlZC4gIFRoZXkgYXJlIG5vdCBjYWNoZWQgYnkgZGVmYXVsdC4KLSAgICoKLSAgICogQHBhcmFtIGIgVHJ1ZSBpZiB0aGlzIGl0ZXJhdG9yIHNob3VsZCBjYWNoZSBub2Rlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFNob3VsZENhY2hlTm9kZXMoYm9vbGVhbiBiKQotICB7Ci0KLSAgICBpZiAoYikKLSAgICAgIG1fY2FjaGVkTm9kZXMgPSBuZXcgTm9kZVNldERUTShnZXREVE1NYW5hZ2VyKCkpOwotICAgIGVsc2UKLSAgICAgIG1fY2FjaGVkTm9kZXMgPSBudWxsOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbHMgaWYgdGhpcyBpdGVyYXRvciBjYW4gaGF2ZSBub2RlcyBhZGRlZCB0byBpdCBvciBzZXQgdmlhIAotICAgKiB0aGUgPGNvZGU+c2V0SXRlbShpbnQgbm9kZSwgaW50IGluZGV4KTwvY29kZT4gbWV0aG9kLgotICAgKiAKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBub2RlbGlzdCBjYW4gYmUgbXV0YXRlZC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzTXV0YWJsZSgpCi0gIHsKLSAgICByZXR1cm4gKG1fY2FjaGVkTm9kZXMgIT0gbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBub2RlIHNldC4KLSAgICogQHBhcmFtIGkgTXVzdCBiZSBhIHZhbGlkIGluZGV4LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Q3VycmVudFBvcyhpbnQgaSkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9jYWNoZWROb2RlcykKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAotICAgICAgICAiVGhpcyBOb2RlU2V0RFRNIGNhbiBub3QgZG8gaW5kZXhpbmcgb3IgY291bnRpbmcgZnVuY3Rpb25zISIpOwotCi0gICAgbV9uZXh0ID0gaTsKLQotICAgIG1fY2FjaGVkTm9kZXMuc2V0Q3VycmVudFBvcyhpKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbGVuZ3RoIG9mIHRoaXMgbGlzdCwgb3IgemVybyBpcyB0aGlzIGlzIG5vdCBhIGNhY2hlZCBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBzaXplKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9jYWNoZWROb2RlcykKLSAgICAgIHJldHVybiAwOwotCi0gICAgcmV0dXJuIG1fY2FjaGVkTm9kZXMuc2l6ZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHRoaXMgTm9kZVNldERUTSBpcyAiZnJlc2giLCBpbiBvdGhlciB3b3JkcywgaWYKLSAgICogdGhlIGZpcnN0IG5leHROb2RlKCkgdGhhdCBpcyBjYWxsZWQgd2lsbCByZXR1cm4gdGhlCi0gICAqIGZpcnN0IG5vZGUgaW4gdGhlIHNldC4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZSBpdGVyYXRpb24gaGFzIG5vdCB5ZXQgYmVndW4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc0ZyZXNoKCkKLSAgewotICAgIHJldHVybiAobV9uZXh0ID09IDApOwotICB9Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBwcmV2aW91cyBub2RlIGluIHRoZSBzZXQgYW5kIG1vdmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgYmFja3dhcmRzIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBwcmV2aW91cyA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsCi0gICAqICAgb3I8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBwcmV2aW91c05vZGUoKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBtX2NhY2hlZE5vZGVzKQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCi0gICAgICAgICJUaGlzIE5vZGVTZXREVE0gY2FuIG5vdCBpdGVyYXRlIHRvIGEgcHJldmlvdXMgbm9kZSEiKTsKLQotICAgIHJldHVybiBtX2NhY2hlZE5vZGVzLnByZXZpb3VzTm9kZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIHdoaWNoIG5vZGUgdHlwZXMgYXJlIHByZXNlbnRlZCB2aWEgdGhlCi0gICAqIGl0ZXJhdG9yLiBUaGUgYXZhaWxhYmxlIHNldCBvZiBjb25zdGFudHMgaXMgZGVmaW5lZCBpbiB0aGUKLSAgICogPGNvZGU+RFRNRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UuCi0gICAqCi0gICAqIEByZXR1cm4gQSBiaXQgc2V0IHRoYXQgdGVsbHMgd2hhdCBub2RlIHR5cGVzIHRvIHNob3cgKERUTUZpbHRlci5TSE9XX0FMTCBhdCAKLSAgICogdGhlIGl0ZXJhdG9yIGxldmVsKS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gIHsKLQotICAgIC8vIFRPRE86ID8/Ci0gICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX0FMTCAmIH5EVE1GaWx0ZXIuU0hPV19FTlRJVFlfUkVGRVJFTkNFOwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgZmlsdGVyIHVzZWQgdG8gc2NyZWVuIG5vZGVzLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwuCi0gICAqLwotICBwdWJsaWMgRFRNRmlsdGVyIGdldEZpbHRlcigpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiAgVGhlIHJvb3Qgbm9kZSBvZiB0aGUgSXRlcmF0b3IsIGFzIHNwZWNpZmllZCB3aGVuIGl0IHdhcyBjcmVhdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjb250ZXh0IG5vZGUgb2YgdGhpcyBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Um9vdCgpCi0gIHsKLSAgICByZXR1cm4gbV9jb250ZXh0OwotICB9Ci0KLSAgLyoqCi0gICAqICBUaGUgdmFsdWUgb2YgdGhpcyBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGUgY2hpbGRyZW4gb2YgZW50aXR5Ci0gICAqIHJlZmVyZW5jZSBub2RlcyBhcmUgdmlzaWJsZSB0byB0aGUgaXRlcmF0b3IuIElmIGZhbHNlLCB0aGV5IHdpbGwgYmUKLSAgICogc2tpcHBlZCBvdmVyLgotICAgKiA8YnI+IFRvIHByb2R1Y2UgYSB2aWV3IG9mIHRoZSBkb2N1bWVudCB0aGF0IGhhcyBlbnRpdHkgcmVmZXJlbmNlcwotICAgKiBleHBhbmRlZCBhbmQgZG9lcyBub3QgZXhwb3NlIHRoZSBlbnRpdHkgcmVmZXJlbmNlIG5vZGUgaXRzZWxmLCB1c2UgdGhlCi0gICAqIHdoYXRUb1Nob3cgZmxhZ3MgdG8gaGlkZSB0aGUgZW50aXR5IHJlZmVyZW5jZSBub2RlIGFuZCBzZXQKLSAgICogZXhwYW5kRW50aXR5UmVmZXJlbmNlcyB0byB0cnVlIHdoZW4gY3JlYXRpbmcgdGhlIGl0ZXJhdG9yLiBUbyBwcm9kdWNlCi0gICAqIGEgdmlldyBvZiB0aGUgZG9jdW1lbnQgdGhhdCBoYXMgZW50aXR5IHJlZmVyZW5jZSBub2RlcyBidXQgbm8gZW50aXR5Ci0gICAqIGV4cGFuc2lvbiwgdXNlIHRoZSB3aGF0VG9TaG93IGZsYWdzIHRvIHNob3cgdGhlIGVudGl0eSByZWZlcmVuY2Ugbm9kZQotICAgKiBhbmQgc2V0IGV4cGFuZEVudGl0eVJlZmVyZW5jZXMgdG8gZmFsc2UuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZS4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGdldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoKQotICB7Ci0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGFuIGl0ZXJhdG9yIHRvIHRoZSB1bmlvbiBsaXN0LgotICAgKgotICAgKiBAcGFyYW0gaXRlciBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWRkSXRlcmF0b3IoTG9jUGF0aEl0ZXJhdG9yIGl0ZXIpCi0gIHsKLQotICAgIC8vIEluY3JlYXNlIGFycmF5IHNpemUgYnkgb25seSAxIGF0IGEgdGltZS4gIEZpeCB0aGlzCi0gICAgLy8gaWYgaXQgbG9va3MgdG8gYmUgYSBwcm9ibGVtLgotICAgIGlmIChudWxsID09IG1faXRlcmF0b3JzKQotICAgIHsKLSAgICAgIG1faXRlcmF0b3JzID0gbmV3IExvY1BhdGhJdGVyYXRvclsxXTsKLSAgICAgIG1faXRlcmF0b3JzWzBdID0gaXRlcjsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIERUTUl0ZXJhdG9yW10gaXRlcnMgPSBtX2l0ZXJhdG9yczsKLSAgICAgIGludCBsZW4gPSBtX2l0ZXJhdG9ycy5sZW5ndGg7Ci0KLSAgICAgIG1faXRlcmF0b3JzID0gbmV3IExvY1BhdGhJdGVyYXRvcltsZW4gKyAxXTsKLQotICAgICAgU3lzdGVtLmFycmF5Y29weShpdGVycywgMCwgbV9pdGVyYXRvcnMsIDAsIGxlbik7Ci0KLSAgICAgIG1faXRlcmF0b3JzW2xlbl0gPSBpdGVyOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBVbmlvblBhdGhJdGVyYXRvciBvYmplY3QsIGluY2x1ZGluZyBjcmVhdGlvbiAKLSAgICogb2YgbG9jYXRpb24gcGF0aCBpdGVyYXRvcnMgZnJvbSB0aGUgb3Bjb2RlIGxpc3QsIGFuZCBjYWxsIGJhY2sgCi0gICAqIGludG8gdGhlIENvbXBpbGVyIHRvIGNyZWF0ZSBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgd2hpY2ggaXMgY3JlYXRpbmcgCi0gICAqIHRoaXMgZXhwcmVzc2lvbi4KLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGlzIGl0ZXJhdG9yIGluIHRoZSAKLSAgICogb3Bjb2RlIGxpc3QgZnJvbSB0aGUgY29tcGlsZXIuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFVuaW9uUGF0aEl0ZXJhdG9yKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIoKTsKLQotICAgIG9wUG9zID0gY29tcGlsZXIuZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICBsb2FkTG9jYXRpb25QYXRocyhjb21waWxlciwgb3BQb3MsIDApOwotICB9Ci0gIAotICAvKioKLSAgICogUmVhZCB0aGUgb2JqZWN0IGZyb20gYSBzZXJpYWxpemF0aW9uIHN0cmVhbS4KLSAgICoKLSAgICogQHBhcmFtIHN0cmVhbSBJbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW0gc3RyZWFtKQotICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBzdHJlYW0uZGVmYXVsdFJlYWRPYmplY3QoKTsKLSAgICAgIG1fY2xvbmVzID0gIG5ldyBJdGVyYXRvclBvb2wodGhpcyk7Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oY25mZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIGNsb25lZCBJdGVyYXRvciB0aGF0IGlzIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcgCi0gICAqIG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lZCBEVE1JdGVyYXRvciBzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeS4KLSAgICoKLSAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGNsb25lV2l0aFJlc2V0KCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIFVuaW9uUGF0aEl0ZXJhdG9yIGNsb25lID0gKFVuaW9uUGF0aEl0ZXJhdG9yKSBjbG9uZSgpOwotICAgIAotICAgIGNsb25lLnJlc2V0KCk7Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgY2xvbmVkIExvY1BhdGhJdGVyYXRvciB0aGF0IGhvbGRzIHRoZSBzYW1lIAotICAgKiBwb3NpdGlvbiBhcyB0aGlzIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIEEgY2xvbmUgb2YgdGhpcyBpdGVyYXRvciB0aGF0IGhvbGRzIHRoZSBzYW1lIG5vZGUgcG9zaXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24KLSAgewotCi0gICAgVW5pb25QYXRoSXRlcmF0b3IgY2xvbmUgPSAoVW5pb25QYXRoSXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7Ci0gICAgaW50IG4gPSBtX2l0ZXJhdG9ycy5sZW5ndGg7Ci0KLSAgICBjbG9uZS5tX2l0ZXJhdG9ycyA9IG5ldyBMb2NQYXRoSXRlcmF0b3Jbbl07Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBjbG9uZS5tX2l0ZXJhdG9yc1tpXSA9IChMb2NQYXRoSXRlcmF0b3IpbV9pdGVyYXRvcnNbaV0uY2xvbmUoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gY2xvbmU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZXhwZXJpbWVudGFsIi8+Ci0gICAqIEdpdmVuIGFuIHNlbGVjdCBleHByZXNzaW9uIGFuZCBhIGNvbnRleHQsIGV2YWx1YXRlIHRoZSBYUGF0aAotICAgKiBhbmQgcmV0dXJuIHRoZSByZXN1bHRpbmcgaXRlcmF0b3IuCi0gICAqIAotICAgKiBAcGFyYW0geGN0eHQgVGhlIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dE5vZGUgVGhlIG5vZGUgdGhhdCAiLiIgZXhwcmVzc2VzLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBUaGUgY29udGV4dCBpbiB3aGljaCBuYW1lc3BhY2VzIGluIHRoZQotICAgKiBYUGF0aCBhcmUgc3VwcG9zZWQgdG8gYmUgZXhwYW5kZWQuCi0gICAqIAotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBkZWNpZGVzCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGFzSXRlcmF0b3IoCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dE5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgVW5pb25QYXRoSXRlcmF0b3IgY2xvbmUgPSAoVW5pb25QYXRoSXRlcmF0b3IpbV9jbG9uZXMuZ2V0SW5zdGFuY2UoKTsKLSAgICAKLSAgICBjbG9uZS5zZXRSb290KGNvbnRleHROb2RlLCB4Y3R4dCk7Ci0gICAgCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRoZSBpdGVyYXRvci4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJlc2V0KCkKLSAgewotCi0gICAgLy8gc3VwZXIucmVzZXQoKTsKLSAgICBtX2ZvdW5kTGFzdCA9IGZhbHNlOwotICAgIG1fbmV4dCA9IDA7Ci0gICAgbV9sYXN0ID0gMDsKLSAgICBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0KLSAgICBpbnQgbiA9IG1faXRlcmF0b3JzLmxlbmd0aDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIG1faXRlcmF0b3JzW2ldLnJlc2V0KCk7Ci0gICAgICBtX2l0ZXJhdG9yc1tpXS5uZXh0Tm9kZSgpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9ycy4gIFJlY3Vyc2l2ZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciB3aGljaCBpcyBjcmVhdGluZyAKLSAgICogdGhpcyBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoaXMgaXRlcmF0b3IgaW4gdGhlIAotICAgKiBvcGNvZGUgbGlzdCBmcm9tIHRoZSBjb21waWxlci4KLSAgICogQHBhcmFtIGNvdW50IFRoZSBpbnNlcnQgcG9zaXRpb24gb2YgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGxvYWRMb2NhdGlvblBhdGhzKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsIGludCBjb3VudCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBUT0RPOiBIYW5kbGUgdW53cmFwcGVkIEZpbHRlckV4cHIKLSAgICBpbnQgc3RlcHR5cGUgPSBjb21waWxlci5nZXRPcE1hcCgpW29wUG9zXTsKLQotICAgIGlmIChzdGVwdHlwZSA9PSBPcENvZGVzLk9QX0xPQ0FUSU9OUEFUSCkKLSAgICB7Ci0gICAgICBsb2FkTG9jYXRpb25QYXRocyhjb21waWxlciwgY29tcGlsZXIuZ2V0TmV4dE9wUG9zKG9wUG9zKSwgY291bnQgKyAxKTsKLQotICAgICAgbV9pdGVyYXRvcnNbY291bnRdID0gY3JlYXRlRFRNSXRlcmF0b3IoY29tcGlsZXIsIG9wUG9zKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gSGF2ZSB0byBjaGVjayBmb3IgdW53cmFwcGVkIGZ1bmN0aW9ucywgd2hpY2ggdGhlIExvY1BhdGhJdGVyYXRvcgotICAgICAgLy8gZG9lc24ndCBoYW5kbGUuIAotICAgICAgc3dpdGNoIChzdGVwdHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgICAgIGxvYWRMb2NhdGlvblBhdGhzKGNvbXBpbGVyLCBjb21waWxlci5nZXROZXh0T3BQb3Mob3BQb3MpLCBjb3VudCArIDEpOwotCi0gICAgICAgIFdhbGtpbmdJdGVyYXRvciBpdGVyID0KLSAgICAgICAgICBuZXcgV2Fsa2luZ0l0ZXJhdG9yKGNvbXBpbGVyLmdldE5hbWVzcGFjZUNvbnRleHQoKSk7Ci0gICAgICAgICAgCi0gICAgICAgIGlmKGNvbXBpbGVyLmdldExvY2F0aW9uUGF0aERlcHRoKCkgPD0gMCkKLSAgICAgICAgICBpdGVyLnNldElzVG9wTGV2ZWwodHJ1ZSk7Ci0KLSAgICAgICAgaXRlci5tX2ZpcnN0V2Fsa2VyID0gbmV3IG9yZy5hcGFjaGUueHBhdGguYXhlcy5GaWx0ZXJFeHByV2Fsa2VyKGl0ZXIpOwotCi0gICAgICAgIGl0ZXIubV9maXJzdFdhbGtlci5pbml0KGNvbXBpbGVyLCBvcFBvcywgc3RlcHR5cGUpOwotCi0gICAgICAgIG1faXRlcmF0b3JzW2NvdW50XSA9IGl0ZXI7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIG1faXRlcmF0b3JzID0gbmV3IExvY1BhdGhJdGVyYXRvcltjb3VudF07Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIG5ldyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIENvbXBpbGVyIHdoaWNoIGlzIGNyZWF0aW5nIAotICAgKiB0aGlzIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciBpbiB0aGUgCi0gICAqCi0gICAqIEByZXR1cm4gTmV3IGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIERUTUl0ZXJhdG9yIGNyZWF0ZURUTUl0ZXJhdG9yKAotICAgICAgICAgIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBEVE1JdGVyYXRvciBscGkgPSBXYWxrZXJGYWN0b3J5Lm5ld0RUTUl0ZXJhdG9yKGNvbXBpbGVyLCBvcFBvcywgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb21waWxlci5nZXRMb2NhdGlvblBhdGhEZXB0aCgpIDw9IDApKTsKLSAgICByZXR1cm4gbHBpOwotICB9Ci0KLSAgLyoqIFRoZSBsYXN0IG5vZGUgdGhhdCB3YXMgZmV0Y2hlZCwgdXN1YWxseSBieSBuZXh0Tm9kZS4gKi8KLSAgdHJhbnNpZW50IGludCBtX2xhc3RGZXRjaGVkID0gRFRNLk5VTEw7Ci0KLSAgLyoqCi0gICAqICBSZXR1cm5zIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHNldCBhbmQgYWR2YW5jZXMgdGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBpdGVyYXRvciBpbiB0aGUgc2V0LiBBZnRlciBhIERUTUl0ZXJhdG9yIGlzIGNyZWF0ZWQsIHRoZSBmaXJzdCBjYWxsCi0gICAqIHRvIG5leHROb2RlKCkgcmV0dXJucyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0LgotICAgKiBAcmV0dXJuICBUaGUgbmV4dCA8Y29kZT5Ob2RlPC9jb2RlPiBpbiB0aGUgc2V0IGJlaW5nIGl0ZXJhdGVkIG92ZXIsIG9yCi0gICAqICAgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgYXJlIG5vIG1vcmUgbWVtYmVycyBpbiB0aGF0IHNldC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbmV4dE5vZGUoKQotICB7Ci0KLS8vICAgIC8vIElmIHRoZSBjYWNoZSBpcyBvbiwgYW5kIHRoZSBub2RlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHRoZW4gCi0vLyAgICAvLyBqdXN0IHJldHVybiBmcm9tIHRoZSBsaXN0LgotLy8gICAgaWYgKChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0vLyAgICAgICAgICAgICYmIChtX2NhY2hlZE5vZGVzLmdldEN1cnJlbnRQb3MoKSA8IG1fY2FjaGVkTm9kZXMuc2l6ZSgpKSkKLS8vICAgIHsKLS8vICAgICAgcmV0dXJuIG1fY2FjaGVkTm9kZXMubmV4dE5vZGUoKTsKLS8vICAgIH0KLSAgICAvLyBJZiB0aGUgY2FjaGUgaXMgb24sIGFuZCB0aGUgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIGZvdW5kLCB0aGVuIAotICAgIC8vIGp1c3QgcmV0dXJuIGZyb20gdGhlIGxpc3QuCi0gICAgaWYgKChudWxsICE9IG1fY2FjaGVkTm9kZXMpCi0gICAgICAgICAgICAmJiAobV9uZXh0IDwgbV9jYWNoZWROb2Rlcy5zaXplKCkpKQotICAgIHsKLSAgICAgIGludCBuZXh0ID0gbV9jYWNoZWROb2Rlcy5lbGVtZW50QXQobV9uZXh0KTsKLSAgICAKLSAgICAgIG1fbmV4dCsrOwotICAgICAgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBuZXh0OwotCi0gICAgICByZXR1cm4gbmV4dDsKLSAgICB9Ci0KLSAgICBpZiAobV9mb3VuZExhc3QpCi0gICAgewotICAgICAgbV9sYXN0RmV0Y2hlZCA9IERUTS5OVUxMOwotICAgICAgcmV0dXJuIERUTS5OVUxMOwotICAgIH0KLQotICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgaXRlcmF0b3JzIGdldHRpbmcgdGhlIGN1cnJlbnQgZmV0Y2hlZCAKLSAgICAvLyBub2RlLCBhbmQgZ2V0IHRoZSBlYXJsaWVzdCBvY2N1cmluZyBpbiBkb2N1bWVudCBvcmRlcgotICAgIGludCBlYXJsaWVzdE5vZGUgPSBEVE0uTlVMTDsKLQotICAgIGlmIChudWxsICE9IG1faXRlcmF0b3JzKQotICAgIHsKLSAgICAgIGludCBuID0gbV9pdGVyYXRvcnMubGVuZ3RoOwotICAgICAgaW50IGl0ZXJhdG9yVXNlZCA9IC0xOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaW50IG5vZGUgPSBtX2l0ZXJhdG9yc1tpXS5nZXRDdXJyZW50Tm9kZSgpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCA9PSBub2RlKQotICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICBlbHNlIGlmIChEVE0uTlVMTCA9PSBlYXJsaWVzdE5vZGUpCi0gICAgICAgIHsKLSAgICAgICAgICBpdGVyYXRvclVzZWQgPSBpOwotICAgICAgICAgIGVhcmxpZXN0Tm9kZSA9IG5vZGU7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKG5vZGUgPT0gZWFybGllc3ROb2RlKQotICAgICAgICAgIHsKLQotICAgICAgICAgICAgLy8gRm91bmQgYSBkdXBsaWNhdGUsIHNvIHNraXAgcGFzdCBpdC4KLSAgICAgICAgICAgIG1faXRlcmF0b3JzW2ldLm5leHROb2RlKCk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBEVE0gZHRtID0gZ2V0RFRNKG5vZGUpOwotCi0gICAgICAgICAgICBpZiAoZHRtLmlzTm9kZUFmdGVyKG5vZGUsIGVhcmxpZXN0Tm9kZSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGl0ZXJhdG9yVXNlZCA9IGk7Ci0gICAgICAgICAgICAgIGVhcmxpZXN0Tm9kZSA9IG5vZGU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIGlmIChEVE0uTlVMTCAhPSBlYXJsaWVzdE5vZGUpCi0gICAgICB7Ci0gICAgICAgIG1faXRlcmF0b3JzW2l0ZXJhdG9yVXNlZF0ubmV4dE5vZGUoKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtX2NhY2hlZE5vZGVzKQotICAgICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkRWxlbWVudChlYXJsaWVzdE5vZGUpOwotCi0gICAgICAgIG1fbmV4dCsrOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICBtX2ZvdW5kTGFzdCA9IHRydWU7Ci0gICAgfQotCi0gICAgbV9sYXN0RmV0Y2hlZCA9IGVhcmxpZXN0Tm9kZTsKLQotICAgIHJldHVybiBlYXJsaWVzdE5vZGU7Ci0gIH0KLQotICAvKioKLSAgICogSWYgYW4gaW5kZXggaXMgcmVxdWVzdGVkLCBOb2RlU2V0RFRNIHdpbGwgY2FsbCB0aGlzIG1ldGhvZAotICAgKiB0byBydW4gdGhlIGl0ZXJhdG9yIHRvIHRoZSBpbmRleC4gIEJ5IGRlZmF1bHQgdGhpcyBzZXRzCi0gICAqIG1fbmV4dCB0byB0aGUgaW5kZXguICBJZiB0aGUgaW5kZXggYXJndW1lbnQgaXMgLTEsIHRoaXMKLSAgICogc2lnbmFscyB0aGF0IHRoZSBpdGVyYXRvciBzaG91bGQgYmUgcnVuIHRvIHRoZSBlbmQuCi0gICAqCi0gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gcnVuIHRvLCBvciAtMSBpZiB0aGUgaXRlcmF0b3IgCi0gICAqIHNob3VsZCBydW4gdG8gdGhlIGVuZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHJ1blRvKGludCBpbmRleCkKLSAgewotCi0gICAgaWYgKG1fZm91bmRMYXN0IHx8ICgoaW5kZXggPj0gMCkgJiYgKGluZGV4IDw9IGdldEN1cnJlbnRQb3MoKSkpKQotICAgICAgcmV0dXJuOwotCi0gICAgaW50IG47Ci0KLSAgICBpZiAoLTEgPT0gaW5kZXgpCi0gICAgewotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmV4dE5vZGUoKSkpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIGlmIChnZXRDdXJyZW50UG9zKCkgPj0gaW5kZXgpCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgY3VycmVudCBwb3NpdGlvbiwgd2hpY2ggaXMgb25lIGxlc3MgdGhhbgotICAgKiB0aGUgbmV4dCBuZXh0Tm9kZSgpIGNhbGwgd2lsbCByZXRyaWV2ZS4gIGkuZS4gaWYKLSAgICogeW91IGNhbGwgZ2V0Q3VycmVudFBvcygpIGFuZCB0aGUgcmV0dXJuIGlzIDAsIHRoZSBuZXh0Ci0gICAqIGZldGNoIHdpbGwgdGFrZSBwbGFjZSBhdCBpbmRleCAxLgotICAgKgotICAgKiBAcmV0dXJuIEEgdmFsdWUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHplcm8gdGhhdCBpbmRpY2F0ZXMgdGhlIG5leHQgCi0gICAqIG5vZGUgcG9zaXRpb24gdG8gZmV0Y2guCi0gICAqLwotICBwdWJsaWMgaW50IGdldEN1cnJlbnRQb3MoKQotICB7Ci0gICAgcmV0dXJuIG1fbmV4dDsKLSAgfQotICAKLSAgLyoqCi0gICAqICBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LiBUaGUgcmFuZ2Ugb2YgdmFsaWQgY2hpbGQgbm9kZSBpbmRpY2VzCi0gICAqIGlzIDAgdG8gPGNvZGU+bGVuZ3RoLTE8L2NvZGU+IGluY2x1c2l2ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LCBhbHdheXMgZ3JlYXRlciBvciBlcXVhbCB0byB6ZXJvLgotICAgKi8KLSAgcHVibGljIGludCBnZXRMZW5ndGgoKQotICB7Ci0KLSAgICAvLyByZXNldFRvQ2FjaGVkTGlzdCgpOwotICAgIGlmKG1fbGFzdCA+IDApCi0gICAgICByZXR1cm4gbV9sYXN0OwotICAgIGVsc2UgaWYobnVsbCA9PSBtX2NhY2hlZE5vZGVzIHx8ICFtX2ZvdW5kTGFzdCkKLSAgICB7Ci0gICAgICBtX2xhc3QgPSBnZXRMYXN0UG9zKG1fZXhlY0NvbnRleHQpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV9sYXN0ID0gbV9jYWNoZWROb2Rlcy5nZXRMZW5ndGgoKTsKLSAgICB9Ci0gICAgcmV0dXJuIG1fbGFzdDsKLSAgfQotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSB0aGF0IGNhbiBiZSBpdHRlcmF0ZWQgdG8uCi0gICAqIFRoaXMgcHJvYmFibHkgd2lsbCBuZWVkIHRvIGJlIG92ZXJyaWRkZWQgYnkgZGVyaXZlZCBjbGFzc2VzLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIHRoYXQgY2FuIGJlIGl0dGVyYXRlZCB0by4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdFBvcyhYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICBpbnQgcG9zID0gbV9uZXh0OwotICAgIFVuaW9uUGF0aEl0ZXJhdG9yIGNsb25lOwotCi0gICAgaW50IHNhdmVkUG9zOwotICAgIGlmKG51bGwgIT0gbV9jYWNoZWROb2RlcykKLSAgICAgIHNhdmVkUG9zID0gbV9jYWNoZWROb2Rlcy5nZXRDdXJyZW50UG9zKCk7Ci0gICAgZWxzZSAKLSAgICAgIHNhdmVkUG9zID0gLTE7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICAvLyAlUkVWSUVXJSAlT1BUJQotICAgICAgaWYoMCA9PSBwb3MgJiYgbV9jdXJyZW50Q29udGV4dE5vZGUgIT0gRFRNLk5VTEwpCi0gICAgICAgIGNsb25lID0gKFVuaW9uUGF0aEl0ZXJhdG9yKSBjbG9uZVdpdGhSZXNldCgpOwotICAgICAgZWxzZQotICAgICAgICBjbG9uZSA9IChVbmlvblBhdGhJdGVyYXRvcikgY2xvbmUoKTsKLSAgICB9Ci0gICAgY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgewotICAgICAgcmV0dXJuIC0xOwotICAgIH0KLQotICAgIGludCBuZXh0OwotICAgIHBvcyA9IGNsb25lLmdldEN1cnJlbnRQb3MoKTsKLQotICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobmV4dCA9IGNsb25lLm5leHROb2RlKCkpKQotICAgIHsKLSAgICAgIHBvcysrOwotICAgIH0KLSAgICAKLSAgICBpZigtMSAhPSBzYXZlZFBvcykKLSAgICAgIG1fY2FjaGVkTm9kZXMuc2V0Q3VycmVudFBvcyhzYXZlZFBvcyk7Ci0gICAgCi0gICAgcmV0dXJuIHBvczsKLSAgfQotCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+IHRoIGl0ZW0gaW4gdGhlIGNvbGxlY3Rpb24uIElmCi0gICAqIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub2RlcyBpbgotICAgKiB0aGUgbGlzdCwgdGhpcyByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IC4KLSAgICogQHBhcmFtIGluZGV4ICBJbmRleCBpbnRvIHRoZSBjb2xsZWN0aW9uLgotICAgKiBAcmV0dXJuICBUaGUgbm9kZSBhdCB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+IHRoIHBvc2l0aW9uIGluIHRoZQotICAgKiAgIDxjb2RlPk5vZGVMaXN0PC9jb2RlPiAsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQgaXMgbm90IGEgdmFsaWQKLSAgICogICBpbmRleC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaXRlbShpbnQgaW5kZXgpCi0gIHsKLSAgICAvLyByZXNldFRvQ2FjaGVkTGlzdCgpOyAlVEJEJSA/PwotCi0gICAgcmV0dXJuIG1fY2FjaGVkTm9kZXMuaXRlbShpbmRleCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXRzIHRoZSBub2RlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhpcyB2ZWN0b3IgdG8gYmUgdGhlCi0gICAqIHNwZWNpZmllZCBub2RlLiBUaGUgcHJldmlvdXMgY29tcG9uZW50IGF0IHRoYXQgcG9zaXRpb24gaXMgZGlzY2FyZGVkLgotICAgKgotICAgKiA8cD5UaGUgaW5kZXggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzCi0gICAqIHRoYW4gdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgdmVjdG9yLiAgCi0gICAqIFRoZSBpdGVyYXRvciBtdXN0IGJlIGluIGNhY2hlZCBtb2RlLjwvcD4KLSAgICogCi0gICAqIDxwPk1lYW50IHRvIGJlIHVzZWQgZm9yIHNvcnRlZCBpdGVyYXRvcnMuPC9wPgotICAgKgotICAgKiBAcGFyYW0gbm9kZSBOb2RlIHRvIHNldAotICAgKiBAcGFyYW0gaW5kZXggSW5kZXggb2Ygd2hlcmUgdG8gc2V0IHRoZSBub2RlCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRJdGVtKGludCBub2RlLCBpbnQgaW5kZXgpCi0gIHsKLSAgICBtX2NhY2hlZE5vZGVzLnNldEVsZW1lbnRBdChub2RlLCBpbmRleCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgY29udGV4dCBub2RlIGZvciB0aGlzIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbiBNdXN0IGJlIGEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBub2RlIGNvbnRleHQuCi0gICAqLwotICBwdWJsaWMgZmluYWwgdm9pZCBzZXRSb290KGludCBuKQotICB7Ci0gICAgbV9jb250ZXh0ID0gbjsKLSAgfQotICAKLSAgLyoqCi0gICAqIFNldCB0aGUgZW52aXJvbm1lbnQgaW4gd2hpY2ggdGhpcyBpdGVyYXRvciBvcGVyYXRlcywgd2hpY2ggc2hvdWxkIHByb3ZpZGU6Ci0gICAqIGEgbm9kZSAodGhlIGNvbnRleHQgbm9kZS4uLiBzYW1lIHZhbHVlIGFzICJyb290IiBkZWZpbmVkIGJlbG93KSAKLSAgICogYSBwYWlyIG9mIG5vbi16ZXJvIHBvc2l0aXZlIGludGVnZXJzICh0aGUgY29udGV4dCBwb3NpdGlvbiBhbmQgdGhlIGNvbnRleHQgc2l6ZSkgCi0gICAqIGEgc2V0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIAotICAgKiBhIGZ1bmN0aW9uIGxpYnJhcnkgCi0gICAqIHRoZSBzZXQgb2YgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBpbiBzY29wZSBmb3IgdGhlIGV4cHJlc3Npb24uCi0gICAqIAotICAgKiA8cD5BdCB0aGlzIHRpbWUgdGhlIGV4YWN0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZW52aXJvbm1lbnQgaXMgYXBwbGljYXRpb24gCi0gICAqIGRlcGVuZGVudC4gIFByb2JhYmx5IGEgcHJvcGVyIGludGVyZmFjZSB3aWxsIGJlIGNyZWF0ZWQgZmFpcmx5IHNvb24uPC9wPgotICAgKiAKLSAgICogQHBhcmFtIGVudmlyb25tZW50IFRoZSBlbnZpcm9ubWVudCBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFbnZpcm9ubWVudChPYmplY3QgZW52aXJvbm1lbnQpCi0gIHsKLSAgICAvLyBuby1vcCBmb3Igbm93LgotICB9Ci0gIAotICAvKioKLSAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBEVE1NYW5hZ2VyLiAgU2luY2UgYSBub2RlIAotICAgKiBpdGVyYXRvciBtYXkgYmUgcGFzc2VkIHdpdGhvdXQgYSBEVE1NYW5hZ2VyLCB0aGlzIGFsbG93cyB0aGUgCi0gICAqIGNhbGxlciB0byBlYXNpbHkgZ2V0IHRoZSBEVE1NYW5hZ2VyIHVzaW5nIGp1c3QgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIGEgbm9uLW51bGwgRFRNTWFuYWdlciByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgRFRNTWFuYWdlciBnZXREVE1NYW5hZ2VyKCkKLSAgewotICAgIHJldHVybiBtX2V4ZWNDb250ZXh0LmdldERUTU1hbmFnZXIoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiB0aGUgbGFzdCBmZXRjaGVkIG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGxhc3QgZmV0Y2hlZCBub2RlLCBvciBudWxsIGlmIHRoZSBsYXN0IGZldGNoIHdhcyBudWxsLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50Tm9kZSgpCi0gIHsKLSAgICByZXR1cm4gbV9sYXN0RmV0Y2hlZDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUgCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0IAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdCAKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUgCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbiAKLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZCAKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX2l0ZXJhdG9ycy5sZW5ndGg7IGkrKykgCi0gICAgewotICAgICAgRFRNSXRlcmF0b3IgaXRlciA9IG1faXRlcmF0b3JzW2ldOwotICAgICAgaWYoaXRlciBpbnN0YW5jZW9mIEV4cHJlc3Npb24pCi0gICAgICB7Ci0gICAgICAgICgoRXhwcmVzc2lvbilpdGVyKS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIAotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGxzIGlmIHdlJ3ZlIGZvdW5kIHRoZSBsYXN0IG5vZGUgeWV0LgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBib29sZWFuIG1fZm91bmRMYXN0ID0gZmFsc2U7Ci0KLSAgLyoqCi0gICAqIFRoZSBleGVjdXRpb24gY29udGV4dCBmb3IgdGhlIGV4cHJlc3Npb24uCi0gICAqLwotICB0cmFuc2llbnQgcHJvdGVjdGVkIFhQYXRoQ29udGV4dCBtX2V4ZWNDb250ZXh0OwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBjb250ZXh0IGZvciB0aGUgZXhwcmVzc2lvbi4KLSAgICovCi0gIHRyYW5zaWVudCBwcm90ZWN0ZWQgaW50IG1fY29udGV4dCA9IERUTS5OVUxMOwotCi0gIC8qKgotICAgKiBUaGUgbm9kZSBjb250ZXh0IGZyb20gd2hlcmUgdGhlIExvY2F0aW9uIFBhdGggaXMgYmVpbmcKLSAgICogZXhlY3V0ZWQgZnJvbSAoaS5lLiBmb3IgY3VycmVudCgpIHN1cHBvcnQpLgotICAgKi8KLSAgdHJhbnNpZW50IHByb3RlY3RlZCBpbnQgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBEVE0uTlVMTDsKLSAgCi0gIC8qKgotICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgYSBEVE0gdGhhdCAib3ducyIgYSBub2RlIGhhbmRsZS4gIFNpbmNlIGEgbm9kZSAKLSAgICogaXRlcmF0b3IgbWF5IGJlIHBhc3NlZCB3aXRob3V0IGEgRFRNTWFuYWdlciwgdGhpcyBhbGxvd3MgdGhlIAotICAgKiBjYWxsZXIgdG8gZWFzaWx5IGdldCB0aGUgRFRNIHVzaW5nIGp1c3QgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gbm9kZUhhbmRsZSB0aGUgbm9kZUhhbmRsZS4KLSAgICoKLSAgICogQHJldHVybiBhIG5vbi1udWxsIERUTSByZWZlcmVuY2UuCi0gICAqLwotICBwdWJsaWMgRFRNIGdldERUTShpbnQgbm9kZUhhbmRsZSkKLSAgewotICAgIHJldHVybiBtX2V4ZWNDb250ZXh0LmdldERUTShub2RlSGFuZGxlKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoZSBub2RlIGNvbnRleHQgZnJvbSB3aGVyZSB0aGUgZXhwcmVzc2lvbiBpcyBiZWluZwotICAgKiBleGVjdXRlZCBmcm9tIChpLmUuIGZvciBjdXJyZW50KCkgc3VwcG9ydCkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHRvcC1sZXZlbCBub2RlIGNvbnRleHQgb2YgdGhlIGVudGlyZSBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIGludCBnZXRDdXJyZW50Q29udGV4dE5vZGUoKQotICB7Ci0gICAgcmV0dXJuIG1fY3VycmVudENvbnRleHROb2RlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9ycywgb25lIGZvciBlYWNoCi0gICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI05ULUxvY2F0aW9uUGF0aCI+bG9jYXRpb24KLSAgICogcGF0aDwvYT4gY29udGFpbmVkIGluIHRoZSB1bmlvbiBleHByZXNzaW9uLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgRFRNSXRlcmF0b3JbXSBtX2l0ZXJhdG9yczsKLSAgCi0gIC8qKgotICAgKiBUaGUgbGFzdCBpbmRleCBpbiB0aGUgbGlzdC4KLSAgICovCi0gIHRyYW5zaWVudCBwcml2YXRlIGludCBtX2xhc3QgPSAwOwotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9kZSBpbiB0aGUgaXR0ZXJhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TGFzdCgpCi0gIHsKLSAgICByZXR1cm4gbV9sYXN0OwotICB9Ci0gIAotICAvKioKLSAgICogU2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub2RlIGluIHRoZSBpdHRlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0TGFzdChpbnQgbGFzdCkKLSAgewotICAgIG1fbGFzdCA9IGxhc3Q7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBSZXR1cm5zIHRydWUgaWYgYWxsIHRoZSBub2RlcyBpbiB0aGUgaXRlcmF0aW9uIHdlbGwgYmUgcmV0dXJuZWQgaW4gZG9jdW1lbnQgCi0gICAqIG9yZGVyLgotICAgKiAKLSAgICogQHJldHVybiB0cnVlIGFzIGEgZGVmYXVsdC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzRG9jT3JkZXJlZCgpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGF4aXMgYmVpbmcgaXRlcmF0ZWQsIGlmIGl0IGlzIGtub3duLgotICAgKiAKLSAgICogQHJldHVybiBBeGlzLkNISUxELCBldGMuLCBvciAtMSBpZiB0aGUgYXhpcyBpcyBub3Qga25vd24gb3IgaXMgb2YgbXVsdGlwbGUgCi0gICAqIHR5cGVzLgotICAgKi8KLSAgcHVibGljIGludCBnZXRBeGlzKCkKLSAgewotICAgIC8vIENvdWxkIGJlIHNtYXJ0ZXIuCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvV2Fsa2VyRmFjdG9yeS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9XYWxrZXJGYWN0b3J5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYyZjk3YzIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9XYWxrZXJGYWN0b3J5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzg3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguYXhlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuT3BDb2RlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuRnVuY3Rpb25UYWJsZTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuU3RlcFBhdHRlcm47Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Db250ZXh0TWF0Y2hTdGVwUGF0dGVybjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLkZ1bmN0aW9uUGF0dGVybjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaXMgYm90aCBhIGZhY3RvcnkgZm9yIFhQYXRoIGxvY2F0aW9uIHBhdGggZXhwcmVzc2lvbnMsCi0gKiB3aGljaCBhcmUgYnVpbHQgZnJvbSB0aGUgb3Bjb2RlIG1hcCBvdXRwdXQsIGFuZCBhbiBhbmFseXNpcyBlbmdpbmUKLSAqIGZvciB0aGUgbG9jYXRpb24gcGF0aCBleHByZXNzaW9ucyBpbiBvcmRlciB0byBwcm92aWRlIG9wdGltaXphdGlvbiBoaW50cy4KLSAqLwotcHVibGljIGNsYXNzIFdhbGtlckZhY3RvcnkKLXsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFRoaXMgbWV0aG9kIGlzIGZvciBidWlsZGluZyBhbiBhcnJheSBvZiBwb3NzaWJsZSBsZXZlbHMKLSAgICogd2hlcmUgdGhlIHRhcmdldCBlbGVtZW50KHMpIGNvdWxkIGJlIGZvdW5kIGZvciBhIG1hdGNoLgotICAgKiBAcGFyYW0geHBhdGggVGhlIHhwYXRoIHRoYXQgaXMgZXhlY3V0aW5nLgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY3VycmVudCBzb3VyY2UgdHJlZSBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSBscGkgVGhlIG93bmluZyBsb2NhdGlvbiBwYXRoIGl0ZXJhdG9yLgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgQXhlc1dhbGtlciBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBBeGVzV2Fsa2VyIGxvYWRPbmVXYWxrZXIoCi0gICAgICAgICAgV2Fsa2luZ0l0ZXJhdG9yIGxwaSwgQ29tcGlsZXIgY29tcGlsZXIsIGludCBzdGVwT3BDb2RlUG9zKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgQXhlc1dhbGtlciBmaXJzdFdhbGtlciA9IG51bGw7Ci0gICAgaW50IHN0ZXBUeXBlID0gY29tcGlsZXIuZ2V0T3BNYXAoKVtzdGVwT3BDb2RlUG9zXTsKLQotICAgIGlmIChzdGVwVHlwZSAhPSBPcENvZGVzLkVORE9QKQotICAgIHsKLQotICAgICAgLy8gbV9heGVzV2Fsa2VycyA9IG5ldyBBeGVzV2Fsa2VyWzFdOwotICAgICAgLy8gQXMgd2UgdW53aW5kIGZyb20gdGhlIHJlY3Vyc2lvbiwgY3JlYXRlIHRoZSBpdGVyYXRvcnMuCi0gICAgICBmaXJzdFdhbGtlciA9IGNyZWF0ZURlZmF1bHRXYWxrZXIoY29tcGlsZXIsIHN0ZXBUeXBlLCBscGksIDApOwotCi0gICAgICBmaXJzdFdhbGtlci5pbml0KGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBzdGVwVHlwZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZpcnN0V2Fsa2VyOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBUaGlzIG1ldGhvZCBpcyBmb3IgYnVpbGRpbmcgYW4gYXJyYXkgb2YgcG9zc2libGUgbGV2ZWxzCi0gICAqIHdoZXJlIHRoZSB0YXJnZXQgZWxlbWVudChzKSBjb3VsZCBiZSBmb3VuZCBmb3IgYSBtYXRjaC4KLSAgICogQHBhcmFtIHhwYXRoIFRoZSB4cGF0aCB0aGF0IGlzIGV4ZWN1dGluZy4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGN1cnJlbnQgc291cmNlIHRyZWUgY29udGV4dCBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbHBpIFRoZSBvd25pbmcgbG9jYXRpb24gcGF0aCBpdGVyYXRvciBvYmplY3QuCi0gICAqIEBwYXJhbSBjb21waWxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIHByb2Nlc3NlZAotICAgKiAgICAgICAgICAgICAgICAgdGhlIFhQYXRoIG9wZXJhdGlvbnMgaW50byBhbiBvcGNvZGUgbWFwLgotICAgKiBAcGFyYW0gc3RlcE9wQ29kZVBvcyBUaGUgb3Bjb2RlIHBvc2l0aW9uIGZvciB0aGUgc3RlcC4KLSAgICogQHBhcmFtIHN0ZXBJbmRleCBUaGUgdG9wLWxldmVsIHN0ZXAgaW5kZXggd2l0aGluZyB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgQXhlc1dhbGtlciBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBBeGVzV2Fsa2VyIGxvYWRXYWxrZXJzKAotICAgICAgICAgIFdhbGtpbmdJdGVyYXRvciBscGksIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgc3RlcE9wQ29kZVBvcywgaW50IHN0ZXBJbmRleCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBzdGVwVHlwZTsKLSAgICBBeGVzV2Fsa2VyIGZpcnN0V2Fsa2VyID0gbnVsbDsKLSAgICBBeGVzV2Fsa2VyIHdhbGtlciwgcHJldldhbGtlciA9IG51bGw7Ci0gICAgaW50IG9wc1tdID0gY29tcGlsZXIuZ2V0T3BNYXAoKTsKLSAgICBpbnQgYW5hbHlzaXMgPSBhbmFseXplKGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBzdGVwSW5kZXgpOwotCi0gICAgd2hpbGUgKE9wQ29kZXMuRU5ET1AgIT0gKHN0ZXBUeXBlID0gb3BzW3N0ZXBPcENvZGVQb3NdKSkKLSAgICB7Ci0gICAgICB3YWxrZXIgPSBjcmVhdGVEZWZhdWx0V2Fsa2VyKGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBscGksIGFuYWx5c2lzKTsKLQotICAgICAgd2Fsa2VyLmluaXQoY29tcGlsZXIsIHN0ZXBPcENvZGVQb3MsIHN0ZXBUeXBlKTsKLQotICAgICAgLy8gd2Fsa2VyLnNldEFuYWx5c2lzKGFuYWx5c2lzKTsKLSAgICAgIGlmIChudWxsID09IGZpcnN0V2Fsa2VyKQotICAgICAgewotICAgICAgICBmaXJzdFdhbGtlciA9IHdhbGtlcjsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcHJldldhbGtlci5zZXROZXh0V2Fsa2VyKHdhbGtlcik7Ci0gICAgICAgIHdhbGtlci5zZXRQcmV2V2Fsa2VyKHByZXZXYWxrZXIpOwotICAgICAgfQotCi0gICAgICBwcmV2V2Fsa2VyID0gd2Fsa2VyOwotICAgICAgc3RlcE9wQ29kZVBvcyA9IGNvbXBpbGVyLmdldE5leHRTdGVwUG9zKHN0ZXBPcENvZGVQb3MpOwotCi0gICAgICBpZiAoc3RlcE9wQ29kZVBvcyA8IDApCi0gICAgICAgIGJyZWFrOwotICAgIH0KLQotICAgIHJldHVybiBmaXJzdFdhbGtlcjsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU2V0KGludCBhbmFseXNpcywgaW50IGJpdHMpCi0gIHsKLSAgICByZXR1cm4gKDAgIT0gKGFuYWx5c2lzICYgYml0cykpOwotICB9Ci0gIAotICBwdWJsaWMgc3RhdGljIHZvaWQgZGlhZ25vc2VJdGVyYXRvcihTdHJpbmcgbmFtZSwgaW50IGFuYWx5c2lzLCBDb21waWxlciBjb21waWxlcikKLSAgewotICAgIFN5c3RlbS5vdXQucHJpbnRsbihjb21waWxlci50b1N0cmluZygpKyIsICIrbmFtZSsiLCAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSW50ZWdlci50b0JpbmFyeVN0cmluZyhhbmFseXNpcykgKyAiLCAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZ2V0QW5hbHlzaXNTdHJpbmcoYW5hbHlzaXMpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgTG9jUGF0aEl0ZXJhdG9yIGl0ZXJhdG9yLiAgVGhlIGV4YWN0IHR5cGUgb2YgaXRlcmF0b3IKLSAgICogcmV0dXJuZWQgaXMgYmFzZWQgb24gYW4gYW5hbHlzaXMgb2YgdGhlIFhQYXRoIG9wZXJhdGlvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIHByb2Nlc3NlZAotICAgKiAgICAgICAgICAgICAgICAgdGhlIFhQYXRoIG9wZXJhdGlvbnMgaW50byBhbiBvcGNvZGUgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoZSBvcGVyYXRpb24gY29kZSBmb3IgdGhpcyBpdHRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTG9jUGF0aEl0ZXJhdG9yIG9yIGRlcml2YXRpdmUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBEVE1JdGVyYXRvciBuZXdEVE1JdGVyYXRvcigKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLAotICAgICAgICAgIGJvb2xlYW4gaXNUb3BMZXZlbCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBjb21waWxlci5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLSAgICBpbnQgYW5hbHlzaXMgPSBhbmFseXplKGNvbXBpbGVyLCBmaXJzdFN0ZXBQb3MsIDApOwotICAgIGJvb2xlYW4gaXNPbmVTdGVwID0gaXNPbmVTdGVwKGFuYWx5c2lzKTsKLSAgICBEVE1JdGVyYXRvciBpdGVyOwotCi0gICAgLy8gSXMgdGhlIGl0ZXJhdGlvbiBhIG9uZS1zdGVwIGF0dHJpYnV0ZSBwYXR0ZXJuIChpLmUuIHNlbGVjdD0iQGZvbyIpPwotICAgIGlmIChpc09uZVN0ZXAgJiYgd2Fsa3NTZWxmT25seShhbmFseXNpcykgJiYgCi0gICAgICAgIGlzV2lsZChhbmFseXNpcykgJiYgIWhhc1ByZWRpY2F0ZShhbmFseXNpcykpCi0gICAgewotICAgICAgaWYgKERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJTZWxmSXRlcmF0b3JOb1ByZWRpY2F0ZSIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0KLSAgICAgIC8vIFRoZW4gdXNlIGEgc2ltcGxlIGl0ZXJhdGlvbiBvZiB0aGUgYXR0cmlidXRlcywgd2l0aCBub2RlIHRlc3QgCi0gICAgICAvLyBhbmQgcHJlZGljYXRlIHRlc3RpbmcuCi0gICAgICBpdGVyID0gbmV3IFNlbGZJdGVyYXRvck5vUHJlZGljYXRlKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICAgIH0KLSAgICAvLyBJcyB0aGUgaXRlcmF0aW9uIGV4YWN0bHkgb25lIGNoaWxkIHN0ZXA/Ci0gICAgZWxzZSBpZiAod2Fsa3NDaGlsZHJlbk9ubHkoYW5hbHlzaXMpICYmIGlzT25lU3RlcCkKLSAgICB7Ci0KLSAgICAgIC8vIERvZXMgdGhlIHBhdHRlcm4gc3BlY2lmeSAqYW55KiBjaGlsZCB3aXRoIG5vIHByZWRpY2F0ZT8gKGkuZS4gc2VsZWN0PSJjaGlsZDo6bm9kZSgpIi4KLSAgICAgIGlmIChpc1dpbGQoYW5hbHlzaXMpICYmICFoYXNQcmVkaWNhdGUoYW5hbHlzaXMpKQotICAgICAgewotICAgICAgICBpZiAoREVCVUdfSVRFUkFUT1JfQ1JFQVRJT04pCi0gICAgICAgICAgZGlhZ25vc2VJdGVyYXRvcigiQ2hpbGRJdGVyYXRvciIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0KLSAgICAgICAgLy8gVXNlIHNpbXBsZSBjaGlsZCBpdGVyYXRpb24gd2l0aG91dCBhbnkgdGVzdC4KLSAgICAgICAgaXRlciA9IG5ldyBDaGlsZEl0ZXJhdG9yKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBpZiAoREVCVUdfSVRFUkFUT1JfQ1JFQVRJT04pCi0gICAgICAgICAgZGlhZ25vc2VJdGVyYXRvcigiQ2hpbGRUZXN0SXRlcmF0b3IiLCBhbmFseXNpcywgY29tcGlsZXIpOwotCi0gICAgICAgIC8vIEVsc2UgdXNlIHNpbXBsZSBub2RlIHRlc3QgaXRlcmF0aW9uIHdpdGggcHJlZGljYXRlIHRlc3QuCi0gICAgICAgIGl0ZXIgPSBuZXcgQ2hpbGRUZXN0SXRlcmF0b3IoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcyk7Ci0gICAgICB9Ci0gICAgfQotICAgIC8vIElzIHRoZSBpdGVyYXRpb24gYSBvbmUtc3RlcCBhdHRyaWJ1dGUgcGF0dGVybiAoaS5lLiBzZWxlY3Q9IkBmb28iKT8KLSAgICBlbHNlIGlmIChpc09uZVN0ZXAgJiYgd2Fsa3NBdHRyaWJ1dGVzKGFuYWx5c2lzKSkKLSAgICB7Ci0gICAgICBpZiAoREVCVUdfSVRFUkFUT1JfQ1JFQVRJT04pCi0gICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIkF0dHJpYnV0ZUl0ZXJhdG9yIiwgYW5hbHlzaXMsIGNvbXBpbGVyKTsKLQotICAgICAgLy8gVGhlbiB1c2UgYSBzaW1wbGUgaXRlcmF0aW9uIG9mIHRoZSBhdHRyaWJ1dGVzLCB3aXRoIG5vZGUgdGVzdCAKLSAgICAgIC8vIGFuZCBwcmVkaWNhdGUgdGVzdGluZy4KLSAgICAgIGl0ZXIgPSBuZXcgQXR0cmlidXRlSXRlcmF0b3IoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcyk7Ci0gICAgfQotICAgIGVsc2UgaWYoaXNPbmVTdGVwICYmICF3YWxrc0ZpbHRlcmVkTGlzdChhbmFseXNpcykpCi0gICAgewotICAgICAgaWYoICF3YWxrc05hbWVzcGFjZXMoYW5hbHlzaXMpIAotICAgICAgJiYgKHdhbGtzSW5Eb2NPcmRlcihhbmFseXNpcykgfHwgaXNTZXQoYW5hbHlzaXMsIEJJVF9QQVJFTlQpKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZhbHNlIHx8IERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIk9uZVN0ZXBJdGVyYXRvckZvcndhcmQiLCBhbmFseXNpcywgY29tcGlsZXIpOwotICAKLSAgICAgICAgLy8gVGhlbiB1c2UgYSBzaW1wbGUgaXRlcmF0aW9uIG9mIHRoZSBhdHRyaWJ1dGVzLCB3aXRoIG5vZGUgdGVzdCAKLSAgICAgICAgLy8gYW5kIHByZWRpY2F0ZSB0ZXN0aW5nLgotICAgICAgICBpdGVyID0gbmV3IE9uZVN0ZXBJdGVyYXRvckZvcndhcmQoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcyk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChmYWxzZSB8fCBERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLSAgICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJPbmVTdGVwSXRlcmF0b3IiLCBhbmFseXNpcywgY29tcGlsZXIpOwotICAKLSAgICAgICAgLy8gVGhlbiB1c2UgYSBzaW1wbGUgaXRlcmF0aW9uIG9mIHRoZSBhdHRyaWJ1dGVzLCB3aXRoIG5vZGUgdGVzdCAKLSAgICAgICAgLy8gYW5kIHByZWRpY2F0ZSB0ZXN0aW5nLgotICAgICAgICBpdGVyID0gbmV3IE9uZVN0ZXBJdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICAvLyBBbmFseXNpcyBvZiAiLy9jZW50ZXIiOgotICAgIC8vIGJpdHM6IDEwMDEwMDAwMDAwMDEwMTAwMDAwMDAwMDAwMDAwMTEKLSAgICAvLyBjb3VudDogMwotICAgIC8vIHJvb3QKLSAgICAvLyBjaGlsZDpub2RlKCkKLSAgICAvLyBCSVRfREVTQ0VOREFOVF9PUl9TRUxGCi0gICAgLy8gSXQncyBoaWdobHkgcG9zc2libGUgdGhhdCB3ZSBzaG91bGQgaGF2ZSBhIHNlcGVyYXRlIGJpdCBzZXQgZm9yIAotICAgIC8vICIvL2ZvbyIgcGF0dGVybnMuCi0gICAgLy8gRm9yIGF0IGxlYXN0IHRoZSB0aW1lIGJlaW5nLCB3ZSBjYW4ndCBvcHRpbWl6ZSBwYXR0ZXJucyBsaWtlIAotICAgIC8vICIvL3RhYmxlWzNdIiwgYmVjYXVzZSB0aGlzIGhhcyB0byBiZSBhbmFseXplZCBhcyAKLSAgICAvLyAiL2Rlc2NlbmRhbnQtb3Itc2VsZjo6bm9kZSgpL3RhYmxlWzNdIiBpbiBvcmRlciBmb3IgdGhlIGluZGV4ZXMgCi0gICAgLy8gdG8gd29yayByaWdodC4KLSAgICBlbHNlIGlmIChpc09wdGltaXphYmxlRm9yRGVzY2VuZGFudEl0ZXJhdG9yKGNvbXBpbGVyLCBmaXJzdFN0ZXBQb3MsIDApCi0gICAgICAgICAgICAgIC8vICYmIGdldFN0ZXBDb3VudChhbmFseXNpcykgPD0gMyAKLSAgICAgICAgICAgICAgLy8gJiYgd2Fsa3NEZXNjZW5kYW50cyhhbmFseXNpcykgCi0gICAgICAgICAgICAgIC8vICYmIHdhbGtzU3VidHJlZU9ubHlGcm9tUm9vdE9yQ29udGV4dChhbmFseXNpcykKLSAgICAgICAgICAgICApCi0gICAgewotICAgICAgaWYgKERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICBkaWFnbm9zZUl0ZXJhdG9yKCJEZXNjZW5kYW50SXRlcmF0b3IiLCBhbmFseXNpcywgY29tcGlsZXIpOwotCi0gICAgICBpdGVyID0gbmV3IERlc2NlbmRhbnRJdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsgCi0gICAgICBpZihpc05hdHVyYWxEb2NPcmRlcihjb21waWxlciwgZmlyc3RTdGVwUG9zLCAwLCBhbmFseXNpcykpCi0gICAgICB7Ci0gICAgICAgIGlmIChmYWxzZSB8fCBERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLSAgICAgICAgewotICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIldhbGtpbmdJdGVyYXRvciIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0gICAgICAgIH0KLSAgCi0gICAgICAgIGl0ZXIgPSBuZXcgV2Fsa2luZ0l0ZXJhdG9yKGNvbXBpbGVyLCBvcFBvcywgYW5hbHlzaXMsIHRydWUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotLy8gICAgICAgIGlmIChERUJVR19JVEVSQVRPUl9DUkVBVElPTikKLS8vICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIk1hdGNoUGF0dGVybkl0ZXJhdG9yIiwgYW5hbHlzaXMsIGNvbXBpbGVyKTsKLS8vCi0vLyAgICAgICAgcmV0dXJuIG5ldyBNYXRjaFBhdHRlcm5JdGVyYXRvcihjb21waWxlciwgb3BQb3MsIGFuYWx5c2lzKTsKLSAgICAgICAgaWYgKERFQlVHX0lURVJBVE9SX0NSRUFUSU9OKQotICAgICAgICAgIGRpYWdub3NlSXRlcmF0b3IoIldhbGtpbmdJdGVyYXRvclNvcnRlZCIsIGFuYWx5c2lzLCBjb21waWxlcik7Ci0KLSAgICAgICAgaXRlciA9IG5ldyBXYWxraW5nSXRlcmF0b3JTb3J0ZWQoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgdHJ1ZSk7Ci0gICAgICB9Ci0gICAgfQotICAgIGlmKGl0ZXIgaW5zdGFuY2VvZiBMb2NQYXRoSXRlcmF0b3IpCi0gICAgICAoKExvY1BhdGhJdGVyYXRvcilpdGVyKS5zZXRJc1RvcExldmVsKGlzVG9wTGV2ZWwpOwotICAgICAgCi0gICAgcmV0dXJuIGl0ZXI7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTcGVjaWFsIHB1cnBvc2UgZnVuY3Rpb24gdG8gc2VlIGlmIHdlIGNhbiBvcHRpbWl6ZSB0aGUgcGF0dGVybiBmb3IgCi0gICAqIGEgRGVzY2VuZGFudEl0ZXJhdG9yLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqIEBwYXJhbSBzdGVwSW5kZXggVGhlIHRvcC1sZXZlbCBzdGVwIGluZGV4IHdpdGhpbmcgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIDMyIGJpdHMgYXMgYW4gaW50ZWdlciB0aGF0IGdpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2F0aW9uCi0gICAqIHBhdGggYXMgYSB3aG9sZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXRBeGlzRnJvbVN0ZXAoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBzdGVwT3BDb2RlUG9zKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wc1tdID0gY29tcGlsZXIuZ2V0T3BNYXAoKTsKLSAgICBpbnQgc3RlcFR5cGUgPSBvcHNbc3RlcE9wQ29kZVBvc107Ci0KLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcgOgotICAgICAgcmV0dXJuIEF4aXMuRk9MTE9XSU5HOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0ZPTExPV0lOR19TSUJMSU5HUyA6Ci0gICAgICByZXR1cm4gQXhpcy5GT0xMT1dJTkdTSUJMSU5HOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElORyA6Ci0gICAgICByZXR1cm4gQXhpcy5QUkVDRURJTkc7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HX1NJQkxJTkdTIDoKLSAgICAgIHJldHVybiBBeGlzLlBSRUNFRElOR1NJQkxJTkc7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUEFSRU5UIDoKLSAgICAgIHJldHVybiBBeGlzLlBBUkVOVDsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgOgotICAgICAgcmV0dXJuIEF4aXMuTkFNRVNQQUNFOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FOQ0VTVE9SUyA6Ci0gICAgICByZXR1cm4gQXhpcy5BTkNFU1RPUjsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlNfT1JfU0VMRiA6Ci0gICAgICByZXR1cm4gQXhpcy5BTkNFU1RPUk9SU0VMRjsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIHJldHVybiBBeGlzLkFUVFJJQlVURTsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9ST09UIDoKLSAgICAgIHJldHVybiBBeGlzLlJPT1Q7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQ0hJTERSRU4gOgotICAgICAgcmV0dXJuIEF4aXMuQ0hJTEQ7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0gICAgICByZXR1cm4gQXhpcy5ERVNDRU5EQU5UT1JTRUxGOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTIDoKLSAgICAgIHJldHVybiBBeGlzLkRFU0NFTkRBTlQ7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fU0VMRiA6Ci0gICAgICByZXR1cm4gQXhpcy5TRUxGOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgICByZXR1cm4gQXhpcy5GSUxURVJFRExJU1Q7Ci0gICAgfQotCi0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTlVMTF9FUlJPUl9IQU5ETEVSLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhzdGVwVHlwZSl9KSk7IC8vIlByb2dyYW1tZXIncyBhc3NlcnRpb246IHVua25vd24gb3Bjb2RlOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHN0ZXBUeXBlKTsKLSAgfQotICAKLSAgc3RhdGljIGJvb2xlYW4gZnVuY3Rpb25Qcm94aW1hdGVPckNvbnRhaW5zUHJveGltYXRlKENvbXBpbGVyIGNvbXBpbGVyLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvcFBvcykKLSAgewotICAgIGludCBlbmRGdW5jID0gb3BQb3MgKyBjb21waWxlci5nZXRPcChvcFBvcyArIDEpIC0gMTsKLSAgICBvcFBvcyA9IGNvbXBpbGVyLmdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotICAgIGludCBmdW5jSUQgPSBjb21waWxlci5nZXRPcChvcFBvcyk7Ci0gICAgLy8gIFN5c3RlbS5vdXQucHJpbnRsbigiZnVuY0lEOiAiK2Z1bmNJRCk7Ci0gICAgLy8gIFN5c3RlbS5vdXQucHJpbnRsbigib3BQb3M6ICIrb3BQb3MpOwotICAgIC8vICBTeXN0ZW0ub3V0LnByaW50bG4oImVuZEZ1bmM6ICIrZW5kRnVuYyk7Ci0gICAgc3dpdGNoKGZ1bmNJRCkKLSAgICB7Ci0gICAgICBjYXNlIEZ1bmN0aW9uVGFibGUuRlVOQ19MQVNUOgotICAgICAgY2FzZSBGdW5jdGlvblRhYmxlLkZVTkNfUE9TSVRJT046Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgZGVmYXVsdDoKLSAgICAgICAgb3BQb3MrKzsKLSAgICAgICAgaW50IGkgPSAwOwotICAgICAgICBmb3IgKGludCBwID0gb3BQb3M7IHAgPCBlbmRGdW5jOyBwID0gY29tcGlsZXIuZ2V0TmV4dE9wUG9zKHApLCBpKyspCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgaW5uZXJFeHByT3BQb3MgPSBwKzI7Ci0gICAgICAgICAgaW50IGFyZ09wID0gY29tcGlsZXIuZ2V0T3AoaW5uZXJFeHByT3BQb3MpOwotICAgICAgICAgIGJvb2xlYW4gcHJveCA9IGlzUHJveGltYXRlSW5uZXJFeHByKGNvbXBpbGVyLCBpbm5lckV4cHJPcFBvcyk7Ci0gICAgICAgICAgaWYocHJveCkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0gIAotICBzdGF0aWMgYm9vbGVhbiBpc1Byb3hpbWF0ZUlubmVyRXhwcihDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zKQotICB7Ci0gICAgaW50IG9wID0gY29tcGlsZXIuZ2V0T3Aob3BQb3MpOwotICAgIGludCBpbm5lckV4cHJPcFBvcyA9IG9wUG9zKzI7Ci0gICAgc3dpdGNoKG9wKQotICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9BUkdVTUVOVDoKLSAgICAgICAgaWYoaXNQcm94aW1hdGVJbm5lckV4cHIoY29tcGlsZXIsIGlubmVyRXhwck9wUG9zKSkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEU6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfTlVNQkVSTElUOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0xJVEVSQUw6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIOgotICAgICAgICBicmVhazsgLy8gT0sKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTjoKLSAgICAgICAgYm9vbGVhbiBpc1Byb3ggPSBmdW5jdGlvblByb3hpbWF0ZU9yQ29udGFpbnNQcm94aW1hdGUoY29tcGlsZXIsIG9wUG9zKTsKLSAgICAgICAgaWYoaXNQcm94KQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HVDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9HVEU6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfTFQ6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfTFRFOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0VRVUFMUzoKLSAgICAgICAgaW50IGxlZnRQb3MgPSBjb21waWxlci5nZXRGaXJzdENoaWxkUG9zKG9wKTsKLSAgICAgICAgaW50IHJpZ2h0UG9zID0gY29tcGlsZXIuZ2V0TmV4dE9wUG9zKGxlZnRQb3MpOwotICAgICAgICBpc1Byb3ggPSBpc1Byb3hpbWF0ZUlubmVyRXhwcihjb21waWxlciwgbGVmdFBvcyk7Ci0gICAgICAgIGlmKGlzUHJveCkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgaXNQcm94ID0gaXNQcm94aW1hdGVJbm5lckV4cHIoY29tcGlsZXIsIHJpZ2h0UG9zKTsKLSAgICAgICAgaWYoaXNQcm94KQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICBicmVhazsKLSAgICAgIGRlZmF1bHQ6Ci0gICAgICAgIHJldHVybiB0cnVlOyAvLyBiZSBjb25zZXJ2YXRpdmUuLi4KLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0gICAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBwcmVkaWNhdGVzIG5lZWQgdG8gaGF2ZSBwcm94aW1pdHkga25vd2xlZGdlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIG1pZ2h0QmVQcm94aW1hdGUoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IHN0ZXBUeXBlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGJvb2xlYW4gbWlnaHRCZVByb3hpbWF0ZSA9IGZhbHNlOwotICAgIGludCBhcmdMZW47Ci0KLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgYXJnTGVuID0gY29tcGlsZXIuZ2V0QXJnTGVuZ3RoKG9wUG9zKTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgYXJnTGVuID0gY29tcGlsZXIuZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zKTsKLSAgICB9Ci0KLSAgICBpbnQgcHJlZFBvcyA9IGNvbXBpbGVyLmdldEZpcnN0UHJlZGljYXRlT3BQb3Mob3BQb3MpOwotICAgIGludCBjb3VudCA9IDA7Ci0KLSAgICB3aGlsZSAoT3BDb2Rlcy5PUF9QUkVESUNBVEUgPT0gY29tcGlsZXIuZ2V0T3AocHJlZFBvcykpCi0gICAgewotICAgICAgY291bnQrKzsKLSAgICAgIAotICAgICAgaW50IGlubmVyRXhwck9wUG9zID0gcHJlZFBvcysyOwotICAgICAgaW50IHByZWRPcCA9IGNvbXBpbGVyLmdldE9wKGlubmVyRXhwck9wUG9zKTsKLQotICAgICAgc3dpdGNoKHByZWRPcCkKLSAgICAgIHsKLSAgICAgICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFOgotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIOgotICAgICAgICAgIC8vIE9LLgotICAgICAgICAgIGJyZWFrOwotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTlVNQkVSOgotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTlVNQkVSTElUOgotICAgICAgICAgIHJldHVybiB0cnVlOyAvLyB0aGF0J3MgYWxsIHNoZSB3cm90ZSEKLSAgICAgICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OOgotICAgICAgICAgIGJvb2xlYW4gaXNQcm94IAotICAgICAgICAgICAgPSBmdW5jdGlvblByb3hpbWF0ZU9yQ29udGFpbnNQcm94aW1hdGUoY29tcGlsZXIsIGlubmVyRXhwck9wUG9zKTsKLSAgICAgICAgICBpZihpc1Byb3gpCi0gICAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgY2FzZSBPcENvZGVzLk9QX0dUOgotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfR1RFOgotICAgICAgICBjYXNlIE9wQ29kZXMuT1BfTFQ6Ci0gICAgICAgIGNhc2UgT3BDb2Rlcy5PUF9MVEU6Ci0gICAgICAgIGNhc2UgT3BDb2Rlcy5PUF9FUVVBTFM6Ci0gICAgICAgICAgaW50IGxlZnRQb3MgPSBjb21waWxlci5nZXRGaXJzdENoaWxkUG9zKGlubmVyRXhwck9wUG9zKTsKLSAgICAgICAgICBpbnQgcmlnaHRQb3MgPSBjb21waWxlci5nZXROZXh0T3BQb3MobGVmdFBvcyk7Ci0gICAgICAgICAgaXNQcm94ID0gaXNQcm94aW1hdGVJbm5lckV4cHIoY29tcGlsZXIsIGxlZnRQb3MpOwotICAgICAgICAgIGlmKGlzUHJveCkKLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgIGlzUHJveCA9IGlzUHJveGltYXRlSW5uZXJFeHByKGNvbXBpbGVyLCByaWdodFBvcyk7Ci0gICAgICAgICAgaWYoaXNQcm94KQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgcmV0dXJuIHRydWU7IC8vIGJlIGNvbnNlcnZhdGl2ZS4uLgotICAgICAgfQotCi0gICAgICBwcmVkUG9zID0gY29tcGlsZXIuZ2V0TmV4dE9wUG9zKHByZWRQb3MpOwotICAgIH0KLQotICAgIHJldHVybiBtaWdodEJlUHJveGltYXRlOwotICB9Ci0gIAotICAvKioKLSAgICogU3BlY2lhbCBwdXJwb3NlIGZ1bmN0aW9uIHRvIHNlZSBpZiB3ZSBjYW4gb3B0aW1pemUgdGhlIHBhdHRlcm4gZm9yIAotICAgKiBhIERlc2NlbmRhbnRJdGVyYXRvci4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21waWxlciBvYmplY3QgdGhhdCBoYXMgcHJvY2Vzc2VkCi0gICAqICAgICAgICAgICAgICAgICB0aGUgWFBhdGggb3BlcmF0aW9ucyBpbnRvIGFuIG9wY29kZSBtYXAuCi0gICAqIEBwYXJhbSBzdGVwT3BDb2RlUG9zIFRoZSBvcGNvZGUgcG9zaXRpb24gZm9yIHRoZSBzdGVwLgotICAgKiBAcGFyYW0gc3RlcEluZGV4IFRoZSB0b3AtbGV2ZWwgc3RlcCBpbmRleCB3aXRoaW5nIHRoZSBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiAzMiBiaXRzIGFzIGFuIGludGVnZXIgdGhhdCBnaXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhdGlvbgotICAgKiBwYXRoIGFzIGEgd2hvbGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc09wdGltaXphYmxlRm9yRGVzY2VuZGFudEl0ZXJhdG9yKAotICAgICAgICAgIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgc3RlcE9wQ29kZVBvcywgaW50IHN0ZXBJbmRleCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBzdGVwVHlwZTsKLSAgICBpbnQgb3BzW10gPSBjb21waWxlci5nZXRPcE1hcCgpOwotICAgIGludCBzdGVwQ291bnQgPSAwOwotICAgIGJvb2xlYW4gZm91bmREb3JEUyA9IGZhbHNlOwotICAgIGJvb2xlYW4gZm91bmRTZWxmID0gZmFsc2U7Ci0gICAgYm9vbGVhbiBmb3VuZERTID0gZmFsc2U7Ci0gICAgCi0gICAgaW50IG5vZGVUZXN0VHlwZSA9IE9wQ29kZXMuTk9ERVRZUEVfTk9ERTsKLSAgICAKLSAgICB3aGlsZSAoT3BDb2Rlcy5FTkRPUCAhPSAoc3RlcFR5cGUgPSBvcHNbc3RlcE9wQ29kZVBvc10pKQotICAgIHsKLSAgICAgIC8vIFRoZSBEZXNjZW5kYW50SXRlcmF0b3IgY2FuIG9ubHkgZG8gb25lIG5vZGUgdGVzdC4gIElmIHRoZXJlJ3MgbW9yZSAKLSAgICAgIC8vIHRoYW4gb25lLCB1c2UgYW5vdGhlciBpdGVyYXRvci4KLSAgICAgIGlmKG5vZGVUZXN0VHlwZSAhPSBPcENvZGVzLk5PREVUWVBFX05PREUgJiYgbm9kZVRlc3RUeXBlICE9IE9wQ29kZXMuTk9ERVRZUEVfUk9PVCkKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAKLSAgICAgIHN0ZXBDb3VudCsrOwotICAgICAgaWYoc3RlcENvdW50ID4gMykKLSAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAKLSAgICAgIGJvb2xlYW4gbWlnaHRCZVByb3hpbWF0ZSA9IG1pZ2h0QmVQcm94aW1hdGUoY29tcGlsZXIsIHN0ZXBPcENvZGVQb3MsIHN0ZXBUeXBlKTsKLSAgICAgIGlmKG1pZ2h0QmVQcm94aW1hdGUpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgc3dpdGNoIChzdGVwVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0ZPTExPV0lORyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9QQVJFTlQgOgotICAgICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQVRUUklCVVRFUyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuTUFUQ0hfQVRUUklCVVRFIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1IgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0lNTUVESUFURV9BTkNFU1RPUiA6Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgICBpZigxICE9IHN0ZXBDb3VudCkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fQ0hJTERSRU4gOgotICAgICAgICBpZighZm91bmREUyAmJiAhKGZvdW5kRG9yRFMgJiYgZm91bmRTZWxmKSkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0gICAgICAgIGZvdW5kRFMgPSB0cnVlOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFMgOgotICAgICAgICBpZigzID09IHN0ZXBDb3VudCkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGZvdW5kRG9yRFMgPSB0cnVlOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1NFTEYgOgotICAgICAgICBpZigxICE9IHN0ZXBDb3VudCkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGZvdW5kU2VsZiA9IHRydWU7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgc3RlcFR5cGUpOwotICAgICAgfQotICAgICAgCi0gICAgICBub2RlVGVzdFR5cGUgPSBjb21waWxlci5nZXRTdGVwVGVzdFR5cGUoc3RlcE9wQ29kZVBvcyk7Ci0KLSAgICAgIGludCBuZXh0U3RlcE9wQ29kZVBvcyA9IGNvbXBpbGVyLmdldE5leHRTdGVwUG9zKHN0ZXBPcENvZGVQb3MpOwotCi0gICAgICBpZiAobmV4dFN0ZXBPcENvZGVQb3MgPCAwKQotICAgICAgICBicmVhazsKLSAgICAgICAgCi0gICAgICBpZihPcENvZGVzLkVORE9QICE9IG9wc1tuZXh0U3RlcE9wQ29kZVBvc10pCi0gICAgICB7Ci0gICAgICAgIGlmKGNvbXBpbGVyLmNvdW50UHJlZGljYXRlcyhzdGVwT3BDb2RlUG9zKSA+IDApCi0gICAgICAgIHsKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIAotICAgICAgc3RlcE9wQ29kZVBvcyA9IG5leHRTdGVwT3BDb2RlUG9zOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIEFuYWx5emUgdGhlIGxvY2F0aW9uIHBhdGggYW5kIHJldHVybiAzMiBiaXRzIHRoYXQgZ2l2ZSBpbmZvcm1hdGlvbiBhYm91dAotICAgKiB0aGUgbG9jYXRpb24gcGF0aCBhcyBhIHdob2xlLiAgU2VlIHRoZSBCSVRfWFhYIGNvbnN0YW50cyBmb3IgbWVhbmluZyBhYm91dAotICAgKiBlYWNoIG9mIHRoZSBiaXRzLgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGNvbXBpbGVyIG9iamVjdCB0aGF0IGhhcyBwcm9jZXNzZWQKLSAgICogICAgICAgICAgICAgICAgIHRoZSBYUGF0aCBvcGVyYXRpb25zIGludG8gYW4gb3Bjb2RlIG1hcC4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqIEBwYXJhbSBzdGVwSW5kZXggVGhlIHRvcC1sZXZlbCBzdGVwIGluZGV4IHdpdGhpbmcgdGhlIGl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIDMyIGJpdHMgYXMgYW4gaW50ZWdlciB0aGF0IGdpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2F0aW9uCi0gICAqIHBhdGggYXMgYSB3aG9sZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBpbnQgYW5hbHl6ZSgKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IHN0ZXBPcENvZGVQb3MsIGludCBzdGVwSW5kZXgpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgc3RlcFR5cGU7Ci0gICAgaW50IG9wc1tdID0gY29tcGlsZXIuZ2V0T3BNYXAoKTsKLSAgICBpbnQgc3RlcENvdW50ID0gMDsKLSAgICBpbnQgYW5hbHlzaXNSZXN1bHQgPSAweDAwMDAwMDAwOyAgLy8gMzIgYml0cyBvZiBhbmFseXNpcwotCi0gICAgd2hpbGUgKE9wQ29kZXMuRU5ET1AgIT0gKHN0ZXBUeXBlID0gb3BzW3N0ZXBPcENvZGVQb3NdKSkKLSAgICB7Ci0gICAgICBzdGVwQ291bnQrKzsKLQotICAgICAgLy8gU3RyaW5nIG5hbWVzcGFjZSA9IGNvbXBpbGVyLmdldFN0ZXBOUyhzdGVwT3BDb2RlUG9zKTsKLSAgICAgIC8vIGJvb2xlYW4gaXNOU1dpbGQgPSAobnVsbCAhPSBuYW1lc3BhY2UpIAotICAgICAgLy8gICAgICAgICAgICAgICAgICAgPyBuYW1lc3BhY2UuZXF1YWxzKE5vZGVUZXN0LldJTEQpIDogZmFsc2U7Ci0gICAgICAvLyBTdHJpbmcgbG9jYWxuYW1lID0gY29tcGlsZXIuZ2V0U3RlcExvY2FsTmFtZShzdGVwT3BDb2RlUG9zKTsKLSAgICAgIC8vIGJvb2xlYW4gaXNXaWxkID0gKG51bGwgIT0gbG9jYWxuYW1lKSA/IGxvY2FsbmFtZS5lcXVhbHMoTm9kZVRlc3QuV0lMRCkgOiBmYWxzZTsKLSAgICAgIGJvb2xlYW4gcHJlZEFuYWx5c2lzID0gYW5hbHl6ZVByZWRpY2F0ZShjb21waWxlciwgc3RlcE9wQ29kZVBvcywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwVHlwZSk7Ci0KLSAgICAgIGlmIChwcmVkQW5hbHlzaXMpCi0gICAgICAgIGFuYWx5c2lzUmVzdWx0IHw9IEJJVF9QUkVESUNBVEU7Ci0KLSAgICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0VYVEZVTkNUSU9OIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfRklMVEVSOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfUk9PVDsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfQU5DRVNUT1I7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfQU5DRVNUT1JfT1JfU0VMRjsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0FUVFJJQlVURTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfTkFNRVNQQUNFOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0NISUxEUkVOIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0NISUxEOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0RFU0NFTkRBTlQ7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0KLSAgICAgICAgLy8gVXNlIGEgc3BlY2lhbCBiaXQgdG8gdG8gbWFrZSBzdXJlIHdlIGdldCB0aGUgcmlnaHQgYW5hbHlzaXMgb2YgIi8vZm9vIi4KLSAgICAgICAgaWYgKDIgPT0gc3RlcENvdW50ICYmIEJJVF9ST09UID09IGFuYWx5c2lzUmVzdWx0KQotICAgICAgICB7Ci0gICAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0FOWV9ERVNDRU5EQU5UX0ZST01fUk9PVDsKLSAgICAgICAgfQotCi0gICAgICAgIGFuYWx5c2lzUmVzdWx0IHw9IEJJVF9ERVNDRU5EQU5UX09SX1NFTEY7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fRk9MTE9XSU5HIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX0ZPTExPV0lORzsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfRk9MTE9XSU5HX1NJQkxJTkc7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX1BSRUNFRElORzsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9QUkVDRURJTkdfU0lCTElOR1MgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSBCSVRfUFJFQ0VESU5HX1NJQkxJTkc7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLkZST01fUEFSRU5UIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX1BBUkVOVDsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9TRUxGIDoKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX1NFTEY7Ci0gICAgICAgIGJyZWFrOwotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FUVFJJQlVURSA6Ci0gICAgICAgIGFuYWx5c2lzUmVzdWx0IHw9IChCSVRfTUFUQ0hfUEFUVEVSTiB8IEJJVF9BVFRSSUJVVEUpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1IgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSAoQklUX01BVENIX1BBVFRFUk4gfCBCSVRfQU5DRVNUT1IpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9JTU1FRElBVEVfQU5DRVNUT1IgOgotICAgICAgICBhbmFseXNpc1Jlc3VsdCB8PSAoQklUX01BVENIX1BBVFRFUk4gfCBCSVRfUEFSRU5UKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBkZWZhdWx0IDoKLSAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfTlVMTF9FUlJPUl9IQU5ETEVSLCBuZXcgT2JqZWN0W117SW50ZWdlci50b1N0cmluZyhzdGVwVHlwZSl9KSk7IC8vIlByb2dyYW1tZXIncyBhc3NlcnRpb246IHVua25vd24gb3Bjb2RlOiAiCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vKyBzdGVwVHlwZSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChPcENvZGVzLk5PREVUWVBFX05PREUgPT0gb3BzW3N0ZXBPcENvZGVQb3MgKyAzXSkgIC8vIGNoaWxkOjpub2RlKCkKLSAgICAgIHsKLSAgICAgICAgYW5hbHlzaXNSZXN1bHQgfD0gQklUX05PREVURVNUX0FOWTsKLSAgICAgIH0KLQotICAgICAgc3RlcE9wQ29kZVBvcyA9IGNvbXBpbGVyLmdldE5leHRTdGVwUG9zKHN0ZXBPcENvZGVQb3MpOwotCi0gICAgICBpZiAoc3RlcE9wQ29kZVBvcyA8IDApCi0gICAgICAgIGJyZWFrOwotICAgIH0KLQotICAgIGFuYWx5c2lzUmVzdWx0IHw9IChzdGVwQ291bnQgJiBCSVRTX0NPVU5UKTsKLQotICAgIHJldHVybiBhbmFseXNpc1Jlc3VsdDsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhlIGdpdmVuIGF4aXMgZ29lcyBkb3dud29yZC4gIEJvZ3VzIG5hbWUsIGlmIHlvdSBjYW4gdGhpbmsgb2YgCi0gICAqIGEgYmV0dGVyIG9uZSwgcGxlYXNlIGRvIHRlbGwuICBUaGlzIHJlYWxseSBoYXMgdG8gZG8gd2l0aCBpbnZlcnRpbmcgCi0gICAqIGF0dHJpYnV0ZSBheGlzLgotICAgKiBAcGFyYW0gYXhpcyBPbmUgb2YgQXhpcy5YWFguCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgYXhpcyBpcyBub3QgYSBjaGlsZCBheGlzIGFuZCBkb2VzIG5vdCBnbyB1cCBmcm9tIAotICAgKiB0aGUgYXhpcyByb290LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRG93bndhcmRBeGlzT2ZNYW55KGludCBheGlzKQotICB7Ci0gICAgcmV0dXJuICgoQXhpcy5ERVNDRU5EQU5UT1JTRUxGID09IGF4aXMpIHx8Ci0gICAgICAgICAgKEF4aXMuREVTQ0VOREFOVCA9PSBheGlzKSAKLSAgICAgICAgICB8fCAoQXhpcy5GT0xMT1dJTkcgPT0gYXhpcykgCi0vLyAgICAgICAgICB8fCAoQXhpcy5GT0xMT1dJTkdTSUJMSU5HID09IGF4aXMpIAotICAgICAgICAgIHx8IChBeGlzLlBSRUNFRElORyA9PSBheGlzKSAKLS8vICAgICAgICAgIHx8IChBeGlzLlBSRUNFRElOR1NJQkxJTkcgPT0gYXhpcykKLSAgICAgICAgICApOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlYWQgYSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNsb2NhdGlvbi1wYXRocyI+TG9jYXRpb25QYXRoPC9hPgotICAgKiBhcyBhIGdlbmVyYWxpemVkIG1hdGNoIHBhdHRlcm4uICBXaGF0IHRoaXMgbWVhbnMgaXMgdGhhdCB0aGUgTG9jYXRpb25QYXRoCi0gICAqIGlzIHJlYWQgYmFja3dhcmRzLCBhcyBhIHRlc3Qgb24gYSBnaXZlbiBub2RlLCB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGUKLSAgICogY3JpdGVyaWEgb2YgdGhlIHNlbGVjdGlvbiwgYW5kIGVuZHMgdXAgYXQgdGhlIGNvbnRleHQgbm9kZS4gIEVzc2VudGlhbGx5LAotICAgKiB0aGlzIGlzIGEgYmFja3dhcmRzIHF1ZXJ5IGZyb20gYSBnaXZlbiBub2RlLCB0byBmaW5kIHRoZSBjb250ZXh0IG5vZGUuCi0gICAqIDxwPlNvLCB0aGUgc2VsZWN0aW9uICJmb28vZGF6WzJdIiBpcywgaW4gbm9uLWFicmV2aWF0ZWQgZXhwYW5kZWQgc3ludGF4LAotICAgKiAic2VsZjo6bm9kZSgpL2ZvbGxvd2luZy1zaWJsaW5nOjpmb28vY2hpbGQ6OmRheltwb3NpdGlvbigpPTJdIi4KLSAgICogVGFraW5nIHRoaXMgYXMgYSBtYXRjaCBwYXR0ZXJuIGZvciBhIHByb2JhYmxlIG5vZGUsIGl0IHdvcmtzIG91dCB0bwotICAgKiAic2VsZjo6ZGF6L3BhcmVudDo6Zm9vW2NoaWxkOjpkYXpbcG9zaXRpb24oKT0yIGFuZCBpc1ByZXZTdGVwTm9kZSgpXQotICAgKiBwcmVjZWRpbmdTaWJsaW5nOjpub2RlKClbaXNDb250ZXh0Tm9kZU9mTG9jYXRpb25QYXRoKCldIiwgYWRkaW5nIG1hZ2ljCi0gICAqIGlzUHJldlN0ZXBOb2RlIGFuZCBpc0NvbnRleHROb2RlT2ZMb2NhdGlvblBhdGggb3BlcmF0aW9ucy4gIFByZWRpY2F0ZXMgaW4KLSAgICogdGhlIGxvY2F0aW9uIHBhdGggaGF2ZSB0byBiZSBleGVjdXRlZCBieSB0aGUgZm9sbG93aW5nIHN0ZXAsCi0gICAqIGJlY2F1c2UgdGhleSBoYXZlIHRvIGtub3cgdGhlIGNvbnRleHQgb2YgdGhlaXIgZXhlY3V0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXBpIFRoZSBNYXRjaFBhdHRlcm5JdGVyYXRvciB0byB3aGljaCB0aGUgc3RlcHMgd2lsbCBiZSBhdHRhY2hlZC4KLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBjb21waWxlciB0aGF0IGhvbGRzIHRoZSBzeW50YXggdHJlZS9vcCBtYXAgdG8KLSAgICogY29uc3RydWN0IGZyb20uCi0gICAqIEBwYXJhbSBzdGVwT3BDb2RlUG9zIFRoZSBjdXJyZW50IG9wIGNvZGUgcG9zaXRpb24gd2l0aGluIHRoZSBvcG1hcC4KLSAgICogQHBhcmFtIHN0ZXBJbmRleCBUaGUgdG9wLWxldmVsIHN0ZXAgaW5kZXggd2l0aGluZyB0aGUgaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gQSBTdGVwUGF0dGVybiBvYmplY3QsIHdoaWNoIG1heSBjb250YWluIHJlbGF0aXZlIFN0ZXBQYXR0ZXJucy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBzdGF0aWMgU3RlcFBhdHRlcm4gbG9hZFN0ZXBzKAotICAgICAgICAgIE1hdGNoUGF0dGVybkl0ZXJhdG9yIG1waSwgQ29tcGlsZXIgY29tcGlsZXIsIGludCBzdGVwT3BDb2RlUG9zLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RlcEluZGV4KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmIChERUJVR19QQVRURVJOX0NSRUFUSU9OKQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPT09PT09PT09PT09PT09PSIpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJsb2FkU3RlcHMgZm9yOiAiK2NvbXBpbGVyLmdldFBhdHRlcm5TdHJpbmcoKSk7Ci0gICAgfQotICAgIGludCBzdGVwVHlwZTsKLSAgICBTdGVwUGF0dGVybiBzdGVwID0gbnVsbDsKLSAgICBTdGVwUGF0dGVybiBmaXJzdFN0ZXAgPSBudWxsLCBwcmV2U3RlcCA9IG51bGw7Ci0gICAgaW50IG9wc1tdID0gY29tcGlsZXIuZ2V0T3BNYXAoKTsKLSAgICBpbnQgYW5hbHlzaXMgPSBhbmFseXplKGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBzdGVwSW5kZXgpOwotCi0gICAgd2hpbGUgKE9wQ29kZXMuRU5ET1AgIT0gKHN0ZXBUeXBlID0gb3BzW3N0ZXBPcENvZGVQb3NdKSkKLSAgICB7Ci0gICAgICBzdGVwID0gY3JlYXRlRGVmYXVsdFN0ZXBQYXR0ZXJuKGNvbXBpbGVyLCBzdGVwT3BDb2RlUG9zLCBtcGksIGFuYWx5c2lzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFN0ZXAsIHByZXZTdGVwKTsKLQotICAgICAgaWYgKG51bGwgPT0gZmlyc3RTdGVwKQotICAgICAgewotICAgICAgICBmaXJzdFN0ZXAgPSBzdGVwOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vcHJldlN0ZXAuc2V0TmV4dFdhbGtlcihzdGVwKTsKLSAgICAgICAgc3RlcC5zZXRSZWxhdGl2ZVBhdGhQYXR0ZXJuKHByZXZTdGVwKTsKLSAgICAgIH0KLQotICAgICAgcHJldlN0ZXAgPSBzdGVwOwotICAgICAgc3RlcE9wQ29kZVBvcyA9IGNvbXBpbGVyLmdldE5leHRTdGVwUG9zKHN0ZXBPcENvZGVQb3MpOwotCi0gICAgICBpZiAoc3RlcE9wQ29kZVBvcyA8IDApCi0gICAgICAgIGJyZWFrOwotICAgIH0KLSAgICAKLSAgICBpbnQgYXhpcyA9IEF4aXMuU0VMRjsKLSAgICBpbnQgcGF4aXMgPSBBeGlzLlNFTEY7Ci0gICAgU3RlcFBhdHRlcm4gdGFpbCA9IHN0ZXA7Ci0gICAgZm9yIChTdGVwUGF0dGVybiBwYXQgPSBzdGVwOyBudWxsICE9IHBhdDsgCi0gICAgICAgICBwYXQgPSBwYXQuZ2V0UmVsYXRpdmVQYXRoUGF0dGVybigpKSAKLSAgICB7Ci0gICAgICBpbnQgbmV4dEF4aXMgPSBwYXQuZ2V0QXhpcygpOwotICAgICAgLy9pbnQgbmV4dFBheGlzID0gcGF0LmdldFByZWRpY2F0ZUF4aXMoKTsKLSAgICAgIHBhdC5zZXRBeGlzKGF4aXMpOwotICAgICAgCi0gICAgICAvLyBUaGUgcHJlZGljYXRlIGF4aXMgY2FuJ3QgYmUgbW92ZWQhISEgIFRlc3QgQXhlczEwMwotICAgICAgLy8gcGF0LnNldFByZWRpY2F0ZUF4aXMocGF4aXMpOwotICAgICAgCi0gICAgICAvLyBJZiB3ZSBoYXZlIGFuIGF0dHJpYnV0ZSBvciBuYW1lc3BhY2UgYXhpcyB0aGF0IHdlbnQgdXAsIHRoZW4gCi0gICAgICAvLyBpdCB3b24ndCBmaW5kIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIGludmVyc2UsIHNpbmNlIHRoZSBzZWxlY3QtdG8tbWF0Y2gKLSAgICAgIC8vIGF4ZXMgYXJlIG5vdCBpbnZlcnRhYmxlIChhbiBlbGVtZW50IGlzIGEgcGFyZW50IG9mIGFuIGF0dHJpYnV0ZSwgYnV0IAotICAgICAgLy8gYW5kIGF0dHJpYnV0ZSBpcyBub3QgYSBjaGlsZCBvZiBhbiBlbGVtZW50KS4KLSAgICAgIC8vIElmIHdlIGRvbid0IGRvIHRoZSBtYWdpYyBiZWxvdywgdGhlbiAiQCovYW5jZXN0b3Itb3Itc2VsZjo6KiIgZ2V0cwotICAgICAgLy8gaW52ZXJ0ZWQgZm9yIG1hdGNoIHRvICJzZWxmOjoqL2Rlc2NlbmRhbnQtb3Itc2VsZjo6QCovcGFyZW50Ojpub2RlKCkiLAotICAgICAgLy8gd2hpY2ggb2J2aW91c2x5IHdvbid0IHdvcmsuCi0gICAgICAvLyBTbyB3ZSB3aWxsIHJld3JpdGUgdGhpcyBhczoKLSAgICAgIC8vICJzZWxmOjoqL2Rlc2NlbmRhbnQtb3Itc2VsZjo6Ki9hdHRyaWJ1dGU6OiovcGFyZW50Ojpub2RlKCkiCi0gICAgICAvLyBDaGlsZCBoYXMgdG8gYmUgcmV3cml0dGVuIGEgbGl0dGxlIGRpZmZlcmVudGx5OgotICAgICAgLy8gc2VsZWN0OiAiQCovcGFyZW50OjoqIgotICAgICAgLy8gaW52ZXJ0ZWQgbWF0Y2g6ICJzZWxmOjoqL2NoaWxkOjpAKi9wYXJlbnQ6Om5vZGUoKSIKLSAgICAgIC8vIHJld3JpdGU6ICJzZWxmOjoqL2F0dHJpYnV0ZTo6Ki9wYXJlbnQ6Om5vZGUoKSIKLSAgICAgIC8vIEF4ZXMgdGhhdCBnbyBkb3duIGluIHRoZSBzZWxlY3QsIGRvIG5vdCBoYXZlIHRvIGhhdmUgc3BlY2lhbCB0cmVhdG1lbnQgCi0gICAgICAvLyBpbiB0aGUgcmV3cml0ZS4gVGhlIGZvbGxvd2luZyBpbnZlcnRlZCBtYXRjaCB3aWxsIHN0aWxsIG5vdCBzZWxlY3QgCi0gICAgICAvLyBhbnl0aGluZy4KLSAgICAgIC8vIHNlbGVjdDogIkAqL2NoaWxkOjoqIgotICAgICAgLy8gaW52ZXJ0ZWQgbWF0Y2g6ICJzZWxmOjoqL3BhcmVudDo6QCovcGFyZW50Ojpub2RlKCkiCi0gICAgICAvLyBMb3ZlbHkgYnVzaW5lc3MsIHRoaXMuCi0gICAgICAvLyAtc2IKLSAgICAgIGludCB3aGF0VG9TaG93ID0gcGF0LmdldFdoYXRUb1Nob3coKTsKLSAgICAgIGlmKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIHx8IAotICAgICAgICAgd2hhdFRvU2hvdyA9PSBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0UpCi0gICAgICB7Ci0gICAgICAgIGludCBuZXdBeGlzID0gKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFKSA/IAotICAgICAgICAgICAgICAgICAgICAgICBBeGlzLkFUVFJJQlVURSA6IEF4aXMuTkFNRVNQQUNFOwotICAgICAgICBpZihpc0Rvd253YXJkQXhpc09mTWFueShheGlzKSkKLSAgICAgICAgewotICAgICAgICAgIFN0ZXBQYXR0ZXJuIGF0dHJQYXQgPSBuZXcgU3RlcFBhdHRlcm4od2hhdFRvU2hvdywgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXQuZ2V0TmFtZXNwYWNlKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXQuZ2V0TG9jYWxOYW1lKCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbmV3QXhpcywgcGF0LmdldFByZWRpY2F0ZUF4aXMpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXhpcywgMCk7IC8vIGRvbid0IGNhcmUgYWJvdXQgdGhlIHByZWRpY2F0ZSBheGlzCi0gICAgICAgICAgWE51bWJlciBzY29yZSA9IHBhdC5nZXRTdGF0aWNTY29yZSgpOwotICAgICAgICAgIHBhdC5zZXROYW1lc3BhY2UobnVsbCk7Ci0gICAgICAgICAgcGF0LnNldExvY2FsTmFtZShOb2RlVGVzdC5XSUxEKTsKLSAgICAgICAgICBhdHRyUGF0LnNldFByZWRpY2F0ZXMocGF0LmdldFByZWRpY2F0ZXMoKSk7Ci0gICAgICAgICAgcGF0LnNldFByZWRpY2F0ZXMobnVsbCk7Ci0gICAgICAgICAgcGF0LnNldFdoYXRUb1Nob3coRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCk7Ci0gICAgICAgICAgU3RlcFBhdHRlcm4gcmVsID0gcGF0LmdldFJlbGF0aXZlUGF0aFBhdHRlcm4oKTsKLSAgICAgICAgICBwYXQuc2V0UmVsYXRpdmVQYXRoUGF0dGVybihhdHRyUGF0KTsKLSAgICAgICAgICBhdHRyUGF0LnNldFJlbGF0aXZlUGF0aFBhdHRlcm4ocmVsKTsKLSAgICAgICAgICBhdHRyUGF0LnNldFN0YXRpY1Njb3JlKHNjb3JlKTsKLSAgICAgICAgICAKLSAgICAgICAgICAvLyBUaGlzIGlzIG5lZWRlZCB0byBpbnZlcnNlIGEgZm9sbG93aW5nIHBhdHRlcm4sIGJlY2F1c2Ugb2YgdGhlIAotICAgICAgICAgIC8vIHdhY2t5IFhhbGFuIHJ1bGVzIGZvciBmb2xsb3dpbmcgZnJvbSBhbiBhdHRyaWJ1dGUuICBTZWUgYXhlczEwOC4KLSAgICAgICAgICAvLyBCeSB0aGVzZSBydWxlcywgZm9sbG93aW5nIGZyb20gYW4gYXR0cmlidXRlIGlzIG5vdCBzdHJpY3RseSAKLSAgICAgICAgICAvLyBpbnZlcnNlYWJsZS4KLSAgICAgICAgICBpZihBeGlzLlBSRUNFRElORyA9PSBwYXQuZ2V0QXhpcygpKQotICAgICAgICAgICAgcGF0LnNldEF4aXMoQXhpcy5QUkVDRURJTkdBTkRBTkNFU1RPUik7Ci0gICAgICAgICAgICAKLSAgICAgICAgICBlbHNlIGlmKEF4aXMuREVTQ0VOREFOVCA9PSBwYXQuZ2V0QXhpcygpKQotICAgICAgICAgICAgcGF0LnNldEF4aXMoQXhpcy5ERVNDRU5EQU5UT1JTRUxGKTsKLSAgICAgICAgICAKLSAgICAgICAgICBwYXQgPSBhdHRyUGF0OwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYoQXhpcy5DSElMRCA9PSBwYXQuZ2V0QXhpcygpKQotICAgICAgICB7Ci0gICAgICAgICAgLy8gSW4gdGhpcyBjYXNlIGp1c3QgY2hhbmdlIHRoZSBheGlzLgotICAgICAgICAgIC8vIHBhdC5zZXRXaGF0VG9TaG93KHdoYXRUb1Nob3cpOwotICAgICAgICAgIHBhdC5zZXRBeGlzKEF4aXMuQVRUUklCVVRFKTsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgYXhpcyA9IG5leHRBeGlzOwotICAgICAgLy9wYXhpcyA9IG5leHRQYXhpczsKLSAgICAgIHRhaWwgPSBwYXQ7Ci0gICAgfQotICAgIAotICAgIGlmKGF4aXMgPCBBeGlzLkFMTCkKLSAgICB7Ci0gICAgICBTdGVwUGF0dGVybiBzZWxmUGF0dGVybiA9IG5ldyBDb250ZXh0TWF0Y2hTdGVwUGF0dGVybihheGlzLCBwYXhpcyk7Ci0gICAgICAvLyBXZSBuZWVkIHRvIGtlZXAgdGhlIG5ldyBub2RldGVzdCBmcm9tIGFmZmVjdGluZyB0aGUgc2NvcmUuLi4KLSAgICAgIFhOdW1iZXIgc2NvcmUgPSB0YWlsLmdldFN0YXRpY1Njb3JlKCk7Ci0gICAgICB0YWlsLnNldFJlbGF0aXZlUGF0aFBhdHRlcm4oc2VsZlBhdHRlcm4pOwotICAgICAgdGFpbC5zZXRTdGF0aWNTY29yZShzY29yZSk7Ci0gICAgICBzZWxmUGF0dGVybi5zZXRTdGF0aWNTY29yZShzY29yZSk7Ci0gICAgfSAgICAgICAgCi0KLSAgICBpZiAoREVCVUdfUEFUVEVSTl9DUkVBVElPTikKLSAgICB7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRvbmUgbG9hZGluZyBzdGVwczogIitzdGVwLnRvU3RyaW5nKCkpOwotICAgICAgICAgICAgCi0gICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOwotICAgIH0KLSAgICByZXR1cm4gc3RlcDsgIC8vIHN0YXJ0IGZyb20gbGFzdCBwYXR0ZXJuPz8gLy9maXJzdFN0ZXA7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIGEgU3RlcFBhdHRlcm4gdGhhdCBpcyBjb250YWluZWQgd2l0aGluIGEgTG9jYXRpb25QYXRoLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIGNvbXBpbGVyIHRoYXQgaG9sZHMgdGhlIHN5bnRheCB0cmVlL29wIG1hcCB0bwotICAgKiBjb25zdHJ1Y3QgZnJvbS4KLSAgICogQHBhcmFtIHN0ZXBPcENvZGVQb3MgVGhlIGN1cnJlbnQgb3AgY29kZSBwb3NpdGlvbiB3aXRoaW4gdGhlIG9wbWFwLgotICAgKiBAcGFyYW0gbXBpIFRoZSBNYXRjaFBhdHRlcm5JdGVyYXRvciB0byB3aGljaCB0aGUgc3RlcHMgd2lsbCBiZSBhdHRhY2hlZC4KLSAgICogQHBhcmFtIGFuYWx5c2lzIDMyIGJpdHMgb2YgYW5hbHlzaXMsIGZyb20gd2hpY2ggdGhlIHR5cGUgb2YgQXhlc1dhbGtlcgotICAgKiAgICAgICAgICAgICAgICAgbWF5IGJlIGluZmx1ZW5jZWQuCi0gICAqIEBwYXJhbSB0YWlsIFRoZSBzdGVwIHRoYXQgaXMgdGhlIGZpcnN0IHN0ZXAgYW5hbHl6ZWQsIGJ1dCB0aGUgbGFzdCAKLSAgICogICAgICAgICAgICAgICAgICBzdGVwIGluIHRoZSByZWxhdGl2ZSBtYXRjaCBsaW5rZWQgbGlzdCwgaS5lLiB0aGUgdGFpbC4KLSAgICogICAgICAgICAgICAgICAgICBNYXkgYmUgbnVsbC4KLSAgICogQHBhcmFtIGhlYWQgVGhlIHN0ZXAgdGhhdCBpcyB0aGUgY3VycmVudCBoZWFkIG9mIHRoZSByZWxhdGl2ZSAKLSAgICogICAgICAgICAgICAgICAgIG1hdGNoIHN0ZXAgbGlua2VkIGxpc3QuCi0gICAqICAgICAgICAgICAgICAgICBNYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgaGVhZCBvZiB0aGUgbGlzdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBTdGVwUGF0dGVybiBjcmVhdGVEZWZhdWx0U3RlcFBhdHRlcm4oCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgTWF0Y2hQYXR0ZXJuSXRlcmF0b3IgbXBpLCAKLSAgICAgICAgICBpbnQgYW5hbHlzaXMsIFN0ZXBQYXR0ZXJuIHRhaWwsIFN0ZXBQYXR0ZXJuIGhlYWQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChvcFBvcyk7Ci0gICAgYm9vbGVhbiBzaW1wbGVJbml0ID0gZmFsc2U7Ci0gICAgaW50IHRvdGFsTnVtYmVyV2Fsa2VycyA9IChhbmFseXNpcyAmIEJJVFNfQ09VTlQpOwotICAgIGJvb2xlYW4gcHJldklzT25lU3RlcERvd24gPSB0cnVlOwotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBjb21waWxlci5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLSAgICAKLSAgICBpbnQgd2hhdFRvU2hvdyA9IGNvbXBpbGVyLmdldFdoYXRUb1Nob3cob3BQb3MpOwotICAgIFN0ZXBQYXR0ZXJuIGFpID0gbnVsbDsKLSAgICBpbnQgYXhpcywgcHJlZGljYXRlQXhpczsKLSAgICAKLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLQotICAgICAgRXhwcmVzc2lvbiBleHByOwotCi0gICAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgICAgewotICAgICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgICAgZXhwciA9IGNvbXBpbGVyLmNvbXBpbGUob3BQb3MpOwotICAgICAgICBicmVhazsKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICBleHByID0gY29tcGlsZXIuY29tcGlsZShvcFBvcyArIDIpOwotICAgICAgfQotCi0gICAgICBheGlzID0gQXhpcy5GSUxURVJFRExJU1Q7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5GSUxURVJFRExJU1Q7Ci0gICAgICBhaSA9IG5ldyBGdW5jdGlvblBhdHRlcm4oZXhwciwgYXhpcywgcHJlZGljYXRlQXhpcyk7Ci0gICAgICBzaW1wbGVJbml0ID0gdHJ1ZTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgd2hhdFRvU2hvdyA9IERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UCi0gICAgICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVDsKLQotICAgICAgYXhpcyA9IEF4aXMuUk9PVDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLlJPT1Q7Ci0gICAgICBhaSA9IG5ldyBTdGVwUGF0dGVybihEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVCB8IAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcywgcHJlZGljYXRlQXhpcyk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIHdoYXRUb1Nob3cgPSBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEU7Ci0gICAgICBheGlzID0gQXhpcy5QQVJFTlQ7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5BVFRSSUJVVEU7Ci0gICAgICAvLyBhaSA9IG5ldyBTdGVwUGF0dGVybih3aGF0VG9TaG93LCBBeGlzLlNFTEYsIEF4aXMuU0VMRik7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgOgotICAgICAgd2hhdFRvU2hvdyA9IERUTUZpbHRlci5TSE9XX05BTUVTUEFDRTsKLSAgICAgIGF4aXMgPSBBeGlzLlBBUkVOVDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLk5BTUVTUEFDRTsKLSAgICAgIC8vIGFpID0gbmV3IFN0ZXBQYXR0ZXJuKHdoYXRUb1Nob3csIGF4aXMsIHByZWRpY2F0ZUF4aXMpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTIDoKLSAgICAgIGF4aXMgPSBBeGlzLkRFU0NFTkRBTlQ7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5BTkNFU1RPUjsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0NISUxEUkVOIDoKLSAgICAgIGF4aXMgPSBBeGlzLlBBUkVOVDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkNISUxEOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOgotICAgICAgYXhpcyA9IEF4aXMuREVTQ0VOREFOVE9SU0VMRjsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkFOQ0VTVE9ST1JTRUxGOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fU0VMRiA6Ci0gICAgICBheGlzID0gQXhpcy5TRUxGOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuU0VMRjsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BBUkVOVCA6Ci0gICAgICBheGlzID0gQXhpcy5DSElMRDsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLlBBUkVOVDsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBheGlzID0gQXhpcy5GT0xMT1dJTkdTSUJMSU5HOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuUFJFQ0VESU5HU0lCTElORzsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElORyA6Ci0gICAgICBheGlzID0gQXhpcy5GT0xMT1dJTkc7Ci0gICAgICBwcmVkaWNhdGVBeGlzID0gQXhpcy5QUkVDRURJTkc7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgYXhpcyA9IEF4aXMuUFJFQ0VESU5HU0lCTElORzsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkZPTExPV0lOR1NJQkxJTkc7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcgOgotICAgICAgYXhpcyA9IEF4aXMuUFJFQ0VESU5HOwotICAgICAgcHJlZGljYXRlQXhpcyA9IEF4aXMuRk9MTE9XSU5HOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0gICAgICBheGlzID0gQXhpcy5BTkNFU1RPUk9SU0VMRjsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkRFU0NFTkRBTlRPUlNFTEY7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UUyA6Ci0gICAgICBheGlzID0gQXhpcy5BTkNFU1RPUjsKLSAgICAgIHByZWRpY2F0ZUF4aXMgPSBBeGlzLkRFU0NFTkRBTlQ7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHN0ZXBUeXBlKTsKLSAgICB9Ci0gICAgaWYobnVsbCA9PSBhaSkKLSAgICB7Ci0gICAgICB3aGF0VG9TaG93ID0gY29tcGlsZXIuZ2V0V2hhdFRvU2hvdyhvcFBvcyk7IC8vICVSRVZJRVclCi0gICAgICBhaSA9IG5ldyBTdGVwUGF0dGVybih3aGF0VG9TaG93LCBjb21waWxlci5nZXRTdGVwTlMob3BQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlci5nZXRTdGVwTG9jYWxOYW1lKG9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcywgcHJlZGljYXRlQXhpcyk7Ci0gICAgfQotICAgCi0gICAgaWYgKGZhbHNlIHx8IERFQlVHX1BBVFRFUk5fQ1JFQVRJT04pCi0gICAgewotICAgICAgU3lzdGVtLm91dC5wcmludCgibmV3IHN0ZXA6ICIrIGFpKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgYXhpczogIiArIEF4aXMubmFtZXNbYWkuZ2V0QXhpcygpXSk7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCIsIHByZWRBeGlzOiAiICsgQXhpcy5uYW1lc1thaS5nZXRBeGlzKCldKTsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoIiwgd2hhdDogIik7Ci0gICAgICBTeXN0ZW0ub3V0LnByaW50KCIgICAgIik7Ci0gICAgICBhaS5kZWJ1Z1doYXRUb1Nob3coYWkuZ2V0V2hhdFRvU2hvdygpKTsKLSAgICB9Ci0KLSAgICBpbnQgYXJnTGVuID0gY29tcGlsZXIuZ2V0Rmlyc3RQcmVkaWNhdGVPcFBvcyhvcFBvcyk7Ci0KLSAgICBhaS5zZXRQcmVkaWNhdGVzKGNvbXBpbGVyLmdldENvbXBpbGVkUHJlZGljYXRlcyhhcmdMZW4pKTsKLQotICAgIHJldHVybiBhaTsKLSAgfQotCi0gIC8qKgotICAgKiBBbmFseXplIGEgc3RlcCBhbmQgZ2l2ZSBpbmZvcm1hdGlvbiBhYm91dCBpdCdzIHByZWRpY2F0ZXMuICBSaWdodCBub3cgdGhpcwotICAgKiBqdXN0IHJldHVybnMgdHJ1ZSBvciBmYWxzZSBpZiB0aGUgc3RlcCBoYXMgYSBwcmVkaWNhdGUuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBub24tbnVsbCByZWZlcmVuY2UgdG8gY29tcGlsZXIgb2JqZWN0IHRoYXQgaGFzIHByb2Nlc3NlZAotICAgKiAgICAgICAgICAgICAgICAgdGhlIFhQYXRoIG9wZXJhdGlvbnMgaW50byBhbiBvcGNvZGUgbWFwLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIG9wY29kZSBwb3NpdGlvbiBmb3IgdGhlIHN0ZXAuCi0gICAqIEBwYXJhbSBzdGVwVHlwZSBUaGUgdHlwZSBvZiBzdGVwLCBvbmUgb2YgT1BfR1JPVVAsIGV0Yy4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHN0ZXAgaGFzIGEgcHJlZGljYXRlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHN0YXRpYyBib29sZWFuIGFuYWx5emVQcmVkaWNhdGUoQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IHN0ZXBUeXBlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBhcmdMZW47Ci0KLSAgICBzd2l0Y2ggKHN0ZXBUeXBlKQotICAgIHsKLSAgICBjYXNlIE9wQ29kZXMuT1BfVkFSSUFCTEUgOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0ZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgYXJnTGVuID0gY29tcGlsZXIuZ2V0QXJnTGVuZ3RoKG9wUG9zKTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgYXJnTGVuID0gY29tcGlsZXIuZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zKTsKLSAgICB9Ci0KLSAgICBpbnQgcG9zID0gY29tcGlsZXIuZ2V0Rmlyc3RQcmVkaWNhdGVPcFBvcyhvcFBvcyk7Ci0gICAgaW50IG5QcmVkaWNhdGVzID0gY29tcGlsZXIuY291bnRQcmVkaWNhdGVzKHBvcyk7Ci0KLSAgICByZXR1cm4gKG5QcmVkaWNhdGVzID4gMCkgPyB0cnVlIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQ3JlYXRlIHRoZSBwcm9wZXIgV2Fsa2VyIGZyb20gdGhlIGF4ZXMgdHlwZS4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21waWxlciBvYmplY3QgdGhhdCBoYXMgcHJvY2Vzc2VkCi0gICAqICAgICAgICAgICAgICAgICB0aGUgWFBhdGggb3BlcmF0aW9ucyBpbnRvIGFuIG9wY29kZSBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgb3Bjb2RlIHBvc2l0aW9uIGZvciB0aGUgc3RlcC4KLSAgICogQHBhcmFtIGxwaSBUaGUgb3duaW5nIGxvY2F0aW9uIHBhdGggaXRlcmF0b3IuCi0gICAqIEBwYXJhbSBhbmFseXNpcyAzMiBiaXRzIG9mIGFuYWx5c2lzLCBmcm9tIHdoaWNoIHRoZSB0eXBlIG9mIEF4ZXNXYWxrZXIKLSAgICogICAgICAgICAgICAgICAgIG1heSBiZSBpbmZsdWVuY2VkLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBBeGVzV2Fsa2VyIGRlcml2YXRpdmUuCi0gICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgaXMgYmFkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgQXhlc1dhbGtlciBjcmVhdGVEZWZhdWx0V2Fsa2VyKENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgb3BQb3MsCi0gICAgICAgICAgV2Fsa2luZ0l0ZXJhdG9yIGxwaSwgaW50IGFuYWx5c2lzKQotICB7Ci0KLSAgICBBeGVzV2Fsa2VyIGFpID0gbnVsbDsKLSAgICBpbnQgc3RlcFR5cGUgPSBjb21waWxlci5nZXRPcChvcFBvcyk7Ci0KLSAgICAvKgotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiMDogIitjb21waWxlci5nZXRPcChvcFBvcykpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiMTogIitjb21waWxlci5nZXRPcChvcFBvcysxKSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCIyOiAiK2NvbXBpbGVyLmdldE9wKG9wUG9zKzIpKTsKLSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIjM6ICIrY29tcGlsZXIuZ2V0T3Aob3BQb3MrMykpOwotICAgIFN5c3RlbS5vdXQucHJpbnRsbigiNDogIitjb21waWxlci5nZXRPcChvcFBvcys0KSk7Ci0gICAgU3lzdGVtLm91dC5wcmludGxuKCI1OiAiK2NvbXBpbGVyLmdldE9wKG9wUG9zKzUpKTsKLSAgICAqLwotICAgIGJvb2xlYW4gc2ltcGxlSW5pdCA9IGZhbHNlOwotICAgIGludCB0b3RhbE51bWJlcldhbGtlcnMgPSAoYW5hbHlzaXMgJiBCSVRTX0NPVU5UKTsKLSAgICBib29sZWFuIHByZXZJc09uZVN0ZXBEb3duID0gdHJ1ZTsKLQotICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgY2FzZSBPcENvZGVzLk9QX0VYVEZVTkNUSU9OIDoKLSAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgIGNhc2UgT3BDb2Rlcy5PUF9HUk9VUCA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotCi0gICAgICBpZiAoREVCVUdfV0FMS0VSX0NSRUFUSU9OKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5ldyB3YWxrZXI6ICBGaWx0ZXJFeHByV2Fsa2VyOiAiICsgYW5hbHlzaXMKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgIiArIGNvbXBpbGVyLnRvU3RyaW5nKCkpOwotCi0gICAgICBhaSA9IG5ldyBGaWx0ZXJFeHByV2Fsa2VyKGxwaSk7Ci0gICAgICBzaW1wbGVJbml0ID0gdHJ1ZTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuUk9PVCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IFJldmVyc2VBeGVzV2Fsa2VyKGxwaSwgQXhpcy5BTkNFU1RPUik7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlNfT1JfU0VMRiA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotICAgICAgYWkgPSBuZXcgUmV2ZXJzZUF4ZXNXYWxrZXIobHBpLCBBeGlzLkFOQ0VTVE9ST1JTRUxGKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FUVFJJQlVURVMgOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuQVRUUklCVVRFKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICBhaSA9IG5ldyBBeGVzV2Fsa2VyKGxwaSwgQXhpcy5OQU1FU1BBQ0UpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fQ0hJTERSRU4gOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFMgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IEF4ZXNXYWxrZXIobHBpLCBBeGlzLkRFU0NFTkRBTlQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRiA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuREVTQ0VOREFOVE9SU0VMRik7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IEF4ZXNXYWxrZXIobHBpLCBBeGlzLkZPTExPV0lORyk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgcHJldklzT25lU3RlcERvd24gPSBmYWxzZTsKLSAgICAgIGFpID0gbmV3IEF4ZXNXYWxrZXIobHBpLCBBeGlzLkZPTExPV0lOR1NJQkxJTkcpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgIHByZXZJc09uZVN0ZXBEb3duID0gZmFsc2U7Ci0gICAgICBhaSA9IG5ldyBSZXZlcnNlQXhlc1dhbGtlcihscGksIEF4aXMuUFJFQ0VESU5HKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBwcmV2SXNPbmVTdGVwRG93biA9IGZhbHNlOwotICAgICAgYWkgPSBuZXcgUmV2ZXJzZUF4ZXNXYWxrZXIobHBpLCBBeGlzLlBSRUNFRElOR1NJQkxJTkcpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUEFSRU5UIDoKLSAgICAgIHByZXZJc09uZVN0ZXBEb3duID0gZmFsc2U7Ci0gICAgICBhaSA9IG5ldyBSZXZlcnNlQXhlc1dhbGtlcihscGksIEF4aXMuUEFSRU5UKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1NFTEYgOgotICAgICAgYWkgPSBuZXcgQXhlc1dhbGtlcihscGksIEF4aXMuU0VMRik7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8rIHN0ZXBUeXBlKTsKLSAgICB9Ci0KLSAgICBpZiAoc2ltcGxlSW5pdCkKLSAgICB7Ci0gICAgICBhaS5pbml0Tm9kZVRlc3QoRFRNRmlsdGVyLlNIT1dfQUxMKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCB3aGF0VG9TaG93ID0gY29tcGlsZXIuZ2V0V2hhdFRvU2hvdyhvcFBvcyk7Ci0KLSAgICAgIC8qCi0gICAgICBTeXN0ZW0ub3V0LnByaW50KCJjb25zdHJ1Y3Q6ICIpOwotICAgICAgTm9kZVRlc3QuZGVidWdXaGF0VG9TaG93KHdoYXRUb1Nob3cpOwotICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJvciBzdHVmZjogIisod2hhdFRvU2hvdyAmIChEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikpKTsKLSAgICAgICovCi0gICAgICBpZiAoKDAgPT0gKHdoYXRUb1Nob3cKLSAgICAgICAgICAgICAgICAgJiAoRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIHwgRFRNRmlsdGVyLlNIT1dfTkFNRVNQQUNFIHwgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVAotICAgICAgICAgICAgICAgICAgICB8IERUTUZpbHRlci5TSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pKSkgfHwgKHdoYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQUxMKSkKLSAgICAgICAgYWkuaW5pdE5vZGVUZXN0KHdoYXRUb1Nob3cpOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBhaS5pbml0Tm9kZVRlc3Qod2hhdFRvU2hvdywgY29tcGlsZXIuZ2V0U3RlcE5TKG9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBpbGVyLmdldFN0ZXBMb2NhbE5hbWUob3BQb3MpKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWk7Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFuYWx5c2lzU3RyaW5nKGludCBhbmFseXNpcykKLSAgewotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0gICAgYnVmLmFwcGVuZCgiY291bnQ6ICIrZ2V0U3RlcENvdW50KGFuYWx5c2lzKSsiICIpOwotICAgIGlmKChhbmFseXNpcyAmIEJJVF9OT0RFVEVTVF9BTlkpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiTlRBTll8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9QUkVESUNBVEUpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiUFJFRHwiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX0FOQ0VTVE9SKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkFOQ3wiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX0FOQ0VTVE9SX09SX1NFTEYpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiQU5DT1N8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9BVFRSSUJVVEUpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiQVRUUnwiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX0NISUxEKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkNIfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfREVTQ0VOREFOVCkgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJERVNDfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfREVTQ0VOREFOVF9PUl9TRUxGKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkRFU0NPU3wiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX0ZPTExPV0lORykgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJGT0x8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9GT0xMT1dJTkdfU0lCTElORykgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCJGT0xTfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfTkFNRVNQQUNFKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIk5TfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfUEFSRU5UKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIlB8Iik7Ci0gICAgfQotICAgIGlmKChhbmFseXNpcyAmIEJJVF9QUkVDRURJTkcpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiUFJFQ3wiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX1BSRUNFRElOR19TSUJMSU5HKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIlBSRUNTfCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfU0VMRikgIT0gMCkKLSAgICB7Ci0gICAgICBidWYuYXBwZW5kKCIufCIpOwotICAgIH0KLSAgICBpZigoYW5hbHlzaXMgJiBCSVRfRklMVEVSKSAhPSAwKQotICAgIHsKLSAgICAgIGJ1Zi5hcHBlbmQoIkZMVHwiKTsKLSAgICB9Ci0gICAgaWYoKGFuYWx5c2lzICYgQklUX1JPT1QpICE9IDApCi0gICAgewotICAgICAgYnVmLmFwcGVuZCgiUnwiKTsKLSAgICB9Ci0gICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotICB9Ci0KLSAgLyoqIFNldCB0byB0cnVlIGZvciBkaWFnbm9zdGljcyBhYm91dCB3YWxrZXIgY3JlYXRpb24gKi8KLSAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfUEFUVEVSTl9DUkVBVElPTiA9IGZhbHNlOwotCi0gIC8qKiBTZXQgdG8gdHJ1ZSBmb3IgZGlhZ25vc3RpY3MgYWJvdXQgd2Fsa2VyIGNyZWF0aW9uICovCi0gIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX1dBTEtFUl9DUkVBVElPTiA9IGZhbHNlOwotCi0gIC8qKiBTZXQgdG8gdHJ1ZSBmb3IgZGlhZ25vc3RpY3MgYWJvdXQgaXRlcmF0b3IgY3JlYXRpb24gKi8KLSAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfSVRFUkFUT1JfQ1JFQVRJT04gPSBmYWxzZTsKLSAgCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNQcmVkaWNhdGUoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuICgwICE9IChhbmFseXNpcyAmIEJJVF9QUkVESUNBVEUpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1dpbGQoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuICgwICE9IChhbmFseXNpcyAmIEJJVF9OT0RFVEVTVF9BTlkpKTsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0FuY2VzdG9ycyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9BTkNFU1RPUiB8IEJJVF9BTkNFU1RPUl9PUl9TRUxGKTsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzQXR0cmlidXRlcyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gKDAgIT0gKGFuYWx5c2lzICYgQklUX0FUVFJJQlVURSkpOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzTmFtZXNwYWNlcyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gKDAgIT0gKGFuYWx5c2lzICYgQklUX05BTUVTUEFDRSkpOwotICB9ICAKLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NDaGlsZHJlbihpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gKDAgIT0gKGFuYWx5c2lzICYgQklUX0NISUxEKSk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NEZXNjZW5kYW50cyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9ERVNDRU5EQU5UIHwgQklUX0RFU0NFTkRBTlRfT1JfU0VMRik7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NTdWJ0cmVlKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX0RFU0NFTkRBTlQgfCBCSVRfREVTQ0VOREFOVF9PUl9TRUxGIHwgQklUX0NISUxEKTsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzU3VidHJlZU9ubHkoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIHdhbGtzU3VidHJlZShhbmFseXNpcykKLSAgICAgICAgICAgJiYgIXdhbGtzRXh0cmFOb2RlcyhhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykgCi0gICAgICAgICAgIDsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0ZpbHRlcmVkTGlzdChpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9GSUxURVIpOwotICB9Ci0gIAotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NTdWJ0cmVlT25seUZyb21Sb290T3JDb250ZXh0KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc1N1YnRyZWUoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc0V4dHJhTm9kZXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIWlzU2V0KGFuYWx5c2lzLCBCSVRfRklMVEVSKSAKLSAgICAgICAgICAgOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzSW5Eb2NPcmRlcihpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gKHdhbGtzU3VidHJlZShhbmFseXNpcykKLSAgICAgICAgICAgfHwgd2Fsa3NFeHRyYU5vZGVzKGFuYWx5c2lzKQotICAgICAgICAgICB8fCBpc1NldChhbmFseXNpcywgQklUX1NFTEYgfCBCSVRfRk9MTE9XSU5HX1NJQkxJTkcgfCBCSVRfRk9MTE9XSU5HKSkgCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIWlzU2V0KGFuYWx5c2lzLCBCSVRfUFJFQ0VESU5HIHwgQklUX1BSRUNFRElOR19TSUJMSU5HKSAKLSAgICAgICAgICAgJiYgIWlzU2V0KGFuYWx5c2lzLCBCSVRfRklMVEVSKSAKLSAgICAgICAgICAgOwotICB9Ci0gIAotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NVcChpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9QQVJFTlQgfCBCSVRfQU5DRVNUT1IgfCBCSVRfQU5DRVNUT1JfT1JfU0VMRik7Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc1NpZGV3YXlzKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX0ZPTExPV0lORyB8IEJJVF9GT0xMT1dJTkdfU0lCTElORyB8IAotICAgICAgICAgICAgICAgICAgICAgICAgICAgQklUX1BSRUNFRElORyB8IEJJVF9QUkVDRURJTkdfU0lCTElORyk7Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0V4dHJhTm9kZXMoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIGlzU2V0KGFuYWx5c2lzLCBCSVRfTkFNRVNQQUNFIHwgQklUX0FUVFJJQlVURSk7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NFeHRyYU5vZGVzT25seShpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gd2Fsa3NFeHRyYU5vZGVzKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhaXNTZXQoYW5hbHlzaXMsIEJJVF9TRUxGKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU3VidHJlZShhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykgCi0gICAgICAgICAgIDsKLSAgfQotCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Fic29sdXRlKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiBpc1NldChhbmFseXNpcywgQklUX1JPT1QgfCBCSVRfRklMVEVSKTsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzQ2hpbGRyZW5Pbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc0NoaWxkcmVuKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhaXNTZXQoYW5hbHlzaXMsIEJJVF9TRUxGKQotICAgICAgICAgICAmJiAhd2Fsa3NFeHRyYU5vZGVzKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NEZXNjZW5kYW50cyhhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykgCi0gICAgICAgICAgIDsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzQ2hpbGRyZW5BbmRFeHRyYUFuZFNlbGZPbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc0NoaWxkcmVuKGFuYWx5c2lzKQotICAgICAgICAgICAmJiAhd2Fsa3NEZXNjZW5kYW50cyhhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykgCi0gICAgICAgICAgIDsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzRGVzY2VuZGFudHNBbmRFeHRyYUFuZFNlbGZPbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiAhd2Fsa3NDaGlsZHJlbihhbmFseXNpcykKLSAgICAgICAgICAgJiYgd2Fsa3NEZXNjZW5kYW50cyhhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykgCi0gICAgICAgICAgIDsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzU2VsZk9ubHkoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgcmV0dXJuIGlzU2V0KGFuYWx5c2lzLCBCSVRfU0VMRikgCi0gICAgICAgICAgICYmICF3YWxrc1N1YnRyZWUoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIWlzQWJzb2x1dGUoYW5hbHlzaXMpIAotICAgICAgICAgICA7Ci0gIH0KLQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIHdhbGtzVXBPbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiAhd2Fsa3NTdWJ0cmVlKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgd2Fsa3NVcChhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIWlzQWJzb2x1dGUoYW5hbHlzaXMpIAotICAgICAgICAgICA7Ci0gIH0KLSAgCi0gIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB3YWxrc0Rvd25Pbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc1N1YnRyZWUoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhd2Fsa3NVcChhbmFseXNpcykgCi0gICAgICAgICAgICYmICF3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIWlzQWJzb2x1dGUoYW5hbHlzaXMpIAotICAgICAgICAgICA7Ci0gIH0KLQotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gd2Fsa3NEb3duRXh0cmFPbmx5KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiB3YWxrc1N1YnRyZWUoYW5hbHlzaXMpICYmICB3YWxrc0V4dHJhTm9kZXMoYW5hbHlzaXMpCi0gICAgICAgICAgICYmICF3YWxrc1VwKGFuYWx5c2lzKSAKLSAgICAgICAgICAgJiYgIXdhbGtzU2lkZXdheXMoYW5hbHlzaXMpIAotICAgICAgICAgICAmJiAhaXNBYnNvbHV0ZShhbmFseXNpcykgCi0gICAgICAgICAgIDsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGNhblNraXBTdWJ0cmVlcyhpbnQgYW5hbHlzaXMpCi0gIHsKLSAgICByZXR1cm4gaXNTZXQoYW5hbHlzaXMsIEJJVF9DSElMRCkgfCB3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKTsKLSAgfQotICAKLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGNhbkNyaXNzQ3Jvc3MoaW50IGFuYWx5c2lzKQotICB7Ci0gICAgLy8gVGhpcyBjb3VsZCBiZSBkb25lIGZhc3Rlci4gIENvZGVkIGZvciBjbGFyaXR5LgotICAgIGlmKHdhbGtzU2VsZk9ubHkoYW5hbHlzaXMpKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIGVsc2UgaWYod2Fsa3NEb3duT25seShhbmFseXNpcykgJiYgIWNhblNraXBTdWJ0cmVlcyhhbmFseXNpcykpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZSBpZih3YWxrc0NoaWxkcmVuQW5kRXh0cmFBbmRTZWxmT25seShhbmFseXNpcykpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZSBpZih3YWxrc0Rlc2NlbmRhbnRzQW5kRXh0cmFBbmRTZWxmT25seShhbmFseXNpcykpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZSBpZih3YWxrc1VwT25seShhbmFseXNpcykpCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgZWxzZSBpZih3YWxrc0V4dHJhTm9kZXNPbmx5KGFuYWx5c2lzKSkKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICBlbHNlIGlmKHdhbGtzU3VidHJlZShhbmFseXNpcykgCi0gICAgICAgICAgICYmICh3YWxrc1NpZGV3YXlzKGFuYWx5c2lzKSAKLSAgICAgICAgICAgIHx8IHdhbGtzVXAoYW5hbHlzaXMpIAotICAgICAgICAgICAgfHwgY2FuU2tpcFN1YnRyZWVzKGFuYWx5c2lzKSkpCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBwYXR0ZXJuIGNhbiBiZSAnd2Fsa2VkJyB3aXRoIHRoZSBpdGVyYXRpb24gc3RlcHMgaW4gbmF0dXJhbCAKLSAgICogZG9jdW1lbnQgb3JkZXIsIHdpdGhvdXQgZHVwbGljYXRlcy4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIG5vbi1udWxsIHJlZmVyZW5jZSB0byBjb21waWxlciBvYmplY3QgdGhhdCBoYXMgcHJvY2Vzc2VkCi0gICAqICAgICAgICAgICAgICAgICB0aGUgWFBhdGggb3BlcmF0aW9ucyBpbnRvIGFuIG9wY29kZSBtYXAuCi0gICAqIEBwYXJhbSBzdGVwT3BDb2RlUG9zIFRoZSBvcGNvZGUgcG9zaXRpb24gZm9yIHRoZSBzdGVwLgotICAgKiBAcGFyYW0gc3RlcEluZGV4IFRoZSB0b3AtbGV2ZWwgc3RlcCBpbmRleCB3aXRoaW5nIHRoZSBpdGVyYXRvci4KLSAgICogQHBhcmFtIGFuYWx5c2lzIFRoZSBnZW5lcmFsIGFuYWx5c2lzIG9mIHRoZSBwYXR0ZXJuLgotICAgKgotICAgKiBAcmV0dXJuIDMyIGJpdHMgYXMgYW4gaW50ZWdlciB0aGF0IGdpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2F0aW9uCi0gICAqIHBhdGggYXMgYSB3aG9sZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTmF0dXJhbERvY09yZGVyKAotICAgICAgICAgIENvbXBpbGVyIGNvbXBpbGVyLCBpbnQgc3RlcE9wQ29kZVBvcywgaW50IHN0ZXBJbmRleCwgaW50IGFuYWx5c2lzKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmKGNhbkNyaXNzQ3Jvc3MoYW5hbHlzaXMpKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgCi0gICAgLy8gTmFtZXNwYWNlcyBjYW4gcHJlc2VudCBzb21lIHByb2JsZW1zLCBzbyBqdXN0IHB1bnQgaWYgd2UncmUgbG9va2luZyBmb3IgCi0gICAgLy8gdGhlc2UuCi0gICAgaWYoaXNTZXQoYW5hbHlzaXMsIEJJVF9OQU1FU1BBQ0UpKQotICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgCi0gICAgLy8gVGhlIGZvbGxvd2luZywgcHJlY2VkaW5nLCBmb2xsb3dpbmctc2libGluZywgYW5kIHByZWNlZGluZyBzaWJsaW5nIGNhbiAKLSAgICAvLyBiZSBmb3VuZCBpbiBkb2Mgb3JkZXIgaWYgd2UgZ2V0IHRvIHRoaXMgcG9pbnQsIGJ1dCBpZiB0aGV5IG9jY3VyIAotICAgIC8vIHRvZ2V0aGVyLCB0aGV5IHByb2R1Y2UgCi0gICAgLy8gZHVwbGljYXRlcywgc28gaXQncyBiZXR0ZXIgZm9yIHVzIHRvIGVsaW1pbmF0ZSB0aGlzIGNhc2Ugc28gd2UgZG9uJ3QgCi0gICAgLy8gaGF2ZSB0byBjaGVjayBmb3IgZHVwbGljYXRlcyBkdXJpbmcgcnVudGltZSBpZiB3ZSdyZSB1c2luZyBhIAotICAgIC8vIFdhbGtpbmdJdGVyYXRvci4KLSAgICBpZihpc1NldChhbmFseXNpcywgQklUX0ZPTExPV0lORyB8IEJJVF9GT0xMT1dJTkdfU0lCTElORykgJiYgCi0gICAgICAgaXNTZXQoYW5hbHlzaXMsIEJJVF9QUkVDRURJTkcgfCBCSVRfUFJFQ0VESU5HX1NJQkxJTkcpKQotICAgICAgcmV0dXJuICBmYWxzZTsKLSAgICAgIAotICAgIC8vIE9LLCBub3cgd2UgaGF2ZSB0byBjaGVjayBmb3Igc2VsZWN0PSJAKi9heGlzOjoqIiBwYXR0ZXJucywgd2hpY2ggCi0gICAgLy8gY2FuIGFsc28gY2F1c2UgZHVwbGljYXRlcyB0byBoYXBwZW4uICBCdXQgc2VsZWN0PSJheGlzKi9AOjoqIiBwYXR0ZXJucyAKLSAgICAvLyBhcmUgT0ssIGFzIGFyZSBzZWxlY3Q9IkBmb28vYXhpczo6KiIgcGF0dGVybnMuCi0gICAgLy8gVW5mb3J0dW5hdGVseSwgd2UgY2FuJ3QgZG8gdGhpcyBqdXN0IHZpYSB0aGUgYW5hbHlzaXMgYml0cy4KLSAgICAKLSAgICBpbnQgc3RlcFR5cGU7Ci0gICAgaW50IG9wc1tdID0gY29tcGlsZXIuZ2V0T3BNYXAoKTsKLSAgICBpbnQgc3RlcENvdW50ID0gMDsKLSAgICBib29sZWFuIGZvdW5kV2lsZEF0dHJpYnV0ZSA9IGZhbHNlOwotICAgIAotICAgIC8vIFN0ZXBzIHRoYXQgY2FuIHRyYXZlcnNlIGFueXRoaW5nIG90aGVyIHRoYW4gZG93biBhIAotICAgIC8vIHN1YnRyZWUgb3IgdGhhdCBjYW4gcHJvZHVjZSBkdXBsaWNhdGVzIHdoZW4gdXNlZCBpbiAKLSAgICAvLyBjb21ib25hdGlvbiBhcmUgY291bnRlZCB3aXRoIHRoaXMgdmFyaWFibGUuCi0gICAgaW50IHBvdGVudGlhbER1cGxpY2F0ZU1ha2luZ1N0ZXBDb3VudCA9IDA7Ci0gICAgCi0gICAgd2hpbGUgKE9wQ29kZXMuRU5ET1AgIT0gKHN0ZXBUeXBlID0gb3BzW3N0ZXBPcENvZGVQb3NdKSkKLSAgICB7ICAgICAgICAKLSAgICAgIHN0ZXBDb3VudCsrOwotICAgICAgICAKLSAgICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgICB7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BVFRSSUJVVEUgOgotICAgICAgICBpZihmb3VuZFdpbGRBdHRyaWJ1dGUpIC8vIE1heWJlIG5vdCBuZWVkZWQsIGJ1dCBiZSBzYWZlLgotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgCi0gICAgICAgIC8vIFRoaXMgZG9lc24ndCBzZWVtIHRvIHdvcmsgYXMgYSB0ZXN0IGZvciB3aWxkIGNhcmQuICBIbXBoLgotICAgICAgICAvLyBpbnQgbm9kZVRlc3RUeXBlID0gY29tcGlsZXIuZ2V0U3RlcFRlc3RUeXBlKHN0ZXBPcENvZGVQb3MpOyAgCi0gICAgICAgIAotICAgICAgICBTdHJpbmcgbG9jYWxOYW1lID0gY29tcGlsZXIuZ2V0U3RlcExvY2FsTmFtZShzdGVwT3BDb2RlUG9zKTsKLSAgICAgICAgLy8gU3lzdGVtLmVyci5wcmludGxuKCJsb2NhbE5hbWU6ICIrbG9jYWxOYW1lKTsKLSAgICAgICAgaWYobG9jYWxOYW1lLmVxdWFscygiKiIpKQotICAgICAgICB7Ci0gICAgICAgICAgZm91bmRXaWxkQXR0cmlidXRlID0gdHJ1ZTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0ZPTExPV0lORyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fUFJFQ0VESU5HIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1BSRUNFRElOR19TSUJMSU5HUyA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9QQVJFTlQgOgotICAgICAgY2FzZSBPcENvZGVzLk9QX1ZBUklBQkxFIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgICAgY2FzZSBPcENvZGVzLk9QX0dST1VQIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BTkNFU1RPUlMgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEYgOiAgICAgIAotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FOWV9BTkNFU1RPUiA6Ci0gICAgICBjYXNlIE9wQ29kZXMuTUFUQ0hfSU1NRURJQVRFX0FOQ0VTVE9SIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0RFU0NFTkRBTlRTX09SX1NFTEYgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fREVTQ0VOREFOVFMgOgotICAgICAgICBpZihwb3RlbnRpYWxEdXBsaWNhdGVNYWtpbmdTdGVwQ291bnQgPiAwKQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICBwb3RlbnRpYWxEdXBsaWNhdGVNYWtpbmdTdGVwQ291bnQrKzsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX1JPT1QgOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQ0hJTERSRU4gOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fU0VMRiA6Ci0gICAgICAgIGlmKGZvdW5kV2lsZEF0dHJpYnV0ZSkKLSAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgIGJyZWFrOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX05VTExfRVJST1JfSEFORExFUiwgbmV3IE9iamVjdFtde0ludGVnZXIudG9TdHJpbmcoc3RlcFR5cGUpfSkpOyAvLyJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogIgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsgc3RlcFR5cGUpOwotICAgICAgfQotCi0gICAgICBpbnQgbmV4dFN0ZXBPcENvZGVQb3MgPSBjb21waWxlci5nZXROZXh0U3RlcFBvcyhzdGVwT3BDb2RlUG9zKTsKLQotICAgICAgaWYgKG5leHRTdGVwT3BDb2RlUG9zIDwgMCkKLSAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgIAotICAgICAgc3RlcE9wQ29kZVBvcyA9IG5leHRTdGVwT3BDb2RlUG9zOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0gIAotICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNPbmVTdGVwKGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiAoYW5hbHlzaXMgJiBCSVRTX0NPVU5UKSA9PSAweDAwMDAwMDAxOwotICB9Ci0KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0U3RlcENvdW50KGludCBhbmFseXNpcykKLSAgewotICAgIHJldHVybiAoYW5hbHlzaXMgJiBCSVRTX0NPVU5UKTsKLSAgfQotCi0gIC8qKgotICAgKiBGaXJzdCA4IGJpdHMgYXJlIHRoZSBudW1iZXIgb2YgdG9wLWxldmVsIGxvY2F0aW9uIHN0ZXBzLiAgSG9wZWZ1bGx5Ci0gICAqICB0aGVyZSB3aWxsIG5ldmVyIGJlIG1vcmUgdGhhdCAyNTUgbG9jYXRpb24gc3RlcHMhISEKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVFNfQ09VTlQgPSAweDAwMDAwMEZGOwotCi0gIC8qKiA0IGJpdHMgYXJlIHJlc2VydmVkIGZvciBmdXR1cmUgdXNlLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRTX1JFU0VSVkVEID0gMHgwMDAwMEYwMDsKLQotICAvKiogQml0IGlzIG9uIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGEgdG9wLWxldmVsIHByZWRpY2F0ZS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX1BSRURJQ0FURSA9ICgweDAwMDAxMDAwKTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGFuIGFuY2VzdG9yIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9BTkNFU1RPUiA9ICgweDAwMDAxMDAwIDw8IDEpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYW4gYW5jZXN0b3Itb3Itc2VsZiBzdGVwLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfQU5DRVNUT1JfT1JfU0VMRiA9ICgweDAwMDAxMDAwIDw8IDIpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYW4gYXR0cmlidXRlIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9BVFRSSUJVVEUgPSAoMHgwMDAwMTAwMCA8PCAzKTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgY2hpbGQgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0NISUxEID0gKDB4MDAwMDEwMDAgPDwgNCk7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhIGRlc2NlbmRhbnQgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX0RFU0NFTkRBTlQgPSAoMHgwMDAwMTAwMCA8PCA1KTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgZGVzY2VuZGFudC1vci1zZWxmIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9ERVNDRU5EQU5UX09SX1NFTEYgPSAoMHgwMDAwMTAwMCA8PCA2KTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgZm9sbG93aW5nIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9GT0xMT1dJTkcgPSAoMHgwMDAwMTAwMCA8PCA3KTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgZm9sbG93aW5nLXNpYmlsaW5nIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9GT0xMT1dJTkdfU0lCTElORyA9ICgweDAwMDAxMDAwIDw8IDgpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBuYW1lc3BhY2Ugc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX05BTUVTUEFDRSA9ICgweDAwMDAxMDAwIDw8IDkpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSBwYXJlbnQgc3RlcC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQklUX1BBUkVOVCA9ICgweDAwMDAxMDAwIDw8IDEwKTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgcHJlY2VkaW5nIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9QUkVDRURJTkcgPSAoMHgwMDAwMTAwMCA8PCAxMSk7Ci0KLSAgLyoqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhIHByZWNlZGluZy1zaWJsaW5nIHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9QUkVDRURJTkdfU0lCTElORyA9ICgweDAwMDAxMDAwIDw8IDEyKTsKLQotICAvKiogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgc2VsZiBzdGVwLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfU0VMRiA9ICgweDAwMDAxMDAwIDw8IDEzKTsKLQotICAvKioKLSAgICogQml0IGlzIG9uIGlmIGFueSBvZiB0aGUgd2Fsa2VycyBjb250YWluIGEgZmlsdGVyIChpLmUuIGlkKCksIGV4dGVuc2lvbgotICAgKiAgZnVuY3Rpb24sIGV0Yy4pIHN0ZXAuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRfRklMVEVSID0gKDB4MDAwMDEwMDAgPDwgMTQpOwotCi0gIC8qKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNvbnRhaW4gYSByb290IHN0ZXAuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9ST09UID0gKDB4MDAwMDEwMDAgPDwgMTUpOwotCi0gIC8qKgotICAgKiBJZiBhbnkgb2YgdGhlc2UgYml0cyBhcmUgb24sIHRoZSBleHByZXNzaW9uIG1heSBsaWtlbHkgdHJhdmVyc2Ugb3V0c2lkZQotICAgKiAgdGhlIGdpdmVuIHN1YnRyZWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCSVRNQVNLX1RSQVZFUlNFU19PVVRTSURFX1NVQlRSRUUgPSAoQklUX05BTUVTUEFDRSAgLy8gPz8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJJVF9QUkVDRURJTkdfU0lCTElORwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX1BSRUNFRElORwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX0ZPTExPV0lOR19TSUJMSU5HCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfRk9MTE9XSU5HCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBCSVRfUEFSRU5UICAvLyBleGNlcHQgcGFyZW50IG9mIGF0dHJzLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX0FOQ0VTVE9SX09SX1NFTEYKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJJVF9BTkNFU1RPUgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX0ZJTFRFUgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQklUX1JPT1QpOwotCi0gIC8qKgotICAgKiBCaXQgaXMgb24gaWYgYW55IG9mIHRoZSB3YWxrZXJzIGNhbiBnbyBiYWNrd2FyZHMgaW4gZG9jdW1lbnQKLSAgICogIG9yZGVyIGZyb20gdGhlIGNvbnRleHQgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9CQUNLV0FSRFNfU0VMRiA9ICgweDAwMDAxMDAwIDw8IDE2KTsKLQotICAvKiogRm91bmQgIi8vZm9vIiBwYXR0ZXJuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9BTllfREVTQ0VOREFOVF9GUk9NX1JPT1QgPSAoMHgwMDAwMTAwMCA8PCAxNyk7Ci0KLSAgLyoqCi0gICAqIEJpdCBpcyBvbiBpZiBhbnkgb2YgdGhlIHdhbGtlcnMgY29udGFpbiBhbiBub2RlKCkgdGVzdC4gIFRoaXMgaXMKLSAgICogIHJlYWxseSBvbmx5IHVzZWZ1bCBpZiB0aGUgY291bnQgaXMgMS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9OT0RFVEVTVF9BTlkgPSAoMHgwMDAwMTAwMCA8PCAxOCk7Ci0KLSAgLy8gY2FuJ3QgZ28gaGlnaGVyIHRoYW4gMTghCi0KLSAgLyoqIEJpdCBpcyBvbiBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIG1hdGNoIHBhdHRlcm4uICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJJVF9NQVRDSF9QQVRURVJOID0gKDB4MDAwMDEwMDAgPDwgMTkpOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9XYWxraW5nSXRlcmF0b3IuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvV2Fsa2luZ0l0ZXJhdG9yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1NjE4OWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9XYWxraW5nSXRlcmF0b3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3MiArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguYXhlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTU1hbmFnZXI7Ci0KLS8vIFhhbGFuIGltcG9ydHMKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5PcE1hcDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuT3BDb2RlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLlBzdWVkb05hbWVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuSW50U3RhY2s7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuT2JqZWN0UG9vbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLkF4ZXNXYWxrZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5WYXJpYWJsZVN0YWNrOwotCi0vKioKLSAqIExvY2F0aW9uIHBhdGggaXRlcmF0b3IgdGhhdCB1c2VzIFdhbGtlcnMuCi0gKi8KLQotcHVibGljIGNsYXNzIFdhbGtpbmdJdGVyYXRvciBleHRlbmRzIExvY1BhdGhJdGVyYXRvcgotewotICAvKioKLSAgICogQ3JlYXRlIGEgV2Fsa2luZ0l0ZXJhdG9yIGl0ZXJhdG9yLCBpbmNsdWRpbmcgY3JlYXRpb24KLSAgICogb2Ygc3RlcCB3YWxrZXJzIGZyb20gdGhlIG9wY29kZSBsaXN0LCBhbmQgY2FsbCBiYWNrCi0gICAqIGludG8gdGhlIENvbXBpbGVyIHRvIGNyZWF0ZSBwcmVkaWNhdGUgZXhwcmVzc2lvbnMuCi0gICAqCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgQ29tcGlsZXIgd2hpY2ggaXMgY3JlYXRpbmcKLSAgICogdGhpcyBleHByZXNzaW9uLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoaXMgaXRlcmF0b3IgaW4gdGhlCi0gICAqIG9wY29kZSBsaXN0IGZyb20gdGhlIGNvbXBpbGVyLgotICAgKiBAcGFyYW0gc2hvdWxkTG9hZFdhbGtlcnMgVHJ1ZSBpZiB3YWxrZXJzIHNob3VsZCBiZQotICAgKiBsb2FkZWQsIG9yIGZhbHNlIGlmIHRoaXMgaXMgYSBkZXJpdmVkIGl0ZXJhdG9yIGFuZAotICAgKiBpdCBkb2Vzbid0IHdpc2ggdG8gbG9hZCBjaGlsZCB3YWxrZXJzLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIFdhbGtpbmdJdGVyYXRvcigKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgaW50IG9wUG9zLCBpbnQgYW5hbHlzaXMsIGJvb2xlYW4gc2hvdWxkTG9hZFdhbGtlcnMpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgc2hvdWxkTG9hZFdhbGtlcnMpOwotICAgIAotICAgIGludCBmaXJzdFN0ZXBQb3MgPSBjb21waWxlci5nZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIGlmIChzaG91bGRMb2FkV2Fsa2VycykKLSAgICB7Ci0gICAgICBtX2ZpcnN0V2Fsa2VyID0gV2Fsa2VyRmFjdG9yeS5sb2FkV2Fsa2Vycyh0aGlzLCBjb21waWxlciwgZmlyc3RTdGVwUG9zLCAwKTsKLSAgICAgIG1fbGFzdFVzZWRXYWxrZXIgPSBtX2ZpcnN0V2Fsa2VyOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhIFdhbGtpbmdJdGVyYXRvciBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBuc2NvbnRleHQgVGhlIG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGlzIGl0ZXJhdG9yLAotICAgKiBzaG91bGQgYmUgT0sgaWYgbnVsbC4KLSAgICovCi0gIHByb3RlY3RlZCBXYWxraW5nSXRlcmF0b3IoUHJlZml4UmVzb2x2ZXIgbnNjb250ZXh0KQotICB7Ci0KLSAgICBzdXBlcihuc2NvbnRleHQpOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBHZXQgYSBjbG9uZWQgV2Fsa2luZ0l0ZXJhdG9yIHRoYXQgaG9sZHMgdGhlIHNhbWUKLSAgICogcG9zaXRpb24gYXMgdGhpcyBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBBIGNsb25lIG9mIHRoaXMgaXRlcmF0b3IgdGhhdCBob2xkcyB0aGUgc2FtZSBub2RlIHBvc2l0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uCi0gIHsKLQotICAgIFdhbGtpbmdJdGVyYXRvciBjbG9uZSA9IChXYWxraW5nSXRlcmF0b3IpIHN1cGVyLmNsb25lKCk7Ci0KLSAgICAvLyAgICBjbG9uZS5tX3ZhclN0YWNrUG9zID0gdGhpcy5tX3ZhclN0YWNrUG9zOwotICAgIC8vICAgIGNsb25lLm1fdmFyU3RhY2tDb250ZXh0ID0gdGhpcy5tX3ZhclN0YWNrQ29udGV4dDsKLSAgICBpZiAobnVsbCAhPSBtX2ZpcnN0V2Fsa2VyKQotICAgIHsKLSAgICAgIGNsb25lLm1fZmlyc3RXYWxrZXIgPSBtX2ZpcnN0V2Fsa2VyLmNsb25lRGVlcChjbG9uZSwgbnVsbCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNsb25lOwotICB9Ci0gIAotICAvKioKLSAgICogUmVzZXQgdGhlIGl0ZXJhdG9yLgotICAgKi8KLSAgcHVibGljIHZvaWQgcmVzZXQoKQotICB7Ci0KLSAgICBzdXBlci5yZXNldCgpOwotCi0gICAgaWYgKG51bGwgIT0gbV9maXJzdFdhbGtlcikKLSAgICB7Ci0gICAgICBtX2xhc3RVc2VkV2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLQotICAgICAgbV9maXJzdFdhbGtlci5zZXRSb290KG1fY29udGV4dCk7Ci0gICAgfQotCi0gIH0KLSAgCi0gIC8qKgotICAgKiAgUmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXQgYW5kIGFkdmFuY2VzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogaXRlcmF0b3IgaW4gdGhlIHNldC4gQWZ0ZXIgYSBOb2RlSXRlcmF0b3IgaXMgY3JlYXRlZCwgdGhlIGZpcnN0IGNhbGwKLSAgICogdG8gbmV4dE5vZGUoKSByZXR1cm5zIHRoZSBmaXJzdCBub2RlIGluIHRoZSBzZXQuCi0gICAqIEByZXR1cm4gIFRoZSBuZXh0IDxjb2RlPk5vZGU8L2NvZGU+IGluIHRoZSBzZXQgYmVpbmcgaXRlcmF0ZWQgb3Zlciwgb3IKLSAgICogICA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gbW9yZSBtZW1iZXJzIGluIHRoYXQgc2V0LgotICAgKi8KLSAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIHsKLQotICAgIC8vIElmIHRoZSBjYWNoZSBpcyBvbiwgYW5kIHRoZSBub2RlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHRoZW4gCi0gICAgLy8ganVzdCByZXR1cm4gZnJvbSB0aGUgbGlzdC4KLSAgICBpZiAobnVsbCAhPSBtX2NhY2hlZE5vZGVzKQotICAgIHsKLSAgICAgIGlmKG1fbmV4dCA8IG1fY2FjaGVkTm9kZXMuc2l6ZSgpKQotICAgICAgewotICAgICAgICBpbnQgbmV4dCA9IG1fbGFzdEZldGNoZWQgPSBtX2N1cnJlbnRDb250ZXh0Tm9kZSAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gbV9jYWNoZWROb2Rlcy5lbGVtZW50QXQobV9uZXh0KTsKLSAgICAgIAotICAgICAgICBpbmNyZW1lbnROZXh0UG9zaXRpb24oKTsKLSAgCi0gICAgICAgIHJldHVybiBuZXh0OwotICAgICAgfQotICAgICAgZWxzZSBpZihtX2ZvdW5kTGFzdCkKLSAgICAgIHsKLSAgICAgICAgbV9sYXN0RmV0Y2hlZCA9IERUTS5OVUxMOwotICAgICAgICByZXR1cm4gRFRNLk5VTEw7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLy8gSWYgdGhlIHZhcmlhYmxlIHN0YWNrIHBvc2l0aW9uIGlzIG5vdCAtMSwgd2UnbGwgaGF2ZSB0byAKLSAgICAvLyBzZXQgb3VyIHBvc2l0aW9uIGluIHRoZSB2YXJpYWJsZSBzdGFjaywgc28gb3VyIHZhcmlhYmxlIGFjY2VzcyAKLSAgICAvLyB3aWxsIGJlIGNvcnJlY3QuICBJdGVyYXRvcnMgdGhhdCBhcmUgYXQgdGhlIHRvcCBsZXZlbCBvZiB0aGUgCi0gICAgLy8gZXhwcmVzc2lvbiBuZWVkIHRvIHJlc2V0IHRoZSB2YXJpYWJsZSBzdGFjaywgd2hpbGUgaXRlcmF0b3JzIAotICAgIC8vIGluIHByZWRpY2F0ZXMgZG8gbm90IG5lZWQgdG8sIGFuZCBzaG91bGQgbm90LCBzaW5jZSB0aGVpciBleGVjdXRpb24KLSAgICAvLyBtYXkgYmUgbXVjaCBsYXRlciB0aGFuIHRvcC1sZXZlbCBpdGVyYXRvcnMuICAKLSAgICAvLyBtX3ZhclN0YWNrUG9zIGlzIHNldCBpbiBzZXRSb290LCB3aGljaCBpcyBjYWxsZWQgCi0gICAgLy8gZnJvbSB0aGUgZXhlY3V0ZSBtZXRob2QuCi0gICAgaWYgKC0xID09IG1fc3RhY2tGcmFtZSkKLSAgICB7Ci0gICAgICBpZiAoRFRNLk5VTEwgPT0gbV9maXJzdFdhbGtlci5nZXRSb290KCkpCi0gICAgICB7Ci0gICAgICAgIHRoaXMuc2V0TmV4dFBvc2l0aW9uKDApOwotICAgICAgICBtX2ZpcnN0V2Fsa2VyLnNldFJvb3QobV9jb250ZXh0KTsKLQotICAgICAgICBtX2xhc3RVc2VkV2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuIHJldHVybk5leHROb2RlKG1fZmlyc3RXYWxrZXIubmV4dE5vZGUoKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBWYXJpYWJsZVN0YWNrIHZhcnMgPSBtX2V4ZWNDb250ZXh0LmdldFZhclN0YWNrKCk7Ci0KLSAgICAgIC8vIFRoZXNlIHRocmVlIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICBpbnQgc2F2ZWRTdGFydCA9IHZhcnMuZ2V0U3RhY2tGcmFtZSgpOwotCi0gICAgICB2YXJzLnNldFN0YWNrRnJhbWUobV9zdGFja0ZyYW1lKTsKLQotICAgICAgaWYgKERUTS5OVUxMID09IG1fZmlyc3RXYWxrZXIuZ2V0Um9vdCgpKQotICAgICAgewotICAgICAgICB0aGlzLnNldE5leHRQb3NpdGlvbigwKTsKLSAgICAgICAgbV9maXJzdFdhbGtlci5zZXRSb290KG1fY29udGV4dCk7Ci0KLSAgICAgICAgbV9sYXN0VXNlZFdhbGtlciA9IG1fZmlyc3RXYWxrZXI7Ci0gICAgICB9Ci0KLSAgICAgIGludCBuID0gcmV0dXJuTmV4dE5vZGUobV9maXJzdFdhbGtlci5uZXh0Tm9kZSgpKTsKLQotICAgICAgLy8gVGhlc2UgdHdvIHN0YXRlbWVudHMgbmVlZCB0byBiZSBjb21iaW5lZCBpbnRvIG9uZSBvcGVyYXRpb24uCi0gICAgICB2YXJzLnNldFN0YWNrRnJhbWUoc2F2ZWRTdGFydCk7Ci0KLSAgICAgIHJldHVybiBuOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBHZXQgdGhlIGhlYWQgb2YgdGhlIHdhbGtlciBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBoZWFkIG9mIHRoZSB3YWxrZXIgbGlzdCwgb3IgbnVsbAotICAgKiBpZiB0aGlzIGl0ZXJhdG9yIGRvZXMgbm90IGltcGxlbWVudCB3YWxrZXJzLgotICAgKi8KLSAgcHVibGljIGZpbmFsIEF4ZXNXYWxrZXIgZ2V0Rmlyc3RXYWxrZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fZmlyc3RXYWxrZXI7Ci0gIH0KLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFNldCB0aGUgbGFzdCB1c2VkIHdhbGtlci4KLSAgICoKLSAgICogQHBhcmFtIHdhbGtlciBUaGUgbGFzdCB1c2VkIHdhbGtlciwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBmaW5hbCB2b2lkIHNldExhc3RVc2VkV2Fsa2VyKEF4ZXNXYWxrZXIgd2Fsa2VyKQotICB7Ci0gICAgbV9sYXN0VXNlZFdhbGtlciA9IHdhbGtlcjsKLSAgfQotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogR2V0IHRoZSBsYXN0IHVzZWQgd2Fsa2VyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsYXN0IHVzZWQgd2Fsa2VyLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIGZpbmFsIEF4ZXNXYWxrZXIgZ2V0TGFzdFVzZWRXYWxrZXIoKQotICB7Ci0gICAgcmV0dXJuIG1fbGFzdFVzZWRXYWxrZXI7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiAgRGV0YWNoZXMgdGhlIGl0ZXJhdG9yIGZyb20gdGhlIHNldCB3aGljaCBpdCBpdGVyYXRlZCBvdmVyLCByZWxlYXNpbmcKLSAgICogYW55IGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFuZCBwbGFjaW5nIHRoZSBpdGVyYXRvciBpbiB0aGUgSU5WQUxJRAotICAgKiBzdGF0ZS4gQWZ0ZXI8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsIGNhbGxzIHRvCi0gICAqIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvcjxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbCByYWlzZSB0aGUKLSAgICogZXhjZXB0aW9uIElOVkFMSURfU1RBVEVfRVJSLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCkKLSAgeyAgICAKLSAgICBtX2xhc3RVc2VkV2Fsa2VyID0gbnVsbDsKLSAgICAKLSAgICAvLyBBbHdheXMgY2FsbCB0aGUgc3VwZXJjbGFzcyBkZXRhY2ggbGFzdCEKLSAgICBzdXBlci5kZXRhY2goKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUgCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0IAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdCAKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUgCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbiAKLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZCAKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgbV9wcmVkaWNhdGVJbmRleCA9IC0xOwotCi0gICAgQXhlc1dhbGtlciB3YWxrZXIgPSBtX2ZpcnN0V2Fsa2VyOwotCi0gICAgd2hpbGUgKG51bGwgIT0gd2Fsa2VyKQotICAgIHsKLSAgICAgIHdhbGtlci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgICB3YWxrZXIgPSB3YWxrZXIuZ2V0TmV4dFdhbGtlcigpOwotICAgIH0KLSAgfQotCi0gIAotICAvKiogVGhlIGxhc3QgdXNlZCBzdGVwIHdhbGtlciBpbiB0aGUgd2Fsa2VyIGxpc3QuCi0gICAqICBAc2VyaWFsICovCi0gIHByb3RlY3RlZCBBeGVzV2Fsa2VyIG1fbGFzdFVzZWRXYWxrZXI7Ci0KLSAgLyoqIFRoZSBoZWFkIG9mIHRoZSBzdGVwIHdhbGtlciBsaXN0LgotICAgKiAgQHNlcmlhbCAqLwotICBwcm90ZWN0ZWQgQXhlc1dhbGtlciBtX2ZpcnN0V2Fsa2VyOwotCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9XYWxraW5nSXRlcmF0b3JTb3J0ZWQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvV2Fsa2luZ0l0ZXJhdG9yU29ydGVkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAyODJhZTcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9XYWxraW5nSXRlcmF0b3JTb3J0ZWQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI5NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmF4ZXM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkNvbXBpbGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogTkVFRFNET0MgQ2xhc3MgV2Fsa2luZ0l0ZXJhdG9yU29ydGVkIDxuZWVkcy1jb21tZW50Lz4KLSAqLwotcHVibGljIGNsYXNzIFdhbGtpbmdJdGVyYXRvclNvcnRlZCBleHRlbmRzIFdhbGtpbmdJdGVyYXRvcgotewotCi0gIC8qKiBORUVEU0RPQyBGaWVsZCBtX2luTmF0dXJhbE9yZGVyICAgICAgICAgICovCi0gIHByb3RlY3RlZCBib29sZWFuIG1faW5OYXR1cmFsT3JkZXIgPSBmYWxzZTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgV2Fsa2luZ0l0ZXJhdG9yU29ydGVkIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIG5zY29udGV4dCBUaGUgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHRoaXMgaXRlcmF0b3IsCi0gICAqIHNob3VsZCBiZSBPSyBpZiBudWxsLgotICAgKi8KLSAgcHVibGljIFdhbGtpbmdJdGVyYXRvclNvcnRlZChQcmVmaXhSZXNvbHZlciBuc2NvbnRleHQpCi0gIHsKLSAgICBzdXBlcihuc2NvbnRleHQpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFdhbGtpbmdJdGVyYXRvclNvcnRlZCBpdGVyYXRvcldhbGtpbmdJdGVyYXRvclNvcnRlZFdhbGtpbmdJdGVyYXRvclNvcnRlZC4KLSAgICoKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBDb21waWxlciB3aGljaCBpcyBjcmVhdGluZwotICAgKiB0aGlzIGV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhpcyBpdGVyYXRvciBpbiB0aGUKLSAgICogb3Bjb2RlIGxpc3QgZnJvbSB0aGUgY29tcGlsZXIuCi0gICAqIE5FRURTRE9DIEBwYXJhbSBhbmFseXNpcwotICAgKiBAcGFyYW0gc2hvdWxkTG9hZFdhbGtlcnMgVHJ1ZSBpZiB3YWxrZXJzIHNob3VsZCBiZQotICAgKiBsb2FkZWQsIG9yIGZhbHNlIGlmIHRoaXMgaXMgYSBkZXJpdmVkIGl0ZXJhdG9yIGFuZAotICAgKiBpdCBkb2Vzbid0IHdpc2ggdG8gbG9hZCBjaGlsZCB3YWxrZXJzLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBXYWxraW5nSXRlcmF0b3JTb3J0ZWQoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIGludCBvcFBvcywgaW50IGFuYWx5c2lzLCBib29sZWFuIHNob3VsZExvYWRXYWxrZXJzKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgc3VwZXIoY29tcGlsZXIsIG9wUG9zLCBhbmFseXNpcywgc2hvdWxkTG9hZFdhbGtlcnMpOwotCi0gICAgLy90aGlzLnNldFNob3VsZENhY2hlTm9kZXModHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogTkVFRFNET0MgTWV0aG9kIGNhbkJlV2Fsa2VkSW5OYXR1cmFsRG9jT3JkZXIgCi0gICAqCi0gICAqCi0gICAqIE5FRURTRE9DIChjYW5CZVdhbGtlZEluTmF0dXJhbERvY09yZGVyKSBAcmV0dXJuCi0gICAqLwotICBib29sZWFuIGNhbkJlV2Fsa2VkSW5OYXR1cmFsRG9jT3JkZXIoKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2ZpcnN0V2Fsa2VyKQotICAgIHsKLSAgICAgIEF4ZXNXYWxrZXIgd2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLSAgICAgIGludCBwcmV2QXhpcyA9IC0xOwotICAgICAgYm9vbGVhbiBwcmV2SXNTaW1wbGVEb3duQXhpcyA9IHRydWU7Ci0KLSAgICAgIGZvcihpbnQgaSA9IDA7IG51bGwgIT0gd2Fsa2VyOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGludCBheGlzID0gd2Fsa2VyLmdldEF4aXMoKTsKLSAgICAgICAgYm9vbGVhbiBpc1NpbXBsZURvd25BeGlzID0gKChheGlzID09IEF4aXMuQ0hJTEQpCi0gICAgICAgICAgIHx8IChheGlzID09IEF4aXMuU0VMRikKLSAgICAgICAgICAgfHwgKGF4aXMgPT0gQXhpcy5ST09UKSk7Ci0gICAgICAgIGlmKHdhbGtlci5pc0RvY09yZGVyZWQoKSkKLSAgICAgICAgewotICAgICAgICAgIGlmKGlzU2ltcGxlRG93bkF4aXMpCi0gICAgICAgICAgICB3YWxrZXIgPSB3YWxrZXIuZ2V0TmV4dFdhbGtlcigpOwotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBib29sZWFuIGlzTGFzdFdhbGtlciA9IChudWxsID09IHdhbGtlci5nZXROZXh0V2Fsa2VyKCkpOwotICAgICAgICAgICAgaWYoaXNMYXN0V2Fsa2VyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICBpZih3YWxrZXIuaXNEb2NPcmRlcmVkKCkgJiYgKGF4aXMgPT0gQXhpcy5ERVNDRU5EQU5UIHx8IAotICAgICAgICAgICAgICAgICBheGlzID09IEF4aXMuREVTQ0VOREFOVE9SU0VMRiB8fCBheGlzID09IEF4aXMuREVTQ0VOREFOVFNGUk9NUk9PVAotICAgICAgICAgICAgICAgICB8fCBheGlzID09IEF4aXMuREVTQ0VOREFOVFNPUlNFTEZGUk9NUk9PVCkgfHwgKGF4aXMgPT0gQXhpcy5BVFRSSUJVVEUpKQotICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgfQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoZSBjb250ZXh0IHZhbHVlcyBmb3IgdGhpcyBleHByZXNzaW9uCi0gICAqIGFmdGVyIGl0IGlzIGNsb25lZC4KLSAgICoKLSAgICogQHBhcmFtIGV4ZWNDb250ZXh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQgZm9yIHRoaXMKLSAgICogdHJhbnNmb3JtYXRpb24uCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBjb250ZXh0Ci0gICAqIE5FRURTRE9DIEBwYXJhbSBlbnZpcm9ubWVudAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0Um9vdChpbnQgY29udGV4dCwgT2JqZWN0IGVudmlyb25tZW50KQotICB7Ci0KLSAgICBzdXBlci5zZXRSb290KGNvbnRleHQsIGVudmlyb25tZW50KTsKLQotICAgIG1faW5OYXR1cmFsT3JkZXIgPSBjYW5CZVdhbGtlZEluTmF0dXJhbERvY09yZGVyKCk7Ci0KLSAgICBpZiAoIW1faW5OYXR1cmFsT3JkZXIpCi0gICAgewotICAgICAgdGhpcy5zZXRTaG91bGRDYWNoZU5vZGVzKHRydWUpOwotCi0gICAgICAvLyBUaGlzIHNob3VsZCByZWFsbHkgYmUgZG9uZSBpbiB0aGUgc3VwZXIncyBzZXRSb290LCBidXQgaWYgSSBkbyB0aGF0IAotICAgICAgLy8gaXQgYmVjb21lcyB1bmhhcHB5IGluIHRoZSBtaW5pdGVzdC4uLiBwb3NzaWJseSBzb21ldGhpbmcgdG8gZG8gd2l0aCAKLSAgICAgIC8vIHRoZSBrZXlyZWYgaXRlcmF0b3IuICAtc2IKLSAgICAgIG1fY2FjaGVkTm9kZXMuc2V0TGFzdCgwKTsKLSAgICAgIG1fY2FjaGVkTm9kZXMucmVzZXQoKTsKLSAgICAgIG1fY2FjaGVkTm9kZXMuUmVtb3ZlQWxsTm9DbGVhcigpOwotICAgICAgc2V0TmV4dFBvc2l0aW9uKDApOwotICAgICAgbV9maXJzdFdhbGtlci5zZXRSb290KGNvbnRleHQpOwotCi0gICAgICBtX2xhc3RVc2VkV2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLQotICAgICAgaW50IG5leHROb2RlID0gRFRNLk5VTEw7Ci0gICAgICBBeGVzV2Fsa2VyIHdhbGtlciA9IGdldExhc3RVc2VkV2Fsa2VyKCk7Ci0gICAgICBYUGF0aENvbnRleHQgZXhlY0NvbnRleHQgPSAoWFBhdGhDb250ZXh0KSBlbnZpcm9ubWVudDsKLQotICAgICAgZXhlY0NvbnRleHQucHVzaEN1cnJlbnROb2RlQW5kRXhwcmVzc2lvbihjb250ZXh0LCBjb250ZXh0KTsKLQotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIGRvCi0gICAgICAgIHsKLSAgICAgICAgICB3aGlsZSAodHJ1ZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobnVsbCA9PSB3YWxrZXIpCi0gICAgICAgICAgICAgIGJyZWFrOwotCi0gICAgICAgICAgICBuZXh0Tm9kZSA9IHdhbGtlci5nZXROZXh0Tm9kZSgpOwotCi0gICAgICAgICAgICBpZiAoRFRNLk5VTEwgPT0gbmV4dE5vZGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHdhbGtlciA9IHdhbGtlci5tX3ByZXZXYWxrZXI7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlmICh3YWxrZXIuYWNjZXB0Tm9kZShuZXh0Tm9kZSkgIT0gRFRNSXRlcmF0b3IuRklMVEVSX0FDQ0VQVCkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgaWYgKG51bGwgPT0gd2Fsa2VyLm1fbmV4dFdhbGtlcikKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHNldExhc3RVc2VkV2Fsa2VyKHdhbGtlcik7Ci0KLSAgICAgICAgICAgICAgICAvLyByZXR1cm4gd2Fsa2VyLnJldHVybk5leHROb2RlKG5leHROb2RlKTsKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBBeGVzV2Fsa2VyIHByZXYgPSB3YWxrZXI7Ci0KLSAgICAgICAgICAgICAgICB3YWxrZXIgPSB3YWxrZXIubV9uZXh0V2Fsa2VyOwotCi0gICAgICAgICAgICAgICAgd2Fsa2VyLnNldFJvb3QobmV4dE5vZGUpOwotCi0gICAgICAgICAgICAgICAgd2Fsa2VyLm1fcHJldldhbGtlciA9IHByZXY7Ci0KLSAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfSAgLy8gaWYobnVsbCAhPSBuZXh0Tm9kZSkKLSAgICAgICAgICB9ICAvLyB3aGlsZShudWxsICE9IHdhbGtlcikKLQotICAgICAgICAgIGlmIChEVE0uTlVMTCAhPSBuZXh0Tm9kZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpbmNyZW1lbnROZXh0UG9zaXRpb24oKTsKLQotICAgICAgICAgICAgLy8gbV9jdXJyZW50Q29udGV4dE5vZGUgPSBuZXh0Tm9kZTsKLSAgICAgICAgICAgIG1fY2FjaGVkTm9kZXMuYWRkTm9kZUluRG9jT3JkZXIobmV4dE5vZGUsIGV4ZWNDb250ZXh0KTsKLQotICAgICAgICAgICAgd2Fsa2VyID0gZ2V0TGFzdFVzZWRXYWxrZXIoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgd2hpbGUgKERUTS5OVUxMICE9IG5leHROb2RlKTsKLSAgICAgIH0KLSAgICAgIGZpbmFsbHkKLSAgICAgIHsKLSAgICAgICAgZXhlY0NvbnRleHQucG9wQ3VycmVudE5vZGVBbmRFeHByZXNzaW9uKCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIG1fcHJldlJldHVybmVkID0gbmV4dE5vZGU7Ci0gICAgICBzZXROZXh0UG9zaXRpb24oMCk7Ci0KLSAgICAgIG1fbGFzdCA9IG1fY2FjaGVkTm9kZXMuc2l6ZSgpOwotICAgICAgbV9sYXN0RmV0Y2hlZCA9IERUTS5OVUxMOwotICAgICAgbV9jdXJyZW50Q29udGV4dE5vZGUgPSBEVE0uTlVMTDsKLSAgICAgIG1fZm91bmRMYXN0ID0gdHJ1ZTsKLSAgICB9Ci0gIH0KLQotICAvLyAgcHVibGljIGludCBuZXh0Tm9kZSgpCi0gIC8vICB7Ci0gIC8vICAgIHJldHVybiBzdXBlci5uZXh0Tm9kZSgpOwotICAvLyAgfQotCi0gIC8qKgotICAgKiBSZXNldCB0aGUgaXRlcmF0b3IuCi0gICAqLwotICBwdWJsaWMgdm9pZCByZXNldCgpCi0gIHsKLQotICAgIGlmIChtX2luTmF0dXJhbE9yZGVyKQotICAgICAgc3VwZXIucmVzZXQoKTsKLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyBzdXBlci5yZXNldCgpOwotICAgICAgLy8gbV9mb3VuZExhc3QgPSBmYWxzZTsKLSAgICAgIG1fbGFzdEZldGNoZWQgPSBEVE0uTlVMTDsKLSAgICAgIG1fbmV4dCA9IDA7Ci0KLSAgICAgIC8vIG1fbGFzdCA9IDA7Ci0gICAgICBpZiAobnVsbCAhPSBtX2ZpcnN0V2Fsa2VyKQotICAgICAgewotICAgICAgICBtX2xhc3RVc2VkV2Fsa2VyID0gbV9maXJzdFdhbGtlcjsKLQotICAgICAgICBtX2ZpcnN0V2Fsa2VyLnNldFJvb3QobV9jb250ZXh0KTsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM3NGJlMWQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw5ICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WFBhdGggTG9jYXRpb25QYXRoIHN1cHBvcnQuPC90aXRsZT4KLSAgPGJvZHk+Ci0gICAgPHA+SW1wbGVtZW50YXRpb24gb2YgWFBhdGggTG9jYXRpb25QYXRoIHN1cHBvcnQgLS0gcHJpbWFyeSBjbGFzc2VzIGFyZSAKLSAgICBMb2NQYXRoSXRlcmF0b3IgYW5kIFVuaW9uUGF0aEl0ZXJhdG9yLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9Db21waWxlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvQ29tcGlsZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTlkZWY4YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9Db21waWxlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI2NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLkFuZDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuQm9vbDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuRGl2OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5FcXVhbHM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLkd0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5HdGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLkx0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5MdGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLk1pbnVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5Nb2Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLk11bHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLk5lZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuTm90RXF1YWxzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5PcGVyYXRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLk9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5QbHVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5VbmFyeU9wZXJhdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuVmFyaWFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmNFeHRGdW5jdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy5Xcm9uZ051bWJlckFyZ3NFeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUU5hbWU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlNBWFNvdXJjZUxvY2F0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkF4aXM7Ci0KLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgY29tcGlsZXMgYW4gWFBhdGggc3RyaW5nIGV4cHJlc3Npb24gaW50byAKLSAqIGEgRXhwcmVzc2lvbiBvYmplY3QuICBUaGlzIGNsYXNzIGNvbXBpbGVzIHRoZSBzdHJpbmcgaW50byBhIHNlcXVlbmNlIAotICogb2Ygb3BlcmF0aW9uIGNvZGVzIChvcCBtYXApIGFuZCB0aGVuIGJ1aWxkcyBmcm9tIHRoYXQgaW50byBhbiBFeHByZXNzaW9uIAotICogdHJlZS4KLSAqLwotcHVibGljIGNsYXNzIENvbXBpbGVyIGV4dGVuZHMgT3BNYXAKLXsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgQ29tcGlsZXIgb2JqZWN0IHdpdGggYSBzcGVjaWZpYyBFcnJvckxpc3RlbmVyIGFuZCAKLSAgICogU291cmNlTG9jYXRvciB3aGVyZSB0aGUgZXhwcmVzc2lvbiBpcyBsb2NhdGVkLgotICAgKgotICAgKiBAcGFyYW0gZXJyb3JIYW5kbGVyIEVycm9yIGxpc3RlbmVyIHdoZXJlIG1lc3NhZ2VzIHdpbGwgYmUgc2VudCwgb3IgbnVsbCAKLSAgICogICAgICAgICAgICAgICAgICAgICBpZiBtZXNzYWdlcyBzaG91bGQgYmUgc2VudCB0byBTeXN0ZW0gZXJyLgotICAgKiBAcGFyYW0gbG9jYXRvciBUaGUgbG9jYXRpb24gb2JqZWN0IHdoZXJlIHRoZSBleHByZXNzaW9uIGxpdmVzLCB3aGljaCAKLSAgICogICAgICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqLwotICBwdWJsaWMgQ29tcGlsZXIoRXJyb3JMaXN0ZW5lciBlcnJvckhhbmRsZXIsIFNvdXJjZUxvY2F0b3IgbG9jYXRvcikKLSAgewotICAgIG1fZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyOwotICAgIGlmKG51bGwgIT0gbG9jYXRvcikKLSAgICB7Ci0gICAgICBTQVhTb3VyY2VMb2NhdG9yIHNzbCA9IG5ldyBTQVhTb3VyY2VMb2NhdG9yKCk7Ci0gICAgICBzc2wuc2V0Q29sdW1uTnVtYmVyKGxvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgICAgc3NsLnNldExpbmVOdW1iZXIobG9jYXRvci5nZXRMaW5lTnVtYmVyKCkpOwotICAgICAgc3NsLnNldFB1YmxpY0lkKGxvY2F0b3IuZ2V0UHVibGljSWQoKSk7Ci0gICAgICBzc2wuc2V0U3lzdGVtSWQobG9jYXRvci5nZXRTeXN0ZW1JZCgpKTsKLSAgICAgIG1fbG9jYXRvciA9IHNzbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgQ29tcGlsZXIgaW5zdGFuY2UgdGhhdCBoYXMgYSBudWxsIGVycm9yIGxpc3RlbmVyIGFuZCBhIAotICAgKiBudWxsIHNvdXJjZSBsb2NhdG9yLgotICAgKi8KLSAgcHVibGljIENvbXBpbGVyKCkKLSAgewotICAgIG1fZXJyb3JIYW5kbGVyID0gbnVsbDsKLSAgICBtX2xvY2F0b3IgPSBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBFeGVjdXRlIHRoZSBYUGF0aCBvYmplY3QgZnJvbSBhIGdpdmVuIG9wY29kZSBwb3NpdGlvbi4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHBhcmFtIGNvbnRleHQgVGhlIGN1cnJlbnQgc291cmNlIHRyZWUgY29udGV4dCBub2RlLgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIHhwYXRoLm1fb3BNYXAgYXJyYXkuCi0gICAqIEBwYXJhbSBjYWxsYmFjayBJbnRlcmZhY2UgdGhhdCBpbXBsZW1lbnRzIHRoZSBwcm9jZXNzTG9jYXRlZE5vZGUgbWV0aG9kLgotICAgKiBAcGFyYW0gY2FsbGJhY2tJbmZvIE9iamVjdCB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBwcm9jZXNzTG9jYXRlZE5vZGUgbWV0aG9kLgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIFhQYXRoLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgc3ludGF4IG9yIG90aGVyIGVycm9yLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gY29tcGlsZShpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3AgPSBtX29wTWFwW29wUG9zXTsKLQotICAgIEV4cHJlc3Npb24gZXhwciA9IG51bGw7Ci0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKGdldFBhdHRlcm5TdHJpbmcoKSsib3A6ICIrb3ApOwotICAgIHN3aXRjaCAob3ApCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5PUF9YUEFUSCA6Ci0gICAgICBleHByID0gY29tcGlsZShvcFBvcyArIDIpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfT1IgOgotICAgICAgZXhwciA9IG9yKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0FORCA6Ci0gICAgICBleHByID0gYW5kKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX05PVEVRVUFMUyA6Ci0gICAgICBleHByID0gbm90ZXF1YWxzKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0VRVUFMUyA6Ci0gICAgICBleHByID0gZXF1YWxzKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0xURSA6Ci0gICAgICBleHByID0gbHRlKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0xUIDoKLSAgICAgIGV4cHIgPSBsdChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9HVEUgOgotICAgICAgZXhwciA9IGd0ZShvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9HVCA6Ci0gICAgICBleHByID0gZ3Qob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfUExVUyA6Ci0gICAgICBleHByID0gcGx1cyhvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9NSU5VUyA6Ci0gICAgICBleHByID0gbWludXMob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTVVMVCA6Ci0gICAgICBleHByID0gbXVsdChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9ESVYgOgotICAgICAgZXhwciA9IGRpdihvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9NT0QgOgotICAgICAgZXhwciA9IG1vZChvcFBvcyk7IGJyZWFrOwotLy8gICAgY2FzZSBPcENvZGVzLk9QX1FVTyA6Ci0vLyAgICAgIGV4cHIgPSBxdW8ob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTkVHIDoKLSAgICAgIGV4cHIgPSBuZWcob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfU1RSSU5HIDoKLSAgICAgIGV4cHIgPSBzdHJpbmcob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfQk9PTCA6Ci0gICAgICBleHByID0gYm9vbChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9OVU1CRVIgOgotICAgICAgZXhwciA9IG51bWJlcihvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9VTklPTiA6Ci0gICAgICBleHByID0gdW5pb24ob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfTElURVJBTCA6Ci0gICAgICBleHByID0gbGl0ZXJhbChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9WQVJJQUJMRSA6Ci0gICAgICBleHByID0gdmFyaWFibGUob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfR1JPVVAgOgotICAgICAgZXhwciA9IGdyb3VwKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX05VTUJFUkxJVCA6Ci0gICAgICBleHByID0gbnVtYmVybGl0KG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX0FSR1VNRU5UIDoKLSAgICAgIGV4cHIgPSBhcmcob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfRVhURlVOQ1RJT04gOgotICAgICAgZXhwciA9IGNvbXBpbGVFeHRlbnNpb24ob3BQb3MpOyBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuT1BfRlVOQ1RJT04gOgotICAgICAgZXhwciA9IGNvbXBpbGVGdW5jdGlvbihvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEggOgotICAgICAgZXhwciA9IGxvY2F0aW9uUGF0aChvcFBvcyk7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9QUkVESUNBVEUgOgotICAgICAgZXhwciA9IG51bGw7IGJyZWFrOyAgLy8gc2hvdWxkIG5ldmVyIGhpdCB0aGlzIGhlcmUuCi0gICAgY2FzZSBPcENvZGVzLk9QX01BVENIUEFUVEVSTiA6Ci0gICAgICBleHByID0gbWF0Y2hQYXR0ZXJuKG9wUG9zICsgMik7IGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEhQQVRURVJOIDoKLSAgICAgIGV4cHIgPSBsb2NhdGlvblBhdGhQYXR0ZXJuKG9wUG9zKTsgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk9QX1FVTzoKLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9PUENPREUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117ICJxdW8iIH0pOyAgLy8iRVJST1IhIFVua25vd24gb3AgY29kZTogIittX29wTWFwW29wUG9zXSk7Ci0gICAgICBicmVhazsKLSAgICBkZWZhdWx0IDoKLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9PUENPREUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IEludGVnZXIudG9TdHJpbmcobV9vcE1hcFtvcFBvc10pIH0pOyAgLy8iRVJST1IhIFVua25vd24gb3AgY29kZTogIittX29wTWFwW29wUG9zXSk7Ci0gICAgfQotICAgIGlmKG51bGwgIT0gZXhwcikKLSAgICAgIGV4cHIuc2V0U291cmNlTG9jYXRvcihtX2xvY2F0b3IpOwotCi0gICAgcmV0dXJuIGV4cHI7Ci0gIH0KLQotICAvKioKLSAgICogQm90dGxlLW5lY2sgY29tcGlsYXRpb24gb2YgYW4gb3BlcmF0aW9uIHdpdGggbGVmdCBhbmQgcmlnaHQgb3BlcmFuZHMuCi0gICAqCi0gICAqIEBwYXJhbSBvcGVyYXRpb24gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHBhcmVudCBvcGVyYXRpb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgb3AgbWFwIHBvc2l0aW9uIG9mIHRoZSBwYXJlbnQgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLk9wZXJhdGlvbn0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBzeW50YXggb3Igb3RoZXIgZXJyb3IuCi0gICAqLwotICBwcml2YXRlIEV4cHJlc3Npb24gY29tcGlsZU9wZXJhdGlvbihPcGVyYXRpb24gb3BlcmF0aW9uLCBpbnQgb3BQb3MpCi0gICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBsZWZ0UG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0gICAgaW50IHJpZ2h0UG9zID0gZ2V0TmV4dE9wUG9zKGxlZnRQb3MpOwotCi0gICAgb3BlcmF0aW9uLnNldExlZnRSaWdodChjb21waWxlKGxlZnRQb3MpLCBjb21waWxlKHJpZ2h0UG9zKSk7Ci0KLSAgICByZXR1cm4gb3BlcmF0aW9uOwotICB9Ci0KLSAgLyoqCi0gICAqIEJvdHRsZS1uZWNrIGNvbXBpbGF0aW9uIG9mIGEgdW5hcnkgb3BlcmF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gdW5hcnkgVGhlIHBhcmVudCB1bmFyeSBvcGVyYXRpb24uCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gaW4gdGhlIG9wIG1hcCBvZiB0aGUgcGFyZW50IG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdW5hcnkgYXJndW1lbnQuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgc3ludGF4IG9yIG90aGVyIGVycm9yIG9jY3Vycy4KLSAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbiBjb21waWxlVW5hcnkoVW5hcnlPcGVyYXRpb24gdW5hcnksIGludCBvcFBvcykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHJpZ2h0UG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICB1bmFyeS5zZXRSaWdodChjb21waWxlKHJpZ2h0UG9zKSk7Ci0KLSAgICByZXR1cm4gdW5hcnk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhbiAnb3InIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5Pcn0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBvcihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE9yKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGFuICdhbmQnIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5BbmR9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gYW5kKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgQW5kKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJyE9JyBvcGVyYXRpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuTm90RXF1YWxzfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG5vdGVxdWFscyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE5vdEVxdWFscygpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICc9JyBvcGVyYXRpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuRXF1YWxzfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGVxdWFscyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IEVxdWFscygpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICc8PScgb3BlcmF0aW9uLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLkx0ZX0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBsdGUoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBMdGUoKSwgb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSAnPCcgb3BlcmF0aW9uLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLkx0fSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGx0KGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgTHQoKSwgb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSAnPj0nIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5HdGV9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gZ3RlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZU9wZXJhdGlvbihuZXcgR3RlKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJz4nIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5HdH0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBndChpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IEd0KCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJysnIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5QbHVzfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHBsdXMoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBQbHVzKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJy0nIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5NaW51c30gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBtaW51cyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE1pbnVzKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJyonIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5NdWx0fSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG11bHQoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBNdWx0KCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJ2Rpdicgb3BlcmF0aW9uLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLkRpdn0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBkaXYoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBEaXYoKSwgb3BQb3MpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSAnbW9kJyBvcGVyYXRpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuTW9kfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG1vZChpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVPcGVyYXRpb24obmV3IE1vZCgpLCBvcFBvcyk7Ci0gIH0KLQotICAvKgotICAgKiBDb21waWxlIGEgJ3F1bycgb3BlcmF0aW9uLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLlF1b30gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotLy8gIHByb3RlY3RlZCBFeHByZXNzaW9uIHF1byhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotLy8gIHsKLS8vICAgIHJldHVybiBjb21waWxlT3BlcmF0aW9uKG5ldyBRdW8oKSwgb3BQb3MpOwotLy8gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIHVuYXJ5ICctJyBvcGVyYXRpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuTmVnfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG5lZyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVVbmFyeShuZXcgTmVnKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJ3N0cmluZyguLi4pJyBvcGVyYXRpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuU3RyaW5nfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHN0cmluZyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVVbmFyeShuZXcgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLlN0cmluZygpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhICdib29sZWFuKC4uLiknIG9wZXJhdGlvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5Cb29sfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIGJvb2woaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBjb21waWxlVW5hcnkobmV3IG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9ucy5Cb29sKCksIG9wUG9zKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgJ251bWJlciguLi4pJyBvcGVyYXRpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMuTnVtYmVyfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG51bWJlcihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBpbGVVbmFyeShuZXcgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLk51bWJlcigpLCBvcFBvcyk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGxpdGVyYWwgc3RyaW5nIHZhbHVlLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmd9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbGl0ZXJhbChpbnQgb3BQb3MpCi0gIHsKLQotICAgIG9wUG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICByZXR1cm4gKFhTdHJpbmcpIG1fdG9rZW5RdWV1ZVttX29wTWFwW29wUG9zXV07Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIGxpdGVyYWwgbnVtYmVyIHZhbHVlLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXJ9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbnVtYmVybGl0KGludCBvcFBvcykKLSAgewotCi0gICAgb3BQb3MgPSBnZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIHJldHVybiAoWE51bWJlcikgbV90b2tlblF1ZXVlW21fb3BNYXBbb3BQb3NdXTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgdmFyaWFibGUgcmVmZXJlbmNlLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zLlZhcmlhYmxlfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHZhcmlhYmxlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFZhcmlhYmxlIHZhciA9IG5ldyBWYXJpYWJsZSgpOwotCi0gICAgb3BQb3MgPSBnZXRGaXJzdENoaWxkUG9zKG9wUG9zKTsKLQotICAgIGludCBuc1BvcyA9IG1fb3BNYXBbb3BQb3NdOwotICAgIGphdmEubGFuZy5TdHJpbmcgbmFtZXNwYWNlIAotICAgICAgPSAoT3BDb2Rlcy5FTVBUWSA9PSBuc1BvcykgPyBudWxsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChqYXZhLmxhbmcuU3RyaW5nKSBtX3Rva2VuUXVldWVbbnNQb3NdOwotICAgIGphdmEubGFuZy5TdHJpbmcgbG9jYWxuYW1lIAotICAgICAgPSAoamF2YS5sYW5nLlN0cmluZykgbV90b2tlblF1ZXVlW21fb3BNYXBbb3BQb3MrMV1dOwotICAgIFFOYW1lIHFuYW1lID0gbmV3IFFOYW1lKG5hbWVzcGFjZSwgbG9jYWxuYW1lKTsKLQotICAgIHZhci5zZXRRTmFtZShxbmFtZSk7Ci0KLSAgICByZXR1cm4gdmFyOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYW4gZXhwcmVzc2lvbiBncm91cC4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8gdGhlIGNvbnRhaW5lZCBleHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gZ3JvdXAoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8tb3AKLSAgICByZXR1cm4gY29tcGlsZShvcFBvcyArIDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSBmdW5jdGlvbiBhcmd1bWVudC4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8gdGhlIGFyZ3VtZW50IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBhcmcoaW50IG9wUG9zKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gbm8tb3AKLSAgICByZXR1cm4gY29tcGlsZShvcFBvcyArIDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYSBsb2NhdGlvbiBwYXRoIHVuaW9uLiBUaGUgVW5pb25QYXRoSXRlcmF0b3IgaXRzZWxmIG1heSBjcmVhdGUKLSAgICoge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguYXhlcy5Mb2NQYXRoSXRlcmF0b3J9IGNoaWxkcmVuLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5heGVzLlVuaW9uUGF0aEl0ZXJhdG9yfSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIHVuaW9uKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBsb2NQYXRoRGVwdGgrKzsKLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXR1cm4gbmV3IFVuaW9uUGF0aEl0ZXJhdG9yKHRoaXMsIG9wUG9zKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGxvY1BhdGhEZXB0aC0tOwotICAgIH0KLSAgfQotICAKLSAgcHJpdmF0ZSBpbnQgbG9jUGF0aERlcHRoID0gLTE7Ci0gIAotICAvKioKLSAgICogR2V0IHRoZSBsZXZlbCBvZiB0aGUgbG9jYXRpb24gcGF0aCBvciB1bmlvbiBiZWluZyBjb25zdHJ1Y3RlZC4gIAotICAgKiBAcmV0dXJuIDAgaWYgaXQgaXMgYSB0b3AtbGV2ZWwgcGF0aC4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0TG9jYXRpb25QYXRoRGVwdGgoKQotICB7Ci0gICAgcmV0dXJuIGxvY1BhdGhEZXB0aDsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgbG9jYXRpb24gcGF0aC4gIFRoZSBMb2NQYXRoSXRlcmF0b3IgaXRzZWxmIG1heSBjcmVhdGUKLSAgICoge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguYXhlcy5BeGVzV2Fsa2VyfSBjaGlsZHJlbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguYXhlcy5Mb2NQYXRoSXRlcmF0b3J9IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gbG9jYXRpb25QYXRoKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBsb2NQYXRoRGVwdGgrKzsKLSAgICB0cnkKLSAgICB7Ci0gICAgICBEVE1JdGVyYXRvciBpdGVyID0gV2Fsa2VyRmFjdG9yeS5uZXdEVE1JdGVyYXRvcih0aGlzLCBvcFBvcywgKGxvY1BhdGhEZXB0aCA9PSAwKSk7Ci0gICAgICByZXR1cm4gKEV4cHJlc3Npb24paXRlcjsgLy8gY2FzdCBPSywgSSBndWVzcy4KLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIGxvY1BhdGhEZXB0aC0tOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgbG9jYXRpb24gc3RlcCBwcmVkaWNhdGUgZXhwcmVzc2lvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY29udGFpbmVkIHByZWRpY2F0ZSBleHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gcHJlZGljYXRlKGludCBvcFBvcykgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGlsZShvcFBvcyArIDIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYW4gZW50aXJlIG1hdGNoIHBhdHRlcm4gZXhwcmVzc2lvbi4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuVW5pb25QYXR0ZXJufSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG1hdGNoUGF0dGVybihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBGaXJzdCwgY291bnQuLi4KLSAgICBpbnQgbmV4dE9wUG9zID0gb3BQb3M7Ci0gICAgaW50IGk7Ci0KLSAgICBmb3IgKGkgPSAwOyBtX29wTWFwW25leHRPcFBvc10gPT0gT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEhQQVRURVJOOyBpKyspCi0gICAgewotICAgICAgbmV4dE9wUG9zID0gZ2V0TmV4dE9wUG9zKG5leHRPcFBvcyk7Ci0gICAgfQotCi0gICAgaWYgKGkgPT0gMSkKLSAgICAgIHJldHVybiBjb21waWxlKG9wUG9zKTsKLQotICAgIFVuaW9uUGF0dGVybiB1cCA9IG5ldyBVbmlvblBhdHRlcm4oKTsKLSAgICBTdGVwUGF0dGVybltdIHBhdHRlcm5zID0gbmV3IFN0ZXBQYXR0ZXJuW2ldOwotCi0gICAgZm9yIChpID0gMDsgbV9vcE1hcFtvcFBvc10gPT0gT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEhQQVRURVJOOyBpKyspCi0gICAgewotICAgICAgbmV4dE9wUG9zID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLSAgICAgIHBhdHRlcm5zW2ldID0gKFN0ZXBQYXR0ZXJuKSBjb21waWxlKG9wUG9zKTsKLSAgICAgIG9wUG9zID0gbmV4dE9wUG9zOwotICAgIH0KLQotICAgIHVwLnNldFBhdHRlcm5zKHBhdHRlcm5zKTsKLQotICAgIHJldHVybiB1cDsKLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgbG9jYXRpb24gbWF0Y2ggcGF0dGVybiB1bml0IGV4cHJlc3Npb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLlN0ZXBQYXR0ZXJufSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uIGxvY2F0aW9uUGF0aFBhdHRlcm4oaW50IG9wUG9zKQotICAgICAgICAgIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotCi0gICAgcmV0dXJuIHN0ZXBQYXR0ZXJuKG9wUG9zLCAwLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgYSB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9IGJpdCBzZXQgdGhhdCB0ZWxscyB3aGF0IAotICAgKiB0byBzaG93IGZvciBhIGdpdmVuIG5vZGUgdGVzdC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIHRoZSBvcCBtYXAgcG9zaXRpb24gZm9yIHRoZSBsb2NhdGlvbiBzdGVwLgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0gYml0IHNldCB0aGF0IHRlbGxzIHdoYXQgCi0gICAqICAgICAgICAgdG8gc2hvdyBmb3IgYSBnaXZlbiBub2RlIHRlc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFdoYXRUb1Nob3coaW50IG9wUG9zKQotICB7Ci0KLSAgICBpbnQgYXhlc1R5cGUgPSBnZXRPcChvcFBvcyk7Ci0gICAgaW50IHRlc3RUeXBlID0gZ2V0T3Aob3BQb3MgKyAzKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigidGVzdFR5cGU6ICIrdGVzdFR5cGUpOwotICAgIHN3aXRjaCAodGVzdFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9DT01NRU5UIDoKLSAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19DT01NRU5UOwotICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9URVhUIDoKLS8vICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX1RFWFQgfCBEVE1GaWx0ZXIuU0hPV19DT01NRU5UOwotICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX1RFWFQgfCBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OIDsKLSAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUEkgOgotICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX1BST0NFU1NJTkdfSU5TVFJVQ1RJT047Ci0gICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX05PREUgOgotLy8gICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgICAgc3dpdGNoIChheGVzVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRToKLSAgICAgICAgcmV0dXJuIERUTUZpbHRlci5TSE9XX05BTUVTUEFDRTsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX0FUVFJJQlVURVMgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0FUVFJJQlVURSA6Ci0gICAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEU7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9TRUxGOgotICAgICAgY2FzZSBPcENvZGVzLkZST01fQU5DRVNUT1JTX09SX1NFTEY6Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGOgotICAgICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgICAgZGVmYXVsdDoKLSAgICAgICAgaWYgKGdldE9wKDApID09IE9wQ29kZXMuT1BfTUFUQ0hQQVRURVJOKQotICAgICAgICAgIHJldHVybiB+RFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFCi0gICAgICAgICAgICAgICAgICAmIH5EVE1GaWx0ZXIuU0hPV19ET0NVTUVOVAotICAgICAgICAgICAgICAgICAgJiB+RFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQ7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgICByZXR1cm4gfkRUTUZpbHRlci5TSE9XX0FUVFJJQlVURTsKLSAgICAgIH0KLSAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUk9PVCA6Ci0gICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQgfCBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVDsKLSAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfRlVOQ1RFU1QgOgotICAgICAgcmV0dXJuIE5vZGVUZXN0LlNIT1dfQllGVU5DVElPTjsKLSAgICBjYXNlIE9wQ29kZXMuTk9ERU5BTUUgOgotICAgICAgc3dpdGNoIChheGVzVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSA6Ci0gICAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0U7Ci0gICAgICBjYXNlIE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BVFRSSUJVVEUgOgotICAgICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFOwotCi0gICAgICAvLyBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1IgOgotICAgICAgY2FzZSBPcENvZGVzLk1BVENIX0lNTUVESUFURV9BTkNFU1RPUiA6Ci0gICAgICAgIHJldHVybiBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UOwotCi0gICAgICAvLyBicmVhazsKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfRUxFTUVOVDsKLSAgICAgIH0KLSAgICBkZWZhdWx0IDoKLSAgICAgIC8vIFN5c3RlbS5lcnIucHJpbnRsbigiV2Ugc2hvdWxkIG5ldmVyIHJlYWNoIGhlcmUuIik7Ci0gICAgICByZXR1cm4gRFRNRmlsdGVyLlNIT1dfQUxMOwotICAgIH0KLSAgfQotICAKLXByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKLQotICAvKioKLSAgICogQ29tcGlsZSBhIHN0ZXAgcGF0dGVybiB1bml0IGV4cHJlc3Npb24sIHVzZWQgZm9yIGJvdGggbG9jYXRpb24gcGF0aHMgCi0gICAqIGFuZCBtYXRjaCBwYXR0ZXJucy4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICogQHBhcmFtIHN0ZXBDb3VudCBUaGUgbnVtYmVyIG9mIHN0ZXBzIHRvIGV4cGVjdC4KLSAgICogQHBhcmFtIGFuY2VzdG9yUGF0dGVybiBUaGUgb3duaW5nIFN0ZXBQYXR0ZXJuLCB3aGljaCBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiByZWZlcmVuY2UgdG8ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuU3RlcFBhdHRlcm59IGluc3RhbmNlLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgZXJyb3Igb2NjdXJzIGNyZWF0aW5nIHRoZSBFeHByZXNzaW9uLgotICAgKi8KLSAgcHJvdGVjdGVkIFN0ZXBQYXR0ZXJuIHN0ZXBQYXR0ZXJuKAotICAgICAgICAgIGludCBvcFBvcywgaW50IHN0ZXBDb3VudCwgU3RlcFBhdHRlcm4gYW5jZXN0b3JQYXR0ZXJuKQotICAgICAgICAgICAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBzdGFydE9wUG9zID0gb3BQb3M7Ci0gICAgaW50IHN0ZXBUeXBlID0gZ2V0T3BNYXAoKVtvcFBvc107Ci0KLSAgICBpZiAoT3BDb2Rlcy5FTkRPUCA9PSBzdGVwVHlwZSkKLSAgICB7Ci0gICAgICByZXR1cm4gbnVsbDsKLSAgICB9Ci0gICAgCi0gICAgYm9vbGVhbiBhZGRNYWdpY1NlbGYgPSB0cnVlOwotCi0gICAgaW50IGVuZFN0ZXAgPSBnZXROZXh0T3BQb3Mob3BQb3MpOwotCi0gICAgLy8gaW50IG5leHRTdGVwVHlwZSA9IGdldE9wTWFwKClbZW5kU3RlcF07Ci0gICAgU3RlcFBhdHRlcm4gcGF0dGVybjsKLSAgICAKLSAgICAvLyBib29sZWFuIGlzU2ltcGxlID0gKChPcENvZGVzLkVORE9QID09IG5leHRTdGVwVHlwZSkgJiYgKHN0ZXBDb3VudCA9PSAwKSk7Ci0gICAgaW50IGFyZ0xlbjsKLQotICAgIHN3aXRjaCAoc3RlcFR5cGUpCi0gICAgewotICAgIGNhc2UgT3BDb2Rlcy5PUF9GVU5DVElPTiA6Ci0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJNQVRDSF9GVU5DVElPTjogIittX2N1cnJlbnRQYXR0ZXJuKTsgCi0gICAgICBhZGRNYWdpY1NlbGYgPSBmYWxzZTsKLSAgICAgIGFyZ0xlbiA9IG1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotICAgICAgcGF0dGVybiA9IG5ldyBGdW5jdGlvblBhdHRlcm4oY29tcGlsZUZ1bmN0aW9uKG9wUG9zKSwgQXhpcy5QQVJFTlQsIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLkZST01fUk9PVCA6Ci0gICAgICBpZihERUJVRykKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGUk9NX1JPT1QsICIrbV9jdXJyZW50UGF0dGVybik7Ci0gICAgICBhZGRNYWdpY1NlbGYgPSBmYWxzZTsKLSAgICAgIGFyZ0xlbiA9IGdldEFyZ0xlbmd0aE9mU3RlcChvcFBvcyk7Ci0gICAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3NPZlN0ZXAob3BQb3MpOwotICAgICAgcGF0dGVybiA9IG5ldyBTdGVwUGF0dGVybihEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVCB8IAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9GUkFHTUVOVCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXhpcy5QQVJFTlQsIEF4aXMuQ0hJTEQpOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPcENvZGVzLk1BVENIX0FUVFJJQlVURSA6Ci0gICAgIGlmKERFQlVHKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk1BVENIX0FUVFJJQlVURTogIitnZXRTdGVwTG9jYWxOYW1lKHN0YXJ0T3BQb3MpKyIsICIrbV9jdXJyZW50UGF0dGVybik7Ci0gICAgICBhcmdMZW4gPSBnZXRBcmdMZW5ndGhPZlN0ZXAob3BQb3MpOwotICAgICAgb3BQb3MgPSBnZXRGaXJzdENoaWxkUG9zT2ZTdGVwKG9wUG9zKTsKLSAgICAgIHBhdHRlcm4gPSBuZXcgU3RlcFBhdHRlcm4oRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRTdGVwTlMoc3RhcnRPcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFN0ZXBMb2NhbE5hbWUoc3RhcnRPcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF4aXMuUEFSRU5ULCBBeGlzLkFUVFJJQlVURSk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIE9wQ29kZXMuTUFUQ0hfQU5ZX0FOQ0VTVE9SIDoKLSAgICAgIGlmKERFQlVHKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk1BVENIX0FOWV9BTkNFU1RPUjogIitnZXRTdGVwTG9jYWxOYW1lKHN0YXJ0T3BQb3MpKyIsICIrbV9jdXJyZW50UGF0dGVybik7Ci0gICAgICBhcmdMZW4gPSBnZXRBcmdMZW5ndGhPZlN0ZXAob3BQb3MpOwotICAgICAgb3BQb3MgPSBnZXRGaXJzdENoaWxkUG9zT2ZTdGVwKG9wUG9zKTsKLSAgICAgIGludCB3aGF0ID0gZ2V0V2hhdFRvU2hvdyhzdGFydE9wUG9zKTsKLSAgICAgIC8vIGJpdC1vLWhhY2tlcnksIGJ1dCB0aGlzIGNvZGUgaXMgZHVlIGZvciB0aGUgbW9yZ3VlIGFueXdheS4uLgotICAgICAgaWYoMHgwMDAwMDUwMCA9PSB3aGF0KQotICAgICAgICBhZGRNYWdpY1NlbGYgPSBmYWxzZTsKLSAgICAgIHBhdHRlcm4gPSBuZXcgU3RlcFBhdHRlcm4oZ2V0V2hhdFRvU2hvdyhzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRTdGVwTlMoc3RhcnRPcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3RlcExvY2FsTmFtZShzdGFydE9wUG9zKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBeGlzLkFOQ0VTVE9SLCBBeGlzLkNISUxEKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgT3BDb2Rlcy5NQVRDSF9JTU1FRElBVEVfQU5DRVNUT1IgOgotICAgICAgaWYoREVCVUcpCi0gICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTUFUQ0hfSU1NRURJQVRFX0FOQ0VTVE9SOiAiK2dldFN0ZXBMb2NhbE5hbWUoc3RhcnRPcFBvcykrIiwgIittX2N1cnJlbnRQYXR0ZXJuKTsKLSAgICAgIGFyZ0xlbiA9IGdldEFyZ0xlbmd0aE9mU3RlcChvcFBvcyk7Ci0gICAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3NPZlN0ZXAob3BQb3MpOwotICAgICAgcGF0dGVybiA9IG5ldyBTdGVwUGF0dGVybihnZXRXaGF0VG9TaG93KHN0YXJ0T3BQb3MpLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRTdGVwTlMoc3RhcnRPcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFN0ZXBMb2NhbE5hbWUoc3RhcnRPcFBvcyksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF4aXMuUEFSRU5ULCBBeGlzLkNISUxEKTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9VTktOT1dOX01BVENIX09QRVJBVElPTiwgbnVsbCk7ICAvLyJ1bmtub3duIG1hdGNoIG9wZXJhdGlvbiEiKTsKLQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotCi0gICAgcGF0dGVybi5zZXRQcmVkaWNhdGVzKGdldENvbXBpbGVkUHJlZGljYXRlcyhvcFBvcyArIGFyZ0xlbikpOwotICAgIGlmKG51bGwgPT0gYW5jZXN0b3JQYXR0ZXJuKQotICAgIHsKLSAgICAgIC8vIFRoaXMgaXMgdGhlIG1hZ2ljIGFuZCBpbnZpc2libGUgIi4iIGF0IHRoZSBoZWFkIG9mIGV2ZXJ5IAotICAgICAgLy8gbWF0Y2ggcGF0dGVybiwgYW5kIGNvcnJlc3BvbmRzIHRvIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIGNvbnRleHQgCi0gICAgICAvLyBsaXN0LCBmcm9tIHdoZXJlIHByZWRpY2F0ZXMgYXJlIGNvdW50ZWQuCi0gICAgICAvLyBTbywgaW4gb3JkZXIgdG8gY2FsY3VsYXRlICJmb29bM10iLCBpdCBoYXMgdG8gY291bnQgZnJvbSB0aGUgCi0gICAgICAvLyBjdXJyZW50IG5vZGUgaW4gdGhlIGNvbnRleHQgbGlzdCwgc28sIGZyb20gdGhhdCBjdXJyZW50IG5vZGUsIAotICAgICAgLy8gdGhlIGZ1bGwgcGF0dGVybiBpcyByZWFsbHkgInNlbGY6Om5vZGUoKS9jaGlsZDo6Zm9vWzNdIi4gIElmIHlvdSAKLSAgICAgIC8vIHRyYW5zbGF0ZSB0aGlzIHRvIGEgc2VsZWN0IHBhdHRlcm4gZnJvbSB0aGUgbm9kZSBiZWluZyB0ZXN0ZWQsIAotICAgICAgLy8gd2hpY2ggaXMgcmVhbGx5IGhvdyB3ZSdyZSB0cmVhdGluZyBtYXRjaCBwYXR0ZXJucywgaXQgd29ya3Mgb3V0IHRvIAotICAgICAgLy8gc2VsZjo6Zm9vL3BhcmVudDo6bm9kZVtjaGlsZDo6Zm9vWzNdXSIsIG9yIGNsb3NlIGVub3VnaC4KLQkvKiAgICAgIGlmKGFkZE1hZ2ljU2VsZiAmJiBwYXR0ZXJuLmdldFByZWRpY2F0ZUNvdW50KCkgPiAwKQotICAgICAgewotICAgICAgICBTdGVwUGF0dGVybiBzZWxmUGF0dGVybiA9IG5ldyBTdGVwUGF0dGVybihEVE1GaWx0ZXIuU0hPV19BTEwsIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBeGlzLlBBUkVOVCwgQXhpcy5DSElMRCk7Ci0gICAgICAgIC8vIFdlIG5lZWQgdG8ga2VlcCB0aGUgbmV3IG5vZGV0ZXN0IGZyb20gYWZmZWN0aW5nIHRoZSBzY29yZS4uLgotICAgICAgICBYTnVtYmVyIHNjb3JlID0gcGF0dGVybi5nZXRTdGF0aWNTY29yZSgpOwotICAgICAgICBwYXR0ZXJuLnNldFJlbGF0aXZlUGF0aFBhdHRlcm4oc2VsZlBhdHRlcm4pOwotICAgICAgICBwYXR0ZXJuLnNldFN0YXRpY1Njb3JlKHNjb3JlKTsKLSAgICAgICAgc2VsZlBhdHRlcm4uc2V0U3RhdGljU2NvcmUoc2NvcmUpOwotCX0qLwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJTZXR0aW5nICIrYW5jZXN0b3JQYXR0ZXJuKyIgYXMgcmVsYXRpdmUgdG8gIitwYXR0ZXJuKTsKLSAgICAgIHBhdHRlcm4uc2V0UmVsYXRpdmVQYXRoUGF0dGVybihhbmNlc3RvclBhdHRlcm4pOwotICAgIH0KLQotICAgIFN0ZXBQYXR0ZXJuIHJlbGF0aXZlUGF0aFBhdHRlcm4gPSBzdGVwUGF0dGVybihlbmRTdGVwLCBzdGVwQ291bnQgKyAxLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4pOwotCi0gICAgcmV0dXJuIChudWxsICE9IHJlbGF0aXZlUGF0aFBhdHRlcm4pID8gcmVsYXRpdmVQYXRoUGF0dGVybiA6IHBhdHRlcm47Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGlsZSBhIHplcm8gb3IgbW9yZSBwcmVkaWNhdGVzIGZvciBhIGdpdmVuIG1hdGNoIHBhdHRlcm4uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBwcmVkaWNhdGUgdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIGFycmF5IG9mIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb259IGluc3RhbmNlcy4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHB1YmxpYyBFeHByZXNzaW9uW10gZ2V0Q29tcGlsZWRQcmVkaWNhdGVzKGludCBvcFBvcykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvdW50ID0gY291bnRQcmVkaWNhdGVzKG9wUG9zKTsKLQotICAgIGlmIChjb3VudCA+IDApCi0gICAgewotICAgICAgRXhwcmVzc2lvbltdIHByZWRpY2F0ZXMgPSBuZXcgRXhwcmVzc2lvbltjb3VudF07Ci0KLSAgICAgIGNvbXBpbGVQcmVkaWNhdGVzKG9wUG9zLCBwcmVkaWNhdGVzKTsKLQotICAgICAgcmV0dXJuIHByZWRpY2F0ZXM7Ci0gICAgfQotCi0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogQ291bnQgdGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIGluIHRoZSBzdGVwLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgVGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBwcmVkaWNhdGUgdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIGZvciB0aGlzIHN0ZXAuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgaW50IGNvdW50UHJlZGljYXRlcyhpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgY291bnQgPSAwOwotCi0gICAgd2hpbGUgKE9wQ29kZXMuT1BfUFJFRElDQVRFID09IGdldE9wKG9wUG9zKSkKLSAgICB7Ci0gICAgICBjb3VudCsrOwotCi0gICAgICBvcFBvcyA9IGdldE5leHRPcFBvcyhvcFBvcyk7Ci0gICAgfQotCi0gICAgcmV0dXJuIGNvdW50OwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGVzIHByZWRpY2F0ZXMgaW4gdGhlIHN0ZXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBUaGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IHByZWRpY2F0ZSB0aGUgbV9vcE1hcCBhcnJheS4KLSAgICogQHBhcmFtIHByZWRpY2F0ZXMgQW4gZW1wdHkgcHJlLWRldGVybWluZWQgYXJyYXkgb2YgCi0gICAqICAgICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbn1zLCB0aGF0IHdpbGwgYmUgZmlsbGVkIGluLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcml2YXRlIHZvaWQgY29tcGlsZVByZWRpY2F0ZXMoaW50IG9wUG9zLCBFeHByZXNzaW9uW10gcHJlZGljYXRlcykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgZm9yIChpbnQgaSA9IDA7IE9wQ29kZXMuT1BfUFJFRElDQVRFID09IGdldE9wKG9wUG9zKTsgaSsrKQotICAgIHsKLSAgICAgIHByZWRpY2F0ZXNbaV0gPSBwcmVkaWNhdGUob3BQb3MpOwotICAgICAgb3BQb3MgPSBnZXROZXh0T3BQb3Mob3BQb3MpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDb21waWxlIGEgYnVpbHQtaW4gWFBhdGggZnVuY3Rpb24uCi0gICAqIAotICAgKiBAcGFyYW0gb3BQb3MgVGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIG1fb3BNYXAgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy5GdW5jdGlvbn0gaW5zdGFuY2UuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBlcnJvciBvY2N1cnMgY3JlYXRpbmcgdGhlIEV4cHJlc3Npb24uCi0gICAqLwotICBFeHByZXNzaW9uIGNvbXBpbGVGdW5jdGlvbihpbnQgb3BQb3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgZW5kRnVuYyA9IG9wUG9zICsgbV9vcE1hcFtvcFBvcyArIDFdIC0gMTsKLQotICAgIG9wUG9zID0gZ2V0Rmlyc3RDaGlsZFBvcyhvcFBvcyk7Ci0KLSAgICBpbnQgZnVuY0lEID0gbV9vcE1hcFtvcFBvc107Ci0KLSAgICBvcFBvcysrOwotCi0gICAgaWYgKC0xICE9IGZ1bmNJRCkKLSAgICB7Ci0gICAgICBGdW5jdGlvbiBmdW5jID0gRnVuY3Rpb25UYWJsZS5nZXRGdW5jdGlvbihmdW5jSUQpOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaW50IGkgPSAwOwotCi0gICAgICAgIGZvciAoaW50IHAgPSBvcFBvczsgcCA8IGVuZEZ1bmM7IHAgPSBnZXROZXh0T3BQb3MocCksIGkrKykKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJhcmdQb3M6ICIrIHApOwotICAgICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYXJnQ29kZTogIisgbV9vcE1hcFtwXSk7Ci0gICAgICAgICAgZnVuYy5zZXRBcmcoY29tcGlsZShwKSwgaSk7Ci0gICAgICAgIH0KLQotICAgICAgICBmdW5jLmNoZWNrTnVtYmVyQXJncyhpKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gd25hZSkKLSAgICAgIHsKLSAgICAgICAgamF2YS5sYW5nLlN0cmluZyBuYW1lID0gRnVuY3Rpb25UYWJsZS5tX2Z1bmN0aW9uc1tmdW5jSURdLmdldE5hbWUoKTsKLQotICAgICAgICBtX2Vycm9ySGFuZGxlci5mYXRhbEVycm9yKCBuZXcgVHJhbnNmb3JtZXJFeGNlcHRpb24obmFtZSArICIgb25seSBhbGxvd3MgIiArIHduYWUuZ2V0TWVzc2FnZSgpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGFyZ3VtZW50cyIsIG1fbG9jYXRvcikpOwotICAgICAgfQotCi0gICAgICByZXR1cm4gZnVuYzsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5ELCBudWxsKTsgIC8vImZ1bmN0aW9uIHRva2VuIG5vdCBmb3VuZC4iKTsKLQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBpbGUgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBtX29wTWFwIGFycmF5LgotICAgKgotICAgKiBAcmV0dXJuIHJlZmVyZW5jZSB0byB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuRnVuY0V4dEZ1bmN0aW9ufSBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhIGVycm9yIG9jY3VycyBjcmVhdGluZyB0aGUgRXhwcmVzc2lvbi4KLSAgICovCi0gIHByaXZhdGUgRXhwcmVzc2lvbiBjb21waWxlRXh0ZW5zaW9uKGludCBvcFBvcykKLSAgICAgICAgICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGVuZEV4dEZ1bmMgPSBvcFBvcyArIG1fb3BNYXBbb3BQb3MgKyAxXSAtIDE7Ci0KLSAgICBvcFBvcyA9IGdldEZpcnN0Q2hpbGRQb3Mob3BQb3MpOwotCi0gICAgamF2YS5sYW5nLlN0cmluZyBucyA9IChqYXZhLmxhbmcuU3RyaW5nKSBtX3Rva2VuUXVldWVbbV9vcE1hcFtvcFBvc11dOwotCi0gICAgb3BQb3MrKzsKLQotICAgIGphdmEubGFuZy5TdHJpbmcgZnVuY05hbWUgPQotICAgICAgKGphdmEubGFuZy5TdHJpbmcpIG1fdG9rZW5RdWV1ZVttX29wTWFwW29wUG9zXV07Ci0KLSAgICBvcFBvcysrOwotCi0gICAgLy8gV2UgY3JlYXRlIGEgbWV0aG9kIGtleSB0byB1bmlxdWVseSBpZGVudGlmeSB0aGlzIGZ1bmN0aW9uIHNvIHRoYXQgd2UKLSAgICAvLyBjYW4gY2FjaGUgdGhlIG9iamVjdCBuZWVkZWQgdG8gaW52b2tlIGl0LiAgVGhpcyB3YXksIHdlIG9ubHkgcGF5IHRoZQotICAgIC8vIHJlZmxlY3Rpb24gb3ZlcmhlYWQgb24gdGhlIGZpcnN0IGNhbGwuCi0KLSAgICBGdW5jdGlvbiBleHRlbnNpb24gPSBuZXcgRnVuY0V4dEZ1bmN0aW9uKG5zLCBmdW5jTmFtZSwgCi0gICAgICAgICBTdHJpbmcudmFsdWVPZihvcFBvcykKLSAgICAgICArIFN0cmluZy52YWx1ZU9mKGhhc2hDb2RlKCkpCi0gICAgICAgKyBTdHJpbmcudmFsdWVPZihTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgaW50IGkgPSAwOwotCi0gICAgICB3aGlsZSAob3BQb3MgPCBlbmRFeHRGdW5jKQotICAgICAgewotICAgICAgICBpbnQgbmV4dE9wUG9zID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLQotICAgICAgICBleHRlbnNpb24uc2V0QXJnKHRoaXMuY29tcGlsZShvcFBvcyksIGkpOwotCi0gICAgICAgIG9wUG9zID0gbmV4dE9wUG9zOwotCi0gICAgICAgIGkrKzsKLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiB3bmFlKQotICAgIHsKLSAgICAgIDsgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4KLSAgICB9Ci0KLSAgICByZXR1cm4gZXh0ZW5zaW9uOwotICB9Ci0KLSAgLyoqCi0gICAqIFdhcm4gdGhlIHVzZXIgb2YgYW4gcHJvYmxlbS4KLSAgICoKLSAgICogQHBhcmFtIG1zZyBBbiBlcnJvciBudW1iZXIgdGhhdCBjb3JyZXNwb25kcyB0byBvbmUgb2YgdGhlIG51bWJlcnMgZm91bmQgCi0gICAqICAgICAgICAgICAgaW4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXN9LCB3aGljaCBpcyAKLSAgICogICAgICAgICAgICBhIGtleSBmb3IgYSBmb3JtYXQgc3RyaW5nLgotICAgKiBAcGFyYW0gYXJncyBBbiBhcnJheSBvZiBhcmd1bWVudHMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm1hdCBzdHJpbmcsIHdoaWNoIAotICAgKiAgICAgICAgICAgICBtYXkgYmUgbnVsbC4KLSAgICoKLSAgICogQHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiB0aGUgY3VycmVudCBFcnJvckxpc3RvbmVyIGRldGVybWluZXMgdG8gCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYW4gZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgd2FybihpbnQgbXNnLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgamF2YS5sYW5nLlN0cmluZyBmbXNnID0gWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhXYXJuaW5nKG1zZywgYXJncyk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2Vycm9ySGFuZGxlcikKLSAgICB7Ci0gICAgICBtX2Vycm9ySGFuZGxlci53YXJuaW5nKG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihmbXNnLCBtX2xvY2F0b3IpKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihmbXNnCi0gICAgICAgICAgICAgICAgICAgICAgICAgICsiOyBmaWxlICIrbV9sb2NhdG9yLmdldFN5c3RlbUlkKCkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgKyI7IGxpbmUgIittX2xvY2F0b3IuZ2V0TGluZU51bWJlcigpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICsiOyBjb2x1bW4gIittX2xvY2F0b3IuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGFzc2VydGlvbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGIgIElmIGZhbHNlLCBhIHJ1bnRpbWUgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgotICAgKiBAcGFyYW0gbXNnIFRoZSBhc3NlcnRpb24gbWVzc2FnZSwgd2hpY2ggc2hvdWxkIGJlIGluZm9ybWF0aXZlLgotICAgKiAKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIHRoZSBiIGFyZ3VtZW50IGlzIGZhbHNlLgotICAgKi8KLSAgcHVibGljIHZvaWQgYXNzZXJ0aW9uKGJvb2xlYW4gYiwgamF2YS5sYW5nLlN0cmluZyBtc2cpCi0gIHsKLQotICAgIGlmICghYikKLSAgICB7Ci0gICAgICBqYXZhLmxhbmcuU3RyaW5nIGZNc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoCi0gICAgICAgIFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfSU5DT1JSRUNUX1BST0dSQU1NRVJfQVNTRVJUSU9OLAotICAgICAgICBuZXcgT2JqZWN0W117IG1zZyB9KTsKLQotICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZk1zZyk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbnVtYmVyIHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBudW1iZXJzIGZvdW5kIAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMgCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaCAKLSAgICogICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgRXJyb3JMaXN0b25lciBkZXRlcm1pbmVzIHRvIAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKGludCBtc2csIE9iamVjdFtdIGFyZ3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBqYXZhLmxhbmcuU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UobXNnLCBhcmdzKTsKLSAgICAKLQotICAgIGlmIChudWxsICE9IG1fZXJyb3JIYW5kbGVyKQotICAgIHsKLSAgICAgIG1fZXJyb3JIYW5kbGVyLmZhdGFsRXJyb3IobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fbG9jYXRvcikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotCi0gICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4odGUuZ2V0TWVzc2FnZSgpCi0gICAgICAvLyAgICAgICAgICAgICAgICAgICAgKyI7IGZpbGUgIit0ZS5nZXRTeXN0ZW1JZCgpCi0gICAgICAvLyAgICAgICAgICAgICAgICAgICAgKyI7IGxpbmUgIit0ZS5nZXRMaW5lTnVtYmVyKCkKLSAgICAgIC8vICAgICAgICAgICAgICAgICAgICArIjsgY29sdW1uICIrdGUuZ2V0Q29sdW1uTnVtYmVyKCkpOwotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIChTQVhTb3VyY2VMb2NhdG9yKW1fbG9jYXRvcik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IHByZWZpeFJlc29sdmVyIGZvciB0aGUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqLwotICBwcml2YXRlIFByZWZpeFJlc29sdmVyIG1fY3VycmVudFByZWZpeFJlc29sdmVyID0gbnVsbDsKLQotICAvKioKLSAgICogR2V0IHRoZSBjdXJyZW50IG5hbWVzcGFjZSBjb250ZXh0IGZvciB0aGUgeHBhdGguCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgcHJlZml4IHJlc29sdmVyLCAqbWF5KiBiZSBudWxsLCB0aG91Z2ggaG9wZWZ1bGx5IG5vdC4KLSAgICovCi0gIHB1YmxpYyBQcmVmaXhSZXNvbHZlciBnZXROYW1lc3BhY2VDb250ZXh0KCkKLSAgewotICAgIHJldHVybiBtX2N1cnJlbnRQcmVmaXhSZXNvbHZlcjsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGN1cnJlbnQgbmFtZXNwYWNlIGNvbnRleHQgZm9yIHRoZSB4cGF0aC4KLSAgICoKLSAgICogQHBhcmFtIHByIFRoZSByZXNvbHZlciBmb3IgcHJlZml4ZXMgaW4gdGhlIFhQYXRoIGV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2VDb250ZXh0KFByZWZpeFJlc29sdmVyIHByKQotICB7Ci0gICAgbV9jdXJyZW50UHJlZml4UmVzb2x2ZXIgPSBwcjsKLSAgfQotCi0gIC8qKiBUaGUgZXJyb3IgbGlzdGVuZXIgd2hlcmUgZXJyb3JzIHdpbGwgYmUgc2VudC4gIElmIHRoaXMgaXMgbnVsbCwgZXJyb3JzIAotICAgKiAgYW5kIHdhcm5pbmdzIHdpbGwgYmUgc2VudCB0byBTeXN0ZW0uZXJyLiAgTWF5IGJlIG51bGwuICAgICovCi0gIEVycm9yTGlzdGVuZXIgbV9lcnJvckhhbmRsZXI7Ci0KLSAgLyoqIFRoZSBzb3VyY2UgbG9jYXRvciBmb3IgdGhlIGV4cHJlc3Npb24gYmVpbmcgY29tcGlsZWQuICBNYXkgYmUgbnVsbC4gKi8KLSAgU291cmNlTG9jYXRvciBtX2xvY2F0b3I7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9GdW5jTG9hZGVyLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9GdW5jTG9hZGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBmNjM5ODkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvRnVuY0xvYWRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXI7Ci0KLWltcG9ydCBqYXZhLmxhbmcuQ2xhc3M7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi1pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogTGF6eSBsb2FkIG9mIGZ1bmN0aW9ucyBpbnRvIHRoZSBmdW5jdGlvbiB0YWJsZSBhcyBuZWVkZWQsIHNvIHdlIGRvbid0IAotICogaGF2ZSB0byBsb2FkIGFsbCB0aGUgZnVuY3Rpb25zIGFsbG93ZWQgaW4gWFBhdGggYW5kIFhTTFQgb24gc3RhcnR1cC4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNMb2FkZXIKLXsKLQotICAvKiogVGhlIGZ1bmN0aW9uIElELCB3aGljaCBtYXkgY29ycmVzcG9uZCB0byBvbmUgb2YgdGhlIEZVTkNfWFhYIHZhbHVlcyAKLSAgICogIGZvdW5kIGluIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLkZ1bmN0aW9uVGFibGV9LCBidXQgbWF5IAotICAgKiAgYmUgYSB2YWx1ZSBpbnN0YWxsZWQgYnkgYW4gZXh0ZXJuYWwgbW9kdWxlLiAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9mdW5jSUQ7Ci0KLSAgLyoqIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSBmdW5jdGlvbi4gIE11c3Qgbm90IGJlIG51bGwuICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmcgbV9mdW5jTmFtZTsKLQotICAvKioKLSAgICogR2V0IHRoZSBsb2NhbCBjbGFzcyBuYW1lIG9mIHRoZSBmdW5jdGlvbiBjbGFzcy4gIElmIGZ1bmN0aW9uIG5hbWUgZG9lcyAKLSAgICogbm90IGhhdmUgYSAnLicgaW4gaXQsIGl0IGlzIGFzc3VtZWQgdG8gYmUgcmVsYXRpdmUgdG8gCi0gICAqICdvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucycuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGNsYXNzIG5hbWUgb2YgdGhlIHtvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy5GdW5jdGlvbn0gY2xhc3MuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIG1fZnVuY05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgZnVuY3Rpb24gbG9hZGVyCi0gICAqCi0gICAqIEBwYXJhbSBmdW5jTmFtZSBUaGUgY2xhc3MgbmFtZSBvZiB0aGUge29yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9ufSAKLSAgICogICAgICAgICAgICAgY2xhc3MsIHdoaWNoLCBpZiBpdCBkb2VzIG5vdCBoYXZlIGEgJy4nIGluIGl0LCBpcyBhc3N1bWVkIHRvIAotICAgKiAgICAgICAgICAgICBiZSByZWxhdGl2ZSB0byAnb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMnLiAKLSAgICogQHBhcmFtIGZ1bmNJRCAgVGhlIGZ1bmN0aW9uIElELCB3aGljaCBtYXkgY29ycmVzcG9uZCB0byBvbmUgb2YgdGhlIEZVTkNfWFhYIAotICAgKiAgICB2YWx1ZXMgZm91bmQgaW4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkgCi0gICAqICAgIGJlIGEgdmFsdWUgaW5zdGFsbGVkIGJ5IGFuIGV4dGVybmFsIG1vZHVsZS4gCi0gICAqLwotICBwdWJsaWMgRnVuY0xvYWRlcihTdHJpbmcgZnVuY05hbWUsIGludCBmdW5jSUQpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBtX2Z1bmNJRCA9IGZ1bmNJRDsKLSAgICBtX2Z1bmNOYW1lID0gZnVuY05hbWU7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IGEgRnVuY3Rpb24gaW5zdGFuY2UgdGhhdCB0aGlzIGluc3RhbmNlIGlzIGxpYWlzb25pbmcgZm9yLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBGdW5jdGlvbiBkZXJpdmF0aXZlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgCi0gICAqICAgIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sIG9yIEluc3RhbnRpYXRpb25FeGNlcHRpb24gaXMgdGhyb3duLgotICAgKi8KLSAgcHVibGljIEZ1bmN0aW9uIGdldEZ1bmN0aW9uKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgQ2xhc3MgZnVuY3Rpb247Ci0KLSAgICAgIC8vIGZpcnN0IGdldCBwYWNrYWdlIG5hbWUgaWYgbmVjZXNzYXJ5Ci0gICAgICBpZiAobV9mdW5jTmFtZS5pbmRleE9mKCIuIikgPCAwKQotICAgICAgewotCi0gICAgICAgIC8vIFN0cmluZyB0aGlzTmFtZSA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7Ci0gICAgICAgIC8vIGludCBsYXN0ZG90ID0gdGhpc05hbWUubGFzdEluZGV4T2YoIi4iKTsKLSAgICAgICAgLy8gU3RyaW5nIGNsYXNzbmFtZSA9IHRoaXNOYW1lLnN1YnN0cmluZygwLGxhc3Rkb3QrMSkgKyBtX2Z1bmNOYW1lOyAKLSAgICAgICAgU3RyaW5nIGNsYXNzbmFtZSA9ICJvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy4iICsgbV9mdW5jTmFtZTsKLQotICAgICAgICBmdW5jdGlvbiA9IENsYXNzLmZvck5hbWUoY2xhc3NuYW1lKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgZnVuY3Rpb24gPSBDbGFzcy5mb3JOYW1lKG1fZnVuY05hbWUpOwotCi0gICAgICBGdW5jdGlvbiBmdW5jID0gKEZ1bmN0aW9uKSBmdW5jdGlvbi5uZXdJbnN0YW5jZSgpOwotCi0gICAgICByZXR1cm4gZnVuYzsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbihlKTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL0Z1bmN0aW9uVGFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL0Z1bmN0aW9uVGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDBmNDg3OC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9GdW5jdGlvblRhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMjMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5jb21waWxlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9ucy5GdW5jdGlvbjsKLQotLyoqCi0gKiBUaGUgZnVuY3Rpb24gdGFibGUgZm9yIFhQYXRoLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY3Rpb25UYWJsZQotewotCi0gIC8qKiBUaGUgJ2N1cnJlbnQoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfQ1VSUkVOVCA9IDA7Ci0KLSAgLyoqIFRoZSAnbGFzdCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19MQVNUID0gMTsKLQotICAvKiogVGhlICdwb3NpdGlvbigpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19QT1NJVElPTiA9IDI7Ci0KLSAgLyoqIFRoZSAnY291bnQoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfQ09VTlQgPSAzOwotCi0gIC8qKiBUaGUgJ2lkKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0lEID0gNDsKLQotICAvKiogVGhlICdrZXkoKScgaWQgKFhTTFQpLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0tFWSA9IDU7Ci0KLSAgLyoqIFRoZSAnbG9jYWwtbmFtZSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19MT0NBTF9QQVJUID0gNzsKLQotICAvKiogVGhlICduYW1lc3BhY2UtdXJpKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX05BTUVTUEFDRSA9IDg7Ci0KLSAgLyoqIFRoZSAnbmFtZSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19RTkFNRSA9IDk7Ci0KLSAgLyoqIFRoZSAnZ2VuZXJhdGUtaWQoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfR0VORVJBVEVfSUQgPSAxMDsKLQotICAvKiogVGhlICdub3QoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfTk9UID0gMTE7Ci0KLSAgLyoqIFRoZSAndHJ1ZSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19UUlVFID0gMTI7Ci0KLSAgLyoqIFRoZSAnZmFsc2UoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfRkFMU0UgPSAxMzsKLQotICAvKiogVGhlICdib29sZWFuKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0JPT0xFQU4gPSAxNDsKLQotICAvKiogVGhlICdudW1iZXIoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfTlVNQkVSID0gMTU7Ci0KLSAgLyoqIFRoZSAnZmxvb3IoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfRkxPT1IgPSAxNjsKLQotICAvKiogVGhlICdjZWlsaW5nKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0NFSUxJTkcgPSAxNzsKLQotICAvKiogVGhlICdyb3VuZCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19ST1VORCA9IDE4OwotCi0gIC8qKiBUaGUgJ3N1bSgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVU0gPSAxOTsKLQotICAvKiogVGhlICdzdHJpbmcoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfU1RSSU5HID0gMjA7Ci0KLSAgLyoqIFRoZSAnc3RhcnRzLXdpdGgoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfU1RBUlRTX1dJVEggPSAyMTsKLQotICAvKiogVGhlICdjb250YWlucygpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19DT05UQUlOUyA9IDIyOwotCi0gIC8qKiBUaGUgJ3N1YnN0cmluZy1iZWZvcmUoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfU1VCU1RSSU5HX0JFRk9SRSA9IDIzOwotCi0gIC8qKiBUaGUgJ3N1YnN0cmluZy1hZnRlcigpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVUJTVFJJTkdfQUZURVIgPSAyNDsKLQotICAvKiogVGhlICdub3JtYWxpemUtc3BhY2UoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfTk9STUFMSVpFX1NQQUNFID0gMjU7Ci0KLSAgLyoqIFRoZSAndHJhbnNsYXRlKCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1RSQU5TTEFURSA9IDI2OwotCi0gIC8qKiBUaGUgJ2NvbmNhdCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19DT05DQVQgPSAyNzsKLQotICAvKiogVGhlICdzdWJzdHJpbmcoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfU1VCU1RSSU5HID0gMjk7Ci0KLSAgLyoqIFRoZSAnc3RyaW5nLWxlbmd0aCgpJyBpZC4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19TVFJJTkdfTEVOR1RIID0gMzA7Ci0KLSAgLyoqIFRoZSAnc3lzdGVtLXByb3BlcnR5KCknIGlkLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX1NZU1RFTV9QUk9QRVJUWSA9IDMxOwotCi0gIC8qKiBUaGUgJ2xhbmcoKScgaWQuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfTEFORyA9IDMyOwotCi0gIC8qKiBUaGUgJ2Z1bmN0aW9uLWF2YWlsYWJsZSgpJyBpZCAoWFNMVCkuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZVTkNfRVhUX0ZVTkNUSU9OX0FWQUlMQUJMRSA9IDMzOwotCi0gIC8qKiBUaGUgJ2VsZW1lbnQtYXZhaWxhYmxlKCknIGlkIChYU0xUKS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19FWFRfRUxFTV9BVkFJTEFCTEUgPSAzNDsKLQotICAvKiogVGhlICd1bnBhcnNlZC1lbnRpdHktdXJpKCknIGlkIChYU0xUKS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlVOQ19VTlBBUlNFRF9FTlRJVFlfVVJJID0gMzY7Ci0KLSAgLy8gUHJvcHJpZXRhcnkKLQotICAvKiogVGhlICdkb2N1bWVudC1sb2NhdGlvbigpJyBpZCAoUHJvcHJpZXRhcnkpLiAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGVU5DX0RPQ0xPQ0FUSU9OID0gMzU7Ci0KLSAgLyoqCi0gICAqIFRoZSBmdW5jdGlvbiB0YWJsZS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgRnVuY0xvYWRlciBtX2Z1bmN0aW9uc1tdOwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2YgYnVpbHQgaW4gZnVuY3Rpb25zLiAgQmUgc3VyZSB0byB1cGRhdGUgdGhpcyBhcwotICAgKiBidWlsdC1pbiBmdW5jdGlvbnMgYXJlIGFkZGVkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9CVUlMVF9JTl9GVU5DUyA9IDM3OwotCi0gIC8qKgotICAgKiBOdW1iZXIgb2YgYnVpbHQtaW4gZnVuY3Rpb25zIHRoYXQgbWF5IGJlIGFkZGVkLgotICAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9BTExPV0FCTEVfQURESU5TID0gMzA7Ci0KLSAgLyoqCi0gICAqIFRoZSBpbmRleCB0byB0aGUgbmV4dCBmcmVlIGZ1bmN0aW9uIGluZGV4LgotICAgKi8KLSAgc3RhdGljIGludCBtX2Z1bmNOZXh0RnJlZUluZGV4ID0gTlVNX0JVSUxUX0lOX0ZVTkNTOwotCi0gIHN0YXRpYwotICB7Ci0gICAgbV9mdW5jdGlvbnMgPSBuZXcgRnVuY0xvYWRlcltOVU1fQlVJTFRfSU5fRlVOQ1MgKyBOVU1fQUxMT1dBQkxFX0FERElOU107Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19DVVJSRU5UXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jQ3VycmVudCIsIEZVTkNfQ1VSUkVOVCk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19MQVNUXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jTGFzdCIsIEZVTkNfTEFTVCk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19QT1NJVElPTl0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY1Bvc2l0aW9uIiwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTkNfUE9TSVRJT04pOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfQ09VTlRdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNDb3VudCIsIEZVTkNfQ09VTlQpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfSURdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNJZCIsIEZVTkNfSUQpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfS0VZXSA9Ci0gICAgICBuZXcgRnVuY0xvYWRlcigib3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRnVuY0tleSIsIEZVTkNfS0VZKTsKLQotICAgIC8vIG1fZnVuY3Rpb25zW0ZVTkNfRE9DXSA9IG5ldyBGdW5jRG9jKCk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19MT0NBTF9QQVJUXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jTG9jYWxQYXJ0IiwKLSAgICAgICAgICAgIEZVTkNfTE9DQUxfUEFSVCk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19OQU1FU1BBQ0VdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNOYW1lc3BhY2UiLAotICAgICAgICAgICAgRlVOQ19OQU1FU1BBQ0UpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfUU5BTUVdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNRbmFtZSIsIEZVTkNfUU5BTUUpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfR0VORVJBVEVfSURdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNHZW5lcmF0ZUlkIiwKLSAgICAgICAgICAgIEZVTkNfR0VORVJBVEVfSUQpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfTk9UXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jTm90IiwgRlVOQ19OT1QpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfVFJVRV0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY1RydWUiLCBGVU5DX1RSVUUpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfRkFMU0VdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNGYWxzZSIsIEZVTkNfRkFMU0UpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfQk9PTEVBTl0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY0Jvb2xlYW4iLCBGVU5DX0JPT0xFQU4pOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfTEFOR10gPSBuZXcgRnVuY0xvYWRlcigiRnVuY0xhbmciLCBGVU5DX0xBTkcpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfTlVNQkVSXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jTnVtYmVyIiwgRlVOQ19OVU1CRVIpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfRkxPT1JdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNGbG9vciIsIEZVTkNfRkxPT1IpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfQ0VJTElOR10gPSBuZXcgRnVuY0xvYWRlcigiRnVuY0NlaWxpbmciLCBGVU5DX0NFSUxJTkcpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfUk9VTkRdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNSb3VuZCIsIEZVTkNfUk9VTkQpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1VNXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jU3VtIiwgRlVOQ19TVU0pOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1RSSU5HXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jU3RyaW5nIiwgRlVOQ19TVFJJTkcpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1RBUlRTX1dJVEhdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNTdGFydHNXaXRoIiwKLSAgICAgICAgICAgIEZVTkNfU1RBUlRTX1dJVEgpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfQ09OVEFJTlNdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNDb250YWlucyIsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGVU5DX0NPTlRBSU5TKTsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1NVQlNUUklOR19CRUZPUkVdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNTdWJzdHJpbmdCZWZvcmUiLAotICAgICAgICAgICAgRlVOQ19TVUJTVFJJTkdfQkVGT1JFKTsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1NVQlNUUklOR19BRlRFUl0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY1N1YnN0cmluZ0FmdGVyIiwKLSAgICAgICAgICAgIEZVTkNfU1VCU1RSSU5HX0FGVEVSKTsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX05PUk1BTElaRV9TUEFDRV0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY05vcm1hbGl6ZVNwYWNlIiwKLSAgICAgICAgICAgIEZVTkNfTk9STUFMSVpFX1NQQUNFKTsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1RSQU5TTEFURV0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY1RyYW5zbGF0ZSIsCi0gICAgICAgICAgICBGVU5DX1RSQU5TTEFURSk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19DT05DQVRdID0gbmV3IEZ1bmNMb2FkZXIoIkZ1bmNDb25jYXQiLCBGVU5DX0NPTkNBVCk7Ci0KLSAgICAvL21fZnVuY3Rpb25zW0ZVTkNfRk9STUFUX05VTUJFUl0gPSBuZXcgRnVuY0Zvcm1hdE51bWJlcigpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfU1lTVEVNX1BST1BFUlRZXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jU3lzdGVtUHJvcGVydHkiLAotICAgICAgICAgICAgRlVOQ19TWVNURU1fUFJPUEVSVFkpOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfRVhUX0ZVTkNUSU9OX0FWQUlMQUJMRV0gPQotICAgICAgbmV3IEZ1bmNMb2FkZXIoIkZ1bmNFeHRGdW5jdGlvbkF2YWlsYWJsZSIsIEZVTkNfRVhUX0ZVTkNUSU9OX0FWQUlMQUJMRSk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19FWFRfRUxFTV9BVkFJTEFCTEVdID0KLSAgICAgIG5ldyBGdW5jTG9hZGVyKCJGdW5jRXh0RWxlbWVudEF2YWlsYWJsZSIsIEZVTkNfRVhUX0VMRU1fQVZBSUxBQkxFKTsKLSAgICBtX2Z1bmN0aW9uc1tGVU5DX1NVQlNUUklOR10gPSBuZXcgRnVuY0xvYWRlcigiRnVuY1N1YnN0cmluZyIsCi0gICAgICAgICAgICBGVU5DX1NVQlNUUklORyk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19TVFJJTkdfTEVOR1RIXSA9IG5ldyBGdW5jTG9hZGVyKCJGdW5jU3RyaW5nTGVuZ3RoIiwKLSAgICAgICAgICAgIEZVTkNfU1RSSU5HX0xFTkdUSCk7Ci0gICAgbV9mdW5jdGlvbnNbRlVOQ19ET0NMT0NBVElPTl0gPSBuZXcgRnVuY0xvYWRlcigiRnVuY0RvY2xvY2F0aW9uIiwKLSAgICAgICAgICAgIEZVTkNfRE9DTE9DQVRJT04pOwotICAgIG1fZnVuY3Rpb25zW0ZVTkNfVU5QQVJTRURfRU5USVRZX1VSSV0gPQotICAgICAgbmV3IEZ1bmNMb2FkZXIoIkZ1bmNVbnBhcnNlZEVudGl0eVVSSSIsIEZVTkNfVU5QQVJTRURfRU5USVRZX1VSSSk7Ci0gIH0KLQotICAvKioKLSAgICogT2J0YWluIGEgbmV3IEZ1bmN0aW9uIG9iamVjdCBmcm9tIGEgZnVuY3Rpb24gSUQuCi0gICAqCi0gICAqIEBwYXJhbSB3aGljaCAgVGhlIGZ1bmN0aW9uIElELCB3aGljaCBtYXkgY29ycmVzcG9uZCB0byBvbmUgb2YgdGhlIEZVTkNfWFhYIAotICAgKiAgICB2YWx1ZXMgZm91bmQgaW4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkgCi0gICAqICAgIGJlIGEgdmFsdWUgaW5zdGFsbGVkIGJ5IGFuIGV4dGVybmFsIG1vZHVsZS4gCi0gICAqCi0gICAqIEByZXR1cm4gYSBhIG5ldyBGdW5jdGlvbiBpbnN0YW5jZS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIAotICAgKiAgICBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uLCBvciBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGlzIHRocm93bi4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgRnVuY3Rpb24gZ2V0RnVuY3Rpb24oaW50IHdoaWNoKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV9mdW5jdGlvbnNbd2hpY2hdLmdldEZ1bmN0aW9uKCk7Ci0gIH0KLQotICAvKioKLSAgICogSW5zdGFsbCBhIGJ1aWx0LWluIGZ1bmN0aW9uLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgZnVuY3Rpb24uCi0gICAqIEBwYXJhbSBmdW5jIEEgSW1wbGVtZW50YXRpb24gb2YgYW4gWFBhdGggRnVuY3Rpb24gb2JqZWN0LgotICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgZnVuY3Rpb24gaW4gdGhlIGludGVybmFsIGluZGV4LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgaW5zdGFsbEZ1bmN0aW9uKFN0cmluZyBuYW1lLCBFeHByZXNzaW9uIGZ1bmMpCi0gIHsKLQotICAgIGludCBmdW5jSW5kZXg7Ci0gICAgT2JqZWN0IGZ1bmNJbmRleE9iaiA9IEtleXdvcmRzLm1fZnVuY3Rpb25zLmdldChuYW1lKTsKLQotICAgIGlmIChudWxsICE9IGZ1bmNJbmRleE9iaikKLSAgICB7Ci0gICAgICBmdW5jSW5kZXggPSAoKEludGVnZXIpIGZ1bmNJbmRleE9iaikuaW50VmFsdWUoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGZ1bmNJbmRleCA9IG1fZnVuY05leHRGcmVlSW5kZXg7Ci0KLSAgICAgIG1fZnVuY05leHRGcmVlSW5kZXgrKzsKLQotICAgICAgS2V5d29yZHMubV9mdW5jdGlvbnMucHV0KG5hbWUsIG5ldyBJbnRlZ2VyKGZ1bmNJbmRleCkpOwotICAgIH0KLQotICAgIEZ1bmNMb2FkZXIgbG9hZGVyID0gbmV3IEZ1bmNMb2FkZXIoZnVuYy5nZXRDbGFzcygpLmdldE5hbWUoKSwgZnVuY0luZGV4KTsKLQotICAgIG1fZnVuY3Rpb25zW2Z1bmNJbmRleF0gPSBsb2FkZXI7Ci0KLSAgICByZXR1cm4gZnVuY0luZGV4OwotICB9Ci0KLSAgLyoqCi0gICAqIEluc3RhbGwgYSBmdW5jdGlvbiBsb2FkZXIgYXQgYSBzcGVjaWZpYyBpbmRleC4KLSAgICogQHBhcmFtIGZ1bmMgQSBJbXBsZW1lbnRhdGlvbiBvZiBhbiBYUGF0aCBGdW5jdGlvbiBvYmplY3QuCi0gICAqIEBwYXJhbSB3aGljaCAgVGhlIGZ1bmN0aW9uIElELCB3aGljaCBtYXkgY29ycmVzcG9uZCB0byBvbmUgb2YgdGhlIEZVTkNfWFhYIAotICAgKiAgICB2YWx1ZXMgZm91bmQgaW4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkgCi0gICAqICAgIGJlIGEgdmFsdWUgaW5zdGFsbGVkIGJ5IGFuIGV4dGVybmFsIG1vZHVsZS4gCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSBmdW5jdGlvbiBpbiB0aGUgaW50ZXJuYWwgaW5kZXguCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgaW5zdGFsbEZ1bmN0aW9uKEV4cHJlc3Npb24gZnVuYywgaW50IGZ1bmNJbmRleCkKLSAgewotCi0gICAgRnVuY0xvYWRlciBsb2FkZXIgPSBuZXcgRnVuY0xvYWRlcihmdW5jLmdldENsYXNzKCkuZ2V0TmFtZSgpLCBmdW5jSW5kZXgpOwotCi0gICAgbV9mdW5jdGlvbnNbZnVuY0luZGV4XSA9IGxvYWRlcjsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvS2V5d29yZHMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL0tleXdvcmRzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE0ZTFhNDQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvS2V5d29yZHMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQxNSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRhYmxlIG9mIHN0cmluZ3MgdG8gb3BlcmF0aW9uIGNvZGUgbG9va3Vwcy4KLSAqLwotcHVibGljIGNsYXNzIEtleXdvcmRzCi17Ci0KLSAgLyoqIFRhYmxlIG9mIGtleXdvcmRzIHRvIG9wY29kZSBhc3NvY2lhdGlvbnMuICovCi0gIHN0YXRpYyBIYXNodGFibGUgbV9rZXl3b3JkcyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAvKiogVGFibGUgb2YgYXhlcyBuYW1lcyB0byBvcGNvZGUgYXNzb2NpYXRpb25zLiAqLwotICBzdGF0aWMgSGFzaHRhYmxlIG1fYXhpc25hbWVzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0gIC8qKiBUYWJsZSBvZiBmdW5jdGlvbiBuYW1lIHRvIGZ1bmN0aW9uIElEIGFzc29jaWF0aW9ucy4gKi8KLSAgc3RhdGljIEhhc2h0YWJsZSBtX2Z1bmN0aW9ucyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAvKiogVGFibGUgb2Ygbm9kZSB0eXBlIHN0cmluZ3MgdG8gb3Bjb2RlIGFzc29jaWF0aW9ucy4gKi8KLSAgc3RhdGljIEhhc2h0YWJsZSBtX25vZGV0eXBlcyA9IG5ldyBIYXNodGFibGUoKTsKLQotICAvKiogYW5jZXN0b3IgYXhlcyBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGUk9NX0FOQ0VTVE9SU19TVFJJTkcgPSAiYW5jZXN0b3IiOwotCi0gIC8qKiBhbmNlc3Rvci1vci1zZWxmIGF4ZXMgc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9BTkNFU1RPUlNfT1JfU0VMRl9TVFJJTkcgPQotICAgICJhbmNlc3Rvci1vci1zZWxmIjsKLQotICAvKiogYXR0cmlidXRlIGF4ZXMgc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9BVFRSSUJVVEVTX1NUUklORyA9ICJhdHRyaWJ1dGUiOwotCi0gIC8qKiBjaGlsZCBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fQ0hJTERSRU5fU1RSSU5HID0gImNoaWxkIjsKLQotICAvKiogZGVzY2VuZGFudC1vci1zZWxmIGF4ZXMgc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9ERVNDRU5EQU5UU19TVFJJTkcgPSAiZGVzY2VuZGFudCI7Ci0KLSAgLyoqIGFuY2VzdG9yIGF4ZXMgc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGX1NUUklORyA9Ci0gICAgImRlc2NlbmRhbnQtb3Itc2VsZiI7Ci0KLSAgLyoqIGZvbGxvd2luZyBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fRk9MTE9XSU5HX1NUUklORyA9ICJmb2xsb3dpbmciOwotCi0gIC8qKiBmb2xsb3dpbmctc2libGluZyBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fRk9MTE9XSU5HX1NJQkxJTkdTX1NUUklORyA9Ci0gICAgImZvbGxvd2luZy1zaWJsaW5nIjsKLQotICAvKiogcGFyZW50IGF4ZXMgc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlJPTV9QQVJFTlRfU1RSSU5HID0gInBhcmVudCI7Ci0KLSAgLyoqIHByZWNlZGluZyBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fUFJFQ0VESU5HX1NUUklORyA9ICJwcmVjZWRpbmciOwotCi0gIC8qKiBwcmVjZWRpbmctc2libGluZyBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fUFJFQ0VESU5HX1NJQkxJTkdTX1NUUklORyA9Ci0gICAgInByZWNlZGluZy1zaWJsaW5nIjsKLQotICAvKiogc2VsZiBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fU0VMRl9TVFJJTkcgPSAic2VsZiI7Ci0KLSAgLyoqIG5hbWVzcGFjZSBheGVzIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZST01fTkFNRVNQQUNFX1NUUklORyA9ICJuYW1lc3BhY2UiOwotCi0gIC8qKiBzZWxmIGF4ZXMgYWJyZXZpYXRlZCBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGUk9NX1NFTEZfQUJCUkVWSUFURURfU1RSSU5HID0gIi4iOwotCi0gIC8qKiBjb21tZW50IG5vZGUgdGVzdCBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9DT01NRU5UX1NUUklORyA9ICJjb21tZW50IjsKLQotICAvKiogdGV4dCBub2RlIHRlc3Qgc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERVRZUEVfVEVYVF9TVFJJTkcgPSAidGV4dCI7Ci0KLSAgLyoqIHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbm9kZSB0ZXN0IHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVUWVBFX1BJX1NUUklORyA9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIjsKLQotICAvKiogQW55IG5vZGUgdGVzdCBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9OT0RFX1NUUklORyA9ICJub2RlIjsKLQotICAvKiogV2lsZGNhcmQgZWxlbWVudCBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9BTllFTEVNRU5UX1NUUklORyA9ICIqIjsKLQotICAvKiogY3VycmVudCBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0NVUlJFTlRfU1RSSU5HID0gImN1cnJlbnQiOwotCi0gIC8qKiBsYXN0IGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfTEFTVF9TVFJJTkcgPSAibGFzdCI7Ci0KLSAgLyoqIHBvc2l0aW9uIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfUE9TSVRJT05fU1RSSU5HID0gInBvc2l0aW9uIjsKLQotICAvKiogY291bnQgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19DT1VOVF9TVFJJTkcgPSAiY291bnQiOwotCi0gIC8qKiBpZCBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19JRF9TVFJJTkcgPSAiaWQiOwotCi0gIC8qKiBrZXkgZnVuY3Rpb24gc3RyaW5nIChYU0xUKS4gKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19LRVlfU1RSSU5HID0gImtleSI7Ci0KLSAgLyoqIGxvY2FsLW5hbWUgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19MT0NBTF9QQVJUX1NUUklORyA9ICJsb2NhbC1uYW1lIjsKLQotICAvKiogbmFtZXNwYWNlLXVyaSBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX05BTUVTUEFDRV9TVFJJTkcgPSAibmFtZXNwYWNlLXVyaSI7Ci0KLSAgLyoqIG5hbWUgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19OQU1FX1NUUklORyA9ICJuYW1lIjsKLQotICAvKiogZ2VuZXJhdGUtaWQgZnVuY3Rpb24gc3RyaW5nIChYU0xUKS4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfR0VORVJBVEVfSURfU1RSSU5HID0gImdlbmVyYXRlLWlkIjsKLQotICAvKiogbm90IGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfTk9UX1NUUklORyA9ICJub3QiOwotCi0gIC8qKiB0cnVlIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfVFJVRV9TVFJJTkcgPSAidHJ1ZSI7Ci0KLSAgLyoqIGZhbHNlIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfRkFMU0VfU1RSSU5HID0gImZhbHNlIjsKLQotICAvKiogYm9vbGVhbiBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0JPT0xFQU5fU1RSSU5HID0gImJvb2xlYW4iOwotCi0gIC8qKiBsYW5nIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfTEFOR19TVFJJTkcgPSAibGFuZyI7Ci0KLSAgLyoqIG51bWJlciBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX05VTUJFUl9TVFJJTkcgPSAibnVtYmVyIjsKLQotICAvKiogZmxvb3IgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19GTE9PUl9TVFJJTkcgPSAiZmxvb3IiOwotCi0gIC8qKiBjZWlsaW5nIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfQ0VJTElOR19TVFJJTkcgPSAiY2VpbGluZyI7Ci0KLSAgLyoqIHJvdW5kIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfUk9VTkRfU1RSSU5HID0gInJvdW5kIjsKLQotICAvKiogc3VtIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1VNX1NUUklORyA9ICJzdW0iOwotCi0gIC8qKiBzdHJpbmcgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19TVFJJTkdfU1RSSU5HID0gInN0cmluZyI7Ci0KLSAgLyoqIHN0YXJ0cy13aXRoIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1RBUlRTX1dJVEhfU1RSSU5HID0gInN0YXJ0cy13aXRoIjsKLQotICAvKiogY29udGFpbnMgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19DT05UQUlOU19TVFJJTkcgPSAiY29udGFpbnMiOwotCi0gIC8qKiBzdWJzdHJpbmctYmVmb3JlIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1VCU1RSSU5HX0JFRk9SRV9TVFJJTkcgPQotICAgICJzdWJzdHJpbmctYmVmb3JlIjsKLQotICAvKiogc3Vic3RyaW5nLWFmdGVyIGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfU1VCU1RSSU5HX0FGVEVSX1NUUklORyA9ICJzdWJzdHJpbmctYWZ0ZXIiOwotCi0gIC8qKiBub3JtYWxpemUtc3BhY2UgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19OT1JNQUxJWkVfU1BBQ0VfU1RSSU5HID0gIm5vcm1hbGl6ZS1zcGFjZSI7Ci0KLSAgLyoqIHRyYW5zbGF0ZSBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1RSQU5TTEFURV9TVFJJTkcgPSAidHJhbnNsYXRlIjsKLQotICAvKiogY29uY2F0IGZ1bmN0aW9uIHN0cmluZy4gKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZVTkNfQ09OQ0FUX1NUUklORyA9ICJjb25jYXQiOwotCi0gIC8qKiBzeXN0ZW0tcHJvcGVydHkgZnVuY3Rpb24gc3RyaW5nLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19TWVNURU1fUFJPUEVSVFlfU1RSSU5HID0gInN5c3RlbS1wcm9wZXJ0eSI7Ci0KLSAgLyoqIGZ1bmN0aW9uLWF2YWlsYWJsZSBmdW5jdGlvbiBzdHJpbmcgKFhTTFQpLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19FWFRfRlVOQ1RJT05fQVZBSUxBQkxFX1NUUklORyA9Ci0gICAgImZ1bmN0aW9uLWF2YWlsYWJsZSI7Ci0KLSAgLyoqIGVsZW1lbnQtYXZhaWxhYmxlIGZ1bmN0aW9uIHN0cmluZyAoWFNMVCkuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX0VYVF9FTEVNX0FWQUlMQUJMRV9TVFJJTkcgPQotICAgICJlbGVtZW50LWF2YWlsYWJsZSI7Ci0KLSAgLyoqIHN1YnN0cmluZyBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1NVQlNUUklOR19TVFJJTkcgPSAic3Vic3RyaW5nIjsKLQotICAvKiogc3RyaW5nLWxlbmd0aCBmdW5jdGlvbiBzdHJpbmcuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1NUUklOR19MRU5HVEhfU1RSSU5HID0gInN0cmluZy1sZW5ndGgiOwotCi0gIC8qKiB1bnBhcnNlZC1lbnRpdHktdXJpIGZ1bmN0aW9uIHN0cmluZyAoWFNMVCkuICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGVU5DX1VOUEFSU0VEX0VOVElUWV9VUklfU1RSSU5HID0KLSAgICAidW5wYXJzZWQtZW50aXR5LXVyaSI7Ci0KLSAgLy8gUHJvcHJpZXRhcnksIGJ1aWx0IGluIGZ1bmN0aW9ucwotCi0gIC8qKiBjdXJyZW50IGZ1bmN0aW9uIHN0cmluZyAoUHJvcHJpZXRhcnkpLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRlVOQ19ET0NMT0NBVElPTl9TVFJJTkcgPSAiZG9jdW1lbnQtbG9jYXRpb24iOwotCi0gIHN0YXRpYwotICB7Ci0gICAgbV9heGlzbmFtZXMucHV0KEZST01fQU5DRVNUT1JTX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoT3BDb2Rlcy5GUk9NX0FOQ0VTVE9SUykpOwotICAgIG1fYXhpc25hbWVzLnB1dChGUk9NX0FOQ0VTVE9SU19PUl9TRUxGX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoT3BDb2Rlcy5GUk9NX0FOQ0VTVE9SU19PUl9TRUxGKSk7Ci0gICAgbV9heGlzbmFtZXMucHV0KEZST01fQVRUUklCVVRFU19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuRlJPTV9BVFRSSUJVVEVTKSk7Ci0gICAgbV9heGlzbmFtZXMucHV0KEZST01fQ0hJTERSRU5fU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLkZST01fQ0hJTERSRU4pKTsKLSAgICBtX2F4aXNuYW1lcy5wdXQoRlJPTV9ERVNDRU5EQU5UU19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UUykpOwotICAgIG1fYXhpc25hbWVzLnB1dChGUk9NX0RFU0NFTkRBTlRTX09SX1NFTEZfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLkZST01fREVTQ0VOREFOVFNfT1JfU0VMRikpOwotICAgIG1fYXhpc25hbWVzLnB1dChGUk9NX0ZPTExPV0lOR19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuRlJPTV9GT0xMT1dJTkcpKTsKLSAgICBtX2F4aXNuYW1lcy5wdXQoRlJPTV9GT0xMT1dJTkdfU0lCTElOR1NfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLkZST01fRk9MTE9XSU5HX1NJQkxJTkdTKSk7Ci0gICAgbV9heGlzbmFtZXMucHV0KEZST01fUEFSRU5UX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoT3BDb2Rlcy5GUk9NX1BBUkVOVCkpOwotICAgIG1fYXhpc25hbWVzLnB1dChGUk9NX1BSRUNFRElOR19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuRlJPTV9QUkVDRURJTkcpKTsKLSAgICBtX2F4aXNuYW1lcy5wdXQoRlJPTV9QUkVDRURJTkdfU0lCTElOR1NfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLkZST01fUFJFQ0VESU5HX1NJQkxJTkdTKSk7Ci0gICAgbV9heGlzbmFtZXMucHV0KEZST01fU0VMRl9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuRlJPTV9TRUxGKSk7Ci0gICAgbV9heGlzbmFtZXMucHV0KEZST01fTkFNRVNQQUNFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoT3BDb2Rlcy5GUk9NX05BTUVTUEFDRSkpOwotICAgIG1fbm9kZXR5cGVzLnB1dChOT0RFVFlQRV9DT01NRU5UX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoT3BDb2Rlcy5OT0RFVFlQRV9DT01NRU5UKSk7Ci0gICAgbV9ub2RldHlwZXMucHV0KE5PREVUWVBFX1RFWFRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLk5PREVUWVBFX1RFWFQpKTsKLSAgICBtX25vZGV0eXBlcy5wdXQoTk9ERVRZUEVfUElfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLk5PREVUWVBFX1BJKSk7Ci0gICAgbV9ub2RldHlwZXMucHV0KE5PREVUWVBFX05PREVfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLk5PREVUWVBFX05PREUpKTsKLSAgICBtX25vZGV0eXBlcy5wdXQoTk9ERVRZUEVfQU5ZRUxFTUVOVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuTk9ERVRZUEVfQU5ZRUxFTUVOVCkpOwotICAgIG1fa2V5d29yZHMucHV0KEZST01fU0VMRl9BQkJSRVZJQVRFRF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoT3BDb2Rlcy5GUk9NX1NFTEYpKTsKLSAgICBtX2tleXdvcmRzLnB1dChGVU5DX0lEX1NUUklORywKLSAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfSUQpKTsKLSAgICBtX2tleXdvcmRzLnB1dChGVU5DX0tFWV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0tFWSkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0NVUlJFTlRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfQ1VSUkVOVCkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0xBU1RfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTEFTVCkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1BPU0lUSU9OX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1BPU0lUSU9OKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfQ09VTlRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfQ09VTlQpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19JRF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19JRCkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0tFWV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19LRVkpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19MT0NBTF9QQVJUX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0xPQ0FMX1BBUlQpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19OQU1FU1BBQ0VfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfTkFNRVNQQUNFKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfTkFNRV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19RTkFNRSkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0dFTkVSQVRFX0lEX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0dFTkVSQVRFX0lEKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfTk9UX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX05PVCkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1RSVUVfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfVFJVRSkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0ZBTFNFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0ZBTFNFKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfQk9PTEVBTl9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19CT09MRUFOKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfTEFOR19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19MQU5HKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfTlVNQkVSX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX05VTUJFUikpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0ZMT09SX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0ZMT09SKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfQ0VJTElOR19TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19DRUlMSU5HKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfUk9VTkRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfUk9VTkQpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19TVU1fU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfU1VNKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfU1RSSU5HX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NUUklORykpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1NUQVJUU19XSVRIX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NUQVJUU19XSVRIKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfQ09OVEFJTlNfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfQ09OVEFJTlMpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19TVUJTVFJJTkdfQkVGT1JFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NVQlNUUklOR19CRUZPUkUpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19TVUJTVFJJTkdfQUZURVJfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfU1VCU1RSSU5HX0FGVEVSKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfTk9STUFMSVpFX1NQQUNFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX05PUk1BTElaRV9TUEFDRSkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1RSQU5TTEFURV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19UUkFOU0xBVEUpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19DT05DQVRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfQ09OQ0FUKSk7Ci0KLSAgICAvL21fZnVuY3Rpb25zLnB1dChGVU5DX0ZPUk1BVF9OVU1CRVJfU1RSSU5HLCBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfRk9STUFUX05VTUJFUikpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1NZU1RFTV9QUk9QRVJUWV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKEZ1bmN0aW9uVGFibGUuRlVOQ19TWVNURU1fUFJPUEVSVFkpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19FWFRfRlVOQ1RJT05fQVZBSUxBQkxFX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0VYVF9GVU5DVElPTl9BVkFJTEFCTEUpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoRlVOQ19FWFRfRUxFTV9BVkFJTEFCTEVfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfRVhUX0VMRU1fQVZBSUxBQkxFKSk7Ci0gICAgbV9mdW5jdGlvbnMucHV0KEZVTkNfU1VCU1RSSU5HX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX1NVQlNUUklORykpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1NUUklOR19MRU5HVEhfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfU1RSSU5HX0xFTkdUSCkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX1VOUEFSU0VEX0VOVElUWV9VUklfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihGdW5jdGlvblRhYmxlLkZVTkNfVU5QQVJTRURfRU5USVRZX1VSSSkpOwotCi0gICAgLy8gVGhlc2UgYXJlbid0IHJlYWxseSBmdW5jdGlvbnMuCi0gICAgbV9mdW5jdGlvbnMucHV0KE5PREVUWVBFX0NPTU1FTlRfU1RSSU5HLAotICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZWdlcihPcENvZGVzLk5PREVUWVBFX0NPTU1FTlQpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoTk9ERVRZUEVfVEVYVF9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuTk9ERVRZUEVfVEVYVCkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChOT0RFVFlQRV9QSV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuTk9ERVRZUEVfUEkpKTsKLSAgICBtX2Z1bmN0aW9ucy5wdXQoTk9ERVRZUEVfTk9ERV9TVFJJTkcsCi0gICAgICAgICAgICAgICAgICAgIG5ldyBJbnRlZ2VyKE9wQ29kZXMuTk9ERVRZUEVfTk9ERSkpOwotICAgIG1fZnVuY3Rpb25zLnB1dChGVU5DX0RPQ0xPQ0FUSU9OX1NUUklORywKLSAgICAgICAgICAgICAgICAgICAgbmV3IEludGVnZXIoRnVuY3Rpb25UYWJsZS5GVU5DX0RPQ0xPQ0FUSU9OKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiBhIGJ1aWx0LWluLCBub24tbmFtZXNwYWNlZCBmdW5jdGlvbiBpcyBhdmFpbGFibGUuCi0gICAqCi0gICAqIEBwYXJhbSBtZXRoTmFtZSBUaGUgbG9jYWwgbmFtZSBvZiB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZnVuY3Rpb24gY2FuIGJlIGV4ZWN1dGVkLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBib29sZWFuIGZ1bmN0aW9uQXZhaWxhYmxlKFN0cmluZyBtZXRoTmFtZSkKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgT2JqZWN0IHRibEVudHJ5ID0gbV9mdW5jdGlvbnMuZ2V0KG1ldGhOYW1lKTsKLQotICAgICAgaWYgKG51bGwgPT0gdGJsRW50cnkpCi0gICAgICAgIHJldHVybiBmYWxzZTsKLQotICAgICAgaW50IGZ1bmNUeXBlID0gKChJbnRlZ2VyKSB0YmxFbnRyeSkuaW50VmFsdWUoKTsKLQotICAgICAgc3dpdGNoIChmdW5jVHlwZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9DT01NRU5UIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9URVhUIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9QSSA6Ci0gICAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfTk9ERSA6Ci0gICAgICAgIHJldHVybiBmYWxzZTsgIC8vIFRoZXNlIGxvb2sgbGlrZSBmdW5jdGlvbnMgYnV0IHRoZXkncmUgTm9kZVRlc3RzLgotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvTGV4ZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL0xleGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAyMDBkZGQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvTGV4ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY5MSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuQ29tcGlsZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5PcENvZGVzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuWFBhdGhQYXJzZXI7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyBpbiBjaGFyZ2Ugb2YgbGV4aWNhbCBwcm9jZXNzaW5nIG9mIHRoZSBYUGF0aAotICogZXhwcmVzc2lvbiBpbnRvIHRva2Vucy4KLSAqLwotY2xhc3MgTGV4ZXIKLXsKLQotICAvKioKLSAgICogVGhlIHRhcmdldCBYUGF0aC4KLSAgICovCi0gIHByaXZhdGUgQ29tcGlsZXIgbV9jb21waWxlcjsKLQotICAvKioKLSAgICogVGhlIHByZWZpeCByZXNvbHZlciB0byBtYXAgcHJlZml4ZXMgdG8gbmFtZXNwYWNlcyBpbiB0aGUgWFBhdGguCi0gICAqLwotICBQcmVmaXhSZXNvbHZlciBtX25hbWVzcGFjZUNvbnRleHQ7Ci0KLSAgLyoqCi0gICAqIFRoZSBYUGF0aCBwcm9jZXNzb3Igb2JqZWN0LgotICAgKi8KLSAgWFBhdGhQYXJzZXIgbV9wcm9jZXNzb3I7Ci0KLSAgLyoqCi0gICAqIFRoaXMgdmFsdWUgaXMgYWRkZWQgdG8gZWFjaCBlbGVtZW50IG5hbWUgaW4gdGhlIFRBUkdFVEVYVFJBCi0gICAqIHRoYXQgaXMgYSAndGFyZ2V0JyAocmlnaHQtbW9zdCB0b3AtbGV2ZWwgZWxlbWVudCBuYW1lKS4KLSAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgVEFSR0VURVhUUkEgPSAxMDAwMDsKLQotICAvKioKLSAgICogSWdub3JlIHRoaXMsIGl0IGlzIGdvaW5nIGF3YXkuCi0gICAqIFRoaXMgaG9sZHMgYSBtYXAgdG8gdGhlIG1fdG9rZW5RdWV1ZSB0aGF0IHRlbGxzIHdoZXJlIHRoZSB0b3AtbGV2ZWwgZWxlbWVudHMgYXJlLgotICAgKiBJdCBpcyB1c2VkIGZvciBwYXR0ZXJuIG1hdGNoaW5nIHNvIHRoZSBtX3Rva2VuUXVldWUgY2FuIGJlIHdhbGtlZCBiYWNrd2FyZHMuCi0gICAqIEVhY2ggZWxlbWVudCB0aGF0IGlzIGEgJ3RhcmdldCcsIChyaWdodC1tb3N0IHRvcCBsZXZlbCBlbGVtZW50IG5hbWUpIGhhcwotICAgKiBUQVJHRVRFWFRSQSBhZGRlZCB0byBpdC4KLSAgICoKLSAgICovCi0gIHByaXZhdGUgaW50IG1fcGF0dGVybk1hcFtdID0gbmV3IGludFsxMDBdOwotCi0gIC8qKgotICAgKiBJZ25vcmUgdGhpcywgaXQgaXMgZ29pbmcgYXdheS4KLSAgICogVGhlIG51bWJlciBvZiBlbGVtZW50cyB0aGF0IG1fcGF0dGVybk1hcCBtYXBzOwotICAgKi8KLSAgcHJpdmF0ZSBpbnQgbV9wYXR0ZXJuTWFwU2l6ZTsKLQotICAvKioKLSAgICogQ3JlYXRlIGEgTGV4ZXIgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gY29tcGlsZXIgVGhlIG93bmluZyBjb21waWxlciBmb3IgdGhpcyBsZXhlci4KLSAgICogQHBhcmFtIHJlc29sdmVyIFRoZSBwcmVmaXggcmVzb2x2ZXIgZm9yIG1hcHBpbmcgcXVhbGlmaWVkIG5hbWUgcHJlZml4ZXMgCi0gICAqICAgICAgICAgICAgICAgICB0byBuYW1lc3BhY2UgVVJJcy4KLSAgICogQHBhcmFtIHhwYXRoUHJvY2Vzc29yIFRoZSBwYXJzZXIgdGhhdCBpcyBwcm9jZXNzaW5nIHN0cmluZ3MgdG8gb3Bjb2Rlcy4KLSAgICovCi0gIExleGVyKENvbXBpbGVyIGNvbXBpbGVyLCBQcmVmaXhSZXNvbHZlciByZXNvbHZlciwKLSAgICAgICAgWFBhdGhQYXJzZXIgeHBhdGhQcm9jZXNzb3IpCi0gIHsKLQotICAgIG1fY29tcGlsZXIgPSBjb21waWxlcjsKLSAgICBtX25hbWVzcGFjZUNvbnRleHQgPSByZXNvbHZlcjsKLSAgICBtX3Byb2Nlc3NvciA9IHhwYXRoUHJvY2Vzc29yOwotICB9Ci0KLSAgLyoqCi0gICAqIFdhbGsgdGhyb3VnaCB0aGUgZXhwcmVzc2lvbiBhbmQgYnVpbGQgYSB0b2tlbiBxdWV1ZSwgYW5kIGEgbWFwIG9mIHRoZSB0b3AtbGV2ZWwKLSAgICogZWxlbWVudHMuCi0gICAqIEBwYXJhbSBwYXQgWFNMVCBFeHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgdG9rZW5pemUoU3RyaW5nIHBhdCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHRva2VuaXplKHBhdCwgbnVsbCk7Ci0gIH0KLQotICAvKioKLSAgICogV2FsayB0aHJvdWdoIHRoZSBleHByZXNzaW9uIGFuZCBidWlsZCBhIHRva2VuIHF1ZXVlLCBhbmQgYSBtYXAgb2YgdGhlIHRvcC1sZXZlbAotICAgKiBlbGVtZW50cy4KLSAgICogQHBhcmFtIHBhdCBYU0xUIEV4cHJlc3Npb24uCi0gICAqIEBwYXJhbSB0YXJnZXRTdHJpbmdzIFZlY3RvciB0byBob2xkIFN0cmluZ3MsIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHZvaWQgdG9rZW5pemUoU3RyaW5nIHBhdCwgVmVjdG9yIHRhcmdldFN0cmluZ3MpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV9jb21waWxlci5tX3Rva2VuUXVldWVTaXplID0gMDsKLSAgICBtX2NvbXBpbGVyLm1fY3VycmVudFBhdHRlcm4gPSBwYXQ7Ci0gICAgbV9wYXR0ZXJuTWFwU2l6ZSA9IDA7Ci0gICAgbV9jb21waWxlci5tX29wTWFwID0gbmV3IGludFtPcE1hcC5NQVhUT0tFTlFVRVVFU0laRSAqIDVdOwotCi0gICAgaW50IG5DaGFycyA9IHBhdC5sZW5ndGgoKTsKLSAgICBpbnQgc3RhcnRTdWJzdHJpbmcgPSAtMTsKLSAgICBpbnQgcG9zT2ZOU1NlcCA9IC0xOwotICAgIGJvb2xlYW4gaXNTdGFydE9mUGF0ID0gdHJ1ZTsKLSAgICBib29sZWFuIGlzQXR0ck5hbWUgPSBmYWxzZTsKLSAgICBib29sZWFuIGlzTnVtID0gZmFsc2U7Ci0KLSAgICAvLyBOZXN0aW5nIG9mICdbJyBzbyB3ZSBjYW4ga25vdyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBzaG91bGQgYmUKLSAgICAvLyBjb3VudGVkIGluc2lkZSB0aGUgbV9wYXR0ZXJuTWFwLgotICAgIGludCBuZXN0aW5nID0gMDsKLQotICAgIC8vIGNoYXJbXSBjaGFycyA9IHBhdC50b0NoYXJBcnJheSgpOwotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkNoYXJzOyBpKyspCi0gICAgewotICAgICAgY2hhciBjID0gcGF0LmNoYXJBdChpKTsKLQotICAgICAgc3dpdGNoIChjKQotICAgICAgewotICAgICAgY2FzZSAnXCInIDoKLSAgICAgIHsKLSAgICAgICAgaWYgKHN0YXJ0U3Vic3RyaW5nICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgaXNOdW0gPSBmYWxzZTsKLSAgICAgICAgICBpc1N0YXJ0T2ZQYXQgPSBtYXBQYXR0ZXJuRWxlbVBvcyhuZXN0aW5nLCBpc1N0YXJ0T2ZQYXQsIGlzQXR0ck5hbWUpOwotICAgICAgICAgIGlzQXR0ck5hbWUgPSBmYWxzZTsKLQotICAgICAgICAgIGlmICgtMSAhPSBwb3NPZk5TU2VwKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBvc09mTlNTZXAgPSBtYXBOU1Rva2VucyhwYXQsIHN0YXJ0U3Vic3RyaW5nLCBwb3NPZk5TU2VwLCBpKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShwYXQuc3Vic3RyaW5nKHN0YXJ0U3Vic3RyaW5nLCBpKSk7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgc3RhcnRTdWJzdHJpbmcgPSBpOwotCi0gICAgICAgIGZvciAoaSsrOyAoaSA8IG5DaGFycykgJiYgKChjID0gcGF0LmNoYXJBdChpKSkgIT0gJ1wiJyk7IGkrKyk7Ci0KLSAgICAgICAgaWYgKGMgPT0gJ1wiJyAmJiBpIDwgbkNoYXJzKQotICAgICAgICB7Ci0gICAgICAgICAgYWRkVG9Ub2tlblF1ZXVlKHBhdC5zdWJzdHJpbmcoc3RhcnRTdWJzdHJpbmcsIGkgKyAxKSk7Ci0KLSAgICAgICAgICBzdGFydFN1YnN0cmluZyA9IC0xOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIG1fcHJvY2Vzc29yLmVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOyAgLy8ibWlzcXVvdGVkIGxpdGVyYWwuLi4gZXhwZWN0ZWQgZG91YmxlIHF1b3RlISIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBicmVhazsKLSAgICAgIGNhc2UgJ1wnJyA6Ci0gICAgICAgIGlmIChzdGFydFN1YnN0cmluZyAhPSAtMSkKLSAgICAgICAgewotICAgICAgICAgIGlzTnVtID0gZmFsc2U7Ci0gICAgICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLSAgICAgICAgICBpc0F0dHJOYW1lID0gZmFsc2U7Ci0KLSAgICAgICAgICBpZiAoLTEgIT0gcG9zT2ZOU1NlcCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwb3NPZk5TU2VwID0gbWFwTlNUb2tlbnMocGF0LCBzdGFydFN1YnN0cmluZywgcG9zT2ZOU1NlcCwgaSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgaSkpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gaTsKLQotICAgICAgICBmb3IgKGkrKzsgKGkgPCBuQ2hhcnMpICYmICgoYyA9IHBhdC5jaGFyQXQoaSkpICE9ICdcJycpOyBpKyspOwotCi0gICAgICAgIGlmIChjID09ICdcJycgJiYgaSA8IG5DaGFycykKLSAgICAgICAgewotICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShwYXQuc3Vic3RyaW5nKHN0YXJ0U3Vic3RyaW5nLCBpICsgMSkpOwotCi0gICAgICAgICAgc3RhcnRTdWJzdHJpbmcgPSAtMTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBtX3Byb2Nlc3Nvci5lcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0VYUEVDVEVEX1NJTkdMRV9RVU9URSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsgIC8vIm1pc3F1b3RlZCBsaXRlcmFsLi4uIGV4cGVjdGVkIHNpbmdsZSBxdW90ZSEiKTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgMHgwQSA6Ci0gICAgICBjYXNlIDB4MEQgOgotICAgICAgY2FzZSAnICcgOgotICAgICAgY2FzZSAnXHQnIDoKLSAgICAgICAgaWYgKHN0YXJ0U3Vic3RyaW5nICE9IC0xKQotICAgICAgICB7Ci0gICAgICAgICAgaXNOdW0gPSBmYWxzZTsKLSAgICAgICAgICBpc1N0YXJ0T2ZQYXQgPSBtYXBQYXR0ZXJuRWxlbVBvcyhuZXN0aW5nLCBpc1N0YXJ0T2ZQYXQsIGlzQXR0ck5hbWUpOwotICAgICAgICAgIGlzQXR0ck5hbWUgPSBmYWxzZTsKLQotICAgICAgICAgIGlmICgtMSAhPSBwb3NPZk5TU2VwKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBvc09mTlNTZXAgPSBtYXBOU1Rva2VucyhwYXQsIHN0YXJ0U3Vic3RyaW5nLCBwb3NPZk5TU2VwLCBpKTsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShwYXQuc3Vic3RyaW5nKHN0YXJ0U3Vic3RyaW5nLCBpKSk7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgc3RhcnRTdWJzdHJpbmcgPSAtMTsKLSAgICAgICAgfQotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgJ0AnIDoKLSAgICAgICAgaXNBdHRyTmFtZSA9IHRydWU7Ci0KLSAgICAgIC8vIGZhbGwtdGhyb3VnaCBvbiBwdXJwb3NlCi0gICAgICBjYXNlICctJyA6Ci0gICAgICAgIGlmICgnLScgPT0gYykKLSAgICAgICAgewotICAgICAgICAgIGlmICghKGlzTnVtIHx8IChzdGFydFN1YnN0cmluZyA9PSAtMSkpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgIH0KLQotICAgICAgICAgIGlzTnVtID0gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgLy8gZmFsbC10aHJvdWdoIG9uIHB1cnBvc2UKLSAgICAgIGNhc2UgJygnIDoKLSAgICAgIGNhc2UgJ1snIDoKLSAgICAgIGNhc2UgJyknIDoKLSAgICAgIGNhc2UgJ10nIDoKLSAgICAgIGNhc2UgJ3wnIDoKLSAgICAgIGNhc2UgJy8nIDoKLSAgICAgIGNhc2UgJyonIDoKLSAgICAgIGNhc2UgJysnIDoKLSAgICAgIGNhc2UgJz0nIDoKLSAgICAgIGNhc2UgJywnIDoKLSAgICAgIGNhc2UgJ1xcJyA6ICAvLyBVbnVzZWQgYXQgdGhlIG1vbWVudAotICAgICAgY2FzZSAnXicgOiAgLy8gVW51c2VkIGF0IHRoZSBtb21lbnQKLSAgICAgIGNhc2UgJyEnIDogIC8vIFVudXNlZCBhdCB0aGUgbW9tZW50Ci0gICAgICBjYXNlICckJyA6Ci0gICAgICBjYXNlICc8JyA6Ci0gICAgICBjYXNlICc+JyA6Ci0gICAgICAgIGlmIChzdGFydFN1YnN0cmluZyAhPSAtMSkKLSAgICAgICAgewotICAgICAgICAgIGlzTnVtID0gZmFsc2U7Ci0gICAgICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLSAgICAgICAgICBpc0F0dHJOYW1lID0gZmFsc2U7Ci0KLSAgICAgICAgICBpZiAoLTEgIT0gcG9zT2ZOU1NlcCkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwb3NPZk5TU2VwID0gbWFwTlNUb2tlbnMocGF0LCBzdGFydFN1YnN0cmluZywgcG9zT2ZOU1NlcCwgaSk7Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgaSkpOwotICAgICAgICAgIH0KLQotICAgICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gLTE7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoKCcvJyA9PSBjKSAmJiBpc1N0YXJ0T2ZQYXQpCi0gICAgICAgIHsKLSAgICAgICAgICBpc1N0YXJ0T2ZQYXQgPSBtYXBQYXR0ZXJuRWxlbVBvcyhuZXN0aW5nLCBpc1N0YXJ0T2ZQYXQsIGlzQXR0ck5hbWUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKCcqJyA9PSBjKQotICAgICAgICB7Ci0gICAgICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLSAgICAgICAgICBpc0F0dHJOYW1lID0gZmFsc2U7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAoMCA9PSBuZXN0aW5nKQotICAgICAgICB7Ci0gICAgICAgICAgaWYgKCd8JyA9PSBjKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChudWxsICE9IHRhcmdldFN0cmluZ3MpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHJlY29yZFRva2VuU3RyaW5nKHRhcmdldFN0cmluZ3MpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpc1N0YXJ0T2ZQYXQgPSB0cnVlOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIGlmICgoJyknID09IGMpIHx8ICgnXScgPT0gYykpCi0gICAgICAgIHsKLSAgICAgICAgICBuZXN0aW5nLS07Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZSBpZiAoKCcoJyA9PSBjKSB8fCAoJ1snID09IGMpKQotICAgICAgICB7Ci0gICAgICAgICAgbmVzdGluZysrOwotICAgICAgICB9Ci0KLSAgICAgICAgYWRkVG9Ub2tlblF1ZXVlKHBhdC5zdWJzdHJpbmcoaSwgaSArIDEpKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlICc6JyA6Ci0gICAgICAgIGlmIChpPjApCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAocG9zT2ZOU1NlcCA9PSAoaSAtIDEpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGlmIChzdGFydFN1YnN0cmluZyAhPSAtMSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgaWYgKHN0YXJ0U3Vic3RyaW5nIDwgKGkgLSAxKSkKLSAgICAgICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgaSAtIDEpKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgaXNOdW0gPSBmYWxzZTsKLSAgICAgICAgICAgIGlzQXR0ck5hbWUgPSBmYWxzZTsKLSAgICAgICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gLTE7Ci0gICAgICAgICAgICBwb3NPZk5TU2VwID0gLTE7Ci0KLSAgICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShwYXQuc3Vic3RyaW5nKGkgLSAxLCBpICsgMSkpOwotCi0gICAgICAgICAgICBicmVhazsKLSAgICAgICAgICB9Ci0gICAgICAgICAgZWxzZQotICAgICAgICAgIHsKLSAgICAgICAgICAgIHBvc09mTlNTZXAgPSBpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAvLyBmYWxsIHRocm91Z2ggb24gcHVycG9zZQotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIGlmICgtMSA9PSBzdGFydFN1YnN0cmluZykKLSAgICAgICAgewotICAgICAgICAgIHN0YXJ0U3Vic3RyaW5nID0gaTsKLSAgICAgICAgICBpc051bSA9IENoYXJhY3Rlci5pc0RpZ2l0KGMpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UgaWYgKGlzTnVtKQotICAgICAgICB7Ci0gICAgICAgICAgaXNOdW0gPSBDaGFyYWN0ZXIuaXNEaWdpdChjKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIGlmIChzdGFydFN1YnN0cmluZyAhPSAtMSkKLSAgICB7Ci0gICAgICBpc051bSA9IGZhbHNlOwotICAgICAgaXNTdGFydE9mUGF0ID0gbWFwUGF0dGVybkVsZW1Qb3MobmVzdGluZywgaXNTdGFydE9mUGF0LCBpc0F0dHJOYW1lKTsKLQotICAgICAgaWYgKC0xICE9IHBvc09mTlNTZXApCi0gICAgICB7Ci0gICAgICAgIHBvc09mTlNTZXAgPSBtYXBOU1Rva2VucyhwYXQsIHN0YXJ0U3Vic3RyaW5nLCBwb3NPZk5TU2VwLCBuQ2hhcnMpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBhZGRUb1Rva2VuUXVldWUocGF0LnN1YnN0cmluZyhzdGFydFN1YnN0cmluZywgbkNoYXJzKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKDAgPT0gbV9jb21waWxlci5tX3Rva2VuUXVldWVTaXplKQotICAgIHsKLSAgICAgIG1fcHJvY2Vzc29yLmVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRU1QVFlfRVhQUkVTU0lPTiwgbnVsbCk7ICAvLyJFbXB0eSBleHByZXNzaW9uISIpOwotICAgIH0KLSAgICBlbHNlIGlmIChudWxsICE9IHRhcmdldFN0cmluZ3MpCi0gICAgewotICAgICAgcmVjb3JkVG9rZW5TdHJpbmcodGFyZ2V0U3RyaW5ncyk7Ci0gICAgfQotCi0gICAgbV9wcm9jZXNzb3IubV9xdWV1ZU1hcmsgPSAwOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY29yZCB0aGUgY3VycmVudCBwb3NpdGlvbiBvbiB0aGUgdG9rZW4gcXVldWUgYXMgbG9uZyBhcwotICAgKiB0aGlzIGlzIGEgdG9wLWxldmVsIGVsZW1lbnQuICBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgdGhlCi0gICAqIG5leHQgdG9rZW4gaXMgYWRkZWQgdG8gdGhlIG1fdG9rZW5RdWV1ZS4KLSAgICoKLSAgICogQHBhcmFtIG5lc3RpbmcgVGhlIG5lc3RpbmcgY291bnQgZm9yIHRoZSBwYXR0ZXJuIGVsZW1lbnQuCi0gICAqIEBwYXJhbSBpc1N0YXJ0IHRydWUgaWYgdGhpcyBpcyB0aGUgc3RhcnQgb2YgYSBwYXR0ZXJuLgotICAgKiBAcGFyYW0gaXNBdHRyTmFtZSB0cnVlIGlmIHdlIGhhdmUgZGV0ZXJtaW5lZCB0aGF0IHRoaXMgaXMgYW4gYXR0cmlidXRlIG5hbWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIHRoZSBzdGFydCBvZiBhIHBhdHRlcm4uCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbWFwUGF0dGVybkVsZW1Qb3MoaW50IG5lc3RpbmcsIGJvb2xlYW4gaXNTdGFydCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNBdHRyTmFtZSkKLSAgewotCi0gICAgaWYgKDAgPT0gbmVzdGluZykKLSAgICB7Ci0gICAgICBpZihtX3BhdHRlcm5NYXBTaXplID49IG1fcGF0dGVybk1hcC5sZW5ndGgpCi0gICAgICB7Ci0gICAgICAgIGludCBwYXR0ZXJuTWFwW10gPSBtX3BhdHRlcm5NYXA7Ci0gICAgICAgIGludCBsZW4gPSBtX3BhdHRlcm5NYXAubGVuZ3RoOwotICAgICAgICBtX3BhdHRlcm5NYXAgPSBuZXcgaW50W21fcGF0dGVybk1hcFNpemUgKyAxMDBdOwotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBhdHRlcm5NYXAsIDAsIG1fcGF0dGVybk1hcCwgMCwgbGVuKTsKLSAgICAgIH0gCi0gICAgICBpZiAoIWlzU3RhcnQpCi0gICAgICB7Ci0gICAgICAgIG1fcGF0dGVybk1hcFttX3BhdHRlcm5NYXBTaXplIC0gMV0gLT0gVEFSR0VURVhUUkE7Ci0gICAgICB9Ci0gICAgICBtX3BhdHRlcm5NYXBbbV9wYXR0ZXJuTWFwU2l6ZV0gPQotICAgICAgICAobV9jb21waWxlci5tX3Rva2VuUXVldWVTaXplIC0gKGlzQXR0ck5hbWUgPyAxIDogMCkpICsgVEFSR0VURVhUUkE7Ci0KLSAgICAgIG1fcGF0dGVybk1hcFNpemUrKzsKLQotICAgICAgaXNTdGFydCA9IGZhbHNlOwotICAgIH0KLQotICAgIHJldHVybiBpc1N0YXJ0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgbWFwIHBvcywgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIHRva2VuIHF1ZXVlIHBvcy4KLSAgICoKLSAgICogQHBhcmFtIGkgVGhlIGluZGV4IGluIHRoZSBtX3BhdHRlcm5NYXAuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHRva2VuIHF1ZXVlIHBvc2l0aW9uLgotICAgKi8KLSAgcHJpdmF0ZSBpbnQgZ2V0VG9rZW5RdWV1ZVBvc0Zyb21NYXAoaW50IGkpCi0gIHsKLQotICAgIGludCBwb3MgPSBtX3BhdHRlcm5NYXBbaV07Ci0KLSAgICByZXR1cm4gKHBvcyA+PSBUQVJHRVRFWFRSQSkgPyAocG9zIC0gVEFSR0VURVhUUkEpIDogcG9zOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlc2V0IHRva2VuIHF1ZXVlIG1hcmsgYW5kIG1fdG9rZW4gdG8gYQotICAgKiBnaXZlbiBwb3NpdGlvbi4KLSAgICogQHBhcmFtIG1hcmsgVGhlIG5ldyBwb3NpdGlvbi4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgdm9pZCByZXNldFRva2VuTWFyayhpbnQgbWFyaykKLSAgewotCi0gICAgaW50IHFzeiA9IG1fY29tcGlsZXIubV90b2tlblF1ZXVlU2l6ZTsKLQotICAgIG1fcHJvY2Vzc29yLm1fcXVldWVNYXJrID0gKG1hcmsgPiAwKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoKG1hcmsgPD0gcXN6KSA/IG1hcmsgLSAxIDogbWFyaykgOiAwOwotCi0gICAgaWYgKG1fcHJvY2Vzc29yLm1fcXVldWVNYXJrIDwgcXN6KQotICAgIHsKLSAgICAgIG1fcHJvY2Vzc29yLm1fdG9rZW4gPQotICAgICAgICAoU3RyaW5nKSBtX2NvbXBpbGVyLm1fdG9rZW5RdWV1ZVttX3Byb2Nlc3Nvci5tX3F1ZXVlTWFyaysrXTsKLSAgICAgIG1fcHJvY2Vzc29yLm1fdG9rZW5DaGFyID0gbV9wcm9jZXNzb3IubV90b2tlbi5jaGFyQXQoMCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX3Byb2Nlc3Nvci5tX3Rva2VuID0gbnVsbDsKLSAgICAgIG1fcHJvY2Vzc29yLm1fdG9rZW5DaGFyID0gMDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBzdHJpbmcsIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBrZXl3b3JkIHRva2VuLgotICAgKgotICAgKiBAcGFyYW0ga2V5IFRoZSBrZXl3b3JkLgotICAgKgotICAgKiBAcmV0dXJuIEFuIG9wY29kZSB2YWx1ZS4KLSAgICovCi0gIGZpbmFsIGludCBnZXRLZXl3b3JkVG9rZW4oU3RyaW5nIGtleSkKLSAgewotCi0gICAgaW50IHRvazsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIEludGVnZXIgaXRvayA9IChJbnRlZ2VyKSBLZXl3b3Jkcy5tX2tleXdvcmRzLmdldChrZXkpOwotCi0gICAgICB0b2sgPSAobnVsbCAhPSBpdG9rKSA/IGl0b2suaW50VmFsdWUoKSA6IDA7Ci0gICAgfQotICAgIGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpCi0gICAgewotICAgICAgdG9rID0gMDsKLSAgICB9Ci0gICAgY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpCi0gICAgewotICAgICAgdG9rID0gMDsKLSAgICB9Ci0KLSAgICByZXR1cm4gdG9rOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlY29yZCB0aGUgY3VycmVudCB0b2tlbiBpbiB0aGUgcGFzc2VkIHZlY3Rvci4KLSAgICoKLSAgICogQHBhcmFtIHRhcmdldFN0cmluZ3MgVmVjdG9yIG9mIHN0cmluZy4KLSAgICovCi0gIHByaXZhdGUgdm9pZCByZWNvcmRUb2tlblN0cmluZyhWZWN0b3IgdGFyZ2V0U3RyaW5ncykKLSAgewotCi0gICAgaW50IHRva1BvcyA9IGdldFRva2VuUXVldWVQb3NGcm9tTWFwKG1fcGF0dGVybk1hcFNpemUgLSAxKTsKLQotICAgIHJlc2V0VG9rZW5NYXJrKHRva1BvcyArIDEpOwotCi0gICAgaWYgKG1fcHJvY2Vzc29yLmxvb2thaGVhZCgnKCcsIDEpKQotICAgIHsKLSAgICAgIGludCB0b2sgPSBnZXRLZXl3b3JkVG9rZW4obV9wcm9jZXNzb3IubV90b2tlbik7Ci0KLSAgICAgIHN3aXRjaCAodG9rKQotICAgICAgewotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX0NPTU1FTlQgOgotICAgICAgICB0YXJnZXRTdHJpbmdzLmFkZEVsZW1lbnQoUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9DT01NRU5UKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfVEVYVCA6Ci0gICAgICAgIHRhcmdldFN0cmluZ3MuYWRkRWxlbWVudChQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX1RFWFQpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9OT0RFIDoKLSAgICAgICAgdGFyZ2V0U3RyaW5ncy5hZGRFbGVtZW50KFBzdWVkb05hbWVzLlBTRVVET05BTUVfQU5ZKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUk9PVCA6Ci0gICAgICAgIHRhcmdldFN0cmluZ3MuYWRkRWxlbWVudChQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX1JPT1QpOwotICAgICAgICBicmVhazsKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9BTllFTEVNRU5UIDoKLSAgICAgICAgdGFyZ2V0U3RyaW5ncy5hZGRFbGVtZW50KFBzdWVkb05hbWVzLlBTRVVET05BTUVfQU5ZKTsKLSAgICAgICAgYnJlYWs7Ci0gICAgICBjYXNlIE9wQ29kZXMuTk9ERVRZUEVfUEkgOgotICAgICAgICB0YXJnZXRTdHJpbmdzLmFkZEVsZW1lbnQoUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9BTlkpOwotICAgICAgICBicmVhazsKLSAgICAgIGRlZmF1bHQgOgotICAgICAgICB0YXJnZXRTdHJpbmdzLmFkZEVsZW1lbnQoUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9BTlkpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaWYgKG1fcHJvY2Vzc29yLnRva2VuSXMoJ0AnKSkKLSAgICAgIHsKLSAgICAgICAgdG9rUG9zKys7Ci0KLSAgICAgICAgcmVzZXRUb2tlbk1hcmsodG9rUG9zICsgMSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChtX3Byb2Nlc3Nvci5sb29rYWhlYWQoJzonLCAxKSkKLSAgICAgIHsKLSAgICAgICAgdG9rUG9zICs9IDI7Ci0gICAgICB9Ci0KLSAgICAgIHRhcmdldFN0cmluZ3MuYWRkRWxlbWVudChtX2NvbXBpbGVyLm1fdG9rZW5RdWV1ZVt0b2tQb3NdKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQWRkIGEgdG9rZW4gdG8gdGhlIHRva2VuIHF1ZXVlLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcyBUaGUgdG9rZW4uCi0gICAqLwotICBwcml2YXRlIGZpbmFsIHZvaWQgYWRkVG9Ub2tlblF1ZXVlKFN0cmluZyBzKQotICB7Ci0gICAgbV9jb21waWxlci5tX3Rva2VuUXVldWVbbV9jb21waWxlci5tX3Rva2VuUXVldWVTaXplKytdID0gczsKLSAgfQotCi0gIC8qKgotICAgKiBXaGVuIGEgc2VwZXJhdG9yIHRva2VuIGlzIGZvdW5kLCBzZWUgaWYgdGhlcmUncyBhIGVsZW1lbnQgbmFtZSBvcgotICAgKiB0aGUgbGlrZSB0byBtYXAuCi0gICAqCi0gICAqIEBwYXJhbSBwYXQgVGhlIFhQYXRoIG5hbWUgc3RyaW5nLgotICAgKiBAcGFyYW0gc3RhcnRTdWJzdHJpbmcgVGhlIHN0YXJ0IG9mIHRoZSBuYW1lIHN0cmluZy4KLSAgICogQHBhcmFtIHBvc09mTlNTZXAgVGhlIHBvc2l0aW9uIG9mIHRoZSBuYW1lc3BhY2Ugc2VwZXJhdG9yICgnOicpLgotICAgKiBAcGFyYW0gcG9zT2ZTY2FuIFRoZSBlbmQgb2YgdGhlIG5hbWUgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKgotICAgKiBAcmV0dXJuIC0xIGFsd2F5cy4KLSAgICovCi0gIHByaXZhdGUgaW50IG1hcE5TVG9rZW5zKFN0cmluZyBwYXQsIGludCBzdGFydFN1YnN0cmluZywgaW50IHBvc09mTlNTZXAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwb3NPZlNjYW4pCi0gICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gewotCi0gICAgU3RyaW5nIHByZWZpeCA9IHBhdC5zdWJzdHJpbmcoc3RhcnRTdWJzdHJpbmcsIHBvc09mTlNTZXApOwotICAgIFN0cmluZyB1TmFtZTsKLQotICAgIGlmICgobnVsbCAhPSBtX25hbWVzcGFjZUNvbnRleHQpICYmIXByZWZpeC5lcXVhbHMoIioiKQotICAgICAgICAgICAgJiYhcHJlZml4LmVxdWFscygieG1sbnMiKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaWYgKHByZWZpeC5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgdU5hbWUgPSAoKFByZWZpeFJlc29sdmVyKSBtX25hbWVzcGFjZUNvbnRleHQpLmdldE5hbWVzcGFjZUZvclByZWZpeCgKLSAgICAgICAgICAgIHByZWZpeCk7Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotCi0gICAgICAgICAgLy8gQXNzdW1lIGxhc3Qgd2FzIHdpbGRjYXJkLiBUaGlzIGlzIG5vdCBsZWdhbCBhY2NvcmRpbmcKLSAgICAgICAgICAvLyB0byB0aGUgZHJhZnQuIFNldCB0aGUgYmVsb3cgdG8gdHJ1ZSB0byBtYWtlIG5hbWVzcGFjZQotICAgICAgICAgIC8vIHdpbGRjYXJkcyB3b3JrLgotICAgICAgICAgIGlmIChmYWxzZSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBhZGRUb1Rva2VuUXVldWUoIjoiKTsKLQotICAgICAgICAgICAgU3RyaW5nIHMgPSBwYXQuc3Vic3RyaW5nKHBvc09mTlNTZXAgKyAxLCBwb3NPZlNjYW4pOwotCi0gICAgICAgICAgICBpZiAocy5sZW5ndGgoKSA+IDApCi0gICAgICAgICAgICAgIGFkZFRvVG9rZW5RdWV1ZShzKTsKLQotICAgICAgICAgICAgcmV0dXJuIC0xOwotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgdU5hbWUgPQotICAgICAgICAgICAgICAoKFByZWZpeFJlc29sdmVyKSBtX25hbWVzcGFjZUNvbnRleHQpLmdldE5hbWVzcGFjZUZvclByZWZpeCgKLSAgICAgICAgICAgICAgICBwcmVmaXgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpCi0gICAgICB7Ci0gICAgICAgIHVOYW1lID0gbV9uYW1lc3BhY2VDb250ZXh0LmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdU5hbWUgPSBwcmVmaXg7Ci0gICAgfQotCi0gICAgaWYgKChudWxsICE9IHVOYW1lKSAmJiAodU5hbWUubGVuZ3RoKCkgPiAwKSkKLSAgICB7Ci0gICAgICBhZGRUb1Rva2VuUXVldWUodU5hbWUpOwotICAgICAgYWRkVG9Ub2tlblF1ZXVlKCI6Iik7Ci0KLSAgICAgIFN0cmluZyBzID0gcGF0LnN1YnN0cmluZyhwb3NPZk5TU2VwICsgMSwgcG9zT2ZTY2FuKTsKLQotICAgICAgaWYgKHMubGVuZ3RoKCkgPiAwKQotICAgICAgICBhZGRUb1Rva2VuUXVldWUocyk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0KLSAgICAgIC8vIGVycm9yKCJDb3VsZCBub3QgbG9jYXRlIG5hbWVzcGFjZSBmb3IgcHJlZml4OiAiK3ByZWZpeCk7Ci0gICAgICBtX3Byb2Nlc3Nvci5lcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1BSRUZJWF9NVVNUX1JFU09MVkUsCi0gICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7cHJlZml4fSk7ICAvLyJQcmVmaXggbXVzdCByZXNvbHZlIHRvIGEgbmFtZXNwYWNlOiB7MH0iOwotCi0KLSAgICAgIC8qKiogIE9sZCBjb2RlIGNvbW1lbnRlZCBvdXQgMTAtSmFuLTIwMDEKLSAgICAgIGFkZFRvVG9rZW5RdWV1ZShwcmVmaXgpOwotICAgICAgYWRkVG9Ub2tlblF1ZXVlKCI6Iik7Ci0KLSAgICAgIFN0cmluZyBzID0gcGF0LnN1YnN0cmluZyhwb3NPZk5TU2VwICsgMSwgcG9zT2ZTY2FuKTsKLQotICAgICAgaWYgKHMubGVuZ3RoKCkgPiAwKQotICAgICAgICBhZGRUb1Rva2VuUXVldWUocyk7Ci0gICAgICAqKiovCi0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9PcENvZGVzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9PcENvZGVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJhYzBhNjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvT3BDb2Rlcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjY4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXI7Ci0KLS8qKgotICogT3BlcmF0aW9ucyBjb2RlcyBmb3IgWFBhdGguCi0gKgotICogQ29kZSBmb3IgdGhlIGRlc2NyaXB0aW9ucyBvZiB0aGUgb3BlcmF0aW9ucyBjb2RlczoKLSAqIFtVUFBFUiBDQVNFXSBpbmRpY2F0ZXMgYSBsaXRlcmFsIHZhbHVlLAotICogW2xvd2VyIGNhc2VdIGlzIGEgZGVzY3JpcHRpb24gb2YgYSB2YWx1ZSwKLSAqICAgICAgKFtsZW5ndGhdIGFsd2F5cyBpbmRpY2F0ZXMgdGhlIGxlbmd0aCBvZiB0aGUgb3BlcmF0aW9uLAotICogICAgICAgaW5jbHVkaW5nIHRoZSBvcGVyYXRpb25zIGNvZGUgYW5kIHRoZSBsZW5ndGggaW50ZWdlci4pCi0gKiB7VVBQRVIgQ0FTRX0gaW5kaWNhdGVzIHRoZSBnaXZlbiBwcm9kdWN0aW9uLAotICoge2Rlc2NyaXB0aW9ufSBpcyB0aGUgZGVzY3JpcHRpb24gb2YgYSBuZXcgcHJvZHVjdGlvbiwKLSAqICAgICAgKEZvciBpbnN0YW5jZSwge2Jvb2xlYW4gZXhwcmVzc2lvbn0gbWVhbnMgc29tZSBleHByZXNzaW9uCi0gKiAgICAgICB0aGF0IHNob3VsZCBiZSByZXNvbHZlZCB0byBhIGJvb2xlYW4uKQotICogICogbWVhbnMgdGhhdCBpdCBvY2N1cnMgemVybyBvciBtb3JlIHRpbWVzLAotICogICsgbWVhbnMgdGhhdCBpdCBvY2N1cnMgb25lIG9yIG1vcmUgdGltZXMsCi0gKiAgPyBtZWFucyB0aGF0IGl0IGlzIG9wdGlvbmFsLgotICoKLSAqIHJldHVybnM6IGluZGljYXRlcyB3aGF0IHRoZSBwcm9kdWN0aW9uIHNob3VsZCByZXR1cm4uCi0gKi8KLXB1YmxpYyBjbGFzcyBPcENvZGVzCi17Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbRU5ET1BdCi0gICAqIFNvbWUgb3BlcmF0b3JzIG1heSBsaWtlIHRvIGhhdmUgYSB0ZXJtaW5hdG9yLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5ET1AgPSAtMTsKLQotICAvKioKLSAgICogW0VNUFRZXQotICAgKiBFbXB0eSBzbG90IHRvIGluZGljYXRlIE5VTEwuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTVBUWSA9IC0yOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW0VMRU1XSUxEQ0FSRF0KLSAgICogTWVhbnMgRUxFTVdJTERDQVJEICgiKiIpLCB1c2VkIGluc3RlYWQKLSAgICogb2Ygc3RyaW5nIGluZGV4IGluIHNvbWUgcGxhY2VzLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRUxFTVdJTERDQVJEID0gLTM7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfWFBBVEhdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqICBYTnVtYmVyCi0gICAqICBYU3RyaW5nCi0gICAqICBYQm9vbGVhbgotICAgKiAgWFJUcmVlCi0gICAqICBYT2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9YUEFUSCA9IDE7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfT1JdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7Ym9vbGVhbiBleHByZXNzaW9ufQotICAgKiAge2Jvb2xlYW4gZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9PUiA9IDI7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfQU5EXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2Jvb2xlYW4gZXhwcmVzc2lvbn0KLSAgICogIHtib29sZWFuIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfQU5EID0gMzsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9OT1RFUVVBTFNdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICogIHtleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX05PVEVRVUFMUyA9IDQ7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfRVFVQUxTXQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9FUVVBTFMgPSA1OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX0xURV0gKGxlc3MtdGhhbi1vci1lcXVhbHMpCi0gICAqIFtsZW5ndGhdCi0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqICB7bnVtYmVyIGV4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfTFRFID0gNjsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9MVF0gKGxlc3MtdGhhbikKLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9MVCA9IDc7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfR1RFXSAoZ3JlYXRlci10aGFuLW9yLWVxdWFscykKLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9HVEUgPSA4OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX0dUXSAoZ3JlYXRlci10aGFuKQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0dUID0gOTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9QTFVTXQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE51bWJlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfUExVUyA9IDEwOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX01JTlVTXQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE51bWJlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfTUlOVVMgPSAxMTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9NVUxUXQotICAgKiBbbGVuZ3RoXQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKiAge251bWJlciBleHByZXNzaW9ufQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE51bWJlcgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfTVVMVCA9IDEyOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX0RJVl0KLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0RJViA9IDEzOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX01PRF0KLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX01PRCA9IDE0OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX1FVT10KLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1FVTyA9IDE1OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX05FR10KLSAgICogW2xlbmd0aF0KLSAgICogIHtudW1iZXIgZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX05FRyA9IDE2OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX1NUUklOR10gKGNhc3Qgb3BlcmF0aW9uKQotICAgKiBbbGVuZ3RoXQotICAgKiAge2V4cHJlc3Npb259Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYU3RyaW5nCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9TVFJJTkcgPSAxNzsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9CT09MXSAoY2FzdCBvcGVyYXRpb24pCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9CT09MID0gMTg7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfTlVNQkVSXSAoY2FzdCBvcGVyYXRpb24pCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9OVU1CRVIgPSAxOTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9VTklPTl0KLSAgICogW2xlbmd0aF0KLSAgICogIHtQYXRoRXhwcn0rCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTm9kZVNldAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfVU5JT04gPSAyMDsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9MSVRFUkFMXQotICAgKiBbM10KLSAgICogW2luZGV4IHRvIHRva2VuXQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWFN0cmluZwotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfTElURVJBTCA9IDIxOwotCi0gIC8qKiBUaGUgbG93IG9wY29kZSBmb3Igbm9kZXNldHMsIG5lZWRlZCBieSBnZXRGaXJzdFByZWRpY2F0ZU9wUG9zIGFuZCAKLSAgICogIGdldE5leHRTdGVwUG9zLiAgICAgICAgICAqLwotICBzdGF0aWMgZmluYWwgaW50IEZJUlNUX05PREVTRVRfT1AgPSAyMjsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9WQVJJQUJMRV0KLSAgICogWzRdCi0gICAqIFtpbmRleCB0byBuYW1lc3BhY2UgdG9rZW4sIG9yIEVNUFRZXQotICAgKiBbaW5kZXggdG8gZnVuY3Rpb24gbmFtZSB0b2tlbl0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhTdHJpbmcKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1ZBUklBQkxFID0gMjI7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfR1JPVVBdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqICBYTnVtYmVyCi0gICAqICBYU3RyaW5nCi0gICAqICBYQm9vbGVhbgotICAgKiAgWFJUcmVlCi0gICAqICBYT2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9HUk9VUCA9IDIzOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX0VYVEZVTkNUSU9OXSAoRXh0ZW5zaW9uIGZ1bmN0aW9uLikKLSAgICogW2xlbmd0aF0KLSAgICogW2luZGV4IHRvIG5hbWVzcGFjZSB0b2tlbl0KLSAgICogW2luZGV4IHRvIGZ1bmN0aW9uIG5hbWUgdG9rZW5dCi0gICAqICB7T1BfQVJHVU1FTlR9Ci0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTm9kZVNldAotICAgKiAgWE51bWJlcgotICAgKiAgWFN0cmluZwotICAgKiAgWEJvb2xlYW4KLSAgICogIFhSVHJlZQotICAgKiAgWE9iamVjdAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfRVhURlVOQ1RJT04gPSAyNDsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9GVU5DVElPTl0KLSAgICogW2xlbmd0aF0KLSAgICogW0ZVTkNfbmFtZV0KLSAgICogIHtPUF9BUkdVTUVOVH0KLSAgICogW0VORE9QXQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWE5vZGVTZXQKLSAgICogIFhOdW1iZXIKLSAgICogIFhTdHJpbmcKLSAgICogIFhCb29sZWFuCi0gICAqICBYUlRyZWUKLSAgICogIFhPYmplY3QKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0ZVTkNUSU9OID0gMjU7Ci0KLSAgLyoqIFRoZSBsYXN0IG9wY29kZSBmb3Igc3R1ZmYgdGhhdCBjYW4gYmUgYSBub2Rlc2V0LiAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBpbnQgTEFTVF9OT0RFU0VUX09QID0gMjU7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfQVJHVU1FTlRdIChGdW5jdGlvbiBhcmd1bWVudC4pCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqICBYTnVtYmVyCi0gICAqICBYU3RyaW5nCi0gICAqICBYQm9vbGVhbgotICAgKiAgWFJUcmVlCi0gICAqICBYT2JqZWN0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9BUkdVTUVOVCA9IDI2OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX05VTUJFUkxJVF0gKE51bWJlciBsaXRlcmFsLikKLSAgICogWzNdCi0gICAqIFtpbmRleCB0byB0b2tlbl0KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhTdHJpbmcKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX05VTUJFUkxJVCA9IDI3OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX0xPQ0FUSU9OUEFUSF0KLSAgICogW2xlbmd0aF0KLSAgICogICB7RlJPTV9zdGVwVHlwZX0KLSAgICogfCB7ZnVuY3Rpb259Ci0gICAqIHtwcmVkaWNhdGV9Ci0gICAqIFtFTkRPUF0KLSAgICoKLSAgICogKE5vdGUgdGhhdCBlbGVtZW50IGFuZCBhdHRyaWJ1dGUgbmFtZXNwYWNlcyBhbmQKLSAgICogbmFtZXMgY2FuIGJlIHdpbGRjYXJkZWQgJyonLikKLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhOb2RlU2V0Ci0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9MT0NBVElPTlBBVEggPSAyODsKLQotICAvLyBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT0NBVElPTlBBVEhFWF9NQVNLID0gMHgwMDAwRkZGRjsKLSAgLy8gcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9DQVRJT05QQVRIRVhfSVNTSU1QTEUgPSAweDAwMDEwMDAwOwotICAvLyBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUF9MT0NBVElPTlBBVEhfRVggPSAoMjggfCAweDAwMDEwMDAwKTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtPUF9QUkVESUNBVEVdCi0gICAqIFtsZW5ndGhdCi0gICAqICB7ZXhwcmVzc2lvbn0KLSAgICogW0VORE9QXSAoRm9yIHNhZmV0eSkKLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuIG9yIFhOdW1iZXIKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX1BSRURJQ0FURSA9IDI5OwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW09QX01BVENIUEFUVEVSTl0KLSAgICogW2xlbmd0aF0KLSAgICogIHtQYXRoRXhwcn0rCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYTm9kZVNldAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BfTUFUQ0hQQVRURVJOID0gMzA7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbT1BfTE9DQVRJT05QQVRIUEFUVEVSTl0KLSAgICogW2xlbmd0aF0KLSAgICogICB7RlJPTV9zdGVwVHlwZX0KLSAgICogfCB7ZnVuY3Rpb259e3ByZWRpY2F0ZX0KLSAgICogW0VORE9QXQotICAgKiByZXR1cm5zOgotICAgKiAgWE5vZGVTZXQKLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QX0xPQ0FUSU9OUEFUSFBBVFRFUk4gPSAzMTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtOT0RFVFlQRV9DT01NRU5UXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICogTm90ZTogbXVzdCBub3Qgb3ZlcmxhcCBmdW5jdGlvbiBPUCBudW1iZXIhCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERVRZUEVfQ09NTUVOVCA9IDEwMzA7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbTk9ERVRZUEVfVEVYVF0KLSAgICogTm8gc2l6ZSBvciBhcmd1bWVudHMuCi0gICAqIE5vdGU6IG11c3Qgbm90IG92ZXJsYXAgZnVuY3Rpb24gT1AgbnVtYmVyIQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PREVUWVBFX1RFWFQgPSAxMDMxOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogW05PREVUWVBFX1BJXQotICAgKiBbaW5kZXggdG8gdG9rZW5dCi0gICAqIE5vdGU6IG11c3Qgbm90IG92ZXJsYXAgZnVuY3Rpb24gT1AgbnVtYmVyIQotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PREVUWVBFX1BJID0gMTAzMjsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtOT0RFVFlQRV9OT0RFXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICogTm90ZTogbXVzdCBub3Qgb3ZlcmxhcCBmdW5jdGlvbiBPUCBudW1iZXIhCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERVRZUEVfTk9ERSA9IDEwMzM7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbTk9ERU5BTUVdCi0gICAqIFtpbmRleCB0byBucyB0b2tlbiBvciBFTVBUWV0KLSAgICogW2luZGV4IHRvIG5hbWUgdG9rZW5dCi0gICAqCi0gICAqIHJldHVybnM6Ci0gICAqICBYQm9vbGVhbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9ERU5BTUUgPSAzNDsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIFtOT0RFVFlQRV9ST09UXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT0RFVFlQRV9ST09UID0gMzU7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbTk9ERVRZUEVfQU5ZXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT0RFVFlQRV9BTllFTEVNRU5UID0gMzY7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbTk9ERVRZUEVfQU5ZXQotICAgKiBObyBzaXplIG9yIGFyZ3VtZW50cy4KLSAgICoKLSAgICogcmV0dXJuczoKLSAgICogIFhCb29sZWFuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT0RFVFlQRV9GVU5DVEVTVCA9IDEwMzQ7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBbRlJPTV9zdGVwVHlwZV0KLSAgICogW2xlbmd0aCwgaW5jbHVkaW5nIHByZWRpY2F0ZXNdCi0gICAqIFtsZW5ndGggb2YganVzdCB0aGUgc3RlcCwgd2l0aG91dCB0aGUgcHJlZGljYXRlc10KLSAgICoge25vZGUgdGVzdH0KLSAgICoge3ByZWRpY2F0ZXN9PwotICAgKgotICAgKiByZXR1cm5zOgotICAgKiAgWEJvb2xlYW4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFYRVNfU1RBUlRfVFlQRVMgPSAzNzsKLQotICAvKiogYW5jZXN0b3IgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9BTkNFU1RPUlMgPSAzNzsKLQotICAvKiogYW5jZXN0b3Itb3Itc2VsZiBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0FOQ0VTVE9SU19PUl9TRUxGID0gMzg7Ci0KLSAgLyoqIGF0dHJpYnV0ZSBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0FUVFJJQlVURVMgPSAzOTsKLQotICAvKiogY2hpbGRyZW4gYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9DSElMRFJFTiA9IDQwOwotCi0gIC8qKiBkZXNjZW5kYW50cyBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0RFU0NFTkRBTlRTID0gNDE7Ci0KLSAgLyoqIGRlc2NlbmRhbnRzLW9mLXNlbGYgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGID0gNDI7Ci0KLSAgLyoqIGZvbGxvd2luZyBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX0ZPTExPV0lORyA9IDQzOwotCi0gIC8qKiBmb2xsb3dpbmctc2libGluZ3MgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9GT0xMT1dJTkdfU0lCTElOR1MgPSA0NDsKLQotICAvKiogcGFyZW50IGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fUEFSRU5UID0gNDU7Ci0KLSAgLyoqIHByZWNlZGluZyBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX1BSRUNFRElORyA9IDQ2OwotCi0gIC8qKiBwcmVjZWRpbmctc2libGluZyBheGVzIG9wY29kZS4gICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGUk9NX1BSRUNFRElOR19TSUJMSU5HUyA9IDQ3OwotCi0gIC8qKiBzZWxmIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fU0VMRiA9IDQ4OwotCi0gIC8qKiBuYW1lc3BhY2UgYXhlcyBvcGNvZGUuICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRlJPTV9OQU1FU1BBQ0UgPSA0OTsKLQotICAvKiogJy8nIGF4ZXMgb3Bjb2RlLiAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZST01fUk9PVCA9IDUwOwotCi0gIC8qKgotICAgKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAgICogRm9yIG1hdGNoIHBhdHRlcm5zLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFUQ0hfQVRUUklCVVRFID0gNTE7Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICAgKiBGb3IgbWF0Y2ggcGF0dGVybnMuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVRDSF9BTllfQU5DRVNUT1IgPSA1MjsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gICAqIEZvciBtYXRjaCBwYXR0ZXJucy4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BVENIX0lNTUVESUFURV9BTkNFU1RPUiA9IDUzOwotCi0gIC8qKiBUaGUgZW5kIG9mIHRoZSBheGVzIHR5cGVzLiAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBWEVTX0VORF9UWVBFUyA9IDUzOwotCi0gIC8qKiBUaGUgbmV4dCBmcmVlIElELiAgUGxlYXNlIGtlZXAgdGhpcyB1cCB0byBkYXRlLiAgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5FWFRfRlJFRV9JRCA9IDk5OwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvT3BNYXAuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL09wTWFwLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkwZDBiNDMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvT3BNYXAuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5MCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3Q7Ci0KLS8qKgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHRoZSBkYXRhIHN0cnVjdHVyZSBiYXNpY3Mgb2YgdGhlIFhQYXRoCi0gKiBvYmplY3QuCi0gKi8KLXB1YmxpYyBjbGFzcyBPcE1hcAotewotCi0gIC8qKgotICAgKiBUaGUgY3VycmVudCBwYXR0ZXJuIHN0cmluZywgZm9yIGRpYWdub3N0aWNzIHB1cnBvc2VzCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIG1fY3VycmVudFBhdHRlcm47Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgZXhwcmVzc2lvbiBhcyBhIHN0cmluZyBmb3IgZGlhZ25vc3RpY3MuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGV4cHJlc3Npb24gc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV9jdXJyZW50UGF0dGVybjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGV4cHJlc3Npb24gYXMgYSBzdHJpbmcgZm9yIGRpYWdub3N0aWNzLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBleHByZXNzaW9uIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0UGF0dGVyblN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gbV9jdXJyZW50UGF0dGVybjsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbWF4IHNpemUgdGhhdCB0aGUgdG9rZW4gcXVldWUgY2FuIGdyb3cgdG8uCi0gICAqLwotICBzdGF0aWMgZmluYWwgaW50IE1BWFRPS0VOUVVFVUVTSVpFID0gNTAwOwotCi0gIC8qKgotICAgKiAgVG9rZW5TdGFjayBpcyB0aGUgcXVldWUgb2YgdXNlZCB0b2tlbnMuIFRoZSBjdXJyZW50IHRva2VuIGlzIHRoZSB0b2tlbiBhdCB0aGUKLSAgICogZW5kIG9mIHRoZSBtX3Rva2VuUXVldWUuIFRoZSBpZGVhIGlzIHRoYXQgdGhlIHF1ZXVlIGNhbiBiZSBtYXJrZWQgYW5kIGEgc2VxdWVuY2UKLSAgICogb2YgdG9rZW5zIGNhbiBiZSByZXVzZWQuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0W10gbV90b2tlblF1ZXVlID0gbmV3IE9iamVjdFtNQVhUT0tFTlFVRVVFU0laRV07Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgWFBhdGggYXMgYSBsaXN0IG9mIHRva2Vucy4KLSAgICoKLSAgICogQHJldHVybiBhbiBhcnJheSBvZiBzdHJpbmcgdG9rZW5zLgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdIGdldFRva2VuUXVldWUoKQotICB7Ci0gICAgcmV0dXJuIG1fdG9rZW5RdWV1ZTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhQYXRoIGFzIGEgbGlzdCBvZiB0b2tlbnMuCi0gICAqCi0gICAqIEBwYXJhbSBwb3MgaW5kZXggaW50byB0b2tlbiBxdWV1ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgdG9rZW4sIG5vcm1hbGx5IGEgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIE9iamVjdCBnZXRUb2tlbihpbnQgcG9zKQotICB7Ci0gICAgcmV0dXJuIG1fdG9rZW5RdWV1ZVtwb3NdOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBjdXJyZW50IHNpemUgb2YgdGhlIHRva2VuIHF1ZXVlLgotICAgKi8KLSAgcHVibGljIGludCBtX3Rva2VuUXVldWVTaXplID0gMDsKLQotICAvKioKLSAgICAqIEdldCBzaXplIG9mIHRoZSB0b2tlbiBxdWV1ZS4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc2l6ZSBvZiB0aGUgdG9rZW4gcXVldWUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFRva2VuUXVldWVTaXplKCkKLSAgewotICAgIHJldHVybiBtX3Rva2VuUXVldWVTaXplOwotICB9Ci0KLSAgLyoqCi0gICAqIEFuIG9wZXJhdGlvbnMgbWFwIGlzIHVzZWQgaW5zdGVhZCBvZiBhIHByb3BlciBwYXJzZSB0cmVlLiAgSXQgY29udGFpbnMKLSAgICogb3BlcmF0aW9ucyBjb2RlcyBhbmQgaW5kZXhlcyBpbnRvIHRoZSBtX3Rva2VuUXVldWUuCi0gICAqIEkgdXNlIGFuIGFycmF5IGluc3RlYWQgb2YgYSBmdWxsIHBhcnNlIHRyZWUgaW4gb3JkZXIgdG8gY3V0IGRvd24KLSAgICogb24gdGhlIG51bWJlciBvZiBvYmplY3RzIGNyZWF0ZWQuCi0gICAqLwotICBwdWJsaWMgaW50IG1fb3BNYXBbXSA9IG51bGw7Ci0KLSAgLyoqCi0gICAgKiBHZXQgdGhlIG9wY29kZSBsaXN0IHRoYXQgZGVzY3JpYmVzIHRoZSBYUGF0aCBvcGVyYXRpb25zLiAgSXQgY29udGFpbnMKLSAgICogb3BlcmF0aW9ucyBjb2RlcyBhbmQgaW5kZXhlcyBpbnRvIHRoZSBtX3Rva2VuUXVldWUuCi0gICAqIEkgdXNlIGFuIGFycmF5IGluc3RlYWQgb2YgYSBmdWxsIHBhcnNlIHRyZWUgaW4gb3JkZXIgdG8gY3V0IGRvd24KLSAgICogb24gdGhlIG51bWJlciBvZiBvYmplY3RzIGNyZWF0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gYXJyYXkgb2YgaW50ZWdlcnMgdGhhdCBpcyB0aGUgb3Bjb2RlIGxpc3QgdGhhdCBkZXNjcmliZXMgdGhlIFhQYXRoIG9wZXJhdGlvbnMuCi0gICAqLwotICBwdWJsaWMgaW50W10gZ2V0T3BNYXAoKQotICB7Ci0gICAgcmV0dXJuIG1fb3BNYXA7Ci0gIH0KLQotICAvLyBQb3NpdGlvbiBpbmRleGVzCi0KLSAgLyoqCi0gICAqIFRoZSBsZW5ndGggaXMgYWx3YXlzIHRoZSBvcGNvZGUgcG9zaXRpb24gKyAxLgotICAgKiBMZW5ndGggaXMgYWx3YXlzIGV4cHJlc3NlZCBhcyB0aGUgb3Bjb2RlK2xlbmd0aCBieXRlcywKLSAgICogc28gaXQgaXMgYWx3YXlzIDIgb3IgZ3JlYXRlci4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUElOREVYX0xFTkdUSCA9IDE7Ci0KLSAgLyoqCi0gICAqIFJlcGxhY2UgdGhlIGxhcmdlIGFycmF5cwotICAgKiB3aXRoIGEgc21hbGwgYXJyYXkuCi0gICAqLwotICB2b2lkIHNocmluaygpCi0gIHsKLQotICAgIGludCBtYXBbXSA9IG1fb3BNYXA7Ci0gICAgaW50IG4gPSBtX29wTWFwW01BUElOREVYX0xFTkdUSF07Ci0gICAgOwotCi0gICAgbV9vcE1hcCA9IG5ldyBpbnRbbiArIDRdOwotCi0gICAgaW50IGk7Ci0KLSAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIG1fb3BNYXBbaV0gPSBtYXBbaV07Ci0gICAgfQotCi0gICAgbV9vcE1hcFtpXSA9IDA7Ci0gICAgbV9vcE1hcFtpICsgMV0gPSAwOwotICAgIG1fb3BNYXBbaSArIDJdID0gMDsKLQotICAgIE9iamVjdFtdIHRva2VucyA9IG1fdG9rZW5RdWV1ZTsKLQotICAgIG4gPSBtX3Rva2VuUXVldWVTaXplOwotICAgIG1fdG9rZW5RdWV1ZSA9IG5ldyBPYmplY3RbbiArIDRdOwotCi0gICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBtX3Rva2VuUXVldWVbaV0gPSB0b2tlbnNbaV07Ci0gICAgfQotCi0gICAgbV90b2tlblF1ZXVlW2ldID0gbnVsbDsKLSAgICBtX3Rva2VuUXVldWVbaSArIDFdID0gbnVsbDsKLSAgICBtX3Rva2VuUXVldWVbaSArIDJdID0gbnVsbDsKLSAgfQotCi0gIC8qKgotICAqIEdpdmVuIGFuIG9wZXJhdGlvbiBwb3NpdGlvbiwgcmV0dXJuIHRoZSBjdXJyZW50IG9wLgotICAgKgotICAgKiBAcGFyYW0gb3BQb3MgaW5kZXggaW50byBvcCBtYXAuCi0gICAqIEByZXR1cm4gdGhlIG9wIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIG9wUG9zIGFyZ3VtZW50LgotICAgKi8KLSAgcHVibGljIGludCBnZXRPcChpbnQgb3BQb3MpCi0gIHsKLSAgICByZXR1cm4gbV9vcE1hcFtvcFBvc107Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gb3BlcmF0aW9uIHBvc2l0aW9uLCByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiwgaS5lLiB0aGUKLSAgICogYmVnaW5uaW5nIG9mIHRoZSBuZXh0IG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIEFuIG9wIHBvc2l0aW9uIG9mIGFuIG9wZXJhdGlvbiBmb3Igd2hpY2ggdGhlcmUgaXMgYSBzaXplIAotICAgKiAgICAgICAgICAgICAgZW50cnkgZm9sbG93aW5nLgotICAgKiBAcmV0dXJuIHBvc2l0aW9uIG9mIG5leHQgb3BlcmF0aW9uIGluIG1fb3BNYXAuCi0gICAqLwotICBwdWJsaWMgaW50IGdldE5leHRPcFBvcyhpbnQgb3BQb3MpCi0gIHsKLSAgICByZXR1cm4gb3BQb3MgKyBtX29wTWFwW29wUG9zICsgMV07Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSBsb2NhdGlvbiBzdGVwIHBvc2l0aW9uLCByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiwgaS5lLiB0aGUKLSAgICogYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHN0ZXAuCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyB0aGUgcG9zaXRpb24gb2YgYSBsb2NhdGlvbiBzdGVwLgotICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgbmV4dCBsb2NhdGlvbiBzdGVwLgotICAgKi8KLSAgcHVibGljIGludCBnZXROZXh0U3RlcFBvcyhpbnQgb3BQb3MpCi0gIHsKLQotICAgIGludCBzdGVwVHlwZSA9IGdldE9wKG9wUG9zKTsKLQotICAgIGlmICgoc3RlcFR5cGUgPj0gT3BDb2Rlcy5BWEVTX1NUQVJUX1RZUEVTKQotICAgICAgICAgICAgJiYgKHN0ZXBUeXBlIDw9IE9wQ29kZXMuQVhFU19FTkRfVFlQRVMpKQotICAgIHsKLSAgICAgIHJldHVybiBnZXROZXh0T3BQb3Mob3BQb3MpOwotICAgIH0KLSAgICBlbHNlIGlmICgoc3RlcFR5cGUgPj0gT3BDb2Rlcy5GSVJTVF9OT0RFU0VUX09QKQotICAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkxBU1RfTk9ERVNFVF9PUCkpCi0gICAgewotICAgICAgaW50IG5ld09wUG9zID0gZ2V0TmV4dE9wUG9zKG9wUG9zKTsKLQotICAgICAgd2hpbGUgKE9wQ29kZXMuT1BfUFJFRElDQVRFID09IGdldE9wKG5ld09wUG9zKSkKLSAgICAgIHsKLSAgICAgICAgbmV3T3BQb3MgPSBnZXROZXh0T3BQb3MobmV3T3BQb3MpOwotICAgICAgfQotCi0gICAgICBzdGVwVHlwZSA9IGdldE9wKG5ld09wUG9zKTsKLQotICAgICAgaWYgKCEoKHN0ZXBUeXBlID49IE9wQ29kZXMuQVhFU19TVEFSVF9UWVBFUykKLSAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkFYRVNfRU5EX1RZUEVTKSkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBPcENvZGVzLkVORE9QOwotICAgICAgfQotCi0gICAgICByZXR1cm4gbmV3T3BQb3M7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKLSAgICAgICAgIlByb2dyYW1tZXIncyBhc3NlcnRpb24gaW4gZ2V0TmV4dFN0ZXBQb3M6IHVua25vd24gc3RlcFR5cGU6ICIKLSAgICAgICAgKyBzdGVwVHlwZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIG9wZXJhdGlvbiBwb3NpdGlvbiwgcmV0dXJuIHRoZSBlbmQgcG9zaXRpb24sIGkuZS4gdGhlCi0gICAqIGJlZ2lubmluZyBvZiB0aGUgbmV4dCBvcGVyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBvcE1hcCBUaGUgb3BlcmF0aW9ucyBtYXAuCi0gICAqIEBwYXJhbSBvcFBvcyBpbmRleCB0byBvcGVyYXRpb24sIGZvciB3aGljaCB0aGVyZSBpcyBhIHNpemUgZW50cnkgZm9sbG93aW5nLgotICAgKiBAcmV0dXJuIHBvc2l0aW9uIG9mIG5leHQgb3BlcmF0aW9uIGluIG1fb3BNYXAuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXROZXh0T3BQb3MoaW50W10gb3BNYXAsIGludCBvcFBvcykKLSAgewotICAgIHJldHVybiBvcFBvcyArIG9wTWFwW29wUG9zICsgMV07Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYW4gRlJPTV9zdGVwVHlwZSBwb3NpdGlvbiwgcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogZmlyc3QgcHJlZGljYXRlLCBpZiB0aGVyZSBpcyBvbmUsIG9yIGVsc2UgdGhpcyB3aWxsIHBvaW50Ci0gICAqIHRvIHRoZSBlbmQgb2YgdGhlIEZST01fc3RlcFR5cGUuCi0gICAqIEV4YW1wbGU6Ci0gICAqICBpbnQgcG9zT2ZQcmVkaWNhdGUgPSB4cGF0aC5nZXROZXh0T3BQb3Moc3RlcFBvcyk7Ci0gICAqICBib29sZWFuIGhhc1ByZWRpY2F0ZXMgPQotICAgKiAgICAgICAgICAgIE9wQ29kZXMuT1BfUFJFRElDQVRFID09IHhwYXRoLmdldE9wKHBvc09mUHJlZGljYXRlKTsKLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIHBvc2l0aW9uIG9mIEZST01fc3RlcFR5cGUgb3AuIAotICAgKiBAcmV0dXJuIHBvc2l0aW9uIG9mIHByZWRpY2F0ZSBpbiBGUk9NX3N0ZXBUeXBlIHN0cnVjdHVyZS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Rmlyc3RQcmVkaWNhdGVPcFBvcyhpbnQgb3BQb3MpCi0gICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBzdGVwVHlwZSA9IG1fb3BNYXBbb3BQb3NdOwotCi0gICAgaWYgKChzdGVwVHlwZSA+PSBPcENvZGVzLkFYRVNfU1RBUlRfVFlQRVMpCi0gICAgICAgICAgICAmJiAoc3RlcFR5cGUgPD0gT3BDb2Rlcy5BWEVTX0VORF9UWVBFUykpCi0gICAgewotICAgICAgcmV0dXJuIG9wUG9zICsgbV9vcE1hcFtvcFBvcyArIDJdOwotICAgIH0KLSAgICBlbHNlIGlmICgoc3RlcFR5cGUgPj0gT3BDb2Rlcy5GSVJTVF9OT0RFU0VUX09QKQotICAgICAgICAgICAgICYmIChzdGVwVHlwZSA8PSBPcENvZGVzLkxBU1RfTk9ERVNFVF9PUCkpCi0gICAgewotICAgICAgcmV0dXJuIG9wUG9zICsgbV9vcE1hcFtvcFBvcyArIDFdOwotICAgIH0KLSAgICBlbHNlIGlmKC0yID09IHN0ZXBUeXBlKQotICAgIHsKLSAgICAgIHJldHVybiAtMjsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGVycm9yKG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9PUENPREUsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IFN0cmluZy52YWx1ZU9mKHN0ZXBUeXBlKSB9KTsgIC8vIkVSUk9SISBVbmtub3duIG9wIGNvZGU6ICIrbV9vcE1hcFtvcFBvc10pOwotICAgICAgcmV0dXJuIC0xOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgdGhlIHVzZXIgb2YgYW4gZXJyb3IsIGFuZCBwcm9iYWJseSB0aHJvdyBhbgotICAgKiBleGNlcHRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbnVtYmVyIHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBudW1iZXJzIGZvdW5kIAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMgCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaCAKLSAgICogICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgRXJyb3JMaXN0b25lciBkZXRlcm1pbmVzIHRvIAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGVycm9yKGludCBtc2csIE9iamVjdFtdIGFyZ3MpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGphdmEubGFuZy5TdHJpbmcgZm1zZyA9IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotICAgIAotCi0gICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oZm1zZyk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBHbyB0byB0aGUgZmlyc3QgY2hpbGQgb2YgYSBnaXZlbiBvcGVyYXRpb24uCi0gICAqCi0gICAqIEBwYXJhbSBvcFBvcyBwb3NpdGlvbiBvZiBvcGVyYXRpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0Rmlyc3RDaGlsZFBvcyhpbnQgb3BQb3MpCi0gIHsKLSAgICByZXR1cm4gb3BQb3MgKyAyOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbGVuZ3RoIG9mIGFuIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFRoZSBwb3NpdGlvbiBvZiB0aGUgb3BlcmF0aW9uIGluIHRoZSBvcCBtYXAuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHNpemUgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0QXJnTGVuZ3RoKGludCBvcFBvcykKLSAgewotICAgIHJldHVybiBtX29wTWFwW29wUG9zICsgTUFQSU5ERVhfTEVOR1RIXTsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIGxvY2F0aW9uIHN0ZXAsIGdldCB0aGUgbGVuZ3RoIG9mIHRoYXQgc3RlcC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFBvc2l0aW9uIG9mIGxvY2F0aW9uIHN0ZXAgaW4gb3AgbWFwLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBsZW5ndGggb2YgdGhlIHN0ZXAuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEFyZ0xlbmd0aE9mU3RlcChpbnQgb3BQb3MpCi0gIHsKLSAgICByZXR1cm4gbV9vcE1hcFtvcFBvcyArIE1BUElOREVYX0xFTkdUSCArIDFdIC0gMzsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGZpcnN0IGNoaWxkIHBvc2l0aW9uIG9mIGEgZ2l2ZW4gbG9jYXRpb24gc3RlcC4KLSAgICoKLSAgICogQHBhcmFtIG9wUG9zIFBvc2l0aW9uIG9mIGxvY2F0aW9uIHN0ZXAgaW4gdGhlIGxvY2F0aW9uIG1hcC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmlyc3QgY2hpbGQgcG9zaXRpb24gb2YgdGhlIHN0ZXAuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGludCBnZXRGaXJzdENoaWxkUG9zT2ZTdGVwKGludCBvcFBvcykKLSAgewotICAgIHJldHVybiBvcFBvcyArIDM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSB0ZXN0IHR5cGUgb2YgdGhlIHN0ZXAsIGkuZS4gTk9ERVRZUEVfWFhYIHZhbHVlLgotICAgKiAKLSAgICogQHBhcmFtIG9wUG9zT2ZTdGVwIFRoZSBwb3NpdGlvbiBvZiB0aGUgRlJPTV9YWFggc3RlcC4KLSAgICoKLSAgICogQHJldHVybiBOT0RFVFlQRV9YWFggdmFsdWUuCi0gICAqLwotICBwdWJsaWMgaW50IGdldFN0ZXBUZXN0VHlwZShpbnQgb3BQb3NPZlN0ZXApCi0gIHsKLSAgICByZXR1cm4gbV9vcE1hcFtvcFBvc09mU3RlcCArIDNdOyAgLy8gc2tpcCBwYXN0IG9wLCBsZW4sIGxlbiB3aXRob3V0IHByZWRpY2F0ZXMKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBvZiB0aGUgc3RlcC4KLSAgICogCi0gICAqIEBwYXJhbSBvcFBvc09mU3RlcCBUaGUgcG9zaXRpb24gb2YgdGhlIEZST01fWFhYIHN0ZXAuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0ZXAncyBuYW1lc3BhY2UsIE5vZGVUZXN0LldJTEQsIG9yIG51bGwgZm9yIG51bGwgbmFtZXNwYWNlLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRTdGVwTlMoaW50IG9wUG9zT2ZTdGVwKQotICB7Ci0KLSAgICBpbnQgYXJnTGVuT2ZTdGVwID0gZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zT2ZTdGVwKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U3RlcE5TLmFyZ0xlbk9mU3RlcDogIithcmdMZW5PZlN0ZXApOwotICAgIGlmIChhcmdMZW5PZlN0ZXAgPT0gMykKLSAgICB7Ci0gICAgICBpbnQgaW5kZXggPSBtX29wTWFwW29wUG9zT2ZTdGVwICsgNF07Ci0KLSAgICAgIGlmIChpbmRleCA+PSAwKQotICAgICAgICByZXR1cm4gKFN0cmluZykgbV90b2tlblF1ZXVlW2luZGV4XTsKLSAgICAgIGVsc2UgaWYgKE9wQ29kZXMuRUxFTVdJTERDQVJEID09IGluZGV4KQotICAgICAgICByZXR1cm4gTm9kZVRlc3QuV0lMRDsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBudWxsOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgc3RlcC4KLSAgICogQHBhcmFtIG9wUG9zT2ZTdGVwIFRoZSBwb3NpdGlvbiBvZiB0aGUgRlJPTV9YWFggc3RlcC4KLSAgICoKLSAgICogQHJldHVybiBPcENvZGVzLkVNUFRZLCBPcENvZGVzLkVMRU1XSUxEQ0FSRCwgb3IgdGhlIGxvY2FsIG5hbWUuCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFN0ZXBMb2NhbE5hbWUoaW50IG9wUG9zT2ZTdGVwKQotICB7Ci0KLSAgICBpbnQgYXJnTGVuT2ZTdGVwID0gZ2V0QXJnTGVuZ3RoT2ZTdGVwKG9wUG9zT2ZTdGVwKTsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U3RlcExvY2FsTmFtZS5hcmdMZW5PZlN0ZXA6ICIrYXJnTGVuT2ZTdGVwKTsKLSAgICBpbnQgaW5kZXg7Ci0KLSAgICBzd2l0Y2ggKGFyZ0xlbk9mU3RlcCkKLSAgICB7Ci0gICAgY2FzZSAwIDoKLSAgICAgIGluZGV4ID0gT3BDb2Rlcy5FTVBUWTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgMSA6Ci0gICAgICBpbmRleCA9IE9wQ29kZXMuRUxFTVdJTERDQVJEOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSAyIDoKLSAgICAgIGluZGV4ID0gbV9vcE1hcFtvcFBvc09mU3RlcCArIDRdOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSAzIDoKLSAgICAgIGluZGV4ID0gbV9vcE1hcFtvcFBvc09mU3RlcCArIDVdOwotICAgICAgYnJlYWs7Ci0gICAgZGVmYXVsdCA6Ci0gICAgICBpbmRleCA9IE9wQ29kZXMuRU1QVFk7Ci0gICAgICBicmVhazsgIC8vIFNob3VsZCBhc3NlcnQgZXJyb3IKLSAgICB9Ci0KLSAgICAvLyBpbnQgaW5kZXggPSAoYXJnTGVuT2ZTdGVwID09IDMpID8gbV9vcE1hcFtvcFBvc09mU3RlcCs1XSAKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgoYXJnTGVuT2ZTdGVwID09IDEpID8gLTMgOiAtMik7Ci0gICAgaWYgKGluZGV4ID49IDApCi0gICAgICByZXR1cm4gKFN0cmluZykgbV90b2tlblF1ZXVlW2luZGV4XS50b1N0cmluZygpOwotICAgIGVsc2UgaWYgKE9wQ29kZXMuRUxFTVdJTERDQVJEID09IGluZGV4KQotICAgICAgcmV0dXJuIE5vZGVUZXN0LldJTEQ7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvUHN1ZWRvTmFtZXMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL1BzdWVkb05hbWVzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGY4MGQxZDkuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvUHN1ZWRvTmFtZXMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXI7Ci0KLS8qKgotICogVGhpcyBpcyB1c2VkIHRvIHJlcHJlc2VudCBuYW1lcyBvZiBub2RlcyB0aGF0IG1heSBub3QgYmUgbmFtZWQsIGxpa2UgYSAKLSAqIGNvbW1lbnQgbm9kZS4KLSAqLwotcHVibGljIGNsYXNzIFBzdWVkb05hbWVzCi17Ci0KLSAgLyoqCi0gICAqIFBzdWVkbyBuYW1lIGZvciBhIHdpbGQgY2FyZCBwYXR0ZXJuICgnKicpLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFNFVURPTkFNRV9BTlkgPSAiKiI7Ci0KLSAgLyoqCi0gICAqIFBzdWVkbyBuYW1lIGZvciB0aGUgcm9vdCBub2RlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFNFVURPTkFNRV9ST09UID0gIi8iOwotCi0gIC8qKgotICAgKiBQc3VlZG8gbmFtZSBmb3IgYSB0ZXh0IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQU0VVRE9OQU1FX1RFWFQgPSAiI3RleHQiOwotCi0gIC8qKgotICAgKiBQc3VlZG8gbmFtZSBmb3IgYSBjb21tZW50IG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQU0VVRE9OQU1FX0NPTU1FTlQgPSAiI2NvbW1lbnQiOwotCi0gIC8qKgotICAgKiBQc3VlZG8gbmFtZSBmb3IgYSBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5vZGUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQU0VVRE9OQU1FX1BJID0gIiNwaSI7Ci0KLSAgLyoqCi0gICAqIFBzdWVkbyBuYW1lIGZvciBhbiB1bmtub3duIHR5cGUgdmFsdWUuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQU0VVRE9OQU1FX09USEVSID0gIioiOwotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvWFBhdGhEdW1wZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL1hQYXRoRHVtcGVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGQ2NjBhNzUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvWFBhdGhEdW1wZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5YUGF0aFBhcnNlcjsKLQotLyoqCi0gKiBDbGFzcyBmb3IgWFBhdGggZGlhZ25vc3RpYyBmdW5jdGlvbnMuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aER1bXBlcgotewotCi0gIC8vIGRlbGV0ZWQgZm9yIHRoZSB0aW1lIGJlaW5nLgotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvWFBhdGhQYXJzZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyL1hQYXRoUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg0ZGQ1ZDUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvWFBhdGhQYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIxODAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5jb21waWxlcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Db21waWxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb247Ci1pbXBvcnQgb3JnLnhtbC5zYXguTG9jYXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLkxvY2F0b3JJbXBsOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRva2VuaXplcyBhbmQgcGFyc2VzIFhQYXRoIGV4cHJlc3Npb25zLiBUaGlzIHNob3VsZCByZWFsbHkgYmUgbmFtZWQKLSAqIFhQYXRoUGFyc2VySW1wbCwgYW5kIG1heSBiZSByZW5hbWVkIGluIHRoZSBmdXR1cmUuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUGF0aFBhcnNlcgotewotCi0gIC8qKgotICAgKiBUaGUgWFBhdGggdG8gYmUgcHJvY2Vzc2VkLgotICAgKi8KLSAgcHJpdmF0ZSBPcE1hcCBtX29wczsKLQotICAvKioKLSAgICogVGhlIG5leHQgdG9rZW4gaW4gdGhlIHBhdHRlcm4uCi0gICAqLwotICB0cmFuc2llbnQgU3RyaW5nIG1fdG9rZW47Ci0KLSAgLyoqCi0gICAqIFRoZSBmaXJzdCBjaGFyIGluIG1fdG9rZW4sIHRoZSB0aGVvcnkgYmVpbmcgdGhhdCB0aGlzCi0gICAqIGlzIGFuIG9wdGltaXphdGlvbiBiZWNhdXNlIHdlIHdvbid0IGhhdmUgdG8gZG8gY2hhckF0KDApIGFzCi0gICAqIG9mdGVuLgotICAgKi8KLSAgdHJhbnNpZW50IGNoYXIgbV90b2tlbkNoYXIgPSAwOwotCi0gIC8qKgotICAgKiBUaGUgcG9zaXRpb24gaW4gdGhlIHRva2VuIHF1ZXVlIGlzIHRyYWNrZWQgYnkgbV9xdWV1ZU1hcmsuCi0gICAqLwotICBpbnQgbV9xdWV1ZU1hcmsgPSAwOwotCi0gIC8qKgotICAgKiBUaGUgcGFyc2VyIGNvbnN0cnVjdG9yLgotICAgKi8KLSAgcHVibGljIFhQYXRoUGFyc2VyKEVycm9yTGlzdGVuZXIgZXJyb3JMaXN0ZW5lciwgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2VMb2NhdG9yIHNvdXJjZUxvY2F0b3IpCi0gIHsKLSAgICBtX2Vycm9yTGlzdGVuZXIgPSBlcnJvckxpc3RlbmVyOwotICAgIG1fc291cmNlTG9jYXRvciA9IHNvdXJjZUxvY2F0b3I7Ci0gIH0KLQotICAvKioKLSAgICogVGhlIHByZWZpeCByZXNvbHZlciB0byBtYXAgcHJlZml4ZXMgdG8gbmFtZXNwYWNlcyBpbiB0aGUgT3BNYXAuCi0gICAqLwotICBQcmVmaXhSZXNvbHZlciBtX25hbWVzcGFjZUNvbnRleHQ7Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIHN0cmluZywgaW5pdCBhbiBYUGF0aCBvYmplY3QgZm9yIHNlbGVjdGlvbnMsCi0gICAqIGluIG9yZGVyIHRoYXQgYSBwYXJzZSBkb2Vzbid0Ci0gICAqIGhhdmUgdG8gYmUgZG9uZSBlYWNoIHRpbWUgdGhlIGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkLgotICAgKiAKLSAgICogQHBhcmFtIGNvbXBpbGVyIFRoZSBjb21waWxlciBvYmplY3QuCi0gICAqIEBwYXJhbSBleHByZXNzaW9uIEEgc3RyaW5nIGNvbmZvcm1pbmcgdG8gdGhlIFhQYXRoIGdyYW1tYXIuCi0gICAqIEBwYXJhbSBuYW1lc3BhY2VDb250ZXh0IEFuIG9iamVjdCB0aGF0IGlzIGFibGUgdG8gcmVzb2x2ZSBwcmVmaXhlcyBpbgotICAgKiB0aGUgWFBhdGggdG8gbmFtZXNwYWNlcy4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbml0WFBhdGgoCi0gICAgICAgICAgQ29tcGlsZXIgY29tcGlsZXIsIFN0cmluZyBleHByZXNzaW9uLCBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgbV9vcHMgPSBjb21waWxlcjsKLSAgICBtX25hbWVzcGFjZUNvbnRleHQgPSBuYW1lc3BhY2VDb250ZXh0OwotCi0gICAgTGV4ZXIgbGV4ZXIgPSBuZXcgTGV4ZXIoY29tcGlsZXIsIG5hbWVzcGFjZUNvbnRleHQsIHRoaXMpOwotCi0gICAgbGV4ZXIudG9rZW5pemUoZXhwcmVzc2lvbik7Ci0KLSAgICBtX29wcy5tX29wTWFwWzBdID0gT3BDb2Rlcy5PUF9YUEFUSDsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gPSAyOwotCi0gICAgbmV4dFRva2VuKCk7Ci0gICAgRXhwcigpOwotCi0gICAgaWYgKG51bGwgIT0gbV90b2tlbikKLSAgICB7Ci0gICAgICBTdHJpbmcgZXh0cmFUb2tlbnMgPSAiIjsKLQotICAgICAgd2hpbGUgKG51bGwgIT0gbV90b2tlbikKLSAgICAgIHsKLSAgICAgICAgZXh0cmFUb2tlbnMgKz0gIiciICsgbV90b2tlbiArICInIjsKLQotICAgICAgICBuZXh0VG9rZW4oKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgICAgICAgIGV4dHJhVG9rZW5zICs9ICIsICI7Ci0gICAgICB9Ci0KLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IGV4dHJhVG9rZW5zIH0pOyAgLy8iRXh0cmEgaWxsZWdhbCB0b2tlbnM6ICIrZXh0cmFUb2tlbnMpOwotICAgIH0KLQotICAgIGNvbXBpbGVyLnNocmluaygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGFuIHN0cmluZywgaW5pdCBhbiBYUGF0aCBvYmplY3QgZm9yIHBhdHRlcm4gbWF0Y2hlcywKLSAgICogaW4gb3JkZXIgdGhhdCBhIHBhcnNlIGRvZXNuJ3QKLSAgICogaGF2ZSB0byBiZSBkb25lIGVhY2ggdGltZSB0aGUgZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQuCi0gICAqIEBwYXJhbSBjb21waWxlciBUaGUgWFBhdGggb2JqZWN0IHRvIGJlIGluaXRpYWxpemVkLgotICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBBIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIFhQYXRoLgotICAgKiBAcGFyYW0gbmFtZXNwYWNlQ29udGV4dCBBbiBvYmplY3QgdGhhdCBpcyBhYmxlIHRvIHJlc29sdmUgcHJlZml4ZXMgaW4KLSAgICogdGhlIFhQYXRoIHRvIG5hbWVzcGFjZXMuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgaW5pdE1hdGNoUGF0dGVybigKLSAgICAgICAgICBDb21waWxlciBjb21waWxlciwgU3RyaW5nIGV4cHJlc3Npb24sIFByZWZpeFJlc29sdmVyIG5hbWVzcGFjZUNvbnRleHQpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBtX29wcyA9IGNvbXBpbGVyOwotICAgIG1fbmFtZXNwYWNlQ29udGV4dCA9IG5hbWVzcGFjZUNvbnRleHQ7Ci0KLSAgICBMZXhlciBsZXhlciA9IG5ldyBMZXhlcihjb21waWxlciwgbmFtZXNwYWNlQ29udGV4dCwgdGhpcyk7Ci0KLSAgICBsZXhlci50b2tlbml6ZShleHByZXNzaW9uKTsKLQotICAgIG1fb3BzLm1fb3BNYXBbMF0gPSBPcENvZGVzLk9QX01BVENIUEFUVEVSTjsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gPSAyOwotCi0gICAgbmV4dFRva2VuKCk7Ci0gICAgUGF0dGVybigpOwotCi0gICAgaWYgKG51bGwgIT0gbV90b2tlbikKLSAgICB7Ci0gICAgICBTdHJpbmcgZXh0cmFUb2tlbnMgPSAiIjsKLQotICAgICAgd2hpbGUgKG51bGwgIT0gbV90b2tlbikKLSAgICAgIHsKLSAgICAgICAgZXh0cmFUb2tlbnMgKz0gIiciICsgbV90b2tlbiArICInIjsKLQotICAgICAgICBuZXh0VG9rZW4oKTsKLQotICAgICAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgICAgICAgIGV4dHJhVG9rZW5zICs9ICIsICI7Ci0gICAgICB9Ci0KLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IGV4dHJhVG9rZW5zIH0pOyAgLy8iRXh0cmEgaWxsZWdhbCB0b2tlbnM6ICIrZXh0cmFUb2tlbnMpOwotICAgIH0KLQotICAgIC8vIFRlcm1pbmF0ZSBmb3Igc2FmZXR5LgotICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IE9wQ29kZXMuRU5ET1A7Ci0gICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdICs9IDE7Ci0KLSAgICBtX29wcy5zaHJpbmsoKTsKLSAgfQotCi0gIC8qKiBUaGUgZXJyb3IgbGlzdGVuZXIgd2hlcmUgc3ludGF4IGVycm9ycyBhcmUgdG8gYmUgc2VudC4KLSAgICovCi0gIHByaXZhdGUgRXJyb3JMaXN0ZW5lciBtX2Vycm9yTGlzdGVuZXI7Ci0gIAotICAvKiogVGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgWFBhdGguICovCi0gIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlTG9jYXRvciBtX3NvdXJjZUxvY2F0b3I7Ci0KLSAgLyoqCi0gICAqIEFsbG93IGFuIGFwcGxpY2F0aW9uIHRvIHJlZ2lzdGVyIGFuIGVycm9yIGV2ZW50IGhhbmRsZXIsIHdoZXJlIHN5bnRheCAKLSAgICogZXJyb3JzIHdpbGwgYmUgc2VudC4gIElmIHRoZSBlcnJvciBsaXN0ZW5lciBpcyBub3Qgc2V0LCBzeW50YXggZXJyb3JzIAotICAgKiB3aWxsIGJlIHNlbnQgdG8gU3lzdGVtLmVyci4KLSAgICogCi0gICAqIEBwYXJhbSBoYW5kbGVyIFJlZmVyZW5jZSB0byBlcnJvciBsaXN0ZW5lciB3aGVyZSBzeW50YXggZXJyb3JzIHdpbGwgYmUgCi0gICAqICAgICAgICAgICAgICAgIHNlbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRFcnJvckhhbmRsZXIoRXJyb3JMaXN0ZW5lciBoYW5kbGVyKQotICB7Ci0gICAgbV9lcnJvckxpc3RlbmVyID0gaGFuZGxlcjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgZXJyb3IgbGlzdGVuZXIuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGVycm9yIGxpc3RlbmVyLCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5IGJlIG51bGwsIGJ1dCBtYXkgYmUuCi0gICAqLwotICBwdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkKLSAgewotICAgIHJldHVybiBtX2Vycm9yTGlzdGVuZXI7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgd2hldGhlciBtX3Rva2VuIG1hdGNoZXMgdGhlIHRhcmdldCBzdHJpbmcuIAotICAgKgotICAgKiBAcGFyYW0gcyBBIHN0cmluZyByZWZlcmVuY2Ugb3IgbnVsbC4KLSAgICoKLSAgICogQHJldHVybiBJZiBtX3Rva2VuIGlzIG51bGwsIHJldHVybnMgZmFsc2UgKG9yIHRydWUgaWYgcyBpcyBhbHNvIG51bGwpLCBvciAKLSAgICogcmV0dXJuIHRydWUgaWYgdGhlIGN1cnJlbnQgdG9rZW4gbWF0Y2hlcyB0aGUgc3RyaW5nLCBlbHNlIGZhbHNlLgotICAgKi8KLSAgZmluYWwgYm9vbGVhbiB0b2tlbklzKFN0cmluZyBzKQotICB7Ci0gICAgcmV0dXJuIChtX3Rva2VuICE9IG51bGwpID8gKG1fdG9rZW4uZXF1YWxzKHMpKSA6IChzID09IG51bGwpOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHdoZXRoZXIgbV90b2tlbkNoYXI9PWMuIAotICAgKgotICAgKiBAcGFyYW0gYyBBIGNoYXJhY3RlciB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4gSWYgbV90b2tlbiBpcyBudWxsLCByZXR1cm5zIGZhbHNlLCBvciByZXR1cm4gdHJ1ZSBpZiBjIG1hdGNoZXMgCi0gICAqICAgICAgICAgdGhlIGN1cnJlbnQgdG9rZW4uCi0gICAqLwotICBmaW5hbCBib29sZWFuIHRva2VuSXMoY2hhciBjKQotICB7Ci0gICAgcmV0dXJuIChtX3Rva2VuICE9IG51bGwpID8gKG1fdG9rZW5DaGFyID09IGMpIDogZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogTG9vayBhaGVhZCBvZiB0aGUgY3VycmVudCB0b2tlbiBpbiBvcmRlciB0bwotICAgKiBtYWtlIGEgYnJhbmNoaW5nIGRlY2lzaW9uLgotICAgKgotICAgKiBAcGFyYW0gYyB0aGUgY2hhcmFjdGVyIHRvIGJlIHRlc3RlZCBmb3IuCi0gICAqIEBwYXJhbSBuIG51bWJlciBvZiB0b2tlbnMgdG8gbG9vayBhaGVhZC4gIE11c3QgYmUKLSAgICogZ3JlYXRlciB0aGFuIDEuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbmV4dCB0b2tlbiBtYXRjaGVzIHRoZSBjaGFyYWN0ZXIgYXJndW1lbnQuCi0gICAqLwotICBmaW5hbCBib29sZWFuIGxvb2thaGVhZChjaGFyIGMsIGludCBuKQotICB7Ci0KLSAgICBpbnQgcG9zID0gKG1fcXVldWVNYXJrICsgbik7Ci0gICAgYm9vbGVhbiBiOwotCi0gICAgaWYgKChwb3MgPD0gbV9vcHMubV90b2tlblF1ZXVlU2l6ZSkgJiYgKHBvcyA+IDApCi0gICAgICAgICAgICAmJiAobV9vcHMubV90b2tlblF1ZXVlU2l6ZSAhPSAwKSkKLSAgICB7Ci0gICAgICBTdHJpbmcgdG9rID0gKChTdHJpbmcpIG1fb3BzLm1fdG9rZW5RdWV1ZVtwb3MgLSAxXSk7Ci0KLSAgICAgIGIgPSAodG9rLmxlbmd0aCgpID09IDEpID8gKHRvay5jaGFyQXQoMCkgPT0gYykgOiBmYWxzZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGIgPSBmYWxzZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYjsKLSAgfQotCi0gIC8qKgotICAgKiBMb29rIGJlaGluZCB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBjdXJyZW50IHRva2VuIGluIG9yZGVyIHRvCi0gICAqIG1ha2UgYSBicmFuY2hpbmcgZGVjaXNpb24uCi0gICAqIAotICAgKiBAcGFyYW0gYyB0aGUgY2hhcmFjdGVyIHRvIGNvbXBhcmUgaXQgdG8uCi0gICAqIEBwYXJhbSBuIG51bWJlciBvZiB0b2tlbnMgdG8gbG9vayBiZWhpbmQuICBNdXN0IGJlCi0gICAqIGdyZWF0ZXIgdGhhbiAxLiAgTm90ZSB0aGF0IHRoZSBsb29rIGJlaGluZCB0ZXJtaW5hdGVzCi0gICAqIGF0IGVpdGhlciB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcgb3Igb24gYSAnfCcKLSAgICogY2hhcmFjdGVyLiAgQmVjYXVzZSBvZiB0aGlzLCB0aGlzIG1ldGhvZCBzaG91bGQgb25seQotICAgKiBiZSB1c2VkIGZvciBwYXR0ZXJuIG1hdGNoaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRva2VuIGJlaGluZCB0aGUgY3VycmVudCB0b2tlbiBtYXRjaGVzIHRoZSBjaGFyYWN0ZXIgCi0gICAqICAgICAgICAgYXJndW1lbnQuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gbG9va2JlaGluZChjaGFyIGMsIGludCBuKQotICB7Ci0KLSAgICBib29sZWFuIGlzVG9rZW47Ci0gICAgaW50IGxvb2tCZWhpbmRQb3MgPSBtX3F1ZXVlTWFyayAtIChuICsgMSk7Ci0KLSAgICBpZiAobG9va0JlaGluZFBvcyA+PSAwKQotICAgIHsKLSAgICAgIFN0cmluZyBsb29rYmVoaW5kID0gKFN0cmluZykgbV9vcHMubV90b2tlblF1ZXVlW2xvb2tCZWhpbmRQb3NdOwotCi0gICAgICBpZiAobG9va2JlaGluZC5sZW5ndGgoKSA9PSAxKQotICAgICAgewotICAgICAgICBjaGFyIGMwID0gKGxvb2tiZWhpbmQgPT0gbnVsbCkgPyAnfCcgOiBsb29rYmVoaW5kLmNoYXJBdCgwKTsKLQotICAgICAgICBpc1Rva2VuID0gKGMwID09ICd8JykgPyBmYWxzZSA6IChjMCA9PSBjKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaXNUb2tlbiA9IGZhbHNlOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaXNUb2tlbiA9IGZhbHNlOwotICAgIH0KLQotICAgIHJldHVybiBpc1Rva2VuOwotICB9Ci0KLSAgLyoqCi0gICAqIGxvb2sgYmVoaW5kIHRoZSBjdXJyZW50IHRva2VuIGluIG9yZGVyIHRvCi0gICAqIHNlZSBpZiB0aGVyZSBpcyBhIHVzZWFibGUgdG9rZW4uCi0gICAqIAotICAgKiBAcGFyYW0gbiBudW1iZXIgb2YgdG9rZW5zIHRvIGxvb2sgYmVoaW5kLiAgTXVzdCBiZQotICAgKiBncmVhdGVyIHRoYW4gMS4gIE5vdGUgdGhhdCB0aGUgbG9vayBiZWhpbmQgdGVybWluYXRlcwotICAgKiBhdCBlaXRoZXIgdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nIG9yIG9uIGEgJ3wnCi0gICAqIGNoYXJhY3Rlci4gIEJlY2F1c2Ugb2YgdGhpcywgdGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkKLSAgICogYmUgdXNlZCBmb3IgcGF0dGVybiBtYXRjaGluZy4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBsb29rIGJlaGluZCBoYXMgYSB0b2tlbiwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGxvb2tiZWhpbmRIYXNUb2tlbihpbnQgbikKLSAgewotCi0gICAgYm9vbGVhbiBoYXNUb2tlbjsKLQotICAgIGlmICgobV9xdWV1ZU1hcmsgLSBuKSA+IDApCi0gICAgewotICAgICAgU3RyaW5nIGxvb2tiZWhpbmQgPSAoU3RyaW5nKSBtX29wcy5tX3Rva2VuUXVldWVbbV9xdWV1ZU1hcmsgLSAobiAtIDEpXTsKLSAgICAgIGNoYXIgYzAgPSAobG9va2JlaGluZCA9PSBudWxsKSA/ICd8JyA6IGxvb2tiZWhpbmQuY2hhckF0KDApOwotCi0gICAgICBoYXNUb2tlbiA9IChjMCA9PSAnfCcpID8gZmFsc2UgOiB0cnVlOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaGFzVG9rZW4gPSBmYWxzZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gaGFzVG9rZW47Ci0gIH0KLQotICAvKioKLSAgICogTG9vayBhaGVhZCBvZiB0aGUgY3VycmVudCB0b2tlbiBpbiBvcmRlciB0bwotICAgKiBtYWtlIGEgYnJhbmNoaW5nIGRlY2lzaW9uLgotICAgKiAKLSAgICogQHBhcmFtIHMgdGhlIHN0cmluZyB0byBjb21wYXJlIGl0IHRvLgotICAgKiBAcGFyYW0gbiBudW1iZXIgb2YgdG9rZW5zIHRvIGxvb2thaGVhZC4gIE11c3QgYmUKLSAgICogZ3JlYXRlciB0aGFuIDEuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdG9rZW4gYmVoaW5kIHRoZSBjdXJyZW50IHRva2VuIG1hdGNoZXMgdGhlIHN0cmluZyAKLSAgICogICAgICAgICBhcmd1bWVudC4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgYm9vbGVhbiBsb29rYWhlYWQoU3RyaW5nIHMsIGludCBuKQotICB7Ci0KLSAgICBib29sZWFuIGlzVG9rZW47Ci0KLSAgICBpZiAoKG1fcXVldWVNYXJrICsgbikgPD0gbV9vcHMubV90b2tlblF1ZXVlU2l6ZSkKLSAgICB7Ci0gICAgICBTdHJpbmcgbG9va2FoZWFkID0gKFN0cmluZykgbV9vcHMubV90b2tlblF1ZXVlW21fcXVldWVNYXJrICsgKG4gLSAxKV07Ci0KLSAgICAgIGlzVG9rZW4gPSAobG9va2FoZWFkICE9IG51bGwpID8gbG9va2FoZWFkLmVxdWFscyhzKSA6IChzID09IG51bGwpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgaXNUb2tlbiA9IChudWxsID09IHMpOwotICAgIH0KLQotICAgIHJldHVybiBpc1Rva2VuOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIHRoZSBuZXh0IHRva2VuIGZyb20gdGhlIGNvbW1hbmQgYW5kCi0gICAqIHN0b3JlIGl0IGluIG1fdG9rZW4gc3RyaW5nLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIG5leHRUb2tlbigpCi0gIHsKLQotICAgIGlmIChtX3F1ZXVlTWFyayA8IG1fb3BzLm1fdG9rZW5RdWV1ZVNpemUpCi0gICAgewotICAgICAgbV90b2tlbiA9IChTdHJpbmcpIG1fb3BzLm1fdG9rZW5RdWV1ZVttX3F1ZXVlTWFyaysrXTsKLSAgICAgIG1fdG9rZW5DaGFyID0gbV90b2tlbi5jaGFyQXQoMCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBtX3Rva2VuID0gbnVsbDsKLSAgICAgIG1fdG9rZW5DaGFyID0gMDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmUgYSB0b2tlbiByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB0b2tlbi4KLSAgICogCi0gICAqIEBwYXJhbSBpIFBvc2l0aW9uIHJlbGF0aXZlIHRvIGN1cnJlbnQgdG9rZW4uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXgsIG9yIG51bGwgaWYgdGhlIGluZGV4IGlzIG91dCAKLSAgICogICAgICAgICBvZiByYW5nZS4KLSAgICovCi0gIHByaXZhdGUgZmluYWwgU3RyaW5nIGdldFRva2VuUmVsYXRpdmUoaW50IGkpCi0gIHsKLQotICAgIFN0cmluZyB0b2s7Ci0gICAgaW50IHJlbGF0aXZlID0gbV9xdWV1ZU1hcmsgKyBpOwotCi0gICAgaWYgKChyZWxhdGl2ZSA+IDApICYmIChyZWxhdGl2ZSA8IG1fb3BzLm1fdG9rZW5RdWV1ZVNpemUpKQotICAgIHsKLSAgICAgIHRvayA9IChTdHJpbmcpIG1fb3BzLm1fdG9rZW5RdWV1ZVtyZWxhdGl2ZV07Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICB0b2sgPSBudWxsOwotICAgIH0KLQotICAgIHJldHVybiB0b2s7Ci0gIH0KLQotICAvKioKLSAgICogUmV0cmlldmUgdGhlIHByZXZpb3VzIHRva2VuIGZyb20gdGhlIGNvbW1hbmQgYW5kCi0gICAqIHN0b3JlIGl0IGluIG1fdG9rZW4gc3RyaW5nLgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIHByZXZUb2tlbigpCi0gIHsKLQotICAgIGlmIChtX3F1ZXVlTWFyayA+IDApCi0gICAgewotICAgICAgbV9xdWV1ZU1hcmstLTsKLQotICAgICAgbV90b2tlbiA9IChTdHJpbmcpIG1fb3BzLm1fdG9rZW5RdWV1ZVttX3F1ZXVlTWFya107Ci0gICAgICBtX3Rva2VuQ2hhciA9IG1fdG9rZW4uY2hhckF0KDApOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbV90b2tlbiA9IG51bGw7Ci0gICAgICBtX3Rva2VuQ2hhciA9IDA7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN1bWUgYW4gZXhwZWN0ZWQgdG9rZW4sIHRocm93aW5nIGFuIGV4Y2VwdGlvbiBpZiBpdAotICAgKiBpc24ndCB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIGV4cGVjdGVkIFRoZSBzdHJpbmcgdG8gYmUgZXhwZWN0ZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNvbnN1bWVFeHBlY3RlZChTdHJpbmcgZXhwZWN0ZWQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHRva2VuSXMoZXhwZWN0ZWQpKQotICAgIHsKLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9FWFBFQ1RFRF9CVVRfRk9VTkQsIG5ldyBPYmplY3RbXXsgZXhwZWN0ZWQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3Rva2VuIH0pOyAgLy8iRXhwZWN0ZWQgIitleHBlY3RlZCsiLCBidXQgZm91bmQ6ICIrbV90b2tlbik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN1bWUgYW4gZXhwZWN0ZWQgdG9rZW4sIHRocm93aW5nIGFuIGV4Y2VwdGlvbiBpZiBpdAotICAgKiBpc24ndCB0aGVyZS4KLSAgICoKLSAgICogQHBhcmFtIGV4cGVjdGVkIHRoZSBjaGFyYWN0ZXIgdG8gYmUgZXhwZWN0ZWQuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNvbnN1bWVFeHBlY3RlZChjaGFyIGV4cGVjdGVkKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICh0b2tlbklzKGV4cGVjdGVkKSkKLSAgICB7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRVhQRUNURURfQlVUX0ZPVU5ELAotICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBTdHJpbmcudmFsdWVPZihleHBlY3RlZCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG1fdG9rZW4gfSk7ICAvLyJFeHBlY3RlZCAiK2V4cGVjdGVkKyIsIGJ1dCBmb3VuZDogIittX3Rva2VuKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogV2FybiB0aGUgdXNlciBvZiBhIHByb2JsZW0uCi0gICAqCi0gICAqIEBwYXJhbSBtc2cgQW4gZXJyb3IgbnVtYmVyIHRoYXQgY29ycmVzcG9uZHMgdG8gb25lIG9mIHRoZSBudW1iZXJzIGZvdW5kIAotICAgKiAgICAgICAgICAgIGluIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzfSwgd2hpY2ggaXMgCi0gICAqICAgICAgICAgICAgYSBrZXkgZm9yIGEgZm9ybWF0IHN0cmluZy4KLSAgICogQHBhcmFtIGFyZ3MgQW4gYXJyYXkgb2YgYXJndW1lbnRzIHJlcHJlc2VudGVkIGluIHRoZSBmb3JtYXQgc3RyaW5nLCB3aGljaCAKLSAgICogICAgICAgICAgICAgbWF5IGJlIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgRXJyb3JMaXN0b25lciBkZXRlcm1pbmVzIHRvIAotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFuIGV4Y2VwdGlvbi4KLSAgICovCi0gIHZvaWQgd2FybihpbnQgbXNnLCBPYmplY3RbXSBhcmdzKSB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSFdhcm5pbmcobXNnLCBhcmdzKTsKLSAgICBFcnJvckxpc3RlbmVyIGVoYW5kbGVyID0gdGhpcy5nZXRFcnJvckxpc3RlbmVyKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBlaGFuZGxlcikKLSAgICB7Ci0gICAgICAvLyBUTyBETzogTmVlZCB0byBnZXQgc3R5bGVzaGVldCBMb2NhdG9yIGZyb20gaGVyZS4KLSAgICAgIGVoYW5kbGVyLndhcm5pbmcobmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fc291cmNlTG9jYXRvcikpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgLy8gU2hvdWxkIG5ldmVyIGhhcHBlbi4KLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihmbXNnKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTm90aWZ5IHRoZSB1c2VyIG9mIGFuIGFzc2VydGlvbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIGIgIElmIGZhbHNlLCBhIHJ1bnRpbWUgZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgotICAgKiBAcGFyYW0gbXNnIFRoZSBhc3NlcnRpb24gbWVzc2FnZSwgd2hpY2ggc2hvdWxkIGJlIGluZm9ybWF0aXZlLgotICAgKiAKLSAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIHRoZSBiIGFyZ3VtZW50IGlzIGZhbHNlLgotICAgKi8KLSAgcHJpdmF0ZSB2b2lkIGFzc2VydGlvbihib29sZWFuIGIsIFN0cmluZyBtc2cpCi0gIHsKLQotICAgIGlmICghYikKLSAgICB7Ci0gICAgICBTdHJpbmcgZk1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZSgKLSAgICAgICAgWFBBVEhFcnJvclJlc291cmNlcy5FUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04sCi0gICAgICAgIG5ldyBPYmplY3RbXXsgbXNnIH0pOwotCi0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihmTXNnKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogTm90aWZ5IHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEFuIGVycm9yIG51bWJlciB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgbnVtYmVycyBmb3VuZCAKLSAgICogICAgICAgICAgICBpbiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlc30sIHdoaWNoIGlzIAotICAgKiAgICAgICAgICAgIGEga2V5IGZvciBhIGZvcm1hdCBzdHJpbmcuCi0gICAqIEBwYXJhbSBhcmdzIEFuIGFycmF5IG9mIGFyZ3VtZW50cyByZXByZXNlbnRlZCBpbiB0aGUgZm9ybWF0IHN0cmluZywgd2hpY2ggCi0gICAqICAgICAgICAgICAgIG1heSBiZSBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IEVycm9yTGlzdG9uZXIgZGV0ZXJtaW5lcyB0byAKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBhbiBleGNlcHRpb24uCi0gICAqLwotICB2b2lkIGVycm9yKGludCBtc2csIE9iamVjdFtdIGFyZ3MpIHRocm93cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgZm1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShtc2csIGFyZ3MpOwotICAgIEVycm9yTGlzdGVuZXIgZWhhbmRsZXIgPSB0aGlzLmdldEVycm9yTGlzdGVuZXIoKTsKLQotICAgIFRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlID0gbmV3IFRyYW5zZm9ybWVyRXhjZXB0aW9uKGZtc2csIG1fc291cmNlTG9jYXRvcik7Ci0gICAgaWYgKG51bGwgIT0gZWhhbmRsZXIpCi0gICAgewotICAgICAgLy8gVE8gRE86IE5lZWQgdG8gZ2V0IHN0eWxlc2hlZXQgTG9jYXRvciBmcm9tIGhlcmUuCi0gICAgICBlaGFuZGxlci5mYXRhbEVycm9yKHRlKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIFN5c3RlbS5lcnIucHJpbnRsbihmbXNnKTsKLSAgICAgIHRocm93IHRlOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBEdW1wIHRoZSByZW1haW5pbmcgdG9rZW4gcXVldWUuCi0gICAqIFRoYW5rcyB0byBDcmFpZyBmb3IgdGhpcy4KLSAgICoKLSAgICogQHJldHVybiBBIGR1bXAgb2YgdGhlIHJlbWFpbmluZyB0b2tlbiBxdWV1ZSwgd2hpY2ggbWF5IGJlIGFwcGVuZGVkIHRvIAotICAgKiAgICAgICAgIGFuIGVycm9yIG1lc3NhZ2UuCi0gICAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIGR1bXBSZW1haW5pbmdUb2tlblF1ZXVlKCkKLSAgewotCi0gICAgaW50IHEgPSBtX3F1ZXVlTWFyazsKLSAgICBTdHJpbmcgcmV0dXJuTXNnOwotCi0gICAgaWYgKHEgPCBtX29wcy5tX3Rva2VuUXVldWVTaXplKQotICAgIHsKLSAgICAgIFN0cmluZyBtc2cgPSAiXG4gUmVtYWluaW5nIHRva2VuczogKCI7Ci0KLSAgICAgIHdoaWxlIChxIDwgbV9vcHMubV90b2tlblF1ZXVlU2l6ZSkKLSAgICAgIHsKLSAgICAgICAgU3RyaW5nIHQgPSAoU3RyaW5nKSBtX29wcy5tX3Rva2VuUXVldWVbcSsrXTsKLQotICAgICAgICBtc2cgKz0gKCIgJyIgKyB0ICsgIiciKTsKLSAgICAgIH0KLQotICAgICAgcmV0dXJuTXNnID0gbXNnICsgIikiOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmV0dXJuTXNnID0gIiI7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJldHVybk1zZzsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHN0cmluZywgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIGZ1bmN0aW9uIHRva2VuLgotICAgKgotICAgKiBAcGFyYW0ga2V5IEEgbG9jYWwgbmFtZSBvZiBhIGZ1bmN0aW9uLgotICAgKgotICAgKiBAcmV0dXJuICAgVGhlIGZ1bmN0aW9uIElELCB3aGljaCBtYXkgY29ycmVzcG9uZCB0byBvbmUgb2YgdGhlIEZVTkNfWFhYIAotICAgKiAgICB2YWx1ZXMgZm91bmQgaW4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuRnVuY3Rpb25UYWJsZX0sIGJ1dCBtYXkgCi0gICAqICAgIGJlIGEgdmFsdWUgaW5zdGFsbGVkIGJ5IGFuIGV4dGVybmFsIG1vZHVsZS4KLSAgICovCi0gIGZpbmFsIGludCBnZXRGdW5jdGlvblRva2VuKFN0cmluZyBrZXkpCi0gIHsKLQotICAgIGludCB0b2s7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICB0b2sgPSAoKEludGVnZXIpIChLZXl3b3Jkcy5tX2Z1bmN0aW9ucy5nZXQoa2V5KSkpLmludFZhbHVlKCk7Ci0gICAgfQotICAgIGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUpCi0gICAgewotICAgICAgdG9rID0gLTE7Ci0gICAgfQotICAgIGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlKQotICAgIHsKLSAgICAgIHRvayA9IC0xOwotICAgIH0KLQotICAgIHJldHVybiB0b2s7Ci0gIH0KLQotICAvKioKLSAgICogSW5zZXJ0IHJvb20gZm9yIG9wZXJhdGlvbi4gIFRoaXMgd2lsbCBOT1Qgc2V0Ci0gICAqIHRoZSBsZW5ndGggdmFsdWUgb2YgdGhlIG9wZXJhdGlvbiwgYnV0IHdpbGwgdXBkYXRlCi0gICAqIHRoZSBsZW5ndGggdmFsdWUgZm9yIHRoZSB0b3RhbCBleHByZXNzaW9uLgotICAgKgotICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgb3AgaXMgdG8gYmUgaW5zZXJ0ZWQuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgb3BlcmF0aW9uIHNwYWNlIGluIHRoZSBvcCBtYXAuCi0gICAqIEBwYXJhbSBvcCBUaGUgb3AgY29kZSB0byB0aGUgaW5zZXJ0ZWQuCi0gICAqLwotICB2b2lkIGluc2VydE9wKGludCBwb3MsIGludCBsZW5ndGgsIGludCBvcCkKLSAgewotCi0gICAgaW50IHRvdGFsTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgZm9yIChpbnQgaSA9IHRvdGFsTGVuIC0gMTsgaSA+PSBwb3M7IGktLSkKLSAgICB7Ci0gICAgICBtX29wcy5tX29wTWFwW2kgKyBsZW5ndGhdID0gbV9vcHMubV9vcE1hcFtpXTsKLSAgICB9Ci0KLSAgICBtX29wcy5tX29wTWFwW3Bvc10gPSBvcDsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gPSB0b3RhbExlbiArIGxlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBJbnNlcnQgcm9vbSBmb3Igb3BlcmF0aW9uLiAgVGhpcyBXSUxMIHNldAotICAgKiB0aGUgbGVuZ3RoIHZhbHVlIG9mIHRoZSBvcGVyYXRpb24sIGFuZCB3aWxsIHVwZGF0ZQotICAgKiB0aGUgbGVuZ3RoIHZhbHVlIGZvciB0aGUgdG90YWwgZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBvcGVyYXRpb24uCi0gICAqIEBwYXJhbSBvcCBUaGUgb3AgY29kZSB0byB0aGUgaW5zZXJ0ZWQuCi0gICAqLwotICB2b2lkIGFwcGVuZE9wKGludCBsZW5ndGgsIGludCBvcCkKLSAgewotCi0gICAgaW50IHRvdGFsTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgbV9vcHMubV9vcE1hcFt0b3RhbExlbl0gPSBvcDsKLSAgICBtX29wcy5tX29wTWFwW3RvdGFsTGVuICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9IGxlbmd0aDsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gPSB0b3RhbExlbiArIGxlbmd0aDsKLSAgfQotCi0gIC8vID09PT09PT09PT09PT0gRVhQUkVTU0lPTlMgRlVOQ1RJT05TID09PT09PT09PT09PT09PT09Ci0KLSAgLyoqCi0gICAqCi0gICAqCi0gICAqIEV4cHIgIDo6PSAgT3JFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBPckV4cHIoKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBPckV4cHIgIDo6PSAgQW5kRXhwcgotICAgKiB8IE9yRXhwciAnb3InIEFuZEV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBPckV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICBBbmRFeHByKCk7Ci0KLSAgICBpZiAoKG51bGwgIT0gbV90b2tlbikgJiYgdG9rZW5Jcygib3IiKSkKLSAgICB7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX09SKTsKLSAgICAgIE9yRXhwcigpOwotCi0gICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBBbmRFeHByICA6Oj0gIEVxdWFsaXR5RXhwcgotICAgKiB8IEFuZEV4cHIgJ2FuZCcgRXF1YWxpdHlFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgQW5kRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLQotICAgIEVxdWFsaXR5RXhwcigtMSk7Ci0KLSAgICBpZiAoKG51bGwgIT0gbV90b2tlbikgJiYgdG9rZW5JcygiYW5kIikpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBpbnNlcnRPcChvcFBvcywgMiwgT3BDb2Rlcy5PUF9BTkQpOwotICAgICAgQW5kRXhwcigpOwotCi0gICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBAcmV0dXJucyBhbiBPYmplY3Qgd2hpY2ggaXMgZWl0aGVyIGEgU3RyaW5nLCBhIE51bWJlciwgYSBCb29sZWFuLCBvciBhIHZlY3RvcgotICAgKiBvZiBub2Rlcy4KLSAgICoKLSAgICogRXF1YWxpdHlFeHByICA6Oj0gIFJlbGF0aW9uYWxFeHByCi0gICAqIHwgRXF1YWxpdHlFeHByICc9JyBSZWxhdGlvbmFsRXhwcgotICAgKgotICAgKgotICAgKiBAcGFyYW0gYWRkUG9zIFBvc2l0aW9uIHdoZXJlIGV4cHJlc3Npb24gaXMgdG8gYmUgYWRkZWQsIG9yIC0xIGZvciBhcHBlbmQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGVxdWFsaXR5IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBFcXVhbGl0eUV4cHIoaW50IGFkZFBvcykgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgaWYgKC0xID09IGFkZFBvcykKLSAgICAgIGFkZFBvcyA9IG9wUG9zOwotCi0gICAgUmVsYXRpb25hbEV4cHIoLTEpOwotCi0gICAgaWYgKG51bGwgIT0gbV90b2tlbikKLSAgICB7Ci0gICAgICBpZiAodG9rZW5JcygnIScpICYmIGxvb2thaGVhZCgnPScsIDEpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9OT1RFUVVBTFMpOwotCi0gICAgICAgIGludCBvcFBsdXNMZWZ0SGFuZExlbiA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIGFkZFBvczsKLQotICAgICAgICBhZGRQb3MgPSBFcXVhbGl0eUV4cHIoYWRkUG9zKTsKLSAgICAgICAgbV9vcHMubV9vcE1hcFthZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIG9wUGx1c0xlZnRIYW5kTGVuICsgMV0gKyBvcFBsdXNMZWZ0SGFuZExlbjsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0b2tlbklzKCc9JykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfRVFVQUxTKTsKLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBhZGRQb3M7Ci0KLSAgICAgICAgYWRkUG9zID0gRXF1YWxpdHlFeHByKGFkZFBvcyk7Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbYWRkUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgICAgbV9vcHMubV9vcE1hcFthZGRQb3MgKyBvcFBsdXNMZWZ0SGFuZExlbiArIDFdICsgb3BQbHVzTGVmdEhhbmRMZW47Ci0gICAgICAgIGFkZFBvcyArPSAyOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBhZGRQb3M7Ci0gIH0KLQotICAvKioKLSAgICogLgotICAgKiBAcmV0dXJucyBhbiBPYmplY3Qgd2hpY2ggaXMgZWl0aGVyIGEgU3RyaW5nLCBhIE51bWJlciwgYSBCb29sZWFuLCBvciBhIHZlY3RvcgotICAgKiBvZiBub2Rlcy4KLSAgICoKLSAgICogUmVsYXRpb25hbEV4cHIgIDo6PSAgQWRkaXRpdmVFeHByCi0gICAqIHwgUmVsYXRpb25hbEV4cHIgJzwnIEFkZGl0aXZlRXhwcgotICAgKiB8IFJlbGF0aW9uYWxFeHByICc+JyBBZGRpdGl2ZUV4cHIKLSAgICogfCBSZWxhdGlvbmFsRXhwciAnPD0nIEFkZGl0aXZlRXhwcgotICAgKiB8IFJlbGF0aW9uYWxFeHByICc+PScgQWRkaXRpdmVFeHByCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhZGRQb3MgUG9zaXRpb24gd2hlcmUgZXhwcmVzc2lvbiBpcyB0byBiZSBhZGRlZCwgb3IgLTEgZm9yIGFwcGVuZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcG9zaXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgcmVsYXRpb25hbCBleHByZXNzaW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgUmVsYXRpb25hbEV4cHIoaW50IGFkZFBvcykgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgaWYgKC0xID09IGFkZFBvcykKLSAgICAgIGFkZFBvcyA9IG9wUG9zOwotCi0gICAgQWRkaXRpdmVFeHByKC0xKTsKLQotICAgIGlmIChudWxsICE9IG1fdG9rZW4pCi0gICAgewotICAgICAgaWYgKHRva2VuSXMoJzwnKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgaWYgKHRva2VuSXMoJz0nKSkKLSAgICAgICAgewotICAgICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9MVEUpOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGluc2VydE9wKGFkZFBvcywgMiwgT3BDb2Rlcy5PUF9MVCk7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgb3BQbHVzTGVmdEhhbmRMZW4gPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBhZGRQb3M7Ci0KLSAgICAgICAgYWRkUG9zID0gUmVsYXRpb25hbEV4cHIoYWRkUG9zKTsKLSAgICAgICAgbV9vcHMubV9vcE1hcFthZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIG9wUGx1c0xlZnRIYW5kTGVuICsgMV0gKyBvcFBsdXNMZWZ0SGFuZExlbjsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0b2tlbklzKCc+JykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICAgIGlmICh0b2tlbklzKCc9JykpCi0gICAgICAgIHsKLSAgICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfR1RFKTsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfR1QpOwotICAgICAgICB9Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IFJlbGF0aW9uYWxFeHByKGFkZFBvcyk7Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbYWRkUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgICAgbV9vcHMubV9vcE1hcFthZGRQb3MgKyBvcFBsdXNMZWZ0SGFuZExlbiArIDFdICsgb3BQbHVzTGVmdEhhbmRMZW47Ci0gICAgICAgIGFkZFBvcyArPSAyOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBhZGRQb3M7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBoYXMgdG8gaGFuZGxlIGNvbnN0cnVjdGlvbiBvZiB0aGUgb3BlcmF0aW9ucyBzbyB0aGF0IHRoZXkgYXJlIGV2YWx1YXRlZAotICAgKiBpbiBwcmUtZml4IG9yZGVyLiAgU28sIGZvciA5KzctNiwgaW5zdGVhZCBvZiB8K3w5fC18N3w2fCwgdGhpcyBuZWVkcyB0byBiZQotICAgKiBldmFsdWF0ZWQgYXMgfC18K3w5fDd8NnwuCi0gICAqCi0gICAqIEFkZGl0aXZlRXhwciAgOjo9ICBNdWx0aXBsaWNhdGl2ZUV4cHIKLSAgICogfCBBZGRpdGl2ZUV4cHIgJysnIE11bHRpcGxpY2F0aXZlRXhwcgotICAgKiB8IEFkZGl0aXZlRXhwciAnLScgTXVsdGlwbGljYXRpdmVFeHByCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhZGRQb3MgUG9zaXRpb24gd2hlcmUgZXhwcmVzc2lvbiBpcyB0byBiZSBhZGRlZCwgb3IgLTEgZm9yIGFwcGVuZC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcG9zaXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgZXF1YWxpdHkgZXhwcmVzc2lvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IEFkZGl0aXZlRXhwcihpbnQgYWRkUG9zKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICBpZiAoLTEgPT0gYWRkUG9zKQotICAgICAgYWRkUG9zID0gb3BQb3M7Ci0KLSAgICBNdWx0aXBsaWNhdGl2ZUV4cHIoLTEpOwotCi0gICAgaWYgKG51bGwgIT0gbV90b2tlbikKLSAgICB7Ci0gICAgICBpZiAodG9rZW5JcygnKycpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX1BMVVMpOwotCi0gICAgICAgIGludCBvcFBsdXNMZWZ0SGFuZExlbiA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIGFkZFBvczsKLQotICAgICAgICBhZGRQb3MgPSBBZGRpdGl2ZUV4cHIoYWRkUG9zKTsKLSAgICAgICAgbV9vcHMubV9vcE1hcFthZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIG9wUGx1c0xlZnRIYW5kTGVuICsgMV0gKyBvcFBsdXNMZWZ0SGFuZExlbjsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0b2tlbklzKCctJykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfTUlOVVMpOwotCi0gICAgICAgIGludCBvcFBsdXNMZWZ0SGFuZExlbiA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIGFkZFBvczsKLQotICAgICAgICBhZGRQb3MgPSBBZGRpdGl2ZUV4cHIoYWRkUG9zKTsKLSAgICAgICAgbV9vcHMubV9vcE1hcFthZGRQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIG9wUGx1c0xlZnRIYW5kTGVuICsgMV0gKyBvcFBsdXNMZWZ0SGFuZExlbjsKLSAgICAgICAgYWRkUG9zICs9IDI7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIGFkZFBvczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGlzIGhhcyB0byBoYW5kbGUgY29uc3RydWN0aW9uIG9mIHRoZSBvcGVyYXRpb25zIHNvIHRoYXQgdGhleSBhcmUgZXZhbHVhdGVkCi0gICAqIGluIHByZS1maXggb3JkZXIuICBTbywgZm9yIDkrNy02LCBpbnN0ZWFkIG9mIHwrfDl8LXw3fDZ8LCB0aGlzIG5lZWRzIHRvIGJlCi0gICAqIGV2YWx1YXRlZCBhcyB8LXwrfDl8N3w2fC4KLSAgICoKLSAgICogTXVsdGlwbGljYXRpdmVFeHByICA6Oj0gIFVuYXJ5RXhwcgotICAgKiB8IE11bHRpcGxpY2F0aXZlRXhwciBNdWx0aXBseU9wZXJhdG9yIFVuYXJ5RXhwcgotICAgKiB8IE11bHRpcGxpY2F0aXZlRXhwciAnZGl2JyBVbmFyeUV4cHIKLSAgICogfCBNdWx0aXBsaWNhdGl2ZUV4cHIgJ21vZCcgVW5hcnlFeHByCi0gICAqIHwgTXVsdGlwbGljYXRpdmVFeHByICdxdW8nIFVuYXJ5RXhwcgotICAgKgotICAgKiBAcGFyYW0gYWRkUG9zIFBvc2l0aW9uIHdoZXJlIGV4cHJlc3Npb24gaXMgdG8gYmUgYWRkZWQsIG9yIC0xIGZvciBhcHBlbmQuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGVxdWFsaXR5IGV4cHJlc3Npb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBNdWx0aXBsaWNhdGl2ZUV4cHIoaW50IGFkZFBvcykgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgaWYgKC0xID09IGFkZFBvcykKLSAgICAgIGFkZFBvcyA9IG9wUG9zOwotCi0gICAgVW5hcnlFeHByKCk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX3Rva2VuKQotICAgIHsKLSAgICAgIGlmICh0b2tlbklzKCcqJykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgICBpbnNlcnRPcChhZGRQb3MsIDIsIE9wQ29kZXMuT1BfTVVMVCk7Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IE11bHRpcGxpY2F0aXZlRXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgICAgIG1fb3BzLm1fb3BNYXBbYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxXSArIG9wUGx1c0xlZnRIYW5kTGVuOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHRva2VuSXMoImRpdiIpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX0RJVik7Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IE11bHRpcGxpY2F0aXZlRXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgICAgIG1fb3BzLm1fb3BNYXBbYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxXSArIG9wUGx1c0xlZnRIYW5kTGVuOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHRva2VuSXMoIm1vZCIpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX01PRCk7Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IE11bHRpcGxpY2F0aXZlRXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgICAgIG1fb3BzLm1fb3BNYXBbYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxXSArIG9wUGx1c0xlZnRIYW5kTGVuOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHRva2VuSXMoInF1byIpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgaW5zZXJ0T3AoYWRkUG9zLCAyLCBPcENvZGVzLk9QX1FVTyk7Ci0KLSAgICAgICAgaW50IG9wUGx1c0xlZnRIYW5kTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gYWRkUG9zOwotCi0gICAgICAgIGFkZFBvcyA9IE11bHRpcGxpY2F0aXZlRXhwcihhZGRQb3MpOwotICAgICAgICBtX29wcy5tX29wTWFwW2FkZFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgICAgIG1fb3BzLm1fb3BNYXBbYWRkUG9zICsgb3BQbHVzTGVmdEhhbmRMZW4gKyAxXSArIG9wUGx1c0xlZnRIYW5kTGVuOwotICAgICAgICBhZGRQb3MgKz0gMjsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gYWRkUG9zOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIFVuYXJ5RXhwciAgOjo9ICBVbmlvbkV4cHIKLSAgICogfCAnLScgVW5hcnlFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgVW5hcnlFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotICAgIGJvb2xlYW4gaXNOZWcgPSBmYWxzZTsKLQotICAgIGlmIChtX3Rva2VuQ2hhciA9PSAnLScpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX05FRyk7Ci0KLSAgICAgIGlzTmVnID0gdHJ1ZTsKLSAgICB9Ci0KLSAgICBVbmlvbkV4cHIoKTsKLQotICAgIGlmIChpc05lZykKLSAgICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogU3RyaW5nRXhwciAgOjo9ICBFeHByCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgU3RyaW5nRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfU1RSSU5HKTsKLSAgICBFeHByKCk7Ci0KLSAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBvcFBvczsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBTdHJpbmdFeHByICA6Oj0gIEV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBCb29sZWFuRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfQk9PTCk7Ci0gICAgRXhwcigpOwotCi0gICAgaW50IG9wTGVuID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0KLSAgICBpZiAob3BMZW4gPT0gMikKLSAgICB7Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCwgbnVsbCk7ICAvLyJib29sZWFuKC4uLikgYXJndW1lbnQgaXMgbm8gbG9uZ2VyIG9wdGlvbmFsIHdpdGggMTk5OTA3MDkgWFBhdGggZHJhZnQuIik7Ci0gICAgfQotCi0gICAgbV9vcHMubV9vcE1hcFtvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPSBvcExlbjsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKgotICAgKiBOdW1iZXJFeHByICA6Oj0gIEV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBOdW1iZXJFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9OVU1CRVIpOwotICAgIEV4cHIoKTsKLQotICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSBjb250ZXh0IG9mIHRoZSByaWdodCBoYW5kIHNpZGUgZXhwcmVzc2lvbnMgaXMgdGhlIGNvbnRleHQgb2YgdGhlCi0gICAqIGxlZnQgaGFuZCBzaWRlIGV4cHJlc3Npb24uIFRoZSByZXN1bHRzIG9mIHRoZSByaWdodCBoYW5kIHNpZGUgZXhwcmVzc2lvbnMKLSAgICogYXJlIG5vZGUgc2V0cy4gVGhlIHJlc3VsdCBvZiB0aGUgbGVmdCBoYW5kIHNpZGUgVW5pb25FeHByIGlzIHRoZSB1bmlvbgotICAgKiBvZiB0aGUgcmVzdWx0cyBvZiB0aGUgcmlnaHQgaGFuZCBzaWRlIGV4cHJlc3Npb25zLgotICAgKgotICAgKgotICAgKiBVbmlvbkV4cHIgICAgOjo9ICAgIFBhdGhFeHByCi0gICAqIHwgVW5pb25FeHByICd8JyBQYXRoRXhwcgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFVuaW9uRXhwcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLSAgICBib29sZWFuIGNvbnRpbnVlT3JMb29wID0gdHJ1ZTsKLSAgICBib29sZWFuIGZvdW5kVW5pb24gPSBmYWxzZTsKLQotICAgIGRvCi0gICAgewotICAgICAgUGF0aEV4cHIoKTsKLQotICAgICAgaWYgKHRva2VuSXMoJ3wnKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZhbHNlID09IGZvdW5kVW5pb24pCi0gICAgICAgIHsKLSAgICAgICAgICBmb3VuZFVuaW9uID0gdHJ1ZTsKLQotICAgICAgICAgIGluc2VydE9wKG9wUG9zLCAyLCBPcENvZGVzLk9QX1VOSU9OKTsKLSAgICAgICAgfQotCi0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBicmVhazsKLSAgICAgIH0KLQotICAgICAgLy8gdGhpcy5tX3Rlc3RGb3JEb2NPcmRlciA9IHRydWU7Ci0gICAgfQotICAgIHdoaWxlIChjb250aW51ZU9yTG9vcCk7Ci0KLSAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBvcFBvczsKLSAgfQotCi0gIC8qKgotICAgKiBQYXRoRXhwciAgOjo9ICBMb2NhdGlvblBhdGgKLSAgICogfCBGaWx0ZXJFeHByCi0gICAqIHwgRmlsdGVyRXhwciAnLycgUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICogfCBGaWx0ZXJFeHByICcvLycgUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICoKLSAgICogQHRocm93cyBYU0xQcm9jZXNzb3JFeGNlcHRpb24gdGhyb3duIGlmIHRoZSBhY3RpdmUgUHJvYmxlbUxpc3RlbmVyIGFuZCBYUGF0aENvbnRleHQgZGVjaWRlCi0gICAqIHRoZSBlcnJvciBjb25kaXRpb24gaXMgc2V2ZXJlIGVub3VnaCB0byBoYWx0IHByb2Nlc3NpbmcuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgUGF0aEV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0gICAgYm9vbGVhbiBmb3VuZExvY2F0aW9uUGF0aDsKLQotICAgIEZpbHRlckV4cHIoKTsKLQotICAgIGlmICh0b2tlbklzKCcvJykpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgIC8vIGludCBsb2NhdGlvblBhdGhPcFBvcyA9IG9wUG9zOwotICAgICAgaW5zZXJ0T3Aob3BQb3MsIDIsIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIKTsKLSAgICAgIFJlbGF0aXZlTG9jYXRpb25QYXRoKCk7Ci0KLSAgICAgIC8vIFRlcm1pbmF0ZSBmb3Igc2FmZXR5LgotICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF1dID0gT3BDb2Rlcy5FTkRPUDsKLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSArPSAxOwotICAgICAgbV9vcHMubV9vcE1hcFtvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBvcFBvczsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogRmlsdGVyRXhwciAgOjo9ICBQcmltYXJ5RXhwcgotICAgKiB8IEZpbHRlckV4cHIgUHJlZGljYXRlCi0gICAqCi0gICAqIEB0aHJvd3MgWFNMUHJvY2Vzc29yRXhjZXB0aW9uIHRocm93biBpZiB0aGUgYWN0aXZlIFByb2JsZW1MaXN0ZW5lciBhbmQgWFBhdGhDb250ZXh0IGRlY2lkZQotICAgKiB0aGUgZXJyb3IgY29uZGl0aW9uIGlzIHNldmVyZSBlbm91Z2ggdG8gaGFsdCBwcm9jZXNzaW5nLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIEZpbHRlckV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICAvLyBib29sZWFuIGlzRnVuYyA9IGxvb2thaGVhZCgnKCcsIDEpOwotICAgIFByaW1hcnlFeHByKCk7Ci0KLSAgICBpZiAodG9rZW5JcygnWycpKQotICAgIHsKLQotICAgICAgLy8gaW50IGxvY2F0aW9uUGF0aE9wUG9zID0gb3BQb3M7Ci0gICAgICBpbnNlcnRPcChvcFBvcywgMiwgT3BDb2Rlcy5PUF9MT0NBVElPTlBBVEgpOwotCi0gICAgICB3aGlsZSAodG9rZW5JcygnWycpKQotICAgICAgewotICAgICAgICBQcmVkaWNhdGUoKTsKLSAgICAgIH0KLQotICAgICAgaWYgKHRva2VuSXMoJy8nKSkKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICAgIFJlbGF0aXZlTG9jYXRpb25QYXRoKCk7Ci0gICAgICB9Ci0KLSAgICAgIC8vIFRlcm1pbmF0ZSBmb3Igc2FmZXR5LgotICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF1dID0gT3BDb2Rlcy5FTkRPUDsKLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSArPSAxOwotICAgICAgbV9vcHMubV9vcE1hcFtvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBvcFBvczsKLSAgICB9Ci0KLSAgICAvKgotICAgICAqIGlmKHRva2VuSXMoJ1snKSkKLSAgICAgKiB7Ci0gICAgICogICBQcmVkaWNhdGUoKTsKLSAgICAgKiAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0gICAgICogfQotICAgICAqLwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIFByaW1hcnlFeHByICA6Oj0gIFZhcmlhYmxlUmVmZXJlbmNlCi0gICAqIHwgJygnIEV4cHIgJyknCi0gICAqIHwgTGl0ZXJhbAotICAgKiB8IE51bWJlcgotICAgKiB8IEZ1bmN0aW9uQ2FsbAotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFByaW1hcnlFeHByKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IG9wUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotCi0gICAgaWYgKChtX3Rva2VuQ2hhciA9PSAnXCcnKSB8fCAobV90b2tlbkNoYXIgPT0gJyInKSkKLSAgICB7Ci0gICAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX0xJVEVSQUwpOwotICAgICAgTGl0ZXJhbCgpOwotCi0gICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICAgIH0KLSAgICBlbHNlIGlmIChtX3Rva2VuQ2hhciA9PSAnJCcpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7ICAvLyBjb25zdW1lICckJwotICAgICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9WQVJJQUJMRSk7Ci0gICAgICBRTmFtZSgpOwotICAgICAgCi0gICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICAgIH0KLSAgICBlbHNlIGlmIChtX3Rva2VuQ2hhciA9PSAnKCcpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX0dST1VQKTsKLSAgICAgIEV4cHIoKTsKLSAgICAgIGNvbnN1bWVFeHBlY3RlZCgnKScpOwotCi0gICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICAgIH0KLSAgICBlbHNlIGlmICgobnVsbCAhPSBtX3Rva2VuKSAmJiAoKCgnLicgPT0gbV90b2tlbkNoYXIpICYmIChtX3Rva2VuLmxlbmd0aCgpID4gMSkgJiYgQ2hhcmFjdGVyLmlzRGlnaXQoCi0gICAgICAgICAgICBtX3Rva2VuLmNoYXJBdCgxKSkpIHx8IENoYXJhY3Rlci5pc0RpZ2l0KG1fdG9rZW5DaGFyKSkpCi0gICAgewotICAgICAgYXBwZW5kT3AoMiwgT3BDb2Rlcy5PUF9OVU1CRVJMSVQpOwotICAgICAgTnVtYmVyKCk7Ci0KLSAgICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0gICAgfQotICAgIGVsc2UgaWYgKGxvb2thaGVhZCgnKCcsIDEpIHx8IChsb29rYWhlYWQoJzonLCAxKSAmJiBsb29rYWhlYWQoJygnLCAzKSkpCi0gICAgewotICAgICAgRnVuY3Rpb25DYWxsKCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBMb2NhdGlvblBhdGgoKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQXJndW1lbnQgICAgOjo9ICAgIEV4cHIKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBBcmd1bWVudCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfQVJHVU1FTlQpOwotICAgIEV4cHIoKTsKLQotICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIEZ1bmN0aW9uQ2FsbCAgICA6Oj0gICAgRnVuY3Rpb25OYW1lICcoJyAoIEFyZ3VtZW50ICggJywnIEFyZ3VtZW50KSopPyAnKScKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBGdW5jdGlvbkNhbGwoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICBpZiAobG9va2FoZWFkKCc6JywgMSkpCi0gICAgewotICAgICAgYXBwZW5kT3AoNCwgT3BDb2Rlcy5PUF9FWFRGVU5DVElPTik7Ci0KLSAgICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEggKyAxXSA9IG1fcXVldWVNYXJrIC0gMTsKLQotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBjb25zdW1lRXhwZWN0ZWQoJzonKTsKLQotICAgICAgbV9vcHMubV9vcE1hcFtvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCArIDJdID0gbV9xdWV1ZU1hcmsgLSAxOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBmdW5jVG9rID0gZ2V0RnVuY3Rpb25Ub2tlbihtX3Rva2VuKTsKLQotICAgICAgaWYgKC0xID09IGZ1bmNUb2spCi0gICAgICB7Ci0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ09VTEROT1RfRklORF9GVU5DVElPTiwKLSAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBtX3Rva2VuIH0pOyAgLy8iQ291bGQgbm90IGZpbmQgZnVuY3Rpb246ICIrbV90b2tlbisiKCkiKTsKLSAgICAgIH0KLQotICAgICAgc3dpdGNoIChmdW5jVG9rKQotICAgICAgewotICAgICAgY2FzZSBPcENvZGVzLk5PREVUWVBFX1BJIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9DT01NRU5UIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9URVhUIDoKLSAgICAgIGNhc2UgT3BDb2Rlcy5OT0RFVFlQRV9OT0RFIDoKLSAgICAgICAgTG9jYXRpb25QYXRoKCk7Ci0KLSAgICAgICAgcmV0dXJuOwotICAgICAgZGVmYXVsdCA6Ci0gICAgICAgIGFwcGVuZE9wKDMsIE9wQ29kZXMuT1BfRlVOQ1RJT04pOwotCi0gICAgICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEggKyAxXSA9IGZ1bmNUb2s7Ci0gICAgICB9Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLQotICAgIGNvbnN1bWVFeHBlY3RlZCgnKCcpOwotCi0gICAgd2hpbGUgKCF0b2tlbklzKCcpJykgJiYgbV90b2tlbiAhPSBudWxsKQotICAgIHsKLSAgICAgIGlmICh0b2tlbklzKCcsJykpCi0gICAgICB7Ci0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRk9VTkRfQ09NTUFfQlVUX05PX1BSRUNFRElOR19BUkcsIG51bGwpOyAgLy8iRm91bmQgJywnIGJ1dCBubyBwcmVjZWRpbmcgYXJndW1lbnQhIik7Ci0gICAgICB9Ci0KLSAgICAgIEFyZ3VtZW50KCk7Ci0KLSAgICAgIGlmICghdG9rZW5JcygnKScpKQotICAgICAgewotICAgICAgICBjb25zdW1lRXhwZWN0ZWQoJywnKTsKLQotICAgICAgICBpZiAodG9rZW5JcygnKScpKQotICAgICAgICB7Ci0gICAgICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9GT1VORF9DT01NQV9CVVRfTk9fRk9MTE9XSU5HX0FSRywKLSAgICAgICAgICAgICAgICBudWxsKTsgIC8vIkZvdW5kICcsJyBidXQgbm8gZm9sbG93aW5nIGFyZ3VtZW50ISIpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgY29uc3VtZUV4cGVjdGVkKCcpJyk7Ci0KLSAgICAvLyBUZXJtaW5hdGUgZm9yIHNhZmV0eS4KLSAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXV0gPSBPcENvZGVzLkVORE9QOwotICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSArPSAxOwotICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICB9Ci0KLSAgLy8gPT09PT09PT09PT09PSBHUkFNTUFSIEZVTkNUSU9OUyA9PT09PT09PT09PT09PT09PQotCi0gIC8qKgotICAgKgotICAgKiBMb2NhdGlvblBhdGggOjo9IFJlbGF0aXZlTG9jYXRpb25QYXRoCi0gICAqIHwgQWJzb2x1dGVMb2NhdGlvblBhdGgKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBMb2NhdGlvblBhdGgoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICAvLyBpbnQgbG9jYXRpb25QYXRoT3BQb3MgPSBvcFBvczsKLSAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX0xPQ0FUSU9OUEFUSCk7Ci0KLSAgICBpZiAodG9rZW5JcygnLycpKQotICAgIHsKLSAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuRlJPTV9ST09UKTsKLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gMl0gPSA0OwotICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSAxXSA9Ci0gICAgICAgIE9wQ29kZXMuTk9ERVRZUEVfUk9PVDsKLQotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotCi0gICAgaWYgKG1fdG9rZW4gIT0gbnVsbCkKLSAgICB7Ci0gICAgICBSZWxhdGl2ZUxvY2F0aW9uUGF0aCgpOwotICAgIH0KLQotICAgIC8vIFRlcm1pbmF0ZSBmb3Igc2FmZXR5LgotICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IE9wQ29kZXMuRU5ET1A7Ci0gICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdICs9IDE7Ci0gICAgbV9vcHMubV9vcE1hcFtvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSF0gPQotICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogUmVsYXRpdmVMb2NhdGlvblBhdGggOjo9IFN0ZXAKLSAgICogfCBSZWxhdGl2ZUxvY2F0aW9uUGF0aCAnLycgU3RlcAotICAgKiB8IEFiYnJldmlhdGVkUmVsYXRpdmVMb2NhdGlvblBhdGgKLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBSZWxhdGl2ZUxvY2F0aW9uUGF0aCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0ZXAoKTsKLQotICAgIHdoaWxlICh0b2tlbklzKCcvJykpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBTdGVwKCk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIFN0ZXAgICAgOjo9ICAgIEJhc2lzIFByZWRpY2F0ZQotICAgKiB8IEFiYnJldmlhdGVkU3RlcAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFN0ZXAoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICBpZiAodG9rZW5JcygiLiIpKQotICAgIHsKLSAgICAgIG5leHRUb2tlbigpOwotCi0gICAgICBpZiAodG9rZW5JcygnWycpKQotICAgICAgewotICAgICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1BSRURJQ0FURV9JTExFR0FMX1NZTlRBWCwgbnVsbCk7ICAvLyInLi5bcHJlZGljYXRlXScgb3IgJy5bcHJlZGljYXRlXScgaXMgaWxsZWdhbCBzeW50YXguICBVc2UgJ3NlbGY6Om5vZGUoKVtwcmVkaWNhdGVdJyBpbnN0ZWFkLiIpOwotICAgICAgfQotCi0gICAgICBhcHBlbmRPcCg0LCBPcENvZGVzLkZST01fU0VMRik7Ci0KLSAgICAgIC8vIFRlbGwgaG93IGxvbmcgdGhlIHN0ZXAgaXMgd2l0aG91dCB0aGUgcHJlZGljYXRlCi0gICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIDJdID0gNDsKLSAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gMV0gPQotICAgICAgICBPcENvZGVzLk5PREVUWVBFX05PREU7Ci0gICAgfQotICAgIGVsc2UgaWYgKHRva2VuSXMoIi4uIikpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBhcHBlbmRPcCg0LCBPcENvZGVzLkZST01fUEFSRU5UKTsKLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gMl0gPSA0OwotICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSAxXSA9Ci0gICAgICAgIE9wQ29kZXMuTk9ERVRZUEVfTk9ERTsKLSAgICB9Ci0KLSAgICAvLyBUaGVyZSBpcyBwcm9iYWJseSBhIGJldHRlciB3YXkgdG8gdGVzdCBmb3IgdGhpcyAKLSAgICAvLyB0cmFuc2l0aW9uLi4uIGJ1dCBpdCBnZXRzIHJlYWwgaGFpcnkgaWYgeW91IHRyeSAKLSAgICAvLyB0byBkbyBpdCBpbiBiYXNpcygpLgotICAgIGVsc2UgaWYgKHRva2VuSXMoJyonKSB8fCB0b2tlbklzKCdAJykgfHwgdG9rZW5JcygnLycpCi0gICAgICAgICAgICAgfHwgdG9rZW5JcygnXycpIHx8IChtX3Rva2VuIT0gbnVsbCAmJiBDaGFyYWN0ZXIuaXNMZXR0ZXIobV90b2tlbi5jaGFyQXQoMCkpKSkKLSAgICB7Ci0gICAgICBCYXNpcygpOwotCi0gICAgICB3aGlsZSAodG9rZW5JcygnWycpKQotICAgICAgewotICAgICAgICBQcmVkaWNhdGUoKTsKLSAgICAgIH0KLQotICAgICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgZW50aXJlIHN0ZXAgaXMuCi0gICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBCYXNpcyAgICA6Oj0gICAgQXhpc05hbWUgJzo6JyBOb2RlVGVzdAotICAgKiB8IEFiYnJldmlhdGVkQmFzaXMKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBCYXNpcygpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLSAgICBpbnQgYXhlc1R5cGU7Ci0KLSAgICAvLyBUaGUgbmV4dCBibG9ja3MgZ3VhcmFudGVlIHRoYXQgYSBGUk9NX1hYWCB3aWxsIGJlIGFkZGVkLgotICAgIGlmIChsb29rYWhlYWQoIjo6IiwgMSkpCi0gICAgewotICAgICAgYXhlc1R5cGUgPSBBeGlzTmFtZSgpOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgICBlbHNlIGlmICh0b2tlbklzKCdAJykpCi0gICAgewotICAgICAgYXhlc1R5cGUgPSBPcENvZGVzLkZST01fQVRUUklCVVRFUzsKLQotICAgICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHRva2VuSXMoJy8nKSkKLSAgICB7Ci0gICAgICBheGVzVHlwZSA9IE9wQ29kZXMuRlJPTV9ERVNDRU5EQU5UU19PUl9TRUxGOwotCi0gICAgICBhcHBlbmRPcCgyLCBheGVzVHlwZSk7Ci0KLSAgICAgIC8vIEhhdmUgdG8gZml4IHVwIGZvciBwYXR0ZXJucyBzdWNoIGFzICcvL0Bmb28nIG9yICcvL2F0dHJpYnV0ZTo6Zm9vJywKLSAgICAgIC8vIHdoaWNoIHRyYW5zbGF0ZSB0byAnZGVzY2VuZGFudC1vci1zZWxmOjpub2RlKCkvYXR0cmlidXRlOjpmb28nLgotICAgICAgLy8gbm90aWNlIEkgbGVhdmUgdGhlICcvJyBvbiB0aGUgcXVldWUsIHNvIHRoZSBuZXh0IHdpbGwgYmUgcHJvY2Vzc2VkCi0gICAgICAvLyBieSBhIHJlZ3VsYXIgc3RlcCBwYXR0ZXJuLgotICAgICAgLy8gaWYobG9va2FoZWFkKCdAJywgMSkgfHwgbG9va2FoZWFkKCI6OiIsIDIpKQotICAgICAgewotCi0gICAgICAgIC8vIE1ha2Ugcm9vbSBmb3IgdGVsbGluZyBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdICs9IDE7Ci0gICAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9Ci0gICAgICAgICAgT3BDb2Rlcy5OT0RFVFlQRV9OT0RFOwotICAgICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgICAgICAvLyBUZWxsIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGhvdXQgdGhlIHByZWRpY2F0ZQotICAgICAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIICsgMV0gPQotICAgICAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotCi0gICAgICAgIHJldHVybjsgIC8vIG1ha2UgYSBxdWljayBleGl0Li4uCi0gICAgICB9Ci0KLSAgICAgIC8vIGVsc2UKLSAgICAgIC8vIHsKLSAgICAgIC8vICBuZXh0VG9rZW4oKTsKLSAgICAgIC8vIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGF4ZXNUeXBlID0gT3BDb2Rlcy5GUk9NX0NISUxEUkVOOwotCi0gICAgICBhcHBlbmRPcCgyLCBheGVzVHlwZSk7Ci0gICAgfQotCi0gICAgLy8gTWFrZSByb29tIGZvciB0ZWxsaW5nIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGhvdXQgdGhlIHByZWRpY2F0ZQotICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSArPSAxOwotCi0gICAgTm9kZVRlc3QoYXhlc1R5cGUpOwotCi0gICAgLy8gVGVsbCBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIICsgMV0gPQotICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdIC0gb3BQb3M7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQmFzaXMgICAgOjo9ICAgIEF4aXNOYW1lICc6OicgTm9kZVRlc3QKLSAgICogfCBBYmJyZXZpYXRlZEJhc2lzCi0gICAqCi0gICAqIEByZXR1cm4gRlJPTV9YWFggYXhlcyB0eXBlLCBmb3VuZCBpbiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5LZXl3b3Jkc30uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBBeGlzTmFtZSgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIE9iamVjdCB2YWwgPSBLZXl3b3Jkcy5tX2F4aXNuYW1lcy5nZXQobV90b2tlbik7Ci0KLSAgICBpZiAobnVsbCA9PSB2YWwpCi0gICAgewotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9JTExFR0FMX0FYSVNfTkFNRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgbV90b2tlbiB9KTsgIC8vImlsbGVnYWwgYXhpcyBuYW1lOiAiK21fdG9rZW4pOwotICAgIH0KLQotICAgIGludCBheGVzVHlwZSA9ICgoSW50ZWdlcikgdmFsKS5pbnRWYWx1ZSgpOwotCi0gICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotCi0gICAgcmV0dXJuIGF4ZXNUeXBlOwotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIE5vZGVUZXN0ICAgIDo6PSAgICBXaWxkY2FyZE5hbWUKLSAgICogfCBOb2RlVHlwZSAnKCcgJyknCi0gICAqIHwgJ3Byb2Nlc3NpbmctaW5zdHJ1Y3Rpb24nICcoJyBMaXRlcmFsICcpJwotICAgKgotICAgKiBAcGFyYW0gYXhlc1R5cGUgRlJPTV9YWFggYXhlcyB0eXBlLCBmb3VuZCBpbiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5LZXl3b3Jkc30uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgTm9kZVRlc3QoaW50IGF4ZXNUeXBlKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZiAobG9va2FoZWFkKCcoJywgMSkpCi0gICAgewotICAgICAgT2JqZWN0IG5vZGVUZXN0T3AgPSBLZXl3b3Jkcy5tX25vZGV0eXBlcy5nZXQobV90b2tlbik7Ci0KLSAgICAgIGlmIChudWxsID09IG5vZGVUZXN0T3ApCi0gICAgICB7Ci0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVU5LTk9XTl9OT0RFVFlQRSwKLSAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBtX3Rva2VuIH0pOyAgLy8iVW5rbm93biBub2RldHlwZTogIittX3Rva2VuKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0KLSAgICAgICAgaW50IG50ID0gKChJbnRlZ2VyKSBub2RlVGVzdE9wKS5pbnRWYWx1ZSgpOwotCi0gICAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IG50OwotICAgICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgICAgICBjb25zdW1lRXhwZWN0ZWQoJygnKTsKLQotICAgICAgICBpZiAoT3BDb2Rlcy5OT0RFVFlQRV9QSSA9PSBudCkKLSAgICAgICAgewotICAgICAgICAgIGlmICghdG9rZW5JcygnKScpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIExpdGVyYWwoKTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBjb25zdW1lRXhwZWN0ZWQoJyknKTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLQotICAgICAgLy8gQXNzdW1lIG5hbWUgb2YgYXR0cmlidXRlIG9yIGVsZW1lbnQuCi0gICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXV0gPSBPcENvZGVzLk5PREVOQU1FOwotICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdICs9IDE7Ci0KLSAgICAgIGlmIChsb29rYWhlYWQoJzonLCAxKSkKLSAgICAgIHsKLSAgICAgICAgaWYgKHRva2VuSXMoJyonKSkKLSAgICAgICAgewotICAgICAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9Ci0gICAgICAgICAgICBPcENvZGVzLkVMRU1XSUxEQ0FSRDsKLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXV0gPSBtX3F1ZXVlTWFyawotICAgICAgICAgICAgICAgICAgLSAxOwotICAgICAgICB9Ci0KLSAgICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICAgIGNvbnN1bWVFeHBlY3RlZCgnOicpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXV0gPSBPcENvZGVzLkVNUFRZOwotICAgICAgfQotCi0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgICAgaWYgKHRva2VuSXMoJyonKSkKLSAgICAgIHsKLSAgICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF1dID0KLSAgICAgICAgICBPcENvZGVzLkVMRU1XSUxEQ0FSRDsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgaWYgKE9wQ29kZXMuRlJPTV9OQU1FU1BBQ0UgPT0gYXhlc1R5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gKFN0cmluZykgdGhpcy5tX29wcy5tX3Rva2VuUXVldWVbbV9xdWV1ZU1hcmsgLSAxXTsKLSAgICAgICAgICBTdHJpbmcgbmFtZXNwYWNlID0KLSAgICAgICAgICAgICgoUHJlZml4UmVzb2x2ZXIpIG1fbmFtZXNwYWNlQ29udGV4dCkuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KAotICAgICAgICAgICAgICBwcmVmaXgpOwotCi0gICAgICAgICAgdGhpcy5tX29wcy5tX3Rva2VuUXVldWVbbV9xdWV1ZU1hcmsgLSAxXSA9IG5hbWVzcGFjZTsKLSAgICAgICAgfQotCi0gICAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IG1fcXVldWVNYXJrIC0gMTsKLSAgICAgIH0KLQotICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdICs9IDE7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBQcmVkaWNhdGUgOjo9ICdbJyBQcmVkaWNhdGVFeHByICddJwotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFByZWRpY2F0ZSgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICh0b2tlbklzKCdbJykpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBQcmVkaWNhdGVFeHByKCk7Ci0gICAgICBjb25zdW1lRXhwZWN0ZWQoJ10nKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogUHJlZGljYXRlRXhwciA6Oj0gRXhwcgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFByZWRpY2F0ZUV4cHIoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0KLSAgICBhcHBlbmRPcCgyLCBPcENvZGVzLk9QX1BSRURJQ0FURSk7Ci0gICAgRXhwcigpOwotCi0gICAgLy8gVGVybWluYXRlIGZvciBzYWZldHkuCi0gICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF1dID0gT3BDb2Rlcy5FTkRPUDsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLSAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBvcFBvczsKLSAgfQotCi0gIC8qKgotICAgKiBRTmFtZSA6Oj0gIChQcmVmaXggJzonKT8gTG9jYWxQYXJ0Ci0gICAqIFByZWZpeCA6Oj0gIE5DTmFtZQotICAgKiBMb2NhbFBhcnQgOjo9ICBOQ05hbWUKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBRTmFtZSgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICAvLyBOYW1lc3BhY2UKLSAgICBpZihsb29rYWhlYWQoJzonLCAxKSkKLSAgICB7Ci0gICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXV0gPSBtX3F1ZXVlTWFyayAtIDE7Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBjb25zdW1lRXhwZWN0ZWQoJzonKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IE9wQ29kZXMuRU1QVFk7Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLSAgICB9Ci0gICAgCi0gICAgLy8gTG9jYWwgbmFtZQotICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IG1fcXVldWVNYXJrIC0gMTsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgIG5leHRUb2tlbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIE5DTmFtZSA6Oj0gIChMZXR0ZXIgfCAnXycpIChOQ05hbWVDaGFyKQotICAgKiBOQ05hbWVDaGFyIDo6PSAgTGV0dGVyIHwgRGlnaXQgfCAnLicgfCAnLScgfCAnXycgfCBDb21iaW5pbmdDaGFyIHwgRXh0ZW5kZXIKLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIE5DTmFtZSgpCi0gIHsKLQotICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IG1fcXVldWVNYXJrIC0gMTsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgIG5leHRUb2tlbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB2YWx1ZSBvZiB0aGUgTGl0ZXJhbCBpcyB0aGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBpbnNpZGUKLSAgICogdGhlICIgb3IgJyBjaGFyYWN0ZXJzPi4KLSAgICoKLSAgICogTGl0ZXJhbCAgOjo9ICAnIicgW14iXSogJyInCi0gICAqIHwgIiciIFteJ10qICInIgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIExpdGVyYWwoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgbGFzdCA9IG1fdG9rZW4ubGVuZ3RoKCkgLSAxOwotICAgIGNoYXIgYzAgPSBtX3Rva2VuQ2hhcjsKLSAgICBjaGFyIGNYID0gbV90b2tlbi5jaGFyQXQobGFzdCk7Ci0KLSAgICBpZiAoKChjMCA9PSAnXCInKSAmJiAoY1ggPT0gJ1wiJykpIHx8ICgoYzAgPT0gJ1wnJykgJiYgKGNYID09ICdcJycpKSkKLSAgICB7Ci0KLSAgICAgIC8vIE11dGF0ZSB0aGUgdG9rZW4gdG8gcmVtb3ZlIHRoZSBxdW90ZXMgYW5kIGhhdmUgdGhlIFhTdHJpbmcgb2JqZWN0Ci0gICAgICAvLyBhbHJlYWR5IG1hZGUuCi0gICAgICBpbnQgdG9rZW5RdWV1ZVBvcyA9IG1fcXVldWVNYXJrIC0gMTsKLQotICAgICAgbV9vcHMubV90b2tlblF1ZXVlW3Rva2VuUXVldWVQb3NdID0gbnVsbDsKLQotICAgICAgT2JqZWN0IG9iaiA9IG5ldyBYU3RyaW5nKG1fdG9rZW4uc3Vic3RyaW5nKDEsIGxhc3QpKTsKLQotICAgICAgbV9vcHMubV90b2tlblF1ZXVlW3Rva2VuUXVldWVQb3NdID0gb2JqOwotCi0gICAgICAvLyBsaXQgPSBtX3Rva2VuLnN1YnN0cmluZygxLCBsYXN0KTsKLSAgICAgIG1fb3BzLm1fb3BNYXBbbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdXSA9IHRva2VuUXVldWVQb3M7Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1BBVFRFUk5fTElURVJBTF9ORUVEU19CRV9RVU9URUQsCi0gICAgICAgICAgICBuZXcgT2JqZWN0W117IG1fdG9rZW4gfSk7ICAvLyJQYXR0ZXJuIGxpdGVyYWwgKCIrbV90b2tlbisiKSBuZWVkcyB0byBiZSBxdW90ZWQhIik7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqCi0gICAqIE51bWJlciA6Oj0gWzAtOV0rKCcuJ1swLTldKyk/IHwgJy4nWzAtOV0rCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgTnVtYmVyKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV90b2tlbikKLSAgICB7Ci0KLSAgICAgIC8vIE11dGF0ZSB0aGUgdG9rZW4gdG8gcmVtb3ZlIHRoZSBxdW90ZXMgYW5kIGhhdmUgdGhlIFhOdW1iZXIgb2JqZWN0Ci0gICAgICAvLyBhbHJlYWR5IG1hZGUuCi0gICAgICBkb3VibGUgbnVtOwotCi0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgbnVtID0gRG91YmxlLnZhbHVlT2YobV90b2tlbikuZG91YmxlVmFsdWUoKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKQotICAgICAgewotICAgICAgICBudW0gPSAwLjA7ICAvLyB0byBzaHV0IHVwIGNvbXBpbGVyLgotCi0gICAgICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiwKLSAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBtX3Rva2VuIH0pOyAgLy9tX3Rva2VuKyIgY291bGQgbm90IGJlIGZvcm1hdHRlZCB0byBhIG51bWJlciEiKTsKLSAgICAgIH0KLQotICAgICAgbV9vcHMubV90b2tlblF1ZXVlW21fcXVldWVNYXJrIC0gMV0gPSBuZXcgWE51bWJlcihudW0pOwotICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF1dID0gbV9xdWV1ZU1hcmsgLSAxOwotICAgICAgbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdICs9IDE7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgfQotCi0gIC8vID09PT09PT09PT09PT0gUEFUVEVSTiBGVU5DVElPTlMgPT09PT09PT09PT09PT09PT0KLQotICAvKioKLSAgICoKLSAgICogUGF0dGVybiAgOjo9ICBMb2NhdGlvblBhdGhQYXR0ZXJuCi0gICAqIHwgUGF0dGVybiAnfCcgTG9jYXRpb25QYXRoUGF0dGVybgotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFBhdHRlcm4oKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICB3aGlsZSAodHJ1ZSkKLSAgICB7Ci0gICAgICBMb2NhdGlvblBhdGhQYXR0ZXJuKCk7Ci0KLSAgICAgIGlmICh0b2tlbklzKCd8JykpCi0gICAgICB7Ci0gICAgICAgIG5leHRUb2tlbigpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICoKLSAgICogTG9jYXRpb25QYXRoUGF0dGVybiAgOjo9ICAnLycgUmVsYXRpdmVQYXRoUGF0dGVybj8KLSAgICogfCBJZEtleVBhdHRlcm4gKCgnLycgfCAnLy8nKSBSZWxhdGl2ZVBhdGhQYXR0ZXJuKT8KLSAgICogfCAnLy8nPyBSZWxhdGl2ZVBhdGhQYXR0ZXJuCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgTG9jYXRpb25QYXRoUGF0dGVybigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBvcFBvcyA9IG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXTsKLQotICAgIGFwcGVuZE9wKDIsIE9wQ29kZXMuT1BfTE9DQVRJT05QQVRIUEFUVEVSTik7Ci0KLSAgICBpZiAobG9va2FoZWFkKCcoJywgMSkKLSAgICAgICAgICAgICYmICh0b2tlbklzKEtleXdvcmRzLkZVTkNfSURfU1RSSU5HKQotICAgICAgICAgICAgICAgIHx8IHRva2VuSXMoS2V5d29yZHMuRlVOQ19LRVlfU1RSSU5HKSkpCi0gICAgewotICAgICAgSWRLZXlQYXR0ZXJuKCk7Ci0KLSAgICAgIGlmICh0b2tlbklzKCcvJykgJiYgbG9va2FoZWFkKCcvJywgMSkpCi0gICAgICB7Ci0gICAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuTUFUQ0hfQU5ZX0FOQ0VTVE9SKTsKLQotICAgICAgICAvLyBUZWxsIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGhvdXQgdGhlIHByZWRpY2F0ZQotICAgICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIDJdID0gNDsKLSAgICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSAxXSA9Ci0gICAgICAgICAgT3BDb2Rlcy5OT0RFVFlQRV9GVU5DVEVTVDsKLQotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKHRva2VuSXMoJy8nKSkKLSAgICB7Ci0gICAgICBpZiAobG9va2FoZWFkKCcvJywgMSkpCi0gICAgICB7Ci0gICAgICAgIGFwcGVuZE9wKDQsIE9wQ29kZXMuTUFUQ0hfQU5ZX0FOQ0VTVE9SKTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgYXBwZW5kT3AoNCwgT3BDb2Rlcy5GUk9NX1JPT1QpOwotICAgICAgfQotCi0gICAgICAvLyBUZWxsIGhvdyBsb25nIHRoZSBzdGVwIGlzIHdpdGhvdXQgdGhlIHByZWRpY2F0ZQotICAgICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSAyXSA9IDQ7Ci0gICAgICBtX29wcy5tX29wTWFwW21fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIDFdID0KLSAgICAgICAgT3BDb2Rlcy5OT0RFVFlQRV9ST09UOwotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0KLSAgICBpZiAoIXRva2VuSXMoJ3wnKSAmJiAobnVsbCAhPSBtX3Rva2VuKSkKLSAgICB7Ci0gICAgICBSZWxhdGl2ZVBhdGhQYXR0ZXJuKCk7Ci0gICAgfQotCi0gICAgLy8gVGVybWluYXRlIGZvciBzYWZldHkuCi0gICAgbV9vcHMubV9vcE1hcFttX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF1dID0gT3BDb2Rlcy5FTkRPUDsKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLSAgICBtX29wcy5tX29wTWFwW29wUG9zICsgT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSA9Ci0gICAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gLSBvcFBvczsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBJZEtleVBhdHRlcm4gIDo6PSAgJ2lkJyAnKCcgTGl0ZXJhbCAnKScKLSAgICogfCAna2V5JyAnKCcgTGl0ZXJhbCAnLCcgTGl0ZXJhbCAnKScKLSAgICogKEFsc28gaGFuZGxlIGRvYygpKQotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIElkS2V5UGF0dGVybigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBGdW5jdGlvbkNhbGwoKTsKLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBSZWxhdGl2ZVBhdGhQYXR0ZXJuICA6Oj0gIFN0ZXBQYXR0ZXJuCi0gICAqIHwgUmVsYXRpdmVQYXRoUGF0dGVybiAnLycgU3RlcFBhdHRlcm4KLSAgICogfCBSZWxhdGl2ZVBhdGhQYXR0ZXJuICcvLycgU3RlcFBhdHRlcm4KLSAgICoKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBSZWxhdGl2ZVBhdGhQYXR0ZXJuKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RlcFBhdHRlcm4oKTsKLQotICAgIHdoaWxlICh0b2tlbklzKCcvJykpCi0gICAgewotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgICBTdGVwUGF0dGVybigpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKgotICAgKiBTdGVwUGF0dGVybiAgOjo9ICBBYmJyZXZpYXRlZE5vZGVUZXN0U3RlcAotICAgKgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIFN0ZXBQYXR0ZXJuKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIEFiYnJldmlhdGVkTm9kZVRlc3RTdGVwKCk7Ci0gIH0KLQotICAvKioKLSAgICoKLSAgICogQWJicmV2aWF0ZWROb2RlVGVzdFN0ZXAgICAgOjo9ICAgICdAJz8gTm9kZVRlc3QgUHJlZGljYXRlCi0gICAqCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgQWJicmV2aWF0ZWROb2RlVGVzdFN0ZXAoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgb3BQb3MgPSBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF07Ci0gICAgaW50IGF4ZXNUeXBlOwotCi0gICAgLy8gVGhlIG5leHQgYmxvY2tzIGd1YXJhbnRlZSB0aGF0IGEgTUFUQ0hfWFhYIHdpbGwgYmUgYWRkZWQuCi0gICAgaW50IG1hdGNoVHlwZVBvcyA9IC0xOwotCi0gICAgaWYgKHRva2VuSXMoJ0AnKSkKLSAgICB7Ci0gICAgICBheGVzVHlwZSA9IE9wQ29kZXMuTUFUQ0hfQVRUUklCVVRFOwotCi0gICAgICBhcHBlbmRPcCgyLCBheGVzVHlwZSk7Ci0gICAgICBuZXh0VG9rZW4oKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAodGhpcy5sb29rYWhlYWQoIjo6IiwgMSkpCi0gICAgewotICAgICAgaWYgKHRva2VuSXMoImF0dHJpYnV0ZSIpKQotICAgICAgewotICAgICAgICBheGVzVHlwZSA9IE9wQ29kZXMuTUFUQ0hfQVRUUklCVVRFOwotCi0gICAgICAgIGFwcGVuZE9wKDIsIGF4ZXNUeXBlKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKHRva2VuSXMoImNoaWxkIikpCi0gICAgICB7Ci0gICAgICAgIGF4ZXNUeXBlID0gT3BDb2Rlcy5NQVRDSF9JTU1FRElBVEVfQU5DRVNUT1I7Ci0KLSAgICAgICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBheGVzVHlwZSA9IC0xOwotCi0gICAgICAgIHRoaXMuZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9BWEVTX05PVF9BTExPV0VELAotICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgdGhpcy5tX3Rva2VuIH0pOwotICAgICAgfQotCi0gICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLSAgICBlbHNlIGlmICh0b2tlbklzKCcvJykpCi0gICAgewotICAgICAgYXhlc1R5cGUgPSBPcENvZGVzLk1BVENIX0FOWV9BTkNFU1RPUjsKLQotICAgICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotICAgICAgbmV4dFRva2VuKCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpZiAodG9rZW5JcygnLycpKQotICAgICAgewotICAgICAgICBuZXh0VG9rZW4oKTsKLSAgICAgIH0KLQotICAgICAgbWF0Y2hUeXBlUG9zID0gbV9vcHMubV9vcE1hcFtPcE1hcC5NQVBJTkRFWF9MRU5HVEhdOwotICAgICAgYXhlc1R5cGUgPSBPcENvZGVzLk1BVENIX0lNTUVESUFURV9BTkNFU1RPUjsKLQotICAgICAgYXBwZW5kT3AoMiwgYXhlc1R5cGUpOwotICAgIH0KLQotICAgIC8vIE1ha2Ugcm9vbSBmb3IgdGVsbGluZyBob3cgbG9uZyB0aGUgc3RlcCBpcyB3aXRob3V0IHRoZSBwcmVkaWNhdGUKLSAgICBtX29wcy5tX29wTWFwW09wTWFwLk1BUElOREVYX0xFTkdUSF0gKz0gMTsKLQotICAgIE5vZGVUZXN0KGF4ZXNUeXBlKTsKLQotICAgIC8vIFRlbGwgaG93IGxvbmcgdGhlIHN0ZXAgaXMgd2l0aG91dCB0aGUgcHJlZGljYXRlCi0gICAgbV9vcHMubV9vcE1hcFtvcFBvcyArIE9wTWFwLk1BUElOREVYX0xFTkdUSCArIDFdID0KLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotCi0gICAgd2hpbGUgKHRva2VuSXMoJ1snKSkKLSAgICB7Ci0gICAgICBQcmVkaWNhdGUoKTsKLSAgICB9Ci0KLSAgICBpZiAoKG1hdGNoVHlwZVBvcyA+IC0xKSAmJiB0b2tlbklzKCcvJykgJiYgbG9va2FoZWFkKCcvJywgMSkpCi0gICAgewotICAgICAgbV9vcHMubV9vcE1hcFttYXRjaFR5cGVQb3NdID0gT3BDb2Rlcy5NQVRDSF9BTllfQU5DRVNUT1I7Ci0KLSAgICAgIG5leHRUb2tlbigpOwotICAgIH0KLQotICAgIC8vIFRlbGwgaG93IGxvbmcgdGhlIGVudGlyZSBzdGVwIGlzLgotICAgIG1fb3BzLm1fb3BNYXBbb3BQb3MgKyBPcE1hcC5NQVBJTkRFWF9MRU5HVEhdID0KLSAgICAgIG1fb3BzLm1fb3BNYXBbT3BNYXAuTUFQSU5ERVhfTEVOR1RIXSAtIG9wUG9zOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlci9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQzZGQzMjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsOSArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIHBhcnNpbmcgYW5kIGNvbXBpbGF0aW9uIHN1cHBvcnQgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRzIGFuIFhQYXRoIHBhcnNlciB3aGljaCBwcm9kdWNlcyBhbiBPcE1hcCwgYW5kIGEgc28tY2FsbGVkIENvbXBpbGVyCi0gICAgd2hpY2ggcHJvZHVjZXMgYW4gZXhwcmVzc2lvbiB0cmVlIGZvciBmYXN0IGV2YWx1YXRpb24uPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jQm9vbGVhbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNCb29sZWFuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGYyYjljNWUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNCb29sZWFuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIEJvb2xlYW4oKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNCb29sZWFuIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLmJvb2woKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jQ2VpbGluZy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNDZWlsaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE5YjJjMGQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNDZWlsaW5nLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotaW1wb3J0IGphdmEubGFuZy5NYXRoOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBDZWlsaW5nKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jQ2VpbGluZyBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKE1hdGguY2VpbChtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkubnVtKCkpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNDb25jYXQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jQ29uY2F0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGMyOGU1NjEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNDb25jYXQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgQ29uY2F0KCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jQ29uY2F0IGV4dGVuZHMgRnVuY3Rpb25NdWx0aUFyZ3MKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIC8vIENvbXBpbGVyIHNheXMgd2UgbXVzdCBoYXZlIGF0IGxlYXN0IHR3byBhcmd1bWVudHMuCi0gICAgc2IuYXBwZW5kKG1fYXJnMC5leGVjdXRlKHhjdHh0KS5zdHIoKSk7Ci0gICAgc2IuYXBwZW5kKG1fYXJnMS5leGVjdXRlKHhjdHh0KS5zdHIoKSk7Ci0KLSAgICBpZiAobnVsbCAhPSBtX2FyZzIpCi0gICAgICBzYi5hcHBlbmQobV9hcmcyLmV4ZWN1dGUoeGN0eHQpLnN0cigpKTsKLQotICAgIGlmIChudWxsICE9IG1fYXJncykKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fYXJncy5sZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgc2IuYXBwZW5kKG1fYXJnc1tpXS5leGVjdXRlKHhjdHh0KS5zdHIoKSk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIG5ldyBYU3RyaW5nKHNiLnRvU3RyaW5nKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRoYXQgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gaXMgY29ycmVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSA8IDIpCi0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKCI+MSIpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0NvbnRhaW5zLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0NvbnRhaW5zLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcwNDNmN2YuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNDb250YWlucy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBDb250YWlucygpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0NvbnRhaW5zIGV4dGVuZHMgRnVuY3Rpb24yQXJncwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHMxID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIFN0cmluZyBzMiA9IG1fYXJnMS5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLQotICAgIC8vIEFkZCB0aGlzIGNoZWNrIGZvciBKREsgY29uc2lzdGVuY3kgZm9yIGVtcHR5IHN0cmluZ3MuCi0gICAgaWYgKHMxLmxlbmd0aCgpID09IDAgJiYgczIubGVuZ3RoKCkgPT0gMCkKLSAgICAgIHJldHVybiBYQm9vbGVhbi5TX1RSVUU7Ci0KLSAgICBpbnQgaW5kZXggPSBzMS5pbmRleE9mKHMyKTsKLQotICAgIHJldHVybiAoaW5kZXggPiAtMSkgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0NvdW50LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0NvdW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDlmOWJmZmQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNDb3VudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIENvdW50KCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jQ291bnQgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRFRNSXRlcmF0b3IgbmwgPSBtX2FyZzAuYXNJdGVyYXRvcih4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0KLSAgICAvLyBXZSBzaG91bGQgcHJvYmFibHkgbWFrZSBhIGZ1bmN0aW9uIG9uIHRoZSBpdGVyYXRvciBmb3IgdGhpcywgCi0gICAgLy8gYXMgYSBnaXZlbiBpbXBsZW1lbnRhdGlvbiBjb3VsZCBvcHRpbWl6ZS4KLSAgICBpbnQgaSA9IDA7Ci0KLSAgICB3aGlsZSAoRFRNLk5VTEwgIT0gbmwubmV4dE5vZGUoKSkKLSAgICB7Ci0gICAgICBpKys7Ci0gICAgfQotICAgIG5sLmRldGFjaCgpOwotCi0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKChkb3VibGUpIGkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0N1cnJlbnQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jQ3VycmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYTdlMmU0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jQ3VycmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLlByZWRpY2F0ZWROb2RlVGVzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Db250ZXh0Tm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLlN1YkNvbnRleHRMaXN0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgY3VycmVudCgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0N1cnJlbnQgZXh0ZW5kcyBGdW5jdGlvbgotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIC8vIElmIHdlJ3JlIGluIGEgcHJlZGljYXRlLCB0aGVuIHRoaXMgd2lsbCByZXR1cm4gbm9uLW51bGwuCi0gICAgT2JqZWN0IHN1YkNvbnRleHRMaXN0ID0geGN0eHQuZ2V0U3ViQ29udGV4dExpc3QoKTsKLSAgICBpbnQgY3VycmVudE5vZGU7Ci0KLSAgICAvLyAlVEJEJSBIYWNrIGNpdHkuLi4KLSAgICBpZiAobnVsbCAhPSBzdWJDb250ZXh0TGlzdCAmJiBzdWJDb250ZXh0TGlzdCBpbnN0YW5jZW9mIFByZWRpY2F0ZWROb2RlVGVzdCkKLSAgICB7Ci0gICAgICAvLyBQcmVkaWNhdGVkTm9kZVRlc3QgaXRlciA9IChQcmVkaWNhdGVkTm9kZVRlc3QpIHhjdHh0LmdldFN1YkNvbnRleHRMaXN0KCk7Ci0gICAgICAvLyBMb2NQYXRoSXRlcmF0b3IgbHBpID0gaXRlci5nZXRMb2NQYXRoSXRlcmF0b3IoKTsKLSAgICAgIExvY1BhdGhJdGVyYXRvciBscGkgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZUxpc3QoKTsKLQotICAgICAgY3VycmVudE5vZGUgPSBscGkuZ2V0Q3VycmVudENvbnRleHROb2RlKCk7ICAKLSAgICAgICAgCi0gICAgfQotICAgIGVsc2UgaWYoeGN0eHQuZ2V0SXRlcmF0b3JSb290KCkgIT0gRFRNLk5VTEwpCi0gICAgewotICAgICAgY3VycmVudE5vZGUgPSB4Y3R4dC5nZXRJdGVyYXRvclJvb3QoKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIERUTUl0ZXJhdG9yIGNubCA9IHhjdHh0LmdldENvbnRleHROb2RlTGlzdCgpOwotCi0gICAgICBpZiAobnVsbCAhPSBjbmwpCi0gICAgICB7Ci0gICAgICAgIC8vICVSRVZJRVclIE5vdCBzbyBjZXJ0YWluIHRoYXQgdGhpcyBpcyBkb2luZyB0aGUgcmlnaHQgdGhpbmc/Ci0gICAgICAgIGN1cnJlbnROb2RlID0gY25sLmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIGN1cnJlbnROb2RlID0gRFRNLk5VTEw7Ci0gICAgfQotICAgIC8vICBpZihEVE0uTlVMTCAhPSBjdXJyZW50Tm9kZSkKLSAgICAvLyAgewotICAgIC8vICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY3VycmVudE5vZGUpOwotICAgIC8vICAgIFN5c3RlbS5lcnIucHJpbnRsbigiY3VycmVudCBub2RlOiAiK2R0bS5nZXROb2RlTmFtZShjdXJyZW50Tm9kZSkrIlsiK0ludGVnZXIudG9IZXhTdHJpbmcoY3VycmVudE5vZGUpKyJdIik7Ci0gICAgLy8gIH0KLSAgICAvLyAgZWxzZQotICAgIC8vICB7Ci0gICAgLy8gICAgIFN5c3RlbS5lcnIucHJpbnRsbigiY3VycmVudCBub2RlOiBEVE0uTlVMTCIpOwotICAgIC8vICB9Ci0KLSAgICByZXR1cm4gbmV3IFhOb2RlU2V0KGN1cnJlbnROb2RlLCB4Y3R4dC5nZXREVE1NYW5hZ2VyKCkpOwotICB9Ci0gIAotICAvKioKLSAgICogTm8gYXJndW1lbnRzIHRvIHByb2Nlc3MsIHNvIHRoaXMgZG9lcyBub3RoaW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICAvLyBuby1vcAotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRG9jbG9jYXRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRG9jbG9jYXRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmFiZjAwNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0RvY2xvY2F0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBwcm9wcmlldGFyeSBkb2N1bWVudC1sb2NhdGlvbigpIGZ1bmN0aW9uLCB3aGljaCByZXR1cm5zCi0gKiBhIG5vZGUgc2V0IG9mIGRvY3VtZW50cy4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNEb2Nsb2NhdGlvbiBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IHdoZXJlTm9kZSA9IGdldEFyZzBBc05vZGUoeGN0eHQpOwotICAgIFN0cmluZyBmaWxlTG9jYXRpb24gPSBudWxsOwotCi0gICAgaWYgKERUTS5OVUxMICE9IHdoZXJlTm9kZSkKLSAgICB7Ci0gICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKHdoZXJlTm9kZSk7Ci0gICAgICAKLSAgICAgIC8vICVSRVZJRVclCi0gICAgICBpZiAoRFRNLkRPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPT0gIGR0bS5nZXROb2RlVHlwZSh3aGVyZU5vZGUpKQotICAgICAgewotICAgICAgICB3aGVyZU5vZGUgPSBkdG0uZ2V0Rmlyc3RDaGlsZCh3aGVyZU5vZGUpOwotICAgICAgfQotCi0gICAgICBpZiAoRFRNLk5VTEwgIT0gd2hlcmVOb2RlKQotICAgICAgeyAgICAgICAgCi0gICAgICAgIGZpbGVMb2NhdGlvbiA9IGR0bS5nZXREb2N1bWVudEJhc2VVUkkoKTsKLS8vICAgICAgICBpbnQgb3duZXIgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLS8vICAgICAgICBmaWxlTG9jYXRpb24gPSB4Y3R4dC5nZXRTb3VyY2VUcmVlTWFuYWdlcigpLmZpbmRVUklGcm9tRG9jKG93bmVyKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoKG51bGwgIT0gZmlsZUxvY2F0aW9uKSA/IGZpbGVMb2NhdGlvbiA6ICIiKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNFeHRFbGVtZW50QXZhaWxhYmxlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0V4dEVsZW1lbnRBdmFpbGFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTQ2ZGQ2My4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0V4dEVsZW1lbnRBdmFpbGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5FeHRlbnNpb25zVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuQ29uc3RhbnRzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgRXh0RWxlbWVudEF2YWlsYWJsZSgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0V4dEVsZW1lbnRBdmFpbGFibGUgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIHByZWZpeDsKLSAgICBTdHJpbmcgbmFtZXNwYWNlOwotICAgIFN0cmluZyBtZXRoTmFtZTsKLQotICAgIFN0cmluZyBmdWxsTmFtZSA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBpbnQgaW5kZXhPZk5TU2VwID0gZnVsbE5hbWUuaW5kZXhPZignOicpOwotCi0gICAgaWYgKGluZGV4T2ZOU1NlcCA8IDApCi0gICAgewotICAgICAgcHJlZml4ID0gIiI7Ci0gICAgICBuYW1lc3BhY2UgPSBDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkw7Ci0gICAgICBtZXRoTmFtZSA9IGZ1bGxOYW1lOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcHJlZml4ID0gZnVsbE5hbWUuc3Vic3RyaW5nKDAsIGluZGV4T2ZOU1NlcCk7Ci0gICAgICBuYW1lc3BhY2UgPSB4Y3R4dC5nZXROYW1lc3BhY2VDb250ZXh0KCkuZ2V0TmFtZXNwYWNlRm9yUHJlZml4KHByZWZpeCk7Ci0gICAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2UpCi0gICAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICAgICAgbWV0aE5hbWU9IGZ1bGxOYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLSAgICB9Ci0KLSAgICBpZiAobmFtZXNwYWNlLmVxdWFscyhDb25zdGFudHMuU19YU0xOQU1FU1BBQ0VVUkwpCi0gICAgfHwgIG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLlNfQlVJTFRJTl9FWFRFTlNJT05TX1VSTCkpCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lciA9IChUcmFuc2Zvcm1lckltcGwpIHhjdHh0LmdldE93bmVyT2JqZWN0KCk7Ci0gICAgICAgIHJldHVybiB0cmFuc2Zvcm1lci5nZXRTdHlsZXNoZWV0KCkuZ2V0QXZhaWxhYmxlRWxlbWVudHMoKS5jb250YWluc0tleSgKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBRTmFtZShuYW1lc3BhY2UsIG1ldGhOYW1lKSkKLSAgICAgICAgICAgICAgID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICBFeHRlbnNpb25zVGFibGUgZXRhYmxlID0geGN0eHQuZ2V0RXh0ZW5zaW9uc1RhYmxlKCk7Ci0KLSAgICAgIHJldHVybiBldGFibGUuZWxlbWVudEF2YWlsYWJsZShuYW1lc3BhY2UsIG1ldGhOYW1lKQotICAgICAgICAgICAgID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgICB9Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRXh0RnVuY3Rpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRXh0RnVuY3Rpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzM5YWU0MC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0V4dEZ1bmN0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMjIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy4qOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5FeHRlbnNpb25zVGFibGU7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy4qOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogQW4gb2JqZWN0IG9mIHRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBleHRlbnNpb24gY2FsbCBleHByZXNzaW9uLiAgV2hlbgotICogdGhlIGV4cHJlc3Npb24gZXhlY3V0ZXMsIGl0IGNhbGxzIEV4dGVuc2lvbnNUYWJsZSNleHRGdW5jdGlvbiwgYW5kIHRoZW4KLSAqIGNvbnZlcnRzIHRoZSByZXN1bHQgdG8gdGhlIGFwcHJvcHJpYXRlIFhPYmplY3QuCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jRXh0RnVuY3Rpb24gZXh0ZW5kcyBGdW5jdGlvbgotewotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIGZvciB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLCB3aGljaCBzaG91bGQgbm90IG5vcm1hbGx5Ci0gICAqICBiZSBudWxsIG9yIGVtcHR5LgotICAgKiAgQHNlcmlhbCAgICAKLSAgICovCi0gIFN0cmluZyBtX25hbWVzcGFjZTsKLQotICAvKioKLSAgICogVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGV4dGVuc2lvbi4KLSAgICogIEBzZXJpYWwgICAKLSAgICovCi0gIFN0cmluZyBtX2V4dGVuc2lvbk5hbWU7Ci0KLSAgLyoqCi0gICAqIFVuaXF1ZSBtZXRob2Qga2V5LCB3aGljaCBpcyBwYXNzZWQgdG8gRXh0ZW5zaW9uc1RhYmxlI2V4dEZ1bmN0aW9uIGluCi0gICAqICBvcmRlciB0byBhbGxvdyBjYWNoaW5nIG9mIHRoZSBtZXRob2QuCi0gICAqICBAc2VyaWFsIAotICAgKi8KLSAgT2JqZWN0IG1fbWV0aG9kS2V5OwotCi0gIC8qKgotICAgKiBBcnJheSBvZiBzdGF0aWMgZXhwcmVzc2lvbnMgd2hpY2ggcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXJzIHRvIHRoZQotICAgKiAgZnVuY3Rpb24uCi0gICAqICBAc2VyaWFsICAgCi0gICAqLwotICBWZWN0b3IgbV9hcmdWZWMgPSBuZXcgVmVjdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICogTkVFRFNET0MgQHBhcmFtIGdsb2JhbHNTaXplCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9hcmdWZWMpCi0gICAgewotICAgICAgaW50IG5BcmdzID0gbV9hcmdWZWMuc2l6ZSgpOwotCi0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BcmdzOyBpKyspCi0gICAgICB7Ci0gICAgICAgIEV4cHJlc3Npb24gYXJnID0gKEV4cHJlc3Npb24pIG1fYXJnVmVjLmVsZW1lbnRBdChpKTsKLQotICAgICAgICBhcmcuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICAgICAgfQotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgRnVuY0V4dEZ1bmN0aW9uIGJhc2VkIG9uIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uLAotICAgKiBhbmQgYSB1bmlxdWUgbWV0aG9kIGtleS4KLSAgICoKLSAgICogQHBhcmFtIG5hbWVzcGFjZSBUaGUgbmFtZXNwYWNlIGZvciB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uLCB3aGljaCBzaG91bGQKLSAgICogICAgICAgICAgICAgICAgICBub3Qgbm9ybWFsbHkgYmUgbnVsbCBvciBlbXB0eS4KLSAgICogQHBhcmFtIGV4dGVuc2lvbk5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGV4dGVuc2lvbi4KLSAgICogQHBhcmFtIG1ldGhvZEtleSBVbmlxdWUgbWV0aG9kIGtleSwgd2hpY2ggaXMgcGFzc2VkIHRvCi0gICAqICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uc1RhYmxlI2V4dEZ1bmN0aW9uIGluIG9yZGVyIHRvIGFsbG93IGNhY2hpbmcKLSAgICogICAgICAgICAgICAgICAgICBvZiB0aGUgbWV0aG9kLgotICAgKi8KLSAgcHVibGljIEZ1bmNFeHRGdW5jdGlvbihqYXZhLmxhbmcuU3RyaW5nIG5hbWVzcGFjZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGV4dGVuc2lvbk5hbWUsIE9iamVjdCBtZXRob2RLZXkpCi0gIHsKLQotICAgIG1fbmFtZXNwYWNlID0gbmFtZXNwYWNlOwotICAgIG1fZXh0ZW5zaW9uTmFtZSA9IGV4dGVuc2lvbk5hbWU7Ci0gICAgbV9tZXRob2RLZXkgPSBtZXRob2RLZXk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWE9iamVjdCByZXN1bHQ7Ci0gICAgVmVjdG9yIGFyZ1ZlYyA9IG5ldyBWZWN0b3IoKTsKLSAgICBpbnQgbkFyZ3MgPSBtX2FyZ1ZlYy5zaXplKCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG5BcmdzOyBpKyspCi0gICAgewotICAgICAgRXhwcmVzc2lvbiBhcmcgPSAoRXhwcmVzc2lvbikgbV9hcmdWZWMuZWxlbWVudEF0KGkpOwotCi0gICAgICBhcmdWZWMuYWRkRWxlbWVudChhcmcuZXhlY3V0ZSh4Y3R4dCkpOwotICAgIH0KLQotICAgIEV4dGVuc2lvbnNUYWJsZSBldGFibGUgPSB4Y3R4dC5nZXRFeHRlbnNpb25zVGFibGUoKTsKLSAgICBPYmplY3QgdmFsID0gZXRhYmxlLmV4dEZ1bmN0aW9uKG1fbmFtZXNwYWNlLCBtX2V4dGVuc2lvbk5hbWUsIGFyZ1ZlYywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fbWV0aG9kS2V5LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGN0eHQuZ2V0RXhwcmVzc2lvbkNvbnRleHQoKSk7Ci0KLSAgICBpZiAobnVsbCAhPSB2YWwpCi0gICAgewotICAgICAgcmVzdWx0ID0gWE9iamVjdC5jcmVhdGUodmFsLCB4Y3R4dCk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWE51bGwoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBhcmd1bWVudCBleHByZXNzaW9uIGZvciBhIGZ1bmN0aW9uLiAgVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZQotICAgKiBYUGF0aCBjb21waWxlci4KLSAgICoKLSAgICogQHBhcmFtIGFyZyBub24tbnVsbCBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGUgYXJndW1lbnQuCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIGFyZ3VtZW50IG51bWJlciBpbmRleC4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24gSWYgdGhlIGFyZ051bSBwYXJhbWV0ZXIgaXMgYmV5b25kIHdoYXQKLSAgICogaXMgc3BlY2lmaWVkIGZvciB0aGlzIGZ1bmN0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXJnKEV4cHJlc3Npb24gYXJnLCBpbnQgYXJnTnVtKQotICAgICAgICAgIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIG1fYXJnVmVjLmFkZEVsZW1lbnQoYXJnKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCBpcyBiZWluZyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb257fQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNFeHRGdW5jdGlvbkF2YWlsYWJsZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNFeHRGdW5jdGlvbkF2YWlsYWJsZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmODE5OTYxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRXh0RnVuY3Rpb25BdmFpbGFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkNvbnN0YW50czsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuRXh0ZW5zaW9uc1RhYmxlOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5LZXl3b3JkczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBFeHRGdW5jdGlvbkF2YWlsYWJsZSgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0V4dEZ1bmN0aW9uQXZhaWxhYmxlIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBwcmVmaXg7Ci0gICAgU3RyaW5nIG5hbWVzcGFjZTsKLSAgICBTdHJpbmcgbWV0aE5hbWU7Ci0KLSAgICBTdHJpbmcgZnVsbE5hbWUgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgaW50IGluZGV4T2ZOU1NlcCA9IGZ1bGxOYW1lLmluZGV4T2YoJzonKTsKLQotICAgIGlmIChpbmRleE9mTlNTZXAgPCAwKQotICAgIHsKLSAgICAgIHByZWZpeCA9ICIiOwotICAgICAgbmFtZXNwYWNlID0gQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMOwotICAgICAgbWV0aE5hbWUgPSBmdWxsTmFtZTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHByZWZpeCA9IGZ1bGxOYW1lLnN1YnN0cmluZygwLCBpbmRleE9mTlNTZXApOwotICAgICAgbmFtZXNwYWNlID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotICAgICAgaWYgKG51bGwgPT0gbmFtZXNwYWNlKQotICAgICAgICByZXR1cm4gWEJvb2xlYW4uU19GQUxTRTsKLSAgICAgICAgbWV0aE5hbWUgPSBmdWxsTmFtZS5zdWJzdHJpbmcoaW5kZXhPZk5TU2VwICsgMSk7Ci0gICAgfQotCi0gICAgaWYgKG5hbWVzcGFjZS5lcXVhbHMoQ29uc3RhbnRzLlNfWFNMTkFNRVNQQUNFVVJMKSkKLSAgICB7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIEtleXdvcmRzLmZ1bmN0aW9uQXZhaWxhYmxlKG1ldGhOYW1lKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgICB9Ci0gICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgRXh0ZW5zaW9uc1RhYmxlIGV0YWJsZSA9IHhjdHh0LmdldEV4dGVuc2lvbnNUYWJsZSgpOwotCi0gICAgICByZXR1cm4gZXRhYmxlLmZ1bmN0aW9uQXZhaWxhYmxlKG5hbWVzcGFjZSwgbWV0aE5hbWUpCi0gICAgICAgICAgICAgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNGYWxzZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNGYWxzZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5OWYwNDkxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRmFsc2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgRmFsc2UoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNGYWxzZSBleHRlbmRzIEZ1bmN0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBObyBhcmd1bWVudHMgdG8gcHJvY2Vzcywgc28gdGhpcyBkb2VzIG5vdGhpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIC8vIG5vLW9wCi0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNGbG9vci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNGbG9vci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkN2RjMGUxLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jRmxvb3IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDg3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBGbG9vcigpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0Zsb29yIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIoamF2YS5sYW5nLk1hdGguZmxvb3IobV9hcmcwLmV4ZWN1dGUoeGN0eHQpLm51bSgpKSk7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jR2VuZXJhdGVJZC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNHZW5lcmF0ZUlkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDcyMDE4M2IuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNHZW5lcmF0ZUlkLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIEdlbmVyYXRlSWQoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNHZW5lcmF0ZUlkIGV4dGVuZHMgRnVuY3Rpb25EZWYxQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgd2hpY2ggPSBnZXRBcmcwQXNOb2RlKHhjdHh0KTsKLQotICAgIGlmIChEVE0uTlVMTCAhPSB3aGljaCkKLSAgICB7Ci0gICAgICAvLyBOb3RlIHRoYXQgdGhpcyBpcyBhIGRpZmZlcmVudCB2YWx1ZSB0aGFuIGluIHByZXZpb3VzIHJlbGVhc2VzCi0gICAgICAvLyBvZiBYYWxhbi4gSXQncyBzZW5zaXRpdmUgdG8gdGhlIGV4YWN0IGVuY29kaW5nIG9mIHRoZSBub2RlCi0gICAgICAvLyBoYW5kbGUgYW55d2F5LCBzbyBmaWdodGluZyB0byBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRhYmlsaXR5Ci0gICAgICAvLyByZWFsbHkgZGlkbid0IG1ha2Ugc2Vuc2U7IGl0IG1heSBjaGFuZ2UgYWdhaW4gYXMgd2UgY29udGludWUKLSAgICAgIC8vIHRvIGV4cGVyaW1lbnQgd2l0aCBiYWxhbmNpbmcgZG9jdW1lbnQgYW5kIG5vZGUgbnVtYmVycyB3aXRoaW4KLSAgICAgIC8vIHRoYXQgdmFsdWUuCi0gICAgICByZXR1cm4gbmV3IFhTdHJpbmcoIk4iICsgSW50ZWdlci50b0hleFN0cmluZyh3aGljaCkudG9VcHBlckNhc2UoKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0lkLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0lkLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFiZmEzZDEuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNJZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTk1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKLWltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5ET01IZWxwZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLk5vZGVTZXREVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ1ZlY3RvcjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIElkKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jSWQgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotCi0gIC8qKgotICAgKiBGaWxsIGluIGEgbGlzdCB3aXRoIG5vZGVzIHRoYXQgbWF0Y2ggYSBzcGFjZSBkZWxpbWl0ZWQgbGlzdCBpZiBJRCAKLSAgICogSUQgcmVmZXJlbmNlcy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIFhQYXRoIGNvbnRleHQuCi0gICAqIEBwYXJhbSBkb2NDb250ZXh0IFRoZSBkb2N1bWVudCB3aGVyZSB0aGUgbm9kZXMgYXJlIGJlaW5nIGxvb2tlZCBmb3IuCi0gICAqIEBwYXJhbSByZWZ2YWwgQSBzcGFjZSBkZWxpbWl0ZWQgbGlzdCBvZiBJRCByZWZlcmVuY2VzLgotICAgKiBAcGFyYW0gdXNlZHJlZnMgTGlzdCBvZiByZWZlcmVuY2VzIGZvciB3aGljaCBub2RlcyB3ZXJlIGZvdW5kLgotICAgKiBAcGFyYW0gbm9kZVNldCBOb2RlIHNldCB3aGVyZSB0aGUgbm9kZXMgd2lsbCBiZSBhZGRlZCB0by4KLSAgICogQHBhcmFtIG1heUJlTW9yZSB0cnVlIGlmIHRoZXJlIGlzIGFub3RoZXIgc2V0IG9mIG5vZGVzIHRvIGJlIGxvb2tlZCBmb3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHVzZWRyZWZzIHZhbHVlLgotICAgKi8KLSAgcHJpdmF0ZSBTdHJpbmdWZWN0b3IgZ2V0Tm9kZXNCeUlEKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGRvY0NvbnRleHQsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVmdmFsLCBTdHJpbmdWZWN0b3IgdXNlZHJlZnMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlU2V0RFRNIG5vZGVTZXQsIGJvb2xlYW4gbWF5QmVNb3JlKQotICB7Ci0KLSAgICBpZiAobnVsbCAhPSByZWZ2YWwpCi0gICAgewotICAgICAgU3RyaW5nIHJlZiA9IG51bGw7Ci0vLyAgICAgIERPTUhlbHBlciBkaCA9IHhjdHh0LmdldERPTUhlbHBlcigpOwotICAgICAgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocmVmdmFsKTsKLSAgICAgIGJvb2xlYW4gaGFzTW9yZSA9IHRva2VuaXplci5oYXNNb3JlVG9rZW5zKCk7Ci0gICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGRvY0NvbnRleHQpOwotCi0gICAgICB3aGlsZSAoaGFzTW9yZSkKLSAgICAgIHsKLSAgICAgICAgcmVmID0gdG9rZW5pemVyLm5leHRUb2tlbigpOwotICAgICAgICBoYXNNb3JlID0gdG9rZW5pemVyLmhhc01vcmVUb2tlbnMoKTsKLQotICAgICAgICBpZiAoKG51bGwgIT0gdXNlZHJlZnMpICYmIHVzZWRyZWZzLmNvbnRhaW5zKHJlZikpCi0gICAgICAgIHsKLSAgICAgICAgICByZWYgPSBudWxsOwotCi0gICAgICAgICAgY29udGludWU7Ci0gICAgICAgIH0KLQotICAgICAgICBpbnQgbm9kZSA9IGR0bS5nZXRFbGVtZW50QnlJZChyZWYpOwotCi0gICAgICAgIGlmIChEVE0uTlVMTCAhPSBub2RlKQotICAgICAgICAgIG5vZGVTZXQuYWRkTm9kZUluRG9jT3JkZXIobm9kZSwgeGN0eHQpOwotCi0gICAgICAgIGlmICgobnVsbCAhPSByZWYpICYmIChoYXNNb3JlIHx8IG1heUJlTW9yZSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAobnVsbCA9PSB1c2VkcmVmcykKLSAgICAgICAgICAgIHVzZWRyZWZzID0gbmV3IFN0cmluZ1ZlY3RvcigpOwotCi0gICAgICAgICAgdXNlZHJlZnMuYWRkRWxlbWVudChyZWYpOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHVzZWRyZWZzOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpbnQgY29udGV4dCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICBpbnQgZG9jQ29udGV4dCA9IGR0bS5nZXREb2N1bWVudCgpOwotCi0gICAgaWYgKERUTS5OVUxMID09IGRvY0NvbnRleHQpCi0gICAgICBlcnJvcih4Y3R4dCwgWFBBVEhFcnJvclJlc291cmNlcy5FUl9DT05URVhUX0hBU19OT19PV05FUkRPQywgbnVsbCk7Ci0KLSAgICBYT2JqZWN0IGFyZyA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KTsKLSAgICBpbnQgYXJnVHlwZSA9IGFyZy5nZXRUeXBlKCk7Ci0gICAgWE5vZGVTZXQgbm9kZXMgPSBuZXcgWE5vZGVTZXQoeGN0eHQuZ2V0RFRNTWFuYWdlcigpKTsKLSAgICBOb2RlU2V0RFRNIG5vZGVTZXQgPSBub2Rlcy5tdXRhYmxlTm9kZXNldCgpOwotCi0gICAgaWYgKFhPYmplY3QuQ0xBU1NfTk9ERVNFVCA9PSBhcmdUeXBlKQotICAgIHsKLSAgICAgIERUTUl0ZXJhdG9yIG5pID0gYXJnLml0ZXIoKTsKLSAgICAgIFN0cmluZ1ZlY3RvciB1c2VkcmVmcyA9IG51bGw7Ci0gICAgICBpbnQgcG9zID0gbmkubmV4dE5vZGUoKTsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IHBvcykKLSAgICAgIHsKLSAgICAgICAgRFRNIG5kdG0gPSBuaS5nZXREVE0ocG9zKTsKLSAgICAgICAgU3RyaW5nIHJlZnZhbCA9IG5kdG0uZ2V0U3RyaW5nVmFsdWUocG9zKS50b1N0cmluZygpOwotCi0gICAgICAgIHBvcyA9IG5pLm5leHROb2RlKCk7Ci0gICAgICAgIHVzZWRyZWZzID0gZ2V0Tm9kZXNCeUlEKHhjdHh0LCBkb2NDb250ZXh0LCByZWZ2YWwsIHVzZWRyZWZzLCBub2RlU2V0LAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVE0uTlVMTCAhPSBwb3MpOwotICAgICAgfQotICAgICAgLy8gbmkuZGV0YWNoKCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfTlVMTCA9PSBhcmdUeXBlKQotICAgIHsKLSAgICAgIHJldHVybiBub2RlczsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIFN0cmluZyByZWZ2YWwgPSBhcmcuc3RyKCk7Ci0KLSAgICAgIGdldE5vZGVzQnlJRCh4Y3R4dCwgZG9jQ29udGV4dCwgcmVmdmFsLCBudWxsLCBub2RlU2V0LCBmYWxzZSk7Ci0gICAgfQotCi0gICAgcmV0dXJuIG5vZGVzOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0xhbmcuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTGFuZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1ZTMzNTU5Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTGFuZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIExhbmcoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNMYW5nIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBsYW5nID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIGludCBwYXJlbnQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIGJvb2xlYW4gaXNMYW5nID0gZmFsc2U7Ci0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShwYXJlbnQpOwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IHBhcmVudCkKLSAgICB7Ci0gICAgICBpZiAoRFRNLkVMRU1FTlRfTk9ERSA9PSBkdG0uZ2V0Tm9kZVR5cGUocGFyZW50KSkKLSAgICAgIHsKLSAgICAgICAgaW50IGxhbmdBdHRyID0gZHRtLmdldEF0dHJpYnV0ZU5vZGUocGFyZW50LCAiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIiwgImxhbmciKTsKLQotICAgICAgICBpZiAoRFRNLk5VTEwgIT0gbGFuZ0F0dHIpCi0gICAgICAgIHsKLSAgICAgICAgICBTdHJpbmcgbGFuZ1ZhbCA9IGR0bS5nZXROb2RlVmFsdWUobGFuZ0F0dHIpOwotICAgICAgICAgIC8vICVPUFQlCi0gICAgICAgICAgaWYgKGxhbmdWYWwudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKGxhbmcudG9Mb3dlckNhc2UoKSkpCi0gICAgICAgICAgewotICAgICAgICAgICAgaW50IHZhbExlbiA9IGxhbmcubGVuZ3RoKCk7Ci0KLSAgICAgICAgICAgIGlmICgobGFuZ1ZhbC5sZW5ndGgoKSA9PSB2YWxMZW4pCi0gICAgICAgICAgICAgICAgICAgIHx8IChsYW5nVmFsLmNoYXJBdCh2YWxMZW4pID09ICctJykpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGlzTGFuZyA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcGFyZW50ID0gZHRtLmdldFBhcmVudChwYXJlbnQpOwotICAgIH0KLQotICAgIHJldHVybiBpc0xhbmcgPyBYQm9vbGVhbi5TX1RSVUUgOiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0xhc3QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTGFzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNzdkNDBlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTGFzdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTM3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuTG9jUGF0aEl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5Db250ZXh0Tm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLlN1YkNvbnRleHRMaXN0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgTGFzdCgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0xhc3QgZXh0ZW5kcyBGdW5jdGlvbgotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvc2l0aW9uIGluIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsaXN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0Q291bnRPZkNvbnRleHROb2RlTGlzdChYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gYXNzZXJ0KG51bGwgIT0gbV9jb250ZXh0Tm9kZUxpc3QsICJtX2NvbnRleHROb2RlTGlzdCBtdXN0IGJlIG5vbi1udWxsIik7Ci0gICAgLy8gSWYgd2UncmUgaW4gYSBwcmVkaWNhdGUsIHRoZW4gdGhpcyB3aWxsIHJldHVybiBub24tbnVsbC4KLSAgICBTdWJDb250ZXh0TGlzdCBpdGVyID0geGN0eHQuZ2V0U3ViQ29udGV4dExpc3QoKTsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIml0ZXI6ICIraXRlcik7Ci0gICAgaWYgKG51bGwgIT0gaXRlcikKLSAgICAgIHJldHVybiBpdGVyLmdldExhc3RQb3MoeGN0eHQpOwotCi0gICAgRFRNSXRlcmF0b3IgY25sID0geGN0eHQuZ2V0Q29udGV4dE5vZGVMaXN0KCk7Ci0gICAgaW50IGNvdW50OwotICAgIGlmKG51bGwgIT0gY25sKQotICAgIHsKLSAgICAgIGNvdW50ID0gY25sLmdldExlbmd0aCgpOwotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJjb3VudDogIitjb3VudCk7IAotICAgIH0KLSAgICBlbHNlCi0gICAgICBjb3VudCA9IDA7ICAgCi0gICAgcmV0dXJuIGNvdW50OwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgWE51bWJlciB4bnVtID0gbmV3IFhOdW1iZXIoKGRvdWJsZSkgZ2V0Q291bnRPZkNvbnRleHROb2RlTGlzdCh4Y3R4dCkpOwotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibGFzdDogIit4bnVtLm51bSgpKTsKLSAgICByZXR1cm4geG51bTsKLSAgfQotICAKLSAgLyoqCi0gICAqIE5vIGFyZ3VtZW50cyB0byBwcm9jZXNzLCBzbyB0aGlzIGRvZXMgbm90aGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0xvY2FsUGFydC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNMb2NhbFBhcnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTA3MjY5YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY0xvY2FsUGFydC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiBFeGVjdXRlIHRoZSBMb2NhbFBhcnQoKSBmdW5jdGlvbi4KLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICovCi1wdWJsaWMgY2xhc3MgRnVuY0xvY2FsUGFydCBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvbnRleHQgPSBnZXRBcmcwQXNOb2RlKHhjdHh0KTsKLSAgICBpZihEVE0uTlVMTCA9PSBjb250ZXh0KQotICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICBTdHJpbmcgcyA9IChjb250ZXh0ICE9IERUTS5OVUxMKSA/IGR0bS5nZXRMb2NhbE5hbWUoY29udGV4dCkgOiAiIjsKLSAgICBpZihzLnN0YXJ0c1dpdGgoIiMiKSB8fCBzLmVxdWFscygieG1sbnMiKSkKLSAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotCi0gICAgcmV0dXJuIG5ldyBYU3RyaW5nKHMpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY05hbWVzcGFjZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNOYW1lc3BhY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmEzOTI1Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY05hbWVzcGFjZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIE5hbWVzcGFjZSgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY05hbWVzcGFjZSBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvbnRleHQgPSBnZXRBcmcwQXNOb2RlKHhjdHh0KTsKLSAgICAKLSAgICBTdHJpbmcgczsKLSAgICBpZihjb250ZXh0ICE9IERUTS5OVUxMKQotICAgIHsKLSAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgICBpbnQgdCA9IGR0bS5nZXROb2RlVHlwZShjb250ZXh0KTsKLSAgICAgIGlmKHQgPT0gRFRNLkVMRU1FTlRfTk9ERSkKLSAgICAgIHsKLSAgICAgICAgcyA9IGR0bS5nZXROYW1lc3BhY2VVUkkoY29udGV4dCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmKHQgPT0gRFRNLkFUVFJJQlVURV9OT0RFKQotICAgICAgewotCi0gICAgICAgIC8vIFRoaXMgZnVuY3Rpb24gYWx3YXlzIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nIGZvciBuYW1lc3BhY2Ugbm9kZXMuCi0gICAgICAgIC8vIFdlIGNoZWNrIGZvciB0aG9zZSBoZXJlLiAgRml4IGluc3BpcmVkIGJ5IERhdmFudW0gU3Jpbml2YXMuCi0KLSAgICAgICAgcyA9IGR0bS5nZXROb2RlTmFtZShjb250ZXh0KTsKLSAgICAgICAgaWYocy5zdGFydHNXaXRoKCJ4bWxuczoiKSB8fCBzLmVxdWFscygieG1sbnMiKSkKLSAgICAgICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLQotICAgICAgICBzID0gZHRtLmdldE5hbWVzcGFjZVVSSShjb250ZXh0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgfQotICAgIGVsc2UgCi0gICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICAKLSAgICByZXR1cm4gKChudWxsID09IHMpID8gWFN0cmluZy5FTVBUWVNUUklORyA6IG5ldyBYU3RyaW5nKHMpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNOb3JtYWxpemVTcGFjZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNOb3JtYWxpemVTcGFjZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYjQ0MGYzLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTm9ybWFsaXplU3BhY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhNTFN0cmluZ0ZhY3RvcnlJbXBsOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTENoYXJhY3RlclJlY29nbml6ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXI7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBub3JtYWxpemUtc3BhY2UoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNOb3JtYWxpemVTcGFjZSBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIFhNTFN0cmluZyBzMSA9IGdldEFyZzBBc1N0cmluZyh4Y3R4dCk7Ci0KLSAgICByZXR1cm4gKFhTdHJpbmcpczEuZml4V2hpdGVTcGFjZSh0cnVlLCB0cnVlLCBmYWxzZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBFeGVjdXRlIGFuIGV4cHJlc3Npb24gaW4gdGhlIFhQYXRoIHJ1bnRpbWUgY29udGV4dCwgYW5kIHJldHVybiB0aGUgCi0gICAqIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbiBpbiB0aGUgZm9ybSBvZiBhIDxjb2RlPlhPYmplY3Q8L2NvZGU+LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYSBydW50aW1lIGV4Y2VwdGlvbiAKLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqLwotICBwdWJsaWMgdm9pZCBleGVjdXRlQ2hhcnNUb0NvbnRlbnRIYW5kbGVyKFhQYXRoQ29udGV4dCB4Y3R4dCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGVudEhhbmRsZXIgaGFuZGxlcikKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiwKLSAgICAgICAgICAgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBpZihBcmcwSXNOb2Rlc2V0RXhwcigpKQotICAgIHsKLSAgICAgIGludCBub2RlID0gZ2V0QXJnMEFzTm9kZSh4Y3R4dCk7Ci0gICAgICBpZihEVE0uTlVMTCAhPSBub2RlKQotICAgICAgewotICAgICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKG5vZGUpOwotICAgICAgICBkdG0uZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG5vZGUsIGhhbmRsZXIsIHRydWUpOwotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgWE9iamVjdCBvYmogPSBleGVjdXRlKHhjdHh0KTsKLSAgICAgIG9iai5kaXNwYXRjaENoYXJhY3RlcnNFdmVudHMoaGFuZGxlcik7Ci0gICAgfQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTm90LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY05vdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5ZDU5NjAwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jTm90LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIE5vdCgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY05vdCBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG1fYXJnMC5leGVjdXRlKHhjdHh0KS5ib29sKCkgPyBYQm9vbGVhbi5TX0ZBTFNFIDogWEJvb2xlYW4uU19UUlVFOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY051bWJlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNOdW1iZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZGJlOTI1Ny4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY051bWJlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgTnVtYmVyKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jTnVtYmVyIGV4dGVuZHMgRnVuY3Rpb25EZWYxQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGdldEFyZzBBc051bWJlcih4Y3R4dCkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1Bvc2l0aW9uLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1Bvc2l0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU4OGZiYmQuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNQb3NpdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5TdWJDb250ZXh0TGlzdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuQ29udGV4dE5vZGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIFBvc2l0aW9uKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jUG9zaXRpb24gZXh0ZW5kcyBGdW5jdGlvbgotewotCi0gIC8qKgotICAgKiBHZXQgdGhlIHBvc2l0aW9uIGluIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZSBsaXN0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgUnVudGltZSBYUGF0aCBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBpdHRlcmF0aW9uIGluIHRoZSBjb250ZXh0IG5vZGUgbGlzdCwgCi0gICAqICAgICAgICAgb3IgLTEgaWYgdGhlcmUgaXMgbm8gYWN0aXZlIGNvbnRleHQgbm9kZSBsaXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRQb3NpdGlvbkluQ29udGV4dE5vZGVMaXN0KFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGdW5jUG9zaXRpb24tIGVudHJ5Iik7Ci0gICAgLy8gSWYgd2UncmUgaW4gYSBwcmVkaWNhdGUsIHRoZW4gdGhpcyB3aWxsIHJldHVybiBub24tbnVsbC4KLSAgICBTdWJDb250ZXh0TGlzdCBpdGVyID0geGN0eHQuZ2V0U3ViQ29udGV4dExpc3QoKTsKLQotICAgIGlmIChudWxsICE9IGl0ZXIpCi0gICAgewotICAgICAgaW50IHByb3ggPSBpdGVyLmdldFByb3hpbWl0eVBvc2l0aW9uKHhjdHh0KTsKLQotICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGdW5jUG9zaXRpb24tIHByb3g6ICIrcHJveCk7Ci0gICAgICByZXR1cm4gcHJveDsKLSAgICB9Ci0KLSAgICBEVE1JdGVyYXRvciBjbmwgPSB4Y3R4dC5nZXRDb250ZXh0Tm9kZUxpc3QoKTsKLQotICAgIGlmIChudWxsICE9IGNubCkKLSAgICB7Ci0gICAgICBpbnQgbiA9IGNubC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgaWYobiA9PSBEVE0uTlVMTCkKLSAgICAgIHsKLSAgICAgICAgaWYoY25sLmdldEN1cnJlbnRQb3MoKSA9PSAwKQotICAgICAgICAgIHJldHVybiAwOwotICAgICAgICAgIAotICAgICAgICAvLyBUaGVuIEkgdGhpbmsgd2UncmUgaW4gYSBzb3J0LiAgU2VlIHNvcnQyMS54c2wuIFNvIHRoZSBpdGVyYXRvciBoYXMgCi0gICAgICAgIC8vIGFscmVhZHkgYmVlbiBzcGVudCwgYW5kIGlzIG5vdCBvbiB0aGUgbm9kZSB3ZSdyZSBwcm9jZXNzaW5nLiAKLSAgICAgICAgLy8gSXQncyBoaWdobHkgcG9zc2libGUgdGhhdCB0aGlzIGlzIGFuIGlzc3VlIGZvciBvdGhlciBjb250ZXh0LWxpc3QgCi0gICAgICAgIC8vIGZ1bmN0aW9ucy4gIFNob3VsZG4ndCBiZSBhIHByb2JsZW0gZm9yIGxhc3QoKSwgYW5kIGl0IHNob3VsZG4ndCBiZSAKLSAgICAgICAgLy8gYSBwcm9ibGVtIGZvciBjdXJyZW50KCkuCi0gICAgICAgIHRyeSAKLSAgICAgICAgeyAKLSAgICAgICAgICBjbmwgPSBjbmwuY2xvbmVXaXRoUmVzZXQoKTsgCi0gICAgICAgIH0KLSAgICAgICAgY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICAgICAgewotICAgICAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihjbnNlKTsKLSAgICAgICAgfQotICAgICAgICBpbnQgY3VycmVudE5vZGUgPSB4Y3R4dC5nZXRDb250ZXh0Tm9kZSgpOwotICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImN1cnJlbnROb2RlOiAiK2N1cnJlbnROb2RlKTsKLSAgICAgICAgd2hpbGUoRFRNLk5VTEwgIT0gKG4gPSBjbmwubmV4dE5vZGUoKSkpCi0gICAgICAgIHsKLSAgICAgICAgICBpZihuID09IGN1cnJlbnROb2RlKQotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigibjogIituKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiRnVuY1Bvc2l0aW9uLSBjbmwuZ2V0Q3VycmVudFBvcygpOiAiK2NubC5nZXRDdXJyZW50UG9zKCkpOwotICAgICAgcmV0dXJuIGNubC5nZXRDdXJyZW50UG9zKCk7Ci0gICAgfQotCi0gICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGdW5jUG9zaXRpb24gLSBvdXQgb2YgZ3Vlc3NlczogLTEiKTsKLSAgICByZXR1cm4gLTE7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICBkb3VibGUgcG9zID0gKGRvdWJsZSkgZ2V0UG9zaXRpb25JbkNvbnRleHROb2RlTGlzdCh4Y3R4dCk7Ci0gICAgCi0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKHBvcyk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBObyBhcmd1bWVudHMgdG8gcHJvY2Vzcywgc28gdGhpcyBkb2VzIG5vdGhpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIC8vIG5vLW9wCi0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jUW5hbWUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jUW5hbWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjRlZGQ5Yy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1FuYW1lLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotLy9pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkF0dHI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIFFuYW1lKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jUW5hbWUgZXh0ZW5kcyBGdW5jdGlvbkRlZjFBcmcKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGludCBjb250ZXh0ID0gZ2V0QXJnMEFzTm9kZSh4Y3R4dCk7Ci0gICAgWE9iamVjdCB2YWw7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gY29udGV4dCkKLSAgICB7Ci0gICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotICAgICAgU3RyaW5nIHFuYW1lID0gZHRtLmdldE5vZGVOYW1lWChjb250ZXh0KTsKLSAgICAgIHZhbCA9IChudWxsID09IHFuYW1lKSA/IFhTdHJpbmcuRU1QVFlTVFJJTkcgOiBuZXcgWFN0cmluZyhxbmFtZSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICB2YWwgPSBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgIH0KLQotICAgIHJldHVybiB2YWw7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jUm91bmQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jUm91bmQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDFiYjU0ZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1JvdW5kLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgcm91bmQoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNSb3VuZCBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGphdmEubGFuZy5NYXRoLmZsb29yKG1fYXJnMC5leGVjdXRlKHhjdHh0KS5udW0oKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDAuNSkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N0YXJ0c1dpdGguamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jU3RhcnRzV2l0aC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMTNiMWQyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jU3RhcnRzV2l0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBTdGFydHNXaXRoKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3RhcnRzV2l0aCBleHRlbmRzIEZ1bmN0aW9uMkFyZ3MKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnhzdHIoKS5zdGFydHNXaXRoKG1fYXJnMS5leGVjdXRlKHhjdHh0KS54c3RyKCkpCi0gICAgICAgICAgID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdHJpbmcuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jU3RyaW5nLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNmYzg1MjUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdHJpbmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDkwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIFN0cmluZygpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY1N0cmluZyBleHRlbmRzIEZ1bmN0aW9uRGVmMUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiAoWFN0cmluZylnZXRBcmcwQXNTdHJpbmcoeGN0eHQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N0cmluZ0xlbmd0aC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdHJpbmdMZW5ndGguamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDU3YzFmMi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N0cmluZ0xlbmd0aC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTAgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOb2RlU2V0OwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgU3RyaW5nTGVuZ3RoKCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3RyaW5nTGVuZ3RoIGV4dGVuZHMgRnVuY3Rpb25EZWYxQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG5ldyBYTnVtYmVyKGdldEFyZzBBc1N0cmluZyh4Y3R4dCkubGVuZ3RoKCkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmM2MzJmZS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTU0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBTdWJzdHJpbmcoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNTdWJzdHJpbmcgZXh0ZW5kcyBGdW5jdGlvbjNBcmdzCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYTUxTdHJpbmcgczEgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkueHN0cigpOwotICAgIGRvdWJsZSBzdGFydCA9IG1fYXJnMS5leGVjdXRlKHhjdHh0KS5udW0oKTsKLSAgICBpbnQgbGVuT2ZTMSA9IHMxLmxlbmd0aCgpOwotICAgIFhNTFN0cmluZyBzdWJzdHI7Ci0KLSAgICBpZiAobGVuT2ZTMSA8PSAwKQotICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBzdGFydEluZGV4OwotCi0gICAgICBpZiAoRG91YmxlLmlzTmFOKHN0YXJ0KSkKLSAgICAgIHsKLQotICAgICAgICAvLyBEb3VibGUuTUlOX1ZBTFVFIGRvZXNuJ3Qgd29yayB3aXRoIG1hdGggYmVsb3cgCi0gICAgICAgIC8vIHNvIGp1c3QgdXNlIGEgYmlnIG51bWJlciBhbmQgaG9wZSBJIG5ldmVyIGdldCBjYXVnaHQuCi0gICAgICAgIHN0YXJ0ID0gLTEwMDAwMDA7Ci0gICAgICAgIHN0YXJ0SW5kZXggPSAwOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBzdGFydCA9IE1hdGgucm91bmQoc3RhcnQpOwotICAgICAgICBzdGFydEluZGV4ID0gKHN0YXJ0ID4gMCkgPyAoaW50KSBzdGFydCAtIDEgOiAwOwotICAgICAgfQotCi0gICAgICBpZiAobnVsbCAhPSBtX2FyZzIpCi0gICAgICB7Ci0gICAgICAgIGRvdWJsZSBsZW4gPSBtX2FyZzIubnVtKHhjdHh0KTsKLSAgICAgICAgaW50IGVuZCA9IChpbnQpIChNYXRoLnJvdW5kKGxlbikgKyBzdGFydCkgLSAxOwotCi0gICAgICAgIC8vIE5vcm1hbGl6ZSBlbmQgaW5kZXguCi0gICAgICAgIGlmIChlbmQgPCAwKQotICAgICAgICAgIGVuZCA9IDA7Ci0gICAgICAgIGVsc2UgaWYgKGVuZCA+IGxlbk9mUzEpCi0gICAgICAgICAgZW5kID0gbGVuT2ZTMTsKLQotICAgICAgICBpZiAoc3RhcnRJbmRleCA+IGxlbk9mUzEpCi0gICAgICAgICAgc3RhcnRJbmRleCA9IGxlbk9mUzE7Ci0KLSAgICAgICAgc3Vic3RyID0gczEuc3Vic3RyaW5nKHN0YXJ0SW5kZXgsIGVuZCk7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGlmIChzdGFydEluZGV4ID4gbGVuT2ZTMSkKLSAgICAgICAgICBzdGFydEluZGV4ID0gbGVuT2ZTMTsKLSAgICAgICAgc3Vic3RyID0gczEuc3Vic3RyaW5nKHN0YXJ0SW5kZXgpOwotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiAoWFN0cmluZylzdWJzdHI7IC8vIGNhc3Qgc2VtaS1zYWZlCi0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdGhhdCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhpcyBmdW5jdGlvbiBpcyBjb3JyZWN0LiAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSA8IDIpCi0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1RXT19PUl9USFJFRSwgbnVsbCkpOyAvLyIyIG9yIDMiKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmdBZnRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmdBZnRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZjQ1MzE2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jU3Vic3RyaW5nQWZ0ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBTdWJzdHJpbmdBZnRlcigpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY1N1YnN0cmluZ0FmdGVyIGV4dGVuZHMgRnVuY3Rpb24yQXJncwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWE1MU3RyaW5nIHMxID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnhzdHIoKTsKLSAgICBYTUxTdHJpbmcgczIgPSBtX2FyZzEuZXhlY3V0ZSh4Y3R4dCkueHN0cigpOwotICAgIGludCBpbmRleCA9IHMxLmluZGV4T2YoczIpOwotCi0gICAgcmV0dXJuICgtMSA9PSBpbmRleCkKLSAgICAgICAgICAgPyBYU3RyaW5nLkVNUFRZU1RSSU5HCi0gICAgICAgICAgIDogKFhTdHJpbmcpczEuc3Vic3RyaW5nKGluZGV4ICsgczIubGVuZ3RoKCkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZ0JlZm9yZS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdWJzdHJpbmdCZWZvcmUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTQ0MDJjYi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N1YnN0cmluZ0JlZm9yZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIFN1YnN0cmluZ0JlZm9yZSgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY1N1YnN0cmluZ0JlZm9yZSBleHRlbmRzIEZ1bmN0aW9uMkFyZ3MKLXsKLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZnVuY3Rpb24uICBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4KLSAgICogYSB2YWxpZCBvYmplY3QuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4KLSAgICogQHJldHVybiBBIHZhbGlkIFhPYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBzMSA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBTdHJpbmcgczIgPSBtX2FyZzEuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgaW50IGluZGV4ID0gczEuaW5kZXhPZihzMik7Ci0KLSAgICByZXR1cm4gKC0xID09IGluZGV4KQotICAgICAgICAgICA/IFhTdHJpbmcuRU1QVFlTVFJJTkcgOiBuZXcgWFN0cmluZyhzMS5zdWJzdHJpbmcoMCwgaW5kZXgpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdW0uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jU3VtLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZlZTg2MTUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTdW0uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRE9NSGVscGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBTdW0oKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNTdW0gZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRFRNSXRlcmF0b3Igbm9kZXMgPSBtX2FyZzAuYXNJdGVyYXRvcih4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gICAgZG91YmxlIHN1bSA9IDAuMDsKLSAgICBpbnQgcG9zOwotCi0gICAgd2hpbGUgKERUTS5OVUxMICE9IChwb3MgPSBub2Rlcy5uZXh0Tm9kZSgpKSkKLSAgICB7Ci0gICAgICBEVE0gZHRtID0gbm9kZXMuZ2V0RFRNKHBvcyk7Ci0gICAgICBYTUxTdHJpbmcgcyA9IGR0bS5nZXRTdHJpbmdWYWx1ZShwb3MpOwotCi0gICAgICBpZiAobnVsbCAhPSBzKQotICAgICAgICBzdW0gKz0gcy50b0RvdWJsZSgpOwotICAgIH0KLSAgICBub2Rlcy5kZXRhY2goKTsKLQotICAgIHJldHVybiBuZXcgWE51bWJlcihzdW0pOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N5c3RlbVByb3BlcnR5LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1N5c3RlbVByb3BlcnR5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1ZTY3Y2IuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNTeXN0ZW1Qcm9wZXJ0eS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjUwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLWltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLQotaW1wb3J0IGphdmEubGFuZy5DbGFzc0xvYWRlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlByZWZpeFJlc29sdmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEV4ZWN1dGUgdGhlIFN5c3RlbVByb3BlcnR5KCkgZnVuY3Rpb24uCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jU3lzdGVtUHJvcGVydHkgZXh0ZW5kcyBGdW5jdGlvbk9uZUFyZwotewotCi0gIC8qKiAKLSAgICogVGhlIHBhdGgvZmlsZW5hbWUgb2YgdGhlIHByb3BlcnR5IGZpbGU6IFhTTFRJbmZvLnByb3BlcnRpZXMgIAotICAgKiBNYWludGVuYW5jZSBub3RlOiBzZWUgYWxzbyBvcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsLlhTTFRfUFJPUEVSVElFUwotICAgKi8KLSAgc3RhdGljIFN0cmluZyBYU0xUX1BST1BFUlRJRVMgPSAib3JnL2FwYWNoZS94YWxhbi9yZXMvWFNMVEluZm8ucHJvcGVydGllcyI7Ci0JCi0JLyoqIGEgemVybyBsZW5ndGggQ2xhc3MgYXJyYXkgdXNlZCBpbiBsb2FkUHJvcGVydHlGaWxlKCkgKi8KLSAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ2xhc3NbXSBOT19DTEFTU0VTID0gbmV3IENsYXNzWzBdOwotCi0gIC8qKiBhIHplcm8gbGVuZ3RoIE9iamVjdCBhcnJheSB1c2VkIGluIGxvYWRQcm9wZXJ0eUZpbGUoKSAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3RbXSBOT19PQkpTID0gbmV3IE9iamVjdFswXTsKLQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZ1bGxOYW1lID0gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnN0cigpOwotICAgIGludCBpbmRleE9mTlNTZXAgPSBmdWxsTmFtZS5pbmRleE9mKCc6Jyk7Ci0gICAgU3RyaW5nIHJlc3VsdDsKLSAgICBTdHJpbmcgcHJvcE5hbWUgPSAiIjsKLSAgICAKLSAgICAvKiBMaXN0IG9mIHByb3BlcnRpZXMgd2hlcmUgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGFyZ3VtZW50IGlzIAotICAgICAqICB0byBiZSBsb29rZWQgZm9yLiAqLwotICAgIFByb3BlcnRpZXMgeHNsdEluZm8gPSBuZXcgUHJvcGVydGllcygpOwotCi0gICAgbG9hZFByb3BlcnR5RmlsZShYU0xUX1BST1BFUlRJRVMsIHhzbHRJbmZvKTsKLQotICAgIGlmIChpbmRleE9mTlNTZXAgPiAwKQotICAgIHsKLSAgICAgIFN0cmluZyBwcmVmaXggPSAoaW5kZXhPZk5TU2VwID49IDApCi0gICAgICAgICAgICAgICAgICAgICAgPyBmdWxsTmFtZS5zdWJzdHJpbmcoMCwgaW5kZXhPZk5TU2VwKSA6ICIiOwotICAgICAgU3RyaW5nIG5hbWVzcGFjZTsKLQotICAgICAgbmFtZXNwYWNlID0geGN0eHQuZ2V0TmFtZXNwYWNlQ29udGV4dCgpLmdldE5hbWVzcGFjZUZvclByZWZpeChwcmVmaXgpOwotICAgICAgcHJvcE5hbWUgPSAoaW5kZXhPZk5TU2VwIDwgMCkKLSAgICAgICAgICAgICAgICAgPyBmdWxsTmFtZSA6IGZ1bGxOYW1lLnN1YnN0cmluZyhpbmRleE9mTlNTZXAgKyAxKTsKLQotICAgICAgaWYgKG5hbWVzcGFjZS5zdGFydHNXaXRoKCJodHRwOi8vd3d3LnczLm9yZy9YU0wvVHJhbnNmb3JtIikKLSAgICAgICAgICAgICAgfHwgbmFtZXNwYWNlLmVxdWFscygiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIikpCi0gICAgICB7Ci0gICAgICAgIHJlc3VsdCA9IHhzbHRJbmZvLmdldFByb3BlcnR5KHByb3BOYW1lKTsKLQotICAgICAgICBpZiAobnVsbCA9PSByZXN1bHQpCi0gICAgICAgIHsKLSAgICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX1BST1BFUlRZX05PVF9TVVBQT1JURUQsCi0gICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZ1bGxOYW1lIH0pOyAgLy8iWFNMIFByb3BlcnR5IG5vdCBzdXBwb3J0ZWQ6ICIrZnVsbE5hbWUpOwotCi0gICAgICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgd2Fybih4Y3R4dCwgWFBBVEhFcnJvclJlc291cmNlcy5XR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMsCi0gICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBuYW1lc3BhY2UsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBmdWxsTmFtZSB9KTsgIC8vIkRvbid0IGN1cnJlbnRseSBkbyBhbnl0aGluZyB3aXRoIG5hbWVzcGFjZSAiK25hbWVzcGFjZSsiIGluIHByb3BlcnR5OiAiK2Z1bGxOYW1lKTsKLQotICAgICAgICB0cnkKLSAgICAgICAgewotICAgICAgICAgIHJlc3VsdCA9IFN5c3RlbS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7Ci0KLSAgICAgICAgICBpZiAobnVsbCA9PSByZXN1bHQpCi0gICAgICAgICAgewotCi0gICAgICAgICAgICAvLyByZXN1bHQgPSBTeXN0ZW0uZ2V0ZW52KHByb3BOYW1lKTsKLSAgICAgICAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpCi0gICAgICAgIHsKLSAgICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZnVsbE5hbWUgfSk7ICAvLyJTZWN1cml0eUV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBhY2Nlc3MgWFNMIHN5c3RlbSBwcm9wZXJ0eTogIitmdWxsTmFtZSk7Ci0KLSAgICAgICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIHJlc3VsdCA9IFN5c3RlbS5nZXRQcm9wZXJ0eShmdWxsTmFtZSk7Ci0KLSAgICAgICAgaWYgKG51bGwgPT0gcmVzdWx0KQotICAgICAgICB7Ci0KLSAgICAgICAgICAvLyByZXN1bHQgPSBTeXN0ZW0uZ2V0ZW52KGZ1bGxOYW1lKTsKLSAgICAgICAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgICAgICAgfQotICAgICAgfQotICAgICAgY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKQotICAgICAgewotICAgICAgICB3YXJuKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLldHX1NFQ1VSSVRZX0VYQ0VQVElPTiwKLSAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZ1bGxOYW1lIH0pOyAgLy8iU2VjdXJpdHlFeGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gYWNjZXNzIFhTTCBzeXN0ZW0gcHJvcGVydHk6ICIrZnVsbE5hbWUpOwotCi0gICAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgICAgfQotICAgIH0KLQotICAgIGlmIChwcm9wTmFtZS5lcXVhbHMoInZlcnNpb24iKSAmJiByZXN1bHQubGVuZ3RoKCkgPiAwKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICAvLyBOZWVkcyB0byByZXR1cm4gdGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBzcGVjIHdlIGNvbmZvcm0gdG8uCi0gICAgICAgIHJldHVybiBuZXcgWE51bWJlcigxLjApOwotICAgICAgfQotICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG5ldyBYU3RyaW5nKHJlc3VsdCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBuZXcgWFN0cmluZyhyZXN1bHQpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHJpZXZlIGEgcHJvcGVyeSBidW5kbGUgZnJvbSBhIHNwZWNpZmllZCBmaWxlCi0gICAqIAotICAgKiBAcGFyYW0gZmlsZSBUaGUgc3RyaW5nIG5hbWUgb2YgdGhlIHByb3BlcnR5IGZpbGUuICBUaGUgbmFtZSAKLSAgICogc2hvdWxkIGFscmVhZHkgYmUgZnVsbHkgcXVhbGlmaWVkIGFzIHBhdGgvZmlsZW5hbWUKLSAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IHByb3BlcnR5IGJhZyB0aGUgZmlsZSB3aWxsIGJlIHBsYWNlZCBpbnRvLgotICAgKi8KLSAgcHVibGljIHZvaWQgbG9hZFByb3BlcnR5RmlsZShTdHJpbmcgZmlsZSwgUHJvcGVydGllcyB0YXJnZXQpCi0gIHsKLQotICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHRyeSB7Ci0gICAgICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBnZXRDQ0wgPSBUaHJlYWQuY2xhc3MuZ2V0TWV0aG9kKCJnZXRDb250ZXh0Q2xhc3NMb2FkZXIiLCBOT19DTEFTU0VTKTsKLSAgICAgICAgaWYgKGdldENDTCAhPSBudWxsKSB7Ci0gICAgICAgICAgQ2xhc3NMb2FkZXIgY29udGV4dENsYXNzTG9hZGVyID0gKENsYXNzTG9hZGVyKSBnZXRDQ0wuaW52b2tlKFRocmVhZC5jdXJyZW50VGhyZWFkKCksIE5PX09CSlMpOwotICAgICAgICAgIGlzID0gY29udGV4dENsYXNzTG9hZGVyLmdldFJlc291cmNlQXNTdHJlYW0oZmlsZSk7IC8vIGZpbGUgc2hvdWxkIGJlIGFscmVhZHkgZnVsbHkgc3BlY2lmaWVkCi0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkge30KLQotICAgICAgaWYgKGlzID09IG51bGwpIHsKLSAgICAgICAgLy8gTk9URSEgRm9yIHRoZSBiZWxvdyBnZXRSZXNvdXJjZUFzU3RyZWFtIGluIFN1biBKREsgMS4xLjhNCi0gICAgICAgIC8vICB3ZSBhcHBhcmVudGx5IG11c3QgYWRkIHRoZSBsZWFkaW5nIHNsYXNoIGNoYXJhY3RlciAtIEkgCi0gICAgICAgIC8vICBkb24ndCBrbm93IHdoeSwgYnV0IGlmIGl0J3Mgbm90IHRoZXJlLCB3ZSB0aHJvdyBhbiBOUEUgZnJvbSB0aGUgYmVsb3cgbG9hZGluZwotICAgICAgICBpcyA9IEZ1bmNTeXN0ZW1Qcm9wZXJ0eS5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvIiArIGZpbGUpOyAvLyBmaWxlIHNob3VsZCBiZSBhbHJlYWR5IGZ1bGx5IHNwZWNpZmllZAotICAgICAgfQotCi0gICAgICAvLyBnZXQgYSBidWZmZXJlZCB2ZXJzaW9uCi0gICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKLQotICAgICAgdGFyZ2V0LmxvYWQoYmlzKTsgIC8vIGFuZCBsb2FkIHVwIHRoZSBwcm9wZXJ0eSBiYWcgZnJvbSB0aGlzCi0gICAgICBiaXMuY2xvc2UoKTsgIC8vIGNsb3NlIG91dCBhZnRlciByZWFkaW5nCi0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCi0gICAgewotICAgICAgLy8gZXgucHJpbnRTdGFja1RyYWNlKCk7Ci0gICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24oZXgpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNUcmFuc2xhdGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jVHJhbnNsYXRlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVlOGYyNjMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNUcmFuc2xhdGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLQotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBFeGVjdXRlIHRoZSBUcmFuc2xhdGUoKSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNUcmFuc2xhdGUgZXh0ZW5kcyBGdW5jdGlvbjNBcmdzCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgdGhlRmlyc3RTdHJpbmcgPSBtX2FyZzAuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgU3RyaW5nIHRoZVNlY29uZFN0cmluZyA9IG1fYXJnMS5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBTdHJpbmcgdGhlVGhpcmRTdHJpbmcgPSBtX2FyZzIuZXhlY3V0ZSh4Y3R4dCkuc3RyKCk7Ci0gICAgaW50IHRoZUZpcnN0U3RyaW5nTGVuZ3RoID0gdGhlRmlyc3RTdHJpbmcubGVuZ3RoKCk7Ci0gICAgaW50IHRoZVRoaXJkU3RyaW5nTGVuZ3RoID0gdGhlVGhpcmRTdHJpbmcubGVuZ3RoKCk7Ci0KLSAgICAvLyBBIHZlY3RvciB0byBjb250YWluIHRoZSBuZXcgY2hhcmFjdGVycy4gIFdlJ2xsIHVzZSBpdCB0byBjb25zdHJ1Y3QKLSAgICAvLyB0aGUgcmVzdWx0IHN0cmluZy4KLSAgICBTdHJpbmdCdWZmZXIgc2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhlRmlyc3RTdHJpbmdMZW5ndGg7IGkrKykKLSAgICB7Ci0gICAgICBjaGFyIHRoZUN1cnJlbnRDaGFyID0gdGhlRmlyc3RTdHJpbmcuY2hhckF0KGkpOwotICAgICAgaW50IHRoZUluZGV4ID0gdGhlU2Vjb25kU3RyaW5nLmluZGV4T2YodGhlQ3VycmVudENoYXIpOwotCi0gICAgICBpZiAodGhlSW5kZXggPCAwKQotICAgICAgewotCi0gICAgICAgIC8vIERpZG4ndCBmaW5kIHRoZSBjaGFyYWN0ZXIgaW4gdGhlIHNlY29uZCBzdHJpbmcsIHNvIGl0Ci0gICAgICAgIC8vIGlzIG5vdCB0cmFuc2xhdGVkLgotICAgICAgICBzYnVmZmVyLmFwcGVuZCh0aGVDdXJyZW50Q2hhcik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmICh0aGVJbmRleCA8IHRoZVRoaXJkU3RyaW5nTGVuZ3RoKQotICAgICAgewotCi0gICAgICAgIC8vIE9LLCB0aGVyZSdzIGEgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgaW4gdGhlCi0gICAgICAgIC8vIHRoaXJkIHN0cmluZywgc28gZG8gdGhlIHRyYW5zbGF0aW9uLi4uCi0gICAgICAgIHNidWZmZXIuYXBwZW5kKHRoZVRoaXJkU3RyaW5nLmNoYXJBdCh0aGVJbmRleCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotCi0gICAgICAgIC8vIFRoZXJlJ3Mgbm8gY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgaW4gdGhlCi0gICAgICAgIC8vIHRoaXJkIHN0cmluZywgc2luY2UgaXQncyBzaG9ydGVyIHRoYW4gdGhlCi0gICAgICAgIC8vIHNlY29uZCBzdHJpbmcuICBJbiB0aGlzIGNhc2UsIHRoZSBjaGFyYWN0ZXIKLSAgICAgICAgLy8gaXMgcmVtb3ZlZCBmcm9tIHRoZSBvdXRwdXQgc3RyaW5nLCBzbyBkb24ndAotICAgICAgICAvLyBkbyBhbnl0aGluZy4KLSAgICAgIH0KLSAgICB9Ci0KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc2J1ZmZlci50b1N0cmluZygpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNUcnVlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1RydWUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmIxMzQ0OS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY1RydWUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk2ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogRXhlY3V0ZSB0aGUgVHJ1ZSgpIGZ1bmN0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgRnVuY1RydWUgZXh0ZW5kcyBGdW5jdGlvbgotewotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmdW5jdGlvbi4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBYQm9vbGVhbi5TX1RSVUU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBObyBhcmd1bWVudHMgdG8gcHJvY2Vzcywgc28gdGhpcyBkb2VzIG5vdGhpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIC8vIG5vLW9wCi0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNVbnBhcnNlZEVudGl0eVVSSS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmNVbnBhcnNlZEVudGl0eVVSSS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZjcyODllLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jVW5wYXJzZWRFbnRpdHlVUkkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDk5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNSXRlcmF0b3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWFN0cmluZzsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmNVbnBhcnNlZEVudGl0eVVSSSBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZ1bmN0aW9uLiAgVGhlIGZ1bmN0aW9uIG11c3QgcmV0dXJuCi0gICAqIGEgdmFsaWQgb2JqZWN0LgotICAgKiBAcGFyYW0geGN0eHQgVGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqIEByZXR1cm4gQSB2YWxpZCBYT2JqZWN0LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgbmFtZSA9IG1fYXJnMC5leGVjdXRlKHhjdHh0KS5zdHIoKTsKLSAgICBpbnQgY29udGV4dCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICBpbnQgZG9jID0gZHRtLmdldERvY3VtZW50KCk7Ci0gICAgCi0gICAgU3RyaW5nIHVyaSA9IGR0bS5nZXRVbnBhcnNlZEVudGl0eVVSSShuYW1lKTsKLQotICAgIHJldHVybiBuZXcgWFN0cmluZyh1cmkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxYWY4M2RkLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTMxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhpcyBpcyBhIHN1cGVyY2xhc3Mgb2YgYWxsIFhQYXRoIGZ1bmN0aW9ucy4gIFRoaXMgYWxsb3dzIHR3bwotICogd2F5cyBmb3IgdGhlIGNsYXNzIHRvIGJlIGNhbGxlZC4gT25lIG1ldGhvZCBpcyB0aGF0IHRoZQotICogc3VwZXIgY2xhc3MgcHJvY2Vzc2VzIHRoZSBhcmd1bWVudHMgYW5kIGhhbmRzIHRoZSByZXN1bHRzIHRvCi0gKiB0aGUgZGVyaXZlZCBjbGFzcywgdGhlIG90aGVyIG1ldGhvZCBpcyB0aGF0IHRoZSBkZXJpdmVkCi0gKiBjbGFzcyBtYXkgcHJvY2VzcyBpdCdzIG93biBhcmd1bWVudHMsIHdoaWNoIGlzIGZhc3RlciBzaW5jZQotICogdGhlIGFyZ3VtZW50cyBkb24ndCBoYXZlIHRvIGJlIGFkZGVkIHRvIGFuIGFycmF5LCBidXQgY2F1c2VzCi0gKiBhIGxhcmdlciBjb2RlIGZvb3RwcmludC4KLSAqLwotcHVibGljIGFic3RyYWN0IGNsYXNzIEZ1bmN0aW9uIGV4dGVuZHMgRXhwcmVzc2lvbgotewotCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgCi0gICAqIFhQYXRoIGNvbXBpbGVyLgotICAgKgotICAgKiBAcGFyYW0gYXJnIG5vbi1udWxsIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSBhcmd1bWVudC4KLSAgICogQHBhcmFtIGFyZ051bSBUaGUgYXJndW1lbnQgbnVtYmVyIGluZGV4LgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiBJZiB0aGUgYXJnTnVtIHBhcmFtZXRlciBpcyBiZXlvbmQgd2hhdCAKLSAgICogaXMgc3BlY2lmaWVkIGZvciB0aGlzIGZ1bmN0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXJnKEV4cHJlc3Npb24gYXJnLCBpbnQgYXJnTnVtKQotICAgICAgICAgIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oIjAiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuCi0gICAqIFRoaXMgbWV0aG9kIGlzIG1lYW50IHRvIGJlIG92ZXJsb2FkZWQgYnkgZGVyaXZlZCBjbGFzc2VzLCB0byBjaGVjayBmb3IgCi0gICAqIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBhIHNwZWNpZmljIGZ1bmN0aW9uIHR5cGUuICBUaGlzIG1ldGhvZCBpcyAKLSAgICogY2FsbGVkIGJ5IHRoZSBjb21waWxlciBmb3Igc3RhdGljIG51bWJlciBvZiBhcmd1bWVudHMgY2hlY2tpbmcuCi0gICAqCi0gICAqIEBwYXJhbSBhcmdOdW0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhhdCBpcyBiZWluZyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgY2hlY2tOdW1iZXJBcmdzKGludCBhcmdOdW0pIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotICAgIGlmIChhcmdOdW0gIT0gMCkKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oIjAiKTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIGFuIFhQYXRoIGZ1bmN0aW9uIG9iamVjdC4gIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybgotICAgKiBhIHZhbGlkIG9iamVjdC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBleGVjdXRpb24gY3VycmVudCBjb250ZXh0LgotICAgKiBAcmV0dXJuIEEgdmFsaWQgWE9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gUHJvZ3JhbW1lcidzIGFzc2VydC4gIChBbmQsIG5vLCBJIGRvbid0IHdhbnQgdGhlIG1ldGhvZCB0byBiZSBhYnN0cmFjdCkuCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJFcnJvciEgRnVuY3Rpb24uZXhlY3V0ZSBzaG91bGQgbm90IGJlIGNhbGxlZCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0gIAotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb24yQXJncy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmN0aW9uMkFyZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGZhYjFlMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb24yQXJncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ5ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogQmFzZSBjbGFzcyBmb3IgZnVuY3Rpb25zIHRoYXQgYWNjZXB0IHR3byBhcmd1bWVudHMuCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jdGlvbjJBcmdzIGV4dGVuZHMgRnVuY3Rpb25PbmVBcmcKLXsKLQotICAvKiogVGhlIHNlY29uZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAxKS4KLSAgICogIEBzZXJpYWwgICovCi0gIEV4cHJlc3Npb24gbV9hcmcxOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHNlY29uZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAxKS4KLSAgICoKLSAgICogQHJldHVybiBBbiBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGUgc2Vjb25kIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgCi0gICAqICAgICAgICAgZnVuY3Rpb24uCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRBcmcxKCkKLSAgewotICAgIHJldHVybiBtX2FyZzE7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBpZihudWxsICE9IG1fYXJnMSkKLSAgICAgIG1fYXJnMS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgCi0gICAqIFhQYXRoIGNvbXBpbGVyLgotICAgKgotICAgKiBAcGFyYW0gYXJnIG5vbi1udWxsIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSBhcmd1bWVudC4KLSAgICogQHBhcmFtIGFyZ051bSBUaGUgYXJndW1lbnQgbnVtYmVyIGluZGV4LgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiBJZiB0aGUgYXJnTnVtIHBhcmFtZXRlciBpcyBncmVhdGVyIHRoYW4gMS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEFyZyhFeHByZXNzaW9uIGFyZywgaW50IGFyZ051bSkKLSAgICAgICAgICB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiYXJnTnVtOiAiK2FyZ051bSk7Ci0gICAgaWYgKGFyZ051bSA9PSAwKQotICAgICAgc3VwZXIuc2V0QXJnKGFyZywgYXJnTnVtKTsKLSAgICBlbHNlIGlmICgxID09IGFyZ051bSkKLSAgICAgIG1fYXJnMSA9IGFyZzsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKCIyIik7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdGhhdCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhpcyBmdW5jdGlvbiBpcyBjb3JyZWN0LiAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSAhPSAyKQotICAgICAgdGhyb3cgbmV3IFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbigiMiIpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZSAKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gICB7Ci0gICAgcmV0dXJuIHN1cGVyLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSAKLSAgICA/IHRydWUgOiBtX2FyZzEuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpOwotICAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb24zQXJncy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmN0aW9uM0FyZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDhmNjdhMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb24zQXJncy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQ3ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogQmFzZSBjbGFzcyBmb3IgZnVuY3Rpb25zIHRoYXQgYWNjZXB0IHRocmVlIGFyZ3VtZW50cy4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmN0aW9uM0FyZ3MgZXh0ZW5kcyBGdW5jdGlvbjJBcmdzCi17Ci0KLSAgLyoqIFRoZSB0aGlyZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIChhdCBpbmRleCAyKS4KLSAgICogIEBzZXJpYWwgICovCi0gIEV4cHJlc3Npb24gbV9hcmcyOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHRoaXJkIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gKGF0IGluZGV4IDIpLgotICAgKgotICAgKiBAcmV0dXJuIEFuIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSB0aGlyZCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIAotICAgKiAgICAgICAgIGZ1bmN0aW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0QXJnMigpCi0gIHsKLSAgICByZXR1cm4gbV9hcmcyOwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZSAKLSAgICogaW5kZXhlcyBhdCBzdHlsZXNoZWV0IGJ1aWxkIHRpbWUuCi0gICAqIEBwYXJhbSB2YXJzIExpc3Qgb2YgUU5hbWVzIHRoYXQgY29ycmVzcG9uZCB0byB2YXJpYWJsZXMuICBUaGlzIGxpc3QgCi0gICAqIHNob3VsZCBiZSBzZWFyY2hlZCBiYWNrd2FyZHMgZm9yIHRoZSBmaXJzdCBxdWFsaWZpZWQgbmFtZSB0aGF0IAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZSAKLSAgICogUU5hbWUgaW4gdGhlIHZlY3RvciBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmVjdG9yIHdpbGwgYmUgaXRzIHBvc2l0aW9uIAotICAgKiBpbiB0aGUgc3RhY2sgZnJhbWUgKGJ1dCB2YXJpYWJsZXMgYWJvdmUgdGhlIGdsb2JhbHNUb3AgdmFsdWUgd2lsbCBuZWVkIAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICBzdXBlci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgaWYobnVsbCAhPSBtX2FyZzIpCi0gICAgICBtX2FyZzIuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCBhbiBhcmd1bWVudCBleHByZXNzaW9uIGZvciBhIGZ1bmN0aW9uLiAgVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSAKLSAgICogWFBhdGggY29tcGlsZXIuCi0gICAqCi0gICAqIEBwYXJhbSBhcmcgbm9uLW51bGwgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhlIGFyZ3VtZW50LgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBhcmd1bWVudCBudW1iZXIgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIElmIHRoZSBhcmdOdW0gcGFyYW1ldGVyIGlzIGdyZWF0ZXIgdGhhbiAyLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXJnKEV4cHJlc3Npb24gYXJnLCBpbnQgYXJnTnVtKQotICAgICAgICAgIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKGFyZ051bSA8IDIpCi0gICAgICBzdXBlci5zZXRBcmcoYXJnLCBhcmdOdW0pOwotICAgIGVsc2UgaWYgKDIgPT0gYXJnTnVtKQotICAgICAgbV9hcmcyID0gYXJnOwotICAgIGVsc2UKLSAgICAgIHRocm93IG5ldyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24oIjMiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDaGVjayB0aGF0IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIGNvcnJlY3QuIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRoYXQgaXMgYmVpbmcgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNoZWNrTnVtYmVyQXJncyhpbnQgYXJnTnVtKSB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLSAgICBpZiAoYXJnTnVtICE9IDMpCi0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKCIzIik7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlIAotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKiAKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgIHsKLSAgICByZXR1cm4gc3VwZXIuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpIAotICAgID8gdHJ1ZSA6IG1fYXJnMi5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCk7Ci0gICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jdGlvbkRlZjFBcmcuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jdGlvbkRlZjFBcmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2MzZTI1NS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb25EZWYxQXJnLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxOTggKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnM7Ci0KLS8vaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE5vZGVTZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi5yZXMuWFNMTWVzc2FnZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZzsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBCYXNlIGNsYXNzIGZvciBmdW5jdGlvbnMgdGhhdCBhY2NlcHQgb25lIGFyZ3VtZW50IHRoYXQgY2FuIGJlIGRlZmF1bHRlZCBpZgotICogbm90IHNwZWNpZmllZC4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmN0aW9uRGVmMUFyZyBleHRlbmRzIEZ1bmN0aW9uT25lQXJnCi17Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIGZpcnN0IGFyZ3VtZW50IGV4cHJlc3Npb24gdGhhdCBpcyBleHBlY3RlZCB0byByZXR1cm4gYQotICAgKiBub2Rlc2V0LiAgSWYgdGhlIGFyZ3VtZW50IGlzIG51bGwsIHRoZW4gcmV0dXJuIHRoZSBjdXJyZW50IGNvbnRleHQgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFJ1bnRpbWUgWFBhdGggY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZmlyc3Qgbm9kZSBvZiB0aGUgZXhlY3V0ZWQgbm9kZXNldCwgb3IgdGhlIGN1cnJlbnQgY29udGV4dAotICAgKiAgICAgICAgIG5vZGUgaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGluZyB0aGUgYXJndW1lbnQgZXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBpbnQgZ2V0QXJnMEFzTm9kZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgcmV0dXJuIChudWxsID09IG1fYXJnMCkKLSAgICAgICAgICAgPyB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpIDogbV9hcmcwLmFzTm9kZSh4Y3R4dCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgbm9kZXNldCBleHByZXNzaW9uLgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGV4cHJlc3Npb24gY2FuIGJlIHJlcHJlc2VudGVkIGFzIGEgbm9kZXNldC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIEFyZzBJc05vZGVzZXRFeHByKCkKLSAgewotICAgIHJldHVybiAobnVsbCA9PSBtX2FyZzApID8gdHJ1ZSA6IG1fYXJnMC5pc05vZGVzZXRFeHByKCk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgZmlyc3QgYXJndW1lbnQgZXhwcmVzc2lvbiB0aGF0IGlzIGV4cGVjdGVkIHRvIHJldHVybiBhCi0gICAqIHN0cmluZy4gIElmIHRoZSBhcmd1bWVudCBpcyBudWxsLCB0aGVuIGdldCB0aGUgc3RyaW5nIHZhbHVlIGZyb20gdGhlCi0gICAqIGN1cnJlbnQgY29udGV4dCBub2RlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgUnVudGltZSBYUGF0aCBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIGZpcnN0IGFyZ3VtZW50LCBvciB0aGUgc3RyaW5nIHZhbHVlIG9mIHRoZQotICAgKiAgICAgICAgIGN1cnJlbnQgY29udGV4dCBub2RlIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBudWxsLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRpbmcgdGhlIGFyZ3VtZW50IGV4cHJlc3Npb24uCi0gICAqLwotICBwcm90ZWN0ZWQgWE1MU3RyaW5nIGdldEFyZzBBc1N0cmluZyhYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIGlmKG51bGwgPT0gbV9hcmcwKQotICAgIHsKLSAgICAgIGludCBjdXJyZW50Tm9kZSA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICBpZihEVE0uTlVMTCA9PSBjdXJyZW50Tm9kZSkKLSAgICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY3VycmVudE5vZGUpOwotICAgICAgICByZXR1cm4gZHRtLmdldFN0cmluZ1ZhbHVlKGN1cnJlbnROb2RlKTsKLSAgICAgIH0KLSAgICAgIAotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLnhzdHIoKTsgICAKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoZSBmaXJzdCBhcmd1bWVudCBleHByZXNzaW9uIHRoYXQgaXMgZXhwZWN0ZWQgdG8gcmV0dXJuIGEKLSAgICogbnVtYmVyLiAgSWYgdGhlIGFyZ3VtZW50IGlzIG51bGwsIHRoZW4gZ2V0IHRoZSBudW1iZXIgdmFsdWUgZnJvbSB0aGUKLSAgICogY3VycmVudCBjb250ZXh0IG5vZGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBSdW50aW1lIFhQYXRoIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG51bWJlciB2YWx1ZSBvZiB0aGUgZmlyc3QgYXJndW1lbnQsIG9yIHRoZSBudW1iZXIgdmFsdWUgb2YgdGhlCi0gICAqICAgICAgICAgY3VycmVudCBjb250ZXh0IG5vZGUgaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIG51bGwuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUKLSAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGluZyB0aGUgYXJndW1lbnQgZXhwcmVzc2lvbi4KLSAgICovCi0gIHByb3RlY3RlZCBkb3VibGUgZ2V0QXJnMEFzTnVtYmVyKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBpZihudWxsID09IG1fYXJnMCkKLSAgICB7Ci0gICAgICBpbnQgY3VycmVudE5vZGUgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgICAgaWYoRFRNLk5VTEwgPT0gY3VycmVudE5vZGUpCi0gICAgICAgIHJldHVybiAwOwotICAgICAgZWxzZQotICAgICAgewotICAgICAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGN1cnJlbnROb2RlKTsKLSAgICAgICAgWE1MU3RyaW5nIHN0ciA9IGR0bS5nZXRTdHJpbmdWYWx1ZShjdXJyZW50Tm9kZSk7Ci0gICAgICAgIHJldHVybiBzdHIudG9Eb3VibGUoKTsKLSAgICAgIH0KLSAgICAgIAotICAgIH0KLSAgICBlbHNlCi0gICAgICByZXR1cm4gbV9hcmcwLmV4ZWN1dGUoeGN0eHQpLm51bSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRoYXQgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gaXMgY29ycmVjdC4KLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIGlmIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIGlzIG5vdCAwIG9yIDEuCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSA+IDEpCi0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1pFUk9fT1JfT05FLCBudWxsKSk7IC8vIjAgb3IgMSIpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fYXJnMCkgPyBmYWxzZSA6IHN1cGVyLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL0Z1bmN0aW9uTXVsdGlBcmdzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb25NdWx0aUFyZ3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDI1ODg0YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb25NdWx0aUFyZ3MuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2NiArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEJhc2UgY2xhc3MgZm9yIGZ1bmN0aW9ucyB0aGF0IGFjY2VwdCBhbiB1bmRldGVybWluZWQgbnVtYmVyIG9mIG11bHRpcGxlCi0gKiBhcmd1bWVudHMuCi0gKi8KLXB1YmxpYyBjbGFzcyBGdW5jdGlvbk11bHRpQXJncyBleHRlbmRzIEZ1bmN0aW9uM0FyZ3MKLXsKLQotICAvKiogQXJndW1lbnQgZXhwcmVzc2lvbnMgdGhhdCBhcmUgYXQgaW5kZXggMyBvciBncmVhdGVyLgotICAgKiAgQHNlcmlhbCAqLwotICBFeHByZXNzaW9uW10gbV9hcmdzOwotCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUKLSAgICogWFBhdGggY29tcGlsZXIuCi0gICAqCi0gICAqIEBwYXJhbSBhcmcgbm9uLW51bGwgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhlIGFyZ3VtZW50LgotICAgKiBAcGFyYW0gYXJnTnVtIFRoZSBhcmd1bWVudCBudW1iZXIgaW5kZXguCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIElmIGEgZGVyaXZlZCBjbGFzcyBkZXRlcm1pbmVzIHRoYXQgdGhlCi0gICAqIG51bWJlciBvZiBhcmd1bWVudHMgaXMgaW5jb3JyZWN0LgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXJnKEV4cHJlc3Npb24gYXJnLCBpbnQgYXJnTnVtKQotICAgICAgICAgIHRocm93cyBXcm9uZ051bWJlckFyZ3NFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKGFyZ051bSA8IDMpCi0gICAgICBzdXBlci5zZXRBcmcoYXJnLCBhcmdOdW0pOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpZiAobnVsbCA9PSBtX2FyZ3MpCi0gICAgICB7Ci0gICAgICAgIG1fYXJncyA9IG5ldyBFeHByZXNzaW9uWzFdOwotICAgICAgICBtX2FyZ3NbMF0gPSBhcmc7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0KLSAgICAgICAgLy8gU2xvdyBidXQgc3BhY2UgY29uc2VydmF0aXZlLgotICAgICAgICBFeHByZXNzaW9uW10gYXJncyA9IG5ldyBFeHByZXNzaW9uW21fYXJncy5sZW5ndGggKyAxXTsKLQotICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG1fYXJncywgMCwgYXJncywgMCwgbV9hcmdzLmxlbmd0aCk7Ci0KLSAgICAgICAgYXJnc1ttX2FyZ3MubGVuZ3RoXSA9IGFyZzsKLSAgICAgICAgbV9hcmdzID0gYXJnczsKLSAgICAgIH0KLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBpZihudWxsICE9IG1fYXJncykKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fYXJncy5sZW5ndGg7IGkrKykgCi0gICAgICB7Ci0gICAgICAgIG1fYXJnc1tpXS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENoZWNrIHRoYXQgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gaXMgY29ycmVjdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbnt9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBleHByZXNzaW9uIG9yIGl0J3Mgc3ViZXhwcmVzc2lvbnMgY2FuIHRyYXZlcnNlIG91dHNpZGUKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICB7Ci0KLSAgICBpZiAoc3VwZXIuY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBuID0gbV9hcmdzLmxlbmd0aDsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIGlmIChtX2FyZ3NbaV0uY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpKQotICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgfQotCi0gICAgICByZXR1cm4gZmFsc2U7Ci0gICAgfQotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvRnVuY3Rpb25PbmVBcmcuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jdGlvbk9uZUFyZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MTNhMzc1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9GdW5jdGlvbk9uZUFyZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTQzICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogQmFzZSBjbGFzcyBmb3IgZnVuY3Rpb25zIHRoYXQgYWNjZXB0IG9uZSBhcmd1bWVudC4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmN0aW9uT25lQXJnIGV4dGVuZHMgRnVuY3Rpb24KLXsKLQotICAvKiogVGhlIGZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gKGF0IGluZGV4IDApLgotICAgKiAgQHNlcmlhbCAgKi8KLSAgRXhwcmVzc2lvbiBtX2FyZzA7Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgZmlyc3QgYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbiAoYXQgaW5kZXggMCkuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhlIGZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgCi0gICAqICAgICAgICAgZnVuY3Rpb24uCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbiBnZXRBcmcwKCkKLSAgewotICAgIHJldHVybiBtX2FyZzA7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgYW4gYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYSBmdW5jdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgCi0gICAqIFhQYXRoIGNvbXBpbGVyLgotICAgKgotICAgKiBAcGFyYW0gYXJnIG5vbi1udWxsIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoZSBhcmd1bWVudC4KLSAgICogQHBhcmFtIGFyZ051bSBUaGUgYXJndW1lbnQgbnVtYmVyIGluZGV4LgotICAgKgotICAgKiBAdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbiBJZiB0aGUgYXJnTnVtIHBhcmFtZXRlciBpcyBncmVhdGVyIHRoYW4gMC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldEFyZyhFeHByZXNzaW9uIGFyZywgaW50IGFyZ051bSkKLSAgICAgICAgICB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmICgwID09IGFyZ051bSkKLSAgICAgIG1fYXJnMCA9IGFyZzsKLSAgICBlbHNlCi0gICAgICB0aHJvdyBuZXcgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uKCIxIik7Ci0gIH0KLQotICAvKioKLSAgICogQ2hlY2sgdGhhdCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhpcyBmdW5jdGlvbiBpcyBjb3JyZWN0LiAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGFyZ051bSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IGlzIGJlaW5nIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBjaGVja051bWJlckFyZ3MoaW50IGFyZ051bSkgdGhyb3dzIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICB7Ci0gICAgaWYgKGFyZ051bSAhPSAxKQotICAgICAgdGhyb3cgbmV3IFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbigiMSIpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZSAKLSAgICogdGhlIGN1cnJlbnQgc3VidHJlZS4KLSAgICogCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICAgcHVibGljIGJvb2xlYW4gY2FuVHJhdmVyc2VPdXRzaWRlU3VidHJlZSgpCi0gICB7Ci0gICAgcmV0dXJuIG1fYXJnMC5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCk7Ci0gICB9Ci0gICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUgCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0IAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdCAKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUgCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbiAKLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZCAKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgaWYobnVsbCAhPSBtX2FyZzApCi0gICAgICBtX2FyZzAuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9Xcm9uZ051bWJlckFyZ3NFeGNlcHRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucy9Xcm9uZ051bWJlckFyZ3NFeGNlcHRpb24uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTVlZDYyNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3OCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLmZ1bmN0aW9uczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIEFuIGV4Y2VwdGlvbiB0aGF0IGlzIHRocm93biBpZiB0aGUgd3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBhbiBleGNlcHRpb24gCi0gKiBhcmUgc3BlY2lmaWVkIGJ5IHRoZSBzdHlsZXNoZWV0LgotICovCi1wdWJsaWMgY2xhc3MgV3JvbmdOdW1iZXJBcmdzRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdG9yIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbgotICAgKgotICAgKiBAcGFyYW0gYXJnc0V4cGVjdGVkIEVycm9yIG1lc3NhZ2UgdGhhdCB0ZWxscyB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0aGF0IAotICAgKiB3ZXJlIGV4cGVjdGVkLgotICAgKi8KLSAgcHVibGljIFdyb25nTnVtYmVyQXJnc0V4Y2VwdGlvbihTdHJpbmcgYXJnc0V4cGVjdGVkKQotICB7Ci0KLSAgICBzdXBlcihhcmdzRXhwZWN0ZWQpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMWU2MGMzZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTEgKzAsMCBAQAotPGh0bWw+Ci0gIDx0aXRsZT5YUGF0aCBmdW5jdGlvbnMgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRzIFhQYXRoIGZ1bmN0aW9ucyAtLSBlYWNoIGZ1bmN0aW9uIGlzIGRlcml2ZWQgZnJvbSBGdW5jdGlvbiwgCi0gICAgRnVuY3Rpb25PbmVBcmcsIEZ1bmN0aW9uMkFyZ3MsIGV0Yywgd2l0aCBudW1iZXItb2YtYXJndW1lbnRzIGNoZWNraW5nIGJlaW5nIAotICAgIGFwcGxpZWQgbWFpbmx5IGF0IGNvbXBpbGUgdGltZSAtLSB0aGlzIHBhY2thZ2Ugb25seSBpbXBsZW1lbnRzIFhQYXRoIGZ1bmN0aW9ucywgCi0gICAgWFNMVCBmdW5jdGlvbnMgYXJlIGZvdW5kIGluIHRoZSAidGVtcGxhdGVzIiBwYWNrYWdlLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hCb29sZWFuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hCb29sZWFuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDZkNDA2ZWUuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YQm9vbGVhbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjA1ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggYm9vbGVhbiBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBib29sZWFuIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICovCi1wdWJsaWMgY2xhc3MgWEJvb2xlYW4gZXh0ZW5kcyBYT2JqZWN0Ci17Ci0KLSAgLyoqCi0gICAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICAgKiBBIHRydWUgYm9vbGVhbiBvYmplY3Qgc28gd2UgZG9uJ3QgaGF2ZSB0byBrZWVwIGNyZWF0aW5nIHRoZW0uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhCb29sZWFuIFNfVFJVRSA9IG5ldyBYQm9vbGVhblN0YXRpYyh0cnVlKTsKLQotICAvKioKLSAgICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+Ci0gICAqIEEgdHJ1ZSBib29sZWFuIG9iamVjdCBzbyB3ZSBkb24ndCBoYXZlIHRvIGtlZXAgY3JlYXRpbmcgdGhlbS4KLSAgICovCi0gIHB1YmxpYyBzdGF0aWMgWEJvb2xlYW4gU19GQUxTRSA9IG5ldyBYQm9vbGVhblN0YXRpYyhmYWxzZSk7Ci0KLSAgLyoqIFZhbHVlIG9mIHRoZSBvYmplY3QuCi0gICAqICBAc2VyaWFsICAgICAgICAgKi8KLSAgYm9vbGVhbiBtX3ZhbDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWEJvb2xlYW4gb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gYiBWYWx1ZSBvZiB0aGUgYm9vbGVhbiBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBYQm9vbGVhbihib29sZWFuIGIpCi0gIHsKLQotICAgIHN1cGVyKCk7Ci0KLSAgICBtX3ZhbCA9IGI7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYQm9vbGVhbiBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBiIFZhbHVlIG9mIHRoZSBib29sZWFuIG9iamVjdAotICAgKi8KLSAgcHVibGljIFhCb29sZWFuKEJvb2xlYW4gYikKLSAgewotCi0gICAgc3VwZXIoKTsKLQotICAgIG1fdmFsID0gYi5ib29sZWFuVmFsdWUoKTsKLSAgICBtX29iaiA9IGI7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBUZWxsIHRoYXQgdGhpcyBpcyBhIENMQVNTX0JPT0xFQU4uCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBvZiBDTEFTU19CT09MRUFOCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIENMQVNTX0JPT0xFQU47Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nICIjQk9PTEVBTiIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gIiNCT09MRUFOIjsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtZXJpYyB2YWx1ZSBvZiB0aGUgb2JqZWN0IHZhbHVlCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gIHsKLSAgICByZXR1cm4gbV92YWwgPyAxLjAgOiAwLjA7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0IHZhbHVlIGFzIGEgYm9vbGVhbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gbV92YWw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QncyB2YWx1ZSBhcyBhIHN0cmluZwotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsID8gInRydWUiIDogImZhbHNlIjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBqYXZhIG9iamVjdCB0aGF0J3MgY2xvc2VzdCB0byB0aGUgcmVwcmVzZW50YXRpb24KLSAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0J3MgdmFsdWUgYXMgYSBqYXZhIG9iamVjdAotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgaWYobnVsbCA9PSBtX29iaikKLSAgICAgIG1fb2JqID0gbV92YWwgPyBTX1RSVUUgOiBTX0ZBTFNFOwotICAgIHJldHVybiBtX29iajsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIE9iamVjdCB0byBjb21wYXJlIHRvIHRoaXMgIAotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mIAotICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZSAKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLgotICAgIGlmIChvYmoyLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX05PREVTRVQpCi0gICAgICByZXR1cm4gb2JqMi5lcXVhbHModGhpcyk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICByZXR1cm4gbV92YWwgPT0gb2JqMi5ib29sKCk7Ci0gICAgfQotICAgIGNhdGNoKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gdGUpCi0gICAgewotICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICB9Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YQm9vbGVhblN0YXRpYy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YQm9vbGVhblN0YXRpYy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNTY4OThhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWEJvb2xlYW5TdGF0aWMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS4qOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5yZXMuWFBBVEhFcnJvclJlc291cmNlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnJlcy5YU0xNZXNzYWdlczsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoaXMgY2xhc3MgZG9lc24ndCBoYXZlIGFueSBYUGF0aENvbnRleHQsIHNvIG92ZXJyaWRlCi0gKiB3aGF0ZXZlciB0byBlbnN1cmUgaXQgd29ya3MgT0suCi0gKi8KLXB1YmxpYyBjbGFzcyBYQm9vbGVhblN0YXRpYyBleHRlbmRzIFhCb29sZWFuCi17Ci0KLSAgLyoqIFRoZSB2YWx1ZSBvZiB0aGUgb2JqZWN0LgotICAgKiAgQHNlcmlhbCAgICAgICAgICAqLwotICBib29sZWFuIG1fdmFsOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYQm9vbGVhblN0YXRpYyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBiIFRoZSB2YWx1ZSBvZiB0aGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgWEJvb2xlYW5TdGF0aWMoYm9vbGVhbiBiKQotICB7Ci0KLSAgICBzdXBlcihiKTsKLQotICAgIG1fdmFsID0gYjsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIE9iamVjdCB0byBjb21wYXJlIHRvIHRoaXMgCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBtX3ZhbCA9PSBvYmoyLmJvb2woKTsKLSAgICB9Ci0gICAgY2F0Y2goamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgb3JnLmFwYWNoZS54bWwudXRpbHMuV3JhcHBlZFJ1bnRpbWVFeGNlcHRpb24odGUpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YTUxTdHJpbmdGYWN0b3J5SW1wbC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YTUxTdHJpbmdGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZmNkNTIwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE1MU3RyaW5nRmFjdG9yeUltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzNyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPgotICogQ2xhc3MgWE1MU3RyaW5nRmFjdG9yeUltcGwgY3JlYXRlcyBYU3RyaW5nIHZlcnNpb25zIG9mIFhNTFN0cmluZ3MuCi0gKi8KLXB1YmxpYyBjbGFzcyBYTUxTdHJpbmdGYWN0b3J5SW1wbCBleHRlbmRzIFhNTFN0cmluZ0ZhY3RvcnkKLXsKLSAgLyoqIFRoZSBYTUxTdHJpbmdGYWN0b3J5IHRvIHBhc3MgdG8gRFRNIGNvbnN0cnVjdGlvbi4gICAqLwotICBwcml2YXRlIHN0YXRpYyBYTUxTdHJpbmdGYWN0b3J5IG1feHN0cmluZ2ZhY3RvcnkgPQotICAgIG5ldyBYTUxTdHJpbmdGYWN0b3J5SW1wbCgpOwotCi0gIC8qKgotICAgKiBHZXQgdGhlIFhNTFN0cmluZ0ZhY3RvcnkgdG8gcGFzcyB0byBEVE0gY29uc3RydWN0aW9uLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIEEgbmV2ZXItbnVsbCBzdGF0aWMgcmVmZXJlbmNlIHRvIGEgU3RyaW5nIGZhY3RvcnkuCi0gICAqLwotICBwdWJsaWMgc3RhdGljIFhNTFN0cmluZ0ZhY3RvcnkgZ2V0RmFjdG9yeSgpCi0gIHsKLSAgICByZXR1cm4gbV94c3RyaW5nZmFjdG9yeTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgYSBuZXcgWE1MU3RyaW5nIGZyb20gYSBKYXZhIHN0cmluZy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBKYXZhIFN0cmluZyByZWZlcmVuY2UsIHdoaWNoIG11c3QgYmUgbm9uLW51bGwuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBTdHJpbmcgcmVmZXJlbmNlLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBuZXdzdHIoU3RyaW5nIHN0cmluZykKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHJpbmcpOwotICB9Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhIFhNTFN0cmluZyBmcm9tIGEgRmFzdFN0cmluZ0J1ZmZlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgbmV3c3RyKEZhc3RTdHJpbmdCdWZmZXIgZnNiLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gIHsKLSAgICByZXR1cm4gbmV3IFhTdHJpbmdGb3JGU0IoZnNiLCBzdGFydCwgbGVuZ3RoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENyZWF0ZSBhIFhNTFN0cmluZyBmcm9tIGEgRmFzdFN0cmluZ0J1ZmZlci4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHN0cmluZyBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZSwgd2hpY2ggbXVzdCBiZSBub24tbnVsbC4KLSAgICogQHBhcmFtIHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkuCi0gICAqIEBwYXJhbSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlYWQgZnJvbSB0aGUgYXJyYXkuCi0gICAqCi0gICAqIEByZXR1cm4gQW4gWE1MU3RyaW5nIG9iamVjdCB0aGF0IHdyYXBzIHRoZSBGYXN0U3RyaW5nQnVmZmVyIHJlZmVyZW5jZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgbmV3c3RyKGNoYXJbXSBzdHJpbmcsIGludCBzdGFydCwgaW50IGxlbmd0aCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZ0ZvckNoYXJzKHN0cmluZywgc3RhcnQsIGxlbmd0aCk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgYSBjaGVhcCByZXByZXNlbnRhdGlvbiBvZiBhbiBlbXB0eSBzdHJpbmcuCi0gICAqIAotICAgKiBAcmV0dXJuIEFuIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhbiBYTUxTdHJpbmcgdGhhdCByZXByZXNlbnRzICIiLgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBlbXB0eXN0cigpCi0gIHsKLSAgICByZXR1cm4gWFN0cmluZy5FTVBUWVNUUklORzsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hOb2RlU2V0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hOb2RlU2V0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1MWE0ZDguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YTm9kZVNldC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTcwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLS8vaW1wb3J0IG9yZy53M2MuZG9tLlRleHQ7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50OwotaW1wb3J0IG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNTWFuYWdlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRE9NSGVscGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuQ29udGV4dE5vZGVMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlN0cmluZ1ZlY3RvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBYUGF0aCBub2Rlc2V0IG9iamVjdCwgYW5kIGlzIGNhcGFibGUgb2YKLSAqIGNvbnZlcnRpbmcgdGhlIG5vZGVzZXQgdG8gb3RoZXIgdHlwZXMsIHN1Y2ggYXMgYSBzdHJpbmcuCi0gKi8KLXB1YmxpYyBjbGFzcyBYTm9kZVNldCBleHRlbmRzIFhPYmplY3QKLXsKLSAgcHJvdGVjdGVkIERUTU1hbmFnZXIgbV9kdG1NZ3I7Ci0gIAotICBwdWJsaWMgRFRNTWFuYWdlciBnZXREVE1NZ3IoKQotICB7Ci0gICAgcmV0dXJuIG1fZHRtTWdyOwotICB9Ci0gIAotICAvKioKLSAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciBmb3IgZGVyaXZlZCBvYmplY3RzLgotICAgKi8KLSAgcHJvdGVjdGVkIFhOb2RlU2V0KCkKLSAgewotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhOb2RlU2V0IG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBWYWx1ZSBvZiB0aGUgWE5vZGVTZXQgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgWE5vZGVTZXQoRFRNSXRlcmF0b3IgdmFsKQotICB7Ci0gICAgc3VwZXIodmFsKTsKLSAgICBtX2R0bU1nciA9IHZhbC5nZXREVE1NYW5hZ2VyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGFuIGVtcHR5IFhOb2RlU2V0IG9iamVjdC4gIFRoaXMgaXMgdXNlZCB0byBjcmVhdGUgYSBtdXRhYmxlIAotICAgKiBub2Rlc2V0IHRvIHdoaWNoIHJhbmRvbSBub2RlcyBtYXkgYmUgYWRkZWQuCi0gICAqLwotICBwdWJsaWMgWE5vZGVTZXQoRFRNTWFuYWdlciBkdG1NZ3IpCi0gIHsKLSAgICBzdXBlcihuZXcgTm9kZVNldERUTShkdG1NZ3IpKTsKLSAgICBtX2R0bU1nciA9IGR0bU1ncjsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QgZm9yIG9uZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGFkZCB0byB0aGUgbmV3IFhOb2RlU2V0IG9iamVjdAotICAgKi8KLSAgcHVibGljIFhOb2RlU2V0KGludCBuLCBEVE1NYW5hZ2VyIGR0bU1ncikKLSAgewotCi0gICAgc3VwZXIobmV3IE5vZGVTZXREVE0oZHRtTWdyKSk7Ci0gICAgbV9kdG1NZ3IgPSBkdG1NZ3I7Ci0KLSAgICBpZiAoRFRNLk5VTEwgIT0gbikKLSAgICB7Ci0gICAgICAoKE5vZGVTZXREVE0pIG1fb2JqKS5hZGROb2RlKG4pOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoYXQgdGhpcyBpcyBhIENMQVNTX05PREVTRVQuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBDTEFTU19OT0RFU0VUCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIENMQVNTX05PREVTRVQ7Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nICIjTk9ERVNFVCIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gIiNOT0RFU0VUIjsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgbnVtZXJpYyB2YWx1ZSBvZiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSBhIHNpbmdsZSBub2RlLgotICAgKgotICAgKiBAcGFyYW0gbiBOb2RlIHRvIGNvbnZlcnQKLSAgICoKLSAgICogQHJldHVybiBudW1lcmljIHZhbHVlIG9mIHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIGEgc2luZ2xlIG5vZGUuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIGdldE51bWJlckZyb21Ob2RlKGludCBuKQotICB7Ci0gICAgWE1MU3RyaW5nIHhzdHIgPSBtX2R0bU1nci5nZXREVE0obikuZ2V0U3RyaW5nVmFsdWUobik7Ci0gICAgcmV0dXJuIHhzdHIudG9Eb3VibGUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtZXJpYyB2YWx1ZSBvZiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSB0aGUgCi0gICAqIG5leHQgbm9kZSBpbiB0aGUgTm9kZVNldERUTSwgb3IgTkFOIGlmIG5vIG5vZGUgd2FzIGZvdW5kCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gIHsKLQotICAgIERUTUl0ZXJhdG9yIG5sID0gaXRlcigpOwotICAgIGludCBub2RlID0gbmwubmV4dE5vZGUoKTsKLQotICAgIHJldHVybiAobm9kZSAhPSBEVE0uTlVMTCkgPyBnZXROdW1iZXJGcm9tTm9kZShub2RlKSA6IERvdWJsZS5OYU47Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIsIGJ1dCBhbGxvdyBzaWRlIGVmZmVjdHMsIHN1Y2ggYXMgdGhlIAotICAgKiBpbmNyZW1lbnRpbmcgb2YgYW4gaXRlcmF0b3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVtZXJpYyB2YWx1ZSBvZiB0aGUgc3RyaW5nIGNvbnZlcnNpb24gZnJvbSB0aGUgCi0gICAqIG5leHQgbm9kZSBpbiB0aGUgTm9kZVNldERUTSwgb3IgTkFOIGlmIG5vIG5vZGUgd2FzIGZvdW5kCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bVdpdGhTaWRlRWZmZWN0cygpCi0gIHsKLSAgICBEVE1JdGVyYXRvciBubCA9IGl0ZXJSYXcoKTsKLSAgICBpbnQgbm9kZSA9IG5sLm5leHROb2RlKCk7Ci0KLSAgICByZXR1cm4gKG5vZGUgIT0gRFRNLk5VTEwpID8gZ2V0TnVtYmVyRnJvbU5vZGUobm9kZSkgOiBEb3VibGUuTmFOOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIGEgbmV4dCBub2RlIGluIHRoZSBub2Rlc2V0Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKCkKLSAgewotICAgIHJldHVybiAoaXRlcigpLm5leHROb2RlKCkgIT0gRFRNLk5VTEwpOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbiwgYnV0IGFsbG93IHNpZGUgZWZmZWN0cywgc3VjaCBhcyB0aGUgCi0gICAqIGluY3JlbWVudGluZyBvZiBhbiBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIGEgbmV4dCBub2RlIGluIHRoZSBub2Rlc2V0Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sV2l0aFNpZGVFZmZlY3RzKCkKLSAgewotICAgIHJldHVybiAoaXRlclJhdygpLm5leHROb2RlKCkgIT0gRFRNLk5VTEwpOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIHN0cmluZyBjb252ZXJzaW9uIGZyb20gYSBzaW5nbGUgbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIG4gTm9kZSB0byBjb252ZXJ0Ci0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN0cmluZyBjb252ZXJzaW9uIGZyb20gYSBzaW5nbGUgbm9kZS4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgZ2V0U3RyaW5nRnJvbU5vZGUoaW50IG4pCi0gIHsKLSAgICAvLyAlT1BUJQotICAgIC8vIEkgZ3Vlc3Mgd2UnbGwgaGF2ZSB0byBnZXQgYSBzdGF0aWMgaW5zdGFuY2Ugb2YgdGhlIERUTSBtYW5hZ2VyLi4uCi0gICAgaWYoRFRNLk5VTEwgIT0gbikKLSAgICB7Ci0gICAgICByZXR1cm4gbV9kdG1NZ3IuZ2V0RFRNKG4pLmdldFN0cmluZ1ZhbHVlKG4pOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmV0dXJuIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgRFRNSXRlcmF0b3IgbmwgPSBpdGVyKCk7Ci0gICAgaW50IG5vZGUgPSBubC5uZXh0Tm9kZSgpOwotCi0gICAgaWYobm9kZSAhPSBEVE0uTlVMTCkKLSAgICB7Ci0gICAgICBtX2R0bU1nci5nZXREVE0obm9kZSkuZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG5vZGUsIGNoLCBmYWxzZSk7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGFuIFhNTFN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgbm9kZSBkYXRhIG9yIHRoZSBlbXB0eSBzdHJpbmcuIAotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKCkKLSAgewotICAgIERUTUl0ZXJhdG9yIG5sID0gaXRlcigpOwotICAgIGludCBub2RlID0gbmwubmV4dE5vZGUoKTsKLQotICAgIHJldHVybiAobm9kZSAhPSBEVE0uTlVMTCkgPyBnZXRTdHJpbmdGcm9tTm9kZShub2RlKSA6IFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVG9Gc2Iob3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlciBmc2IpCi0gIHsKLSAgICBYU3RyaW5nIHhzdHJpbmcgPSAoWFN0cmluZyl4c3RyKCk7Ci0gICAgeHN0cmluZy5hcHBlbmRUb0ZzYihmc2IpOwotICB9Ci0gIAotICAvKioKLSAgICogU3BlY2lmeSBpZiBpdCdzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGUgaXRlcmF0b3IgZm9yIHJldXNlLgotICAgKiAKLSAgICogQHBhcmFtIGFsbG93UmVsZWFzZSB0cnVlIGlmIGl0IGlzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGlzIGl0ZXJhdG9yIAotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKQotICB7Ci0gICAgaWYobnVsbCAhPSBtX29iaikKLSAgICAgICgoRFRNSXRlcmF0b3IpIG1fb2JqKS5hbGxvd0RldGFjaFRvUmVsZWFzZShhbGxvd1JlbGVhc2UpOwotICB9Ci0KLSAgLyoqCi0gICAqIERldGFjaGVzIHRoZSA8Y29kZT5EVE1JdGVyYXRvcjwvY29kZT4gZnJvbSB0aGUgc2V0IHdoaWNoIGl0IGl0ZXJhdGVkCi0gICAqIG92ZXIsIHJlbGVhc2luZyBhbnkgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIHBsYWNpbmcgdGhlIGl0ZXJhdG9yCi0gICAqIGluIHRoZSBJTlZBTElEIHN0YXRlLiBBZnRlciA8Y29kZT5kZXRhY2g8L2NvZGU+IGhhcyBiZWVuIGludm9rZWQsCi0gICAqIGNhbGxzIHRvIDxjb2RlPm5leHROb2RlPC9jb2RlPiBvciA8Y29kZT5wcmV2aW91c05vZGU8L2NvZGU+IHdpbGwKLSAgICogcmFpc2UgYSBydW50aW1lIGV4Y2VwdGlvbi4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRldGFjaCgpCi0gIHsKLSAgICBpZihudWxsICE9IG1fb2JqKQotICAgIHsKLSAgICAgIE9iamVjdCBvYmogPSBtX29iajsKLSAgICAgIG1fb2JqID0gbnVsbDsKLSAgICAgICgoRFRNSXRlcmF0b3IpIG9iaikuZGV0YWNoKCk7Ci0gICAgfQotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIHRoZSBuZXh0IG5vZGUgaW4gdGhlIG5vZGVzZXQKLSAgICogb3IgIiIgaWYgdGhlcmUgaXMgbm8gbmV4dCBub2RlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLQotICAgIERUTUl0ZXJhdG9yIG5sID0gaXRlcigpOwotICAgIGludCBub2RlID0gbmwubmV4dE5vZGUoKTsKLQotICAgIHJldHVybiAobm9kZSAhPSBEVE0uTlVMTCkgPyBnZXRTdHJpbmdGcm9tTm9kZShub2RlKS50b1N0cmluZygpIDogIiI7Ci0gIH0KLQotICAvLyAlUkVWSUVXJQotICAvLyBobW1tLi4uCi0vLyAgLyoqCi0vLyAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0vLyAgICoKLS8vICAgKiBAcGFyYW0gc3VwcG9ydCBUaGUgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uIAotLy8gICAqCi0vLyAgICogQHJldHVybiB0aGUgbm9kZXNldCBhcyBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotLy8gICAqLwotLy8gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoQ29udGV4dCBzdXBwb3J0KQotLy8gIHsKLS8vICAgIERvY3VtZW50QnVpbGRlckZhY3RvcnkgZGJmID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotLy8gICAgRG9jdW1lbnRCdWlsZGVyIGRiID0gZGJmLm5ld0RvY3VtZW50QnVpbGRlcigpOwotLy8gICAgRG9jdW1lbnQgbXlEb2MgPSBkYi5uZXdEb2N1bWVudCgpOwotLy8gICAgCi0vLyAgICBEb2N1bWVudEZyYWdtZW50IGRvY0ZyYWcgPSBteURvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0vLwotLy8gICAgRFRNSXRlcmF0b3IgbmwgPSBpdGVyKCk7Ci0vLyAgICBpbnQgbm9kZTsKLS8vCi0vLyAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5vZGUgPSBubC5uZXh0Tm9kZSgpKSkKLS8vICAgIHsKLS8vICAgICAgZnJhZy5hcHBlbmRDaGlsZChub2RlLCB0cnVlLCB0cnVlKTsKLS8vICAgIH0KLS8vCi0vLyAgICByZXR1cm4gZnJhZy5nZXREb2N1bWVudCgpOwotLy8gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlSXRlcmF0b3Igbm9kZXNldCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IG9yZy5hcGFjaGUueG1sLmR0bS5yZWYuRFRNTm9kZUl0ZXJhdG9yKGl0ZXIoKSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4gQWx3YXlzIGlzc3VlcyBhbiBlcnJvci4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVMaXN0IG5vZGVsaXN0KCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Ob2RlTGlzdChpdGVyKCkpOwotICB9Ci0KLSAgCi0vLyAgLyoqCi0vLyAgICogUmV0dXJuIGEgamF2YSBvYmplY3QgdGhhdCdzIGNsb3Nlc3QgdG8gdGhlIHJlcHJlc2VudGF0aW9uCi0vLyAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLS8vICAgKgotLy8gICAqIEByZXR1cm4gVGhlIG9iamVjdCB0aGF0IHRoaXMgY2xhc3Mgd3JhcHMKLS8vICAgKi8KLS8vICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0vLyAgewotLy8gICAgcmV0dXJuIG5ldyBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVMaXN0KGl0ZXIoKSk7Ci0vLyAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGl0ZXJhdG9yIHdpdGhvdXQgY2xvbmluZywgZXRjLgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGl0ZXJSYXcoKQotICB7Ci0KLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkluIFhOb2RlU2V0Lml0ZXIoKSIpOwotICAgIHJldHVybiAoRFRNSXRlcmF0b3IpIG1fb2JqOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG5vZGVzZXQgYXMgYSBub2RlbGlzdAotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGl0ZXIoKQotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgcmV0dXJuICgoRFRNSXRlcmF0b3IpIG1fb2JqKS5jbG9uZVdpdGhSZXNldCgpOwotICAgIH0KLSAgICBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY25zZSkKLSAgICB7Ci0gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihjbnNlLmdldE1lc3NhZ2UoKSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG11dGFibGVOb2Rlc2V0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBub2Rlc2V0IGFzIGEgbXV0YWJsZU5vZGVzZXQKLSAgICovCi0gIHB1YmxpYyBOb2RlU2V0RFRNIG11dGFibGVOb2Rlc2V0KCkKLSAgewotCi0gICAgTm9kZVNldERUTSBtbmw7Ci0KLSAgICBpZihtX29iaiBpbnN0YW5jZW9mIE5vZGVTZXREVE0pCi0gICAgewotICAgICAgbW5sID0gKE5vZGVTZXREVE0pIG1fb2JqOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgbW5sID0gbmV3IE5vZGVTZXREVE0oaXRlcigpKTsKLSAgICAgIG1fb2JqID0gbW5sOwotICAgIH0KLQotICAgIHJldHVybiBtbmw7Ci0gIH0KLQotICAvKiogTGVzcyB0aGFuIGNvbXBhcmF0b3IgICAgICAgICAqLwotICBzdGF0aWMgTGVzc1RoYW5Db21wYXJhdG9yIFNfTFQgPSBuZXcgTGVzc1RoYW5Db21wYXJhdG9yKCk7Ci0KLSAgLyoqIExlc3MgdGhhbiBvciBlcXVhbCBjb21wYXJhdG9yICAgICAgICAgICovCi0gIHN0YXRpYyBMZXNzVGhhbk9yRXF1YWxDb21wYXJhdG9yIFNfTFRFID0gbmV3IExlc3NUaGFuT3JFcXVhbENvbXBhcmF0b3IoKTsKLQotICAvKiogR3JlYXRlciB0aGFuIGNvbXBhcmF0b3IgICAgICAgICAqLwotICBzdGF0aWMgR3JlYXRlclRoYW5Db21wYXJhdG9yIFNfR1QgPSBuZXcgR3JlYXRlclRoYW5Db21wYXJhdG9yKCk7Ci0KLSAgLyoqIEdyZWF0ZXIgdGhhbiBvciBlcXVhbCBjb21wYXJhdG9yICAgICAgICAgICovCi0gIHN0YXRpYyBHcmVhdGVyVGhhbk9yRXF1YWxDb21wYXJhdG9yIFNfR1RFID0KLSAgICBuZXcgR3JlYXRlclRoYW5PckVxdWFsQ29tcGFyYXRvcigpOwotCi0gIC8qKiBFcXVhbCBjb21wYXJhdG9yICAgICAgICAgKi8KLSAgc3RhdGljIEVxdWFsQ29tcGFyYXRvciBTX0VRID0gbmV3IEVxdWFsQ29tcGFyYXRvcigpOwotCi0gIC8qKiBOb3QgZXF1YWwgY29tcGFyYXRvciAgICAgICAgICovCi0gIHN0YXRpYyBOb3RFcXVhbENvbXBhcmF0b3IgU19ORVEgPSBuZXcgTm90RXF1YWxDb21wYXJhdG9yKCk7Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gdGhlIG90aGVyLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICogQHBhcmFtIGNvbXBhcmF0b3IgQ29tcGFyYXRvciB0byB1c2UKLSAgICoKLSAgICogQHJldHVybiBTZWUgdGhlIGNvbW1lbnRzIGJlbG93IGZvciBlYWNoIG9iamVjdCB0eXBlIGNvbXBhcmlzb24gCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gY29tcGFyZShYT2JqZWN0IG9iajIsIENvbXBhcmF0b3IgY29tcGFyYXRvcikKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotICAgIGludCB0eXBlID0gb2JqMi5nZXRUeXBlKCk7Ci0KLSAgICBpZiAoWE9iamVjdC5DTEFTU19OT0RFU0VUID09IHR5cGUpCi0gICAgewotICAgICAgLy8gJU9QVCUgVGhpcyBzaG91bGQgYmUgWE1MU3RyaW5nIGJhc2VkIGluc3RlYWQgb2Ygc3RyaW5nIGJhc2VkLi4uCi0KLSAgICAgIC8vIEZyb20gaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGg6IAotICAgICAgLy8gSWYgYm90aCBvYmplY3RzIHRvIGJlIGNvbXBhcmVkIGFyZSBub2RlLXNldHMsIHRoZW4gdGhlIGNvbXBhcmlzb24gCi0gICAgICAvLyB3aWxsIGJlIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlcmUgaXMgYSBub2RlIGluIHRoZSBmaXJzdCBub2RlLXNldCAKLSAgICAgIC8vIGFuZCBhIG5vZGUgaW4gdGhlIHNlY29uZCBub2RlLXNldCBzdWNoIHRoYXQgdGhlIHJlc3VsdCBvZiBwZXJmb3JtaW5nIAotICAgICAgLy8gdGhlIGNvbXBhcmlzb24gb24gdGhlIHN0cmluZy12YWx1ZXMgb2YgdGhlIHR3byBub2RlcyBpcyB0cnVlLgotICAgICAgLy8gTm90ZSB0aGlzIGxpdHRsZSBnZW0gZnJvbSB0aGUgZHJhZnQ6Ci0gICAgICAvLyBOT1RFOiBJZiAkeCBpcyBib3VuZCB0byBhIG5vZGUtc2V0LCB0aGVuICR4PSJmb28iIAotICAgICAgLy8gZG9lcyBub3QgbWVhbiB0aGUgc2FtZSBhcyBub3QoJHghPSJmb28iKTogdGhlIGZvcm1lciAKLSAgICAgIC8vIGlzIHRydWUgaWYgYW5kIG9ubHkgaWYgc29tZSBub2RlIGluICR4IGhhcyB0aGUgc3RyaW5nLXZhbHVlIAotICAgICAgLy8gZm9vOyB0aGUgbGF0dGVyIGlzIHRydWUgaWYgYW5kIG9ubHkgaWYgYWxsIG5vZGVzIGluICR4IGhhdmUgCi0gICAgICAvLyB0aGUgc3RyaW5nLXZhbHVlIGZvby4KLSAgICAgIERUTUl0ZXJhdG9yIGxpc3QxID0gaXRlcigpOwotICAgICAgRFRNSXRlcmF0b3IgbGlzdDIgPSAoKFhOb2RlU2V0KSBvYmoyKS5pdGVyKCk7Ci0gICAgICBpbnQgbm9kZTE7Ci0gICAgICBqYXZhLnV0aWwuVmVjdG9yIG5vZGUyU3RyaW5ncyA9IG51bGw7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZTEgPSBsaXN0MS5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgWE1MU3RyaW5nIHMxID0gZ2V0U3RyaW5nRnJvbU5vZGUobm9kZTEpOwotCi0gICAgICAgIGlmIChudWxsID09IG5vZGUyU3RyaW5ncykKLSAgICAgICAgewotICAgICAgICAgIGludCBub2RlMjsKLQotICAgICAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZTIgPSBsaXN0Mi5uZXh0Tm9kZSgpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBYTUxTdHJpbmcgczIgPSBnZXRTdHJpbmdGcm9tTm9kZShub2RlMik7Ci0KLSAgICAgICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmVTdHJpbmdzKHMxLCBzMikpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7Ci0KLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmIChudWxsID09IG5vZGUyU3RyaW5ncykKLSAgICAgICAgICAgICAgbm9kZTJTdHJpbmdzID0gbmV3IGphdmEudXRpbC5WZWN0b3IoKTsKLQotICAgICAgICAgICAgbm9kZTJTdHJpbmdzLmFkZEVsZW1lbnQoczIpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICBpbnQgbiA9IG5vZGUyU3RyaW5ncy5zaXplKCk7Ci0KLSAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlU3RyaW5ncyhzMSwgKFhNTFN0cmluZylub2RlMlN0cmluZ3MuZWxlbWVudEF0KGkpKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKLQotICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAoWE9iamVjdC5DTEFTU19CT09MRUFOID09IHR5cGUpCi0gICAgewotCi0gICAgICAvLyBGcm9tIGh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoOiAKLSAgICAgIC8vIElmIG9uZSBvYmplY3QgdG8gYmUgY29tcGFyZWQgaXMgYSBub2RlLXNldCBhbmQgdGhlIG90aGVyIGlzIGEgYm9vbGVhbiwgCi0gICAgICAvLyB0aGVuIHRoZSBjb21wYXJpc29uIHdpbGwgYmUgdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGUgcmVzdWx0IG9mIAotICAgICAgLy8gcGVyZm9ybWluZyB0aGUgY29tcGFyaXNvbiBvbiB0aGUgYm9vbGVhbiBhbmQgb24gdGhlIHJlc3VsdCBvZiAKLSAgICAgIC8vIGNvbnZlcnRpbmcgdGhlIG5vZGUtc2V0IHRvIGEgYm9vbGVhbiB1c2luZyB0aGUgYm9vbGVhbiBmdW5jdGlvbiAKLSAgICAgIC8vIGlzIHRydWUuCi0gICAgICBkb3VibGUgbnVtMSA9IGJvb2woKSA/IDEuMCA6IDAuMDsKLSAgICAgIGRvdWJsZSBudW0yID0gb2JqMi5udW0oKTsKLQotICAgICAgcmVzdWx0ID0gY29tcGFyYXRvci5jb21wYXJlTnVtYmVycyhudW0xLCBudW0yKTsKLSAgICB9Ci0gICAgZWxzZSBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gdHlwZSkKLSAgICB7Ci0KLSAgICAgIC8vIEZyb20gaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGg6IAotICAgICAgLy8gSWYgb25lIG9iamVjdCB0byBiZSBjb21wYXJlZCBpcyBhIG5vZGUtc2V0IGFuZCB0aGUgb3RoZXIgaXMgYSBudW1iZXIsIAotICAgICAgLy8gdGhlbiB0aGUgY29tcGFyaXNvbiB3aWxsIGJlIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlcmUgaXMgYSAKLSAgICAgIC8vIG5vZGUgaW4gdGhlIG5vZGUtc2V0IHN1Y2ggdGhhdCB0aGUgcmVzdWx0IG9mIHBlcmZvcm1pbmcgdGhlIAotICAgICAgLy8gY29tcGFyaXNvbiBvbiB0aGUgbnVtYmVyIHRvIGJlIGNvbXBhcmVkIGFuZCBvbiB0aGUgcmVzdWx0IG9mIAotICAgICAgLy8gY29udmVydGluZyB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoYXQgbm9kZSB0byBhIG51bWJlciB1c2luZyAKLSAgICAgIC8vIHRoZSBudW1iZXIgZnVuY3Rpb24gaXMgdHJ1ZS4gCi0gICAgICBEVE1JdGVyYXRvciBsaXN0MSA9IGl0ZXIoKTsKLSAgICAgIGRvdWJsZSBudW0yID0gb2JqMi5udW0oKTsKLSAgICAgIGludCBub2RlOwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG5vZGUgPSBsaXN0MS5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgZG91YmxlIG51bTEgPSBnZXROdW1iZXJGcm9tTm9kZShub2RlKTsKLQotICAgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlTnVtYmVycyhudW0xLCBudW0yKSkKLSAgICAgICAgewotICAgICAgICAgIHJlc3VsdCA9IHRydWU7Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX1JUUkVFRlJBRyA9PSB0eXBlKQotICAgIHsKLSAgICAgIFhNTFN0cmluZyBzMiA9IG9iajIueHN0cigpOwotICAgICAgRFRNSXRlcmF0b3IgbGlzdDEgPSBpdGVyKCk7Ci0gICAgICBpbnQgbm9kZTsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChub2RlID0gbGlzdDEubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIFhNTFN0cmluZyBzMSA9IGdldFN0cmluZ0Zyb21Ob2RlKG5vZGUpOwotCi0gICAgICAgIGlmIChjb21wYXJhdG9yLmNvbXBhcmVTdHJpbmdzKHMxLCBzMikpCi0gICAgICAgIHsKLSAgICAgICAgICByZXN1bHQgPSB0cnVlOwotCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAoWE9iamVjdC5DTEFTU19TVFJJTkcgPT0gdHlwZSkKLSAgICB7Ci0KLSAgICAgIC8vIEZyb20gaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGg6IAotICAgICAgLy8gSWYgb25lIG9iamVjdCB0byBiZSBjb21wYXJlZCBpcyBhIG5vZGUtc2V0IGFuZCB0aGUgb3RoZXIgaXMgYSAKLSAgICAgIC8vIHN0cmluZywgdGhlbiB0aGUgY29tcGFyaXNvbiB3aWxsIGJlIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlcmUgCi0gICAgICAvLyBpcyBhIG5vZGUgaW4gdGhlIG5vZGUtc2V0IHN1Y2ggdGhhdCB0aGUgcmVzdWx0IG9mIHBlcmZvcm1pbmcgCi0gICAgICAvLyB0aGUgY29tcGFyaXNvbiBvbiB0aGUgc3RyaW5nLXZhbHVlIG9mIHRoZSBub2RlIGFuZCB0aGUgb3RoZXIgCi0gICAgICAvLyBzdHJpbmcgaXMgdHJ1ZS4gCi0gICAgICBYTUxTdHJpbmcgczIgPSBvYmoyLnhzdHIoKTsKLSAgICAgIERUTUl0ZXJhdG9yIGxpc3QxID0gaXRlcigpOwotICAgICAgaW50IG5vZGU7Ci0KLSAgICAgIHdoaWxlIChEVE0uTlVMTCAhPSAobm9kZSA9IGxpc3QxLm5leHROb2RlKCkpKQotICAgICAgewotICAgICAgICBYTUxTdHJpbmcgczEgPSBnZXRTdHJpbmdGcm9tTm9kZShub2RlKTsKLSAgICAgICAgaWYgKGNvbXBhcmF0b3IuY29tcGFyZVN0cmluZ3MoczEsIHMyKSkKLSAgICAgICAgewotICAgICAgICAgIHJlc3VsdCA9IHRydWU7Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmVzdWx0ID0gY29tcGFyYXRvci5jb21wYXJlTnVtYmVycyh0aGlzLm51bSgpLCBvYmoyLm51bSgpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gdGhlIG90aGVyLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBvYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICoKLSAgICogQHJldHVybiBzZWUgdGhpcy5jb21wYXJlKC4uLikgCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbGVzc1RoYW4oWE9iamVjdCBvYmoyKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBhcmUob2JqMiwgU19MVCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiBvbmUgb2JqZWN0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgb3RoZXIuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIG9iamVjdCB0byBjb21wYXJlIHRoaXMgbm9kZXNldCB0bwotICAgKgotICAgKiBAcmV0dXJuIHNlZSB0aGlzLmNvbXBhcmUoLi4uKSAKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBhcmUob2JqMiwgU19MVEUpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgb25lIG9iamVjdCBpcyBsZXNzIHRoYW4gdGhlIG90aGVyLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBvYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICoKLSAgICogQHJldHVybiBzZWUgdGhpcy5jb21wYXJlKC4uLikgCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZ3JlYXRlclRoYW4oWE9iamVjdCBvYmoyKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBhcmUob2JqMiwgU19HVCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiBvbmUgb2JqZWN0IGlzIGxlc3MgdGhhbiB0aGUgb3RoZXIuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIG9iamVjdCB0byBjb21wYXJlIHRoaXMgbm9kZXNldCB0bwotICAgKgotICAgKiBAcmV0dXJuIHNlZSB0aGlzLmNvbXBhcmUoLi4uKSAKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBncmVhdGVyVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gY29tcGFyZShvYmoyLCBTX0dURSk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBvYmplY3QgdG8gY29tcGFyZSB0aGlzIG5vZGVzZXQgdG8KLSAgICoKLSAgICogQHJldHVybiBzZWUgdGhpcy5jb21wYXJlKC4uLikgCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBjb21wYXJlKG9iajIsIFNfRVEpOwotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBub3QgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIG9iamVjdCB0byBjb21wYXJlIHRoaXMgbm9kZXNldCB0bwotICAgKgotICAgKiBAcmV0dXJuIHNlZSB0aGlzLmNvbXBhcmUoLi4uKSAKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBub3RFcXVhbHMoWE9iamVjdCBvYmoyKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGNvbXBhcmUob2JqMiwgU19ORVEpOwotICB9Ci19Ci0KLS8qKgotICogY29tcGFyZXMgbm9kZXMgZm9yIHZhcmlvdXMgYm9vbGVhbiBvcGVyYXRpb25zLgotICovCi1hYnN0cmFjdCBjbGFzcyBDb21wYXJhdG9yCi17Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIHN0cmluZ3MKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHMxIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBzMiBTZWNvbmQgU3RyaW5nIHRvIGNvbXBhcmUgCi0gICAqCi0gICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5ncyBhcmUgZXF1YWwgb3Igbm90Ci0gICAqLwotICBhYnN0cmFjdCBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFhNTFN0cmluZyBzMSwgWE1MU3RyaW5nIHMyKTsKLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gbnVtYmVycwotICAgKgotICAgKgotICAgKiBAcGFyYW0gbjEgRmlyc3QgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIG4yIFNlY29uZCBudW1iZXIgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG51bWJlcnMgYXJlIGVxdWFsIG9yIG5vdAotICAgKi8KLSAgYWJzdHJhY3QgYm9vbGVhbiBjb21wYXJlTnVtYmVycyhkb3VibGUgbjEsIGRvdWJsZSBuMik7Ci19Ci0KLS8qKgotICogQ29tcGFyZSBzdHJpbmdzIG9yIG51bWJlcnMgZm9yIGxlc3MgdGhhbi4KLSAqLwotY2xhc3MgTGVzc1RoYW5Db21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGZvciBsZXNzIHRoYW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlIAotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgczEgaXMgbGVzcyB0aGFuIHMyCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFhNTFN0cmluZyBzMSwgWE1MU3RyaW5nIHMyKQotICB7Ci0gICAgcmV0dXJuIChzMS50b0RvdWJsZSgpIDwgczIudG9Eb3VibGUoKSk7Ci0gICAgLy8gcmV0dXJuIHMxLmNvbXBhcmVUbyhzMikgPCAwOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIG51bWJlcnMgZm9yIGxlc3MgdGhhbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIG4xIEZpcnN0IG51bWJlciB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBuMiBTZWNvbmQgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIG4xIGlzIGxlc3MgdGhhbiBuMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlTnVtYmVycyhkb3VibGUgbjEsIGRvdWJsZSBuMikKLSAgewotICAgIHJldHVybiBuMSA8IG4yOwotICB9Ci19Ci0KLS8qKgotICogQ29tcGFyZSBzdHJpbmdzIG9yIG51bWJlcnMgZm9yIGxlc3MgdGhhbiBvciBlcXVhbC4KLSAqLwotY2xhc3MgTGVzc1RoYW5PckVxdWFsQ29tcGFyYXRvciBleHRlbmRzIENvbXBhcmF0b3IKLXsKLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gc3RyaW5ncyBmb3IgbGVzcyB0aGFuIG9yIGVxdWFsLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gczEgRmlyc3Qgc3RyaW5nIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIHMyIFNlY29uZCBTdHJpbmcgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgczEgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHMyCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVTdHJpbmdzKFhNTFN0cmluZyBzMSwgWE1MU3RyaW5nIHMyKQotICB7Ci0gICAgcmV0dXJuIChzMS50b0RvdWJsZSgpIDw9IHMyLnRvRG91YmxlKCkpOwotICAgIC8vIHJldHVybiBzMS5jb21wYXJlVG8oczIpIDw9IDA7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gbnVtYmVycyBmb3IgbGVzcyB0aGFuIG9yIGVxdWFsLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbjEgRmlyc3QgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIG4yIFNlY29uZCBudW1iZXIgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbjEgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIG4yCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVOdW1iZXJzKGRvdWJsZSBuMSwgZG91YmxlIG4yKQotICB7Ci0gICAgcmV0dXJuIG4xIDw9IG4yOwotICB9Ci19Ci0KLS8qKgotICogQ29tcGFyZSBzdHJpbmdzIG9yIG51bWJlcnMgZm9yIGdyZWF0ZXIgdGhhbi4KLSAqLwotY2xhc3MgR3JlYXRlclRoYW5Db21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGZvciBncmVhdGVyIHRoYW4uCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBzMSBpcyBncmVhdGVyIHRoYW4gczIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZVN0cmluZ3MoWE1MU3RyaW5nIHMxLCBYTUxTdHJpbmcgczIpCi0gIHsKLSAgICByZXR1cm4gKHMxLnRvRG91YmxlKCkgPiBzMi50b0RvdWJsZSgpKTsKLSAgICAvLyByZXR1cm4gczEuY29tcGFyZVRvKHMyKSA+IDA7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gbnVtYmVycyBmb3IgZ3JlYXRlciB0aGFuLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbjEgRmlyc3QgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIG4yIFNlY29uZCBudW1iZXIgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbjEgaXMgZ3JlYXRlciB0aGFuIG4yCi0gICAqLwotICBib29sZWFuIGNvbXBhcmVOdW1iZXJzKGRvdWJsZSBuMSwgZG91YmxlIG4yKQotICB7Ci0gICAgcmV0dXJuIG4xID4gbjI7Ci0gIH0KLX0KLQotLyoqCi0gKiBDb21wYXJlIHN0cmluZ3Mgb3IgbnVtYmVycyBmb3IgZ3JlYXRlciB0aGFuIG9yIGVxdWFsLgotICovCi1jbGFzcyBHcmVhdGVyVGhhbk9yRXF1YWxDb21wYXJhdG9yIGV4dGVuZHMgQ29tcGFyYXRvcgotewotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGZvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBzMSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gczIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZVN0cmluZ3MoWE1MU3RyaW5nIHMxLCBYTUxTdHJpbmcgczIpCi0gIHsKLSAgICByZXR1cm4gKHMxLnRvRG91YmxlKCkgPj0gczIudG9Eb3VibGUoKSk7Ci0gICAgLy8gcmV0dXJuIHMxLmNvbXBhcmVUbyhzMikgPj0gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBudW1iZXJzIGZvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuMSBGaXJzdCBudW1iZXIgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gbjIgU2Vjb25kIG51bWJlciB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuMSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gbjIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZU51bWJlcnMoZG91YmxlIG4xLCBkb3VibGUgbjIpCi0gIHsKLSAgICByZXR1cm4gbjEgPj0gbjI7Ci0gIH0KLX0KLQotLyoqCi0gKiBDb21wYXJlIHN0cmluZ3Mgb3IgbnVtYmVycyBmb3IgZXF1YWxpdHkuCi0gKi8KLWNsYXNzIEVxdWFsQ29tcGFyYXRvciBleHRlbmRzIENvbXBhcmF0b3IKLXsKLQotICAvKioKLSAgICogQ29tcGFyZSB0d28gc3RyaW5ncyBmb3IgZXF1YWxpdHkuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBzMSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gczIgU2Vjb25kIFN0cmluZyB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBzMSBpcyBlcXVhbCB0byBzMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlU3RyaW5ncyhYTUxTdHJpbmcgczEsIFhNTFN0cmluZyBzMikKLSAgewotICAgIHJldHVybiBzMS5lcXVhbHMoczIpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIG51bWJlcnMgZm9yIGVxdWFsaXR5LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbjEgRmlyc3QgbnVtYmVyIHRvIGNvbXBhcmUKLSAgICogQHBhcmFtIG4yIFNlY29uZCBudW1iZXIgdG8gY29tcGFyZQotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgbjEgaXMgZXF1YWwgdG8gbjIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZU51bWJlcnMoZG91YmxlIG4xLCBkb3VibGUgbjIpCi0gIHsKLSAgICByZXR1cm4gbjEgPT0gbjI7Ci0gIH0KLX0KLQotLyoqCi0gKiBDb21wYXJlIHN0cmluZ3Mgb3IgbnVtYmVycyBmb3Igbm9uLWVxdWFsaXR5LgotICovCi1jbGFzcyBOb3RFcXVhbENvbXBhcmF0b3IgZXh0ZW5kcyBDb21wYXJhdG9yCi17Ci0KLSAgLyoqCi0gICAqIENvbXBhcmUgdHdvIHN0cmluZ3MgZm9yIG5vbi1lcXVhbGl0eS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHMxIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCi0gICAqIEBwYXJhbSBzMiBTZWNvbmQgU3RyaW5nIHRvIGNvbXBhcmUKLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHMxIGlzIG5vdCBlcXVhbCB0byBzMgotICAgKi8KLSAgYm9vbGVhbiBjb21wYXJlU3RyaW5ncyhYTUxTdHJpbmcgczEsIFhNTFN0cmluZyBzMikKLSAgewotICAgIHJldHVybiAhczEuZXF1YWxzKHMyKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlIHR3byBudW1iZXJzIGZvciBub24tZXF1YWxpdHkuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuMSBGaXJzdCBudW1iZXIgdG8gY29tcGFyZQotICAgKiBAcGFyYW0gbjIgU2Vjb25kIG51bWJlciB0byBjb21wYXJlCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiBuMSBpcyBub3QgZXF1YWwgdG8gbjIKLSAgICovCi0gIGJvb2xlYW4gY29tcGFyZU51bWJlcnMoZG91YmxlIG4xLCBkb3VibGUgbjIpCi0gIHsKLSAgICByZXR1cm4gbjEgIT0gbjI7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE5vZGVTZXRGb3JET00uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE5vZGVTZXRGb3JET00uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTFjMjM2Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hOb2RlU2V0Rm9yRE9NLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MSArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci1pbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7Ci1pbXBvcnQgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIG92ZXJyaWRlcyB0aGUgWE5vZGVTZXQjb2JqZWN0KCkgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIG9yaWdpbmFsIAotICogTm9kZSBvYmplY3QsIE5vZGVMaXN0IG9iamVjdCwgb3IgTm9kZUl0ZXJhdG9yLgotICovCi1wdWJsaWMgY2xhc3MgWE5vZGVTZXRGb3JET00gZXh0ZW5kcyBYTm9kZVNldAotewotICBPYmplY3QgbV9vcmlnT2JqOwotCi0gIHB1YmxpYyBYTm9kZVNldEZvckRPTShOb2RlIG5vZGUsIERUTU1hbmFnZXIgZHRtTWdyKQotICB7Ci0gICAgbV9kdG1NZ3IgPSBkdG1NZ3I7Ci0gICAgbV9vcmlnT2JqID0gbm9kZTsKLSAgICBpbnQgZHRtSGFuZGxlID0gZHRtTWdyLmdldERUTUhhbmRsZUZyb21Ob2RlKG5vZGUpOwotICAgIG1fb2JqID0gbmV3IE5vZGVTZXREVE0oZHRtTWdyKTsKLSAgICAoKE5vZGVTZXREVE0pIG1fb2JqKS5hZGROb2RlKGR0bUhhbmRsZSk7Ci0gIH0KLSAgCi0gIHB1YmxpYyBYTm9kZVNldEZvckRPTShOb2RlTGlzdCBub2RlTGlzdCwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgbV9kdG1NZ3IgPSB4Y3R4dC5nZXREVE1NYW5hZ2VyKCk7Ci0gICAgbV9vcmlnT2JqID0gbm9kZUxpc3Q7Ci0gICAgbV9vYmogPSBuZXcgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNKG5vZGVMaXN0LCB4Y3R4dCk7Ci0gIH0KLQotICBwdWJsaWMgWE5vZGVTZXRGb3JET00oTm9kZUl0ZXJhdG9yIG5vZGVJdGVyLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICBtX2R0bU1nciA9IHhjdHh0LmdldERUTU1hbmFnZXIoKTsKLSAgICBtX29yaWdPYmogPSBub2RlSXRlcjsKLSAgICBtX29iaiA9IG5ldyBvcmcuYXBhY2hlLnhwYXRoLk5vZGVTZXREVE0obm9kZUl0ZXIsIHhjdHh0KTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybiB0aGUgb3JpZ2luYWwgRE9NIG9iamVjdCB0aGF0IHRoZSB1c2VyIHBhc3NlZCBpbi4gIEZvciB1c2UgcHJpbWFyaWx5Ci0gICAqIGJ5IHRoZSBleHRlbnNpb24gbWVjaGFuaXNtLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBvYmplY3QgdGhhdCB0aGlzIGNsYXNzIHdyYXBzCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0gIHsKLSAgICByZXR1cm4gbV9vcmlnT2JqOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlSXRlcmF0b3Igbm9kZXNldCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKG1fb3JpZ09iaiBpbnN0YW5jZW9mIE5vZGVJdGVyYXRvcikgCi0gICAgICAgICAgICAgICAgICAgPyAoTm9kZUl0ZXJhdG9yKW1fb3JpZ09iaiA6IHN1cGVyLm5vZGVzZXQoKTsgICAgICAKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG5vZGVsaXN0LiBBbHdheXMgaXNzdWVzIGFuIGVycm9yLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgTm9kZUxpc3Qgbm9kZWxpc3QoKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChtX29yaWdPYmogaW5zdGFuY2VvZiBOb2RlTGlzdCkgCi0gICAgICAgICAgICAgICAgICAgPyAoTm9kZUxpc3QpbV9vcmlnT2JqIDogc3VwZXIubm9kZWxpc3QoKTsgICAgICAKLSAgfQotCi0KLQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE51bGwuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE51bGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWMzOWVlNy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hOdWxsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxNzEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotLy9pbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnRGcmFnbWVudDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJnZW5lcmFsIi8+Ci0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gWFBhdGggbnVsbCBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBudWxsIHRvIG90aGVyIHR5cGVzLCBzdWNoIGFzIGEgc3RyaW5nLgotICovCi1wdWJsaWMgY2xhc3MgWE51bGwgZXh0ZW5kcyBYT2JqZWN0Ci17Ci0KLSAgLyoqCi0gICAqIENyZWF0ZSBhbiBYT2JqZWN0LgotICAgKi8KLSAgcHVibGljIFhOdWxsKCkKLSAgewotICAgIHN1cGVyKCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB3aGF0IGtpbmQgb2YgY2xhc3MgdGhpcyBpcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIENMQVNTX05VTEwKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBHaXZlbiBhIHJlcXVlc3QgdHlwZSwgcmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy4KLSAgICogRm9yIGRpYWdub3N0aWMgcHVycG9zZXMuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBzdHJpbmcgIiNDTEFTU19OVUxMIgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiI0NMQVNTX05VTEwiOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlci4KLSAgICogCi0gICAqIEByZXR1cm4gMC4wCi0gICAqLwotCi0gIHB1YmxpYyBkb3VibGUgbnVtKCkKLSAgewotICAgIHJldHVybiAwLjA7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIGVtcHR5IHN0cmluZyAiIgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuICIiOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBYUGF0aCBjb250ZXh0IHRvIHVzZSBmb3IgdGhlIGNvbnZlcnNpb24KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0IGFzIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IHJ0ZihYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotICAgIC8vIERUTSBmcmFnID0gc3VwcG9ydC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0gICAgLy8gJVJFVklFVyUKLSAgICByZXR1cm4gRFRNLk5VTEw7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGl0ZXIoKQotICB7Ci0gICAgcmV0dXJuIG51bGw7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIG9mIHR5cGUgQ0xBU1NfTlVMTAotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotICAgIHJldHVybiBvYmoyLmdldFR5cGUoKSA9PSBDTEFTU19OVUxMOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hOdW1iZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE51bWJlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0ZGY5ZWFiLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE51bWJlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDUxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLio7Ci1pbXBvcnQgamF2YS5tYXRoLkJpZ0RlY2ltYWw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBYUGF0aCBudW1iZXIsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBudW1iZXIgdG8gb3RoZXIgdHlwZXMsIHN1Y2ggYXMgYSBzdHJpbmcuCi0gKi8KLXB1YmxpYyBjbGFzcyBYTnVtYmVyIGV4dGVuZHMgWE9iamVjdAotewotCi0gIC8qKiBWYWx1ZSBvZiB0aGUgWE51bWJlciBvYmplY3QuCi0gICAqICBAc2VyaWFsICAgICAgICAgKi8KLSAgZG91YmxlIG1fdmFsOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBkIFZhbHVlIG9mIHRoZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBYTnVtYmVyKGRvdWJsZSBkKQotICB7Ci0gICAgc3VwZXIoKTsKLQotICAgIG1fdmFsID0gZDsKLSAgfQotICAKLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhOb2RlU2V0IG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIGQgVmFsdWUgb2YgdGhlIG9iamVjdAotICAgKi8KLSAgcHVibGljIFhOdW1iZXIoTnVtYmVyIG51bSkKLSAgewotCi0gICAgc3VwZXIoKTsKLQotICAgIG1fdmFsID0gbnVtLmRvdWJsZVZhbHVlKCk7Ci0gICAgbV9vYmogPSBudW07Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB0aGF0IHRoaXMgaXMgYSBDTEFTU19OVU1CRVIuCi0gICAqCi0gICAqIEByZXR1cm4gbm9kZSB0eXBlIENMQVNTX05VTUJFUiAKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfTlVNQkVSOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgcmVxdWVzdCB0eXBlLCByZXR1cm4gdGhlIGVxdWl2YWxlbnQgc3RyaW5nLgotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIHN0cmluZyAiI05VTUJFUiIgCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldFR5cGVTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuICIjTlVNQkVSIjsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBYTnVtYmVyIG9iamVjdAotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKQotICB7Ci0gICAgcmV0dXJuIG1fdmFsOwotICB9Ci0gIAotICAvKioKLSAgICogRXZhbHVhdGUgZXhwcmVzc2lvbiB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiAwLjAKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bShYUGF0aENvbnRleHQgeGN0eHQpIAotICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiBtX3ZhbDsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcmV0dXJuIGZhbHNlIGlmIHRoZSB2YWx1ZSBpcyBOYU4gb3IgZXF1YWwgdG8gMC4wCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKCkKLSAgewotICAgIHJldHVybiAoRG91YmxlLmlzTmFOKG1fdmFsKSB8fCAobV92YWwgPT0gMC4wKSkgPyBmYWxzZSA6IHRydWU7Ci0gIH0KLQotLy8gIC8qKgotLy8gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLS8vICAgKgotLy8gICAqIEByZXR1cm4gIk5hTiIgaWYgdGhlIG51bWJlciBpcyBOYU4sIEluZmluaXR5IG9yIC1JbmZpbml0eSBpZgotLy8gICAqIHRoZSBudW1iZXIgaXMgaW5maW5pdGUgb3IgdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbnVtYmVyLgotLy8gICAqLwotLy8gIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUkVDSVNJT04gPSAxNjsKLS8vICBwdWJsaWMgU3RyaW5nIHN0cigpCi0vLyAgewotLy8KLS8vICAgIGlmIChEb3VibGUuaXNOYU4obV92YWwpKQotLy8gICAgewotLy8gICAgICByZXR1cm4gIk5hTiI7Ci0vLyAgICB9Ci0vLyAgICBlbHNlIGlmIChEb3VibGUuaXNJbmZpbml0ZShtX3ZhbCkpCi0vLyAgICB7Ci0vLyAgICAgIGlmIChtX3ZhbCA+IDApCi0vLyAgICAgICAgcmV0dXJuICJJbmZpbml0eSI7Ci0vLyAgICAgIGVsc2UKLS8vICAgICAgICByZXR1cm4gIi1JbmZpbml0eSI7Ci0vLyAgICB9Ci0vLwotLy8gICAgbG9uZyBsb25nVmFsID0gKGxvbmcpbV92YWw7Ci0vLyAgICBpZiAoKGRvdWJsZSlsb25nVmFsID09IG1fdmFsKQotLy8gICAgICByZXR1cm4gTG9uZy50b1N0cmluZyhsb25nVmFsKTsKLS8vCi0vLwotLy8gICAgU3RyaW5nIHMgPSBEb3VibGUudG9TdHJpbmcobV92YWwpOwotLy8gICAgaW50IGxlbiA9IHMubGVuZ3RoKCk7Ci0vLwotLy8gICAgaWYgKHMuY2hhckF0KGxlbiAtIDIpID09ICcuJyAmJiBzLmNoYXJBdChsZW4gLSAxKSA9PSAnMCcpCi0vLyAgICB7Ci0vLyAgICAgIHJldHVybiBzLnN1YnN0cmluZygwLCBsZW4gLSAyKTsKLS8vICAgIH0KLS8vCi0vLyAgICBpbnQgZXhwID0gMDsKLS8vICAgIGludCBlID0gcy5pbmRleE9mKCdFJyk7Ci0vLyAgICBpZiAoZSAhPSAtMSkKLS8vICAgIHsKLS8vICAgICAgZXhwID0gSW50ZWdlci5wYXJzZUludChzLnN1YnN0cmluZyhlICsgMSkpOwotLy8gICAgICBzID0gcy5zdWJzdHJpbmcoMCxlKTsKLS8vICAgICAgbGVuID0gZTsKLS8vICAgIH0KLS8vCi0vLyAgICAvLyBDYWxjdWxhdGUgU2lnbmlmaWNhbnQgRGlnaXRzOgotLy8gICAgLy8gbG9vayBmcm9tIHN0YXJ0IG9mIHN0cmluZyBmb3IgZmlyc3QgZGlnaXQKLS8vICAgIC8vIGxvb2sgZnJvbSBlbmQgZm9yIGxhc3QgZGlnaXQKLS8vICAgIC8vIHNpZ25pZmljYW50IGRpZ2l0cyA9IGVuZCAtIHN0YXJ0ICsgKDAgb3IgMSBkZXBlbmRpbmcgb24gZGVjaW1hbCBsb2NhdGlvbikKLS8vCi0vLyAgICBpbnQgZGVjaW1hbFBvcyA9IC0xOwotLy8gICAgaW50IHN0YXJ0ID0gKHMuY2hhckF0KDApID09ICctJykgPyAxIDogMDsKLS8vICAgIGZpbmRTdGFydDogZm9yKCA7IHN0YXJ0IDwgbGVuOyBzdGFydCsrICkKLS8vICAgIHsKLS8vICAgICAgc3dpdGNoIChzLmNoYXJBdChzdGFydCkpCi0vLyAgICAgIHsKLS8vICAgICAgY2FzZSAnMCc6Ci0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGNhc2UgJy4nOgotLy8gICAgICAgIGRlY2ltYWxQb3MgPSBzdGFydDsKLS8vICAgICAgICBicmVhazsKLS8vICAgICAgZGVmYXVsdDoKLS8vICAgICAgICBicmVhayBmaW5kU3RhcnQ7Ci0vLyAgICAgIH0KLS8vICAgIH0KLS8vICAgIGludCBlbmQgPSBzLmxlbmd0aCgpIC0gMTsKLS8vICAgIGZpbmRFbmQ6IGZvciggOyBlbmQgPiBzdGFydDsgZW5kLS0gKQotLy8gICAgewotLy8gICAgICBzd2l0Y2ggKHMuY2hhckF0KGVuZCkpCi0vLyAgICAgIHsKLS8vICAgICAgY2FzZSAnMCc6Ci0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGNhc2UgJy4nOgotLy8gICAgICAgIGRlY2ltYWxQb3MgPSBlbmQ7Ci0vLyAgICAgICAgYnJlYWs7Ci0vLyAgICAgIGRlZmF1bHQ6Ci0vLyAgICAgICAgYnJlYWsgZmluZEVuZDsKLS8vICAgICAgfQotLy8gICAgfQotLy8KLS8vICAgIGludCBzaWdEaWcgPSBlbmQgLSBzdGFydDsKLS8vCi0vLyAgICAvLyBjbGFyaWZ5IGRlY2ltYWwgbG9jYXRpb24gaWYgaXQgaGFzIG5vdCB5ZXQgYmVlbiBmb3VuZAotLy8gICAgaWYgKGRlY2ltYWxQb3MgPT0gLTEpCi0vLyAgICAgIGRlY2ltYWxQb3MgPSBzLmluZGV4T2YoJy4nKTsKLS8vCi0vLyAgICAvLyBpZiBkZWNpbWFsIGlzIG5vdCBiZXR3ZWVuIHN0YXJ0IGFuZCBlbmQsIGFkZCBvbmUgdG8gc2lnRGlnCi0vLyAgICBpZiAoZGVjaW1hbFBvcyA8IHN0YXJ0IHx8IGRlY2ltYWxQb3MgPiBlbmQpCi0vLyAgICAgICsrc2lnRGlnOwotLy8KLS8vICAgIC8vIHJlZHVjZSBzaWduaWZpY2FudCBkaWdpdHMgdG8gUFJFQ0lTSU9OIGlmIG5lY2Vzc2FyeQotLy8gICAgaWYgKHNpZ0RpZyA+IFBSRUNJU0lPTikKLS8vICAgIHsKLS8vICAgICAgLy8gcmUtc2NhbGUgQmlnRGVjaW1hbCBpbiBvcmRlciB0byBnZXQgc2lnbmlmaWNhbnQgZGlnaXRzID0gUFJFQ0lTSU9OCi0vLyAgICAgIEJpZ0RlY2ltYWwgbnVtID0gbmV3IEJpZ0RlY2ltYWwocyk7Ci0vLyAgICAgIGludCBuZXdTY2FsZSA9IG51bS5zY2FsZSgpIC0gKHNpZ0RpZyAtIFBSRUNJU0lPTik7Ci0vLyAgICAgIGlmIChuZXdTY2FsZSA8IDApCi0vLyAgICAgICAgbmV3U2NhbGUgPSAwOwotLy8gICAgICBzID0gbnVtLnNldFNjYWxlKG5ld1NjYWxlLCBCaWdEZWNpbWFsLlJPVU5EX0hBTEZfVVApLnRvU3RyaW5nKCk7Ci0vLwotLy8gICAgICAvLyByZW1vdmUgdHJhaWxpbmcgJzAnczsga2VlcCB0cmFjayBvZiBkZWNpbWFsUG9zCi0vLyAgICAgIGludCB0cnVuY2F0ZVBvaW50ID0gcy5sZW5ndGgoKTsKLS8vICAgICAgd2hpbGUgKHMuY2hhckF0KC0tdHJ1bmNhdGVQb2ludCkgPT0gJzAnKQotLy8gICAgICAgIDsKLS8vCi0vLyAgICAgIGlmIChzLmNoYXJBdCh0cnVuY2F0ZVBvaW50KSA9PSAnLicpCi0vLyAgICAgIHsKLS8vICAgICAgICBkZWNpbWFsUG9zID0gdHJ1bmNhdGVQb2ludDsKLS8vICAgICAgfQotLy8gICAgICBlbHNlCi0vLyAgICAgIHsKLS8vICAgICAgICBkZWNpbWFsUG9zID0gcy5pbmRleE9mKCcuJyk7Ci0vLyAgICAgICAgdHJ1bmNhdGVQb2ludCArPSAxOwotLy8gICAgICB9Ci0vLwotLy8gICAgICBzID0gcy5zdWJzdHJpbmcoMCwgdHJ1bmNhdGVQb2ludCk7Ci0vLyAgICAgIGxlbiA9IHMubGVuZ3RoKCk7Ci0vLyAgICB9Ci0vLwotLy8gICAgLy8gQWNjb3VudCBmb3IgZXhwb25lbnQgYnkgYWRkaW5nIHplcm9zIGFzIG5lZWRlZCAKLS8vICAgIC8vIGFuZCBtb3ZpbmcgdGhlIGRlY2ltYWwgcGxhY2UKLS8vCi0vLyAgICBpZiAoZXhwID09IDApCi0vLyAgICAgICByZXR1cm4gczsKLS8vCi0vLyAgICBzdGFydCA9IDA7Ci0vLyAgICBTdHJpbmcgc2lnbjsKLS8vICAgIGlmIChzLmNoYXJBdCgwKSA9PSAnLScpCi0vLyAgICB7Ci0vLyAgICAgIHNpZ24gPSAiLSI7Ci0vLyAgICAgIHN0YXJ0Kys7Ci0vLyAgICB9Ci0vLyAgICBlbHNlCi0vLyAgICAgIHNpZ24gPSAiIjsKLS8vCi0vLyAgICBTdHJpbmcgd2hvbGVQYXJ0ID0gcy5zdWJzdHJpbmcoc3RhcnQsIGRlY2ltYWxQb3MpOwotLy8gICAgU3RyaW5nIGRlY2ltYWxQYXJ0ID0gcy5zdWJzdHJpbmcoZGVjaW1hbFBvcyArIDEpOwotLy8KLS8vICAgIC8vIGdldCB0aGUgbnVtYmVyIG9mIGRpZ2l0cyByaWdodCBvZiB0aGUgZGVjaW1hbAotLy8gICAgaW50IGRlY2ltYWxMZW4gPSBkZWNpbWFsUGFydC5sZW5ndGgoKTsKLS8vCi0vLyAgICBpZiAoZXhwID49IGRlY2ltYWxMZW4pCi0vLyAgICAgIHJldHVybiBzaWduICsgd2hvbGVQYXJ0ICsgZGVjaW1hbFBhcnQgKyB6ZXJvcyhleHAgLSBkZWNpbWFsTGVuKTsKLS8vCi0vLyAgICBpZiAoZXhwID4gMCkKLS8vICAgICAgcmV0dXJuIHNpZ24gKyB3aG9sZVBhcnQgKyBkZWNpbWFsUGFydC5zdWJzdHJpbmcoMCwgZXhwKSArICIuIgotLy8gICAgICAgICAgICAgKyBkZWNpbWFsUGFydC5zdWJzdHJpbmcoZXhwKTsKLS8vCi0vLyAgICByZXR1cm4gc2lnbiArICIwLiIgKyB6ZXJvcygtMSAtIGV4cCkgKyB3aG9sZVBhcnQgKyBkZWNpbWFsUGFydDsKLS8vICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiAiTmFOIiBpZiB0aGUgbnVtYmVyIGlzIE5hTiwgSW5maW5pdHkgb3IgLUluZmluaXR5IGlmCi0gICAqIHRoZSBudW1iZXIgaXMgaW5maW5pdGUgb3IgdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbnVtYmVyLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0KLSAgICBpZiAoRG91YmxlLmlzTmFOKG1fdmFsKSkKLSAgICB7Ci0gICAgICByZXR1cm4gIk5hTiI7Ci0gICAgfQotICAgIGVsc2UgaWYgKERvdWJsZS5pc0luZmluaXRlKG1fdmFsKSkKLSAgICB7Ci0gICAgICBpZiAobV92YWwgPiAwKQotICAgICAgICByZXR1cm4gIkluZmluaXR5IjsKLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuICItSW5maW5pdHkiOwotICAgIH0KLQotICAgIGRvdWJsZSBudW0gPSBtX3ZhbDsKLSAgICBTdHJpbmcgcyA9IERvdWJsZS50b1N0cmluZyhudW0pOwotICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOwotCi0gICAgaWYgKHMuY2hhckF0KGxlbiAtIDIpID09ICcuJyAmJiBzLmNoYXJBdChsZW4gLSAxKSA9PSAnMCcpCi0gICAgewotICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIGxlbiAtIDIpOwotCi0gICAgICBpZiAocy5lcXVhbHMoIi0wIikpCi0gICAgICAgIHJldHVybiAiMCI7Ci0KLSAgICAgIHJldHVybiBzOwotICAgIH0KLQotICAgIGludCBlID0gcy5pbmRleE9mKCdFJyk7Ci0KLSAgICBpZiAoZSA8IDApCi0gICAgICByZXR1cm4gczsKLQotICAgIGludCBleHAgPSBJbnRlZ2VyLnBhcnNlSW50KHMuc3Vic3RyaW5nKGUgKyAxKSk7Ci0gICAgU3RyaW5nIHNpZ247Ci0KLSAgICBpZiAocy5jaGFyQXQoMCkgPT0gJy0nKQotICAgIHsKLSAgICAgIHNpZ24gPSAiLSI7Ci0gICAgICBzID0gcy5zdWJzdHJpbmcoMSk7Ci0KLSAgICAgIC0tZTsKLSAgICB9Ci0gICAgZWxzZQotICAgICAgc2lnbiA9ICIiOwotCi0gICAgaW50IG5EaWdpdHMgPSBlIC0gMjsKLQotICAgIGlmIChleHAgPj0gbkRpZ2l0cykKLSAgICAgIHJldHVybiBzaWduICsgcy5zdWJzdHJpbmcoMCwgMSkgKyBzLnN1YnN0cmluZygyLCBlKQotICAgICAgICAgICAgICsgemVyb3MoZXhwIC0gbkRpZ2l0cyk7Ci0KLSAgICBpZiAoZXhwID4gMCkKLSAgICAgIHJldHVybiBzaWduICsgcy5zdWJzdHJpbmcoMCwgMSkgKyBzLnN1YnN0cmluZygyLCAyICsgZXhwKSArICIuIgotICAgICAgICAgICAgICsgcy5zdWJzdHJpbmcoMiArIGV4cCwgZSk7Ci0KLSAgICByZXR1cm4gc2lnbiArICIwLiIgKyB6ZXJvcygtMSAtIGV4cCkgKyBzLnN1YnN0cmluZygwLCAxKQotICAgICAgICAgICArIHMuc3Vic3RyaW5nKDIsIGUpOwotICB9Ci0KLQotICAvKioKLSAgICogUmV0dXJuIGEgc3RyaW5nIG9mICcwJyBvZiB0aGUgZ2l2ZW4gbGVuZ3RoCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBuIExlbmd0aCBvZiB0aGUgc3RyaW5nIHRvIGJlIHJldHVybmVkCi0gICAqCi0gICAqIEByZXR1cm4gYSBzdHJpbmcgb2YgJzAnIHdpdGggdGhlIGdpdmVuIGxlbmd0aAotICAgKi8KLSAgc3RhdGljIHByaXZhdGUgU3RyaW5nIHplcm9zKGludCBuKQotICB7Ci0gICAgaWYgKG4gPCAxKQotICAgICAgcmV0dXJuICIiOwotCi0gICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyW25dOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgYnVmW2ldID0gJzAnOwotICAgIH0KLQotICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1Zik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJuIGEgamF2YSBvYmplY3QgdGhhdCdzIGNsb3Nlc3QgdG8gdGhlIHJlcHJlc2VudGF0aW9uCi0gICAqIHRoYXQgc2hvdWxkIGJlIGhhbmRlZCB0byBhbiBleHRlbnNpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoaXMgWE51bWJlciBhcyBhIERvdWJsZSBvYmplY3QKLSAgICovCi0gIHB1YmxpYyBPYmplY3Qgb2JqZWN0KCkKLSAgewotICAgIGlmKG51bGwgPT0gbV9vYmopCi0gICAgICBtX29iaiA9IG5ldyBEb3VibGUobV92YWwpOwotICAgIHJldHVybiBtX29iajsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIE9iamVjdCB0byBjb21wYXJlIHRoaXMgdG8KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0d28gb2JqZWN0cyBhcmUgZXF1YWwgCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YgCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlIAotICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uCi0gICAgaWYgKG9iajIuZ2V0VHlwZSgpID09IFhPYmplY3QuQ0xBU1NfTk9ERVNFVCkKLSAgICAgIHJldHVybiBvYmoyLmVxdWFscyh0aGlzKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHJldHVybiBtX3ZhbCA9PSBvYmoyLm51bSgpOwotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gcmV0dXJucyBhIHN0YWJsZSBudW1iZXIgdGhhdCB3aWxsIG5vdCBjaGFuZ2UgZHVyaW5nIAotICAgKiBpdGVyYXRpb25zIHdpdGhpbiB0aGUgZXhwcmVzc2lvbi4gIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBwcm94aW1pdHkgCi0gICAqIHBvc2l0aW9uIHByZWRpY2F0ZSBjYW4gaW5kaWNhdGUgdGhhdCBubyBtb3JlIHNlYXJjaGluZyBoYXMgdG8gb2NjdXIuCi0gICAqIAotICAgKgotICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGV4cHJlc3Npb24gcmVwcmVzZW50cyBhIHN0YWJsZSBudW1iZXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBpc1N0YWJsZU51bWJlcigpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hPYmplY3QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE9iamVjdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxM2E0MmI2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE9iamVjdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzQyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotaW1wb3J0IG9yZy53M2MuZG9tLkRvY3VtZW50RnJhZ21lbnQ7Ci0vL2ltcG9ydCBvcmcudzNjLmRvbS5UZXh0OwotLy9pbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLWltcG9ydCBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotCi1pbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBYUGF0aCBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBvYmplY3QgdG8gdmFyaW91cyB0eXBlcywgc3VjaCBhcyBhIHN0cmluZy4KLSAqIFRoaXMgY2xhc3MgYWN0cyBhcyB0aGUgYmFzZSBjbGFzcyB0byBvdGhlciBYUGF0aCB0eXBlIG9iamVjdHMsCi0gKiBzdWNoIGFzIFhTdHJpbmcsIGFuZCBwcm92aWRlcyBwb2x5bW9ycGhpYyBjYXN0aW5nIGNhcGFiaWxpdGllcy4KLSAqLwotcHVibGljIGNsYXNzIFhPYmplY3QgZXh0ZW5kcyBFeHByZXNzaW9uIGltcGxlbWVudHMgU2VyaWFsaXphYmxlLCBDbG9uZWFibGUKLXsKLQotICAvKioKLSAgICogVGhlIGphdmEgb2JqZWN0IHdoaWNoIHRoaXMgb2JqZWN0IHdyYXBzLgotICAgKiAgQHNlcmlhbCAgCi0gICAqLwotICBwcm90ZWN0ZWQgT2JqZWN0IG1fb2JqOyAgLy8gVGhpcyBtYXkgYmUgTlVMTCEhIQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0KCl7fQotCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWE9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIG9iaiBDYW4gYmUgYW55IG9iamVjdCwgc2hvdWxkIGJlIGEgc3BlY2lmaWMgdHlwZQotICAgKiBmb3IgZGVyaXZlZCBjbGFzc2VzLCBvciBudWxsLgotICAgKi8KLSAgcHVibGljIFhPYmplY3QoT2JqZWN0IG9iaikKLSAgewotICAgIG1fb2JqID0gb2JqOwotICB9Ci0KLSAgLyoqCi0gICAqIEZvciBzdXBwb3J0IG9mIGxpdGVyYWwgb2JqZWN0cyBpbiB4cGF0aHMuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFNwZWNpZnkgaWYgaXQncyBPSyBmb3IgZGV0YWNoIHRvIHJlbGVhc2UgdGhlIGl0ZXJhdG9yIGZvciByZXVzZS4KLSAgICoKLSAgICogQHBhcmFtIGFsbG93UmVsZWFzZSB0cnVlIGlmIGl0IGlzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGlzIGl0ZXJhdG9yCi0gICAqIGZvciBwb29saW5nLgotICAgKi8KLSAgcHVibGljIHZvaWQgYWxsb3dEZXRhY2hUb1JlbGVhc2UoYm9vbGVhbiBhbGxvd1JlbGVhc2Upe30KLQotICAvKioKLSAgICogRGV0YWNoZXMgdGhlIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQKLSAgICogb3ZlciwgcmVsZWFzaW5nIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IKLSAgICogaW4gdGhlIElOVkFMSUQgc3RhdGUuIEFmdGVyIDxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwKLSAgICogY2FsbHMgdG8gPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yIDxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbAotICAgKiByYWlzZSBhIHJ1bnRpbWUgZXhjZXB0aW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgZGV0YWNoKCl7fQotCi0gIC8qKgotICAgKiBGb3JjZXMgdGhlIG9iamVjdCB0byByZWxlYXNlIGl0J3MgcmVzb3VyY2VzLiAgVGhpcyBpcyBtb3JlIGhhcnNoIHRoYW4KLSAgICogZGV0YWNoKCkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXN0cnVjdCgpCi0gIHsKLQotICAgIGlmIChudWxsICE9IG1fb2JqKQotICAgIHsKLSAgICAgIGFsbG93RGV0YWNoVG9SZWxlYXNlKHRydWUpOwotICAgICAgZGV0YWNoKCk7Ci0KLSAgICAgIG1fb2JqID0gbnVsbDsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY2hhcmFjdGVycyBtZXRob2Qgb24gdGhlIHBhc3NlZCBDb250ZW50SGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAqIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICB4c3RyKCkuZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKGNoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDcmVhdGUgdGhlIHJpZ2h0IFhPYmplY3QgYmFzZWQgb24gdGhlIHR5cGUgb2YgdGhlIG9iamVjdCBwYXNzZWQuICBUaGlzIAotICAgKiBmdW5jdGlvbiBjYW4gbm90IG1ha2UgYW4gWE9iamVjdCB0aGF0IGV4cG9zZXMgRE9NIE5vZGVzLCBOb2RlTGlzdHMsIGFuZCAKLSAgICogTm9kZUl0ZXJhdG9ycyB0byB0aGUgWFNMVCBzdHlsZXNoZWV0IGFzIG5vZGUtc2V0cy4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBUaGUgamF2YSBvYmplY3Qgd2hpY2ggdGhpcyBvYmplY3Qgd2lsbCB3cmFwLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLgotICAgKi8KLSAgc3RhdGljIHB1YmxpYyBYT2JqZWN0IGNyZWF0ZShPYmplY3QgdmFsKQotICB7Ci0gICAgcmV0dXJuIFhPYmplY3RGYWN0b3J5LmNyZWF0ZSh2YWwpOwotICB9Ci0gIAotICAvKioKLSAgICogQ3JlYXRlIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLgotICAgKiBUaGlzIGZ1bmN0aW9uIDxlbXBoPmNhbjwvZW1waD4gbWFrZSBhbiBYT2JqZWN0IHRoYXQgZXhwb3NlcyBET00gTm9kZXMsIE5vZGVMaXN0cywgYW5kIAotICAgKiBOb2RlSXRlcmF0b3JzIHRvIHRoZSBYU0xUIHN0eWxlc2hlZXQgYXMgbm9kZS1zZXRzLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSBqYXZhIG9iamVjdCB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHdyYXAuCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcmlnaHQgWE9iamVjdCBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHBhc3NlZC4KLSAgICovCi0gIHN0YXRpYyBwdWJsaWMgWE9iamVjdCBjcmVhdGUoT2JqZWN0IHZhbCwgWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgcmV0dXJuIFhPYmplY3RGYWN0b3J5LmNyZWF0ZSh2YWwsIHhjdHh0KTsKLSAgfQotCi0gIC8qKiBDb25zdGFudCBmb3IgTlVMTCBvYmplY3QgdHlwZSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19OVUxMID0gLTE7Ci0KLSAgLyoqIENvbnN0YW50IGZvciBVTktOT1dOIG9iamVjdCB0eXBlICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX1VOS05PV04gPSAwOwotCi0gIC8qKiBDb25zdGFudCBmb3IgQk9PTEVBTiAgb2JqZWN0IHR5cGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfQk9PTEVBTiA9IDE7Ci0KLSAgLyoqIENvbnN0YW50IGZvciBOVU1CRVIgb2JqZWN0IHR5cGUgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0xBU1NfTlVNQkVSID0gMjsKLQotICAvKiogQ29uc3RhbnQgZm9yIFNUUklORyBvYmplY3QgdHlwZSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19TVFJJTkcgPSAzOwotCi0gIC8qKiBDb25zdGFudCBmb3IgTk9ERVNFVCBvYmplY3QgdHlwZSAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19OT0RFU0VUID0gNDsKLQotICAvKiogQ29uc3RhbnQgZm9yIFJFU1VMVCBUUkVFIEZSQUdNRU5UIG9iamVjdCB0eXBlICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX1JUUkVFRlJBRyA9IDU7Ci0KLSAgLyoqIFJlcHJlc2VudHMgYW4gdW5yZXNvbHZlZCB2YXJpYWJsZSB0eXBlIGFzIGFuIGludGVnZXIuICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTX1VOUkVTT0xWRURWQVJJQUJMRSA9IDYwMDsKLQotICAvKioKLSAgICogVGVsbCB3aGF0IGtpbmQgb2YgY2xhc3MgdGhpcyBpcy4KLSAgICoKLSAgICogQHJldHVybiBDTEFTU19VTktOT1dOCi0gICAqLwotICBwdWJsaWMgaW50IGdldFR5cGUoKQotICB7Ci0gICAgcmV0dXJuIENMQVNTX1VOS05PV047Ci0gIH0KLQotICAvKioKLSAgICogR2l2ZW4gYSByZXF1ZXN0IHR5cGUsIHJldHVybiB0aGUgZXF1aXZhbGVudCBzdHJpbmcuCi0gICAqIEZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKiBAcmV0dXJuIHR5cGUgc3RyaW5nICIjVU5LTk9XTiIgKyBvYmplY3QgY2xhc3MgbmFtZQotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUeXBlU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAiI1VOS05PV04gKCIgKyBvYmplY3QoKS5nZXRDbGFzcygpLmdldE5hbWUoKSArICIpIjsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBudW1iZXIuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gMC4wCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBnZXRUeXBlU3RyaW5nKCkgfSk7ICAvLyJDYW4gbm90IGNvbnZlcnQgIitnZXRUeXBlU3RyaW5nKCkrIiB0byBhIG51bWJlciIpOwotCi0gICAgcmV0dXJuIDAuMDsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlciwgYnV0IGFsbG93IHNpZGUgZWZmZWN0cywgc3VjaCBhcyB0aGUgCi0gICAqIGluY3JlbWVudGluZyBvZiBhbiBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBudW1lcmljIHZhbHVlIG9mIHRoZSBzdHJpbmcgY29udmVyc2lvbiBmcm9tIHRoZSAKLSAgICogbmV4dCBub2RlIGluIHRoZSBOb2RlU2V0RFRNLCBvciBOQU4gaWYgbm8gbm9kZSB3YXMgZm91bmQKLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtV2l0aFNpZGVFZmZlY3RzKCkgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbnVtKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbi4gQWx3YXlzIGlzc3VlcyBhbiBlcnJvci4KLSAgICoKLSAgICogQHJldHVybiBmYWxzZQotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBlcnJvcihYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NBTlRfQ09OVkVSVF9UT19OVU1CRVIsCi0gICAgICAgICAgbmV3IE9iamVjdFtdeyBnZXRUeXBlU3RyaW5nKCkgfSk7ICAvLyJDYW4gbm90IGNvbnZlcnQgIitnZXRUeXBlU3RyaW5nKCkrIiB0byBhIG51bWJlciIpOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgYm9vbGVhbiwgYnV0IGFsbG93IHNpZGUgZWZmZWN0cywgc3VjaCBhcyB0aGUgCi0gICAqIGluY3JlbWVudGluZyBvZiBhbiBpdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoZXJlIGlzIGEgbmV4dCBub2RlIGluIHRoZSBub2Rlc2V0Ci0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sV2l0aFNpZGVFZmZlY3RzKCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBib29sKCk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKCkKLSAgewotICAgIHJldHVybiBYTUxTdHJpbmdGYWN0b3J5SW1wbC5nZXRGYWN0b3J5KCkubmV3c3RyKHN0cigpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCBhcyBhIHN0cmluZwotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgcmV0dXJuIChtX29iaiAhPSBudWxsKSA/IG1fb2JqLnRvU3RyaW5nKCkgOiAiIjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgb2JqZWN0Ci0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgb2JqZWN0Ci0gICAqLwotICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKLSAgewotICAgIHJldHVybiBzdHIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICoKLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIG9iamVjIGFzIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCi0gICAqLwotICBwdWJsaWMgaW50IHJ0ZihYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgaW50IHJlc3VsdCA9IHJ0ZigpOwotCi0gICAgaWYgKERUTS5OVUxMID09IHJlc3VsdCkKLSAgICB7Ci0gICAgICBEVE0gZnJhZyA9IHN1cHBvcnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOwotCi0gICAgICAvLyAlT1BUJQotICAgICAgZnJhZy5hcHBlbmRUZXh0Q2hpbGQoc3RyKCkpOwotCi0gICAgICByZXN1bHQgPSBmcmFnLmdldERvY3VtZW50KCk7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBYUGF0aCBjb250ZXh0IHRvIHVzZSBmb3IgdGhlIGNvbnZlcnNpb24KLSAgICoKLSAgICogQHJldHVybiB0aGUgb2JqZWMgYXMgYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICovCi0gIHB1YmxpYyBEb2N1bWVudEZyYWdtZW50IHJ0cmVlKFhQYXRoQ29udGV4dCBzdXBwb3J0KQotICB7Ci0gICAgRG9jdW1lbnRGcmFnbWVudCBkb2NGcmFnID0gbnVsbDsKLSAgICBpbnQgcmVzdWx0ID0gcnRmKCk7Ci0KLSAgICBpZiAoRFRNLk5VTEwgPT0gcmVzdWx0KQotICAgIHsKLSAgICAgIERUTSBmcmFnID0gc3VwcG9ydC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7Ci0KLSAgICAgIC8vICVPUFQlCi0gICAgICBmcmFnLmFwcGVuZFRleHRDaGlsZChzdHIoKSk7Ci0KLSAgICAgIGRvY0ZyYWcgPSAoRG9jdW1lbnRGcmFnbWVudClmcmFnLmdldE5vZGUoZnJhZy5nZXREb2N1bWVudCgpKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIERUTSBmcmFnID0gc3VwcG9ydC5nZXREVE0ocmVzdWx0KTsKLSAgICAgIGRvY0ZyYWcgPSAoRG9jdW1lbnRGcmFnbWVudClmcmFnLmdldE5vZGUoZnJhZy5nZXREb2N1bWVudCgpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZG9jRnJhZzsKLSAgfQotICAKLSAgCi0gIAotICAvKioKLSAgICogRm9yIGZ1bmN0aW9ucyB0byBvdmVycmlkZS4KLSAgICoKLSAgICogQHJldHVybiBudWxsCi0gICAqLwotICBwdWJsaWMgRG9jdW1lbnRGcmFnbWVudCBydHJlZSgpCi0gIHsKLSAgICByZXR1cm4gbnVsbDsKLSAgfQotCi0gIC8qKgotICAgKiBGb3IgZnVuY3Rpb25zIHRvIG92ZXJyaWRlLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICovCi0gIHB1YmxpYyBpbnQgcnRmKCkKLSAgewotICAgIHJldHVybiBEVE0uTlVMTDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBqYXZhIG9iamVjdCB0aGF0J3MgY2xvc2VzdCB0byB0aGUgcmVwcmVzZW50YXRpb24KLSAgICogdGhhdCBzaG91bGQgYmUgaGFuZGVkIHRvIGFuIGV4dGVuc2lvbi4KLSAgICoKLSAgICogQHJldHVybiBUaGUgb2JqZWN0IHRoYXQgdGhpcyBjbGFzcyB3cmFwcwotICAgKi8KLSAgcHVibGljIE9iamVjdCBvYmplY3QoKQotICB7Ci0gICAgcmV0dXJuIG1fb2JqOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG5vZGVsaXN0LiBBbHdheXMgaXNzdWVzIGFuIGVycm9yLgotICAgKgotICAgKiBAcmV0dXJuIG51bGwKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgaXRlcigpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSBOb2RlTGlzdCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlSXRlcmF0b3Igbm9kZXNldCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSBOb2RlTGlzdCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gbnVsbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBOb2RlTGlzdCBub2RlbGlzdCgpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNULAotICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSBOb2RlTGlzdCEiKTsKLQotICAgIHJldHVybiBudWxsOwotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbm9kZWxpc3QuIEFsd2F5cyBpc3N1ZXMgYW4gZXJyb3IuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCBhcyBhIE5vZGVTZXREVE0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIE5vZGVTZXREVE0gbXV0YWJsZU5vZGVzZXQoKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGVycm9yKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCwKLSAgICAgICAgICBuZXcgT2JqZWN0W117IGdldFR5cGVTdHJpbmcoKSB9KTsgIC8vIkNhbiBub3QgY29udmVydCAiK2dldFR5cGVTdHJpbmcoKSsiIHRvIGEgTm9kZVNldERUTSEiKTsKLQotICAgIHJldHVybiAoTm9kZVNldERUTSkgbV9vYmo7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCBvYmplY3QgdG8gdHlwZSB0LgotICAgKgotICAgKiBAcGFyYW0gdCBUeXBlIG9mIG9iamVjdCB0byBjYXN0IHRoaXMgdG8KLSAgICogQHBhcmFtIHN1cHBvcnQgWFBhdGggY29udGV4dCB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCi0gICAqCi0gICAqIEByZXR1cm4gVGhpcyBvYmplY3QgYXMgdGhlIGdpdmVuIHR5cGUgdAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBPYmplY3QgY2FzdFRvVHlwZShpbnQgdCwgWFBhdGhDb250ZXh0IHN1cHBvcnQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgT2JqZWN0IHJlc3VsdDsKLQotICAgIHN3aXRjaCAodCkKLSAgICB7Ci0gICAgY2FzZSBDTEFTU19TVFJJTkcgOgotICAgICAgcmVzdWx0ID0gc3RyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIENMQVNTX05VTUJFUiA6Ci0gICAgICByZXN1bHQgPSBuZXcgRG91YmxlKG51bSgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQ0xBU1NfTk9ERVNFVCA6Ci0gICAgICByZXN1bHQgPSBpdGVyKCk7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIENMQVNTX0JPT0xFQU4gOgotICAgICAgcmVzdWx0ID0gbmV3IEJvb2xlYW4oYm9vbCgpKTsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgQ0xBU1NfVU5LTk9XTiA6Ci0gICAgICByZXN1bHQgPSBtX29iajsKLSAgICAgIGJyZWFrOwotCi0gICAgLy8gJVRCRCUgIFdoYXQgdG8gZG8gaGVyZT8KLSAgICAvLyAgICBjYXNlIENMQVNTX1JUUkVFRlJBRyA6Ci0gICAgLy8gICAgICByZXN1bHQgPSBydHJlZShzdXBwb3J0KTsKLSAgICAvLyAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgZXJyb3IoWFBBVEhFcnJvclJlc291cmNlcy5FUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSwKLSAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZ2V0VHlwZVN0cmluZygpLAotICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKHQpIH0pOyAgLy8iQ2FuIG5vdCBjb252ZXJ0ICIrZ2V0VHlwZVN0cmluZygpKyIgdG8gYSB0eXBlIyIrdCk7Ci0KLSAgICAgIHJlc3VsdCA9IG51bGw7Ci0gICAgfQotCi0gICAgcmV0dXJuIHJlc3VsdDsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgbGVzcyB0aGFuIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbihYT2JqZWN0IG9iajIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YgCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlIAotICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uICBCZWNhdXNlIHRoZSBhcmd1bWVudHMgCi0gICAgLy8gYXJlIGJhY2t3YXJkcywgd2UgY2FsbCB0aGUgb3Bwb3NpdGUgY29tcGFyaXNvbgotICAgIC8vIGZ1bmN0aW9uLgotICAgIGlmIChvYmoyLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX05PREVTRVQpCi0gICAgICByZXR1cm4gb2JqMi5ncmVhdGVyVGhhbih0aGlzKTsKLQotICAgIHJldHVybiB0aGlzLm51bSgpIDwgb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBsZXNzVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mIAotICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZSAKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLiAgQmVjYXVzZSB0aGUgYXJndW1lbnRzIAotICAgIC8vIGFyZSBiYWNrd2FyZHMsIHdlIGNhbGwgdGhlIG9wcG9zaXRlIGNvbXBhcmlzb24KLSAgICAvLyBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIuZ3JlYXRlclRoYW5PckVxdWFsKHRoaXMpOwotCi0gICAgcmV0dXJuIHRoaXMubnVtKCkgPD0gb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBncmVhdGVyVGhhbihYT2JqZWN0IG9iajIpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YgCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlIAotICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uICBCZWNhdXNlIHRoZSBhcmd1bWVudHMgCi0gICAgLy8gYXJlIGJhY2t3YXJkcywgd2UgY2FsbCB0aGUgb3Bwb3NpdGUgY29tcGFyaXNvbgotICAgIC8vIGZ1bmN0aW9uLgotICAgIGlmIChvYmoyLmdldFR5cGUoKSA9PSBYT2JqZWN0LkNMQVNTX05PREVTRVQpCi0gICAgICByZXR1cm4gb2JqMi5sZXNzVGhhbih0aGlzKTsKLQotICAgIHJldHVybiB0aGlzLm51bSgpID4gb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIG9uZSBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBvdGhlci4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhpcyBvYmplY3QgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBncmVhdGVyVGhhbk9yRXF1YWwoWE9iamVjdCBvYmoyKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIC8vIEluIG9yZGVyIHRvIGhhbmRsZSB0aGUgJ2FsbCcgc2VtYW50aWNzIG9mIAotICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZSAKLSAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLiAgQmVjYXVzZSB0aGUgYXJndW1lbnRzIAotICAgIC8vIGFyZSBiYWNrd2FyZHMsIHdlIGNhbGwgdGhlIG9wcG9zaXRlIGNvbXBhcmlzb24KLSAgICAvLyBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIubGVzc1RoYW5PckVxdWFsKHRoaXMpOwotCi0gICAgcmV0dXJuIHRoaXMubnVtKCkgPj0gb2JqMi5udW0oKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHR3byBvYmplY3RzIGFyZSBmdW5jdGlvbmFsbHkgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIE9iamVjdCB0byBjb21wYXJlIHRoaXMgdG8KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoaXMgb2JqZWN0IGlzIGVxdWFsIHRvIHRoZSBnaXZlbiBvYmplY3QKLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE9iamVjdCBvYmoyKQotICB7Ci0KLSAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZiAKLSAgICAvLyBub2Rlc2V0IGNvbXBhcmlzb25zLCB3ZSBhbHdheXMgY2FsbCB0aGUgCi0gICAgLy8gbm9kZXNldCBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIuZXF1YWxzKHRoaXMpOwotCi0gICAgaWYgKG51bGwgIT0gbV9vYmopCi0gICAgewotICAgICAgcmV0dXJuIG1fb2JqLmVxdWFscyhvYmoyLm1fb2JqKTsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIHJldHVybiBvYmoyLm1fb2JqID09IG51bGw7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBub3QgZXF1YWwuCi0gICAqCi0gICAqIEBwYXJhbSBvYmoyIE9iamVjdCB0byBjb21wYXJlIHRoaXMgdG8KLSAgICoKLSAgICogQHJldHVybiBUcnVlIGlmIHRoaXMgb2JqZWN0IGlzIG5vdCBlcXVhbCB0byB0aGUgZ2l2ZW4gb2JqZWN0Ci0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gbm90RXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZiAKLSAgICAvLyBub2Rlc2V0IGNvbXBhcmlzb25zLCB3ZSBhbHdheXMgY2FsbCB0aGUgCi0gICAgLy8gbm9kZXNldCBmdW5jdGlvbi4KLSAgICBpZiAob2JqMi5nZXRUeXBlKCkgPT0gWE9iamVjdC5DTEFTU19OT0RFU0VUKQotICAgICAgcmV0dXJuIG9iajIubm90RXF1YWxzKHRoaXMpOwotCi0gICAgcmV0dXJuICFlcXVhbHMob2JqMik7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB0aGUgdXNlciBvZiBhbiBlcnJvciwgYW5kIHByb2JhYmx5IHRocm93IGFuCi0gICAqIGV4Y2VwdGlvbi4KLSAgICoKLSAgICogQHBhcmFtIG1zZyBFcnJvciBtZXNzYWdlIHRvIGlzc3VlCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoaW50IG1zZykKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgZXJyb3IobXNnLCBudWxsKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHRoZSB1c2VyIG9mIGFuIGVycm9yLCBhbmQgcHJvYmFibHkgdGhyb3cgYW4KLSAgICogZXhjZXB0aW9uLgotICAgKgotICAgKiBAcGFyYW0gbXNnIEVycm9yIG1lc3NhZ2UgdG8gaXNzdWUKLSAgICogQHBhcmFtIGFyZ3MgQXJndW1lbnRzIHRvIHVzZSBpbiB0aGUgbWVzc2FnZQotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGVycm9yKGludCBtc2csIE9iamVjdFtdIGFyZ3MpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgU3RyaW5nIGZtc2cgPSBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UobXNnLCBhcmdzKTsKLQotICAgIC8vIGJvb2xlYW4gc2hvdWxkVGhyb3cgPSBzdXBwb3J0LnByb2JsZW0obV9zdXBwb3J0LlhQQVRIUFJPQ0VTU09SLCAKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9zdXBwb3J0LkVSUk9SLAotICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLCAKLSAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgZm1zZywgMCwgMCk7Ci0gICAgLy8gaWYoc2hvdWxkVGhyb3cpCi0gICAgewotICAgICAgdGhyb3cgbmV3IFhQYXRoRXhjZXB0aW9uKGZtc2cpOwotICAgIH0KLSAgfQotICAKLSAgLyoqCi0gICAqIFhPYmplY3RzIHNob3VsZCBub3Qgbm9ybWFsbHkgbmVlZCB0byBmaXggdXAgdmFyaWFibGVzLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLSAgICAvLyBuby1vcAotICB9Ci0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gZnNiCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVG9Gc2Iob3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlciBmc2IpCi0gIHsKLSAgICBmc2IuYXBwZW5kKHN0cigpKTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YT2JqZWN0RmFjdG9yeS5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YT2JqZWN0RmFjdG9yeS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZDg3M2I2Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWE9iamVjdEZhY3RvcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzOSArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguTm9kZVNldERUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLmF4ZXMuT25lU3RlcEl0ZXJhdG9yOwotCi0KLXB1YmxpYyBjbGFzcyBYT2JqZWN0RmFjdG9yeQotewotICAKLSAgLyoqCi0gICAqIENyZWF0ZSB0aGUgcmlnaHQgWE9iamVjdCBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHBhc3NlZC4gIFRoaXMgCi0gICAqIGZ1bmN0aW9uIGNhbiBub3QgbWFrZSBhbiBYT2JqZWN0IHRoYXQgZXhwb3NlcyBET00gTm9kZXMsIE5vZGVMaXN0cywgYW5kIAotICAgKiBOb2RlSXRlcmF0b3JzIHRvIHRoZSBYU0xUIHN0eWxlc2hlZXQgYXMgbm9kZS1zZXRzLgotICAgKgotICAgKiBAcGFyYW0gdmFsIFRoZSBqYXZhIG9iamVjdCB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHdyYXAuCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHJpZ2h0IFhPYmplY3QgYmFzZWQgb24gdGhlIHR5cGUgb2YgdGhlIG9iamVjdCBwYXNzZWQuCi0gICAqLwotICBzdGF0aWMgcHVibGljIFhPYmplY3QgY3JlYXRlKE9iamVjdCB2YWwpCi0gIHsKLQotICAgIFhPYmplY3QgcmVzdWx0OwotCi0gICAgaWYgKHZhbCBpbnN0YW5jZW9mIFhPYmplY3QpCi0gICAgewotICAgICAgcmVzdWx0ID0gKFhPYmplY3QpIHZhbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgU3RyaW5nKQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYU3RyaW5nKChTdHJpbmcpIHZhbCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIEJvb2xlYW4pCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhCb29sZWFuKChCb29sZWFuKXZhbCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIERvdWJsZSkKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWE51bWJlcigoKERvdWJsZSkgdmFsKSk7Ci0gICAgfQotICAgIGVsc2UKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWE9iamVjdCh2YWwpOwotICAgIH0KLQotICAgIHJldHVybiByZXN1bHQ7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDcmVhdGUgdGhlIHJpZ2h0IFhPYmplY3QgYmFzZWQgb24gdGhlIHR5cGUgb2YgdGhlIG9iamVjdCBwYXNzZWQuCi0gICAqIFRoaXMgZnVuY3Rpb24gPGVtcGg+Y2FuPC9lbXBoPiBtYWtlIGFuIFhPYmplY3QgdGhhdCBleHBvc2VzIERPTSBOb2RlcywgTm9kZUxpc3RzLCBhbmQgCi0gICAqIE5vZGVJdGVyYXRvcnMgdG8gdGhlIFhTTFQgc3R5bGVzaGVldCBhcyBub2RlLXNldHMuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgVGhlIGphdmEgb2JqZWN0IHdoaWNoIHRoaXMgb2JqZWN0IHdpbGwgd3JhcC4KLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHRoZSByaWdodCBYT2JqZWN0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgcGFzc2VkLgotICAgKi8KLSAgc3RhdGljIHB1YmxpYyBYT2JqZWN0IGNyZWF0ZShPYmplY3QgdmFsLCBYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLQotICAgIFhPYmplY3QgcmVzdWx0OwotCi0gICAgaWYgKHZhbCBpbnN0YW5jZW9mIFhPYmplY3QpCi0gICAgewotICAgICAgcmVzdWx0ID0gKFhPYmplY3QpIHZhbDsKLSAgICB9Ci0gICAgZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgU3RyaW5nKQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYU3RyaW5nKChTdHJpbmcpIHZhbCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIEJvb2xlYW4pCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhCb29sZWFuKChCb29sZWFuKXZhbCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIE51bWJlcikKLSAgICB7Ci0gICAgICByZXN1bHQgPSBuZXcgWE51bWJlcigoKE51bWJlcikgdmFsKSk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIERUTSkKLSAgICB7Ci0gICAgICBEVE0gZHRtID0gKERUTSl2YWw7Ci0gICAgICB0cnkKLSAgICAgIHsKLSAgICAgICAgaW50IGR0bVJvb3QgPSBkdG0uZ2V0RG9jdW1lbnQoKTsKLSAgICAgICAgRFRNQXhpc0l0ZXJhdG9yIGl0ZXIgPSBkdG0uZ2V0QXhpc0l0ZXJhdG9yKEF4aXMuU0VMRik7Ci0gICAgICAgIGl0ZXIuc2V0U3RhcnROb2RlKGR0bVJvb3QpOwotICAgICAgICBEVE1JdGVyYXRvciBpdGVyYXRvciA9IG5ldyBPbmVTdGVwSXRlcmF0b3IoaXRlciwgQXhpcy5TRUxGKTsKLSAgICAgICAgaXRlcmF0b3Iuc2V0Um9vdChkdG1Sb290LCB4Y3R4dCk7Ci0gICAgICAgIHJlc3VsdCA9IG5ldyBYTm9kZVNldChpdGVyYXRvcik7Ci0gICAgICB9Ci0gICAgICBjYXRjaChFeGNlcHRpb24gZXgpCi0gICAgICB7Ci0gICAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbihleCk7Ci0gICAgICB9Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIERUTUF4aXNJdGVyYXRvcikKLSAgICB7Ci0gICAgICBEVE1BeGlzSXRlcmF0b3IgaXRlciA9IChEVE1BeGlzSXRlcmF0b3IpdmFsOwotICAgICAgdHJ5Ci0gICAgICB7Ci0gICAgICAgIERUTUl0ZXJhdG9yIGl0ZXJhdG9yID0gbmV3IE9uZVN0ZXBJdGVyYXRvcihpdGVyLCBBeGlzLlNFTEYpOwotICAgICAgICBpdGVyYXRvci5zZXRSb290KGl0ZXIuZ2V0U3RhcnROb2RlKCksIHhjdHh0KTsKLSAgICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0KGl0ZXJhdG9yKTsKLSAgICAgIH0KLSAgICAgIGNhdGNoKEV4Y2VwdGlvbiBleCkKLSAgICAgIHsKLSAgICAgICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKGV4KTsKLSAgICAgIH0KLSAgICB9Ci0gICAgZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgRFRNSXRlcmF0b3IpCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0KChEVE1JdGVyYXRvcikgdmFsKTsKLSAgICB9Ci0gICAgLy8gVGhpcyBuZXh0IHRocmVlIGluc3RhbmNlb2ZzIGFyZSBhIGxpdHRsZSB3b3JyeXNvbWUsIHNpbmNlIGEgTm9kZUxpc3QgCi0gICAgLy8gbWlnaHQgYWxzbyBpbXBsZW1lbnQgYSBOb2RlIQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIG9yZy53M2MuZG9tLk5vZGUpCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0Rm9yRE9NKChvcmcudzNjLmRvbS5Ob2RlKXZhbCwgeGN0eHQpOwotICAgIH0KLSAgICAvLyBUaGlzIG11c3QgY29tZSBhZnRlciBvcmcudzNjLmRvbS5Ob2RlLCBzaW5jZSBtYW55IE5vZGUgaW1wbGVtZW50YXRpb25zIAotICAgIC8vIGFsc28gaW1wbGVtZW50IE5vZGVMaXN0LgotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIG9yZy53M2MuZG9tLk5vZGVMaXN0KQotICAgIHsKLSAgICAgIHJlc3VsdCA9IG5ldyBYTm9kZVNldEZvckRPTSgob3JnLnczYy5kb20uTm9kZUxpc3QpdmFsLCB4Y3R4dCk7Ci0gICAgfQotICAgIGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IpCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0Rm9yRE9NKChvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yKXZhbCwgeGN0eHQpOwotICAgIH0KLSAgICBlbHNlCi0gICAgewotICAgICAgcmVzdWx0ID0gbmV3IFhPYmplY3QodmFsKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YUlRyZWVGcmFnLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hSVHJlZUZyYWcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGQ1ZmVjOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hSVHJlZUZyYWcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3MyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHM7Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlTGlzdDsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkRPTUhlbHBlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImdlbmVyYWwiLz4KLSAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBYUGF0aCByZXN1bHQgdHJlZSBmcmFnbWVudCBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBSVEYgdG8gb3RoZXIgdHlwZXMsIHN1Y2ggYXMgYSBzdHJpbmcuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUlRyZWVGcmFnIGV4dGVuZHMgWE9iamVjdCBpbXBsZW1lbnRzIENsb25lYWJsZQotewotICBEVE0gbV9kdG07Ci0gIGludCBtX2R0bVJvb3Q7Ci0gIFhQYXRoQ29udGV4dCBtX3hjdHh0OwotICBib29sZWFuIG1fYWxsb3dSZWxlYXNlID0gdHJ1ZTsKLQotLy8gIC8qKgotLy8gICAqIENyZWF0ZSBhbiBYUlRyZWVGcmFnIE9iamVjdC4KLS8vICAgKgotLy8gICAqIEBwYXJhbSBmcmFnIERvY3VtZW50IGZyYWdtZW50IHRoaXMgd2lsbCB3cmFwCi0vLyAgICovCi0vLyAgcHVibGljIFhSVHJlZUZyYWcoRFRNSXRlcmF0b3IgZnJhZykKLS8vICB7Ci0vLyAgICBzdXBlcihmcmFnKTsKLS8vICAgIAotLy8gICAgLy8gT2J2aW91c2x5LCB0aGlzIGNvbnN0cnVjdG9yIHNob3VsZCBiZSBhdm9pZGVkIHdoZW4gcG9zc2libGUuCi0vLyAgICBtX2R0bVJvb3QgPSBmcmFnLmNsb25lV2l0aFJlc2V0KCkubmV4dE5vZGUoKTsKLS8vICB9Ci0gIAotICAvKioKLSAgICogQ3JlYXRlIGFuIFhSVHJlZUZyYWcgT2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gZnJhZyBEb2N1bWVudCBmcmFnbWVudCB0aGlzIHdpbGwgd3JhcAotICAgKi8KLSAgcHVibGljIFhSVHJlZUZyYWcoaW50IHJvb3QsIFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgewotICAgIHN1cGVyKG51bGwpOwotICAgIAotICAgIC8vIE9idmlvdXNseSwgdGhpcyBjb25zdHJ1Y3RvciBzaG91bGQgYmUgYXZvaWRlZCB3aGVuIHBvc3NpYmxlLgotICAgIG1fZHRtUm9vdCA9IHJvb3Q7Ci0gICAgbV94Y3R4dCA9IHhjdHh0OwotICAgIG1fZHRtID0geGN0eHQuZ2V0RFRNKHJvb3QpOwotICB9Ci0gIAotICAvKioKLSAgICogUmV0dXJuIGEgamF2YSBvYmplY3QgdGhhdCdzIGNsb3Nlc3QgdG8gdGhlIHJlcHJlc2VudGF0aW9uCi0gICAqIHRoYXQgc2hvdWxkIGJlIGhhbmRlZCB0byBhbiBleHRlbnNpb24uCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIG9iamVjdCB0aGF0IHRoaXMgY2xhc3Mgd3JhcHMKLSAgICovCi0gIHB1YmxpYyBPYmplY3Qgb2JqZWN0KCkKLSAgewotICAgIHJldHVybiBuZXcgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5EVE1Ob2RlSXRlcmF0b3IoKERUTUl0ZXJhdG9yKShuZXcgb3JnLmFwYWNoZS54cGF0aC5Ob2RlU2V0RFRNKG1fZHRtUm9vdCwgbV94Y3R4dC5nZXREVE1NYW5hZ2VyKCkpKSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDcmVhdGUgYW4gWFJUcmVlRnJhZyBPYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSBmcmFnIERvY3VtZW50IGZyYWdtZW50IHRoaXMgd2lsbCB3cmFwCi0gICAqLwotICBwdWJsaWMgWFJUcmVlRnJhZyhFeHByZXNzaW9uIGV4cHIpCi0gIHsKLSAgICBzdXBlcihleHByKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJlbGVhc2UgYW55IHJlc291cmNlcyB0aGlzIG9iamVjdCBtYXkgaGF2ZSBieSBjYWxsaW5nIGRlc3RydWN0KCkuCi0gICAqCi0gICAqIEB0aHJvd3MgVGhyb3dhYmxlCi0gICAqLwotICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUKLSAgewotCi0gICAgdHJ5Ci0gICAgewotICAgICAgZGVzdHJ1Y3QoKTsKLSAgICB9Ci0gICAgZmluYWxseQotICAgIHsKLSAgICAgIHN1cGVyLmZpbmFsaXplKCk7ICAvLyBBbHdheXMgdXNlIHRoaXMuCi0gICAgfQotICB9Ci0gIAotICAvKioKLSAgICogU3BlY2lmeSBpZiBpdCdzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGUgaXRlcmF0b3IgZm9yIHJldXNlLgotICAgKiAKLSAgICogQHBhcmFtIGFsbG93UmVsZWFzZSB0cnVlIGlmIGl0IGlzIE9LIGZvciBkZXRhY2ggdG8gcmVsZWFzZSB0aGlzIGl0ZXJhdG9yIAotICAgKiBmb3IgcG9vbGluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGFsbG93RGV0YWNoVG9SZWxlYXNlKGJvb2xlYW4gYWxsb3dSZWxlYXNlKQotICB7Ci0gICAgbV9hbGxvd1JlbGVhc2UgPSBhbGxvd1JlbGVhc2U7Ci0gIH0KLQotICAvKioKLSAgICogRGV0YWNoZXMgdGhlIDxjb2RlPkRUTUl0ZXJhdG9yPC9jb2RlPiBmcm9tIHRoZSBzZXQgd2hpY2ggaXQgaXRlcmF0ZWQKLSAgICogb3ZlciwgcmVsZWFzaW5nIGFueSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBhbmQgcGxhY2luZyB0aGUgaXRlcmF0b3IKLSAgICogaW4gdGhlIElOVkFMSUQgc3RhdGUuIEFmdGVyIDxjb2RlPmRldGFjaDwvY29kZT4gaGFzIGJlZW4gaW52b2tlZCwKLSAgICogY2FsbHMgdG8gPGNvZGU+bmV4dE5vZGU8L2NvZGU+IG9yIDxjb2RlPnByZXZpb3VzTm9kZTwvY29kZT4gd2lsbAotICAgKiByYWlzZSBhIHJ1bnRpbWUgZXhjZXB0aW9uLgotICAgKiAKLSAgICogSW4gZ2VuZXJhbCwgZGV0YWNoIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbmNlIG9uIHRoZSBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXRhY2goKQotICB7Ci0gICAgaWYobV9hbGxvd1JlbGVhc2UpCi0gICAgewotICAgICAgaWYobnVsbCAhPSBtX2R0bSkKLSAgICAgIHsKLSAgICAgICAgbV94Y3R4dC5yZWxlYXNlKG1fZHRtLCB0cnVlKTsKLSAgICAgICAgbV9kdG0gPSBudWxsOwotICAgICAgICBtX3hjdHh0ID0gbnVsbDsKLSAgICAgIH0KLSAgICAgIG1fb2JqID0gbnVsbDsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBGb3JjZXMgdGhlIG9iamVjdCB0byByZWxlYXNlIGl0J3MgcmVzb3VyY2VzLiAgVGhpcyBpcyBtb3JlIGhhcnNoIHRoYW4gCi0gICAqIGRldGFjaCgpLiAgWW91IGNhbiBjYWxsIGRlc3RydWN0IGFzIG1hbnkgdGltZXMgYXMgeW91IHdhbnQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBkZXN0cnVjdCgpCi0gIHsKLSAgICBpZihudWxsICE9IG1fZHRtKQotICAgIHsKLSAgICAgIG1feGN0eHQucmVsZWFzZShtX2R0bSwgdHJ1ZSk7Ci0gICAgICBtX2R0bSA9IG51bGw7Ci0gICAgICBtX3hjdHh0ID0gbnVsbDsKLSAgICB9Ci0gICAgbV9vYmogPSBudWxsOwotIH0KLQotICAvKioKLSAgICogVGVsbCB3aGF0IGtpbmQgb2YgY2xhc3MgdGhpcyBpcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIENMQVNTX1JUUkVFRlJBRyAKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfUlRSRUVGUkFHOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgcmVxdWVzdCB0eXBlLCByZXR1cm4gdGhlIGVxdWl2YWxlbnQgc3RyaW5nLgotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIHN0cmluZyAiI1JUUkVFRlJBRyIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gIiNSVFJFRUZSQUciOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IHRyZWUgZnJhZ21lbnQgYXMgYSBudW1iZXIgb3IgTmFOCi0gICAqLwotICBwdWJsaWMgZG91YmxlIG51bSgpCi0gICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgWE1MU3RyaW5nIHMgPSB4c3RyKCk7Ci0KLSAgICByZXR1cm4gcy50b0RvdWJsZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIGJvb2xlYW4uICBUaGlzIGFsd2F5cyByZXR1cm5zIHRydWUgZm9yIGEgUlRyZWVGcmFnCi0gICAqIGJlY2F1c2UgaXQgaXMgdHJlYXRlZCBsaWtlIGEgbm9kZS1zZXQgd2l0aCBhIHNpbmdsZSByb290IG5vZGUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gYm9vbCgpCi0gIHsKLSAgICByZXR1cm4gdHJ1ZTsKLSAgfQotICAKLSAgcHJpdmF0ZSBYTUxTdHJpbmcgbV94bWxTdHIgPSBudWxsOwotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhbiBYTUxTdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IG5vZGUgZGF0YSBvciB0aGUgZW1wdHkgc3RyaW5nLiAKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgeHN0cigpCi0gIHsKLSAgICBpZihudWxsID09IG1feG1sU3RyKQotICAgICAgbV94bWxTdHIgPSBtX2R0bS5nZXRTdHJpbmdWYWx1ZShtX2R0bVJvb3QpOwotICAgIAotICAgIHJldHVybiBtX3htbFN0cjsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBhcHBlbmRUb0ZzYihvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyIGZzYikKLSAgewotICAgIFhTdHJpbmcgeHN0cmluZyA9IChYU3RyaW5nKXhzdHIoKTsKLSAgICB4c3RyaW5nLmFwcGVuZFRvRnNiKGZzYik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IG5vZGUgZGF0YSBvciB0aGUgZW1wdHkgc3RyaW5nLiAKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIFN0cmluZyBzdHIgPSBtX2R0bS5nZXRTdHJpbmdWYWx1ZShtX2R0bVJvb3QpLnRvU3RyaW5nKCk7Ci0KLSAgICByZXR1cm4gKG51bGwgPT0gc3RyKSA/ICIiIDogc3RyOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkb2N1bWVudCBmcmFnbWVudCB0aGlzIHdyYXBzCi0gICAqLwotICBwdWJsaWMgaW50IHJ0ZigpCi0gIHsKLSAgICByZXR1cm4gbV9kdG1Sb290OwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIERUTUl0ZXJhdG9yLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkb2N1bWVudCBmcmFnbWVudCBhcyBhIERUTUl0ZXJhdG9yCi0gICAqLwotICBwdWJsaWMgRFRNSXRlcmF0b3IgYXNOb2RlSXRlcmF0b3IoKQotICB7Ci0gICAgcmV0dXJuIG1feGN0eHQuY3JlYXRlRFRNSXRlcmF0b3IobV9kdG1Sb290KTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBub2RlbGlzdC4gKHNwZWNpYWwgZnVuY3Rpb24pLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBkb2N1bWVudCBmcmFnbWVudCBhcyBhIG5vZGVsaXN0Ci0gICAqLwotICBwdWJsaWMgTm9kZUxpc3QgY29udmVydFRvTm9kZXNldCgpCi0gIHsKLQotICAgIGlmIChtX29iaiBpbnN0YW5jZW9mIE5vZGVMaXN0KQotICAgICAgcmV0dXJuIChOb2RlTGlzdCkgbV9vYmo7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIG5ldyBvcmcuYXBhY2hlLnhtbC5kdG0ucmVmLkRUTU5vZGVMaXN0KGFzTm9kZUl0ZXJhdG9yKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdHdvIG9iamVjdHMgYXJlIGZ1bmN0aW9uYWxseSBlcXVhbC4KLSAgICoKLSAgICogQHBhcmFtIG9iajIgT2JqZWN0IHRvIGNvbXBhcmUgdGhpcyB0bwotICAgKgotICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHR3byBvYmplY3RzIGFyZSBlcXVhbAotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYT2JqZWN0IG9iajIpCi0gIHsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIGlmIChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gb2JqMi5nZXRUeXBlKCkpCi0gICAgICB7Ci0gIAotICAgICAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZiAKLSAgICAgICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlIAotICAgICAgICAvLyBub2Rlc2V0IGZ1bmN0aW9uLgotICAgICAgICByZXR1cm4gb2JqMi5lcXVhbHModGhpcyk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX0JPT0xFQU4gPT0gb2JqMi5nZXRUeXBlKCkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBib29sKCkgPT0gb2JqMi5ib29sKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX05VTUJFUiA9PSBvYmoyLmdldFR5cGUoKSkKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG51bSgpID09IG9iajIubnVtKCk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX05PREVTRVQgPT0gb2JqMi5nZXRUeXBlKCkpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiB4c3RyKCkuZXF1YWxzKG9iajIueHN0cigpKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKFhPYmplY3QuQ0xBU1NfU1RSSU5HID09IG9iajIuZ2V0VHlwZSgpKQotICAgICAgewotICAgICAgICByZXR1cm4geHN0cigpLmVxdWFscyhvYmoyLnhzdHIoKSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChYT2JqZWN0LkNMQVNTX1JUUkVFRlJBRyA9PSBvYmoyLmdldFR5cGUoKSkKLSAgICAgIHsKLSAgCi0gICAgICAgIC8vIFByb2JhYmx5IG5vdCBzbyBnb29kLiAgVGhpbmsgYWJvdXQgdGhpcy4KLSAgICAgICAgcmV0dXJuIHhzdHIoKS5lcXVhbHMob2JqMi54c3RyKCkpOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgewotICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iajIpOwotICAgICAgfQotICAgIH0KLSAgICBjYXRjaChqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIHRlKQotICAgIHsKLSAgICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbih0ZSk7Ci0gICAgfQotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGM4MmQ1Yi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hSVHJlZUZyYWdTZWxlY3RXcmFwcGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMzAgKzAsMCBAQAotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5ET01IZWxwZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBtYWtlcyBhbiBzZWxlY3Qgc3RhdGVtZW50IGFjdCBsaWtlIGFuIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICovCi1wdWJsaWMgY2xhc3MgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgZXh0ZW5kcyBYUlRyZWVGcmFnIGltcGxlbWVudHMgQ2xvbmVhYmxlCi17Ci0gIFhPYmplY3QgbV9zZWxlY3RlZDsKLQotICBwdWJsaWMgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIoRXhwcmVzc2lvbiBleHByKQotICB7Ci0gICAgc3VwZXIoZXhwcik7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgICgoRXhwcmVzc2lvbiltX29iaikuZml4dXBWYXJpYWJsZXModmFycywgZ2xvYmFsc1NpemUpOwotICB9Ci0gIAotICAvKioKLSAgICogRm9yIHN1cHBvcnQgb2YgbGl0ZXJhbCBvYmplY3RzIGluIHhwYXRocy4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGlzIG9iamVjdC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgdHJ5Ci0gICAgewotICAgICAgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIgeHJ0ZiA9IChYUlRyZWVGcmFnU2VsZWN0V3JhcHBlcil0aGlzLmNsb25lKCk7Ci0gICAgICB4cnRmLm1fc2VsZWN0ZWQgPSAoKEV4cHJlc3Npb24pbV9vYmopLmV4ZWN1dGUoeGN0eHQpOwotICAgICAgcmV0dXJuIHhydGY7Ci0gICAgfQotICAgIGNhdGNoKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNuc2UpCi0gICAgewotICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oY25zZSk7Ci0gICAgfQotICAgIAotICB9Ci0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgbnVtYmVyLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgdHJlZSBmcmFnbWVudCBhcyBhIG51bWJlciBvciBOYU4KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gbV9zZWxlY3RlZC5udW0oKTsKLSAgfQotCi0gIAotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGFuIFhNTFN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgbm9kZSBkYXRhIG9yIHRoZSBlbXB0eSBzdHJpbmcuIAotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKCkKLSAgewotICAgIHJldHVybiBtX3NlbGVjdGVkLnhzdHIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIGRvY3VtZW50IGZyYWdtZW50IG5vZGUgZGF0YSBvciB0aGUgZW1wdHkgc3RyaW5nLiAKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotICAgIHJldHVybiBtX3NlbGVjdGVkLnN0cigpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCB3aGF0IGtpbmQgb2YgY2xhc3MgdGhpcyBpcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIENMQVNTX1JUUkVFRlJBRyAKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfU1RSSU5HOyAvLyBobW0uLi4KLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgdGhpcyB3cmFwcwotICAgKi8KLSAgcHVibGljIGludCBydGYoKQotICB7Ci0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfUlRGX05PVF9TVVBQT1JURURfWFJUUkVFRlJBR1NFTEVDVFdSQVBQRVIsIG51bGwpKTsgLy8icnRmKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBEVE1JdGVyYXRvci4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZG9jdW1lbnQgZnJhZ21lbnQgYXMgYSBEVE1JdGVyYXRvcgotICAgKi8KLSAgcHVibGljIERUTUl0ZXJhdG9yIGFzTm9kZUl0ZXJhdG9yKCkKLSAgewotICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSLCBudWxsKSk7IC8vImFzTm9kZUl0ZXJhdG9yKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciEiKTsKLSAgfQotCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YU3RyaW5nLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hTdHJpbmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGEzNjE4YS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hTdHJpbmcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExODEgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzOwotCi0vL2ltcG9ydCBvcmcudzNjLmRvbS4qOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iZ2VuZXJhbCIvPgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGFuIFhQYXRoIHN0cmluZyBvYmplY3QsIGFuZCBpcyBjYXBhYmxlIG9mCi0gKiBjb252ZXJ0aW5nIHRoZSBzdHJpbmcgdG8gb3RoZXIgdHlwZXMsIHN1Y2ggYXMgYSBudW1iZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBYU3RyaW5nIGV4dGVuZHMgWE9iamVjdCBpbXBsZW1lbnRzIFhNTFN0cmluZwotewotCi0gIC8qKiBFbXB0eSBzdHJpbmcgWFN0cmluZyBvYmplY3QgKi8KLSAgcHVibGljIHN0YXRpYyBYU3RyaW5nIEVNUFRZU1RSSU5HID0gbmV3IFhTdHJpbmcoIiIpOwotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYU3RyaW5nIG9iamVjdC4gIFRoaXMgY29uc3RydWN0b3IgZXhpc3RzIGZvciBkZXJpdmVkIGNsYXNzZXMuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgU3RyaW5nIG9iamVjdCB0aGlzIHdpbGwgd3JhcC4KLSAgICovCi0gIHByb3RlY3RlZCBYU3RyaW5nKE9iamVjdCB2YWwpCi0gIHsKLSAgICBzdXBlcih2YWwpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIFhOb2RlU2V0IG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtIHZhbCBTdHJpbmcgb2JqZWN0IHRoaXMgd2lsbCB3cmFwLgotICAgKi8KLSAgcHVibGljIFhTdHJpbmcoU3RyaW5nIHZhbCkKLSAgewotICAgIHN1cGVyKHZhbCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCB0aGF0IHRoaXMgaXMgYSBDTEFTU19TVFJJTkcuCi0gICAqCi0gICAqIEByZXR1cm4gdHlwZSBDTEFTU19TVFJJTkcKLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCi0gIHsKLSAgICByZXR1cm4gQ0xBU1NfU1RSSU5HOwotICB9Ci0KLSAgLyoqCi0gICAqIEdpdmVuIGEgcmVxdWVzdCB0eXBlLCByZXR1cm4gdGhlIGVxdWl2YWxlbnQgc3RyaW5nLgotICAgKiBGb3IgZGlhZ25vc3RpYyBwdXJwb3Nlcy4KLSAgICoKLSAgICogQHJldHVybiB0eXBlIHN0cmluZyAiI1NUUklORyIKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVN0cmluZygpCi0gIHsKLSAgICByZXR1cm4gIiNTVFJJTkciOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBvYmplY3QgY29udGFpbnMgYSBqYXZhIFN0cmluZyBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIFhNTFN0cmluZyBjYW4gcmV0dXJuIGEgc3RyaW5nIHdpdGhvdXQgY3JlYXRpbmcgb25lLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIG51bWJlci4KLSAgICoKLSAgICogQHJldHVybiAwLjAgaWYgdGhpcyBzdHJpbmcgaXMgbnVsbCwgbnVtZXJpYyB2YWx1ZSBvZiB0aGlzIHN0cmluZwotICAgKiBvciBOYU4KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKCkKLSAgewotICAgIHJldHVybiB0b0RvdWJsZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBkb3VibGUgLS0gQWxsb3dlZCBpbnB1dCBpcyBpbiBmaXhlZAotICAgKiBub3RhdGlvbiBkZGQuZmZmLgotICAgKgotICAgKiBAcmV0dXJuIEEgZG91YmxlIHZhbHVlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcsIG9yIHJldHVybiBEb3VibGUuTmFOCi0gICAqIGlmIHRoZSBzdHJpbmcgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIHRvRG91YmxlKCkKLSAgewotICAgIGludCBlbmQgPSBsZW5ndGgoKTsKLSAgICAKLSAgICBpZigwID09IGVuZCkKLSAgICAgIHJldHVybiBEb3VibGUuTmFOOwotCi0gICAgZG91YmxlIHJlc3VsdCA9IDAuMDsKLSAgICBpbnQgc3RhcnQgPSAwOwotICAgIGludCBwdW5jdFBvcyA9IGVuZC0xOwotCi0gICAgLy8gU2NhbiB0byBmaXJzdCB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4KLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykKLSAgICB7Ci0gICAgICBjaGFyIGMgPSBjaGFyQXQoaSk7Ci0KLSAgICAgIGlmICghWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoYykpCi0gICAgICB7Ci0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgICAgZWxzZQotICAgICAgICBzdGFydCsrOwotICAgIH0KLQotICAgIGRvdWJsZSBzaWduID0gMS4wOwotCi0gICAgaWYgKHN0YXJ0IDwgZW5kICYmIGNoYXJBdChzdGFydCkgPT0gJy0nKQotICAgIHsKLSAgICAgIHNpZ24gPSAtMS4wOwotCi0gICAgICBzdGFydCsrOwotICAgIH0KLQotICAgIGludCBkaWdpdHNGb3VuZCA9IDA7Ci0KLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgIC8vIHBhcnNlIHRoZSBzdHJpbmcgZnJvbSBsZWZ0IHRvIHJpZ2h0IGNvbnZlcnRpbmcgdGhlIGludGVnZXIgcGFydAotICAgIHsKLSAgICAgIGNoYXIgYyA9IGNoYXJBdChpKTsKLQotICAgICAgaWYgKGMgIT0gJy4nKQotICAgICAgewotICAgICAgICBpZiAoWE1MQ2hhcmFjdGVyUmVjb2duaXplci5pc1doaXRlU3BhY2UoYykpCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICAgIGVsc2UgaWYgKENoYXJhY3Rlci5pc0RpZ2l0KGMpKQotICAgICAgICB7Ci0gICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICogMTAuMCArIChjIC0gMHgzMCk7Ci0KLSAgICAgICAgICBkaWdpdHNGb3VuZCsrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBEb3VibGUuTmFOOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIHB1bmN0UG9zID0gaTsKLQotICAgICAgICBicmVhazsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAoY2hhckF0KHB1bmN0UG9zKSA9PSAnLicpICAvLyBwYXJzZSB0aGUgc3RyaW5nIGZyb20gdGhlIGVuZCB0byB0aGUgJy4nIGNvbnZlcnRpbmcgdGhlIGZyYWN0aW9uYWwgcGFydAotICAgIHsKLSAgICAgIGRvdWJsZSBmcmFjdFBhcnQgPSAwLjA7Ci0KLSAgICAgIGZvciAoaW50IGkgPSBlbmQgLSAxOyBpID4gcHVuY3RQb3M7IGktLSkKLSAgICAgIHsKLSAgICAgICAgY2hhciBjID0gY2hhckF0KGkpOwotCi0gICAgICAgIGlmIChYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZShjKSkKLSAgICAgICAgICBicmVhazsKLSAgICAgICAgZWxzZSBpZiAoQ2hhcmFjdGVyLmlzRGlnaXQoYykpCi0gICAgICAgIHsKLSAgICAgICAgICBmcmFjdFBhcnQgPSBmcmFjdFBhcnQgLyAxMC4wICsgKGMgLSAweDMwKTsKLQotICAgICAgICAgIGRpZ2l0c0ZvdW5kKys7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgICAgIH0KLSAgICAgIH0KLQotICAgICAgcmVzdWx0ICs9IGZyYWN0UGFydCAvIDEwLjA7Ci0gICAgfQotCi0gICAgaWYgKDAgPT0gZGlnaXRzRm91bmQpCi0gICAgICByZXR1cm4gRG91YmxlLk5hTjsKLQotICAgIHJldHVybiByZXN1bHQgKiBzaWduOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nIG9iamVjdCBpcyBncmVhdGVyCi0gICAqIHRoYW4gMC4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmxlbmd0aCgpID4gMDsKLSAgfQotCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyB4c3RyKCkKLSAgewotICAgIHJldHVybiB0aGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIHN0cigpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgIT0gbV9vYmopID8gKChTdHJpbmcpIG1fb2JqKSA6ICIiOwotICB9Ci0KLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgotICAgKgotICAgKiBAcGFyYW0gc3VwcG9ydCBYcGF0aCBjb250ZXh0IHRvIHVzZSBmb3IgdGhlIGNvbnZlcnNpb24KLSAgICoKLSAgICogQHJldHVybiBBIGRvY3VtZW50IGZyYWdtZW50IHdpdGggdGhpcyBzdHJpbmcgYXMgYSBjaGlsZCBub2RlCi0gICAqLwotICBwdWJsaWMgaW50IHJ0ZihYUGF0aENvbnRleHQgc3VwcG9ydCkKLSAgewotCi0gICAgRFRNIGZyYWcgPSBzdXBwb3J0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsKLQotICAgIGZyYWcuYXBwZW5kVGV4dENoaWxkKHN0cigpKTsKLQotICAgIHJldHVybiBmcmFnLmdldERvY3VtZW50KCk7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY2hhcmFjdGVycyBtZXRob2Qgb24gdGhlIHBhc3NlZCBDb250ZW50SGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4gTXVsdGlwbGUgY2FsbHMgdG8gdGhlCi0gICAqIENvbnRlbnRIYW5kbGVyJ3MgY2hhcmFjdGVycyBtZXRob2RzIG1heSB3ZWxsIG9jY3VyIGZvciBhIHNpbmdsZSBjYWxsIHRvCi0gICAqIHRoaXMgbWV0aG9kLgotICAgKgotICAgKiBAcGFyYW0gY2ggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBDb250ZW50SGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQ2hhcmFjdGVyc0V2ZW50cyhvcmcueG1sLnNheC5Db250ZW50SGFuZGxlciBjaCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLQotICAgIFN0cmluZyBzdHIgPSBzdHIoKTsKLQotICAgIGNoLmNoYXJhY3RlcnMoc3RyLnRvQ2hhckFycmF5KCksIDAsIHN0ci5sZW5ndGgoKSk7Ci0gIH0KLQotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY29tbWVudCBtZXRob2Qgb24gdGhlIHBhc3NlZCBMZXhpY2FsSGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGxoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaEFzQ29tbWVudChvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgbGgpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0KLSAgICBTdHJpbmcgc3RyID0gc3RyKCk7Ci0KLSAgICBsaC5jb21tZW50KHN0ci50b0NoYXJBcnJheSgpLCAwLCBzdHIubGVuZ3RoKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIGxlbmd0aCBvZiB0aGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBzdHIoKS5sZW5ndGgoKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gQW4gaW5kZXggcmFuZ2VzCi0gICAqIGZyb20gPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoKCkgLSAxPC9jb2RlPi4gVGhlIGZpcnN0IGNoYXJhY3RlcgotICAgKiBvZiB0aGUgc2VxdWVuY2UgaXMgYXQgaW5kZXggPGNvZGU+MDwvY29kZT4sIHRoZSBuZXh0IGF0IGluZGV4Ci0gICAqIDxjb2RlPjE8L2NvZGU+LCBhbmQgc28gb24sIGFzIGZvciBhcnJheSBpbmRleGluZy4KLSAgICoKLSAgICogQHBhcmFtICAgICAgaW5kZXggICB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgICAgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgc3RyaW5nLgotICAgKiAgICAgICAgICAgICBUaGUgZmlyc3QgY2hhcmFjdGVyIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+Ci0gICAqICAgICAgICAgICAgIGFyZ3VtZW50IGlzIG5lZ2F0aXZlIG9yIG5vdCBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBjaGFyIGNoYXJBdChpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuY2hhckF0KGluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBDb3BpZXMgY2hhcmFjdGVycyBmcm9tIHRoaXMgc3RyaW5nIGludG8gdGhlIGRlc3RpbmF0aW9uIGNoYXJhY3RlcgotICAgKiBhcnJheS4KLSAgICoKLSAgICogQHBhcmFtICAgICAgc3JjQmVnaW4gICBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICB0byBjb3B5LgotICAgKiBAcGFyYW0gICAgICBzcmNFbmQgICAgIGluZGV4IGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgZHN0ICAgICAgICB0aGUgZGVzdGluYXRpb24gYXJyYXkuCi0gICAqIEBwYXJhbSAgICAgIGRzdEJlZ2luICAgdGhlIHN0YXJ0IG9mZnNldCBpbiB0aGUgZGVzdGluYXRpb24gYXJyYXkuCi0gICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBJZiBhbnkgb2YgdGhlIGZvbGxvd2luZwotICAgKiAgICAgICAgICAgIGlzIHRydWU6Ci0gICAqICAgICAgICAgICAgPHVsPjxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUuCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPnNyY0JlZ2luPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gPGNvZGU+c3JjRW5kPC9jb2RlPgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNFbmQ8L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgICAgICAgc3RyaW5nCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPmRzdEJlZ2luPC9jb2RlPiBpcyBuZWdhdGl2ZQotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbisoc3JjRW5kLXNyY0JlZ2luKTwvY29kZT4gaXMgbGFyZ2VyIHRoYW4KLSAgICogICAgICAgICAgICAgICAgPGNvZGU+ZHN0Lmxlbmd0aDwvY29kZT48L3VsPgotICAgKiBAZXhjZXB0aW9uIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPmRzdDwvY29kZT4gaXMgPGNvZGU+bnVsbDwvY29kZT4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGdldENoYXJzKGludCBzcmNCZWdpbiwgaW50IHNyY0VuZCwgY2hhciBkc3RbXSwgaW50IGRzdEJlZ2luKQotICB7Ci0gICAgc3RyKCkuZ2V0Q2hhcnMoc3JjQmVnaW4sIHNyY0VuZCwgZHN0LCBkc3RCZWdpbik7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotCi0gICAgLy8gSW4gb3JkZXIgdG8gaGFuZGxlIHRoZSAnYWxsJyBzZW1hbnRpY3Mgb2YgCi0gICAgLy8gbm9kZXNldCBjb21wYXJpc29ucywgd2UgYWx3YXlzIGNhbGwgdGhlIAotICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uCi0gICAgaWYgKG9iajIuZ2V0VHlwZSgpID09IFhPYmplY3QuQ0xBU1NfTk9ERVNFVCkKLSAgICAgIHJldHVybiBvYmoyLmVxdWFscyh0aGlzKTsKLQotICAgIHJldHVybiBzdHIoKS5lcXVhbHMob2JqMi5zdHIoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyBzdHJpbmcgdG8gdGhlIHNwZWNpZmllZCBvYmplY3QuCi0gICAqIFRoZSByZXN1bHQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYW5kIG9ubHkgaWYgdGhlIGFyZ3VtZW50IGlzIG5vdAotICAgKiA8Y29kZT5udWxsPC9jb2RlPiBhbmQgaXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCB0aGF0IHJlcHJlc2VudHMKLSAgICogdGhlIHNhbWUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBhcyB0aGlzIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtICAgYW5PYmplY3QgICB0aGUgb2JqZWN0IHRvIGNvbXBhcmUgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+Ci0gICAqICAgICAgICAgICAgICAgICAgICAgYWdhaW5zdC4KLSAgICoKLSAgICogTkVFRFNET0MgQHBhcmFtIG9iajIKLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIDxjb2RlPlN0cmluZyA8L2NvZGU+YXJlIGVxdWFsOwotICAgKiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI2NvbXBhcmVUbyhqYXZhLmxhbmcuU3RyaW5nKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI2VxdWFsc0lnbm9yZUNhc2UoamF2YS5sYW5nLlN0cmluZykKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFscyhYTUxTdHJpbmcgb2JqMikKLSAgewotCi0gICAgaWYgKCFvYmoyLmhhc1N0cmluZygpKQotICAgICAgcmV0dXJuIG9iajIuZXF1YWxzKHRoaXMpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBzdHIoKS5lcXVhbHMob2JqMi50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICBhbk9iamVjdCAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gb2JqMgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmoyKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBvYmoyKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZiAKLSAgICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZSAKLSAgICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uCi0gICAgZWxzZSBpZiAob2JqMiBpbnN0YW5jZW9mIFhOb2RlU2V0KQotICAgICAgcmV0dXJuIG9iajIuZXF1YWxzKHRoaXMpOwotICAgIGVsc2UKLSAgICAgIHJldHVybiBzdHIoKS5lcXVhbHMob2JqMi50b1N0cmluZygpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gYW5vdGhlciA8Y29kZT5TdHJpbmc8L2NvZGU+LAotICAgKiBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLiAgVHdvIHN0cmluZ3MgYXJlIGNvbnNpZGVyZWQgZXF1YWwKLSAgICogaWdub3JpbmcgY2FzZSBpZiB0aGV5IGFyZSBvZiB0aGUgc2FtZSBsZW5ndGgsIGFuZCBjb3JyZXNwb25kaW5nCi0gICAqIGNoYXJhY3RlcnMgaW4gdGhlIHR3byBzdHJpbmdzIGFyZSBlcXVhbCBpZ25vcmluZyBjYXNlLgotICAgKgotICAgKiBAcGFyYW0gICBhbm90aGVyU3RyaW5nICAgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gY29tcGFyZSB0aGlzCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IGFnYWluc3QuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBpcyBub3QgPGNvZGU+bnVsbDwvY29kZT4KLSAgICogICAgICAgICAgYW5kIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+cyBhcmUgZXF1YWwsCi0gICAqICAgICAgICAgIGlnbm9yaW5nIGNhc2U7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgICNlcXVhbHMoT2JqZWN0KQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuQ2hhcmFjdGVyI3RvTG93ZXJDYXNlKGNoYXIpCi0gICAqIEBzZWUgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzSWdub3JlQ2FzZShTdHJpbmcgYW5vdGhlclN0cmluZykKLSAgewotICAgIHJldHVybiBzdHIoKS5lcXVhbHNJZ25vcmVDYXNlKGFub3RoZXJTdHJpbmcpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHR3byBzdHJpbmdzIGxleGljb2dyYXBoaWNhbGx5LgotICAgKgotICAgKiBAcGFyYW0gICBhbm90aGVyU3RyaW5nICAgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gYmUgY29tcGFyZWQuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB4c3RyCi0gICAqIEByZXR1cm4gIHRoZSB2YWx1ZSA8Y29kZT4wPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgc3RyaW5nIGlzIGVxdWFsIHRvCi0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyBhIHZhbHVlIGxlc3MgdGhhbiA8Y29kZT4wPC9jb2RlPiBpZiB0aGlzIHN0cmluZwotICAgKiAgICAgICAgICBpcyBsZXhpY29ncmFwaGljYWxseSBsZXNzIHRoYW4gdGhlIHN0cmluZyBhcmd1bWVudDsgYW5kIGEKLSAgICogICAgICAgICAgdmFsdWUgZ3JlYXRlciB0aGFuIDxjb2RlPjA8L2NvZGU+IGlmIHRoaXMgc3RyaW5nIGlzCi0gICAqICAgICAgICAgIGxleGljb2dyYXBoaWNhbGx5IGdyZWF0ZXIgdGhhbiB0aGUgc3RyaW5nIGFyZ3VtZW50LgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5hbm90aGVyU3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBpbnQgY29tcGFyZVRvKFhNTFN0cmluZyB4c3RyKQotICB7Ci0KLSAgICBpbnQgbGVuMSA9IHRoaXMubGVuZ3RoKCk7Ci0gICAgaW50IGxlbjIgPSB4c3RyLmxlbmd0aCgpOwotICAgIGludCBuID0gTWF0aC5taW4obGVuMSwgbGVuMik7Ci0gICAgaW50IGkgPSAwOwotICAgIGludCBqID0gMDsKLQotICAgIHdoaWxlIChuLS0gIT0gMCkKLSAgICB7Ci0gICAgICBjaGFyIGMxID0gdGhpcy5jaGFyQXQoaSk7Ci0gICAgICBjaGFyIGMyID0geHN0ci5jaGFyQXQoaik7Ci0KLSAgICAgIGlmIChjMSAhPSBjMikKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIGMxIC0gYzI7Ci0gICAgICB9Ci0KLSAgICAgIGkrKzsKLSAgICAgIGorKzsKLSAgICB9Ci0KLSAgICByZXR1cm4gbGVuMSAtIGxlbjI7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdHdvIHN0cmluZ3MgbGV4aWNvZ3JhcGhpY2FsbHksIGlnbm9yaW5nIGNhc2UgY29uc2lkZXJhdGlvbnMuCi0gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gaW50ZWdlciB3aG9zZSBzaWduIGlzIHRoYXQgb2YKLSAgICogPGNvZGU+dGhpcy50b1VwcGVyQ2FzZSgpLnRvTG93ZXJDYXNlKCkuY29tcGFyZVRvKAotICAgKiBzdHIudG9VcHBlckNhc2UoKS50b0xvd2VyQ2FzZSgpKTwvY29kZT4uCi0gICAqIDxwPgotICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgZG9lcyA8ZW0+bm90PC9lbT4gdGFrZSBsb2NhbGUgaW50byBhY2NvdW50LAotICAgKiBhbmQgd2lsbCByZXN1bHQgaW4gYW4gdW5zYXRpc2ZhY3Rvcnkgb3JkZXJpbmcgZm9yIGNlcnRhaW4gbG9jYWxlcy4KLSAgICogVGhlIGphdmEudGV4dCBwYWNrYWdlIHByb3ZpZGVzIDxlbT5jb2xsYXRvcnM8L2VtPiB0byBhbGxvdwotICAgKiBsb2NhbGUtc2Vuc2l0aXZlIG9yZGVyaW5nLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBiZSBjb21wYXJlZC4KLSAgICogQHJldHVybiAgYSBuZWdhdGl2ZSBpbnRlZ2VyLCB6ZXJvLCBvciBhIHBvc2l0aXZlIGludGVnZXIgYXMgdGhlCi0gICAqICAgICAgICAgIHRoZSBzcGVjaWZpZWQgU3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiwgZXF1YWwgdG8sIG9yIGxlc3MKLSAgICogICAgICAgICAgdGhhbiB0aGlzIFN0cmluZywgaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4KLSAgICogQHNlZSAgICAgamF2YS50ZXh0LkNvbGxhdG9yI2NvbXBhcmUoU3RyaW5nLCBTdHJpbmcpCi0gICAqIEBzaW5jZSAgIDEuMgotICAgKi8KLSAgcHVibGljIGludCBjb21wYXJlVG9JZ25vcmVDYXNlKFhNTFN0cmluZyBzdHIpCi0gIHsKLSAgICAvLyAlUkVWSUVXJSAgTGlrZSBpdCBzYXlzLCBAc2luY2UgMS4yLiBEb2Vzbid0IGV4aXN0IGluIGVhcmxpZXIKLSAgICAvLyB2ZXJzaW9ucyBvZiBKYXZhLCBoZW5jZSB3ZSBjYW4ndCB5ZXQgc2hlbGwgb3V0IHRvIGl0LiBXZSBjYW4gaW1wbGVtZW50Ci0gICAgLy8gaXQgYXMgY2hhcmFjdGVyLWJ5LWNoYXJhY3RlciBjb21wYXJlLCBidXQgZG9pbmcgc28gZWZmaWNpZW50bHkKLSAgICAvLyBpcyBsaWtlbHkgdG8gYmUgKGFoZW0pIGludGVyZXN0aW5nLgotICAgIC8vICAKLSAgICAvLyBIb3dldmVyLCBzaW5jZSBub2JvZHkgaXMgYWN0dWFsbHkgX3VzaW5nXyB0aGlzIG1ldGhvZCB5ZXQ6Ci0gICAgLy8gICAgcmV0dXJuIHN0cigpLmNvbXBhcmVUb0lnbm9yZUNhc2Uoc3RyLnRvU3RyaW5nKCkpOwotICAgIAotICAgIHRocm93IG5ldyBvcmcuYXBhY2hlLnhtbC51dGlscy5XcmFwcGVkUnVudGltZUV4Y2VwdGlvbigKLSAgICAgIG5ldyBqYXZhLmxhbmcuTm9TdWNoTWV0aG9kRXhjZXB0aW9uKAotICAgICAgICAiSmF2YSAxLjIgbWV0aG9kLCBub3QgeWV0IGltcGxlbWVudGVkIikpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4IGJlZ2lubmluZwotICAgKiBhIHNwZWNpZmllZCBpbmRleC4KLSAgICoKLSAgICogQHBhcmFtICAgcHJlZml4ICAgIHRoZSBwcmVmaXguCi0gICAqIEBwYXJhbSAgIHRvZmZzZXQgICB3aGVyZSB0byBiZWdpbiBsb29raW5nIGluIHRoZSBzdHJpbmcuCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBzdWJzdHJpbmcgb2YgdGhpcyBvYmplY3Qgc3RhcnRpbmcKLSAgICogICAgICAgICAgYXQgaW5kZXggPGNvZGU+dG9mZnNldDwvY29kZT47IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIFRoZSByZXN1bHQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIDxjb2RlPnRvZmZzZXQ8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIG5lZ2F0aXZlIG9yIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3Q7IG90aGVyd2lzZSB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lCi0gICAqICAgICAgICAgIGFzIHRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24KLSAgICogICAgICAgICAgPHByZT4KLSAgICogICAgICAgICAgdGhpcy5zdWJTdHJpbmcodG9mZnNldCkuc3RhcnRzV2l0aChwcmVmaXgpCi0gICAqICAgICAgICAgIDwvcHJlPgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5wcmVmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gc3RhcnRzV2l0aChTdHJpbmcgcHJlZml4LCBpbnQgdG9mZnNldCkKLSAgewotICAgIHJldHVybiBzdHIoKS5zdGFydHNXaXRoKHByZWZpeCwgdG9mZnNldCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgIHRoZSBwcmVmaXguCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIE5vdGUgYWxzbyB0aGF0IDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgYmUgcmV0dXJuZWQgaWYgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGFuIGVtcHR5IHN0cmluZyBvciBpcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFzIGRldGVybWluZWQgYnkgdGhlCi0gICAqICAgICAgICAgIHtAbGluayAjZXF1YWxzKE9iamVjdCl9IG1ldGhvZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoU3RyaW5nIHByZWZpeCkKLSAgewotICAgIHJldHVybiBzdGFydHNXaXRoKHByZWZpeCwgMCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXggYmVnaW5uaW5nCi0gICAqIGEgc3BlY2lmaWVkIGluZGV4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICAgdGhlIHByZWZpeC4KLSAgICogQHBhcmFtICAgdG9mZnNldCAgIHdoZXJlIHRvIGJlZ2luIGxvb2tpbmcgaW4gdGhlIHN0cmluZy4KLSAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGUKLSAgICogICAgICAgICAgYXJndW1lbnQgaXMgYSBwcmVmaXggb2YgdGhlIHN1YnN0cmluZyBvZiB0aGlzIG9iamVjdCBzdGFydGluZwotICAgKiAgICAgICAgICBhdCBpbmRleCA8Y29kZT50b2Zmc2V0PC9jb2RlPjsgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogICAgICAgICAgVGhlIHJlc3VsdCBpcyA8Y29kZT5mYWxzZTwvY29kZT4gaWYgPGNvZGU+dG9mZnNldDwvY29kZT4gaXMKLSAgICogICAgICAgICAgbmVnYXRpdmUgb3IgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdDsgb3RoZXJ3aXNlIHRoZSByZXN1bHQgaXMgdGhlIHNhbWUKLSAgICogICAgICAgICAgYXMgdGhlIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbgotICAgKiAgICAgICAgICA8cHJlPgotICAgKiAgICAgICAgICB0aGlzLnN1YlN0cmluZyh0b2Zmc2V0KS5zdGFydHNXaXRoKHByZWZpeCkKLSAgICogICAgICAgICAgPC9wcmU+Ci0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBzdGFydHNXaXRoKFhNTFN0cmluZyBwcmVmaXgsIGludCB0b2Zmc2V0KQotICB7Ci0KLSAgICBpbnQgdG8gPSB0b2Zmc2V0OwotICAgIGludCB0bGltID0gdGhpcy5sZW5ndGgoKTsKLSAgICBpbnQgcG8gPSAwOwotICAgIGludCBwYyA9IHByZWZpeC5sZW5ndGgoKTsKLQotICAgIC8vIE5vdGU6IHRvZmZzZXQgbWlnaHQgYmUgbmVhciAtMT4+PjEuCi0gICAgaWYgKCh0b2Zmc2V0IDwgMCkgfHwgKHRvZmZzZXQgPiB0bGltIC0gcGMpKQotICAgIHsKLSAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0KLSAgICB3aGlsZSAoLS1wYyA+PSAwKQotICAgIHsKLSAgICAgIGlmICh0aGlzLmNoYXJBdCh0bykgIT0gcHJlZml4LmNoYXJBdChwbykpCi0gICAgICB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgIH0KLQotICAgICAgdG8rKzsKLSAgICAgIHBvKys7Ci0gICAgfQotCi0gICAgcmV0dXJuIHRydWU7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgIHRoZSBwcmVmaXguCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcHJlZml4IG9mIHRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkKLSAgICogICAgICAgICAgdGhpcyBzdHJpbmc7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqICAgICAgICAgIE5vdGUgYWxzbyB0aGF0IDxjb2RlPnRydWU8L2NvZGU+IHdpbGwgYmUgcmV0dXJuZWQgaWYgdGhlCi0gICAqICAgICAgICAgIGFyZ3VtZW50IGlzIGFuIGVtcHR5IHN0cmluZyBvciBpcyBlcXVhbCB0byB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGFzIGRldGVybWluZWQgYnkgdGhlCi0gICAqICAgICAgICAgIHtAbGluayAjZXF1YWxzKE9iamVjdCl9IG1ldGhvZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCkKLSAgewotICAgIHJldHVybiBzdGFydHNXaXRoKHByZWZpeCwgMCk7Ci0gIH0KLQotICAvKioKLSAgICogVGVzdHMgaWYgdGhpcyBzdHJpbmcgZW5kcyB3aXRoIHRoZSBzcGVjaWZpZWQgc3VmZml4LgotICAgKgotICAgKiBAcGFyYW0gICBzdWZmaXggICB0aGUgc3VmZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHN1ZmZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgb2JqZWN0OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLiBOb3RlIHRoYXQgdGhlCi0gICAqICAgICAgICAgIHJlc3VsdCB3aWxsIGJlIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBhcmd1bWVudCBpcyB0aGUKLSAgICogICAgICAgICAgZW1wdHkgc3RyaW5nIG9yIGlzIGVxdWFsIHRvIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QKLSAgICogICAgICAgICAgYXMgZGV0ZXJtaW5lZCBieSB0aGUge0BsaW5rICNlcXVhbHMoT2JqZWN0KX0gbWV0aG9kLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdWZmaXg8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZW5kc1dpdGgoU3RyaW5nIHN1ZmZpeCkKLSAgewotICAgIHJldHVybiBzdHIoKS5lbmRzV2l0aChzdWZmaXgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBoYXNoY29kZSBmb3IgdGhpcyBzdHJpbmcuIFRoZSBoYXNoY29kZSBmb3IgYQotICAgKiA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBpcyBjb21wdXRlZCBhcwotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiBzWzBdKjMxXihuLTEpICsgc1sxXSozMV4obi0yKSArIC4uLiArIHNbbi0xXQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIHVzaW5nIDxjb2RlPmludDwvY29kZT4gYXJpdGhtZXRpYywgd2hlcmUgPGNvZGU+c1tpXTwvY29kZT4gaXMgdGhlCi0gICAqIDxpPmk8L2k+dGggY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcsIDxjb2RlPm48L2NvZGU+IGlzIHRoZSBsZW5ndGggb2YKLSAgICogdGhlIHN0cmluZywgYW5kIDxjb2RlPl48L2NvZGU+IGluZGljYXRlcyBleHBvbmVudGlhdGlvbi4KLSAgICogKFRoZSBoYXNoIHZhbHVlIG9mIHRoZSBlbXB0eSBzdHJpbmcgaXMgemVyby4pCi0gICAqCi0gICAqIEByZXR1cm4gIGEgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgaGFzaENvZGUoKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmhhc2hDb2RlKCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMKLSAgICogaW4gdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkIC0tCi0gICAqIHRoYXQgaXMsIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KDxpPms8L2k+KSA9PSBjaAotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LiBJZiBubyBzdWNoIGNoYXJhY3RlciBvY2N1cnMgaW4gdGhpcyBzdHJpbmcsCi0gICAqIHRoZW4gPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgIGEgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LCBvcgotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgY2gpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuaW5kZXhPZihjaCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLCBzdGFydGluZyB0aGUgc2VhcmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIDxwPgotICAgKiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMgaW4gdGhlIGNoYXJhY3RlcgotICAgKiBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGF0IGFuIGluZGV4Ci0gICAqIG5vIHNtYWxsZXIgdGhhbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QKLSAgICogc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkLS10aGF0IGlzLCB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4KLSAgICogc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAodGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoKSAmJiAoPGk+azwvaT4gPj0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuIElmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZyBhdCBvciBhZnRlcgotICAgKiBwb3NpdGlvbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGlzIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZiBpdAotICAgKiBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIHplcm86IHRoaXMgZW50aXJlCi0gICAqIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZgotICAgKiB0aGlzIHN0cmluZzogPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgICAgICAgICBhIGNoYXJhY3Rlci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB0aGF0IGlzIGdyZWF0ZXIKLSAgICogICAgICAgICAgdGhhbiBvciBlcXVhbCB0byA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4KLSAgICogICAgICAgICAgaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgY2gsIGludCBmcm9tSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuaW5kZXhPZihjaCwgZnJvbUluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUKLSAgICogc3BlY2lmaWVkIGNoYXJhY3Rlci4gVGhhdCBpcywgdGhlIGluZGV4IHJldHVybmVkIGlzIHRoZSBsYXJnZXN0Ci0gICAqIHZhbHVlIDxpPms8L2k+IHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4KLSAgICogVGhlIFN0cmluZyBpcyBzZWFyY2hlZCBiYWNrd2FyZHMgc3RhcnRpbmcgYXQgdGhlIGxhc3QgY2hhcmFjdGVyLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgIGEgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY2hhcmFjdGVyIGluIHRoZQotICAgKiAgICAgICAgICBjaGFyYWN0ZXIgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QsIG9yCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyLgotICAgKi8KLSAgcHVibGljIGludCBsYXN0SW5kZXhPZihpbnQgY2gpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkubGFzdEluZGV4T2YoY2gpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGlzIHN0cmluZyBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLCBzZWFyY2hpbmcgYmFja3dhcmQgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZAotICAgKiBpbmRleC4gVGhhdCBpcywgdGhlIGluZGV4IHJldHVybmVkIGlzIHRoZSBsYXJnZXN0IHZhbHVlIDxpPms8L2k+Ci0gICAqIHN1Y2ggdGhhdDoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogdGhpcy5jaGFyQXQoaykgPT0gY2gpICYmIChrIDw9IGZyb21JbmRleCkKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyB0cnVlLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgICAgICAgICBhIGNoYXJhY3Rlci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4gVGhlcmUgaXMgbm8KLSAgICogICAgICAgICAgcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIDxjb2RlPmZyb21JbmRleDwvY29kZT4uIElmIGl0IGlzCi0gICAqICAgICAgICAgIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nLCBpdCBoYXMKLSAgICogICAgICAgICAgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gb25lIGxlc3MgdGhhbiB0aGUKLSAgICogICAgICAgICAgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nOiB0aGlzIGVudGlyZSBzdHJpbmcgbWF5IGJlIHNlYXJjaGVkLgotICAgKiAgICAgICAgICBJZiBpdCBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIC0xOgotICAgKiAgICAgICAgICAtMSBpcyByZXR1cm5lZC4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0IHRoYXQgaXMgbGVzcwotICAgKiAgICAgICAgICB0aGFuIG9yIGVxdWFsIHRvIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIG9yIDxjb2RlPi0xPC9jb2RlPgotICAgKiAgICAgICAgICBpZiB0aGUgY2hhcmFjdGVyIGRvZXMgbm90IG9jY3VyIGJlZm9yZSB0aGF0IHBvaW50LgotICAgKi8KLSAgcHVibGljIGludCBsYXN0SW5kZXhPZihpbnQgY2gsIGludCBmcm9tSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkubGFzdEluZGV4T2YoY2gsIGZyb21JbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgc3Vic3RyaW5nLiBUaGUgaW50ZWdlciByZXR1cm5lZCBpcyB0aGUgc21hbGxlc3QgdmFsdWUKLSAgICogPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCA8aT5rPC9pPikKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgYW55IHN0cmluZy4KLSAgICogQHJldHVybiAgaWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgYXMgYSBzdWJzdHJpbmcgd2l0aGluIHRoaXMKLSAgICogICAgICAgICAgb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBmaXJzdAotICAgKiAgICAgICAgICBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZDsgaWYgaXQgZG9lcyBub3Qgb2NjdXIgYXMgYQotICAgKiAgICAgICAgICBzdWJzdHJpbmcsIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihTdHJpbmcgc3RyKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmluZGV4T2Yoc3RyKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhpcyBzdHJpbmcgb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlCi0gICAqIHNwZWNpZmllZCBzdWJzdHJpbmcuIFRoZSBpbnRlZ2VyIHJldHVybmVkIGlzIHRoZSBzbWFsbGVzdCB2YWx1ZQotICAgKiA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIDxpPms8L2k+KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICBhbnkgc3RyaW5nLgotICAgKiBAcmV0dXJuICBpZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBhcyBhIHN1YnN0cmluZyB3aXRoaW4gdGhpcwotICAgKiAgICAgICAgICBvYmplY3QsIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGZpcnN0Ci0gICAqICAgICAgICAgIHN1Y2ggc3Vic3RyaW5nIGlzIHJldHVybmVkOyBpZiBpdCBkb2VzIG5vdCBvY2N1ciBhcyBhCi0gICAqICAgICAgICAgIHN1YnN0cmluZywgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKFhNTFN0cmluZyBzdHIpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuaW5kZXhPZihzdHIudG9TdHJpbmcoKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgc3Vic3RyaW5nLCBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LiBUaGUgaW50ZWdlcgotICAgKiByZXR1cm5lZCBpcyB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiB0aGlzLnN0YXJ0c1dpdGgoc3RyLCA8aT5rPC9pPikgJiYgKDxpPms8L2k+ID49IGZyb21JbmRleCkKLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiBpcyA8Y29kZT50cnVlPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGlzIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZgotICAgKiBpdCBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIHplcm86IHRoaXMgZW50aXJlCi0gICAqIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZgotICAgKiB0aGlzIHN0cmluZzogPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBzdHIgICAgICAgICB0aGUgc3Vic3RyaW5nIHRvIHNlYXJjaCBmb3IuCi0gICAqIEBwYXJhbSAgIGZyb21JbmRleCAgIHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uCi0gICAqIEByZXR1cm4gIElmIHRoZSBzdHJpbmcgYXJndW1lbnQgb2NjdXJzIGFzIGEgc3Vic3RyaW5nIHdpdGhpbiB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdCBhdCBhIHN0YXJ0aW5nIGluZGV4IG5vIHNtYWxsZXIgdGhhbgotICAgKiAgICAgICAgICA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyCi0gICAqICAgICAgICAgIG9mIHRoZSBmaXJzdCBzdWNoIHN1YnN0cmluZyBpcyByZXR1cm5lZC4gSWYgaXQgZG9lcyBub3Qgb2NjdXIKLSAgICogICAgICAgICAgYXMgYSBzdWJzdHJpbmcgc3RhcnRpbmcgYXQgPGNvZGU+ZnJvbUluZGV4PC9jb2RlPiBvciBiZXlvbmQsCi0gICAqICAgICAgICAgIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+c3RyPC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPgotICAgKi8KLSAgcHVibGljIGludCBpbmRleE9mKFN0cmluZyBzdHIsIGludCBmcm9tSW5kZXgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCkuaW5kZXhPZihzdHIsIGZyb21JbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSByaWdodG1vc3Qgb2NjdXJyZW5jZQotICAgKiBvZiB0aGUgc3BlY2lmaWVkIHN1YnN0cmluZy4gIFRoZSByaWdodG1vc3QgZW1wdHkgc3RyaW5nICIiIGlzCi0gICAqIGNvbnNpZGVyZWQgdG8gb2NjdXIgYXQgdGhlIGluZGV4IHZhbHVlIDxjb2RlPnRoaXMubGVuZ3RoKCk8L2NvZGU+LgotICAgKiBUaGUgcmV0dXJuZWQgaW5kZXggaXMgdGhlIGxhcmdlc3QgdmFsdWUgPGk+azwvaT4gc3VjaCB0aGF0Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuc3RhcnRzV2l0aChzdHIsIGspCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICogaXMgdHJ1ZS4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgdGhlIHN1YnN0cmluZyB0byBzZWFyY2ggZm9yLgotICAgKiBAcmV0dXJuICBpZiB0aGUgc3RyaW5nIGFyZ3VtZW50IG9jY3VycyBvbmUgb3IgbW9yZSB0aW1lcyBhcyBhIHN1YnN0cmluZwotICAgKiAgICAgICAgICB3aXRoaW4gdGhpcyBvYmplY3QsIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YKLSAgICogICAgICAgICAgdGhlIGxhc3Qgc3VjaCBzdWJzdHJpbmcgaXMgcmV0dXJuZWQuIElmIGl0IGRvZXMgbm90IG9jY3VyIGFzCi0gICAqICAgICAgICAgIGEgc3Vic3RyaW5nLCA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uICBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGludCBsYXN0SW5kZXhPZihTdHJpbmcgc3RyKQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmxhc3RJbmRleE9mKHN0cik7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YKLSAgICogdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgICAgICAgIHRoZSBzdWJzdHJpbmcgdG8gc2VhcmNoIGZvci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4gVGhlcmUgaXMgbm8KLSAgICogICAgICAgICAgcmVzdHJpY3Rpb24gb24gdGhlIHZhbHVlIG9mIGZyb21JbmRleC4gSWYgaXQgaXMgZ3JlYXRlciB0aGFuCi0gICAqICAgICAgICAgIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcsIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQKLSAgICogICAgICAgICAgd2VyZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nOiB0aGlzIGVudGlyZSBzdHJpbmcKLSAgICogICAgICAgICAgbWF5IGJlIHNlYXJjaGVkLiBJZiBpdCBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdAotICAgKiAgICAgICAgICBhcyBpZiBpdCB3ZXJlIC0xOiAtMSBpcyByZXR1cm5lZC4KLSAgICogQHJldHVybiAgSWYgdGhlIHN0cmluZyBhcmd1bWVudCBvY2N1cnMgb25lIG9yIG1vcmUgdGltZXMgYXMgYSBzdWJzdHJpbmcKLSAgICogICAgICAgICAgd2l0aGluIHRoaXMgb2JqZWN0IGF0IGEgc3RhcnRpbmcgaW5kZXggbm8gZ3JlYXRlciB0aGFuCi0gICAqICAgICAgICAgIDxjb2RlPmZyb21JbmRleDwvY29kZT4sIHRoZW4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YKLSAgICogICAgICAgICAgdGhlIGxhc3Qgc3VjaCBzdWJzdHJpbmcgaXMgcmV0dXJuZWQuIElmIGl0IGRvZXMgbm90IG9jY3VyIGFzIGEKLSAgICogICAgICAgICAgc3Vic3RyaW5nIHN0YXJ0aW5nIGF0IDxjb2RlPmZyb21JbmRleDwvY29kZT4gb3IgZWFybGllciwKLSAgICogICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIGludCBsYXN0SW5kZXhPZihTdHJpbmcgc3RyLCBpbnQgZnJvbUluZGV4KQotICB7Ci0gICAgcmV0dXJuIHN0cigpLmxhc3RJbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB0aGF0IGlzIGEgc3Vic3RyaW5nIG9mIHRoaXMgc3RyaW5nLiBUaGUKLSAgICogc3Vic3RyaW5nIGJlZ2lucyB3aXRoIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBhbmQKLSAgICogZXh0ZW5kcyB0byB0aGUgZW5kIG9mIHRoaXMgc3RyaW5nLiA8cD4KLSAgICogRXhhbXBsZXM6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqICJ1bmhhcHB5Ii5zdWJzdHJpbmcoMikgcmV0dXJucyAiaGFwcHkiCi0gICAqICJIYXJiaXNvbiIuc3Vic3RyaW5nKDMpIHJldHVybnMgImJpc29uIgotICAgKiAiZW1wdGluZXNzIi5zdWJzdHJpbmcoOSkgcmV0dXJucyAiIiAoYW4gZW1wdHkgc3RyaW5nKQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqCi0gICAqIEBwYXJhbSAgICAgIGJlZ2luSW5kZXggICB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmUuCi0gICAqIEByZXR1cm4gICAgIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZgotICAgKiAgICAgICAgICAgICA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBpcyBuZWdhdGl2ZSBvciBsYXJnZXIgdGhhbiB0aGUKLSAgICogICAgICAgICAgICAgbGVuZ3RoIG9mIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHN1YnN0cmluZyhpbnQgYmVnaW5JbmRleCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS5zdWJzdHJpbmcoYmVnaW5JbmRleCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHRoYXQgaXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcuIFRoZQotICAgKiBzdWJzdHJpbmcgYmVnaW5zIGF0IHRoZSBzcGVjaWZpZWQgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gYW5kCi0gICAqIGV4dGVuZHMgdG8gdGhlIGNoYXJhY3RlciBhdCBpbmRleCA8Y29kZT5lbmRJbmRleCAtIDE8L2NvZGU+LgotICAgKiBUaHVzIHRoZSBsZW5ndGggb2YgdGhlIHN1YnN0cmluZyBpcyA8Y29kZT5lbmRJbmRleC1iZWdpbkluZGV4PC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtICAgICAgYmVnaW5JbmRleCAgIHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZS4KLSAgICogQHBhcmFtICAgICAgZW5kSW5kZXggICAgIHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZS4KLSAgICogQHJldHVybiAgICAgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmIHRoZQotICAgKiAgICAgICAgICAgICA8Y29kZT5iZWdpbkluZGV4PC9jb2RlPiBpcyBuZWdhdGl2ZSwgb3IKLSAgICogICAgICAgICAgICAgPGNvZGU+ZW5kSW5kZXg8L2NvZGU+IGlzIGxhcmdlciB0aGFuIHRoZSBsZW5ndGggb2YKLSAgICogICAgICAgICAgICAgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCwgb3IKLSAgICogICAgICAgICAgICAgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gaXMgbGFyZ2VyIHRoYW4KLSAgICogICAgICAgICAgICAgPGNvZGU+ZW5kSW5kZXg8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBzdWJzdHJpbmcoaW50IGJlZ2luSW5kZXgsIGludCBlbmRJbmRleCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS5zdWJzdHJpbmcoYmVnaW5JbmRleCwgZW5kSW5kZXgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25jYXRlbmF0ZXMgdGhlIHNwZWNpZmllZCBzdHJpbmcgdG8gdGhlIGVuZCBvZiB0aGlzIHN0cmluZy4KLSAgICoKLSAgICogQHBhcmFtICAgc3RyICAgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdGhhdCBpcyBjb25jYXRlbmF0ZWQgdG8gdGhlIGVuZAotICAgKiAgICAgICAgICAgICAgICBvZiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4uCi0gICAqIEByZXR1cm4gIGEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyB0aGUgY29uY2F0ZW5hdGlvbiBvZiB0aGlzIG9iamVjdCdzCi0gICAqICAgICAgICAgIGNoYXJhY3RlcnMgZm9sbG93ZWQgYnkgdGhlIHN0cmluZyBhcmd1bWVudCdzIGNoYXJhY3RlcnMuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnN0cjwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGNvbmNhdChTdHJpbmcgc3RyKQotICB7Ci0KLSAgICAvLyAlUkVWSUVXJSBNYWtlIGFuIEZTQiBoZXJlPwotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS5jb25jYXQoc3RyKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydHMgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBsb3dlcgotICAgKiBjYXNlIHVzaW5nIHRoZSBydWxlcyBvZiB0aGUgZ2l2ZW4gPGNvZGU+TG9jYWxlPC9jb2RlPi4KLSAgICoKLSAgICogQHBhcmFtIGxvY2FsZSB1c2UgdGhlIGNhc2UgdHJhbnNmb3JtYXRpb24gcnVsZXMgZm9yIHRoaXMgbG9jYWxlCi0gICAqIEByZXR1cm4gdGhlIFN0cmluZywgY29udmVydGVkIHRvIGxvd2VyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b0xvd2VyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvVXBwZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdG9Mb3dlckNhc2UoTG9jYWxlIGxvY2FsZSkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS50b0xvd2VyQ2FzZShsb2NhbGUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGxvd2VyCi0gICAqIGNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSBkZWZhdWx0IGxvY2FsZSwgd2hpY2ggaXMgcmV0dXJuZWQKLSAgICogYnkgPGNvZGU+TG9jYWxlLmdldERlZmF1bHQ8L2NvZGU+LgotICAgKiA8cD4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIHN0cmluZywgY29udmVydGVkIHRvIGxvd2VyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b0xvd2VyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvTG93ZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdG9Mb3dlckNhc2UoKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYU3RyaW5nKHN0cigpLnRvTG93ZXJDYXNlKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbnZlcnRzIGFsbCBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gdXBwZXIKLSAgICogY2FzZSB1c2luZyB0aGUgcnVsZXMgb2YgdGhlIGdpdmVuIGxvY2FsZS4KLSAgICogQHBhcmFtIGxvY2FsZSB1c2UgdGhlIGNhc2UgdHJhbnNmb3JtYXRpb24gcnVsZXMgZm9yIHRoaXMgbG9jYWxlCi0gICAqIEByZXR1cm4gdGhlIFN0cmluZywgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b1VwcGVyQ2FzZShjaGFyKQotICAgKiBAc2VlICAgICBqYXZhLmxhbmcuU3RyaW5nI3RvTG93ZXJDYXNlKExvY2FsZSkKLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdG9VcHBlckNhc2UoTG9jYWxlIGxvY2FsZSkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS50b1VwcGVyQ2FzZShsb2NhbGUpKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb252ZXJ0cyBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIHVwcGVyCi0gICAqIGNhc2UgdXNpbmcgdGhlIHJ1bGVzIG9mIHRoZSBkZWZhdWx0IGxvY2FsZSwgd2hpY2ggaXMgcmV0dXJuZWQKLSAgICogYnkgPGNvZGU+TG9jYWxlLmdldERlZmF1bHQ8L2NvZGU+LgotICAgKgotICAgKiA8cD4KLSAgICogSWYgbm8gY2hhcmFjdGVyIGluIHRoaXMgc3RyaW5nIGhhcyBhIGRpZmZlcmVudCB1cHBlcmNhc2UgdmVyc2lvbiwKLSAgICogYmFzZWQgb24gY2FsbGluZyB0aGUgPGNvZGU+dG9VcHBlckNhc2U8L2NvZGU+IG1ldGhvZCBkZWZpbmVkIGJ5Ci0gICAqIDxjb2RlPkNoYXJhY3RlcjwvY29kZT4sIHRoZW4gdGhlIG9yaWdpbmFsIHN0cmluZyBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIE90aGVyd2lzZSwgdGhpcyBtZXRob2QgY3JlYXRlcyBhIG5ldyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdAotICAgKiByZXByZXNlbnRpbmcgYSBjaGFyYWN0ZXIgc2VxdWVuY2UgaWRlbnRpY2FsIGluIGxlbmd0aCB0byB0aGUKLSAgICogY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgYW5kCi0gICAqIHdpdGggZXZlcnkgY2hhcmFjdGVyIGVxdWFsIHRvIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlIG1ldGhvZAotICAgKiA8Y29kZT5DaGFyYWN0ZXIudG9VcHBlckNhc2U8L2NvZGU+IHRvIHRoZSBjb3JyZXNwb25kaW5nIGNoYXJhY3RlciBvZgotICAgKiB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0LiA8cD4KLSAgICogRXhhbXBsZXM6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqICJGYWhydmVyZ278Z2VuIi50b1VwcGVyQ2FzZSgpIHJldHVybnMgIkZBSFJWRVJHTtxHRU4iCi0gICAqICJWaXNpdCBManViaW5qZSEiLnRvVXBwZXJDYXNlKCkgcmV0dXJucyAiVklTSVQgTEpVQklOSkUhIgotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqCi0gICAqIEByZXR1cm4gIHRoZSBzdHJpbmcsIGNvbnZlcnRlZCB0byB1cHBlcmNhc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9VcHBlckNhc2UoY2hhcikKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyN0b1VwcGVyQ2FzZShMb2NhbGUpCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRvVXBwZXJDYXNlKCkKLSAgewotICAgIHJldHVybiBuZXcgWFN0cmluZyhzdHIoKS50b1VwcGVyQ2FzZSgpKTsKLSAgfQotCi0gIC8qKgotICAgKiBSZW1vdmVzIHdoaXRlIHNwYWNlIGZyb20gYm90aCBlbmRzIG9mIHRoaXMgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuICB0aGlzIHN0cmluZywgd2l0aCB3aGl0ZSBzcGFjZSByZW1vdmVkIGZyb20gdGhlIGZyb250IGFuZCBlbmQuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIHRyaW0oKQotICB7Ci0gICAgcmV0dXJuIG5ldyBYU3RyaW5nKHN0cigpLnRyaW0oKSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgPHZhcj5jaDwvdmFyPiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uCi0gICAqIG9mIHdoaXRlc3BhY2UuICBSZWZlciB0byA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy14bWwtMTk5ODAyMTAjTlQtUyI+Ci0gICAqIHRoZSBkZWZpbml0aW9uIG9mIDxDT0RFPlM8L0NPREU+PC9BPiBmb3IgZGV0YWlscy4KLSAgICogQHBhcmFtICAgY2ggICAgICBDaGFyYWN0ZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gICAgICAgICAgPXRydWUgaWYgPHZhcj5jaDwvdmFyPiBpcyBYTUwgd2hpdGVzcGFjZTsgb3RoZXJ3aXNlID1mYWxzZS4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShjaGFyIGNoKQotICB7Ci0gICAgcmV0dXJuIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoKTsgIC8vIFRha2UgdGhlIGVhc3kgd2F5IG91dCBmb3Igbm93LgotICB9Ci0KLSAgLyoqCi0gICAqIENvbmRpdGlvbmFsbHkgdHJpbSBhbGwgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBpbiB0aGUgc3BlY2lmaWVkIFN0cmluZy4KLSAgICogQWxsIHN0cmluZ3Mgb2Ygd2hpdGUgc3BhY2UgYXJlCi0gICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIHNwYWNlIGNoYXJhY3RlciAoI3gyMCksIGV4Y2VwdCBzcGFjZXMgYWZ0ZXIgcHVuY3R1YXRpb24gd2hpY2gKLSAgICogcmVjZWl2ZSBkb3VibGUgc3BhY2VzIGlmIGRvdWJsZVB1bmN0dWF0aW9uU3BhY2VzIGlzIHRydWUuCi0gICAqIFRoaXMgZnVuY3Rpb24gbWF5IGJlIHVzZWZ1bCB0byBhIGZvcm1hdHRlciwgYnV0IHRvIGdldCBmaXJzdCBjbGFzcwotICAgKiByZXN1bHRzLCB0aGUgZm9ybWF0dGVyIHNob3VsZCBwcm9iYWJseSBkbyBpdCdzIG93biB3aGl0ZSBzcGFjZSBoYW5kbGluZwotICAgKiBiYXNlZCBvbiB0aGUgc2VtYW50aWNzIG9mIHRoZSBmb3JtYXR0aW5nIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtICAgdHJpbUhlYWQgICAgVHJpbSBsZWFkaW5nIHdoaXRlc3BhY2U/Ci0gICAqIEBwYXJhbSAgIHRyaW1UYWlsICAgIFRyaW0gdHJhaWxpbmcgd2hpdGVzcGFjZT8KLSAgICogQHBhcmFtICAgZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgICAgVXNlIGRvdWJsZSBzcGFjZXMgZm9yIHB1bmN0dWF0aW9uPwotICAgKiBAcmV0dXJuICAgICAgICAgICAgICBUaGUgdHJpbW1lZCBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGZpeFdoaXRlU3BhY2UoYm9vbGVhbiB0cmltSGVhZCwgYm9vbGVhbiB0cmltVGFpbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG91YmxlUHVuY3R1YXRpb25TcGFjZXMpCi0gIHsKLQotICAgIC8vICVPUFQlICEhISEhISEKLSAgICBpbnQgbGVuID0gdGhpcy5sZW5ndGgoKTsKLSAgICBjaGFyW10gYnVmID0gbmV3IGNoYXJbbGVuXTsKLQotICAgIHRoaXMuZ2V0Q2hhcnMoMCwgbGVuLCBidWYsIDApOwotCi0gICAgYm9vbGVhbiBlZGl0ID0gZmFsc2U7Ci0gICAgaW50IHM7Ci0KLSAgICBmb3IgKHMgPSAwOyBzIDwgbGVuOyBzKyspCi0gICAgewotICAgICAgaWYgKGlzU3BhY2UoYnVmW3NdKSkKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgLyogcmVwbGFjZSBTIHRvICcgJy4gYW5kICcgJysgLT4gc2luZ2xlICcgJy4gKi8KLSAgICBpbnQgZCA9IHM7Ci0gICAgYm9vbGVhbiBwcmVzID0gZmFsc2U7Ci0KLSAgICBmb3IgKDsgcyA8IGxlbjsgcysrKQotICAgIHsKLSAgICAgIGNoYXIgYyA9IGJ1ZltzXTsKLQotICAgICAgaWYgKGlzU3BhY2UoYykpCi0gICAgICB7Ci0gICAgICAgIGlmICghcHJlcykKLSAgICAgICAgewotICAgICAgICAgIGlmICgnICcgIT0gYykKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBlZGl0ID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgICBidWZbZCsrXSA9ICcgJzsKLQotICAgICAgICAgIGlmIChkb3VibGVQdW5jdHVhdGlvblNwYWNlcyAmJiAocyAhPSAwKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBjaGFyIHByZXZDaGFyID0gYnVmW3MgLSAxXTsKLQotICAgICAgICAgICAgaWYgKCEoKHByZXZDaGFyID09ICcuJykgfHwgKHByZXZDaGFyID09ICchJykKLSAgICAgICAgICAgICAgICAgIHx8IChwcmV2Q2hhciA9PSAnPycpKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcHJlcyA9IHRydWU7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGVsc2UKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwcmVzID0gdHJ1ZTsKLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgZWRpdCA9IHRydWU7Ci0gICAgICAgICAgcHJlcyA9IHRydWU7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgYnVmW2QrK10gPSBjOwotICAgICAgICBwcmVzID0gZmFsc2U7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgaWYgKHRyaW1UYWlsICYmIDEgPD0gZCAmJiAnICcgPT0gYnVmW2QgLSAxXSkKLSAgICB7Ci0gICAgICBlZGl0ID0gdHJ1ZTsKLQotICAgICAgZC0tOwotICAgIH0KLQotICAgIGludCBzdGFydCA9IDA7Ci0KLSAgICBpZiAodHJpbUhlYWQgJiYgMCA8IGQgJiYgJyAnID09IGJ1ZlswXSkKLSAgICB7Ci0gICAgICBlZGl0ID0gdHJ1ZTsKLQotICAgICAgc3RhcnQrKzsKLSAgICB9Ci0KLSAgICBYTUxTdHJpbmdGYWN0b3J5IHhzZiA9IFhNTFN0cmluZ0ZhY3RvcnlJbXBsLmdldEZhY3RvcnkoKTsKLQotICAgIHJldHVybiBlZGl0ID8geHNmLm5ld3N0cihuZXcgU3RyaW5nKGJ1Ziwgc3RhcnQsIGQgLSBzdGFydCkpIDogdGhpczsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YU3RyaW5nRm9yQ2hhcnMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvWFN0cmluZ0ZvckNoYXJzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDg5MDRiNzguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YU3RyaW5nRm9yQ2hhcnMuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDIwMSArMCwwIEBACi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0czsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLkZhc3RTdHJpbmdCdWZmZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlhNTFN0cmluZ0ZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MQ2hhcmFjdGVyUmVjb2duaXplcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgucmVzLlhQQVRIRXJyb3JSZXNvdXJjZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwotCi0KLS8qKgotICogVGhpcyBjbGFzcyB3aWxsIHdyYXAgYSBGYXN0U3RyaW5nQnVmZmVyIGFuZCBhbGxvdyBmb3IKLSAqLwotcHVibGljIGNsYXNzIFhTdHJpbmdGb3JDaGFycyBleHRlbmRzIFhTdHJpbmcKLXsKLSAgLyoqIFRoZSBzdGFydCBwb3NpdGlvbiBpbiB0aGUgZnNiLiAqLwotICBpbnQgbV9zdGFydDsKLSAgCi0gIC8qKiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcuICovCi0gIGludCBtX2xlbmd0aDsKLSAgCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9zdHJDYWNoZSA9IG51bGw7Ci0gIAotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gdmFsIEZhc3RTdHJpbmdCdWZmZXIgb2JqZWN0IHRoaXMgd2lsbCB3cmFwLCBtdXN0IGJlIG5vbi1udWxsLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICovCi0gIHB1YmxpYyBYU3RyaW5nRm9yQ2hhcnMoY2hhcltdIHZhbCwgaW50IHN0YXJ0LCBpbnQgbGVuZ3RoKQotICB7Ci0gICAgc3VwZXIodmFsKTsKLSAgICBtX3N0YXJ0ID0gc3RhcnQ7Ci0gICAgbV9sZW5ndGggPSBsZW5ndGg7Ci0gICAgaWYobnVsbCA9PSB2YWwpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xNZXNzYWdlcy5jcmVhdGVYUEFUSE1lc3NhZ2UoWFBBVEhFcnJvclJlc291cmNlcy5FUl9GQVNUU1RSSU5HQlVGRkVSX0NBTk5PVF9CRV9OVUxMLCBudWxsKSk7IC8vIlRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCEhIik7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgU3RyaW5nIG9iamVjdCB0aGlzIHdpbGwgd3JhcC4KLSAgICovCi0gIHByaXZhdGUgWFN0cmluZ0ZvckNoYXJzKFN0cmluZyB2YWwpCi0gIHsKLSAgICBzdXBlcih2YWwpOwotICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCi0gICAgICAgICAgICAgICAgICAgICAgWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORywgbnVsbCkpOyAvLyJYU3RyaW5nRm9yQ2hhcnMgY2FuIG5vdCB0YWtlIGEgc3RyaW5nIGZvciBhbiBhcmd1bWVudCEiKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgRmFzdFN0cmluZ0J1ZmZlciBmc2IoKQotICB7Ci0gICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfRlNCX05PVF9TVVBQT1JURURfWFNUUklOR0ZPUkNIQVJTLCBudWxsKSk7IC8vImZzYigpIG5vdCBzdXBwb3J0ZWQgZm9yIFhTdHJpbmdGb3JDaGFycyEiKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIENhc3QgcmVzdWx0IG9iamVjdCB0byBhIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiBUaGUgc3RyaW5nIHRoaXMgd3JhcHMgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBudWxsCi0gICAqLwotICBwdWJsaWMgdm9pZCBhcHBlbmRUb0ZzYihvcmcuYXBhY2hlLnhtbC51dGlscy5GYXN0U3RyaW5nQnVmZmVyIGZzYikKLSAgewotICAgIGZzYi5hcHBlbmQoKGNoYXJbXSltX29iaiwgbV9zdGFydCwgbV9sZW5ndGgpOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgb2JqZWN0IGNvbnRhaW5zIGEgamF2YSBTdHJpbmcgb2JqZWN0LgotICAgKiAKLSAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgWE1MU3RyaW5nIGNhbiByZXR1cm4gYSBzdHJpbmcgd2l0aG91dCBjcmVhdGluZyBvbmUuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIChudWxsICE9IG1fc3RyQ2FjaGUpOwotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIFN0cmluZyBzdHIoKQotICB7Ci0gICAgaWYobnVsbCA9PSBtX3N0ckNhY2hlKQotICAgICAgbV9zdHJDYWNoZSA9IG5ldyBTdHJpbmcoKGNoYXJbXSltX29iaiwgbV9zdGFydCwgbV9sZW5ndGgpOwotICAgIAotICAgIHJldHVybiBtX3N0ckNhY2hlOwotICB9Ci0gIAotCi0gIC8qKgotICAgKiBTaW5jZSB0aGlzIG9iamVjdCBpcyBpbmNvbXBsZXRlIHdpdGhvdXQgdGhlIGxlbmd0aCBhbmQgdGhlIG9mZnNldCwgd2UgCi0gICAqIGhhdmUgdG8gY29udmVydCB0byBhIHN0cmluZyB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBqYXZhIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3Qgb2JqZWN0KCkKLSAgewotICAgIHJldHVybiBzdHIoKTsKLSAgfQotCi0gIC8qKgotICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgKiBjaGFyYWN0ZXJzIG1ldGhvZCBvbiB0aGUgcGFzc2VkIENvbnRlbnRIYW5kbGVyIGZvciB0aGUKLSAgICogc3RyaW5nLXZhbHVlLiBNdWx0aXBsZSBjYWxscyB0byB0aGUKLSAgICogQ29udGVudEhhbmRsZXIncyBjaGFyYWN0ZXJzIG1ldGhvZHMgbWF5IHdlbGwgb2NjdXIgZm9yIGEgc2luZ2xlIGNhbGwgdG8KLSAgICogdGhpcyBtZXRob2QuCi0gICAqCi0gICAqIEBwYXJhbSBjaCBBIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIENvbnRlbnRIYW5kbGVyLgotICAgKgotICAgKiBAdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHZvaWQgZGlzcGF0Y2hDaGFyYWN0ZXJzRXZlbnRzKG9yZy54bWwuc2F4LkNvbnRlbnRIYW5kbGVyIGNoKQotICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgY2guY2hhcmFjdGVycygoY2hhcltdKW1fb2JqLCBtX3N0YXJ0LCBtX2xlbmd0aCk7Ci0gIH0KLSAgICAgIAotICAvKioKLSAgICogRGlyZWN0bHkgY2FsbCB0aGUKLSAgICogY29tbWVudCBtZXRob2Qgb24gdGhlIHBhc3NlZCBMZXhpY2FsSGFuZGxlciBmb3IgdGhlCi0gICAqIHN0cmluZy12YWx1ZS4KLSAgICoKLSAgICogQHBhcmFtIGxoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgTGV4aWNhbEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaEFzQ29tbWVudChvcmcueG1sLnNheC5leHQuTGV4aWNhbEhhbmRsZXIgbGgpCi0gICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBsaC5jb21tZW50KChjaGFyW10pbV9vYmosIG1fc3RhcnQsIG1fbGVuZ3RoKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIGxlbmd0aCBvZiB0aGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2xlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gQW4gaW5kZXggcmFuZ2VzCi0gICAqIGZyb20gPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoKCkgLSAxPC9jb2RlPi4gVGhlIGZpcnN0IGNoYXJhY3RlcgotICAgKiBvZiB0aGUgc2VxdWVuY2UgaXMgYXQgaW5kZXggPGNvZGU+MDwvY29kZT4sIHRoZSBuZXh0IGF0IGluZGV4Ci0gICAqIDxjb2RlPjE8L2NvZGU+LCBhbmQgc28gb24sIGFzIGZvciBhcnJheSBpbmRleGluZy4KLSAgICoKLSAgICogQHBhcmFtICAgICAgaW5kZXggICB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgICAgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgc3RyaW5nLgotICAgKiAgICAgICAgICAgICBUaGUgZmlyc3QgY2hhcmFjdGVyIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+Ci0gICAqICAgICAgICAgICAgIGFyZ3VtZW50IGlzIG5lZ2F0aXZlIG9yIG5vdCBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBjaGFyIGNoYXJBdChpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gKChjaGFyW10pbV9vYmopW2luZGV4K21fc3RhcnRdOwotICB9Ci0KLSAgLyoqCi0gICAqIENvcGllcyBjaGFyYWN0ZXJzIGZyb20gdGhpcyBzdHJpbmcgaW50byB0aGUgZGVzdGluYXRpb24gY2hhcmFjdGVyCi0gICAqIGFycmF5LgotICAgKgotICAgKiBAcGFyYW0gICAgICBzcmNCZWdpbiAgIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIHNyY0VuZCAgICAgaW5kZXggYWZ0ZXIgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcKLSAgICogICAgICAgICAgICAgICAgICAgICAgICB0byBjb3B5LgotICAgKiBAcGFyYW0gICAgICBkc3QgICAgICAgIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KLSAgICogQHBhcmFtICAgICAgZHN0QmVnaW4gICB0aGUgc3RhcnQgb2Zmc2V0IGluIHRoZSBkZXN0aW5hdGlvbiBhcnJheS4KLSAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIElmIGFueSBvZiB0aGUgZm9sbG93aW5nCi0gICAqICAgICAgICAgICAgaXMgdHJ1ZToKLSAgICogICAgICAgICAgICA8dWw+PGxpPjxjb2RlPnNyY0JlZ2luPC9jb2RlPiBpcyBuZWdhdGl2ZS4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIGdyZWF0ZXIgdGhhbiA8Y29kZT5zcmNFbmQ8L2NvZGU+Ci0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPnNyY0VuZDwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIHRoZSBsZW5ndGggb2YgdGhpcwotICAgKiAgICAgICAgICAgICAgICBzdHJpbmcKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlCi0gICAqICAgICAgICAgICAgPGxpPjxjb2RlPmRzdEJlZ2luKyhzcmNFbmQtc3JjQmVnaW4pPC9jb2RlPiBpcyBsYXJnZXIgdGhhbgotICAgKiAgICAgICAgICAgICAgICA8Y29kZT5kc3QubGVuZ3RoPC9jb2RlPjwvdWw+Ci0gICAqIEBleGNlcHRpb24gTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+ZHN0PC9jb2RlPiBpcyA8Y29kZT5udWxsPC9jb2RlPgotICAgKi8KLSAgcHVibGljIHZvaWQgZ2V0Q2hhcnMoaW50IHNyY0JlZ2luLCBpbnQgc3JjRW5kLCBjaGFyIGRzdFtdLCBpbnQgZHN0QmVnaW4pCi0gIHsKLSAgICBTeXN0ZW0uYXJyYXljb3B5KChjaGFyW10pbV9vYmosIG1fc3RhcnQrc3JjQmVnaW4sIGRzdCwgZHN0QmVnaW4sIHNyY0VuZCk7Ci0gIH0KLSAgCi19ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cy9YU3RyaW5nRm9yRlNCLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hTdHJpbmdGb3JGU0IuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjI3NjlhNS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL1hTdHJpbmdGb3JGU0IuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNTQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxTdHJpbmc7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuWE1MU3RyaW5nRmFjdG9yeTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5YTUxDaGFyYWN0ZXJSZWNvZ25pemVyOwotCi1pbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKLQotLyoqCi0gKiBUaGlzIGNsYXNzIHdpbGwgd3JhcCBhIEZhc3RTdHJpbmdCdWZmZXIgYW5kIGFsbG93IGZvcgotICovCi1wdWJsaWMgY2xhc3MgWFN0cmluZ0ZvckZTQiBleHRlbmRzIFhTdHJpbmcKLXsKLQotICAvKiogVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBmc2IuICovCi0gIGludCBtX3N0YXJ0OwotCi0gIC8qKiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcuICovCi0gIGludCBtX2xlbmd0aDsKLQotICAvKiogSWYgdGhlIHN0cigpIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhlIHN0cmluZyB3aWxsIGJlIGNhY2hlZCBoZXJlLiAqLwotICBwcm90ZWN0ZWQgU3RyaW5nIG1fc3RyQ2FjaGUgPSBudWxsOwotCi0gIC8qKiBjYWNoZWQgaGFzaCBjb2RlICovCi0gIHByb3RlY3RlZCBpbnQgbV9oYXNoID0gMDsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgWE5vZGVTZXQgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gdmFsIEZhc3RTdHJpbmdCdWZmZXIgb2JqZWN0IHRoaXMgd2lsbCB3cmFwLCBtdXN0IGJlIG5vbi1udWxsLgotICAgKiBAcGFyYW0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uIGluIHRoZSBhcnJheS4KLSAgICogQHBhcmFtIGxlbmd0aCBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVhZCBmcm9tIHRoZSBhcnJheS4KLSAgICovCi0gIHB1YmxpYyBYU3RyaW5nRm9yRlNCKEZhc3RTdHJpbmdCdWZmZXIgdmFsLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCi0gIHsKLQotICAgIHN1cGVyKHZhbCk7Ci0KLSAgICBtX3N0YXJ0ID0gc3RhcnQ7Ci0gICAgbV9sZW5ndGggPSBsZW5ndGg7Ci0KLSAgICBpZiAobnVsbCA9PSB2YWwpCi0gICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAotICAgICAgICAiVGhlIEZhc3RTdHJpbmdCdWZmZXIgYXJndW1lbnQgY2FuIG5vdCBiZSBudWxsISEiKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYSBYTm9kZVNldCBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSB2YWwgU3RyaW5nIG9iamVjdCB0aGlzIHdpbGwgd3JhcC4KLSAgICovCi0gIHByaXZhdGUgWFN0cmluZ0ZvckZTQihTdHJpbmcgdmFsKQotICB7Ci0KLSAgICBzdXBlcih2YWwpOwotCi0gICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKLSAgICAgICJYU3RyaW5nRm9yRlNCIGNhbiBub3QgdGFrZSBhIHN0cmluZyBmb3IgYW4gYXJndW1lbnQhIik7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdGhpcyB3cmFwcyBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG51bGwKLSAgICovCi0gIHB1YmxpYyBGYXN0U3RyaW5nQnVmZmVyIGZzYigpCi0gIHsKLSAgICByZXR1cm4gKChGYXN0U3RyaW5nQnVmZmVyKSBtX29iaik7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBDYXN0IHJlc3VsdCBvYmplY3QgdG8gYSBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHN0cmluZyB0aGlzIHdyYXBzIG9yIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbAotICAgKi8KLSAgcHVibGljIHZvaWQgYXBwZW5kVG9Gc2Iob3JnLmFwYWNoZS54bWwudXRpbHMuRmFzdFN0cmluZ0J1ZmZlciBmc2IpCi0gIHsKLSAgICAvLyAlT1BUJSAhISEgRlNCIGhhcyB0byBiZSB1cGRhdGVkIHRvIHRha2UgcGFydGlhbCBmc2IncyBmb3IgYXBwZW5kLgotICAgIGZzYi5hcHBlbmQoc3RyKCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlbGwgaWYgdGhpcyBvYmplY3QgY29udGFpbnMgYSBqYXZhIFN0cmluZyBvYmplY3QuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIFhNTFN0cmluZyBjYW4gcmV0dXJuIGEgc3RyaW5nIHdpdGhvdXQgY3JlYXRpbmcgb25lLgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nKCkKLSAgewotICAgIHJldHVybiAobnVsbCAhPSBtX3N0ckNhY2hlKTsKLSAgfQotCi0vLyAgLyoqIE5FRURTRE9DIEZpZWxkIHN0ckNvdW50ICovCi0vLyAgcHVibGljIHN0YXRpYyBpbnQgc3RyQ291bnQgPSAwOwotLy8KLS8vICAvKiogTkVFRFNET0MgRmllbGQgeHRhYmxlICovCi0vLyAgc3RhdGljIGphdmEudXRpbC5IYXNodGFibGUgeHRhYmxlID0gbmV3IGphdmEudXRpbC5IYXNodGFibGUoKTsKLQotICAvKioKLSAgICogU2luY2UgdGhpcyBvYmplY3QgaXMgaW5jb21wbGV0ZSB3aXRob3V0IHRoZSBsZW5ndGggYW5kIHRoZSBvZmZzZXQsIHdlIAotICAgKiBoYXZlIHRvIGNvbnZlcnQgdG8gYSBzdHJpbmcgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgamF2YSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgT2JqZWN0IG9iamVjdCgpCi0gIHsKLSAgICByZXR1cm4gc3RyKCk7Ci0gIH0KLQotICAvKioKLSAgICogQ2FzdCByZXN1bHQgb2JqZWN0IHRvIGEgc3RyaW5nLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBzdHJpbmcgdGhpcyB3cmFwcyBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG51bGwKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgc3RyKCkKLSAgewotCi0gICAgaWYgKG51bGwgPT0gbV9zdHJDYWNoZSkKLSAgICB7Ci0gICAgICBtX3N0ckNhY2hlID0gZnNiKCkuZ2V0U3RyaW5nKG1fc3RhcnQsIG1fbGVuZ3RoKTsKLQotLy8gICAgICBzdHJDb3VudCsrOwotLy8KLS8vICAgICAgUnVudGltZUV4Y2VwdGlvbiBlID0gbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkJhZCEgIEJhZCEiKTsKLS8vICAgICAgamF2YS5pby5DaGFyQXJyYXlXcml0ZXIgd3JpdGVyID0gbmV3IGphdmEuaW8uQ2hhckFycmF5V3JpdGVyKCk7Ci0vLyAgICAgIGphdmEuaW8uUHJpbnRXcml0ZXIgcHcgPSBuZXcgamF2YS5pby5QcmludFdyaXRlcih3cml0ZXIpOwotLy8KLS8vICAgICAgZS5wcmludFN0YWNrVHJhY2UocHcpOwotLy8KLS8vICAgICAgU3RyaW5nIHN0ciA9IHdyaXRlci50b1N0cmluZygpOwotLy8KLS8vICAgICAgc3RyID0gc3RyLnN1YnN0cmluZygwLCA2MDApOwotLy8KLS8vICAgICAgaWYgKG51bGwgPT0geHRhYmxlLmdldChzdHIpKQotLy8gICAgICB7Ci0vLyAgICAgICAgeHRhYmxlLnB1dChzdHIsIHN0cik7Ci0vLyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHN0cik7Ci0vLyAgICAgIH0KLS8vICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdHJDb3VudDogIiArIHN0ckNvdW50KTsKLQotLy8gICAgICB0aHJvdyBlOwotLy8gICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwotICAgICAgLy8gU3lzdGVtLmV4aXQoLTEpOwotICAgIH0KLQotICAgIHJldHVybiBtX3N0ckNhY2hlOwotICB9Ci0KLSAgLyoqCi0gICAqIERpcmVjdGx5IGNhbGwgdGhlCi0gICAqIGNoYXJhY3RlcnMgbWV0aG9kIG9uIHRoZSBwYXNzZWQgQ29udGVudEhhbmRsZXIgZm9yIHRoZQotICAgKiBzdHJpbmctdmFsdWUuIE11bHRpcGxlIGNhbGxzIHRvIHRoZQotICAgKiBDb250ZW50SGFuZGxlcidzIGNoYXJhY3RlcnMgbWV0aG9kcyBtYXkgd2VsbCBvY2N1ciBmb3IgYSBzaW5nbGUgY2FsbCB0bwotICAgKiB0aGlzIG1ldGhvZC4KLSAgICoKLSAgICogQHBhcmFtIGNoIEEgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGEgQ29udGVudEhhbmRsZXIuCi0gICAqCi0gICAqIEB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgdm9pZCBkaXNwYXRjaENoYXJhY3RlcnNFdmVudHMob3JnLnhtbC5zYXguQ29udGVudEhhbmRsZXIgY2gpCi0gICAgICAgICAgdGhyb3dzIG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbgotICB7Ci0gICAgZnNiKCkuc2VuZFNBWGNoYXJhY3RlcnMoY2gsIG1fc3RhcnQsIG1fbGVuZ3RoKTsKLSAgfQotCi0gIC8qKgotICAgKiBEaXJlY3RseSBjYWxsIHRoZQotICAgKiBjb21tZW50IG1ldGhvZCBvbiB0aGUgcGFzc2VkIExleGljYWxIYW5kbGVyIGZvciB0aGUKLSAgICogc3RyaW5nLXZhbHVlLgotICAgKgotICAgKiBAcGFyYW0gbGggQSBub24tbnVsbCByZWZlcmVuY2UgdG8gYSBMZXhpY2FsSGFuZGxlci4KLSAgICoKLSAgICogQHRocm93cyBvcmcueG1sLnNheC5TQVhFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyB2b2lkIGRpc3BhdGNoQXNDb21tZW50KG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlciBsaCkKLSAgICAgICAgICB0aHJvd3Mgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uCi0gIHsKLSAgICBmc2IoKS5zZW5kU0FYQ29tbWVudChsaCwgbV9zdGFydCwgbV9sZW5ndGgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZy4KLSAgICoKLSAgICogQHJldHVybiAgdGhlIGxlbmd0aCBvZiB0aGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyByZXByZXNlbnRlZCBieSB0aGlzCi0gICAqICAgICAgICAgIG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBpbnQgbGVuZ3RoKCkKLSAgewotICAgIHJldHVybiBtX2xlbmd0aDsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gQW4gaW5kZXggcmFuZ2VzCi0gICAqIGZyb20gPGNvZGU+MDwvY29kZT4gdG8gPGNvZGU+bGVuZ3RoKCkgLSAxPC9jb2RlPi4gVGhlIGZpcnN0IGNoYXJhY3RlcgotICAgKiBvZiB0aGUgc2VxdWVuY2UgaXMgYXQgaW5kZXggPGNvZGU+MDwvY29kZT4sIHRoZSBuZXh0IGF0IGluZGV4Ci0gICAqIDxjb2RlPjE8L2NvZGU+LCBhbmQgc28gb24sIGFzIGZvciBhcnJheSBpbmRleGluZy4KLSAgICoKLSAgICogQHBhcmFtICAgICAgaW5kZXggICB0aGUgaW5kZXggb2YgdGhlIGNoYXJhY3Rlci4KLSAgICogQHJldHVybiAgICAgdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IG9mIHRoaXMgc3RyaW5nLgotICAgKiAgICAgICAgICAgICBUaGUgZmlyc3QgY2hhcmFjdGVyIGlzIGF0IGluZGV4IDxjb2RlPjA8L2NvZGU+LgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUgPGNvZGU+aW5kZXg8L2NvZGU+Ci0gICAqICAgICAgICAgICAgIGFyZ3VtZW50IGlzIG5lZ2F0aXZlIG9yIG5vdCBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgIHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyBjaGFyIGNoYXJBdChpbnQgaW5kZXgpCi0gIHsKLSAgICByZXR1cm4gZnNiKCkuY2hhckF0KG1fc3RhcnQgKyBpbmRleCk7Ci0gIH0KLQotICAvKioKLSAgICogQ29waWVzIGNoYXJhY3RlcnMgZnJvbSB0aGlzIHN0cmluZyBpbnRvIHRoZSBkZXN0aW5hdGlvbiBjaGFyYWN0ZXIKLSAgICogYXJyYXkuCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIHNyY0JlZ2luICAgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nCi0gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gY29weS4KLSAgICogQHBhcmFtICAgICAgc3JjRW5kICAgICBpbmRleCBhZnRlciB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGNvcHkuCi0gICAqIEBwYXJhbSAgICAgIGRzdCAgICAgICAgdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAcGFyYW0gICAgICBkc3RCZWdpbiAgIHRoZSBzdGFydCBvZmZzZXQgaW4gdGhlIGRlc3RpbmF0aW9uIGFycmF5LgotICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gSWYgYW55IG9mIHRoZSBmb2xsb3dpbmcKLSAgICogICAgICAgICAgICBpcyB0cnVlOgotICAgKiAgICAgICAgICAgIDx1bD48bGk+PGNvZGU+c3JjQmVnaW48L2NvZGU+IGlzIG5lZ2F0aXZlLgotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5zcmNCZWdpbjwvY29kZT4gaXMgZ3JlYXRlciB0aGFuIDxjb2RlPnNyY0VuZDwvY29kZT4KLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+c3JjRW5kPC9jb2RlPiBpcyBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgICAgICAgIHN0cmluZwotICAgKiAgICAgICAgICAgIDxsaT48Y29kZT5kc3RCZWdpbjwvY29kZT4gaXMgbmVnYXRpdmUKLSAgICogICAgICAgICAgICA8bGk+PGNvZGU+ZHN0QmVnaW4rKHNyY0VuZC1zcmNCZWdpbik8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgICAgIDxjb2RlPmRzdC5sZW5ndGg8L2NvZGU+PC91bD4KLSAgICogQGV4Y2VwdGlvbiBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5kc3Q8L2NvZGU+IGlzIDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqLwotICBwdWJsaWMgdm9pZCBnZXRDaGFycyhpbnQgc3JjQmVnaW4sIGludCBzcmNFbmQsIGNoYXIgZHN0W10sIGludCBkc3RCZWdpbikKLSAgewotCi0gICAgLy8gJU9QVCUgTmVlZCB0byBjYWxsIHRoaXMgb24gRlNCIHdoZW4gaXQgaXMgaW1wbGVtZW50ZWQuCi0gICAgLy8gJVVOVEVTVEVEJSAoSSBkb24ndCB0aGluayBhbnlvbmUgY2FsbHMgdGhpcyB5ZXQ/KQotICAgIGludCBuID0gc3JjRW5kIC0gc3JjQmVnaW47Ci0KLSAgICBpZiAobiA+IG1fbGVuZ3RoKQotICAgICAgbiA9IG1fbGVuZ3RoOwotCi0gICAgaWYgKG4gPiAoZHN0Lmxlbmd0aCAtIGRzdEJlZ2luKSkKLSAgICAgIG4gPSAoZHN0Lmxlbmd0aCAtIGRzdEJlZ2luKTsKLQotICAgIGludCBlbmQgPSBzcmNCZWdpbiArIG1fc3RhcnQgKyBuOwotICAgIGludCBkID0gZHN0QmVnaW47Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLQotICAgIGZvciAoaW50IGkgPSBzcmNCZWdpbiArIG1fc3RhcnQ7IGkgPCBlbmQ7IGkrKykKLSAgICB7Ci0gICAgICBkc3RbZCsrXSA9IGZzYi5jaGFyQXQoaSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHRoaXMgc3RyaW5nIHRvIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgotICAgKiBUaGUgcmVzdWx0IGlzIDxjb2RlPnRydWU8L2NvZGU+IGlmIGFuZCBvbmx5IGlmIHRoZSBhcmd1bWVudCBpcyBub3QKLSAgICogPGNvZGU+bnVsbDwvY29kZT4gYW5kIGlzIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgdGhhdCByZXByZXNlbnRzCi0gICAqIHRoZSBzYW1lIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgdGhpcyBvYmplY3QuCi0gICAqCi0gICAqIEBwYXJhbSAgIGFuT2JqZWN0ICAgdGhlIG9iamVjdCB0byBjb21wYXJlIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICAgICAgICAgICAgIGFnYWluc3QuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBvYmoyCi0gICAqIEByZXR1cm4gIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSA8Y29kZT5TdHJpbmcgPC9jb2RlPmFyZSBlcXVhbDsKLSAgICogICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNjb21wYXJlVG8oamF2YS5sYW5nLlN0cmluZykKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLlN0cmluZyNlcXVhbHNJZ25vcmVDYXNlKGphdmEubGFuZy5TdHJpbmcpCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoWE1MU3RyaW5nIG9iajIpCi0gIHsKLQotICAgIGlmICh0aGlzID09IG9iajIpCi0gICAgewotICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgaW50IG4gPSBtX2xlbmd0aDsKLQotICAgIGlmIChuID09IG9iajIubGVuZ3RoKCkpCi0gICAgewotICAgICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLSAgICAgIGludCBpID0gbV9zdGFydDsKLSAgICAgIGludCBqID0gMDsKLQotICAgICAgd2hpbGUgKG4tLSAhPSAwKQotICAgICAgewotICAgICAgICBpZiAoZnNiLmNoYXJBdChpKSAhPSBvYmoyLmNoYXJBdChqKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGkrKzsKLSAgICAgICAgaisrOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFhPYmplY3Qgb2JqMikKLSAgewotCi0gICAgaWYgKHRoaXMgPT0gb2JqMikKLSAgICB7Ci0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICBTdHJpbmcgc3RyID0gb2JqMi5zdHIoKTsKLSAgICBpbnQgbiA9IG1fbGVuZ3RoOwotCi0gICAgaWYgKG4gPT0gc3RyLmxlbmd0aCgpKQotICAgIHsKLSAgICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0gICAgICBpbnQgaSA9IG1fc3RhcnQ7Ci0gICAgICBpbnQgaiA9IDA7Ci0KLSAgICAgIHdoaWxlIChuLS0gIT0gMCkKLSAgICAgIHsKLSAgICAgICAgaWYgKGZzYi5jaGFyQXQoaSkgIT0gc3RyLmNoYXJBdChqKSkKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBmYWxzZTsKLSAgICAgICAgfQotCi0gICAgICAgIGkrKzsKLSAgICAgICAgaisrOwotICAgICAgfQotCi0gICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9Ci0KLSAgICByZXR1cm4gZmFsc2U7Ci0gIH0KLQotICAvKioKLSAgICogVGVsbCBpZiB0d28gb2JqZWN0cyBhcmUgZnVuY3Rpb25hbGx5IGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gb2JqMiBPYmplY3QgdG8gY29tcGFyZSB0aGlzIHRvCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBhbm90aGVyU3RyaW5nCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHdvIG9iamVjdHMgYXJlIGVxdWFsCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFN0cmluZyBhbm90aGVyU3RyaW5nKQotICB7Ci0KLSAgICBpbnQgbiA9IG1fbGVuZ3RoOwotCi0gICAgaWYgKG4gPT0gYW5vdGhlclN0cmluZy5sZW5ndGgoKSkKLSAgICB7Ci0gICAgICBGYXN0U3RyaW5nQnVmZmVyIGZzYiA9IGZzYigpOwotICAgICAgaW50IGkgPSBtX3N0YXJ0OwotICAgICAgaW50IGogPSAwOwotCi0gICAgICB3aGlsZSAobi0tICE9IDApCi0gICAgICB7Ci0gICAgICAgIGlmIChmc2IuY2hhckF0KGkpICE9IGFub3RoZXJTdHJpbmcuY2hhckF0KGopKQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICB9Ci0KLSAgICAgICAgaSsrOwotICAgICAgICBqKys7Ci0gICAgICB9Ci0KLSAgICAgIHJldHVybiB0cnVlOwotICAgIH0KLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0aGlzIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLSAgICogVGhlIHJlc3VsdCBpcyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbmQgb25seSBpZiB0aGUgYXJndW1lbnQgaXMgbm90Ci0gICAqIDxjb2RlPm51bGw8L2NvZGU+IGFuZCBpcyBhIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cwotICAgKiB0aGUgc2FtZSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGFzIHRoaXMgb2JqZWN0LgotICAgKgotICAgKiBAcGFyYW0gICBhbk9iamVjdCAgIHRoZSBvYmplY3QgdG8gY29tcGFyZSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogICAgICAgICAgICAgICAgICAgICBhZ2FpbnN0LgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0gb2JqMgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgPGNvZGU+U3RyaW5nIDwvY29kZT5hcmUgZXF1YWw7Ci0gICAqICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjY29tcGFyZVRvKGphdmEubGFuZy5TdHJpbmcpCi0gICAqIEBzZWUgICAgIGphdmEubGFuZy5TdHJpbmcjZXF1YWxzSWdub3JlQ2FzZShqYXZhLmxhbmcuU3RyaW5nKQotICAgKi8KLSAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmoyKQotICB7Ci0KLSAgICBpZiAobnVsbCA9PSBvYmoyKQotICAgICAgcmV0dXJuIGZhbHNlOwotCi0gICAgICAvLyBJbiBvcmRlciB0byBoYW5kbGUgdGhlICdhbGwnIHNlbWFudGljcyBvZiAKLSAgICAgIC8vIG5vZGVzZXQgY29tcGFyaXNvbnMsIHdlIGFsd2F5cyBjYWxsIHRoZSAKLSAgICAgIC8vIG5vZGVzZXQgZnVuY3Rpb24uCi0gICAgZWxzZSBpZiAob2JqMiBpbnN0YW5jZW9mIFhOb2RlU2V0KQotICAgICAgcmV0dXJuIG9iajIuZXF1YWxzKHRoaXMpOwotICAgIGVsc2UgaWYgKG9iajIgaW5zdGFuY2VvZiBYU3RyaW5nRm9yRlNCKQotICAgICAgcmV0dXJuIGVxdWFscygoWE1MU3RyaW5nKSB0aGlzKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gZXF1YWxzKG9iajIudG9TdHJpbmcoKSk7Ci0gIH0KLQotICAvKioKLSAgICogQ29tcGFyZXMgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGFub3RoZXIgPGNvZGU+U3RyaW5nPC9jb2RlPiwKLSAgICogaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4gIFR3byBzdHJpbmdzIGFyZSBjb25zaWRlcmVkIGVxdWFsCi0gICAqIGlnbm9yaW5nIGNhc2UgaWYgdGhleSBhcmUgb2YgdGhlIHNhbWUgbGVuZ3RoLCBhbmQgY29ycmVzcG9uZGluZwotICAgKiBjaGFyYWN0ZXJzIGluIHRoZSB0d28gc3RyaW5ncyBhcmUgZXF1YWwgaWdub3JpbmcgY2FzZS4KLSAgICoKLSAgICogQHBhcmFtICAgYW5vdGhlclN0cmluZyAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGNvbXBhcmUgdGhpcwotICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+U3RyaW5nPC9jb2RlPiBhZ2FpbnN0LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgaXMgbm90IDxjb2RlPm51bGw8L2NvZGU+Ci0gICAqICAgICAgICAgIGFuZCB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPnMgYXJlIGVxdWFsLAotICAgKiAgICAgICAgICBpZ25vcmluZyBjYXNlOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiBAc2VlICAgICAjZXF1YWxzKE9iamVjdCkKLSAgICogQHNlZSAgICAgamF2YS5sYW5nLkNoYXJhY3RlciN0b0xvd2VyQ2FzZShjaGFyKQotICAgKiBAc2VlIGphdmEubGFuZy5DaGFyYWN0ZXIjdG9VcHBlckNhc2UoY2hhcikKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGVxdWFsc0lnbm9yZUNhc2UoU3RyaW5nIGFub3RoZXJTdHJpbmcpCi0gIHsKLSAgICByZXR1cm4gKG1fbGVuZ3RoID09IGFub3RoZXJTdHJpbmcubGVuZ3RoKCkpCi0gICAgICAgICAgID8gc3RyKCkuZXF1YWxzSWdub3JlQ2FzZShhbm90aGVyU3RyaW5nKSA6IGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIENvbXBhcmVzIHR3byBzdHJpbmdzIGxleGljb2dyYXBoaWNhbGx5LgotICAgKgotICAgKiBAcGFyYW0gICBhbm90aGVyU3RyaW5nICAgdGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gYmUgY29tcGFyZWQuCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSB4c3RyCi0gICAqIEByZXR1cm4gIHRoZSB2YWx1ZSA8Y29kZT4wPC9jb2RlPiBpZiB0aGUgYXJndW1lbnQgc3RyaW5nIGlzIGVxdWFsIHRvCi0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyBhIHZhbHVlIGxlc3MgdGhhbiA8Y29kZT4wPC9jb2RlPiBpZiB0aGlzIHN0cmluZwotICAgKiAgICAgICAgICBpcyBsZXhpY29ncmFwaGljYWxseSBsZXNzIHRoYW4gdGhlIHN0cmluZyBhcmd1bWVudDsgYW5kIGEKLSAgICogICAgICAgICAgdmFsdWUgZ3JlYXRlciB0aGFuIDxjb2RlPjA8L2NvZGU+IGlmIHRoaXMgc3RyaW5nIGlzCi0gICAqICAgICAgICAgIGxleGljb2dyYXBoaWNhbGx5IGdyZWF0ZXIgdGhhbiB0aGUgc3RyaW5nIGFyZ3VtZW50LgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5hbm90aGVyU3RyaW5nPC9jb2RlPgotICAgKiAgICAgICAgICBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBpbnQgY29tcGFyZVRvKFhNTFN0cmluZyB4c3RyKQotICB7Ci0KLSAgICBpbnQgbGVuMSA9IG1fbGVuZ3RoOwotICAgIGludCBsZW4yID0geHN0ci5sZW5ndGgoKTsKLSAgICBpbnQgbiA9IE1hdGgubWluKGxlbjEsIGxlbjIpOwotICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0gICAgaW50IGkgPSBtX3N0YXJ0OwotICAgIGludCBqID0gMDsKLQotICAgIHdoaWxlIChuLS0gIT0gMCkKLSAgICB7Ci0gICAgICBjaGFyIGMxID0gZnNiLmNoYXJBdChpKTsKLSAgICAgIGNoYXIgYzIgPSB4c3RyLmNoYXJBdChqKTsKLQotICAgICAgaWYgKGMxICE9IGMyKQotICAgICAgewotICAgICAgICByZXR1cm4gYzEgLSBjMjsKLSAgICAgIH0KLQotICAgICAgaSsrOwotICAgICAgaisrOwotICAgIH0KLQotICAgIHJldHVybiBsZW4xIC0gbGVuMjsKLSAgfQotCi0gIC8qKgotICAgKiBDb21wYXJlcyB0d28gc3RyaW5ncyBsZXhpY29ncmFwaGljYWxseSwgaWdub3JpbmcgY2FzZSBjb25zaWRlcmF0aW9ucy4KLSAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBpbnRlZ2VyIHdob3NlIHNpZ24gaXMgdGhhdCBvZgotICAgKiA8Y29kZT50aGlzLnRvVXBwZXJDYXNlKCkudG9Mb3dlckNhc2UoKS5jb21wYXJlVG8oCi0gICAqIHN0ci50b1VwcGVyQ2FzZSgpLnRvTG93ZXJDYXNlKCkpPC9jb2RlPi4KLSAgICogPHA+Ci0gICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIDxlbT5ub3Q8L2VtPiB0YWtlIGxvY2FsZSBpbnRvIGFjY291bnQsCi0gICAqIGFuZCB3aWxsIHJlc3VsdCBpbiBhbiB1bnNhdGlzZmFjdG9yeSBvcmRlcmluZyBmb3IgY2VydGFpbiBsb2NhbGVzLgotICAgKiBUaGUgamF2YS50ZXh0IHBhY2thZ2UgcHJvdmlkZXMgPGVtPmNvbGxhdG9yczwvZW0+IHRvIGFsbG93Ci0gICAqIGxvY2FsZS1zZW5zaXRpdmUgb3JkZXJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIGNvbXBhcmVkLgotICAgKgotICAgKiBORUVEU0RPQyBAcGFyYW0geHN0cgotICAgKiBAcmV0dXJuICBhIG5lZ2F0aXZlIGludGVnZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBhcyB0aGUKLSAgICogICAgICAgICAgdGhlIHNwZWNpZmllZCBTdHJpbmcgaXMgZ3JlYXRlciB0aGFuLCBlcXVhbCB0bywgb3IgbGVzcwotICAgKiAgICAgICAgICB0aGFuIHRoaXMgU3RyaW5nLCBpZ25vcmluZyBjYXNlIGNvbnNpZGVyYXRpb25zLgotICAgKiBAc2VlICAgICBqYXZhLnRleHQuQ29sbGF0b3IjY29tcGFyZShTdHJpbmcsIFN0cmluZykKLSAgICogQHNpbmNlICAgMS4yCi0gICAqLwotICBwdWJsaWMgaW50IGNvbXBhcmVUb0lnbm9yZUNhc2UoWE1MU3RyaW5nIHhzdHIpCi0gIHsKLQotICAgIGludCBsZW4xID0gbV9sZW5ndGg7Ci0gICAgaW50IGxlbjIgPSB4c3RyLmxlbmd0aCgpOwotICAgIGludCBuID0gTWF0aC5taW4obGVuMSwgbGVuMik7Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLSAgICBpbnQgaSA9IG1fc3RhcnQ7Ci0gICAgaW50IGogPSAwOwotCi0gICAgd2hpbGUgKG4tLSAhPSAwKQotICAgIHsKLSAgICAgIGNoYXIgYzEgPSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UoZnNiLmNoYXJBdChpKSk7Ci0gICAgICBjaGFyIGMyID0gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHhzdHIuY2hhckF0KGopKTsKLQotICAgICAgaWYgKGMxICE9IGMyKQotICAgICAgewotICAgICAgICByZXR1cm4gYzEgLSBjMjsKLSAgICAgIH0KLQotICAgICAgaSsrOwotICAgICAgaisrOwotICAgIH0KLQotICAgIHJldHVybiBsZW4xIC0gbGVuMjsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgaGFzaGNvZGUgZm9yIHRoaXMgc3RyaW5nLiBUaGUgaGFzaGNvZGUgZm9yIGEKLSAgICogPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QgaXMgY29tcHV0ZWQgYXMKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogc1swXSozMV4obi0xKSArIHNbMV0qMzFeKG4tMikgKyAuLi4gKyBzW24tMV0KLSAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgotICAgKiB1c2luZyA8Y29kZT5pbnQ8L2NvZGU+IGFyaXRobWV0aWMsIHdoZXJlIDxjb2RlPnNbaV08L2NvZGU+IGlzIHRoZQotICAgKiA8aT5pPC9pPnRoIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nLCA8Y29kZT5uPC9jb2RlPiBpcyB0aGUgbGVuZ3RoIG9mCi0gICAqIHRoZSBzdHJpbmcsIGFuZCA8Y29kZT5ePC9jb2RlPiBpbmRpY2F0ZXMgZXhwb25lbnRpYXRpb24uCi0gICAqIChUaGUgaGFzaCB2YWx1ZSBvZiB0aGUgZW1wdHkgc3RyaW5nIGlzIHplcm8uKQotICAgKgotICAgKiBAcmV0dXJuICBhIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyBvYmplY3QuCi0gICAqLwotICBwdWJsaWMgaW50IGhhc2hDb2RlKCkKLSAgewotCi0gICAgaW50IGggPSBtX2hhc2g7Ci0KLSAgICBpZiAoaCA9PSAwKQotICAgIHsKLSAgICAgIGludCBvZmYgPSBtX3N0YXJ0OwotICAgICAgaW50IGxlbiA9IG1fbGVuZ3RoOwotICAgICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykKLSAgICAgIHsKLSAgICAgICAgaCA9IDMxICogaCArIGZzYi5jaGFyQXQob2ZmKTsKLQotICAgICAgICBvZmYrKzsKLSAgICAgIH0KLQotICAgICAgbV9oYXNoID0gaDsKLSAgICB9Ci0KLSAgICByZXR1cm4gaDsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0cyBpZiB0aGlzIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeCBiZWdpbm5pbmcKLSAgICogYSBzcGVjaWZpZWQgaW5kZXguCi0gICAqCi0gICAqIEBwYXJhbSAgIHByZWZpeCAgICB0aGUgcHJlZml4LgotICAgKiBAcGFyYW0gICB0b2Zmc2V0ICAgd2hlcmUgdG8gYmVnaW4gbG9va2luZyBpbiB0aGUgc3RyaW5nLgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgc3Vic3RyaW5nIG9mIHRoaXMgb2JqZWN0IHN0YXJ0aW5nCi0gICAqICAgICAgICAgIGF0IGluZGV4IDxjb2RlPnRvZmZzZXQ8L2NvZGU+OyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBUaGUgcmVzdWx0IGlzIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiA8Y29kZT50b2Zmc2V0PC9jb2RlPiBpcwotICAgKiAgICAgICAgICBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzCi0gICAqICAgICAgICAgIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0OyBvdGhlcndpc2UgdGhlIHJlc3VsdCBpcyB0aGUgc2FtZQotICAgKiAgICAgICAgICBhcyB0aGUgcmVzdWx0IG9mIHRoZSBleHByZXNzaW9uCi0gICAqICAgICAgICAgIDxwcmU+Ci0gICAqICAgICAgICAgIHRoaXMuc3ViU3RyaW5nKHRvZmZzZXQpLnN0YXJ0c1dpdGgocHJlZml4KQotICAgKiAgICAgICAgICA8L3ByZT4KLSAgICogQGV4Y2VwdGlvbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPGNvZGU+cHJlZml4PC9jb2RlPiBpcwotICAgKiAgICAgICAgICA8Y29kZT5udWxsPC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCwgaW50IHRvZmZzZXQpCi0gIHsKLQotICAgIEZhc3RTdHJpbmdCdWZmZXIgZnNiID0gZnNiKCk7Ci0gICAgaW50IHRvID0gbV9zdGFydCArIHRvZmZzZXQ7Ci0gICAgaW50IHRsaW0gPSBtX3N0YXJ0ICsgbV9sZW5ndGg7Ci0gICAgaW50IHBvID0gMDsKLSAgICBpbnQgcGMgPSBwcmVmaXgubGVuZ3RoKCk7Ci0KLSAgICAvLyBOb3RlOiB0b2Zmc2V0IG1pZ2h0IGJlIG5lYXIgLTE+Pj4xLgotICAgIGlmICgodG9mZnNldCA8IDApIHx8ICh0b2Zmc2V0ID4gbV9sZW5ndGggLSBwYykpCi0gICAgewotICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLQotICAgIHdoaWxlICgtLXBjID49IDApCi0gICAgewotICAgICAgaWYgKGZzYi5jaGFyQXQodG8pICE9IHByZWZpeC5jaGFyQXQocG8pKQotICAgICAgewotICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICB9Ci0KLSAgICAgIHRvKys7Ci0gICAgICBwbysrOwotICAgIH0KLQotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLSAgLyoqCi0gICAqIFRlc3RzIGlmIHRoaXMgc3RyaW5nIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LgotICAgKgotICAgKiBAcGFyYW0gICBwcmVmaXggICB0aGUgcHJlZml4LgotICAgKiBAcmV0dXJuICA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhIHByZWZpeCBvZiB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5Ci0gICAqICAgICAgICAgIHRoaXMgc3RyaW5nOyA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICAgKiAgICAgICAgICBOb3RlIGFsc28gdGhhdCA8Y29kZT50cnVlPC9jb2RlPiB3aWxsIGJlIHJldHVybmVkIGlmIHRoZQotICAgKiAgICAgICAgICBhcmd1bWVudCBpcyBhbiBlbXB0eSBzdHJpbmcgb3IgaXMgZXF1YWwgdG8gdGhpcwotICAgKiAgICAgICAgICA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdCBhcyBkZXRlcm1pbmVkIGJ5IHRoZQotICAgKiAgICAgICAgICB7QGxpbmsgI2VxdWFscyhPYmplY3QpfSBtZXRob2QuCi0gICAqIEBleGNlcHRpb24gamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDxjb2RlPnByZWZpeDwvY29kZT4gaXMKLSAgICogICAgICAgICAgPGNvZGU+bnVsbDwvY29kZT4uCi0gICAqIEBzaW5jZSAgIEpESzEuIDAKLSAgICovCi0gIHB1YmxpYyBib29sZWFuIHN0YXJ0c1dpdGgoWE1MU3RyaW5nIHByZWZpeCkKLSAgewotICAgIHJldHVybiBzdGFydHNXaXRoKHByZWZpeCwgMCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMKLSAgICogaW4gdGhlIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4KLSAgICogb2JqZWN0LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkIC0tCi0gICAqIHRoYXQgaXMsIHRoZSBzbWFsbGVzdCB2YWx1ZSA8aT5rPC9pPiBzdWNoIHRoYXQ6Ci0gICAqIDxibG9ja3F1b3RlPjxwcmU+Ci0gICAqIHRoaXMuY2hhckF0KDxpPms8L2k+KSA9PSBjaAotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+LiBJZiBubyBzdWNoIGNoYXJhY3RlciBvY2N1cnMgaW4gdGhpcyBzdHJpbmcsCi0gICAqIHRoZW4gPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgIGEgY2hhcmFjdGVyLgotICAgKiBAcmV0dXJuICB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciBpbiB0aGUKLSAgICogICAgICAgICAgY2hhcmFjdGVyIHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHRoaXMgb2JqZWN0LCBvcgotICAgKiAgICAgICAgICA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgY2gpCi0gIHsKLSAgICByZXR1cm4gaW5kZXhPZihjaCwgMCk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoaXMgc3RyaW5nIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZQotICAgKiBzcGVjaWZpZWQgY2hhcmFjdGVyLCBzdGFydGluZyB0aGUgc2VhcmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguCi0gICAqIDxwPgotICAgKiBJZiBhIGNoYXJhY3RlciB3aXRoIHZhbHVlIDxjb2RlPmNoPC9jb2RlPiBvY2N1cnMgaW4gdGhlIGNoYXJhY3RlcgotICAgKiBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0IGF0IGFuIGluZGV4Ci0gICAqIG5vIHNtYWxsZXIgdGhhbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QKLSAgICogc3VjaCBvY2N1cnJlbmNlIGlzIHJldHVybmVkLS10aGF0IGlzLCB0aGUgc21hbGxlc3QgdmFsdWUgPGk+azwvaT4KLSAgICogc3VjaCB0aGF0OgotICAgKiA8YmxvY2txdW90ZT48cHJlPgotICAgKiAodGhpcy5jaGFyQXQoPGk+azwvaT4pID09IGNoKSAmJiAoPGk+azwvaT4gPj0gZnJvbUluZGV4KQotICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+Ci0gICAqIGlzIHRydWUuIElmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZyBhdCBvciBhZnRlcgotICAgKiBwb3NpdGlvbiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCB0aGVuIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KLSAgICogPHA+Ci0gICAqIFRoZXJlIGlzIG5vIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LiBJZiBpdAotICAgKiBpcyBuZWdhdGl2ZSwgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIHplcm86IHRoaXMgZW50aXJlCi0gICAqIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMKLSAgICogc3RyaW5nLCBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZgotICAgKiB0aGlzIHN0cmluZzogPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgotICAgKgotICAgKiBAcGFyYW0gICBjaCAgICAgICAgICBhIGNoYXJhY3Rlci4KLSAgICogQHBhcmFtICAgZnJvbUluZGV4ICAgdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4KLSAgICogQHJldHVybiAgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBjaGFyYWN0ZXIgaW4gdGhlCi0gICAqICAgICAgICAgIGNoYXJhY3RlciBzZXF1ZW5jZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdCB0aGF0IGlzIGdyZWF0ZXIKLSAgICogICAgICAgICAgdGhhbiBvciBlcXVhbCB0byA8Y29kZT5mcm9tSW5kZXg8L2NvZGU+LCBvciA8Y29kZT4tMTwvY29kZT4KLSAgICogICAgICAgICAgaWYgdGhlIGNoYXJhY3RlciBkb2VzIG5vdCBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBpbnQgaW5kZXhPZihpbnQgY2gsIGludCBmcm9tSW5kZXgpCi0gIHsKLQotICAgIGludCBtYXggPSBtX3N0YXJ0ICsgbV9sZW5ndGg7Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLQotICAgIGlmIChmcm9tSW5kZXggPCAwKQotICAgIHsKLSAgICAgIGZyb21JbmRleCA9IDA7Ci0gICAgfQotICAgIGVsc2UgaWYgKGZyb21JbmRleCA+PSBtX2xlbmd0aCkKLSAgICB7Ci0KLSAgICAgIC8vIE5vdGU6IGZyb21JbmRleCBtaWdodCBiZSBuZWFyIC0xPj4+MS4KLSAgICAgIHJldHVybiAtMTsKLSAgICB9Ci0KLSAgICBmb3IgKGludCBpID0gbV9zdGFydCArIGZyb21JbmRleDsgaSA8IG1heDsgaSsrKQotICAgIHsKLSAgICAgIGlmIChmc2IuY2hhckF0KGkpID09IGNoKQotICAgICAgewotICAgICAgICByZXR1cm4gaSAtIG1fc3RhcnQ7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIC0xOwotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybnMgYSBuZXcgc3RyaW5nIHRoYXQgaXMgYSBzdWJzdHJpbmcgb2YgdGhpcyBzdHJpbmcuIFRoZQotICAgKiBzdWJzdHJpbmcgYmVnaW5zIHdpdGggdGhlIGNoYXJhY3RlciBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuIDxwPgotICAgKiBFeGFtcGxlczoKLSAgICogPGJsb2NrcXVvdGU+PHByZT4KLSAgICogInVuaGFwcHkiLnN1YnN0cmluZygyKSByZXR1cm5zICJoYXBweSIKLSAgICogIkhhcmJpc29uIi5zdWJzdHJpbmcoMykgcmV0dXJucyAiYmlzb24iCi0gICAqICJlbXB0aW5lc3MiLnN1YnN0cmluZyg5KSByZXR1cm5zICIiIChhbiBlbXB0eSBzdHJpbmcpCi0gICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KLSAgICoKLSAgICogQHBhcmFtICAgICAgYmVnaW5JbmRleCAgIHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZS4KLSAgICogQHJldHVybiAgICAgdGhlIHNwZWNpZmllZCBzdWJzdHJpbmcuCi0gICAqIEBleGNlcHRpb24gIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gIGlmCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIG5lZ2F0aXZlIG9yIGxhcmdlciB0aGFuIHRoZQotICAgKiAgICAgICAgICAgICBsZW5ndGggb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+IG9iamVjdC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4KQotICB7Ci0KLSAgICBpbnQgbGVuID0gbV9sZW5ndGggLSBiZWdpbkluZGV4OwotCi0gICAgaWYgKGxlbiA8PSAwKQotICAgICAgcmV0dXJuIFhTdHJpbmcuRU1QVFlTVFJJTkc7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIGludCBzdGFydCA9IG1fc3RhcnQgKyBiZWdpbkluZGV4OwotCi0gICAgICByZXR1cm4gbmV3IFhTdHJpbmdGb3JGU0IoZnNiKCksIHN0YXJ0LCBsZW4pOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB0aGF0IGlzIGEgc3Vic3RyaW5nIG9mIHRoaXMgc3RyaW5nLiBUaGUKLSAgICogc3Vic3RyaW5nIGJlZ2lucyBhdCB0aGUgc3BlY2lmaWVkIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGFuZAotICAgKiBleHRlbmRzIHRvIHRoZSBjaGFyYWN0ZXIgYXQgaW5kZXggPGNvZGU+ZW5kSW5kZXggLSAxPC9jb2RlPi4KLSAgICogVGh1cyB0aGUgbGVuZ3RoIG9mIHRoZSBzdWJzdHJpbmcgaXMgPGNvZGU+ZW5kSW5kZXgtYmVnaW5JbmRleDwvY29kZT4uCi0gICAqCi0gICAqIEBwYXJhbSAgICAgIGJlZ2luSW5kZXggICB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmUuCi0gICAqIEBwYXJhbSAgICAgIGVuZEluZGV4ICAgICB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmUuCi0gICAqIEByZXR1cm4gICAgIHRoZSBzcGVjaWZpZWQgc3Vic3RyaW5nLgotICAgKiBAZXhjZXB0aW9uICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICBpZiB0aGUKLSAgICogICAgICAgICAgICAgPGNvZGU+YmVnaW5JbmRleDwvY29kZT4gaXMgbmVnYXRpdmUsIG9yCi0gICAqICAgICAgICAgICAgIDxjb2RlPmVuZEluZGV4PC9jb2RlPiBpcyBsYXJnZXIgdGhhbiB0aGUgbGVuZ3RoIG9mCi0gICAqICAgICAgICAgICAgIHRoaXMgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3QsIG9yCi0gICAqICAgICAgICAgICAgIDxjb2RlPmJlZ2luSW5kZXg8L2NvZGU+IGlzIGxhcmdlciB0aGFuCi0gICAqICAgICAgICAgICAgIDxjb2RlPmVuZEluZGV4PC9jb2RlPi4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgc3Vic3RyaW5nKGludCBiZWdpbkluZGV4LCBpbnQgZW5kSW5kZXgpCi0gIHsKLQotICAgIGludCBsZW4gPSBlbmRJbmRleCAtIGJlZ2luSW5kZXg7Ci0KLSAgICBpZiAobGVuID4gbV9sZW5ndGgpCi0gICAgICBsZW4gPSBtX2xlbmd0aDsKLQotICAgIGlmIChsZW4gPD0gMCkKLSAgICAgIHJldHVybiBYU3RyaW5nLkVNUFRZU1RSSU5HOwotICAgIGVsc2UKLSAgICB7Ci0gICAgICBpbnQgc3RhcnQgPSBtX3N0YXJ0ICsgYmVnaW5JbmRleDsKLQotICAgICAgcmV0dXJuIG5ldyBYU3RyaW5nRm9yRlNCKGZzYigpLCBzdGFydCwgbGVuKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogQ29uY2F0ZW5hdGVzIHRoZSBzcGVjaWZpZWQgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEBwYXJhbSAgIHN0ciAgIHRoZSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRoYXQgaXMgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQKLSAgICogICAgICAgICAgICAgICAgb2YgdGhpcyA8Y29kZT5TdHJpbmc8L2NvZGU+LgotICAgKiBAcmV0dXJuICBhIHN0cmluZyB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhpcyBvYmplY3QncwotICAgKiAgICAgICAgICBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IHRoZSBzdHJpbmcgYXJndW1lbnQncyBjaGFyYWN0ZXJzLgotICAgKiBAZXhjZXB0aW9uIGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8Y29kZT5zdHI8L2NvZGU+IGlzCi0gICAqICAgICAgICAgIDxjb2RlPm51bGw8L2NvZGU+LgotICAgKi8KLSAgcHVibGljIFhNTFN0cmluZyBjb25jYXQoU3RyaW5nIHN0cikKLSAgewotCi0gICAgLy8gJU9QVCUgTWFrZSBhbiBGU0IgaGVyZT8KLSAgICByZXR1cm4gbmV3IFhTdHJpbmcoc3RyKCkuY29uY2F0KHN0cikpOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlbW92ZXMgd2hpdGUgc3BhY2UgZnJvbSBib3RoIGVuZHMgb2YgdGhpcyBzdHJpbmcuCi0gICAqCi0gICAqIEByZXR1cm4gIHRoaXMgc3RyaW5nLCB3aXRoIHdoaXRlIHNwYWNlIHJlbW92ZWQgZnJvbSB0aGUgZnJvbnQgYW5kIGVuZC4KLSAgICovCi0gIHB1YmxpYyBYTUxTdHJpbmcgdHJpbSgpCi0gIHsKLSAgICByZXR1cm4gZml4V2hpdGVTcGFjZSh0cnVlLCB0cnVlLCBmYWxzZSk7Ci0gIH0KLQotICAvKioKLSAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgPHZhcj5jaDwvdmFyPiBjb25mb3JtcyB0byB0aGUgWE1MIDEuMCBkZWZpbml0aW9uCi0gICAqIG9mIHdoaXRlc3BhY2UuICBSZWZlciB0byA8QSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk4L1JFQy14bWwtMTk5ODAyMTAjTlQtUyI+Ci0gICAqIHRoZSBkZWZpbml0aW9uIG9mIDxDT0RFPlM8L0NPREU+PC9BPiBmb3IgZGV0YWlscy4KLSAgICogQHBhcmFtICAgY2ggICAgICBDaGFyYWN0ZXIgdG8gY2hlY2sgYXMgWE1MIHdoaXRlc3BhY2UuCi0gICAqIEByZXR1cm4gICAgICAgICAgPXRydWUgaWYgPHZhcj5jaDwvdmFyPiBpcyBYTUwgd2hpdGVzcGFjZTsgb3RoZXJ3aXNlID1mYWxzZS4KLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTcGFjZShjaGFyIGNoKQotICB7Ci0gICAgcmV0dXJuIFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGNoKTsgIC8vIFRha2UgdGhlIGVhc3kgd2F5IG91dCBmb3Igbm93LgotICB9Ci0KLSAgLyoqCi0gICAqIENvbmRpdGlvbmFsbHkgdHJpbSBhbGwgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBpbiB0aGUgc3BlY2lmaWVkIFN0cmluZy4KLSAgICogQWxsIHN0cmluZ3Mgb2Ygd2hpdGUgc3BhY2UgYXJlCi0gICAqIHJlcGxhY2VkIGJ5IGEgc2luZ2xlIHNwYWNlIGNoYXJhY3RlciAoI3gyMCksIGV4Y2VwdCBzcGFjZXMgYWZ0ZXIgcHVuY3R1YXRpb24gd2hpY2gKLSAgICogcmVjZWl2ZSBkb3VibGUgc3BhY2VzIGlmIGRvdWJsZVB1bmN0dWF0aW9uU3BhY2VzIGlzIHRydWUuCi0gICAqIFRoaXMgZnVuY3Rpb24gbWF5IGJlIHVzZWZ1bCB0byBhIGZvcm1hdHRlciwgYnV0IHRvIGdldCBmaXJzdCBjbGFzcwotICAgKiByZXN1bHRzLCB0aGUgZm9ybWF0dGVyIHNob3VsZCBwcm9iYWJseSBkbyBpdCdzIG93biB3aGl0ZSBzcGFjZSBoYW5kbGluZwotICAgKiBiYXNlZCBvbiB0aGUgc2VtYW50aWNzIG9mIHRoZSBmb3JtYXR0aW5nIG9iamVjdC4KLSAgICoKLSAgICogQHBhcmFtICAgdHJpbUhlYWQgICAgVHJpbSBsZWFkaW5nIHdoaXRlc3BhY2U/Ci0gICAqIEBwYXJhbSAgIHRyaW1UYWlsICAgIFRyaW0gdHJhaWxpbmcgd2hpdGVzcGFjZT8KLSAgICogQHBhcmFtICAgZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgICAgVXNlIGRvdWJsZSBzcGFjZXMgZm9yIHB1bmN0dWF0aW9uPwotICAgKiBAcmV0dXJuICAgICAgICAgICAgICBUaGUgdHJpbW1lZCBzdHJpbmcuCi0gICAqLwotICBwdWJsaWMgWE1MU3RyaW5nIGZpeFdoaXRlU3BhY2UoYm9vbGVhbiB0cmltSGVhZCwgYm9vbGVhbiB0cmltVGFpbCwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZG91YmxlUHVuY3R1YXRpb25TcGFjZXMpCi0gIHsKLQotICAgIGludCBlbmQgPSBtX2xlbmd0aCArIG1fc3RhcnQ7Ci0gICAgY2hhcltdIGJ1ZiA9IG5ldyBjaGFyW21fbGVuZ3RoXTsKLSAgICBGYXN0U3RyaW5nQnVmZmVyIGZzYiA9IGZzYigpOwotICAgIGJvb2xlYW4gZWRpdCA9IGZhbHNlOwotCi0gICAgLyogcmVwbGFjZSBTIHRvICcgJy4gYW5kICcgJysgLT4gc2luZ2xlICcgJy4gKi8KLSAgICBpbnQgZCA9IDA7Ci0gICAgYm9vbGVhbiBwcmVzID0gZmFsc2U7Ci0KLSAgICBmb3IgKGludCBzID0gbV9zdGFydDsgcyA8IGVuZDsgcysrKQotICAgIHsKLSAgICAgIGNoYXIgYyA9IGZzYi5jaGFyQXQocyk7Ci0KLSAgICAgIGlmIChpc1NwYWNlKGMpKQotICAgICAgewotICAgICAgICBpZiAoIXByZXMpCi0gICAgICAgIHsKLSAgICAgICAgICBpZiAoJyAnICE9IGMpCi0gICAgICAgICAgewotICAgICAgICAgICAgZWRpdCA9IHRydWU7Ci0gICAgICAgICAgfQotCi0gICAgICAgICAgYnVmW2QrK10gPSAnICc7Ci0KLSAgICAgICAgICBpZiAoZG91YmxlUHVuY3R1YXRpb25TcGFjZXMgJiYgKGQgIT0gMCkpCi0gICAgICAgICAgewotICAgICAgICAgICAgY2hhciBwcmV2Q2hhciA9IGJ1ZltkIC0gMV07Ci0KLSAgICAgICAgICAgIGlmICghKChwcmV2Q2hhciA9PSAnLicpIHx8IChwcmV2Q2hhciA9PSAnIScpCi0gICAgICAgICAgICAgICAgICB8fCAocHJldkNoYXIgPT0gJz8nKSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHByZXMgPSB0cnVlOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLSAgICAgICAgICBlbHNlCi0gICAgICAgICAgewotICAgICAgICAgICAgcHJlcyA9IHRydWU7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIGVkaXQgPSB0cnVlOwotICAgICAgICAgIHByZXMgPSB0cnVlOwotICAgICAgICB9Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGJ1ZltkKytdID0gYzsKLSAgICAgICAgcHJlcyA9IGZhbHNlOwotICAgICAgfQotICAgIH0KLQotICAgIGlmICh0cmltVGFpbCAmJiAxIDw9IGQgJiYgJyAnID09IGJ1ZltkIC0gMV0pCi0gICAgewotICAgICAgZWRpdCA9IHRydWU7Ci0KLSAgICAgIGQtLTsKLSAgICB9Ci0KLSAgICBpbnQgc3RhcnQgPSAwOwotCi0gICAgaWYgKHRyaW1IZWFkICYmIDAgPCBkICYmICcgJyA9PSBidWZbMF0pCi0gICAgewotICAgICAgZWRpdCA9IHRydWU7Ci0KLSAgICAgIHN0YXJ0Kys7Ci0gICAgfQotCi0gICAgWE1MU3RyaW5nRmFjdG9yeSB4c2YgPSBYTUxTdHJpbmdGYWN0b3J5SW1wbC5nZXRGYWN0b3J5KCk7Ci0KLSAgICByZXR1cm4gZWRpdCA/IHhzZi5uZXdzdHIoYnVmLCBzdGFydCwgZCAtIHN0YXJ0KSA6IHRoaXM7Ci0gIH0KLQotICAvKioKLSAgICogQ29udmVydCBhIHN0cmluZyB0byBhIGRvdWJsZSAtLSBBbGxvd2VkIGlucHV0IGlzIGluIGZpeGVkCi0gICAqIG5vdGF0aW9uIGRkZC5mZmYuCi0gICAqCi0gICAqIEByZXR1cm4gQSBkb3VibGUgdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZywgb3IgcmV0dXJuIERvdWJsZS5OYU4gCi0gICAqIGlmIHRoZSBzdHJpbmcgY2FuIG5vdCBiZSBjb252ZXJ0ZWQuCi0gICAqLwotICBwdWJsaWMgZG91YmxlIHRvRG91YmxlKCkKLSAgewotCi0gICAgaW50IHN0YXJ0ID0gbV9zdGFydDsKLSAgICBpbnQgZW5kID0gbV9sZW5ndGgrc3RhcnQ7Ci0gICAgCi0gICAgaWYoMCA9PSBlbmQpCi0gICAgICByZXR1cm4gRG91YmxlLk5hTjsKLSAgICAgIAotICAgIGRvdWJsZSByZXN1bHQgPSAwLjA7Ci0gICAgaW50IHB1bmN0UG9zID0gZW5kLTE7Ci0gICAgRmFzdFN0cmluZ0J1ZmZlciBmc2IgPSBmc2IoKTsKLSAgICAKLSAgICAvLyBTY2FuIHRvIGZpcnN0IHdoaXRlc3BhY2UgY2hhcmFjdGVyLgotICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSAKLSAgICB7Ci0gICAgICBjaGFyIGMgPSBmc2IuY2hhckF0KGkpOwotICAgICAgaWYoICFYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZSggYyApICkKLSAgICAgIHsKLSAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICAgIHN0YXJ0Kys7Ci0gICAgfQotCi0gICAgZG91YmxlIHNpZ24gPSAxLjA7Ci0gICAgaWYgKHN0YXJ0IDwgZW5kICYmIGZzYi5jaGFyQXQoc3RhcnQpID09ICctJykKLSAgICB7Ci0gICAgICBzaWduID0gLTEuMDsKLQotICAgICAgc3RhcnQrKzsKLSAgICB9Ci0gICAgCi0gICAgaW50IGRpZ2l0c0ZvdW5kID0gMDsKLSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgIC8vIHBhcnNlIHRoZSBzdHJpbmcgZnJvbSBsZWZ0IHRvIHJpZ2h0IGNvbnZlcnRpbmcgdGhlIGludGVnZXIgcGFydAotICAgIHsKLSAgICAgIGNoYXIgYyA9IGZzYi5jaGFyQXQoaSk7Ci0gICAgICBpZiAoYyAhPSAnLicpCi0gICAgICB7Ci0gICAgICAgIGlmKFhNTENoYXJhY3RlclJlY29nbml6ZXIuaXNXaGl0ZVNwYWNlKGMpKQotICAgICAgICAgIGJyZWFrOwotICAgICAgICBlbHNlIGlmIChDaGFyYWN0ZXIuaXNEaWdpdChjKSkKLSAgICAgICAgewotICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCAqIDEwLjAgKyAoYyAtIDB4MzApOwotICAgICAgICAgIGRpZ2l0c0ZvdW5kKys7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgIHsKLSAgICAgICAgcHVuY3RQb3MgPSBpOwotCi0gICAgICAgIGJyZWFrOwotICAgICAgfQotICAgIH0KLSAgICAKLSAgICBpZiAoZnNiLmNoYXJBdChwdW5jdFBvcykgPT0gJy4nKSAgLy8gcGFyc2UgdGhlIHN0cmluZyBmcm9tIHRoZSBlbmQgdG8gdGhlICcuJyBjb252ZXJ0aW5nIHRoZSBmcmFjdGlvbmFsIHBhcnQKLSAgICB7Ci0gICAgICBkb3VibGUgZnJhY3RQYXJ0ID0gMC4wOwotICAgICAgZm9yIChpbnQgaSA9IGVuZCAtIDE7IGkgPiBwdW5jdFBvczsgaS0tKQotICAgICAgewotICAgICAgICBjaGFyIGMgPSBmc2IuY2hhckF0KGkpOwotICAgICAgICBpZihYTUxDaGFyYWN0ZXJSZWNvZ25pemVyLmlzV2hpdGVTcGFjZShjKSkKLSAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgZWxzZSBpZiAoQ2hhcmFjdGVyLmlzRGlnaXQoYykpCi0gICAgICAgIHsKLSAgICAgICAgICBmcmFjdFBhcnQgPSBmcmFjdFBhcnQgLyAxMC4wICsgKGMgLSAweDMwKTsKLSAgICAgICAgICBkaWdpdHNGb3VuZCsrOwotICAgICAgICB9Ci0gICAgICAgIGVsc2UKLSAgICAgICAgewotICAgICAgICAgIHJldHVybiBEb3VibGUuTmFOOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIHJlc3VsdCArPSBmcmFjdFBhcnQgLyAxMC4wOwotICAgIH0KLSAgICAKLSAgICBpZigwID09IGRpZ2l0c0ZvdW5kKQotICAgICAgcmV0dXJuIERvdWJsZS5OYU47Ci0KLSAgICByZXR1cm4gcmVzdWx0ICogc2lnbjsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkODM0NjU1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsOSArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIG9iamVjdHMgUGFja2FnZS48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRhdGlvbiBvZiBYUGF0aCBwb2x5bW9ycGhpYyB0eXBlIG9iamVjdHMgLS0gdGhpcyBwYWNrYWdlIHdpbGwgZ3JvdyAKLSAgICBhcyBYUGF0aCBvYmplY3RzIGFyZSBleHBhbmRlZCB0byBzdXBwb3J0IFhNTCBTY2hlbWEgZGF0YSB0eXBlcy48cD4KLSA8L2JvZHk+Ci08L2h0bWw+Ci0KLQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9BbmQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvQW5kLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUxY2IzZjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9BbmQuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDExNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLWltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOwotCi0vKioKLSAqIFRoZSAnYW5kJyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIEFuZCBleHRlbmRzIE9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBBTkQgdHdvIGV4cHJlc3Npb25zIGFuZCByZXR1cm4gdGhlIGJvb2xlYW4gcmVzdWx0LiBPdmVycmlkZQotICAgKiBzdXBlcmNsYXNzIG1ldGhvZCBmb3Igb3B0aW1pemF0aW9uIHB1cnBvc2VzLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbiNTX1RSVUV9IG9yIAotICAgKiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuI1NfRkFMU0V9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IGV4cHIxID0gbV9sZWZ0LmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgaWYgKGV4cHIxLmJvb2woKSkKLSAgICB7Ci0gICAgICBYT2JqZWN0IGV4cHIyID0gbV9yaWdodC5leGVjdXRlKHhjdHh0KTsKLQotICAgICAgcmV0dXJuIGV4cHIyLmJvb2woKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBYQm9vbGVhbi5TX0ZBTFNFOwotICB9Ci0gIAotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBib29sZWFuLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgYm9vbGVhbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBib29sKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChtX2xlZnQuYm9vbCh4Y3R4dCkgJiYgbV9yaWdodC5ib29sKHhjdHh0KSk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9Cb29sLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0Jvb2wuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjRmZWNmNC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0Jvb2wuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwMyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci0KLS8qKgotICogVGhlICdib29sZWFuKCknIG9wZXJhdGlvbiBleHByZXNzaW9uIGV4ZWN1dGVyLgotICovCi1wdWJsaWMgY2xhc3MgQm9vbCBleHRlbmRzIFVuYXJ5T3BlcmF0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCByaWdodCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKFhPYmplY3QuQ0xBU1NfQk9PTEVBTiA9PSByaWdodC5nZXRUeXBlKCkpCi0gICAgICByZXR1cm4gcmlnaHQ7Ci0gICAgZWxzZQotICAgICAgcmV0dXJuIHJpZ2h0LmJvb2woKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBFdmFsdWF0ZSB0aGlzIG9wZXJhdGlvbiBkaXJlY3RseSB0byBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBib29sZWFuLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbV9yaWdodC5ib29sKHhjdHh0KTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0Rpdi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9EaXYuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNThlODU3Zi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0Rpdi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIFRoZSAnZGl2JyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIERpdiBleHRlbmRzIE9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIobGVmdC5udW0oKSAvIHJpZ2h0Lm51bSgpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgZG91YmxlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgZG91YmxlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gKG1fbGVmdC5udW0oeGN0eHQpIC8gbV9yaWdodC5udW0oeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0VxdWFscy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9FcXVhbHMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjMwMmNhOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0VxdWFscy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODQgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuOwotCi0vKioKLSAqIFRoZSAnPScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBFcXVhbHMgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGxlZnQuZXF1YWxzKHJpZ2h0KSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvR3QuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvR3QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTFlZTRiMi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0d0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogVGhlICc+JyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIEd0IGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBsZWZ0LmdyZWF0ZXJUaGFuKHJpZ2h0KSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvR3RlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0d0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0MmUxNGJlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvR3RlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogVGhlICc+PScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBHdGUgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGxlZnQuZ3JlYXRlclRoYW5PckVxdWFsKHJpZ2h0KQotICAgICAgICAgICA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTHQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTHQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzE4NzhiYS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0x0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogVGhlICc8JyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIEx0IGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBsZWZ0Lmxlc3NUaGFuKHJpZ2h0KSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTHRlLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL0x0ZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwY2NmNGJhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTHRlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogVGhlICc8PScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBMdGUgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIGxlZnQubGVzc1RoYW5PckVxdWFsKHJpZ2h0KSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTWludXMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTWludXMuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjRlZTY1NS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL01pbnVzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhOdW1iZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci0KLS8qKgotICogVGhlIGJpbmFyeSAnLScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBNaW51cyBleHRlbmRzIE9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIAotICAgKiAgICAgICAgIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIobGVmdC5udW0oKSAtIHJpZ2h0Lm51bSgpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgZG91YmxlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgZG91YmxlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gKG1fbGVmdC5udW0oeGN0eHQpIC0gbV9yaWdodC5udW0oeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL01vZC5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9Nb2QuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzZhOGVhNi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL01vZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIFRoZSAnbW9kJyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIE1vZCBleHRlbmRzIE9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIobGVmdC5udW0oKSAlIHJpZ2h0Lm51bSgpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgZG91YmxlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgZG91YmxlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gKG1fbGVmdC5udW0oeGN0eHQpICUgbV9yaWdodC5udW0oeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL011bHQuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTXVsdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNWQxMGVlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTXVsdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIFRoZSAnKicgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBNdWx0IGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgWE51bWJlcihsZWZ0Lm51bSgpICogcmlnaHQubnVtKCkpOwotICB9Ci0gIAotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKG1fbGVmdC5udW0oeGN0eHQpICogbV9yaWdodC5udW0oeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL05lZy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9OZWcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTdmZTIwZC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL05lZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIFRoZSB1bmFyeSAnLScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBOZWcgZXh0ZW5kcyBVbmFyeU9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgcmlnaHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIoLXJpZ2h0Lm51bSgpKTsKLSAgfQotICAKLSAgLyoqCi0gICAqIEV2YWx1YXRlIHRoaXMgb3BlcmF0aW9uIGRpcmVjdGx5IHRvIGEgZG91YmxlLgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgVGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGFzIGEgZG91YmxlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgbnVtKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICByZXR1cm4gLShtX3JpZ2h0Lm51bSh4Y3R4dCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTm90RXF1YWxzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL05vdEVxdWFscy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNmM0ODcyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTm90RXF1YWxzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW47Ci0KLS8qKgotICogVGhlICchPScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBOb3RFcXVhbHMgZXh0ZW5kcyBPcGVyYXRpb24KLXsKLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIChsZWZ0Lm5vdEVxdWFscyhyaWdodCkpID8gWEJvb2xlYW4uU19UUlVFIDogWEJvb2xlYW4uU19GQUxTRTsKLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9OdW1iZXIuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvTnVtYmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMyMjkxZjIuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9OdW1iZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwNCArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLQotLyoqCi0gKiBUaGUgJ251bWJlcigpJyBvcGVyYXRpb24gZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIE51bWJlciBleHRlbmRzIFVuYXJ5T3BlcmF0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCByaWdodCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKFhPYmplY3QuQ0xBU1NfTlVNQkVSID09IHJpZ2h0LmdldFR5cGUoKSkKLSAgICAgIHJldHVybiByaWdodDsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gbmV3IFhOdW1iZXIocmlnaHQubnVtKCkpOwotICB9Ci0gIAotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiBtX3JpZ2h0Lm51bSh4Y3R4dCk7Ci0gIH0KLQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9PcGVyYXRpb24uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvT3BlcmF0aW9uLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBjODRmOTMuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9PcGVyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE2NSArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlIGJhc2VjbGFzcyBmb3IgYSBiaW5hcnkgb3BlcmF0aW9uLgotICovCi1wdWJsaWMgY2xhc3MgT3BlcmF0aW9uIGV4dGVuZHMgRXhwcmVzc2lvbgotewotCi0gIC8qKiBUaGUgbGVmdCBvcGVyYW5kIGV4cHJlc3Npb24uCi0gICAqICBAc2VyaWFsICovCi0gIHByb3RlY3RlZCBFeHByZXNzaW9uIG1fbGVmdDsKLQotICAvKiogVGhlIHJpZ2h0IG9wZXJhbmQgZXhwcmVzc2lvbi4KLSAgICogIEBzZXJpYWwgKi8KLSAgcHJvdGVjdGVkIEV4cHJlc3Npb24gbV9yaWdodDsKLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIG1fbGVmdC5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgbV9yaWdodC5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9sZWZ0ICYmIG1fbGVmdC5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkpCi0gICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIGlmIChudWxsICE9IG1fcmlnaHQgJiYgbV9yaWdodC5jYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkpCi0gICAgICByZXR1cm4gdHJ1ZTsKLQotICAgIHJldHVybiBmYWxzZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGxlZnQgYW5kIHJpZ2h0IG9wZXJhbmQgZXhwcmVzc2lvbnMgZm9yIHRoaXMgb3BlcmF0aW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbCBUaGUgbGVmdCBleHByZXNzaW9uIG9wZXJhbmQuCi0gICAqIEBwYXJhbSByIFRoZSByaWdodCBleHByZXNzaW9uIG9wZXJhbmQuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRMZWZ0UmlnaHQoRXhwcmVzc2lvbiBsLCBFeHByZXNzaW9uIHIpCi0gIHsKLSAgICBtX2xlZnQgPSBsOwotICAgIG1fcmlnaHQgPSByOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgYSBiaW5hcnkgb3BlcmF0aW9uIGJ5IGNhbGxpbmcgZXhlY3V0ZSBvbiBlYWNoIG9mIHRoZSBvcGVyYW5kcywKLSAgICogYW5kIHRoZW4gY2FsbGluZyB0aGUgb3BlcmF0ZSBtZXRob2Qgb24gdGhlIGRlcml2ZWQgY2xhc3MuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgWE9iamVjdCByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IGxlZnQgPSBtX2xlZnQuZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgWE9iamVjdCByaWdodCA9IG1fcmlnaHQuZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICByZXR1cm4gb3BlcmF0ZShsZWZ0LCByaWdodCk7Ci0gIH0KLQotICAvKioKLSAgICogQXBwbHkgdGhlIG9wZXJhdGlvbiB0byB0d28gb3BlcmFuZHMsIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIGxlZnQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgbGVmdCBvcGVyYW5kLgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgbGVmdCwgWE9iamVjdCByaWdodCkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0gICAgcmV0dXJuIG51bGw7ICAvLyBuby1vcAotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL09yLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL09yLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFkNGQ3NTYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9Pci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTE0ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YQm9vbGVhbjsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlICdvcicgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBPciBleHRlbmRzIE9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBPUiB0d28gZXhwcmVzc2lvbnMgYW5kIHJldHVybiB0aGUgYm9vbGVhbiByZXN1bHQuIE92ZXJyaWRlCi0gICAqIHN1cGVyY2xhc3MgbWV0aG9kIGZvciBvcHRpbWl6YXRpb24gcHVycG9zZXMuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhCb29sZWFuI1NfVFJVRX0gb3IgCi0gICAqIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWEJvb2xlYW4jU19GQUxTRX0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhPYmplY3QgZXhwcjEgPSBtX2xlZnQuZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICBpZiAoIWV4cHIxLmJvb2woKSkKLSAgICB7Ci0gICAgICBYT2JqZWN0IGV4cHIyID0gbV9yaWdodC5leGVjdXRlKHhjdHh0KTsKLQotICAgICAgcmV0dXJuIGV4cHIyLmJvb2woKSA/IFhCb29sZWFuLlNfVFJVRSA6IFhCb29sZWFuLlNfRkFMU0U7Ci0gICAgfQotICAgIGVsc2UKLSAgICAgIHJldHVybiBYQm9vbGVhbi5TX1RSVUU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBFdmFsdWF0ZSB0aGlzIG9wZXJhdGlvbiBkaXJlY3RseSB0byBhIGJvb2xlYW4uCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBib29sZWFuLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGJvb2woWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKG1fbGVmdC5ib29sKHhjdHh0KSB8fCBtX3JpZ2h0LmJvb2woeGN0eHQpKTsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL1BsdXMuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvUGx1cy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NzgzYWE1Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvUGx1cy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTAyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgub3BlcmF0aW9uczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotCi0vKioKLSAqIFRoZSAnKycgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBQbHVzIGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBsZWZ0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIGxlZnQgb3BlcmFuZC4KLSAgICogQHBhcmFtIHJpZ2h0IG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgZXZhbHVhdGVkIHJpZ2h0IG9wZXJhbmQuCi0gICAqCi0gICAqIEByZXR1cm4gbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBYT2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3Qgb3BlcmF0ZShYT2JqZWN0IGxlZnQsIFhPYmplY3QgcmlnaHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotICAgIHJldHVybiBuZXcgWE51bWJlcihsZWZ0Lm51bSgpICsgcmlnaHQubnVtKCkpOwotICB9Ci0gIAotICAvKioKLSAgICogRXZhbHVhdGUgdGhpcyBvcGVyYXRpb24gZGlyZWN0bHkgdG8gYSBkb3VibGUuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gYXMgYSBkb3VibGUuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIGRvdWJsZSBudW0oWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiAobV9yaWdodC5udW0oeGN0eHQpICsgbV9sZWZ0Lm51bSh4Y3R4dCkpOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvUXVvLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL1F1by5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0NzAwNTUyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvUXVvLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLQotLyoqCi0gKiBUaGUgJ3F1bycgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuIChubyBsb25nZXIgc3VwcG9ydGVkIGJ5IFhQYXRoKS4KLSAqIEBkZXByZWNhdGVkLgotICovCi1wdWJsaWMgY2xhc3MgUXVvIGV4dGVuZHMgT3BlcmF0aW9uCi17Ci0KLSAgLy8gQWN0dWFsbHksIHRoaXMgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCBieSB4cGF0aC4uLgotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gbGVmdCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCBsZWZ0IG9wZXJhbmQuCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCBsZWZ0LCBYT2JqZWN0IHJpZ2h0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gbmV3IFhOdW1iZXIoKGludCkgKGxlZnQubnVtKCkgLyByaWdodC5udW0oKSkpOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL1N0cmluZy5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9TdHJpbmcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2NkMzgwZi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL1N0cmluZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsODIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhTdHJpbmc7Ci0KLS8qKgotICogVGhlICdzdHJpbmcoKScgb3BlcmF0aW9uIGV4cHJlc3Npb24gZXhlY3V0ZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBTdHJpbmcgZXh0ZW5kcyBVbmFyeU9wZXJhdGlvbgotewotCi0gIC8qKgotICAgKiBBcHBseSB0aGUgb3BlcmF0aW9uIHRvIHR3byBvcGVyYW5kcywgYW5kIHJldHVybiB0aGUgcmVzdWx0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gcmlnaHQgbm9uLW51bGwgcmVmZXJlbmNlIHRvIHRoZSBldmFsdWF0ZWQgcmlnaHQgb3BlcmFuZC4KLSAgICoKLSAgICogQHJldHVybiBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBvcGVyYXRlKFhPYmplY3QgcmlnaHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gKFhTdHJpbmcpcmlnaHQueHN0cigpOyAvLyBzZW1pLXNhZmUgY2FzdC4KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9VbmFyeU9wZXJhdGlvbi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9VbmFyeU9wZXJhdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhYTNhOGFhLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvVW5hcnlPcGVyYXRpb24uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDE0NyArMCwwIEBACi0vKgotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAqLwotcGFja2FnZSBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLS8qKgotICogVGhlIHVuYXJ5IG9wZXJhdGlvbiBiYXNlIGNsYXNzLgotICovCi1wdWJsaWMgYWJzdHJhY3QgY2xhc3MgVW5hcnlPcGVyYXRpb24gZXh0ZW5kcyBFeHByZXNzaW9uCi17Ci0KLSAgLyoqIFRoZSBvcGVyYW5kIGZvciB0aGUgb3BlcmF0aW9uLgotICAgKiAgQHNlcmlhbCAqLwotICBwcm90ZWN0ZWQgRXhwcmVzc2lvbiBtX3JpZ2h0OwotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUgCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0IAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdCAKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUgCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbiAKLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZCAKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgbV9yaWdodC5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlCi0gICAqIHRoZSBjdXJyZW50IHN1YnRyZWUuCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0cmF2ZXJzYWwgb3V0c2lkZSB0aGUgY29udGV4dCBub2RlJ3Mgc3VidHJlZSBjYW4gb2NjdXIuCi0gICAqLwotICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgewotCi0gICAgaWYgKG51bGwgIT0gbV9yaWdodCAmJiBtX3JpZ2h0LmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSkKLSAgICAgIHJldHVybiB0cnVlOwotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgZXhwcmVzc2lvbiBvcGVyYW5kIGZvciB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gciBUaGUgZXhwcmVzc2lvbiBvcGVyYW5kIHRvIHdoaWNoIHRoZSB1bmFyeSBvcGVyYXRpb24gd2lsbCBiZSAKLSAgICogICAgICAgICAgYXBwbGllZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFJpZ2h0KEV4cHJlc3Npb24gcikKLSAgewotICAgIG1fcmlnaHQgPSByOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIG9wZXJhbmQgYW5kIGFwcGx5IHRoZSB1bmFyeSBvcGVyYXRpb24gdG8gdGhlIHJlc3VsdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBydW50aW1lIGV4ZWN1dGlvbiBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIEFuIFhPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgdGhlIHVuYXJ5IAotICAgKiAgICAgICAgIG9wZXJhdGlvbiB0byB0aGUgZXZhbHVhdGVkIG9wZXJhbmQuCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHJldHVybiBvcGVyYXRlKG1fcmlnaHQuZXhlY3V0ZSh4Y3R4dCkpOwotICB9Ci0KLSAgLyoqCi0gICAqIEFwcGx5IHRoZSBvcGVyYXRpb24gdG8gdHdvIG9wZXJhbmRzLCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSByaWdodCBub24tbnVsbCByZWZlcmVuY2UgdG8gdGhlIGV2YWx1YXRlZCByaWdodCBvcGVyYW5kLgotICAgKgotICAgKiBAcmV0dXJuIG5vbi1udWxsIHJlZmVyZW5jZSB0byB0aGUgWE9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBhYnN0cmFjdCBYT2JqZWN0IG9wZXJhdGUoWE9iamVjdCByaWdodCkKLSAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvVmFyaWFibGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvVmFyaWFibGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZmJiNjg3Mi4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zL1ZhcmlhYmxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNjMgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5vcGVyYXRpb25zOwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueG1sLnV0aWxzLlFOYW1lOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTm9kZVNldDsKLQotaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ucmVzLlhTTE1lc3NhZ2VzOwotCi0vKioKLSAqIFRoZSB2YXJpYWJsZSByZWZlcmVuY2UgZXhwcmVzc2lvbiBleGVjdXRlci4KLSAqLwotcHVibGljIGNsYXNzIFZhcmlhYmxlIGV4dGVuZHMgRXhwcmVzc2lvbgotewotICAvKiogVGVsbCBpZiBmaXh1cFZhcmlhYmxlcyB3YXMgY2FsbGVkLgotICAgKiAgQHNlcmlhbCAgICovCi0gIHByaXZhdGUgYm9vbGVhbiBtX2ZpeFVwV2FzQ2FsbGVkID0gZmFsc2U7Ci0KLSAgLyoqIFRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgdmFyaWFibGUuCi0gICAqICBAc2VyaWFsICAgKi8KLSAgcHJvdGVjdGVkIFFOYW1lIG1fcW5hbWU7Ci0gIAotICAvKioKLSAgICogVGhlIGluZGV4IG9mIHRoZSB2YXJpYWJsZSwgd2hpY2ggaXMgZWl0aGVyIGFuIGFic29sdXRlIGluZGV4IHRvIGEgCi0gICAqIGdsb2JhbCwgb3IsIGlmIGhpZ2hlciB0aGFuIHRoZSBnbG9iYWxzIGFyZWEsIG11c3QgYmUgYWRqdXN0ZWQgYnkgYWRkaW5nIAotICAgKiB0aGUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lLgotICAgKi8KLSAgcHJvdGVjdGVkIGludCBtX2luZGV4OwotICAKLSAgcHJvdGVjdGVkIGJvb2xlYW4gbV9pc0dsb2JhbCA9IGZhbHNlOwotICAKLSAgLyoqCi0gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBmaXh1cCB2YXJpYWJsZXMgZnJvbSBRTmFtZXMgdG8gc3RhY2sgZnJhbWUgCi0gICAqIGluZGV4ZXMgYXQgc3R5bGVzaGVldCBidWlsZCB0aW1lLgotICAgKiBAcGFyYW0gdmFycyBMaXN0IG9mIFFOYW1lcyB0aGF0IGNvcnJlc3BvbmQgdG8gdmFyaWFibGVzLiAgVGhpcyBsaXN0IAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdCAKLSAgICogY29ycmVzcG9uZHMgdG8gdGhlIHZhcmlhYmxlIHJlZmVyZW5jZSBxbmFtZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGUgCi0gICAqIFFOYW1lIGluIHRoZSB2ZWN0b3IgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZlY3RvciB3aWxsIGJlIGl0cyBwb3NpdGlvbiAKLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZCAKLSAgICogdG8gYmUgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lKS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgbV9maXhVcFdhc0NhbGxlZCA9IHRydWU7Ci0gICAgaW50IHN6ID0gdmFycy5zaXplKCk7Ci0gICAgZm9yIChpbnQgaSA9IHZhcnMuc2l6ZSgpLTE7IGkgPj0gMDsgaS0tKSAKLSAgICB7Ci0gICAgICBRTmFtZSBxbiA9IChRTmFtZSl2YXJzLmVsZW1lbnRBdChpKTsKLSAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigicW46ICIrcW4pOwotICAgICAgaWYocW4uZXF1YWxzKG1fcW5hbWUpKQotICAgICAgewotICAgICAgICAKLSAgICAgICAgaWYoaSA8IGdsb2JhbHNTaXplKQotICAgICAgICB7Ci0gICAgICAgICAgbV9pc0dsb2JhbCA9IHRydWU7Ci0gICAgICAgICAgbV9pbmRleCA9IGk7Ci0gICAgICAgIH0KLSAgICAgICAgZWxzZQotICAgICAgICB7Ci0gICAgICAgICAgbV9pbmRleCA9IGktZ2xvYmFsc1NpemU7Ci0gICAgICAgIH0KLSAgICAgICAgICAKLSAgICAgICAgcmV0dXJuOwotICAgICAgfQotICAgIH0KLSAgICBqYXZhLmxhbmcuU3RyaW5nIG1zZyA9IFhTTE1lc3NhZ2VzLmNyZWF0ZVhQQVRITWVzc2FnZShYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NPVUxEX05PVF9GSU5EX1ZBUiwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bV9xbmFtZS50b1N0cmluZygpfSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICBUcmFuc2Zvcm1lckV4Y2VwdGlvbiB0ZSA9IG5ldyBUcmFuc2Zvcm1lckV4Y2VwdGlvbihtc2csIG1fc2xvY2F0b3IpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgdGhyb3cgbmV3IG9yZy5hcGFjaGUueG1sLnV0aWxzLldyYXBwZWRSdW50aW1lRXhjZXB0aW9uKHRlKTsKLSAgICAKLSAgfQotCi0KLSAgLyoqCi0gICAqIFNldCB0aGUgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHZhcmlhYmxlLgotICAgKgotICAgKiBAcGFyYW0gcW5hbWUgTXVzdCBiZSBhIG5vbi1udWxsIHJlZmVyZW5jZSB0byBhIHF1YWxpZmllZCBuYW1lLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UU5hbWUoUU5hbWUgcW5hbWUpCi0gIHsKLSAgICBtX3FuYW1lID0gcW5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogRGVyZWZlcmVuY2UgdGhlIHZhcmlhYmxlLCBhbmQgcmV0dXJuIHRoZSByZWZlcmVuY2UgdmFsdWUuICBOb3RlIHRoYXQgbGF6eSAKLSAgICogZXZhbHVhdGlvbiB3aWxsIG9jY3VyLiAgSWYgYSB2YXJpYWJsZSB3aXRoaW4gc2NvcGUgaXMgbm90IGZvdW5kLCBhIHdhcm5pbmcgCi0gICAqIHdpbGwgYmUgc2VudCB0byB0aGUgZXJyb3IgbGlzdGVuZXIsIGFuZCBhbiBlbXB0eSBub2Rlc2V0IHdpbGwgYmUgcmV0dXJuZWQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgcnVudGltZSBleGVjdXRpb24gY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgZXZhbHVhdGVkIHZhcmlhYmxlLCBvciBhbiBlbXB0eSBub2Rlc2V0IGlmIG5vdCBmb3VuZC4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCkgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgLy8gSXMgdGhlIHZhcmlhYmxlIGZldGNoZWQgYWx3YXlzIHRoZSBzYW1lPwotICAgIC8vIFhPYmplY3QgcmVzdWx0ID0geGN0eHQuZ2V0VmFyaWFibGUobV9xbmFtZSk7Ci0gICAgaWYobV9maXhVcFdhc0NhbGxlZCkKLSAgICB7ICAgIAotICAgICAgWE9iamVjdCByZXN1bHQ7Ci0gICAgICBpZihtX2lzR2xvYmFsKQotICAgICAgICByZXN1bHQgPSB4Y3R4dC5nZXRWYXJTdGFjaygpLmdldEdsb2JhbFZhcmlhYmxlKHhjdHh0LCBtX2luZGV4KTsKLSAgICAgIGVsc2UKLSAgICAgICAgcmVzdWx0ID0geGN0eHQuZ2V0VmFyU3RhY2soKS5nZXRMb2NhbFZhcmlhYmxlKHhjdHh0LCBtX2luZGV4KTsKLSAgCi0gICAgICBpZiAobnVsbCA9PSByZXN1bHQpCi0gICAgICB7Ci0gICAgICAgIC8vIFRoaXMgc2hvdWxkIG5vdyBuZXZlciBoYXBwZW4uLi4KLSAgICAgICAgd2Fybih4Y3R4dCwgWFBBVEhFcnJvclJlc291cmNlcy5XR19JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSwKLSAgICAgICAgICAgICBuZXcgT2JqZWN0W117IG1fcW5hbWUuZ2V0TG9jYWxQYXJ0KCkgfSk7ICAvLyJWYXJpYWJsZVJlZmVyZW5jZSBnaXZlbiBmb3IgdmFyaWFibGUgb3V0ICIrCi0gIC8vICAgICAgKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpLnByaW50U3RhY2tUcmFjZSgpOwotICAvLyAgICAgIGVycm9yKHhjdHh0LCBYUEFUSEVycm9yUmVzb3VyY2VzLkVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQsCi0gIC8vICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBtX3FuYW1lLmdldExvY2FsUGFydCgpIH0pOyAgLy8iQ291bGQgbm90IGdldCB2YXJpYWJsZSBuYW1lZCAiK3Zhck5hbWUpOwotICAgICAgICAKLSAgICAgICAgcmVzdWx0ID0gbmV3IFhOb2RlU2V0KHhjdHh0LmdldERUTU1hbmFnZXIoKSk7Ci0gICAgICB9Ci0gIAotICAgICAgcmV0dXJuIHJlc3VsdDsKLSAgICB9Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIC8vIEhhY2sgY2l0eS4uLiBiaWcgdGltZS4gIFRoaXMgaXMgbmVlZGVkIHRvIGV2YWx1YXRlIHhwYXRocyBmcm9tIGV4dGVuc2lvbnMsIAotICAgICAgLy8gcGVuZGluZyBzb21lIGJyaWdodCBsaWdodCBnb2luZyBvZmYgaW4gbXkgaGVhZC4gIFNvbWUgc29ydCBvZiBjYWxsYmFjaz8KLSAgICAgIHN5bmNocm9uaXplZCh0aGlzKQotICAgICAgewotICAgICAgICBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlciBwcmVmaXhSZXNvbHZlciA9IHhjdHh0LmdldE5hbWVzcGFjZUNvbnRleHQoKTsKLQotICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgRWxlbVRlbXBsYXRlRWxlbWVudCwgd2hpY2ggbXVzdCBiZSBwdXNoZWQgaW4gYXMgdGhlIAotICAgICAgICAvLyBwcmVmaXggcmVzb2x2ZXIsIGFuZCB0aGVuIHdhbGsgYmFja3dhcmRzIGluIGRvY3VtZW50IG9yZGVyLCBzZWFyY2hpbmcgCi0gICAgICAgIC8vIGZvciBhbiB4c2w6cGFyYW0gZWxlbWVudCBvciB4c2w6dmFyaWFibGUgZWxlbWVudCB0aGF0IG1hdGNoZXMgb3VyIAotICAgICAgICAvLyBxbmFtZS4gIElmIHdlIHJlYWNoIHRoZSB0b3AgbGV2ZWwsIHVzZSB0aGUgU3R5bGVzaGVldFJvb3QncyBjb21wb3NlZAotICAgICAgICAvLyBsaXN0IG9mIHRvcCBsZXZlbCB2YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMuCi0KLSAgICAgICAgaWYgKHByZWZpeFJlc29sdmVyIGluc3RhbmNlb2Ygb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVRlbXBsYXRlRWxlbWVudCkKLSAgICAgICAgewotCi0gICAgICAgICAgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbVZhcmlhYmxlIHZ2YXI7Ci0KLSAgICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50IHByZXYgPSAKLSAgICAgICAgICAgIChvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50KSBwcmVmaXhSZXNvbHZlcjsKLQotICAgICAgICAgIGlmICghKHByZXYgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0KSkKLSAgICAgICAgICB7ICAgICAgICAgICAgCi0gICAgICAgICAgICB3aGlsZSAoICEocHJldi5nZXRQYXJlbnROb2RlKCkgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5TdHlsZXNoZWV0KSApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1UZW1wbGF0ZUVsZW1lbnQgc2F2ZWRwcmV2ID0gcHJldjsKLQotICAgICAgICAgICAgICB3aGlsZSAobnVsbCAhPSAocHJldiA9IHByZXYuZ2V0UHJldmlvdXNTaWJsaW5nRWxlbSgpKSkKLSAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmKHByZXYgaW5zdGFuY2VvZiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgdnZhciA9IChvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVmFyaWFibGUpIHByZXY7Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICBpZiAodnZhci5nZXROYW1lKCkuZXF1YWxzKG1fcW5hbWUpKQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBtX2luZGV4ID0gdnZhci5nZXRJbmRleCgpOwotICAgICAgICAgICAgICAgICAgICBtX2lzR2xvYmFsID0gZmFsc2U7Ci0gICAgICAgICAgICAgICAgICAgIG1fZml4VXBXYXNDYWxsZWQgPSB0cnVlOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIHByZXYgPSBzYXZlZHByZXYuZ2V0UGFyZW50RWxlbSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgIH0KLQotICAgICAgICAgIHZ2YXIgPSBwcmV2LmdldFN0eWxlc2hlZXRSb290KCkuZ2V0VmFyaWFibGVPclBhcmFtQ29tcG9zZWQobV9xbmFtZSk7Ci0gICAgICAgICAgaWYgKG51bGwgIT0gdnZhcikKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBtX2luZGV4ID0gdnZhci5nZXRJbmRleCgpOwotICAgICAgICAgICAgbV9pc0dsb2JhbCA9IHRydWU7Ci0gICAgICAgICAgICBtX2ZpeFVwV2FzQ2FsbGVkID0gdHJ1ZTsKLSAgICAgICAgICAgIHJldHVybiBleGVjdXRlKHhjdHh0KTsKLSAgICAgICAgICB9Ci0KLSAgICAgICAgfQotICAgICAgfQotICAgICAgdGhyb3cgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24oWFNMTWVzc2FnZXMuY3JlYXRlWFBBVEhNZXNzYWdlKFhQQVRIRXJyb3JSZXNvdXJjZXMuRVJfVkFSX05PVF9SRVNPTFZBQkxFLCBuZXcgT2JqZWN0W117bV9xbmFtZS50b1N0cmluZygpfSkpOyAvLyJWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogIittX3FuYW1lKTsKLSAgICB9Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiByZXR1cm5zIGEgc3RhYmxlIG51bWJlciB0aGF0IHdpbGwgbm90IGNoYW5nZSBkdXJpbmcgCi0gICAqIGl0ZXJhdGlvbnMgd2l0aGluIHRoZSBleHByZXNzaW9uLiAgVGhpcyBpcyB1c2VkIHRvIGRldGVybWluZSBpZiBhIHByb3hpbWl0eSAKLSAgICogcG9zaXRpb24gcHJlZGljYXRlIGNhbiBpbmRpY2F0ZSB0aGF0IG5vIG1vcmUgc2VhcmNoaW5nIGhhcyB0byBvY2N1ci4KLSAgICogCi0gICAqCi0gICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZXhwcmVzc2lvbiByZXByZXNlbnRzIGEgc3RhYmxlIG51bWJlci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGlzU3RhYmxlTnVtYmVyKCkKLSAgewotICAgIHJldHVybiB0cnVlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMvcGFja2FnZS5odG1sIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGI0ZDRiZDAuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw4ICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WGFsYW4gWFBhdGggb3BlcmF0aW9ucy48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5TdXBwb3J0IGZvciBYUGF0aCBvcGVyYXRpb25zLCBzdWNoIGFzICssIC0sIHN0cmluZygpLCBldGMuPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhY2thZ2UuaHRtbCBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhY2thZ2UuaHRtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWEzNTEyYy4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw5ICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WFBhdGggc3VwcG9ydCBQYWNrYWdlLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkltcGxlbWVudGF0aW9uIG9mIFhQYXRoOyBmb3IgdGhlIG1vc3QgcGFydCwgb25seSBjbGFzc2VzIG1lYW50IGZvciBwdWJsaWMgdXNlIGFyZQotICAgIGZvdW5kIGF0IHRoaXMgcm9vdCBsZXZlbCBvZiB0aGUgWFBhdGggcGFja2FnZXMuPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL0NvbnRleHRNYXRjaFN0ZXBQYXR0ZXJuLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9Db250ZXh0TWF0Y2hTdGVwUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZTBjOTNlLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL0NvbnRleHRNYXRjaFN0ZXBQYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMTcgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJuczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1BeGlzVHJhdmVyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguYXhlcy5XYWxrZXJGYWN0b3J5OyAvLyBldmlsIGltcG9ydC4KLQotLyoqCi0gKiBTcGVjaWFsIGNvbnRleHQgbm9kZSBwYXR0ZXJuIG1hdGNoZXIuCi0gKi8KLXB1YmxpYyBjbGFzcyBDb250ZXh0TWF0Y2hTdGVwUGF0dGVybiBleHRlbmRzIFN0ZXBQYXR0ZXJuCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIENvbnRleHRNYXRjaFN0ZXBQYXR0ZXJuLgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqLwotICBwdWJsaWMgQ29udGV4dE1hdGNoU3RlcFBhdHRlcm4oaW50IGF4aXMsIGludCBwYXhpcykKLSAgewotICAgIHN1cGVyKERUTUZpbHRlci5TSE9XX0FMTCwgYXhpcywgcGF4aXMpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhpcyBwYXR0ZXJuIHN0ZXAsIGluY2x1ZGluZyBwcmVkaWNhdGVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKHhjdHh0LmdldEl0ZXJhdG9yUm9vdCgpID09IHhjdHh0LmdldEN1cnJlbnROb2RlKCkpCi0gICAgICByZXR1cm4gZ2V0U3RhdGljU2NvcmUoKTsKLSAgICBlbHNlCi0gICAgICByZXR1cm4gdGhpcy5TQ09SRV9OT05FOwotICB9Ci0gIAotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgbWF0Y2ggcGF0dGVybiBzdGVwIHJlbGF0aXZlIHRvIGFub3RoZXIgc3RlcC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIE5FRURTRE9DIEBwYXJhbSBwcmV2U3RlcAotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZVJlbGF0aXZlUGF0aFBhdHRlcm4oCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBTdGVwUGF0dGVybiBwcmV2U3RlcCkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIFhPYmplY3Qgc2NvcmUgPSBOb2RlVGVzdC5TQ09SRV9OT05FOwotICAgIGludCBjb250ZXh0ID0geGN0eHQuZ2V0Q3VycmVudE5vZGUoKTsKLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGNvbnRleHQpOwotCi0gICAgaWYgKG51bGwgIT0gZHRtKQotICAgIHsKLSAgICAgIGludCBwcmVkQ29udGV4dCA9IHhjdHh0LmdldEN1cnJlbnROb2RlKCk7Ci0gICAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlcjsKLSAgICAgIAotICAgICAgaW50IGF4aXMgPSBtX2F4aXM7Ci0gICAgICAKLSAgICAgIGJvb2xlYW4gbmVlZFRvVHJhdmVyc2VBdHRycyA9IFdhbGtlckZhY3RvcnkuaXNEb3dud2FyZEF4aXNPZk1hbnkoYXhpcyk7Ci0gICAgICBib29sZWFuIGl0ZXJSb290SXNBdHRyID0gKGR0bS5nZXROb2RlVHlwZSh4Y3R4dC5nZXRJdGVyYXRvclJvb3QoKSkgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSBEVE0uQVRUUklCVVRFX05PREUpOwotCi0gICAgICBpZigoQXhpcy5QUkVDRURJTkcgPT0gYXhpcykgJiYgaXRlclJvb3RJc0F0dHIpCi0gICAgICB7Ci0gICAgICAgIGF4aXMgPSBBeGlzLlBSRUNFRElOR0FOREFOQ0VTVE9SOwotICAgICAgfQotICAgICAgCi0gICAgICB0cmF2ZXJzZXIgPSBkdG0uZ2V0QXhpc1RyYXZlcnNlcihheGlzKTsKLQotICAgICAgZm9yIChpbnQgcmVsYXRpdmUgPSB0cmF2ZXJzZXIuZmlyc3QoY29udGV4dCk7IERUTS5OVUxMICE9IHJlbGF0aXZlOwotICAgICAgICAgICAgICByZWxhdGl2ZSA9IHRyYXZlcnNlci5uZXh0KGNvbnRleHQsIHJlbGF0aXZlKSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUocmVsYXRpdmUpOwotCi0gICAgICAgICAgc2NvcmUgPSBleGVjdXRlKHhjdHh0KTsKLQotICAgICAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICAgIHsKLQkgICAgICAvL3Njb3JlID0gZXhlY3V0ZVByZWRpY2F0ZXMoIHhjdHh0LCBwcmV2U3RlcCwgU0NPUkVfT1RIRVIsIAotCSAgICAgIC8vICAgICAgIHByZWRDb250ZXh0LCByZWxhdGl2ZSk7Ci0JICAgICAgaWYgKGV4ZWN1dGVQcmVkaWNhdGVzKHhjdHh0LCBkdG0sIGNvbnRleHQpKQotCQkgIHJldHVybiBzY29yZTsKLQkgICAgICAKLQkgICAgICBzY29yZSA9IE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgICAgICAgfQotICAgICAgICAgIAotICAgICAgICAgIGlmKG5lZWRUb1RyYXZlcnNlQXR0cnMgJiYgaXRlclJvb3RJc0F0dHIKLSAgICAgICAgICAgICAmJiAoRFRNLkVMRU1FTlRfTk9ERSA9PSBkdG0uZ2V0Tm9kZVR5cGUocmVsYXRpdmUpKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpbnQgeGF4aXMgPSBBeGlzLkFUVFJJQlVURTsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSAKLSAgICAgICAgICAgIHsgICAgICAgICAgICAKLSAgICAgICAgICAgICAgRFRNQXhpc1RyYXZlcnNlciBhdHJhdmVyc2VyID0gZHRtLmdldEF4aXNUcmF2ZXJzZXIoeGF4aXMpOwotICAgICAgICAKLSAgICAgICAgICAgICAgZm9yIChpbnQgYXJlbGF0aXZlID0gYXRyYXZlcnNlci5maXJzdChyZWxhdGl2ZSk7IAotICAgICAgICAgICAgICAgICAgICAgIERUTS5OVUxMICE9IGFyZWxhdGl2ZTsKLSAgICAgICAgICAgICAgICAgICAgICBhcmVsYXRpdmUgPSBhdHJhdmVyc2VyLm5leHQocmVsYXRpdmUsIGFyZWxhdGl2ZSkpCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoYXJlbGF0aXZlKTsKLSAgICAgICAgCi0gICAgICAgICAgICAgICAgICBzY29yZSA9IGV4ZWN1dGUoeGN0eHQpOwotICAgICAgICAKLSAgICAgICAgICAgICAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICAgICAgICAgICAgewotCQkgICAgICAvL3Njb3JlID0gZXhlY3V0ZVByZWRpY2F0ZXMoIHhjdHh0LCBwcmV2U3RlcCwgU0NPUkVfT1RIRVIsIAotCQkgICAgICAvLyAgICAgICBwcmVkQ29udGV4dCwgYXJlbGF0aXZlKTsKLSAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgIGlmIChzY29yZSAhPSBOb2RlVGVzdC5TQ09SRV9OT05FKQotICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzY29yZTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZmluYWxseQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgIHhheGlzID0gQXhpcy5OQU1FU1BBQ0U7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICAgICAgZmluYWxseQotICAgICAgICB7Ci0gICAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgfQotCi0gICAgcmV0dXJuIHNjb3JlOwotICB9Ci0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL0Z1bmN0aW9uUGF0dGVybi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvcGF0dGVybnMvRnVuY3Rpb25QYXR0ZXJuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNlOWYwYzYuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvcGF0dGVybnMvRnVuY3Rpb25QYXR0ZXJuLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyNTUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJuczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGg7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5FeHByZXNzaW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguWFBhdGhDb250ZXh0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YTnVtYmVyOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cy5YT2JqZWN0OwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUl0ZXJhdG9yOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogTWF0Y2ggcGF0dGVybiBzdGVwIHRoYXQgY29udGFpbnMgYSBmdW5jdGlvbi4KLSAqLwotcHVibGljIGNsYXNzIEZ1bmN0aW9uUGF0dGVybiBleHRlbmRzIFN0ZXBQYXR0ZXJuCi17Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhIEZ1bmN0aW9uUGF0dGVybiBmcm9tIGEKLSAgICoge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uIGV4cHJlc3Npb259LgotICAgKgotICAgKgotICAgKiBAcGFyYW0gYSBzaG91bGQgYmUgYSB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5mdW5jdGlvbnMuRnVuY3Rpb24gZXhwcmVzc2lvbn0uCi0gICAqCi0gICAqIE5FRURTRE9DIEBwYXJhbSBleHByCi0gICAqLwotICBwdWJsaWMgRnVuY3Rpb25QYXR0ZXJuKEV4cHJlc3Npb24gZXhwciwgaW50IGF4aXMsIGludCBwcmVkYXhpcykKLSAgewotCi0gICAgc3VwZXIoMCwgbnVsbCwgbnVsbCwgYXhpcywgcHJlZGF4aXMpOwotCi0gICAgbV9mdW5jdGlvbkV4cHIgPSBleHByOwotICB9Ci0KLSAgLyoqCi0gICAqIFN0YXRpYyBjYWxjIG9mIG1hdGNoIHNjb3JlLgotICAgKi8KLSAgcHVibGljIGZpbmFsIHZvaWQgY2FsY1Njb3JlKCkKLSAgewotCi0gICAgbV9zY29yZSA9IFNDT1JFX09USEVSOwotCi0gICAgaWYgKG51bGwgPT0gbV90YXJnZXRTdHJpbmcpCi0gICAgICBjYWxjVGFyZ2V0U3RyaW5nKCk7Ci0gIH0KLQotICAvKioKLSAgICogU2hvdWxkIGJlIGEge0BsaW5rIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zLkZ1bmN0aW9uIGV4cHJlc3Npb259LgotICAgKiAgQHNlcmlhbCAgIAotICAgKi8KLSAgRXhwcmVzc2lvbiBtX2Z1bmN0aW9uRXhwcjsKLSAgCi0gIC8qKgotICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml4dXAgdmFyaWFibGVzIGZyb20gUU5hbWVzIHRvIHN0YWNrIGZyYW1lIAotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdCAKLSAgICogc2hvdWxkIGJlIHNlYXJjaGVkIGJhY2t3YXJkcyBmb3IgdGhlIGZpcnN0IHF1YWxpZmllZCBuYW1lIHRoYXQgCi0gICAqIGNvcnJlc3BvbmRzIHRvIHRoZSB2YXJpYWJsZSByZWZlcmVuY2UgcW5hbWUuICBUaGUgcG9zaXRpb24gb2YgdGhlIAotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24gCi0gICAqIGluIHRoZSBzdGFjayBmcmFtZSAoYnV0IHZhcmlhYmxlcyBhYm92ZSB0aGUgZ2xvYmFsc1RvcCB2YWx1ZSB3aWxsIG5lZWQgCi0gICAqIHRvIGJlIG9mZnNldCB0byB0aGUgY3VycmVudCBzdGFjayBmcmFtZSkuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICBtX2Z1bmN0aW9uRXhwci5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gIH0KLQotICAKLSAgLyoqCi0gICAqIFRlc3QgYSBub2RlIHRvIHNlZSBpZiBpdCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlIHRlc3QuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PTkV9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05TV0lMRH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX09USEVSfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRFRNSXRlcmF0b3IgbmwgPSBtX2Z1bmN0aW9uRXhwci5hc0l0ZXJhdG9yKHhjdHh0LCBjb250ZXh0KTsKLSAgICBYTnVtYmVyIHNjb3JlID0gU0NPUkVfTk9ORTsKLQotICAgIGlmIChudWxsICE9IG5sKQotICAgIHsKLSAgICAgIGludCBuOwotCi0gICAgICB3aGlsZSAoRFRNLk5VTEwgIT0gKG4gPSBubC5uZXh0Tm9kZSgpKSkKLSAgICAgIHsKLSAgICAgICAgc2NvcmUgPSAobiA9PSBjb250ZXh0KSA/IFNDT1JFX09USEVSIDogU0NPUkVfTk9ORTsKLQotICAgICAgICBpZiAoc2NvcmUgPT0gU0NPUkVfT1RIRVIpCi0gICAgICAgIHsKLSAgICAgICAgICBjb250ZXh0ID0gbjsKLQotICAgICAgICAgIGJyZWFrOwotICAgICAgICB9Ci0gICAgICB9Ci0KLSAgICAgIC8vIG5sLmRldGFjaCgpOwotICAgIH0KLSAgICBubC5kZXRhY2goKTsKLQotICAgIHJldHVybiBzY29yZTsKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlc3QgYSBub2RlIHRvIHNlZSBpZiBpdCBtYXRjaGVzIHRoZSBnaXZlbiBub2RlIHRlc3QuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PTkV9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05TV0lMRH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX09USEVSfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQsIAotICAgICAgICAgICAgICAgICAgICAgICAgIERUTSBkdG0sIGludCBleHBUeXBlKQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIERUTUl0ZXJhdG9yIG5sID0gbV9mdW5jdGlvbkV4cHIuYXNJdGVyYXRvcih4Y3R4dCwgY29udGV4dCk7Ci0gICAgWE51bWJlciBzY29yZSA9IFNDT1JFX05PTkU7Ci0KLSAgICBpZiAobnVsbCAhPSBubCkKLSAgICB7Ci0gICAgICBpbnQgbjsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmwubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIHNjb3JlID0gKG4gPT0gY29udGV4dCkgPyBTQ09SRV9PVEhFUiA6IFNDT1JFX05PTkU7Ci0KLSAgICAgICAgaWYgKHNjb3JlID09IFNDT1JFX09USEVSKQotICAgICAgICB7Ci0gICAgICAgICAgY29udGV4dCA9IG47Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBubC5kZXRhY2goKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc2NvcmU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBUZXN0IGEgbm9kZSB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gbm9kZSB0ZXN0LgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIERUTUl0ZXJhdG9yIG5sID0gbV9mdW5jdGlvbkV4cHIuYXNJdGVyYXRvcih4Y3R4dCwgY29udGV4dCk7Ci0gICAgWE51bWJlciBzY29yZSA9IFNDT1JFX05PTkU7Ci0KLSAgICBpZiAobnVsbCAhPSBubCkKLSAgICB7Ci0gICAgICBpbnQgbjsKLQotICAgICAgd2hpbGUgKERUTS5OVUxMICE9IChuID0gbmwubmV4dE5vZGUoKSkpCi0gICAgICB7Ci0gICAgICAgIHNjb3JlID0gKG4gPT0gY29udGV4dCkgPyBTQ09SRV9PVEhFUiA6IFNDT1JFX05PTkU7Ci0KLSAgICAgICAgaWYgKHNjb3JlID09IFNDT1JFX09USEVSKQotICAgICAgICB7Ci0gICAgICAgICAgY29udGV4dCA9IG47Ci0KLSAgICAgICAgICBicmVhazsKLSAgICAgICAgfQotICAgICAgfQotCi0gICAgICBubC5kZXRhY2goKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gc2NvcmU7Ci0gIH0KLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL05vZGVUZXN0LmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9Ob2RlVGVzdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5NmM4MTA0Li4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL05vZGVUZXN0LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw2ODIgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJuczsKLQotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuT3BDb2RlczsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoOwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguRXhwcmVzc2lvbjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLlhQYXRoQ29udGV4dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE51bWJlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDsKLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLldoaXRlc3BhY2VTdHJpcHBpbmdFbGVtZW50TWF0Y2hlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC51dGlscy5QcmVmaXhSZXNvbHZlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE07Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLnJlZi5FeHBhbmRlZE5hbWVUYWJsZTsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iYWR2YW5jZWQiLz4KLSAqIFRoaXMgaXMgdGhlIGJhc2ljIG5vZGUgdGVzdCBjbGFzcyBmb3IgYm90aCBtYXRjaCBwYXR0ZXJucyBhbmQgbG9jYXRpb24gcGF0aAotICogc3RlcHMuCi0gKi8KLXB1YmxpYyBjbGFzcyBOb2RlVGVzdCBleHRlbmRzIEV4cHJlc3Npb24KLXsKLQotICAvKioKLSAgICogVGhlIG5hbWVzcGFjZSBvciBsb2NhbCBuYW1lIGZvciBub2RlIHRlc3RzIHdpdGggYSB3aWxkY2FyZC4KLSAgICogIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgjTlQtTmFtZVRlc3QiPnRoZSBYUGF0aCBOYW1lVGVzdCBwcm9kdWN0aW9uLjwvYT4gCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXSUxEID0gIioiOwotCi0gIC8qKgotICAgKiBUaGUgVVJMIHRvIHBhc3MgdG8gdGhlIE5vZGUjc3VwcG9ydHMgbWV0aG9kLCB0byBzZWUgaWYgdGhlCi0gICAqIERPTSBoYXMgYWxyZWFkeSBiZWVuIHN0cmlwcGVkIG9mIHdoaXRlc3BhY2Ugbm9kZXMuIAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1VQUE9SVFNfUFJFX1NUUklQUElORyA9Ci0gICAgImh0dHA6Ly94bWwuYXBhY2hlLm9yZy94cGF0aC9mZWF0dXJlcy93aGl0ZXNwYWNlLXByZS1zdHJpcHBpbmciOwotCi0gIC8qKgotICAgKiBUaGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIHdoaWNoIG5vZGUgdHlwZXMgYXJlIGFjY2VwdGVkLgotICAgKiBAc2VyaWFsCi0gICAqLwotICBwcm90ZWN0ZWQgaW50IG1fd2hhdFRvU2hvdzsKLQotICAvKioKLSAgICogU3BlY2lhbCBiaXRtYXAgZm9yIG1hdGNoIHBhdHRlcm5zIHN0YXJ0aW5nIHdpdGggYSBmdW5jdGlvbi4KLSAgICogTWFrZSBzdXJlIHRoaXMgZG9lcyBub3QgY29uZmxpY3Qgd2l0aCB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0hPV19CWUZVTkNUSU9OID0gMHgwMDAxMDAwMDsKLQotICAvKioKLSAgICogVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBhY2NlcHRlZC4KLSAgICogVGhlc2UgY29uc3RhbnRzIGFyZSBkZWZpbmVkIGluIHRoZSB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9Ci0gICAqIGludGVyZmFjZS4KLSAgICoKLSAgICogQHJldHVybiBiaXRzZXQgbWFpbmx5IGRlZmluZWQgaW4ge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICovCi0gIHB1YmxpYyBpbnQgZ2V0V2hhdFRvU2hvdygpCi0gIHsKLSAgICByZXR1cm4gbV93aGF0VG9TaG93OwotICB9Ci0gIAotICAvKioKLSAgICogVGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyB3aGljaCBub2RlIHR5cGVzIGFyZSBhY2NlcHRlZC4KLSAgICogVGhlc2UgY29uc3RhbnRzIGFyZSBkZWZpbmVkIGluIHRoZSB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9Ci0gICAqIGludGVyZmFjZS4KLSAgICoKLSAgICogQHBhcmFtIHdoYXQgYml0c2V0IG1haW5seSBkZWZpbmVkIGluIHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXRXaGF0VG9TaG93KGludCB3aGF0KQotICB7Ci0gICAgbV93aGF0VG9TaG93ID0gd2hhdDsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbmFtZXNwYWNlIHRvIGJlIHRlc3RlZCBmb3IsIHdoaWNoIG1heSBiZSBudWxsLgotICAgKiAgQHNlcmlhbCAKLSAgICovCi0gIFN0cmluZyBtX25hbWVzcGFjZTsKLQotICAvKioKLSAgICogUmV0dXJuIHRoZSBuYW1lc3BhY2UgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBuYW1lc3BhY2UgdG8gYmUgdGVzdGVkIGZvciwgb3Ige0BsaW5rICNXSUxEfSwgb3IgbnVsbC4KLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZXNwYWNlKCkKLSAgewotICAgIHJldHVybiBtX25hbWVzcGFjZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSBucyBUaGUgbmFtZXNwYWNlIHRvIGJlIHRlc3RlZCBmb3IsIG9yIHtAbGluayAjV0lMRH0sIG9yIG51bGwuCi0gICAqLwotICBwdWJsaWMgdm9pZCBzZXROYW1lc3BhY2UoU3RyaW5nIG5zKQotICB7Ci0gICAgbV9uYW1lc3BhY2UgPSBuczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbG9jYWwgbmFtZSB0byBiZSB0ZXN0ZWQgZm9yLgotICAgKiAgQHNlcmlhbCAKLSAgICovCi0gIHByb3RlY3RlZCBTdHJpbmcgbV9uYW1lOwotCi0gIC8qKgotICAgKiBSZXR1cm4gdGhlIGxvY2FsIG5hbWUgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZCwgb3Ige0BsaW5rICNXSUxEfSwgb3IgYW4gZW1wdHkgc3RyaW5nLgotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRMb2NhbE5hbWUoKQotICB7Ci0gICAgcmV0dXJuIChudWxsID09IG1fbmFtZSkgPyAiIiA6IG1fbmFtZTsKLSAgfQotCi0gIC8qKgotICAgKiBTZXQgdGhlIGxvY2FsIG5hbWUgdG8gYmUgdGVzdGVkLgotICAgKgotICAgKiBAcGFyYW0gbmFtZSB0aGUgbG9jYWwgbmFtZSB0byBiZSB0ZXN0ZWQsIG9yIHtAbGluayAjV0lMRH0sIG9yIGFuIGVtcHR5IHN0cmluZy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldExvY2FsTmFtZShTdHJpbmcgbmFtZSkKLSAgewotICAgIG1fbmFtZSA9IG5hbWU7Ci0gIH0KLQotICAvKioKLSAgICogU3RhdGljYWxseSBjYWxjdWxhdGVkIHNjb3JlIGZvciB0aGlzIHRlc3QuICBPbmUgb2YKLSAgICogIHtAbGluayAjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAge0BsaW5rICNTQ09SRV9OT05FfSwKLSAgICogIHtAbGluayAjU0NPUkVfTlNXSUxEfSwKLSAgICogIHtAbGluayAjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAge0BsaW5rICNTQ09SRV9PVEhFUn0uCi0gICAqICBAc2VyaWFsCi0gICAqLwotICBYTnVtYmVyIG1fc2NvcmU7Ci0KLSAgLyoqCi0gICAqIFRoZSBtYXRjaCBzY29yZSBpZiB0aGUgcGF0dGVybiBjb25zaXN0cyBvZiBqdXN0IGEgTm9kZVRlc3QuCi0gICAqICBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPlhTTFQgU3BlY2lmaWNhdGlvbiAtIDUuNSBDb25mbGljdCBSZXNvbHV0aW9uIGZvciBUZW1wbGF0ZSBSdWxlczwvYT4gCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhOdW1iZXIgU0NPUkVfTk9ERVRFU1QgPQotICAgIG5ldyBYTnVtYmVyKFhQYXRoLk1BVENIX1NDT1JFX05PREVURVNUKTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIHBhdHRlcm4gaGFzIHRoZSBmb3JtIE5DTmFtZToqLgotICAgKiAgQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2NvbmZsaWN0Ij5YU0xUIFNwZWNpZmljYXRpb24gLSA1LjUgQ29uZmxpY3QgUmVzb2x1dGlvbiBmb3IgVGVtcGxhdGUgUnVsZXM8L2E+IAotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYTnVtYmVyIFNDT1JFX05TV0lMRCA9Ci0gICAgbmV3IFhOdW1iZXIoWFBhdGguTUFUQ0hfU0NPUkVfTlNXSUxEKTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGhhcyB0aGUgZm9ybQotICAgKiBvZiBhIFFOYW1lIG9wdGlvbmFsbHkgcHJlY2VkZWQgYnkgYW4gQCBjaGFyYWN0ZXIuCi0gICAqICBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPlhTTFQgU3BlY2lmaWNhdGlvbiAtIDUuNSBDb25mbGljdCBSZXNvbHV0aW9uIGZvciBUZW1wbGF0ZSBSdWxlczwvYT4gCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhOdW1iZXIgU0NPUkVfUU5BTUUgPQotICAgIG5ldyBYTnVtYmVyKFhQYXRoLk1BVENIX1NDT1JFX1FOQU1FKTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIHRoZSBwYXR0ZXJuIGNvbnNpc3RzIG9mIHNvbWV0aGluZwotICAgKiBvdGhlciB0aGFuIGp1c3QgYSBOb2RlVGVzdCBvciBqdXN0IGEgcW5hbWUuCi0gICAqICBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPlhTTFQgU3BlY2lmaWNhdGlvbiAtIDUuNSBDb25mbGljdCBSZXNvbHV0aW9uIGZvciBUZW1wbGF0ZSBSdWxlczwvYT4gCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhOdW1iZXIgU0NPUkVfT1RIRVIgPQotICAgIG5ldyBYTnVtYmVyKFhQYXRoLk1BVENIX1NDT1JFX09USEVSKTsKLQotICAvKioKLSAgICogVGhlIG1hdGNoIHNjb3JlIGlmIG5vIG1hdGNoIGlzIG1hZGUuCi0gICAqICBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjY29uZmxpY3QiPlhTTFQgU3BlY2lmaWNhdGlvbiAtIDUuNSBDb25mbGljdCBSZXNvbHV0aW9uIGZvciBUZW1wbGF0ZSBSdWxlczwvYT4gCi0gICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFhOdW1iZXIgU0NPUkVfTk9ORSA9Ci0gICAgbmV3IFhOdW1iZXIoWFBhdGguTUFUQ0hfU0NPUkVfTk9ORSk7Ci0KLSAgLyoqCi0gICAqIENvbnN0cnVjdCBhbiBOb2RlVGVzdCB0aGF0IHRlc3RzIGZvciBuYW1lc3BhY2VzIGFuZCBub2RlIG5hbWVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZC4KLSAgICovCi0gIHB1YmxpYyBOb2RlVGVzdChpbnQgd2hhdFRvU2hvdywgU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpCi0gIHsKLSAgICBpbml0Tm9kZVRlc3Qod2hhdFRvU2hvdywgbmFtZXNwYWNlLCBuYW1lKTsKLSAgfQotCi0gIC8qKgotICAgKiBDb25zdHJ1Y3QgYW4gTm9kZVRlc3QgdGhhdCBkb2Vzbid0IHRlc3QgZm9yIG5vZGUgbmFtZXMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IEJpdCBzZXQgZGVmaW5lZCBtYWlubHkgYnkge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICovCi0gIHB1YmxpYyBOb2RlVGVzdChpbnQgd2hhdFRvU2hvdykKLSAgewotICAgIGluaXROb2RlVGVzdCh3aGF0VG9TaG93KTsKLSAgfQotCi0gIC8qKgotICAgKiBOdWxsIGFyZ3VtZW50IGNvbnN0cnVjdG9yLgotICAgKi8KLSAgcHVibGljIE5vZGVUZXN0KCl7fQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoaXMgbm9kZSB0ZXN0IGJ5IHNldHRpbmcgdGhlIHdoYXRUb1Nob3cgcHJvcGVydHksIGFuZAotICAgKiBjYWxjdWxhdGluZyB0aGUgc2NvcmUgdGhhdCB0aGlzIHRlc3Qgd2lsbCByZXR1cm4gaWYgYSB0ZXN0IHN1Y2NlZWRzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqLwotICBwdWJsaWMgdm9pZCBpbml0Tm9kZVRlc3QoaW50IHdoYXRUb1Nob3cpCi0gIHsKLQotICAgIG1fd2hhdFRvU2hvdyA9IHdoYXRUb1Nob3c7Ci0KLSAgICBjYWxjU2NvcmUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBJbml0aWFsaXplIHRoaXMgbm9kZSB0ZXN0IGJ5IHNldHRpbmcgdGhlIHdoYXRUb1Nob3cgcHJvcGVydHkgYW5kIHRoZQotICAgKiBuYW1lc3BhY2UgYW5kIGxvY2FsIG5hbWUsIGFuZAotICAgKiBjYWxjdWxhdGluZyB0aGUgc2NvcmUgdGhhdCB0aGlzIHRlc3Qgd2lsbCByZXR1cm4gaWYgYSB0ZXN0IHN1Y2NlZWRzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IHtAbGluayBvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUZpbHRlcn0uCi0gICAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSB0byBiZSB0ZXN0ZWQuCi0gICAqIEBwYXJhbSBuYW1lIFRoZSBsb2NhbCBuYW1lIHRvIGJlIHRlc3RlZC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGluaXROb2RlVGVzdChpbnQgd2hhdFRvU2hvdywgU3RyaW5nIG5hbWVzcGFjZSwgU3RyaW5nIG5hbWUpCi0gIHsKLQotICAgIG1fd2hhdFRvU2hvdyA9IHdoYXRUb1Nob3c7Ci0gICAgbV9uYW1lc3BhY2UgPSBuYW1lc3BhY2U7Ci0gICAgbV9uYW1lID0gbmFtZTsKLQotICAgIGNhbGNTY29yZSgpOwotICB9Ci0KLSAgLyoqCi0gICAqIFRydWUgaWYgdGhpcyB0ZXN0IGhhcyBhIG51bGwgbmFtZXNwYWNlIGFuZCBhIGxvY2FsIG5hbWUgb2Yge0BsaW5rICNXSUxEfS4KLSAgICogIEBzZXJpYWwgCi0gICAqLwotICBwcml2YXRlIGJvb2xlYW4gbV9pc1RvdGFsbHlXaWxkOwotICAKLSAgLyoqCi0gICAqIEdldCB0aGUgc3RhdGljIHNjb3JlIGZvciB0aGlzIG5vZGUgdGVzdC4KLSAgICogQHJldHVybiBTaG91bGQgYmUgb25lIG9mIHRoZSBTQ09SRV9YWFggY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIFhOdW1iZXIgZ2V0U3RhdGljU2NvcmUoKQotICB7Ci0gICAgcmV0dXJuIG1fc2NvcmU7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBTZXQgdGhlIHN0YXRpYyBzY29yZSBmb3IgdGhpcyBub2RlIHRlc3QuCi0gICAqIEBwYXJhbSBzY29yZSBTaG91bGQgYmUgb25lIG9mIHRoZSBTQ09SRV9YWFggY29uc3RhbnRzLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0U3RhdGljU2NvcmUoWE51bWJlciBzY29yZSkKLSAgewotICAgIG1fc2NvcmUgPSBzY29yZTsKLSAgfQotCi0gIC8qKgotICAgKiBTdGF0aWMgY2FsYyBvZiBtYXRjaCBzY29yZS4KLSAgICovCi0gIHByb3RlY3RlZCB2b2lkIGNhbGNTY29yZSgpCi0gIHsKLQotICAgIGlmICgobV9uYW1lc3BhY2UgPT0gbnVsbCkgJiYgKG1fbmFtZSA9PSBudWxsKSkKLSAgICAgIG1fc2NvcmUgPSBTQ09SRV9OT0RFVEVTVDsKLSAgICBlbHNlIGlmICgoKG1fbmFtZXNwYWNlID09IFdJTEQpIHx8IChtX25hbWVzcGFjZSA9PSBudWxsKSkKLSAgICAgICAgICAgICAmJiAobV9uYW1lID09IFdJTEQpKQotICAgICAgbV9zY29yZSA9IFNDT1JFX05PREVURVNUOwotICAgIGVsc2UgaWYgKChtX25hbWVzcGFjZSAhPSBXSUxEKSAmJiAobV9uYW1lID09IFdJTEQpKQotICAgICAgbV9zY29yZSA9IFNDT1JFX05TV0lMRDsKLSAgICBlbHNlCi0gICAgICBtX3Njb3JlID0gU0NPUkVfUU5BTUU7Ci0KLSAgICBtX2lzVG90YWxseVdpbGQgPSAobV9uYW1lc3BhY2UgPT0gbnVsbCAmJiBtX25hbWUgPT0gV0lMRCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBzY29yZSB0aGF0IHRoaXMgdGVzdCB3aWxsIHJldHVybiBpZiBhIHRlc3Qgc3VjY2VlZHMuCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gdGhlIHNjb3JlIHRoYXQgdGhpcyB0ZXN0IHdpbGwgcmV0dXJuIGlmIGEgdGVzdCBzdWNjZWVkcy4KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgZ2V0RGVmYXVsdFNjb3JlKCkKLSAgewotICAgIHJldHVybiBtX3Njb3JlLm51bSgpOwotICB9Ci0gIAotICAvKioKLSAgICogVGVsbCB3aGF0IG5vZGUgdHlwZSB0byB0ZXN0LCBpZiBub3QgRFRNRmlsdGVyLlNIT1dfQUxMLgotICAgKgotICAgKiBAcGFyYW0gd2hhdFRvU2hvdyBCaXQgc2V0IGRlZmluZWQgbWFpbmx5IGJ5IAotICAgKiAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueG1sLmR0bS5EVE1GaWx0ZXJ9LgotICAgKiBAcmV0dXJuIHRoZSBub2RlIHR5cGUgZm9yIHRoZSB3aGF0VG9TaG93LiAgU2luY2Ugd2hhdFRvU2hvdyBjYW4gc3BlY2lmeSAKLSAgICogICAgICAgICBtdWx0aXBsZSB0eXBlcywgaXQgd2lsbCByZXR1cm4gdGhlIGZpcnN0IGJpdCB0ZXN0ZWQgdGhhdCBpcyBvbiwgCi0gICAqICAgICAgICAgc28gdGhlIGNhbGxlciBvZiB0aGlzIGZ1bmN0aW9uIHNob3VsZCB0YWtlIGNhcmUgdGhhdCB0aGlzIGlzIAotICAgKiAgICAgICAgIHRoZSBmdW5jdGlvbiB0aGV5IHJlYWxseSB3YW50IHRvIGNhbGwuICBJZiBub25lIG9mIHRoZSBrbm93biBiaXRzCi0gICAqICAgICAgICAgYXJlIHNldCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB6ZXJvLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBpbnQgZ2V0Tm9kZVR5cGVUZXN0KGludCB3aGF0VG9TaG93KQotICB7Ci0gICAgLy8gJVJFVklFVyUgSXMgdGhlcmUgYSBiZXR0ZXIgd2F5PwotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRUxFTUVOVCkpCi0gICAgICByZXR1cm4gRFRNLkVMRU1FTlRfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFKSkKLSAgICAgIHJldHVybiBEVE0uQVRUUklCVVRFX05PREU7Ci0gICAgICAKLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX1RFWFQpKQotICAgICAgcmV0dXJuIERUTS5URVhUX05PREU7Ci0gICAgICAKLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UKSkKLSAgICAgIHJldHVybiBEVE0uRE9DVU1FTlRfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQpKQotICAgICAgcmV0dXJuIERUTS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0UpKQotICAgICAgcmV0dXJuIERUTS5OQU1FU1BBQ0VfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQ09NTUVOVCkpCi0gICAgICByZXR1cm4gRFRNLkNPTU1FTlRfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikpCi0gICAgICByZXR1cm4gRFRNLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfVFlQRSkpCi0gICAgICByZXR1cm4gRFRNLkRPQ1VNRU5UX1RZUEVfTk9ERTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRU5USVRZKSkKLSAgICAgIHJldHVybiBEVE0uRU5USVRZX05PREU7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0VOVElUWV9SRUZFUkVOQ0UpKQotICAgICAgcmV0dXJuIERUTS5FTlRJVFlfUkVGRVJFTkNFX05PREU7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX05PVEFUSU9OKSkKLSAgICAgIHJldHVybiBEVE0uTk9UQVRJT05fTk9ERTsKLSAgICAgIAotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfQ0RBVEFfU0VDVElPTikpCi0gICAgICByZXR1cm4gRFRNLkNEQVRBX1NFQ1RJT05fTk9ERTsKLQotCi0gICAgcmV0dXJuIDA7Ci0gIH0KLQotCi0gIC8qKgotICAgKiBEbyBhIGRpYWdub3N0aWNzIGR1bXAgb2YgYSB3aGF0VG9TaG93IGJpdCBzZXQuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IEJpdCBzZXQgZGVmaW5lZCBtYWlubHkgYnkgCi0gICAqICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54bWwuZHRtLkRUTUZpbHRlcn0uCi0gICAqLwotICBwdWJsaWMgc3RhdGljIHZvaWQgZGVidWdXaGF0VG9TaG93KGludCB3aGF0VG9TaG93KQotICB7Ci0KLSAgICBqYXZhLnV0aWwuVmVjdG9yIHYgPSBuZXcgamF2YS51dGlsLlZlY3RvcigpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUpKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX0FUVFJJQlVURSIpOwotICAgICAgCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19OQU1FU1BBQ0UpKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX05BTUVTUEFDRSIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19DREFUQV9TRUNUSU9OIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0NPTU1FTlQpKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX0NPTU1FTlQiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlQpKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX0RPQ1VNRU5UIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19ET0NVTUVOVF9GUkFHTUVOVCIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVF9UWVBFKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19ET0NVTUVOVF9UWVBFIik7Ci0KLSAgICBpZiAoMCAhPSAod2hhdFRvU2hvdyAmIERUTUZpbHRlci5TSE9XX0VMRU1FTlQpKQotICAgICAgdi5hZGRFbGVtZW50KCJTSE9XX0VMRU1FTlQiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRU5USVRZKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19FTlRJVFkiKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfRU5USVRZX1JFRkVSRU5DRSkpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfRU5USVRZX1JFRkVSRU5DRSIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19OT1RBVElPTikpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfTk9UQVRJT04iKTsKLQotICAgIGlmICgwICE9ICh3aGF0VG9TaG93ICYgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTikpCi0gICAgICB2LmFkZEVsZW1lbnQoIlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiIpOwotCi0gICAgaWYgKDAgIT0gKHdoYXRUb1Nob3cgJiBEVE1GaWx0ZXIuU0hPV19URVhUKSkKLSAgICAgIHYuYWRkRWxlbWVudCgiU0hPV19URVhUIik7Ci0KLSAgICBpbnQgbiA9IHYuc2l6ZSgpOwotCi0gICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgewotICAgICAgaWYgKGkgPiAwKQotICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgfCAiKTsKLQotICAgICAgU3lzdGVtLm91dC5wcmludCh2LmVsZW1lbnRBdChpKSk7Ci0gICAgfQotCi0gICAgaWYgKDAgPT0gbikKLSAgICAgIFN5c3RlbS5vdXQucHJpbnQoImVtcHR5IHdoYXRUb1Nob3c6ICIgKyB3aGF0VG9TaG93KTsKLQotICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwotICB9Ci0KLSAgLyoqCi0gICAqIFR3byBuYW1lcyBhcmUgZXF1YWwgaWYgdGhleSBhbmQgZWl0aGVyIGJvdGggYXJlIG51bGwgb3IKLSAgICogdGhlIG5hbWUgdCBpcyB3aWxkIGFuZCB0aGUgbmFtZSBwIGlzIG5vbi1udWxsLCBvciB0aGUgdHdvCi0gICAqIHN0cmluZ3MgYXJlIGVxdWFsLgotICAgKgotICAgKiBAcGFyYW0gcCBwYXJ0IHN0cmluZyBmcm9tIHRoZSBub2RlLgotICAgKiBAcGFyYW0gdCB0YXJnZXQgc3RyaW5nLCB3aGljaCBtYXkgYmUge0BsaW5rICNXSUxEfS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmdzIG1hdGNoIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgdGhpcyBtZXRob2QuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHN1YlBhcnRNYXRjaChTdHJpbmcgcCwgU3RyaW5nIHQpCi0gIHsKLQotICAgIC8vIGJvb2xlYW4gYiA9IChwID09IHQpIHx8ICgobnVsbCAhPSBwKSAmJiAoKHQgPT0gV0lMRCkgfHwgcC5lcXVhbHModCkpKTsKLSAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oInN1YlBhcnRNYXRjaCAtIHA6ICIrcCsiLCB0OiAiK3QrIiwgcmVzdWx0OiAiK2IpOwotICAgIHJldHVybiAocCA9PSB0KSB8fCAoKG51bGwgIT0gcCkgJiYgKCh0ID09IFdJTEQpIHx8IHAuZXF1YWxzKHQpKSk7Ci0gIH0KLQotICAvKioKLSAgICogVGhpcyBpcyB0ZW1wb3JhcnkgdG8gcGF0Y2ggb3ZlciBYZXJjZXMgaXNzdWUgd2l0aCByZXByZXNlbnRpbmcgRE9NCi0gICAqIG5hbWVzcGFjZXMgYXMgIiIuCi0gICAqCi0gICAqIEBwYXJhbSBwIHBhcnQgc3RyaW5nIGZyb20gdGhlIG5vZGUsIHdoaWNoIG1heSByZXByZXNlbnQgdGhlIG51bGwgbmFtZXNwYWNlCi0gICAqICAgICAgICBhcyBudWxsIG9yIGFzICIiLgotICAgKiBAcGFyYW0gdCB0YXJnZXQgc3RyaW5nLCB3aGljaCBtYXkgYmUge0BsaW5rICNXSUxEfS4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmdzIG1hdGNoIGFjY29yZGluZyB0byB0aGUgcnVsZXMgb2YgdGhpcyBtZXRob2QuCi0gICAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHN1YlBhcnRNYXRjaE5TKFN0cmluZyBwLCBTdHJpbmcgdCkKLSAgewotCi0gICAgcmV0dXJuIChwID09IHQpCi0gICAgICAgICAgIHx8ICgobnVsbCAhPSBwKQotICAgICAgICAgICAgICAgJiYgKChwLmxlbmd0aCgpID4gMCkKLSAgICAgICAgICAgICAgICAgICA/ICgodCA9PSBXSUxEKSB8fCBwLmVxdWFscyh0KSkgOiBudWxsID09IHQpKTsKLSAgfQotCi0gIC8qKgotICAgKiBUZWxsIHdoYXQgdGhlIHRlc3Qgc2NvcmUgaXMgZm9yIHRoZSBnaXZlbiBub2RlLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgbm9kZSBiZWluZyB0ZXN0ZWQuCi0gICAqCi0gICAqIEByZXR1cm4ge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ERVRFU1R9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PTkV9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05TV0lMRH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfUU5BTUV9LCBvcgotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX09USEVSfS4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGNvbnRleHQpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgRFRNIGR0bSA9IHhjdHh0LmdldERUTShjb250ZXh0KTsKLSAgICBzaG9ydCBub2RlVHlwZSA9IGR0bS5nZXROb2RlVHlwZShjb250ZXh0KTsKLQotICAgIGlmIChtX3doYXRUb1Nob3cgPT0gRFRNRmlsdGVyLlNIT1dfQUxMKQotICAgICAgcmV0dXJuIG1fc2NvcmU7Ci0KLSAgICBpbnQgbm9kZUJpdCA9IChtX3doYXRUb1Nob3cgJiAoMHgwMDAwMDAwMSA8PCAobm9kZVR5cGUgLSAxKSkpOwotCi0gICAgc3dpdGNoIChub2RlQml0KQotICAgIHsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UIDoKLSAgICAgIHJldHVybiBTQ09SRV9PVEhFUjsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0NPTU1FTlQgOgotICAgICAgcmV0dXJuIG1fc2NvcmU7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX1RFWFQgOgotCi0gICAgICAvLyB3YXM6IAotICAgICAgLy8gcmV0dXJuICgheGN0eHQuZ2V0RE9NSGVscGVyKCkuc2hvdWxkU3RyaXBTb3VyY2VOb2RlKGNvbnRleHQpKQotICAgICAgLy8gICAgICAgPyBtX3Njb3JlIDogU0NPUkVfTk9ORTsKLSAgICAgIHJldHVybiBtX3Njb3JlOwotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA6Ci0gICAgICByZXR1cm4gc3ViUGFydE1hdGNoKGR0bS5nZXROb2RlTmFtZShjb250ZXh0KSwgbV9uYW1lKQotICAgICAgICAgICAgID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0KLSAgICAvLyBGcm9tIHRoZSBkcmFmdDogIlR3byBleHBhbmRlZCBuYW1lcyBhcmUgZXF1YWwgaWYgdGhleSAKLSAgICAvLyBoYXZlIHRoZSBzYW1lIGxvY2FsIHBhcnQsIGFuZCBlaXRoZXIgYm90aCBoYXZlIG5vIFVSSSBvciAKLSAgICAvLyBib3RoIGhhdmUgdGhlIHNhbWUgVVJJLiIKLSAgICAvLyAiQSBub2RlIHRlc3QgKiBpcyB0cnVlIGZvciBhbnkgbm9kZSBvZiB0aGUgcHJpbmNpcGFsIG5vZGUgdHlwZS4gCi0gICAgLy8gRm9yIGV4YW1wbGUsIGNoaWxkOjoqIHdpbGwgc2VsZWN0IGFsbCBlbGVtZW50IGNoaWxkcmVuIG9mIHRoZSAKLSAgICAvLyBjb250ZXh0IG5vZGUsIGFuZCBhdHRyaWJ1dGU6Oiogd2lsbCBzZWxlY3QgYWxsIGF0dHJpYnV0ZXMgb2YgCi0gICAgLy8gdGhlIGNvbnRleHQgbm9kZS4iCi0gICAgLy8gIkEgbm9kZSB0ZXN0IGNhbiBoYXZlIHRoZSBmb3JtIE5DTmFtZToqLiBJbiB0aGlzIGNhc2UsIHRoZSBwcmVmaXggCi0gICAgLy8gaXMgZXhwYW5kZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHdpdGggYSBRTmFtZSB1c2luZyB0aGUgY29udGV4dCAKLSAgICAvLyBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLiBUaGUgbm9kZSB0ZXN0IHdpbGwgYmUgdHJ1ZSBmb3IgYW55IG5vZGUgCi0gICAgLy8gb2YgdGhlIHByaW5jaXBhbCB0eXBlIHdob3NlIGV4cGFuZGVkIG5hbWUgaGFzIHRoZSBVUkkgdG8gd2hpY2ggCi0gICAgLy8gdGhlIHByZWZpeCBleHBhbmRzLCByZWdhcmRsZXNzIG9mIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBuYW1lLiIKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX05BTUVTUEFDRSA6Ci0gICAgewotICAgICAgU3RyaW5nIG5zID0gZHRtLmdldE5vZGVWYWx1ZShjb250ZXh0KTsKLQotICAgICAgcmV0dXJuIChzdWJQYXJ0TWF0Y2gobnMsIG1fbmFtZSkpID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0gICAgfQotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0VMRU1FTlQgOgotICAgIHsKLSAgICAgIHJldHVybiAobV9pc1RvdGFsbHlXaWxkIHx8IChzdWJQYXJ0TWF0Y2hOUyhkdG0uZ2V0TmFtZXNwYWNlVVJJKGNvbnRleHQpLCBtX25hbWVzcGFjZSkgJiYgc3ViUGFydE1hdGNoKGR0bS5nZXRMb2NhbE5hbWUoY29udGV4dCksIG1fbmFtZSkpKQotICAgICAgICAgICAgID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0gICAgfQotICAgIGRlZmF1bHQgOgotICAgICAgcmV0dXJuIFNDT1JFX05PTkU7Ci0gICAgfSAgLy8gZW5kIHN3aXRjaCh0ZXN0VHlwZSkKLSAgfQotICAKLSAgLyoqCi0gICAqIFRlbGwgd2hhdCB0aGUgdGVzdCBzY29yZSBpcyBmb3IgdGhlIGdpdmVuIG5vZGUuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBub2RlIGJlaW5nIHRlc3RlZC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBpbnQgY29udGV4dCwgCi0gICAgICAgICAgICAgICAgICAgICAgICAgRFRNIGR0bSwgaW50IGV4cFR5cGUpCi0gICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgaWYgKG1fd2hhdFRvU2hvdyA9PSBEVE1GaWx0ZXIuU0hPV19BTEwpCi0gICAgICByZXR1cm4gbV9zY29yZTsKLQotICAgIGludCBub2RlQml0ID0gKG1fd2hhdFRvU2hvdyAmICgweDAwMDAwMDAxIAotICAgICAgICAgICAgICAgICAgIDw8ICgoZXhwVHlwZSA+PiBFeHBhbmRlZE5hbWVUYWJsZS5ST1RBTU9VTlRfVFlQRSkgLSAxKSkpOwotCi0gICAgc3dpdGNoIChub2RlQml0KQotICAgIHsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UIDoKLSAgICAgIHJldHVybiBTQ09SRV9PVEhFUjsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0NPTU1FTlQgOgotICAgICAgcmV0dXJuIG1fc2NvcmU7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX1RFWFQgOgotCi0gICAgICAvLyB3YXM6IAotICAgICAgLy8gcmV0dXJuICgheGN0eHQuZ2V0RE9NSGVscGVyKCkuc2hvdWxkU3RyaXBTb3VyY2VOb2RlKGNvbnRleHQpKQotICAgICAgLy8gICAgICAgPyBtX3Njb3JlIDogU0NPUkVfTk9ORTsKLSAgICAgIHJldHVybiBtX3Njb3JlOwotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfUFJPQ0VTU0lOR19JTlNUUlVDVElPTiA6Ci0gICAgICByZXR1cm4gc3ViUGFydE1hdGNoKGR0bS5nZXROb2RlTmFtZShjb250ZXh0KSwgbV9uYW1lKQotICAgICAgICAgICAgID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0KLSAgICAvLyBGcm9tIHRoZSBkcmFmdDogIlR3byBleHBhbmRlZCBuYW1lcyBhcmUgZXF1YWwgaWYgdGhleSAKLSAgICAvLyBoYXZlIHRoZSBzYW1lIGxvY2FsIHBhcnQsIGFuZCBlaXRoZXIgYm90aCBoYXZlIG5vIFVSSSBvciAKLSAgICAvLyBib3RoIGhhdmUgdGhlIHNhbWUgVVJJLiIKLSAgICAvLyAiQSBub2RlIHRlc3QgKiBpcyB0cnVlIGZvciBhbnkgbm9kZSBvZiB0aGUgcHJpbmNpcGFsIG5vZGUgdHlwZS4gCi0gICAgLy8gRm9yIGV4YW1wbGUsIGNoaWxkOjoqIHdpbGwgc2VsZWN0IGFsbCBlbGVtZW50IGNoaWxkcmVuIG9mIHRoZSAKLSAgICAvLyBjb250ZXh0IG5vZGUsIGFuZCBhdHRyaWJ1dGU6Oiogd2lsbCBzZWxlY3QgYWxsIGF0dHJpYnV0ZXMgb2YgCi0gICAgLy8gdGhlIGNvbnRleHQgbm9kZS4iCi0gICAgLy8gIkEgbm9kZSB0ZXN0IGNhbiBoYXZlIHRoZSBmb3JtIE5DTmFtZToqLiBJbiB0aGlzIGNhc2UsIHRoZSBwcmVmaXggCi0gICAgLy8gaXMgZXhwYW5kZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHdpdGggYSBRTmFtZSB1c2luZyB0aGUgY29udGV4dCAKLSAgICAvLyBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLiBUaGUgbm9kZSB0ZXN0IHdpbGwgYmUgdHJ1ZSBmb3IgYW55IG5vZGUgCi0gICAgLy8gb2YgdGhlIHByaW5jaXBhbCB0eXBlIHdob3NlIGV4cGFuZGVkIG5hbWUgaGFzIHRoZSBVUkkgdG8gd2hpY2ggCi0gICAgLy8gdGhlIHByZWZpeCBleHBhbmRzLCByZWdhcmRsZXNzIG9mIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBuYW1lLiIKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX05BTUVTUEFDRSA6Ci0gICAgewotICAgICAgU3RyaW5nIG5zID0gZHRtLmdldE5vZGVWYWx1ZShjb250ZXh0KTsKLQotICAgICAgcmV0dXJuIChzdWJQYXJ0TWF0Y2gobnMsIG1fbmFtZSkpID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0gICAgfQotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFIDoKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0VMRU1FTlQgOgotICAgIHsKLSAgICAgIHJldHVybiAobV9pc1RvdGFsbHlXaWxkIHx8IChzdWJQYXJ0TWF0Y2hOUyhkdG0uZ2V0TmFtZXNwYWNlVVJJKGNvbnRleHQpLCBtX25hbWVzcGFjZSkgJiYgc3ViUGFydE1hdGNoKGR0bS5nZXRMb2NhbE5hbWUoY29udGV4dCksIG1fbmFtZSkpKQotICAgICAgICAgICAgID8gbV9zY29yZSA6IFNDT1JFX05PTkU7Ci0gICAgfQotICAgIGRlZmF1bHQgOgotICAgICAgcmV0dXJuIFNDT1JFX05PTkU7Ci0gICAgfSAgLy8gZW5kIHN3aXRjaCh0ZXN0VHlwZSkKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0IHRoZSBjdXJyZW50IG5vZGUgdG8gc2VlIGlmIGl0IG1hdGNoZXMgdGhlIGdpdmVuIG5vZGUgdGVzdC4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBOb2RlIHRlc3RzIGJ5IHRoZW1zZWx2ZXMgZG8gbm90IG5lZWQgdG8gZml4IHVwIHZhcmlhYmxlcy4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGZpeHVwVmFyaWFibGVzKGphdmEudXRpbC5WZWN0b3IgdmFycywgaW50IGdsb2JhbHNTaXplKQotICB7Ci0gICAgLy8gbm8tb3AKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9Ob2RlVGVzdEZpbHRlci5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvcGF0dGVybnMvTm9kZVRlc3RGaWx0ZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTIzMDIzOS4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9Ob2RlVGVzdEZpbHRlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNzUgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJuczsKLQotLyoqCi0gKiBUaGlzIGludGVyZmFjZSBzaG91bGQgYmUgaW1wbGVtZW50ZWQgYnkgTm9kZXMgYW5kL29yIGl0ZXJhdG9ycywKLSAqIHdoZW4gdGhleSBuZWVkIHRvIGtub3cgd2hhdCB0aGUgbm9kZSB0ZXN0IGlzIGJlZm9yZSB0aGV5IGRvCi0gKiBnZXROZXh0Q2hpbGQsIGV0Yy4KLSAqLwotcHVibGljIGludGVyZmFjZSBOb2RlVGVzdEZpbHRlcgotewotCi0gIC8qKgotICAgKiBTZXQgdGhlIG5vZGUgdGVzdCBmb3IgdGhpcyBmaWx0ZXIuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBub2RlVGVzdCBSZWZlcmVuY2UgdG8gYSBOb2RlVGVzdCB0aGF0IG1heSBiZSB1c2VkIHRvIHByZWRldGVybWluZSAKLSAgICogICAgICAgICAgICAgICAgIHdoYXQgbm9kZXMgdG8gcmV0dXJuLgotICAgKi8KLSAgdm9pZCBzZXROb2RlVGVzdChOb2RlVGVzdCBub2RlVGVzdCk7Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9TdGVwUGF0dGVybi5qYXZhIGIvc3JjL29yZy9hcGFjaGUveHBhdGgvcGF0dGVybnMvU3RlcFBhdHRlcm4uamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMmU4Y2Q3NC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9TdGVwUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTYyICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMuUHJlZml4UmVzb2x2ZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5heGVzLlN1YkNvbnRleHRMaXN0OwotaW1wb3J0IG9yZy5hcGFjaGUueHBhdGguY29tcGlsZXIuUHN1ZWRvTmFtZXM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54bWwuZHRtLkRUTTsKLWltcG9ydCBvcmcuYXBhY2hlLnhtbC5kdG0uRFRNRmlsdGVyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5EVE1BeGlzVHJhdmVyc2VyOwotaW1wb3J0IG9yZy5hcGFjaGUueG1sLmR0bS5BeGlzOwotCi0vKioKLSAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJhZHZhbmNlZCIvPgotICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgc2luZ2xlIHBhdHRlcm4gbWF0Y2ggc3RlcC4KLSAqLwotcHVibGljIGNsYXNzIFN0ZXBQYXR0ZXJuIGV4dGVuZHMgTm9kZVRlc3QgaW1wbGVtZW50cyBTdWJDb250ZXh0TGlzdAotewotCi0gIC8qKiBUaGUgYXhpcyBmb3IgdGhpcyB0ZXN0LiAqLwotICBwcm90ZWN0ZWQgaW50IG1fYXhpczsKLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgU3RlcFBhdHRlcm4gdGhhdCB0ZXN0cyBmb3IgbmFtZXNwYWNlcyBhbmQgbm9kZSBuYW1lcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHdoYXRUb1Nob3cgQml0IHNldCBkZWZpbmVkIG1haW5seSBieSB7QGxpbmsgb3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVGaWx0ZXJ9LgotICAgKiBAcGFyYW0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgdG8gYmUgdGVzdGVkLgotICAgKiBAcGFyYW0gbmFtZSBUaGUgbG9jYWwgbmFtZSB0byBiZSB0ZXN0ZWQuCi0gICAqIEBwYXJhbSBheGlzIFRoZSBBeGlzIGZvciB0aGlzIHRlc3QsIG9uZSBvZiBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqIEBwYXJhbSBheGlzRm9yUHJlZGljYXRlIE5vIGxvbmdlciB1c2VkLgotICAgKi8KLSAgcHVibGljIFN0ZXBQYXR0ZXJuKGludCB3aGF0VG9TaG93LCBTdHJpbmcgbmFtZXNwYWNlLCBTdHJpbmcgbmFtZSwgaW50IGF4aXMsCi0gICAgICAgICAgICAgICAgICAgICBpbnQgYXhpc0ZvclByZWRpY2F0ZSkKLSAgewotCi0gICAgc3VwZXIod2hhdFRvU2hvdywgbmFtZXNwYWNlLCBuYW1lKTsKLQotICAgIG1fYXhpcyA9IGF4aXM7Ci0gIH0KLQotICAvKioKLSAgICogQ29uc3RydWN0IGEgU3RlcFBhdHRlcm4gdGhhdCBkb2Vzbid0IHRlc3QgZm9yIG5vZGUgbmFtZXMuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSB3aGF0VG9TaG93IEJpdCBzZXQgZGVmaW5lZCBtYWlubHkgYnkge0BsaW5rIG9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlRmlsdGVyfS4KLSAgICogQHBhcmFtIGF4aXMgVGhlIEF4aXMgZm9yIHRoaXMgdGVzdCwgb25lIG9mIG9mIEF4ZXMuQU5DRVNUT1JPUlNFTEYsIGV0Yy4KLSAgICogQHBhcmFtIGF4aXNGb3JQcmVkaWNhdGUgTm8gbG9uZ2VyIHVzZWQuCi0gICAqLwotICBwdWJsaWMgU3RlcFBhdHRlcm4oaW50IHdoYXRUb1Nob3csIGludCBheGlzLCBpbnQgYXhpc0ZvclByZWRpY2F0ZSkKLSAgewotCi0gICAgc3VwZXIod2hhdFRvU2hvdyk7Ci0KLSAgICBtX2F4aXMgPSBheGlzOwotICB9Ci0KLSAgLyoqCi0gICAqIFRoZSB0YXJnZXQgbG9jYWwgbmFtZSBvciBwc3VlZG8gbmFtZSwgZm9yIGhhc2ggdGFibGUgbG9va3VwIG9wdGltaXphdGlvbi4KLSAgICogIEBzZXJpYWwKLSAgICovCi0gIFN0cmluZyBtX3RhcmdldFN0cmluZzsgIC8vIG9ubHkgY2FsY3VsYXRlIG9uIGhlYWQKLQotICAvKioKLSAgICogQ2FsY3VsYXRlIHRoZSBsb2NhbCBuYW1lIG9yIHBzdWVkbyBuYW1lIG9mIHRoZSBub2RlIHRoYXQgdGhpcyBwYXR0ZXJuIHdpbGwgdGVzdCwKLSAgICogZm9yIGhhc2ggdGFibGUgbG9va3VwIG9wdGltaXphdGlvbi4KLSAgICoKLSAgICogQHNlZSBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyLlBzdWVkb05hbWVzCi0gICAqLwotICBwdWJsaWMgdm9pZCBjYWxjVGFyZ2V0U3RyaW5nKCkKLSAgewotCi0gICAgaW50IHdoYXRUb1Nob3cgPSBnZXRXaGF0VG9TaG93KCk7Ci0KLSAgICBzd2l0Y2ggKHdoYXRUb1Nob3cpCi0gICAgewotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfQ09NTUVOVCA6Ci0gICAgICBtX3RhcmdldFN0cmluZyA9IFBzdWVkb05hbWVzLlBTRVVET05BTUVfQ09NTUVOVDsKLSAgICAgIGJyZWFrOwotICAgIGNhc2UgRFRNRmlsdGVyLlNIT1dfVEVYVCA6Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19DREFUQV9TRUNUSU9OIDoKLSAgICBjYXNlIChEVE1GaWx0ZXIuU0hPV19URVhUIHwgRFRNRmlsdGVyLlNIT1dfQ0RBVEFfU0VDVElPTikgOgotICAgICAgbV90YXJnZXRTdHJpbmcgPSBQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX1RFWFQ7Ci0gICAgICBicmVhazsKLSAgICBjYXNlIERUTUZpbHRlci5TSE9XX0FMTCA6Ci0gICAgICBtX3RhcmdldFN0cmluZyA9IFBzdWVkb05hbWVzLlBTRVVET05BTUVfQU5ZOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVCA6Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19ET0NVTUVOVCB8IERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UX0ZSQUdNRU5UIDoKLSAgICAgIG1fdGFyZ2V0U3RyaW5nID0gUHN1ZWRvTmFtZXMuUFNFVURPTkFNRV9ST09UOwotICAgICAgYnJlYWs7Ci0gICAgY2FzZSBEVE1GaWx0ZXIuU0hPV19FTEVNRU5UIDoKLSAgICAgIGlmICh0aGlzLldJTEQgPT0gbV9uYW1lKQotICAgICAgICBtX3RhcmdldFN0cmluZyA9IFBzdWVkb05hbWVzLlBTRVVET05BTUVfQU5ZOwotICAgICAgZWxzZQotICAgICAgICBtX3RhcmdldFN0cmluZyA9IG1fbmFtZTsKLSAgICAgIGJyZWFrOwotICAgIGRlZmF1bHQgOgotICAgICAgbV90YXJnZXRTdHJpbmcgPSBQc3VlZG9OYW1lcy5QU0VVRE9OQU1FX0FOWTsKLSAgICAgIGJyZWFrOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGxvY2FsIG5hbWUgb3IgcHN1ZWRvIG5hbWUgb2YgdGhlIG5vZGUgdGhhdCB0aGlzIHBhdHRlcm4gd2lsbCB0ZXN0LAotICAgKiBmb3IgaGFzaCB0YWJsZSBsb29rdXAgb3B0aW1pemF0aW9uLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIGxvY2FsIG5hbWUgb3IgcHN1ZWRvIG5hbWUgb2YgdGhlIG5vZGUuCi0gICAqIEBzZWUgb3JnLmFwYWNoZS54cGF0aC5jb21waWxlci5Qc3VlZG9OYW1lcwotICAgKi8KLSAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRTdHJpbmcoKQotICB7Ci0gICAgcmV0dXJuIG1fdGFyZ2V0U3RyaW5nOwotICB9Ci0KLSAgLyoqCi0gICAqIFJlZmVyZW5jZSB0byBub2RldGVzdCBhbmQgcHJlZGljYXRlIGZvcgotICAgKiBwYXJlbnQgb3IgYW5jZXN0b3IuCi0gICAqIEBzZXJpYWwKLSAgICovCi0gIFN0ZXBQYXR0ZXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybjsKLQotICAvKioKLSAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGZpeHVwIHZhcmlhYmxlcyBmcm9tIFFOYW1lcyB0byBzdGFjayBmcmFtZQotICAgKiBpbmRleGVzIGF0IHN0eWxlc2hlZXQgYnVpbGQgdGltZS4KLSAgICogQHBhcmFtIHZhcnMgTGlzdCBvZiBRTmFtZXMgdGhhdCBjb3JyZXNwb25kIHRvIHZhcmlhYmxlcy4gIFRoaXMgbGlzdAotICAgKiBzaG91bGQgYmUgc2VhcmNoZWQgYmFja3dhcmRzIGZvciB0aGUgZmlyc3QgcXVhbGlmaWVkIG5hbWUgdGhhdAotICAgKiBjb3JyZXNwb25kcyB0byB0aGUgdmFyaWFibGUgcmVmZXJlbmNlIHFuYW1lLiAgVGhlIHBvc2l0aW9uIG9mIHRoZQotICAgKiBRTmFtZSBpbiB0aGUgdmVjdG9yIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3Igd2lsbCBiZSBpdHMgcG9zaXRpb24KLSAgICogaW4gdGhlIHN0YWNrIGZyYW1lIChidXQgdmFyaWFibGVzIGFib3ZlIHRoZSBnbG9iYWxzVG9wIHZhbHVlIHdpbGwgbmVlZAotICAgKiB0byBiZSBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgc3RhY2sgZnJhbWUpLgotICAgKiBAcGFyYW0gZ2xvYmFsc1NpemUgVGhlIG51bWJlciBvZiB2YXJpYWJsZXMgaW4gdGhlIGdsb2JhbCB2YXJpYWJsZSBhcmVhLgotICAgKi8KLSAgcHVibGljIHZvaWQgZml4dXBWYXJpYWJsZXMoamF2YS51dGlsLlZlY3RvciB2YXJzLCBpbnQgZ2xvYmFsc1NpemUpCi0gIHsKLQotICAgIHN1cGVyLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLQotICAgIGlmIChudWxsICE9IG1fcHJlZGljYXRlcykKLSAgICB7Ci0gICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fcHJlZGljYXRlcy5sZW5ndGg7IGkrKykKLSAgICAgIHsKLSAgICAgICAgbV9wcmVkaWNhdGVzW2ldLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAobnVsbCAhPSBtX3JlbGF0aXZlUGF0aFBhdHRlcm4pCi0gICAgewotICAgICAgbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuLmZpeHVwVmFyaWFibGVzKHZhcnMsIGdsb2JhbHNTaXplKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSByZWZlcmVuY2UgdG8gbm9kZXRlc3QgYW5kIHByZWRpY2F0ZSBmb3IKLSAgICogcGFyZW50IG9yIGFuY2VzdG9yLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gZXhwciBUaGUgcmVsYXRpdmUgcGF0dGVybiBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UmVsYXRpdmVQYXRoUGF0dGVybihTdGVwUGF0dGVybiBleHByKQotICB7Ci0KLSAgICBtX3JlbGF0aXZlUGF0aFBhdHRlcm4gPSBleHByOwotCi0gICAgY2FsY1Njb3JlKCk7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSByZWZlcmVuY2UgdG8gbm9kZXRlc3QgYW5kIHByZWRpY2F0ZSBmb3IKLSAgICogcGFyZW50IG9yIGFuY2VzdG9yLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZWxhdGl2ZSBwYXR0ZXJuIGV4cHJlc3Npb24uCi0gICAqLwotICBwdWJsaWMgU3RlcFBhdHRlcm4gZ2V0UmVsYXRpdmVQYXRoUGF0dGVybigpCi0gIHsKLSAgICByZXR1cm4gbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuOwotICB9Ci0KLSAgLy8gIC8qKgotICAvLyAgICogU2V0IHRoZSBsaXN0IG9mIHByZWRpY2F0ZSBleHByZXNzaW9ucyBmb3IgdGhpcyBwYXR0ZXJuIHN0ZXAuCi0gIC8vICAgKiBAcGFyYW0gcHJlZGljYXRlcyBMaXN0IG9mIGV4cHJlc3Npb24gb2JqZWN0cy4KLSAgLy8gICAqLwotICAvLyAgcHVibGljIHZvaWQgc2V0UHJlZGljYXRlcyhFeHByZXNzaW9uW10gcHJlZGljYXRlcykKLSAgLy8gIHsKLSAgLy8gICAgbV9wcmVkaWNhdGVzID0gcHJlZGljYXRlczsKLSAgLy8gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBsaXN0IG9mIHByZWRpY2F0ZSBleHByZXNzaW9ucyBmb3IgdGhpcyBwYXR0ZXJuIHN0ZXAuCi0gICAqIEByZXR1cm4gTGlzdCBvZiBleHByZXNzaW9uIG9iamVjdHMuCi0gICAqLwotICBwdWJsaWMgRXhwcmVzc2lvbltdIGdldFByZWRpY2F0ZXMoKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZGljYXRlczsKLSAgfQotCi0gIC8qKgotICAgKiBUaGUgbGlzdCBvZiBwcmVkaWNhdGUgZXhwcmVzc2lvbnMgZm9yIHRoaXMgcGF0dGVybiBzdGVwLgotICAgKiAgQHNlcmlhbAotICAgKi8KLSAgRXhwcmVzc2lvbltdIG1fcHJlZGljYXRlczsKLQotICAvKioKLSAgICogVGVsbCBpZiB0aGlzIGV4cHJlc3Npb24gb3IgaXQncyBzdWJleHByZXNzaW9ucyBjYW4gdHJhdmVyc2Ugb3V0c2lkZQotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKgotICAgKiBOT1RFOiBBbmNlc3RvcnMgdGVzdHMgd2l0aCBwcmVkaWNhdGVzIGFyZSBwcm9ibGVtYXRpYywgYW5kIHdpbGwgcmVxdWlyZQotICAgKiBzcGVjaWFsIHRyZWF0bWVudC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gIHB1YmxpYyBib29sZWFuIGNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKQotICB7Ci0KLSAgICBpbnQgbiA9IGdldFByZWRpY2F0ZUNvdW50KCk7Ci0KLSAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKLSAgICB7Ci0gICAgICBpZiAoZ2V0UHJlZGljYXRlKGkpLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSkKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfQotCi0gICAgcmV0dXJuIGZhbHNlOwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCBhIHByZWRpY2F0ZSBleHByZXNzaW9uLgotICAgKgotICAgKgotICAgKiBAcGFyYW0gaSBUaGUgaW5kZXggb2YgdGhlIHByZWRpY2F0ZS4KLSAgICoKLSAgICogQHJldHVybiBBIHByZWRpY2F0ZSBleHByZXNzaW9uLgotICAgKi8KLSAgcHVibGljIEV4cHJlc3Npb24gZ2V0UHJlZGljYXRlKGludCBpKQotICB7Ci0gICAgcmV0dXJuIG1fcHJlZGljYXRlc1tpXTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIG51bWJlciBvZiBwcmVkaWNhdGVzIGZvciB0aGlzIG1hdGNoIHBhdHRlcm4gc3RlcC4KLSAgICoKLSAgICoKLSAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHByZWRpY2F0ZXMgZm9yIHRoaXMgbWF0Y2ggcGF0dGVybiBzdGVwLgotICAgKi8KLSAgcHVibGljIGZpbmFsIGludCBnZXRQcmVkaWNhdGVDb3VudCgpCi0gIHsKLSAgICByZXR1cm4gKG51bGwgPT0gbV9wcmVkaWNhdGVzKSA/IDAgOiBtX3ByZWRpY2F0ZXMubGVuZ3RoOwotICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgcHJlZGljYXRlcyBmb3IgdGhpcyBtYXRjaCBwYXR0ZXJuIHN0ZXAuCi0gICAqCi0gICAqCi0gICAqIEBwYXJhbSBwcmVkaWNhdGVzIEFuIGFycmF5IG9mIGV4cHJlc3Npb25zIHRoYXQgZGVmaW5lIHByZWRpY2F0ZXMKLSAgICogICAgICAgICAgICAgICAgICAgZm9yIHRoaXMgc3RlcC4KLSAgICovCi0gIHB1YmxpYyB2b2lkIHNldFByZWRpY2F0ZXMoRXhwcmVzc2lvbltdIHByZWRpY2F0ZXMpCi0gIHsKLQotICAgIG1fcHJlZGljYXRlcyA9IHByZWRpY2F0ZXM7Ci0KLSAgICBjYWxjU2NvcmUoKTsKLSAgfQotCi0gIC8qKgotICAgKiBTdGF0aWMgY2FsYyBvZiBtYXRjaCBzY29yZS4KLSAgICovCi0gIHB1YmxpYyB2b2lkIGNhbGNTY29yZSgpCi0gIHsKLQotICAgIGlmICgoZ2V0UHJlZGljYXRlQ291bnQoKSA+IDApIHx8IChudWxsICE9IG1fcmVsYXRpdmVQYXRoUGF0dGVybikpCi0gICAgewotICAgICAgbV9zY29yZSA9IFNDT1JFX09USEVSOwotICAgIH0KLSAgICBlbHNlCi0gICAgICBzdXBlci5jYWxjU2NvcmUoKTsKLQotICAgIGlmIChudWxsID09IG1fdGFyZ2V0U3RyaW5nKQotICAgICAgY2FsY1RhcmdldFN0cmluZygpOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhpcyBwYXR0ZXJuIHN0ZXAsIGluY2x1ZGluZyBwcmVkaWNhdGVzLgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gY3VycmVudE5vZGUgVGhlIGN1cnJlbnQgbm9kZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIFhPYmplY3QgZXhlY3V0ZShYUGF0aENvbnRleHQgeGN0eHQsIGludCBjdXJyZW50Tm9kZSkKLSAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBEVE0gZHRtID0geGN0eHQuZ2V0RFRNKGN1cnJlbnROb2RlKTsKLQotICAgIGlmIChkdG0gIT0gbnVsbCkKLSAgICB7Ci0gICAgICBpbnQgZXhwVHlwZSA9IGR0bS5nZXRFeHBhbmRlZFR5cGVJRChjdXJyZW50Tm9kZSk7Ci0KLSAgICAgIHJldHVybiBleGVjdXRlKHhjdHh0LCBjdXJyZW50Tm9kZSwgZHRtLCBleHBUeXBlKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gTm9kZVRlc3QuU0NPUkVfTk9ORTsKLSAgfQotCi0gIC8qKgotICAgKiBFeGVjdXRlIHRoaXMgcGF0dGVybiBzdGVwLCBpbmNsdWRpbmcgcHJlZGljYXRlcy4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLSAgICByZXR1cm4gZXhlY3V0ZSh4Y3R4dCwgeGN0eHQuZ2V0Q3VycmVudE5vZGUoKSk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSBhbiBleHByZXNzaW9uIGluIHRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQsIGFuZCByZXR1cm4gdGhlCi0gICAqIHJlc3VsdCBvZiB0aGUgZXhwcmVzc2lvbi4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjdXJyZW50Tm9kZSBUaGUgY3VycmVudE5vZGUuCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKiBAcGFyYW0gZXhwVHlwZSBUaGUgZXhwYW5kZWQgdHlwZSBJRCBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKgotICAgKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgdGhlIGV4cHJlc3Npb24gaW4gdGhlIGZvcm0gb2YgYSA8Y29kZT5YT2JqZWN0PC9jb2RlPi4KLSAgICoKLSAgICogQHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uIGlmIGEgcnVudGltZSBleGNlcHRpb24KLSAgICogICAgICAgICBvY2N1cnMuCi0gICAqLwotICBwdWJsaWMgWE9iamVjdCBleGVjdXRlKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgaW50IGN1cnJlbnROb2RlLCBEVE0gZHRtLCBpbnQgZXhwVHlwZSkKLSAgICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIGlmIChtX3doYXRUb1Nob3cgPT0gTm9kZVRlc3QuU0hPV19CWUZVTkNUSU9OKQotICAgIHsKLSAgICAgIGlmIChudWxsICE9IG1fcmVsYXRpdmVQYXRoUGF0dGVybikKLSAgICAgIHsKLSAgICAgICAgcmV0dXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybi5leGVjdXRlKHhjdHh0KTsKLSAgICAgIH0KLSAgICAgIGVsc2UKLSAgICAgICAgcmV0dXJuIE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgfQotCi0gICAgWE9iamVjdCBzY29yZTsKLQotICAgIHNjb3JlID0gc3VwZXIuZXhlY3V0ZSh4Y3R4dCwgY3VycmVudE5vZGUsIGR0bSwgZXhwVHlwZSk7Ci0KLSAgICBpZiAoc2NvcmUgPT0gTm9kZVRlc3QuU0NPUkVfTk9ORSkKLSAgICAgIHJldHVybiBOb2RlVGVzdC5TQ09SRV9OT05FOwotCi0gICAgaWYgKGdldFByZWRpY2F0ZUNvdW50KCkgIT0gMCkKLSAgICB7Ci0gICAgICBpZiAoIWV4ZWN1dGVQcmVkaWNhdGVzKHhjdHh0LCBkdG0sIGN1cnJlbnROb2RlKSkKLSAgICAgICAgcmV0dXJuIE5vZGVUZXN0LlNDT1JFX05PTkU7Ci0gICAgfQotCi0gICAgaWYgKG51bGwgIT0gbV9yZWxhdGl2ZVBhdGhQYXR0ZXJuKQotICAgICAgcmV0dXJuIG1fcmVsYXRpdmVQYXRoUGF0dGVybi5leGVjdXRlUmVsYXRpdmVQYXRoUGF0dGVybih4Y3R4dCwgZHRtLAotICAgICAgICAgICAgICBjdXJyZW50Tm9kZSk7Ci0KLSAgICByZXR1cm4gc2NvcmU7Ci0gIH0KLQotICAvKioKLSAgICogTmV3IE1ldGhvZCB0byBjaGVjayB3aGV0aGVyIHRoZSBjdXJyZW50IG5vZGUgc2F0aXNmaWVzIGEgcG9zaXRpb24gcHJlZGljYXRlCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gcHJlZFBvcyBXaGljaCBwcmVkaWNhdGUgd2UncmUgZXZhbHVhdGluZyBvZiBmb29bMV1bMl1bM10uCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY3VycmVudE5vZGUuCi0gICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGJlaW5nIHJlcXVlc3RlZCwgaS5lLiB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgCi0gICAqICAgICAgICAgICAgbV9wcmVkaWNhdGVzW3ByZWRQb3NdLmV4ZWN1dGUoeGN0eHQpLgotICAgKgotICAgKiBAcmV0dXJuIHRydWUgb2YgdGhlIHBvc2l0aW9uIG9mIHRoZSBjb250ZXh0IG1hdGNoZXMgcG9zLCBmYWxzZSBvdGhlcndpc2UuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tQcm94aW1pdHlQb3NpdGlvbihYUGF0aENvbnRleHQgeGN0eHQsCi0gICAgICAgICAgaW50IHByZWRQb3MsIERUTSBkdG0sIGludCBjb250ZXh0LCBpbnQgcG9zKQotICB7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlciA9Ci0gICAgICAgIGR0bS5nZXRBeGlzVHJhdmVyc2VyKEF4aXMuUFJFQ0VESU5HU0lCTElORyk7Ci0KLSAgICAgIGZvciAoaW50IGNoaWxkID0gdHJhdmVyc2VyLmZpcnN0KGNvbnRleHQpOyBEVE0uTlVMTCAhPSBjaGlsZDsKLSAgICAgICAgICAgICAgY2hpbGQgPSB0cmF2ZXJzZXIubmV4dChjb250ZXh0LCBjaGlsZCkpCi0gICAgICB7Ci0gICAgICAgIHRyeQotICAgICAgICB7Ci0gICAgICAgICAgeGN0eHQucHVzaEN1cnJlbnROb2RlKGNoaWxkKTsKLQotICAgICAgICAgIGlmIChOb2RlVGVzdC5TQ09SRV9OT05FICE9IHN1cGVyLmV4ZWN1dGUoeGN0eHQsIGNoaWxkKSkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBib29sZWFuIHBhc3MgPSB0cnVlOwotCi0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgeGN0eHQucHVzaFN1YkNvbnRleHRMaXN0KHRoaXMpOwotCi0gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJlZFBvczsgaSsrKQotICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgeGN0eHQucHVzaFByZWRpY2F0ZVBvcyhpKTsKLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICBYT2JqZWN0IHByZWQgPSBtX3ByZWRpY2F0ZXNbaV0uZXhlY3V0ZSh4Y3R4dCk7Ci0gICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gcHJlZC5nZXRUeXBlKCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIldoeTogU2hvdWxkIG5ldmVyIGhhdmUgYmVlbiBjYWxsZWQiKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghcHJlZC5ib29sV2l0aFNpZGVFZmZlY3RzKCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICBwYXNzID0gZmFsc2U7Ci0gICAgCi0gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZC5kZXRhY2goKTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZmluYWxseQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHhjdHh0LnBvcFByZWRpY2F0ZVBvcygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWxseQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB4Y3R4dC5wb3BTdWJDb250ZXh0TGlzdCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocGFzcykKLSAgICAgICAgICAgICAgcG9zLS07Ci0KLSAgICAgICAgICAgIGlmIChwb3MgPCAxKQotICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGZpbmFsbHkKLSAgICAgICAgewotICAgICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICAgIH0KLSAgICAgIH0KLSAgICB9Ci0gICAgY2F0Y2ggKGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24gc2UpCi0gICAgewotCi0gICAgICAvLyBUT0RPOiBzaG91bGQga2VlcCB0aHJvdyBzYXggZXhjZXB0aW9uLi4uCi0gICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24oc2UuZ2V0TWVzc2FnZSgpKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gKHBvcyA9PSAxKTsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIHByb3hpbWl0eSBwb3NpdGlvbiBpbmRleCBvZiB0aGUgY3VycmVudCBub2RlIGJhc2VkIG9uIHRoaXMKLSAgICogbm9kZSB0ZXN0LgotICAgKgotICAgKgotICAgKiBAcGFyYW0geGN0eHQgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gcHJlZFBvcyBXaGljaCBwcmVkaWNhdGUgd2UncmUgZXZhbHVhdGluZyBvZiBmb29bMV1bMl1bM10uCi0gICAqIEBwYXJhbSBmaW5kTGFzdCBJZiB0cnVlLCBkb24ndCB0ZXJtaW5hdGUgd2hlbiB0aGUgY29udGV4dCBub2RlIGlzIGZvdW5kLgotICAgKgotICAgKiBAcmV0dXJuIHRoZSBwcm94aW1pdHkgcG9zaXRpb24gaW5kZXggb2YgdGhlIGN1cnJlbnQgbm9kZSBiYXNlZCBvbiB0aGUKLSAgICogICAgICAgICBub2RlIHRlc3QuCi0gICAqLwotICBwcml2YXRlIGZpbmFsIGludCBnZXRQcm94aW1pdHlQb3NpdGlvbihYUGF0aENvbnRleHQgeGN0eHQsIGludCBwcmVkUG9zLCAKLSAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaW5kTGFzdCkKLSAgewotCi0gICAgaW50IHBvcyA9IDA7Ci0gICAgaW50IGNvbnRleHQgPSB4Y3R4dC5nZXRDdXJyZW50Tm9kZSgpOwotICAgIERUTSBkdG0gPSB4Y3R4dC5nZXREVE0oY29udGV4dCk7Ci0gICAgaW50IHBhcmVudCA9IGR0bS5nZXRQYXJlbnQoY29udGV4dCk7Ci0KLSAgICB0cnkKLSAgICB7Ci0gICAgICBEVE1BeGlzVHJhdmVyc2VyIHRyYXZlcnNlciA9IGR0bS5nZXRBeGlzVHJhdmVyc2VyKEF4aXMuQ0hJTEQpOwotCi0gICAgICBmb3IgKGludCBjaGlsZCA9IHRyYXZlcnNlci5maXJzdChwYXJlbnQpOyBEVE0uTlVMTCAhPSBjaGlsZDsKLSAgICAgICAgICAgICAgY2hpbGQgPSB0cmF2ZXJzZXIubmV4dChwYXJlbnQsIGNoaWxkKSkKLSAgICAgIHsKLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUoY2hpbGQpOwotCi0gICAgICAgICAgaWYgKE5vZGVUZXN0LlNDT1JFX05PTkUgIT0gc3VwZXIuZXhlY3V0ZSh4Y3R4dCwgY2hpbGQpKQotICAgICAgICAgIHsKLSAgICAgICAgICAgIGJvb2xlYW4gcGFzcyA9IHRydWU7Ci0KLSAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB4Y3R4dC5wdXNoU3ViQ29udGV4dExpc3QodGhpcyk7Ci0KLSAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcmVkUG9zOyBpKyspCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB4Y3R4dC5wdXNoUHJlZGljYXRlUG9zKGkpOwotICAgICAgICAgICAgICAgIHRyeQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIFhPYmplY3QgcHJlZCA9IG1fcHJlZGljYXRlc1tpXS5leGVjdXRlKHhjdHh0KTsKLSAgCi0gICAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFhPYmplY3QuQ0xBU1NfTlVNQkVSID09IHByZWQuZ2V0VHlwZSgpKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgaWYgKChwb3MgKyAxKSAhPSAoaW50KSBwcmVkLm51bVdpdGhTaWRlRWZmZWN0cygpKQotICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBhc3MgPSBmYWxzZTsKLSAgICAKLSAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghcHJlZC5ib29sV2l0aFNpZGVFZmZlY3RzKCkpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICBwYXNzID0gZmFsc2U7Ci0gICAgCi0gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcHJlZC5kZXRhY2goKTsKLSAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZmluYWxseQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHhjdHh0LnBvcFByZWRpY2F0ZVBvcygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZmluYWxseQotICAgICAgICAgICAgewotICAgICAgICAgICAgICB4Y3R4dC5wb3BTdWJDb250ZXh0TGlzdCgpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpZiAocGFzcykKLSAgICAgICAgICAgICAgcG9zKys7Ci0KLSAgICAgICAgICAgIGlmICghZmluZExhc3QgJiYgY2hpbGQgPT0gY29udGV4dCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgcmV0dXJuIHBvczsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgZmluYWxseQotICAgICAgICB7Ci0gICAgICAgICAgeGN0eHQucG9wQ3VycmVudE5vZGUoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBjYXRjaCAoamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbiBzZSkKLSAgICB7Ci0KLSAgICAgIC8vIFRPRE86IHNob3VsZCBrZWVwIHRocm93IHNheCBleGNlcHRpb24uLi4KLSAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbihzZS5nZXRNZXNzYWdlKCkpOwotICAgIH0KLQotICAgIHJldHVybiBwb3M7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBwcm94aW1pdHkgcG9zaXRpb24gaW5kZXggb2YgdGhlIGN1cnJlbnQgbm9kZSBiYXNlZCBvbiB0aGlzCi0gICAqIG5vZGUgdGVzdC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgcHJveGltaXR5IHBvc2l0aW9uIGluZGV4IG9mIHRoZSBjdXJyZW50IG5vZGUgYmFzZWQgb24gdGhlCi0gICAqICAgICAgICAgbm9kZSB0ZXN0LgotICAgKi8KLSAgcHVibGljIGludCBnZXRQcm94aW1pdHlQb3NpdGlvbihYUGF0aENvbnRleHQgeGN0eHQpCi0gIHsKLSAgICByZXR1cm4gZ2V0UHJveGltaXR5UG9zaXRpb24oeGN0eHQsIHhjdHh0LmdldFByZWRpY2F0ZVBvcygpLCBmYWxzZSk7Ci0gIH0KLSAgCi0gIC8qKgotICAgKiBHZXQgdGhlIGNvdW50IG9mIHRoZSBub2RlcyB0aGF0IG1hdGNoIHRoZSB0ZXN0LCB3aGljaCBpcyB0aGUgcHJveGltaXR5Ci0gICAqIHBvc2l0aW9uIG9mIHRoZSBsYXN0IG5vZGUgdGhhdCBjYW4gcGFzcyB0aGlzIHRlc3QgaW4gdGhlIHN1YiBjb250ZXh0Ci0gICAqIHNlbGVjdGlvbi4gIEluIFhTTFQgMS1iYXNlZCBpbmRleGluZywgdGhpcyBjb3VudCBpcyB0aGUgaW5kZXggb2YgdGhlIGxhc3QKLSAgICogbm9kZS4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0aGUgY291bnQgb2YgdGhlIG5vZGVzIHRoYXQgbWF0Y2ggdGhlIHRlc3QuCi0gICAqLwotICBwdWJsaWMgaW50IGdldExhc3RQb3MoWFBhdGhDb250ZXh0IHhjdHh0KQotICB7Ci0gICAgcmV0dXJuIGdldFByb3hpbWl0eVBvc2l0aW9uKHhjdHh0LCB4Y3R4dC5nZXRQcmVkaWNhdGVQb3MoKSwgdHJ1ZSk7Ci0gIH0KLQotICAvKioKLSAgICogRXhlY3V0ZSB0aGUgbWF0Y2ggcGF0dGVybiBzdGVwIHJlbGF0aXZlIHRvIGFub3RoZXIgc3RlcC4KLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBkdG0gVGhlIERUTSBvZiB0aGUgY3VycmVudCBub2RlLgotICAgKiBAcGFyYW0gY3VycmVudE5vZGUgVGhlIGN1cnJlbnQgbm9kZSBjb250ZXh0LgotICAgKgotICAgKiBAcmV0dXJuIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX05PREVURVNUfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT05FfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OU1dJTER9LAotICAgKiAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLnhwYXRoLnBhdHRlcm5zLk5vZGVUZXN0I1NDT1JFX1FOQU1FfSwgb3IKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9PVEhFUn0uCi0gICAqCi0gICAqIEB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICAgKi8KLSAgcHJvdGVjdGVkIGZpbmFsIFhPYmplY3QgZXhlY3V0ZVJlbGF0aXZlUGF0aFBhdHRlcm4oCi0gICAgICAgICAgWFBhdGhDb250ZXh0IHhjdHh0LCBEVE0gZHRtLCBpbnQgY3VycmVudE5vZGUpCi0gICAgICAgICAgICB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IHNjb3JlID0gTm9kZVRlc3QuU0NPUkVfTk9ORTsKLSAgICBpbnQgY29udGV4dCA9IGN1cnJlbnROb2RlOwotICAgIERUTUF4aXNUcmF2ZXJzZXIgdHJhdmVyc2VyOwotCi0gICAgdHJhdmVyc2VyID0gZHRtLmdldEF4aXNUcmF2ZXJzZXIobV9heGlzKTsKLQotICAgIGZvciAoaW50IHJlbGF0aXZlID0gdHJhdmVyc2VyLmZpcnN0KGNvbnRleHQpOyBEVE0uTlVMTCAhPSByZWxhdGl2ZTsKLSAgICAgICAgICAgIHJlbGF0aXZlID0gdHJhdmVyc2VyLm5leHQoY29udGV4dCwgcmVsYXRpdmUpKQotICAgIHsKLSAgICAgIHRyeQotICAgICAgewotICAgICAgICB4Y3R4dC5wdXNoQ3VycmVudE5vZGUocmVsYXRpdmUpOwotCi0gICAgICAgIHNjb3JlID0gZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgICAgaWYgKHNjb3JlICE9IE5vZGVUZXN0LlNDT1JFX05PTkUpCi0gICAgICAgICAgYnJlYWs7Ci0gICAgICB9Ci0gICAgICBmaW5hbGx5Ci0gICAgICB7Ci0gICAgICAgIHhjdHh0LnBvcEN1cnJlbnROb2RlKCk7Ci0gICAgICB9Ci0gICAgfQotCi0gICAgcmV0dXJuIHNjb3JlOwotICB9Ci0KLSAgLyoqCi0gICAqIEV4ZWN1dGUgdGhlIHByZWRpY2F0ZXMgb24gdGhpcyBzdGVwIHRvIGRldGVybWluZSBpZiB0aGUgY3VycmVudCBub2RlIAotICAgKiBzaG91bGQgYmUgZmlsdGVyZWQgb3IgYWNjZXB0ZWQuCi0gICAqCi0gICAqIEBwYXJhbSB4Y3R4dCBUaGUgWFBhdGggcnVudGltZSBjb250ZXh0LgotICAgKiBAcGFyYW0gZHRtIFRoZSBEVE0gb2YgdGhlIGN1cnJlbnQgbm9kZS4KLSAgICogQHBhcmFtIGN1cnJlbnROb2RlIFRoZSBjdXJyZW50IG5vZGUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB0cnVlIGlmIHRoZSBub2RlIHNob3VsZCBiZSBhY2NlcHRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGV4ZWN1dGVQcmVkaWNhdGVzKAotICAgICAgICAgIFhQYXRoQ29udGV4dCB4Y3R4dCwgRFRNIGR0bSwgaW50IGN1cnJlbnROb2RlKQotICAgICAgICAgICAgdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgewotCi0gICAgYm9vbGVhbiByZXN1bHQgPSB0cnVlOwotICAgIGJvb2xlYW4gcG9zaXRpb25BbHJlYWR5U2VlbiA9IGZhbHNlOwotICAgIGludCBuID0gZ2V0UHJlZGljYXRlQ291bnQoKTsKLQotICAgIHRyeQotICAgIHsKLSAgICAgIHhjdHh0LnB1c2hTdWJDb250ZXh0TGlzdCh0aGlzKTsKLQotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi0gICAgICB7Ci0gICAgICAgIHhjdHh0LnB1c2hQcmVkaWNhdGVQb3MoaSk7Ci0KLSAgICAgICAgdHJ5Ci0gICAgICAgIHsKLSAgICAgICAgICBYT2JqZWN0IHByZWQgPSBtX3ByZWRpY2F0ZXNbaV0uZXhlY3V0ZSh4Y3R4dCk7Ci0KLSAgICAgICAgICB0cnkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoWE9iamVjdC5DTEFTU19OVU1CRVIgPT0gcHJlZC5nZXRUeXBlKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIGludCBwb3MgPSAoaW50KSBwcmVkLm51bSgpOwotICAKLSAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uQWxyZWFkeVNlZW4pCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXN1bHQgPSAocG9zID09IDEpOwotICAKLSAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBwb3NpdGlvbkFscmVhZHlTZWVuID0gdHJ1ZTsKLSAgCi0gICAgICAgICAgICAgICAgaWYgKCFjaGVja1Byb3hpbWl0eVBvc2l0aW9uKHhjdHh0LCBpLCBkdG0sIGN1cnJlbnROb2RlLCBwb3MpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOwotICAKLSAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgfQotICAgICAgICAgICAgCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICghcHJlZC5ib29sV2l0aFNpZGVFZmZlY3RzKCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOwotICAKLSAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgfQotICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICB7Ci0gICAgICAgICAgICBwcmVkLmRldGFjaCgpOwotICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBmaW5hbGx5Ci0gICAgICAgIHsKLSAgICAgICAgICB4Y3R4dC5wb3BQcmVkaWNhdGVQb3MoKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLSAgICBmaW5hbGx5Ci0gICAgewotICAgICAgeGN0eHQucG9wU3ViQ29udGV4dExpc3QoKTsKLSAgICB9Ci0KLSAgICByZXR1cm4gcmVzdWx0OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgc3RyaW5nIHJlcHJlc2VuZW50YXRpb24gb2YgdGhpcyBzdGVwIGZvciBkaWFnbm9zdGljIHB1cnBvc2VzLgotICAgKgotICAgKgotICAgKiBAcmV0dXJuIEEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc3RlcCwgYnVpbHQgYnkgcmV2ZXJzZS1lbmdpbmVlcmluZyAKLSAgICogdGhlIGNvbnRhaW5lZCBpbmZvLgotICAgKi8KLSAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCi0gIHsKLQotICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0KLSAgICBmb3IgKFN0ZXBQYXR0ZXJuIHBhdCA9IHRoaXM7IHBhdCAhPSBudWxsOyBwYXQgPSBwYXQubV9yZWxhdGl2ZVBhdGhQYXR0ZXJuKQotICAgIHsKLSAgICAgIGlmIChwYXQgIT0gdGhpcykKLSAgICAgICAgYnVmLmFwcGVuZCgiLyIpOwotCi0gICAgICBidWYuYXBwZW5kKEF4aXMubmFtZXNbcGF0Lm1fYXhpc10pOwotICAgICAgYnVmLmFwcGVuZCgiOjoiKTsKLQotICAgICAgaWYgKDB4MDAwMDA1MDAwID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoImRvYygpIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE1GaWx0ZXIuU0hPV19CWUZVTkNUSU9OID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoImZ1bmN0aW9uKCkiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKERUTUZpbHRlci5TSE9XX0FMTCA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCJub2RlKCkiKTsKLSAgICAgIH0KLSAgICAgIGVsc2UgaWYgKERUTUZpbHRlci5TSE9XX1RFWFQgPT0gcGF0Lm1fd2hhdFRvU2hvdykKLSAgICAgIHsKLSAgICAgICAgYnVmLmFwcGVuZCgidGV4dCgpIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE1GaWx0ZXIuU0hPV19QUk9DRVNTSU5HX0lOU1RSVUNUSU9OID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oIik7Ci0KLSAgICAgICAgaWYgKG51bGwgIT0gcGF0Lm1fbmFtZSkKLSAgICAgICAgewotICAgICAgICAgIGJ1Zi5hcHBlbmQocGF0Lm1fbmFtZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBidWYuYXBwZW5kKCIpIik7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE1GaWx0ZXIuU0hPV19DT01NRU5UID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoImNvbW1lbnQoKSIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAobnVsbCAhPSBwYXQubV9uYW1lKQotICAgICAgewotICAgICAgICBpZiAoRFRNRmlsdGVyLlNIT1dfQVRUUklCVVRFID09IHBhdC5tX3doYXRUb1Nob3cpCi0gICAgICAgIHsKLSAgICAgICAgICBidWYuYXBwZW5kKCJAIik7Ci0gICAgICAgIH0KLQotICAgICAgICBpZiAobnVsbCAhPSBwYXQubV9uYW1lc3BhY2UpCi0gICAgICAgIHsKLSAgICAgICAgICBidWYuYXBwZW5kKCJ7Iik7Ci0gICAgICAgICAgYnVmLmFwcGVuZChwYXQubV9uYW1lc3BhY2UpOwotICAgICAgICAgIGJ1Zi5hcHBlbmQoIn0iKTsKLSAgICAgICAgfQotCi0gICAgICAgIGJ1Zi5hcHBlbmQocGF0Lm1fbmFtZSk7Ci0gICAgICB9Ci0gICAgICBlbHNlIGlmIChEVE1GaWx0ZXIuU0hPV19BVFRSSUJVVEUgPT0gcGF0Lm1fd2hhdFRvU2hvdykKLSAgICAgIHsKLSAgICAgICAgYnVmLmFwcGVuZCgiQCIpOwotICAgICAgfQotICAgICAgZWxzZSBpZiAoKERUTUZpbHRlci5TSE9XX0RPQ1VNRU5UIHwgRFRNRmlsdGVyLlNIT1dfRE9DVU1FTlRfRlJBR01FTlQpCi0gICAgICAgICAgICAgICA9PSBwYXQubV93aGF0VG9TaG93KQotICAgICAgewotICAgICAgICBidWYuYXBwZW5kKCJkb2Mtcm9vdCgpIik7Ci0gICAgICB9Ci0gICAgICBlbHNlCi0gICAgICB7Ci0gICAgICAgIGJ1Zi5hcHBlbmQoIj8iICsgSW50ZWdlci50b0hleFN0cmluZyhwYXQubV93aGF0VG9TaG93KSk7Ci0gICAgICB9Ci0KLSAgICAgIGlmIChudWxsICE9IHBhdC5tX3ByZWRpY2F0ZXMpCi0gICAgICB7Ci0gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGF0Lm1fcHJlZGljYXRlcy5sZW5ndGg7IGkrKykKLSAgICAgICAgewotICAgICAgICAgIGJ1Zi5hcHBlbmQoIlsiKTsKLSAgICAgICAgICBidWYuYXBwZW5kKHBhdC5tX3ByZWRpY2F0ZXNbaV0pOwotICAgICAgICAgIGJ1Zi5hcHBlbmQoIl0iKTsKLSAgICAgICAgfQotICAgICAgfQotICAgIH0KLQotICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKLSAgfQotCi0gIC8qKiBTZXQgdG8gdHJ1ZSB0byBzZW5kIGRpYWdub3N0aWNzIGFib3V0IHBhdHRlcm4gbWF0Y2hlcyB0byB0aGUgY29uc29sLiAqLwotICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX01BVENIRVMgPSBmYWxzZTsKLQotICAvKioKLSAgICogR2V0IHRoZSBtYXRjaCBzY29yZSBvZiB0aGUgZ2l2ZW4gbm9kZS4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFRoZSBYUGF0aCBydW50aW1lIGNvbnRleHQuCi0gICAqIEBwYXJhbSBjb250ZXh0IFRoZSBub2RlIHRvIGJlIHRlc3RlZC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBkb3VibGUgZ2V0TWF0Y2hTY29yZShYUGF0aENvbnRleHQgeGN0eHQsIGludCBjb250ZXh0KQotICAgICAgICAgIHRocm93cyBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uCi0gIHsKLQotICAgIHhjdHh0LnB1c2hDdXJyZW50Tm9kZShjb250ZXh0KTsKLSAgICB4Y3R4dC5wdXNoQ3VycmVudEV4cHJlc3Npb25Ob2RlKGNvbnRleHQpOwotCi0gICAgdHJ5Ci0gICAgewotICAgICAgWE9iamVjdCBzY29yZSA9IGV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICByZXR1cm4gc2NvcmUubnVtKCk7Ci0gICAgfQotICAgIGZpbmFsbHkKLSAgICB7Ci0gICAgICB4Y3R4dC5wb3BDdXJyZW50Tm9kZSgpOwotICAgICAgeGN0eHQucG9wQ3VycmVudEV4cHJlc3Npb25Ob2RlKCk7Ci0gICAgfQotCi0gICAgLy8gcmV0dXJuIFhQYXRoLk1BVENIX1NDT1JFX05PTkU7Ci0gIH0KLQotICAvKioKLSAgICogU2V0IHRoZSBheGlzIHRoYXQgdGhpcyBzdGVwIHNob3VsZCBmb2xsb3cuIAotICAgKgotICAgKgotICAgKiBAcGFyYW0gYXhpcyBUaGUgQXhpcyBmb3IgdGhpcyB0ZXN0LCBvbmUgb2Ygb2YgQXhlcy5BTkNFU1RPUk9SU0VMRiwgZXRjLgotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0QXhpcyhpbnQgYXhpcykKLSAgewotICAgIG1fYXhpcyA9IGF4aXM7Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBheGlzIHRoYXQgdGhpcyBzdGVwIGZvbGxvd3MuIAotICAgKgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBBeGlzIGZvciB0aGlzIHRlc3QsIG9uZSBvZiBvZiBBeGVzLkFOQ0VTVE9ST1JTRUxGLCBldGMuCi0gICAqLwotICBwdWJsaWMgaW50IGdldEF4aXMoKQotICB7Ci0gICAgcmV0dXJuIG1fYXhpczsKLSAgfQotCi19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9VbmlvblBhdHRlcm4uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL1VuaW9uUGF0dGVybi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NzMyM2QyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zL1VuaW9uUGF0dGVybi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTY4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhwYXRoLkV4cHJlc3Npb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5YUGF0aENvbnRleHQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54cGF0aC5vYmplY3RzLlhPYmplY3Q7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSB1bmlvbiBwYXR0ZXJuLCB3aGljaCBjYW4gaGF2ZSBtdWx0aXBsZSBpbmRpdmlkdWFsIAotICogU3RlcFBhdHRlcm4gcGF0dGVybnMuCi0gKi8KLXB1YmxpYyBjbGFzcyBVbmlvblBhdHRlcm4gZXh0ZW5kcyBFeHByZXNzaW9uCi17Ci0KLSAgLyoqIEFycmF5IG9mIHRoZSBjb250YWluZWQgc3RlcCBwYXR0ZXJucyB0byBiZSB0ZXN0ZWQuCi0gICAqICBAc2VyaWFsICAqLwotICBwcml2YXRlIFN0ZXBQYXR0ZXJuW10gbV9wYXR0ZXJuczsKLSAgCi0gIC8qKgotICAgKiBObyBhcmd1bWVudHMgdG8gcHJvY2Vzcywgc28gdGhpcyBkb2VzIG5vdGhpbmcuCi0gICAqLwotICBwdWJsaWMgdm9pZCBmaXh1cFZhcmlhYmxlcyhqYXZhLnV0aWwuVmVjdG9yIHZhcnMsIGludCBnbG9iYWxzU2l6ZSkKLSAgewotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9wYXR0ZXJucy5sZW5ndGg7IGkrKykgCi0gICAgewotICAgICAgbV9wYXR0ZXJuc1tpXS5maXh1cFZhcmlhYmxlcyh2YXJzLCBnbG9iYWxzU2l6ZSk7Ci0gICAgfQotICB9Ci0KLSAgCi0gIC8qKgotICAgKiBUZWxsIGlmIHRoaXMgZXhwcmVzc2lvbiBvciBpdCdzIHN1YmV4cHJlc3Npb25zIGNhbiB0cmF2ZXJzZSBvdXRzaWRlIAotICAgKiB0aGUgY3VycmVudCBzdWJ0cmVlLgotICAgKiAKLSAgICogQHJldHVybiB0cnVlIGlmIHRyYXZlcnNhbCBvdXRzaWRlIHRoZSBjb250ZXh0IG5vZGUncyBzdWJ0cmVlIGNhbiBvY2N1ci4KLSAgICovCi0gICBwdWJsaWMgYm9vbGVhbiBjYW5UcmF2ZXJzZU91dHNpZGVTdWJ0cmVlKCkKLSAgIHsKLSAgICAgaWYobnVsbCAhPSBtX3BhdHRlcm5zKQotICAgICB7Ci0gICAgICBpbnQgbiA9IG1fcGF0dGVybnMubGVuZ3RoOwotICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIAotICAgICAgewotICAgICAgICBpZihtX3BhdHRlcm5zW2ldLmNhblRyYXZlcnNlT3V0c2lkZVN1YnRyZWUoKSkKLSAgICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgIH0KLSAgICAgfQotICAgICByZXR1cm4gZmFsc2U7Ci0gICB9Ci0KLSAgLyoqCi0gICAqIFNldCB0aGUgY29udGFpbmVkIHN0ZXAgcGF0dGVybnMgdG8gYmUgdGVzdGVkLiAKLSAgICoKLSAgICoKLSAgICogQHBhcmFtIHBhdHRlcm5zIHRoZSBjb250YWluZWQgc3RlcCBwYXR0ZXJucyB0byBiZSB0ZXN0ZWQuIAotICAgKi8KLSAgcHVibGljIHZvaWQgc2V0UGF0dGVybnMoU3RlcFBhdHRlcm5bXSBwYXR0ZXJucykKLSAgewotICAgIG1fcGF0dGVybnMgPSBwYXR0ZXJuczsKLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGNvbnRhaW5lZCBzdGVwIHBhdHRlcm5zIHRvIGJlIHRlc3RlZC4gCi0gICAqCi0gICAqCi0gICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgdGhlIGNvbnRhaW5lZCBzdGVwIHBhdHRlcm5zIHRvIGJlIHRlc3RlZC4gCi0gICAqLwotICBwdWJsaWMgU3RlcFBhdHRlcm5bXSBnZXRQYXR0ZXJucygpCi0gIHsKLSAgICByZXR1cm4gbV9wYXR0ZXJuczsKLSAgfQotCi0gIC8qKgotICAgKiBUZXN0IGEgbm9kZSB0byBzZWUgaWYgaXQgbWF0Y2hlcyBhbnkgb2YgdGhlIHBhdHRlcm5zIGluIHRoZSB1bmlvbi4KLSAgICoKLSAgICogQHBhcmFtIHhjdHh0IFhQYXRoIHJ1bnRpbWUgY29udGV4dC4KLSAgICoKLSAgICogQHJldHVybiB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9OT0RFVEVTVH0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTk9ORX0sCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfTlNXSUxEfSwKLSAgICogICAgICAgICB7QGxpbmsgb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucy5Ob2RlVGVzdCNTQ09SRV9RTkFNRX0sIG9yCi0gICAqICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUueHBhdGgucGF0dGVybnMuTm9kZVRlc3QjU0NPUkVfT1RIRVJ9LgotICAgKgotICAgKiBAdGhyb3dzIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJFeGNlcHRpb24KLSAgICovCi0gIHB1YmxpYyBYT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0KSB0aHJvd3MgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckV4Y2VwdGlvbgotICB7Ci0KLSAgICBYT2JqZWN0IGJlc3RTY29yZSA9IG51bGw7Ci0gICAgaW50IG4gPSBtX3BhdHRlcm5zLmxlbmd0aDsKLQotICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQotICAgIHsKLSAgICAgIFhPYmplY3Qgc2NvcmUgPSBtX3BhdHRlcm5zW2ldLmV4ZWN1dGUoeGN0eHQpOwotCi0gICAgICBpZiAoc2NvcmUgIT0gTm9kZVRlc3QuU0NPUkVfTk9ORSkKLSAgICAgIHsKLSAgICAgICAgaWYgKG51bGwgPT0gYmVzdFNjb3JlKQotICAgICAgICAgIGJlc3RTY29yZSA9IHNjb3JlOwotICAgICAgICBlbHNlIGlmIChzY29yZS5udW0oKSA+IGJlc3RTY29yZS5udW0oKSkKLSAgICAgICAgICBiZXN0U2NvcmUgPSBzY29yZTsKLSAgICAgIH0KLSAgICB9Ci0KLSAgICBpZiAobnVsbCA9PSBiZXN0U2NvcmUpCi0gICAgewotICAgICAgYmVzdFNjb3JlID0gTm9kZVRlc3QuU0NPUkVfTk9ORTsKLSAgICB9Ci0KLSAgICByZXR1cm4gYmVzdFNjb3JlOwotICB9Ci19CmRpZmYgLS1naXQgYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhZWQ5MjguLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvcGF0dGVybnMvcGFja2FnZS5odG1sCisrKyAvZGV2L251bGwKQEAgLTEsOCArMCwwIEBACi08aHRtbD4KLSAgPHRpdGxlPlhQYXRoIG5vZGV0ZXN0IGFuZCBYU0xUIHBhdHRlcm4gbWF0Y2hpbmcgc3VwcG9ydC48L3RpdGxlPgotICA8Ym9keT4KLSAgICA8cD5JbXBsZW1lbnRhdGlvbiBvZiBYUGF0aCBub2RlVGVzdCBzdXBwb3J0LCBhbmQgWFNMVCBwYXR0ZXJuIG1hdGNoaW5nIHN1cHBvcnQuPHA+Ci0gPC9ib2R5PgotPC9odG1sPgotCi0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VCdW5kbGUuamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VCdW5kbGUuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWYxNWJiMC4uMDAwMDAwMAotLS0gYS9zcmMvb3JnL2FwYWNoZS94cGF0aC9yZXMvWFBBVEhFcnJvclJlc291cmNlQnVuZGxlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMDkgKzAsMCBAQAotLyoKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS54cGF0aC5yZXM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLQotLyoqCi0gKiA8bWV0YSBuYW1lPSJ1c2FnZSIgY29udGVudD0iaW50ZXJuYWwiLz4KLSAqIFRoZSBkZWZhdWx0IChlbmdsaXNoKSByZXNvdXJjZSBidW5kbGUuCi0gKi8KLXB1YmxpYyBjbGFzcyBYUEFUSEVycm9yUmVzb3VyY2VCdW5kbGUgZXh0ZW5kcyBMaXN0UmVzb3VyY2VCdW5kbGUKLXsKLQotICAvKioKLSAgICogR2V0IHRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKgotICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGlvbiBsaXN0LgotICAgKi8KLSAgcHVibGljIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKQotICB7Ci0gICAgcmV0dXJuIGNvbnRlbnRzOwotICB9Ci0KLSAgLyoqIFRoZSBhc3NvY2lhdGlvbiBsaXN0LiAgICAgICAgICovCi0gIHN0YXRpYyBmaW5hbCBPYmplY3RbXVtdIGNvbnRlbnRzID0KLSAgewotICAgIHsgInVpX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJoZWxwX2xhbmd1YWdlIiwgImVuIiB9LCB7ICJsYW5ndWFnZSIsICJlbiIgfSwKLSAgICB7ICJFUlJPUjAwMDEiLCAiMDAwMSIgfSwgeyAiRVJST1IwMDAyIiwgIjAwMDIiIH0sIHsgIkVSUk9SMDAwMyIsICIwMDAzIiB9LAotICAgIHsgIkVSUk9SMDAwNCIsICIwMDA0IiB9LCB7ICJFUlJPUjAwMDUiLCAiMDAwNSIgfSwgeyAiRVJST1IwMDA2IiwgIjAwMDYiIH0sCi0gICAgeyAiRVJST1IwMDA3IiwgIjAwMDciIH0sIHsgIkVSUk9SMDAwOCIsICIwMDA4IiB9LCB7ICJFUlJPUjAwMDkiLCAiMDAwOSIgfSwKLSAgICB7ICJFUlJPUjAwMTAiLCAiMDAxMCIgfSwgeyAiRVJST1IwMDExIiwgIjAwMTEiIH0sIHsgIkVSUk9SMDAxMiIsICIwMDEyIiB9LAotICAgIHsgIkVSUk9SMDAxMyIsICIwMDEzIiB9LCB7ICJFUlJPUjAwMTQiLCAiMDAxNCIgfSwgeyAiRVJST1IwMDE1IiwgIjAwMTUiIH0sCi0gICAgeyAiRVJST1IwMDE2IiwgIjAwMTYiIH0sIHsgIkVSUk9SMDAxNyIsICIwMDE3IiB9LCB7ICJFUlJPUjAwMTgiLCAiMDAxOCIgfSwKLSAgICB7ICJFUlJPUjAwMTkiLCAiMDAxOSIgfSwgeyAiRVJST1IwMDIwIiwgIjAwMjAiIH0sIHsgIkVSUk9SMDAyMSIsICIwMDIxIiB9LAotICAgIHsgIkVSUk9SMDAyMiIsICIwMDIyIiB9LCB7ICJFUlJPUjAwMjMiLCAiMDAyMyIgfSwgeyAiRVJST1IwMDI0IiwgIjAwMjQiIH0sCi0gICAgeyAiRVJST1IwMDI1IiwgIjAwMjUiIH0sIHsgIkVSUk9SMDAyNiIsICIwMDI2IiB9LCB7ICJFUlJPUjAwMjciLCAiMDAyNyIgfSwKLSAgICB7ICJFUlJPUjAwMjgiLCAiMDAyOCIgfSwgeyAiRVJST1IwMDI5IiwgIjAwMjkiIH0sIHsgIkVSUk9SMDAzMCIsICIwMDMwIiB9LAotICAgIHsgIkVSUk9SMDAzMSIsICIwMDMxIiB9LCB7ICJFUlJPUjAwMzIiLCAiMDAzMiIgfSwgeyAiRVJST1IwMDMzIiwgIjAwMzMiIH0sCi0gICAgeyAiRVJST1IwMDM0IiwgIjAwMzQiIH0sIHsgIkVSUk9SMDAzNSIsICIwMDM1IiB9LCB7ICJFUlJPUjAwMzYiLCAiMDAzNiIgfSwKLSAgICB7ICJFUlJPUjAwMzciLCAiMDAzNyIgfSwgeyAiRVJST1IwMDM4IiwgIjAwMzgiIH0sIHsgIkVSUk9SMDAzOSIsICIwMDM5IiB9LAotICAgIHsgIkVSUk9SMDA0MCIsICIwMDQwIiB9LCB7ICJFUlJPUjAwNDEiLCAiMDA0MSIgfSwgeyAiRVJST1IwMDQyIiwgIjAwNDIiIH0sCi0gICAgeyAiRVJST1IwMDQzIiwgIjAwNDMiIH0sIHsgIkVSUk9SMDA0NCIsICIwMDQ0IiB9LCB7ICJFUlJPUjAwNDUiLCAiMDA0NSIgfSwKLSAgICB7ICJFUlJPUjAwNDYiLCAiMDA0NiIgfSwgeyAiRVJST1IwMDQ3IiwgIjAwNDciIH0sIHsgIkVSUk9SMDA0OCIsICIwMDQ4IiB9LAotICAgIHsgIkVSUk9SMDA0OSIsICIwMDQ5IiB9LCB7ICJFUlJPUjAwNTAiLCAiMDA1MCIgfSwgeyAiRVJST1IwMDUxIiwgIjAwNTEiIH0sCi0gICAgeyAiRVJST1IwMDUyIiwgIjAwNTIiIH0sIHsgIkVSUk9SMDA1MyIsICIwMDUzIiB9LCB7ICJFUlJPUjAwNTQiLCAiMDA1NCIgfSwKLSAgICB7ICJFUlJPUjAwNTUiLCAiMDA1NSIgfSwgeyAiRVJST1IwMDU2IiwgIjAwNTYiIH0sIHsgIkVSUk9SMDA1NyIsICIwMDU3IiB9LAotICAgIHsgIkVSUk9SMDA1OCIsICIwMDU4IiB9LCB7ICJFUlJPUjAwNTkiLCAiMDA1OSIgfSwgeyAiRVJST1IwMDYwIiwgIjAwNjAiIH0sCi0gICAgeyAiV0FSTklORzAwMDEiLCAiMDAwMSIgfSwgeyAiV0FSTklORzAwMDIiLCAiMDAwMiIgfSwKLSAgICB7ICJXQVJOSU5HMDAwMyIsICIwMDAzIiB9LCB7ICJXQVJOSU5HMDAwNCIsICIwMDA0IiB9LAotICAgIHsgIldBUk5JTkcwMDA1IiwgIjAwMDUiIH0sIHsgIldBUk5JTkcwMDA2IiwgIjAwMDYiIH0sCi0gICAgeyAiV0FSTklORzAwMDciLCAiMDAwNyIgfSwgeyAiV0FSTklORzAwMDgiLCAiMDAwOCIgfSwKLSAgICB7ICJXQVJOSU5HMDAwOSIsICIwMDA5IiB9LCB7ICJXQVJOSU5HMDAxMCIsICIwMDEwIiB9LAotICAgIHsgIldBUk5JTkcwMDExIiwgIjAwMTEiIH0KLSAgfTsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzLmphdmEgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9yZXMvWFBBVEhFcnJvclJlc291cmNlcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzNTZiOTEwLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjMxICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgucmVzOwotCi1pbXBvcnQgb3JnLmFwYWNoZS54bWwudXRpbHMucmVzLlhSZXNvdXJjZUJ1bmRsZUJhc2U7Ci0KLQotaW1wb3J0IGphdmEudXRpbC4qOwotCi1pbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBTZXQgdXAgZXJyb3IgbWVzc2FnZXMuCi0gKiBXZSBidWlsZCBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiBtZXNzYWdlIGtleXMgYW5kCi0gKiBtZXNzYWdlIHN0cmluZ3MuIEluIG9yZGVyIHRvIGFkZCBhIG5ldyBtZXNzYWdlIGhlcmUsCi0gKiB5b3UgbmVlZCB0byBmaXJzdCB1cGRhdGUgdGhlIGNvdW50IG9mIG1lc3NhZ2VzKE1BWF9DT0RFKW9yCi0gKiB0aGUgY291bnQgb2Ygd2FybmluZ3MoTUFYX1dBUk5JTkcpLiBUaGUgYXJyYXkgd2lsbCBiZQotICogYXV0b21hdGljYWxseSBmaWxsZWQgaW4gd2l0aCB0aGUga2V5cywgYnV0IHlvdSBuZWVkIHRvCi0gKiBmaWxsIGluIHRoZSBhY3R1YWwgbWVzc2FnZSBzdHJpbmcuIEZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zCi0gKiBiZWxvdy4KLSAqLwotcHVibGljIGNsYXNzIFhQQVRIRXJyb3JSZXNvdXJjZXMgZXh0ZW5kcyBYUmVzb3VyY2VCdW5kbGVCYXNlCi17Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1NVRkZJWCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9TVUZGSVggPSAiRVIiOwotCi0gIC8qKiBGaWVsZCBXQVJOSU5HX1NVRkZJWCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX1NVRkZJWCA9ICJXUiI7Ci0KLSAgLyoqIEZpZWxkIE1BWF9DT0RFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9DT0RFID0gODM7ICAvLyB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMgICAgICAgICAgCi0KLSAgLyoqIEZpZWxkIE1BWF9XQVJOSU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9XQVJOSU5HID0gMTE7ICAvLyB0aGlzIGlzIG5lZWRlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2Ygd2FybmluZ3MKLQotICAvKiogRmllbGQgTUFYX09USEVSUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfT1RIRVJTID0gMjA7Ci0KLSAgLyoqIEZpZWxkIE1BWF9NRVNTQUdFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhfTUVTU0FHRVMgPSBNQVhfQ09ERSArIE1BWF9XQVJOSU5HICsgMTsKLQotICAvKiogRmllbGQgY29udGVudHMgICAgICAgICAgKi8KLSAgc3RhdGljIGZpbmFsIE9iamVjdFtdW10gY29udGVudHMgPQotICAgIG5ldyBPYmplY3RbTUFYX01FU1NBR0VTICsgTUFYX09USEVSUyArIDFdWzJdOwotCi0gIC8qCi0gICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2Uga2V5cy4KLSAgKiBUaGlzIGRvZXMgbm90IG5lZWQgdG8gYmUgdXBkYXRlZC4gSWYgTUFYX0NPREUgYW5kIE1BWF9XQVJOSU5HCi0gICogYXJlIGNvcnJlY3QsIHRoZSBrZXlzIHdpbGwgZ2V0IGZpbGxlZCBpbiBhdXRvbWF0aWNhbGx5IHdpdGgKLSAgKiB0aGUgdmFsdWUgRVJ4eHh4IChXUnh4eHggZm9yIHdhcm5pbmdzKSB3aGVyZSB4eHh4IGlzIGEKLSAgKiBmb3JtYXR0ZWQgbnVtYmVyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGVycm9yIGNvZGUgKGkuZS4gRVIwMDAxKS4KLSAgKi8KLSAgc3RhdGljCi0gIHsKLSAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BWF9DT0RFICsgMTsgaSsrKQotICAgIHsKLSAgICAgIGNvbnRlbnRzW2ldWzBdID0gZ2V0TUtleShpKTsKLSAgICB9Ci0KLSAgICBmb3IgKGludCBpID0gMTsgaSA8IE1BWF9XQVJOSU5HICsgMTsgaSsrKQotICAgIHsKLSAgICAgIGNvbnRlbnRzW2kgKyBNQVhfQ09ERV1bMF0gPSBnZXRXS2V5KGkpOwotICAgIH0KLSAgfQotCi0gIC8qCi0gICogTm93IGZpbGwgaW4gdGhlIG1lc3NhZ2UgdGV4dC4KLSAgKiBGaXJzdCBjcmVhdGUgYW4gaW50IGZvciB0aGUgbWVzc2FnZSBjb2RlLiBNYWtlIHN1cmUgeW91Ci0gICogdXBkYXRlIE1BWF9DT0RFIGZvciBlcnJvciBtZXNzYWdlcyBhbmQgTUFYX1dBUk5JTkcgZm9yIHdhcm5pbmdzCi0gICogVGhlbiBmaWxsIGluIHRoZSBtZXNzYWdlIHRleHQgZm9yIHRoYXQgbWVzc2FnZSBjb2RlIGluIHRoZQotICAqIGFycmF5LiBVc2UgdGhlIG5ldyBlcnJvciBjb2RlIGFzIHRoZSBpbmRleCBpbnRvIHRoZSBhcnJheS4KLSAgKi8KLQotICAvLyBFcnJvciBtZXNzYWdlcy4uLgotCi0gIC8qKiBGaWVsZCBFUlJPUjAwMDAgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJST1IwMDAwID0gMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSUk9SMDAwMF1bMV0gPSAiezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9DVVJSRU5UX05PVF9BTExPV0VEX0lOX01BVENIICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NVUlJFTlRfTk9UX0FMTE9XRURfSU5fTUFUQ0ggPSAxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ1VSUkVOVF9OT1RfQUxMT1dFRF9JTl9NQVRDSF1bMV0gPQotICAgICAgIlRoZSBjdXJyZW50KCkgZnVuY3Rpb24gaXMgbm90IGFsbG93ZWQgaW4gYSBtYXRjaCBwYXR0ZXJuISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ1VSUkVOVF9UQUtFU19OT19BUkdTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NVUlJFTlRfVEFLRVNfTk9fQVJHUyA9IDI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DVVJSRU5UX1RBS0VTX05PX0FSR1NdWzFdID0KLSAgICAgICJUaGUgY3VycmVudCgpIGZ1bmN0aW9uIGRvZXMgbm90IGFjY2VwdCBhcmd1bWVudHMhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9ET0NVTUVOVF9SRVBMQUNFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9ET0NVTUVOVF9SRVBMQUNFRCA9IDM7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9ET0NVTUVOVF9SRVBMQUNFRF1bMV0gPQotICAgICAgImRvY3VtZW50KCkgZnVuY3Rpb24gaW1wbGVtZW50YXRpb24gaGFzIGJlZW4gcmVwbGFjZWQgYnkgb3JnLmFwYWNoZS54YWxhbi54c2x0LkZ1bmNEb2N1bWVudCEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DID0gNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPTlRFWFRfSEFTX05PX09XTkVSRE9DXVsxXSA9Ci0gICAgICAiY29udGV4dCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfTE9DQUxOQU1FX0hBU19UT09fTUFOWV9BUkdTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0xPQ0FMTkFNRV9IQVNfVE9PX01BTllfQVJHUyA9IDU7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9MT0NBTE5BTUVfSEFTX1RPT19NQU5ZX0FSR1NdWzFdID0KLSAgICAgICJsb2NhbC1uYW1lKCkgaGFzIHRvbyBtYW55IGFyZ3VtZW50cy4iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX05BTUVTUEFDRVVSSV9IQVNfVE9PX01BTllfQVJHUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OQU1FU1BBQ0VVUklfSEFTX1RPT19NQU5ZX0FSR1MgPSA2OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTkFNRVNQQUNFVVJJX0hBU19UT09fTUFOWV9BUkdTXVsxXSA9Ci0gICAgICAibmFtZXNwYWNlLXVyaSgpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHUyA9IDc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT1JNQUxJWkVTUEFDRV9IQVNfVE9PX01BTllfQVJHU11bMV0gPQotICAgICAgIm5vcm1hbGl6ZS1zcGFjZSgpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9OVU1CRVJfSEFTX1RPT19NQU5ZX0FSR1MgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTlVNQkVSX0hBU19UT09fTUFOWV9BUkdTID0gODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05VTUJFUl9IQVNfVE9PX01BTllfQVJHU11bMV0gPQotICAgICAgIm51bWJlcigpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9OQU1FX0hBU19UT09fTUFOWV9BUkdTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX05BTUVfSEFTX1RPT19NQU5ZX0FSR1MgPSA5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTkFNRV9IQVNfVE9PX01BTllfQVJHU11bMV0gPSAibmFtZSgpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1MgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU1RSSU5HX0hBU19UT09fTUFOWV9BUkdTID0gMTA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TVFJJTkdfSEFTX1RPT19NQU5ZX0FSR1NdWzFdID0KLSAgICAgICJzdHJpbmcoKSBoYXMgdG9vIG1hbnkgYXJndW1lbnRzLiI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1NUUklOR0xFTkdUSF9IQVNfVE9PX01BTllfQVJHUyA9IDExOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfU1RSSU5HTEVOR1RIX0hBU19UT09fTUFOWV9BUkdTXVsxXSA9Ci0gICAgICAic3RyaW5nLWxlbmd0aCgpIGhhcyB0b28gbWFueSBhcmd1bWVudHMuIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9UUkFOU0xBVEVfVEFLRVNfM19BUkdTICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1RSQU5TTEFURV9UQUtFU18zX0FSR1MgPSAxMjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1RSQU5TTEFURV9UQUtFU18zX0FSR1NdWzFdID0KLSAgICAgICJUaGUgdHJhbnNsYXRlKCkgZnVuY3Rpb24gdGFrZXMgdGhyZWUgYXJndW1lbnRzISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfVU5QQVJTRURFTlRJVFlVUklfVEFLRVNfMV9BUkcgPSAxMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOUEFSU0VERU5USVRZVVJJX1RBS0VTXzFfQVJHXVsxXSA9Ci0gICAgICAiVGhlIHVucGFyc2VkLWVudGl0eS11cmkgZnVuY3Rpb24gc2hvdWxkIHRha2Ugb25lIGFyZ3VtZW50ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTkFNRVNQQUNFQVhJU19OT1RfSU1QTEVNRU5URUQgPSAxNDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05BTUVTUEFDRUFYSVNfTk9UX0lNUExFTUVOVEVEXVsxXSA9Ci0gICAgICAibmFtZXNwYWNlIGF4aXMgbm90IGltcGxlbWVudGVkIHlldCEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX1VOS05PV05fQVhJUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9VTktOT1dOX0FYSVMgPSAxNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOS05PV05fQVhJU11bMV0gPSAidW5rbm93biBheGlzOiB7MH0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1VOS05PV05fTUFUQ0hfT1BFUkFUSU9OID0gMTY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9VTktOT1dOX01BVENIX09QRVJBVElPTl1bMV0gPSAidW5rbm93biBtYXRjaCBvcGVyYXRpb24hIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTkNPUlJFQ1RfQVJHX0xFTkdUSCA9IDE3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSU5DT1JSRUNUX0FSR19MRU5HVEhdWzFdID0KLSAgICAgICJBcmcgbGVuZ3RoIG9mIHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24oKSBub2RlIHRlc3QgaXMgaW5jb3JyZWN0ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ0FOVF9DT05WRVJUX1RPX05VTUJFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSID0gMTg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DQU5UX0NPTlZFUlRfVE9fTlVNQkVSXVsxXSA9Ci0gICAgICAiQ2FuIG5vdCBjb252ZXJ0IHswfSB0byBhIG51bWJlciI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTlRfQ09OVkVSVF9UT19OT0RFTElTVCA9IDE5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOVF9DT05WRVJUX1RPX05PREVMSVNUXVsxXSA9Ci0gICAgICAiQ2FuIG5vdCBjb252ZXJ0IHswfSB0byBhIE5vZGVMaXN0ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ0FOVF9DT05WRVJUX1RPX01VVEFCTEVOT0RFTElTVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUID0gMjA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DQU5UX0NPTlZFUlRfVE9fTVVUQUJMRU5PREVMSVNUXVsxXSA9Ci0gICAgICAiQ2FuIG5vdCBjb252ZXJ0IHswfSB0byBhIE5vZGVTZXREVE0hIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX0NPTlZFUlRfVE9fVFlQRSA9IDIxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOVF9DT05WRVJUX1RPX1RZUEVdWzFdID0KLSAgICAgICJDYW4gbm90IGNvbnZlcnQgezB9IHRvIGEgdHlwZSN7MX0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0VYUEVDVEVEX01BVENIX1BBVFRFUk4gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTiA9IDIyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRVhQRUNURURfTUFUQ0hfUEFUVEVSTl1bMV0gPQotICAgICAgIkV4cGVjdGVkIG1hdGNoIHBhdHRlcm4gaW4gZ2V0TWF0Y2hTY29yZSEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NPVUxETk9UX0dFVF9WQVJfTkFNRUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRCA9IDIzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ09VTEROT1RfR0VUX1ZBUl9OQU1FRF1bMV0gPQotICAgICAgIkNvdWxkIG5vdCBnZXQgdmFyaWFibGUgbmFtZWQgezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9VTktOT1dOX09QQ09ERSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9VTktOT1dOX09QQ09ERSA9IDI0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfVU5LTk9XTl9PUENPREVdWzFdID0gIkVSUk9SISBVbmtub3duIG9wIGNvZGU6IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRVhUUkFfSUxMRUdBTF9UT0tFTlMgPSAyNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0VYVFJBX0lMTEVHQUxfVE9LRU5TXVsxXSA9ICJFeHRyYSBpbGxlZ2FsIHRva2VuczogezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRVhQRUNURURfRE9VQkxFX1FVT1RFID0gMjY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FWFBFQ1RFRF9ET1VCTEVfUVVPVEVdWzFdID0KLSAgICAgICJtaXNxdW90ZWQgbGl0ZXJhbC4uLiBleHBlY3RlZCBkb3VibGUgcXVvdGUhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRVhQRUNURURfU0lOR0xFX1FVT1RFID0gMjc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FWFBFQ1RFRF9TSU5HTEVfUVVPVEVdWzFdID0KLSAgICAgICJtaXNxdW90ZWQgbGl0ZXJhbC4uLiBleHBlY3RlZCBzaW5nbGUgcXVvdGUhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9FTVBUWV9FWFBSRVNTSU9OICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0VNUFRZX0VYUFJFU1NJT04gPSAyODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0VNUFRZX0VYUFJFU1NJT05dWzFdID0gIkVtcHR5IGV4cHJlc3Npb24hIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9FWFBFQ1RFRF9CVVRfRk9VTkQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRVhQRUNURURfQlVUX0ZPVU5EID0gMjk7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9FWFBFQ1RFRF9CVVRfRk9VTkRdWzFdID0gIkV4cGVjdGVkIHswfSwgYnV0IGZvdW5kOiB7MX0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTkNPUlJFQ1RfUFJPR1JBTU1FUl9BU1NFUlRJT04gPSAzMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lOQ09SUkVDVF9QUk9HUkFNTUVSX0FTU0VSVElPTl1bMV0gPQotICAgICAgIlByb2dyYW1tZXIgYXNzZXJ0aW9uIGlzIGluY29ycmVjdCEgLSB7MH0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9CT09MRUFOX0FSR19OT19MT05HRVJfT1BUSU9OQUwgPSAzMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0JPT0xFQU5fQVJHX05PX0xPTkdFUl9PUFRJT05BTF1bMV0gPQotICAgICAgImJvb2xlYW4oLi4uKSBhcmd1bWVudCBpcyBubyBsb25nZXIgb3B0aW9uYWwgd2l0aCAxOTk5MDcwOSBYUGF0aCBkcmFmdC4iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0ZPVU5EX0NPTU1BX0JVVF9OT19QUkVDRURJTkdfQVJHID0gMzI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9GT1VORF9DT01NQV9CVVRfTk9fUFJFQ0VESU5HX0FSR11bMV0gPQotICAgICAgIkZvdW5kICcsJyBidXQgbm8gcHJlY2VkaW5nIGFyZ3VtZW50ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRk9VTkRfQ09NTUFfQlVUX05PX0ZPTExPV0lOR19BUkcgPSAzMzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0ZPVU5EX0NPTU1BX0JVVF9OT19GT0xMT1dJTkdfQVJHXVsxXSA9Ci0gICAgICAiRm91bmQgJywnIGJ1dCBubyBmb2xsb3dpbmcgYXJndW1lbnQhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVggICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUFJFRElDQVRFX0lMTEVHQUxfU1lOVEFYID0gMzQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUkVESUNBVEVfSUxMRUdBTF9TWU5UQVhdWzFdID0KLSAgICAgICInLi5bcHJlZGljYXRlXScgb3IgJy5bcHJlZGljYXRlXScgaXMgaWxsZWdhbCBzeW50YXguICBVc2UgJ3NlbGY6Om5vZGUoKVtwcmVkaWNhdGVdJyBpbnN0ZWFkLiI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfSUxMRUdBTF9BWElTX05BTUUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSUxMRUdBTF9BWElTX05BTUUgPSAzNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lMTEVHQUxfQVhJU19OQU1FXVsxXSA9ICJpbGxlZ2FsIGF4aXMgbmFtZTogezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9VTktOT1dOX05PREVUWVBFICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1VOS05PV05fTk9ERVRZUEUgPSAzNjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOS05PV05fTk9ERVRZUEVdWzFdID0gIlVua25vd24gbm9kZXR5cGU6IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfUEFUVEVSTl9MSVRFUkFMX05FRURTX0JFX1FVT1RFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEID0gMzc7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QQVRURVJOX0xJVEVSQUxfTkVFRFNfQkVfUVVPVEVEXVsxXSA9Ci0gICAgICAiUGF0dGVybiBsaXRlcmFsICh7MH0pIG5lZWRzIHRvIGJlIHF1b3RlZCEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NPVUxETk9UX0JFX0ZPUk1BVFRFRF9UT19OVU1CRVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUiA9IDM4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ09VTEROT1RfQkVfRk9STUFUVEVEX1RPX05VTUJFUl1bMV0gPQotICAgICAgInswfSBjb3VsZCBub3QgYmUgZm9ybWF0dGVkIHRvIGEgbnVtYmVyISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04gICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09VTEROT1RfQ1JFQVRFX1hNTFBST0NFU1NPUkxJQUlTT04gPSAzOTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPVUxETk9UX0NSRUFURV9YTUxQUk9DRVNTT1JMSUFJU09OXVsxXSA9Ci0gICAgICAiQ291bGQgbm90IGNyZWF0ZSBYTUwgVHJhbnNmb3JtZXJGYWN0b3J5IExpYWlzb246IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfRElETk9UX0ZJTkRfWFBBVEhfU0VMRUNUX0VYUCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQID0gNDA7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9ESUROT1RfRklORF9YUEFUSF9TRUxFQ1RfRVhQXVsxXSA9Ci0gICAgICAiRXJyb3IhIERpZCBub3QgZmluZCB4cGF0aCBzZWxlY3QgZXhwcmVzc2lvbiAoLXNlbGVjdCkuIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9DT1VMRE5PVF9GSU5EX0VORE9QX0FGVEVSX09QTE9DQVRJT05QQVRIICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEggPSA0MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPVUxETk9UX0ZJTkRfRU5ET1BfQUZURVJfT1BMT0NBVElPTlBBVEhdWzFdID0KLSAgICAgICJFUlJPUiEgQ291bGQgbm90IGZpbmQgRU5ET1AgYWZ0ZXIgT1BfTE9DQVRJT05QQVRIIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9FUlJPUl9PQ0NVUkVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0VSUk9SX09DQ1VSRUQgPSA0MjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0VSUk9SX09DQ1VSRURdWzFdID0gIkVycm9yIG9jY3VyZWQhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9JTExFR0FMX1ZBUklBQkxFX1JFRkVSRU5DRSA9IDQzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0VdWzFdID0KLSAgICAgICJWYXJpYWJsZVJlZmVyZW5jZSBnaXZlbiBmb3IgdmFyaWFibGUgb3V0IG9mIGNvbnRleHQgb3Igd2l0aG91dCBkZWZpbml0aW9uISAgTmFtZSA9IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQVhFU19OT1RfQUxMT1dFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9BWEVTX05PVF9BTExPV0VEID0gNDQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9BWEVTX05PVF9BTExPV0VEXVsxXSA9Ci0gICAgICAiT25seSBjaGlsZDo6IGFuZCBhdHRyaWJ1dGU6OiBheGVzIGFyZSBhbGxvd2VkIGluIG1hdGNoIHBhdHRlcm5zISAgT2ZmZW5kaW5nIGF4ZXMgPSB7MH0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0tFWV9IQVNfVE9PX01BTllfQVJHUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9LRVlfSEFTX1RPT19NQU5ZX0FSR1MgPSA0NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0tFWV9IQVNfVE9PX01BTllfQVJHU11bMV0gPQotICAgICAgImtleSgpIGhhcyBhbiBpbmNvcnJlY3QgbnVtYmVyIG9mIGFyZ3VtZW50cy4iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NPVU5UX1RBS0VTXzFfQVJHICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVU5UX1RBS0VTXzFfQVJHID0gNDY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DT1VOVF9UQUtFU18xX0FSR11bMV0gPQotICAgICAgIlRoZSBjb3VudCBmdW5jdGlvbiBzaG91bGQgdGFrZSBvbmUgYXJndW1lbnQhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gPSA0NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT05dWzFdID0gIkNvdWxkIG5vdCBmaW5kIGZ1bmN0aW9uOiB7MH0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1VOU1VQUE9SVEVEX0VOQ09ESU5HID0gNDg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9VTlNVUFBPUlRFRF9FTkNPRElOR11bMV0gPSAiVW5zdXBwb3J0ZWQgZW5jb2Rpbmc6IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfUFJPQkxFTV9JTl9EVE1fTkVYVFNJQkxJTkcgPSA0OTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BST0JMRU1fSU5fRFRNX05FWFRTSUJMSU5HXVsxXSA9Ci0gICAgICAiUHJvYmxlbSBvY2N1cmVkIGluIERUTSBpbiBnZXROZXh0U2libGluZy4uLiB0cnlpbmcgdG8gcmVjb3ZlciI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9XUklURV9UT19FTVBUWU5PREVMSVNUSU1QTCA9IDUwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOTk9UX1dSSVRFX1RPX0VNUFRZTk9ERUxJU1RJTVBMXVsxXSA9Ci0gICAgICAiUHJvZ3JhbW1lciBlcnJvcjogRW1wdHlOb2RlTGlzdCBjYW4gbm90IGJlIHdyaXR0ZW4gdG8uIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU0VURE9NRkFDVE9SWV9OT1RfU1VQUE9SVEVEID0gNTE7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9TRVRET01GQUNUT1JZX05PVF9TVVBQT1JURURdWzFdID0KLSAgICAgICJzZXRET01GYWN0b3J5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgWFBhdGhDb250ZXh0ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfUFJFRklYX01VU1RfUkVTT0xWRSAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9QUkVGSVhfTVVTVF9SRVNPTFZFID0gNTI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUkVGSVhfTVVTVF9SRVNPTFZFXVsxXSA9Ci0gICAgICAiUHJlZml4IG11c3QgcmVzb2x2ZSB0byBhIG5hbWVzcGFjZTogezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9QQVJTRV9OT1RfU1VQUE9SVEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BBUlNFX05PVF9TVVBQT1JURUQgPSA1MzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1BBUlNFX05PVF9TVVBQT1JURURdWzFdID0KLSAgICAgICJwYXJzZSAoSW5wdXRTb3VyY2Ugc291cmNlKSBub3Qgc3VwcG9ydGVkIGluIFhQYXRoQ29udGV4dCEgQ2FuIG5vdCBvcGVuIHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ1JFQVRFRE9DVU1FTlRfTk9UX1NVUFBPUlRFRCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEID0gNTQ7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DUkVBVEVET0NVTUVOVF9OT1RfU1VQUE9SVEVEXVsxXSA9Ci0gICAgICAiY3JlYXRlRG9jdW1lbnQoKSBub3Qgc3VwcG9ydGVkIGluIFhQYXRoQ29udGV4dCEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DSElMRF9IQVNfTk9fT1dORVJfRE9DVU1FTlQgPSA1NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF1bMV0gPQotICAgICAgIkF0dHJpYnV0ZSBjaGlsZCBkb2VzIG5vdCBoYXZlIGFuIG93bmVyIGRvY3VtZW50ISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0hJTERfSEFTX05PX09XTkVSX0RPQ1VNRU5UX0VMRU1FTlQgPSA1NjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NISUxEX0hBU19OT19PV05FUl9ET0NVTUVOVF9FTEVNRU5UXVsxXSA9Ci0gICAgICAiQXR0cmlidXRlIGNoaWxkIGRvZXMgbm90IGhhdmUgYW4gb3duZXIgZG9jdW1lbnQgZWxlbWVudCEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX1NBWF9BUElfTk9UX0hBTkRMRUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfU0FYX0FQSV9OT1RfSEFORExFRCA9IDU3OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfU0FYX0FQSV9OT1RfSEFORExFRF1bMV0gPQotICAgICAgIlNBWCBBUEkgY2hhcmFjdGVycyhjaGFyIGNoW10uLi4gbm90IGhhbmRsZWQgYnkgdGhlIERUTSEiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0lHTk9SQUJMRV9XSElURVNQQUNFX05PVF9IQU5ETEVEID0gNTg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9JR05PUkFCTEVfV0hJVEVTUEFDRV9OT1RfSEFORExFRF1bMV0gPQotICAgICAgImlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhciBjaFtdLi4uIG5vdCBoYW5kbGVkIGJ5IHRoZSBEVE0hIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9EVE1fQ0FOTk9UX0hBTkRMRV9OT0RFUyA9IDU5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRFRNX0NBTk5PVF9IQU5ETEVfTk9ERVNdWzFdID0KLSAgICAgICJEVE1MaWFpc29uIGNhbiBub3QgaGFuZGxlIG5vZGVzIG9mIHR5cGUgezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9YRVJDRVNfQ0FOTk9UX0hBTkRMRV9OT0RFUyA9IDYwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfWEVSQ0VTX0NBTk5PVF9IQU5ETEVfTk9ERVNdWzFdID0KLSAgICAgICJET00ySGVscGVyIGNhbiBub3QgaGFuZGxlIG5vZGVzIG9mIHR5cGUgezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9YRVJDRVNfUEFSU0VfRVJST1JfREVUQUlMUyA9IDYxOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfWEVSQ0VTX1BBUlNFX0VSUk9SX0RFVEFJTFNdWzFdID0KLSAgICAgICJET00ySGVscGVyLnBhcnNlIGVycm9yOiBTeXN0ZW1JRCAtIHswfSBsaW5lIC0gezF9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBFUl9YRVJDRVNfUEFSU0VfRVJST1IgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWEVSQ0VTX1BBUlNFX0VSUk9SID0gNjI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9YRVJDRVNfUEFSU0VfRVJST1JdWzFdID0gIkRPTTJIZWxwZXIucGFyc2UgZXJyb3IiOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9DQU5UX09VVFBVVF9URVhUX0JFRk9SRV9ET0MgPSA2MzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTlRfT1VUUFVUX1RFWFRfQkVGT1JFX0RPQ11bMV0gPQotICAgICAgIldhcm5pbmc6IGNhbid0IG91dHB1dCB0ZXh0IGJlZm9yZSBkb2N1bWVudCBlbGVtZW50ISAgSWdub3JpbmcuLi4iOwotICB9Ci0KLSAgLyoqIEZpZWxkIEVSX0NBTlRfSEFWRV9NT1JFX1RIQU5fT05FX1JPT1QgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVCA9IDY0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQ0FOVF9IQVZFX01PUkVfVEhBTl9PTkVfUk9PVF1bMV0gPQotICAgICAgIkNhbid0IGhhdmUgbW9yZSB0aGFuIG9uZSByb290IG9uIGEgRE9NISI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfSU5WQUxJRF9VVEYxNl9TVVJST0dBVEUgPSA2NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0lOVkFMSURfVVRGMTZfU1VSUk9HQVRFXVsxXSA9Ci0gICAgICAiSW52YWxpZCBVVEYtMTYgc3Vycm9nYXRlIGRldGVjdGVkOiB7MH0gPyI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfT0lFUlJPUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9PSUVSUk9SID0gNjY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9PSUVSUk9SXVsxXSA9ICJJTyBlcnJvciI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfQ0FOTk9UX0NSRUFURV9VUkwgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ0FOTk9UX0NSRUFURV9VUkwgPSA2NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTk5PVF9DUkVBVEVfVVJMXVsxXSA9ICJDYW5ub3QgY3JlYXRlIHVybCBmb3I6IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgRVJfWFBBVEhfUkVBRE9CSkVDVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9YUEFUSF9SRUFET0JKRUNUID0gNjg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9YUEFUSF9SRUFET0JKRUNUXVsxXSA9ICJJbiBYUGF0aC5yZWFkT2JqZWN0OiB7MH0iOwotICB9Ci0gIAotICAvKiogRmllbGQgRVJfWFBBVEhfUkVBRE9CSkVDVCAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCA9IDY5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EXVsxXSA9Ci0gICAgICAiZnVuY3Rpb24gdG9rZW4gbm90IGZvdW5kLiI7Ci0gIH0KLSAgCi0gICAvKiogIEFyZ3VtZW50ICdsb2NhbE5hbWUnIGlzIG51bGwgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0FSR19MT0NBTE5BTUVfTlVMTCA9IDcwOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQVJHX0xPQ0FMTkFNRV9OVUxMXVsxXSA9Ci0gICAgICAgIkFyZ3VtZW50ICdsb2NhbE5hbWUnIGlzIG51bGwiOwotICB9Ci0gIAotICAgLyoqICBDYW4gbm90IGRlYWwgd2l0aCBYUGF0aCB0eXBlOiAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEUgPSA3MTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0NBTk5PVF9ERUFMX1hQQVRIX1RZUEVdWzFdID0KLSAgICAgICAiQ2FuIG5vdCBkZWFsIHdpdGggWFBhdGggdHlwZTogezB9IjsKLSAgfQotICAKLSAgIC8qKiAgVGhpcyBOb2RlU2V0IGlzIG5vdCBtdXRhYmxlICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OT0RFU0VUX05PVF9NVVRBQkxFID0gNzI7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9OT0RFU0VUX05PVF9NVVRBQkxFXVsxXSA9Ci0gICAgICAgIlRoaXMgTm9kZVNldCBpcyBub3QgbXV0YWJsZSI7Ci0gIH0KLSAgCi0gICAvKiogIFRoaXMgTm9kZVNldERUTSBpcyBub3QgbXV0YWJsZSAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRSA9IDczOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfTk9ERVNFVERUTV9OT1RfTVVUQUJMRV1bMV0gPQotICAgICAgICJUaGlzIE5vZGVTZXREVE0gaXMgbm90IG11dGFibGUiOwotICB9Ci0gIAotICAgLyoqICBWYXJpYWJsZSBub3QgcmVzb2x2YWJsZTogICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9WQVJfTk9UX1JFU09MVkFCTEUgPSA3NDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1ZBUl9OT1RfUkVTT0xWQUJMRV1bMV0gPQotICAgICAgICAiVmFyaWFibGUgbm90IHJlc29sdmFibGU6IHswfSI7Ci0gIH0KLSAgCi0gICAvKiogTnVsbCBlcnJvciBoYW5kbGVyICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9OVUxMX0VSUk9SX0hBTkRMRVIgPSA3NTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX05VTExfRVJST1JfSEFORExFUl1bMV0gPQotICAgICAgICAiTnVsbCBlcnJvciBoYW5kbGVyIjsKLSAgfQotICAKLSAgIC8qKiAgUHJvZ3JhbW1lcidzIGFzc2VydGlvbjogdW5rbm93biBvcGNvZGUgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1BST0dfQVNTRVJUX1VOS05PV05fT1BDT0RFID0gNzY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9QUk9HX0FTU0VSVF9VTktOT1dOX09QQ09ERV1bMV0gPQotICAgICAgICJQcm9ncmFtbWVyJ3MgYXNzZXJ0aW9uOiB1bmtub3duIG9wY29kZTogezB9IjsKLSAgfQotICAKLSAgIC8qKiAgMCBvciAxICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWkVST19PUl9PTkUgPSA3NzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1pFUk9fT1JfT05FXVsxXSA9Ci0gICAgICAgIjAgb3IgMSI7Ci0gIH0KLSAgCi0gICAvKiogIDIgb3IgMyAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1RXT19PUl9USFJFRSA9IDc4OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfVFdPX09SX1RIUkVFXVsxXSA9Ci0gICAgICAgIjAgb3IgMSI7Ci0gIH0KLSAgCi0gIAotICAKLSAgIC8qKiAgcnRmKCkgbm90IHN1cHBvcnRlZCBieSBYUlRyZWVGcmFnU2VsZWN0V3JhcHBlciAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSX1JURl9OT1RfU1VQUE9SVEVEX1hSVFJFRUZSQUdTRUxFQ1RXUkFQUEVSID0gNzg7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9SVEZfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUl1bMV0gPQotICAgICAgICJydGYoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyIjsKLSAgfQotICAKLSAgIC8qKiAgYXNOb2RlSXRlcmF0b3IoKSBub3Qgc3VwcG9ydGVkIGJ5IFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUiA9IDc5OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfQVNOT0RFSVRFUkFUT1JfTk9UX1NVUFBPUlRFRF9YUlRSRUVGUkFHU0VMRUNUV1JBUFBFUl1bMV0gPQotICAgICAgICJhc05vZGVJdGVyYXRvcigpIG5vdCBzdXBwb3J0ZWQgYnkgWFJUcmVlRnJhZ1NlbGVjdFdyYXBwZXIiOwotICB9Ci0gIAotICAgLyoqICBmc2IoKSBub3Qgc3VwcG9ydGVkIGZvciBYU3RyaW5nRm9yQ2hhcnMgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUl9GU0JfTk9UX1NVUFBPUlRFRF9YU1RSSU5HRk9SQ0hBUlMgPSA4MDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX0ZTQl9OT1RfU1VQUE9SVEVEX1hTVFJJTkdGT1JDSEFSU11bMV0gPQotICAgICAgICJmc2IoKSBub3Qgc3VwcG9ydGVkIGZvciBYU3RyaW5nRm9yQ2hhcnMiOwotICB9Ci0gIAotICAgLyoqICBDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfQ09VTERfTk9UX0ZJTkRfVkFSID0gODE7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tFUl9DT1VMRF9OT1RfRklORF9WQVJdWzFdID0KLSAgICAgICJDb3VsZCBub3QgZmluZCB2YXJpYWJsZSB3aXRoIHRoZSBuYW1lIG9mIHswfSI7Ci0gIH0KLSAgCi0gICAvKiogIFhTdHJpbmdGb3JDaGFycyBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50ICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklORyA9IDgyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfWFNUUklOR0ZPUkNIQVJTX0NBTk5PVF9UQUtFX1NUUklOR11bMV0gPQotICAgICAgIlhTdHJpbmdGb3JDaGFycyBjYW4gbm90IHRha2UgYSBzdHJpbmcgZm9yIGFuIGFyZ3VtZW50IjsKLSAgfQotICAKLSAgIC8qKiAgVGhlIEZhc3RTdHJpbmdCdWZmZXIgYXJndW1lbnQgY2FuIG5vdCBiZSBudWxsICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTCA9IDgzOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbRVJfRkFTVFNUUklOR0JVRkZFUl9DQU5OT1RfQkVfTlVMTF1bMV0gPQotICAgICAgIlRoZSBGYXN0U3RyaW5nQnVmZmVyIGFyZ3VtZW50IGNhbiBub3QgYmUgbnVsbCI7Ci0gIH0gIAotICAKLQotCi0gIC8vIFdhcm5pbmdzLi4uCi0KLSAgLyoqIEZpZWxkIFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEID0gMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0xPQ0FMRV9OQU1FX05PVF9IQU5ETEVEICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJsb2NhbGUgbmFtZSBpbiB0aGUgZm9ybWF0LW51bWJlciBmdW5jdGlvbiBub3QgeWV0IGhhbmRsZWQhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBXR19QUk9QRVJUWV9OT1RfU1VQUE9SVEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX1BST1BFUlRZX05PVF9TVVBQT1JURUQgPSAyOwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfUFJPUEVSVFlfTk9UX1NVUFBPUlRFRCArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiWFNMIFByb3BlcnR5IG5vdCBzdXBwb3J0ZWQ6IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgV0dfRE9OVF9ET19BTllUSElOR19XSVRIX05TICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0RPTlRfRE9fQU5ZVEhJTkdfV0lUSF9OUyA9IDM7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19ET05UX0RPX0FOWVRISU5HX1dJVEhfTlMgKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIkRvIG5vdCBjdXJyZW50bHkgZG8gYW55dGhpbmcgd2l0aCBuYW1lc3BhY2UgezB9IGluIHByb3BlcnR5OiB7MX0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIFdHX1NFQ1VSSVRZX0VYQ0VQVElPTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19TRUNVUklUWV9FWENFUFRJT04gPSA0OwotCi0gIHN0YXRpYwotICB7Ci0gICAgY29udGVudHNbV0dfU0VDVVJJVFlfRVhDRVBUSU9OICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJTZWN1cml0eUV4Y2VwdGlvbiB3aGVuIHRyeWluZyB0byBhY2Nlc3MgWFNMIHN5c3RlbSBwcm9wZXJ0eTogezB9IjsKLSAgfQotCi0gIC8qKiBGaWVsZCBXR19RVU9fTk9fTE9OR0VSX0RFRklORUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfUVVPX05PX0xPTkdFUl9ERUZJTkVEID0gNTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX1FVT19OT19MT05HRVJfREVGSU5FRCArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiT2xkIHN5bnRheDogcXVvKC4uLikgaXMgbm8gbG9uZ2VyIGRlZmluZWQgaW4gWFBhdGguIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCA9IDY7Ci0KLSAgc3RhdGljCi0gIHsKLSAgICBjb250ZW50c1tXR19ORUVEX0RFUklWRURfT0JKRUNUX1RPX0lNUExFTUVOVF9OT0RFVEVTVCArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiWFBhdGggbmVlZHMgYSBkZXJpdmVkIG9iamVjdCB0byBpbXBsZW1lbnQgbm9kZVRlc3QhIjsKLSAgfQotCi0gIC8qKiBGaWVsZCBXR19GVU5DVElPTl9UT0tFTl9OT1RfRk9VTkQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfRlVOQ1RJT05fVE9LRU5fTk9UX0ZPVU5EID0gNzsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0ZVTkNUSU9OX1RPS0VOX05PVF9GT1VORCArIE1BWF9DT0RFXVsxXSA9Ci0gICAgICAiZnVuY3Rpb24gdG9rZW4gbm90IGZvdW5kLiI7Ci0gIH0KLQotICAvKiogRmllbGQgV0dfQ09VTEROT1RfRklORF9GVU5DVElPTiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXR19DT1VMRE5PVF9GSU5EX0ZVTkNUSU9OID0gODsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0NPVUxETk9UX0ZJTkRfRlVOQ1RJT04gKyBNQVhfQ09ERV1bMV0gPQotICAgICAgIkNvdWxkIG5vdCBmaW5kIGZ1bmN0aW9uOiB7MH0iOwotICB9Ci0KLSAgLyoqIEZpZWxkIFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdHX0NBTk5PVF9NQUtFX1VSTF9GUk9NID0gOTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0NBTk5PVF9NQUtFX1VSTF9GUk9NICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJDYW4gbm90IG1ha2UgVVJMIGZyb206IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfRVhQQU5EX0VOVElUSUVTX05PVF9TVVBQT1JURUQgPSAxMDsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0VYUEFORF9FTlRJVElFU19OT1RfU1VQUE9SVEVEICsgTUFYX0NPREVdWzFdID0KLSAgICAgICItRSBvcHRpb24gbm90IHN1cHBvcnRlZCBmb3IgRFRNIHBhcnNlciI7Ci0gIH0KLQotICAvKiogRmllbGQgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfSUxMRUdBTF9WQVJJQUJMRV9SRUZFUkVOQ0UgPSAxMTsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW1dHX0lMTEVHQUxfVkFSSUFCTEVfUkVGRVJFTkNFICsgTUFYX0NPREVdWzFdID0KLSAgICAgICJWYXJpYWJsZVJlZmVyZW5jZSBnaXZlbiBmb3IgdmFyaWFibGUgb3V0IG9mIGNvbnRleHQgb3Igd2l0aG91dCBkZWZpbml0aW9uISAgTmFtZSA9IHswfSI7Ci0gIH0KLQotICAvKiogRmllbGQgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgV0dfVU5TVVBQT1JURURfRU5DT0RJTkcgPSAxMjsKLQotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW0VSX1VOU1VQUE9SVEVEX0VOQ09ESU5HXVsxXSA9ICJVbnN1cHBvcnRlZCBlbmNvZGluZzogezB9IjsKLSAgfQotCi0gIC8vIE90aGVyIG1pc2NlbGxhbmVvdXMgdGV4dCB1c2VkIGluc2lkZSB0aGUgY29kZS4uLgotICBzdGF0aWMKLSAgewotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFU11bMF0gPSAidWlfbGFuZ3VhZ2UiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFU11bMV0gPSAiZW4iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDFdWzBdID0gImhlbHBfbGFuZ3VhZ2UiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDFdWzFdID0gImVuIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyXVswXSA9ICJsYW5ndWFnZSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMl1bMV0gPSAiZW4iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDNdWzBdID0gIkJBRF9DT0RFIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAzXVsxXSA9Ci0gICAgICAiUGFyYW1ldGVyIHRvIGNyZWF0ZU1lc3NhZ2Ugd2FzIG91dCBvZiBib3VuZHMiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDRdWzBdID0gIkZPUk1BVF9GQUlMRUQiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDRdWzFdID0KLSAgICAgICJFeGNlcHRpb24gdGhyb3duIGR1cmluZyBtZXNzYWdlRm9ybWF0IGNhbGwiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDVdWzBdID0gInZlcnNpb24iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDVdWzFdID0gIj4+Pj4+Pj4gWGFsYW4gVmVyc2lvbiAiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDZdWzBdID0gInZlcnNpb24yIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA2XVsxXSA9ICI8PDw8PDw8IjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA3XVswXSA9ICJ5ZXMiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDddWzFdID0gInllcyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgOF1bMF0gPSAibGluZSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgOF1bMV0gPSAiTGluZSAjIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyA5XVswXSA9ICJjb2x1bW4iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDldWzFdID0gIkNvbHVtbiAjIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxMF1bMF0gPSAieHNsZG9uZSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTBdWzFdID0gIlhTTFByb2Nlc3NvcjogZG9uZSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTFdWzBdID0gInhwYXRoX29wdGlvbiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTFdWzFdID0gInhwYXRoIG9wdGlvbnM6ICI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTJdWzBdID0gIm9wdGlvbklOIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxMl1bMV0gPSAiICAgWy1pbiBpbnB1dFhNTFVSTF0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDEzXVswXSA9ICJvcHRpb25TZWxlY3QiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDEzXVsxXSA9ICIgICBbLXNlbGVjdCB4cGF0aCBleHByZXNzaW9uXSI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTRdWzBdID0gIm9wdGlvbk1hdGNoIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxNF1bMV0gPQotICAgICAgIiAgIFstbWF0Y2ggbWF0Y2ggcGF0dGVybiAoZm9yIG1hdGNoIGRpYWdub3N0aWNzKV0iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE1XVswXSA9ICJvcHRpb25BbnlFeHByIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxNV1bMV0gPQotICAgICAgIk9yIGp1c3QgYW4geHBhdGggZXhwcmVzc2lvbiB3aWxsIGRvIGEgZGlhZ25vc3RpYyBkdW1wIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxNl1bMF0gPSAibm9QYXJzZXJtc2cxIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAxNl1bMV0gPSAiWFNMIFByb2Nlc3Mgd2FzIG5vdCBzdWNjZXNzZnVsLiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTddWzBdID0gIm5vUGFyc2VybXNnMiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMTddWzFdID0gIioqIENvdWxkIG5vdCBmaW5kIHBhcnNlciAqKiI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMThdWzBdID0gIm5vUGFyc2VybXNnMyI7Ci0gICAgY29udGVudHNbTUFYX01FU1NBR0VTICsgMThdWzFdID0gIlBsZWFzZSBjaGVjayB5b3VyIGNsYXNzcGF0aC4iOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE5XVswXSA9ICJub1BhcnNlcm1zZzQiOwotICAgIGNvbnRlbnRzW01BWF9NRVNTQUdFUyArIDE5XVsxXSA9Ci0gICAgICAiSWYgeW91IGRvbid0IGhhdmUgSUJNJ3MgWE1MIFBhcnNlciBmb3IgSmF2YSwgeW91IGNhbiBkb3dubG9hZCBpdCBmcm9tIjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyMF1bMF0gPSAibm9QYXJzZXJtc2c1IjsKLSAgICBjb250ZW50c1tNQVhfTUVTU0FHRVMgKyAyMF1bMV0gPQotICAgICAgIklCTSdzIEFscGhhV29ya3M6IGh0dHA6Ly93d3cuYWxwaGF3b3Jrcy5pYm0uY29tL2Zvcm11bGEveG1sIjsKLSAgfQotCi0gIC8vID09PT09PT09PT09PT09PT09IElORlJBU1RSVUNUVVJFID09PT09PT09PT09PT09PT09PT09PT0KLQotICAvKiogRmllbGQgQkFEX0NPREUgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQkFEX0NPREUgPSAiQkFEX0NPREUiOwotCi0gIC8qKiBGaWVsZCBGT1JNQVRfRkFJTEVEICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUk1BVF9GQUlMRUQgPSAiRk9STUFUX0ZBSUxFRCI7Ci0KLSAgLyoqIEZpZWxkIEVSUk9SX1JFU09VUkNFUyAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJPUl9SRVNPVVJDRVMgPQotICAgICJvcmcuYXBhY2hlLnhwYXRoLnJlcy5YUEFUSEVycm9yUmVzb3VyY2VzIjsKLQotICAvKiogRmllbGQgRVJST1JfU1RSSU5HICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUk9SX1NUUklORyA9ICIjZXJyb3IiOwotCi0gIC8qKiBGaWVsZCBFUlJPUl9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJST1JfSEVBREVSID0gIkVycm9yOiAiOwotCi0gIC8qKiBGaWVsZCBXQVJOSU5HX0hFQURFUiAgICAgICAgICAqLwotICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBXQVJOSU5HX0hFQURFUiA9ICJXYXJuaW5nOiAiOwotCi0gIC8qKiBGaWVsZCBYU0xfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhTTF9IRUFERVIgPSAiWFNMICI7Ci0KLSAgLyoqIEZpZWxkIFhNTF9IRUFERVIgICAgICAgICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX0hFQURFUiA9ICJYTUwgIjsKLQotICAvKiogRmllbGQgUVVFUllfSEVBREVSICAgICAgICAgICovCi0gIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFFVRVJZX0hFQURFUiA9ICJQQVRURVJOICI7Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICoKLSAgICogQHJldHVybiBUaGUgYXNzb2NpYXRpb24gbGlzdC4KLSAgICovCi0gIHB1YmxpYyBPYmplY3RbXVtdIGdldENvbnRlbnRzKCkKLSAgewotICAgIHJldHVybiBjb250ZW50czsKLSAgfQotCi0gIC8qKgotICAgKiBSZXR1cm4gYSBuYW1lZCBSZXNvdXJjZUJ1bmRsZSBmb3IgYSBwYXJ0aWN1bGFyIGxvY2FsZS4gIFRoaXMgbWV0aG9kIG1pbWljcyB0aGUgYmVoYXZpb3IKLSAgICogb2YgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKCkuCi0gICAqCi0gICAqIEBwYXJhbSByZXMgdGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxvYWQuCi0gICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSB0byBwcmVmZXIgd2hlbiBzZWFyY2hpbmcgZm9yIHRoZSBidW5kbGUKLSAgICoKLSAgICogQHBhcmFtIGNsYXNzTmFtZSBOYW1lIG9mIGxvY2FsLXNwZWNpZmljIHN1YmNsYXNzLgotICAgKiBAcmV0dXJuIHRoZSBSZXNvdXJjZUJ1bmRsZQotICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBmaW5hbCBYUEFUSEVycm9yUmVzb3VyY2VzIGxvYWRSZXNvdXJjZUJ1bmRsZShTdHJpbmcgY2xhc3NOYW1lKQotICAgICAgICAgIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24KLSAgewotCi0gICAgTG9jYWxlIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7Ci0gICAgU3RyaW5nIHN1ZmZpeCA9IGdldFJlc291cmNlU3VmZml4KGxvY2FsZSk7Ci0KLSAgICB0cnkKLSAgICB7Ci0KLSAgICAgIC8vIGZpcnN0IHRyeSB3aXRoIHRoZSBnaXZlbiBsb2NhbGUKLSAgICAgIHJldHVybiAoWFBBVEhFcnJvclJlc291cmNlcykgUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGNsYXNzTmFtZQotICAgICAgICAgICAgICArIHN1ZmZpeCwgbG9jYWxlKTsKLSAgICB9Ci0gICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKQotICAgIHsKLSAgICAgIHRyeSAgLy8gdHJ5IHRvIGZhbGwgYmFjayB0byBlbl9VUyBpZiB3ZSBjYW4ndCBsb2FkCi0gICAgICB7Ci0KLSAgICAgICAgLy8gU2luY2Ugd2UgY2FuJ3QgZmluZCB0aGUgbG9jYWxpemVkIHByb3BlcnR5IGZpbGUsCi0gICAgICAgIC8vIGZhbGwgYmFjayB0byBlbl9VUy4KLSAgICAgICAgcmV0dXJuIChYUEFUSEVycm9yUmVzb3VyY2VzKSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoY2xhc3NOYW1lLAotICAgICAgICAgICAgICAgIG5ldyBMb2NhbGUoImVuIiwgIlVTIikpOwotICAgICAgfQotICAgICAgY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlMikKLSAgICAgIHsKLQotICAgICAgICAvLyBOb3cgd2UgYXJlIHJlYWxseSBpbiB0cm91YmxlLgotICAgICAgICAvLyB2ZXJ5IGJhZCwgZGVmaW5pdGVseSB2ZXJ5IGJhZC4uLm5vdCBnb2luZyB0byBnZXQgdmVyeSBmYXIKLSAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbigKLSAgICAgICAgICAiQ291bGQgbm90IGxvYWQgYW55IHJlc291cmNlIGJ1bmRsZXMuIiwgY2xhc3NOYW1lLCAiIik7Ci0gICAgICB9Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIFJldHVybiB0aGUgcmVzb3VyY2UgZmlsZSBzdWZmaWMgZm9yIHRoZSBpbmRpY2F0ZWQgbG9jYWxlCi0gICAqIEZvciBtb3N0IGxvY2FsZXMsIHRoaXMgd2lsbCBiZSBiYXNlZCB0aGUgbGFuZ3VhZ2UgY29kZS4gIEhvd2V2ZXIKLSAgICogZm9yIENoaW5lc2UsIHdlIGRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gVGFpd2FuIGFuZCBQUkMKLSAgICoKLSAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlCi0gICAqIEByZXR1cm4gYW4gU3RyaW5nIHN1ZmZpeCB3aGljaCBjYW5iZSBhcHBlbmRlZCB0byBhIHJlc291cmNlIG5hbWUKLSAgICovCi0gIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBnZXRSZXNvdXJjZVN1ZmZpeChMb2NhbGUgbG9jYWxlKQotICB7Ci0KLSAgICBTdHJpbmcgc3VmZml4ID0gIl8iICsgbG9jYWxlLmdldExhbmd1YWdlKCk7Ci0gICAgU3RyaW5nIGNvdW50cnkgPSBsb2NhbGUuZ2V0Q291bnRyeSgpOwotCi0gICAgaWYgKGNvdW50cnkuZXF1YWxzKCJUVyIpKQotICAgICAgc3VmZml4ICs9ICJfIiArIGNvdW50cnk7Ci0KLSAgICByZXR1cm4gc3VmZml4OwotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgZXJyb3Igc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgZXJyb3IgY29kZQotICAgKgotICAgKiBAcGFyYW0gZXJyb3JDb2RlIEVycm9yIGNvZGUKLSAgICoKLSAgICogQHJldHVybiBlcnJvciBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBlcnJvciBjb2RlCi0gICAqLwotICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2VLZXkoaW50IGVycm9yQ29kZSkKLSAgewotCi0gICAgaWYgKGVycm9yQ29kZSA+IE1BWF9DT0RFKQotICAgICAgcmV0dXJuIG51bGw7Ci0gICAgZWxzZQotICAgIHsKLSAgICAgIERlY2ltYWxGb3JtYXQgZGYgPSBuZXcgRGVjaW1hbEZvcm1hdCgiMDAwMCIpOwotCi0gICAgICByZXR1cm4gRVJST1JfU1VGRklYICsgZGYuZm9ybWF0KGVycm9yQ29kZSk7Ci0gICAgfQotICB9Ci0KLSAgLyoqCi0gICAqIEdldCB0aGUgd2FybmluZyBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoZSBlcnJvciBjb2RlCi0gICAqCi0gICAqIEBwYXJhbSBlcnJvckNvZGUgRXJyb3IgY29kZQotICAgKiAKLSAgICogQHJldHVybiB3YXJuaW5nIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGVycm9yIGNvZGUKLSAgICovCi0gIHB1YmxpYyBTdHJpbmcgZ2V0V2FybmluZ0tleShpbnQgZXJyb3JDb2RlKQotICB7Ci0KLSAgICBpZiAoZXJyb3JDb2RlID4gTUFYX1dBUk5JTkcpCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICBlbHNlCi0gICAgewotICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwMDAwIik7Ci0KLSAgICAgIHJldHVybiBXQVJOSU5HX1NVRkZJWCArIGRmLmZvcm1hdChlcnJvckNvZGUpOwotICAgIH0KLSAgfQotCi0gIC8qKgotICAgKiBHZXQgdGhlIGtleSBzdHJpbmcgZm9yIGFuIGVycm9yIGJhc2VkIG9uIHRoZSBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gZXJyb3JDb2RlIEVycm9yIGNvZGUKLSAgICogCi0gICAqIEByZXR1cm4ga2V5IHN0cmluZyB0aGF0IG1heSBiZSB1c2VkIGZvciBsb29rdXAgaW4gdGhlIGFzc29jaWF0aW9uIHRhYmxlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0TUtleShpbnQgZXJyb3JDb2RlKQotICB7Ci0KLSAgICBpZiAoZXJyb3JDb2RlID4gTUFYX0NPREUpCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICBlbHNlCi0gICAgewotICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwMDAwIik7Ci0KLSAgICAgIHJldHVybiBFUlJPUl9TVUZGSVggKyBkZi5mb3JtYXQoZXJyb3JDb2RlKTsKLSAgICB9Ci0gIH0KLQotICAvKioKLSAgICogR2V0IHRoZSBrZXkgc3RyaW5nIGZvciBhbiB3YXJuaW5nIGJhc2VkIG9uIHRoZSBpbnRlZ2VyIHJlcHJlc2VudGF0aW9uLgotICAgKgotICAgKiBAcGFyYW0gZXJyb3JDb2RlIEVycm9yIGNvZGUKLSAgICogCi0gICAqIEByZXR1cm4ga2V5IHN0cmluZyB0aGF0IG1heSBiZSB1c2VkIGZvciBsb29rdXAgaW4gdGhlIGFzc29jaWF0aW9uIHRhYmxlLgotICAgKi8KLSAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0V0tleShpbnQgZXJyb3JDb2RlKQotICB7Ci0KLSAgICBpZiAoZXJyb3JDb2RlID4gTUFYX1dBUk5JTkcpCi0gICAgICByZXR1cm4gbnVsbDsKLSAgICBlbHNlCi0gICAgewotICAgICAgRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwMDAwIik7Ci0KLSAgICAgIHJldHVybiBXQVJOSU5HX1NVRkZJWCArIGRmLmZvcm1hdChlcnJvckNvZGUpOwotICAgIH0KLSAgfQotfQpkaWZmIC0tZ2l0IGEvc3JjL29yZy9hcGFjaGUveHBhdGgvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZW4uamF2YSBiL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9YUEFUSEVycm9yUmVzb3VyY2VzX2VuLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMzODMwNzcuLjAwMDAwMDAKLS0tIGEvc3JjL29yZy9hcGFjaGUveHBhdGgvcmVzL1hQQVRIRXJyb3JSZXNvdXJjZXNfZW4uamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDY4ICswLDAgQEAKLS8qCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUueHBhdGgucmVzOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci0KLS8qKgotICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImFkdmFuY2VkIi8+Ci0gKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIFhQQVRIRXJyb3JSZXNvdXJjZXMuICBUaGlzIGlzIGp1c3QKLSAqIGFuIGVtcHR5IGNsYXNzLgotICovCi1wdWJsaWMgY2xhc3MgWFBBVEhFcnJvclJlc291cmNlc19lbiBleHRlbmRzIFhQQVRIRXJyb3JSZXNvdXJjZXMKLXsKLX0KZGlmZiAtLWdpdCBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9wYWNrYWdlLmh0bWwgYi9zcmMvb3JnL2FwYWNoZS94cGF0aC9yZXMvcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMWI0NzMyLi4wMDAwMDAwCi0tLSBhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3Jlcy9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSw4ICswLDAgQEAKLTxodG1sPgotICA8dGl0bGU+WFBhdGggcmVzb3VyY2VzLjwvdGl0bGU+Ci0gIDxib2R5PgotICAgIDxwPkNvbnRhaW5zIHN0cmluZ3MgZm9yIFhQYXRoIHN1cHBvcnQgdGhhdCByZXF1aXJlIGludGVybmF0aW9uYWxpemF0aW9uLjxwPgotIDwvYm9keT4KLTwvaHRtbD4KLQotCmRpZmYgLS1naXQgYS9zcmMvdHJheC90cmF4LnByb3BlcnRpZXMgYi9zcmMvdHJheC90cmF4LnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGU1OTNjMzkuLjAwMDAwMDAKLS0tIGEvc3JjL3RyYXgvdHJheC5wcm9wZXJ0aWVzCisrKyAvZGV2L251bGwKQEAgLTEsMTEgKzAsMCBAQAotIyAkUmV2aXNpb24kICREYXRlJAotIwotIyBOb3RlOiBUaGlzIHByb3BlcnRpZXMgZmlsZSBpcyBwcm92aWRlZCBmb3IgaWxsdXN0cmF0aXZlIHB1cnBvc2VzCi0jICAgICAgIG9ubHkgYW5kIGlzIG5vdCBwYXJ0IG9mIHRoZSBpbnRlcmZhY2UgZGVmaW5pdGlvbi4KLSMgICAgICAgVGhpcyBwcm9wZXJ0aWVzIGZpbGUgaXMgbG9jYXRlZCBpbiB0aGUgaW1wbGVtZW50YXRpb24gSkFSCi0jICAgICAgIGFuZCBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zIHdpbGwgc3BlY2lmeSBkaWZmZXJlbnQKLSMgICAgICAgaW1wbGVtZW50YXRpb24gY2xhc3NlcyBhbmQgb3V0cHV0IG1ldGhvZHMuCi0jCi0KLSMgVGhlIFRSYVggU3R5bGVzaGVldCBwcm9jZXNzb3IKLXRyYXgucHJvY2Vzc29yLnhzbHQ9b3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuU3R5bGVzaGVldFByb2Nlc3NvcgpkaWZmIC0tZ2l0IGEvc3JjL3hhbGFuajIuamluIGIvc3JjL3hhbGFuajIuamluCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MWI4NGI2Li4wMDAwMDAwCi0tLSBhL3NyYy94YWxhbmoyLmppbgorKysgL2Rldi9udWxsCkBAIC0xLDM4MCArMCwwIEBACi0jIyMKLSMjIyBKaW5kZW50IDMuMjMgcHJvcGVydHkgZmlsZSAtLSBodHRwOi8vd3d3LmppbmRlbnQuZGUKLSMjIwotCi0KLQotCi0jIyMgR2VuZXJhbCAtLSBDb252ZW50aW9uCi0KLWNvbnZlbnRpb25OYW1lICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gInhhbGFuajIiCi1jb252ZW50aW9uU3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgICA9ICInRm9ybWF0dGVkIGluICRjb252ZW50aW9uTmFtZSQgU3R5bGUgb24nIEVFRSwgTU1NIGQsICcneXkiCi1jb252ZW50aW9uTm90ZVBvc2l0aW9uICAgICAgICAgICAgICAgICAgICA9ICJub25lIgotYmxhbmtMaW5lc1RvU2VwYXJhdGVDb252ZW50aW9uTm90ZSAgICAgICAgPSAyCi0KLQotIyMjIEdlbmVyYWwgLS0gSmluZGVudCBOb3RlCi0KLWppbmRlbnROb3RlUG9zaXRpb24gICAgICAgICAgICAgICAgICAgICAgID0gIm5vbmUiCi1ibGFua0xpbmVzVG9TZXBhcmF0ZUppbmRlbnROb3RlICAgICAgICAgICA9IDIKLQotCi0KLSMjIyBIZWFkZXIvRm9vdGVyIC0tIEhlYWRlciBUZW1wbGF0ZQotCi1oZWFkZXJTbWFydE1vZGUgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGluZmluaXRlCi0KLWhlYWRlcklkZW50aWZ5S2V5ICAgICAgICAgICAgICAgICAgICAgICAgID0gIlRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEiCi0KLWJsYW5rTGluZXNCZWZvcmVIZWFkZXIgICAgICAgICAgICAgICAgICAgID0gMAotaGVhZGVyWzAwXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiLyoiCi1oZWFkZXJbMDFdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xIgotaGVhZGVyWzAyXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICoiCi1oZWFkZXJbMDNdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWhlYWRlclswNF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzICIKLWhlYWRlclswNV0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIHJlc2VydmVkLiIKLWhlYWRlclswNl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIgotaGVhZGVyWzA3XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IgotaGVhZGVyWzA4XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIgotaGVhZGVyWzA5XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogYXJlIG1ldDoiCi1oZWFkZXJbMTBdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWhlYWRlclsxMV0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IgotaGVhZGVyWzEyXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAiCi1oZWFkZXJbMTNdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWhlYWRlclsxNF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IgotaGVhZGVyWzE1XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIgotaGVhZGVyWzE2XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSIKLWhlYWRlclsxN10gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqICAgIGRpc3RyaWJ1dGlvbi4iCi1oZWFkZXJbMThdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWhlYWRlclsxOV0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLCIKLWhlYWRlclsyMF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAiCi1oZWFkZXJbMjFdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUiCi1oZWFkZXJbMjJdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIiCi1oZWFkZXJbMjNdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsIgotaGVhZGVyWzI0XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4iCi1oZWFkZXJbMjVdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWhlYWRlclsyNl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QiCi1oZWFkZXJbMjddICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMiCi1oZWFkZXJbMjhdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gIgotaGVhZGVyWzI5XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuIgotaGVhZGVyWzMwXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICoiCi1oZWFkZXJbMzFdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwiCi1oZWFkZXJbMzJdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4iCi1oZWFkZXJbMzNdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4iCi1oZWFkZXJbMzRdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWhlYWRlclszNV0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQiCi1oZWFkZXJbMzZdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyIKLWhlYWRlclszN10gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIgotaGVhZGVyWzM4XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUiIKLWhlYWRlclszOV0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwiCi1oZWFkZXJbNDBdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIgotaGVhZGVyWzQxXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiIKLWhlYWRlcls0Ml0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQiCi1oZWFkZXJbNDNdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwiCi1oZWFkZXJbNDRdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQiCi1oZWFkZXJbNDVdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YiCi1oZWFkZXJbNDZdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBTVUNIIERBTUFHRS4iCi1oZWFkZXJbNDddICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIKLWhlYWRlcls0OF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiAqIgotaGVhZGVyWzQ5XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkiCi1oZWFkZXJbNTBdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMiCi1oZWFkZXJbNTFdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMiCi1oZWFkZXJbNTJdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUiCi1oZWFkZXJbNTNdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUiCi1oZWFkZXJbNTRdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uIgotaGVhZGVyWzU1XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICovIgotYmxhbmtMaW5lc0FmdGVySGVhZGVyICAgICAgICAgICAgICAgICAgICAgPSAwCi0KLQotIyMjIEhlYWRlci9Gb290ZXIgLS0gRm9vdGVyIFRlbXBsYXRlCi0KLWZvb3RlclNtYXJ0TW9kZSAgICAgICAgICAgICAgICAgICAgICAgICAgID0gaW5maW5pdGUKLQotZm9vdGVySWRlbnRpZnlLZXkgICAgICAgICAgICAgICAgICAgICAgICAgPSAiIgotCi1ibGFua0xpbmVzQmVmb3JlRm9vdGVyICAgICAgICAgICAgICAgICAgICA9IDAKLWZvb3RlclswMF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gIiIKLWJsYW5rTGluZXNBZnRlckZvb3RlciAgICAgICAgICAgICAgICAgICAgID0gMAotCi0KLQotIyMjIEluZGVudGF0aW9uIC0tIE1pc2MKLQotdGFidWxhdG9yU2l6ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAyCi1pbmRlbnRTaXplICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDIKLWZpcnN0TGV2ZWxJbmRlbnQgICAgICAgICAgICAgICAgICAgICAgICAgID0gMAotaW5kZW50Q2FzZUZyb21Td2l0Y2ggICAgICAgICAgICAgICAgICAgICAgPSBmYWxzZQotbGFiZWxOZXdMaW5lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSB0cnVlCi1pbmRlbnRMYWJlbHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHRydWUKLQotbWluaW11bUNvbW1lbnRJbmRlbnQgICAgICAgICAgICAgICAgICAgICAgPSAyCi0KLWluZGVudExlYWRpbmdzQnlUYWJzICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWluZGVudENvbW1lbnRzQnlUYWJzICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWluZGVudERlY2xhcmF0aW9uc0J5VGFicyAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWluZGVudEFzc2lnbm1lbnRzQnlUYWJzICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLQotCi0jIyMgSW5kZW50YXRpb24gLS0gQWxpZ25tZW50Ci0KLWFsaWduQ29tbWVudHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsaWduRGVjbGFyYXRpb25zICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsaWduQXNzaWdubWVudHMgICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsaWduVGVybmFyeUNvbmRpdGlvbnMgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsaWduVGVybmFyeUV4cHJlc3Npb25zICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsaWduVG9vTG9uZ0NvbW1lbnRzICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLQotCi0KLSMjIyBCcmFjZXMgLS0gU3R5bGUKLQotbGVmdEJyYWNlTmV3TGluZUdlbmVyYWwgICAgICAgICAgICAgICAgICAgPSB0cnVlCi1yaWdodEJyYWNlTmV3TGluZUdlbmVyYWwgICAgICAgICAgICAgICAgICA9IHRydWUKLWluZGVudExlZnRCcmFjZUdlbmVyYWwgICAgICAgICAgICAgICAgICAgID0gMAotaW5kZW50UmlnaHRCcmFjZUdlbmVyYWwgICAgICAgICAgICAgICAgICAgPSAwCi1pbmRlbnRBZnRlclJpZ2h0QnJhY2VHZW5lcmFsICAgICAgICAgICAgICA9IDAKLQotY3VkZGxlRW1wdHlCcmFjZXNHZW5lcmFsICAgICAgICAgICAgICAgICAgPSB0cnVlCi1pbmRlbnRDdWRkbGVkQnJhY2VzR2VuZXJhbCAgICAgICAgICAgICAgICA9IDAKLQotCi1sZWZ0QnJhY2VOZXdMaW5lQ2xhc3NJbnRlcmZhY2UgICAgICAgICAgICA9IHRydWUKLXJpZ2h0QnJhY2VOZXdMaW5lQ2xhc3NJbnRlcmZhY2UgICAgICAgICAgID0gdHJ1ZQotaW5kZW50TGVmdEJyYWNlQ2xhc3NJbnRlcmZhY2UgICAgICAgICAgICAgPSAwCi1pbmRlbnRSaWdodEJyYWNlQ2xhc3NJbnRlcmZhY2UgICAgICAgICAgICA9IDAKLWluZGVudEFmdGVyUmlnaHRCcmFjZUNsYXNzSW50ZXJmYWNlICAgICAgID0gMAotCi1jdWRkbGVFbXB0eUJyYWNlc0NsYXNzSW50ZXJmYWNlICAgICAgICAgICA9IGZhbHNlCi1pbmRlbnRDdWRkbGVkQnJhY2VzQ2xhc3NJbnRlcmZhY2UgICAgICAgICA9IDEKLQotCi1sZWZ0QnJhY2VOZXdMaW5lTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IHRydWUKLXJpZ2h0QnJhY2VOZXdMaW5lTWV0aG9kICAgICAgICAgICAgICAgICAgID0gdHJ1ZQotaW5kZW50TGVmdEJyYWNlTWV0aG9kICAgICAgICAgICAgICAgICAgICAgPSAwCi1pbmRlbnRSaWdodEJyYWNlTWV0aG9kICAgICAgICAgICAgICAgICAgICA9IDAKLWluZGVudEFmdGVyUmlnaHRCcmFjZU1ldGhvZCAgICAgICAgICAgICAgID0gMAotCi1jdWRkbGVFbXB0eUJyYWNlc01ldGhvZCAgICAgICAgICAgICAgICAgICA9IHRydWUKLWluZGVudEN1ZGRsZWRCcmFjZXNNZXRob2QgICAgICAgICAgICAgICAgID0gMAotCi0KLWxlZnRCcmFjZU5ld0xpbmVUcnlDYXRjaCAgICAgICAgICAgICAgICAgID0gdHJ1ZQotcmlnaHRCcmFjZU5ld0xpbmVUcnlDYXRjaCAgICAgICAgICAgICAgICAgPSB0cnVlCi1pbmRlbnRMZWZ0QnJhY2VUcnlDYXRjaCAgICAgICAgICAgICAgICAgICA9IDAKLWluZGVudFJpZ2h0QnJhY2VUcnlDYXRjaCAgICAgICAgICAgICAgICAgID0gMAotaW5kZW50QWZ0ZXJSaWdodEJyYWNlVHJ5Q2F0Y2ggICAgICAgICAgICAgPSAwCi0KLWN1ZGRsZUVtcHR5QnJhY2VzVHJ5Q2F0Y2ggICAgICAgICAgICAgICAgID0gdHJ1ZQotaW5kZW50Q3VkZGxlZEJyYWNlc1RyeUNhdGNoICAgICAgICAgICAgICAgPSAwCi0KLQotIyMjIEJyYWNlcyAtLSBJbnNlcnQgQXQKLQotaW5zZXJ0QnJhY2VzQXRJZkVsc2UgICAgICAgICAgICAgICAgICAgICAgPSBmYWxzZQotaW5zZXJ0QnJhY2VzQXRGb3IgICAgICAgICAgICAgICAgICAgICAgICAgPSB0cnVlCi1pbnNlcnRCcmFjZXNBdFdoaWxlICAgICAgICAgICAgICAgICAgICAgICA9IHRydWUKLWluc2VydEJyYWNlc0F0RG9XaGlsZSAgICAgICAgICAgICAgICAgICAgID0gdHJ1ZQotCi1pbnNlcnRQYXJlbnRoZXNpc0F0Q29uZGl0aW9ucyAgICAgICAgICAgICA9IGZhbHNlCi0KLQotIyMjIEJyYWNlcyAtLSBJZi1FbHNlCi0KLXNpbmdsZUlmU3RhdGVtZW50SW5PbmVMaW5lICAgICAgICAgICAgICAgID0gZmFsc2UKLXNpbmdsZUVsc2VTdGF0ZW1lbnRJbk9uZUxpbmUgICAgICAgICAgICAgID0gZmFsc2UKLXNwZWNpYWxFbHNlSWZUcmVhdG1lbnQgICAgICAgICAgICAgICAgICAgID0gdHJ1ZQotCi0KLQotIyMjIEphdmFEb2MgLS0gTWlzYwotCi1kZWxldGVKYXZhRG9jQ29tbWVudHMgICAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1mb3JtYXRKYXZhRG9jQ29tbWVudHMgICAgICAgICAgICAgICAgICAgICA9IHRydWUKLQotaW5zZXJ0TWlzc2luZ0phdmFEb2NUYWdzICAgICAgICAgICAgICAgICAgPSB0cnVlCi1kZWxldGVPYnNvbGV0ZUphdmFEb2NUYWdzICAgICAgICAgICAgICAgICA9IGZhbHNlCi0KLWNyZWF0ZVB1YmxpY0NsYXNzSW50ZXJmYWNlSmF2YURvY3MgICAgICAgID0gdHJ1ZQotY3JlYXRlRnJpZW5kbHlDbGFzc0ludGVyZmFjZUphdmFEb2NzICAgICAgPSB0cnVlCi1jcmVhdGVQcml2YXRlQ2xhc3NJbnRlcmZhY2VKYXZhRG9jcyAgICAgICA9IHRydWUKLWNyZWF0ZVByb3RlY3RlZENsYXNzSW50ZXJmYWNlSmF2YURvY3MgICAgID0gdHJ1ZQotCi1jcmVhdGVQdWJsaWNNZXRob2RKYXZhRG9jcyAgICAgICAgICAgICAgICA9IHRydWUKLWNyZWF0ZUZyaWVuZGx5TWV0aG9kSmF2YURvY3MgICAgICAgICAgICAgID0gdHJ1ZQotY3JlYXRlUHJpdmF0ZU1ldGhvZEphdmFEb2NzICAgICAgICAgICAgICAgPSB0cnVlCi1jcmVhdGVQcm90ZWN0ZWRNZXRob2RKYXZhRG9jcyAgICAgICAgICAgICA9IHRydWUKLQotY3JlYXRlUHVibGljRmllbGRKYXZhRG9jcyAgICAgICAgICAgICAgICAgPSB0cnVlCi1jcmVhdGVGcmllbmRseUZpZWxkSmF2YURvY3MgICAgICAgICAgICAgICA9IHRydWUKLWNyZWF0ZVByaXZhdGVGaWVsZEphdmFEb2NzICAgICAgICAgICAgICAgID0gdHJ1ZQotY3JlYXRlUHJvdGVjdGVkRmllbGRKYXZhRG9jcyAgICAgICAgICAgICAgPSB0cnVlCi0KLQotIyMjIEphdmFEb2MgLS0gVGVtcGxhdGVzCi0KLXNvcnRFeGNlcHRpb25zSW5UZW1wbGF0ZXMgICAgICAgICAgICAgICAgID0gdHJ1ZQotCi1qYXZhRG9jTWV0aG9kVG9wWzAwXSAgICAgICAgICAgICAgICAgICAgICA9ICIvKioiCi1qYXZhRG9jTWV0aG9kVG9wWzAxXSAgICAgICAgICAgICAgICAgICAgICA9ICIgKiBORUVEU0RPQyBNZXRob2QgJG9iamVjdE5hbWUkICIKLWphdmFEb2NNZXRob2RUb3BbMDJdICAgICAgICAgICAgICAgICAgICAgID0gIiAqIgotamF2YURvY01ldGhvZFBhcmFtU2VwYXJhdG9yWzAwXSAgICAgICAgICAgPSAiICoiCi1qYXZhRG9jTWV0aG9kUGFyYW1bMDBdICAgICAgICAgICAgICAgICAgICA9ICIgKiBORUVEU0RPQyBAcGFyYW0gJHBhcmFtTmFtZSQiCi1qYXZhRG9jTWV0aG9kUmV0dXJuWzAwXSAgICAgICAgICAgICAgICAgICA9ICIgKiIKLWphdmFEb2NNZXRob2RSZXR1cm5bMDFdICAgICAgICAgICAgICAgICAgID0gIiAqIE5FRURTRE9DICgkb2JqZWN0TmFtZSQpIEByZXR1cm4iCi1qYXZhRG9jTWV0aG9kRXhjZXB0aW9uU2VwYXJhdG9yWzAwXSAgICAgICA9ICIgKiIKLWphdmFEb2NNZXRob2RFeGNlcHRpb25bMDBdICAgICAgICAgICAgICAgID0gIiAqIEB0aHJvd3MgJGV4Y2VwdGlvbk5hbWUkIgotamF2YURvY01ldGhvZEJvdHRvbVswMF0gICAgICAgICAgICAgICAgICAgPSAiICovIgotCi1qYXZhRG9jQ29uc3RydWN0b3JUb3BbMDBdICAgICAgICAgICAgICAgICA9ICIvKioiCi1qYXZhRG9jQ29uc3RydWN0b3JUb3BbMDFdICAgICAgICAgICAgICAgICA9ICIgKiBDb25zdHJ1Y3RvciAkb2JqZWN0TmFtZSQiCi1qYXZhRG9jQ29uc3RydWN0b3JUb3BbMDJdICAgICAgICAgICAgICAgICA9ICIgKiIKLWphdmFEb2NDb25zdHJ1Y3RvclBhcmFtU2VwYXJhdG9yWzAwXSAgICAgID0gIiAqIgotamF2YURvY0NvbnN0cnVjdG9yUGFyYW1bMDBdICAgICAgICAgICAgICAgPSAiICogTkVFRFNET0MgQHBhcmFtICRwYXJhbU5hbWUkIgotamF2YURvY0NvbnN0cnVjdG9yRXhjZXB0aW9uU2VwYXJhdG9yWzAwXSAgPSAiICoiCi1qYXZhRG9jQ29uc3RydWN0b3JFeGNlcHRpb25bMDBdICAgICAgICAgICA9ICIgKiBAdGhyb3dzICRleGNlcHRpb25OYW1lJCIKLWphdmFEb2NDb25zdHJ1Y3RvckJvdHRvbVswMF0gICAgICAgICAgICAgID0gIiAqLyIKLQotamF2YURvY0NsYXNzWzAwXSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiLyoqIgotamF2YURvY0NsYXNzWzAxXSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogPG1ldGEgbmFtZT0idXNhZ2UiIGNvbnRlbnQ9ImludGVybmFsIi8+IgotamF2YURvY0NsYXNzWzAyXSAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiICogTkVFRFNET0MgQ2xhc3MgJG9iamVjdE5hbWUkIDxuZWVkcy1jb21tZW50Lz4iCi1qYXZhRG9jQ2xhc3NbMDNdICAgICAgICAgICAgICAgICAgICAgICAgICA9ICIgKi8iCi0KLWphdmFEb2NJbnRlcmZhY2VbMDBdICAgICAgICAgICAgICAgICAgICAgID0gIi8qKiIKLWphdmFEb2NJbnRlcmZhY2VbMDFdICAgICAgICAgICAgICAgICAgICAgID0gIiAqIDxtZXRhIG5hbWU9InVzYWdlIiBjb250ZW50PSJpbnRlcm5hbCIvPiIKLWphdmFEb2NJbnRlcmZhY2VbMDJdICAgICAgICAgICAgICAgICAgICAgID0gIiAqIE5FRURTRE9DIEludGVyZmFjZSAkb2JqZWN0TmFtZSQiCi1qYXZhRG9jSW50ZXJmYWNlWzAzXSAgICAgICAgICAgICAgICAgICAgICA9ICIgKi8iCi0KLWphdmFEb2NGaWVsZFswMF0gICAgICAgICAgICAgICAgICAgICAgICAgID0gIi8qKiBORUVEU0RPQyBGaWVsZCAkb2JqZWN0TmFtZSQgICAgICAgICAgKi8iCi0KLQotCi0jIyMgQ29tbWVudHMgLS0gRm9ybWF0L0RlbGV0ZQotCi1kZWxldGVCbG9ja0NvbW1lbnRzICAgICAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1kZWxldGVTaW5nbGVMaW5lQ29tbWVudHMgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1kZWxldGVUcmFpbGluZ0NvbW1lbnRzICAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1kZWxldGVFbmRPZkxpbmVDb21tZW50cyAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi0KLWZvcm1hdEJsb2NrQ29tbWVudHMgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWZvcm1hdFNpbmdsZUxpbmVDb21tZW50cyAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWZvcm1hdFRyYWlsaW5nQ29tbWVudHMgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWZvcm1hdEVuZE9mTGluZUNvbW1lbnRzICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLQotCi0jIyMgQ29tbWVudHMgLS0gRXhjZXB0aW9ucwotCi1uZXZlckluZGVudEZpcnN0Q29sdW1uQ29tbWVudHMgICAgICAgICAgICA9IGZhbHNlCi1uZXZlckZvcm1hdEZpcnN0Q29sdW1uQ29tbWVudHMgICAgICAgICAgICA9IGZhbHNlCi0KLW5ldmVyRm9ybWF0SGVhZGVyICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLW5ldmVyRm9ybWF0Rm9vdGVyICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLQotCi0KLSMjIyBTZXBhcmF0aW9uIC0tIE1pc2MKLQota2VlcEJsYW5rTGluZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAwCi0KLW1pbkxpbmVzVG9JbnNlcnRCbGFua0xpbmVJbkNsYXNzZXMgICAgICAgID0gMwotbWluTGluZXNUb0luc2VydEJsYW5rTGluZUluTWV0aG9kcyAgICAgICAgPSAzCi0KLQotIyMjIFNlcGFyYXRpb24gLS0gU2VwYXJhdGUKLQotc2VwYXJhdGVDaHVua3NCeUNvbW1lbnRzICAgICAgICAgICAgICAgICAgPSB0cnVlCi1hbGxvd0JyZWFrU2VwYXJhdGVkRnJvbUNhc2VCbG9jayAgICAgICAgICA9IGZhbHNlCi1ibGFua0xpbmVzQmV0d2VlbkNhc2VCbG9ja3MgICAgICAgICAgICAgICA9IDAKLWJsYW5rTGluZXNCZXR3ZWVuQ2h1bmtzICAgICAgICAgICAgICAgICAgID0gMQotCi1jb21wYXJhYmxlSW1wb3J0RGVwdGggICAgICAgICAgICAgICAgICAgICA9IDIKLWJsYW5rTGluZXNUb1NlcGFyYXRlSW1wb3J0cyAgICAgICAgICAgICAgID0gMQotCi1ibGFua0xpbmVzQmV0d2VlbkNsYXNzSW50ZXJmYWNlICAgICAgICAgICA9IDAKLQotCi0jIyMgU2VwYXJhdGlvbiAtLSBJbnNlcnQgQmxhbmsgTGluZXMKLQotYmxhbmtMaW5lc0FmdGVyRGVjbGFyYXRpb25zICAgICAgICAgICAgICAgPSAxCi1ibGFua0xpbmVzQWZ0ZXJNZXRob2RzICAgICAgICAgICAgICAgICAgICA9IDEKLWJsYW5rTGluZXNBZnRlckNsYXNzZXMgICAgICAgICAgICAgICAgICAgID0gMAotYmxhbmtMaW5lc0FmdGVySW50ZXJmYWNlcyAgICAgICAgICAgICAgICAgPSAwCi0KLWJsYW5rTGluZXNCZWZvcmVKYXZhRG9jQ29tbWVudHMgICAgICAgICAgID0gMQotYmxhbmtMaW5lc0FmdGVySmF2YURvY0NvbW1lbnRzICAgICAgICAgICAgPSAwCi0KLWJsYW5rTGluZXNCZWZvcmVCbG9ja0NvbW1lbnRzICAgICAgICAgICAgID0gMQotYmxhbmtMaW5lc0FmdGVyQmxvY2tDb21tZW50cyAgICAgICAgICAgICAgPSAwCi0KLWJsYW5rTGluZXNCZWZvcmVTaW5nbGVMaW5lQ29tbWVudHMgICAgICAgID0gMQotYmxhbmtMaW5lc0FmdGVyU2luZ2xlTGluZUNvbW1lbnRzICAgICAgICAgPSAwCi0KLWJsYW5rTGluZXNCZWZvcmVFbmRPZkxpbmVDb21tZW50cyAgICAgICAgID0gMQotYmxhbmtMaW5lc0FmdGVyRW5kT2ZMaW5lQ29tbWVudHMgICAgICAgICAgPSAwCi0KLWJsYW5rTGluZXNBZnRlclN3aXRjaCAgICAgICAgICAgICAgICAgICAgID0gMAotYmxhbmtMaW5lc0FmdGVyUGFja2FnZSAgICAgICAgICAgICAgICAgICAgPSAxCi1ibGFua0xpbmVzQWZ0ZXJMYXN0SW1wb3J0ICAgICAgICAgICAgICAgICA9IDEKLQotCi0KLSMjIyBXaGl0ZXNwYWNlcyAtLSBQYWRkaW5nCi0KLXNlcGFyYXRlQXNzaWdubWVudE9wZXJhdG9ycyAgICAgICAgICAgICAgID0gdHJ1ZQotc2VwYXJhdGVDb25kaXRpb25hbE9wZXJhdG9ycyAgICAgICAgICAgICAgPSB0cnVlCi1zZXBhcmF0ZUNvbXBhcmlzb25PcGVyYXRvcnMgICAgICAgICAgICAgICA9IHRydWUKLXNlcGFyYXRlTnVtZXJpY2FsT3BlcmF0b3JzICAgICAgICAgICAgICAgID0gdHJ1ZQotCi1wYWRkaW5nQ2FzdFBhcmVudGhlc2lzICAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1wYWRkaW5nUGFyZW50aGVzaXMgICAgICAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1wYWRkaW5nQnJhY2tldHMgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGZhbHNlCi1wYWRkaW5nQnJhY2VzICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHRydWUKLQotCi0jIyMgV2hpdGVzcGFjZXMgLS0gU3BhY2UgQmVmb3JlCi0KLXNwYWNlQmVmb3JlTWV0aG9kRGVjbGFyYXRpb25QYXJlbnRoZXNpcyAgID0gZmFsc2UKLXNwYWNlQmVmb3JlTWV0aG9kQ2FsbFBhcmVudGhlc2lzICAgICAgICAgID0gZmFsc2UKLXNwYWNlQmVmb3JlQnJhY2tldHMgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLXNwYWNlQmVmb3JlQnJhY2tldHNJblR5cGVzICAgICAgICAgICAgICAgID0gZmFsc2UKLXNwYWNlQmVmb3JlU3RhdGVtZW50UGFyZW50aGVzaXMgICAgICAgICAgID0gdHJ1ZQotc3BhY2VCZWZvcmVDb25kaXRpb25CYW5nICAgICAgICAgICAgICAgICAgPSBmYWxzZQotc3BhY2VCZWZvcmVDYXNlQ29sb24gICAgICAgICAgICAgICAgICAgICAgPSB0cnVlCi0KLQotIyMjIFdoaXRlc3BhY2VzIC0tIFNwYWNlIEFmdGVyCi0KLXNwYWNlQWZ0ZXJDb21tYSAgICAgICAgICAgICAgICAgICAgICAgICAgID0gdHJ1ZQotc3BhY2VBZnRlclNlbWljb2xvbiAgICAgICAgICAgICAgICAgICAgICAgPSB0cnVlCi1zcGFjZUFmdGVyQ2FzdGluZyAgICAgICAgICAgICAgICAgICAgICAgICA9IHRydWUKLQotCi0jIyMgV2hpdGVzcGFjZXMgLS0gTm8gU3BhY2VzCi0KLW5vU3BhY2VzSW5FbXB0eUZvckV4cHJlc3Npb25zICAgICAgICAgICAgID0gdHJ1ZQotCi0KLQotIyMjIExpbmUgV3JhcHBpbmcgLS0gTWlzYwotCi1tYXhGaWVsZEVsZW1lbnRzUGVyTGluZSAgICAgICAgICAgICAgICAgICA9IGluZmluaXRlCi0KLXdyYXBMaW5lcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gdHJ1ZQotd3JhcEJlY2F1c2VPZkNvbW1lbnRzICAgICAgICAgICAgICAgICAgICAgPSBmYWxzZQotd3JhcExvbmdNZXRob2ROYW1lcyAgICAgICAgICAgICAgICAgICAgICAgPSBmYWxzZQotbWF4TGluZUxlbmd0aCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA3OAotZGVlcEluZGVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA0NQotZm9yY2VJbmRlbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA4Ci1mb3JjZUluZGVudFRvbGVyYW5jZSAgICAgICAgICAgICAgICAgICAgICA9IDQKLQotYWxsb3dXcmFwcGluZ0FmdGVyQXNzaWdubWVudHMgICAgICAgICAgICAgPSB0cnVlCi1hbGxvd1dyYXBwaW5nQWZ0ZXJQYXJlbnRoZXNpcyAgICAgICAgICAgICA9IHRydWUKLXByZWZlcldyYXBwaW5nQWZ0ZXJUaHJvd3MgICAgICAgICAgICAgICAgID0gdHJ1ZQotCi0KLWFsd2F5c1dyYXBUaHJvd3MgICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsd2F5c1dyYXBFeHRlbmRzICAgICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLWFsd2F5c1dyYXBJbXBsZW1lbnRzICAgICAgICAgICAgICAgICAgICAgID0gZmFsc2UKLQotaW5kZW50V3JhcHBlZFRocm93cyAgICAgICAgICAgICAgICAgICAgICAgPSAwCi1pbmRlbnRXcmFwcGVkRXh0ZW5kcyAgICAgICAgICAgICAgICAgICAgICA9IDAKLWluZGVudFdyYXBwZWRJbXBsZW1lbnRzICAgICAgICAgICAgICAgICAgID0gMApkaWZmIC0tZ2l0IGEvdG9kby54bWwgYi90b2RvLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTFlY2JiYS4uMDAwMDAwMAotLS0gYS90b2RvLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDQwOCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLQotPHRvZG8gdGl0bGU9IlRoaW5ncyBUbyBEbyIgcHJvamVjdD0iWGFsYW4tSmF2YSIgbWFqb3ItdmVyc2lvbj0iMiI+Ci0KLSA8ZGV2cz4KLSAgPCEtLSBpbiBhbHBoYWJldGljYWwgb3JkZXIsIGJ5IGxhc3QgbmFtZSAtLT4KLSAgPHBlcnNvbiBuYW1lPSJTY290dCBCb2FnIiBlbWFpbD0ic2NvdHRfYm9hZ0Bsb3R1cy5jb20iIGlkPSJTQiIgZXhwZXJ0aXNlPSJjb2RlIj4KLSAgICBYYWxhbiBhcmNoaXRlY3QsIGxlYWQgZGV2ZWxvcGVyIG9uIFhhbGFuLUogMi54LgotICA8L3BlcnNvbj4KLSAgPHBlcnNvbiBuYW1lPSJTaGFuZSBDdXJjdXJ1IiBlbWFpbD0iU2hhbmVfQ3VyY3VydUBsb3R1cy5jb20iIGlkPSJTQyIgZXhwZXJ0aXNlPSJ0ZXN0Ij4KLSAgICBMZWFkIHRlc3RlciBmb3IgQVBJIGlzc3VlcywgYXV0b21hdGlvbiBmcmFtZXdvcmsuCi0gIDwvcGVyc29uPgotICA8cGVyc29uIG5hbWU9IlBhdWwgRGljayIgZW1haWw9IlBhdWxfRGlja0Bsb3R1cy5jb20iIGlkPSJQRCIgZXhwZXJ0aXNlPSJ0ZXN0Ij4KLSAgICBYU0xUIENvbmZvcm1hbmNlIHN0eWxlc2hlZXQgaXNzdWVzIGFuZCBYYWxhbi1DIHRlc3RpbmcuCi0gIDwvcGVyc29uPgotICA8cGVyc29uIG5hbWU9Ikpvc2VwaCBLZXNzZWxtYW4iIGVtYWlsPSJKb3NlcGhfS2Vzc2VsbWFuQGxvdHVzLmNvbSIgaWQ9IkpLIiBleHBlcnRpc2U9ImNvZGUiPgotICAgIFhhbGFuLUogMi54IGRldmVsb3BlciwgY29tcGlsaW5nL2NvbXBpbGVkIHN0eWxlc2hlZXRzIGV4cGVyaW1lbnRzLgotICA8L3BlcnNvbj4KLSAgPHBlcnNvbiBuYW1lPSJEb25hbGQgTGVzbGllIiBlbWFpbD0iZG9uYWxkX2xlc2xpZUBsb3R1cy5jb20iIGlkPSJETCIgZXhwZXJ0aXNlPSJkb2MiPgotICAgIFhhbGFuLUogYW5kIC1DIGRvY3VtZW50YXRpb24sIHNlcnZsZXRzLCBhcHBsZXRzLCBhbmQgc2FtcGxlcy4KLSAgPC9wZXJzb24+Ci0gIDxwZXJzb24gbmFtZT0iQ29zdGluIE1hbm9sYWNoZSIgZW1haWw9ImNtYW5vbGFjaGVAeWFob28uY29tIiBpZD0iQ00iPgotICAgIFhhbGFuLUogMi54IGRldmVsb3Blci4KLSAgPC9wZXJzb24+Ci0gIDxwZXJzb24gbmFtZT0iRGF2aWQgTWFyc3RvbiIgZW1haWw9IkRhdmlkX01hcnN0b25AbG90dXMuY29tIiBpZD0iRE0iIGV4cGVydGlzZT0idGVzdCI+Ci0gICAgTGVhZCB0ZXN0ZXIgZm9yIFhTTFQgQ29uZm9ybWFuY2Ugc3R5bGVzaGVldCBpc3N1ZXMuCi0gIDwvcGVyc29uPgotICA8cGVyc29uIG5hbWU9Ik15cmlhbSBNaWR5IiBlbWFpbD0ibXlyaWFtX21pZHlAbG90dXMuY29tIiBpZD0iTU0iIGV4cGVydGlzZT0iY29kZSI+Ci0gICAgWGFsYW4tSiAxLnggYW5kIDIueCBkZXZlbG9wZXIuCi0gIDwvcGVyc29uPgotICA8cGVyc29uIG5hbWU9IkdhcnkgTCBQZXNraW4iIGVtYWlsPSJnYXJ5cEBmaXJzdGVjaC5jb20iIGlkPSJHUCIgZXhwZXJ0aXNlPSJjb2RlIj4KLSAgICBYYWxhbi1KIDEueCBhbmQgMi54IGRldmVsb3BlciwgZXNwZWNpYWxseSBleHRlbnNpb24gbWVjaGFuaXNpbS4KLSAgPC9wZXJzb24+Ci0gIDxwZXJzb24gbmFtZT0iSm9obiBHZW50aWxpbiIgZW1haWw9ImpvaG5nQGFwYWNoZS5vcmciIGlkPSJKRyIgZXhwZXJ0aXNlPSJjb2RlIj4KLSAgICBNYWpvciB3b3JrIG9uIHRoZSBTUUwgZXh0ZW5zaW9ucyBsaWJyYXJ5LgotICAgPC9wZXJzb24+Ci0gICA8cGVyc29uIG5hbWU9IkNvc3RpbiBNYW5vbGFjaGUiIGVtYWlsPSJjb3N0aW5AYXBhY2hlLm9yZyIgaWQ9IkNNIiBleHBlcnRpc2U9ImNvZGUiPgotICAgICBKQVhQIGV4cGVydC4KLSAgIDwvcGVyc29uPgotCi0gPC9kZXZzPgotCi0gPGFjdGlvbnM+Ci0KLSAgIDx0YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbj4KLSAgICA8ZGF0ZT4wMS8xOS8wMTwvZGF0ZT4KLSAgICA8bGV2ZWw+cHJvZHVjdGlvbjwvbGV2ZWw+Ci0gICAgPGdvYWwgdHlwZT0iY29uZm9ybWFuY2UiPlhTTFQgMS4wIGFuZCBYUGF0aCAxLjAgY29tcGxpYW50LCA5OSUgY29uZm9ybWFuY2UgdGVzdCBwYXNzYWdlLjwvZ29hbD4KLSAgICA8Z29hbCB0eXBlPSJwZXJmb3JtYW5jZSI+UmVhc29uYWJsZSwgY29tcGV0YXRpdmUgcGVyZm9ybWFuY2UuIFtuZWVkIG1ldHJpY3NdPC9nb2FsPgotICAgIDxnb2FsIHR5cGU9InN0YWJpbGl0eSI+Um9idXN0LjwvZ29hbD4KLSAgICA8Z29hbCB0eXBlPSJhcGkiPkFQSSBDb21wbGV0ZS48L2dvYWw+Ci0gICAgPGdvYWwgdHlwZT0iZG9jdW1lbnRhdGlvbiI+RG9jdW1lbnRhdGlvbiBjb21wbGV0ZS48L2dvYWw+Ci0gICA8L3RhcmdldC1yZWxlYXNlLWRlc2NyaXB0aW9uPgotCi0gIDwhLS0gTW92ZSB0byBjb21wbGV0ZWQgc2VjdGlvbiB3aGVuIGRvbmUuIC0tPgotICAgICAgICAgICAgCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJyZWxlYXNlIj4KLSAgICAgIE5vIGtub3duIGFjdGlvbnMgcGVuZGluZyBmb3IgMi4wLjAgcmVsZWFzZS4KLSAgIDwvYWN0aW9uPgotICAKLSA8L2FjdGlvbnM+Ci0KLSA8YWN0aW9ucyBwcmlvcml0eT0ibG9uZy10ZXJtIiA+Ci0gIDwhLS0gTW92ZSB0byBjb21wbGV0ZWQgc2VjdGlvbiB3aGVuIGRvbmUuIC0tPgotCi0gICA8dGFyZ2V0LXJlbGVhc2UtZGVzY3JpcHRpb24+Ci0gICAgPGRhdGU+NC8xNS8wMTwvZGF0ZT4KLSAgICA8bGV2ZWw+YmV0YTwvbGV2ZWw+Ci0gICAgPGdvYWwgdHlwZT0iY29uZm9ybWFuY2UiPlhTTFQgMS4xIGFuZCBYUGF0aCAxLjArYWRkZW5kdW0gY29tcGxpYW50LCAxMDAlIGNvbmZvcm1hbmNlIHRlc3QgcGFzc2FnZS48L2dvYWw+Ci0gICAgPGdvYWwgdHlwZT0icGVyZm9ybWFuY2UiPlZlcnkgZ29vZCBwZXJmb3JtYW5jZS4gW25lZWQgbWV0cmljc108L2dvYWw+Ci0gICAgPGdvYWwgdHlwZT0ic3RhYmlsaXR5Ij5TdGFibGUsIHJlYXNvbmFibGUuPC9nb2FsPgotICAgIDxnb2FsIHR5cGU9ImFwaSI+QVBJIENvbXBsZXRlLjwvZ29hbD4KLSAgICA8Z29hbCB0eXBlPSJkb2N1bWVudGF0aW9uIj5Eb2N1bWVudGF0aW9uIGZ1bmN0aW9uYWxseSBjb21wbGV0ZS48L2dvYWw+Ci0gICA8L3RhcmdldC1yZWxlYXNlLWRlc2NyaXB0aW9uPgotICAgCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJjb25mb3JtYW5jZSIgd2hvPSJHUCI+Ci0gICAgICBWZXJpZnkgdGhhdCB0aGUgcmVjb21wb3NpbmcgcHJvY2VkdXJlIGZvciBlYWNoIG9mIHRoZSByZWNvbXBvc2FibGUKLSAgICAgIGVsZW1lbnRzIG1hdGNoZXMgdGhlIHN0YW5kYXJkIChpbmNsdWRpbmcgZXJyYXRhKS4KLSAgIDwvYWN0aW9uPgotCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJjb25mb3JtYW5jZSIgd2hvPSJHUCI+Ci0gICAgICBGaXggeHNsOm91dHB1dCBtZXRob2Q9IHNvIHRoYXQgaXQgb25seSBhY2NlcHRzIHZhbGlkIHZhbHVlcyBwZXIgdGhlCi0gICAgICBzdGFuZGFyZCAoeG1sLCBodG1sLCB0ZXh0LCBxbmFtZS10aGF0LWlzLW5vdC1hbi1uY25hbWUpLiAgSSdtIGxvb2tpbmcKLSAgICAgIGludG8gd2hlcmUgdGhpcyBjaGFuZ2Ugc2hvdWxkIGJlIG1hZGUuCi0gICA8L2FjdGlvbj4KLQotICAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0iY29uZm9ybWFuY2UiIHdobz0iR1AiPgotICAgICAgVmVyaWZ5IHRoYXQgdGhlIGVsZW1lbnQtYXZhaWxhYmxlIGZ1bmN0aW9uIGV4aGliaXRzIHRoZSBwcm9wZXIKLSAgICAgIGJlaGF2aW9yIGFjY29yZGluZyB0byBFcnJhdGEgRTcgcmVnYXJkaW5nIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZQotICAgICAgZGVmYXVsdCBuYW1lc3BhY2UgYW5kIHRoZSBlbGVtZW50LWF2YWlsYWJsZSBmdW5jdGlvbi4KLSAgIDwvYWN0aW9uPgotCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJleHRlbnNpb25zIiB3aG89IkdQIj4KLSAgICAgIEFkZCBjb21wYXRpYmlsaXR5IHdpdGggWGFsYW5KMSBOb2RlU2V0IGV4dGVuc2lvbiwgc28gdGhhdCBzdHlsZWhzaGVldHMgCi0gICAgICBjYW4gd29yayB3aXRoIGJvdGggcHJvY2Vzc29ycy4KLSAgIDwvYWN0aW9uPgotCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJidWciIHdobz0iU0IiPgotICAgIEhhbmRsZSBxTmFtZSBwYXJhbXRlcmVyIHRvIHRoZSBDb250ZW50SGFuZGxlciBtZXRob2RzIGJlaW5nIGFuIGVtcHR5IHN0cmluZy4KLSAgICBTZWUgbm90ZSBmcm9tIG1pa2FlbEBpbmdlbi5yZWtsYW0uc3RhbGRhbC5udSAoTWlrYWVsIFN05WxkYWwpLCAwMS8wMS8yMDAxIDA5OjQyIEFNLgotICAgPC9hY3Rpb24+Ci0KLSAgIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIiB3aG89IlNCIj4KLSAgICBPcHRpbWl6ZSAiLiIgcGF0dGVybnMgdG8gYmUgdWx0cmEgc2ltcGxlIGl0ZXJhdG9yLgotICAgPC9hY3Rpb24+Ci0KLSAgIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIiB3aG89IlNCIj4KLSAgICBPcHRpbWl6ZSAiL2Zvby9iYXoiIHBhdHRlcm5zIHRoYXQgaGF2ZSBubyB2YXJpYWJpbGl0eSwgdG8gYSBnbG9iYWwgc3BhY2UsIAotICAgIGFuZCBkb24ndCByZS1ldmFsdWF0ZSBlYWNoIHRpbWUuCi0gICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJmZWF0dXJlIj4KLSAgICBEb24gcHVibGlzaGVkIGEgbGlzdCBvZiBwcm9wb3NlZCBleHRlbnNpb25zIGEgd2hpbGUgYWdvLgotICAgIEkgd291bGQgcmVhbGx5IGxpa2UgdG8gZ2V0IHRoZXNlIGltcGxlbWVudGVkLiAgVGhpcyBpcyBhIGdvb2QKLSAgICBhcmVhIGZvciBwYXJ0LXRpbWUgY29udHJpYnV0ZXJzLCBhcyB0aGUgZXh0ZW5zaW9ucyBoYXZlIGxpbWl0ZWQgc2NvcGUuCi0gIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIj4KLSAgICBKb2UgY291bGQgdXNlIGhlbHAgd2l0aCB0aGUgc3R5bGVzaGVldCBjb21waWxlciBzdHVmZi4KLSAgICBMb3RzIG9mIHdvcmsgdG8gYmUgZG9uZSB0aGVyZS4gIEluIHBhcnRpY3VsYXIsIEkgd291bGQgbGlrZSB0bwotICAgIGZpZ3VyZSBvdXQgaG93IHRvIGlubGluZSBzb21lIHNpbXBsZSBpdHRlcmF0b3Igb3BlcmF0aW9ucywKLSAgICBsaWtlIHNlbGVjdD0ibm9kZSgpIiBhbmQgc2VsZWN0PSJmb28iLiAgQWxzbywgd2UgbmVlZCB0byBmaWd1cmUKLSAgICBvdXQgaG93IHRvIGFuYWx5emUgYSBwYXJ0aWN1bGFyIHN0eWxlc2hlZXQncyBkZXBlbmRlbmNpZXMsIGFuZAotICAgIGJlIGFibGUgdG8gcGFja2FnZSBqdXN0IHRob3NlIGNsYXNzZXMgaW4gYSBqYXIsIGFsb25nIHdpdGggdGhlCi0gICAgY29tcGlsZWQgY2xhc3Nlcy4KLSAgICA8aXNzdWUgaWQ9Imlzc3VlLWNvbXBpbGVyLWZvci1qYW51YXJ5LXJlbGVhc2UiPkkgc3VzcGVjdCBpdCBpcyB1bmxpa2VseSB0aGlzCi0gICAgd2lsbCBiZSByZWFkeSBpbiB0aW1lIGZvciB0aGlzIHJlbGVhc2UuPC9pc3N1ZT4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJ0ZXN0IiBjYXRlZ29yeT0iZmVhdHVyZSIgcHJpb3JpdHk9ImhpZ2giPgotICAgIEB0b2RvIG5lZWQgdG8gZmluZCBhbiBIVE1MIHRvIERPTSBwYXJzZXIgd2UgY2FuIHVzZSEhCi0gICAgR2V0IGEgZ29vZCwgYXBhY2hlLWxpY2Vuc2VkIEhUTUwtdG8tRE9NIHBhcnNlciBjaGVja2VkIGludG8gdGhlIAotICAgIHhtbC14YWxhblx0ZXN0XGphdmEgcmVwb3NpdG9yeSwgZm9yIHVzZSBieSBvcmcuYXBhY2hlLnFldGVzdC54c2wuWEhUQ29tcGFyYXRvcgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9InRlc3QiIGNhdGVnb3J5PSJ0ZXN0cyIgcHJpb3JpdHk9Im1lZGl1bSI+Ci0gICAgR2V0IG1vcmUgcmVhbC13b3JsZCBzdHlsZXNoZWV0cyBjaGVja2VkIGludG8geG1sLXhhbGFuXHRlc3RcdGVzdHNcY29udHJpYi4KLSAgICBXZSBuZWVkIG1vcmUgcmVhbC1saWZlIGV4YW1wbGVzIG9mIGhvdyBwZW9wbGUgYXJlIHVzaW5nIHN0eWxlc2hlZXRzLCBhbG9uZyAKLSAgICB3aXRoIGV4cGVjdGVkIG91dHB1dHMgKGluIGNvbnRyaWItZ29sZCkgLSB3ZSBjYW4gdGhlbiBydW4gb3VyIHRlc3QgZHJpdmVyIAotICAgIG92ZXIgdGhlIHdob2xlIHNldCBvZiB0aGVtIGVhc2lseSB0byBnZXQgbW9yZSB0ZXN0IHBvaW50cy4KLSAgICBOb3RlOiBwbGVhc2UgZmVlbCBmcmVlIHRvIGNvbnRyaWJ1dGUgdGVzdHMgaGVyZSAtIHRoZSBjb21taXR0ZXJzIAotICAgIHdpbGwgcmV2aWV3IGFuZCBtb3ZlIHRlc3RzIGludG8gY29uZm9ybWFuY2UsIHByb2R1Y3QsIGV0Yy4gdGVzdCAKLSAgICBhcmVhcyBhcyBuZWVkZWQsIGJ1dCB3ZSBjYW4gYWx3YXlzIGp1c3QgcnVuIENvbnRyaWJUZXN0IG9uIGFueSB0ZXN0cy4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJ0ZXN0IiBjYXRlZ29yeT0idGVzdHMiIHByaW9yaXR5PSJoaWdoIj4KLSAgICBHZXQgZXh0ZW5zaW9uIHRlc3RzIGNoZWNrZWQgaW50byB4bWwteGFsYW5cdGVzdFx0ZXN0c1xleHRlbmQKLSAgICBXZSBoYXZlIHNvbWUgYXQgTG90dXMgd2UgbmVlZCB0byBjbGVhbnVwIGFuZCBjaGVja2luLCBhbmQgd2UgCi0gICAgaG9wZSB0byBnZXQgbW9yZSBleGFtcGxlcyBmcm9tIEdhcnkgYW5kIG90aGVyIGxpc3QgbWVtYmVycy4KLSAgPC9hY3Rpb24+Ci0gICAKLSAgIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIiB3aG89IlNCIj4KLSAgICBEZWxldGUgbm9kZXMgaW4gdGhlIHNvdXJjZSB0cmVlIHdoZW4gcG9zc2libGUuICAoPz8gTm90ZSBzdXJlIGlmIHRoaXMgCi0gICAgaXMgZG8tYWJsZSBieSBiZXRhMi4pCi0gICAgPHBzdWVkby1jb2RlPgotICAgICAgMSkgRm9yIGVhY2ggZXhwcmVzc2lvbiwgdGVsbCBpZiBleHByZXNzaW9uIGNhbiB0cmF2ZXJzZSBvdXRzaWRlIGl0J3MgCi0gICAgICAgICBzdWJ0cmVlLgotICAgICAgMikgRm9yIGVhY2ggZWxlbWVudCwgdGVsbCBpZiBhbnkgZm9sbG93aW5nIGVsZW1lbnRzIG1heSBuZWVkIHRvICAKLSAgICAgICAgIGFjY2VzcyB0aGF0IG5vZGUuCi0gICAgICAzKSBJbiBpbnN0cnVjdGlvbnMgdGhhdCB0cmF2ZXJzZSBub2Rlcywgb25jZSB0aGUgcHJvY2Vzc2luZyBvZiB0aGUgCi0gICAgICAgICBub2RlIGlzIGNvbXBsZXRlZCwgcmVtb3ZlIHRoZSBub2RlIGlmIG5vIGZvbGxvd2luZyBlbGVtZW50cyBtYXkgCi0gICAgICAgICBuZWVkIHRvIGFjY2VzcyB0aGF0IG5vZGUuCi0gICAgICA0KSBLZWVwIHRoZSBwYXJzZSBldmVudHMgZnJvbSBnZXR0aW5nIHRvbyBmYXIgYWhlYWQgb2YgdGhlIHRyYW5zZm9ybS4KLSAgICAgIAotICAgICAgVE9ETzogSW4gU3RlcFBhdHRlcm4sIEFuY2VzdG9ycyB0ZXN0cyB3aXRoIHByZWRpY2F0ZXMgYXJlIHByb2JsZW1hdGljLCAKLSAgICAgIGFuZCB3aWxsIHJlcXVpcmUgc3BlY2lhbCB0cmVhdG1lbnQuCi0gICAgPC9wc3VlZG8tY29kZT4KLSAgIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImZlYXR1cmUiPgotICAgIFhQb2ludGVyIGJ1aWx0IG9uIHRoZSBYUGF0aCBwYWNrYWdlLgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIHBhY2thZ2VzPSJ4cGF0aC5heGVzIiBjYXRlZ29yeT0icGVyZm9ybWFuY2UiPgotICAgIFNjaGVtYS1zYXZ5IGl0dGVyYXRvcnMuCi0gICAgVGhpcyBpcyBoYXJkIGJlY2F1c2UgdGhlcmUgaXMgbm8gc3RhbmRhcmQgQVBJIGZvciBzY2hlbWFzIHlldC4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBpZD0ic3R5bGVzaGVldC1hbmFseXNpcyIgcGFja2FnZXM9InByb2Nlc3NvciIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIj4KLSAgICBTdHlsZXNoZWV0IGFuYWx5c2lzIG1vZHVsZS4gIFdoZW4gSSBjYWxsIGEgdGVtcGxhdGUsIHdoZXJlIGlzIGl0IGxpa2VseSB0byB3YWxrIGluIHRoZSB0cmVlPwotICAgIENhbiBJIGJlIHN1cmUgdGhhdCBpdCB3aWxsIG5vdCB3YWxrIHVwIGFnYWluPwotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIHBhY2thZ2VzPSJzdHJlZSIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIj4KLSAgICBSZWxhdGVkIHRvIHN0eWxlc2hlZXQtYW5hbHlzaXMsIHRoZSBhYmlsaXR5IHRvIHRocm93IGF3YXkgcGFydHMgb2YgdGhlIHRyZWUgdGhhdCBoYXZlIGJlZW4gcHJvY2Vzc2VkLAotICAgIGFuZCB3ZSBrbm93IHdlIHdvbid0IHJldXNlLCBiYXNlZCBvbiB0aGUgc3R5bGVzaGVldCBhbmFseXNpcy4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBwYWNrYWdlcz0icHJvY2Vzc29yIiBjYXRlZ29yeT0icGVyZm9ybWFuY2UiPgotICAgIFN1Yi1leHByZXNzaW9uIGVsaW1pbmF0aW9uLiAgV2hlbiBJIGNhbGwgYSBzZXJpZXMgb2YKLSAgICB4c2w6d2hlbiB0ZXN0cywgYXJlIHRoZXJlIGNvbW1vbiBzdWJleHByZXNzaW9ucyB0aGF0IGNhbiBiZQotICAgIGV4ZWN1dGVkIG9uY2UgYW5kIHRoZW4gc2hhcmVkPwotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiPgotICA8L2FjdGlvbj4KLQotIDwvYWN0aW9ucz4KLQotIDxjb21wbGV0ZWQ+Ci0gIDwhLS0gTW92ZSBhY3Rpb24gc2VjdGlvbnMgdG8gaGVyZSB3aGVuIGNvbXBsZXRlZCwgYW5kIGRhdGUgdGhlbS4gLS0+Ci0gIAotICAgPGFjdGlvbiBjb250ZXh0PSJkb2MiIGNhdGVnb3J5PSJkb2N1bWVudGF0aW9uIiB3aG89IlNCIiBjb21wbGV0ZWQ9IjAxLzEyLzAxIj4KLSAgICBVcGRhdGUgYW5kIGFkZCB0byBhcmNoaXRlY3R1cmUgZG9jdW1lbnRhdGlvbiwgaW5jbHVkaW5nIHBhY2thZ2UgaGVhZGVycy4KLSAgIDwvYWN0aW9uPgotCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJlcnJvci1oYW5kbGluZyIgd2hvPSJTQiIgY29tcGxldGVkPSIwMS8wNi8wMSI+Ci0gICAgU2ltcGxpZnkgc29tZSBvZiB0aGUgZXhjZXB0aW9uIG5lc3RpbmcsIG1heWJlLCBhbmQgbWFrZSBzdXJlIGVycm9yIGxpc3RlbmVycyAKLSAgICBhcmUgYmVpbmcgY2FsbGVkIGZvciBhbGwgY2FzZXMuCi0gICAgPG5vdGU+Rml4ZWQgYnVnIHdpdGggWFBhdGhzIGluIHRoaXMgYXJlYS4gIE1vc3Qgb2YgdGhlIG5lc3RpbmcgaXMgYmVpbmcgY2F1c2VkIAotICAgIGJ5IFRyYW5mb3JtZXJIYW5kbGVyIHRvIFNBWEV4Y2VwdGlvbiBuZXN0aW5nLCB3aGljaCBjYW4gYmUgdW5uZXN0ZWQuPC9ub3RlPgotICAgPC9hY3Rpb24+Ci0gIAotICAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0iYnVnIiB3aG89IlNCIiBjb21wbGV0ZWQ9IjAxLzA2LzAxIj4KLSAgICBGaXggMS44IHByb2JsZW1zOiBleHRlbmQwMSAoZXhjZXB0aW9uKSwgbnVtYmVyZm9ybWF0IDA2LCBudW1iZXJmb3JtYXQxNiwgb3V0cHV0NzcgKGV4Y2VwdGlvbikuCi0gICAgSkRLIDEuMS44LCB1c2luZyB4bWwteGFsYW5cdGVzdFxDb25mb3JtYW5jZVRlc3QuYmF0LCBydW5oYXJuZXNzLmJhdCwgYW5kIHRlc3R0aHJlYWRzLmJhdCBhcy1pcy4KLSAgICA8bm90ZT5UaGUgbnVtYmVyIGZvcm1hdCBzdHVmZiBpcyBhIGJ1ZyBpbiBKREsgMS44IGFuZCBjYW4ndCBlYXNpbHkgYmUgZml4ZWQgCi0gICAgb3IgaGFja2VkLjwvbm90ZT4KLSAgIDwvYWN0aW9uPgotCi0gICA8IS0tIGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0iZmVhdHVyZSIgd2hvPSJTQiIgY29tcGxldGVkPSIwMS8wNC8wMSI+Ci0gICAgSW50ZWdyYXRlIEpvaG4gR2VudGlsaW4gJmx0O2pvaG5nbGludXhAZXllY2F0Y2hpbmcuY29tPiBjb2RlLCAKLSAgICBmb3IgU1FMIEV4dGVuc2lvbiBFbmhhbmNlbWVudHMuCi0gICA8L2FjdGlvbiAgKENIQU5HRVMgQkFDS0VEIE9VVCBPRikgLS0+Ci0KLSAgIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImJ1ZyIgd2hvPSJTQiIgY29tcGxldGVkPSIwMS8wNC8wMSI+Ci0gICAgSW1wbGVtZW50IHhzbDpzdHJpcC1zcGFjZSBmb3IgZ2VuZXJpYyBET00gcHJvY2Vzc2luZy4KLSAgIDwvYWN0aW9uPgotCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJwZXJmb3JtYW5jZSIgd2hvPSJTQiIgY29tcGxldGVkPSIwMS8wMy8wMSI+Ci0gICAgRm9yIGRlZmF1bHQgdHJhbnNmb3JtZXIsIGRvIGRpcmVjdCB0cmFuc2Zvcm0gd2l0aG91dCBzdHlsZXNoZWV0LgotICAgPC9hY3Rpb24+Ci0gICAKLSAgIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImRvY3VtZW50YXRpb24iIHdobz0iU0IiIGNvbXBsZXRlZD0iMDEvMDEvMDEiPgotICAgIEZpeCBzb21lIGphdmFkb2MgaGVhZGVycyB0aGF0IHN0aWxsIGhhdmUgb2xkIFhhbGFuSjEgdGV4dC4gIEZvciBpbnN0YW5jZSwgCi0gICAgVHJhbnNmb3JtZXJJbXBsLgotICAgPC9hY3Rpb24+Ci0gIAotICAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0iYnVncyIgd2hvPSJTQiIgY29tcGxldGVkPSIxMi8zMS8wMCI+Ci0gICAgRml4IGJ1ZyB3aXRoIFNoYW5lJ3MgczJzIHRlc3QgaGFuZy4KLSAgIDwvYWN0aW9uPgotICAgCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJidWdzIiB3aG89IlNCLCBKSyIgY29tcGxldGVkPSIxMi8zMS8wMCI+Ci0gICAgRml4IGJ1ZyB3aXRoIHJhcmUgaW50ZXJtaXR0ZW50IGZhaWx1cmVzLCBwcm9iYWJseSBpbiB0aGUgU1RyZWUuCi0gICAgPG5vdGU+VmVyaWZpY2F0aW9uIHRlc3Rpbmcgb24gSksncyBtYWNoaW5lIG5lZWRlZC48L25vdGU+Ci0gICA8L2FjdGlvbj4KLQotICAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0icGVyZm9ybWFuY2UiIHdobz0iU0IiIGNvbXBsZXRlZD0iMTIvMjYvMDAiPgotICAgIE9wdGltaXplICIvZm9vL2JheiIgcGF0dGVybnMgdG8gdXNlIHNpbXBsZSBjaGlsZCB3YWxrZXJzLgotICAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9InRlc3QiIHdobz0iU0MiIGNhdGVnb3J5PSJtaW5pdGVzdCIgcHJpb3JpdHk9Im1lZGl1bSIgY29tcGxldGVkPSIxMi8wOC8wMCI+Ci0gICAgQ3JlYXRlIE1pbml0ZXN0IGF1dG9tYXRlZCB0ZXN0IGZvciBkZXZlbG9wZXJzIHRvIHJ1biBiZWZvcmUgY2hlY2tpbjsgCi0gICAgdmVyaWZpZXMgYmFzaWMgZnVuY3Rpb25hbGl0eSBvZiBUUkFYIGludGVyZmFjZSBhbmQgWGFsYW4gcHJvY2Vzc29yLiAKLSAgICAoU3RpbGwgdG9kbywgbWlub3I6IGdldCB4YWxhbi1kZXYgbGlzdCB0byB2b3RlIHRvIHVzZSB0aGlzKQotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJhcmNoaXRlY3R1cmUiIHByaW9yaXR5PSJoaWdoIiB3aG89IlNCIiBjb21wbGV0ZWQ9IjEyLzEwLzAwIj4KLSAgICBGaXggcmVtYWluaW5nIGF4ZXMgdGVzdHMuCi0gIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIiBwcmlvcml0eT0iaGlnaCIgd2hvPSJNTSIgY29tcGxldGVkPSIxMi84LzAwIj4KLSAgICBXaGVuIHVzaW5nIFNUcmVlIGZvciB0aGUgaW5wdXQsIHVzZSBTVHJlZSBmb3IgdGhlIGRvY3VtZW50KCkgYW5kCi0gICAgcmVzdWx0IHRyZWUgZnJhZ21lbnRzLgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJhcmNoaXRlY3R1cmUsIGNvbmZvcm1hbmNlIiBwcmlvcml0eT0iaGlnaCIgd2hvPSJTQiIgY29tcGxldGVkPSIxMi8wNi8wMCI+Ci0gICAgUmVzdHJ1Y3R1cmUgT3V0cHV0Rm9ybWF0IGNsYXNzIHRvIGJlIGJhc2VkIG9uIHByb3BlcnRpZXMuICBNYWtlIHN1cmUgCi0gICAgaW5jbHVkZS9pbXBvcnQgY29uZm9ybWFuY2UgaXMgY29ycmVjdC4KLSAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJhcmNoaXRlY3R1cmUiIHByaW9yaXR5PSJoaWdoIiB3aG89IlNCIiBjb21wbGV0ZWQ9IjEyLzA2LzAwIj4KLSAgICBNYWtlIGVudGl0aWVzIGluIHRoZSBodG1sIHNlcmlhbGl6ZXIgdG8gYmUgcmVzb3VyY2UgZmlsZSBkcml2ZW4uCi0gIDwvYWN0aW9uPgotICAKLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0iYXJjaGl0ZWN0dXJlIiBwcmlvcml0eT0iaGlnaCIgd2hvPSJTQiIgY29tcGxldGVkPSIxMi8wNi8wMCI+Ci0gICAgUmVtb3ZlZCBsaW5lZmVlZCBub3JtYWxpemF0aW9uIGZyb20gc2VyaWFsaXplcnMuICBJIHRoaW5rLgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNvbXBsZXRlZC1kYXRlPSIxMC8zMS8wMCI+Ci0gICAgTWFrZSB0aGlzIHRvZG8gbGlzdC4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiB3aG89IlNCIiAgY2F0ZWdvcnk9InRyYXgiIGNvbXBsZXRlZC1kYXRlPSIxMS8wNi8wMCI+Ci0gICAgaW1wbGVtZW50IGphdmF4LnRyYXggaW50ZXJmYWNlcy4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBwYWNrYWdlcz0ic2VyaWFsaXplIiB3aG89IlNCIiAgY2F0ZWdvcnk9ImZlYXR1cmUiCi0gICAgICAgICAgY29tcGxldGVkLWRhdGU9IjExLzE3LzAwIj4KLSAgICBJbXBsZW1lbnQgRE9NU2VyaWFsaXplciBvbiBTZXJpYWxpemVyVG9YTUwuCi0gIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgd2hvPSJTQiIgcGFja2FnZXM9InhwYXRoLmF4ZXMiIGNhdGVnb3J5PSJwZXJmb3JtYW5jZSIKLSAgICAgICAgICBwcmlvcml0eT0iaGlnaCIgY29tcGxldGVkLWRhdGU9IjExLzE3LzAwIj4KLSAgICBpbXBsZW1lbnQgZmFzdCBpdGVyYXRvciBmb3IgImZvbyIgcGF0dGVybi4KLSAgPC9hY3Rpb24+Ci0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiB3aG89Ik1NIiBjYXRlZ29yeT0icGVyZm9ybWFuY2UiIHByaW9yaXR5PSJoaWdoIiBjb21wbGV0ZWQtZGF0ZT0iMTEvMjkvMDAiPgotICAgIG9wdGltaXplIHhzbDprZXkgYW5kIGtleSgpIHN0dWZmIGJ5IGJ1aWxkaW5nIGhhc2ggdGFibGUgb2YgaXRlcmF0b3JzIGZvcgotICAgIGVhY2gga2V5LgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJjb2RlLWNsZWFudXAiIHByaW9yaXR5PSJtZWRpdW0iIGNvbXBsZXRlZD0iMTIvMDEvMDAiPgotICAgIENsZWFuIHVwIHRyZWF0bWVudCBvZiBudWxsIG5hbWVzcGFjZXMsIHJlICIiIHZzLiBudWxsLgotICAgIDxjb21wbGV0ZWQtY29tbWVudD5JIGNvbnNpZGVyIHRoaXMgdG8gYmUgcHJldHR5IGdvb2QgaW4gbW9zdCBwbGFjZXMuICAiIiAKLSAgICBlcXVhbHMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLiAgTm8gcGVuZGluZyBwbGFucyBmb3IgYWN0aW9uLCBvdGhlciB0aGFuIG9uZ29pbmcgCi0gICAgY2xlYW51cCBhbmQgamF2YWRvYyBhcyBpdCBvY2N1cnMuPC9jb21wbGV0ZWQtY29tbWVudD4KLSAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiICBjYXRlZ29yeT0iY29uZm9ybWFuY2UiIHByaW9yaXR5PSJoaWdoIiBjb21wbGV0ZWQ9IjEyLzEwLzAwIj4KLSAgICBJbXBsZW1lbnQgbmFtZXNwYWNlIGFsaWFzaW5nLgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIHBhY2thZ2VzPSJ0ZW1wbGF0ZXMiIGNhdGVnb3J5PSJjb25mb3JtYW5jZSIgcHJpb3JpdHk9Im1lZGl1bSIKLSAgICAgICAgICBub3RlPSJkb25lPyIgY29tcGxldGVkPSIxMS8yOS8wMCI+Ci0gICAgQ2F0Y2ggbXVsdGlwbGUgZGVmaW5pdGlvbnMgb2YgYSB2YXJpYWJsZSB3aXRoIHRoZSBzYW1lIG5hbWUgYW5kIHNjb3BlLgotICA8L2FjdGlvbj4KLSAgCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImNvZGUtY2xlYW51cCIgcHJpb3JpdHk9Im1lZGl1bSIgY29tcGxldGVkPSIxMS8yNS8wMCI+Ci0gICAgTW92ZSBvcmcuYXBhY2hlLnhhbGFuLnV0aWxzIHBhY2thZ2UgdG8gb3JnLmFwYWNoZS54bWwudXRpbHMuCi0gICAgcmVtb3ZlIHJlc291cmNlIGRlcGVuZGVuY2llcyBvbiB4YWxhbiBhbmQvb3IgeHBhdGggcGFja2FnZS4KLSAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJjb2RlLWNsZWFudXAsIHBlcmZvcm1hbmNlIiBwYWNrYWdlcz0idGVtcGxhdGVzIgotICAgcHJpb3JpdHk9Im1lZGl1bSIgd2hvPSJHUCIgY29tcGxldGVkPSIxMS8zMC8wMCI+Ci0gICAgUmVmYWN0b3JlZCB0aGUgcmVjb21wb3NlIGxvZ2ljIHRvIG9wZXJhdGUgbW9yZSBjbGVhbmx5IGFuZCBxdWlja2x5LiBGaXhlZCBUZW1wbGF0ZUxpc3QKLSAgICB0byBwcm9wZXJseSBvcmRlciB0ZW1wbGF0ZXMuCi0gIDwvYWN0aW9uPgotICAKLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiBjYXRlZ29yeT0iY29kZS1jbGVhbnVwIiBwYWNrYWdlcz0iZXh0ZW5zaW9ucyIKLSAgIHByaW9yaXR5PSJtZWRpdW0iIHdobz0iR1AiIGNvbXBsZXRlZD0iMTAvMjkvMDAiPgotICAgIEltcHJvdmVkIGVycm9yIHJlcG9ydGluZyBmb3IgamF2YSBleHRlbnNpb24gbWV0aG9kIGVycm9ycy4KLSAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJkb2N1bWVudGF0aW9uIiBwcmlvcml0eT0ibWVkaXVtIiB3aG89IkdQIiBjb21wbGV0ZWQ9IjExLzIzLzAwIj4KLSAgICBVcGRhdGVkIGRvY3VtZW50YXRpb24gZm9yIEV4dGVuc2lvbiBIYW5kbGluZyB0byBjb25mb3JtIHRvIHRoZSBuZXcgZXh0ZW5zaW9uIG1lY2hhbmlzbS4KLSAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJmZWF0dXJlIiBwcmlvcml0eT0ibWVkaXVtIiB3aG89IkdQIiBjb21wbGV0ZWQ9IjEyLzAzLzAwIj4KLSAgICBDaGFuZ2VkIGV4dGVuc2lvbiBtZWNoYW5pc20gdG8gbG9hZCBleHRlbnNpb25zIHVzaW5nIHRoZSB0aHJlYWQncyBDb250ZXh0Q2xhc3NMb2FkZXIsCi0gICAgaWYgYXZhaWxhYmxlLgotICA8L2FjdGlvbj4KLSAgCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImZlYXR1cmUiIHBhY2thZ2VzPSJleHRlbnNpb25zIiAKLSAgIHByaW9yaXR5PSJtZWRpdW0iIHdobz0iR1AiIGNvbXBsZXRlZD0iMTEvMjgvMDAiPgotICAgIEltcGxlbWVudCB0b2tlbml6ZSBleHRlbnNpb24uICBJbXBsZW1lbnQgZWxlbWVudC1hdmFpbGFibGUgYW5kIGZ1bmN0aW9uLWF2YWlsYWJsZSBmb3IKLSAgICBidWlsdC1pbiBlbGVtZW50cyBhbmQgZnVuY3Rpb25zLgotICA8L2FjdGlvbj4KLSAgCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImNvZGUtY2xlYW51cCIgcGFja2FnZXM9ImV4dGVuc2lvbnMiIAotICAgcHJpb3JpdHk9Im1lZGl1bSIgd2hvPSJHUCIgY29tcGxldGVkPSIxMS8wNy8wMCI+Ci0gICAgIEZpeCBoYW5kbGluZyBvZiB4c2w6ZmFsbGJhY2sgZWxlbWVudHMgd2l0aGluIGV4dGVuc2lvbiBlbGVtZW50cyB0aGF0IHByb2Nlc3MgdGhlaXIgb3duCi0gICAgIGNvZGUgKGxpa2UgcmVkaXJlY3QpLgotICA8L2FjdGlvbj4KLSAgCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImNvZGUtY2xlYW51cCIgcGFja2FnZXM9ImNvbXBpbGVyIiAKLSAgIHByaW9yaXR5PSJtZWRpdW0iIHdobz0iR1AiIGNvbXBsZXRlZD0iMTEvMDkvMDAiPgotICAgICBDbGVhbmVkIHVwIGNvbXBpbGVyIGhhbmRsaW5nIG9mIGdldFdoYXRUb1Nob3coKSB0byByZXN1bHQgaW4gY2xlYW5lciBjb2RlIGFuZCBwcm92aWRlCi0gICAgIGEgbW9yZSBhY2N1cmF0ZSBmaWx0ZXIuCi0gIDwvYWN0aW9uPgotICAKLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlIiB3aG89IlNCIiBwYWNrYWdlcz0ieHBhdGguYXhlcyIgY2F0ZWdvcnk9InBlcmZvcm1hbmNlIiBwcmlvcml0eT0iaGlnaCIgY29tcGxldGVkPSIxMi8xMy8wMCI+Ci0gICAgaW1wbGVtZW50IGZhc3QgaXRlcmF0b3IgZm9yICJAZm9vIiBwYXR0ZXJuLgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIHdobz0iU0IiIHBhY2thZ2VzPSJ4cGF0aC5heGVzIiBjYXRlZ29yeT0icGVyZm9ybWFuY2UiIHByaW9yaXR5PSJoaWdoIiBjb21wbGV0ZWQ9IjEyLzE0LzAwIj4KLSAgICBpbXBsZW1lbnQgZmFzdCBpdGVyYXRvciBmb3IgIi8vZm9vIiBwYXR0ZXJuLgotICA8L2FjdGlvbj4KLSAgCi0gICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJjb2RlLWNsZWFudXAiIHdobz0iREwiIHBhY2thZ2VzPSJ4YWxhbnNlcnZsZXQiIHByaW9yaXR5PSJtZWRpdW0iIGNvbXBsZXRlZD0iMTIvMTUvMDAiPgotICAgICBSZXdyaXRlIHRoZSBzYW1wbGUgc2VydmxldCB0byB1c2UgdGhlIFRyQVggaW50ZXJmYWNlcyBhbmQgZWxpbWluYXRlIHNldHRpbmcgc3lzdGVtIHByb3BlcnRpZXMKLSAgICAgd2l0aGluIHRoZSBzZXJ2bGV0LgotICA8L2FjdGlvbj4gIAotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgd2hvPSJTQiIgcGFja2FnZXM9Im9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplIiBjYXRlZ29yeT0ic2FtcGxlcyIgcHJpb3JpdHk9ImhpZ2giIGNvbXBsZXRlZD0iMTIvMTYvMDAiPgotICAgIEZpeCB0aGUgc2VyaWFsaXplciBzbyBpdCBjYW4gc2VyaWFsaXplIGFyYml0cmFyeSBYUGF0aCBleHByZXNzaW9uIHJlc3VsdHMgKG90aGVyIHRoYW4gRG9jdW1lbnQgbm9kZXMpLgotICAgIEFzIGl0IGN1cnJlbnRseSBzdGFuZHMsIHRoZSBBcHBseVhQYXRoIHNhbXBsZSBvbmx5IHdvcmtzIHdoZW4geW91IGdpdmUgaXQgYW4gZXhwcmVzc2lvbiB0aGF0IHJldHVybnMgCi0gICAgdGhlIGVudGlyZSBEb2N1bWVudC4KLSAgPC9hY3Rpb24+Ci0gIAotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiIGNhdGVnb3J5PSJkb2N1bWVudGF0aW9uIiBwcmlvcml0eT0iaGlnaCIgY29tcGxldGVkPSIxMi8xNy8wMCI+Ci0gICAgRmlsbCBpbiBhbGwgTkVFRFNET0Mgc2VjdGlvbnMuCi0gIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSIgY2F0ZWdvcnk9ImNvZGUtY2xlYW51cCIgd2hvPSJETCIgcGFja2FnZXM9InhhbGFuLmNsaWVudCIgcHJpb3JpdHk9Im1lZGl1bSIgY29tcGxldGVkPSIxMi8xNy8wMCI+Ci0gICAgUmV3cml0ZSB0aGUgY2xpZW50IGFwcGxldCB0byB1c2UgdGhlIFRyQVggaW50ZXJmYWNlcywgYW5kIG1vdmUgZmV0Y2hpbmcgb2Ygc291cmNlCi0gICAgZG9jdW1lbnRzIGFuZCBzdHlsZXNoZWV0cyB0byB0aGUgdHJ1c3RlZCB3b3JrZXIgdGhyZWFkIHRvIGdldCBhcm91bmQgSUUgc2VjdXJpdHkgcmVzdHJpY3Rpb25zLgotICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUiICBjYXRlZ29yeT0iY29uZm9ybWFuY2UiIHByaW9yaXR5PSJoaWdoIiBjb21wbGV0ZWQ9IjEyLzE5LzAwIj4KLSAgICBDaGVjayByZWxhdGl2ZSBVUkwgcmVzb2x1dGlvbiB3aXRoIG5vdGF0aW9ucyBhbmQgdW5wYXJzZWQgZW50aXRpZXMuCi0gICAgTm90IHN1cmUgaWYgdGhlcmUgaXMgYSBidWcgaGVyZS4gIFNlZSBub3RlIGZyb20gVGhvbWFsIE1hZXNpbmcgb24KLSAgICAxMC8yNC8yMDAwLCB0aXRsZWQgIkFudHdvcnQ6IFJlOiIuCi0gIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0idGVzdCIgY2F0ZWdvcnk9ImZlYXR1cmUiIHByaW9yaXR5PSJoaWdoIiBjb21wbGV0ZWQ9IjEyLzE5LzAwIj4KLSAgICBVcGRhdGUgdGhlIHhtbC14YWxhblx0ZXN0XHZpZXdSZXN1bHRzLnhzbCBzdHlsZXNoZWV0IHRvIHNob3cgCi0gICAgZGlmZmVyZW5jZXMgYmV0d2VlbiB0d28gcmVzdWx0IGZpbGVzIGZyb20gdGhlIHNhbWUgdGVzdCAoZWcuCi0gICAgc2hvdyBkaWZmZXJlbmNlcyBmcm9tIGEgcmVzdWx0cy1iZWZvcmUueG1sIHJ1biBiZWZvcmUgYSBkZXZlbG9wZXIgCi0gICAgbWFrZXMgYSBjaGFuZ2UsIHdpdGggcmVzdWx0cy1hZnRlci54bWwsIHdoaWNoIHdhcyBhZnRlciB0aGUgCi0gICAgZGV2ZWxvcGVyJ3MgY2hhbmdlLikKLSAgICBUaGlzIGNvdWxkIGJlIGEgYnVuY2ggb2Ygc3R1ZmYgYWRkZWQgdG8gdmlld1Jlc3VsdHMueHNsIG9yIGNvdWxkIAotICAgIGJlIGEgc2VwYXJhdGUgc3R5bGVzaGVldC4gU2VlIDxiPlNDPC9iPiBmb3IgZGV0YWlscy4KLSAgPC9hY3Rpb24+Ci0KLSA8L2NvbXBsZXRlZD4KLQotPC90b2RvPgpkaWZmIC0tZ2l0IGEvdG9kby54c2wgYi90b2RvLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmZmOGNhYy4uMDAwMDAwMAotLS0gYS90b2RvLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDE0NiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLTx4c2w6dmFyaWFibGUgbmFtZT0idGl0bGUiIHNlbGVjdD0iY29uY2F0KHRvZG8vQHByb2plY3QsICcgJywgdG9kby9AbWFqb3ItdmVyc2lvbikiLz4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iLyI+Ci0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgIDxUSVRMRT48eHNsOnZhbHVlLW9mIHNlbGVjdD0iJHRpdGxlIi8+PC9USVRMRT4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotCi0gICAgICAgIDxIMj48eHNsOnZhbHVlLW9mIHNlbGVjdD0iY29uY2F0KCR0aXRsZSwgJzogJywgdG9kby9AdGl0bGUpIi8+PC9IMj4KLSAgICAgICAgPHA+PGZvbnQgc2l6ZT0iLTEiPlNlZSBhIAotICAgICAgICAgIDx4c2w6ZWxlbWVudCBuYW1lPSJhIj4KLSAgICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9ImhyZWYiPiNkZXZlbG9wZXItbGlzdDwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgICAgIDx4c2w6dGV4dD5saXN0IG9mIGRldmVsb3BlcnMvaW5pdGlhbHMuPC94c2w6dGV4dD4KLSAgICAgICAgICA8L3hzbDplbGVtZW50PgotICAgICAgICA8L2ZvbnQ+PC9wPgotICAgICAgICA8Zm9udCBzaXplPSItMSI+PHA+UGxhbm5lZCByZWxlYXNlczogCi0gICAgICAgICAgICA8QlIvPjx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJ0b2RvL2FjdGlvbnMvdGFyZ2V0LXJlbGVhc2UtZGVzY3JpcHRpb24iPgotICAgICAgICAgICAgICA8eHNsOmVsZW1lbnQgbmFtZT0iYSI+Ci0gICAgICAgICAgICAgICAgPHhzbDphdHRyaWJ1dGUgbmFtZT0iaHJlZiI+I3JlbGVhc2UtZGF0ZS08eHNsOnZhbHVlLW9mIHNlbGVjdD0iZGF0ZSIvPjwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iZGF0ZSIvPgotICAgICAgICAgICAgICA8L3hzbDplbGVtZW50Pjx4c2w6dGV4dD4gPC94c2w6dGV4dD48eHNsOnRleHQ+IDwveHNsOnRleHQ+Ci0gICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICAgIDx4c2w6ZWxlbWVudCBuYW1lPSJhIj4KLSAgICAgICAgICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJocmVmIj4jcmVsZWFzZS1kYXRlLWNvbXBsZXRlZDwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgICAgICAgICA8eHNsOnRleHQ+Q29tcGxldGVkPC94c2w6dGV4dD4KLSAgICAgICAgICAgICAgPC94c2w6ZWxlbWVudD4KLQotICAgICAgICA8L3A+PC9mb250PgotICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0idG9kbyI+Ci0gICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9ImFjdGlvbnMiPgotICAgICAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0idGFyZ2V0LXJlbGVhc2UtZGVzY3JpcHRpb24iPgotICAgICAgICAgICAgICAgIDxwPgotICAgICAgICAgICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgICAgICAgICAgICAgIDwvcD4KLSAgICAgICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJhY3Rpb24iPgotICAgICAgICAgICAgICAgIDx4c2w6aWYgdGVzdD0ibm9ybWFsaXplLXNwYWNlKC4pIj4KLSAgICAgICAgICAgICAgICAgIDxwPgotICAgICAgICAgICAgICAgICAgIDx4c2w6bnVtYmVyLz4pIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgICAgICAgICAgICAgICA8eHNsOmlmIHRlc3Q9IkAqIj4KLSAgICAgICAgICAgICAgICAgICAgPEJSLz4KLSAgICAgICAgICAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IkAqIi8+Ci0gICAgICAgICAgICAgICAgICA8L3A+Ci0gICAgICAgICAgICAgICAgPC94c2w6aWY+Ci0gICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICAgIDxIUi8+Ci0gICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0KLSAgICAgICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iY29tcGxldGVkIj4KLSAgICAgICAgICAgICAgPHhzbDplbGVtZW50IG5hbWU9ImEiPgotICAgICAgICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9Im5hbWUiPnJlbGVhc2UtZGF0ZS1jb21wbGV0ZWQ8L3hzbDphdHRyaWJ1dGU+Ci0gICAgICAgICAgICAgICAgPEgzPkNvbXBsZXRlZDogPC9IMz4KLSAgICAgICAgICAgICAgPC94c2w6ZWxlbWVudD4KLSAgICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJhY3Rpb24iPgotICAgICAgICAgICAgICA8eHNsOmlmIHRlc3Q9Im5vcm1hbGl6ZS1zcGFjZSguKSI+Ci0gICAgICAgICAgICAgICAgPHA+Ci0gICAgICAgICAgICAgICAgIDx4c2w6bnVtYmVyLz4pIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgICAgICAgICAgICAgPHhzbDppZiB0ZXN0PSJAKiI+Ci0gICAgICAgICAgICAgICAgICA8QlIvPgotICAgICAgICAgICAgICAgICA8L3hzbDppZj4KLSAgICAgICAgICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJAKiIvPgotICAgICAgICAgICAgICAgIDwvcD4KLSAgICAgICAgICAgICAgPC94c2w6aWY+Ci0gICAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgICAgICAgPEhSLz4KLSAgICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0KLSAgICAgICAgPHhzbDpjYWxsLXRlbXBsYXRlIG5hbWU9ImRldmVsb3Blci1saXN0Ii8+Ci0gICAgICAgPC94c2w6Zm9yLWVhY2g+Ci0KLSAgICAgIDwvQk9EWT4KLSAgICA8L0hUTUw+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImFjdGlvbi9AKiI+Ci0gIDwhLS0gQWRkIGxpbmsgdG8gdGhlIHdobyBhdHRyaWJ1dGVzIHRvIGNvcnJlc3BvbmRpbmcgaXRlbSBpbiBkZXZlbG9wZXItbGlzdCAtLT4KLSAgICA8Yj48eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSguKSIvPjo8L2I+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0PgotICAgICAgPHhzbDpjaG9vc2U+Ci0gICAgICAgIDx4c2w6d2hlbiB0ZXN0PSJuYW1lKC4pPSd3aG8nIj4KLSAgICAgICAgICA8eHNsOmVsZW1lbnQgbmFtZT0iYSI+Ci0gICAgICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJocmVmIj4jcGVyc29ucmVmLTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC94c2w6YXR0cmlidXRlPgotICAgICAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz4KLSAgICAgICAgICA8L3hzbDplbGVtZW50PgotICAgICAgICA8L3hzbDp3aGVuPgotICAgICAgICA8eHNsOm90aGVyd2lzZT4KLSAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPgotICAgICAgICA8L3hzbDpvdGhlcndpc2U+Ci0gICAgICA8L3hzbDpjaG9vc2U+Ci0gICAgPHhzbDppZiB0ZXN0PSJub3QgKHBvc2l0aW9uKCk9bGFzdCgpKSI+Ci0gICAgICA8eHNsOnRleHQ+LCA8L3hzbDp0ZXh0PgotICAgIDwveHNsOmlmPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbi9kYXRlIj4KLSAgICAgIDx4c2w6ZWxlbWVudCBuYW1lPSJhIj4KLSAgICAgICAgPHhzbDphdHRyaWJ1dGUgbmFtZT0ibmFtZSI+cmVsZWFzZS1kYXRlLTx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PC94c2w6YXR0cmlidXRlPgotICAgICAgICA8Yj48eHNsOnRleHQ+Rm9yIHJlbGVhc2U6IDwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L2I+Ci0gICAgICA8L3hzbDplbGVtZW50PgotICAgIAotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJpc3N1ZSI+Ci0gICAgPEJSLz48Yj5Jc3N1ZSA8L2I+PHhzbDp0ZXh0Pls8L3hzbDp0ZXh0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAaWQiLz4KLSAgICA8eHNsOnRleHQ+XTogPC94c2w6dGV4dD4KLSAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InRhcmdldC1yZWxlYXNlLWRlc2NyaXB0aW9uL2xldmVsIj4KLSAgICA8eHNsOnRleHQ+LCA8L3hzbDp0ZXh0Pjx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGFyZ2V0LXJlbGVhc2UtZGVzY3JpcHRpb24vZ29hbCI+Ci0gICAgPEJSLz48Yj5Hb2FsIDwvYj48eHNsOnRleHQ+WzwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0eXBlIi8+Ci0gICAgPHhzbDp0ZXh0Pl06IDwveHNsOnRleHQ+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotCi0gIDx4c2w6dGVtcGxhdGUgbmFtZT0iZGV2ZWxvcGVyLWxpc3QiPgotICAgIDxIMz4KLSAgICAgIDx4c2w6ZWxlbWVudCBuYW1lPSJhIj4KLSAgICAgICAgPHhzbDphdHRyaWJ1dGUgbmFtZT0ibmFtZSI+ZGV2ZWxvcGVyLWxpc3Q8L3hzbDphdHRyaWJ1dGU+Ci0gICAgICAgIDx4c2w6dGV4dD5EZXZlbG9wZXJzOjwveHNsOnRleHQ+Ci0gICAgICA8L3hzbDplbGVtZW50PgotICAgIDwvSDM+Ci0gICAgPHA+QSBsaXN0IG9mIHNvbWUgb2YgcGVvcGxlIGN1cnJlbnRseSB3b3JraW5nIG9uIHdvcmtpbmcgb24gPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii90b2RvL0Bwcm9qZWN0Ii8+OjwvcD4KLSAgICA8dWw+Ci0gICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9ImRldnMvcGVyc29uIj4KLSAgICAgIDxsaT4KLSAgICAgICAgPGEgaHJlZj0ibWFpbHRvOntAZW1haWx9Ij4KLSAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQG5hbWUiLz4KLSAgICAgICAgPC9hPgotICAgICAgICAgPHhzbDplbGVtZW50IG5hbWU9ImEiPgotICAgICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJuYW1lIj48eHNsOnRleHQ+cGVyc29ucmVmLTwveHNsOnRleHQ+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBpZCIvPjwveHNsOmF0dHJpYnV0ZT4KLSAgICAgICAgICAgPHhzbDp0ZXh0PiAoPC94c2w6dGV4dD48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGlkIi8+PHhzbDp0ZXh0Pik8L3hzbDp0ZXh0PgotICAgICAgICAgPC94c2w6ZWxlbWVudD4KLSAgICAgICAgIDxCUi8+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz4KLSAgICAgIDwvbGk+Ci0gICAgPC94c2w6Zm9yLWVhY2g+Ci0gICAgPC91bD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+CmRpZmYgLS1naXQgYS90cmF4X2J1Z3MueG1sIGIvdHJheF9idWdzLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2I2ZjljNS4uMDAwMDAwMAotLS0gYS90cmF4X2J1Z3MueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNTMgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08P3htLXdlbGxfZm9ybWVkIHBhdGg9IkU6XHhtbC14YWxhblxqYXZhXGJ1Z3MuZHRkIj8+Ci08IS0tIFRoaXMgc2hvdWxkIGNvbnRhaW4gKm9ubHkqIFNQUnMgKFNvZnR3YXJlIFByb2JsZW0gUmVwb3J0cykgZm9yIHRoZSBUckFYIEFQSSAKLSAgICAgaW50ZXJmYWNlcyBhbmQgY2xhc3Nlcy4gLS0+Ci08U3Bycz48U3ByPjxOYW1lPlRSQVhTUFIwMDAxPC9OYW1lPgotPERhdGVDcmVhdGVkPjExLzE1LzIwMDA8L0RhdGVDcmVhdGVkPgotPFN0YXRlPk9wZW48L1N0YXRlPgotPFRlc3REZXNjPlNBWFRyYW5zZm9ybWVyRmFjdG90eSNGRUFUVVJFIHNob3VsZCBkb2N1bWVudCBzdXBwb3J0IGZvciBhbGwgVHJhbnNmb3JtZXJGYWN0b3JpZXMuPC9UZXN0RGVzYz48RGV0YWlscz48IVtDREFUQVtJbiBTQVhUcmFuc2Zvcm1lckZhY3RvdHk6Ci0KLSAgICAvKiogSWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9Ci0gICAgICogcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCi0gICAgICogdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSByZXR1cm5lZCBmcm9tCi0gICAgICoge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I25ld0luc3RhbmNlfSBtYXkKLSAgICAgKiBiZSBzYWZlbHkgY2FzdCB0byBhIFNBWFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgKi8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGRUFUVVJFID0KLQotSSBwcm9wb3NlIHlvdSByZW1vdmUgdGhlIHBocmFzZSAicmV0dXJuZWQgZnJvbQotVHJhbnNmb3JlckZhY3RvcnkubmV3SW5zdGFuY2UiLiBJc24ndCB0aGUgaW50ZW50IHRoYXQgZmVhdHVyZSB0ZXN0aW5nCi1jYW4gYmUgZG9uZSBvbiBhbGwgVHJhbnNmb3JtZXJGYWN0b3JpZXMsIHJlZ2FyZGxlc3MgaG93IHRoZXkgYXJlCi1jcmVhdGVkPyBJdCBjYW4gYmUgbGlrZSB0aGlzIGluc3RlYWQ6Ci0KLSAgICAvKiogSWYge0BsaW5rIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5I2dldEZlYXR1cmV9Ci0gICAgICogcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIHRoaXMgdmFsdWUgYXMgYW4gYXJndW1lbnQsCi0gICAgICogdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBjYW4gYmUgc2FmZWx5IGNhc3QgdG8gYQotICAgICAqIFNBWFRyYW5zZm9ybWVyRmFjdG9yeS4KLSAgICAgKi9dXT48L0RldGFpbHM+PC9TcHI+PFNwcj48TmFtZT5UUkFYU1BSMDAwMjwvTmFtZT4KLTxEYXRlQ3JlYXRlZD4xMS8xNS8yMDAwPC9EYXRlQ3JlYXRlZD4KLTxTdGF0ZT5PcGVuPC9TdGF0ZT4KLTxUZXN0RGVzYz5PdXRwdXRLZXlzI21ldGhvZCBzaG91bGQgZG9jdW1lbnQgcW5hbWUgaW5zdGVhZCBvZiBxbmFtZS1idXQtbm90LW5jbmFtZTwvVGVzdERlc2M+PERldGFpbHM+PCFbQ0RBVEFbSW4gT3V0cHV0S2V5czoKLQotICAgIC8qKgotICAgICAqIG1ldGhvZCA9ICJ4bWwiIHwgImh0bWwiIHwgInRleHQiIHwgPHZhcj5xbmFtZS1idXQtbm90LW5jbmFtZTwvdmFyPi4KLSAgICAgKgotICAgICAqIDxwPlRoZSBtZXRob2QgYXR0cmlidXRlIGlkZW50aWZpZXMgdGhlIG92ZXJhbGwgbWV0aG9kIHRoYXQKLSAgICAgKiBzaG91bGQgYmUgdXNlZCBmb3Igb3V0cHV0dGluZyB0aGUgcmVzdWx0IHRyZWUuICBPdGhlcgotICAgICAqIG5vbi1uYW1lc3BhY2VkIHZhbHVlcyBtYXkgYmUgdXNlZCwKLQotVGhpcyBpcyBjb250cmFkaWN0YXJ5LCBjaGFuZ2UgInFuYW1lLWJ1dC1ub3QtbmNuYW1lIiB0byAicW5hbWUiLl1dPjwvRGV0YWlscz48L1Nwcj4KLTxTcHI+PE5hbWU+VFJBWFNQUjAwMDM8L05hbWU+Ci08RGF0ZUNyZWF0ZWQ+MTEvMTUvMjAwMDwvRGF0ZUNyZWF0ZWQ+Ci08U3RhdGU+T3BlbjwvU3RhdGU+Ci08VGVzdERlc2M+PC9UZXN0RGVzYz48RGV0YWlscz48IVtDREFUQVtdXT48L0RldGFpbHM+PC9TcHI+Ci08U3ByPjxOYW1lPlRSQVhTUFIwMDA0PC9OYW1lPgotPERhdGVDcmVhdGVkPjExLzE1LzIwMDA8L0RhdGVDcmVhdGVkPgotPFN0YXRlPk9wZW48L1N0YXRlPgotPFRlc3REZXNjPjwvVGVzdERlc2M+PERldGFpbHM+PCFbQ0RBVEFbXV0+PC9EZXRhaWxzPjwvU3ByPgotPFNwcj48TmFtZT5UUkFYU1BSMDAwNTwvTmFtZT4KLTxEYXRlQ3JlYXRlZD4xMS8xNS8yMDAwPC9EYXRlQ3JlYXRlZD4KLTxTdGF0ZT5PcGVuPC9TdGF0ZT4KLTxUZXN0RGVzYz48L1Rlc3REZXNjPjxEZXRhaWxzPjwhW0NEQVRBW11dPjwvRGV0YWlscz48L1Nwcj4KLQotPC9TcHJzPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy9kZXNpZ24vY29tcGlsYXRpb24uZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24vY29tcGlsYXRpb24uZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2NzVkN2Q0Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL2NvbXBpbGF0aW9uLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL2NvbmNlcHR1YWwuZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24vY29uY2VwdHVhbC5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDI4M2ZlZTUuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy9kZXNpZ24vY29uY2VwdHVhbC5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL2Rlc2lnbi9kYXRhLmdpZiBiL3hkb2NzL3NvdXJjZXMvZGVzaWduL2RhdGEuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZjI4YTE3Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL2RhdGEuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy9kZXNpZ24vZGVzaWduMl8wXzAueG1sIGIveGRvY3Mvc291cmNlcy9kZXNpZ24vZGVzaWduMl8wXzAueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMmRkNTA5Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL2Rlc2lnbjJfMF8wLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDI3NyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotPHMxIHRpdGxlPSJYYWxhbi1KIDIuMCBEZXNpZ24iPgotICA8cD48aW1nIHNyYz0ieG1sbG9nby5naWYiIGFsdD0ieG1sbG9nby5naWYiLz48L3A+Ci0gIDxwPkF1dGhvcjogU2NvdHQgQm9hZzxici8+U3RhdGU6IEluIFByb2dyZXNzPC9wPgotICA8dWw+IAotCSAgIDxsaT48bGluayBhbmNob3I9ImludHJvIj5JbnRyb2R1Y3Rpb248L2xpbms+PC9saT4KLSAJICAgPGxpPjxsaW5rIGFuY2hvcj0icmVxdWlyZW1lbnRzIj5YYWxhbiBSZXF1aXJlbWVudHM8L2xpbms+PC9saT4KLQkgICA8bGk+PGxpbmsgYW5jaG9yPSJvdmVyYXJjaCI+T3ZlcnZpZXcgb2YgQXJjaGl0ZWN0dXJlPC9saW5rPjwvbGk+Ci0JICAgPGxpPjxsaW5rIGFuY2hvcj0icHJvY2VzcyI+UHJvY2VzcyBNb2R1bGU8L2xpbms+PC9saT4KLQkgICA8bGk+PGxpbmsgYW5jaG9yPSJ0ZW1wbGF0ZXMiPlRlbXBsYXRlcyBNb2R1bGU8L2xpbms+PC9saT4KLQkgICA8bGk+PGxpbmsgYW5jaG9yPSJ0cmFuc2Zvcm1lciI+VHJhbnNmb3JtZXIgTW9kdWxlPC9saW5rPjwvbGk+Ci0gICAgICAgPHVsPgotICAgICAgICAgPGxpPjxsaW5rIGFuY2hvcj0ic3RyZWUiPlN0cmVlIE1vZHVsZTwvbGluaz48L2xpPgotICAgICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZXh0ZW5zaW9ucyI+RXh0ZW5zaW9ucyBNb2R1bGU8L2xpbms+PC9saT4KLSAgICAgPC91bD4KLQkgICA8bGk+PGxpbmsgYW5jaG9yPSJ4cGF0aCI+WFBhdGggTW9kdWxlPC9saW5rPjwvbGk+Ci0gICAgICAgPHVsPjxsaT48bGluayBhbmNob3I9InhwYXRoZGJjb25uIj5YUGF0aCBEYXRhYmFzZSBDb25uZWN0aW9uPC9saW5rPjwvbGk+PC91bD4KLQkgICA8bGk+PGxpbmsgYW5jaG9yPSJ1dGlscyI+VXRpbHMgUGFja2FnZTwvbGluaz48L2xpPiAgICAgICAgIAotCSAgIDxsaT48bGluayBhbmNob3I9Im90aGVyIj5PdGhlciBQYWNrYWdlczwvbGluaz48L2xpPiAgICAgICAgIAotCSAgIDxsaT48bGluayBhbmNob3I9ImNvbXBpbGF0aW9uIj5YYWxhbiBTdHlsZXNoZWV0IENvbXBsaWxhdGlvbiB0byBKYXZhPC9saW5rPjwvbGk+PGxpPjxsaW5rIGFuY2hvcj0ib3B0aW1pemF0aW9ucyI+RnV0dXJlIE9wdGltaXphdGlvbnM8L2xpbms+PC9saT48bGk+PGxpbmsgYW5jaG9yPSJjb2RpbmciPkNvZGluZyBDb252ZW50aW9uczwvbGluaz48L2xpPgotCSAgICAgICAgCi0gICA8bGk+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9pbmRleC5odG1sIj5YYWxhbi1KIDIuMCBKYXZhZG9jPC9qdW1wPjwvbGk+Ci0gIDwvdWw+PGFuY2hvciBuYW1lPSJpbnRybyIvPgotICA8czIgdGl0bGU9IkludHJvZHVjdGlvbiI+IAotCSA8cD5UaGlzIGRvY3VtZW50IHByZXNlbnRzIHRoZSBiYXNpYyBkZXNpZ24gZm9yIFhhbGFuLUogMi4wLCB3aGljaCBpcyBhCi0JCTxqdW1wIGhyZWY9Imh0dHA6Ly93d3cuYXdsLmNvbS9jc2VuZy90aXRsZXMvMC0yMDEtODk1NDItMC90ZWNobmlxdWVzL3JlZmFjdG9yaW5nLmh0bSI+cmVmYWN0b3Jpbmc8L2p1bXA+Ci0JCWFuZCByZWRlc2lnbiBvZiB0aGUgWGFsYW4tSiAxLnggcHJvY2Vzc29yLiAgIFRoaXMgZG9jdW1lbnQgd2lsbCBleHBhbmQgYW5kIGdyb3cgb3ZlciB0aW1lLCBhbmQgaXMgYWxzbyBpbmNvbXBsZXRlIGluIHNvbWUgc2VjdGlvbnMsIHRob3VnaCBob3BlZnVsbHkgb3ZlcmFsbCBhY2N1cmF0ZS4gIFRoZSByZWFkZXIgc2hvdWxkIGJlIGFibGUgdG8gZ2V0IGEgZ29vZCBvdmVyYWxsIGlkZWEgb2YgdGhlIGludGVybmFsIGRlc2lnbiBvZiBYYWxhbiwgYW5kIGJlZ2luIHRvIHVuZGVyc3RhbmQgdGhlIHByb2Nlc3MgZmxvdywgYW5kIGFsc28gdGhlIHRlY2huaWNhbCBjaGFsbGVuZ2VzLjwvcD4gCi0JIDxwPlRoZSBtYWluIGdvYWxzIG9mIHRoaXMgcmVkZXNpZ24gYXJlCi0JCXRvOiA8L3A+PG9sPiAKLQkJPGxpPk1ha2UgdGhlIGRlc2lnbiBhbmQgY29kZSBtb3JlIHVuZGVyc3RhbmRhYmxlIGJ5IE9wZW4gU291cmNlCi0JCSAgcGVvcGxlLjwvbGk+IAotCQk8bGk+UmVkdWNlIGNvZGUgc2l6ZSBhbmQgY29tcGxleGl0eS48L2xpPgotCQk8bGk+Qnkgc2ltcGxpZnlpbmcgdGhlIGNvZGUsIG1ha2Ugb3B0aW1pemF0aW9uIGVhc2llci48L2xpPiAKLQkJPGxpPk1ha2UgbW9kdWxlcyBnZW5lcmFsbHkgbW9yZSBsb2NhbGl6ZWQsIGFuZCBsZXNzIHRhbmdsZWQgd2l0aCBvdGhlcgotCQkgIG1vZHVsZXMuPC9saT4gCi0JCTxsaT5Db25mb3JtIHRvIHRoZSA8anVtcCBocmVmPSJodHRwOi8vamF2YS5zdW4uY29tL2Fib3V0SmF2YS9jb21tdW5pdHlwcm9jZXNzL2pzci9qc3JfMDYzX2pheHAxMS5odG1sIj5qYXZheC54bWwudHJhbnNmb3JtICAoVHJBWCBbVHJhbnNmb3JtYXRpb25zIGZvciBYTUxdKTwvanVtcD4gaW50ZXJmYWNlcy48L2xpPiAKLQkgPGxpPkluY3JlYXNlIHRoZSBhYmlsaXR5IHRvIGluY3JlbWVudGFsbHkgcHJvZHVjZSB0aGUgcmVzdWx0IHRyZWUuPC9saT48L29sPiAKLQkgPHA+VGhlIHRlY2huaXF1ZXMgdXNlZCB0b3dhcmQgdGhlc2UgZ29hbHMgYXJlIHRvOjwvcD4gCi0JIDxvbD4gCi0JCTxsaT5JbiBnZW5lcmFsLCBmbGF0dGVuIHRoZSBoaWVyYXJjaHkgb2YgcGFja2FnZXMsIGluIG9yZGVyIHRvIG1ha2UgdGhlCi0JCSAgc3RydWN0dXJlIG1vcmUgYXBwYXJlbnQgZnJvbSB0aGUgdG9wLWxldmVsIHZpZXcuPC9saT4gCi0JCTxsaT5CcmVhayB0aGUgY29uc3RydWN0aW9uIGFuZCB0aGUgdmFsaWRhdGlvbiBvZiB0aGUgWFNMVCBzdHlsZXNoZWV0IGZyb20KLQkJICB0aGUgc3R5bGVzaGVldCBvYmplY3RzIHRoZW1zZWx2ZXMuPC9saT4KLQkJPGxpPkRyaXZlIHRoZSBjb25zdHJ1Y3Rpb24gb2YgdGhlIHN0eWxlc2hlZXQgdGhyb3VnaCBhIHRhYmxlLCBzbyB0aGF0IGl0Ci0JCSAgaXMgbGVzcyBwcm9uZSB0byBlcnJvci48L2xpPiAKLQkJPGxpPkJyZWFrIHRoZSB0cmFuc2Zvcm1hdGlvbiBwcm9jZXNzIGludG8gYSBzZXBhcmF0ZSBwYWNrYWdlLCBhd2F5IGZyb20KLQkJICB0aGUgc3R5bGVzaGVldCBvYmplY3RzLjwvbGk+IAotCQk8bGk+Q3JlYXRlIHRoaXMgZGVzaWduIGRvY3VtZW50LCBhcyBhIHN0YXJ0aW5nIHBvaW50IGZvciBwZW9wbGUgaW50ZXJlc3RlZCBpbgotCQkgIGFwcHJvYWNoaW5nIHRoZSBjb2RlLjwvbGk+IAotCSA8L29sPiAKLQkgPHA+VGhlIGdvYWxzIGFyZSBub3Q6PC9wPiAKLQkgPG9sPiAKLQkJPGxpPlRvIGFkZCBtb3JlIGZlYXR1cmVzIGluIHRoZSBwcm9ncmVzcyBvZiB0aGlzIHJlZmFjdG9yaW5nLiBUaGlzIGlzCi0JCSAgZGVzaWduIGFuZCBjb2RlIGNsZWFuLXVwIGluIG9yZGVyIHRvIG1lZXQgdGhlIGFib3ZlLW5hbWVkIGdvYWxzLiBXZSBleHBlY3QgdGhhdCBpdCB3aWxsIGJlIDxlbT5tdWNoPC9lbT4gZWFzaWVyIHRvIGFkZAotCQkgIGZlYXR1cmVzIG9uY2UgdGhpcyB3b3JrIGlzIGNvbXBsZXRlZC48L2xpPiAKLQkJPGxpPlRvIG9wdGltaXplIGNvZGUgZm9yIHRoZSBzYWtlIG9mIG9wdGltaXphdGlvbi4gSG93ZXZlciwgd2UKLQkJICBleHBlY3QgdGhhdCB0aGUgY29kZSB3aWxsIGJlIGZhc3RlciBvbmNlIHRoaXMgd29yayBpcyBjb21wbGV0ZS48L2xpPiAKLQkgPC9vbD4gCi0JIDxwPkhvdyB3ZWxsIHdlJ3ZlIGFjaGlldmVkIHRoZSBnb2FscyB3aWxsIGJlIG1lYXN1cmVkIGJ5IGZlZWRiYWNrIGZyb20gdGhlCi0JCTxqdW1wIGhyZWY9Imh0dHA6Ly9hcmNoaXZlLmNvdmFsZW50Lm5ldC8iPlhhbGFuLWRldjwvanVtcD4gbGlzdCwgYW5kIGJ5IHNvZnR3YXJlIG1ldHJpY3MgdG9vbHMuPC9wPiAKLQkgPHA+UGxlYXNlIG5vdGUgdGhhdCB0aGUgZGlhZ3JhbXMgaW4gdGhpcyBkZXNpZ24gZG9jdW1lbnQgYXJlIG1lYW50IHRvIGJlCi0JCXVzZWZ1bCBhYnN0cmFjdGlvbnMsIGFuZCBtYXkgbm90IGFsd2F5cyBiZSBleGFjdC48L3A+IAotICA8L3MyPjxhbmNob3IgbmFtZT0icmVxdWlyZW1lbnRzIi8+IAotICA8czIgdGl0bGU9IlhhbGFuIFJlcXVpcmVtZW50cyI+Ci0gIDxwPlRoZXNlIGFyZSB0aGUgY29uY3JldGUgZ2VuZXJhbCByZXF1aXJlbWVudHMgb2YgWGFsYW4sIGFzIEkgdW5kZXJzdGFuZCB0aGVtLCBhbmQgY292ZXJpbmcgYm90aCB0aGUgSmF2YSBhbmQgQysrIHZlcnNpb25zLiAgVGhlc2UgcmVxdWlyZW1lbnRzIGhhdmUgYmVlbiBidWlsdCB1cCBvdmVyIHRpbWUgYnkgZXhwZXJpZW5jZSB3aXRoIHByb2R1Y3QgZ3JvdXBzIGFuZCBnZW5lcmFsIHVzZXJzLjwvcD48b2w+PGxpPkphdmEsIEMrKyBWZXJzaW9ucy48L2xpPjxsaT5YU0xUIDEuMCBjb25mb3JtYW5jZSwgYW5kIGJleW9uZC4gKGkuZS4gY29uZm9ybSB0byB0aGUgY3VycmVudCBXM0MgcmVjb21tZW5kYXRpb24pLjwvbGk+PGxpPkhhdmUgZGVzaWduIGFuZCBDb2RlIHVuZGVyc3RhbmRhYmxlIGJ5IE9wZW4gU291cmNlIENvbW11bml0eS48L2xpPjxsaT5BYmlsaXR5IHRvIGludGVyb3BlcmF0ZSB3aXRoIHN0YW5kYXJkIEFQSXMuICAoU0FYMiwgRE9NMiwgSkFYUCkgIFt0aGlzIGlzIGN1cnJlbnRseSBMZXNzIG9mIGFuIGlzc3VlIHdpdGggQysrXS48L2xpPjxsaT5IaWdoIFBlcmZvcm1hbmNlIChSYXcgcGVyZm9ybWFuY2UsIEluY3JlbWVudGFsIGFiaWxpdHksIFNjYWxlYWJpbGl0eSB0byBsYXJnZSBkb2N1bWVudHMsIFJlZHVjdGlvbiBvZiBHYXJiYWdlIENvbGxlY3Rpb24gZm9yIHRoZSBKYXZhIHZlcnNpb24uKTwvbGk+PGxpPlRvb2xpbmcgQVBJIChBY2Nlc3Mgc3R5bGVzaGVldCBkYXRhIHN0cnVjdHVyZXMsIEFjY2VzcyBzb3VyY2Ugbm9kZSBmcm9tIHJlc3VsdCBldmVudCwgQXNrIHJ1bnRpbWUgcXVlc3Rpb25zLCBEZWJ1Z2dpbmcgQVBJKS48L2xpPjxsaT5TdXBwb3J0IGFkZHJlc3Npbmcgb2YgWE1MIGluIHN0YW5kYWxvbmUgZmFzaGlvbiAoaS5lLiBYUGF0aCBBUEkpLjwvbGk+PGxpPkV4dGVuc2liaWxpdHkgKEFiaWxpdHkgdG8gY2FsbCBKYXZhLCBBYmlsaXR5IHRvIGNhbGwgSmF2YVNjcmlwdCwgb3RoZXIgbGFuZ3VhZ2VzKS48L2xpPjxsaT5NdWx0aXBsZSBkYXRhIHNvdXJjZXMgKEpEQkMsIExEQVAsIG90aGVyIGRhdGEgc291cmNlcywgRGlyZWN0IFhNTCByZXBvc2l0b3J5IGNvdXBsaW5nKS48L2xpPjwvb2w+PC9zMj48YW5jaG9yIG5hbWU9Im92ZXJhcmNoIi8+IAotICA8czIgdGl0bGU9Ik92ZXJ2aWV3IG9mIEFyY2hpdGVjdHVyZSI+IAotCSA8cD5UaGUgZm9sbG93aW5nIGRpYWdyYW0gc2hvd3MgdGhlIFhTTFQgYWJzdHJhY3QgcHJvY2Vzc2luZyBtb2RlbC4gIEEgdHJhbnNmb3JtYXRpb24gZXhwcmVzc2VkIGluIFhTTFQgZGVzY3JpYmVzIHJ1bGVzIGZvciB0cmFuc2Zvcm1pbmcgYSA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsIj5Tb3VyY2UgVHJlZSA8L2p1bXA+IGludG8gYSByZXN1bHQgdHJlZS4gVGhlIHRyYW5zZm9ybWF0aW9uIGlzIGFjaGlldmVkIGJ5IGFzc29jaWF0aW5nIHBhdHRlcm5zIHdpdGggdGVtcGxhdGVzLiBBIHBhdHRlcm4gaXMgbWF0Y2hlZCBhZ2FpbnN0IGVsZW1lbnRzIGluIHRoZSBzb3VyY2UgdHJlZS4gQSB0ZW1wbGF0ZSBpcyBpbnN0YW50aWF0ZWQgdG8gY3JlYXRlIHBhcnQgb2YgdGhlIHJlc3VsdCB0cmVlLiBUaGUgcmVzdWx0IHRyZWUgaXMgc2VwYXJhdGUgZnJvbSB0aGUgc291cmNlIHRyZWUuIFRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHJlc3VsdCB0cmVlIGNhbiBiZSBjb21wbGV0ZWx5IGRpZmZlcmVudCBmcm9tIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHNvdXJjZSB0cmVlLiBJbiBjb25zdHJ1Y3RpbmcgdGhlIHJlc3VsdCB0cmVlLCBlbGVtZW50cyBmcm9tIHRoZSBzb3VyY2UgdHJlZSBjYW4gYmUgZmlsdGVyZWQgYW5kIHJlb3JkZXJlZCwgYW5kIGFyYml0cmFyeSBzdHJ1Y3R1cmUgY2FuIGJlIGFkZGVkLgotCi08L3A+PHA+VGhlIHRlcm0gInRyZWUiLCBhcyB1c2VkIHdpdGhpbiB0aGlzIGRvY3VtZW50LCBkZXNjcmliZXMgYW4KLQkJCSBhYnN0cmFjdCBzdHJ1Y3R1cmUgdGhhdCBjb25zaXN0cyBvZiBub2RlcyBvciBldmVudHMgdGhhdCBtYXkgYmUgcHJvZHVjZWQgYnkKLQkJCSBYTUwuIEEgVHJlZSBwaHlzaWNhbGx5IG1heSBiZSBhIERPTSB0cmVlLCBhIHNlcmllcyBvZiB3ZWxsIGJhbGFuY2VkIHBhcnNlCi0JCQkgZXZlbnRzIChzdWNoIGFzIHRob3NlIGNvbWluZyBmcm9tIGEgU0FYMiBDb250ZW50SGFuZGVyKSwgYSBzZXJpZXMgb2YgcmVxdWVzdHMKLQkJCSAodGhlIHJlc3VsdCBvZiB3aGljaCBjYW4gZGVzY3JpYmUgYSB0cmVlKSwgb3IgYSBzdHJlYW0gb2YgbWFya2VkLXVwCi0JCQkgY2hhcmFjdGVycy48L3A+PHA+PGltZyBzcmM9InhzbHRfYWJzdHJhY3QuZ2lmIiBhbHQ9InhzbHRfYWJzdHJhY3QuZ2lmIi8+PC9wPjxwPlRoZSBwcmltYXJ5IGludGVyZmFjZSBmb3IgWGFsYW4gMi4wIGV4dGVybmFsIHVzYWdlIGlzIGRlZmluZWQgaW4gdGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9wYWNrYWdlLXN1bW1hcnkuaHRtbCNwYWNrYWdlX2Rlc2NyaXB0aW9uIj5qYXZheC54bWwudHJhbnNmb3JtPC9qdW1wPiBpbnRlcmZhY2VzLiAgVGhlc2UgaW50ZXJmYWNlcyBkZWZpbmUgYSBzdGFuZGFyZCBhbmQgcG93ZXJmdWwgaW50ZXJmYWNlIHRvIHBlcmZvcm0gdHJlZS1iYXNlZCB0cmFuc2Zvcm1hdGlvbnMuPC9wPiAKLQkgPHA+VGhlIGludGVybmFsIGFyY2hpdGVjdHVyZSBvZiBYYWxhbiAyLjAgaXMgZGl2aWRlZCBpbnRvIGZvdXIgbWFqb3IgbW9kdWxlcywgYW5kIHZhcmlvdXMgc21hbGxlcgotCQltb2R1bGVzLiBUaGUgbWFpbiBtb2R1bGVzIGFyZTo8L3A+IAotCSA8Z2xvc3M+IAotCQk8bGFiZWw+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3I8L2p1bXA+PC9sYWJlbD4gCi0JCTxpdGVtPlRoZSBtb2R1bGUgdGhhdCBwcm9jZXNzZXMgdGhlIHN0eWxlc2hlZXQsIGFuZCBwcm92aWRlcyB0aGUgbWFpbgotCQkgIGVudHJ5IHBvaW50IGludG8gWGFsYW4uPC9pdGVtPiAKLQkgPC9nbG9zcz4gCi0JIDxnbG9zcz4gCi0JCTxsYWJlbD48anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczwvanVtcD48L2xhYmVsPiAKLQkJPGl0ZW0+VGhlIG1vZHVsZSB0aGF0IGRlZmluZXMgdGhlIHN0eWxlc2hlZXQgc3RydWN0dXJlcywgaW5jbHVkaW5nIHRoZQotCQkgIFN0eWxlc2hlZXQgb2JqZWN0LCB0ZW1wbGF0ZSBlbGVtZW50IGluc3RydWN0aW9ucywgYW5kIEF0dHJpYnV0ZSBWYWx1ZQotCQkgIFRlbXBsYXRlcy4gPC9pdGVtPiAKLQkgPC9nbG9zcz4gCi0JIDxnbG9zcz4gCi0JCTxsYWJlbD48anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPm9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXI8L2p1bXA+PC9sYWJlbD4gCi0JCTxpdGVtPlRoZSBtb2R1bGUgdGhhdCBhcHBsaWVzIHRoZSBzb3VyY2UgdHJlZSB0byB0aGUgVGVtcGxhdGVzLCBhbmQKLQkJICBwcm9kdWNlcyBhIHJlc3VsdCB0cmVlLjwvaXRlbT4gCi0JIDwvZ2xvc3M+IAotCSA8Z2xvc3M+IAotCQk8bGFiZWw+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hwYXRoL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5vcmcuYXBhY2hlLnhwYXRoPC9qdW1wPjwvbGFiZWw+IAotCQk8aXRlbT5UaGUgbW9kdWxlIHRoYXQgcHJvY2Vzc2VzIGJvdGggWFBhdGggZXhwcmVzc2lvbnMsIGFuZCBYU0xUIE1hdGNoCi0JCSAgcGF0dGVybnMuPC9pdGVtPiAKLQkgPC9nbG9zcz4gCi0JIDxwPkluIGFkZGl0aW9uIHRvIHRoZSBhYm92ZSBtb2R1bGVzLCBYYWxhbiBpbXBsZW1lbnRzIHRoZQotCQk8anVtcCBocmVmPSIuLi9hcGlkb2NzL2phdmF4L3htbC90cmFuc2Zvcm0vcGFja2FnZS1zdW1tYXJ5Lmh0bWwjcGFja2FnZV9kZXNjcmlwdGlvbiI+amF2YXgueG1sLnRyYW5zZm9ybTwvanVtcD4gaW50ZXJmYWNlcywgYW5kIGRlcGVuZHMgb24gdGhlCi0JIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cubWVnZ2luc29uLmNvbS9TQVgvSmF2YS9pbmRleC5odG1sIj5TQVgyPC9qdW1wPiBhbmQgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTIvIj5ET008L2p1bXA+IHBhY2thZ2VzLgotPC9wPjxwPjxpbWcgc3JjPSJ0cmF4LmdpZiIgYWx0PSJ0cmF4LmdpZiIvPjwvcD48cD5UaGVyZSBpcyBhbHNvIGEgZ2VuZXJhbCB1dGlsaXRpZXMgcGFja2FnZSB0aGF0IGNvbnRhaW5zIGJvdGggWE1MIHV0aWxpdHkKLQkgY2xhc3NlcyBzdWNoIGFzIFFOYW1lLCBidXQgZ2VuZXJhbGx5IHVzZWZ1bCBjbGFzc2VzIHN1Y2ggYXMKLQkgU3RyaW5nVG9JbnRUYWJsZS48L3A+IAotCSA8cD5JbiB0aGUgZGlhZ3JhbSBiZWxvdywgdGhlIGRhc2hlZCBsaW5lcyBkZW5vdGUgdmlzaWJpbGl0eS4gQWxsIHBhY2thZ2VzCi0JCWFjY2VzcyB0aGUgU0FYMiBhbmQgRE9NIHBhY2thZ2VzLjwvcD4gCi0JIDxwPjxpbWcgc3JjPSJ4YWxhbjFfMXgxLmdpZiIgYWx0PSJ4YWxhbjFfMXgxLmdpZiIvPjwvcD4gCi0JIDxwPkluIGFkZGl0aW9uIHRvIHRoZSBhYm92ZSBwYWNrYWdlcywgdGhlcmUgYXJlIHRoZSBmb2xsb3dpbmcgYWRkaXRpb25hbAotCQlwYWNrYWdlczo8L3A+IAotCSA8Z2xvc3M+IAotCQk8bGFiZWw+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2NsaWVudC9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5jbGllbnQ8L2p1bXA+PC9sYWJlbD4gCi0JCTxpdGVtPlRoaXMgcGFja2FnZSBoYXMgYSBjbGllbnQgYXBwbGV0LiBJIHN1c3BlY3QgdGhpcyBzaG91bGQgYmUgbW92ZWQKLQkJICBpbnRvIHRoZSBzYW1wbGVzIGRpcmVjdG9yeS48L2l0ZW0+IAotCSA8L2dsb3NzPiAKLQkgPGdsb3NzPiAKLQkJPGxhYmVsPjxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnM8L2p1bXA+PC9sYWJlbD4gCi0JCTxpdGVtPlRoaXMgaG9sZHMgY2xhc3NlcyBiZWxvbmdpbmcgdG8gdGhlIFhhbGFuIGV4dGVuc2lvbnMgbWVjaGFuaXNtLAotCQkgIHdoaWNoIGFsbG93cyBKYXZhIGNvZGUgYW5kIHNjcmlwdCB0byBiZSBjYWxsZWQgZnJvbSB3aXRoaW4gYSBzdHlsZXNoZWV0LjwvaXRlbT4KLQkJCi0JIDwvZ2xvc3M+IAotCSA8Z2xvc3M+IAotCQk8bGFiZWw+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5saWI8L2p1bXA+PC9sYWJlbD4gCi0JCTxpdGVtPlRoaXMgaXMgdGhlIGJ1aWx0LWluIFhhbGFuIGV4dGVuc2lvbnMgbGlicmFyeSwgd2hpY2ggaG9sZHMKLQkJICBleHRlbnNpb25zIHN1Y2ggYXMgUmVkaXJlY3QgKHdoaWNoIGFsbG93cyBhIHN0eWxlc2hlZXQgdG8gcHJvZHVjZSBtdWx0aXBsZQotCQkgIG91dHB1dCBmaWxlcykuPC9pdGVtPiAKLQkgPC9nbG9zcz4gCi0JIDxnbG9zcz4gCi0JCTxsYWJlbD48anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vcmVzL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnJlczwvanVtcD48L2xhYmVsPiAKLQkJPGl0ZW0+VGhpcyBob2xkcyByZXNvdXJjZSBmaWxlcyBuZWVkZWQgYnkgWGFsYW4sIHN1Y2ggYXMgZXJyb3IgbWVzc2FnZQotCQkgIHJlc291cmNlcy48L2l0ZW0+IAotCSA8L2dsb3NzPiAKLQkgIAotCSA8Z2xvc3M+IAotCQk8bGFiZWw+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnRyYWNlPC9qdW1wPjwvbGFiZWw+IAotCQk8aXRlbT5UaGlzIHBhY2thZ2UgY29udGFpbnMgY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyB0aGF0IGFsbG93IGEgY2FsbGVyIHRvCi0JCSAgYWRkIHRyYWNlIGxpc3RlbmVycyB0byB0aGUgdHJhbnNmb3JtYXRpb24sIGFsbG93aW5nIGFuIGludGVyZmFjZSB0byBYU0xUCi0JCSAgZGVidWdnZXJzIGFuZCBzaW1pbGFyIHRvb2xzLjwvaXRlbT4gCi0JIDwvZ2xvc3M+IAotCSA8Z2xvc3M+IAotCQk8bGFiZWw+PGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ueHNsdDwvanVtcD48L2xhYmVsPiAKLQkJPGl0ZW0+VGhpcyBwYWNrYWdlIGhvbGRzIHRoZSBYYWxhbjIgY29tbWFuZCBsaW5lIHByb2Nlc3Nvci48L2l0ZW0+IAotCSA8L2dsb3NzPiAKLSAgPHA+QSBtb3JlIGNvbmNlcHR1YWwgdmlldyBvZiB0aGlzIGFyY2hpdGVjdHVyZSBpcyBhcyBmb2xsb3dzOjwvcD48cD48aW1nIHNyYz0iY29uY2VwdHVhbC5naWYiIGFsdD0iUGljdHVyZSBvZiBjb25jZXB0dWFsIGFyY2hpdGVjdHVyZS4iLz48L3A+PC9zMj48YW5jaG9yIG5hbWU9InByb2Nlc3MiLz4gCi0gIDxzMiB0aXRsZT0iUHJvY2VzcyBNb2R1bGUiPiAKLQkgPHA+VGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yPC9qdW1wPiBtb2R1bGUgaW1wbGVtZW50cyB0aGUKLQkJPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyRmFjdG9yeS5odG1sIj5qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTwvanVtcD4gaW50ZXJmYWNlLCB3aGljaCBwcm92aWRlcyBhCi0JCWZhY3RvcnkgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbmNyZXRlIFByb2Nlc3NvciBpbnN0YW5jZSwgYW5kIHByb3ZpZGVzIG1ldGhvZHMKLQkJZm9yIGNyZWF0aW5nIGEgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RlbXBsYXRlcy5odG1sIj5qYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczwvanVtcD4gaW5zdGFuY2UsIHdoaWNoLCBpbgotCQlYYWxhbiBhbmQgWFNMVCB0ZXJtcywgaXMgdGhlIFN0eWxlc2hlZXQuIFRodXMgdGhlIHRhc2sgb2YgdGhlIHByb2Nlc3MgbW9kdWxlIGlzCi0JCXRvIHJlYWQgdGhlIFhTTFQgaW5wdXQgaW4gdGhlIGZvcm0gb2YgYSBmaWxlLCBzdHJlYW0sIFNBWCBldmVudHMsIG9yIGEgRE9NCi0JCXRyZWUsIGFuZCBwcm9kdWNlIGEgVGVtcGxhdGVzL1N0eWxlc2hlZXQgb2JqZWN0LjwvcD4gCi0JIDxwPlRoZSBvdmVyYWxsIHN0cmF0ZWd5IGlzIHRvIGRlZmluZSBhIHNjaGVtYSBpbiB0aGF0IGRpY3RhdGVzIHRoZSBsZWdhbAotCQlzdHJ1Y3R1cmUgZm9yIFhTTFQgZWxlbWVudHMgYW5kIGF0dHJpYnV0ZXMsIGFuZCB0byBhc3NvY2lhdGUgd2l0aCB0aG9zZQotCQllbGVtZW50cyBjb25zdHJ1Y3Rpb24tdGltZSBwcm9jZXNzb3JzIHRoYXQgY2FuIGZpbGwgaW4gdGhlIGFwcHJvcHJpYXRlIGZpZWxkcwotCQlpbiB0aGUgdG9wLWxldmVsIFN0eWxlc2hlZXQgb2JqZWN0LCBhbmQgYWxzbyBhc3NvY2lhdGUgY2xhc3NlcyBpbiB0aGUgdGVtcGxhdGVzCi0JCW1vZHVsZSB0aGF0IGNhbiBiZSBjcmVhdGVkIGluIGEgZ2VuZXJhbGl6ZWQgZmFzaGlvbi4gVGhpcyBtYWtlcyB0aGUgdmFsaWRhdGlvbgotCQlvYmplY3QtdG8tY2xhc3MgYXNzb2NpYXRpb25zIGNlbnRyYWxpemVkIGFuZCBkZWNsYXJhdGl2ZS48L3A+IAotCSA8cD5UaGUgc2NoZW1hJ3Mgcm9vdCBjbGFzcyBpcwotCQk8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1hTTFRTY2hlbWEuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuWFNMVFNjaGVtYTwvanVtcD4sIGFuZCBpdCBpcyBoZXJlIHRoYXQgdGhlCi0JCVhTTFQgc2NoZW1hIHN0cnVjdHVyZSBpcyBkZWZpbmVkLiBYU0xUU2NoZW1hIHVzZXMKLQkJPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xURWxlbWVudERlZi5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5YU0xURWxlbWVudERlZjwvanVtcD4gdG8gZGVmaW5lIGVsZW1lbnRzLCBhbmQKLQkJPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3Nvci9YU0xUQXR0cmlidXRlRGVmLmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlhTTFRBdHRyaWJ1dGVEZWY8L2p1bXA+IHRvIGRlZmluZSBhdHRyaWJ1dGVzLgotCQlCb3RoIGNsYXNzZXMgaG9sZCB0aGUgYWxsb3dlZCBuYW1lc3BhY2UsIGxvY2FsIG5hbWUsIGFuZCB0eXBlIG9mIGVsZW1lbnQgb3IKLQkJYXR0cmlidXRlLiBUaGUgWFNMVEVsZW1lbnREZWYgYWxzbyBob2xkcyBhIHJlZmVyZW5jZSB0byBhCi0JCTxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IvWFNMVEVsZW1lbnRQcm9jZXNzb3IuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuWFNMVEVsZW1lbnRQcm9jZXNzb3I8L2p1bXA+LCBhbmQgYSBzb21ldGltZXMgYQotCQk8Y29kZT5DbGFzczwvY29kZT4gb2JqZWN0LCB3aXRoIHdoaWNoIGl0IGNhbiBjcmVhdGUgb2JqZWN0cyB0aGF0IGRlcml2ZSBmcm9tCi0JCTxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRlbXBsYXRlRWxlbWVudC5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtVGVtcGxhdGVFbGVtZW50PC9qdW1wPi4gSW4gYWRkaXRpb24sIHRoZQotCQlYU0xURWxlbWVudERlZiBpbnN0YW5jZSBob2xkcyBhIGxpc3Qgb2YgWFNMVEVsZW1lbnREZWYgaW5zdGFuY2VzIHRoYXQgZGVmaW5lCi0JCWxlZ2FsIGVsZW1lbnRzIG9yIGNoYXJhY3RlciBldmVudHMgdGhhdCBhcmUgYWxsb3dlZCBhcyBjaGlsZHJlbiBvZiB0aGUgZ2l2ZW4KLQkJZWxlbWVudC48L3A+IAotCSA8cD5UaGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuaHRtbCI+amF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk8L2p1bXA+Ci0JCWludGVyZmFjZSBpcyBpbiA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbDwvanVtcD4sCi0JCXdoaWNoIGNyZWF0ZXMgYSA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1N0eWxlc2hlZXRIYW5kbGVyLmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlN0eWxlc2hlZXRIYW5kbGVyPC9qdW1wPgotCQlpbnN0YW5jZS4gVGhpcyBpbnN0YW5jZSBhY3RzIGFzIHRoZSBDb250ZW50SGFuZGxlciBmb3IgdGhlIHBhcnNlIGV2ZW50cywgYW5kIGlzCi0JCWhhbmRlZCB0byB0aGUgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcveG1sL3NheC9YTUxSZWFkZXIuaHRtbCI+b3JnLnhtbC5zYXguWE1MUmVhZGVyPC9qdW1wPiwgd2hpY2ggdGhlIFN0eWxlc2hlZXRQcm9jZXNzb3IKLQkJdXNlcyB0byBwYXJzZSB0aGUgWFNMVCBkb2N1bWVudC4gVGhlIDxjb2RlPlN0eWxlc2hlZXRIYW5kbGVyPC9jb2RlPiB0aGVuIHJlY2VpdmVzIHRoZSBwYXJzZQotCQlldmVudHMsIHdoaWNoIG1haW50YWlucyB0aGUgc3RhdGUgb2YgdGhlIGNvbnN0cnVjdGlvbiwgYW5kIHBhc3NlcyB0aGUgZXZlbnRzIG9uCi0JCXRvIHRoZSBhcHByb3ByaWF0ZSA8Y29kZT5YU0xURWxlbWVudFByb2Nlc3NvcjwvY29kZT4gZm9yIHRoZSBnaXZlbiBldmVudCwgYXMgZGljdGF0ZWQgYnkgdGhlCi0JCTxjb2RlPlhTTFRFbGVtZW50RGVmPC9jb2RlPiB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gZXZlbnQuPC9wPiAKLQkgPC9zMj48YW5jaG9yIG5hbWU9InRlbXBsYXRlcyIvPiAKLSAgPHMyIHRpdGxlPSJUZW1wbGF0ZXMgTW9kdWxlIj4gCi0JIDxwPlRoZSA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczwvanVtcD4gbW9kdWxlIGltcGxlbWVudHMgdGhlCi0JCTxqdW1wIGhyZWY9Ii4uL2FwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UZW1wbGF0ZXMuaHRtbCI+amF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM8L2p1bXA+IGludGVyZmFjZSwgYW5kIGRlZmluZXMgYSBzZXQgb2YKLQkJY2xhc3NlcyB0aGF0IHJlcHJlc2VudCBhIFN0eWxlc2hlZXQuIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgdGhpcyBtb2R1bGUgaXMgdG8KLQkJaG9sZCBzdHlsZXNoZWV0IGRhdGEsIG5vdCB0byBwZXJmb3JtIHByb2NlZHVyYWwgdGFza3MgYXNzb2NpYXRlZCB3aXRoIHRoZQotCQljb25zdHJ1Y3Rpb24gb2YgdGhlIGRhdGEsIG5vciB0YXNrcyBhc3NvY2lhdGVkIHdpdGggdGhlIHRyYW5zZm9ybWF0aW9uIGl0c2VsZi4KLQkJPC9wPiAKLQkgPHA+VGhlIGJhc2UgY2xhc3Mgb2YgYWxsIHRlbXBsYXRlcyBvYmplY3RzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBhbiBYU0xUIGVsZW1lbnQgaXMgdGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbVRlbXBsYXRlRWxlbWVudC5odG1sIj5FbGVtVGVtcGxhdGVFbGVtZW50PC9qdW1wPiBvYmplY3QsIHdoaWNoIGluIHR1cm4gaW1wbGVtZW50cyA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveG1sL3V0aWxzL1VuSW1wbE5vZGUuaHRtbCI+VW5JbXBsTm9kZTwvanVtcD4uICBBIDxjb2RlPkVsZW1UZW1wbGF0ZUVsZW1lbnQ8L2NvZGU+IG9iamVjdCBtdXN0IGJlIGltbXV0YWJsZSBvbmNlIGl0J3MgY29uc3RydWN0ZWQsIHNvIHRoYXQgaXQgbWF5IGJlIHNoYXJlZCBhbW9uZyBtdWx0aXBsZSB0aHJlYWRzIGNvbmN1cnJlbnRseS4gIElkZWFsbHksIGEgPGNvZGU+RWxlbVRlbXBsYXRlRWxlbWVudDwvY29kZT4gc2hvdWxkIGJlIGEgZGF0YSBvYmplY3Qgb25seSwgYW5kIGJlIHVzZWQgdmlhIGEgdmlzaXRvciBwYXR0ZXJuLiAgSG93ZXZlciwgaW4gcHJhY3RpY2UgdGhpcyBpcyBpbXByYWN0aWNhbCwgYmVjYXVzZSBpdCB3b3VsZCBjYXVzZSB0b28gbXVjaCBkYXRhIGV4cG9zdXJlIGFuZCB3b3VsZCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHBlcmZvcm1hbmNlLiAgVGhlcmVmb3JlLCBlYWNoIDxjb2RlPkVsZW1UZW1wbGF0ZUVsZW1lbnQ8L2NvZGU+IGNsYXNzIGhhcyBhbiA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1UZW1wbGF0ZUVsZW1lbnQuaHRtbCNleGVjdXRlKG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuVHJhbnNmb3JtZXJJbXBsLCBvcmcudzNjLmRvbS5Ob2RlLCBvcmcuYXBhY2hlLnhtbC51dGlscy5RTmFtZSkiPmV4ZWN1dGU8L2p1bXA+IG1ldGhvZCB3aGVyZSBpdCBwZXJmb3JtcyBpdCdzIHRyYW5zZm9ybWF0aW9uIGR1dGllcy4gIEEgPGNvZGU+RWxlbVRlbXBsYXRlRWxlbWVudDwvY29kZT4gYWxzbyBrbm93cyBpdCdzIHBvc2l0aW9uIGluIHRoZSBzb3VyY2Ugc3R5bGVzaGVldCwgYW5kIGNhbiBhbnN3ZXIgcXVlc3Rpb25zIGFib3V0IGN1cnJlbnQgbmFtZXNwYWNlIG5vZGVzLjwvcD48cD5BIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvU3R5bGVzaGVldFJvb3QuaHRtbCI+U3R5bGVzaGVldFJvb3Q8L2p1bXA+LCB3aGljaCBpbXBsZW1lbnRzIHRoZQotCQk8Y29kZT5UZW1wbGF0ZXM8L2NvZGU+IGludGVyZmFjZSwgaXMgYSB0eXBlIG9mIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvU3R5bGVzaGVldENvbXBvc2VkLmh0bWwiPlN0eWxlc2hlZXRDb21wb3NlZDwvanVtcD4sCi0JCXdoaWNoIGlzIGEgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9TdHlsZXNoZWV0Lmh0bWwiPlN0eWxlc2hlZXQ8L2p1bXA+IGNvbXBvc2VkIG9mIGl0c2VsZiBhbmQgYWxsIGluY2x1ZGVkCi0JCTxjb2RlPlN0eWxlc2hlZXQ8L2NvZGU+IG9iamVjdHMuIEEgPGNvZGU+U3R5bGVzaGVldFJvb3Q8L2NvZGU+IGhhcyBhIGdsb2JhbAotCQlpbXBvcnRzIGxpc3QsIHdoaWNoIGlzIGEgbGlzdCBvZiBhbGwgaW1wb3J0ZWQgPGNvZGU+U3R5bGVzaGVldENvbXBvc2VkPC9jb2RlPgotCQlpbnN0YW5jZXMuIEZyb20gZWFjaCA8Y29kZT5TdHlsZXNoZWV0Q29tcG9zZWQ8L2NvZGU+IG9iamVjdCwgb25lIGNhbiBpdGVyYXRlCi0JCXRocm91Z2ggdGhlIGxpc3Qgb2YgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCA8Y29kZT5TdHlsZXNoZWV0PC9jb2RlPgotCQlvYmplY3RzLCBhbmQgb25lIGNhbGwgYWxzbyBpdGVyYXRlIHRocm91Z2ggdGhlIGxpc3Qgb2YgYWxsCi0JCTxjb2RlPlN0eWxlc2hlZXRDb21wb3NlZDwvY29kZT4gb2JqZWN0cyBvZiBsZXNzZXIgaW1wb3J0IHByZWNlZGVuY2UuCi0JCTxjb2RlPlN0eWxlc2hlZXRSb290PC9jb2RlPiBpcyBhIDxjb2RlPlN0eWxlc2hlZXRDb21wb3NlZDwvY29kZT4sIHdoaWNoIGlzIGEKLQkJPGNvZGU+U3R5bGVzaGVldDwvY29kZT4uPC9wPiAKLQkgPHA+RWFjaCBzdHlsZXNoZWV0IGhhcyBhIHNldCBvZiBwcm9wZXJ0aWVzLCB3aGljaCBjYW4gYmUgc2V0IGJ5IHZhcmlvdXMKLQkJbWVhbnMsIHVzdWFsbHkgZWl0aGVyIHZpYSBhbiBhdHRyaWJ1dGUgb24geHNsOnN0eWxlc2hlZXQsIG9yIHZpYSBhIHRvcC1sZXZlbAotCQl4c2wgaW5zdHJ1Y3Rpb24gKGZvciBpbnN0YW5jZSwgeHNsOmF0dHJpYnV0ZS1zZXQpLiBUaGUgZ2V0IG1ldGhvZHMgZm9yIHRoZXNlCi0JCXByb3BlcnRpZXMgb25seSBhY2Nlc3MgdGhlIGRlY2xhcmF0aW9uIHdpdGhpbiB0aGUgZ2l2ZW4gPGNvZGU+U3R5bGVzaGVldDwvY29kZT4KLQkJb2JqZWN0LCBhbmQgbmV2ZXIgdGFrZXMgaW50byBhY2NvdW50IGluY2x1ZGVkIG9yIGltcG9ydGVkIHN0eWxlc2hlZXRzLiBUaGUKLQkJPGNvZGU+U3R5bGVzaGVldENvbXBvc2VkPC9jb2RlPiBkZXJpdmF0aXZlIG9iamVjdCwgaWYgaXQgaXMgYSByb290Ci0JCTxjb2RlPlN0eWxlc2hlZXQ8L2NvZGU+IG9yIGltcG9ydGVkIDxjb2RlPlN0eWxlc2hlZXQ8L2NvZGU+LCBoYXMgImNvbXBvc2VkIgotCQlnZXR0ZXIgbWV0aG9kcyB0aGF0IGRvIHRha2UgaW50byBhY2NvdW50IGltcG9ydGVkIGFuZCBpbmNsdWRlZCBzdHlsZXNoZWV0cywgZm9yCi0JCXNvbWUgb2YgdGhlc2UgcHJvcGVydGllcy48L3A+IAotCSAgCi0gIDwvczI+PGFuY2hvciBuYW1lPSJ0cmFuc2Zvcm1lciIvPiAKLSAgPHMyIHRpdGxlPSJUcmFuc2Zvcm1lciBNb2R1bGUiPiAKLQkgPHA+VGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+VHJhbnNmb3JtZXI8L2p1bXA+IG1vZHVsZSBpcyBpbiBjaGFyZ2Ugb2YgcnVuLXRpbWUgdHJhbnNmb3JtYXRpb25zLiAgVGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9UcmFuc2Zvcm1lckltcGwuaHRtbCI+VHJhbnNmb3JtZXJJbXBsPC9qdW1wPiBvYmplY3QsIHdoaWNoIGltcGxlbWVudHMgdGhlIFRyQVggPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyLmh0bWwiPlRyYW5zZm9ybWVyPC9qdW1wPiBpbnRlcmZhY2UsIGFuZCBoYXMgYW4gYXNzb2NpYXRpb24gd2l0aCBhIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvU3R5bGVzaGVldFJvb3QuaHRtbCI+U3R5bGVzaGVldFJvb3Q8L2p1bXA+IG9iamVjdCwgYmVnaW5zIHRoZSBwcm9jZXNzaW5nIG9mIHRoZSBzb3VyY2UgdHJlZSAob3IgcHJvdmlkZXMgYSA8anVtcCBocmVmPSJodHRwOi8vd3d3Lm1lZ2dpbnNvbi5jb20vU0FYL0phdmEvamF2YWRvYy9vcmcveG1sL3NheC9Db250ZW50SGFuZGxlci5odG1sIj5Db250ZW50SGFuZGxlcjwvanVtcD4gcmVmZXJlbmNlIHZpYSB0aGUgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3N0cmVlL1NvdXJjZVRyZWVIYW5kbGVyLmh0bWwiPlNvdXJjZVRyZWVIYW5kbGVyPC9qdW1wPiksIGFuZCBwZXJmb3JtcyB0aGUgdHJhbnNmb3JtYXRpb24uICBUaGUgVHJhbnNmb3JtZXIgcGFja2FnZSBkb2VzIGFzIG11Y2ggb2YgdGhlIHRyYW5zZm9ybWF0aW9uIGFzIGl0IGNhbiwgYnV0IGVsZW1lbnQgbGV2ZWwgb3BlcmF0aW9ucyBhcmUgZ2VuZXJhbGx5IHBlcmZvcm1lZCBpbiB0aGUgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcy9FbGVtVGVtcGxhdGVFbGVtZW50Lmh0bWwjZXhlY3V0ZShvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVySW1wbCwgb3JnLnczYy5kb20uTm9kZSwgb3JnLmFwYWNoZS54YWxhbi51dGlscy5RTmFtZSkiPkVsZW1UZW1wbGF0ZUVsZW1lbnQuZXhlY3V0ZSguLi4pPC9qdW1wPiBtZXRob2RzLjwvcD48cD5SZXN1bHQgVHJlZSBldmVudHMgYXJlIGZlZCBpbnRvIGEgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyL1Jlc3VsdFRyZWVIYW5kbGVyLmh0bWwiPlJlc3VsdFRyZWVIYW5kbGVyPC9qdW1wPiBvYmplY3QsIHdoaWNoIGFjdHMgYXMgYSBsYXllciBiZXR3ZWVuIHRoZSBkaXJlY3QgY2FsbHMgdG8gdGhlIHJlc3VsdCAKLXRyZWUgY29udGVudCBoYW5kbGVyIChvZnRlbiBhIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPlNlcmlhbGl6ZXI8L2p1bXA+KSwgYW5kIHRoZSA8Y29kZT5UcmFuc2Zvcm1lcjwvY29kZT4uICBGb3Igb25lIHRoaW5nLCAKLSB3ZSBoYXZlIHRvIGRlbGF5IHRoZSBjYWxsIHRvCi0gc3RhcnRFbGVtZW50KG5hbWUsIGF0dHMpIGJlY2F1c2Ugb2YgdGhlCi0geHNsOmF0dHJpYnV0ZSBhbmQgeHNsOmNvcHkgY2FsbHMuICBJbiBvdGhlciB3b3JkcywKLSB0aGUgYXR0cmlidXRlcyBoYXZlIHRvIGJlIGZ1bGx5IGNvbGxlY3RlZCBiZWZvcmUgeW91Ci0gY2FuIGNhbGwgc3RhcnRFbGVtZW50LjwvcD48cD5PdGhlciBpbXBvcnRhbnQgY2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UgYXJlOjwvcD48Z2xvc3M+PGxhYmVsPkNvdW50ZXJzVGFibGUgYW5kIENvdW50ZXI8L2xhYmVsPjxpdGVtPlRoZSA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIvQ291bnRlci5odG1sIj5Db3VudGVyPC9qdW1wPiBjbGFzcyBkb2VzIGluY3JlbWVudGFsIGNvdW50aW5nIGZvciBzdXBwb3J0IG9mIHhzbDpudW1iZXIuCi0gVGhpcyBjbGFzcyBzdG9yZXMgYSBjYWNoZSBvZiBjb3VudGVkIG5vZGVzIChtX2NvdW50Tm9kZXMpLiAKLSAgSXQgdHJpZXMgdG8gY2FjaGUgdGhlIGNvdW50ZWQgbm9kZXMgaW4gZG9jdW1lbnQgb3JkZXIuLi4gCi0gdGhlIG5vZGUgY291bnQgaXMgYmFzZWQgb24gaXRzIHBvc2l0aW9uIGluIHRoZSBjYWNoZSBsaXN0LiAgVGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lci9Db3VudGVyc1RhYmxlLmh0bWwiPkNvdW50ZXJzVGFibGU8L2p1bXA+IGNsYXNzIGlzIGEgdGFibGUgb2YgY291bnRlcnMsIGtleWVkIGJ5IDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbU51bWJlci5odG1sIj5FbGVtTnVtYmVyPC9qdW1wPiBvYmplY3RzLCBlYWNoIAotIG9mIHdoaWNoIGhhcyBhIGxpc3Qgb2YgPGNvZGU+Q291bnRlcjwvY29kZT4gb2JqZWN0cy48L2l0ZW0+PC9nbG9zcz48Z2xvc3M+PGxhYmVsPktleUl0ZXJhdG9yLCBLZXlNYW5hZ2VyLCBhbmQgS2V5VGFibGU8L2xhYmVsPjxpdGVtPlRoZXNlIGNsYXNzZXMgaGFuZGxlIG1hcHBpbmcgb2Yga2V5cyBkZWNsYXJlZCB3aXRoIHRoZSB4c2w6a2V5IGVsZW1lbnQuICBUaGV5IGF0dGVtcHQgdG8gd29yayBpbmNyZW1lbnRhbGx5LCBsb2NhdGluZyBub2RlcyBvbiByZXF1ZXN0IGJ1dCBpbmRleGluZyBhbGwgYXMgdGhleSB0cmF2ZXJzZSB0aGUgdHJlZSwgYW5kIHN0b3BwaW5nIHdoZW4gdGhlIHJlcXVlc3RlZCBub2RlIGlzIGZvdW5kLiAgSWYgYSByZXF1ZXN0ZWQgbm9kZSBpcyBub3QgZm91bmQsIHRoZW4gdGhlIGVudGlyZSB0cmVlIHdpbGwgYmUgdHJhdmVyc2VkLiAgU3VjaCBpcyB0aGUgbmF0dXJlIG9mIHhzbDprZXkuPC9pdGVtPjwvZ2xvc3M+PGdsb3NzPjxsYWJlbD5UcmFuc2Zvcm1TdGF0ZTwvbGFiZWw+PGl0ZW0+VGhpcyBpbnRlcmZhY2UgaXMgbWVhbnQgdG8gYmUgdXNlZCBieSBhIGNvbnN1bWVyIG9mIFNBWDIgZXZlbnRzIHByb2R1Y2VkIGJ5IFhhbGFuLCBhbmQgZW5hYmxlcyB0aGUgY29uc3VtZXIgCi0gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IHRoZSBzdGF0ZSBvZiB0aGUgdHJhbnNmb3JtLiAgSXQgCi0gaXMgcHJpbWFyaWx5IGludGVuZGVkIGFzIGEgdG9vbGluZyBpbnRlcmZhY2UuPC9pdGVtPjwvZ2xvc3M+PHA+RXZlbiB0aG91Z2ggdGhlIGZvbGxvd2luZyBtb2R1bGVzIGFyZSBkZWZpbmVkIGluIHRoZSA8Y29kZT5vcmcuYXBhY2hlLnhhbGFuPC9jb2RlPiBwYWNrYWdlLCBpbnN0ZWFkIG9mIHRoZSB0cmFuc2Zvcm1lciBwYWNrYWdlLCB0aGV5IGFyZSBkZWZpbmVkIGluIHRoaXMgc2VjdGlvbiBhcyB0aGV5IGFyZSBtb3N0bHkgcmVsYXRlZCB0byBydW50aW1lIHRyYW5zZm9ybWF0aW9uLjwvcD48YW5jaG9yIG5hbWU9InN0cmVlIi8+Ci0gIDxzMyB0aXRsZT0iU3RyZWUgTW9kdWxlIFthbmQgZGlzY3Vzc2lvbnMgYWJvdXQgc3RyZWFtaW5nXSI+Ci0gIDxwPlRoZSBTdHJlZSBtb2R1bGUgaW1wbGVtZW50cyB0aGUgZGVmYXVsdCA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94cGF0aCNkYXRhLW1vZGVsIj5Tb3VyY2UgVHJlZSA8L2p1bXA+IGZvciBYYWxhbiwgdGhhdCBpcyB0byBiZSB0cmFuc2Zvcm1lZC4gIEl0IGltcGxlbWVudHMgcmVhZC1vbmx5IDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLyI+RE9NMjwvanVtcD4gaW50ZXJmYWNlcywgYW5kIHByb3ZpZGVzIHNvbWUgaW5mb3JtYXRpb24gbmVlZGVkIGZvciBmYXN0IHRyYW5zZm9ybXMsIHN1Y2ggYXMgZG9jdW1lbnQgb3JkZXIgaW5kZXhlcy4gIEl0IGFsc28gYXR0ZW1wdHMgdG8gYWxsb3cgYW4gaW5jcmVtZW50YWwgdHJhbnNmb3JtIGJ5IGxhdW5jaGluZyB0aGUgdHJhbnNmb3JtIG9uIGEgc2Vjb25kYXJ5IHRocmVhZCBhcyBzb29uIGFzIHRoZSBTQVgyIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cubWVnZ2luc29uLmNvbS9TQVgvSmF2YS9qYXZhZG9jL29yZy94bWwvc2F4L0NvbnRlbnRIYW5kbGVyLmh0bWwjc3RhcnREb2N1bWVudCgpIj5TdGFydERvY3VtZW50PC9qdW1wPiBldmVudCBoYXMgb2NjdXJyZWQuICBXaGVuIHRoZSB0cmFuc2Zvcm0gcmVxdWVzdHMgYSBub2RlLCBhbmQgdGhlIG5vZGUgaXMgbm90IHByZXNlbnQsIHRoZSBnZXRGaXJzdENoaWxkIGFuZCBHZXROZXh0U2libGluZyBtZXRob2RzIHdpbGwgd2FpdCB1bnRpbCB0aGUgY2hpbGQgbm9kZSBoYXMgYXJyaXZlZCwgb3IgYW4gPGp1bXAgaHJlZj0iaHR0cDovL3d3dy5tZWdnaW5zb24uY29tL1NBWC9KYXZhL2phdmFkb2Mvb3JnL3htbC9zYXgvQ29udGVudEhhbmRsZXIuaHRtbCNlbmRFbGVtZW50KGphdmEubGFuZy5TdHJpbmcsJTIwamF2YS5sYW5nLlN0cmluZywlMjBqYXZhLmxhbmcuU3RyaW5nKSI+ZW5kRWxlbWVudDwvanVtcD4gZXZlbnQgaGFzIG9jY3VycmVkLjwvcD48cD5Ob3RlIHRoYXQgdGhlIHNlY29uZGFyeSB0aHJlYWQgaXMgYW4gaXNzdWUuICBJdCB3b3VsZCBiZSBiZXR0ZXIgdG8gZG8gdGhlIHNhbWUgdGhpbmcgYXMgZGVzY3JpYmVkIGFib3ZlIG9uIGEgc2luZ2xlIHRocmVhZCwgYnV0IHVzaW5nIHRoZSBwYXJzZXIgaW4gJ3B1bGwnIG1vZGUsIG9yIHNpbXBseSB3aXRoIGEgcGFyc2VOZXh0IG1ldGhvZCBzbyB0aGUgcGFyc2Ugd291bGQgb2NjdXIgaW4gYmxvY2tzLiAgSG93ZXZlciwgdGhpcyBtb2RlbCB3b3VsZCBvbmx5IGJlIHBvc3NpYmxlPC9wPjxwPlRoaXMga2luZCBvZiBpbmNyZW1lbnRhbGl0eSBpcyBub3QgcGVyZmVjdCBiZWNhdXNlIGl0IHN0aWxsIHJlcXVpcmVzIGFuIGVudGlyZSBzb3VyY2UgdHJlZSB0byBiZSBjb25jcmV0ZWx5IGJ1aWx0LiAgVGhlcmUgaGF2ZSBiZWVuIGEgbG90IG9mIGdvb2QgZGlzY3Vzc2lvbnMgb24gdGhlIHhhbGFuLWRldiBsaXN0IGFib3V0IGhvdyB0byBkbyBzdGF0aWMgYW5hbHlzaXMgb2YgYSBzdHlsZXNoZWV0LCBhbmQgYmUgYWJsZSB0byBhbGxvY2F0ZSBvbmx5IHRoZSBub2RlcyBuZWVkZWQgYnkgdGhlIHRyYW5zZm9ybSwgd2hpbGUgdGhleSBhcmUgbmVlZGVkIChvciBub3QgYWxsb2NhdGUgc291cmNlIG9iamVjdHMgYXQgYWxsKS48L3A+PC9zMz4KLTxhbmNob3IgbmFtZT0ic2VyaWFsaXplciIvPgotPHMzIHRpdGxlPSJTZXJpYWxpemVyIE1vZHVsZSI+Ci08cD5YTUwgc2VyaWFsaXphdGlvbiBpcyBhIHRlcm0gdXNlZCBmb3IgdHVybmluZyBhIHRyZWUgb3Igc2V0IG9mIGV2ZW50cyBpbnRvIGEgc3RyZWFtLCBhbmQgc2hvdWxkIG5vdCBiZSBjb25mdXNlZCB3aXRoIEphdmEgb2JqZWN0IHNlcmlhbGl6YXRpb24uICBUaGUgWGFsYW4gc2VyaWFsaXplcnMgaW1wbGVtZW50IHRoZSA8anVtcCBocmVmPSJodHRwOi8vd3d3Lm1lZ2dpbnNvbi5jb20vU0FYL0phdmEvamF2YWRvYy9vcmcveG1sL3NheC9Db250ZW50SGFuZGxlci5odG1sIj5Db250ZW50SGFuZGxlcjwvanVtcD4gdG8gdHVybiBwYXJzZXIgZXZlbnRzIGNvbWluZyBmcm9tIHRoZSB0cmFuc2Zvcm0sIGludG8gYSBzdHJlYW0gb2YgWE1MLCBIVE1MLCBvciBwbGFpbiB0ZXh0LiAgVGhlIHNlcmlhbGl6ZXJzIGFsc28gaW1wbGVtZW50IHRoZSA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplci9TZXJpYWxpemVyLmh0bWwiPlNlcmlhbGl6ZXI8L2p1bXA+IHdoaWNoIGFsbG93cyB0aGUgdHJhbnNmb3JtIHByb2Nlc3MgdG8gc2V0IFhTTFQgb3V0cHV0IHByb3BlcnRpZXMgYW5kIHRoZSBvdXRwdXQgc3RyZWFtIG9yIFdyaXRlci48L3A+PC9zMz48YW5jaG9yIG5hbWU9ImV4dGVuc2lvbnMiLz4KLTxzMyB0aXRsZT0iRXh0ZW5zaW9ucyBNb2R1bGUiPgotPHA+VGhpcyBwYWNrYWdlIGNvbnRhaW5zIGFuIGltcGxlbWVudGF0aW9uIG9mIFhhbGFuIEV4dGVuc2lvbiBNZWNoYW5pc20sIHdoaWNoIHVzZXMgdGhlIDxqdW1wIGhyZWY9Imh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9kZXZlbG9wZXJ3b3Jrcy9vcGVuc291cmNlL2JzZi8iPkJlYW4gU2NyaXB0aW5nIEZyYW1ld29yazwvanVtcD4uCi0KLVRoZSBCZWFuIFNjcmlwdGluZyBGcmFtZXdvcmsgKEJTRikgaXMgYW4gYXJjaGl0ZWN0dXJlIGZvciBpbmNvcnBvcmF0aW5nIHNjcmlwdGluZyBpbnRvIEphdmEgYXBwbGljYXRpb25zIGFuZCBhcHBsZXRzLiAgU2NyaXB0aW5nIGxhbmd1YWdlcyBzdWNoIGFzIE5ldHNjYXBlIFJoaW5vIChKYXZhc2NyaXB0KSwgVkJTY3JpcHQsIFBlcmwsIFRjbCwgUHl0aG9uLCBOZXRSZXh4IGFuZCBSZXh4IGNhbiBiZSB1c2VkIHRvIGF1Z21lbnQgWFNMVCdzIGZ1bmN0aW9uYWxpdHkuICBJbiBhZGRpdGlvbiwgdGhlIFhhbGFuIGV4dGVuc2lvbiBtZWNoYW5pc20gYWxsb3dzIHVzZSBvZiBKYXZhIGNsYXNzZXMuICBTZWUgdGhlIDxqdW1wIGhyZWY9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9leHRlbnNpb25zLmh0bWwiPlhhbGFuLUogMiBleHRlbnNpb24gZG9jdW1lbnRhdGlvbjwvanVtcD4gZm9yIGEgZGVzY3JpcHRpb24gb2YgdXNpbmcgZXh0ZW5zaW9ucyBpbiBhIHN0eWxlc2hlZXQuIFBsZWFzZSBub3RlIHRoYXQgdGhlIFczQyBYU0wgV29ya2luZyBHcm91cCBpcyB3b3JraW5nIG9uIGEgc3BlY2lmaWNhdGlvbiBmb3Igc3RhbmRhcmQgZXh0ZW5zaW9uIGJpbmRpbmdzLCBhbmQgdGhpcyBtb2R1bGUgd2lsbCBjaGFuZ2UgdG8gZm9sbG93IHRoYXQgc3BlY2lmaWNhdGlvbi4gIDwvcD48cD5bTW9yZSBuZWVkZWQuLi4gLXNiXTwvcD48L3MzPjwvczI+PGFuY2hvciBuYW1lPSJ4cGF0aCIvPiAKLSAgPHMyIHRpdGxlPSJYUGF0aCBNb2R1bGUiPiAKLQkgPHA+VGhpcyBtb2R1bGUgaXMgcHVsbGVkIG91dCBvZiB0aGUgWGFsYW4gcGFja2FnZSwgYW5kIHB1dCBpbiB0aGUgb3JnLmFwYWNoZSBwYWNrYWdlLCB0byBlbXBoYXNpemUgdGhhdCB0aGUgaW50ZW50aW9uIGlzIHRoYXQgdGhpcyBwYWNrYWdlIGNhbiBiZSB1c2VkIGluZGVwZW5kZW50bHkgb2YgdGhlIFhTTFQgZW5naW5lLCBldmVuIHRob3VnaCBpdCBoYXMgZGVwZW5kZW5jaWVzIG9uIHRoZSBYYWxhbiB1dGlscyBtb2R1bGUuPC9wPjxwPjxpbWcgc3JjPSJvcmdfYXBhY2hlLmdpZiIgYWx0PSJ4YWxhbiAtLS0+IHhwYXRoIi8+PC9wPiAKLSAgPHA+VGhlIFhQYXRoIG1vZHVsZSBmaXJzdCBjb21waWxlcyB0aGUgWFBhdGggc3RyaW5ncyBpbnRvIGV4cHJlc3Npb24gdHJlZXMsIGFuZCB0aGVuIGV4ZWN1dGVzIHRoZXNlIGV4cHJlc3Npb25zIHZpYSBhIGNhbGwgdG8gdGhlIFhQYXRoIGV4ZWN1dGUoLi4uKSBmdW5jdGlvbi4gIDwvcD4gIDxwPk1ham9yIGNsYXNzZXMgYXJlOjwvcD48Z2xvc3M+PGxhYmVsPlhQYXRoPC9sYWJlbD48aXRlbT5SZXByZXNlbnRzIGEgY29tcGlsZWQgWFBhdGguICBNYWpvciBmdW5jdGlvbiBpcyA8Y29kZT5YT2JqZWN0IGV4ZWN1dGUoWFBhdGhDb250ZXh0IHhjdHh0LCBOb2RlIGNvbnRleHROb2RlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICBQcmVmaXhSZXNvbHZlciBuYW1lc3BhY2VDb250ZXh0KTwvY29kZT4uPC9pdGVtPjwvZ2xvc3M+PGdsb3NzPjxsYWJlbD5YUGF0aEFQSTwvbGFiZWw+PGl0ZW0+VGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBhcmUgY29udmVuaWVuY2UgbWV0aG9kcyBpbnRvIHRoZQotIGxvdy1sZXZlbCBYUGF0aCBBUEkuPC9pdGVtPjwvZ2xvc3M+PGdsb3NzPjxsYWJlbD5YUGF0aENvbnRleHQ8L2xhYmVsPjxpdGVtPlVzZWQgYXMgdGhlIHJ1bnRpbWUgZXhlY3V0aW9uIGNvbnRleHQgZm9yIFhQYXRoLjwvaXRlbT48L2dsb3NzPjxnbG9zcz48bGFiZWw+RE9NSGVscGVyPC9sYWJlbD48aXRlbT5Vc2VkIGFzIGEgaGVscGVyIGZvciBoYW5kbGluZyBET00gaXNzdWVzLiAgTWF5IGJlIHN1YmNsYXNzZWQgdG8gdGFrZSBhZHZhbnRhZ2UgCi0gICBvZiBzcGVjaWZpYyBET00gaW1wbGVtZW50YXRpb25zLjwvaXRlbT48L2dsb3NzPjxnbG9zcz48bGFiZWw+U291cmNlVHJlZU1hbmFnZXI8L2xhYmVsPjxpdGVtPmJvdHRsZW5lY2tzIGFsbCBtYW5hZ2VtZW50IG9mIHNvdXJjZSB0cmVlcy4gIFRoZSBtZXRob2RzCi0gaW4gdGhpcyBjbGFzcyBzaG91bGQgYWxsb3cgZWFzeSBnYXJiYWdlIGNvbGxlY3Rpb24gb2Ygc291cmNlIAotIHRyZWVzLCBhbmQgc2hvdWxkIGNlbnRyYWxpemUgcGFyc2luZyBmb3IgdGhvc2Ugc291cmNlIHRyZWVzLjwvaXRlbT48L2dsb3NzPjxnbG9zcz48bGFiZWw+RXhwcmVzc2lvbjwvbGFiZWw+PGl0ZW0+VGhlIGJhc2UtY2xhc3Mgb2YgYWxsIGV4cHJlc3Npb24gb2JqZWN0cywgYWxsb3dpbmcgcG9seW1vcnBoaWMgYmVoYXZpb3JzLjwvaXRlbT48L2dsb3NzPjxwPlRoZSBnZW5lcmFsIGFyY2hpdGVjdHVyZSBvZiB0aGUgWFBhdGggbW9kdWxlIGlzIGRpdmlkZWQgaW50byB0aGUgY29tcGlsZXIsIGFuZCBjYXRlZ29yaWVzIG9mIGV4cHJlc3Npb24gb2JqZWN0cy48L3A+PHA+PGltZyBzcmM9InhwYXRoLmdpZiIgYWx0PSJ4cGF0aCBtb2R1bGVzIi8+PC9wPjxwPlRoZSBtb3N0IGltcG9ydGFudCBtb2R1bGUgaXMgdGhlIGF4ZXMgbW9kdWxlLiAgVGhpcyBtb2R1bGUgaW1wbGVtZW50cyB0aGUgRE9NMiA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi90cmF2ZXJzYWwuaHRtbCNJdGVyYXRvci1vdmVydmlldyI+Tm9kZUl0ZXJhdG9yPC9qdW1wPiBpbnRlcmZhY2UsIGFuZCBpcyBtZWFudCB0byBhbGxvdyBYUGF0aCBjbGllbnRzIHRvIGVpdGhlciBvdmVycmlkZSB0aGUgZGVmYXVsdCBiZWhhdmlvciBvciB0byByZXBsYWNlIHRoaXMgYmVoYXZpb3IuPC9wPjxwPlRoZSA8anVtcCBocmVmPSIuLi9hcGlkb2NzL29yZy9hcGFjaGUveHBhdGgvYXhlcy9Mb2NQYXRoSXRlcmF0b3IuaHRtbCI+TG9jUGF0aEl0ZXJhdG9yPC9qdW1wPiBhbmQgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvVW5pb25QYXRoSXRlcmF0b3IuaHRtbCI+VW5pb25QYXRoSXRlcmF0b3I8L2p1bXA+IGNsYXNzZXMgaW1wbGVtZW50IHRoZSA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi9qYXZhLWJpbmRpbmcuaHRtbCNvcmcudzNjLmRvbS50cmF2ZXJzYWwuTm9kZUl0ZXJhdG9yIj5Ob2RlSXRlcmF0b3I8L2p1bXA+IGludGVyZmFjZSwgYW5kIHBvbHltb3JwaGljYWxseSB1c2UgPGp1bXAgaHJlZj0iLi4vYXBpZG9jcy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMvQXhlc1dhbGtlci5odG1sIj5BeGVzV2Fsa2VyPC9qdW1wPiBkZXJpdmVkIG9iamVjdHMgdG8gZXhlY3V0ZSBlYWNoIHN0ZXAgaW4gdGhlIHBhdGguICBUaGUgd2hvbGUgdHJpY2sgaXMgdG8gZXhlY3V0ZSB0aGUgPGNvZGU+TG9jYXRpb25QYXRoPC9jb2RlPiBpbiBkZXB0aC1maXJzdCBkb2N1bWVudCBvcmRlciBzbyB0aGF0IG5vZGVzIGNhbiBiZSBmb3VuZCB3aXRob3V0IG5lY2Vzc2FyaWx5IGxvb2tpbmcgYWhlYWQgb3IgcGVyZm9ybWluZyBhIGJyZWFkdGgtZmlyc3Qgc2VhcmNoLiAgQmVjYXVzZSBhIGRvY3VtZW50IG9yZGVyIGRlcHRoLWZpcnN0IHNlYXJjaCByZXF1aXJlcyBzdGF0ZSB0byBiZSBzYXZlZCBmb3IgbWFueSBleHByZXNzaW9ucywgdGhlIGRlZmF1bHQgb3BlcmF0aW9ucyBjcmVhdGUgIldhaXRlciIgY2xvbmVzIHRoYXQgaGF2ZSB0byB3YWl0IHdoaWxlIHRoZSBtYWluIDxjb2RlPkF4ZXNXYWxrZXJzPC9jb2RlPiB0cmF2ZXJzZXMgY2hpbGQgbm9kZXMgKHRoaW5rIGNhcmVmdWxseSBhYm91dCB3aGF0IGhhcHBlbnMgd2hlbiBhICIvL2Zvby9iYXoiIGV4cHJlc3Npb24gaXMgZXhlY3V0ZWQpLiAgIE9wdGltaXphdGlvbiBpcyBkb25lIGJ5IGltcGxlbWVudGluZyBzcGVjaWFsaXplZCBpdGVyYXRvcnMgYW5kIDxjb2RlPkF4ZXNXYWxrZXJzPC9jb2RlPiBmb3IgY2VydGFpbiB0eXBlcyBvZiBvcGVyYXRpb25zLiAgVGhlIGRlY2lzaW9uIGFzIHRvIHdoYXQgdHlwZSBvZiBpdGVyYXRvciBvciB3YWxrZXIgd2lsbCBiZSBjcmVhdGVkIGlzIGRvbmUgaW4gdGhlIDxqdW1wIGhyZWY9Ii4uL2FwaWRvY3Mvb3JnL2FwYWNoZS94cGF0aC9heGVzL1dhbGtlckZhY3RvcnkuaHRtbCI+V2Fsa2VyRmFjdG9yeTwvanVtcD4gY2xhc3MuPC9wPjxwPltGcmFua2x5LCB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIGRlZmF1bHQgQXhlc1dhbGtlciwgd2l0aCBpdCdzIHdhaXRlcnMsIGlzIHRoZSBvbmUgdG90YWxseSBpbmNvbXByZWhlbnNpYmxlIHBhcnQgb2YgWGFsYW4uICBJdCBnZXRzIGVzcGVjaWFsbHkgZGlmZmljdWx0IGJlY2F1c2UgeW91IGNhbiBub3QgbG9vayB0byB0aGUgbm9kZSBhaGVhZC4gIEkgd291bGQgYmUgdmVyeSBpbnRlcmVzdGVkIGlmIGFueSByb2NrZXQgc2NpZW50aXN0cyBvdXQgdGhlcmUgY2FuIGNvbWUgdXAgd2l0aCBhIGJldHRlciBhbGdvcml0aG0uXTwvcD48YW5jaG9yIG5hbWU9InhwYXRoZGJjb25uIi8+Ci08czMgdGl0bGU9IlhQYXRoIERhdGFiYXNlIENvbm5lY3Rpb24iPgotPHA+QW4gaW1wb3J0YW50IHBhcnQgb2YgdGhlIFhQYXRoIGRlc2lnbiBpbiBib3RoIFhhbGFuIDEgYW5kIFhhbGFuIDIsIGlzIHRvIGVuYWJsZSBkYXRhYmFzZSBjb25uZWN0aW9ucyB0byBiZSB1c2VkIGFzIGRyaXZlcnMgZGlyZWN0bHkgdG8gdGhlIFhQYXRoIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hwYXRoI2xvY2F0aW9uLXBhdGhzIj5Mb2NhdGlvblBhdGg8L2p1bXA+IGhhbmRsaW5nLiAgVGhpcyBhbGxvd3MgZGF0YWJhc2VzIHRvIGJlIGRpcmVjdGx5IGNvbm5lY3RlZCB0byB0aGUgdHJhbnNmb3JtLCBhbmQgYmUgYWJsZSB0byB0YWtlIGFkdmFudGFnZSBvZiBpbnRlcm5hbCBpbmRleGluZyBhbmQgdGhlIGxpa2UuICBXaGlsZSBpbiBYYWxhbiAxIHRoaXMgd2FzIGRvbmUgdmlhIHRoZSA8anVtcCBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL1hMb2NhdG9yLmh0bWwiPlhMb2NhdG9yPC9qdW1wPiBpbnRlcmZhY2UsIGluIFhhbGFuIDIgdGhpcyBpbnRlcmZhY2UgaXMgbm8gbG9uZ2VyIHVzZWQsIGFuZCBoYXMgYmVlbiByZXBsYWNlZCBieSB0aGUgRE9NMiA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi90cmF2ZXJzYWwuaHRtbCNJdGVyYXRvci1vdmVydmlldyI+Tm9kZUl0ZXJhdG9yPC9qdW1wPiBpbnRlcmZhY2UuICBBbiBhcHBsaWNhdGlvbiBvciBleHRlbnNpb24gc2hvdWxkIGJlIGFibGUgdG8gaW5zdGFsbCB0aGVpciBvd24gTm9kZUl0ZXJhdG9yIGZvciBhIGdpdmVuIGRvY3VtZW50LjwvcD48cD48aW1nIHNyYz0iZGF0YS5naWYiIGFsdD0iZGF0YS5naWYiLz48L3A+PHA+W01vcmUgdG8gZG9dPC9wPjwvczM+PC9zMj48YW5jaG9yIG5hbWU9InV0aWxzIi8+IAotICA8czIgdGl0bGU9IlV0aWxzIFBhY2thZ2UiPiAKLSAgPHA+VGhpcyBwYWNrYWdlIGNvbnRhaW5zIGdlbmVyYWwgdXRpbGl0aWVzIGZvciB1c2UgYnkgYm90aCB0aGUgeGFsYW4gYW5kIHhwYXRoIHBhY2thZ2VzLjwvcD48L3MyPjxhbmNob3IgbmFtZT0ib3RoZXIiLz4KLSAgPHMyIHRpdGxlPSJPdGhlciBQYWNrYWdlcyI+IAotCSA8Z2xvc3M+PGxhYmVsPmNsaWVudDwvbGFiZWw+PGl0ZW0+SW1wbGVtZW50YXRpb24gb2YgWGFsYW4gQXBwbGV0IFtzaG91bGQgd2Uga2VlcCB0aGlzP10uCi0KLTwvaXRlbT48L2dsb3NzPiAKLQkJIAotCQkgCi0JCTxnbG9zcz48bGFiZWw+bGliPC9sYWJlbD48aXRlbT5JbXBsZW1lbnRhdGlvbiBvZiBYYWxhbi1zcGVjaWZpYyBleHRlbnNpb25zLjwvaXRlbT48L2dsb3NzPjxnbG9zcz48bGFiZWw+cmVzPC9sYWJlbD48aXRlbT5Db250YWlucyBzdHJpbmdzIHRoYXQgcmVxdWlyZSBpbnRlcm5hdGlvbmFsaXphdGlvbi48L2l0ZW0+PC9nbG9zcz48L3MyPjxhbmNob3IgbmFtZT0iY29tcGlsYXRpb24iLz4KLTxzMiB0aXRsZT0iWGFsYW4gU3R5bGVzaGVldCBDb21wbGlsYXRpb24gdG8gSmF2YSI+Ci08cD5XZSBhcmUgZG9pbmcgc29tZSB3b3JrIG9uIGNvbXBpbGluZyBzdHlsZXNoZWV0IG9iamVjdHMgdG8gSmF2YS4gIFRoaXMgaXMgYSB3b3JrIGluIHByb2dyZXNzLCBhbmQgaXMgbm90IG1lYW50IGZvciBnZW5lcmFsIHVzZSB5ZXQuICBGb3IgdGhlIG1vbWVudCwgd2UgYXJlIHdyaXRpbmcgb3V0IEphdmEgdGV4dCBmaWxlcywgYW5kIHRoZW4gY29tcGlsaW5nIHRoZW0gdG8gYnl0ZWNvZGVzIHZpYSBqYXZhYywgcmF0aGVyIHRoYW4gZGlyZWN0bHkgcHJvZHVjaW5nIGJ5dGVjb2Rlcy4gIFRoZSBDb21waWxpbmdTdHlsZXNoZWV0UHJvY2Vzc29yIGRlcml2ZXMgZnJvbSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIHRvIHByb2R1Y2UgdGhlc2UgY2xhc3Nlcywgd2hpY2ggYXJlIHRoZW4gYnVuZGxlZCBpbnRvIGEgamFyIGZpbGUuICBGb3IgdGhlIG1vbWVudCB0aGUgZnVsbCBYYWxhbiBqYXIgaXMgcmVxdWlyZWQsIGJ1dCB3ZSdyZSBsb29raW5nIGF0IHdheXMgdG8gb25seSB1c2UgYSBzdWJzZXQgb2YgWGFsYW4sIHNvIHRoYXQgb25seSBhIG1pbmltYWwgamFyIHdvdWxkIGJlIHJlcXVpcmVkLjwvcD48cD48aW1nIHNyYz0iY29tcGlsYXRpb24uZ2lmIiBhbHQ9ImNvbXBpbGF0aW9uLmdpZiIvPjwvcD48L3MyPjxhbmNob3IgbmFtZT0ib3B0aW1pemF0aW9ucyIvPgotPHMyIHRpdGxlPSJGdXR1cmUgT3B0aW1pemF0aW9ucyI+Ci08cD5UaGlzIHNlY3Rpb24gZW51bWVyYXRlcyBzb21lIG9wdGltaXphdGlvbnMgdGhhdCB3ZSdyZSBwbGFubmluZyB0byBkbyBpbiBmdXR1cmUgdmVyc2lvbnMgb2YgWGFsYW4uPC9wPjxwPkxpa2VseSBuZWFyIHRlcm0gb3B0aW1pemF0aW9ucyAobmV4dCBzaXggbW9udGhzPyk6PC9wPjxvbD48bGk+QnkgcHJlLWFuYWx5c2lzIG9mIHRoZSBzdHlsZXNoZWV0LCBwcnVuZSBub2RlcyBmcm9tIHRoZSB0cmVlIHRoYXQgaGF2ZSBiZWVuIHByb2Nlc3NlZCBhbmQgY2FuIGJlIHByZWRpY3RlZCB0aGF0IHRoZXkgd29uJ3QgYmUgdmlzaXRlZCBhZ2Fpbi48L2xpPjxsaT5FbGltaW5hdGUgcmVkdW5kZW50IGV4cHJlc3Npb25zICh4c2w6d2hlbiwgdmFyaWFibGUgc2V0cywgcm9vdGVkIHBhdHRlcm5zLCBldGMuKS48L2xpPjxsaT5PcHRpbWl6ZSB2YXJpYWJsZSBwYXR0ZXJucyBzdWNoIGFzICZsdDt4c2w6dmFyaWFibGUgbmFtZT0iZm9vIiZndDsmbHQ7eHNsOnZhcmlhYmxlIHNlbGVjdD0ieWFkYSIvJmd0OyZsdDsveHNsOnZhcmlhYmxlJmd0OyBpbnRvICZsdDt4c2w6dmFyaWFibGUgbmFtZT0iZm9vIiBzZWxlY3Q9InN0cmluZyh5YWRhKSIvJmd0OywgaW4gb3JkZXIgdG8gcmVkdWNlIHJlc3VsdCB0cmVlIGZyYWdtZW50IGNyZWF0aW9uLjwvbGk+PGxpPlJlZHVjZSBzaXplIG9mIFN0cmVlIG5vZGVzLjwvbGk+PGxpPkltcGxlbWVudCBvdXIgb3duIE5hbWVzcGFjZVN1cHBvcnQgY2xhc3MgKHRoZSBTQVgyIG9uZSBpcyB0b28gZXhwZW5zaXZlKS48L2xpPjxsaT5Nb3JlIHNwZWNpYWxpemF0aW9uIG9mIGl0dGVyYXRvcnMgYW5kIHdhbGtlcnMuPC9saT48bGk+RnVsbCBKYXZhIGNvbXBpbGF0aW9uIHN1cHBvcnQuPC9saT48bGk+U2NoZW1hIEF3YXJlbmVzcyAoaWYgIi8vZm9vIiwgdGhlIFNjaGVtYSBjYW4gdGVsbCB1cyB3aGVyZSB0byBsb29rLCBidXQgd2UgbmVlZCBzdGFuZGFyZCBpbnRlcmZhY2UgdG8gU2NoZW1hcykuPC9saT48L29sPjxwPkxpa2VseSBsb25nZXIgdGVybSBvcHRpbWl6YXRpb25zICgxMi0xOCBtb250aHM/KTo8L3A+PG9sPjxsaT5Pbi10aGUtZmx5IGluZGV4aW5nLjwvbGk+PGxpPlByZWRpY3QgaWYgbm9kZXMgd29uJ3QgYmUgcHJvY2Vzc2VkIGF0IGFsbCwgYW5kIHNvIGRvbid0IGJ1aWxkIHRoZW0sIGFjaGlldmUgZnVsbCBzdHJlYW1pbmcgc3VwcG9ydCBmb3IgYSBjZXJ0YWluIGNsYXNzIG9mIHN0eWxlc2hlZXRzLjwvbGk+PC9vbD48L3MyPjxhbmNob3IgbmFtZT0iY29kaW5nIi8+IAotICA8czIgdGl0bGU9IkNvZGluZyBDb252ZW50aW9ucyI+IAotCSA8cD5UaGlzIHNlY3Rpb24gZG9jdW1lbnRzIHRoZSBjb2RpbmcgY29udmVudGlvbnMgdXNlZCBpbiB0aGUgWGFsYW4KLQkJc291cmNlLjwvcD4gCi0JIDxvbD4gCi0JCTxsaT5DbGFzcyBmaWxlcyBhcmUgYXJyYW5nZWQgd2l0aCBjb25zdHJ1Y3RvcnMgYW5kIHBvc3NpYmx5IGFuIGluaXQoKQotCQkgIGZ1bmN0aW9uIGZpcnN0LCBwdWJsaWMgQVBJIG1ldGhvZHMgc2Vjb25kLCBwYWNrYWdlIHNwZWNpZmljLCBwcm90ZWN0ZWQsIGFuZAotCQkgIHByaXZhdGUgbWV0aG9kcyBmb2xsb3dpbmcgKGFycmFuZ2VkIGJhc2VkIG9uIHJlbGF0ZWQgZnVuY3Rpb25hbGl0eSksIG1lbWJlcgotCQkgIHZhcmlhYmxlcyB3aXRoIHRoZWlyIGdldHRlci9zZXR0ZXIgYWNjZXNzIG1ldGhvZHMgbGFzdC48L2xpPiAKLQkJPGxpPk5vbi1zdGF0aWMgbWVtYmVyIHZhcmlhYmxlcyBhcmUgcHJlZml4ZWQgd2l0aCAibV8iLjwvbGk+IAotCQk8bGk+c3RhdGljIGZpbmFsIG1lbWJlciB2YXJpYWJsZXMgc2hvdWxkIGFsd2F5cyBiZSB1cHBlciBjYXNlLCB3aXRob3V0Ci0JCSAgdGhlICJtXyIgcHJlZml4LiBUaGV5IG5lZWQgbm90IGhhdmUgYWNjZXNzb3JzLjwvbGk+IAotCQk8bGk+UHJpdmF0ZSBtZW1iZXIgdmFyaWFibGVzIHRoYXQgYXJlIG5vdCBhY2Nlc3NlZCBvdXRzaWRlIHRoZSBjbGFzcyBuZWVkCi0JCSAgbm90IGhhdmUgZ2V0dGVyL3NldHRlciBtZXRob2RzIGRlY2xhcmVkLjwvbGk+IAotCQk8bGk+UHJpdmF0ZSBtZW1iZXIgdmFyaWFibGVzIHRoYXQgYXJlIGFjY2Vzc2VkIG91dHNpZGUgdGhlIGNsYXNzIHNob3VsZAotCQkgIGhhdmUgZWl0aGVyIHBhY2thZ2Ugc3BlY2lmaWMgb3IgcHVibGljIGdldHRlci9zZXR0ZXIgbWV0aG9kcyBkZWNsYXJlZC4gQWxsCi0JCSAgYWNjZXNzb3JzIHNob3VsZCBmb2xsb3cgdGhlIGJlYW4gZGVzaWduIHBhdHRlcm5zLjwvbGk+IAotCQk8bGk+UGFja2FnZS1zY29wZWQgbWVtYmVyIHZhcmlhYmxlcywgcHVibGljIG1lbWJlciB2YXJpYWJsZXMsIGFuZAotCQkgIHByb3RlY3RlZCBtZW1iZXIgdmFyaWFibGVzIHNob3VsZCBub3QgYmUgZGVjbGFyZWQuPC9saT4gCi0JIDwvb2w+IAotICA8L3MyPjxhbmNob3IgbmFtZT0ib3BlbiIvPiAKLSAgCi08L3MxPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy9kZXNpZ24vb3JnX2FwYWNoZS5naWYgYi94ZG9jcy9zb3VyY2VzL2Rlc2lnbi9vcmdfYXBhY2hlLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTA1ZjI2NC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL2Rlc2lnbi9vcmdfYXBhY2hlLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3Byb2Nlc3MuZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24vcHJvY2Vzcy5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM3YTg3MWUuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy9kZXNpZ24vcHJvY2Vzcy5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL2Rlc2lnbi90cmF4LmdpZiBiL3hkb2NzL3NvdXJjZXMvZGVzaWduL3RyYXguZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4ZWI5NjE0Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3RyYXguZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy9kZXNpZ24veGFsYW4uZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24veGFsYW4uZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYTRhNTdjLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3hhbGFuLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3hhbGFuMV8xeDEuZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24veGFsYW4xXzF4MS5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM5ZTE1MzYuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy9kZXNpZ24veGFsYW4xXzF4MS5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL2Rlc2lnbi94bWxsb2dvLmdpZiBiL3hkb2NzL3NvdXJjZXMvZGVzaWduL3htbGxvZ28uZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNjMxODhkLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3htbGxvZ28uZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy9kZXNpZ24veHBhdGguZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24veHBhdGguZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjZjI4ZjljLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3hwYXRoLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMvZGVzaWduL3hzbHRfYWJzdHJhY3QuZ2lmIGIveGRvY3Mvc291cmNlcy9kZXNpZ24veHNsdF9hYnN0cmFjdC5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZhMDQxYTYuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy9kZXNpZ24veHNsdF9hYnN0cmFjdC5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL2VudGl0aWVzLmVudCBiL3hkb2NzL3NvdXJjZXMvZW50aXRpZXMuZW50CmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhNDVkY2NiLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMvZW50aXRpZXMuZW50CisrKyAvZGV2L251bGwKQEAgLTEsNjggKzAsMCBAQAotPD94bWwgZW5jb2Rpbmc9IlVTLUFTQ0lJIj8+Ci0KLTwhRU5USVRZIHhzbHQ0aiAiWGFsYW4tSmF2YSI+Ci08IUVOVElUWSB4c2x0NGoyICJYYWxhbi1KYXZhIDIiPgotPCFFTlRJVFkgeHNsdDRqLWRpc3QgInhhbGFuLWpfMl8yX0QxMCI+Ci08IUVOVElUWSB4c2x0NGotY3VycmVudCAiJnhzbHQ0ajsgdmVyc2lvbiAyLjIuRDEwIj4KLTwhRU5USVRZIHhtbDRqICJYZXJjZXMtSmF2YSI+Ci08IUVOVElUWSB4bWw0ai11c2VkICImeG1sNGo7IHZlcnNpb24gMS40LjMiPgotPCFFTlRJVFkgeHNsdDRjICJYYWxhbi1DKysiPgotPCFFTlRJVFkgeG1sNGMgIlhlcmNlcy1DKysiPgotPCFFTlRJVFkgZG93bmxvYWQgIlRoZSAmeHNsdDRqLWN1cnJlbnQ7IGRvd25sb2FkIGZyb20geG1sLmFwYWNoZS5vcmcgaW5jbHVkZXMgeGVyY2VzLmphciBmcm9tICZ4bWw0ai11c2VkOy4iPgotCi08IUVOVElUWSB4c2x0Y3doYXRzbmV3aGVhZCAnPGxpPjxsaW5rIGFuY2hvcj0ieHNsdGMiPlhTTFRDPC9saW5rPjwvbGk+Jz4KLSAgICAgICAgICAgICAgICAgICAgICAgICAKLTwhRU5USVRZIHhzbHRjd2hhdHNuZXcgJzxhbmNob3IgbmFtZT0ieHNsdGMiLz48czIgdGl0bGU9IlhTTFRDIj4KLSAgICAgICAgICAgICAgICA8cD5JbiBBcHJpbCAyMDAxLCBTdW4gZG9uYXRlZCBYU0xUQyB0byB0aGUgWGFsYW4gcHJvamVjdC4gWFNMVEMgY29tcGlsZXMgc3R5bGVzaGVldHMgaW50byB0cmFuc2xldHMgYW5kCi0gICAgICAgICAgICAgICAgcHJvdmlkZXMgYSBydW50aW1lIGVudmlyb25tZW50IGZvciB1c2luZyB0cmFuc2xldHMgdG8gdHJhbnNmb3JtIFhNTCBkb2N1bWVudHMuIEluaXRpYWxseSwgWFNMVEMgaXMKLSAgICAgICAgICAgICAgICBhdmFpbGFibGUgaW4gYSBzZXBhcmF0ZSBKQVIuIE92ZXIgdGltZSwgd2UgcGxhbiB0byBpbnRlZ3JhdGUgdGhlIHR3byBjb2RlYmFzZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLAotICAgICAgICAgICAgICAgIHNlZSA8bGluayBpZHJlZj0ieHNsdGNfdXNhZ2UiPlVzaW5nIFhTTFRDPC9saW5rPiwgPGxpbmsgaWRyZWY9InJlYWRtZSIgYW5jaG9yPSJ4c2x0Y3JlbGVhc2Vub3RlcyI+WFNMVEMgCi0gICAgICAgICAgICAgICAgUmVsZWFzZSBOb3RlczwvbGluaz4sIGFuZCA8anVtcCBocmVmPSJ4c2x0Yy9pbmRleC5odG1sIj5YU0xUQyBEZXNpZ248L2xpbms+LjwvcD4KLSAgICAgICAgICAgICAgICA8L3MyPic+Ci0gICAgICAgICAgICAgICAgCi08IUVOVElUWSB4c2x0Y3JlbGVhc2Vub3Rlc2VudHJ5ICc8bGk+PGxpbmsgYW5jaG9yPSJ4c2x0Y3JlbGVhc2Vub3RlcyI+WFNMVEMgUmVsZWFzZSBOb3RlczwvbGluaz48L2xpPic+Ci0KLTwhRU5USVRZIHhzbHRjc2FtcGxlc2hlYWQgJzxsaT48bGluayBhbmNob3I9InRyYW5zbGV0cyI+dHJhbnNsZXRzPC9saW5rPjwvbGk+Jz4KLQotPCFFTlRJVFkgeHNsdGNzYW1wbGVzICc8YW5jaG9yIG5hbWU9InRyYW5zbGV0cyIvPjxzMiB0aXRsZT0iVHJhbnNsZXRzIj4KLSAgICAgICAgICAgICAgICAgPHVsPgotICAgICAgICAgICAgICAgICA8bGk+PGxpbmsgYW5jaG9yPSJ4c2x0YzEiPkpBWFBUcmFuc2xldE9uZVRyYW5zZm9ybWF0aW9uPC9saW5rPjwvbGk+Ci0gICAgICAgICAgICAgICAgIDxsaT48bGluayBhbmNob3I9InhzbHRjMiI+SkFYUFRyYW5zbGV0TXVsdGlwbGVUcmFuc2Zvcm1hdGlvbnM8L2xpbms+PC9saT4KLSAgICAgICAgICAgICAgICAgPC91bD4KLSAgICAgICAgICAgICAgICAgPHA+U2VlIGFsc286IDxsaW5rIGlkcmVmPSJyZWFkbWUiIGFuY2hvcj0ieHNsdGNkZW1vcyI+WFNMVEMgZGVtb3M8L2xpbms+LjwvcD48YW5jaG9yIG5hbWU9InhzbHRjMSIvPgotICAgICAgICAgICAgICAgICA8cD5Zb3UgY2FuIHVzZSB0aGUgVHJBWC9KQVhQIDEuMSBpbnRlcmZhY2VzIHRvIGNvbXBpbGUgYW5kIHJ1biB0cmFuc2xldHMuIEZvciB0aGlzIHJlbGVhc2UsIHlvdSBtdXN0IHN0aWxsCi0gICAgICAgICAgICAgICAgIHVzZSBTdHJlYW1Tb3VyY2Ugb2JqZWN0cyBmb3IgdGhlIFhTTCBzdHlsZXNoZWV0IGFuZCBYTUwgaW5wdXQgZG9jdW1lbnQsIGFuZCBhIFN0cmVhbVJlc3VsdCBvYmplY3QgZm9yIHRoZSAKLSAgICAgICAgICAgICAgICAgdHJhbnNmb3JtYXRpb24gb3V0cHV0LiBGb3IgYW4gb3ZlcnZpZXcgb2YgdGhlIHVzYWdlIHBhdHRlcm5zIHRoZXNlIHNhbXBsZXMgaWxsdXN0cmF0ZSwgc2VlIAotICAgICAgICAgICAgICAgICA8bGluayBpZHJlZj0ieHNsdGNfdXNhZ2UiIGFuY2hvcj0iYXBpIj5DYWxsaW5nIFhTTFRDIHdpdGggdGhlIFRyQVgvSkFYUCBBUEk8L2xpbms+LjwvcD4KLSAgICAgICAgICAgICAgICAgPGFuY2hvciBuYW1lPSJ4c2x0Y3ByZXBhcmUiLz4KLSAgICAgICAgICAgICAgICAgPHA+PGVtPkltcG9ydGFudDo8L2VtPiBUbyBydW4gdGhlc2Ugc2FtcGxlcywgeW91IG11c3QgY29tcGlsZSB0aGUgc2FtcGxlIGNsYXNzIGZpbGVzIGFuZCBhZGp1c3QgdGhlIAotICAgICAgICAgICAgICAgICBzeXN0ZW0gY2xhc3NwYXRoLjwvcD4KLSAgICAgICAgICAgICAgICAgPG9sPgotICAgICAgICAgICAgICAgICAgIDxsaT5UbyBjb21waWxlIHRoZSBzYW1wbGVzLCB5b3UgY2FuIHJ1biB0aGUgQW50IGJ1aWxkIGZyb20gdGhlIHJvb3QgZGlyZWN0b3J5IGFzIGZvbGxvd3M6PGJyLz48YnIvPgotICAgICAgICAgICAgICAgICAgIDxjb2RlPiZuYnNwOyZuYnNwO2J1aWxkIHhzbHRjLnNhbXBsZXM8L2NvZGU+PGJyLz48YnIvPjwvbGk+Ci0gICAgICAgICAgICAgICAgICAgPGxpPkFkZCB4c2x0Yy5qYXIsIHJ1bnRpbWUuamFyLCBCQ0VMLmphciwgamF2YV9jdXAuamFyLCBhbmQgdGhlIHNhbXBsZXMvdHJhbnNsZXRzIHN1YmRpcmVjdG9yeSB0byAKLSAgICAgICAgICAgICAgICAgICB0aGUgY2xhc3NwYXRoPC9saT4KLSAgICAgICAgICAgICAgICAgPC9vbD4KLSAgICAgICAgICAgICAgICAgPG5vdGU+VGhlIEpBUiBmaWxlcyBsaXN0ZWQgYWJvdmUgYXJlIGluIHRoZSBiaW4gZGlyZWN0b3J5LiAKLSAgICAgICAgICAgICAgICAgVGhlIHNhbXBsZXMvdHJhbnNsZXRzIGRpcmVjdG9yeSBjb250YWlucyB0aGUgc2FtcGxlIGNsYXNzIGZpbGVzIGFzIHdlbGwgYXMgdGhlIHRyYW5zbGV0IGNsYXNzIGZpbGUgdGhhdCBpcwotICAgICAgICAgICAgICAgICBnZW5lcmF0ZWQgYXQgdHVuIHRpbWUgKHRvZG8uY2xhc3MgZnJvbSB0aGUgdG9kby54c2wgc3R5bGVzaGVldCkuPC9ub3RlPiAKLSAgICAgICAgICAgICAgICAgPGFuY2hvciBuYW1lPSJ4c2x0YzEiLz4KLSAgICAgICAgICAgICAgICAgPHMzIHRpdGxlPSJKQVhQVHJhbnNsZXRPbmVUcmFuc2Zvcm1hdGlvbiI+Ci0gICAgICAgICAgICAgICAgIDxwPldoYXQgaXQgZG9lczogVXNlcyB0aGUgWFNMVEMgVHJhbnNmb3JtZXJGYWN0b3J5IHRvIGNvbXBpbGUgYSB0cmFuc2xldCBhbmQgdXNlCi0gICAgICAgICAgICAgICAgIHRoZSB0cmFuc2xldCB0byB0cmFuc2Zvcm0gdGhlIFhTTFRDIHRvLWRvIGxpc3QgZnJvbSBYTUwgaW50byBIVE1MLjwvcD4KLSAgICAgICAgICAgICAgICAgPHA+Q29tcGxldGUgdGhlIDxsaW5rIGFuY2hvcj0ieHNsdGNwcmVwYXJlIj5zdGVwcyBkZXRhaWxlZCBhYm92ZTwvbGluaz4sIGFuZCBydW4gdGhpcyBzYW1wbGUgCi0gICAgICAgICAgICAgICAgIGZyb20gdGhlIHRyYW5zbGV0cyBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4KLSAgICAgICAgICAgICAgICAgPHA+PGNvZGU+amF2YSBKQVhQVHJhbnNsZXRPbmVUcmFuc2Zvcm1hdGlvbjwvY29kZT48L3A+Ci0gICAgICAgICAgICAgICAgIDxwPlZpZXcgdGhlIHJlc3VsdCBpbiB0b2RvLXhzbHRjLmh0bWwuPC9wPgotICAgICAgICAgICAgICAgICA8L3MzPjxhbmNob3IgbmFtZT0ieHNsdGMyIi8+Ci0gICAgICAgICAgICAgICAgIDxzMyB0aXRsZT0iSkFYUFRyYW5zbGV0TXVsdGlwbGVUcmFuc2Zvcm1hdGlvbnMiPgotICAgICAgICAgICAgICAgICA8cD5XaGF0IGl0IGRvZXM6IFVzZXMgdGhlIFhTTFRDIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBjb21waWxlIGEgdHJhbnNsZXQgYW5kIHVzZQotICAgICAgICAgICAgICAgICB0aGUgVGVtcGxhdGVzIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHRyYW5zbGV0IHRvIHRyYW5zZm9ybSB0aGUgWFNMVEMgYW5kIFhhbGFuIHRvLWRvIGxpc3RzIGZyb20gWE1MIAotICAgICAgICAgICAgICAgICBpbnRvIEhUTUwuPC9wPgotICAgICAgICAgICAgICAgICA8cD5Db21wbGV0ZSB0aGUgPGxpbmsgYW5jaG9yPSJ4c2x0Y3ByZXBhcmUiPnN0ZXBzIGRldGFpbGVkIGFib3ZlPC9saW5rPiwgYW5kIHJ1biB0aGlzIHNhbXBsZSAKLSAgICAgICAgICAgICAgICAgZnJvbSB0aGUgdHJhbnNsZXRzIHN1YmRpcmVjdG9yeSB3aXRoPC9wPgotICAgICAgICAgICAgICAgICA8cD48Y29kZT5qYXZhIEpBWFBUcmFuc2xldE9uZVRyYW5zZm9ybWF0aW9uPC9jb2RlPjwvcD4KLSAgICAgICAgICAgICAgICAgPHA+VmlldyB0aGUgcmVzdWx0cyBpbiB0b2RvLXhzbHRjLmh0bWwgYW5kIHRvZG8teGFsYW4uaHRtbC48L3A+ICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgICA8L3MzPgotICAgICAgICAgICAgICAgICA8L3MyPic+Ci0gICAgICAgICAgICAgICAgCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuLWNvbGxhdGUueHNsIGIveGRvY3Mvc291cmNlcy94YWxhbi1jb2xsYXRlLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2NjYWFkMS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuLWNvbGxhdGUueHNsCisrKyAvZGV2L251bGwKQEAgLTEsMzIgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci0KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaCA9Ii8iPgotICA8ZG9jdW1lbnRhdGlvbj4KLSAgICA8Y2hhcHRlciBpZD0iaW5kZXgiPjx4c2w6Y29weS1vZiBzZWxlY3Q9ImRvY3VtZW50KCd4YWxhbi9pbmRleC54bWwnKSIvPjwvY2hhcHRlcj4gIAotICAgIDxjaGFwdGVyIGlkPSJ3aGF0c25ldyI+PHhzbDpjb3B5LW9mIHNlbGVjdD0iZG9jdW1lbnQoJ3hhbGFuL3doYXRzbmV3LnhtbCcpIi8+PC9jaGFwdGVyPgotICAgIDxjaGFwdGVyIGlkPSJvdmVydmlldyI+PHhzbDpjb3B5LW9mIHNlbGVjdD0iZG9jdW1lbnQoJ3hhbGFuL292ZXJ2aWV3LnhtbCcpIi8+PC9jaGFwdGVyPgotICAgIDxjaGFwdGVyIGlkPSJnZXRzdGFydGVkIj48eHNsOmNvcHktb2Ygc2VsZWN0PSJkb2N1bWVudCgneGFsYW4vZ2V0c3RhcnRlZC54bWwnKSIvPjwvY2hhcHRlcj4KLSAgICA8Y2hhcHRlciBpZD0iZmFxIj48eHNsOmNvcHktb2Ygc2VsZWN0PSJkb2N1bWVudCgneGFsYW4vZmFxLnhtbCcpIi8+PC9jaGFwdGVyPgotICAgIDxjaGFwdGVyIGlkPSJzYW1wbGVzIj48eHNsOmNvcHktb2Ygc2VsZWN0PSJkb2N1bWVudCgneGFsYW4vc2FtcGxlcy54bWwnKSIvPjwvY2hhcHRlcj4KLSAgICA8Y2hhcHRlciBpZD0iY29tbWFuZGxpbmUiPjx4c2w6Y29weS1vZiBzZWxlY3Q9ImRvY3VtZW50KCd4YWxhbi9jb21tYW5kbGluZS54bWwnKSIvPjwvY2hhcHRlcj4KLSAgICA8Y2hhcHRlciBpZD0idXNhZ2VwYXR0ZXJucyI+PHhzbDpjb3B5LW9mIHNlbGVjdD0iZG9jdW1lbnQoJ3hhbGFuL3VzYWdlcGF0dGVybnMueG1sJykiLz48L2NoYXB0ZXI+Ci0gICAgPGNoYXB0ZXIgaWQ9InRyYXgiPjx4c2w6Y29weS1vZiBzZWxlY3Q9ImRvY3VtZW50KCd4YWxhbi90cmF4LnhtbCcpIi8+PC9jaGFwdGVyPgotICAgIDxjaGFwdGVyIGlkPSJleHRlbnNpb25zIj48eHNsOmNvcHktb2Ygc2VsZWN0PSJkb2N1bWVudCgneGFsYW4vZXh0ZW5zaW9ucy54bWwnKSIvPjwvY2hhcHRlcj4KLSAgICA8Y2hhcHRlciBpZD0iZXh0ZW5zaW9uc2xpYiI+PHhzbDpjb3B5LW9mIHNlbGVjdD0iZG9jdW1lbnQoJ3hhbGFuL2V4dGVuc2lvbnNsaWIueG1sJykiLz48L2NoYXB0ZXI+Ci0gICAgPGNoYXB0ZXIgaWQ9InJlYWRtZSI+PHhzbDpjb3B5LW9mIHNlbGVjdD0iZG9jdW1lbnQoJ3hhbGFuL3JlYWRtZS54bWwnKSIvPjwvY2hhcHRlcj4KLSAgICA8Y2hhcHRlciBpZD0iYXBpIj4KLSAgICAgIDxzMSB0aXRsZT0iSmF2YSBBUEkiPgotICAgICAgICA8cD5KYXZhZG9jIGZvciB0aGUgZW50aXJlIFhhbGFuLUphdmEgQVBJOjwvcD4KLSAgICAgICAgPHVsPgotICAgICAgICAgIDxsaT48anVtcCBocmVmPSJhcGlkb2NzL2luZGV4Lmh0bWwiPlhhbGFuLUphdmEgMiBBUEk8L2p1bXA+PC9saT4KLSAgICAgICAgICA8bGk+PGp1bXAgaHJlZj0iY29tcGF0X2FwaWRvY3MvaW5kZXguaHRtbCI+WGFsYW4tSmF2YSAxIGNvbXBhdGliaWxpdHkgQVBJPC9qdW1wPjwvbGk+Ci0gICAgICAgIDwvdWw+ICAgICAgICAgCi0gICAgICA8L3MxPgotICAgIDwvY2hhcHRlcj4KLSAgPC9kb2N1bWVudGF0aW9uPgotPC94c2w6dGVtcGxhdGU+Ci08L3hzbDpzdHlsZXNoZWV0PgotCi0KZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveGFsYW4tamxvY2FsLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4tamxvY2FsLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTFmMTQ5ZS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuLWpsb2NhbC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw5MyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTwhRE9DVFlQRSBib29rIFNZU1RFTSAic2JrOi9zdHlsZS9kdGQvYm9vay5kdGQiPgotCi08IS0tCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotIC0tPgotCi08Ym9vayB0aXRsZT0iWGFsYW4gWFNMIFRyYW5zZm9ybWVyIFVzZXIncyBHdWlkZSIgY29weXJpZ2h0PSIyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiI+Ci0gIDxyZXNvdXJjZXMgc291cmNlPSJzYms6L3NvdXJjZXMveGFsYW4vcmVzb3VyY2VzLnhtbCIvPgotICA8ZG9jdW1lbnQgaWQ9IndoYXRzbmV3IiBsYWJlbD0iV2hhdCdzIE5ldyIgc291cmNlPSJ4YWxhbi93aGF0c25ldy54bWwiLz4KLSAgPGRvY3VtZW50IGlkPSJkdG0iIGxhYmVsPSJEVE0iIHNvdXJjZT0ieGFsYW4vZHRtLnhtbCIvPgotICA8ZG9jdW1lbnQgaWQ9InhzbHRjX3VzYWdlIiBsYWJlbD0iWFNMVEMgVHJhbnNsZXRzIiBzb3VyY2U9InhhbGFuL3hzbHRjX3VzYWdlLnhtbCIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGRvY3VtZW50IGlkPSJvdmVydmlldyIgbGFiZWw9Ik92ZXJ2aWV3IiBzb3VyY2U9InhhbGFuL292ZXJ2aWV3LnhtbCIvPgotICA8ZG9jdW1lbnQgaWQ9ImdldHN0YXJ0ZWQiIGxhYmVsPSJHZXR0aW5nIFN0YXJ0ZWQiIHNvdXJjZT0ieGFsYW4vZ2V0c3RhcnRlZC54bWwiLz4KLSAgPHNlcGFyYXRvci8+Ci0gIDxmYXFzIGlkPSJmYXEiIGxhYmVsPSJGQVFzIiBzb3VyY2U9InhhbGFuL2ZhcS54bWwiLz4KLSAgPHNlcGFyYXRvci8+Ci0gIDxkb2N1bWVudCBpZD0ic2FtcGxlcyIgbGFiZWw9IlNhbXBsZSBBcHBzIiBzb3VyY2U9InhhbGFuL3NhbXBsZXMueG1sIi8+Ci0gIDxkb2N1bWVudCBpZD0iY29tbWFuZGxpbmUiIGxhYmVsPSJDb21tYW5kIExpbmUiIHNvdXJjZT0ieGFsYW4vY29tbWFuZGxpbmUueG1sIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZG9jdW1lbnQgaWQ9InVzYWdlcGF0dGVybnMiIGxhYmVsPSJVc2FnZSBQYXR0ZXJucyIgc291cmNlPSJ4YWxhbi91c2FnZXBhdHRlcm5zLnhtbCIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGRvY3VtZW50IGlkPSJ0cmF4IiBsYWJlbD0iVHJBWCIgc291cmNlPSJ4YWxhbi90cmF4LnhtbCIvPgotICA8ZXh0ZXJuYWwgaHJlZj0iYXBpZG9jcy9pbmRleC5odG1sIiBsYWJlbD0iQVBJIChKYXZhZG9jKSIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGRvY3VtZW50IGlkPSJleHRlbnNpb25zIiBsYWJlbD0iRXh0ZW5zaW9ucyIgc291cmNlPSJ4YWxhbi9leHRlbnNpb25zLnhtbCIvPgotICA8ZG9jdW1lbnQgaWQ9ImV4dGVuc2lvbnNsaWIiIGxhYmVsPSJFeHRlbnNpb25zIExpYnJhcnkiIHNvdXJjZT0ieGFsYW4vZXh0ZW5zaW9uc2xpYi54bWwiLz4KLSAgPHNlcGFyYXRvci8+Ci0gIDxkb2N1bWVudCBpZD0icmVhZG1lIiBsYWJlbD0iUmVsZWFzZSBOb3RlcyIgc291cmNlPSJ4YWxhbi9yZWFkbWUueG1sIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZXh0ZXJuYWwgaHJlZj0iZGVzaWduL2Rlc2lnbjJfMF8wLmh0bWwiIGxhYmVsPSJYYWxhbiAyIERlc2lnbiIvPgotICA8ZXh0ZXJuYWwgaHJlZj0ieHNsdGMvaW5kZXguaHRtbCIgbGFiZWw9IlhTTFRDIERlc2lnbiIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGV4dGVybmFsIGhyZWY9InJlYWRtZS5odG1sI2J1Z3MiIGxhYmVsPSJCdWdzIi8+Ci0gIDxleHRlcm5hbCBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4tai90ZXN0L292ZXJ2aWV3Lmh0bWwiIGxhYmVsPSJUZXN0aW5nIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZXh0ZXJuYWwgaHJlZj0idG9kby5odG1sI2RldmVsb3Blci1saXN0IiBsYWJlbD0iQ3JlZGl0cyIvPgotICA8ZXh0ZXJuYWwgaHJlZj0ieHNsdGMvdG9kby5odG1sI2RldmVsb3Blci1saXN0IiBsYWJlbD0iWFNMVEMgQ3JlZGl0cyIvPiAgCi08L2Jvb2s+CmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuLWpzaXRlLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4tanNpdGUueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYmVkYjkzLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4tanNpdGUueG1sCisrKyAvZGV2L251bGwKQEAgLTEsOTYgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08IURPQ1RZUEUgYm9vayBTWVNURU0gInNiazovc3R5bGUvZHRkL2Jvb2suZHRkIj4KLQotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLQotPGJvb2sgdGl0bGU9IlhhbGFuIFhTTCBUcmFuc2Zvcm1lciBVc2VyJ3MgR3VpZGUiIGNvcHlyaWdodD0iMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iPgotICA8cmVzb3VyY2VzIHNvdXJjZT0ic2JrOi9zb3VyY2VzL3hhbGFuL3Jlc291cmNlcy54bWwiLz4KLSAgPGV4dGVybmFsIGhyZWY9Ii4uL2luZGV4Lmh0bWwiIGxhYmVsPSJIb21lIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZG9jdW1lbnQgaWQ9ImluZGV4IiBsYWJlbD0iWGFsYW4tSiAyLjIuRDEwIiBzb3VyY2U9InhhbGFuL2luZGV4LnhtbCIvPgotICA8ZG9jdW1lbnQgaWQ9IndoYXRzbmV3IiBsYWJlbD0iV2hhdCdzIE5ldyIgc291cmNlPSJ4YWxhbi93aGF0c25ldy54bWwiLz4KLSAgPGRvY3VtZW50IGlkPSJkdG0iIGxhYmVsPSJEVE0iIHNvdXJjZT0ieGFsYW4vZHRtLnhtbCIvPiAgCi0gIDxkb2N1bWVudCBpZD0ieHNsdGNfdXNhZ2UiIGxhYmVsPSJYU0xUQyBUcmFuc2xldHMiIHNvdXJjZT0ieGFsYW4veHNsdGNfdXNhZ2UueG1sIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZG9jdW1lbnQgaWQ9Im92ZXJ2aWV3IiBsYWJlbD0iT3ZlcnZpZXciIHNvdXJjZT0ieGFsYW4vb3ZlcnZpZXcueG1sIi8+Ci0gIDxkb2N1bWVudCBpZD0iZ2V0c3RhcnRlZCIgbGFiZWw9IkdldHRpbmcgU3RhcnRlZCIgc291cmNlPSJ4YWxhbi9nZXRzdGFydGVkLnhtbCIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGZhcXMgaWQ9ImZhcSIgbGFiZWw9IkZBUXMiIHNvdXJjZT0ieGFsYW4vZmFxLnhtbCIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGRvY3VtZW50IGlkPSJzYW1wbGVzIiBsYWJlbD0iU2FtcGxlIEFwcHMiIHNvdXJjZT0ieGFsYW4vc2FtcGxlcy54bWwiLz4KLSAgPGRvY3VtZW50IGlkPSJjb21tYW5kbGluZSIgbGFiZWw9IkNvbW1hbmQgTGluZSIgc291cmNlPSJ4YWxhbi9jb21tYW5kbGluZS54bWwiLz4KLSAgPHNlcGFyYXRvci8+Ci0gIDxkb2N1bWVudCBpZD0idXNhZ2VwYXR0ZXJucyIgbGFiZWw9IlVzYWdlIFBhdHRlcm5zIiBzb3VyY2U9InhhbGFuL3VzYWdlcGF0dGVybnMueG1sIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZG9jdW1lbnQgaWQ9InRyYXgiIGxhYmVsPSJUckFYIiBzb3VyY2U9InhhbGFuL3RyYXgueG1sIi8+Ci0gIDxleHRlcm5hbCBocmVmPSJhcGlkb2NzL2luZGV4Lmh0bWwiIGxhYmVsPSJBUEkgKEphdmFkb2MpIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZG9jdW1lbnQgaWQ9ImV4dGVuc2lvbnMiIGxhYmVsPSJFeHRlbnNpb25zIiBzb3VyY2U9InhhbGFuL2V4dGVuc2lvbnMueG1sIi8+Ci0gIDxkb2N1bWVudCBpZD0iZXh0ZW5zaW9uc2xpYiIgbGFiZWw9IkV4dGVuc2lvbnMgTGlicmFyeSIgc291cmNlPSJ4YWxhbi9leHRlbnNpb25zbGliLnhtbCIvPgotICA8c2VwYXJhdG9yLz4KLSAgPGRvY3VtZW50IGlkPSJyZWFkbWUiIGxhYmVsPSJSZWxlYXNlIE5vdGVzIiBzb3VyY2U9InhhbGFuL3JlYWRtZS54bWwiLz4KLSAgPHNlcGFyYXRvci8+Ci0gIDxleHRlcm5hbCBocmVmPSJkZXNpZ24vZGVzaWduMl8wXzAuaHRtbCIgbGFiZWw9IlhhbGFuIDIgRGVzaWduIi8+Ci0gIDxleHRlcm5hbCBocmVmPSJ4c2x0Yy9pbmRleC5odG1sIiBsYWJlbD0iWFNMVEMgRGVzaWduIi8+ICAKLSAgPHNlcGFyYXRvci8+Ci0gIDxleHRlcm5hbCBocmVmPSJyZWFkbWUuaHRtbCNidWdzIiBsYWJlbD0iQnVncyIvPiAgCi0gIDxleHRlcm5hbCBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4tai90ZXN0L292ZXJ2aWV3Lmh0bWwiIGxhYmVsPSJUZXN0aW5nIi8+Ci0gIDxzZXBhcmF0b3IvPgotICA8ZXh0ZXJuYWwgaHJlZj0idG9kby5odG1sI2RldmVsb3Blci1saXN0IiBsYWJlbD0iQ3JlZGl0cyIvPgotICA8ZXh0ZXJuYWwgaHJlZj0ieHNsdGMvdG9kby5odG1sI2RldmVsb3Blci1saXN0IiBsYWJlbD0iWFNMVEMgQ3JlZGl0cyIvPiAgICAgIAotPC9ib29rPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi9jb21tYW5kbGluZS54bWwgYi94ZG9jcy9zb3VyY2VzL3hhbGFuL2NvbW1hbmRsaW5lLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDM0ZjBkYS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL2NvbW1hbmRsaW5lLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDEyMiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLQotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLSAKLQotPHMxIHRpdGxlPSJDb21tYW5kLUxpbmUgVXRpbGl0eSI+Ci0gICAKLSAgIDxzMiB0aXRsZT0iVXNpbmcgdGhlIENvbW1hbmQtTGluZSBVdGlsaXR5Ij4KLSAgICAgIDxwPlRvIHBlcmZvcm0gYSB0cmFuc2Zvcm1hdGlvbiwgeW91IGNhbiBjYWxsICZ4c2x0NGo7IGZyb20gdGhlIGNvbW1hbmQgbGluZSAob3Igc2NyaXB0KSwgCi0gICAgICBhbiBhcHBsZXQsIGFuIGFwcGxpY2F0aW9uLCBvciBhIHNlcnZsZXQgKHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyI+VXNhZ2UgUGF0dGVybnM8L2xpbms+KS48L3A+Ci0gICAgIDxwPlRoZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyBtYWluKCkgbWV0aG9kIHByb3ZpZGVzIGEgY29tbWFuZC1saW5lIGludGVyZmFjZQotICAgIGZvciBwZXJmb3JtaW5nIFhTTCB0cmFuc2Zvcm1hdGlvbi4gVG8gcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uIGZyb20gdGhlIGNvbW1hbmQgbGluZSBvciBhIHNjcmlwdCwKLSAgICBkbyB0aGUgZm9sbG93aW5nOjwvcD4KLSAJCTxvbD4KLSAgICA8bGk+RG93bmxvYWQgJnhzbHQ0ajsuPGJyLz48YnIvPjwvbGk+IAotICAgIDxsaT48bGluayBpZHJlZj0iZ2V0c3RhcnRlZCIgYW5jaG9yPSJjbGFzc3BhdGgiPlNldCB0aGUgSmF2YSBjbGFzc3BhdGg8L2xpbms+IHRvIGluY2x1ZGUgeGFsYW4uamFyIGFuZAotICAgIHhlcmNlcy5qYXIgKG9yIGFub3RoZXIgY29uZm9ybWFudCBYTUwgUGFyc2VyIC0tIHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJwbHVnIj5QbHVnZ2luZyBpbiAKLSAgICB0aGUgVHJhbnNmb3JtZXIgYW5kIFhNTCBwYXJzZXI8L2xpbms+KS48YnIvPjxici8+PC9saT4KLSAgICA8bGk+Q2FsbCBqYXZhIGFuZCB0aGUgUHJvY2VzcyBjbGFzcyB3aXRoIHRoZSBhcHByb3ByaWF0ZSBmbGFncyBhbmQKLSAgICBhcmd1bWVudHMgKGRlc2NyaWJlZCBiZWxvdykuIFRoZSBmb2xsb3dpbmcgY29tbWFuZCBsaW5lLCBmb3IgZXhhbXBsZSwgaW5jbHVkZXMgdGhlIC1JTiwgLVhTTCwKLSAgICBhbmQgLU9VVCBmbGFncyB3aXRoIHRoZWlyIGFjY29tcGFueWluZyBhcmd1bWVudHMgLS0gdGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQsIHRoZSBYU0wKLSAgICBzdHlsZXNoZWV0LCBhbmQgdGhlIG91dHB1dCBmaWxlOjxici8+PGJyLz4KLSAgICA8Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzIC1JTiBmb28ueG1sIC1YU0wgZm9vLnhzbCAtT1VUIGZvby5vdXQ8L2NvZGU+Ci0gICAgPC9saT48L29sPgotICAgIDxwPlRoZSBjb21tYW5kIGxpbmUgdXRpbGl0eSBjYW4gdGFrZSB0aGUgZm9sbG93aW5nIGZsYWdzIGFuZCBhcmd1bWVudHMgKHRoZSBmbGFncyBhcmUgY2FzZSBpbnNlbnNpdGl2ZSk6PC9wPiAKLSAgICAgIDxzb3VyY2U+LUlOIGlucHV0WE1MVVJMCi0tWFNMIFhTTFRyYW5zZm9ybWF0aW9uVVJMCi0tT1VUIG91dHB1dEZpbGVOYW1lCi0tViAoVmVyc2lvbiBpbmZvKQotLVFDIChRdWlldCBQYXR0ZXJuIENvbmZsaWN0cyBXYXJuaW5ncykKLS1RICAoUXVpZXQgTW9kZSkKLS1MRiAoVXNlIGxpbmVmZWVkcyBvbmx5IG9uIG91dHB1dCAtLSBkZWZhdWx0IGlzIENSL0xGKQotLUNSIChVc2UgY2FycmlhZ2UgcmV0dXJucyBvbmx5IG9uIG91dHB1dCAtLSBkZWZhdWx0IGlzIENSL0xGKQotLUlOREVOVCAoTnVtYmVyIG9mIHNwYWNlcyB0byBpbmRlbnQgZWFjaCBsZXZlbCBpbiBvdXRwdXQgdHJlZSAtLWRlZmF1bHQgaXMgMCkKLS1UVCAoVHJhY2UgdGhlIHRlbXBsYXRlcyBhcyB0aGV5IGFyZSBiZWluZyBjYWxsZWQpCi0tVEcgKFRyYWNlIGVhY2ggcmVzdWx0IHRyZWUgZ2VuZXJhdGlvbiBldmVudCkKLS1UUyAoVHJhY2UgZWFjaCBzZWxlY3Rpb24gZXZlbnQpCi0tVFRDIChUcmFjZSB0aGUgdGVtcGxhdGUgY2hpbGRyZW4gYXMgdGhleSBhcmUgYmVpbmcgcHJvY2Vzc2VkKQotLUVEVU1QIFtvcHRpb25hbF1GaWxlTmFtZSAoRG8gc3RhY2tkdW1wIG9uIGVycm9yKQotLVhNTCAoVXNlIFhNTCBmb3JtYXR0ZXIgYW5kIGFkZCBYTUwgaGVhZGVyKQotLVRFWFQgKFVzZSBzaW1wbGUgVGV4dCBmb3JtYXR0ZXIpCi0tSFRNTCAoVXNlIEhUTUwgZm9ybWF0dGVyKQotLVBBUkFNIG5hbWUgdmFsdWUgKFNldCBhIHN0eWxlc2hlZXQgcGFyYW1ldGVyKQotLURJQUcgcHV0IG91dCB0aW1pbmcgZGlhZ25vc3RpY3MKLS1VUklSRVNPTFZFUiBmdWxsQ2xhc3NOYW1lIChVc2UgYSBjdXN0b20gVVJJUmVzb2x2ZXIpCi0tRU5USVRZUkVTT0xWRVIgZnVsbENsYXNzTmFtZSAoVXNlIGEgY3VzdG9tIEVudGl0eVJlc29sdmVyKQotLUNPTlRFTlRIQU5ETEVSIGZ1bGxDbGFzc05hbWUgKFVzZSBhIGN1c3RvbSBDb250ZW50SGFuZGxlcikKLTwvc291cmNlPgotICAgICAgPHA+VXNlIDxjb2RlPi1JTjwvY29kZT4gdG8gc3BlY2lmeSB0aGUgWE1MIHNvdXJjZSBkb2N1bWVudC48L3A+IAotICAgICAgPHA+VXNlIDxjb2RlPi1YU0w8L2NvZGU+IHRvIHNwZWNpZnkgdGhlIFhTTCBzdHlsZXNoZWV0IGZpbGUuPC9wPgotICAgICAgPHA+VXNlIDxjb2RlPi1URVhUPC9jb2RlPiBpZiB5b3Ugd2FudCB0aGUgb3V0cHV0IHRvIGluY2x1ZGUgb25seSBlbGVtZW50IHZhbHVlcyAobm90IGVsZW1lbnQgdGFncyB3aXRoIGVsZW1lbnQgbmFtZXMgYW5kCi0gICAgICBhdHRyaWJ1dGVzKS48L3A+Ci0gICAgICA8cD5Vc2UgPGNvZGU+LUhUTUw8L2NvZGU+IHRvIHdyaXRlIDQuMCB0cmFuc2l0aW9uYWwgSFRNTCAoc29tZSBlbGVtZW50cywgc3VjaCBhcyAmbHQ7YnImZ3Q7LCBhcmUKLSAgICAgIG5vdCB3ZWxsIGZvcm1lZCBYTUwpLjwvcD4KLSAgICAgIDxwPlRvIHNldCBzdHlsZXNoZWV0IHBhcmFtZXRlcnMgZnJvbSB0aGUgY29tbWFuZCBsaW5lLCB1c2UgPGJyLz4KLSAgICAgIDxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0LlByb2Nlc3MgLVBBUkFNIDxyZWY+bmFtZSB2YWx1ZTwvcmVmPjwvY29kZT48L3A+Ci0gICAgICA8cD5UaGUgdmFsdWUgaXMgcGFzc2VkIHRvIHRoZSB0cmFuc2Zvcm1lciBhcyBhIFN0cmluZy48L3A+Ci0gICAgICA8cD5Vc2UgPGNvZGU+LVVSSVJFU09MVkVSPC9jb2RlPiB3aXRoIGEgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgdG8gdXRpbGl6ZSBhIGN1c3RvbSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKLSAgICAgIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9VUklSZXNvbHZlci5odG1sIj5VUklSZXNvbHZlcjwvanVtcD4gVHJBWCBpbnRlcmZhY2UgdG8gcmVzb2x2ZSBVUklzIGZvcgotICAgICAgIHhzbDppbmNsdWRlLCB4c2w6aW1wb3J0LCBhbmQgdGhlIGRvY3VtZW50KCkgZnVuY3Rpb24uPC9wPgotICAgICAgIDxwPlVzZSA8Y29kZT4tRU5USVRZUkVTT0xWRVI8L2NvZGU+IHdpdGggYSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSB0byB1dGlsaXplIGEgY3VzdG9tIGltcGxlbWVudGF0aW9uIG9mIHRoZQotICAgICAgIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL3htbC9zYXgvRW50aXR5UmVzb2x2ZXIuaHRtbCI+RW50aXR5UmVzb2x2ZXI8L2p1bXA+IFNBWCBpbnRlcmZhY2UgdG8gaGFuZGxlIGV4dGVybmFsIGVudGl0eSByZWZlcmVuY2VzLjwvcD4KLSAgICAgICA8cD5Vc2UgPGNvZGU+LUNPTlRFTlRIQU5ETEVSPC9jb2RlPiB3aXRoIGEgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgdG8gdXRpbGl6ZSBhIGN1c3RvbSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgCi0gICAgICAgPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcveG1sL3NheC9Db250ZW50SGFuZGxlci5odG1sIj5Db250ZW50SGFuZGxlcjwvanVtcD4gU0FYIGludGVyZmFjZSB0byBzZXJpYWxpemUgb3V0cHV0LjwvcD4KLSAgIDwvczI+Ci08L3MxPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi9kdG0ueG1sIGIveGRvY3Mvc291cmNlcy94YWxhbi9kdG0ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyNWNkZDA5Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4vZHRtLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDc5ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4KLQotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci0KLTxzMSB0aXRsZT0iJnhzbHQ0ajsgRFRNIj4KLTx1bD4KLSAgPGxpPjxsaW5rIGFuY2hvcj0iaW50cm8iPkludHJvZHVjdGlvbjwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJzZXR0aW5ncyI+UGVyZm9ybWFuY2Ugc2V0dGluZ3M8L2xpbms+PC9saT4gIAotPC91bD48YW5jaG9yIG5hbWU9ImludHJvIi8+Ci08czIgdGl0bGU9IkludHJvZHVjdGlvbiI+Ci0gIDxwPlRoZSBEb2N1bWVudCBUYWJsZSBNb2RlbCAoRFRNKSBpcyBhbiBpbnRlcmZhY2UgdG8gYSBEb2N1bWVudCBNb2RlbCBkZXNpZ25lZCBzcGVjaWZpY2FsbHkgZm9yIHRoZSBuZWVkcyBvZiBvdXIgWFBhdGggYW5kIFhTTFQgCi0gIGltcGxlbWVudGF0aW9ucy4gVGhlIG1vdGl2YXRpb24gYmVoaW5kIHRoaXMgbW9kZWwgaXMgdG8gb3B0aW1pemUgcGVyZm9ybWFuY2UgYW5kIG1pbmltaXplIHN0b3JhZ2UuPC9wPgotICA8cD5TcGVjaWZpY2FsbHksIERUTSBhdm9pZHMgdGhlIG92ZXJoZWFkIG9mIGluc3RhbnRpYXRpbmcgdGhlIG9iamVjdHMgdGhlIHN0YW5kYXJkIERPTSByZXF1aXJlcyB0byByZXByZXNlbnQgYSB0cmVlIG9mIG5vZGVzLiAKLSAgRFRNIHVzZXMgdW5pcXVlIGludGVnZXIgImhhbmRsZXMiIHRvIGlkZW50aWZ5IG5vZGVzLCBpbnRlZ2VyIElEIHZhbHVlcyB0byByZXByZXNlbnQgVVJMcywgbG9jYWwgbmFtZXMsIGFuZCBleHBhbmRlZCBuYW1lcywgYW5kIAotICBpbnRlZ2VyIGluZGV4IGFuZCBsZW5ndGggcmVmZXJlbmNlcyB0byBhIHN0cmluZyBidWZmZXIgdG8gcmVwcmVzZW50IHRoZSB0ZXh0IHZhbHVlIG9mIGVhY2ggbm9kZS48L3A+Ci0gIDxwPkluIGdlbmVyYWwsIHRoZSAicmVhZCIgQVBJcyB0byBEVE0gcmVzZW1ibGUgdGhvc2Ugb2YgdGhlIFczQyBEb2N1bWVudCBPYmplY3QgTW9kZWwgKDxyZXNvdXJjZS1yZWYgaWRyZWY9ImRvbSIvPikgaW50ZXJmYWNlLiAKLSAgSG93ZXZlciwgaW4gcGxhY2Ugb2YgdGhlIERPTSBvYmplY3QgdHJlZSBvZiBub2RlcywgRFRNIHVzZXMgaW50ZWdlciBhcnJheXMgYW5kIHN0cmluZyBwb29scyB0byByZXByZXNlbnQgdGhlIHN0cnVjdHVyZSBhbmQgY29udGVudCAKLSAgb2YgdGhlIFhNTCBkb2N1bWVudCB0byBiZSB0cmFuc2Zvcm1lZC4gRFRNIGFsc28gc3RydWN0dXJlcyB0aGUgZG9jdW1lbnQncyBjb250ZW50cyBzbGlnaHRseSBkaWZmZXJlbnRseSwgdG8gYmV0dGVyIG1hdGNoIHRoZSBYUGF0aCAKLSAgZGF0YSBtb2RlbDsgc29tZSBkZXRhaWxzIGFuZCBjb25zdHJhaW50cyBwcmVzZW50IGluIGEgc3RhbmRhcmQgRE9NIGFyZSBzdXBwcmVzc2VkLCBhbmQgYSBmZXcgWFBhdGgtc3BlY2lmaWMgZmVhdHVyZXMgYXJlIGFkZGVkLjwvcD4KLSAgPHA+RFRNIGlzIGludGVuZGVkIHRvIGJlIGEgcmVhZC1vbmx5IG1vZGVsLCBhbmQgc28gZG9lcyBub3QgYXR0ZW1wdCB0byByZXBsaWNhdGUgdGhlIERPTSdzIHdyaXRlIG9yIGNyZWF0ZS1ub2RlIG9wZXJhdGlvbnMuPC9wPiAKLSAgPHA+VGhlIGRldGFpbHMgb2YgY29uc3RydWN0aW5nIGEgRFRNIHZhcnkgZGVwZW5kaW5nIG9uIHdoaWNoIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgQVBJIHlvdSBhcmUgdXNpbmcuIFR3byByZWZlcmVuY2UgaW1wbGVtZW50YXRpb25zIGFyZQotICBjdXJyZW50bHkgYXZhaWxhYmxlOjwvcD4KLTx1bD4KLSAgPGxpPlNBWDJEVE0gKGJ1aWx0IHZpYSBhIFNBWCBzdHJlYW0pPC9saT4KLSAgPGxpPkRPTTJEVE0gKHdoaWNoIHByb3ZpZGVzIERUTSBhY2Nlc3MgdG8gYW4gZXhpc3RpbmcgRE9NKTwvbGk+Ci08L3VsPiAKLSAgPHA+Qm90aCBEVE1zIGNhbiBiZSBidWlsdCBpbmNyZW1lbnRhbGx5IChzZWUgPGxpbmsgYW5jaG9yPSJpbmNyZW1lbnRhbCI+aW5jcmVtZW50YWwgdHJhbnNmb3JtczwvbGluaz4pLiBXaGVuIG9wZXJhdGluZyBpbmNyZW1lbnRhbGx5LCB0aGUKLSAgRFRNIGFsbG93cyB0aGUgWGFsYW4gcHJvY2Vzc29yIHRvIGJlZ2luIHJlYWRpbmcgdGhlIERUTSBhbmQgcGVyZm9ybWluZyB0aGUgdHJhbnNmb3JtYXRpb24gd2hpbGUgdGhlIERUTSBpcyBzdGlsbCBiZWluZyBhc3NlbWJsZWQgCi0gIChmb3IgZXhhbXBsZSwgd2hpbGUgdGhlIHBhcnNlciBpcyBzdGlsbCBwYXJzaW5nIHRoZSBYTUwgc291cmNlKSwgYW5kIGF0dGVtcHRzIHRvIGRvIG9ubHkgYXMgbXVjaCB3b3JrIGFzIGlzIG5lZWRlZCB0byBzdXBwb3J0IHRoZQotICByZWFkIHJlcXVlc3RzIGFjdHVhbGx5IG1hZGUgYnkgdGhlIFhQYXRoIG9yIFhTTFQgcHJvY2Vzc29yLjwvcD4KLSAgPHA+Rm9yIHRoZSBjb252ZW5pZW5jZSBvZiB1c2VyLXdyaXR0ZW4gZXh0ZW5zaW9ucywgYSBwcm94eSBtZWNoYW5pc20gcHJlc2VudHMgdGhlIGNvbnRlbnRzIG9mIHRoZSBEVE0gYXMgYSByZWFkLW9ubHkgc3Vic2V0IG9mIHRoZSBET00uPC9wPgotICA8L3MyPjxhbmNob3IgbmFtZT0ic2V0dGluZ3MiLz4KLSAgPHMyIHRpdGxlPSJEVE0gcGVyZm9ybWFuY2Ugc2V0dGluZ3MiPgotICA8cD4meHNsdDRqOyBpbXBsZW1lbnRzIHR3byBEVE0gcGVyZm9ybWFuY2UgZmVhdHVyZXMgdGhhdCB5b3UgY2FuIGNvbnRyb2wgd2l0aCB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5Ci0gIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuaHRtbCNzZXRBdHRyaWJ1dGUoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLk9iamVjdCkiPnNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKTwvanVtcD4KLSAgbWV0aG9kLjwvcD4KLSAgPHRhYmxlPgotICA8dHI+Ci0gICAgPHRoPkF0dHJpYnV0ZSBuYW1lIChVUkwpPC90aD4KLSAgICA8dGg+RGVmYXVsdCBzZXR0aW5nPC90aD4KLSAgICA8dGg+RGVzY3JpcHRpb248L3RoPgotICA8L3RyPgotICA8dHI+Ci0gICAgPHRkPiJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vZmVhdHVyZXMvaW5jcmVtZW50YWwiPC90ZD4KLSAgICA8dGQ+ZmFsc2U8L3RkPgotICAgIDx0ZD48bGluayBhbmNob3I9ImluY3JlbWVudGFsIj5pbmNyZW1lbnRhbCB0cmFuc2Zvcm1zPC9saW5rPjwvdGQ+Ci0gIDwvdHI+Ci0gIDx0cj4KLSAgICA8dGQ+Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi9mZWF0dXJlcy9vcHRpbWl6ZSI8L3RkPgotICAgIDx0ZD50cnVlPC90ZD4KLSAgICA8dGQ+PGxpbmsgYW5jaG9yPSJvcHRpbWl6ZWQiPm9wdGltaXplZCB0cmFuc2Zvcm1zPC9saW5rPjwvdGQ+Ci0gIDwvdHI+Ci0gIDwvdGFibGU+Ci0gIDxwPkJvdGggb2YgdGhlc2UgRFRNIHNldHRpbmdzIGFyZSBkZXNjcmliZWQgYmVsb3cuPC9wPgotICA8YW5jaG9yIG5hbWU9ImluY3JlbWVudGFsIi8+Ci0gIDxzMyB0aXRsZT0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIj4KLSAgIDxwPlNldCB0aGlzIGZlYXR1cmUgdG8gdHJ1ZSB0byBlbmFibGUgaW5jcmVtZW50YWwgdHJhbnNmb3JtYXRpb25zLiBJZiBzZXQgdG8gZmFsc2UgKHRoZSBkZWZhdWx0KSwgdGhlIHRyYW5zZm9ybSBhbmQgdGhlIHBhcnNlIAotICAgYXJlIHBlcmZvcm1lZCBvbiB0aGUgc2FtZSB0aHJlYWQuPC9wPgotICAgPG5vdGU+IFdoZW4gc2V0IHRvIHRydWU6IElmIHRoZSBwYXJzZXIgaXMgWGVyY2VzLCB3ZSBwZXJmb3JtIGFuCi1pbmNyZW1lbnRhbCB0cmFuc2Zvcm0gb24gYSBzaW5nbGUgdGhyZWFkIHVzaW5nIHRoZSBYZXJjZXMKLSAgICJwYXJzZSBvbiBkZW1hbmQiIGZlYXR1cmUuIElmIHRoZSBwYXJzZXIgaXMgbm90IFhlcmNlcywgd2UgcnVuIHRoZQotdHJhbnNmb3JtIGluIG9uZSB0aHJlYWQgYW5kIHRoZSBwYXJzZSBpbiBhbm90aGVyLiBFeGNlcHRpb246IGlmIHRoZQotICAgcGFyc2VyIGlzIG5vdCBYZXJjZXMgYW5kIHRoZSBYTUwgc291cmNlIGlzIGEgRE9NU291cmNlLCBzZXR0aW5nIHRoaXMKLWZlYXR1cmUgdG8gdHJ1ZSBoYXMgbm8gZWZmZWN0Ljwvbm90ZT4KLSAgIDxwPkV4YW1wbGU6IHNldHRpbmcgaW5jcmVtZW50YWwgdHJhbnNmb3JtcyB0byB0cnVlOjwvcD4KLSAgIDxzb3VyY2U+amF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkgdEZhY3RvcnkgPQotICAgICAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAvLyBzZXRBdHRyaWJ1dGUoKSB0YWtlcyBhIFN0cmluZyBhbmQgYW4gT2JqZWN0LiAgICAgICAgICAgIAotICB0RmFjdG9yeS5zZXRBdHRyaWJ1dGUKLSAgICAgICAgICAgICgiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL2luY3JlbWVudGFsIiwgCi0gICAgICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uVFJVRSk7Ci0gIC4uLjwvc291cmNlPgotICA8L3MzPjxhbmNob3IgbmFtZT0ib3B0aW1pemVkIi8+Ci0gIDxzMyB0aXRsZT0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL2ZlYXR1cmVzL29wdGltaXplIj4KLSAgIDxwPldoZW4gc2V0IHRvIHRydWUgKHRoZSBkZWZhdWx0KSwgdGhpcyBmZWF0dXJlIGVuYWJsZXMgb3B0aW1pemF0aW9ucyB0aGF0IG1heSBpbnZvbHZlIHN0cnVjdHVyYWwgcmV3cml0ZXMgb2YgdGhlIHN0eWxlc2hlZXQuIAotICAgQW55IHRvb2wgdGhhdCByZXF1aXJlcyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBzdHlsZXNoZWV0IHN0cnVjdHVyZSBzaG91bGQgc2V0IHRoaXMgZmVhdHVyZSB0byBmYWxzZS48L3A+Ci08L3MzPgotPC9zMj4KLTwvczE+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi9leHRlbnNpb25zLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vZXh0ZW5zaW9ucy54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDUyZGJmOTkuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94YWxhbi9leHRlbnNpb25zLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDc2MiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLQotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLQotPHMxIHRpdGxlPSImeHNsdDRqOyBFeHRlbnNpb25zIj4KLTx1bD4KLTxsaT48bGluayBhbmNob3I9ImludHJvIj5JbnRyb2R1Y3Rpb248L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InN1cHBvcnRlZC1sYW5nIj5TdXBwb3J0ZWQgbGFuZ3VhZ2VzPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJiYXNpYy1wYXR0ZXJuIj5UaGUgYmFzaWMgcGF0dGVybjwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0ic2V0dXAtcnVudGltZSI+U2V0dGluZyB1cCB0aGUgcnVudGltZSBlbnZpcm9ubWVudDwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iYmFzaWMtc3ludGF4Ij5TeW50YXg8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImV4dC1lbGVtZW50cyI+VXNpbmcgYW4gZXh0ZW5zaW9uIGVsZW1lbnQ8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImV4dC1mdW5jdGlvbnMiPlVzaW5nIGV4dGVuc2lvbiBmdW5jdGlvbnM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImphdmEtbmFtZXNwYWNlIj5BbHRlcm5hdGl2ZTogdXNpbmcgdGhlIGFiYnJldmlhdGVkIHN5bnRheCBmb3IgZXh0ZW5zaW9ucyBpbXBsZW1lbnRlZCBpbiBKYXZhPC9saW5rPjwvbGk+Ci08bGk+RXhhbXBsZXM6IDxsaW5rIGFuY2hvcj0iZXgtYmFzaWMiPmJhc2ljIEphdmFTY3JpcHQgZXhhbXBsZTwvbGluaz4sIDxsaW5rIGFuY2hvcj0iZXgtamF2YS1uYW1lc3BhY2UiPnVzaW5nIHRoZSBqYXZhIG5hbWVzcGFjZTwvbGluaz4sIDxsaW5rIGFuY2hvcj0iZXgtamF2YSI+dXNpbmcgYSBKYXZhIEhhc2h0YWJsZTwvbGluaz4sIDxsaW5rIGFuY2hvcj0iZXgtamF2YXNjcmlwdCI+dXNpbmcgYSBKYXZhU2NyaXB0IGFycmF5PC9saW5rPjwvbGk+Ci08L3VsPjxhbmNob3IgbmFtZT0iaW50cm8iLz4KLSAgPHMyIHRpdGxlPSJJbnRyb2R1Y3Rpb24iPgotICA8cD5Gb3IgdGhvc2Ugc2l0dWF0aW9ucyB3aGVyZSB5b3Ugd291bGQgbGlrZSB0byBhdWdtZW50IHRoZSBmdW5jdGlvbmFsaXR5IG9mIFhTTFQgd2l0aCBjYWxscyB0byBhIHByb2NlZHVyYWwgbGFuZ3VhZ2UsICZ4c2x0NGo7IHN1cHBvcnRzIHRoZSBjcmVhdGlvbiBhbmQgdXNlIG9mIGV4dGVuc2lvbiBlbGVtZW50cyBhbmQgZXh0ZW5zaW9uIGZ1bmN0aW9ucy4gJnhzbHQ0ajsgYWxzbyBwcm92aWRlcyBhIGdyb3dpbmcgPGxpbmsgaWRyZWY9ImV4dGVuc2lvbnNsaWIiPmV4dGVuc2lvbnMgbGlicmFyeTwvbGluaz4gYXZhaWxhYmxlIGZvciB5b3VyIHVzZS4gQW4gZXh0ZW5zaW9uIChhIGNvbGxlY3Rpb24gb2YgZWxlbWVudHMgYW5kIGZ1bmN0aW9ucykgaW5oYWJpdHMgYSBuYW1lc3BhY2UsIGVpdGhlciBhIG5hbWVzcGFjZSB5b3UgZGVjbGFyZSBhbmQgZGVzaWduYXRlIGFzIGFuIGV4dGVuc2lvbnMgbmFtZXNwYWNlLCBvciBvbmUgb2YgdGhlIHByZWRlZmluZWQgbmFtZXNwYWNlcyB0aGF0ICZ4c2x0NGo7IHByb3ZpZGVzLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgWE1MIG5hbWVzcGFjZXMsIHNlZSA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyI+TmFtZXNwYWNlcyBpbiBYTUw8L2p1bXA+LjwvcD4KLQotPHA+PGVtPkV4dGVuc2lvbiBlbGVtZW50czwvZW0+ICBVbmxpa2UgYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50LCB3aGljaCB0aGUgc3R5bGVzaGVldCBzaW1wbHkgdHJhbnNmZXJzIHRvIHRoZSByZXN1bHQgdHJlZSwgYW4gZXh0ZW5zaW9uIGVsZW1lbnQgcGVyZm9ybXMgYW4gYWN0aW9uLiBGb3IgZXhhbXBsZSwgeW91IGNhbiB1c2UgdGhlIFJlZGlyZWN0IGV4dGVuc2lvbiBlbGVtZW50cyBzaGlwcGVkIHdpdGggJnhzbHQ0ajsgdG8gcmVkaXJlY3QgcG9ydGlvbnMgb2YgeW91ciB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQgdG8gb25lIG9yIG1vcmUgZmlsZXMuIEV4dGVuc2lvbiBlbGVtZW50cyBtYXkgY29udGFpbiBhdHRyaWJ1dGVzLCB0ZXh0IG5vZGVzLCBvdGhlciBlbGVtZW50cywgYmFzaWNhbGx5IGFueSB2YWxpZCBYTUwuIEV4dGVuc2lvbiBlbGVtZW50cyBtYXkgcGVyZm9ybSBxdWl0ZSBzb3BoaXN0aWNhdGVkIGFjdGlvbnMsIGdpdmVuIHRoYXQgdGhlIGV4dGVuc2lvbiByb3V0aW5lICh0aGUgaW1wbGVtZW50YXRpb24pIGhhcyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBYU0xUIHByb2Nlc3NvciBjb250ZXh0IG9iamVjdCBhbmQgdG8gdGhlIGVsZW1lbnQuIEluIG1hbnkgY2FzZXMgdGhlIGltcGxlbWVudGF0aW9uIHJldHVybnMgdm9pZCBvciBudWxsOyBpZiBpdCBkb2VzIHJldHVybiBhIHZhbHVlLCB0aGF0IHZhbHVlIGlzIHBsYWNlZCBpbiB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0IHRyZWUuPC9wPgotCi08cD48ZW0+RXh0ZW5zaW9uIGZ1bmN0aW9uczwvZW0+ICBZb3UgY2FuIHRoaW5rIG9mIGV4dGVuc2lvbiBmdW5jdGlvbnMgYXMgZXh0ZW5kaW5nIHRoZSBjb3JlIGxpYnJhcnkgb2YgZnVuY3Rpb25zIHRoYXQgWFBhdGggcHJvdmlkZXMuIEFuIGV4dGVuc2lvbiBmdW5jdGlvbiBwYXNzZXMgYXJndW1lbnRzIHRvIHRoZSBleHRlbnNpb24gaW1wbGVtZW50YXRpb24gYW5kIHJldHVybnMgYSB2YWx1ZS4gWW91IGNhbiB1c2UgZXh0ZW5zaW9uIGZ1bmN0aW9ucyB0byByZXR1cm4gdmFsdWVzIHRoYXQgWFNMVCBjYW4gaW50ZXJhY3Qgd2l0aCBkaXJlY3RseSAobm9kZS1zZXQsIHJlc3VsdCB0cmVlIGZyYWdtZW50LCBzdHJpbmcsIGJvb2xlYW4sIGFuZCBudW1iZXIpIGFzIHdlbGwgYXMgdmFsdWVzIChvZiBhbnkgdHlwZSkgdGhhdCB5b3UgcGFzcyBpbiB0dXJuIHRvIG90aGVyIGV4dGVuc2lvbiBmdW5jdGlvbnMuIEV4dGVuc2lvbiBmdW5jdGlvbnMgd3JpdHRlbiBpbiBKYXZhIGNhbiBhbHNvIGFjY2VzcyBjZXJ0YWluIGl0ZW1zIGluIHRoZSBYU0xUIGV4ZWN1dGlvbiBlbnZpcm9ubWVudCB0aHJvdWdoIGFuIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zL0V4cHJlc3Npb25Db250ZXh0Lmh0bWwiPkV4cHJlc3Npb25Db250ZXh0PC9qdW1wPiBpbnRlcmZhY2UuPC9wPgotCi08cD5YU0xUIGV4dGVuc2lvbnMgYXJlIHNwZWNpZmllZCBpbiB0aGUgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNleHRlbnNpb24iPlhTTFQgUmVjb21tZW5kYXRpb248L2p1bXA+LiAgVGhpcyBkb2N1bWVudCBmb2N1c2VzIG9uIHRoZSAmeHNsdDRqOyBpbXBsZW1lbnRhdGlvbiBvZiB0aG9zZSByZXF1aXJlbWVudHMsIG5vdCBvbiBYU0xUIGV4dGVuc2lvbnMgaW4gZ2VuZXJhbC4gRm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb24gZXh0ZW5zaW9ucywgY29uc3VsdCB0aGUgUmVjb21tZW5kYXRpb24gb3IgdGhlIG90aGVyIHJlc291cmNlcyBsaXN0ZWQgaW4gPGxpbmsgaWRyZWY9Im92ZXJ2aWV3IiBhbmNob3I9InVwdG9zcGVlZCI+R2V0dGluZyB1cCB0byBzcGVlZCB3aXRoIFhTTFQ8L2xpbms+LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJzdXBwb3J0ZWQtbGFuZyIvPgotPHMyIHRpdGxlPSJTdXBwb3J0ZWQgbGFuZ3VhZ2VzIj4KLTxwPkV4dGVuc2lvbnMgd3JpdHRlbiBpbiBKYXZhIGFyZSBkaXJlY3RseSBzdXBwb3J0ZWQgYnkgJnhzbHQ0ajsuICBGb3IgZXh0ZW5zaW9ucyB3cml0dGVuIGluIGxhbmd1YWdlcyBvdGhlciB0aGFuIEphdmEsICZ4c2x0NGo7IHVzZXMgdGhlIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImJzZiIvPiwgYW4gYXJjaGl0ZWN0dXJlIGZvciBpbmNvcnBvcmF0aW5nIHNjcmlwdGluZyBpbnRvIEphdmEgYXBwbGljYXRpb25zIGFuZCBhcHBsZXRzLiBCU0YgYWxsb3dzIGFuIGFwcGxpY2F0aW9uIHRvIHRha2UgYWR2YW50YWdlIG9mIHNjcmlwdGluZyB3aGlsZSBiZWluZyBpbmRlcGVuZGVudCBvZiBhbnkgc3BlY2lmaWMgc2NyaXB0aW5nIGxhbmd1YWdlLiBUbyBkYXRlLCB3ZSBoYXZlIHRlc3RlZCBleHRlbnNpb25zIGltcGxlbWVudGVkIGluIEphdmFTY3JpcHQuIE90aGVyIGxhbmd1YWdlcyB3aXRoIEJTRiBzdXBwb3J0IGFwcGVhciBpbiB0aGUgdGFibGUgYmVsb3cuPC9wPgotPHA+QlNGIHJlcXVpcmVzIGJzZi5qYXIgb24gdGhlIGNsYXNzcGF0aC4gVGhpcyBKQVIgZmlsZSBpcyBzaGlwcGVkIHdpdGggJnhzbHQ0ajsgYW5kIGlzIHJlcXVpcmVkIG9ubHkgaWYgeW91IGhhdmUgZXh0ZW5zaW9ucyB3cml0dGVuIGluIGxhbmd1YWdlcyBvdGhlciB0aGFuIEphdmEuIFRoZSBhZGRpdGlvbmFsIEpBUiBmaWxlcyBvciBETExzIHJlcXVpcmVkIHRvIHN1cHBvcnQgZXh0ZW5zaW9ucyB3cml0dGVuIGluIG90aGVyIGxhbmd1YWdlcyBhcmUgbGlzdGVkIGluIHRoZSB0YWJsZSBiZWxvdy4gVGhlc2UgZmlsZXMgYXJlIGF2YWlsYWJsZSBmcm9tIHRoZSBzb3VyY2VzIGluZGljYXRlZCBhbmQgYXJlIG5vdCBzaGlwcGVkIHdpdGggJnhzbHQ0ajsuPC9wPgotPHRhYmxlPgotICA8dHI+Ci0gICAgPHRkPjxlbT5MYW5ndWFnZTwvZW0+PC90ZD4KLSAgICA8dGQ+PGVtPlZlcnNpb248L2VtPjwvdGQ+Ci0gICAgPHRkPjxlbT5SZXF1aXJlbWVudHM8L2VtPjwvdGQ+Ci0gIDwvdHI+Ci0gIDx0cj4KLSAgICA8dGQ+TW96aWxsYSBSaGlubyAoSmF2YVNjcmlwdCk8YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+MS41PGJyLz48YnIvPjwvdGQ+Ci0gICAgPHRkPmpzLmphciBhdmFpbGFibGUgZnJvbSAKLQkJCQkgICAgaHR0cDovL3d3dy5tb3ppbGxhLm9yZy9yaGlubzxici8+PGJyLz48L3RkPgotICA8L3RyPgotICA8dHI+Ci0gICAgPHRkPk5ldFJleHg8YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+MS4xNDggdXAgPGJyLz48YnIvPjwvdGQ+Ci0gICAgPHRkPk5ldFJleHhDLnppcCBhdmFpbGFibGUgZnJvbSBodHRwOi8vd3d3Mi5odXJzbGV5LmlibS5jb20vbmV0cmV4eDxici8+PGJyLz48L3RkPgotICA8L3RyPgotICAgIDx0cj4KLSAgICA8dGQ+Qk1MPGJyLz48YnIvPjwvdGQ+Ci0gICAgPHRkPjIuNDxici8+PGJyLz48L3RkPgotICAgIDx0ZD5ibWxhbGwuamFyIGF2YWlsYWJsZSBmcm9tIGh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9kZXZlbG9wZXJ3b3Jrcy9wcm9qZWN0cy9ic2Y8YnIvPjxici8+PC90ZD4KLSAgPC90cj4KLSAgICA8dHI+Ci0gICAgPHRkPkpQeXRob248YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+MS4xLWJldGEzPGJyLz48YnIvPjwvdGQ+Ci0gICAgPHRkPnB5dGhvbi5qYXIgYXZhaWxhYmxlIGZyb20gaHR0cDovL3d3dy5qcHl0aG9uLm9yZy88YnIvPjxici8+PC90ZD4KLSAgPC90cj4KLSAgICA8dHI+Ci0gICAgPHRkPkphY2w8YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+MS4xLjE8YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+IGphY2wuamFyIGFuZCB0Y2xqYXZhLmphciBmcm9tIGh0dHA6Ly93d3cuc2NyaXB0aWNzLmNvbS9qYXZhPGJyLz48YnIvPjwvdGQ+Ci0gIDwvdHI+Ci0gICAgPHRyPgotICAgIDx0ZD5XaW4zMiBBY3RpdmVTY3JpcHQgbGFuZ3MKLQlKU2NyaXB0LCBWQlNjcmlwdDxici8+PGJyLz48L3RkPgotICAgIDx0ZD48YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+TVNWQ1A2MC5ETEwgZnJvbSBNaWNyb3NvZnQsIGFwcHJvcHJpYXRlIGxhbmd1YWdlIERMTHMgZnJvbSBNaWNyb3NvZnQgCi0gICAgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9zY3JpcHRpbmc8YnIvPjxici8+PC90ZD4KLSAgPC90cj4KLSAgICA8dHI+Ci0gICAgPHRkPlBlcmxTY3JpcHQ8YnIvPjxici8+PC90ZD4KLSAgICA8dGQ+PGJyLz48YnIvPjwvdGQ+Ci0gICAgPHRkPkFjdGl2ZVBlcmwgZnJvbSBodHRwOi8vd3d3LmFjdGl2ZXN0YXRlLmNvbS88YnIvPjxici8+PC90ZD4KLSAgPC90cj4gIAotPC90YWJsZT4KLTwvczI+PGFuY2hvciBuYW1lPSJiYXNpYy1wYXR0ZXJuIi8+Ci08czIgdGl0bGU9IlRoZSBiYXNpYyBwYXR0ZXJuIj4KLTxwPkxldCdzIGV4YW1pbmUgYSBzaW1wbGUgZXhhbXBsZS4gVGhlIHN0eWxlc2hlZXQgYmVsb3cgdXNlcyBhbiBleHRlbnNpb24gZWxlbWVudCBhbmQgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uIHRvIHRyYW5zZm9ybSBhbiBlbGVtZW50IGluIHRoZSBYTUwgc291cmNlIGludG8gYSBzdGF0ZW1lbnQgaW4gdGhlIG91dHB1dCBpbmRpY2F0aW5nIHRoZSBkYXRlIGJ5IHdoaWNoIGEgY3VzdG9tZXIgY2FuIGV4cGVjdCBhIHJlc3BvbnNlIHRvIGEgZ2l2ZW4gZW5xdWlyeS48L3A+Ci0KLTxwPlRoZSBzb3VyY2UgZWxlbWVudCBjb250YWlucyBhIG51bWRheXMgYXR0cmlidXRlLiBUaGUgZXh0ZW5zaW9uIGVsZW1lbnQgY29udGFpbnMgYSBtdWx0aXBsaWVyIGF0dHJpYnV0ZSwgd2hpY2ggaXMgdXNlZCB0byBzZXQgYSB2YXJpYWJsZSBpbiB0aGUgZXh0ZW5zaW9uLiBUaGUgZXh0ZW5zaW9uIGZ1bmN0aW9uIGNvbXB1dGVzIHRoZSBkZWFkbGluZSwgdGhhdCBpcyB0aGUgY3VycmVudCBkYXRlIHBsdXMgbnVtZGF5cyAqIG11bHRpcGxpZXIuIFNvIGZvciAmbHQ7ZGVhZGxpbmUgbnVtZGF5cz0iMyIvJmd0OyAoaW4gdGhlIFhNTCBzb3VyY2UpIGFuZCAmbHQ7bXktZXh0OnRpbWVsYXBzZSBtdWx0aXBsaWVyPSIyIi8mZ3Q7IChpbiB0aGUgc3R5bGVzaGVldCksIHRoZSBleHRlbnNpb24gY29tcHV0ZXMgYSBkZWFkbGluZSA2IGRheXMgZnJvbSBub3csIGFuZCB0aGUgc3R5bGVzaGVldCB0ZW1wbGF0ZSB0cmFuc2Zvcm1zIHRoZSBkZWFkbGluZSBlbGVtZW50IGludG8gYSBzdHJpbmcgYWxvbmcgdGhlIGxpbmVzIG9mIDxjb2RlPiZsdDtwJmd0O1dlIGhhdmUgbG9nZ2VkIHlvdXIgZW5xdWlyeSBhbmQgd2lsbCByZXNwb25kIGJ5IEFwcmlsIDI5LCAyMDAwIDEyOjA3OjE2IFBNIEVTVC4mbHQ7L3AmZ3Q7PC9jb2RlPjwvcD4KLTxub3RlPlRoZSBleHRlbnNpb24gZnVuY3Rpb24gY291bGQgaW5jbHVkZSBib3RoIG51bWRheXMgYW5kIG11bHRpcGxpZXIgYXMgYXJndW1lbnRzLCB0aHVzIGJ5cGFzc2luZyB0aGUgbmVlZCBmb3IgdGhlIGV4dGVuc2lvbiBlbGVtZW50LCBidXQgdGhlIHB1cnBvc2UgaGVyZSBpcyB0byBpbGx1c3RyYXRlIHRoZSB1c2FnZSBwYXR0ZXJuIGZvciBleHRlbnNpb24gZWxlbWVudHMuPC9ub3RlPgotPHA+QXMgeW91IHJldmlldyB0aGlzIHN0eWxlc2hlZXQsIHBsZWFzZSBub3RlIHRoZSBmb2xsb3dpbmc6PC9wPgotPG9sPgotCSAgPGxpPlRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgWGFsYW4gbHhzbHQgbmFtZXNwYWNlLCB3aGljaCBwcm92aWRlcyBzdXBwb3J0IGZvciB0aGUgY29tcG9uZW50IGFuZAotICAgICBjb21wb25lbnQvc2NyaXB0IGVsZW1lbnRzOjxici8+PGJyLz4KLSAgICA8Y29kZT54bWxuczpseHNsdD0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiPC9jb2RlPjxici8+PGJyLz48L2xpPgotICAgIDxsaT5UaGUgZGVjbGFyYXRpb24gb2YgYSBuYW1lc3BhY2UgZm9yIHRoaXMgZXh0ZW5zaW9uOjxici8+PGJyLz4KLSAgICA8Y29kZT54bWxuczpteS1leHQ9ImV4dDEiPC9jb2RlPjxici8+PGJyLz48L2xpPgotICAJPGxpPlRoZSBkZXNpZ25hdGlvbiBvZiB0aGlzIG5hbWVzcGFjZSBwcmVmaXggYXMgYW4gZXh0ZW5zaW9uIHByZWZpeC4gVGhpcyBjYXVzZXMgYW55IGVsZW1lbnQgaW4gdGhlIG5hbWVzcGFjZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcmVmaXggdG8gYmUgdHJlYXRlZCBhcyBhbiBleHRlbnNpb24gZWxlbWVudCByYXRoZXIgdGhhbiBhIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnQuPGJyLz48YnIvPgotICAgICA8Y29kZT5leHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ibXktZXh0IjwvY29kZT48YnIvPjxici8+PC9saT4KLQkgIDxsaT5UaGUgbHhzbHQ6Y29tcG9uZW50IHdpdGggYXR0cmlidXRlcyBkZXNpZ25hdGluZyB0aGUgbmFtZXNwYWNlIHByZWZpeCBhbmQgdGhlIGVsZW1lbnRzIGFuZAotICAgICBmdW5jdGlvbnMgdGhpcyBleHRlbnNpb24gcHJvdmlkZXMuPGJyLz48YnIvPjwvbGk+Ci0gIAk8bGk+VGhlIGx4c2x0OnNjcmlwdCBzdWJlbGVtZW50IHdpdGggYSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBleHRlbnNpb24uIEZvciBKYXZhCi0gICAgIGV4dGVuc2lvbnMsIHRoZSBseHNsdDpzY3JpcHQgZWxlbWVudCBoYXMgYSBzcmMgYXR0cmlidXRlIHRoYXQgeW91IHNldCB0byBpZGVudGlmeSB0aGUgSmF2YSBjbGFzcy48L2xpPgotPC9vbD48YW5jaG9yIG5hbWU9ImV4LWJhc2ljIi8+ICAgCi08c291cmNlPiZsdDs/eG1sIHZlcnNpb249IjEuMCI/Jmd0OwotJmx0OyEtLU5hbWVzcGFjZXMgYXJlIGdsb2JhbCBpZiB5b3Ugc2V0IHRoZW0gaW4gdGhlIHN0eWxlc2hlZXQgZWxlbWVudC0tJmd0OwotJmx0O3hzbDpzdHlsZXNoZWV0IAotICAgIHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiAKLSAgICB2ZXJzaW9uPSIxLjAiICAgCi0gICAgeG1sbnM6bHhzbHQ9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0IgotICAgIHhtbG5zOm15LWV4dD0iZXh0MSIKLSAgICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ibXktZXh0IiZndDsKLSAgICAKLSAgJmx0OyEtLVRoZSBjb21wb25lbnQgYW5kIGl0cyBzY3JpcHQgYXJlIGluIHRoZSBseHNsdCBuYW1lc3BhY2UgYW5kIGRlZmluZSB0aGUgCi0gICAgaW1wbGVtZW50YXRpb24gb2YgdGhlIGV4dGVuc2lvbi4tLSZndDsKLSAgJmx0O2x4c2x0OmNvbXBvbmVudCBwcmVmaXg9Im15LWV4dCIgZWxlbWVudHM9InRpbWVsYXBzZSIgZnVuY3Rpb25zPSJnZXRkYXRlIiZndDsKLSAgICAmbHQ7bHhzbHQ6c2NyaXB0IGxhbmc9ImphdmFzY3JpcHQiJmd0OwotICAgICAgdmFyIG11bHRpcGxpZXI9MTsKLSAgICAgIC8vIFRoZSBtZXRob2RzIG9yIGZ1bmN0aW9ucyB0aGF0IGltcGxlbWVudCBleHRlbnNpb24gZWxlbWVudHMgYWx3YXlzIHRha2UgMgotICAgICAgLy8gYXJndW1lbnRzLiBUaGUgZmlyc3QgYXJndW1lbnQgaXMgdGhlIFhTTCBQcm9jZXNzb3IgY29udGV4dDsgdGhlIHNlY29uZCAKLSAgICAgIC8vIGFyZ3VtZW50IGlzIHRoZSBlbGVtZW50IG5vZGUuCi0gICAgICBmdW5jdGlvbiB0aW1lbGFwc2UoeHNsUHJvY2Vzc29yQ29udGV4dCwgZWxlbSkKLSAgICAgIHsKLSAgICAgICAgbXVsdGlwbGllcj1wYXJzZUludChlbGVtLmdldEF0dHJpYnV0ZSgibXVsdGlwbGllciIpKTsKLSAgICAgICAgLy8gVGhlIGVsZW1lbnQgcmV0dXJuIHZhbHVlIGlzIHBsYWNlZCBpbiB0aGUgcmVzdWx0IHRyZWUuCi0gICAgICAgIC8vIElmIHlvdSBkbyBub3Qgd2FudCBhIHJldHVybiB2YWx1ZSwgcmV0dXJuIG51bGwuCi0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotICAgICAgZnVuY3Rpb24gZ2V0ZGF0ZShudW1kYXlzKQotICAgICAgewotICAgICAgICB2YXIgZCA9IG5ldyBEYXRlKCk7Ci0gICAgICAgIHZhciB0b3RhbERheXMgPSBwYXJzZUludChudW1kYXlzKSAqIG11bHRpcGxpZXI7Ci0gICAgICAgIGQuc2V0RGF0ZShkLmdldERhdGUoKSArIHRvdGFsRGF5cyk7Ci0gICAgICAgIHJldHVybiBkLnRvTG9jYWxlU3RyaW5nKCk7Ci0gICAgICB9Ci0gICAgJmx0Oy9seHNsdDpzY3JpcHQmZ3Q7Ci0gICZsdDsvbHhzbHQ6Y29tcG9uZW50Jmd0OwotICAgICAgCi0gICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9ImRlYWRsaW5lIiZndDsKLSAgICAmbHQ7cCZndDsmbHQ7bXktZXh0OnRpbWVsYXBzZSBtdWx0aXBsaWVyPSIyIi8mZ3Q7V2UgaGF2ZSBsb2dnZWQgeW91ciBlbnF1aXJ5IGFuZCB3aWxsIAotICAgICAgcmVzcG9uZCBieSAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0ibXktZXh0OmdldGRhdGUoc3RyaW5nKEBudW1kYXlzKSkiLyZndDsuJmx0Oy9wJmd0OwotICAmbHQ7L3hzbDp0ZW1wbGF0ZT4KLQotJmx0Oy94c2w6c3R5bGVzaGVldCZndDsKLTwvc291cmNlPgotPC9zMj48YW5jaG9yIG5hbWU9InNldHVwLXJ1bnRpbWUiLz4KLTxzMiB0aXRsZT0iU2V0dGluZyB1cCB0aGUgcnVudGltZSBlbnZpcm9ubWVudCI+Ci08cD5UbyBydW4gdGhlIHByZWNlZGluZyBleGFtcGxlLCBic2YuamFyIGFuZCBqcy5qYXIgbXVzdCBiZSBvbiB0aGUgY2xhc3NwYXRoLiBSZW1lbWJlciB0aGF0IGJzZi5qYXIgbXVzdCBiZSBvbiB0aGUgY2xhc3NwYXRoIHRvIHJ1biBhbnkgZXh0ZW5zaW9uIHdyaXR0ZW4gaW4gYSBsYW5ndWFnZSBvdGhlciB0aGFuIEphdmEuIEZvciBleHRlbnNpb25zIGltcGxlbWVudGVkIGluIGEgc2NyaXB0aW5nIGxhbmd1YWdlLCBzZWUgdGhlIGFkZGl0aW9uYWwgcmVxdWlyZW1lbnRzIGluIDxsaW5rIGFuY2hvcj0ic3VwcG9ydGVkLWxhbmciPlN1cHBvcnRlZCBsYW5ndWFnZXM8L2xpbms+LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJiYXNpYy1zeW50YXgiLz4KLTxzMiB0aXRsZT0iU3ludGF4Ij4KLTxwPllvdSBjYW4gYWx3YXlzIHVzZSB0aGUgcGF0dGVybiBpbGx1c3RyYXRlZCBhYm92ZSB0byBzZXQgdXAgYW5kIHVzZSBleHRlbnNpb24gZWxlbWVudHMgYW5kIGV4dGVuc2lvbiBmdW5jdGlvbnMuIEZvciBleHRlbnNpb24gZWxlbWVudHMgYW5kIGZ1bmN0aW9ucyBpbXBsZW1lbnRlZCBpbiBKYXZhLCB5b3UgY2FuIGFsc28gdXNlIGFuIGFiYnJldmlhdGVkIHN5bnRheCwgZGVzY3JpYmVkIGluIDxsaW5rIGFuY2hvcj0iamF2YS1uYW1lc3BhY2UiPkFsdGVybmF0aXZlOiB1c2luZyB0aGUgYWJicmV2aWF0ZWQgc3ludGF4IGZvciBleHRlbnNpb25zIGltcGxlbWVudGVkIGluIEphdmE8L2xpbms+LiBVbmxlc3MgeW91IGFyZSB1c2luZyB0aGUgYWJicmV2aWF0ZWQgc3ludGF4LCBkbyB0aGUgZm9sbG93aW5nOjwvcD4KLTxzMyB0aXRsZT0iMS4gRGVjbGFyZSB0aGUgbHhzbHQgbmFtZXNwYWNlIj4KLTxwPjxici8+PGNvZGU+eG1sbnM6bHhzbHQ9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0IjwvY29kZT48L3A+Ci08cD5UaGUgbHhzbHQgbmFtZXNwYWNlIHByb3ZpZGVzIHN1cHBvcnQgZm9yIHRoZSBseHNsdDpjb21wb25lbnQgZWxlbWVudCBhbmQgbHhzbHQ6c2NyaXB0IHN1YmVsZW1lbnQuPC9wPgotPC9zMz4KLTxzMyB0aXRsZT0iMi4gRGVjbGFyZSBhIHVuaXF1ZSBuYW1lc3BhY2UgZm9yIGVhY2ggZXh0ZW5zaW9uIHByZWZpeCI+Ci08cD48YnIvPjxjb2RlPnhtbG5zOjxyZWY+cHJlZml4PC9yZWY+PTxyZWY+VVJJPC9yZWY+PC9jb2RlPjwvcD4KLTxwPlRoZSA8cmVmPnByZWZpeDwvcmVmPiBpZGVudGlmaWVzIHRoZSBuYW1lc3BhY2UsIGFuZCA8cmVmPlVSSTwvcmVmPiBpcyBhbiBhcmJpdHJhcnkgKGJ1dCB1bmlxdWUpIHN0cmluZyB0aGF0IG1hdGNoZXMgdGhlIHZhbHVlIG9mIHRoZSBwcmVmaXggYXR0cmlidXRlIG9mIGFuIGx4c2x0OmNvbXBvbmVudCBlbGVtZW50IGluIHRoZSBzdHlsZXNoZWV0Ljxici8+Ci1FeGFtcGxlOiA8Y29kZT54bWxuczpleHQxPSJ4eXoiPC9jb2RlPjxici8+PGJyLz48L3A+Ci08L3MzPgotPHMzIHRpdGxlPSIzLiBJZiB5b3UgYXJlIHVzaW5nIGV4dGVuc2lvbiBlbGVtZW50cywgZGVzaWduYXRlIHRoZSBleHRlbnNpb24gZWxlbWVudCBwcmVmaXhlcyI+Ci08cD48YnIvPlRoaXMgc3RlcCBpcyByZXF1aXJlZCBvbmx5IGlmIHlvdSBhcmUgdXNpbmcgZXh0ZW5zaW9uIGVsZW1lbnRzLiAgSWYgeW91IGFyZSB1c2luZyBleHRlbnNpb24gZnVuY3Rpb25zIG9ubHksIHlvdSBjYW4gc2tpcCB0aGlzIHN0ZXAuPC9wPgotPHA+SW4gdGhlIHN0eWxlc2hlZXQgZWxlbWVudCwgd3JpdGU6PC9wPiAKLTxwPjxjb2RlPmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSI8cmVmPnByZWZpeC0xIHByZWZpeC0yIC4uLjwvcmVmPiI8L2NvZGU+PC9wPgotPHA+SW4gYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50IG9yIGV4dGVuc2lvbiBlbGVtZW50IGluY2x1ZGUgdGhlIHhzbCBwcmVmaXg6PC9wPgotPHA+PGNvZGU+eHNsOmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSI8cmVmPnByZWZpeDEgcHJlZml4MiAuLi48L3JlZj4iPC9jb2RlPjwvcD4KLTxwPktlZXAgaW4gbWluZCB0aGF0IHdoZXJlIHlvdSBkZWNsYXJlIG5hbWVzcGFjZXMgYW5kIGRlc2lnbmF0ZSBleHRlbnNpb24gcHJlZml4ZXMgZGV0ZXJtaW5lcyB0aGUgc2NvcGUgb2YgdGhvc2UgbmFtZXNwYWNlcy5UbyBtYWtlIHlvdXIgZXh0ZW5zaW9ucyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgc3R5bGVzaGVldCwgaW5jbHVkZSB0aGVzZSBzZXR0aW5ncyBhbmQgYXR0cmlidXRlIGluIHRoZSBzdHlsZXNoZWV0IGVsZW1lbnQuPC9wPgotPC9zMz4KLTxzMyB0aXRsZT0iNC4gKE9wdGlvbmFsKSBFeGNsdWRlIHRoZSBleHRlbnNpb24gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGZyb20gdGhlIHJlc3VsdCB0cmVlIj4KLTxwPjxici8+QnkgZGVmYXVsdCwgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBhcmUgaW5jbHVkZWQgaW4gdGhlIHRyYW5zZm9ybWF0aW9uIG91dHB1dC4gVG8gZXhjbHVkZSBuYW1lc3BhY2VzIGZyb20gdGhlIG91dHB1dCwgdXNlPC9wPgotPHA+PGNvZGU+ZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXM9IjxyZWY+cHJlZml4LTEgcHJlZml4LTIgLi4uPC9yZWY+IjwvY29kZT48L3A+Ci08cD5pbiB0aGUgc3R5bGVzaGVldCBlbGVtZW50IG9yPC9wPgotPHA+PGNvZGU+eHNsOmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzPSI8cmVmPnByZWZpeC0xIHByZWZpeC0yIC4uLjwvcmVmPiI8L2NvZGU+PC9wPiAKLTxwPmluIGEgbGl0ZXJhbCByZXN1bHQgZWxlbWVudCBvciBleHRlbnNpb24gZWxlbWVudC48L3A+Ci08L3MzPgotPHMzIHRpdGxlPSI1LiBTZXQgdXAgYW4gbHhzbHQ6Y29tcG9uZW50Ij4KLTxwPjxici8+SW4gdGhlIHNjb3BlIG9mIHRoZSBseHNsdCBuYW1lc3BhY2UgZGVjbGFyYXRpb246PC9wPgotPHA+PGNvZGU+Jmx0O2x4c2x0OmNvbXBvbmVudCBwcmVmaXg9IjxyZWY+cHJlZml4PC9yZWY+IiA8L2NvZGU+PGJyLz4KLSAgIDxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO2Z1bmN0aW9ucz0iPHJlZj5mdW5jLTEgZnVuYy0yIC4uLmZ1bmMtbjwvcmVmPiI8L2NvZGU+PGJyLz4gCi0gICA8Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtlbGVtZW50cz0iPHJlZj5lbGVtLTEgZWxlbS0yIC4uLmVsZW0tbjwvcmVmPiImZ3Q7PC9jb2RlPjxici8+Ci0gICA8Y29kZT4mbmJzcDsmbmJzcDsmbHQ7IS0tU2VlIGx4c2x0OnNjcmlwdCBiZWxvdy0tJmd0OzwvY29kZT48YnIvPgotICAgPGNvZGU+Jmx0Oy9seHNsdDpjb21wb25lbnQmZ3Q7PC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+ZnVuYy0xIGZ1bmMtMiAuLi4gZnVuYy1uPC9yZWY+IGFuZCA8cmVmPmVsZW0tMSBlbGVtLTIgLi4uIGVsZW0tbjwvcmVmPiBkZXNpZ25hdGUgdGhlIGZ1bmN0aW9ucyBhbmQgZWxlbWVudHMgdGhlIGV4dGVuc2lvbiBwcm92aWRlcyBhbmQgdGhlIHN0eWxlc2hlZXQgdXNlcy4gWW91IGNhbiB1c2UgdGhlIGZ1bmN0aW9uLWF2YWlsYWJsZSBhbmQgZWxlbWVudC1hdmFpbGFibGUgZnVuY3Rpb25zIHRvIGRldGVybWluZSBhdCBydW4gdGltZSB3aGV0aGVyIGEgZnVuY3Rpb24gb3IgZWxlbWVudCBkZXNpZ25hdGVkIGluIHRoZSBseHNsdDpjb21wb25lbnQgaXMgYWN0dWFsbHkgYXZhaWxhYmxlLjwvcD4KLTxub3RlPklmIHRoZSBjb21wb25lbnQgaXMgaW1wbGVtZW50ZWQgaW4gSmF2YSwgdGhlIHZhbHVlcyBvZiB0aGUgPGNvZGU+ZnVuY3Rpb25zPC9jb2RlPiBhbmQgPGNvZGU+ZWxlbWVudHM8L2NvZGU+IGF0dHJpYnV0ZXMgYXJlIGlnbm9yZWQuIFRoZSBmdW5jdGlvbi1hdmFpbGFibGUgYW5kIGVsZW1lbnQtYXZhaWxhYmxlIGZ1bmN0aW9ucyB1c2UgcmVmbGVjdGlvbiB0byBleGFtaW5lIHRoZSBhY3R1YWwgSmF2YSBtZXRob2RzLjwvbm90ZT4KLTwvczM+Ci08YW5jaG9yIG5hbWU9InNldHVwLXNjcmlwdCIvPgotPHMzIHRpdGxlPSI2LiBTZXQgdXAgdGhlIGx4c2x0OnNjcmlwdCBlbGVtZW50Ij4KLTxwPjxici8+SW4gZWFjaCBseHNsdDpjb21wb25lbnQsIHlvdSBtdXN0IGluY2x1ZGUgZXhhY3RseSBvbmUgbHhzbHQ6c2NyaXB0IGVsZW1lbnQuIElmIHRoZSBleHRlbnNpb24gaXMgaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdDo8L3A+Ci08cD48Y29kZT4mbHQ7bHhzbHQ6c2NyaXB0IGxhbmc9ImphdmFzY3JpcHQiICZndDs8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZsdDshLS1UaGUgaW1wbGVtZW50YXRpb24gc2NyaXB0LS0mZ3Q7PC9jb2RlPjxici8+Ci08Y29kZT4mbHQ7L2x4c2x0OnNjcmlwdCZndDs8L2NvZGU+PC9wPgotPHA+Rm9yIG90aGVyIHNjcmlwdGluZyBsYW5ndWFnZXMgc3VwcG9ydGVkIGJ5IEJTRiwgdXNlIHRoZSBzYW1lIGFwcHJvYWNoIGFzIGZvciBKYXZhU2NyaXB0LiAmeHNsdDRqOyBwbGFucyB0byBhZGQgc3VwcG9ydCBmb3IgdXNpbmcgdGhlIHNyYyBhdHRyaWJ1dGUgdG8gaWRlbnRpZnkgYW5vdGhlciBkb2N1bWVudCB0aGF0IGNvbnRhaW5zIHRoZSBpbXBsZW1lbnRhdGlvbiBzY3JpcHQ7IHRoaXMgZmVhdHVyZSBpcyBub3QgeWV0IHN1cHBvcnRlZC48L3A+Ci08cD5JZiB0aGUgZXh0ZW5zaW9uIGlzIGltcGxlbWVudGVkIGluIEphdmEsIHlvdSBoYXZlIHRocmVlIGNob2ljZXMgZm9yIHRoZSBmb3JtYXQgb2YgdGhlIHNyYyBhdHRyaWJ1dGUgaW4gdGhlIGx4c2x0OnNjcmlwdCBlbGVtZW50LjwvcD4KLTxwPjxjb2RlPiZsdDtseHNsdDpzY3JpcHQgbGFuZz0iamF2YWNsYXNzIiBzcmM9InhhbGFuOi8vPHJlZj5GUUNOPC9yZWY+Ii8mZ3Q7PC9jb2RlPgotPGJyLz53aGVyZSA8cmVmPkZRQ048L3JlZj4gaXMgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLgotPGJyLz5FeGFtcGxlOiA8Y29kZT4mbHQ7bHhzbHQ6c2NyaXB0IGxhbmc9ImphdmFjbGFzcyIgc3JjPSJ4YWxhbjovL2phdmEudXRpbC5IYXNodGFibGUiLyZndDs8L2NvZGU+PC9wPgotPHA+PGNvZGU+Jmx0O2x4c2x0OnNjcmlwdCBsYW5nPSJqYXZhY2xhc3MiIHNyYz0ieGFsYW46Ly88cmVmPlBKUE48L3JlZj4iLyZndDs8L2NvZGU+Ci08YnIvPndoZXJlIDxyZWY+UEpQTjwvcmVmPiBpcyB0aGUgYmVnaW5uaW5nIG9mIG9yIHRoZSBjb21wbGV0ZSBuYW1lIG9mIGEgamF2YSBwYWNrYWdlLgotPGJyLz5FeGFtcGxlOiA8Y29kZT4mbHQ7bHhzbHQ6c2NyaXB0IGxhbmc9ImphdmFjbGFzcyIgc3JjPSJqYXZhLnV0aWwiLyZndDs8L2NvZGU+PC9wPgotPHA+PGNvZGU+Jmx0O2x4c2x0OnNjcmlwdCBsYW5nPSJqYXZhY2xhc3MiIHNyYz0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQvamF2YSIvJmd0OzwvY29kZT48L3A+Ci08cD5UaGUgZGlmZmVyZW50IGZvcm1hdHMgZm9yIHRoZSB2YWx1ZSBvZiB0aGUgc3JjIGF0dHJpYnV0ZSB3aGVuIHVzaW5nIEphdmEgZXh0ZW5zaW9ucyBhcmUgbW9yZSBmdWxseSBleHBsYWluZWQgaW4gPGxpbmsgYW5jaG9yPSJqYXZhLW5hbWVzcGFjZS1kZWNsYXJlIj5EZWNsYXJlIHRoZSBuYW1lc3BhY2U8L2xpbms+LjwvcD4KLTwvczM+Ci08czMgdGl0bGU9IkltcGxpY2l0IERURCBmb3IgbHhzbHQ6Y29tcG9uZW50Ij4KLTxzb3VyY2U+Jmx0OyFFTEVNRU5UIGx4c2x0OmNvbXBvbmVudCAobHhzbHQ6c2NyaXB0KSZndDsKLSZsdDshQVRUTElTVCBseHNsdDpjb21wb25lbnQKLSAgcHJlZml4IENEQVRBICNSRVFVSVJFRAotICBlbGVtZW50cyBOTVRPS0VOUyAjSU1QTElFRAotICBmdW5jdGlvbnMgTk1UT0tFTlMgI0lNUExJRUQmZ3Q7Ci0KLSZsdDshRUxFTUVOVCBseHNsdDpzY3JpcHQgKCNQQ0RBVEEgfCBFTVBUWSk/Jmd0OwotJmx0OyFBVFRMSVNUIGx4c2x0OnNjcmlwdAotICBsYW5nIENEQVRBICNSRVFVSVJFRAotICBzcmMgQ0RBVEEgI0lNUExJRUQmZ3Q7PC9zb3VyY2U+Ci08L3MzPgotPC9zMj48YW5jaG9yIG5hbWU9ImV4dC1lbGVtZW50cyIvPgotPHMyIHRpdGxlPSJVc2luZyBhbiBleHRlbnNpb24gZWxlbWVudCI+Ci08cD5FeHRlbnNpb24gZWxlbWVudHMgcGFzcyB0aGUgZXh0ZW5zaW9uIHR3byBvYmplY3RzOjwvcD4KLTx1bD4KLTxsaT48anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucy9YU0xQcm9jZXNzb3JDb250ZXh0Lmh0bWwiPm9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5YU0xQcm9jZXNzb3JDb250ZXh0PC9qdW1wPiwgd2hpY2ggcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBYU0wgcHJvY2Vzc29yLCB0aGUgWE1MIHNvdXJjZSB0cmVlLCB0aGUgc3R5bGVzaGVldCB0cmVlLCB0aGUgY3VycmVudCBjb250ZXh0IG5vZGUsIGFuZCB0aGUgY3VycmVudCBtb2RlIChpZiBhbnkpLjxici8+PGJyLz48L2xpPgotPGxpPjxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvRWxlbUV4dGVuc2lvbkNhbGwuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUV4dGVuc2lvbkNhbGw8L2p1bXA+LCB3aGljaCBwcm92aWRlcyB0aGUgQVBJIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBleHRlbnNpb24gZWxlbWVudC48L2xpPgotPC91bD4KLTxwPllvdSBjYW4gdXNlIHRoZSBFbGVtRXh0ZW5zaW9uQ2FsbCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIG1ldGhvZCwgZm9yIGV4YW1wbGUsIHRvIHJlYWQgZWxlbWVudCBhdHRyaWJ1dGVzIGluIHRoZWlyIHJhdyBmb3JtLiAgVXNlIHRoZSBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIE5vZGUgc291cmNlTm9kZSwgWFNMVEVuZ2luZUltcGwgcHJvY2Vzc29yKSBtZXRob2QgdG8gZXZhbHVhdGUgdGhlIGF0dHJpYnV0ZSBhcyBhbiBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUuICBOb3RlIHRoYXQgdGhlIG1ldGhvZCBuYW1lcyBhcmUgdGhlIHNhbWUgYnV0IHRoZSBtZXRob2Qgc2lnbmF0dXJlcyBhcmUgZGlmZmVyZW50LiAgRm9yIGZ1bGwgZGV0YWlscywgc2VlIHRoZSA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzL0VsZW1FeHRlbnNpb25DYWxsLmh0bWwiPkphdmFkb2M8L2p1bXA+IGZvciB0aGUgRWxlbUV4dGVuc2lvbkNhbGwgY2xhc3MuPC9wPgotPHMzIHRpdGxlPSJJbXBsZW1lbnRpbmcgYW4gZXh0ZW5zaW9uIGVsZW1lbnQiPgotPHA+Rm9yIGVhY2ggZXh0ZW5zaW9uIGVsZW1lbnQgaW4gYSBuYW1lc3BhY2UsIHRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IGJlIGEgSmF2YSBtZXRob2Qgd2l0aCB0aGUgZm9sbG93aW5nIHNpZ25hdHVyZSwgb3IgdGhlIHNjcmlwdGluZyBsYW5ndWFnZSBlcXVpdmFsZW50OjwvcD4KLTxwPjxjb2RlPjxyZWY+VHlwZSBlbGVtZW50PC9yZWY+KG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5YU0xQcm9jZXNzb3JDb250ZXh0LCA8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO29yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1FeHRlbnNpb25DYWxsIGV4dGVuc2lvbkVsZW1lbnQpPC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+VHlwZTwvcmVmPiBkZXNpZ25hdGVzIHRoZSByZXR1cm4gdHlwZSBhbmQgPHJlZj5lbGVtZW50PC9yZWY+IGlzIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBleHRlbnNpb24gZWxlbWVudCBuYW1lICh0aGUgZWxlbWVudCBuYW1lIHdpdGhvdXQgdGhlIG5hbWVzcGFjZSBwcmVmaXgpLiBJbiB0aGUgbWV0aG9kIHNpZ25hdHVyZSwgeW91IG1heSBhbHNvIHVzZSBzdXBlcmNsYXNzZXMgb2YgdGhlIGluZGljYXRlZCB0eXBlcy48L3A+Ci08cD5JZiB0aGUgZXh0ZW5zaW9uIGVsZW1lbnQgaXMgaW1wbGVtZW50ZWQgaW4gYSBsb29zZWx5IHR5cGVkIHNjcmlwdGluZyBsYW5ndWFnZSwgc3VjaCBhcyBKYXZhU2NyaXB0LCB0aGUgYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWUgYXJlIHVudHlwZWQuPC9wPgotPHA+PGVtPkNhdXRpb246PC9lbT4gVGhlIHZhbHVlIHJldHVybmVkIGJ5IGFuIGV4dGVuc2lvbiBlbGVtZW50IGlzIHBsYWNlZCBpbiB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0LiBJZiB5b3UgYXJlIG5vdCBpbnRlcmVzdGVkIGluIGEgcmV0dXJuIHZhbHVlLCB1c2UgYSBwdWJsaWMgdm9pZCBKYXZhIG1ldGhvZCBvciByZXR1cm4gbnVsbCBmcm9tIGEgc2NyaXB0aW5nIGxhbmd1YWdlIGZ1bmN0aW9uLjwvcD4KLTxwPkphdmEgZXhhbXBsZTogPGNvZGU+cHVibGljIHZvaWQgbXlFbGVtZW50PC9jb2RlPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsob3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLlhTTFByb2Nlc3NvckNvbnRleHQsIDwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7b3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMuRWxlbUV4dGVuc2lvbkNhbGwgZXh0ZW5zaW9uRWxlbWVudCk8L2NvZGU+PC9wPgotPHA+SmF2YVNjcmlwdCBleGFtcGxlOiA8Y29kZT5mdW5jdGlvbiBteUVsZW1lbnQoeHNsUHJvY0NvbnRleHQsIGVsZW1lbnQpPC9jb2RlPjwvcD4KLTxwPlRoZSA8bGluayBpZHJlZj0iZXh0ZW5zaW9uc2xpYiIgYW5jaG9yPSJyZWRpcmVjdCI+UmVkaXJlY3QgZXh0ZW5zaW9uPC9saW5rPiBpbiB0aGUgZXh0ZW5zaW9ucyBsaWJyYXJ5IGNvbnRhaW5zIHRocmVlIGV4dGVuc2lvbiBlbGVtZW50cy48L3A+Ci08L3MzPgotCi08L3MyPjxhbmNob3IgbmFtZT0iZXh0LWZ1bmN0aW9ucyIvPgotPHMyIHRpdGxlPSJVc2luZyBleHRlbnNpb24gZnVuY3Rpb25zIj4KLTxwPkV4dGVuc2lvbiBmdW5jdGlvbnMgbWF5IGluY2x1ZGUgYXJndW1lbnRzIG9mIGFueSB0eXBlIGFuZCByZXR1cm4gYSB2YWx1ZSBvZiBhbnkgdHlwZS48L3A+Ci08cD5YU0xUIHJlY29nbml6ZXMgZml2ZSBkYXRhIHR5cGVzOiBub2RlLXNldCwgcmVzdWx0LXRyZWUtZnJhZ21lbnQsIHN0cmluZywgYm9vbGVhbiwgYW5kIG51bWJlci4gWW91IGNhbiB1c2UgWFBhdGggZXhwcmVzc2lvbnMgdG8gc2V0IHZhcmlhYmxlcyB3aXRoIHZhbHVlcyBvZiB0aGVzZSB0eXBlcy4gWW91IGNhbiBhbHNvIHBhc3MgbGl0ZXJhbHMgZm9yIHN0cmluZywgYm9vbGVhbiwgYW5kIG51bWJlciBhcmd1bWVudHMuIElmIHlvdSB3YW50IHRvIHBhc3MgYW4gYXJndW1lbnQgb2YgYSB0eXBlIHRoYXQgWFNMVCBkb2VzIG5vdCByZWNvZ25pemUsIHVzZSBhbm90aGVyIGV4dGVuc2lvbiBmdW5jdGlvbiB0byByZXR1cm4gYW4gb2JqZWN0IG9mIHRoYXQgdHlwZS4gVGhlIHN0eWxlc2hlZXQgdGhhdCBhcHBlYXJzIGluIDxsaW5rIGFuY2hvcj0iZm9ybWF0LWRhdGUtc3R5bGVzaGVldCI+Rm9ybWF0dGluZyBhIGRhdGU8L2xpbms+LCBmb3IgZXhhbXBsZSB1c2VzIGV4dGVuc2lvbiBmdW5jdGlvbnMgdG8gcmV0dXJuIGEgRGF0ZSBvYmplY3QgYW5kIGEgU2ltcGxlRGF0ZUZvcm1hdCBvYmplY3QsIGFuZCB0aGVuIHVzZXMgdGhlc2Ugb2JqZWN0cyB0byBjYWxsIGFub3RoZXIgZXh0ZW5zaW9uIGZ1bmN0aW9uLjwvcD4KLTxzMyB0aXRsZT0iRGF0YSB0eXBlIG1hcHBpbmcgYW5kIG1ldGhvZCBzZWxlY3Rpb24iPgotPHA+V2hlbiBjYWxsaW5nIGFuIGV4dGVuc2lvbiBmdW5jdGlvbiB3cml0dGVuIGluIGEgbGFuZ3VhZ2Ugb3RoZXIgdGhhbiBKYXZhLCBvYmplY3RzIG9mIHRoZSBmb2xsb3dpbmcgSmF2YSBjbGFzc2VzIHdpbGwgYWx3YXlzIGJlIHBhc3NlZCB0byB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uOjwvcD4KLSAgPHRhYmxlPgotICAgIDx0cj4KLSAgICAgIDx0aD5YU0xUIFR5cGU8L3RoPgotICAgICAgPHRoPkphdmEgVHlwZTwvdGg+Ci0gICAgPC90cj4KLSAgICA8dHI+Ci0gICAgICAgPHRkPk5vZGUtU2V0PC90ZD4KLSAgICAgICA8dGQ+b3JnLnczYy5kb20udHJhdmVyc2FsLk5vZGVJdGVyYXRvcjwvdGQ+Ci0gICAgPC90cj4KLSAgICA8dHI+Ci0gICAgICAgPHRkPlN0cmluZzwvdGQ+Ci0gICAgICAgPHRkPmphdmEubGFuZy5TdHJpbmc8L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5Cb29sZWFuPC90ZD4KLSAgICAgICA8dGQ+amF2YS5sYW5nLkJvb2xlYW48L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5OdW1iZXI8L3RkPgotICAgICAgIDx0ZD5qYXZhLmxhbmcuRG91YmxlPC90ZD4KLSAgICA8L3RyPgotICAgIDx0cj4KLSAgICAgICA8dGQ+UmVzdWx0IFRyZWUgRnJhZ21lbnQ8L3RkPgotICAgICAgIDx0ZD5vcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50PC90ZD4KLSAgICA8L3RyPgotICA8L3RhYmxlPgotPHA+QW55IG5vbi1YU0xUIHR5cGUgaXMgcGFzc2VkIHdpdGhvdXQgY29udmVyc2lvbi48L3A+Ci08cD5XaGVuIGNhbGxpbmcgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uIHdyaXR0ZW4gaW4gSmF2YSwgdGhlIGV4dGVuc2lvbiBmdW5jdGlvbiBzaWduYXR1cmUgY2FuIHNwZWNpZnkgYW55IG9mIHRoZSBpbmRpY2F0ZWQgSmF2YSB0eXBlcywgYXMgZXhwbGFpbmVkIGJlbG93OjwvcD4KLSAgPHRhYmxlPgotICAgIDx0cj4KLSAgICAgIDx0aD5YU0xUIFR5cGU8L3RoPgotICAgICAgPHRoPkphdmEgVHlwZXM8L3RoPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5Ob2RlLVNldDwvdGQ+Ci0gICAgICAgPHRkPm9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IsIG9yZy53M2MuZG9tLk5vZGVMaXN0LCBvcmcudzNjLmRvbS5Ob2RlIG9yIGl0cyBzdWJjbGFzc2VzLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0LCBjaGFyLCBbZG91YmxlLCBmbG9hdCwgbG9uZywgaW50LCBzaG9ydCwgYnl0ZSxdIGJvb2xlYW48L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5TdHJpbmc8L3RkPgotICAgICAgIDx0ZD5qYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0LCBjaGFyLCBbZG91YmxlLCBmbG9hdCwgbG9uZywgaW50LCBzaG9ydCwgYnl0ZSxdIGJvb2xlYW48L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5Cb29sZWFuPC90ZD4KLSAgICAgICA8dGQ+Ym9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5PYmplY3QsIGphdmEubGFuZy5TdHJpbmc8L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5OdW1iZXI8L3RkPgotICAgICAgIDx0ZD5kb3VibGUsIGphdmEubGFuZy5Eb3VibGUsIGZsb2F0LCBsb25nLCBpbnQsIHNob3J0LGNoYXIsIGJ5dGUsIGJvb2xlYW4sIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5PYmplY3Q8L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5SZXN1bHQgVHJlZSBGcmFnbWVudDwvdGQ+Ci0gICAgICAgPHRkPm9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3IsIG9yZy53M2MuZG9tLk5vZGVMaXN0LCBvcmcudzNjLmRvbS5Ob2RlIG9yIGl0cyBzdWJjbGFzc2VzLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0LCBjaGFyLCBbZG91YmxlLCBmbG9hdCwgbG9uZywgaW50LCBzaG9ydCwgYnl0ZSxdIGJvb2xlYW48L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5Ob24tWFNMVCBUeXBlPC90ZD4KLSAgICAgICA8dGQ+dGhlIG5hdGl2ZSB0eXBlIG9yIGFueSBvZiBpdHMgc3VwZXJjbGFzc2VzLCBkb3VibGUsIGZsb2F0LCBsb25nLCBpbnQsIHNob3J0LCBjaGFyLCBieXRlLCBqYXZhLmxhbmcuU3RyaW5nPC90ZD4KLSAgICA8L3RyPgotICA8L3RhYmxlPgotPHA+V2hlbiBjYWxsaW5nIGV4dGVuc2lvbiBmdW5jdGlvbnMgd3JpdHRlbiBpbiBKYXZhLCAmeHNsdDRqOyBzZWxlY3RzIHRoZSBtZXRob2QgdG8gY2FsbCBhcyBmb2xsb3dzOjwvcD4KLTxvbD4KLSAgPGxpPiZ4c2x0NGo7IHNlbGVjdHMgYWxsIG1ldGhvZHMgd2hvc2UgbmFtZSBtYXRjaGVzIHRoZSBleHRlbnNpb24gZnVuY3Rpb24gbmFtZSBhcyBzcGVjaWZpZWQgaW4gPGxpbmsgYW5jaG9yPSJleHQtZnVuYy1jYWxscyI+RXh0ZW5zaW9uIGZ1bmN0aW9uIEphdmEgY2FsbHM8L2xpbms+LjwvbGk+Ci0gIDxsaT5Gcm9tIHRoaXMgbGlzdCBvZiBtZXRob2RzLCAmeHNsdDRqOyBkZXRlcm1pbmVzIHdoaWNoIG1ldGhvZHMgYXJlIDxyZWY+cXVhbGlmaWVkPC9yZWY+LjwvbGk+Ci0gIDxsaT5FYWNoIHF1YWxpZmllZCBtZXRob2QgaXMgYXNzaWduZWQgYSBzY29yZSBiYXNlZCBvbiB0aGUgdGFibGUgc2hvd24gYWJvdmUuIFRvIGFzc2lnbiB0aGUgc2NvcmUgdG8gYSBnaXZlbiBtZXRob2QsICZ4c2x0NGo7IGV4YW1pbmVzIGVhY2ggb2YgdGhlIFhTTFQgYXJndW1lbnQgdHlwZXMgaW4gdGhlIGZ1bmN0aW9uIGludm9jYXRpb24gaW4gdGhlIHN0eWxlc2hlZXQuIEZvciBlYWNoIGFyZ3VtZW50LCB0aGUgYXBwcm9wcmlhdGUgcm93IGluIHRoZSB0YWJsZSBhYm92ZSBpcyBzZWxlY3RlZC4gVGhlbiwgdGhlIGNvcnJlc3BvbmRpbmcgSmF2YSBwYXJhbWV0ZXIgdHlwZSBpbiB0aGUgbWV0aG9kIHNpZ25hdHVyZSBpbiB0aGUgSmF2YSBwcm9ncmFtIGlzIHNjb3JlZC4gVHlwZXMgd2hpY2ggYXBwZWFyIGVhcmxpZXIgaW4gdGhlIGxpc3QgYXJlIGdpdmVuIGEgaGlnaGVyIHNjb3JlLiAgVGhhdCBpcywgdGhlIGxpc3QgYXBwZWFycyBpbiBvcmRlciBvZiBzY29yaW5nIHByZWZlcmVuY2UgZnJvbSBoaWdoZXN0IHRvIGxvd2VzdC4gVHlwZXMgc2hvd24gaW4gc3F1YXJlIGJyYWNrZXRzIGhhdmUgZXF1YWwgcHJpb3JpdHkuPC9saT4KLSAgPGxpPlRoZSBtZXRob2Qgd2l0aCB0aGUgaGlnaGVzdCBzY29yZSBpcyBpbnZva2VkIGFmdGVyIHRoZSBhcmd1bWVudHMgYXJlIGNvbnZlcnRlZCB0byB0aGUgYXBwcm9wcmlhdGUgdHlwZS4gSWYgbW9yZSB0aGFuIG9uZSBtZXRob2QgaGFzIHRoZSBoaWdoZXN0IHNjb3JlLCBhbiBleGNlcHRpb24gaXMgdGhyb3duLjwvbGk+Ci08L29sPgotPHA+QW55IGV4dGVuc2lvbiBmdW5jdGlvbiB3cml0dGVuIGluIEphdmEgY2FuIGhhdmUgYSBmaXJzdCBwYXJhbWV0ZXIgb2YgdHlwZSA8Y29kZT5vcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMuRXhwcmVzc2lvbkNvbnRleHQ8L2NvZGU+LiBBbnkgbWV0aG9kIHdpdGggYW4gRXhwcmVzc2lvbkNvbnRleHQgYXMgdGhlIGZpcnN0IHBhcmFtZXRlciB3aWxsIHNjb3JlIGhpZ2hlciB0aGFuIGFueSBtZXRob2Qgd2hpY2ggZG9lcyBub3QgaGF2ZSBhbiBFeHByZXNzaW9uQ29udGV4dCBhcyBhIGZpcnN0IHBhcmFtZXRlci48L3A+Ci08L3MzPgotCi08YW5jaG9yIG5hbWU9ImV4dC1mdW5jLXJldHZhbCIvPgotPHMzIHRpdGxlPSJSZXR1cm4gdmFsdWVzIj4KLTxwPlRoZSAmeHNsdDRqOyBleHRlbnNpb24gbWVjaGFuaXNtIGV4YW1pbmVzIHRoZSBjbGFzcyBvZiB0aGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBhIGZ1bmN0aW9uIGFuZCBjb252ZXJ0cyB0aGUgdmFsdWUgaW50byBhbiBYU0xUIHR5cGUgYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcgdGFibGU6PC9wPgotICA8dGFibGU+Ci0gICAgPHRyPgotICAgICAgPHRoPkphdmEgVHlwZXM8L3RoPgotICAgICAgPHRoPlhTTFQgVHlwZTwvdGg+Ci0gICAgPC90cj4KLSAgICA8dHI+Ci0gICAgICAgPHRkPm9yZy53M2MuZG9tLnRyYXZlcnNhbC5Ob2RlSXRlcmF0b3I8YnIvPm9yZy5hcGFjaGUueG1sLmR0bS5EVE08YnIvPm9yZy5hcGFjaGUueG1sLmR0bS5EVE1BeGlzSXRlcmF0b3I8YnIvPm9yZy5hcGFjaGUueG1sLmR0bS5EVE1JdGVyYXRvcjxici8+b3JnLnczYy5kb20uTm9kZTwvdGQ+Ci0gICAgICAgPHRkPk5vZGUtU2V0PC90ZD4KLSAgICA8L3RyPgotICAgIDx0cj4KLSAgICAgICA8dGQ+amF2YS5sYW5nLlN0cmluZzwvdGQ+Ci0gICAgICAgPHRkPlN0cmluZzwvdGQ+Ci0gICAgPC90cj4KLSAgICA8dHI+Ci0gICAgICAgPHRkPmphdmEubGFuZy5Cb29sZWFuPC90ZD4KLSAgICAgICA8dGQ+Qm9vbGVhbjwvdGQ+Ci0gICAgPC90cj4KLSAgICA8dHI+Ci0gICAgICAgPHRkPmphdmEubGFuZy5OdW1iZXI8L3RkPgotICAgICAgIDx0ZD5OdW1iZXI8L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5vcmcudzNjLmRvbS5Eb2N1bWVudEZyYWdtZW50PC90ZD4KLSAgICAgICA8dGQ+UmVzdWx0IFRyZWUgRnJhZ21lbnQ8L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5vcmcuYXBhY2hlLnhwYXRoLm9iamVjdHMuWE9iamVjdDwvdGQ+Ci0gICAgICAgPHRkPlNwZWNpZmllZCBYU0xUIFR5cGU8L3RkPgotICAgIDwvdHI+Ci0gICAgPHRyPgotICAgICAgIDx0ZD5BbGwgb3RoZXIgY2xhc3NlczwvdGQ+Ci0gICAgICAgPHRkPk5vbi1YU0xUIFR5cGU8L3RkPgotICAgIDwvdHI+Ci0gIDwvdGFibGU+Ci0gIDxwPk5vdGUgdGhhdCB0aGUgYWJvdmUgdGVzdCBpcyBhcHBsaWVkIHVzaW5nIDxjb2RlPmluc3RhbmNlb2Y8L2NvZGU+IHNvIHRoYXQgYW55IHN1YmNsYXNzZXMgb2YgdGhlIGNsYXNzZXMgbGlzdGVkIGFib3ZlIHdpbGwgYmUgdHJlYXRlZCB0aGUgc2FtZSBhcyB0aGUgbGlzdGVkIHN1cGVyY2xhc3MuICBGb3IgZXhhbXBsZSwgYSA8Y29kZT5qYXZhLmxhbmcuRG91YmxlPC9jb2RlPiB3aWxsIGJlIHRyZWF0ZWQgdGhlIHNhbWUgYXMgYSA8Y29kZT5qYXZhLmxhbmcuTnVtYmVyPC9jb2RlPiBhbmQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gYW4gWFNMVCBOdW1iZXIuPC9wPgotICA8bm90ZT5UaGUgcmV0dXJuIHZhbHVlIGNvbnZlcnNpb24gY2FuIHNvbXRpbWVzIGNhdXNlIGNvbmZ1c2lvbi4gIEZvciBleGFtcGxlLCBpZiB5b3VyIGV4dGVuc2lvbiBmdW5jdGlvbiByZXR1cm5zIGFuIG9iamVjdCB0aGF0IGlzIGEgc3ViY2xhc3Mgb2YgTm9kZUl0ZXJhdG9yLCB0aGF0IG9iamVjdCB3aWxsIGJlIGNvbnZlcnRlZCBieSAmeHNsdDRqOyB0byBhbiBYU0xUIE5vZGUtU2V0LiAgSWYgeW91IGxhdGVyIGF0dGVtcHQgdG8gdHJlYXQgdGhhdCBvYmplY3QgYXMgYSBub24tWFNMVCBvYmplY3Qgb2YgeW91ciBvcmlnaW5hbCBjbGFzcyBhbmQgdHJ5IHRvIGludm9rZSBhIG1ldGhvZCBvbiB0aGF0IG9iamVjdCwgeW91ciBtZXRob2QgaW52b2NhdGlvbiB3aWxsIGZhaWwuPC9ub3RlPgotPC9zMz4KLQotPGFuY2hvciBuYW1lPSJleHQtZnVuYy1jYWxscyIvPgotPHMzIHRpdGxlPSJFeHRlbnNpb24gZnVuY3Rpb24gSmF2YSBjYWxscyI+Ci08cD5UaGUgdGVjaG5pcXVlIGZvciBpbnN0YW50aWF0aW5nIEphdmEgb2JqZWN0cyBhbmQgY2FsbGluZyBKYXZhIG1ldGhvZHMgZGVwZW5kcyBvbiB0aGUgZm9ybWF0IG9mIHRoZSBleHRlbnNpb24gbmFtZXNwYWNlIHRoYXQgd2FzIGRlY2xhcmVkLiAgU2VlIDxsaW5rIGFuY2hvcj0iamF2YS1uYW1lc3BhY2UtZGVjbGFyZSI+RGVjbGFyZSB0aGUgbmFtZXNwYWNlPC9saW5rPiBmb3IgdGhlIHRocmVlIGRpZmZlcmVudCBmb3JtYXRzIG9mIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgZm9yIEphdmEgZXh0ZW5zaW9ucy4gRm9yIGVhY2ggbmFtZXNwYWNlIGZvcm1hdCwgdGhlIHNlY3Rpb24gYmVsb3cgZGVzY3JpYmVzIGhvdyB0byBpbnN0YW50aWF0ZSBhbiBvYmplY3QsIGhvdyB0byBpbnZva2UgYW4gaW5zdGFuY2UgbWV0aG9kLCBhbmQgaG93IHRvIGludm9rZSBhIHN0YXRpYyBtZXRob2QuIFRoZSBzZWN0aW9ucyBiZWxvdyBleHBsYWluLCBmb3IgZWFjaCBzeW50YXgsIHdoaWNoIG1ldGhvZHMgYXJlIDxyZWY+cXVhbGlmaWVkPC9yZWY+IGZvciBtZXRob2Qgc2VsZWN0aW9uIGFzIGRlc2NyaWJlZCBpbiB0aGUgcHJlY2VlZGluZyBzZWN0aW9uLjwvcD4KLTxzNCB0aXRsZT0iQ2xhc3MgZm9ybWF0IG5hbWVzcGFjZSI+Ci08cD48YnIvPjxlbT5UbyBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYW4gb2JqZWN0PC9lbT46Ci08YnIvPjxjb2RlPjxyZWY+cHJlZml4PC9yZWY+Om5ldyAoPHJlZj5hcmdzPC9yZWY+KTwvY29kZT48L3A+Ci08cD53aGVyZSA8cmVmPnByZWZpeDwvcmVmPiBpcyB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXguIEEgbmV3IGluc3RhbmNlIGlzIHRvIGJlIGNyZWF0ZWQgd2l0aCB0aGUgPHJlZj5hcmdzPC9yZWY+IGNvbnN0cnVjdG9yIGFyZ3VtZW50cyAoaWYgYW55KS4gQWxsIGNvbnN0cnVjdG9yIG1ldGhvZHMgYXJlIHF1YWxpZmllZCBmb3IgbWV0aG9kIHNlbGVjdGlvbi4KLTxici8+RXhhbXBsZTogPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJteVR5cGUiPC9jb2RlPgotPGJyLz48Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtzZWxlY3Q9Im15LWNsYXNzOm5ldygpIiZndDs8L2NvZGU+PC9wPgotCi08cD48ZW0+VG8gaW52b2tlIGFuIGluc3RhbmNlIG1ldGhvZCBvbiBhIHNwZWNpZmllZCBvYmplY3Q8L2VtPjoKLTxici8+PGNvZGU+PHJlZj5wcmVmaXg8L3JlZj46PHJlZj5tZXRob2ROYW1lPC9yZWY+ICg8cmVmPm9iamVjdDwvcmVmPiwgPHJlZj5hcmdzPC9yZWY+KTwvY29kZT48L3A+Ci08cD53aGVyZSA8cmVmPnByZWZpeDwvcmVmPiBpcyB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXggYW5kIDxyZWY+bWV0aG9kTmFtZTwvcmVmPiBpcyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSBvbiA8cmVmPm9iamVjdDwvcmVmPiB3aXRoIHRoZSA8cmVmPmFyZ3M8L3JlZj4gYXJndW1lbnRzLiA8cmVmPm9iamVjdDwvcmVmPiBtdXN0IGJlIGFuIG9iamVjdCBvZiB0aGUgY2xhc3MgaW5kaWNhdGVkIGJ5IHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24uICBPdGhlcndpc2UsIHRoZSBjYXNlIHNob3duIGltbWVkaWF0ZWx5IGJlbG93IHdpbGwgYXBwbHkuIE9ubHkgaW5zdGFuY2UgbWV0aG9kcyB3aXRoICB0aGUgbmFtZSA8cmVmPm1ldGhvZE5hbWU8L3JlZj4gYXJlIHF1YWxpZmllZCBtZXRob2RzLiBJZiBhIG1hdGNoaW5nIG1ldGhvZCBpcyBmb3VuZCwgPHJlZj5vYmplY3Q8L3JlZj4gd2lsbCBiZSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBvYmplY3QgaW5zdGFuY2UgYW5kIDxyZWY+YXJnczwvcmVmPiB3aWxsIGJlIHBhc3NlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuCi08YnIvPgotRXhhbXBsZTogPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJuZXctcG9wIjwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7c2VsZWN0PSJteS1jbGFzczp2YWx1ZU9mKCRteVR5cGUsIHN0cmluZyhAcG9wdWxhdGlvbikpIiZndDs8L2NvZGU+PC9wPgotCi08cD48ZW0+VG8gaW52b2tlIGFuIGluc3RhbmNlIG1ldGhvZCBvbiBhIGRlZmF1bHQgb2JqZWN0PC9lbT46Ci08YnIvPjxjb2RlPjxyZWY+cHJlZml4PC9yZWY+OjxyZWY+bWV0aG9kTmFtZTwvcmVmPiAoPHJlZj5hcmdzPC9yZWY+KTwvY29kZT48L3A+Ci08cD53aGVyZSA8cmVmPnByZWZpeDwvcmVmPiBpcyB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXggYW5kIDxyZWY+bWV0aG9kTmFtZTwvcmVmPiBpcyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSB3aXRoIHRoZSA8cmVmPmFyZ3M8L3JlZj4gYXJndW1lbnRzLiBUaGUgZmlyc3QgPHJlZj5hcmc8L3JlZj4sIGlmIGFueSwgbXVzdCBub3QgYmUgYW4gb2JqZWN0IG9mIHRoZSBjbGFzcyBpbmRpY2F0ZWQgYnkgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4gIE90aGVyd2lzZSwgdGhlIGNhc2Ugc2hvd24gaW1tZWRpYXRlbHkgYWJvdmUgd2lsbCBhcHBseS4gT25seSBpbnN0YW5jZSBtZXRob2RzIHdpdGggdGhlIG5hbWUgPHJlZj5tZXRob2ROYW1lPC9yZWY+IGFyZSBxdWFsaWZpZWQgbWV0aG9kcy4gSWYgYSBtYXRjaGluZyBtZXRob2QgaXMgZm91bmQsIGEgZGVmYXVsdCBpbnN0YW5jZSBvZiB0aGUgY2xhc3Mgd2lsbCBiZSBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGFscmVhZHkgZXhpc3QuCi08YnIvPgotRXhhbXBsZTogPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJuZXctcG9wIjwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7c2VsZWN0PSJteS1jbGFzczp2YWx1ZU9mKHN0cmluZyhAcG9wdWxhdGlvbikpIiZndDs8L2NvZGU+PC9wPgotCi08cD48ZW0+VG8gaW52b2tlIGEgc3RhdGljIG1ldGhvZDwvZW0+OgotPGJyLz48Y29kZT48cmVmPnByZWZpeDwvcmVmPjo8cmVmPm1ldGhvZE5hbWU8L3JlZj4gKDxyZWY+YXJnczwvcmVmPik8L2NvZGU+PC9wPgotPHA+d2hlcmUgPHJlZj5wcmVmaXg8L3JlZj4gaXMgdGhlIGV4dGVuc2lvbiBuYW1lc3BhY2UgcHJlZml4IGFuZCA8cmVmPm1ldGhvZE5hbWU8L3JlZj4gaXMgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBpbnZva2Ugd2l0aCB0aGUgPHJlZj5hcmdzPC9yZWY+IGFyZ3VtZW50cy4gT25seSBzdGF0aWMgbWV0aG9kcyB3aXRoIHRoZSBuYW1lIDxyZWY+bWV0aG9kTmFtZTwvcmVmPiBhcmUgcXVhbGlmaWVkIG1ldGhvZHMuIElmIGEgbWF0Y2hpbmcgbWV0aG9kIGlzIGZvdW5kLCA8cmVmPmFyZ3M8L3JlZj4gd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGludm9rZWQgc3RhdGljIG1ldGhvZC4KLTxici8+Ci1FeGFtcGxlOiA8Y29kZT4mbHQ7eHNsOnZhcmlhYmxlIG5hbWU9Im5ldy1wb3AiPC9jb2RlPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtzZWxlY3Q9Im15LWNsYXNzOnByaW50aXQoc3RyaW5nKEBwb3B1bGF0aW9uKSkiJmd0OzwvY29kZT48L3A+Ci08L3M0PgotPHM0IHRpdGxlPSJQYWNrYWdlIGZvcm1hdCBuYW1lc3BhY2UiPgotPHA+PGJyLz48ZW0+VG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIG9iamVjdDwvZW0+OgotPGJyLz48Y29kZT48cmVmPnByZWZpeDwvcmVmPjo8cmVmPnN1YnBhY2thZ2U8L3JlZj4uPHJlZj5jbGFzczwvcmVmPi5uZXcgKDxyZWY+YXJnczwvcmVmPik8L2NvZGU+PC9wPgotPHA+d2hlcmUgPHJlZj5wcmVmaXg8L3JlZj4gaXMgdGhlIGV4dGVuc2lvbiBuYW1lc3BhY2UgcHJlZml4LCA8cmVmPnN1YnBhY2thZ2U8L3JlZj4gaXMgdGhlIHJlc3Qgb2YgdGhlIHBhY2thZ2UgbmFtZSAodGhlIGJlZ2lubmluZyBvZiB0aGUgcGFja2FnZSBuYW1lIHdhcyBpbiB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9uKSwgYW5kIDxyZWY+Y2xhc3M8L3JlZj4gaXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzLiBBIG5ldyBpbnN0YW5jZSBpcyB0byBiZSBjcmVhdGVkIHdpdGggdGhlIDxyZWY+YXJnczwvcmVmPiBjb25zdHJ1Y3RvciBhcmd1bWVudHMgKGlmIGFueSkuIEFsbCBjb25zdHJ1Y3RvciBtZXRob2RzIGFyZSBxdWFsaWZpZWQgZm9yIG1ldGhvZCBzZWxlY3Rpb24uCi08YnIvPkV4YW1wbGU6IDxjb2RlPiZsdDt4c2w6dmFyaWFibGUgbmFtZT0ibXlUeXBlIjwvY29kZT4KLTxici8+PGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7c2VsZWN0PSJteS1wYWNrYWdlOmV4dGNsYXNzLm5ldygpIiZndDs8L2NvZGU+PC9wPgotCi08cD48ZW0+VG8gaW52b2tlIGFuIGluc3RhbmNlIG1ldGhvZCBvbiBhIHNwZWNpZmllZCBpbnN0YW5jZTwvZW0+OgotPGJyLz48Y29kZT48cmVmPnByZWZpeDwvcmVmPjo8cmVmPm1ldGhvZE5hbWU8L3JlZj4gKDxyZWY+b2JqZWN0PC9yZWY+LCA8cmVmPmFyZ3M8L3JlZj4pPC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+cHJlZml4PC9yZWY+IGlzIHRoZSBleHRlbnNpb24gbmFtZXNwYWNlIHByZWZpeCBhbmQgPHJlZj5tZXRob2ROYW1lPC9yZWY+IGlzIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlIG9uIDxyZWY+b2JqZWN0PC9yZWY+IHdpdGggdGhlIDxyZWY+YXJnczwvcmVmPiBhcmd1bWVudHMuIE9ubHkgaW5zdGFuY2UgbWV0aG9kcyBvZiB0aGUgPHJlZj5vYmplY3Q8L3JlZj4gd2l0aCB0aGUgbmFtZSA8cmVmPm1ldGhvZE5hbWU8L3JlZj4gYXJlIHF1YWxpZmllZCBtZXRob2RzLiBJZiBhIG1hdGNoaW5nIG1ldGhvZCBpcyBmb3VuZCwgPHJlZj5vYmplY3Q8L3JlZj4gd2lsbCBiZSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBvYmplY3QgaW5zdGFuY2UgYW5kIDxyZWY+YXJnczwvcmVmPiB3aWxsIGJlIHBhc3NlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuCi08YnIvPgotRXhhbXBsZTogPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJuZXctcG9wIjwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7c2VsZWN0PSJteS1wYWNrYWdlOnZhbHVlT2YoJG15VHlwZSwgc3RyaW5nKEBwb3B1bGF0aW9uKSkiJmd0OzwvY29kZT48L3A+Ci0KLTxwPjxlbT5UbyBpbnZva2UgYSBzdGF0aWMgbWV0aG9kPC9lbT46Ci08YnIvPjxjb2RlPjxyZWY+cHJlZml4PC9yZWY+OjxyZWY+c3VicGFja2FnZTwvcmVmPi48cmVmPmNsYXNzPC9yZWY+LjxyZWY+bWV0aG9kTmFtZTwvcmVmPiAoPHJlZj5hcmdzPC9yZWY+KTwvY29kZT48L3A+Ci08cD53aGVyZSA8cmVmPnByZWZpeDwvcmVmPiBpcyB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXgsIDxyZWY+c3VicGFja2FnZTwvcmVmPiBpcyB0aGUgcmVzdCBvZiB0aGUgcGFja2FnZSBuYW1lICh0aGUgYmVnaW5uaW5nIG9mIHRoZSBwYWNrYWdlIG5hbWUgd2FzIGluIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24pLCA8cmVmPmNsYXNzPC9yZWY+IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcywgYW5kIDxyZWY+bWV0aG9kTmFtZTwvcmVmPiBpcyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSB3aXRoIHRoZSA8cmVmPmFyZ3M8L3JlZj4gYXJndW1lbnRzLiBPbmx5IHN0YXRpYyBtZXRob2RzIHdpdGggdGhlIG5hbWUgPHJlZj5tZXRob2ROYW1lPC9yZWY+IGFyZSBxdWFsaWZpZWQgbWV0aG9kcy4gSWYgYSBtYXRjaGluZyBtZXRob2QgaXMgZm91bmQsIDxyZWY+YXJnczwvcmVmPiB3aWxsIGJlIHBhc3NlZCB0byB0aGUgaW52b2tlZCBzdGF0aWMgbWV0aG9kLgotPGJyLz4KLUV4YW1wbGU6IDxjb2RlPiZsdDt4c2w6dmFyaWFibGUgbmFtZT0ibmV3LXBvcCI8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3NlbGVjdD0ibXktcGFja2FnZTpleHRjbGFzcy5wcmludGl0KHN0cmluZyhAcG9wdWxhdGlvbikpIiZndDs8L2NvZGU+PC9wPgotPG5vdGU+VW5saWtlIHRoZSBjbGFzcyBmb3JtYXQgbmFtZXNwYWNlLCB0aGVyZSBpcyBubyBjb25jZXB0IG9mIGEgZGVmYXVsdCBvYmplY3Qgc2luY2UgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBkb2VzIG5vdCBpZGVudGlmeSBhIHVuaXF1ZSBjbGFzcy48L25vdGU+Ci08L3M0PgotPHM0IHRpdGxlPSJKYXZhIGZvcm1hdCBuYW1lc3BhY2UiPgotPHA+PGJyLz48ZW0+VG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIG9iamVjdDwvZW0+OgotPGJyLz48Y29kZT48cmVmPnByZWZpeDwvcmVmPjo8cmVmPkZRQ048L3JlZj4ubmV3ICg8cmVmPmFyZ3M8L3JlZj4pPC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+cHJlZml4PC9yZWY+IGlzIHRoZSBleHRlbnNpb24gbmFtZXNwYWNlIHByZWZpeCBmb3IgdGhlIEphdmEgbmFtZXNwYWNlIGFuZCA8cmVmPkZRQ048L3JlZj4gaXMgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIG9mIHRoZSBjbGFzcyB3aG9zZSBjb25zdHJ1Y3RvciBpcyB0byBiZSBjYWxsZWQuIEEgbmV3IGluc3RhbmNlIGlzIHRvIGJlIGNyZWF0ZWQgd2l0aCB0aGUgPHJlZj5hcmdzPC9yZWY+IGNvbnN0cnVjdG9yIGFyZ3VtZW50cyAoaWYgYW55KS4gQWxsIGNvbnN0cnVjdG9yIG1ldGhvZHMgYXJlIHF1YWxpZmllZCBmb3IgbWV0aG9kIHNlbGVjdGlvbi4KLTxici8+RXhhbXBsZTogPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJteUhhc2giPC9jb2RlPgotPGJyLz48Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtzZWxlY3Q9ImphdmE6amF2YS51dGlsLkhhc2h0YWJsZS5uZXcoKSImZ3Q7PC9jb2RlPjwvcD4KLQotPHA+PGVtPlRvIGludm9rZSBhbiBpbnN0YW5jZSBtZXRob2Qgb24gYSBzcGVjaWZpZWQgaW5zdGFuY2U8L2VtPjoKLTxici8+PGNvZGU+PHJlZj5wcmVmaXg8L3JlZj46PHJlZj5tZXRob2ROYW1lPC9yZWY+ICg8cmVmPm9iamVjdDwvcmVmPiwgPHJlZj5hcmdzPC9yZWY+KTwvY29kZT48L3A+Ci08cD53aGVyZSA8cmVmPnByZWZpeDwvcmVmPiBpcyB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXggYW5kIDxyZWY+bWV0aG9kTmFtZTwvcmVmPiBpcyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSBvbiA8cmVmPm9iamVjdDwvcmVmPiB3aXRoIHRoZSA8cmVmPmFyZ3M8L3JlZj4gYXJndW1lbnRzLiBPbmx5IGluc3RhbmNlIG1ldGhvZHMgb2YgdGhlIDxyZWY+b2JqZWN0PC9yZWY+IHdpdGggdGhlIG5hbWUgPHJlZj5tZXRob2ROYW1lPC9yZWY+IGFyZSBxdWFsaWZpZWQgbWV0aG9kcy4gSWYgYSBtYXRjaGluZyBtZXRob2QgaXMgZm91bmQsIDxyZWY+b2JqZWN0PC9yZWY+IHdpbGwgYmUgdXNlZCB0byBpZGVudGlmeSB0aGUgb2JqZWN0IGluc3RhbmNlIGFuZCA8cmVmPmFyZ3M8L3JlZj4gd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGludm9rZWQgbWV0aG9kLgotPGJyLz4KLUV4YW1wbGU6IDxjb2RlPiZsdDt4c2w6dmFyaWFibGUgbmFtZT0ibmV3LXBvcCI8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3NlbGVjdD0iamF2YTpwdXQoJG15SGFzaCwgc3RyaW5nKEByZWdpb24pLCAkbmV3cG9wKSImZ3Q7PC9jb2RlPjwvcD4KLQotPHA+PGVtPlRvIGludm9rZSBhIHN0YXRpYyBtZXRob2Q8L2VtPjoKLTxici8+PGNvZGU+PHJlZj5wcmVmaXg8L3JlZj46PHJlZj5GUUNOPC9yZWY+LjxyZWY+bWV0aG9kTmFtZTwvcmVmPiAoPHJlZj5hcmdzPC9yZWY+KTwvY29kZT48L3A+Ci08cD53aGVyZSA8cmVmPnByZWZpeDwvcmVmPiBpcyB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZSBwcmVmaXgsIDxyZWY+RlFDTjwvcmVmPiBpcyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgb2YgdGhlIGNsYXNzIHdob3NlIHN0YXRpYyBtZXRob2QgaXMgdG8gYmUgY2FsbGVkLCBhbmQgPHJlZj5tZXRob2ROYW1lPC9yZWY+IGlzIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlIHdpdGggdGhlIDxyZWY+YXJnczwvcmVmPiBhcmd1bWVudHMuIE9ubHkgc3RhdGljIG1ldGhvZHMgd2l0aCB0aGUgbmFtZSA8cmVmPm1ldGhvZE5hbWU8L3JlZj4gYXJlIHF1YWxpZmllZCBtZXRob2RzLiBJZiBhIG1hdGNoaW5nIG1ldGhvZCBpcyBmb3VuZCwgPHJlZj5hcmdzPC9yZWY+IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBpbnZva2VkIHN0YXRpYyBtZXRob2QuCi08YnIvPgotRXhhbXBsZTogPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJuZXctcG9wIjwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7c2VsZWN0PSJqYXZhOmphdmEubGFuZy5JbnRlZ2VyLnZhbHVlT2Yoc3RyaW5nKEBwb3B1bGF0aW9uKSkiJmd0OzwvY29kZT48L3A+Ci08bm90ZT5Vbmxpa2UgdGhlIGNsYXNzIGZvcm1hdCBuYW1lc3BhY2UsIHRoZXJlIGlzIG5vIGNvbmNlcHQgb2YgYSBkZWZhdWx0IG9iamVjdCBzaW5jZSB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGRvZXMgbm90IGlkZW50aWZ5IGEgdW5pcXVlIGNsYXNzLjwvbm90ZT4KLTwvczQ+Ci08L3MzPgotCi08czMgdGl0bGU9IlBhc3NpbmcgTm9kZXMgdG8gamF2YSI+Ci08cD5QbGVhc2Uga2VlcCBpbiBtaW5kIHRoYXQgPGVtPmFsbDwvZW0+IExvY2F0aW9uUGF0aCBleHByZXNzaW9ucyByZXR1cm4gYSBub2RlLXNldCwgZXZlbiBpZiB0aGUgZXhwcmVzc2lvbiBvbmx5IHJldHVybnMgYSBzaW5nbGUgYXR0cmlidXRlIG9yIGEgdGV4dCBub2RlIChub2RlLXNldHMgd2l0aCBvbmUgbWVtYmVyKS4gWW91IGNhbiB1c2UgdGhlIFhTTFQgc3RyaW5nKCkgZnVuY3Rpb24gKGFzIGluIHRoZSBzeW50YXggZXhhbXBsZXMgYWJvdmUpIHRvIGNvbnZlcnQgYSBub2RlLXNldCB2YWx1ZSB0byBzdHJpbmcsIGFuZCB0aGUgbnVtYmVyKCkgZnVuY3Rpb24gdG8gY29udmVydCBhIG5vZGUtc2V0IHZhbHVlIHRvIG51bWJlciAoYSBkb3VibGUpLjwvcD4KLTxwPklmIHlvdSB3YW50IHRvIHBhc3MgYSBub2RlLXNldCB0byBhbiBleHRlbnNpb24gZnVuY3Rpb24sIHNldCB1cCBhIEphdmEgbWV0aG9kIHRvIGFjY2VwdCBhbiAKLW9yZy53M2MuZG9tLk5vZGVMaXN0IChvciBhbiBvcmcuYXBhY2hlLnhwYXRoLk5vZGVTZXQsIHdoaWNoIGltcGxlbWVudHMgTm9kZUxpc3QsIGlmIHlvdSB3YW50IHRvIG1vZGlmeSB0aGUgbm9kZXMpLjwvcD4KLTxwPlN1cHBvc2UsIGZvciBleGFtcGxlLCB5b3UgaGF2ZSBhIG15RXh0ZW5zaW9ucy5Qcm9jZXNzTm9kZXMgY2xhc3Mgd2l0aCB0aGUgZm9sbG93aW5nIGRvU29tZXRoaW5nIG1ldGhvZDo8L3A+Ci08cD48Y29kZT5wdWJsaWMgc3RhdGljIGJvb2xlYW4gZG9Tb21ldGhpbmcob3JnLnczYy5kb20uTm9kZUxpc3Qgbkxpc3QpPC9jb2RlPjwvcD4KLTxwPkFzc3VtaW5nIHlvdSBzZXQgdXAgdGhpcyBleHRlbnNpb24gaW4gdGhlIG5vZGUtZXh0IG5hbWVzcGFjZSwgYW55IG9mIHRoZSBmb2xsb3dpbmcgZXh0ZW5zaW9uIGNhbGxzIGZyb20gYSBzdHlsZXNoZWV0IGFyZSBzeW50YWN0aWNhbGx5IHBvc3NpYmxlOjwvcD4KLTxwPjxjb2RlPiZsdDshLS1Qcm9jZXNzIHRoZSBjdXJyZW50IG5vZGUtLSZndDs8L2NvZGU+PGJyLz4KLTxjb2RlPiZsdDt4c2w6dmFyaWFibGUgbmFtZT0ic3VjY2VzcyIgc2VsZWN0PSJub2RlLWV4dDpNeUV4dGVuc2lvbnMuUHJvY2Vzc05vZGVzLmRvU29tZXRoaW5nKC4pIi8mZ3Q7PC9jb2RlPjwvcD4KLTxwPjxjb2RlPiZsdDshLS1Qcm9jZXNzIGFsbCBub2RlcyBpbiBjdXJyZW50IGNvbnRleHQtLT48L2NvZGU+PGJyLz4KLTxjb2RlPiZsdDt4c2w6dmFyaWFibGUgbmFtZT0ic3VjY2VzcyIgc2VsZWN0PSJub2RlLWV4dDpNeUV4dGVuc2lvbnMuUHJvY2Vzc05vZGVzLmRvU29tZXRoaW5nKCopIi8mZ3Q7PC9jb2RlPjwvcD4KLTxwPjxjb2RlPiZsdDshLS0gUHJvY2VzcyBhbGwgbm9kZXMgLS0+PC9jb2RlPjxici8+Ci08Y29kZT4mbHQ7eHNsOnZhcmlhYmxlIG5hbWU9InN1Y2Nlc3MiIHNlbGVjdD0ibm9kZS1leHQ6TXlFeHRlbnNpb25zLlByb2Nlc3NOb2Rlcy5kb1NvbWV0aGluZygvKikiLyZndDs8L2NvZGU+PC9wPgotPHA+PGNvZGU+Jmx0OyEtLVByb2Nlc3MgdGhlIGZvby9iYXogbm9kZXMgaW4gY3VycmVudCBjb250ZXh0IC0tPjwvY29kZT48YnIvPgotPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJzdWNjZXNzIiBzZWxlY3Q9Im5vZGUtZXh0Ok15RXh0ZW5zaW9ucy5Qcm9jZXNzTm9kZXMuZG9Tb21ldGhpbmcoZm9vL2JheikiLyZndDs8L2NvZGU+PC9wPgotPHA+PGNvZGU+Jmx0OyEtLVByb2Nlc3MgdGhlL2Zvby9iYXogYW5kIC9iYXIvc2F6IG5vZGVzIC0tPjwvY29kZT48YnIvPgotPGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJzdWNjZXNzIiBzZWxlY3Q9Im5vZGUtZXh0Ok15RXh0ZW5zaW9ucy5Qcm9jZXNzTm9kZXMuZG9Tb21ldGhpbmcoL2Zvby9iYXogfCAvYmFyL3NheikiLyZndDs8L2NvZGU+PC9wPgotPHA+VGhlIE5vZGVMaXN0IGlzIGluIGZhY3QgYSBsaXN0IG9mIHJlZmVyZW5jZXMgaW50byB0aGUgWE1MIGRvY3VtZW50LCBzbyBrZWVwIGluIG1pbmQgdGhhdCBnZXROZXh0U2libGluZygpLCBmb3IgZXhhbXBsZSwgZ2V0cyB5b3UgdGhlIG5leHQgc2libGluZyBpbiB0aGUgZG9jdW1lbnQsIHdoaWNoIG1heSBub3QgYmUgdGhlIG5leHQgTm9kZSBpbiB0aGUgTm9kZUxpc3QuPC9wPgotPC9zMz4KLTxzMyB0aXRsZT0iSW1wbGVtZW50aW5nIGV4dGVuc2lvbiBmdW5jdGlvbnMiPgotPHA+Rm9yIGVhY2ggZXh0ZW5zaW9uIGZ1bmN0aW9uIGluIGEgbmFtZXNwYWNlIHdoaWNoIGlzIGltcGxlbWVudGVkIGluIGEgbGFuZ3VhZ2Ugb3RoZXIgdGhhbiBKYXZhLCB0aGUgaW1wbGVtZW50YXRpb24gbXVzdCBpbmNsdWRlIGEgbWV0aG9kIHdpdGggdGhlIGZvbGxvd2luZyBzaWduYXR1cmUsIG9yIHRoZSBzY3JpcHRpbmcgbGFuZ3VhZ2UgZXF1aXZhbGVudDo8L3A+Ci08cD48Y29kZT5wdWJsaWMgPHJlZj4gb2JqZWN0IGZ1bmN0aW9uPC9yZWY+KDxyZWY+YXJnczwvcmVmPik8L2NvZGU+PC9wPgotPHA+d2hlcmUgPHJlZj5vYmplY3Q8L3JlZj4gaXMgdGhlIHJldHVybiB0eXBlLCA8cmVmPmZ1bmN0aW9uPC9yZWY+IGlzIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBleHRlbnNpb24gZnVuY3Rpb24gbmFtZSAodGhlIGZ1bmN0aW9uIG5hbWUgd2l0aG91dCB0aGUgbmFtZXNwYWNlIHByZWZpeCksIGFuZCA8cmVmPmFyZ3M8L3JlZj4gY29ycmVzcG9uZCB0byB0aGUgYXJndW1lbnRzIGluIHRoZSBmdW5jdGlvbiBjYWxsLjwvcD4KLTxwPkluIGFkZGl0aW9uLCBmb3IgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBpbXBsZW1lbnRlZCBpbiBKYXZhLCB0aGUgaW1wbGVtZW50YXRpb24gbWF5IGluY2x1ZGUgZWl0aGVyIGEgSmF2YSBtZXRob2Qgd2l0aCB0aGUgc2lnbmF0dXJlIHNob3duIGFib3ZlIG9yIG9uZSB3aXRoIHRoZSBmb2xsb3dpbmcgc2lnbmF0dXJlOjwvcD4KLTxwPjxjb2RlPnB1YmxpYyA8cmVmPiBvYmplY3QgZnVuY3Rpb248L3JlZj4ob3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLkV4cHJlc3Npb25Db250ZXh0LCA8cmVmPmFyZ3M8L3JlZj4pPC9jb2RlPjwvcD4KLTwvczM+Ci08L3MyPjxhbmNob3IgbmFtZT0iamF2YS1uYW1lc3BhY2UiLz4KLTxzMiB0aXRsZT0iQWx0ZXJuYXRpdmU6IHVzaW5nIHRoZSBhYmJyZXZpYXRlZCBzeW50YXggZm9yIGV4dGVuc2lvbnMgaW1wbGVtZW50ZWQgaW4gSmF2YSI+Ci08cD5Gb3IgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBhbmQgZXh0ZW5zaW9uIGVsZW1lbnRzIGltcGxlbWVudGVkIGluIEphdmEsIFhhbGFuIHBlcm1pdHMgYW4gYWJicmV2aWF0ZWQgc3ludGF4LiBXaGVuIHlvdSB1c2UgdGhlIGFiYnJldmlhdGVkIHN5bnRheCwgeW91IGRvIG5vdCB1c2UgYW4gbHhzbHQ6Y29tcG9uZW50IHRvIGRlc2lnbmF0ZSB0aGUgZnVuY3Rpb25zLjwvcD4KLTxwPlRoZSBhYmJyZXZpYXRlZCBzeW50YXggc3VwcG9ydHMgdGhlIHVzZSBvZiBleHRlbnNpb24gZnVuY3Rpb25zIGFuZCBleHRlbnNpb24gZWxlbWVudHMgaW1wbGVtZW50ZWQgaW4gSmF2YS4gWW91IGNhbm5vdCB1c2UgdGhpcyBzeW50YXggd2l0aCBleHRlbnNpb25zIGltcGxlbWVudGVkIGluIEphdmFTY3JpcHQgb3IgYW5vdGhlciBzY3JpcHRpbmcgbGFuZ3VhZ2UuPC9wPgotPGFuY2hvciBuYW1lPSJqYXZhLW5hbWVzcGFjZS1kZWNsYXJlIi8+Ci08czMgdGl0bGU9IkRlY2xhcmUgdGhlIG5hbWVzcGFjZSI+Ci08cD5EZWNsYXJlIHRoZSBuYW1lc3BhY2UgZm9yIHlvdXIgZXh0ZW5zaW9ucyB1c2luZyBvbmUgb2YgdGhlIGZvbGxvd2luZyB0aHJlZSBmb3JtYXRzLiBUaGUgdGVjaG5pcXVlIGZvciBpbnZva2luZyBhbiBleHRlbnNpb24gZm9yIGVhY2ggZm9ybWF0IGlzIGV4cGxhaW5lZCBpbiA8bGluayBhbmNob3I9ImV4dC1mdW5jLWNhbGxzIj5FeHRlbnNpb24gZnVuY3Rpb24gSmF2YSBjYWxsczwvbGluaz4uPC9wPgotPHA+PGVtPmNsYXNzIGZvcm1hdDo8L2VtPiA8Y29kZT54bWxuczpteS1jbGFzcz0ieGFsYW46Ly88cmVmPkZRQ048L3JlZj4iPC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+RlFDTjwvcmVmPiBpcyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUuCi08YnIvPkV4YW1wbGVzOiA8Y29kZT54bWxuczpteS1jbGFzcz0ieGFsYW46Ly9qYXZhLnV0aWwuSGFzaHRhYmxlIjwvY29kZT4KLTxici8+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PGNvZGU+eG1sbnM6bXktY2xhc3M9InhhbGFuOi8vbXlwYWNrYWdlLm15Y2xhc3MiPC9jb2RlPjwvcD4KLTxwPjxlbT5wYWNrYWdlIGZvcm1hdDo8L2VtPiA8Y29kZT54bWxuczpteS1jbGFzcz0ieGFsYW46Ly88cmVmPlBKUE48L3JlZj4iPC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+UEpQTjwvcmVmPiBpcyBhIHBhcnRpYWwgamF2YSBwYWNrYWdlIG5hbWUuICBUaGF0IGlzLCBpdCBpcyB0aGUgYmVnaW5uaW5nIG9mIG9yIHRoZSBjb21wbGV0ZSBuYW1lIG9mIGEgamF2YSBwYWNrYWdlLgotPGJyLz5FeGFtcGxlczogPGNvZGU+eG1sbnM6bXktcGFja2FnZT0ieGFsYW46Ly9qYXZhLnV0aWwiPC9jb2RlPgotPGJyLz4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs8Y29kZT54bWxuczpteS1wYWNrYWdlPSJ4YWxhbjovL215cGFja2FnZSI8L2NvZGU+PC9wPgotPHA+PGVtPkphdmEgZm9ybWF0OjwvZW0+IDxjb2RlPnhtbG5zOmphdmE9Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0L2phdmEiPC9jb2RlPjwvcD4KLTxub3RlPkFsdGhvdWdoIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIGZvciB0aGUgY2xhc3MgYW5kIHBhY2thZ2UgZm9ybWF0cyBhcmUgc2hvd24gd2l0aCB0aGUgeGFsYW46Ly8gcHJlZml4LCB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhvc2UgZm9ybWF0cyB3aWxsIHNpbXBseSB1c2UgdGhlIHN0cmluZyB0byB0aGUgcmlnaHQgb2YgdGhlIHJpZ2h0bW9zdCBmb3J3YXJkIHNsYXNoIGFzIHRoZSBKYXZhIGNsYXNzIG5hbWUuIFRoaXMgZm9ybWF0LCBob3dldmVyLCBpcyB0aGUgcHJlZmVycmVkIGZvcm1hdCBmb3IgZXh0ZW5zaW9uIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMuPC9ub3RlPgotPG5vdGU+VGhlIGNsYXNzOiBwcmVmaXggd2hpY2ggd2FzIHNvbWV0aW1lcyByZXF1aXJlZCBpbiBlYXJsaWVyIHZlcnNpb25zIG9mICZ4c2x0NGo7IGlzIG5vIGxvbmdlciByZXF1aXJlZC48L25vdGU+Ci08bm90ZT5UaGVzZSBmb3JtYXRzIGFyZSBhbHNvIGF2YWlsYWJsZSB3aGVuIGNvZGluZyB0aGUgc3JjIGF0dHJpYnV0ZSBvZiB0aGUgbHhzbHQ6c2NyaXB0IGVsZW1lbnQgYXMgZXhwbGFpbmVkIGluIDxsaW5rIGFuY2hvcj0ic2V0dXAtc2NyaXB0Ij5TZXQgdXAgdGhlIGx4c2x0OnNjcmlwdCBlbGVtZW50PC9saW5rPi48L25vdGU+Ci08L3MzPgotPHMzIHRpdGxlPSJVc2UgdGhlIG5hbWVzcGFjZSB3aGVuIHlvdSBtYWtlIGV4dGVuc2lvbiBjYWxscyI+Ci08cD5Vc2UgdGhlIGRlY2xhcmVkIHByZWZpeCB3aXRoIHRoZSBzeW50YXggZGVzY3JpYmVkIGluIDxsaW5rIGFuY2hvcj0iZXh0LWZ1bmMtY2FsbHMiPkV4dGVuc2lvbiBmdW5jdGlvbiBKYXZhIGNhbGxzPC9saW5rPi48L3A+Ci08cD5UaGF0IGlzIGFsbC4gWW91IGRvIG5vdCBpbmNsdWRlIGFuIGx4c2x0OmNvbXBvbmVudCBlbGVtZW50LiBVc2luZyB0aGUgYWJicmV2aWF0ZWQgc3ludGF4IGNsZWFybHkgaW52b2x2ZXMgbGVzcyBzZXR1cCB0aGFuIHVzaW5nIHRoZSBseHNsdDpjb21wb25lbnQvbHhzbHQ6c2NyaXB0IGFwcHJvYWNoLjwvcD4KLTxub3RlPldlIHJlY29tbWVuZCB0aGF0LCBmb3IgZXh0ZW5zaW9ucyBjb2RlZCBpbiBKYXZhLCB0aGUgYWJicmV2aWF0ZWQgc3ludGF4IHNob3VsZCBhbHdheXMgYmUgdXNlZCBzaW5jZSB0aGUgbHhzbHQ6Y29tcG9uZW50L2x4c2x0OnNjcmlwdCBjb25zdHJ1Y3RzIGFkZCBubyBmdW5jdGlvbmFsaXR5Ljwvbm90ZT4KLTwvczM+PGFuY2hvciBuYW1lPSJleC1qYXZhLW5hbWVzcGFjZSIvPiAKLTxzMyB0aXRsZT0iRXhhbXBsZTogRm9ybWF0dGluZyBhIGRhdGUiPgotPHA+VGhpcyBleGFtcGxlIHVzZXMgZXh0ZW5zaW9uIGZ1bmN0aW9ucyB0byBjYWxsIHRoZSBTaW1wbGVEYXRlRm9ybWF0IGNsYXNzIGFuZCB0aGUgSW50RGF0ZSBjbGFzcy4gSW50RGF0ZSB1c2VzIFN0cmluZyBhcmd1bWVudHMgdG8gc2V0IHVwIGEgRGF0ZSBvYmplY3Q6PC9wPgotPHNvdXJjZT5pbXBvcnQgamF2YS51dGlsLkRhdGU7Ci1pbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOwotCi1wdWJsaWMgY2xhc3MgSW50RGF0ZQotewotICBwdWJsaWMgc3RhdGljIERhdGUgZ2V0RGF0ZShTdHJpbmcgeWVhciwgU3RyaW5nIG1vbnRoLCBTdHJpbmcgZGF5KQotICAgIHsKLSAgICAgIC8vIERhdGUoaW50LCBpbnQsIGludCkgaGFzIGJlZW4gZGVwcmVjYXRlZCwgc28gdXNlIENhbGVuZGFyIHRvCi0gICAgICAvLyBzZXQgdGhlIHllYXIsIG1vbnRoLCBhbmQgZGF5LgotICAgICAgQ2FsZW5kYXIgYyA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7Ci0gICAgICAvLyBDb252ZXJ0IGVhY2ggYXJndW1lbnQgdG8gaW50LgotICAgICAgYy5zZXQgKCBJbnRlZ2VyLnBhcnNlSW50KHllYXIpLAotICAgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KG1vbnRoKSwKLSAgICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludChkYXkpICk7Ci0gICAgICByZXR1cm4gYy5nZXRUaW1lKCk7Ci0gICAgfQotfTwvc291cmNlPgotPHA+VGhlIHRlbXBsYXRlIHRyYW5zZm9ybXMgZGF0ZSBlbGVtZW50cyB3aXRoIGZvdXIgYXR0cmlidXRlcy4gRm9yIGV4YW1wbGUsIGl0IHRyYW5zZm9ybXMgPGNvZGU+Jmx0O2RhdGUgZm9ybWF0PSJFRUVFLCBNTU0gZGQsIHl5eXkiIHllYXI9IjIwMDAiIG1vbnRoPSI0IiBkYXk9IjI3Ii8mZ3Q7PC9jb2RlPiBpbnRvICZsdDtwJmd0O0RhdGU6IFRodXJzZGF5LCBBcHJpbCAyNywgMjAwMC4mbHQ7L3AmZ3Q7LjwvcD4KLTxwPkFzIHlvdSByZXZpZXcgdGhpcyBzdHlsZXNoZWV0LCBwbGVhc2Uga2VlcCB0aGUgZm9sbG93aW5nIGluIG1pbmQ6PC9wPgotIDx1bD4KLSAgPGxpPlRoZSBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBzdHlsZXNoZWV0IGF0dHJpYnV0ZSBwcmV2ZW50cyB0aGUgamF2YSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gZnJvbQotICAgYXBwZWFyaW5nIGluIHRoZSBvdXRwdXQuPC9saT4KLSAgPGxpPlRoZSBYU0xUIHR5cGUgcmV0dXJuZWQgYnkgYW55IExvY2F0aW9uUGF0aCBleHByZXNzaW9uIGlzIG5vZGUtc2V0LCBzbyB0aGUgWFNMVCBzdHJpbmcKLSAgICBmdW5jdGlvbiBpcyB1c2VkIHRvIGNvbnZlcnQgdGhlIGZvcm1hdCwgeWVhciwgbW9udGgsIGFuZCBkYXkgYXR0cmlidXRlIHZhbHVlcyBmcm9tIG5vZGUtc2V0cyB0bwotICAgIHN0cmluZ3MuPC9saT4KLSAgPGxpPlRoZSBmb3JtYXQgYXR0cmlidXRlIHByb3ZpZGVzIGEgU3RyaW5nIGFyZ3VtZW50IGZvciBjb25zdHJ1Y3RpbmcgYSBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdAotICAgIG9iamVjdC48L2xpPgotICAgIDxsaT5UaGUgSW50RGF0ZSBjbGFzcyB1c2VzIFN0cmluZyB2YWx1ZXMgcHJvdmlkZWQgYnkgdGhlIHllYXIsIG1vbnRoLCBhbmQgZGF5IGF0dHJpYnV0ZXMsIHRvIHNldCB0aGUKLSAgICBkYXRlLiBYU0xUIGNhbiBwYXNzIG51bWJlciB2YWx1ZXMsIGJ1dCB0aGVzZSBhcmUgY29udmVydGVkIGludG8gZG91Ymxlcy48L2xpPgotICA8bGk+VGhlIGZvcm1hdHRlciB2YXJpYWJsZSBob2xkcyBhIFNpbXBsZURhdGVGb3JtYXQgb2JqZWN0LCBhbmQgdGhlIGRhdGUgdmFyaWFibGUgaG9sZHMgYSBEYXRlIG9iamVjdC4KLSAgICBYU0xUIGRvZXMgbm90IHVuZGVyc3RhbmQgZWl0aGVyIG9mIHRoZXNlIHR5cGVzLCBidXQgdGhleSBhcmUgdXNlZCB0byBjYWxsIHRoZSBTaW1wbGVEYXRlRm9ybWF0IGZvcm1hdAotICAgICBtZXRob2QuIEluIHRoYXQgY2FsbCwgJGZvcm1hdHRlciBpcyB0aGUgb2JqZWN0LCBhbmQgJGRhdGUgaXMgdGhlIGFyZ3VtZW50LiBUaGUgc3ludGF4IGZvciBjYWxsaW5nCi0gICAgIEphdmEgY29uc3RydWN0b3JzIGFuZCBtZXRob2RzIGlzIGRlc2NyaWJlZCBhYm92ZSBpbiA8bGluayBhbmNob3I9ImV4dC1mdW5jLWNhbGxzIj5FeHRlbnNpb24gZnVuY3Rpb24gSmF2YSBjYWxsczwvbGluaz4uPC9saT4gICAgCi0gPC91bD48YW5jaG9yIG5hbWU9ImZvcm1hdC1kYXRlLXN0eWxlc2hlZXQiLz4gICAKLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8mZ3Q7Ci0mbHQ7eHNsOnN0eWxlc2hlZXQgCi0gICAgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iIAotICAgIHZlcnNpb249IjEuMCIgICAKLSAgICB4bWxuczpqYXZhPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdC9qYXZhIgotICAgIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzPSJqYXZhIiZndDsKLSAgICAKLSAgJmx0OyEtLU90aGVyIHRlbXBsYXRlcyBmb3IgdHJhbnNmb3JtaW5nIHRoZSByZXN0IG9mCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBYTUwgc291cmNlIGRvY3VtZW50cy0tJmd0OwotICAKLSAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iZGF0ZSImZ3Q7IAotICAgICZsdDt4c2w6dmFyaWFibGUgbmFtZT0ieWVhciIgc2VsZWN0PSJzdHJpbmcoLi9AeWVhcikiLyZndDsKLSAgICAmbHQ7eHNsOnZhcmlhYmxlIG5hbWU9Im1vbnRoIiBzZWxlY3Q9InN0cmluZyguL0Btb250aCkiLyZndDsgCi0gICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJkYXkiIHNlbGVjdD0ic3RyaW5nKC4vQGRheSkiLyZndDsgICAgICAgICAgCi0gICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJmb3JtYXQiIHNlbGVjdD0ic3RyaW5nKC4vQGZvcm1hdCkiLyZndDsKLQotICAgICZsdDt4c2w6dmFyaWFibGUgbmFtZT0iZm9ybWF0dGVyIiAgICAgICAKLSAgICAgICAgc2VsZWN0PSJqYXZhOmphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0Lm5ldygkZm9ybWF0KSIvJmd0OwotCi0gICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJkYXRlIiAKLSAgICAgICAgc2VsZWN0PSJqYXZhOkludERhdGUuZ2V0RGF0ZSgkeWVhciwgJG1vbnRoLCAkZGF5KSIvJmd0OwotCi0gICAgJmx0O3AmZ3Q7RGF0ZTogJmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9ImphdmE6Zm9ybWF0KCRmb3JtYXR0ZXIsICRkYXRlKSIvJmd0OyZsdDsvcCZndDsKLSAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OyAgCi08L3NvdXJjZT4KLTwvczM+Ci08L3MyPgotPHMyIHRpdGxlPSJFeGFtcGxlczogdXNpbmcgSmF2YSBhbmQgSmF2YVNjcmlwdCB0byBpbXBsZW1lbnQgdGhlIHNhbWUgZXh0ZW5zaW9uIj4KLTxwPlRoaXMgc2VjdGlvbiBjb250YWlucyB0d28gZXhhbXBsZXMuIFRoZSBmaXJzdCBleGFtcGxlIHVzZXMgYSBKYXZhIGV4dGVuc2lvbiB0byB0cmFuc2Zvcm0gYSBzZXQgb2YgbmFtZSBlbGVtZW50cyAgaW50byBhbiBhbHBoYWJldGljYWwgYW5kIG51bWJlcmVkIGxpc3QuIFRoZSBzZWNvbmQgZXhhbXBsZSB1c2VzIGEgSmF2YVNjcmlwdCBzY3JpcHQgdG8gZG8gdGhlIHNhbWUuIEJvdGggZXhhbXBsZXMgaW5jbHVkZSBlcXVpdmFsZW50IGV4dGVuc2lvbiBlbGVtZW50cyBhbmQgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uLjwvcD4KLTxhbmNob3IgbmFtZT0iZXgtamF2YSIvPiAKLTxzMyB0aXRsZT0iSmF2YSBpbXBsZW1lbnRhdGlvbiI+Ci08cD5NeUNvdW50ZXIuamF2YTwvcD4KLTxzb3VyY2U+SW1wb3J0IGphdmEudXRpbC4qOwotCi1wdWJsaWMgY2xhc3MgTXlDb3VudGVyIHsKLSAgSGFzaHRhYmxlIGNvdW50ZXJzID0gbmV3IEhhc2h0YWJsZSAoKTsKLQotICBwdWJsaWMgTXlDb3VudGVyICgpIAotICB7fQotCi0gIHB1YmxpYyB2b2lkIGluaXQKLSAgICAgICAgICAgICAoIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9ucy5YU0xQcm9jZXNzb3JDb250ZXh0IGNvbnRleHQsCi0gICAgICAgICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5FbGVtRXh0ZW5zaW9uQ2FsbCBleHRFbGVtICkgCi0gIHsKLSAgICBTdHJpbmcgbmFtZSA9IGV4dEVsZW0uZ2V0QXR0cmlidXRlKCJuYW1lIik7Ci0gICAgU3RyaW5nIHZhbHVlID0gZXh0RWxlbS5nZXRBdHRyaWJ1dGUoInZhbHVlIik7Ci0gICAgaW50IHZhbDsKLSAgICB0cnkgCi0gICAgewotICAgICAgdmFsID0gSW50ZWdlci5wYXJzZUludCAodmFsdWUpOwotICAgIH0gCi0gICAgY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSAKLSAgICB7Ci0gICAgICBlLnByaW50U3RhY2tUcmFjZSAoKTsKLSAgICAgIHZhbCA9IDA7Ci0gICAgfQotICAgIGNvdW50ZXJzLnB1dCAobmFtZSwgbmV3IEludGVnZXIgKHZhbCkpOwotICB9Ci0KLSAgcHVibGljIGludCByZWFkKFN0cmluZyBuYW1lKSAKLSAgewotICAgIEludGVnZXIgY3ZhbCA9IChJbnRlZ2VyKSBjb3VudGVycy5nZXQgKG5hbWUpOwotICAgIHJldHVybiAoY3ZhbCA9PSBudWxsKSA/IDAgOiBjdmFsLmludFZhbHVlICgpOwotICB9Ci0KLSAgcHVibGljIHZvaWQgaW5jcgotICAgICAgICAgICAgICggb3JnLmFwYWNoZS54YWxhbi5leHRlbnNpb25zLlhTTFByb2Nlc3NvckNvbnRleHQgY29udGV4dCwKLSAgICAgICAgICAgICAgIG9yZy5hcGFjaGUueGFsYW4udGVtcGxhdGVzLkVsZW1FeHRlbnNpb25DYWxsIGV4dEVsZW0pIAotICB7Ci0gICAgU3RyaW5nIG5hbWUgPSBleHRFbGVtLmdldEF0dHJpYnV0ZSgibmFtZSIpOwotICAgIEludGVnZXIgY3ZhbCA9IChJbnRlZ2VyKSBjb3VudGVycy5nZXQobmFtZSk7Ci0gICAgaW50IG52YWwgPSAoY3ZhbCA9PSBudWxsKSA/IDAgOiAoY3ZhbC5pbnRWYWx1ZSAoKSArIDEpOwotICAgIGNvdW50ZXJzLnB1dCAobmFtZSwgbmV3IEludGVnZXIgKG52YWwpKTsKLSAgfQotfQotPC9zb3VyY2U+Ci08cD5BbiBYTUwgc291cmNlIGRvY3VtZW50OjwvcD4KLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8mZ3Q7Ci0mbHQ7ZG9jJmd0OwotICAmbHQ7bmFtZSBmaXJzdD0iRGF2aWQiIGxhc3Q9Ik1hcnN0b24iLyZndDsKLSAgJmx0O25hbWUgZmlyc3Q9IkRhdmlkIiBsYXN0PSJCZXJ0b25pIi8mZ3Q7Ci0gICZsdDtuYW1lIGZpcnN0PSJEb25hbGQiIGxhc3Q9Ikxlc2xpZSIvJmd0OwotICAmbHQ7bmFtZSBmaXJzdD0iRW1pbHkiIGxhc3Q9IkZhcm1lciIvJmd0OwotICAmbHQ7bmFtZSBmaXJzdD0iSmFjayIgbGFzdD0iRG9ub2h1ZSIvJmd0OwotICAmbHQ7bmFtZSBmaXJzdD0iTXlyaWFtIiBsYXN0PSJNaWR5Ii8mZ3Q7Ci0gICZsdDtuYW1lIGZpcnN0PSJQYXVsIiBsYXN0PSJEaWNrIi8mZ3Q7Ci0gICZsdDtuYW1lIGZpcnN0PSJSb2JlcnQiIGxhc3Q9IldlaXIiLyZndDsKLSAgJmx0O25hbWUgZmlyc3Q9IlNjb3R0IiBsYXN0PSJCb2FnIi8mZ3Q7Ci0gICZsdDtuYW1lIGZpcnN0PSJTaGFuZSIgbGFzdD0iQ3VyY3VydSIvJmd0OwotJmx0Oy9kb2MmZ3Q7PC9zb3VyY2U+Ci08cD5UaGUgc3R5bGVzaGVldDo8L3A+Ci08c291cmNlPiZsdDs/eG1sIHZlcnNpb249IjEuMCI/Jmd0OyAKLSZsdDt4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB4bWxuczpseHNsdD0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiCi0gICAgICAgICAgICAgICAgeG1sbnM6Y291bnRlcj0iTXlDb3VudGVyIgotICAgICAgICAgICAgICAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJjb3VudGVyIgotICAgICAgICAgICAgICAgIHZlcnNpb249IjEuMCImZ3Q7Ci0KLSAgJmx0O2x4c2x0OmNvbXBvbmVudCBwcmVmaXg9ImNvdW50ZXIiCi0gICAgICAgICAgICAgICAgICAgZWxlbWVudHM9ImluaXQgaW5jciIgZnVuY3Rpb25zPSJyZWFkIiZndDsKLSAgICAmbHQ7bHhzbHQ6c2NyaXB0IGxhbmc9ImphdmFjbGFzcyIgc3JjPSJ4YWxhbjovL015Q291bnRlciIvJmd0OwotICAmbHQ7L2x4c2x0OmNvbXBvbmVudCZndDsKLQotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIiZndDsKLSAgICAmbHQ7SFRNTCZndDsKLSAgICAgICZsdDtIMSZndDtOYW1lcyBpbiBhbHBoYWJldGljYWwgb3JkZXImbHQ7L0gxJmd0OwotICAgICAgJmx0O2NvdW50ZXI6aW5pdCBuYW1lPSJpbmRleCIgdmFsdWU9IjEiLyZndDsKLSAgICAgICZsdDt4c2w6Zm9yLWVhY2ggc2VsZWN0PSJkb2MvbmFtZSImZ3Q7Ci0gICAgICAgICZsdDt4c2w6c29ydCBzZWxlY3Q9IkBsYXN0Ii8mZ3Q7Ci0gICAgICAgICZsdDt4c2w6c29ydCBzZWxlY3Q9IkBmaXJzdCIvJmd0OwotICAgICAgICAmbHQ7cCZndDsKLSAgICAgICAgJmx0O3hzbDp0ZXh0Jmd0O1smbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgICAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0iY291bnRlcjpyZWFkKCdpbmRleCcpIi8mZ3Q7Ci0gICAgICAgICZsdDt4c2w6dGV4dCZndDtdLiAmbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgICAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGxhc3QiLyZndDsKLSAgICAgICAgJmx0O3hzbDp0ZXh0Jmd0OywgJmx0Oy94c2w6dGV4dCZndDsKLSAgICAgICAgJmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBmaXJzdCIvJmd0OwotICAgICAgICAmbHQ7L3AmZ3Q7Ci0gICAgICAgICZsdDtjb3VudGVyOmluY3IgbmFtZT0iaW5kZXgiLyZndDsKLSAgICAgICZsdDsveHNsOmZvci1lYWNoJmd0OwotICAgICZsdDsvSFRNTCZndDsKLSAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0gCi0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotPC9zb3VyY2U+Ci08cD5UcmFuc2Zvcm1hdGlvbiBvdXRwdXQ6PC9wPgotPHNvdXJjZT4mbHQ7SFRNTCZndDsKLSZsdDtIMSZndDtOYW1lcyBpbiBhbHBoYWJldGljYWwgb3JkZXImbHQ7L0gxJmd0OwotJmx0O3AmZ3Q7WzFdLiBCZXJ0b25pLCBEYXZpZCZsdDsvcCZndDsKLSZsdDtwJmd0O1syXS4gQm9hZywgU2NvdHQmbHQ7L3AmZ3Q7Ci0mbHQ7cCZndDtbM10uIEN1cmN1cnUsIFNoYW5lJmx0Oy9wJmd0OwotJmx0O3AmZ3Q7WzRdLiBEaWNrLCBQYXVsJmx0Oy9wJmd0OwotJmx0O3AmZ3Q7WzVdLiBEb25vaHVlLCBKYWNrJmx0Oy9wJmd0OwotJmx0O3AmZ3Q7WzZdLiBGYXJtZXIsIEVtaWx5Jmx0Oy9wJmd0OwotJmx0O3AmZ3Q7WzddLiBMZXNsaWUsIERvbmFsZCZsdDsvcCZndDsKLSZsdDtwJmd0O1s4XS4gTWFyc3RvbiwgRGF2aWQmbHQ7L3AmZ3Q7Ci0mbHQ7cCZndDtbOV0uIE1pZHksIE15cmlhbSZsdDsvcCZndDsKLSZsdDtwJmd0O1sxMF0uIFdlaXIsIFJvYmVydCZsdDsvcCZndDsKLSZsdDsvSFRNTCZndDs8L3NvdXJjZT4KLTwvczM+PGFuY2hvciBuYW1lPSJleC1qYXZhc2NyaXB0Ii8+IAotPHMzIHRpdGxlPSJKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIj4KLTxwPjwvcD4KLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8mZ3Q7IAotJmx0O3hzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICAgICAgICAgICAgIHhtbG5zOmx4c2x0PSJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdCIKLSAgICAgICAgICAgICAgICB4bWxuczpjb3VudGVyPSJNeUNvdW50ZXIiCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9ImNvdW50ZXIiCi0gICAgICAgICAgICAgICAgdmVyc2lvbj0iMS4wIiZndDsKLQotICAmbHQ7bHhzbHQ6Y29tcG9uZW50IHByZWZpeD0iY291bnRlciIKLSAgICAgICAgICAgICAgICAgICBlbGVtZW50cz0iaW5pdCBpbmNyIiBmdW5jdGlvbnM9InJlYWQiJmd0OwotICAgICZsdDtseHNsdDpzY3JpcHQgbGFuZz0iamF2YXNjcmlwdCImZ3Q7Ci0gICAgICB2YXIgY291bnRlcnMgPSBuZXcgQXJyYXkoKTsKLQotICAgICAgZnVuY3Rpb24gaW5pdCAoeHNscHJvYywgZWxlbSkgewotICAgICAgICBuYW1lID0gZWxlbS5nZXRBdHRyaWJ1dGUgKCJuYW1lIik7Ci0gICAgICAgIHZhbHVlID0gcGFyc2VJbnQoZWxlbS5nZXRBdHRyaWJ1dGUgKCJ2YWx1ZSIpKTsKLSAgICAgICAgY291bnRlcnNbbmFtZV0gPSB2YWx1ZTsKLSAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICB9Ci0KLSAgICAgIGZ1bmN0aW9uIHJlYWQgKG5hbWUpIHsKLSAgICAgICAgLy8gUmV0dXJuIGEgc3RyaW5nLgotICAgICAgICByZXR1cm4gIiIgKyAoY291bnRlcnNbbmFtZV0pOwotICAgICAgfQotCi0gICAgICBmdW5jdGlvbiBpbmNyICh4c2xwcm9jLCBlbGVtKQotICAgICAgewotICAgICAgICBuYW1lID0gZWxlbS5nZXRBdHRyaWJ1dGUgKCJuYW1lIik7Ci0gICAgICAgIGNvdW50ZXJzW25hbWVdKys7Ci0gICAgICAgIHJldHVybiBudWxsOwotICAgICAgfQotICAgICZsdDsvbHhzbHQ6c2NyaXB0Jmd0OwotICAmbHQ7L2x4c2x0OmNvbXBvbmVudCZndDsKLQotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIiZndDsKLSAgICAmbHQ7SFRNTCZndDsKLSAgICAgICZsdDtIMSZndDtOYW1lcyBpbiBhbHBoYXRlYmljYWwgb3JkZXImbHQ7L0gxJmd0OwotICAgICAgJmx0O2NvdW50ZXI6aW5pdCBuYW1lPSJpbmRleCIgdmFsdWU9IjEiLyZndDsKLSAgICAgICZsdDt4c2w6Zm9yLWVhY2ggc2VsZWN0PSJkb2MvbmFtZSImZ3Q7Ci0gICAgICAgICZsdDt4c2w6c29ydCBzZWxlY3Q9IkBsYXN0Ii8mZ3Q7Ci0gICAgICAgICZsdDt4c2w6c29ydCBzZWxlY3Q9IkBmaXJzdCIvJmd0OwotICAgICAgICAmbHQ7cCZndDsKLSAgICAgICAgJmx0O3hzbDp0ZXh0Jmd0O1smbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgICAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0iY291bnRlcjpyZWFkKCdpbmRleCcpIi8mZ3Q7Ci0gICAgICAgICZsdDt4c2w6dGV4dCZndDtdLiAmbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgICAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGxhc3QiLyZndDsKLSAgICAgICAgJmx0O3hzbDp0ZXh0Jmd0OywgJmx0Oy94c2w6dGV4dCZndDsKLSAgICAgICAgJmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBmaXJzdCIvJmd0OwotICAgICAgICAmbHQ7L3AmZ3Q7Ci0gICAgICAgICZsdDtjb3VudGVyOmluY3IgbmFtZT0iaW5kZXgiLyZndDsKLSAgICAgICZsdDsveHNsOmZvci1lYWNoJmd0OwotICAgICZsdDsvSFRNTCZndDsKLSAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0gCi0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotPC9zb3VyY2U+Ci08cD5UaGlzIHN0eWxlc2hlZXQgcHJvZHVjZXMgdGhlIHNhbWUgb3V0cHV0IGFzIHRoZSBwcmVjZWRpbmcgZXhhbXBsZSB3aXRoIHRoZSBKYXZhIGV4dGVuc2lvbi48L3A+Ci08L3MzPgotPC9zMj4KLTwvczE+CmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuL2V4dGVuc2lvbnNsaWIueG1sIGIveGRvY3Mvc291cmNlcy94YWxhbi9leHRlbnNpb25zbGliLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzk4YmM0NC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL2V4dGVuc2lvbnNsaWIueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNDg5ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4gCi08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLTwhLS0gCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotIC0tPgotPHMxIHRpdGxlPSJFeHRlbnNpb25zIGxpYnJhcnkiPgotPHVsPgotPGxpPjxsaW5rIGFuY2hvcj0iaW50cm8iPkludHJvZHVjdGlvbjwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0ieGFsYW5ucyI+WGFsYW4gbmFtZXNwYWNlPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJyZWRpcmVjdCI+UmVkaXJlY3Q8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Im5vZGVzZXQiPm5vZGVzZXQ8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImludGVyc2VjdGlvbiI+aW50ZXJzZWN0aW9uPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJkaWZmZXJlbmNlIj5kaWZmZXJlbmNlPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJkaXN0aW5jdCI+ZGlzdGluY3Q8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Imhhc3NhbWVub2RlcyI+aGFzU2FtZU5vZGVzPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJzcWwiPlNRTCBsaWJyYXJ5PC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJwaXBlZG9jdW1lbnQiPlBpcGVEb2N1bWVudDwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iZXZhbHVhdGUiPmV2YWx1YXRlPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJ0b2tlbml6ZSI+dG9rZW5pemU8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Imdyb3VwaXRlbSI+Z3JvdXAgYW5kIGl0ZW08L2xpbms+IDxyZWY+KHRvIGJlIGRvbmUpPC9yZWY+PC9saT4KLTxsaT48bGluayBhbmNob3I9InR5cGUiPnR5cGU8L2xpbms+IDxyZWY+KHRvIGJlIGRvbmUpPC9yZWY+PC9saT4KLTxsaT48bGluayBhbmNob3I9InRvZGF0ZSI+dG9EYXRlPC9saW5rPiA8cmVmPih0byBiZSBkb25lKTwvcmVmPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJmb3JtYXRkYXRlIj5mb3JtYXREYXRlPC9saW5rPiA8cmVmPih0byBiZSBkb25lKTwvcmVmPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJncmVwIj5ncmVwPC9saW5rPiA8cmVmPih0byBiZSBkb25lKTwvcmVmPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJmb3JlYWNodG9rZW4iPmZvckVhY2hUb2tlbjwvbGluaz4gPHJlZj4odG8gYmUgZG9uZSk8L3JlZj48L2xpPgotPGxpPkV4YW1wbGVzOiA8bGluayBhbmNob3I9ImV4LXJlZGlyZWN0Ij5SZWRpcmVjdDwvbGluaz4sIDxsaW5rIGFuY2hvcj0iZXgtbm9kZXNldCI+bm9kZXNldDwvbGluaz4sIDxsaW5rIGFuY2hvcj0iZXgtc3FsIj5TUUwgbGlicmFyeTwvbGluaz48L2xpPgotPC91bD48YW5jaG9yIG5hbWU9ImludHJvIi8+Ci08czIgdGl0bGU9ICJJbnRyb2R1Y3Rpb24iPgotPHA+RXh0ZW5zaW9uIGVsZW1lbnRzIGFuZCBmdW5jdGlvbnMgcHJvdmlkZSBhIHBvd2VyZnVsIG1lY2hhbmlzbQotZm9yIGV4dGVuZGluZyBhbmQgc2ltcGxpZnlpbmcgd2hhdCB5b3UgY2FuIGRvIHdpdGggYW4gWExTVCBwcm9jZXNzb3IgbGlrZQotWGFsYW4uIFdpdGggaW5wdXQgYW5kIGNvbnRyaWJ1dGlvbnMgZnJvbSB0aGUgWE1MIG9wZW4tc291cmNlIGRldmVsb3BlciBjb21tdW5pdHksIHdlIGFyZSB3b3JraW5nIG9uIHBsYWNpbmcgdGhlIG1vc3QgdXNlZnVsCi1leHRlbnNpb25zIGluIGFuIGV4dGVuc2lvbnMgbGlicmFyeSBkaXN0cmlidXRlZCB3aXRoICZ4c2x0NGo7LiBJZiB5b3UgaGF2ZSBpZGVhcyBhbmQvb3IgY29udHJpYnV0aW9ucyB5b3Ugd291bGQgbGlrZSB0byBtYWtlLCBwbGVhc2UgZW1haWwgdXMgYXQgdGhlIDxodW1hbi1yZXNvdXJjZS1yZWYgaWRyZWY9InhhbGFuZGV2Ii8+LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJ4YWxhbm5zIi8+Ci08czIgdGl0bGU9IlhhbGFuIG5hbWVzcGFjZSI+Ci08cD5XaGVyZSBpdCBtYWtlcyBzZW5zZSwgd2UgYXJlIHBsYWNpbmcgdGhlIG5ldyBYYWxhbiBleHRlbnNpb25zIGluIHRoZSBvcmcuYXBhY2hlLnhhbGFuLmxpYi5FeHRlbnNpb25zIGNsYXNzIGFuZCB3ZSBoYXZlIGRlZmluZWQgYSBuYW1lc3BhY2UgZm9yIHRoaXMgY2xhc3M6PC9wPgotPHA+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PGNvZGU+aHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuPC9jb2RlPjwvcD4KLTxwPklmIHlvdSBhcmUgY2FsbGluZyAmeHNsdDRqOy1zdXBwbGllZCBleHRlbnNpb25zLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgZGVmaW5lIHRoaXMgbmFtZXNwYWNlIGluIHlvdXIgc3R5bGVzaGVldCBlbGVtZW50LCBhbmQgY2FsbCB0aGUgZXh0ZW5zaW9uIHVzaW5nIHRoZSBuYW1lc3BhY2UgcHJlZml4IHRoYXQgeW91IGhhdmUgYXNzb2NpYXRlZCB3aXRoIHRoYXQgbmFtZXNwYWNlLiBUaGF0IHdheSwgaWYgd2UgbGF0ZXIgcmVvcmdhbml6ZSBob3cgdGhlICZ4c2x0NGo7LXN1cHBsaWVkIGV4dGVuc2lvbnMgYXJlIHN0b3JlZCwgeW91IHdvbid0IGhhdmUgdG8gbW9kaWZ5IHlvdXIgc3R5bGVzaGVldC48L3A+Ci08cD5Gb3IgYW4gZXhhbXBsZSB0aGF0IHVzZXMgdGhpcyBuYW1lc3BhY2UsIHNlZSA8bGluayBhbmNob3I9ImV4LW5vZGVzZXQiPkV4YW1wbGUgd2l0aCB0aGUgbm9kZXNldCBleHRlbnNpb24gZnVuY3Rpb248L2xpbms+LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJyZWRpcmVjdCIvPgotPHMyIHRpdGxlPSAiUmVkaXJlY3QiPgotPHA+QSBzdGFuZGFyZCBYU0wgdHJhbnNmb3JtYXRpb24gaW52b2x2ZXMgYW4gWFNMIHN0eWxlc2hlZXQsIGFuIFhNTCBzb3VyY2UgdHJlZSwgYW5kIHRoZSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQgdHJlZS4gVGhlIHRyYW5zZm9ybWF0aW9uIHNlbmRzIHRoZSBlbnRpcmUgcmVzdWx0IHRvIGEgc2luZ2xlIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS90cmF4L1Jlc3VsdC5odG1sIj5vcmcuYXBhY2hlLnRyYXguUmVzdWx0PC9qdW1wPiBvYmplY3QuPC9wPiAKLTxwPlRoZSBSZWRpcmVjdCBleHRlbnNpb24gCi0oPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQvZXh0ZW5zaW9ucy9SZWRpcmVjdC5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLnhzbHQuZXh0ZW5zaW9ucy5SZWRpcmVjdDwvanVtcD4pIHN1cHBsaWVzIHRocmVlIGV4dGVuc2lvbiBlbGVtZW50cyB0aGF0IHlvdSBjYW4gdXNlIHRvIHJlZGlyZWN0IHBvcnRpb25zIG9mIHlvdXIgdHJhbnNmb3JtYXRpb24gb3V0cHV0IHRvIG11bHRpcGxlIGZpbGVzOiAmbHQ7b3BlbiZndDssICZsdDt3cml0ZSZndDssIGFuZCAmbHQ7Y2xvc2UmZ3Q7LiBJZiB5b3UgdXNlIHRoZSAmbHQ7d3JpdGUmZ3Q7IGVsZW1lbnQgYWxvbmUsIHRoZSBleHRlbnNpb24gb3BlbnMgYSBmaWxlLCB3cml0ZXMgdG8gaXQsIGFuZCBjbG9zZXMgdGhlIGZpbGUgaW1tZWRpYXRlbHkuIElmIHlvdSB3YW50IGV4cGxpY2l0IGNvbnRyb2wgb3ZlciB0aGUgb3BlbmluZyBhbmQgY2xvc2luZyBvZiBmaWxlcywgdXNlICZsdDt3cml0ZSZndDsgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgJmx0O29wZW4mZ3Q7IGFuZCAmbHQ7Y2xvc2UmZ3Q7IGVsZW1lbnRzLjwvcD4KLTxwPkVhY2ggb2YgdGhlc2UgZWxlbWVudHMgaW5jbHVkZXMgYSBmaWxlIGF0dHJpYnV0ZSBhbmQvb3IgYSBzZWxlY3QgYXR0cmlidXRlIHRvIGRlc2lnbmF0ZSB0aGUgb3V0cHV0IGZpbGUuIFRoZSBmaWxlIGF0dHJpYnV0ZSB0YWtlcyBhIHN0cmluZywgc28geW91IGNhbiB1c2UgaXQgdG8gZGlyZWN0bHkgc3BlY2lmeSB0aGUgb3V0cHV0IGZpbGUgbmFtZS4gVGhlIHNlbGVjdCBhdHRyaWJ1dGUgdGFrZXMgYW4gWFBhdGggZXhwcmVzc2lvbiwgc28geW91IGNhbiB1c2UgaXQgdG8gZHluYW1pY2FsbHkgZ2VuZXJhdGUgdGhlIG91dHB1dCBmaWxlIG5hbWUuIElmIHlvdSBpbmNsdWRlIGJvdGggYXR0cmlidXRlcywgdGhlIFJlZGlyZWN0IGV4dGVuc2lvbiBmaXJzdCBldmFsdWF0ZXMgdGhlIHNlbGVjdCBhdHRyaWJ1dGUsIGFuZCBmYWxscyBiYWNrIHRvIHRoZSBmaWxlIGF0dHJpYnV0ZSBpZiB0aGUgc2VsZWN0IGF0dHJpYnV0ZSBleHByZXNzaW9uIGRvZXMgbm90IHJldHVybiBhIHZhbGlkIGZpbGUgbmFtZS48L3A+Ci08YW5jaG9yIG5hbWU9ImV4LXJlZGlyZWN0Ii8+IAotPHMzIHRpdGxlPSJFeGFtcGxlIHdpdGggdGhlIFJlZGlyZWN0IGV4dGVuc2lvbiI+Ci08cD5TdXBwb3NlIHlvdSBhcmUgb3V0cHV0dGluZyB0aGUgYnVsayBvZiB5b3VyIHJlc3VsdCB0cmVlIHRvIG9uZSBmaWxlLCBidXQgeW91IHdhbnQgdG8gb3V0cHV0IHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBhbGwgJmx0O2ZvbyZndDsgZWxlbWVudHMgYW5kIHRoZWlyIGNoaWxkcmVuIHRvIGFub3RoZXIgZmlsZS4gVGhlIGZvbGxvd2luZyBleGFtcGxlIGlsbHVzdHJhdGVzIHRoZSBiYXNpYyBzdHJ1Y3R1cmUgb2YgdGhlIFhNTCBzb3VyY2U6PC9wPgotPHNvdXJjZT4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsgCi0mbHQ7ZG9jJmd0OwotICAmbHQ7Zm9vIGZpbGU9ImZvby5vdXQiJmd0OwotICAgIFRlc3RpbmcgUmVkaXJlY3QgZXh0ZW5zaW9uOgotICAgICAgJmx0O2JhciZndDtBIGZvbyBzdWJlbGVtZW50IHRleHQgbm9kZSZsdDsvYmFyJmd0OwotICAmbHQ7L2ZvbyZndDsKLSAgJmx0O21haW4mZ3Q7Ci0gICAgRXZlcnl0aGluZyBlbHNlCi0gICZsdDsvbWFpbiZndDsgIAotJmx0Oy9kb2MmZ3Q7PC9zb3VyY2U+Ci08cD5UaGlzIHN0eWxlc2hlZXQgcmVkaXJlY3RzIHBhcnQgb2YgdGhlIG91dHB1dCB0byBhIHNlY29uZGFyeSBmaWxlOjwvcD4KLTxzb3VyY2U+Ci0mbHQ7eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICAgdmVyc2lvbj0iMS4wIgotICAgIHhtbG5zOmx4c2x0PSJodHRwOi8veG1sLmFwYWNoZS5vcmcveHNsdCIKLSAgICB4bWxuczpyZWRpcmVjdD0ib3JnLmFwYWNoZS54YWxhbi54c2x0LmV4dGVuc2lvbnMuUmVkaXJlY3QiCi0gICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InJlZGlyZWN0IiZndDsKLQotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIiZndDsKLSAgICAmbHQ7c3RhbmRhcmQtb3V0Jmd0OwotICAgICAgU3RhbmRhcmQgb3V0cHV0OgotICAgICAgJmx0O3hzbDphcHBseS10ZW1wbGF0ZXMvJmd0OwotICAgICZsdDsvc3RhbmRhcmQtb3V0Jmd0OwotICAmbHQ7L3hzbDp0ZW1wbGF0ZSZndDsKLSAgCi0gICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9Im1haW4iJmd0OwotICAgICZsdDttYWluJmd0OwotICAgICAgJmx0O3hzbDphcHBseS10ZW1wbGF0ZXMvJmd0OwotICAgICZsdDsvbWFpbiZndDsKLSAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0gIAotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvZG9jL2ZvbyImZ3Q7Ci0gICAgJmx0O3JlZGlyZWN0OndyaXRlIHNlbGVjdD0iQGZpbGUiJmd0OwotICAgICAgJmx0O2Zvby1vdXQmZ3Q7Ci0gICAgICAgICZsdDt4c2w6YXBwbHktdGVtcGxhdGVzLyZndDsKLSAgICAgICZsdDsvZm9vLW91dCZndDsKLSAgICAmbHQ7L3JlZGlyZWN0OndyaXRlJmd0OwotICAmbHQ7L3hzbDp0ZW1wbGF0ZSZndDsKLSAgCi0gICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9ImJhciImZ3Q7Ci0gICAgJmx0O2Zvb2Jhci1vdXQmZ3Q7Ci0gICAgICAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcy8mZ3Q7Ci0gICAgJmx0Oy9mb29iYXItb3V0Jmd0OwotICAmbHQ7L3hzbDp0ZW1wbGF0ZSZndDsKLSAgCi0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0Ozwvc291cmNlPgotPHA+VGhlIHN0YW5kYXJkIG91dHB1dCBpczo8L3A+Ci08c291cmNlPiZsdDs/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8mZ3Q7Ci0mbHQ7c3RhbmRhcmQtb3V0Jmd0OwotICBTdGFuZGFyZCBvdXRwdXQ6Ci0gICZsdDttYWluJmd0OwotICAgIEV2ZXJ5dGhpbmcgZWxzZS4KLSAgJmx0Oy9tYWluJmd0OwotJmx0O3N0YW5kYXJkLW91dCZndDs8L3NvdXJjZT4KLTxwPlRoZSBvdXRwdXQgcmVkaXJlY3RlZCB0byBmb28ub3V0IGlzOjwvcD4KLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPyZndDsKLSZsdDtmb28tb3V0Jmd0OwotICAgIFRlc3RpbmcgUmVkaXJlY3QgZXh0ZW5zaW9uOgotICAgICZsdDtmb29iYXItb3V0Jmd0O2ZvbyBzdWJlbGVtZW50IHRleHQgbm9kZSZsdDsvZm9vYmFyLW91dCZndDsKLSAgJmx0Oy9mb28tb3V0Jmd0Ozwvc291cmNlPgotPHA+Rm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdXNpbmcgdGhlIFJlZGlyZWN0IGV4dGVuc2lvbiB0byBzZW5kIG91dHB1dCB0byBtdWx0aXBsZSBmaWxlcywgZXhhbWluZSB0aGUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0iZXh0MSI+U2ltcGxlUmVkaXJlY3Q8L2xpbms+IHNhbXBsZSBhbmQgc2VlIHRoZSA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vbGliL1JlZGlyZWN0Lmh0bWwiPlJlZGlyZWN0PC9qdW1wPiBjbGFzcyBKYXZhZG9jLjwvcD4gIAotPC9zMz48L3MyPjxhbmNob3IgbmFtZT0ibm9kZXNldCIvPgotPHMyIHRpdGxlPSAibm9kZXNldCI+Ci08cD5JbXBsZW1lbnRlZCBpbiA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vbGliL0V4dGVuc2lvbnMuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5saWIuRXh0ZW5zaW9uczwvanVtcD4sPGJyLz4KLTxjb2RlPm5vZGVzZXQgKHJlc3VsdC10cmVlLWZyYWdtZW50KTwvY29kZT4gIGNhc3RzIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQgaW50byBhIG5vZGUtc2V0LjwvcD4KLTxub3RlPldoZW4geW91IGJpbmQgYSB2YXJpYWJsZSB0byBhIHRlbXBsYXRlLCByYXRoZXIgdGhhbiB0byB0aGUgdmFsdWUgZ2VuZXJhdGVkIGJ5IGEgc2VsZWN0IGV4cHJlc3Npb24sIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHZhcmlhYmxlIGlzIHJlc3VsdCB0cmVlIGZyYWdtZW50LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1SZXN1bHQtVHJlZS1GcmFnbWVudHMiPlJlc3VsdCBUcmVlIEZyYWdtZW50czwvanVtcD4uPC9ub3RlPgotPGFuY2hvciBuYW1lPSJleC1ub2Rlc2V0Ii8+Ci08czMgdGl0bGU9IkV4YW1wbGUgd2l0aCB0aGUgbm9kZXNldCBleHRlbnNpb24gZnVuY3Rpb24iPgotPHA+VGhlIGZvbGxvd2luZyBzdHlsZXNoZWV0IHVzZXMgdGhlIG5vZGVzZXQgZXh0ZW5zaW9uIGZ1bmN0aW9uIHRvIGNhc3QgYSByZXN1bHQgdHJlZSBmcmFnbWVudCBpbnRvIGEgbm9kZS1zZXQgdGhhdCBjYW4gdGhlbiBiZSBuYXZpZ2F0ZWQgaW4gc3RhbmRhcmQgWFBhdGggbWFubmVyLiBJdCB1c2VzIHRoZSBodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4gbmFtZXNwYWNlIHRvIHByb3ZpZGUgYWNjZXNzIHRvIHRoZSBub2Rlc2V0KCkgbWV0aG9kIGluIHhtbC5hcGFjaGUueGFsYW4ubGliLkV4dGVuc2lvbnMuPC9wPgotPHNvdXJjZT4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLSZsdDt4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgCi0gICAgICAgICAgICAgICAgICAgdmVyc2lvbj0iMS4wIgotICAgICAgICAgICAgICAgICAgIHhtbG5zOnhhbGFuPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4iCi0gICAgICAgICAgICAgICAgICAgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXM9InhhbGFuIiZndDsKLSZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iJmd0OwotICAmbHQ7b3V0Jmd0OwotCSAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJydGYiJmd0OwotICAgICAgJmx0O2RvY2VsZW0mZ3Q7Ci0gICAgICAgICZsdDtlbGVtMSZndDsKLSAgICAgICAgICAmbHQ7ZWxlbTFhJmd0O0VMRU1FTlQxQSZsdDsvZWxlbTFhJmd0OwotICAgICAgICAgICZsdDtlbGVtMWImZ3Q7LEVMRU1FTlQxQiZsdDsvZWxlbTFiJmd0OwotICAgICAgICAmbHQ7L2VsZW0xJmd0OwotICAgICAgICAmbHQ7ZWxlbTImZ3Q7Ci0gICAgICAgICAgJmx0O2VsZW0yYSZndDtFTEVNRU5UMkEmbHQ7L2VsZW0yYSZndDsKLSAgICAgICAgJmx0Oy9lbGVtMiZndDsKLSAgICAgICZsdDsvZG9jZWxlbSZndDsKLSAgICAmbHQ7L3hzbDp2YXJpYWJsZSZndDsgICAgIAotICAgICAgJmx0O3hzbDpmb3ItZWFjaCBzZWxlY3Q9InhhbGFuOm5vZGVzZXQoJHJ0ZikvZG9jZWxlbS8vKiImZ3Q7Ci0gICAgICAgICZsdDt4c2w6dmFsdWUtb2Ygc2VsZWN0PSJuYW1lKC4pIi8mZ3Q7Jmx0O3hzbDp0ZXh0Jmd0OywmbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgJmx0Oy94c2w6Zm9yLWVhY2g+Ci0gICZsdDsvb3V0PgotJmx0Oy94c2w6dGVtcGxhdGU+IAotJmx0Oy94c2w6c3R5bGVzaGVldCZndDs8L3NvdXJjZT4KLTxwPlRoZSBvdXRwdXQgb2YgcnVubmluZyB0aGlzIHN0eWxlc2hlZXQgKHdpdGggYW55IFhNTCBpbnB1dCBzb3VyY2UpIGlzIGEgY29tbWEtZGVsaW1pdGVkIGxpc3Qgb2YgdGhlIGVsZW1lbnQgbmFtZXMgaW4gdGhlIG5vZGUtc2V0PGJyLz4KLSZuYnNwOyZuYnNwOzxjb2RlPiZsdDtvdXQmZ3Q7ZWxlbTEsZWxlbTFhLGVsZW0xYixlbGVtMixlbGVtMmEmbHQ7L291dCZndDs8L2NvZGU+PC9wPgotPG5vdGU+Rm9yIGlsbHVzdHJhdGlvbiBwdXJwb3NlcywgdGhlIHByZWNlZGluZyBzdHlsZXNoZWV0IHBheXMgbm8gYXR0ZW50aW9uIHRvIHRoZSBzdHJ1Y3R1cmUgYW5kIGNvbnRlbnQgb2YgdGhlIFhNTCBpbnB1dCBkb2N1bWVudC4gSW5zdGVhZCwgaXQgcHJvY2Vzc2VzIHRoZSB0ZW1wbGF0ZSAoaW4gdGhlIHN0eWxlc2hlZXQpIGJvdW5kIHRvIHRoZSB2YXJpYWJsZSBuYW1lZCBydGYuPC9ub3RlPgotCi08L3MzPgotPC9zMj48YW5jaG9yIG5hbWU9ImludGVyc2VjdGlvbiIvPgotPHMyIHRpdGxlPSJpbnRlcnNlY3Rpb24iPgotPHA+SW1wbGVtZW50ZWQgaW4gPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9FeHRlbnNpb25zLmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ubGliLkV4dGVuc2lvbnM8L2p1bXA+LDxici8+Ci08Y29kZT5pbnRlcnNlY3Rpb24gKG5vZGUtc2V0MSwgbm9kZS1zZXQyKTwvY29kZT4gIGZ1bmN0aW9uIHJldHVybnMgYSBub2RlLXNldCB3aXRoIGFsbCBub2RlcyB0aGF0IGFyZSBpbiBuczEgYW5kIGluIG5zMiAuPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9ImRpZmZlcmVuY2UiLz4KLTxzMiB0aXRsZT0gImRpZmZlcmVuY2UiPgotPHA+SW1wbGVtZW50ZWQgaW4gPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9FeHRlbnNpb25zLmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ubGliLkV4dGVuc2lvbnM8L2p1bXA+LDxici8+Ci08Y29kZT5kaWZmZXJlbmNlKG5vZGUtc2V0MSwgbm9kZS1zZXQyKTwvY29kZT4gcmV0dXJucyBhIG5vZGUtc2V0IHdpdGggdGhlIG5vZGVzIGluIG5vZGUtc2V0MSBhbmQgbm90IGluIG5vZGUtc2V0Mi48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iZGlzdGluY3QiLz4KLTxzMiB0aXRsZT0gImRpc3RpbmN0Ij4KLSA8cD5JbXBsZW1lbnRlZCBpbiA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vbGliL0V4dGVuc2lvbnMuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5saWIuRXh0ZW5zaW9uczwvanVtcD4sPGJyLz4KLSBkaXN0aW5jdCAobm9kZS1zZXQpIHJldHVybnMgYSBub2RlLXNldCBjb250YWluaW5nIG5vZGVzIHdpdGggZGlzdGluY3Qgc3RyaW5nIHZhbHVlcy4gSWYgbW9yZSB0aGFuIG9uZSBub2RlIGluIHRoZSBub2RlLXNldCAKLSBjb250YWlucyB0aGUgc2FtZSB0ZXh0IG5vZGUgdmFsdWUsIGRpc3RpbmN0IG9ubHkgcmV0dXJucyB0aGUgZmlyc3Qgb2YgdGhlc2Ugbm9kZXMgdGhhdCBpdCBmaW5kcy48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iaGFzc2FtZW5vZGVzIi8+Ci08czIgdGl0bGU9ICJoYXNTYW1lTm9kZXMiPgotPHA+SW1wbGVtZW50ZWQgaW4gPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9FeHRlbnNpb25zLmh0bWwiPm9yZy5hcGFjaGUueGFsYW4ubGliLkV4dGVuc2lvbnM8L2p1bXA+LDxici8+Ci08Y29kZT5oYXNTYW1lTm9kZXMobm9kZS1zZXQxLCBub2RlLXNldDIpPC9jb2RlPiByZXR1cm5zIHRydWUgaWYgYm90aCBub2RlLXNldDEgYW5kIG5vZGUtc2V0MiBjb250YWluIGV4YWN0bHkgdGhlIHNhbWUgc2V0IG9mIG5vZGVzLjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJzcWwiLz4KLTxzMiB0aXRsZT0gIlNRTCBsaWJyYXJ5Ij4KLTxub3RlPkZvciBVTUwgRGlhZ3JhbXMgb2YgdGhlIFNRTCBMaWJyYXJ5LCBzZWUgPGp1bXAgaHJlZj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuLWovWGFsYW4tU1FMLUV4dGVuc2lvbi9EaWFncmFtSW5kZXguaHRtbCI+U1FMIExpYnJhcnkgVU1MIERpYWdyYW1zPC9qdW1wPi48L25vdGU+Ci08dWw+Ci08bGk+PGxpbmsgYW5jaG9yPSJzcWxjb25uIj5TZXR0aW5nIHVwIGEgY29ubmVjdGlvbjwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0ic3FscGFyYW0iPlBhcmFtZXRlcml6ZWQgcXVlcmllczwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iZXgtc3FsIj5TUUwgbGlicmFyeSBleGFtcGxlPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0ic3FsIj5TUUwgbGlicmFyeSBzYW1wbGUgYXBwbGljYXRpb25zPC9saW5rPjwvbGk+Ci08L3VsPgotPHA+PGVtPioqRXhwZXJpbWVudGFsKio8L2VtPiBQcm92aWRlcyBleHRlbnNpb24gZnVuY3Rpb25zIGZvciBjb25uZWN0aW5nIHRvIGEgSkRCQyBkYXRhIHNvdXJjZSwgZXhlY3V0aW5nIGEgcXVlcnksCi1hbmQgb3B0aW9uYWxseSB3b3JraW5nIGluY3JlbWVudGFsbHkgdGhyb3VnaCBhICJzdHJlYW1hYmxlIiByZXN1bHQgc2V0LiA8cmVmPkR1ZSB0byBhIGJ1ZywgY2FjaGluZywgbm90IHN0cmVhbWluZywgaXMgY3VycmVudGx5IAotdGhlIGRlZmF1bHQgbW9kZSBvZiBvcGVyYXRpb24uPC9yZWY+IDwvcD4KLTxub3RlPk1hbnkgZmVhdHVyZXMgb2YgdGhlIFNRTCBsaWJyYXJ5LCBpbmNsdWRpbmcgc3VwcG9ydCBmb3IgY29ubmVjdGlvbiBwb29scywgcGFyYW1ldGVyaXplZCBxdWVyaWVzLCBjYWNoaW5nLCAgCi1hbmQgYWRkZWQgc3VwcG9ydCBmb3IgZXh0cmFjdGluZyBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGFuZCBxdWVyeSBwYXJhbWV0ZXJzIGZyb20gWE1MIHNvdXJjZSBkb2N1bWVudHMgZXhpc3QKLXRoYW5rcyB0byBKb2huIEdlbnRpbGluIChqb2huZ2xpbnV4QGV5ZWNhdGNoaW5nLmNvbSksIHdobyBoYXMgYWxzbyBhZGRlZCBhIG51bWJlciBvZiBTUUwgbGlicmFyeSBzYW1wbGVzLjwvbm90ZT4KLTxwPjxlbT5UaGUgU1FMIGV4dGVuc2lvbiB1c2UgaW4gc3RyZWFtaW5nIG1vZGUgb2YgYSBzaW5nbGUgcm93LXNldCBub2RlIHRvIGluY3JlbWVudGFsbHkgcmV0dXJuIGEgcXVlcnkgcmVzdWx0IHNldCBpcyBleHBlcmltZW50YWwuIElmIHlvdSB1c2Ugc3RyZWFtaW5nIG1vZGUsIHlvdSBjYW4gb25seSBhY2Nlc3Mgcm93IGVsZW1lbnRzIG9uZSBhdCBhIHRpbWUgbW92aW5nIGZvcndhcmQgdGhyb3VnaCB0aGUgcmVzdWx0IHNldC4gVGhlIHVzZSBvZiBYUGF0aCBleHByZXNzaW9ucyBpbiB5b3VyIHN0eWxlc2hlZXQsIGZvciBleGFtcGxlLCB0aGF0IGF0dGVtcHQgdG8gcmV0dXJuIG5vZGVzIGZyb20gdGhlIHJlc3VsdCBzZXQgaW4gYW55IG90aGVyIG1hbm5lciBtYXkgcHJvZHVjZSB1bnByZWRpY3RhYmxlIHJlc3VsdHMuPC9lbT48L3A+Ci08cD48anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbC9YQ29ubmVjdGlvbi5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb248L2p1bXA+IHByb3ZpZGVzIGEgbnVtYmVyIAotb2YgZXh0ZW5zaW9uIGZ1bmN0aW9ucyB0aGF0IHlvdSBjYW4gdXNlIGluIHlvdXIgc3R5bGVzaGVldC48L3A+Ci0gICAgPG9sPgotICAgICAgPGxpPm5ldygpIC0tIFVzZSBvbmUgb2YgdGhlIFhDb25uZWN0aW9uIGNvbnN0cnVjdG9ycyB0byBjb25uZWN0IHRvIGEgZGF0YSBzb3VyY2UsIGFuZCByZXR1cm4gYW4gWENvbm5lY3Rpb24KLSAgICAgICBvYmplY3QuIFlvdSBjYW4gdXNlIG9uZSBvZiB0aGUgY29uc3RydWN0b3JzIGNyZWF0ZXMgYSBjb25uZWN0aW9uIHBvb2wgZnJvbSB3aGljaCBzdHlsZXNoZWV0cyBjYW4gb2J0YWluIGNvbm5lY3Rpb25zIAotICAgICAgIHRvIGEgZGF0YXNvdXJjZS4gVG8gc3VwcG9ydCBjb25uY3Rpb24gcG9vbHMsIFNRTCBsaWJyYXJ5IGluY2x1ZGVzIGEgQ29ubmVjdGlvblBvb2wgaW50ZXJmYWNlIGFuZCBhIGltcGxlbWVudGF0aW9uOgotICAgICAgIERlZmF1bHRDb25uZWN0aW9uUG9vbC4gWW91IGNhbiBhbHNvIHByb3ZpZGUgeW91ciBvd24gQ29ubmVjdGlvblBvb2wgaW1wbGVtZW50YXRpb24uPGJyLz48YnIvPjwvbGk+Ci0gICAgICA8bGk+cXVlcnkoKSAtLSBVc2UgdGhlIFhDb25uZWN0aW9uIG9iamVjdCBxdWVyeSgpIG1ldGhvZCB0byByZXR1cm4gYSAic3RyZWFtYWJsZSIgcmVzdWx0IHNldCBpbiB0aGUgZm9ybSBvZiBhIHJvdy1zZXQKLSAgICAgICBub2RlLiBXb3JrIHlvdXIgd2F5IHRocm91Z2ggdGhlIHJvdy1zZXQgb25lIHJvdyBhdCBhIHRpbWUuIFRoZSBzYW1lIHJvdyBlbGVtZW50IGlzIHVzZWQgb3ZlciBhbmQgb3ZlciBhZ2Fpbiwgc28geW91IGNhbgotICAgICAgIGJlZ2luICJ0cmFuc2Zvcm1pbmciIHRoZSByb3ctc2V0IGJlZm9yZSB0aGUgZW50aXJlIHJlc3VsdCBzZXQgaGFzIGJlZW4gcmV0dXJuZWQuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgPGxpPnBxdWVyeSgpLCBhZGRQYXJhbWV0ZXIoKSwgYWRkUGFyYW1ldGVyRnJvbUVsZW1lbnQoKSwgY2xlYXJQYXJhbWV0ZXJzKCkgLS0gVXNlIHRoZSBYQ29ubmVjdGlvbiBwcXVlcnkoKSBtZXRob2QgaW4gCi0gICAgICAgY29uanVuY3Rpb24gd2l0aCB0aGVzZSBvdGhlciBtZXRob2RzIHRvIHNldCB1cCBhbmQgZXhlY3V0ZSBwYXJhbWV0ZXJpemVkIHF1ZXJpZXMuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgPGxpPlVzZSBkaXNhYmxlQ2FjaGVOb2RlcygpIHRvIHVzZSBzdHJlYW1pbmcgbm9kZSwgYW5kIGVuYWJsZUNhY2hlTm9kZXMoKSB0byBjYWNoZSB0aGUgcXVlcnkgcmVzdWx0IHNldC4gPGJyLz48YnIvPjwvbGk+Ci0gICAgICA8bGk+Y2xvc2UoKSAtLSBVc2UgdGhlIFhDb25uZWN0aW9uIG9iamVjdCBjbG9zZSgpIG1ldGhvZCB0byB0ZXJtaW5hdGUgdGhlIGNvbm5lY3Rpb24uPC9saT4gICAgICAKLSAgICA8L29sPgotICAgIDxwPlRoZSBxdWVyeSgpIGFuZCBwcXVlcnkoKSBleHRlbnNpb24gZnVuY3Rpb25zIHJldHVybiBhIERvY3VtZW50IG5vZGUgdGhhdCBjb250YWlucyAoYXMgbmVlZGVkKSBhbiBhcnJheSBvZiBjb2x1bW4taGVhZGVyIGVsZW1lbnRzLCAKLSAgICBhIHNpbmdsZSByb3cgZWxlbWVudCB0aGF0IGlzIHVzZWQgcmVwZWF0ZWRseSwgYW5kIGFuIGFycmF5IG9mIGNvbCBlbGVtZW50cy4gRWFjaCBjb2x1bW4taGVhZGVyIGVsZW1lbnQgKG9uZSBwZXIgY29sdW1uIGluCi0gICAgdGhlIHJvdy1zZXQpIGNvbnRhaW5zIGFuIGF0dHJpYnV0ZSAoQ29sdW1uQXR0cmlidXRlKSBmb3IgZWFjaCBvZiB0aGUgY29sdW1uIGRlc2NyaXB0b3JzIGluIHRoZSBSZXN1bHRTZXRNZXRhRGF0YSBvYmplY3QuIAotICAgIEVhY2ggY29sIGVsZW1lbnQgY29udGFpbnMgYSB0ZXh0IG5vZGUgd2l0aCBhIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlIGZvciB0aGF0IGNvbHVtbiBpbiB0aGUgY3VycmVudCByb3cuPC9wPgotICAgIDxhbmNob3IgbmFtZT0ic3FsY29ubiIvPgotICAgIDxzMyB0aXRsZT0iU2V0dGluZyB1cCBhIGNvbm5lY3Rpb24iPgotICAgIDxwPllvdSBjYW4gcGxhY2UgY29ubmVjdGlvbiBpbmZvcm1hdGlvbiAoSkRCQyBkcml2ZXIsIGRhdGFzb3VyY2UgVVJMLCBhbmQgdXN1YWxseSB1c2VyIElEIGFuZCBwYXNzd29yZCkgaW4gc3R5bGVzaGVldHMgb3IKLSAgICAgaW4gWE1MIHNvdXJjZSBkb2N1bWVudHMuPC9wPiAKLSAgICAgPHA+VGhlIGZvbGxvd2luZyBzdHlsZXNoZWV0IGZyYWdtZW50IHVzZXMgc3R5bGVzaGVldCBwYXJhbWV0ZXJzIHRvIGRlc2lnbmF0ZSBhIEpEQkMgZHJpdmVyIGFuZCBkYXRhc291cmNlLiBUaGUgZGVmYXVsdAotICAgICBwYXJhbWV0ZXIgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHdpdGggcnVudGltZSBwYXJhbWV0ZXIgdmFsdWVzLjwvcD4KLSAgICAgPHNvdXJjZT4mbHQ7eHNsOnBhcmFtIG5hbWU9ImRyaXZlciIgc2VsZWN0PSInb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJyIvJmd0OwotJmx0O3hzbDpwYXJhbSBuYW1lPSJkYXRhc291cmNlIiBzZWxlY3Q9IidqZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycCciLyZndDsKLSZsdDt4c2w6cGFyYW0gbmFtZT0icXVlcnkiIHNlbGVjdD0iJ1NFTEVDVCAqIEZST00gaW1wb3J0MSciLyZndDs8L3NvdXJjZT4KLSAgICAgIDxwPllvdSBjYW4gYWxzbyBvYnRhaW4gY29ubmVjdGlvbiBpbmZvcm1hdGlvbiBmcm9tIHRoZSBYTUwgc291cmNlIGRvY3VtZW50IHRoYXQgeW91IHVzZSBmb3IgdGhlIHRyYW5zZm9ybWF0aW9ubC4gU3VwcG9zZSAKLSAgICAgIHlvdSBoYXZlIHRoZSBmb2xsb3dpbmcgREJJTkZPIG5vZGVzZXQgaW4gYW4gWE1MIGRvY3VtZW50OjwvcD4KLSAgICAgIDxzb3VyY2U+Jmx0O0RCSU5GTyZndDsKLSAgJmx0O2RiZHJpdmVyJmd0O29yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlciZsdDsvZGJkcml2ZXImZ3Q7Ci0gICZsdDtkYnVybCZndDtqZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycCZsdDsvZGJ1cmwmZ3Q7Ci0gICZsdDt1c2VyJmd0O2pibG9lJmx0Oy91c2VyJmd0OwotICAmbHQ7cGFzc3dvcmQmZ3Q7Z2Vyb24wN21vZSZsdDsvcGFzc3dvcmQmZ3Q7Ci0mbHQ7L0RCSU5GTyZndDs8L3NvdXJjZT4KLSAgICAgICA8cD5JbiB0aGUgc3R5bGVzaGVldCwgeW91IGNhbiBleHRyYWN0IHRoaXMgaW5mb3JtYXRpb24gYXMgZm9sbG93czo8L3A+Ci0gICAgICAgPHNvdXJjZT4mbHQ7eHNsOnN0eWxlc2hlZXQgdmVyc2lvbiAxLjAKLSZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3htbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7eG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iCi0mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcz0ic3FsIiZndDsKLSZuYnNwOyZuYnNwOyZsdDt4c2w6cGFyYW0gbmFtZT0iY2luZm8iIHNlbGVjdD0iLy9EQklORk8iLyZndDsKLSZuYnNwOyZuYnNwOyZsdDt4c2w6dmFyaWFibGUgbmFtZT0iZGIiIHNlbGVjdD0ic3FsOm5ldygkY2luZm8pIi8mZ3Q7Ci0uLi4uPC9zb3VyY2U+IAotICAgICAgPHA+Rm9yIGFuIGV4YW1wbGUgb2YgYm90aCBhcHByb2FjaGVzLCBzZWUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0iYmFzaWMtY29ubiI+QmFzaWMgQ29ubmVjdGlvbjwvbGluaz4gc2FtcGxlcy48L3A+Ci0gICAgICA8cD5Zb3UgY2FuIGFsc28gY3JlYXRlIGEgbmFtZWQgY29ubmVjdGlvbiBwb29sIHRoYXQgaXMgbWFpbnRhaW5lZCBleHRlcm5hbCB0byAmeHNsdDRqOy48L3A+Ci0gICAgICA8c291cmNlPmltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuRGVmYXVsdENvbm5lY3Rpb25Qb29sOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvblBvb2xNYW5hZ2VyOwotLi4uCi1EZWZhdWx0Q29ubmVjdGlvblBvb2wgY3AgPSBuZXcgRGVmYXVsdENvbm5lY3Rpb25Qb29sKCk7Ci1jcC5zZXREcml2ZXIoIm9yZy5lbmh5ZHJhLmluc3RhbnRkYi5qZGJjLmlkYkRyaXZlciIpOwotY3Auc2V0VVJMKCJqZGJjOmlkYjouLi8uLi9pbnN0YW50ZGIvc2FtcGxlLnBycCIpOwotY3Auc2V0VXNlcigiamJsb2UiKTsKLWNwLnNldFBhc3N3b3JkKCJnZXJvbjA3bW9lIik7Ci0vLyBTdGFydCB3aXRoIDEwIGNvbm5lY3Rpb25zLgotY3Auc2V0TWluQ29ubmVjdGlvbnMoMTApOwotY3AuZW5hYmxlUG9vbCgpOwotLy8gUmVnaXN0ZXIgdGhlIGNvbm5lY3Rpb24gcG9vbCBzbyBzdHlsZXNoZWV0cyBjYW4gdXNlIGl0LgotWENvbm5lY3Rpb25Qb29sTWFuYWdlciBwbSA9IG5ldyBYQ29ubmVjdGlvblBvb2xNYW5hZ2VyKCk7Ci1wbS5yZWdpc3RlclBvb2woImV4dHBvb2wiLCBjcCk7PC9zb3VyY2U+Ci0gICAgICA8cD5BIHN0eWxlc2hlZXQgY2FuIHVzZSB0aGlzIGNvbm5lY3Rpb24gcG9vbCBhcyBmb2xsb3dzOjwvcD4KLSAgICAgIDxzb3VyY2U+Jmx0O3hzbDpzdHlsZXNoZWV0IHZlcnNpb24gMS4wCi0gICAgIHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIgotICAgICB4bWxuczpzcWw9Im9yZy5hcGFjaGUueGFsYW4ubGliLnNxbC5YQ29ubmVjdGlvbiIKLSAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InNxbCImZ3Q7Ci0uLi4KLSAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJkYiIgc2VsZWN0PSJzcWw6bmV3KCRkcml2ZXIsICdleHRwb29sJykiLyZndDs8L3NvdXJjZT4KLSAgICAgIDxwPkZvciBhbiBleGFtcGxlLCBzZWUgdGhlIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9ImV4dC1jb25uIj5FeHRlcm5hbENvbm5lY3Rpb248L2xpbms+IHNhbXBsZS48L3A+Ci0gICAgPC9zMz48YW5jaG9yIG5hbWU9InNxbHBhcmFtIi8+Ci0gICAgPHMzIHRpdGxlPSJQYXJhbWV0ZXJpemVkIHF1ZXJpZXMiPgotICAgICAgPHA+VG8gZGVmaW5lIGEgcGFyYW1ldGVyaXplZCBxdWVyeSwgdXNlIGEgU1FMIHF1ZXJ5IHN0cmluZyB3aXRoIGEgcXVlc3Rpb24gbWFyayAoPykgZm9yIGVhY2ggcGFyYW1ldGVyLiBZb3UgY2FuIHByb3ZpZGUgCi0gICAgICB0aGUgcGFyYW1ldGVyIHZhbHVlcyBhdCBydW50aW1lIHdpdGggc3R5bGVzaGVldCBwYXJhbWV0ZXJzIG9yIHdpdGggbm9kZXMgaW4gdGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQuIEZvciBlYWNoIHBhcmFtZXRlciwgCi0gICAgICB5b3Ugc2hvdWxkIGFsc28gZGVzaWduYXRlIHRoZSBTUUwgZGF0YSB0eXBlLjwvcD4KLSAgICAgIDxwPlhDb25uZWN0aW9uIHByb3ZpZGVzIGEgbnVtYmVyIG9mIGFkZFBhcmFtZXRlcigpIG1ldGhvZHMgYW5kIGFuIGFkZFBhcmFtZXRlckZyb21FbGVtZW50KCkgbWV0aG9kIHRoYXQgeW91IGNhbiB1c2UgCi0gICAgICBhcyBleHRlbnNpb24gZnVuY3Rpb25zIHRvIHB1bGwgaW4gdGhlIHBhcmFtZXRlciB2YWx1ZXMgKGluIHRoZSBvcmRlciB0aGUgcGFyYW1ldGVycyBhcHBlYXIgaW4gdGhlIHF1ZXJ5KS4gVG8KLSAgICAgIGV4ZWN1dGUgdGhlIHF1ZXJ5IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBzZXQsIGNhbGwgdGhlIHBxdWVyeSgpIG1ldGhvZCBhcyBhbiBleHRlbnNpb24gZnVuY3Rpb24uIFRoZXJlIGFyZSB0d28gdmFyaWF0aW9ucyAKLSAgICAgIG9mIHRoZSBwcXVlcnkoKSBtZXRob2QuIFRoZSBvbmUgeW91IHNob3VsZCBvcmRpbmFyaWx5IHVzZSBpbmNsdWRlcyBhcyBhcmd1bWVudHMgdGhlIFNRTCBxdWVyeSBzdHJpbmcgYW5kIGEgc3RyaW5nIGxpc3QgCi0gICAgICAoZGVsaW1pdGVkIGJ5IHRoZSBzcGFjZSwgdGFiLCBvciBsaW5lIGZlZWRzKSBvZiBwYXJhbWV0ZXIgdHlwZXMuIEZvciBleGFtcGxlOjwvcD4KLSAgICAgIDxzb3VyY2U+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJyZXN1bHRzZXQiIAotICAgICAgICBzZWxlY3Q9c3FsOnBxdWVyeSgkWENvbm5lY3Rpb25PYmosIAotICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VsZWN0ICogZnJvbSBYIHdoZXJlIFkgPSA/IGFuZCBaID0gPycsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICdpbnQgc3RyaW5nJykiLyZndDs8L3NvdXJjZT4KLSAgICAgIDxwPkZvciBhIGNvbXBsZXRlIGV4YW1wbGUsIHNlZSB0aGUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0icHF1ZXJ5Ij5QYXJhbWV0ZXJpemVkIHF1ZXJ5PC9saW5rPiBzYW1wbGUuPC9wPgotICA8L3MzPjxhbmNob3IgbmFtZT0iZXgtc3FsIi8+IAotICAgIDxzMyB0aXRsZT0iRXhhbXBsZSB3aXRoIFNRTCBsaWJyYXJ5Ij4KLSAgICA8cD5UaGlzIGV4YW1wbGUgZGlzcGxheXMgdGhlIHJlc3VsdCBzZXQgZnJvbSBhIHRhYmxlIGluIGEgc2FtcGxlIEluc3RhbnREQiBkYXRhYmFzZS4gSXQgaXMgYWxzbwotICAgIGF2YWlsYWJsZSBhcyBhIHNhbXBsZSBhcHBsaWNhdGlvbjsgc2VlIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9ImV4dDYiPjYtc3FsbGliLWluc3RhbnRkYjwvbGluaz4uPC9wPgotPHNvdXJjZT4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLSZsdDt4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB2ZXJzaW9uPSIxLjAiCi0gICAgICAgICAgICAgICAgeG1sbnM6c3FsPSJvcmcuYXBhY2hlLnhhbGFuLmxpYi5zcWwuWENvbm5lY3Rpb24iCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InNxbCImZ3Q7Ci0gICZsdDt4c2w6b3V0cHV0IG1ldGhvZD0iaHRtbCIgaW5kZW50PSJ5ZXMiLyZndDsKLSAgJmx0O3hzbDpwYXJhbSBuYW1lPSJxdWVyeSIgc2VsZWN0PSInU0VMRUNUICogRlJPTSBpbXBvcnQxJyIvJmd0OwotIAotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIiZndDsKLSAgICAmbHQ7IS0tIDEuIE1ha2UgdGhlIGNvbm5lY3Rpb24gLS0mZ3Q7Ci0gICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJwcm9kdWN0cyIKLSAgICAgICAgICAgICAgICAgIHNlbGVjdD0ic3FsOm5ldygnb3JnLmVuaHlkcmEuaW5zdGFudGRiLmpkYmMuaWRiRHJpdmVyJywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2pkYmM6aWRiOi5caW5zdGFudGRiXHNhbXBsZS5wcnAnKSIvJmd0OwotICAgICZsdDtIVE1MJmd0OwotICAgICAgJmx0O0hFQUQmZ3Q7Ci0gICAgICAmbHQ7L0hFQUQmZ3Q7Ci0gICAgICAmbHQ7Qk9EWSZndDsKLSAgICAgICAgJmx0O1RBQkxFIGJvcmRlcj0iMSImZ3Q7Ci0gICAgICAgICZsdDshLS0yLiBFeGVjdXRlIHRoZSBxdWVyeSAtLSZndDsKLSAgICAgICAgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJ0YWJsZSIgc2VsZWN0PSdzcWw6cXVlcnkoJHByb2R1Y3RzLCAkcXVlcnkpJy8mZ3Q7Ci0gICAgICAgICAgJmx0O1RSJmd0OwotICAgICAgICAgICZsdDshLS0gR2V0IGNvbHVtbi1sYWJlbCBhdHRyaWJ1dGUgZnJvbSBlYWNoIGNvbHVtbi1oZWFkZXItLSZndDsKLSAgICAgICAgICAmbHQ7eHNsOmZvci1lYWNoIHNlbGVjdD0iJHRhYmxlL3Jvdy1zZXQvY29sdW1uLWhlYWRlciImZ3Q7Ci0gICAgICAgICAgICAmbHQ7VEgmZ3Q7Jmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBjb2x1bW4tbGFiZWwiLyZndDsmbHQ7L1RIJmd0OwotICAgICAgICAgICZsdDsveHNsOmZvci1lYWNoJmd0OwotICAgICAgICAgICZsdDsvVFImZ3Q7Ci0gICAgICAgICAgJmx0O3hzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIkdGFibGUvcm93LXNldC9yb3ciLyZndDsKLSAgICAgICAgICAmbHQ7eHNsOnRleHQmZ3Q7JmFtcDsjMTA7Jmx0Oy94c2w6dGV4dCZndDsKLSAgICAgICAgJmx0Oy9UQUJMRSZndDsKLSAgICAgICZsdDsvQk9EWSZndDsKLSAgICAmbHQ7L0hUTUwmZ3Q7IAotICAgICZsdDshLS0gMy4gQ2xvc2UgdGhlIGNvbm5lY3Rpb24gLS0mZ3Q7Ci0gICAgJmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9InNxbDpjbG9zZSgkcHJvZHVjdHMpIi8mZ3Q7Ci0gICZsdDsveHNsOnRlbXBsYXRlJmd0OwotCi0gICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9InJvdyImZ3Q7Ci0gICAgICAgICZsdDtUUiZndDsKLSAgICAgICAgICAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9ImNvbCIvJmd0OwotICAgICAgICAmbHQ7L1RSJmd0OwotICAmbHQ7L3hzbDp0ZW1wbGF0ZSZndDsKLQotICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSJjb2wiJmd0OwotICAgICZsdDtURCZndDsKLSAgICAgICZsdDshLS0gSGVyZSBpcyB0aGUgY29sdW1uIGRhdGEgLS0+Ci0gICAgICAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0idGV4dCgpIi8+Ci0gICAgJmx0Oy9URD4KLSAgJmx0Oy94c2w6dGVtcGxhdGU+Ci0KLSZsdDsveHNsOnN0eWxlc2hlZXQmZ3Q7Ci08L3NvdXJjZT4KLTwvczM+Ci0gIAotICA8L3MyPjxhbmNob3IgbmFtZT0icGlwZWRvY3VtZW50Ii8+Ci0gIDxzMiB0aXRsZT0icGlwZURvY3VtZW50Ij4KLSAgPHA+SW1wbGVtZW50ZWQgaW4gPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9QaXBlRG9jdW1lbnQuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5saWIuUGlwZURvY3VtZW50PC9qdW1wPiw8YnIvPgotICB0aGUgcGlwZURvY3VtZW50IGV4dGVuc2lvbiBlbGVtZW50IHBpcGVzIGFuIFhNTCBkb2N1bWVudCB0aHJvdWdoIGEgc2VyaWVzIG9mIG9uZSBvciBtb3JlIHRyYW5zZm9ybWF0aW9ucy4gVGhlIG91dHB1dCBvZgotICBlYWNoIHRyYW5zZm9ybWF0aW9uIGlzIHBpcGVkIHRvIHRoZSBuZXh0IHRyYW5zZm9ybWF0aW9uLiBUaGUgZmluYWwgdHJhbnNvZnJtYXRpb24gY3JlYXRlcyBhIHRhcmdldCBmaWxlLjwvcD4KLSAgCi0gIDxwPlN1cHBvc2UsIGZvciBleGFtcGxlLHlvdSBoYXZlIGEgc3R5bGVzaGVldCB0aGF0IGlzIHByb2Nlc3NpbmcgYSAiYm9vayIgZG9jdW1lbnQgd2l0aCBlbGVtZW50cyBkZXNpZ25hdGluZyB0aGUgCi0gIGRvY3VtZW50cyB0byBiZSB0cmFuc2Zvcm1lZC4gVGhpcyBwcmltYXJ5IHN0eWxlc2hlZXQgZ2VuZXJhdGVzIGEgdGFibGUgb2YgY29udGVudHMgZm9yIHRoZSBib29rLiBGb3IgZWFjaCBzb3VyY2UgCi0gIGRvY3VtZW50IGl0IHVzZXMgYSBwaXBlRG9jdW1lbnQgZXh0ZW5zaW9uIGVsZW1lbnQgdG8gcGlwZSB0aGUgZG9jdW1lbnQgdGhyb3VnaCBhIHNlcmllcyBvZiBvbmUgb3IgbW9yZSB0cmFuc2Zvcm1hdGlvbnMuPC9wPgotICA8czMgdGl0bGU9IlNhbXBsZTogZ2VuZXJhdGluZyBhIHRhYmxlIG9mIGNvbnRlbnRzIGFuZCBhbiBIVE1MICZxdW90O2Jvb2smcXVvdDsiPgotICAgIDxwPkFuIFhNTCAiYm9vayIgZG9jdW1lbnQgY29udGFpbnMgYSBudW1iZXIgb2YgZG9jIGVsZW1lbnRzIGxpa2UgdGhlIGZvbGxvd2luZzo8YnIvPgotICAgIDxjb2RlPiZsdDtkb2Mgc291cmNlPSJzb3VyY2VzL2ludHJvLnhtbCIgaWQ9ImludHJvIiBsYWJlbD0iSW50cm9kdWN0aW9uIiZndDs8L2NvZGU+PC9wPgotICAgIDxwPlRoZSBzb3VyY2UgYXR0cmlidXRlIGlkZW50aWZpZXMgdGhlIGRvY3VtZW50IHRvIGJlIHRyYW5zZm9ybWVkLCB0aGUgaWQgaXMgdGhlIG91dHB1dCBmaWxlIG5hbWUsIAotICAgIGFuZCB0aGUgcHJpbWFyeSBzdHlsZXNoZWV0IHBsYWNlcyB0aGUgbGFiZWwgaW4gdGhlIHRhYmxlLW9mLWNvbnRlbnRzIGxpbmsuPC9wPgotICAgIDxwPlRoZSBzdHlsZXNoZWV0IGRlY2xhcmVzIHRoZSBwaXBlRG9jdW1lbnQgbmFtZXNwYWNlLCBkZXNpZ25hdGVzIHRoZSBuYW1lc3BhY2UgcHJlZml4IGFzIGFuIGV4dGVuc2lvbiBlbGVtZW50IHByZWZpeCwKLSAgICBhbmQgY29udGFpbnMgYSBwYXJhbWV0ZXIgZGVzaWduYXRpbmcgd2hlcmUgdGhlIG91dHB1dCBmaWxlcyBhcmUgdG8gYmUgcGxhY2VkOjwvcD4KLSAgPHNvdXJjZT4mbHQ7eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIgotICAgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICB4bWxuczpwaXBlPSJ4YWxhbjovL1BpcGVEb2N1bWVudCIKLSAgIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzPSJwaXBlIiZndDsKLSAgIAotJmx0O3hzbDpwYXJhbSAgbmFtZT0iZGVzdGRpciIgdmFsdWU9Imh0bWwvb3V0cHV0IiZndDsKLS4uLjwvc291cmNlPgotPHA+VGhpcyBzdHlsZXNoZWV0IGNvbnRhaW5zIGEgdGVtcGxhdGUgd2hlcmUgZWFjaCBkb2MgZWxlbWVudCBpcyBwcm9jZXNzZWQuIEZvciBlYWNoIGRvYyBlbGVtZW50LCB0aGUgc3R5bGVzaGVldCBhZGRzIGFuIAotZW50cnkgdG8gdGhlIHRhYmxlLW9mLWNvbnRlbnRzIGRvY3VtZW50LiBUaGUgZXh0ZW5zaW9uIGVsZW1lbnQgcGlwZXMgdGhlIHNwZWNpZmllZCBkb2N1bWVudCB0aHJvdWdoIGEgc2VyaWVzIG9mIHR3byAKLXRyYW5zZm9ybWF0aW9ucywgd2l0aCBhbiBzdHlsZXNoZWV0IGlucHV0IHBhcmFtZXRlciBmb3IgdGhlIGZpcnN0IHRyYW5zZm9ybWF0aW9uLiBUaGUgcGlwZURvY3VtZW50IHRhcmdldCBhdHRyaWJ1dGUgCi1kZXNpZ25hdGVzIHRoZSBvdXRwdXQgZnJvbSB0aGUgc2Vjb25kIHRyYW5zZm9ybWF0aW9uLjwvcD4KLQotPHNvdXJjZT4mbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSJkb2MiJmd0OwotICAmbHQ7cCZndDsKLSAgICAmbHQ7YSBocmVmPXskZGVzdGRpcn0mZ3Q7Jmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9IkBsYWJlbCIvJmd0OyZsdDthJmd0OwotICAmbHQ7L3AmZ3Q7Ci0KLSAgJmx0O3BpcGU6cGlwZURvY3VtZW50ICAgc291cmNlPSJ7QHNvdXJjZX0iIHRhcmdldD0ieyRkZXN0ZGlyL0BpZH0iJmd0OwotICAgICZsdDtzdHlsZXNoZWV0IGhyZWY9InNzMS54c2wiJmd0OwotICAgICAgJmx0O3BhcmFtIG5hbWU9ImRvYy1pZCIgdmFsdWU9IkBpZCIvJmd0OwotICAgICZsdDsvc3R5bGVzaGVldCZndDsKLSAgICAmbHQ7c3R5bGVzaGVldCBocmVmPSJzczIueHNsIi8mZ3Q7ICAgCi0gICZsdDsvcGlwZTpwaXBlRG9jdW1lbnQmZ3Q7Ci0gIAotJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7PC9zb3VyY2U+Ci0gCi0gICA8cD5Ob3Rlczo8L3A+Ci0gICA8dWw+Ci0gICA8bGk+VGhlIGJhc2UgVVJJIGZvciB0aGUgc291cmNlIGF0dHJpYnV0ZSBpcyB0aGUgWE1MICJib29rIiBkb2N1bWVudC48L2xpPgotICAgPGxpPlRoZSB0YXJnZXQgYXR0cmlidXRlIGlzIHRha2VuIGFzIGlzICh0aGUgYmFzZSBpcyB0aGUgY3VycmVudCB1c2VyIGRpcmVjdG9yeSBmcm9tIHdoaWNoIHRoaXMgdHJhbnNmb3JtYXRpb24gaXMgYmVpbmcgcnVuKS48L2xpPgotICAgPGxpPlRoZSBzdHlsc2hlZXQgY29udGFpbmcgdGhlIGV4dGVuc2lvbiBlbGVtZW50IGlzIHRoZSBiYXNlIFVSSSBmb3IgdGhlIHN0eWxlc2hlZXQgaHJlZnMuPC9saT4KLSAgIDwvdWw+Ci08L3MzPgotPHMzIHRpdGxlPSJWYXJpYXRpb246IHVzaW5nIHBpcGVEb2N1bWVudCBpbiBhbiBlbXB0eSBzdHlsZXNoZWV0Ij4KLTxwPlN1cHBvc2UgeW91IHdhbnQgdG8gcGlwZSBhIGRvY3VtZW50IHRocm91Z2ggYSBzZXJpZXMgb2YgdHJhbnNmb3JtYXRpb25zLiBZb3UgY2FuIHVzZSB0aGUgcGlwZURvY3VtZW50IGV4dGVuc2lvbiBlbGVtZW50Ci10byBwZXJmb3JtIHRoaXMgb3BlcmF0aW9uIGJ5IHBsYWNpbmcgdGhlIGV4dGVuc2lvbiBlbGVtZW50IGluIGFuIG90aGVyd2lzZSBlbXB0eSBzdHlsZXNoZWV0LjwvcD4KLTxwPlRoZSBmb2xsb3dpbmcgc3R5bGVzaGVldCBpcyB1c2VkIHRvIG1lcmdlIHRoZSBYYWxhbiBkb2N1bWVudHMgaW50byBhIGJvb2sgKHRoZSBmaXJzdCB0cmFuc2Zvcm1hdGlvbiksIGFuZCB0cmFuc2Zvcm0gdGhlIGJvb2sKLWludG8gYSB0cmVlIG9mIGZvcm1hdHRpbmcgb2JqZWN0cywgd2hpY2ggY2FuIHRoZW4gYmUgdXNlZCB0byBnZW5lcmF0ZSBhIFBERiBmaWxlLiBUaGlzIHRyYW5zZm9ybWF0aW9uIGlzIGludm9rZWQgYXMgZm9sbG93czo8L3A+Ci08cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzIC1pbiBwcmludGJvb2sueG1sPC9jb2RlPjxici8+Ci08Y29kZT4gLXBhcmFtIHNvdXJjZSBwcmludGJvb2sueG1sPC9jb2RlPjxici8+Ci08Y29kZT4gLXBhcmFtIHRhcmdldCB4YWxhbmJvb2suZm88L2NvZGU+PC9wPgotPHA+VGhlcmUgaXMgbm8gWE1MIGlucHV0IGRvY3VtZW50IG9yIG91dHB1dCBkb2N1bWVudCBmb3IgdGhlIHByaW1hcnkgdHJhbnNmb3JtYXRpb24sIHdoaWNoIGRvZXMgbm8gbW9yZSB0aGFuIGludm9rZQotdGhlIGV4dGVuc2lvbiBlbGVtZW50LjwvcD4KLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0nMS4wJz8mZ3Q7Ci0KLSZsdDt4c2w6c3R5bGVzaGVldCB2ZXJzaW9uPSIxLjAiCi0gICAgICAgICAgICAgICAgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICAgICAgICAgICAgICAgeG1sbnM6cGlwZT0ieGFsYW46Ly9vcmcuYXBhY2hlLnhhbGFuLmxpYi5QaXBlRG9jdW1lbnQiCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InBpcGUiJmd0OwotCi0mbHQ7eHNsOnBhcmFtIG5hbWU9InNvdXJjZSIvJmd0OwotJmx0O3hzbDpwYXJhbSBuYW1lPSJ0YXJnZXQiLyZndDsKLQotJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iLyImZ3Q7Ci0KLSAgJmx0O3BpcGU6cGlwZURvY3VtZW50IAotICAgICAgICBzb3VyY2U9Inskc291cmNlfSIKLSAgICAgICAgdGFyZ2V0PSJ7JHRhcmdldH0iJmd0OwotICAgICZsdDtzdHlsZXNoZWV0IGhyZWY9InByaW50Ym9va19hc3NlbWJsZS54c2wiLyZndDsKLSAgICAmbHQ7c3R5bGVzaGVldCBocmVmPSJia2Jvb2s4eDExX3hhbGFuLnhzbCIvJmd0OwotICAmbHQ7L3BpcGU6cGlwZURvY3VtZW50Jmd0OwotICAKLSZsdDsveHNsOnRlbXBsYXRlJmd0OwotCi0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0Ozwvc291cmNlPgotCi08L3MzPiAgCi0gIDwvczI+PGFuY2hvciBuYW1lPSJldmFsdWF0ZSIvPgotICA8czIgdGl0bGU9ICJldmFsdWF0ZSI+Ci0gIDxwPkltcGxlbWVudGVkIGluIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9saWIvRXh0ZW5zaW9ucy5odG1sIj5vcmcuYXBhY2hlLnhhbGFuLmxpYi5FeHRlbnNpb25zPC9qdW1wPiw8YnIvPgotPGNvZGU+ZXZhbHVhdGUgKHhwYXRoLWV4cHJlc3Npb24pPC9jb2RlPiBmdW5jdGlvbiByZXR1cm5zIHRoZSByZXN1bHQgb2YgZXZhbHVhdGluZyB0aGUgeHBhdGgtZXhwcmVzc2lvbiBpbiB0aGUgY3VycmVudCAKLVhQYXRoIGV4cHJlc3Npb24gY29udGV4dCAoYXV0b21hdGljYWxseSBwYXNzZWQgaW4gYnkgdGhlIGV4dGVuc2lvbiBtZWNoYW5pc20pLjwvcD4KLTxwPlVzZSB0aGUgZXZhbHVhdGlvbiBleHRlbnNpb24gZnVuY3Rpb24gd2hlbiB0aGUgdmFsdWUgb2YgdGhlIGV4cHJlc3Npb24gaXMgbm90IGtub3duIHVudGlsIHJ1biB0aW1lLjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJ0b2tlbml6ZSIvPgotPHMyIHRpdGxlPSJ0b2tlbml6ZSI+Ci08cD5JbXBsZW1lbnRlZCBpbiA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vbGliL0V4dGVuc2lvbnMuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5saWIuRXh0ZW5zaW9uczwvanVtcD4sPGJyLz4KLTxjb2RlPnRva2VuaXplICh0b2tlbml6ZS1zdHJpbmcsIGRlbGltaXRlcnMpPC9jb2RlPjxici8+Ci1vcjxici8+Ci08Y29kZT50b2tlbml6ZSAodG9rZW5pemUtc3RyaW5nKTwvY29kZT4gZnVuY3Rpb24gcmV0dXJucyBhIG5vZGUtc2V0IGNvbnRhaW5pbmcgb25lIHRleHQgbm9kZSBmb3IgZWFjaCB0b2tlbiBpbiB0aGUgdG9rZW5pemUtc3RyaW5nLjwvcD4KLTxwPlRoZSBkZWxpbWl0ZXJzIGRldGVybWluZSB3aGljaCBjaGFyYWN0ZXJzIGFyZSB1c2VkIHRvIGRpdmlkZSB0aGUgdG9rZW5pemUtc3RyaW5nIGludG8gaW5kaXZpZHVhbCB0b2tlbnMuIElmIHlvdSBkbyBub3QgaW5jbHVkZQotdGhlIGRlbGltaXRlcnMgYXJndW1lbnQsIHRoZSBmdW5jdGlvbiB1c2VzIHRhYiAoJmFtcDsjeDA5KSwgbGluZWZlZWQgKCZhbXA7I3gwQSksIHJldHVybiAoJmFtcDsjeDBEKSwgYW5kIHNwYWNlICgmYW1wOyN4MjApIGFzIGRlbGltaXRlcnMuCi1JZiB0b2tlbml6ZS1zdHJpbmcgaXMgYW4gZW1wdHkgc3RyaW5nIG9yIGNvbnRhaW5zIG9ubHkgZGVsaW1pdGVycywgdGhlIHJlc3VsdCBpcyBhbiBlbXB0eSBub2RlLXNldC48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iZ3JvdXBpdGVtIi8+Ci08czIgdGl0bGU9ICJncm91cCBhbmQgaXRlbSI+Ci08cD48ZW0+VG8gYmUgZG9uZS48L2VtPiBQcm92aWRlcyBlZmZpY2llbnQgZ3JvdXBpbmcgb2YgaXRlbXMgd2l0aCBhIGNvbW1vbiB2YWx1ZS48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0idHlwZSIvPgotPHMyIHRpdGxlPSAidHlwZSI+Ci08cD48ZW0+VG8gYmUgZG9uZS48L2VtPiBSZXR1cm5zIGEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyB0aGUgU2NoZW1hIG9yIERURCB0eXBlLjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJ0b2RhdGUiLz4KLTxzMiB0aXRsZT0idG8tZGF0ZSI+Ci08cD48ZW0+VG8gYmUgZG9uZS48L2VtPiBUYWtlcyBhIHN0cmluZyBhcyBpbnB1dCwgYW5kIHJldHVybnMgYSBsb25nIHZhbHVlIHJlcHJlc2VudGluZyB0aGUgZGF0ZS48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iZm9ybWF0ZGF0ZSIvPgotPHMyIHRpdGxlPSJmb3JtYXQtZGF0ZSI+Ci08cD48ZW0+VG8gYmUgZG9uZS48L2VtPiBUYWtlcyBhIGRhdGUgc3RyaW5nLCBhbmQgZm9ybWF0cyBpdCBhY2NvcmRpbmcgdG8gYSBzcGVjaWZpY2F0aW9uLjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJncmVwIi8+Ci08czIgdGl0bGU9ImdyZXAiPgotPHA+PGVtPlRvIGJlIGRvbmUuPC9lbT4gUGVyZm9ybXMgYSBncmVwIGZ1bmN0aW9uIGFuZCByZXR1cm5zIHRoZSBzdWJzdHJpbmcuPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9ImZvcmVhY2h0b2tlbiIvPgotPHMyIHRpdGxlPSJmb3ItZWFjaC10b2tlbiI+Ci08cD48ZW0+VG8gYmUgZG9uZS48L2VtPiBUb2tlbml6ZXMgYSBzdHJpbmcsIHRyZWF0cyBlYWNoIHRva2VuIGFzIGEgRE9NIFRleHQgbm9kZSwgYW5kIGV4ZWN1dGVzIHRoZQotc3ViLXRlbXBsYXRlLjwvcD4KLTwvczI+Ci08L3MxPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi9mYXEueG1sIGIveGRvY3Mvc291cmNlcy94YWxhbi9mYXEueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MjliOWMxLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4vZmFxLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDIyNCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+IAotPCFET0NUWVBFIGZhcXMgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZmFxcy5kdGQiPgotCi08ZmFxcyB0aXRsZT0iRnJlcXVlbnRseSBhc2tlZCBxdWVzdGlvbnMiPgotCi0gIDxmYXEgdGl0bGU9IldoZXJlIGRvIEkgZ28gdG8gbGVhcm4gYWJvdXQgWFNMVCI+ICAKLSAgICA8cT5XaGVyZSBkbyBJIGdvIHRvIGxlYXJuIGFib3V0IFhTTFQ/PC9xPiAgICAKLSAgICA8YT48cD5UaGUgZGVmaW5pdGl2ZSBzb3VyY2VzIGFyZSB0aGUgVzNDIFhTTFQgYW5kIFhQYXRoIHJlY29tbWVuZGF0aW9uczogPHJlc291cmNlLXJlZiBpZHJlZj0ieHNsdCIvPiBhbmQgCi0gICAgPHJlc291cmNlLXJlZiBpZHJlZj0ieHBhdGgiLz4uPC9wPgotICAgIDxwPkZvciBhIGJyaWVmIGxpc3Rpbmcgb2YgdHV0b3JpYWxzLCBkaXNjdXNzaW9uIGZvcnVtcywgYW5kIG90aGVyIG1hdGVyaWFscywgc2VlIDxsaW5rIGlkcmVmPSJvdmVydmlldyIKLSAgICAgYW5jaG9yPSJ1cHRvc3BlZWQiPkdldHRpbmcgdXAgdG8gc3BlZWQgd2l0aCBYU0xUPC9saW5rPi48L3A+PC9hPgotICA8L2ZhcT4KLQotICA8ZmFxIHRpdGxlPSJXaGljaCB2ZXJzaW9uIG9mIFhlcmNlcyBzaG91bGQgSSBiZSB1c2luZz8iPiAgCi0gICAgPHE+V2hpY2ggdmVyc2lvbiBvZiBYZXJjZXMgc2hvdWxkIEkgYmUgdXNpbmc/PC9xPiAgICAKLSAgICA8YT48cD4meHNsdDRqLWN1cnJlbnQ7IGhhcyBiZWVuIHRlc3RlZCB3aXRoICZ4bWw0ai11c2VkOy4gU2VlIDxsaW5rIGlkcmVmPSJyZWFkbWUiIGFuY2hvcj0ic3RhdHVzIj5TdGF0dXM8L2xpbms+LjwvcD48L2E+Ci0gIDwvZmFxPgotICAKLSAgPGZhcSB0aXRsZT0iQ29tcGF0aWJpbGl0eSB3aXRoICZ4c2x0NGo7IHZlcnNpb24gMSI+Ci0gICA8cT5Ib3cgZG8gSSBydW4gYXBwbGljYXRpb25zIHRoYXQgdXNlIHRoZSAmeHNsdDRqOyB2ZXJzaW9uIDEgQVBJIHdpdGggJnhzbHQ0ajI7PC9xPgotICAgPGE+PHA+VXNlIHRoZSBYYWxhbi1KYXZhIDEgY29tcGF0aWJpbGl0eSBKQVIgdG8gcmVjb21waWxlIGFuZCBydW4geW91ciAmeHNsdDRqOyAxIGFwcGxpY2F0aW9ucyB3aXRoICZ4c2x0NGoyOy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSAKLSAgIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIiBhbmNob3I9ImNvbXBhdCI+VXNpbmcgdGhlICZ4c2x0NGo7IHZlcnNpb24gMSBBUEk8L2xpbms+LjwvcD48L2E+Ci0gIDwvZmFxPgotICAgIAotICA8ZmFxIHRpdGxlPSJUckFYIGFuZCBKQVhQIj4KLSAgICA8cT5XaGF0IGFyZSBUckFYIGFuZCBKQVhQLCBhbmQgYXJlIHRoZXkgcmVsYXRlZD88L3E+Ci0gICAgPGE+PHA+VHJBWCBpcyB0aGUgVHJhbnNmb3JtYXRpb24gQVBJIGZvciBYTUwuIEluIE5vdmVtYmVyIDIwMDAsIFRyQVggd2FzIHJldmlzZWQgYW5kIGluY29ycG9yYXRlZCBpbnRvIEpBWFAsIHRoZSBKQVZBIEFQSSBmb3IgWE1MCi0gICAgUHJvY2Vzc2luZy4gSkFYUCAoaW5jbHVkaW5nIFRyQVgpIHByb3ZpZGVzIHVzZXJzIGEgc3RhbmRhcmQsIHZlbmRvci1uZXV0cmFsIEFQSSBmb3Igd29ya2luZyB3aXRoIChhbmQgdHJhbnNmb3JtaW5nKSBYTUwgZG9jdW1lbnRzLiAKLSAgICBZb3UgY2FuIHVzZSB0aGlzIEFQSSB0byBidWlsZCBhcHBsaWNhdGlvbnMgdGhhdCBhcmUgbm90IGJvdW5kIHRvIHRoZSBwYXJ0aWN1bGFyIGltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgYSBnaXZlbiBYTUwgcGFyc2VyIG9yIFhTTAotICAgIHRyYW5zZm9ybWVyLjwvcD4KLSAgICA8cD4meHNsdDRqOyBpbmNsdWRlcyB0aGUgSkFYUCBwYWNrYWdlcywgaW1wbGVtZW50cyB0aGUgVHJBWCBwb3J0aW9uIG9mIHRoYXQgQVBJIChqYXZheC54bWwudHJhbnNmb3JtLi4uLiksIGFuZCBpbmNsdWRlcyB4ZXJjZXMuamFyIGZyb20KLSAgICAmeG1sNGo7LCB3aGljaCBpbXBsZW1lbnRzIHRoZSBwYXJzZXIgcG9ydGlvbiBvZiB0aGUgQVBJIChqYXZheC54bWwucGFyc2VyLi4uLikuPC9wPgotPHA+Rm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSA8bGluayBpZHJlZj0idHJheCI+VFJhWCAoVHJhbnNmb3JtYXRpb24gQVBJIGZvciBYTUwpPC9saW5rPiBhbmQgPHJlc291cmNlLXJlZiBpZHJlZj0iamF4cDExIi8+LjwvcD48L2E+Ci0gIDwvZmFxPgotICA8ZmFxIHRpdGxlPSJDaGFpbmluZyB0cmFuc2Zvcm1hdGlvbnMiPiAgCi0gICAgPHE+SG93IGRvIHlvdSBjaGFpbiB0b2dldGhlciBhIHNlcmllcyBvZiB0cmFuc2Zvcm1hdGlvbnM/IjwvcT4KLSAgICAKLSAgICA8YT48cD4meHNsdDRqOyBzdXBwb3J0cyB0d28gc3RyYXRlZ2llcyBmb3IgY2hhaW5pbmcgdG9nZXRoZXIgYSBzZXJpZXMgb2YgdHJhbnNmb3JtYXRpb25zIHN1Y2ggdGhhdCB0aGUgb3V0cHV0IG9mIGVhY2ggCi0gICAgdHJhbnNmb3JtYXRpb24gcHJvdmlkZXMgaW5wdXQgZm9yIHRoZSBuZXh0IHRyYW5zZm9ybWF0aW9uLjwvcD4KLSAgICA8dWw+Ci0gICAgICA8bGk+Rm9yIGVhY2ggdHJhbnNmb3JtYXRpb24gaW4gdGhlIHNlcmllcywgeW91IGNhbiBzZXQgb25lIFNBWCBDb250ZW50SGFuZGxlciB0byBwcm9jZXNzIHRoZSBpbnB1dCwgYW5kIGFub3RoZXIgQ29udGVuSGFuZGxlciB0byBwcm9jZXNzCi0gICAgICAgdGhlIG91dHB1dC48YnIvPjxici8+PC9saT4KLSAgICAgIDxsaT5Zb3UgY2FuIGFsc28gc2V0IHVwIGEgc2VyaWVzIG9mIHBhcmVudC1jaGlsZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gYW4gWE1MUmVhZGVyIGFuZCBvbmUgb3IgbW9yZSBYTUxGaWx0ZXJzLjwvbGk+IAotICAgIDwvdWw+Ci0gICAgPHA+Rm9yIHRoZSBkZXRhaWxzIGFuZCBsaW5rcyB0byBleGFtcGxlcywgc2VlIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIiBhbmNob3I9Im91dGFzaW4iPlVzaW5nIHRyYW5zZm9ybWF0aW9uIG91dHB1dCBhcyBpbnB1dCBmb3IgCi0gICAgYW5vdGhlciB0cmFuc2Zvcm1hdGlvbjwvbGluaz4uPGFuY2hvciBuYW1lPSJqZGsxMyIvPjwvcD48L2E+Ci0gIDwvZmFxPgotICAKLSAgPGZhcSB0aXRsZT0iSXNzdWVzIHJ1bm5pbmcgWGFsYW4gb24gSkRLIDEuMyI+Ci0gIDxxPkknbSBoYXZpbmcgYSBwcm9ibGVtIGJ1aWxkaW5nIG9yIHJ1bm5pbmcgJnhzbHQ0ajsgb24gdGhlIEpESyAxLjMuPC9xPgotICA8YT48cD5UaGUgSkRLIDEuMyBhdXRvbWF0aWNhbGx5IHBsYWNlcyBldmVyeXRoaW5nIGluIHRoZSBsaWIvZXh0IGRpcmVjdG9yeSBpbiBmcm9udCBvZiBldmVyeXRoaW5nIHlvdSBwbGFjZSBvbiB0aGUgY2xhc3NwYXRoLiBJZiB0aGlzIGRpcmVjdG9yeSBjb250YWlucyBhIHZlcnNpb24gb2YgRE9NLCBKQVhQLCBvciBYZXJjZXMgdGhhdCBwcmVkYXRlcyB0aGUgJnhzbHQ0ajsgZGlzdHJpYnV0aW9uIHlvdSBhcmUgdXNpbmcsIHlvdSBtYXkgaGF2ZSBwcm9ibGVtcyE8L3A+IAotPHA+VGhlIElCTSBKREsgMS4zIGluY2x1ZGVzIGFuIGVhcmxpZXIgdmVyc2lvbiBvZiB4ZXJjZXMuamFyIGluIHRoZSBsaWIvZXh0IGRpcmVjdG9yeSwgYSB2ZXJzaW9uIHRoYXQgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBKQVhQIDEuMSBpbnRlcmZhY2VzIGFuZCB0aGVyZWZvcmUgZG9lcyBub3Qgd29yayB3aXRoIHRoZSBjdXJyZW50IFhhbGFuIHJlbGVhc2UuIEFjY29yZGluZ2x5LCB5b3UgbXVzdCBlaXRoZXIgcHVyZ2UgdGhlIHhlcmNlcy5qYXIgdGhhdCBpcyBpbiB0aGF0IGRpcmVjdG9yeSBvciBvdmVyd3JpdGUgaXQgd2l0aCB0aGUgeGVyY2VzLmphciB0aGF0IGlzIGluY2x1ZGVkIHdpdGggdGhlIFhhbGFuIGRpc3RyaWJ1dGlvbi48L3A+Ci08cD5UaGUgU1VOIEpESyAxLjMgaW5jbHVkZXMgYSBwcmUtMS4xIHZlcnNpb24gb2YgdGhlIEpBWFAgaW4gY3JpbXNvbi5qYXIuIEVpdGhlciBwdXJnZSB0aGUgY3JpbXNvbi5qYXIgaW4gdGhhdCBkaXJlY3Rvcnkgb3Igb3ZlcndyaXRlIGl0IHdpdGggYSBuZXdlciBjcmltc29uLmphciB0aGF0IGluY2x1ZGVzIGFuZCBpbXBsZW1lbnRzIHRoZSBKQVhQIDEuMSBpbnRlcmZhY2VzLjwvcD48L2E+ICAKLSAgPC9mYXE+Ci0gIDxmYXEgdGl0bGU9ImEgJnF1b3Q7RE9NMDA2IEhpZXJhcmNoeSByZXF1ZXN0IGVycm9yJnF1b3Q7Ij4KLSAgPHE+V2h5IGRvIEkgZ2V0IGEgIkRPTTAwNiBIaWVyYXJjaHkgcmVxdWVzdCBlcnJvciIgd2hlbiBJIHRyeSB0byB0cmFuc2Zvcm0gaW50byBhIERPTSBEb2N1bWVudCBub2RlPzwvcT4KLSAgPGE+Ci0gIDxwPlRoaXMgZXJyb3Igb2NjdXJzIHdoZW4gWGFsYW4gdHJpZXMgdG8gYWRkIGEgTm9kZSB0byBhIERvY3VtZW50IG5vZGUgd2hlcmUgaXQgaXNuJ3QgYWxsb3dlZC4gRm9yIGV4YW1wbGUsIGF0dGVtcHRpbmcgdG8gYWRkIG5vbi13aGl0ZXNwYWNlCi0gIHRleHQgdG8gdGhlIERPTSBEb2N1bWVudCBub2RlIHByb2R1Y2VzIHRoaXMgZXJyb3IuPC9wPgotICAgPHA+VGhlIGVycm9yIGNhbiBhbHNvIG9jY3VyIHdoZW4gYSBEb2N1bWVudCBub2RlIGlzIGNyZWF0ZWQgd2l0aCB0aGUgRE9NSW1wbGVtZW50YXRpb24gY3JlYXRlRG9jdW1lbnQoKSBtZXRob2QsIHdoaWNoIHRha2VzIGEgcXVhbGlmaWVkIG5hbWUKLSAgICBhcyBhbiBhcmd1bWVudCBhbmQgY3JlYXRlcyBhbiBlbGVtZW50IG5vZGUuICBJZiB5b3UgdGhlbiBwYXNzIHRoZSByZXR1cm5lZCBEb2N1bWVudCBub2RlIHRvIFhhbGFuLCB5b3UgZ2V0IGEgIkRPTTAwNiBIaWVyYXJjaHkgcmVxdWVzdAotICAgIGVycm9yIiB3aGVuIFhhbGFuIHRyaWVzIHRvIGFkZCBhIHNlY29uZCBlbGVtZW50IHRvIHRoZSBEb2N1bWVudCBub2RlLiBUaGUgc29sdXRpb24gaXMgdG8gZWl0aGVyIHVzZSB0aGUgRG9jdW1lbnRCdWlsZGVyIG5ld0RvY3VtZW50KCkgbWV0aG9kCi0gICAgdG8gY3JlYXRlIGEgRG9jdW1lbnQgdGhhdCBkb2VzIG5vdCBjb250YWluIGFuIGVsZW1lbnQgbm9kZSwgb3IgdXNlIGEgRG9jdW1lbnRGcmFnbWVudC4gSXQgc2hvdWxkIGJlIG5vdGVkIHRoYXQgdGhlIAotICAgIERvY3VtZW50QnVpbGRlciBuZXdEb2N1bWVudCgpIG1ldGhvZCBpcyAiTm9uLXByZWZlcnJlZCIgYWNjb3JkaW5nIHRvIHRoZSBKQVhQIDEuMSBkb2N1bWVudGF0aW9uLjwvcD4KLSAgPC9hPgotICA8L2ZhcT4KLSAgCi0gIDxmYXEgdGl0bGU9IlNwZWVkaW5nIHVwIHRyYW5zZm9ybWF0aW9ucyI+Ci0gIAotICAgIDxxPldoYXQgY2FuIEkgZG8gdG8gc3BlZWQgdXAgdHJhbnNmb3JtYXRpb25zPzwvcT4KLSAgICAKLSAgICA8YT48cD5JbiB0aGUgb25nb2luZyBkZXZlbG9wbWVudCBvZiAmeHNsdDRqOywgZW5oYW5jaW5nIHBlcmZvcm1hbmNlIGlzIHRoZSBwcmltYXJ5IGdvYWwgb2YgdGhlICZ4c2x0NGo7IHRlYW0uCi0gICAgSGVyZSBhcmUgc29tZSBwcmVsaW1pbmFyeSBzdWdnZXN0aW9ucyBmb3IgeW91IHRvIGtlZXAgaW4gbWluZCBhcyB5b3Ugc2V0IHVwIHlvdXIgYXBwbGljYXRpb25zOjwvcD48dWw+Ci0gICAgPGxpPlVzZSBhIFRlbXBsYXRlcyBvYmplY3QgKHdpdGggYSBkaWZmZXJlbnQgVHJhbnNmb3JtZXJzIGZvciBlYWNoIHRyYW5zZm9ybWF0aW9uKSB0byBwZXJmb3JtIG11bHRpcGxlIHRyYW5zZm9ybWF0aW9ucyB3aXRoIHRoZSBzYW1lIAotICAgIHNldCBvZiBzdHlsZXNoZWV0IGluc3RydWN0aW9ucyAoc2VlIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIiBhbmNob3I9Im11bHRpdGhyZWFkaW5nIj5NdWx0aXRocmVhZGluZzwvbGluaz4pLjxici8+PGJyLz48L2xpPiAgICAgICAgIAotICAgIDxsaT5TZXQgdXAgeW91ciBzdHlsZXNoZWV0cyB0byBmdW5jdGlvbiBlZmZpY2llbnRseS48YnIvPjxici8+PC9saT4KLSAgICAgICA8dWw+Ci0gICAgICAgICA8bGk+RG9uJ3QgdXNlICIvLyIgKGRlc2NlbmRhbnQgYXhlcykgcGF0dGVybnMgbmVhciB0aGUgcm9vdCBvZiBhIGxhcmdlIGRvY3VtZW50Ljxici8+PGJyLz48L2xpPgotICAgICAgICAgPGxpPlVzZSB4c2w6a2V5IGVsZW1lbnRzIGFuZCB0aGUga2V5KCkgZnVuY3Rpb24gYXMgYW4gZWZmaWNpZW50IHdheSB0byByZXRyaWV2ZSBub2RlIHNldHMuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgICA8bGk+V2hlcmUgcG9zc2libGUsIHVzZSBwYXR0ZXJuIG1hdGNoaW5nIHJhdGhlciB0aGFuIHhzbDppZiBvciB4c2w6d2hlbiBzdGF0ZW1lbnRzLjxici8+PGJyLz48L2xpPgotICAgICAgICAgPGxpPnhzbDpmb3ItZWFjaCBpcyBmYXN0IGJlY2F1c2UgaXQgZG9lcyBub3QgcmVxdWlyZSBwYXR0ZXJuIG1hdGNoaW5nLjxici8+PGJyLz48L2xpPgotICAgICAgICAgPGxpPktlZXAgaW4gbWluZCB0aGF0IHhzbDpzb3J0IHByZXZlbnRzIGluY3JlbWVudGFsIHByb2Nlc3NpbmcuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgICA8bGk+V2hlbiB5b3UgY3JlYXRlIHZhcmlhYmxlcywgJmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJmb29FbGVtIiBzZWxlY3Q9ImZvbyIvJmd0OyBpcyB1c3VhbGx5IGZhc3RlciB0aGFuCi0gICAgICAgICAmZ3Q7eHNsOnZhcmlhYmxlIG5hbWU9ImZvb0VsZW0iJmd0OyZsdDt4c2w6dmFsdWUtb2Ytc2VsZWN0PSJmb28iLyZndDsmbHQ7L3hzbDp2YXJpYWJsZSZndDsuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgICA8bGk+QmUgY2FyZWZ1bCB1c2luZyB0aGUgbGFzdCgpIGZ1bmN0aW9uLjxici8+PGJyLz48L2xpPgotICAgICAgICAgPGxpPlRoZSB1c2Ugb2YgaW5kZXggcHJlZGljYXRlcyB3aXRoaW4gbWF0Y2ggcGF0dGVybnMgY2FuIGJlIGV4cGVuc2l2ZS48YnIvPjxici8+PC9saT4KLSAgICAgICAgIDxsaT5EZWNvZGluZyBhbmQgZW5jb2RpbmcgaXMgZXhwZW5zaXZlLjxici8+PGJyLz48L2xpPgotICAgICAgIDwvdWw+Ci0gICAgIDxsaT5Gb3IgdGhlIHVsdGltYXRlIGluIHNlcnZlci1zaWRlIHNjYWxhYmlsaXR5LCBwZXJmb3JtIHRyYW5zZm9ybSBvcGVyYXRpb25zIG9uIHRoZSBjbGllbnQuIEZvciBleGFtcGxlcywgc2VlIAotICAgICA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJhcHBsZXR4bWx0b2h0bWwiPmFwcGxldFhNTHRvSFRNTDwvbGluaz4gYW5kIDxsaW5rIGlkcmVmPSJzYW1wbGVzIgotICAgICBhbmNob3I9ImdldC10b2RvLWxpc3QiPmdldC10b2RvLWxpc3Q8L2xpbms+LjwvbGk+Ci0gICAgPC91bD48L2E+Ci0gIDwvZmFxPgotCi0gIDxmYXEgdGl0bGU9Ik5vQ2xhc3NEZWZGb3VuZCBlcnJvcnMiPgotICAKLSAgICA8cT5JJ20gZ2V0dGluZyBhIE5vQ2xhc3NEZWZGb3VuZCBlcnJvci4gV2hhdCBoYXMgdG8gYmUgb24gdGhlIGNsYXNzcGF0aD88L3E+Ci0gICAgCi0gICAgPGE+PG9sPgotICAgIDxsaT54YWxhbi5qYXIgYW5kIHhlcmNlcy5qYXIgKG9yIHRoZSBYTUwgcGFyc2VyIHlvdSBhcmUgdXNpbmcpIG11c3QgYWx3YXlzIGJlIG9uIHRoZSBjbGFzc3BhdGguPGJyLz48YnIvPjwvbGk+Ci0gICAgPGxpPlRvIHJ1biB0aGUgc2FtcGxlcyBpbiB0aGUgc2FtcGxlcyBzdWJkaXJlY3RvcmllcywgeGFsYW5zYW1wbGVzLmphciBtdXN0IGJlIG9uIHRoZSBjbGFzc3BhdGguIFRvIHJ1biB0aGUgc2VydmxldCAoaW4KLSAgICBzYW1wbGVzL3NlcnZsZXQpLCB4YWxhbnNlcnZsZXQuamFyIG11c3QgYmUgb24gdGhlIGNsYXNzcGF0aCBhbG9uZyB3aXRoIHRoZSBqYXZheC5zZXJ2bGV0IGFuZCBqYXZheC5zZXJ2bGV0Lmh0dHAgcGFja2FnZXMuIFN1biBkaXN0cmlidXRlcwotICAgIHRoZSBqYXZheC5zZXJ2bGV0IHBhY2thZ2VzIGluIHRoZSBKU1dESyBzZXJ2bGV0LmphciBmaWxlLjxici8+PGJyLz48L2xpPgotICAgIDxsaT5UbyBydW4gZXh0ZW5zaW9ucyAoaW5jbHVkaW5nIHRoZSBzYW1wbGVzIGluIHNhbXBsZXMvZXh0ZW5zaW9ucyksIGJzZi5qYXIsIGFuZCBic2ZlbmdpbmVzLmphciBtdXN0IGJlIG9uIHRoZSAKLSAgICBjbGFzc3BhdGguIFRvIHJ1biBleHRlbnNpb25zIGltcGxlbWVudGVkIGluIEphdmFTY3JpcHQsIGpzLmphciBtdXN0IGFsc28gYmUgb24gdGhlIGNsYXNzcGF0aC4gRm9yIGluZm9ybWF0aW9uIG9uIHdoYXQgCi0gICAgeW91IG5lZWQgdG8gcnVuIGV4dGVuc2lvbnMgaW1wbGVtZW50ZWQgaW4gb3RoZXIgc2NyaXB0aW5nIGxhbmd1YWdlcywgc2VlIDxsaW5rIGlkcmVmPSJleHRlbnNpb25zIgotICAgIGFuY2hvcj0ic3VwcG9ydGVkLWxhbmciPlN1cHBvcnRlZCBsYW5ndWFnZXM8L2xpbms+Ljxici8+PGJyLz48L2xpPgotICAgIDxsaT5UbyBydW4gYXBwbGljYXRpb25zIHRoYXQgdXNlIHRoZSAmeHNsdDRqOyB2ZXJzaW9uIDEgQVBJLCB5b3UgbXVzdCBwdXQgeGFsYW5qMWNvbXBhdC5qYXIgb24gdGhlIGNsYXNzcGF0aCwgcmVjb21waWxlIHRoZSBhcHBsaWNhdGlvbiwKLSAgICBhbmQgYmUgc3VyZSB4YWxhbmoxY29tcGF0LmphciBpcyBvbiB0aGUgY2xhc3NwYXRoIGF0IHJ1biB0aW1lIChzZWUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0iY29tcGF0Ij5Vc2luZyB0aGUgJnhzbHQ0ajsgdmVyc2lvbiAxCi0gICAgQVBJKTwvbGluaz4uPC9saT4KLSAgICA8L29sPgotICAgIDxwPkZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgPGxpbmsgaWRyZWY9ImdldHN0YXJ0ZWQiIGFuY2hvcj0iY2xhc3NwYXRoIj5TZXR0aW5nIHVwIHRoZSBzeXN0ZW0gY2xhc3NwYXRoPC9saW5rPi48L3A+Ci0gICAgPHA+PGFuY2hvciBuYW1lPSJlbnZpcm9ubWVudGNoZWNrIi8+PGVtPlVzaW5nIHRoZSBFbnZpcm9ubWVudENoZWNrIHV0aWxpdHk6PC9lbT4gVG8gaGVscCBkaWFnbm9zZSBjbGFzc3BhdGggcHJvYmxlbXMsIHRyeSBydW5uaW5nIFhhbGFuJ3MgZW52aXJvbm1lbnQgY2hlY2tpbmcgdXRpbGl0eSwgY2hlY2tlZCBpbiBhdCAKLSAgICB4bWwteGFsYW4vamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0L0Vudmlyb25tZW50Q2hlY2suPC9wPgotICAgIDxwPllvdSBjYW4gcnVuIHRoaXMgdXRpbGl0eSBmcm9tIHRoZSBjb21tYW5kIGxpbmUgYXMgZm9sbG93czo8L3A+Ci0gICAgPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuRW52aXJvbm1lbnRDaGVjayBbLW91dCBvdXRGaWxlXTwvY29kZT48L3A+Ci0gICAgPHA+WW91IGNhbiBhbHNvIGNhbGwgdGhpcyB1dGlsaXR5IGZyb20gd2l0aGluIHlvdXIgYXBwbGljYXRpb24uIEZvciBleGFtcGxlLDwvcD4KLSAgICA8cD48Y29kZT5ib29sZWFuIGVudmlyb25tZW50T0sgPSAobmV3IEVudmlyb25tZW50Q2hlY2soKSkuY2hlY2tFbnZpcm9ubWVudCAoeW91clByaW50V3JpdGVyKTs8L2NvZGU+PC9wPgotICAgIDxwPkJlIHN1cmUgdG8gcnVuIEVudmlyb25tZW50Q2hlY2sgaW4gdGhlIGVudmlyb25tZW50IHdoZXJlIHlvdSBhcmUgZXhwZXJpZW5jaW5nIHRoZSBwcm9ibGVtLiBGb3IgZXhhbXBsZSwgaWYgeW91IGdldCBhIAotICAgIE5vQ2xhc3NEZWZGb3VuZCBlcnJvciBmcm9tIGEgY29tbWFuZC1saW5lIGFwcGxpY2F0aW9uLCBydW4gRW52aXJvbm1lbnRDaGVjayBvbiB0aGUgY29tbWFuZCBsaW5lIHdpdGggZXhhY3RseSB0aGUgc2FtZSAKLSAgICBjbGFzc3BhdGguIElmIHRoZSBlcnJvciBvY2N1cnMgaW5zaWRlIHlvdXIgSmF2YSBhcHBsaWNhdGlvbiAob3IgaW4gYSBzZXJ2bGV0LCBldGMuKSwgYmUgc3VyZSB0byBjYWxsIHRoZSAKLSAgICBFbnZpcm9ubWVudENoZWNrIGNoZWNrRW52aXJvbm1lbnQoLi4uKSBtZXRob2QgZnJvbSB3aXRoaW4geW91ciBydW5uaW5nIGFwcGxpY2F0aW9uLjwvcD4KLSAgICA8L2E+Ci0gICA8L2ZhcT4KLSAKLQk8ZmFxIHRpdGxlPSJTdHlsZXNoZWV0IHZhbGlkYXRpb24iPgotCQk8cT5Ib3cgZG8gSSB2YWxpZGF0ZSBhbiBYU0wgc3R5bGVzaGVldD88L3E+Ci0JCTxhPgotICAgICAgPHA+QW4gWFNMIHN0eWxlc2hlZXQgaXMgYW4gWE1MIGRvY3VtZW50LCBzbyBpdCBjYW4gaGF2ZSBhIERPQ1RZUEUgYW5kIGJlIHN1YmplY3QgdG8gdmFsaWRhdGlvbiwgcmlnaHQ/IDwvcD4KLSAgICAgIDxwPlRoZSBYU0xUIFJlY29tbWVuZGF0aW9uIGluY2x1ZGVzIGEgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCNkdGQiPkRURCBGcmFnbWVudCAKLSAgICAgIGZvciBYU0wgU3R5bGVzaGVldHM8L2p1bXA+IHdpdGggc29tZSBpbmRpY2F0aW9ucyBvZiB3aGF0IHlvdSBuZWVkIHRvIGRvIHRvIGNyZWF0ZSBhIGNvbXBsZXRlIERURCBmb3IgYSBnaXZlbgotICAgICAgc3R5bGVzaGVldC4gS2VlcCBpbiBtaW5kIHRoYXQgc3R5bGVzaGVldHMgY2FuIGluY2x1ZGUgbGl0ZXJhbCByZXN1bHQgZWxlbWVudHMgYW5kIHByb2R1Y2Ugb3V0cHV0IHRoYXQgaXMgbm90IHZhbGlkCi0gICAgICBYTUwuPC9wPgotICAgICAgPHA+WW91IGNhbiB1c2UgdGhlIHhzbDpzdHlsZXNoZWV0IGRvY3R5cGUgZGVmaW5lZCBpbiB4c2wtaHRtbDQwcy5kdGQgZm9yIHN0eWxlc2hlZXRzIHRoYXQgZ2VuZXJhdGUgSFRNTC48L3A+Ci0JCTwvYT4KLQk8L2ZhcT4KLSAgICAKLSAgICA8ZmFxIHRpdGxlPSJSZXRyaWV2aW5nIG5vZGVzIGluIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSI+Ci0gICAgIDxxPlhQYXRoIGlzbid0IHJldHJpZXZpbmcgbm9kZXMgdGhhdCBhcmUgaW4gdGhlIGRlZmF1bHQgbmFtZXNwYWNlIEkgZGVmaW5lZC4gSG93IGRvIEkgZ2V0IHRoZW0/PC9xPgotICAgICA8YT48cD5JZiB5b3UgYXJlIGxvb2tpbmcgZm9yIG5vZGVzIGluIGEgbmFtZXNwYWNlLCB0aGUgWFBhdGggZXhwcmVzc2lvbiBtdXN0IGluY2x1ZGUgYSBuYW1lc3BhY2UgcHJlZml4IHRoYXQgeW91IGhhdmUgbWFwcGVkIHRvIHRoZQotICAgICAgIG5hbWVzcGFjZSB3aXRoIGFuIHhtbG5zIGRlY2xhcmF0aW9uLiBJZiB5b3UgaGF2ZSBkZWNsYXJlZCBhIGRlZmF1bHQgbmFtZXNwYWNlLCBpdCBkb2VzIG5vdCBoYXZlIGEgcHJlZml4IChzZWUgCi0gICAgICAgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGguaHRtbCNub2RlLXRlc3RzIj5YUGF0aCBOb2RlIFRlc3RzPC9qdW1wPikuIEluIG9yZGVyIHRvIGNvbnN0cnVjdCBYUGF0aCBleHByZXNzaW9ucyAKLSAgICAgICB0byByZXRyaWV2ZSBub2RlcyBmcm9tIHRoaXMgbmFtZXNwYWNlLCB5b3UgbXVzdCBhZGQgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gdGhhdCBwcm92aWRlcyBhIHByZWZpeCB5b3UgY2FuIGluY2x1ZGUgaW4gdGhlIFhQYXRoCi0gICAgICAgIGV4cHJlc3Npb25zLjwvcD4KLSAgICAgICA8cD5TdXBwb3NlLCBmb3IgZXhhbXBsZSwgeW91IHlvdSB3YW50IHRvIGxvY2F0ZSBub2RlcyBpbiBhIGRlZmF1bHQgbmFtZXNwYWNlIGRlY2xhcmVkIGFzIGZvbGxvd3M6PGJyLz4KLSAgICAgICA8Y29kZT54bWxucz0iaHR0cDovL215LW5hbWVzcGFjZSI8L2NvZGU+PC9wPgotICAgICAgIDxwPkFkZCBhIG5hbXBlc3BhY2UgZGVjbGFyYXRpb24gd2l0aCBhIHByZWZpeDo8YnIvPgotICAgICAgIDxjb2RlPnhtbG5zOmZvbz0iaHR0cDovL215LW5hbWVzcGFjZSI8L2NvZGU+PC9wPiAgICAgICAKLSAgICAgICA8cD5UaGVuIHlvdSBjYW4gdXNlIGZvbzogaW4geW91ciBYUGF0aCBleHByZXNzaW9uLjwvcD4KLSAgICAgICA8cD5IaW50OiBEb24ndCB1c2UgZGVmYXVsdCBuYW1lc3BhY2VzLCBhbmQgdGhlIHByb2JsZW0gZG9lc24ndCBhcmlzZS48L3A+PC9hPgotICAgIDwvZmFxPgotICAgICAgIAotICAgIDxmYXEgdGl0bGU9IlVzaW5nIHRoZSAnc2lnbmF0dXJlJyBmaWxlIHRvIHZlcmlmeSBhIGRvd25sb2FkIj4KLSAgICAgIDxxPkhvdyBkbyBJIHVzZSB0aGUgInNpZ25hdHVyZSIgZmlsZSB0byB2ZXJpZnkgbXkgZG93bmxvYWQ/PC9xPgotICAgICAgPGE+Ci0gICAgICAgIDxwPkZvciBlYWNoIFhhbGFuIGRvd25sb2FkIGZpbGUgaW4gPHJlc291cmNlLXJlZiBpZHJlZj0ieHNsdDRqLWRpc3RkaXIiLz4sIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZyBzaWduYXR1cmUgZmlsZS4gCi0gICAgICAgIFRoZSBzaWduYXR1cmUgZmlsZSBmb3IgeGFsYW4tal8yXzBfMS50YXIuZ3osIGZvciBleGFtcGxlLCBpcyB4YWxhbi1qXzJfMF8xLnRhci5nei5zaWcuPC9wPgotICAgICAgICA8cD5UaGUgLnNpZyBmaWxlcyBhcmUgUEdQIHNpZ25hdHVyZXMgb2YgdGhlIGFjdHVhbCAuemlwIG9yIC50YXIuZ3oKLSAgICAgICAgZG93bmxvYWQgZmlsZXMuICBZb3UgY2FuIHVzZSB0aGVzZSBmaWxlcyB0byB2ZXJpZnkgdGhlIGF1dGhlbnRpY2l5IG9mIHRoZSBkb3dubG9hZC4gWW91IGRvIG5vdCBuZWVkIHRoZSAuc2lnIGZpbGUgdG8gCi0gICAgICAgIHVzZSB0aGUgY29ycmVzcG9uZGluZyBkb253bG9hZCBmaWxlLjwvcD4KLSAgICAgICAgPHA+VG8gY2hlY2sgdGhlIGF1dGhlbnRpY2l0eSBvZiBhIFhhbGFuIGRpc3RyaWJ1dGlvbiwgeW91IG5lZWQgYSBjb3B5IG9mCi0gICAgICAgIFBHUCB3aGljaCBpcyBhdmFpbGFibGUgaW4gYSBudW1iZXIgb2YgbGljZW5zZXMsIGluY2x1ZGluZyBzb21lIGZyZWUKLSAgICAgICAgbm9uLWNvbW1lcmNpYWwgbGljZW5zZXMsIGVpdGhlciBmcm9tIGFuIG1pdC5lZHUgc2l0ZSBvciBvbgotICAgICAgICB0aGUgcGdwLmNvbSBzaXRlLiBPbmNlIHlvdSBoYXZlIGEgdmVyc2lvbiBvZiBQR1AgaW5zdGFsbGVkLCB5b3UKLSAgICAgICAgc2hvdWxkIGJlIGFibGUgdG8gJ3ZlcmlmeSB0aGUgc2lnbmF0dXJlJyBvZiB0aGUgLnNpZyBmaWxlLCB3aGljaCBiYXNpY2FsbHkgdmVyaWZpZXMgdGhhdCB0aGUgY29ycmVzcG9uZGluZyAKLSAgICAgICAgLnppcCBvciB0YXIuZ3ogZmlsZSBoYXMgbm90IGJlZW4gY2hhbmdlZCBzaW5jZSB3ZSBzaWduZWQgaXQuPC9wPgotICAgICAgPC9hPgotICAgIDwvZmFxPgotICAgIDxmYXEgdGl0bGU9IlNldHRpbmcgb3V0cHV0IGVuY29kaW5nIj4KLSAgICA8cT5XaHkgaXMgdGhlIG91dHB1dCBjaGFyYWN0ZXIgZW5jb2RpbmcgSSBzZXQgaW4gdGhlIHN0eWxlc2hlZXQgbm90IGJlaW5nIHVzZWQ/PC9xPgotICAgIDxhPgotICAgIDxwPklmIHlvdSB1c2UgYSBjaGFyYWN0ZXIgb3V0cHV0IHN0cmVhbSB0byBpbnN0YW50aWF0ZSB0aGUgCi0gICAgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1SZXN1bHQuaHRtbCI+U3RyZWFtUmVzdWx0PC9qdW1wPiBvYmplY3Qgd2hpY2ggaG9sZHMgdGhlIAotICAgIHRyYW5zZm9ybWF0aW9uIG91dHB1dCwgdGhlIFdyaXRlciB1c2VzIGl0cyBvd24gZW5jb2RpbmcsIG5vdCB0aGUgZW5jb2RpbmcgeW91IHNwZWNpZnkKLSAgICBpbiB0aGUgc3R5bGVzaGVldC48L3A+Ci0gICAgPHA+SWYgeW91IHdhbnQgdG8gdXNlIHRoZSBzdHlsZXNoZWV0IG91dHB1dCBlbmNvZGluZywgZG8gbm90IHVzZSBTdHJlYW1SZXN1bHQoamF2YS5pby5Xcml0ZXIpIHRvCi0gICAgaW5zdGFudGlhdGUgdGhlIGhvbGRlciBmb3IgdGhlIG91dHB1dC4gQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBzcGVjaWZ5IHRoZSBlbmNvZGluZyB3aGVuIHlvdSBjcmVhdGUgYSBXcml0ZXIgCi0gICAgKGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyKS4gT25jZSB0aGUgV3JpdGVyIGV4aXN0cywgeW91IGNhbm5vdCBjaGFuZ2UgaXRzIGVuY29kaW5nLjwvcD4KLSAgICA8L2E+Ci0gICAgPC9mYXE+Ci0gICAgPGZhcSB0aXRsZT0iU2VydmxldCB1bmFibGUgdG8gZmluZCBjbGFzc2VzIGZvciBleHRlbnNpb24gZnVuY3Rpb25zL2VsZW1lbnRzIj4KLSAgICA8cT5NeSBzZXJ2bGV0IGNhbm5vdCBmaW5kIGNsYXNzZXMgdGhhdCBpbXBsZW1lbnQgZXh0ZW5zaW9uIGZ1bmN0aW9ucyBvciBlbGVtZW50cy4gV2hhdCBjYW4gSSBkbz88L3E+Ci0gICAgPGE+Ci0gICAgPHA+SWYgeW91IGluc3RhbGwgeGFsYW4uamFyIGluIHRoZSBzZXJ2bGV0IGVuZ2luZSdzIGxpYiBkaXJlY3RvcnkgKGUuZy4sIHRvbWNhdC9saWIpLCBhcyBvcHBvc2VkIHRvIHRoZSBzZXJ2bGV0J3MgCi0gICAgbGliIGRpcmVjdG9yeSwgdGhlbiB0aGUgWGFsYW4gY2xhc3NlcyBhcmUgbG9hZGVkIGJ5IGEgY2xhc3Nsb2FkZXIgdGhhdCBkb2VzIG5vdCBzZWUgdGhlIGNsYXNzZXMgaW4gdGhlIHNlcnZsZXQncwotICAgIGNsYXNzbG9hZGVyIChpLmUuLCB0aGUgZXh0ZW5zaW9uIGNsYXNzZXMsIGlmIHlvdSBwbGFjZWQgdGhlbSB0aGVyZSkuIFRoZSBYYWxhbiBjbGFzc2VzIHRyeSB0byBsb2FkIHRoZSBleHRlbnNpb24gCi0gICAgY2xhc3NlcyB1c2luZyB0aGVpciBvd24gY2xhc3Nsb2FkZXIsIGFuZCB0aGF0IGF0dGVtcHQgZmFpbHMuPC9wPgotICAgIDxwPldvcmthcm91bmQ6IHBsYWNlIHhhbGFuLmphciBpbiB0aGUgc2VydmxldCdzIGxpYiBkaXJlY3RvcnkgYW5kIE5PVCBpbiB0aGUgc2VydmxldCBlbmdpbmUncyBsaWIgZGlyZWN0b3J5LiAKLSAgICBBbm90aGVyIHdvcmthcm91bmQgaXMgdG8gcGxhY2UgdGhlIGV4dGVuc2lvbiBjbGFzc2VzIGFsc28gaW4gdGhlIHNlcnZsZXQgZW5naW5lJ3MgbGliIGRpcmVjdG9yeSwgYnV0IHlvdQotICAgIGdlbmVyYWxseSB3YW50IHRvIGF2b2lkIGNsdXR0ZXJpbmcgdGhhdCBkaXJlY3RvcnkuPC9wPgotICAgIDxwPlRoYW5rcyB0byBHdW5ubGF1Z2VyIFRob3IgQnJpZW0gKGd0aGJAZGltb24uaXMpIGZvciBwcm92aWRpbmcgdGhpcyBpbmZvcm1hdGlvbi4gPC9wPgotICAgIDwvYT4KLSAgPC9mYXE+Ci0gIDxmYXEgdGl0bGU9Ik5hbWVzcGFjZSBub3Qgc3VwcG9ydGVkIGJ5IFNBWFBhcnNlciI+Ci0gIDxxPldoeSBhbSBJIGdldHRpbmcgYSAiTmFtZXNwYWNlIG5vdCBzdXBwb3J0ZWQgYnkgU0FYUGFyc2VyIGV4Y2VwdGlvbj88L3E+Ci0gIDxhPgotICA8cD5XZSBoYXZlIHNlZW4gdGhpcyBwcm9iZW0gYXJpc2UgZm9yIHR3byBxdWl0ZSBkaWZmZXJlbnQgcmVhc29uczo8L3A+Ci0gIDx1bD4KLSAgPGxpPlNBWDEgaW50ZXJmYWNlcyBhcmUgb24geW91ciBjbGFzc3BhdGggaW4gZnJvbnQgb2YgdGhlIFNBWDIgaW50ZXJmYWNlcyBwcm92aWRlZCB3aXRoIHlvdXIgWE1MCi0gIHBhcnNlci48YnIvPjxici8+Ci0gIG9yPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5UaGUgcGFyc2VyIHlvdSBhcmUgdXNpbmcgdG8gcHJvY2VzcyBhIHN0eWxlc2hlZXQgU291cmNlIGFuZCBnZW5lcmF0ZSBhIFRyYW5zZm9ybWVyIGRvZXMgbm90IGhhdmUgdGhlIAotICBuYW1lc3BhY2VBd2FyZSBwcm9wZXJ0eSBzZXQgdG8gdHJ1ZS48L2xpPgotICA8L3VsPgotICA8cD48ZW0+U0FYMSBvbiB0aGUgY2xhc3NwYXRoPC9lbT48L3A+Ci0gIDxwPlNBWDEgc2hvdWxkIG5vdCBiZSBvbiB5b3VyIGNsYXNzcGF0aC4gVGhlIFNBWDEgaW50ZXJmYWNlcyBhbmQgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBTQVgxIFNBWFBwYXJzZXIKLSAgYXJlIG5vdCBuYW1lc3BhY2UgYXdhcmUuPC9wPgotICA8cD5UbyBoZWxwIGRpYWdub3NlIHlvdXIgY2xhc3NwYXRoLCB5b3UgY2FuIHVzZSB0aGUgPGxpbmsgYW5jaG9yPSJlbnZpcm9ubWVudGNoZWNrIj5FbnZpcm9ubWVudENoZWNrCi0gIHV0aWxpdHk8L2xpbms+LiBJZiB5b3UgYXJlIHJ1bm5pbmcgdW5kZXIgSkRLIDEuMywgc2VlIDxsaW5rIGFuY2hvcj0iamRrMTMiPklzc3VlcyBydW5uaW5nIFhhbGFuIG9uIEpESwotICAxLjM8L2xpbms+LiBJZiB5b3UgYXJlIHJ1bm5pbmcgYSBzZXJ2bGV0LCBtYWtlIHN1cmUgdGhlIHNlcnZsZXQgZW5naW5lIGlzIG5vdCBwbGFjaW5nIFNBWDEgb24gdGhlCi0gIGNsYXNzcGF0aC48L3A+Ci0gIDxwPjxlbT5TZXR0aW5nIHRoZSBwYXJzZXIgdG8gYmUgbmFtZXNwYWNlIGF3YXJlPC9lbT48L3A+Ci0gIDxwPldoZW4geW91IGNyZWF0ZSBhIFRyYW5zZm9ybWVyLCB5b3UgbXVzdCB1c2UgYSBuYW1lc3BhY2UtYXdhcmUgcGFyc2VyIHRvIHBhcnNlIHRoZSBzdHlsZXNoZWV0LjwvcD4KLSAgPHA+SWYgeW91IHVzZSBhIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBwcm9jZXNzIGEgc3R5bGVzaGVldCBTb3VyY2UgYW5kIGdlbmVyYXRlIGEgVHJhbnNmb3JtZXIsIHRoZQotICBUcmFuc2Zvcm1lckZhY3RvcnkgaW5zdHJ1Y3RzIHRoZSAgU0FYUGFyc2VyRmFjdG9yeSB0byBzZXQgdGhlIHBhcnNlcidzIG5hbWVzcGFjZUF3YXJlIHByb3BlcnR5IHRvIHRydWUuCi0gIEJ1dCBpZiB5b3UgY2FsbCB0aGUgcGFyc2VyIGRpcmVjdGx5LCB5b3UgbWF5IG5lZWQgdG8gc2V0IHRoZSBuYW1lc3BhY2VBd2FyZSBwcm9wZXJ0eSB5b3Vyc2VsZi4gRm9yCi0gIGV4YW1wbGU6PC9wPgotPHNvdXJjZT5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5IHNwRmFjdG9yeSA9Ci0gIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLXNwRmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZSh0cnVlKTs8L3NvdXJjZT4KLTxub3RlPkZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHNldHRpbmcgdGhlIG5hbWVzcGFjZUF3YXJlIHByb3BlcnR5LCBhbmQgU0FYMiB2cy4gSkFYUCBkZWZhdWx0IHNldHRpbmdzLCBzZWUgPGp1bXAgaHJlZj0iaHR0cDovL3htbC5hcGFjaGUub3JnL35lZHdpbmdvL2pheHAtZmFxLmh0bWwjbnNEZWZhdWx0cyI+SkFYUCBGQVE6IFdhcm5pbmcgYWJvdXQgbmFtZXNwYWNlIHByb2Nlc3NpbmcgZGVmYXVsdHM8L2p1bXA+Ljwvbm90ZT4KLTwvYT4KLTwvZmFxPgotPC9mYXFzPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi9nZXRzdGFydGVkLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vZ2V0c3RhcnRlZC54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2NDk1YTUuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94YWxhbi9nZXRzdGFydGVkLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDYzICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4gIAotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci0KLTxzMSB0aXRsZT0iR2V0dGluZyBTdGFydGVkIj4KLTx1bD4KLTxsaT48bGluayBhbmNob3I9ImRvd25sb2FkIj5Eb3dubG9hZGluZyB3aGF0IHlvdSBuZWVkPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJjbGFzc3BhdGgiPlNldHRpbmcgdXAgdGhlIHN5c3RlbSBjbGFzc3BhdGg8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InNhbXBsZXMiPlRyeWluZyBvdXQgdGhlIHNhbXBsZXM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImNvbW1hbmRsaW5lIj5QZXJmb3JtaW5nIHlvdXIgb3duIHRyYW5zZm9ybWF0aW9ucyBmcm9tIHRoZSBjb21tYW5kIGxpbmU8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImphdmEtYXBwcyI+U2V0dGluZyB1cCB5b3VyIG93biBYU0xUIGFwcGxpY2F0aW9uczwvbGluaz48L2xpPgotPC91bD4KLTxhbmNob3IgbmFtZT0iZG93bmxvYWQiLz4KLTxzMiB0aXRsZT0iRG93bmxvYWRpbmcgd2hhdCB5b3UgbmVlZCI+Ci08cD5UbyB1c2UgWGFsYW4sIHlvdSBuZWVkIHRoZSBmb2xsb3dpbmc6PC9wPgotPHVsPgotPGxpPlRoZSBKREsgb3IgSlJFIDEuMS44LCAxLjIuMiwgb3IgMS4zPC9saT4KLTxsaT54YWxhbi5qYXI8L2xpPgotPGxpPnhlcmNlcy5qYXIgKG9yIGFub3RoZXIgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0icGx1ZyI+WE1MIFBhcnNlcjwvbGluaz4pPC9saT4KLTwvdWw+Ci08cD5Zb3UgY2FuIGdldCB0aGUgSkRLIG9yIEpSRSBmcm9tIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cuaWJtLmNvbS9qYXZhL2pkayI+aWJtLmNvbS9qYXZhL2pkay88L2p1bXA+IG9yIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cuamF2YS5zdW4uY29tIj5qYXZhLnN1bi5jb208L2p1bXA+LjwvcD4gCi08cD5Eb3dubG9hZCA8cmVzb3VyY2UtcmVmIGlkcmVmPSJ4c2x0NGotZGlzdC16aXAiLz4gb3IgPHJlc291cmNlLXJlZiBpZHJlZj0ieHNsdDRqLWRpc3QtdGFyZ3oiLz4uIEJvdGggb2YgdGhlc2UgZmlsZXMgY29udGFpbiA8cmVzb3VyY2UtcmVmIGlkcmVmPSJ4c2x0NGotY3VycmVudCIvPiAod2l0aCB4YWxhbi5qYXIpIGFuZCB4ZXJjZXMuamFyIGZyb20gPHJlc291cmNlLXJlZiBpZHJlZj0ieG1sNGotdXNlZCIvPi4gWW91IGNhbiB1c2UgYSB6aXAgb3IgdGFyIHV0aWxpdHkgdG8gZXhwYW5kIHRoZXNlIGZpbGVzIGludG8gYSBmdWxsIGJ1aWxkLjwvcD4KLQotPHA+SWYgeW91IHBsYW4gdG8gcnVuIDxsaW5rIGlkcmVmPSJleHRlbnNpb25zIj5YU0xUIGV4dGVuc2lvbnM8L2xpbms+LCB5b3UgbmVlZCBic2YuamFyLCB3aGljaCBpcyBpbmNsdWRlZCBpbiB0aGUgJnhzbHQ0ajsgZGlzdHJpYnV0aW9uLiBJZiB5b3UgcGxhbiB0byBydW4gWFNMVCBleHRlbnNpb25zIGltcGxlbWVudGVkIGluIEphdmFzY3JpcHQgb3IgYW5vdGhlciBzY3JpcHRpbmcgbGFuZ3VhZ2UsIHlvdSB3aWxsIG5lZWQgb25lIG9yIG1vcmUgYWRkaXRpb25hbCBmaWxlcyBhcyBpbmRpY2F0ZWQgaW4gPGxpbmsgaWRyZWY9ImV4dGVuc2lvbnMiIGFuY2hvcj0ic3VwcG9ydGVkLWxhbmciPmV4dGVuc2lvbnMgbGFuZ3VhZ2UgcmVxdWlyZW1lbnRzPC9saW5rPi48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iY2xhc3NwYXRoIi8+Ci08czIgdGl0bGU9IlNldHRpbmcgdXAgdGhlIHN5c3RlbSBjbGFzc3BhdGgiPgotPHA+QXQgdGhlIHZlcnkgbWluaW11bSwgeW91IG11c3QgaW5jbHVkZSB4YWxhbi5qYXIgYW5kIHhlcmNlcy5qYXIgKG9yIGFub3RoZXIgY29uZm9ybWFudCBYTUwgcGFyc2VyIC0tIHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJwbHVnIj5QbHVnZ2luZyBpbiBhIFRyYW5zZm9ybWVyIGFuZCBYTUwgcGFyc2VyPC9saW5rPikgb24gdGhlIHN5c3RlbSBjbGFzc3BhdGguIFRvIHJ1biB0aGUgc2FtcGxlIGFwcGxpY2F0aW9ucywgaW5jbHVkZSB4YWxhbnNhbXBsZXMuamFyIChhbGwgc2FtcGxlcyBvdGhlciB0aGFuIHRoZSBzZXJ2bGV0KSBhbmQgeGFsYW5zZXJ2bGV0Lmphci4gVG8gcnVuIGV4dGVuc2lvbnMsIGluY2x1ZGUgYnNmLmphci4gQWxsIHRoZXNlIEpBUiBmaWxlcyBhcmUgZGlzdHJpYnV0ZWQgd2l0aCAmeHNsdDRqOy4gRm9yIGV4dGVuc2lvbnMgaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdCBvciBhbm90aGVyIHNjcmlwdGluZyBsYW5ndWFnZSwgc2VlIDxsaW5rIGlkcmVmPSJleHRlbnNpb25zIiBhbmNob3I9InN1cHBvcnRlZC1sYW5nIj5leHRlbnNpb25zIGxhbmd1YWdlIHJlcXVpcmVtZW50czwvbGluaz4gdG8gaWRlbnRpZnkgYW55IGFkZGl0aW9uYWwgSkFSIGZpbGVzIHlvdSBtdXN0IHBsYWNlIG9uIHRoZSBjbGFzc3BhdGggYW5kIHdoZXJlIHlvdSBjYW4gZ2V0IHRoZW0uPC9wPgotPHA+SWYgeW91IGFyZSB1c2luZyBKREsgb3IgSlJFIDEuMS44LCBhbHNvIGluY2x1ZGUgY2xhc3Nlcy56aXAgb24gdGhlIGNsYXNzcGF0aC4gSWYgeW91IGFyZSB1c2luZyBKREsgb3IgSlJFIDEuMiwgaW5jbHVkZSB0b29scy5qYXIgb24gdGhlIGNsYXNzcGF0aC48L3A+Ci08bm90ZT5JZiB5b3UgYXJlIHJ1bm5pbmcgWGFsYW4gb24gYSAxLjEuOCBwbGF0Zm9ybSBvciByZWNvbXBpbGluZyBYYWxhbiBvbiBhbnkgcGxhdGZvcm0sIGJlIHN1cmUgdG8gcHV0IHhhbGFuLmphciBpbiBmcm9udCBvZiB4ZXJjZXMuamFyIG9uIHRoZSBjbGFzc3BhdGguIEJvdGggSkFSIGZpbGVzIGluY2x1ZGUgdGhlIG9yZy53M2MuZG9tIHBhY2thZ2VzLiBYZXJjZXMgaGFzIGFkZGVkIGEgbnVtYmVyIG9mIERPTSBsZXZlbC0zIG1ldGhvZHMuIFRoZXNlIGFyZSBub3QgeWV0IHBhcnQgb2YgdGhlIFczQyBET00gcmVjb21tZW5kYXRpb24sIGFuZCBYYWxhbiBkb2VzIG5vdCBzdXBwb3J0IHRoZXNlIG1ldGhvZHMuPC9ub3RlPgotPC9zMj48YW5jaG9yIG5hbWU9InNhbXBsZXMiLz4KLTxzMiB0aXRsZT0iVHJ5aW5nIG91dCB0aGUgc2FtcGxlcyI+Ci08cD5UaGUgJnhzbHQ0ajsgZGlzdHJpYnV0aW9uIGluY2x1ZGVzIGEgbnVtYmVyIG9mIGJhc2ljIHNhbXBsZSBhcHBsaWNhdGlvbnMuIFRoZXNlIHNhbXBsZXMgYXJlIGVhc3kgdG8gcnVuLCBhbmQgeW91IGNhbiByZXZpZXcgdGhlIHNvdXJjZSBmaWxlcyAtLSBhbGwgb2Ygd2hpY2ggYXJlIGJyaWVmIC0tIHRvIHNlZSBqdXN0IGhvdyB0aGV5IHdvcmsuPC9wPgotPHA+VG8gcnVuIHRoZSBzYW1wbGVzLCBkbyB0aGUgZm9sbG93aW5nOjwvcD4KLTxvbD4KLTxsaT5TZXQgdXAgeW91ciBjbGFzc3BhdGggKHNlZSBhYm92ZSksIGluY2x1ZGluZyB4YWxhbnNhbXBsZXMuamFyIGFuZCAoZm9yIHRoZSBzZXJ2bGV0KSB4YWxhbnNlcnZsZXQuamFyLjwvbGk+Ci08bGk+QmUgc3VyZSB0aGUgamF2YSBleGVjdXRhYmxlIGlzIG9uIHlvdXIgcGF0aC48L2xpPgotPGxpPkdvIHRvIHRoZSBzYW1wbGVzIHN1YmRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBzYW1wbGUgKHVzZSB0aGUgRE9TIHNoZWxsIGlmIHlvdSBhcmUgcnVubmluZyBXaW5kb3dzKS48L2xpPgotPGxpPlVzZSB0aGUgamF2YSBleGVjdXRhYmxlIHRvIHJ1biB0aGUgc2FtcGxlIGZyb20gdGhlIGNvbW1hbmQgbGluZS48L2xpPgotPGxpPkV4YW1pbmUgdGhlIGFwcGxpY2F0aW9uIHNvdXJjZSBhbmQgcmVzdWx0IGZpbGVzLjwvbGk+Ci08L29sPgotPHA+Rm9yIGV4YW1wbGUsIGdvIHRvIHRoZSBTaW1wbGVUcmFuc2Zvcm0gc3ViZGlyZWN0b3J5IGFuZCBpc3N1ZSB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6PC9wPgotPHA+PGNvZGU+amF2YSBTaW1wbGVUcmFuc2Zvcm08L2NvZGU+PC9wPgotPHA+VGhlIHNhbXBsZSB3cml0ZXMgdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdCAgdG8gYSBmaWxlIChiaXJkcy5vdXQpLiBUbyBzZWUgaG93IHRoZSBleGFtcGxlIHdvcmtzLCBleGFtaW5lIHRoZSBzb3VyY2UgZmlsZXM6IGJpcmRzLnhtbCwgYmlyZHMueHNsLCBhbmQgU2ltcGxlVHJhbnNmb3JtLmphdmEuPC9wPgotPHA+VGhlIGV4dGVuc2lvbnMgZXhhbXBsZXMgcmVxdWlyZSBhZGRpdGlvbmFsIEpBUiBmaWxlcyBvbiB0aGUgY2xhc3NwYXRoLCBhbmQgdGhlIHByb2NlZHVyZSBmb3IgcnVubmluZyB0aGUgc2FtcGxlIGFwcGxldCBhbmQgc2FtcGxlIHNlcnZsZXQgaXMgZGlmZmVyZW50LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBhbGwgdGhlIHNhbXBsZXMsIHNlZSA8bGluayBpZHJlZj0ic2FtcGxlcyI+JnhzbHQ0ajsgU2FtcGxlczwvbGluaz4uPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9ImNvbW1hbmRsaW5lIi8+Ci08czIgdGl0bGU9IlBlcmZvcm1pbmcgeW91ciBvd24gdHJhbnNmb3JtYXRpb25zIGZyb20gdGhlIGNvbW1hbmQgbGluZSI+Ci08cD5qYXZhLm9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzIHByb3ZpZGVzIGEgYmFzaWMgdXRpbGl0eSBmb3IgcGVyZm9ybWluZyB0cmFuc2Zvcm1hdGlvbnMgZnJvbSB0aGUgY29tbWFuZCBsaW5lLiBZb3UgdXNlIHRoaXMgdXRpbGl0eSwgZm9yIGV4YW1wbGUsIHRvIHJ1biBzZXZlcmFsIG9mIHRoZSBleHRlbnNpb25zIHNhbXBsZXMuIFRoZSBjb21tYW5kIGxpbmUgZm9yIG1vc3Qgc3RhbmRhcmQgdHJhbnNmb3JtYXRpb25zIGlzIGFzIGZvbGxvd3M6PC9wPgotPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyAtaW4gPHJlZj54bWxTb3VyY2U8L3JlZj48L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOy14c2wgPHJlZj5zdHlsZXNoZWV0PC9yZWY+IC1vdXQgPHJlZj5vdXRwdXRmaWxlPC9yZWY+PC9jb2RlPjwvcD4KLTxwPndoZXJlIDxyZWY+eG1sU291cmNlPC9yZWY+IGlzIHRoZSBYTUwgc291cmNlIGZpbGUgbmFtZSwgPHJlZj5zdHlsZXNoZWV0PC9yZWY+IGlzIHRoZSBYU0wgc3R5bGVzaGVldCBmaWxlIG5hbWUsIGFuZCA8cmVmPm91dHB1dGZpbGU8L3JlZj4gaXMgdGhlIG91dHB1dCBmaWxlIG5hbWUuPC9wPgotPHA+SWYgeW91IHdhbnQgdGhlIG91dHB1dCB0byBiZSBkaXNwbGF5ZWQgb24gdGhlIHNjcmVlbiwgc2ltcGx5IG9taXQgdGhlIC1vdXQgZmxhZyBhbmQgYXJndW1lbnQuPC9wPgotPHA+WW91IGNhbiB1c2UgdGhpcyB1dGlsaXR5IHRvIHRyeSBvdXQgWFNMIHN0eWxlc2hlZXRzIHlvdSBoYXZlIHdyaXR0ZW4sIHRvIG1ha2Ugc3VyZSB0aGV5IGRvIHdoYXQgeW91IGV4cGVjdCB3aXRoIHRoZSBYTUwgc291cmNlIGZpbGVzIHRoZXkgYXJlIGRlc2lnbmVkIHRvIHRyYW5zZm9ybS4gVGhlIHV0aWxpdHkgcHJvdmlkZXMgdXNlZnVsIG1lc3NhZ2VzIGlmIHRoZSBzb3VyY2UgZmlsZSBvciBzdHlsZXNoZWV0IGlzIG5vdCB3ZWxsIGZvcm1lZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSA8bGluayBpZHJlZj0iY29tbWFuZGxpbmUiPkNvbW1hbmQtTGluZSBVdGlsaXR5PC9saW5rPi48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iamF2YS1hcHBzIi8+Ci08czIgdGl0bGU9IlNldHRpbmcgdXAgeW91ciBvd24gSmF2YSBhcHBsaWNhdGlvbnMiPgotPHA+WW91IGNhbiBzdGFydCBieSB1c2luZyB5b3VyIG93biBYTUwgc291cmNlIGZpbGVzIGFuZCBYU0wgc3R5bGVzaGVldHMgd2l0aCB0aGUgc2FtcGxlIGFwcGxpY2F0aW9ucywgd2hpY2ggaWxsdXN0cmF0ZSBhIG51bWJlciBvZiB0aGUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiPmJhc2ljIHVzYWdlIHBhdHRlcm5zPC9saW5rPi48L3A+Ci08cD5IZXJlIGlzIHRoZSBiYXNpYyBUUmFYIHByb2NlZHVyZSB0byBrZWVwIGluIG1pbmQgd2hlbiB5b3Ugc2V0IHVwIGEgdHJhbnNmb3JtYXRpb246PC9wPgotPG9sPgotPGxpPlVzZSB0aGUgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyRmFjdG9yeS5odG1sIj5UcmFuc2Zvcm1lckZhY3Rvcnk8L2p1bXA+IHN0YXRpYyBuZXdJbnN0YW5jZSgpIG1ldGhvZCB0byBpbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyRmFjdG9yeS48YnIvPjxici8+PC9saT4KLTxsaT5Vc2UgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBuZXdUcmFuc2Zvcm1lcihTb3VyY2Ugc3R5bGVzaGVldCkgbWV0aG9kIHRvIHByb2Nlc3MgdGhlIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyBpbiBhbiBYU0xUIHN0eWxlc2hlZXQgU291cmNlIChwcm9kdWNpbmcgdW5kZXIgdGhlIGNvdmVycyBhIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UZW1wbGF0ZXMuaHRtbCI+VGVtcGxhdGVzPC9qdW1wPiBvYmplY3QpIGFuZCBnZW5lcmF0ZSBhIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lci5odG1sIj5UcmFuc2Zvcm1lcjwvanVtcD4uPGJyLz48YnIvPjwvbGk+Ci08bGk+VXNlIHRoZSBUcmFuc2Zvcm1lciB0cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IHRyYW5zZm9ybVJlc3VsdCkgbWV0aG9kIHRvIGFwcGx5IHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMgKHRoZSBUZW1wbGF0ZXMgb2JqZWN0KSB0byB0aGUgWE1MIFNvdXJjZSBhbmQgcHJvZHVjZSB0aGUgdHJhbnNmb3JtYXRpb24gUmVzdWx0Ljxici8+PGJyLz48L2xpPgotPC9vbD4KLTxwPkZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgcHJvY2VkdXJlIGFuZCBpdHMgdmFyaWF0aW9ucywgc2VlIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIj5CYXNpYyBVc2FnZSBQYXR0ZXJuczwvbGluaz4uPC9wPgotPC9zMj4KLTwvczE+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi9oaXN0b3J5LnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vaGlzdG9yeS54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDQxOTY3MjEuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94YWxhbi9oaXN0b3J5LnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDE0MDcgKzAsMCBAQAotPHMzIHRpdGxlPSJDaGFuZ2VzIGZvciAmeHNsdDRqOyAyLjIuRDkiPgotPHA+IENvcmUgKE5vbi1YU0xUQykgc291cmNlIGNvZGUgdXBkYXRlczo8L3A+Ci08dWw+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzIFhTTFRJbmZvLnByb3BlcnRpZXM8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj4yLjIuRDg8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgWFNMUHJvY2Vzc29yVmVyc2lvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Mi4yLkQ4PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIE5vZGVTb3J0S2V5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5TdWJtaXR0ZWQgZml4IGZvciBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTI4NTEuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SnVzdCBhZGRlZCBzb21lIHN0dWZmIHRvIGRpYWdub3NlIGJ1Z3MgZm9yIGZsYXZvciB0aC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBXYWxrZXJGYWN0b3J5LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyIENvbXBpbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zCi0gQ29udGV4dE1hdGNoU3RlcFBhdHRlcm4uamF2YSBTdGVwUGF0dGVybi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VGhlc2UgYXJlIGNoYW5nZXMgc3VibWl0dGVkIChvZmZsaW5lKSBieSBNdWt1bmQgUmFnaGF2YWNoYXJpL1dhdHNvbi9JQk1ASUJNVVMuCi0KLSBUaGlzIGZpeGVzIGEgYnVnIHdpdGggbWF0Y2g9ImNoYXB0ZXIvL2Zvb3Rub3RlWzFdIiBwYXR0ZXJucy4KLQotIFRoZSBtYWluIGNoYW5nZSBoZXJlIGlzIG1pbm9yIHRvIHJlbW92ZSB0aGUgYXV0b21hdGljIGF0dGFjaG1lbnQgb2YgcGFyZW50OjoqIAotdG8gc2ltcGxlIHN0ZXAgcGF0dGVybnMuCi0KLSBIZSBoYXMgcmUtaW1wbGVtZW50ZWQgZXhlY3V0ZVByZWRpY2F0ZXMgdG8gYmUKLSBtb3JlIGVmZmljaWVudC4gR2l2ZW4gYSBwYXR0ZXJuIHN1Y2ggYXMgcm93WzZdLCBpdAotIGRvZXMgbm90IGl0ZXJhdGUgb3ZlciB0aGUgZW50aXJlIGF4aXMgdW50aWwgaXQgcmVhY2hlcwotIHRoZSBub2RlIHRvIHNlZSBpZiBpdCBpcyB0aGUgc2l4dGggbm9kZS4gUmF0aGVyLAotIHN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnQgbm9kZSwgaXQgd29ya3MgYmFja3dhcmRzCi0gKHByZWNlZGluZyBzaWJsaW5ncykgdW50aWwgaXQgZWl0aGVyIHJ1bnMgb3V0IG9mIG5vZGVzCi0gb3IgZmluZHMgbW9yZSB0aGFuIHNpeCBub2RlcyB0aGF0IG1hdGNoIHRoZQotIHByZWRpY2F0ZSBbSSBjYW4gZXhwbGFpbiBpdCBiZXR0ZXIgaWYgZGVzaXJlZF0uCi0gVGhpcyBvcHRpbWl6YXRpb24gaW1wcm92ZXMgcGVyZm9ybWFuY2Ugc2xpZ2h0bHkKLSBvdmVyYWxsLiBJdCBoZWxwcyBkZWNveSBhbmQgcGF0dGVybnMgbW9zdCAoYnkKLSBhYm91dCAxMCUpLgotCi0gVGhlIG90aGVyIG9wdGltaXphdGlvbiB0aGF0IEkgaW1wbGVtZW50ZWQgd2FzIHRoZQotIGZvbGxvd2luZy4gRm9yIGEgcGF0dGVybiBmb29bXVszXVtdWzRdIC4uLiwgd2hlcmUgbW9yZQotIHRoYW4gb25lIHByZWRpY2F0ZSBpcyBhIG51bWJlciAocG9zaXRpb24gY2hlY2spLAotIGluIGNoZWNraW5nIHRoZSBwcmVkaWNhdGUgWzRdLCB0aGUgZmFjdCB0aGF0IHRoZQotIGN1cnJlbnQgbm9kZSBoYXMgcGFzc2VkIGZvb1tdWzNdIGltcGxpZXMgdGhhdCBpdCBpcwotIHRoZSBvbmx5IG5vZGUgdGhhdCBpcyB0aGUgdGhpcmQgbm9kZSBhbW9uZyBpdHMKLSBzaWJsaW5ncyB0aGF0IHBhc3NlcyBmb29bXS4gVGhlcmVmb3JlLCBhbnkKLSBzdWJzZXF1ZW50IHBvc2l0aW9uIGNoZWNrcyBjYW4gYmUgdHJ1ZSBpZiBhbmQKLSBvbmx5IGlmIHRoZSBwb3NpdGlvbiBpcyBbMV0uIFRoaXMgb3B0aW1pemF0aW9uIGlzIG5vdAotIHVzZWQgYnkgdGhlIHhzbHRtYXJrIGJlbmNobWFya3MgYW5kIHNvIGRvZXMKLSBub3Qgb2ZmZXIgYW55IHBlcmZvcm1hbmNlIGJlbmVmaXRzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIERlc2NlbmRhbnRJdGVyYXRvci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTEzMzY8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIgTGV4ZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlJlc2l6ZSB0aGUgbV9wYXR0ZXJuTWFwIGlmIG1fcGF0dGVybk1hcFNpemUgZXhjZWVkcyB0aGUgYm91bmRzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zCi0gRXh0ZW5zaW9uSGFuZGxlckdlbmVyYWwuamF2YQotIEV4dGVuc2lvbkhhbmRsZXJKYXZhUGFja2FnZS5qYXZhCi0gRXh0ZW5zaW9uc1RhYmxlLmphdmEgTWV0aG9kUmVzb2x2ZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliIEV4dGVuc2lvbnMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBDb25uZWN0aW9uUG9vbE1hbmFnZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFByb2Nlc3NvckxSRS5qYXZhCi0gUHJvY2Vzc29yVGVtcGxhdGVFbGVtLmphdmEgU3R5bGVzaGVldEhhbmRsZXIuamF2YQotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YSBYU0xUQXR0cmlidXRlRGVmLmphdmEKLSBYU0xURWxlbWVudFByb2Nlc3Nvci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMgWFNMVEVycm9yUmVzb3VyY2VzLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZSBDaGFySW5mby5qYXZhCi0gV3JpdGVyVG9VVEY4QnVmZmVyZWQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzIEVsZW1FeHRlbnNpb25DYWxsLmphdmEKLSBFbGVtRXh0ZW5zaW9uRGVjbC5qYXZhIEVsZW1NZXNzYWdlLmphdmEKLSBGdW5jRG9jdW1lbnQuamF2YSBGdW5jRm9ybWF0TnVtYi5qYXZhCi0gT3V0cHV0UHJvcGVydGllcy5qYXZhIFN0eWxlc2hlZXRSb290LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyQVhGaWx0ZXIuamF2YQotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YQotIFRyYW5zZm9ybWVySWRlbnRpdHlJbXBsLmphdmEgVHJhbnNmb3JtZXJJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtIERUTUV4Y2VwdGlvbi5qYXZhCi0gRFRNTWFuYWdlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBDaHVua2VkSW50QXJyYXkuamF2YQotIENvcm91dGluZU1hbmFnZXIuamF2YSBDb3JvdXRpbmVTQVhQYXJzZXIuamF2YQotIENvcm91dGluZVNBWFBhcnNlcl9YZXJjZXMuamF2YSBEVE1CdWlsZGVyLmphdmEKLSBEVE1EZWZhdWx0QmFzZS5qYXZhIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzLmphdmEKLSBEVE1EZWZhdWx0QmFzZVRyYXZlcnNlcnMuamF2YQotIERUTU1hbmFnZXJEZWZhdWx0LmphdmEKLSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuamF2YQotIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcy5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9zYXgyZHRtIFNBWDJEVE0uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIE9iamVjdFBvb2wuamF2YSBRTmFtZS5qYXZhCi0gVVJJLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIE5vZGVTZXQuamF2YSBOb2RlU2V0RFRNLmphdmEKLSBWYXJpYWJsZVN0YWNrLmphdmEgWFBhdGguamF2YSBYUGF0aENvbnRleHQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBXYWxrZXJGYWN0b3J5LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucyBGdW5jU3Vic3RyaW5nLmphdmEKLSBGdW5jdGlvbkRlZjFBcmcuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cwotIFhSVHJlZUZyYWdTZWxlY3RXcmFwcGVyLmphdmEgWFN0cmluZ0ZvckNoYXJzLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMgVmFyaWFibGUuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvcmVzIFhQQVRIRXJyb3JSZXNvdXJjZXMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkdldHRpbmcgYWxsIChhbG1vc3QgYWxsKSBlcnJvciBtZXNzYWdlIHN0cmluZ3MgaW50byB0aGUgcmVzb3VyY2UgYnVuZGxlPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yNy8yMDAxPGJyLz48cmVmPlJlbW92ZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYgRFRNQnVpbGRlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWNjaWRlbnRhbGx5IGFkZGVkLiBOb3cgZGVsZXRpbmcuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIEV4cHJlc3Npb24uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBBeGVzV2Fsa2VyLmphdmEKLSBMb2NQYXRoSXRlcmF0b3IuamF2YSBQcmVkaWNhdGVkTm9kZVRlc3QuamF2YQotIFJldmVyc2VBeGVzV2Fsa2VyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMgWE51bWJlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vcGVyYXRpb25zIFZhcmlhYmxlLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5JZiBhIHByb3hpbWl0eSBwcmVkaWNhdGUgaXMgYSBzdGFibGUgbnVtYmVyICh2YXJpYWJsZSBvciBudW1iZXIgbGl0ZXJhbCkgdGhlbiwKLSBvbmNlIHRoZSBub2RlIGlzIGZvdW5kLCBkb24ndCBrZWVwIHNlYXJjaGluZyEgKHNpbmNlIG9ubHkgb25lCi0gbm9kZSBpcyBwb3NzaWJsZSkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8zMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTURlZmF1bHRCYXNlLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5JbiBnZXROZXh0TmFtZXNwYWNlTm9kZSBhbmQgZ2V0Rmlyc3ROYW1lc3BhY2VOb2RlLCB3YXMKLSBzb21ldGltZXMgcmV0dXJuaW5nIGEgbm9kZSB3aXRob3V0IHRoZSBEVE0gaWRlbnRpdHkgYml0cy4KLSBGaXggZm9yIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9Mjg3OC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzMwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIgT3BNYXAuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlRocm93IHJlYWwgZXJyb3IgaW5zdGVhZCBvZiBydW50aW1lIGVycm9yIGluIGdldEZpcnN0UHJlZGljYXRlT3BQb3MKLSBmb3IgYmV0dGVyIGVycm9yIHJlcG9ydGluZy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzMwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBQcmVkaWNhdGVkTm9kZVRlc3QuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIgT3BNYXAuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkJpdCBvZiBhIGhhY2sgdG8gbWFrZSAvZGVzY2VuZGFudC1vci1zZWxmOjpub3J0aCB3aXRoIGdldEZpcnN0UHJlZGljYXRlT3BQb3MKLSB3aGVyZSBnZXRGaXJzdFByZWRpY2F0ZU9wUG9zIHdhcyBhbHdheXMgdGhyb3dpbmcgYW4gZXJyb3IgaWYKLSB0aGVyZSB3YXMgbm90IGEgcHJlZGljYXRlICghISBTaG91bGQgaGF2ZSBiZWVuIGRpc2NvdmVyZWQgYmVmb3JlCi0gbm93PyE/ISkuIElmIC0yIHJldHVybiAtMiAoaW5zdGVhZCBvZiB0aHJvd2luZyBhbiBlcnJvciksIGFuZAotIGhhbmRsZSB0aGlzIGNhc2UgaW4gUHJlZGljYXRlZE5vZGVUZXN0I2luaXRQcmVkaWNhdGVJbmZvLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qb2huZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMzAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIE9iamVjdEFycmF5LmphdmEKLSBTUUxEb2N1bWVudC5qYXZhIFNRTEVycm9yRG9jdW1lbnQuamF2YQotIFhDb25uZWN0aW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCB0aGUgb3JpZ2luYWwgcHF1ZXJ5IGFuZCBzdHJlYW1pbmcgbW9kZSBmdW5jdGlvbmFsaXR5Ci0gU3VibWl0dGVkIGJ5OiBKb2huIEdlbnRpbGluPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmpvaG5nQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8zMC8yMDAxPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgRFRNRG9jdW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIERUTSBEb2N1bWVudCwgYSBjb21tb24gaW1wbCBiZXR3ZWVuIFNRTERvY3VtZW50IGFuZCBTUUxFcnJvckRvY3VtZW50Ci0gU3VibWl0dGVkIGJ5OiBKb2huIEdlbnRpbGluPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8zMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMgRGVzY2VuZGFudEl0ZXJhdG9yLmphdmEKLSBXYWxrZXJGYWN0b3J5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggYWRkcmVzc2VzIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9lbnRlcl9idWcuY2dpP3Byb2R1Y3Q9WGFsYW5KMiwKLSBhbmQgYSB3aG9sZSBjbGFzcyBvZiByZWxhdGVkIHByb2JsZW1zLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMzEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzIFhOb2RlU2V0LmphdmEgWE9iamVjdC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucyBTdGVwUGF0dGVybi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+RGV0YWNoIGV4cHJlc3Npb25zIGluIG1hdGNoIHBhdHRlcm5zLiBBbHNvLCBkZWZpbmVkCi0gbnVtV2l0aFNpZGVFZmZlY3RzIGFuZCBib29sV2l0aFNpZGVFZmZlY3RzIChmb3IgbGFjayBvZgotIGJldHRlciBuYW1lcykgdGhhdCB3aWxsIGluY3JlbWVudCB0aGUgaXRlcmF0b3IsIGFuZCBjYWxsIHRoZXNlCi0gZm9yIHByZWRpY2F0ZXMuIFRoZSBjb21iaW5hdGlvbiBvZiB0aGVzZSByZXN1bHRzIGluIGFib3V0IGFuCi0gMTglIHBlcmZvcm1hbmNlIGltcHJvdmVtZW50IGZvciBkZWNveS54c2wuCi0gQ3JlZGl0cyB0byBNdWt1bmQgUmFnaGF2YWNoYXJpL1dhdHNvbi9JQk1ASUJNVVMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8zMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMKLSBFeHRlbnNpb25IYW5kbGVyR2VuZXJhbC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMgWFNMVEVycm9yUmVzb3VyY2VzLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtRXh0ZW5zaW9uRGVjbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkIHN1cHBvcnQgZm9yIGV4dGVybmFsIHNjcmlwdHMgKGllLCB0aGUgc3JjIGF0dHJpYnV0ZSBvbiBhIHNjcmlwdCBlbGVtZW50KTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMzEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aCBYUGF0aENvbnRleHQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBDaGlsZFRlc3RJdGVyYXRvci5qYXZhCi0gT25lU3RlcEl0ZXJhdG9yRm9yd2FyZC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW4gWFBhdGhDb250ZXh0I2NyZWF0ZURUTUl0ZXJhdG9yKGludCBub2RlKSwgY2FsbCAKLU9uZVN0ZXBJdGVyYXRvckZvcndhcmQoQXhpcy5TRUxGKQotIGluc3RlYWQgb2YgRGVzY2VuZGFudEl0ZXJhdG9yLiBUaGlzIGFkZHJlc3NlcyBvbmUgb2YgdGhlIGJ1Z3MKLSBpbiBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTI5MjUKLSAoaS5lLiAmbHQ7eHNsOmNvcHktb2Ygc2VsZWN0PSJ4YWxhbjpub2Rlc2V0KCRzdHlsZXNoZWV0cykiLyZndDsuLi4KLSBUaGUgRGVzY2VuZGFudEl0ZXJhdG9yIHdhcyBlbnVtZXJhdGluZyBhbGwgb2YgdGhlIG5vZGVzIGluIHRoZSBSVEYKLSByYXRoZXIgdGhhbiBqdXN0IHRoZSBvbmUuKTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qb2huZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMzEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIENvbm5lY3Rpb25Qb29sLmphdmEKLSBDb25uZWN0aW9uUG9vbE1hbmFnZXIuamF2YSBEVE1Eb2N1bWVudC5qYXZhCi0gRGVmYXVsdENvbm5lY3Rpb25Qb29sLmphdmEgT2JqZWN0QXJyYXkuamF2YQotIFBvb2xlZENvbm5lY3Rpb24uamF2YSBTUUxEb2N1bWVudC5qYXZhCi0gU1FMRXJyb3JEb2N1bWVudC5qYXZhIFhDb25uZWN0aW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBFcnJvciBNYW5hZ21lbnQgYW5kIGphdmFkb2NzCi0gU3VibWl0dGVkIGJ5OiBKb2huIEdlbnRpbGluPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL3BhdHRlcm5zIFN0ZXBQYXR0ZXJuLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXhlZCBzb21lIG1ham9yIHByb2JsZW1zIHdpdGggcG9zaXRpb24oKSBhbmQgbGFzdCgpIGluIHNlY29uZGFyeQotIHByZWRpY2F0ZXMgZm9yIG1hdGNoIHBhdHRlcm5zLiBDcmVkaXQgZ29lcyB0bwotIE11a3VuZCBSYWdoYXZhY2hhcmkvV2F0c29uL0lCTUBJQk1VUyBmb3IgZmxhZ2dpbmcgdGhlc2UuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmpvaG5nQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgWENvbm5lY3Rpb24uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlVwZGF0ZSBhZnRlciBidWlsZGluZyBVbml0IFRlc3QncwotIFN1Ym1pdHRlZCBieTogSm9obiBHZW50aWxpbjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgWFNMVEF0dHJpYnV0ZURlZi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBCdWd6aWxsYSAyOTMwLiBGaXggZnJvbSBBbGV4YW5kZXIgUnVkbmV2LiBIYW5kbGUgbmFtZXNwYWNlZCBlbGVtZW50cy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAxLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bSBEVE1BeGlzSXRlcmF0b3IuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYgRFRNQXhpc0l0ZXJhdG9yQmFzZS5qYXZhCi0gRFRNRGVmYXVsdEJhc2VJdGVyYXRvcnMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBPbmVTdGVwSXRlcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZHJlc3NlcyBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTI5NDUKLQotIEJ1ZyB3YXMgY2F1c2VkIGJ5IChyZWR1bmRlbnQpIGNsb25lV2l0aFJlc2V0IGJlaW5nIGNhbGxlZCBmcm9tCi0gdGhlIFVuaW9uUGF0aEl0ZXJhdG9yLCBhbmQgdGhlIGl0ZXJhdG9yIGluIE9uZVN0ZXBJdGVyYXRvciBub3QgYmVpbmcKLSByZXNldC4gKE5lZWQgdG8gcmV2aWV3OiBjaGVjayBvdGhlciBpdGVyYXRvcnMgZm9yIHRoaXMuKQotCi0gQ2FsbCByZXNldCBvbiB0aGUgaXRlcmF0b3IgaW4gT25lU3RlcEl0ZXJhdG9yI3Jlc2V0LiBSZXNldCB0aGUgcG9zaXRpb24KLSB2YWx1ZSBpbiB0aGUgYW5jZXN0b3IgaXRlcmF0b3IgcmVzZXQuIERlZmluZSBEVE1BeGlzSXRlcmF0b3IjY2xvbmVJdGVyYXRvcgotIHRvIG5vdCByZXNldCB0aGUgaXRlcmF0b3IgcG9zaXRpb24sIGFuZCBmaXggdGhlIGltcGxlbWVudGF0aW9ucyBvZgotIHRoaXMgdG8gbm90IGNhbGwgY2xvbmUucmVzZXQoKS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIE5vZGVTZXREVE0uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zIEZ1bmNFeHRGdW5jdGlvbi5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzIFhCb29sZWFuLmphdmEKLSBYTm9kZVNldC5qYXZhIFhOdW1iZXIuamF2YSBYT2JqZWN0LmphdmE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cyBYTm9kZVNldEZvckRPTS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkcmVzcyBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTI5MjUKLQotIENyZWF0ZSBuZXcgWE9iamVjdCwgWE5vZGVTZXRGb3JET00sIHdoaWNoIGlzIGNvbnN0cnVjdGVkCi0gZnJvbSBhIE5vZGUsIE5vZGVMaXN0LCBvciBOb2RlSXRlcmF0b3IsIGFuZCBhY3RzIHRoZSBzYW1lIGFzCi0gWE5vZGVTZXQsIGV4Y2VwdCBpdCByZXR1cm5zIHRoZSBvcmlnaW5hbCBvYmplY3QgZm9yIG9iamVjdCgpLAotIG5vZGVzZXQoKSwgYW5kIG5vZGVsaXN0KCkuCi0KLSBBZGQgWE9iamVjdCNjcmVhdGUoT2JqZWN0IHZhbCwgWFBhdGhDb250ZXh0IHhjdHh0KSwgd2hpY2ggaXMKLSBjYWxsZWQgZnJvbSBUcmFuc2Zvcm1lckltcGwjc2V0UGFyYW1ldGVyKHMpLCBhbmQKLSBGdW5jRXh0RnVuY3Rpb24jZXhlY3V0ZSAoZm9yIHRoZSByZXR1cm4gdmFsdWVzIG9mIHRoZQotIGV4dGVuc2lvbikuCi0KLSBYQm9vbGVhbiBhbmQgWE51bWJlciBub3cgYWxzbyBoYXZlIEJvb2xlYW4gYW5kIE51bWJlcgotIGNvbnN0cnVjdG9ycywgaW4gd2hpY2ggY2FzZSB0aGUgb3JpZ2luYWwgb2JqZWN0IHdpbGwgYWxzbyBiZQotIHJldHVybmVkIGZyb20gdGhlIG9iamVjdCgpIG1ldGhvZC4KLQotIFRoaXMgc2hvdWxkIG1ha2UgdGhlIGNvbnZlcnNpb24gZnJvbSBqYXZhIG9iamVjdCB0byBYT2JqZWN0Ci0gY29uc2lzdGVudCBiZXR3ZWVuIGZ1bmN0aW9uIHJldHVybnMgYW5kIHNldFBhcmFtZXRlci4gVGhlc2UKLSBjaGFuZ2VzIHNob3VsZCBhbHNvIGZpeCBhIGJ1ZyB3aGVyZSBOb2RlTGlzdHMgd2VyZW4ndCBiZWluZyBjb252ZXJ0ZWQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMy8yMDAxPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBOYW1lc3BhY2VTdXBwb3J0Mi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVwbGFjZW1lbnQgZm9yIG9yZy54bWwuc2F4LmhlbHBlcnMuTmFtZXNwYWNlU3VwcG9ydDsgZXh0ZW5kcwotIHRoYXQgQVBJIHNvIGl0IGNhbiBiZSBlYXNpbHkgc3dhcHBlZCBpbi4KLQotIEN1cnJlbnQgY2hhbmdlczsKLQotIE1pbm9yIGNvZGUgcmVvcmcuIEknbSBzb3JyeSwgYnV0IEkgZmluZCBjbGFzc2VzIGVhc2llciB0byByZWFkCi0gaWYgZmllbGRzIGFyZSBkZWZpbmVkIGJlZm9yZSBtZXRob2RzIHJlZmVyZW5jZSB0aGVtIHJhdGhlciB0aGFuCi0gYXQgZW5kLCBlc3BlY2lhbGx5IHdoZW4gaW5uZXIgY2xhc3NlcyBhcmUgcHJlc2VudC4KLQotIFB1bnQgc3RhY2sgdmVjdG9yIGluIGZhdm9yIG9mIGRvdWJseS1saW5rZWQgbGlzdC4gKEl0IHdhcyBhbHJlYWR5Ci0gc2luZ2x5LWxpbmtlZCBpbiBwYXJhbGxlbCB3aXRoIHRoZSB2ZWN0b3IhKQotCi0gVGhlIHdob2xlIGRpcnR5LXRhYmxlcyBjb25jZXB0IHdhcyBicm9rZW4sIGJlY2F1c2UgQ29udGV4dCdzCi0gY3RvciBhbHdheXMgY2FsbGVkIGNvcHlUYWJsZXMgYW5kIHRodXMgYWx3YXlzIG1hcmtlZCB0YWJsZXMKLSBkaXJ0eS4gSXQgYWxzbyB3YXN0ZWQgc29tZSB0aW1lIHNldHRpbmcgaXRzZWxmIG9ubHkgdG8gYmUgcmVzZXQgYnkKLSBzZXRQYXJlbnQuIEkndmUgZml4ZWQgYm90aCBieSBwYXJhbWV0ZXJpemluZyB0aGUgY3RvciBhbmQgbWFraW5nCi0gY29weVRhYmxlcyBzcGVjaWZpYyB0byBwcmVwLWZvci1uZXctZGVjbGFyYXRpb24uIChDb3VsZCBiZQotIG1vdmVkIGJhY2sgaW50byB0aGUgZGVjbGFyYXRpb24gbWV0aG9kLCBmb3IgdGhhdCBtYXR0ZXIuKQotCi0gSSdtIGR1YmlvdXMgYWJvdXQgdGhlIGNhY2hlcyBpbiBwcm9jZXNzTmFtZS4gQXMgZmFyIGFzIEkgY2FuCi0gdGVsbCwgWGFsYW4gcGVyIHNlIG5ldmVyIGFjdHVhbGx5IHVzZXMgdGhhdCBtZXRob2QuLi4KLQotIFRoZSB1c2Ugb2YgSGFzaHRhYmxlcyBpcyBxdWVzdGlvbmFibGUuIEhhc2h0YWJsZSBpcwotIGtub3duIHRvIGJlIGluZWZmaWNpZW50IGFuZCBvdmVyc3luY2hyb25pemVkIGluIG9sZGVyIEpWTXMsIGFuZAotIHRoZSBmYWN0IHRoYXQgdGhpcyBpcyBhIGJpZGlyZWN0aW9uYWwgbWFwcGluZyBzdWdnZXN0cyB0aGF0IGFuCi0gYXBwcm9hY2ggc2ltaWxhciB0byBvdXIgb3duIFN0cmluZyBQb29sIC0tIGxpZ2h0ZXItd2VpZ2h0LCBtb3JlCi0gdGFyZ2V0ZWQsIGhhc2hpbmcgd2l0aG91dCByZWR1cGxpY2F0aW5nIHRoZSB0d28gY29sdW1uIHRhYmxlcyAtLQotIHdvdWxkIGJlIGEgd2luLiBTaW5jZSB0aGVzZSBhcmUgdHlwaWNhbGx5IHNob3J0IHNldHMsIGV2ZW4KLSBzaW1wbGUgbGluZWFyIHNlYXJjaCBpcyB3b3J0aCBjb25zaWRlcmluZyE8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFN0eWxlc2hlZXRIYW5kbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtVGVtcGxhdGVFbGVtZW50LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFJlc3VsdFRyZWVIYW5kbGVyLmphdmEKLSBUcmFuc2Zvcm1TbmFwc2hvdEltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkN1dG92ZXIgdG8gTmFtZXNwYWNlU3VwcG9ydDIsIHEudi48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIE5hbWVzcGFjZVN1cHBvcnQyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Db250aW51aW5nIGNvZGUgcmV2aWV3Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgTmFtZXNwYWNlU3VwcG9ydDIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1vcmUgZWZmaWNpZW50IHByZWZpeGVzLWZvci1zcGVjaWZpYy1VUkkuIFRoaXMgbWF5IHdpbmQgdXAgYmVpbmcKLSByZWRvbmUgeWV0IGFnYWluIGlmL3doZW4gdGhlIHVuZGVybHlpbmcgc3RvcmFnZSByZXByZXNlbnRhdGlvbgotIGNoYW5nZXMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAzLzIwMDE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliIFBpcGVEb2N1bWVudC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UGlwZURvY3VtZW50IGV4dGVuc2lvbiBlbGVtZW50ICh0aGUgcGlwZURvY3VtZW50IG1ldGhvZCkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyYW5zZm9ybWVySW1wbC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aCBOb2RlU2V0LmphdmEgTm9kZVNldERUTS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QnVnIGZpeGVkIHJlZ2FyZGluZyB0aGUgY3VycmVudCgpIGZ1bmN0aW9uIGluIHRoZSByb290IHRlbXBsYXRlCi0gKHJlbGF0ZWQgdG8gYnVnIzEyNjkpLiBCdWcgd2FzIHJlcG9ydGVkIGJ5IERhdmlkIE1hcnN0b24KLSBvZmZsaW5lLiBUaGUgdGVzdCBmb3IgdGhpcyBpcyBjb25mL2NvcHkvY29weTI5LgotCi0gSW4gVHJhbnNmb3JtZXJJbXBsI2FwcGx5VGVtcGxhdGVUb05vZGUsIGNyZWF0ZSBhIE5vZGVTZXREVE0gYW5kIHBhc3MgaXQgdG8gCi1tX3hjb250ZXh0LnB1c2hDb250ZXh0Tm9kZUxpc3QoY25sKTsuCi0gSW4gTm9kZVNldERUTSBmaXggZ2V0Q3VycmVudE5vZGUgc28gdGhhdCBpdCBkb2Vzbid0IHVzZSBtX25leHQtMQotICh3aGljaCBzaW1wbHkgYXBwZWFycyB0byBiZSBjb21wbGV0ZWx5IHdyb25nKS4gRG8gdGhlIHNhbWUgZm9yCi0gTm9kZVNldC4uLiB0aG91Z2ggSSBkb24ndCB0aGluayB0aGlzIHdpbGwgYmUgY2FsbGVkIGFueXdoZXJlIGluCi0gWGFsYW4uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0gRFRNQXhpc0l0ZXJhdG9yLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTUF4aXNJdGVyYXRvckJhc2UuamF2YQotIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Qcm92aWRlIG1ldGhvZCBmb3IgRFRNQXhpc0l0ZXJhdG9yIHRvIGdldCB0aGUgY3VycmVudCByb290IG5vZGUKLSBvZiB0aGUgaXRlcmF0aW9uLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzIFhPYmplY3QuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkluIHJlc3BvbnNlIHRvIHJlZ3Jlc3Npb24gcG9zdGVkIG9uIHhhbGFuLWRldiBieSBKb2huIEdlbnRpbGluIAotJmx0O2pvaG5nbGludXhAZXllY2F0Y2hpbmcuY29tJmd0OwotIG9uIDA4LzAzLzIwMDEgMDY6NDkgUE0uIFdoZW4gdGhlIFhOb2RlU2V0IHRha3MgYSBEVE1JdGVyYXRvciwgaXQKLSB3aWxsIGNhbGwgdmFsLmdldERUTU1hbmFnZXIoKTssIHdoaWNoIHdpbGwgY2FsbCBMb2NQYXRoSXRlcmF0b3IjZ2V0RFRNTWFuYWdlciwKLSB3aGljaCB3aWxsIGNhbGwgbV9leGVjQ29udGV4dC4uZ2V0RFRNTWFuYWdlcigpLCB3aGljaCBtZWFucwotIHRoYXQgc2V0Um9vdCBoYXMgdG8gYmUgY2FsbGVkIG9uIHRoZSBpdGVyYXRvciBiZWZvcmUgaXQgaXMgYWRkZWQgdG8KLSBYTm9kZVNldC4gVGh1cywgY2FsbCBzZXRSb290IG9uIHRoZSBPbmVTdGVwSXRlcmF0b3IgaW4KLSBjcmVhdGUoT2JqZWN0LCBYUGF0aENvbnRleHQpIGJlZm9yZSBpdCBpcyBhZGRlZCB0byB0aGUgWE5vZGVTZXQuCi0gVGhlIHJlZ3Jlc3Npb24gd2FzIHJlbGF0ZWQgdG8gZml4IGZvciAKLWh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MjkyNS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBPbmVTdGVwSXRlcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZvciB0aGUgT25lU3RlcEl0ZXJhdG9yKERUTUF4aXNJdGVyYXRvciBpdGVyYXRvcikgY29uc3RydWN0b3IsCi0gaW5pdGlhbGl6ZSB0aGUgbm9kZSB0ZXN0cyB0byBEVE1GaWx0ZXIuU0hPV19BTEwgKGR1aCkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMgWE9iamVjdC5qYXZhPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29iamVjdHMgWE9iamVjdEZhY3RvcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1vdmUgY3JlYXRlIG1ldGhvZHMgZnJvbSBYT2JqZWN0IHRvIFhPYmplY3RGYWN0b3J5LCBpbiByZXNwb25zZQotIHRvIGN5Y2xpYyBidWlsZCBwcm9ibGVtcyBlbmNvdW50ZXJlZCB3aXRoIGphdmFjIDEuMS44Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgTmFtZXNwYWNlU3VwcG9ydDIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1vdmVkIGFub25vbW91cyBjbGFzcyB0byBQcmVmaXhFbnVtZXJhdG9yLCBpbiByZXNwb25zZQotIHRvIHByb2JsZW1zIGVuY291bnRlcmVkIHdpdGggMS4xLjggYnVpbGQuCi0gSm9lIG1heSB3YW50IHRvIGZpeCB0aGlzIGluIGFub3RoZXIgd2F5LCBhcwotIEknbSBzdXJlIHRoZSBhbm9uIGNsYXNzIGlzIHByb2JhYmx5IGEgYml0Ci0gY2hlYXBlcj88YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggVmFyaWFibGVTdGFjay5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkcmVzcyBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTI5NzIsCi0gd2hlcmUgaXQgd2FzIHRocm93aW5nIGEgTlBFIGluc3RlYWQgb2YgcmVwb3J0aW5nIHRoYXQgdGhlIHZhcmlhYmxlCi0gd2FzIGJlaW5nIGFjY2Vzc2VkIGJlZm9yZSBpdCB3YXMgYm91bmQgKGkuZS4gdGhlIHZhcmlhYmxlIHdhcyBiZWluZwotIGFjY2Vzc2VkIGluc2lkZSBhbiBSVEYgZm9yIHRoYXQgc2FtZSB2YXJpYWJsZSkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtb3ZlIG1faGFzU3RhcnRlZCB2YXJpYWJsZSBhbmQgYXNzb2NpYXRlZCBhc3NlcnRpb24uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTURlZmF1bHRCYXNlSXRlcmF0b3JzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRyZXNzZXMgYnVnIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MzAwMS4KLSBJbiB0aGUgY2xvbmVJdGVyYXRvciBmdW5jdGlvbiBvZiBQcmVjZWRpbmdJdGVyYXRvciwgdGhlIGNsb25lZCBhcnJheQotIHdhcyBiZWluZyBzaXplZCBmb3IgX21heEFuY2VzdG9ycywgd2hpY2ggZGVmYXVsdHMgdG8gOC4gQnV0IGlmIHRoZQotIF9zdGFjayB3YXMgcmVzaXplZCwgaXQgd2lsbCBjb3B5IG1vcmUgaW50byB0aGUgbmV3IHN0YWNrIHRoYW4gaXMKLSBhbGxvY2F0ZWQuIFRoZSBzb2x1dGlvbiBpcyB0byBhbGxvY2F0ZSB0aGUgbmV3IGNsb25lLl9zdGFjayBhcnJheSB0bwotIF9zdGFjay5sZW5ndGguPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBOYW1lc3BhY2VTdXBwb3J0Mi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+RG9uJ3QgY3JlYXRlIGNhY2hlcyB1bmxlc3MgdXNlZCAod2hpY2ggSSBkb24ndCB0aGluayB0aGV5IGFyZSwgaW4gWGFsYW4pLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBEVE1EZWZhdWx0QmFzZUl0ZXJhdG9ycy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+TWFkZSBfbWF4QW5jZXN0b3JzIG5vdCBzdGF0aWMsIGFzIHRoaXMgaXMKLSBub3QgY29tcGF0aWJsZSB3aXRoIDEuMS44IChyZXBvcnRlZCBieQotIEdhcnkgUGVza2luKS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIE5hbWVzcGFjZVN1cHBvcnQyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5QbGF5aW5nIGEgaHVuY2gsIEkgbW92ZWQgdGhlIENvbnRleHQgb2JqZWN0cyBvdXQgb2YgTmFtZXNwYWNlU3VwcG9ydDIuCi0gVGhleSdyZSBub3cgYSBzZWNvbmQgY2xhc3MgaW4gdGhlIHNhbWUgZmlsZSByYXRoZXIgdGhhbiBiZWluZyBhbiBpbm5lciBjbGFzcy4KLSBUaGF0IHJlZHVjZXMgdGhlIHNpemUgb2YgdGhlIENvbnRleHQyIG9iamVjdCwgYW5kIGl0cyBpbml0aWFsaXphdGlvbiB0aW1lLCBieQotIHJlbW92aW5nIHRoZSBuZWVkIGZvciBpdCB0byBjYXJyeSBhIHJlZmVyZW5jZSB0byB0aGUgTmFtZXNwYWNlU3VwcG9ydDIKLSBvYmplY3QgdGhhdCBjcmVhdGVkIGl0LgotCi0gUGVyZm9ybWFuY2Ugc2VlbXMgc2lnbmlmaWNhbnRseSBpbXByb3ZlZC4uLiBldmVuIChzdXJwcmlzaW5nbHkhKSBvbiB0aGUKLSBnZXREZWNsYXJlZFByZWZpeGVzIG9wZXJhdGlvbi4gTWVtb3J5IHVzYWdlIGFsc28gc2VlbXMgYmV0dGVyLCBhcwotIGV4cGVjdGVkLgotCi0gTmFtZXNwYWNlU3VwcG9ydDIgaXMgc3RpbGwgYWNvdW50aW5nIGZvciBhYm91dCA1JQotIG9mIHRoZSB0aW1lIHNwZW50IGluIHRoZSBSZXN1bHRUcmVlSGFuZGxlciwgYWNjb3JkaW5nCi0gdG8gbXkgbGF0ZXN0IHRyYWNlLiBBcHBhcmVudGx5IHdlIGFyZSBjYWxsaW5nCi0gZ2V0RGVjbGFyZWRQcmVmaXhlcyBhbiBvYnNjZW5lbHkgbGFyZ2UgbnVtYmVyIG9mCi0gdGltZXMsIGFuZCB0aGUgVmVjdG9yLmVsZW1lbnRzIGNhbGwgaXMgYWRkaW5nIHVwLiBXZQotIG1heSB3YW50IHRvIGxvb2sgYXQgd2hlcmUgdGhpcyBpcyBiZWluZyBjYWxsZWQgZnJvbQotIGFuZCB3aGV0aGVyIHdlIGNhbiByZWR1Y2UgdGhlIG51bWJlciBvZiBpbnZvY2F0aW9ucy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgUmVzdWx0VHJlZUhhbmRsZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlBlcmZvcm1hbmNlIGltcHJvdmVtZW50OyBhdm9pZCBzY2FubmluZyB0aGUgc2FtZSBsaXN0IHR3aWNlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lcgotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBQcm9jZXNzLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmCi0gSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBEZWZhdWx0RXJyb3JIYW5kbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL29wZXJhdGlvbnMgVmFyaWFibGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlRoaXMgY2hlY2tpbiBob3BlZnVsbHkgZml4ZXMgbWFueSBwcm9ibGVtcyB3aXRoIGJhZCBkaWFnbm9zdGljcyBsYXRlbHksIGJ1dAotIGF0IHRoZSBleHBlbnNlIG9mIGEgc2xpZ2h0IGNoYW5nZSBpbiBiZWhhdmlvci4gVGhlIHJ1bGUgbm93IGlzLCB0aGUKLSBEZWZhdWx0RXJyb3JIYW5kbGVyIG5ldmVyIG91dHB1dHMgbG9jYXRpb24gaW5mbyBmb3IgZXJyb3IgYW5kIGZhdGFsRXJyb3IuLi4gCi10aGlzIGhhcyB0byBiZSBkb25lCi0gYnkgdGhlIGNhdGNoZXIgb2YgdGhlIGV4Y2VwdGlvbi4gQ29udmVuaWVuY2UgbWV0aG9kcyBmb3IgdGhpcyBhcmUKLSBpbiBEZWZhdWx0RXJyb3JIYW5kbGVyI3ByaW50TG9jYXRpb24uIFRoaXMgbWV0aG9kIHdpbGwgdW53cmFwIHRoZQotIGV4Y2VwdGlvbiBhcyBjbG9zZSB0byB0aGUgb3JpZ2luYXRpbmcgc291cmNlIGFzIHBvc3NpYmxlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zCi0gWFNMUHJvY2Vzc29yQ29udGV4dC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtIERUTUl0ZXJhdG9yLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTUF4aXNJdGVyYXRvckJhc2UuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggTm9kZVNldERUTS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIEF0dHJpYnV0ZUl0ZXJhdG9yLmphdmEKLSBBeGVzV2Fsa2VyLmphdmEgQ2hpbGRJdGVyYXRvci5qYXZhCi0gQ2hpbGRUZXN0SXRlcmF0b3IuamF2YSBEZXNjZW5kYW50SXRlcmF0b3IuamF2YQotIEZpbHRlckV4cHJXYWxrZXIuamF2YSBMb2NQYXRoSXRlcmF0b3IuamF2YQotIE9uZVN0ZXBJdGVyYXRvci5qYXZhIE9uZVN0ZXBJdGVyYXRvckZvcndhcmQuamF2YQotIFJldmVyc2VBeGVzV2Fsa2VyLmphdmEgVW5pb25QYXRoSXRlcmF0b3IuamF2YQotIFdhbGtpbmdJdGVyYXRvclNvcnRlZC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzIFhPYmplY3RGYWN0b3J5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DaGFuZ2VzIHRvIGFsbG93IHNvbWUgZHluYW1pYyBkZXRlcm1pbmF0aW9uIGluIFdhbGtlckl0ZXJhdG9yU29ydGVkIHRvCi0gc2VlIGlmIHRoZSBub2RlcyByZWFsbHkgbmVlZCB0byBiZSBzb3J0ZWQuIEFkZGVkIGlzRG9jT3JkZXJlZCgpIGFuZAotIGdldEF4aXMoKSB0byBib3RoIERUTUl0ZXJhdG9yIGFuZCBBeGVzV2Fsa2VyLCBhbmQgaW1wbGVtZW50ZWQKLSBhcHByb3ByaWF0ZSBvdmVybG9hZHMgaW4gZGVyaXZlZCBvciBpbXBsZW1lbnRpbmcgY2xhc3Nlcy4gSW4gRmlsdGVyRXhwcldhbGtlcgotIHJldHVybiB0aGUgY29udGFpbmVkIERUTUl0ZXJhdG9yJ3MgZ2V0QXhpcygpLiBJbiBXYWxrZXJJdGVyYXRvclNvcnRlZCwKLSBpbXBsZW1lbnQgY2FuQmVXYWxrZWRJbk5hdHVyYWxEb2NPcmRlcigpIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkCi0gZnJvbSBzZXRSb290KC4uLikuIElmIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0cnVlLCB0aGFuIGRvbid0IHNvcnQgdGhlIG5vZGVzCi0gaW4gc2V0Um9vdCwgYW5kIGluIGFsbCBvdGhlciByZXNwZWN0cyB0cmVhdCB0aGlzIGFzIGlmIGl0IGlzIGEgc2ltcGxlCi0gV2Fsa2luZ0l0ZXJhdG9yLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgYnVnemlsbGEgMTI1MS4gTWFrZSBzdXJlIGV4Y2VwdGlvbnMgYXJlIHRocm93biB3aGVuIHdlJ3JlIG9uIHRoZSBtYWluIAotdGhyZWFkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIEF4ZXNXYWxrZXIuamF2YQotIFdhbGtlckZhY3RvcnkuamF2YSBXYWxraW5nSXRlcmF0b3JTb3J0ZWQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkVsaW1pbmF0ZSBkby93aGlsZSBjaGVjayBmb3IgZHVwbGljYXRlcyBpbiBBeGVzV2Fsa2VyI25leHROb2RlKCkKLSBieSB1c2luZyBXYWxraW5nSXRlcmF0b3JTb3J0ZWQgZm9yIGNhc2VzIHdoZXJlIGJvdGggdGhlIHByZWNlZGluZ1stc2libGluZ10KLSBhbmQgZm9sbG93aW5nWy1zaWJsaW5nXSBheGVzIGFyZSBiZWluZyB3YWxrZWQsIGFuZCBmb3IgIkAqL2ZvbyIgcGF0dGVybnMKLSAoIkBhdHRyL2ZvbyIgcGF0dGVybnMgc3RpbGwgdXNlIFdhbGtpbmdJdGVyYXRvcikuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBGdW5jRm9ybWF0TnVtYi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGJ1Z3ppbGxhIGJ1ZyAzMDM2IAotKGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MzAzNikuIFdoZW4gbm8gCi14c2w6ZGVjaW1hbC1mb3JtYXQgZWxlbWVudCBpcyBzdXBwbGllZCBpbiB0aGUgY29tcG9zZWQgc3R5bGVzaGVldCwgdGhlIGRlZmF1bHRzIAotc3BlY2lmaWVkIGluIHRoZSBSZWNvbW1lbmRhdGlvbiBzZWN0aW9uIDEyLjMgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBhdHRyaWJ1dGUgCi12YWx1ZXMsIG5vdCBsb2NhbGUtc3BlY2lmaWMgZGVmYXVsdHMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL3NheDJkdG0gU0FYMkRUTS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBidWd6aWxsYSAzMDYwIAotKGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MzA2MCkuIFByZWZpeGVzIGFuZAotIG5hbWVzcGFjZVVSSXMgYXJlIGtlcHQgaW4gdGhlIHNhbWUgVmVjdG9yLCBtX3ByZWZpeE1hcHBpbmdzLiBUaGUgZW50cmllcyBhcmUgCi1zdG9yZWQgYXMgcGFpcnMgb2YgdmVjdG9yIGVsZW1lbnRzLiBUaGUgZXZlbiBlbGVtZW50cyBjb250YWluIHRoZSBwcmVmaXggYW5kIAotdGhlIG9kZCBlbGVtZW50cyBjb250YWluIHRoZSBVUkkuIEluIHR3byByb3V0aW5lcywgZ2V0UHJlZml4IGFuZCBlbmRFbGVtZW50LCAKLXRoZSBhcHByb3ByaWF0ZSBwcmVmaXggb3IgVVJJIHdhcyBiZWluZyBsb2NhdGVkIGluIHRoZSBWZWN0b3IgdXNpbmcgYW4gCi1pbmRleE9mLiBIb3dldmVyLCBpbiB0aGlzIGNhc2Ugd2hlcmUgdGhlIHByZWZpeCBhbmQgdGhlIFVSSSB3ZXJlIHRoZSBzYW1lLCB0aGUgCi1yb3V0aW5lIHdhcyBsb29raW5nIGZvciB0aGUgVVJJIGJ1dCBmaW5kaW5nIHRoZSBwcmVmaXggaW5zdGVhZCBvZiB0aGUgVVJJLiBJdCAKLXRyaWVkIHRyaWVkIHRvIGJhY2sgdXAgb25lIHRvIGdldCB0aGUgcHJlZml4IGFuZCB1bmRlcmZsb3dlZCB0aGUgVmVjdG9yIHNpemUuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFJlc3VsdFRyZWVIYW5kbGVyLmphdmEKLSBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkltcGxlbWVudCBFcnJvckhhbmRsZXIgaW4gUmVzdWx0VHJlZUhhbmRsZXIgc28gdGhhdCBmYXRhbCBlcnJvcnMgY2FuIGdldCAKLXBhc3NlZCBpbiB0byB0aGUgU0FYSGFuZGxlci4gQWxzbyBjaGFuZ2UgdGhlIGNvZGUgaW4gVHJhbnNmb3JtZXJJbXBsIHRvIGNhbGwgCi1mYXRhbEVycm9yIGluIGNhc2Ugb2YgYW4gZXJyb3IgaW5zdGVhZCBvZiBlbmREb2N1bWVudC4gKG92ZXJsYXBzIHdpdGggVVJJIAotaGFuZGxpbmcgZml4Li4uKTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtZXJJZGVudGl0eUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIFN5c3RlbUlEUmVzb2x2ZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBjb2RlIHRvIGhhbmRsZSBhYnNvbHV0ZSBwYXRocyBmcm9tIHVuaXggc3lzdGVtcy4gVGhpcyBmaXggaXMgcGFydCBvZiBhbiAKLW9uZ29pbmcgcHJvY2VzcyBhbmQgaXMganVzdCBtZWFudCB0byBmaXggYSBmZXcgcGVuZGluZyBidWdzLiBNb3JlIGNoYW5nZXMgYXJlIAotZXhwZWN0ZWQgaW4gdGhpcyBhcmVhLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgWFNMUHJvY2Vzc29yVmVyc2lvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2hhbmdlIHZlcnNpb24gZm9yIHhhbGFuMi4yLkQ5IGJ1aWxkPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtRWxlbWVudC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBSZXN1bHRUcmVlSGFuZGxlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgRGVmYXVsdEVycm9ySGFuZGxlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVzdWx0VHJlZUhhbmRsZXIgd2FzIHB1c2hpbmcgYSBuZXcgbmFtZXNwYWNlIGNvbnRleHQgYnV0IGZhaWxpbmcgdG8gbm90ZSAKLXRoYXQgcmVzdWx0IGluIG1vcmUgcHVzaGVzIHRoYW4gcG9wcy4gQ2xlYW5lZCB1cCB0aGUgZXhlY3V0ZSgpIG1ldGhvZCBvZiAKLUVsZW1FbGVtZW50IHRvIG1ha2UgaXQgbW9yZSB1bmRlcnN0YW5kYWJsZSAodG8gbWUpIGFuZCBhZGRlZCBhIGZldyBjb21tZW50cy4gCi1UaGUgRGVmYXVsdEVycm9ySGFuZGxlciB3YXMgbm90IGZsdXNoaW5nIFdyaXRlcnMgdGhhdCBpdCBjcmVhdGVkLiBTaW5jZSB0aGUgCi1Xcml0ZXJzIGFyZSBuZXZlciBjbG9zZWQgKGFuZCBjYW5ub3QgYmUgYXMgdGhlcmUgaXMgbm8gY2xvc2UgbWV0aG9kKSwgZXJyb3IgCi1tZXNzYWdlcyB3ZXJlIGZhaWxpbmcgdG8gYXBwZWFyLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtIERUTU1hbmFnZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkluY3JlYXNpbmcgdGhlIG51bWJlciBvZiBiaXRzIHVzZWQgdG8gaWRlbnRpZnkgRFRNIG5vZGVzLCBhdCB0aGUgZXhwZW5zZSBvZiAKLWRlY3JlYXNpbmcgdGhlIG51bWJlciBvZiBEVE1zIHRoYXQgYSBEVE1NYW5hZ2VyIGNhbiB0cmFjayBzaW11bHRhbmVvdXNseS4gU29tZSAKLW90aGVyIGNvZGUgaGFzIGJlZW4gdXBkYXRlZCB0byB0cmFjayB0aGlzIGNoYW5nZSAoYW5kIHRvIGJldHRlciB0cmFjayBwb3NpYmxlIAotZnV0dXJlIGNoYW5nZXMpLCBhcyBoYXZlIHRoZSBJREtFWSB0ZXN0Y2FzZXMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTURlZmF1bHRCYXNlLmphdmEKLSBEVE1Eb2N1bWVudEltcGwuamF2YSBEVE1NYW5hZ2VyRGVmYXVsdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW5jcmVhc2luZyB0aGUgbnVtYmVyIG9mIGJpdHMgdXNlZCB0byBpZGVudGlmeSBEVE0gbm9kZXMsIGF0IHRoZSBleHBlbnNlIG9mIAotZGVjcmVhc2luZyB0aGUgbnVtYmVyIG9mIERUTXMgdGhhdCBhIERUTU1hbmFnZXIgY2FuIHRyYWNrIHNpbXVsdGFuZW91c2x5LiBTb21lIAotb3RoZXIgY29kZSBoYXMgYmVlbiB1cGRhdGVkIHRvIHRyYWNrIHRoaXMgY2hhbmdlIChhbmQgdG8gYmV0dGVyIHRyYWNrIHBvc2libGUgCi1mdXR1cmUgY2hhbmdlcyksIGFzIGhhdmUgdGhlIElES0VZIHRlc3RjYXNlcy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzEwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zIEZ1bmNHZW5lcmF0ZUlkLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5JbmNyZWFzaW5nIHRoZSBudW1iZXIgb2YgYml0cyB1c2VkIHRvIGlkZW50aWZ5IERUTSBub2RlcywgYXQgdGhlIGV4cGVuc2Ugb2YgCi1kZWNyZWFzaW5nIHRoZSBudW1iZXIgb2YgRFRNcyB0aGF0IGEgRFRNTWFuYWdlciBjYW4gdHJhY2sgc2ltdWx0YW5lb3VzbHkuIFNvbWUgCi1vdGhlciBjb2RlIGhhcyBiZWVuIHVwZGF0ZWQgdG8gdHJhY2sgdGhpcyBjaGFuZ2UgKGFuZCB0byBiZXR0ZXIgdHJhY2sgcG9zaWJsZSAKLWZ1dHVyZSBjaGFuZ2VzKSwgYXMgaGF2ZSB0aGUgSURLRVkgdGVzdGNhc2VzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aCBOb2RlU2V0RFRNLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5UcnkgdG8gc3VwcG9ydCBnZXRSb290LiBGaXhlcyBwcm9ibGVtIHdpdGggVHJhbnNmb3JtU3RhdGVUZXN0Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIFdhbGtlckZhY3RvcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBwcm9ibGVtIHdpdGggZHVwbGljYXRlIG5vZGVzIHByb2R1Y2VkIGZyb20gYSB3YWxraW5nIGl0ZXJhdG9yPGJyLz48YnIvPjwvbGk+PC91bD48bm90ZT5UaGlzIHJlbGVhc2UgaW5jbHVkZXMgbm8gdXBkYXRlcyBvZiB0aGUgY29tcGF0aWJpbGl0eSBzb3VyY2UgY29kZSAobm93IGRlcHJlY2F0ZWQpLjwvbm90ZT4KLTwvczM+Ci08czMgdGl0bGU9IkNoYW5nZXMgZm9yICZ4c2x0NGo7IDIuMi5EOCI+Ci08cD4gQ29yZSAoTm9uLVhTTFRDKSBzb3VyY2UgY29kZSB1cGRhdGVzOjwvcD48dWw+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmpvaG5nQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgU1FMRG9jdW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNvZGUgVXBkYXRlCi0gU3VibWl0dGVkIGJ5OkpvaG4gR2VudGlsaW48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+am9obmdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBTUUxEb2N1bWVudC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4ZWQgRFRNLk5VTEwgY29tcGlsZSBlcnJvcjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBUcmVlV2Fsa2VyMlJlc3VsdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVkdW5kYW50IHRlc3QgcmVtb3ZlZCwgcG9zc2libHkgcmVkdW5kYW50IGNvZGUgZmxhZ2dlZCBmb3IgJVJFVklFVyU8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBTUUxEb2N1bWVudC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lcgotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYgRFRNRGVmYXVsdEJhc2UuamF2YQotIERUTURvY3VtZW50SW1wbC5qYXZhIERUTU1hbmFnZXJEZWZhdWx0LmphdmEKLSBJbmNyZW1lbnRhbFNBWFNvdXJjZS5qYXZhCi0gSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEKLSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9YZXJjZXMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvZG9tMmR0bSBET00yRFRNLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL3NheDJkdG0gU0FYMkRUTS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgU3ViYWxsb2NhdGVkSW50VmVjdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5JbmNyZW1lbnRhbFNBWFNvdXJjZSByZXBsYWNlcyBDb3JvdXRpbmVTQVhQYXJzZXIgLS0gc2ltcGxlciBBUEksCi0gaGVuY2UgbGVzcyByaXNrIG9mIHByb2dyYW1taW5nIGVycm9ycyBpbnRyb2R1Y2luZyB0aW1pbmcgd2luZG93cy4gSSBob3BlLgotIEEgZmV3IHBlcmZvcm1hbmNlLXJlbGF0ZWQgdHdlYWtzIGFyZSBhbHNvIGluY2x1ZGVkIGluIHRoaXMgY2hlY2staW4uCi0gT25seSB2ZXJ5IG1pbm9yIGdhaW5zIGFyZSBleHBlY3RlZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+am9obmdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBPYmplY3RBcnJheS5qYXZhCi0gU1FMRG9jdW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlByb2plY3QgVXBkYXRlPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+T29wcy5TaG91bGQgaGF2ZSBiZWVuIGNoZWNrZWQgaW4gYXMgcGFydCBvZiB0aGUgSW5jcmVtZW50YWxTQVhTb3VyY2UgY3V0b3Zlci4gCi1Tb3JyeSE8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y29zdGluQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhIGJ1aWxkLnhtbAotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYKLSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzL3N5bnRoZXRpYyBKYXZhVXRpbHMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPjMgc21hbGwgZml4ZXMgdG8gdGhlIGJ1aWxkIHByb2Nlc3MgKCB0byBtYWtlIGl0IHdvcmsgd2l0aCBqZGsxLjQgYW5kIGNyaW1zb24pCi0KLSAtIGV4Y2x1ZGUgSW5jcmVtZW50YWxTQVhTb3VyY2VfWGVyY2VzIGlmIHhlcmNlcyBpcyBub3QgZGV0ZWN0ZWQKLSAtIGNvbW1lbnQtb3V0IHRoZSAibWFpbiIgaW4gSW5jcmVtZW50YWxTQVhTb3VyY2VfRmlsdGVyLmphdmEgKCBpdCBpcyBhCi0gdGVzdCwgYnV0IGhhcyBkZXBzIG9uIHhlcmNlcyApCi0gLSBkb24ndCB0cnkgdG8gbG9hZCB0aGUgY29tcGlsZXIgaW4gc3ludGV0aWMvSmF2YVV0aWxzLiBUaGlzIGlzIGEgbWVzcywKLSBpdCB3YXMgZGViYXRlZCBvbiB0b21jYXQtZGV2IGFuZCBhbnQtZGV2LCBhcyB5b3UgbWF5IGtub3cgc29tZSBwZW9wbGUKLSBkZWNpZGVkIHRvIHJlbW92ZSB0aGUgaW50ZXJuYWwgY29tcGlsZXIgY2xhc3MgKCBzdW4udG9vbHMuamF2YWMuTWFpbiApLAotIGFuZCB0aGF0IGJyYWtlcyBqYXNwZXIsIGFudCBhbmQgbm93IHhhbGFuLgotCi0gSXQgc2VlbXMgcmlnaHQgbm93IHRoZSBvbmx5IHBvcnRhYmxlIHdheSB0byBydW4gdGhlIGNvbXBpbGVyIGlzIHZpYSBjb21tYW5kCi0gbGluZSBjYWxsIGluIGEgc2VwYXJhdGUgcHJvY2VzcyAoIGppa2VzIGNhbiBlYXNpbHkgbWFrZSB1cCBmb3IgdGhlCi0gb3ZlcmhlYWQgb2YgY3JlYXRpbmcgYSBuZXcgcHJvY2VzcyBhbmQgZG9lc24ndCBsZWF2ZSBnYXJiYWdlICkuCi0KLSBRdWVzdGlvbjogaXMgc3ludGhldGljIHVzZWQgPyBTZWVtcyBsaWtlIGEgdmVyeSB1c2VmdWxsIHBhY2thZ2UsIGJ1dCBpZgotIHhhbGFuIGlzIG5vdCB1c2luZyBpdCBpdCBtaWdodCBiZSBiZXR0ZXIgdG8gbW92ZSBpdCB0byB4bWwtY29tbW9ucyBvcgotIGpha2FydGEtY29tbW9ucyBvciBzb21lIG90aGVyIHBsYWNlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIFNRTERvY3VtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Eb24ndCBzZXQgbV9sZXZlbCBhbnltb3JlLCBhcyBpdCBsb29rcyBsaWtlIEpvZSBjb21tZW50ZWQgb3V0IGl0J3MKLSBpbml0aWFsaXphdGlvbi4gbV9sZXZlbCBpcyBubyBsb25nZXIgY2FsbGVkIGJ5IFhhbGFuLCBhbmQgdGhlIGltcGxlbWVudGF0aW9uCi0gY2FuIGNhbGN1bGF0ZSBpdCB3aGVuIGl0IGlzIGNhbGxlZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI0LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIKLSBUcmFuc2Zvcm1lcklkZW50aXR5SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4ZWQgYnVnIDI3NTggKGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9Mjc1OCkuIFRoZSAKLWZsYWcgaW5kaWNhdGluZyB0aGF0IGEgY2FsbCB0byBzdGFydERvY3VtZW50KCkgaW4gdGhlIHJlc3VsdENvbnRlbnRIYW5kbGVyIHdhcyAKLW5lY2Vzc2FyeSB3YXMgbm90IGJlaW5nIHJlc2V0IGZvciBtdWx0aXBsZSB0cmFuc2Zvcm1zLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9zYXgyZHRtIFNBWDJEVE0uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBidWcgMjcyNyAoaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0yNzI3KS4gCi1BdHRyaWJ1dGVzIHdoaWNoIGNvbnRhaW4gYSBuYW1lc3BhY2UgcHJlZml4IGFyZSBpbmRpY2F0ZWQgYnkgcGxhY2luZyBhIG5lZ2F0aXZlIAotbnVtYmVyIGluIHRoZSBhcHByb3ByaWF0ZSBlbnRyeSBpbiB0aGUgbV9kYXRhT3JRTmFtZSBhcnJheS4gVGhlIGFic29sdXRlIHZhbHVlIAotb2YgdGhpcyBudW1iZXIgaXMgYW4gZW50cnkgaW4gbV9kYXRhLiBIb3dldmVyLCBpbiB0aGlzIGV4YW1wbGUsIHRoZXJlIHdlcmUgbm8gCi10ZXh0IG5vZGVzIGJlZm9yZSB0aGUgZmlyc3QgbmFtZXNwYWNlZCBhdHRyaWJ1dGUgc28gdGhlIGVudHJ5IGluIG1fZGF0YSBoYWQgYW4gCi1hcnJheSBpbmRleCBvZiAwLiBUaGlzIHJlc3VsdGVkIGluIGFuIGVudHJ5IG9mIHplcm8sIG5vdCBhIG5lZ2F0aXZlIG51bWJlciwgaW4gCi1tX2RhdGFPclFOYW1lLiBUaGlzIHNpdHVhdGlvbiBnb3Qgc2V2ZXJhbCByb3V0aW5lcyB3aGljaCB0ZXN0ZWQgZm9yICZsdDsgMCAKLWNvbmZ1c2VkLiBJIGxvb2tlZCBhdCBzZXZlcmFsIHdheXMgb2YgZml4aW5nIHRoaXMgYnV0IGRlY2lkZWQgdG8ganVzdCBhbHdheXMgCi1hbGxvY2F0ZSBtX2RhdGEuZWxlbWVudEF0KDApIGVudHJ5IHRvIGEgZHVtbXkgZW50cnkuIFRoZSBvdGhlciBzb2x1dGlvbnMgCi1pbnZvbHZlZCBydW50aW1lIGNoZWNraW5nIHdoaWNoIGNvdWxkIHNsb3cgZG93biB0aGlzIHBpZWNlIG9mIGNvZGUgYW5kIEkgZmVsdCAKLXRoYXQgd2FzdGluZyBvbmUgZW50cnkgd2FzIHdvcnRoIGl0IHRvIG5vdCBzbG93IGRvd24gdGhlIHJ1biB0aW1lLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUKLSBXcml0ZXJUb1VURjhCdWZmZXJlZC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGJ1Z3ppbGxhIGJ1ZyAyNjM5IAotKGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MjYzOSkgd2hlcmUgYnVmZmVyIHdhcyAKLW92ZXJmbG93aW5nIGJlY2F1c2UgdGhlIGV4cGFuc2lvbiBvZiB0aGUgVW5pY29kZSBjaGFyYWN0ZXJzIGludG8gbXVsdGlwbGUgVVRGOCAKLWNoYXJhY3RlcnMgd2FzIG5vdCBiZWluZyBwcm9wZXJseSB0YWtlbiBpbnRvIGFjY291bnQuIE1hbnkgdGhhbmtzIHRvIAotR3VubmxhdWd1ciBUaG9yIEJyaWVtIGZvciBoaXMgIm11bHRpcGx5IGJ5IHRocmVlIiB0cmljay48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgTm9kZVNvcnRlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q29tbWVudGVkIG91dCBOdW1iZXJGb3JtYXQgbV9mb3JtYXR0ZXIgPSBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UoKTsuCi0KLSBNdWt1bmQgcmVwb3J0ZWQ6Ci0KLSBhIG1pbm9yIGltcHJvdmVtZW50IGZvciBhbHBoYWJldGl6ZS54c2wgaXMgdG8gY29tbWVudCBvdXQgdGhlIGxpbmUKLQotIC8vTnVtYmVyRm9ybWF0IG1fZm9ybWF0dGVyID0gTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCk7Ci0KLSBpbiBOb2RlU29ydGVyLmphdmEuIFRoZSB2YXJpYWJsZSBtX2Zvcm1hdHRlciBkb2VzIG5vdCBzZWVtIHRvIGJlIHVzZWQgCi1hbnl3aGVyZSwgYW5kIHRoZSBwZXJmb3JtYW5jZSBkaWZmZXJlbmNlIGlzOgotCi0gQmVmb3JlOiBhbHBoYWJldGl6ZSAxMCA5MCA1MTA4IDE5NiAxNTYgMzQuNTggCi1PSwotIEFmdGVyIDogYWxwaGFiZXRpemUgMTAgNzAgNDMxNiAxOTYgMTU2IAotNDAuOTMgT0s8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMgWFNMVEluZm8ucHJvcGVydGllczxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPjIuMi5EODxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvciBYU0xQcm9jZXNzb3JWZXJzaW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj4yLjIuRDg8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgTm9kZVNvcnRLZXkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlN1Ym1pdHRlZCBmaXggZm9yIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9Mjg1MS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBQcm9jZXNzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5KdXN0IGFkZGVkIHNvbWUgc3R1ZmYgdG8gZGlhZ25vc2UgYnVncyBmb3IgZmxhdm9yIHRoLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIFdhbGtlckZhY3RvcnkuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvY29tcGlsZXIgQ29tcGlsZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvcGF0dGVybnMKLSBDb250ZXh0TWF0Y2hTdGVwUGF0dGVybi5qYXZhIFN0ZXBQYXR0ZXJuLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5UaGVzZSBhcmUgY2hhbmdlcyBzdWJtaXR0ZWQgKG9mZmxpbmUpIGJ5IE11a3VuZCBSYWdoYXZhY2hhcmkvV2F0c29uL0lCTUBJQk1VUy4KLQotIFRoaXMgZml4ZXMgYSBidWcgd2l0aCBtYXRjaD0iY2hhcHRlci8vZm9vdG5vdGVbMV0iIHBhdHRlcm5zLgotCi0gVGhlIG1haW4gY2hhbmdlIGhlcmUgaXMgbWlub3IgdG8gcmVtb3ZlIHRoZSBhdXRvbWF0aWMgYXR0YWNobWVudCBvZiBwYXJlbnQ6OiogCi10byBzaW1wbGUgc3RlcCBwYXR0ZXJucy4KLQotIEhlIGhhcyByZS1pbXBsZW1lbnRlZCBleGVjdXRlUHJlZGljYXRlcyB0byBiZQotIG1vcmUgZWZmaWNpZW50LiBHaXZlbiBhIHBhdHRlcm4gc3VjaCBhcyByb3dbNl0sIGl0Ci0gZG9lcyBub3QgaXRlcmF0ZSBvdmVyIHRoZSBlbnRpcmUgYXhpcyB1bnRpbCBpdCByZWFjaGVzCi0gdGhlIG5vZGUgdG8gc2VlIGlmIGl0IGlzIHRoZSBzaXh0aCBub2RlLiBSYXRoZXIsCi0gc3RhcnRpbmcgZnJvbSB0aGUgY3VycmVudCBub2RlLCBpdCB3b3JrcyBiYWNrd2FyZHMKLSAocHJlY2VkaW5nIHNpYmxpbmdzKSB1bnRpbCBpdCBlaXRoZXIgcnVucyBvdXQgb2Ygbm9kZXMKLSBvciBmaW5kcyBtb3JlIHRoYW4gc2l4IG5vZGVzIHRoYXQgbWF0Y2ggdGhlCi0gcHJlZGljYXRlIFtJIGNhbiBleHBsYWluIGl0IGJldHRlciBpZiBkZXNpcmVkXS4KLSBUaGlzIG9wdGltaXphdGlvbiBpbXByb3ZlcyBwZXJmb3JtYW5jZSBzbGlnaHRseQotIG92ZXJhbGwuIEl0IGhlbHBzIGRlY295IGFuZCBwYXR0ZXJucyBtb3N0IChieQotIGFib3V0IDEwJSkuCi0KLSBUaGUgb3RoZXIgb3B0aW1pemF0aW9uIHRoYXQgSSBpbXBsZW1lbnRlZCB3YXMgdGhlCi0gZm9sbG93aW5nLiBGb3IgYSBwYXR0ZXJuIGZvb1tdWzNdW11bNF0gLi4uLCB3aGVyZSBtb3JlCi0gdGhhbiBvbmUgcHJlZGljYXRlIGlzIGEgbnVtYmVyIChwb3NpdGlvbiBjaGVjayksCi0gaW4gY2hlY2tpbmcgdGhlIHByZWRpY2F0ZSBbNF0sIHRoZSBmYWN0IHRoYXQgdGhlCi0gY3VycmVudCBub2RlIGhhcyBwYXNzZWQgZm9vW11bM10gaW1wbGllcyB0aGF0IGl0IGlzCi0gdGhlIG9ubHkgbm9kZSB0aGF0IGlzIHRoZSB0aGlyZCBub2RlIGFtb25nIGl0cwotIHNpYmxpbmdzIHRoYXQgcGFzc2VzIGZvb1tdLiBUaGVyZWZvcmUsIGFueQotIHN1YnNlcXVlbnQgcG9zaXRpb24gY2hlY2tzIGNhbiBiZSB0cnVlIGlmIGFuZAotIG9ubHkgaWYgdGhlIHBvc2l0aW9uIGlzIFsxXS4gVGhpcyBvcHRpbWl6YXRpb24gaXMgbm90Ci0gdXNlZCBieSB0aGUgeHNsdG1hcmsgYmVuY2htYXJrcyBhbmQgc28gZG9lcwotIG5vdCBvZmZlciBhbnkgcGVyZm9ybWFuY2UgYmVuZWZpdHMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMgRGVzY2VuZGFudEl0ZXJhdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MTMzNjxici8+PGJyLz48L2xpPjwvdWw+PG5vdGU+VGhpcyByZWxlYXNlIGluY2x1ZGVzIG5vIHVwZGF0ZXMgb2YgdGhlIGNvbXBhdGliaWxpdHkgc291cmNlIGNvZGUgKG5vdyBkZXByZWNhdGVkKS48L25vdGU+Ci08L3MzPgotPHMzIHRpdGxlPSJDaGFuZ2VzIGZvciAmeHNsdDRqOyAyLjIuRDciPgotPHA+IENvcmUgKE5vbi1YU0xUQykgc291cmNlIGNvZGUgdXBkYXRlczo8L3A+PHVsPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMDMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBEVE1NYW5hZ2VyRGVmYXVsdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+U2luY2UgdGhlIHJlYWwgcm9vdCBvZiBvdXIgdHJlZSBtYXkgYmUgYSBEb2N1bWVudEZyYWdtZW50LCB3ZSBuZWVkIHRvCi0gdXNlIGdldFBhcmVudCB0byBmaW5kIHRoZSByb290LCBpbnN0ZWFkIG9mIGdldE93bmVyRG9jdW1lbnQuIE90aGVyd2lzZQotIERPTTJEVE0jZ2V0SGFuZGxlT2ZOb2RlIHdpbGwgYmUgdmVyeSB1bmhhcHB5LgotIFJlc3VsdCBvZiByZXBvcnQgdmlhIHByaXZhdGUgbWFpbCBieSBDYXJzdGVuIFppZWdlbGVyIG9mIGJyZWFrYWdlCi0gaW4gQ29jb29uLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMDUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUgU2VyaWFsaXplclRvSFRNTC5qYXZhCi0gU2VyaWFsaXplclRvWE1MLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5NYWRlIG1fbWF4Q2hhcmFjdGVyLCBhY2N1bURlZmF1bHRFc2NhcGUsCi0gYWNjdW1EZWZhdWx0RW50aXR5LCBhbmQgbV9pc1Jhd1N0YWNrCi0gcHJvdGVjdGVkIGJ5IHJlcXVlc3QgZnJvbSBKb2hhbm5lcyBGYXJyZW5rb3BmCi0gYW5kIEZyYW5rIE5lc3RlbC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzA1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zIEZ1bmNOb3JtYWxpemVTcGFjZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW4gZXhlY3V0ZUNoYXJzVG9Db250ZW50SGFuZGxlciBjaGVjayBmaXJzdCBmb3IKLSBEVE0uTlVMTCBiZWZvcmUgdHJ5aW5nIHRvIGdldCB0aGUgRFRNLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMDUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgRmFzdFN0cmluZ0J1ZmZlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGJ1ZyByZXBvcnRlZCBieSAiQ2Fyc3RlbiBaaWVnZWxlciIgJmx0O2N6aWVnZWxlckBzdW5kbi5kZSZndDsuCi0gVGVzdCBmb3IgdGhpcyBpcyB3aGl0ZXNwYWNlMjMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8wNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBTdWJhbGxvY2F0ZWRJbnRWZWN0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkRyb3Agc29tZSBib3VuZHMgdGVzdHMgZm9yIGNhc2VzIHdoaWNoIHNob3VsZG4ndCBhcmlzZSBpbiB0aGUgZmlyc3QgcGxhY2UsIAotc2luY2UgdGhpcyBpcyBhbiBpbm5lci1sb29wIG1ldGhvZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzA1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIFN1YmFsbG9jYXRlZEJ5dGVWZWN0b3IuamF2YQotIFN1YmFsbG9jYXRlZEludFZlY3Rvci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+U3luY2ggU3ViYWxsb2NhdGVkQnl0ZVZlY3RvciB3aXRoIGNoYW5nZWQgU3ViYWxsb2NhdGVkSW50VmVjdG9yPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8wNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIENvcm91dGluZVNBWFBhcnNlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmV2ZXJ0IGJhY2sgdG8gdGhyb3dpbmcgYSBzaHV0ZG93bkV4Y2VwdGlvbiBpZiAoYXJnID09IG51bGwpIGluIGNvX3lpZWxkLiBJIAotc2VlIHRoaXMKLSBvY2N1ciBpZiB0aGUgcGFyc2VyIGlzIENyaW1zb24gd2l0aCBvdXRwdXRcb3V0cHV0MDEsIGFuZCBpdCBjYXVzZXMKLSBhIGhhbmcgaWYgdGhlIHNodXRkb3duRXhjZXB0aW9uIGlzIG5vdCB0aHJvd24uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8wNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZSBTZXJpYWxpemVyVG9YTUwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1ha2UgYWNjdW1EZWZhdWx0RW50aXR5IGFuZCBhY2N1bURlZmF1bHRFc2NhcGUgbm9uLWZpbmFsLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIENoaWxkVGVzdEl0ZXJhdG9yLmphdmEKLSBPbmVTdGVwSXRlcmF0b3IuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvZnVuY3Rpb25zIEZ1bmNFeHRGdW5jdGlvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBKb2huIEcuIGZvciB0aGUgU1FMIGV4dGVuc2lvbjogaGFuZGxlIHJldHVybiB0eXBlcyBvZgotIERUTSBhbmQgRFRNQXhpc0l0ZXJhdG9yLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMDkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkluIGV4ZWN1dGVDaGlsZFRlbXBsYXRlcywgc29tZWhvdyB0aGVyZSB3YXMgYSBwb3BNb2RlIHdpdGhvdXQKLSBhIGNvcnJlc3BvbmRpbmcgcHVzaE1vZGUuIFRoZSBwdXNoTW9kZSB3YXMgYWRkZWQuCi0gQWRkcmVzc2VzIGJ1ZyBwb3N0ZWQgYnkgU3RlcGhhbmUgQmFpbGxpZXogJmx0O3NiYWlsbGllekBpbWVkaWF0aW9uLmNvbSZndDsKLSBvbiB0aGUgeGFsYW4tZGV2IGxpc3Qgb24gMDcvMDkvMjAwMSAwNzoyOCBBTS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucyBFeHByZXNzaW9uQ29udGV4dC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgU3R5bGVzaGVldFJvb3QuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggVmFyaWFibGVTdGFjay5qYXZhCi0gWFBhdGhDb250ZXh0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZXNvbHZlIGJ1Z3ppbGxhIDIzNTUgCi0mbHQ7aHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0yMzU1Jmd0Oy4gVG8gbWFrZSB0aGUgCi1mdW5jdGlvbmFsaXR5IGNsZWFyZXIsIEkndmUgY2hhbmdlZCB0aGUgbWV0aG9kIG5hbWUgZnJvbSBnZXRWYXJpYWJsZSB0byAKLWdldFZhcmlhYmxlT3JQYXJhbSBzaW5jZSB0aGUgcm91dGluZSB3aWxsIHBpY2sgdXAgZWl0aGVyIG9uZS4gQWxzbyBmaXhlZCBhIAotYnVnIHdoZXJlIHRvcCBsZXZlbCB2YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMgd2VyZSBub3QgZ2V0dGluZyBtYXJrZWQgYXMgc3VjaC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliIEV4dGVuc2lvbnMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggWFBhdGhDb250ZXh0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZXNvbHZlIGJ1Z3ppbGxhIDI1MjMgCi0mbHQ7aHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0yNTIzJmd0Oy4gZXZhbHVhdGUgZXh0ZW5zaW9uIAotZnVuY3Rpb24gd2FzIG5vdCByZWZhY3RvcmVkIHdpdGggRFRNLiBBbHNvIG5lZWQgdG8gYWRkIGZ1bmN0aW9uIHRvIAotWFBhdGhDb250ZXh0LlhQYXRoRXhwcmVzc2lvbkNvbnRleHQgdG8gYWxsb3cgYW4gZXh0ZW5zaW9uIHRvIG9idGFpbiB0aGUgCi1hc3NvY2lhdGVkIFhQYXRoQ29udGV4dC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvYXhlcyBEZXNjZW5kYW50SXRlcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBwcm9ibGVtIHdpdGggZGVzY2VuZGFudC1vci1zZWxmIGFuZCBmcm9tIHJvb3QgcGF0dGVybi4gV2hlbiBmcm9tIHJvb3QsIAotZGVzY2VkYW50IG9yIHNlbGYgd2FzIG5vdCByZWNvZ25pemVkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9kb20yZHRtIERPTTJEVE0uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlF1aWNrIHBhdGNoIHRvIGhhbmRsZSBjYXNlIHdoZXJlIHNvbWVvbmUgd2FudHMgdG8gYnVpbGQgYSBEVE0gZnJvbQotIGFuIEVsZW1lbnQgcmF0aGVyIHRoYW4gZnJvbSBhIERvY3VtZW50LiBUaGUgQXR0ciBoYW5kbGluZyBtaWdodCB3YW50IHRvCi0gbW92ZSBkb3duIGludG8gYWRkTm9kZS4KLQotIFRoaXMgb3BlbnMgc2V2ZXJhbCBjYW5zIG9mIHdvcm1zIC0tIHdoYXQgaWYgdGhlIG5leHQgdXNlciB3YW50cyB0aGUKLSByb290IG9mIHRoZWlyIERUTSB0byBiZSBhbiBFbnRpdHlSZWZlcmVuY2Ugbm9kZSwgd2hpY2ggaGFzIG5vIERUTQotIG5vZGUgZXF1aXZhbGVudCAtLSBidXQgd2UnbGwgZWF0IHRob3NlIHdoZW4gd2UgZ2V0IHRvIHRoZW0uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYiBFeHRlbnNpb25zLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Nb2RpZnkgZGlzdGluY3QoKSBleHRlbnNpb24gc28gdGhhdCBpdCBubyBsb25nZXIgcmVsaWVzIG9uIERPTUhlbHBlciB3aGljaCBpcyAKLWRlcHJlY2F0ZWQgYnV0IHVzZXMgRXhwcmVzc2lvbkNvbnRleHQudG9TdHJpbmcoKS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzIFhTTFRFcnJvclJlc291cmNlcy5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFjZSBQcmludFRyYWNlTGlzdGVuZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtIERUTS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBEVE1Eb2N1bWVudEltcGwuamF2YQotIEV4cGFuZGVkTmFtZVRhYmxlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL2RvbTJkdG0gRE9NMkRUTS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9zYXgyZHRtIFNBWDJEVE0uamF2YTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIgTm9kZUluZm8uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgWGFsYW5Qcm9wZXJ0aWVzLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIE5vZGVMb2NhdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BcHBsaWNhdGlvbiBvZiBwYXRjaCBzdWJtaXR0ZWQgYnkgT3ZpZGl1IFByZWRlc2N1ICZsdDtvdmlkaXVAY3VwLmhwLmNvbSZndDsKLSBmb3IgZmlsZSwgbGluZSwgY29sdW1uIG51bWJlciBpbmZvcm1hdGlvbiBmb3IgWE1MIHNvdXJjZSBkb2N1bWVudC4KLQotIFtBIG1hZGUgb25lIGNoYW5nZTogbV9zb3VyY2VTeXN0ZW1JZCwgbV9zb3VyY2VMaW5lLCBhbmQKLSBtX3NvdXJjZUNvbHVtbiBhcmUgbm90IGNyZWF0ZWQgd2l0aCB0aGUgbWVtYmVyIHZhcmlhYmxlCi0gaW5pdGlhbGl6ZXIsIHNpbmNlIHRoZXkgYXJlIGluaXRpYWxpemVkIGluIHNldFByb3BlcnR5Ll0KLQotIFRoZSBmb2xsb3dpbmcgcGF0Y2ggaXMgYSByZXdvcmsgb2YgYSBwcmV2aW91cyBwYXRjaCBJJ3ZlIHN1Ym1pdHRlZCBvbgotIE1heSAyNCBhZ2FpbnN0IHRoZSBTdHJlZSBtb2RlbCwgY3VycmVudCBhdCB0aGF0IHRpbWUuIFRoaXMgdGltZSB0aGUKLSBwYXRjaCBpcyBhZ2FpbnN0IHRoZSBEVE0gbW9kZWwsIGFuZCBtYWtlcyB1c2Ugb2YgRFRNIGZlYXR1cmVzIHRvCi0gb3B0aW1pemUgdGhlIGxvb2t1cCB0aW1lIGFuZCBzdG9yYWdlIHJlcXVpcmVtZW50cy4gSSBob3BlIHRoaXMgdGltZQotIHRoZSBwYXRjaCBnZXRzIGluY29ycG9yYXRlZCBpbiB0aGUgQ1ZTIHJlcG9zaXRvcnksIGJlZm9yZSBhbnkgbWFqb3IKLSByZXdvcmsgaGFwcGVucyBhZ2FpbiA7LSkuCi0KLSBBcyB3aXRoIHRoZSBwcmV2aW91cyBwYXRjaCwgdGhlcmUgaXMgbm8gb3ZlcmhlYWQgaW4gc3BhY2Ugb3IgdGltZSBpZgotIHNvdXJjZSBpbmZvcm1hdGlvbiBpcyBub3QgbmVlZGVkLgotCi0gRnJvbSBhIHVzZXIgcGVyc3BlY3RpdmUsIHRoaXMgZmVhdHVyZSBjYW4gYmUgdHVybmVkIG9uIGJ5IHBhc3NpbmcgdGhlCi0gLUwgZmxhZyB0byBYYWxhbiB3aGVuIGludm9raW5nIGl0IGZyb20gdGhlIGNvbW1hbmQKLSBsaW5lLiBQcm9ncmFtbWF0aWNhbGx5IHlvdSBjYW4gYWxzbyBlbmFibGUgaXQgYnkgaW52b2tpbmcgdGhlCi0gc2V0UHJvcGVydHkgbWV0aG9kIG9uIHRoZSBUcmFuc2Zvcm1lckltcGw6Ci0KLSBUcmFuc2Zvcm1lckltcGwgaW1wbCA9ICgoVHJhbnNmb3JtZXJJbXBsKSB0cmFuc2Zvcm1lcik7Ci0gCi1pbXBsLnNldFByb3BlcnR5KG9yZy5hcGFjaGUueGFsYW4udHJhbnNmb3JtZXIuWGFsYW5Qcm9wZXJ0aWVzLlNPVVJDRV9MT0NBVElPTiwKLSBCb29sZWFuLlRSVUUpOwotCi0gQSBUcmFuc2Zvcm1lciAicHJvcGVydHkiIGlzIGRpZmZlcmVudCBmcm9tIGEgImZlYXR1cmUiOiB3aGlsZSBhCi0gZmVhdHVyZSBpcyBzcGVjaWZpYyB0byBhbGwgdGhlIHRyYW5zZm9ybWVyIGluc3RhbmNlcyBhbmQgdXN1YWxseQotIHJlZmVycyB0byBhbiBpbXBsZW1lbnRhdGlvbiBhc3BlY3QsIGEgcHJvcGVydHkgaXMgYSBydW50aW1lIGNhcGFiaWxpdHkKLSB0aGF0IGlzIHNldCBwZXIgVHJhbnNmb3JtZXIgaW5zdGFuY2UuIEN1cnJlbnRseSB0aGUgb25seSBwcm9wZXJ0eQotIGFkZGVkIGJ5IHRoaXMgcGF0Y2ggaXMgdGhlIHNvdXJjZSBsb2NhdGlvbiBpbiB0aGUgWE1MIHNvdXJjZSBkb2N1bWVudC4KLQotIFRoZSBwYXRjaCBhZGRzIHR3byBtZXRob2RzIHRvIHRoZSBEVE0gaW50ZXJmYWNlOgotCi0gcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5LCBPYmplY3QgdmFsdWUpOwotIHB1YmxpYyBTb3VyY2VMb2NhdG9yIGdldFNvdXJjZUxvY2F0b3JGb3IoaW50IG5vZGUpOwotCi0gVGhlIHNlY29uZCBtZXRob2QgaXMgdXNlZCB0byBvYnRhaW4gdGhlIHNvdXJjZSBsb2NhdGlvbiBnaXZlbiBhIG5vZGUKLSBoYW5kbGUuCi0KLSBUaGVyZSBhcmUgdHdvIHdheXMgeW91IGNhbiBtYWtlIHVzZSBvZiB0aGUgc291cmNlIGxvY2F0aW9uLiBUaGUgZmlyc3QKLSBvbmUgaXMgZnJvbSB3aXRoaW4gYSBzdHlsZXNoZWV0LCB3aGVyZSB5b3UgY2FuIGhhdmUgc29tZXRoaW5nIGxpa2UKLSB0aGlzOgotCi0gJmx0O3hzbDpzdHlsZXNoZWV0Ci0geG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0geG1sbnM6bm9kZWluZm89InhhbGFuOi8vb3JnLmFwYWNoZS54YWxhbi5saWIuTm9kZUluZm8iCi0gdmVyc2lvbj0iMS4wIiZndDsKLQotICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9IioiJmd0OwotIC8vbm9kZSAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0ibmFtZSgpIi8mZ3Q7Ci0gLy9maWxlICZsdDt4c2w6dmFsdWUtb2Ygc2VsZWN0PSJub2RlaW5mbzpzeXN0ZW1JZCgpIi8mZ3Q7Ci0gLy9saW5lICZsdDt4c2w6dmFsdWUtb2Ygc2VsZWN0PSJub2RlaW5mbzpsaW5lTnVtYmVyKCkiLyZndDsKLSAvL2NvbHVtbiAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0ibm9kZWluZm86Y29sdW1uTnVtYmVyKCkiLyZndDsKLSAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcy8mZ3Q7Ci0gJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0KLSAmbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotCi0gSWYgbm8gYXJndW1lbnRzIGFyZSBwYXNzZWQgdG8gdGhlIHN5c3RlbUlkKCksIGxpbmVOdW1iZXIoKSBvcgotIGNvbHVtbk51bWJlcigpIGZ1bmN0aW9ucywgdGhlIGNvcnJlc3BvbmRpbmcgaW5mb3JtYXRpb24gb2YgdGhlIGN1cnJlbnQKLSBjb250ZXh0IG5vZGUgaXMgcmV0dXJuZWQuIEEgbm9kZSBjYW4gYmUgcGFzc2VkIGFzIGFyZ3VtZW50IHRvIHRoZQotIGFib3ZlIGZ1bmN0aW9ucywgaW4gd2hpY2ggY2FzZSB0aGUgY29ycmVzcG9uZGluZyBpbmZvcm1hdGlvbiBhYm91dAotIHRoYXQgbm9kZSBpcyByZXR1cm5lZC4gSWYgYSBub2RlIHNldCBjb250YWluaW5nIG11bHRpcGxlIG5vZGVzIGlzCi0gcGFzc2VkIGFzIGFyZ3VtZW50LCBvbmx5IHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgc2V0Ci0gaXMgcmV0dXJuZWQuCi0KLSBUaGUgc2Vjb25kIHdheSBvZiBvYnRhaW5pbmcgdGhlIHNvdXJjZSBsb2NhdGlvbiBpcwotIHByb2dyYW1tYXRpY2FsbHkuIEdpdmVuIGEgTm9kZSBpbnN0YW5jZSwgb25lIGNhbiBvYnRhaW4gdGhlIG93bmVyIERUTQotIGFuZCB0aGUgbm9kZSBoYW5kbGUgKGFuIGludGVnZXIpIHRoYXQgcmVwcmVzZW50cyB0aGUKLSBub2RlLiBVbmZvcnR1bmF0ZWx5IEkgZGlkbid0IHNlZSBhbnkgd2F5IG9mIGhpZGluZyB0aGlzOiBpZiB5b3UgZmluZAotIG9uZSBwbGVhc2UgbGV0IG1lIGtub3cgYW5kIEknbGwgZml4IGl0LgotCi0gVGhlIGZvbGxvd2luZyBleGFtcGxlIGlzIGV4dHJhY3RlZCBmcm9tIFByaW50VHJhY2VMaXN0ZW5lciBhbmQKLSBpbGx1c3RyYXRlcyB0aGUgQVBJOgotCi0gTm9kZSBzb3VyY2VOb2RlID0gZXYubV9zb3VyY2VOb2RlOwotIGludCBub2RlSGFuZGxlciA9ICgoRFRNTm9kZVByb3h5KXNvdXJjZU5vZGUpLmdldERUTU5vZGVOdW1iZXIoKTsKLSBTb3VyY2VMb2NhdG9yIGxvY2F0b3IgPSAoKERUTU5vZGVQcm94eSlzb3VyY2VOb2RlKS5nZXREVE0oKQotIC5nZXRTb3VyY2VMb2NhdG9yRm9yKG5vZGVIYW5kbGVyKTsKLQotIG1fcHcucHJpbnRsbigiU2VsZWN0ZWQgc291cmNlIG5vZGUgJyIgKyBzb3VyY2VOb2RlLmdldE5vZGVOYW1lKCkKLSArICInLCBhdCAiICsgbG9jYXRvcik7PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyIENvbXBpbGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggYnVnIDIxNzUgJmx0O2h0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MjE3NSZndDsgYnkgCi1hZGRpbmcgdGhlIGN1cnJlbnQgdGltZSB0byB0aGUgbWV0aG9kIGtleSB0byBlbnN1cmUgbWV0aG9kIGtleSB1bmlxdWVuZXNzLiAKLU11bHRpcGxlIENvbXBpbGVycyB3ZXJlIGdldHRpbmcgdGhlIHNhbWUgaGFzaENvZGUsIHBhcnRpY3VsYXJseSBpbiBWaXN1YWwgQWdlIAotZm9yIEphdmEsIGR1ZSB0byBhZ2dyZXNzaXZlIGdhcmJhZ2UgY29sbGVjdGlvbi4gQWRkZWQgdGhlIGN1cnJlbnQgdGltZSBpbiAKLW1pbGxzIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gdGhlIGRpZmZlcmVudCBmdW5jdGlvbnMgYmVpbmcgY29tcGlsZWQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtVmFyaWFibGUuamF2YQotIFN0eWxlc2hlZXRSb290LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIFZhcmlhYmxlU3RhY2suamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvb3BlcmF0aW9ucyBWYXJpYWJsZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVzb2x2ZSBidWd6aWxsYSAyMzU1IAotJmx0O2h0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MjM1NSZndDsuIEFkZGVkIGNvZGUgdG8gCi1wb3B1bGF0ZSBtX2luZGV4IGZvciBnbG9iYWwgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzLiBJZiB0aGUgYmFja3dhcmQgc2VhcmNoIAotZm9yIHRlbXBsYXRlcyByZWFjaGVzIHRoZSB0b3AgbGV2ZWwsIHVzZSB0aGUgbGlzdCBvZiBjb21wb3NlZCB0b3AtbGV2ZWwgCi12YXJpYWJsZXMgYW5kIHBhcmFtZXRlcnMgZnJvbSBTdHlsZXNoZWV0Um9vdC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYgRFRNTm9kZVByb3h5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Ob3cgaW1wbGVtZW50cyBEb2N1bWVudEZyYWdtZW50Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3JlcyBYU0xUSW5mby5wcm9wZXJ0aWVzPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VXBkYXRlZCB2ZXJzaW9uIHRvIDIuMi4wLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvciBYU0xQcm9jZXNzb3JWZXJzaW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5VcGRhdGVkIHZlcnNpb24gdG8gMi4yLjAuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTU5vZGVQcm94eS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4ZWQgdmVyeSB1Z2x5IGJ1ZywgbGVmdC1vdmVyIGZyb20gRFRNMSwgaW4gZ2V0VmFsdWUsIHdoZXJlICsxIHdhcyBiZWluZyAKLWFkZGVkIHBlciB0aGUgb2xkIGF0dHJpYnV0ZSBzdHJ1Y3R1cmUgb2YgRFRNMS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+am9obmdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBDb25uZWN0aW9uUG9vbC5qYXZhCi0gRGVmYXVsdENvbm5lY3Rpb25Qb29sLmphdmEgUG9vbGVkQ29ubmVjdGlvbi5qYXZhCi0gUXVlcnlQYXJhbWV0ZXIuamF2YSBYQ29ubmVjdGlvbi5qYXZhPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgQ29ubmVjdGlvblBvb2xNYW5hZ2VyLmphdmEKLSBPYmplY3RBcnJheS5qYXZhIFNRTERvY3VtZW50LmphdmEKLSBTUUxFcnJvckRvY3VtZW50LmphdmE8YnIvPjxyZWY+UmVtb3ZlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIENvbHVtbi5qYXZhCi0gQ29sdW1uQXR0cmlidXRlLmphdmEgQ29sdW1uRGF0YS5qYXZhCi0gQ29sdW1uSGVhZGVyLmphdmEgRXh0ZW5zaW9uRXJyb3IuamF2YSBSb3cuamF2YQotIFJvd1NldC5qYXZhIFNRTEV4dGVuc2lvbkVycm9yLmphdmEKLSBTdHJlYW1hYmxlTm9kZS5qYXZhIFhDb25uZWN0aW9uUG9vbE1hbmFnZXIuamF2YQotIFhTdGF0ZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpcnN0IHJvdW5kIG9mIGNoYW5nZXMgdG8gcG9ydCBET00gbW9kZSB0byBEVE0gTW9kZQotIFN1Ym1pdHRlZCBieTogSm9obiBHZW50aWxpbiBtYWlsdG86Ly9qb2huZ0BhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmL3NheDJkdG0gU0FYMkRUTS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2hlY2sgaWYgbG9jYXRvciBwcm9wZXJ0eSBpcyBzZXQgYmVmb3JlIHRyeWluZyB0byB1c2UgbG9jYXRvciBmaWVsZHM8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhY2UgUHJpbnRUcmFjZUxpc3RlbmVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Eb24ndCBwcmludCBsb2NhdG9yIG1lc3NhZ2UgaWYgbG9jYXRvciBpcyBudWxsPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtZXJIYW5kbGVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW4gc3RhcnREb2N1bWVudCwgcnVuIG1fY29udGVudEhhbmRsZXIuc3RhcnREb2N1bWVudCBiZWZvcmUgeW91IHN0YXJ0IHRoZSAKLXRocmVhZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DYWxsIHdhaXQgZm9yIGluaXRpYWwgZXZlbnRzIGJlZm9yZSB0aGUgdGhlIHRyYW5zZm9ybSBpcyBzdGFydGVkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBDb3JvdXRpbmVTQVhQYXJzZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFsbG93IGNvX3lpZWxkIHRvIGJlIGNhbGxlZCBhZnRlciB0aGUgcGFyc2UgaGFzIGZpbmlzaGVkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIFNRTERvY3VtZW50LmphdmEKLSBTUUxFcnJvckRvY3VtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBzZXRQcm9wZXJ0eSBhbmQgZ2V0U291cmNlTG9jYXRvckZvciBlbXB0eSBtZXRob2RzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9kb20yZHRtIERPTTJEVE0uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBwcm9ibGVtIHJlcG9ydGVkIGJ5IENhcnN0ZW4gWmllZ2VsZXIgJmx0O2N6aWVnZWxlckBzdW5kbi5kZSZndDsuIFVzaW5nIAotQXBwbHlYUGF0aCAob3IgZG9pbmcgYSB0cmFuc2Zvcm1hdGlvbikgd2l0aCBET00gaW5wdXQgd2FzIHJlc3VsdGluZyBpbiBhbiBOUEUgCi1kdWUgdG8gZGVjbGFyZU5hbWVzcGFjZUluQ29udGV4dCgpIGJlaW5nIGNhbGxlZCBiZWZvcmUgc2V0dGluZyBtX2V4cHR5cGUgd2hpY2ggCi1pcyBuZWVkZWQgYnkgZGVjbGFyZU5hbWVzcGFjZUluQ29udGV4dCgpLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lcgotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZCBwYXVzZUZvclRyYW5zZm9ybVRocmVhZFN0YXJ0dXAuIENhbGwgdGhpcyBpbiBzdGFydERvY3VtZW50IGp1c3QKLSBhZnRlciBzdGFydGluZyB0aGUgdHJhbnNmb3JtIHRocmVhZC4gVGhpcyBzaG91bGQgZ2V0IHJpZCBvZiBhbnkgdmFyaWFiaWxpdHkKLSB3aXRoIHJhY2luZyB0aHJlYWRzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zCi0gWFNMUHJvY2Vzc29yQ29udGV4dC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IHByb2JsZW0gcmVwb3J0ZWQgYnkgamFzb24gaGVkZGluZ3MgJmx0O0phc29uLkhlZGRpbmdzQFN1bi5DT00mZ3Q7LgotCi0gIkluIHYyLjAuMSwgSSB3YXMgYWJsZSB0byBwYXNzIGEgTm9kZSB0byB0aGlzIGZ1bmN0aW9uIGFuZCBoYXZlIHRoZSBub2RlCi0gYmUgY29waWVkIHRvIHRoZSByZXN1bHQgdHJlZSAoYXMgZXhwZWN0ZWQpLiBJbiB0aGUgc291cmNlIGNvZGUgZm9yCi0gWFNMUHJvY2Vzc29yQ29udGV4dCwgaXQgYXBwZWFycyB0aGF0IHRoZSBvbmx5IG9iamVjdHMgdGhhdCBjYW4gYmUgc2VudAotIHRvIHRoZSByZXN1bHQgdHJlZSBhcmUgWE9iamVjdHMuIEV2ZXJ5dGhpbmcgZWxzZSBpcyBjb252ZXJ0ZWQgdG8gYQotIFN0cmluZy4gU28gZm9yIGluc3RhbmNlLCBJIGNhbiBubyBsb25nZXIgY3JlYXRlIGEgUHJvY2Vzc2luZ0luc3RydWN0aW9uCi0gYW5kIHBhc3MgaXQgdG8gdGhlIHJlc3VsdCB0cmVlIHZpYSB0aGlzIG1ldGhvZCBzaW5jZSB0aGUgUEkgaXMgc2ltcGx5Ci0gY29udmVydGVkIHRvIGEgU3RyaW5nLiI8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplIFNlcmlhbGl6ZXJUb0hUTUwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFwcGxpY2F0aW9uIG9mIHBhdGNoIHN1Ym1pdHRlZCBieSBCZW5qYW1pbiBSaWVmZW5zdGFobCAKLSZsdDtCZW5qYW1pbi5SaWVmZW5zdGFobEBpc2lvbi5uZXQmZ3Q7Ci0KLSBNb3RpdmF0aW9uOiBXZSBhcmUgdXNpbmcgWGFsYW4gdG8gZ2VuZXJhdGUgSFRNTCBwYWdlcy4gV2UgaGF2ZSB0aGUKLSByZXF1aXJlbWVudCB0byBpbnRlZ3JhdGUgY29kZSBmb3IgYWQgYmFubmVycy4gVGhlIGFkIHNlcnZlciBwcm92aWRlcgotIGhhcyB3cml0dGVuIHRoZSBjb2RlIHRvIHVzZSB3aXRoIGNvbXBhdGliaWxpdHkgdG8gTmV0U2NhcGUgNCBpbiBtaW5kLgotIFRoZSBjb2RlIHVzZXMgdGhlIE5ldFNjYXBlIHByb3ByaWV0b3J5ICZsdDtMQVlFUiZndDsgZWxlbWVudCBhbmQgJmx0O0lGUkFNRSZndDsKLSBlbGVtZW50cyBmb3Igb3RoZXIgYnJvd3NlcnMuIFRoZSBTUkMgYXR0cmlidXRlcyBvZiB0aGVzZSBlbGVtZW50cwotIGNvbnRhaW4gVVJMcyB3aXRoIHNldmVyYWwgVVJMIHBhcmFtZXRlcnMgc2VwYXJhdGVkIGJ5ICcmYW1wOycsIGFzIGlzIHRoZQotIGNvbW1vbiBjb252ZW50aW9uLgotCi0gUHJvYmxlbTogVGhlIGNvZGUgaXMgaW50ZWdyYXRlZCBpbiBvdXIgWFNMIHN0eWxlc2hlZXRzLiBJbiB0aGUKLSBzdHlsZXNoZWV0IHRoZSAnJmFtcDsnIGhhcyB0byBiZSB3cml0dGVuIGFzIHRoZSBlbnRpdHkgJyZhbXA7YW1wOycuIFRoYXQncwotIG9rLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGluIHRoZSBvdXRwdXQgdGhlICcmYW1wOycgaXMgYWxzbyB3cml0dGVuIGFzCi0gJyZhbXA7YW1wOycgd2hpY2ggaXMgbm90IG9rLCBiZWNhdXNlIE5ldFNjYXBlIGRvZXNuJ3QgdW5kZXJzdGFuZCB0aGF0LgotIE9UT0ggdGhlIHNhbWUgVVJMIGlzIHdyaXR0ZW4gd2l0aCAnJmFtcDsnIHdoZW4gdXNlZCBpbiBhbiAmbHQ7QSZndDsgZWxlbWVudC4KLQotIFNvbHV0aW9uOiBUaGlzIGdvZXMgZG93biB0byBhIGRpZmZlcmVudCBoYW5kbGluZyBvZiBhdHRyaWJ1dGUgdmFsdWVzCi0gaW4gdGhlIGNsYXNzIFNlcmlhbGl6ZVRvSFRNTCwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGF0dHJpYnV0ZSBpbgotIHF1ZXN0aW9uIGlzIGtub3duIHRvIGNvbnRhaW4gYSBVUkkgb3Igbm90LiBYYWxhbiBrbm93cyB0aGlzIGZvciAmbHQ7QSZndDsKLSBidXQgbm90IGZvciAmbHQ7TEFZRVImZ3Q7IGFuZCAmbHQ7SUZSQU1FJmd0Oy4gV2hlbiBJIGNvbXBhcmUgdGhlIGxpc3QgaW4KLSBTZXJpYWxpemVUb0hUTUwuamF2YSB3aXRoIHRoZSBIVE1MIHNwZWNzLCBJIGZpbmQgYSBjb3VwbGUgb2Ygb3RoZXIKLSBtaXNzaW5nIFVSSSBhdHRyaWJ1dGVzIGluIFNlcmlhbGl6ZVRvSFRNTC5qYXZhLiBXaGVuIEkgYWRkIHRoZQotIG1pc3NpbmcgcGllY2VzLCB0aGUgZ2VuZXJhdGlvbiB3b3JrcyBmaW5lLgotCi0gUGF0Y2g6IEhlcmUgaXMgdGhlIHBhdGNoIChkaWZmIC1jKSBmb3IgeGFsYW4tal8yXzJfRDYuIEkgYWxzbyBoYXZlCi0gb25lIGZvciB4YWxhbi1qXzJfMF8xIHdoaWNoIGlzIHRoZSB2ZXJzaW9uIEkgYWN0dWFsbHkgdGVzdGVkIHRoaXMKLSB3aXRoLiBQbGVhc2UgbGV0IG1lIGtub3cgaWYgdGhpcyBpcyBpbnN1ZmZpY2llbnQgb3IgdGhlIHBhdGNoIGlzCi0gd3Jvbmcgb3IgaWYgdGhlcmUgaXMgc29tZXRoaW5nIGVsc2UgSSBjYW4gZG8gdG8gZml4IHRoaXMgcHJvYmxlbS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvZG9tMmR0bSBET00yRFRNLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5PbiBjb2RlIHJldmlldyBvZiBwcmV2aW91cyBjaGVja2luIGZyb20gR2FyeSBQLiwgd2UgZGV0ZXJtaW5lZCB0aGVyZQotIHdhcyBhIHByb2JsZW0gd2l0aCB0aGUgcG9pbnQgYXQgd2hpY2ggdHlwZSB3YXMgZGVjbGFyZWQgYQotIERUTS5OQU1FU1BBQ0VfTk9ERS4gU28gdGhhdCBwYXJ0IHdhcyBtb3ZlZCBiYWNrIHVwIChhY3R1YWxsCi0gYSBiaXQgaGlnaGVyIHRoYW4gd2hlcmUgaXQgd2FzIGJlZm9yZSksCi0gYW5kIHRoZSBjYWxsIHRvIGRlY2xhcmVOYW1lc3BhY2VJbkNvbnRleHQgd2FzIG1vdmVkIGEgYml0Ci0gZnVydGhlciBkb3duLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qb2huZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIFhDb25uZWN0aW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Qcm9qZWN0IFVwZGF0ZQotIFN1Ym1pdHRlZCBieTogSm9obiBHZW50aWxpbiBtYWlsdG86Ly9qb2huZ0BhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmpvaG5nQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgU1FMRG9jdW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlByb2plY3QgVXBkYXRlCi0gU3VibWl0dGVkIGJ5OiBKb2huIGdlbnRpbGluIG1haWx0bzovL2pvaG5nQGFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+am9obmdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBTUUxEb2N1bWVudC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4dXAgZnJvbSBwcmV2aW91cyBjaGVjay1pbiwgZGVmaW5lZCBuZXcKLSBmdW5jdGlvbnMuCi0gU3VibWl0dGVkIGJ5OiBKb2huIEdlbnRpbGluIG1haWx0bzovL2pvaG5nQGFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+am9obmdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBTUUxEb2N1bWVudC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UHJvamVjdCBVcGRhdGU8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+am9obmdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBTUUxEb2N1bWVudC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+cmVkdWNlZCBBdHRyaWJ1dGUncyBmb3IgdGVzdGluZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9zYXgyZHRtIFNBWDJEVE0uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1pbm9yIGhhY2sgdG8gY2F0Y2ggYW4gYXR0cmlidXRlIHZhbHVlIGJlaW5nIG51bGwuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtTnVtYmVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIENvdW50ZXIuamF2YQotIENvdW50ZXJzVGFibGUuamF2YSBLZXlSZWZJdGVyYXRvci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZi9kb20yZHRtIERPTTJEVE0uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggTm9kZVNldERUTS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIExvY1BhdGhJdGVyYXRvci5qYXZhCi0gVW5pb25QYXRoSXRlcmF0b3IuamF2YSBXYWxraW5nSXRlcmF0b3JTb3J0ZWQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGgvb2JqZWN0cyBYTm9kZVNldC5qYXZhCi0gWFJUcmVlRnJhZy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkIG5ldyBwYXJhbWV0ZXIgdG8gTm9kZVNldERUTSBjb25zdHJ1Y3Rvci4gV2UgbmVlZCB0byBoYXZlIGEgRFRNTWFuYWdlciBvbiAKLWhhbmQuIENoYW5nZSBjb2RlIHRvIHVzZSB0aGUgbmV3IGNvbnN0cnVjdG9ycy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL2R0bS9yZWYvZG9tMmR0bSBET00yRFRNLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5PT3BzISBCYWNrIG91dCB0aGlzIGxhc3QgY2hhbmdlLiBPbGQgY29kZSBvbiBteSBtYWNoaW5lISEhPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmpvaG5nQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgU1FMRG9jdW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeGVkIGEgZmV3IGJ1Z3MsIGFsbW9zdCB0aGVyZQotIFN1Ym1pdHRlZCBieTogSm9obiBHZW50aWxpbiBtYWlsdG86Ly9qb2huZ0BhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIENvcm91dGluZU1hbmFnZXIuamF2YQotIENvcm91dGluZVNBWFBhcnNlci5qYXZhCi0gQ29yb3V0aW5lU0FYUGFyc2VyX1hlcmNlcy5qYXZhPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIEluY3JlbWVudGFsU0FYU291cmNlLmphdmEKLSBJbmNyZW1lbnRhbFNBWFNvdXJjZV9GaWx0ZXIuamF2YQotIEluY3JlbWVudGFsU0FYU291cmNlX1hlcmNlcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+U3RhcnRpbmcgdG8gcGhhc2Ugb3V0IENvcm91dGluZSpQYXJzZXIqIGluIGZhdm9yIG9mIEluY3JlbWVudGFsU0FYU291cmNlKi4KLSBUaGUgbGF0dGVyIHNpbXBsaWZpZXMgdGhlIGNvZGUsIGFuZCBzaG91bGQgaGVscCB1cyBhdm9pZCBzb21lIG9mIHRoZQotIGNvbmZ1c2lvbiB0aGF0IGNhbiBhcmlzZSBpbiB1c2luZyB0aGUgb2xkZXIgdG9vbHMuCi0KLSBNb3N0IGltcG9ydGFudGx5LCBpdCBncmVhdGx5IHNpbXBsaWZpZXMgdGhlIGNhbGxpbmcgc2VxdWVuY2VzLCBieSBkaXNjYXJkaW5nCi0gdGhlICJ3aGljaCBmaWxlIGRvIHlvdSB3YW50IHRvIHBhcnNlIiBhbmQgImRvIHlvdSB3YW50IHRvIHBhcnNlIGFueSBtb3JlCi0gZmlsZXMiIHRyYW5zYWN0aW9ucy4gVGhlc2Ugbm93IG9wZXJhdGUgX29ubHlfIGFzIGZpbHRlcnMsIGFuZCBvbmx5IGFzIHNpbmdsZQotIC11c2UgKHRob3VnaCBpbiBmYWN0IHRoZSBYZXJjZXMtc3BlY2lmaWMgdmVyc2lvbiBpcyByZXVzYWJsZSwgYW5kIHdlIG1heQotIHJlaW50cm9kdWNlIHRoYXQgZmVhdHVyZSBpbiB0aGUgZ2VuZXJpYyBmaWx0ZXJpbmcgdmVyc2lvbiBhdCBhIGxhdGVyIGRhdGUpLgotCi0gTm90ZSB0b28gdGhhdCB3ZSBoYXZlIHN3ZXB0IHRoZSBDb3JvdXRpbmVNYW5hZ2VyIGNvbXBsZXRlbHkKLSB1bmRlciB0aGUgY292ZXJzIG9mIHRoZSBmaWx0ZXIncyBBUEkuIFRoZXJlJ3Mgbm8gcGFydGljdWxhciByZWFzb24gdG8gZXhwb3NlCi0gdGhhdCBpbXBsZW1lbnRhdGlvbiBkZXRhbCB0byB0aGUgb3V0c2lkZSB3b3JsZC4KLQotIFN0aWxsIHRvIGJlIGRvbmU6IFJld29yayB0aGUgcmVzdCBvZiBYYWxhbiB0byB1c2UgdGhlIG5ldyBjb2RlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBDb3JvdXRpbmVQYXJzZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlN0YXJ0aW5nIHRvIHBoYXNlIG91dCBDb3JvdXRpbmUqUGFyc2VyKiBpbiBmYXZvciBvZiBJbmNyZW1lbnRhbFNBWFNvdXJjZSouCi0gU2VlIGNvbW1lbnQgaW4gcHJldmlvdXMgY2hlY2staW47IEkganVzdCBtaXNzZWQgdGhpcyBvbmUuLi4uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC9kdG0vcmVmIERUTVN0cmluZ1Bvb2wuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmRvYy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9yZXMgWFNMVEluZm8ucHJvcGVydGllczxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPjIuMi5ENzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvciBYU0xQcm9jZXNzb3JWZXJzaW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj4yLjIuRDc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE4LzIwMDE8YnIvPjxyZWY+UmVtb3ZlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvZHRtL3JlZiBEVE1CdWlsZGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5PYnNvbGV0ZTxici8+PGJyLz48L2xpPjwvdWw+PG5vdGU+VGhpcyByZWxlYXNlIGluY2x1ZGVzIG5vIHVwZGF0ZXMgb2YgdGhlIGNvbXBhdGliaWxpdHkgc291cmNlIGNvZGUgKG5vdyBkZXByZWNhdGVkKS48L25vdGU+Ci08L3MzPgotPHMzIHRpdGxlPSJDaGFuZ2VzIGZvciAmeHNsdDRqOyAyLjIuRDYiPgotICAgICA8cD48ZW0+SW1wb3J0YW50OiBYZXJjZXMgaGFzIGFkZGVkIGEgbnVtYmVyIG9mIERPTSBsZXZlbC0zIG1ldGhvZHMgdG8gaXRzIERPTSBpbnRlcmZhY2VzLiBUaGUgRE9NIGxldmVsLTMgcHJvcG9zYWwKLWlzIGN1cnJlbnRseSBhIHdvcmtpbmcgZHJhZnQgKGl0IGlzIG5vdCB5ZXQgYSBXM0MgcmVjb21tZW5kYXRpb24pLCBhbmQgWGFsYW4gZG9lcyBub3Qgc3VwcG9ydCB0aGVzZSBuZXcgbWV0aG9kcy4gCi1UbyBydW4gWGFsYW4gaW4gdGhlIEpESyAxLjEuOCBwbGF0Zm9ybSwgeW91IG11c3QgcHV0IHhhbGFuLmphciAod2l0aCBpdHMgRE9NIGxldmVsLTIgaW50ZXJmYWNlcykgaW4gZnJvbnQgb2YgCi14ZXJjZXMuamFyIG9uIHRoZSBzeXN0ZW0gY2xhc3MgcGF0aC4gSWYgeW91IHdhbnQgdG8gcmVidWlsZCBYYWxhbiAob24gSkRLIDEuMS44IG9yIGhpZ2hlciksIHlvdSBtdXN0IHB1dCBYYWxhbiAKLWluIGZyb250IG9mIHhlcmNlcy5qYXIgb24gdGhlIHN5c3RlbSBjbGFzcyBwYXRoLjwvZW0+PC9wPgotCi0gICAgIDxwPlRoaXMgYmV0YSByZWxlYXNlIGluY2x1ZGVzIHRoZSBmb2xsb3dpbmcgbm9uLVhTTFRDIGNvZGUgY2hhbmdlczo8L3A+ICAgICAKLSAgICAgPHVsPgotICAgICAgIDxsaT5Db3N0aW4gTWFub2xhY2hlIGhhcyBzbGlnaHRseSBtb2RpZmllZCB0aGUgQ29Sb3V0aW5lIHN0dWZmIHNvIHRoYXQgYSB5b3UgY2FuIGNvbXBpbGUgYW5kIHJ1biBldmVyeXRoaW5nIGJ1dCB0aGUgQ29Sb3V0aW5lWGVyY2VzUGFyc2VyIHdpdGhvdXQgaGF2aW5nIFhlcmNlcyBvbiB0aGUgY2xhc3NwYXRoLjxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5Kb3NlcGggS2Vzc2VsbWFuIGFkZGVkIGNodW5rZWQgaW50IGFycmF5IHN0dWZmIHRvIGFkZHJlc3Mgb3VyIHNjYWxpbmcgcHJvYmxlbXMgdGhhdCBNdWt1bmQgJmFtcDsgY28uIHVuY292ZXJlZC4gIFRoaXMgd2FzIGEgZmFpcmx5IG1lY2hhbmljYWwsIGJ1dCBzdGlsbCBzdWJzdGFudGlhbCwgY2hhbmdlLiAgTm8gYnVncyBoYXZlIHlldCBiZWVuIGRpc2NvdmVyZWQgdGhhdCByZWxhdGUgdG8gdGhpcy4gIFRoaXMgaXMgcHJvYmFibHkgdGhlIG1vc3QgY29udHJvdmVyc2lhbCBjaGFuZ2UuPGJyLz48YnIvPjwvbGk+ICAgICAgIAotICAgICAgIDxsaT5UaGUgUHJvY2VzcyBjbGFzcyBub3cgb3V0cHV0cyBpbmNyZW1lbnRhbGx5IGlmIHRoZSBvdXRwdXQgaXMgc3RhbmRhcmQgb3V0LiAgVGhpcyBpcyBtb3N0bHkgZm9yIHRlc3RpbmcgcHVycG9zZXMsIGJ1dCBpdCBtYWtlcyBnZW5lcmFsIHNlbnNlLjxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5CdWcgd2FzIGZpeGVkIHdpdGggc2V0dGluZyB0aGUgaW5jcmVtZW50YWwgZmxhZyBpbiBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLiAgQ2xlYXJseSB0aGUgY2hhbmdlIHdhcyBtYWRlIGJ1dCBuZXZlciB0ZXN0ZWQuICBTaW1wbHkgYSBtaXNzaW5nICdlbHNlJy48YnIvPjxici8+PC9saT4KLSAgICAgICA8bGk+Rml4IGZvciBCdWd6aWxsYSBCdWcgMjI3NSwgWGFsYW4gZGlkIG5vdCBmaXJlIHRoZSByaWdodCB0ZW1wbGF0ZXMuICBUaGlzIHdhcyBzdWJzdGFudGlhbCBhbmQgc29tZXdoYXQgcmlza3kuICBYYWxhbiBoYWQgc2V2ZXJhbCBwcm9ibGVtcyByZWxhdGVkIHRvIHRoZSBsYXN0KCkgZnVuY3Rpb24uICBGaXhlcyBjb3ZlciBmb3VyIGF4ZXMgZmlsZXMuPGJyLz48YnIvPjwvbGk+ICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgPGxpPkNoYW5nZSBQcmludFRyYWNlTGlzdGVuZXIgdG8gb3V0cHV0IHRoZSBmaWxlLCBhcyB3ZWxsIGFzIHRoZSBsaW5lIG51bWJlcnMuICBUaGlzIGlzIHJlYWxseSBhIGZlYXR1cmUgY2hhbmdlLCBidXQgc2ltcGxlLCBhbmQgYWlkcyBkaWFnbm9zaW5nIHByb2JsZW1zIHdpdGggbXVsdGktcGFydCBzdHlsZXNoZWV0cy48YnIvPjxici8+PC9saT4gICAgICAgCi0gICAgICAgPGxpPlhQYXRoIGZpeDogdGhlIFhQYXRoIEFQSSB3YXNuJ3Qgd29ya2luZyBjb3JyZWN0bHkgZHVlIHRvIGEgcHJvYmxlbSB3aXRoIHdpdGggTm9kZVNldC9Ob2RlSXRlcmF0b3IgYWRhcHRlcnMuICBUaGlzIGZpeCBlbmRlZCB1cCBpbnRlcmFjdGluZyBxdWl0ZSBhIGJpdCB3aXRoIHRoZSAjMjI3NSBmaXguPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgPGxpPkZpeCBmb3IgdGhlIE5vcm0gV2Fsc2ggYnVnIHBvc3RlZCAwNi8yMC8yMDAxOiBpdGVyYXRvcnMgd2VyZW4ndCBhbHdheXMgYmVpbmcgY2xvbmVkIGNvcnJlY3RseSBmcm9tIHRoZSB2YXJpYWJsZSB2YWx1ZSBzdGFjay4gIFRoaXMgZml4IGlzIG5vdCB3aXRob3V0IHNvbWUgcmlzaywgdGhvdWdoIHdlIGhhdmVuJ3Qgc2VlbiBhbnkgcHJvYmxlbXMgc2luY2UgU2NvdHQgQm9hZyBtYWRlIGl0Ljxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5EYXZpZCBCZXJ0b25pIGFkZGVkIG1pc3NpbmcgaHRtbCBlbGVtZW50IHByb3BlcnRpZXMgdG8gU2VyaWFsaXplclRvSFRNTC5qYXZhLjxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5TaGFuY2UgQ3VyY3VydSBtb2RpZmllZCBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLnNldEF0dHJpYnV0ZSgpIHRvIGFjY2VwdCBhIFN0cmluZyAoInRydWUiIG9yICJmYWxzZSIpIGFzIHdlbGwgYXMgYSBCb29sZWFuIG9iamVjdCB0byBzZXQgdGhlIHZhbHVlIG9mIGEgQm9vbGVhbiBhdHRyaWJ1dGUuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgPGxpPlRyYW5zZm9ybWVySGFuZGxlckltcGwgd2FzIHRocmVhZGluZyB3aGVuIGluY3JlbWVudGFsaXR5IGlzIHR1cm5lZCBvZmYuIFNjb3R0IEJvYWcgaGFzIGZpeGVkIHRoaXMgYnVnLjwvbGk+ICAgICAgIAotICAgICA8L3VsPgotPC9zMz4gICAgIAotICAgPGFuY2hvciBuYW1lPSJkdG0iLz4KLSAgICAgPHMzIHRpdGxlPSJDaGFuZ2VzIGZvciAmeHNsdDRqOyAyLjIuRDIiPgotICAgICA8cD5UaGlzIHJlbGVhc2UgaW5jbHVkZXMgdGhlIGZvbGxvd2luZyBjaGFuZ2VzOjwvcD4KLSAgICAgPHVsPgotICAgICAgIDxsaT5EZXByZWNhdGlvbiBvZiB0aGUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0iY29tcGF0Ij5YYWxhbi1KYXZhIDEgY29tcGF0aWJsaXR5IEFQSTwvbGluaz48L2xpPgotICAgICAgIDxsaT5UaGUgRFRNPC9saT4KLSAgICAgICA8bGk+T3RoZXIgb3B0aW1pemF0aW9uIHdvcms8L2xpPgotICAgICA8L3VsPgotICAgICA8cD5UaGUgcHJpbWFyeSBmb2N1cyBvZiB0aGUgMi4yIERldmVsb3BlciByZWxlYXNlcyBpcyBpbmNvcnBvcmF0aW9uIG9mIGFsbCBvdXIgd29yayBvdmVyIHRoZSBwYXN0IHNldmVyYWwgbW9udGhzIG9uIHRoZSBEb2N1bWVudCBUYWJsZQotICAgICAgTW9kZWwgKDxsaW5rIGlkcmVmPSJkdG0iPkRUTTwvbGluaz4pLjwvcD4KLQotPHA+QXMgYSByZXN1bHQgb2YgdGhlIGNoYW5nZXMgaW4gKmludGVybmFsKiBhcGksIHlvdSBtYXkgZW5jb3VudGVyIHByb2JsZW1zIHdpdGggZXh0ZW5zaW9ucy4gV2UgaGF2ZSBkb25lIHNvbWUgYnVnIGZpeGluZyBpbiBzdXBwb3J0Ci1mb3IgZXh0ZW5zaW9ucyBzaW5jZSAyLjIuRDEuICBKb2huIEdlbnRpbGluIGlzIHdvcmtpbmcgb24gZml4aW5nIHRoZSBTUUwgbGlicmFyeSBleHRlbnNpb24sd2hpY2ggY3VycmVudGx5IGlzIGJyb2tlbi4gUGxlYXNlIHJlcG9ydCAKLWFueSBwcm9ibGVtcyB5b3UgZmluZCAoc2VlIDxsaW5rIGFuY2hvcj0iYnVncyI+YnVnczwvbGluaz4pLjwvcD4KLQotPHA+VGhlIERUTSBhbmQgcmVsYXRlZCB3b3JrIHByb3ZpZGVzIGZhc3RlciBwZXJmb3JtYW5jZSBhbmQgbGVzcyBhY2N1bXVsYXRpb24gb2YgZ2FyYmFnZS4uLiB0aG91Z2ggaXQgaXMgYW4KLW9uZ29pbmcgYmF0dGxlLiAgQnJpZWYgc3VtbWFyeTo8L3A+Ci08dWw+Ci08bGk+VGhlIERUTSBpZGVudGlmaWVzIG5vZGVzIHdpdGggMzItYml0IGludGVnZXIgaGFuZGxlcy4KLVRoZSBEVE0gaGFzIG1hbnkgZmVhdHVyZXMsIGluY2x1ZGluZyBkaXJlY3QgY2hhcmFjdGVyIGRpc3BhdGNoIHRvIFNBWDIsCi1uYXRpdmUgRFRNIGl0ZXJhdG9ycyBhbmQgInRyYXZlcnNlcnMiLCBtdWx0aXBsZSBkb2N1bWVudCBtYW5hZ2VtZW50LCBldGMuPGJyLz48YnIvPjwvbGk+Ci08bGk+Sm9lIEtlc3NlbG1hbidzIENvUm91dGluZSBwYXJzZXJzLCB3aGljaCBhcmUgaW4gYSB0aHJlYWRlZCBTQVggZmxhdm9yCi1hbmQgaW4gYSBYZXJjZXMgcGFyc2VNb3JlKCkgZmxhdm9yIChubyB0aHJlYWRzKS4gIFRoZXNlIGRvIGF3YXkgd2l0aCB0aGUKLSJyYWNlIiBjb25kaXRpb25zIHRoYXQgb2NjdXJlZCBpbiB0aGUgb3JpZ2luYWwgY29kZSwgYW5kIHNob3VsZCBtYWtlIFhhbGFuCi1tdWNoIG1vcmUgcm9idXN0Ljxici8+PGJyLz48L2xpPgotPGxpPipNdWNoKiBtb3JlIHJvYnVzdCBYUGF0aCBpdHRlcmF0aW9uLiAgVGhlICJ3YWl0aW5nIiBpdGVyYXRvcnMgb2Ygb2xkIGFyZQotbm8gbW9yZSwgYW5kIGdvb2QgcmlkZGFuY2UuICBUaGVyZSBpcyBzdGlsIGxvdHMgbW9yZSB3ZSB3YW50IHRvIGRvIHdpdGgKLXRoaXMgbWVjaGFuaXNtLiAgKFRoZXJlIGlzIHNvbWV0aGluZyBoZXJlIGNhbGxlZCBNYXRjaEl0ZXJhdG9ycywgYnV0IGl0J3MKLW5vdCBiZWluZyB1c2VkIHlldCBmb3IgdmFyaW91cyByZWFzb25zLiAgV2Ugd2lsbCBiZSB0YWtpbmcgYWR2YW50YWdlIG9mCi10aGVzZSBkb3duIHRoZSBsaW5lLik8YnIvPjxici8+PC9saT4KLTxsaT5BIGZhaXIgYW1vdW50IG9mIFhPYmplY3QgY3JlYXRpb24gcmVkdWN0aW9uLiAgWW91IGNhbiBub3cgZ2V0IGJvb2xlYW4sCi1udW1iZXIsIG5vZGVzZXQsIGFuZCBzdHJpbmcgdmFsdWVzIGRpcmVjdGx5IGZyb20gYW4gRXhwcmVzc2lvbiwgaW5zdGVhZCBvZgotZ29pbmcgdGhyb3VnaCBhbiBYT2JqZWN0Ljxici8+PGJyLz48L2xpPgotPGxpPlhNTFN0cmluZywgd2hpY2ggYWxsb3dzIHVzIHRvIHdvcmsgd2l0aCBzdHJpbmcgb2JqZWN0cyB0aGF0IGRvbid0IHdyYXAKLUphdmEncyBTdHJpbmcgb2JqZWN0LiBUaGVzZSBvYmplY3RzIGdldCB0aGVpciBjaGFyYWN0ZXIgZGF0YSBmcm9tIGFuIGFycmF5IG9yCi1GYXN0IFN0cmluZyBCdWZmZXIuPGJyLz48YnIvPjwvbGk+Ci08bGk+U2VyaWFsaXplcnMgbm93IG9ubHkgZG8gaW50ZXJuYWwgYnVmZmVyaW5nIGlmIHRoZXkga25vdyB0aGV5IGFyZSB3cml0aW5nCi10byBhIEZpbGVTdHJlYW0uPGJyLz48YnIvPjwvbGk+Ci08bGk+VGhlIHZhcmlhYmxlIHN0YWNrIG1lY2hhbmlzbSBoYXMgYmVlbiByZWRpc2lnbmVkLCBzbyB0aGF0IGl0IGlzIG5vCi1sb25nZXIgc28gaW50ZXJwcmV0aXZlLCBhbmQgd2UgYmVsaWV2ZSBpdCBpcyBtdWNoIG1vcmUgcm9idXN0Ljxici8+PGJyLz48L2xpPgotPGxpPiBTb21lIHNtYWxsIGFtb3VudCBvZiBzdHlsZXNoZWV0IHJld3JpdGluZyAoYnV0IG5vdCB5ZXQgcmVkdW5kZW50Ci1leHByZXNzaW9uIGVsaW1pbmF0aW9uKSwgaW4gcGFydGljdWxhciB0byByZWR1Y2UgZnVsbCBSVEYgY3JlYXRpb24gYW5kCi1pbnRlcnByZXRhdGlvbi48L2xpPgotPC91bD4KLTxwPiZ4c2x0NGo7IGltcGxlbWVudHMgdHdvIERUTSBwZXJmb3JtYW5jZSBmZWF0dXJlcyB0aGF0IHlvdSBjYW4gY29udHJvbCB3aXRoIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkKLTxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuaHRtbCNzZXRBdHRyaWJ1dGUoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLk9iamVjdCkiPnNldEF0dHJpYnV0ZSgpPC9qdW1wPgotbWV0aG9kLiBTZWUgPGxpbmsgaWRyZWY9ImR0bSIgYW5jaG9yPSJzZXR0aW5ncyI+RFRNIHBlcmZvcm1hbmNlIHNldHRpbmdzPC9saW5rPjwvcD4KLSAgICAgPC9zMz4KLSAgICAgPHMzIHRpdGxlPSJDaGFuZ2VzIGZvciAmeHNsdDRqOyAyLjEuMCI+Ci0gICAgIDxwPlRoaXMgcmVsZWFzZSBpbmNsdWRlcyBhIG51bWJlciBvZiBidWcgZml4ZXMgdG8gJnhzbHQ0ajsgYW5kIFRyQVguIAotICAgICBXZSBoYXZlIGFsc28gZW5oYW5jZWQgdGhlIEFwcGx5WFNMVCBzZXJ2bGV0LiBJdCBjYW4gbm93IGJlIHNldCB1cCB0byB1c2UgYSBjb21waWxlZCBUZW1wbGF0ZXMgb2JqZWN0IHRvIHJlc3BvbmQgdG8gbXVsdGlwbGUKLSAgICAgY2xpZW50IHRyYW5zZm9ybWF0aW9uIHJlcXVlc3RzIGludm9sdmluZyB0aGUgc2FtZSBzdHlsZXNoZWV0LjwvcD4KLTwhLS1UaGlzIFhNTCBmcmFnbWVudCBjb250YWlucyBhIGxpc3Qgb2Ygc291cmNlIGNvZGUgdXBkYXRlcyB0byBwbGFjZSBpbiBhbiA8czM+IHNlY3Rpb24gb2YgcmVhZG1lLnhtbC0tPjxwPkNvcmUgc291cmNlIGNvZGUgdXBkYXRlczo8L3A+PHVsPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jb3N0aW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzE2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFN0eWxlc2hlZXRIYW5kbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIEV4cHJlc3Npb24uamF2YSBYUGF0aC5qYXZhCi0gWFBhdGhDb250ZXh0LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyIENvbXBpbGVyLmphdmEKLSBYUGF0aFBhcnNlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVuYW1lZCAiYXNzZXJ0KCkiIHRvICJhc3NlcnRpb24oKSIuCi0KLSBBc3NlcnQgY2FuIGJlIGEga2V5d29yZCwgYW5kIGJyYWtlIHRoZSBjb21waWxhdGlvbi48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzE5LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgS2V5V2Fsa2VyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5UaHJvdyBhbiBlcnJvciBtZXNzYWdlIGlmIHRoZSBrZXkgbmFtZSBpbiBhIGtleSBmdW5jdGlvbiB3YXMgbm90IGRlZmluZWQ8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIEZhc3RTdHJpbmdCdWZmZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlJld29ya2VkICJjaHVuayBncm93dGgiIGFsZ29yaXRobSBhZ2Fpbi4gR3Jvd2luZyBtb2RlIG5vdAotIHlldCBhZGVxdWF0ZWx5IHRlc3RlZCwgYnV0IGZpeGVkLXNpemUgbW9kZSAod2hpY2ggaXMgd2hhdCBYYWxhbgotIGlzIGN1cnJlbnRseSB1c2luZykgaXMgc2ltcGxlciBjb2RlIGFuZCBzaG93cyBpbXByb3ZlZCBwZXJmb3JtYW5jZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y3VyY3VydUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMjAvMjAwMTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IEVudmlyb25tZW50Q2hlY2suamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlV0aWxpdHkgY2xhc3MgdG8gY2hlY2sgeW91ciBKVk0gZW52aXJvbm1lbnQgZm9yIGNvbW1vbiBwcm9ibGVtczxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jdXJjdXJ1QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8yMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgRW52aXJvbm1lbnRDaGVjay5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgbW9yZSAuamFyIHNpemVzIHRvIGphclZlcnNpb25zIGxpc3Rpbmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+amtlc3NlbG1AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzIyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIEZhc3RTdHJpbmdCdWZmZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPldlJ3ZlIHJld29ya2VkIHRoZSBhbGdvcml0aG0gYWdhaW4uIFRoZSBmaXhlZC1jaHVuay1zaXplIG1vZGUgKGluaXRpYWwKLSBhbmQgbWF4LiBjaHVuayBzaXplcyBlcXVhbCkgcnVucyBlc3NlbnRpYWxseSB1bmNoYW5nZWQsIHRob3VnaCB3aXRoIGEKLSBmZXcgY3ljbGVzIGxlc3Mgb3ZlcmhlYWQuIFRoZSB2YXJpYWJsZS1jaHVuay1zaXplIG1vZGUgbm93IHVzZXMgYQotIHJlY3Vyc2l2ZS1lbmNhcHN1bGF0aW9uIHNjaGVtZSwgd2hlcmUgdGhlIGZpcnN0IGNodW5rIG1heSBpdHNlbGYgYmUgYQotIEZhc3RTdHJpbmdCdWZmZXIgd2hvc2UgdG90YWwgbGVuZ3RoIGVxdWFscyBvbmUgY2h1bms7IGV2ZXJ5IHNvIG9mdGVuCi0gd2UgcHVzaCB0aGUgZXhpc3RpbmcgZGF0YSBkb3duIG9uZSBsZXZlbCBhbmQgcmVzdGFydCB3aXRoIGEgbGFyZ2VyCi0gY2h1bmsgc2l6ZS4gVGhlIG5ldyBzY2hlbWUgaGFzIGJlZW4gc3RyZXNzLXRlc3RlZCBhbmQgaXMgYXBwYXJlbnRseQotIHdvcmtpbmcuIEF0IHRoaXMgd3JpdGluZywgaG93ZXZlciwgWGFsYW4gdXNlcyBvbmx5IHRoZSBmaXhlZC1zaXplCi0gbW9kZSAoaW5pdGlhbCBzaXplIGVxdWFscyBtYXggc2l6ZSksIGFuZCBubyBlZmZvcnQgaGFzIGJlZW4gbWFkZSB0bwotIGZpbmQgdGhlIG9wdGltaWFsIHZhbHVlcyBmb3IgdGhlIHR1bmluZyBwYXJhbWV0ZXJzLiBJdCBkb2VzIGFwcGVhcgotIGxpa2VseSB0aGF0IHRoZSBiZXN0IHZhbHVlcyB3aWxsIHZhcnkgd2l0aCB1c2FnZSBwYXR0ZXJucywgYnV0IHdlIGhvcGUKLSB0byBmaW5kIGEgZ29vZCBjb21wcm9taXNlLgotCi0gSSdsbCBwcm9iYWJseSBiZSBwdXR0aW5nIHRoaXMgYXNpZGUgZm9yIGEgd2hpbGUgdG8gd29yayBvbiBvdGhlciB0aGluZ3MuCi0gSWYgc29tZW9uZSB3YW50cyB0byBleHBlcmltZW50IHdpdGggdmFyeWluZyB0aGUgYmxvY2sgc2l6ZXMgYW5kCi0gaG93IGZyZXF1ZW50bHkgdGhleSBncm93LCBhbmQgc3VnZ2VzdCBnb29kIHBlcmZvcm1hbmNlL21lbW9yeQotIHRyYWRlb2ZmIHBvaW50cywgZ28gZm9yIGl0ITxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMjIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgRmFzdFN0cmluZ0J1ZmZlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+TWlub3IgdHdlYWsgdG8gdGhlIGphdmFkb2MuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmprZXNzZWxtQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8yMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBGYXN0U3RyaW5nQnVmZmVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5yZXNldCgpIHZlcnN1cyBzZXRMZW5ndGgoMCkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8yNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtRm9yRWFjaC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBidWcjIDExMTYsIGdldE1hdGNoZWRUZW1wbGF0ZSB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uLgotIERvbid0IHB1c2ggdGVtcGxhdGUgdW5sZXNzIGl0IGlzIGEgeHNsOnRlbXBsYXRlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMjYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgT3V0cHV0UHJvcGVydGllcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UGF0Y2hlcyBzdWJtaXR0ZWQgYnkgUGF0cmljayBNb29yZSAmbHQ7cGF0cmlja21AcmlvcG9ydC5jb20mZ3Q7Ci0gb24gMDMvMTUvMjAwMSAwMToyNSBQTToKLQotIFRoaXMgcHJvcG9zZWQgY2hhbmdlIGRvZXMgYSBudW1iZXIgb2YgdGhpbmdzOgotCi0gMS4gUHJvYmxlbTogSFRNTCBvdXRwdXQgbWV0aG9kIGRvZXMgbm90IHVzZXMgWE1MIG91dHB1dCBwcm9wZXJ0aWVzIGFzCi0gZGVmYXVsdC4KLQotIEluIGJvdGggb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvb3V0cHV0X2h0bWwucHJvcGVydGllcyBhbmQgaW4gdGhlIGphdmEKLSBkb2MgZm9yCi0gb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMvT3V0cHV0UHJvcGVydGllcyNnZXREZWZhdWx0TWV0aG9kUHJvcGVydGllcyhTdHJpbgotIGcpIEl0IHNwZWNpZmljYWxseSBzdGF0ZXMgdGhhdCBhbGwgT3V0cHV0UHJvcGVydGllcyB1c2UgdGhlCi0gb3V0cHV0X3htbC5wcm9wZXJ0aWVzIGFzIGEgYmFzZS4gSW4gdGhlIGNvZGUgdGhpcyBpcyBub3QgdHJ1ZSBmb3IgaHRtbC4gVGhpcwotIGlzIG5vdyBjaGFuZ2VkIHRvIG1hdGNoIHRoZSBjb21tZW50cwotCi0gMi4gUHJvYmxlbTogdW5jbGVhciBJT0V4Y2VwdGlvbi4KLQotIElmIHRoZXJlIHdhcyBhIHByb2JsZW0gbG9hZGluZyB0aGUgWE1MIHByb3BlcnRpZXMgZmlsZS4gVGhlIHdyYXBwZWQKLSBleGNlcHRpb24gbm93IHdpbGwgc2F5IHdoaWNoIGZpbGUgd2FzIHRyeWluZyB0byBiZSBsb2FkZWQuIElmIHRoZSBmaWxlIGRpZAotIG5vdCBleGlzdCBJIHdhcyBnZXR0aW5nIGEgdmVyeSBzdHJhbmdlICJTdHJlYW0gY2xvc2VkIiBJT0V4Y2VwdGlvbiBtZXNzYWdlLgotCi0gMy4gUHJvYmxlbTogdGhlIHN0cmVhbXMgd2VyZSBub3QgY2xvc2VkIGFmdGVyIHJlYWRpbmcgdGhlIHByb3BlcnR5IGZpbGUuCi0KLSBGaXhlZC4KLQotIDQuIFByb2JsZW06IHRoZSBkb3VibGUtY2hlY2sgbG9ja2luZyBtZWNoYW5pc20gZG9lcyBub3Qgd29yayBpbiBKYXZhIChzZWUKLSBidWcgIzkxOSkKLQotICZsdDtodHRwOi8vd3d3LmphdmF3b3JsZC5jb20vamF2YXdvcmxkL2p3LTAyLTIwMDEvanctMDIwOS10b29sYm94Lmh0bWwmZ3Q7Ci0KLSA1LiBRVUVTVElPTjogbm93IGlmIHRoZXJlIGlzIGEgZGVmYXVsdCBwcm9wZXJ0aWVzIChpLmUuCi0gb3V0cHV0X3htbC5wcm9wZXJ0aWVzIGhhcyBiZWVuIGxvYWRlZCkgYnV0IHRoZSBleHBlY3RlZCBwcm9wZXJ0aWVzIGZpbGUgZG9lcwotIG5vdCBleGlzdCBhIGVycm9yIG1lc3NhZ2Ugd2lsbCBiZSBwcmludGVkIHRvIFN5c3RlbS5lcnIgYW5kIHRoZSBwcm9jZXNzaW5nCi0gd2lsbCBjb250aW51aW5nIHVzaW5nIGp1c3QgdGhlIGRlZmF1bHQgcHJvcGVydGllcyAob3V0cHV0X3htbC5wcm9wZXJ0aWVzKSBJCi0gZmVsdCB0aGF0IHRoaXMgaXMgdGhlIGJlc3QgYmVoYXZpb3IuCi0KLSAoY29tbWVudCBieSBzYm9hZzogSSB0aGluayBpdCdzIGJldHRlciB0bwotIHRocm93IGEgcnVudGltZSBleGNlcHRpb24gaW4gdGhpcyBjYXNlLgotIGJ1dCB3ZSBjYW4gZGlzY3VzcyB0aGlzIG92ZXIgdGltZS4gRm9yIG5vdwotIHRoZSBwYXRjaCB3YXMgbW9kaWZpZWQgdG8gZG8gdGhlIHJ1bnRpbWUgZXhjZXB0aW9uKS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFhTTFRTY2hlbWEuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc3RyZWUgU291cmNlVHJlZUhhbmRsZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzIEVsZW1Gb3JFYWNoLmphdmEKLSBFbGVtTGl0ZXJhbFJlc3VsdC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBRdWV1ZWRTQVhFdmVudC5qYXZhCi0gUmVzdWx0VHJlZUhhbmRsZXIuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIEJvb2xTdGFjay5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aCBYUGF0aENvbnRleHQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlRoaXMgY2hlY2staW4gY29udGFpbnMgYSBjb3VwbGUgdGhpbmdzIHRoYXQgb3ZlcmxhcHBlZCBvbiBteQotIHN5c3RlbSwgc28gSSdtIGNoZWNraW5nIHRoZW0gaW4gdG9nZXRoZXIuCi0gMSkgVW5maW5pc2hlZCAoaW4gcHJvZ3Jlc3MpIGltcGxlbWVudGF0aW9uIG9mIFRyYW5zZm9ybVNuYXBzaG90IG1lY2hhbmlzbSwKLSB3aGljaCB3aWxsIGhvcGVmdWxseSBhbGxvdyBhIHJlc3VsdCBDb250ZW50SGFuZGxlciB0byB0YWtlIGEgc25hcHNob3QKLSBhdCBhIGdpdmVuIHBvaW50LCBhbmQgdGhlIHJlc3RhcnQgZXhlY3V0aW9uIGZyb20gdGhhdCBwb2ludCBhdCBzb21lCi0gbGF0ZXIgdGltZS4gRm9yIHRvb2xpbmcgc3VwcG9ydC4KLSAyKSBDaGVjayB0byBtYWtlIHN1cmUgU291cmNlVHJlZUhhbmRsZXIgaXNuJ3QgYmVpbmcgZW50ZXJlZCB0d2ljZSwKLSB3aGljaCBpcyByZWxhdGVkIHRvIHRoZSBjb2Nvb24gYnVnIGZyb20gYSBjb3VwbGUgb2Ygd2Vla3MgYWdvLiBUaGlzCi0gd2lsbCBqdXN0IGhlbHAgZGlhZ25vc2Ugc3VjaCBhIHByb2JsZW0gaW4gdGhlIGZ1dHVyZS4KLSAzKSBSZW1vdmVkIHRoZSBlcnJvciBzdGFjayB0cmFjZSBwcmludCBmcm9tIHBvc3RFeGNlcHRpb25Gcm9tVGhyZWFkLgotIDQpIFJlcG9ydCBleGNlcHRpb24gaW4gU291cmNlVHJlZUhhbmRsZXIjZW5kRG9jdW1lbnQgYWZ0ZXIKLSB0aGUgam9pbiwgaWYgd2UgY2FuIGRldGVybWluZSB0aGF0IHRoZSBwb3N0ZWQgZXhjZXB0aW9uIHdvbid0IGJlCi0gY2F1Z2h0IGVsc2V3aGVyZS4KLSA1KSByZW1vdmVkIHNvbWUgY2F0Y2hlcyB0aGF0IHNpbXBseSByZXRocmV3IHRoZSBleGNlcHRpb24KLSAodGhhbmtzIHRvIFBhdHJpY2sgTW9vcmUgJmx0O3BhdHJpY2ttQHJpb3BvcnQuY29tJmd0OykuCi0gU2VlIG15IG5vdGUgb24gMy8yNy8yMDAxIHRvIFBhdHJpY2sgZm9yIG1vcmUgaW5mbwotIG9uIHRoZSBsYXN0IHR3by48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzI3LzIwMDE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtU25hcHNob3QuamF2YQotIFRyYW5zZm9ybVNuYXBzaG90SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VW5maW5pc2hlZCAoaW4gcHJvZ3Jlc3MpIGltcGxlbWVudGF0aW9uIG9mIFRyYW5zZm9ybVNuYXBzaG90IG1lY2hhbmlzbSwKLSB3aGljaCB3aWxsIGhvcGVmdWxseSBhbGxvdyBhIHJlc3VsdCBDb250ZW50SGFuZGxlciB0byB0YWtlIGEgc25hcHNob3QKLSBhdCBhIGdpdmVuIHBvaW50LCBhbmQgdGhlIHJlc3RhcnQgZXhlY3V0aW9uIGZyb20gdGhhdCBwb2ludCBhdCBzb21lCi0gbGF0ZXIgdGltZS4gRm9yIHRvb2xpbmcgc3VwcG9ydC5vbiB0aGUgbGFzdCB0d28uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8yOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvcgotIFByb2Nlc3NvclN0eWxlc2hlZXRFbGVtZW50LmphdmEKLSBQcm9jZXNzb3JUZW1wbGF0ZUVsZW0uamF2YSBTdHlsZXNoZWV0SGFuZGxlci5qYXZhCi0gWFNMVEVsZW1lbnREZWYuamF2YSBYU0xURWxlbWVudFByb2Nlc3Nvci5qYXZhCi0gWFNMVFNjaGVtYS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VHJ5IHRvIGNhdGNoIGVsZW1lbnQgb3JkZXIgYW5kIHJlcXVpcmVkIGVsZW1lbnQgZXJyb3JzIGR1cmluZyBzdHlsZXNoZWV0IAotb2JqZWN0IGNyZWF0aW9uLiBUaGlzIG5ldyBjb2RlIGFkZHMgYW4gb3JkZXIgYW5kIGEgcmVxdWlyZWQgZmllbGQgdG8gCi1YU0xFbGVtZW50RGVmIG9iamVjdHMgd2hlcmUgaXQgaXMgYXBwbGljYWJsZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA0LzAyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggYnVnemlsbGEgYnVnIDExNzAuIElmIHdlJ3JlIHRyeWluZyBhbiB4c2w6YXBwbHktaW1wb3J0cyBhdCB0aGUgdG9wIGxldmVsIAotKGllIHRoZXJlIGFyZSBubwotIGltcG9ydGVkIHN0eWxlc2hlZXRzKSwgd2UgbmVlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZXJlIGlzIG5vIG1hdGNoaW5nIHRlbXBsYXRlIAotYW5kIHByZXZlbnQgYW5kIGluZmluaXRlIHJlY3Vyc2lvbiBieSB1c2luZyB0aGUgYnVpbHQtaW4gdGVtcGxhdGUuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8wMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2V4dGVuc2lvbnMgTWV0aG9kUmVzb2x2ZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNvZGUgY2xlYW51cCBzdWJtaXR0ZWQgYnkgQXJ0IFdlbGNoICZsdDthcnRfd0BFQVNUUE9JTlQuQ09NJmd0Oy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA0LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIFRyZWVXYWxrZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZCBsb2NhdG9yIHN1cHBvcnQgdG8gVHJlZVdhbGtlcjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lcgotIFF1ZXVlZFN0YXJ0RWxlbWVudC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+U21hbGwgZml4IG1hZGUgZm9yIGdldEN1cnJlbnROb2RlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgVHJlZVdhbGtlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q29tbWVudGVkIG91dCBleHRyYSBjYWxsIHRvIGdldERhdGEoKS4uLiB0aGlzIGNvdWxkIGJlIGEgYmlnIHBlcmZvcm1hbmNlCi0gaW1wcm92ZW1lbnQgZm9yIHNvbWUgc3R5bGVzaGVldHMuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8wOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtU25hcHNob3RJbXBsLmphdmEgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRpdGlvbmFsIHN1cHBvcnQgZm9yIHRvb2xpbmcuIEFsbG93IHRvb2xzIHRvIHRha2UgYSBzbmFwc2hvdCBvZiBjb250ZXh0IGFuZCAKLXJlc3RhcnQgZXhlY3V0aW9uIGF0IHRoYXQgcG9pbnQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvcgotIFhTTFRFbGVtZW50UHJvY2Vzc29yLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3JlcyBYU0xURXJyb3JSZXNvdXJjZXMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIKLSBUcmFuc2Zvcm1TbmFwc2hvdEltcGwuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1pc2Mgc3R1ZmYgbGVmdCBvdXQgZnJvbSBwcmV2aW91cyBjaGVjayBpbjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMTEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMgRnVuY0N1cnJlbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkRvbid0IGFzc3VtZSB0aGF0IHRoZSBvYmplY3QgcmV0dXJuZWQgYnkgZ2V0U3ViQ29udGV4dExpc3QoKSBpcyBhIAotUHJlZGljYXRlZE5vZGVUZXN0IG9iamVjdC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA0LzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFByb2Nlc3NvckluY2x1ZGUuamF2YQotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIKLSBUcmFuc2Zvcm1lcklkZW50aXR5SW1wbC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgVHJlZVdhbGtlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q3JlYXRlIG5ldyBUcmVlV2Fsa2VyIGNvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBzeXN0ZW1JZCBwYXJhbWV0ZXIuIENoYW5nZSAKLVRyZWVXYWxrZXIgdG8gY2hhbmdlIGZpZWxkcyBpbiB0aGUgbG9jYXRvciBhbmQgbm90IHNldCBpdCBmb3IgZWFjaCBub2RlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jdXJjdXJ1QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8xNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIFhQYXRoLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggQnVnemlsbGEgYnVnOgotIFBSOiAxMTA2Ci0gU3VibWl0dGVkIGJ5OiBlbGhhcm9AbWV0YWxhYi51bmMuZWR1PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmN1cmN1cnVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA0LzE4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBRdWVyeVBhcmFtZXRlci5qYXZhCi0gU1FMRXh0ZW5zaW9uRXJyb3IuamF2YSBYQ29ubmVjdGlvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+TWlub3IgSmF2YWRvYyB1cGRhdGVzIChhZGQgQGF1dGhvciBuYW1lLCByZW1vdmUgZGVjbGFyZWQgYnV0IHVudGhyb3duIEB0aHJvd3MpPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmpvaG5nQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8xOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgQ29sdW1uLmphdmEKLSBDb2x1bW5BdHRyaWJ1dGUuamF2YSBDb2x1bW5EYXRhLmphdmEKLSBDb2x1bW5IZWFkZXIuamF2YSBSb3cuamF2YSBSb3dTZXQuamF2YQotIFN0cmVhbWFibGVOb2RlLmphdmEgWENvbm5lY3Rpb24uamF2YQotIFhTdGF0ZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlN1cHBvcnQgZm9yIFN0cmVhbWFibGUgTW9kZS0gSm9obiBHZW50aWxpbjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMjQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9vYmplY3RzIFhPYmplY3QuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlJlc29sdmUgYnVnemlsbGEgYnVnIDEwMTUgCi0mbHQ7aHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0xMDE1Jmd0Oy4KLSBGaXggcHJldmVudHMgbnVsbCBwb2ludGVyIGV4Y2VwdGlvbnMgd2hlbiBudWxsIG5vbi1YU0xUIGFyZ3VtZW50cyBhcmUKLSBwYXNzZWQgdG8gYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMjQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zIE1ldGhvZFJlc29sdmVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZXNvbHZlIGJ1Z3ppbGxhIGJ1ZyAxMDE1IAotJmx0O2h0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MTAxNSZndDsuCi0gRml4IHByZXZlbnRzIG51bGwgcG9pbnRlciBleGNlcHRpb25zIHdoZW4gbnVsbCBub24tWFNMVCBhcmd1bWVudHMgYXJlCi0gcGFzc2VkIHRvIGFuIGV4dGVuc2lvbiBmdW5jdGlvbi48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA0LzI0LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yCi0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGNvcHkvcGFzdGUgZXJyb3IuIFdhbnQgdG8gdXNlIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwncyBjbGFzcyBsb2FkZXIuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8yNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtU25hcHNob3RJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5LZWVwIGEgY29weSBvZiBjdXJyZW50IGNvbnRleHROb2RlTGlzdCBpcyB0aGVyZSBpcyBvbmU8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y3VyY3VydUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMjUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IEVudmlyb25tZW50Q2hlY2suamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIGNoZWNrRGlyRm9ySmFycygpIHdoaWNoIGNoZWNrcyBqYXZhLmV4dC5kaXJzIGFzIHdlbGwgbm93PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA0LzI2LzIwMDE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL2phdmF4L3htbC90cmFuc2Zvcm0gcGFja2FnZS5odG1sCi0gamF2YS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9kb20gcGFja2FnZS5odG1sCi0gamF2YS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zYXggcGFja2FnZS5odG1sCi0gamF2YS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0gcGFja2FnZS5odG1sPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkIHBhY2thZ2UuaHRtbCBmb3IgZWFjaCBwYWNrYWdlIGluIGphdmF4LnhtbC50cmFuc2Zvcm0uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVzb2x2ZSBidWcgMTQ5NiAmbHQ7aHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0xNDk2Jmd0OyAKLXdoZXJlIHhzbDpwYXJhbSBzdGF0ZW1lbnRzIHdlcmUgbm90IGJlaW5nIHJlc2V0IHByb3Blcmx5IGlmIHRoZSBUcmFuc2Zvcm1lckltcGwgCi13YXMgcmV1c2VkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDQvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zdHJlZSBEb2NJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yICMxNTYxPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNC8yOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucyBGdW5jRXh0RnVuY3Rpb24uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlJlc29sdmUgYnVnemlsbGEgYnVnIDEzNzMgCi0mbHQ7aHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0xMzczJmd0Oy4KLSBBZGRlZCBjb2RlIHRvIHN1cHBvcnQgcmV0dXJuIG9mIEludGVnZXIgb3IgTG9uZyBieSBhbiBleHRlcm5hbCBmdW5jdGlvbi4KLSBDb2RlIHdhcyBjb250cmlidXRlZCBieSBQYXRyaWNrIE1vb3JlICZsdDtwYXRtb29yZUBpZWVlLm9yZyZndDsuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmNvc3RpbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMDMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0gU3RyZWFtUmVzdWx0LmphdmEKLSBTdHJlYW1Tb3VyY2UuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlNtYWxsIGZpeCB0byBhdm9pZCBmaWxlOi8vLy9wYXRoIHRoYXQgbWF5IGZhaWwgb24gc29tZSBKREsuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA1LzA0LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBwYWNrYWdlLmh0bWw8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5QcmVsaW1pbmFyeSB1cGRhdGVzIGZvciBKb2huIEcncyB3b3JrLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNoZWNrIGZvciBhIG51bGwgY29udGV4dE5vZGVMaXN0IGJlZm9yZSByZXR1cm5pbmcgaXRzIGNsb25lPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8wNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3N0cmVlIFN0cmVlRE9NQnVpbGRlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+U2V0IHRoZSBlbGVtZW50J3MgbGV2ZWwgY29ycmVjdGx5LCBiZWZvcmUgd2UgcHJvY2VzcyBhdHRyaWJ1dGVzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMDgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lcgotIFRyYW5zZm9ybWVySWRlbnRpdHlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZXNvbHZlIGJ1Z3ppbGxhIDE2NDggCi0oaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0xNjQ4KS4KLSBUcmFuc2Zvcm1lcklkZW50aXR5SW1wbCB3YXMgaW1wcm9wZXJseSB1c2luZyBhbiBvbGQgTGV4aWNhbEhhbmRsZXIgd2hlbiAKLWludm9rZWQgZm9yIGEgc2Vjb25kIHRyYW5zZm9ybS4KLSBUaGlzIGJ1ZyBvbmx5IGFmZmVjdHMgaWRlbnRpdHkgdHJhbnNmb3JtcyB3aXRoIFN0cmVhbVJlc3VsdHMuCi0gTWFueSB0aGFua3MgdG8gSm9obiBLZXllcyAmbHQ7am9obmtleWVzQHlhaG9vLmNvbSZndDsgZm9yIHJlcG9ydGluZyB0aGlzIGJ1Zy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgWFNMUHJvY2Vzc29yVmVyc2lvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VXBkYXRlZCB2ZXJzaW9uIG51bWJlciB0byAyLjEuMDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3JlcyBYU0xUSW5mby5wcm9wZXJ0aWVzPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VXBkYXRlZCB2ZXJzaW9uIG51bWJlciB0byAyLjEuMDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMgRnVuY0V4dEZ1bmN0aW9uLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DaGFuZ2Ugc3VibWl0dGVkIGJ5IFBhdHJpY2sgTW9vcmUgJmx0O3BhdG1vb3JlQGllZWUub3JnJmd0OyBhcyBwYXJ0IG9mIGJ1Z3ppbGxhIAotMTM3MyAoaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0xMzczKS4KLSBSZXR1cm4gdmFsdWUgZnJvbSBleHRlbnNpb24gZnVuY3Rpb24gaXMgbm93IGdlbmVyYWxpemVkIHNvIHRoYXQgYWxsIAotZGVyaXZhdGl2ZXMgb2YgTnVtYmVyIGFyZSBub3cgcHJvcGVybHkgaGFuZGxlZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA1LzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFhTTFRTY2hlbWEuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlNldCB0aGUgY29ycmVjdCBvcmRlciBvZiB4c2w6aW5jbHVkZSBlbGVtZW50czxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qb2huZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIENvbHVtbi5qYXZhCi0gQ29sdW1uQXR0cmlidXRlLmphdmEgQ29sdW1uRGF0YS5qYXZhCi0gQ29sdW1uSGVhZGVyLmphdmEgQ29ubmVjdGlvblBvb2wuamF2YQotIERlZmF1bHRDb25uZWN0aW9uUG9vbC5qYXZhIEV4dGVuc2lvbkVycm9yLmphdmEKLSBQb29sZWRDb25uZWN0aW9uLmphdmEgUXVlcnlQYXJhbWV0ZXIuamF2YSBSb3cuamF2YQotIFJvd1NldC5qYXZhIFNRTEV4dGVuc2lvbkVycm9yLmphdmEKLSBTdHJlYW1hYmxlTm9kZS5qYXZhIFhDb25uZWN0aW9uLmphdmEKLSBYQ29ubmVjdGlvblBvb2xNYW5hZ2VyLmphdmEgWFN0YXRlbWVudC5qYXZhCi0gcGFja2FnZS5odG1sPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VXBkYXRlcyBKYXZhZG9jcwotIFN1Ym1pdHRlZCBieTpKb2huIEdlbnRpbGluIG1haWx0bzovL2pvaG5nbGludXhAZXllY2F0Y2hpbmcuY29tPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmdhcnlwQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8xNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q29ycmVjdCB0eXBvIGludHJvZHVjZWQgaW4gcmV2aXNpb24gMS4zMCBjYXVzaW5nIHByb2JsZW1zIHdpdGggdHJhbnNmb3JtcyBvbiAKLVVuaXggcGxhdGZvcm1zLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRWxlbUNob29zZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q29ycmVjdCBidWd6aWxsYSBidWcgMTc0OCAKLSZsdDtodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTE3NDgmZ3Q7LgotIFdoZW4gZXZhbHVhdGluZyB4c2w6d2hlbiwgdGhlIHhzbDpjaG9vc2UgZWxlbWVudCB3YXMgdXNlZCB0byByZXNvbHZlIAotbmFtZXNwYWNlIHByZWZpeGVzIGluc3RlYWQgb2YKLSB0aGUgeHNsOndoZW4gZWxlbWVudCBpdHNlbGYuIFRoaXMgY2F1c2VkIG5hbWVzcGFjZSBwcmVmaXhlcyBkZWZpbmVkIG9uIHRoZSAKLXhzbDp3aGVuIHRvIGJlIGlnbm9yZWQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmNvc3RpbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvamF2YXgveG1sL3BhcnNlcnMgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5qYXZhCi0gU0FYUGFyc2VyRmFjdG9yeS5qYXZhCi0gamF2YS9zcmMvamF2YXgveG1sL3RyYW5zZm9ybSBUcmFuc2Zvcm1lckZhY3RvcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlVzZSB0aGUgY29udGV4dCBjbGFzcyBsb2FkZXIgaWYgYXZhaWxhYmxlLgotCi0gVGhlIGltcGxlbWVudGF0aW9uIGlzIGJhc2VkIG9uIEV4dGVuc2lvbkhhbmRsZXIsIGFuZCBpdCdzIG5lZWRlZCBpbiBvcmRlcgotIHRvIHdvcmsgaW4gY2VydGFpbiBlbnZpcm9ubWVudHMgKCBsaWtlIHRvbWNhdCApLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jb3N0aW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA1LzE1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vZXh0ZW5zaW9ucyBFeHRlbnNpb25IYW5kbGVyLmphdmEKLSBFeHRlbnNpb25IYW5kbGVyR2VuZXJhbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+TWFrZSBnZXRDbGFzc0Zvck5hbWUgYSBwdWJsaWMgbWV0aG9kLiBUaGVyZSBhcmUgZmV3IG90aGVyIHBsYWNlcyBpbiB4YWxhbgotIHdoZXJlIENsYXNzLmZvck5hbWUgaXMgdXNlZCwgYW5kIHRoaXMgY2FuIGNyZWF0ZSBwcm9ibGVtcyBpbiBzb21lIGNhc2VzCi0gd2hlcmUgdGhlIFRocmVhZC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIgc2hvdWxkIGJlIHVzZWQuCi0KLSBnZXRDbGFzc0Zvck5hbWUgdXNlcyBpbnRyb3NwZWN0aW9uIHRvIGNhbGwgZ2V0Q29udGV4dENsYXNzTG9hZGVyCi0gKCBzbyBpdCB3b3JrcyBpbiBKREsxLjEgKS4KLQotIEluIEV4dGVuc2lvbkhhbmRsZXJHZW5lcmFsLCB1c2UgdGhlIHRocmVhZCBsb2FkZXIgdG8gZmluZCBCU0YgKCBpdCBtYXkgYmUKLSBwb3NzaWJsZSB0aGF0IHhhbGFuIGlzIGluc3RhbGxlZCBpbiBDTEFTU1BBVEgsIGJ1dCBCU0YgaXMgaW4gYSB3ZWJhcHAgKS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y29zdGluQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8xNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvcgotIENvbXBpbGluZ1N0eWxlc2hlZXRIYW5kbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZSBTZXJpYWxpemVyRmFjdG9yeS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+MiBtb3JlIGluc3RhbmNlcyB3aGVyZSBDbGFzcy5mb3JOYW1lIHdhcyB1c2VkLgotCi0gVXNlIHRoZSBtZXRob2QgaW4gRXh0ZW5zaW9uSGFuZGxlciBmb3IgY29uc2lzdGVuY3kgKCB3ZSBjb3VsZCBtb3ZlIGl0IGluCi0gb3JnLmFwYWNoZS54bWwudXRpbHMsIGJ1dCBmb3Igbm93IGl0J3MgZWFzaWVyIHRvIGp1c3QgdXNlIGl0IGFzIGl0IGlzICk8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y29zdGluQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8xNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3N0cmVlIFNvdXJjZVRyZWVIYW5kbGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VGhpcyBpcyB0aGUgInRocmVhZCBwb29saW5nIGhvb2siLgotCi0gSXQgc2xpZ2h0bHkgY2hhbmdlcyB0aGUgQVBJIHVzZWQgdG8gY3JlYXRlIGFuZCB3YWl0IGZvciB0aGUgdHJhbnNmb3JtIHRocmVhZC4KLSBJbnN0ZWFkIG9mIHVzaW5nIHRocmVhZENyZWF0ZSgpIGFuZCBUaHJlYWQuc3RhcnQoKSB0aGF0IGNyZWF0ZXMgYSBuZXcgdGhyZWFkCi0gYW5kIHRocmVhZC5qb2luKCkgdGhhdCB3YWl0cyBmb3IgYSB0aHJlYWQgdG8gZW5kLCB3ZSBub3cgdXNlIGEgCi1UaHJlYWRDb250cm9sZXIKLSBjbGFzcyB0aGF0IGhhcyB0aGUgZXF1aXZhbGVudCBtZXRob2RzOgotIC0gcnVuKCBSdW5uYWJsZSApIC0gZXhlY3V0ZXMgYSB0YXNrIGluIGEgdGhyZWFkLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgotIGlzIGlkZW50aWNhbCB3aXRoIHdoYXQgd2UgaGFkLCB1c2luZyBuZXcgVGhyZWFkKCkgYW5kIHN0YXJ0KCkKLSAtIHdhaXRUcmVhZCgpIC0gd2FpdHMgZm9yIGEgdGFzayB0byBlbmQuIFRoZSBkZWZhdWx0IGltcGwuIGlzIGlkZW50aWNhbCB3aXRoCi0gdGhlIHByZXZpb3VzIGNvZGUsIHVzaW5nIHRocmVhZC5qb2luKCkuCi0KLSBTb21lb25lIHdhbnRpbmcgdG8gdXNlIGEgdGhyZWFkIHBvb2wgZm9yIHhhbGFuIHdpbGwgaGF2ZSB0byBleHRlbmQKLSB0aGUgVGhyZWFkQ29udHJvbGVyIGFuZCBvdmVycmlkZSB0aGUgMiBtZXRob2RzLCB0aGVuIGNhbGwgc2V0VGhyZWFkQ29udHJvbGxlci4KLQotIFhhbGFuIGl0c2VsZiBkb2Vzbid0IGltcGxlbWVudCBhIHRocmVhZCBwb29sIHJpZ2h0IG5vdyAoIGZvciBtb3N0cyB1c2VzIGl0J3MKLSBub3QgZXZlbiBuZWVkZWQgLSBpZiB5b3UganVzdCBkbyBmZXcgdHJhbnNmb3JtcyBmb3IgZXhhbXBsZSApLCBpbnN0ZWFkCi0gYSBzZXJ2ZXIgdGhhdCBydW5zIHhhbGFuIGNvdWxkIHBsdWcgaXQncyBvd24gdGhyZWFkIHBvb2wuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPkdhcnkgTCBQZXNraW4gJmx0O2dhcnlwQGZpcnN0ZWNoLmNvbSZndDs8cmVmPiBvbiA8L3JlZj4wNS8xNS8yMDAxPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Ci0mZ3Q7IFVzZSB0aGUgY29udGV4dCBjbGFzcyBsb2FkZXIgaWYgYXZhaWxhYmxlLgotJmd0OwotJmd0OyBUaGUgaW1wbGVtZW50YXRpb24gaXMgYmFzZWQgb24gRXh0ZW5zaW9uSGFuZGxlciwgYW5kIGl0J3MgbmVlZGVkIGluIG9yZGVyCi0mZ3Q7IHRvIHdvcmsgaW4gY2VydGFpbiBlbnZpcm9ubWVudHMgKCBsaWtlIHRvbWNhdCApLgotJmd0OwotJmd0Ozxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8xNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgRXh0ZW5zaW9uRXJyb3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeGVkICJjb25mbGljdCIgaW4gamF2YWRvYyBjb21tZW50cy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIHBhY2thZ2UuaHRtbDxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkVkaXRpbmcgcGFzcy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBUcmFuc2xldE91dHB1dEhhbmRsZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmJ1ZyAjIDE0MDYgZml4ZWQsIG9taXQgeG1sIGhlYWRlciBpbXBsZW1lbnRlZDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jdXJjdXJ1QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8xNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VXBkYXRlIEphdmFkb2MgYW5kIHJlbW92ZSBjb21tZW50ZWQgb3V0IHJlZmVyZW5jZSB0byBwcm9wZXJ0aWVzIGZpbGUKLSBQUjpCdWd6aWxsYTE2Mjc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA1LzE4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgUmVzdWx0VHJlZUhhbmRsZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlJlc29sdmUgYnVnIDEzMzAgJmx0O2h0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MTMzMCZndDsuCi0gc2V0Q29udGVudEhhbmRsZXIgZmFpbGVkIHRvIGFsc28gcmVzZXQgbV9sZXhpY2FsSGFuZGxlciBpZiB0aGUgQ29udGVudEhhbmRsZXIKLSB3YXMgYWxzbyBhIExleGljYWxIYW5kbGVyLiBUaGlzIGNhdXNlZCB0aGUgb2xkIExleGljYWxIYW5kbGVyIHRvIGJlIHVzZWQgCi13aGljaAotIHdhcyBwb2ludGluZyB0byBhIHByZXZpb3VzIHJlc3VsdCB0cmVlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZXNvbHZlIGJ1ZyAxNzYyICZsdDtodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTE3NjImZ3Q7LgotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwncyBVUklSZXNvbHZlciB3YXMgbm90IHByb3BhZ2F0ZWQgdG8gY3JlYXRlZCAKLVRyYW5zZm9ybWVycy4KLSBNb2RpZmllZCBjb2RlIHRvIHByb3BhZ2F0ZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y3VyY3VydUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMTkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgVHJlZVdhbGtlci5qYXZhCi0gU3lzdGVtSURSZXNvbHZlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2F0Y2ggU2VjdXJpdHlFeGNlcHRpb24gd2hlbmV2ZXIgYWNjZXNzaW5nIFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5kaXIiKTsKLSBtaW5vciBqYXZhZG9jIHVwZGF0ZTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMjEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRWxlbUNvcHkuamF2YQotIEVsZW1WYWx1ZU9mLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyZWVXYWxrZXIyUmVzdWx0LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2Z1bmN0aW9ucyBGdW5jTGFzdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBidWdzIHJlcG9ydGVkIGJ5IHRoZSBFY2xpcHNlIGZvbGtzIGZvciBUcmFuc2Zvcm1TdGF0ZSwgd2hlcmUKLSBzb21lIG9wZXJhdGlvbnMgKHhzbDp2YWx1ZS1vZiwgeHNsLWNvcHkpIHdlcmUgbm90IHB1c2hpbmcgdGhlCi0gY3VycmVudCBub2RlIG9uIHRoZSBjdXJyZW50IG5vZGUgc3RhY2suIEFkZHJlc3NlcwotIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9MTUyNC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y3VyY3VydUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMjEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgT3V0cHV0UHJvcGVydGllcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2F0Y2ggU2VjdXJpdHlFeGNlcHRpb24gYXMgbmVlZGVkCi0gUFI6IEJ1Z3ppbGxhMTI1ODxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMjEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgT3V0cHV0UHJvcGVydGllcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IHRvIHRoZSBmb2xsb3dpbmcgYnVnIHJlcG9ydGVkIGJ5IGRpbXNAeWFob28uY29tOgotCi0gbG9hZFByb3BlcnRpZXNGaWxlIG1ldGhvZCBpbiBvcmdcYXBhY2hlXHhhbGFuXHRlbXBsYXRlc1xPdXRwdXRQcm9wZXJ0aWVzLmphdmEgCi1kb2VzIG5vdCBmYWxsIGJhY2sKLSB0byB0aGUgVGhyZWFkIENvbnRleHQgQ2xhc3MgTG9hZGVyIHRvIGxvYWQgcHJvcGVydGllcyBmaWxlcyBsaWtlIAotb3V0cHV0X3htbC5wcm9wZXJ0aWVzIGV0Yy4gVGhpcwotIGlzIGNhdXNpbmcgcHJvYmxlbXMgaW4gU2VydmxldEV4ZWNfM18xK0MyLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMjEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgT3V0cHV0UHJvcGVydGllcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q29ycmVjdCBpbXBsZW1lbnRhdGlvbiBvZiBDb250ZXh0Q2xhc3NMb2FkZXIgdG8gc3VwcG9ydCBjYXNlIHdoZXJlIHByb3BlcnRpZXMgCi1maWxlIGlzIHRvIGJlIGxvYWRlZCBieSBhIGRpZmZlcmVudCBDbGFzc0xvYWRlciB0aGFuIHRoZSBPdXRwdXRQcm9wZXJ0aWVzIAotY2xhc3MuIFRoYW5rcyB0byBEYXZhbnVtIFNyaW5pdmFzICZsdDtkaW1zQHlhaG9vLmNvbSZndDsgZm9yIHRoaXMgY29kZSBhbmQgZm9yIAotcmVwb3J0aW5nIHRoaXMgYnVnLgotIGxvYWRQcm9wZXJ0aWVzRmlsZSBzaG91bGQgZXZlbnR1YWxseSBiZSBtb3ZlZCBpbnRvIGEgdGhyZWFkLXNwZWNpZmljIGNsYXNzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDUvMjEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZSBDaGFySW5mby5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9mdW5jdGlvbnMgRnVuY1N5c3RlbVByb3BlcnR5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Nb2RpZnkgZ2V0UmVzb3VyY2VBc1N0cmVhbSBjYWxscyB0byB1c2UgdGhlIGNvbnRleHRDbGFzc0xvYWRlciwgaWYgYXZhaWxhYmxlLgotIFRoaXMgaXMgYSB0ZW1wb3JhcnkgZml4IHVudGlsIHdlIGNhbiBjZW50cmFsaXplIHRoaXMgZnVuY3Rpb24uPGJyLz48YnIvPjwvbGk+PC91bD48bm90ZT5UaGlzIHJlbGVhc2UgaW5jbHVkZXMgbm8gdXBkYXRlcyBvZiB0aGUgY29tcGF0aWJpbGl0eSBzb3VyY2UgY29kZS48L25vdGU+Ci0gPC9zMz4KLSAKLTxzMyB0aXRsZT0iQ2hhbmdlcyBmb3IgJnhzbHQ0ajsgMi4wLjEiPgotPHA+VGhpcyByZWxlYXNlIGluY2x1ZGVzIGEgbnVtYmVyIG9mIGJ1ZyBmaXhlcyB0byB0aGUgJnhzbHQ0ajsgYW5kIFRyQVggY29yZSBhbmQgWGFsYW4tSmF2YSAxIGNvbXBhYmlsaXR5IEFQSS4gV2UgaGF2ZSBhbHNvPC9wPgotPHVsPgotICA8bGk+RW50ZXJlZCBhbGwga25vd24gJnhzbHQ0ajsgMiA8bGluayBhbmNob3I9ImJ1Z3MiPmJ1Z3M8L2xpbms+IGluIHRoZSBBcGFjaGUgQnVnemlsbGEgZGF0YWJhc2U8YnIvPjxici8+PC9saT4KLSAgPGxpPkFkZGVkIHN1cHBvcnQgZm9yIHVzaW5nIGN1c3RvbSBVUklSZXNvbHZlciwgRW50aXR5UmVzb2x2ZXIsIGFuZCBDb250ZW50SGFuZGxlciBpbXBsZW1lbnRhdGlvbnMgd2l0aCB0aGUgPGxpbmsKLSAgICAgIGlkcmVmPSJjb21tYW5kbGluZSI+Y29tbWFuZC1saW5lIHV0aWxpdHk8L2xpbms+PGJyLz48YnIvPjwvbGk+IAotICA8bGk+VXBncmFkZWQgZnJvbSBBbnQgMS4yIHRvIEFudCAxLjMgZm9yIG91ciA8bGluayBhbmNob3I9ImJ1aWxkIj5idWlsZHM8L2xpbms+ICh0aGUgbmV3IGFudC5qYXIgaXMgaW4gdGhlIGJpbiBkaXJlY3RvcnkpLjwvbGk+Ci08L3VsPgotPHA+Q29yZSBzb3VyY2UgY29kZSB1cGRhdGVzOjwvcD4KLTx1bD4KLTxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIENoaWxkV2Fsa2VyTXVsdGlTdGVwLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIGJ1ZyByZXBvcnRlZCBieSAiQ2hyaXMgUC4gTWNDYWJlIiAmbHQ7Y2hyaXNfbWNjYWJlQGNob2ljZWhvdGVscy5jb20mZ3Q7Ci0gMDIvMDYvMjAwMSAwNjo1NSBQTS4KLSBEZWZlbnNpdmUgZml4IGZvciBpZiB0aGUgbGFzdCB1c2VkIHdhbGtlciBpcyBudWxsLCB0aGVuIGRvbid0IGNoZWNrIHRvCi0gc2VlIGlmIGl0IGlzIGEgZmFzdCB3YWxrZXIhIFdpdGhvdXQgdGhpcywgYSBudWxsIHBvaW50ZXIgZXhjZXB0aW9uIGlzCi0gdmVyeSBwb3NzaWJsZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXhlcyBmb3IgZXhjZXB0aW9ucyBiZWluZyB0aHJvd24gdGhhdCB3ZXJlbid0IGJlaW5nIHBhc3NlZCB0aHJvdWdoCi0gdGhlIGVycm9yIGxpc3RlbmVyLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9heGVzIEZvbGxvd2luZ1dhbGtlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBidWcgcmVwb3J0ZWQgYnkgRGF2ZSBIYWZmbmVyICZsdDtkYXZlLmhhZmZuZXJAeG1scy5jb20mZ3Q7Ci0gMDIvMDYvMjAwMSAwNDowMyBBTQotIEluIHBhcmVudE5vZGUoKSwgZG9uJ3Qgc2NyZWVuIG91dCBuZXh0QW5jZXN0b3IsIHNpbmNlIHRoZSBwYXJlbnQKLSBpcyBuZXZlciBhY3R1YWxseSByZXR1cm5lZC4gVGhpcyBzZXRzIHRoaW5ncyB1cCBjb3JyZWN0bHkgZm9yIGZpcnN0Q2hpbGQKLSBhbmQgbmV4dFNpYmxpbmcuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8wNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMgUHJlY2VkaW5nV2Fsa2VyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIGJ1ZyByZXBvcnRlZCBieSBEYXZlIEhhZmZuZXIgJmx0O2RhdmUuaGFmZm5lckB4bWxzLmNvbSZndDsKLSAwMi8wNi8yMDAxIDA0OjAzIEFNCi0gSW4gbmV4dFNpYmxpbmcoKSwgZG9uJ3QgcmV0dXJuIG51bGwgaWYgaXNBbmNlc3Rvck9mUm9vdENvbnRleHQsIGluc3RlYWQKLSBkbyBuZXh0LmdldEZpcnN0Q2hpbGQoKS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggU291cmNlVHJlZU1hbmFnZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgYnVnIHJlcG9ydGVkIGJ5IGFuZGVycy5kb21laWpAdWMuc2UKLSAwMi8wNy8yMDAxIDA5OjM1IEFNCi0gcmVtb3ZlZCBleHRyYSBib2d1cyBUcmFuc2Zvcm1lckV4Y2VwdGlvbiBkZWNsIGluIHJlc29sdmVVUkk8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzA4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc3RyZWUgU291cmNlVHJlZUhhbmRsZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBidWcgcmVwb3J0ZWQgYnkgSmFzb24gSGFycm9wICZsdDtqaGFycm9wQGJpZ3BvbmQubmV0LmF1Jmd0OwotIDAyLzA3LzIwMDEgMDg6MTIgUE0KLSBEb24ndCBwcm9jZXNzIGNvbW1lbnQgb3Igd2hpdGVzcGFjZSBldmVudHMgaWYgaW5zaWRlIGEgc3RhcnREVEQvZW5kRFRECi0gZXZlbnQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2F4ZXMgV2Fsa2VyRmFjdG9yeS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW4gaW5kaXJlY3QgcmVzcG9uc2UgdG8gYnVnIHBvc3RlZCBieSAiVGhlZSBCb29uIEhvbyIgJmx0O3RoZWViaEBuZXdzdGFrZXMuY29tJmd0OwotIDAyLzA3LzIwMDEgMDk6MzcgUE0KLQotICIvL3RhYmxlWzFdIiBwYXR0ZXJucyB3b3VsZCBnaXZlIG9uZSBub2RlCi0gd2hlbiB0aGV5IHNob3VsZCBoYXZlIGdpdmVuIDIsIHdoZW4gYXBwbGllZCB0byBCb29uIEhvbydzCi0gc291cmNlLgotICIvL3RhYmxlWzFdIiBpcyBlcXVpdmVsZW50IHRvCi0gIi9kZXNjZW5kYW50LW9yLXNlbGY6Om5vZGUoKS90YWJsZVsxXSIsCi0gYW5kIHNvIG11c3QgcmV0dXJuIHRoZSBmaXJzdCB0YWJsZSBjaGlsZAotIG9mIGVhY2ggdGFibGUtaW5zdCBlbGVtZW50LgotCi0gQW4gb3B0aW1pemF0aW9uIHdhcyBvcHRpbWl6aW5nIHRoaXMgdG8KLSAiL2Rlc2NlbmRhbnQtb3Itc2VsZjo6dGFibGUsIHdoaWNoIGlzCi0gZmluZSBhcyBsb25nIGFzIGluZGV4aW5nIGlzbid0IHVzZWQuIFNpbmNlCi0gd2UgY2FuIG5vdCB0ZWxsIHVudGlsIHJ1bnRpbWUgaWYgaW5kZXhpbmcKLSBpcyBiZWluZyB1c2VkLCB3ZSBoYXZlIHRvIHR1cm4gb2YgdGhpcwotIG9wdGltaXphdGlvbiBmb3IgYWxsIHByZWRpY2F0ZWQgIi8vZm9vW3h4XSIKLSBwYXR0ZXJucy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFN0eWxlc2hlZXRQSUhhbmRsZXIuamF2YQotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlBhdGNoIGZvciBEbWl0cmkgSUl5aW4gdG8gdXNlIHRoZSBzcGVjaWZpZWQgVVJJUmVzb2x2ZXIuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8xMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RlbXBsYXRlcyBFbGVtTnVtYmVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5OdW1iZXIgRXhwcmVzc2lvbiBzaG91bGQgYmUgZXZhbHVhdGVkIHRoZW4gcm91bmRlZCB1cC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzEzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBQcm9jZXNzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DcmVhdGUgYSBkb2N1bWVudCBmcmFnbWVudCBmb3IgdGhlIG91dHB1dCBub2RlLCBmb3IgLWZsYXZvciBkMmQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8xMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoL2NvbXBpbGVyIENvbXBpbGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5CZXR0ZXIgZXJyb3IgbWVzc2FnZSB3aGVuIHF1byBpcyB1c2VkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRWxlbUNhbGxUZW1wbGF0ZS5qYXZhCi0gRWxlbUNob29zZS5qYXZhIEVsZW1Db3B5LmphdmEgRWxlbUZhbGxiYWNrLmphdmEKLSBFbGVtSWYuamF2YSBFbGVtTGl0ZXJhbFJlc3VsdC5qYXZhCi0gRWxlbVRlbXBsYXRlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtb3ZlIGV4dHJhIG1ldGhvZC9jYWxsIHRvIFRyYW5zZm9ybWVySW1wbC5leGVjdXRlQ2hpbGRUZW1wbGF0ZXMoKTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucyBOb2RlVGVzdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmV0dXJuIGFuIGVtcHR5IHN0cmluZyBpbnN0ZWFkIG9mIG51bGwgZnJvbSBnZXRMb2NhbE5hbWUoKSB3aGVuIHRoZQotIG5vZGV0ZXN0IGRvZXMgbm90IGhhdmUgYSBuYW1lLiBFbmNvdW50ZXJlZCB3aXRoIHRoZSBTUUwgZXh0ZW5zaW9uLAotIGluIHJlc3BvbnNlIHRvIGJ1ZyByZXBvcnRlZCBieSAiTWljaGFlbCBLYXkiICZsdDttaGtheUBpY2x3YXkuY28udWsmZ3Q7LAotIDAyLzA4LzIwMDEgMDg6NTcgQU0uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8xMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgQ29sdW1uRGF0YS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW4gZ2V0RGF0YSgpIHJldHVybiBhbiBlbXB0eSBzdHJpbmcgaW5zdGVhZCBvZiBudWxsIGlmIHRoZXJlIGlzCi0gbm8gZGF0YSB0byBiZSBvYnRhaW5lZC4KLSBJbiByZXNwb25zZSB0byBidWcgcmVwb3J0ZWQgYnkgIk1pY2hhZWwgS2F5IiAmbHQ7bWhrYXlAaWNsd2F5LmNvLnVrJmd0OywKLSAwMi8wOC8yMDAxIDA4OjU3IEFNLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMTkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9leHRlbnNpb25zIE1ldGhvZFJlc29sdmVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Db3JyZWN0IENvbnZlcnNpb25JbmZvIGFycmF5IGZvciBOb2RlLVNldCBhbmQgUlRGLiBSZW1vdmUgRG9jdW1lbnRGcmFnbWVudCAKLWZyb20gUlRGIGFuZCByZXBsYWNlIHdpdGggTm9kZUxpc3QuIFJlbW92ZSBkdXBsaWNhdGUgQm9vbGVhbiBmcm9tIGJvdGguIEZpeCAKLUJvb2xlYW4gY29udmVyc2lvbiB0byBtYWtlIGphdmEubGFuZy5Cb29sZWFuIGhpZ2hlciB0aGFuIHN0cmluZy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzE5LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBDb2x1bW5IZWFkZXIuamF2YQotIFJvd1NldC5qYXZhIFhTdGF0ZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlVzZSBudWxsIG5vZGV0ZXN0IHRvIG1lYW4gdGhlIHNhbWUgYXMgIm5vZGUoKSIuIFRoaXMgZml4ZXMgYSBidWcgcmVwb3J0ZWQKLSBieSAiVm95dGVua28sIERpbWl0cnkiICZsdDtEVm95dGVua29AU0VDVE9SQkFTRS5DT00mZ3Q7Ci0gd2hlcmUgJmx0O3hzbDpjb3B5LW9mIHNlbGVjdD0ic3FsOnF1ZXJ5KC4uLikiLyZndDsKLSBjcmFzaGVzIHdpdGggTnVsbFBvaW50ZXJFeGNlcHRpb24sIGkuZS4KLSB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgd2UgcmVhbGx5IGRvbid0IHdhbnQKLSB0byBzZXQgdGhlIE5vZGVUZXN0Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMjAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9jb21waWxlciBYUGF0aFBhcnNlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2hlY2sgZm9yIG51bGwgdG9rZW4gYmVmb3JlIGNoZWNraW5nIGlmIGl0IGlzIGEgbGV0dGVyPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8yMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtZXJJZGVudGl0eUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBtYWRlIGZvciBidWcgcmVwb3J0ZWQgYnkgIkdsZW5jcm9zcywgQ2hyaXN0aWFuIiAKLSZsdDtDaHJpc3RpYW4uR2xlbmNyb3NzQGdzLmNvbSZndDsKLSBvbiAwMi8xNi8yMDAxIDEwOjE4IEFNLgotIFhlcmNlcyAxLjIuMyBTQVggcGFyc2VyIGNhbGxzCi0gaGFuZGxlci5zZXREb2N1bWVudExvY2F0b3IoKSBiZWZvcmUgaGFuZGxlci5zdGFydERvY3VtZW50KCkuCi0gVHJhbnNmb3JtZXJJZGVudGl0eUltcGwubV9yZXN1bHRDb250ZW50SGFuZGxlciBpc24ndCBpbml0aWFsaXNlZCB1bnRpbAotIFRyYW5zZm9ybWVySWRlbnRpdHlJbXBsLnN0YXJ0RG9jdW1lbnQoKSBpcyBjYWxsZWQuCi0gQWRkZWQgbGF6eSBjb25zdHJ1Y3Rpb24gb2YgcmVzdWx0IGhhbmRsZXIKLSBpbiBzZXREb2N1bWVudExvY2F0b3IsIGluIGFkZGl0aW9uIHRvCi0gc3RhcnREb2N1bWVudC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzIxLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliIEV4dGVuc2lvbnMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNvcnJlY3QgaW1wbGVtZW50YXRpb24gb2Ygc3RyaW5nIHZhbHVlIG9mIGEgbm9kZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMjEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIENvbHVtbi5qYXZhCi0gQ29sdW1uQXR0cmlidXRlLmphdmEgQ29sdW1uRGF0YS5qYXZhCi0gQ29sdW1uSGVhZGVyLmphdmEgUm93LmphdmEgUm93U2V0LmphdmEKLSBTdHJlYW1hYmxlTm9kZS5qYXZhIFhDb25uZWN0aW9uLmphdmEKLSBYU3RhdGVtZW50LmphdmEgcGFja2FnZS5odG1sPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgZXhwZXJpbWVudGFsIHVzYWdlIG1ldGF0YWcgdG8gYWxsIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlLAotIGFuZCBhbiBleHBsYW5hdG9yeSBub3RlIHRvIHBhY2thZ2UuaHRtbC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzIyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc3RyZWUgRWxlbWVudEltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkJ1ZyBmaXggYXR0cmlidXRlZCB0byBOb3JtYW4gV2Fsc2ggJmx0O25kd0Bud2Fsc2guY29tJmd0Oywgb24KLSAwMi8yMC8yMDAxIDA5OjUwIEFNLiBpZiB0aGUgYXR0cmlidXRlICduYW1lJyBkb2Vzbid0IG9jY3VyIGluIHRoZSBBdHRMaXN0LCAKLXRoZQotIHJlc3VsdCBvZiBnZXRJbmRleChuYW1lKSBpcyAtMSwgYnV0Ci0gZ2V0Q2hpbGRBdHRyaWJ1dGUoKSB3b3VsZCBpbmNvcnJlY3RseQotIHJldHVybiB0aGUgZmlyc3QgYXR0cmlidXRlLiBGaXggcmV0dXJucwotIG51bGwgaWYgaW5kZXggJmx0OyAwLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMjIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUgU2VyaWFsaXplclRvWE1MLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtZXJJZGVudGl0eUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkltcGxlbWVudCBEZWNsSGFuZGxlciBmb3IgaWRlbnRpdHkgdHJhbnNmb3Jtczxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMjIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgYnVnIG9yaWdpbmFsbHkgcmVwb3J0ZWQgYnkgRGFyeWwgQmVhdHRpZSAmbHQ7RGFyeWxCQHNjcmVhbWluZ21lZGlhLmNvbSZndDsKLSBvbiAwMi8xNC8yMDAxIDA0OjE2IFBNLiBBIGhhbmcgd2FzIG9jY3VyaW5nIGluc2lkZSB0aGUgdXNlCi0gb2YgYSBSZXN1bHQgVHJlZSBGcmFnbWVudC4gV2hlbiB0aGUgcmVzdWx0IHRyZWUgZnJhZ2VtZW50IHdhcwotIGJlaW5nIGNyZWF0ZWQsIHRoZSBSZWRpcmVjdCBleHRlbnNpb24gd2FzIGJlaW5nIGNhbGxlZCwgd2hpY2gKLSBjYWxsZWQgY3JlYXRlUmVzdWx0Q29udGVudEhhbmRsZXIgd2hpY2ggc2V0IHRoZSBDb250ZW50SGFuZGxlcgotIGluIHRoZSBUcmFuc2Zvcm1lciwgYnV0IG5vdCBpbiB0aGUgUmVzdWx0VHJlZUhhbmRsZXIuIFRoZW4sIFJlZGlyZWN0Ci0gY2FsbGVkIFRyYW5zZm9ybWVyI2V4ZWN1dGVDaGlsZFRlbXBsYXRlcygKLSBFbGVtVGVtcGxhdGVFbGVtZW50IGVsZW0sIE5vZGUgc291cmNlTm9kZSwgUU5hbWUgbW9kZSwgCi1Db250ZW50SGFuZGxlciBoYW5kbGVyKQotIHdoaWNoIHNhdmVzIHRoZSByZWZlcmVuY2UgdG8gdGhlIG9yaWdpbmFsIGNvbnRlbnQgaGFuZGxlciBpbgotIHRoZSB0cmFuc2Zvcm1lciwgYW5kIHRoZW4gc2V0cyB0aGUgbmV3IG9uZSBieSBjYWxsaW5nIHNldENvbnRlbnRIYW5kbGVyLAotIHdoaWNoIHNldHMgdGhlIENvbnRlbnRIYW5kbGVyIGluIHRoZSBSZXN1bHRUcmVlSGFuZGxlciBhcyB3ZWxsCi0gYXMgdGhlIFRyYW5zZm9ybWVyLiBXaGVuIGl0IHRyaWVkIHRvIHJlc3RvcmUgdGhlIG9sZCBDb250ZW50SGFuZGxlciwKLSBpdCByZXN0b3JlZCB0aGUgdmFsdWUgaW4gdGhlIFJlc3VsdFRyZWVIYW5kbGVyIHRvIGEgU2VyaWFsaXplciwgaW5zdGVhZAotIG9mIHRoZSBjb3JyZWN0IENvbnRlbnRIYW5kbGVyLiBXaGVuIHRyYW5zZm9ybVRvUlRGIHRoZW4gY2FsbGVkCi0gZW5kRG9jdW1lbnQgb24gaXQncyByZXN1bHRUcmVlRnJhZ21lbnQsIHRoZSBldmVudCB3YXMgc2VudAotIHRvIHRoZSBTZXJpYWxpemVyIGluc3RlYWQgb2YgdGhlIFNvdXJjZVRyZWVIYW5kbGVyLCBhbmQgdGh1cyB0aGUKLSBpc0NvbXBsZXRlIGZsYWcgd2FzIG5vdCBzZXQsIGFuZCB0aHVzIHRoZSBoYW5nLiAod2hldyEpCi0gVGhlIGZpeCBpcyBpbiBleGVjdXRlQ2hpbGRUZW1wbGF0ZXMgc2F2ZSB0aGUgdmFsdWUgb2YgdGhlCi0gcmVzdWx0VHJlZUhhbmRsZXIncyBjb250ZW50SGFuZGxlciBhcyB3ZWxsIGFzIFRyYW5zZm9ybWVyJ3MKLSBjb250ZW50IGhhbmRsZXIsIGFuZCByZXN0b3JlIHRoZW0gYm90aC4gQSBtb3JlIGFyY2hpdGVjdHVhbCBmaXgKLSBjb3VsZCBiZSBtYWRlLCBidXQgbm90IHdpdGhvdXQgaGlnaCByaXNrLCBzbyBJIHRoaW5rIHRoaXMgaXMgdGhlIGJlc3QKLSBhbmQgc2FmZXN0IHdheSB0byBmaXggaXQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzIzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzIFhTTFRJbmZvLnByb3BlcnRpZXM8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DaGFuZ2VkIHZlcnNpb24gdG8gMi4wLjE8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMjMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgWFNMUHJvY2Vzc29yVmVyc2lvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2hhbmdlZCB2ZXJzaW9uIHRvIDIuMC4xPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmN1cmN1cnVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzI4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcmVzIFhTTFRFcnJvclJlc291cmNlcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VXBkYXRlIHRleHQgb2YgZXJyb3IgbWVzc2FnZXMKLSBTdWJtaXR0ZWQgYnk6IEFuZHJlYXMgWmVobnBmdW5kPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmN1cmN1cnVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzI4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBQcm9jZXNzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5VcGRhdGUgcHJpbnRBcmdPcHRpb25zKCkgd2l0aCBiZXR0ZXIgdGV4dCBhbmQgdG8gYmV0dGVyIHJlZmxlY3QgYWN0dWFsCi0gb3B0aW9ucyB0aGF0IGFyZSBjdXJyZW50bHkgc3VwcG9ydGVkOyBjYXRjaCBtaXNzaW5nIC1JTiBhcmd1bWVudDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5qa2Vzc2VsbUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMDUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9jbGllbnQgWFNMVFByb2Nlc3NvckFwcGxldC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgU3R5bGVzaGVldEhhbmRsZXIuamF2YQotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc3RyZWUgRG9jSW1wbC5qYXZhCi0gU3RyZWVET01CdWlsZGVyLmphdmEgVGV4dEltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzIE91dHB1dFByb3BlcnRpZXMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBQcm9jZXNzLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBGYXN0U3RyaW5nQnVmZmVyLmphdmEKLSBqYXZhL3NyYy90cmF4IHRyYXgucHJvcGVydGllczxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk5ldyBhcHByb2FjaCB0byBGYXN0U3RyaW5nQnVmZmVyLCBhbmQgY2hhbmdlcyBuZWVkZWQgdG8gc3VwcG9ydCBpdC4KLSBXZSBzdGlsbCBuZWVkIHRvIGRvIHNvbWUgc2VyaW91cyB3b3JrIG9uIGJvdGggdGhlIGluaXRpYWwgdmFsdWVzIG9mIHRoZQotIHR1bmluZyBwYXJhbWV0ZXJzIGFuZCB0aGUgaGV1cmlzdGljcyBkcml2aW5nIHRoZSAiY2h1bmsgZ3Jvd3RoIiBhbGdvcml0aG1zLgotIEN1cnJlbnRseSBzZXQgZm9yIGZpeGVkLXNpemVkIGNodW5rcyBvZiA4S2NoIGluIG1haW4gdHJlZSwgLjVLY2ggaW4gUlRGLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRWxlbUVsZW1lbnQuamF2YQotIEVsZW1Gb3JFYWNoLmphdmEgRWxlbUxpdGVyYWxSZXN1bHQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIKLSBDbG9uZXJUb1Jlc3VsdFRyZWUuamF2YSBRdWV1ZWRTQVhFdmVudC5qYXZhCi0gUXVldWVkU3RhcnREb2N1bWVudC5qYXZhIFF1ZXVlZFN0YXJ0RWxlbWVudC5qYXZhCi0gUmVzdWx0VHJlZUhhbmRsZXIuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YQotIFRyZWVXYWxrZXIyUmVzdWx0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9NzQxLgotCi0gMSkgUmVzdWx0VHJlZUhhbmRsZXIgbm93IGltcGxlbWVudHMgdGhlIFRyYW5zZm9ybVN0YXRlIGludGVyZmFjZS4KLSAyKSBRdWV1ZWQgc3RhdGUgc3VjaCBhcyB0aGUgY3VycmVudCBub2RlIGFuZCB0aGUgY3VycmVudCB0ZW1wbGF0ZSBpcyBzdG9yZWQgCi1hcyBwYXJ0IG9mIFF1ZXVlZFN0YXJ0RWxlbWVudC4gU3RvcmFnZSB3aWxsIG9ubHkgb2NjdXIgaWYgdGhlIENvbnRlbnRIYW5kbGVyIAotaW1wbGVtZW50cyBUcmFuc2Zvcm1DbGllbnQuCi0gMykgV2hlbiBzdGF0ZSBpcyByZXF1ZXN0ZWQgKGZvciBpbnN0YW5jZSBUcmFuc2Zvcm1TdGF0ZSNnZXRDdXJyZW50RWxlbWVudCgpKSwgCi1pZiB0aGUgcXVldWVkIGVsZW1lbnQgaXMgbnVsbCBvciBub3QgcGVuZGluZyAoZm9yIGluc3RhbmNlLCBpbiBhIGNoYXJhY3RlcnMgCi1ldmVudCksIGl0IHdpbGwgZ2V0IHRoZSBzdGF0ZSBmcm9tIHRoZSB0cmFuc2Zvcm1lciwgb3RoZXJ3aXNlIGl0IHdpbGwgZ2V0IHRoZSAKLXN0YXRlIGZyb20gdGhlIHF1ZXVlZCBlbGVtZW50LgotCi0gT3RoZXIgZml4ZXMgd2VyZSBhdHRlbXB0ZWQgZm9yIHRoaXMgcHJvYmxlbSwgaW5jbHVkaW5nIHRyeWluZyB0bwotIGdldCByaWQgb2YgcXVldWVpbmcgYWx0b2dldGhlciwgYW5kIGZsdXNoaW5nIGEgYml0IGVhcmxpZXIgYmVmb3JlCi0gdGhlIHN0YXRlIHdhcyBwdXNoZWQgb24gdGhlIHZhcmlvdXMgc3RhY2tzLCBidXQgYm90aCBvZgotIHRoZXNlIGhhZCBzaG93LXN0b3BwaW5nIGlzc3VlcyAoc2VlIGRpc2N1c3Npb25zCi0gb24geGFsYW4tZGV2KS4KLQotIE5vdGUgdGhhdCBmb3IgdGhlIG1vbWVudCB0aGUgQ29udGV4dE5vZGVMaXN0IGlzIG5vZGUKLSBjbG9uZWQgYXMgaXQgbmVlZHMgdG8gYmUgaW4gb3JkZXIgZm9yCi0gVHJhbnNmb3JtU3RhdGUjZ2V0Q29udGV4dE5vZGVMaXN0Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRWxlbVBhcmFtLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIEFyZy5qYXZhIFZhcmlhYmxlU3RhY2suamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlRoZSBmaWVsZCBBcmcuaXNQYXJhbVZhciB3YXMgYXR0ZW1wdGluZyB0byBzZXJ2ZSB0d28gZnVuY3Rpb25zOiB0byBpbmRpY2F0ZSAKLXZhcmlhYmxlIEZyYW1lIGVudHJpZXMgd2hpY2ggYXJlIG5vdCBjdXJyZW50bHkgYWN0aXZhdGVkIGFuZCB0byBpbmRpY2F0ZSBGcmFtZXMgCi1jb250YWluaW5nIHBhcmFtZXRlcnMgcGFzc2VkIHdpdGggeHNsOndpdGgtcGFyYW0uIFdoZW4gcHJvY2Vzc2luZyB3YXMgZmluaXNoZWQgCi1mb3IgYSBub2RlIGluIGEgbm9kZS1zZXQsIHRoZSBpc1BhcmFtVmFyIGZsYWcgd2FzIHR1cm5lZCBvbiB0byBpbmRpY2F0ZSB0aGUgCi1GcmFtZSBzbG90IHdhcyBhdmFpbGFibGUuIFVuZm9ydHVuYXRlbHksIHRoaXMgYWxzbyBpbmRpY2F0ZWQgdGhhdCB0aGUgaXRlbSB3YXMgCi1wYXNzZWQgYXMgYSBwYXJhbWV0ZXIgd2hpY2ggaXQgd2Fzbid0LiBUaGlzIGZpeCBjaGFuZ2VzIGlzUGFyYW1WYXIgaW50byB0byAKLWZpZWxkcywgaXNBdmFpbGFibGUgd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhlIHNsb3QgaXMgYXZhaWxhYmxlIGFuZCAKLWlzRnJvbVdpdGhQYXJhbSBpbmRpY2F0aW5nIHRoZSBGcmFtZSBzbG90IGNhbWUgZnJvbSBhbiB4c2w6d2l0aC1wYXJhbSBvciBhIAotdG9wLWxldmVsIHBhcmFtZXRlciBwYXNzZWQgaW4gdmlhIHRoZSB0cmFuZm9ybWVySW1wbC5zZXRQYXJhbWV0ZXIoKSBBUEkuCi0gSSBoYXZlIHRlc3RlZCB0aGlzIGNoYW5nZSBhZ2FpbnN0IHRoZSBjb25mb3JtYW5jZSBzdWl0ZSBhbmQgaGFkIG5vIAotcmVncmVzc2lvbi4gSSd2ZSBhbHNvIHN1Ym1pdHRlZCBhIHRlc3QgY2FzZSB3aGljaCBmYWlscyBvbiB0aGUgZXhpc3RpbmcgCi1jb2RlYmFzZSBidXQgd29ya3Mgb2theSBhZnRlciB0aGlzIGZpeC4KLSBJdCBpcyBwb3NzaWJsZSB0aGF0IEkndmUgbWlzc2VkIHNvbWV0aGluZyB3aXRoIHJlZ2FyZCB0byB0aGUgQVBJIHNldFBhcmFtZXRlciAKLWNhbGxzIGJ1dCB3ZSBjYW4gZml4IHRob3NlIGlmIHByb2JsZW1zIGFyZSByZXBvcnRlZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIEZhc3RTdHJpbmdCdWZmZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNvcnJlY3Qgb3BlcmF0aW9uIHdoZW4gbGVuZ3RoIG9mIGNvbnRlbnQgdG8gYmUgYXBwZW5kZWQgaXMgemVyby48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplIFNlcmlhbGl6ZXJUb1hNTC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGNsb3Npbmcgb3V0IGRvY3R5cGUgZGVjbGFyYXRpb248YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzA4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveG1sL3V0aWxzIFN5c3RlbUlEUmVzb2x2ZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNoYW5nZSBTeXN0ZW1JZFJlc29sdmVyIHRvIGRlZmF1bHQgdG8gdXNlci5kaXIgaWYgdGhlIGJhc2UgVVJJIGlzIG51bGw8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Z2FyeXBAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzA5LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIFZhcmlhYmxlU3RhY2suamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlBhcmFtZXRlcnMgc2V0IHdpdGggc2V0UGFyYW1ldGVyIHdlcmUgYXZhaWxhYmxlIHRvIHN0eWxlc2hlZXQgYXMgdmFyaWFibGUgCi1yZWZlcmVuY2VzICgkbXlQYXJhbSkgZXZlbiB0aG91Z2ggdGhlcmUgd2FzIG5vIHhzbDpwYXJhbSBlbGVtZW50IHRvIHJlY2VpdmUgaXQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8wOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyCi0gVHJhbnNmb3JtZXJJZGVudGl0eUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNoZWNrIGlmIHRoZXJlIGlzIGEgRGVjbEhhbmRsZXIgYmVmb3JlIGNhbGxpbmcgaXQuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBXcmFwcGVkUnVudGltZUV4Y2VwdGlvbi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UGF0Y2ggYXR0cmlidXRlZCB0byBQYXRyaWNrIE1vb3JlICZsdDtwYXRyaWNrbUByaW9wb3J0LmNvbSZndDsgb24gMDMvMDkvMjAwMS4KLSBBZGRzIGFub3RoZXIgY29uc3RydWN0b3IgdG8gcGFzcyBpbiB0aGUgZXJyb3IgbWVzc2FnZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzIEVsZW1BdHRyaWJ1dGUuamF2YQotIEVsZW1FbGVtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DaGVja2luIGFkZHJlc3NlcyBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTkyMy4KLSBlbGVtQXR0cmlidXRlIG5vdyBkZXJpdmVzIGZyb20gZWxlbUVsZW1lbnQgc28gdGhlIGJhc2ljIG5hbWUgcmVzb2x1dGlvbgotIGNvZGUgY2FuIGJlIHNoYXJlZC4gQnJlYWtzIGF0dHJpYnNldDI0IHRlc3QsIGJ1dCBJIHRoaW5rIHRoZSBuZXdlcgotIGJlaGF2aW9yIGlzIGJldHRlci4gTmV3IHZpcnR1YWwgbWV0aG9kcyBvdmVybG9hZGVkIGJ5IGVsZW1BdHRyaWJ1dGUgYXJlCi0gY29uc3RydWN0Tm9kZSwgcmVzb2x2ZVByZWZpeCwgYW5kIHZhbGlkYXRlTm9kZU5hbWUuIEFsc28sIGluIHRoZQotIGVsZW1BdHRyaWJ1dGUjZXhlY3V0ZSBtZXRob2QsIGNoZWNrcyBhcmUgbWFkZSB0byBtYWtlIHN1cmUgYW4KLSBlbGVtZW50IGlzIHBlbmRpbmcuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3htbC91dGlscyBTeXN0ZW1JRFJlc29sdmVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBnZXRBYnNvbHV0ZVVSSShTdHJpbmcgdXJsKSwgYW5kIG1lcmdlCi0gd2l0aCBNeXJpYW0ncyBjaGFuZ2VzLgotIFBhcnQgb2YgZml4IGZvciBwcm9ibGVtIGZvdW5kIHdoZW4KLSBpbnZlc3RpZ2F0aW5nIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9OTA2Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5DYWxsIGdldEFic29sdXRlVVJJKFN0cmluZyB1cmwpIGZvciB0aGUgc291cmNlIFVSTC4KLSBGaXggZm9yIHByb2JsZW0gZm91bmQgd2hlbgotIGludmVzdGlnYXRpbmcgaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD05MDYuCi0gVGhpcyB0cmllcyB0byBmb3JjZSB1cyBhbHdheXMgaGF2aW5nIGFuIGFic29sdXRlIFVSTCBpbiB0aGUgcHJvY2Vzc2luZwotIHN0YWNrIGFzIHRoZSBiYXNlIFVSTCwgd2hpY2ggc2hvdWxkIGJlIE9LLCBJIGhvcGUuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3RyYW5zZm9ybWVyIFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2FsbCBnZXRBYnNvbHV0ZVVSSShTdHJpbmcgdXJsKSBmb3IgdGhlIHNvdXJjZSBVUkwuCi0gRml4IGZvciBwcm9ibGVtIGZvdW5kIHdoZW4KLSBpbnZlc3RpZ2F0aW5nIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9OTA2LgotIFRoaXMgdHJpZXMgdG8gZm9yY2UgdXMgYWx3YXlzIGhhdmluZyBhbiBhYnNvbHV0ZSBVUkwgaW4gdGhlIHByb2Nlc3NpbmcKLSBzdGFjayBhcyB0aGUgYmFzZSBVUkwsIHdoaWNoIHNob3VsZCBiZSBPSywgSSBob3BlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBRdWV1ZWRFdmVudHMuamF2YQotIFF1ZXVlZFN0YXJ0RWxlbWVudC5qYXZhIFJlc3VsdFRyZWVIYW5kbGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5UaGUgdXNlciBmb3IgaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD03NDEgcmVwb3J0ZWQKLSBwcm9ibGVtcyBvbiB0ZXN0aW5nLCBzbyB0aGVzZSBjaGFuZ2VzIGFyZSBhIHJlLWZpeC4gSGUgdGVzdGVkIGFuZAotIGV2ZXJ5dGhpbmcgc2VlbXMgT0sgbm93LiBUaGVyZSBhY3R1YWxseSBtYXkgYmUgYSBzbGlnaHQgcGVyZm9ybWFuY2UKLSBpbXByb3ZlbWVudCBpbnZvbHZlZCBoZXJlLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zZXJpYWxpemUgU2VyaWFsaXplclRvSFRNTC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QXBwbGllZCBwYXRjaGVzIGZyb20gZG1pdHJpLmlseWluQG1lbWlxLmNvbSAoRG1pdHJpIElseWluKQotIGZyb20gaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD03MDUuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hwYXRoIFhQYXRoQVBJLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BcHBsaWVkIHBhdGNoIHN1Ym1pdHRlZCBieSBuYm95ZEBhdGcuY29tIChOb3JyaXMgQm95ZCkKLSBhdCBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTcwMi48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplIEVuY29kaW5ncy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QXBwbGllZCBwYXRjaCBzdWJtaXR0ZWQgYnkgaGF2YXJkd0B1bmRlcmR1c2tlbi5ubyAoSOW2oXJkIFdpZ3RpbCkuCi0gQWxzbyBhZGRlZCAiWFhYLVgiIHZhcmlhbnRzIGZvciBhbGwgIlhYWF9YIiBqYXZhIGVuY29kaW5nIG5hbWVzLgotIEknbSBub3QgdG90YWxseSBjb25maWRlbnQgdGhhdCB0aGlzIGlzIHRoZSByaWdodCB0aGluZyB0byBkbywgYnV0IEkgY2FuJ3QKLSBzZWUgdGhhdCBpdCB3aWxsIGh1cnQsIGV4Y2VwdCB0byBtYWtlIHRoZSB0YWJsZSBhIGJpdCBsYXJnZXIuIEkKLSB3b3VsZCBwcmVmZXIgdG8gYmUgc2FmZSBhbmQgbWFrZSBzdXJlIHdlIGhhbmRsZSB0aGUgZW5jb2RpbmcuCi0gU2VlIG15IGNvbW1lbnRzIGluIGh0dHA6Ly9uYWdveWEuYXBhY2hlLm9yZy9idWd6aWxsYS9zaG93X2J1Zy5jZ2k/aWQ9NzE4Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRWxlbVRlbXBsYXRlRWxlbWVudC5qYXZhCi0gU3R5bGVzaGVldFJvb3QuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1pbm9yIGNoYW5nZXMgdG8gYmV0dGVyIGJvdHRsZW5lY2sgdGhyb3dpbmcgb2YgUnVudGltZSBleGNlcHRpb25zCi0gZHVyaW5nIHByb2Nlc3NpbmcuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnNib2FnQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3Byb2Nlc3NvcgotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNhdGNoIGFsbCBleGNlcHRpb25zIHRocm93biB3aGVuIHByb2Nlc3Npbmcgc3R5bGVzaGVldCwgYW5kIHNlbmQKLSB0aGVtIHRvIHRoZSBlcnJvciBsaXN0ZW5lci4gVGhlcmUncyBwcm9iYWJseSBzb21lIGRhbmdlciBvZiBoYXZpbmcKLSB0aGUgc2FtZSBlcnJvciBzZW50IHRvIHRoZSBlcnJvciBsaXN0ZW5lciBtdWx0aXBsZSB0aW1lcywgYnV0IGJldHRlciB0b28KLSBtYW55IHJlcG9ydHMsIHRoYW4gbm9uZSwgSSBndWVzcy4KLSBUaGlzIGFkZHJlc3NlcyBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTkwNi48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBYQ29ubmVjdGlvbi5qYXZhCi0gWFN0YXRlbWVudC5qYXZhPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL2xpYi9zcWwgQ29ubmVjdGlvblBvb2wuamF2YQotIERlZmF1bHRDb25uZWN0aW9uUG9vbC5qYXZhIEV4dGVuc2lvbkVycm9yLmphdmEKLSBQb29sZWRDb25uZWN0aW9uLmphdmEgUXVlcnlQYXJhbWV0ZXIuamF2YQotIFNRTEV4dGVuc2lvbkVycm9yLmphdmEgWENvbm5lY3Rpb25Qb29sTWFuYWdlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VGhlc2UgYXJlIEpvaG4gR2VudGlsaW4gJmx0O2pvaG5nbGludXhAZXllY2F0Y2hpbmcuY29tJmd0OwotIHBhdGNoZXMgZm9yIGNvbm5lY3Rpb24gcG9vbGluZyBhbmQgcGFyYW1ldGVyaXplZAotIHF1ZXJpZXMuIFRoZXNlIHNob3VsZCBiZSBjb25zaWRlcmVkIHRvIGJlIHVuc3RhYmxlCi0gcmlnaHQgbm93LCBhcyB3ZSBhcmUgc3RpbGwgd29ya2luZyBvbiBzb21lIHRoaW5ncy48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yIFByb2Nlc3NvckluY2x1ZGUuamF2YQotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplIFNlcmlhbGl6ZXJUb1hNTC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9zdHJlZSBTdHJlZURPTUhlbHBlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90cmFuc2Zvcm1lciBSZXN1bHRUcmVlSGFuZGxlci5qYXZhCi0gVHJhbnNmb3JtZXJJZGVudGl0eUltcGwuamF2YSBUcmVlV2Fsa2VyMlJlc3VsdC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgQXR0TGlzdC5qYXZhIFRyZWVXYWxrZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggRE9NMkhlbHBlci5qYXZhIFhQYXRoQ29udGV4dC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VGhlIERPTTJIZWxwZXIjaXNOb2RlQWZ0ZXIoTm9kZSBub2RlMSwgTm9kZSBub2RlMikgbWV0aG9kCi0gaGFzIGJlZW4gZml4ZWQgc28gdGhhdCBpdCBubyBsb25nZXIgZG9lcyB0aGUgdHJ5L2NhdGNoIHRoaW5nIGlmIG9uZQotIG9mIHRoZSBub2RlcyBkb2Vzbid0IGltcGxlbWVudCBET01PcmRlciwgYnV0IGluc3RlYWQgZG9lcyBhbgotIGluc3RhbmNlb2YgdGVzdC4gSW4gU3RyZWVET01IZWxwZXIsIGl0IG92ZXJsb2FkcyB0aGlzIG1ldGhvZCBhbmQKLSAqZG9lcyogZG8gdGhlIHRyeS9jYXRjaCBidXNpbmVzcywgc2luY2UgYWxtb3N0IGFsd2F5cyBib3RoIG5vZGVzCi0gd2lsbCBpbXBsZW1lbnQgRE9NT3JkZXIgaW4gdGhpcyBjYXNlLCBhbmQgdGhpcyB3aWxsIGJlIGZhc3RlciB0aGFuCi0gYW4gaW5zdGFuY2VvZiB0ZXN0LiBBbHNvLCBpbiB2YXJpb3VzIGNsYXNzZXMsIEkgZGlkIHNvbWUgc3R1ZmYgdG8gdHJ5Ci0gYW5kIG1ha2Ugc3VyZSB0aGF0IGEgRE9NMkhlbHBlciB3YXNuJ3QgYmVpbmcgY3JlYXRlZCBhbmQgdXNlZAotIHdoZW4gYSBTdHJlZURPTUhlbHBlciBpcyBuZWVkZWQuCi0KLSBUaGlzIGFkZHJlc3NlcyBodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPTgwMAotIGFuZCBzaG91bGQgZ2l2ZSBhIGdvb2QgcGVyZm9ybWFuY2UgZml4IGZvciBmb3JlaWduIERPTSBwcm9jZXNzaW5nLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94cGF0aC9wYXR0ZXJucyBOb2RlVGVzdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+WGVyY2VzIGF0IHNvbWUgcG9pbnQgZGVjaWRlZCB0byB1c2UgIiIgaW5zdGVhZAotIG9mIG51bGwgZm9yIG51bGwgbmFtZXNwYWNlcy4gVGhlcmUgaGFzIGJlZW4gYQotIGRpc2N1c3Npb24gYmV0d2VlbiBHYXJ5IFBlc2tpbiBpbgotIEpvZSBLZXNzbGVtYW4gb24geGFsYW4tZGV2IGFib3V0IHRoaXMsCi0gYnV0IEkgaGFkbid0IGJlZW4gZnVsbHkga2VlcGluZyB1cCB0aGUgdGhlCi0gdGhyZWFkIHRoYXQgd2VsbCwgYW5kIG1pc3NlZCBpdCdzIHJlbGF0aW9uIHRvCi0gdGhpcyBwcm9ibGVtLiBJIGluY2x1ZGUgc29tZSBvZiB0aGUgZGlzY3Vzc2lvbgotIGF0IHRoZSBlbmQgb2YgdGhpcyBub3RlLiBJIG1hZGUgWGFsYW4gYmUgYWJsZSB0bwotIGNvbXBhcmUgYSAiIiBuYW1lc3BhY2UgdG8gbnVsbCBmb3Igbm93LCB1bnRpbAotIHdlIGdldCB0aGlzIHJlc29sdmVkLgotCi0gVGhlIGdpc3Qgb2YgdGhlIGRpc2N1c3Npb24gb24geGFsYW4tZGV2IHJlZ2FyZGluZyB0aGlzIGlzOgotCi0gJmd0OyZndDsxLiBEZWNsYXJlIHRoZSBYZXJjZXMtSiBzdXBwb3J0IG9mIHNjaGVtYXMgdG8gaGF2ZSBhIGJ1ZyBhbmQgYXNrIHRoYXQKLSAmZ3Q7Jmd0O1hlcmNlcyBiZSBjb3JyZWN0ZWQgdG8gYWx3YXlzIHVzZSBhIG51bGwgbmFtZXNwYWNlIFVSSSB0byBpbmRpY2F0ZSB0aGF0Ci0gJmd0OyZndDt0aGVyZSBpcyBubyBkZWZhdWx0IG5hbWVzcGFjZS4gRXZlbiBpZiB0aGUgWGVyY2VzIHBlb3BsZSBjaGFuZ2UgdGhpcwotICZndDsmZ3Q7YmVoYXZpb3IsIGlzIHRoaXMgY29ycmVjdD8KLSAmZ3Q7Ci0gJmd0OyBZZXMuIElmIHlvdXIgZGVzY3JpcHRpb24gb2YgdGhlIHByb2JsZW0gaXMgYWNjdXJhdGUgKHlvdSBzaG91bGQgcHJvYmFibHkKLSAmZ3Q7IHN1Ym1pdCBhIG1vcmUgZGV0YWlsZWQgY2FzZSBzbyBpdCBjYW4gYmUgcmVwcm9kdWNlZCBpbiB0aGUgbGFiKSwgdGhpcyBpcyBhCi0gJmd0OyBwYXJzZXIvRE9NLWJ1aWxkZXIgYnVnLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jb3N0aW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vbGliL3NxbCBFeHRlbnNpb25FcnJvci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtb3ZlZCAoIGNvbW1lbnRlZCBvdXQgKSBkdW1wKCkgbWV0aG9kIGFuZCB0aGUgaW1wb3J0cyBpbiBFeHRlbnNpb25FcnJvci4KLQotIFNvIGZhciB0aGUgbWV0aG9kIGRvZXNuJ3Qgc2VlbSB0byBiZSB1c2VkICggbm8gd2FybmluZyBpbiB0aGUgY29tcGlsZSApLgotCi0gVGhlIHByb2JsZW0gaXMgdGhhdCB0aGlzIG1ldGhvZCBpcyBicmVha2luZyB0aGUgYnVpbGQgd2l0aCBjcmltc29uICggc2luY2UKLSBpdCB1c2VzIHhlcmNlcy1zcGVjaWZpYyBjbGFzc2VzICkuIEl0IGlzIHBvc3NpYmxlIHRvIGltcGxlbWVudCBpdCBvbiB0b3AKLSBvZiB0aGUgc2VyaWFsaXphdGlvbiBjbGFzc2VzIHRoYXQgYXJlIHBhcnQgb2YgeGFsYW4gLSBpZiBzb21lb25lIG5lZWRzIHRoZQotIG1ldGhvZCBJJ2xsIHRyeSB0byBwb3J0IGl0Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgVHJlZVdhbGtlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgYmFjayBpbiB0aGUgVHJlZVdhbGtlcihDb250ZW50SGFuZGxlciBjb250ZW50SGFuZGxlcikKLSBjb25zdHJ1Y3RvciwgYmVjYXVzZSBJJ20gd29ycmllZCBJJ2xsIGJyZWFrIG1vcmUgZGVwZW5kZW50IGNvZGUuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3JlcyBYU0xURXJyb3JSZXNvdXJjZXMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBQcm9jZXNzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5JbXBsZW1lbnQgbmV3IGFyZ3VtZW50cyBmb3IgdGhlIGNvbW1hbmQgbGluZSBpbnRlcmZhY2U6IFVSSVJlc29sdmVyLCAKLUVudGl0eVJlc29sdmVyIGFuZCBDb250ZW50SGFuZGxlcjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi90ZW1wbGF0ZXMgRnVuY0Zvcm1hdE51bWIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBlcnJvciBtZXNzYWdlIHRvIHNheSB0aGF0IDIgb3IgMyBhcmd1bWVudHMgYXJlIHJlcXVpcmVkLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9wcm9jZXNzb3IgUHJvY2Vzc29yTFJFLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3JlcyBYU0xURXJyb3JSZXNvdXJjZXMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkJldHRlciBlcnJvciBtZXNzYWdlIGZvciBtaXNzaW5nIG9yIGluY29ycmVjdCBYU0xUIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiBhIAotc3R5bGVzaGVldDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5nYXJ5cEBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIgUmVkaXJlY3QuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4vdHJhbnNmb3JtZXIgVHJhbnNmb3JtZXJJbXBsLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtZW1iZXIgdGhlIFJlc3VsdCB0aGF0IHdhcyB1c2VkIHRvIHRyaWdnZXIgdGhlIHRyYW5zZm9ybS4gQWNjZXNzIHRoYXQgCi1yZXN1bHQgZnJvbSB0aGUgUmVkaXJlY3QgZXh0ZW5zaW9uIHRvIG1ha2UgZmlsZSByZWZlcmVuY2VzIGluIFJlZGlyZWN0IHJlbGF0aXZlIAotdG8gdGhlIG9yaWdpbmFsIHJlc3VsdCBVUkkuCi0gSWYgdGhpcyBpcyBub3QgYXZhaWxhYmxlLCByZWZlcmVuY2VzIGFyZSByZWxhdGl2ZSB0byB0aGUgc291cmNlIFVSSS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzE0LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveHBhdGggVmFyaWFibGVTdGFjay5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgcHJvdGVjdGlvbiBmb3IgbnVsbCBwb2ludGVyIGV4Y2VwdGlvbiB0aGF0IEkgZGlzY292ZXJlZCB3aGVuCi0gcnVubmluZyBzb21lIENvY29vbiB0ZXN0cy4gU2luY2UgSSd2ZSBuZXZlciBzZWVuIHRoaXMgYmVmb3JlLAotIEkgYXNzdW1lIHRoaXMgaXMgcmVsYXRlZCB0byB0aGUgY2hhbmdlcyB0aGF0IEdhcnkgbWFkZSwgYnV0IGFtCi0gdW5zdXJlIGFzIGl0J3MgNDowMCBpbiB0aGUgbW9ybmluZyBhbmQgSSdtIHRvbyB0aXJlZCB0byBsb29rIGludG8gaXQgZGVlcGx5Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5jdXJjdXJ1QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtb3ZlIGNoZWNrIGZvciBtaXNzaW5nIC1JTiBhcmc7IHRoZXJlIGFyZSBhIG51bWJlciBvZiB1c2UKLSBjYXNlcyBmb3IgY2FsbGluZyBQcm9jZXNzLm1haW4gd2l0aG91dCBhbiBYTUwgZG9jdW1lbnQ8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+Y29zdGluQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMy8xNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgUHJvY2Vzcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSAobGFzdCA/ICkgcGxhY2Ugd2hlcmUgWE1MUmVhZGVyRmFjdG9yeSB3YXMgdXNlZCB3aXRob3V0Ci0gdHJ5aW5nIGpheHAgZmlyc3QuIEkgdXNlZCB0aGUgc2FtZSBjb2RlIHRoYXQgaXMgdXNlZCBpbiBhbGwgb3RoZXIKLSBwbGFjZXMgaW4geGFsYW4uCi0KLSBXaXRoIHRoaXMgY2hhbmdlLCB0aGUgcGFyc2VyIGRlZmluZWQgaW4gWFNMVEluZm8ucHJvcGVydGllcyB3aWxsIGJlIHVzZWQKLSBvbmx5IGlmIGpheHAgaXMgbm90IGF2YWlsYWJsZS48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+ZGxlc2xpZUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94bWwvdXRpbHMgU3RyaW5nVmVjdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBtaXNzaW5nIEBzZXJpYWwgSmF2YWRvYyB0YWdzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5zYm9hZ0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDMvMTUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi9saWIvc3FsIENvbm5lY3Rpb25Qb29sLmphdmEKLSAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRDb25uZWN0aW9uUG9vbC5qYXZhIEV4dGVuc2lvbkVycm9yLmphdmEKLSAgICAgICAgICAgICAgICAgICAgICAgIFNRTEV4dGVuc2lvbkVycm9yLmphdmEgWENvbm5lY3Rpb24uamF2YQotICAgICAgICAgICAgICAgICAgICAgICAgWENvbm5lY3Rpb25Qb29sTWFuYWdlci5qYXZhIFhTdGF0ZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlVwZGF0ZSBmcm9tIEpvaG4gR2VudGlsaW4gJmx0O2pvaG5nbGludXhAZXllY2F0Y2hpbmcuY29tJmd0OyB0bwotICBmaXggY29ubmVjdGlvbiBjbGVhbnVwLjxici8+PGJyLz48L2xpPjwvdWw+PHA+Q29tcGF0aWJpbGl0eSBzb3VyY2UgY29kZSB1cGRhdGVzOjwvcD48dWw+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8wMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IFhTTFRJbnB1dFNvdXJjZS5qYXZhCi0gWFNMVFJlc3VsdFRhcmdldC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW1wbGVtZW50IHNvbWUgbW9yZSBtZXRob2RzIGZvciBjb21wYXRpYmlsaXR5PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzAyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgWFNMVElucHV0U291cmNlLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXhlZCBqYXZhZG9jIGZvciBhcGkgdGhhdCB3YXMganVzdCBhZGRlZCBiYWNrLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5kbGVzbGllQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8wMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IFhTTFRSZXN1bHRUYXJnZXQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeGVkIGphdmFkb2MgZm9yIGFwaSB0aGF0IHdhcyBqdXN0IGFkZGVkIGJhY2suPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8wMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IFhTTFRFbmdpbmVJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggcHJvYmxlbSB3aXRoIGNhbGxpbmcgdGhlIHByb2Nlc3NvciB3aXRoIGEgbGlhaXNvbjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMDIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBYU0xURW5naW5lSW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IHByb2JsZW0gd2hlcmUgc291cmNlIGZpbGUgd2FzIGJlaW5nIHBhcnNlZCBtb3JlIHRoYW4gb25jZSBhbmQgaWYgdXNpbmcgYW4gCi1pbnB1dCBzdHJlYW0sIHdlIHdvdWxkIGdldCBhIHJlYWQgZXJyb3I8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgWFNMVEVuZ2luZUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlNldCBzeXN0ZW0gaWQgaW4gc3R5bGVzaGVldCBoYW5kbGVyPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1taWR5QGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wMi8xNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IFhTTFRJbnB1dFNvdXJjZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Q2FsbCBsb2NhbCBzZXRTeXN0ZW1JZC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW1pZHlAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAyLzE1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHQgWFNMVEVuZ2luZUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBwcm9ibGVtIHdpdGggcHJvY2Vzc2luZyBhbiBpbnB1dCBzb3VyY2UgY3JlYXRlZCBmcm9tIGEgcmVhZGVyIHdpdGggbm8gCi1zeXN0ZW1JZAotIEZpeCBwcm9ibGVtIHdpdGggcmVhZGluZyBhbiBpbnB1dCBzb3VyY2UgZmlsZSB0d2ljZSBpZiBpdCBoYXMgYSBQSTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tbWlkeUBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDIvMjIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9jb21wYXRfc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdCBTdHlsZXNoZWV0Um9vdC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkIGdldE91dHB1dE1ldGhvZCBBUEkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmRsZXNsaWVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbAotIFhNTFBhcnNlckxpYWlzb25EZWZhdWx0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5QdXQgaW4gQXBhY2hlIGNvcHlyaWdodC48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+c2JvYWdAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjAzLzEzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvY29tcGF0X3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hwYXRoL3htbCBUcmVlV2Fsa2VyLmphdmEKLSBqYXZhL2NvbXBhdF9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0IFhTTFRFbmdpbmVJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5NYWRlIGNoYW5nZXMgZm9yIGNoYW5nZSB0byBBUEkgZm9yIFhhbGFuSjIgVHJlZVdhbGtlciwgd2hpY2gKLSBub3cgcmVxdWlyZXMgdGhhdCB0aGUgRE9NIGhlbHBlciBiZSBjcmVhdGVkIGJ5IHRoZSBjYWxsZXIuPC9saT4KLSA8L3VsPgotPC9zMz4KLQotPHMzIHRpdGxlPSJDaGFuZ2VzIGZvciAmeHNsdDRqOyB2ZXJzaW9uIDIuMC4wIj4KLTxwPlJlbGVhc2UgMi4wIGluY2x1ZGVzIHNldmVyYWwgYnVnIGZpeGVzIHRvIHRoZSAmeHNsdDRqOyBhbmQgVHJBWCBjb3JlIGFuZCB0byB0aGUgWGFsYW4tSmF2YSAxIGNvbXBhdGliaWxpdHkgQVBJLiBXZSBhbHNvIHVwZGF0ZWQgYnNmLmphciB0byB0aGUgPHJlc291cmNlLXJlZiBpZHJlZj0iYnNmIi8+IHJlbGVhc2UgY2FuZGlkYXRlIDIuMiwgd2hpY2ggZml4ZXMgYSBidWcgcnVubmluZyBKUHl0aG9uIGV4dGVuc2lvbnMuPC9wPgotPHA+PGVtPkNvcmUgYnVnIGZpeGVzOjwvZW0+PC9wPgotPHVsPgotICA8bGk+QSB0aHJlYWRpbmcgcHJvYmxlbSBzaG93ZWQgdXAgd2hlbiB1c2luZyBtdWx0aXBsZSBwcm9jZXNzb3JzLiBXZSBmaXhlZCBpdCBieSB1c2luZyBhIHNlcGFyYXRlIFhQYXRoQ29udGV4dCBvYmplY3QgdG8gZG8gd2hpdGVzcGFjZSBub2RlCi0gICBtYXRjaGVzICh4c2w6c3RyaXAtc3BhY2UpLjxici8+PGJyLz48L2xpPgotICA8bGk+Rml4ZWQgYSBidWcgcnVubmluZyBOb3JtIFdhbHNoJ3MgRG9jQm9vayBzdHlsZXNoZWV0cyBieSBub3Qgc2V0dGluZyB0aGUgdmFyaWFibGUgc3RhY2sgcG9zaXRpb24gaWYgdGhlIEZpbHRlckV4cHJXYWxrZXIgaXMgbm90IG93bmVkIGJ5IGEKLSAgdG9wLWxldmVsIE5vZGVJdGVyYXRvci48YnIvPjxici8+PC9saT4KLSAgPGxpPkZpeGVkIGEgcHJvYmxlbSB3aXRoIG51bGwgbmFtZXNwYWNlIGJlaW5nIHBhc3NlZCBmcm9tIHhzbDplbGVtZW50LiBUaGlzIGJ1ZyBhbHNvIHN1cmZhY2VkIHdoaWxlIHByb2Nlc3NpbmcgRG9jQm9vawotICAgc3R5bGVzaGVldHMuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5JbiB0aGUgaW50ZXJlc3Qgb2Ygc3RhYmlsaXR5LCB3ZSBub3cgdHJlYXQgInVua25vd24gZXJyb3IgaW4gWFBhdGgiIGFzIGEgZmF0YWwgZXJyb3IuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5BZGRlZCBzdXBwb3J0IGluIHN0eWxlc2hlZXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgZm9yICJ0ZXh0L3htbCIgYW5kICJhcHBsaWNhdGlvbi94bWwreHNsdCIgbWltZSB0eXBlcy48YnIvPjxici8+PC9saT4KLSAgPGxpPkZpeGVkIHRva2VuaXppbmcgb2Ygc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyB0byBhbGxvdyBwYXJhbWV0ZXJzIHRvIGJlIHBhc3NlZCB0byBzZXJ2ZXIgaW4gaHJlZiBhdHRyaWJ1dGVzLjxici8+PGJyLz48L2xpPgotICA8bGk+Rml4ZWQgYSBidWcgcGFzc2luZyBUcmFuc2Zvcm1lciBjcmVhdGlvbiBlcnJvciBtZXNzYWdlcyB0byBFcnJvckxpc3RlbmVyIHdoZW4gYW4gRXJyb3JMaXN0ZW5lciBoYXMgYmVlbiBzZXQgb24KLSAgIFRyYW5zZm9ybWVyRmFjdG9yeS48YnIvPjxici8+PC9saT4KLSAgPGxpPldoZW4gdXNpbmcgYW4gRXhjZXB0aW9uIHRvIGluc3RhbnRpYXRlIGEgRmFjdG9yeUNvbmZpZ3VyYXRpb25FcnJvciAoZXh0ZW5kcyBFcnJvciksIHdlIG5vdyBwcm9wYWdhdGUgdGhlIEV4Y2VwdGlvbiBtZXNzYWdlIHRvIAotICBzdXBlcigpLjxici8+PGJyLz48L2xpPgotICA8bGk+QWRkZWQgZGVmZW5zaXZlIGNvZGUgdG8gRWxlbVRlbXBsYXRlRWxlbWVudCBmb3IgaGFuZGxpbmcgYSBudWxsIFVSSS48YnIvPjxici8+PC9saT4KLSAgPGxpPldoZW4gdXNpbmcgYW4gRXhjZXB0aW9uIHRvIGluc3RhbnRpYXRlIGEgVHJhbnNmb3JtZXJFeGNlcHRpb24gKGV4dGVuZHMgRXhjZXB0aW9uKSwgd2Ugbm93IHByb3BhZ2F0ZSB0aGUgRXhjZXB0aW9uIG1lc3NhZ2UgdG8gc3VwZXIoKSAKLSAgcmF0aGVyIHRoYW4gYSBnZW5lcmljIG1lc3NhZ2UuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5GaXhlZCBhIGJ1ZyAodGhlIGdlbmVyYXRpb24gb2YgYW4gdW53YW50ZWQgZW50aXR5IHJlZmVyZW5jZSkgcGVyZm9ybWluZyB0aGUgaWRlbnRpdHkgdHJhbnNmb3JtYXRpb24gCi0gIChzZWUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0ic2VyaWFsaXplIj5TZXJpYWxpemluZyBvdXRwdXQ8L2xpbms+KSB3aXRoIGFuIFhNTCBkb2N1bWVudCBjb250YWluaW5nIGEgRE9DVFlQRQotICAgZGVjbGFyYXRpb24uPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+TWVzc2FnZSBtYW5hZ2VyIG1vZGlmaWVkIHNvIHRoYXQgdGhlIFNvdXJjZUxvY2F0b3IgbXVzdCBhbHdheXMgYmUgcGFzc2VkIGluLAotICB3aGljaCB3aWxsIG1ha2UgYSBtYWpvciBkaWZmZXJlbmNlIGluIGdldHRpbmcgbGluZSBudW1iZXIgaW5mb3JtYXRpb24uPGJyLz48YnIvPjwvbGk+IAotICA8bGk+eHNsOmVsZW1lbnQncyBoYW5kbGluZyBvZiBuYW1lc3BhY2UgYXR0cmlidXRlIGFuZCBwcmVmaXggaW4KLSAgbmFtZSBhdHRyaWJ1dGUgY2hhbmdlZCBzbyB0aGF0IGl0IG5vIGxvbmdlciBtYW51ZmFjdHVyZXMgcHJlZml4ZXMuLi4KLSAgaXQgYWx3YXlzIHRyaWVzIGl0cyBiZXN0IHRvIG1hdGNoIHRoZSBwcmVmaXggZW50ZXJlZC48YnIvPjxici8+PC9saT4gIAotICA8bGk+QnVnIGZpeGVkIHdpdGggbmFtZXNwYWNlIGNvbnRleHRzIGluIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3Nvci4KLSAgVGhlIGJ1ZyBjb3VsZCBjYXVzZSAmbHQ7YSB4bWxuczphPSJ4IiZndDsmbHQ7YiZndDsgdG8gcHJvZHVjZSAmbHQ7YSB4bWxuczphPSJ4IiZndDsmbHQ7YiB4bWxuczphPSJ4IiZndDsuPGJyLz48YnIvPjwvbGk+ICAKLSAgPGxpPk1vZGlmaWVkIHByb2Nlc3Npbmcgb2YgeHNsOm1lc3NhZ2UgdG8gZW5oYW5jZSBpdCBhcyBhIGRlYnVnZ2luZyBhaWQuIExpbmUgbnVtYmVycyBhcmUgbm93IG91dHB1dCB3aXRoIGVhY2gKLSAgbWVzc2FnZS4gSWYgdGhlIHRlcm1pbmF0ZSBhdHRyaWJ1dGUgaXMgdHJ1ZSAodGhlIGRlZmF1bHQgaXMgZmFsc2UpIHRoZSBtZXNzYWdlIGlzIHNlbnQgdG8gdGhlIGNvbnNvbGUsIGFuZCBhbiBleGNlcHRpb24gaXMgdGhyb3duIHdpdGggdGhlCi0gIG1lc3NhZ2UgIlN0eWxlc2hlZXQgZGlyZWN0ZWQgdGVybWluYXRpb24iLjxici8+PGJyLz48L2xpPgotICA8bGk+SW4gVHJhbnNmb3JtZXJFeGNlcHRpb24sIGNoZWNrIHRoYXQgdGhlIGNhdXNlICE9IG51bGwgd2hlbiBjaGVja2luZyBmb3IgYSBjb250YWluZWQgZXhjZXB0aW9uLjxici8+PGJyLz48L2xpPgotICA8bGk+Rml4ZWQgYSBwcm9ibGVtIHZhbGlkYXRpbmcgbm9uLW5hbWVzcGFjZWQgYXR0cmlidXRlcyBhbmQgYSBwcm9ibGVtIGFsbG93aW5nIG5vbi1uYW1lc3BhY2VkIGF0dHJpYnV0ZXMgdG8gYmUgY2hpbGRyZW4gb2YgdGhlCi0gICBzdHlsZXNoZWV0IGVsZW1lbnQuPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rml4ZWQgY2hlY2tpbmcgb2YgbnVtYmVyIG9mIGFyZ3VtZW50cyBpbiBkb2N1bWVudCgpIGZ1bmN0aW9uLjxici8+PGJyLz48L2xpPgotICAgPGxpPkZpeGVkIHByb2JsZW0gd2l0aCBtdXRhdGlvbiBvZiB0ZW1wbGF0ZXMgYXQgcnVuIHRpbWUuIFRlbXBsYXRlcyByZXNvbHV0aW9uIG5vdyB0YWtlcyBwbGFjZSBkdXJpbmcgdGhlIGNvbXBvc2UoKSBtZXRob2QuPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rml4ZWQgc29tZSBtaW5vciB0aHJlYWRpbmcgaXNzdWVzIGluIG9yZy5hcGFjaGUueGFsYW4uc3RyZWUgKENoaWxkLCBQYXJlbnQsIEVsZW1lbnRJbXBsLCBTb3VyY2VUcmVlSGFuZGxlcikuPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+U3luY2hyb25pemVkIFRyQVggQVBJIGZ1bmN0aW9ucyBzdWJqZWN0IHRvIG11dGF0aW9uIHRvIHByZXZlbnQgbXV0YXRpb24gZHVyaW5nIGEgdHJhbnNmb3JtYXRpb24uPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rml4ZWQgYnVnIHJlcG9ydGVkIGJ5IEphbm8gRWxvdmlydGE6IHN1YnN0cmluZygpIHdhcyByZXR1cm5pbmcgYW4gZXJyb3IgaWYgdGhlIHN0YXJ0IGluZGV4IGlzIGxhcmdlciB0aGFuIHRoZSBzdHJpbmcuPGJyLz48YnIvPjwvbGk+ICAgCi0gICA8bGk+U2V0IFN0cmluZ0tleS50b1N0cmluZygpIHRvIHJldHVybiB0aGUgdW5kZXJseWluZyBTdHJpbmcgKG1fc3RyKSwgdGh1cyBhdm9pZGluZyBhIHBvdGVudGlhbCBzeW1tZXRyeSBwcm9ibGVtIHdpdGggdGhlIGVxdWFscygpIG1ldGhvZAotICAgcmVwb3J0ZWQgYnkgSXRvIEthenVtaXRzdS48YnIvPjxici8+PC9saT4KLSAgIDxsaT5JbiByZXNwb25zZSB0byBub3RlIGZyb20gSXRvIEthenVtaXRzdSwgY2hhbmdlZCBKYXZhIGVuY29kaW5nIG5hbWUgIkVVQ0pJUyIgaW4gRm9ybWF0dGVyVG9YTUwgdG8gIkVVQ19KUCIuPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+V2hlbiBYYWxhbiBjcmVhdGVzIGEgRmlsZU91dHB1dFN0cmVhbSwgaXQgbm93IGNsb3NlcyB0aGUgc3RyZWFtIGJlZm9yZSBleGl0aW5nLjxici8+PGJyLz48L2xpPgotICAgPGxpPkZpeGVkIGhhbmRsaW5nIG9mIGFuIGV4Y2VwdGlvbiB0aGF0IGNhbiBiZSB0aHJvd24gd2hpbGUgYnVpbGRpbmcgYSBET00uPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rml4ZWQgYSBwcm9ibGVtIHJlcG9ydGVkIGJ5IERpbWl0cnkgVm95dGVua28gc2VyaWFsaXppbmcgY29tcGlsZWQgc3R5bGVzaGVldHMuPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rm9yIHN1cHBvcnQgb2YgYXBwbGV0cywgbW9kaWZpZWQgVHJhbnNmb3JtZXJGYWN0b3J5IFN5c3RlbS5nZXRQcm9wZXJ0eSgpIGNhbGxzIHRvIGNhdGNoIFNlY3VyaXR5RXhjZXB0aW9ucy48YnIvPjxici8+PC9saT4KLSAgIDxsaT5GaXhlZCBhIGJ1ZyByZXBvcnRlZCBieSBLcmlzaG5hIE1vaGFuIE1lZHVyaSBzZXR0aW5nIG91dHB1dCBwcm9wZXJ0aWVzLjxici8+PGJyLz48L2xpPgotICAgPGxpPkZpeGVkIGVycm9yIHJlY292ZXJ5IHdoZW4geHNsOmVsZW1lbnQgZW5jb3VudGVycyBhIGJhZCBuYW1lIG9yIHVucmVzb2x2YWJsZSBwcmVmaXguPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+QWRkZWQgQWJzdHJhY3RNZXRob2RFcnJvciBoYW5kbGluZyB0byBleGlzdGluZyBOb1N1Y2hNZXRob2RFcnJvciBoYW5kbGluZyBhcyBhIGZhbGxiYWNrIHRvIHRoZSBYTUxSZWFkZXJGYWN0b3J5IGZvciBYTUwgcGFyc2VycyB0aGF0IGRvCi0gICAgICAgbm90IGltcGxlbWVudCB0aGUgSkFYUCBwYXJzZXJzIGludGVyZmFjZSBmb3IgY3JlYXRpbmcgYW4gWE1MUmVhZGVyPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rml4ZWQgYnVnIHdpdGggY2xvbmVkIGl0ZXJhdG9ycyByZXBvcnRlZCBieSBUaW0gU2Vhbi48YnIvPjxici8+PC9saT4KLSAgIDxsaT5GaXhlZCBudWxsIHBvaW50ZXIgZXhjZXB0aW9uIHRoYXQgY291bGQgb2NjdXIgd2l0aCBnZXRWYWx1ZSgieHh4IikuPGJyLz48YnIvPjwvbGk+Ci0gICA8bGk+Rml4ZWQgYnVnIHJlcG9ydGVkIGJ5IFRpbSBTZWFuIGhhbmRsaW5nIHRoZSB4bWw6c3BhY2UgYXR0cmlidXRlLjwvbGk+Ci08L3VsPgotPHA+PGVtPkJ1ZyBmaXhlcyBpbiB0aGUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0iY29tcGF0Ij5YYWxhbi1KYXZhIDEgY29tcGF0aWJpbGl0eSBBUEk8L2xpbms+OjwvZW0+PC9wPgotPHVsPgotICA8bGk+Rml4ZWQgUHJvYmxlbUxpc3RlbmVyIChmb3IgcHJvY2Vzc2luZyBlcnJvciBtZXNzYWdlcykgdG8gZGVyaXZlIGZyb20gJnhzbHQ0ajsgMiBFcnJvckhhbmRsZXIuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5GaXhlZCBldmFsdWF0aW9uIG9mIHN0eWxlc2hlZXQgc3RyaW5nIHBhcmFtZXRlcnMgdG8gY29uZm9ybSB0byAmeHNsdDRqOyAxIGJlaGF2aW9yIChleHByZXNzaW9ucyBmb3IgJnhzbHQ0ajsgMSB2cy4gU3RyaW5nIG9iamVjdHMgCi0gIGZvciAmeHNsdDRqOyAyKS48YnIvPjxici8+PC9saT4gICAgCi0gIDxsaT5BZGRlZCBYUGF0aFN1cHBvcnQgYW5kIFhQYXRoU3VwcG9ydERlZmF1bHQsIGFuZCBmaXhlZCB0aGUgZGVyaXZhdGlvbiBvZiBYT2JqZWN0IHN1Yi10eXBlcyAoWFN0cmluZywgZXRjLikuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5GaXhlZCBidWcgd2l0aCBYU0xUUHJvY2Vzc29yIHByb2Nlc3MoeG1sSW4sIG51bGwsIG91dCkgbWV0aG9kIHNvIHRoYXQgaXQgdXNlcyB0aGUgU3R5bGVzaGVldFJvb3QgKGlmIG9uZSBleGlzdHMpIHRoYXQgaGFzIGJlZW4gY3JlYXRlZAotICAgd2l0aCB0aGUgcHJvY2Vzc1N0eWxlc2hlZXQoKSBtZXRob2QuPC9saT4KLTwvdWw+Ci08cD5Gb3IgYSBsaXN0IG9mIHRhc2tzIGluIHRoZSAmeHNsdDRqMjsgVG8tRG8gbGlzdCB0aGF0IGhhdmUgYmVlbiBjb21wbGV0ZWQsIHNlZSA8anVtcCBocmVmPSJ0b2RvLmh0bWwjcmVsZWFzZS1kYXRlLWNvbXBsZXRlZCI+VGFza3MgY29tcGxldGVkPC9qdW1wPi48L3A+Ci08L3MzPgotCi08czMgdGl0bGU9IkNoYW5nZXMgZm9yICZ4c2x0NGo7IHZlcnNpb24gMi4wLkQwNyI+Ci08cD4meHNsdDRqOyAyLjAuRDA3IGluY29ycG9yYXRlcyBhIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIiBhbmNob3I9ImNvbXBhdCI+WGFsYW4tSmF2YSAxIGNvbXBhdGliaWxpdHkgamFyPC9saW5rPiwgc29tZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMsIGFuZCBhIG51bWJlciBvZiBidWcgZml4ZXMgZm9yIGJ1Z3MgZm91bmQgaW4gdmVyc2lvbiAyLjAuRDA2LjwvcD4KLTx1bD4KLTxsaT5GaXhlZCBoYW5kbGluZyBvZiBkaXNhYmxlLW91dHB1dC1lc2NhcGluZz0ibm8iLiAgUHJldmlvdXNseSwgb25jZSBpdCB3YXMgdHVybmVkIG9uLCBpdCBjb3VsZCBub3QgYmUgdHVybmVkIG9mZi48YnIvPjxici8+PC9saT4KLTxsaT5GaXhlZCBhIGJ1ZyB3aXRoIHdoaXRlc3BhY2UgaGFuZGxpbmcgd2hlcmUgWGFsYW4gd2FzIGluY29ycmVjdGx5IGNoZWNraW5nIGZvciB3aGl0ZXNwYWNlIAotICAgIHN0cmlwcGluZyBiZWZvcmUgY29sbGF0aW9uIG9mIG11bHRpcGxlIHdoaXRlc3BhY2UgZXZlbnRzIGludG8gYSBzaW5nbGUgdGV4dCBub2RlLjxici8+PGJyLz48L2xpPgotPGxpPldoaXRlc3BhY2Ugc3RyaXBwaW5nIHdhc24ndCB3b3JraW5nIHdpdGggaW5wdXQgRE9NcyBiZWZvcmUuICBUaGlzIGlzIG5vdyBmaXhlZC48YnIvPjxici8+PC9saT4KLTxsaT5GaXhlZCBtYW55IGV4Y2VwdGlvbiBoYW5kbGluZyBwcm9ibGVtcyBhbmQgcHJvYmxlbXMgd2l0aCBlcnJvciByZXBvcnRpbmcuPGJyLz48YnIvPjwvbGk+Ci08bGk+Rml4ZWQgYSBidWcgcmVzZXR0aW5nIHBhcmFtZXRlcnMgaW4gVHJhbnNmb3JtZXIgY2xlYXJQYXJhbWV0ZXJzKCkuPGJyLz48YnIvPjwvbGk+Ci08bGk+Rml4ZWQgYSBidWcgd2hlcmUgQ0RBVEEgc2VjdGlvbnMgd2VyZSBub3QgbWF0Y2hpbmcgdGhlIHRleHQoKSBub2RlIHRlc3QuPGJyLz48YnIvPjwvbGk+Ci08bGk+TWFkZSBiZXR0ZXIgbWVtb3J5IGFsbG9jYXRpb24gcHJvYmxlbSB3aXRoIHJlc3VsdCB0cmVlIGZyYWdtZW50cy48YnIvPjxici8+PC9saT4KLTxsaT5NYWRlIHJlc3VsdCB0cmVlIGZyYWdtZW50IHBhcnNpbmcgb2YgbnVtYmVycyBjb25zaXN0ZW50IHdpdGggc3RyaW5ncy48YnIvPjxici8+PC9saT4KLTxsaT5FeGNlcHRpb25zIHRocm93biBmcm9tIGV4dGVuc2lvbnMgc2hvdWxkIG5vdyBiZSBwcm9wZXJseSByZXBvcnRlZCB2aWEgdGhlIGVycm9yIGxpc3RlbmVyLjxici8+PGJyLz48L2xpPgotPGxpPkZpeGVkIGhhcmQtY29kZWQgc3RhY2sgZHVtcCBzZXQgb2ZmIGJ5IG1fcmVwb3J0SW5Qb3N0RXhjZXB0aW9uRnJvbVRocmVhZCB2YXJpYWJsZS48YnIvPjxici8+PC9saT4KLTxsaT5GaXhlZCBpbnRlcm1pdHRlbnQgdGhyZWFkaW5nIHByb2JsZW0gd2l0aCB0ZXh0IG5vZGVzIGJlaW5nIGRyb3BwZWQuPGJyLz48YnIvPjwvbGk+Ci08bGk+Rml4ZWQgcHJvYmxlbSB3aXRoIHZhcmlhYmxlIGV2YWx1YXRpb24gaW5zaWRlIG9mIHVuaW9uIGV4cHJlc3Npb25zLjwvbGk+Ci08L3VsPgotPC9zMz4KLTxzMyB0aXRsZT0iQ2hhbmdlcyBmb3IgJnhzbHQ0ajsgdmVyc2lvbiAyLjAuRDA2Ij4KLTxwPldlIGhhdmUgZml4ZWQgdGhlIGJ1Z3MgcmVwb3J0ZWQgaW4gJnhzbHQ0ajsgMi4wLkQwNS4gQWxvbmcgd2l0aCBzZXZlcmFsIG90aGVyIGVuaGFuY2VtZW50cywgCi13ZSBoYXZlIGFsc28gZml4ZWQgYSBudW1iZXIgb2YgYnVncyBmb3VuZCBieSB0ZXN0aW5nIGFuZCBvdXIgdXNlcnM6PC9wPgotPHVsPgotPGxpPkZpeGVkIHNvbWUgdGhyZWFkaW5nIHByb2JsZW1zIGFuZCBpbXByb3ZlZCBzdXBwb3J0IGZvciBoYW5kbGluZyBFeGNlcHRpb25zIHRocm93biBpbiBhIHNlY29uZGFyeSB0aHJlYWQuPGJyLz48YnIvPgotTm90ZTogVG8gc3VwcG9ydCBpbmNyZW1lbnRhbCBvdXRwdXQsICZ4c2x0NGo7IHBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbiBhIHNlY29uZCB0aHJlYWQgd2hpbGUgYnVpbGRpbmcgdGhlIHNvdXJjZSB0cmVlIGluIHRoZSBtYWluIHRocmVhZC48YnIvPjxici8+PC9saT4KLTxsaT5GaXhlZCBwcm9ibGVtcyBlbmNvdW50ZXJlZCBpbiBwaXBpbmcgKHV0aWxpemluZyB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQgYXMgaW5wdXQgZm9yIGFub3RoZXIgdHJhbnNmb3JtYXRpb24pLjxici8+PGJyLz48L2xpPgotPGxpPkZpeGVkIHByb2JsZW1zIGhhbmRsaW5nIGF0dHJpYnV0ZXMgYW5kIGFkZGluZyBhdHRyaWJ1dGVzIHRvIHJlc3VsdCB0cmVlLjxici8+PGJyLz48L2xpPgotPGxpPkFkZGVkIGRlZmVuc2l2ZSBjaGVja2luZyBmb3IgbnVsbCBlbnRpdGllcywgbnVsbCBuYW1lc3BhY2VzLCBhbmQgZW1wdHkgc3RyaW5ncyBwYXNzZWQgaW4gZm9yIFVSSXMgYW5kIGxvY2FsIG5hbWVzLjxici8+PGJyLz48L2xpPgotPGxpPldlIG5vdyBjb25mb3JtIHRvIHRoZSBTQVggY29udmVudGlvbiBvZiByZXByZXNlbnRpbmcgbnVsbCBuYW1lc3BhY2VzIHdpdGggZW1wdHkgc3RyaW5ncy48YnIvPjxici8+PC9saT4KLTxsaT5GaXhlZCBhIGJ1ZyBlbmNvdW50ZXJlZCBldmFsdWF0aW5nIGEgdmFyaWFibGUgaW4gYSBwcmVkaWNhdGUgZXhwcmVzc2lvbiBhcHBsaWVkIHRvIGNoaWxkIG5vZGVzLjxici8+PGJyLz48L2xpPgotPGxpPkNoYW5nZWQgbmFtZXMgb2Ygc2VyaWFsaXplcnMgZnJvbSBGb3JtYXR0ZXJUbzxyZWY+WHh4PC9yZWY+IHRvIFNlcmlhbGl6ZXJUbzxyZWY+WHh4PC9yZWY+LiBTZWUgCi08anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vc2VyaWFsaXplL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5QYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplPC9qdW1wPi48YnIvPjxici8+PC9saT4KLTxsaT5JbXByb3ZlZCBkZWJ1Z2dpbmcgc3VwcG9ydCBpbiBhIG51bWJlciBvZiBhcmVhcy48L2xpPgotPC91bD4KLTwvczM+Ci08czMgdGl0bGU9IkNoYW5nZXMgZm9yICZ4c2x0NGo7IHZlcnNpb24gMi4wLkQwNSI+Ci08cD5BbGwgb2YgdGhlIGJ1Z3MgcmVwb3J0ZWQgaW4gJnhzbHQ0ajsgMi4wLkQwMSBoYXZlIGJlZW4gZml4ZWQuIFRoZSByZW1haW5kZXIgb2YgdGhpcyBzZWN0aW9uIGRpc2N1c3NlcyB0d28gY2hhbmdlcyB0aGF0IHdlIGJlbGlldmUgYXJlIG9mIHBhcnRpY3VsYXIgaW1wb3J0YW5jZTo8L3A+Ci08cD48ZW0+VHJBWDwvZW0+PC9wPgotPHA+VGhlIFRyYW5zZm9ybWF0aW9uIEFQSSBmb3IgWE1MIChUckFYKSB0aGF0ICZ4c2x0NGoyOyBpbXBsZW1lbnRzIGhhcyB1bmRlcmdvbmUgc3Vic3RhbnRpYWwgcmV2aXNpb25zIHNpbmNlIHRoZSByZWxlYXNlIG9mICZ4c2x0NGo7IDIuMC5EMDEuIFRyQVggaGFzIGpvaW5lZCB0aGUgSmF2YSBBUEkgZm9yIFhNTCBQYXJzaW5nIChKQVhQKSBhcyBwYXJ0IG9mIHRoZSBTdW4mcmVnOyA8cmVzb3VyY2UtcmVmIGlkcmVmPSJqc3IwNjMiLz4uIEFjY29yZGluZ2x5LCB0aGUgVHJBWCBwYWNrYWdlIG5hbWVzIGhhdmUgY2hhbmdlZC4gVGhlIGNvbmNlcHR1YWwgb3JnYW5pemF0aW9uIGhhcyBhbHNvIGNoYW5nZWQgc29tZXdoYXQ6IFRoZSBwcmltYXJ5IHRyYW5zZm9ybWF0aW9uIGludGVyZmFjZXMgYXJlIGRlZmluZWQgaW4gamF2YXgueG1sLnRyYW5zZm9ybSwgd2l0aCBjb25jcmV0ZSBjbGFzc2VzIGZvciBtYW5hZ2luZyBzdHJlYW0gaW5wdXQvb3V0cHV0LCBTQVggcGFyc2VycyBhbmQgQ29udGVudEhhbmRsZXIsIGFuZCBET00gcGFyc2VycyBhbmQgRE9NIHRyZWVzIGluIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLCBqYXZheC54bWwudHJhbnNmb3JtLnNheCwgYW5kIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxsaW5rIGlkcmVmPSJ0cmF4Ij5UUmFYIChUcmFuc2Zvcm1hdGlvbiBBUEkgZm9yIFhNTCk8L2xpbms+LCBhbmQgcmV2aWV3IDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIj5Vc2FnZSBQYXR0ZXJuczwvbGluaz4uPC9wPgotPGFuY2hvciBuYW1lPSJvdXRwdXRwcm9wcyIvPjxwPjxlbT5PdXRwdXQgcHJvcGVydGllczwvZW0+PC9wPgotPHA+VGhlIGhhbmRsaW5nIG9mIHhzbDpvdXRwdXQgcHJvcGVydGllcyBoYXMgY2hhbmdlZDogb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuT3V0cHV0Rm9ybWF0IGFuZCBhcGFjaGUueGFsYW4udGVtcGxhdGVzLk91dHB1dEZvcm1hdEV4dGVuZGVkIHdlcmUgcmVtb3ZlZCBhbmQgcmVwbGFjZWQgd2l0aCBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzLiBUaGUgU2VyaWFsaXplckZhY3RvcnkgZ2V0U2VyaWFsaXplcigpIG1ldGhvZCBub3cgdGFrZXMgUHJvcGVydGllcyByYXRoZXIgdGhhbiBhIFN0cmluZyBpbmRpY2F0aW5nIHRoZSBvdXRwdXQgbWV0aG9kLiBZb3UgY2FuIHJlcGxhY2UgPGNvZGU+Z2V0U2VyaWFsaXplcigieG1sIik8L2NvZGU+LCBmb3IgZXhhbXBsZSwgd2l0aCA8Y29kZT5nZXRTZXJpYWxpemVyKE91dHB1dFByb3BlcnRpZXMuZ2V0RGVmYXVsdE1ldGhvZFByb3BlcnRpZXMoInhtbCIpKTwvY29kZT4uPC9wPgotPHA+SFRNTCwgWE1MLCBhbmQgdGV4dCB4c2w6b3V0cHV0IHByb3BlcnRpZXMgYXJlIHNwZWNpZmllZCBpbiBwcm9wZXJ0eSBmaWxlcyBpbiBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczogb3V0cHV0X2h0bWwucHJvcGVydGllcywgb3V0cHV0X3htbC5wcm9wZXJ0aWVzLCBhbmQgb3V0cHV0X3RleHQucHJvcGVydGllcy48L3A+Ci08cD5Zb3UgY2FuIHN0YXJ0IHVzaW5nIHRoZSBvdXRwdXQgcHJvcGVydGllcyBkZWZpbmVkIGluIHRoZXNlIGZpbGVzIGluIHlvdXIgc3R5bGVzaGVldHMuIEZvciBleGFtcGxlLCB5b3UgY2FuIHR1cm4gVVJMIGVzY2FwaW5nIG9mZiBpbiBIVE1MIG91dHB1dCB3aXRoPGJyLz48Y29kZT57aHR0cFx1MDAzYS8veG1sLmFwYWNoZS5vcmcveHNsdH11c2UtdXJsLWVzY2FwaW5nPW5vPC9jb2RlPjxici8+Ci1hbmQgeW91IGNhbiBjb250cm9sIGluZGVudGluZyB3aXRoPGJyLz4KLTxjb2RlPntodHRwXHUwMDNhLy94bWwuYXBhY2hlLm9yZy94c2x0fWluZGVudC1hbW91bnQ9PHJlZj5uPC9yZWY+PC9jb2RlPjwvcD4KLTxub3RlPlRoZSBjb2xvbiBhZnRlciB0aGUgImh0dHAiIHByb3RvY29sIG11c3QgYmUgZXNjYXBlZC48L25vdGU+Ci08cD5DaGFyYWN0ZXItdG8tZW50aXR5IG1hcHBpbmcgaXMgc3BlY2lmaWVkIGluIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOiBIVE1MRW50aXRpZXMucmVzIGFuZCBYTUxFbnRpdGllcy5yZXMuIFlvdSBjYW4gb3ZlcnJpZGUgZW50aXR5IHJlZiAKLW1hcHBpbmcgZnJvbSBhIHN0eWxlc2hlZXQuIEZvciBleGFtcGxlOjwvcD4KLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8mZ3Q7Ci0mbHQ7eHNsOnN0eWxlc2hlZXQgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iCi0gICAgICAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiIHZlcnNpb249IjEuMCImZ3Q7Ci0KLSAgJmx0O3hzbDpvdXRwdXQgeGFsYW46ZW50aXRpZXM9Im15ZW50aXRpZXMuZW50Ii8mZ3Q7Ci0KLSAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iLyImZ3Q7Ci0gICAgJmx0O291dCZndDsmYW1wOyMxMjU7Jmx0Oy9vdXQmZ3Q7Ci0gICZsdDsveHNsOnRlbXBsYXRlJmd0OwotCi0mbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0Ozwvc291cmNlPgotPHA+PT09IG15ZW50aXRpZXMuZW50ID09PTwvcD4KLTxzb3VyY2U+cXVvdCAzNAotYW1wIDM4Ci1sdCA2MAotZ3QgNjIKLWxhbGEgMTI1PC9zb3VyY2U+Ci08cD5UaGUgb3V0cHV0IGlzOjwvcD4KLTxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPyZndDsKLSZsdDtvdXQmZ3Q7JmFtcDtsYWxhOyZsdDsvb3V0Jmd0Ozwvc291cmNlPgotPHA+U2VlIGFsc28gPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0ib3V0cHV0cHJvcHMiPlNldHRpbmcgb3V0cHV0IHByb3BlcnRpZXMgaW4geW91ciBzdHlsZXNoZWV0czwvbGluaz4uPC9wPgotPC9zMz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuL2luZGV4LnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vaW5kZXgueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4YTEwOTc0Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4vaW5kZXgueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTAwICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4KLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotPCEtLSAKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci08czEgdGl0bGU9IiZ4c2x0NGotY3VycmVudDsiPgotPCEtLW5vdGU+QSBsYXRlciBEZXZlbG9wZXIgcmVsZWFzZSBoYXMgYmVlbiBwb3N0ZWQgaW4gdGhlIDxyZXNvdXJjZS1yZWYgaWRyZWY9InhzbHQ0ai1kaXN0ZGlyIi8+LiBGb3IgdGhlIGNoYW5nZXMgdGhhdCBoYXZlIG9jY3VycmVkIHNpbmNlICZ4c2x0NGotY3VycmVudDssIGNvbnN1bHQgdGhlIHhtbC14YWxhbi1jdnNAYXBhY2hlLm9yZyBtYWlsaW5nIGxpc3QsIG9yIGRvd25sb2FkIHRoZSByZWxlYXNlIGFuZCBjb25zdWx0IHRoZSByZWxlYXNlIG5vdGVzLjwvbm90ZS0tPgotICA8czIgdGl0bGU9IldoYXQgaXMgaXQ/Ij4KLSAgICA8cD5YYWxhbiBpcyBhbiBYU0xUIHByb2Nlc3NvciBmb3IgdHJhbnNmb3JtaW5nIFhNTCBkb2N1bWVudHMgaW50byBIVE1MLCB0ZXh0LCBvciBvdGhlciBYTUwgZG9jdW1lbnQgdHlwZXMuIEl0IGltcGxlbWVudHMgdGhlCi0gICAgIFczQyBSZWNvbW1lbmRhdGlvbnMgZm9yIFhTTCBUcmFuc2Zvcm1hdGlvbnMgKFhTTFQpIGFuZCB0aGUgWE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKS4gSXQgY2FuIGJlIHVzZWQgZnJvbSB0aGUgY29tbWFuZCBsaW5lLAotICAgICBpbiBhbiBhcHBsZXQgb3IgYSBzZXJ2bGV0LCBvciBhcyBhIG1vZHVsZSBpbiBvdGhlciBwcm9ncmFtLjwvcD4KLSAgPC9zMj4KLSAgPHMyIHRpdGxlPSJJJ3ZlIGhlYXJkIG9mICZ4c2x0NGo7LCBidXQgd2hhdCBpcyB2ZXJzaW9uIDI/Ij4KLSAgICA8cD4meHNsdDRqOyB2ZXJzaW9uIDIgcmVjYXN0cyBYYWxhbiBhcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgPGxpbmsgaWRyZWY9InRyYXgiPlRSYVggKFRyYW5zZm9ybWF0aW9uIEFQSSBmb3IgWE1MKTwvbGluaz4gaW50ZXJmYWNlcywgcGFydCBvZiB0aGUgPHJlc291cmNlLXJlZiBpZHJlZj0iamF4cDExIi8+LiBUUmFYIHByb3ZpZGVzIGEKLSAgICBtb2R1bGFyIGZyYW1ld29yayBhbmQgYSBzdGFuZGFyZCBBUEkgZm9yIHBlcmZvcm1pbmcgWE1MIHRyYW5zZm9ybWF0aW9ucywgYW5kIGl0IHV0aWxpemVzIHN5c3RlbSBwcm9wZXJ0aWVzIHRvIGRldGVybWluZSB3aGljaCBUcmFuc2Zvcm1lciBhbmQgd2hpY2ggWE1MIHBhcnNlciB0byB1c2UuPC9wPgotICAgICA8cD4meHNsdDRqOyB2ZXJzaW9uIDIgYWxzbyBidWlsZHMgb24gPHJlc291cmNlLXJlZiBpZHJlZj0ic2F4MiIvPiwgPHJlc291cmNlLXJlZiBpZHJlZj0iZG9tMiIvPiwgYW5kIHRoZSBYTUwgcGFyc2VyIEFQSSBpbgotICAgICA8cmVzb3VyY2UtcmVmIGlkcmVmPSJqYXhwIi8+LjwvcD4KLSAgICAgPHA+Rm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSA8bGluayBpZHJlZj0id2hhdHNuZXciPldoYXQncyBuZXcgaW4gJnhzbHQ0ajI7PC9saW5rPi48L3A+Ci0gICAgIDxub3RlPiZ4c2x0NGM7IHZlcnNpb24gMSBpcyBubyBsb25nZXIgc3VwcG9ydGVkIGFuZCBubyBsb25nZXIgYXZhaWxhYmxlIGZyb20geG1sLmFwYWNoZS5vcmcuPC9ub3RlPgotICA8L3MyPgotICA8czIgdGl0bGU9IkhvdyBhYm91dCB0aGlzIHJlbGVhc2U/Ij4KLSAgPHA+JnhzbHQ0ai1jdXJyZW50OyBpcyBhIERldmVsb3BlciByZWxlYXNlLiBUbyBpbXByb3ZlIHBlcmZvcm1hbmNlLCBpdCB1c2VzIHRoZSBEb2N1bWVudCBUYWJsZSBNb2RlbCAoPGxpbmsgaWRyZWY9ImR0bSI+RFRNPC9saW5rPikgdG8gcmVwcmVzZW50IHRoZSBYTUwgc291cmNlIGRvY3VtZW50IHRvIGJlIHRyYW5zZm9ybWVkLiBQbGVhc2Ugc2VuZCB5b3VyIGZlZWRiYWNrIHRvIHRoZSA8aHVtYW4tcmVzb3VyY2UtcmVmIGlkcmVmPSJ4YWxhbmRldiIvPi48L3A+Ci0gIDwvczI+IAotICA8czIgdGl0bGU9IkhvdyBkbyBJIGdldCBpdD8iPgotICAgIDxwPkRvd25sb2FkIGFuZCB1bnppcCBlaXRoZXIgb2YgdGhlIGZvbGxvd2luZzo8L3A+Ci0gICAgPHVsPgotICAgICAgPGxpPjxyZXNvdXJjZS1yZWYgaWRyZWY9InhzbHQ0ai1kaXN0LXppcCIvPjwvbGk+Ci0gICAgICA8bGk+PHJlc291cmNlLXJlZiBpZHJlZj0ieHNsdDRqLWRpc3QtdGFyZ3oiLz48L2xpPgotICAgIDwvdWw+ICAgICAKLSAgPC9zMj4KLSAgCi0gIDxzMiB0aXRsZT0iV2hlcmUgZG8gSSBnZXQgWGVyY2VzPyI+Ci0gICAgPHA+VGhlIFhhbGFuIGRvd25sb2FkIGluY2x1ZGVzIHhlcmNlcy5qYXIgZnJvbSAmeG1sNGotdXNlZDsuIFRoaXMgaXMgYWxsIHlvdSBuZWVkIHRvIHJ1biBYYWxhbiB3aXRoIHRoZSBYZXJjZXMgWE1MIHBhcnNlci4gCi0gICAgWW91IGNhbiwgaG93ZXZlciwgZG93bmxvYWQgdGhlIGNvbXBsZXRlIFhlcmNlcyBkaXN0cmlidXRpb24gZnJvbSB0aGUgPHJlc291cmNlLXJlZiBpZHJlZj0ieG1sNGotZGlzdGRpciIvPi48L3A+Ci0gICAgPG5vdGU+SWYgeW91IHBsYW4gdG8gdXNlIGEgZGlmZmVyZW50IFhNTCBwYXJzZXIsIHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJwbHVnIj5QbHVnZ2luZyBpbiBhIFRyYW5zZm9ybWVyCi0gICAgIGFuZCBYTUwgcGFyc2VyPC9saW5rPi48L25vdGU+IAotICA8L3MyPgotICA8czIgdGl0bGU9IldoYXQgZWxzZSBkbyBJIG5lZWQ/Ij4KLSAgICA8cD5Zb3UgbmVlZCB0aGUgSmF2YSBEZXZlbG9wbWVudCBLaXQgb3IgSmF2YSBSdW50aW1lIDEuMS44LCAxLjIuMiwgb3IgMS4zLCB3aGljaCB5b3UgY2FuIG9idGFpbiBmcm9tIDxqdW1wCi0gICAgaHJlZj0iaHR0cDovL3d3dy5pYm0uY29tL2phdmEvamRrIj5pYm0uY29tL2phdmEvamRrLzwvanVtcD4gb3IgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy5qYXZhLnN1bi5jb20iPmphdmEuc3VuLmNvbTwvanVtcD4uPC9wPiAKLSAgPC9zMj4gIAotICAgIDxzMiB0aXRsZT0iRm9yIG1vcmUgaW5mb3JtYXRpb24uLi4iPgotICAgIDxwPkZvciBtb3JlIGluZm9ybWF0aW9uLCBnbyB0byA8bGluayBpZHJlZj0ib3ZlcnZpZXciPlhhbGFuIE92ZXJ2aWV3PC9saW5rPiBhbmQgPGxpbmsgaWRyZWY9ImdldHN0YXJ0ZWQiPkdldHRpbmcKLSAgICBTdGFydGVkPC9saW5rPi4gQWxsIG9mIHRoZSBYYWxhbiBkb2N1bWVudGF0aW9uIG9uIHRoaXMgd2Vic2l0ZSBpcyBpbmNsdWRlZCBpbiB0aGUgWGFsYW4gZG93bmxvYWQsIGFzIGFyZSBhIG51bWJlciBvZgotICAgIDxsaW5rIGlkcmVmPSJzYW1wbGVzIj5TYW1wbGVzPC9saW5rPiB0byBoZWxwIHlvdSBzdGFydCB1c2luZyAmeHNsdDRqMjsgdG8gdHJhbnNmb3JtIFhNTCBkb2N1bWVudHMuPC9wPgotICA8L3MyPiAgCi08L3MxPiAKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuL292ZXJ2aWV3LnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vb3ZlcnZpZXcueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjM2RkN2VjLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4vb3ZlcnZpZXcueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMjA0ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4KLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotCi08IS0tCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotIC0tPgotIAotPHMxIHRpdGxlPSImeHNsdDRqOyBPdmVydmlldyI+Ci08dWw+Ci08bGk+PGxpbmsgYW5jaG9yPSJpbnRybyI+SW50cm9kdWN0aW9uPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJmZWF0dXJlcyI+JnhzbHQ0ajsgRmVhdHVyZXM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InRvd29yayI+R2V0dGluZyB0byB3b3JrIHdpdGggJnhzbHQ0ajs8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InVwdG9zcGVlZCI+R2V0dGluZyB1cCB0byBzcGVlZCB3aXRoIFhTTFQ8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Imdsb3NzYXJ5Ij5HbG9zc2FyeTwvbGluaz48L2xpPgotPC91bD48YW5jaG9yIG5hbWU9ImludHJvIi8+Ci0gIDxzMiB0aXRsZT0iSW50cm9kdWN0aW9uIj4KLSAgICA8cD4meHNsdDRqOyAobmFtZWQgYWZ0ZXIgYSByYXJlIG11c2ljYWwgaW5zdHJ1bWVudCkgZnVsbHkgaW1wbGVtZW50cyB0aGUgPHJlc291cmNlLXJlZiBpZHJlZj0ieHNsdCIvPiBhbmQgdGhlIAotICAgIDxyZXNvdXJjZS1yZWYgaWRyZWY9InhwYXRoIi8+LiBYU0xUIGlzIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBYU0wgc3R5bGVzaGVldCBsYW5ndWFnZSBmb3IgWE1MLiBJdCBpbmNsdWRlcyB0aGUgWFNMCi0gICAgIFRyYW5zZm9ybWF0aW9uIHZvY2FidWxhcnkgYW5kIFhQYXRoLCBhIGxhbmd1YWdlIGZvciBhZGRyZXNzaW5nIHBhcnRzIG9mIFhNTCBkb2N1bWVudHMuIEZvciBsaW5rcyB0byBiYWNrZ3JvdW5kIG1hdGVyaWFscywgCi0gICAgZGlzY3Vzc2lvbiBncm91cHMsIGZyZXF1ZW50bHkgYXNrZWQgcXVlc3Rpb25zLCBhbmQgdHV0b3JpYWxzIG9uIFhTTFQsIHNlZSA8bGluayBhbmNob3I9InVwdG9zcGVlZCI+R2V0dGluZyB1cAotICAgIHRvIHNwZWVkIHdpdGggWFNMVDwvbGluaz4uPC9wPiAKLSAgICA8bm90ZT5YU0wgYWxzbyBpbmNsdWRlcyBhIHZvY2FidWxhcnkgZm9yIGZvcm1hdHRpbmcgZG9jdW1lbnRzLCB3aGljaCBpcyBub3QgcGFydCBvZiAmeHNsdDRqOy4gCi0gICAgRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSA8cmVzb3VyY2UtcmVmIGlkcmVmPSJ4c2x0Ii8+IGFuZCB0aGUgPGp1bXAKLSAgICBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmcvZm9wIj5BcGFjaGUgWE1MIEZPUCAoRm9ybWF0dGluZyBPYmplY3RzIFByb2plY3QpPC9qdW1wPi48L25vdGU+Ci0gICAgPHA+WW91IHVzZSB0aGUgWFNMVCBsYW5ndWFnZSB0byBjb21wb3NlIFhTTCBzdHlsZXNoZWV0cy4gQW4gWFNMIHN0eWxlc2hlZXQgY29udGFpbnMgaW5zdHJ1Y3Rpb25zIGZvcgotICAgICB0cmFuc2Zvcm1pbmcgWE1MIGRvY3VtZW50cyBmcm9tIG9uZSBkb2N1bWVudCB0eXBlIGludG8gYW5vdGhlciBkb2N1bWVudCB0eXBlIChYTUwsIEhUTUwsIG9yIG90aGVyKS4gSW4gc3RydWN0dXJhbAotICAgICB0ZXJtcywgYW4gWFNMIHN0eWxlc2hlZXQgc3BlY2lmaWVzIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBvbmUgdHJlZSBvZiBub2RlcyAodGhlIFhNTCBpbnB1dCkgaW50byBhbm90aGVyIHRyZWUgb2Ygbm9kZXMgCi0gICAgICh0aGUgb3V0cHV0IG9yIHRyYW5zZm9ybWF0aW9uIHJlc3VsdCkuPC9wPgotICAgIDxub3RlPlRoZSBYU0wgc3R5bGVzaGVldCBtYXkgZ2VuZXJhdGUgYW5kIHJlZmVyIHRvIGNhc2NhZGluZyBzdHlsZSBzaGVldHMgKDxqdW1wCi0gICAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvU3R5bGUvQ1NTLyI+Q1NTPC9qdW1wPikgYXMgcGFydCBvZiBpdHMgb3V0cHV0Ljwvbm90ZT4gCi0gICAgPHA+SW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLCB0aGUgZm9vLnhzbCBzdHlsZXNoZWV0IGlzIHVzZWQgdG8gdHJhbnNmb3JtIGZvby54bWwgaW50byBmb28ub3V0OjwvcD4KLSAgICA8cD5mb28ueG1sOjwvcD4KLSAgICAgICAgPHNvdXJjZT4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPz4KLSZsdDtkb2M+SGVsbG8mbHQ7L2RvYz48L3NvdXJjZT4KLSAgICAgICAgPHA+Zm9vLnhzbDo8L3A+Ci0gICAgICAgIDxzb3VyY2U+Jmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8+IAotJmx0O3hzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iZG9jIj4KLSZsdDtvdXQ+Jmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz4mbHQ7L291dD4KLSZsdDsveHNsOnRlbXBsYXRlPgotJmx0Oy94c2w6c3R5bGVzaGVldD48L3NvdXJjZT4KLTxwPmZvby5vdXQ6PC9wPgotPHNvdXJjZT4mbHQ7b3V0PkhlbGxvJmx0Oy9vdXQ+PC9zb3VyY2U+Ci08cD5CeSBkZWZhdWx0LCAmeHNsdDRqOyB1c2VzICZ4bWw0ajssIGFuZCBpdCBtYXkgYmUgY29uZmlndXJlZCB3aXRoIHN5c3RlbSBwcm9wZXJ0aWVzIHRvIHdvcmsgd2l0aCBvdGhlciBYTUwgcGFyc2VycyAoc2VlIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIiBhbmNob3I9InBsdWciPlBsdWdnaW5nIGluIGEgVHJhbnNmb3JtZXIgYW5kIFhNTCBwYXJzZXI8L2xpbms+KS4gVGhlIGlucHV0IG1heSBiZSBzdWJtaXR0ZWQgaW4gdGhlIGZvcm0gb2YgYSBzdHJlYW0gb2YgWE1MIG1hcmt1cCAoZnJvbSBhIFVSSSwgYSBjaGFyYWN0ZXIgb3IgYnl0ZSBzdHJlYW0sIG9yIGFub3RoZXIgdHJhbnNmb3JtYXRpb24pLCBhIFNBWCBJbnB1dFN0cmVhbSwgb3IgYSBET00gTm9kZS48L3A+Ci08cD4meHNsdDRqOyBwZXJmb3JtcyB0aGUgdHJhbnNmb3JtYXRpb25zIHNwZWNpZmllZCBpbiB0aGUgWFNMIHN0eWxlc2hlZXQgYW5kIHBhY2thZ2VzIGEgc2VxdWVuY2Ugb2YgU0FYIGV2ZW50cyB0aGF0IG1heSBiZSBzZXJpYWxpemVkIHRvIGFuIG91dHB1dCBzdHJlYW0gb3Igd3JpdGVyLCB1c2VkIHRvIGJ1aWxkIGEgRE9NIHRyZWUsIG9yIGZvcndhcmRlZCBhcyBpbnB1dCB0byBhbm90aGVyIHRyYW5zZm9ybWF0aW9uLjwvcD4KLSAgICAgIDwvczI+PGFuY2hvciBuYW1lPSJmZWF0dXJlcyIvPgotICAgCSAgPHMyIHRpdGxlPSImeHNsdDRqOyBGZWF0dXJlcyI+Ci0JICAgIDx1bD4gCi0JCSAgICA8bGk+SW1wbGVtZW50cyB0aGUgcmVsZXZhbnQgVzNDIHNwZWNpZmljYXRpb25zOiA8cmVzb3VyY2UtcmVmIGlkcmVmPSJ4c2x0Ii8+IGFuZCA8cmVzb3VyY2UtcmVmIGlkcmVmPSJ4cGF0aCIvPi48YnIvPjxici8+PC9saT4KLSAgICAgICAgPGxpPkltcGxlbWVudHMgPGxpbmsgaWRyZWY9InRyYXgiPlRSYVggKFRyYW5zZm9ybWF0aW9uIEFQSSBmb3IgWE1MKTwvbGluaz4sIG5vdyBwYXJ0IG9mIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImpheHAiLz4sIGFuZCBidWlsZHMgb24KLSAgICAgICAgIDxyZXNvdXJjZS1yZWYgaWRyZWY9InNheDIiLz4gYW5kIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImRvbTIiLz4uPGJyLz48YnIvPjwvbGk+Ci0gICAgCSAgPGxpPk1heSBiZSBjb25maWd1cmVkIHRvIHdvcmsgd2l0aCBhbnkgWE1MIHBhcnNlciwgc3VjaAotICAgICAgICA8anVtcCBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGVyY2VzLWovaW5kZXguaHRtbCI+JnhtbDRqOzwvanVtcD4sIHRoYXQgaW1wbGVtZW50cyA8cmVzb3VyY2UtcmVmCi0gICAgICAgIGlkcmVmPSJqYXhwIi8+IChzZWUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0icGx1ZyI+UGx1Z2dpbmcgaW4gYW4gWE1MCi0gICAgICAgICBwYXJzZXI8L2xpbms+KS48YnIvPjxici8+PC9saT4KLSAgICAJICA8bGk+Q2FuIHByb2Nlc3MgU3RyZWFtLCBTQVggb3IgRE9NIGlucHV0LCBhbmQgb3V0cHV0IHRvIGEgU3RyZWFtLCBTQVggb3IgRE9NLjxici8+PGJyLz48L2xpPgotICAgICAgICA8bGk+VHJhbnNmb3JtYXRpb25zIG1heSBiZSBjaGFpbmVkICh0aGUgb3V0cHV0IG9mIG9uZSB0cmFuc2Zvcm1hdGlvbiBtYXkgYmUgdGhlIGlucHV0IGZvcgotICAgICAgICAgYW5vdGhlcikuPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgIDxsaT5NYXkgYmUgcnVuIGZyb20gdGhlIDxsaW5rIGlkcmVmPSJjb21tYW5kbGluZSI+Y29tbWFuZCBsaW5lPC9saW5rPiBmb3IgY29udmVuaWVudCBmaWxlLXRvLWZpbGUKLSAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9ucy48YnIvPjxici8+PC9saT4KLSAgICAJICA8bGk+SW5jbHVkZXMgYW4gPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0iYXBwbGV0Ij5hcHBsZXQgd3JhcHBlcjwvbGluaz4uPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgIDxsaT5NYXkgYmUgdXNlZCBpbiBhIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9InNlcnZsZXQiPnNlcnZsZXQ8L2xpbms+IHRvIHRyYW5zZm9ybSBYTUwgZG9jdW1lbnRzIGludG8KLSAgICAgICAgSFRNTCBhbmQgc2VydmUgdGhlIHJlc3VsdHMgdG8gY2xpZW50cy48YnIvPjxici8+PC9saT4KLSAgICAgICAgPGxpPlN1cHBvcnRzIHRoZSBjcmVhdGlvbiBvZiA8bGluayBpZHJlZj0iZXh0ZW5zaW9ucyI+SmF2YSBhbmQgc2NyaXB0aW5nIGxhbmd1YWdlIGV4dGVuc2lvbnM8L2xpbms+LiBhbmQKLSAgICAgICAgIHByb3ZpZGVzIGEgZ3Jvd2luZyBsaWJyYXJ5IG9mIGV4dGVuc2lvbiBlbGVtZW50cyBhbmQgZnVuY3Rpb25zLjwvbGk+Ci0JICAgIDwvdWw+IAotCSAgPC9zMj48YW5jaG9yIG5hbWU9InRvd29yayIvPgotICAgIDxzMiB0aXRsZT0iR2V0dGluZyB0byB3b3JrIHdpdGggJnhzbHQ0ajsiPgotICAgICA8cD5Gb3IgaW5zdHJ1Y3Rpb25zIGFuZCBzb21lIHN1Z2dlc3Rpb25zIGFib3V0IGhvdyB0byBnZXQgc3RhcnRlZCB1c2luZyAmeHNsdDRqOywgc2VlIAotICAgICA8bGluayBpZHJlZj0iZ2V0c3RhcnRlZCI+R2V0dGluZyBTdGFydGVkPC9saW5rPi48L3A+Ci0gICAgPC9zMj48YW5jaG9yIG5hbWU9InVwdG9zcGVlZCIvPgotICAgIDxzMiB0aXRsZT0iR2V0dGluZyB1cCB0byBzcGVlZCB3aXRoIFhTTFQiPgotICAgIDxwPklmIHlvdSBhcmUgc3RpbGwgd29ya2luZyB0aHJvdWdoIHRoZSBkZXRhaWxzIG9mIHRoZSBYU0xUIHNwZWMgKHRoZSBXM0MgMS4wIFJlY29tbWVuZGF0aW9uKSwgeW91IG1heSB3YW50IAotICAgIHRvIGNvbnN1bHQgb25lIG9yIG1vcmUgb2YgdGhlIGZvbGxvd2luZzo8L3A+Ci0gICAgPHVsPgotICAgICAgICA8bGk+WFNMVCAtIFhTTCBUcmFuc2Zvcm1hdGlvbnMgaW4gCi0gICAgICAgIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cuYnJpY3MuZGsvfmFtb2VsbGVyL1hNTC8iPlRoZSBYTUwgUmV2b2x1dGlvbjogVGVjaG5vbG9naWVzIGZvciB0aGUgZnV0dXJlIFdlYjwvanVtcD4gYnkKLSAgICAgICAgQW5kZXJzIE0mb3NsYXNoO2xsZXIgYW5kIE1pY2hhZWwgSS4gU2Nod2FydHpiYWNoIChXZWIgcGFnZXMsIGJ1dCBkZXNpZ25lZCBmb3Igc2VxdWVudGlhbCByZWFkaW5nKTwvbGk+Ci0gICAgICAgIDxsaT5DcmFuZSBTb2Z0d3JpZ2h0J3MgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy5DcmFuZVNvZnR3cmlnaHRzLmNvbS90cmFpbmluZy8iPkZyZWUgcHJldmlldyBvZiBQcmFjdGljYWwKLSAgICAgICAgIFRyYW5zZm9ybWF0aW9uIFVzaW5nIFhTTFQgYW5kIFhQYXRoPC9qdW1wPjxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5Eb3VnIFRpZHdlbGwncyA8anVtcCBocmVmPSJodHRwOi8vd3d3Lm9yZWlsbHkuY29tL2NhdGFsb2cveHNsdC8iPlhTTFQ8L2p1bXA+LCBPJ1JlaWxseSwgMjAwMTxici8+PGJyLz48L2xpPiAgICAgICAgICAgICAgICAgCi0gICAgICAgPGxpPkJvYiBEdWNoYXJtZSdzIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cubWFubmluZy5jb20vZHVjaGFybWUvaW5kZXguaHRtbCI+WFNMVCBRdWlja2x5PC9qdW1wPiwgTWFubmluZyBQdWJsaWNhdGlvbnMsCi0gICAgICAgIDIwMDE8YnIvPjxici8+PC9saT4gICAgICAgICAgICAgICAgIAotICAgICAgIDxsaT5Kb2huIFJvYmVydCBHYXJkbmVyIGFuZCBaYXJlbGxhIFJlbmRvbidzIAotICAgICAgIDxqdW1wIGhyZWY9Imh0dHA6Ly92aWcucHJlbmhhbGwuY29tL2NhdGFsb2cvYWNhZGVtaWMvcHJvZHVjdC8xLDQwOTYsMDEzMDQwNDQ2MiwwMC5odG1sIj5YU0xUIGFuZCBYUGF0aDogQSBHdWlkZSB0bwotICAgICAgICBUcmFuc2Zvcm1hdGlvbnM8L2p1bXA+LCBQcmVudGljZS1IYWxsLCAyMDAxPGJyLz48YnIvPjwvbGk+ICAgICAgICAgICAgICAgICAKLSAgICAgICA8bGk+TWljaGFlbCBLYXkncyA8anVtcCBocmVmPSJodHRwOi8vd3d3Lndyb3guY29tL0Jvb2tzL0Jvb2tfRGV0YWlscy5hc3A/SVNCTj0xODYxMDA1MDY3Ij5YU0xUIFByb2dyYW1tZXIncwotICAgICAgIFJlZmVyZW5jZTwvanVtcD4sIDJuZCBlZC4sIFdyb3ggUHJlc3MsIDIwMDE8YnIvPjxici8+PC9saT4KLSAgICAgICA8bGk+U3RldmVuIEhvbHpuZXIncyA8anVtcCBocmVmPSJodHRwOi8vd3d3Lm5ld3JpZGVycy5jb20vYm9va3MvdGl0bGUuY2ZtP2lzYm49MDczNTcxMTM2NCI+SW5zaWRlIFhTTFQ8L2p1bXA+LCAKLSAgICAgICBOZXcgUmlkZXJzLCAyMDAxPGJyLz48YnIvPjwvbGk+ICAgICAgICAgICAgICAgICAKLSAgICAgICA8bGk+TmVpbCBCcmFkbGV5J3MgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy5hd2xvbmxpbmUuY29tL3Byb2R1Y3QvMCwyNjI3LDAyMDE2NzQ4NzQsMDAuaHRtbCI+WFNMIENvbXBhbmlvbjwvanVtcD4sCi0gICAgICAgIEFkZGlzb24tV2VzbGV5LCAyMDAwPGJyLz48YnIvPjwvbGk+ICAgICAgICAgICAgICAgICAKLSAgICAgICA8bGk+S2h1biBZZWUgRnVuZydzIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cuYXdsb25saW5lLmNvbS9wcm9kdWN0LzAsMjYyNywwMjAxNzExMDM2LDAwLmh0bWwiPlhTTFQ6IFdvcmtpbmcgd2l0aCBYTUwgYW5kCi0gICAgICAgIEhUTUw8L2p1bXA+LCBBZGRpc29uLVdlc2xleSwgMjAwMTxici8+PGJyLz48L2xpPiAgICAgICAgICAgICAgICAgCi0gICAgICAgIDxsaT5EYXZlIFBhd3NvbidzIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImRwYXdzb254c2xmYXEiLz4gdG8gc2VhcmNoIG91dCBwYXJ0aWN1bGFyIGFuc3dlcnMgYW5kIHRlY2huaXF1ZXM8YnIvPjxici8+PC9saT4KLSAgICAgICAgIDxsaT5NaWxvc2xhdiBOaWMncyA8anVtcCBocmVmPSJodHRwOi8venZvbi52c2NodC5jei9IVE1Mb25seS9YU0xUdXRvcmlhbC9Cb29rcy9Cb29rMS9pbmRleC5odG1sIj5YU0wgVHV0b3JpYWw8L2p1bXA+LAotICAgICAgICAgYSBjb2xsZWN0aW9uIG9mIHN0eWxlc2hlZXQgZXhhbXBsZXM8YnIvPjxici8+PC9saT4KLSAgICAgICAgPGxpPkVsbGlvdHRlIFJ1c3R5IEhhcm9sZCdzIDxqdW1wIGhyZWY9Imh0dHA6Ly9tZXRhbGFiLnVuYy5lZHUveG1sL2Jvb2tzL2JpYmxlL3VwZGF0ZXMvMTQuaHRtbCI+Q2hhcHRlciAxNCBvZiAKLSAgICAgICAgdGhlIFhNTCBCaWJsZTogWFNMIFRyYW5zZm9ybWF0aW9uczwvanVtcD48YnIvPjxici8+PC9saT4KLSAgICAgICAgPGxpPlRoZSBNdWxiZXJyeSA8anVtcCBocmVmPSJodHRwOi8vd3d3Lm11bGJlcnJ5dGVjaC5jb20veHNsL3hzbC1saXN0LyI+WFNMLUxpc3QgLS0gT3BlbiBGb3J1bSBvbiBYU0w8L2p1bXA+IAotICAgICAgICAob2YgaW50ZXJlc3QgdG8gWFNMIHVzZXJzIGF0IGFsbCBsZXZlbHMpPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgIDxsaT5PYmplY3RzIGJ5IERlc2lnbidzIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cub2JqZWN0c2J5ZGVzaWduLmNvbS9wcm9qZWN0cy94bWlfdG9faHRtbC5odG1sIj5UcmFuc2Zvcm1pbmcgWE1JIHRvCi0gICAgICAgICBIVE1MPC9qdW1wPiAob3JpZW50ZWQgdG93YXJkcyBYTUksICJhbiBYTUwtYmFzZWQsIHN0cmVhbSByZXByZXNlbnRhdGlvbiBvZiBhIFVNTCBtb2RlbCwiIGJ1dCBhbHNvIGNvdmVycyAiZ2VuZXJpYyIKLSAgICAgICAgIFhNTCB0cmFuc2Zvcm1hdGlvbnMpIGFuZCB0aGVpciByZWxhdGVkIDxqdW1wIGhyZWY9Imh0dHA6Ly9vYmplY3RzYnlkZXNpZ24uY29tL3Byb2plY3RzL3hzbHQveHNsdF9ieV9leGFtcGxlLmh0bWwiPlhTTFQKLSAgICAgICAgIGJ5IEV4YW1wbGU8L2p1bXA+PGJyLz48YnIvPjwvbGk+ICAgICAgICAgCi0gICAgICAgICA8bGk+T0FTSVMgKHRoZSBPcmdhbml6YXRpb24gZm9yIHRoZSBBZHZhbmNlbWVudCBvZiBTdHJ1Y3R1cmVkIEluZm9ybWF0aW9uIFN0YW5kYXJkcyk6IAotICAgICAgICAgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy5vYXNpcy1vcGVuLm9yZy9jb3Zlci94c2wuaHRtbCI+RXh0ZW5zaWJsZSBTdHlsZXNoZWV0IExhbmd1YWdlIChYU0wpPC9qdW1wPiBieSBSb2JpbgotICAgICAgICAgQ292ZXI8YnIvPjxici8+PC9saT4KLSAgICAgICAgIDxsaT5Eb25hbGQgQmFsbCdzIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cud2Vic2xpbmdlclouY29tL2JhbGxkL3hzbC9kZXNpZ25lcl9tYW51YWwueG1sIj5BIEd1aWRlIHRvIFhNTCBhbmQgWFNMIGZvcgotICAgICAgICAgRGVzaWduZXJzPC9qdW1wPjxici8+PGJyLz48L2xpPiAgICAgICAgIAotICAgIDwvdWw+Ci0gICAgPHA+V2hlbiB5b3UgY29tZSBhY3Jvc3Mgb3RoZXIgdXNlZnVsIGludHJvZHVjdG9yeSBvciBiYWNrZ3JvdW5kIG1hdGVyaWFscywgcGxlYXNlIGVtYWlsIDxodW1hbi1yZXNvdXJjZS1yZWYKLSAgICAgaWRyZWY9InhhbGFuZGV2Ii8+LCBzbyB3ZSBjYW4gYWRkIHRoZW0gdG8gdGhpcyBsaXN0LjwvcD4KLSAgICAKLSAgICA8L3MyPjxhbmNob3IgbmFtZT0iZ2xvc3NhcnkiLz4KLSAgICA8czIgdGl0bGU9Ikdsb3NzYXJ5Ij4KLSAgICAgIDxnbG9zcz4KLSAgICAgICAgPGxhYmVsPlhTTFQgTmFtZXNwYWNlPC9sYWJlbD4KLSAgICAgICAgPGl0ZW0+VGhlIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwtbmFtZXMvIj5YTUwgbmFtZXNwYWNlPC9qdW1wPiBmb3IgWFNMVC4gQW4gWE1MIG5hbWVzcGFjZSBpcyBhIAotICAgICAgICBjb2xsZWN0aW9uIG9mIGVsZW1lbnQgYW5kIGF0dHJpYnV0ZSBuYW1lcywgaWRlbnRpZmllZCBieSBhIFVuaXF1ZSBSZXNvdXJjZSBJZGVudGlmaWVyIChVUkkpLCB3aGljaCBvZnRlbiB0YWtlcyB0aGUgZm9ybSBvZgotICAgICAgICBhIFVSTCwgYnV0IGlzIHJlYWxseSBqdXN0IGEgdW5pcXVlIHN0cmluZywgbm90IGEgcG9pbnRlciB0byBhIHdlYiBwYWdlLiBUaGUgWFNMVCBuYW1lc3BhY2UgVVJJIGlzCi0gICAgICAgIGh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybS4gSW4gZWFjaCBYU0xUIHN0eWxlc2hlZXQsIHlvdSBtdXN0IGRlY2xhcmUgdGhpcyBuYW1lc3BhY2UgaW4gdGhlIHN0eWxlc2hlZXQgZWxlbWVudAotICAgICAgICB0YWcgYW5kIGJpbmQgaXQgdG8gYSBsb2NhbCBwcmVmaXguIExpa2UgdGhlIFhTTFQgc3BlY2lmaWNhdGlvbiwgd2UgYWx3YXlzIHVzZSB4c2wgYXMgdGhlIFhTTFQgbmFtZXNwYWNlIHByZWZpeCBpbiBvdXIKLSAgICAgICAgZGVzY3JpcHRpb25zIGFuZCBleGFtcGxlcywgYWx0aG91Z2ggeW91IGFyZSBmcmVlIHRvIGJpbmQgYW55IHByZWZpeCB0byB0aGlzIG5hbWVzcGFjZS48YnIvPjxici8+PC9pdGVtPgotICAgICAgICAKLSAgICAgICAgPGxhYmVsPlhTTCBJbnN0cnVjdGlvbjwvbGFiZWw+Ci0gICAgICAgIDxpdGVtPkFueSB0YWcgYXNzb2NpYXRlZCB3aXRoIHRoZSBYU0xUIG5hbWVzcGFjZS48YnIvPjxici8+PC9pdGVtPgotICAgICAgICAKLSAgICAgICAgPGxhYmVsPlRlbXBsYXRlPC9sYWJlbD4KLSAgICAgICAgPGl0ZW0+QW4gZWxlbWVudCwgdXN1YWxseSB3aXRoIGNoaWxkIGVsZW1lbnRzLCB0aGF0IHNwZWNpZmllcyBhICJydWxlIiBvciBzZXQgb2YgCi0gICAgICAgIGluc3RydWN0aW9ucyB0byBwZXJmb3JtIHdoZW4gYSBwYXJ0aWN1bGFyIGtpbmQgb2Ygbm9kZSBpcyBlbmNvdW50ZXJlZCBpbiB0aGUgc291cmNlIHRyZWUuPGJyLz48YnIvPjwvaXRlbT4KLSAgICAgICAgICAgICAgICAKLSAgICAgICAgPGxhYmVsPlhTTCBUZW1wbGF0ZSBJbnN0cnVjdGlvbjwvbGFiZWw+Ci0gICAgICAgIDxpdGVtPkFueSB0YWcgdGhhdCBvY2N1cnMgaW5zaWRlIGFuIHhzbDp0ZW1wbGF0ZSBlbGVtZW50IGFuZCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIFhTTFQgbmFtZXNwYWNlLjxici8+PGJyLz48L2l0ZW0+Ci0gICAgICAgICAgICAgICAgICAgCi0gICAgICAgIDxsYWJlbD5Tb3VyY2UgVHJlZTwvbGFiZWw+Ci0gICAgICAgIDxpdGVtPlRoZSBYTUwgdHJlZSBpbnB1dCB0byB0aGUgWFNMIHByb2Nlc3MuPGJyLz48YnIvPjwvaXRlbT4KLSAgICAgICAgCi0gICAgICAgIDxsYWJlbD5SZXN1bHQgVHJlZTwvbGFiZWw+Ci0gICAgICAgIDxpdGVtPlRoZSB0cmVlIHRoYXQgaXMgb3V0cHV0IGJ5IHRoZSBYU0wgcHJvY2Vzcy48YnIvPjxici8+PC9pdGVtPgotICAgICAgICAgICAgICAgIAotICAgICAgICA8bGFiZWw+TWF0Y2ggUGF0dGVybjwvbGFiZWw+Ci0gICAgICAgIDxpdGVtPlRoZSBwYXJ0IG9mIGEgdGVtcGxhdGUgdGhhdCBkZWZpbmVzIHRoZSBraW5kKHMpIG9mIG5vZGVzIHRvIHdoaWNoIHRoZSB0ZW1wbGF0ZSBhcHBsaWVzLjxici8+PGJyLz48L2l0ZW0+Ci0KLSAgICAgIDwvZ2xvc3M+Ci0gICAgICA8cD5Gb3IgbW9yZSBkZWZpbml0aW9ucyBvZiBYU0xUIHRlcm1pbm9sb2d5LCBzZWUgRGF2ZSBQYXdzb24ncyAKLSAgICAgIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cuZHBhd3Nvbi5jby51ay94c2wvdm9jYWIuaHRtbCI+WFNMVCBUZXJtaW5vbG9neQotICAgICAgQ2xhcmlmaWNhdGlvbjwvanVtcD4gYW5kIHRoZSBHbG9zc2FyeSBpbiBNaWNoYWVsIEtheSdzIAotICAgICAgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53cm94LmNvbS9Db25zdW1lci9TdG9yZS9EZXRhaWxzLmFzcD9JU0JOPTE4NjEwMDMxMjkiPlhTTFQgUHJvZ3JhbW1lcidzIFJlZmVyZW5jZTwvanVtcD4uPC9wPgotICAgIDwvczI+Ci08L3MxPiAKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveGFsYW4vcmVhZG1lLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vcmVhZG1lLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2NiZjkyYi4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL3JlYWRtZS54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyODYgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PiAKLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiWwotPCFFTlRJVFkgZG9uZS1qIFNZU1RFTSAiRE9ORSI+Ci08IUVOVElUWSB4c2x0Y3JlbGVhc2Vub3RlcyBTWVNURU0gInhzbHRjX2NvbnN0cmFpbnRzLnhtbCI+Ci0KLTwhRU5USVRZIGhpc3RvcnktaiBTWVNURU0gImhpc3RvcnkueG1sIj5dPgotCi08IS0tCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMTk5OSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzIAotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4gCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4gCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDE5OTksIExvdHVzCi0gKiBEZXZlbG9wbWVudCBDb3Jwb3JhdGlvbi4sIGh0dHA6Ly93d3cubG90dXMuY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotIC0tPgotPHMxIHRpdGxlPSJSZWxlYXNlIE5vdGVzIj4KLTxwPiZ4c2x0NGotY3VycmVudDs8L3A+Ci0gPHVsPgotICA8bGk+PGxpbmsgYW5jaG9yPSJzdGF0dXMwIj5TdGF0dXM8L2xpbms+PC9saT4meHNsdGNyZWxlYXNlbm90ZXNlbnRyeTsKLSAgPGxpPjxsaW5rIGFuY2hvcj0iYnVpbGQiPkJ1aWxkIE5vdGVzPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9ImNvbnRhY3QiPkdldHRpbmcgaW4gdG91Y2g8L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0iaGlzdG9yeSI+SGlzdG9yeSBvZiBzb2Z0d2FyZSBjaGFuZ2VzPC9saW5rPjwvbGk+Ci0gPC91bD48YW5jaG9yIG5hbWU9InN0YXR1czAiLz4KLSAgPHMyIHRpdGxlPSJTdGF0dXMiPgotICAgPHVsPgotICAgIDxsaT48bGluayBhbmNob3I9ImRvbmUiPkNoYW5nZXMgc2luY2UgdmVyc2lvbiAyLjIuRDk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJvdGhlciI+T3RoZXIgcG9pbnRzIG9mIGludGVyZXN0PC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iYnVncyI+QnVnczwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9InN0YXR1cyI+VmVyc2lvbiBvZiBYZXJjZXMgdG8gdXNlPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0idG8tZG8iPlRvLWRvIHRhc2tzIGZvciBmdXR1cmUgJnhzbHQ0ajsgcmVsZWFzZXM8L2xpbms+PC9saT4KLSAgIDwvdWw+Ci0gICAgIDxhbmNob3IgbmFtZT0iZG9uZSIvPgotICAgICA8czMgdGl0bGU9IkNoYW5nZXMgc2luY2UgJnhzbHQ0ajsgMi4yLkQ5Ij4KLSAgICAgPHA+JnhzbHQ0ai1jdXJyZW50OyBpcyBhIERldmVsb3BlciByZWxlYXNlLiBGb3IgZW5oYW5jZWQgcGVyZm9ybWFuY2UsIGl0IGluY29ycG9yYXRlcyB0aGUgCi0gICAgIDxsaW5rIGlkcmVmPSJkdG0iPkRUTTwvbGluaz4uPC9wPgotICAgICA8bm90ZT5UaGUgU1FMIEV4dGVuc2lvbiBsaWJyYXJ5IGhhcyBiZWVuIHVwZGF0ZWQgdG8gd29yayB3aXRoIERUTS48L25vdGU+Ci0gICAgICZkb25lLWo7Ci0gICAgIDwvczM+Ci0gICAgIDxhbmNob3IgbmFtZT0ib3RoZXIiLz4KLSAgICAgPHMzIHRpdGxlPSJPdGhlciBwb2ludHMgb2YgaW50ZXJlc3QiPgotICAgICA8dWw+Ci0gICAgIDxsaT5IYW5kbGluZyB4c2w6bmFtZXNwYWNlLWFsaWFzIGRlY2xhcmF0aW9uczogSW4gcmVsZWFzZSAyLjAuRDAxLCB3ZSByZXBvcnRlZCB0aGUgbmVlZCB0byBkbyBzb21lIHJlc2VhcmNoIGNvbmNlcm5pbmcgZXhhY3RseSBob3cgWGFsYW4KLSAgICAgc2hvdWxkIGhhbmRsZSB4c2w6bmFtZXNwYWNlLWFsaWFzIGRlY2xhcmF0aW9ucy4gQXMgYSByZXN1bHQgb2YgZGlzY3Vzc2lvbnMgYW1vbmcgbWVtYmVycyBvZiB0aGUgVzNDIFdvcmtpbmcgR3JvdXAgb24gWFNMLCB3ZSBoYXZlIHJlYWNoZWQgYQotICAgICBtb3JlIHByZWNpc2UgY29uc2Vuc3VzIG9uIGhvdyBuYW1lc3BhY2VzIHNob3VsZCBiZSByZXByZXNlbnRlZCB3aGVuIGFuIHhzbDpuYW1lc3BhY2UtYWxpYXMgZGVjbGFyYXRpb24gaXMgaW4gZWZmZWN0Ljxici8+PGJyLz4KLSAgICAgSWYgYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50IGhhcyBhIG5hbWVzcGFjZSBwcmVmaXgsIHRoZSBwcmVmaXggd2lsbCBiZSBwcmVzZXJ2ZWQgYW5kIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoZSBlbGVtZW50IHdpbGwgYmUgYXMKLSAgICAgc3BlY2lmaWVkIGluIHRoZSB4c2w6bmFtZXNwYWNlLWFsaWFzIGVsZW1lbnQsIGJ1dCB0aGUgcmVzdWx0LXByZWZpeCBpcyBub3QgcmVxdWlyZWQgdG8gYXBwZWFyIGluIHRoZSByZXN1bHQuIFRoaXMgYWxzbyBhcHBsaWVzIHRvIHRoZQotICAgICB0d28gb3RoZXIgY2FzZXMgb2YgIkxpdGVyYWwgbmFtZXNwYWNlIFVSSSIgbWVudGlvbmVkIGluIHRoZSBYU0xUIFJlY29tbWVuZGF0aW9uIG9uIAotICAgICA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0I2xpdGVyYWwtcmVzdWx0LWVsZW1lbnQiPkxpdGVyYWwgUmVzdWx0IEVsZW1lbnRzPC9qdW1wPi4gTW9yZSBzaW1wbHksIGlmIHRoZSBzdHlsZXNoZWV0IGNhbGxzIGZvcgotICAgICAmbHQ7YXhzbDpmb28mZ3Q7IHRvIGJlIG91dHB1dCBhcyBhIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnQsIHRoZW4gaXQgd2lsbCBiZSBvdXRwdXQgYXMgJmx0O2F4c2w6Zm9vJmd0OyBpbiB0aGUgcmVzdWx0LCBidXQgdGhlIG5hbWVzcGFjZQotICAgICBhc3NvY2lhdGVkIHdpdGggdGhpcyAiYXhzbCIgcHJlZml4IHdpbGwgYmUgYXMgZGVzaWduYXRlZCBpbiB0aGUgeHNsOm5hbWVzcGFjZS1hbGlhcyBkZWNsYXJhdGlvbi48YnIvPjxici8+PC9saT4KLSAgICAgPGxpPkZvciBIVE1MIG91dHB1dCwgJnhzbHQ0ajI7IG91dHB1dHMgY2hhcmFjdGVyIGVudGl0eSByZWZlcmVuY2VzICgmYW1wO2NvcHk7IGV0Yy4pIGZvciB0aGUgc3BlY2lhbCBjaGFyYWN0ZXJzIGRlc2lnbmF0ZWQgaW4gIAotICAgICA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94aHRtbDEvI2R0ZHMiPkFwcGVuZGl4IEEuIERURHMgb2YgdGhlIFhIVE1MIDEuMDogVGhlIEV4dGVuc2libGUgSHlwZXJUZXh0IE1hcmt1cAotICAgICBMYW5ndWFnZTwvanVtcD4uICZ4c2x0NGo7IDEueCwgb24gdGhlIG90aGVyIGhhbmQsIG91dHB1dHMgbGl0ZXJhbCBjaGFyYWN0ZXJzIGZvciBzb21lIG9mIHRoZXNlIHNwZWNpYWwgY2hhcmFjdGVycy48YnIvPjxici8+PC9saT4KLSAgICAgPGxpPkluIGNvbmZvcm1hbmNlIHdpdGggdGhlIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQjc2VjdGlvbi1IVE1MLU91dHB1dC1NZXRob2QiPlhTTFQgUmVjb21tZW5kYXRpb24gb24gdGhlIEhUTUwgCi0gICAgIE91dHB1dCBNZXRob2Q8L2p1bXA+IGFuZCA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL2FwcGVuZGl4L25vdGVzLmh0bWwjaC1CLjIuMSI+U2VjdGlvbiBCLjIuMSBvZiB0aGUgSFRNTCA0LjAKLSAgICAgUmVjb21tZW5kYXRpb248L2p1bXA+LCAmeHNsdDRqMjsgdXNlcyAlaGggZW5jb2RpbmcgZm9yIGVhY2ggYnl0ZSBvZiB0aGUgVVRGLTggcmVwcmVzZW50YXRpb24gb2Ygbm9uLUFTQ0lJIGNoYXJhY3RlcnMgaW4gSFRNTCBVUkkKLSAgICAgYXR0cmlidXRlcy48YnIvPjxici8+PC9saT4KLSAgICAgPGxpPldoZW4geW91ciBzdHlsZXNoZWV0IGFza3MgZm9yIGFuIGV4cGxpY2l0IGNhcnJpYWdlLXJldHVybiBjaGFyYWN0ZXIgKCZhbXA7IzEzOykgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgb3V0cHV0LCBpdCBpcyBvdXRwdXQgZHVyaW5nCi0gICAgIHRoZSBzZXJpYWxpemF0aW9uIHByb2Nlc3MgaW4gZXNjYXBlZCBmb3JtIHVubGVzcyBlc2NhcGluZyBoYXMgYmVlbiBkaXNhYmxlZC4gIFdoZW4geW91ciBzdHlsZXNoZWV0IGFza3MgZm9yIGFuIGV4cGxpY2l0IGxpbmUtZmVlZCBjaGFyYWN0ZXIKLSAgICAgKCZhbXA7IzEwOykgdG8gYmUgb3V0cHV0LCB0aGUgc3lzdGVtLWRlZmF1bHQgbGluZS1icmVhayBjaGFyYWN0ZXIocykgaXMvYXJlIG91dHB1dCBkdXJpbmcgdGhlIHNlcmlhbGl6YXRpb24gcHJvY2Vzcy4gIEFsc28ga2VlcCBpbiBtaW5kIHRoYXQKLSAgICAgdGhlIFhNTCBwYXJzZXIgbm9ybWFsaXplcyBsaW5lLWJyZWFrcyB0byBsaW5lLWZlZWRzIHdoZW4gaXQgc2VuZHMgY2hhcmFjdGVyIGV2ZW50cyB0byB0aGUgcHJvY2Vzc29yLjxici8+PGJyLz48L2xpPgotICAgICA8bGk+SWYgeW91ciBYTUwgaW5wdXQgaXMgYSBET00sIHVzZSB0aGUgamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBzZXRDb2FsZXNjaW5nKCkgbWV0aG9kIHRvIHNldCBjb2FsZXNjaW5nIHRvIHRydWUgKGl0IGlzCi0gICAgIGZhbHNlIGJ5IGRlZmF1bHQpLCBpZiB5b3Ugd2FudCB0byBhcHBlbmQgQ0RBVEEgc2VjdGlvbnMgdG8gYWRqYWNlbnQgdGV4dCBzZWN0aW9ucyB0byBmb3JtIGEgc2luZ2xlIHRleHQgbm9kZSAoYXMgdGhlIFhQYXRoIHN0YW5kYXJkIGNhbGxzCi0gICAgICBmb3IpLCBhbmQgaWYgdGhlIFhNTCBwYXJzZXIgc3VwcG9ydHMgdGhpcyBmZWF0dXJlICgmeG1sNGotdXNlZDsgZG9lcyBub3QpLjwvbGk+Ci0gICAgIDwvdWw+Ci0gICAgIDwvczM+PGFuY2hvciBuYW1lPSJidWdzIi8+Ci0gICAgIDxzMyB0aXRsZT0iQnVncyI+Ci0gICAgIDxwPkFsbCBrbm93biAmeHNsdDRqOyBidWdzIGFyZSBsaXN0ZWQgaW4gPHJlc291cmNlLXJlZiBpZHJlZj0iYnVnemlsbGEiLz4uIEZvciBhIGxpc3Qgb2Ygb3BlbiBidWdzIHdpdGggbGlua3MgdG8gZWFjaCBidWcKLSAgICAgIHJlcG9ydCwgc2VlIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImJ1Z2xpc3QiLz4uIElmIHlvdSBmaW5kIGEgbmV3IGJ1ZywgcGxlYXNlIGVudGVyIGEgWGFsYW5KMiBidWcgcmVwb3J0IGluIHRoaXMKLSAgICAgIGRhdGFiYXNlLjwvcD4KLSAgICAgPG5vdGU+QmVmb3JlIHlvdSBjYW4gZW50ZXIgeW91ciBmaXJzdCBidWcgcmVwb3J0LCB5b3UgbXVzdCBzdWJtaXQgeW91ciBlbWFpbCBhZGRyZXNzIHRvIEJ1Z3ppbGxhIGFuZCByZWNlaXZlIGEgcGFzc3dvcmQuPC9ub3RlPiAKLSAgICAgPHA+V2Ugc3Ryb25nbHkgZW5jb3VyYWdlIHlvdSB3cml0ZSBwYXRjaGVzIGZvciBwcm9ibGVtcyB5b3UgZmluZCBhbmQgc3VibWl0IHRoZW0gdG8KLSAgICAgIHhhbGFuLWRldkB4bWwuYXBhY2hlLm9yZy4gV2UgcmV2aWV3IHRoZSBwYXRjaGVzIHdlIHJlY2VpdmUgdG8gbWFrZSBzdXJlIHRoZXkgZG8gbm90IGJyZWFrIHNvbWV0aGluZyBlbHNlLCBhbmQgKGFzc3VtaW5nIHRoZXkgCi0gICAgIGRvIG5vdCkgaW5jbHVkZSB0aGVtIGluIG91ciBuZXh0IHJlbGVhc2UuIEluIHRoZSBpbnRlcmVzdCBvZiBmaXhpbmcgYnVncywgYWRkaW5nIGVuaGFuY2VtZW50cywgYW5kIGFkZHJlc3Npbmcgb3V0c3RhbmRpbmcgZGVzaWduCi0gICAgIGlzc3Vlcywgd2Ugc2luY2VyZWx5IHdhbnQgKGFuZCBuZWVkISkgeW91ciBhY3RpdmUgcGFydGljaXBhdGlvbiBpbiB0aGUgb25nb2luZyBkZXZlbG9wbWVudCBvZiBYYWxhbi48L3A+Ci0gICAgIDwvczM+ICAgICAKLSAgICAgPGFuY2hvciBuYW1lPSJzdGF0dXMiLz4KLSAgICAgPHMzIHRpdGxlPSJWZXJzaW9uIG9mIFhlcmNlcyB0byB1c2UiPiAKLSAgICAgICA8cD5UaGUgJnhzbHQ0ai1jdXJyZW50OyBoYXMgYmVlbiB0ZXN0ZWQgd2l0aCAmeG1sNGotdXNlZDsuICZkb3dubG9hZDsgRm9yIGluZm9ybWF0aW9uIGFib3V0IGluY2x1ZGluZyB4ZXJjZXMuamFyIG9uIHRoZSBzeXN0ZW0gY2xhc3MgcGF0aCwgc2VlIDxsaW5rIGlkcmVmPSJnZXRzdGFydGVkIiBhbmNob3I9ImNsYXNzcGF0aCI+U2V0dGluZyB1cCB0aGUgc3lzdGVtIGNsYXNzIHBhdGg8L2xpbms+LjwvcD4KLSAgICAgICA8cD48ZW0+SW1wb3J0YW50PC9lbT4gWW91IG1heSBleHBlcmllbmNlIHVucHJlZGljdGFibGUgYW5vbWFsaWVzIGlmIHlvdXIgWGFsYW4gYW5kIFhlcmNlcyBidWlsZHMgYXJlIG5vdCBpbiBzeW5jaC4gSWYgeW91IGRvd25sb2FkIGFuIHVwZGF0ZSB0byBYYWxhbiwgY2hlY2sgdGhlIHJlbGVhc2Ugbm90ZXMgdG8gZGV0ZXJtaW5lIHdoaWNoIHZlcnNpb24gb2YgWGVyY2VzIHlvdSBzaG91bGQgdXNlLjwvcD4KLSAgICAgICA8bm90ZT5Zb3UgY2FuIHVzZSBYYWxhbiB3aXRoIG90aGVyIFhNTCBwYXJzZXJzIHRoYXQgaW1wbGVtZW50IHRoZSA8cmVzb3VyY2UtcmVmIGlkcmVmPSJqYXhwIi8+LiBTZWUgCi0gICAgICAgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0icGx1ZyI+UGx1Z2dpbmcgaW4gdGhlIFRyYW5zZm9ybWVyIGFuZCBYTUwgcGFyc2VyPC9saW5rPi48L25vdGU+Ci0gICAgIDwvczM+Ci0gICAgIDxhbmNob3IgbmFtZT0idG8tZG8iLz4KLSAgICAgPHMzIHRpdGxlPSJUby1kbyB0YXNrcyI+Ci0gICAgICAgPHA+Rm9yIGEgbGlzdCBvZiBnb2FscywgdGFza3MsIGFuZCB0YXJnZXQgZGF0ZXMgZm9yIGNvbXBsZXRpb24sIHNlZSA8anVtcCBocmVmPSJ0b2RvLmh0bWwiPlhhbGFuLUphdmEgVmVyc2lvbiAyOiBUaGluZ3MgVG8gRG88L2p1bXA+LiAKLSAgICAgICBBcyB0YXNrcyBhcmUgY29tcGxldGVkLCB0aGV5IGFyZSBtb3ZlZCBmcm9tIHRoZSB0by1kbyBsaXN0IHRvIAotICAgICAgIDxqdW1wIGhyZWY9InRvZG8uaHRtbCNyZWxlYXNlLWRhdGUtY29tcGxldGVkIj5Db21wbGV0ZWQ8L2p1bXA+LjwvcD4KLSAgICAgICA8cD5UaGUgc291cmNlIGRvY3VtZW50IGZvciB0aGUgdG8tZG8gbGlzdCBpcyBhbiBhY3RpdmUgZG9jdW1lbnQgaW4gdGhlIEFwYWNoZSBDVlMgcmVwb3NpdG9yeTogCi0gICAgICAgPGp1bXAgaHJlZj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3dlYnNyYy9jdnN3ZWIuY2dpL3htbC14YWxhbi9qYXZhL3RvZG8ueG1sIj54bWwteGFsYW4vamF2YS90b2RvLnhtbDwvanVtcD4uPC9wPgotICAgICAgPC9zMz4gCi0gIDwvczI+Ci0gICAgJnhzbHRjcmVsZWFzZW5vdGVzOyAgCi0gIDxhbmNob3IgbmFtZT0iYnVpbGQiLz4gIAotICA8czIgdGl0bGU9IkJ1aWxkIE5vdGVzIj4KLTx1bD4KLTxsaT48bGluayBhbmNob3I9ImFudCI+VXNpbmcgQW50PC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJqYXIiPlJlYnVpbGRpbmcgeGFsYW4uamFyPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJzYW1wbGVzIj5SZWJ1aWxkaW5nIHNhbXBsZSBhcHBsaWNhdGlvbnM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImRvYyI+UmVidWlsZGluZyB0aGUgJnhzbHQ0ajsgZG9jdW1lbnRhdGlvbjwvbGluaz48L2xpPgotPC91bD4KLTxhbmNob3IgbmFtZT0iYW50Ii8+Ci0gICA8czMgdGl0bGU9IlVzaW5nIEFudCI+Ci0gICAgIDxwPkFwYWNoZSA8cmVzb3VyY2UtcmVmIGlkcmVmPSJhbnQiLz4gaXMgYSBmbGV4aWJsZSwgcG93ZXJmdWwsIGFuZCBlYXN5LXRvLXVzZSBKYXZhIGJ1aWxkIHRvb2wgdGhhdCB3ZSBpbmNsdWRlIHdpdGggdGhlCi0gICAgICZ4c2x0NGo7IGRpc3RyaWJ1dGlvbi4gVGhlIEFudCBKQVIgZmlsZSBpcyBpbiB0aGUgYmluIGRpcmVjdG9yeSwgYW5kIHRoZSBjcm9zcy1wbGF0Zm9ybSBYTUwgYnVpbGQgZmlsZSAoYnVpbGQueG1sKSBpcyBpbiAKLSAgICAgdGhlIHJvb3QgZGlyZWN0b3J5IGFsb25nIHdpdGggYSBXaW5kb3dzMzIgYmF0Y2ggZmlsZSAoYnVpbGQuYmF0KSBhbmQgYSBVTklYIHNoZWxsIGZpbGUgKGJ1aWxkLnNoKS4gVGhlIGJ1aWxkIGZpbGUgZGVmaW5lcyAKLSAgICAgdGhlICJ0YXJnZXRzIiB0aGF0IHlvdSBjYW4gdXNlIEFudCB0byBidWlsZC4gVGhlIGJhdGNoIGFuZCBzaGVsbCBmaWxlcyBzZXQgdXAgdGhlIGNsYXNzcGF0aCBhbmQgbGF1bmNoIEFudCB3aXRoIHRoZSB0YXJnZXQgCi0gICAgIChhbmQgYW55IG90aGVyIGFyZ3VtZW50cykgeW91IHByb3ZpZGUuPC9wPgotICAgICA8cD48ZW0+SW5zdHJ1Y3Rpb25zIGZvciB1c2luZyBBbnQ8L2VtPjwvcD4KLSAgICAgPG9sPgotICAgICAgIDxsaT5TZXQgdGhlIEpBVkFfSE9NRSBlbnZpcm9ubWVudCB2YXJpYWJsZSB0byB0aGUgSkRLIHJvb3QgZGlyZWN0b3J5Ljxici8+PGJyLz4KLSAgICAgICBJZiB5b3UgYXJlIHVzaW5nIEpESyAxLjEuOCwgeW91IG11c3QgYWxzbyBwdXQgY2xhc3Nlcy56aXAgaW4gdGhlIEpESyBiaW4gZGlyZWN0b3J5IG9uIHRoZSBjbGFzc3BhdGguIFlvdSBjYW4gdXNlIEFudCAKLSAgICAgICB3aXRoIEpESyAxLjEuOCB0byBjb21waWxlIGFuZCBqYXIgdGhlICZ4c2x0NGo7IHNvdXJjZSBmaWxlcywgYnV0IHlvdSBtdXN0IGhhdmUgSkRLIDEuMi4yIG9yIGhpZ2hlciB0byBidWlsZCB0aGUKLSAgICAgICBkb2N1bWVudGF0aW9uLjxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5EZXBlbmRpbmcgb24geW91ciBlbnZpcm9ubWVudCwgcnVuIHRoZSBiYXRjaCBmaWxlIChidWlsZC5iYXQpIG9yIHNoZWxsIGZpbGUgKGJ1aWxkLnNoKSBmcm9tIHRoZSAmeHNsdDRqOyByb290Ci0gICAgICAgZGlyZWN0b3J5LCBvcHRpb25hbGx5IHdpdGggYXJndW1lbnRzIChzZWUgdGhlIHRhYmxlIG9mIHRhcmdldHMgYmVsb3cpLjxici8+PGJyLz4KLSAgICAgICBUaGUgYmF0Y2gvc2hlbGwgZmlsZSBhZGRzIHNldmVyYWwgSkFSIGZpbGVzIHRvIHRoZSBjbGFzc3BhdGggYW5kIGxhdW5jaGVzIEFudCB3aXRoIGFueSBhcmd1bWVudHMgeW91IHByb3ZpZGUuIElmIHlvdQotICAgICAgIHByb3ZpZGUgbm8gdGFyZ2V0LCBBbnQgY29tcGlsZXMgdGhlIHNvdXJjZSBmaWxlcyBhbmQgcmVidWlsZHMgeGFsYW4uamFyICh0aGUgImphciIgdGFyZ2V0KS48L2xpPgotICAgICA8L29sPgotICAgICA8cD5Zb3UgY2FuIGFsc28gc2V0IHVwIHlvdXIgY2xhc3NwYXRoIG1hbnVhbGx5IChzZWUgYnVpbGQuYmF0IG9yIGJ1aWxkLnNoIGZvciB0aGUgZGV0YWlscyksIGFuZCB0aGVuIHJ1biBBbnQgYXMKLSAgICAgZm9sbG93czo8YnIvPjxici8+Ci0gICAgIDxjb2RlPmphdmEgb3JnLmFwYWNoZS50b29scy5hbnQuTWFpbiA8cmVmPnRhcmdldDwvcmVmPjwvY29kZT48YnIvPjxici8+Ci0gICAgIHdoZXJlIDxyZWY+dGFyZ2V0PC9yZWY+IGlzIG5vdGhpbmcgKGZvciB0aGUgZGVmYXVsdCB0YXJnZXQpIG9yIG9uZSBvZiB0aGUgZm9sbG93aW5nLjwvcD4KLSAgICAgPHRhYmxlPgotICAgICAgIDx0cj48dGQ+PGVtPlRhcmdldDwvZW0+PC90ZD48dGQ+PGVtPldoYXQgQW50IGRvZXM8L2VtPjwvdGQ+PC90cj4KLSAgICAgICA8dHI+PHRkPmNvbXBpbGU8L3RkPjx0ZD5jb21waWxlcyBYYWxhbi1KYXZhIGluIGJ1aWxkL2NsYXNzZXMuPC90ZD48L3RyPgotICAgICAgIDx0cj48dGQ+amFyICh0aGUgZGVmYXVsdCk8L3RkPjx0ZD5jcmVhdGVzIHhhbGFuLmphciBpbiB0aGUgYnVpbGQgZGlyZWN0b3J5PC90ZD48L3RyPgotICAgICAgIDx0cj48dGQ+c2FtcGxlczwvdGQ+PHRkPmNvbXBpbGVzIGFuZCBqYXJzIHRoZSBzYW1wbGUgYXBwcyBpbiBidWlsZC94YWxhbnNhbXBsZXMuamFyPC90ZD48L3RyPgotICAgICAgIDx0cj48dGQ+c2VydmxldDwvdGQ+PHRkPmNvbXBpbGVzIGFuZCBqYXJzIHRoZSBzYW1wbGUgc2VydmxldCBpbiBidWlsZC94YWxhbnNlcnZsZXQuamFyPC90ZD48L3RyPiAgICAgICAKLSAgICAgICA8dHI+PHRkPmRvY3M8L3RkPjx0ZD5jcmVhdGVzIHRoZSBIVE1MIFVzZXIncyBHdWlkZSBpbiBidWlsZC9kb2NzPC90ZD48L3RyPgotICAgICAgIDx0cj48dGQ+amF2YWRvY3M8L3RkPjx0ZD5nZW5lcmF0ZXMgdGhlIEFQSSBkb2N1bWVudGF0aW9uIGluIC4vYnVpbGQvZG9jcy9hcGlkb2NzPC90ZD48L3RyPgotICAgICAgIDx0cj48dGQ+ZGlzdDwvdGQ+PHRkPmdlbmVyYXRlcyBhIGNvbXBsZXRlIGRpc3RyaWJ1dGlvbiB0cmVlIHdpdGggemlwIGFuZCB0YXIuZ3ogZGlzdHJpYnV0aW9uIGZpbGVzIGluIGJ1aWxkPC90ZD48L3RyPgotICAgICAgIDx0cj48dGQ+Y2xlYW48L3RkPjx0ZD5wdXJnZXMgdGhlIGJ1aWxkIGFuZCBkaXN0cmlidXRpb248L3RkPjwvdHI+IAotICA8L3RhYmxlPgotICA8cD5JZiB5b3UgYnVpbGQgYSB0YXJnZXQgdGhhdCBkZXBlbmRzIG9uIG90aGVyIHRhcmdldHMsIEFudCBjcmVhdGVzIHRob3NlIG90aGVyIHRhcmdldHMgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuPC9wPgotICAgPC9zMz48YW5jaG9yIG5hbWU9ImphciIvPiAKLSAgIDxzMyB0aXRsZT0iUmVidWlsZGluZyAmeHNsdDRqOyI+Ci0gICAgIDxwPlRoZSAmeHNsdDRqOyBidWlsZCBpcyBpbiB4YWxhbi5qYXIuIFRoZSAmeHNsdDRqOyBzb3VyY2UgY29kZSB0cmVlIGlzIGluIHRoZSBzcmMgZGlyZWN0b3J5LjwvcD4KLSAgICAgPHA+SWYgeW91IGFyZSB1c2luZyBBbnQsIHRoZSB0YXJnZXQgaXMgamFyICh0aGUgZGVmYXVsdCkuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgPGxpbmsgYW5jaG9yPSJhbnQiPlVzaW5nCi0gICAgIEFudDwvbGluaz4uPC9wPgotICAgICA8cD5JZiB5b3Ugd2FudCB0byBkbyB0aGUgYnVpbGQgd2l0aG91dCBBbnQsIGtlZXAgdGhlIGZvbGxvd2luZyBpbiBtaW5kOjwvcD4KLSAgICAgPHVsPgotICAgICA8bGk+U2V0IHRoZSBjbGFzc3BhdGggdG8gaW5jbHVkZSB0aGUgc3JjIGRpcmVjdG9yeSwgeGVyY2VzLmphciwgYnNmLmphciwgYW5kIGJzZmVuZ2luZXMuamFyLjwvbGk+Ci0gICAgIDxsaT5Vc2UgYSBKYXZhIGNvbXBpbGVyIChzdWNoIGFzIHRoZSBJQk0gSnVzdC1Jbi1UaW1lIGNvbXBpbGVyIG9yIHRoZSBTdW4gamF2YWMpIHRvIGNvbXBpbGUgYWxsIHRoZSAuamF2YSBmaWxlcyBpbiB0aGUgc3JjCi0gICAgIHRyZWUuIDwvbGk+Ci0gICAgIDxsaT5Vc2UgdGhlIFN1biBqYXIgdXRpbGl0eSB0byBzdG9yZSB0aGUgcmVzdWx0aW5nIC5jbGFzcyBmaWxlcyBpbiB4YWxhbi5qYXI8L2xpPgotICAgICA8L3VsPgotICAgPC9zMz48YW5jaG9yIG5hbWU9InNhbXBsZXMiLz4KLSAgIDxzMyB0aXRsZT0iUmVidWlsZGluZyBhIHNhbXBsZSBhcHBsaWNhdGlvbiI+Ci0gICA8cD5JZiB5b3UgbW9kaWZ5IGEgc2FtcGxlIGFuZCB3YW50IHRvIHJlY29tcGlsZSBpdCwgeW91IGNhbiBydW4gdGhlIEphdmEgY29tcGlsZXIgaW4gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZQotICAgZXhhbXBsZS4gQmUgc3VyZSB4YWxhbi5qYXIgYW5kIHhlcmNlcy5qYXIgYXJlIG9uIHRoZSBjbGFzc3BhdGguIFRvIHJlY29tcGlsZSAoYW5kIHJ1biEpIHRoZSBjbGFzcyBmaWxlcyBpbiB0aGUKLSAgIFNlcnZsZXQgc3ViZGlyZWN0b3J5LCB0aGUgamF2YXguc2VydmxldCBhbmQgamF2YXguc2VydmxldC5odHRwIHBhY2thZ2VzIG11c3QgYWxzbyBiZSBvbiB0aGUgY2xhc3NwYXRoLiBTdW4KLSAgIGRpc3RyaWJ1dGVzIHRoZXNlIHBhY2thZ2VzIGluIHRoZSBKU1dESyAxLjAuMSBzZXJ2bGV0LmphciBmaWxlLjwvcD4gCi0gICA8cD5BZnRlciByZWNvbXBpbGluZyBhIHNhbXBsZSwgeW91IGNhbiB1c2UgdGhlIFN1biBqYXIgdXRpbGl0eSB0byBwbGFjZSB5b3VyIG5ldyAuY2xhc3MgZmlsZXMgaW4KLSAgICB4YWxhbnNhbXBsZXMuamFyLjwvcD4KLSAgICA8cD5Zb3UgY2FuIHVzZSBBbnQgd2l0aCB0aGUgc2FtcGxlcyB0YXJnZXQgdG8gcmVjb21waWxlIHRoZSBzYW1wbGVzIGFuZCBwbGFjZSB0aGUgdW5wYWNrYWdlZCBjbGFzcyBmaWxlcyBpbiB4YWxhbnNhbXBsZXMuamFyLgotICAgICBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxsaW5rIGFuY2hvcj0iYW50Ij5Vc2luZyBBbnQ8L2xpbms+LjwvcD4KLSAgICA8bm90ZT5UbyByZWJ1aWxkIChhbmQgdG8gcnVuKSB0aGUgc2FtcGxlIHNlcnZsZXQsIHRoZSBqYXZheC5zZXJ2bGV0IGFuZCBqYXZheC5zZXJ2bGV0Lmh0dHAgcGFja2FnZXMgbXVzdCBiZSBvbiB5b3VyCi0gICAgY2xhc3NwYXRoLjwvbm90ZT4KLSAgIDwvczM+PGFuY2hvciBuYW1lPSJkb2MiLz4KLSAgIDxzMyB0aXRsZT0iUmVidWlsZGluZyB0aGUgJnhzbHQ0ajsgZG9jdW1lbnRhdGlvbiI+Ci0gICAgIDxwPiZ4c2x0NGo7IGluY2x1ZGVzIGEgbnVtYmVyIG9mIFhNTCBzb3VyY2UgZmlsZXMsIFhTTCBzdHlsZXNoZWV0cywgZG9jdW1lbnQgdHlwZSBkZWZpbml0aW9uIChEVEQpCi0gICAgICBmaWxlcywgZW50aXR5IHJlbGF0aW9uc2hpcCAoRU5UKSBmaWxlcywgZ3JhcGhpY3MsIGFuZCBhIEphdmFTY3JpcHQgZmlsZSB0aGF0IHByb3ZpZGUgdGhlIGlucHV0IGZvciB0aGUgWGFsYW4KLSAgICAgIEhUTUwgVXNlcidzIEd1aWRlLCBhbmQgdGhlIG92ZXJ2aWV3IGFuZCBwYWNrYWdlLWxldmVsIGRvY3VtZW50cyB1c2VkIGR1cmluZyB0aGUgZ2VuZXJhdGlvbiBvZiBKYXZhZG9jLjwvcD4KLSAgICAgIDxwPlRvIHJlYnVpbGQgdGhlIGRvY3VtZW50YXRpb24sIHlvdSBtdXN0IHVzZSB0aGUgU3R5bGVCb29rIHRvb2wgYW5kIHRoZSBKREsgMS4yLjIgamF2YSBhbmQgamF2YWRvYwotICAgICAgdG9vbHMuIFN0eWxlQm9vayAod2hpY2ggdXNlcyBYYWxhbiBhbmQgWGVyY2VzKSBpcyBpbiBzdHlsZWJvb2stMS4wLWIyLmphci4gU29tZSBvZiB0aGUgZG9jdW1lbnQgZGVmaW5pdGlvbiBmaWxlcywKLSAgICAgIHN0eWxlc2hlZXRzLCBhbmQgcmVzb3VyY2VzIGFyZSBzdG9yZWQgaW4geG1sLXNpdGUtc3R5bGUudGFyLmd6LCBhbmQgYXJlIHVuemlwcGVkIHdoZW4geW91IHJ1biBBbnQgYXMgZGVzY3JpYmVkCi0gICAgICAgYmVsb3cuPC9wPgotICAgICAgPHA+WW91IGNhbiB1c2UgQW50IHdpdGggdGhlIGRvY3MgdGFyZ2V0IHRvIHJlZ2VuZXJhdGUgdGhlIFVzZXIncyBHdWlkZSBhbmQgd2l0aCB0aGUgamF2YWRvY3MgdGFyZ2V0IHRvIHJlZ2VuZXJhdGUgdGhlCi0gICAgICBKYXZhZG9jIEFQSSBkb2N1bWVudGF0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxsaW5rIGFuY2hvcj0iYW50Ij5Vc2luZyBBbnQ8L2xpbms+LjwvcD4KLSAgICAgIDxwPklmIHlvdSB3YW50IHRvIHJlYnVpbGQgdGhlIGRvY3VtZW50YXRpb24gd2l0aG91dCB1c2luZyBBbnQsIGtlZXAgdGhlIGZvbGxvd2luZyBpbiBtaW5kOjwvcD4KLSAgICAgICA8dWw+Ci0gICAgICAgPGxpPlVuemlwIHhtbC1zaXRlLXN0eWxlLnRhci5neiBpbnRvIHRoZSB4ZG9jcyBkaXJlY3RvcnkgKHRoZSBvcGVyYXRpb24gcGxhY2VzIGZpbGVzIGluIGEgbnVtYmVyIG9mIHN1YmRpcmVjdG9yaWVzKS4KLSAgICAgICA8YnIvPjxici8+PC9saT4KLSAgICAgICA8bGk+QmUgc3VyZSBzdHlsZWJvb2stMS4wLWIyLmphciwgeGFsYW5qZG9jLmphciwgeGFsYW4uamFyLCBic2YuamFyLCBic2ZlbmdpbmVzLmphciwgYW5kIHhlcmNlcy5qYXIgYXJlIG9uIHRoZSBjbGFzcwotICAgICAgIHBhdGguPGJyLz48YnIvPjwvbGk+Ci0gICAgICAgPGxpPlRvIGJ1aWxkIGRvYyBpbiBhIGJ1aWxkL2RvY3Mgc3ViZGlyZWN0b3J5LCBydW4gU3R5bGVCb29rIGZyb20gdGhlIHhkb2NzIGRpcmVjdG9yeSBhcyBmb2xsb3dzOjxici8+PGJyLz4KLSAgICAgICA8Y29kZT5qYXZhIG9yZy5hcGFjaGUuc3R5bGVib29rLlN0eWxlQm9vayAidGFyZ2V0RGlyZWN0b3J5PS4uL2J1aWxkL2RvY3MvIiBzb3VyY2VzL3hhbGFuTG9jYWwueG1sIHN0eWxlPC9jb2RlPgotICAgICAgIDxici8+PGJyLz48L2xpPgotICAgICAgIDxsaT5UbyBidWlsZCB0aGUgSFRNTCBzb3VyY2UgZmlsZXMgdGhhdCBqYXZhZG9jIG5lZWRzIGZvciB0aGUgVHJBWCB0b3AtbGV2ZWwgYW5kIHBhY2thZ2UtbGV2ZWwgZG9jdW1lbnRhdGlvbiwgYWRkCi0gICAgICAgYSBidWlsZC9kb2NzL2FwZGlkb2NzL2phdmF4L3htbC90cmFuc2Zvcm0gZGlyZWN0b3J5IGFuZCBydW4gdGhlIFhhbGFuIGNvbW1hbmQtbGluZSB1dGlsaXR5IGZyb20gdGhlIHhkb2NzIGRpcmVjdG9yeSAKLSAgICAgICBhcyBmb2xsb3dzIChhbGwgb25lIGxpbmUpOjxici8+PGJyLz4KLTxjb2RlPgotamF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyAKLSAgLWluIHNvdXJjZXMvdHJheC90cmF4LnhtbAotICAtcGFyYW0gcGFja2FnZS1yb290ICcuLi8uLi8uLi9zcmMvJwotICAteHNsIHN0eWxlL3N0eWxlc2hlZXRzL3NwZWMueHNsIAotICAtb3V0IGJ1aWxkL2RvY3MvYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3RyYXguaHRtbDwvY29kZT48YnIvPjxici8+PC9saT4KLSAgICAgICAgPGxpPkJlZm9yZSB5b3UgcnVuIGphdmFkb2MsIG1ha2Ugc3VyZSB0aGUgZm9sbG93aW5nIGRpcmVjdG9yeSBzdHJ1Y3R1cmUgZXhpc3RzIHVuZGVyIHRoZSBYYWxhbiByb290Ci0gICAgICAgICBkaXJlY3Rvcnk6IGJ1aWxkL2RvY3MvYXBpZG9jcy48YnIvPjxici8+PC9saT4KLSAgICAgICA8bGk+VG8gYnVpbGQgdGhlIEFQSSBkb2N1bWVudGF0aW9uLCBydW4gdGhlIEpESyAxLjIuMiBqYXZhZG9jIHRvb2wgZnJvbSB0aGUgeGRvY3MgZGlyZWN0b3J5IChhbGwgb25lIGxpbmUpOjxici8+PGJyLz4KLTxjb2RlPgotamF2YWRvYyAtZG9jbGV0IHhhbGFuamRvYy5TdGFuZGFyZCAKLSAtZG9jbGV0cGF0aCAuLi9iaW4veGFsYW5qZG9jLmphciAKLSAtcHJpdmF0ZQotIC1vdmVydmlldyAuLi9zcmMvamF2YWRvY092ZXJ2aWV3Lmh0bWwgLXNvdXJjZXBhdGggLi4vc3JjIAotIC1ncm91cCBUckFYICJqYXZheC54bWwudHJhbnNmb3JtKiIgCi0gLWdyb3VwIFhhbGFuX0NvcmUgIm9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yOgotICAgICAgICBvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlczoKLSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyIgotIC1ncm91cCBYUGF0aCAib3JnLmFwYWNoZS54cGF0aCoiCi0gLWdyb3VwIFV0aWxpdGllcyAib3JnLmFwYWNoZS54bWwudXRpbHMqIgotIC1ncm91cCBYYWxhbl9PdGhlciAib3JnLmFwYWNoZS54YWxhbi5jbGllbnQ6Ci0gICAgICAgIG9yZy5hcGFjaGUueGFsYW4uZHRtOgotIG9yZy5hcGFjaGUueGFsYW4uZXh0ZW5zaW9uczpvcmcuYXBhY2hlLnhhbGFuLnJlczoKLSBvcmcuYXBhY2hlLnhhbGFuLnN0cmVlOm9yZy5hcGFjaGUueGFsYW4udHJhY2U6Ci0gb3JnLmFwYWNoZS54YWxhbi54c2x0IiAKLSAtZ3JvdXAgWGFsYW5fRXh0ZW5zaW9ucyAib3JnLmFwYWNoZS54YWxhbi5saWIqIiAKLSAtZ3JvdXAgU2VyaWFsaXplcnMgIm9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplIiAKLSBvcmcuYXBhY2hlLnhhbGFuLmNsaWVudCBvcmcuYXBhY2hlLnhhbGFuLmR0bSAKLSBvcmcuYXBhY2hlLnhhbGFuLmV4dGVuc2lvbnMgb3JnLmFwYWNoZS54YWxhbi5saWIgCi0gb3JnLmFwYWNoZS54YWxhbi5saWIuc3FsIG9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yIAotIG9yZy5hcGFjaGUueGFsYW4ucmVzIG9yZy5hcGFjaGUueGFsYW4uc3RyZWUgCi0gb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMgb3JnLmFwYWNoZS54YWxhbi50cmFjZSAKLSBvcmcuYXBhY2hlLnhhbGFuLnRyYW5zZm9ybWVyIG9yZy5hcGFjaGUueGFsYW4ueHNsdCAKLSBvcmcuYXBhY2hlLnhwYXRoIG9yZy5hcGFjaGUueHBhdGguYXhlcyAKLSBvcmcuYXBhY2hlLnhwYXRoLmNvbXBpbGVyIG9yZy5hcGFjaGUueHBhdGguZnVuY3Rpb25zIAotIG9yZy5hcGFjaGUueHBhdGgub2JqZWN0cyBvcmcuYXBhY2hlLnhwYXRoLm9wZXJhdGlvbnMgCi0gb3JnLmFwYWNoZS54cGF0aC5wYXR0ZXJucyBvcmcuYXBhY2hlLnhwYXRoLnJlcwotIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplIGphdmF4LnhtbC50cmFuc2Zvcm0gIAotIGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4IAotIGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtIGphdmF4LnhtbC5wYXJzZXJzCi0gLWQgLi4vYnVpbGQvZG9jcy9hcGlkb2NzIC13aW5kb3d0aXRsZSAiWGFsYW4tSmF2YSAyIiAKLSAtZG9jdGl0bGUgIlhhbGFuLUphdmEgMiIgLWJvdHRvbSAiQ29weXJpZ2h0ICYjMTY5OyAKLSAgMjAwMCBBcGFjaGUgWE1MIFByb2plY3QuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIgotPC9jb2RlPjwvbGk+Ci08L3VsPgotICA8L3MzPiAgICAKLSA8L3MyPjxhbmNob3IgbmFtZT0iY29udGFjdCIvPgotIDxzMiB0aXRsZT0iR2V0dGluZyBpbiBUb3VjaCI+Ci0gIDxwPllvdXIgZmVlZGJhY2sgaXMgbW9yZSB0aGFuIHdlbGNvbWUuIE9mZmVycyBvZiBoZWxwIGFyZSBldmVuIG1vcmUgc28hIFBlcmhhcHMgeW91IHdvdWxkIGxpa2UgdG8gdGFrZSBvbiBhbiBhY3RpdmUgcm9sZSBpbiB0aGUgb25nb2luZyBkZXZlbG9wbWVudCwgdGVzdGluZywgYW5kIGRvY3VtZW50YXRpb24gb2YgJnhzbHQ0ajs/PC9wPiAKLTxwPlBsZWFzZSBlbWFpbCB5b3VyIGNvbW1lbnRzLCBxdWVzdGlvbnMsIHN1Z2dlc3Rpb25zLCBhbmQgb2ZmZXJzIHRvIGpvaW4gdGhlIFhhbGFuIHRlYW0gdG8gPGh1bWFuLXJlc291cmNlLXJlZiBpZHJlZj0ieGFsYW5kZXYiLz4uPC9wPgotIDwvczI+PGFuY2hvciBuYW1lPSJoaXN0b3J5Ii8+Ci0gPHMyIHRpdGxlPSJDdW11bGF0aXZlIGhpc3Rvcnkgb2Ygc29mdHdhcmUgY2hhbmdlcyI+Ci0gICA8cD5UaGUgZm9sbG93aW5nIHNlY3Rpb25zIGxpc3QgdGhlIGNoYW5nZXMgaW4gZWFjaCByZWxlYXNlIHNpbmNlICZ4c2x0NGo7IHZlcnNpb24gMi4wLkQwMS48L3A+Ci0gICAmaGlzdG9yeS1qOwotIDwvczI+Ci08L3MxPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveGFsYW4vcmVzb3VyY2VzLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW4vcmVzb3VyY2VzLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjcwNDI2Yy4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL3Jlc291cmNlcy54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw5OCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVUy1BU0NJSSI/PgotPCFET0NUWVBFIHJlc291cmNlcyBbCi0gIDwhRU5USVRZICUgZXh0ZXJuYWxFbnRpdHkgU1lTVEVNICIuLi9lbnRpdGllcy5lbnQiPgotICAlZXh0ZXJuYWxFbnRpdHk7Ci0gIDwhRUxFTUVOVCByZXNvdXJjZXMgKHJlc291cmNlfGh1bWFuLXJlc291cmNlKSs+Ci0gIDwhRUxFTUVOVCByZXNvdXJjZSBFTVBUWT4KLSAgPCFBVFRMSVNUIHJlc291cmNlIAkJCi0gICAgICAgIGlkIENEQVRBICNJTVBMSUVECi0JCQkJdGl0bGUgQ0RBVEEgI0lNUExJRUQKLQkJCQlsb2NhdGlvbiBDREFUQSAjSU1QTElFRD4KLSAgPCFFTEVNRU5UIGh1bWFuLXJlc291cmNlIEVNUFRZPgotICA8IUFUVExJU1QgaHVtYW4tcmVzb3VyY2UgCQotICAgICAgICBpZCBDREFUQSAjSU1QTElFRAotCQkJCW5hbWUgQ0RBVEEgI0lNUExJRUQKLQkJCQltYWlsdG8gQ0RBVEEgI0lNUExJRUQ+Ci0gICBdPiAgCi08cmVzb3VyY2VzPiAJCi0gIDxyZXNvdXJjZSBpZD0ieHNsdDRqLWN1cnJlbnQiIAotICAgICAgICAgICAgdGl0bGU9IiZ4c2x0NGotY3VycmVudDsiIAotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbiIvPgotICA8cmVzb3VyY2UgaWQ9InhzbHQ0ai1kaXN0LXppcCIgCi0gICAgICAgICAgICB0aXRsZT0iJnhzbHQ0ai1kaXN0Oy56aXAiIAotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy9kaXN0L3hhbGFuLWovJnhzbHQ0ai1kaXN0Oy56aXAiLz4KLSAgPHJlc291cmNlIGlkPSJ4c2x0NGotZGlzdC10YXJneiIgCi0gICAgICAgICAgICB0aXRsZT0iJnhzbHQ0ai1kaXN0Oy50YXIuZ3oiIAotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy9kaXN0L3hhbGFuLWovJnhzbHQ0ai1kaXN0Oy50YXIuZ3oiLz4KLSAgPHJlc291cmNlIGlkPSJ4c2x0NGotZGlzdGRpciIgCi0gICAgICAgICAgICB0aXRsZT0ieGFsYW4taiBkaXN0cmlidXRpb24gZGlyZWN0b3J5IiAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8veG1sLmFwYWNoZS5vcmcvZGlzdC94YWxhbi1qLyIvPgotICA8cmVzb3VyY2UgaWQ9InhtbDRqLXVzZWQiIAotICAgICAgICAgICAgdGl0bGU9IiZ4bWw0ai11c2VkOyIgCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hlcmNlcy1qL2luZGV4Lmh0bWwiLz4KLSAgPHJlc291cmNlIGlkPSJ4bWw0ai1kaXN0ZGlyIiAKLSAgICAgICAgICAgIHRpdGxlPSJ4ZXJjZXMtaiBkaXN0cmlidXRpb24gZGlyZWN0b3J5IiAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8veG1sLmFwYWNoZS5vcmcvZGlzdC94ZXJjZXMtai8iLz4KLSAgPHJlc291cmNlIGlkPSJhbnQiIHRpdGxlPSJBbnQiIAotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly9qYWthcnRhLmFwYWNoZS5vcmcvYW50L2luZGV4Lmh0bWwiLz4KLSAgPHJlc291cmNlIGlkPSJBcGFjaGVMaWNlbnNlIiAKLSAgICAgICAgICAgIHRpdGxlPSJUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xIiAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8veG1sLmFwYWNoZS5vcmcvZGlzdC9MSUNFTlNFLnR4dCIvPgotICA8cmVzb3VyY2UgaWQ9ImJ1Z3ppbGxhIgotICAgICAgICAgICAgdGl0bGU9IkJ1Z3ppbGxhICh0aGUgQXBhY2hlIGJ1ZyBkYXRhYmFzZSkiCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL25hZ295YS5hcGFjaGUub3JnL2J1Z3ppbGxhIi8+Ci0gIDxyZXNvdXJjZSBpZD0iYnVnbGlzdCIKLSAgICAgICAgICAgIHRpdGxlPSJYYWxhbkoyIG9wZW4gYnVncyIgICAgICAgICAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8vbmFnb3lhLmFwYWNoZS5vcmcvYnVnemlsbGEvYnVnbGlzdC5jZ2k/YnVnX3N0YXR1cz1ORVcmYW1wO2J1Z19zdGF0dXM9QVNTSUdORUQmYW1wO2J1Z19zdGF0dXM9UkVPUEVORUQmYW1wO2VtYWlsMT0mYW1wO2VtYWlsdHlwZTE9c3Vic3RyaW5nJmFtcDtlbWFpbGFzc2lnbmVkX3RvMT0xJmFtcDtlbWFpbDI9JmFtcDtlbWFpbHR5cGUyPXN1YnN0cmluZyZhbXA7ZW1haWxyZXBvcnRlcjI9MSZhbXA7YnVnaWR0eXBlPWluY2x1ZGUmYW1wO2J1Z19pZD0mYW1wO2NoYW5nZWRpbj0mYW1wO3ZvdGVzPSZhbXA7Y2hmaWVsZGZyb209JmFtcDtjaGZpZWxkdG89Tm93JmFtcDtjaGZpZWxkdmFsdWU9JmFtcDtwcm9kdWN0PVhhbGFuSjImYW1wO3Nob3J0X2Rlc2M9JmFtcDtzaG9ydF9kZXNjX3R5cGU9c3Vic3RyaW5nJmFtcDtsb25nX2Rlc2M9JmFtcDtsb25nX2Rlc2NfdHlwZT1zdWJzdHJpbmcmYW1wO2J1Z19maWxlX2xvYz0mYW1wO2J1Z19maWxlX2xvY190eXBlPXN1YnN0cmluZyZhbXA7a2V5d29yZHM9JmFtcDtrZXl3b3Jkc190eXBlPWFueXdvcmRzJmFtcDtmaWVsZDAtMC0wPW5vb3AmYW1wO3R5cGUwLTAtMD1ub29wJmFtcDt2YWx1ZTAtMC0wPSZhbXA7Y21kdHlwZT1kb2l0JmFtcDtvcmRlcj0lMjdJbXBvcnRhbmNlJTI3Ii8+ICAgICAgICAgICAgICAgICAgIAotICA8cmVzb3VyY2UgaWQ9ImJzZiIKLSAgICAgICAgICAgIHRpdGxlPSJCZWFuIFNjcmlwdGluZyBGcmFtZXdvcmsgKEJTRikiCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2RldmVsb3BlcndvcmtzL3Byb2plY3RzL2JzZiIvPiAgICAgCi0JCi0gIDxyZXNvdXJjZSBpZD0iUmVhZG1lIiAKLSAgICAgICAgICAgIHRpdGxlPSJYYWxhbiBSZXBvc2l0b3J5IFJlbGVhc2UgTm90ZXMiIAotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly93d3cuYXBhY2hlLm9yZy93ZWJzcmMvY3Zzd2ViLmNnaS94bWwteGFsYW4vUkVBRE1FIi8+Ci0gICAgICAgICAgICAKLSAgPHJlc291cmNlIGlkPSJ4c2x0IiB0aXRsZT0iRXh0ZW5zaWJsZSBTdHlsZXNoZWV0IExhbmd1YWdlIChYU0wpIFZlcnNpb24gMS4wIFczQyBDYW5kaWRhdGUgUmVjb21tZW5kYXRpb24iCi0gICBsb2NhdGlvbj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsIi8+Ci0KLSAgPHJlc291cmNlIGlkPSJkcGF3c29ueHNsZmFxIiB0aXRsZT0iWFNMIEZyZXF1ZW50bHkgQXNrZWQgUXVlc3Rpb25zIiBsb2NhdGlvbj0iaHR0cDovL3d3dy5kcGF3c29uLmNvLnVrL3hzbC94c2xmYXEuaHRtbCIvPgotICAKLSAgPHJlc291cmNlIGlkPSJ4c2x0IiAKLSAgICAgICAgICAgIHRpdGxlPSJXM0MgUmVjb21tZW5kYXRpb24gWFNMIFRyYW5zZm9ybWF0aW9ucyAoWFNMVCkgVmVyc2lvbiAxLjAiCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCIvPgotICAKLSAgPHJlc291cmNlIGlkPSJ4cGF0aCIgCi0gICAgICAgICAgICB0aXRsZT0iWE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMCIgCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL3d3dy53My5vcmcvVFIveHBhdGgiLz4gICAgICAgICAgICAKLSAgICAgICAgICAgIAotICA8cmVzb3VyY2UgaWQ9ImRvbSIgCi0gICAgICAgICAgICB0aXRsZT0iRE9NIiAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8vd3d3LnczLm9yZy9ET00iLz4KLSAgPHJlc291cmNlIGlkPSJkb20yIiAKLSAgICAgICAgICAgIHRpdGxlPSJET00gbGV2ZWwgMiIgCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTIvIi8+Ci0KLSAgPHJlc291cmNlIGlkPSJzYXgiIAotICAgICAgICAgICAgdGl0bGU9IlNBWCIgCi0gICAgICAgICAgICBsb2NhdGlvbj0iaHR0cDovL3d3dy5tZWdnaW5zb24uY29tL1NBWC9zYXguaHRtbCIvPgotICA8cmVzb3VyY2UgaWQ9InNheDIiIAotICAgICAgICAgICAgdGl0bGU9IlNBWCAyIiAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8vd3d3Lm1lZ2dpbnNvbi5jb20vU0FYL0phdmEvaW5kZXguaHRtbCIvPgotICA8cmVzb3VyY2UgaWQ9ImpheHAiIAotICAgICAgICAgICAgdGl0bGU9IkphdmEgQVBJIGZvciBYTUwgUGFyc2luZyAxLjAiIAotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2RvY3MvYXBpL2luZGV4Lmh0bWwiLz4KLSAgPHJlc291cmNlIGlkPSJqYXhwMTEiIAotICAgICAgICAgICAgdGl0bGU9IkphdmEgQVBJIGZvciBYTUwgUHJvY2Vzc2luZyAxLjEgUHVibGljIFJldmlldyAyIiAKLSAgICAgICAgICAgIGxvY2F0aW9uPSJodHRwOi8vamF2YS5zdW4uY29tL2Fib3V0SmF2YS9jb21tdW5pdHlwcm9jZXNzL3Jldmlldy9qc3IwNjMvamF4cC1wZDIucGRmIi8+Ci0gIDxyZXNvdXJjZSBpZD0ianNyMDYzIgotICAgICAgICAgICAgdGl0bGU9IkphdmEgU3BlY2lmaWNhdGlvbiBSZXF1ZXN0IDYzIgotICAgICAgICAgICAgbG9jYXRpb249Imh0dHA6Ly9qYXZhLnN1bi5jb20vYWJvdXRKYXZhL2NvbW11bml0eXByb2Nlc3MvcmV2aWV3L2pzcjA2MyIvPgotICAgICAgICAgICAgCi0gIDxyZXNvdXJjZSBpZD0iY29tcGF0YXBpIgotICAgICAgICAgICAgdGl0bGU9IlhhbGFuLUphdmEgMSBjb21wYXRpYmlsaXR5IEphdmFkb2MiCi0gICAgICAgICAgICBsb2NhdGlvbj0iY29tcGF0X2FwaWRvY3MvaW5kZXguaHRtbCIvPgotICAgICAgICAgICAgCi0gIDxodW1hbi1yZXNvdXJjZSBpZD0ieGFsYW5kZXYiIAotICAgICAgICAgICAgICAgICAgbmFtZT0iWGFsYW4gRGV2ZWxvcG1lbnQgTWFpbGluZyBMaXN0IiAKLSAgICAgICAgICAgICAgICAgIG1haWx0bz0ieGFsYW4tZGV2QHhtbC5hcGFjaGUub3JnIi8+Ci08L3Jlc291cmNlcz4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuL3NhbXBsZXMueG1sIGIveGRvY3Mvc291cmNlcy94YWxhbi9zYW1wbGVzLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggN2YxNTdkMy4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL3NhbXBsZXMueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNDg0ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4KLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLTxzMSB0aXRsZT0iJnhzbHQ0ajI7IFNhbXBsZXMiPgotPHVsPgotPGxpPjxsaW5rIGFuY2hvcj0ic2ltcGxldHJhbnNmb3JtIj5TaW1wbGVUcmFuc2Zvcm08L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InVzZXN0eWxlc2hlZXRwaSI+VXNlU3R5bGVzaGVldFBJPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJ1c2VzdHlsZXNoZWV0cGFyYW0iPlVzZVN0eWxlc2hlZXRQYXJhbTwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0ic2F4MnNheCI+U0FYMlNBWDwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iZG9tMmRvbSI+RE9NMkRPTTwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0icGlwZSI+UGlwZTwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0idXNleG1sZmlsdGVycyI+VXNlWE1MRmlsdGVyczwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iYXBwbHl4cGF0aCI+QXBwbHlYUGF0aDwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iYXBwbGV0eG1sdG9odG1sIj5BcHBsZXRYTUx0b0hUTUw8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImdldC10b2RvLWxpc3QiPmdldC10b2RvLWxpc3Q8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InNlcnZsZXQiPnNlcnZsZXQ8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImV4dGVuc2lvbnMiPkV4dGVuc2lvbnM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InRyYWNlIj5UcmFjZTwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0idmFsaWRhdGUiPlZhbGlkYXRlPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJ0cmF4Ij50cmF4PC9saW5rPjwvbGk+JnhzbHRjc2FtcGxlc2hlYWQ7Ci08L3VsPiAgCi0JICA8czIgdGl0bGU9IlNhbXBsZXMgdG8gaGVscCB5b3UgZ2V0IHN0YXJ0ZWQiPgotICAgIDxwPkVhY2ggb2YgdGhlIHN1YmRpcmVjdG9yaWVzIGluIHRoZSAmeHNsdDRqOyBqYXZhL3NhbXBsZXMgZGlyZWN0b3J5IGNvbnRhaW5zIHRoZSBzb3VyY2UgZmlsZXMgZm9yIG9uZSBvciBtb3JlCi0gICAgIHNhbXBsZSBhcHBsaWNhdGlvbnMuIFRoZSBjbGFzcyBmaWxlcyBmb3IgdGhlIHNhbXBsZXMgYXJlIGluIHhhbGFuc2FtcGxlcy5qYXIgKGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBzZXJ2bGV0KSBhbmQgeGFsYW5zZXJ2bGV0Lmphciwgc28gdG8gcnVuIHRoZSBzYW1wbGVzLCB5b3Ugc2hvdWxkIHBsYWNlIHRoZXNlIEpBUiBmaWxlcyBvbiB0aGUgc3lzdGVtIGNsYXNzcGF0aC48L3A+Ci0gICAgIDxwPldpdGggbW9zdCBvZiB0aGUgc2FtcGxlcywgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBwcm9jZWR1cmU6PC9wPgotICAgICA8b2w+Ci0gICAgIDxsaT5CZSBzdXJlIHhhbGFuLmphciwgeGFsYW5zYW1wbGVzLmphciwgYW5kIHhlcmNlcy5qYXIgYXJlIG9uIHRoZSBzeXN0ZW0gY2xhc3MKLSAgICAgIHBhdGguIEZvciB0aGUgZXh0ZW5zaW9uIGV4YW1wbGVzLCBic2YuamFyIGFuZCAoZm9yIHRoZSBKYXZhU2NyaXB0IGV4dGVuc2lvbnMpIGpzLmphciBtdXN0IGFsc28gYmUgb24gdGhlIGNsYXNzCi0gICAgICBwYXRoLjwvbGk+Ci0gICAgIDxsaT5CZSBzdXJlIHRoZSBqYXZhIGV4ZWN1dGFibGUgaXMgb24geW91ciBwYXRoLjwvbGk+Ci0gICAgIDxsaT5HbyB0byB0aGUgc2FtcGxlcyBzdWJkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgc2FtcGxlICh1c2UgdGhlIERPUyBzaGVsbCBpZiB5b3UgYXJlIHJ1bm5pbmcgV2luZG93cykuPC9saT4KLSAgICAgPGxpPlJ1biB0aGUgc2FtcGxlIGZyb20gdGhlIGNvbW1hbmQgbGluZSAoYXMgaW5kaWNhdGVkIGJlbG93KS48L2xpPgotICAgIDxsaT5FeGFtaW5lIHRoZSBhcHBsaWNhdGlvbiBzb3VyY2UgZmlsZXMuIFlvdSBtYXkgYWxzbyB3YW50IHRvIG1vZGlmeSB0aGUgc291cmNlIGZpbGVzLiBSZW1lbWJlciB0aGF0IGlmIHlvdQotICAgICBtb2RpZnkgYSBqYXZhIGZpbGUsIHlvdSBtdXN0IHJlY29tcGlsZSB0aGUgY2xhc3MgYW5kIHBsYWNlIGl0IG9uIHRoZSBjbGFzc3BhdGggYmVmb3JlIHlvdSBjYW4gcnVuIHRoZQotICAgICBtb2RpZmllZCBhcHBsaWNhdGlvbi48L2xpPgotICAgICA8L29sPiAgICAgIAotICAgIDxwPlRoZSBiYXNpYyBjb21tYW5kIGxpbmUgZm9yIHJ1bm5pbmcgbW9zdCBvZiB0aGUgc2FtcGxlcyBpcyA8L3A+IAotICAgIDxwPjxjb2RlPmphdmEgPHJlZj5jbGFzc25hbWUgYXJnczwvcmVmPjwvY29kZT48L3A+Ci0gICAgPHA+d2hlcmUgPHJlZj5jbGFzc25hbWU8L3JlZj4gaXMgdGhlIHNhbXBsZSBjbGFzcyBhbmQgPHJlZj5hcmdzPC9yZWY+IGFyZSB0aGUgYXJndW1lbnRzLCBpZiBhbnkuIEFzIGRlc2NyaWJlZCBpbgotICAgICB0aGUgZm9sbG93aW5nIHNlY3Rpb25zLCBzb21lIHNhbXBsZXMgdGFrZSBubyBhcmd1bWVudHMuIFRoZSBVc2VTdHlsZXNoZWV0UGFyYW0gc2FtcGxlIHRha2VzIGFuCi0gICAgIGFkZGl0aW9uYWwgYXJndW1lbnQuIFNldmVyYWwgc2FtcGxlcyBpbiBleHRlbnNpb25zIHVzZSB0aGUgJnhzbHQ0ajsgCi0gICAgIDxsaW5rIGlkcmVmPSJjb21tYW5kbGluZSI+Y29tbWFuZC1saW5lIHV0aWxpdHk8L2xpbms+LCBzbyB0aGV5IHRha2UgYXJndW1lbnRzIGZvciB0aGUgWE1MIHNvdXJjZQotICAgICBmaWxlIGFuZCB0aGUgWFNMIHN0eWxlc2hlZXQuPC9wPgotICAJPC9zMj48YW5jaG9yIG5hbWU9InNpbXBsZXRyYW5zZm9ybSIvPgotICAgIDxzMiB0aXRsZT0iU2ltcGxlVHJhbnNmb3JtIj4KLSAgICA8cD5XaGF0IGl0IGRvZXM6IFRoZSBTaW1wbGVUcmFuc2Zvcm0gY2xhc3MgdXNlcyB0aGUgYmlyZHMueHNsIHN0eWxlc2hlZXQgdG8gdHJhbnNmb3JtIGJpcmRzLnhtbCwgYW5kIHByaW50cyB0aGUKLSAgICAgb3V0cHV0IHRvIGJpcmRzLm91dC48L3A+Ci0gICAgPHA+WW91IGNhbiBydW4gaXQgZnJvbSB0aGUgU2ltcGxlVHJhbnNmb3JtIHN1YmRpcmVjdG9yeSB3aXRoPC9wPgotICAgIDxwPjxjb2RlPmphdmEgU2ltcGxlVHJhbnNmb3JtPC9jb2RlPjwvcD4KLSAgICA8L3MyPjxhbmNob3IgbmFtZT0idXNlc3R5bGVzaGVldHBpIi8+Ci0gICAgPHMyIHRpdGxlPSJVc2VTdHlsZXNoZWV0UEkiPgotICAgIDxwPldoYXQgaXQgZG9lczogVGhlIFVzZVN0eWxlc2hlZXRQSSBjbGFzcyB1c2VzIHRoZSBzdHlsZXNoZWV0IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gaW4gdGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQgdG8gZGV0ZXJtaW5lCi0gICAgIHdoaWNoIHN0eWxlc2hlZXQgdG8gdXNlIHRvIHBlcmZvcm0gdGhlIHRyYW5zZm9ybWF0aW9uLjwvcD4KLSAgICAgPHA+WW91IGNhbiBydW4gaXQgZnJvbSB0aGUgVXNlU3R5bGVzaGVldFBJIHN1YmRpcmVjdG9yeSB3aXRoPC9wPgotICAgICA8cD48Y29kZT5qYXZhIFVzZVN0eWxlc2hlZXRQSTwvY29kZT48L3A+Ci0gICAgIDxwPkZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0iZW1iZWQiPldvcmtpbmcgd2l0aCBlbWJlZGRlZCBzdHlsZXNoZWV0czwvbGluaz4uPC9wPgotICAgIDwvczI+PGFuY2hvciBuYW1lPSJ1c2VzdHlsZXNoZWV0cGFyYW0iLz4KLSAgICA8czIgdGl0bGU9IlVzZVN0eWxlc2hlZXRQYXJhbSI+Ci0gICAgICA8cD5XaGF0IGl0IGRvZXM6IFRoZSBVc2VTdHlsZVNoZWV0UGFyYW0gY2xhc3MgdXNlcyBmb28ueHNsIGFuZCBhIHN0eWxlc2hlZXQgcGFyYW1ldGVyIHRvIHRyYW5zZm9ybSBmb28ueG1sLAotICAgICAgIGFuZCBwcmludHMgdGhlIG91dHB1dCB0byBTeXN0ZW0ub3V0LiBUaGUgc3R5bGVzaGVldCBwYXJhbWV0ZXIgYXBwZWFycyBhcyBhIHRleHQgbm9kZSBpbiB0aGUgb3V0cHV0LjwvcD4KLSAgICA8cD5SdW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgVXNlU3R5bGVzaGVldFBhcmFtIHN1YmRpcmVjdG9yeSB3aXRoPC9wPiAKLSAgICA8cD48Y29kZT5qYXZhIFVzZVN0eWxlc2hlZXRQYXJhbSA8cmVmPnBhcmFtPC9yZWY+PC9jb2RlPjwvcD4KLSAgICA8cD53aGVyZSA8cmVmPnBhcmFtPC9yZWY+IGlzIHRoZSBzdHlsZXNoZWV0IHBhcmFtZXRlciB2YWx1ZSAoYSBzdHJpbmcgb2YgeW91ciBjaG9pY2UpLjwvcD4gIAotICAgIDwvczI+PGFuY2hvciBuYW1lPSJzYXgyc2F4Ii8+Ci0gIDxzMiB0aXRsZT0iU0FYMlNBWCI+Ci0gIDxwPldoYXQgaXQgZG9lczogRXhwbGljaXRseSBzZXQgdGhlIFNBWCBYTUxSZWFkZXIgYW5kIFNBWCBDb250ZW50SGFuZGxlciBmb3IgcHJvY2Vzc2luZyB0aGUgc3R5bGVzaGVldCAoYmlyZHMueHNsKSwgcHJvY2Vzc2luZyB0aGUgWE1MIGlucHV0IChiaXJkcy54bWwpLCBhbmQgcHJvZHVjaW5nIHRoZSBvdXRwdXQgKGJpcmRzLm91dCkuPC9wPgotICA8cD5SdW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgU0FYMlNBWCBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4KLSAgIDxwPjxjb2RlPmphdmEgU0FYMlNBWDwvY29kZT48L3A+Ci0gICAgPC9zMj48YW5jaG9yIG5hbWU9ImRvbTJkb20iLz4KLSAgICA8czIgdGl0bGU9IkRPTTJET00iPgotICAgIDxwPldoYXQgaXQgZG9lczogdGhlIERPTTJET00gY2xhc3MgdXNlcyB0aGUgYmlyZHMueHNsIHN0eWxlc2hlZXQgdG8gdHJhbnNmb3JtIGEgRE9NIERvY3VtZW50IGdlbmVyYXRlZCBmcm9tIGJpcmRzLnhtbCwKLSAgICAgcHJvZHVjZXMgYW4gb3V0cHV0IERPTSwgYW5kIHRyYXZlcnNlcyB0aGUgRE9NLCBwcmludGluZyB0aGUgdHJhdmVyc2FsIHRvIFN5c3RlbS5vdXQuIEluIGNvbnRyYXN0IHRvIFNpbXBsZVRyYW5zZm9ybSwKLSAgICAgIERPTTJET00gaWxsdXN0cmF0ZXMgdGhlIHByb2NlZHVyZSBmb3IgcHJvY2Vzc2luZyBhbiBpbnB1dCBET00gYW5kIGNyZWF0aW5nIGFuIG91dHB1dCBET00gdGhhdCBpcyBhdmFpbGFibGUgZm9yCi0gICAgICBmdXJ0aGVyIHByb2Nlc3NpbmcuPC9wPgotICAgPHA+WW91IGNhbiBydW4gaXQgZnJvbSB0aGUgRE9NMkRPTSBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4KLSAgICA8cD48Y29kZT5qYXZhIERPTTJET008L2NvZGU+PC9wPgotICAgIDwvczI+PGFuY2hvciBuYW1lPSJwaXBlIi8+Ci0gICAgPHMyIHRpdGxlPSJQaXBlIj4KLSAgICA8cD5XaGF0IGl0IGRvZXM6IFBpcGVzIHRoZSBvdXRwdXQgZnJvbSBvbmUgdHJhbnNmb3JtYXRpb24gdG8gYSBzZWNvbmQgdHJhbnNmb3JtYXRpb24sIHRoZW4gZnJvbSB0aGUgc2Vjb25kCi0gICAgdHJhbnNmb3JtYXRpb24gdG8gdGhlIHRoaXJkIHRyYW5zZm9ybWF0aW9uLiBUcmFuc2Zvcm1lcjEgaXMgdGhlIENvbnRlbnRIYW5kbGVyIGZvciB0aGUgWE1MUmVhZGVyICh3aGljaCBwYXJzZXMgdGhlCi0gICAgaW5wdXQgZG9jdW1lbnQpLiBUcmFuc2Zvcm1lcjIgcHJvdmlkZXMgdGhlIENvbnRlbnRIYW5kbGVyIGZvciBUcmFuc2Zvcm1lcjEsIGFuZCBUcmFuc2Zvcm1lcjMgZm9yIFRyYW5zZm9ybWVyMi48L3A+Ci0gICAgPG5vdGU+UGlwZSBhbmQgVXNlWE1MRmlsdGVycyBpbGx1c3RyYXRlIHR3byBzdHJhdGVnaWVzIGZvciB1c2luZyB0aGUgb3V0cHV0IG9mIG9uZSB0cmFuc2Zvcm1hdGlvbiBhcyB0aGUgaW5wdXQgZm9yCi0gICAgYW5vdGhlciB0cmFuc2Zvcm1hdGlvbi4gVGhlIFBpcGUgc2FtcGxlIGluY29ycG9yYXRlcyBhICJwdXNoIiBtb2RlbCAtLSBUcmFuc2Zvcm1lcjEgInB1c2hlcyIgaXRzIG91dHB1dCB0bwotICAgIFRyYW5zZm9ybWVyMiwgYW5kIHNvIG9uIC0tIHdoZXJlYXMgaW4gdGhlIFVzZVhNTEZpbHRlcnMgc2FtcGxlLCBUcmFuc2Zvcm1lcjMgInB1bGxzIiBpdHMgaW5wdXQgZnJvbSBUcmFuc2Zvcm1lcjIsCi0gICAgYW5kIHNvIG9uLjwvbm90ZT4KLSAgICA8cD5SdW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgUGlwZSBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4gCi0gICAgPHA+PGNvZGU+amF2YSBQaXBlPC9jb2RlPjwvcD4KLSAgICA8L3MyPjxhbmNob3IgbmFtZT0idXNleG1sZmlsdGVycyIvPgotICAgIDxzMiB0aXRsZT0iVXNlWE1MRmlsdGVycyI+Ci0gICAgPHA+V2hhdCBpdCBkb2VzOiBDaGFpbnMgdG9nZXRoZXIgdGhlIHNhbWUgdHJhbnNmb3JtYXRpb25zIGFzIHRoZSBwcmVjZWRpbmcgUGlwZSBzYW1wbGUuIFVzaW5nIGVhY2ggVHJhbnNmb3JtZXIKLSAgICAgb2JqZWN0IGFzIGFuIGV4dGVuc2lvbiBvZiB0aGUgU0FYIFhNTEZpbHRlciBpbnRlcmZhY2UsIHNldHMgdGhlIFhNTFJlYWRlciBhcyB0aGUgcGFyZW50IG9mIGZpbHRlcjEsCi0gICAgIGZpbHRlcjEgYXMgdGhlIHBhcmVudCBvZiBmaWx0ZXIyLCBhbmQgZmlsdGVyMiBhcyB0aGUgcGFyZW50IG9mIG9mIGZpbHRlcjMuPC9wPgotICAgICA8cD48aW1nIHNyYz0ieG1sZmlsdGVycy5naWYiIGFsdD0ieG1sZmlsdGVycy5naWYiLz48L3A+Ci0gICAgICA8cD5SdW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgVXNlWE1MRmlsdGVycyBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4KLSAgIDxwPjxjb2RlPmphdmEgVXNlWE1MRmlsdGVyczwvY29kZT48L3A+Ci0gICAgPC9zMj48YW5jaG9yIG5hbWU9ImFwcGx5eHBhdGgiLz4KLSAgICA8czIgdGl0bGU9IkFwcGx5WFBhdGgiPgotICAgIDxwPldoYXQgaXQgZG9lczogQXBwbHlYUGF0aCB1c2VzIHRoZSA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveHBhdGgvWFBhdGhBUEkuaHRtbCI+WFBhdGhBUEk8L2p1bXA+IGNvbnZlbmllbmNlIG1ldGhvZHMgdG8KLSAgICBleGVjdXRlIGFuIFhQYXRoIGV4cHJlc3Npb24gYWdhaW5zdCBhbiBYTUwgZG9jdW1lbnQgYW5kIHJldHVybiB0aGUgbm9kZXMgKGlmIGFueSkgaXQgZmluZHMuPC9wPgotICAgICA8bm90ZT5Zb3UgY2FuIHVzZSB0aGlzIHNhbXBsZSBhcyBhbiBhaWQgd2hlbiB5b3Ugd2FudCB0byBmaW5kIG91dCB3aGF0IGEgZ2l2ZW4gWFBhdGggZXhwcmVzc2lvbiByZXR1cm5zIGZyb20gYQotICAgICBnaXZlbiBYTUwgZmlsZS4gS2VlcCBpbiBtaW5kIHRoYXQgdGhlIGNvbnRleHQgbm9kZSAoYmFzZSBwb2ludCBvZiBldmFsdWF0aW9uKSBmb3IgdGhlIFhQYXRoIGV4cHJlc3Npb24gaXMgdGhlIGRvY3VtZW50Ci0gICAgIHJvb3QuPC9ub3RlPgotICAgIDxwPlJ1biB0aGlzIHNhbXBsZSBmcm9tIHRoZSBBcHBseVhQYXRoIHN1YmRpcmVjdG9yeSB3aXRoPC9wPiAKLSAgICA8cD48Y29kZT5qYXZhIEFwcGx5WFBhdGggPHJlZj5YTUxGaWxlIFhQYXRoRXhwcmVzc2lvbjwvcmVmPjwvY29kZT48L3A+Ci0gICAgPHA+d2hlcmUgPHJlZj5YTUxGaWxlPC9yZWY+IGlzIGFuIFhNTCBzb3VyY2UgZmlsZSBhbmQgPHJlZj5YUGF0aEV4cHJlc3Npb248L3JlZj4gaXMgYW4gWFBhdGggZXhwcmVzc2lvbiB0bwotICAgICBhcHBseSB0byB0aGF0IGZpbGUuIFRoZSBBcHBseVhQYXRoIHN1YmRpcmVjdG9yeSBjb250YWlucyBhbiBYTUwgZmlsZSBuYW1lZCBmb28ueG1sIC0tPGJyLz4KLSAgICAgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PGNvZGU+Jmx0O2RvYyZndDsmbHQ7bmFtZSBmaXJzdD0iRGF2aWQiIGxhc3Q9Ik1hcnN0b24iLyZndDsuLi4mbHQ7L2RvYz48L2NvZGU+PGJyLz4gLS0gc28geW91IGNhbiB0cnkgY29tbWFuZAotICAgICBsaW5lcyBsaWtlPC9wPgotICAgIDxwPjxjb2RlPmphdmEgQXBwbHlYUGF0aCBmb28ueG1sIC88L2NvZGU+PC9wPgotICAgIDxwPmFuZDwvcD4KLSAgICA8cD48Y29kZT5qYXZhIEFwcGx5WFBhdGggZm9vLnhtbCAvZG9jL25hbWUvQGZpcnN0PC9jb2RlPjwvcD4KLSAgICA8cD5Gb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxsaW5rIGlkcmVmPSJ1c2FnZXBhdHRlcm5zIiBhbmNob3I9InhwYXRoIj5Xb3JraW5nIHdpdGggWFBhdGggZXhwcmVzc2lvbnM8L2xpbms+LjwvcD4KLSAgICA8L3MyPjxhbmNob3IgbmFtZT0iYXBwbGV0eG1sdG9odG1sIi8+Ci0gICAgPHMyIHRpdGxlPSJBcHBsZXRYTUx0b0hUTUwiPgotICAgIDxwPlRoZSBhcHBsZXQgdXNlcyBhIHN0eWxlc2hlZXQgdG8gdHJhbnNmb3JtIGFuIFhNTCBkb2N1bWVudCBpbnRvIEhUTUwuIEl0IGRpc3BsYXlzIHRoZSBYTUwgZG9jdW1lbnQsIHRoZQotICAgICBzdHlsZXNoZWV0LCBhbmQgdGhlIEhUTUwgb3V0cHV0LjwvcD4KLSAgICA8cD5Ib3cgdG8gcnVuIGl0OiBPcGVuIGFwcGxldFhNTHRvSFRNTC5obXRsIGluIHRoZSBJbnRlcm5ldCBFeHBsb3JlciA1IGJyb3dzZXIuPC9wPgotICAgIDxub3RlPlRoaXMgYW5kIHRoZSBmb2xsb3dpbmcgc2FtcGxlIGFwcGxldCBkbyBub3Qgd29yayBpbiB0aGUgTmV0c2NhcGUgQ29tbXVuaWNhdG9yIDQuNy4gV2UgaGF2ZSBzb21lIHdvcmsgdG8gZG8gdG8gZ2V0Ci0gICAgb3VyIGJhc2ljIHN0cmF0ZWd5IG9mIHVzaW5nIHN5c3RlbSBwcm9wZXJ0aWVzIHRvIGlkZW50aWZ5IHRoZSBUcmFuc2Zvcm1lciBhbmQgWE1MIFBhcnNlciB0byB3b3JrIGluIHRoZSBOZXRzY2FwZSBhcHBsZXQKLSAgICBzYW5kYm94Ljxici8+PGJyLz4KLSAgICBCb3RoIGFwcGxldHMgbG9vayBmb3IgeGFsYW4uamFyIGFuZCB4ZXJjZXMuamFyIGluIHRoZSBiaW4gc3ViZGlyZWN0b3J5LiBJZiB5b3UgaGF2ZSBwbGFjZWQgdGhlc2UgSkFSIGZpbGVzCi0gICAgZWxzZXdoZXJlLCBhZGp1c3QgdGhlIGFwcGxldCBhcmNoaXZlIHNldHRpbmcgaW4gY2xpZW50Lmh0bWwgYW5kIGdldC10b2RvLWxpc3QuaHRtbCBhY2NvcmRpbmdseS48L25vdGU+Ci0gICAgPC9zMj48YW5jaG9yIG5hbWU9ImdldC10b2RvLWxpc3QiLz4KLSAgICA8czIgdGl0bGU9ImdldC10b2RvLWxpc3QiPgotICAgIDxwPlRoaXMgYXBwbGV0IHVzZXMgdG9kby54c2wgdG8gdHJhbnNmb3JtIHRvZG8ueG1sIGFuZCBkaXNwbGF5IHRoZSByZXN1bHQuIFRoZSBYTUwgc291cmNlICh0b2RvLnhtbCkgaXMgYSBzbmFwc2hvdCBvZiBhbgotICAgICBvbmdvaW5nIGxpc3Qgb2YgdGFza3MgYW5kIHRhc2sgY29tcGxldGlvbnMgZm9yIHRoZSAmeHNsdDRqMjsgcHJvamVjdCB0aGF0IGlzIG1haW50YWluZWQgaW4gdGhlIHhtbC14YWxhbi9qYXZhCi0gICAgIHN1YmRpcmVjdG9yeSBvZiB0aGUgQXBhY2hlIENWUyByZXBvc2l0b3J5LjwvcD4KLSAgICAgPHA+SG93IHRvIHJ1biBpdDogT3BlbiBnZXQtdG9kby1saXN0Lmh0bWwgaW4gdGhlIEludGVybmV0IEV4cGxvcmVyIDUgYnJvd3Nlci48L3A+Ci0gICAgPC9zMj48YW5jaG9yIG5hbWU9InNlcnZsZXQiLz4KLSAgICA8czIgdGl0bGU9InNlcnZsZXQiPgotICAgPHA+Rm9yIGEgZ2VuZXJhbCBpbnRyb2R1Y3Rpb24sIHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJzZXJ2bGV0Ij5Vc2luZyAmeHNsdDRqOyBpbiBhIHNlcnZsZXQ8L2xpbms+LjwvcD4KLSAgICA8cD5UaGUgc2VydmxldCBzdWJkaXJlY3RvcnkgY29udGFpbnMgZm91ciBzYW1wbGUgc2VydmxldHMgdGhhdCB1c2UgJnhzbHQ0ajsgdG8gcGVyZm9ybSB0cmFuc2Zvcm1hdGlvbnMuIFRoZXNlIHNlcnZsZXRzIAotICAgIGFyZSBpbiBhIHBhY2thZ2UgbmFtZWQgc2VydmxldCBhbmQgYXJlIGNvbXBpbGVkIGluIHhhbGFuc2VydmxldC5qYXIuIFRvIHJ1biB0aGVzZSBzYW1wbGVzLCB5b3UgbXVzdCBwbGFjZSAKLSAgICB4YWxhbnNlcnZsZXQuamFyLCBhbmQgYW55IFhNTCBhbmQgWFNMIGZpbGVzIHlvdSB3YW50IHRvIHVzZSBvbiBhIHdlYiBzZXJ2ZXIgd2l0aCBhIHNlcnZsZXQgZW5naW5lLCBwbGFjZSAKLSAgICB4YWxhbnNlcnZsZXQuamFyLCB4YWxhbi5qYXIsIGFuZCB4ZXJjZXMuamFyIG9uIHRoZSBzZXJ2bGV0IGVuZ2luZSBjbGFzcyBwYXRoLCBhbmQgY29uZmlndXJlIHRoZSBzZXJ2bGV0IGVuZ2luZSB0bwotICAgIGxvY2F0ZSB0aGUgWE1MIGFuZCBYU0wgZmlsZXMsIGFuZCB0aGUgcHJvcGVydGllcyBmaWxlIHVzZWQgYnkgQXBwbHlYU0wuPC9wPgotICAgIDxwPjxsaW5rIGFuY2hvcj0ic2ltcGxleHNsdHNlcnZsZXQiPnNlcnZsZXQuU2ltcGxlWFNMVFNlcnZsZXQ8L2xpbms+IGFwcGxpZXMgYSBwYXJ0aWN1bGFyIHN0eWxlc2hlZXQgdG8gYSBwYXJ0aWN1bGFyIAotICAgIFhNTCBkb2N1bWVudC48L3A+IAotICAgIDxwPjxsaW5rIGFuY2hvcj0idXNlc3R5bGVzaGVldHBhcmFtc2VydmxldCI+c2VydmxldC5Vc2VTdHlsZXNoZWV0UGFyYW1TZXJ2bGV0PC9saW5rPiBzZXRzIGEgc3R5bGVzaGVldCBwYXJhbWV0ZXIgCi0gICAgKHRoZSBwYXJhbWV0ZXIgbmFtZSBpcyBoYXJkd2lyZWQgaW50byB0aGUgc2VydmxldCksIGFuZCByZXF1aXJlcyB0aGUgdXNlciB0byBzdXBwbHkgcGFyYW1ldGVycyBmb3IgdGhlIAotICAgIFhNTCBkb2N1bWVudCBhbmQgWFNMIHN0eWxlc2hlZXQuPC9wPgotICAgIDxwPjxsaW5rIGFuY2hvcj0ianNwc2FtcGxlIj5qc3BTYW1wbGUuanNwPC9saW5rPiBpcyBhIEphdmEgU2VydmVyUGFnZSB0aGF0IHNldHMgYSBzdHlsZXNoZWV0IHBhcmFtZXRlciBhbmQgYXBwbGllcyB0aGUKLSAgICAgc3R5bGVzaGVldCB0byB0aGUgWE1MIGRvY3VtZW50LjwvcD4KLSAgICA8cD48bGluayBhbmNob3I9InhzbHRzZXJ2bGV0d2l0aHBhcmFtcyI+c2VydmxldC5YU0xUU2VydmxldFdpdGhQYXJhbXM8L2xpbms+IGFjY2VwdHMgcGFyYW1ldGVycyBmb3IgdGhlIFhNTCBkb2N1bWVudCwgCi0gICAgdGhlIFhTTCBzdHlsZXNoZWV0LCBhbmQgYW55IG51bWJlciBvZiBzdHlsZXNoZWV0IHBhcmFtZXRlcnMuPC9wPgotICAgIDxwPjxsaW5rIGFuY2hvcj0iYXBwbHl4c2x0Ij5zZXJ2bGV0LkFwcGx5WFNMVDwvbGluaz4gKGFuZCBhc3NvY2lhdGVkIGNsYXNzZXMpIGlzIGNsb3NlciB0byBhIHByb2R1Y3Rpb24gbGV2ZWwgc2VydmxldC4gSXQgYWNjZXB0cyBwYXJhbWV0ZXJzLCBwcm92aWRlcyBhIAotICAgIGxpc3RlbmVyIGZvciBjYXB0dXJpbmcgYW5kIHJlcG9ydGluZyBkZWJ1Z2dlciBtZXNzYWdlcywgYW5kIHN1cHBvcnRzICB1c2Ugb2YgYSBwcm9wZXJ0eSBmaWxlIHRvIGRldGVybWluZSB3aGljaCAKLSAgICBzdHlsZXNoZWV0IHRvIGFwcGx5IGJhc2VkIG9uIHRoZSBpZGVudGl0eSBvZiB0aGUgY2xpZW50IGJyb3dzZXIvZGV2aWNlLjwvcD4KLSAgICA8YW5jaG9yIG5hbWU9InNpbXBsZXhzbHRzZXJ2bGV0Ii8+Ci0gICAgPHMzIHRpdGxlPSJzZXJ2bGV0LlNpbXBsZVhTTFRTZXJ2bGV0Ij4KLSAgICA8cD5XaGF0IGl0IGRvZXM6IHNlcnZsZXQuU2ltcGxlWFNMVFNlcnZsZXQgYXBwbGllcyB0aGUgdG9kby54c2wgc3R5bGVzaGVldCB0byB0b2RvLnhtbCBhbmQgcmV0dXJucyB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0IHRvIHRoZQotICAgIEhUVFAgY2xpZW50LjwvcD4KLSAgICA8cD5UbyBydW4gdGhpcyBzZXJ2bGV0OiBwbGFjZSB0b2RvLnhzbCBhbmQgdG9kby54bWwgKGZyb20gdGhlIGRpc3RyaWJ1dGlvbiByb290IGRpcmVjdG9yeSkgaW4gdGhlIGRpcmVjdG9yeSB3aGVyZSB5b3VyIHNlcnZsZXQgZW5naW5lCi0gICAgbG9va3MgZm9yIEhUVFAgZG9jdW1lbnRzLCBwbGFjZSB4YWxhbnNlcnZsZXQuamFyIG9uIHRoZSBzZXJ2bGV0IGVuZ2luZSBjbGFzc3BhdGgsIGFuZCBzZXQgdXAgYW4gSFRNTCBwYWdlIHRvIGNhbGwgdGhlIHNlcnZsZXQgYXMKLSAgICBmb2xsb3dzOjwvcD4KLTxnbG9zcz48bGFiZWw+aHR0cDovL2xvY2FsaG9zdC9zZXJ2bGV0aG9tZS9zZXJ2bGV0LlNpbXBsZVhTTFRTZXJ2bGV0PC9sYWJlbD48L2dsb3NzPgotICAgICA8L3MzPjxhbmNob3IgbmFtZT0idXNlc3R5bGVzaGVldHBhcmFtc2VydmxldCIvPgotICAgICA8czMgdGl0bGU9InNlcnZsZXQuVXNlU3R5bGVzaGVldFBhcmFtU2VydmxldCI+Ci0gICAgIDxub3RlPlBhdWwgQ2FtcGJlbGwgJmx0O3NlYXB3Y0BoYWxjeW9uLmNvbSZndDsgd3JvdGUgdGhpcyBzZXJ2bGV0IGFuZCB0aGUgZm9sbG93aW5nIGV4cGxhbmF0b3J5IHRleHQuCi0gICAgIFRoYW5rIHlvdSwgUGF1bCE8L25vdGU+Ci0gICAgIDxwPldoYXQgaXQgZG9lczogVGhlIGNsaWVudCAocGVyaGFwcyBhbiBIVE1MIGZvcm0gKSBzcGVjaWZpZXMgYW4gWE1MIGRvY3VtZW50LCBhIHN0eWxlc2hlZXQsIGFuZCBhIHZhbHVlIHRvIGJlIHBhc3NlZAotICAgICAgdG8gdGhlIHN0eWxlc2hlZXQgZm9yIGEgc3R5bGVzaGVldCBwYXJhbWV0ZXIgbmFtZWQgInBhcmFtMSIuIFRoZSBzZXJ2bGV0IHBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBhbmQgcmV0dXJucwotICAgICAgdGhlIG91dHB1dCB0byB0aGUgY2xpZW50LiBUaGUgY2xpZW50IG11c3Qgc3BlY2lmeSB3aGljaCBzdHlsZXNoZWV0IChjb250YWluaW5nIGEgInBhcmFtMSIgc3R5bGVzaGVldCBwYXJhbWV0ZXIiKSAKLSAgICAgIGFuZCBYTUwgZmlsZSBhcmUgdG8gYmUgdXNlZC48L3A+Ci0gICAgIDxwPkhvdyB0byBydW4gaXQ6IENvbmZpZ3VyZSB5b3VyIGFwcGxpY2F0aW9uIHNlcnZlciAoVG9tY2F0LCBXZWJzcGhlcmUgb3IgSlNlcnYsIGZvciBleGFtcGxlKQotICAgICBzbyBpdCBjYW4gZmluZCBzZXJ2bGV0LlVzZVN0eWxlc2hlZXRQYXJhbVNlcnZsZXQgKGluIHhhbGFuc2VydmxldC5qYXIpIGFzIHdlbGwgYXMgdGhlIFhNTCBkb2N1bWVudCAKLSAgICAgYW5kIFhTTCBzdHlsZXNoZWV0LiBGb3IgZXhhbXBsZSwgeW91IGNhbiBjb3B5IGZvb3BhcmFtLnhtbCBhbmQgZm9vcGFyYW0ueHNsIGZyb20gc2FtcGxlcy9zZXJ2bGV0IHRvIHRoZSBhcHBsaWNhdGlvbiAKLSAgICAgc2VydmVyIHJvb3QgZGlyZWN0b3J5IGZvciBkb2N1bWVudHMuPC9wPgotICAgICA8cD5UaGVuIHlvdSBjYW4gc2V0IHVwIGFuIEhUTUwgY2xpZW50IHRvIGNhbGwgdGhlIHNlcnZsZXQgd2l0aCBhcmd1bWVudHMgYWxvbmcgdGhlIGxpbmVzIG9mPC9wPgotICAgIDxnbG9zcz48bGFiZWw+aHR0cDovL2xvY2FsaG9zdC9zZXJ2bGV0aG9tZS9zZXJ2bGV0LlVzZVN0eWxlc2hlZXRQYXJhbVNlcnZsZXQ/Ci0gICAgWE1MPWZvb3BhcmFtLnhtbCZhbXA7WFNMPWZvb3BhcmFtLnhzbCZhbXA7UFZBTD1Hb29kQnllPC9sYWJlbD48L2dsb3NzPgotICAgICA8cD5JbiB0aGUgZG9HZXQoKSBtZXRob2QsIHRoZSBzZXJ2bGV0IG9idGFpbnMgdGhlIFBWQUwgdmFsdWUgIkdvb2RCeWUiKSBmcm9tIHRoZSBzZXJ2bGV0IHJlcXVlc3QgYW5kIHBhc3NlcyBpdCB0byB0aGUgCi0gICAgIHN0eWxlc2hlZXQgYXMgdGhlIHBhcmFtVmFsdWUgYXJndW1lbnQgaW4gYSBUcmFuc2Zvcm1lciBzZXRQYXJhbWV0ZXIoKSBjYWxsOjwvcD4KLSAgICAgIDxwPjxjb2RlPlN0cmluZyBwYXJhbVZhbHVlID0gaHR0cFNlcnZsZXRSZXF1ZXN0LmdldFBhcmFtZXRlcigiUFZBTCIpOzwvY29kZT48YnIvPgotICAgICAgPGNvZGU+Li4uPC9jb2RlPjxici8+Ci0gICAgIDxjb2RlPnRyYW5zZm9ybWVyLnNldFBhcmFtZXRlcigicGFyYW0xIiwgcGFyYW1WYWx1ZSk7PC9jb2RlPjwvcD4KLSA8cD5UaGUgcmVzdWx0IGlzIHJldHVybmVkIHRvIHRoZSBjbGllbnQ6PC9wPgotPHA+PGNvZGU+Jmx0O2h0bWwmZ3Q7Jmx0O2JvZHkmZ3Q7Jmx0O3AmZ3Q7R29vZEJ5ZSZsdDsvcCZndDsmbHQ7L2JvZHkmZ3Q7Jmx0Oy9odG1sJmd0OzwvY29kZT48L3A+Ci0gICAgIDwvczM+PGFuY2hvciBuYW1lPSJqc3BzYW1wbGUiLz4KLSAgICAgPHMzIHRpdGxlPSJqc3BTYW1wbGUuanNwIj4KLSAgICAgPG5vdGU+UGF1bCBDYW1wYmVsbCAmbHQ7c2VhcHdjQGhhbGN5b24uY29tJmd0OyB3cm90ZSB0aGlzIEphdmEgU2VydmVyIFBhZ2UuPC9ub3RlPgotICAgICA8cD5UaGlzIEphdmEgU2VydmVyIFBhZ2UgcGVyZm9ybXMgZXNzZW50aWFsbHkgdGhlIHNhbWUgb3BlcmF0aW9uIGFzIAotICAgICA8bGluayBhbmNob3I9InVzZXN0eWxlc2hlZXRwYXJhbXNlcnZsZXQiPnNlcnZsZXQuVXNlU3R5bGVzaGVldFBhcmFtU2VydmxldDwvbGluaz4uIEl0IGFwcGxpZXMgYSBzdHlsZXNoZWV0IHBhcmFtZXRlciAKLSAgICAgIHRvIGEgc3R5bGVzaGVldCAoZm9vcGFyYW0ueHNsKSwgYXBwbGllcyB0aGUgc3R5bGVzaGVldCB0byBhbiBYTUwgc291cmNlIGRvY3VtZW50IChmb29wYXJhbS54bWwpLCBhbmQgcmV0dXJucyB0aGUKLSAgICAgIHJlc3VsdC48L3A+ICAgICAKLSAgICAgPC9zMz48YW5jaG9yIG5hbWU9InhzbHRzZXJ2bGV0d2l0aHBhcmFtcyIvPgotICAgICA8czMgdGl0bGU9InNlcnZsZXQuWFNMVFNlcnZsZXRXaXRoUGFyYW1zIj4KLSAgICAgPHA+V2hhdCBpdCBkb2VzOiBzZXJ2bGV0LlhTTFRTZXJ2bGV0V2l0aFBhcmFtcyB0YWtlcyBwYXJhbWV0ZXJzIGluIHRoZSByZXF1ZXN0IC0tIGEgVVJMIHBhcmFtZXRlciBmb3IKLSAgICAgdGhlIFhNTCBpbnB1dCBkb2N1bWVudCBVUkwgYW5kIGFuIHhzbFVSTCBwYXJhbWV0ZXIgZm9yIHRoZSBzdHlsZXNoZWV0IFVSTC48L3A+Ci0gICAgIDxwPlRvIHVzZSBYU0xUU2VydmxldFdpdGhQYXJhbXMgdG8gcGVyZm9ybSB0aGUgc2FtZSB0cmFuc2Zvcm1hdGlvbiBhcyBTaW1wbGVzdFNlcnZsZXQ6IAotICAgICBwbGFjZSB0b2RvLnhzbCBhbmQgdG9kby54bWwgaW4gdGhlIGRpcmVjdG9yeSB3aGVyZSB5b3VyIHNlcnZsZXQgZW5naW5lIGxvb2tzIGZvciBIVFRQIGRvY3VtZW50cywgcGxhY2UKLSAgICAgeGFsYW5zZXJ2bGV0LmphciBvbiB0aGUgc2VydmxldCBlbmdpbmUgY2xhc3NwYXRoLCBhbmQgc2V0IHVwIGFuIEhUTUwgcGFnZSB0byBjYWxsIHRoZSBzZXJ2bGV0IGFzIGZvbGxvd3M6PC9wPgotPGdsb3NzPjxsYWJlbD5odHRwOi8vbG9jYWxob3N0L3NlcnZsZXRob21lL3NlcnZsZXQuWFNMVFNlcnZsZXRXaXRoUGFyYW1zP1VSTD1maWxlOnRvZG8ueG1sJmFtcDsKLXhzbFVSTD1maWxlOnRvZG8ueHNsPC9sYWJlbD48L2dsb3NzPgotICAgICA8cD5JZiB0aGUgWE1MIGRvY3VtZW50IGNvbnRhaW5zIGFuIGFzc29jaWF0ZWQgc3R5bGVzaGVldCAoYSBzdHlsZXNoZWV0IFByb2Nlc3NpbmcgSW5zdHJ1Y3Rpb24pIHRoYXQgeW91IHdhbnQgdG8gdXNlLCBzaW1wbHkgb21pdCB0aGUKLSAgICAgeHNsVVJMIHBhcmFtZXRlci48L3A+Ci0gICAgIDxwPklmIHRoZSBzdHlsZXNoZWV0IHRha2VzIHN0eWxlc2hlZXQgcGFyYW1ldGVycywgeW91IGNhbiBpbmNsdWRlIHRoZW0gaW4gdGhlIFVSTC4gRm9yIGV4YW1wbGUgdG8gc2V0IHNldCB0aGUgcGFyYW0xCi0gICAgIHN0eWxlc2hlZXQgcGFyYW1ldGVyIHRvIGZvbywgaW5jbHVkZSBwYXJhbTE9Zm9vIGluIHRoZSBVUkwuPC9wPgotICAgICA8L3MzPjxhbmNob3IgbmFtZT0iYXBwbHl4c2x0Ii8+Ci0gICAgIDxzMyB0aXRsZT0ic2VydmxldC5BcHBseVhTTFQiPgotICAgIDxwPldoYXQgaXQgZG9lczogVGhlIGNsaWVudCAod2hpY2ggeW91IG11c3Qgc2V0IHVwKSBzcGVjaWZpZXMgYW4gWE1MIGRvY3VtZW50IGFuZCBhIHN0eWxlc2hlZXQuIFRoZSBzZXJ2bGV0Ci0gICAgIHBlcmZvcm1zIHRoZSB0cmFuc2Zvcm1hdGlvbiBhbmQgcmV0dXJucyB0aGUgb3V0cHV0IHRvIHRoZSBjbGllbnQuIFlvdSBjYW4gdXNlIG1lZGlhLnByb3BlcnRpZXMgdG8gc3BlY2lmeSAKLSAgICB3aGljaCBzdHlsZXNoZWV0IGlzIHRvIGJlIHVzZWQgZGVwZW5kaW5nIG9uIHRoZSBjbGllbnQgYnJvd3Nlci9kZXZpY2UuPC9wPgotICAgIDxub3RlPlRoZSBzb3VyY2UgZmlsZXMgZm9yIHRoaXMgc2VydmxldCBpbmNsdWRlIEFwcGx5WFNMVC5qYXZhLCBBcHBseVhTTFRQcm9wZXJ0aWVzLmphdmEsIERlZmF1bHRBcHBseVhTTFRQcm9wZXJ0aWVzLmphdmEsCi0gICAgQXBwbHlYU0xUTGlzdGVuZXIuamF2YSwgYW5kIEFwcGx5WFNMVEV4Y2VwdGlvbi5qYXZhLjwvbm90ZT4KLSAgICA8cD5UbyBydW4gdGhlIHNlcnZsZXQ6IHB1dCB4YWxhbnNlcnZsZXQuamFyIG9uIHRoZSBzZXJ2bGV0IGVuZ2luZSBjbGFzc3BhdGgsIGNvbmZpZ3VyZSB5b3VyIHNlcnZsZXQgZW5naW5lIHNvIGl0IGNhbiBmaW5kIHRoZSAKLSAgICAgc3R5bGVzaGVldHMgYW5kIHByb3BlcnRpZXMgZmlsZSBpbiB0aGUgc2VydmxldCBzdWJkaXJlY3RvcnkgKGFuZCBpbiB4YWxhbnNlcnZsZXQuamFyKSwgYW5kIHNldCB1cCBhbiBIVE1MIHBhZ2UgdG8gY2FsbAotICAgICBzZXJ2bGV0LkFwcGx5WFNMVCB3aXRoIGFyZ3VtZW50cyBhcyBpbGx1c3RyYXRlZCBiZWxvdy48L3A+Ci0gICAgIDxwPkV4YW1wbGVzOjwvcD4KLTxnbG9zcz4KLTxsYWJlbD5odHRwOi8vbG9jYWxob3N0L3NlcnZsZXRob21lL3NlcnZsZXQuQXBwbHlYU0xUP1VSTD0vZGF0YS54bWwmYW1wO3hzbFVSTD0KLS9zdHlsZS54c2w8L2xhYmVsPgotPGl0ZW0+Li4uYXBwbGllcyB0aGUgc3R5bGUueHNsIHN0eWxlc2hlZXQgdG8gdGhlIGRhdGEueG1sIGRhdGEuIEJvdGggZmlsZXMgYXJlPGJyLz4KLXNlcnZlZCBmcm9tIHRoZSBXZWIgc2VydmVyJ3MgSFRUUCBkb2N1bWVudCByb290Ljxici8+PGJyLz48L2l0ZW0+Ci08bGFiZWw+aHR0cDovL2xvY2FsaG9zdC9zZXJ2bGV0aG9tZS9zZXJ2bGV0LkFwcGx5WFNMVD9VUkw9L2RhdGEueG1sJmFtcDt4c2xVUkw9Ci0vc3R5bGUueHNsJmFtcDtkZWJ1Zz10cnVlPC9sYWJlbD4KLTxpdGVtPi4uLmVuc3VyZXMgdGhhdCBYTUwgYW5kIFhTTCBwcm9jZXNzb3IgbWVzc2FnZXMgYXJlIHJldHVybmVkIGluIHRoZSBldmVudCBvZiBwcm9ibGVtcwotYXBwbHlpbmcgc3R5bGUueHNsIHRvIGRhdGEueG1sPGJyLz48YnIvPjwvaXRlbT4KLTxsYWJlbD5odHRwOi8vbG9jYWxob3N0L3NlcnZsZXRob21lL3NlcnZsZXQuQXBwbHlYU0xUL2RhdGEueG1sP3hzbFVSTD0vc3R5bGUueHNsPC9sYWJlbD4KLTxpdGVtPi4uLmFwcGxpZXMgdGhlIHN0eWxlLnhzbCBzdHlsZXNoZWV0IHRvIHRoZSBkYXRhLnhtbCBkYXRhLCBqdXN0IGxpa2UgdGhlIGZpcnN0IGV4YW1wbGUuCi1UaGlzIGlzIGFuIGFsdGVybmF0aXZlIHdheSBvZiBzcGVjaWZ5aW5nIHRoZSBYTUwgWFNMVElucHV0U291cmNlIGJ5IHV0aWxpemluZyB0aGUgSFRUUCByZXF1ZXN0J3MgcGF0aAotaW5mb3JtYXRpb24uPGJyLz48YnIvPjwvaXRlbT4KLTxsYWJlbD5odHRwOi8vbG9jYWxob3N0L3NlcnZsZXRob21lL3NlcnZsZXQuQXBwbHlYU0xUL2RhdGEueG1sPC9sYWJlbD4KLTxpdGVtPi4uLmV4YW1pbmVzIGRhdGEueG1sIGZvciBhbiBhc3NvY2lhdGVkIFhTTCBzdHlsZXNoZWV0IChhIHN0eWxlc2hlZXQgUHJvY2Vzc2luZyBJbnN0cnVjdGlvbikuIElmIG11bHRpcGxlIFhTTHMgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGF0YSwgdGhlIHN0eWxlc2hlZXQgd2hvc2UgbWVkaWEgYXR0cmlidXRlIG1hcHMgdG8geW91ciBicm93c2VyIHR5cGUgd2lsbCBiZSBjaG9zZW4uICBJZiBubyBtYXBwaW5nIGlzIHN1Y2Nlc3NmdWwsIHRoZSBwcmltYXJ5IGFzc29jaWF0ZWQgc3R5bGVzaGVldCBpcyB1c2VkLjxici8+PGJyLz48L2l0ZW0+Ci08bGFiZWw+aHR0cDovL2xvY2FsaG9zdC9zZXJ2bGV0L2RhdGEueG1sPC9sYWJlbD4KLTxpdGVtPi4uLnByb3ZpZGVzIHRoZSBzYW1lIGZ1bmN0aW9uIGFzIHRoZSBwcmV2aW91cyBleGFtcGxlLCBidXQgdGhpcyBleGFtcGxlIGFzc3VtZXMKLXRoYXQgL3NlcnZsZXQvZGF0YS54bWwgaGFzIGJlZW4gbWFwcGVkIHRvIGJlIGV4ZWN1dGVkIGJ5IHRoaXMgc2VydmxldC4gIFRoZSBzZXJ2bGV0IGVuZ2luZSBtYXkgYmUgY29uZmlndXJlZAotdG8gbWFwIGFsbCBvciBzb21lICoueG1sIGZpbGVzIHRvIHRoaXMgc2VydmxldCB0aHJvdWdoIHRoZSB1c2Ugb2Ygc2VydmxldCBhbGlhc2VzIG9yIGZpbHRlcnMuPGJyLz48YnIvPjwvaXRlbT4KLTxsYWJlbD5odHRwOi8vbG9jYWxob3N0L3NlcnZsZXQvZGF0YS54bWw/Y2F0YWxvZz1odHRwOi8vd3d3LnhtbC5vcmcvZHRkcy9vYWcueG1sPC9sYWJlbD4KLTxpdGVtPi4uLnN1cHBsZW1lbnRzIGFueSBzZXJ2bGV0LWNvbmZpZ3VyZWQgWENhdGFsb2cKLXdpdGggYSBjYXRhbG9nIG9mIHN1cHBseSBjaGFpbiBEVERzIHJlc2lkaW5nIGF0IHRoZSBYTUwuT1JHIERURCByZXBvc2l0b3J5LjwvaXRlbT4KLTwvZ2xvc3M+ICAgICAKLSAgIDwvczM+Ci0gICAgIDwvczI+PGFuY2hvciBuYW1lPSJleHRlbnNpb25zIi8+Ci0gICAgPHMyIHRpdGxlPSJFeHRlbnNpb25zIj4KLSAgICA8cD5Gb3IgYW4gaW50cm9kdWN0aW9uIHRvIHRoZSBjcmVhdGlvbiBhbmQgdXNlIG9mIGV4dGVuc2lvbiBlbGVtZW50cyBhbmQgZXh0ZW5zaW9uIGZ1bmN0aW9ucywgYW5kCi0gICAgZm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBleHRlbnNpb25zIGxpYnJhcnkgZGlzdHJpYnV0ZWQgd2l0aCAmeHNsdDRqOywgc2VlCi0gICAgPGxpbmsgaWRyZWY9ImV4dGVuc2lvbnMiPkV4dGVuc2lvbnM8L2xpbms+LjwvcD4KLSAgICA8dWw+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJleHQxIj4xLXJlZGlyPC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJleHQyIj4yLWJhc2ljSnNjcmlwdDwvbGluaz48L2xpPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZXh0MyI+My1qYXZhLW5hbWVzcGFjZTwvbGluaz48L2xpPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZXh0NCI+NC1udW1saXN0SmF2YTwvbGluaz48L2xpPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZXh0NSI+NS1udW1saXN0SlNjcmlwdDwvbGluaz48L2xpPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0ic3FsIj5TUUwgbGlicmFyeSBleHRlbnNpb25zPC9saW5rPjwvbGk+Ci0gICAgPC91bD4KLSAgICA8cD5UaGUgZXh0ZW5zaW9ucyBzdWJkaXJlY3RvcnkgY29udGFpbnMgc2l4IHNhbXBsZXMgd2l0aCAmeHNsdDRqOyBleHRlbnNpb25zLiBUd28gb2YgdGhlIHNhbXBsZXMgdXNlCi0gICAgIGV4dGVuc2lvbnMgaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdCwgYW5kIGZvdXIgb2YgdGhlIHNhbXBsZXMgdXNlIGV4dGVuc2lvbnMgaW1wbGVtZW50ZWQgaW4gSmF2YS48L3A+Ci0gICAgIDxwPlRvIHJ1biB0aGVzZSBleGFtcGxlcywgeW91IG11c3QgcGxhY2UgYnNmLmphciAoZGlzdHJpYnV0ZWQgd2l0aCAmeHNsdDRqOyksIGFuZCBqcy5qYXIKLSAgICAgICh2ZXJzaW9uIDEuNSwgYXZhaWxhYmxlIGZyb20gCi0gICAgICA8anVtcCBocmVmPSJodHRwOi8vd3d3Lm1vemlsbGEub3JnL3JoaW5vIj5odHRwOi8vd3d3Lm1vemlsbGEub3JnL3JoaW5vPC9qdW1wPikgb24gdGhlIGNsYXNzcGF0aC4gCi0gICAgIFlvdSBkbyBub3QgbmVlZCBqcy5qYXIgb24gdGhlIGNsYXNzcGF0aCBmb3IgdGhlIHNhbXBsZXMgdGhhdCB1c2UgSmF2YSBleHRlbnNpb25zLiA8L3A+Ci0gICAgIDxwPlVzZSBqYXZhLm9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzLCB0aGUgJnhzbHQ0ajsgY29tbWFuZC1saW5lIHV0aWxpdHksIHRvIHJ1biBtb3N0IG9mIHRoZXNlIHNhbXBsZXMgZnJvbQotICAgICAgdGhlIDxsaW5rIGlkcmVmPSJjb21tYW5kbGluZSI+Y29tbWFuZCBsaW5lPC9saW5rPi4gVGhlIGNvbW1hbmQgbGluZSBtdXN0IGluY2x1ZGUgYW4gLWluIGZsYWcgd2l0aCB0aGUgCi0gICAgICBYTUwgc291cmNlIGFuZCBhbiAteHNsIGZsYWcgd2l0aCB0aGUgWFNMIHN0eWxlc2hlZXQuIElmIHlvdSB3YW50IHRoZSBvdXRwdXQgdG8gYmUgd3JpdHRlbiB0byBhIGZpbGUsIHJhdGhlcgotICAgICAgdGhhbiB0byB0aGUgc2NyZWVuLCBhZGQgYW4gLW91dCBmbGFnIHdpdGggdGhlIG91dHB1dCBmaWxlIG5hbWUuPC9wPgotICAgICAgPHA+UnVuIHRoZXNlIHNhbXBsZXMgZnJvbSB0aGUgZXh0ZW5zaW9ucyBkaXJlY3RvcnkgYXMgZm9sbG93cyAoZWFjaCBvZiB0aGUgZm9sbG93aW5nIGlzIGEgc2luZ2xlIGNvbW1hbmQKLSAgICAgICBsaW5lKTo8L3A+IAotCi0gICAgICA8YW5jaG9yIG5hbWU9ImV4dDEiLz4KLSAgICAgIDxzMyB0aXRsZT0iMS1yZWRpciI+Ci0gICAgICA8cD5XaGF0IGl0IGRvZXM6IFVzZXMgdGhlIFJlZGlyZWN0IGV4dGVuc2lvbiBlbGVtZW50cyBzaGlwcGVkIHdpdGggJnhzbHQ0ajsgdG8gZGlyZWN0IG91dHB1dCB0byB0d28gb3V0cHV0Ci0gICAgICAgIGZpbGVzLjwvcD4KLSAgICAgIDxwPlJ1biB0aGlzIHNhbXBsZSBmcm9tIHRoZSBleHRlbnNpb25zIHN1YmRpcmVjdG9yeSB3aXRoPC9wPiAKLSAgICAgICA8cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzIC1pbiAxLXJlZGlyLnhtbDwvY29kZT48YnIvPgotICAgICAgICZuYnNwOyZuYnNwOzxjb2RlPi14c2wgMS1yZWRpci54c2w8L2NvZGU+PC9wPgotICAgICAgPHA+VGhlIHN0YW5kYXJkIChub24tcmVkaXJlY3RlZCkgb3V0cHV0IGlzIHdyaXR0ZW4gdG8gdGhlIHNjcmVlbi4gVGhlIHJlZGlyZWN0ZWQgb3V0cHV0IGlzIHdyaXR0ZW4gdG8gMS1yZWRpci1vdXQsIG9yCi0gICAgICB3aGF0ZXZlciBmaWxlbmFtZSB5b3UgYXNzaWduIHRvIHRoZSBkb2MvZm9vIEBmaWxlIGF0dHJpYnV0ZSBpbiAxLXJlZGlyLnhtbC4gVGhlIHN0eWxlc2hlZXQgZ2V0cyB0aGUgZmlsZSBuYW1lIGZvcgotICAgICAgcmVkaXJlY3RlZCBvdXRwdXQgZnJvbSB0aGUgWE1MIGlucHV0IGZpbGUuPC9wPgotICAgICAgPC9zMz48YW5jaG9yIG5hbWU9ImV4dDIiLz4KLSAgICAgIDxzMyB0aXRsZT0iMi1iYXNpY0pzY3JpcHQiPgotICAgICAgPHA+V2hhdCBpdCBkb2VzOiBVc2VzIGFuIGV4dGVuc2lvbiBlbGVtZW50IGFuZCBleHRlbnNpb24gZnVuY3Rpb24gaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdCB0byBjb21wdXRlIGEKLSAgICAgIGRlYWRsaW5lIGZvciByZXNwb25kaW5nIHRvIGEgY3VzdG9tZXIgaW5xdWlyeS48L3A+Ci0gICAgICA8bm90ZT5qcy5qYXIgbXVzdCBiZSBvbiB0aGUgY2xhc3NwYXRoLjwvbm90ZT4KLSAgICAgIDxwPlJ1biB0aGlzIHNhbXBsZSBmcm9tIHRoZSBleHRlbnNpb25zIHN1YmRpcmVjdG9yeSB3aXRoPC9wPgotICAgICAgPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyAtaW4gMi1iYXNpY0pzY3JpcHQueG1sPC9jb2RlPgotICAgICAgICAgPGJyLz4mbmJzcDsmbmJzcDs8Y29kZT4teHNsIDItYmFzaWNKc2NyaXB0LnhzbDwvY29kZT48L3A+ICAgICAKLSAgICAgIDwvczM+PGFuY2hvciBuYW1lPSJleHQzIi8+Ci0gICAgICA8czMgdGl0bGU9IjMtamF2YS1uYW1lc3BhY2UiPgotICAgICAgPHA+V2hhdCBpdCBkb2VzOiBVc2VzIGV4dGVuc2lvbiBmdW5jdGlvbnMgdG8gZm9ybWF0IGRhdGVzLiBUaGlzIHNhbXBsZSBpbGx1c3RyYXRlcyB1c2Ugb2YgdGhlIHByZWRlZmluZWQgamF2YQotICAgICAgICBleHRlbnNpb24gbmFtZXNwYWNlIHRvIHByb3ZpZGUgcmVhZHkgYWNjZXNzIHRvIGV4dGVuc2lvbnMgaW1wbGVtZW50ZWQgaW4gSmF2YS48L3A+Ci0gICAgICA8cD5SdW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgZXh0ZW5zaW9ucyBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4gCi0gICAgICA8cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzIC1pbiAzLWphdmEtbmFtZXNwYWNlLnhtbDwvY29kZT4KLSAgICAgICAgIDxici8+Jm5ic3A7Jm5ic3A7PGNvZGU+LXhzbCAzLWphdmEtbmFtZXNwYWNlLnhzbDwvY29kZT48L3A+ICAgIAotICAgICAgPC9zMz48YW5jaG9yIG5hbWU9ImV4dDQiLz4KLSAgICAgIDxzMyB0aXRsZT0iNC1udW1saXN0SmF2YSI+Ci0gICAgICA8cD5XaGF0IGl0IGRvZXM6IFVzZXMgYSBKYXZhIGV4dGVuc2lvbiB0byB0cmFuc2Zvcm0gYSBzZXQgb2YgbmFtZSBlbGVtZW50cyBpbnRvIGEgbnVtYmVyZWQgYW5kIGFscGhhYmV0aXplZAotICAgICAgIGxpc3QuPC9wPgotICAgICAgPHA+UnVuIHRoaXMgc2FtcGxlIGZyb20gdGhlIGV4dGVuc2lvbnMgc3ViZGlyZWN0b3J5IHdpdGg8L3A+IAotICAgICAgPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyAtaW4gbnVtbGlzdC54bWw8L2NvZGU+IAotICAgICAgICA8YnIvPiZuYnNwOyZuYnNwOzxjb2RlPi14c2wgNC1udW1saXN0SmF2YS54c2w8L2NvZGU+PC9wPiAgICAKLSAgICAgIDwvczM+PGFuY2hvciBuYW1lPSJleHQ1Ii8+Ci0gICAgICA8czMgdGl0bGU9IjUtbnVtbGlzdEpzY3JpcHQiPgotICAgICAgPHA+V2hhdCBpdCBkb2VzOiBVc2VzIGEgSmF2YVNjcmlwdCAgZXh0ZW5zaW9uIHRvIHRyYW5zZm9ybSBhIHNldCBvZiBuYW1lIGVsZW1lbnRzIGludG8gYSBudW1iZXJlZCBhbmQKLSAgICAgIGFscGhhYmV0aXplZCBsaXN0LiBUaGlzIHNhbXBsZSBwZXJmb3JtcyB0aGUgc2FtZSBvcGVyYXRpb25zIGFzIHRoZSBwcmVjZWRpbmcgSmF2YSBleHRlbnNpb24uPC9wPgotICAgICAgPG5vdGU+anMuamFyIG11c3QgYmUgb24gdGhlIGNsYXNzcGF0aC48L25vdGU+Ci0gICAgPHA+UnVuIHRoaXMgc2FtcGxlIGZyb20gdGhlIGV4dGVuc2lvbnMgc3ViZGlyZWN0b3J5IHdpdGg8L3A+Ci0gICAgICA8cD48Y29kZT4gamF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzcyAtaW4gbnVtbGlzdC54bWw8L2NvZGU+Ci0gICAgICAgIDxici8+Jm5ic3A7Jm5ic3A7PGNvZGU+LXhzbCA1LW51bWxpc3RKc2NyaXB0LnhzbDwvY29kZT48L3A+Ci0gICAgICA8L3MzPgotICAgICAgPC9zMj48YW5jaG9yIG5hbWU9InNxbCIvPgotICAgICAgPHMyIHRpdGxlPSJTUUwgTGlicmFyeSBleHRlbnNpb25zIj4KLSAgICAgIDxwPlRoZSBTUUwgTGlicmFyeSBleHRlbnNpb24gc2FtcGxlcyB1c2UgPGxpbmsgaWRyZWY9ImV4dGVuc2lvbnNsaWIiIGFuY2hvcj0ic3FsIj5TUUwgbGlicmFyeSBYQ29ubmVjdGlvbgotICAgICAgZXh0ZW5zaW9uPC9saW5rPnRvIGNvbm5lY3QgdG8gYW4gSW5zdGFudERCIGRhdGFzb3VyY2UsIHBlcmZvcm0gcXVlcmllcywgYW5kIHJldHVybiBxdWVyeSByZXN1bHQgc2V0cy48L3A+Ci0gICAgICA8bm90ZT5UbyBydW4gdGhlc2Ugc2FtcGxlcywgeW91IG11c3QgaW5jbHVkZSBpZGIuamFyIG9uIHRoZSBjbGFzc3BhdGguIFdlIGhhdmUgcGxhY2VkIGEgY29weSBvZiBpZGIuamFyIGZyb20KLSAgICAgIEluc3RhbnREQiB2ZXJzaW9uIDMuMjUgaW4gc2FtcGxlcy9leHRlbnNpb25zL2luc3RhbnRkYi4gRm9yIGluZm9ybWF0aW9uIGFib3V0IEluc3RhbnREQiwgc2VlCi0gICAgICA8anVtcCBocmVmPSJodHRwOi8vaW5zdGFudGRiLmVuaHlkcmEub3JnL3NvZnR3YXJlL2RvY3VtZW50YXRpb24vaW5kZXguaHRtbCI+SW5zdGFudERCPC9qdW1wPgotICAgICAgYW5kIHRoZSA8anVtcCBocmVmPSJodHRwOi8vaW5zdGFudGRiLmVuaHlkcmEub3JnL3NvZnR3YXJlL2xpY2Vuc2UvaW5kZXguaHRtbCI+RW55ZHJhIFB1YmxpYwotICAgICAgTGljZW5zZTwvanVtcD4uPC9ub3RlPiAgICAgIAotICAgICAgPHVsPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZXh0NiI+Ni1zcWxsaWItaW5zdGFudGRiPC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJiYXNpYy1jb25uIj5CYXNpYyBDb25uZWN0aW9uczwvbGluaz48L2xpPiAgICAgIAotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZXh0LWNvbm4iPkV4dGVybmFsQ29ubmVjdGlvbjwvbGluaz48L2xpPiAgICAgIAotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0icHF1ZXJ5Ij5QYXJhbWV0ZXJpemVkIHF1ZXJ5PC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJzdHJlYW1hYmxlIj5TdHJlYW1hYmxlPC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJzaG93ZXJyb3IiPlNob3ctZXJyb3I8L2xpbms+PC9saT4KLSAgICAgIDwvdWw+Ci0gICAgICA8bm90ZT5FeGNlcHQgZm9yIDYtc3FsbGliLWluc3RhbnRkYiwgYWxsIHRoZXNlIHNhbXBsZXMgaGF2ZSBiZWVuIGNyZWF0ZWQgYnkgSm9obiBHZW50aWxpbiAKLSAgICAgIChqb2huZ2xpbnV4QGV5ZWNhdGNoaW5nLmNvbSkgdG8gdGFrZSBpbGx1c3RyYXRlIHRoZSByaWNoIGZlYXR1cmUgc2V0IGhlIGhhcyBjb250cmlidXRlZCB0byB0aGUgU1FMIExpYnJhcnkuIAotICAgICAgVG8gcnVuIGVhY2ggb2YgdGhlc2Ugc2FtcGxlcywgYmUgc3VyZSAgeW91IGFyZSBpbiB0aGUgYXBwcm9wcmlhdGUgZXh0ZW5zaW9ucy9zcWwgc3ViZGlyZWN0b3J5Ljwvbm90ZT4KLSAgICAgPGFuY2hvciBuYW1lPSJleHQ2Ii8+Ci0gICAgICA8czMgdGl0bGU9IjYtc3FsbGliLWluc3RhbnRkYiI+Ci0gICAgICA8cD5XaGF0IGl0IGRvZXM6IFVzZXMgdGhlIFNRTCBsaWJyYXJ5IFhDb25uZWN0aW9uIGV4dGVuc2lvbiB0byBjb25uZWN0IHRvIHRoZSBJbnN0YW50REIgc2FtcGxlIGRhdGFiYXNlLCAKLSAgICAgIHBlcmZvcm1zIGEgcXVlcnksIGFuZCByZXR1cm5zIHRoZSBxdWVyeSByZXN1bHQgaW4gYW4gSFRNTCB0YWJsZS48L3A+Ci0gICAgICA8cD5BZGQgaWRiLmphciB0byB0aGUgY2xhc3NwYXRoLCBhbmQgcnVuIHRoaXMgc2FtcGxlIGZyb20gdGhlIGV4dGVuc2lvbnMgc3ViZGlyZWN0b3J5OjwvcD4KLSAgICAgIDxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0LlByb2Nlc3M8L2NvZGU+Ci0gICAgICA8YnIvPiZuYnNwOyZuYnNwOzxjb2RlPi14c2wgNi1zcWxsaWItaW5zdGFudGRiLnhzbCAtb3V0IGltcG9ydDEuaHRtbDwvY29kZT48L3A+Ci0gICAgICA8L3MzPjxhbmNob3IgbmFtZT0iYmFzaWMtY29ubiIvPgotICAgICAgPHMzIHRpdGxlPSJCYXNpYy1Db25uZWN0aW9uIj4KLSAgICAgIDxwPjxlbT5Db250cmlidXRlZCBieSBKb2huIEdlbnRpbGluIChqb2huZ2xpbnV4QGV5ZWNhdGNoaW5nLmNvbSkuPC9lbT48L3A+Ci0gICAgICA8cD5XaGF0IGl0IGRvZXM6IGlsbHVzdHJhdGVzIHR3byBzdHJhdGVnaWVzIGZvciBjb25uZWN0aW5nIHRvIGEgZGF0YWJhc2UsIGV4ZWN1dGluZyBhIHN0YXRpYyBxdWVyeSwgYW5kIHJldHVybmluZyAKLSAgICAgIHRoZSBxdWVyeSByZXN1bHQuPC9wPgotICAgICAgPHA+VGhlIGZpcnN0IHN0cmF0ZWd5IGlzIHRvIGdldCBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGFsb25nIHdpdGggdGhlIHN0YXRpYyBxdWVyeSBmcm9tIHRoZSBzdHlsZXNoZWV0IChkYnRlc3QueHNsKVwKLSAgICAgIGluIHRoZSBmb3JtIG9mIHN0eWxlc2hlZXQgcGFyYW1ldGVycy48L3A+ICAgICAgCi0gICAgICA8cD5UaGUgc2Vjb25kIHN0cmF0ZWd5IGlzIHRvIGdldCBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGZyb20gYSBub2Rlc2V0IGluIGFuIFhNTCBzb3VyY2UgZG9jdW1lbnQgKGRiSW5mby54bWwpLjwvcD4KLSAgICAgIAotICAgICAgPHA+QWRkIGV4dGVuc2lvbnMvaW5zdGFudGRiL2lkYi5qYXIgdG8gdGhlIGNsYXNzcGF0aCwgYW5kIHJ1biB0aGlzIHNhbXBsZSBmcm9tIHRoZSBleHRlbnNpb25zL3NxbC9iYXNpYy1jb25uZWN0aW9uIAotICAgICAgIGRpcmVjdG9yeS48L3A+Ci0gICAgICAgPHA+MS4gVG8gZ2V0IGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gZnJvbSB0aGUgc3R5bGVzaGVldDo8L3A+Ci0gICAgICA8cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzPC9jb2RlPgotICAgICAgPGJyLz4mbmJzcDsmbmJzcDs8Y29kZT4teHNsIGRidGVzdC54c2wgLW91dCBpbXBvcnQxLmh0bWw8L2NvZGU+PC9wPgotICAgICAgPHA+Mi4gVG8gZ2V0IGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gaW4gdGhlIGZvcm0gb2YgYSBub2Rlc2V0IGZyb20gdGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQ6PC9wPiAgICAgIAotICAgICAgPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzczwvY29kZT4KLSAgICAgIDxici8+Jm5ic3A7Jm5ic3A7PGNvZGU+LWluIGRiaW5mby54bWwgLXhzbCBkYnRlc3QtY2luZm8ueHNsPC9jb2RlPiAKLSAgICAgIDxici8+Jm5ic3A7Jm5ic3A7PGNvZGU+LW91dCBpbXBvcnQxLmh0bWw8L2NvZGU+PC9wPgotICAgICAgPHA+My4gVG8gZ2V0IGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gZnJvbSB0aGUgc3R5bGVzaGVldCBhbmQgZHVtcCB0aGUgcmF3IHJlc3VsdCBzZXQgdG8gYW4gWE1MIGZpbGU6PC9wPgotICAgICAgPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHQuUHJvY2VzczwvY29kZT4KLSAgICAgIDxici8+Jm5ic3A7Jm5ic3A7PGNvZGU+LXhzbCBEdW1wU1FMLnhzbCAtb3V0IGltcG9ydDEueG1sPC9jb2RlPjwvcD4KLSAgICA8L3MzPiA8YW5jaG9yIG5hbWU9ImV4dC1jb25uIi8+Ci0gICAgPHMzIHRpdGxlPSJFeHRlcm5hbENvbm5lY3Rpb24iPgotICAgIDxwPjxlbT5Db250cmlidXRlZCBieSBKb2huIEdlbnRpbGluIChqb2huZ2xpbnV4QGV5ZWNhdGNoaW5nLmNvbSkuPC9lbT48L3A+Ci0gICAgPHA+V2hhdCBpdCBkb2VzOiBUaGUgRXh0ZXJuYWxDb25uZWN0aW9uIGNsYXNzZXMgdXNlcyB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ29ubmVjdGlvblBvb2wgaW50ZXJmYWNlIAotICAgIHRvIGNyZWF0ZSBhIHBvb2wgb2YgY29ubmVjdGlvbnMuIEEgc3R5bGVzaGVldCBpbiB0dXJuIHVzZXMgYSBjb25uZWN0aW9uIGZyb20gdGhpcyBwb29sIHRvIGluc3RhbnRpYXRlIGFuIAotICAgIFhDb25uZWN0aW9uIG9iamVjdCBhbmQgY29ubmVjdCB0byBhIGRhdGFzb3VjZS48L3A+Ci0gICAgPHA+VGhlIHN0eWxlc2hlZXQgdXNlcyB0aGlzIG5hbWVkIGNvbm5lY3Rpb24gcG9vbCB0byBpbnN0YW50aWF0ZSBhbiBYQ29ubmVjdGlvbiBvYmplY3QgYW5kIGNvbm5lY3QgdG8gdGhlIGRhdGFzb3VyY2UuPC9wPgotICAgIDxwPlRoZSBFeHRlcm5hbENvbm5lY3Rpb24gY2xhc3MgaXMgaW4geGFsYW5zYW1wbGVzLmphci4gQmUgc3VyZSB4YWxhbnNhbXBsZXMuamFyIGFuZCBpZGIuamFyIGFyZSBvbiB0aGUgY2xhc3NwYXRoLCBhbmQgCi0gICAgcnVuIHRoaXMgc2FtcGxlIGZyb20gdGhlIGV4dGVuc2lvbnMvc3FsL2V4dC1jb25uZWN0aW9uIGRpcmVjdG9yeTo8L3A+Ci0gICAgPHA+PGNvZGU+amF2YSBFeHRlcm5hbENvbm5lY3Rpb248L2NvZGU+PC9wPgotICAgIDxwPkV4dGVybmFsQ29ubmVjdGlvbiBjcmVhdGVzIHRoZSBDb25uZWN0aW9uUG9vbCwgYW5kIHBlcmZvcm1zIGEgdHJhbnNmb3JtYXRpb24gd2lodCBkYnRlc3QueHNsLCB3aGljaCBkcmF3cyAKLSAgICBmcm9tIHRoZSBwb29sIHRvIGluc3RhbnRpYXRlIGFuIFhDb25uZWN0aW9uIG9iamVjdCwgY29ubmVjdCB0byB0aGUgZGF0YXNvdXJjZSwgZXhlY3V0ZSBhIHN0YXRpYyBxdWVyeSwgYW5kIHJldHVybiB0aGUKLSAgICBxdWVyeSByZXN1bHQuPC9wPgotICAgIDwvczM+PGFuY2hvciBuYW1lPSJwcXVlcnkiLz4KLSAgICA8czMgdGl0bGU9IlBhcmFtZXRlcml6ZWQgcXVlcnkiPgotICAgIDxwPjxlbT5Db250cmlidXRlZCBieSBKb2huIEdlbnRpbGluIChqb2huZ2xpbnV4QGV5ZWNhdGNoaW5nLmNvbSkuPC9lbT48L3A+Ci0gICAgPHA+V2hhdCBpdCBkb2VzOiBjb25uZWN0IHRvIGEgZGF0YXNvdXJjZSwgZXhlY3V0ZSBhIHBhcmFtZXRlcml6ZWQgcXVlcnksIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4gVGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQKLSAgICBwcm92aWRlcyB0aGUgcGFyYW1ldGVyIHZhbHVlIGFzIHdlbGwgYXMgdGhlIGNvbm5lY3Rpb24gaW5mb3JtYXRpb24uIFRoZSBwYXJhbWV0ZXIgdmFsdWUgaXMgaW4gYSBub2RlIGluIHRoZSBYTUwgc291cmNlLjwvcD4KLSAgICA8cD5UaGUgc3R5bGVzaGVldCBnZXRzIHRoZSByZXF1aXJlZCBjb25uZWN0aW9uIGFuZCBwYXJhbWV0ZXIgaW5mb3JtYXRpb24gZnJvbSB0aGUgWE1MIHNvdXJjZSwgc2V0cyB1cCBhbmQgZXhlY3V0ZXMgdGhlCi0gICAgcGFyYW1ldGVyaXplZCBxdWVyeSwgYW5kIHJldHVucyB0aGUgcXVlcnkgcmVzdWx0IHNldC48L3A+Ci0gICAgPHA+QmUgc3VyZSBpZGIuamFyIGlzIG9uIHRoZSBjbGFzc3BhdGgsIGFuZCBydW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgc3FsL3BxdWVyeSBzdWJkaXJlY3Rvcnk6PC9wPgotICAgIDxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0LlByb2Nlc3MgLWluIGRiSW5mby54bWw8L2NvZGU+Ci0gICAgPGJyLz48Y29kZT4teHNsIGRiVGVzdC54c2wgLW91dCBkYlRlc3QuaHRtbDwvY29kZT48L3A+ICAgIAotICAgIDwvczM+PGFuY2hvciBuYW1lPSJzdHJlYW1hYmxlIi8+Ci0gICAgPHMzIHRpdGxlPSJTdHJlYW1hYmxlIj4KLSAgICA8cD48ZW0+Q29udHJpYnV0ZWQgYnkgSm9obiBHZW50aWxpbiAoam9obmdsaW51eEBleWVjYXRjaGluZy5jb20pLjwvZW0+PC9wPiAgICAKLSAgICA8cD5XaGF0IGl0IGRvZXM6IElsbHVzdHJhdGVzIGVuYWJsaW5nIGFuZCBkaXNhYmxpbmcgb2YgY2FjaGluZyB0aGUgc3RyZWFtYWJsZSByZXN1bHQgc2V0IHJldHVybmVkIGJ5IGEgcXVlcnkuPC9wPgotICAgIDxwPlRoZSBzdHlsZXNoZWV0cyB1c2UgdGhlIFhDb25uZWN0aW9uIGVuYWJsZUNhY2hlTm9kZXMoKSBhbmQgZGlzYWJsZUNhY2hlTm9kZXMoKSBtZXRob2RzLjwvcD4KLSAgICA8cD5CZSBzdXJlIGlkYi5qYXIgaXMgb24gdGhlIGNsYXNzcGF0aCwgYW5kIHJ1biB0aGVzZSBzYW1wbGVzIGZyb20gdGhlIHNxbC9zdHJlYW1hYmxlIHN1YmRpcmVjdG9yeS48L3A+Ci0gICAgPHA+MS4gVG8gdHVybiBjYWNoaW5nIG9uOjwvcD4KLSAgICA8cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzPC9jb2RlPgotICAgIDxici8+PGNvZGU+LXhzbCBjYWNoZWROb2Rlcy54c2w8L2NvZGU+PC9wPgotICAgIDxwPjEuIFRvIHR1cm4gY2FjaGluZyBvZmY6PC9wPgotICAgIDxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0LlByb2Nlc3M8L2NvZGU+Ci0gICAgPGJyLz48Y29kZT4teHNsIHN0cmVhbU5vZGVzLnhzbDwvY29kZT48L3A+Ci0gICAgPHA+My4gPHJlZj5UbyBiZSBhZGRlZDwvcmVmPjwvcD4KLSAgICA8L3MzPjxhbmNob3IgbmFtZT0ic2hvd2Vycm9yIi8+Ci0gICAgPHMzIHRpdGxlPSJTaG93LWVycm9yIj4KLSAgICA8cD48ZW0+Q29udHJpYnV0ZWQgYnkgSm9obiBHZW50aWxpbiAoam9obmdsaW51eEBleWVjYXRjaGluZy5jb20pLjwvZW0+PC9wPgotICAgIDxwPldoYXQgaXQgZG9lczogdXNlIHRoZSBTUUwgbGlicmFyeSBFeHRlbnNpb25FcnJvciBjbGFzcyB0byByZXR1cm4gYW4gZXJyb3IgbWVzc2FnZSBpbiB0aGUgb3V0cHV0IHN0cmVhbS4gVGhlIHN0eWxlc2hlZXQKLSAgICBjYWxscyBhIHRlbXBsYXRlIHdpdGggYSBzZWxlY3Qgc3RhdGVtZW50IHRoYXQgcmV0dXJucyBhIG5vZGVzZXQgd2hlbiBhbiBlcnJvciBvY2N1cnMuPC9wPgotICAgIDxzb3VyY2U+Jmx0O3hzbDp2YXJpYWJsZSBuYW1lPSJ0YWJsZSIgc2VsZWN0PSdzcWw6cXVlcnkoJGRiLCAkcXVlcnkpJy8mZ3Q7Ci0gICZsdDt4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iJHRhYmxlL3Jvdy1zZXQiIC8mZ3Q7CQotICAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IiR0YWJsZS9leHQtZXJyb3IiLyZndDs8L3NvdXJjZT4KLSAgPHA+V2l0aCBpZGIuamFyIG9uIHRoZSBjbGFzc3BhdGgsIHJ1biB0aGlzIHNhbXBsZSBmcm9tIHRoZSBleHRlbnNpb25zL3NxbC9zaG93LWVycm9yIHN1YmRpcmVjdG9yeTo8L3A+Ci0gIDxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0LlByb2Nlc3M8L2NvZGU+Ci0gIDxici8+PGNvZGU+IC14c2wgPHJlZj5pbnZhbGlkU29tZXRoaW5nLnhzbDwvcmVmPiAtb3V0IGRidGVzdG91dC5odG1sPC9jb2RlPjwvcD4KLSAgPHA+d2hlcmUgPHJlZj5pbnZhbGlkU29tZXRoaW5nLnhzbDwvcmVmPiBpcyA8Y29kZT5pbnZhbGlkQ29ubi54c2w8L2NvZGU+IChzcGVjaWZpZXMgYSBkYXRhYmFzZSB0aGF0IGRvZXMgbm90IGV4aXN0KSwgCi0gIDxjb2RlPmludmFsaWRRdWVyeS54c2w8L2NvZGU+IChzcGVjaWZpZXMgYSB0YWJsZSB0aGF0IGRvZXMgbm90IGV4aXN0KSwgb3IgPGNvZGU+aW52YWxpZFBRdWVyeS54c2w8L2NvZGU+IChpbmNsdWRlcwotICB0b28gbWFueSBwYXJhbWV0ZXJzIGZvciB0aGUgcGFyYW1ldGVyaXplZCBxdWVyeSkuPC9wPgotICAgIDwvczM+Ci0gICAgPC9zMj48YW5jaG9yIG5hbWU9InRyYWNlIi8+Ci0gICAgPHMyIHRpdGxlPSJUcmFjZSI+Ci0gICAgICA8cD5XaGF0IGl0IGRvZXM6IFRyYWNlIHVzZXMgdGhlIFRyYWNlTGlzdGVuZXIgYW5kIFRyYWNlTWFuYWdlciBjbGFzc2VzIHRvIGxvZyB0cmFuc2Zvcm1hdGlvbiBldmVudHMuPC9wPgotICAgICAgPHA+UnVuIHRoaXMgc2FtcGxlIGZyb20gdGhlIFRyYWNlIHN1YmRpcmVjdG9yeSB3aXRoPC9wPgotICAgICAgPHA+PGNvZGU+amF2YSBUcmFjZTwvY29kZT48L3A+Ci0gICAgICA8cD5hbmQgZXhhbWluZSB0aGUgcmVzdWx0IGluIGV2ZW50cy5sb2cuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiIGFuY2hvcj0iZGVidWdnaW5nIj5EZWJ1Z2dlcgotICAgICAgSW50ZXJmYWNlPC9saW5rPjwvcD4KLSAgICAgPC9zMj48YW5jaG9yIG5hbWU9InZhbGlkYXRlIi8+Ci0gICAgIDxzMiB0aXRsZT0iVmFsaWRhdGUiPgotICAgICA8cD5XaGF0IGl0IGRvZXM6IFVzZXMgdGhlIDxqdW1wIGhyZWY9ImFwaWRvY3NcamF2YXhceG1sXHBhcnNlcnNcU0FYUGFyc2VyLmh0bWwiPkpBWFAgU0FYUGFyc2VyPC9qdW1wPiB3aXRoIGEgU0FYIGV2ZW50IGhhbmRsZXIgCi0gICAgIChleHRlbmRzIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL3htbC9zYXgvaGVscGVycy9EZWZhdWx0SGFuZGxlci5odG1sIj5EZWZhdWx0SGFuZGxlcjwvanVtcD4gYW5kIGltcGxlbWVudHMgCi0gICAgIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL3htbC9zYXgvZXh0L0xleGljYWxIYW5kbGVyLmh0bWwiPkxleGljYWxIYW5kbGVyPC9qdW1wPikgdG8gdmVyaWZ5IHRoYXQgWE1MIGZpbGVzIGNvbmZvcm0gdG8gdGhlaXIgZGVjbGFyZWQgCi0gICAgIGRvY3VtZW50IHR5cGUuIFlvdSBjYW4gdXNlIHRoaXMgdXRpbGl0eSB0byB2ZXJpZnkgdGhhdCBhbiBpbmRpdmlkdWFsIGZpbGUgb3IgYWxsIHRoZSAueG1sIGZpbGVzIGluIGEgZGlyZWN0b3J5IGFyZQotICAgICB3ZWxsLWZvcm1lZCBhbmQgdmFsaWQuIEVhY2ggLnhtbCBmaWxlIHNob3VsZCBjb250YWluIGEgRE9DVFlQRSBkZWNsYXJhdGlvbi48L3A+Ci0gICAgIDxwPlJ1biB0aGlzIHNhbXBsZSBmcm9tIGFueSBkaXJlY3Rvcnkgd2l0aDwvcD4KLSAgICAgPHA+PGNvZGU+amF2YSBWYWxpZGF0ZSA8cmVmPmZpbGUtb3ItZGlyLW5hbWU8L3JlZj4gWzxyZWY+bG9nZmlsZTwvcmVmPjwvY29kZT5dPC9wPgotICAgICA8cD53aGVyZSA8cmVmPmZpbGUtb3ItZGlyLW5hbWU8L3JlZj4gaXMgYW4gWE1MIGZpbGUgb3IgZGlyZWN0b3J5IHBhdGhuYW1lLCBhbmQgPHJlZj5sb2dmaWxlPC9yZWY+IGRlc2lnbmF0ZXMgYSBsb2cuCi0gICAgIElmIHlvdSBvbWl0IHRoZSBzZWNvbmQgYXJndW1lbnQsIFZhbGlkYXRlIHJlcG9ydHMgaXRzIGZpbmRpbmdzIHRvIHRoZSBzY3JlZW4uPC9wPgotICAgICA8bm90ZT5BIGxpbWl0YXRpb246IEZpbGVzIGNvbnRhaW5pbmcgZG9jdW1lbnQgcGFydHMgYXBwZWFyIHRvIGZhaWwgaWYgeW91IGNoZWNrIHRoZW0gd2l0aCBWYWxpZGF0ZS4gQ2hlY2sgcmVhZG1lLnhtbCwgCi0gICAgIHdoaWNoICJpbmNsdWRlcyIgYnkgZW50aXR5IHJlZmVyZW5jZSBhIG51bWJlciBvZiBmaWxlcywgYW5kIGl0IHBhc3Nlcy4gVGhlIHBhcnNlIG9wZXJhdGlvbiBzY2FucyB0aGUgZW50aXJlIGRvY3VtZW50Ci0gICAgIHdpdGggdGhlIGluY2x1ZGVzLiBDaGVjayBhbiAiaW5jbHVkZWQiIGZpbGUgKHN1Y2ggYXMgaGlzdG9yeS54bWwpIGFzIGlmIGl0IHdlcmUgYW4gaW5kZXBlbmRlbnQgZG9jdW1lbnQgYW5kIGl0IGZhaWxzLjwvbm90ZT4KLSAgICAgPC9zMj4KLSAgICAgPGFuY2hvciBuYW1lPSJ0cmF4Ii8+Ci0gICAgIDxzMiB0aXRsZT0idHJheCI+Ci0gICAgIDxwPldoYXQgaXQgZG9lczogcnVuIGEgbnVtYmVyIG9mIHNhbXBsZXMgaWxsdXN0cmF0aW5nIHVzZXMgb2YgdGhlIDxsaW5rIGlkcmVmPSJ0cmF4Ij5UUmFYIChUcmFuc2Zvcm1hdGlvbiBBUEkgZm9yIFhNTCk8L2xpbms+IGludGVyZmFjZXMuPC9wPgotICAgICA8cD5SdW4gdGhpcyBzYW1wbGUgZnJvbSB0aGUgdHJheCBzdWJkaXJlY3Rvcnkgd2l0aDwvcD4KLSAgICAgPHA+PGNvZGU+amF2YSBFeGFtcGxlczwvY29kZT48L3A+Ci0gICAgIDxwPmFuZCBleGFtaW5lIHRoZSBzb3VyY2UgaW4gRXhhbXBsZXMuamF2YSBhbmQgRXhhbXBsZUNvbnRlbnRIYW5kbGVyLmphdmEuPC9wPgotICAgICA8L3MyPiZ4c2x0Y3NhbXBsZXM7Ci08L3MxPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveGFsYW4vdHJheC54bWwgYi94ZG9jcy9zb3VyY2VzL3hhbGFuL3RyYXgueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkNjg4ZGE1Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4vdHJheC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwzODIgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLTxzMSB0aXRsZT0iVHJhbnNmb3JtYXRpb24gQVBJIEZvciBYTUwiPgotPHVsPgotIDxsaT48bGluayBhbmNob3I9ImludHJvIj5JbnRyb2R1Y3Rpb248L2xpbms+PC9saT4KLSA8bGk+PGxpbmsgYW5jaG9yPSJ0ZXJtaW5vbG9neSI+R2VuZXJhbCBUZXJtaW5vbG9neTwvbGluaz48L2xpPgotIDxsaT48bGluayBhbmNob3I9InJlcXVpcmVtZW50cyI+UmVxdWlyZW1lbnRzPC9saW5rPjwvbGk+Ci0gPGxpPjxsaW5rIGFuY2hvcj0ibW9kZWwiPk1vZGVsPC9saW5rPjwvbGk+Ci0gPGxpPjxsaW5rIGFuY2hvcj0icGF0dGVybnMiPlBhdHRlcm5zPC9saW5rPjwvbGk+IAotPC91bD48YW5jaG9yIG5hbWU9ImludHJvIi8+Ci08czIgdGl0bGU9IkludHJvZHVjdGlvbiI+ICAgCi08cD5UaGlzIGRvY3VtZW50IGRlc2NyaWJlcyB0aGUgdHJhbnNmb3JtYXRpb24gQVBJIGZvciBYTUwgKFRyQVgpLCB0aGUgc2V0IG9mIEFQSXMgY29udGFpbmVkIGluCi0JIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+amF2YXgueG1sLnRyYW5zZm9ybTwvanVtcD4sIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPmphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtPC9qdW1wPiwgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+amF2YXgueG1sLnRyYW5zZm9ybS5kb208L2p1bXA+LCBhbmQgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9wYWNrYWdlLXN1bW1hcnkuaHRtbCI+amF2YXgueG1sLnRyYW5zZm9ybS5zYXg8L2p1bXA+LjwvcD4gCi0gIAotPHA+VGhlcmUgaXMgYSBicm9hZCBuZWVkIGZvciBKYXZhIGFwcGxpY2F0aW9ucyB0byBiZSBhYmxlIHRvIHRyYW5zZm9ybSBYTUwKLQkgYW5kIHJlbGF0ZWQgdHJlZS1zaGFwZWQgZGF0YSBzdHJ1Y3R1cmVzLiBJbiBmYWN0LCBYTUwgaXMgbm90IG5vcm1hbGx5IHZlcnkKLQkgdXNlZnVsIHRvIGFuIGFwcGxpY2F0aW9uIHdpdGhvdXQgZ29pbmcgdGhyb3VnaCBzb21lIHNvcnQgb2YgdHJhbnNmb3JtYXRpb24sCi0JIHVubGVzcyB0aGUgc2VtYW50aWMgc3RydWN0dXJlIGlzIHVzZWQgZGlyZWN0bHkgYXMgZGF0YS4gQWxtb3N0IGFsbCBYTUwtcmVsYXRlZAotCSBhcHBsaWNhdGlvbnMgbmVlZCB0byBwZXJmb3JtIHRyYW5zZm9ybWF0aW9ucy4gVHJhbnNmb3JtYXRpb25zIG1heSBiZSBkZXNjcmliZWQKLQkgYnkgSmF2YSBjb2RlLCBQZXJsIGNvZGUsIDxqdW1wIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3hzbHQiPlhTTFQ8L2p1bXA+Ci0JIFN0eWxlc2hlZXRzLCBvdGhlciB0eXBlcyBvZiBzY3JpcHQsIG9yIGJ5IHByb3ByaWV0YXJ5IGZvcm1hdHMuIFRoZSBpbnB1dHMsIG9uZQotCSBvciBtdWx0aXBsZSwgdG8gYSB0cmFuc2Zvcm1hdGlvbiwgbWF5IGJlIGEgVVJMLCBYTUwgc3RyZWFtLCBhIERPTSB0cmVlLCBTQVgKLQkgRXZlbnRzLCBvciBhIHByb3ByaWV0YXJ5IGZvcm1hdCBvciBkYXRhIHN0cnVjdHVyZS4gVGhlIG91dHB1dCB0eXBlcyBhcmUgdGhlCi0JIHByZXR0eSBtdWNoIHRoZSBzYW1lIHR5cGVzIGFzIHRoZSBpbnB1dHMsIGJ1dCBkaWZmZXJlbnQgaW5wdXRzIG1heSBuZWVkIHRvIGJlCi0JIGNvbWJpbmVkIHdpdGggZGlmZmVyZW50IG91dHB1dHMuPC9wPiAKLSAgCi08cD5UaGUgZ3JlYXQgY2hhbGxlbmdlIG9mIGEgdHJhbnNmb3JtYXRpb24gQVBJIGlzIGhvdyB0byBkZWFsIHdpdGggYWxsIHRoZQotCSBwb3NzaWJsZSBjb21iaW5hdGlvbnMgb2YgaW5wdXRzIGFuZCBvdXRwdXRzLCB3aXRob3V0IGJlY29taW5nIHNwZWNpYWxpemVkIGZvcgotCSBhbnkgb2YgdGhlIGdpdmVuIHR5cGVzLjwvcD4gCi0gIAotPHA+VGhlIEphdmEgY29tbXVuaXR5IHdpbGwgZ3JlYXRseSBiZW5lZml0IGZyb20gYSBjb21tb24gQVBJIHRoYXQgd2lsbAotCSBhbGxvdyB0aGVtIHRvIHVuZGVyc3RhbmQgYW5kIGFwcGx5IGEgc2luZ2xlIG1vZGVsLCB3cml0ZSB0byBjb25zaXN0ZW50Ci0JIGludGVyZmFjZXMsIGFuZCBhcHBseSB0aGUgdHJhbnNmb3JtYXRpb25zIHBvbHltb3JwaGljYWxseS4gVHJBWCBhdHRlbXB0cyB0bwotCSBkZWZpbmUgYSBtb2RlbCB0aGF0IGlzIGNsZWFuIGFuZCBnZW5lcmljLCB5ZXQgZmlsbHMgZ2VuZXJhbCBhcHBsaWNhdGlvbgotCSByZXF1aXJlbWVudHMgYWNyb3NzIGEgd2lkZSB2YXJpZXR5IG9mIHVzZXMuIDwvcD4gCi0gICAKLTwvczI+PGFuY2hvciBuYW1lPSJ0ZXJtaW5vbG9neSIvPgkgCi08czIgdGl0bGU9IkdlbmVyYWwgVGVybWlub2xvZ3kiPiAKLQkgCi08cD5UaGlzIHNlY3Rpb24gd2lsbCBleHBsYWluIHNvbWUgZ2VuZXJhbCB0ZXJtaW5vbG9neSB1c2VkIGluIHRoaXMKLQkJZG9jdW1lbnQuIFRlY2huaWNhbCB0ZXJtaW5vbG9neSB3aWxsIGJlIGV4cGxhaW5lZCBpbiB0aGUgTW9kZWwgc2VjdGlvbi4gSW4gbWFueQotCQljYXNlcywgdGhlIGdlbmVyYWwgdGVybWlub2xvZ3kgb3ZlcmxhcHMgd2l0aCB0aGUgdGVjaG5pY2FsIHRlcm1pbm9sb2d5LjwvcD4gCi0JIAotPGdsb3NzPgotPGxhYmVsPlRyZWU8L2xhYmVsPgotPGl0ZW0+VGhpcyB0ZXJtLCBhcyB1c2VkIHdpdGhpbiB0aGlzIGRvY3VtZW50LCBkZXNjcmliZXMgYW4KLQkJCSBhYnN0cmFjdCBzdHJ1Y3R1cmUgdGhhdCBjb25zaXN0cyBvZiBub2RlcyBvciBldmVudHMgdGhhdCBtYXkgYmUgcHJvZHVjZWQgYnkKLQkJCSBYTUwuIEEgVHJlZSBwaHlzaWNhbGx5IG1heSBiZSBhIERPTSB0cmVlLCBhIHNlcmllcyBvZiB3ZWxsIGJhbGFuY2VkIHBhcnNlCi0JCQkgZXZlbnRzIChzdWNoIGFzIHRob3NlIGNvbWluZyBmcm9tIGEgU0FYMiBDb250ZW50SGFuZGVyKSwgYSBzZXJpZXMgb2YgcmVxdWVzdHMKLQkJCSAodGhlIHJlc3VsdCBvZiB3aGljaCBjYW4gZGVzY3JpYmUgYSB0cmVlKSwgb3IgYSBzdHJlYW0gb2YgbWFya2VkLXVwCi0JCQkgY2hhcmFjdGVycy48L2l0ZW0+Ci0KLTxsYWJlbD5Tb3VyY2UgVHJlZShzKTwvbGFiZWw+Ci08aXRlbT5PbmUgb3IgbW9yZSB0cmVlcyB0aGF0IGFyZSB0aGUgaW5wdXRzIHRvIHRoZQotCQkJIHRyYW5zZm9ybWF0aW9uLjwvaXRlbT4KLQotPGxhYmVsPlJlc3VsdCBUcmVlKHMpPC9sYWJlbD4KLTxpdGVtPk9uZSBvciBtb3JlIHRyZWVzIHRoYXQgYXJlIHRoZSBvdXRwdXQgb2YgdGhlCi0JCQkgdHJhbnNmb3JtYXRpb24uPC9pdGVtPgotCi0KLQotPGxhYmVsPlRyYW5zZm9ybWF0aW9uPC9sYWJlbD4KLTxpdGVtPlRoZSBwcm9jZXNzIG9mIGNvbnN1bWluZyBhIHN0cmVhbSBvciB0cmVlIHRvIHByb2R1Y2UKLQkJCSBhbm90aGVyIHN0cmVhbSBvciB0cmVlLjwvaXRlbT4KLQotCi0KLTxsYWJlbD5JZGVudGl0eSAob3IgQ29weSkgVHJhbnNmb3JtYXRpb248L2xhYmVsPgotPGl0ZW0+VGhlIHByb2Nlc3Mgb2YgdHJhbnNmb3JtYXRpb24gZnJvbSBhIHNvdXJjZSB0byBhIHJlc3VsdCwKLQkJCSBtYWtpbmcgYXMgZmV3IHN0cnVjdHVyYWwgY2hhbmdlcyBhcyBwb3NzaWJsZSBhbmQgbm8gaW5mb3JtYXRpb25hbCBjaGFuZ2VzLiBUaGUKLQkJCSB0ZXJtIGlzIHNvbWV3aGF0IGxvb3NlbHkgdXNlZCwgYXMgdGhlIHByb2Nlc3MgaXMgcmVhbGx5IGEgY29weS4gZnJvbSBvbmUKLQkJCSAiZm9ybWF0IiAoc3VjaCBhcyBhIERPTSB0cmVlLCBzdHJlYW0sIG9yIHNldCBvZiBTQVggZXZlbnRzKSB0bwotCQkJIGFub3RoZXIuPC9pdGVtPgotCi0KLQotPGxhYmVsPlNlcmlhbGl6YXRpb248L2xhYmVsPgotPGl0ZW0+VGhlIHByb2Nlc3Mgb2YgdGFraW5nIGEgdHJlZSBhbmQgdHVybmluZyBpdCBpbnRvIGEgc3RyZWFtLiBJbgotCQkJIHNvbWUgc2Vuc2UsIGEgc2VyaWFsaXphdGlvbiBpcyBhIHNwZWNpYWxpemVkIHRyYW5zZm9ybWF0aW9uLjwvaXRlbT4KLQotCi0KLTxsYWJlbD5QYXJzaW5nPC9sYWJlbD4KLTxpdGVtPlRoZSBwcm9jZXNzIG9mIHRha2luZyBhIHN0cmVhbSBhbmQgdHVybmluZyBpdCBpbnRvIGEgdHJlZS4gSW4KLQkJCSBzb21lIHNlbnNlLCBwYXJzaW5nIGlzIGEgc3BlY2lhbGl6ZWQgdHJhbnNmb3JtYXRpb24uPC9pdGVtPgotCi0KLQotPGxhYmVsPlRyYW5zZm9ybWVyPC9sYWJlbD4KLTxpdGVtPkEgVHJhbnNmb3JtZXIgaXMgdGhlIG9iamVjdCB0aGF0IGV4ZWN1dGVzIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLQkJCSA8L2l0ZW0+Ci0KLQotCi08bGFiZWw+VHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zPC9sYWJlbD4KLTxpdGVtPkRlc2NyaWJlcyB0aGUgdHJhbnNmb3JtYXRpb24uIEEgZm9ybSBvZiBjb2RlLCBzY3JpcHQsIG9yCi0JCQkgc2ltcGx5IGEgZGVjbGFyYXRpb24gb3Igc2VyaWVzIG9mIGRlY2xhcmF0aW9ucy48L2l0ZW0+Ci0KLQotCi08bGFiZWw+U3R5bGVzaGVldDwvbGFiZWw+Ci08aXRlbT5UaGUgc2FtZSBhcyAidHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLCIgZXhjZXB0IGl0IGlzCi0JCQkgbGlrZWx5IHRvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij5YU0xUPC9qdW1wPi48L2l0ZW0+Ci0KLQotCi08bGFiZWw+VGVtcGxhdGVzPC9sYWJlbD4KLTxpdGVtPkFub3RoZXIgZm9ybSBvZiAidHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLiIgSW4gdGhlIFRyQVgKLQkJCSBpbnRlcmZhY2UsIHRoaXMgdGVybSBpcyB1c2VkIHRvIGRlc2NyaWJlIHByb2Nlc3NlZCBvciBjb21waWxlZCB0cmFuc2Zvcm1hdGlvbgotCQkJIGluc3RydWN0aW9ucy4gVGhlIFNvdXJjZSBmbG93cyB0aHJvdWdoIGEgVGVtcGxhdGVzIG9iamVjdCB0byBiZSBmb3JtZWQgaW50byB0aGUKLQkJCSBSZXN1bHQuPC9pdGVtPgotCi0KLQotPGxhYmVsPlByb2Nlc3NvcjwvbGFiZWw+Ci08aXRlbT5BIGdlbmVyYWwgdGVybSBmb3IgdGhlIHRoaW5nIHRoYXQgbWF5IGJvdGggcHJvY2VzcyB0aGUKLQkJCSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsIGFuZCBwZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbi48L2l0ZW0+Ci0KLSAgICAgICAKLQotCi08bGFiZWw+RE9NPC9sYWJlbD4KLTxpdGVtPkRvY3VtZW50IE9iamVjdCBNb2RlbCwgc3BlY2lmaWNhbGx5IHJlZmVycmluZyB0byB0aGUKLQkJCSA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMiUyMCI+RG9jdW1lbnQgT2JqZWN0IE1vZGVsCi0JCQkgKERPTSkgTGV2ZWwgMiBTcGVjaWZpY2F0aW9uPC9qdW1wPi48L2l0ZW0+Ci0KLQotPGxhYmVsPlNBWDwvbGFiZWw+Ci08aXRlbT5TaW1wbGUgQVBJIGZvciBYTUwsIHNwZWNpZmljYWxseSByZWZlcnJpbmcgdG8gdGhlCi0JCQkgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy5tZWdnaW5zb24uY29tL1NBWC9TQVgyIj5TQVggMi4wCi0JCQkgcmVsZWFzZTwvanVtcD4uPC9pdGVtPgotPC9nbG9zcz4gCi08L3MyPiA8YW5jaG9yIG5hbWU9InJlcXVpcmVtZW50cyIvPgotPHMyIHRpdGxlPSJSZXF1aXJlbWVudHMiPiAKLSAgCi08cD5UaGUgZm9sbG93aW5nIHJlcXVpcmVtZW50cyBoYXZlIGJlZW4gZGV0ZXJtaW5lZCBmcm9tIGJyb2FkIGV4cGVyaWVuY2UKLQkgd2l0aCBYTUwgcHJvamVjdHMgZnJvbSB0aGUgdmFyaW91cyBtZW1iZXJzIHBhcnRpY2lwYXRpbmcgb24gdGhlIEpDUC48L3A+IAotICAKLTx1bD4KLTxsaT5UckFYIG11c3QgcHJvdmlkZSBhIGNsZWFuLCBzaW1wbGUKLQkJaW50ZXJmYWNlIGZvciBzaW1wbGUgdXNlcy48L2xpPgotPGxpPlRyQVggbXVzdCBiZSBwb3dlcmZ1bCBlbm91Z2ggdG8gYmUKLQkJYXBwbGllZCB0byBhIHdpZGUgcmFuZ2Ugb2YgdXNlcywgc3VjaCBhcywgZS1jb21tZXJjZSwgY29udGVudCBtYW5hZ2VtZW50LAotCQlzZXJ2ZXIgY29udGVudCBkZWxpdmVyeSwgYW5kIGNsaWVudCBhcHBsaWNhdGlvbnMuPC9saT4KLTxsaT5BIHByb2Nlc3NvciB0aGF0IGltcGxlbWVudHMgYSBUckFYCi0JCWludGVyZmFjZSBtdXN0IGJlIG9wdGltaXplYWJsZS4gUGVyZm9ybWFuY2UgaXMgYSBjcml0aWNhbCBpc3N1ZSBmb3IgbW9zdAotCQl0cmFuc2Zvcm1hdGlvbiB1c2UgY2FzZXMuPC9saT4KLTxsaT5BcyBhIHNwZWNpYWxpemF0aW9uIG9mIHRoZSBhYm92ZQotCQlyZXF1aXJlbWVudCwgYSBUckFYIHByb2Nlc3NvciBtdXN0IGJlIGFibGUgdG8gc3VwcG9ydCBhIGNvbXBpbGVkIG1vZGVsLCBzbyB0aGF0Ci0JCWEgc2luZ2xlIHNldCBvZiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMgY2FuIGJlIGNvbXBpbGVkLCBvcHRpbWl6ZWQsIGFuZAotCQlhcHBsaWVkIHRvIGEgbGFyZ2Ugc2V0IG9mIGlucHV0IHNvdXJjZXMuPC9saT4KLTxsaT5UckFYIG11c3Qgbm90IGJlIGRlcGVuZGVudCBhbiBhbnkKLQkJZ2l2ZW4gdHlwZSBvZiB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuIEZvciBpbnN0YW5jZSwgaXQgbXVzdCByZW1haW4KLQkJaW5kZXBlbmRlbnQgb2YgPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveHNsdCI+WFNMVDwvanVtcD4uPC9saT4KLTxsaT5UckFYIG11c3QgYmUgYWJsZSB0byBhbGxvdyBwcm9jZXNzb3JzCi0JCXRvIHRyYW5zZm9ybSBET00gdHJlZXMuPC9saT4KLTxsaT5UckFYIG11c3QgYmUgYWJsZSB0byBhbGxvdyBwcm9jZXNzb3JzIHRvCi0JCXByb2R1Y2UgRE9NIHRyZWVzLjwvbGk+Ci08bGk+VHJBWCBtdXN0IGFsbG93IHByb2Nlc3NvcnMgdG8gdHJhbnNmb3JtCi0JCVNBWCBldmVudHMuPC9saT4KLTxsaT5UckFYIG11c3QgYWxsb3cgcHJvY2Vzc29ycyB0byBwcm9kdWNlIFNBWAotCQlldmVudHMuPC9saT4KLTxsaT5UckFYIG11c3QgYWxsb3cgcHJvY2Vzc29ycyB0bwotCQl0cmFuc2Zvcm0gc3RyZWFtcyBvZiBYTUwuPC9saT4KLTxsaT5UckFYIG11c3QgYWxsb3cgcHJvY2Vzc29ycyB0byBwcm9kdWNlCi0JCVhNTCwgSFRNTCwgYW5kIG90aGVyIHR5cGVzIG9mIHN0cmVhbXMuPC9saT4KLTxsaT5UckFYIG11c3QgYWxsb3cgcHJvY2Vzc29ycyB0bwotCQlpbXBsZW1lbnQgdGhlIHZhcmlvdXMgY29tYmluYXRpb25zIG9mIGlucHV0cyBhbmQgb3V0cHV0cyB3aXRoaW4gYSBzaW5nbGUKLQkJcHJvY2Vzc29yLjwvbGk+Ci08bGk+VHJBWCBtdXN0IGFsbG93IHByb2Nlc3NvcnMKLQkJdG8gaW1wbGVtZW50IG9ubHkgYSBsaW1pdGVkIHNldCBvZiBpbnB1dHMuIEZvciBpbnN0YW5jZSwgaXQgc2hvdWxkIGJlIHBvc3NpYmxlCi0JCXRvIHdyaXRlIGEgcHJvY2Vzc29yIHRoYXQgaW1wbGVtZW50cyB0aGUgVHJBWCBpbnRlcmZhY2VzIGFuZCB0aGF0IG9ubHkKLQkJcHJvY2Vzc2VzIERPTSB0cmVlcywgbm90IHN0cmVhbXMgb3IgU0FYIGV2ZW50cy48L2xpPgotPGxpPlRyQVggc2hvdWxkIGFsbG93IGEKLQkJcHJvY2Vzc29yIHRvIGltcGxlbWVudCB0cmFuc2Zvcm1hdGlvbnMgb2YgcHJvcHJpZXRhcnkgZGF0YSBzdHJ1Y3R1cmVzLiBGb3IKLQkJaW5zdGFuY2UsIGl0IHNob3VsZCBiZSBwb3NzaWJsZSB0byBpbXBsZW1lbnQgYSBwcm9jZXNzb3IgdGhhdCBwcm92aWRlcyBUckFYCi0JCWludGVyZmFjZXMgdGhhdCBwZXJmb3JtcyB0cmFuc2Zvcm1hdGlvbiBvZiBKRE9NIHRyZWVzLjwvbGk+Ci08bGk+VHJBWCBtdXN0IGFsbG93IHRoZSBzZXR0aW5nCi0JCW9mIHNlcmlhbGl6YXRpb24gcHJvcGVydGllcywgd2l0aG91dCBjb25zdHJhaW50IGFzIHRvIHdoYXQgdGhlIGRldGFpbHMgb2YgdGhvc2UKLQkJcHJvcGVydGllcyBhcmUuPC9saT4KLTxsaT5UckFYIG11c3QgYWxsb3cgdGhlIHNldHRpbmcKLQkJb2YgcGFyYW1ldGVycyB0byB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zLjwvbGk+Ci08bGk+VHJBWCBtdXN0IHN1cHBvcnQgdGhlCi0JCXNldHRpbmcgb2YgcGFyYW1ldGVycyBhbmQgcHJvcGVydGllcyBhcyBYTUwgTmFtZXNwYWNlZCBpdGVtcyAoaS5lLiwgcXVhbGlmaWVkCi0JCW5hbWVzKS48L2xpPgotPGxpPlRyQVggbXVzdCBzdXBwb3J0IFVSTAotCQlyZXNvbHV0aW9uIGZyb20gd2l0aGluIHRoZSB0cmFuc2Zvcm1hdGlvbiwgYW5kIGhhdmUgaXQgcmV0dXJuIHRoZSBuZWVkZWQgZGF0YQotCQlzdHJ1Y3R1cmUuPC9saT4KLTxsaT5UckFYIG11c3QgaGF2ZSBhIG1lY2hhbmlzbSBmb3IKLQkJcmVwb3J0aW5nIGVycm9ycyBhbmQgd2FybmluZ3MgdG8gdGhlIGNhbGxpbmcgYXBwbGljYXRpb24uPC9saT4KLTwvdWw+ICAKLSAgIAotPC9zMj4gPGFuY2hvciBuYW1lPSJtb2RlbCIvPgotPHMyIHRpdGxlPSJNb2RlbCI+IAotICAKLTxwPlRoZSBzZWN0aW9uIGRlZmluZXMgdGhlIGFic3RyYWN0IG1vZGVsIGZvciBUckFYLCBhcGFydCBmcm9tIHRoZSBkZXRhaWxzCi0JIG9mIHRoZSBpbnRlcmZhY2VzLjwvcD4gCi0gIAotPHA+QSBUUmFYIDxsaW5rIGFuY2hvcj0icGF0dGVybi1UcmFuc2Zvcm1lckZhY3RvcnkiPlRyYW5zZm9ybWVyRmFjdG9yeTwvbGluaz4gaXMgYW4gb2JqZWN0Ci0JIHRoYXQgcHJvY2Vzc2VzIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucywgYW5kIHByb2R1Y2VzCi0JIDxsaW5rIGFuY2hvcj0icGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvbGluaz4gKGluIHRoZSB0ZWNobmljYWwKLQkgdGVybWlub2xvZ3kpLiBBIDxsaW5rIGFuY2hvcj0icGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvbGluaz4KLQkgb2JqZWN0IHByb3ZpZGVzIGEgPGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVRyYW5zZm9ybWVyIj5UcmFuc2Zvcm1lcjwvbGluaz4sIHdoaWNoIHRyYW5zZm9ybXMgb25lIG9yCi0JIG1vcmUgPGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVNvdXJjZSI+U291cmNlPC9saW5rPnMgaW50byBvbmUgb3IgbW9yZQotCSA8bGluayBhbmNob3I9InBhdHRlcm4tUmVzdWx0Ij5SZXN1bHQ8L2xpbms+cy48L3A+IAotICAKLTxwPlRvIHVzZSB0aGUgVFJhWCBpbnRlcmZhY2UsIHlvdSBjcmVhdGUgYQotCSA8bGluayBhbmNob3I9InBhdHRlcm4tVHJhbnNmb3JtZXJGYWN0b3J5Ij5UcmFuc2Zvcm1lckZhY3Rvcnk8L2xpbms+LAotCSB3aGljaCBtYXkgZGlyZWN0bHkgcHJvdmlkZSBhIDxsaW5rIGFuY2hvcj0icGF0dGVybi1UcmFuc2Zvcm1lciI+VHJhbnNmb3JtZXJzPC9saW5rPiwgb3Igd2hpY2ggY2FuIHByb3ZpZGUKLQkgPGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVRlbXBsYXRlcyI+VGVtcGxhdGVzPC9saW5rPiBmcm9tIGEgdmFyaWV0eSBvZgotCSA8bGluayBhbmNob3I9InBhdHRlcm4tU291cmNlIj5Tb3VyY2U8L2xpbms+cy4gVGhlCi0JIDxsaW5rIGFuY2hvcj0icGF0dGVybi1UZW1wbGF0ZXMiPlRlbXBsYXRlczwvbGluaz4gb2JqZWN0IGlzIGEgcHJvY2Vzc2VkCi0JIG9yIGNvbXBpbGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsIGFuZCBwcm92aWRlcyBhCi0JIDxsaW5rIGFuY2hvcj0icGF0dGVybi1UcmFuc2Zvcm1lciI+VHJhbnNmb3JtZXI8L2xpbms+LiBUaGUKLQkgPGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVRyYW5zZm9ybWVyIj5UcmFuc2Zvcm1lcjwvbGluaz4gcHJvY2Vzc2VzIGEKLQkgPGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVRyYW5zZm9ybWVyIj5Tb3VyY2U8L2xpbms+IGFjY29yZGluZyB0byB0aGUKLQkgaW5zdHJ1Y3Rpb25zIGZvdW5kIGluIHRoZSA8bGluayBhbmNob3I9InBhdHRlcm4tVGVtcGxhdGVzIj5UZW1wbGF0ZXM8L2xpbms+LCBhbmQgcHJvZHVjZXMgYQotCSA8bGluayBhbmNob3I9InBhdHRlcm4tUmVzdWx0Ij5SZXN1bHQ8L2xpbms+LjwvcD4gCi0gIAotPHA+VGhlIHByb2Nlc3Mgb2YgdHJhbnNmb3JtYXRpb24gZnJvbSBhIHRyZWUsIGVpdGhlciBpbiB0aGUgZm9ybSBvZiBhbgotCSBvYmplY3QgbW9kZWwsIG9yIGluIHRoZSBmb3JtIG9mIHBhcnNlIGV2ZW50cywgaW50byBhIHN0cmVhbSwgaXMga25vd24gYXMKLQkgPHJlZj5zZXJpYWxpemF0aW9uPC9yZWY+LiBXZSBiZWxpZXZlIHRoaXMgaXMgdGhlIG1vc3Qgc3VpdGFibGUgdGVybSBmb3IKLQkgdGhpcyBwcm9jZXNzLCBkZXNwaXRlIHRoZSBvdmVybGFwIHdpdGggSmF2YSBvYmplY3Qgc2VyaWFsaXphdGlvbi48L3A+IAotPC9zMj48YW5jaG9yIG5hbWU9InBhdHRlcm5zIi8+Ci08czIgdGl0bGU9IlRSYVggUGF0dGVybnMiPgotPHA+VGhlIGludGVudCwgcmVzcG9uc2liaWxpdGllcywgYW5kIHRocmVhZCBzYWZldHkgb2YgVHJBWCBvYmplY3RzOjwvcD4KLTx1bD4KLSAgPGxpPjxsaW5rIGFuY2hvcj0icGF0dGVybi1Qcm9jZXNzb3IiPlByb2Nlc3NvcjwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVRyYW5zZm9ybWVyRmFjdG9yeSI+VHJhbnNmb3JtZXJGYWN0b3J5PC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9InBhdHRlcm4tVGVtcGxhdGVzIj5UZW1wbGF0ZXM8L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0icGF0dGVybi1UcmFuc2Zvcm1lciI+VHJhbnNmb3JtZXI8L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0icGF0dGVybi1Tb3VyY2UiPlNvdXJjZTwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJwYXR0ZXJuLVJlc3VsdCI+UmVzdWx0PC9saW5rPjwvbGk+ICAKLTwvdWw+Ci08YW5jaG9yIG5hbWU9InBhdHRlcm4tUHJvY2Vzc29yIi8+PHMzIHRpdGxlPSJQcm9jZXNzb3IiPgotPGdsb3NzPgotPGxhYmVsPkludGVudDwvbGFiZWw+Ci08aXRlbT5HZW5lcmljIGNvbmNlcHQgZm9yIHRoZQotICBzZXQgb2Ygb2JqZWN0cyB0aGF0IGltcGxlbWVudCB0aGUgVHJBWCBpbnRlcmZhY2VzLjwvaXRlbT4KLTxsYWJlbD5SZXNwb25zaWJpbGl0aWVzPC9sYWJlbD4KLTxpdGVtPkNyZWF0ZSBjb21waWxlZCB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMsIHRyYW5zZm9ybQotICBzb3VyY2VzLCBhbmQgbWFuYWdlIHRyYW5zZm9ybWF0aW9uIHBhcmFtZXRlcnMgYW5kCi0gIHByb3BlcnRpZXMuPC9pdGVtPgotPGxhYmVsPlRocmVhZCBzYWZldHk8L2xhYmVsPgotPGl0ZW0+T25seSB0aGUgVGVtcGxhdGVzIG9iamVjdCBjYW4gYmUKLSAgdXNlZCBjb25jdXJyZW50bHkgaW4gbXVsdGlwbGUgdGhyZWFkcy4gVGhlIHJlc3Qgb2YgdGhlIHByb2Nlc3NvciBkb2VzIG5vdCBkbwotICBzeW5jaHJvbml6ZWQgYmxvY2tpbmcsIGFuZCBzbyBtYXkgbm90IGJlIHVzZWQgdG8gcGVyZm9ybSBtdWx0aXBsZSBjb25jdXJyZW50Ci0gIG9wZXJhdGlvbnMuPC9pdGVtPgotPC9nbG9zcz4KLTwvczM+IDxhbmNob3IgbmFtZT0icGF0dGVybi1UcmFuc2Zvcm1lckZhY3RvcnkiLz4KLTxzMyB0aXRsZT0iVHJhbnNmb3JtZXJGYWN0b3J5Ij4KLTxnbG9zcz4KLTxsYWJlbD5JbnRlbnQ8L2xhYmVsPgotPGl0ZW0+U2VydmUgYXMgYSB2ZW5kb3ItbmV1dHJhbCBQcm9jZXNzb3IgaW50ZXJmYWNlIGZvcgotICA8anVtcCBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0Ij5YU0xUPC9qdW1wPiBhbmQgc2ltaWxhcgotICBwcm9jZXNzb3JzLjwvaXRlbT4KLTxsYWJlbD5SZXNwb25zaWJpbGl0aWVzPC9sYWJlbD4KLTxpdGVtPlNlcnZlIGFzIGEgZmFjdG9yeSBmb3IgYSBjb25jcmV0ZQotICBpbXBsZW1lbnRhdGlvbiBvZiBhbiBUcmFuc2Zvcm1lckZhY3RvcnksIHNlcnZlIGFzIGEgZGlyZWN0IGZhY3RvcnkgZm9yCi0gIFRyYW5zZm9ybWVyIG9iamVjdHMsIHNlcnZlIGFzIGEgZmFjdG9yeSBmb3IgVGVtcGxhdGVzIG9iamVjdHMsIGFuZCBtYW5hZ2UKLSAgcHJvY2Vzc29yIHNwZWNpZmljIGZlYXR1cmVzLjwvaXRlbT4KLTxsYWJlbD5UaHJlYWQgc2FmZXR5PC9sYWJlbD4KLTxpdGVtPkEgVHJhbnNmb3JtZXJGYWN0b3J5IG1heSBub3QgcGVyZm9ybSBtdWxpdHBsZSBjb25jdXJyZW50Ci0gIG9wZXJhdGlvbnMuPC9pdGVtPgotPC9nbG9zcz4gIAotPC9zMz48YW5jaG9yIG5hbWU9InBhdHRlcm4tVGVtcGxhdGVzIi8+Ci08czMgdGl0bGU9IlRlbXBsYXRlcyI+Ci08Z2xvc3M+Ci08bGFiZWw+SW50ZW50PC9sYWJlbD4KLTxpdGVtPlRoZSBydW50aW1lIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBpbnN0cnVjdGlvbnMuPC9pdGVtPgotPGxhYmVsPlJlc3BvbnNpYmlsaXRpZXM8L2xhYmVsPgotPGl0ZW0+QSBkYXRhIGJhZyBmb3IgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zOyBhY3QgYXMgYSBmYWN0b3J5Ci0gIGZvciBUcmFuc2Zvcm1lcnMuPC9pdGVtPgotPGxhYmVsPlRocmVhZCBzYWZldHk8L2xhYmVsPgotPGl0ZW0+VGhyZWFkc2FmZSBmb3IgY29uY3VycmVudAotICB1c2FnZSBvdmVyIG11bHRpcGxlIHRocmVhZHMgb25jZSBjb25zdHJ1Y3Rpb24gaXMgY29tcGxldGUuPC9pdGVtPgotPC9nbG9zcz4gIAotPC9zMz48YW5jaG9yIG5hbWU9InBhdHRlcm4tVHJhbnNmb3JtZXIiLz4KLTxzMyB0aXRsZT0iVHJhbnNmb3JtZXIiPgotPGdsb3NzPgotPGxhYmVsPkludGVudDwvbGFiZWw+Ci08aXRlbT5BY3QgYXMgYSBwZXItdGhyZWFkCi0gIGV4ZWN1dGlvbiBjb250ZXh0IGZvciB0cmFuc2Zvcm1hdGlvbnMsIGFjdCBhcyBhbiBpbnRlcmZhY2UgZm9yIHBlcmZvcm1pbmcgdGhlCi0gIHRyYW5zZm9ybWF0aW9uLjwvaXRlbT4KLTxsYWJlbD5SZXNwb25zaWJpbGl0aWVzPC9sYWJlbD4KLTxpdGVtPlBlcmZvcm0gdGhlCi0gIHRyYW5zZm9ybWF0aW9uLjwvaXRlbT4KLTxsYWJlbD5UaHJlYWQgc2FmZXR5PC9sYWJlbD4KLTxpdGVtPk9ubHkgb25lIGluc3RhbmNlIHBlciB0aHJlYWQKLSAgaXMgc2FmZS48L2l0ZW0+Ci08L2dsb3NzPiAgCi08bm90ZT5UaGUgVHJhbnNmb3JtZXIgaXMgYm91bmQgdG8gdGhlIFRlbXBsYXRlcwotICBvYmplY3QgdGhhdCBjcmVhdGVkIGl0Ljwvbm90ZT4KLTwvczM+PGFuY2hvciBuYW1lPSJwYXR0ZXJuLVNvdXJjZSIvPgotPHMzIHRpdGxlPSJTb3VyY2UiPgotPGdsb3NzPgotPGxhYmVsPkludGVudDwvbGFiZWw+Ci08aXRlbT5TZXJ2ZSBhcyBhCi0gIHNpbmdsZSB2ZW5kb3ItbmV1dHJhbCBvYmplY3QgZm9yIG11bHRpcGxlIHR5cGVzIG9mIGlucHV0LjwvaXRlbT4KLTxsYWJlbD5SZXNwb25zaWJpbGl0aWVzPC9sYWJlbD4KLTxpdGVtPkFjdCBhcyBzaW1wbGUgZGF0YSBob2xkZXIgZm9yIFN5c3RlbSBJRHMsIERPTSBub2Rlcywgc3RyZWFtcywKLSAgZXRjLjwvaXRlbT4KLTxsYWJlbD5UaHJlYWQgc2FmZXR5PC9sYWJlbD4KLTxpdGVtPlRocmVhZHNhZmUgY29uY3VycmVudGx5IG92ZXIgbXVsdGlwbGUKLSAgdGhyZWFkcyBmb3IgcmVhZC1vbmx5IG9wZXJhdGlvbnM7IG11c3QgYmUgc3luY2hyb25pemVkIGZvciBlZGl0Ci0gIG9wZXJhdGlvbnMuPC9pdGVtPgotPC9nbG9zcz4gIAotPC9zMz48YW5jaG9yIG5hbWU9InBhdHRlcm4tUmVzdWx0Ii8+Ci08czMgdGl0bGU9IlJlc3VsdCI+Ci08cD5BbHRlcm5hdGl2ZSBuYW1lOiBSZXN1bHRUYXJnZXQuPC9wPgotPGdsb3NzPgotPGxhYmVsPkludGVudDwvbGFiZWw+Ci08aXRlbT5TZXJ2ZQotICBhcyBhIHNpbmdsZSBvYmplY3QgZm9yIG11bHRpcGxlIHR5cGVzIG9mIG91dHB1dCwgc28gdGhlcmUgY2FuIGJlIHNpbXBsZSBwcm9jZXNzCi0gIG1ldGhvZCBzaWduYXR1cmVzLjwvaXRlbT4KLTxsYWJlbD5SZXNwb25zaWJpbGl0aWVzPC9sYWJlbD4KLTxpdGVtPkFjdCBhcyBzaW1wbGUgZGF0YSBob2xkZXIgZm9yCi0gIG91dHB1dCBzdHJlYW0sIERPTSBub2RlLCBDb250ZW50SGFuZGxlciwgZXRjLjwvaXRlbT4KLTxsYWJlbD5UaHJlYWQgc2FmZXR5PC9sYWJlbD4KLTxpdGVtPlRocmVhZHNhZmUgY29uY3VycmVudGx5IG92ZXIgbXVsdGlwbGUgdGhyZWFkcyBmb3IgcmVhZC1vbmx5LAotICBtdXN0IGJlIHN5bmNocm9uaXplZCBmb3IgZWRpdC48L2l0ZW0+Ci08L2dsb3NzPgotPC9zMz4gCi0gPC9zMj4KLSA8L3MxPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveGFsYW4vdXNhZ2VwYXR0ZXJucy54bWwgYi94ZG9jcy9zb3VyY2VzL3hhbGFuL3VzYWdlcGF0dGVybnMueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiNjA3MTBlLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW4vdXNhZ2VwYXR0ZXJucy54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw1MzMgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PiAKLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLTxzMSB0aXRsZT0iQmFzaWMgdXNhZ2UgcGF0dGVybnMiPgotPHVsPgotPGxpPjxsaW5rIGFuY2hvcj0iYmFzaWMiPkJhc2ljIHN0ZXBzPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJwbHVnIj5QbHVnZ2luZyBpbiB0aGUgVHJhbnNmb3JtZXIgYW5kIFhNTCBwYXJzZXI8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Im91dHB1dHByb3BzIj5TZXR0aW5nIG91dHB1dCBwcm9wZXJ0aWVzIGluIHlvdXIgc3R5bGVzaGVldHM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Im91dHB1dGVuY29kaW5nIj5DYXV0aW9uOiBzZXR0aW5nIG91dHB1dCBlbmNvZGluZyBpbiB0aGUgc3R5bGVzaGVldDwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iZW1iZWQiPldvcmtpbmcgd2l0aCBlbWJlZGRlZCBzdHlsZXNoZWV0czwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0icGFyYW1zIj5TZXR0aW5nIHN0eWxlc2hlZXQgcGFyYW1ldGVyczwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0ic2VyaWFsaXplIj5TZXJpYWxpemluZyBvdXRwdXQ8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InNheCI+RXhwbGljaXRseSB3b3JraW5nIHdpdGggU0FYPC9saW5rPjwvbGk+Ci08bGk+PGxpbmsgYW5jaG9yPSJvdXRhc2luIj5Vc2luZyB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQgYXMgaW5wdXQgZm9yIGFub3RoZXIgdHJhbnNmb3JtYXRpb248L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImRvbSI+UHJvY2Vzc2luZyBhbmQgcHJvZHVjaW5nIERPTSB0cmVlczwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0ieHBhdGgiPldvcmtpbmcgd2l0aCBYUGF0aCBleHByZXNzaW9uczwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iYXBwbGV0Ij5Vc2luZyB0aGUgJnhzbHQ0ajsgYXBwbGV0IHdyYXBwZXI8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9InNlcnZsZXQiPlVzaW5nICZ4c2x0NGo7IGluIGEgc2VydmxldDwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iZXh0ZW5zaW9ucyI+Q3JlYXRpbmcgYW5kIHVzaW5nIGV4dGVuc2lvbnM8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9Im11bHRpdGhyZWFkaW5nIj5NdWx0aXRocmVhZGluZzwvbGluaz48L2xpPgotPGxpPjxsaW5rIGFuY2hvcj0iZGVidWdnaW5nIj5EZWJ1Z2dlciBpbnRlcmZhY2U8L2xpbms+PC9saT4KLTxsaT48bGluayBhbmNob3I9ImNvbXBhdCI+VXNpbmcgdGhlICZ4c2x0NGo7IHZlcnNpb24gMSBBUEk8L2xpbms+IDxlbT5bRGVwcmVjYXRlZF08L2VtPjwvbGk+Ci08L3VsPgotPGFuY2hvciBuYW1lPSJiYXNpYyIvPgotICA8czIgdGl0bGU9IkJhc2ljIHN0ZXBzIj4KLSAgICA8b2w+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0idHJhbnNmb3JtZXJmYWN0b3J5Ij5JbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyRmFjdG9yeTwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9InRyYW5zZm9ybWVyIj5Qcm9jZXNzIHRoZSBzdHlsZXNoZWV0IGFuZCBnZW5lcmF0ZSBhIFRyYW5zZm9ybWVyPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0idHJhbnNmb3JtYXRpb24iPlBlcmZvcm0gdGhlIHRyYW5zZm9ybWF0aW9uPC9saW5rPjwvbGk+Ci0gIDwvb2w+Ci0gICAgPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlIGlsbHVzdHJhdGVzIHRoZSB0aHJlZSBiYXNpYyBzdGVwcyBpbnZvbHZlZCBpbiBwZXJmb3JtaW5nIGEgdHJhbnNmb3JtYXRpb24uPC9wPgotICAgIDxzb3VyY2U+Ly8gMS4gSW5zdGFudGlhdGUgYSBUcmFuc2Zvcm1lckZhY3RvcnkuCi1qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IAotICAgICAgICAgICAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybWVyVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0KLS8vIDIuIFVzZSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IHRvIHByb2Nlc3MgdGhlIHN0eWxlc2hlZXQgU291cmNlIGFuZAotLy8gICAgZ2VuZXJhdGUgYSBUcmFuc2Zvcm1lci4KLWphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0RmFjdG9yeS5uZXdUcmFuc2Zvcm1lcgotICAgICAgICAgICAgICAgIChuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlKCJmb28ueHNsIik7Ci0KLS8vIDMuIFVzZSB0aGUgVHJhbnNmb3JtZXIgdG8gdHJhbnNmb3JtIGFuIFhNTCBTb3VyY2UgYW5kIHNlbmQgdGhlCi0vLyAgICBvdXRwdXQgdG8gYSBSZXN1bHQgb2JqZWN0LgotdHJhbnNmb3JtZXIudHJhbnNmb3JtCi0gICAgKG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2UoImZvby54bWwiKSwgCi0gICAgIG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQoIG5ldwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbSgiZm9vLm91dCIpKSk7PC9zb3VyY2U+Ci0gIDxub3RlPkZvciBhIHdvcmtpbmcgZXhhbXBsZSBvZiB0aGlzIG1vZGVsIGF0IGl0cyBzaW1wbGVzdCwgc2VlIFNpbXBsZVRyYW5zZm9ybS5qYXZhIGluIHRoZSBqYXZhL3NhbXBsZXMvU2ltcGxlVHJhbnNmb3JtIHN1YmRpcmVjdG9yeS48L25vdGU+Ci0gIDwvczI+PGFuY2hvciBuYW1lPSJ0cmFuc2Zvcm1lcmZhY3RvcnkiLz4KLSAgPHMyIHRpdGxlPSIxLiBJbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyRmFjdG9yeSI+Ci0gIDxwPjxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuaHRtbCI+VHJhbnNmb3JtZXJGYWN0b3J5PC9qdW1wPiBpcyBhbiBhYnN0cmFjdCBjbGFzcyB3aXRoIGEgc3RhdGljIG5ld0luc3RhbmNlKCkgbWV0aG9kIHRoYXQgaW5zdGFudGlhdGVzIHRoZSBjb25jcmV0ZSBzdWJjbGFzcyBkZXNpZ25hdGVkIGJ5IHRoZSBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSBzeXN0ZW0gcHJvcGVydHkuPC9wPgotICA8cD5UaGUgZGVmYXVsdCBzZXR0aW5nIGZvciB0aGlzIHN5c3RlbSBwcm9wZXJ0eSBpcyA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vcHJvY2Vzc29yL1RyYW5zZm9ybWVyRmFjdG9yeUltcGwuaHRtbCI+b3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbDwvanVtcD4uPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9InRyYW5zZm9ybWVyIi8+Ci0gIDxzMiB0aXRsZT0iMi4gVXNlIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgdG8gcHJvY2VzcyB0aGUgc3R5bGVzaGVldCBTb3VyY2UgYW5kIHByb2R1Y2UgYSBUcmFuc2Zvcm1lciI+Ci08cD5UaGUgVHJhbnNmb3JtZXJGYWN0b3J5IDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuaHRtbCNuZXdUcmFuc2Zvcm1lcihqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZSkiPm5ld1RyYW5zZm9ybWVyKFNvdXJjZSB4c2xTb3VyY2UpPC9qdW1wPiBtZXRob2QgcHJvY2Vzc2VzIHRoZSBzdHlsZXNoZWV0IFNvdXJjZSBpbnRvIGEgVGVtcGxhdGVzIG9iamVjdCBhbmQgcmV0dXJucyBhIFRyYW5zZm9ybWVyIHRoYXQgeW91IGNhbiB1c2UgdG8gcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uIChhcHBseSB0aGUgVGVtcGxhdGVzIG9iamVjdCB0byBhbiBYTUwgU291cmNlKS48L3A+Ci08cD5Zb3UgbWF5IHByb3ZpZGUgdGhlIHN0eWxlc2hlZXQgU291cmNlIGluIHRoZSBmb3JtIG9mIGEgc3RyZWFtIG9mIFhNTCBtYXJrdXAgKDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9zdHJlYW0vU3RyZWFtU291cmNlLmh0bWwiPlN0cmVhbVNvdXJjZTwvanVtcD4pLCBhIERPTSBOb2RlICg8anVtcCBocmVmPSJhcGlkb2NzL2phdmF4L3htbC90cmFuc2Zvcm0vZG9tL0RPTVNvdXJjZS5odG1sIj5ET01Tb3VyY2U8L2p1bXA+KSwgb3IgYSBTQVggSW5wdXRTb3VyY2UgKDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9zYXgvU0FYU291cmNlLmh0bWwiPlNBWFNvdXJjZTwvanVtcD4pLiBUbyBzcGVjaWZ5IGEgU3RyZWFtU291cmNlLCB5b3UgbWF5IHVzZSBhIHN5c3RlbSBJRCBvciBmaWxlIG5hbWUgKHVzaW5nIFVSSSBzeW50YXgpLCBhIGphdmEuaW8uSW5wdXRTdHJlYW0sIG9yIGEgamF2YS5pby5SZWFkZXIuIFRoZSB1c2Ugb2YgRE9NU291cmNlIGFuZCBTQVhTb3VyY2UgYXJlIGlsbHVzdHJhdGVkIGluIHN1YnNlcXVlbnQgc2VjdGlvbnMuPC9wPgotPG5vdGU+SWYgeW91IHBsYW4gdG8gdXNlIHRoZSBzdHlsZXNoZWV0IFNvdXJjZSB0byB0cmFuc2Zvcm0gbXVsdGlwbGUgWE1MIFNvdXJjZXMsIHlvdSBzaG91bGQgdXNlIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyRmFjdG9yeS5odG1sI25ld1RlbXBsYXRlcyhqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZSkiPm5ld1RlbXBsYXRlcyhTb3VyY2UgeHNsU291cmNlKTwvanVtcD4gbWV0aG9kIHRvIGV4cGxpY2l0bHkgZ2VuZXJhdGUgYSBUZW1wbGF0ZXMgb2JqZWN0LiBGb3IgZWFjaCB0cmFuc2Zvcm1hdGlvbiwgdXNlIHRoZSBUZW1wbGF0ZXMgb2JqZWN0IHRvIGdlbmVyYXRlIGEgbmV3IFRyYW5zZm9ybWVyLiBGb3IgdGhlIGRldGFpbHMsIHNlZSA8bGluayBhbmNob3I9Im11bHRpdGhyZWFkaW5nIj5NdWx0aXRocmVhZGluZzwvbGluaz4uPC9ub3RlPgotPC9zMj48YW5jaG9yIG5hbWU9InRyYW5zZm9ybWF0aW9uIi8+Ci08czIgdGl0bGU9IjMuIFVzZSB0aGUgVHJhbnNmb3JtZXIgdG8gcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uIj4KLTxwPlVzZSB0aGUgVHJhbnNmb3JtZXIgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RyYW5zZm9ybWVyLmh0bWwjdHJhbnNmb3JtKGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlLGphdmF4LnhtbC50cmFuc2Zvcm0uUmVzdWx0Ij50cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IHRyYW5zZm9ybVJlc3VsdCk8L2p1bXA+IG1ldGhvZCB0byB0cmFuc2Zvcm0gIHRoZSBYTUwgU291cmNlIGFuZCBwbGFjZSB0aGUgdHJhbnNmb3JtYXRpb24gb3V0cHV0IGluIGEgUmVzdWx0IG9iamVjdC48L3A+Ci08cD5KdXN0IGFzIHdpdGggdGhlIHN0eWxlc2hlZXQsIHlvdSBjYW4gc3VwcGx5IHRoZSBYTUwgU291cmNlIGluIHRoZSBmb3JtIG9mIGEgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1Tb3VyY2UuaHRtbCI+U3RyZWFtU291cmNlPC9qdW1wPiwgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01Tb3VyY2UuaHRtbCI+RE9NU291cmNlPC9qdW1wPiwgb3IgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhTb3VyY2UuaHRtbCI+U0FYU291cmNlPC9qdW1wPi4gTGlrZXdpc2UsIHRoZSBSZXN1bHQgbWF5IGJlIGEgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1SZXN1bHQuaHRtbCI+U3RyZWFtUmVzdWx0PC9qdW1wPiwgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01SZXN1bHQuaHRtbCI+RE9NUmVzdWx0PC9qdW1wPiwgb3IgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3NheC9TQVhSZXN1bHQuaHRtbCI+U0FYUmVzdWx0PC9qdW1wPi48L3A+Ci08cD5Gb3IgZWFjaCBub2RlIGluIHRoZSBYTUwgc291cmNlLCB0aGUgVHJhbnNmb3JtZXIgdXNlcyB0aGUgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zIGluIHRoZSBUZW1wbGF0ZXMgb2JqZWN0IHRvIGRldGVybWluZSB3aGljaCB0ZW1wbGF0ZSB0byBhcHBseTogb25lIG9mIHRoZSB0ZW1wbGF0ZXMgaW4gdGhlIFRlbXBsYXRlcyBvYmplY3QsIGEgZGVmYXVsdCB0ZW1wbGF0ZSBydWxlIGFzIHNwZWNpZmllZCBpbiB0aGUgWFNMVCBzcGVjLCBvciBub25lLjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJwbHVnIi8+Ci08czIgdGl0bGU9IlBsdWdnaW5nIGluIGEgVHJhbnNmb3JtZXIgYW5kIFhNTCBwYXJzZXIiPgotPHA+VGhlIEphdmEgQVBJIGZvciBYTUwgUHJvY2Vzc2luZyBpbnRlcmZhY2VzIGVuYWJsZSB5b3UgdG8gaXNvbGF0ZSB5b3VyIGFwcGxpY2F0aW9uIGZyb20gdGhlIGludGVybmFsIGltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgYSBnaXZlbiBUcmFuc2Zvcm1lciwgU0FYIHBhcnNlciwgb3IgRE9NIHBhcnNlci4gRm9yIGVhY2ggb2YgdGhlc2Ugb2JqZWN0cywgdGhlcmUgaXMgYW4gYWJzdHJhY3QgRmFjdG9yeSBjbGFzcyB3aXRoIGEgc3RhdGljIG5ld0luc3RhbmNlKCkgbWV0aG9kIHRoYXQgaW5zdGFudGlhdGVzIGEgY29uY3JldGUgRmFjdG9yeSB3aGljaCB3cmFwcyB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbi4gVGhlc2UgbmV3SW5zdGFuY2UoKSBtZXRob2RzIHVzZSBzeXN0ZW0gcHJvcGVydHkgc2V0dGluZ3MgdG8gZGV0ZXJtaW5lIHdoaWNoIGltcGxlbWVudGF0aW9uIHRvIGluc3RhbnRpYXRlLjwvcD4KLTxwPiZ4c2x0NGo7IGlzIGRpc3RyaWJ1dGVkIHdpdGggYSBzeXN0ZW0gcHJvcGVydHkgc2V0dGluZyBmb3IgdGhlIFhhbGFuIFhTTFQgVHJhbnNmb3JtZXIuIFRoaXMgc2V0dGluZyBpcyBpbiB4YWxhbi5qYXIgaW4gTUVUQS1JTkYvc2VydmljZXMgKHNlZSBzcmMvTUVUQS1JTkYvc2VydmljZXMpLjwvcD4KLTxnbG9zcz4KLSAgPGxhYmVsPlN5c3RlbSBwcm9wZXJ0eTwvbGFiZWw+Ci0gICAgPGl0ZW0+U2V0dGluZzwvaXRlbT4KLSAgPGxhYmVsPjxjb2RlPmphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5PC9jb2RlPjwvbGFiZWw+Ci0gICA8aXRlbT48Y29kZT5vcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsPC9jb2RlPjwvaXRlbT4KLTwvZ2xvc3M+Ci08cD5JZiB5b3UgYXJlIHVzaW5nIFhlcmNlcywgdGhlIFhNTCBwYXJzZXIgZmFjdG9yeSBzZXR0aW5ncyBhcmUgYXMgZm9sbG93czo8L3A+Ci08Z2xvc3M+Ci0gIDxsYWJlbD5TeXN0ZW0gcHJvcGVydHk8L2xhYmVsPgotICAgIDxpdGVtPlNldHRpbmc8L2l0ZW0+Ci0gIDxsYWJlbD48Y29kZT5qYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5PC9jb2RlPjwvbGFiZWw+Ci0gICA8aXRlbT48Y29kZT5vcmcuYXBhY2hlLnhlcmNlcy5qYXhwLkRvY3VtZW50QnVpbGRlckZhY3RvcnlJbXBsPC9jb2RlPjwvaXRlbT4gICAgCi0gIDxsYWJlbD48Y29kZT5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5PC9jb2RlPjwvbGFiZWw+Ci0gICA8aXRlbT48Y29kZT5vcmcuYXBhY2hlLnhlcmNlcy5qYXhwLlNBWFBhcnNlckZhY3RvcnlJbXBsPC9jb2RlPjwvaXRlbT4KLSA8L2dsb3NzPgotPHA+WW91IGNhbiBjaGFuZ2UgYW55IG9mIHRoZXNlIHNldHRpbmdzIGFzIGZvbGxvd3MgKGluIG9yZGVyIG9mIHByZWNlZGVuY2UpOjwvcD4KLTxvbD4KLSAgPGxpPlNldCB0aGUgc3lzdGVtIHByb3BlcnR5IGZyb20gdGhlIGNvbW1hbmQgbGluZSB3aGVuIHlvdSBsYXVuY2ggSmF2YSBvciBmcm9tIHdpdGhpbiB5b3VyIGFwcGxpY2F0aW9uLjxici8+PGJyLz48L2xpPgotICA8bGk+U2V0IHRoZSBzeXN0ZW0gcHJvcGVydHkgaW4gamF4cC5wcm9wZXJ0aWVzIGluIHRoZSBKQVZBX0hPTUUvbGliIGRpcmVjdG9yeSwgd2hlcmUgSkFWQV9IT01FIGlzIHRoZSByb290IG9mIHRoZSBKREsuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5SZXZpc2UgdGhlIGVudHJ5IGluIHNyYy9NRVRBLUlORi9zZXJ2aWNlcyBhbmQgcmVidWlsZCB4YWxhbi5qYXIgb3IgeGVyY2VzLmphciAoZGVwZW5kaW5nIG9uIHdoaWNoIGVudHJ5IHlvdSBoYXZlIGNoYW5nZWQpLjxici8+PGJyLz48L2xpPgotPC9vbD4KLTxwPkZvciBleGFtcGxlLCB0byB1c2UgdGhlIENyaW1zb24gWE1MIHBhcnNlciBpbiBwbGFjZSBvZiB0aGUgWGVyY2VzIFhNTCBwYXJzZXIsIHBsYWNlIENyaW1zb24gb24gdGhlIGNsYXNzIHBhdGggYW5kIHNldCB0aGUgCi08Y29kZT5qYXZheC54bWwucGFyc2Vycy5TQVhQYXJzZXJGYWN0b3J5PC9jb2RlPiBzeXN0ZW0gcHJvcGVydHkgdG8gPGNvZGU+b3JnLmFwYWNoZS5jcmltc29uLmpheHAuU0FYUGFyc2VyRmFjdG9yeUltcGw8L2NvZGU+LjwvcD4KLTxwPkZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWNoYW5pc20gdXNlZCB0byBkZXRlcm1pbmUgc3lzdGVtIHByb3BlcnR5IHZhbHVlcyBhbmQgaG93IHlvdSBjYW4gcGx1ZyBvdGhlciBpbXBsZW1lbnRhdGlvbnMgaW50byB5b3VyIGFwcGxpY2F0aW9ucywgc2VlICJTZWN0aW9uIDM6IFBsdWdhYmlsaXR5IExheWVyIiBpbiB0aGUgPHJlZj5KYXZhIEFQSSBmb3IgWE1MIFByb2Nlc3Npbmc8L3JlZj4gYXQgCi08anVtcCBocmVmPSJodHRwOi8vamF2YS5zdW4uY29tL2Fib3V0SmF2YS9jb21tdW5pdHlwcm9jZXNzL3Jldmlldy9qc3IwNjMvaW5kZXguaHRtbCI+SlNSLTAwMDA2MyAxLjE8L2p1bXA+LjwvcD4gCi08L3MyPjxhbmNob3IgbmFtZT0ib3V0cHV0cHJvcHMiLz4KLTxzMiB0aXRsZT0iU2V0dGluZyBvdXRwdXQgcHJvcGVydGllcyBpbiB5b3VyIHN0eWxlc2hlZXRzIj4KLTxwPk91dHB1dCBwcm9wZXJ0aWVzIGZvciBYTUwsIEhUTUwsIGFuZCBUZXh0IHRyYW5zZm9ybWF0aW9uIG91dHB1dCBhcmUgZGVmaW5lZCBpbiBwcm9wZXJ0eSBmaWxlcyBpbiB0aGUgb3JnLmFwYWNoZS54YWxhbi50ZW1wbGF0ZXMgcGFja2FnZS48L3A+Ci08cD5Zb3UgY2FuIGNoYW5nZSB0aGVzZSBzZXR0aW5ncyBhcyBmb2xsb3dzOjwvcD4KLTxvbD4KLSAgPGxpPkRlY2xhcmUgdGhlIHhhbGFuIG5hbWVzcGFjZSBpbiB5b3VyIHN0eWxlc2hlZXQgZWxlbWVudCAoeG1sbnM6eGFsYW49Imh0dHA6Ly94bWwuYXBhY2hlLm9yZy94c2x0IikuPGJyLz48YnIvPjwvbGk+Ci0gIDxsaT5Vc2UgdGhlIG5hbWVzcGFjZSBwcmVmaXggeW91IGFzc2lnbiAoZm9yIGV4YW1wbGUsICJ4YWxhbiIpIHRvIHJlZGVmaW5lIHByb3BlcnRpZXMgb2YgaW50ZXJlc3QgaW4gdGhlIHN0eWxlc2hlZXQgeHNsOm91dHB1dAotICAgICAgZWxlbWVudCAoZm9yIGV4YW1wbGUsIHhhbGFuOmluZGVudC1hbW91bnQ9IjUiKS48L2xpPgotPC9vbD4KLTxwPlRoZSBmb2xsb3dpbmcgc3R5bGVzaGVldCBmcmFnbWVudCBkZWNsYXJlcyB0aGUgeGFsYW4gbmFtZXNwYWNlIGFuZCBzZXRzIGluZGVudC1hbW91bnQgdG8gMjo8L3A+Ci08c291cmNlPiZsdDs/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8mZ3Q7Ci0mbHQ7eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIiAKLSAgICAgICAgICAgICAgICB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB4bWxuczp4YWxhbj0iaHR0cDovL3htbC5hcGFjaGUub3JnL3hzbHQiJmd0OwotICAgICAgICAgICAgICAgIAotICAmbHQ7eHNsOm91dHB1dCBtZXRob2Q9InhtbCIgCi0gICAgICAgICAgICAgIGVuY29kaW5nPSJVVEYtOCIKLSAgICAgICAgICAgICAgaW5kZW50PSJ5ZXMiIAotICAgICAgICAgICAgICB4YWxhbjppbmRlbnQtYW1vdW50PSIyIi8mZ3Q7PC9zb3VyY2U+Ci0gIDxwPklmIHlvdSB3YW50IHRvIGNoYW5nZSB0aGUgcHJvcGVydHkgc2V0dGluZ3MgZ2xvYmFsbHksIGVkaXQgdGhlIHZhbHVlcyBpbiB0aGUgcHJvcGVydHkgZmlsZXMgaW4gc3JjL29yZy9hcGFjaGUveGFsYW4vdGVtcGxhdGVzLCAKLSAgYW5kIHVzZSBBbnQgdG8gPGxpbmsgaWRyZWY9InJlYWRtZSIgYW5jaG9yPSJqYXIiPnJlYnVpbGQgeGFsYW4uamFyPC9saW5rPi48L3A+Ci08cD5UaGUgcHJvcGVydGllcyBmaWxlcyBkZWZpbmUgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOjwvcD4KLTxwPjxyZWY+b3V0cHV0X3htbC5wcm9wZXJ0aWVzPC9yZWY+OjwvcD4KLTx0YWJsZT4KLSAgPHRyPgotICAgIDx0aD5Qcm9wZXJ0eTwvdGg+Ci0gICAgPHRoPkRlZmF1bHQgdmFsdWU8L3RoPgotICA8L3RyPiAgCi0gIDx0cj4KLSAgICA8dGQ+eGFsYW46aW5kZW50LWFtb3VudDwvdGQ+Ci0gICAgPHRkPjA8L3RkPgotICA8L3RyPgotICA8dHI+Ci0gICAgPHRkPnhhbGFuOmNvbnRlbnQtaGFuZGxlcjwvdGQ+Ci0gICAgPHRkPm9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb1hNTDwvdGQ+Ci0gIDwvdHI+Ci08L3RhYmxlPgotPHA+PHJlZj5vdXRwdXRfaHRtbC5wcm9wZXJ0aWVzPC9yZWY+OjwvcD4KLTx0YWJsZT4KLSAgPHRyPgotICAgIDx0aD5Qcm9wZXJ0eTwvdGg+Ci0gICAgPHRoPkRlZmF1bHQgdmFsdWU8L3RoPgotICA8L3RyPiAgCi0gIDx0cj4KLSAgICA8dGQ+eGFsYW46aW5kZW50LWFtb3VudDwvdGQ+Ci0gICAgPHRkPjA8L3RkPgotICA8L3RyPgotICA8dHI+Ci0gICAgPHRkPnhhbGFuOmNvbnRlbnQtaGFuZGxlcjwvdGQ+Ci0gICAgPHRkPm9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplLlNlcmlhbGl6ZXJUb0hUTUw8L3RkPgotICA8L3RyPgotICA8dHI+Ci0gICAgPHRkPnhhbGFuOmVudGl0aWVzPC90ZD4KLSAgICA8dGQ+SFRNTEVudGl0aWVzLnJlczwvdGQ+Ci0gIDwvdHI+Ci0gIDx0cj4KLSAgICA8dGQ+eGFsYW46dXNlLXVybC1lc2NhcGluZzwvdGQ+Ci0gICAgPHRkPnllczwvdGQ+Ci0gIDwvdHI+Ci0gIDx0cj4KLSAgICA8dGQ+eGFsYW46b21pdC1tZXRhLXRhZzwvdGQ+Ci0gICAgPHRkPm5vPC90ZD4KLSAgPC90cj4KLTwvdGFibGU+Ci08bm90ZT5Zb3UgY2FuIGFsc28gY3JlYXRlIHlvdXIgb3duIEhUTUwgZW50aXR5IGZpbGUgKG1hcHBpbmcgY2hhcmFjdGVycyB0byBlbnRpdGllcykgCi1vciBlZGl0IHNyYy9vcmcvYXBhY2hlL3hhbGFuL3NlcmlhbGl6ZS9IVE1MRW50aXRpZXMucmVzIGFuZCByZWJ1aWxkIHhhbGFuLmphci48L25vdGU+Ci08cD48cmVmPm91dHB1dF90ZXh0LnByb3BlcnRpZXM8L3JlZj46PC9wPgotPHRhYmxlPiAgCi0gIDx0cj4KLSAgICA8dGg+UHJvcGVydHk8L3RoPgotICAgIDx0aD5EZWZhdWx0IHZhbHVlPC90aD4KLSAgPC90cj4KLSAgPHRyPgotICAgIDx0ZD54YWxhbjpjb250ZW50LWhhbmRsZXI8L3RkPgotICAgIDx0ZD5vcmcuYXBhY2hlLnhhbGFuLnNlcmlhbGl6ZS5TZXJpYWxpemVyVG9UZXh0PC90ZD4KLSAgPC90cj4KLTwvdGFibGU+Ci08L3MyPjxhbmNob3IgbmFtZT0ib3V0cHV0ZW5jb2RpbmciLz4KLTxzMiB0aXRsZT0iQ2F1dGlvbjogc2V0dGluZyBvdXRwdXQgZW5jb2RpbmcgaW4gdGhlIHN0eWxlc2hlZXQiPgotPHA+V2hlbiB5b3UgdXNlIHRoZSAmbHQ7eHNsOm91dHB1dCZndDsgZW5jb2RpbmcgYXR0cmlidXRlIHRvIHNldCBvdXRwdXQgY2hhcmFjdGVyIGVuY29kaW5nLCB5b3Ugc2hvdWxkIG5vdCAKLXVzZSBTdHJlYW1SZXN1bHQoamF2YS5pby5Xcml0ZXIpIHRvIGNvbnN0cnVjdCBhIAotPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL3N0cmVhbS9TdHJlYW1SZXN1bHQuaHRtbCI+U3RyZWFtUmVzdWx0PC9qdW1wPiBvYmplY3QgdG8gaG9sZCB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0LgotSWYgeW91IGRvLCB0aGUgV3JpdGVyIHVzZXMgaXRzIG93biBlbmNvZGluZyByYXRoZXIgdGhhbiB0aGUgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0LjwvcD4KLTxwPklmIHlvdSB3YW50IHRvIHVzZSBhIFdyaXRlciwgeW91IGNhbiBzcGVjaWZ5IGFuIGVuY29kaW5nIHdoZW4geW91IGNyZWF0ZSB0aGUgV3JpdGVyIChqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcikuIE9uY2UgdGhlIAotV3JpdGVyIGV4aXN0cywgeW91IGNhbm5vdCByZXNldCB0aGUgZW5jb2RpbmcgaXQgdXNlcy48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iZW1iZWQiLz4KLTxzMiB0aXRsZT0iV29ya2luZyB3aXRoIGVtYmVkZGVkIHN0eWxlc2hlZXRzIj4KLTxwPkFuIFhNTCBTb3VyY2UgbWF5IGluY2x1ZGUgYW4gPGp1bXAgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIveG1sLXN0eWxlc2hlZXQvIj54bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uPC9qdW1wPiB3aGljaCBpZGVudGlmaWVzIHRoZSBzdHlsZXNoZWV0IHRvIGJlIHVzZWQgdG8gcHJvY2VzcyB0aGUgZG9jdW1lbnQuIEFzIGluZGljYXRlZCBieSB0aGUgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiA8cmVmPmhyZWY8L3JlZj4gYXR0cmlidXRlLCB0aGUgc3R5bGVzaGVldCBpdHNlbGYgbWF5IGJlIGVtYmVkZGVkIGluIHRoZSBYTUwgZG9jdW1lbnQgb3IgbG9jYXRlZCBlbHNld2hlcmUuPC9wPgotPHA+U3VwcG9zZSB5b3UgaGF2ZSBhbiBYTUwgZG9jdW1lbnQgKGZvby54bWwpIHdpdGggdGhlIGZvbGxvd2luZyB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uOjwvcD4KLTxwPjxjb2RlPiZsdDs/eG1sLXN0eWxlc2hlZXQgdHlwZT0idGV4dC94bWwiIGhyZWY9ImZvby54c2wiPyZndDs8L2NvZGU+PC9wPgotPHA+VGhlIGZvbGxvd2luZyBmcmFnbWVudCwgdXNlcyB0aGlzIGluc3RydWN0aW9uIHRvIGxvY2F0ZSB0aGUgc3R5bGVzaGVldCAoZm9vLnhzbCBpbiB0aGUgc2FtZSBkaXJlY3RvcnkgYXMgZm9vLnhtbCkgYW5kIGNyZWF0ZSBhIFRlbXBsYXRlcyBvYmplY3QuIE5vdGUgdGhlIHVzZSBvZiB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGdldEFzc29jaWF0ZWRTdHlsZXNoZWV0KCkgaW4gc3RlcCAyYS48L3A+Ci08bm90ZT5BbiBYTUwgZG9jdW1lbnQgbWF5IGluY2x1ZGUgbW9yZSB0aGFuIG9uZSB4bWwtc3R5bGVzaGVldCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBoZW5jZSB0aGUgc3VwcG9ydCBmb3Igd29ya2luZyB3aXRoIG11bHRpcGxlIHN0eWxlc2hlZXRzLiBJZiBtb3JlIHRoYW4gb25lIHN0eWxlc2hlZXQgaXMgcmV0dXJuZWQsIHRoZSBvdGhlciBzdHlsZXNoZWV0cyBhcmUgaW1wb3J0ZWQgaW50byB0aGUgZmlyc3Qgc3R5bGVzaGVldC48L25vdGU+Ci08c291cmNlPi8vIDEuIEluc3RhbnRpYXRlIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkuCi1qYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IAotICAgICAgICAgICAgICAgICAgICBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotLy8gMmEuIEdldCB0aGUgc3R5bGVzaGVldCBmcm9tIHRoZSBYTUwgc291cmNlLgotU3RyaW5nIG1lZGlhID0gbnVsbCAsIHRpdGxlID0gbnVsbCwgY2hhcnNldCA9IG51bGw7Ci1qYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZSBzdHlsZXNoZWV0ID0gdEZhY3RvcnkuZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQKLSAgICAgICAgICAgICAgICAgICAobmV3IFN0cmVhbVNvdXJjZSgiZm9vLnhtbCIpLG1lZGlhLCB0aXRsZSwgY2hhcnNldCk7Ci0KLS8vIDJiLiBQcm9jZXNzIHRoZSBzdHlsZXNoZWV0IGFuZCBnZW5lcmF0ZSBhIFRyYW5zZm9ybWVyLgotVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0RmFjdG9yeS5uZXdUcmFuc2Zvcm1lcihzdHlsZXNoZWV0KTsKLQotLy8gMy4gVXNlIHRoZSBUcmFuc2Zvcm1lciB0byBwZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbiBhbmQgc2VuZCB0aGUKLS8vICAgIHRoZSBvdXRwdXQgdG8gYSBSZXN1bHQgb2JqZWN0LgotdHJhbnNmb3JtZXIudHJhbnNmb3JtCi0gICAgICAgICAgICAgKG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2UoImZvby54bWwiKSwKLSAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdCAobmV3IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbSgiZm9vLm91dCIpKSk7PC9zb3VyY2U+Ci08cD5Gb3IgYSBzYW1wbGUgdGhhdCB1c2VzIHRoaXMgdGVjaG5pcXVlLCBzZWUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0idXNlc3R5bGVzaGVldHBpIj5Vc2VTdHlsZXNoZWV0UEk8L2xpbms+LjwvcD4KLTxwPllvdSBjYW4gYWxzbyBpbnN0cnVjdCB0aGUgPGxpbmsgaWRyZWY9ImNvbW1hbmRsaW5lIj5jb21tYW5kLWxpbmUgdXRpbGl0eTwvbGluaz4gdG8gdXNlIHN0eWxlc2hlZXQgcHJvY2Vzc2luZwotaW5zdHJ1Y3Rpb25zOjwvcD4KLTxvbD4KLSAgPGxpPkluY2x1ZGUgdGhlIDxjb2RlPi1pbjwvY29kZT4gZmxhZyB3aXRoIGFuIFhNTCBzb3VyY2UgdGhhdCBjb250YWlucyBhIHN0eWxlc2hlZXQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbi48YnIvPjxici8+PC9saT4KLSAgPGxpPkRvIG5vdCBpbmNsdWRlIHRoZSA8Y29kZT4teHNsPC9jb2RlPiBmbGFnLjwvbGk+Ci08L29sPgotPC9zMj48YW5jaG9yIG5hbWU9InNlcmlhbGl6ZSIvPgotPHMyIHRpdGxlPSJTZXJpYWxpemluZyBvdXRwdXQiPgotPHA+SW4gc29tZSBjYXNlcywgeW91IG1heSB3YW50IHRvICJ0cmFuc2Zvcm0iIGEgRE9NIHRyZWUgaW50byBhIHN0cmVhbSwgd2hpY2ggdGhlIFhNTCBjb21tdW5pdHkgY2FsbHMgc2VyaWFsaXphdGlvbi4gPGxpbmsgaWRyZWY9InRyYXgiPlRSYVggKFRyYW5zZm9ybWF0aW9uIEFQSSBmb3IgWE1MKTwvbGluaz4gYW5kIHRoZSAmeHNsdDRqOyBUcmFuc2Zvcm1lciBpbXBsZW1lbnRhdGlvbiBwcm92aWRlIGRpcmVjdCBzdXBwb3J0IGZvciB0aGlzIG9wZXJhdGlvbi4gU2ltcGx5IHVzZSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IG5ld1RyYW5zZm9ybWVyKCkgbWV0aG9kIChubyBhcmd1bWVudHMpIHRvIGNyZWF0ZSBhIFRyYW5zZm9ybWVyIHRoYXQgeW91IGNhbiB1c2UgdG8gImNvcHkiIGEgRE9NU291cmNlIHRvIGEgU3RyZWFtUmVzdWx0LiBGb3IgZXhhbXBsZXMsIHNlZSBFeGFtcGxlcy5leGFtcGxlRE9NMkRPTSgpLCBFeGFtcGxlcy5leGFtcGxlU2VyaWFsaXplTm9kZSgpLCBhbmQgRXhhbXBsZXMuZXhhbXBsZUFzU2VyaWFsaXplcigpIGluIHRoZSA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJ0cmF4Ij50cmF4IHNhbXBsZTwvbGluaz4uPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9InBhcmFtcyIvPgotPHMyIHRpdGxlPSJTZXR0aW5nIHN0eWxlc2hlZXQgcGFyYW1ldGVycyI+Ci08cD5BbiBYU0xUIHN0eWxlc2hlZXQgbWF5IGluY2x1ZGUgcGFyYW1ldGVycyB0aGF0IGFyZSBzZXQgYXQgcnVuIHRpbWUgZWFjaCB0aW1lIGEgdHJhbnNmb3JtYXRpb24gaXMgcGVyZm9ybWVkLiBUbyBzZXQgYSBzdHlsZXNoZWV0IHBhcmFtZXRlciwgdXNlIHRoZSBUcmFuc2Zvcm1lciAKLTxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lci5odG1sI3NldFBhcmFtZXRlcihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5PYmplY3QpIj5zZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSk8L2p1bXA+IG1ldGhvZC4gRm9yIGEgd29ya2luZyBleGFtcGxlLCBzZWUgVXNlU3R5bGVzaGVldFBhcmFtLmphdmEgaW4gdGhlIHNhbXBsZXMvVXNlU3R5bGVzaGVldFBhcmFtIHN1YmRpcmVjdG9yeS48L3A+Ci08cD5Zb3UgY2FuIGFsc28gc2V0IGEgcGFyYW1ldGVyIHdpdGggdGhlIGNvbW1hbmQtbGluZSB1dGlsaXR5IGJ5IGluY2x1ZGluZyB0aGUgPGNvZGU+LXBhcmFtPC9jb2RlPiBmbGFnLiBGb3IgZXhhbXBsZTo8L3A+Ci08cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5Qcm9jZXNzIC1pbiBmb28ueG1sIC14c2wgZm9vLnhzbCAtcGFyYW0gcGFyYW0xIGZvb2JhcjwvY29kZT48L3A+Ci08cD53aGVyZSA8Y29kZT5wYXJhbTwvY29kZT4gaXMgdGhlIHBhcmFtZXRlciBuYW1lIGFuZCA8Y29kZT5mb29iYXI8L2NvZGU+IGlzIHRoZSBwYXJhbWV0ZXIgdmFsdWUuIFRoZSBwYXJhbWV0ZXIgbmFtZXNwYWNlIGlzIG51bGwuPC9wPgotPG5vdGU+JnhzbHQ0ajI7IHByb2Nlc3NlcyBzdHJpbmcgcGFyYW1ldGVycy4gWW91IGFyZSBubyBsb25nZXIgcmVxdWlyZWQgKGFzIHlvdSB3ZXJlIHdpdGggJnhzbHQ0ajsgdmVyc2lvbiAxKSB0byBlbmNsb3NlIHN0cmluZ3MgaW4gc2luZ2xlIAotcXVvdGVzICgnKSBhcyBzdHJpbmcgZXhwcmVzc2lvbnMuPC9ub3RlPgotPC9zMj48YW5jaG9yIG5hbWU9InNheCIvPgotPHMyIHRpdGxlPSJFeHBsaWNpdGx5IHdvcmtpbmcgd2l0aCBTQVgiPgotICA8cD4meHNsdDRqOyB1c2VzIHRoZSBTQVggZXZlbnQgbW9kZWwgdG8gcHJvY2VzcyBzdHlsZXNoZWV0cywgdG8gcGFyc2UgWE1MIGlucHV0IGRvY3VtZW50cywgYW5kIHRvIHByb2R1Y2Ugb3V0cHV0LiBGb3IgZWFjaCBvZiB0aGVzZSBvcGVyYXRpb25zLCBhbiBYTUxSZWFkZXIgcmVhZHMgaW5wdXQsIGZpcmluZyBwYXJzZSBldmVudHMsIGFuZCBhIENvbnRlbnRIYW5kbGVyIGxpc3RlbnMgdG8gdGhlIFhNTFJlYWRlciBhbmQgZXhlY3V0ZXMgcGFyc2UgZXZlbnQgbWV0aG9kcy48L3A+Ci08cD5XaGVuIHlvdSB1c2UgdGhlIGJhc2ljIHByb2NlZHVyZSBkZXNjcmliZWQgYWJvdmUgZm9yIHBlcmZvcm1pbmcgdHJhbnNmb3JtYXRpb25zLCAmeHNsdDRqOyB0YWtlcyBjYXJlIG9mIG1hbnkgb2YgdGhlIFNBWCBkZXRhaWxzIHVuZGVyIHRoZSBjb3ZlcnMuIFlvdSBhcmUgZnJlZSB0byBtYWtlIHRoZXNlIGRldGFpbHMgZXhwbGljaXQsIHdoaWNoIHNpbXBseSBtZWFucyB0aGF0IHlvdSBjYW4gaW50ZXJ2ZW5lIGluIHRoZSBwcm9jZWR1cmUgdG8gYWNjb21tb2RhdGUgdGhlIHByZWNpc2UgZW52aXJvbm1lbnQgaW4gd2hpY2ggeW91ciBhcHBsaWNhdGlvbiBvcGVyYXRlcy48L3A+Ci08cD5TdXBwb3NlLCBmb3IgZXhhbXBsZSwgeW91IGFyZSB1c2luZyBhIGN1c3RvbSBYTUxSZWFkZXIsIHBlcmhhcHMgZG9pbmcgbW9yZSB0aGFuIGp1c3QgcGFyc2luZyBzdGF0aWMgWE1MIGRvY3VtZW50cykgdG8gZ2VuZXJhdGUgJnhzbHQ0ajsgU0FYIHBhcnNlIGV2ZW50cy4gWW91IG1pZ2h0IGV2ZW4gaGF2ZSBhIGN1c3RvbSByZWFkZXIgZm9yIHByb2R1Y2luZy9wcm9jZXNzaW5nIHN0eWxlc2hlZXRzLiBZb3UgY2FuIGNhc3QgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBhIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSwgd2hpY2ggcHJvdmlkZXMgYWNjZXNzIHRvIGEgVHJhbnNmb3JtZXJIYW5kbGVyLCB3aGljaCB5b3UgY2FuIHNldCBhcyB0aGUgQ29udGVudEhhbmRsZXIgZm9yIHRoaXMgcmVhZGVyLjwvcD4KLSAgPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlIGV4cGxpY2l0bHkgc2V0cyB1cCB0aGUgWE1MUmVhZGVyIGFuZCBDb250ZW50SGFuZGxlcnMsIGFuZCByZXBsaWNhdGVzIHRoZSA8bGluayBhbmNob3I9ImJhc2ljIj5iYXNpYyBzdGVwczwvbGluaz4gZGVzY3JpYmVkIGFib3ZlLjwvcD4KLSAgPHNvdXJjZT4vLyBJbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyRmFjdG9yeS4KLWphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5ID0gCi0gICAgICAgICAgICAgICAgICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0vLyBWZXJpZnkgdGhhdCB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGltcGxlbWVudGF0aW9uIHlvdSBhcmUgdXNpbmcKLS8vIHN1cHBvcnRzIFNBWCBpbnB1dCBhbmQgb3V0cHV0ICgmeHNsdDRqOyBkb2VzISkuCi1pZiAodEZhY3RvcnkuZ2V0RmVhdHVyZShqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhTb3VyY2UuRkVBVFVSRSkgJmFtcDsmYW1wOyAKLSAgICB0RmFjdG9yeS5nZXRGZWF0dXJlKGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFJlc3VsdC5GRUFUVVJFKSkKLSAgeyAKLSAgICAvLyBDYXN0IHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgdG8gU0FYVHJhbnNmb3JtZXJGYWN0b3J5LgotICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeSBzYXhURmFjdG9yeSA9IAotICAgICAgICAgICAgICAgICAgICgoamF2YXgueG1sLnRyYW5zZm9ybS5TQVhUcmFuc2Zvcm1lckZhY3RvcnkpIHRGYWN0b3J5KTsKLSAgICAvLyBDcmVhdGUgYSBUZW1wbGF0ZXMgQ29udGVudEhhbmRsZXIgdG8gaGFuZGxlIHBhcnNpbmcgb2YgdGhlIAotICAgIC8vIHN0eWxlc2hlZXQuCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVGVtcGxhdGVzSGFuZGxlciB0ZW1wbGF0ZXNIYW5kbGVyID0gCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F4VEZhY3RvcnkubmV3VGVtcGxhdGVzSGFuZGxlcigpOwotCi0gICAgLy8gQ3JlYXRlIGFuIFhNTFJlYWRlciBhbmQgc2V0IGl0cyBDb250ZW50SGFuZGxlci4KLSAgICBvcmcueG1sLnNheC5YTUxSZWFkZXIgcmVhZGVyID0gCi0gICAgICAgICAgICAgICAgICAgb3JnLnhtbC5zYXguaGVscGVycy5YTUxSZWFkZXJGYWN0b3J5LmNyZWF0ZVhNTFJlYWRlcigpOwotICAgIHJlYWRlci5zZXRDb250ZW50SGFuZGxlcih0ZW1wbGF0ZXNIYW5kbGVyKTsKLSAgICAKLSAgICAvLyBQYXJzZSB0aGUgc3R5bGVzaGVldC4gICAgICAgICAgICAgICAgICAgICAgIAotICAgIHJlYWRlci5wYXJzZSgiZm9vLnhzbCIpOwotCi0gICAgLy8gR2V0IHRoZSBUZW1wbGF0ZXMgb2JqZWN0IChnZW5lcmF0ZWQgZHVyaW5nIHRoZSBwYXJzaW5nIG9mIHRoZSBzdHlsZXNoZWV0KQotICAgIC8vIGZyb20gdGhlIFRlbXBsYXRlc0hhbmRsZXIuCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXMgdGVtcGxhdGVzID0gCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZXNIYW5kbGVyLmdldFRlbXBsYXRlcygpOwotICAgIC8vIENyZWF0ZSBhIFRyYW5zZm9ybWVyIENvbnRlbnRIYW5kbGVyIHRvIGhhbmRsZSBwYXJzaW5nIG9mIAotICAgIC8vIHRoZSBYTUwgU291cmNlLiAgCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5zYXguVHJhbnNmb3JtZXJIYW5kbGVyIHRyYW5zZm9ybWVySGFuZGxlciAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgID0gc2F4VEZhY3RvcnkubmV3VHJhbnNmb3JtZXJIYW5kbGVyKHRlbXBsYXRlcyk7Ci0gICAgLy8gUmVzZXQgdGhlIFhNTFJlYWRlcidzIENvbnRlbnRIYW5kbGVyIHRvIHRoZSBUcmFuc2Zvcm1lckhhbmRsZXIuCi0gICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKHRyYW5zZm9ybWVySGFuZGxlcik7Ci0KLSAgICAvLyBTZXQgdGhlIENvbnRlbnRIYW5kbGVyIHRvIGFsc28gZnVuY3Rpb24gYXMgYSBMZXhpY2FsSGFuZGxlciwgd2hpY2gKLSAgICAvLyBjYW4gcHJvY2VzcyAibGV4aWNhbCIgZXZlbnRzIChzdWNoIGFzIGNvbW1lbnRzIGFuZCBDREFUQSkuIAotICAgIHJlYWRlci5zZXRQcm9wZXJ0eSgiaHR0cDovL3htbC5vcmcvc2F4L3Byb3BlcnRpZXMvbGV4aWNhbC1oYW5kbGVyIiwgCi0gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lckhhbmRsZXIpOwotCi0gICAgLy8gU2V0IHVwIGEgU2VyaWFsaXplciB0byBzZXJpYWxpemUgdGhlIFJlc3VsdCB0byBhIGZpbGUuCi0gICAgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplciBzZXJpYWxpemVyID0gCi0gICAgb3JnLmFwYWNoZS54YWxhbi5zZXJpYWxpemUuU2VyaWFsaXplckZhY3RvcnkuZ2V0U2VyaWFsaXplcgotICAgIChvcmcuYXBhY2hlLnhhbGFuLnRlbXBsYXRlcy5PdXRwdXRQcm9wZXJ0aWVzLmdldERlZmF1bHRNZXRob2RQcm9wZXJ0aWVzCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJ4bWwiKSk7Ci0gICAgc2VyaWFsaXplci5zZXRPdXRwdXRTdHJlYW0obmV3IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbSgiZm9vLm91dCIpKTsKLSAgICAvLyBUaGUgU2VyaWFsaXplciBmdW5jdGlvbnMgYXMgYSBTQVggQ29udGVudEhhbmRsZXIuCi0gICAgamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQgcmVzdWx0ID0KLSAgICAgIG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhSZXN1bHQoc2VyaWFsaXplci5hc0NvbnRlbnRIYW5kbGVyKCkpOwotICAgIHRyYW5zZm9ybWVySGFuZGxlci5zZXRSZXN1bHQocmVzdWx0KTsKLSAgICAgIAotICAgIC8vIFBhcnNlIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQuCi0gICAgcmVhZGVyLnBhcnNlKCJmb28ueG1sIik7PC9zb3VyY2U+Ci08L3MyPjxhbmNob3IgbmFtZT0ib3V0YXNpbiIvPgotPHMyIHRpdGxlPSJVc2luZyB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQgYXMgaW5wdXQgZm9yIGFub3RoZXIgdHJhbnNmb3JtYXRpb24iPgotCi08cD5Zb3UgY2FuIGNoYWluIHRvZ2V0aGVyIGEgc2VyaWVzIG9mIHRyYW5zZm9ybWF0aW9ucyBzdWNoIHRoYXQgdGhlIG91dHB1dCBvZiBlYWNoIHRyYW5zZm9ybWF0aW9uIHByb3ZpZGVzIGlucHV0IGZvciB0aGUgbmV4dCB0cmFuc2Zvcm1hdGlvbi4gJnhzbHQ0ajsgc3VwcG9ydHMgdHdvIGJhc2ljIHN0cmF0ZWdpZXMgZm9yIGNoYWluaW5nIGEgc2VyaWVzIG9mIHRyYW5zZm9ybWF0aW9uczo8L3A+Ci08dWw+Ci0gIDxsaT5Vc2UgdGhlIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSB0byBwcm9jZXNzIHRoZSBzdHlsZXNoZWV0IGFuZCBjcmVhdGUgYSBUcmFuc2Zvcm1lckhhbmRsZXIgZm9yIGVhY2ggdHJhbnNmb3JtYXRpb24uIFRoZW4geW91IGNhbiBzZXQKLXRoZSBmaXJzdCBUcmFuc2Zvcm1lckhhbmRsZXIgYXMgdGhlIENvbnRlbnRIYW5kbGVyIGZvciB0aGUgWE1MUmVhZGVyIHRoYXQgcGFyc2VzIHRoZSBpbnB1dCwgbWFrZSB0aGUgc2Vjb25kIFRyYW5zZm9ybWVySGFuZGxlciB0aGUgQ29udGVudEhhbmRsZXIgZm9yIHRoZSBvdXRwdXQgb2YgdGhlIGZpcnN0IFRyYW5zZm9ybWVySGFuZGxlciwgYW5kIHNvIG9uLiBGb3IgbW9yZSBkZXRhaWwgYW5kIGFuIGV4YW1wbGUsIHNlZSB0aGUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0icGlwZSI+UGlwZTwvbGluaz4gc2FtcGxlLjxici8+PGJyLz48L2xpPgotICA8bGk+VXNlIHRoZSBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgdG8gcHJvY2VzcyB0aGUgc3R5bGVzaGVldCBhbmQgY3JlYXRlIGEgU0FYIFhNTEZpbHRlciBmb3IgZWFjaCB0cmFuc2Zvcm1hdGlvbi4gU2V0IGFuIFhNTFJlYWRlciBhcyB0aGUgcGFyZW50IG9mIHRoZSBmaXJzdCBYTUxGaWx0ZXIsIHRoZSBmaXJzdCBYTUxGaWx0ZXIgYXMgdGhlIHBhcmVudCBvZiB0aGUgc2Vjb25kIFhNTEZpbHRlciwgYW5kIHNvIG9uLiBZb3UgbGF1bmNoIHRoZSBzZXJpZXMgb2YgdHJhbnNmb3JtYXRpb25zIGJ5IGluc3RydWN0aW5nIHRoZSBsYXN0IFhNTEZpbHRlciB0byBwYXJzZSB0aGUgWE1MIFNvdXJjZSBmb3IgdGhlIGZpcnN0IHRyYW5zZm9ybWF0aW9uLiBGb3IgbW9yZSBkZXRhaWwgYW5kIGFuIGV4YW1wbGUsIHNlZSB0aGUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0idXNleG1sZmlsdGVycyI+VXNlWE1MRmlsdGVyczwvbGluaz4gc2FtcGxlLjwvbGk+Ci08L3VsPgotPC9zMj48YW5jaG9yIG5hbWU9ImRvbSIvPgotPHMyIHRpdGxlPSJQcm9jZXNzaW5nIGFuZCBwcm9kdWNpbmcgRE9NIHRyZWVzIj4KLSAgPHA+SW4gc29tZSBjYXNlcywgdGhlIGlucHV0IGFuZC9vciBkZXNpcmVkIG91dHB1dCBmb3IgYSB0cmFuc2Zvcm1hdGlvbiBtYXkgYmUgYSBET00gdHJlZSBvYmplY3QuIFRoZSBqYXZheC54bWwudHJhbnNmb3JtLkRPTSBwYWNrYWdlIHByb3ZpZGVzIDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9kb20vRE9NU291cmNlLmh0bWwiPkRPTVNvdXJjZTwvanVtcD4gYW5kIGEgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL2RvbS9ET01SZXN1bHQuaHRtbCI+RE9NUmVzdWx0PC9qdW1wPiwgZWl0aGVyIG9yIGJvdGggb2Ygd2hpY2ggeW91IGNhbiB1c2Ugd2hlbiB5b3UgcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uLjwvcD4KLTxwPkluIHNvbWUgY2FzZXMsIHlvdXIgYXBwbGljYXRpb24gcHJvdmlkZXMgaW5wdXQgaW4gdGhlIGZvcm0gb2YgYSBET00gdHJlZSwgd2hpY2ggYWNjZWxlcmF0ZXMgdGhlIHRyYW5zZm9ybWF0aW9uIHByb2Nlc3MsIHNpbmNlIHRoZSBpbnB1dCBoYXMgaW4gZWZmZWN0IGFscmVhZHkgYmVlbiBwcm9jZXNzZWQuIFRvIHByb2R1Y2UgRE9NIGlucHV0IGZyb20gYSBzdHJlYW0sIHlvdSBjYW4gdXNlIGEgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvcGFyc2Vycy9Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lmh0bWwiPkRvY3VtZW50QnVpbGRlckZhY3Rvcnk8L2p1bXA+IHRvIHByb2R1Y2UgYSA8anVtcCBocmVmPSJhcGlkb2NzL2phdmF4L3htbC9wYXJzZXJzL0RvY3VtZW50QnVpbGRlci5odG1sIj5Eb2N1bWVudEJ1aWxkZXI8L2p1bXA+IHdpdGggd2hpY2ggeW91IGNhbiBwYXJzZSB0aGUgWE1MIGlucHV0IGludG8gYSBET00gRG9jdW1lbnQsIGFzIGlsbHVzdHJhdGVkIGJlbG93LjwvcD4KLTxzb3VyY2U+Ly8gSW5zdGFudGlhdGUgYSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5LgotamF2YXgueG1sLnBhcnNlcnMuRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkZmFjdG9yeSA9Ci0gICAgICAgICAgICAgICAgICAgIGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLS8vIFVzZSB0aGUgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSB0byBwcm92aWRlIGFjY2VzcyB0byBhIERvY3VtZW50QnVpbGRlci4KLWphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlciBkQnVpbGRlciA9IGRmYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOwotLy8gVXNlIHRoZSBEb2N1bWVudEJ1aWxkZXIgdG8gcGFyc2UgdGhlIFhNTCBpbnB1dC4KLW9yZy53M2MuZG9tLkRvY3VtZW50IGluRG9jID0gZEJ1aWxkZXIuUGFyc2UoImZvby54bWwiKTs8L3NvdXJjZT4KLTxwPlRvIHByb2R1Y2UgRE9NIG91dHB1dCwgc2ltcGx5IHVzZSBhIFRyYW5zZm9ybWVyIHRvIHRyYW5zZm9ybSB0byBhIERPTVJlc3VsdCBvYmplY3QuPC9wPgotPHNvdXJjZT4vLyBHZW5lcmF0ZSBhIFRyYW5zZm9ybWVyLgotamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyCi0gICAgICAgICAgICAgICAgICAobmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uU3RyZWFtLlN0cmVhbVNvdXJjZSgiZm9vLnhzbCIpKTsKLS8vIENyZWF0ZSBhbiBlbXB5IERPTVJlc3VsdCBvYmplY3QgZm9yIHRoZSBvdXRwdXQuCi1qYXZheC54bWwudHJhbnNmb3JtLmRvbS5ET01SZXN1bHQgZG9tUmVzdWx0ID0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVJlc3VsdCgpOwotLy8gUGVyZm9ybSB0aGUgdHJhbnNmb3JtYXRpb24uCi10cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IGphdmF4LnhtbC50cmFuc2Zvcm0uZG9tLkRPTVNvdXJjZShpbkRvYykKLSAgICAgICAgICAgICAgICAgICAgICBkb21SZXN1bHQ7Ci0vLyBOb3cgeW91IGNhbiBnZXQgdGhlIG91dHB1dCBOb2RlIGZyb20gdGhlIERPTVJlc3VsdC4KLW9yZy53M2MuZG9tLk5vZGUgbm9kZSA9IGRvbVJlc3VsdC5nZXROb2RlKCk7PC9zb3VyY2U+Ci08bm90ZT5DcmVhdGUgYSBuZXcgRE9NUmVzdWx0IG9iamVjdCBvciB1c2UgRE9NUmVzdWx0LnNldE5vZGUoKSB0byBhc3NpZ24gYSBuZXcgY29udGFpbmVyIGVhY2ggdGltZSB5b3Ugd2FudCB0byBwZXJmb3JtIGEgdHJhbnNmb3JtYXRpb24gCi1hbmQgcGxhY2UgdGhlIG91dHB1dCBpbiBhIERPTVJlc3VsdCBvYmplY3QuPC9ub3RlPgotPHA+VGhlIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9ImRvbTJkb20iPkRPTTJET008L2xpbms+IGlsbHVzdHJhdGVzIGJvdGggcHJvY2VkdXJlcywgYW5kIHNlcmlhbGl6ZXMgdGhlIERPTVJlc3VsdCB0byBTeXN0ZW0ub3V0LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJ4cGF0aCIvPgotPHMyIHRpdGxlPSJXb3JraW5nIHdpdGggWFBhdGggZXhwcmVzc2lvbnMiPgotPHA+WFNMVCBzdHlsZXNoZWV0cyB1c2UgWFBhdGggZXhwcmVzc2lvbnMgdG8gc2VsZWN0IG5vZGVzLCBzcGVjaWZ5IGNvbmRpdGlvbnMsIGFuZCBnZW5lcmF0ZSB0ZXh0IGZvciB0aGUgcmVzdWx0IHRyZWUuIFhQYXRoIHByb3ZpZGVzIGFuIEFQSSB0aGF0IHlvdSBjYW4gY2FsbCBkaXJlY3RseS4gRm9yIGV4YW1wbGUsIHlvdSBtYXkgd2FudCB0byBzZWxlY3Qgbm9kZXMgcHJvZ3JhbW1hdGljYWxseSBhbmQgZG8geW91ciBvd24gcHJvY2Vzc2luZyB3aXRob3V0IGEgc3R5bGVzaGVldC48L3A+Ci08cD5YUGF0aCBpcyBhbiBpbmRlcGVuZGVudCBlbnRpdHksIHdpdGggY2xpZW50cyBvdGhlciB0aGFuIFhTTFQgcHJvY2Vzc29ycyAoc3VjaCBhcyBYUG9pbnRlcikuIEFjY29yZGluZ2x5LCAmeHNsdDRqMjsgaGFzIHBhY2thZ2VkIFhQYXRoIGFzIGEgc2VwYXJhdGUgbW9kdWxlIChvcmcuYXBhY2hlLnhwYXRoIGFuZCBpdHMgc3VicGFja2FnZXMpLCBhbHRob3VnaCBjb25jdXJyZW50bHkgdGhpcyBtb2R1bGUgZG9lcyB1c2Ugc29tZSB1dGlsaXR5IGNsYXNzZXMgcGFja2FnZWQgaW4gb3JnLmFwYWNoZS54YWxhbi51dGlscy4gVGhlIG9yZy5hcGFjaGUueHBhdGguWFBhdGhBUEkgY2xhc3MgY29udGFpbnMgY29udmVuaWVuY2UgbWV0aG9kcyB0aGF0IHlvdSBjYW4gdXNlIHRvIHJldHVybiBzaW5nbGUgRE9NIE5vZGVzLCBOb2RlSXRlcmF0b3JzLCBhbmQgWE9iamVjdHMuIEFwYXJ0IGZyb20gdGhlaXIgb3duIGZ1bmN0aW9uYWxpdHksIHRoZXNlIG1ldGhvZHMgYWxzbyBwcm92aWRlIGEgcGF0aCBpbnRvIHRoZSBsb3dlci1sZXZlbCBYUGF0aCBBUEkgdGhhdCB5b3UgbWF5IGZpbmQgdXNlZnVsLjwvcD4KLTxwPkZvciBhbiBleGFtcGxlIHRoYXQgdXNlcyB0aGUgWFBhdGhBUEkgY29udmVuaWVuY2UgbWV0aG9kcyB0byBleGVjdXRlIFhQYXRoIGV4cHJlc3Npb25zIGFnYWluc3QgWE1MIHNvdXJjZSBmaWxlcywgc2VlIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9ImFwcGx5eHBhdGgiPkFwcGx5WFBhdGg8L2xpbms+LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJhcHBsZXQiLz4KLTxzMiB0aXRsZT0iVXNpbmcgdGhlICZ4c2x0NGo7IGFwcGxldCB3cmFwcGVyIj4KLTxvbD4gCi08bGk+SW5jbHVkZSA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vY2xpZW50L1hTTFRQcm9jZXNzb3JBcHBsZXQuaHRtbCI+WFNMVFByb2Nlc3NvckFwcGxldDwvanVtcD4gaW4gYW4gSFRNTCBjbGllbnQuPGJyLz48YnIvPjwvbGk+Ci08bGk+U3BlY2lmeSB0aGUgWE1MIHNvdXJjZSBkb2N1bWVudCBhbmQgWFNMIHN0eWxlc2hlZXQuPGJyLz48YnIvPgotWW91IGNhbiB1c2UgdGhlIERvY3VtZW50VVJMIGFuZCBTdHlsZVVSTCBQQVJBTSB0YWdzIG9yIHRoZSA8anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vY2xpZW50L1hTTFRQcm9jZXNzb3JBcHBsZXQuaHRtbCNzZXREb2N1bWVudFVSTChqYXZhLmxhbmcuU3RyaW5nKSI+c2V0ZG9jdW1lbnRVUkwoKTwvanVtcD4gYW5kIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9jbGllbnQvWFNMVFByb2Nlc3NvckFwcGxldC5odG1sI3NldFN0eWxlVVJMKGphdmEubGFuZy5TdHJpbmcpIj5zZXRTdHlsZVVSTCgpPC9qdW1wPiBtZXRob2RzLiBJZiB0aGUgWE1MIGRvY3VtZW50IGNvbnRhaW5zIGEgc3R5bGVzaGVldCBQcm9jZXNzaW5nIEluc3RydWN0aW9uIChQSSksIHlvdSBkbyBub3QgbmVlZCB0byBzcGVjaWZ5IGFuIFhTTCBzdHlsZXNoZWV0Ljxici8+PGJyLz48L2xpPgotPGxpPkNhbGwgdGhlIDxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi9jbGllbnQvWFNMVFByb2Nlc3NvckFwcGxldC5odG1sI3RyYW5zZm9ybVRvSHRtbChqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIj50cmFuc2Zvcm1Ub0h0bWwoKTwvanVtcD4gb3IgPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL2NsaWVudC9YU0xUUHJvY2Vzc29yQXBwbGV0Lmh0bWwjZ2V0SHRtbFRleHQoKSI+Z2V0SHRtbFRleHQoKTwvanVtcD4gbWV0aG9kLCB3aGljaCBwZXJmb3JtcyB0aGUgdHJhbnNmb3JtYXRpb24gYW5kIHJldHVybnMgdGhlIG5ldyBkb2N1bWVudCBhcyBhIFN0cmluZy48L2xpPjwvb2w+Ci08bm90ZT5UaGUgdHJhbnNmb3JtVG9IVE1MKCkgbWV0aG9kIHRha2VzIGFyZ3VtZW50cyBmb3IgdGhlIFhNTCBzb3VyY2UgZG9jdW1lbnQgYW5kIFhTTCBzdHlsZXNoZWV0LiBUaGUgZ2V0SHRtbFRleHQoKSBtZXRob2QgdGFrZXMgbm8gYXJndW1lbnRzOiBpdCB1c2VzIHByb3BlcnR5IG9yIHBhcmFtZXRlciBzZXR0aW5ncywgYXMgaW4gdGhlIGV4YW1wbGUgYmVsb3cuPC9ub3RlPgotPHA+Rm9yIGFuIGV4YW1wbGUsIHNlZSB0aGUgPGxpbmsgaWRyZWY9InNhbXBsZXMiIGFuY2hvcj0iYXBwbGV0eG1sdG9odG1sIj5BcHBsZXRYTUx0b0hUTUw8L2xpbms+IHNhbXBsZSBhcHBsZXQuIFRoZSAmbHQ7YXBwbGV0Jmd0OyB0YWcgaXMgaW4gc2FtcGxlcy9BcHBsZXRYTUx0b0hUTUwvY2xpZW50Lmh0bWw6PC9wPgotPHNvdXJjZT4mbHQ7YXBwbGV0ICAKLSAgICBuYW1lPSJ4c2xDb250cm9sIgotICAgIGNvZGU9Im9yZy5hcGFjaGUueGFsYW4uY2xpZW50LlhTTFRQcm9jZXNzb3JBcHBsZXQuY2xhc3MiCi0gICAgYXJjaGl2ZT0iLi4vLi4vYmluL3hhbGFuLmphciwuLi8uLi9iaW4veGVyY2VzLmphciIKLSAgICBoZWlnaHQ9IjAiCi0gICAgd2lkdGgiMCI+Ci0gICAgJmx0O3BhcmFtIG5hbWU9ImRvY3VtZW50VVJMIiB2YWx1ZT0ieGFsYW5BcHBsZXRzLnhtbCIvJmd0OwotICAgICZsdDtwYXJhbSBuYW1lPSJzdHlsZVVSTCIgdmFsdWU9InMxVG9IVE1MLnhzbCIvJmd0OwotJmx0Oy9hcHBsZXQmZ3Q7PC9zb3VyY2U+Ci08cD5XaGVuIHRoZSB1c2VyIGNsaWNrcyB0aGUgVHJhbnNmb3JtIGJ1dHRvbiwgdGhlIEhUTUwgY2xpZW50IGNhbGxzIHRoZSBnZXRIdG1sVGV4dCgpIG1ldGhvZCwgYW5kIHB1dHMgdGhlIHJldHVybmVkIEhUTUwgdGV4dCBpbiBhIGZyYW1lIGZvciB0aGUgdXNlciB0byB2aWV3LjwvcD4KLQotPC9zMj48YW5jaG9yIG5hbWU9InNlcnZsZXQiLz4KLTxzMiB0aXRsZT0iVXNpbmcgJnhzbHQ0ajsgaW4gYSBzZXJ2bGV0Ij4KLTxwPllvdSBjYW4gc2V0IHVwIGEgc2VydmxldCB0byB1c2UgJnhzbHQ0ajsgdG8gcmVzcG9uZCB0byByZXF1ZXN0cyBmb3IgWE1MIGRvY3VtZW50cyBieSB0cmFuc2Zvcm1pbmcgdGhvc2UgZG9jdW1lbnRzIGludG8gSFRNTCBhbmQgc2VydmluZyB0aGVtIHRvIHdlYiBicm93c2Vycy4gVG8gcmVzcG9uZCB0byBIVFRQIEdFVCByZXF1ZXN0cywgYWxsIHlvdSBuZWVkIHRvIGRvIGlzIG92ZXJ3cml0ZSB0aGUgSHR0cFNlcnZsZXQgZG9HZXQoKSBtZXRob2Qgd2l0aCBhIHByb2NlZHVyZSB0aGF0IGluc3RhbnRpYXRlcyBhIFRyYW5zZm9ybWVyIGFuZCB1c2VzIGl0IHRvIHBlcmZvcm0gYSB0cmFuc2Zvcm1hdGlvbi4gQXMgdGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzLCB5b3UgY2FuIGdlbmVyYXRlIGEgUmVzdWx0U3RyZWFtIHRoYXQgYSBQcmludFdyaXRlciB3cml0ZXMgdG8gdGhlIEh0dHBSZXNwb25zZSBPdXRwdXRTdHJlYW0sIHJldHVybmluZyB0aGUgdHJhbnNmb3JtYXRpb24gb3V0cHV0IHRvIHRoZSB3ZWIgYnJvd3Nlci48L3A+Ci08c291cmNlPgotcHVibGljIGNsYXNzIFNhbXBsZVhTTFRTZXJ2bGV0IGV4dGVuZHMgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0IHsKLSAgCi0gIC8vIFJlc3BvbmQgdG8gSFRUUCBHRVQgcmVxdWVzdHMgZnJvbSBicm93c2Vycy4KLSAgcHVibGljIHZvaWQgZG9HZXQgKGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKLSAgICAgICAgICAgICAgICAgICAgIGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQotICAgIHRocm93cyBqYXZheC5zZXJ2bGV0LlNlcnZsZXRFeGNlcHRpb24sIGphdmEuaW8uSU9FeGNlcHRpb24KLSAgewotICAgIC8vIFNldCBjb250ZW50IHR5cGUgZm9yIEhUTUwuCi0gICAgcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIpOyAgICAKLSAgICAvLyBPdXRwdXQgZ29lcyB0byB0aGUgcmVzcG9uc2UgUHJpbnRXcml0ZXIuCi0gICAgamF2YS5pby5QcmludFdyaXRlciBvdXQgPSByZXNwb25zZS5nZXRXcml0ZXIoKSk7Ci0gICAgdHJ5Ci0gICAgewkKLSAgICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5ID0gCi0gICAgICAgICAgICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICAgIC8vIEdldCB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGFuZCB0aGUgc3R5bGVzaGVldCwgYm90aCBpbiB0aGUgc2VydmxldAotICAgICAgLy8gZW5naW5lIGRvY3VtZW50IGRpcmVjdG9yeS4KLSAgICAgIGphdmF4LnhtbC50cmFuc2Zvcm0uU291cmNlIHhtbFNvdXJjZSA9IAotICAgICAgICAgICAgICAgIG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2UKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ldyBqYXZhLm5ldC5VUkwoImZpbGU6Zm9vLnhtbCIpLm9wZW5TdHJlYW0oKSk7Ci0gICAgICBqYXZheC54bWwudHJhbnNmb3JtLlNvdXJjZSB4c2xTb3VyY2UgPSAKLSAgICAgICAgICAgICAgICBuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZXcgamF2YS5uZXQuVVJMKCJmaWxlOmZvby54c2wiKS5vcGVuU3RyZWFtKCkpOwotICAgICAgLy8gR2VuZXJhdGUgdGhlIHRyYW5zZm9ybWVyLgotICAgICAgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RmFjdG9yeS5uZXdUcmFuc2Zvcm1lcih4c2xTb3VyY2UpOwotICAgICAgLy8gUGVyZm9ybSB0aGUgdHJhbnNmb3JtYXRpb24sIHNlbmRpbmcgdGhlIG91dHB1dCB0byB0aGUgcmVzcG9uc2UuCi0gICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oeG1sU291cmNlLCAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQob3V0KSk7Ci0gICAgfQotICAgIC8vIElmIGFuIEV4Y2VwdGlvbiBvY2N1cnMsIHJldHVybiB0aGUgZXJyb3IgdG8gdGhlIGNsaWVudC4KLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCi0gICAgewotICAgICAgb3V0LndyaXRlKGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgIGUucHJpbnRTdGFja1RyYWNlKG91dCk7ICAgIAotICAgIH0KLSAgICAvLyBDbG9zZSB0aGUgUHJpbnRXcml0ZXIuCi0gICAgb3V0LmNsb3NlKCk7Ci0gIH0gIAotfTwvc291cmNlPgotPHA+Rm9yIGEgd29ya2luZyBzYW1wbGUsIHNlZSA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJzaW1wbGV4c2x0c2VydmxldCI+U2ltcGxlWFNMVFNlcnZsZXQ8L2xpbms+LjwvcD4KLTxwPkluIHRoZSBwcmVjZWRpbmcgZXhhbXBsZSwgdGhlIFVSTHMgZm9yIHRoZSBYTUwgZG9jdW1lbnQgYW5kIFhTTCBzdHlsZXNoZWV0IGFyZSBoYXJkY29kZWQgaW4gdGhlIHNlcnZsZXQuIFlvdSBjYW4gYWxzbyBjcmVhdGUgYSBzZXJ2bGV0IHRoYXQgcGFyc2VzIHRoZSByZXF1ZXN0IFVSTCBmb3IgaW5wdXQgcGFyYW1ldGVycyBzcGVjaWZ5aW5nIHRoZSBYTUwgZG9jdW1lbnQsIFhTTCBzdHlsZXNoZWV0LCBhbmQgYW55IHJlbGV2YW50IHN0eWxlc2hlZXQgcGFyYW1ldGVycy4gRm9yIHNhbXBsZXMsIHNlZSA8bGluayBpZHJlZj0ic2FtcGxlcyIKLWFuY2hvcj0idXNlc3R5bGVzaGVldHBhcmFtc2VydmxldCI+VXNlU3R5bGVzaGVldFBhcmFtU2VydmxldDwvbGluaz4gYW5kIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9InhzbHRzZXJ2bGV0d2l0aHBhcmFtcyI+WFNMVFNlcnZsZXRXaXRoUGFyYW1zPC9saW5rPi4gRm9yIGEgbW9yZSByb2J1c3QgYW5kIGNvbXBsZXggc2FtcGxlIHRoYXQgYWxzbyBlbXBsb3lzIGEgcHJvcGVydGllcyBmaWxlIHRvIGRldGVybWluZSB3aGljaCBzdHlsZXNoZWV0IHRvIHVzZSBkZXBlbmRpbmcgb24gdGhlIGNsaWVudCBicm93c2VyL2RldmljZSwgc2VlIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9ImFwcGx5eHNsdCI+QXBwbHlYU0xUPC9saW5rPi48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iZXh0ZW5zaW9ucyIvPgotPHMyIHRpdGxlPSJDcmVhdGluZyBhbmQgdXNpbmcgZXh0ZW5zaW9ucyI+Ci08cD5Gb3IgdGhvc2UgY2FzZXMgd2hlcmUgeW91IHdhbnQgdG8gYmUgYWJsZSB0byBjYWxsIHByb2NlZHVyYWwgY29kZSBmcm9tIHdpdGhpbiBhIHN0eWxlc2hlZXQsIHRoZSAmeHNsdDRqOyBFeHRlbnNpb25zIGZhY2lsaXR5IHN1cHBvcnRzIHRoZSBjcmVhdGlvbiBvZiBleHRlbnNpb24gZWxlbWVudHMgYW5kIGV4dGVuc2lvbiBmdW5jdGlvbnMuIFNlZSA8bGluayBpZHJlZj0iZXh0ZW5zaW9ucyI+RXh0ZW5zaW9uczwvbGluaz4gYW5kIDxsaW5rIGlkcmVmPSJzYW1wbGVzIiBhbmNob3I9ImV4dGVuc2lvbnMiPkV4dGVuc2lvbnMgc2FtcGxlczwvbGluaz4uPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9Im11bHRpdGhyZWFkaW5nIi8+Ci08czIgdGl0bGU9Ik11bHRpdGhyZWFkaW5nIj4KLTxwPkEgZ2l2ZW4gVGVtcGxhdGVzIG9iamVjdCBtYXkgYmUgdXNlZCByZXBlYXRlZGx5IGFuZCBldmVuIGluIG11bHRpcGxlIHRocmVhZHMgcnVubmluZyBjb25jdXJyZW50bHkgZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiBYTUwgaW5wdXQsIGJ1dCB5b3Ugc2hvdWxkIHVzZSB0aGUgVGVtcGxhdGVzIG9iamVjdCB0byBpbnN0YW50aWF0ZSBhIHNlcGFyYXRlIFRyYW5zZm9ybWVyIGZvciBlYWNoIHRyYW5zZm9ybWF0aW9uIHlvdSBwZXJmb3JtLiBUaGUgVGVtcGxhdGVzIG9iamVjdCBpcyBhbiBpbW11dGFibGUgcnVudGltZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RydWN0dXJlIGFuZCBjb250ZW50IG9mIGEgc3R5bGVzaGVldCAod2hpY2ggbWF5IGluY2x1ZGUgYW5kIGltcG9ydCBtdWx0aXBsZSBzdHlsZXNoZWV0IHNvdXJjZXMpLiBBIFRyYW5zZm9ybWVyLCBvbiB0aGUgb3RoZXIgaGFuZCwgaXMgYSBsaWdodHdlaWdodCBvYmplY3QgdGhhdCB0cmFja3Mgc3RhdGUgaW5mb3JtYXRpb24gZHVyaW5nIHRoZSB0cmFuc2Zvcm1hdGlvbiwgYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgdG8gcGVyZm9ybSBhIHNpbmdsZSB0cmFuc2Zvcm1hdGlvbi48L3A+Ci0KLTxwPklmIHlvdSB3YW50IHRvIHBlcmZvcm0gbXVsdGlwbGUgdHJhbnNmb3JtYXRpb25zIChzZXF1ZW50aWFsbHkgb3IgY29uY3VycmVudGx5KSB3aXRoIHRoZSBzYW1lIHN0eWxlc2hlZXQgaW5zdHJ1Y3Rpb25zLCBkbyB0aGUgZm9sbG93aW5nOjwvcD4KLTxvbD4KLSAgPGxpPlVzZSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IDxqdW1wIGhyZWY9ImFwaWRvY3MvamF2YXgveG1sL3RyYW5zZm9ybS9UcmFuc2Zvcm1lckZhY3RvcnkuaHRtbCNuZXdUZW1wbGF0ZXMoamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2UpIj5uZXdUZW1wbGF0ZXMoU291cmNlIHhzbFNvdXJjZSk8L2p1bXA+IG1ldGhvZCB0byBjcmVhdGUgYSBUZW1wbGF0ZXMgb2JqZWN0Ljxici8+PGJyLz48L2xpPgotPGxpPkZvciBlYWNoIHRyYW5zZm9ybWF0aW9uLCB1c2UgdGhlIFRlbXBsYXRlcyBvYmplY3QgPGp1bXAgaHJlZj0iYXBpZG9jcy9qYXZheC94bWwvdHJhbnNmb3JtL1RlbXBsYXRlcy5odG1sI25ld1RyYW5zZm9ybWVyKCkiPm5ld1RyYW5zZm9ybWVyKCk8L2p1bXA+IG1ldGhvZCB0byBjcmVhdGUgYSBUcmFuc2Zvcm1lciwgYW5kIHVzZSB0aGF0IFRyYW5zZm9ybWVyJ3MgCi08anVtcCBocmVmPSJhcGlkb2NzL2phdmF4L3htbC90cmFuc2Zvcm0vVHJhbnNmb3JtZXIuaHRtbCN0cmFuc2Zvcm0oamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2UsamF2YXgueG1sLnRyYW5zZm9ybS5SZXN1bHQpIj50cmFuc2Zvcm0oU291cmNlIHhtbFNvdXJjZSwgUmVzdWx0IHRyYW5zZm9ybVJlc3VsdCk8L2p1bXA+IG1ldGhvZCB0byBwZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbi48L2xpPgotPC9vbD4KLTxwPkZvciBhbiBleGFtcGxlLCBzZWUgRXhhbXBsZXMuZXhhbXBsZVVzZVRlbXBsYXRlc09iaigpIGluIHRoZSA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJ0cmF4Ij50cmF4IHNhbXBsZTwvbGluaz4uPC9wPgotPC9zMj48YW5jaG9yIG5hbWU9ImRlYnVnZ2luZyIvPgotPHMyIHRpdGxlPSJEZWJ1Z2dlciBJbnRlcmZhY2UiPgotCQk8cD4meHNsdDRqOyBjb250YWlucyBhIGRlYnVnZ2VyIGludGVyZmFjZSBpbiB0aGUgb3JnLmFwYWNoZS54YWxhbi54c2x0LnRyYWNlIHBhY2thZ2U6PC9wPiAKLQkJPHVsPgotCQkgIDxsaT48anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvVHJhY2VMaXN0ZW5lci5odG1sIj5UcmFjZUxpc3RlbmVyPC9qdW1wPiBpcyBhbiBpbnRlcmZhY2UgdGhhdCBkZWJ1Z2dlcnMgCi0JCSAgY2FuIGltcGxlbWVudC4gT3IsIGxpa2UgdGhlIDxsaW5rIGlkcmVmPSJjb21tYW5kbGluZSI+Y29tbWFuZC1saW5lIHV0aWxpdHk8L2xpbms+LCB5b3UgY2FuIHVzZSB0aGUgPGp1bXAKLSAgICAgIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9QcmludFRyYWNlTGlzdGVuZXIuaHRtbCI+UHJpbnRUcmFjZUxpc3RlbmVyPC9qdW1wPiBpbXBsZW1lbnRhdGlvbiBvZiB0aGF0IGludGVyZmFjZS4KLSAgICAgIDxici8+PGJyLz48L2xpPgotICAgICAgPGxpPllvdSBjYW4gcmVnaXN0ZXIgYSBUcmFjZUxpc3RlbmVyIHdpdGggdGhlIAotICAgICAgPGp1bXAgaHJlZj0iYXBpZG9jcy9vcmcvYXBhY2hlL3hhbGFuL3RyYWNlL1RyYWNlTWFuYWdlci5odG1sIj5UcmFjZU1hbmFnZXI8L2p1bXA+IGFzc29jaWF0ZWQKLSAgICAgIHdpdGggdGhlIFRyYW5zZm9ybWVyIHRoYXQgd2lsbCBwZXJmb3JtIGEgZ2l2ZW4gdHJhbnNmb3JtYXRpb24uPGJyLz48YnIvPjwvbGk+Ci0JCSAgPGxpPjxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9UcmFjZXJFdmVudC5odG1sIj5UcmFjZXJFdmVudDwvanVtcD4gaXMgYW4gZXZlbnQgdGhhdCBpcyAKLQkJICBwYXNzZWQgdG8gdGhlIFRyYWNlTGlzdGVuZXIudHJhY2UgZnVuY3Rpb24uIEl0IGlzIGNhbGxlZCBiZWZvcmUgYSBub2RlIGlzICdleGVjdXRlZCcgaW4gdGhlIHN0eWxlc2hlZXQuPGJyLz48YnIvPjwvbGk+Ci0JCSAgPGxpPjxqdW1wIGhyZWY9ImFwaWRvY3Mvb3JnL2FwYWNoZS94YWxhbi90cmFjZS9HZW5lcmF0ZUV2ZW50Lmh0bWwiPkdlbmVyYXRlRXZlbnQ8L2p1bXA+IGlzIGFuIGV2ZW50IHRoYXQgaXMgCi0JCSAgcGFzc2VkIHRvIHRoZSBUcmFjZUxpc3RlbmVyLmdlbmVyYXRlZCgpIGZ1bmN0aW9uLiBJdCBpcyBjYWxsZWQgYWZ0ZXIgYW4gZXZlbnQgb2NjdXJzIHRvIGNyZWF0ZSBzb21ldGhpbmcgaW4gdGhlIHJlc3VsdAotICAgICAgdHJlZS48YnIvPjxici8+PC9saT4KLSAgICAgIDxsaT48anVtcCBocmVmPSJhcGlkb2NzL29yZy9hcGFjaGUveGFsYW4vdHJhY2UvU2VsZWN0aW9uRXZlbnQuaHRtbCI+U2VsZWN0aW9uRXZlbnQ8L2p1bXA+IGlzIGFuIGV2ZW50IHRyaWdnZXJlZCBieSB0aGUKLSAgICAgICBzZWxlY3Rpb24gb2YgYSBzdHlsZXNoZWV0IG5vZGUuPC9saT4KLQkJPC91bD4KLSAgICA8cD5UaGUgPGxpbmsgaWRyZWY9ImNvbW1hbmRsaW5lIj5jb21tYW5kLWxpbmUgdXRpbGl0eTwvbGluaz4gdXNlcyB0aGUgZGVidWdnZXIgaW50ZXJmYWNlIHdoZW4geW91IGluY2x1ZGUgb25lIG9yIG1vcmUgb2YgdGhlCi0gICAgIGZvbGxvd2luZyBzd2l0Y2hlczogPGNvZGU+LVRUPC9jb2RlPiwgPGNvZGU+LVRHPC9jb2RlPiwgPGNvZGU+LVRTPC9jb2RlPiwgPGNvZGU+LVRUQzwvY29kZT4uPC9wPgotICAgIDxwPkV4YW1wbGU6PC9wPgotPHNvdXJjZT5pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFuc2Zvcm1lci5UcmFuc2Zvcm1lckltcGw7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5UcmFjZU1hbmFnZXI7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi50cmFjZS5QcmludFRyYWNlTGlzdGVuZXI7Ci0uLi4KLS8vIFNldCB1cCBhIFByaW50VHJhY2VMaXN0ZW5lciBvYmplY3QgdG8gcHJpbnQgdG8gYSBmaWxlLgotamF2YS5pby5GaWxlV3JpdGVyIGZ3ID0gbmV3IGphdmEuaW8uRmlsZVdyaXRlcigiZXZlbnRzLmxvZyIpOwotamF2YS5pby5QcmludFdyaXRlciBwdyA9IG5ldyBqYXZhLmlvLlByaW50V3JpdGVyKGZ3KTsKLVByaW50VHJhY2VMaXN0ZW5lciBwdGwgPSBuZXcgUHJpbnRUcmFjZUxpc3RlbmVyKHB3KTsKLQotLy8gUHJpbnQgaW5mb3JtYXRpb24gYXMgZWFjaCBub2RlIGlzICdleGVjdXRlZCcgaW4gdGhlIHN0eWxlc2hlZXQuCi1wdGwubV90cmFjZUVsZW1lbnRzID0gdHJ1ZTsKLS8vIFByaW50IGluZm9ybWF0aW9uIGFmdGVyIGVhY2ggcmVzdWx0LXRyZWUgZ2VuZXJhdGlvbiBldmVudC4KLXB0bC5tX3RyYWNlR2VuZXJhdGlvbiA9IHRydWU7Ci0vLyBQcmludCBpbmZvcm1hdGlvbiBhZnRlciBlYWNoIHNlbGVjdGlvbiBldmVudC4KLXB0bC5tX3RyYWNlU2VsZWN0aW9uID0gdHJ1ZTsKLS8vIFByaW50IGluZm9ybWF0aW9uIHdoZW5ldmVyIGEgdGVtcGxhdGUgaXMgaW52b2tlZC4KLXB0bC5tX3RyYWNlVGVtcGxhdGVzID0gdHJ1ZTsKLQotLy8gU2V0IHVwIHRoZSB0cmFuc2Zvcm1hdGlvbiAgICAKLWphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5ID0gCi0gICAgICAgICAgICAgICAgICAgICBqYXZheC54bWwudHJuYXNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IAotICB0RmFjdG9yeS5uZXdUcmFuc2Zvcm1lcihuZXcgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJmb28ueHNsIikpOwotCi0vLyBDYXN0IHRoZSBUcmFuc2Zvcm1lciBvYmplY3QgdG8gVHJhbnNmb3JtZXJJbXBsLgotaWYgKHRyYW5zZm9ybWVyIGluc3RhbmNlb2YgVHJhbnNmb3JtZXJJbXBsKSB7Ci0gIFRyYW5zZm9ybWVySW1wbCB0cmFuc2Zvcm1lckltcGwgPSAoVHJhbnNmb3JtZXJJbXBsKXRyYW5zZm9ybWVyOwotICAKLSAgLy8gUmVnaXN0ZXIgdGhlIFRyYWNlTGlzdGVuZXIgd2l0aCB0aGUgVHJhY2VNYW5hZ2VyIGFzc29jaWF0ZWQgCi0gIC8vIHdpdGggdGhlIFRyYW5zZm9ybWVySW1wbC4KLSAgVHJhY2VNYW5hZ2VyIHRyTWdyID0gdHJhbnNmb3JtZXJJbXBsLmdldFRyYWNlTWFuYWdlcigpOwotICB0ck1nci5hZGRUcmFjZUxpc3RlbmVyKHB0bCk7Ci0gIAotICAvLyBQZXJmb3JtIHRoZSB0cmFuc2Zvcm1hdGlvbiAtLXByaW50aW5nIGluZm9ybWF0aW9uIHRvCi0gIC8vIHRoZSBldmVudHMgbG9nIGR1cmluZyB0aGUgcHJvY2Vzcy4KLSAgdHJhbnNmb3JtZXIudHJhbnNmb3JtCi0gICAgICAoIG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2UoImZvby54bWwiKSwgCi0gICAgICAgIG5ldyBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZXcgamF2YS5pby5GaWxlV3JpdGVyKCJmb28ub3V0IikpICk7Ci19Ci0vLyBDbG9zZSB0aGUgUHJpbnRXcml0ZXIgYW5kIEZpbGVXcml0ZXIuCi1wdy5jbG9zZSgpOwotZncuY2xvc2UoKTs8L3NvdXJjZT4KLTxwPkZvciBhIHNhbXBsZSBhcHBsaWNhdGlvbiB0aGF0IHVzZXMgdGhpcyB0ZWNobmlxdWUsIHNlZSA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJ0cmFjZSI+VHJhY2U8L2xpbms+LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJjb21wYXQiLz4KLTxzMiB0aXRsZT0iVXNpbmcgdGhlICZ4c2x0NGo7IHZlcnNpb24gMSBBUEkiPgotPG5vdGU+PGVtPlRoZSBjb21wYXRpYmlsaXR5IGphciAoeGFsYW5qMWNvbXBhdC5qYXIpLCB3aGljaCBwcm92aWRlcyBzdXBwb3J0IGZvciBYYWxhbi1KYXZhIDEgQVBJLCBoYXMgYmVlbiBkZXByZWNhdGVkLiBBbGwgCi1zdXBwb3J0IGZvciB0aGlzIEFQSSB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5leHQgcmVsZWFhc2UuIElmIHlvdSBoYXZlIG5vdCBhbHJlYWR5IGRvbmUgc28sIHdlIHN0b25nbHkgdXJnZSB5b3UgdG8gc2hpZnQgaW1tZWRpYXRlbHkgdG8gdGhlIFhhbGFuLUphdmEgMi9KQVhQIDEuMSBBUEkuPC9lbT48YnIvPjxici8+Ci08ZW0+JnhzbHQ0ajsgdmVyc2lvbiAxIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQgYW5kIG5vIGxvbmdlciBhdmFpbGFibGUgZnJvbSB4bWwuYXBhY2hlLm9yZy48L2VtPjwvbm90ZT4KLTxwPlRoZSBiaW4gZGlyZWN0b3J5IGluY2x1ZGVzIGEgY29tcGF0aWJpbGl0eSBqYXIsIHhhbGFuajFjb21wYXQuamFyLCB0aGF0IGxldHMgeW91IHJlYnVpbGQgeW91ciBYYWxhbi1KYXZhIDEueCBhcHBsaWNhdGlvbnMgdG8gcnVuIHdpdGggWGFsYW4tSmF2YSAyLiBBcyBhIHBvaW50IG9mIHJlZmVyZW5jZSwgdGhpcyBKQVIgaW5jbHVkZXMgdGhlIEFQSSByZXF1aXJlZCB0byByZWNvbXBpbGUgdGhlIFhhbGFuLUphdmEgMS54IGNvcmUgc2FtcGxlIGFwcGxpY2F0aW9ucyAoZXhjbHVkaW5nIHRoZSBzYW1wbGUgZXh0ZW5zaW9ucykgYW5kIHJ1biB0aGVtIHdpdGggWGFsYW4tSmF2YSAyLiBUbyB1c2UgdGhpcyBjb21wYXRpYmlsaXR5IGxheWVyIHdpdGggYW4gZXhpc3RpbmcgWGFsYW4tSmF2YSAxLnggYXBwbGljYXRpb24sIGRvIHRoZSBmb2xsb3dpbmc6PC9wPgotPG9sPgotPGxpPlBsYWNlIHhhbGFuajFjb21wYXQuamFyIG9uIHRoZSBzeXN0ZW0gY2xhc3NwYXRoIGluIGZyb250IG9mIHRoZSBYYWxhbi1KYXZhIDIgeGFsYW4uamFyIChib3RoIGFyZSBpbiB0aGUgYmluIGRpcmVjdG9yeSkuPGJyLz48YnIvPjwvbGk+Ci08bGk+UmVjb21waWxlIHlvdXIgYXBwbGljYXRpb24uIEl0IGl0IGRvZXMgbm90IGNvbXBpbGUsIHlvdSBtYXkgYmUgdXNpbmcgWGFsYW4tSmF2YSAxLnggQVBJIHRoYXQgdGhlIGNvbXBhdGliaWxpdHkgbGF5ZXIgZG9lcyBub3Qgc3VwcG9ydC4gPGJyLz48YnIvPjwvbGk+Ci08bGk+UnVuIHRoZSByZWNvbXBpbGVkIGFwcGxpY2F0aW9uIHdpdGggeGFsYW5qMWNvbXBhdC5qYXIgb24gdGhlIHN5c3RlbSBjbGFzc3BhdGggaW4gZnJvbnQgb2YgdGhlIFhhbGFuLUphdmEgMiB4YWxhbi5qYXIuPC9saT4KLTwvb2w+Ci08cD5XZSB1cmdlIG91ciBYYWxhbi1KYXZhIDEueCB1c2VycyB0byBzdGFydCB1c2luZyBYYWxhbi1KYXZhIDIuIFRoYXQgaXMgd2hlcmUgd2UgYXJlIGNvbmNlbnRyYXRpbmcgb3VyIGVmZm9ydHMgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZSBhbmQgZml4IGFueSBvdXRzdGFuZGluZyBidWdzLiBUbyBzZWUgd2hhdCBwb3J0aW9uIG9mIHRoZSBYYWxhbi1KYXZhIDEueCBBUEkgd2UgaGF2ZSBpbmNsdWRlZCBpbiB4YWxhbmoxY29tcGF0Lmphciwgc2VlIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImNvbXBhdGFwaSIvPi4gRm9yIGV4YW1wbGUsIHRoZSBjb21wYXRpYmlsaXR5IGxheWVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHVzZSBvZiBYYWxhbi1KYXZhIDEueCBleHRlbnNpb25zLiBJZiB5b3UgZmVlbCB0aGF0IHdlIHNob3VsZCBleHRlbmQgb3VyIGNvbXBhdGliaWxpdHkgSkFSIHRvIHN1cHBvcnQgYWRkaXRpb25hbCBYYWxhbi1KYXZhIDEueCBBUEkgY2FsbHMsIHBsZWFzZSBsZXQgdXMga25vdyBleGFjdGx5IHdoYXQgeW91IHdvdWxkIGxpa2UgdG8gc2VlLjwvcD4KLTwvczI+Ci08L3MxPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi93aGF0c25ldy54bWwgYi94ZG9jcy9zb3VyY2VzL3hhbGFuL3doYXRzbmV3LnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzJmZDU3My4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL3doYXRzbmV3LnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDc1ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4KLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLTxzMSB0aXRsZT0iV2hhdCdzIG5ldyBpbiAmeHNsdDRqMjsiPgotPHVsPgotICAgICA8bGk+PGxpbmsgYW5jaG9yPSJkZXNpZ24iPk5ldyBkZXNpZ248L2xpbms+PC9saT4KLSAgICAgPGxpPjxsaW5rIGFuY2hvcj0iZHRtIj5Eb2N1bWVudCBUYWJsZSBNb2RlbCAoRFRNKTwvbGluaz48L2xpPgotICA8L3VsPjxhbmNob3IgbmFtZT0iZGVzaWduIi8+Ci0gIDxzMiB0aXRsZT0iTmV3IERlc2lnbiI+Ci0gIDxwPiZ4c2x0NGoyOyByZXByZXNlbnRzIGEgZnVuZGFtZW50YWwgcmVkZXNpZ24gb2YgWGFsYW4uIFRoZSBwcmltYXJ5IG9iamVjdGl2ZSBvZiB0aGlzIHJlZGVzaWduIGlzIGFuIGVhc2llci10by11c2UsIG1vcmUgdW5kZXJzdGFuZGFibGUsIGFuZCBtb3JlIG1vZHVsYXIgQVBJIHRoYXQgZW5jb3VyYWdlcyB3aWRlciBwYXJ0aWNpcGF0aW9uIGluIGl0cyBvbmdvaW5nIGRldmVsb3BtZW50IGJ5IHRoZSBvcGVuLXNvdXJjZSBYTUwgZGV2ZWxvcGVyIGNvbW11bml0eSwgYW5kIHRoYXQgbGVuZHMgaXRzZWxmIHRvICJzdHJlYW1pbmcsIiB0aGUgcHJvZHVjdGlvbiBvZiB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQgd2hpbGUgdGhlIGlucHV0IGlzIHN0aWxsIGJlaW5nIHBhcnNlZC48L3A+Ci08cD4meHNsdDRqMjsgYnVpbGRzIG9uIDxyZXNvdXJjZS1yZWYgaWRyZWY9InNheDIiLz4sIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImRvbTIiLz4sIGFuZCB0aGUgPHJlc291cmNlLXJlZiBpZHJlZj0iamF4cCIvPi4gRm9yIGV4YW1wbGUsICZ4c2x0NGoyOyBpbmNvcnBvcmF0ZXMgdGhlIFNBWCBwYXJzaW5nIGV2ZW50IG1vZGVsIGluIGl0cyBzdXBwb3J0IGZvciB0aGUgaW5jcmVtZW50YWwgcHJvZHVjdGlvbiBvZiB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQuICZ4c2x0NGoyOyBhbHNvIGltcGxlbWVudHMgdGhlICBzdGFuZGFyZCBUckFYIEFQSSAoc2VlIGJlbG93KSB0aGF0IGVuYWJsZXMgeW91IHRvIGNvZGUgeW91ciBYTUwgYXBwbGljYXRpb25zIHdpdGhvdXQgcmVmZXJlbmNlIHRvIHRoZSBpbnRlcm5hbCBkZXRhaWxzIG9mIGEgcGFydGljdWxhciBUcmFuc2Zvcm1lciBvciBYTUwgcGFyc2VyLjwvcD4KLTxwPkdpdmVuIHRoZSBzY29wZSBvZiB0aGUgcmVkZXNpZ24sIHRoZSBjaGFuZ2VzIHdpdGggcmVzcGVjdCB0byA8anVtcCBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4vaW5kZXguaHRtbCI+JnhzbHQ0ajsgMS54PC9qdW1wPiBhcmUgZ2xvYmFsIGluIG5hdHVyZS4gRm9yIGFuIGludHJvZHVjdGlvbiB0byB0aGUgJnhzbHQ0ajI7IHVzYWdlIHBhdHRlcm5zLCBzZWUgPGxpbmsgaWRyZWY9InVzYWdlcGF0dGVybnMiPkJhc2ljIFVzYWdlIFBhdHRlcm5zPC9saW5rPi48L3A+Ci08cD4meHNsdDRqMjsgaW1wbGVtZW50cyB0aGUgPGxpbmsgaWRyZWY9InRyYXgiPlRSYVggKFRyYW5zZm9ybWF0aW9uIEFQSSBmb3IgWE1MKTwvbGluaz4gaW50ZXJmYWNlcy4gVGhlIHByb2R1Y3Qgb2YgZXh0ZW5zaXZlIG9wZW4tc291cmNlIGNvbGxhYm9yYXRpb24gYnkgbWVtYmVycyBvZiB0aGUgWE1MIGRldmVsb3BlciBjb21tdW5pdHksIFRyQVggcHJvdmlkZXMgYSBjb25jZXB0dWFsIGZyYW1ld29yayBhbmQgYSBzdGFuZGFyZCBBUEkgZm9yIHBlcmZvcm1pbmcgWE1MIHRyYW5zZm9ybWF0aW9ucy4gRHVyaW5nIGl0cyBldm9sdXRpb24sIHRoZSBUckFYIEFQSSBoYXMgdW5kZXJnb25lIHNldmVyYWwgcmV2aXNpb25zLiBXZSBiZWxpZXZlIHRoaXMgQVBJIGhhcyBub3cgcmVhY2hlZCBvciBpcyB2ZXJ5IGNsb3NlIHRvIGZpbmFsIGZvcm0uIEluIE5vdmVtYmVyIDIwMDAsIFRyQVggd2FzIGluY29ycG9yYXRlZCBpbnRvIDxyZXNvdXJjZS1yZWYgaWRyZWY9ImpzcjA2MyIvPiwgdGhlIEphdmEgQVBJIGZvciBYTUwgUHJvY2Vzc2luZyAxLjEgLCB3aGljaCBoYXMgYmVlbiBwdWJsaXNoZWQgZm9yIHB1YmxpYyByZXZpZXcgKHNlZSA8cmVzb3VyY2UtcmVmIGlkcmVmPSJqYXhwMTEiLz4pLiBXZSBzdHJvbmdseSBlbmNvdXJhZ2UgeW91IHRvIHV0aWxpemUgdGhlIFRyQVggZnJhbWV3b3JrIHdoZW4geW91IHVzZSAmeHNsdDRqMjsgdG8gcGVyZm9ybSBYTUwgdHJhbnNmb3JtYXRpb25zLjwvcD4KLTxwPlRoZSBiYXNpYyBvcmdhbml6YXRpb24gb2YgVHJBWCBpcyBxdWl0ZSBzaW1wbGU6IHVzZSBhIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBwcm9jZXNzIHRyYW5zZm9ybWF0aW9uIGluc3RydWN0aW9ucyBhbmQgZ2VuZXJhdGUgYSBUcmFuc2Zvcm1lciwgd2l0aCB3aGljaCB5b3UgY2FuIGFwcGx5IHRoZSBwcm9jZXNzZWQgdHJhbnNmb3JtYXRpb24gaW5zdHJ1Y3Rpb25zIHRvIHlvdXIgWE1MIFNvdXJjZSwgcHJvZHVjaW5nIGEgdHJhbnNmb3JtYXRpb24gUmVzdWx0LiBGb3IgbW9yZSBkZXRhaWwsIHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJiYXNpYyI+QmFzaWMgc3RlcHM8L2xpbms+LjwvcD4KLTxwPkFzIHBhcnQgb2YgdGhlIEphdmEgQVBJIGZvciBYTUwgUHJvY2Vzc2luZywgVHJhWCBwcm92aWRlcyBhIHN0YWJsZSBmcmFtZXdvcmsgZm9yIHBsdWdnaW5nIFRyYW5zZm9ybWVycyAobGlrZSAmeHNsdDRqOykgYW5kIFhNTCBwYXJzZXJzIChsaWtlICZ4bWw0ajspIGludG8geW91ciBhcHBsaWNhdGlvbnMgd2l0aG91dCB0eWluZyB5b3Vyc2VsZiB0byB0aGUgaW50ZXJuYWwgZGV0YWlscyBvZiB0aG9zZSBpbXBsZW1lbnRhdGlvbnMuIFNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJwbHVnIj5QbHVnZ2luZyBpbiBhIFRyYW5zZm9ybWVyIGFuZCBYTUwgcGFyc2VyPC9saW5rPi48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0iZHRtIi8+Ci08czIgdGl0bGU9IiZ4c2x0NGo7IERUTSI+Ci08cD5JbiBwbGFjZSBvZiB0aGUgRE9NIG9iamVjdCB0cmVlIG9mIG5vZGVzLCB0aGUgRG9jdW1lbnQgVGFibGUgTW9kZWwgKERUTSkgdXNlcyBpbnRlZ2VyIGFycmF5cyBhbmQgc3RyaW5nIHBvb2xzIHRvIHJlcHJlc2VudCB0aGUgc3RydWN0dXJlIGFuZCBjb250ZW50IG9mIHRoZSBYTUwgZG9jdW1lbnQgdG8gYmUgdHJhbnNmb3JtZWQuIFRoZSBtb3RpdmF0aW9uIGJlaGluZCB0aGlzIG1vZGVsIGlzIHRvIG9wdGltaXplIHBlcmZvcm1hbmNlIGFuZCBtaW5pbWl6ZSBzdG9yYWdlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxsaW5rIGlkcmVmPSJkdG0iPkRUTTwvbGluaz4uPC9wPgotPC9zMj4KLTwvczE+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi94bWxmaWx0ZXJzLmdpZiBiL3hkb2NzL3NvdXJjZXMveGFsYW4veG1sZmlsdGVycy5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiNGQ2NDAuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94YWxhbi94bWxmaWx0ZXJzLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveGFsYW4veHNsdGNfY29uc3RyYWludHMueG1sIGIveGRvY3Mvc291cmNlcy94YWxhbi94c2x0Y19jb25zdHJhaW50cy54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDFkMDZkOWEuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94YWxhbi94c2x0Y19jb25zdHJhaW50cy54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMTExICswLDAgQEAKLTxhbmNob3IgbmFtZT0ieHNsdGNyZWxlYXNlbm90ZXMiLz4KLTxzMiB0aXRsZT0iWFNMVEMgUmVsZWFzZSBOb3RlcyI+Ci08cD5Gb3IgdGhpcyByZWxlYXNlLCBwbGVhc2Ugbm90ZSB0aGUgZm9sbG93aW5nIGNoYW5nZXMsIGFkZGl0aW9ucywgb21pc3Npb25zLCBwcm9ibGVtcywgcHJvY2VkdXJlcyBmb3IgcnVubmluZyBkZW1vcywgYW5kIG5ldyBzdXBwb3J0IGZvciB0aGUgVHJBWCBBUEkuPC9wPgotPHVsPgotICA8bGk+PGxpbmsgYW5jaG9yPSJ4c2x0Y25ldyI+Q2hhbmdlcyBhbmQgTmV3IEZlYXR1cmVzPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9InhzbHRjY29uZiI+Q29uZm9ybWFuY2U8L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0ieHNsdGNrbm93bnByb2JsZW1zIj5Lbm93biBQcm9ibGVtczwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJ4c2x0Y2RlbW9zIj5SdW5uaW5nIERlbW9zPC9saW5rPjwvbGk+ICAKLSAgPGxpPjxsaW5rIGFuY2hvcj0ieHNsdGN0cmF4Ij5UcmFuc2xldHMgYW5kIFRyQVg8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJ4c2x0Y2hpc3RvcnkiPkhpc3Rvcnkgb2YgWFNMVEMgc29mdHdhcmUgY2hhbmdlczwvbGluaz48L2xpPgotPC91bD4KLTxhbmNob3IgbmFtZT0ieHNsdGNuZXciLz4KLTxzMyB0aXRsZT0iQ2hhbmdlcyBzaW5jZSAmeHNsdDRqOyAyLjIuRDkiPgotPHA+WFNMVEMgc291cmNlIGNvZGUgdXBkYXRlczo8L3A+Ci08dWw+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBQYXJzZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkkgYWRkZWQgYSBmbGFnIHRvIHRoZSBjb21waWxlci9QYXJzZXIgY2xhc3MgdGhhdCBpcyBzZXQgaWYgdGhlIG91dGVybW9zdCAKLWVsZW1lbnQKLSBpbiB0aGUgc3R5bGVzaGVldCBjb250YWlucyBhIGRlZmluaXRpb24gb2YgdGhlIFhTTCBuYW1lc3BhY2UuIFRoZSBwYXJzZXIgCi1hbHJlYWR5Ci0gaGFzIGEgZ2xvYmFsIHZhcmlhYmxlICdfdGFyZ2V0JyB0aGF0IGlzIHNldCBpZiB0aGUgc3R5bGVzaGVldCBjb250YWlucyBhCi0gJmx0Oz94bWwtc3R5bGVzaGVldD8mZ3Q7IFBJIG9yIG5vdC4gVGhlIGNvbXBpbGVyIHdpbGwgbm93IGZsYWcgYW4gZXJyb3IgaWYgbmVpdGhlcgotIGZsYWdzIGFyZSBzZXQgYWZ0ZXIgdGhlIHdob2xlIFhTTC9YTUwgaW5wdXQgZG9jdW1lbnQgaGFzIGJlZW4gcGFyc2VkLgotIFBSOiBidWd6aWxsYSAxNzgwCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzEzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgVW5pb25QYXRoRXhwci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgYSBzbWFsbCBmaXggdGhhdCBvcmRlcnMgdGhlIGV4cHJlc3Npb25zIGluc2lkZSBhIHVuaW9uIGluIHN1Y2ggYSB3YXkgCi10aGF0Ci0gZXhwcmVzc2lvbnMgd2l0aCBhbiBhdHRyaWJ1dGUgYXhpcyBvciBhdHRyaWJ1dGUgbm9kZSB0eXBlIHdpbGwgYmUgcHV0IGZpcnN0LgotIFBSOiBidWd6aWxsYSAyOTIxCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzEzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgUGFyc2VyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BIHNtYWxsIGZpeCB0aGF0IHdpbGwgYWxsb3cgdG9wLWxldmVsIGVsZW1lbnRzIG9mIGFuIHVua25vd24gVVJJLgotIFhTTFRDIG5vdyBpZ25vcmVkIHRoZSBlbGVtZW50KHMpLCB3aGlsZSBpdCBwcmV2aW91c2x5IHJlcG9ydGVkIGFuIGVycm9yCi0gb2YgYW4gdW5zdXBwb3J0ZWQgWFNMVCBleHRlbnNpb24uCi0gUFI6IGJ1Z3ppbGxhIDI4NDAKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gQWJzdHJhY3RUcmFuc2xldC5qYXZhIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmEKLSBUZXh0T3V0cHV0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BIHN0YXJ0IG9uIGEgZml4IGZvciBvdXRwdXQgRE9DVFlQRSBkZWNsYXJhdGlvbnMgYmFzZWQgb24gdGhlIGF0dHJpYnV0ZXMKLSBvZiB0aGUgJmx0O3hzbDpvdXRwdXQmZ3Q7IGVsZW1lbnQuIEkgYWxzbyBhZGRlZCBhIGZpeCBmb3IgYnVnIDI4NjMsIHRvIHByZXZlbnQKLSB1cyBmcm9tIG91dHB1dHRpbmcgbmFtZXNwYWNlIGRlbGNhcmF0aW9uIHRoYXQgcG9pbnQgYSBwcmVmaXggdG8gdGhlIG51bGwKLSBVUkkgKHN1Y2ggYXMgJ3htbG5zOmJsb2I9IiInKS4KLSBQUjogYnVnemlsbGEgMjg2MwotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQGFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQGFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciB4cGF0aC5jdXA8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5idWcgMjU1MywgZml4ZXMgQWJicmV2aWF0ZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aCwKLSBzb21lIHJlbGF0aXZlIGxvY2F0aW9uIHBhdGhzIHN0aWxsIGdpdmUgZHVwbGljYXRlcywgd2lsbCBuZWVkIHRvIGZpbHRlci48YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NtZGxpbmUgVHJhbnNmb3JtLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIE91dHB1dC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIERlZmF1bHRSdW4uamF2YQotIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmEgVGV4dE91dHB1dC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW1wbGVtZW50ZWQgc3VwcG9ydCBmb3IgdGhlIGRvY3R5cGUtc3lzdGVtIGFuZCBkb2N0eXBlLXB1YmxpYyBhdHRyaWJ1dGVzCi0gb2YgdGhlICZsdDt4c2w6b3V0cHV0LyZndDsgZWxlbWVudC4gVGhlIHRyYW5zbGV0IHBvc3QtcHJvY2Vzc29yIChUZXh0T3V0cHV0KSBjYW4KLSBub3cgYmUgaW5zdGFuY2lhdGVkIHdpdGggYSBDb250ZW50SGFuZGxlciBhbmQgYW4gb3B0aW9uYWwgTGV4aWNhbEhhbmRsZXIuCi0gVGhlIExleGljYWxIYW5kbGVyIHdpbGwgcmVjZWl2ZSBub3RvZmljYXRpb25zIG9mIHRoZSBET0NUWVBFIGRlY2xhcmF0aW9uLgotIFRoZSBkZWZhdWx0IFNBWCBvdXRwdXQgaGFuZGxlciBub3cgaW1wbGVtZW50cyBib3RoIENvbnRlbnRIYW5kbGVyIGFuZAotIExleGljYWxIYW5kbGVyLiBUaGUgTGV4aWNhbEhhbmRsZXIgb25seSBoYW5kbGVzIHRoZSBzdGFydERURCgpIG1ldGhvZCwKLSBieSBvdXRwdXR0aW5nIHRoZSBET0NUWVBFIGRlY2xhcmF0aW9uLCBhbmQgYWxsIG90aGVyIG1ldGhvZHMgYXJlIGVtcHR5LgotIFRoZSB0cmF4LlRyYW5zZm9ybWVyIGltcGxlbWVudGF0aW9uIGhhcyBhbHNvIGJlZW4gdXBkYXRlZCB0byB1c2UgdGhlCi0gTGV4aWNhbEhhbmRsZXIsIGJ1dCBJIHN0aWxsIGhhdmUgbm90IGZvdW5kIGFueSB3YXkgaW4gd2hpY2ggYSBTQVggY2xpZW50Ci0gY2FuIHNldCB0aGUgTGV4aWNhbEhhbmRsZXIuCi0gUFI6IGJ1Z3ppbGxhIDE1MDQKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBYc2xFbGVtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BIG1pbm9yIGNoYW5nZSB0byB0aGUgY2xhc3MgaGFuZGxpbmcgdGhlICZsdDt4c2w6ZWxlbWVudCZndDsgZWxlbWVudCB0byBiZSBtb3JlCi0gaW4tc3luYyB3aXRoIHRoZSBYU0xUIDEuMCBzcGVjIChhbmQgTS5LYXkncyBib29rKS4gVGhpcyBpbiBvcmRlciB0byBtYWtlCi0gaXQgbW9yZSByZWFkYWJsZSBhbmQgbWFpbnRhaW5hYmxlLiBJIHdhcyB0cnlpbmcgdG8gZGVidWcgdGhlIGNvZGUgZm9yCi0gc29tZXRoaW5nIEkgdGhvdWdodCB3YXMgYSBidWcsIGFuZCBpdCB3YXMganVzdCBpbXBvc3NpYmxlIHRvIG5hdmlnYXRlLgotIFRoaXMgY2hhbmdlIHdhcyBuZWNlc3NhcnksIGV2ZW4gdGhvdWdoIHRoZSBjb2RlIGZ1bmN0aW9uZWQgYXMgaXQgc2hvdWxkLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTQvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBMaXRlcmFsRWxlbWVudC5qYXZhCi0gUGFyc2VyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIG91dHB1dHRpbmcgYWxsIG5lY2Vzc2FyeSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zIHdpdGggTFJFcy4KLSBQUjogYnVnemlsbGEgMjg2MwotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQGFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQGFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBSZXZlcnNlSXRlcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkEgZml4IHRvIGFsbG93IHJldmVyc2UgaXRlcmF0b3JzIHRvIGJlIHJlc2V0IChpbnNpZGUgbmVzdGVkIGZvci1lYWNoIGxvb3BzKS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNS8yMDAxPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBEdXBGaWx0ZXJJdGVyYXRvci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YnVnIGZpeCAyNTUzLCBuZXcgaXRlcmF0b3IgdG8gZ2V0IHJpZCBvZiBkdXBzPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzE1LzIwMDE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIKLSBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5idWcgZml4IDI1NTMsIG5ldyBhYnMgbG9jYXRpb24gcGF0aDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIHhwYXRoLmN1cAotIENvbnN0YW50cy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YnVnIGZpeCAyNTUzLCB1cGRhdGVkIENvbnN0YW50cyBmb3IgZHVwIHByb2Nlc3NpbmcKLSBhbmQgdXBkYXRlZCBDVVAgcnVsZSBmb3IgQWJicmV2aWF0ZWRBYnNvbHV0ZUxvY2F0aW9uUGF0aHM8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBBYnNvbHV0ZUl0ZXJhdG9yLmphdmEKLSBET01JbXBsLmphdmEgRHVwRmlsdGVySXRlcmF0b3IuamF2YQotIFN0ZXBJdGVyYXRvci5qYXZhIFVuaW9uSXRlcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkltcGxlbWVudGF0aW9uIG9mIGlkKCkgYW5kIGtleSgpIHBhdHRlcm4gLSBmaW5hbGx5IQotIEFkZGVkIGEgc21hbGwgZml4IHRvIHRoZSBET01JbXBsJERlc2NlbmRhbnRJdGVyYXRvciB0byBwcmV2ZW50IE5QRXMuCi0gUFI6IGJ1Z3ppbGxhIDEzNzYKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIElkS2V5UGF0dGVybi5qYXZhCi0gS2V5Q2FsbC5qYXZhIE1vZGUuamF2YSBPdXRwdXQuamF2YSBQYXJzZXIuamF2YQotIFRlc3RTZXEuamF2YSB4cGF0aC5jdXA8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Gb3Jnb3QgYW4gJ2ltcG9ydCcgaW4gRHVwRmlsdGVySXRlcmF0b3IKLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBUcmFuc2xldE91dHB1dEhhbmRsZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIER1cEZpbHRlckl0ZXJhdG9yLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBBYnN0cmFjdFRyYW5zbGV0LmphdmEgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIuamF2YQotIFNBWEFkYXB0ZXIuamF2YSBUZXh0T3V0cHV0LmphdmEKLSBUcmFuc2xldE91dHB1dEJhc2UuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPm1pc3NpbmcgZmlsZTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzE2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBhbm90aGVyIGZpeCBmb3IgdGhlIG1pc3NpbmcgRE9DVFlQRSBkZWNsYXJhdGlvbi4gWFNMVEMgd2lsbCBub3cgb3V0cHV0Ci0gRE9DVFlQRSBkZWNsYXJhdGlvbnMgZm9yIEhUTUwgb3V0cHV0IGlmIGVpdGhlciBkb2N0eXBlLXN5c3RlbSBvciBkb2N0eXBlLQotIHB1YmxpYyBpcyBkZWNsYXJlZCBpbiB0aGUgJmx0O3hzbDpvdXRwdXQmZ3Q7IGVsZW1lbnQuIFhTTCBvdXRwdXQgd2lsbCBnZXQgYQotIERPQ1RZUEUgZGVjbGFyYXRpb24gb25seSBpZiBkb2N0eXBlLXN5c3RlbSBpcyBkZWNsYXJlZC4KLSBQUjogMTUwNAotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzE2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIEFic29sdXRlSXRlcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPgotCi0KLTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8xNi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIHhwYXRoLmN1cDxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPnR1cm5pbmcgb24gZmlsdGVyaW5nLCBidWcgMjU1Mzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzE2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIER1cEZpbHRlckl0ZXJhdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZW1vdmVkIGEgYmFkIG9wdGltaXNhdGlvbiBpbiB0aGUgZHVwbGljYXRlIGZpbHRlciBpdGVyYXRvci4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzE3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgeHBhdGguY3VwPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+cmUtYWN0aXZhdGVkIHRoZSBubyBkdXBzIGZpbHRlcmluZywgZG9udCBrbm93IGhvdwotIHRoaXMgZ290IHJldmVydGVkIGJhY2sgdG8gbm8gZmlsdGVyaW5nLCBidXQgaXQgaXMgZml4ZWQgYWdhaW4uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMTcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBJZEtleVBhdHRlcm4uamF2YQotIEtleS5qYXZhIEtleUNhbGwuamF2YSBQYXJzZXIuamF2YSBTb3J0LmphdmEKLSB4cGF0aC5jdXAKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBDb21wYXJlR2VuZXJhdG9yLmphdmEgTm9kZVNvcnRSZWNvcmRHZW5lcmF0b3IuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERURE1vbml0b3IuamF2YQotIER1cEZpbHRlckl0ZXJhdG9yLmphdmEgS2V5SW5kZXguamF2YQotIE5vZGVTb3J0UmVjb3JkLmphdmEgTm9kZVNvcnRSZWNvcmRGYWN0b3J5LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBBYnN0cmFjdFRyYW5zbGV0LmphdmEgQmFzaXNMaWJyYXJ5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5NYWpvciB1cGRhdGUgZm9yIGlkKCkgYW5kIGtleSgpLiBQYXR0ZXJucyBjb250YWluaW5nIGlkKCkgYW5kIGtleSgpIGFyZQotIG5vdyAxMDAlIHN1cHBvcnRlZCAoYWJvdXQgdGltZSksIGFuZCBpZCgpIGFuZCBrZXkoKSBleHByZXNzaW9ucyBzaG91bGQKLSBub3cgd29yayBpbiBhbGwgKGF0IGxlYXN0IG1vc3QpIGNvbWJpbmF0aW9ucy4KLSBQUjogYnVnemlsbGEgMTM3NiAoISEhKSBhbmQgMjYyNAotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZSBCYXNpc0xpYnJhcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkEgc21hbGwgZml4IGZvciBhIGNsZWFudXAgSSBkaWQgaW4gdGhlIGJhc2lzIGxpYnJhcnkgKGl0IGJyb2tlIHRoZQotIHN1YnN0cmluZygpIGZ1bmN0aW9uKSZndDsKLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIFRleHRPdXRwdXQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIHNtYWxsIGZpeCB0byBwcmV2ZW50IE5QRSBpbiBvdXRwdXQgaGFuZGxlci4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBUcmFuc2xldE91dHB1dEhhbmRsZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgVmFyaWFibGUuamF2YQotIFZhcmlhYmxlUmVmLmphdmEgVmFyaWFibGVSZWZCYXNlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBNdWx0aUhhc2h0YWJsZS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRE9NSW1wbC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIEJhc2lzTGlicmFyeS5qYXZhCi0gVGV4dE91dHB1dC5qYXZhIFRyYW5zbGV0T3V0cHV0QmFzZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgZWxlbWVudC9hdHRyaWJ1dGUgcHJlZml4IGluZm9ybWF0aW9uIGluIHRoZSBpbnRlcm5hbCBET00uCi0gVGhpcyBzaG91bGQgZml4IHNvbWUgcHJvYmxlbXMgd2UgaGF2ZSBoYWQgd2l0aCB0aGUgY29weSBhbmQgY29weS1vZgotIGVsZW1lbnRzLiBBZGRlZCBhIGZldyBsaW5lcyBvZiBjb2RlIGluIGFuIGF0dGVtcHQgdG8gc3BlZWQgdXAgdGhlIERPTSBidWlsZGVyLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8yMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBEVERNb25pdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BbiBhdHRlbXB0IHRvIG9wdGltaXNlIHRoZSBidWlsZGluZyBvZiB0aGUgSUQgaW5kZXguIFRoZSBwcmV2aW91cyB2ZXJzaW9uIG9mCi0gdGhpcyBjb2RlIHdvdWxkIHRyYXZlcnNlIHRoZSBET00gb25jZSBmb3IgZWFjaCB0eXBlIG9mIGVsZW1lbnQgdGhhdCBoYWQgYQotIGRlZmluZWQgSUQgYXR0cmlidXRlLiBUaGUgbmV3IHZlcnNpb24gdHJhdmVyc2VzIHRoZSBET00gb25jZSwgYW5kIGxvb2tzIHVwCi0gZWFjaCBlbGVtZW50J3MgdHlwZSBpbiBhIGhhc2h0YWJsZSB0byBkZXRlcm1pbmUgaXRzIElEIGF0dHJpYnV0ZSB0eXBlIChpZiAKLWFueSkuCi0gVGhlIG5ldyB2ZXJzaW9uIG9mIHRoZSBjb2RlIGRvZXMgbm90IHVzZSBzdHJpbmcgY29tcGFyaXNvbnMsIGxpa2UgdGhlIG9sZCBvbmUuCi0gVGhpcyB1cGRhdGUgd2FzIGRvbmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIHBvc3NpYmxlIHBlcmZvcm1hbmNlIGRlZ3JhZGF0aW9uIG9mCi0gaGF2aW5nIGltcGxlbWVudGVkIGFuIGVsZW1lbnQvYXR0cmlidXRlIHByZWZpeCBhcnJheSBpbiB0aGUgaW50ZXJuYWwgRE9NLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8yMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgKLSBUZW1wbGF0ZXNIYW5kbGVySW1wbC5qYXZhIFRlbXBsYXRlc0ltcGwuamF2YQotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlByb3RlY3RlZCBzb21lIG1ldGhvZHMgaW4gb3VyIFRyQVggY29kZSB0aGF0IGFyZSBub3QgZGVmaW5lZCBpbiB0aGUgVHJBWCBBUEkuCi0gVGhlc2UgbWV0aG9kcyB3ZXJlIG5ldmVyIGludGVuZGVkIGZvciBwdWJsaWMgdXNlIGFuZCBzaG91bGQgaGF2ZSBiZWVuIGRlZmluZWQKLSBhcyAicHJvdGVjdGVkIiB0byBiZWdpbiB3aXRoLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8yMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFhzbEVsZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgYSBwcm9ibGVtIHdpdGggc29tZSBjb21iaW5hdGlvbnMgb2YgJmx0O3hzbDplbGVtZW50Jmd0OyBhbmQgbmFtZXNwYWNlCi0gYWxpYXNpbmcuIFRoZSBvdXRwdXQgbGFja2VkIHRoZSBuZWNlc3NhcnkgbmFtZXNwYWNlIGRlZmluaXRpb25zIHdoZW4gYW4KLSBlbGVtZW50IGNyZWF0ZWQgd2l0aCAmbHQ7eHNsOmVsZW1lbnQmZ3Q7IHdhcyBnaXZlbiBhIHFuYW1lIHdpdGggYSBwcmVmaXggdGhhdAotIHdhcyBtYXBwZWQgdG8gc29tZSBvdGhlciBwcmVmaXguCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8yMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFBhcmFtZXRlclJlZi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+cmVtb3ZlZCB0eXBlQ2hlY2soKSwgdXNlcyB0aGUgYmFzZSBjbGFzc2VzIG1ldGhvZCBub3c8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlcgotIFZhcmlhYmxlUmVmQmFzZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YWRkZWQgZGVmYXVsdCB0eXBlQ2hlY2soKSB0byB0aGlzIGJhc2UgY2xhc3M8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBSZWxhdGlvbmFsRXhwci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YnVnIGZpeCAyODM4LCBjYXN0IHRvIHR5cGUgcmVhbCBpZiBib3RoIG9wZXJhbmRzIGFyZQotIFJlc3VsdFRyZWVUeXBlPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBET00uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIKLSBBYnNvbHV0ZUxvY2F0aW9uUGF0aC5qYXZhIEFic29sdXRlUGF0aFBhdHRlcm4uamF2YQotIEFuY2VzdG9yUGF0dGVybi5qYXZhIEFwcGx5VGVtcGxhdGVzLmphdmEKLSBCb29sZWFuRXhwci5qYXZhIENhbGxUZW1wbGF0ZS5qYXZhIENhc3RFeHByLmphdmEKLSBDb25zdGFudHMuamF2YSBDb3B5LmphdmEgQ29weU9mLmphdmEKLSBEb2N1bWVudENhbGwuamF2YSBGaWx0ZXJFeHByLmphdmEKLSBGaWx0ZXJlZEFic29sdXRlTG9jYXRpb25QYXRoLmphdmEgRm9yRWFjaC5qYXZhCi0gRnVuY3Rpb25DYWxsLmphdmEgS2V5LmphdmEgS2V5Q2FsbC5qYXZhCi0gTGFzdENhbGwuamF2YSBMb2NhbE5hbWVDYWxsLmphdmEgTW9kZS5qYXZhCi0gTmFtZUNhbGwuamF2YSBOYW1lc3BhY2VVcmlDYWxsLmphdmEgTnVtYmVyLmphdmEKLSBQYXJhbS5qYXZhIFBhcmFtZXRlclJlZi5qYXZhCi0gUGFyZW50TG9jYXRpb25QYXRoLmphdmEgUGFyZW50UGF0dGVybi5qYXZhCi0gUG9zaXRpb25DYWxsLmphdmEgUHJlZGljYXRlLmphdmEKLSBSZWxhdGlvbmFsRXhwci5qYXZhIFNvcnQuamF2YSBTdGVwLmphdmEKLSBTdGVwUGF0dGVybi5qYXZhIFN0eWxlc2hlZXQuamF2YQotIFN5bnRheFRyZWVOb2RlLmphdmEgVGVtcGxhdGUuamF2YSBUZXN0U2VxLmphdmEKLSBUZXh0LmphdmEgVHJhbnNsZXRPdXRwdXQuamF2YSBWYWx1ZU9mLmphdmEKLSBWYXJpYWJsZS5qYXZhIFZhcmlhYmxlUmVmLmphdmEgV2hpdGVzcGFjZS5qYXZhCi0gWFNMVEMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbAotIENsYXNzR2VuZXJhdG9yLmphdmEgRXJyb3JNc2cuamF2YQotIE1ldGhvZEdlbmVyYXRvci5qYXZhIE5vZGVTZXRUeXBlLmphdmEgTm9kZVR5cGUuamF2YQotIFJlc3VsdFRyZWVUeXBlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBBeGlzLmphdmEKLSBET01BZGFwdGVyLmphdmEgRE9NSW1wbC5qYXZhIExvYWREb2N1bWVudC5qYXZhCi0gTXVsdGlET00uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YSBCYXNpc0xpYnJhcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNoYW5nZXMgYWxsIGNhbGxzIGZyb20gdGhlIGNvbXBpbGVkIHRyYW5zbGV0IGNvZGUgdG8gdGhlIERPTSB0byBiZSBjYWxscwotIHRvIHRoZSBET00gaW50ZXJmYWNlIChhbmQgbm90IHRvIGEgc3BlY2lmaWMgRE9NIGNsYXNzKS4gSSBkaWQgdGhpcyB0byBtYWtlCi0gaXQgcG9zc2libGUgdG8gcGx1Z2kgaW4gYW55IERPTSBpbXBsZW1lbnRhdGlvbi4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBUcmFuc2xldE91dHB1dEhhbmRsZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgQ29uc3RhbnRzLmphdmEKLSBUcmFuc2xldE91dHB1dC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gQWJzdHJhY3RUcmFuc2xldC5qYXZhIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmEKLSBUZXh0T3V0cHV0LmphdmEgVHJhbnNsZXRPdXRwdXRCYXNlLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBhbiAmbHQ7eHNsdGM6b3V0cHV0Jmd0OyBleHRlbnNpb24gdG8gYWxsb3cgZm9yIG11bHRpcGxlIG91dHB1dCBmaWxlcy4gSSBrbm93Ci0gdGhhdCB0aGlzIGlzIG5vdCBhIHByaW9yaXRpc2VkIHRhc2ssIGJ1dCBJIG5lZWQgdGhpcyBmb3IgYSBsaXR0bGUgcHJvamVjdCBJCi0gYW0gd29ya2luZyBvbi4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMjgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBQYXJhbS5qYXZhCi0gUGFyYW1ldGVyUmVmLmphdmEgVmFyaWFibGUuamF2YSBWYXJpYWJsZUJhc2UuamF2YQotIFZhcmlhYmxlUmVmLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBOb2RlU2V0VHlwZS5qYXZhIE5vZGVUeXBlLmphdmEgUmVmZXJlbmNlVHlwZS5qYXZhCi0gUmVzdWx0VHJlZVR5cGUuamF2YSBTdHJpbmdUeXBlLmphdmEgVHlwZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSBmZXcgZml4ZXMgZm9yIHRoZSByZWdyZXNzaW9uIGNhdXNlZCBieSBteSBsYXN0IChodWdlKSBwdXRiYWNrLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8yOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBEdXBGaWx0ZXJJdGVyYXRvci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSBmaXggZm9yIHRoZSBwb3NpdGlvbigpIGZ1bmN0aW9uIHdoZW4gdXNpbmcgZHVwbGljYXRlIGZpbHRlciBpdGVyYXRvcnMuCi0gUFI6IG4vCi0gT2J0YWluZWQgZnJvbTogTi9BCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PC91bD4KLTwvczM+Ci08YW5jaG9yIG5hbWU9InhzbHRjY29uZiIvPgotPHMzIHRpdGxlPSJYU0xUIDEuMCBDb25mb3JtYW5jZSBhbmQgRXh0ZW5zaW9ucyI+Ci08cD5YU0xUQyBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIG9mIHRoZSA8cmVzb3VyY2UtcmVmIGlkcmVmPSJ4c2wiLz46PC9wPgotPHVsPgotICA8bGk+VGhlIG5hbWVzcGFjZSBheGlzIGlzIG5vdCBpbXBsZW1lbnRlZC4gWW91IGNhbm5vdCBnZXQgYSBub2RlIHNldCBjb250YWluaW5nIHRoZSBuYW1lc3BhY2Ugbm9kZXMKLSAgICBpbiBzY29wZSBmcm9tIGEgY29udGV4dCBub2RlIGluIHRoZSBkb2N1bWVudCB0cmVlLiBPdGhlcndpc2UsIG5hbWVzcGFjZSBmdW5jdGlvbmFsaXR5IGlzIGltcGxlbWVudGVkLjwvbGk+Ci08L3VsPgotPHA+WFNMVEMgZG9lcyBub3Qgc3VwcG9ydCBhIG51bWJlciBvZiBmZWF0dXJlcyB0aGF0IGFyZSBub3QgcmVxdWlyZWQgYnkgdGhlIFhTTFQgMS4wIHNwZWNpZmljYXRpb24sCi1idXQgd2hpY2ggYXJlIHN1cHBvcnRlZCBieSBhIG51bWJlciBvZiBvdGhlciBYU0xUIHByb2Nlc3NvcnM6PC9wPgotPHVsPgotICA8bGk+SW5jb21wbGV0ZSBzdXBwb3J0IGZvciBleHRlbnNpb24gZWxlbWVudHMgYW5kIGV4dGVybmFsIEphdmEgZnVuY3Rpb25zLiBDdXJyZW50bHkgeW91IGNhbiBzZXQgdXAgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uCi0gICAgdG8gY2FsbCBhIHN0YXRpYyBKYXZhIGZ1bmN0aW9uLiBGb3IgdGhlIGV4dGVuc2lvbiBuYW1lc3BhY2UsIHVzZTxici8+Ci0gICAgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7aHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3hzbHRjL2phdmEvJmx0O2NsYXNzJmd0Ozxici8+Ci0gICAgd2hlcmUgJmx0O2NsYXNzJmd0OyBpZGVudGlmaWVzIHRoZSBjbGFzcyB3aXRoIHRoZSBzdGF0aWMgbWV0aG9kLjwvbGk+Ci0gIDxsaT5MYWNrIG9mIHN1cHBvcnQgZm9yIHRoZSByZWRpcmVjdGlvbiBvZiBvdXRwdXQgdG8gbXVsdGlwbGUKLSAgICBvdXRwdXQgZmlsZXMgZnJvbSB3aXRoaW4gYSBzdHlsZXNoZWV0IChlcXVpdmFsZW50IHRvIHhhbGFuOnJlZGlyZWN0IG9yCi0gICAgc2F4b246b3V0cHV0KS48L2xpPgotICA8bGk+WFNMVEMgZG9lcyBub3QgaW1wbGVtZW50IGEgbm9kZS1zZXQgZXh0ZW5zaW9uIHRvIGNvbnZlcnQgcmVzdWx0IHRyZWUgZnJhZ21lbnRzIHRvCi0gICAgbm9kZS1zZXRzLiBUaGlzIHdvdWxkIGVuYWJsZSBzb3J0aW5nIGFuZCBncm91cGluZyBvZiBub2RlcyBhc3NpZ25lZCB0byBhIHRyZWUgPC9saT4KLTwvdWw+Ci08L3MzPgotPGFuY2hvciBuYW1lPSJ4c2x0Y2tub3ducHJvYmxlbXMiLz4KLTxzMyB0aXRsZT0iS25vd24gUHJvYmxlbXMiPgotPHVsPgotICA8bGk+Q2FzdGluZyB2YXJpYWJsZXM6IFhTTFRDIHJlcXVpcmVzIHlvdSB0byBleHBsaWNpdGx5IHR5cGUgY2FzdCB2YWx1ZXMgCi0gIHJldHVybmVkIGJ5IHZhcmlhYmxlcyBvciBleHByZXNzaW9ucywgd2hlbiB5b3UgdXNlIHRoZW0gaW4gdGVzdHMuIEFsd2F5cyBhIGdvb2QKLSAgcHJhY3RpY2UsIGJ1dCBpdCBtYXkgc2VlbSBsaWtlIG92ZXJraWxsIGluIHNvbWUgaW4gY29udGV4dHMsIHdoZXJlIG90aGVyIFhTTFQgcHJvY2Vzc29ycwotICBhdXRvbWF0aWNhbGx5IGFzc3VtZSBvciBjb252ZXJ0IHRvIHRoZSBjb3JyZWN0IHR5cGUuIEZvciBleGFtcGxlLiB1bmxlc3MgeW91IGNhc3QgJGNvdW50cnkKLSAgdG8gYSBzdHJpbmcgaW4gdGhlIGZvbGxvd2luZyBhcHBseS10ZW1wbGF0ZXMsIGVudHJ5IG5vZGVzIHdob3NlICZsdDtjb3VudHJ5Jmd0OyBlbGVtZW50cwotICBjb250YWluIGEgc3RyaW5nIG1hdGNoaW5nIHRoZSBnbG9iYWwgJGNvdW50cnkgcGFyYW1ldGVyIGFyZSBOT1Qgc2VsZWN0ZWQuPGJyLz48YnIvPgotJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PGNvZGU+Jmx0O3hzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJlbnRyeVtjb3VudHJ5PXN0cmluZygkY291bnRyeSldIi8mZ3Q7PC9jb2RlPjwvbGk+Ci0gIDxsaT5PcmRlciBkZXBlbmRlbmN5IG9mIGNvbmRpdGlvbnMgd2l0aGluIGEgcHJlZGljYXRlOiBJZiB5b3UgaGF2ZSBhIHByZWRpY2F0ZSBpbiBhIHNlbGVjdCBvciBtYXRjaAotICBleHByZXNzaW9uIHRoYXQgaGFzIG11bHRpcGxlIGNvbmRpdGlvbnMsIG9uZSBvZiB3aGljaCBjb250YWlucyBhIHVuaW9uIChYIG9yIFkpLCBwdXQgaXQgbGFzdC4gCi0gIE90aGVyd2lzZSwgdGhlIHByZWRpY2F0ZSBmYWlscyB0byBtYXRjaCBub2RlIHRoYXQgaXQgc2hvdWxkLjwvbGk+Ci0gIDxsaT5XaGVuIHVzaW5nIERPTSBjYWNoaW5nLCBhcyBzaG93biBpbiB0aGUgU2VydmxldCBkZW1vLCBpZiB0aGUgc291cmNlIGRvY3VtZW50IGlzIGxvY2FsIHRvIHRoZSAKLSAgc2VydmVyLCB0aGUgY2FjaGUgaXMgbm90IHJlZnJlc2hlZCB3aGVuIHRoZSBzb3VyY2UgWE1MIGRvY3VtZW50IGlzIG1vZGlmaWVkLiBUaGlzIAotICBwcm9ibGVtIGRvZXMgbm90IGFwcGx5IHdoZW4gdGhlIHNvdXJjZSBpcyBhc3NvY2lhdGVkIHdpdGggYSBVUkwuPC9saT4KLSAgPGxpPklmIHlvdSBoYXZlIGEgbGlzdCBvZiByZWZlcmVuY2VzIGluY2x1ZGVkIG9yIGltcG9ydGVkIHN0eWxlc2hlZXRzLCBwdXQgYW55IHdpdGggCi0gIGEgcmVsYXRpdmUgcGF0aCBsYXN0OyBvdGhlcndpc2UsIHN0eWxlc2hlZXRzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBhcmUgbm90IGZvdW5kLjwvbGk+Ci0gIDxsaT5bMV0gc2hvdWxkIGJlIHRyZWF0ZWQgZXF1aXZhbGVudCB0byBwb3NpdGlvbigpPTEsIGJ1dCBpdCBpcyBub3QuIFRoZXJlZm9yZSwgaWYgCi0gIHlvdSBnZXQgdW5leHBlY3RlZCByZXN1bHRzIHVzaW5nIHN1Y2ggc2hvcnRjdXQgcG9zaXRpb25hbCBwcmVkaWNhdGVzLCBzdWJzdGl0dXRlIHRoZSAKLSAgZnVsbCBwb3N0aW9uKCk9IHZlcnNpb24uPC9saT4KLSAgPGxpPlhTTFRDIGZhaWxzIHRvIG1hdGNoIGV4aXN0aW5nIG5vZGVzIHdoZW4gbWF0Y2ggZXhwcmVzc2lvbnMgaGF2ZSAKLSAgbXVsdGlwbGUgc3RlcHMgd2l0aCBwcmVkaWNhdGVzIGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uIGZ1bmN0aW9uLgotICBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGFyZSB0YWtlbiBmcm9tIHRoZSBYU0xUTWFyayBvZGR0ZW1wbGF0ZXMueHNsIHRlc3Q6PGJyLz48YnIvPgotICA8Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDttYXRjaD0ndG9wLypbcG9zaXRpb24oKT0yXSc8L2NvZGU+PGJyLz4KLSAgPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7bWF0Y2g9J3RvcC8qWzZdL2tpZFsyXSc8L2NvZGU+PGJyLz4KLSAgPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7bWF0Y2g9J3RvcC8qW3Bvc2l0aW9uKCk9bGFzdCgpXSc8L2NvZGU+PGJyLz48L2xpPgotICA8bGk+WFNUTEMgaGFzIHByb2JsZW1zIHdpdGggb3V0cHV0IGVzY2FwaW5nLCBzZWUgYnVnIDE0MDMuPC9saT4KLSAgPGxpPkNhc2Utb3JkZXIgb3B0aW9uIHdpdGggc29ydGluZyBpcyBpZ25vcmVkLjwvbGk+Ci0gIDxsaT5BcyBhIG1pbm9yIHNpZGUtZWZmZWN0IG9mIGltcGxlbWVudGluZyBzaW1wbGlmaWVkIHN0eWxlc2hlZXRzLCBpZiB5b3UgaW5hZHZlcnRlbmx5IAotICBnbyB0byBjb21waWxlIGEgc3R5bGVzaGVldCBhbmQgZ2l2ZSB0aGUgbmFtZSBvZiB0aGUgLnhtbCBkb2MgaW5zdGVhZCBvZiB0aGUgLnhzbCBkb2MsCi0gIGl0IG1heSBjb21waWxlIHdpdGhvdXQgYSB3YXJuaW5nLiBJbiBzb21lIGNhc2VzLCB0aGUgY29tcGlsZXIgYWJvcnRzIHdpdGggYW4gZXJyb3IgCi0gIGFib3V0IHRvbyBtYW55IGJyYW5jaGVzLjwvbGk+Ci08L3VsPgotPC9zMz4KLTxhbmNob3IgbmFtZT0ieHNsdGNkZW1vcyIvPgotPHMzIHRpdGxlPSJSdW5uaW5nIERlbW9zIj4KLTxwPlhTTFRDIHByb3ZpZGVzIGRlbW9zIGZvciB1c2luZyBYU0xUQyBhcyBhIHNlcnZsZXQgYW5kIGFzIGEgaGFuZGxlciBmb3IgCi1CcmF6aWwgKGEgbmV3IGFuZCBwb3dlcmZ1bCBXZWIgdGVjaG9sb2d5IGZyb20gU3VuIGxhYnMpLiBUbyBydW4gdGhlc2UgZGVtb3MsCi1kb3dubG9hZCBCcmF6aWwgZnJvbSBzdW5sYWJzOjwvcD4KLTxwPjxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzxqdW1wIGhyZWY9Imh0dHA6Ly9yZXNlYXJjaC5zdW4uY29tL3Jlc2VhcmNoL2Rvd25sb2FkL2luZGV4Lmh0bWwiPmh0dHA6Ly9yZXNlYXJjaC5zdW4uY29tL3Jlc2VhcmNoL2Rvd25sb2FkL2luZGV4Lmh0bWw8L2p1bXA+PC9jb2RlPjwvcD4KLTxwPmFuZCB0aGUgamF2YSBleHRlbnNpb25zIGZvciBzZXJ2bGV0cyBmcm9tIFN1bjo8L3A+Ci08cD48Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsKLTxqdW1wIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vcHJvZHVjdHMvc2VydmxldC9kb3dubG9hZC5odG1sIj4KLWh0dHA6Ly9qYXZhLnN1bi5jb20vcHJvZHVjdHMvc2VydmxldC9kb3dubG9hZC5odG1sPC9qdW1wPgotPC9jb2RlPjwvcD4KLTxwPlRoZSB0cmFuc2xldCBtdXN0IGJlIHNwZWNpZmllZCBhcyBhIHB1cmUgY2xhc3MgbmFtZSwgYWNjZXNzaWJsZQotdGhyb3VnaCB0aGUgQnJhemlsIGhhbmRsZXIncyBjbGFzc3BhdGguIEZvciBleGFtcGxlOjwvcD4KLTxwPjxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3RyYW5zbGV0PW1rMDU0PC9jb2RlPjwvcD4KLTxwPlRoZSBkb2N1bWVudCBtdXN0IGJlIHNwZWNpZmllZCBhcyBhIHZhbGlkIFVSTC4gRm9yIGV4YW1wbGU6PC9wPgotPHA+PGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ZG9jdW1lbnQ9aHR0cDovL3NlcnZlci9wYXRoL3RvL2ZpbGVuYW1lLnhtbDwvY29kZT48L3A+Ci08cD5JZiB0aGUgZmlsZSBpcyBsb2NhbCB0byB0aGUgQnJhemlsIGhhbmRsZXIsIGl0IGhhcyB0byBiZQotc3BlY2lmaWVkIHVzaW5nIHRoZSAiZmlsZTpmaWxlbmFtZS54bWwiIGZvcm1hdC48L3A+Ci08bm90ZT5Zb3UgYWxzbyBuZWVkIHRvIG1ha2UgdGhlIEJyYXppbCBhbmQgamF2YXggY2xhc3NlcyBhdmFpbGFibGUgZnJvbSB5b3VyIGNsYXNzcGF0aDwvbm90ZT4KLTxwPlNlZSBhbHNvOiA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJ0cmFuc2xldHMiPnNhbXBsZSBKQVhQIHRyYW5zbGV0czwvbGluaz4uPC9wPgotPC9zMz4KLQotPGFuY2hvciBuYW1lPSJ4c2x0Y3RyYXgiLz4KLTxzMyB0aXRsZT0iVHJhbnNsZXRzIGFuZCBUckFYIj4KLTxwPgotVGhlIFRyYW5zbGV0IEFQSSBoYXMgYmVlbiBleHRlbmRlZCB0byBjb25mb3JtIHdpdGggdGhlIEpBWFAxLjEgVHJBWCBtb2RlbC4KLVRoaXMgcmVsZWFzZSBjb250YWlucyB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGhhdCBleHRlbnNpb24uIFR3bwotbmV3IGNsYXNzZXMgaGF2ZSBiZWVuIGFkZGVkIHRvIHRoZSBUcmFuc2xldCBYU0xUIGNvZGViYXNlLCB0aGV5IGFyZTo8L3A+Ci08cD4oMSkgPGNvZGU+b3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLlRyYW5zZm9ybWVyRmFjdG9yeUltcGw8L2NvZGU+IC08YnIvPgotJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7dGhlIFRyYW5zbGV0IGltcGxlbWVudGF0aW9uIG9mIGEgU0FYVHJhbnNmb3JtZXJGYWN0b3J5LjwvcD4KLTxwPigyKSA8Y29kZT5vcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuVHJhbnNsZXRUZW1wbGF0ZXM8L2NvZGU+IC0KLSZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3RoZSBUcmFuc2xldCBpbXBsZW1lbnRhdGlvbiBvZiBhIFRlbXBsYXRlcyBvYmplY3QuPC9wPgotPHA+Ci1UaGUgZXhpc3RpbmcgWFNMVCBjbGFzcyAnb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQnCi10aGF0IGltcGxlbWVudHMgdGhlIFRyYW5zbGV0IGludGVyZmFjZSBpcyBub3cgYWxzbyBleHRlbmRpbmcgdGhlIAotamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lciBhYnN0cmFjdCBjbGFzcy4KLTwvcD4KLTxwPgotVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBvbmx5IGEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiwgd2l0aCBtYW55IGxpbWl0YXRpb25zLgotVGhlc2UgbGltaXRhdGlvbnMgaW5jbHVkZToKLTwvcD4KLTxvbD4KLTxsaT5DdXJyZW50bHkgICdTdHJlYW1Tb3VyY2UnIGFuZCAnU3RyZWFtUmVzdWx0JyBhcmUgdGhlIG9ubHkKLSBUckFYIFNvdXJjZXMgYW5kIFJlc3VsdHMgdGhhdCBhcmUgc3VwcG9ydGVkLjwvbGk+Ci08bGk+VGhlIHRyYW5zbGV0IGlzIGNvbXBpbGVkIGV2ZXJ5dGltZSBhIGNhbGwgaXMgbWFkZSB0byB0aGU8YnIvPgotPGNvZGU+VHJhbnNmb3JtZXJGYWN0b3J5SW1wbCAnbmV3VHJhbnNmb3JtZXIoKSc8L2NvZGU+IG1ldGhvZC48L2xpPgotPGxpPlRoZSB0cmFuc2xldCBpcyBjb21waWxlZCBldmVyeXRpbWUgYSBjYWxsIGlzIG1hZGUgdG8gdGhlIDxici8+Ci08Y29kZT5UZW1wbGF0ZUZhY3RvcnlJbXBsICduZXdUcmFuc2Zvcm1lcigpJzwvY29kZT4gbWV0aG9kLjwvbGk+Ci08bGk+VHJhbnNsZXQgYXJlIGN1cnJlbnRseSBub3QgY2FjaGVkLiAoU2VlICgyKSBhbmQgKDMpKS48L2xpPgotPGxpPlNldmVyYWwgYWJzdHJhY3QgbWV0aG9kcyBmcm9tIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBzdGlsbCBuZWVkIHRvCi1iZSBpbXBsZW1lbnRlZCBpbiB0aGUgeHNsdGMucnVudGltZS5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsIGNsYXNzOjxici8+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1RlbXBsYXRlc0hhbmRsZXIgbmV3VGVtcGxhdGVzSGFuZGxlcigpPC9jb2RlPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKCk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1RyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoU291cmNlIHNyYyk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1RyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoVGVtcGxhdGVzIHRlbXBsYXRlcyk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1hNTEZpbHRlciBuZXdYTUxGaWx0ZXIoU291cmNlIHNyYyk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1hNTEZpbHRlciBuZXdYTUxGaWx0ZXIoVGVtcGxhdGVzIHRlbXBsYXRlcyk8L2NvZGU+PC9saT4KLTxsaT5TZXZlcmFsIGFic3RyYWN0IG1ldGhvZHMgZnJvbSBUcmFuc2Zvcm1lciBzdGlsbCBuZWVkIHRvIGJlIGltcGxlbWVudGVkIGluIHRoZSAKLUFic3RyYWN0VHJhbnNsZXQgY2xhc3M6PGJyLz48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7RXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3ZvaWQgc2V0RXJyb3JMaXN0ZW5lcihFcnJvckxpc3RlbmVyKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7UHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1N0cmluZyBnZXRPdXRwdXRQcm9wZXJ0eShTdHJpbmcgbmFtZSk8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO3ZvaWQgc2V0T3V0cHV0UHJvcGVydGllcyhQcm9wZXJ0aWVzIHByb3BzKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7dm9pZCBzZXRPdXRwdXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7VVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7dm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcik8L2NvZGU+PC9saT4KLTxsaT5BYnN0cmFjdCBtZXRob2QgZnJvbSBUZW1wbGF0ZXMgc3RpbGwgbmVlZCB0byBiZSBpbXBsZW1lbnRlZCBpbiB0aGUgVHJhbnNsZXRUZW1wbGF0ZXMgY2xhc3M6PGJyLz48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7UHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCk8L2NvZGU+PC9saT4KLTxsaT5TZXZlcmFsIGFic3RyYWN0IG1ldGhvZHMgZnJvbSBUcmFuc2Zvcm1lckZhY3Rvcnkgc3RpbGwgbmVlZCB0byBiZSBpbXBsZW1lbnRlZCAKLWluIHRoZSA8Y29kZT54c2x0Yy5ydW50aW1lLlRyYW5zZm9ybWVyRmFjdG9yeUltcGw8L2NvZGU+IGNsYXNzOjxici8+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO0Vycm9yTGlzdGVuZXIgZ2V0RXJyb3JMaXN0ZW5lcigpPC9jb2RlPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDt2b2lkIHNldEVycm9yTGlzdGVuZXIoRXJyb3JMaXN0ZW5lciBsaXN0ZW5lcik8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO09iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpPC9jb2RlPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDt2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Ym9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7VVJJUmVzb2x2ZXIgZ2V0VVJJUmVzb2x2ZXIoKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7dm9pZCBzZXRVUklSZXNvbHZlcihVUklSZXNvbHZlciByZXNvbHZlcik8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1NvdXJjZSBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldChTb3VyY2Ugc3JjLCBTdHJpbmcgbWVkaWEsIFN0cmluZyB0aXRsZSw8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1N0cmluZyBjaGFyc2V0KTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7VGVtcGxhdGVzIG5ld1RlbXBsYXRlcyhTb3VyY2UgeHNsU3JjKTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7VHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoKTwvY29kZT48L2xpPgotPGxpPldoZW5ldmVyIHBvc3NpYmxlLCB0aGUgcmVxdWlyZWQgbWV0aG9kcyB0aGF0IGFyZSBjdXJyZW50bHkgdW5pbXBsZW1lbnRlZCB3aWxsIHRocm93IGFuIAotZXhjZXB0aW9uIGlmIHNvbWVvbmUgdHJpZXMgdG8gY2FsbCB0aGVtLSB0aGlzIHdpbGwgYWxlcnQgdGhlIHVzZXIgdGhhdCB0aGUgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZC4gCi1UaGUgbWVzc2FnZSBpcyBvZiB0aGUgZm9ybTo8YnIvPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmcXVvdDsmbHQ7Q2xhc3MgTmFtZSZndDs6Jmx0O01ldGhvZCBOYW1lJmd0OyggJmx0O2FyZ3MmZ3Q7ICkgbm90IGltcGxlbWVudGVkIHlldC4mcXVvdDs8L2NvZGU+Ci08L2xpPgotPC9vbD4KLTwvczM+Ci08YW5jaG9yIG5hbWU9InhzbHRjaGlzdG9yeSIvPgotPHMzIHRpdGxlPSJIaXN0b3J5IG9mIFhTTFRDIHNvZnR3YXJlIGNoYW5nZXMiPgotPHA+VGhlIGZvbGxvd2luZyBzZWN0aW9ucyBsaXN0IFhTTFQgY2hhbmdlcyBiYWNrIHRvIHRoZSBpbmNvcnBvcmF0aW9uIG9mIFhTTFRDIGludG8gJnhzbHQ0YzsuPC9wPgotCi08czQgdGl0bGU9IlhTTFRDIHNvdXJjZSBjb2RlIHVwZGF0ZXMgZm9yICZ4c2x0NGo7IDIuMi5EOSI+Ci08cD5YU0xUQyBzb3VyY2UgY29kZSB1cGRhdGVzOjwvcD48dWw+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRE9NSW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+SW50ZWdyYXRlZCBmaXggZm9yIHByb2JsZW0gd2l0aCBjb3VudCgpIGZ1bmN0aW9uIGZvciBjZXJ0YWluIGl0ZXJhdG9ycy4KLSBQUjogQnVnemlsbGEgMTQwNwotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogSm9obiBIb3dhcmQgJmx0O2pvaG5oQHNjaGVtYXNvZnQuY29tJmd0OwotIFJldmlld2VkIGJ5OiBNb3J0ZW4gSm9yZ2Vuc2VuICZsdDttb3J0ZW5AeG1sLmFwYWNoZS5vcmcmZ3Q7PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMzAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0YyBET00uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgRXF1YWxpdHlFeHByLmphdmEKLSBGaWx0ZXJQYXJlbnRQYXRoLmphdmEgUGFyc2VyLmphdmEgUHJlZGljYXRlLmphdmEKLSBTdGVwLmphdmEgU3ludGF4VHJlZU5vZGUuamF2YSBWYXJpYWJsZS5qYXZhCi0gWFNMVEMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUFkYXB0ZXIuamF2YQotIERPTUltcGwuamF2YSBNdWx0aURPTS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gQWJzdHJhY3RUcmFuc2xldC5qYXZhIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmEKLSBUZXh0T3V0cHV0LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBjb2RlIHRoYXQgd2lsbCBzcGVlZCB1cCBwcmVkaWNhdGVzIHN1Y2ggYXMgLy9mb29bQGF0dHI9JHZhcl0sCi0gLy9mb29bYmFyID0gJHZhcl0gYW5kIC8vZm9vL1tAYXR0ciA9ICdzdHInXS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMzEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBFeHByZXNzaW9uLmphdmEKLSBQYXJhbS5qYXZhIFBhcmFtZXRlclJlZi5qYXZhIFByZWRpY2F0ZS5qYXZhCi0gU3R5bGVzaGVldC5qYXZhIFN5bnRheFRyZWVOb2RlLmphdmEgVmFyaWFibGUuamF2YQotIFZhcmlhYmxlUmVmLmphdmEgV2l0aFBhcmFtLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIHBhcmFtZXRlciBhbmQgdmFyaWFibGUgaGFuZGxpbmcuIFRoaXMgZml4IG1ha2VzIHN1cmUgdmFyaWFibGUgc2xvdHMKLSBhcmUgcmVsZWFzZWQgb25jZSBhIHZhcmlhYmxlIGdvZXMgb3V0IG9mIHNjb3BlLiBJIGhhdmUgYWxzbyBleHRyYWN0ZWQgY29tbW9uCi0gZnVuY3Rpb25hbGl0eSBmcm9tIFZhcmlhYmxlIGFuZCBQYXJhbSBpbnRvIFZhcmlhYmxlQmFzZSwgYW5kIHNpbWlsYXJseQotIGV4dHJhY3RlZCBzb21lIGZ1bmN0aW9uYWxpdHkgZnJvbSBWYXJpYWJsZVJlZiBhbmQgUGFyYW1ldGVyUmVmIGludG8gYSBuZXcKLSBjbGFzcyBWYXJpYWJsZVJlZkJhc2UuIFRoaXMgY2FuIHBvdGVudGlhbGx5IG1ha2Ugc29tZSBjb2RlIG1vcmUgZWZmaWNpZW50IGFzCi0gb25lIGNhbiB0ZXN0IGZvciAnaWYgKGJsb2IgaW5zdGFuY2VvZiBWYXJpYWJsZUJhc2UpJyBpbnN0ZWFkIG9mIHRlc3Rpbmcgb24KLSBib3RoIFZhcmlhYmxlIGFuZCBQYXJhbS4KLSBQUjogQnVnemlsbGEgMjY2MSBhbmQgMjY5OQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogSm9obiBIb3dhcmQgJmx0O0pvaG5IQHNjaGVtYXNvZnQuY29tJmd0OwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8zMS8yMDAxPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFZhcmlhYmxlQmFzZS5qYXZhCi0gVmFyaWFibGVSZWZCYXNlLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Gb3Jnb3QgdG8gYWRkIHRoZXNlIHR3byBpbiBteSBsYXN0IHB1dGJhY2suCi0gUFI6IG5vbmUKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8zMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFByZWRpY2F0ZS5qYXZhCi0gU3RlcC5qYXZhIFN0eWxlc2hlZXQuamF2YSBYU0xUQy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtb3ZlZCB0eXBlLWNhc3QgZXJyb3IgaW4gU3R5bGVzaGVldC5qYXZhCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzMxLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgVmFyaWFibGVCYXNlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+UmVtb3ZlZCBzb21lIG9mIHRoZSBsaW5lZmVlZHMgd2Ugb3V0cHV0IGluIHRoZSBkZWZhdWx0IFNBWCBvdXRwdXQgaGFuZGxlcgotIHRvIHByb2R1Y2Ugb3V0cHV0IG1vcmUgc2ltaWxhciB0byBTYXhvbiAoZm9yIHRlc3RpbmcgcHVycG9zZXMpLgotIEFkZGVkIGEgdGVzdCBmb3IgbnVsbC1wb2ludGVycyBpbiB0aGUgbmV3IFZhcmlhYmxlQmFzZSBjbGFzcy4KLSBQUjogYnVnemlsbGEgMjkyMiAmYW1wOyAyNTk4Ci0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnYDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzMxLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIE5vZGVDb3VudGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBhIHNtYWxsIGZpeCB0byBwcmV2ZW50IHVud2FudGVkIG91dHB1dCB3aGVuIHVzaW5nIHRoZSB4c2w6bnVtYmVyCi0gZWxlbWVudC4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDEvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBDb25zdGFudHMuamF2YQotIElmLmphdmEgS2V5LmphdmEgUHJlZGljYXRlLmphdmEgU3RlcC5qYXZhIFdoZW4uamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbAotIENvbXBhcmVHZW5lcmF0b3IuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIE5vZGVDb3VudGVyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSBmZXcgY2hhbmdlcyB0byBtYWtlIG91ciBvdXRwdXQgbG9vayBtb3JlIGxpa2UgU2F4b24ncyAodG8gc2ltcGx5ZnkKLSB0ZXN0IGRpZmZzKS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAxLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUcmFuc2Zvcm1lckltcGwuamF2YQotIERPTTJTQVguamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmFkZCBzdXBwb3J0IGZvciBET01SZXN1bHQgaGFuZGxpbmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDEvMjAwMTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IFNBWDJET00uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPndvcmsgaW4gcHJvZ3Jlc3MsIGNvbnZlcnRlZCBuZWVkZWQgZm9yIERPTVJlc3VsdDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXggVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5hZGRlZCBzZXR0aW5nIG9mIHN5c3RlbUlkIGluIERPTVNvdXJjZSBoYW5kbGluZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBTQVgyRE9NLmphdmEKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBUcmFuc2Zvcm1lckhhbmRsZXIgaW50ZXJmYWNlIG9mIFRyQVgvSkFYUC4KLSBJbXBsZW1lbnRlZCB0aGUgNCBtZXRob2RzIGluIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBpbnN0YW5jaWF0ZSB0aGlzCi0gVHJhbnNmb3JtZXJIYW5kbGVyIGltcGxlbWVudGF0aW9uLgotIEFkZGVkIGFuIGF0dHJpYnV0ZSBvZiB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IHdoaWNoIGNvbnRhaW5zIHRoZSBkZWZhdWx0Ci0gbmFtZSBmb3IgZ2VuZXJhdGVkIHRyYW5zbGV0IGNsYXNzZXMgKHRoZSBkZWZhdWx0IG5hbWUgaXMgR3JlZ29yU2Ftc2EgZnJvbQotIEthZmthJ3MgTWV0ZW1vcnBob3NpcyksIGJ1dCBzaG91bGQgYmUgc2V0IGJ5IHRoZSB1c2VyIGluIGNhc2VzIHdoZXJlIHRoZQotIFRlbXBsYXRlcyBpbXBsZW1lbnRhdGlvbiBjYW5ub3QgZ2V0IHRoZSBzeXN0ZW1JZCBmcm9tIHRoZSBTb3VyY2Ugb2JqZWN0Ljxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YQotIFRyYW5zZm9ybWVySGFuZGxlckltcGwuamF2YTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4Ci0gVGVtcGxhdGVzSGFuZGxlckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIG1pc3NpbmcgVGVtcGxhdGVzSGFuZGxlckltcGwgZmlsZSAoaW1wbGVtZW50YXRpb24gb2YgdGhlIFRyQVgKLSBUZW1wbGF0ZXNIYW5kbGVyIGludGVyZmFjZSkuCi0gQWRkZWQgaW5pdGlhbCBpbXBsZW1lbnRhdGlvbiBvZiBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldCgpIGluCi0gdGhlIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgY2xhc3MuCi0gQ2hhbmdlZCBiZWhhdmlvdXIgb2YgVHJhbnNmb3JtZXJIYW5kbGVySW1wbCBjbGFzcyB3aXRoIHJlZ2FyZCB0bwotIHRoZSBzZXRSZXN1bHQoKSBtZXRob2QuIFRoaXMgbWV0aG9kIG5vdyBoYXMgdG8gYmUgY2FsbGVkIGJlZm9yZQotIHN0YXJ0RG9jdW1lbnQoKSBpcyBjYWxsZWQsIHdoaWNoIGdpdmVzIFhTTFRDIHRoZSBzYW1lIGJlaGF2aW91cgotIGFzIFhhbGFuLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFBhcnNlci5qYXZhCi0gWFNMVEMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIHN1cHBvcnQgZm9yIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkncyBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldCgpCi0gbWV0aG9kLiBBZGRlZCBzaW1pbGFyIG1ldGhvZHMgdG8gdGhlIG5hdGl2ZSBYU0xUQyBBUEksIGFzIHRoZXkgY2FuIGNvbWUKLSBpbiBoYW5keS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBDb25zdGFudHMuamF2YQotIERvY3VtZW50Q2FsbC5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gTG9hZERvY3VtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIHRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uLiBUaGUgY29kZSBjb21waWxlZCBieSBEb2N1bWVudENhbGwgbm93Ci0gcGFzc2VzIHRoZSBjb250ZXh0IFVSSSB0byB0aGUgTG9hZERvY3VtZW50LmRvY3VtZW50KCkgbWV0aG9kLCBhbmQgdGhlCi0gZG9jdW1lbnQoKSBtZXRob2QgcmVzb2x2ZXMgdGhlIGJhc2UvbmV3IFVSSXMgYW5kIGNvbnN0cnVjdHMgYW4gYWJzb2x1dGUKLSBwYXRoL1VSSSB0byB0aGUgZG9jdW1lbnQgdG8gbG9hZC4KLSBQUjogYnVnemlsbGEgMjgzMgotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXggRE9NMlNBWC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+bmV3IHJlY3Vyc2l2ZSBwYXJzZShJbnB1dFNvdXJjZSkgaW1wbGVtZW50ZWQ8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IERPTTJTQVguamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPnVwYXRlZDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXggRE9NMlNBWC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+dXBkYXRlZCBhZ2Fpbjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBTQVgyRE9NLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggdG8gZ2V0IGFyb3VuZCBwcm9ibGVtIHdpdGggQ3JpbXNvbi4gQ3JpbXNvbiBkb2VzIG5vdCBsaWtlIGF0dHJpYnV0ZS0KLSBub2RlcyB0byBiZSBjcmVhdGVkIHdpdGggJ251bGwnIG9yICIiIG5hbWVzcGFjZSBVUkkuIEFkZGVkIGFuIGlmLXRlc3QgdG8KLSBpbnZva2Ugc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKSBpbnN0ZWFkIG9mIHNldEF0dHJpYnV0ZU5TKHVyaSwgbmFtZSwgdmFsdWUpLgotIEhhZCB0byBhZGQgYSBsaXR0bGUgdGVzdCB0byBET01JbXBsJERPTUJ1aWxkZXIubWFrZUF0dHJpYnV0ZU5vZGUoKSB0byBnZXQKLSBhcm91bmQgYW4gaW50ZXJuYWwgTlBFIHByb2JsZW0uCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4uYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzAzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgQ29weU9mLmphdmEKLSBTdGVwLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBET01JbXBsLmphdmEKLSBVbmlvbkl0ZXJhdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIHVuaW9uLWl0ZXJhdG9ycyB3cmFwcGluZyBvbmUgb3IgbW9yZSBhdHRyaWJ1dGUtaXRlcmF0b3JzLgotIEF0dHJpYnV0ZXMgc2hvdWxkIGJlIHdyYXBwZWQgaW4gVHlwZWRBdHRyaWJ1dGVJdGVyYXRvciBvYmplY3RzIGFuZCBub3QKLSBTaW5nbGV0b25JdGVyYXRvciBvYmplY3RzIHdoZW4gdGhleSBvY2N1ciBpbnN1ZGUgdW5pb25zLgotIEZpeCBmb3IgY29weWluZyBhdHRyaWJ1dGUgbm9kZXMgdXNpbmcgJmx0O3hzbDpjb3B5Jmd0OyBhbmQgJmx0O3hzbDpjb3B5LW9mJmd0OwotIFBSOiBidWd6aWxsYSAyNjAzCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gTG9hZERvY3VtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBjb2RlIGJlaGluZCB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbiB0byBmb3JjZSB0aGUgcGFyc2VyIHRvIGJlCi0gbmFtZXNwYWNlIGF3YXJlIChDcmltc29uIGlzIHByLiBkZWZhdWx0LCBYZXJjZXMgaXMgbm90KS4KLSBQUjogYnVnemlsbGEgMjg2MgotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZSBUZXh0T3V0cHV0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggdG8gcHJldmVudCBlc2NhcGluZyBvZiBhdHRyaWJ1dGUgdmFsdWVzIGluIEhUTUwgb3V0cHV0LgotIFBSOiBidWd6aWxsYSAzMDAzCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIFRleHRPdXRwdXQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgZ3JvdXBpbmcgYSBzZXF1ZW5jZSBvZiB0ZXh0IG5vZGVzIGluc2lkZSBvbmUgQ0RBVEEgc2VjdGlvbi4KLSBQUjogYnVnemlsbGEgMzAwNQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgRm9yRWFjaC5qYXZhCi0geHBhdGguY3VwCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gQWJzdHJhY3RUcmFuc2xldC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBwYXNzaW5nIG5vZGUtc2V0cyBhcyBwYXJhbWV0ZXJzIGludG8gYSB0ZW1wbGF0ZSB3aXRoIGEgZm9yLWVhY2ggbG9vcC4KLSBUaGUgRm9yRWFjaCBjbGFzcyByZXNldHMgaXRzIG5vZGUgaXRlcmF0b3IgYnkgZGVmYXVsdC4gVGhpcyBiZWhhdmlvdXIgaXMgbm90Ci0gZGVzaWVyZCBmb3IgaXRlcmF0b3JzIHRoYXQgYXJlIHBhc3NlZCBpbiB0aHJvdWdoIGEgcGFyYW1ldGVyLCBzbyBJIGFkZGVkIGFuCi0gaXQtdGVzdCB0aGF0IGNoZWNrcyBpZiB0aGUgaXRlcmF0b3IgaXMgb2YgdHlwZSAnUmVmZXJlbmNlJy4KLSBQUjogYnVnemlsbGEgMjQ2OAotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIKLSBBYnNvbHV0ZVBhdGhQYXR0ZXJuLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIGEgY2VydGFpbiBjb21iaW5hdGlvbiBvZiBhYnNvbHV0ZSBwYXRoIHBhdHRlcm5zIGFuZCBhbmNlc3RvciBwYXR0ZXJucywKLSBzdWNoIGFzICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9Ii9mb28vLyoiLyZndDsuCi0gUFI6IGJ1Z3ppbGxhIDI4MzYKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wOC8wNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIERvY3VtZW50Q2FsbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBkb2N1bWVudCgpIGZ1bmN0aW9uLiBQcmV2ZW50cyBydW4tdGltZSBlcnJvci4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBYc2xFbGVtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBhIHRlc3QgdG8gdGhlICZsdDt4c2w6ZWxlbWVudCZndDsgZWxlbWVudCB0byB2ZXJpZnkgdGhhdCB0aGUgZWxlbWVudCBuYW1lCi0gZ2l2ZW4gaW4gdGhlICduYW1lJyBhdHRyaWJ1dGUgY29udGFpbnMgc29tZXRoaW5nIG90aGVyIHRoYW4gYW4gZW1wdHkgc3RyaW5nLgotIFBSOiBidWd6aWxsYSAyNzk0Ci0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgTGl0ZXJhbEVsZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFwcGxpZWQgYSBmaXggdG8gb3VyIGNsYXNzIGZvciBoYW5kbGluZyBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cy4gVGhlIG9ubHkKLSBhdHRyaWJ1dGVzIGluIHRoZSBYU0xUIG5hbWVzcGFjZSB3ZSBoYW5kbGUgaW4gTFJFcyBhcmUgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMKLSBhbmQgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMuIFdlIGhhdmUgYSB0ZXN0IHRvIGNoZWNrIGlmIGFuIGF0dHJpYnV0ZSBpcwotIGluIHRoZSBYU0xUIG5hbWVzcGFjZSwgYW5kIGlmIGl0IGlzIHdlIGlnbm9yZSB0aGUgYXR0cmlidXRlLiBUaGlzIHRlc3Qgd2FzCi0gcGxhY2VkIGJlZm9yZSB0aGUgdGVzdCBmb3IgdGhlIHR3byBYU0xUIGF0dHJpYnV0ZXMgd2UgZG8gd2FudCB0byBoYW5kbGUsCi0gY2F1c2luZyB1cyB0byBpZ25vcmUgYWxsIHhzbDpleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBhdHRyaWJ1dGVzIGluIExSRXMuCi0gUFI6IGJ1Z3ppbGxhIDE1MDYKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDgvMDgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBBdHRyaWJ1dGUuamF2YQotIEF0dHJpYnV0ZVNldC5qYXZhIENvcHkuamF2YSBVc2VBdHRyaWJ1dGVTZXRzLmphdmEKLSBYc2xBdHRyaWJ1dGUuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBhbmQgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQgZm9yIGF0dHJpYnV0ZSBzZXRzLgotIFBSOiBidWd6aWxsYSAyNTM2Ci0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA4LzA4LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgQ29weS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciB1c2Ugb2YgYXR0cmlidXRlIHNldHMgd2l0aCB0aGUgeHNsOmNvcHkgZWxlbWVudC4gV2Ugd2VyZSBhIGJpdCB0b28KLSByZXN0cmljdGl2ZSBpbiBvdXIgdGVzdHMgdG8gc2VlIGlmIGl0IHdhcyBzYWZlIHRvIHNlbmQgdGhlIGF0dHJpYnV0ZXMgdG8KLSB0aGUgb3V0cHV0IGhhbmRsZXIuIFdlIG9ubHkgY29tcGlsZWQgaW4gYSB0ZXN0IHRvIHNlZSBpZiB0aGUgY29waWVkIG5vZGUKLSB3YXMgYW4gZWxtZW50LCBidXQgc2hvdWxkIGFsc28gaGF2ZSB0ZXN0ZWQgaWYgdGhlIHhzbDpjb3B5IGVsZW1lbnQncwotIHBhcmVudCBub2RlIHdhcyBhIExSRSBvciBhIHhzbDplbGVtZW50IGVsZW1lbnQuCi0gUFI6IGJ1Z3ppbGxhIDI1MzgKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkBhcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PC91bD4KLTwvczQ+Ci08czQgdGl0bGU9IlhTTFRDIHNvdXJjZSBjb2RlIHVwZGF0ZXMgZm9yICZ4c2x0NGo7IDIuMi5EOCI+Ci08cD5YU0xUQyBzb3VyY2UgY29kZSB1cGRhdGVzOjwvcD48dWw+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIHN1cHBvcnQgZm9yIFNBWFNvdXJjZSBhbmQgU0FYUmVzdWx0IGluIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwKLSBhbmQgVHJhbnNmb3JtZXJGYWN0b3J5LiBJIGhhZCB0byBhZGQgYSBuZXcgY29uc3R1cmN0b3IgdGhlIHRoZQotIGRlZmF1bHQgU0FYIG91dHB1dCBoYW5kbGVyIChpbiB0aGUgeHNsdGMgcnVudGltZSBsaWJyYXJ5KSB0byBhY29tbW9kYXRlCi0gdGhlIFNBWFJlc3VsdCBUckFYIG91dHB1dCBoYW5kbGVyLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFhTTFRDLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBkZWZhdWx0IGVycm9yLXJlcG9ydGluZyBiZWhhdmlvdXIgZm9yIG91ciB0cmF4IGNvZGUgKGVycm9yIG1lc3NhZ2VzCi0gYXJlIGR1bXBlZCB0byBTeXN0ZW0uZXJyKS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmluIHByb2dyZXNzLCBhZGRpbmcgRE9NU291cmNlIHN1cHBvcnQ8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjAvMjAwMTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IERPTTJTQVguamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPm5ldyBjbGFzcywgRE9NMlNBWCwgc3VwcG9ydHMgRE9NU291cmNlcywgaW4gcHJvZ3Jlc3M8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIEltcG9ydC5qYXZhCi0gSW5jbHVkZS5qYXZhIFN0eWxlc2hlZXQuamF2YSBYU0xUQy5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4Ci0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhIFRyYW5zZm9ybWVySW1wbC5qYXZhPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFNvdXJjZUxvYWRlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgYSBTb3VyY2VMb2FkZXIgaW50ZXJmYWNlIHRvIHRoZSBjb21waWxlciBwYWNrYWdlLiBUaGlzIGludGVyZmFjZSBjYW4KLSBiZSB1c2VkIHRvIHBsdWcgaW4gYW4gZXh0ZXJuYWwgZG9jdW1lbnQgbG9hZGVyIGZvciBpbXBvcnRlZCBhbmQvb3IKLSBpbmNsdWRlZCBzdHlsZXNoZWV0cy4gVGhlIHRyYXguVHJhbnNmb3JtZXJJbXBsIGNsYXNzIGlzIHVwZGF0ZWQgdG8KLSBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgYW5kIGFjdCBhcyBhbiBhZGFwdGVyIGJldHdlZW4gdGhlIGludGVybmFsIFhTTFRDCi0gU291cmNlTG9hZGVyIGludGVyZmFjZSBhbmQgVHJBWCdzIFVSSVJlc29sdmVyIGludGVyZmFjZS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5hbWlyb0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjAvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIENvbnN0YW50cy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgdGhlIE5BTUVTUEFDRV9GRUFUVVJFIGNvbnN0YW50LiBDaGVja2VkIHRvIHNlZSBpZiBpdCB3YXMgaW4KLSBvcmcueG1sLnNheCBmaXJzdCwgYnV0IGl0IHdhc24ndC4gU2luY2UgdGhpcyBjb25zdGFudCBpcyB1c2VkIGJvdGgKLSBhdCBjb21waWxlIGFuZCBydW50aW1lLCBpdCBzaG91bGQgYmUgaW4gdGhlIHJ1bnRpbWUgQ29uc3RhbnRzIGNsYXNzCi0gYXMgd2VsbCBhcyB0aGUgY29tcGlsZSBDb25zdGFudHMgY2xhc3MuIFJ1bnRpbWUgY29kZSBuZWVkcyB0byBiZQotIGtlcHQgc2VwYXJhdGUgZnJvbSB0aGUgY29tcGlsZSB0aW1lIGNvZGUuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmFtaXJvQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgRGVmYXVsdFJ1bi5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lIFRyYW5zZm9ybS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRG9jdW1lbnRDYWNoZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgaW1wb3J0IGZvciBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQ29uc3RhbnRzOwotIHRvIHRoZSBydW50aW1lIGNsYXNzZXMgdGhhdCBuZWVkIHRvIHVzZSB0aGUgTkFNRVNQQUNFX0ZFQVRVUkUgY29uc3RhbnQKLSBhbmQgaGFkIHRoZW0gcmVmZXJlbmNlIGl0IHJhdGhlciB0aGFuIGRlZmluZSBpdCB0aGVtc2VsdmVzLjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFhTTFRDLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5taW5vciBjaGFuZ2VzIGZvciBET01Tb3VyY2UgaW1wbCBzdXBwb3J0PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIERPTVNvdXJjZSBzdXBwb3J0IGZvciBzdHlsZXNoZWV0PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIwLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBET00yU0FYLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj51cGRhdGVkIGNvbnZlcnRvciB3aGljaCBzdXBwb3J0cyBET01Tb3VyY2UgaW1wbDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzIzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgWFNMVEMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIGEgc21hbGwgZml4IHRvIHRoZSBjb21waWxlciAoWFNMVEMuamF2YSkgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIFNBWAotIHBhcnNlciByZWZlcmVuY2Ugd2FzIG5vdCByZXNldCBwcmlvciB0byBjb21waWxpbmcgdGhlIHRyYW5zbGV0LgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8yMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBzdXBwb3J0IGZvciBET01Tb3VyY2UgYXMgaW5wdXQgdG8gb3VyIFRyYW5zZm9ybWVyIGltcGxlbWVudGF0aW9uPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBJbXBvcnQuamF2YQotIFNvcnQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIE5vZGVTb3J0UmVjb3JkLmphdmEKLSBOb2RlU29ydFJlY29yZEZhY3RvcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZvciBzb21lIHJlYXNvbiBJIGRlY2lkZWQgdG8gb3B0aW1pc2UgdGhlICZsdDt4c2w6c29ydCZndDsgZnVuY3Rpb25haWxpdHkuIFRoZQotIHNvcnQgcmVjb3JkcyB3ZSB1c2VkIGhhcyBzb21lIGdsb2JhbCB2YWx1ZXMgc3RvcmVkIGJlaGluZCBtZXRob2RzLCBidXQgYXJlCi0gbm93IHN0YXRpYyBmaWVsZHMuIFNvbWV3aGF0IGZhc3Rlci4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMjMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBJbXBvcnQuamF2YQotIEluY2x1ZGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgcHJvYmxlbSB3aXRoIGltcG9ydCAmYW1wOyBpbmNsdWRlIGludHJvZHVjZWQgd2l0aCB0aGUgbGF0ZXN0IHVwZGF0ZWQKLSBmb3IgVHJBWCBVUklSZXNvbHZlcnMuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkludGVncmF0ZWQgZml4IGZvciBwcm9ibGVtIHdpdGggY291bnQoKSBmdW5jdGlvbiBmb3IgY2VydGFpbiBpdGVyYXRvcnMuCi0gUFI6IEJ1Z3ppbGxhIDE0MDcKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IEpvaG4gSG93YXJkICZsdDtqb2huaEBzY2hlbWFzb2Z0LmNvbSZndDsKLSBSZXZpZXdlZCBieTogTW9ydGVuIEpvcmdlbnNlbiAmbHQ7bW9ydGVuQHhtbC5hcGFjaGUub3JnJmd0Ozxici8+PGJyLz48L2xpPjwvdWw+Ci08L3M0PgotPHM0IHRpdGxlPSJYU0xUQyBzb3VyY2UgY29kZSB1cGRhdGVzIGZvciAmeHNsdDRqOyAyLjIuRDciPgotPHVsPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzA5LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgQ29uc3RhbnRzLmphdmEKLSBQYXJhbS5qYXZhIFN0ZXBQYXR0ZXJuLmphdmEgU3R5bGVzaGVldC5qYXZhCi0gU3ludGF4VHJlZU5vZGUuamF2YSBWYXJpYWJsZS5qYXZhIFdpdGhQYXJhbS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gS2V5SW5kZXguamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YSBCYXNpc0xpYnJhcnkuamF2YQotIERlZmF1bHRSdW4uamF2YSBQYXJhbWV0ZXIuamF2YSBUZXh0T3V0cHV0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Mb2FkcyBvZiBzbWFsbCBmaXhlcyBhbmQgYSBnb29kIGZldyBjb21tZW50cyBhZGRlZCB0byB0aGUgc291cmNlIGNvZGUuCi0gVGhlIG1ham9yIGZpeGVzIGFyZSBvbmUgZml4IGZvciB2YXJpYWJsZS9wYXJhbWV0ZXIgaGFuZGxpbmdpIGFuZCBvbmUgZm9yCi0ga2V5L2lkIGluZGV4IGhhbmRsaW5nLiBYU0xUQyBub3cgY29ycmVjdGx5IHVwZGF0ZXMgdGhlIHZhbHVlIG9mIHBhcmFtZXRlcnMKLSB3aXRoIGNoYW5naW5nIGRlZmF1bHQgdmFsdWVzLCBzdWNoIGFzIHdpdGgKLSAmbHQ7eHNsOnBhcmFtIG5hbWU9ImZvbyIgc2VsZWN0PSJjdXJyZW50KCkiLyZndDsuCi0gQWxzbyB1cGRhdGVkIGJpdC1hcnJheXMgdG8gY29ycmVjdGx5IHJldHVybiBzaW5nbGUgbm9kZSBpZHMsIHNvIHRoYXQgdGhlCi0ga2V5KCkgYW5kIGlkKCkgZnVuY3Rpb25zIHJldHVybiB0aGUgY29ycmVjdCBudW1iZXIgb2Ygbm9kZXMgKHRoZXkgd291bGQKLSBzb21ldGltZXMgc2tpcCB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgZGVmaW5lZCBub2RlIHNldCBmb3IgdGhlIGtleS9pZCkuCi0gQWRkZWQgc29tZSBzdHJ1Y3R1cmUgYW5kIGxvYWRzIG9mIGNvbW1lbnRzIHRvIHRoZSBUcmFuc2xldCBiYXNlIGNsYXNzLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyCi0gQW5jZXN0b3JQYXR0ZXJuLmphdmEgQXR0cmlidXRlU2V0LmphdmEKLSBDYWxsVGVtcGxhdGUuamF2YSBDYXN0RXhwci5qYXZhIEVxdWFsaXR5RXhwci5qYXZhCi0gRXhwcmVzc2lvbi5qYXZhIEZ1bmN0aW9uQ2FsbC5qYXZhIElmLmphdmEKLSBJbXBvcnQuamF2YSBJbmNsdWRlLmphdmEgTW9kZS5qYXZhIE5hbWVCYXNlLmphdmEKLSBQYXJhbS5qYXZhIFBhcmFtZXRlclJlZi5qYXZhIFBhcnNlci5qYXZhCi0gU3RlcFBhdHRlcm4uamF2YSBTeW50YXhUcmVlTm9kZS5qYXZhIFRlbXBsYXRlLmphdmEKLSBUZXN0U2VxLmphdmEgVmFyaWFibGUuamF2YSBWYXJpYWJsZVJlZi5qYXZhCi0gWFNMVEMuamF2YSBYc2xBdHRyaWJ1dGUuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbCBFcnJvck1zZy5qYXZhCi0gUmVmZXJlbmNlVHlwZS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gTXVsdGlET00uamF2YQotIFN0ZXBJdGVyYXRvci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIEJhc2lzTGlicmFyeS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSB3aWRlIHJhbmdlIG9mIGZpeGVzIHByb3ZpZGVkIGJ5IEVyd2luIEJvbHdpZHQuCi0gbykgZml4IGZvciBsb25nIElGIGFuZCBHT1RPIGluc3RydWN0aW9ucyBpbnNpZGUgdHJhbnNsZXRzLgotICd3aWRlJyBHT1RPcyBhcmUgbm93IHVzZWQgKEdPVE9fVykgaW5zdGVhZCBvZiBwbGFpbiBHT1RPCi0gdG8gYWxsb3cgbG9uZ2VyIGp1bXAgb2Zmc2V0cwotIG8pIGZpeCBmb3IgaWxsZWdhbCBmaWVsZC9tZXRob2QgbmFtZXMgaW4gdGhlIHRyYW5zbGV0LgotIE1ldGhvZHMgYW5kIGZpZWxkcyBubyBsb25nZXIgY29udGFpbiB0aGUgJy4nIG9yICctJyBjaGFyYWN0ZXJzCi0gbykgc291cmNlIGZpbGVuYW1lcyAoYW5kIGlmIHBvc3NpYmxlIGFsc28gbGluZSBudW1iZXJzKSBhcmUgbm93Ci0gcHJvdmlkZWQgd2l0aCBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcwotIG8pIGV4dGVybmFsIGZ1bmN0aW9ucyB0aGF0IGFyZSBub3Qgc3VwcG9ydGVkIGJ5IFhTTFRDIGRvIG5vdCBjYXVzZQotIGNvbXBpbGUgZXJyb3JzLiBUaGV5IHdpbGwgc3RpbGwgY2F1c2UgYSB3YXJuaW5nIG1lc3NhZ2UgYXQKLSBjb21waWxlLXRpbWUgaWYgdGhleSBhcmUgbm90IHdyYXBwZWQgaW4gcHJvcGVyICZsdDt4c2w6aWYmZ3Q7IG9yCi0gJmx0O3hzbDp3aGVuJmd0OyBlbGVtZW50cyB0aGF0IHRlc3Qgb24gdGhlIGF2YWlsYWJpbGl0eSBvZiB0aGUgZnVuY3Rpb24sCi0gYW5kIHdpbGwgY2F1c2UgYSBydW50aW1lIGVycm9yIGlmIHRoZSBmdW5jdGlvbiBpcyBhdHRlbXB0ZWQgY2FsbGVkLgotIG8pIGFkZGVkIHR5cGUgY2FzdCBmcm9tIHJlZmVyZW5jZS10eXBlIHRvIG5vZGUtdHlwZQotIG8pIHNvbWUgb3RoZXIgc21hbGxlciBmaXhlcyB0byBwcmV2ZW50IG51bGwtcG9pbnRlciBleGNlcHRpb25zCi0gT3RoZXIgY2hhbmdlczoKLSBvKSBjb2RlIGNsZWFudXAgYW5kIHNvbWUgYWRkZWQgY29tbWVudHMKLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBFcndpbiBCb2x3aWR0ICZsdDtlamJAa2xvbXAub3JnJmd0OwotIFJldmlld2VkIGJ5OiBNb3J0ZW4gSm9yZ2Vuc2VuICZsdDttb3J0ZW5AeG1sLmFwYWNoZS5vcmcmZ3Q7PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBQYXJzZXIuamF2YQotIFN5bnRheFRyZWVOb2RlLmphdmEgWFNMVEMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkNsZWFuZWQgdXAgdGhlIFhTTFRDIGNvbXBpbGVyIGNsYXNzIGluIGFuIGF0dGVtcHQgdG8gbWFrZSBpdCBtb3JlIGZsZXhpYmxlLgotIFRoaXMgY2xhc3Mgd2FzIG9yaWdpbmFsbHkgd3JpdHRlbiBhcyBhIGNvbW1hbmQtbGluZSBpbnRlcmZhY2UsIGJ1dCBpdCBoYXMKLSBub3cgZ3Jvd24gaHVnZSBhbmQgbWVzc3kuIEkgc2VwYXJhdGVkIHRoZSBjb21tYW5kLWxpbmUgc3R1ZmYgZnJvbSB0aGUKLSBtZXRob2RzIHRoYXQgbWFrZSB1cCB0aGUgYWN0dWFsIGZ1bmN0aW9uYWxpdHkgYW5kIG1hZGUgc29tZSBtZXRob2RzIHB1YmxpYy4KLSBUaGlzIGlzIHBhcnQgb2YgdGhlIHByZXBhcmF0aW9uIGZvciBvdXIgbmV3IGltcGxlbWVudGF0aW9uIG9mIHRoZSBKQVhQCi0gVGVtcGxhdGVzIG9iamVjdC4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi5hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIERlZmF1bHRSdW4uamF2YTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lIENvbXBpbGUuamF2YQotIFRyYW5zZm9ybS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+RXh0cmFjdGVkIHRoZSBjb21tYW5kLWxpbmUgc3R1ZmYgZnJvbSB0aGUgY29yZSBYU0xUQyBwYWNrYWdlcy4gVGhlIGNvbW1hbmQtCi0gbGluZSBoYW5kbGluZyBpcyBub3cgaW4geGFsYW4ueHNsdGMuY21kbGluZS5Db21waWxlIGFuZAotIHhhbGFuLnhzbHRjLmNtZGxpbmUuVHJhbnNmb3JtLiBUaGUgY29tbWFuZC1saW5lIHN0dWZmIGlzIHN0aWxsIGxlZnQgaW4KLSB4YWxhbi54c2x0Yy5jb21waWxlci5YU0xUQyBhbmQgeGFsYW4ueHNsdGMucnVudGltZS5EZWZhdWx0UnVuIGZvciBiYWNrd2FyZHMKLSBjb21wYXRhYmlsaXR5LiBUaGlzIHNob3VsZCBiZSByZW1vdmVkIHNob3J0bHkuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY21kbGluZSBDb21waWxlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFhTTFRDLmphdmE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY21kbGluZS9nZXRvcHQgR2V0T3B0LmphdmEKLSBHZXRPcHRzRXhjZXB0aW9uLmphdmEgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmphdmEKLSBNaXNzaW5nT3B0QXJnRXhjZXB0aW9uLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXggVGVtcGxhdGVzSW1wbC5qYXZhCi0gVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+UmVtb3ZlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy91dGlsL2dldG9wdCBHZXRPcHQuamF2YQotIEdldE9wdHNFeGNlcHRpb24uamF2YSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uamF2YQotIE1pc3NpbmdPcHRBcmdFeGNlcHRpb24uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1vdmVkIHRoZSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWwuZ2V0b3B0IHBhY2thZ2UgdG8KLSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNtZGxpbmUuZ2V0b3B0LiBBbHNvIGFkZGVkIHNvbWUgc2tlbGV0b24KLSBjb2RlIGluIGEgbmV3IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheCBkaXJlY3RvcnkuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUcmFuc2xldFRlbXBsYXRlcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+bWlub3IgYWRqdXN0bWVudAotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5yZW1vdmVkIG9ic2VsZXRlIHRyeS9jYXRjaDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgWFNMVEMuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUZW1wbGF0ZXNJbXBsLmphdmEKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+UmVtb3ZlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IFRyYW5zbGV0VGVtcGxhdGVzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BIGZpcnN0IHN0YWIgYXQgb3VyIG5ldyBUckFYIGRlc2lnbi5gCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBYU0xUQy5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IFRlbXBsYXRlc0ltcGwuamF2YQotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YSBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkEgZmV3IG1pbm9yIGFkanVzdG1lbnRzIHRvIHllc3RlcmRheXMgSkFYUC9UckFYIGltcGxlbWVudGF0aW9uLiBUaGVzZSBpcyBvbmUKLSBjaGFuZ2UgaW4gdGhlIHdheSB0aGUgY29tcGlsZXIgKFhTTFRDKSBnZW5lcmF0ZXMgYnl0ZWNvZGUgYXJyYXlzLCBhbmQgdGhlCi0gcmVzdCBpcyBiYXNpY2FsbHkgYSBjbGVhbnVwIG9mIGVycm9yIHJlcG9ydGluZyBhbmQgYSBmZXcgYWRkZWQgY29tbWVudHMuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERvY3VtZW50Q2FjaGUuamF2YTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy90cmF4IE91dHB1dFNldHRpbmdzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZWR1Y2VkIHRoZSByZWZyZXNoIHJhdGUgb2YgdGhlIERvY3VtZW50Q2FjaGUgdG8gMSBzZWNvbmQuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5hbWlyb0BhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDcvMTcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRG9jdW1lbnRDYWNoZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+U3VibWl0dGVkIGJ5OiBUb20gQW1pcm8KLSBGaXhlcyBidWcgMTU5MS4gQ2hhbmdlZCB0aGUgbGFzdE1vZGlmaWVkKCkgbWV0aG9kIHRvIHJldHVybgotIHRoZSBjb3JyZWN0IHRpbWVzdGFtcCBmb3IgbG9jYWwgZmlsZXMgYmVnaW5uaWcgd2l0aCB0aGUgImZpbGU6IgotIHByb3RvY29sLiBJbmNvcnBvcmF0ZWQgQnJpYW4gRXdpbidzIHN1Z2dlc3Rpb24gdG8gdXNlIFVSTGRlY29kZS4KLSBUb2RkIE1pbGxlciBhbmQgTW9ydGVuIEpvcmdlbnNlbjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUZW1wbGF0ZXNJbXBsLmphdmEKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEgVHJhbnNmb3JtZXJJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRlZCBzb21lIGphdmFkb2MgY29tbWVudHMgdG8gb3VyIHRyYXggc3R1ZmYuIEFkZGVkIHByZWxpbWluYXJ5IHN1cHBvcnQKLSBmb3IgZ2V0dGluZy9zZXR0aW5nIG91dHB1dCBwcm9wZXJ0aWVzLCBhbmQgZm9yIGdldHRpbmcvc2V0dGluZyBVUkwgcmVzb2x2ZXJzLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjIFRyYW5zbGV0T3V0cHV0SGFuZGxlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jbWRsaW5lIFRyYW5zZm9ybS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBPdXRwdXQuamF2YQotIFN0eWxlc2hlZXQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YSBEZWZhdWx0UnVuLmphdmEKLSBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlci5qYXZhIFNBWEFkYXB0ZXIuamF2YQotIFN0cmluZ1ZhbHVlSGFuZGxlci5qYXZhIFRleHRPdXRwdXQuamF2YQotIFRyYW5zbGV0T3V0cHV0QmFzZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSBzZXJpZXMgb2YgY2hhbmdlcyB0byB0aGUgWFNMVEMgb3V0cHV0IGhhbmRsaW5nIHRvIGFjY29tb2RhdGUgdGhlCi0gc2V0L2dldE91dHB1dFNldHRpbmdzKCkgbWV0aG9kcyBpbiB0aGUgVHJBWCBBUEkuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE5LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZSBUZXh0T3V0cHV0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXhlZCB0aGUgaGFuZGxpbmcgb2YgdGhlICdjZGF0YS1zZWN0aW9uLWVsZW1lbnRzJyBhdHRyaWJ1dGUgb2YgdGhlCi0gJmx0O3hzbDpvdXRwdXQmZ3Q7IGVsZW1lbnQuIFByZXZpb3VzbHkgd2Ugb3V0cHV0IHRoZSB3aG9sZSBlbGVtZW50LCBpbmNsdWRpbmcKLSBhbGwgY29udGVudHMsIGNoaWxkIGVsZW1lbnRzIGFuZCB0aGUgc3RhcnQtIGFuZCBlbmQtdGFncyBpbiBvbmUgYmlnCi0gQ0RBVEEgc2VjdGlvbi4gV2Ugbm93IGNvcnJlY3RseSBvdXRwdXQgb25seSBpbW1lZGlhdGUgdGV4dCBjaGlsZC1ub2RlcwotIGFzIENEQVRBIHNlY3Rpb25zLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNy8xOS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjIFRyYW5zbGV0LmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBMb2FkRG9jdW1lbnQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIEFic3RyYWN0VHJhbnNsZXQuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUcmFuc2Zvcm1lckltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIGltcGxlbWVudGF0aW9uIG9mIGdldC9zZXRPdXRwdXRQcm9wZXJ0aWVzKCkgb2YgdGhlIFRyYW5zZm9ybWVyCi0gaW1wbGVtZW50YXRpb24uCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA3LzE5LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERvY3VtZW50Q2FjaGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIChhIHJhdGhlciBicnV0YWwpIGhhbmRsaW5nIG9mIGFsbCBFeGNlcHRpb25zIHRocm93biBpbiB0aGUKLSBEb2N1bWVudENhY2hlLmdldExhc3RNb2RpZmllZCgpIG1ldGhvZC4gVGhpcyBjbGFzcyBpcyBwcm92aWRlZCBvbmx5Ci0gYXMgYW4gZXhhbXBsZS9za2VsZXRvbiwgYnV0IHNob3VsZCBzdGlsbCAtIGZvciB2YXJpb3VzIHJlYXNvbnMgLQotIGJlIHByb3ZpZGVkIGluIHRoZSBiYXNlICd4c2x0Yy5kb20nIHBhY2thZ2UuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjwvdWw+Ci08L3M0PgotPHM0IHRpdGxlPSJYU0xUQyBzb3VyY2UgY29kZSB1cGRhdGVzIGZvciB0aGUgJnhzbHQ0ajsgMi4yLkQgcmVsZWFzZXMgdXAgdG8gYW5kIGluY2x1ZGluZyAyLjIuRDYiPgotPHVsPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNS8yMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFRleHQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmJ1ZyBmaXggMTQwMywgb3V0cHV0IGVzY2FwaW5nIGZpeGVkPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA1LzIzLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZSBUZXh0T3V0cHV0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5idWcgZml4IDE0MDMsIG91dHB1dCBlc2NhcGluZyBmaXhlZDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8wNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFBhcnNlci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+c3R5bGVzaGVldCBjb21waWxhdGlvbiBlcnJvciBsaXN0ZW5pbmcgYWRkZWQgZm9yCi0gVHJBWCBzdXBwb3J0PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzA1LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgWFNMVEMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPnN0eWxlc2hlZXQgY29tcGlsYXRpb24gZXJyb3IgbGlzdGVuaW5nIGFkZGVkIGZvcgotIFRyQVggc3VwcG9ydDxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8wNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5zdHlsZXNoZWV0IGNvbXBpbGF0aW9uIGVycm9yIGxpc3RlbmluZyBhZGRlZCBmb3IKLSBUckFYIHN1cHBvcnQ8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMDUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VHJhbnNmb3JtZXIgZmFjdG9yeSdzIHNldEVycm9yTGlzdGVuZXIoKSBub3cgdGhyb3dzCi0gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIGxpc3RlbmVyIGlzIG51bGw8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMDUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+dHJhbnNsZXQgdHJhbnNmb3JtYXRpb24gZXJyb3JzIG5vdyBmb3J3YXJkZWQgdG8KLSBUckFYIGVycm9yIGxpc3RlbmVyIHdoZW4gYXBwbGljYWJsZTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8wNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBBYnN0cmFjdFRyYW5zbGV0LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj50cmFuc2xldCB0cmFuc2Zvcm1hdGlvbiBlcnJvcnMgbm93IGZvcndhcmRlZCB0bwotIFRyQVggZXJyb3IgbGlzdGVuZXIgd2hlbiBhcHBsaWNhYmxlPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIEF0dHJpYnV0ZUxpc3QuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIGEgY29uc3RydWN0b3IgZm9yIGNvcHlpbmcgYW4gb3JnLnhtbC5zYXguQXR0cmlidXRlcyB0byBvdXIKLSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQXR0cmlidXRlTGlzdC4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBBcHBseUltcG9ydHMuamF2YQotIEFwcGx5VGVtcGxhdGVzLmphdmEgQXR0cmlidXRlLmphdmEKLSBBdHRyaWJ1dGVTZXQuamF2YSBBdHRyaWJ1dGVWYWx1ZVRlbXBsYXRlLmphdmEKLSBCaW5PcEV4cHIuamF2YSBDYWxsVGVtcGxhdGUuamF2YSBDb21tZW50LmphdmEKLSBDb25jYXRDYWxsLmphdmEgQ29uc3RhbnRzLmphdmEgQ29weS5qYXZhCi0gQ29weU9mLmphdmEgRGVjaW1hbEZvcm1hdHRpbmcuamF2YQotIERvY3VtZW50Q2FsbC5qYXZhIEV4cHJlc3Npb24uamF2YSBGYWxsYmFjay5qYXZhCi0gRm9yRWFjaC5qYXZhIEZvcm1hdE51bWJlckNhbGwuamF2YQotIEZ1bmN0aW9uQXZhaWxhYmxlQ2FsbC5qYXZhIEZ1bmN0aW9uQ2FsbC5qYXZhCi0gSWYuamF2YSBJbXBvcnQuamF2YSBJbmNsdWRlLmphdmEgS2V5LmphdmEKLSBMaXRlcmFsQXR0cmlidXRlLmphdmEgTGl0ZXJhbEVsZW1lbnQuamF2YQotIExpdGVyYWxFeHByLmphdmEgTG9naWNhbEV4cHIuamF2YSBNZXNzYWdlLmphdmEKLSBOYW1lc3BhY2VBbGlhcy5qYXZhIE51bWJlci5qYXZhIE91dHB1dC5qYXZhCi0gUGFyYW0uamF2YSBQYXJzZXIuamF2YSBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24uamF2YQotIFFOYW1lLmphdmEgUmVsYXRpb25hbEV4cHIuamF2YSBTb3J0LmphdmEKLSBTdHlsZXNoZWV0LmphdmEgU3ltYm9sVGFibGUuamF2YQotIFN5bnRheFRyZWVOb2RlLmphdmEgVGVtcGxhdGUuamF2YSBUZXh0LmphdmEKLSBUcmFuc2xldE91dHB1dC5qYXZhIFVuYXJ5T3BFeHByLmphdmEgVmFsdWVPZi5qYXZhCi0gVmFyaWFibGUuamF2YSBXaGVuLmphdmEgV2hpdGVzcGFjZS5qYXZhCi0gV2l0aFBhcmFtLmphdmEgWFNMVEMuamF2YSBYc2xBdHRyaWJ1dGUuamF2YQotIFhzbEVsZW1lbnQuamF2YSB4cGF0aC5jdXAKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBNZXRob2RUeXBlLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZW1vdmVkIHRoZSBpbnRlcm1lZGlhdGUgRE9NIHVzZWQgdG8gY29udGFpbiB0aGUgaW5wdXQgZG9jdW1lbnQgKHRoZQotIHN0eWxlc2hlZXQpIGZvciB0aGUgY29tcGlsZXIuIFRoZSBjb21waWxlciBub3cgdXNlcyBTQVgyIHRvIGltcG9ydAotIHRoZSBzdHlsZXNoZWV0LCBhbmQgYWxsIHJlZmVyZW5jZXMgdG8gRE9NIGludGVyZmFjZXMgaGF2ZSBiZWVuIHJlbW92ZWQuCi0gVGhpcyBtZWFucyB0aGF0IG1vc3QgY2xhc3NlcyByZXByZXNlbnRpbmcgWFNMIGVsZW1lbnRzIGhhdmUgYmVlbgotIGNoYW5nZWQsIGJ1dCBtb3N0IGNsYXNzZXMgcmVwcmVzZW50aW5nIFhQYXRoIGZ1bmN0aW9ucywgZXhwcmVzc2lvbnMKLSBhbmQgcGF0dGVybnMgYXJlIHVuY2hhbmdlZC4KLSBQUjogQWZ0ZXIgc3VnZ2VzdGlvbiBmcm9tIFNjb3R0IEJvYWcKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8wNi8yMDAxPGJyLz48cmVmPkFkZGVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyCi0gVW5zdXBwb3J0ZWRFbGVtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5BZGRpbmcgYSBjbGFzcyBmb3IgaGFuZGxpbmcgdW5zdXBwb3J0ZWQgc3R5bGVzaGVldCBlbGVtZW50cwotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPk1pbm9yIGZpeCB0byBtYWtlIHN1cmUgdGhhdCBhdHRyaWJ1dGVzIGFyZSBwcm9jZXNzZWQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4uYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5NaW5vciBjaGFuZ2UgaW4gb3V0cHV0IGluZGVudGF0aW9uL2xpbmUgZmVlZHMuCi0gUFI6IG4vYQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bXAuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIKLSBMb2NhdGlvblBhdGhQYXR0ZXJuLmphdmEgUGFyc2VyLmphdmEgVGVtcGxhdGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeGVkIHRoZSBjb2RlIHRoYXQgcmVzb2x2ZXMgY29uZmxpY3RzIGJldHdlZW4gdGVtcGxhdGVzIHdpdGggaWRlbnRpY2FsCi0gcGF0dGVybnMuIFRoZSBvcmRlciBvZiB0aGUgdGVtcGxhdGVzIGlzIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgLSBhZnRlcgotIGltcG9ydCBwcmVjZWRlbmNlIGFuZCBwcmlvcml0eSBoYXMgYmVlbiBjaGVja2VkLgotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzA2LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZQotIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5SZXZlcnRlZCBjaGFuZ2VzIHRvIFNBWCBvdXRwdXQgaGFuZGxlci4KLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMDYvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBQYXJzZXIuamF2YQotIFRlbXBsYXRlLmphdmEgeHBhdGguY3VwPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+dW5pZmllZCBQYXJzZXIgZXJyb3IgcmVwb3J0aW5nIHRvIHVzZSBNb3J0ZW5zCi0gcmVwb3J0RXJyb3Igcm91dGluZTxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzA3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgQmluT3BFeHByLmphdmEKLSBGdW5jdGlvbkNhbGwuamF2YSBPdGhlcndpc2UuamF2YSBQYXJhbS5qYXZhCi0gUmVsYXRpb25hbEV4cHIuamF2YSBTdHlsZXNoZWV0LmphdmEKLSBTeW50YXhUcmVlTm9kZS5qYXZhIFZhcmlhYmxlLmphdmEgV2hlbi5qYXZhCi0gWFNMVEMuamF2YSBYc2xFbGVtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5VcGRhdGVkIGEgZmV3IGNsYXNzZXMgdGhhdCB3ZXJlIHN0aWxsIGNhbGxpbmcgUGFyc2VyLmFkZEVycm9yKCksCi0gUGFyc2VyLmFkZFdhcm5pbmcoKSBhbmQgUGFyc2VyLmFkZEZhdGFsRXJyb3IoKSB0byB1c2UgdGhlIG5ldyBjb21tb24KLSBlcnJvciBoYW5kbGVyIFByYXJzZXIucmVwb3J0RXJyb3IoaW50IGNhdGVnb3J5LCBFcnJvck1zZyBtZXNzYWdlKS4KLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8wOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFBhcnNlci5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIERlZmF1bHRSdW4uamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIHR3byBsaW5lcyBvZiBjb2RlIHRvIGV4cGxpY2l0bHkgc2V0IHRoZSBmZWF0dXJlCi0gImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy9uYW1lc3BhY2VzIiBvZiB0aGUgU0FYUGFyc2VyIHRvICJ0cnVlIi4KLSBUaGUgZGVmYXVsdCBpcyAidHJ1ZSIgYnV0IHhlcmNlcyBzZWVtcyB0byBzZXQgaXQgdG8gImZhbHNlIiwgYW5kIHRoaXMKLSBjYXVzZWQgc29tZSBwcm9ibGVtcyBmb3Igb3VyIFN0eWxlc2hlZXQgYW5kIFhNTCBkb2MgcGFyc2VycyAod2hpY2ggYXJlCi0gYm90aCB1c2luZyBTQVgyKS4KLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8wOC8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIENvbnN0YW50cy5qYXZhCi0gUGFyc2VyLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgRGVmYXVsdFJ1bi5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QSBmZXcgbW9yZSBjaGFuZ2VzIHRvIG1ha2Ugc3VyZSB0aGUgcGFyc2VycyB1c2VkIGFyZSBuYW1lc3BhY2UgYXdhcmUuCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMDgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBMaXRlcmFsRWxlbWVudC5qYXZhCi0gU3ludGF4VHJlZU5vZGUuamF2YSBYc2xBdHRyaWJ1dGUuamF2YQotIFhzbEVsZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlRoZSBjaGFuZ2UgZnJvbSB1c2luZyBET00gdG8gdXNpbmcgU0FYIGluIHRoZSBzdHlsZXNoZWV0IGlucHV0IGNhdXNlZCBzb21lCi0gb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBBYnN0cmFjdCBTeW50YXggVHJlZSAoQVNUKSB0byBiZSBvdXQgb2Ygb3JkZXIuIEkKLSBhZGRlZCBhIGZldyBsaW5lcyBvZiBjb2RlIHRvIHRoZSB4c2w6ZWxlbWVudC9hdHRyaWJ1dGUgaGFuZGxpbmcgY29kZSB0bwotIGZpeCB0aGlzLgotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzExLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgQXR0cmlidXRlU2V0LmphdmEKLSBDaG9vc2UuamF2YSBDb25zdGFudHMuamF2YSBJZi5qYXZhCi0gTGl0ZXJhbEVsZW1lbnQuamF2YSBTdHlsZXNoZWV0LmphdmEKLSBVc2VBdHRyaWJ1dGVTZXRzLmphdmEgV2hlbi5qYXZhIFhTTFRDLmphdmEKLSBYc2xBdHRyaWJ1dGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlRoaXMgcHV0YmFjayBjb250YWlucyB0aHJlZSBmaXhlczoKLSBvKSBmaXggZm9yIGNvbXBsZXggJmx0O3hzbDphdHRyaWJ1dGUtc2V0Jmd0OyBpbmhlcml0YW5jZSBzdHJ1Y3R1cmVzCi0gbykgZml4IGZvciB4c2w6ZWxlbWVudC1hdmFpbGFibGUoKSBmdW5jdGlvbiB1c2VkIGluICZsdDt4c2w6d2hlbiZndDsgb3IKLSAmbHQ7eHNsOmlmJmd0OyB0byB0ZXN0IHN1cHBvcnQgZm9yIHZhcmlvdXMgZXh0ZW5zaW9uIGVsZW1lbnRzCi0gbykgZml4IGZvciBwcmVzZXJ2aW5nIG5hbWVzcGFjZSBwcmVmaXhlcyBmb3IgJmx0O3hzbDphdHRyaWJ1dGUmZ3Q7IG91dHB1dC4KLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIENvbnN0YW50cy5qYXZhCi0gVXNlQXR0cmlidXRlU2V0cy5qYXZhIFZhbHVlT2YuamF2YQotIFhzbEF0dHJpYnV0ZS5qYXZhCi0gamF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsCi0gQXR0cmlidXRlU2V0TWV0aG9kR2VuZXJhdG9yLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggdG8gYWxsb3cgaXRlcmF0b3IgYWNjZXNzIHdpdGhpbiBhdHRyaWJ1dGUgc2V0cy4gVGhpcyBpcyBuZWNlc3NhcnkgZm9yCi0gYXR0cmlidXRlIHNldHMgdGhhdCBjb250YWluIGF0dHJpYnV0ZXMgd2hvc2UgdmFsdWVzIGFyZSBnZW5lcmF0ZWQgYnkgWFNMCi0gZnVuY3Rpb25zIHN1Y2ggYXMgcG9zaXRpb24oKSBhbmQgbGFzdCgpLgotIE9idGFpbmVkIGZyb206IHRlc3QgbWswMTMKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgVGV4dE91dHB1dC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+QWRkZWQgb3V0cHV0IGNoYXJhY3RlciBlc2NhcGluZyBmb3Igbm9uLWJyZWFraW5nIHNwYWNlIGNoYXJhY3RlcnMuCi0gSSBjYW5ub3QgYmVsaWV2ZSB3ZSd2ZSB3YWl0ZWQgdGhpcyBsb25nIGJlZm9yZSBkb2luZyB0aGlzLiBNYWRuZXNzIQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFhTTFRDLmphdmEKLSBQYXJzZXIuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPnN1cHBvcnQgZm9yIGphdmEuaW8uSW5wdXRTdHJlYW0gU3RyZWFtU291cmNlczxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xMS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBUcmFuc2xldFRlbXBsYXRlcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+c3VwcG9ydCBmb3IgamF2YS5pby5JbnB1dFN0cmVhbSBTdHJlYW1Tb3VyY2VzPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBMb2dpY2FsRXhwci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBidWcgMTUxMS4gUHJlZGljYXRlcyBvbiB0aGUgZm9ybWF0ICgoYSBvciBiKSBhbmQgYykgYXJlIG5vdAotIGhhbmRsZWQgY29ycmVjdGx5LiBJIGFkZGVkIGEgc21hbGwgcGllY2Ugb2YgY29kZSB0byBkaXJlY3QgdGhlIHRydWUtbGlzdAotIG9mIHRoZSBPUiBleHByZXNzaW9uIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIEFORCB0ZXN0LgotIFBSOiBCdWd6aWxsYSAxNTExCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lIEJhc2lzTGlicmFyeS5qYXZhCi0gVGV4dE91dHB1dC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGF0dHJpYnV0ZSBub2RlLXNldCBjb21wYXJpc29ucy4gVGhlcmUgd2FzIGEgYnVnIGluIG9uZSBvZiB0aGUgY29tcGFyZSgpCi0gbWV0aG9kcyBvZiB0aGUgQmFzaXNMaWJyYXJ5IGNsYXNzIHdoaWNoIHByZXZlbnRlZCBhdHRyaWJ1dGUgdmFsdWVzIGZyb20KLSBiZWluZyBjb21wYXJlZC4gVGhlIG1ldGhvZCBjb21wYXJlZCBub2RlIElEcyBpbnN0ZWFkIG9mIG5vZGUgdmFsdWVzLgotIFByZXR0eSBzdHVwaWQgYnVnLCBidXQgbm93IGl0IGlzIHNvbHZlZCBhbnl3YXkuCi0gUFI6IEJ1Z3ppbGxhIDE0MDkKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xMi8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIE1vZGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgaW1wbGljaXQgInRleHQoKSIgcGF0dGVybiBpcyBydW4gd2hlbiB0ZW1wbGF0ZXMKLSBjb250YWluaW5nICJ0ZXh0KCkiIGluIHRoZWlyIHBhdHRlcm4gZmFpbC4gWFNMVEMgd291bGQgbm90IHByZXZpb3VzbHkKLSBpbnZva2UgdGhlIGJ1aWx0LWluIHBhdHRlcm4gZm9yICJ0ZXh0KCkiIGlmIGEgc3R5bGVzaGVldCBjb250YWluZWQgYQotIHRlbXBsYXRlIHN1Y2ggYXMgJmx0O3hzbDp0ZW1wbGF0ZSBwYXR0ZXJuPSJmb28vYmFyL3RleHQoKSIgLi4uLyZndDsKLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBYc2xFbGVtZW50LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5Nb2RpZmllZCB0ZXN0IGZvciBsZWdhbCBlbGVtZW50IG5hbWVzIGluICZsdDt4c2w6ZWxlbWVudCZndDsuIFRoZSBlbGVtZW50IG5hbWUgaXMKLSB0cmVhdGVkIGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZS4gV2hpdGVzcGFjZXMgYXJlIG5vdCBhbGxvd2VkIGluIHBsYWluIHRleHQKLSBlbGVtZW50IG5hbWVzLCBidXQgc2hvdWxkIGJlIGFsbG93ZWQgaW5zaWRlICJ7Li4ufSIgYXR0cmlidXRlIHZhbHVlcy4KLSBQUjogQnVnemlsbGEgMTQ4OQotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvZG9tIERPTUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkEgZml4IGZvciB0aGUgcHJlY2VkaW5nOjogaXRlcmF0b3IKLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9kb20gRE9NSW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+TWlub3IgcmUtYWRqdXN0bWVudCB0byBsYXN0IGZpeCBmb3IgcHJlY2VkaW5nOjogaXRlcmF0b3IKLSBQUjogMTQwNwotIE9idGFpbmVkIGZyb206IG4vYQotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzEyLzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgRm9yRWFjaC5qYXZhCi0gWFNMVEMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCB0byBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmdzIHRvIGJlIG91dHB1dCBtb3JlIHRoYW4gb25jZS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBBdHRyaWJ1dGVTZXQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpbmFsIGZpeCAoZm9yIG5vdykgZm9yIGF0dHJpYnV0ZSBzZXRzLiBJbiBjYXNlcyB3aGVyZSBtdWx0aXBsZQotICZsdDt4c2w6YXR0cmlidXRlLXNldC4uLi8mZ3Q7IGVsZW1lbnRzIG1ha2UgdXAgb25lIGF0dHJpYnV0ZSBzZXQgKGllLiB0aGV5IHNoYXJlCi0gdGhlIHNhbWUgbmFtZSkgYXR0cmlidXRlcyB0aGF0IG9jY3VyZWQgbGFzdCBpbiB0aGUgc3R5bGVzaGVldCB3aWxsIHRha2UKLSBwcmVjZWRlbmNlLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTIvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YWRkZWQgc3VwcG9ydCBmb3IgamF2YS5pby5JbnB1dFN0cmVhbSBTdHJlYW1Tb3VyY2VzPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTMvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBMb2dpY2FsRXhwci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBjb2RlIGhhbmRsaW5nIGxvZ2ljYWwgZXhwcmVzc2lvbnMgYW5kIGNvbWJpbmF0aW9ucyBvZiBsb2dpY2FsCi0gZXhwcmVzc2lvbnMuIE1pbmRibG93aW5nIHN0dWZmLCBidXQgaXQgbm93IHNlZW1zIHRvIHdvcmsgYXMgaXQgc2hvdWxkLgotIEFkZGVkIGFub3RoZXIgZmV3IGxpbmVzIG9mIGNvZGUgdG8gcHJvcGVybHkgZGlyZWN0IHRoZSBwcm9ncmFtIGZsb3cgaW4KLSBjb21waWxlZCBwcmVkaWNhdGVzIHdpdGggdmFyaW91cyBjb21iaW5hdGlvbnMgb2YgImFuZCIgYW5kICJvciIgZXhwcmVzc2lvbnMuCi0gUFI6IEJ1Z3ppbGxhIDE1MTEKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xMy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBTaW5nbGV0b25JdGVyYXRvci5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Rml4IGZvciBzaW5nbGV0b24gaXRlcmF0b3JzIGVuY2Fwc3VsYXRpbmcgdmFyaWFibGUgcmVmZXJlbmNlcy4KLSBQUjogQnVnemlsbGEgMTQxMgotIFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0gUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzE0LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIgTGl0ZXJhbEVsZW1lbnQuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIG9uZS1saW5lIGZpeCB0byBwcmV2ZW50IG51bGwtcG9pbnRlciBlcnJvci4gU2ltcGxlIGNvZGUgY2xlYW51cC4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogc3VnZ2VzdGlvbiBieSBHdW9saWFuZyBDYW8gJmx0O2Nhb0Bpc3Bzb2Z0LmNvbSZndDsKLSBTdWJtaXR0ZWQgYnk6IGNhb0Bpc3Bzb2Z0LmNvbQotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8xNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIExvZ2ljYWxFeHByLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggdG8gcHJldmVudCBjb21waWxlLXRpbWUgbnVsbC1wb2ludGVyIGV4Y2VwdGlvbnMgZm9yIGNlcnRhaW4gbG9naWNhbAotIGV4cHJlc3Npb25zLiBTb21lIG5leHRlZCBBTkQtZXhwcmVzc2lvbnMgd291bGQgY2F1c2UgdGhpcyBlcnJvciBiZWNhdXNlCi0gdGhlaXIgdHJ1ZS1saXN0IHdvdWxkIG5vdCBiZSBiYWNrcGF0Y2hlZC4gVGhpcyB3b3VsZCByZXN1bHQgaW4gYW4KLSBpbnN0cnVjdGlvbiBsaXN0IHdpdGggb25lIG9yIG1vcmUgYnJhbmNoIGluc3RydWN0aW9ucyB3aXRoIG5vIHRhcmdldCwKLSBzdWNoIGFzIGEgR09UTyhudWxsKSBvciBhbiBJRkVRKG51bGwpIGluc3RydWN0aW9uLgotIFBSOiBub25lLCBidWcgZm91bmQgaW4gdGVzdCBydW4gYW5kIGZpeGVkIGltbWVkaWF0ZWx5Ci0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPmN1cmN1cnVAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzE3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIKLSBBYnNvbHV0ZUxvY2F0aW9uUGF0aC5qYXZhIEFwcGx5SW1wb3J0cy5qYXZhCi0gQXBwbHlUZW1wbGF0ZXMuamF2YSBDYXN0RXhwci5qYXZhIENvcHlPZi5qYXZhCi0gRG9jdW1lbnRDYWxsLmphdmEgRXF1YWxpdHlFeHByLmphdmEgRXhwcmVzc2lvbi5qYXZhCi0gRmlsdGVyRXhwci5qYXZhIEZpbHRlclBhcmVudFBhdGguamF2YSBGb3JFYWNoLmphdmEKLSBGdW5jdGlvbkNhbGwuamF2YSBJZEtleVBhdHRlcm4uamF2YSBLZXkuamF2YQotIEtleUNhbGwuamF2YSBOYW1lQmFzZS5qYXZhIFBhcmVudExvY2F0aW9uUGF0aC5qYXZhCi0gUGFyc2VyLmphdmEgUHJlZGljYXRlLmphdmEgUmVsYXRpb25hbEV4cHIuamF2YQotIFN0ZXAuamF2YSBVbmlvblBhdGhFeHByLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBOb2RlU2V0VHlwZS5qYXZhIE5vZGVUeXBlLmphdmEgUmVmZXJlbmNlVHlwZS5qYXZhCi0gUmVzdWx0VHJlZVR5cGUuamF2YSBUeXBlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2RvbSBVbmlvbkl0ZXJhdG9yLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgQmFzaXNMaWJyYXJ5LmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5PSywgSSdtIGdvaW5nIHRvIG1ha2UgYSB3aWxkIGd1ZXNzIGFuZCBhc3N1bWUgdGhhdCBzYm9hZydzIHJlY2VudCBjb21taXQKLSBvZiAvTm9kZVNldC9Ob2RlU2V0RFRNLyBnb3QgYSBsaXR0bGUgb3V0IG9mIGNvbnRyb2wgYW5kIHNob3VsZG4ndCBoYXZlCi0gZ29uZSBkb3duIGludG8gb3JnLmFwYWNoZS54YWxhbi54c2x0YyAtIHVuZG9uZSB0byBmaXggY29tcGlsZSBlcnJvcjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj5tb3J0ZW5AYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzE4LzIwMDE8YnIvPjxyZWY+UmVtb3ZlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsCi0gTm9kZVNldFR5cGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlJlbW92aW5nIE5vZGVTZXRUeXBlIChyZW5hbWVkIHRvIE5vZGVTZXREVE1UeXBlKS4KLSBQUjogbi9hCi0gT2J0YWluZWQgZnJvbTogbi9hCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsIFR5cGUuamF2YTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsCi0gTm9kZVNldERUTVR5cGUuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPgotPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsIFR5cGUuamF2YTxici8+PHJlZj5BZGRlZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlci91dGlsCi0gTm9kZVNldFR5cGUuamF2YTxici8+PHJlZj5SZW1vdmVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBOb2RlU2V0RFRNVHlwZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+Ci0KLQotPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMTkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBDb250YWluc0NhbGwuamF2YQotIEZ1bmN0aW9uQ2FsbC5qYXZhIElmLmphdmEgTG9naWNhbEV4cHIuamF2YQotIFBhcmFtLmphdmEgUU5hbWUuamF2YSBTdGFydHNXaXRoQ2FsbC5qYXZhCi0gU3ltYm9sVGFibGUuamF2YSBTeW50YXhUcmVlTm9kZS5qYXZhIFRlbXBsYXRlLmphdmEKLSBWYXJpYWJsZS5qYXZhIHhwYXRoLmN1cAotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZSBCYXNpc0xpYnJhcnkuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkZpeCBmb3IgZnVuY3Rpb24gY2FsbHMgdXNlZCBhcyBjbGF1c2VzIGluIGxvZ2ljYWwgZXhwcmVzc2lvbnMuCi0gU3VibWl0dGVkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmcKLSBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPlRvbS5BbWlyb0BTdW4uQ09NPHJlZj4gb24gPC9yZWY+MDYvMTkvMjAwMTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPgotJmd0OyBGaXggZm9yIGZ1bmN0aW9uIGNhbGxzIHVzZWQgYXMgY2xhdXNlcyBpbiBsb2dpY2FsIGV4cHJlc3Npb25zLgotJmd0OyBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotJmd0OyBSZXZpZXdlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0mZ3Q7Ci0mZ3Q7PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPk1vcnRlbi5Kb3JnZW5zZW5Ac3VuLmNvbTxyZWY+IG9uIDwvcmVmPjA2LzE5LzIwMDE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj4KLSZndDsgJmd0OyBGaXggZm9yIGZ1bmN0aW9uIGNhbGxzIHVzZWQgYXMgY2xhdXNlcyBpbiBsb2dpY2FsIGV4cHJlc3Npb25zLgotJmd0OyAmZ3Q7IFN1Ym1pdHRlZCBieTogbW9ydGVuQHhtbC5hcGFjaGUub3JnCi0mZ3Q7ICZndDsgUmV2aWV3ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotJmd0OyAmZ3Q7Ci0mZ3Q7ICZndDs8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YWRkZWQgY2hlY2sgdG8gc2VlIGlmIHN0eWxlc2hlZXQgaXMgYWxyZWFkeSBhbiBVUkw8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjUvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gVHJhbnNsZXRUZW1wbGF0ZXMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmFkZGVkIGNoZWNrIHRvIHNlZSBpZiBzdHlsZXNoZWV0IGlzIGFscmVhZHkgYW4gVVJMPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzI1LzIwMDE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvcnVudGltZSBUckFYRmlsdGVyLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5wcm90bzxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8yNS8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5yZW1vdmVkIGRlYnVnIHN0YXRlbWVudHM8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjYvMjAwMTxici8+PHJlZj5SZW1vdmVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3J1bnRpbWUgVHJBWEZpbHRlci5qYXZhCi0gVHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhIFRyYW5zbGV0VGVtcGxhdGVzLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5pbiBwcm9jZXNzIG9mIG1vdmluZyB0aGVzZSB0byBuZXcgc3ViZGlyPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzI2LzIwMDE8YnIvPjxyZWY+QWRkZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUckFYRmlsdGVyLmphdmEKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEgVHJhbnNsZXRUZW1wbGF0ZXMuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPm1vdmVkIGZyb20gcnVudGltZSBzdWJkaXIgdG8gaXRzIG93biB0cmF4IHN1YmRpcjxici8+PGJyLz48L2xpPjxsaT48cmVmPkNvbW1pdHRlZCBieSA8L3JlZj50bWlsbGVyQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL3RyYXgKLSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5maXhlZCBidWcgd2l0aCBkZXJpdmluZyB0cmFuc2xldCBuYW1lIGZyb20KLSBzdHlsZXNoZWV0IG5hbWUgdGhhdCBpbmNsdWRlZCBwYXRocywgZS5nLiAvdG1wL2Zvby54c2w8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+bW9ydGVuQGFwYWNoZS5vcmc8cmVmPiBvbiA8L3JlZj4wNi8yNy8yMDAxPGJyLz48cmVmPk1vZGlmaWVkOiA8L3JlZj5qYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyIFByZWRpY2F0ZS5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+VGhpcyB1cGRhdGUgYWxsb3dzIHZhcmlhYmxlcyB0aGF0IGNvbnRhaW4gcmVmZXJlbmNlcyB0byByZXN1bHQtdHJlZSBmcmFnbWVudHMKLSB0byBiZSB1c2VkIGluc2lkZSBwb3NpdGlvbiBmaWx0ZXJzLgotIFBSOiBuL2EKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9ydW50aW1lCi0gQWJzdHJhY3RUcmFuc2xldC5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YWRkZWQgdXJsIGhhbmRsaW5nIGluIGRvVHJhbnNmb3JtPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheAotIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPmFkZGVkIGEgbmV3IHN5cyBwcm9wZXJ0eSBjYWxsZWQgJ3RyYW5zbGV0UG9vbCcKLSB0byBhbGxvdyB1c2VyIHRvIHNldCB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5IGZvciBnZW5lcmF0ZWQgdHJhbnNsZXRzPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPnRtaWxsZXJAYXBhY2hlLm9yZzxyZWY+IG9uIDwvcmVmPjA2LzI3LzIwMDE8YnIvPjxyZWY+TW9kaWZpZWQ6IDwvcmVmPmphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvdHJheCBUcmFuc2xldFRlbXBsYXRlcy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+YWRkZWQgYSBuZXcgc3lzIHByb3BlcnR5IGNhbGxlZCAndHJhbnNsZXRQb29sJwotIHRvIGFsbG93IHVzZXIgdG8gc2V0IHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZm9yIGdlbmVyYXRlZCB0cmFuc2xldHM8YnIvPjxici8+PC9saT48bGk+PHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+dG1pbGxlckBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjcvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBYU0xUQy5qYXZhPGJyLz48cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+bWFkZSBwcml2YXRlIG1ldGhvZCBzZXREZXN0RGlyZWN0b3J5KCkgcHVibGljIHRvCi0gc3VwcG9ydCB0aGUgbmV3IHRyYW5zbGV0UG9vbCBzeXN0ZW0gcHJvcGVydHkuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjgvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBQcmVkaWNhdGUuamF2YQotIFN0ZXAuamF2YSBTdHlsZXNoZWV0LmphdmEgVmFyaWFibGVSZWYuamF2YQotIGphdmEvc3JjL29yZy9hcGFjaGUveGFsYW4veHNsdGMvY29tcGlsZXIvdXRpbAotIE1ldGhvZEdlbmVyYXRvci5qYXZhIE5vZGVTb3J0UmVjb3JkR2VuZXJhdG9yLmphdmEKLSBSZXN1bHRUcmVlVHlwZS5qYXZhIFRlc3RHZW5lcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPlZhcmlvdXMgYnVnZml4ZXMgaW4gdGhlIHdheSBhdXhpbGlhcnkgY2xhc3NlcyBhY2Nlc3MgdmFyaWFibGVzL2ZpZWxkcyBpbgotIHRoZSBtYWluIHRyYW5zbGV0IGNsYXNzLiBGaXhlcyBhIGZldyBWQVIgdGVzdHMgYW5kIGN1c3RvbWVyIHRlc3RzLgotIFBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc6PGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBDaG9vc2UuamF2YQotIEVsZW1lbnRBdmFpbGFibGVDYWxsLmphdmEKLSBGdW5jdGlvbkF2YWlsYWJsZUNhbGwuamF2YSBQYXJzZXIuamF2YSBXaGVuLmphdmE8YnIvPjxyZWY+Q29tbWl0dGVyJ3MgbG9nIGVudHJ5OiA8L3JlZj5GaXggZm9yIGVsZW1lbnQtYXZhaWxhYmxlKCkgYW5kIGZ1bmN0aW9uLWF2YWlsYWJsZSgpIGNhbGxzLiBUaWVzIHRoZXNlCi0gY2FsbHMgdG8gdGFibGVzIGluIHRoZSBYU0wgcGFyc2VyIGFuZCB0aGUgc3ltYm9sLXRhYmxlICh0aGUgYWN0dWFsCi0gaW1wbGVtZW50YXRpb24pIGluc3RlYWQgb2YgdXNpbmcgcmVkdW5kYW50IGFuZCBub3QtdXAtdG8tZGF0ZSB0YWJsZXMKLSBpbiB0aGUgY2xhc3NlcyB0aGF0IGltcGxlbWVudCB0aGUgWC1hdmFpYWJsZSgpIGNhbGxzLgotIEkgYWxzbyBjbGVhbmVkIHVwIHRoZSBDaG9vc2UgY2FsbCBzbyB0aGF0IGl0IG5vdyBwcm9wZXJseSBoYW5kbGVzCi0gYWxsIHR5cGVzIG9mIGZ1bmN0aW9uIGNhbGxzIGluIHRoZSB4c2w6d2hlbiBlbGVtZW50cycgdGVzdCBjbGF1c2UuPGJyLz48YnIvPjwvbGk+PGxpPjxyZWY+Q29tbWl0dGVkIGJ5IDwvcmVmPm1vcnRlbkBhcGFjaGUub3JnPHJlZj4gb24gPC9yZWY+MDYvMjkvMjAwMTxici8+PHJlZj5Nb2RpZmllZDogPC9yZWY+amF2YS9zcmMvb3JnL2FwYWNoZS94YWxhbi94c2x0Yy9jb21waWxlciBGb3JFYWNoLmphdmEKLSBQYXJhbS5qYXZhIFZhcmlhYmxlLmphdmEKLSBqYXZhL3NyYy9vcmcvYXBhY2hlL3hhbGFuL3hzbHRjL2NvbXBpbGVyL3V0aWwKLSBNZXRob2RHZW5lcmF0b3IuamF2YTxici8+PHJlZj5Db21taXR0ZXIncyBsb2cgZW50cnk6IDwvcmVmPkFkZGVkIGEgZml4IGZvciBsb2NhbCB2YXJpYWJsZXMgaW5zaWRlIG5lc3RlZCB4c2w6Zm9yLWVhY2ggZWxlbWVudHMuCi0gTG9jYWwgdmFyaWFibGVzIGFyZSB1c3VhbGx5IG5vdCBpbml0aWFsaXplZCB0byBhbnkgZGVmYXVsdCB2YWx1ZSAoc3VjaCBhcwotIHdpdGggZ2VuZXJhbCBKYXZhIGNsYXNzZXMpLCBiZWNhdXNlIGNvZGUgY29tcGlsZWQgZm9yICZsdDt4c2w6dmFyaWFibGUmZ3Q7Ci0gZWxlbWVudHMgYWx3YXlzIGFzc2lnbiB2YWx1ZXMgdG8gdmFyaWFibGUgc2xvdHMgYmVmb3JlIHRoZXkgYXJlIGFjY2Vzc2VkLgotIEJ1dCB0aGUgY29kZSBzdHJ1Y3R1cmUgZ2VuZXJhdGVkIGJ5IG5lc3RlZCAmbHQ7eHNsOmZvci1lYWNoJmd0OyBlbGVtZW50cyBpcyB0b28KLSBtdWNoIGZvciB0aGUgSlZNcyB2ZXJpZmllciB0byBnZXQgYXJvdW5kLCBzbyB3ZSBoYXZlIHRvIGluaXRpYWxpemUgYWxsCi0gbG9jYWwgdmFyaWFibGVzIGluc2lkZSBzdWNoIGxvb3BzIHRvIHplcm8sIGZhbHNlLCBudWxsLCB3aGF0ZXZlci4KLSBUaGlzIHRha2VzIGNhcmUgc29tZSBvZiBvdXIgcnVudGltZS1lcnJvcnMgY2F1c2VkIGJ5IGFwcGFyZW50IGNvcnJ1cHQgY29kZS4KLSAoVGhlIEpWTXMgdmVyaWZpZXIgdGhpbmtzIHRoYXQgaXQgaXMgY29ycnVwdCwgYnV0IGl0IGlzbid0IHJlYWxseS4pCi0gUFI6IG5vbmUKLSBPYnRhaW5lZCBmcm9tOiBuL2EKLSBTdWJtaXR0ZWQgYnk6IG1vcnRlbkB4bWwuYXBhY2hlLm9yZwotIFJldmlld2VkIGJ5OiBtb3J0ZW5AeG1sLmFwYWNoZS5vcmc8YnIvPjxici8+PC9saT48L3VsPgotIDwvczQ+Ci0gPHM0IHRpdGxlPSJYU0xUQyBDaGFuZ2VzIGZvciAmeHNsdDRqOyAyLjEuMCI+Ci08cD5UaGUgU3VuIFhTTFRDIHRlYW0gKGRhdmlkLmhvZmVydEBlYXN0LnN1bi5jb20sIHRvbS5hbWlyb0BlYXN0LnN1bi5jb20sIHRvZGQubWlsbGVyQGVhc3Quc3VuLmNvbSwgCi1tb3J0ZW4uam9yZ2Vuc2VuQElyZWxhbmQuc3VuLmNvbSkgaGFzIGNoZWNrZWQgPGxpbmsgaWRyZWY9InhzbHRjX3VzYWdlIj5YU0xUQzwvbGluaz4gaW50byB0aGUgWGFsYW4KLXNvdXJjZSB0cmVlLCBhbmQgd2UgaGF2ZSBiZWd1biB0aGUgcHJvY2VzcyBvZiBtZXJnaW5nIFhTTFRDIGludG8gWGFsYW4uIFhTTFRDIHByb3ZpZGVzIGEgY29tcGlsZXIgZm9yIGNvbXBpbGluZwotc3R5bGVzaGVldHMgaW50byB0cmFuc2xldHMsIGFuZCBhIHN0cmVhbWxpbmVkIHJ1bnRpbWUgZW52aXJvbm1lbnQgZm9yIHVzaW5nIHRyYW5zbGV0cyB0byB0cmFuc2Zvcm0gWE1MIGlucHV0LiAKLUluIHRoZSBuZWFyIHRlcm0sIFhTTFRDIHdpbGwgYXBwZWFyIGluIGEgc2VwYXJhdGUgSkFSIGZpbGUgKHhzbHRjLmphcikgd2l0aCBpdHMgb3duIEFQSSBhbmQgY29tbWFuZC1saW5lCi11dGlsaXRpZXMuIFlvdSBjYW4gYWxyZWFkeSB1c2UgdGhlIHNhbWUgSkFYUCBpbnRlcmZhY2VzIHRvIHBlcmZvcm0KLXRyYW5zZm9ybWF0aW9ucyB3aXRoIHRoZSBYYWxhbiB0cmFuc2Zvcm1lciBhbmQgd2l0aCB0cmFuc2xldHMuIE92ZXIgdGltZSwgd2UgcGxhbiB0byBtZXJnZSB0aGUgdHdvIGNvZGViYXNlcy4KLTxyZWY+U2VlIDxqdW1wIGhyZWY9InhzbHRjL2luZGV4Lmh0bWwiPlhTTFRDIERlc2lnbiBEb2N1bWVudHM8L2p1bXA+LjwvcmVmPjwvcD4KLTxwPlNpbmNlIHRoaXMgaXMgdGhlIGZpcnN0IHJlbGVhc2Ugb2YgWFNMVEMgb24gQXBhY2hlICh4bWwuYXBhY2hlLm9yZyksIGNoYW5nZXMgYXJlICAKLXJlbGF0aXZlIHRvIFByZXZpZXcgNSBvZiBYU0xUQyBwb3N0ZWQgb24gd3d3LnN1bi5jb20veG1sL2RldmVsb3BlcnMuPC9wPgotPHVsPgotICA8bGk+U2ltcGxpZmllZCBzdHlsZXNoZWV0cyBhcmUgbm93IGltcGxlbWVudGVkLjwvbGk+Ci0gIDxsaT5CYXNlIHBhY2thZ2UgbmFtZSBoYXMgY2hhbmdlZCBmcm9tIDxjb2RlPmNvbS5zdW4ueHNsdDwvY29kZT4gdG8gPGNvZGU+b3JnLmFwYWNoZS54YWxhbi54c2x0YzwvY29kZT48L2xpPgotICA8bGk+WW91IG5vIGxvbmdlciBoYXZlIHRvIGdldCB0aGUgQkNFTC5qYXIgZmlsZTsgaXQgaXMgaW5jbHVkZWQgaW4gdGhlIGRpc3RyaWJ1dGlvbi48L2xpPgotICA8bGk+VGhlIFByb2plY3QgWCBwYXJzZXIgY29tcG9uZW50cyBhbmQgQVBJcyBoYXZlIGFsbCBiZWVuIHJlcGxhY2VkIHdpdGggSkFYUCBlcXVpdmFsZW50cy4gCi0gIENvbnNlcXVlbnRseSwgeW91IG1heSBkZXBsb3kgWFNMVEMgd2l0aCBKQVhQLWNvbmZvcm1hbnQgcGFyc2Vycywgc3VjaCBhcyBYZXJjZXMgb3IgQ3JpbXNvbi48L2xpPgotICA8bGk+UHJldmlvdXNseSB1bmRvY3VtZW50ZWQgZmVhdHVyZTogLXguIFlvdSBjYW4gdXNlIHRoZSAteCBvcHRpb24gb24gdGhlIGphdmEgY29tbWFuZCBsaW5lIHdoZW4geW91Ci0gIGNvbXBpbGUgdHJhbnNsZXRzIG9yIHJ1biB0aGVtIHRvIGdldCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIG9uIGVycm9ycy48L2xpPgotICA8bGk+QWRkaXRpb24gb2YgLXMgdG8gRGVmYXVsdFJ1biAtIGEgbmV3IC1zIG9wdGlvbiBoYXMgYmVlbiBhZGRlZCB0byB0aGUgRGVmYXVsdFJ1biBjbGFzcyAKLSAgZm9yIHVzZSB3aXRoIHRlc3QgYXVvdG1hdGlvbi4gV2hlbiB5b3UgdXNlIHRoZSBvcHRpb24sIGl0IHByZXZlbnRzIFN5c3RlbS5leGl0KCkgZnJvbSBiZWluZyBjYWxsZWQgd2hlbiAKLSAgYW5kIGV4Y2VwdGlvbiBpcyBlbmNvdW50ZXJlZC48L2xpPgotPC91bD4KLTwvczQ+IAotPC9zMz4KLTwvczI+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94YWxhbi94c2x0Y191c2FnZS54bWwgYi94ZG9jcy9zb3VyY2VzL3hhbGFuL3hzbHRjX3VzYWdlLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjIwMGJhMi4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hhbGFuL3hzbHRjX3VzYWdlLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDY1NSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLTwhLS0KLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAxOTk5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMgCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OiAgCi0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiAKLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKLSAqIERldmVsb3BtZW50IENvcnBvcmF0aW9uLiwgaHR0cDovL3d3dy5sb3R1cy5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci08czEgdGl0bGU9IlVzaW5nIFhTTFRDIj4KLQotPHVsPgotPGxpPjxsaW5rIGFuY2hvcj0iaW50cm8iPkludHJvZHVjdGlvbjwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJjbGFzc3BhdGgiPlNldHRpbmcgdGhlIHN5c3RlbSBjbGFzc3BhdGggZm9yIFhTTFRDPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9ImNvbXBpbGUiPkNvbXBpbGluZyB0cmFuc2xldHMgZnJvbSB0aGUgY29tbWFuZCBsaW5lPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9InJ1biI+UnVubmluZyB0cmFuc2xldHMgZnJvbSB0aGUgY29tbWFuZCBsaW5lPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9ImFwaSI+Q2FsbGluZyBYU0xUQyB3aXRoIHRoZSBUckFYL0pBWFAgQVBJPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9Im5hdGl2ZV9hcGkiPkNhbGxpbmcgWFNMVEMgd2l0aCB0aGUgbmF0aXZlIEFQSTwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJjb25zdHJhaW50cyI+WFNMVEMgdXNhZ2UgY29uc3RyYWludHM8L2xpbms+PC9saT4gIAotPC91bD4KLTxwPlNlZSBhbHNvOiA8anVtcCBocmVmPSJ4c2x0Yy9pbmRleC5odG1sIj5YU0xUQyBEZXNpZ248L2p1bXA+PC9wPgotPGFuY2hvciBuYW1lPSJpbnRybyIvPgotPHMyIHRpdGxlPSJJbnRyb2R1Y3Rpb24iPgotPHA+WFNMVCBwcm92aWRlcyBhIGNvbXBpbGVyIGFuZCBhIHJ1bnRpbWUgcHJvY2Vzc29yLiBVc2UgdGhlIGNvbXBpbGVyIHRvIGNvbXBpbGUgYW4gWFNMIHN0eWxlc2hlZXQgaW50byBhIHRyYW5zbGV0LCBhIHNldCBvZiBKYXZhIGNsYXNzZXMuIFVzZSB0aGUgcnVudGltZSBwcm9jZXNzb3IgdG8gYXBwbHkgdGhlIHRyYW5zbGV0IHRvIGFuIFhNTCBkb2N1bWVudCBhbmQgcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uLjwvcD4KLTxub3RlPlRvIGNvbXBpbGUgdHJhbnNsZXRzLCB5b3UgbXVzdCBiZSBydW5uaW5nIHRoZSBKREsgb3IgSlJFIDEuMiBvciBoaWdoZXIuIFlvdSBjYW4gcnVuIHRyYW5zbGV0cyB3aXRoIHRoZSBKREsgb3IgSlJFIDEuMS44IG9yIGhpZ2hlci48L25vdGU+Ci08L3MyPjxhbmNob3IgbmFtZT0iY2xhc3NwYXRoIi8+Ci08czIgdGl0bGU9IlNldHRpbmcgdGhlIHN5c3RlbSBjbGFzc3BhdGggZm9yIFhTTFRDIj4KLTxwPlRvIGNvbXBpbGUgdHJhbnNsZXRzLCBydW4gdHJhbnNsZXRzLCBhbmQgdXNlIHRoZSBYU0xUQyBBUEksIHB1dCB0aGUgZm9sbG93aW5nIG9uIHRoZSBzeXN0ZW0gY2xhc3NwYXRoOjwvcD4KLTx0YWJsZT4KLTx0cj4KLSAgPHRoPkNsYXNzZXMgb3IgSkFSPC90aD4KLSAgPHRoPlRvIGNvbXBpbGUgYSB0cmFuc2xldDwvdGg+Ci0gIDx0aD5UbyBydW4gYSB0cmFuc2xldDwvdGg+Ci0gIDx0aD5UbyB1c2UgdGhlIFhTTFRDIEFQSTwvdGg+Ci08L3RyPgotPHRyPgotICA8dGQ+dGhlIHRyYW5zbGV0PC90ZD4KLSAgPHRkPjwvdGQ+Ci0gIDx0ZD5yZXF1aXJlZDwvdGQ+Ci0gIDx0ZD5yZXF1aXJlZDwvdGQ+ICAKLTwvdHI+Ci08dHI+Ci0gIDx0ZD54c2x0Yy5qYXI8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPiAgCi08L3RyPgotPCEtLSBUV0EgLSB4bWwuamFyIGhhcyBvbGQgcHJvamVjdCB4IHN0dWZmOyB3YXMgYWJsZSB0byBjb21waWxlIGFuZCBydW4gd2l0aG91dCBpdCAtLT4KLTwhLS0KLTx0cj4KLSAgPHRkPnhtbC5qYXI8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPiAgCi08L3RyPgotLS0+Ci08dHI+Ci0gIDx0ZD5ydW50aW1lLmphcjwvdGQ+Ci0gIDx0ZD5yZXF1aXJlZDwvdGQ+Ci0gIDx0ZD48L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPiAgCi08L3RyPgotPHRyPgotICA8dGQ+QkNFTC5qYXI8L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPgotICA8dGQ+PC90ZD4KLSAgPHRkPnJlcXVpcmVkPC90ZD4gIAotPC90cj4KLTx0cj4KLSAgPHRkPkpsZXguamFyPC90ZD4KLSAgPHRkPjwvdGQ+Ci0gIDx0ZD48L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPiAgCi08L3RyPgotPHRyPgotICA8dGQ+amF2YV9jdXAuamFyPC90ZD4KLSAgPHRkPjwvdGQ+Ci0gIDx0ZD48L3RkPgotICA8dGQ+cmVxdWlyZWQ8L3RkPiAgCi08L3RyPgotPC90YWJsZT4KLTxwPlRoZSBKQVIgZmlsZXMgbGlzdGVkIGFib3ZlIGFyZSBpbiB0aGUgJnhzbHQ0ajsgYmluIGRpcmVjdG9yeS4gVGhlIHRyYW5zbGV0IGlzIHRoZSBzZXQgb2YgY2xhc3MgZmlsZXMgb3IgdGhlIEpBUiBmaWxlIHRoYXQgeW91IGdlbmVyYXRlIHdpdGggdGhlIGNvbXBpbGVyOyBzZWUgPGxpbmsgYW5jaG9yPSJjb21waWxlIj5Db21waWxpbmcgdHJhbnNsZXRzPC9saW5rPi48L3A+Ci08cD5JZiB5b3UgYXJlIHVzaW5nIEpESyBvciBKUkUgMS4xLjgsIGFsc28gaW5jbHVkZSBjbGFzc2VzLnppcCBvbiB0aGUgY2xhc3NwYXRoLiBJZiB5b3UgYXJlIHVzaW5nIEpESyBvciBKUkUgMS4yLCBpbmNsdWRlIHRvb2xzLmphciBvbiB0aGUgY2xhc3NwYXRoLjwvcD4KLTxub3RlPkZvciB0aGUgdGltZSBiZWluZywgdGhlIFhhbGFuIHByb2Nlc3NvciBhbmQgWFNMVCBkbyBub3QgeWV0IHVzZSB0aGUgc2FtZSBET00sIFNBWCwgYW5kIHBhcnNlciBpbmZhc3RydWN0dXJlcy4gQWNjb3JkaW5nbHksIHlvdSBtYXkgZmluZCBpdCBuZWNlc3NhcnkgdG8gcmVzZXQgdGhlIHN5c3RlbSBjbGFzc3BhdGggZWFjaCB0aW1lIHlvdSBzd2l0Y2ggYmV0d2VlbiB0aGUgWGFsYW4gcHJvY2Vzc29yIGFuZCBYU0xUQy4gRm9yIGluZm9ybWF0aW9uIG9uIHNldHRpbmcgdGhlIGNsYXNzcGF0aCBmb3IgdGhlIFhhbGFuIHByb2Nlc3Nvciwgc2VlIDxsaW5rIGlkcmVmPSJnZXRzdGFydGVkIiBhbmNob3I9ImNsYXNzcGF0aCI+U2V0dGluZyB0aGUgc3lzdGVtIGNsYXNzcGF0aCBmb3IgWGFsYW48L2xpbms+Ljwvbm90ZT4KLTwvczI+Ci08YW5jaG9yIG5hbWU9ImNvbXBpbGUiLz4KLTxzMiB0aXRsZT0iQ29tcGlsaW5nIHRyYW5zbGV0cyBmcm9tIHRoZSBjb21tYW5kIGxpbmUiPgotICAgIDx1bD4KLSAgICAgIDxsaT48bGluayBhbmNob3I9ImNvbXAtc3lub3BzaXMiPlN5bm9waXM8L2xpbms+PC9saT4KLSAgICAgIDxsaT48bGluayBhbmNob3I9ImNvbXAtYXJncyI+RmxhZ3MgYW5kIGFyZ3VtZW50czwvbGluaz48L2xpPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0iY29tcC1leGFtcGxlcyI+RXhhbXBsZXM8L2xpbms+PC9saT4KLSAgICA8L3VsPgotCTxwPlRoZSBYU0xUIENvbXBpbGVyIGlzIGEgSmF2YS1iYXNlZCB0b29sIGZvciBjb21waWxpbmcgWFNMVAotCXN0eWxlc2hlZXRzIGludG8gbGlnaHR3ZWlnaHQgYW5kIHBvcnRhYmxlIEphdmEgYnl0ZSBjb2RlcyAKLQljYWxsZWQgdHJhbnNsZXRzLjwvcD4gIAotCi0JPHA+VGhlIFhTTFQgQ29tcGlsZXIgY2FuIGJlIHJ1biBvbiBhbnkgcGxhdGZvcm0gaW5jbHVkaW5nIFVOSVgsCi0JV2luZG93cywgTlQsIG9yIE1hYyB0aGF0IHN1cHBvcnRzIEphdmEgMS4yLnggb3IgbGF0ZXIuIFRoZSBnZW5lcmF0ZWQKLQl0cmFuc2xldHMgY2FuIGJlIHJ1biBvbiBhbnkgcGxhdGZvcm0gdGhhdCBzdXBwb3J0cyBhIEphdmEKLQlSdW50aW1lIEVudmlyb25tZW50LCBpbmNsdWRpbmcgYSBQYWxtIFBpbG90IHdpdGggSjJNRSBDTERDIAotCShKYXZhIDIgTWljcm8gRWRpdGlvbiwgQ29ubmVjdGVkIExpbWl0ZWQgRGV2aWNlIENvbmZpZ3VyYXRpb24pLjwvcD4KLSAgICAKLSAgICA8cD5UbyBydW4gdGhlIGNvbXBpbGVyIGZyb20gdGhlIGNvbW1hbmQgbGluZSBvciBhIHNjcmlwdCwgPGxpbmsgYW5jaG9yPSJjbGFzc3BhdGgiPnNldCB0aGUgY2xhc3NwYXRoPC9saW5rPiBhbmQgCi0gICAgcnVuIHRoZSBYU0xUQyBjbGFzcyB3aXRoIHRoZSBhcHByb3ByaWF0ZSBmbGFncyBhbmQgYXJndW1lbnRzIChkZXNjcmliZWQgYmVsb3cpLjwvcD4KLSAgICA8YW5jaG9yIG5hbWU9ImNvbXAtc3lub3BzaXMiLz4KLTxzMyB0aXRsZT0iU3lub3BzaXMiPgotPHA+Ci08Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuWFNMVEM8L2NvZGU+PGJyLz4KLTxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO1stbyAmbHQ7b3V0cHV0Jmd0O10gWy1kICZsdDtkaXJlY3RvcnkmZ3Q7XSBbLWogJmx0O2phcmZpbGUmZ3Q7XTwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Wy1wICZsdDtwYWNrYWdlIG5hbWUmZ3Q7XSBbLXVdICZsdDtzdHlsZXNoZWV0Jmd0Oy4uLjwvY29kZT48L3A+IAotCi08L3MzPjxhbmNob3IgbmFtZT0iY29tcC1hcmdzIi8+Ci08czMgdGl0bGU9IkZsYWdzIGFuZCBhcmd1bWVudHMiPgotCTxwPlRoZSBmb2xsb3dpbmcgZmxhZ3MgYW5kIGFyZ3VtZW50cyBhcmUgc3VwcG9ydGVkOjwvcD4KLQotPHNvdXJjZT4tbyAmbHQ7b3V0cHV0Jmd0OwotICAgU3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQgY2xhc3MuCi0gICBJZiB5b3Ugb21pdCB0aGlzIGFyZ3VtZW50LCB0aGUgdHJhbnNsZXQgY2xhc3MgaXMKLSAgIG5hbWVkICZsdDtzdHlsZXNoZWV0Jmd0Oy4gVHJhbnNsZXRzIGFyZSB3cml0dGVuIGFzIAotICAgLmNsYXNzIGZpbGVzLgotCi0tZCAmbHQ7ZGlyZWN0b3J5Jmd0OwotICAgU3BlY2lmaWVzIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuIElmIHlvdSBvbWl0Ci0gICB0aGlzIGFyZ3VtZW50LCB0aGUgdHJhbnNsZXQgY2xhc3MgZmlsZXMgYXJlIHBsYWNlZAotICAgaW4gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuCi0KLS1qICZsdDtqYXJmaWxlJmd0OwotICAgT3V0cHV0cyB0aGUgZ2VuZXJhdGVkIHRyYW5zbGV0IGNsYXNzIGZpbGVzIGludG8gYSAKLSAgIGphciBmaWxlIG5hbWVkICZsdDtqYXJmaWxlJmd0Oy5qYXIuIFdoZW4gdGhpcyBvcHRpb24gaXMgCi0gICB1c2VkLCBvbmx5IHRoZSBqYXIgZmlsZSBpcyBvdXRwdXQuCi0KLS1wICZsdDtwYWNrYWdlIG5hbWUmZ3Q7Ci0gICBTcGVjaWZpZXMgYSBwYWNrYWdlIG5hbWUgZm9yIHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQKLSAgIGNsYXNzZXMuCQkKLQotLXUgICZsdDtzdHlsZXNoZWV0Jmd0OwotICBTcGVjaWZpZXMgdGhlIHN0eWxlc2hlZXQgd2l0aCBhIFVSSSBzdWNoIGFzIAotICAnaHR0cDovL215c2VydmVyL3N0eWxlc2hlZXQxLnhzbCcuCi0KLSAgICZsdDtzdHlsZXNoZWV0Jmd0OwotICAgKE5vIGZsYWcpIFRoZSBwYXRobmFtZSBvZiB0aGUgc3R5bGVzaGVldCBmaWxlLjwvc291cmNlPgotCi08L3MzPjxhbmNob3IgbmFtZT0iY29tcC1leGFtcGxlcyIvPgotPHMzIHRpdGxlPSJFeGFtcGxlcyI+Ci0JPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlcyBhc3N1bWUgdGhhdCB5b3UgaGF2ZSBhbHJlYWR5IHNldCB0aGUgY2xhc3NwYXRoIHRvIGluY2x1ZGUgdGhlIHRyYW5zbGV0IGFuZCB0aGUgcmVxdWlyZWQgSkFSCi0gICAgZmlsZXMgKHNlZSA8bGluayBhbmNob3I9ImNsYXNzcGF0aCI+c2V0dGluZyB0aGUgc3lzdGVtIGNsYXNzcGF0aDwvbGluaz4pLjwvcD4KLQotCTxwPjxlbT5FeGFtcGxlIDE6PC9lbT4gIENyZWF0aW5nIGEgdHJhbnNsZXQgZnJvbSB0aGUgaGFtbGV0LnhzbCBzdHlsZXNoZWV0LjwvcD4KLQk8cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuWFNMVEM8L2NvZGU+PGJyLz4KLSAgICA8Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgaGFtbGV0LnhzbDwvY29kZT48L3A+ICAgIAotICAgIDxwPkV4YW1wbGUgMSBwcm9kdWNlcyBhIHNldCBvZiBjbGFzcyBmaWxlcyBzdWNoIGFzIGhhbWxldC5jbGFzcywgaGFtbGV0JDAuY2xhc3MsIGhhbWxldCQxLmNsYXNzLjwvcD4JCi0KLQk8cD48ZW0+RXhhbXBsZSAyOjwvZW0+ICBPdXRwdXR0aW5nIHRvIGEgSkFSIGZpbGUuPC9wPgotICAgIDxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5YU0xUQzwvY29kZT48YnIvPgotICAgIDxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAtaiBoYW1sZXQuamFyIGhhbWxldC54c2w8L2NvZGU+PC9wPgotICAgIDxwPkV4YW1wbGUgMiBwcm9kdWNlcyBoYW1sZXQuamFyLCB3aGljaCBjb250YWlucyB0aGUgdHJhbnNsZXQgY2xhc3MgZmlsZXMuPC9wPgkKLQotCTxwPjxlbT5FeGFtcGxlIDM6PC9lbT4gU3BlY2lmeWluZyB0aGUgdHJhbnNsZXQgY2xhc3MgbmFtZS4gPC9wPiAKLQk8cD48Y29kZT5qYXZhIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIuWFNMVEM8L2NvZGU+PGJyLz4KLSAgICA8Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgLW8gbmV3aGFtbGV0IGhhbWxldC54c2w8L2NvZGU+PC9wPgotICAgIDxwPkV4YW1wbGUgMyBwcm9kdWNzIGEgc2V0IG9mIGNsYXNzIGZpbGVzIHN1Y2ggYXMgbmV3aGFtbGV0LmNsYXNzLCBuZXdoYW1sZXQkMC5jbGFzcywgZXRjLiwgcmF0aGVyIHRoYW4gaGFtbGV0LmNsYXNzLAotICAgIGhhbWxlcyQwLmNsYXNzLCBldGMuPC9wPgotCi0KLQk8cD48ZW0+RXhhbXBsZSA0OjwvZW0+IENvbXBpbGluZyBtdWx0aXBsZSBzdHlsZXNoZWV0cy48L3A+Ci0JPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlhTTFRDPC9jb2RlPjxici8+Ci0gICAgPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IGhhbWxldDEueHNsIGhhbWxldDIueHNsIGhhbWxldDMueHNsPC9jb2RlPjwvcD4KLSAgICA8cD5FeGFtcGxlIDQgcHJvZHVjZXMgdGhyZWUgdHJhbnNsZXRzIGFuZCBzZXQgb2YgY2xhc3MgZmlsZXMgZGVyaXZlZCBmcm9tIHRoZSB0aHJlZSBzdHlsZXNoZWV0cy48L3A+Ci0KLQk8cD48ZW0+RXhhbXBsZSA1OjwvZW0+IFBhY2thZ2UgU3BlY2lmaWNhdGlvbi48L3A+Ci0JPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlhTTFRDPC9jb2RlPjxici8+Ci0gICAgPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IC1wIGNvbS5teWNvbXBhbnkudHJhbnNsZXRzIGhhbWxldC54c2w8L2NvZGU+PC9wPgotICAgIDxwPkV4YW1wbGUgNSBwcm9kdWNlcyBhIHNldCBvZiBjbGFzcyBmaWxlcyBzdWNoIGFzIGNvbS9teWNvbXBhbnkvdHJhbnNsZXRzL2hhbWxldC5jbGFzcywKLQljb20vbXljb21wYW55L3RyYW5zbGV0cy9oYW1sZXQkMC5jbGFzcycsIGV0Yy48L3A+Ci08L3MzPgotPC9zMj48YW5jaG9yIG5hbWU9InJ1biIvPgotPHMyIHRpdGxlPSJSdW5uaW5nIHRyYW5zbGV0cyBmcm9tIHRoZSBjb21tYW5kIGxpbmUiPgotICAgIDx1bD4KLSAgICAgIDxsaT48bGluayBhbmNob3I9InJ1bi1zeW5vcHNpcyI+U3lub3BpczwvbGluaz48L2xpPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0icnVuLWFyZ3MiPkZsYWdzIGFuZCBhcmd1bWVudHM8L2xpbms+PC9saT4KLSAgICAgIDxsaT48bGluayBhbmNob3I9InJ1bi1leGFtcGxlcyI+RXhhbXBsZXM8L2xpbms+PC9saT4KLSAgICA8L3VsPgotCi0gICAgPHA+VGhlIFN1biBYU0xUIHJ1bnRpbWUgcHJvY2Vzc29yIGlzIGEgSmF2YS1iYXNlZCB0b29sIGZvciAKLQl0cmFuc2Zvcm1pbmcgWE1MIGRvY3VtZW50IGZpbGVzIHVzaW5nIGEgdHJhbnNsZXQgKGNvbXBpbGVkIAotCXN0eWxlc2hlZXQpLiA8L3A+Ci0KLQk8cD5UaGUgWFNMVCBwcm9jZXNzb3IgY2FuIGJlIHJ1biBvbiBhbnkgcGxhdGZvcm0gaW5jbHVkaW5nIFVOSVgsCi0JV2luZG93cywgTlQsIE1hYyB0aGF0IHN1cHBvcnRzIEphdmEsIGluY2x1ZGluZyBhIFBhbG0gUGlsb3QKLQl3aXRoIEoyTUUgQ0xEQyAoSmF2YSAyIE1pY3JvIEVkaXRpb24sIENvbm5lY3RlZCBMaW1pdGVkIERldmljZQotCUNvbmZpZ3VyYXRpb24pLjwvcD4KLSAgICAKLSAgICA8cD5UbyBydW4gIHRyYW5zbGV0IGZyb20gdGhlIGNvbW1hbmQgbGluZSBvciBhIHNjcmlwdCwgPGxpbmsgYW5jaG9yPSJjbGFzc3BhdGgiPnNldCB0aGUgY2xhc3NwYXRoPC9saW5rPiAoYmUgc3VyZSB0byBpbmNsdWRlCi0gICAgIHRoZSB0cmFuc2xldCkgYW5kIHJ1biB0aGUgdHJhbnNsc2V0IHdpdGggdGhlIGFwcHJvcHJpYXRlIGZsYWdzIGFuZCBhcmd1bWVudHMgKGRlc2NyaWJlZCBiZWxvdykuPC9wPgotPGFuY2hvciBuYW1lPSJydW4tc3lub3BzaXMiLz4KLTxzMyB0aXRsZT0iU3lub3BzaXMiPgotPHA+PGNvZGU+amF2YSAmbHQ7dHJhbnNsZXQmZ3Q7PC9jb2RlPjxici8+Ci08Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgey11ICZsdDtkb2N1bWVudF91cmwmZ3Q7IHwgJmx0O2RvY3VtZW50Jmd0O30gJmx0O2NsYXNzJmd0OzwvY29kZT48YnIvPgotPGNvZGU+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFsmbHQ7bmFtZTEmZ3Q7PSZsdDt2YWx1ZTEmZ3Q7IC4uLl08L2NvZGU+PC9wPgotCi08L3MzPjxhbmNob3IgbmFtZT0icnVuLWFyZ3MiLz4KLTxzMyB0aXRsZT0iRmxhZ3MgYW5kIGFyZ3VtZW50cyI+Ci0KLQk8cD5UaGUgZm9sbG93aW5nIGZsYWdzIGFuZCBhcmd1bWVudHMgYXJlIHN1cHBvcnRlZDo8L3A+Ci0KLTxzb3VyY2U+LXUKLSAgIFNwZWNpZmllcyB0aGUgWE1MIGlucHV0ICZsdDtkb2N1bWVudCZndDsgd2l0aCBhIFVSSSwKLSAgIHN1Y2ggYXMgJ2h0dHA6Ly9teXNlcnZlci9oYW1sZXQueG1sJy4JCQotCi1Bcmd1bWVudHMgd2lyaG91dCBmbGFnczoKLQotICAgJmx0O2RvY3VtZW50Jmd0OyAgICAgCQkKLSAgIEZpbGVuYW1lIG9mIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQuIAotICAgCi0gICAmbHQ7ZG9jdW1lbnRfdXJsJmd0OyAgICAgCQotICAgVVJJIG9mIHRoZSBYTUwgaW5wdXQgZG9jdW1lbnQgKHNlZSB0aGUgLXUgZmxhZyBhYm92ZSkuIAotCi0gICAmbHQ7Y2xhc3MmZ3Q7Ci0gICBUaGUgdHJhbnNsZXQgdGhhdCBwZXJmb3JtcyB0aGUgdHJhbnNmb3JtYXRpb24uIFRoZSB0cmFuc2xldAotICAgbWF5IHRha2UgYSBzZXQgb2Ygc3R5bGVzaGVldCBwYXJhbWV0ZXJzIHNwZWNpZmllZCBhcwotICAgbmFtZS12YWx1ZSBwYWlycy4gVGhlIGZvcm1hdCBmb3IgYSBuYW1lLXZhbHVlIHBhaXIgaXMKLSAgICZsdDtuYW1lJmd0Oz0mbHQ7dmFsdWUmZ3Q7Ljwvc291cmNlPgotPC9zMz48YW5jaG9yIG5hbWU9InJ1bi1leGFtcGxlcyIvPgotPHMzIHRpdGxlPSJFeGFtcGxlcyI+Ci0KLQk8cD5UaGUgZm9sbG93aW5nIGV4YW1wbGVzIGFzc3VtZSB0aGF0IHlvdSBoYXZlIGFscmVhZHkgc2V0IHRoZSBjbGFzc3BhdGggdG8gaW5jbHVkZSB0aGUgdHJhbnNsZXQgYW5kIHRoZSByZXF1aXJlZCBKQVIKLSAgICBmaWxlcyAoc2VlIDxsaW5rIGFuY2hvcj0iY2xhc3NwYXRoIj5zZXR0aW5nIHRoZSBzeXN0ZW0gY2xhc3NwYXRoPC9saW5rPikuPC9wPgotICAgIDxwPkEgcG9zc2libGUgdmFyaWF0aW9uOiBZb3UgaGF2ZSBzZXQgdGhlIGNsYXNzcGF0aCB0byBpbmNsdWRlIHRoZSByZXF1aXJlZCBKQVIgZmlsZXMsIGJ1dCB3aGVuIHlvdSBydW4gdGhlIHRyYW5zbGV0LAotICAgIHlvdSB1c2UgdGhlIGphdmEgLWNwIGZsYWcgdG8gYWRkIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IChjb250YWluaW5nIHRoZSB0cmFuc2xldCBjbGFzcyBmaWxlcyB5b3UgaGF2ZSBqdXN0IGdlbmVyYXRlZCkKLSAgICB0byB0aGUgY2xhc3NwYXRoLjwvcD4KLSAgICA8cD48cmVmPldpbmRvd3M6PC9yZWY+PGNvZGU+IGphdmEgLWNwIC47JUNMQVNTUEFUSCUgLi4uPC9jb2RlPjxici8+Ci0gICAgICAgPHJlZj5VTklYOiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvcmVmPjxjb2RlPiBqYXZhIC1jcCAuOiRDTEFTU1BBVEggLi4uPC9jb2RlPjwvcD4KLSAgICAKLSAgICA8cD48ZW0+RXhhbXBsZSAxOjwvZW0+IFByb2Nlc3NpbmcgYW4gWE1MIGRvY3VtZW50LjwvcD4KLQotCTxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkRlZmF1bHRSdW48L2NvZGU+PGJyLz4KLSAgICAgICA8Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgIGhhbWxldC54bWwgaGFtbGV0PC9jb2RlPjwvcD4gCi0KLQk8cD5FeGFtcGxlIDEgdXNlcyB0aGUgc3BlY2lmaWVkIHRyYW5zbGV0IChoYW1sZXQpIHRvIHRyYW5zZm9ybSB0aGUgc3BlY2lmaWVkIFhNTCBpbnB1dCBkb2N1bWVudCAoaGFtbGV0LnhtbCkuIAotICAgIFRoZSBYTUwgaW5wdXQgZG9jdW1lbnQgaXMgaW4gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuIFRoZSB0cmFuc2xldCB3YXMgY3JlYXRlZCBieSB1c2luZwotICAgIG9yZy5hcGFjaGUueGFsYW4ueHNsdC5jb21waWxlci5YU0xUQyB0byBjb21waWxlIGFuIFhTTCBzdHlsZXNoZWV0IChoYW1sZXQueHNsKS4gPC9wPgotCi0JPHA+PGVtPkV4YW1wbGUgMjo8L2VtPiBQYXNzaW5nIHN0eWxlc2hlZXQgcGFyYW1ldGVycyB0byB0aGUgdHJhbnNsZXQuPC9wPgotCi0JPHA+PGNvZGU+amF2YSBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuRGVmYXVsdFJ1bjwvY29kZT48YnIvPgotICAgICAgIDxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBoYW1sZXQueG1sIGhhbWxldDwvY29kZT48YnIvPgotICAgICAgIDxjb2RlPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBzcGVha2VyPUhBTUxFVCAnc2NlbmU9U0NFTkUgSVYnPC9jb2RlPjwvcD4KLQotCTxwPkV4YW1wbGUgMiBwYXNzZXMgIkhBTUxFVCIgdG8gdGhlIHN0eWxlc2hlZXQgZm9yIHRoZSBzdHlsZXNoZWV0IHBhcmFtZXRlciBuYW1lZCBzcGVha2VyLCBhbmQgIlNDRU5FIElWIiBmb3IgdGhlCi0gICAgc3R5bGVzaGVldCBwYXJhbWV0ZXIgbmFtZWQgc2NlbmUuIFRoZSBzZWNvbmQgbmFtZS12YWx1ZSBwYWlyIHdhcyBwbGFjZWQgaW4gc2luZ2xlIHF1b3RlcyB0byAKLSAgICBzcGVjaWZ5IGEgdmFsdWUgY29udGFpbmluZyBhIHNwYWNlLjwvcD4KLSAgICAKLSAgICA8cD48ZW0+RXhhbXBsZSAzOjwvZW0+IFByb2Nlc3NpbmcgYW4gWE1MIGlucHV0IGRvY3VtZW50IHNwZWNpZmllZCB3aXRoIGEgVVJJLjwvcD4KLQotCTxwPjxjb2RlPmphdmEgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkRlZmF1bHRSdW48L2NvZGU+PGJyLz4KLSAgICAgICA8Y29kZT4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgIC11IGh0dHA6Ly96YXJ5YS5lYXN0L3Rlc3QueG1sIGhhbWxldDwvY29kZT48L3A+Ci0KLQk8cD5FeGFtcGxlIDMgYXBwbGllcyB0aGUgdHJhbnNsZXQgKGhhbWxldCkgdG8gdGhlIFhNTCBpbnB1dCBkb2N1bWVudCAoaHR0cDovL3phcnlhLmVhc3QvdGVzdC54bWwgaGFtbGV0KS4gSW5jbHVzaW9uIG9mCi0gICAgdGhlIGZsYWcgKC11KSBpcyBvcHRpb25hbC48L3A+Ci08L3MzPgotPC9zMj48YW5jaG9yIG5hbWU9ImFwaSIvPgotPHMyIHRpdGxlPSJDYWxsaW5nIFhTTFRDIHdpdGggdGhlIFRyQVgvSkFYUCBBUEkiPgotPHA+Ry4gVG9kZCBNaWxsZXIgaGFzIGJlZ3VuIGludGVncmF0aW5nIHRoZSB0cmFuc2xldCB3aXRoIHRoZSBUckFYL0pBWFAgMS4xIEFQSS4gU2VlIDxqdW1wIGhyZWY9InhzbHRjL3hzbHRjX3RyYXguaHRtbCI+VGhlIFRyYW5zbGV0IEFQSSAmYW1wOyBUckFYPC9qdW1wPi4gQWNjb3JkaW5nbHksIGl0IGlzIG5vdyBwb3NzaWJsZSB0byBzZXQgYSBzeXN0ZW0gcHJvcGVydHkgYW5kIHVzZSBhIFRyYW5zZm9ybWVyRmFjdG9yeSB0byBnZW5lcmF0ZSBhIFRyYW5zZm9ybWVyIHRoYXQgcGVyZm9ybXMgYSB0cmFuc2Zvcm1hdGlvbiBieSBjb21waWxpbmcgYW5kIHJ1bm5pbmcgYSB0cmFuc2xldC48L3A+Ci0KLQotPHA+V2hlbiB5b3UgdXNlIHRoZSBKQVhQIDEuMSBBUEkgdG8gcnVuICZ4c2x0NGo7LCB0aGUgPGNvZGU+amF2YXgueG1sLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gc3lzdGVtIHByb3BlcnR5IGlzIHNldCB0byA8Y29kZT5vcmcuYXBhY2hlLnhhbGFuLnByb2Nlc3Nvci5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsPC9jb2RlPi4gQXMgaXQgY3VycmVudGx5IHN0YW5kcywgdGhpcyBYYWxhbiBpbXBsZW1lbnRhdGlvbiBvZiBUcmFuc2Zvcm1lckZhY3RvcnkgYWx3YXlzIHVzZXMgdGhlIFhhbGFuIFRyYW5zZm9ybWVyIHRvIHBlcmZvcm0gdHJhbnNmb3JtYXRpb25zLiBUbyB1c2UgdHJhbnNsZXRzIHRvIHBlcmZvcm0gdHJhbnNmb3JtYXRpb25zLCBzZXQgdGhpcyBzeXN0ZW0gcHJvcGVydHkgdG8gPGNvZGU+b3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLlRyYW5zZm9ybWVyRmFjdG9yeUltcGw8L2NvZGU+LiBGb3IgaW5mb3JtYXRpb24gb24gc2V0dGluZyB0aGlzIGFuZCByZWxhdGVkIHN5c3RlbSBwcm9wZXJ0aWVzIGRlc2lnbmF0aW5nIFhNTCBwYXJzZXJlIGFuZCBYU0wgdHJhbnNmb3JtZXIsIHNlZSA8bGluayBpZHJlZj0idXNhZ2VwYXR0ZXJucyIgYW5jaG9yPSJwbHVnIj5QbHVnZ2luZyBpbiBhIFRyYW5zZm9ybWVyIGFuZCBYTUwgcGFyc2VyPC9saW5rPi48L3A+Ci08cD5UbyBVc2UgdGhlIEpBWFAgMS4xIEFQSSB0byBwZXJmb3JtIHRyYW5zZm9ybWF0aW9ucyB3aXRoIHRyYW5zbGV0cyBkbyB0aGUgZm9sbG93aW5nOjwvcD4KLTxvbD4KLSAgPGxpPlNldCB0aGUgPGNvZGU+amF2YXgueG1sLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVyRmFjdG9yeTwvY29kZT4gc3lzdGVtIHByb3BlcnR5IGFzIGluZGljYXRlZCBhYm92ZS48YnIvPjxici8+PC9saT4KLSAgPGxpPkluc3RhbnRpYXRlIGEgVHJhbnNmb3JtZXJGYWN0b3J5Ljxici8+PGJyLz48L2xpPgotICA8bGk+QXNzdW1pbmcgeW91IHdhbnQgdG8gcGVyZm9ybSBhIHNlcmllcyBvZiB0cmFuc2Zvcm1hdGlvbnMgd2l0aCB0aGUgc2FtZSB0cmFuc2xldCwgdXNlIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgYW5kIGEKLSAgIFN0cmVhbVNvdXJjZSBYU0wgc3R5bGVzaGVldCB0byBnZW5lcmF0ZSBhIFRlbXBsYXRlcyBvYmplY3QgKHRoZSB0cmFuc2xldCkuIElmIHlvdSBhcmUgcGVyZm9ybWluZyBhIHNpbmdsZQotICAgdHJhbnNmb3JtYXRpb24sIHVzZSB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGFuZCB0aGUgU3RyZWFtU291cmNlIG9iamVjdCB0byBpbnN0YW50aWF0ZSBhIFRyYW5zZm9ybWVyLjxici8+PGJyLz48L2xpPgotICA8bGk+UGVyZm9ybSB0aGUgdHJhbnNmb3JtYXRpb24sIHVzaW5nIGEgU3RyZWFtU291cmNlIG9iamVjdCBmb3IgdGhlIFhNTCBpbnB1dCBhbmQgYSBTdHJlYW1SZXN1bHQgb2JqZWN0IHRvIGhvbGQgdGhlCi0gICB0cmFuc2Zvcm1hdGlvbiBvdXRwdXQuPC9saT4KLTwvb2w+Ci08czMgdGl0bGU9IkV4YW1wbGVzIj4KLTxwPjxlbT5FeGFtcGxlIDE6PC9lbT4gVXNpbmcgYSB0cmFuc2xldC9UZW1wbGF0ZXMgb2JqZWN0IGZvciBtdWx0aXBsZSB0cmFuc2Zvcm1hdGlvbnM8L3A+Ci08c291cmNlPmltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyOwotaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlczsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtUmVzdWx0OwotLi4uCi0vLyBTZXQgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBzeXN0ZW0gcHJvcGVydHkuCi0vLyBOb3RlOiBGb3IgbW9yZSBmbGV4aWJpbGl0eSwgbG9hZCBwcm9wZXJ0aWVzIGZyb20gYSBwcm9wZXJ0aWVzIGZpbGUuCi1TdHJpbmcga2V5ID0gImphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5IjsKLVN0cmluZyB2YWx1ZSA9ICJvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCI7Ci1Qcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKLXByb3BzLnB1dChrZXksIHZhbHVlKTsKLVN5c3RlbS5zZXRQcm9wZXJ0aWVzKHByb3BzKTsKLS4uLgotU3RyaW5nIHhzbEluVVJJOwotLy8gSW5zdGFudGlhdGUgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSwgYW5kIHVzZSBpdCBhbG9uZyB3aXRoIGEgU3RlYW1Tb3VyY2UKLS8vIFhTTCBzdHlsZXNoZWV0IHRvIGNyZWF0ZSBhIHRyYW5zbGV0IGFzIGEgVGVtcGxhdGVzIG9iamVjdC4KLVRyYW5zZm9ybWVyRmFjdG9yeSB0RmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotVGVtcGxhdGVzIHRyYW5zbGV0ID0gdEZhY3RvcnkubmV3VGVtcGxhdGVzKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSW5VUkkpKTsKLS4uLgotU3RyaW5nIHhtbEluVVJJOwotU3RyaW5nIGh0bWxPdXRVUkk7Ci0uLi4KLS8vIEZvciBlYWNoIHRyYW5zZm9ybWF0aW9uLCBpbnN0YW50aWF0ZSBhIG5ldyBUcmFuc2Zvcm1lciwgYW5kIHBlcmZvcm0KLS8vIHRoZSB0cmFuc2Zvcm1hdGlvbiBmcm9tIGEgU3RyZWFtU291cmNlIHRvIGEgU3RyZWFtUmVzdWx0OwotVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPSB0cmFuc2xldC5uZXdUcmFuc2Zvcm1lcigpOwotdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoeG1sSW5VUkkpLAotICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1SZXN1bHQobmV3IEZpbGVPdXRwdXRTdHJlYW0oaHRtbE91dFVSSSkpKTsKLS4uLjwvc291cmNlPgotPHA+Rm9yIGEgd29ya2luZyBzYW1wbGUgdGhhdCBpbGx1c3RyYXRlcyB0aGlzIHVzYWdlIHBhdHRlcm4sIHNlZSA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJ4c2x0YzEiPkpBWFBUcmFuc2xldE9uZVRyYW5zZm9ybWF0aW9uPC9saW5rPi48L3A+Ci08cD48ZW0+RXhhbXBsZSAyOjwvZW0+IENvbXBpbGluZyBhIHRyYW5zbGV0L1RlbXBsYXRlcyBvYmplY3QgZm9yIGEgc2luZ2xlIHRyYW5zZm9ybWF0aW9uPC9wPgotPHNvdXJjZT5pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLS4uLgotLy8gU2V0IHRoZSBUcmFuc2Zvcm1lckZhY3Rvcnkgc3lzdGVtIHByb3BlcnR5LgotLy8gTm90ZTogRm9yIG1vcmUgZmxleGliaWxpdHksIGxvYWQgcHJvcGVydGllcyBmcm9tIGEgcHJvcGVydGllcyBmaWxlLgotU3RyaW5nIGtleSA9ICJqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeSI7Ci1TdHJpbmcgdmFsdWUgPSAib3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLlRyYW5zZm9ybWVyRmFjdG9yeUltcGwiOwotUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7Ci1wcm9wcy5wdXQoa2V5LCB2YWx1ZSk7Ci1TeXN0ZW0uc2V0UHJvcGVydGllcyhwcm9wcyk7Ci0uLi4KLVN0cmluZyB4c2xJblVSSTsKLVN0cmluZyB4bWxJblVSSTsKLVN0cmluZyBodG1sT3V0VVJJOwotLy8gSW5zdGFudGlhdGUgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSwgYW5kIHVzZSBpdCBhbG9uZyB3aXRoIGEgU3RlYW1Tb3VyY2UKLS8vIFhTTCBzdHlsZXNoZWV0IHRvIGNyZWF0ZSBhIFRyYW5zZm9ybWVyLgotVHJhbnNmb3JtZXJGYWN0b3J5IHRGYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci1UcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKG5ldyBTdHJlYW1Tb3VyY2UoeHNsSW5VUkkpKTsKLS8vIFBlcmZvcm0gdGhlIHRyYW5zZm9ybWF0aW9uIGZyb20gYSBTdHJlYW1Tb3VyY2UgdG8gYSBTdHJlYW1SZXN1bHQ7Ci10cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZSh4bWxJblVSSSksCi0gICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVJlc3VsdChuZXcgRmlsZU91dHB1dFN0cmVhbShodG1sT3V0VVJJKSkpOzwvc291cmNlPgotPHA+Rm9yIGEgd29ya2luZyBzYW1wbGUgdGhhdCBpbGx1c3RyYXRlcyB0aGlzIHVzYWdlIHBhdHRlcm4sIHNlZSA8bGluayBpZHJlZj0ic2FtcGxlcyIgYW5jaG9yPSJ4c2x0YzIiPkpBWFBUcmFuc2xldE11bHRpcGxlVHJhbnNmb3JtYXRpb25zPC9saW5rPi48L3A+Ci08L3MzPgotPC9zMj48YW5jaG9yIG5hbWU9Im5hdGl2ZV9hcGkiLz4KLTxzMiB0aXRsZT0iQ2FsbGluZyBYU0xUQyB3aXRoIHRoZSBuYXRpdmUgQVBJIj4KLTxwPlRoaXMgc2VjdGlvbiBkZW1vbnN0cmF0ZXMgaG93IHRvIHVzZSB0aGUgbmF0aXZlIFhTTFRDIEFQSSBpbiBhIHN0YW5kYWxvbmUgSmF2YSBhcHBsaWNhdGlvbi48L3A+IAotPHA+UHJvY2Vzc2luZyBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhIHRyYW5zbGV0IGludm9sdmVzIHRocmVlIG1haW4gc3RlcHM6PC9wPgotPG9sPiAKLSAgPGxpPjxsaW5rIGFuY2hvcj0ibmF0aXZlX2NvbXBpbGUiPkNvbXBpbGUgdGhlIHN0eWxlc2hlZXQgdG8gYSB0cmFuc2xldDwvbGluaz4uPC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0ibmF0aXZlX3BhcnNlIj5QYXJzZSB0aGUgaW5wdXQgWE1MIGRvY3VtZW50PC9saW5rPi48L2xpPiAKLSAgPGxpPjxsaW5rIGFuY2hvcj0ibmF0aXZlX3RyYW5zZm9ybSI+VXNlIHRoZSB0cmFuc2xldCB0byB0cmFuc2Zvcm0gdGhlIFhNTCBkb2N1bWVudDwvbGluaz4uPC9saT4KLTwvb2w+PGFuY2hvciBuYW1lPSJuYXRpdmVfb3ZlcnZpZXciLz4KLTxzMyB0aXRsZT0iQ29kZSBvdmVydmlldyI+Ci08cD5Yc2x0QXBwLmphdmEgaWxsdXN0cmF0ZXMgdGhlIGJhc2ljIHN0cnVjdHVyZSBmb3IgY29kaW5nIGEgdHJhbnNmb3JtYXRpb24gd2l0aCB0aGUgbmF0aXZlIFhTTFRDIEFQSS4gSW4gdGhlIGZvbGxvd2luZyBsaXN0aW5nLCB0aGUgbWV0aG9kIGZvciBwZXJmb3JtaW5nIGVhY2ggb2YgdGhlIHRocmVlIHN0ZXBzIGlzIGFuIGVtcHR5IHNoZWxsLiBUaGUgbWV0aG9kcyBhcmUgZmlsbGVkIGluIHRoZSBsaXN0aW5ncyBpbiBzdWJzZXF1ZW50IHNlY3Rpb25zLjwvcD4KLTxzb3VyY2U+aW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NSW1wbDsKLQotcHVibGljIGNsYXNzIFhzbHRBcHAgewotICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7Ci0gICAgWHNsdEFwcCBwcm9jID0gbmV3IFhzbHRBcHAoKTsKLSAgICBwcm9jLnJ1bihhcmdzKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHJ1bihTdHJpbmdbXSBhcmdzKSB7Ci0gICAgaWYgKGFyZ3MubGVuZ3RoICE9IDIpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6XG5cdHByb2Nlc3NvciAmbHQ7eG1sZmlsZSZndDsgJmx0O3hzbGZpbGUmZ3Q7IiArCi0gICAgICAgICAgICAiXG5cblx0d2hlcmUgJmx0O3htbGZpbGUmZ3Q7ID0geG1sIGlucHV0IGZpbGVuYW1lLCBhbmQiICsKLSAgICAgICAgICAgICJcblx0ICAgICAgJmx0O3hzbGZpbGUmZ3Q7ID0gc3R5bGVzaGVldCBmaWxlbmFtZS4iKTsKLSAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgIH0KLSAgICBTdHJpbmcgeG1sZG9jRmlsZW5hbWUgICAgID0gYXJnc1swXTsKLSAgICBTdHJpbmcgc3R5bGVzaGVldEZpbGVuYW1lID0gYXJnc1sxXTsKLQotICAgIC8vIENvbXBpbGUgdGhlIHN0eWxlc2hlZXQgdG8gYSB0cmFuc2xldAotICAgIFRyYW5zbGV0IHRyYW5zbGV0ID0gY29tcGlsZVN0eWxlc2hlZXQoc3R5bGVzaGVldEZpbGVuYW1lKTsKLQotICAgIC8vIFBhcnNlIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQKLSAgICBET01JbXBsIGRvbSA9IGdldERPTSh4bWxkb2NGaWxlbmFtZSk7Ci0KLSAgICAvLyBUcmFuc2Zvcm0gdGhlIFhNTCBkb2N1bWVudCBhZ2FpbnN0IHRoZSB0cmFuc2xldAotICAgIGRvVHJhbnNmb3JtKHRyYW5zbGV0LCBkb20pOwotICAgIFN5c3RlbS5leGl0KDApOwotICB9Ci0gIAotICAvLyBjb21waWxlIHRoZSBzdHlsZXNoZWV0IFtFbXB0eSBzaGVsbDogc2VlIGJlbG93XQotICBwcml2YXRlIFRyYW5zbGV0IGNvbXBpbGVTdHlsZXNoZWV0KFN0cmluZyBzdHlsZXNoZWV0TmFtZSkgeyByZXR1cm4gbnVsbDsgfQotCi0gIC8vIHBhcnNlIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQgW0VtcHR5IHNoZWxsOiBzZWUgYmVsb3ddCi0gIHByaXZhdGUgRE9NSW1wbCBnZXRET00oU3RyaW5nIHhtbGRvY25hbWUpIHsgcmV0dXJuIG51bGw7IH0KLQotICAvLyB0cmFuc2Zvcm0gdGhlIFhNTCBkb2N1bWVudCBbRW1wdHkgc2hlbGw6IHNlZSBiZWxvd10KLSAgcHJpdmF0ZSB2b2lkIGRvVHJhbnNmb3JtKFRyYW5zbGV0IHRyYW5zbGV0LCBET01JbXBsIGRvbSkgeyB9Ci19PC9zb3VyY2U+Ci0KLTxwPlhzbHRBcHAgdGFrZXMgdHdvIGNvbW1hbmQgbGluZSBhcmd1bWVudHM6IHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQgZmlsZW5hbWUsIGFuZCB0aGUKLVhTTCBzdHlsZXNoZWV0IGZpbGVuYW1lLiBUaGUgcHVibGljIHJ1bigpIG1ldGhvZCBwcm9jZXNzZXMgdGhlIGNvbW1hbmRsaW5lIGFyZ3MsCi1hbmQgdGhlbiBjYXJyaWVzIG91dCB0aGUgdGhyZWUgc3RlcHMuPC9wPiAKLTxwPlRoZSBmaXJzdCBzdGVwIGlzIGFjY29tcGxpc2hlZCBieSBjYWxsaW5nIHRoZSBjb21waWxlU3R5bGVzaGVldCgpIG1ldGhvZC4gVGhpcyBtZXRob2QKLXRha2VzIHRoZSBzdHlsZXNoZWV0IGZpbGVuYW1lIGFzIGlucHV0IChTdHJpbmcpLCBhbmQgcmV0dXJucyBhbiBpbnN0YW5jZQotb2YgdGhlIHRyYW5zbGV0LCBhcyB0eXBlIG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQuPC9wPgotCi08cD5UaGUgaW5wdXQgWE1MIGRvY3VtZW50IG5vdyBuZWVkcyB0byBiZSBwYXJzZWQuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IHRoZSBnZXRET00oKSBtZXRob2QuIFRoaXMgbWV0aG9kIHRha2VzIHRoZSBYTUwgZG9jdW1lbnQncyBmaWxlbmFtZSAoU3RyaW5nKQotYW5kIHJldHVybnMgdGhlIERvY3VtZW50IE9iamVjdCBNb2RlbCBmb3IgdGhlIGRvY3VtZW50LCBhcyBhbiBvYmplY3Qgb2YKLXR5cGUgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NSW1wbC4gPC9wPgotCi08cD5GaW5hbGx5LCB0aGUgdHJhbnNmb3JtYXRpb24gcHJlc2NyaWJlZCBieSB0aGUgc3R5bGVzaGVldCBpcyBjYXJyaWVkIG91dCBieQotY2FsbGluZyB0aGUgZG9UcmFuc2Zvcm0oKSBtZXRob2QuIFRoaXMgbWV0aG9kIHRha2VzIHRoZSB0cmFuc2xldCAoY29tcGlsZWQKLXN0eWxlc2hlZXQpIGFuZCB0aGUgZG9tIChEb2N1bWVudCBPYmplY3QgTW9kZWwgZm9yIHRoZSBYTUwgZG9jdW1lbnQpIGFzCi1pbnB1dCBwYXJhbWV0ZXJzLiBJbiB0aGlzIGV4YW1wbGUsIHRoZSByZXN1bHRzIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBhcmUKLW91dHB1dCB0byBzdGFuZGFyZCBvdXRwdXQsIHNvIHRoaXMgbWV0aG9kIHJldHVybnMgbm90aGluZy4gPC9wPgotCi08cD5JZiBhbGwgdGhyZWUgc3RlcHMgYXJlIGNhcnJpZWQgb3V0IHN1Y2Nlc3NmdWxseSwgdGhlIGFwcGxpY2F0aW9uIGV4aXRzIHdpdGgKLWEgc3VjY2Vzc2Z1bCAoemVybykgdmFsdWUuPC9wPgotCi08cD5UaGUgZm9sbG93aW5nIHNlY3Rpb25zIGV4YW1pbmUgZWFjaCBvZiB0aGUgdGhyZWUgc3RlcHMgaW4gZGV0YWlsLjwvcD4KLTwvczM+PGFuY2hvciBuYW1lPSJuYXRpdmVfY29tcGlsZSIvPgotPHMzIHRpdGxlPSIxLiBDb21waWxpbmcgdGhlIFN0eWxlc2hlZXQgdG8gYSBUcmFuc2xldCI+Ci08cD5UaGUgJ2NvbXBpbGVTdHlsZXNoZWV0JyBtZXRob2Q6PC9wPgotCi08c291cmNlPmltcG9ydCBqYXZhLmlvLkZpbGU7Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOyAKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlhTTFRDOwotLi4uCi0gIHByaXZhdGUgVHJhbnNsZXQgY29tcGlsZVN0eWxlc2hlZXQoU3RyaW5nIHN0eWxlc2hlZXROYW1lKSB7Ci0gICAgVHJhbnNsZXQgcmV0dmFsID0gbnVsbDsKLSAgICBTdHJpbmcgdHJhbnNsZXROYW1lID0gc3R5bGVzaGVldE5hbWUuc3Vic3RyaW5nKDAsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0TmFtZS5pbmRleE9mKCcuJykpOwotICAgIHRyeSB7Ci0gICAgICBYU0xUQyB4c2x0YyA9IG5ldyBYU0xUQygpOwotICAgICAgeHNsdGMuaW5pdCgpOwotICAgICAgRmlsZSBzdHlsZXNoZWV0ID0gbmV3IEZpbGUoc3R5bGVzaGVldE5hbWUpOwotICAgICAgeHNsdGMuY29tcGlsZShzdHlsZXNoZWV0LnRvVVJMKCkpOwotICAgICAgQ2xhc3MgY2xhenogPSBDbGFzcy5mb3JOYW1lKHRyYW5zbGV0TmFtZSk7Ci0gICAgICByZXR2YWwgPSAoVHJhbnNsZXQpY2xhenoubmV3SW5zdGFuY2UoKTsKLSAgICB9IAotICAgIGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewotICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDb3VsZCBub3QgY3JlYXRlIFVSTCB0byBzdHlsZXNoZWV0IGZpbGU6ICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0TmFtZSArICIuXG4iICsgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICAgfSAKLSAgICBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvdWxkIG5vdCBmaW5kIGNsYXNzIGZpbGU6ICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xldE5hbWUgKyAiLmNsYXNzIC5cbiIgKyBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICBTeXN0ZW0uZXhpdCgxKTsKLSAgICB9IAotICAgIGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ291bGQgbm90IGluc3RhbnRpYXRlIGNsYXNzIGZpbGU6ICIgKwotICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xldE5hbWUgKyAiLmNsYXNzIC5cbiIgKyBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICBTeXN0ZW0uZXhpdCgxKTsKLSAgICB9IAotICAgIGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ291bGQgbm90IGluc3RhbnRpYXRlIGNsYXNzIGZpbGU6ICIgKwotICAgICAgICAgICAgdHJhbnNsZXROYW1lICsgIi5jbGFzcywgaWxsZWdhbCBhY2Nlc3MuXG4iICsgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICAgfQotICAgIHJldHVybiByZXR2YWw7Ci0gIH08L3NvdXJjZT4KLQotPHA+VGhpcyBtZXRob2QgcmVhZHMgaW4gdGhlIHN0eWxlc2hlZXQgZmlsZSwgY29tcGlsZXMgaXQgdG8gSmF2YSBieXRlY29kZXMgCi0odGhlIHRyYW5zbGV0KSwgYW5kIHRoZW4gd3JpdGVzIHRoZSBieXRlY29kZXMgdG8gdGhlIGZpbGVzeXN0ZW0sIGFzIGEgCi1zZXJpZXMgb2YgLmNsYXNzIGZpbGVzLiBUaGVpciBiYXNlIG5hbWUgaXMgZGVyaXZlZCBmcm9tIHRoZSBuYW1lIG9mIHRoZSAKLXN0eWxlc2hlZXQuIDwvcD4KLQotPHA+VGhlIFhTTFQgY29tcGlsZXIgb2JqZWN0IChvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyLlhTTFRDKSwgaXMgY3JlYXRlZCwKLWluaXRpYWxpemVkIGFuZCB0aGVuIGl0cyBjb21waWxlKCkgbWV0aG9kIGlzIGNhbGxlZCBwYXNzaW5nIGluIGEgVVJMCi10byB0aGUgc3R5bGVzaGVldCBpdHNlbGYuIE9uY2UgdGhlIC5jbGFzcyBmaWxlcyBoYXZlIGJlZW4gd3JpdHRlbiwKLXRoZSB0cmFuc2xldCBpcyBpbnN0YW50aWF0ZWQgdXNpbmcgSmF2YSByZWZsZWN0aW9uIHRvIGNyZWF0ZSB0aGUgQ2xhc3MKLWFuZCB0aGVuIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBDbGFzcyBhcyAncmV0dmFsJyBvZiB0eXBlIAotb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldC4gPC9wPgotCi08cD5Ob3RpY2UgYWxsIG9mIHRoZSB2YXJpb3VzIGV4Y2VwdGlvbnMgdGhhdCBjb3VsZCBiZSB0aHJvd24gaW4gdGhlIHByb2Nlc3MKLWhhdmUgYmVlbiBoYW5kbGVkIHdpdGggZXhwbGljaXQgd2FybmluZyBtZXNzYWdlcyBhbmQgYSBTeXN0ZW0uZXhpdCB3aXRoIGEgbm9uLXplcm8gcmV0dXJuIHZhbHVlLiAKLUluIHlvdXIgYXBwbGljYXRpb25zLCB5b3UgbWF5IHdhbnQgdG8gaGFuZGxlIHRoZXNlIGV4Y2VwdGlvbnMgZGlmZmVyZW50bHkuPC9wPgotCi08L3MzPjxhbmNob3IgbmFtZT0ibmF0aXZlX3BhcnNlIi8+Ci08czMgdGl0bGU9IjIuIFBhcnNpbmcgdGhlIFhNTCBEb2N1bWVudCI+Ci0KLTxwPlBhcnNpbmcgdGhlIGlucHV0IFhNTCBkb2N1bWVudCBpcyBoYW5kbGVkIGluIHRoZSBnZXRET00oKSBtZXRob2Q6PC9wPgotCi08c291cmNlPmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlckZhY3Rvcnk7Ci1pbXBvcnQgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyOwotaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLlBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb247Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5Db25zdGFudHM7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRFRETW9uaXRvcjsKLWltcG9ydCBvcmcueG1sLnNheC5YTUxSZWFkZXI7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotLi4uCi0gIHByaXZhdGUgRFRETW9uaXRvciBfZHRkTW9uaXRvciA9IG51bGw7Ci0KLSAgcHJpdmF0ZSBET01JbXBsIGdldERPTShTdHJpbmcgeG1sZG9jbmFtZSkgewotICAgIGZpbmFsIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICB0cnkgewotICAgICAgZmFjdG9yeS5zZXRGZWF0dXJlKENvbnN0YW50cy5OQU1FU1BBQ0VfRkVBVFVSRSwgdHJ1ZSk7Ci0gICAgfSAKLSAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLSAgICAgIGZhY3Rvcnkuc2V0TmFtZXNwYWNlQXdhcmUodHJ1ZSk7Ci0gICAgfQotICAgIGZpbmFsIERPTUltcGwgZG9tID0gbmV3IERPTUltcGwoKTsKLSAgICBkb20uc2V0RG9jdW1lbnRVUkkoeG1sZG9jbmFtZSk7Ci0gICAgWE1MUmVhZGVyIHJlYWRlciA9IG51bGw7Ci0gICAgU0FYUGFyc2VyIHBhcnNlciA9IG51bGw7Ci0gICAgX2R0ZE1vbml0b3IgPSBuZXcgRFRETW9uaXRvcigpOwotICAgIHRyeSB7Ci0gICAgICBwYXJzZXIgPSBmYWN0b3J5Lm5ld1NBWFBhcnNlcigpOwotICAgICAgcmVhZGVyID0gcGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgICAgcmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKGRvbS5nZXRCdWlsZGVyKCkpOwotICAgICAgX2R0ZE1vbml0b3IuaGFuZGxlRFREKHJlYWRlcik7Ci0gICAgICByZWFkZXIucGFyc2UoeG1sZG9jbmFtZSk7Ci0gICAgfSAKLSAgICBjYXRjaCAoUGFyc2VyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBlKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlNBWCBQYXJzZXIgaXMgbm90IGNvbmZpZ3VyZWQgcHJvcGVybHkuXG4iKwotICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICBTeXN0ZW0uZXhpdCgxKTsKLSAgICB9IAotICAgIGNhdGNoIChTQVhFeGNlcHRpb24gZSApIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiU0FYIFBhcnNlciBjb3VsZCBub3QgYmUgY3JlYXRlZC5cbiIrCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgIH0gCi0gICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUgKSB7Ci0gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlhNTCBSZWFkZXIgY291bGQgbm90IHJlYWQgeG1sIGRvY3VtZW50ICciKwotICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxkb2NuYW1lICsgIicsIiArIGUuZ2V0TWVzc2FnZSgpKTsKLSAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgIH0KLSAgICByZXR1cm4gZG9tOwotICB9PC9zb3VyY2U+Ci0KLTxwPlRoZSBtZXRob2QgcGFyc2VzIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQgYW5kIGNyZWF0ZXMgYSBEb2N1bWVudAotT2JqZWN0IE1vZGVsIHRvIHJldHVybiB0byB0aGUgcnVuKCkgbWV0aG9kIGZvciBsYXRlciB1c2UuIFRvIHBhcnNlIHRoZSAKLWRvY3VtZW50IHdlIHVzZSBhIGphdmF4LnhtbC5wYXJzZXJzLlNBWFBhcnNlciwgZnJvbSB0aGUgSkFYUC4gIFRoZSBKQVhQCi1tb2RlbCB1c2VzIGEgZmFjdG9yeSBtZXRob2Q7IGFjY29yZGluZ2x5IHdlIGZpcnN0IGNyZWF0ZSB0aGUgZmFjdG9yeSwKLXdoaWNoIGlzIG9mIHR5cGUgamF2YXgueG1sLnBhcnNlcnMuU0FYUGFyc2VyRmFjdG9yeS4gQWZ0ZXIgY29uZmlndXJpbmcgCi10aGUgZmFjdG9yeSB0byBoYW5kbGUgbmFtZXNwYWNlcywgdGhlIHByb2NlZHVyZSBnZXRzIGFuIG9yZy54bWwuc2F4LlhNTFJlYWRlcgotZnJvbSB0aGUgU0FYUGFyc2VyLiBUaGUgcmVhZGVyIGlzIHJlZ2lzdGVyZWQKLXdpdGggdGhlIGNsYXNzIERURE1vbml0b3IsIGFuZCB0aGVuIHRoZSByZWFkZXIgaXMgaW5zdHJ1Y3RlZCB0byBwYXJzZQotdGhlIFhNTCBkb2N1bWVudC4gVGhlIERPTUltcGwgb2JqZWN0IGlzIHJldHVybmVkIHRvIHRoZSBtYWluKCkgbWV0aG9kLjwvcD4gCi0KLTxub3RlPkJlZm9yZSB0aGUgZG9jdW1lbnQgaXMgcGFyc2VkLCB0aGUgRE9NSW1wbCBpcyBjb25maWd1cmVkIHdpdGggdGhlCi1YTUwgZG9jdW1lbnQncyBVUkkgd2l0aCBhIGNhbGwgdG8gdGhlIHNldERvY3VtZW50VVJJKCkgbWV0aG9kLiBUaGlzCi1pcyBuZWNlc3NhcnkgdG8gZGVmaW5lIHRoZSBvcmlnaW4gb2YgdGhlIGRvY3VtZW50IGZyb20gd2hpY2ggdGhlIERPTSB0cmVlCi1pcyBidWlsdC4gVGhpcyBpbmZvcm1hdGlvbiBpcyBuZWVkZWQgZm9yIHhzbDppbXBvcnQsIHhzbDppbmNsdWRlLCBhbmQKLXRoZSBkb2N1bWVudCgpIGZ1bmN0aW9uLjwvbm90ZT4KLTwvczM+PGFuY2hvciBuYW1lPSJuYXRpdmVfdHJhbnNmb3JtIi8+Ci08czMgdGl0bGU9IjMuIERvaW5nIHRoZSBUcmFuc2Zvcm1hdGlvbiI+Ci0KLTxwPk5vdyBldmVyeXRoaW5nIGlzIHNldCB0byBjYXJyeSBvdXQgdGhlIFhTTCB0cmFuc2Zvcm1hdGlvbi4gVGhlIGRvVHJhbnNmb3JtKCkKLW1ldGhvZCB0YWtlcyBhIHJlZmVyZW5jZSB0byB0aGUgVHJhbnNsZXQgb2JqZWN0IGdlbmVyYXRlZCAKLWZyb20gdGhlIHN0eWxlc2hlZXQsIGFuZCB0aGUgRE9NSW1wbCBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBYTUwgZG9jdW1lbnQuPC9wPgotCi08c291cmNlPmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMucnVudGltZS5EZWZhdWx0U0FYT3V0cHV0SGFuZGxlcjsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuVGV4dE91dHB1dDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLlRyYW5zbGV0RXhjZXB0aW9uOwotLi4uCi0gIHByaXZhdGUgdm9pZCBkb1RyYW5zZm9ybShUcmFuc2xldCB0cmFuc2xldCwgRE9NSW1wbCBkb20pIHsKLSAgICBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlciBvdXRwdXRoYW5kbHIgPSBudWxsOwotICAgIFRleHRPdXRwdXQgdGV4dG91dHB1dCA9IG51bGw7Ci0gICAgdHJ5IHsKLSAgICAgIG91dHB1dGhhbmRscj0gbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKFN5c3RlbS5vdXQsICJ1dGYtOCIpOwotICAgICAgdGV4dG91dHB1dCA9IG5ldyBUZXh0T3V0cHV0KG91dHB1dGhhbmRsciwgInV0Zi04Iik7Ci0gICAgfSAKLSAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDb3VsZCBub3QgY3JlYXRlIFNBWCBPdXRwdXQgSGFuZGxlci4iKwotICAgICAgICAgICAgICAgICAgICAgICAgICBlLmdldE1lc3NhZ2UoKSk7Ci0gICAgICBTeXN0ZW0uZXhpdCgxKTsKLSAgICB9Ci0gIAotICAgIC8vIGZvciBYU0wga2V5cwotICAgIEFic3RyYWN0VHJhbnNsZXQgYWJzVHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldDsKLSAgICBhYnNUcmFuc2xldC5zZXRJbmRleFNpemUoZG9tLmdldFNpemUoKSk7Ci0gICAgX2R0ZE1vbml0b3IuYnVpbGRJZEluZGV4KGRvbSwgMCwgYWJzVHJhbnNsZXQpOwotCi0gICAgdHJ5IHsKLSAgICAgIGFic1RyYW5zbGV0LnRyYW5zZm9ybShkb20sIHRleHRvdXRwdXQpOwotICAgIH0gCi0gICAgY2F0Y2ggKFRyYW5zbGV0RXhjZXB0aW9uIGUpIHsKLSAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ291bGQgbm90IHRyYW5zZm9ybSBYTUwgZG9jdW1lbnQuIisKLSAgICAgICAgICAgICAgICAgICAgICAgICAgZS5nZXRNZXNzYWdlKCkpOwotICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICAgfQotICB9PC9zb3VyY2U+Ci0KLTxwPlRoZSBUcmFuc2xldCdzIHRyYW5zZm9ybSgpIG1ldGhvZCB0YWtlcyB0d28gYXJndW1lbnRzOiB0aGUgRE9NSW1wbAotcmVmZXJlbmNlIGNyZWF0ZWQgaW4gdGhlIGdldERPTSgpIG1ldGhvZCwgYW5kIGFuIHhzbHRjLnJ1bnRpbWUuVGV4dE91dHB1dAotb2JqZWN0LiBUZXh0T3V0cHV0IGlzIGEgQ29udGVudEhhbmRsZXIgd3JhcHBlciBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlCi14c2x0Yy5UcmFuc2xldE91dHB1dEhhbmRsZXIgaW50ZXJmYWNlLiBJbiB0aGlzIGV4YW1wbGUsIHRoZSBjb250ZW50Ci1oYW5kbGVyIChEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcikgaXMgd3JhcHBlZC48L3A+ICAgICAKLQotPHA+VHJhbnNsZXQgaXMgYW4gaW50ZXJmYWNlLiBBYnN0cmFjdFRyYW5zbGV0IGlzIGEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoYXQKLWludGVyZmFjZS4gQmVmb3JlIHRoZSB0cmFuc2Zvcm0oKSBtZXRob2QgaXMgY2FsbGVkLCBzZXRJbmRleFNpemUoaW50KQotaXMgY2FsbGVkIHRvIHBhc3MgaW4gdGhlIG1heGltdW0gRE9NIHNpemUgdG8gdGhlIHRyYW5zbGV0IGFuZCB0aGUgRFRETW9uaXRvcgotaXMgY2FsbGVkIHRvIGJ1aWxkIHRoZSBub2RlIGluZGV4IHRoYXQgdGhlIEtleSAoeHNsOmtleSBpbXBsZW1lbnRhdGlvbikKLWNsYXNzIHVzZXMuIFRoaXMgaXMgYSBnZW5lcmFsIGNhc2UsIGlmIHlvdSBhcmUgbm90IHVzaW5nIGtleXMsIHRoZW4geW91Ci1kbyBub3QgbmVlZCB0byBzZXQgdGhlIGluZGV4IHNpemUsIGNvbnNlcXVlbnRseSB5b3Ugd291bGQgbm90IG5lZWQgdG8KLXdvcmsgd2l0aCB0aGUgQWJzdHJhY3RUcmFuc2xldCBlaXRoZXIuIEluIHRoYXQgY2FzZSwgeW91IGNhbiAgdXNlIHRoZQotVHJhbnNsZXQgZGlyZWN0bHkgYnkgY2FsbGluZyB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCB0ZXh0b3V0cHV0KS4gPC9wPgotPC9zMz48YW5jaG9yIG5hbWU9Im5hdGl2ZV9jb25jbHVzaW9uIi8+Ci08czMgdGl0bGU9IkNvbmNsdXNpb24iPgotPHA+VGhlIG5hdGl2ZSBYU0xUIGNvbXBpbGVyIEFQSSBwcm92aWRlcyBhIHdheSB0byBjb21waWxlIGFuIFhTTCBzdHlsZXNoZWV0Ci1pbnRvIGEgdHJhbnNsZXQuIFRoZSB0cmFuc2xldCBjYW4gdGhlbiBiZSB1c2VkIHRvIHRyYW5zZm9ybSB0aGUgRE9NSW1wbAotb2YgYW4gaW5wdXQgWE1MIGRvY3VtZW50LiAgIFRoaXMgZXhhbXBsZSBkZW1vbnN0cmF0ZWQgaG93IHRvIGNvbXBpbGUgYQotc3R5bGVzaGVldCBpbnRvIGEgdHJhbnNsZXQsIHBhcnNlIGFuIGlucHV0IFhNTCBkb2N1bWVudCwgYW5kIHRoZW4gdHJhbnNmb3JtCi10aGUgWE1MIGRvY3VtZW50IHVzaW5nIHRoZSB0cmFuc2xldC48L3A+Ci08L3MzPjwvczI+PGFuY2hvciBuYW1lPSJjb25zdHJhaW50cyIvPgotPHMyIHRpdGxlPSJYU0xUQyB1c2FnZSBjb25zdHJhaW50cyI+Ci08cD5TZWUgPGxpbmsgaWRyZWY9InJlYWRtZSIgYW5jaG9yPSJ4c2x0Y2NvbmYiPkNvbmZvcm1hbmNlIGlzc3VlczwvbGluaz4gYW5kIDxsaW5rIGlkcmVmPSJyZWFkbWUiIAotYW5jaG9yPSJ4c2x0Y2tub3ducHJvYmxlbXMiPktub3duIHByb2JsZW1zPC9saW5rPi48L3A+Ci08L3MyPgotPC9zMT4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hhbGFuZGVzaWduLnhtbCBiL3hkb2NzL3NvdXJjZXMveGFsYW5kZXNpZ24ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3MDJkYTI4Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveGFsYW5kZXNpZ24ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci08IURPQ1RZUEUgYm9vayBTWVNURU0gInNiazovc3R5bGUvZHRkL2Jvb2suZHRkIj4KLQotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDAgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAwLCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLQotPGJvb2sgdGl0bGU9IlhhbGFuIDIuMC4wIERlc2lnbiIgY29weXJpZ2h0PSIyMDAwIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiI+Ci0gCi0gIDxkb2N1bWVudCBpZD0iZGVzaWduMl8wXzAiCi0gICAgICAgICAgICBsYWJlbD0iWGFsYW4tSiAyLjAuMCBEZXNpZ24iCi0gICAgICAgICAgICBzb3VyY2U9ImRlc2lnbi9kZXNpZ24yXzBfMC54bWwiLz4gICAgCi08L2Jvb2s+Ci0gIApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDM0ZmI2OTIuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw2OSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLTwhRE9DVFlQRSBib29rIFNZU1RFTSAic2JrOi9zdHlsZS9kdGQvYm9vay5kdGQiPgotCi08Ym9vayB0aXRsZT0iWFNMVEMgRGVzaWduIiBjb3B5cmlnaHQ9IjIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIj4KLSAKLSAgPGRvY3VtZW50IGlkPSJpbmRleCIKLSAgICAgICAgICAgIGxhYmVsPSJPdmVydmlldyIKLSAgICAgICAgICAgIHNvdXJjZT0ieHNsdGMvaW5kZXgueG1sIi8+Ci0KLSA8c2VwYXJhdG9yLz4KLQotICA8ZG9jdW1lbnQgaWQ9InhzbHRjX2NvbXBpbGVyIgotICAgICAgICAgICAgbGFiZWw9IkNvbXBpbGVyIGRlc2lnbiIKLSAgICAgICAgICAgIHNvdXJjZT0ieHNsdGMveHNsdGNfY29tcGlsZXIueG1sIi8+Ci0KLSA8c2VwYXJhdG9yLz4KLSAKLSAgIDxkb2N1bWVudCBpZD0ieHNsX3doaXRlc3BhY2VfZGVzaWduIgotICAgICAgICAgICAgbGFiZWw9IldoaXRlc3BhY2UiCi0gICAgICAgICAgICBzb3VyY2U9InhzbHRjL3hzbF93aGl0ZXNwYWNlX2Rlc2lnbi54bWwiLz4KLQotICA8ZG9jdW1lbnQgaWQ9InhzbF9zb3J0X2Rlc2lnbiIKLSAgICAgICAgICAgIGxhYmVsPSJ4c2w6c29ydCIKLSAgICAgICAgICAgIHNvdXJjZT0ieHNsdGMveHNsX3NvcnRfZGVzaWduLnhtbCIvPiAKLQotICA8ZG9jdW1lbnQgaWQ9InhzbF9rZXlfZGVzaWduIgotICAgICAgICAgICAgbGFiZWw9IktleXMiCi0gICAgICAgICAgICBzb3VyY2U9InhzbHRjL3hzbF9rZXlfZGVzaWduLnhtbCIvPiAKLQotICA8ZG9jdW1lbnQgaWQ9InhzbF9jb21tZW50X2Rlc2lnbiIKLSAgICAgICAgICAgIGxhYmVsPSJDb21tZW50IGRlc2lnbiIKLSAgICAgICAgICAgIHNvdXJjZT0ieHNsdGMveHNsX2NvbW1lbnRfZGVzaWduLnhtbCIvPgotIAotICA8c2VwYXJhdG9yLz4KLQotICA8ZG9jdW1lbnQgaWQ9InhzbF9sYW5nX2Rlc2lnbiIKLSAgICAgICAgICAgIGxhYmVsPSJsYW5nKCkiCi0gICAgICAgICAgICBzb3VyY2U9InhzbHRjL3hzbF9sYW5nX2Rlc2lnbi54bWwiLz4gCi0KLSAgPGRvY3VtZW50IGlkPSJ4c2xfdW5wYXJzZWRfZGVzaWduIgotICAgICAgICAgICAgbGFiZWw9IlVucGFyc2VkIGVudGl0aWVzIgotICAgICAgICAgICAgc291cmNlPSJ4c2x0Yy94c2xfdW5wYXJzZWRfZGVzaWduLnhtbCIvPiAKLSAgCi0gPHNlcGFyYXRvci8+Ci0gICAKLSAgPGRvY3VtZW50IGlkPSJ4c2x0Y19ydW50aW1lIgotICAgICAgICAgICAgbGFiZWw9IlJ1bnRpbWUiCi0gICAgICAgICAgICBzb3VyY2U9InhzbHRjL3hzbHRjX3J1bnRpbWUueG1sIi8+IAotICAgICAgICAgICAgCi0gPHNlcGFyYXRvci8+Ci0KLSAgPGRvY3VtZW50IGlkPSJ4c2x0Y19kb20iCi0gICAgICAgICAgICBsYWJlbD0iSW50ZXJuYWwgRE9NIgotICAgICAgICAgICAgc291cmNlPSJ4c2x0Yy94c2x0Y19kb20ueG1sIi8+ICAgICAgICAgICAgCi0gICAgICAgICAgICAKLSAgPGRvY3VtZW50IGlkPSJ4c2x0Y19uYW1lc3BhY2UiCi0gICAgICAgICAgICBsYWJlbD0iTmFtZXNwYWNlcyIKLSAgICAgICAgICAgIHNvdXJjZT0ieHNsdGMveHNsdGNfbmFtZXNwYWNlLnhtbCIvPiAgICAgICAgICAgICAKLSAgICAgICAgICAgIAotIDxzZXBhcmF0b3IvPgotIAotICAgPGRvY3VtZW50IGlkPSJ4c2x0Y190cmF4IgotICAgICAgICAgICAgIGxhYmVsPSJUcmFuc2xldCAmYW1wOyBUckFYIgotICAgICAgICAgICAgIHNvdXJjZT0ieHNsdGMveHNsdGNfdHJheC54bWwiLz4KLSA8c2VwYXJhdG9yLz4KLSA8ZXh0ZXJuYWwgaHJlZj0idG9kby5odG1sIiBsYWJlbD0iVG8tZG8gbGlzdCIvPgotICAgICAgICAgICAgCi08L2Jvb2s+Ci0gIApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvRE9NSW50ZXJmYWNlLmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvRE9NSW50ZXJmYWNlLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGY4OTE5ZS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL0RPTUludGVyZmFjZS5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL0RPTUxvY2tpbmcuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9ET01Mb2NraW5nLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggY2FlMzNiNC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL0RPTUxvY2tpbmcuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTdiNDk4ZS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRQorKysgL2Rldi9udWxsCkBAIC0xLDI0NiArMCwwIEBACi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICAgICAgICAgUkVBRE1FIEZJTEUgRk9SIFRIRSBTVU4gWFNMVCBDT01QSUxFUgotICAgICAgICAgICAgICAgICBQcmV2aWV3IFZlcnNpb24gNiAKLSAgICAgICAgICAgICAgICAgICAgQXByaWwsIDIwMDEKLSAgICAgICAgICAgQ29weXJpZ2h0IChjKSBTdW4gTWljcm9zeXN0ZW1zLCAyMDAxCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotCi1UaGUgU3VuIFhTTFQgQ29tcGlsZXIgKFhTTFRDKSBpcyBhIEphdmEtYmFzZWQgdG9vbCBmb3IgY29tcGlsaW5nIFhTTCAKLXN0eWxlc2hlZXRzIGludG8gZXh0cmVtZWx5IGxpZ2h0d2VpZ2h0IGFuZCBwb3J0YWJsZSBKYXZhIGJ5dGUgY29kZS4gCi1UaGUgU3VuIFhTTFRDIEphdmEgUnVudGltZSBlbnZpcm9ubWVudCBjYW4gdGhlbiBwcm9jZXNzIFhNTCBmaWxlcyAKLWFnYWluc3QgdGhlc2UgY29tcGlsZWQgc3R5bGVzaGVldHMgKFRyYW5zbGV0cykgdG8gZ2VuZXJhdGUgYW55IG1hbm5lciAKLW9mIG91dHB1dCBwZXIgdGhlIHN0eWxlLXNoZWV0IGluc3RydWN0aW9ucy4KLQotVGhpcyBwcmV2aWV3IHZlcnNpb24gb2YgdGhlIFhTTFQgQ29tcGlsZXIgY2FuIGJlIHJ1biBvbiBhbnkgCi1wbGF0Zm9ybSAtLSBpbmNsdWRpbmcgVU5JWCwgV2luZG93cywgTlQsIE1hYyAtLSB0aGF0IHN1cHBvcnRzIAotSmF2YTIgb3IgbGF0ZXIuIFRoZSBUcmFuc2xldHMgKGNvbXBpbGVkIHN0eWxlc2hlZXRzKSBjYW4gYmUgcnVuIG9uIGFueSAKLUphdmEgcGxhdGZvcm0gaW5jbHVkaW5nIGEgUGFsbSBQaWxvdCB3aXRoIEoyTUUgQ0xEQyAKLShKYXZhIDIgTWljcm8gRWRpdGlvbiwgQ29ubmVjdGVkIExpbWl0ZWQgRGV2aWNlIENvbmZpZ3VyYXRpb24pLiAKLVdoaWxlIHRoZSBjb21waWxlciBpdHNlbGYgcmVxdWlyZXMgSmF2YTIsdHJhbnNsZXRzIGFyZSBkZXNpZ25lZCB0byBydW4gCi1hbnl3aGVyZSBKYXZhIGlzIGF2YWlsYWJsZS4KLQotQWxtb3N0IGFsbCBmdW5jdGlvbnMgb2YgdGhlIFhMU1QgMS4wIGxhbmd1YWdlIGFyZSBpbXBsZW1lbnRlZDsgCi1tb3JlIHRoYW4gZW5vdWdoIHRvIHNob3cgeW91IGhvdyB0aGlzIG5ldyBhcHByb2FjaCB0byBYU0xUIHdvcmtzIAotYW5kIGl0cyBhZHZhbnRhZ2VzISBVc2luZyB0aGUgc2FtcGxlcyBwcm92aWRlZCwgeW91IHdpbGwgYmUgYWJsZSAKLXRvIHNlZSBmb3IgeW91cnNlbGYuIEFsc28sIGRlbW9zIGZvciB0aGUgUGFsbSBQaWxvdCwgQXBwbGV0cywgYW5kIAotU2VydmxldHMgYXJlIHByb3ZpZGVkLgotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotQVRUUklCVVRJT05TCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotVGhlIFhTTFQgQ29tcGlsZXIgcHJvZ3JhbSB1c2VzIHRoZSBDVVAgUGFyc2VyIEdlbmVyYXRvcgotZm9yIEphdmEsIENvcHlyaWdodCAxOTk2LTE5OTkgYnkgU2NvdHQgSHVkc29uLCBGcmFuayBGbGFubmVyeSwKLUMuIFNjb3R0IEFuYW5pYW4uICBGb3IgbW9yZSBkZXRhaWxzLCBwbGVhc2Ugc2VlOgotaHR0cDovL3d3dy5jcy5wcmluY2V0b24uZWR1L35hcHBlbC9tb2Rlcm4vamF2YS9DVVAvCi0KLVRoZSBYU0xUIENvbXBpbGVyIHByb2dyYW0gYWxzbyB1c2VzIGEgbW9kaWZpZWQgdmVyc2lvbiBvZiB0aGUKLUJ5dGUgQ29kZSBFbmdpbmVlcmluZyBMaWJyYXJ5IChCQ0VMKSwgZm9ybWVybHkga25vd24gYXMgCi0oSmF2YUNsYXNzIEFQSSksIENvcHlyaWdodCAyMDAwIE1hcmt1cyBEYWhtLgotCi0qKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgYWRkaXRpb25hbCBwYWNrYWdlLCBCQ0VMLCBpcwotKiogbmVlZGVkIGluIG9yZGVyIHRvIGdlbmVyYXRlIHRoZSBjbGFzcyBmaWxlcyBmcm9tIHRoZSBjb21waWxlci4KLSoqIFdpdGhvdXQgdGhlIEJDRUwgcGFja2FnZSwgdGhpcyBwcmV2aWV3IHZlcnNpb24gb2YgdGhlCi0qKiBjb21waWxlciBXSUxMIE5PVCBXT1JLLiAgQkNFTCBpcyBmcmVlbHkgYXZhaWxhYmxlIGZvcgotKiogZG93bmxvYWQgYXMgZGVzY3JpYmVkIGJlbG93LgotCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotUkVRVUlSRUQgUEFDS0FHRQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLUJDRUwgKGZvcm1lcmx5IEphdmFDbGFzcykgYnkgTWFya3VzIERhaG0gaGFzIGJlZW4gCi11c2VkIHRvIGF1dG9tYXRpY2FsbHkgY3JlYXRlIGNsYXNzIGZpbGVzIGZyb20gdGhlIFhTTFQgY29tcGlsZXIgb3V0cHV0LiAgCi1Zb3UgbXVzdCBvYnRhaW4gdGhlIEJDRUwuamFyIGZpbGUgYW5kIGluc3RhbGwgaXQgYmVmb3JlIHVzaW5nIHRoZSAKLVhTTFQgY29tcGlsZXIuCi0KLVRoZSBzaW1wbGVzdCB3YXkgdG8gZG93bmxvYWQgdGhlIEJDRUwuamFyIGZpbGUgZnJvbSAKLQotICAgIGh0dHA6Ly9iY2VsLnNvdXJjZWZvcmdlLm5ldC9kb3dubG9hZHMuaHRtbAotCi1pcyB0byB1c2UgdGhlICJKQVIgZmlsZSAod2l0aG91dCBkb2NzKSIgbGluay4KLQotWW91IG1heSB3YW50IHRvIG9idGFpbiB0aGUgcHJlY29tcGlsZWQgY2xhc3MgZmlsZXMgYW5kIGRvY3VtZW50YXRpb24uCi1UbyBkb3dubG9hZCB0aGVtIHRvIGEgVW5peCBzeXN0ZW06Ci0KLSAgICAxKSBDaG9vc2UgdGhlICJsYXRlc3QgdmVyc2lvbiAoUHJlY29tcGlsZWQgKyBkb2NzKSIgCi0gICAgICAgR3ppcHBlZCBUYXItRmlsZSBvciBaSVAtRmlsZSBsaW5rLgotCi0gICAgMikgVW5wYWNrIGFuZCBleHBhbmQgdGhlIGRvd25sb2FkZWQgQkNFTCBmaWxlcyBpbiB5b3VyIAotICAgICAgIGRvd25sb2FkIGRpcmVjdG9yeSAoZS5nLiwgL3Vzci9sb2NhbCkuCi0KLSAgICAzKSBDaGFuZ2UgZGlyZWN0b3J5IHRvIEJDRUwuCi0KLSAgICA0KSBDcmVhdGUgdGhlIGphciBmaWxlIEJDRUwuamFyLgotICAgIAotICAgICAgIEZyb20gd2l0aGluIHRoZSBCQ0VMIGRpcmVjdG9yeSwgeW91IGNhbiBlaXRoZXIgdXNlIHRoZSAKLSAgICAgICBpbmNsdWRlZCBHTlVtYWtlZmlsZSBvciBjcmVhdGUgdGhlIGphciB5b3Vyc2VsZi4KLSAgICAgICAKLSAgICAgICBUbyB1c2UgdGhlIEdOVW1ha2VmaWxlLCB0eXBlIHRoZSBjb21tYW5kICdtYWtlIGphcicuCi0gICAgICAgCi0gICAgICAgVG8gY3JlYXRlIHRoZSBqYXIgeW91cnNlbGYsIHR5cGUgdGhlIGNvbW1hbmQ6Ci0gICAgICAgCi0gICAgICAgICBqYXIgY3ZmIEJDRUwuamFyIGBmaW5kIGRlIGdudSAtbmFtZSBcKi5jbGFzc2AgbGlzdGNsYXNzLmNsYXNzCi0KLVRvIGRvd25sb2FkIHRoZSBwcmVjb21waWxlZCBjbGFzcyBmaWxlcyBhbmQgZG9jdW1lbnRhdGlvbiAKLXRvIGEgV2luZG93cyBzeXN0ZW06Ci0KLSAgICAxKSBDaG9vc2UgdGhlICJsYXRlc3QgdmVyc2lvbiAoUHJlY29tcGlsZWQgKyBkb2NzKSIgCi0gICAgICAgWklQLUZpbGUgbGluay4KLQotICAgIDIpIFVuemlwIHRoZSBkb3dubG9hZGVkIEJDRUwgZmlsZXMgaW4geW91ciAKLSAgICAgICBkb3dubG9hZCBkaXJlY3RvcnkuCi0KLSAgICAzKSBDaGFuZ2UgZGlyZWN0b3J5IHRvIEJDRUwgYW5kIGZyb20gYSBET1MgY29tbWFuZCBsaW5lLAotICAgICAgIHR5cGUgdGhlIGNvbW1hbmQ6Ci0KLSAgICAgICAgIGphciAtY3ZmIEJDRUwuamFyIGRlXGZ1YlxieXRlY29kZVxjbGFzc2ZpbGVcKi5jbGFzcwotICAgICAgICAgICBnbnVccmVnZXhwXCouY2xhc3MgbGlzdGNsYXNzLmNsYXNzCi0KLVRvIGNvbXBsZXRlIHRoZSBCQ0VMIHNldHVwOgotCi0gICAgMSkgSW5zdGFsbCBYU0xUQywgYXMgZGVzY3JpYmVkIGluIHRoZSBzZWN0aW9uIGJlbG93LAotICAgICAgICJIT1cgVE8gSU5TVEFMTCBYU0xUQyBBTkQgUlVOIFRIRSBTQU1QTEVTLiIKLQotICAgIDIpIENvcHkgdGhlIEJDRUwuamFyIGZpbGUgaW50byB0aGUgImxpYiIgZGlyZWN0b3J5Ci0gICAgICAgdW5kZXIgeW91ciAieHNsdGMiIGRpcmVjdG9yeS4KLQotICAgICAgIFlvdSBhcmUgbm93IHNldCB0byBydW4gdGhlIFhTTFQgY29tcGlsZXIuCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotQURESVRJT05TIEZST00gVkVSU0lPTiA1IChvZiB0aGUgUFJFVklFVyBDT01QSUxFUikKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi1TdXBwb3J0IGZvciAKLQotCS0gU2ltcGxpZmllZCBTdHlsZXNoZWV0cwotCS0gaWQoKSBhbmQga2V5KCkgaW4gbWF0Y2ggcGF0dGVybnMKLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1YU0xUIDEuMCBGZWF0dXJlcyBOb3QgU3Vwb3J0ZWQgaW4gUFJFVklFVyBWRVJTSU9OIDYKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotCi1UaGUgZm9sbG93aW5nIFhTTFQgMS4wIGZlYXR1cmVzIGFyZSBub3QgeWV0IHN1cHBvcnRlZDoKLQotICAgICogTm9uc3RhdGljIGV4dGVybmFsIEphdmEgbWV0aG9kcy4gCi0gICAgICBZb3UgbWF5IGNhbGwgc3RhdGljIEphdmEgZnVuY3Rpb25zCi0gICAgICB1c2luZyBhIG5hbWVzcGFjZSBwcmVmaXggbWF0Y2hpbmcgdGhlIGNsYXNzIG5hbWUgdGhhdCBpcyAKLSAgICAgIGFzc29jaWF0ZWQgd2l0aCB0aGUgZm9sbG93aW5nIFVSTDoKLSAgICAgIAotICAgICAgICBodHRwOi8vd3d3LnN1bi5jb20veHNsdGMvamF2YS9Zb3VySmF2YUNsYXNzCi0gICAgICAKLSAgICAqIE5hbWVzcGFjZSBheGlzCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotTElTVCBPRiBGSUxFUwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLVRoZSBmaWxlcyBpbmNsdWRlZCBpbiB0aGlzIHByZXZpZXcgcGFja2FnZSBhcmUgYXMgZm9sbG93czoKLQoteHNsdGMtMV8wLWFscGhhNS1iaW4uemlwCi0gICA8aW5zdGFsbCBkaXI+L3hzbHRjCi0gICAgICBMSUNFTlNFLnR4dCAgICAgICAgICAgKGxpY2Vuc2UgZmlsZSkKLSAgICAgIFhTTFRDcHJuX2xnLnR4dCAgICAgICAoY29weXJpZ2h0IG5vdGljZSkKLSAgICAgIFJFQURNRSAgICAgICAgICAgICAgICAodGhpcyBmaWxlKQotICAgICAgUkVBRE1FLmFwaSAgICAgICAgICAgIChkZXNjcmliZXMgVHJhbnNsZXQgQVBJKQotICAgICAgUkVBRE1FLnhzbHQgICAgICAgICAgIChkZXNjcmliZXMgcnVudGltZSBjb21tYW5kIGxpbmUgaW50ZXJmYWNlKQotICAgICAgUkVBRE1FLnhzbHRjICAgICAgICAgIChkZXNjcmliZXMgY29tcGlsZXIgY29tbWFuZCBsaW5lIGludGVyZmFjZSkKLSAgICAgIGJpbiAKLSAgICAgICAgIHhzbHQgICAgICAgICAgICAgICAocnVudGltZSBmb3IgVW5peCkKLSAgICAgICAgIHhzbHRjICAgICAgICAgICAgICAoY29tcGlsZXIgZm9yIFVuaXgpCi0KLSAgICAgICAgIHhzbHQuYmF0ICAgICAgICAgICAocnVudGltZSBmb3IgRE9TKQotICAgICAgICAgeHNsdGMuYmF0ICAgICAgICAgIChjb21waWxlciBmb3IgRE9TKQotICAgICAgZGVtbwotICAgICAgICAgUkVBRE1FCi0gICAgICAgICBUcmFuc2xldERlbW8ucHJjIChQYWxtIFBpbG90IGluc3RhbGwgZmlsZSkKLSAgICAgIGxpYgotICAgICAgICAgeG1sLmphcgotICAgICAgICAgeHNsdGMuamFyCi0gICAgICAgICB4c2x0Y3J0LmphciAgICAgICAgICAgICAgICgncnQnID0gcnVudGltZSkKLSAgICAgICAgIFtCQ0VMLmphciBnb2VzIGhlcmVdIChzZWUgUkVRVUlSRUQgUEFDS0FHRSBhYm92ZSkKLSAgICAgIHNhbXBsZXMKLSAgICAgICAgIHNldCBvZiB4bWwgYW5kIHhzbCBmaWxlcyBmb3IgeW91IHRvIHRyeQotICAgICAgc3JjCi0gICAgICAgICBzdWJzZXQgb2YgdGhlIHJ1bnRpbWUgcGFja2FnZSB0byBjb21wbGVtZW50IFJFQURNRS5hcGkKLSAgICAgICAgIHBsdXMgYW4gQXBwbGV0IGRlbW8gYW5kIGEgc2VydmxldCBkZW1vCi0gICAgICAgICBjb20vc3VuL3hzbHQvZGVtby9zZXJ2bGV0Ci0gICAgICAgICAgICAgUkVBRE1FLnNlcnZsZXQgICAgICAgIChkZXNjcmliZXMgU2VydmxldCBkZW1vKQotICAgICAgICAgY29tL3N1bi94c2x0L2RlbW8vYXBwbGV0Ci0gICAgICAgICAgICAgUkVBRE1FLmFwcGxldCAgICAgICAgIChkZXNjcmliZXMgQXBwbGV0IGRlbW8pCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotSE9XIFRPIElOU1RBTEwgWFNMVEMgQU5EIFJVTiBUSEUgU0FNUExFUwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLTEuIFVuemlwIHRoZSBmaWxlcyBpbiBhIGRpcmVjdG9yeSBvZiB5b3VyIGNob2ljZSwgZm9yIGV4YW1wbGUKLSAgIGZyb20gdGhlIHVzZXIgZGlyZWN0b3J5ICcvaG9tZS91c2VyMScsIHRoZSBkaXN0cmlidXRpb24KLSAgIHppcCBmaWxlIGNhbiBiZSB1bnppcHBlZCB1c2luZyB0aGUgamFyIGNvbW1hbmQgYXM6Ci0KLSAgIGphciB4dmYgeHNsdGMtMV8wLWFscGhhNS1iaW4uemlwIAotCi0gICBUaGUgc3ViZGlyZWN0b3J5ICd4c2x0JyB3aWxsIGJlIGNyZWF0ZWQgaW4gJy9ob21lL3VzZXIxJy4KLQotMi4gU2V0IHRoZSBYU0xUIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIHBvaW50IHRvIHlvdXIgaW5zdGFsbGF0aW9uCi0gICBkaXJlY3RvcnkuIFNldCB5b3VyIFBBVEggZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gaW5jbHVkZQotICAgdGhlIGJpbiBkaXJlY3Rvcnkgb2YgWFNMVC4gCi0KLSAgIEZvciBleGFtcGxlLCBpbiB0aGUgYmFzaCBzaGVsbDoKLSAKLSAgICAgIGV4cG9ydCBYU0xUPS9ob21lL3VzZXIxL3hzbHQKLSAgICAgIGV4cG9ydCBQQVRIPSRYU0xUL2JpbjokUEFUSAotCi0zLiBDb21waWxlIHRoZSBzdHlsZXNoZWV0IHRvIHByb2R1Y2UgYSBKYXZhIGNsYXNzIGZpbGUuCi0KLSAgIEZvciBleGFtcGxlLCBvbiB0aGUgVW5peCBwbGF0Zm9ybSwgdG8gY29tcGlsZSB0aGUgcGxheTEueHNsCi0gICBzdHlsZXNoZWV0IGZvciB0aGUgcGxheS54bWwgZG9jdW1lbnQ6Ci0KLSAgICAgIGNkIC9ob21lL3VzZXIxL3hzbHRjL3NhbXBsZXMKLSAgICAgIHhzbHRjIHBsYXkxLnhzbAotCi0gICBUaGUgY29tcGlsZWQgc3R5bGVzaGVldCB3aWxsIGJlIGluIHRoZSBtYWluIEphdmEgY2xhc3MgZmlsZSAKLSAgICdwbGF5MS5jbGFzcycKLQotICAgTk9URTogVGhlICd4bHN0Yycgc2hlbGwgc2NyaXB0IGFkZHMgdGhlIHJlcXVpcmVkIGphcnMgdG8geW91ciBDTEFTU1BBVEgKLQotICAgRm9yIGV4YW1wbGUsIG9uIHRoZSBXaW5kb3dzIHBsYXRmb3JtLCB0byBjb21waWxlIHRoZSBwbGF5MS54c2wKLSAgIHN0eWxlc2hlZXQgZm9yIHRoZSBwbGF5LnhtbCBkb2N1bWVudDoKLSAgIAotICAgICAgc2V0IGNsYXNzcGF0aD1jOlx4c2x0Y1xzYW1wbGVzO2M6XHhzbHRjXGxpYlx4c2x0Yy5qYXI7Ci0gICAgICBjOlx4c2x0Y1xsaWJceHNsdGNydC5qYXI7YzpceHNsdGNcbGliXHhtbC5qYXI7Ci0gICAgICBjOlx4c2x0Y1xsaWJcQkNFTC5qYXI7LgotICAgICAgY2QgYzpceHNsdGNcc2FtcGxlcwotICAgICAgamF2YSBjb20uc3VuLnhzbHQuY29tcGlsZXIuWFNMVEMgcGxheTEueHNsCi0KLTQuIFVzZSB0aGUgY29tcGlsZWQgSmF2YSBjbGFzcyBmaWxlIChwbGF5MS5jbGFzcykgdG8gdHJhbnNmb3JtIAotICAgdGhlIGV4YW1wbGUgWE1MIGRvY3VtZW50LgotCi0gICBGb3IgZXhhbXBsZSwgb24gdGhlIFVuaXggcGxhdGZvcm06Ci0KLSAgICAgIHhzbHQgcGxheS54bWwgcGxheTEKLQotICAgRm9yIGV4YW1wbGUsIG9uIHRoZSBXaW5kb3dzIHBsYXRmb3JtOgotCi0gICAgICBqYXZhIGNvbS5zdW4ueHNsdC5ydW50aW1lLkRlZmF1bHRSdW4gcGxheS54bWwgcGxheTEKLQotICAgVGhlIHJlc3VsdCBpcyBzZW50IHRvIHN0YW5kYXJkIG91dHB1dC4KLQotICAgTk9URTogV2hlbiBydW5uaW5nIHRoZSBjb21waWxlZCBzdHlsZXNoZWV0LCB5b3UgCi0gICAgICAgICBqdXN0IHNwZWNpZnkgdGhlIG5hbWUgb2YgaXRzIEphdmEgY2xhc3MsIG5vdCBpdHMKLSAgICAgICAgIGZpbGUgbmFtZSAoZS5nLiwgcGxheTEsIG5vdCBwbGF5MS5jbGFzcykuCi0gICAgICAgICBZb3UgZG8gbm90IGluY2x1ZGUgdGhlICIuY2xhc3MiIGV4dGVuc2lvbiwgbm9yCi0gICAgICAgICB0aGUgcGF0aCB0byB0aGUgY2xhc3MuIFRoZSBjbGFzcyBpcyBmb3VuZCBieSBtZWFucyAKLSAgICAgICAgIG9mIHRoZSBKYXZhIENMQVNTUEFUSCB2YXJpYWJsZS4gSWYgeW91IHJ1bgotICAgICAgICAgdGhlIHRyYW5zbGV0IGZyb20gYSBkaXJlY3Rvcnkgb3RoZXIKLSAgICAgICAgIHRoYW4gdGhlIGRpcmVjdG9yeSBpbiB3aGljaCB0aGUgY29tcGlsZWQKLSAgICAgICAgIHN0eWxlc2hlZXQgY2xhc3MgaXMgbG9jYXRlZCwgeW91IG5lZWQgdG8gYWRkIAotICAgICAgICAgdGhhdCBkaXJlY3RvcnkgdG8geW91ciBKYXZhIENMQVNTUEFUSC4gQWxzbywgeW91Ci0gICAgICAgICBuZWVkIHRvIHJlbW92ZSBkaXJlY3RvcmllcyBmcm9tIHlvdXIgQ0xBU1NQQVRIIAotICAgICAgICAgZm9yIHByaW9yIGluc3RhbGxhdGlvbnMgb2YgWFNMVEMgYW5kIGFueSByZWZlcmVuY2VzIAotICAgICAgICAgdG8gU3VuJ3MgcHJvamVjdCBYIHBhcnNlciAoY29tLnN1bi54bWwudHJlZSkKLSAgICAgICAgIGluc3RhbGxlZCBmcm9tIHNvbWUgb3RoZXIgWE1MIGFwcGxpY2F0aW9uL3Rvb2wuCi0gCi0gICBOT1RFOiBUaGUgamF2YWRvY1RvSHRtbCBzYW1wbGUgY2FsbHMgZXh0ZXJuYWwgSmF2YSBtZXRob2RzCi0gICAgICAgICBmcm9tIHRoZSBKYXZhZG9jRm9ybWF0dGVyIGNsYXNzLiBCZWZvcmUgY29tcGlsaW5nIHRoZQotICAgICAgICAgamF2YWRvY1RvSHRtbC54c2wgc3R5bGVzaGVldCwgY29tcGlsZSB0aGUgCi0gICAgICAgICBKYXZhZG9jRm9ybWF0dGVyIGNsYXNzIHVzaW5nICdqYXZhYycuCi0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotRU5EIE9GIFJFQURNRQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUuQVBBQ0hFIGIveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUuQVBBQ0hFCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjN2NkNjFmLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvUkVBRE1FLkFQQUNIRQorKysgL2Rldi9udWxsCkBAIC0xLDg2ICswLDAgQEAKLVJFQURNRS5BUEFDSEUKLT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotRW50aXJlIHNvdXJjZSB0cmVlIGFuZCBzdXBwb3J0IHBhY2thZ2VzIGFyZSBsb2NhdGVkIGluIHRoZSBzaW5nbGUgamFyCi1maWxlICdhcGFjaGUuamFyJy4gCi0KLQotSW5zdGFsbGF0aW9uCi0tLS0tLS0tLS0tLS0tCi0KLSgxKSBjcmVhdGUgZGlyZWN0b3J5IFtSb290XSwgdW5wYWNrICdhcGFjaGUuamFyJyB0aGVyZS4KLQlleCkgJSBjZCAvdG1wOyBta2RpciB4c2x0Y19hcGFjaGUgCi0JICAgICUgY2QgeHNsdGNfYXBhY2hlCi0gICAgICAgIGNvcHkgYXBhY2hlLmphciB0byB4c2x0Y19hcGFjaGUgZGlyZWN0b3J5Ci0JICAgICUgamFyIHh2ZiBhcGFjaGUuamFyIAotCWNsZWFudXAKLQkgICAgJSBybSAtcmYgTUVUQS1JTkYgYXBhY2hlLmphcgotCi0gICAgVW5wYWNraW5nIHRoZSBqYXIgZmlsZSB3aWxsIHJlc3VsdCBpbiB0aGUgZm9sbG93aW5nIHRyZWU6Ci0KLQlbUm9vdF0KLQkgIEV4dGVybmFsLwotCSAgICBCQ0VMLyAgICAgICAgICAgICAgICAuLi4gY29udGFpbnMgQkNFTC5qYXIKLQkgICAgSkxleC8gICAgICAgICAgICAgICAgLi4uIGNvbnRhaW5zIEpMZXguamFyCi0JICAgIGphdmFfY3VwLyAgICAgICAgICAgIC4uLiBjb250YWlucyBqYXZhX2N1cC5qYXIsIHJ1bnRpbWUvcnVudGltZS5qYXIKLQkgICAgeG1sLXRyMi8gICAgICAgICAgICAgLi4uIGNvbnRhaW5zIHhtbC5qYXIKLQkgIGJpbi8KLQkgICAgeHNsdAotCSAgICB4c2x0YwotCSAgZG9jLwotCSAgICBhcGkvICAgICAgICAgICAgICAgICAuLi4gY29udGFpbnMgamF2YWRvYyBmb3IgYXBpCi0JICBzcmMvCi0JICAgIEdOVW1ha2VmaWxlCi0JICAgIEdOVW1ha2VmaWxlLmFsbGluYwotCSAgICBkb2NzLwotCSAgICAgIExJQ0VOU0UudHh0Ci0JICAgICAgTWVzc2FnZS50eHQKLQkgICAgICBSRUFETUUKLQkgICAgICBSRUFETUUuYXBpCi0JICAgICAgUkVBRE1FLnhzbHQKLQkgICAgICBSRUFETUUueHNsdGMKLQkgICAgICBYU0xUQ3Bybl9sZy50eHQqCi0JICAgICAgeHNsdGNBMy50eHQKLQkgICAgb3JnLwotCSAgICAgIGFwYWNoZS8KLQkJeGFsYW4vCi0JCSAgeHNsdGMvCi0JCSAgICAgKHNyYyB0cmVlKSAgLi4uIGFsbCB0aGUgc291cmNlIGNvZGUgZmlsZXMKLQotCi0gICAgVGhlICdzcmMgdHJlZScgaXMgYSBoaWVyYXJjaHkgb2YgdGhlIGZvbGxvd2luZyBwYWNrYWdlczoKLQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlcgotCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuY29tcGlsZXIudXRpbAotCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy51dGlsCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy51dGlsLmdldG9wdAotCi0KLSgyKSBtYWtlIGJpbiBwcm9ncmFtcyBleGVjdXRhYmxlCi0JICAgICUgY2htb2QgK3ggYmluLyoKLQotKDMpIHNldCBlbnYgdmFyaWFibGUgdG8gcG9pbnQgdG8gdG9wIG9mIGRpcmVjdG9yeSBbUm9vdF0KLQlleCkgJSBzZXRlbnYgWFNMVCAvdG1wL3hzbHRjX2FwYWNoZQotCi0oNCkgY29tcGlsZSBzb3VyY2VzICh1c2VzIGdudSBtYWtlIGFuZCB0aGUgcHJvdmlkZXMgJ0dOVW1ha2VmaWxlJykuIFRoaXMKLSAgICB3aWxsIGNyZWF0ZSBqYXZhIGNsYXNzZXMgaW4gW1Jvb3RdL2NsYXNzZXMsIGUuZy4gL3RtcC94c2x0Y19hcGFjaGUvY2xhc3Nlcy4KLSAgICAoTm8gbmVlZCB0byBzZXQgeW91ciBDTEFTU1BBVEggdmFyaWFibGUuKQotICAgIAotCWV4KSAlIGNkIHNyYzsgZ21ha2UgYWdhaW4KLQotICAgIE5vdGU6IHRoZSAnYWdhaW4nIHRhcmdldCBmb3JjZXMgZXZlcnl0aGluZyB0byBiZSBidWlsdCBmcm9tIHNjcmF0Y2gsCi0gICAgaW5jbHVkaW5nIHRoZSBqYXZhX2N1cCBzb3VyY2UgZmlsZXMuIFN1YnNlcXVlbnQgYnVpbGRzIGNhbiBiZSBkb25lCi0gICAgdXNpbmcgdGhlICdjbGFzc2VzJyB0YXJnZXQuIAotCi0oNSkgbWFrZSB0aGUgamF2YWRvYwotCWV4KSAlIGdtYWtlIGpkb2MKLQotKDYpIGFkZCBiaW4gZGlyZWN0b3J5IHRvIHlvdXIgZXhlY3V0YWJsZSBwYXRoLCAKLQlleCkgJSBzZXQgcGF0aD0oJFhTTFQvYmluICRwYXRoKQotCi0oNykgdGVzdCBkaXN0cmlidXRpb24sIGdpdmVuIGEgc3R5bGVzaGVldCAodGVzdC54c2wpIGFuZCBhbiBpbnB1dCB4bWwgZG9jCi0gICAgKHRlc3QueG1sKSwgYW5kIGJlIHN1cmUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSAoLikgaXMgaW4geW91cgotICAgIENMQVNTUEFUSC4KLSAJJSB4c2x0YyB0ZXN0LnhzbAkJLi4uIGNyZWF0ZXMgdHJhbnNsZXQsIHRlc3QuY2xhc3MKLQklIHhzbHQgdGVzdC54bWwgdGVzdAkJLi4uIHJ1bnMgdHJhbnNsZXQgb24geG1sIGlucHV0CQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUuYXBpIGIveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUuYXBpCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2MDFiMDkyLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvUkVBRE1FLmFwaQorKysgL2Rldi9udWxsCkBAIC0xLDQyMiArMCwwIEBACi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAgICAgICAgIFJFQURNRSBGSUxFIEZPUiBUSEUgU1VOIFhTTFQgQ09NUElMRVIgQVBJCi0gICAgICAgICAgICAgICAgICBQcmV2aWV3IFZlcnNpb24gNSAKLSAgICAgICAgICAgICAgICAgICAgRmVicnVhcnksIDIwMDEKLSAgICAgICAgICAgQ29weXJpZ2h0IChjKSBTdW4gTWljcm9zeXN0ZW1zLCAyMDAxCi09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLQotVGhlIFN1biBYU0xUIENvbXBpbGVyIChYU0xUQykgaXMgYSBKYXZhLWJhc2VkIHRvb2wgZm9yIAotY29tcGlsaW5nIFhTTCBzdHlsZXNoZWV0cyBpbnRvIGV4dHJlbWVseSBsaWdodHdlaWdodCBhbmQgCi1wb3J0YWJsZSBKYXZhIGJ5dGUgY29kZS4gVGhlIFN1biBYU0xUQyBKYXZhIFJ1bnRpbWUgZW52aXJvbm1lbnQgCi1jYW4gdGhlbiBwcm9jZXNzIFhNTCBmaWxlcyBhZ2FpbnN0IHRoZXNlIGNvbXBpbGVkIHN0eWxlc2hlZXRzIAotKFRyYW5zbGV0cykgdG8gZ2VuZXJhdGUgYW55IG1hbm5lciBvZiBvdXRwdXQgcGVyIHRoZSBzdHlsZS0KLXNoZWV0IGluc3RydWN0aW9ucy4KLQotQ09OVEVOVFMgT0YgVEhJUyBET0NVTUVOVDoKLQkxLiBIT1cgVE8gSU5DTFVERSBUUkFOU0xFVFMgSU4gWU9VUiBBUFBMSUNBVElPTlMKLQkyLiBGVUxMIENPREUgRVhBTVBMRSAxLCAodXNlcyBhIFNBWCBEb2N1bWVudEhhbmRsZXIpLgotCTMuIENPTVBJTElORyBBTkQgUlVOTklORyBUSEUgRVhBTVBMRSAKLQk0LiBGVUxMIENPREUgRVhBTVBMRSAyLCAodXNlcyBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcikuIAotCTUuIEFQUEVORElYIChUZXh0T3V0IGFuZCBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcikKLQotCi0KLQotMS4gSE9XIFRPIElOQ0xVREUgVFJBTlNMRVRTIElOIFlPVVIgQVBQTElDQVRJT05TCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotVHJhbnNsZXRzIGltcGxlbWVudCB0aGUgaW50ZXJmYWNlIGNvbS5zdW4ueHNsdC5UcmFuc2xldAotdGhhdCB5b3Ugd2lsbCBmaW5kIGluIHRoZSBzcmMgZGlyZWN0b3J5LgotCi1wdWJsaWMgaW50ZXJmYWNlIFRyYW5zbGV0IHsKLSAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oRE9NIGRvY3VtZW50LCBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oRE9NIGRvY3VtZW50LCBUcmFuc2xldE91dHB1dEhhbmRsZXJbXSBoYW5kbGVycykKLQl0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0KLSAgICBwdWJsaWMgdm9pZCB0cmFuc2Zvcm0oRE9NIGRvY3VtZW50LCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyKSB0aHJvd3MgCi0JCQkgIFRyYW5zbGV0RXhjZXB0aW9uOwotCi0gICAgcHVibGljIE9iamVjdCBhZGRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSk7Ci0KLSAgICBwdWJsaWMgdm9pZCBidWlsZEtleXMoRE9NIGRvY3VtZW50LCBOb2RlSXRlcmF0b3IgaXRlcmF0b3IsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBoYW5kbGVyLCBpbnQgcm9vdCkgdGhyb3dzIAotCQkJICBUcmFuc2xldEV4Y2VwdGlvbjsKLQotICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3V0cHV0RW5jb2RpbmcoKTsKLX0KLQotVGhlIFRyYW5zbGV0IHRha2VzIGEgRE9NSW1wbCBvYmplY3QgKGNyZWF0ZWQgZnJvbSBhbiBpbnB1dCBYTUwgZG9jdW1lbnQpLAotYXMgaW5wdXQgYW5kIHRyYW5zZm9ybXMgaXQuIFRoZSByZXN1bHRzIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbiBhcmUgCi1zZW50IHRvIGFuICBldmVudC1iYXNlZCBvdXRwdXQgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgdGhlIAotY29tLnN1bi54c2x0LlRyYW5zbGV0T3V0cHV0SGFuZGxlciBpbnRlcmZhY2UgOgotCi0KLXB1YmxpYyBpbnRlcmZhY2UgY29tLnN1bi54c2x0LlRyYW5zbGV0T3V0cHV0SGFuZGxlciB7Ci0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBjaGFyYWN0ZXJzKGNoYXJbXSBjaGFyYWN0ZXJzLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIHZvaWQgYXR0cmlidXRlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBTdHJpbmcgYXR0cmlidXRlVmFsdWUpCi0gICAgICAgIHRocm93cyBUcmFuc2xldEV4Y2VwdGlvbjsKLSAgICBwdWJsaWMgdm9pZCBjb21tZW50KFN0cmluZyBjb21tZW50KSB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgVHJhbnNsZXRFeGNlcHRpb247Ci0gICAgcHVibGljIHZvaWQgc2V0VHlwZShpbnQgdHlwZSk7Ci0gICAgcHVibGljIHZvaWQgc2V0SW5kZW50KGJvb2xlYW4gaW5kZW50KTsKLSAgICBwdWJsaWMgYm9vbGVhbiBzZXRFc2NhcGluZyhib29sZWFuIGVzY2FwZSkgdGhyb3dzIFRyYW5zbGV0RXhjZXB0aW9uOwotICAgIHB1YmxpYyB2b2lkIGluc2VydENkYXRhRWxlbWVudChTdHJpbmcgZWxlbWVudE5hbWUpOwotfQotCi0KLVlvdSBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUgVHJhbnNsZXQgaW50ZXJmYWNlCi11c2luZyBKYXZhIHJlZmxlY3Rpb246Ci0KLSAgQ2xhc3MgY2xhenogPSBDbGFzcy5mb3JOYW1lKCJjbGFzc25hbWUiKTsKLSAgVHJhbnNsZXQgdHJhbnNsZXQgPSAoVHJhbnNsZXQpIGNsYXp6Lm5ld0luc3RhbmNlKCk7Ci0KLXdoZXJlICJjbGFzc25hbWUiIGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyBnZW5lcmF0ZWQgYnkgWFNMVEMuCi1JbiBvcmRlciB0byBleGVjdXRlIGEgdHJhbnNmb3JtYXRpb24sIGJvdGggYSBkb2N1bWVudCBhbmQgYSBTQVgtbGlrZQotaGFuZGxlciAoVHJhbnNsZXRPdXRwdXRIYW5kbGVyKSBhcmUgbmVlZGVkLgotQSBkb2N1bWVudCBpbnN0YW5jZSBjYW4gYmUgY3JlYXRlZCB3aXRoIHRoZSBhaWQgb2YgU0FYLWNvbXBsYWludCBYTUwgcGFyc2VyLgotRm9yIGV4YW1wbGUsIHVzaW5nIFN1bidzIHBhcnNlciB5b3Ugd291bGQgd3JpdGUsCi0KLSAgaW1wb3J0IGNvbS5zdW4ueHNsdC5kb20uRE9NSW1wbDsKLSAgaW1wb3J0IGNvbS5zdW4ueG1sLnBhcnNlci5QYXJzZXI7Ci0gIGltcG9ydCBjb20uc3VuLnhtbC5wYXJzZXIuUmVzb2x2ZXI7Ci0KLSAgLy8gQ3JlYXRlIG5ldyBpbnN0YW5jZXMgb2YgRE9NIGFuZCBQYXJzZXIKLSAgRE9NSW1wbCBkb20gPSBuZXcgRE9NSW1wbCgpOwotICBQYXJzZXIgcGFyc2VyID0gbmV3IFBhcnNlcigpOwotCi0gIC8vIFNldCBhIFNBWCBoYW5kbGVyIHRvIGJ1aWxkIGEgRE9NIHRyZWUKLSAgcGFyc2VyLnNldERvY3VtZW50SGFuZGxlcihkb20uZ2V0QnVpbGRlcigpKTsKLQotICAvLyBQYXJzZSB0aGUgZG9jdW1lbnQgYW5kIGJ1aWxkIGEgRE9NIHRyZWUKLSAgSW5wdXRTb3VyY2UgaW5wdXQgPSBuZXcgSW5wdXRTb3VyY2UoCi0gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlUmVhZGVyKCJ4bWxmaWxlLnhtbCIpKTsKLSAgcGFyc2VyLnBhcnNlKGlucHV0KTsKLSAgCi1JbiB0aGlzIGV4YW1wbGUgYSBkb2N1bWVudCBpcyBwYXJzZWQgZnJvbSBhIGZpbGUsIGJ1dCBpdCBpcyBhbHNvIAotcG9zc2libGUgdG8gcGFyc2UgYSBkb2N1bWVudCBmcm9tIGEgVVJJIGJ5IHdyaXRpbmcsCi0KLSAgcGFyc2VyLnBhcnNlKCJodHRwOi8vLi4uL3htbGZpbGUueG1sIik7Ci0KLVRvIHRyYW5zZm9ybSB0aGUgaW5wdXQgWE1MIGRvY3VtZW50LCBhIGNhbGwgaXMgbWFkZSB0byB0aGUgdHJhbnNsZXQncwotdHJhbnNmb3JtKCkgbWV0aG9kLiBJbiBvcmRlciB0byBkbyBpdHMgd29yaywgdGhlIHRyYW5zZm9ybSgpIG1ldGhvZAotdGFrZXMgdHdvIGFyZ3VtZW50cywgKDEpIHRoZSBET01JbXBsIG9iamVjdCBjcmVhdGVkIGZyb20gcGFyc2luZwotdGhlIGlucHV0IFhNTCBkb2N1bWVudCwgYW5kICgyKSBhbiBvdXRwdXQgaGFuZGxlci4gVGhlIG91dHB1dCBoYW5kbGVyCi1tdXN0IGltcGxlbWVudCB0aGUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyIGludGVyZmFjZS4gIFlvdSAKLWhhdmUgdGhlIG9wdGlvbiBvZjogKDEpIHdyaXRpbmcgeW91ciBvd24gY2xhc3MgdGhhdCBpbXBsZW1lbnRzIAotRG9jdW1lbnRIYW5kbGVyLCBvciAoMikgdXNpbmcgb3VyIGRlZmF1bHQgY2xhc3MKLSdjb20uc3VuLnhzbHQucnVudGltZS5EZWZhdWx0U0FYT3V0cHV0SGFuZGxlcicgaW5zdGVhZC4gIAotVGhlIHNvdXJjZSBjb2RlIGZvciBvdXIgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgaXMgaW5jbHVkZWQKLWluIHRoaXMgcGFja2FnZSBpbiB0aGUgY29tL3N1bi94c2x0L3J1bnRpbWUgZGlyZWN0b3J5LiAKLVRoaXMgaXMgYSBjaGFuZ2UgZnJvbSB0aGUgcHJldmlvdXMgcmVsZWFzZXMgb2YKLW91ciBjb21waWxlciBBUEkuIElmIHlvdSAgd2FudGVkIHRvIGNyZWF0ZSB5b3VyIG93biAKLW91dHB1dCBoYW5kbGVyIGluIHByZXZpb3VzIHJlbGVhc2VzLCB5b3Ugd291bGQgaGF2ZSB3cml0ZSBhIGNsYXNzIHRoYXQgCi1pbXBsZW1lbnRlZCB0aGUgaW50ZXJmYWNlIFRyYW5zbGV0T3V0cHV0SGFuZGxlci4gVGhpcyBjaGFuZ2Ugd2FzIG1hZGUKLXNvIHRoYXQgdXNlcnMgY291bGQgbW9yZSBlYXNpbHkgcGx1ZyBpbiBhbnkgU0FYIGNvbXBsaWFudCBvdXRwdXQKLWhhbmRsZXIuIFRvIHBsdWcgaW4gdGhlIFNBWCBjb21wbGlhbnQgb3V0cHV0IGhhbmRsZXIsCi0od2hldGhlciBpdCBpcyBhIHVzZXIgd3JpdHRlbiBjbGFzcyBvciBvdXIgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIpCi1pbnRvIHRoZSB0cmFuc2Zvcm0oKSBtZXRob2QsIGl0IG11c3QgYmUgd3JhcHBlZCBpbiBhCi1UZXh0T3V0cHV0IG9iamVjdCBmaXJzdC4gCi0KLVRoZSBUcmFuc2xldC50cmFuc2Zvcm0oKSBtZXRob2QgbWF5IGFsc28gdGFrZSBhbiBhcnJheSBvZiBvdXRwdXQgaGFuZGxlcnMuIAotSW4gdGhpcyBjYXNlIHRoZSB0cmFuc2Zvcm1hdGlvbiB3aWxsIGJlIGFibGUgdG8gc2VsZWN0IHdoaWNoIGhhbmRsZXIgCi10byBzZW5kIG91dHB1dCB0byBieSB1c2luZyB0aGUgZXh0ZW5zaW9uIGVsZW1lbnQgPHRyYW5zbGV0Om91dHB1dCBwb3J0PSJuIj4gCi13aGVyZSAnbicgaXMgYSAwLWJhc2VkIGluZGV4IGluIHRoZSBhcnJheSBvZiBvdXRwdXQgaGFuZGxlcnMuCi0KLUxldHMgdGFrZSBhIGxvb2sgYXQgdGhlIGNvZGUgbmVlZGVkIHRvIGNhcnJ5IG91dCBib3RoIG9mIHRoZSBvcHRpb25zCi1mb3IgcGFzc2luZyB0aGUgU0FYIG91dHB1dCBoYW5kbGVyIHRvIHRoZSB0cmFuc2xldCdzIHRyYW5zZm9ybSgpIG1ldGhvZDoKLQotICAgKDEpIFlvdSB3b3VsZCB3cml0ZSB5b3VyIG93biBvdXRwdXQgaGFuZGxlciB0aGF0IGltcGxlbWVudHMKLSAgICAgICB0aGUgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyIGludGVyZmFjZSwgcGFzcyB0aGlzIGNsYXNzCi0gICAgICAgaW50byBvdXIgY29tLnN1bi54c2x0LnJ1bnRpbWUuVGV4dE91dHB1dCBjbGFzcyB3aGljaCBpdHNlbGYKLSAgICAgICBpbXBsZW1lbnRzIHRoZSBUcmFuc2xldE91dHB1dEhhbmRsZXIgaW50ZXJmYWNlLgotCi0gICAoMikgWW91IHdvdWxkIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgZGVmYXVsdCBTQVggb3V0cHV0IGhhbmRsZXIsCi0gICAgICAgY29tLnN1bi54c2x0LnJ1bnRpbWUuRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIsIHBhc3MgdGhpcwotICAgICAgIGluc3RhbmNlIGludG8gb3VyIGNvbS5zdW4ueHNsdC5ydW50aW1lLlRleHRPdXRwdXQgY2xhc3Mgd2hpY2gKLSAgICAgICBpdHNlbGYgaW1wbGVtZW50cyB0aGUgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGludGVyZmFjZS4KLQotCi1JbiBvcHRpb24gKDEpLCB3ZSB3YW50IHRvIHVzZSBhIFNBWCBjb21wbGlhbnQgb3V0cHV0IGhhbmRsZXIgdGhhdCB3ZSB3cml0ZQotb3Vyc2VsdmVzLiBJbiB0aGlzIGNhc2Ugd2UgY3JlYXRlIG91ciBIYW5kbGVyIGNsYXNzLCB3aGljaCBpbXBsZW1lbnRzIAotb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOgotCi1pbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOwotCi0vLyB1c2VyIHN1cHBsaWVkIFNBWCBIYW5kbGVyOgotY2xhc3MgSGFuZGxlciBpbXBsZW1lbnRzIERvY3VtZW50SGFuZGxlciB7Ci0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG5ldyBTdHJpbmcoY2hhcmFjdGVycywgb2Zmc2V0LCBsZW5ndGgpKTsKLSAgICB9Ci0gICAgcHVibGljIHZvaWQgc3RhcnRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgQXR0cmlidXRlTGlzdCBhdHRycykKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7fQotICAgIHB1YmxpYyB2b2lkIGVuZEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHt9Ci0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jKSB7fQotICAgIHB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoYXJhY3RlcnMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24ge30KLSAgICBwdWJsaWMgdm9pZCBwcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oU3RyaW5nIHRhcmdldCwgU3RyaW5nIGRhdGEpCi0gICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24ge30KLX0KLQotTm93IGJlZm9yZSB3ZSBwYXNzIG91ciBoYW5kbGVyIHRvIHRoZSB0cmFuc2Zvcm0oKSBtZXRob2QsIHdlIHdyYXAgaXQKLWluIGEgVGV4dE91dHB1dCBvYmplY3QgKHdoaWNoIGltcGxlbWVudHMgdGhlIFRyYW5zbGV0T3V0cHV0SGFuZGxlcgotaW50ZXJmYWNlIGZvciB1cykuICBUaGVuIGdpdmVuIHRoZSBpbnN0YW50aWF0ZWQgdHJhbnNsZXQgY2xhc3MsIAotdGhlIHRyYW5zZm9ybSBtZXRob2QgY291bGQgYmUgY2FsbGVkIGFzOgotCi0JaW1wb3J0IGNvbS5zdW4ueHNsdC5ydW50aW1lLlRleHRPdXRwdXQ7Ci0KLQlET01JbXBsIGRvbTsKLSAgICAgICAgLi4uCi0gICAgICAgIEhhbmRsZXIgc2F4SGFuZGxlcjsKLSAgICAgICAgVGV4dE91dHB1dCB0ZXh0T3V0cHV0OwotICAgICAgICB0cnkgewotICAgICAgICAgICAgc2F4SGFuZGxlciA9IG5ldyBIYW5kbGVyKCk7Ci0gICAgICAgICAgICB0ZXh0T3V0cHV0ID0gbmV3IFRleHRPdXRwdXQoc2F4SGFuZGxlcik7Ci0gICAgICAgICAgICB0cmFuc2xldC50cmFuc2Zvcm0oZG9tLCB0ZXh0T3V0cHV0KTsKLSAgICAgICAgfSBjYXRjaCAoVHJhbnNsZXRFeGNlcHRpb24gIGUpewotCSAgICAuLi4KLSAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gIGUpewotCSAgICAuLi4KLSAgICAgICAgfQotCi0KLUJ5IHVzaW5nIHRoZSBUZXh0T3V0cHV0IHdyYXBwZXIgY2xhc3MsIG9uZSBjYW4gYWxzbyBjb250cm9sIHRoZSBjaGFyYWN0ZXIKLWVuY29kaW5nLiBUaGUgVGV4dE91dHB1dCBjbGFzcyBoYXMgYW4gYWRkaXRpb25hbCBjb25zdHJ1Y3RvciB0aGF0IHRha2VzCi10aGUgRG9jdW1lbnRIYW5kbGVyIGFuZCBhIFN0cmluZyB0aGF0IGRlc2NyaWJlcyB0aGUgZW5jb2RpbmcsIGZvciBleGFtcGxlCi0ndGV4dE91dHB1dCcgY291bGQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXM6Ci0KLQl0ZXh0T3V0cHV0ID0gbmV3IFRleHRPdXRwdXQoc2F4SGFuZGxlciwgInV0Zi04Iik7Ci0KLUZpbmFsbHksIG9wdGlvbiAoMikgaXMgbXVjaCBsaWtlIG9wdGlvbiAoMSkgZXhjZXB0IHlvdSBkbyBub3QgaGF2ZQotdG8gd3JpdGUgeW91ciBvd24gRG9jdW1lbnRIYW5kbGVyLiBXZSBwcm92aWRlIG9uZSBieSBkZWZhdWx0LiBUbyB1c2UgdGhlCi1kZWZhdWx0IG9uZSwgaW5zdGFudGlhdGUgJ2NvbS5zdW4ueHNsdC5ydW50aW1lLkRlZmF1bHRTQVhPdXRwdXRIYW5kbGVyJwotcmF0aGVyIHRoYW4gaW5zdGFudGlhdGluZyB5b3VyIG93biBjbGFzcyAoc3VjaCBhcyBIYW5kbGVyIGFib3ZlKToKLQotCWltcG9ydCBjb20uc3VuLnhzbHQucnVudGltZS5EZWZhdWx0U0FYT3V0cHV0SGFuZGxlcjsKLQlpbXBvcnQgY29tLnN1bi54c2x0LnJ1bnRpbWUuVGV4dE91dHB1dDsKLQotCURlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIGRlZmhhbmRscjsKLQl0cnkgewotICAgICAgICAgICAgZGVmaGFuZGxyID0gbmV3IERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKFN5c3RlbS5vdXQsICJ1dGYtOCIpOwotICAgICAgICAgICAgdHJhbnNsZXQudHJhbnNmb3JtKGRvbSwgbmV3IFRleHRPdXRwdXQoZGVmaGFuZGxyKSk7Ci0gICAgICAgIH0gY2F0Y2ggKFRyYW5zbGV0RXhjZXB0aW9uICBlKXsKLQkgICAgLi4uCi0gICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uICBlKXsKLQkgICAgLi4uCi0gICAgICAgIH0KLQotRm9yIGEgcXVpY2sgcmVmZXJlbmNlIHRvIHRoZSBUZXh0T3V0cHV0IGFuZCBEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcgotY29uc3RydWN0b3JzIGF2YWlsYWJsZSwgc2VlIHRoZSBBcHBlbmRpeC4gCi0KLUluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMsIGZ1bGwgY29kZSBleGFtcGxlcyBhcmUgc2hvd24uCi0JCi1GaW5hbGx5LCBpZiB5b3Ugd2FudCB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0cyBpbiB0aGUgRE9NIGZvcm06Ci0KLURPTSByZXN1bHQgPSBuZXcgRE9NKCk7Ci10cmFuc2xldC50cmFuc2Zvcm0oZG9tLCByZXN1bHQuZ2V0T3V0cHV0RG9tQnVpbGRlcigpKTsKLQotSWYgdGhlIGNvbXBpbGVkIHN0eWxlc2hlZXQgcmVxdWlyZXMgdGhlIHZhbHVlcyBvZiBnbG9iYWwgCi1wYXJhbWV0ZXJzIHRvIGJlIHNldCwgeW91IHNob3VsZCBjYWxsIGFkZFBhcmFtZXRlcigpIGJlZm9yZSAKLWNhbGxpbmcgdGhlIHRyYW5zZm9ybSgpIG1ldGhvZC4KLQotIAotMi4gRlVMTCBDT0RFIEVYQU1QTEUgMSwgWHNsdEFwcC5qYXZhLCB1c2VzIGEgU0FYIERvY3VtZW50SGFuZGxlci4KLQlUaGlzIGV4YW1wbGUgY29ycmVzcG9uZHMgdG8gb3B0aW9uICgxKSBpbiBkaXNjdXNzaW9uIGFib3ZlLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1pbXBvcnQgamF2YS5pby5GaWxlUmVhZGVyOwotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgY29tLnN1bi54c2x0LmRvbS5ET01JbXBsOwotaW1wb3J0IGNvbS5zdW4ueHNsdC5ydW50aW1lLlRleHRPdXRwdXQ7Ci1pbXBvcnQgY29tLnN1bi54c2x0LlRyYW5zbGV0OwotaW1wb3J0IGNvbS5zdW4ueHNsdC5UcmFuc2xldEV4Y2VwdGlvbjsKLWltcG9ydCBjb20uc3VuLnhtbC5wYXJzZXIuUGFyc2VyOwotaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZUxpc3Q7Ci1pbXBvcnQgb3JnLnhtbC5zYXguRG9jdW1lbnRIYW5kbGVyOwotaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwotaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7Ci1pbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwotCi0KLS8vIENyZWF0ZSBhIFNBWCBPdXRwdXQgSGFuZGxlcgotY2xhc3MgSGFuZGxlciBpbXBsZW1lbnRzIERvY3VtZW50SGFuZGxlciB7Ci0gICAgcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24ge30KLQotICAgIHB1YmxpYyB2b2lkIGVuZERvY3VtZW50KCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgY2hhcmFjdGVycyhjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbgotICAgIHsKLSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG5ldyBTdHJpbmcoY2hhcmFjdGVycywgb2Zmc2V0LCBsZW5ndGgpKTsKLSAgICB9Ci0KLSAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoU3RyaW5nIGVsZW1lbnROYW1lLCBBdHRyaWJ1dGVMaXN0IGF0dHJzKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHt9Ci0KLSAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jKSB7fQotCi0gICAgcHVibGljIHZvaWQgaWdub3JhYmxlV2hpdGVzcGFjZShjaGFyW10gY2hhcmFjdGVycywgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKLSAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7fQotCi0gICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uKFN0cmluZyB0YXJnZXQsIFN0cmluZyBkYXRhKQotICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHt9Ci0KLX0KLQotcHVibGljIGNsYXNzIFhzbHRBcHAgewotICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncyl7Ci0gICAgICAgIFhzbHRBcHAgYXBwID0gbmV3IFhzbHRBcHAoKTsKLSAgICAgICAgYXBwLnJ1bihhcmdzKTsKLSAgIH0KLQotICAgcHVibGljIHZvaWQgcnVuKFN0cmluZ1tdIGFyZ3MpewotICAgICAgICBpZihhcmdzLmxlbmd0aCAhPSAyKXsKLSAgICAgICAgICAgICAgICB1c2FnZSgpOwotICAgICAgICB9Ci0gICAgICAgIFN0cmluZyBpbnB1dEZpbGVOYW1lID0gYXJnc1swXTsKLSAgICAgICAgU3RyaW5nIHRyYW5zbGV0TmFtZSA9IGFyZ3NbMV07Ci0KLSAgICAgICAgRE9NSW1wbCBkb20gPSBuZXcgRE9NSW1wbCgpOwotICAgICAgICBQYXJzZXIgcGFyc2VyID0gbmV3IFBhcnNlcigpOwotICAgICAgICBwYXJzZXIuc2V0RG9jdW1lbnRIYW5kbGVyKGRvbS5nZXRCdWlsZGVyKCkpOwotICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dCA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICBpbnB1dCA9IG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZVJlYWRlcihpbnB1dEZpbGVOYW1lKSk7Ci0gICAgICAgIH0gY2F0Y2goIGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJGaWxlICIgKyBpbnB1dEZpbGVOYW1lICsgIiBub3QgZm91bmQiKTsKLSAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgICAgICB9Ci0KLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHBhcnNlci5wYXJzZShpbnB1dCk7Ci0gICAgICAgIH0gY2F0Y2ggKG9yZy54bWwuc2F4LlNBWEV4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXJyb3I6ICIgKyBlKTsKLSAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKXsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXJyb3I6ICIgKyBlKTsKLSAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgICAgICB9Ci0KLSAgICAgICAgQ2xhc3MgdHJhbnNsZXRQbHVnZ2FibGUgPSBudWxsOwotICAgICAgICB0cnkgewotICAgICAgICAgICAgdHJhbnNsZXRQbHVnZ2FibGUgPSBDbGFzcy5mb3JOYW1lKHRyYW5zbGV0TmFtZSk7Ci0gICAgICAgIH0gY2F0Y2ggKGphdmEubGFuZy5DbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJFcnJvcjogIiArIGUpOwotICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICAgICAgIH0KLQotICAgICAgICBUcmFuc2xldCB0cmFuc2xldCA9IG51bGw7Ci0gICAgICAgIHRyeSB7Ci0gICAgICAgICAgICB0cmFuc2xldCA9IChUcmFuc2xldCl0cmFuc2xldFBsdWdnYWJsZS5uZXdJbnN0YW5jZSgpOwotICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuRXhjZXB0aW9uIGUpewotICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJFcnJvciBpbnN0YW50aWF0aW5nIHBsdWdnYWJsZSB0cmFuc2xldCIpOwotICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICAgICAgIH0KLQotICAgICAgICBIYW5kbGVyIHNheEhhbmRsZXI7Ci0gICAgICAgIFRleHRPdXRwdXQgdGV4dE91dHB1dDsKLSAgICAgICAgdHJ5IHsKLSAgICAgICAgICAgIHNheEhhbmRsZXIgPSBuZXcgSGFuZGxlcigpOwotICAgICAgICAgICAgdGV4dE91dHB1dCA9IG5ldyBUZXh0T3V0cHV0KHNheEhhbmRsZXIsICJ1dGYtOCIpOwotICAgICAgICAgICAgdHJhbnNsZXQudHJhbnNmb3JtKGRvbSwgdGV4dE91dHB1dCk7Ci0gICAgICAgIH0gY2F0Y2ggKFRyYW5zbGV0RXhjZXB0aW9uICBlKXsKLSAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXJyb3I6ICIgKyBlKTsKLSAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOwotICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiAgZSl7Ci0gICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkVycm9yOiAiICsgZSk7Ci0gICAgICAgICAgICBTeXN0ZW0uZXhpdCgxKTsKLSAgICAgICAgfQotICAgfQotCi0gICBwdWJsaWMgdm9pZCB1c2FnZSgpewotICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlVzYWdlOiBcbiIgKwotICAgICAgICAgICAgICAgICIgICAgIHhzbHRhcHAgPHhtbF9maWxlPiA8dHJhbnNsZXRfbmFtZT5cblxuIiArCi0gICAgICAgICAgICAgICAgIiAgICAgd2hlcmUgPGZpbGU+IGlzIHhtbCBzb3VyY2UgKGUuZy4gcGxheS54bWwpLiBcbiIgKwotICAgICAgICAgICAgICAgICIgICAgIGFuZCAgPHRyYW5zbGV0X25hbWU+IGlzIGphdmEgY2xhc3MgKGUuZy4gcGxheTEpLiBcbiIKLSAgICAgICAgKTsKLSAgICAgICAgU3lzdGVtLmV4aXQoMSk7Ci0gICB9Ci19Ci0KLQotCi0zLiBDT01QSUxJTkcgQU5EIFJVTk5JTkcgVEhFIEVYQU1QTEU6Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotVG8gY29tcGlsZSB0aGUgZXhhbXBsZSBhYm92ZSwgYXNzdW1pbmcgeW91IHVucGFja2VkIHRoZSBjb2RlCi1pbnRvIHRoZSBkaXJlY3RvcnkgL3RtcDoKLQotamF2YWMgLWNsYXNzcGF0aCAiL3RtcC94c2x0Yy9saWIveG1sLmphcjovdG1wL3hzbHRjL2xpYi9CQ0VMLmphcjovdG1wL3hzbHRjCi0vbGliL3hzbHRjcnQuamFyIiBYc2x0QXBwLmphdmEKLQotVG8gcnVuIHRoZSBleGFtcGxlIG9uIHhtbCBkb2N1bWVudCAncGxheS54bWwnIGFuZCBzdHlsZXNoZWV0ICdwbGF5MS54c2wnOgotCi0oMSkgY29tcGlsZSB0aGUgc3R5bGVzaGVldDoKLSAgICAgICAgeHNsdGMgcGxheTEueHNsCi0gCi0gICAgdGhpcyB3aWxsIHByb2R1Y2UgdGhlIHRyYW5zbGV0ICdwbGF5MS5jbGFzcycuCi0KLSgyKSBydW4gdGhlIHRyYW5zbGV0IHdpdGggdGhlIFhzbHRBcHAgZGVtbzoKLQotamF2YSAtY2xhc3NwYXRoIC90bXAveHNsdGMvbGliL3hzbHRjcnQuamFyOi90bXAveHNsdGMvbGliL3htbC5qYXI6LiBYc2x0QXBwIHBsYXkKLS54bWwgcGxheTEKLQotCi0gCi00LiBGVUxMIENPREUgRVhBTVBMRSAyLCBEZWZhdWx0UnVuLmphdmEKLQlUaGlzIGV4YW1wbGUgY29ycmVzcG9uZHMgdG8gb3B0aW9uICgyKSBpbiB0aGUgZGlzY3Vzc2lvbiBhYm92ZS4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotU2VlIHRoZSBzb3VyY2UgZmlsZSBmb3IgdGhlIGNsYXNzICdjb20uc3VuLnhzbHQucnVudGltZS5EZWZhdWx0UnVuJywKLXdoaWNoIGlzIGluY2x1ZGVkIGluIHRoZSBzcmMgZGlyZWN0b3J5LiBJdCB1c2VzIHRoZSAKLSdEZWZhdWx0U0FYT3V0cHV0SGFuZGxlcicgYXBwcm9hY2guCi0KLQotCi0KLTUuIEFQUEVORElYCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLQotVGV4dE91dHB1dAotLS0tLS0tLS0tLQotCi1wYWNrYWdlIGNvbS5zdW4ueHNsdC5ydW50aW1lOwotCi1wdWJsaWMgZmluYWwgY2xhc3MgVGV4dE91dHB1dCBpbXBsZW1lbnRzIFRyYW5zbGV0T3V0cHV0SGFuZGxlciB7Ci0JcHVibGljIFRleHRPdXRwdXQoRG9jdW1lbnRIYW5kbGVyIGhhbmRsZXIpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQlwdWJsaWMgVGV4dE91dHB1dChEb2N1bWVudEhhbmRsZXIgaGFuZGxlciwgU3RyaW5nIGVuY29kaW5nKSB0aHJvd3MKLQkJSU9FeGNlcHRpb247Ci19Ci0KLQotRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1wYWNrYWdlIGNvbS5zdW4ueHNsdC5ydW50aW1lOwotCi1wdWJsaWMgY2xhc3MgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIgaW1wbGVtZW50cyBEb2N1bWVudEhhbmRsZXJ7Ci0JcHVibGljIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKFdyaXRlciB3cml0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbjsKLQlwdWJsaWMgRGVmYXVsdFNBWE91dHB1dEhhbmRsZXIoT3V0cHV0U3RyZWFtIG91dCwgU3RyaW5nIGVuY29kaW5nKQotCSAgICB0aHJvd3MgSU9FeGNlcHRpb247Ci0JcHVibGljIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKFN0cmluZyBmaWxlbmFtZSwgU3RyaW5nIGVuY29kaW5nKQotICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOwotCS4uLgotfQotCi0KLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1FTkQgT0YgUkVBRE1FCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRS54c2x0IGIveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUueHNsdApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggM2MwY2JlOC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRS54c2x0CisrKyAvZGV2L251bGwKQEAgLTEsOTcgKzAsMCBAQAotTkFNRQotCXhzbHQgLSBTdW4gWFNMVCBydW50aW1lIHByb2Nlc3Nvci4gCi0KLQotU1lOT1BTSVMKLQl4c2x0IFstaiA8amFyZmlsZT5dIHstdSA8ZG9jdW1lbnRfdXJsPiB8IDxkb2N1bWVudD59IDxjbGFzcz4gCi0gICAgICAgICAgICAgWzxuYW1lMT49PHZhbHVlMT4gLi4uXQotCi0KLURFU0NSSVBUSU9OCi0JVGhlIFN1biBYU0xUIHJ1bnRpbWUgcHJvY2Vzc29yIGlzIGEgSmF2YS1iYXNlZCB0b29sIGZvciAKLQl0cmFuc2Zvcm1pbmcgWE1MIGRvY3VtZW50IGZpbGVzIHVzaW5nIGEgdHJhbnNsZXQgKGNvbXBpbGVkIAotCXN0eWxlc2hlZXQpLiAKLQotCVRoZSBYU0xUIHByb2Nlc3NvciBjYW4gYmUgcnVuIG9uIGFueSBwbGF0Zm9ybSBpbmNsdWRpbmcgVU5JWCwKLQlXaW5kb3dzLCBOVCwgTWFjIHRoYXQgc3VwcG9ydHMgSmF2YSwgaW5jbHVkaW5nIGEgUGFsbSBQaWxvdAotCXdpdGggSjJNRSBDTERDIChKYXZhIDIgTWljcm8gRWRpdGlvbiwgQ29ubmVjdGVkIExpbWl0ZWQgRGV2aWNlCi0JQ29uZmlndXJhdGlvbikuCi0KLU9QVElPTlMKLQotCVRoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcmUgc3VwcG9ydGVkOgotCi0JLWogPGphcmZpbGU+Ci0JCWdldHMgdGhlIHRyYW5zbGV0IDxjbGFzcz4gZnJvbSB0aGUgc3BlY2lmaWVkIDxqYXJmaWxlPgotCQlpbnN0ZWFkIG9mIGZyb20gdGhlIHVzZXIncyBDTEFTU1BBVEguCQotCi0JLXUKLQkJU3BlY2lmaWVzIHRoYXQgdGhlIFhNTCA8ZG9jdW1lbnQ+IGxvY2F0aW9uIHdpbGwgYmUgYSBVUkkKLQkJc3VjaCBhcyAnaHR0cDovL215c2VydmVyL2hhbWxldC54bWwnLgkJCi0KLQotT1BFUkFORFMKLQotCVRoZSBmb2xsb3dpbmcgb3BlcmFuZHMgYXJlIHN1cHBvcnRlZDoKLQotCTxkb2N1bWVudD4gICAgIAkJQW4gWE1MIGRvY3VtZW50IHRvIGJlIHByb2Nlc3NlZC4gCi0JPGRvY3VtZW50X3VybD4gICAgIAlBbiBYTUwgZG9jdW1lbnQgdG8gYmUgcHJvY2Vzc2VkLCBzcGVjaWZpZWQKLQkJCQlhcyBhIFVSTCAoU2VlIC11IG9wdGlvbiBhYm92ZSkuIAotCi0JPGNsYXNzPgkJCVRoZSB0cmFuc2xldCB0aGF0IHdpbGwgZG8gdGhlIHByb2Nlc3NpbmcuCi0JCQkJVGhlIHRyYW5zbGV0IG1heSBvcHRpb25hbGx5IHRha2UgYSBzZXQgb2YgCi0JCQkJZ2xvYmFsIHBhcmFtZXRlcnMgc3BlY2lmaWVkIGFzIG5hbWUtdmFsdWUgCi0JCQkJcGFpcnMuIEEgbmFtZS12YWx1ZSBwYWlyIHVzZXMgdGhlIGZvcm1hdAotCQkJCTxuYW1lPj08dmFsdWU+LgotCi1FWEFNUExFUwotCUV4YW1wbGUgMTogIFByb2Nlc3NpbmcgYW4gWE1MIGRvY3VtZW50LgotCi0JZXhhbXBsZSUgIHhzbHQgaGFtbGV0LnhtbCBoYW1sZXQgCi0KLQl3aGVyZSB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBjb250YWlucyBhbiBYTUwgZG9jdW1lbnQKLQknaGFtbGV0LnhtbCcgdG8gYmUgcHJvY2Vzc2VkIGJ5IHRoZSB0cmFuc2xldCBjbGFzcyAnaGFtbGV0Jy4KLQlUaGUgdHJhbnNsZXQgd291bGQgaGF2ZSBiZWVuIGNyZWF0ZWQgaW5pdGlhbGx5IHVzaW5nCi0JeHNsdGMgdG8gY29tcGlsZSBhIFhTTFQgc3R5bGVzaGVldCBuYW1lZCAnaGFtbGV0LnhzbCcuIAotCi0JRXhhbXBsZSAyOiAgTG9hZGluZyB0cmFuc2xldCBmcm9tIGEgamFyIGZpbGUuIAotCi0JZXhhbXBsZSUgIHhzbHQgLWogaGFtbGV0LmphciBoYW1sZXQueG1sIGhhbWxldAotCi0JSW4gdGhpcyBjYXNlIHRoZSB0cmFuc2xldCBjbGFzcyAnaGFtbGV0JyBpcyBsb2FkZWQgZnJvbSB0aGUKLQlzcGVjaWZpZWQgamFyIGZpbGUsICdoYW1sZXQuamFyJyBpbnN0ZWFkIG9mIGZyb20gdGhlIHVzZXIncwotCUNMQVNTUEFUSC4KLQotCUV4YW1wbGUgMzogSWYgdGhlIHRyYW5zbGV0IGRlZmluZWQgZ2xvYmFsIHBhcmFtZXRlcnMsIHRoZW4gCi0JdGhlc2UgY2FuIGJlIHBhc3NlZCBvbiB0aGUgY29tbWFuZCBsaW5lIHRvIHRoZSBydW50aW1lIHByb2Nlc3NvcgotCWFzIGEgc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgbmFtZS12YWx1ZSBwYWlycyB1c2luZyB0aGUgZm9ybWF0Ci0JPG5hbWU+PTx2YWx1ZT4uIEZvciBleGFtcGxlLAotCi0JZXhhbXBsZSUgIHhzbHQgaGFtbGV0LnhtbCBoYW1sZXQgc3BlYWtlcj1IQU1MRVQgJ3NjZW5lPVNDRU5FIElWJwotCi0JTm90aWNlIHRoYXQgdGhlIHNlY29uZCBuYW1lLXZhbHVlIHBhaXIgaGFkIHRvIGJlIHF1b3RlZCBkdWUgdG8gCi0JdGhlIGludGVydmVuaW5nIHNwYWNlIGluIHRoZSB2YWx1ZSAiU0NFTkUgSVYiLgotCi0JZXhhbXBsZSUgeHNsdCAtdSBodHRwOi8vemFyeWEuZWFzdC90ZXN0LnhtbCBoYW1sZXQKLQotCXdoZXJlIHRoZSB4bWwgZG9jdW1lbnQgJ3Rlc3QueG1sJyBjYW4gYmUgc3BlY2lmaWVkIGFzIGEgVVJMLgotCi1GSUxFUwotCWZpbGUueG1sCQlpbnB1dCBYTUwgZG9jdW1lbnQgdG8gYmUgcHJvY2Vzc2VkLiAKLQlmaWxlLmNsYXNzCQlieXRlIGNvZGUgZmlsZS4KLQlmaWxlLmphcgkJamF2YSBhcmNoaXZlIGZpbGUuCi0JCi1TRUUgQUxTTwotCXhzbHRjLCBqYXIuCi0KLUJVR1MKLQlSZWZlciB0byB0aGUgdG9wLWxldmVsIFJFQURNRSBpbmNsdWRlZCBpbiB0aGlzIHJlbGVhc2UuCi0KLUFVVEhPUlMKLQlKYWNlayBBbWJyb3ppYWssICAgICAgICAgICAgICAgICAgICAgICBqYWNlay5hbWJyb3ppYWtARWFzdC5TdW4uQ09NCi0JU2FudGlhZ28gUGVyaWNhcy1HZWVydHNlbiwgICAgc2FudGlhZ28ucGVyaWNhc2dlZXJ0c2VuQEVhc3QuU3VuLkNPTSAKLQotCUNvbnRyaWJ1dG9yczoKLQotCU1vcnRlbiBKb3JnZW5zZW4JCSAgIG1vcnRlbi5qb3JnZW5zZW5ASXJlbGFuZC5TdW4uQ09NCi0JRy4gVG9kZCBNaWxsZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvZGQubWlsbGVyQEVhc3QuU3VuLkNPTQpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUueHNsdGMgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRS54c2x0YwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTBjNzdkNC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRS54c2x0YworKysgL2Rldi9udWxsCkBAIC0xLDExNiArMCwwIEBACi1OQU1FCi0JeHNsdGMgLSBTdW4gWFNMVCBDb21waWxlciAKLQotCi1TWU5PUFNJUwotCXhzbHRjIFstbyA8b3V0cHV0Pl0gWy1kIDxkaXJlY3Rvcnk+XSBbLWogPGphcmZpbGU+XSAKLQkgICAgICBbLXAgPHBhY2thZ2UgbmFtZT5dCi0gICAgICAgICAgICAgIFstdV0gPHN0eWxlc2hlZXQ+Li4uIAotCi0KLURFU0NSSVBUSU9OCi0JVGhlIFN1biBYU0xUIENvbXBpbGVyIGlzIGEgSmF2YS1iYXNlZCB0b29sIGZvciBjb21waWxpbmcgWFNMVAotCXN0eWxlc2hlZXRzIGludG8gbGlnaHR3ZWlnaHQgYW5kIHBvcnRhYmxlIEphdmEgYnl0ZSBjb2RlcyAKLQljYWxsZWQgdHJhbnNsZXRzLiAgCi0KLQlUaGUgWFNMVCBDb21waWxlciBjYW4gYmUgcnVuIG9uIGFueSBwbGF0Zm9ybSBpbmNsdWRpbmcgVU5JWCwKLQlXaW5kb3dzLCBOVCwgTWFjIHRoYXQgc3VwcG9ydHMgSmF2YSAxLjIueCBvciBsYXRlci4gVGhlIGdlbmVyYXRlZAotCXRyYW5zbGV0cyBjYW4gYmUgcnVuIG9uIGFueSBwbGF0Zm9ybSB0aGF0IHN1cHBvcnRzIGEgSmF2YQotCVJ1bnRpbWUgRW52aXJvbm1lbnQsIGluY2x1ZGluZyBhIFBhbG0gUGlsb3Qgd2l0aCBKMk1FIENMREMgCi0JKEphdmEgMiBNaWNybyBFZGl0aW9uLCBDb25uZWN0ZWQgTGltaXRlZCBEZXZpY2UgQ29uZmlndXJhdGlvbikuCi0KLU9QVElPTlMKLQotCVRoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcmUgc3VwcG9ydGVkOgotCi0JLW8gPG91dHB1dD4KLQkJQ2hhbmdlcyB0aGUgbmFtZSBvZiB0aGUgZ2VuZXJhdGVkIHRyYW5zbGV0IGNsYXNzLgotCQlCeSBkZWZhdWx0LCB0aGUgdHJhbnNsZXQgY2xhc3Mgd291bGQgYmUgbmFtZWQKLQkJPHN0eWxlc2hlZXQ+LCBpZiAtbyA8b3V0cHV0PiBpcyBzZXQsIHRoZW4gdGhlIAotCQl0cmFuc2xldCBjbGFzcyB3b3VsZCBiZSBuYW1lZCA8b3V0cHV0Pi4gVHJhbnNsZXQKLQkJY2xhc3MgZmlsZXMgYXJlIHdyaXR0ZW4gYXMgLmNsYXNzIGZpbGVzLgotCi0JLWQgPGRpcmVjdG9yeT4KLQkJQ2hhbmdlcyB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5LiBCeSBkZWZhdWx0LCBhbnkKLQkJdHJhbnNsZXQgY2xhc3MgZmlsZXMgZ2VuZXJhdGVkIHdvdWxkIGJlIHBsYWNlZCBpbiAKLQkJdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuIElmIC1kIDxkaXJlY3Rvcnk+IAotCQlpcyBzcGVjaWZpZWQsIHRoZSBmaWxlcyB3b3VsZCBiZSBvdXRwdXQgdG8gPGRpcmVjdG9yeT4uCi0KLQktaiA8amFyZmlsZT4KLQkJT3V0cHV0cyBhbGwgZ2VuZXJhdGVkIHRyYW5zbGV0IGNsYXNzIGZpbGVzIGludG8gYSAKLQkJamFyIGZpbGUgbmFtZWQgPGphcmZpbGU+Lmphci4gV2hlbiB0aGlzIG9wdGlvbiBpcyAKLQkJdXNlZCBvbmx5IGEgamFyIGZpbGUgd2lsbCBiZSBvdXRwdXQuCi0KLQktcCA8cGFja2FnZSBuYW1lPgotCQlTcGVjaWZ5IGEgcGFja2FnZSBuYW1lIGZvciBhbGwgZ2VuZXJhdGVkIHRyYW5zbGV0Ci0JCWNsYXNzZXMuCQkKLQotCS11Ci0JCVNwZWNpZmllcyB0aGF0IDxzdHlsZXNoZWV0PiBsb2NhdGlvbiB3aWxsIGJlIGEgVVJJCi0JCXN1Y2ggYXMgJ2h0dHA6Ly9teXNlcnZlci9zdHlsZXNoZWV0MS54c2wnLgkJCi0KLQotT1BFUkFORFMKLQotCVRoZSBmb2xsb3dpbmcgb3BlcmFuZCBpcyBzdXBwb3J0ZWQ6Ci0KLQk8c3R5bGVzaGVldD4gICAgQSBwYXRoIG5hbWUgb2YgYW4gaW5wdXQgc3R5bGVzaGVldCBmaWxlLiAKLQotCi1FWEFNUExFUwotCUV4YW1wbGUgMTogIENyZWF0aW5nIGEgdHJhbnNsZXQgZnJvbSBzdHlsZXNoZWV0ICdoYW1sZXQueHNsJy4KLQotCWV4YW1wbGUlICB4c2x0YyBoYW1sZXQueHNsCi0KLQl3b3VsZCBwcm9kdWNlIGEgc2V0IG9mIGNsYXNzIGZpbGVzIHN1Y2ggYXMgJ2hhbWxldC5jbGFzcycsCi0JJ2hhbWxldCQwLmNsYXNzJywgJ2hhbWxldCQxLmNsYXNzJy4KLQotCUV4YW1wbGUgMjogIE91dHB1dHRpbmcgYWxsIGNsYXNzZXMgaW50byBhIGphciBmaWxlLgotCi0JZXhhbXBsZSUgIHhzbHRjIC1qIGhhbWxldC5qYXIgaGFtbGV0LnhzbAotCi0Jd291bGQgcHJvZHVjZSBhIHNpbmdsZSBqYXIgZmlsZSBvdXRwdXQsICdoYW1sZXQuamFyJyB3aGljaCB3b3VsZAotCWNvbnRhaW4gYWxsIHRoZSBnZW5lcmF0ZWQgLmNsYXNzIGZpbGVzIGZvciB0aGUgaGFtbGV0IHRyYW5zbGV0LgotCi0JRXhhbXBsZSAzOiBOYW1pbmcgdGhlIGNsYXNzIGZpbGUuICAKLQotCWV4YW1wbGUlICB4c2x0YyAtbyBuZXdoYW1sZXQgaGFtbGV0LnhzbAotCi0Jd291bGQgcHJvZHVjZSBhIHNldCBvZiBjbGFzcyBmaWxlcyBzdWNoIGFzICduZXdoYW1sZXQuY2xhc3MnLAotCSduZXdoYW1sZXQkMC5jbGFzcycsIGV0YyByYXRoZXIgdGhhbiB0aGUgZGVmYXVsdCB3aGljaCB3b3VsZCAKLQliZSAnaGFtbGV0LmNsYXNzJywgJ2hhbWxldCQwLmNsYXNzJywgZXRjLgkKLQotCUV4YW1wbGUgNDogTXVsdGlwbGUgc3R5bGVzaGVldHMuIAotCi0JZXhhbXBsZSUgIHhzbHRjIGhhbWxldDEueHNsIGhhbWxldDIueHNsIGhhbWxldDMueHNsCi0KLQl3b3VsZCBwcm9kdWNlIGEgc2V0IG9mIGNsYXNzIGZpbGVzIGRlcml2ZWQgZnJvbSB0aGUgdGhyZWUKLQlzdHlsZXNoZWV0cy4gCi0KLQlFeGFtcGxlIDU6IFBhY2thZ2UgU3BlY2lmaWNhdGlvbi4KLQotCWV4YW1wbGUlIHhzbHRjIC1wIGNvbS5teWNvbXBhbnkudHJhbnNsZXRzIGhhbWxldC54c2wKLQotCXdvdWxkIHByb2R1Y2UgYSBzZXQgb2YgY2xhc3MgZmlsZXMgc3VjaCBhcyAKLQknY29tL215Y29tcGFueS90cmFuc2xldHMvaGFtbGV0LmNsYXNzJywKLQknY29tL215Y29tcGFueS90cmFuc2xldHMvaGFtbGV0JDAuY2xhc3MnLCBldGMuCi0KLUZJTEVTCi0JZmlsZS54c2wJCWlucHV0IFhTTFQgc3R5bGVzaGVldAotCWZpbGUuY2xhc3MJCWJ5dGUgY29kZSBmaWxlCi0JZmlsZS5qYXIJCWphdmEgYXJjaGl2ZSBmaWxlCi0JCi1TRUUgQUxTTwotCXhzbHQsIGphci4KLQotQlVHUwotCVJlZmVyIHRvIHRoZSB0b3AtbGV2ZWwgUkVBRE1FIGluY2x1ZGVkIGluIHRoaXMgcmVsZWFzZS4KLQotQVVUSE9SUwotCUphY2VrIEFtYnJvemlhaywgICAgICAgICAgICAgICAgICAgICAgIGphY2VrLmFtYnJvemlha0BFYXN0LlN1bi5DT00KLQlTYW50aWFnbyBQZXJpY2FzLUdlZXJ0c2VuLCAgICBzYW50aWFnby5wZXJpY2FzZ2VlcnRzZW5ARWFzdC5TdW4uQ09NIAotCi0JQ29udHJpYnV0b3JzOgotCi0JTW9ydGVuIEpvcmdlbnNlbgkJICAgbW9ydGVuLmpvcmdlbnNlbkBJcmVsYW5kLlN1bi5DT00KLQlHLiBUb2RkIE1pbGxlciwgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9kZC5taWxsZXJARWFzdC5TdW4uQ09NCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRTIgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL1JFQURNRTIKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGM3Y2Q2MWYuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9SRUFETUUyCisrKyAvZGV2L251bGwKQEAgLTEsODYgKzAsMCBAQAotUkVBRE1FLkFQQUNIRQotPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci1FbnRpcmUgc291cmNlIHRyZWUgYW5kIHN1cHBvcnQgcGFja2FnZXMgYXJlIGxvY2F0ZWQgaW4gdGhlIHNpbmdsZSBqYXIKLWZpbGUgJ2FwYWNoZS5qYXInLiAKLQotCi1JbnN0YWxsYXRpb24KLS0tLS0tLS0tLS0tLS0KLQotKDEpIGNyZWF0ZSBkaXJlY3RvcnkgW1Jvb3RdLCB1bnBhY2sgJ2FwYWNoZS5qYXInIHRoZXJlLgotCWV4KSAlIGNkIC90bXA7IG1rZGlyIHhzbHRjX2FwYWNoZSAKLQkgICAgJSBjZCB4c2x0Y19hcGFjaGUKLSAgICAgICAgY29weSBhcGFjaGUuamFyIHRvIHhzbHRjX2FwYWNoZSBkaXJlY3RvcnkKLQkgICAgJSBqYXIgeHZmIGFwYWNoZS5qYXIgCi0JY2xlYW51cAotCSAgICAlIHJtIC1yZiBNRVRBLUlORiBhcGFjaGUuamFyCi0KLSAgICBVbnBhY2tpbmcgdGhlIGphciBmaWxlIHdpbGwgcmVzdWx0IGluIHRoZSBmb2xsb3dpbmcgdHJlZToKLQotCVtSb290XQotCSAgRXh0ZXJuYWwvCi0JICAgIEJDRUwvICAgICAgICAgICAgICAgIC4uLiBjb250YWlucyBCQ0VMLmphcgotCSAgICBKTGV4LyAgICAgICAgICAgICAgICAuLi4gY29udGFpbnMgSkxleC5qYXIKLQkgICAgamF2YV9jdXAvICAgICAgICAgICAgLi4uIGNvbnRhaW5zIGphdmFfY3VwLmphciwgcnVudGltZS9ydW50aW1lLmphcgotCSAgICB4bWwtdHIyLyAgICAgICAgICAgICAuLi4gY29udGFpbnMgeG1sLmphcgotCSAgYmluLwotCSAgICB4c2x0Ci0JICAgIHhzbHRjCi0JICBkb2MvCi0JICAgIGFwaS8gICAgICAgICAgICAgICAgIC4uLiBjb250YWlucyBqYXZhZG9jIGZvciBhcGkKLQkgIHNyYy8KLQkgICAgR05VbWFrZWZpbGUKLQkgICAgR05VbWFrZWZpbGUuYWxsaW5jCi0JICAgIGRvY3MvCi0JICAgICAgTElDRU5TRS50eHQKLQkgICAgICBNZXNzYWdlLnR4dAotCSAgICAgIFJFQURNRQotCSAgICAgIFJFQURNRS5hcGkKLQkgICAgICBSRUFETUUueHNsdAotCSAgICAgIFJFQURNRS54c2x0YwotCSAgICAgIFhTTFRDcHJuX2xnLnR4dCoKLQkgICAgICB4c2x0Y0EzLnR4dAotCSAgICBvcmcvCi0JICAgICAgYXBhY2hlLwotCQl4YWxhbi8KLQkJICB4c2x0Yy8KLQkJICAgICAoc3JjIHRyZWUpICAuLi4gYWxsIHRoZSBzb3VyY2UgY29kZSBmaWxlcwotCi0KLSAgICBUaGUgJ3NyYyB0cmVlJyBpcyBhIGhpZXJhcmNoeSBvZiB0aGUgZm9sbG93aW5nIHBhY2thZ2VzOgotCW9yZy5hcGFjaGUueGFsYW4ueHNsdGMKLQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmNvbXBpbGVyCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci51dGlsCi0Jb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20KLQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUKLQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWwKLQlvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnV0aWwuZ2V0b3B0Ci0KLQotKDIpIG1ha2UgYmluIHByb2dyYW1zIGV4ZWN1dGFibGUKLQkgICAgJSBjaG1vZCAreCBiaW4vKgotCi0oMykgc2V0IGVudiB2YXJpYWJsZSB0byBwb2ludCB0byB0b3Agb2YgZGlyZWN0b3J5IFtSb290XQotCWV4KSAlIHNldGVudiBYU0xUIC90bXAveHNsdGNfYXBhY2hlCi0KLSg0KSBjb21waWxlIHNvdXJjZXMgKHVzZXMgZ251IG1ha2UgYW5kIHRoZSBwcm92aWRlcyAnR05VbWFrZWZpbGUnKS4gVGhpcwotICAgIHdpbGwgY3JlYXRlIGphdmEgY2xhc3NlcyBpbiBbUm9vdF0vY2xhc3NlcywgZS5nLiAvdG1wL3hzbHRjX2FwYWNoZS9jbGFzc2VzLgotICAgIChObyBuZWVkIHRvIHNldCB5b3VyIENMQVNTUEFUSCB2YXJpYWJsZS4pCi0gICAgCi0JZXgpICUgY2Qgc3JjOyBnbWFrZSBhZ2FpbgotCi0gICAgTm90ZTogdGhlICdhZ2FpbicgdGFyZ2V0IGZvcmNlcyBldmVyeXRoaW5nIHRvIGJlIGJ1aWx0IGZyb20gc2NyYXRjaCwKLSAgICBpbmNsdWRpbmcgdGhlIGphdmFfY3VwIHNvdXJjZSBmaWxlcy4gU3Vic2VxdWVudCBidWlsZHMgY2FuIGJlIGRvbmUKLSAgICB1c2luZyB0aGUgJ2NsYXNzZXMnIHRhcmdldC4gCi0KLSg1KSBtYWtlIHRoZSBqYXZhZG9jCi0JZXgpICUgZ21ha2UgamRvYwotCi0oNikgYWRkIGJpbiBkaXJlY3RvcnkgdG8geW91ciBleGVjdXRhYmxlIHBhdGgsIAotCWV4KSAlIHNldCBwYXRoPSgkWFNMVC9iaW4gJHBhdGgpCi0KLSg3KSB0ZXN0IGRpc3RyaWJ1dGlvbiwgZ2l2ZW4gYSBzdHlsZXNoZWV0ICh0ZXN0LnhzbCkgYW5kIGFuIGlucHV0IHhtbCBkb2MKLSAgICAodGVzdC54bWwpLCBhbmQgYmUgc3VyZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5ICguKSBpcyBpbiB5b3VyCi0gICAgQ0xBU1NQQVRILgotIAklIHhzbHRjIHRlc3QueHNsCQkuLi4gY3JlYXRlcyB0cmFuc2xldCwgdGVzdC5jbGFzcwotCSUgeHNsdCB0ZXN0LnhtbCB0ZXN0CQkuLi4gcnVucyB0cmFuc2xldCBvbiB4bWwgaW5wdXQJCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2FsbF9uYW1lc3BhY2VzLmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvYWxsX25hbWVzcGFjZXMuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzODAzNGI3Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvYWxsX25hbWVzcGFjZXMuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9jYXN0X2V4cHJlc3Npb24uZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9jYXN0X2V4cHJlc3Npb24uZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5YmIwMDkwLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvY2FzdF9leHByZXNzaW9uLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvY29tcGlsZXJfQVNULmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvY29tcGlsZXJfQVNULmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjk4NzFiNi4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2NvbXBpbGVyX0FTVC5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2NvbXBpbGVyX0RPTS5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL2NvbXBpbGVyX0RPTS5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGEwNTZjYmIuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9jb21waWxlcl9ET00uZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9jb21waWxlcl9hcmNoaXRlY3R1cmUuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9jb21waWxlcl9hcmNoaXRlY3R1cmUuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlNTdkNjYxLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvY29tcGlsZXJfYXJjaGl0ZWN0dXJlLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvZG9tX25hbWVzcGFjZTEuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9kb21fbmFtZXNwYWNlMS5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiOTQxOGUuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9kb21fbmFtZXNwYWNlMS5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2RvbV9uYW1lc3BhY2UyLmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvZG9tX25hbWVzcGFjZTIuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZmNlMjRkLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvZG9tX25hbWVzcGFjZTIuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9kb21fbmFtZXNwYWNlMy5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL2RvbV9uYW1lc3BhY2UzLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZDYyYjliOC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2RvbV9uYW1lc3BhY2UzLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvaW5kZXgueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy9pbmRleC54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGNiZTE4NzguLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9pbmRleC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMTggKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci08czEgdGl0bGU9IkludHJvZHVjdGlvbiB0byBYU0xUQyI+Ci0gICAgPHA+PHJlZj5EZXNpZ24gZG9jdW1lbnRzIGJ5IDxqdW1wIGhyZWY9Im1haWx0bzptb3J0ZW5AeG1sLmFwYWNoZS5vcmciPk1vcnRlbiBKJm9zbGFzaDtyZ2Vuc2VuPC9qdW1wPiAKLSAgICAtIHVwZGF0ZWQgMDYuMDMuMjAwMTwvcmVmPjwvcD4KLTx1bD4KLSAgPGxpPjxsaW5rIGFuY2hvcj0iY29tcGlsZXIiPkNvbXBpbGVyIGRlc2lnbjwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJydW50aW1lIj5SdW50aW1lIGxpYnJhcnkvRE9NIGRlc2lnbjwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgaWRyZWY9InhzbHRjX3RyYXgiPkludGVncmF0aW9uIG9mIHRoZSBUcmFuc2xldCBBUEkgYW5kIFRyQVg8L2xpbms+IChieSBHIFRvZGQgTWlsbGVyKTwvbGk+IAotICAgCi08L3VsPgotPHA+U2VlIGFsc28gPGp1bXAgaHJlZj0iLi4veHNsdGNfdXNhZ2UuaHRtbCI+VXNpbmcgWFNMVEM8L2p1bXA+LjwvcD4KLTxhbmNob3IgbmFtZT0iY29tcGlsZXIiLz4KLSA8czIgdGl0bGU9IkNvbXBpbGVyIGRlc2lnbiI+Ci0gIDxwPjxsaW5rIGlkcmVmPSJ4c2x0Y19jb21waWxlciI+PGltZyBzcmM9ImNvbXBpbGVyX2FyY2hpdGVjdHVyZS5naWYiIGFsdD0iY29tcGlsZXJfYXJjaGl0ZWN0dXJlLmdpZiIvPjwvbGluaz48L3A+Ci0gIDxwPjxyZWY+RmlndXJlIDE6IENvbXBpbGVyIGFyY2hpdGVjdHVyZSBvdmVydmlldzwvcmVmPjwvcD4KLSAgPHA+Q2xpY2sgb24gdGhlIHBpY3R1cmUgdG8ganVtcCB0byB0aGUgb3ZlcmFsbCBkZXNpZ24gZG9jdW1lbnQgZm9yIHRoZSBjb21waWxlci48L3A+Ci0gICAgPHA+RWFjaCBYU0wgZWxlbWVudC9mdW5jdGlvbiBhbmQgWFBhdGggZXhwcmVzc2lvbi9wYXR0ZXJuIGlzIHJlcHJlc2VudGVkIGJ5Ci0gIGl0cyBvd24gY2xhc3MgaW4gdGhlIEFic3RyYWN0IFN5bnRheCBUcmVlIChBU1QpLiBTb21lIG9mIHRoZXNlIGNsYXNzZXMgaGF2ZQotICB0aGVpciBvd24gZGVzaWduIGRvY3VtZW50cyAoSSBhbSB3b3JraW5nIG9uIHRoZSByZXN0IG9mIHRoZW0pOjwvcD4KLSAgICA8czMgdGl0bGU9IlhTTCBlbGVtZW50cyI+Ci0gICAgICAgIDx1bD4KLSAgICAgICAgICA8bGk+Ci0gICAgICAgICAgICA8bGluayBpZHJlZj0ieHNsX3doaXRlc3BhY2VfZGVzaWduIj4mbHQ7eHNsOnByZXNlcnZlLXNwYWNlJmd0Oy8mbHQ7eHNsOnN0cmlwLXNwYWNlJmd0OzwvbGluaz4KLSAgICAgICAgICA8L2xpPgotICAgICAgICAgIDxsaT4KLSAgICAgICAgICAgIDxsaW5rIGlkcmVmPSJ4c2xfc29ydF9kZXNpZ24iPiZsdDt4c2w6c29ydCZndDs8L2xpbms+Ci0gICAgICAgICAgPC9saT4KLSAgICAgICAgICA8bGk+Ci0gICAgICAgICAgICA8bGluayBpZHJlZj0ieHNsX2tleV9kZXNpZ24iPiZsdDt4c2w6a2V5Jmd0OzwvbGluaz4KLSAgICAgICAgICA8L2xpPgotICAgICAgICAgIDxsaT4KLSAgICAgICAgICAgIDxsaW5rIGlkcmVmPSJ4c2xfY29tbWVudF9kZXNpZ24iPiZsdDt4c2w6Y29tbWVudCZndDsvJmx0O3hzbDptZXNzYWdlJmd0OzwvbGluaz4KLSAgICAgICAgICA8L2xpPgotICAgICAgICA8L3VsPgotICAgICAgICA8L3MzPgotICAgICAgICA8czMgdGl0bGU9IlhTTCBmdW5jdGlvbnMiPgotICAgICAgICA8dWw+Ci0gICAgICAgICAgPGxpPgotICAgICAgICAgICAgPGxpbmsgaWRyZWY9InhzbF9rZXlfZGVzaWduIj5rZXkoKTwvbGluaz4KLSAgICAgICAgICA8L2xpPgotICAgICAgICAgIDxsaT4KLSAgICAgICAgICAgIDxsaW5rIGlkcmVmPSJ4c2xfbGFuZ19kZXNpZ24iPmxhbmcoKTwvbGluaz4KLSAgICAgICAgICA8L2xpPgotICAgICAgICAgIDxsaT4KLSAgICAgICAgICAgIDxsaW5rIGlkcmVmPSJ4c2xfdW5wYXJzZWRfZGVzaWduIj51bnBhcnNlZC1lbnRpdHktdXJpKCk8L2xpbms+Ci0gICAgICAgICAgPC9saT4KLSAgICAgICAgPC91bD4KLSAgPC9zMz4KLSAgPC9zMj48YW5jaG9yIG5hbWU9InJ1bnRpbWUiLz4KLSAgPHMyIHRpdGxlPSJSdW50aW1lIGxpYnJhcnkvRE9NIGRlc2lnbiI+Ci0gIDxwPjxsaW5rIGlkcmVmPSJ4c2x0Y19ydW50aW1lIj48aW1nIHNyYz0icnVudGltZV9hcmNoaXRlY3R1cmUuZ2lmIiBhbHQ9InJ1bnRpbWVfYXJjaGl0ZWN0dXJlLmdpZiIvPjwvbGluaz48L3A+Ci0gIDxwPjxyZWY+RmlndXJlIDI6IFJ1bnRpbWUgbGlicmFyeSBhcmNoaXRlY3R1cmUgb3ZlcnZpZXc8L3JlZj48L3A+Ci0gIDxwPkNsaWNrIG9uIHRoZSBwaWN0dXJlIHRvIGp1bXAgdG8gdGhlIG92ZXJhbGwgZGVzaWduIGRvY3VtZW50IGZvciB0aGUgWFNMVEMKLSAgcnVudGltZSBsaWJyYXJ5LiBUaGlzIGRvY3VtZW50IGRlc2NyaWJlcyB0aGUgc3RydWN0dXJlIG9mIHRoZSBjb21waWxlZAotICB0cmFuc2xldCBhcyB3ZWxsIGFzIHRoZSB0cmFuc2xldCBydW50aW1lIGxpYnJhcnkuPC9wPiAKLSAgPHA+VGhlIDxsaW5rIGlkcmVmPSJ4c2x0Y19kb20iPkludGVybmFsIERPTTwvbGluaz4gZGVzY3JpYmVzIHRoZSBjb21wb25lbnRzIGFuZCBzdHJ1Y3R1cmUgb2YgdGhlIGludGVybmFsIERPTSwKLSAgIHN1cHBvcnQgZm9yIERPTTIgbmF2aWdhdGlvbiwgdGhlIERPTSBhZGFwdGVyLCBET00gbXVsdGlwbGV4ZXIsIGFuZCBET00gYnVpbGRlci48L3A+Ci0gICAgPHA+PGxpbmsgaWRyZWY9InhzbHRjX25hbWVzcGFjZSI+TmFtZXNwYWNlczwvbGluaz4gZXhwbGFpbnMgaG93IFhTTFRDIChpbmNsdWRpbmcgdGhlIGNvbXBpbGVyKSBoYW5kbGVzCi0gICAgIG5hbWVzcGFjZXMuPC9wPiAgIAotICA8L3MyPgotPC9zMT4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2tleV9yZWxhdGlvbnMuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9rZXlfcmVsYXRpb25zLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTQ2ZDRkYy4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL2tleV9yZWxhdGlvbnMuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9tYXRjaF9uYW1lc3BhY2UxLmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvbWF0Y2hfbmFtZXNwYWNlMS5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRkMDA1NmQuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9tYXRjaF9uYW1lc3BhY2UxLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvbWF0Y2hfbmFtZXNwYWNlMi5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL21hdGNoX25hbWVzcGFjZTIuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkYjEwMjc3Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvbWF0Y2hfbmFtZXNwYWNlMi5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL25hbWVzcGFjZV9zdGFjay5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL25hbWVzcGFjZV9zdGFjay5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGE0NjlkMjMuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9uYW1lc3BhY2Vfc3RhY2suZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9vdXRwdXRfbmFtZXNwYWNlczEuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9vdXRwdXRfbmFtZXNwYWNlczEuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1MDY4ZmMyLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvb3V0cHV0X25hbWVzcGFjZXMxLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvb3V0cHV0X25hbWVzcGFjZXMyLmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvb3V0cHV0X25hbWVzcGFjZXMyLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYWFmN2NmNy4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL291dHB1dF9uYW1lc3BhY2VzMi5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3BhdHRlcm5fb2JqZWN0cy5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3BhdHRlcm5fb2JqZWN0cy5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGVhMDczOTMuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9wYXR0ZXJuX29iamVjdHMuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy9ydW50aW1lX2FyY2hpdGVjdHVyZS5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3J1bnRpbWVfYXJjaGl0ZWN0dXJlLmdpZgpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOWM4ZTJlNy4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3J1bnRpbWVfYXJjaGl0ZWN0dXJlLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvcnVudGltZV90eXBlX21hcHBpbmcuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy9ydW50aW1lX3R5cGVfbWFwcGluZy5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDc2OWE5OTMuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9ydW50aW1lX3R5cGVfbWFwcGluZy5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3NvcnRfb2JqZWN0cy5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3NvcnRfb2JqZWN0cy5naWYKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBlYzdjYmIuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy9zb3J0X29iamVjdHMuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy90eXBlX21hcHBpbmcuZ2lmIGIveGRvY3Mvc291cmNlcy94c2x0Yy90eXBlX21hcHBpbmcuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiYjNjYmI5Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvdHlwZV9tYXBwaW5nLmdpZgorKysgL2Rldi9udWxsCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMvdHlwZV9tYXBwaW5ncy5naWYgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3R5cGVfbWFwcGluZ3MuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzMWY4ODhjLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvdHlwZV9tYXBwaW5ncy5naWYKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3R5cGVjYXN0LmdpZiBiL3hkb2NzL3NvdXJjZXMveHNsdGMvdHlwZWNhc3QuZ2lmCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyYTljMTY4Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMvdHlwZWNhc3QuZ2lmCisrKyAvZGV2L251bGwKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfY29tbWVudF9kZXNpZ24ueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfY29tbWVudF9kZXNpZ24ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmY2MwZmVmLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX2NvbW1lbnRfZGVzaWduLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDExMSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLTwhLS0gCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLSAgPHMxIHRpdGxlPSImbHQ7eHNsOmNvbW1lbnQmZ3Q7IC8gJmx0O3hzbDptZXNzYWdlJmd0OyI+Ci0gIDx1bD4KLSAgPGxpPjxsaW5rIGFuY2hvcj0iZnVuY3Rpb25hbGl0eSI+RnVuY3Rpb25hbGl0eTwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJpbXBsZW1lbnRhdGlvbiI+SW1wbGVtZW50YXRpb248L2xpbms+PC9saT4gIAotICA8L3VsPgotPGFuY2hvciBuYW1lPSJmdW5jdGlvbmFsaXR5Ii8+Ci08czIgdGl0bGU9IkZ1bmN0aW9uYWxpdHkiPgotCi0gIDxwPlRoZSA8Y29kZT4mbHQ7eHNsOmNvbW1lbnQmZ3Q7PC9jb2RlPiBlbGVtZW50IGlzIHVzZWQgdG8gaW5zZXJ0IFhNTCBjb21tZW50cwotICBpbnRvIHRoZSByZXN1bHQgZG9jdW1lbnQuIFRoZSBjb21tZW50IGlzIGluc2VydGVkIGFzIGZvbGxvd3MgaW4gdGhlIFhTTAotICBzdHlsZXNoZWV0OjwvcD4KLQotICA8c291cmNlPiAgICAmbHQ7ZWxlbWVudCZndDsKLSAgICAgICZsdDt4c2w6Y29tbWVudCZndDtUaGlzIGlzIGEgY29tbWVudCEmbHQ7L3hzbDpjb21tZW50Jmd0OwotICAgICZsdDsvZWxlbWVudCZndDs8L3NvdXJjZT4KLQotICA8cD5hbmQgaXQgd2lsbCBiZSBvdXRwdXQgaW4gdGhlIHJlc3VsdCBkb2N1bWVudCBhcyBmb2xsb3dzOjwvcD4KLQotICA8c291cmNlPiAgICAmbHQ7ZWxlbWVudCZndDsKLSAgICAgICZsdDshLS0gVGhpcyBpcyBhIGNvbW1lbnQhIC0tJmd0OwotICAgICZsdDsvZWxlbWVudCZndDs8L3NvdXJjZT4KLQotICA8cD5UaGUgPGNvZGU+Jmx0O3hzbDptZXNzYWdlJmd0OzwvY29kZT4gZWxlbWVudCBpcyB1c2VkIHRvIHNlbmQgbWVzc2FnZXMgdG8KLSAgd2hvL3doYXRldmVyIGlzIHBlcmZvcm1pbmcgdGhlIHRyYW5zZm9ybWF0aW9uLiBUaGUgbWVzc2FnZSBjYW4gYmUgZGlzcGxheWVkCi0gIGluIGEgdGVybWluYWwsIGEgZGlhbG9nIGJveCwgZXRjLiBUaGUgIDxjb2RlPiZsdDt4c2w6bWVzc2FnZSZndDs8L2NvZGU+IGVsZW1lbnQKLSAgaXMgdXNlZCBpbiB0aGUgc2FtZSB3YXkgYXMgdGhlIDxjb2RlPiZsdDt4c2w6Y29tbWVudCZndDs8L2NvZGU+IGVsZW1lbnQsCi0gIGhvd2V2ZXIgdGhlIG1lc3NhZ2UgaXMgPGVtPm5vdDwvZW0+IG91dHB1dCBpbiB0aGUgcmVzdWx0IGRvY3VtZW50LjwvcD4KLQotICA8cD5UaGUgPGNvZGU+Jmx0O3hzbDptZXNzYWdlJmd0OzwvY29kZT4gZWxlbWVudCBoYXMgYW4gYXR0cmlidXRlCi0gIDxjb2RlPiJ0ZXJtaW5hdGUiPC9jb2RlPiB3aGljaCBjYW4gYmUgdXNlZCB0byB0ZXJtaW5hdGUgdGhlIHRyYW5zZm9ybWF0aW9uIGF0IGFueQotICBnaXZlbiBzdGFnZS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB1c2luZyBtZXNzYWdlIHRvIGdpdmUgaW5mb3JtYXRpb24gYWJvdXQKLSAgaWxsZWdhbCB2YWx1ZXMgaW4gdGhlIGlucHV0IGRvY3VtZW50LjwvcD4KLTwvczI+PGFuY2hvciBuYW1lPSJpbXBsZW1lbnRhdGlvbiIvPgotPHMyIHRpdGxlPSJJbXBsZW1lbnRhdGlvbiI+Ci0KLSAgPHA+VGhlIG91dHB1dCBoYW5kbGVyIGNsYXNzIGhhcyBhIG1ldGhvZCBmb3Igb3V0cHV0dGluZyBjb21tZW50cyBpbiB0aGUKLSAgb3V0cHV0IGRvY3VtZW50IGFuZCBtZXNzYWdlcyB0byB0aGUgb3BlcmF0b3IuIFRoZSBjb2RlIGNvbXBpbGVkIGZvciBhCi0gIGNvbW1lbnQgZ2F0aGVycyBhbGwgdGV4dCB0aGF0IGdvZXMgaW50byB0aGUgY29tbWVudCBpbiBhIFN0cmluZ1ZhbHVlSGFuZGxlcgotICBvYmplY3QsIHJldHJpZXZlcyB0aGUgZnVsbCB0ZXh0IHN0cmluZyBmcm9tIHRoaXMgaGFuZGxlciwgYW5kIHRoZW4gZmluYWxseQotICBzZW5kcyBpdCB0byB0aGUgb3V0cHV0IGhhbmRsZXIuIFNpbWlsYXJseSB0aGUgY29kZSBjb21waWxlZCBmb3IgYSBtZXNzYWdlCi0gIHdpbGwgc2ltcGx5IHNlbmQgdGhlIG1lc3NhZ2UgdG8gdGhlIG91dHB1dCBoYW5kbGVyIGluIHVzZS48L3A+Ci0KLSAgPHA+TWVzc2FnZXMgd2lsbCBiZSBvdXRwdXQgdG8gdGhlIHRlcm1pbmFsIChzdGRvdXQpIHdoZW4gYSB0cmFuc2Zvcm1hdGlvbgotICBpcyBydW4gaW4gYSB0ZXJtaW5hbC4gVGhlIG1lc3NhZ2Ugd2lsbCBiZSBvdXRwdXQgYmVmb3JlIHRoZSBiZWdpbm5pbmcgb2YgdGhlCi0gIG91dHB1dCBkb2N1bWVudC4gTWVzc2FnZXMgd2lsbCBiZSBzaG93biBpbiBhIGRpYWxvZyBib3ggaWYgYSB0cmFuc2Zvcm1hdGlvbgotICBpcyBydW4gaW4gYW4gYXBwbGV0LjwvcD4KLQotICA8cD48Y29kZT4mbHQ7eHNsOm1lc3NhZ2UmZ3Q7PC9jb2RlPiBlbGVtZW50cyB0aGF0IHVzZSB0aGUgPGNvZGU+InRlcm1pbmF0ZSI8L2NvZGU+Ci0gIGF0dHJpYnV0ZSB0byBhYm9ydCB0cmFuc2Zvcm1hdGlvbnMgY2F1c2UgYW4gZXhjZXB0aW9uIHRvIGJlIHRocm93bi4gQQotICBSdW50aW1lRXhjZXB0aW9uIGlzIHVzZWQgZm9yIHRoaXMsIGFuZCB0aGUgZXhjZXB0aW9uIHRleHQgaXM6PC9wPgotICA8cD48Y29kZT5UZXJtaW5hdGlvbiBmb3JjZWQgYnkgYW4geHNsOm1lc3NhZ2UgaW5zdHJ1Y3Rpb248L2NvZGU+PC9wPgotICA8L3MyPgotPC9zMT4gIApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX2tleV9kZXNpZ24ueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfa2V5X2Rlc2lnbi54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFhMTM3ZjYuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfa2V5X2Rlc2lnbi54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyMTQgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci0gIDxzMSB0aXRsZT0iJmx0O3hzbDprZXkmZ3Q7IC8ga2V5KCkgLyBLZXlQYXR0ZXJuIj4KLSAgPHVsPgotICAgIDxsaT48bGluayBhbmNob3I9ImZ1bmN0aW9uYWxpdHkiPkZ1bmN0aW9uYWxpdHk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJpbXBsZW1lbnRhdGlvbiI+SW1wbGVtZW50YXRpb248L2xpbms+PC9saT4gICAgCi0gIDwvdWw+Ci0gIDxhbmNob3IgbmFtZT0iZnVuY3Rpb25hbGl0eSIvPgotICA8czIgdGl0bGU9IkZ1bmN0aW9uYWxpdHkiPgotCi0gIDxwPlRoZSA8Y29kZT4mbHQ7eHNsOmtleSZndDs8L2NvZGU+IGVsZW1lbnQgaXMgYSB0b3AtbGV2ZWwgZWxlbWVudCB0aGF0IGNhbiBiZQotICB1c2VkIHRvIGRlZmluZSBhIG5hbWVkIGluZGV4IG9mIG5vZGVzIGZyb20gdGhlIHNvdXJjZSBYTUwgdHJlZShzKS4gVGhlCi0gIGVsZW1lbnQgaGFzIHRocmVlIGF0dHJpYnV0ZXM6PC9wPgotCi0gIDx1bD4KLSAgICA8bGk+Ci0gICAgICA8Y29kZT5uYW1lPC9jb2RlPiAtIHRoZSBuYW1lIG9mIHRoZSBpbmRleAotICAgIDwvbGk+Ci0gICAgPGxpPgotICAgICAgPGNvZGU+bWF0Y2g8L2NvZGU+IC0gYSBwYXR0ZXJuIHRoYXQgZGVmaW5lcyB0aGUgbm9kZXNldCB3ZSB3YW50Ci0gICAgICBpbmRleGVkCi0gICAgPC9saT4KLSAgICA8bGk+Ci0gICAgICA8Y29kZT51c2U8L2NvZGU+IC0gYW4gZXhwcmVzc2lvbiB0aGF0IGRlZmluZXMgdGhlIHZhbHVlIHRvIGJlIHVzZWQKLSAgICAgIGFzIHRoZSBpbmRleCBrZXkgdmFsdWUuCi0gICAgPC9saT4KLSAgPC91bD4KLQotICA8cD5BIG5hbWVkIGluZGV4IGNhbiBiZSBhY2Nlc3NlZCB1c2luZyBlaXRoZXIgdGhlIDxjb2RlPmtleSgpPC9jb2RlPiBmdW5jdGlvbiBvcgotICBhIEtleVBhdHRlcm4uIEJvdGggdGhlc2UgbWV0aG9kcyBhZGRyZXNzIHRoZSBpbmRleCB1c2luZyBpdHMgZGVmaW5lZCBuYW1lCi0gICh0aGUgIm5hbWUiIGF0dHJpYnV0ZSBhYm92ZSkgYW5kIGEgcGFyYW1ldGVyIGRlZmluaW5nIG9uZSBvciBtb3JlIGxvb2t1cAotICB2YWx1ZXMgZm9yIHRoZSBpbmRleC4gVGhlIGZ1bmN0aW9uIG9yIHBhdHRlcm4gcmV0dXJucyBhIG5vZGUgc2V0IGNvbnRhaW5pbmcKLSAgYWxsIG5vZGVzIGluIHRoZSBpbmRleCB3aG9zZSBrZXkgdmFsdWUgbWF0Y2ggdGhlIHBhcmFtZXRlcidzIHZhbHVlKHMpOjwvcD4KLQotICA8c291cmNlPgotICAgICZsdDt4c2w6a2V5IG5hbWU9ImJvb2stYXV0aG9yIiBtYXRjaD0iYm9vayIgdXNlPSJhdXRob3IiLyZndDsKLSAgICA6Ci0gICAgOgotICAgICZsdDt4c2w6Zm9yLWVhY2ggc2VsZWN0PSJrZXkoJ2Jvb2stYXV0aG9yJywgJ01pa2hhaWwgQnVsZ2Frb3YnKSImZ3Q7Ci0gICAgICAmbHQ7eHNsOnZhbHVlLW9mIHNlbGVjdD0iYXV0aG9yIi8mZ3Q7Ci0gICAgICAmbHQ7eHNsOnRleHQmZ3Q7OiAmbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgJmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9ImF1dGhvciIvJmd0OwotICAgICAgJmx0O3hzbDp0ZXh0Jmd0OyZhbXA7I3hhOyZsdDsveHNsOnRleHQmZ3Q7Ci0gICAgJmx0Oy94c2w6Zm9yLWVhY2gmZ3Q7Ci0gIDwvc291cmNlPgotCi0gIDxwPlRoZSBLZXlQYXR0ZXJuIGNhbiBiZSB1c2VkIHdpdGhpbiBhbiBpbmRleCBkZWZpbml0aW9uIHRvIGNyZWF0ZSB1bmlvbnMKLSAgYW5kIGludGVyc2VjdGlvbnMgb2Ygbm9kZSBzZXRzOjwvcD4KLQotPHNvdXJjZT4KLSAgICAmbHQ7eHNsOmtleSBuYW1lPSJjdWx0Y2llcyIgbWF0Y2g9ImZhcm1lciB8IGZpc2hlcm1hbiIgdXNlPSJuYW1lIi8mZ3Q7Ci08L3NvdXJjZT4KLQotICA8cD5UaGlzIGNvdWxkIG9mIGNvdXJzZSBiZSBkb25lIHVzaW5nIHJlZ3VsYXIgPGNvZGU+Jmx0O3hzbDpmb3ItZWFjaCZndDs8L2NvZGU+Ci0gIGFuZCA8Y29kZT4mbHQ7eHNsOnNlbGVjdCZndDs8L2NvZGU+IGVsZW1lbnRzLiBIb3dldmVyLCBpZiB5b3VyIHN0eWxlc2hlZXQKLSAgYWNjZXNzZXMgdGhlIHNhbWUgc2VsZWN0aW9uIG9mIG5vZGVzIG92ZXIgYW5kIG92ZXIgYWdhaW4sIHRoZSB0cmFuc2Zvcm1hdGlvbgotICB3aWxsIGJlIG11Y2ggbW9yZSBlZmZpY2llbnQgdXNpbmcgcHJlLWluZGV4ZWQga2V5cyBhcyBzaG93biBhYm92ZS48L3A+Ci0gPC9zMj48YW5jaG9yIG5hbWU9ImltcGxlbWVudGF0aW9uIi8+Ci0gPHMyIHRpdGxlPSJJbXBsZW1lbnRhdGlvbiI+Ci0KLSAgPHA+QWJzdHJhY3RUcmFuc2xldCBoYXMgYSBnbG9iYWwgaGFzaHRhYmxlIHRoYXQgaG9sZHMgYW4gaW5kZXggZm9yIGVhY2ggbmFtZWQKLSAga2V5IGluIHRoZSBzdHlsZXNoZWV0IChoYXNoaW5nIG9uIHRoZSAibmFtZSIgYXR0cmlidXRlIG9mIHhzbDprZXkpLgotICBBYnN0cmFjdFRyYW5zbGV0IGhhcyBhIGNvdXBsZSBvZiBwdWJsaWMgbWV0aG9kcyBmb3IgaW5zZXJ0aW5nIGFuZCByZXRyaWV2aW5nCi0gIGRhdGEgZnJvbSB0aGlzIGhhc2h0YWJsZTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgcHVibGljIHZvaWQgYnVpbGRLZXlJbmRleChTdHJpbmcgbmFtZSwgaW50IG5vZGVJRCwgU3RyaW5nIHZhbHVlKTsKLSAgICBwdWJsaWMgS2V5SW5kZXggS2V5SW5kZXggZ2V0S2V5SW5kZXgoU3RyaW5nIG5hbWUpOwotPC9zb3VyY2U+Ci0KLSAgPHA+VGhlIEtleSBjbGFzcyBjb21waWxlcyBjb2RlIHRoYXQgdHJhdmVyc2VzIHRoZSBpbnB1dCBET00gYW5kIGV4dHJhY3RzCi0gIG5vZGVzIHRoYXQgbWF0Y2ggc29tZSBnaXZlbiBwYXJhbWV0ZXJzICh0aGUgPGNvZGU+Im1hdGNoIjwvY29kZT4gYXR0cmlidXRlIG9mIHRoZQotICA8Y29kZT4mbHQ7eHNsOmtleSZndDs8L2NvZGU+IGVsZW1lbnQpLiBBIG5ldyBlbGVtZW50IGlzIGluc2VydGVkIGludG8gdGhlIG5hbWVkCi0gIGtleSdzIGluZGV4LiBUaGUgbm9kZXMnIERPTSBpbmRleCBhbmQgdGhlIHZhbHVlIHRyYW5zbGF0ZWQgZnJvbSB0aGUgCi0gIDxjb2RlPiJ1c2UiPC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlIDxjb2RlPiZsdDt4c2w6a2V5Jmd0OzwvY29kZT4gZWxlbWVudCBhcmUgc3RvcmVkCi0gIGluIHRoZSBuZXcgZW50cnkgaW4gdGhlIGluZGV4LjwvcD4KLQotICA8cD5UaGUgaW5kZXggaXRzZWxmIGlzIGltcGxlbWVudGVkIGluIHRoZSA8Y29kZT5LZXlJbmRleDwvY29kZT4gY2xhc3MuCi0gIFRoZSBpbmRleCBoYXMgYW4gaGFzaHRhYmxlIHdpdGggYWxsIHRoZSB2YWx1ZXMgZnJvbSB0aGUgbWF0Y2hpbmcgbm9kZXMgKHRoZQotICBwYXJ0IG9mIHRoZSBub2RlIHVzZWQgdG8gZ2VuZXJhdGUgdGhpcyB2YWx1ZSBpcyB0aGUgb25lIHNwZWNpZmllZCBpbiB0aGUKLSAgPGNvZGU+InVzZSI8L2NvZGU+IGF0dHJpYnV0ZSkuIEZvciBldmVyeSBtYXRjaGluZyB2YWx1ZSB0aGVyZSBpcyBhIFZlY3RvcgotICBob2xkaW5nIGEgbGlzdCBvZiBhbGwgbm9kZSBpbmRleGVzIGZvciB3aGljaCB0aGlzIHZhbHVlIGdpdmVzIGEgbWF0Y2g6PC9wPgotCi0gIDxwPjxpbWcgc3JjPSJrZXlfcmVsYXRpb25zLmdpZiIgYWx0PSJrZXlfcmVsYXRpb25zLmdpZiIvPjwvcD4KLSAgPHA+PHJlZj5GaWd1cmUgMTogSW5kZXhpbmcgdGFibGVzPC9yZWY+PC9wPgotCi0gIDxwPlRoZSA8Y29kZT5LZXlJbmRleDwvY29kZT4gY2xhc3MgaW1wbGVtZW50cyB0aGUgPGNvZGU+Tm9kZUl0ZXJhdG9yPC9jb2RlPgotICBpbnRlcmZhY2UsIHNvIHRoYXQgaXQgY2FuIGJlIHJldHVybmVkIGRpcmVjdGx5IGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKLSAgPGNvZGU+a2V5KCk8L2NvZGU+IGZ1bmN0aW9uLiBUaGlzIGlzIGhvdyB0aGUgaW5kZXggZ2VuZXJhdGVkIGJ5Ci0gIDxjb2RlPiZsdDt4c2w6a2V5Jmd0OzwvY29kZT4gYW5kIHRoZSBub2RlLXNldCByZXR1cm5lZCBieSB0aGUgPGNvZGU+a2V5KCk8L2NvZGU+IGFuZAotICBLZXlQYXR0ZXJuIGFyZSB0aWVkIHRvZ2V0aGVyLiBZb3UgY2FuIHNlZSBob3cgdGhpcyBpcyBkb25lIGluIHRoZQotICA8Y29kZT50cmFuc2xhdGUoKTwvY29kZT4gbWV0aG9kIG9mIHRoZSA8Y29kZT5LZXlDYWxsPC9jb2RlPiBjbGFzcy48L3A+Ci0KLSAgPHA+VGhlIDxjb2RlPmtleSgpPC9jb2RlPiBmdW5jdGlvbiBjYW4gYmUgY2FsbGVkIGluIHR3byB3YXlzOjwvcD4KLQotPHNvdXJjZT4KLSAgICBrZXkoJ2tleS1uYW1lJywndmFsdWUnKQotICAgIGtleSgna2V5LW5hbWUnLCdub2RlLXNldCcpCi08L3NvdXJjZT4KLQotICA8cD5UaGUgZmlyc3QgcGFyYW1ldGVyIGlzIGFsd2F5cyB0aGUgbmFtZSBvZiB0aGUga2V5LiBXZSB1c2UgdGhpcyB2YWx1ZSB0bwotICBsb29rdXAgb3VyIGluZGV4IGZyb20gdGhlIF9rZXlJbmRleGVzIGhhc2h0YWJsZSBpbiBBYnN0cmFjdFRyYW5zbGV0OjwvcD4KLQotPHNvdXJjZT4KLSAgICBpbC5hcHBlbmQoY2xhc3NHZW4uYWxvYWRUaGlzKCkpOwotICAgIF9uYW1lLnRyYW5zbGF0ZShjbGFzc0dlbiwgbWV0aG9kR2VuKTsKLSAgICBpbC5hcHBlbmQobmV3IElOVk9LRVZJUlRVQUwoZ2V0S2V5SW5kZXgpKTsKLTwvc291cmNlPgotCi0gIDxwPlRoaXMgY29tcGlsZXMgaW50byBhIGNhbGwgdG8KLSAgPGNvZGU+QWJzdHJhY3RUcmFuc2xldC5nZXRLZXlJbmRleChTdHJpbmcgbmFtZSk8L2NvZGU+LCBhbmQgaXQgbGVhdmVzIGEKLSAgPGNvZGU+S2V5SW5kZXg8L2NvZGU+IG9iamVjdCBvbiB0aGUgc3RhY2suIFdoYXQgd2UgdGhlbiBuZWVkIHRvIGRvIGl0IHRvCi0gIGluaXRpYWxpc2UgdGhlIDxjb2RlPktleUluZGV4PC9jb2RlPiB0byBnaXZlIHVzIG5vZGVzIHdpdGggdGhlIHJlcXVlc3RlZCB2YWx1ZS4KLSAgVGhpcyBpcyBkb25lIGJ5IGxlYXZpbmcgdGhlIDxjb2RlPktleUluZGV4PC9jb2RlPiBvYmplY3Qgb24gdGhlIHN0YWNrIGFuZCBwdXNoaW5nCi0gIHRoZSA8Y29kZT4idmFsdWUiPC9jb2RlPiBwYXJhbWV0ZXIgdG8gPGNvZGU+a2V5KCk8L2NvZGU+LCBiZWZvcmUgY2FsbGluZwotICA8Y29kZT5sb29rdXAoKTwvY29kZT4gb24gdGhlIGluZGV4OjwvcD4KLQotPHNvdXJjZT4KLSAgICBpbC5hcHBlbmQoRFVQKTsgIC8vIGR1cGxpY2F0ZSB0aGUgS2V5SW5kZXggb2JlamN0IGJlZm9yZSByZXR1cm4KLSAgICBfdmFsdWUudHJhbnNsYXRlKGNsYXNzR2VuLCBtZXRob2RHZW4pOwotICAgIGlsLmFwcGVuZChuZXcgSU5WT0tFVklSVFVBTChsb29rdXApKTsKLTwvc291cmNlPgotCi0gIDxwPlRoaXMgY29tcGlsZXMgaW50byBhIGNhbGwgdG8gPGNvZGU+S2V5SW5kZXgubG9va3VwKFN0cmluZyB2YWx1ZSk8L2NvZGU+LiBUaGlzCi0gIHdpbGwgaW5pdGlhbGlzZSB0aGUgPGNvZGU+S2V5SW5kZXg8L2NvZGU+IG9iamVjdCB0byByZXR1cm4gbm9kZXMgdGhhdCBtYXRjaCB0aGUKLSAgZ2l2ZW4gdmFsdWUsIHNvIHRoZSA8Y29kZT5LZXlJbmRleDwvY29kZT4gb2JqZWN0IGNhbiBiZSBsZWZ0IG9uIHRoZSBzdGFjayB3aGVuCi0gIHdlIHJldHVybi4gVGhpcyBiZWNhdXNlIHRoZSA8Y29kZT5LZXlJbmRleDwvY29kZT4gb2JqZWN0IGltcGxlbWVudHMgdGhlCi0gIDxjb2RlPk5vZGVJdGVyYXRvcjwvY29kZT4gaW50ZXJmYWNlLjwvcD4KLQotICA8cD5UaGlzIG1hdHRlciBpcyBhIGJpdCBtb3JlIGNvbXBsZXggd2hlbiB0aGUgc2Vjb25kIHBhcmFtZXRlciBvZgotICA8Y29kZT5rZXkoKTwvY29kZT4gaXMgYSBub2RlLXNldC4gSW4gdGhpcyBjYXNlIHdlIG5lZWQgdG8gdHJhdmVyc2UgdGhlIG5vZGVzIGluCi0gIHRoZSBzZXQgYW5kIGRvIGEgbG9va3VwIGZvciBlYWNoIG5vZGUgaW4gdGhlIHNldC4gV2hhdCBJIGRvIGlzIHRoaXM6PC9wPgotCi0gIDx1bD4KLSAgICA8bGk+Ci0gICAgICBjb25zdHJ1Y3QgYSA8Y29kZT5LZXlJbmRleDwvY29kZT4gb2JqZWN0IHRoYXQgd2lsbCBob2xkIHRoZSByZXR1cm4gbm9kZS1zZXQKLSAgICA8L2xpPgotICAgIDxsaT4KLSAgICAgIGZpbmQgdGhlIG5hbWVkIDxjb2RlPktleUluZGV4PC9jb2RlPiBvYmplY3QgZnJvbSB0aGUgaGFzaHRhYmxlIGluCi0gICAgICBBYnN0cmFjdFRyYW5zbGV0Ci0gICAgPC9saT4KLSAgICA8bGk+Ci0gICAgICBnZXQgYW4gaXRlcmF0b3IgZm9yIHRoZSBub2RlLXNldCBhbmQgZG8gdGhlIGZvbG93aW5nIGxvb3A6PC9saT4KLSAgICAgIDx1bD4KLSAgICAgICAgPGxpPmdldCBzdHJpbmcgdmFsdWUgZm9yIGN1cnJlbnQgbm9kZTwvbGk+Ci0gICAgICAgIDxsaT5kbyBsb29rdXAgaW4gS2V5SW5kZXggb2JqZWN0IGZvciB0aGUgbmFtZWQgaW5kZXg8L2xpPgotICAgICAgICA8bGk+bWVyZ2UgdGhlIHJlc3VsdGluZyBub2RlLXNldCBpbnRvIHRoZSByZXR1cm4gbm9kZS1zZXQ8L2xpPgotICAgICAgPC91bD4KLSAgICA8bGk+Ci0gICAgICBsZWF2ZSB0aGUgcmV0dXJuIG5vZGUtc2V0IG9uIHN0YWNrIHdoZW4gZG9uZQotICAgIDwvbGk+Ci0gIDwvdWw+Ci0KLSAgPHA+VGhlIG9ubHkgd29yayB0aGF0IHJlbWFpbnMgaXMgdG8gdXBkYXRlIHRoZSA8Y29kZT5tZXJnZSgpPC9jb2RlPiBtZXRob2Qgb2YKLSAgdGhlIDxjb2RlPktleUluZGV4PC9jb2RlPiBjbGFzcyBzbyB0aGF0IGl0IGVsaW1pbmF0ZXMgZHVwbGljYXRlIG5vZGVzIGluIHRoZQotICByZXN1bHRpbmcgbm9kZS1zZXQuPC9wPgotICA8L3MyPgotPC9zMT4KZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX2xhbmdfZGVzaWduLnhtbCBiL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX2xhbmdfZGVzaWduLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjhjMGJmMC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbF9sYW5nX2Rlc2lnbi54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxMTUgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci0gIDxzMSB0aXRsZT0ibGFuZygpIGZ1bmN0aW9uIj4KLSAgPHVsPgotICAgIDxsaT48bGluayBhbmNob3I9ImZ1bmN0aW9uYWxpdHkiPkZ1bmN0aW9uYWxpdHk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJpbXBsZW1lbnRhdGlvbiI+SW1wbGVtZW50YXRpb248L2xpbms+PC9saT4gICAgCi0gIDwvdWw+Ci0gIDxhbmNob3IgbmFtZT0iZnVuY3Rpb25hbGl0eSIvPgotICA8czIgdGl0bGU9IkZ1bmN0aW9uYWxpdHkiPgotCi0gIDxwPlRoZSA8Y29kZT54bWw6bGFuZzwvY29kZT4gY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBsYW5ndWFnZSBmb3IgYSBub2RlIG9yCi0gIGEgbm9kZS1zZXQuIFRoZSBhdHRyaWJ1dGUgY2FuIGJlIHVzZWQgdG8gc3RvcmUgbGFuZ3VhZ2Utc3BlY2lmaWMgZGF0YSBpbiBhbgotICBYTUwgZG9jdW1lbnQ6PC9wPgotCi0gIDxzb3VyY2U+Ci0gICAgJmx0O3BocmFzZXMmZ3Q7Ci0gICAgICAmbHQ7Z3JlZXRpbmcgeG1sOmxhbmc9ImVuIiZndDtIZWxsbyEmbHQ7L2dyZWV0aW5nJmd0OwotICAgICAgJmx0O2dyZWV0aW5nIHhtbDpsYW5nPSJubyImZ3Q7SGVpISZsdDsvZ3JlZXRpbmcmZ3Q7Ci0gICAgICAmbHQ7Z3JlZXRpbmcgeG1sOmxhbmc9ImZyIiZndDtTYWx1dCEmbHQ7L2dyZWV0aW5nJmd0OwotICAgICAgJmx0O2dyZWV0aW5nIHhtbDpsYW5nPSJlcyImZ3Q7SG9sYSEmbHQ7L2dyZWV0aW5nJmd0OwotICAgICAgJmx0O2dyZWV0aW5nIHhtbDpsYW5nPSJkZSImZ3Q7U3dlaW5odW5kISZsdDsvZ3JlZXRpbmcmZ3Q7Ci0gICAgJmx0Oy9waHJhc2VzJmd0OwotICA8L3NvdXJjZT4KLQotICA8cD5UaGUgWFNMIHN0eWxlc2hlZXQgY2FuIHVzZSB0aGUgPGNvZGU+bGFuZygpPC9jb2RlPiBmdW5jdGlvbiB0byBzZWxlY3QgdGhlCi0gIGVsZW1lbnQgd2l0aCB0aGUgZGVzaXJlZCBsYW5ndWFnZTo8L3A+Ci0KLSAgPHNvdXJjZT4KLSAgICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSJncmVldGluZyImZ3Q7Ci0gICAgICAmbHQ7eHNsOmlmIHRlc3Q9ImxhbmcoImRlIikmZ3Q7Ci0gICAgICAgICZsdDt4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8mZ3Q7Ci0gICAgICAgICZsdDt4c2w6dGV4dCZndDsgR3Jvc3NnbHVja2xpY2hlciB3dW5jaGUhJmx0Oy94c2w6dGV4dCZndDsKLSAgICAgICZsdDsveHNsOmlmJmd0OwotICAgICZsdDsveHNsOnRlbXBsYXRlJmd0OwotICA8L3NvdXJjZT4KLTwvczI+IDxhbmNob3IgbmFtZT0iaW1wbGVtZW50YXRpb24iLz4KLTxzMiB0aXRsZT0iSW1wbGVtZW50YXRpb24iPgotCi0gIDxwPlRoZSBET00gaW50ZXJmYWNlIGhhcyBiZWVuIGdpdmVuIGEgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgbGFuZ3VhZ2UgZm9yCi0gIGEgZ2l2ZW4gbm9kZS4gVGhlIGxhbmd1YWdlIGlzIHJldHVybmVkIGFzIGEgc3RyaW5nIChvbiB3aGF0ZXZlciBmb3JtYXQgaXMKLSAgdXNlZCBpbiB0aGUgWE1MIGRvY3VtZW50IC0gc2hvdWxkIGJlIGlzbyksIGFuZCBtYXkgYmUgbnVsbCBpZiBubyBsYW5ndWFnZSBpcwotICBkZWZpbmVkLjwvcD4KLQotICA8c291cmNlPgotICAgIHB1YmxpYyBTdHJpbmcgRE9NLmdldExhbmd1YWdlKGludCBub2RlKTsKLSAgPC9zb3VyY2U+Ci0KLSAgPHA+VGhlIEJhc2lzTGlicmFyeSBjbGFzcyBoYXMgYSBzdGF0aWMgbWV0aG9kIHRoYXQgd2lsbCBjb21wYXJlIHRoZSBsYW5ndWFnZQotICBvZiB0aGUgY29udGV4dCBub2RlIHdpdGggc29tZSBvdGhlciBsYW5ndWFnZSBhbmQgcmV0dXJuIHRoZSByZXN1bHQgYXMgYQotICBib29sZWFuLjwvcD4KLQotICA8c291cmNlPgotICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBCYXNpc0xpYnJhcnkudGVzdExhbmd1YWdlKFN0cmluZyBsYW5ndWFnZSwgRE9NIGRvbSwgaW50IG5vZGUpOwotICA8L3NvdXJjZT4KLQotICA8cD5UaGUgY29tcGlsZWQgY29kZSBmb3IgdGhlIDxjb2RlPmxhbmcoKTwvY29kZT4gbWV0aG9kIGNhbGxzIHRoaXMgbWV0aG9kIGluIHRoZQotICBCYXNpc0xpYnJhcnkgYW5kIGxlYXZlcyB0aGUgcmVzdWx0IG9uIHRoZSBzdGFjayBmb3IgdGhlIGNhbGxpbmcgZWxlbWVudC48L3A+Ci0gIDwvczI+Ci08L3MxPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfc29ydF9kZXNpZ24ueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfc29ydF9kZXNpZ24ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA2ZGRhM2E0Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX3NvcnRfZGVzaWduLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDIxMSArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLTwhLS0gCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLSAgPHMxIHRpdGxlPSImbHQ7eHNsOnNvcnQmZ3Q7Ij4KLSAgPHVsPgotICAgIDxsaT48bGluayBhbmNob3I9ImZ1bmN0aW9uYWxpdHkiPkZ1bmN0aW9uYWxpdHk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJzb3J0LWNsYXNzIj5UaGUgU29ydCBjbGFzczwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9InNvcnRpbmdpdGVyYXRvci1jbGFzcyI+VGhlIFNvcnRpbmdJdGVyYXRvciBjbGFzczwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9Im5vZGVzb3J0cmVjb3JkLWNsYXNzIj5UaGUgTm9kZVNvcnRSZWNvcmQgY2xhc3M8L2xpbms+PC9saT4gICAgCi0gICAgPGxpPjxsaW5rIGFuY2hvcj0ibm9kZXNvcnRyZWNvcmRmYWN0b3J5LWNsYXNzIj5UaGUgTm9kZVNvcnRSZWNvcmRGYWN0b3J5IGNsYXNzPC9saW5rPjwvbGk+Ci0gIDwvdWw+Ci0gIAotICA8YW5jaG9yIG5hbWU9ImZ1bmN0aW9uYWxpdHkiLz4KLSAgPHMyIHRpdGxlPSJGdW5jdGlvbmFsaXR5Ij4KLQotICA8cD5UaGUgPGNvZGU+Jmx0O3hzbDpzb3J0Jmd0OzwvY29kZT4gZWxlbWVudCBpcyB1c2VkIHRvIGRlZmluZSBhIHNvcnQga2V5IHdoaWNoCi0gIHNwZWNpZmllcyB0aGUgb3JkZXIgaW4gd2hpY2ggbm9kZXMgc2VsZWN0ZWQgYnkgZWl0aGVyCi0gIDxjb2RlPiZsdDt4c2w6YXBwbHktdGVtcGxhdGVzJmd0OzwvY29kZT4gb3IgPGNvZGU+Jmx0O3hzbDpmb3ItZWFjaCZndDs8L2NvZGU+IGFyZQotICBwcm9jZXNzZWQuIFRoZSBub2RlcyBjYW4gYmUgc29ydGVkIGVpdGhlciBpbiBudW1lcmljYWwgb3IgYWxwaGFiZXRpYyBvcmRlciwKLSAgYW5kIHRoZSBhbHBoYWJldGljIG9yZGVyIG1heSB2YXJ5IGRlcGVpbmRpbmcgb24gdGhlIGxhbmd1YWdlIGluIHVzZS4gVGhlCi0gIG5vZGVzIGNhbiBiZSBzb3J0ZWQgZWl0aGVyIGluIGFzY2VuZGluZyBvciBkZXNjZW5kaW5nIG9yZGVyLjwvcD4KLQotICA8L3MyPjxhbmNob3IgbmFtZT0ic29ydC1jbGFzcyIvPgotICA8czIgdGl0bGU9IlRoZSBTb3J0IGNsYXNzIj4KLQotICA8cD5TdGF0aWMgbWV0aG9kcyBvZiB0aGUgU29ydCBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZyB0aGUKLSAgbmVjZXNzYXJ5IGNvZGUgZm9yIGludm9raW5nIFNvcnRpbmdJdGVyYXRvcnMgdW5kZXIKLSAgPGNvZGU+Jmx0O3hzbDphcHBseS10ZW1wbGF0ZXMmZ3Q7PC9jb2RlPiBhbmQgPGNvZGU+Jmx0O3hzbDpmb3ItZWFjaCZndDs8L2NvZGU+Ci0gIGVsZW1lbnRzLiBCb3RoIHRoZXNlIGVsZW1lbnRzIGNhbiBoYXZlIHNldmVyYWwgPGNvZGU+Jmx0O3hzbDpzb3J0Jmd0OzwvY29kZT4KLSAgY2hpbGQgbm9kZXMgZGVmaW5pbmcgcHJpbWFyeSwgc2Vjb25kYXJ5LCB0ZXJpYXJ5LCBldGMuIGtleXMuIFRoZSBjb2RlIGZvcgotICA8Y29kZT4mbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcyZndDs8L2NvZGU+IGFuZCA8Y29kZT4mbHQ7eHNsOmZvci1lYWNoJmd0OzwvY29kZT4KLSAgY3JlYXRlICB2ZWN0b3JzIGNvbnRhaW5nIGEgU29ydCBvYmplY3QgZm9yIGVhY2ggc29ydCBrZXkuIFRoZSBvYmplY3QgbWV0aG9kcwotICBvZiB0aGUgU29ydCBvYmplY3QgZW5jYXBzdWxhdGUgYSBjb250YWluZXIgZm9yIGtleS1zcGVjaWZpYyBkYXRhIChzdWNoIGFzIHRoZQotICBzb3J0IGtleSBpdHNlbGYsIHNvcnQgb3JkZXIsIHNvcnQgdHlwZSwgYW5kIHN1Y2gpIHdoaWxlIHRoZSBzdGF0aWMgbWV0aG9kcwotICB0YWtlIGEgdmVjdG9yIG9mIFNvcnQgb2JqZWN0cyBhbmQgZ2VuZXJhdGUgdGhlIGFjdHVhbCBjb2RlLjwvcD4KLQotICA8cD5UaGUgPGNvZGU+dHJhbnNsYXRlKCk8L2NvZGU+IG1ldGhvZCBvZiB0aGUgU29ydCBvYmplY3QgaXMgbmV2ZXIgY2FsbGVkLiBUaGUKLSAgdmVjdG9ycyBjb250YWluaW5nIHRoZSBTb3J0IG9iamVjdHMgZm9yIGEgPGNvZGU+Jmx0O3hzbDphcHBseS10ZW1wbGF0ZXMmZ3Q7PC9jb2RlPgotICBvciA8Y29kZT4mbHQ7eHNsOmZvci1lYWNoJmd0OzwvY29kZT4gZWxlbWVudCBhcmUgaW5zdGVhZCBwYXNzZWQgdG8gdGhlIHN0YXRpYwotICA8Y29kZT50cmFuc2xhdGVTb3J0SXRlcmF0b3IoKTwvY29kZT4gbWV0aG9kLiBUaGlzIG1ldGhvZCBjb21waWxlcyBjb2RlIHRoYXQKLSAgaW5zdGFuY2lhdGVzIGEgU29ydGluZ0l0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgcGFzcyBvbiBhIG5vZGUtc2V0IGluIGEKLSAgc3BlY2lmaWMgb3JkZXIgdG8gdGhlIGNvZGUgaGFuZGxpbmcgdGhlIDxjb2RlPiZsdDt4c2w6YXBwbHktdGVtcGxhdGVzJmd0OzwvY29kZT4KLSAgb3IgPGNvZGU+Jmx0O3hzbDpmb3ItZWFjaCZndDs8L2NvZGU+IGVsZW1lbnQuPC9wPgotCi0gIDwvczI+PGFuY2hvciBuYW1lPSJzb3J0aW5naXRlcmF0b3ItY2xhc3MiLz4KLSAgPHMyIHRpdGxlPSJUaGUgU29ydGluZ0l0ZXJhdG9yIGNsYXNzIj4KLQotICA8cD5UaGUgU29ydGluZ0l0ZXJhdG9yIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzb3J0aW5nIG5vZGVzIGVuY2Fwc3VsYXRlZCBpbgotICBzb3J0IG9iZWN0cy4gVGhlc2Ugc29ydCBvYmplY3RzIG11c3QgYmUgb2YgYSBjbGFzcyBpbmhlcml0aW5nIGZyb20KLSAgTm9kZVNvcnRSZWNvcmQsIGEgdGhlIFNvcnRpbmdJdGVyYXRvciBvYmplY3QgbmVlZHMgYSBmYWN0b3J5IG9iamVjdCBwcm92aWRpbmcKLSAgaXQgd2l0aCB0aGUgY29ycmVjdCB0eXBlIG9mIG9iamVjdHM6PC9wPgotCi0gIDxwPjxpbWcgc3JjPSJzb3J0X29iamVjdHMuZ2lmIiBhbHQ9InNvcnRfb2JqZWN0cy5naWYiLz48L3A+Ci0gIDxwPjxyZWY+RmlndXJlIDE6IFNvcnRpbmdJdGVyYXRvcjwvcmVmPjwvcD4KLQotICA8cD5UaGUgU29ydGluZ0l0ZXJhdG9yIGNsYXNzIGlzIGZhaXJseSBkdW1iIGFuZCBsZWF2ZXMgbXVjaCBvZiB0aGUgd29yayB0byB0aGUKLSAgTm9kZVNvcnRSZWNvcmQgY2xhc3MuIFRoZSBpdGVyYXRvciBnZXRzIHRoZSBOb2RlU29ydFJlY29yZHMgZnJvbSB0aGUgZmFjdG9yeQotICBvYmplY3QgYW5kIHNvcnRzIHRoZW0gdXNpbmcgcXVpY2tzb3J0IGFuZCBjYWxsaW5nIDxjb2RlPmNvbXBhcmVUbygpPC9jb2RlPiBvbgotICBwYWlycyBvZiBOb2RlU29ydFJlY29yZCBvYmplY3RzLjwvcD4KLQotICA8L3MyPjxhbmNob3IgbmFtZT0ibm9kZXNvcnRyZWNvcmQtY2xhc3MiLz4KLSAgPHMyIHRpdGxlPSJUaGUgTm9kZVNvcnRSZWNvcmQgY2xhc3MiPgotCi0gIDxwPlRoZSBzdGF0aWMgbWV0aG9kcyBpbiB0aGUgU29ydCBjbGFzcyBnZW5lcmF0ZXMgYSBjbGFzcyBpbmhlcml0aW5nIGZyb20KLSAgTm9kZVNvcnRSZWNvcmQsIHdpdGggdGhlIGZvbGxvd2luZyBvdmVybG9hZGVkIG1ldGhvZHM6PC9wPgotCi0gIDx1bD4KLSAgICA8bGk+PGVtPkNsYXNzIENvbnN0cnVjdG9yPC9lbT48L2xpPgotICAgICAgPHVsPjxsaT5UaGUgY2xhc3MgY29uc3RydWN0b3IgaXMgb3ZlcmxvYWRlZCB0byBjcmVhdGUgc29ydC1rZXkgZ2xvYmFsCi0gICAgICB0YWJsZXMsIHN1Y2ggYXMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgc29ydCBvcmRlciBmb3IgYWxsIHRoZSBzb3J0IGtleXMKLSAgICAgIGFuZCBhbm90aGVyIGFycmF5IGNvbnRhaW5nIGFsbCB0aGUgc29ydCB0eXBlcy4gRGlmZmVyZW50IHNvcnQgb3JkZXIvdHlwZXMKLSAgICAgIGNhbiBiZSBzcGVjaWZpZWQgZm9yIHRoZSBkaWZmZXJlbnQgbGV2ZWxzIG9mIHNvcnQga2V5cywgYnV0IHdlIGFzc3VtZSB0aGF0Ci0gICAgICB0aGUgc2FtZSBsYW5ndWFnZSBpcyB1c2VkIGZvciBhbGwgbGV2ZWxzLjwvbGk+PC91bD4KLSAgICAgIAotICAgIDxsaT48Y29kZT5leHRyYWN0VmFsdWVGcm9tRE9NKGludCBsZXZlbCk8L2NvZGU+PC9saT4KLSAgICAgIDx1bD48bGk+VGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBTb3J0aW5nSXRlcmF0b3Igb2JqZWN0IHRvIGV4dHJhY3QgdGhlCi0gICAgICB2YWx1ZSBmb3IgYSBzcGVjaWZpYyBzb3J0IGtleSBmb3IgYSBub2RlLiBUaGUgU29ydGluZ0l0ZXJhdG9yIHdpbGwgb25seQotICAgICAgdXNlIHRoaXMgbWV0aG9kIG9uY2UgYW5kIHdpbGwgY2FjaGUgdGhlIHJldHVybmVkIHZhbHVlIGZvciBsYXRlciB1c2UuIFRoZQotICAgICAgbWV0aG9kIHdpbGwgb25seSBiZSBjYWxsZWQgaWYgYWJzdWx0ZWx5IG5lY2Vzc2FyeS48L2xpPjwvdWw+Ci0KLSAgICA8bGk+PGNvZGU+Y29tcGFyZVR5cGUoaW50IGxldmVsKTwvY29kZT48L2xpPgotICAgICAgPHVsPjxsaT5UaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBzb3J0IHR5cGUgZm9yIG9uZSBzb3J0IGtleSBsZXZlbC4gUmV0dXJucwotICAgICAgZWl0aGVyIDxjb2RlPkNPTVBBUkVfU1RSSU5HPC9jb2RlPiBvciA8Y29kZT5DT01QQVJFX05VTUVSSUM8L2NvZGU+LjwvbGk+PC91bD4KLSAgICAKLSAgICA8bGk+PGNvZGU+c29ydE9yZGVyKGludCBsZXZlbCk8L2NvZGU+PC9saT4KLSAgICAgIDx1bD48bGk+VGhpcyBtZXRob2QgcmV0dXJucyB0aGUgc29ydCBvcmRlciBmb3Igb25lIHNvcnQga2V5IGxldmVsLiBSZXR1cm5zCi0gICAgICBlaXRoZXIgPGNvZGU+Q09NUEFSRV9BU0NFTkRJTkc8L2NvZGU+IG9yIDxjb2RlPkNPTVBBUkVfREVTQ0VORElORzwvY29kZT48L2xpPjwvdWw+Ci0gICAgCi0gICAgPGxpPjxjb2RlPmdldENvbGxhdG9yKGludCBsZXZlbCk8L2NvZGU+PC9saT4KLSAgICAgIDx1bD48bGk+VGhpcyBtZXRob2QgcmV0dXJucyBhIENvbGxhdG9yIG9iamVjdCBmb3IgbGFuZ3VhZ2Utc3BlY2lmaWMKLSAgICAgIHN0cmluZyBjb21wYXJpc29ucy4gVGhlIHNhbWUgQ29sbGF0b3IgaXMgdXNlZCBmb3IgYWxsIGxldmVscyBvZiB0aGUga2V5LgotICAgICAgPC9saT48L3VsPiAKLSAgPC91bD4KLQotICA8cD5UaGUgPGNvZGU+Y29tcGFyZVRvKCk8L2NvZGU+IG1ldGhvZCBvZiB0aGUgTm9kZVNvcnRSZWNvcmQgYmFzZSBjbGFzcyBkZXNlcnZlcwotICBhIGJpdCBvZiBhdHRlbnRpb24uIEl0IHRha2VzIGl0cyBvd24gbm9kZSAoZnJvbSB0aGUgdGhpcyBwb2ludGVyKSBhbmQgYW5vdGhlcgotICBub2RlIGFuZCBjb21wYXJlcywgaWYgbmVjZXNzYXJ5LCB0aGUgdmFsdWVzIGZvciBhbGwgc29ydCBrZXlzOjwvcD4KLQotICA8c291cmNlPgotICAgIC8qKgotICAgICAqIENvbXBhcmUgdGhpcyBzb3J0IGVsZW1lbnQgdG8gYW5vdGhlci4gVGhlIGZpcnN0IGxldmVsIGlzIGNoZWNrZWQgZmlyc3QsCi0gICAgICogYW5kIHdlIHByb2NlZWQgdG8gdGhlIG5leHQgbGV2ZWwgb25seSBpZiB0aGUgZmlyc3QgbGV2ZWwga2V5cyBhcmUKLSAgICAgKiBpZGVudGljYWwgKGFuZCBzbyB0aGUga2V5IHZhbHVlcyBtYXkgbm90IGV2ZW4gYmUgZXh0cmFjdGVkIGZyb20gdGhlIERPTSkKLSAgICAgKi8KLSAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhOb2RlU29ydFJlY29yZCBvdGhlcikgewotCWludCBjbXA7Ci0gICAgCi0JZm9yIChpbnQgbGV2ZWw9MDsgbGV2ZWwmbHQ7X2xldmVsczsgbGV2ZWwrKykgewotCSAgICAKLQkgICAgLy8gQ29tcGFyZSB0aGUgdHdvIG5vZGVzIGVpdGhlciBhcyBudW1lcmljIG9yIHRleHQgdmFsdWVzCi0JICAgIGlmIChjb21wYXJlVHlwZShsZXZlbCkgPT0gQ09NUEFSRV9OVU1FUklDKSB7Ci0JCWZpbmFsIERvdWJsZSBvdXIgPSBudW1lcmljVmFsdWUobGV2ZWwpOwotCQlmaW5hbCBEb3VibGUgdGhlaXIgPSBvdGhlci5udW1lcmljVmFsdWUobGV2ZWwpOwotCQlpZiAob3VyID09IG51bGwpIHJldHVybigtMSk7Ci0JCWlmICh0aGVpciA9PSBudWxsKSByZXR1cm4oMSk7Ci0JCWNtcCA9IG91ci5jb21wYXJlVG8odGhlaXIpOwotCSAgICB9Ci0JICAgIGVsc2UgewotCQlTdHJpbmcgb3VyID0gc3RyaW5nVmFsdWUobGV2ZWwpOwotCQlTdHJpbmcgdGhlaXIgPSBvdGhlci5zdHJpbmdWYWx1ZShsZXZlbCk7Ci0JCWlmIChvdXIgPT0gbnVsbCkgcmV0dXJuKC0xKTsKLQkJaWYgKHRoZWlyID09IG51bGwpIHJldHVybigxKTsKLQkJY21wID0gZ2V0Q29sbGF0b3IoKS5jb21wYXJlKG91cix0aGVpcik7Ci0JICAgIH0KLQkgICAgCi0JICAgIC8vIFJldHVybiBpbnZlcnNlIGNvbXBhcmUgdmFsdWUgaWYgaW52ZXJzZSBzb3J0IG9yZGVyCi0JICAgIGlmIChjbXAgIT0gMCkgewotCQlpZiAoc29ydE9yZGVyKGxldmVsKSA9PSBDT01QQVJFX0RFU0NFTkRJTkcpCi0JCSAgICByZXR1cm4oMCAtIGNtcCk7Ci0JCWVsc2UKLQkJICAgIHJldHVybihjbXApOwotCSAgICB9Ci0JICAgIAotCX0KLQlyZXR1cm4oMCk7Ci0gICAgfQotICA8L3NvdXJjZT4KLQotICA8cD5UaGUgdHdvIG1ldGhvZHMgPGNvZGU+c3RyaW5nVmFsdWUoaW50IGxldmVsKTwvY29kZT4gYW5kIAotICA8Y29kZT5udW1lcmljVmFsdWUoaW50IGxldmVsKTwvY29kZT4gcmV0dXJuIHZhbHVlcyBmb3Igb25lIGxldmVsIG9mIHRoZSBzb3J0IGtleQotICBvZiBhIG5vZGUuIFRoZXNlIG1ldGhvZHMgY2FjaGUgdGhlc2UgdmFsdWVzIGFmdGVyIHRoZXkgYXJlIGZpcnN0IHJlYWQgc28gdGhhdAotICB0aGUgPGNvZGU+RE9NLmdldE5vZGVWYWx1ZSgpPC9jb2RlPiBpcyBvbmx5IGNhbGxlZCBvbmNlLiBBbHNvLCB0aGUgYWxnb3JpdGhtCi0gIHVzZWQgZm9yIHRoZXNlIHR3byBtZXRob2RzIGFzc3VyZSB0aGF0IDxjb2RlPkRPTS5nZXROb2RlVmFsdWUoKTwvY29kZT4gaXMgb25seQotICBjYWxsZWQgd2hlbiBuZWVkZWQuIFRoZSB2YWx1ZSBmb3IgYSBub2RlJ3Mgc2Vjb25kYXJ5IHNvcnQga2V5IGlzIG5ldmVyCi0gIHJldHJpZXZlZCBpZiB0aGUgbm9kZSBjYW4gYmUgdW5pcXVlbHkgaWRlbnRpZmllZCBieSBpdHMgcHJpbWFyeSBrZXkuPC9wPgotCi0gIDwvczI+PGFuY2hvciBuYW1lPSJub2Rlc29ydHJlY29yZGZhY3RvcnktY2xhc3MiLz4KLSAgPHMyIHRpdGxlPSJUaGUgTm9kZVNvcnRSZWNvcmRGYWN0b3J5IGNsYXNzIj4KLQotICA8cD5BZnRlciB0aGUgc3RhdGljIG1ldGhvZHMgb2YgdGhlIFNvcnQgY2xhc3MgaGFzIGdlbmVyYXRlZCB0aGUgbmV3IGNsYXNzIGZvcgotICBzb3J0IG9iamVjdHMgaXQgZ2VuZXJhdGVzIGNvZGUgdGhhdCBpbnN0YW5jaWF0ZXMgYSBuZXcgTm9kZVNvcnRSZWNvcmRGYWN0b3J5Ci0gIG9iamVjdC4gVGhpcyBvYmplY3QgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIFNvcnRpbmdJdGVyYXRvcnMgY29uc3RydWN0b3IKLSAgYW5kIGlzIHVzZWQgYnkgdGhlIGl0ZXJhdG9yIHRvIGdlbmVyYXRlIHRoZSBuZWNlc3Nhcnkgc29ydCBvYmplY3RzLjwvcD4KLQotICA8L3MyPgotPC9zMT4KZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX3VucGFyc2VkX2Rlc2lnbi54bWwgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbF91bnBhcnNlZF9kZXNpZ24ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjNzRkNzQ5Li4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX3VucGFyc2VkX2Rlc2lnbi54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw5OCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLTwhLS0gCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLSAgPHMxIHRpdGxlPSJ1bnBhcnNlZC1lbnRpdHktdXJpKCkiPgotICA8dWw+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iZnVuY3Rpb25hbGl0eSI+RnVuY3Rpb25hbGl0eTwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9ImltcGxlbWVudGF0aW9uIj5JbXBsZW1lbnRhdGlvbjwvbGluaz48L2xpPgotICA8L3VsPgotICAKLSAgPGFuY2hvciBuYW1lPSJmdW5jdGlvbmFsaXR5Ii8+Ci0gIDxzMiB0aXRsZT0iRnVuY3Rpb25hbGl0eSI+Ci0KLQotICA8cD5UaGUgPGNvZGU+dW5wYXJzZWQtZW50aXR5LXVyaSgpPC9jb2RlPiBmdW5jdGlvbiBnaXZlcyBhY2Nlc3MgdG8gZGVjbGFyYXRpb25zCi0gIG9mIHVucGFyc2VkIGVudGl0aWVzIGluIHRoZSBEVEQgb2YgdGhlIHNvdXJjZSBkb2N1bWVudC4gSWYgdGhlIERURCBjb250YWlucwotICB0aGUgZGVjbGFyYXRpb246PC9wPgotCi0gIDxzb3VyY2U+Ci0gICAgJmx0OyFFTlRJVFkgbW9tLXBpY3R1cmUgU1lTVEVNICJodHRwOi8vd3d3LmhvbWUuY29tL21vbS5qcGciIE5EQVRBIEpQRUcmZ3Q7Ci0gIDwvc291cmNlPgotCi0gIDxwPnRoZSBleHByZXNzaW9uIDxjb2RlPnVucGFyc2VkLWVudGl0eS11cmkoJ21vbS1waWN0dXJlJyk8L2NvZGU+IHJldHVybnMgYW4KLSAgVVJJIGZvciB0aGUgZmlsZSA8Y29kZT5tb20uanBnPC9jb2RlPi48L3A+Ci0KLSAgPC9zMj48YW5jaG9yIG5hbWU9ImltcGxlbWVudGF0aW9uIi8+Ci0gIDxzMiB0aXRsZT0iSW1wbGVtZW50YXRpb24iPgotCi0gIDxwPlVucGFyc2VkIGVudGl0aWVzIG11c3QgYmUgZ2F0aGVyZWQgZnJvbSB0aGUgWE1MIGlucHV0IGRvY3VtZW50IGF0IHRoZSB0aW1lCi0gIHdoZW4gdGhlIERPTSBpcyBidWlsdC4gVG8gYWNoaWV2ZSB0aGlzIG91ciBwYXJzZXIgbXVzdCBwYXJzZSB0aGUgZG9jdW1lbnQgRFRECi0gIChpZiBhbnkpIGFuZCBzdG9yZSBhbGwgZGF0YSBvZiB0eXBlIE5EQVRBIChub3QgWE1MIGRhdGEpIGluIGEKLSAgaGFzaHRhYmxlIGluIHRoZSBBYnN0cmFjdFRyYW5zbGV0IG9iamVjdC4gQWxsIHRoZSBjb21waWxlZCBjb2RlIGZvciB0aGlzCi0gIGZ1bmN0aW9uIG5lZWRzIHRvIGRvIGlzIGNhbGwgYSBtZXRob2QgaW4gdGhlIHRyYW5zbGV0IGZvciByZXRyaWV2aW5nIHRoZQotICB2YWx1ZSBmb3IgdGhlIHJlcXVlc3RlZCBlbGVtZW50OjwvcD4KLQotICA8c291cmNlPgotICAgIHB1YmxpYyBTdHJpbmcgQWJzdHJhY3RUcmFuc2xldC5nZXRVbnBhcnNlZEVudGl0eShTdHJpbmcgZW50aXR5TmFtZSk7Ci0gIDwvc291cmNlPgotCi0gIDxwPlRoZSB0cmFuc2xldCB3aWxsIHVzZSB0aGUgc3VwcGxpZWQgPGNvZGU+ZW50aXR5TmFtZTwvY29kZT4gdG8gbG9vayB1cCB0aGUKLSAgdmFsdWUgaW4gdGhlIGhhc2h0YWJsZSBhbmQgdGhlbiBsZWF2ZSB0aGUgc3RyaW5nIHZhbHVlIG9uIHRoZSBzdGFjayBmb3IgdGhlCi0gIGVsZW1lbnQgdGhhdCBjYWxsZWQgPGNvZGU+bGFuZygpPC9jb2RlPi48L3A+Ci0gIDwvczI+Ci08L3MxPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfd2hpdGVzcGFjZV9kZXNpZ24ueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy94c2xfd2hpdGVzcGFjZV9kZXNpZ24ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA4M2IyOWRiLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsX3doaXRlc3BhY2VfZGVzaWduLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDM0MiArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLTwhLS0gCi0gKiBUaGUgQXBhY2hlIFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4xCi0gKgotICoKLSAqIENvcHlyaWdodCAoYykgMjAwMSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCi0gKiByZXNlcnZlZC4KLSAqCi0gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKLSAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwotICogYXJlIG1ldDoKLSAqCi0gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6Ci0gKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKLSAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgotICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVkZ21lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAotICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KLSAqCi0gKiA0LiBUaGUgbmFtZXMgIlhhbGFuIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBtdXN0Ci0gKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKLSAqICAgIHNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAyMDAxLCBTdW4KLSAqIE1pY3Jvc3lzdGVtcy4sIGh0dHA6Ly93d3cuc3VuLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLSAgPHMxIHRpdGxlPSImbHQ7eHNsOnN0cmlwL3ByZXNlcnZlLXNwYWNlJmd0OyI+Ci0gIDx1bD4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJmdW5jdGlvbmFsaXR5Ij5GdW5jdGlvbmFsaXR5PC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iaWRlbnRpZnkiPklkZW50aWZ5aW5nIHN0cmlwcGFibGUgd2hpdGVzcGFjZSBub2RlczwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9IndoaWNoIj5EZXRlcm1pbmluZyB3aGljaCBub2RlcyB0byBzdHJpcDwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9InN0cmlwIj5TdHJpcHBpbmcgbm9kZXM8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJmaWx0ZXIiPkZpbHRlcmluZyB3aGl0ZXNwYWNlIG5vZGVzPC9saW5rPjwvbGk+Ci0gIDwvdWw+Ci0gIAotICA8YW5jaG9yIG5hbWU9ImZ1bmN0aW9uYWxpdHkiLz4KLSAgPHMyIHRpdGxlPSJGdW5jdGlvbmFsaXR5Ij4KLQotICA8cD5UaGUgPGNvZGU+Jmx0O3hzbDpzdHJpcC1zcGFjZSZndDs8L2NvZGU+IGFuZCA8Y29kZT4mbHQ7eHNsOnByZXNlcnZlLXNwYWNlJmd0OzwvY29kZT4KLSAgZWxlbWVudHMgYXJlIHVzZWQgdG8gY29udHJvbCB0aGUgd2F5IHdoaXRlc3BhY2Ugbm9kZXMgaW4gdGhlIHNvdXJjZSBYTUwKLSAgZG9jdW1lbnQgYXJlIGhhbmRsZWQuIFRoZXNlIGVsZW1lbnRzIGhhdmUgbm8gaW1wYWN0IG9uIHdoaXRlc3BhY2UgaW4gdGhlIFhTTFQKLSAgc3R5bGVzaGVldC4gQm90aCBlbGVtZW50cyBjYW4gb2NjdXIgb25seSBhcyB0b3AtbGV2ZWwgZWxlbWVudHMsIHBvc3NpYmxlIG1vcmUKLSAgdGhhbiBvbmNlLCBhbmQgdGhlIGVsZW1lbnRzIGFyZSBhbHdheXMgZW1wdHk8L3A+Ci0gCi0gIDxwPkJvdGggZWxlbWVudHMgdGFrZSBvbmUgYXR0cmlidXRlICZxdW90O2VsZW1lbnRzJnF1b3Q7IHdoaWNoIGNvbnRhaW5zIGEKLSAgd2hpdGVzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBuYW1lZCBub2RlcyB3aGljaCBzaG91bGQgYmUgb3IgcHJlc2VydmVkCi0gIHN0cmlwcGVkIGZyb20gdGhlIHNvdXJjZSBkb2N1bWVudC4gVGhlc2UgbmFtZXMgY2FuIGJlIG9uIG9uZSBvZiB0aGVzZSB0aHJlZQotICBmb3JtYXRzIChOYW1lVGVzdCBmb3JtYXQpOjwvcD4KLQotICA8dWw+Ci0gICAgPGxpPgotICAgICAgQWxsIHdoaXRlc3BhY2Ugbm9kZXM6Ci0gICAgICA8Y29kZT5lbGVtZW50cz0mcXVvdDsqJnF1b3Q7PC9jb2RlPgotICAgIDwvbGk+Ci0gICAgPGxpPgotICAgICAgQWxsIHdoaXRlc3BhY2Ugbm9kZXMgd2l0aCBhIG5hbWVzcGFjZToKLSAgICAgIDxjb2RlPmVsZW1lbnRzPSZxdW90OyZsdDtuYW1lc3BhY2UmZ3Q7OiomcXVvdDs8L2NvZGU+Ci0gICAgPC9saT4KLSAgICA8bGk+Ci0gICAgICBTcGVjaWZpYyB3aGl0ZXNwYWNlIG5vZGVzOiA8Y29kZT5lbGVtZW50cz0mcXVvdDsmbHQ7cW5hbWUmZ3Q7JnF1b3Q7PC9jb2RlPgotICAgIDwvbGk+Ci0gIDwvdWw+Ci0KLSAgPC9zMj48YW5jaG9yIG5hbWU9ImlkZW50aWZ5Ii8+Ci0gIDxzMiB0aXRsZT0iSWRlbnRpZnlpbmcgc3RyaXBwYWJsZSB3aGl0ZXNwYWNlIG5vZGVzIj4KLQotICA8cD5UaGUgRE9NIGRldGVjdHMgYWxsIHRleHQgbm9kZXMgYW5kIGFzc2lnbnMgdGhlbSB0aGUgdHlwZSA8Y29kZT5URVhUPC9jb2RlPi4KLSAgQWxsIHRleHQgbm9kZXMgYXJlIHNjYW5uZWQgdG8gZGV0ZWN0IHdoaXRlc3BhY2Utb25seSBub2Rlcy4gQSB0ZXh0LW5vZGUgaXMKLSAgY29uc2lkZXJlZCBhIHdoaXRlc3BhY2Ugbm9kZSBvbmx5IGlmIGl0IGNvbnNpc3QgZW50aXJlbHkgb2YgY2hhcmFjdGVycyBmcm9tCi0gIHRoZSBzZXQgeyAweDA5LCAweDBhLCAweDBkLCAweDIwIH0uIFRoZSBET00gaW1wbGVtZW50YXRpb24gY2xhc3MgaGFzIGEgc3RhdGljCi0gIG1ldGhvZCB1c2VkIHRvIGRldGVjdCBzdWNoIG5vZGVzOjwvcD4KLQotPHNvdXJjZT4KLSAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzV2hpdGVzcGFjZUNoYXIoY2hhciBjKSB7Ci0gICAgICAgIHJldHVybiBjID09IDB4MjAgfHwgYyA9PSAweDBBIHx8IGMgPT0gMHgwRCB8fCBjID09IDB4MDk7Ci0gICAgfQotPC9zb3VyY2U+Ci0KLSAgPHA+VGhlIGNoYXJhY3RlcnMgYXJlIGNoZWNrZWQgaW4gcHJvYmFibGUgb3JkZXIuPC9wPgotCi0gIDxwPiBUaGUgRE9NIGhhcyBhIGJpdC1hcnJheSB0aGF0IGlzIHVzZWQgdG8gIHRhZyB0ZXh0LW5vZGVzIGFzIHN0cmlwcGFibGUKLSAgd2hpdGVzcGFjZSBub2Rlczo8L3A+Ci0KLSAgPHNvdXJjZT5wcml2YXRlIGludFtdIF93aGl0ZXNwYWNlOzwvc291cmNlPgotCi0gIDxwPlRoZXJlIGFyZSB0d28gbWV0aG9kcyBpbiB0aGUgRE9NIGltcGxlbWVudGF0aW9uIGNsYXNzIGZvciBhY2Nlc3NpbmcgdGhpcwotICBiaXQtYXJyYXk6IDxjb2RlPm1hcmtXaGl0ZXNwYWNlKG5vZGUpPC9jb2RlPiBhbmQgPGNvZGU+aXNXaGl0ZXNwYWNlKG5vZGUpPC9jb2RlPi4KLSAgVGhlIGFycmF5IGlzIHJlc2l6ZWQgdG9nZXRoZXIgd2l0aCBhbGwgb3RoZXIgYXJyYXlzIGluIHRoZSBET00gYnkgdGhlCi0gIDxjb2RlPkRPTS5yZXNpemVBcnJheXMoKTwvY29kZT4gbWV0aG9kLiBUaGUgYml0cyBpbiB0aGUgYXJyYXkgYXJlIHNldCBpbiB0aGUKLSAgPGNvZGU+RE9NLm1heWJlQ3JlYXRlVGV4dE5vZGUoKTwvY29kZT4gbWV0aG9kLiBUaGlzIG1ldGhvZCBtdXN0IGtub3cgd2hldGhlcgotICB0aGUgY3VycmVudCBub2RlIGlzIGEgbG9jYXRlZCB1bmRlciBhbiBlbGVtZW50IHdpdGggYW4KLSAgPGNvZGU+eG1sOnNwYWNlPSZxdW90OyZsdDt2YWx1ZSZndDsmcXVvdDs8L2NvZGU+IGF0dHJpYnV0ZSBpbiB0aGUgRE9NLCBpbiB3aGljaAotICBjYXNlIGl0IGlzIG5vdCBhIHN0cmlwcGFibGUgd2hpdGVzcGFjZSBub2RlLjwvcD4KLQotICA8cD5BbiBhdXhpbGxhcnkgY2xhc3MsIFdoaXRlc3BhY2VIYW5kbGVyLCBpcyB1c2VkIGZvciB0aGlzIHB1cnBvc2UuIFRoZSBjbGFzcwotICB3b3JrcyBpbiBhIHdheSBhcyBhIHN0YWNrLCB3aGVyZSB5b3UgInB1c2giIGEgbmV3IHN0cmlwL3ByZXNlcnZlIHNldHRpbmcKLSAgdG9nZXRoZXIgd2l0aCB0aGUgbm9kZSBpbiB3aGljaCB0aGlzIHNldHRpbmcgd2FzIGRldGVybWluZWQuIFRoaXMgbWVhbnMgdGhhdAotICBmb3IgZXZlcnkgdGltZSB0aGUgRE9NIGJ1aWxkZXIgZW5jb3VudGVycyBhbiA8Y29kZT54bWw6c3BhY2U8L2NvZGU+IGF0dHJpYnV0ZQotICBpdCB3aWxsIGludm9rZSBhIG1ldGhvZCBvbiBhbiBpbnN0YW5jZSBvZiB0aGUgV2hpdGVzcGFjZUhhbmRsZXIgY2xhc3MgdG8KLSAgc2lnbmFsIHRoYXQgYSBuZXcgcHJlc2VydmUvc3RyaXAgc2V0dGluZyBoYXMgYmVlbiBlbmNvdW50ZXJlZC4gVGhpcyBpcyBkb25lCi0gIGluIHRoZSA8Y29kZT5tYWtlQXR0cmlidXRlTm9kZSgpPC9jb2RlPiBtZXRob2QuIFRoZSB3aGl0ZXNwYWNlIGhhbmRsZXIgc3RvcmVzIHRoZQotICBuZXcgc2V0dGluZyBhbmQgcHVzaGVzIHRoZSBjdXJyZW50IGVsZW1lbnQgbm9kZSBvbiBpdHMgc3RhY2suIFdoZW4gdGhlCi0gIERPTSBidWlsZGVyIGNsb3NlcyB1cCBhbiBlbGVtZW50IChpbiA8Y29kZT5lbmRFbGVtZW50KCk8L2NvZGU+KSwgaXQgaW52b2tlcwotICBhbm90aGVyIG1ldGhvZCBvZiB0aGUgd2hpdGVzcGFjZSBoYW5kbGVyIHRvIGNoZWNrIGlmIHRoZSBzdHJpcC9wcmVzZXJ2ZQotICBzZXR0aW5nIGlzIHN0aWxsIHZhbGlkLiBJZiB0aGUgc2V0dGluZyBpcyBub3cgaW52YWxpZCAod2UncmUgY2xvc2luZyB0aGUKLSAgZWxlbWVudCB3aG9zZSBub2RlIGlkIGlzIG9uIHRoZSB0b3Agb2YgdGhlIHN0YWNrKSB0aGUgaGFuZGxlciBpbnZlcnRzIHRoZQotICBzZXR0aW5nIGFuZCBwb3BzIHRoZSBlbGVtZW50IG5vZGUgaWQgb2ZmIHRoZSBzdGFjay4gVGhlIHByZXZpb3VzCi0gIHN0cmlwL3ByZXNlcnZlIHNldHRpbmcgaXMgdGhlbiB2YWxpZCwgYW5kIHRoZSBpZCBvZiBub2RlIHdoZXJlIHRoaXMgc2V0dGluZwotICB3YXMgZGVmaW5lZCBpcyBvbiB0aGUgdG9wIG9mIHRoZSBzdGFjay48L3A+Ci0KLSAgPC9zMj48YW5jaG9yIG5hbWU9IndoaWNoIi8+Ci0gIDxzMiB0aXRsZT0iRGV0ZXJtaW5pbmcgd2hpY2ggbm9kZXMgdG8gc3RyaXAiPgotCi0gIDxwPkEgdGV4dCBub2RlIGlzIG5ldmVyIHN0cmlwcGVkIHVubGVzcyBpdCBjb250YWlucyBvbmx5IHdoaXRlc3BhY2UKLSAgY2hhcmFjdGVycyAoVW5pY29kZSBjaGFyYWN0ZXJzIDB4MDksIDB4MEEsIDB4MEQgYW5kIDB4MjApLiBTdHJpcHBpbmcgYSB0ZXh0Ci0gIG5vZGUgbWVhbnMgdGhhdCB0aGUgbm9kZSBkaXNhcHBlYXJzIGZyb20gdGhlIERPTTsgc28gdGhhdCBpdCBpcyBuZXZlcgotICBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGFuZCB0aGF0IGl0IGlzIGlnbm9yZWQgYnkgYWxsIGZ1bmN0aW9ucyBzdWNoIGFzCi0gIDxjb2RlPmNvdW50KCk8L2NvZGU+LiBBIHRleHQgbm9kZSBpcyBwcmVzZXJ2ZWQgaWYgYW55IG9mIHRoZSBmb2xsb3dpbmcgYXBwbHk6PC9wPgotCi0gIDx1bD4KLSAgICA8bGk+Ci0gICAgICB0aGUgZWxlbWVudCBuYW1lIG9mIHRoZSBwYXJlbnQgb2YgdGhlIHRleHQgbm9kZSBpcyBpbiB0aGUgc2V0IG9mCi0gICAgICBlbGVtZW50cyBsaXN0ZWQgaW4gPGNvZGU+Jmx0O3hzbDpwcmVzZXJ2ZS1zcGFjZSZndDs8L2NvZGU+Ci0gICAgPC9saT4KLSAgICA8bGk+Ci0gICAgICB0aGUgdGV4dCBub2RlIGNvbnRhaW5zIGF0IGxlYXN0IG9uZSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIKLSAgICA8L2xpPgotICAgIDxsaT4KLSAgICAgIGFuIGFuY2Vuc3RvciBvZiB0aGUgd2hpdGVzcGFjZSB0ZXh0IG5vZGUgaGFzIGFuIGF0dHJpYnV0ZSBvZgotICAgICAgPGNvZGU+eHNsOnNwYWNlPSZxdW90O3ByZXNlcnZlJnF1b3Q7PC9jb2RlPiwgYW5kIG5vIGNsb3NlIGFuY2VzdG9yIGhhcyBhbmQKLSAgICAgIGF0dHJpYnV0ZSBvZiA8Y29kZT54c2w6c3BhY2U9JnF1b3Q7ZGVmYXVsdCZxdW90OzwvY29kZT4uCi0gICAgPC9saT4KLSAgPC91bD4KLQotICA8cD5PdGhlcndpc2UsIHRoZSB0ZXh0IG5vZGUgaXMgc3RyaXBwZWQuIEluaXRpYWxseSB0aGUgc2V0IG9mIAotICB3aGl0ZXNwYWNlLXByZXNlcnZpbmcgZWxlbWVudCBuYW1lcyBjb250YWlucyBhbGwgZWxlbWVudCBuYW1lcywgc28gdGhlCi0gIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIHByZXNlcnZlIGFsbCB3aGl0ZXNwYWNlIHRleHQgbm9kZXMuPC9wPgotCi0gIDxwPlRoaXMgc2VlbXMgc2ltcGxlIGVub3VnaCwgYnV0IHJlc29sdmluZyBjb25mbGljdHMgYmV0d2VlbiBtYXRjaGluZwotICA8Y29kZT4mbHQ7eHNsOnN0cmlwLXNwYWNlJmd0OzwvY29kZT4gYW5kIDxjb2RlPiZsdDt4c2w6cHJlc2VydmUtc3BhY2UmZ3Q7PC9jb2RlPgotICBlbGVtZW50cyByZXF1aXJlcyBhIGxvdCBvZiB0aG91Z2h0LiBPdXIgZmlyc3QgY29uc2lkZXJhdGlvbiBpcyBpbXBvcnQKLSAgcHJlY2VkZW5jZTsgdGhlIG1hdGNoIHdpdGggdGhlIGhpZ2hlc3QgaW1wb3J0IHByZWNlZGVuY2UgaXMgYWx3YXlzIGNob3Nlbi4KLSAgSW1wb3J0IHByZWNlZGVuY2UgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlIGNvbXBhcmVkIGVsZW1lbnRzCi0gIGFyZSB2aXNpdGVkLiAoSW4gdGhpcyBjYXNlIHRob3NlIGVsZW1lbnRzIGFyZSB0aGUgdG9wLWxldmVsCi0gIDxjb2RlPiZsdDt4c2w6c3RyaXAtc3BhY2UmZ3Q7PC9jb2RlPiBhbmQgPGNvZGU+Jmx0O3hzbDpwcmVzZXJ2ZS1zcGFjZSZndDs8L2NvZGU+Ci0gIGVsZW1lbnRzLikgVGhpcyBleGFtcGxlIGlzIHRha2VuIGZyb20gdGhlIFhTTFQgcmVjb21tZW5kYXRpb246PC9wPgotCi0gIDx1bD4KLSAgICA8bGk+c3R5bGVzaGVldCBBIGltcG9ydHMgc3R5bGVzaGVldHMgQiBhbmQgQyBpbiB0aGF0IG9yZGVyOzwvbGk+Ci0gICAgPGxpPnN0eWxlc2hlZXQgQiBpbXBvcnRzIHN0eWxlc2hlZXQgRDs8L2xpPgotICAgIDxsaT5zdHlsZXNoZWV0IEMgaW1wb3J0cyBzdHlsZXNoZWV0IEUuPC9saT4KLSAgPC91bD4KLQotICA8cD5UaGVuIHRoZSBvcmRlciBvZiBpbXBvcnQgcHJlY2VkZW5jZSAobG93ZXN0IGZpcnN0KSBpcyBELCBCLCBFLCBDLCBBLjwvcD4KLQotICA8cD5PdXIgbmV4dCBjb25zaWRlcmF0aW9uIGlzIHRoZSBwcmlvcml0eSBvZiBOYW1lVGVzdHMgKFhQYXRoIHNwZWMpOjwvcD4KLSAgPHVsPgotICAgIDxsaT4KLSAgICAgIDxjb2RlPmVsZW1lbnRzPSZxdW90OyZsdDtxbmFtZSZndDsmcXVvdDs8L2NvZGU+IGhhcyBwcmlvcml0eSAwCi0gICAgPC9saT4KLSAgICA8bGk+Ci0gICAgICA8Y29kZT5lbGVtZW50cz0mcXVvdDsmbHQ7bmFtZXNwYWNlJmd0OzoqJnF1b3Q7PC9jb2RlPiBoYXMgcHJpb3JpdHkgLTAuMjUKLSAgICA8L2xpPgotICAgIDxsaT4KLSAgICAgIDxjb2RlPmVsZW1lbnRzPSZxdW90OyomcXVvdDs8L2NvZGU+IGhhcyBwcmlvcml0eSAtMC41Ci0gICAgPC9saT4KLSAgPC91bD4KLQotICA8cD5JdCBpcyBjb25zaWRlcmVkIGFuIGVycm9yIGlmIHRoZSBkZXNpY2lvbiBpcyBzdGlsbCBhbWJpZ3VvdXMgYWZ0ZXIgdGhpcywKLSAgYW5kIGl0IGlzIHVwIHRvIHRoZSBpbXBsZW1lbnRvcnMgdG8gZGVjaWRlIHdoYXQgdGhlIGFwcm9wcmlhdGUgYWN0aW9uIGlzLjwvcD4KLQotICA8cD5XaXRoIGFsbCB0aGlzIGNvbXBsZXhpdHksIHRoZSBub3JtYWwgdXNhZ2UgZm9yIHRoZXNlIGVsZW1lbnRzIGlzIHF1aXRlCi0gIHNtaXBsZTsgZWl0aGVyIHByZXNlcnZlIGFsbCB3aGl0ZXNwYWNlIG5vZGVzIGJ1dCBvbmUgdHlwZTo8L3A+Ci0KLSAgPHNvdXJjZT4mbHQ7eHNsOnN0cmlwLXNwYWNlIGVsZW1lbnRzPSJmb28iLyZndDs8L3NvdXJjZT4KLQotICA8cD5vciBzdHJpcCBhbGwgd2hpdGVzcGFjZSBub2RlcyBidXQgb25lIHR5cGU6PC9wPgotCi0gIDxzb3VyY2U+Ci0gICAgJmx0O3hzbDpzdHJpcC1zcGFjZSBlbGVtZW50cz0iKiIvJmd0OwotICAgICZsdDt4c2w6cHJlc2VydmUtc3BhY2UgZWxlbWVudHM9ImZvbyIvJmd0Ozwvc291cmNlPgotCi0gIDwvczI+PGFuY2hvciBuYW1lPSJzdHJpcCIvPgotICA8czIgdGl0bGU9IlN0cmlwcGluZyBub2RlcyI+Ci0KLSAgPHA+VGhlIHVsdGltYXRlIGdvYWwgb2Ygb3VyIGRlc2lnbiB3b3VsZCBiZSB0byB0b3RhbGx5IHNjcmVlbiBhbGwgc3RyaXBwZWQKLSAgbm9kZXMgZnJvbSB0aGUgdHJhbnNsZXQ7IHRvIGVpdGhlciBwaHlzaWNhbGx5IHJlbW92ZSB0aGVtIGZyb20gdGhlIERPTSBvciB0bwotICBtYWtlIGl0IGFwcGVhciBhcyBpZiB0aGV5IGFyZSBub3QgdGhlcmUuIFRoZSBmaXJzdCBhcHByb2FjaCB3aWxsIGNhdXNlCi0gIHByb2JsZW1zIGluIGNhc2VzIHdoZXJlIG11bHRpcGxlIHRyYW5zbGV0cyBhY2Nlc3MgdGhlIHNhbWUgRE9NLiBJbiB0aGUgZnV0dXJlCi0gIHdlIHdpc2ggdG8gbGV0IHRyYW5zbGV0cyBydW4gd2l0aGluIHNlcnZsZXRzIC8gSlNQcyB3aXRoIGEgY29tbW9uIERPTSBjYWNoZS4KLSAgVGhpcyBET00gY2FjaGUgd2lsbCBrZWVwIGNvcGllcyBvZiBET01zIGluIG1lbW9yeSB0byBwcmV2ZW50IHRoZSBzYW1lIFhNTAotICBmaWxlIGZyb20gYmVpbmcgZG93bmxvYWRlZCBhbmQgcGFyc2VkIHNldmVyYWwgdGltZXMuIFRoaXMgaXMgYSBzY2VuYXJpb3Mgd2UKLSAgbWlnaHQgc2VlOjwvcD4KLQotICAgIDxwPjxpbWcgc3JjPSJET01JbnRlcmZhY2UuZ2lmIiBhbHQ9IkRPTUludGVyZmFjZS5naWYiLz48L3A+Ci0gICAgPHA+PHJlZj5GaWd1cmUgMTogTXVsdGlwbGUgdHJhbnNsZXRzIGFjY2Vzc2luZyBhIGNvbW1vbiBwb29sIG9mIERPTXM8L3JlZj48L3A+Ci0KLSAgPHA+VGhlIHRocmVlIHRyYW5zbGV0cyBydW5uaW5nIG9uIHRoaXMgaG9zdCBhY2Nlc3MgYSBjb21tb24gcG9vbCBvZiA0IERPTXMuCi0gIFRoZSBET01zIGFyZSBhY2Nlc3NlZCB0aHJvdWdoIGEgY29tbW9uIERPTSBpbnRlcmZhY2UuIFRyYW5zbGV0cyBhY2Nlc3NpbmcKLSAgYSBzaW5nbGUgRE9NIHdpbGwgaGF2ZSBhIERPTUFkYXB0ZXIgYW5kIGEgc2luZ2xlIERPTUltcGwgb2JqZWN0IGJlaGluZCB0aGlzCi0gIGludGVyZmFjZSwgd2hpbGUgdHJhbnNsZXRzIGFjY2Vzc2luZyBzZXZlcmFsIERPTXMgd2lsbCBiZSBnaXZlbiBhIE11bHRpRE9NCi0gIGFuZCBhIHNldCBvZiBET01JbXBsIG9iamVjdHMuPC9wPgotCi0gIDxwPlRoZSB0cmFuc2xldCB0byB0aGUgbGVmdCBtYXkgd2FudCB0byBzdHJpcCBzb21lIG5vZGVzIGZyb20gdGhlIHNoYXJlZCBET00KLSAgaW4gdGhlIGNhY2hlLCB3aGlsZSB0aGUgb3RoZXIgdHJhbnNsZXRzIG1heSB3YW50IHRvIHByZXNlcnZlIGFsbCB3aGl0ZXNwYWNlCi0gIG5vZGVzLiBPdXIgaW5pdGlhbCB0aG91Z2h0IHRoZW4gaXMgdG8ga2VlcCB0aGUgRE9NIGFzIGl0IGlzIGFuZCBzb21laG93Ci0gIHNjcmVlbiB0aGUgbGVmdC1oYW5kIHRyYW5zbGV0IG9mIGFsbCB0aGUgd2hpdGVzcGFjZSBub2RlcyBpdCBkb2VzIG5vdCB3YW50IHRvCi0gIHByb2Nlc3MuIFRoZXJlIGFyZSBhIGZldyB3YXlzIGluIHdoaWNoIHdlIGNhbiBhY2NvbXBsaXNoIHRoaXM6PC9wPgotCi0gIDx1bD4KLSAgICA8bGk+Ci0gICAgICBUaGUgdHJhbnNsZXQgY2FuLCBwcmlvciB0byBzdGFydGluZyB0byB0cmF2ZXJzZSB0aGUgRE9NLCBzZW5kIGEgcmVmZXJlbmNlCi0gICAgICB0byB0aGUgdGFibGVzIGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gb24gd2hpY2ggbm9kZXMgd2Ugd2FudCBzdHJpcHBlZCB0bwotICAgICAgdGhlIERPTSBpbnRlcmZhY2UuIFRoZSBET00gaW50ZXJmYWNlIGlzIHRoZW4gcmVzcG9uc2libGUgZm9yIGhpZGluZyBhbGwKLSAgICAgIHN0cmlwcGVkIHdoaXRlc3BhY2Ugbm9kZXMgZnJvbSB0aGUgaXRlcmF0b3JzIGFuZCB0aGUgdHJhbnNsZXQuIEEgcHJvYmxlbQotICAgICAgd2l0aCB0aGlzIGFwcHJvYWNoIGlzIHRoYXQgd2Ugd2FudCB0byBvbWl0IHRoZSBET00gaW50ZXJmYWNlIGxheWVyIGlmCi0gICAgICB0aGUgdHJhbnNsZXQgaXMgb25seSBhY2Nlc3NpbmcgYSBzaW5nbGUgRE9NLiBUaGUgRE9NIGludGVyZmFjZSBsYXllciB3aWxsCi0gICAgICBvbmx5IGJlIGluc3RhbmNpYXRlZCBieSB0aGUgdHJhbnNsZXQgaWYgdGhlIHN0eWxlc2hlZXQgY29udGFpbmVkIGEgY2FsbAotICAgICAgdG8gdGhlIDxjb2RlPmRvY3VtZW50KCk8L2NvZGU+IGZ1bmN0aW9uLjxici8+PGJyLz4KLSAgICA8L2xpPgotICAgIDxsaT4KLSAgICAgIFRoZSB0cmFuc2xldCBjYW4gcHJvdmlkZSBpdHMgaXRlcmF0b3JzIHdpdGggaW5mb3JtYXRpb24gb24gd2hpY2ggbm9kZXMgaXQKLSAgICAgIGRvZXMgbm90IHdhbnQgdG8gc2VlLiBUaGUgdHJhbnNsZXQgaXMgc3RpbGwgc2hpZWxkZWQgZnJvbSB1bndhbnRlZAotICAgICAgd2hpdGVzcGFjZSBub2RlcywgYnV0IGl0IGhhcyB0aGUgaGFzc2xlIG9mIHBhc3NpbmcgZXh0cmEgaW5mb3JtYXRpb24gb3ZlcgotICAgICAgdG8gbW9zdCBpdGVyYXRvcnMgaXQgZXZlciBpbnN0YW5jaWF0ZXMuIE5vdGUgdGhhdCBhbGwgaXRlcmF0b3JzIGRvIG5vdAotICAgICAgbmVlZCBiZSBhd2FyZSBvZiB3aGl0ZXBzcGFjZSBub2RlcyBpbiB0aGlzIGNhc2UuIElmIHlvdSBoYXZlIGEgbG9vayBhdAotICAgICAgdGhlIGZpZ3VyZSBhZ2FpbiB5b3Ugd2lsbCBzZWUgdGhhdCBvbmx5IHRoZSBmaXJzdCBsZXZlbCBpdGVyYXRvciAodGhhdCBpcwotICAgICAgdGhlIG9uZSBjbG9zZXN0IHRvIHRoZSBET00gb3IgRE9NIGludGVyZmFjZSkgd2lsbCBoYXZlIHRvIHN0cmlwIG9mZgotICAgICAgd2hpdGVzcGFjZSBub2Rlcy4gQnV0LCB0aGVyZSBtYXkgYmUgc2V2ZXJhbCBpdGVyYXRvcnMgdGhhdCBvcGVyYXRlCi0gICAgICBkaXJlY3RseSBvbiB0aGUgRE9NICggaW52b2tlZCBieSBjb2RlIGhhbmRsaW5nIFhTTCBmdW5jdGlvbnMgc3VjaCBhcwotICAgICAgPGNvZGU+Y291bnQoKTwvY29kZT4pIGFuZCBldmVyeSBzaW5nbGUgb25lIG9mIHRob3NlIHdpbGwgbmVlZCB0byBiZSB0b2xkCi0gICAgICB3aGljaCB3aGl0ZXNwYWNlIG5vZGVzIHRoZSB0cmFuc2xldCBkb2VzIG5vdCB3YW50IHRvIHNlZS48YnIvPjxici8+Ci0gICAgPC9saT4KLSAgICA8bGk+Ci0gICAgICBUaGUgdGhpcmQgYXBwcm9hY2ggd2lsbCB0YWtlIGFkdmFudGFnZSBvZiB0aGUgZmFjdCB0aGF0IG5vdCBhbGwKLSAgICAgIHRyYW5zbGV0cyB3aWxsIHdhbnQgdG8gc3RyaXAgd2hpdGVzcGFjZSBub2Rlcy4gVGhlIG1vc3QgZWZmZWN0aXZlIHdheSBvZgotICAgICAgcmVtb3ZpbmcgdW53YW50ZWQgd2hpdGVzcGFjZSBub2RlcyBpcyB0byBkbyBpdCBvbmNlIGFuZCBmb3IgYWxsLCBiZWZvcmUKLSAgICAgIHRoZSBhY3R1YWwgdHJhdmVyc2FsIG9mIHRoZSBET00gc3RhcnRzLiBUaGlzIGNhbiBiZSBkb25lIGJ5IG1ha2luZyBhCi0gICAgICBjbG9uZSBvZiB0aGUgRE9NIHdpdGggZXhsdXNpdmUtYWNjZXNzIHJpZ2h0cyBmb3IgdGhpcyB0cmFuc2xldCBvbmx5LiBXZQotICAgICAgc3RpbGwgZ2FpbiBwZXJmb3JtYW5jZSBmcm9tIHRoZSBjYWNoZSBiZWNhdXNlIHdlIGRvIG5vdCBoYXZlIHRvIHBheSB0aGUKLSAgICAgIGNvc3Qgb2YgdGhlIGRlbGF5IGNhdXNlZCBieSBkb3dubG9hZGluZyBhbmQgcGFyc2luZyB0aGUgWE1MIHNvdXJjZSBmaWxlLgotICAgICAgVGhlIGNvc3Qgd2UgaGF2ZSB0byBwYXkgaXMgdGhlIHRpbWUgbmVlZGVkIGZvciB0aGUgYWN0dWFsIGNsb25pbmcgYW5kIHRoZQotICAgICAgZXh0cmEgbWVtb3J5IHdlIHVzZS48YnIvPjxici8+Ci0gICAgICBOb3JtYWxseSBvbmUgd291bGQgaW1hZ2luZSB0aGUgdHJhbnNsZXQgKG9yIHRoZSB3cmFwcGVyIGNsYXNzIHRoYXQKLSAgICAgIGludm9rZXMgdGhlIHRyYW5zbGV0KSBjYWxscyB0aGUgRE9NIGNhY2hlIHdpdGgganVzdCBhbiBVUkwgYW5kIHJlY2VpdmVzCi0gICAgICBhIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jaWF0ZWQgRE9NLiBUaGUgY2FjaGUgd2lsbCBlaXRoZXIgaGF2ZSBidWlsdAotICAgICAgdGhpcyBET00gb24tZGVtYW5kIG9yIGp1c3QgcGFzc2VkIGJhY2sgYSByZWZlcmVuY2UgdG8gYW4gZXhpc3RpbmcgdHJlZS4KLSAgICAgIEluIHRoaXMgY2FzZSB0aGUgRE9NIHdvdWxkIG5lZWQgYW4gZXh0cmEgY2FsbCB0aGF0IGEgdHJhbnNsZXQgd291bGQgdXNlCi0gICAgICB0byBjbG9uZSBhIERPTSwgcGFzc2luZyB0aGUgZXhpc3RpbmcgRE9NIHJlZmVyZW5jZSB0byB0aGUgY2FjaGUgYW5kCi0gICAgICByZWNpZXZpbmcgYSBuZXcgcmVmZXJlbmNlIHRvIHRoZSBjbG9uZWQgRE9NLiBUaGUgdHJhbnNsZXQgY2FuIHRoZW4gZG8KLSAgICAgIHdoYXRldmVyIGl0IHdhbnRzIHdpdGggdGhpcyBET00gKHRoZSBjYWNoZSBuZWVkIG5vdCBldmVuIGtlZXAgYSByZWZlcmVuY2UKLSAgICAgIHRvIHRoaXMgdHJlZSkuCi0gICAgPC9saT4KLSAgPC91bD4KLSAgCi0gIDxwPldlIGFyZSBsdWNreSBlbm91Z2ggdG8gYmUgYWJsZSB0byBjb21iaW5lIHRoZSBmaXJzdCB0d28gYXBwcm9hY2hlcy4gQWxsCi0gIGl0ZXJhdG9ycyB0aGF0IGRpcmVjdGx5IGFjY2VzcyB0aGUgRE9NIChheGlzIGl0ZXJhdG9ycykgYXJlIGluc3RhbmNpYXRlZCBieQotICBjYWxscyB0byB0aGUgRE9NIGludGVyZmFjZSBsYXllciAodGhlIERPTSBjbGFzcykuIFRoZSBhY3R1YWwgaXRlcmF0b3JzIGFyZQotICBjcmVhdGVkIGluIHRoZSBET00gaW1wbGVtZW50YXRpb24gbGF5ZXIgKHRoZSBET01JbXBsIGNsYXNzKS4gU28sIHdlIGNhbiBwYXNzCi0gIHJlZmVyZW5jZXMgdG8gdGhlIHByZXNlcnZlL3N0cmlwIHdoaXRlc3BhY2UgdGFibGVzIHRvIHRoZSBET00sIGFuZCB0aGUgRE9NCi0gIHdpbGwgbWFrZSBzdXJlIHRoYXQgYWxsIGF4aXMgaXRlcmF0b3JzIHJldHVybiBub2RlIHNldHMgd2l0aCByZXNwZWN0IHRvIHRoZXNlCi0gIHRhYmxlcy48L3A+Ci0gIDwvczI+PGFuY2hvciBuYW1lPSJmaWx0ZXIiLz4gCi0gIDxzMiB0aXRsZT0iRmlsdGVyaW5nIHdoaXRlc3BhY2Ugbm9kZXMiPgotCi0gIDxwPkZvciBlYWNoIGF4aXMgaXRlcmF0b3IgYW5kIGZvciA8Y29kZT5ET00ubWFrZVN0cmluZ1ZhbHVlKCk8L2NvZGU+IGFuZAotICA8Y29kZT5ET00uc3RyaW5nVmFsdWVBdXgoKTwvY29kZT4gd2UgbXVzdCBhcHBseSBhIGZpbHRlciBmb3IgZWxpbWluYXRpbmcgYWxsCi0gIHVud2FudGVkIHdoaXRlc3BhY2Ugbm9kZXMuIFRvIGFjaGl2ZSB0aGlzIHdlIG11c3QgYnVpbGQgYSB2ZXJ5IGVmZmljaWVudAotICBwcmVkaWNhdGUgZm9yIGRldGVybWluaW5nIGlmIHRoZSBjdXJyZW50IG5vZGUgc2hvdWxkIGJlIHN0cmlwcGVkIG9yIG5vdC4gVGhpcwotICBwcmVkaWNhdGUgaXMgYnVpbHQgYnkgPGNvZGU+V2hpdGVzcGFjZS5jb21waWxlUHJlZGljYXRlKCk8L2NvZGU+LiBUaGlzIG1ldGhvZCBpcwotICBzdGF0aWMgYW5kIGJ1aWxkcyBhIHByZWRpY2F0ZSBmb3IgYSB2ZWN0b3Igb2YgV2hpdGVzcGFjZVJ1bGUgb2JqZWN0cy4gKFRoZQotICBXaGl0ZXNwYWNlUnVsZSBjbGFzcyBpcyBkZWZpbmVkIHdpdGhpbiB0aGUgV2hpdGVzcGFjZSBjbGFzcy4pIEVhY2gKLSAgV2hpdGVzcGFjZVJ1bGUgb2JqZWN0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGZvciBhIHNpbmdsZSBlbGVtZW50IGxpc3RlZAotICBpbiBhbiA8Y29kZT4mbHQ7eHNsOnN0cmlwL3ByZXNlcnZlLXNwYWNlJmd0OzwvY29kZT4gZWxlbWVudCwgYW5kIGlzIGJyb2tlbiBkb3duCi0gIGludG8gdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjo8L3A+Ci0KLSAgPHVsPgotICAgIDxsaT50aGUgbmFtZXNwYWNlIChjYW4gYmUgdGhlIGRlZmF1bHQgbmFtZXNwYWNlKTwvbGk+Ci0gICAgPGxpPnRoZSBlbGVtZW50IG5hbWUgb3IgIjxjb2RlPio8L2NvZGU+IjwvbGk+Ci0gICAgPGxpPnRoZSB0eXBlIG9mIHJ1bGU7IE5TOkVMLCBOUzo8Y29kZT4qPC9jb2RlPiBvciA8Y29kZT4qPC9jb2RlPjwvbGk+Ci0gICAgPGxpPnRoZSBwcmlvcml0eSBvZiB0aGUgcnVsZSAoYmFzZWQgb24gaW1wb3J0IHByZWNlZGVuY2UgYW5kIHR5cGUpPC9saT4KLSAgICA8bGk+dGhlIGFjdGlvbjsgZWl0aGVyIHN0cmlwIG9yIHByZXNlcnZlcjwvbGk+Ci0gIDwvdWw+Ci0KLSAgPHA+VGhlIFZlY3RvciBvZiBXaGl0ZXNwYWNlUnVsZXMgaXMgYXJyYW5nZWQgaW4gb3JkZXIgb2YgcHJpb3JpdHkgYW5kCi0gIHJlZHVuZGFudCBydWxlcyBhcmUgcmVtb3ZlZC4gQSBwcmVkaWNhdGUgbWV0aG9kIGlzIHRoZW4gY29tcGlsZWQgaW50byB0aGUKLSAgdHJhbnNsZXQgYXM6PC9wPgotCi08c291cmNlPgotICAgIHB1YmxpYyBib29sZWFuIHN0cmlwU3BhY2UoaW50IG5vZGUpOwotPC9zb3VyY2U+Ci0KLSAgPHA+VW5mb3J0dW5hdGVseSB0aGlzIG1ldGhvZCBjYW5ub3QgYmUgZGVjbGFyZWQgc3RhdGljLjwvcD4KLQotICA8cD5XaGVuIHRoZSBTdHlsZXNoZWV0IG9iamVjdGNvbXBpbGVzIHRoZSA8Y29kZT50b3BMZXZlbCgpPC9jb2RlPiBtZXRob2Qgb2YgdGhlCi0gIHRyYW5zbGV0IGl0IGNoZWNrcyBmb3IgdGhlIGV4aXN0YW5jZSBvZiB0aGUgPGNvZGU+c3RyaXBTcGFjZSgpPC9jb2RlPiBtZXRob2QuIElmCi0gIHRoaXMgbWV0aG9kIGV4aXN0cyB0aGUgPGNvZGU+dG9wTGV2ZWwoKTwvY29kZT4gd2lsbCBiZSBjb21waWxlZCB0byBwYXNzIHRoZQotICB0cmFuc2xldCB0byB0aGUgRE9NIGFzIGEgU3RyaXBXaGl0ZXNwYWNlRmlsdGVyICh0aGUgdHJhbnNsZXQgaW1wbGVtZW50cyB0aGlzCi0gIGludGVyZmFjZSB3aGVuIHRoZSA8Y29kZT5zdHJpcFNwYWNlKCk8L2NvZGU+IG1ldGhvZCBpcyBjb21waWxlZCkuPC9wPgotCi0gIDxwPkFsbCBheGlzIGl0ZXJhdG9ycyBhbmQgdGhlIDxjb2RlPkRPTS5tYWtlU3RyaW5nVmFsdWUoKTwvY29kZT4gYW5kCi0gIDxjb2RlPkRPTS5zdHJpbmdWYWx1ZUF1eCgpPC9jb2RlPiBtZXRob2RzIGNoZWNrIGZvciB0aGUgZXhpc3RhbmNlIG9mIHRoaXMgZmlsdGVyCi0gIChpdCBpcyBrZXB0IGluIGEgZ2xvYmFsIHZhcmlhYmxlIGluIHRoZSBET00gaW1wbGVtZW50YXRpb24gY2xhc3MpIGFuZCB0YWtlcwotICB0aGUgYXBwcm9wcmlhdGUgYWN0aW9ucy4gVGhlIG1ldGhvZHMgaW4gdGhlIERPTSBmb3IgcmV0dXJuaW5nIGF4aXMgaXRlcmF0b3JzCi0gIHdpbGwgcGxhY2UgYSBTdHJpcHBpbmdJdGVyYXRvciBvbiB0b3Agb2YgdGhlIGF4aXMgaXRlcmF0b3IgaWYgdGhlIGZpbHRlciBpcwotICBwcmVzZW50LCBhbmQgdGhlIHR3byBtZXRob2RzIGp1c3QgbWVudGlvbmVkIHdpbGwgcmV0dXJuIGVtcHR5IHN0cmluZ3MgZm9yCi0gIHdoaXRlc3BhY2Ugbm9kZXMgdGhhdCBzaG91bGQgYmUgc3RyaXBwZWQuPC9wPgotIAotICA8L3MyPgotPC9zMT4KZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfY29tcGlsZXIueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy94c2x0Y19jb21waWxlci54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFlNGQ2OWQuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2x0Y19jb21waWxlci54bWwKKysrIC9kZXYvbnVsbApAQCAtMSwyNzAgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci0gIDxzMSB0aXRsZT0iWFNMVEMgQ29tcGlsZXIgRGVzaWduIj4KLSAgICA8dWw+ICAKLSAgICAgPGxpPjxsaW5rIGFuY2hvcj0ib3ZlcnZpZXciPkNvbXBpbGVyIE92ZXJ2aWV3PC9saW5rPjwvbGk+Ci0gICAgIDxsaT48bGluayBhbmNob3I9ImFzdCI+QnVpbGRpbmcgYW4gQWJzdHJhY3QgU3ludGF4IFRyZWU8L2xpbms+PC9saT4KLSAgICAgPGxpPjxsaW5rIGFuY2hvcj0idHlwZWNoZWNrIj5UeXBlLWNoZWNrIGFuZCBDYXN0IEV4cHJlc3Npb25zPC9saW5rPjwvbGk+Ci0gICAgIDxsaT48bGluayBhbmNob3I9ImNvbXBpbGUiPkNvZGUgZ2VuZXJhdGlvbjwvbGluaz48L2xpPgotICAgIDwvdWw+Ci0KLSAgICA8YW5jaG9yIG5hbWU9Im92ZXJ2aWV3Ii8+Ci0gICAgPHMyIHRpdGxlPSJDb21waWxlciBvdmVydmlldyI+Ci0KLSAgICA8cD5UaGUgaW5wdXQgc3R5bGVzaGVldCBpcyBwYXJzZWQgdXNpbmcgdGhlIFNBWCAxLWJhc2VkIHBhcnNlciBmcm9tIFN1bidzCi0gICAgUHJvamVjdCBYOjwvcD4gICAKLSAgICA8dWw+Ci0gICAgICA8bGk+PGNvZGU+Y29tLnN1bi54bWwucGFyc2VyLlBhcnNlcjwvY29kZT48L2xpPgotICAgIDwvdWw+Ci0KLSAgICA8cD5UaGlzIHBhcnNlciBidWlsZHMgYSBET00gZnJvbSB0aGUgc3R5bGVzaGVldCBkb2N1bWVudCwgYW5kIGhhbmRzIHRoaXMKLSAgICBET00gb3ZlciB0byB0aGUgY29tcGlsZXIuIFRoZSBjb21waWxlciB1c2VzIGl0cyBvd24gc3BlY2lhbGlzZWQgcGFyc2VyIHRvCi0gICAgcGFyc2UgWFBhdGggZXhwcmVzc2lvbnMgYW5kIHBhdHRlcm5zOjwvcD4KLSAgICA8dWw+Ci0gICAgICA8bGk+PGNvZGU+Y29tLnN1bi54c2x0LmNvbXBpbGVyLlhQYXRoUGFyc2VyPC9jb2RlPjwvbGk+Ci0gICAgPC91bD4KLSAgICA8cD5Cb3RoIHBhcnNlcnMgYXJlIGVuY2Fwc3VsYXRlZCBpbiBYU0xUQydzIHBhcnNlciBjbGFzczo8L3A+Ci0gICAgPHVsPgotICAgICAgPGxpPjxjb2RlPmNvbS5zdW4ueHNsdC5jb21waWxlci5QYXJzZXI8L2NvZGU+PC9saT4KLSAgICA8L3VsPgotCi0gICAgPC9zMj48YW5jaG9yIG5hbWU9ImFzdCIvPgotICAgIDxzMiB0aXRsZT0iQnVpbGRpbmcgYW4gQWJzdHJhY3QgU3ludGF4IFRyZWUiPgotICAgIDx1bD4KLSAgICAgIDxsaT48bGluayBhbmNob3I9Im1hcHBpbmciPk1hcHBpbmcgc3R5bGVzaGVldCBlbGVtZW50cyB0byBKYXZhIGNsYXNzZXM8L2xpbms+PC9saT4KLSAgICAgIDxsaT48bGluayBhbmNob3I9ImRvbXhzbCI+QnVpbGRpbmcgYSBET00gdHJlZSBmcm9tIHRoZSBpbnB1dCBYU0wgZmlsZTwvbGluaz48L2xpPiAgICAgIAotICAgIDwvdWw+Ci0gICAgPHA+VGhlIFNBWCBwYXJzZXIgYnVpbGRzIGEgc3RhbmRhcmQgVzNDIERPTSBmcm9tIHRoZSBzb3VyY2Ugc3R5bGVzaGVldC4KLSAgICBUaGlzIERPTSBkb2VzIG5vdCBjb250YWluIGFsbCB0aGUgaW5mb3JtYXRpb24gbmVlZGVkIHRvIHJlcHJlc2VudCB0aGUKLSAgICB3aG9sZSBzdHlsZXNoZWV0LiAoIFJlbWVtYmVyIHRoYXQgWFNMIGlzIHR3byBsYW5ndWFnZXM7IFhNTCBhbmQgWFBhdGguCi0gICAgVGhlIERPTSBvbmx5IGNvdmVycyBYTUwuICkgVGhlIGNvbXBpbGVyIHVzZXMgdGhlIERPTSB0byBidWlsZCBhbgotICAgIGFic3RyYWN0IHN5bnRheCB0cmVlIChBU1QpIHRoYXQgY29udGFpbnMgYWxsIHRoZSBub2RlcyBmcm9tIHRoZSBET00sIHBsdXMKLSAgICBhZGRpdGlvbmFsIG5vZGVzIGZvciB0aGUgWFBhdGggZXhwcmVzc2lvbnMuPC9wPgotICAgIDxhbmNob3IgbmFtZT0ibWFwcGluZyIvPgotICAgIDxzMyB0aXRsZT0iTWFwcGluZyBzdHlsZXNoZWV0cyBlbGVtZW50cyB0byBKYXZhIGNsYXNzZXMiPgotICAgIDxwPkVhY2ggWFNMIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSBjbGFzcyBpbiB0aGUKLSAgICA8Y29kZT5jb20uc3VuLnhzbHQuY29tcGlsZXI8L2NvZGU+IHBhY2thZ2UuIFRoZSBQYXJzZXIgY2xhc3MgY29udGFpbnMgYQotICAgIEhhc2h0YWJsZSB0aGF0IHRoYXQgbWFwcyBYU0wgaW5zdHJ1Y3Rpb25zIHRvIGNsYXNzZXMgdGhhdCBpbmhlcml0IGZyb20gYQotICAgIGNvbW1vbiBwYXJlbnQgY2xhc3MgJ0luc3RydWN0aW9uJyAod2hpY2ggYWdhaW4gaW5oZXJpdHMgZnJvbQotICAgICdTeW50YXhUcmVlTm9kZScpLiBUaGlzIG1hcHBpbmcgaXMgc2V0IHVwIGluIHRoZSA8Y29kZT5pbml0Q2xhc3NlcygpPC9jb2RlPiBtZXRob2Q6PC9wPgotPHNvdXJjZT4gICAgcHJpdmF0ZSB2b2lkIGluaXRTdGRDbGFzc2VzKCkgewotCXRyeSB7Ci0JICAgIGluaXRTdGRDbGFzcygidGVtcGxhdGUiLCAgICAiVGVtcGxhdGUiKTsKLQkgICAgaW5pdFN0ZENsYXNzKCJwYXJhbSIsICAgICAgICJQYXJhbSIpOwotCSAgICBpbml0U3RkQ2xhc3MoIndpdGgtcGFyYW0iLCAgIldpdGhQYXJhbSIpOwotCSAgICBpbml0U3RkQ2xhc3MoInZhcmlhYmxlIiwgICAgIlZhcmlhYmxlIik7Ci0JICAgIGluaXRTdGRDbGFzcygib3V0cHV0IiwgICAgICAiT3V0cHV0Iik7Ci0JICAgIDoKLQkgICAgOgotCSAgICA6Ci0JfQotICAgIH0KLQotICAgIHByaXZhdGUgdm9pZCBpbml0Q2xhc3MoU3RyaW5nIGVsZW1lbnROYW1lLCBTdHJpbmcgY2xhc3NOYW1lKQotCXRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKLQlfY2xhc3Nlcy5wdXQoZWxlbWVudE5hbWUsCi0JCSAgICAgQ2xhc3MuZm9yTmFtZShDT01QSUxFUl9QQUNLQUdFICsgJy4nICsgY2xhc3NOYW1lKSk7Ci0gICAgfTwvc291cmNlPgotICAgIDwvczM+PGFuY2hvciBuYW1lPSJkb214c2wiLz4KLSAgICA8czMgdGl0bGU9IkJ1aWxkaW5nIGEgRE9NIHRyZWUgZnJvbSB0aGUgaW5wdXQgWFNMIGZpbGUiPgotICAgIDxwPlRoZSBwYXJzZXIgaW5zdGFuY2lhdGVzIGEgRE9NIHRoYXQgaG9sZHMgdGhlIGlucHV0IFhTTCBzdHlsZXNoZWV0LiBUaGUKLSAgICBET00gY2FuIG9ubHkgaGFuZGxlIFhNTCBmaWxlcyBhbmQgd2lsbCBub3QgYnJlYWsgdXAgYW5kIGlkZW50aWZ5IFhQYXRoCi0gICAgcGF0dGVybnMvZXhwcmVzc2lvbnMgKHRoZXNlIGFyZSBzdG9yZWQgYXMgYXR0cmlidXRlcyB0byB0aGUgdmFyaW91cwotICAgIG5vZGVzIGluIHRoZSB0cmVlKSBvciBjYWxscyB0byBYU0wgZnVuY3Rpb25zKCkuIEVhY2ggWFNMIGluc3RydWN0aW9uIGdldHMKLSAgICBpdHMgb3duIG5vZGUgaW4gdGhlIERPTSwgYW5kIHRoZSBYUGF0aCBwYXR0ZXJucy9leHByZXNzaW9ucyBhcmUgc3RvcmVkIGFzCi0gICAgYXR0cmlidXRlcyBvZiB0aGVzZSBub2Rlcy4gQSBzdHlsZXNoZWV0IGxvb2tpbmcgbGlrZSB0aGlzOjwvcD4KLTxzb3VyY2U+Ci0gICAgJmx0O3hzbDpzdHlsZXNoZWV0IC4uLi4uLi4mZ3Q7Ci0gICAgICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSJjaGFwdGVyIiZndDsKLSAgICAgICAgJmx0O3hzbDp0ZXh0Jmd0O0NoYXB0ZXImbHQ7L3hzbDp0ZXh0Jmd0OwotICAgICAgICAmbHQ7eHNsdmFsdWUtb2Ygc2VsZWN0PSIuIiZndDsKLSAgICAgICZsdDsveHNsOnRlbXBsYXRlJmd0OwotICAgICZsdDsveHNsJmd0O3N0eWxlc2hlZXQmZ3Q7Ci08L3NvdXJjZT4KLSAgICA8cD53aWxsIGJlIHN0b3JlZCBpbiB0aGUgRE9NIGFzIGluZGljYXRlZCBpbiB0aGUgZm9sbG93aW5nIHBpY3R1cmU6PC9wPgotICAgIDxwPjxpbWcgc3JjPSJjb21waWxlcl9ET00uZ2lmIiBhbHQ9ImNvbXBpbGVyX0RPTS5naWYiLz48L3A+Ci0gICAgPHA+PHJlZj5GaWd1cmUgMTogRE9NIGNvbnRhaW5pbmcgWFNMIHN0eWxlc2hlZXQ8L3JlZj48L3A+Ci0gICAgPHA+VGhlIHBhdHRlcm4gJzxjb2RlPm1hdGNoPSJjaGFwdGVyIjwvY29kZT4nIGFuZCB0aGUgZXhwcmVzc2lvbgotICAgICc8Y29kZT5zZWxlY3Q9Ii4iPC9jb2RlPicgYXJlIHN0b3JlZCBhcyBhdHRyaWJ1dGVzIGZvciB0aGUgbm9kZXMKLSAgICAnPGNvZGU+eHNsOnRlbXBsYXRlPC9jb2RlPicgYW5kICc8Y29kZT54c2w6dmFsdWUtb2Y8L2NvZGU+JyByZXNwZWN0aXZlbHkuCi0gICAgVGhlc2UgYXR0cmlidXRlcyBhcmUgYWNjZXNzaWJsZSB0aHJvdWdoIHRoZSBET00gaW50ZXJmYWNlLjwvcD4KLSAgICA8L3MzPgotICAgICA8czMgdGl0bGU9IkNyZWF0aW5nIHRoZSBBYnN0cmFjdCBTeW50YXggVHJlZSBmcm9tIHRoZSBET00iPgotICAgIDxwPldoYXQgd2UgaGF2ZSB0byBkbyBuZXh0IGlzIHRvIGNyZWF0ZSBhIHRyZWUgdGhhdCBhbHNvIGhvbGRzIHRoZSBYU0wKLSAgICBzcGVjaWZpYyBlbGVtZW50czsgWFBhdGggZXhwcmVzc2lvbnMgYW5kIHBhdHRlcm5zICh3aXRoIHBvc3NpYmxlIGZpbHRlcnMpCi0gICAgYW5kIGNhbGxzIHRvIFhTTCBmdW5jdGlvbnMuIFRoaXMgaXMgZG9uZSBieSBwYXJzaW5nIHRoZSBET00gYW5kIGNyZWF0aW5nIGFuCi0gICAgaW5zdGFuY2Ugb2YgYSBzdWJjbGFzcyBvZiAnU3ludGF4VHJlZU5vZGUnIGZvciBlYWNoIG5vZGUgaW4gdGhlIERPTS4gQSBub2RlCi0gICAgaW4gdGhlIERPTSBjb250YWluaW5nIGFuIFhTTCBpbnN0cnVjdGlvbiAoZm9yIGV4YW1wbGUsICJ4c2w6dGVtcGxhdGUiKSByZXN1bHRzIGluIGFuCi0gICAgaW5zdGFuY2Ugb2YgdGhlIGNvcnJlc3BvZGluZyBjbGFzcyBkZXJpdmVkIGZyb20gdGhlIEhhc2hUYWJsZSBjcmVhdGVkIGJ5Ci0gICAgdGhlIHBhcnNlciAoaW4gdGhpcyBjYXNlIGluIGluc3RhbmNlIG9mIHRoZSAnVGVtcGxhdGUnIGNsYXNzKS48L3A+Ci0KLSAgICA8cD5FYWNoIGNsYXNzIHRoYXQgaW5oZXJpdHMgU3ludGF4VHJlZU5vZGUgaGFzIGEgdmVjdG9yIGNhbGxlZAotICAgICc8Y29kZT5fY29udGVudHM8L2NvZGU+JyB0aGF0IGhvbGRzIHJlZmVyZW5jZXMgdG8gYWxsIHRoZSBjaGlsZHJlbiBvZiB0aGUgbm9kZQotICAgIChpZiBhbnkpLiBFYWNoIG5vZGUgaGFzIGEgbWV0aG9kIGNhbGxlZCAnPGNvZGU+cGFyc2VDb250ZW50cygpPC9jb2RlPicuIEl0IGlzCi0gICAgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoaXMgbWV0aG9kIHRvIHBhcnNlIGFueSBYUGF0aCBleHByZXNzaW9ucy9wYXR0ZXJucwotICAgIHRoYXQgYXJlIGV4cGVjdGVkIGFuZCBmb3VuZCBpbiB0aGUgbm9kZSdzIGF0dHJpYnV0ZXMuIFRoZSBYUGF0aCBwYXR0ZXJucwotICAgIGFuZCBpbnN0cnVjdGlvbnMgYXJlIHRva2VuaXNlZCB1c2luZyB0aGUgYXV0by1nZW5lcmF0ZWQgY2xhc3MgJ1hQYXRoUGFyc2VyJwotICAgIChnZW5lcmF0ZWQgdXNpbmcgSmF2YUN1cCBhbmQgSkxleCkuIFRoZSB0b2tlbmlzZWQgZXhwcmVzc2lvbnMvcGF0dGVybnMKLSAgICB3aWxsIHJlc3VsdCBpbiBhIHNtYWxsIHN1Yi10cmVlIG93bmVkIGJ5IHRoZSBzeW50YXggdHJlZSBub2RlLjwvcD4KLQotICAgIDxwPlhTTCBub2RlcyBob2xkaW5nIGV4cHJlc3Npb25zIGhhcyBhIHBvaW50ZXIgY2FsbGVkICc8Y29kZT5fc2VsZWN0PC9jb2RlPicgdGhhdAotICAgIHBvaW50cyB0byBhIHN1Yi10cmVlIHJlcHJlc2VudGluZyB0aGUgZXhwcmVzc2lvbi4gVGhpcyBjYW4gYmUgc2VlbiBmb3IKLSAgICBpbnN0YW5jZSBpbiB0aGUgJ1RlbXBsYXRlJyBjbGFzczo8L3A+Ci0gICAgPHA+PGltZyBzcmM9ImNvbXBpbGVyX0FTVC5naWYiIGFsdD0iY29tcGlsZXJfQVNULmdpZiIvPjwvcD4KLSAgICA8cD48cmVmPkZpdWdyZSAyOiBTYW1wbGUgQWJzdHJhY3QgU3ludGF4IFRyZWU8L3JlZj48L3A+Ci0gICAgPHA+SW4gdGhpcyBleGFtcGxlIF9zZWxlY3Qgb25seSBwb2ludHMgdG8gYSBzaW5nbGUgbm9kZS4gSW4gbW9yZSBjb21wbGV4Ci0gICAgZXhwcmVzc2lvbnMgdGhlIHBvaW50ZXIgd2lsbCBwb2ludCB0byBhbiB3aG9sZSBzdWItdHJlZS48L3A+Ci0gICAgIDwvczM+Ci0gICAgIDwvczI+PGFuY2hvciBuYW1lPSJ0eXBlY2hlY2siLz4KLSAgICA8czIgdGl0bGU9IlR5cGUtY2hlY2sgYW5kIENhc3QgRXhwcmVzc2lvbnMiPgotICAgIDxwPkluIG1hbnkgY2FzZXMgd2Ugd2lsbCBuZWVkIHRvIHR5cGVjYXN0IHRoZSB0b3Agbm9kZSBpbiB0aGUgZXhwcmVzc2lvbgotICAgIHN1Yi10cmVlIHRvIHN1aXQgdGhlIGV4cGVjdGVkIHJlc3VsdC10eXBlIG9mIHRoZSBleHByZXNzaW9uLCBvciB0byB0eXBlY2FzdAotICAgIGNoaWxkIG5vZGVzIHRvIHN1aXQgdGhlIGFsbG93ZWQgdHlwZXMgZm9yIHRoZSB2YXJpb3VzIG9wZXJhdG9ycyBpbiB0aGUKLSAgICBleHByZXNzaW9uLiBUaGlzIGlzIGRvbmUgYnkgY2FsbGluZyAndHlwZUNoZWNrKCknIG9uIHRoZSByb290LW5vZGUgaW4gdGhlCi0gICAgWFNMIHRyZWUuIEVhY2ggU3ludGF4VHJlZSBub2RlIGlzIHJlc3BvbnNpYmxlIGZvciBpdHMgb3duIHR5cGUgY2hlY2tpbmcKLSAgICAoaWUuIHRoZSA8Y29kZT50eXBlQ2hlY2soKTwvY29kZT4gbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbikuIExldCB1cyBzYXkgdGhhdAotICAgIG91ciBwYXR0ZXJuIHdhczo8L3A+Ci0gICAgPHA+PGNvZGU+Jmx0O3hzbDp2YWx1ZS1vZiBzZWxlY3Q9JnF1b3Q7MSsyLjczJnF1b3Q7LyZndDs8L2NvZGU+PC9wPgotICAgIDxwPjxpbWcgc3JjPSJ0eXBlY2FzdC5naWYiIGFsdD0idHlwZWNhc3QuZ2lmIi8+PC9wPgotICAgIDxwPjxyZWY+RmlndXJlIDM6IFhQYXRoIGV4cHJlc3Npb24gdHlwZSBjb25mbGljdDwvcmVmPjwvcD4KLSAgICA8cD5UaGUgbnVtYmVyIDEgaXMgYW4gaW50ZWdlciwgYW5kIHRoZSBudW1iZXIgMi43MyBpcyBhIHJlYWwgbnVtYmVyLCBzbyB0aGUKLSAgICAxIGhhcyB0byBiZSBwcm9tb3RlZCB0byBhIHJlYWwuIFRoaXMgaXMgZG9uZSBueSBpbnNlcnRpbmcgYSBuZXcgbm9kZSBiZXR3ZWVuCi0gICAgdGhlIFsxXSBhbmQgdGhlIFsrXS4gVGhpcyBub2RlIHdpbGwgY29udmVydCB0aGUgMSB0byBhIHJlYWwgbnVtYmVyOjwvcD4KLSAgICA8cD48aW1nIHNyYz0iY2FzdF9leHByZXNzaW9uLmdpZiIgYWx0PSJjYXN0X2V4cHJlc3Npb24uZ2lmIi8+PC9wPgotICAgIDxwPjxyZWY+RmlndXJlIDQ6IFR5cGUgY2FzdGluZzwvcmVmPjwvcD4KLQotICAgIDxwPlRoZSBpbnNlcnRlZCBub2RlIGlzIGFuIG9iamVjdCBvZiB0aGUgY2xhc3MgQ2FzdEV4cHIuIFRoZSBTeW1ib2xUYWJsZQotICAgIHRoYXQgd2FzIGluc3RhbmNpYXRlZCBpbiAoMSkgaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hhdCBjYXN0cyBhcmUgbmVlZGVkIGZvcgotICAgIHRoZSB2YXJpb3VzIG9wZXJhdG9ycyBhbmQgd2hhdCByZXR1cm4gdHlwZXMgdGhlIHZhcmlvdXMgZXhwcmVzc2lvbnMgd2lsbAotICAgIGhhdmUuPC9wPgotCi0gICAgPC9zMj48YW5jaG9yIG5hbWU9ImNvbXBpbGUiLz4KLSAgICA8czIgdGl0bGU9IkNvZGUgZ2VuZXJhdGlvbiI+Ci0gICAgPHVsPgotICAgICAgPGxpPjxsaW5rIGFuY2hvcj0idG9wbGV2ZWxlbGVtIj5Db21waWxpbmcgdG9wLWxldmVsIGVsZW1lbnRzPC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJ0ZW1wbGF0ZWNvZGUiPkNvbXBpbGluZyB0ZW1wbGF0ZSBjb2RlPC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJpbnN0cmZ1bmMiPkNvbXBpbGluZyBYU0wgaW5zdHJ1Y3Rpb25zIGFuZCBmdW5jdGlvbnM8L2xpbms+PC9saT4gICAgICAgICAgICAKLSAgICA8L3VsPgotICAgIDxwPkEgZ2VuZXJhbCBydWxlIGlzIHRoYXQgYWxsIGNsYXNzZXMgdGhhdCByZXByZXNlbnQgZWxlbWVudHMgaW4gdGhlIFhTTAotICAgIHRyZWUvZG9jdW1lbnQsIGkuZS4sIGNsYXNzZXMgdGhhdCBpbmhlcml0IGZyb20gU3ludGF4VHJlZU5vZGUsIG91dHB1dAotICAgIGJ5dGVjb2RlIGluIHRoZSAndHJhbnNsYXRlKCknIG1ldGhvZC48L3A+Ci0gICAgPGFuY2hvciBuYW1lPSJ0b3BsZXZlbGVsZW0iLz4KLSAgICA8czMgdGl0bGU9IkNvbXBpbGluZyB0b3AtbGV2ZWwgZWxlbWVudHMiPgotICAgIDxwPlRoZSBieXRlY29kZSB0aGF0IGhhbmRsZXMgdG9wLWxldmVsIGVsZW1lbnRzIG11c3QgYmUgZ2VuZXJhdGVkIGJlZm9yZSBhbnkKLSAgICBvdGhlciBjb2RlLiBUaGUgJzxjb2RlPnRyYW5zbGF0ZSgpPC9jb2RlPicgbWV0aG9kIGluIHRoZXNlIGNsYXNzZXMgYXJlIG1haW5seQotICAgIGNhbGxlZCBmcm9tIHRoZXNlIG1ldGhvZHMgaW4gdGhlIFN0eWxlc2hlZXQgY2xhc3M6PC9wPgotCi08c291cmNlPiAgICBwcml2YXRlIFN0cmluZyBjb21waWxlQnVpbGRLZXlzKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuKTsKLSAgICBwcml2YXRlIFN0cmluZyBjb21waWxlVG9wTGV2ZWwoQ2xhc3NHZW5lcmF0b3IgY2xhc3NHZW4sIEVudW1lcmF0aW9uIGVsZW1lbnRzKTsKLSAgICBwcml2YXRlIHZvaWQgY29tcGlsZUNvbnN0cnVjdG9yKENsYXNzR2VuZXJhdG9yIGNsYXNzR2VuLCBPdXRwdXQgb3V0cHV0KTs8L3NvdXJjZT4KLQotICAgIDxwPlRoZXNlIG1ldGhvZHMgaGFuZGxlIG1vc3QgdG9wLWxldmVsIGVsZW1lbnRzLCBzdWNoIGFzIGdsb2JhbCB2YXJpYWJsZXMKLSAgICBhbmQgcGFyYW1ldGVycywgPGNvZGU+Jmx0O3hzbDpvdXRwdXQmZ3Q7PC9jb2RlPiBhbmQKLSAgICA8Y29kZT4mbHQ7eHNsOmRlY2ltYWwtZm9ybWF0Jmd0OzwvY29kZT4gaW5zdHJ1Y3Rpb25zLjwvcD4KLSAgICA8L3MzPjxhbmNob3IgbmFtZT0idGVtcGxhdGVjb2RlIi8+Ci0gICAgPHMzIHRpdGxlPSJDb21waWxpbmcgdGVtcGxhdGUgY29kZSI+Ci0gICAgPHA+QWxsIFhQYXRoIHBhdHRlcm5zIGluIDxjb2RlPiZsdDt4c2w6YXBwbHktdGVtcGxhdGUmZ3Q7PC9jb2RlPiBpbnN0cnVjdGlvbnMKLSAgICBhcmUgY29udmVydGVkIGludG8gbnVtZXJpYyB2YWx1ZXMgKGtub3duIGFzIHRoZSBwYXR0ZXJuJ3Mga2VybmVsICd0eXBlJykuCi0gICAgQWxsIHRlbXBsYXRlcyB3aXRoIGlkZW50aWNhbCBwYXR0ZXJuIGtlcm5lbCB0eXBlcyBhcmUgZ3JvdXBlZCB0b2dldGhlciBhbmQKLSAgICBpbnNlcnRlZCBpbnRvIGEgdGFibGUgd2l0aCBpdHMgYXNzaWduZWQgdHlwZS4gKFRoaXMgdGFibGUgaXMgZm91bmQgaW4gdGhlCi0gICAgTW9kZSBjbGFzcy4gVGhlcmUgd2lsbCBiZSBvbmUgc3VjaCB0YWJsZSBmb3IgZWFjaCBtb2RlIHRoYXQgaXMgdXNlZCBpbiB0aGUKLSAgICBzdHlsZXNoZWV0KS4gVGhpcyB0YWJsZSBpcyB1c2VkIHRvIGJ1aWxkIGEgYmlnIDxjb2RlPnN3aXRjaCgpPC9jb2RlPiBzdGF0ZW1lbnQKLSAgICBpbiB0aGUgdHJhbnNsZXQncyA8Y29kZT5hcHBseVRlbXBsYXRlcygpPC9jb2RlPiBtZXRob2QuIFRoaXMgbWV0aG9kIGlzIGluaXRpYWxseQotICAgIGNhbGxlZCB3aXRoIHRoZSByb290IG5vZGUgb2YgdGhlIGlucHV0IGRvY3VtZW50LjwvcD4KLSAgICA8cD5UaGUgPGNvZGU+YXBwbHlUZW1wbGF0ZXMoKTwvY29kZT4gbWV0aG9kIGRldGVybWluZXMgdGhlIG5vZGUncyB0eXBlIGFuZCBwYXNzZXMKLSAgICB0aGlzIHR5cGUgdG8gdGhlIDxjb2RlPnN3aXRjaCgpPC9jb2RlPiBzdGF0ZW1lbnQgdG8gbG9vayB1cCB0aGUgbWF0Y2hpbmcKLSAgICB0ZW1wbGF0ZS48L3A+Ci0KLSAgICA8cD5UaGVyZSBtYXkgYmUgc2V2ZXJhbCB0ZW1wbGF0ZXMgdGhhdCBzaGFyZSB0aGUgc2FtZSBwYXR0ZXJuIGtlcm5lbCB0eXBlLgotICAgIEhlcmUgYXJlIGEgZmV3IGV4YW1wbGVzIG9mIHRlbXBsYXRlcyB3aXRoIHBhdHRlcm5zIHRoYXQgYWxsIGhhdmUgdGhlIHNhbWUKLSAgICBrZXJuZWwgdHlwZTo8L3A+Ci0KLTxzb3VyY2U+ICAgICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9JnF1b3Q7QS9DJnF1b3Q7Jmd0OwotICAgICZsdDt4c2w6dGVtcGxhdGUgbWF0Y2g9JnF1b3Q7QS9CL0MmcXVvdDsmZ3Q7Ci0gICAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0mcXVvdDtBIHwgQyZxdW90OyZndDs8L3NvdXJjZT4KLQotICAgIDxwPkFsbCB0aGVzZSB0ZW1wbGF0ZXMgd2lsbCBiZSBncm91cGVkIHVuZGVyIHRoZSB0eXBlIGZvciA8Y29kZT4mbHQ7QyZndDs8L2NvZGU+Ci0gICAgYW5kIHdpbGwgYWxsIGdldCB0aGUgc2FtZSBrZXJuZWwgdHlwZSAodGhlIHR5cGUgZm9yIDxjb2RlPiJDIjwvY29kZT4pLiBUaGUgbGFzdAotICAgIHRlbXBsYXRlIHdpbGwgYmUgZ3JvdXBlZCBib3RoIHVuZGVyIDxjb2RlPiJDIjwvY29kZT4gYW5kIDxjb2RlPiJBIjwvY29kZT4uIElmIHRoZQotICAgIHR5cGUgaWRlbnRpZmllciBmb3IgPGNvZGU+IkMiPC9jb2RlPiBpbiB0aGlzIGNhc2UgaXMgOCwgYWxsIHRoZXNlIHRlbXBsYXRlcyB3aWxsCi0gICAgYmUgcHV0IHVuZGVyIDxjb2RlPmNhc2UgODo8L2NvZGU+IGluIDxjb2RlPmFwcGx5VGVtcGxhdGVzKCk8L2NvZGU+J3MgYmlnCi0gICAgPGNvZGU+c3dpdGNoKCk8L2NvZGU+IHN0YXRlbWVudC4gVGhlIE1vZGUgY2xhc3Mgd2lsbCBpbnNlcnQgZXh0cmEgY29kZSB0byBjaG9vc2UKLSAgICB3aGljaCB0ZW1wbGF0ZSBjb2RlIHRvIGludm9rZS48L3A+Ci0gICAgPC9zMz48YW5jaG9yIG5hbWU9Imluc3RyZnVuYyIvPgotICAgIDxzMyB0aXRsZT0iQ29tcGlsaW5nIFhTTCBpbnN0cnVjdGlvbnMgYW5kIGZ1bmN0aW9ucyI+Ci0KLSAgICA8cD5UaGUgdGVtcGxhdGUgY29kZSBpcyBnZW5lcmF0ZWQgYnkgY2FsbGluZyA8Y29kZT50cmFuc2xhdGUoKTwvY29kZT4gb24gZWFjaAotICAgIFRlbXBsYXRlIG9iamVjdCBpbiB0aGUgYWJzdHJhY3Qgc3ludGF4IHRyZWUuIFRoaXMgY2FsbCB3aWxsIGJlIHByb3BhZ2F0ZWQKLSAgICBkb3duIHRoZSB0cmVlIGFuZCBldmVyeSBlbGVtZW50IHdpbGwgb3V0cHV0IHRoZSBieXRlY29kZXMgbmVjZXNzYXJ5IHRvCi0gICAgY29tcGxldGUgaXRzIHRhc2suPC9wPgotCi0gICAgPHA+RWFjaCBub2RlIHdpbGwgY2FsbCAndHJhbnNsYXRlKCknIG9uIGl0cyBjaGlsZHJlbiwgYW5kIHBvc3NpYmx5IG9uCi0gICAgb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlIG5vZGUncyBYUGF0aCBleHByZXNzaW9ucywgYmVmb3JlIG91dHB1dHRpbmcgaXRzCi0gICAgb3duIGJ5dGVjb2RlLiBJbiB0aGF0IHdheSB0aGUgY29ycmVjdCBzZXF1ZW5jZSBvZiBpbnN0cnVjdGlvbnMgaXMgZ2VuZXJhdGVkLgotICAgIEVhY2ggb25lIG9mIHRoZSBjaGlsZCBub2RlcyBpcyByZXNwb25zaWJsZSBvZiBjcmVhdGluZyBjb2RlIHRoYXQgbGVhdmVzIHRoZQotICAgIG5vZGUncyBvdXRwdXQgdmFsdWUgKGlmIGFueSkgb24gdGhlIHN0YWNrLiBUaGUgdHlwaWNhbCBwcm9jZWR1cmUgZm9yIHRoZQotICAgIHBhcmVudCBub2RlIGlzIHRvIGNyZWF0ZSBjb2RlIHRoYXQgY29uc3VtZXMgdGhlc2UgdmFsdWVzIG9mZiB0aGUgc3RhY2sgYW5kCi0gICAgdGhlbiBsZWF2ZSBpdHMgb3duIG91dHB1dCBvbiB0aGUgc3RhY2sgZm9yIGl0cyBwYXJlbnQuPC9wPgotCi0gICAgPHA+VGhlIHRyZWUtc3RydWN0dXJlIG9mIHRoZSBzdHlsZXNoZWV0IGlzIGluIHRoaXMgd2F5IGNsb3NlbHkgdGllZCB3aXRoCi0gICAgdGhlIHN0YWNrLWJhc2VkIEpWTS4gVGhlIGRlc2lnbiBkb2VzIG5vdCBvZmZlciBhbnkgb2J2aW91cyB3YXkgb2YgZXh0ZW5kaW5nCi0gICAgdGhlIGNvbXBpbGVyIHRvIG91dHB1dCBjb2RlIGZvciBvdGhlciBWTXMgb3IgcHJvY2Vzc29ycy48L3A+Ci0gICA8L3MzPgotICA8L3MyPgotPC9zMT4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbHRjX2RvbS54bWwgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbHRjX2RvbS54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDkzNTU3ZGQuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2x0Y19kb20ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsNDgzICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgc3RhbmRhbG9uZT0ibm8iPz4KLTwhRE9DVFlQRSBzMSBTWVNURU0gIi4uLy4uL3N0eWxlL2R0ZC9kb2N1bWVudC5kdGQiPgotPCEtLSAKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotIC0tPgotPHMxIHRpdGxlPSJYU0xUQyBJbnRlcm5hbCBET00iPgotICA8dWw+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iZnVuY3Rpb25hbGl0eSI+R2VuZXJhbCBmdW5jdGlvbmxhaXR5PC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iY29tcG9uZW50cyI+Q29tcG9uZW50cyBvZiB0aGUgaW50ZXJuYWwgRE9NPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0ic3RydWN0dXJlIj5JbnRlcm5hbCBzdHJ1Y3R1cmU8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJuYXZpZ2F0aW9uIj5UcmVlIG5hdmlnYXRpb248L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJuYW1lc3BhY2VzIj5OYW1lc3BhY2VzPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0idzNjIj5XM0MgRE9NMiBuYXZpZ2F0aW9uIHN1cHBvcnQ8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJhZGFwdGVyIj5UaGUgRE9NIGFkYXB0ZXIgLSBET01BZGFwdGVyPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0ibXVsdGlwbGV4ZXIiPlRoZSBET00gbXVsdGlwbGV4ZXIgLSBNdWx0aURPTTwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9ImJ1aWxkZXIiPlRoZSBET00gYnVpbGRlciAtIERPTUltcGwkRE9NQnVpbGRlcjwvbGluaz48L2xpPgotICA8L3VsPgotCi0gIDxhbmNob3IgbmFtZT0iZnVuY3Rpb25hbGl0eSIvPgotICA8czIgdGl0bGU9IkdlbmVyYWwgZnVuY3Rpb25hbGl0eSI+Ci0gIDxwPlRoZSBpbnRlcm5hbCBET00gZ2l2ZXMgdGhlIHRyYW5zbGV0IGFjY2VzcyB0byB0aGUgWE1MIGRvY3VtZW50KHMpIGl0IGhhcwotICB0byB0cmFuc2Zvcm0uIFRoZSBpbnRlcmZhY2UgdG8gdGhlIGludGVybmFsIERPTSBpcyBzcGVjaWZpZWQgaW4gdGhlIERPTS5qYXZhCi0gIGNsYXNzLiBUaGlzIGlzIHRoZSBpbnRlcmZhY2UgdGhhdCB0aGUgdHJhbnNsZXQgdXNlcyB0byBhY2Nlc3MgdGhlIERPTS4gCi0gIFRoZXJlIGlzIGFsc28gYW4gaW50ZXJmYWNlIHNwZWNpZmllZCBmb3IgRE9NIGNhY2hlcyAtLSBET01DYWNoZS5qYXZhPC9wPgotCi0gIDwvczI+PGFuY2hvciBuYW1lPSJjb21wb25lbnRzIi8+Ci0gIDxzMiB0aXRsZT0iQ29tcG9uZW50cyBvZiB0aGUgaW50ZXJuYWwgRE9NIj4KLQotICA8cD5UaGlzIERPTSBpbnRlcmZhY2UgaXMgaW1wbGVtZW50ZWQgYnkgdGhyZWUgY2xhc3Nlczo8L3A+Ci0gIDx1bD4KLSAgICA8bGk+PGVtPm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRPTUltcGw8L2VtPjxici8+PGJyLz4KLSAgICAgIFRoaXMgaXMgdGhlIG1haW4gRE9NIGNsYXNzLiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGNvbnRhaW5zIHRoZSBub2RlcwotICAgICAgb2YgYSA8ZW0+c2luZ2xlPC9lbT4gWE1MIGRvY3VtZW50Ljxici8+YnIvPgotICAgIDwvbGk+Ci0gICAgPGxpPjxlbT5vcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5NdWx0aURPTTwvZW0+PGJyLz48YnIvPgotICAgICAgVGhpcyBjbGFzcyBpcyBiZXN0IGRlc2NyaWJlZCBhcyBhIERPTSBtdWx0aXBsZXhlci4gWFNMVEMgd2FzIGluaXRpYWxseQotICAgICAgZGVzaWduZWQgdG8gb3BlcmF0ZSBvbiBhIHNpbmdsZSBYTUwgZG9jdW1lbnQsIGFuZCB0aGUgaW5pdGlhbCBET00gYW5kCi0gICAgICB0aGUgRE9NIGludGVyZmFjZSB3ZXJlIGRlc2lnbmVkIGFuZCBpbXBsZW1lbnRlZCB3aXRob3V0IHRoZQotICAgICAgPGNvZGU+ZG9jdW1lbnQoKTwvY29kZT4gZnVuY3Rpb24gaW4gbWluZC4gVGhpcyBjbGFzcyB3aWxsIGFsbG93IGEgdHJhbnNsZXQKLSAgICAgIHRvIGFjY2VzcyBtdWx0aXBsZSBET01zIHRocm91Z2ggdGhlIG9yaWdpbmFsIERPTSBpbnRlcmZhY2UuPGJyLz48YnIvPgotICAgIDwvbGk+Ci0gICAgPGxpPjxlbT5vcmcuYXBhY2hlLnhhbGFuLnhzbHRjLmRvbS5ET01BZGFwdGVyPC9lbT48YnIvPmJyLz4KLSAgICAgIFRoZSBET00gYWRhcHRlciBpcyBhIG1lZGlhdG9yIGJldHdlZW4gYSBET01JbXBsIG9yIGEgTXVsdGlET00gb2JqZWN0IGFuZAotICAgICAgYSBzaW5nbGUgdHJhbnNsZXQuIEEgRE9NQWRhcHRlciBvYmplY3QgY29udGFpbnMgbWFwcGluZ3MgYW5kIHJldmVyc2UKLSAgICAgIG1hcHBpbmdzIGJldHdlZW4gbm9kZSAgdHlwZXMgaW4gdGhlIERPTShzKSBhbmQgbm9kZSB0eXBlcyBpbiB0aGUgdHJhbnNsZXQuCi0gICAgICBUaGlzIG1lZGlhdG9yIGlzIG5lZWRlZCB0byBhbGxvdyBzZXZlcmFsIHRyYW5zbGV0cyBhY2Nlc3MgdG8gYSBzaW5nbGUgRE9NLgotICAgICAgPGJyLz5ici8+Ci0gICAgPC9saT4KLSAgICA8bGk+PGVtPm9yZy5hcGFjaGUueGFsYW4ueHNsdGMuZG9tLkRvY3VtZW50Q2FjaGU8L2VtPjxici8+YnIvPgotICAgICAgQSBzYW1wbGUgRE9NIGNhY2hlIChpbXBsZW1lbnRpbmcgRE9NQ2FjaGUpIHRoYXQgaXMgdXNlZCB3aXRoIG91ciBzYW1wbGUKLSAgICAgIHRyYW5zZm9ybWF0aW9uIGFwcGxpY2F0aW9ucy4KLSAgICA8L2xpPgotICA8L3VsPgotCi0gIDxwPjxpbWcgc3JjPSJET01JbnRlcmZhY2UuZ2lmIiBhbHQ9IkRPTUludGVyZmFjZS5naWYiLz48L3A+Ci0gIDxwPjxyZWY+RmlndXJlIDE6IE1haW4gY29tcG9uZW50cyBvZiB0aGUgaW50ZXJuYWwgRE9NPC9yZWY+PC9wPgotCi0gIDxwPlRoZSBmaWd1cmUgYWJvdmUgc2hvd3MgaG93IHNldmVyYWwgdHJhbnNsZXRzIGNhbiBhY2Nlc3Mgb25lIG9yIG1vcmUKLSAgaW50ZXJuYWwgRE9NIGZyb20gYSBzaGFyZWQgcG9vbCBvZiBjYWNoZWQgRE9Ncy4gQSB0cmFuc2xldCBjYW4gYWxzbyBhY2Nlc3MgYQotICBET00gdHJlZSBvdXRzaWRlIG9mIGEgY2FjaGUuIFRoZSBTdHlsZXNoZWV0IGNsYXNzIHRoYXQgcmVwcmVzZW50cyB0aGUgWFNMCi0gIHN0eWxlc2hlZXQgdG8gY29tcGlsZSBjb250YWlucyBhIGZsYWcgdGhhdCBpbmRpY2F0ZXMgaWYgdGhlIHRyYW5zbGV0IHVzZXMgdGhlCi0gIDxjb2RlPmRvY3VtZW50KCk8L2NvZGU+IGZ1bmN0aW9uLiBUaGUgY29kZSBjb21waWxlZCBpbnRvIHRoZSB0cmFuc2xldCB3aWxsIGFjdAotICBhY2NvcmRpbmdseSBhbmQgaW5zdGFuY2lhdGUgYSBNdWx0aURPTSBvYmplY3QgaWYgbmVlZGVkICh0aGlzIGNvZGUgaXMgY29tcGlsZWQKLSAgIGluIHRoZSBjb21waWxlcidzIDxjb2RlPlN0eWxlc2hlZXQuY29tcGlsZVRyYW5zZm9ybSgpPC9jb2RlPiBtZXRob2QpLjwvcD4KLQotICA8L3MyPjxhbmNob3IgbmFtZT0ic3RydWN0dXJlIi8+Ci0gIDxzMiB0aXRsZT0iSW50ZXJuYWwgU3RydWN0dXJlIj4KLSAgPHVsPgotICAgIDxsaT48bGluayBhbmNob3I9Im5vZGUtaWQiPk5vZGUgaWRlbnRpZmljYXRpb248L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJlbGVtZW50LW5vZGVzIj5FbGVtZW50IG5vZGVzPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iYXR0cmlidXRlLW5vZGVzIj5BdHRyaWJ1dGUgbm9kZXM8L2xpbms+PC9saT4gICAgCi0gICAgPGxpPjxsaW5rIGFuY2hvcj0idGV4dC1ub2RlcyI+VGV4dCBub2RlczwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9ImNvbW1lbnQtbm9kZXMiPkNvbW1lbnQgbm9kZXM8L2xpbms+PC9saT4gICAgCi0gICAgPGxpPjxsaW5rIGFuY2hvcj0icGkiPjwvbGluaz5Qcm9jZXNzaW5nIGluc3RydWN0aW9uczwvbGk+Ci0gIDwvdWw+Ci0gIDxhbmNob3IgbmFtZT0ibm9kZS1pZCIvPgotICA8czMgdGl0bGU9Ik5vZGUgaWRlbnRpZmF0aW9uIj4KLQotICA8cD5FYWNoIG5vZGUgaW4gdGhlIERPTSBpcyByZXByZXNlbnRlZCBieSBhbiBpbnRlZ2VyLiBUaGlzIGludGVnZXIgaXMgYW4KLSAgaW5kZXggaW50byBhIHNlcmllcyBvZiBhcnJheXMgdGhhdCBkZXNjcmliZXMgdGhlIG5vZGUuIE1vc3QgaW1wb3J0YW50IGlzCi0gIHRoZSA8Y29kZT5fdHlwZVtdPC9jb2RlPiBhcnJheSwgd2hpY2ggaG9sZHMgdGhlIChET00gaW50ZXJuYWwpIG5vZGUgdHlwZS4gVGhlcmUKLSAgYXJlIHNvbWUgZ2VuZXJhbCBub2RlIHR5cGVzIHRoYXQgYXJlIGRlc2NyaWJlZCBpbiB0aGUgRE9NLmphdmEgaW50ZXJmYWNlOjwvcD4KLQotPHNvdXJjZT4KLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBST09UICAgICAgICAgICAgICAgICAgID0gMDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBURVhUICAgICAgICAgICAgICAgICAgID0gMTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBVTlVTRUQgICAgICAgICAgICAgICAgID0gMjsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBFTEVNRU5UICAgICAgICAgICAgICAgID0gMzsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBBVFRSSUJVVEUgICAgICAgICAgICAgID0gNDsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OID0gNTsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDT01NRU5UICAgICAgICAgICAgICAgID0gNjsKLSAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBOVFlQRVMgICAgICAgICAgICAgICAgID0gNzsKLTwvc291cmNlPgotCi0gIDxwPkVsZW1lbnQgYW5kIGF0dHJpYnV0ZSBub2RlcyB3aWxsIGJlIGFzc2lnbmVkIHR5cGVzIGJhc2VkIG9uIHRoZWlyIGV4cGFuZGVkCi0gIFFOYW1lcy4gVGhlIDxjb2RlPl90eXBlW108L2NvZGU+IGFycmF5IGlzIHVzZWQgZm9yIHRoaXM6PC9wPgotCi08c291cmNlPgotICAgIGludCAgICB0eXBlICAgICAgPSBfdHlwZVtub2RlXTsgICAgICAgICAgICAgLy8gZ2V0IG5vZGUgdHlwZQotPC9zb3VyY2U+Ci0KLSAgPHA+VGhlIG5vZGUgdHlwZSBjYW4gYmUgdXNlZCB0byBsb29rIHVwIHRoZSBlbGVtZW50L2F0dHJpYnV0ZSBuYW1lIGluIHRoZQotICBlbGVtZW50L2F0dHJpYnV0ZSBuYW1lIGFycmF5IDxjb2RlPl9uYW1lc0FycmF5W108L2NvZGU+OjwvcD4KLQotPHNvdXJjZT4KLSAgICBTdHJpbmcgbmFtZSAgICAgID0gX25hbWVzQXJyYXlbdHlwZS1OVFlQRVNdOyAvLyBnZXQgbm9kZSBlbGVtZW50IG5hbWUKLTwvc291cmNlPgotCi0gIDxwPlRoZSByZXN1bHRpbmcgc3RyaW5nIGNvbnRhaW5zIHRoZSBmdWxsLCBleHBhbmRlZCBRTmFtZSBvZiB0aGUgZWxlbWVudCBvcgotICBhdHRyaWJ1dGUuIFJldHJpZXZpbmcgdGhlIG5hbWVzcGFjZSBVUkkgb2YgYW4gZWxlbWVudC9hdHRyaWJ1dGUgaXMgZG9uZSBpbiBhCi0gIHZlcnkgc2ltaWxhciBmYXNoaW9uOjwvcD4KLQotPHNvdXJjZT4KLSAgICBpbnQgICAgbnN0eXBlICAgID0gX25hbWVzcGFjZVt0eXBlLU5UWVBFU107IC8vIGdldCBuYW1lc3BhY2UgdHlwZQotICAgIFN0cmluZyBuYW1lc3BhY2UgPSBfbnNOYW1lc0FycmF5W25zdHlwZV07ICAgLy8gZ2V0IG5vZGUgbmFtZXNwYWNlIG5hbWUKLTwvc291cmNlPgotICA8L3MzPjxhbmNob3IgbmFtZT0iZWxlbWVudC1ub2RlcyIvPgotICA8czMgdGl0bGU9IkVsZW1lbnQgbm9kZXMiPgotCi0gIDxwPlRoZSBjb250ZW50cyBvZiBhbiBlbGVtZW50IG5vZGUgKGNoaWxkIG5vZGVzKSBjYW4gYmUgaWRlbnRpZmllZCB1c2luZwotICB0aGUgPGNvZGU+X29mZnNldE9yQ2hpbGRbXTwvY29kZT4gYW5kIDxjb2RlPl9uZXh0U2libGluZ1tdPC9jb2RlPiBhcnJheXMuIFRoZQotICA8Y29kZT5fb2Zmc2V0T3JDaGlsZFtdPC9jb2RlPiBhcnJheSB3aWxsIGdpdmUgeW91IHRoZSBmaXJzdCBjaGlsZCBvZiBhbiBlbGVtZW50Ci0gIG5vZGU6PC9wPgotCi08c291cmNlPgotICAgIGludCAgICBjaGlsZCAgICAgPSBfb2Zmc2V0T3JDaGlsZFtub2RlXTsgICAgLy8gZmlyc3QgY2hpbGQKLSAgICBjaGlsZCA9IF9uZXh0U2libGluZ1tjaGlsZF07ICAgICAgICAgICAgICAgIC8vIG5leHQgY2hpbGQKLTwvc291cmNlPgotCi0gIDxwPlRoZSBsYXN0IGNoaWxkIHdpbGwgaGF2ZSBhICZxdW90Ozxjb2RlPl9uZXh0U2libGluZ1tdPC9jb2RlPiZxdW90OyBvZiAwICh6ZXJvKS4KLSAgVGhpcyB2YWx1ZSBpcyBPSyBzaW5jZSB0aGUgcm9vdCBub2RlICh0aGUgMCBub2RlKSB3aWxsIG5vdCBiZSBhIGNoaWxkIG9mCi0gIGFueSBlbGVtZW50LjwvcD4KLQotICA8L3MzPjxhbmNob3IgbmFtZT0iYXR0cmlidXRlLW5vZGVzIi8+Ci0gIDxzMyB0aXRsZT0iQXR0cmlidXRlIG5vZGVzIj4KLQotICA8cD5UaGUgZmlyc3QgYXR0cmlidXRlIG5vZGUgb2YgYW4gZWxlbWVudCBpcyBmb3VuZCBieSBhIGxvb2t1cCBpbiB0aGUKLSAgPGNvZGU+X2xlbmd0aE9yQXR0cltdPC9jb2RlPiBhcnJheSB1c2luZyB0aGUgbm9kZSBpbmRleDo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgaW50ICAgIGF0dHJpYnV0ZSA9IF9vZmZzZXRPckNoaWxkW25vZGVdOyAgICAvLyBmaXJzdCBhdHRyaWJ1dGUKLSAgICBhdHRyaWJ1dGUgPSBfbmV4dFNpYmxpbmdbYXR0cmlidXRlXTsgICAgICAgIC8vIG5leHQgYXR0cmlidXRlCi08L3NvdXJjZT4KLQotICA8cD5UaGUgbmFtZXMgb2YgYXR0cmlidXRlcyBhcmUgY29udGFpbmVkIGluIHRoZSA8Y29kZT5fbmFtZXNBcnJheVtdPC9jb2RlPiBqdXN0Ci0gIGxpa2UgdGhlIG5hbWVzIG9mIGVsZW1lbnQgbm9kZXMuIFRoZSB2YWx1ZSBvZiBhdHRyaWJ1dGVzIGFyZSBzdG9yZSB0aGUgc2FtZQotICB3YXkgYXMgdGV4dCBub2Rlczo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgaW50ICAgIG9mZnNldCAgICA9IF9vZmZzZXRPckNoaWxkW2F0dHJpYnV0ZV07IC8vIG9mZnNldCBpbnRvIGNoYXJhY3RlciBhcnJheQotICAgIGludCAgICBsZW5ndGggICAgPSBfbGVuZ3RoT3JBdHRyW2F0dHJpYnV0ZV07ICAvLyBsZW5ndGggb2YgYXR0cmlidXRlIHZhbHVlCi0gICAgU3RyaW5nIHZhbHVlICAgICA9IG5ldyBTdHJpbmcoX3RleHQsIG9mZnNldCwgbGVuZ3RoKTsKLTwvc291cmNlPgotICA8L3MzPjxhbmNob3IgbmFtZT0idGV4dC1ub2RlcyIvPgotICA8czMgdGl0bGU9IlRleHQgbm9kZXMiPgotCi0gIDxwPlRleHQgbm9kZXMgYXJlIHN0b3JlZCBpZGVudGljYWxseSB0byBhdHRyaWJ1dGUgdmFsdWVzLiBTZWUgdGhlIHByZXZpb3VzCi0gIHNlY3Rpb24gb24gPGxpbmsgYW5jaG9yPSJhdHRyaWJ1dGUtbm9kZXMiPmF0dHJpYnV0ZSBub2RlczwvbGluaz4uPC9wPgotICA8L3MzPjxhbmNob3IgbmFtZT0iY29tbWVudC1ub2RlcyIvPgotICA8czMgdGl0bGU9IkNvbW1lbnQgbm9kZXMiPgotCi0gIDxwPlRoZSBpbnRlcm5hbCBET00gZG9lcyBjdXJyZW50bHkgPGVtPm5vdDwvZW0+IGNvbnRhaW4gY29tbWVudCBub2Rlcy4gWWVzLCBJCi0gIGFtIHF1aXRlIGF3YXJlIHRoYXQgdGhlIERPTSBoYXMgYSB0eXBlIGFzc2lnbmVkIHRvIGNvbW1lbnQgbm9kZXMsIGJ1dCBjb21tZW50cwotICBhcmUgc3RpbGwgbm90IGluc2VydGVkIGludG8gdGhlIERPTS48L3A+Ci0gIDwvczM+PGFuY2hvciBuYW1lPSJwaSIvPgotICA8czMgdGl0bGU9IlByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zIj4KLQotICA8cD5Qcm9jZXNzaW5nIGluc3RydWN0aW9ucyBhcmUgaGFuZGxlZCBhcyB0ZXh0IG5vZGVzLiBUaGVzZSBub2RlcyBhcmUgc3RvcmVkCi0gIGlkZW50aWNhbGx5IHRvIGF0dHJpYnV0ZSB2YWx1ZXMuIFNlZSB0aGUgcHJldmlvdXMgc2VjdGlvbiBvbgotICA8bGluayBhbmNob3I9ImF0dHJpYnV0ZS1ub2RlcyI+YXR0cmlidXRlIG5vZGVzPC9saW5rPi48L3A+Ci0KLSAgPC9zMz48L3MyPjxhbmNob3IgbmFtZT0ibmF2aWdhdGlvbiIvPgotICA8czIgdGl0bGU9IlRyZWUgbmF2aWdhdGlvbiI+Ci0KLSAgPHA+VGhlIERPTSBpbXBsZW1lbnRhdGlvbiBjb250YWlucyBhIHNlcmllcyBvZiBpdGVyYXRvciB0aGF0IGltcGxlbWVudCB0aGUKLSAgWFBhdGggYXhpcy4gQWxsIHRoZXNlIGl0ZXJhdG9ycyBpbXBsZW1lbnQgdGhlIE5vZGVJdGVyYXRvciBpbnRlcmZhY2UgYW5kCi0gIGV4dGVuZCB0aGUgTm9kZUl0ZXJhdG9yQmFzZSBiYXNlIGNsYXNzLiBUaGVzZSBpdGVyYXRvcnMgZG8gdGhlIGpvYiBvZgotICBuYXZpZ2F0aW5nIHRoZSB0cmVlIHVzaW5nIHRoZSA8Y29kZT5fb2Zmc2V0T3JDaGlsZFtdPC9jb2RlPiwgPGNvZGU+X25leHRTaWJsaW5nPC9jb2RlPgotICBhbmQgPGNvZGU+X3BhcmVudFtdPC9jb2RlPiBhcnJheXMuIEFsbCBpdGVyYXRvcnMgdGhhdCBoYW5kbGVzIFhQYXRoIGF4aXMgYXJlCi0gIGltcGxlbWVudGVkIGFzIGEgcHJpdmF0ZSBpbm5lciBjbGFzcyBvZiBET01JbXBsLiBUaGUgdHJhbnNsZXQgdXNlcyBhIGhhbmRmdWwKLSAgb2YgbWV0aG9kcyB0byBpbnN0YW5jaWF0ZSB0aGVzZSBpdGVyYXRvcnM6PC9wPgotCi08c291cmNlPgotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0SXRlcmF0b3IoKTsKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldENoaWxkcmVuKGZpbmFsIGludCBub2RlKTsKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldFR5cGVkQ2hpbGRyZW4oZmluYWwgaW50IHR5cGUpOwotICAgIHB1YmxpYyBOb2RlSXRlcmF0b3IgZ2V0QXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzKTsKLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldFR5cGVkQXhpc0l0ZXJhdG9yKGZpbmFsIGludCBheGlzLCBmaW5hbCBpbnQgdHlwZSk7Ci0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROdGhEZXNjZW5kYW50KGludCBub2RlLCBpbnQgbik7Ci0gICAgcHVibGljIE5vZGVJdGVyYXRvciBnZXROYW1lc3BhY2VBeGlzSXRlcmF0b3IoZmluYWwgaW50IGF4aXMsIGZpbmFsIGludCBucyk7Ci0gICAgcHVibGljIE5vZGVJdGVyYXRvciBvcmRlck5vZGVzKE5vZGVJdGVyYXRvciBzb3VyY2UsIGludCBub2RlKTsKLTwvc291cmNlPgotCi0gIDxwPlRoZXJlIGFyZSBhIGZldyBpdGVyYXRvcnMgaW4gYWRkaXRpb24gdG8gdGhlc2UsIHN1Y2ggYXMgc29ydGluZy9vcmRlcmluZwotICBpdGVyYXRvcnMgYW5kIGZpbHRlcmluZyBpdGVyYXRvcnMuIFRoZXNlIGl0ZXJhdG9ycyBhcmUgaW1wbGVtZW50ZWQgaW4KLSAgc2VwYXJhdGUgY2xhc3NlcyBhbmQgY2FuIGJlIGluc3RhbmNpYXRlZCBkaXJlY3RseSBieSB0aGUgdHJhbnNsZXQuPC9wPgotCi0gIDwvczI+PGFuY2hvciBuYW1lPSJuYW1lc3BhY2VzIi8+Ci0gIDxzMiB0aXRsZT0iTmFtZXNwYWNlcyI+Ci0KLSAgPHA+TmFtZXNwYWNlIHN1cHBvcnQgd2FzIGFkZGVkIHRvIHRoZSBpbnRlcm5hbCBET00gYXQgYSBsYXRlIHN0YWdlLCBhbmQgdGhlCi0gIGRlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIERPTSBiZWFycyBhIGZldyBzY2FycyBiZWNhdXNlIG9mIHRoaXMuIAotICBUaGVyZSBpcyBhIHNlcGFyYXRlIDxsaW5rIGlkcmVmPSJ4c2x0Y19uYW1lc3BhY2UiPmRlc2lnbgotICBkb2N1bWVudDwvbGluaz4gdGhhdCBjb3ZlcnMgbmFtZXNwYWNlcy48L3A+Ci0KLSAgPC9zMj48YW5jaG9yIG5hbWU9InczYyIvPgotICA8czIgdGl0bGU9IlczQyBET00yIG5hdmlnYXRpb24gc3VwcG9ydCI+Ci0KLSAgPHA+VGhlIERPTSBoYXMgYSBmZXcgbWV0aG9kcyB0aGF0IGdpdmUgYmFzaWMgVzNDLXR5cGUgRE9NIG5hdmlnYXRpb24uIFRoZXNlCi0gIG1ldGhvZHMgYXJlOjwvcD4KLQotPHNvdXJjZT4KLSAgICBwdWJsaWMgTm9kZSBtYWtlTm9kZShpbnQgaW5kZXgpOwotICAgIHB1YmxpYyBOb2RlIG1ha2VOb2RlKE5vZGVJdGVyYXRvciBpdGVyKTsKLSAgICBwdWJsaWMgTm9kZUxpc3QgbWFrZU5vZGVMaXN0KGludCBpbmRleCk7Ci0gICAgcHVibGljIE5vZGVMaXN0IG1ha2VOb2RlTGlzdChOb2RlSXRlcmF0b3IgaXRlcik7Ci08L3NvdXJjZT4KLQotICA8cD5UaGVzZSBtZXRob2RzIHJldHVybiBpbnN0YW5jZXMgb2YgaW5uZXIgY2xhc3NlcyBvZiB0aGUgRE9NIHRoYXQgaW1wbGVtZW50Ci0gIHRoZSBXM0MgTm9kZSBhbmQgTm9kZUxpc3QgaW50ZXJmYWNlcy48L3A+Ci0KLSAgPC9zMj48YW5jaG9yIG5hbWU9ImFkYXB0ZXIiLz4KLSAgPHMyIHRpdGxlPSJUaGUgRE9NIGFkYXB0ZXIgLSBET01BZGFwdGVyIj4KLSAgPHVsPgotICAgIDxsaT48bGluayBhbmNob3I9InRyYW5zbGV0LWRvbSI+VHJhbnNsZXQvRE9NIHR5cGUgbWFwcGluZzwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9IndoaXRlc3BhY2UiPldoaXRlc3BhY2UgdGV4dC1ub2RlIHN0cmlwcGluZzwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9Im1ldGhvZC1tYXBwaW5nIj5NZXRob2QgbWFwcGluZzwvbGluaz48L2xpPgotICA8L3VsPgotICA8YW5jaG9yIG5hbWU9InRyYW5zbGV0LWRvbSIvPgotICA8czMgdGl0bGU9IlRyYW5zbGV0L0RPTSB0eXBlIG1hcHBpbmciPgotCi0gIDxwPlRoZSBET01BZGFwdGVyIGNsYXNzIHBlcmZvcm1zIHRoZSBtYXBwaW5ncyBiZXR3ZWVuIERPTSBhbmQgdHJhbnNsZXQgbm9kZQotICB0eXBlcywgYW5kIHZpY2UgdmVyc2EuIFRoZXNlIG1hcHBpbmdzIGFyZSBuZWNlc3NhcnkgaW4gb3JkZXIgZm9yIHRoZSB0cmFuc2xldAotICB0byBjb3JyZWN0bHkgaWRlbnRpZnkgYW4gZWxlbWVudC9hdHRyaWJ1dGUgaW4gdGhlIERPTSBhbmQgZm9yIHRoZSBET00gdG8KLSAgY29ycmVjdGx5IGlkZW50aWZ5IHRoZSBlbGVtZW50L2F0dHJpYnV0ZSB0eXBlIG9mIGEgdHlwZWQgaXRlcmF0b3IgcmVxdWVzdGVkCi0gIGJ5IHRoZSB0cmFuc2xldC4gTm90ZSB0aGF0IHRoZSBET01BZGFwdGVyIGFsc28gbWFwcyB0cmFuc2xldCBuYW1lc3BhY2UgdHlwZXMKLSAgdG8gRE9NIG5hbWVzcGFjZSB0eXBlcywgYW5kIHZpY2UgdmVyc2EuPC9wPgotCi0gIDxwPlRoZSBET01BZGFwdGVyIGNsYXNzIGhhcyBmb3VyIGdsb2JhbCB0YWJsZXMgdGhhdCBob2xkIHRoZSB0cmFuc2xldC9ET00KLSAgdHlwZSBhbmQgbmFtZXNwYWNlLXR5cGUgbWFwcGluZ3MuIElmIHRoZSBET00ga25vd3MgYW4gZWxlbWVudCBhcyB0eXBlCi0gIDE5LCB0aGUgRE9NQWRhcHRlciB3aWxsIHRyYW5zbGF0ZSB0aGlzIHRvIHNvbWUgb3RoZXIgaW50ZWdlciB1c2luZyB0aGUKLSAgPGNvZGU+X21hcHBpbmdbXTwvY29kZT4gYXJyYXk6PC9wPgotCi08c291cmNlPgotICAgIGludCBkb21UeXBlID0gX21hcHBpbmdbdHJhbnNsZXRUeXBlXTsKLTwvc291cmNlPgotCi0gIDxwPlRoaXMgYWN0aW9uIHdpbGwgYmUgcGVyZm9ybWVkIHdoZW4gdGhlIERPTSBhc2tzIHdoYXQgdHlwZSBhIHNwZWNpZmljIG5vZGUKLSAgaXMuIFRoZSByZXZlcnNlIGlzIGRvbmUgdGhlbiB0aGUgdHJhbnNsZXQgd2FudHMgYW4gaXRlcmF0b3IgZm9yIGEgc3BlY2lmaWMKLSAgbm9kZSB0eXBlLiBUaGUgRE9NQWRhcHRlciBtdXN0IHRyYW5zbGF0ZSB0aGUgdHJhbnNsZXQtdHlwZSB0byB0aGUgdHlwZSB1c2VkCi0gIGludGVybmFsbHkgaW4gdGhlIERPTSBieSBsb29raW5nIHVwIHRoZSA8Y29kZT5fcmV2ZXJzZVtdPC9jb2RlPiBhcnJheTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgaW50IHRyYW5zbGV0VHlwZSA9IF9tYXBwaW5nW2RvbVR5cGVdOwotPC9zb3VyY2U+Ci0KLSAgPHA+VGhlcmUgYXJlIHR3byBhZGRpdGlvbmFsIG1hcHBpbmcgdGFibGVzOiA8Y29kZT5fTlNtYXBwaW5nW108L2NvZGU+IGFuZAotICA8Y29kZT5fTlNyZXZlcnNlW108L2NvZGU+IHRoYXQgZG8gdGhlIHNhbWUgZm9yIG5hbWVzcGFjZSB0eXBlcy48L3A+Ci0gIDwvczM+PGFuY2hvciBuYW1lPSJ3aGl0ZXNwYWNlIi8+Ci0gIDxzMyB0aXRsZT0iV2hpdGVzcGFjZSB0ZXh0LW5vZGUgc3RyaXBwaW5nIj4KLQotICA8cD5UaGUgRE9NQWRhcHRlciBjbGFzcyBoYXMgdGhlIGFkZGl0aW9uYWwgZnVuY3Rpb24gb2Ygc3RyaXBwaW5nIHdoaXRlc3BhY2UKLSAgbm9kZXMgaW4gdGhlIERPTS4gVGhpcyBmdW5jdGlvbmFsaXR5IGhhZCB0byBiZSBwdXQgaW4gdGhlIERPTUFkYXB0ZXIsIGFzCi0gIGRpZmZlcmVudCB0cmFuc2xldHMgd2lsbCBoYXZlIGRpZmZlcmVudCBwcmVmZXJlbmNlcyBmb3Igbm9kZSBzdHJpcHBpbmcuPC9wPgotICA8L3MzPjxhbmNob3IgbmFtZT0ibWV0aG9kLW1hcHBpbmciLz4KLSAgPHMzIHRpdGxlPSJNZXRob2QgbWFwcGluZyI+Ci0KLSAgPHA+VGhlIERPTUFkYXB0ZXIgY2xhc3MgaW1wbGVtZW50cyB0aGUgc2FtZSA8Y29kZT5ET008L2NvZGU+IGludGVyZmFjZSBhcyB0aGUKLSAgRE9NSW1wbCBjbGFzcy4gQSBET01BZGFwdGVyIG9iamVjdCB3aWxsIGxvb2sgbGlrZSBhIERPTUltcGwgdHJlZSwgYnV0IHRoZQotICB0cmFuc2xldCBjYW4gYWNjZXNzIGl0IGRpcmVjdGx5IHdpdGhvdXQgYmVpbmcgY29uY2VybmVkIHdpdGggdHlwZSBtYXBwaW5nCi0gIGFuZCB3aGl0ZXNwYWNlIHN0cmlwcGluZy4gVGhlIDxjb2RlPmdldFR5cGVkQ2hpbGRyZW4oKTwvY29kZT4gZGVtb25zdHJhdGVzIHZlcnkKLSAgd2VsbCBob3cgdGhpcyBpcyBkb25lOjwvcD4KLQotPHNvdXJjZT4KLSAgICBwdWJsaWMgTm9kZUl0ZXJhdG9yIGdldFR5cGVkQ2hpbGRyZW4oaW50IHR5cGUpIHsKLSAgICAgICAgLy8gR2V0IHRoZSBET00gdHlwZSBmb3IgdGhlIHJlcXVlc3RlZCB0eXBlZCBpdGVyYXRvcgotICAgICAgICBmaW5hbCBpbnQgZG9tVHlwZSA9IF9yZXZlcnNlW3R5cGVdOwotICAgICAgICAvLyBOb3cgZ2V0IHRoZSB0eXBlZCBjaGlsZCBpdGVyYXRvciBmcm9tIHRoZSBET01JbXBsIG9iamVjdAotICAgICAgICBOb2RlSXRlcmF0b3IgaXRlcmF0b3IgPSBfZG9tSW1wbC5nZXRUeXBlZENoaWxkcmVuKGRvbVR5cGUpOwotICAgICAgICAvLyBXcmFwIHRoZSBpdGVyYXRvciBpbiBhIFdTIHN0cmlwcGluZyBpdGVyYXRvciBpZiBjaGlsZC1ub2RlcyBhcmUgdGV4dCBub2RlcwotCWlmICgoZG9tVHlwZSA9PSBET00uVEVYVCkgJmFtcDsmYW1wOyAoX2ZpbHRlciAhPSBudWxsKSkKLQkgICAgaXRlcmF0b3IgPSBfZG9tSW1wbC5zdHJpcHBpbmdJdGVyYXRvcihpdGVyYXRvcixfbWFwcGluZyxfZmlsdGVyKTsKLQlyZXR1cm4oaXRlcmF0b3IpOwotICAgIH0KLTwvc291cmNlPgotCi0gIDwvczM+PC9zMj48YW5jaG9yIG5hbWU9Im11bHRpcGxleGVyIi8+Ci0gIDxzMiB0aXRsZT0iVGhlIERPTSBtdWx0aXBsZXhlciAtIE11bHRpRE9NIj4KLQotICA8cD5UaGUgRE9NIG11bHRpcGxleGVyIGNsYXNzIGlzIG9ubHkgdXNlZCB3aGVuIHRoZSBjb21waWxlZCBzdHlsZXNoZWV0IHVzZXMKLSAgdGhlIDxjb2RlPmRvY3VtZW50KCk8L2NvZGU+IGZ1bmN0aW9uLiBBbiBpbnN0YW5jZSBvZiB0aGUgTXVsdGlET00gY2xhc3MgYWxzbwotICBpbXBsZW1lbnRzIHRoZSBET00gaW50ZXJmYWNlLCBzbyB0aGF0IGl0IGNhbiBiZSBhY2Nlc3NlZCBpbiB0aGUgc2FtZSB3YXkKLSAgYXMgYSBET01BZGFwdGVyIG9iamVjdC48L3A+Ci0KLSAgPHA+QSBub2RlIGluIHRoZSBET00gaXMgaWRlbnRpZmllZCBieSBhbiBpbnRlZ2VyLiBUaGUgZmlyc3QgOCBiaXRzIG9mIHRoaXMKLSAgaW50ZWdlciBhcmUgdXNlZCB0byBpZGVudGlmeSB0aGUgRE9NIGluIHdoaWNoIHRoZSBub2RlIGJlbG9uZ3MsIHdoaWxlIHRoZQotICBsb3dlciAyNCBiaXRzIGFyZSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBub2RlIHdpdGhpbiB0aGUgRE9NOjwvcD4KLSAgICA8dGFibGU+Ci0gICAgICA8dHI+Ci0gICAgICAgIDx0ZD4zMS0yNDwvdGQ+Ci0gICAgICAgIDx0ZD4yMy0xNjwvdGQ+Ci0gICAgICAgIDx0ZD4xNi04PC90ZD4KLSAgICAgICAgPHRkPjctMDwvdGQ+Ci0gICAgICA8L3RyPgotICAgICAgPHRyPgotICAgICAgICA8dGQ+RE9NIGlkPC90ZD4KLSAgICAgICAgPHRkIGNvbHNwYW49IjMiPm5vZGUgaWQ8L3RkPgotICAgICAgPC90cj4KLSAgICA8L3RhYmxlPgotCi0gIDxwPlRoZSBET00gbXVsdGlwbGV4ZXIgaGFzIGFuIGFycmF5IG9mIERPTUFkYXB0ZXIgb2JqZWN0cy4gVGhlIHRvcG1vc3QgOAotICBiaXRzIG9mIHRoZSBpZGVudGlmaWVyIGlzIHVzZWQgdG8gZmluZCB0aGUgY29ycmVjdCBET00gZnJvbSB0aGUgYXJyYXkuIFRoZW4KLSAgdGhlIGxvd2VyIDI0IGJpdHMgYXJlIHVzZWQgaW4gY2FsbHMgdG8gbWV0aG9kcyBpbiB0aGUgRE9NQWRhcHRlciBvYmplY3Q6PC9wPgotCi08c291cmNlPgotICAgIHB1YmxpYyBpbnQgZ2V0UGFyZW50KGludCBub2RlKSB7Ci0JcmV0dXJuIF9hZGFwdGVyc1tub2RlPj4+MjRdLmdldFBhcmVudChub2RlICZhbXA7IDB4MDBmZmZmZmYpIHwgbm9kZSAmYW1wOyAweGZmMDAwMDAwOwotICAgIH0KLTwvc291cmNlPgotCi0gIDxwPk5vdGUgdGhhdCB0aGUgbm9kZSBpZGVudGlmaWVyIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGhhcyB0aGUgc2FtZSB1cHBlciA4Ci0gIGJpdHMgYXMgdGhlIGlucHV0IG5vZGUuIFRoaXMgaXMgd2h5IHdlIDxjb2RlPk9SPC9jb2RlPiB0aGUgcmVzdWx0IGZyb20KLSAgPGNvZGU+RE9NQWRhcHRlci5nZXRQYXJlbnQoKTwvY29kZT4gd2l0aCB0aGUgdG9wIDggYml0cyBvZiB0aGUgaW5wdXQgbm9kZS48L3A+Ci0KLSAgPC9zMj48YW5jaG9yIG5hbWU9ImJ1aWxkZXIiLz4KLSAgPHMyIHRpdGxlPSJUaGUgRE9NIGJ1aWxkZXIgLSBET01JbXBsJERPTUJ1aWxkZXIiPgotICA8dWw+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0ic3RhcnRlbGVtZW50Ij5zdGFydEVsZW1lbnQoKTwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9ImVuZGVsZW1lbnQiPmVuZEVsZW1lbnQoKTwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9InN0YXJ0cHJlZml4bWFwcGluZyI+c3RhcnRQcmVmaXhNYXBwaW5nKCk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJlbmRwcmVmaXhtYXBwaW5nIj5lbmRQcmVmaXhNYXBwaW5nKCk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJjaGFyYWN0ZXJzIj5jaGFyYWN0ZXJzKCk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJzdGFydGRvY3VtZW50Ij5zdGFydERvY3VtZW50KCk8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJlbmRkb2N1bWVudCI+ZW5kRG9jdW1lbnQoKTwvbGluaz48L2xpPgotICA8L3VsPgotCi0gIDxwPlRoZSBET00gYnVpbGRlciBpcyBhbiBpbm5lciBjbGFzcyBvZiB0aGUgRE9NIGltcGxlbWVudGF0aW9uLiBUaGUgYnVpbGRlcgotICBpbXBsZW1lbnRzIHRoZSBTQVgyIDxjb2RlPkNvbnRlbnRIYW5kbGVyPC9jb2RlPiBpbnRlcmZhY2UgYW5kIHBvcHVsYXRlcyB0aGUgRE9NCi0gIGJ5IHJlY2VpdmluZyBTQVgyIGV2ZW50cyBmcm9tIGEgU0FYMiBwYXJzZXIgKHByZXNlbnRseSB4ZXJjZXMpLiBBbiBpbnN0YW5jZQotICBvZiB0aGUgRE9NIGJ1aWxkZXIgY2xhc3MgY2FuIGJlIHJldHJpZXZlZCBmcm9tIDxjb2RlPkRPTUltcGwuZ2V0QnVpbGRlcigpPC9jb2RlPgotICBtZXRob2QsIGFuZCB0aGlzIGhhbmRsZXIgY2FuIGJlIHNldCBhcyBhbiBYTUxSZWFkZXIncyBjb250ZW50IGhhbmRsZXI6PC9wPgotCi08c291cmNlPgotICAgIGZpbmFsIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKLSAgICBmaW5hbCBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgICBmaW5hbCBYTUxSZWFkZXIgcmVhZGVyID0gcGFyc2VyLmdldFhNTFJlYWRlcigpOwotICAgIGZpbmFsIERPTUltcGwgZG9tID0gbmV3IERPTUltcGwoKTsKLSAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoZG9tLmdldEJ1aWxkZXIoKSk7Ci08L3NvdXJjZT4KLQotICA8cD5UaGUgRE9NIGJ1aWxkZXIgd2lsbCBzdGFydCB0byBwb3B1bGF0ZSB0aGUgRE9NIG9uY2UgdGhlIFhNTCBwYXJzZXIgc3RhcnRzCi0gIGdlbmVyYXRpbmcgU0FYMiBldmVudHM6PC9wPgotICA8YW5jaG9yIG5hbWU9InN0YXJ0ZWxlbWVudCIvPgotICA8czMgdGl0bGU9InN0YXJ0RWxlbWVudCgpIj4KLQotICA8cD5UaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGluIG9uZSBvZiB0d28gd2F5czsgZWl0aGVyIHdpdGggdGhlIGV4cGFuZGVkCi0gIFFOYW1lICh0aGUgZWxlbWVudCdzIHNlcGFyYXRlIHVyaSBhbmQgbG9jYWwgbmFtZSBhcmUgc3VwcGxpZWQpIG9yIGFzIGEKLSAgbm9ybWFsIFFOYW1lIChvbmUgU3RyaW5nIG9uIHRoZSBmb3JtYXQgcHJlZml4OmxvY2FsLW5hbWUpLiBUaGUgRE9NIHN0b3JlcwotICBlbGVtZW50cyBhcyBleHBhbmRlZCBRTmFtZXMgc28gaXQgbmVlZHMgdG8ga25vdyB0aGUgZWxlbWVudCdzIG5hbWVzcGFjZSBVUkkuCi0gIFNpbmNlIHRoZSBVUkkgaXMgbm90IHN1cHBsaWVkIHdpdGggdGhpcyBjYWxsLCB3ZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YKLSAgbmFtZXNwYWNlIHByZWZpeC91cmkgbWFwcGluZ3Mgd2hpbGUgd2UncmUgYnVpbGRpbmcgdGhlIERPTS4gU2VlIAotICA8Y29kZT48bGluayBhbmNob3I9InN0YXJ0cHJlZml4bWFwcGluZyI+c3RhcnRQcmVmaXhNYXBwaW5nKCk8L2xpbms+PC9jb2RlPiBiZWxvdyBmb3IgZGV0YWlscyBvbgotICBuYW1lc3BhY2UgaGFuZGxpbmcuPC9wPgotCi0gIDxwPlRoZSA8Y29kZT5zdGFydEVsZW1lbnQoKTwvY29kZT4gaW5zZXJ0cyB0aGUgZWxlbWVudCBhcyBhIGNoaWxkIG9mIHRoZSBjdXJyZW50Ci0gIHBhcmVudCBlbGVtZW50LCBjcmVhdGVzIGF0dHJpYnV0ZSBub2RlcyBmb3IgYWxsIGF0dHJpYnV0ZXMgaW4gdGhlIHN1cHBsaWVkCi0gICZxdW90Ozxjb2RlPkF0dHJpYnV0ZXM8L2NvZGU+JnF1b3Q7IGF0dHJpYnV0ZSBsaXN0IChieSBhIHNlcmllcyBvZiBjYWxscyB0bwotICA8Y29kZT5tYWtlQXR0cmlidXRlTm9kZSgpPC9jb2RlPiksIGFuZCBmaW5hbGx5IGNyZWF0ZXMgdGhlIGFjdHVhbCBlbGVtZW50IG5vZGUKLSAgKGJ5IGNhbGxpbmcgPGNvZGU+aW50ZXJuRWxlbWVudCgpPC9jb2RlPiwgd2hpY2ggaW5zZXJ0cyBhIG5ldyBlbnRyeSBpbiB0aGUKLSAgPGNvZGU+X3R5cGVbXTwvY29kZT4gYXJyYXkpLjwvcD4KLSAgPC9zMz48YW5jaG9yIG5hbWU9ImVuZGVsZW1lbnQiLz4KLSAgPHMzIHRpdGxlPSJlbmRFbGVtZW50KCkiPgotCi0gIDxwPlRoaXMgbWV0aG9kIGRvZXMgc29tZSBjbGVhbnVwIGFmdGVyIHRoZSA8Y29kZT5zdGFydEVsZW1lbnQoKTwvY29kZT4gbWV0aG9kLAotICBzdWNoIGFzIHJldmVyaW5nIDxjb2RlPnhtbDpzcGFjZTwvY29kZT4gc2V0dGluZ3MgYW5kIGxpbmtpbmcgdGhlIGVsZW1lbnQncwotICBjaGlsZCBub2Rlcy48L3A+Ci0gIDwvczM+PGFuY2hvciBuYW1lPSJzdGFydHByZWZpeG1hcHBpbmciLz4KLSAgPHMzIHRpdGxlPSJzdGFydFByZWZpeE1hcHBpbmcoKSI+Ci0KLSAgPHA+VGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciBlYWNoIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiB0aGUgc291cmNlCi0gIGRvY3VtZW50LiBUaGUgcGFyc2VyIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSB0aGUgcHJlZml4IGlzIHJlZmVyZW5jZWQKLSAgaW4gYSBRTmFtZSB0aGF0IGlzIHBhc3NlZCB0byB0aGUgPGNvZGU+c3RhcnRFbGVtZW50KCk8L2NvZGU+IGNhbGwuIE5hbWVzcGFjZQotICBwcmVmaXgvdXJpIG1hcHBpbmdzIGFyZSBzdG9yZWQgaW4gYSBIYXNodGFibGUgc3RydWN0dXJlLiBOYW1lc3BhY2UgcHJlZml4ZXMKLSAgYXJlIHVzZWQgYXMgdGhlIGtleXMgaW4gdGhlIEhhc2h0YWJsZSwgYW5kIGVhY2gga2V5IG1hcHMgdG8gYSBTdGFjayB0aGF0Ci0gIGNvbnRhaW5zIHRoZSB2YXJpb3VzIFVSSXMgdGhhdCB0aGUgcHJlZml4IG1hcHMgdG8uIFRoZSBVUkkgb24gdG9wIG9mIHRoZQotICBzdGFjayBpcyB0aGUgVVJJIHRoYXQgdGhlIHByZWZpeCBjdXJyZW50bHkgbWFwcyB0by48L3A+Ci0KLSAgCi0gICAgPHA+PGltZyBzcmM9Im5hbWVzcGFjZV9zdGFjay5naWYiIGFsdD0ibmFtZXNwYWNlX3N0YWNrLmdpZiIvPjwvcD4KLSAgICA8cD48cmVmPkZpZ3VyZSAyOiBOYW1lc3BhY2UgaGFuZGxpbmcgaW4gdGhlIERPTSBidWlsZGVyPC9yZWY+PC9wPgotCi0KLSAgPHA+RWFjaCBjYWxsIHRvIDxjb2RlPnN0YXJ0UHJlZml4TWFwcGluZygpPC9jb2RlPiByZXN1bHRzIGluIGEgbG9va3VwIGluIHRoZQotICBIYXNodGFibGUgKHVzaW5nIHRoZSBwcmVmaXgpLCBhbmQgYSA8Y29kZT5wdXNoKCk8L2NvZGU+IG9mIHRoZSBVUkkgb250byB0aGUKLSAgU3RhY2sgdGhhdCB0aGUgcHJlZml4IG1hcHMgdG8uPC9wPgotICA8L3MzPjxhbmNob3IgbmFtZT0iZW5kcHJlZml4bWFwcGluZyIvPgotICA8czMgdGl0bGU9ImVuZFByZWZpeE1hcHBpbmcoKSI+Ci0KLSAgPHA+QSBuYW1lc3BhY2UgcHJlZml4L3VyaSBtYXBwaW5nIGlzIGNsb3NlZCBieSBsb2NhdGluZyB0aGUgU3RhY2sgZm9yIHRoZQotICBwcmVmaXgsIGFuZCB0aGVuIDxjb2RlPnBvcCgpPC9jb2RlPidpbmcgdGhlIHRvcG1vc3QgVVJJIG9mZiB0aGlzIFN0YWNrLjwvcD4KLSAgPC9zMz48YW5jaG9yIG5hbWU9ImNoYXJhY3RlcnMiLz4KLSAgPHMzIHRpdGxlPSJjaGFyYWN0ZXJzKCkiPgotCi0gIDxwPlRleHQgbm9kZXMgYXJlIHN0b3JlZCBhcyBzaW1wbGUgY2hhcmFjdGVyIHNlcXVlbmNlcyBpbiB0aGUgY2hhcmFjdGVyIGFycmF5Ci0gIDxjb2RlPl90ZXh0W108L2NvZGU+LiBUaGUgc3RhcnQgYW5kIGxlbmdodCBvZiBhIG5vZGUncyB0ZXh0IGNhbiBiZSBkZXRlcm1pbmVkIGJ5Ci0gIHVzaW5nIHRoZSBub2RlIGluZGV4IHRvIGxvb2sgdXAgPGNvZGU+X29mZnNldE9yQ2hpbGRbXTwvY29kZT4gYW5kCi0gIDxjb2RlPl9sZW5ndGhPckF0dHJpYnV0ZVtdPC9jb2RlPi48L3A+Ci0KLSAgPHA+V2Ugd2FudCB0byByZS11c2UgY2hhcmFjdGVyIHNlcXVlbmNlcyBpZiB0d28gb3IgbW9yZSB0ZXh0IG5vZGVzIGhhdmUKLSAgaWRlbnRpY2FsIGNvbnRlbnQuIFRoaXMgY2FuIGJlIGFjaGlldmVkIGJ5IGhhdmluZyB0d28gZGlmZmVyZW50IHRleHQgbm9kZQotICBpbmRleGVzIG1hcCB0byB0aGUgc2FtZSBjaGFyYWN0ZXIgc2VxdWVuY2UuIFRoZSA8Y29kZT5tYXliZVJldXNlVGV4dCgpPC9jb2RlPgotICBtZXRob2QgaXMgYWx3YXlzIGNhbGxlZCBiZWZvcmUgYSBuZXcgY2hhcmFjdGVyIHN0cmluZyBpcyBzdG9yZWQgaW4gdGhlCi0gIDxjb2RlPl90ZXh0W108L2NvZGU+IGFycmF5LiBUaGlzIG1ldGhvZCB3aWxsIGxvY2F0ZSB0aGUgb2Zmc2V0IG9mIGFuIGV4aXN0aW5nCi0gIGluc3RhbmNlIG9mIGEgY2hhcmFjdGVyIHNlcXVlbmNlLjwvcD4KLSAgPC9zMz48YW5jaG9yIG5hbWU9InN0YXJ0ZG9jdW1lbnQiLz4KLSAgPHMzIHRpdGxlPSJzdGFydERvY3VtZW50KCkiPgotCi0gIDxwPlRoaXMgbWV0aG9kIGluaXRpYWxpc2VzIGEgYnVuY2ggb2YgZGF0YSBzdHJ1Y3R1cmVzIHRoYXQgYXJlIHVzZWQgYnkgdGhlCi0gIGJ1aWxkZXIuIEl0IGFsc28gcHVzaGVzIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBvbiB0aGUgbmFtZXNwYWNlIHN0YWNrIChzbyB0aGF0Ci0gIHRoZSAmcXVvdDsmcXVvdDsgcHJlZml4IG1hcHMgdG8gdGhlIDxjb2RlPm51bGw8L2NvZGU+IG5hbWVzcGFjZSkuPC9wPgotICA8L3MzPjxhbmNob3IgbmFtZT0iZW5kZG9jdW1lbnQiLz4KLSAgPHMzIHRpdGxlPSJlbmREb2N1bWVudCgpIj4KLQotICA8cD5UaGlzIG1ldGhvZCBidWlsZHMgdGhlIDxjb2RlPl9uYW1lc0FycmF5W108L2NvZGU+LCA8Y29kZT5fbmFtZXNwYWNlW108L2NvZGU+Ci0gIGFuZCA8Y29kZT5fbnNOYW1lc0FycmF5W108L2NvZGU+IHN0cnVjdHVyZXMgZnJvbSB0ZW1wb3JhcnkgZGF0YXN0cnVjdHVyZXMgdXNlZAotICBpbiB0aGUgRE9NIGJ1aWxkZXIuPC9wPgotCi0gICA8L3MzPgotIDwvczI+Ci08L3MxPiAgIApcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfbmFtZXNwYWNlLnhtbCBiL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfbmFtZXNwYWNlLnhtbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYTlhYjMyMy4uMDAwMDAwMAotLS0gYS94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbHRjX25hbWVzcGFjZS54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw2MDYgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCEtLSAKLSAqIFRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjEKLSAqCi0gKgotICogQ29weXJpZ2h0IChjKSAyMDAxIFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEFsbCByaWdodHMKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCi0gKgotICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgotICogICAgdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQotICogICAgZGlzdHJpYnV0aW9uLgotICoKLSAqIDMuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLAotICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KLSAqCi0gKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIiwKLSAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgotICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCi0gKgotICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAotICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKLSAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCi0gKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCi0gKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCi0gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCi0gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCi0gKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECi0gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKLSAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAotICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCi0gKiBTVUNIIERBTUFHRS4KLSAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gKgotICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKLSAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwotICogb3JpZ2luYWxseSBiYXNlZCBvbiBzb2Z0d2FyZSBjb3B5cmlnaHQgKGMpIDIwMDEsIFN1bgotICogTWljcm9zeXN0ZW1zLiwgaHR0cDovL3d3dy5zdW4uY29tLiAgRm9yIG1vcmUKLSAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQotICogPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgotIC0tPgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci0gIDxzMSB0aXRsZT0iWFNMVEMgYW5kIE5hbWVzcGFjZXMiPgotICA8dWw+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iZnVuY3Rpb25hbGl0eSI+RnVuY3Rpb25hbGl0eTwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9Im92ZXJ2aWV3Ij5OYW1lc3BhY2Ugb3ZlcnZpZXc8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJOU0EiPlRoZSBET00gJmFtcDsgbmFtZXNwYWNlczwvbGluaz48L2xpPiAgICAKLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJOU0IiPk5hbWVzcGFjZXMgaW4gdGhlIFhTTCBzdHlsZXNoZWV0PC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0iTlNDIj5OYW1lc3BhY2VzIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQ8L2xpbms+PC9saT4KLSAgPC91bD4KLSAgPGFuY2hvciBuYW1lPSJmdW5jdGlvbmFsaXR5Ii8+Ci0gIDxzMiB0aXRsZT0iRnVuY3Rpb25hbGl0eSI+Ci0KLSAgICA8cD5OYW1lc3BhY2VzIGFyZSB1c2VkIHdoZW4gYW4gWE1MIGRvY3VtZW50cyBoYXMgZWxlbWVudHMgaGF2ZSB0aGUgc2FtZQotICAgIG5hbWUsIGJ1dCBhcmUgZnJvbSBkaWZmZXJlbnQgY29udGV4dHMsIGFuZCB0aHVzIGhhdmUgZGlmZmVyZW50IG1lYW5pbmdzCi0gICAgYW5kIGludGVycHJldGF0aW9ucy4gRm9yIGluc3RhbmNlLCBhIDxjb2RlPiZsdDtUSVRMRSZndDs8L2NvZGU+IGVsZW1lbnQgY2FuCi0gICAgYmUgYSBIVE1MIHRpdGxlIGVsZW1lbnQgaW4gb25lIHBhcnQgb2YgdGhlIFhNTCBkb2N1bWVudCwgd2hpbGUgaXQgaW4gb3RoZXIKLSAgICBwYXJ0cyBvZiB0aGUgZG9jdW1lbnQgdGhlIDxjb2RlPiZsdDtUSVRMRSZndDs8L2NvZGU+IGVsZW1lbnQgaXMgdXNlZCBmb3IKLSAgICBlbmNhcHN1bGF0aW5nIHRoZSB0aXRsZSBvZiBhIHBsYXkgb3IgYSBib29rLiBUaGlzIHNvcnQgb2YgY29uZnVzaW9uIGlzCi0gICAgdmVyeSBjb21tb24gd2hlbiByZWFkaW5nIFhNTCBzb3VyY2UgZnJvbSBtdWx0aXBsZSBkb2N1bWVudHMsIGJ1dCBjYW4gYWxzbwotICAgIG9jY3VyIHdpdGhpbiBhIHNpbmdsZSBkb2N1bWVudC48L3A+Ci0KLSAgICA8cD5OYW1lc3BhY2VzIGhhdmUgdGhyZWUgdmVyeSBpbXBvcnRhbnQgcHJvcGVydGllczogYSBuYW1lLCBhIHByZWZpeCAoYW4KLSAgICBhbGlhcyBmb3IgaXRzIG5hbWUpIGFuZCBhIHNjb3BlLiBOYW1lc3BhY2VzIGFyZSBkZWNsYXJlZCBhcyBhdHRyaWJ1dGVzIG9mCi0gICAgYWxtb3N0IGFueSBub2RlIGluIGFuIFhNTCBkb2N1bWVudC4gVGhlIGRlY2xhcmF0aW9uIGxvb2tzIGxpa2UgdGhpczo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgJmx0O2VsZW1lbnQgeG1sbnM6cHJlZml4PSJodHRwOi8vc29tZS5zaXRlL3NwZWMiJmd0Oy4uLi4mbHQ7L2VsZW1lbnQmZ3Q7Ci08L3NvdXJjZT4KLQotICAgIDxwPlRoZSA8Y29kZT4ieG1sbnMiPC9jb2RlPiB0ZWxscyB0aGF0IHRoaXMgaXMgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24uIFRoZQotICAgIHNjb3BlIG9mIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgdGhlIGVsZW1lbnQgaW4gd2hpY2ggaXQgaXMgZGVmaW5lZAotICAgIGFuZCBhbGwgdGhlIGNoaWxkcmVuIG9mIHRoYXQgZWxlbWVudC5UaGUgcHJlZml4IGlzIHRoZSBsb2NhbCBhbGlhcyB3ZSB1c2UKLSAgICBmb3IgcmVmZXJlbmNpbmcgdGhlIG5hbWVzcGFjZSwgYW5kIHRoZSBVUkwgKGl0IGNhbiBiZSBhbnl0aGluZywgcmVhbGx5KSBpcwotICAgIHRoZSBuYW1lL2RlZmluaXRpb24gb2YgdGhlIG5hbWVzcGFjZS4gTm90ZSB0aGF0IGV2ZW4gdGhvdWdoIHRoZSBuYW1lc3BhY2UKLSAgICBkZWZpbml0aW9uIGlzIG5vcm1hbGx5IGFuIFVSTCwgaXQgZG9lcyBub3QgaGF2ZSB0byBwb2ludCB0byBhbnl0aGluZy4gSXQKLSAgICBpcyByZWNvbW1lbmRlZCB0aGF0IGl0IHBvaW50cyB0byBhIHBhZ2UgdGhhdCBkZXNjcmliZXMgdGhlIGVsZW1lbnRzIGluIHRoZQotICAgIG5hbWVzcGFjZSwgYnV0IGl0IGRvZXMgbm90IGhhdmUgdG8uIFRoZSBwcmVmaXggY2FuIGJlIGp1c3QgYWJvdXQgYW55dGhpbmcKLSAgICAtIG9yIG5vdGhpbmcgKGluIHdoaWNoIGNhc2UgaXQgaXMgdGhlIGRlZmF1bHQgbmFtZXNwYWNlKS4gQW55IHByZWZpeCwKLSAgICBpbmNsdWRpbmcgdGhlIGVtcHR5IHByZWZpeCBmb3IgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLCBjYW4gYmUgcmVkZWZpbmVkIHRvCi0gICAgcmVmZXIgdG8gYSBkaWZmZXJlbnQgbmFtZXNwYWNlIGF0IGFueSB0aW1lIGluIGFuIFhNTCBkb2N1bWVudC4gVGhpcyBpcwotICAgIG1vcmUgbGlrZWx5IHRvIGhhcHBlbiB0byB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgdGhhbiBhbnkgb3RoZXIgcHJlZml4LiBIZXJlCi0gICAgaXMgYW4gZXhhbXBsZSBvZiB0aGlzOjwvcD4KLQotICAgIDxhbmNob3IgbmFtZT0ieG1sX3NhbXBsZV8xIi8+Ci08c291cmNlPgotICAgICZsdDs/eG1sIHZlcnNpb249IjEuMCI/Jmd0OwotICAgIAotICAgICZsdDtlbXBsb3llZXMgeG1sbnM6cG9zdGFsPSJodHRwOi8vcG9zdGFsLmllL3NwZWMtMS4wIgotICAgICAgICAgICAgICAgeG1sbnM6ZW1haWw9Imh0dHA6Ly93d3cudzNjLm9yZy9zb21lLXNwZWMtMy4yIiZndDsKLSAgICAgICAgJmx0O2VtcGxveWVlJmd0OwotICAgICAgICAgICAgJmx0O25hbWUmZ3Q7Qm9iIFdvcmtlciZsdDsvbmFtZSZndDsKLSAgICAgICAgICAgICZsdDtwb3N0YWw6YWRkcmVzcyZndDsKLSAgICAgICAgICAgICAgICAmbHQ7cG9zdGFsOnN0cmVldCZndDtOYXNzYXUgU3RyZWV0Jmx0Oy9wb3N0YWw6c3RyZWV0Jmd0OwotICAgICAgICAgICAgICAgICZsdDtwb3N0YWw6Y2l0eSZndDtEdWJsaW4gMyZsdDsvcG9zdGFsOmNpdHkmZ3Q7Ci0gICAgICAgICAgICAgICAgJmx0O3Bvc3RhbDpjb3VudHJ5Jmd0O0lyZWxhbmQmbHQ7L3Bvc3RhbDpjb3VudHJ5Jmd0OwotICAgICAgICAgICAgJmx0Oy9wb3N0YWw6YWRkcmVzcyZndDsKLSAgICAgICAgICAgICZsdDtlbWFpbDphZGRyZXNzJmd0O2JvYi53b3JrZXJAaGlzam9iLmllJmx0Oy9lbWFpbDphZGRyZXNzJmd0OwotICAgICAgICAmbHQ7L2VtcGxveWVlJmd0OwotICAgICZsdDsvZW1wbG95ZWVzJmd0OwotPC9zb3VyY2U+Ci0KLSAgICA8cD5UaGlzIHNob3J0IGRvY3VtZW50IGhhcyB0d28gbmFtZXNwYWNlIGRlY2xhcmF0aW9ucywgb25lIHdpdGggdGhlIHByZWZpeAotICAgIDxjb2RlPiJwb3N0YWwiPC9jb2RlPiBhbmQgYW5vdGhlciB3aXRoIHRoZSBwcmVmaXggPGNvZGU+ImVtYWlsIjwvY29kZT4uIFRoZQotICAgIHByZWZpeGVzIGFyZSB1c2VkIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gZWxlbWVudHMgZm9yIGUtbWFpbCBhZGRyZXNzZXMgYW5kCi0gICAgcmVndWxhciBwb3N0YWwgYWRkcmVzc2VzLiBJbiBhZGRpdGlvbiB0byB0aGVzZSB0d28gbmFtZXNwYWNlcyB0aGVyZSBpcyBhbHNvCi0gICAgYW4gaW5pdGlhbCAodW5uYW1lZCkgZGVmYXVsdCBuYW1lc3BhY2UgYmVpbmcgdXNlZCBmb3IgdGhlCi0gICAgPGNvZGU+Jmx0O25hbWUmZ3Q7PC9jb2RlPiBhbmQgPGNvZGU+Jmx0O2VtcGxveWVlJmd0OzwvY29kZT4gdGFncy4gVGhlIHNjb3BlIG9mIHRoZQotICAgIGRlZmF1bHQgbmFtZXNwYWNlIGlzIGluIHRoaXMgY2FzZSB0aGUgd2hvbGUgZG9jdW1lbnQsIHdoaWxlIHRoZSBzY29wZSBvZgotICAgIHRoZSBvdGhlciB0d28gZGVjbGFyZWQgbmFtZXNwYWNlcyBpcyB0aGUgPGNvZGU+Jmx0O2VtcGxveWVlcyZndDs8L2NvZGU+Ci0gICAgZWxlbWVudCBhbmQgaXRzIGNoaWxkcmVuLjwvcD4KLQotICAgIDxwPkJ5IGNoYW5naW5nIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSB3ZSBjb3VsZCBoYXZlIG1hZGUgdGhlIGRvY3VtZW50IGEKLSAgICBsaXR0bGUgYml0IHNpbXBsZXIgYW5kIG1vcmUgcmVhZGFibGU6PC9wPgotCi0gICAgPGFuY2hvciBuYW1lPSJ4bWxfc2FtcGxlXzIiLz4KLTxzb3VyY2U+Ci0gICAgJmx0Oz94bWwgdmVyc2lvbj0iMS4wIj8mZ3Q7Ci0gICAgCi0gICAgJmx0O2VtcGxveWVlcyB4bWxuczplbWFpbD0iaHR0cDovL3d3dy53M2Mub3JnL3NvbWUtc3BlYy0zLjIiJmd0OwotICAgICAgICAmbHQ7ZW1wbG95ZWUmZ3Q7Ci0gICAgICAgICAgICAmbHQ7bmFtZSZndDtCb2IgV29ya2VyJmx0Oy9uYW1lJmd0OwotICAgICAgICAgICAgJmx0O2FkZHJlc3MgeG1sbnM9Imh0dHA6Ly9wb3N0YWwuaWUvc3BlYy0xLjAiJmd0OwotICAgICAgICAgICAgICAgICZsdDtzdHJlZXQmZ3Q7TmFzc2F1IFN0cmVldCZsdDsvc3RyZWV0Jmd0OwotICAgICAgICAgICAgICAgICZsdDtjaXR5Jmd0O0R1YmxpbiAzJmx0Oy9jaXR5Jmd0OwotICAgICAgICAgICAgICAgICZsdDtjb3VudHJ5Jmd0O0lyZWxhbmQmbHQ7L2NvdW50cnkmZ3Q7Ci0gICAgICAgICAgICAmbHQ7L2FkZHJlc3MmZ3Q7Ci0gICAgICAgICAgICAmbHQ7ZW1haWw6YWRkcmVzcyZndDtib2Iud29ya2VyQGhpc2pvYi5pZSZsdDsvZW1haWw6YWRkcmVzcyZndDsKLSAgICAgICAgJmx0Oy9lbXBsb3llZSZndDsKLSAgICAmbHQ7L2VtcGxveWVlcyZndDsKLTwvc291cmNlPgotCi0gICAgPHA+VGhlIGRlZmF1bHQgbmFtZXNwYWNlIGlzIHJlZGVmaW5lZCBmb3IgdGhlIDxjb2RlPiZsdDthZGRyZXNzJmd0OzwvY29kZT4gbm9kZQotICAgIGFuZCBpdHMgY2hpbGRyZW4sIHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8gc3BlY2lmeSB0aGUgc3RyZWV0IGFzCi0gICAgPGNvZGU+Jmx0O3Bvc3RhbDpzdHJlZXQmZ3Q7PC9jb2RlPiAtIGp1c3QgcGxhaW4gPGNvZGU+Jmx0O3N0cmVldCZndDs8L2NvZGU+IGlzCi0gICAgc3VmZmljaWVudC4gTm90ZSB0aGF0IHRoaXMgYWxzbyBhcHBsaWVzIHRvIHRoZSA8Y29kZT4mbHQ7YWRkcmVzcyZndDs8L2NvZGU+Ci0gICAgd2hlcmUgdGhlIG5hbWVzcGFjZSBpcyBmaXJzdCBkZWZpbmVkLiBUaGlzIGlzIGluIGVmZmVjdCBhIHJlZGVmaW5pdGlvbiBvZgotICAgIHRoZSBkZWZhdWx0IG5hbWVzcGFjZS48L3A+Ci0gIDwvczI+PGFuY2hvciBuYW1lPSJvdmVydmlldyIvPgotICA8czIgdGl0bGU9Ik5hbWVzcGFjZSBvdmVydmlldyI+Ci0KLSAgICA8cD5OYW1lc3BhY2VzIHdpbGwgaGF2ZSB0byBiZSBoYW5kbGVkIGluIHRocmVlIHNlcGFyYXRlIHBhcnRzIG9mIHRoZSBYU0xUCi0gICAgY29tcGlsZXI6PC9wPgotCi0gICAgPGFuY2hvciBuYW1lPSJhbGxfbmFtZXNwYWNlcyIvPgotICAgICAgPHA+PGltZyBzcmM9ImFsbF9uYW1lc3BhY2VzLmdpZiIgYWx0PSJhbGxfbmFtZXNwYWNlcy5naWYiLz48L3A+Ci0gICAgICA8cD48cmVmPkZpZ3VyZSAxOiBOYW1lc3BhY2UgaGFuZGxlcnMgaW4gdGhlIFhTTFRDPC9yZWY+PC9wPgotCi0gICAgPHA+VGhlIG1vc3Qgb2J2aW91cyBpcyB0aGUgbmFtZXNwYWNlcyBpbiB0aGUgc291cmNlIFhNTCBkb2N1bWVudAotICAgIChtYXJrZWQgPGxpbmsgYW5jaG9yPSJOU0EiPiJOUyBBIjwvbGluaz4gaW4gZmlndXJlIDEpLiBUaGVzZSBuYW1lc3BhY2VzIHdpbGwgYmUKLSAgICBoYW5kbGVkIGJ5IG91ciBET00gaW1wbGVtZW50YXRpb24gY2xhc3MuIFRoZSBzb3VyY2UgWFNMIHN0eWxlc2hlZXQgYWxzbwotICAgIGhhcyBpdHMgb3duIHNldCBvZiBuYW1lc3BhY2VzICg8bGluayBpZHJlZj0iTlNCIj4iTlMgQiI8L2xpbms+KSAtIG9uZSBvZiB3aGljaAotICAgIGlzIHRoZSBYU0wgbmFtZXNwYWNlLiBUaGVzZSBuYW1lc3BhY2VzIHdpbGwgYmUgaGFuZGxlZCBhdCBydW4tdGltZSBhbmQKLSAgICB3aGF0ZXZlciBpbmZvcm1hdGlvbiB0aGF0IGlzIG5lZWRlZCB0byBwcm9jZXNzIHRoZXJlIHNob3VsZCBiZSBjb21waWxlZAotICAgIGludG8gdGhlIHRyYW5zbGV0LiBUaGVyZSBpcyBhbHNvIGEgc2V0IG9mIG5hbWVzcGFjZXMgdGhhdCB3aWxsIGJlIHVzZWQgaW4KLSAgICB0aGUgcmVzdWx0aW5nIGRvY3VtZW50ICg8bGluayBpZHJlZj0iTlNDIj4iTlMgQyI8L2xpbms+KS4gVGhpcyBpcyBhbgotICAgIGludGVyc2VjdGlvbiBvZiB0aGUgZmlyc3QgdHdvLiBUaGUgb3V0cHV0IGRvY3VtZW50IHNob3VsZCBub3QgY29udGFpbiBhbnkKLSAgICBtb3JlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgdGhhbiBuZWNlc3NhcnkuPC9wPgotCi0gICAgPC9zMj48YW5jaG9yIG5hbWU9Ik5TQSIvPgotICAgIDxzMiB0aXRsZT0iVGhlIERPTSAmYW1wOyBuYW1lc3BhY2VzIj4KLSAgICA8dWw+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJkb20tbmFtZXNwYWNlIj5ET00gbm9kZSB0eXBlcyBhbmQgbmFtZXNwYWNlIHR5cGVzPC9saW5rPjwvbGk+Ci0gICAgICA8bGk+PGxpbmsgYW5jaG9yPSJhc3NpZ24iPkFzc2lnbmluZyBuYW1lc3BhY2UgdHlwZXMgdG8gRE9NIG5vZGVzPC9saW5rPjwvbGk+ICAgICAgICAgICAgICAgIAotICAgIDwvdWw+Ci0gICAgPGFuY2hvciBuYW1lPSJkb20tbmFtZXNwYWNlIi8+Ci0gICAgPHMzIHRpdGxlPSJET00gbm9kZSB0eXBlcyBhbmQgbmFtZXNwYWNlIHR5cGVzIj4KLQotICAgIDxwPlJlZmVyIHRvIHRoZSBYU0xUQyA8bGluayBpZHJlZj0ieHNsdGNfcnVudGltZSI+cnVudGltZQotICAgIGVudmlyb25tZW50IGRlc2lnbjwvbGluaz4gZG9jdW1lbnQgZm9yIGEgZGVzY3JpcHRpb24gb2Ygbm9kZSB0eXBlcyBiZWZvcmUKLSAgICBwcm9jZWVkaW5nLiBJbiBzaG9ydCwgZWFjaCBub2RlIGluIHRoZSBvdXIgRE9NIGltcGxlbWVudGF0aW9uIGlzCi0gICAgcmVwcmVzZW50ZWQgYnkgYSBzaW1wbGUgaW50ZWdlci4gQnkgdXNpbmcgdGhpcyBpbnRlZ2VyIGFzIGFuIGluZGV4IGludG8gYW4KLSAgICBhcnJheSBjYWxsZWQgPGNvZGU+X3R5cGVbXTwvY29kZT4gd2UgY2FuIGZpbmQgdGhlIHR5cGUgb2YgdGhlIG5vZGUuPC9wPgotCi0gICAgPHA+VGhlIHR5cGUgb2YgdGhlIG5vZGUgaXMgYW4gaW50ZWdlciByZXByZXNlbnRpbmcgdGhlIHR5cGUgb2YgZWxlbWVudCB0aGUKLSAgICBub2RlIGlzLiBBbGwgZWxlbWVudHMgPGNvZGU+Jmx0O2JvYiZndDs8L2NvZGU+IHdpbGwgYmUgZ2l2ZW4gdGhlIHNhbWUgdHlwZSwKLSAgICBhbGwgdGV4dCBub2RlcyB3aWxsIGJlIGdpdmVuIHRoZSBzYW1lIHR5cGUsIGFuZCBzbyBvbi4gQnkgdXNpbmcgdGhlIG5vZGUKLSAgICB0eXBlIGFzIGFuIGluZGV4IGFuIGFycmF5IGNhbGxlZCA8Y29kZT5fbmFtZXNBcnJheVtdPC9jb2RlPiB3ZSBjYW4gZmluZCB0aGUKLSAgICBuYW1lIG9mIHRoZSBlbGVtZW50IHR5cGUgLSBpbiB0aGlzIGNhc2UgImJvYiIuIFRoaXMgY29kZSBmcmFnbWVudCBzaG93cwotICAgIGhvdyB5b3UgY2FuLCB3aXRoIG91ciBjdXJyZW50IGltcGxlbWVudGF0aW9uLCBmaW5kIHRoZSBuYW1lIG9mIGEgbm9kZTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgaW50ICAgIG5vZGUgPSBpdGVyYXRvci5nZXROZXh0KCk7ICAvLyBnZXQgbmV4dCBub2RlCi0gICAgaW50ICAgIHR5cGUgPSBfdHlwZVtub2RlXTsgICAgICAgICAvLyBnZXQgbm9kZSB0eXBlCi0gICAgU3RyaW5nIG5hbWUgPSBfbmFtZXNBcnJheVt0eXBlXTsgICAvLyBnZXQgbm9kZSBuYW1lCi08L3NvdXJjZT4KLQotICAgIDxwPldlIHdhbnQgdG8ga2VlcCB0aGUgb25lLXR5cGUtcGVyLW5vZGUgYXJyYW5nZW1lbnQsIHNpbmNlIHRoYXQgbGV0cyB1cwotICAgIHByb2R1Y2UgZmFpcmx5IGVmZmljaWVudCBjb2RlLiBPbmUgdHlwZSBpbiB0aGUgRE9NIG1hcHMgdG8gb25lIHR5cGUgaW4KLSAgICB0aGUgY29tcGlsZWQgdHJhbnNsZXQuIFdoYXQgd2UgY291bGQgZG8gdG8gcmVwcmVzZW50IHRoZSBuYW1lc3BhY2UgZm9yCi0gICAgZWFjaCBub2RlIGluIHRoZSBET00gaXMgdG8gYWRkIGEgPGNvZGU+X25hbWVzcGFjZVR5cGVbXTwvY29kZT4gYXJyYXkgdGhhdCBob2xkcwotICAgIG5hbWVzcGFjZSB0eXBlcy4gRWFjaCBub2RlIHR5cGUgbWFwcyB0byBhIG5hbWVzcGFjZSB0eXBlLCBhbmQgZWFjaAotICAgIG5hbWVzcGFjZSB0eXBlIG1hcHMgdG8gYSBuYW1lc3BhY2UgbmFtZSAoYW5kIGEgcHJlZml4IHdpdGggYSBsaW1pdGVkCi0gICAgc2NvcGUpOjwvcD4KLQotICAgIDxhbmNob3IgbmFtZT0idHlwZV9tYXBwaW5ncyIvPgotICAgIDxwPjxpbWcgc3JjPSJ0eXBlX21hcHBpbmdzLmdpZiIgYWx0PSJ0eXBlX21hcHBpbmdzLmdpZiIvPjwvcD4KLSAgICAgIDxwPjxyZWY+RmlndXJlIDI6IE1hcHBpbmcgYmV0d2VlbiBub2RlIHR5cGVzL25hbWVzLCBuYW1lc3BhY2UgdHlwZXMvbmFtZXM8L3JlZj48L3A+Ci0KLSAgICA8cD5UaGlzIGNvZGUgZnJhZ21lbnQgc2hvd3MgaG93IHdlIGNvdWxkIGdldCB0aGUgbmFtZXNwYWNlIG5hbWUgZm9yIGEgbm9kZTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgaW50ICAgIG5vZGUgICAgICA9IGl0ZXJhdG9yLmdldE5leHQoKTsgICAgLy8gZ2V0IG5leHQgbm9kZQotICAgIGludCAgICB0eXBlICAgICAgPSBfdHlwZVtub2RlXTsgICAgICAgICAgIC8vIGdldCBub2RlIHR5cGUKLSAgICBpbnQgICAgbnN0eXBlICAgID0gX25hbWVzcGFjZVt0eXBlXTsgICAgICAvLyBnZXQgbmFtZXNwYWNlIHR5cGUKLSAgICBTdHJpbmcgbmFtZSAgICAgID0gX25hbWVzQXJyYXlbdHlwZV07ICAgICAvLyBnZXQgbm9kZSBlbGVtZW50IG5hbWUKLSAgICBTdHJpbmcgbmFtZXNwYWNlID0gX25zTmFtZXNBcnJheVtuc3R5cGVdOyAvLyBnZXQgbm9kZSBuYW1lc3BhY2UgbmFtZQotPC9zb3VyY2U+Ci0KLSAgICA8cD5Ob3RlIHRoYXQgbmFtZXNwYWNlIHByZWZpeGVzIGFyZSBub3QgaW5jbHVkZWQgaGVyZS4gTmFtZXNwYWNlIHByZWZpeGVzCi0gICAgYXJlIGxvY2FsIHRvIHRoZSBYTUwgZG9jdW1lbnQgYW5kIHdpbGwgYmUgZXhwYW5kZWQgdG8gdGhlIGZ1bGwgbmFtZXNwYWNlCi0gICAgbmFtZXMgd2hlbiB0aGUgbm9kZXMgYXJlIHB1dCBpbnRvIHRoZSBET00uIFRoaXMsIGhvd2V2ZXIsIGlzIG5vdCBhIHRyaXZpYWwKLSAgICBtYXR0ZXIuPC9wPgotICAgIDwvczM+PGFuY2hvciBuYW1lPSJhc3NpZ24iLz4KLSAgICA8czMgdGl0bGU9IkFzc2lnbmluZyBuYW1lc3BhY2UgdHlwZXMgdG8gRE9NIG5vZGVzIj4KLQotICAgIDxwPldlIGNhbm5vdCBzaW1wbHkgaGF2ZSBhIHNpbmdsZSBuYW1lc3BhY2UgcHJlZml4IGFycmF5IHNpbWlsYXIgdG8gdGhlCi0gICAgPGNvZGU+X25hbWVzcGFjZUFycmF5W108L2NvZGU+IGFycmF5IGZvciBtYXBwaW5nIGEgbmFtZXNwYWNlIHR5cGUgdG8gYSBzaW5nbGUKLSAgICBwcmVmaXguIFRoaXMgYmVjYXVzZSBwcmVmaXhlcyBjYW4gcmVmZXIgdG8gZGlmZmVyZW50IG5hbWVzcGFjZXMgZGVwZW5kaW5nCi0gICAgb24gd2hlcmUgaW4gdGhlIGRvY3VtZW50IHRoZSBwcmVmaXhlcyBhcmUgYmVpbmcgdXNlZC4gSW4gb3VyIGxhc3QgZXhhbXBsZSdzCi0gICAgPGxpbmsgaWRyZWY9InhtbF9zYW1wbGVfMiI+WE1MIGZyYWdtZW50PC9saW5rPiB0aGUgZW1wdHkgcHJlZml4IDxjb2RlPiIiPC9jb2RlPgotICAgIGluaXRpYWxseSByZWZlcnJlZCB0byB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgKHRoZSBvbmUgd2l0aCBubyBuYW1lIC0ganVzdAotICAgIGxpa2UgYSBDbGludCBFYXN0d29vZCBjaGFyYWN0ZXIpLiBMYXRlciBvbiBpbiB0aGUgZG9jdW1lbnQgdGhlIGVtcHR5Ci0gICAgcHJlZml4IGlzIGNoYW5nZWQgdG8gcmVmZXIgdG8gYSBuYW1lc3BhY2UgY2FsbGVkIAotICAgIDxjb2RlPiJodHRwOi8vcG9zdGFsLmllL3NwZWMtMS4wIjwvY29kZT4uPC9wPgotCi0gICAgPHA+TmFtZXNwYWNlIHByZWZpeGVzIGFyZSBvbmx5IHJlbGV2YW50IGF0IHRoZSB0aW1lIHdoZW4gdGhlIFhNTCBkb2N1bWVudAotICAgIGlzIHBhcnNlZCBhbmQgdGhlIERPTSBpcyBidWlsdC4gT25jZSB3ZSBoYXZlIHRoZSBET00gY29tcGxldGVkIHdlIG9ubHkgbmVlZAotICAgIGEgdGFibGUgdGhhdCBtYXBzIGVhY2ggbm9kZSB0eXBlIHRvIGEgbmFtZXNwYWNlIHR5cGUsIGFuZCBhbm90aGVyIGFycmF5IG9mCi0gICAgYWxsIHRoZSBuYW1lcyBvZiB0aGUgZGlmZmVyZW50IG5hbWVzcGFjZXMuIFNvIHdoYXQgd2Ugd2FudCB0byBlbmQgdXAgd2l0aAotICAgIGlzIHNvbWV0aGluZyBsaWtlIHRoaXM6PC9wPgotCi0gICAgIDxwPjxpbWcgc3JjPSJkb21fbmFtZXNwYWNlMS5naWYiIGFsdD0iZG9tX25hbWVzcGFjZTEuZ2lmIi8+PC9wPgotICAgICA8cD48cmVmPkZpZ3VyZSAzOiBFYWNoIG5hbWVzcGFjZSByZWZlcmVuY2VzIGluIHRoZSBET00gZ2V0cyBvbmUgZW50cnk8L3JlZj48L3A+Ci0KLSAgICA8cD5UaGUgbmFtZXNwYWNlIHRhYmxlIGhhcyBvbmUgZW50cnkgZm9yIGVhY2ggbmFtZXNwYWNlLCBub21hdHRlciBob3cgbWFueQotICAgIHByZWZpeGVzIHdlcmUgdXNlZCBybyByZWZlcmVuY2UgdGhpcyBuYW1lc3BhY2UgaW4gdGhlIERPTS4gVG8gYnVpbGQgdGhpcwotICAgIGFycmF5IHdlIG5lZWQgYSB0ZW1wb3JhcnkgZGF0YSBzdHJ1Y3R1cmUgdXNlZCBieSB0aGUgRE9NIGJ1aWxkZXIuIFRoaXMKLSAgICBzdHJ1Y3R1cmUgaXMgYSBoYXNodGFibGUgLSB3aGVyZSB0aGUgdmFyaW91cyBwcmVmaXhlcyBhcmUgdXNlZCBmb3IgdGhlCi0gICAgaGFzaCB2YWx1ZXMuIFRoZSBjb250ZW50cyBvZiBlYWNoIGVudHJ5IGluIHRoZSB0YWJsZSB3aWxsIGJlIGEgc21hbGwgc3RhY2sKLSAgICB3aGVyZSBwcmV2aW91cyBtZWFuaW5ncyBvZiBlYWNoIHByZWZpeCB3aWxsIGJlIHN0b3JlZDo8L3A+Ci0KLSAgICAgPHA+PGltZyBzcmM9ImRvbV9uYW1lc3BhY2UyLmdpZiIgYWx0PSJkb21fbmFtZXNwYWNlMi5naWYiLz48L3A+Ci0gICAgIDxwPjxyZWY+RmlndXJlIDQ6IFRlbXBvcmFyeSBkYXRhIHN0cnVjdHVyZSB1c2VkIGJ5IHRoZSBET00gYnVpbGRlcjwvcmVmPjwvcD4KLQotICAgIDxwPldoZW4gdGhlIGZpcnN0IG5vZGUgaXMgZW5jb3VudGVyZWQgd2UgZGVmaW5lIGEgbmV3IG5hbWVzcGFjZQotICAgIDxjb2RlPiJmb28iPC9jb2RlPiBhbmQgYXNzaWduIHRoaXMgbmFtZXNwYWNlIHR5cGUvaW5kZXggMSAodGhlIGRlZmF1bHQgCi0gICAgbmFtZXNwYWNlIDxjb2RlPiIiPC9jb2RlPiBoYXMgaW5kZXggMCkuIEF0IHRoZSBzYW1lIHRpbWUgd2UgdXNlIHRoZSBwcmVmaXgKLSAgICA8Y29kZT4iQSI8L2NvZGU+IGZvciBhIGxvb2t1cCBpbiB0aGUgaGFzaHRhYmxlLiBUaGlzIGdpdmVzIHVzCi0gICAgYW4gaW50ZWdlciBzdGFjayB1c2VkIGZvciB0aGUgcHJlZml4IDxjb2RlPiJBIjwvY29kZT4uIFdlIHB1c2ggdGhlIG5hbWVzcGFjZQotICAgIHR5cGUgMSBvbiB0aGlzIHN0YWNrLiBGcm9tIG5vdyBvbiwgdW50aWwgPGNvZGU+IkEiPC9jb2RlPiBpcyBwb3AnZWQgb2ZmIHRoaXMKLSAgICBzdGFjaywgdGhlIHByZWZpeCA8Y29kZT4iQSI8L2NvZGU+IHdpbGwgbWFwIHRvIG5hbWVzcGFjZSB0eXBlIDEsIHdoaWNoCi0gICAgcmVwcmVzZW50cyB0aGUgbmFtZXNwYWNlIFVSSSA8Y29kZT4iZm9vIjwvY29kZT4uPC9wPgotCi0gICAgPHA+V2UgdGhlbiBlbmNvdW50ZXIgdGhlIG5leHQgbm9kZSB3aXRoIGEgbmV3IG5hbWVzcGFjZSBkZWZpbml0aW9uIHdpdGgKLSAgICB0aGUgc2FtZSBuYW1lc3BhY2UgcHJlZml4LCB3ZSBjcmVhdGUgYSBuZXcgbmFtZXNwYWNlIDxjb2RlPiJiYXIiPC9jb2RlPiBhbmQKLSAgICB3ZSBwdXQgdGhhdCBpbiB0aGUgbmFtZXNwYWNlIHRhYmxlIHVuZGVyIHR5cGUgMi4gQWdhaW4gd2UgdXNlIHRoZSBwcmVmaXgKLSAgICA8Y29kZT4iQSI8L2NvZGU+IGFzIGFuIGVudHJ5IGludG8gdGhlIG5hbWVzcGFjZSBwcmVmaXggdGFibGUgYW5kIHdlIGdldCB0aGUKLSAgICBzYW1lIGludGVnZXIgc3RhY2suIFdlIG5vdyBwdXNoIG5hbWVzcGFjZSB0eXBlIDIgb24gdGhlIHN0YWNrLCBzbyB0aGF0Ci0gICAgbmFtZXNwYWNlIHByZWZpeCA8Y29kZT4iQSI8L2NvZGU+IG1hcHMgdG8gbmFtZXNwYWNlIFVSSSA8Y29kZT4iYmFyIjwvY29kZT4uIFdoZW4KLSAgICB3ZSBoYXZlIHRyYXZlcnNlZCB0aGlzIG5vZGUncyBjaGlsZHJlbiB3ZSBuZWVkIHRvIHBvcCB0aGUgaW50ZWdlciBvZmYgdGhlCi0gICAgc3RhY2ssIHNvIHdoZW4gd2UncmUgYmFjayBhdCB0aGUgZmlyc3Qgbm9kZSB0aGUgcHJlZml4IDxjb2RlPiJBIjwvY29kZT4gYWdhaW4KLSAgICB3aWxsIHBvaW50IHRvIG5hbWVzcGFjZSB0eXBlIDAsIHdoaWNoIG1hcHMgdG8gPGNvZGU+ImZvbyI8L2NvZGU+LiBUbyBrZWVwCi0gICAgdHJhY2sgb2Ygd2hhdCBub2RlcyBoYWQgd2hhdCBuYW1lc3BhY2UgZGVjbGFyYXRpb25zLCB3ZSB1c2UgYSBuYW1lc3BhY2UKLSAgICBkZWNsYXJhdGlvbiBzdGFjazo8L3A+Ci0KLSAgICA8cD48aW1nIHNyYz0iZG9tX25hbWVzcGFjZTMuZ2lmIiBhbHQ9ImRvbV9uYW1lc3BhY2UzLmdpZiIvPjwvcD4KLSAgICAgPHA+PHJlZj5GaWd1cmUgNTogTmFtZXNwYWNlIGRlY2xhcmF0aW9uIHN0YWNrPC9yZWY+PC9wPgotICAgICAKLSAgICA8cD5FdmVyeSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgcHVzaGVkIG9uIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24KLSAgICBzdGFjay4gVGhpcyBzdGFjayBob2xkcyB0aGUgbm9kZSBpbmRleCBmb3Igd2hlcmUgdGhlIG5hbWVzcGFjZSB3YXMKLSAgICBkZWNsYXJlZCwgYW5kIGEgcmVmZXJlbmNlIHRvIHRoZSBwcmVmaXggc3RhY2sgZm9yIHRoaXMgZGVjbGFyYXRpb24uCi0gICAgVGhlIDxjb2RlPmVuZEVsZW1lbnQoKTwvY29kZT4gbWV0aG9kIG9mIHRoZSBET01CdWlsZGVyIGNsYXNzIHdpbGwgbmVlZCB0bwotICAgIHJlbW92ZSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gZm9yIHRoZSBub2RlIHRoYXQgaXMgY2xvc2VkLiBUaGlzIGlzIGRvbmUKLSAgICBieSBmaXJzdCBjaGVja2luZyB0aGUgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHN0YWNrIGZvciBhbnkgbmFtZXNwYWNlcwotICAgIGRlY2xhcmVkIGJ5IHRoaXMgbm9kZS4gSWYgYW55IGRlY2xhcmF0aW9ucyBhcmUgZm91bmQgdGhlc2UgYXJlIHVuLWRlY2xhcmVkCi0gICAgYnkgcG9waW5nIHRoZSBuYW1lc3BhY2UgcHJlZml4ZXMgb2ZmIHRoZSByZXNwZWN0aXZlIHByZWZpeCBzdGFjayhzKSwgYW5kCi0gICAgdGhlbiBwb3BpbmcgdGhlIGVudHJ5L2VudHJpZXMgZm9yIHRoaXMgbm9kZSBvZmYgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgotICAgIHN0YWNrLjwvcD4KLQotICAgIDxwPlRoZSA8Y29kZT5lbmREb2N1bWVudCgpPC9jb2RlPiBtZXRob2Qgd2lsbCBidWlsZCBhbiBhcnJheSB0aGF0IGNvbnRhaW5zCi0gICAgYWxsIG5hbWVzcGFjZXMgdXNlZCBpbiB0aGUgc291cmNlIFhNTCBkb2N1bWVudCAtIDxjb2RlPl9uc05hbWVzQXJyYXlbXTwvY29kZT4KLSAgICAtIHdoaWNoIGhvbGRzIHRoZSBVUklzIG9mIGFsbCByZWZlcmVkIG5hbWVzcGFjZXMuIFRoaXMgbWV0aG9kIGFsc28gYnVpbGRzCi0gICAgYW4gYXJyYXkgdGhhdCBtYXBzIGFsbCBET00gbm9kZSB0eXBlcyB0byBuYW1lc3BhY2UgdHlwZXMuIFRoaXMgdHdvIGFycmF5cwotICAgIGFyZSBhY2Nlc3NlZCB0aHJvdWdoIHR3byBuZXcgbWV0aG9kcyBpbiB0aGUgRE9NIGludGVyZmFjZTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgcHVibGljIFN0cmluZyBnZXROYW1lc3BhY2VOYW1lKGludCBub2RlKTsKLSAgICBwdWJsaWMgaW50ICAgIGdldE5hbWVzcGFjZVR5cGUoaW50IG5vZGUpOwotPC9zb3VyY2U+Ci0KLSAgPC9zMz48L3MyPjxhbmNob3IgbmFtZT0iTlNCIi8+Ci0gIDxzMiB0aXRsZT0iTmFtZXNwYWNlcyBpbiB0aGUgWFNMIHN0eWxlc2hlZXQiPgotICA8dWw+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0ic3RvcmUtYWNjZXNzIj5TdG9yaW5nIGFuZCBhY2Nlc3NpbmcgbmFtZXNwYWNlIGluZm9ybWF0aW9uPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0ibWFwZG9tLXN0eWxlc2hlZXQiPk1hcHBpbmcgRE9NIG5hbWVzcGFjZXMgdG8gc3R5bGVzaGVldCBuYW1lc3BhY2VzPC9saW5rPjwvbGk+Ci0gICAgPGxpPjxsaW5rIGFuY2hvcj0id2lsZGNhcmRzIj5XaWxkY2FyZHMgYW5kIG5hbWVzcGFjZXM8L2xpbms+PC9saT4KLSAgPC91bD4KLSAgICA8YW5jaG9yIG5hbWU9InN0b3JlLWFjY2VzcyIvPgotICAgIDxzMyB0aXRsZT0iU3RvcmluZyBhbmQgYWNjZXNzaW5nIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiI+Ci0gICAgPHA+VGhlIFN5bWJvbFRhYmxlIGNsYXNzIGhhcyB0aHJlZSBkYXRhc3RydWN0dXJlcyB0aGF0IGFyZSB1c2VkIHRvIGhvbGQKLSAgICBuYW1lc3BhY2UgaW5mb3JtYXRpb246PC9wPgotCi0gICAgPHVsPgotICAgICAgPGxpPgotICAgICAgICBGaXJzdCB0aGVyZSBpcyB0aGUgPGNvZGU+X25hbWVzcGFjZXNbXTwvY29kZT4gSGFzaHRhYmxlIHRoYXQgbWFwcyB0aGUgbmFtZXMKLSAgICAgICAgb2YgaW4tc2NvcGUgbmFtZXNwYWNlIHRvIHRoZWlyIHJlc3BlY3RpdmUgcHJlZml4ZXMuIEVhY2gga2V5IGluIHRoZQotICAgICAgICBIYXNodGFibGUgb2JqZWN0IGhhcyBhIHN0YWNrLiBBIG5ldyBwcmVmaXggaXMgcHVzaGVkIG9uIHRoZSBzdGFjayBmb3IKLSAgICAgICAgZWFjaCBuZXcgZGVjbGFyYXRpb24gb2YgYSBuYW1lc3BhY2UuCi0gICAgICA8L2xpPgotICAgICAgPGxpPgotICAgICAgICBUaGVuIHRoZXJlIGlzIHRoZSA8Y29kZT5fcHJlZml4ZXNbXTwvY29kZT4gSGFzaHRhYmxlLiBUaGlzIGhhcyB0aGUgcmV2ZXJzZQotICAgICAgICBmdW5jdGlvbiBvZiB0aGUgPGNvZGU+X25hbWVzcGFjZXNbXTwvY29kZT4gSGFzaHRhYmxlIC0gaXQgbWFwcyBmcm9tCi0gICAgICAgIHByZWZpeGVzIHRvIG5hbWVzcGFjZXMuCi0gICAgICA8L2xpPgotICAgICAgPGxpPgotICAgICAgICBUaGVyZSBpcyBhbHNvIGEgaGFzaHRhYmxlIHRoYXQgaXMgdXNlZCBmb3IgaW1wbGVtZW50aW5nIHRoZQotICAgICAgICA8Y29kZT4mbHQ7eHNsOm5hbWVzcGFjZS1hbGlhcyZndDs8L2NvZGU+IGVsZW1lbnQuIFRoZSBrZXlzIGluIHRoaXMKLSAgICAgICAgaGFzaHRhYmxlIGlzIHRha2VuIGZyb20gdGhlIDxjb2RlPnN0eWxlc2hlZXQtcHJlZml4PC9jb2RlPiBhdHRyaWJ1dGUgb2YKLSAgICAgICAgdGhpcyBlbGVtZW50LCBhbmQgdGhlIHJlc3VsdGluZyBwcmVmaXggKGZyb20gdGhlIDxjb2RlPnJlc3VsdC1wcmVmaXg8L2NvZGU+Ci0gICAgICAgIGF0dHJpYnV0ZSkgaXMgdXNlZCBhcyB0aGUgdmFsdWUgZm9yIGVhY2gga2V5LgotICAgICAgPC9saT4KLSAgICA8L3VsPgotCi0gICAgPHA+VGhlIFN5bWJvbFRhYmxlIGNsYXNzIG9mZmVycyA0IG1ldGhvZHMgZm9yIGFjY2Vzc2luZyB0aGVzZSBkYXRhCi0gICAgc3RydWN0dXJlczo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgcHVibGljIHZvaWQgICBwdXNoTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgsIFN0cmluZyB1cmkpOwotICAgIHB1YmxpYyB2b2lkICAgcG9wTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgpOwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwUHJlZml4KFN0cmluZyB1cmkpOwotICAgIHB1YmxpYyBTdHJpbmcgbG9va3VwTmFtZXNwYWNlKFN0cmluZyBwcmVmaXgpOwotPC9zb3VyY2U+Ci0KLSAgICA8cD5UaGVzZSBtZXRob2RzIGFyZSB3cmFwcGVkIGJ5IHR3byBtZXRob2RzIGluIHRoZSBQYXJzZXIgY2xhc3MgKGEgUGFyc2VyCi0gICAgb2JqZWN0IGFsd2FzIGhhcyBhIFN5bWJvbFRhYmxlIG9iamVjdCk6PC9wPgotPHNvdXJjZT4KLSAgICAvLyBUaGlzIG1ldGhvZCBwdXNoZXMgYWxsIG5hbWVzcGFjZXMgZGVjbGFyZWQgd2l0aGluIGEgc2luZ2xlIGVsZW1lbnQKLSAgICBwdWJsaWMgdm9pZCBwdXNoTmFtZXNwYWNlcyhFbGVtZW50RXggZWxlbWVudCk7Ci0gICAgLy8gVGhpcyBtZXRob2QgcG9wcyBhbGwgbmFtZXNwYWNlcyBkZWNsYXJlZCB3aXRoaW4gYSBzaW5nbGUgZWxlbWVudAotICAgIHB1YmxpYyB2b2lkIHBvcE5hbWVzcGFjZXMoRWxlbWVudEV4IGVsZW1lbnQpOwotPC9zb3VyY2U+Ci0KLSAgICA8cD5UaGUgdHJhbnNsZXQgY2xhc3MgaGFzLCBqdXN0IGxpa2UgdGhlIERPTSwgYSA8Y29kZT5uYW1lc0FycmF5W108L2NvZGU+Ci0gICAgc3RydWN0dXJlIGZvciBob2xkaW5nIHRoZSBleHBhbmRlZCBRTmFtZXMgb2YgYWxsIGFjY2Vzc2VkIGVsZW1lbnRzLiBUaGUKLSAgICBjb21waWxlZCB0cmFuc2xldCBmaWxscyB0aGlzIGFycmF5IGluIGl0cyBjb25zdHJ1Y3Rvci4gV2hlbiB0aGUgdHJhbnNsZXQKLSAgICBoYXMgYnVpbHQgdGhlIERPTSAoYSBET01JbXBsIG9iamVjdCksIGl0IHBhc3NlcyB0aGUgRE9NIHRvIHRoZSBhIERPTQotICAgIGFkYXB0ZXIgKGEgRE9NQWRhcHRlciBvYmplY3QpIHRvZ2V0aGVyIHdpdGggdGhlIG5hbWVzIGFycmF5LiBUaGUgRE9NCi0gICAgYWRhcHRlciB0aGVuIG1hcHMgdGhlIHRyYW5zbGV0J3MgdHlwZXMgdG8gdGhlIERPTSdzIHR5cGVzLjwvcD4KLSAgIDwvczM+PGFuY2hvciBuYW1lPSJtYXBkb20tc3R5bGVzaGVldCIvPgotICA8czMgdGl0bGU9Ik1hcHBpbmcgRE9NIG5hbWVzcGFjZXMgYW5kIHN0eWxlc2hlZXQgbmFtZXNwYWNlcyI+Ci0KLSAgICA8cD5FYWNoIGVudHJ5IGluIHRoZSBET00ncyA8Y29kZT5fbmFtZXNBcnJheVtdPC9jb2RlPiBpcyBleHBhbmRlZCB0byBjb250YWluCi0gICAgdGhlIGZ1bGwgUU5hbWUsIHNvIHRoYXQgaW5zdGVhZCBvZiBjb250YWluaW5nIDxjb2RlPnByZWZpeDpsb2NhbG5hbWU8L2NvZGU+IGl0Ci0gICAgd2lsbCBub3cgY29udGFpbiA8Y29kZT5uYW1lc3BhY2UtdXJpOmxvY2FsbmFtZTwvY29kZT4uIEluIHRoaXMgd2F5IHRoZSBleHBhbmRlZAotICAgIFFOYW1lIGluIHRoZSB0cmFuc2xldCB3aWxsIG1hdGNoIHRoZSBleGFuZGVkIFFOYW1lIGluIHRoZSBET00uIFRoaXMgYXNzdXJlcwotICAgIG1hdGNoZXMgb24gZnVsbCBRTmFtZXMsIGJ1dCBkb2VzIG5vdCBkbyBtdWNoIGZvciA8Y29kZT5tYXRjaD0iQToqIjwvY29kZT4gdHlwZQotICAgIFhQYXRoIHBhdHRlcm5zLiBUaGlzIGlzIHdoZXJlIG91ciBtYWluIGNoYWxsZW5nZSBsaWVzLjwvcD4KLSAgICA8L3MzPjxhbmNob3IgbmFtZT0id2lsZGNhcmRzIi8+Ci0gICAgPHMzIHRpdGxlPSJXaWxkY2FyZHMgYW5kIG5hbWVzcGFjZXMiPgotCi0gICAgPHA+VGhlIG9yaWdpbmFsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBYU0xUQyBydW50aW1lIGVudmlyb25tZW50IHdvdWxkCi0gICAgb25seSBhbGxvdyBtYXRjaGVzIG9uICI8Y29kZT4qPC9jb2RlPiIgYW5kICI8Y29kZT5AKjwvY29kZT4iIHBhdHRlcm5zLiBUaGlzIHdhcwotICAgIGFjaGlldmVkIGJ5IG1hcHBpbmcgYWxsIGVsZW1lbnRzIHRoYXQgY291bGQgbm90IGJlIG1hcHBlZCB0byBhIHRyYW5zbGV0Ci0gICAgdHlwZSB0byAzIChET00uRUxFTUVOVCB0eXBlKSwgYW5kIHNpbWlsYXJseSBhbGwgdW5rbm93biBhdHRyaWJ1dGVzIHRvCi0gICAgdHlwZSA0IChET00uQVRUUklCVVRFIHR5cGUpLiBUaGUgbWFpbiA8Y29kZT5zd2l0Y2goKTwvY29kZT4gc3RhdGVtZW50IGluCi0gICAgPGNvZGU+YXBwbHlUZW1wbGF0ZXMoKTwvY29kZT4gd291bGQgdGhlbiBoYXZlIGEgc2VwYXJhdGUgIjxjb2RlPmNhc2UoKTwvY29kZT4iCi0gICAgZm9yIGVhY2ggb2YgdGhlc2UuIChVbmRlciBlYWNoIDxjb2RlPmNhc2UoKTwvY29kZT4geW91IG1pZ2h0IGhhdmUgdG8gY2hlY2sKLSAgICBmb3IgdGhlIG5vZGUncyBwYXJlbnRzIGluIGNhc2UgeW91IHdlcmUgbWF0Y2hpbmcgb24gIjxjb2RlPnBhdGgvKjwvY29kZT4iLXR5cGUKLSAgICBwYXR0ZXJucy4pIFRoaXMgZmlndXJlIHNob3dzIGhvdyB0aGF0IHdhcyBkb25lOjwvcD4KLQotICAgIDxhbmNob3IgbmFtZT0ibWF0Y2hfbmFtZXNwYWNlMSIvPgotICAgIDxwPjxpbWcgc3JjPSJtYXRjaF9uYW1lc3BhY2UxLmdpZiIgYWx0PSJtYXRjaF9uYW1lc3BhY2UxLmdpZiIvPjwvcD4KLSAgICA8cD48cmVmPkZpZ3VyZSA2OiBQcmV2aW91cyBwYXR0ZXJuIG1hdGNoaW5nPC9yZWY+PC9wPgotCi0gICAgPHA+VGhlICJOb2RlIHRlc3QiIGJveCBoZXJlIHJlcHJlc2VudHMgdGhlICI8Y29kZT5zd2l0Y2goKTwvY29kZT4iIHN0YXRlbWVudC4KLSAgICBUaGUgIk5vZGUgcGFyZW50IHRlc3QiIGJveCByZXByZXNlbnQgZWFjaCAiPGNvZGU+Y2FzZTo8L2NvZGU+IiBmb3IgdGhhdCAKLSAgICA8Y29kZT5zd2l0Y2goKTwvY29kZT4gc3RhdGVtZW50LiBUaGVyZSBpcyBvbmUgPGNvZGU+Y2FzZTo8L2NvZGU+IGZvciBlYWNoIGtub3cKLSAgICB0cmFuc2xldCBub2RlIHR5cGUuIEZvciBlYWNoIG5vZGUgdHlwZSB3ZSBoYXZlIHRvIGNoZWNrIGZvciBhbnkgcGFyZW50Ci0gICAgcGF0dGVybnMgLSBmb3IgaW5zdGFuY2UsIGZvciB0aGUgcGF0dGVybiAiPGNvZGU+L2Zvby9iYXIvYmF6PC9jb2RlPiIsIHdlIHdpbGwKLSAgICBnZXQgYSBtYXRjaCB3aXRoIDxjb2RlPmNhc2UgImJheiI8L2NvZGU+LCBhbmQgd2UgaGF2ZSB0byBjaGVjayB0aGF0IHRoZSBwYXJlbnQKLSAgICBub2RlIGlzICI8Y29kZT5iYXI8L2NvZGU+IiBhbmQgdGhhdCB0aGUgZ3JhbmRwYXJlbnQgaXMgIjxjb2RlPmZvbzwvY29kZT4iIGJlZm9yZQotICAgIHdlIGNhbiBzYXkgdGhhdCB3ZSBoYXZlIGEgaGl0LiBUaGUgIkVsZW1lbnQgcGFyZW50IHRlc3QiIGlzIHRoZSB0ZXN0IHRoYXQKLSAgICBpcyBkb25lIGFsbCBET00gbm9kZXMgdGhhdCBkbyBub3QgZGlyZWN0bHkgbWF0Y2ggYW55IHRyYW5zbGV0IHR5cGVzLiBUaGlzCi0gICAgaXMgdGhlIHRlc3QgZm9yICI8Y29kZT4qPC9jb2RlPiIgb3IgIjxjb2RlPmZvby8qPC9jb2RlPiIuIFNpbWlsYXJseSB3ZSBoYXZlIGEKLSAgICAiPGNvZGU+Y2FzZTo8L2NvZGU+IiBmb3IgbWF0Y2ggb24gYXR0cmlidXRlcyAoIjxjb2RlPkAqPC9jb2RlPiIpLjwvcD4KLQotICAgIDxwPldoYXQgd2Ugbm93IHdhbnQgdG8gYWNoaWV2ZSBpcyB0byBpbnNlcnQgYSBjaGVjayBmb3IgcGF0dGVybnMgb24gdGhlCi0gICAgZm9ybWF0ICI8Y29kZT5uczoqPC9jb2RlPiIsICI8Y29kZT5mb28vbnM6KjwvY29kZT4iIG9yICI8Y29kZT5uczpAKjwvY29kZT4iLCB3aGljaAotICAgIHRoaXMgZmlndXJlIGlsbHVzdHJhdGVzOjwvcD4KLQotICAgIDxhbmNob3IgbmFtZT0ibWF0Y2hfbmFtZXNwYWNlMiIvPgotICAgICAgPHA+PGltZyBzcmM9Im1hdGNoX25hbWVzcGFjZTIuZ2lmIiBhbHQ9Im1hdGNoX25hbWVzcGFjZTIuZ2lmIi8+PC9wPgotICAgICAgPHA+PHJlZj5GaWd1cmUgNzogUGF0dGVybiBtYXRjaGluZyB3aXRoIG5hbWVzcGFjZSB0ZXN0czwvcmVmPjwvcD4KLQotCi0gICAgPHA+RWFjaCBub2RlIGluIHRoZSBET00gbmVlZHMgYSBuYW1lc3BhY2UgdHlwZSBhcyB3ZWxsIGFzIHRoZSBRTmFtZSB0eXBlLgotICAgIFdpdGggdGhpcyB0eXBlIHdlIGNhbiBtYXRjaCB3aWxkY2FyZCBydWxlcyB0byBhbnkgc3BlY2lmaWMgbmFtZXNwYWNlLgotICAgIFNvIGFmdGVyIGFueSBjaGVja3MgaGF2ZSBiZWVuIGRvbmUgb24gdGhlIHdob2xlIFFOYW1lIG9mIGEgbm9kZSAodGhlIHR5cGUpLAotICAgIHdlIGNhbiBtYXRjaCBvbiB0aGUgbmFtZXNwYWNlIHR5cGUgb2YgdGhlIG5vZGUuIFRoZSBtYWluIGRpc3BhdGNoCi0gICAgPGNvZGU+c3dpdGNoKCk8L2NvZGU+IGluIDxjb2RlPmFwcGx5VGVtcGxhdGVzKCk8L2NvZGU+IG11c3QgYmUgY2hhbmdlZCBmcm9tIHRoaXM6PC9wPgotCi0gICAgPHNvdXJjZT4KLSAgICAgICAgcHVibGljIHZvaWQgYXBwbHlUZW1wbGF0ZXMoRE9NIGRvbSwgTm9kZUl0ZXJhdG9yIGl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikgewotCi0gICAgICAgICAgICAvLyBHZXQgbmV4dCBub2RlIGZyb20gaXRlcmF0b3IKLSAgICAgICAgICAgIHdoaWxlICgobm9kZSA9IGl0ZXJhdG9yLm5leHQoKSkgIT0gRU5EKSB7Ci0gICAgICAgICAgICAgICAgLy8gR2V0IGludGVybmFsIG5vZGUgdHlwZQotICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gRE9NLmdldFR5cGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgc3dpdGNoKHR5cGUpIHsKLSAgICAgICAgICAgICAgICBjYXNlIERPTS5ST09UOiAgICAgIC8vIE1hdGNoIG9uICIvIiBwYXR0ZXJuCi0gICAgICAgICAgICAgICAgICAgIGhhbmRsZVJvb3ROb2RlKCk7ICAgICAgIAotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIERPTS5URVhUOiAgICAgIC8vIEhhbmRsZSB0ZXh0IG5vZGVzCi0gICAgICAgICAgICAgICAgICAgIGhhbmRsZVRleHQoKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBET00uRUxFTUVOVDogICAvLyBNYXRjaCBvbiAiKiIgcGF0dGVybgotICAgICAgICAgICAgICAgICAgICBoYW5kbGVXaWxkY2FyZEVsZW1lbnQoKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBET00uQVRUUklCVVRFOiAvLyBIYW5kbGUgb24gIkAqIiBwYXR0ZXJuCi0gICAgICAgICAgICAgICAgICAgIGhhbmRsZVdpbGRjYXJkRWxlbWVudCgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIG5vZGVUeXBlMTogICAgIC8vIEhhbmRsZSAxc3Qga25vd24gZWxlbWVudCB0eXBlCi0gICAgICAgICAgICAgICAgICAgIGNvbXBpbGVkQ29kZUZvclR5cGUxKCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICA6Ci0gICAgICAgICAgICAgICAgICAgIDoKLSAgICAgICAgICAgICAgICAgICAgOgotICAgICAgICAgICAgICAgIGNhc2Ugbm9kZVR5cGVOOiAgIC8vIEhhbmRsZSBudGgga25vd24gZWxlbWVudCB0eXBlCi0gICAgICAgICAgICAgICAgICAgIGNvbXBpbGVkQ29kZUZvclR5cGVOKCk7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgTm9kZUl0ZXJhdG9yIG5ld0l0ZXJhdG9yID0gRE9NLmdldENoaWxkcmVuKG5vZGUpOwotICAgICAgICAgICAgICAgICAgIGFwcGx5VGVtcGxhdGVzKERPTSwgbmV3SXRlcmF0b3IsIGhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgfQotPC9zb3VyY2U+Ci0KLSAgICA8cD5UbyBzb21ldGhpbmcgbGlrZSB0aGlzOjwvcD4KLQotICAgIDxzb3VyY2U+Ci0gICAgICAgIHB1YmxpYyB2b2lkIGFwcGx5VGVtcGxhdGVzKERPTSBkb20sIE5vZGVJdGVyYXRvciBpdGVyYXRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNsZXRPdXRwdXRIYW5kbGVyIGhhbmRsZXIpIHsKLQotICAgICAgICAgICAgLy8gR2V0IG5leHQgbm9kZSBmcm9tIGl0ZXJhdG9yCi0gICAgICAgICAgICB3aGlsZSAoKG5vZGUgPSBpdGVyYXRvci5uZXh0KCkpICE9IEVORCkgewotCi0gICAgICAgICAgICAgICAgLy8gRmlyc3QgcnVuIGNoZWNrIG9uIG5vZGUgdHlwZQotICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gRE9NLmdldFR5cGUobm9kZSk7Ci0gICAgICAgICAgICAgICAgc3dpdGNoKHR5cGUpIHsKLSAgICAgICAgICAgICAgICBjYXNlIERPTS5ST09UOiAgICAgIC8vIE1hdGNoIG9uICIvIiBwYXR0ZXJuCi0gICAgICAgICAgICAgICAgICAgIGhhbmRsZVJvb3ROb2RlKCk7Ci0gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgIGNhc2UgRE9NLlRFWFQ6ICAgICAgLy8gSGFuZGxlIHRleHQgbm9kZXMKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlVGV4dCgpOwotICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICBjYXNlIERPTS5FTEVNRU5UOiAgIC8vIE5vdCBoYW5kbGVkIGhlcmUhISEKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSBET00uQVRUUklCVVRFOiAvLyBOb3QgaGFuZGxlZCBoZXJlISEhCi0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2Ugbm9kZVR5cGUxOiAgICAgLy8gSGFuZGxlIDFzdCBrbm93biBlbGVtZW50IHR5cGUKLSAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBpbGVkQ29kZUZvclR5cGUxKCkgPT0gbWF0Y2gpIGNvbnRpbnVlOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgOgotICAgICAgICAgICAgICAgICAgICA6Ci0gICAgICAgICAgICAgICAgICAgIDoKLSAgICAgICAgICAgICAgICBjYXNlIG5vZGVUeXBlTjogICAgIC8vIEhhbmRsZSBudGgga25vd24gZWxlbWVudCB0eXBlCi0gICAgICAgICAgICAgICAgICAgIGlmIChjb21waWxlZENvZGVGb3JUeXBlTigpID09IG1hdGNoKSBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgLy8gVGhlbiBydW4gY2hlY2sgb24gbmFtZXNwYWNlIHR5cGUKLSAgICAgICAgICAgICAgICBmaW5hbCBpbnQgbmFtZXNwYWNlID0gRE9NLmdldE5hbWVzcGFjZSh0eXBlKTsKLSAgICAgICAgICAgICAgICBzd2l0Y2gobmFtZXNwYWNlKSB7Ci0gICAgICAgICAgICAgICAgY2FzZSAwOiAvLyBIYW5kbGUgbm9kZXMgbWF0Y2hpbmcgMXN0IGtub3duIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZGxlVGhpc05hbWVzcGFjZSgpID09IG1hdGNoKSBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAxOiAvLyBIYW5kbGUgbm9kZXMgbWF0Y2hpbmcgMm5kIGtub3duIG5hbWVzcGFjZQotICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZGxlT3RoZXJOYW1lc3BhY2UoKSA9PSBtYXRjaCkgY29udGludWU7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIC8vIEZpbmFsbHkgY2hlY2sgb24gZWxlbWVudC9hdHRyaWJ1dGUgd2lsZGNhcmQKLSAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBET00uRUxFTUVOVCkgewotICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZGxlV2lsZGNhcmRFbGVtZW50KCkgPT0gbWF0Y2gpCi0gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKLSAgICAgICAgICAgICAgICAgICAgZWxzZSB7Ci0gICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBkZWZhdWx0IGFjdGlvbiBmb3IgZWxlbWVudHMKLSAgICAgICAgICAgICAgICAgICAgICAgTm9kZUl0ZXJhdG9yIG5ld0l0ZXJhdG9yID0gRE9NLmdldENoaWxkcmVuKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICAgICBhcHBseVRlbXBsYXRlcyhET00sIG5ld0l0ZXJhdG9yLCBoYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IERPTS5BVFRSSUJVVEUpIHsKLSAgICAgICAgICAgICAgICAgICAgaGFuZGxlV2lsZGNhcmRBdHRyaWJ1dGUoKTsKLSAgICAgICAgICAgICAgICAgICAgY29udGludWU7IAotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotPC9zb3VyY2U+Ci0KLSAgICA8cD5GaXJzdCBub3RlIHRoYXQgdGhlIGRlZmF1bHQgYWN0aW9uIChpdGVyYXRlIG9uIGNoaWxkcmVuKSBkb2VzIG5vdCBob2xkIGZvcgotICAgIGF0dHJpYnV0ZXMsIHNpbmNlIGF0dHJpYnV0ZSBub2RlcyBkbyBub3QgaGF2ZSBjaGlsZHJlbi4gVGhlbiBub3RlIHRoYXQgdGhlIHdheQotICAgIHRoZSB0aHJlZSBsZXZlbHMgb2YgdGVzdHMgYXJlIG9yZGVyZWQgaXMgY29uc2lzdGVudCB3aXRoIHRoZSB3YXkgcGF0dGVybnMKLSAgICBzaG91bGQgYmUgcHJpb3JpdGlzZWQ6PC9wPgotCi0gICAgPHVsPgotCi0gICAgICA8bGk+PGVtPk1hdGNoIG9uIGVsZW1lbnQvYXR0cmlidXRlIHR5cGVzOjwvZW0+PC9saT4KLSAgICAgICAgPHVsPgotICAgICAgICAgIDxsaT48Y29kZT5tYXRjaD0iLyI8L2NvZGU+IC0gbWF0Y2ggb24gdGhlIHJvb3Qgbm9kZTwvbGk+Ci0gICAgICAgICAgPGxpPjxjb2RlPm1hdGNoPSJCIjwvY29kZT4gLSBtYXRjaCBvbiBhbnkgQiBlbGVtZW50PC9saT4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9IkEvQiI8L2NvZGU+IC0gbWF0Y2ggb24gQiBlbGVtZW50cyB3aXRoIEEgcGFyZW50PC9saT4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9IkEgfCBCIjwvY29kZT4gLSBtYXRjaCBvbiBCIG9yIEEgZWxlbWVudDwvbGk+Ci0gICAgICAgICAgPGxpPjxjb2RlPm1hdGNoPSJmb286QiI8L2NvZGU+IC0gbWF0Y2ggb24gQiBlbGVtZW50IHdpdGhpbiAiZm9vIiBuYW1lc3BhY2U8L2xpPgotICAgICAgICA8L3VsPgotICAgICAgICA8bGk+PGVtPk1hdGNoIG9uIG5hbWVzcGFjZTo8L2VtPjwvbGk+Ci0gICAgICAgIDx1bD4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9ImZvbzoqIjwvY29kZT4gLSBtYXRjaCBvbiBhbnkgZWxlbWVudCB3aXRoaW4gImZvbyIgbmFtZXNwYWNlPC9saT4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9ImZvbzpAKiI8L2NvZGU+IC0gbWF0Y2ggb24gYW55IGF0dHJpYnV0ZSB3aXRoaW4gImZvbyIgbmFtZXNwYWNlPC9saT4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9IkEvZm9vOioiPC9jb2RlPiAtIG1hdGNoIG9uIGFueSBlbGVtZW50IHdpdGhpbiAiZm9vIiBuYW1lc3BhY2Ugd2l0aCBBIHBhcmVudDwvbGk+Ci0gICAgICAgICAgPGxpPjxjb2RlPm1hdGNoPSJBL2ZvbzpAKiI8L2NvZGU+IC0gbWF0Y2ggb24gYW55IGF0dHJpYnV0ZSB3aXRoaW4gImZvbyIgbmFtZXNwYWNlIHdpdGggQSBwYXJlbnQ8L2xpPgotICAgICAgICA8L3VsPiAgICAgIAotCi0gICAgICA8bGk+PGVtPk1hdGNoIG9uIHdpbGRjYXJkOjwvZW0+IDwvbGk+Ci0gICAgICAgIDx1bD4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9IioiPC9jb2RlPiAtIG1hdGNoIG9uIGFueSBlbGVtZW50PC9saT4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9IkAqIjwvY29kZT4gLSBtYXRjaCBvbiBhbnkgYXR0cmlidXRlPC9saT4KLSAgICAgICAgICA8bGk+PGNvZGU+bWF0Y2g9IkEvKiI8L2NvZGU+IC0gbWF0Y2ggb24gYW55IGVsZW1lbnQgd2l0aCBBIHBhcmVudDwvbGk+Ci0gICAgICAgICAgPGxpPjxjb2RlPm1hdGNoPSJBL0AqIjwvY29kZT4gLSBtYXRjaCBvbiBhbnkgYXR0cmlidXRlIHdpdGggQSBwYXJlbnQ8L2xpPgotICAgICAgICA8L3VsPgotICAgICAKLSAgICA8L3VsPgotCi0gICAgIDwvczM+PC9zMj48YW5jaG9yIG5hbWU9Ik5TQyIvPgotICAgICA8czIgdGl0bGU9Ik5hbWVzcGFjZXMgaW4gdGhlIG91dHB1dCBkb2N1bWVudCI+Ci0KLSAgICA8cD5UaGVzZSBhcmUgdGhlIGNhdGVnb3JpZXMgb2YgbmFtZXNwYWNlcyB0aGF0IGVuZCB1cCBpbiB0aGUgb3V0cHV0Ci0gICAgZG9jdW1lbnQ6PC9wPgotCi0gICAgPHVsPgotICAgICAgPGxpPgotICAgICAgICBOYW1lc3BhY2VzIHVzZWQgaW4gbGl0ZXJhbCBlbGVtZW50cy9hdHRyaWJ1dGVzIGluIHRoZSBzdHlsZXNoZWV0LiBUaGVzZQotICAgICAgICBuYW1lc3BhY2VzIHNob3VsZCBiZSBkZWNsYXJlZCA8ZW0+b25jZTwvZW0+IGJlZm9yZSB1c2UgaW4gdGhlIG91dHB1dAotICAgICAgICBkb2N1bWVudC4gVGhlc2UgZWxlbWVudHMgYXJlIGNvcGllZCB0byB0aGUgb3V0cHV0IGRvY3VtZW50IGluZGVwZW5kZW50Ci0gICAgICAgIG9mIG5hbWVzcGFjZXMgaW4gdGhlIGlucHV0IFhNTCBkb2N1bWVudC4gSG93ZXZlciwgdGhlIG5hbWVzcGFjZXMgY2FuCi0gICAgICAgIGJlIGRlY2xhcmVkIHVzaW5nIHRoZSBzYW1lIHByZWZpeCwgc3VjaCB0aGF0IGEgbmFtZXNwYWNlIHVzZWQgYnkgYQotICAgICAgICBsaXRlcmFsIHJlc3VsdCBlbGVtZW50IGNhbiBvdmVyc2hhZG93IGEgbmFtZXNwYWNlIGZyb20gdGhlIERPTS4KLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0gICAgICAgIE5hbWVzcGFjZXMgZnJvbSBlbGVtZW50cyBpbiB0aGUgc3R5bGVzaGVldCB0aGF0IG1hdGNoIGVsZW1lbnRzIGluIHRoZQotICAgICAgICBET00uIE5vIG5hbWVzcGFjZXMgZnJvbSB0aGUgRE9NIHNob3VsZCBiZSBjb3BpZWQgdG8gdGhlIG91dHB1dCBkb2N1bWVudAotICAgICAgICB1bmxlc3MgdGhleSBhcmUgYWN0dWFsbHkgcmVmZXJlbmNlZCBpbiB0aGUgc3R5bGVzaGVldC4gTm8gbmFtZXNwYWNlcwotICAgICAgICBmcm9tIHRoZSBzdHlsZXNoZWV0IHNob3VsZCBiZSBjb3BpZWQgdG8gdGhlIG91dHB1dCBkb2N1bWVudCB1bmxlc3MgdGhlCi0gICAgICAgIGVsZW1lbnRzIGluIHdoaWNoIHRoZXkgYXJlIHJlZmVyZW5jZXMgbWF0Y2ggZWxlbWVudHMgaW4gdGhlIERPTS4KLSAgICAgIDwvbGk+Ci0gICAgPC91bD4KLQotICAgICAgPGFuY2hvciBuYW1lPSJvdXRwdXRfbmFtZXNwYWNlczEiLz4KLSAgICAgIDxwPjxpbWcgc3JjPSJvdXRwdXRfbmFtZXNwYWNlczEuZ2lmIiBhbHQ9Im91dHB1dF9uYW1lc3BhY2VzMS5naWYiLz48L3A+Ci0gICAgICA8cD48cmVmPkZpZ3VyZSA4OiBOYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gdGhlIG91dHB1dCBkb2N1bWVudDwvcmVmPjwvcD4gICAgCi0KLSAgICA8cD5BbnkgbGl0ZXJhbCBlbGVtZW50IHRoYXQgZW5kcyB1cCBpbiB0aGUgb3V0cHV0IGRvY3VtZW50IG11c3QgZGVjbGFyZSBhbGwKLSAgICBuYW1lc3BhY2VzIHRoYXQgd2VyZSBkZWNsYXJlZCBpbiB0aGUgPGNvZGU+Jmx0O3hzbDpzdHlsZXNoZWV0Jmx0OzwvY29kZT4KLSAgICBlbGVtZW50LiBFeGNlcHRpb25zIGFyZSBuYW1lc3BhY2VzIHRoYXQgYXJlIGxpc3RlZCBpbiB0aGlzIGVsZW1lbnQncwotICAgIDxjb2RlPmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzPC9jb2RlPiBvciA8Y29kZT5leHRlbnNpb24tZWxlbWVudC1wcmVmaXhlczwvY29kZT4KLSAgICBhdHRyaWJ1dGVzLiBUaGVzZSBuYW1lc3BhY2VzIHNob3VsZCBvbmx5IGJlIGRlY2xhcmVkIGlmIHRoZXkgYXJlIHJlZmVyZW5jZWQKLSAgICBpbiB0aGUgb3V0cHV0LjwvcD4KLQotICAgIDxwPkxpdGVyYWwgZWxlbWVudHMgc2hvdWxkIG9ubHkgZGVjbGFyZSBuYW1lc3BhY2VzIHdoZW4gbmVjZXNzYXJ5LiBBCi0gICAgbGl0ZXJhbCBlbGVtZW50IHNob3VsZCBvbmx5IGRlY2xhcmUgYSBuYW1lc3BhY2UgaW4gdGhlIGNhc2Ugd2hlcmUgaXQKLSAgICByZWZlcmVuY2VzIGEgbmFtZXNwYWNlIHVzaW5nIHByZWZpeCB0aGF0IGlzIG5vdCBpbiBzY29wZSBmb3IgdGhpcwotICAgIG5hbWVzcGFjZS4gVGhlIG91dHB1dCBoYW5kbGVyIHdpbGwgdGFrZSBjYXJlIG9mIHRoaXMgcHJvYmxlbS4gQWxsIG5hbWVzcGFjZQotICAgIGRlY2xhcmF0aW9ucyBhcmUgcHV0IGluIHRoZSBvdXRwdXQgZG9jdW1lbnQgdXNpbmcgdGhlIG91dHB1dCBoYW5kbGVyJ3MKLSAgICA8Y29kZT5kZWNsYXJlbmFtZXNwYWNlKCk8L2NvZGU+IG1ldGhvZC4gVGhpcyBtZXRob2Qgd2lsbCBtb25pdG9yIGFsbCBuYW1lc3BhY2UKLSAgICBkZWNsYXJhdGlvbnMgYW5kIG1ha2Ugc3VyZSB0aGF0IG5vIHVubmVjZXNzYXJ5IGRlY2xhcmF0aW9ucyBhcmUgb3V0cHV0LgotICAgIFRoZSBkYXRhc3RydWN0dXJlcyB1c2VkIGZvciB0aGlzIGFyZSBzaW1pbGFyIHRvIHRob3NlIHVzZWQgdG8gdHJhY2sKLSAgICBuYW1lc3BhY2VzIGluIHRoZSBYU0wgc3R5bGVzaGVldDo8L3A+Ci0KLSAgICA8YW5jaG9yIG5hbWU9Im91dHB1dF9uYW1lc3BhY2VzMiIvPgotICAgIDxwPjxpbWcgc3JjPSJvdXRwdXRfbmFtZXNwYWNlczIuZ2lmIiBhbHQ9Im91dHB1dF9uYW1lc3BhY2VzMi5naWYiLz48L3A+Ci0gICAgICA8cD48cmVmPkZpZ3VyZSA5OiBIYW5kbGluZyBOYW1lc3BhY2UgZGVjbGFyYXRpb25zIGluIHRoZSBvdXRwdXQgZG9jdW1lbnQ8L3JlZj48L3A+Ci0KLSA8L3MyPgotPC9zMT4KZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfcnVudGltZS54bWwgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbHRjX3J1bnRpbWUueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkZDBiYTQzLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfcnVudGltZS54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw0MTUgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci0gIDxzMSB0aXRsZT0iWFNMVEMgcnVudGltZSBlbnZpcm9ubWVudCI+Ci0gIDx1bD4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJvdmVydmlldyI+UnVudGltZSBvdmVydmlldzwvbGluaz48L2xpPgotICAgIDxsaT48bGluayBhbmNob3I9InRyYW5zbGV0Ij5UaGUgY29tcGlsZWQgdHJhbnNsZXQ8L2xpbms+PC9saT4KLSAgICA8bGk+PGxpbmsgYW5jaG9yPSJ0eXBlcyI+RXh0ZXJuYWwvaW50ZXJuYWwgdHlwZSBtYXBwaW5nPC9saW5rPjwvbGk+ICAgIAotICAgIDxsaT48bGluayBhbmNob3I9Im1haW5sb29wIj5NYWluIHByb2dyYW0gbG9vcDwvbGluaz48L2xpPgotCi0gIDwvdWw+Ci0gIDxhbmNob3IgbmFtZT0ib3ZlcnZpZXciLz4KLSAgPHMyIHRpdGxlPSJSdW50aW1lIG92ZXJ2aWV3Ij4KLSAgICA8cD5UaGUgYWN0dWFsIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQgaXMgaW5pdGlhdGVkIGJ5Ci0gICAgb25lIG9mIHRoZXNlIGNsYXNzZXM6PC9wPgotCi0gICAgPHVsPgotICAgICAgPGxpPgotICAgICAgICA8Y29kZT5jb20uc3VuLnhzbHQucnVudGltZS5EZWZhdWx0UnVuPC9jb2RlPiAocnVucyBpbiBhIHRlcm1pbmFsKQotICAgICAgPC9saT4KLSAgICAgIDxsaT4KLSAgICAgICAgPGNvZGU+Y29tLnN1bi54c2x0LmRlbW8uYXBwbGV0LlRyYW5zZm9ybUFwcGxldDwvY29kZT4gKHJ1bnMgaW4gYW4gYXBwbGV0KQotICAgICAgPC9saT4KLSAgICAgIDxsaT4KLSAgICAgICAgPGNvZGU+Y29tLnN1bi54c2x0LmRlbW8uc2VydmxldC5UcmFuc2xhdGU8L2NvZGU+IChydW5zIGluIGEgc2VydmxldCkKLSAgICAgIDwvbGk+Ci0gICAgPC91bD4KLQotICAgIDxwPkFueSBvbmUgb2YgdGhlc2UgY2xhc3NlcyB3aWxsIGhhdmUgdG8gZ28gdGhyb3VnaCB0aGUgZm9sbG9pbmcgc3RlcHMgaW4KLSAgICBvcmRlciB0byBpbml0aWF0ZSBhIHRyYW5zZm9ybWF0aW9uOjwvcD4KLQotICAgIDx1bD4KLSAgICAgIDxsaT4KLSAgICAgICAgSW5zdGFuY2lhdGUgdGhlIHRyYW5zbGV0IG9iamVjdC4gVGhlIG5hbWUgb2YgdGhlIHRyYW5zbGV0IChpZS4gY2xhc3MpCi0gICAgICAgIHRvIHVzZSBpcyBwYXNzZWQgdG8gdXMgYXMgYSBzdHJpbmcuIFdlIHVzZSB0aGlzIHN0cmluZyBhcyBhIHBhcmFtZXRlcgotICAgICAgICB0byB0aGUgc3RhdGljIG1ldGhvZCA8Y29kZT5DbGFzcy5mb3JOYW1lKFN0cmluZyBuYW1lKTwvY29kZT4gdG8gZ2V0IGEKLSAgICAgICAgcmVmZXJlbmNlIHRvIGEgdHJhbnNsZXQgb2JqZWN0LgotICAgICAgPC9saT4KLSAgICAgIDxsaT4KLSAgICAgICAgSW5zdGFuY2lhdGUgYSA8Y29kZT5jb20uc3VuLnhzbC5wYXJzZXIuUGFyc2VyPC9jb2RlPiBvYmplY3QgdG8gcGFyc2UgdGhlCi0gICAgICAgIGlucHV0IFhNTCBmaWxlLCBhbmQgaW5zdGFuY2lhdGUgYSBET00gKHdlIGhhdmUgb3VyIG93biBET00KLSAgICAgICAgaW1wbGVtZW50YXRpb24gZXNwZWNpYWxseSBkZXNpZ25lZCBmb3IgWFNMVEMpIHdoZXJlIHdlIHN0b3JlIHRoZQotICAgICAgICBpbnB1dCBkb2N1bWVudC4KLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0gICAgICAgIFBhc3MgYW55IHBhcmFtZXRlcnMgdG8gdGhlIHRyYW5zbGV0IChjdXJyZW50bHkgb25seSBwb3NzaWJsZSB3aGVuCi0gICAgICAgIHJ1bm5pbmcgdGhlIHRyYW5zZm9ybWF0aW9uIGluIGEgdGVybWluYWwgdXNpbmcgRGVmYXVsdFJ1bikKLSAgICAgIDwvbGk+Ci0gICAgICA8bGk+Ci0gICAgICAgIEluc3RhbmNpYXRlIGEgaGFuZGxlciBmb3IgdGhlIHJlc3VsdCBkb2N1bWVudC4gVGhpcyBoYW5kbGVyIG11c3QgYmUKLSAgICAgICAgZXh0ZW5kIHRoZSA8Y29kZT5UcmFuc2xldE91dHB1dEhhbmRsZXI8L2NvZGU+IGNsYXNzLgotICAgICAgPC9saT4KLSAgICAgIDxsaT4KLSAgICAgICAgSW52b2tlIHRoZSA8Y29kZT50cmFuc2Zvcm0oKTwvY29kZT4gbWV0aG9kIG9uIHRoZSB0cmFuc2xldCwgcGFzc2luZyB0aGUKLSAgICAgICAgaW5zdGFuY2lhdGVkIERPTSBhbmQgdGhlIG91dHB1dCBoYW5kbGVyIGFzIHBhcmFtZXRlcnMuCi0gICAgICA8L2xpPgotICAgIDwvdWw+Ci0KLSAgICA8L3MyPjxhbmNob3IgbmFtZT0idHJhbnNsZXQiLz4KLSAgICA8czIgdGl0bGU9IlRoZSBjb21waWxlZCB0cmFuc2xldCI+Ci0KLSAgICA8cD5BIHRyYW5zbGV0IGlzIGFsd2F5cyBhIHN1YmNsYXNzIG9mIDxjb2RlPkFic3RyYWN0VHJhbnNsZXQ8L2NvZGU+LiBBcyB3ZWxsCi0gICAgYXMgaGF2aW5nIGFjY2VzcyB0byB0aGUgcHVibGljL3Byb3RlY3RlZCBtZXRob2RzIGluIHRoaXMgY2xhc3MsIHRoZQotICAgIHRyYW5zbGV0IGlzIGNvbXBpbGVkIHdpdGggdGhlc2UgbWV0aG9kczo8L3A+Ci0KLSAgICA8cD48Y29kZT5wdWJsaWMgdm9pZCB0cmFuc2Zvcm0oRE9NLCBOb2RlSXRlcmF0b3IsIFRyYW5zbGV0T3V0cHV0SGFuZGxlcik7PC9jb2RlPjwvcD4KLQotICAgIDxwPlRoaXMgbWV0aG9kIGlzIHBhc3NlZCBhIDxjb2RlPkRPTUltcGw8L2NvZGU+IG9iamVjdC4gRGVwZW5kaW5nIG9uIHdoZXRoZXIKLSAgICB0aGUgc3R5bGVzaGVldCBoYWQgYW55IGNhbGxzIHRvIHRoZSA8Y29kZT5kb2N1bWVudCgpPC9jb2RlPiBmdW5jdGlvbiB0aGlzCi0gICAgbWV0aG9kIHdpbGwgZWl0aGVyIGdlbmVyYXRlIGEgPGNvZGU+RE9NQWRhcHRlcjwvY29kZT4gb2JqZWN0ICh3aGVuIG9ubHkgb25lCi0gICAgWE1MIGRvY3VtZW50IGlzIHVzZWQgYXMgaW5wdXQpIG9yIGEgPGNvZGU+TXVsdGlET008L2NvZGU+IG9iamVjdCAod2hlbiB0aGVyZQotICAgIGFyZSBtb3JlIHRoYW4gb25lIFhNTCBpbnB1dCBkb2N1bWVudHMpLiBUaGlzIERPTSBvYmplY3QgaXMgcGFzc2VkIG9uIHRvCi0gICAgdGhlIDxjb2RlPnRvcExldmVsKCk8L2NvZGU+IG1ldGhvZC48L3A+Ci0KLSAgICA8cD5XaGVuIHRoZSA8Y29kZT50b3BMZXZlbCgpPC9jb2RlPiBtZXRob2QgcmV0dXJucyB3ZSBpbml0aWF0ZSB0aGUgb3V0cHV0Ci0gICAgZG9jdW1lbnQgYnkgY2FsbGluZyA8Y29kZT5zdGFydERvY3VtZW50KCk8L2NvZGU+IG9uIHRoZSBzdXBwbGllZCBvdXRwdXQKLSAgICBoYW5kbGVyIG9iamVjdC4gV2UgdGhlbiBjYWxsIDxjb2RlPmFwcGx5VGVtcGxhdGVzKCk8L2NvZGU+IHRvIGdldCB0aGUgYWN0dWFsCi0gICAgb3V0cHV0IGNvbnRlbnRzLCBiZWZvcmUgd2UgY2xvc2UgdGhlIG91dHB1dCBkb2N1bWVudCBieSBjYWxsaW5nCi0gICAgPGNvZGU+ZW5kRG9jdW1lbnQoKTwvY29kZT4gb24gdGhlIG91dHB1dCBoYW5kbGVyLjwvcD4KLQotICAgIDxwPjxjb2RlPnB1YmxpYyB2b2lkIHRvcExldmVsKERPTSwgTm9kZUl0ZXJhdG9yLCBUcmFuc2xldE91dHB1dEhhbmRsZXIpOzwvY29kZT48L3A+Ci0KLSAgICA8cD5UaGlzIG1ldGhvZCBoYW5kbGVzIGFsbCBvZiB0aGVzZSB0b3AtbGV2ZWwgZWxlbWVudHM6PC9wPgotICAgIDx1bD4KLSAgICAgIDxsaT48Y29kZT4mbHQ7eHNsOm91dHB1dCZndDs8L2NvZGU+PC9saT4KLSAgICAgIDxsaT48Y29kZT4mbHQ7eHNsOmRlY2ltYWwtZm9ybWF0Jmd0OzwvY29kZT48L2xpPgotICAgICAgPGxpPjxjb2RlPiZsdDt4c2w6a2V5Jmd0OzwvY29kZT48L2xpPgotICAgICAgPGxpPjxjb2RlPiZsdDt4c2w6cGFyYW0mZ3Q7PC9jb2RlPiAoZm9yIGdsb2JhbCBwYXJhbWV0ZXJzKTwvbGk+Ci0gICAgICA8bGk+PGNvZGU+Jmx0O3hzbDp2YXJpYWJsZSZndDs8L2NvZGU+IChmb3IgZ2xvYmFsIHZhcmlhYmxlcyk8L2xpPgotICAgIDwvdWw+Ci0KLSAgICA8cD48Y29kZT5wdWJsaWMgdm9pZCBhcHBseVRlbXBsYXRlcyhET00sIE5vZGVJdGVyYXRvciwgVHJhbnNsZXRPdXRwdXRIYW5kbGVyKTs8L2NvZGU+PC9wPgotCi0gICAgPHA+VGhpcyBpcyB0aGUgbWV0aG9kIHRoYXQgcHJvZHVjZXMgdGhlIGFjdHVhbCBvdXRwdXQuIEl0cyBjZW50cmFsIGVsZW1lbnQKLSAgICBpcyBhIGJpZyA8Y29kZT5zd2l0Y2goKTwvY29kZT4gc3RhdGVtZW50IHRoYXQgaXMgdXNlZCB0byBjaG9vc2UgdGhlIGF2YWlsYWJsZQotICAgIHRlbXBsYXRlcyBmb3IgdGhlIHZhcmlvdXMgbm9kZSBpbiB0aGUgaW5wdXQgZG9jdW1lbnQuIFNlZSB0aGUgY2hhcHRlcgotICAgIDxsaW5rIGFuY2hvcj0ibWFpbmxvb3AiPk1haW4gUHJvZ3JhbSBMb29wPC9saW5rPiBmb3IgZGV0YWlscyBvbiB0aGlzIG1ldGhvZC48L3A+Ci0KLSAgICA8cD48Y29kZT5wdWJsaWMgdm9pZCAmbHQ7aW5pdCZndDsgKCk7PC9jb2RlPjwvcD4KLSAgICA8YW5jaG9yIG5hbWU9Im5hbWVzYXJyYXkiLz4KLSAgICA8cD5UaGUgdHJhbnNsZXQncyBjb25zdHJ1Y3RvciBpbml0aWFsaXplcyBhIHRhYmxlCi0gICAgb2YgYWxsIHRoZSBlbGVtZW50cyB3ZSB3YW50IHRvIHNlYXJjaCBmb3IgaW4gdGhlIFhNTCBpbnB1dCBkb2N1bWVudC4KLSAgICBUaGlzIHRhYmxlIGlzIGNhbGxlZCB0aGUgPGNvZGU+bmFtZXNBcnJheTwvY29kZT4gYW5kIGl0IGlzIHBhc3NlZCB0byB0aGUgRE9NCi0gICAgaG9sZGluZyB0aGUgaW5wdXQgWE1MIGRvY3VtZW50LjwvcD4KLQotICAgIDxwPlRoZSBjb25zdHJ1Y3RvciBhbHNvIGluaXRpYWxpemVzIGFueSA8Y29kZT5EZWNpbWFsRm9ybWF0U3ltYm9sPC9jb2RlPgotICAgIG9iamVjdHMgdGhhdCBhcmUgdXNlZCB0byBmb3JtYXQgbnVtYmVycyBiZWZvcmUgcGFzc2luZyB0aGVtIHRvIHRoZQotICAgIG91dHB1dCBoYW5kbGVyLjwvcD4KLQotICAgIDxwPjxjb2RlPnB1YmxpYyBib29sZWFuIHN0cmlwU3BhY2UoaW50IG5vZGVUeXBlKTs8L2NvZGU+PC9wPgotCi0gICAgPHA+VGhpcyBtZXRob2QgaXMgb25seSBwcmVzZW50IGlmIGFueSA8Y29kZT4mbHQ7eHNsOnN0cmlwLXNwYWNlJmd0OzwvY29kZT4gb3IKLSAgICA8Y29kZT4mbHQ7eHNsOnByZXNlcnZlLXNwYWNlJmd0OzwvY29kZT4gZWxlbWVudHMgYXJlIHByZXNlbnQgaW4gdGhlIHN0eWxlc2hlZXQuCi0gICAgSWYgdGhhdCBpcyB0aGUgY2FzZSwgdGhlIHRyYW5zbGV0IGltcGxlbWVudHMgdGhlCi0gICAgPGNvZGU+U3RyaXBXaGl0ZXNwYWNlRmlsdGVyPC9jb2RlPiBpbnRlcmZhY2UgYnkgY29udGFpbmluZyB0aGlzIG1ldGhvZC48L3A+Ci0KLSAgICA8L3MyPjxhbmNob3IgbmFtZT0idHlwZXMiLz4KLSAgICA8czIgdGl0bGU9IkV4dGVybmFsL2ludGVybmFsIHR5cGUgbWFwcGluZyI+Ci0KLSAgICA8YW5jaG9yIG5hbWU9ImV4dGVybmFsLXR5cGVzIi8+Ci0KLSAgICA8cD5UaGlzIGlzIHRoZSB2ZXJ5IGNvcmUgb2YgWFNMIHRyYW5zZm9ybWF0aW9uczogPGVtPlJlYWQgY2FyZWZ1bGx5ISEhPC9lbT48L3A+Ci0KLSAgICA8cD5FdmVyeSBub2RlIGluIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQocykgaXMgYXNzaWduZWQgYSB0eXBlIGJ5IHRoZQotICAgIERPTSBidWlsZGVyIGNsYXNzLiBUaGlzIHR5cGUgaXMgYW4gaW50ZWdlciB2YWx1ZSB3aGljaCByZXByZXNlbnRzIHRoZQotICAgIGVsZW1lbnQsIHNvIHRoYXQgZm9yIGluc3RhbmNlIGFsbCA8Y29kZT4mbHQ7Ym9iJmd0OzwvY29kZT4gZWxlbWVudHMgaW4gdGhlCi0gICAgaW5wdXQgZG9jdW1lbnQgd2lsbCBiZSBnaXZlbiB0eXBlIDxyZWY+NzwvcmVmPiBhbmQgY2FuIGJlIHJlZmVycmVkIHRvIGJ5IHVzaW5nCi0gICAgdGhhdCBpbnRlZ2VyLiBUaGVzZSB0eXBlcyBjYW4gYmUgdXNlZCBmb3IgbG9va3VwcyBpbiB0aGUKLSAgICA8bGluayBhbmNob3I9Im5hbWVzYXJyYXkiPm5hbWVzQXJyYXk8L2xpbms+IHRhYmxlIHRvIGdldCB0aGUgYWN0dWFsCi0gICAgZWxlbWVudCBuYW1lIChpbiB0aGlzIGNhc2UgImJvYiIpLiBUaGVzZSB0eXBlcyBhcmUgcmVmZXJyZWQgdG8gYXMKLSAgICA8ZW0+ZXh0ZXJuYWwgdHlwZXM8L2VtPiBvciA8ZW0+RE9NIHR5cGVzPC9lbT4sIGFzIHRoZXkgYXJlIHR5cGVzIGtub3duIG9ubHkKLSAgICB0byB0aGUgRE9NIGFuZCB0aGUgRE9NIGJ1aWxkZXIuPC9wPgotCi0gICAgPGFuY2hvciBuYW1lPSJpbnRlcm5hbC10eXBlcyIvPgotCi0gICAgPHA+U2ltaWxhcmx5IHRoZSB0cmFuc2xldCBhc3NpZ25lcyB0eXBlcyB0byBhbGwgZWxlbWVudCBhbmQgYXR0cmlidXRlIG5hbWVzCi0gICAgdGhhdCBhcmUgcmVmZXJlbmNlZCBpbiB0aGUgc3R5bGVzaGVldC4gVGhlc2UgdHlwZXMgYXJlIHJlZmVycmVkIHRvIGFzCi0gICAgPGVtPmludGVybmFsIHR5cGVzPC9lbT4gb3IgPGVtPnRyYW5zbGV0IHR5cGVzPC9lbT4uPC9wPgotCi0gICAgPHA+SXQgaXMgbm90IHZlcnkgcHJvYmFibGUgdGhhdCB0aGVyZSB3aWxsIGJlIGEgb25lLXRvLW9uZSBtYXBwaW5nIGJldHdlZW4KLSAgICBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgdHlwZXMuIFRoZXJlIHdpbGwgbW9zdCBvZnRlbiBiZSBlbGVtZW50cyBpbiB0aGUgRE9NCi0gICAgKGllLiB0aGUgaW5wdXQgZG9jdW1lbnQpIHRoYXQgYXJlIG5vdCBtZW50aW9uZWQgaW4gdGhlIHN0eWxlc2hlZXQsIGFuZAotICAgIHRoZXJlIGNvdWxkIGJlIGVsZW1lbnRzIGluIHRoZSBzdHlsZXNoZWV0IHRoYXQgZG8gbm90IG1hdGNoIGFueSBlbGVtZW50cwotICAgIGluIHRoZSBET00uIEhlcmUgaXMgYW4gZXhhbXBsZTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgICAmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLSAgICAgICZsdDt4c2w6c3R5bGVzaGVldCB2ZXJzaW9uPSIxLjAiIHhtbG5zOnhzbD0iYmxhaGJsYWhibGFoIiZndDsKLQotICAgICAgJmx0O3hzbDp0ZW1wbGF0ZSBtYXRjaD0iLyImZ3Q7Ci0gICAgICAgICZsdDt4c2w6Zm9yLWVhY2ggc2VsZWN0PSIvL0IiJmd0OwotICAgICAgICAgICZsdDt4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0iLiIgLyZndDsKLSAgICAgICAgJmx0Oy94c2w6Zm9yLWVhY2gmZ3Q7Ci0gICAgICAgICZsdDt4c2w6Zm9yLWVhY2ggc2VsZWN0PSJDIiZndDsKLSAgICAgICAgICAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9Ii4iIC8mZ3Q7Ci0gICAgICAgICZsdDsveHNsOmZvci1lYWNoJmd0OwotICAgICAgICAmbHQ7eHNsOmZvci1lYWNoIHNlbGVjdD0iQS9CIiZndDsKLSAgICAgICAgICAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9Ii4iIC8mZ3Q7Ci0gICAgICAgICZsdDsveHNsOmZvci1lYWNoJmd0OwotICAgICAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0KLSAgICAmbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotPC9zb3VyY2U+Ci0KLSAgICA8cD5JbiB0aGlzIHN0eWxlc2hlZXQgd2UgYXJlIGxvb2tpbmcgZm9yIGVsZW1lbnRzIDxjb2RlPiZsdDtCJmd0OzwvY29kZT4sCi0gICAgPGNvZGU+Jmx0O0MmZ3Q7PC9jb2RlPiBhbmQgPGNvZGU+Jmx0O0EmZ3Q7PC9jb2RlPi4gRm9yIHRoaXMgZXhhbXBsZSB3ZSBjYW4gYXNzdW1lCi0gICAgdGhhdCB0aGVzZSBlbGVtZW50IHR5cGVzIHdpbGwgYmUgYXNzaWduZWQgdGhlIHZhbHVlcyAwLCAxIGFuZCAyLiBOb3csIGxldHMKLSAgICBzYXkgd2UgYXJlIHRyYW5zZm9ybWluZyB0aGlzIFhNTCBkb2N1bWVudDo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgICAmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLQotICAgICAgJmx0O0EmZ3Q7Ci0gICAgICAgIFRoZSBjcm9jb2RpbGUgY3JpZWQ6Ci0gICAgICAgICZsdDtGJmd0O2ZvbyZsdDsvRiZndDsKLSAgICAgICAgJmx0O0ImZ3Q7YmFyJmx0Oy9CJmd0OwotICAgICAgICAmbHQ7QiZndDtiYXombHQ7L0ImZ3Q7Ci0gICAgICAmbHQ7L0EmZ3Q7Ci08L3NvdXJjZT4KLQotICAgIDxwPlRoaXMgWE1MIGRvY3VtZW50IGhhcyB0aGUgZWxlbWVudHMgPGNvZGU+Jmx0O0EmZ3Q7PC9jb2RlPiwKLSAgICA8Y29kZT4mbHQ7QiZndDs8L2NvZGU+IGFuZCA8Y29kZT4mbHQ7RiZndDs8L2NvZGU+LCB3aGljaCB3ZSBhc3N1bWUgYXJlIGFzc2lnbmVkIHRoZQotICAgIHR5cGVzIDcsIDggYW5kIDkgcmVzcGVjdGl2ZWx5ICAodGhlIG51bWJlcnMgYmVsb3cgdGhhdCBhcmUgYXNzaWduZWQgZm9yCi0gICAgc3BlY2lmaWMgZWxlbWVudCB0eXBlcywgc3VjaCBhcyB0aGUgcm9vdCBub2RlLCB0ZXh0IG5vZGVzLCBldGMuKS4gVGhpcwotICAgIGNhdXNlcyBhIG1pc21hdGNoIGJldHdlZW4gdGhlIHR5cGUgdXNlZCBmb3IgPGNvZGU+Jmx0O0ImZ3Q7PC9jb2RlPiBpbiB0aGUKLSAgICB0cmFuc2xldCBhbmQgdGhlIHR5cGUgdXNlZCBmb3IgPGNvZGU+Jmx0O0ImZ3Q7PC9jb2RlPiBpbiB0aGUgRE9NLiBUaAotICAgIERPTUFkYXB0ZXIgY2xhc3MgKHdoaWNoIG1lZGlhdGVzIGJldHdlZW4gdGhlIERPTSBhbmQgdGhlIHRyYW5zbGV0KSBoYXMgYmVlbgotICAgIGdpdmVuIHR3byB0YWJsZXMgZm9yIGNvbnZlcnRpbnQgYmV0d2VlbiB0aGUgdHdvIHR5cGVzOyA8Y29kZT5tYXBwaW5nPC9jb2RlPiBmb3IKLSAgICBtYXBwaW5nIGZyb20gaW50ZXJuYWwgdG8gZXh0ZXJuYWwgdHlwZXMsIGFuZCA8Y29kZT5yZXZlcnNlTWFwcGluZzwvY29kZT4gZm9yCi0gICAgdGhlIG90aGVyIHdheSBhcm91bmQuPC9wPgotCi0gICAgPHA+VGhlIHRyYW5zbGV0IGNvbnRhaW5zIGEgPGNvZGU+U3RyaW5nW108L2NvZGU+IGFycmF5IGNhbGxlZAotICAgIDxjb2RlPm5hbWVzQXJyYXk8L2NvZGU+LiBUaGlzIGFycmF5IHdpbGwgY29udGFpbiBhbGwgdGhlIGVsZW1lbnQgYW5kIGF0dHJpYnV0ZQotICAgIG5hbWVzIHRoYXQgd2VyZSByZWZlcmVuY2VkIGluIHRoZSBzdHlsZXNoZWV0LiBJbiBvdXIgZXhhbXBsZSwgdGhpcyBhcnJheQotICAgIHdvdWxkIGNvbnRhaW4gdGhlc2Ugc3RyaW5nIChpbiB0aGlzIHNwZWNpZmljIG9yZGVyKTogJnF1b3Q7QiZxdW90OywgCi0gICAgJnF1b3Q7QyZxdW90OyBhbmQgJnF1b3Q7QSZxdW90Oy4gVGhpcyBhcnJheSBpcyBwYXNzZWQgYXMgb25lIG9mIHRoZQotICAgIHBhcmFtZXRlcnMgdG8gdGhlIERPTSBhZGFwdGVyIGNvbnN0cnVjdG9yICh0aGUgb3RoZXIgYWRhcHRlciBpcyB0aGUgRE9NCi0gICAgaXRzZWxmKS4gVGhlIERPTSBhZGFwdGVyIHBhc3NlcyB0aGlzIHRhYmxlIG9uIHRvIHRoZSBET00uIFRoZSBET00gaGFzCi0gICAgYSBoYXNodGFibGUgdGhhdCBtYXBzIGtub3duIGVsZW1lbnQgbmFtZXMgdG8gZXh0ZXJuYWwgdHlwZXMuIFRoZSBET00gZ29lcwotICAgIHRocm91Z2ggdGhlIDxjb2RlPm5hbWVzQXJyYXk8L2NvZGU+IGZyb20gdGhlIERPTSBzZXF1ZW50aWFsbHksIGxvb2tzIHVwIGVhY2gKLSAgICBuYW1lIGluIHRoZSBoYXNodGFibGUsIGFuZCBpcyB0aGVuIGFibGUgdG8gbWFwIHRoZSBpbnRlcm5hbCB0eXBlIHRvIGFuCi0gICAgZXh0ZXJuYWwgdHlwZS4gVGhlIHJlc3VsdCBpcyB0aGVuIHBhc3NlZCBiYWNrIHRvIHRoZSBET00gYWRhcHRlci48L3A+Ci0KLSAgICA8cD5UaGUgcmV2ZXJzZSBpcyBkb25lIGZvciBleHRlcm5hbCB0eXBlcy4gRXh0ZXJuYWwgdHlwZXMgdGhhdCBhcmUgbm90Ci0gICAgaW50ZXJlc3RpbmcgZm9yIHRoZSB0cmFuc2xldCAoc3VjaCBhcyB0aGUgdHlwZSBmb3IgPGNvZGU+Jmx0O0YmZ3Q7PC9jb2RlPgotICAgIGVsZW1lbnRzIGluIHRoZSBleGFtcGxlIGFib3ZlKSBhcmUgbWFwcGVkIHRvIGEgZ2VuZXJpYyA8Y29kZT4iRUxFTUVOVCI8L2NvZGU+Ci0gICAgdHlwZSAzLCBhbmQgYXJlIG1vcmUgb3IgbGVzcyBpZ25vcmVkIGJ5IHRoZSB0cmFuc2xldC48L3A+Ci0KLSAgICA8cD5JdCBpcyBpbXBvcnRhbnQgdGhhdCB3ZSBzZXBhcmF0ZSB0aGUgRE9NIGZyb20gdGhlIHRyYW5zbGV0LiBJbiBzZXZlcmFsCi0gICAgY2FzZXMgd2Ugd2FudCB0aGUgRE9NIGFzIGEgc3RydWN0dXJlIGNvbXBsZXRlbHkgaW5kZXBlbmRlbnQgZnJvbSB0aGUKLSAgICB0cmFuc2xldCAtIGV2ZW4gdGhvdWdoIHRoZSBET00gaXMgYSBzdHJ1Y3R1cmUgaW50ZXJuYWwgdG8gWFNMVEMuIE9uZSBzdWNoCi0gICAgY2FzZSBpcyB3aGVuIHRyYW5zZm9ybWF0aW9ucyBhcmUgb2ZmZXJlZCBieSBhIHNlcnZsZXQgYXMgYSB3ZWIgc2VydmljZS4KLSAgICBBbnkgRE9NIHRoYXQgaXMgYnVpbHQgc2hvdWxkIHBvdGVudGlhbGx5IGJlIHN0b3JlZCBpbiBhIGNhY2hlIGFuZCBtYWRlCi0gICAgYXZhaWxhYmxlIGZvciBzaW11bHRhbmVvdXMgYWNjZXNzIGJ5IHNldmVyYWwgdHJhbnNsZXQvc2VydmxldCBjb3VwbGVzLjwvcD4KLQotICAgIDxwPjxpbWcgc3JjPSJydW50aW1lX3R5cGVfbWFwcGluZy5naWYiIGFsdD0icnVudGltZV90eXBlX21hcHBpbmcuZ2lmIi8+PC9wPgotICAgIDxwPjxyZWY+RmlndXJlIDE6IFR3byB0cmFuc2xldHMgYWNjZXNzaW5nIGEgc2luZ2xlIGRvbSB1c2luZyBkaWZmZXJlbnQgdHlwZSBtYXBwaW5nczwvcmVmPjwvcD4KLQotICAgIDwvczI+PGFuY2hvciBuYW1lPSJtYWlubG9vcCIvPgotICAgIDxzMiB0aXRsZT0iTWFpbiBwcm9ncmFtIGxvb3AiPgotCi0gICAgPHA+VGhlIG1haW4gbG9vcCBpbiB0aGUgdHJhbnNsZXQgaXMgZm91bmQgaW4gdGhlIDxjb2RlPmFwcGx5VGVtcGxhdGVzKCk8L2NvZGU+Ci0gICAgbWV0aG9kLiBUaGlzIG1ldGhvZCBnb2VzIHRocm91Z2ggdGhlc2Ugc3RlcHM6PC9wPgotCi0gICAgPHVsPgotICAgICAgPGxpPgotICAgICAgICBHZXQgdGhlIG5leHQgbm9kZSBmcm9tIHRoZSBub2RlIGl0ZXJhdG9yCi0gICAgICA8L2xpPgotICAgICAgPGxpPgotICAgICAgICBHZXQgdGhlIGludGVybmFsIHR5cGUgb2YgdGhpcyBub2RlLiBUaGUgRE9NQWRhcHRlciBvYmplY3QgaG9sZHMgdGhlCi0gICAgICAgIGludGVybmFsL2V4dGVybmFsIHR5cGUgbWFwcGluZyB0YWJsZSwgYW5kIGl0IHdpbGwgc3VwcGx5IHRoZSB0cmFuc2xldAotICAgICAgICB3aXRoIHRoZSBpbnRlcm5hbCB0eXBlIG9mIHRoZSBjdXJyZW50IG5vZGUuCi0gICAgICA8L2xpPgotICAgICAgPGxpPgotICAgICAgICBFeGVjdXRlIGEgc3dpdGNoIHN0YXRlbWVudCBvbiB0aGUgaW50ZXJuYWwgbm9kZSB0eXBlLiBUaGVyZSB3aWxsIGJlCi0gICAgICAgIG9uZSAiY2FzZSIgbGFiZWwgZm9yIGVhY2ggcmVjb2duaXNlZCBub2RlIHR5cGUgLSB0aGlzIGluY2x1ZGVzIHRoZQotICAgICAgICBmaXJzdCA3IGludGVybmFsIG5vZGUgdHlwZXMuCi0gICAgICA8L2xpPgotICAgIDwvdWw+Ci0KLSAgICA8cD5UaGUgcm9vdCBub2RlIHdpbGwgaGF2ZSBpbnRlcm5hbCB0eXBlIDAgYW5kIHdpbGwgY2F1c2UgYW55IGluaXRpYWwKLSAgICBsaXRlcmFsIGVsZW1lbnRzIHRvIGJlIG91dHB1dC4gVGV4dCBub2RlcyB3aWxsIGhhdmUgaW50ZXJuYWwgbm9kZSB0eXBlIDEKLSAgICBhbmQgd2lsbCBzaW1wbHkgYmUgZHVtcGVkIHRvIHRoZSBvdXRwdXQgaGFuZGxlci4gVW5yZWNvZ25pemVkIGVsZW1lbnRzCi0gICAgd2lsbCBoYXZlIGludGVybmFsIG5vZGUgdHlwZSAzIGFuZCB3aWxsIGJlIGdpdmVuIHRoZSBkZWZhdWx0IHRyZWF0bWVudAotICAgIChhIG5ldyBpdGVyYXRvciBpcyBjcmVhdGVkIGZvciB0aGUgbm9kZSdzIGNoaWxkcmVuLCBhbmQgdGhpcyBpdGVyYXRvcgotICAgIGlzIHBhc3NlZCB3aXRoIGEgcmVjdXJzaXZlIGNhbGwgdG8gPGNvZGU+YXBwbHlUZW1wbGF0ZXMoKTwvY29kZT4pLgotICAgIFVucmVjb2duaXNlZCBhdHRyaWJ1dGUgbm9kZXMgKHR5cGUgNCkgd2lsbCBiZSBoYW5kbGVkIGxpa2UgdGV4dCBub2Rlcy4KLSAgICBUaGUgPGNvZGU+c3dpdGNoKCk8L2NvZGU+IHN0YXRlbWVudCBpbiA8Y29kZT5hcHBseVRlbXBsYXRlczwvY29kZT4gd2lsbCB0aGVyZWJ5Ci0gICAgbG9vayBzb21ldGhpbmcgbGlrZSB0aGlzOjwvcD4KLQotPHNvdXJjZT4KLSAgICAgICAgcHVibGljIHZvaWQgYXBwbHlUZW1wbGF0ZXMoRE9NIGRvbSwgTm9kZUl0ZXJhdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2xldE91dHB1dEhhbmRsZXIgaGFuZGxlcikgewotCi0gICAgICAgICAgICAvLyBnZXQgbm9kZXMgZnJvbSBpdGVyYXRvcgotICAgICAgICAgICAgd2hpbGUgKChub2RlID0gaXRlcmF0b3IubmV4dCgpKSAhPSBFTkQpIHsKLSAgICAgICAgICAgICAgICAvLyBnZXQgaW50ZXJuYWwgbm9kZSB0eXBlCi0gICAgICAgICAgICAgICAgc3dpdGNoKERPTS5nZXRUeXBlKG5vZGUpKSB7Ci0KLSAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIHJvb3QKLSAgICAgICAgICAgICAgICAgICAgb3V0cHV0UHJlYWJsZShoYW5kbGVyKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSAxOiAvLyB0ZXh0Ci0gICAgICAgICAgICAgICAgICAgIERPTS5jaGFyYWN0ZXJzKG5vZGUsaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgMzogLy8gdW5yZWNvZ25pc2VkIGVsZW1lbnQKLSAgICAgICAgICAgICAgICAgICAgTm9kZUl0ZXJhdG9yIG5ld0l0ZXJhdG9yID0gRE9NLmdldENoaWxkcmVuKG5vZGUpOwotICAgICAgICAgICAgICAgICAgICBhcHBseVRlbXBsYXRlcyhET00sbmV3SXRlcmF0b3IsaGFuZGxlcik7Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgIGNhc2UgNDogLy8gdW5yZWNvZ25pc2VkIGF0dHJpYnV0ZQotICAgICAgICAgICAgICAgICAgICBET00uY2hhcmFjdGVycyhub2RlLGhhbmRsZXIpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBjYXNlIDc6IC8vIGVsZW1lbnRzIG9mIHR5cGUgJmx0O0ImZ3Q7Ci0gICAgICAgICAgICAgICAgICAgIHNvbWVDb21waWxlZENvZGUoKTsKLSAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgY2FzZSA4OiAvLyBlbGVtZW50cyBvZiB0eXBlICZsdDtDJmd0OwotICAgICAgICAgICAgICAgICAgICBvdGhlckNvbXBpbGVkQ29kZSgpOwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLTwvc291cmNlPgotCi0gICAgPHA+RWFjaCByZWNvZ25pc2VkIGVsZW1lbnQgd2lsbCBoYXZlIGl0cyBvd24gcGllY2Ugb2YgY29tcGlsZWQgY29kZS48L3A+Ci0KLSAgICA8cD5Ob3RlIHRoYXQgZWFjaCAiY2FzZSIgd2lsbCBub3QgbGVhZCBkaXJlY3RseSB0byBhIHNpbmdsZSB0ZW1wbGF0ZS4KLSAgICBUaGVyZSBtYXkgYmUgc2V2ZXJhbCB0ZW1wbGF0ZXMgdGhhdCBtYXRjaCBub2RlIHR5cGUgNwotICAgIChzYXkgPGNvZGU+Jmx0O0ImZ3Q7PC9jb2RlPikuIEluIHRoZSBzYW1wbGUgc3R5bGVzaGVldCBpbiB0aGUgcHJldmlvdXMgY2hhcHRlcgotICAgIHdlIGhhdmUgdG8gdGVtcGxhdGVzIHRoYXQgd291bGQgbWF0Y2ggYSBub2RlIDxjb2RlPiZsdDtCJmd0OzwvY29kZT4uIFdlIGhhdmUKLSAgICBvbmUgPGNvZGU+bWF0Y2g9Ii8vQiI8L2NvZGU+IChtYXRjaCBqdXN0IGFueSA8Y29kZT4mbHQ7QiZndDs8L2NvZGU+IGVsZW1lbnQpIGFuZAotICAgIG9uZSA8Y29kZT5tYXRjaD0iQS9CIjwvY29kZT4gKG1hdGNoIGEgPGNvZGU+Jmx0O0ImZ3Q7PC9jb2RlPiBlbGVtZW50IHRoYXQgaXMgYQotICAgIGNoaWxkIG9mIGEgPGNvZGU+Jmx0O0EmZ3Q7PC9jb2RlPiBlbGVtZW50KS4gSW4gdGhpcyBjYXNlIHdlIHdvdWxkIGhhdmUgdG8KLSAgICBjb21waWxlIGNvZGUgdGhhdCBmaXJzdCBnZXRzIHRoZSB0eXBlIG9mIHRoZSBjdXJyZW50IG5vZGUncyBwYXJlbnQsIGFuZAotICAgIHRoZW4gY29tcGFyZWQgdGhpcyB0eXBlIHdpdGggdGhlIHR5cGUgZm9yIDxjb2RlPiZsdDtBJmd0OzwvY29kZT4uIElmIHRoZXJlIHdhcwotICAgIG5vIG1hdGNoIHdlIHdpbGwgaGF2ZSBleGVjdXRlZCB0aGUgZmlyc3QgPGNvZGU+Jmx0O3hzbDpmb3ItZWFjaCZndDs8L2NvZGU+Ci0gICAgZWxlbWVudCwgYnV0IGlmIHRoZXJlIHdhcyBhIG1hdGNoIHdlIHdpbGwgaGF2ZSBleGVjdXRlZCB0aGUgbGFzdCBvbmUuCi0gICAgQ29uc2VxdWVudGFsbHksIHRoZSBjb21waWxlciB3aWxsIGdlbmVyYXRlIHRoZSBmb2xsb3dpbmcgY29kZTo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgICAgIHN3aXRjaChET00uZ2V0VHlwZShub2RlKSkgewotICAgICAgICAgIDoKLSAgICAgICAgICA6Ci0gICAgICAgIGNhc2UgNzogLy8gZWxlbWVudHMgb2YgdHlwZSAmbHQ7QiZndDsKLSAgICAgICAgICAgIGludCBwYXJlbnQgPSBET00uZ2V0UGFyZW50KG5vZGUpOwotICAgICAgICAgICAgaWYgKERPTS5nZXRUeXBlKHBhcmVudCkgPT0gOSkgLy8gdHlwZSA5ID0gZWxlbWVudHMgJmx0O0EmZ3Q7Ci0gICAgICAgICAgICAgICAgc29tZUNvbXBpbGVkQ29kZSgpOwotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIGV2ZW5PdGhlckNvbXBpbGVkQ29kZSgpOwotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgOgotICAgICAgICAgIDoKLSAgICAgICAgfQotPC9zb3VyY2U+Ci0KLSAgICA8cD5XZSBjb3VsZCBkbyB0aGUgc2FtZSBmb3IgbmFtZXNwYWNlcywgdGhhdCBpcywgYXNzaWduIGEgbnVtZXJpYyB2YWx1ZQotICAgIHRvIGV2ZXJ5IG5hbWVzcGFjZSB0aGF0IGlzIHJlZmVyZW5jZXMgaW4gdGhlIHN0eWxlc2hlZXQsIGFuZCB1c2UgYW4KLSAgICA8Y29kZT4iaWYiPC9jb2RlPiBzdGF0ZW1lbnQgZm9yIGVhY2ggbmFtZXNwYWNlIHRoYXQgbmVlZHMgdG8gYmUgY2hlY2tlZCBmb3IKLSAgICBlYWNoIHR5cGUuIExldHMgc2F5IHdlIGhhZCBhIHN0eWxlc2hlZXQgbGlrZSB0aGlzOjwvcD4KLQotPHNvdXJjZT4KLSAgICAgICZsdDs/eG1sIHZlcnNpb249IjEuMCI/Jmd0OwotICAgICAgJmx0O3hzbDpzdHlsZXNoZWV0IHZlcnNpb249IjEuMCIgeG1sbnM6eHNsPSJibGFoYmxhaGJsYWgiJmd0OwotCi0gICAgICAmbHQ7eHNsOnRlbXBsYXRlIG1hdGNoPSIvIgotICAgICAgICAgIHhtbG5zOmZvbz0iaHR0cDovL2Zvby5jb20vc3BlYyIKLSAgICAgICAgICB4bWxuczpiYXI9Imh0dHA6Ly9iYXIubmV0L3JlZiImZ3Q7Ci0gICAgICAgICZsdDt4c2w6Zm9yLWVhY2ggc2VsZWN0PSJmb286QSImZ3Q7Ci0gICAgICAgICAgJmx0O3hzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSIuIiAvJmd0OwotICAgICAgICAmbHQ7L3hzbDpmb3ItZWFjaCZndDsKLSAgICAgICAgJmx0O3hzbDpmb3ItZWFjaCBzZWxlY3Q9ImJhcjpBIiZndDsKLSAgICAgICAgICAmbHQ7eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9Ii4iIC8mZ3Q7Ci0gICAgICAgICZsdDsveHNsOmZvci1lYWNoJmd0OwotICAgICAgJmx0Oy94c2w6dGVtcGxhdGUmZ3Q7Ci0KLSAgICAmbHQ7L3hzbDpzdHlsZXNoZWV0Jmd0OwotPC9zb3VyY2U+Ci0KLSAgICA8cD5BbmQgYSBzdHlsZXNoZWV0IGxpa2UgdGhpczo8L3A+Ci0KLTxzb3VyY2U+Ci0gICAgICAmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiPyZndDsKLQotICAgICAgJmx0O0RPQwotICAgICAgICAgIHhtbG5zOmZvbz0iaHR0cDovL2Zvby5jb20vc3BlYyIKLSAgICAgICAgICB4bWxuczpiYXI9Imh0dHA6Ly9iYXIubmV0L3JlZiImZ3Q7Ci0gICAgICAgICZsdDtmb286QSZndDtJbiBmb28gbmFtZXNwYWNlJmx0Oy9mb286QSZndDsKLSAgICAgICAgJmx0O2JhcjpBJmd0O0luIGJhciBuYW1lc3BhY2UmbHQ7L2JhcjpBJmd0OwotICAgICAgJmx0Oy9ET0MmZ3Q7Ci08L3NvdXJjZT4KLQotICAgIDxwPldlIGNvdWxkIHN0aWxsIGtlZXAgdGhlIHNhbWUgdHlwZSBmb3IgYWxsIDxjb2RlPiZsdDtBJmd0OzwvY29kZT4gZWxlbWVudHMKLSAgICByZWdhcmRsZXNzIG9mIHdoYXQgbmFtZXNwYWNlIHRoZXkgYXJlIGluLCBhbmQgdXNlIHRoZSBzYW1lIDxjb2RlPiJpZiI8L2NvZGU+Ci0gICAgc3RydWN0dXJlIHdpdGhpbiB0aGUgPGNvZGU+c3dpdGNoKCk8L2NvZGU+IHN0YXRlbWVudCBhYm92ZS4gVGhlIG90aGVyIG9wdGlvbgotICAgIGlzIHRvIGFzc2lnbiBkaWZmZXJlbnQgdHlwZXMgdG8gPGNvZGU+Jmx0O2ZvbzpBJmd0OzwvY29kZT4gYW5kCi0gICAgPGNvZGU+Jmx0O2JhcjpBJmd0OzwvY29kZT4gZWxlbWVudHMuPC9wPgotCi0gIDwvczI+Ci08L3MxPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfdHJheC54bWwgYi94ZG9jcy9zb3VyY2VzL3hzbHRjL3hzbHRjX3RyYXgueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxNGViODAxLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdGNfdHJheC54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw2OTEgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PgotPCFET0NUWVBFIHMxIFNZU1RFTSAiLi4vLi4vc3R5bGUvZHRkL2RvY3VtZW50LmR0ZCI+Ci08IS0tIAotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDEgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwotICogcmVzZXJ2ZWQuCi0gKgotICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0Ci0gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKLSAqIGFyZSBtZXQ6Ci0gKgotICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKLSAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KLSAqCi0gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAotICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCi0gKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCi0gKiAgICBkaXN0cmlidXRpb24uCi0gKgotICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sCi0gKiAgICBpZiBhbnksIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgotICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCi0gKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKLSAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKLSAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCi0gKgotICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAotICogICAgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi0gKiAgICBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgotICoKLSAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAotICogICAgbm9yIG1heSAiQXBhY2hlIiBhcHBlYXIgaW4gdGhlaXIgbmFtZSwgd2l0aG91dCBwcmlvciB3cml0dGVuCi0gKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLSAqCi0gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECi0gKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwotICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKLSAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKLSAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKLSAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKLSAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKLSAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKLSAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAotICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCi0gKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKLSAqIFNVQ0ggREFNQUdFLgotICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLSAqCi0gKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQotICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiBhbmQgd2FzCi0gKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMjAwMSwgU3VuCi0gKiBNaWNyb3N5c3RlbXMuLCBodHRwOi8vd3d3LnN1bi5jb20uICBGb3IgbW9yZQotICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCi0gKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCi0gLS0+Ci08czEgdGl0bGU9IlRoZSBUcmFuc2xldCBBUEkgJmFtcDsgVHJBWCI+Ci08cD48cmVmPkJ5PC9yZWY+IDxqdW1wIGhyZWY9Im1haWx0bzp0b2RkLm1pbGxlckBlYXN0LnN1bi5jb20iPkcuIFRvZGQgTWlsbGVyPC9qdW1wPiAtdXBkYXRlZCBNYXkgMTEsIDIwMDE8L3A+Ci08dWw+Ci0gIDxsaT48bGluayBhbmNob3I9ImFic3RyYWN0Ij5BYnN0cmFjdDwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJ0cmF4Ij5UckFYPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9ImludGVncmF0ZSI+VHJhbnNsZXQgSW50ZWdyYXRpb248L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0iZmFjdG9yeSI+U0FYVHJhbnNmb3JtZXJGYWN0b3J5IGZvciBUcmFuc2xldHM8L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0idHJhbnNmb3JtIj5BYnN0cmFjdFRyYW5zbGV0IHRyYW5zZm9ybSgpIG1ldGhvZDwvbGluaz48L2xpPgotICA8bGk+PGxpbmsgYW5jaG9yPSJjb25jbHVzaW9uIj5Db25jbHVzaW9uPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9ImFwcGVuZGl4Ij5BcHBlbmRpeDwvbGluaz48L2xpPiAgICAgIAotPC91bD4KLTxwPlNlZSBhbHNvOiA8anVtcCBocmVmPSIuLi94c2x0Y191c2FnZS5odG1sI2FwaSI+Q2FsbGluZyBYU0xUQyB3aXRoIHRoZSBUckFYL0pBWFAgQVBJPC9qdW1wPjwvcD4KLTxhbmNob3IgbmFtZT0iYWJzdHJhY3QiLz4KLTxzMiB0aXRsZT0iQWJzdHJhY3QiPgotPHA+VGhpcyBkb2N1bWVudCBkZXNjcmliZXMgd2hhdCBJIGhhdmUgc28gZmFyIGFzIGEgcHJvdG90eXBlIGZvciBpbnRlZ3JhdGluZwotVHJhbnNsZXRzIHdpdGggdGhlIEpBWFAgVHJBWC4gSW4gYSBudXRzaGVsbCwgYSBuZXcgVHJhbnNmb3JtZXIgZmFjdG9yeQotY2xhc3MgaGFzIGJlIHdyaXR0ZW4gdGhhdCBleHRlbmRzIHRoZSBKQVhQIFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBjbGFzcy4KLVRoZSBuZXdmYWN0b3J5IGRlbGl2ZXJzIFRyYW5zbGV0cyBhcyBUcmFuc2Zvcm1lcnMsIGFuZCBjcmVhdGVzIFRlbXBsYXRlcy4KLUNhbGxpbmcgdGhlIFRyYW5zZm9ybWVyIHRyYW5zZm9ybSgpIG1ldGhvZCB3aWxsIGNhdXNlIHRoZSBnaXZlbiBYTUwKLWRvY3VtZW50IHRvIGJlIHRyYW5zZm9ybWVkIGJ5IGEgdHJhbnNsZXQgdGhhdCBoYXMgYmVlbiBjb21waWxlZCBmcm9tIHRoZQotc3VwcGxpZWQgc3R5bGVzaGVldC4gVGhlIHN3aXRjaCB0aGF0IGRldGVybWluZXMgd2hhdCBYU0xUIHByb2Nlc3NvciBnZXRzCi10byB0cmFuc2Zvcm0gdGhlIFhNTCBkb2N1bWVudCBpcyBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgYSBKQVhQIHN5c3RlbQotcHJvcGVydHkgZm9yIHRoZSBUcmFuc2Zvcm1lcnMgZmFjdG9yeS48L3A+Ci08L3MyPjxhbmNob3IgbmFtZT0idHJheCIvPgotPHMyIHRpdGxlPSJUckFYIj4KLTxwPlRoZSBKYXZhIEFQSSBmb3IgWE1MIFByb2Nlc3NpbmcgKEpBWFApIGluY2x1ZGVzIGFuIFhTTFQgZnJhbWV3b3JrIGJhc2VkIG9uIHRoZQotVHJhbnNmb3JtYXRpb24gQVBJIGZvciBYTUwgKFRyQVgpLiBJbiBhIHR5cGljYWwgSkFYUCB0cmFuc2Zvcm1hdGlvbiBhcHBsaWNhdGlvbgotdGhlIHN0ZXBzIGludm9sdmVkIGluIHRyYW5zZm9ybWluZyBhbiBYTUwgZG9jdW1lbnQgd2l0aCBhbiBYU0xUIHN0eWxlc2hlZXQgYXJlOiAoMSkKLWNyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGNsYXNzLCAoMikgZnJvbSB0aGUgZmFjdG9yeSBpbnN0YW5jZSBhbmQKLWEgZ2l2ZW4gWFNMVCBzdHlsZXNoZWV0LCBjcmVhdGUgYSBuZXcgVHJhbnNmb3JtZXIgb2JqZWN0LCAoMykgY2FsbCB0aGUgVHJhbnNmb3JtZXIKLW9iamVjdHMgdHJhbnNmb3JtKCkgbWV0aG9kIG9uIGEgZ2l2ZW4gWE1MIGRvY3VtZW50IGFuZCBhIHNwZWNpZmllZCBSZXN1bHQgb2JqZWN0LgotQWx0ZXJuYXRpdmVseSwgb25lIGNvdWxkIGFsc28gYXNrIHRoZSBpbnN0YW5jZSBvZiB0aGUgVHJhbnNmb3JtZXJGYWN0b3J5IGZvcgotYSBUZW1wbGF0ZXMgb2JqZWN0IGdpdmVuIGFuIFhTTFQgc3R5bGVzaGVldC4gRnJvbSB0aGUgVGVtcGxhdGVzIG9iamVjdCwgYSBuZXcKLVRyYW5zZm9ybWVyIGNhbiBiZSBjcmVhdGVkLCBhbmQgYWdhaW4sIGl0cyB0cmFuc2Zvcm0oKSBtZXRob2QgY2FuIGJlIGNhbGxlZCB3aXRoCi1hbiBYTUwgZG9jdW1lbnQgYW5kIHNwZWNpZmllZCBSZXN1bHQgb2JqZWN0LjwvcD4KLTxwPlRoZSBjb2RlIGJlbG93IGlsbHVzdHJhdGVzIGEgc2ltcGxlIEpBWFAgdHJhbnNmb3JtYXRpb24gYXBwbGljYXRpb24gKFByb3RvLmphdmEpCi10aGF0IGNyZWF0ZXMgdGhlIFRyYW5zZm9ybWVyIGRpcmVjdGx5LjwvcD4KLTxzb3VyY2U+aW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVNvdXJjZTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1SZXN1bHQ7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKLQotcHVibGljIGNsYXNzIFByb3RvIHsKLSAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncyl7Ci0gICAgUHJvdG8gYXBwID0gbmV3IFByb3RvKCk7Ci0gICAgYXBwLnJ1bihhcmdzKTsKLSAgfQotCi0gIHB1YmxpYyB2b2lkIHJ1bihTdHJpbmdbXSBhcmdzKXsKLSAgICBpZiAoYXJncy5sZW5ndGggIT0gMikgewotICAgICAgdXNhZ2UoKTsKLSAgICB9Ci0gICAgU3RyaW5nIGlucHV0RmlsZW5hbWUgPSBhcmdzWzBdOwotICAgIFN0cmluZyBzdHlsZXNoZWV0ID0gYXJnc1sxXTsKLSAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lcjsKLSAgICBUcmFuc2Zvcm1lckZhY3RvcnkgZmFjdG9yeSA9IFRyYW5zZm9ybWVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwotICAgIHRyeSB7Ci0gICAgICB0cmFuc2Zvcm1lciA9IGZhY3RvcnkubmV3VHJhbnNmb3JtZXIobmV3IFN0cmVhbVNvdXJjZShzdHlsZXNoZWV0KSk7Ci0gICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0obmV3IFN0cmVhbVNvdXJjZShpbnB1dEZpbGVuYW1lKSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLSAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgLy8gbm90aGluZy4uLgotICAgIH0KLSAgfQotCi0gIHB1YmxpYyB2b2lkIHVzYWdlKCkgewotICAgIFN5c3RlbS5lcnIucHJpbnRsbigKLSAgICAgICAiVXNhZ2U6IHJ1biAmbHQ7eG1sX2ZpbGUmZ3Q7ICZsdDt4c2xfZmlsZSZndDsiKTsKLSAgICBTeXN0ZW0uZXhpdCgxKTsKLSAgfQotfTwvc291cmNlPgotPHA+VGhlIHVzZSBvZiBUZW1wbGF0ZXMgaXMgdXNlZnVsIHdoZW4gbXVsdGlwbGUgaW5zdGFuY2VzIG9mIHRoZSBzYW1lIHRyYW5zZm9ybWVyCi1hcmUgbmVlZGVkLiBGb3IgZXhhbXBsZSB0cmFuc2Zvcm1pbmcgbXVsdGlwbGUgZG9jdW1lbnRzIGJ5IHRoZSBzYW1lIHRyYW5zZm9ybWVyLAotZWFjaCB3b3JraW5nIGluIGEgc2VwYXJhdGUgdGhyZWFkLiBJbiB0aGlzIGNhc2UsIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgaXMgdXNlZCB0bwotY3JlYXRlIGEgVGVtcGxhdGVzIG9iamVjdCBmb3IgYSBnaXZlbiBzdHlsZXNoZWV0LiBFYWNoIFRyYW5zZm9ybWVyIGluc3RhbmNlIGlzIHRoZW4KLWNyZWF0ZWQgYnkgdGhlIFRlbXBsYXRlcyBvYmplY3QuIEluIHRoaXMgd2F5IHRoZSBUZW1wbGF0ZXMgb2JqZWN0IGNhbiBjb21waWxlIHRoZQotc3R5bGVzaGVldCBvbmNlLCBhbmQgZWFjaCB0aW1lIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB0cmFuc2Zvcm1lciBpcyBhc2tlZCBmb3IsIGEgY2xvbmUgaXMKLXByb3ZpZGVkIHJhdGhlciB0aGFuIHJlY29tcGlsZSB0aGUgc3R5bGVzaGVldCBhZ2FpbiBhbmQgYWdhaW4uIFRoZSBQcm90byBjbGFzcyBhYm92ZQotd291bGQgYmUgbW9kaWZpZWQgYXMgZm9sbG93czo8L3A+Ci08c291cmNlPnRyeSB7Ci0gIFRlbXBsYXRlcyB0ZW1wbGF0ZXMgPSBmYWN0b3J5Lm5ld1RlbXBsYXRlcyhuZXcgU3RyZWFtU291cmNlKHN0eWxlc2hlZXQpKTsKLSAgdHJhbnNmb3JtZXIgPSB0ZW1wbGF0ZXMubmV3VHJhbnNmb3JtZXIoKTsKLSAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKG5ldyBTdHJlYW1Tb3VyY2UoaW5wdXRGaWxlbmFtZSksCi0gICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUmVzdWx0KFN5c3RlbS5vdXQpKTsKLX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0gIC8vIG5vdGhpbmcuLi4KLX08L3NvdXJjZT4KLTxwPlRoZSBKQVhQIFRyYW5zZm9ybWVyRmFjdG9yeSBpcyBjb25maWd1cmFibGUuIFRoZSBBUEkgc3VwcG9ydHMgY29uZmlndXJpbmcgdGhlCi1mYWN0b3J5IHRvOiAoMSkgdXNlIGF0dHJpYnV0ZXMgd2hpY2ggYXJlIHBhc3NlZCBkb3duIHRvIHRoZSB1bmRlcmx5aW5nIFhTTCBwcm9jZXNzb3IsCi10aGVzZSBhcmUgdmVuZG9yIGRlcGVuZGVudCwgKDIpIHJlZ2lzdGVyIGFuIEVycm9yTGlzdGVuZXIgdGhhdCBwcm92aWRlcyBjYWxsYmFja3MKLXRvIGhhbmRsZSBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlIGdlbmVyYXRlZCBieSB0aGUgWFNMIHByb2Nlc3NvciwgKDMpIHJlZ2lzdGVyCi1hbiBVUklSZXNvbHZlciB3aGljaCBjYW4gYmUgdXNlZCB0byByZXNvbHZlIFVSSXMgZW5jb3VudGVyZWQgaW4geHNsOmluY2x1ZGUsCi14c2w6aW1wb3J0LGFuZGRvY3VtZW50KCkgZnVuY3Rpb25zLjwvcD4KLTxwPlRoZSBKQVhQIFRyYW5zZm9ybWVyRmFjdG9yeSBjYW4gYmUgcXVlcmllZCBhdCBydW50bWUgdG8gZGlzY292ZXIgd2hhdCBmZWF0dXJlcwotaXQgc3VwcG9ydHMuIEZvciBleGFtcGxlLCBhbiBhcHBsaWNhdGlvbiBtaWdodCB3YW50IHRvIGtub3cgaWYgYSBwYXJ0aWN1bGFyIGZhY3RvcnkKLWltcGxlbWVudGF0aW9uIHN1cHBvcnRzIHRoZSB1c2Ugb2YgU0FYIGV2ZW50cyBhcyBhIHNvdXJjZSwgb3Igd2hldGhlciBpdCBjYW4gd3JpdGUKLW91dCB0cmFuc2Zvcm1hdGlvbiByZXN1bHRzIGFzIGEgRE9NLiBUaGUgZmFjdG9yeSBBUEkgcXVlcmllcyB3aXRoIHRoZSBnZXRGZWF0dXJlKCkKLW1ldGhvZC4gSW4gdGhlIFByb3RvIGNvZGUgYWJvdmUsIEkgY291bGQgYWRkIHRoZSBmb2xsb3dpbmcgY29kZSBiZWZvcmUgdGhlIHRyeS1jYXRjaAotYmxvY2s6PC9wPgotPHNvdXJjZT5pZiAoIShmYWN0b3J5LmdldEZlYXR1cmUoU3RyZWFtU291cmNlLkZFQVRVUkUpKSB8fAotICAgICEoZmFjdG9yeS5nZXRGZWF0dXJlKFN0cmVhbVJlc3VsdC5GRUFUVVJFKSkpIHsKLSAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oCi0gICAgICAgICAiU3RyZWFtIFNvdXJjZS9SZXN1bHQgbm90IHN1cHBvcnRlZCBieSBUcmFuc2Zvcm1lciBGYWN0b3J5XG4iICsKLSAgICAgICAgICJleGl0aW5nLiIpOwotICAgICAgIFN5c3RlbS5leGl0KDEpOwotfTwvc291cmNlPgotPC9zMj48YW5jaG9yIG5hbWU9ImludGVncmF0ZSIvPgotPHMyIHRpdGxlPSJUcmFuc2xldCBJbnRlZ3JhdGlvbiI+Ci08cD5UaGUgY3J1eCBvZiB0aGUgaW50ZWdyYXRpb24gc3RyYXRlZ3kgaXMgdGhlIHBsdWdnYWJsZSBUcmFuc2Zvcm1lckZhY3RvcnkgY2xhc3MuIFRoZQotSkFYUCBzcGVjaWZpZXMgdGhhdCB0aGUgYWN0dWFsIFRyYW5zZm9ybWVyRmFjdG9yeSBpbXBsZW1lbnRhdGlvbiBiZSBjb250cm9sbGVkIGJ5IHRoZQotYSBKYXZhIHN5c3RlbSBwcm9wZXJ0eSAoamF2YXgueG1sLnRyYW5zZm9ybWVyLlRyYW5zZm9ybWVyRmFjdG9yeSkgLiBUaGlzIHN5c3RlbSBwcm9wZXJ0eSBjYW4gYmUgc3BlY2lmaWVkIGluIHRoZSB1c3VhbCB3YXlzLCBmb3IKLWV4YW1wbGUgaW4gYSBwcm9wZXJ0aWVzIGZpbGUgb3Igb24gdGhlIGNvbW1hbmQgbGluZSBhcyBhIC1EIG9wdGlvbnBhc3NlZCB0byB0aGVqYXZhCi1lbmdpbmUgaXRzZWxmLiBUaGUgc3RyYXRlZ3kgaW52b2x2ZXMgd3JpdGluZyBhIFRyYW5zZm9ybWVyRmFjdG9yeSBmb3IgVHJhbnNsZXRzLgotSW4gdGhlIEpBWFAgdGhlIFRyYW5zZm9ybWVyRmFjdG9yeSBpcyBhbiBhYnN0cmFjdCBjbGFzcy4gSW4gWGFsYW4sIHRoZSBzeXN0ZW0KLXByb3BlcnR5IHNwZWNpZmllcyB0aGUgaW1wbGVtZW50YXRpb24gY2xhc3MgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCAob3JnLmFwYWNoZS54YWxhbi5wcm9jZXNzb3IuVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCkuCi0gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBhbiBleHRlbnNpb24gb2YgdGhlIGFic3RyYWN0IFNBWFRyYW5zZm9ybWVyRmFjdG9yeSBjbGFzcywgd2hpY2ggaW4KLXR1cm4gaXMgYW4gZXh0ZW5zaW9uIG9mIHRoZSBhYnN0cmFjdCBUcmFuc2Zvcm1lckZhY3RvcnkgY2xhc3MgKGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeSkuPC9wPgotPHA+SW4gdGhpcyBwcm90b3R5cGUgaW50ZWdyYXRpb24gSSBoYXZlIGNvbnN0cnVjdGVkIGFuIFhTTFRDIFRyYW5zZm9ybWVyRmFjdG9yeSBhcwotYW4gZXh0ZW5zaW9uIG9mIHRoZSBhYnN0cmFjdCBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgY2xhc3MuPC9wPgotCi08L3MyPjxhbmNob3IgbmFtZT0iZmFjdG9yeSIvPgotPHMyIHRpdGxlPSJTQVhUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIFRyYW5zbGV0cyI+Ci08cD5UaGUgcHJvdG90eXBlIFhTTFRDIFRyYW5zZm9ybWVyRmFjdG9yeSBuZWVkcyB0byBhY2NvbXBsaXNoIHRoZSBmb2xsb3dpbmc6PC9wPgotIDx1bD4KLSAgIDxsaT48bGluayBhbmNob3I9InNheHRyYW5zZm9ybWVyZmFjdG9yeSI+SW1wbGVtZW50IHRoZSBhYnN0cmFjdCBtZXRob2RzIG9mIHRoZSBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgY2xhc3M8L2xpbms+PC9saT4KLSAgIDxsaT48bGluayBhbmNob3I9InRyYW5zZm9ybWVyZmFjdG9yeSI+SW1wbGVtZW50IHRoZSBhYnN0cmFjdCBtZXRob2RzIG9mIHRoZSBUcmFuc2Zvcm1lckZhY3RvcnkgY2xhc3M8L2xpbms+PC9saT48L3VsPgotPGFuY2hvciBuYW1lPSJzYXh0cmFuc2Zvcm1lcmZhY3RvcnkiLz4KLTxzMyB0aXRsZT0iU0FYVHJhbnNmb3JtZXJGYWN0b3J5IE1ldGhvZHMiPgotCi08cD5UaGUgbWV0aG9kcyBvZiB0aGUgYWJzdHJhY3QgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IGNsYXNzIGhhdmUgYmVlbiBzdHViYmVkIG91dCBhcwotZm9sbG93cy48L3A+Ci08c291cmNlPnB1YmxpYyBUZW1wbGF0ZXNIYW5kbGVyIG5ld1RlbXBsYXRlc0hhbmRsZXIoKSB7IHJldHVybiBudWxsOyB9Ci1wdWJsaWMgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcigpIHsgcmV0dXJuIG51bGw7IH0KLXB1YmxpYyBUcmFuc2Zvcm1lckhhbmRsZXIgbmV3VHJhbnNmb3JtZXJIYW5kbGVyKFNvdXJjZSBzcmMpIHsKLXJldHVybiBudWxsOwotfQotcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykgewotcmV0dXJuIG51bGw7Ci19Ci1wdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihTb3VyY2Ugc3JjKSB7IHJldHVybiBudWxsOyB9Ci1wdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihUZW1wbGF0ZXMgdGVtcGxhdGVzKSB7IHJldHVybiBudWxsOyB9PC9zb3VyY2U+Ci08cD5UaGVzZSBzdHViYmVkIG91dCBtZXRob2RzIHdpbGwgbmVlZCB0byBiZSByZXBsYWNlZCB3aXRoIHJlYWwgaW1wbGVtZW50YXRpb25zLjwvcD4KLTwvczM+PGFuY2hvciBuYW1lPSJ0cmFuc2Zvcm1lcmZhY3RvcnkiLz4KLTxzMyB0aXRsZT0iVHJhbnNmb3JtZXJGYWN0b3J5IE1ldGhvZHMiPgotPHA+VGhlIG1ldGhvZHMgb2YgdGhlIGFic3RyYWN0IFRyYW5zZm9ybWVyRmFjdG9yeSBjbGFzcyBoYXZlIGJlZW4gc3R1YmJlZCBvdXQgYXMKLWZvbGxvd3M6PC9wPgotPHNvdXJjZT5wdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkgeyByZXR1cm4gbnVsbDsgfQotcHVibGljIHZvaWQgc2V0RXJyb3JMaXN0ZW5lcihFcnJvckxpc3RlbmVyIGxpc3RlbmVyKSB7IH0KLXB1YmxpYyBPYmplY3QgZ2V0QXR0cmlidXRlKFN0cmluZyBuYW1lKSB7IHJldHVybiBudWxsOyB9Ci1wdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgeyB9Ci1wdWJsaWMgYm9vbGVhbiBnZXRGZWF0dXJlKFN0cmluZyBuYW1lKSB7IHJldHVybiBmYWxzZTsgfQotcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkgeyByZXR1cm4gbnVsbDsgfQotcHVibGljIHZvaWQgc2V0VVJJUmVzb2x2ZXIoVVJJUmVzb2x2ZXIgcmVzb2x2ZXIpIHsgfQotcHVibGljIFNvdXJjZSBnZXRBc3NvY2lhdGVkU3R5bGVzaGVldChTb3VyY2Ugc3JjLCBTdHJpbmcgbWVkaWEsCi1TdHJpbmcgdGl0bGUsIFN0cmluZyBjaGFyc2V0KSB7IHJldHVybiBudWxsOyB9Ci1wdWJsaWMgVGVtcGxhdGVzIG5ld1RlbXBsYXRlcyhTb3VyY2UgeHNsU3JjKSB0aHJvd3MKLVRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7IHJldHVybiBudWxsOyB9Ci1wdWJsaWMgVHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoKSB0aHJvd3MKLVRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiB7IHJldHVybiBudWxsOyB9PC9zb3VyY2U+Ci08cD5UaGUgbWV0aG9kcyBsaXN0ZWQgYWJvdmUgZmFsbCBpbnRvIDQgY2F0ZWdvcmllczogKDEpIDxsaW5rIGFuY2hvcj0idHJhbnNmb3JtY3JlYXRpb24iPlRyYW5zZm9ybSBjcmVhdGlvbjwvbGluaz4sIAotKDIpIDxsaW5rIGFuY2hvcj0idGVtcGxhdGVzY3JlYXRpb24iPlRlbXBsYXRlcyBjcmVhdGlvbjwvbGluaz4sICgzKSA8bGluayBhbmNob3I9ImZlYXR1cmVkaXNjb3ZlcnkiPmZlYXR1cmUgZGlzY292ZXJ5PC9saW5rPiwgCi1hbmQgKDQpIDxsaW5rIGFuY2hvcj0ibGltaXRhdGlvbnMiPm90aGVycyB0aGF0IHdpbGwgcmVtYWluIHVuaW1wbGVtZW50ZWQgYXQgdGhpcyB0aW1lPC9saW5rPi48L3A+Ci08YW5jaG9yIG5hbWU9InRyYW5zZm9ybWVyY3JlYXRpb24iLz4KLTxzNCB0aXRsZT0iVHJhbnNmb3JtZXIgQ3JlYXRpb24iPgotPHA+VGhlIEpBWFAgc3BlY2lmaWVzIGEgbWV0aG9kIHRoYXQgdGFrZXMgdGhlIHN0eWxlc2hlZXQgYXMgYSBTb3VyY2Ugb2JqZWN0IGFuZCByZXR1cm5zIGEKLVRyYW5zZm9ybWVyLjwvcD4KLTxwPjxjb2RlPnB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcihTb3VyY2UgeHNsU3JjKTwvY29kZT48L3A+Ci08cD5UaGlzIG1ldGhvZCBuZWVkcyB0byByZXR1cm4gYSBUcmFuc2Zvcm1lciB0byBjb21wbHkgd2l0aCB0aGUgSkFYUCBBUEksIGJ1dCBhbHNvCi1uZWVkcyB0byByZXR1cm4gYSBUcmFuc2xldC4gSW4gdGhlIFhTTFRDL1hhbGFuIEFQSSwgYSBUcmFuc2xldCBpcyBhbiBpbnRlcmZhY2UgdGhhdCBpcwotaW1wbGVtZW50ZWQgYnkgdGhlIHJ1bnRpbWUgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RUcmFuc2xldCAob3JnLmFwYWNoZS54YWxhbi54c2x0Yy5UcmFuc2xldCBhbmQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQsIHJlcGVjdGl2ZWx5KS4gVGhlcmVmb3JlLCBJIGhhZCB0bwotY2hhbmdlIHRoZSBBYnN0cmFjdFRyYW5zbGV0IGNsYXNzIHNvIHRoYXQgaXQgd2lsbCBleHRlbmQgdGhlIGFic3RyYWN0IFRyYW5zZm9ybWVyCi1jbGFzcyB3aGlsZSBzdGlsbCBpbXBsZW1lbnRpbmcgdGhlIFRyYW5zbGV0IGludGVyZmFjZS4gT25jZSB0aGlzIGlzIGRvbmUsIHRoZW4gdGhlCi1uZXdUcmFuc2Zvcm1lcigpIG1ldGhvZCBvZiB0aGUgbmV3IFRyYW5zZm9ybWVyRmFjdG9yeSBjYW4gcmV0dXJuIGEgVHJhbnNsZXQgdGhhdAotaXMgYSBUcmFuc2Zvcm1lci48L3A+Ci08cD5JbiBvcmRlciB0byBoYXZlIEFic3RyYWN0VHJhbnNsZXQgZXh0ZW5kIFRyYW5zZm9ybWVyLCBzZXZlcmFsIGFic3RyYWN0IG1ldGhvZHMKLWhhdmUgdG8gYmUgaW1wbGVtZW50ZWQgaW4gQWJzdHJhY3RUcmFuc2xldCBjbGFzcy4gVGhlc2UgYXJlOjwvcD4KLTxzb3VyY2U+cHVibGljIHZvaWQgY2xlYXJQYXJhbWV0ZXJzKCkgeyB9Ci1wdWJsaWMgRXJyb3JMaXN0ZW5lciBnZXRFcnJvckxpc3RlbmVyKCkgeyByZXR1cm4gbnVsbDsgfQotcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0UHJvcGVydGllcygpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotICByZXR1cm4gbnVsbDsKLX0KLXB1YmxpYyBTdHJpbmcgZ2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUpCi0gIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb257IHJldHVybiAiIjsgfQotLy9wdWJsaWMgT2JqZWN0IGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSkgeyByZXR1cm4gbnVsbDsgfQotcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkgeyByZXR1cm4gbnVsbDsgfQotcHVibGljIHZvaWQgc2V0RXJyb3JMaXN0ZW5lcihFcnJvckxpc3RlbmVyIGxpc3RlbmVyKQotICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsgfQotcHVibGljIHZvaWQgc2V0T3V0cHV0UHJvcGVydGllcyhQcm9wZXJ0aWVzIHByb3BzKQotICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsgfQotcHVibGljIHZvaWQgc2V0T3V0cHV0UHJvcGVydHkoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKLSAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7IH0KLXB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlKSB7IH0KLXB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKSB7IH0KLXB1YmxpYyB2b2lkIHRyYW5zZm9ybShTb3VyY2UgeG1sc3JjLCBSZXN1bHQgb3V0cHV0VGFyZ2V0KQotICB0aHJvd3MgVHJhbnNmb3JtZXJFeGNlcHRpb24geyAuLi4gfTwvc291cmNlPgotPHA+TWFwcGluZyB0aGVzZSBtZXRob2RzIHRvIHNvbWUgZXhpc3Rpbmcgb25lcyBpbiBBYnN0cmFjdFRyYW5zbGV0IHN0aWxsIGhhcyB0byBiZQotZG9uZS4gSW4gcGFydGljdWxhciB0aGUgdHJhbnNmb3JtKCkgbWV0aG9kIHdoaWNoIGlzIGV4cGxhaW5lZCBmdXJ0aGVyIGluIGEgZm9sbG93aW5nCi1zZWN0aW9uLjwvcD4KLTxwPk5vdyB0aGF0IFhTTFRDknMgQWJzdHJhY3RUcmFuc2xldCBpcyBhIFRyYW5zZm9ybWVyLCB0aGUgbmV3IFRyYW5zZm9ybWVyCi1mYWN0b3J5IGNsYXNzIGNhbiBpbXBsZW1lbnQgdGhlIG5ld1RyYW5zZm9ybWVyKCkgbWV0aG9kLiBUaGlzIG1ldGhvZCBuZWVkcyB0byBkbwotdHdvIGZ1bmRhbWVudGFsIHRoaW5nczogKDEpIGNyZWF0ZSBhIHRyYW5zbGV0IGZyb20gdGhlIGdpdmVuIFhTTFQgc3R5bGVzaGVldCBhbmQgKDIpCi1pbnN0YW50aWF0ZSB0aGUgdHJhbnNsZXQgc28gaXQgY2FuIGJlIHJldHVybmVkIGFzIGEgVHJhbnNmb3JtZXIuPC9wPgotPHA+VGhlIGNvZGUgYmVsb3dzIGhvd3MgbXkgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgbmV3VHJhbnNmb3JtZXIoKSBtZXRob2QKLWluIHRoZSBuZXcgZmFjdG9yeSBjbGFzczo8L3A+Ci08c291cmNlPnB1YmxpYyBjbGFzcyBUb2Rkc1RyYW5zZm9ybWVyRmFjdG9yeUltcGwgZXh0ZW5kcyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgewotICAuLi4KLSAgcHVibGljIFRyYW5zZm9ybWVyIG5ld1RyYW5zZm9ybWVyKFNvdXJjZSBzdHlsZXNoZWV0KSB0aHJvd3MKLSAgICBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIFhTTFRDIHhzbHRjID0gbmV3IFhTTFRDKCk7Ci0gICAgeHNsdGMuaW5pdCgpOwotICAgIFN0cmluZyBzdHlsZXNoZWV0TmFtZSA9IHN0eWxlc2hlZXQuZ2V0U3lzdGVtSWQoKTsKLSAgICBpbnQgaW5kZXggPSBzdHlsZXNoZWV0TmFtZS5pbmRleE9mKJIukik7Ci0gICAgU3RyaW5nIHRyYW5zbGV0TmFtZSA9IHN0eWxlc2hlZXROYW1lLnN1YnN0cmluZygwLGluZGV4KTsKLSAgICBib29sZWFuIGlzU3VjY2Vzc2Z1bCA9IHRydWU7Ci0gICAgdHJ5IHsKLSAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKHN0eWxlc2hlZXROYW1lKTsKLSAgICAgIFVSTCB1cmwgPSBmaWxlLnRvVVJMKCk7Ci0gICAgICBpc1N1Y2Nlc3NmdWwgPSB4c2x0Yy5jb21waWxlKHVybCk7Ci0gICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgICJVUkwgZm9yIHN0eWxlc2hlZXQgkiIgKyBzdHlsZXNoZWV0TmFtZSArCi0gICAgICAgICAgICAgICAikiBjYW4gbm90IGJlIGZvcm1lZC4iKTsKLSAgICB9Ci0KLSAgICBpZiAoIWlzU3VjY2Vzc2Z1bCkgewotICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAiQ29tcGlsYXRpb24gb2Ygc3R5bGVzaGVldCCSIiArIHN0eWxlc2hlZXROYW1lICsgIpIgZmFpbGVkLiIpOwotICAgIH0KLSAgICAKLSAgICBUcmFuc2xldCB0cmFuc2xldCA9IG51bGw7Ci0gICAgdHJ5IHsKLSAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZSh0cmFuc2xldE5hbWUpOwotICAgICAgdHJhbnNsZXQgPSAoVHJhbnNsZXQpY2xhenoubmV3SW5zdGFuY2UoKTsKLSAgICAgICgoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldCkuc2V0VHJhbnNsZXROYW1lKHRyYW5zbGV0TmFtZSk7Ci0gICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgewotICAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICAgIlRyYW5zbGV0IGNsYXNzIJIiICsgdHJhbnNsZXROYW1lICsgIpIgbm90IGZvdW5kLiIpOwotICAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAgICJUcmFuc2xldCBjbGFzcyCSIiArIHRyYW5zbGV0TmFtZSArCi0gICAgICAgICAgICAgICKSIGNvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQiKTsKLSAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICJUcmFuc2xldCBjbGFzcyCSIiArIHRyYW5zbGV0TmFtZSArICKSIGNvdWxkIG5vdCBiZSBhY2Nlc3NlZC4iKTsKLSAgICAgfQotICAgICByZXR1cm4gKEFic3RyYWN0VHJhbnNsZXQpdHJhbnNsZXQ7Ci0gIH0KLX08L3NvdXJjZT4KLTwvczQ+PGFuY2hvciBuYW1lPSJ0ZW1wbGF0ZXNjcmVhdGlvbiIvPgotPHM0IHRpdGxlPSJUZW1wbGF0ZXMgQ3JlYXRpb24iPgotPHA+VGhlIEpBWFAgc3BlY2lmaWVzIGEgbWV0aG9kIHRoYXQgdGFrZXMgdGhlIHN0eWxlc2hlZXQgYXMgYSBTb3VyY2Ugb2JqZWN0IGFuZCByZXR1cm5zIGEKLVRlbXBsYXRlcyBvYmplY3QuPC9wPgotPHA+PGNvZGU+cHVibGljIFRlbXBsYXRlcyBuZXdUZW1wbGF0ZXMoU291cmNlIHhzbFNyYyk8L2NvZGU+PC9wPgotPHA+VG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kIEkgbmVlZGVkIHRvIGNyZWF0ZSBhIG5ldyBjbGFzcyB0aGF0IHdvdWxkIGJlIGEgVGVtcGxhdGVzCi1mb3IgVHJhbnNsZXRzIG9iamVjdC4gVGhlIG5ldyBjbGFzcyBUcmFuc2xldFRlbXBsYXRlcyAob3JnLmFwYWNoZS54YWxhbi54c2x0Yy50cmF4LlRyYW5zbGV0VGVtcGxhdGVzKSBpbXBsZW1lbnRzIHRoZSBUZW1wbGF0ZXMKLWludGVyZmFjZSBhcyBpcyBzaG93biBiZWxvdzo8L3A+Ci08c291cmNlPnBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy50cmF4OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5ydW50aW1lLkFic3RyYWN0VHJhbnNsZXQ7Ci1pbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7Ci0KLXB1YmxpYyBjbGFzcyBUcmFuc2xldFRlbXBsYXRlcyBpbXBsZW1lbnRzIFRlbXBsYXRlcyB7Ci0gIHB1YmxpYyBUcmFuc2xldFRlbXBsYXRlcyhUcmFuc2Zvcm1lciB0cmFuc2xldCkgewotICAgIF90cmFuc2xldCA9IChBYnN0cmFjdFRyYW5zbGV0KXRyYW5zbGV0OwotICB9Ci0KLSAgcHVibGljIFByb3BlcnRpZXMgZ2V0T3V0cHV0UHJvcGVydGllcygpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotCi0gIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpIHRocm93cwotICAgIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKF90cmFuc2xldCA9PSBudWxsKSB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAgICAiRXJyb3I6IE51bGwgVHJhbnNsZXQiKTsKLSAgICB9Ci0gICAgcmV0dXJuIF90cmFuc2xldDsKLSAgfQotICBwcml2YXRlIEFic3RyYWN0VHJhbnNsZXQgX3RyYW5zbGV0ID0gbnVsbDsKLX08L3NvdXJjZT4KLTxwPlRoZSBmYWN0b3J5IG1ldGhvZCBuZXdUZW1wbGF0ZXMoKSBzaW1wbHkgY3JlYXRlcyBhIFRyYW5zZm9ybWVyIGZvciB0aGUgc3R5bGVzaGVldCwKLWFuZCByZXR1cm5zIGEgbmV3VHJhbnNsZXRUZW1wbGF0ZXMgb2JqZWN0LiBUaGUgaW1wbGVtZW50YXRpb24gb2YgbmV3VGVtcGxhdGVzKCkKLWlzIHNob3duIGJlbG93OjwvcD4KLTxzb3VyY2U+cHVibGljIGNsYXNzIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgZXh0ZW5kcyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgewotLi4uCi0gIHB1YmxpYyBUZW1wbGF0ZXMgbmV3VGVtcGxhdGVzKFNvdXJjZSBzdHlsZXNoZWV0KSB0aHJvd3MKLSAgICBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24KLSAgewotICAgIFRyYW5zZm9ybWVyIHRyYW5zbGV0ID0gbmV3VHJhbnNmb3JtZXIoc3R5bGVzaGVldCk7Ci0gICAgcmV0dXJuIG5ldyBUcmFuc2xldFRlbXBsYXRlcyh0cmFuc2xldCk7Ci0gIH0KLX08L3NvdXJjZT4KLTxwPlRoaXMgaW1wbGVtZW50YXRpb24gb25seSBzYXRpc2ZpZXMgdGhlIEpBWFAsIGl0IGRvZXMgbm90IGFkZHJlc3MgY2FjaGluZyBvZiBwcmV2aW91c2x5Ci1jcmVhdGVkIHRyYW5zbGV0cy4gVGhpcyB0eXBlIG9mIG1lY2hhbmlzbSBiZWxvbmdzIGluIFRlbXBsYXRlcyx3aGVyZSBhIGdpdmVuCi1zdHlsZXNoZWV0IHdpbGwgYmUgY29tcGlsZWQgb25lIHRpbWUgb25seSwgYnV0IHRoZSBnZW5lcmF0ZWQgdHJhbnNsZXQgY2FuIGJlIGNsb25lZCB0bwotY3JlYXRlIG11bHRpcGxlIGluc3RhbmNlcyB1cG9uIGRlbWFuZC48L3A+Ci08L3M0PjxhbmNob3IgbmFtZT0iZmVhdHVyZWRpc2NvdmVyeSIvPgotPHM0IHRpdGxlPSJGZWF0dXJlIERpc2NvdmVyeSI+Ci08cD5UaGUgSkFYUCBzcGVjaWZpZXMgYSBtZXRob2QgdGhhdCBhbGxvd3MgcHJvZ3JhbXMgdG8gZGlzY292ZXIgd2hhdCBmZWF0dXJlcyB0aGUgZmFjdG9yeQotaXMgY2FwYWJsZSBvZiBzdXBwb3J0aW5nLjwvcD4KLTxwPjxjb2RlPnB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIGZlYXR1cmVOYW1lKTwvY29kZT48L3A+Ci08cD5BdCB0aGlzIHRpbWUgdGhlIG5ldyB0cmFuc2Zvcm1lciBmYWN0b3J5IHN1cHBvcnRzIFN0cmVhbSBzb3VyY2VzIGFuZCByZXN1bHRzLCBhbmQKLXRoZSBTQVggVHJhbnNmb3JtIGZhY3RvcnkgZmVhdHVyZS4gVGhlIGdldEZlYXR1cmUoKSBpbXBsZW1lbnRhdGlvbiBpcyBzaG93biBiZWxvdzo8L3A+Ci08c291cmNlPnB1YmxpYyBjbGFzcyBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIGV4dGVuZHMgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IHsKLSAgLi4uCi0gIHB1YmxpYyBib29sZWFuIGdldEZlYXR1cmUoU3RyaW5nIG5hbWUpIHsKLSAgICBpZiAoKFN0cmVhbVNvdXJjZS5GRUFUVVJFID09IG5hbWUpIHx8Ci0gICAgICAgIChTdHJlYW1SZXN1bHQuRkVBVFVSRSA9PSBuYW1lKSB8fAotICAgICAgICAoU0FYVHJhbnNmb3JtZXJGYWN0b3J5LkZFQVRVUkUgPT0gbmFtZSkpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgfSBlbHNlIGlmICgoU3RyZWFtU291cmNlLkZFQVRVUkUuZXF1YWxzKG5hbWUpKQotICAgICAgICAgICAgfHwgKFN0cmVhbVJlc3VsdC5GRUFUVVJFLmVxdWFscyhuYW1lKSkKLSAgICAgICAgICAgIHx8IChTQVhUcmFuc2Zvcm1lckZhY3RvcnkuRkVBVFVSRS5lcXVhbHMobmFtZSkpKSB7Ci0gICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICB9IGVsc2UgewotICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgIH0KLSAgfQotfTwvc291cmNlPgotPHA+QXMgdGhlIG90aGVyIGZlYXR1cmVzIGFyZSBpbXBsZW1lbnRlZCwgdGhpcyBtZXRob2RzIHdpbGwgbmVlZCB0byBiZSB1cGRhdGVkLjwvcD4KLQotPC9zND48YW5jaG9yIG5hbWU9ImxpbWl0YXRpb25zIi8+Ci08czQgdGl0bGU9IkxpbWl0YXRpb25zIj4KLTxwPkFzIHlvdSBjYW4gc2VlLCB0aGUgcHJvdG90eXBlIHdpbGwgY29tcGlsZSB0aGUgc3R5bGVzaGVldCBldmVyeXRpbWUuIFRoaXMgb2J2aW91c2x5Ci1uZWVkcyB0byBiZSBzbWFydGVyLiBUaGlzIGlzIHdoZXJlIHRoZSBxdWVzdGlvbiCUZG8gSSBhbHJlYWR5IGhhdmUgdGhpcyB0cmFuc2xldD+UIG5lZWRzCi10byBiZSBhbnN3ZXJlZC4gQWxzbyBmb3Igbm93IHRoZSB0cmFuc2xldCBieXRlY29kZXMgYXJlIHdyaXR0ZW4gb3V0IHRvIGEgRmlsZSBpbiB0aGUgY3VycmVudAotd29ya2luZyBkaXJlY3RvcnksIGFuZCB0aGVuIGluc3RhbnRpYXRlZCB1c2luZyBhIENsYXNzLmZvck5hbWUsIG5ld0luc3RhbmNlKCkKLXBhaXIuIFRoaXMgYWxzbyBuZWVkcyB3b3JrLiBOb3RlIHRoZSByZXR1cm4gc3RhdGVtZW50LCB0aGUgVHJhbnNsZXQgaXMgY2FzdCB0byBhbiBBYnN0cmFjdFRyYW5zbGV0Ci13aGljaCBub3cgaXMgYSBUcmFuc2Zvcm1lci48L3A+Ci08L3M0PgotPC9zMz4KLTwvczI+PGFuY2hvciBuYW1lPSJ0cmFuc2Zvcm0iLz4KLTxzMiB0aXRsZT0iQWJzdHJhY3RUcmFuc2xldJJzIHRyYW5zZm9ybSgpIE1ldGhvZCI+Ci08cD5Ob3cgdGhlIEpBWFAgcHJvZ3JhbSAoUHJvdG8pIHNob3duIGluIHRoZSBmaXJzdCBzZWN0aW9uIGhhcyBhIHdheSB0byBnZXQgYSBUcmFuc2Zvcm1lcgotZmFjdG9yeSB0aGF0IGNhbiByZXR1cm4gVHJhbnNsZXRzLiBUaGUgbmV4dCBzdGVwIG9mIHRoZSBQcm90by5qYXZhIHByb2dyYW0gaXMKLWNhbGxpbmcgdGhlIHRyYW5zZm9ybSgpIG1ldGhvZCBhbmQgaGF2aW5nIHRoZSBUcmFuc2xldCBwcm9jZXNzIHRoZSBnaXZlbiBYTUwKLWRvY3VtZW50LjwvcD4KLTxwPlRoaXMgcmVxdWlyZXMgc29tZSBzdXJnZXJ5IGluIHRoZSBBYnN0cmFjdFRyYW5zbGV0IGNsYXNzIGFnYWluLiBUaGUgQWJzdHJhY3RUcmFuc2xldAotYWxyZWFkeSBoYXMgYSB0cmFuc2Zvcm0oKSBtZXRob2QsIGJ1dCBpdHMgc2lnbmF0dXJlIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUKLUpBWFAgVHJhbnNmb3JtIHNpZ25hdHVyZS4gSW4gdGhlIEFic3RyYWN0VHJhbnNsZXQsIHRyYW5zZm9ybSBtZXRob2RzIGV4cGVjdCBhIERPTQotYXJndW1lbnQsIGluIHNvbWUgY2FzZXMgYSBOb2RlSXRlcmF0b3IsIGFuZCBhIFRyYW5zbGV0T3V0cHV0SGFuZGxlciBhcmd1bWVudC4gVGhlCi1KQVhQIFRyYW5zZm9ybZJzIHRyYW5zZm9ybSgpIHNpZ25hdHVyZSByZXF1aXJlcyBvbmx5IHRoZSBYTUwgZG9jdW1lbnQgYXMgYSBTb3VyY2UKLW9iamVjdCByZWZlcmVuY2UgYW5kIGFuIG91dHB1dFRhcmdldCBhcyBhIFJlc3VsdCBvYmplY3QgcmVmZXJlbmNlLiBNeSBpbXBsZW1lbnRhdGlvbgotb2YgdGhlIEpBWFAgdHJhbnNmb3JtKCkgc2lnbmF0dXJlIGlzIGFzIHNob3duOjwvcD4KLQotPHNvdXJjZT5wdWJsaWMgdm9pZCB0cmFuc2Zvcm0oU291cmNlIHhtbHNyYywgUmVzdWx0IG91dHB1dFRhcmdldCkKLSAgdGhyb3dzIFRyYW5zZm9ybWVyRXhjZXB0aW9uCi17Ci0gIGRvVHJhbnNmb3JtKCB4bWxzcmMuZ2V0U3lzdGVtSWQoKSwKLSAgICAoKFN0cmVhbVJlc3VsdClvdXRwdXRUYXJnZXQpLmdldE91dHB1dFN0cmVhbSgpICk7Ci19PC9zb3VyY2U+Ci08cD5UaGlzIGltcGxlbWVudGF0aW9uIGxldmVyYWdlcyBjb2RlIGRlcml2ZWQgZnJvbSBYU0xUQ5JzIERlZmF1bHRSdW4gY2xhc3MuIEluCi10aGF0IGNsYXNzIHRoZXJlIGlzIGEgZG9UcmFuc2Zvcm0oKSBtZXRob2QgdGhhdCBjYXJyaWVzIG91dCB0aGUgd29yayBvZjogKDEpIHBhcnNpbmcgdGhlCi1pbnB1dCBYTUwgZG9jdW1lbnQgKHVzaW5nIGEgSkFYUCBTQVhQYXJzZXJGYWN0b3J5IGFuZCBTQVhQYXJzZXIpLCAoMikgY3JlYXRpbmcKLWEgRE9NSW1wbCAob3JnLmFwYWNoZS54YWxhbi54c2x0Yy5kb20uRE9NSW1wbCksICgzKSBjcmVhdGluZyBhIFNBWE91dHB1dEhhbmRsZXIsIGFuZCBmaW5hbGx5ICg0KSBjYWxsaW5nIHRoZSB0cmFuc2xldCB0bwotdHJhbnNmb3JtIHRoZSBpbnB1dCBYTUwgZG9jdW1lbnQgKGZyb20gdGhlIERPTUltcGwpLjwvcD4KLTxwPlRoZSBjb2RlIGZvciBkb1RyYW5zZm9ybSBpcyBzaG93biBiZWxvdzo8L3A+Ci08c291cmNlPnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFRyYW5zbGV0IGV4dGVuZHMgVHJhbnNmb3JtZXIgaW1wbGVtZW50cyBUcmFuc2xldHsKLSAgLi4uCi0gIHByaXZhdGUgdm9pZCBkb1RyYW5zZm9ybShTdHJpbmcgeG1sRG9jTmFtZSwgT3V0cHV0U3RyZWFtIG9zdHJlYW0pIHsKLSAgICB0cnkgewotICAgICAgZmluYWwgVHJhbnNsZXQgdHJhbnNsZXQgPSAoVHJhbnNsZXQpdGhpczsgLy8gR1RNIGFkZGVkCi0KLSAgICAgIC8vIENyZWF0ZSBhIFNBWCBwYXJzZXIgYW5kIGdldCB0aGUgWE1MUmVhZGVyIG9iamVjdCBpdCB1c2VzCi0gICAgICBmaW5hbCBTQVhQYXJzZXJGYWN0b3J5IGZhY3RvcnkgPSBTQVhQYXJzZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7Ci0gICAgICBmaW5hbCBTQVhQYXJzZXIgcGFyc2VyID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKLSAgICAgIGZpbmFsIFhNTFJlYWRlciByZWFkZXIgPSBwYXJzZXIuZ2V0WE1MUmVhZGVyKCk7Ci0KLSAgICAgIC8vIFNldCB0aGUgRE9NknMgRE9NIGJ1aWxkZXIgYXMgdGhlIFhNTFJlYWRlcpJzIFNBWDIgY29udGVudCBoYW5kbGVyCi0gICAgICBmaW5hbCBET01JbXBsIGRvbSA9IG5ldyBET01JbXBsKCk7Ci0gICAgICByZWFkZXIuc2V0Q29udGVudEhhbmRsZXIoZG9tLmdldEJ1aWxkZXIoKSk7Ci0gICAgICAvLyBDcmVhdGUgYSBEVEQgbW9uaXRvciBhbmQgcGFzcyBpdCB0byB0aGUgWE1MUmVhZGVyIG9iamVjdAotICAgICAgZmluYWwgRFRETW9uaXRvciBkdGRNb25pdG9yID0gbmV3IERURE1vbml0b3IoKTsKLSAgICAgIGR0ZE1vbml0b3IuaGFuZGxlRFREKHJlYWRlcik7Ci0gICAgICBkb20uc2V0RG9jdW1lbnRVUkkoeG1sRG9jTmFtZSk7Ci0gICAgICAvKioqKioqKioqKioqKioqKgotICAgICAgaWYgKF91cmkpCi0gICAgICAgIHJlYWRlci5wYXJzZSh4bWxEb2NOYW1lKTsKLSAgICAgIGVsc2UKLSAgICAgICoqKioqKioqKioqKioqKioqKiovCi0gICAgICByZWFkZXIucGFyc2UoImZpbGU6IisobmV3IEZpbGUoeG1sRG9jTmFtZSkuZ2V0QWJzb2x1dGVQYXRoKCkpKTsKLQotICAgICAgLy8gU2V0IHNpemUgb2Yga2V5L2lkIGluZGljZXMKLSAgICAgIHNldEluZGV4U2l6ZShkb20uZ2V0U2l6ZSgpKTsKLSAgICAgIC8vIElmIHRoZXJlIGFyZSBhbnkgZWxlbWVudHMgd2l0aCBJRCBhdHRyaWJ1dGVzLCBidWlsZCBhbiBpbmRleAotICAgICAgZHRkTW9uaXRvci5idWlsZElkSW5kZXgoZG9tLCAwLCB0aGlzKTsKLQotICAgICAgc2V0VW5wYXJzZWRFbnRpdHlVUklzKGR0ZE1vbml0b3IuZ2V0VW5wYXJzZWRFbnRpdHlVUklzKCkpOwotICAgIAotICAgICAgLy8gVHJhbnNmb3JtIHRoZSBkb2N1bWVudAotICAgICAgU3RyaW5nIGVuY29kaW5nID0gdHJhbnNsZXQuZ2V0T3V0cHV0RW5jb2RpbmcoKTsKLSAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKSBlbmNvZGluZyA9ICJVVEYtOCI7Ci0gICAgCi0gICAgICAvL1RleHRPdXRwdXQgdGV4dE91dHB1dCA9IG5ldyBUZXh0T3V0cHV0KFN5c3RlbS5vdXQsIGVuY29kaW5nKTsKLSAgICAgIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyIHNheEhhbmRsZXIgPSBuZXcKLSAgICAgICAgIERlZmF1bHRTQVhPdXRwdXRIYW5kbGVyKG9zdHJlYW0sIGVuY29kaW5nKTsKLSAgICAgIFRleHRPdXRwdXQgdGV4dE91dHB1dCA9IG5ldyBUZXh0T3V0cHV0KHNheEhhbmRsZXIsIGVuY29kaW5nKTsKLSAgICAgIHRyYW5zbGV0LnRyYW5zZm9ybShkb20sIHRleHRPdXRwdXQpOwotICAgICAgdGV4dE91dHB1dC5mbHVzaCgpOwotICAgIH0KLSAgICBjYXRjaCAoVHJhbnNsZXRFeGNlcHRpb24gZSkgewotICAgICAgLi4uCi0gICAgfQotICAgIGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKLSAgICAgIC4uLgotICAgIH0KLSAgICBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKLSAgICAgIC4uLgotICAgIH0KLSAgICBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGUpIHsKLSAgICAgIC4uLgotICAgIH0KLSAgICBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgewotICAgICAgLi4uCi0gICAgfQotICAgIGNhdGNoIChFeGNlcHRpb24gZSkgewotICAgICAgLi4uCi0gICAgfQotICB9Ci19PC9zb3VyY2U+Ci08L3MyPjxhbmNob3IgbmFtZT0iY29uY2x1c2lvbiIvPgotPHMyIHRpdGxlPSJDb25jbHVzaW9uIj4KLTxwPlRoaXMgaXMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGludGVncmF0aW9uIG9mIFRyYW5zbGV0IGFuZCBUckFYLiBUaGUgSkFYUCBwcm9ncmFtCi1pbGx1c3RyYXRlZCBpbiB0aGUgZmlyc3Qgc2VjdGlvbiAoUHJvdG8uamF2YSkgY29tcGlsZXMgYW5kIHJ1bnMgd2l0aCB0aGUgY2hhbmdlcyBvdXRsaW5lZAotYWJvdmUuIFRoZSBuZXcgdHJhbnNmb3JtZXIgZmFjdG9yeSBUcmFuc2Zvcm1lckZhY3RvcnlJbXBsIHN1cHBvcnRzIHRyYW5zZm9ybWVyLAotdGVtcGxhdGVzIGNyZWF0aW9uLCBhbmQgdGhlIGZlYXR1cmUgZGlzY292ZXJ5IG1lY2hhbmlzbS4gVGhlIHRyYW5zZm9ybWVycwotcmV0dXJuZWQgZnJvbSB0aGUgZmFjdG9yeSBhcmUgaW4gZmFjdCBBYnN0cmFjdFRyYW5zbGV0IG9iamVjdHMuIFRoZSBuZXcgY2xhc3MKLVRyYW5zbGV0VGVtcGxhdGVzIGltcGxlbWVudHMgdGhlIFRlbXBsYXRlcyBpbnRlcmZhY2UgZm9yIHRyYW5zbGV0cy4gVGhpcyBpcyB0aGUKLXJlc3VsdCBvZiBhIGZpcnN0IHBhc3MgaW1wbGVtZW50YXRpb24sIHRoZXJlIGFyZSBtYW55IHN0dWJiZWQgb3V0IG1ldGhvZHMgdGhhdCBuZWVkIHRvCi1iZSBpbXBsZW1lbnRlZCwgdHJhbnNsZXQgY2FjaGluZyBpbiBUZW1wbGF0ZXMgbmVlZHMgdG8gYmUgaW1wbGVtZW50ZWQgYW5kIHN1cHBvcnQKLWZvciBTb3VyY2UgYW5kIFJlc3VsdCB0eXBlcyBiZXlvbmQgc2ltcGxlIHN0cmVhbSB0eXBlcywgc3VjaCBhcyBET00gYW5kIFNBWC48L3A+Ci0KLTwvczI+PGFuY2hvciBuYW1lPSJhcHBlbmRpeCIvPgotPHMyIHRpdGxlPSJBcHBlbmRpeCI+Ci08dWw+Ci0gIDxsaT48bGluayBhbmNob3I9InJ1bnNjcmlwdCI+VGhlIFJ1biBzY3JpcHQ8L2xpbms+PC9saT4KLSAgPGxpPjxsaW5rIGFuY2hvcj0idHJhbnNmb3JtZXJmYWN0b3J5aW1wbCI+VHJhbnNmb3JtZXJGYWN0b3J5SW1wbC5qYXZhPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9IlRyYW5zbGV0VGVtcGxhdGVzIj5UcmFuc2xldFRlbXBsYXRlcy5qYXZhPC9saW5rPjwvbGk+Ci0gIDxsaT48bGluayBhbmNob3I9Im1ha2VmaWxlIj5UaGUgTWFrZWZpbGU8L2xpbms+PC9saT4KLTwvdWw+Ci08YW5jaG9yIG5hbWU9InJ1bnNjcmlwdCIvPgotPHMzIHRpdGxlPSJUaGUgUnVuIHNjcmlwdCI+Ci08cD5CeSBjaGFuZ2luZyB0aGUgRkFDIHZhcmlhYmxlIEkgY2FuIHN3aXRjaCBiZXR3ZWVuIHRoZSB0d28gVHJhbnNmb3JtZXIgZmFjdG9yeSBpbXBsZW1lbnRhdGlvbnMKLWZvciB0ZXN0aW5nLjwvcD4KLTxzb3VyY2U+IyEvYmluL2tzaAotSkFYUD0vdXNyL2xvY2FsL2pheHAtMS4xL2pheHAuamFyCi1DUklNU09OPS91c3IvbG9jYWwvamF4cC0xLjEvY3JpbXNvbi5qYXIKLVhTTFQ9L25ldC9iaWdibG9jay9maWxlczE4L3RtaWxsZXIveG1sLXhhbGFuL2phdmEvYnVpbGQvY2xhc3NlcwotWE1MPS9uZXQvYmlnYmxvY2svZmlsZXMxOC90bWlsbGVyL3htbC14YWxhbi9qYXZhL2Jpbi94bWwuamFyCi1CQ0VMPS9uZXQvYmlnYmxvY2svZmlsZXMxOC90bWlsbGVyL3htbC14YWxhbi9qYXZhL2Jpbi9CQ0VMLmphcgotSkNVUD0vbmV0L2JpZ2Jsb2NrL2ZpbGVzMTgvdG1pbGxlci94bWwteGFsYW4vamF2YS9iaW4vamF2YV9jdXAuamFyCi1KQ1VQUlQ9L25ldC9iaWdibG9jay9maWxlczE4L3RtaWxsZXIveG1sLXhhbGFuL2phdmEvYmluL3J1bnRpbWUuamFyCi1DTEFTU1BBVEg9JHtKQVhQfToke0NSSU1TT059OiR7WFNMVH06JHtYTUx9OiR7QkNFTH06JHtKQ1VQfToke0pDVVBSVH06LgotRkFDPW9yZy5hcGFjaGUueGFsYW4ueHNsdGMudHJheC5UcmFuc2Zvcm1lckZhY3RvcnlJbXBsCi0jRkFDPW9yZy5hcGFjaGUueGFsYW4ucHJvY2Vzc29yLlRyYW5zZm9ybWVyRmFjdG9yeUltcGwKLWphdmEgLWNsYXNzcGF0aCAke0NMQVNTUEFUSH0gXAotICAgICAtRGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJGYWN0b3J5PSR7RkFDfSBcCi0gICAgIFByb3RvICRAPC9zb3VyY2U+Ci08L3MzPjxhbmNob3IgbmFtZT0idHJhbnNmb3JtZXJmYWN0b3J5aW1wbCIvPgotPHMzIHRpdGxlPSJUcmFuc2Zvcm1lckZhY3RvcnlJbXBsLmphdmEiPgotCi08c291cmNlPnBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy50cmF4OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLkVycm9yTGlzdGVuZXI7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uU3RyZWFtU291cmNlOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlVSSVJlc29sdmVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlNBWFRyYW5zZm9ybWVyRmFjdG9yeTsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5UZW1wbGF0ZXNIYW5kbGVyOwotaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc2F4LlRyYW5zZm9ybWVySGFuZGxlcjsKLQotaW1wb3J0IG9yZy54bWwuc2F4LlhNTEZpbHRlcjsKLQotaW1wb3J0IG9yZy5hcGFjaGUueGFsYW4ueHNsdGMuVHJhbnNsZXQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS54YWxhbi54c2x0Yy5jb21waWxlci5YU0xUQzsKLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLQotaW1wb3J0IGphdmEuaW8uRmlsZTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwotCi0vKioKLSAqIEltcGxlbWVudGF0aW9uIG9mIGEgSkFYUDEuMSBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgZm9yIFRyYW5zbGV0cy4KLSAqLwotcHVibGljIGNsYXNzIFRyYW5zZm9ybWVyRmFjdG9yeUltcGwgZXh0ZW5kcyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgewotICBwdWJsaWMgVHJhbnNmb3JtZXJGYWN0b3J5SW1wbCgpIHsgLyogbm90aGluZyB5ZXQgKi8gfQotCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBTQVhUcmFuc2Zvcm1lckZhY3RvcnkgKHN1YmNsYXNzIG9mIFRyYW5zZm9ybWVyRmFjdG9yeSkKLSAgLy8KLSAgcHVibGljIFRlbXBsYXRlc0hhbmRsZXIgbmV3VGVtcGxhdGVzSGFuZGxlcigpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotICBwdWJsaWMgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcigpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotICBwdWJsaWMgVHJhbnNmb3JtZXJIYW5kbGVyIG5ld1RyYW5zZm9ybWVySGFuZGxlcihTb3VyY2Ugc3JjKSB7Ci0gICAgIC8qVEJEKi8gcmV0dXJuIG51bGw7Ci0gIH0KLSAgcHVibGljIFRyYW5zZm9ybWVySGFuZGxlciBuZXdUcmFuc2Zvcm1lckhhbmRsZXIoVGVtcGxhdGVzIHRlbXBsYXRlcykgewotICAgICAvKlRCRCovIHJldHVybiBudWxsOwotICB9Ci0gIHB1YmxpYyBYTUxGaWx0ZXIgbmV3WE1MRmlsdGVyKFNvdXJjZSBzcmMpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotICBwdWJsaWMgWE1MRmlsdGVyIG5ld1hNTEZpbHRlcihUZW1wbGF0ZXMgdGVtcGxhdGVzKSB7IC8qVEJEKi8gcmV0dXJuIG51bGw7IH0KLQotICAvLwotICAvLyBFbmQgU0FYVHJhbnNmb3JtZXJGYWN0b3J5IG1ldGhvZHMKLSAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotICAvLyBUcmFuc2Zvcm1lckZhY3RvcnkKLSAgLy8KLSAgcHVibGljIEVycm9yTGlzdGVuZXIgZ2V0RXJyb3JMaXN0ZW5lcigpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotICBwdWJsaWMgdm9pZCBzZXRFcnJvckxpc3RlbmVyKEVycm9yTGlzdGVuZXIgbGlzdGVuZXIpIHsvKlRCRCovIH0KLSAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgeyAvKlRCRCovIH0KLSAgcHVibGljIGJvb2xlYW4gZ2V0RmVhdHVyZShTdHJpbmcgbmFtZSkgewotICAgIGlmICgoU3RyZWFtU291cmNlLkZFQVRVUkUgPT0gbmFtZSkgfHwKLSAgICAgICAgKFN0cmVhbVJlc3VsdC5GRUFUVVJFID09IG5hbWUpIHx8Ci0gICAgICAgIChTQVhUcmFuc2Zvcm1lckZhY3RvcnkuRkVBVFVSRSA9PSBuYW1lKSkgewotICAgICAgICByZXR1cm4gdHJ1ZTsKLSAgICAgfSBlbHNlIGlmICgoU3RyZWFtU291cmNlLkZFQVRVUkUuZXF1YWxzKG5hbWUpKQotICAgICAgICAgICAgIHx8IChTdHJlYW1SZXN1bHQuRkVBVFVSRS5lcXVhbHMobmFtZSkpCi0gICAgICAgICAgICAgfHwgKFNBWFRyYW5zZm9ybWVyRmFjdG9yeS5GRUFUVVJFLmVxdWFscyhuYW1lKSkpIHsKLSAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgIH0gZWxzZSB7Ci0gICAgICAgIHJldHVybiBmYWxzZTsKLSAgICB9Ci0gIH0KLSAgcHVibGljIFVSSVJlc29sdmVyIGdldFVSSVJlc29sdmVyKCkgeyAvKlRCRCovIHJldHVybiBudWxsOyB9Ci0gIHB1YmxpYyB2b2lkIHNldFVSSVJlc29sdmVyKFVSSVJlc29sdmVyIHJlc29sdmVyKSB7LypUQkQqLyB9Ci0gIHB1YmxpYyBTb3VyY2UgZ2V0QXNzb2NpYXRlZFN0eWxlc2hlZXQoU291cmNlIHNyYywgU3RyaW5nIG1lZGlhLAotICAgICAgIFN0cmluZyB0aXRsZSwgU3RyaW5nIGNoYXJzZXQpIHsgLypUQkQqLyByZXR1cm4gbnVsbDsgfQotICBwdWJsaWMgVHJhbnNmb3JtZXIgbmV3VHJhbnNmb3JtZXIoKSB0aHJvd3MKLSAgICBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24geyAvKlRCRCovIHJldHVybiBudWxsOyB9Ci0gIC8vCi0gIC8vIEVuZCBUcmFuc2Zvcm1lckZhY3RvcnkgbWV0aG9kcwotICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgcHVibGljIFRyYW5zZm9ybWVyIG5ld1RyYW5zZm9ybWVyKFNvdXJjZSBzdHlsZXNoZWV0KSB0aHJvd3MKLSAgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uCi0gIHsKLSAgICBYU0xUQyB4c2x0YyA9IG5ldyBYU0xUQygpOwotICAgIHhzbHRjLmluaXQoKTsKLSAgICBTdHJpbmcgc3R5bGVzaGVldE5hbWUgPSBzdHlsZXNoZWV0LmdldFN5c3RlbUlkKCk7Ci0gICAgaW50IGluZGV4ID0gc3R5bGVzaGVldE5hbWUuaW5kZXhPZiiSLpIpOwotICAgIFN0cmluZyB0cmFuc2xldE5hbWUgPSBzdHlsZXNoZWV0TmFtZS5zdWJzdHJpbmcoMCxpbmRleCk7Ci0gICAgYm9vbGVhbiBpc1N1Y2Nlc3NmdWwgPSB0cnVlOwotICAgIHRyeSB7Ci0gICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShzdHlsZXNoZWV0TmFtZSk7Ci0gICAgICBVUkwgdXJsID0gZmlsZS50b1VSTCgpOwotICAgICAgaXNTdWNjZXNzZnVsID0geHNsdGMuY29tcGlsZSh1cmwpOwotICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAiVVJMIGZvciBzdHlsZXNoZWV0IJIiICsgc3R5bGVzaGVldE5hbWUgKwotICAgICAgICAgICAgIpIgY2FuIG5vdCBiZSBmb3JtZWQuIik7Ci0gICAgfQotICAgIGlmICghaXNTdWNjZXNzZnVsKSB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAiQ29tcGlsYXRpb24gb2Ygc3R5bGVzaGVldCCSIiArIHN0eWxlc2hlZXROYW1lICsgIpIgZmFpbGVkLiIpOwotICAgIH0KLSAgICAKLSAgICBUcmFuc2xldCB0cmFuc2xldCA9IG51bGw7Ci0gICAgdHJ5IHsKLSAgICAgIENsYXNzIGNsYXp6ID0gQ2xhc3MuZm9yTmFtZSh0cmFuc2xldE5hbWUpOwotICAgICAgdHJhbnNsZXQgPSAoVHJhbnNsZXQpY2xhenoubmV3SW5zdGFuY2UoKTsKLSAgICAgICgoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldCkuc2V0VHJhbnNsZXROYW1lKHRyYW5zbGV0TmFtZSk7Ci0gICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0gICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICJUcmFuc2xldCBjbGFzcyCSIiArIHRyYW5zbGV0TmFtZSArICKSIG5vdCBmb3VuZC4iKTsKLSAgICB9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsKLSAgICAgICAgdGhyb3cgbmV3IFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbigKLSAgICAgICAgICAgICJUcmFuc2xldCBjbGFzcyCSIiArIHRyYW5zbGV0TmFtZSArCi0gICAgICAgICAgICAikiBjb3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIik7Ci0gICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7Ci0gICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1lckNvbmZpZ3VyYXRpb25FeGNlcHRpb24oCi0gICAgICAgICAgICAiVHJhbnNsZXQgY2xhc3MgkiIgKyB0cmFuc2xldE5hbWUgKyAikiBjb3VsZCBub3QgYmUgYWNjZXNzZWQuIik7Ci0gICAgfQotICAgIHJldHVybiAoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldDsKLSAgfQotICBwdWJsaWMgVGVtcGxhdGVzIG5ld1RlbXBsYXRlcyhTb3VyY2Ugc3R5bGVzaGVldCkgdGhyb3dzCi0gIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gIFRyYW5zZm9ybWVyIHRyYW5zbGV0ID0gbmV3VHJhbnNmb3JtZXIoc3R5bGVzaGVldCk7Ci0gIHJldHVybiBuZXcgVHJhbnNsZXRUZW1wbGF0ZXModHJhbnNsZXQpOwotICB9Ci19PC9zb3VyY2U+Ci08L3MzPjxhbmNob3IgbmFtZT0idHJhbnNsZXR0ZW1wbGF0ZXMiLz4KLTxzMyB0aXRsZT0iVHJhbnNsZXRUZW1wbGF0ZXMuamF2YSI+Ci08c291cmNlPnBhY2thZ2Ugb3JnLmFwYWNoZS54YWxhbi54c2x0Yy50cmF4OwotCi1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXM7Ci1pbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKLWltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnNheC5TQVhUcmFuc2Zvcm1lckZhY3Rvcnk7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLnhhbGFuLnhzbHRjLnJ1bnRpbWUuQWJzdHJhY3RUcmFuc2xldDsKLWltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKLQotLyoqCi0gKiBJbXBsZW1lbnRhdGlvbiBvZiBhIEpBWFAxLjEgVGVtcGxhdGVzIG9iamVjdCBmb3IgVHJhbnNsZXRzLgotICovCi1wdWJsaWMgY2xhc3MgVHJhbnNsZXRUZW1wbGF0ZXMgaW1wbGVtZW50cyBUZW1wbGF0ZXMgewotICBwdWJsaWMgVHJhbnNsZXRUZW1wbGF0ZXMoVHJhbnNmb3JtZXIgdHJhbnNsZXQpIHsKLSAgICBfdHJhbnNsZXQgPSAoQWJzdHJhY3RUcmFuc2xldCl0cmFuc2xldDsKLSAgfQotICBwdWJsaWMgUHJvcGVydGllcyBnZXRPdXRwdXRQcm9wZXJ0aWVzKCkgeyAvKlRCRCovIHJldHVybiBudWxsOyB9Ci0gIHB1YmxpYyBUcmFuc2Zvcm1lciBuZXdUcmFuc2Zvcm1lcigpIHRocm93cwotICAgIFRyYW5zZm9ybWVyQ29uZmlndXJhdGlvbkV4Y2VwdGlvbgotICB7Ci0gICAgaWYgKF90cmFuc2xldCA9PSBudWxsKSB7Ci0gICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtZXJDb25maWd1cmF0aW9uRXhjZXB0aW9uKAotICAgICAgICAgICAiRXJyb3I6IE51bGwgVHJhbnNsZXQiKTsKLSAgICB9Ci0gICAgcmV0dXJuIF90cmFuc2xldDsKLSAgfQotICBwcml2YXRlIEFic3RyYWN0VHJhbnNsZXQgX3RyYW5zbGV0ID0gbnVsbDsKLX08L3NvdXJjZT4KLTwvczM+PGFuY2hvciBuYW1lPSJtYWtlZmlsZSIvPiAKLTxzMyB0aXRsZT0iVGhlIE1ha2VmaWxlIj4KLTxzb3VyY2U+SkFYUD0vdXNyL2xvY2FsL2pheHAtMS4xL2pheHAuamFyCi1DUklNU09OPS91c3IvbG9jYWwvamF4cC0xLjEvY3JpbXNvbi5qYXIKLVhTTFQ9L25ldC9iaWdibG9jay9maWxlczE4L3RtaWxsZXIveG1sLXhhbGFuL2phdmEvYnVpbGQvY2xhc3NlcwotQ0xBU1NQQVRIPSR7SkFYUH06JHtDUklNU09OfToke1hTTFR9Ci1TUkNTPVwKLVByb3RvLmphdmEKLWFsbDoKLWphdmFjIC1jbGFzc3BhdGggJHtDTEFTU1BBVEh9ICR7U1JDU308L3NvdXJjZT4KLTwvczM+Ci08L3MyPgotPC9zMT4KZGlmZiAtLWdpdCBhL3hkb2NzL3NvdXJjZXMveHNsdGMveHNsdG92ZXIueG1sIGIveGRvY3Mvc291cmNlcy94c2x0Yy94c2x0b3Zlci54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE1NTc4MmMuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc291cmNlcy94c2x0Yy94c2x0b3Zlci54bWwKKysrIC9kZXYvbnVsbApAQCAtMSw2NyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIHN0YW5kYWxvbmU9Im5vIj8+Ci08IURPQ1RZUEUgczEgU1lTVEVNICIuLi8uLi9zdHlsZS9kdGQvZG9jdW1lbnQuZHRkIj4KLQotPCEtLQotICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQotICoKLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKLSAqIHJlc2VydmVkLgotICoKLSAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAotICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCi0gKiBhcmUgbWV0OgotICoKLSAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuIAotICoKLSAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Ci0gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KLSAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKLSAqICAgIGRpc3RyaWJ1dGlvbi4KLSAqCi0gKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKLSAqICAgIGlmIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ21lbnQ6ICAKLSAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQotICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCi0gKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCi0gKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWRnbWVudHMgbm9ybWFsbHkgYXBwZWFyLgotICoKLSAqIDQuIFRoZSBuYW1lcyAiWGFsYW4iIGFuZCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iIG11c3QKLSAqICAgIG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcwotICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAotICogICAgcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCi0gKgotICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCi0gKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0IHByaW9yIHdyaXR0ZW4KLSAqICAgIHBlcm1pc3Npb24gb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgotICoKLSAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKLSAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCi0gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQotICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgotICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAotICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAotICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgotICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAotICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCi0gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKLSAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgotICogU1VDSCBEQU1BR0UuCi0gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotICoKLSAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55Ci0gKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFuZCB3YXMKLSAqIG9yaWdpbmFsbHkgYmFzZWQgb24gc29mdHdhcmUgY29weXJpZ2h0IChjKSAxOTk5LCBMb3R1cwotICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCi0gKiBpbmZvcm1hdGlvbiBvbiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24sIHBsZWFzZSBzZWUKLSAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KLSAtLT4KLSAKLQotPHMxIHRpdGxlPSJYU0xUIENvbXBpbGVyIGFuZCBSdW50aW1lIj4KLSAgIAotICAgPHMyIHRpdGxlPSJVc2luZyB0aGUgQ29tbWFuZC1MaW5lIFV0aWxpdHkiPgotCi0gICA8L3MyPgotPC9zMT4KZGlmZiAtLWdpdCBhL3hkb2NzL3N0eWxlL2R0ZC9zcGVjLmR0ZCBiL3hkb2NzL3N0eWxlL2R0ZC9zcGVjLmR0ZApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggODcyMDI4OS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zdHlsZS9kdGQvc3BlYy5kdGQKKysrIC9kZXYvbnVsbApAQCAtMSw1NzggKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLTwhLS0gIE1PRFVMRTogICAgc3BlYyBEVEQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gIFZFUlNJT046ICAgMS4wICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gIERBVEU6ICAgICAgT2N0b2JlciAxOCwgMjAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLQotCi08IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci08IS0tICAgICAgICAgICAgICAgICAgIElTTyBTVEFOREFSRCBTUEVDSUFMIENIQVJBQ1RFUiBTRVRTICAgICAgICAgLS0+Ci08IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci08IS0tCi08IUVOVElUWSAlIGlzb2xhdDEgICAgICBQVUJMSUMKLSJJU08gODg3OS0xOTg2Ly9FTlRJVElFUyBBZGRlZCBMYXRpbiAxLy9FTiIKLSJlbnRpdGllcy9JU09sYXQxLnBlbiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi08IUVOVElUWSAlIGlzb251bSAgICAgICBQVUJMSUMKLSJJU08gODg3OS0xOTg2Ly9FTlRJVElFUyBOdW1lcmljIGFuZCBTcGVjaWFsIEdyYXBoaWMvL0VOIgotImVudGl0aWVzL0lTT251bS5wZW4iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotPCFFTlRJVFkgJSBpc29wdWIgICAgICAgUFVCTElDCi0iSVNPIDg4NzktMTk4Ni8vRU5USVRJRVMgUHVibGlzaGluZy8vRU4iCi0iZW50aXRpZXMvSVNPcHViLnBlbiIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi08IUVOVElUWSAlIGlzb3RlY2ggICAgICBQVUJMSUMKLSJJU08gODg3OS0xOTg2Ly9FTlRJVElFUyBHZW5lcmFsIFRlY2huaWNhbC8vRU4iCi0iZW50aXRpZXMvSVNPdGVjaC5wZW4iCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotJWlzb2xhdDE7ICVpc29udW07ICVpc29wdWI7ICVpc290ZWNoOwotLS0+Ci0KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciBlbnRpdGllcyBmb3IgY29udGVudCBtb2RlbHMgICAgICAtLT4KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBsaXN0IGVsZW1lbnRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVOVElUWSAlIGxpc3RzICAgICAgICJpdGVtaXplZGxpc3QgfCBvcmRlcmVkbGlzdCB8IHZhcmlhYmxlbGlzdCIgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgbGluZXNwZWNpZmljIGVsZW1lbnRzICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgd2hlcmUgbGluZSBlbmRpbmdzIGFuZCB3aGl0ZXNwYWNlCi0gICAgICAgICAgICAgICAgICAgICAgICBhcmUgc2lnbmlmaWNhbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVOVElUWSAlIGxpbmVzcGVjaWZpYwotICAgICAgICAgICAgICAgICAgICAgICAibGl0ZXJhbGxheW91dCB8IHByb2dyYW1saXN0aW5nIiAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIHBocmFzZS1sZXZlbCBlbGVtZW50cyAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzIGFsbG93ZWQgYXQgdGhlIHNhbWUgbGV2ZWwgYXMgdGV4dCAtLT4KLTwhRU5USVRZICUgcGhyYXNlbGV2ZWwgImNpdGF0aW9uIHwgZW1waGFzaXMgfCBpbmxpbmVncmFwaGljIHwgbGluayB8IHBsaW5rIHwKLSAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmlwdCB8IHN1cGVyc2NyaXB0IHwgdWxpbmsgfCB0ZXJtcmVmIiAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBwYXJhZ3JhcGgtbGV2ZWwgZWxlbWVudHMgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyAoaW5jbHVkaW5nIHBhcmFncmFwaHMpIGFsbG93ZWQgYXQKLSAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBsZXZlbCBvZiBwYXJhZ3JhcGhzICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRU5USVRZICUgcGFyYWxldmVsICAgIiVsaW5lc3BlY2lmaWM7IHwgJWxpc3RzOyB8IG5vdGUgfCBwYXJhIHwgaXNzdWUgfAotICAgICAgICAgICAgICAgICAgICAgICAgdGFibGUgfCBmaWd1cmUgfCBncmFwaGljIiAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciBlbnRpdGllcyBmb3IgYXR0cmlidXRlcyAgICAgICAgICAtLT4KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBjb21tb24gYXR0cmlidXRlcyAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVOVElUWSAlIGNvbW1vbi5hdHRzCi0gICAgICAgICAgICAgImlkICAgICAgICAgSUQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjSU1QTElFRAotICAgICAgICAgICAgICBsaW5rLXVybCAgIENEQVRBICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQiID4KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgZ3JhcGhpYy1yZWxhdGVkIGF0dHJpYnV0ZXMgICAgICAgICAgICAgICAgIC0tPgotPCFFTlRJVFkgJSBncmFwaGljLmF0dHMKLSAgICAgICAgICAgICJmaWxlcmVmICAgIENEQVRBICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICBhbHQgICAgICAgIENEQVRBICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICBzcmNjcmVkaXQgIENEQVRBICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICB3aWR0aCAgICAgIE5NVE9LRU4gICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICBkZXB0aCAgICAgIE5NVE9LRU4gICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICBzY2FsZSAgICAgIE5NVE9LRU4gICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICBzY2FsZWZpdCAgIE5NVE9LRU4gICAgICAgICAgICAgICAgICAgICAgICAgICAgI0lNUExJRUQiID4KLQotPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotPCEtLSAgICAgICAgICAgICAgICAgICAgZXh0ZXJuYWwgbW9kdWxlcyAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotCi08IS0tCi08IUVOVElUWSAlIHRhYmxlLmVudCBTWVNURU0gInRhYmxlLmVudCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0ldGFibGUuZW50OwotLS0+Ci0KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgZGVmaW5pdGlvbnMgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBzcGVjaWZpY2F0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHNwZWMgICAgICAgICAodGl0bGUsIGZyb250bWF0dGVyLCBpbnRyb2R1Y3Rpb24sIHJlcXVpcmVtZW50cywgbW9kZWwsIHNlY3QxKywKLSAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRpeCosIGJpYmxpb2dyYXBoeT8pICAgICAgICAgICAgICAgICAgID4KLQotPCFBVFRMSVNUICBzcGVjCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLTwhRUxFTUVOVCAgZnJvbnRtYXR0ZXIgICAocHViZGF0ZSwgY29weXJpZ2h0LCBhdXRob3IqLCBhYnN0cmFjdD8pICAgID4KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgdGl0bGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICB0aXRsZSAgICAgICAgKCNQQ0RBVEEgfCAlcGhyYXNlbGV2ZWw7KSogICAgICAgICAgICAgICAgICAgPgotPCFBVFRMSVNUICB0aXRsZQotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGlzc3VlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgaXNzdWUgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqICAgICAgICAgICAgICAgICAgID4KLTwhQVRUTElTVCAgaXNzdWUKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBwdWJsaWNhdGlvbiBkYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tICAgICAgICAgICAgICAgICAgICBwdWJsaWNhdGlvbiBkYXRlIGFuZCwgcG9zc2libHksIHRpbWUgICAgICAgLS0+Ci08IUVMRU1FTlQgIHB1YmRhdGUgICAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IUFUVExJU1QgIHB1YmRhdGUKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBjb3B5cmlnaHQgc3RhdGVtZW50ICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIGNvcHlyaWdodCAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGNvcHlyaWdodAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGF1dGhvciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgYXV0aG9yICAgICAgIChmaXJzdG5hbWUsIHN1cm5hbWUsIGpvYnRpdGxlPywgb3JnbmFtZT8sCi0gICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcz8pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGF1dGhvcgotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGFic3RyYWN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgYWJzdHJhY3QgICAgIChwYXJhKykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgYWJzdHJhY3QKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotPCFFTEVNRU5UICBpbnRyb2R1Y3Rpb24gICAgICAgICh0aXRsZSwgKCgoJXBhcmFsZXZlbDspKywgc2VjdDIqKSB8IHNlY3QyKykpID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgaW50cm9kdWN0aW9uCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLTwhRUxFTUVOVCAgcmVxdWlyZW1lbnRzICAgICAgICAodGl0bGUsICgoKCVwYXJhbGV2ZWw7KSssIHNlY3QyKikgfCBzZWN0MispKSA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHJlcXVpcmVtZW50cwotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyA+ICAgIAotCi08IUVMRU1FTlQgIG1vZGVsICAgICAgICAodGl0bGUsICgoKCVwYXJhbGV2ZWw7KSssIHBhdHRlcm5zKSB8IHNlY3QyKykpID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgbW9kZWwKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotPCFFTEVNRU5UICBwYXR0ZXJucyAgICAgICAgKHBhdHRlcm4rKSA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHBhdHRlcm5zCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7IAotCQkJbW9kdWxlICBDREFUQSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNJTVBMSUVECi0gICAgICAgICAgICA+IAotICAgICAgICAgICAgICAgICAgICAgICAgCi08IUVMRU1FTlQgIHBhdHRlcm4gICAgICAgIChwYXR0ZXJuLW5hbWUsIHBvdGVudGlhbC1hbHRlcm5hdGUtbmFtZT8sIGludGVudCwgcmVzcG9uc2liaWxpdGllcywgdGhyZWFkLXNhZmV0eSwgbm90ZXM/KSA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHBhdHRlcm4KLSAgICAgICAgICAgICVjb21tb24uYXR0czsgIAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCFFTEVNRU5UICBwYXR0ZXJuLW5hbWUgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgcGF0dGVybi1uYW1lCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ID4KLSAgICAgICAgICAgIAotPCFFTEVNRU5UICBwb3RlbnRpYWwtYWx0ZXJuYXRlLW5hbWUgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgcG90ZW50aWFsLWFsdGVybmF0ZS1uYW1lCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ID4gIAotCi08IUVMRU1FTlQgIGludGVudCAgICAgICAgKCNQQ0RBVEEgfCAlcGhyYXNlbGV2ZWw7KSogPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBpbnRlbnQKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgPiAgCi0KLTwhRUxFTUVOVCAgcmVzcG9uc2liaWxpdGllcyAgICAgICAgKCNQQ0RBVEEgfCAlcGhyYXNlbGV2ZWw7KSogPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICByZXNwb25zaWJpbGl0aWVzCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ID4gIAotCi08IUVMRU1FTlQgIHRocmVhZC1zYWZldHkgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgdGhyZWFkLXNhZmV0eQotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyA+Ci0KLTwhRUxFTUVOVCAgbm90ZXMgICAgICAgICAoI1BDREFUQSB8ICVwaHJhc2VsZXZlbDspKiAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIG5vdGVzCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgc2VjdDEKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgc2VjdGlvbiAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBzZWN0MSAgICAgICAgKHRpdGxlLCAoKCglcGFyYWxldmVsOykrLCBzZWN0MiopIHwgc2VjdDIrKSkgPgkJCQkJCSAgIAotPCEtLSAgICAgICAgICAgICAgICAgICAgc2VjdGlvbiAyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBzZWN0MiAgICAgICAgKHRpdGxlLCAoKCglcGFyYWxldmVsOykrLCBzZWN0MyopIHwgc2VjdDMrKSkgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBzZWN0MgotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIHNlY3Rpb24gMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgc2VjdDMgICAgICAgICh0aXRsZSwgKCgoJXBhcmFsZXZlbDspKywgc2VjdDQqKSB8IHNlY3Q0KykpID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgc2VjdDMKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBzZWN0aW9uIDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHNlY3Q0ICAgICAgICAodGl0bGUsICglcGFyYWxldmVsOykrKSAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHNlY3Q0Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgYXBwZW5kaXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBhcHBlbmRpeCAgICAgKHRpdGxlLCAoKCglcGFyYWxldmVsOykrLCBzZWN0MSopIHwgc2VjdDErKSkgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBhcHBlbmRpeAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGJpYmxpb2dyYXBoeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgYmlibGlvZ3JhcGh5ICh0aXRsZSwgYmlibGlvaXRlbSspICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgYmlibGlvZ3JhcGh5Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgYmlibGlvZ3JhcGh5IGl0ZW0gICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBiaWJsaW9pdGVtICAgKGRlc2lnbmF0b3IsIGJpYmxpb2VudHJ5KSAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBiaWJsaW9pdGVtCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgYmlibGlvZ3JhcGh5IGl0ZW0gZGVzaWduYXRvciAgICAgICAgICAgICAgIC0tPgotPCEtLSAgICAgICAgICAgICAgICAgICAgZGVzaWduYXRvciBjb250YWlucyB3aGF0ZXZlciBkZXNpZ25hdG9yIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgYXV0aG9yIHVzZXMgdG8gaWRlbnRpZnkgcHVibGljYXRpb25zIGxpc3RlZCBpbgotICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGJpYmxpb2dyYXBoeSAoZS5nLiwgW2xhYiA4N10pLiAgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0IGdlbmVyYXRlcyB0aGUgc3F1YXJlICJbXSIgYnJhY2tldHMKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvcmUgJiBhZnQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgZGVzaWduYXRvciAgICgjUENEQVRBKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgZGVzaWduYXRvcgotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGJpYmxpb2dyYXBoeSBlbnRyeSAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgYmlibGlvZW50cnkgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgYmlibGlvZW50cnkKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci08IS0tICAgICAgICAgICAgICAgICAgICBhdXRob3ItcmVsYXRlZCBlbGVtZW50cyAgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgZmlyc3QgbmFtZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBmaXJzdG5hbWUgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBmaXJzdG5hbWUKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBzdXJuYW1lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHN1cm5hbWUgICAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHN1cm5hbWUKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBqb2IgdGl0bGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIGpvYnRpdGxlICAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGpvYnRpdGxlCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgb3JnYW5pemF0aW9uIG5hbWUgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBvcmduYW1lICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBvcmduYW1lCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgYWRkcmVzcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBhZGRyZXNzICAgICAgKHN0cmVldD8sIHBvYj8sIGNpdHk/LCBzdGF0ZT8sIHBvc3Rjb2RlPywgCi0gICAgICAgICAgICAgICAgICAgICAgICAgY291bnRyeT8sIHBob25lPywgZmF4PywgZW1haWw/KSAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGFkZHJlc3MKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci08IS0tICAgICAgICAgICAgICAgICAgICBhZGRyZXNzIGVsZW1lbnRzICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgc3RyZWV0IGFkZHJlc3MgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBzdHJlZXQgICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBzdHJlZXQKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBwb3N0IG9mZmljZSBib3ggICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHBvYiAgICAgICAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHBvYgotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIHBvc3Rjb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgcG9zdGNvZGUgICAgICgjUENEQVRBKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgcG9zdGNvZGUKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBjaXR5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIGNpdHkgICAgICAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGNpdHkKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBzdGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHN0YXRlICAgICAgICAoI1BDREFUQSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHN0YXRlCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgY291bnRyeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBjb3VudHJ5ICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBjb3VudHJ5Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgcGhvbmUgbnVtYmVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBwaG9uZSAgICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBwaG9uZQotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGZheCBudW1iZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgZmF4ICAgICAgICAgICgjUENEQVRBKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgZmF4Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgZW1haWwgYWRkcmVzcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBlbWFpbCAgICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGlkICAgICAgICAgdW5pcXVlIGlkZW50aWZpZXIgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFBVFRMSVNUICBlbWFpbAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaC1sZXZlbCBlbGVtZW50cyAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBwYXJhZ3JhcGggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHBhcmEgICAgICAgICAoI1BDREFUQSB8ICVwaHJhc2VsZXZlbDspKiAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHBhcmEKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBub3RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIG5vdGUgICAgICAgICAoJXBhcmFsZXZlbDspKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIG5vdGUKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBpdGVtaXplZCBsaXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIGl0ZW1pemVkbGlzdCAobGlzdGl0ZW0rKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGl0ZW1pemVkbGlzdAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgbGlzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgb3JkZXJlZGxpc3QgIChsaXN0aXRlbSspICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgb3JkZXJlZGxpc3QKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZSBsaXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHZhcmlhYmxlbGlzdCAodmFybGlzdGVudHJ5KykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHZhcmlhYmxlbGlzdAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGxpc3QgaXRlbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgbGlzdGl0ZW0gICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOyB8ICVwYXJhbGV2ZWw7KSogICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgbGlzdGl0ZW0KLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZSBsaXN0IGVudHJ5ICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHZhcmxpc3RlbnRyeSAodGVybSssIGxpc3RpdGVtKSAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHZhcmxpc3RlbnRyeQotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIHRlcm0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgdGVybSAgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgdGVybQotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi08IS0tICAgICAgICAgICAgICAgICAgICB0ZXJtcmVmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHRlcm1yZWYgICAgICAgICAoI1BDREFUQSB8ICVwaHJhc2VsZXZlbDspKiAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHRlcm1yZWYKLSAgICAgICAgICAgICVjb21tb24uYXR0czsJICAgPgotCi08IS0tICAgICAgICAgICAgICAgICAgICBsaXRlcmFsIGxheW91dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIGxpdGVyYWxsYXlvdXQKLSAgICAgICAgICAgICAgICAgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICB4bWw6c3BhY2UgIHdoaXRlc3BhY2UgaGFuZGxpbmcKLSAgICAgICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgbGl0ZXJhbGxheW91dAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIHByb2dyYW0gbGlzdGluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgcHJvZ3JhbWxpc3RpbmcKLSAgICAgICAgICAgICAgICAgICAgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICB4bWw6c3BhY2UgIHdoaXRlc3BhY2UgaGFuZGxpbmcKLSAgICAgICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgcHJvZ3JhbWxpc3RpbmcKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBmaWd1cmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIGZpZ3VyZSAgICAgICAodGl0bGUsIGdyYXBoaWMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGZpZ3VyZQotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGdyYXBoaWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgZ3JhcGhpYyAgICAgIEVNUFRZICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBhbGlnbiAgICAgIGFsaWdubWVudCBvZiBncmFwaGljIGltYWdlLiAgdmFsdWVzIGFyZToKLSAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdCAgICAgICAgICBsZWZ0IGFsaWduZWQKLSAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgICAgICAgICByaWdodCBhbGlnbmVkCi0gICAgICAgICAgICAgICAgICAgICAgICAgIGNlbnRlciAgICAgICAgY2VudGVyZWQKLSAgICAgICAgICAgICBmaWxlcmVmICAgIHBhdGggdG8gZXh0ZXJuYWwgZmlsZQotICAgICAgICAgICAgIGFsdCAgICAgICAgYWx0ZXJuYXRlIHRleHQKLSAgICAgICAgICAgICBzcmNjcmVkaXQgIHNvdXJjZSBvZiBncmFwaGljCi0gICAgICAgICAgICAgd2lkdGggICAgICB3aWR0aCBvZiBhcmVhIGluIHdoaWNoIHRvIGZpdCBncmFwaGljCi0gICAgICAgICAgICAgZGVwdGggICAgICBkZXB0aCBvZiBhcmVhIGluIHdoaWNoIHRvIGZpdCBncmFwaGljCi0gICAgICAgICAgICAgc2NhbGUgICAgICBwZXJjZW50YWdlIHNjYWxpbmcgZmFjdG9yCi0gICAgICAgICAgICAgc2NhbGVmaXQgICBzY2FsZSB0byBmaXQgd2lkdGggYW5kL29yIGRlcHRoCi0gICAgICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGdyYXBoaWMKLSAgICAgICAgICAgICBhbGlnbiAgICAgIChsZWZ0IHxyaWdodCB8Y2VudGVyKSAgICAgICAgICAgICAgI0lNUExJRUQKLSAgICAgICAgICAgICVncmFwaGljLmF0dHM7Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGlubGluZSBncmFwaGljICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgaW5saW5lZ3JhcGhpYwotICAgICAgICAgICAgICAgICAgICAgICAgRU1QVFkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGZpbGVyZWYgICAgcGF0aCB0byBleHRlcm5hbCBmaWxlCi0gICAgICAgICAgICAgYWx0ICAgICAgICBhbHRlcm5hdGUgdGV4dAotICAgICAgICAgICAgIHNyY2NyZWRpdCAgc291cmNlIG9mIGdyYXBoaWMKLSAgICAgICAgICAgICB3aWR0aCAgICAgIHdpZHRoIG9mIGFyZWEgaW4gd2hpY2ggdG8gZml0IGdyYXBoaWMKLSAgICAgICAgICAgICBkZXB0aCAgICAgIGRlcHRoIG9mIGFyZWEgaW4gd2hpY2ggdG8gZml0IGdyYXBoaWMKLSAgICAgICAgICAgICBzY2FsZSAgICAgIHBlcmNlbnRhZ2Ugc2NhbGluZyBmYWN0b3IKLSAgICAgICAgICAgICBzY2FsZWZpdCAgIHNjYWxlIHRvIGZpdCB3aWR0aCBhbmQvb3IgZGVwdGgKLSAgICAgICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgaW5saW5lZ3JhcGhpYwotICAgICAgICAgICAgJWdyYXBoaWMuYXR0czsKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotPCEtLSAgICAgICAgICAgICAgICAgICAgdGV4dC1sZXZlbCBlbGVtZW50cyAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGJpYmxpb2dyYXBoaWMgY2l0YXRpb24gICAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgIGEgPGNpdGF0aW9uPiBhcHBlYXJzIGluIHRoZSBib2R5IG9mIHRoZQotICAgICAgICAgICAgICAgICAgICAgICAgYXJ0aWNsZSwgYW5kIGl0IHJlZmVycyB0aHJvdWdoIGl0cwotICAgICAgICAgICAgICAgICAgICAgICAgImxpbmtlbmQiIGF0dHJpYnV0ZSB0byB0aGUgaWQgb2YgdGhlCi0gICAgICAgICAgICAgICAgICAgICAgICByZWxldmFudCBiaWJsaW9ncmFwaHkgaXRlbS4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIDxjaXRhdGlvbj4gcmVjZWl2ZXMgdGhlIHNhbWUKLSAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRpbmcgYXMgdGhlIDxkZXNpZ25hdG9yPiBlbGVtZW50Ci0gICAgICAgICAgICAgICAgICAgICAgICB3aXRoaW4gdGhlIDxiaWJsaW9pdGVtPiBiZWluZyByZWZlcmVuY2VkLgotICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGV4YW1wbGUsIHdoZW4gZm9yIHRoZSBiaWJpdGVtCi0gICAgICAgICAgICAgICAgICAgICAgICA8YmlibGlvaXRlbSBpZD0iYmliMSI+PGRlc2lnbmF0b3I+bGFiCi0gICAgICAgICAgICAgICAgICAgICAgICA4NzwvZGVzaWduYXRvcj4uLi48L2JpYmxpb2l0ZW0+IGlzCi0gICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZWQgYXMgIltsYWIgODddIiwgdGhlIGJpYmxpb2dyYXBoaWMKLSAgICAgICAgICAgICAgICAgICAgICAgIGNpdGF0aW9uIDxjaXRhdGlvbiBsaW5rZW5kPSJiaWIxIj5sYWIKLSAgICAgICAgICAgICAgICAgICAgICAgIDg3PC9jaXRhdGlvbj4gYWxzbyBmb3JtYXRzIGFzICJbbGFiIDg3XSIuICAtLT4KLTwhRUxFTUVOVCAgY2l0YXRpb24gICAgICgjUENEQVRBIHwgZW1waGFzaXMgfCBpbmxpbmVncmFwaGljIHwKLSAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHQgfCBzdXBlcnNjcmlwdCkqICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBsaW5rZW5kICAgIGlkIG9mIHJlZmVyZW5jZWQgYmlibGlvZ3JhcGh5IGVudHJ5Ci0gICAgICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGNpdGF0aW9uCi0gICAgICAgICAgICAgbGlua2VuZCAgICBJRFJFRiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNSRVFVSVJFRAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KLTwhLS0gICAgICAgICAgICAgICAgICAgIGVtcGhhc2lzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgZW1waGFzaXMgICAgICgjUENEQVRBIHwgJXBocmFzZWxldmVsOykqICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgZW1waGFzaXMKLSAgICAgICAgICAgICVjb21tb24uYXR0czsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLQotCi08IS0tICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHN1YnNjcmlwdCAgICAoI1BDREFUQSB8IGVtcGhhc2lzIHwgc3Vic2NyaXB0IHwKLSAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlcnNjcmlwdCkqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICBpZCAgICAgICAgIHVuaXF1ZSBpZGVudGlmaWVyICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhQVRUTElTVCAgc3Vic2NyaXB0Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgc3VwZXJzY3JpcHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBzdXBlcnNjcmlwdCAgKCNQQ0RBVEEgfCBlbXBoYXNpcyB8IHN1YnNjcmlwdCB8Ci0gICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXJzY3JpcHQpKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IS0tICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHN1cGVyc2NyaXB0Ci0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLQotPCEtLSAgICAgICAgICAgICAgICAgICAgbGluayAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCFFTEVNRU5UICBsaW5rICAgICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotPCEtLSAgICAgICAgIGxpbmtlbmQgICAgaWQgb2YgcmVmZXJlbmNlZCBlbGVtZW50Ci0gICAgICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIGxpbmsKLSAgICAgICAgICAgICBsaW5rZW5kICAgIElEUkVGICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1JFUVVJUkVECi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLTwhLS0gIHBhY2thZ2UgbGluayAoZm9yIHtAbGluayBvcmcueG1sLnRyYXguUHJvY2Vzc29yfSB0eXBlIGxpbmtzLCBmb3IgamF2YWRvY3MuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUVMRU1FTlQgIHBsaW5rICAgICAgICAgKCNQQ0RBVEEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci08IUFUVExJU1QgIHBsaW5rCi0gICAgICAgICAgICAlY29tbW9uLmF0dHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ci0KLTwhLS0gICAgICAgICAgICAgICAgICAgIHVsaW5rIChleHRlcm5hbCBsaW5rKSAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhRUxFTUVOVCAgdWxpbmsgICAgICAgICgjUENEQVRBKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KLTwhLS0gICAgICAgICB1cmwgICAgICAgIHVuaWZvcm0gcmVzb3VyY2UgbG9jYXRvcjsgdGhlIHRhcmdldCBvZiB0aGUKLSAgICAgICAgICAgICAgICAgICAgICAgIHVsaW5rCi0gICAgICAgICAgICAgaWQgICAgICAgICB1bmlxdWUgaWRlbnRpZmllciAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IUFUVExJU1QgIHVsaW5rCi0gICAgICAgICAgICAgdXJsICAgICAgICBDREFUQSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNSRVFVSVJFRAotICAgICAgICAgICAgJWNvbW1vbi5hdHRzOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgotCi0KZGlmZiAtLWdpdCBhL3hkb2NzL3N0eWxlL2R0ZC94c2wtaHRtbDQwcy5kdGQgYi94ZG9jcy9zdHlsZS9kdGQveHNsLWh0bWw0MHMuZHRkCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBhODg0OGJkLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3N0eWxlL2R0ZC94c2wtaHRtbDQwcy5kdGQKKysrIC9kZXYvbnVsbApAQCAtMSwxNTA1ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KLTwhLS0gCi0gICAgIFhTTFQgKFdELTE5OTkwODEzKSBEVEQgYW5kIEhUTUwgNC4wIFN0cmljdCAoUkVDLUhUTUw0MC0xOTk4MDQyNCkgRFRECi0gICAgIFRoaXMgRFREIGRlZmluZXMgYSBYU0xUIHN0eWxlc2hlZXQgd2l0aCBhIHJlc3VsdC1ucyBvZiBodG1sCi0KLSAgICAgQ3JlZGl0czoKLSAgICAgICBPcmlnaW5hbCBYU0xUIERURCBmcm9tIFczQyBYU0xUIFdELTE5OTkwODEzCi0gICAgICAgT3JpZ2luYWwgWE1MICBEVEQgZm9yIEhUTUwgNC4wIFN0cmljdCBieQotICAgICAgICAgVEFNVVJBLCBLZW50IDxrZW50QHRybC5pYm0uY28uanA+LCBmb3IgSUJNJ3MgWE1MNEogcGFja2FnZQotICAgICAgIE1pbm9yIGZpeGVzIHRvIFhTTFQgJiBIVE1MIERURHMgYnkgCi0gICAgICAgICBTY290dCBCb2FnIDxzY290dF9ib2FnQGxvdHVzLmNvbT4KLSAgICAgICAgIEhlbnJpcXVlIE0uIEhvbHNjaHVoIDxoZW5yaXFtaEBkY2EuZmVlLnVuaWNhbXAuYnI+Ci0gICAgICAgSFRNTC9YU0xUIGNvbXBvc2l0ZSBEVEQgYnkKLSAgICAgICAgIEhlbnJpcXVlIE0uIEhvbHNjaHVoIDxoZW5yaXFtaEBkY2EuZmVlLnVuaWNhbXAuYnI+Ci0KLSAgICAgQ2F2ZWF0czogSXQgaXMgcG9zc2libGUgdG8gZ2VuZXJhdGUgaW52YWxpZCBYU0xUIGFuZCBIVE1MIGRvY3VtZW50cyAKLSAgICAgICB1c2luZyB0aGlzIERURCwgYXMgdGhlIHJlc3VsdC1ucyBlbGVtZW50cyAoSFRNTCkgbXVzdCBhbGxvdyBhbGwgCi0gICAgICAgcG9zc2libGUgeHNsIGVsZW1lbnRzIGFzIGNvbnRlbnQsIGFuZCBhbGwgcmVzdWx0LW5zIGVsZW1lbnRzIGhhZCAKLSAgICAgICB0byBiZSByZWxheGVkIG9uIHRoZWlyIGVsZW1lbnQgY29udGVudCBydWxlcy4KLQotICAgICBUT0RPOgotICAgICAgIC0gQSBYU0xUL1hIVE1MMS4wIFN0cmljdCBEVEQgdG8gdXNlIGluc3RlYWQgb2YgdGhpcyBvbmUuIExvd2VyY2FzZQotICAgICAgICAgZWxlbWVudCBuYW1lcyBhbGxvdyBmb3IgYmV0dGVyIGNvbXByZXNzaW9uIHJhdGlvcywgYXQgbGVhc3QgaW4KLSAgICAgICAgIEVuZ2xpc2ggZG9jdW1lbnRzLgotICAgICAgIC0gVXBkYXRlIHRvIEhUTUwgNC4wMQotCi0gICAgICRJZCQKLS0tPgotCi08IS0tIFByZWRlZmluZWQgWE1MIChSRUMtWE1MLTE5OTgwMjEwKSBlbnRpdGllcyAtLT4KLTwhRU5USVRZIGx0ICAgICAiJiMzODsjNjA7Ij4KLTwhRU5USVRZIGd0ICAgICAiJiM2MjsiPgotPCFFTlRJVFkgYW1wICAgICImIzM4OyMzODsiPgotPCFFTlRJVFkgYXBvcyAgICImIzM5OyI+Ci08IUVOVElUWSBxdW90ICAgIiYjMzQ7Ij4KLQotPCEtLSAKLSAgUmVzdWx0IGVsZW1lbnRzIGFsbG93ZWQgKGluc2lkZSB4c2wgZWxlbWVudHMpLiBUaGVzZSBhcmUgYWN0dWFsbHkKLSAgYWxsIG9mIHRoZSBIVE1MNDAgU3RyaWN0IGVsZW1lbnRzLiAKLS0tPgotCi08IUVOVElUWSAlIHJlc3VsdC1lbGVtZW50cyAiCi0gIHwgVFQKLSAgfCBJCi0gIHwgQgotICB8IEJJRwotICB8IFNNQUxMCi0gIHwgRU0KLSAgfCBTVFJPTkcKLSAgfCBERk4KLSAgfCBDT0RFCi0gIHwgU0FNUAotICB8IEtCRAotICB8IFZBUgotICB8IENJVEUKLSAgfCBBQkJSCi0gIHwgQUNST05ZTQotICB8IFNVUAotICB8IFNVQgotICB8IFNQQU4KLSAgfCBCRE8KLSAgfCBCUgotICB8IEJPRFkKLSAgfCBBRERSRVNTCi0gIHwgRElWCi0gIHwgQQotICB8IE1BUAotICB8IEFSRUEKLSAgfCBMSU5LCi0gIHwgSU1HCi0gIHwgT0JKRUNUCi0gIHwgUEFSQU0KLSAgfCBIUgotICB8IFAKLSAgfCBIMQotICB8IEgyCi0gIHwgSDMKLSAgfCBINAotICB8IEg1Ci0gIHwgSDYKLSAgfCBQUkUKLSAgfCBRCi0gIHwgQkxPQ0tRVU9URQotICB8IElOUwotICB8IERFTAotICB8IERMCi0gIHwgRFQKLSAgfCBERAotICB8IE9MCi0gIHwgVUwKLSAgfCBMSQotICB8IEZPUk0KLSAgfCBMQUJFTAotICB8IElOUFVUCi0gIHwgU0VMRUNUCi0gIHwgT1BUR1JPVVAKLSAgfCBPUFRJT04KLSAgfCBURVhUQVJFQQotICB8IEZJRUxEU0VUCi0gIHwgTEVHRU5ECi0gIHwgQlVUVE9OCi0gIHwgVEFCTEUKLSAgfCBDQVBUSU9OCi0gIHwgVEhFQUQKLSAgfCBURk9PVAotICB8IFRCT0RZCi0gIHwgQ09MR1JPVVAKLSAgfCBDT0wKLSAgfCBUUgotICB8IFRICi0gIHwgVEQKLSAgfCBIRUFECi0gIHwgVElUTEUKLSAgfCBCQVNFCi0gIHwgTUVUQQotICB8IFNUWUxFCi0gIHwgU0NSSVBUCi0gIHwgTk9TQ1JJUFQKLSAgfCBIVE1MCi0iPgotCi08IS0tIGJlZ2luIFhTTFQgRFRELCBwYXRjaGVkIC0tPgotCi08IUVOVElUWSAlIGNoYXItaW5zdHJ1Y3Rpb25zICIKLSB8IHhzbDphcHBseS10ZW1wbGF0ZXMKLSB8IHhzbDpjYWxsLXRlbXBsYXRlCi0gfCB4c2w6YXBwbHktaW1wb3J0cwotIHwgeHNsOmZvci1lYWNoCi0gfCB4c2w6dmFsdWUtb2YKLSB8IHhzbDpjb3B5LW9mCi0gfCB4c2w6bnVtYmVyCi0gfCB4c2w6Y2hvb3NlCi0gfCB4c2w6aWYKLSB8IHhzbDp0ZXh0Ci0gfCB4c2w6Y29weQotIHwgeHNsOnZhcmlhYmxlCi0gfCB4c2w6bWVzc2FnZQotIj4KLQotPCFFTlRJVFkgJSBpbnN0cnVjdGlvbnMgIgotICVjaGFyLWluc3RydWN0aW9uczsKLSB8IHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uCi0gfCB4c2w6Y29tbWVudAotIHwgeHNsOmVsZW1lbnQKLSB8IHhzbDphdHRyaWJ1dGUKLSI+Ci0KLTwhRU5USVRZICUgY2hhci10ZW1wbGF0ZSAiCi0oI1BDREFUQQotICVjaGFyLWluc3RydWN0aW9uczspKgotIj4KLQotPCFFTlRJVFkgJSB0ZW1wbGF0ZSAiCi0oI1BDREFUQQotICVpbnN0cnVjdGlvbnM7Ci0gJXJlc3VsdC1lbGVtZW50czspKgotIj4KLQotPCEtLSBVc2VkIGZvciB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBpcyBhIFVSSSByZWZlcmVuY2UuLS0+Ci08IUVOVElUWSAlIFVSSSAiQ0RBVEEiPgotCi08IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGEgcGF0dGVybi4tLT4KLTwhRU5USVRZICUgcGF0dGVybiAiQ0RBVEEiPgotCi08IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGFuCi0gICAgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlLi0tPgotPCFFTlRJVFkgJSBhdnQgIkNEQVRBIj4KLQotPCEtLSBVc2VkIGZvciB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBpcyBhIFFOYW1lOyB0aGUgcHJlZml4Ci0gICAgZ2V0cyBleHBhbmRlZCBieSB0aGUgWFNMVCBwcm9jZXNzb3IuIC0tPgotPCFFTlRJVFkgJSBxbmFtZSAiTk1UT0tFTiI+Ci0KLTwhLS0gTGlrZSBxbmFtZSBidXQgYSB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIFFOYW1lcy4gLS0+Ci08IUVOVElUWSAlIHFuYW1lcyAiTk1UT0tFTlMiPgotCi08IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGFuIGV4cHJlc3Npb24uLS0+Ci08IUVOVElUWSAlIGV4cHIgIkNEQVRBIj4KLQotPCEtLSBVc2VkIGZvciB0aGUgdHlwZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBjb25zaXN0cwotICAgIG9mIGEgc2luZ2xlIGNoYXJhY3Rlci4tLT4KLTwhRU5USVRZICUgY2hhciAiQ0RBVEEiPgotCi08IS0tIFVzZWQgZm9yIHRoZSB0eXBlIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZSB0aGF0IGlzIGEgcHJpb3JpdHkuIC0tPgotPCFFTlRJVFkgJSBwcmlvcml0eSAiTk1UT0tFTiI+Ci0KLTwhRU5USVRZICUgc3BhY2UtYXR0ICJ4bWw6c3BhY2UgKGRlZmF1bHR8cHJlc2VydmUpICNJTVBMSUVEIj4KLQotPCEtLSBUaGlzIG1heSBiZSBvdmVycmlkZGVuIHRvIGN1c3RvbWl6ZSB0aGUgc2V0IG9mIGVsZW1lbnRzIGFsbG93ZWQKLWF0IHRoZSB0b3AtbGV2ZWwuIC0tPgotCi08IUVOVElUWSAlIG5vbi14c2wtdG9wLWxldmVsICIiPgotCi08IUVOVElUWSAlIHRvcC1sZXZlbCAiCi0oeHNsOmltcG9ydCosCi0gKHhzbDppbmNsdWRlCi0gfCB4c2w6c3RyaXAtc3BhY2UKLSB8IHhzbDpwcmVzZXJ2ZS1zcGFjZQotIHwgeHNsOm91dHB1dAotIHwgeHNsOmtleQotIHwgeHNsOmxvY2FsZQotIHwgeHNsOmF0dHJpYnV0ZS1zZXQKLSB8IHhzbDp2YXJpYWJsZQotIHwgeHNsOnBhcmFtCi0gfCB4c2w6dGVtcGxhdGUKLSAlbm9uLXhzbC10b3AtbGV2ZWw7KSopCi0iPgotCi08IS0tIGFkZGVkIHhtbG5zIGF0dHJpYnV0ZSBzdWl0YWJsZSBmb3IgdGhpcyBEVEQgLS0+Ci08IUVOVElUWSAlIHRvcC1sZXZlbC1hdHRzICcKLSBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyBDREFUQSAjSU1QTElFRAotIGlkIElEICNJTVBMSUVECi0geG1sbnM6eHNsIENEQVRBICNGSVhFRCAiaHR0cDovL3d3dy53My5vcmcvWFNMLzE5OTkvVHJhbnNmb3JtIgotIHhtbG5zIENEQVRBICNGSVhFRCAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MCIKLSAlc3BhY2UtYXR0OwotJz4KLQotPCEtLSBUaGlzIGVudGl0eSBpcyBkZWZpbmVkIGZvciB1c2UgaW4gdGhlIEFUVExJU1QgZGVjbGFyYXRpb24KLWZvciByZXN1bHQgZWxlbWVudHMuIC0tPgotCi08IUVOVElUWSAlIHJlc3VsdC1lbGVtZW50LWF0dHMgJwotIHhzbDpleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyBDREFUQSAjSU1QTElFRAotIHhzbDp1c2UtYXR0cmlidXRlLXNldHMgJXFuYW1lczsgI0lNUExJRUQKLSc+Ci0KLTwhRUxFTUVOVCB4c2w6c3R5bGVzaGVldCAldG9wLWxldmVsOz4KLTwhQVRUTElTVCB4c2w6c3R5bGVzaGVldCAldG9wLWxldmVsLWF0dHM7PgotCi08IUVMRU1FTlQgeHNsOnRyYW5zZm9ybSAldG9wLWxldmVsOz4KLTwhQVRUTElTVCB4c2w6dHJhbnNmb3JtICV0b3AtbGV2ZWwtYXR0czs+Ci0KLTwhRUxFTUVOVCB4c2w6aW1wb3J0IEVNUFRZPgotPCFBVFRMSVNUIHhzbDppbXBvcnQgaHJlZiAlVVJJOyAjUkVRVUlSRUQ+Ci0KLTwhRUxFTUVOVCB4c2w6aW5jbHVkZSBFTVBUWT4KLTwhQVRUTElTVCB4c2w6aW5jbHVkZSBocmVmICVVUkk7ICNSRVFVSVJFRD4KLQotPCFFTEVNRU5UIHhzbDpzdHJpcC1zcGFjZSBFTVBUWT4KLTwhQVRUTElTVCB4c2w6c3RyaXAtc3BhY2UgZWxlbWVudHMgQ0RBVEEgI1JFUVVJUkVEPgotCi08IUVMRU1FTlQgeHNsOnByZXNlcnZlLXNwYWNlIEVNUFRZPgotPCFBVFRMSVNUIHhzbDpwcmVzZXJ2ZS1zcGFjZSBlbGVtZW50cyBDREFUQSAjUkVRVUlSRUQ+Ci0KLTwhRUxFTUVOVCB4c2w6b3V0cHV0IEVNUFRZPgotPCFBVFRMSVNUIHhzbDpvdXRwdXQKLSBtZXRob2QgJXFuYW1lOyAjSU1QTElFRAotIHZlcnNpb24gTk1UT0tFTiAjSU1QTElFRAotIGVuY29kaW5nIE5NVE9LRU4gI0lNUExJRUQKLSB4bWwtZGVjbGFyYXRpb24gKHllc3xubykgI0lNUExJRUQKLSBzdGFuZGFsb25lICh5ZXN8bm8pICNJTVBMSUVECi0gZG9jdHlwZS1wdWJsaWMgQ0RBVEEgI0lNUExJRUQKLSBkb2N0eXBlLXN5c3RlbSBDREFUQSAjSU1QTElFRAotIGNkYXRhLXNlY3Rpb24tZWxlbWVudHMgJXFuYW1lczsgI0lNUExJRUQKLSBpbmRlbnQgKHllc3xubykgI0lNUExJRUQKLSBtZWRpYS10eXBlIENEQVRBICNJTVBMSUVECi0+Ci0KLTwhRUxFTUVOVCB4c2w6a2V5IEVNUFRZPgotPCFBVFRMSVNUIHhzbDprZXkKLSBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gbWF0Y2ggJXBhdHRlcm47ICNSRVFVSVJFRAotIHVzZSAlZXhwcjsgI1JFUVVJUkVECi0+Ci0KLTwhRUxFTUVOVCB4c2w6bG9jYWxlIEVNUFRZPgotPCFBVFRMSVNUIHhzbDpsb2NhbGUKLSBuYW1lICVxbmFtZTsgI0lNUExJRUQKLSBkZWNpbWFsLXNlcGFyYXRvciAlY2hhcjsgIi4iCi0gZ3JvdXBpbmctc2VwYXJhdG9yICVjaGFyOyAiLCIKLSBpbmZpbml0eSBDREFUQSAiJiN4MjIxRTsiCi0gbWludXMtc2lnbiAlY2hhcjsgIi0iCi0gTmFOIENEQVRBICImI3hGRkZEOyIKLSBwZXJjZW50ICVjaGFyOyAiJSIKLSBwZXItbWlsbGUgJWNoYXI7ICImI3gyMDMwOyIKLSB6ZXJvLWRpZ2l0ICVjaGFyOyAiMCIKLSBkaWdpdCAlY2hhcjsgIiMiCi0gcGF0dGVybi1zZXBhcmF0b3IgJWNoYXI7ICI7IgotPgotCi08IUVMRU1FTlQgeHNsOnRlbXBsYXRlCi0oI1BDREFUQQotICVpbnN0cnVjdGlvbnM7Ci0gJXJlc3VsdC1lbGVtZW50czsKLSB8IHhzbDpwYXJhbSkqCi0+Ci0KLTwhQVRUTElTVCB4c2w6dGVtcGxhdGUKLSBtYXRjaCAlcGF0dGVybjsgI0lNUExJRUQKLSBuYW1lICVxbmFtZTsgI0lNUExJRUQKLSBwcmlvcml0eSAlcHJpb3JpdHk7ICNJTVBMSUVECi0gbW9kZSAlcW5hbWU7ICNJTVBMSUVECi0gJXNwYWNlLWF0dDsKLT4KLQotPCFFTEVNRU5UIHhzbDp2YWx1ZS1vZiBFTVBUWT4KLTwhQVRUTElTVCB4c2w6dmFsdWUtb2YKLSBzZWxlY3QgJWV4cHI7ICNSRVFVSVJFRAotIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nICh5ZXN8bm8pICJubyIKLT4KLQotPCFFTEVNRU5UIHhzbDpjb3B5LW9mIEVNUFRZPgotPCFBVFRMSVNUIHhzbDpjb3B5LW9mIHNlbGVjdCAlZXhwcjsgI1JFUVVJUkVEPgotCi08IUVMRU1FTlQgeHNsOm51bWJlciBFTVBUWT4KLTwhQVRUTElTVCB4c2w6bnVtYmVyCi0gIGxldmVsIChzaW5nbGV8bXVsdGlwbGV8YW55KSAic2luZ2xlIgotICBjb3VudCAlcGF0dGVybjsgI0lNUExJRUQKLSAgZnJvbSAlcGF0dGVybjsgI0lNUExJRUQKLSAgdmFsdWUgJWV4cHI7ICNJTVBMSUVECi0gIGZvcm1hdCAlYXZ0OyAnMScKLSAgbGFuZyAlYXZ0OyAjSU1QTElFRAotICBsZXR0ZXItdmFsdWUgJWF2dDsgI0lNUExJRUQKLSAgZ3JvdXBpbmctc2VwYXJhdG9yJWF2dDsgI0lNUExJRUQKLSAgZ3JvdXBpbmctc2l6ZSAlYXZ0OyAjSU1QTElFRAotPgotCi08IUVMRU1FTlQgeHNsOmFwcGx5LXRlbXBsYXRlcyAoeHNsOnNvcnR8eHNsOndpdGgtcGFyYW0pKj4KLTwhQVRUTElTVCB4c2w6YXBwbHktdGVtcGxhdGVzCi0gc2VsZWN0ICVleHByOyAibm9kZSgpIgotIG1vZGUgJXFuYW1lOyAjSU1QTElFRAotPgotCi08IUVMRU1FTlQgeHNsOmFwcGx5LWltcG9ydHMgRU1QVFk+Ci0KLTwhLS0geHNsOnNvcnQgY2Fubm90IG9jY3VyIGFmdGVyIGFueSBvdGhlciBlbGVtZW50cyBvcgotYW55IG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlciAtLT4KLQotPCFFTEVNRU5UIHhzbDpmb3ItZWFjaAotKCNQQ0RBVEEKLSAlaW5zdHJ1Y3Rpb25zOwotICVyZXN1bHQtZWxlbWVudHM7Ci0gfCB4c2w6c29ydCkqCi0+Ci0KLTwhQVRUTElTVCB4c2w6Zm9yLWVhY2gKLSBzZWxlY3QgJWV4cHI7ICNSRVFVSVJFRAotICVzcGFjZS1hdHQ7Ci0+Ci0KLTwhRUxFTUVOVCB4c2w6c29ydCBFTVBUWT4KLTwhQVRUTElTVCB4c2w6c29ydAotIHNlbGVjdCAlZXhwcjsgIi4iCi0gbGFuZyAlYXZ0OyAjSU1QTElFRAotIGRhdGEtdHlwZSAlYXZ0OyAidGV4dCIKLSBvcmRlciAlYXZ0OyAiYXNjZW5kaW5nIgotIGNhc2Utb3JkZXIgJWF2dDsgI0lNUExJRUQKLT4KLQotPCFFTEVNRU5UIHhzbDppZiAldGVtcGxhdGU7PgotPCFBVFRMSVNUIHhzbDppZgotIHRlc3QgJWV4cHI7ICNSRVFVSVJFRAotICVzcGFjZS1hdHQ7Ci0+Ci0KLTwhRUxFTUVOVCB4c2w6Y2hvb3NlICh4c2w6d2hlbissIHhzbDpvdGhlcndpc2U/KT4KLTwhQVRUTElTVCB4c2w6Y2hvb3NlICVzcGFjZS1hdHQ7PgotCi08IUVMRU1FTlQgeHNsOndoZW4gJXRlbXBsYXRlOz4KLTwhQVRUTElTVCB4c2w6d2hlbgotIHRlc3QgJWV4cHI7ICNSRVFVSVJFRAotICVzcGFjZS1hdHQ7Ci0+Ci0KLTwhRUxFTUVOVCB4c2w6b3RoZXJ3aXNlICV0ZW1wbGF0ZTs+Ci08IUFUVExJU1QgeHNsOm90aGVyd2lzZSAlc3BhY2UtYXR0Oz4KLQotPCFFTEVNRU5UIHhzbDphdHRyaWJ1dGUtc2V0ICh4c2w6YXR0cmlidXRlKSo+Ci08IUFUVExJU1QgeHNsOmF0dHJpYnV0ZS1zZXQKLSBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gdXNlLWF0dHJpYnV0ZS1zZXRzICVxbmFtZXM7ICNJTVBMSUVECi0+Ci0KLTwhRUxFTUVOVCB4c2w6Y2FsbC10ZW1wbGF0ZSAoeHNsOndpdGgtcGFyYW0pKj4KLTwhQVRUTElTVCB4c2w6Y2FsbC10ZW1wbGF0ZQotIG5hbWUgJXFuYW1lOyAjUkVRVUlSRUQKLT4KLQotPCFFTEVNRU5UIHhzbDp3aXRoLXBhcmFtICV0ZW1wbGF0ZTs+Ci08IUFUVExJU1QgeHNsOndpdGgtcGFyYW0KLSBuYW1lICVxbmFtZTsgI1JFUVVJUkVECi0gc2VsZWN0ICVleHByOyAjSU1QTElFRAotPgotCi08IUVMRU1FTlQgeHNsOnZhcmlhYmxlICV0ZW1wbGF0ZTs+Ci08IUFUVExJU1QgeHNsOnZhcmlhYmxlIAotIG5hbWUgJXFuYW1lOyAjUkVRVUlSRUQKLSBzZWxlY3QgJWV4cHI7ICNJTVBMSUVECi0+Ci0KLTwhRUxFTUVOVCB4c2w6cGFyYW0gJXRlbXBsYXRlOz4KLTwhQVRUTElTVCB4c2w6cGFyYW0gCi0gbmFtZSAlcW5hbWU7ICNSRVFVSVJFRAotIHNlbGVjdCAlZXhwcjsgI0lNUExJRUQKLT4KLQotPCFFTEVNRU5UIHhzbDp0ZXh0ICgjUENEQVRBKT4KLTwhQVRUTElTVCB4c2w6dGV4dAotIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nICh5ZXN8bm8pICJubyIKLT4KLQotPCFFTEVNRU5UIHhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uICVjaGFyLXRlbXBsYXRlOz4KLTwhQVRUTElTVCB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbiAKLSBuYW1lICVhdnQ7ICNSRVFVSVJFRAotICVzcGFjZS1hdHQ7Ci0+Ci0KLTwhRUxFTUVOVCB4c2w6ZWxlbWVudCAldGVtcGxhdGU7PgotPCFBVFRMSVNUIHhzbDplbGVtZW50IAotIG5hbWUgJWF2dDsgI1JFUVVJUkVECi0gbmFtZXNwYWNlICVhdnQ7ICNJTVBMSUVECi0gdXNlLWF0dHJpYnV0ZS1zZXRzICVxbmFtZXM7ICNJTVBMSUVECi0gJXNwYWNlLWF0dDsKLT4KLQotPCFFTEVNRU5UIHhzbDphdHRyaWJ1dGUgJWNoYXItdGVtcGxhdGU7PgotPCFBVFRMSVNUIHhzbDphdHRyaWJ1dGUgCi0gbmFtZSAlYXZ0OyAjUkVRVUlSRUQKLSBuYW1lc3BhY2UgJWF2dDsgI0lNUExJRUQKLSAlc3BhY2UtYXR0OwotPgotCi08IUVMRU1FTlQgeHNsOmNvbW1lbnQgJWNoYXItdGVtcGxhdGU7PgotPCFBVFRMSVNUIHhzbDpjb21tZW50ICVzcGFjZS1hdHQ7PgotCi08IUVMRU1FTlQgeHNsOmNvcHkgJXRlbXBsYXRlOz4KLTwhQVRUTElTVCB4c2w6Y29weQotICVzcGFjZS1hdHQ7Ci0gdXNlLWF0dHJpYnV0ZS1zZXRzICVxbmFtZXM7ICNJTVBMSUVECi0+Ci0KLTwhRUxFTUVOVCB4c2w6bWVzc2FnZSAldGVtcGxhdGU7PgotPCFBVFRMSVNUIHhzbDptZXNzYWdlICVzcGFjZS1hdHQ7PgotCi08IUVMRU1FTlQgeHNsOmZhbGxiYWNrICV0ZW1wbGF0ZTs+Ci08IUFUVExJU1QgeHNsOmZhbGxiYWNrICVzcGFjZS1hdHQ7PgotCi0KLQotPCEtLSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgLS0+Ci08IS0tICAgSFRNTCA0LjAgU3RyaWN0IERURCAgIChyZXZpc2VkIHRvIGFsbG93IGZvciB4c2wgY29udGVudCkgICAgICAgICAgICAgICAtLT4KLTwhLS0gICBPcmlnaW5hbCBEVEQgZnJvbSBYTUw0SiBwYWNrYWdlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgotPCEtLSAgIE9yaWdpbmFsIFNHTUwgdG8gWE1MIGNvbnZlcnNpb24gYnkgVEFNVVJBLCBLZW50IGZvciBJQk0ncyBYTUw0SiAgICAgICAgLS0+Ci0KLTwhLS0gCi0gICAgIENvbnRhaW5lciBmb3IgYWxsIHhzbCBlbGVtZW50cyBhbGxvd2VkIGluc2lkZSByZXN1bHQtZWxlbWVudHMgZWxlbWVudHMsCi0gICAgIGkuZS46IGFsbCB4c2wgZWxlbWVudHMgd2hpY2ggYXJlIHZhbGlkIHdoZXJlIGEgcmVzdWx0LWVsZW1lbnQgaXMgdmFsaWQsCi0gICAgIGFuZCB0aGVyZWZvcmUgbXVzdCBiZSB2YWxpZCBpbnNpZGUgQUxMIG5vbi1lbXB0eSBIVE1MIGVsZW1lbnRzLgotCi0gICAgIFlvdSdsbCBub3RpY2UgdGhpcyBkb2VzIGFsbG93IHRoZSB1c2VyIHRvIGNyZWF0ZSBpbnZhbGlkIFhTTCBkb2N1bWVudHMuCi0KLSAgeHNsOnNvcnQsIHhzbDpwYXJhbSwgeHNsOnBhcmFtLXZhcmlhYmxlIHdlcmUgbm90IGlubHVkZWQgYmVjYXVzZQotICBJTUhPIGl0IGlzIGJhZCBwcmFjdGljZSAoYW5kIGFuIGVycm9yPykgbm90IHRvIGluY2x1ZGUgdGhlbSBiZWZvcmUgCi0gIG90aGVyIHNpYmxpbmdzLCBlc3BlY2lhbGx5IHJlc3VsdC1ucyBvbmVzLgotLS0+Ci0KLTwhLS0gV2hpbGUgdGhlIGNvbnRlbnQgc2hvdWxkIGJlIHNpbXBseSAlaW5zdHJ1Y3Rpb25zOyB3ZSBjYW5ub3QgZG8gdGhhdAotICAgICBkdWUgdG8gdGhlIGZpcnN0ICd8JyBpbiAlaW5zdHJ1Y3Rpb25zIC0tPgotPCFFTlRJVFkgJSB4c2wtdmFsaWQtaW4tcmVzdWx0bnMgIgotICB4c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbgotICB8IHhzbDpjb21tZW50Ci0gIHwgeHNsOmVsZW1lbnQKLSAgfCB4c2w6YXR0cmlidXRlCi0gICVjaGFyLWluc3RydWN0aW9uczsKLSI+Ci0KLTwhLS0gQWxzbywgJXJlc3VsdC1lbGVtZW50LWF0dHM7IHdhcyBhZGRlZCB0byB0aGUgQVRUTElTVCBvZiBhbGwgaHRtbAotICAgICBlbG1lbnRzIC0tPgotCi08IS0tIFJldmlzaW9uOiAyMyAxLjMgZG9jcy9kYXRhL0hUTUw0MHN0cmljdC54bWwuZHRkLCB4bWw0amRvY3MsIHhtbDRqLWp0Y3N2LCB4bWw0al8xXzFfOSAgLS0+Ci0KLTwhLS0KLSAgICBUaGlzIGlzIEhUTUwgNC4wIFN0cmljdCBEVEQsIHdoaWNoIGV4Y2x1ZGVzIHRoZSBwcmVzZW50YXRpb24gCi0gICAgYXR0cmlidXRlcyBhbmQgZWxlbWVudHMgdGhhdCBXM0MgZXhwZWN0cyB0byBwaGFzZSBvdXQgYXMgCi0gICAgc3VwcG9ydCBmb3Igc3R5bGUgc2hlZXRzIG1hdHVyZXMuIEF1dGhvcnMgc2hvdWxkIHVzZSB0aGUgU3RyaWN0Ci0gICAgRFREIHdoZW4gcG9zc2libGUsIGJ1dCBtYXkgdXNlIHRoZSBUcmFuc2l0aW9uYWwgRFREIHdoZW4gc3VwcG9ydAotICAgIGZvciBwcmVzZW50YXRpb24gYXR0cmlidXRlIGFuZCBlbGVtZW50cyBpcyByZXF1aXJlZC4KLSAgICAKLSAgICBIVE1MIDQuMCBpbmNsdWRlcyBtZWNoYW5pc21zIGZvciBzdHlsZSBzaGVldHMsIHNjcmlwdGluZywKLSAgICBlbWJlZGRpbmcgb2JqZWN0cywgaW1wcm92ZWQgc3VwcG9ydCBmb3IgcmlnaHQgdG8gbGVmdCBhbmQgbWl4ZWQKLSAgICBkaXJlY3Rpb24gdGV4dCwgYW5kIGVuaGFuY2VtZW50cyB0byBmb3JtcyBmb3IgaW1wcm92ZWQKLSAgICBhY2Nlc3NpYmlsaXR5IGZvciBwZW9wbGUgd2l0aCBkaXNhYmlsaXRpZXMuCi0KLSAgICAgICAgICBEcmFmdDogRGF0ZTogMTk5OC8wNy8wNiAxNzo1MDozMgotCi0gICAgICAgICAgQXV0aG9yczoKLSAgICAgICAgICAgICAgRGF2ZSBSYWdnZXR0IDxkc3JAdzMub3JnPgotICAgICAgICAgICAgICBBcm5hdWQgTGUgSG9ycyA8bGVob3JzQHczLm9yZz4KLSAgICAgICAgICAgICAgSWFuIEphY29icyA8aWpAdzMub3JnPgotCi0gICAgRnVydGhlciBpbmZvcm1hdGlvbiBhYm91dCBIVE1MIDQuMCBpcyBhdmFpbGFibGUgYXQ6Ci0KLSAgICAgICAgaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MAotLS0+Ci0KLTwhLS0KLSAgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0gICAgTW9kaWZpZWQgZm9yIFhNTCAxLjAgYnk6Ci0JIlRBTVVSQSwgS2VudCIgPGtlbnRAdHJsLmlibS5jby5qcD4KLQotICAgIG8gSFRNTHNwZWNpYWwsIEhUTUxzeW1ib2wsIEhUTUxsYXQxIGFyZW4ndCBpbmNsdWRlZCBpbiB0aGlzIERURC4KLSAgICBvIFRoZSBgbGFuZycgYXR0cmlidXRlIHdhcyByZW5hbWVkIHRvIGB4bWw6bGFuZycuCi0KLQotICAgIFR5cGljYWwgdXNhZ2U6Ci0KLSAgICA8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSIuLi4iPz4KLSAgICA8IURPQ1RZUEUgSFRNTCBTWVNURU0gIi4uLi9IVE1MNDBzdHJpY3QueG1sLmR0ZCI+Ci0gICAgPEhUTUw+Ci0gICAgICA8SEVBRD4KLSAgICAgICAgLi4uCi0gICAgICAgIDxUSVRMRT4uLi48L1RJVExFPgotICAgICAgICAuLi4KLSAgICAgIDwvSEVBRD4KLSAgICAgIDxCT0RZPgotICAgICAgICAuLi4KLSAgICAgIDwvQk9EWT4KLSAgICA8L0hUTUw+Ci0KLSAgICBOb3RlOiBYTUwgaXMgY2FzZS1zZW5zaXRpdmUuICBTbyBlbGVtZW50IG5hbWVzIG11c3QgYmUgd3JpdHRlbgotICAgIGluIHVwcGVyY2FzZSBhbmQgYXR0cmlidXRlIG5hbWVzIG11c3QgYmUgd3JpdHRlbiBpbiBsb3dlcmNhc2UuCi0gICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0+Ci0KLTwhLS0KLSAgICBUeXBpY2FsIHVzYWdlOgotCi0gICAgPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMC8vRU4iCi0gICAgICAgICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9zdHJpY3QuZHRkIj4KLSAgICA8aHRtbD4KLSAgICA8aGVhZD4KLSAgICAuLi4KLSAgICA8L2hlYWQ+Ci0gICAgPGJvZHk+Ci0gICAgLi4uCi0gICAgPC9ib2R5PgotICAgIDwvaHRtbD4KLQotICAgIFRoZSBVUkkgdXNlZCBhcyBhIHN5c3RlbSBpZGVudGlmaWVyIHdpdGggdGhlIHB1YmxpYyBpZGVudGlmaWVyIGFsbG93cwotICAgIHRoZSB1c2VyIGFnZW50IHRvIGRvd25sb2FkIHRoZSBEVEQgYW5kIGVudGl0eSBzZXRzIGFzIG5lZWRlZC4KLQotICAgIFRoZSBGUEkgZm9yIHRoZSBUcmFuc2l0aW9uYWwgSFRNTCA0LjAgRFREIGlzOgotCi0gICAgICAgICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIgotCi0gICAgYW5kIGl0cyBVUkkgaXM6Ci0KLSAgICAgICAgaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9sb29zZS5kdGQKLQotICAgIElmIHlvdSBhcmUgd3JpdGluZyBhIGRvY3VtZW50IHRoYXQgaW5jbHVkZXMgZnJhbWVzLCB1c2UgCi0gICAgdGhlIGZvbGxvd2luZyBGUEk6Ci0KLSAgICAgICAgIi0vL1czQy8vRFREIEhUTUwgNC4wIEZyYW1lc2V0Ly9FTiIKLQotICAgIHdpdGggdGhlIFVSSToKLQotICAgICAgICBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL2ZyYW1lc2V0LmR0ZAotCi0gICAgVGhlIGZvbGxvd2luZyBVUklzIGFyZSBzdXBwb3J0ZWQgaW4gcmVsYXRpb24gdG8gSFRNTCA0LjAKLQotICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL3N0cmljdC5kdGQiIChTdHJpY3QgRFREKQotICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwL2xvb3NlLmR0ZCIgKExvb3NlIERURCkKLSAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9mcmFtZXNldC5kdGQiIChGcmFtZXNldCBEVEQpCi0gICAgImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvSFRNTGxhdDEuZW50IiAoTGF0aW4tMSBlbnRpdGllcykKLSAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9IVE1Mc3ltYm9sLmVudCIgKFN5bWJvbCBlbnRpdGllcykKLSAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9IVE1Mc3BlY2lhbC5lbnQiIChTcGVjaWFsIGVudGl0aWVzKQotCi0gICAgVGhlc2UgVVJJcyBwb2ludCB0byB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgZWFjaCBmaWxlLiBUbyByZWZlcmVuY2UKLSAgICB0aGlzIHNwZWNpZmljIHJldmlzaW9uIHVzZSB0aGUgZm9sbG93aW5nIFVSSXM6Ci0KLSAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC05NzEyMTgvc3RyaWN0LmR0ZCIKLSAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC05NzEyMTgvbG9vc2UuZHRkIgotICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwLTk3MTIxOC9mcmFtZXNldC5kdGQiCi0gICAgImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAtOTcxMjE4L0hUTUxsYXQxLmVudCIKLSAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC05NzEyMTgvSFRNTHN5bWJvbC5lbnQiCi0gICAgImh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAtOTcxMjE4L0hUTUxzcGVjaWFsLmVudCIKLQotLS0+Ci0KLTwhLS09PT0gZm9yIFhNTCA9PT0tLT4KLTwhRU5USVRZICUgTnVtYmVyICJDREFUQSI+Ci08IUVOVElUWSAlIE5hbWUgIk5NVE9LRU4iPgotCi0KLTwhLS09PT09PT09PT09PT09PT09PT0gSW1wb3J0ZWQgTmFtZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09LS0+Ci0KLTwhRU5USVRZICUgQ29udGVudFR5cGUgIkNEQVRBIgotPiA8IS0tIG1lZGlhIHR5cGUsIGFzIHBlciBbUkZDMjA0NV0KLSAgICAtLT4KLQotPCFFTlRJVFkgJSBDb250ZW50VHlwZXMgIkNEQVRBIgotPiA8IS0tIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIG1lZGlhIHR5cGVzLCBhcyBwZXIgW1JGQzIwNDVdCi0gICAgLS0+Ci0KLTwhRU5USVRZICUgQ2hhcnNldCAiQ0RBVEEiCi0+IDwhLS0gYSBjaGFyYWN0ZXIgZW5jb2RpbmcsIGFzIHBlciBbUkZDMjA0NV0KLSAgICAtLT4KLQotPCFFTlRJVFkgJSBDaGFyc2V0cyAiQ0RBVEEiCi0+IDwhLS0gYSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBjaGFyYWN0ZXIgZW5jb2RpbmdzLCBhcyBwZXIgW1JGQzIwNDVdCi0gICAgLS0+Ci0KLTwhRU5USVRZICUgTGFuZ3VhZ2VDb2RlICJOTVRPS0VOIgotPiA8IS0tIGEgbGFuZ3VhZ2UgY29kZSwgYXMgcGVyIFtSRkMxNzY2XQotICAgIC0tPgotCi08IUVOVElUWSAlIENoYXJhY3RlciAiQ0RBVEEiCi0+IDwhLS0gYSBzaW5nbGUgY2hhcmFjdGVyIGZyb20gW0lTTzEwNjQ2XSAKLSAgICAtLT4KLQotPCFFTlRJVFkgJSBMaW5rVHlwZXMgIkNEQVRBIgotPiA8IS0tIHNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIGxpbmsgdHlwZXMKLSAgICAtLT4KLQotPCFFTlRJVFkgJSBNZWRpYURlc2MgIkNEQVRBIgotPiA8IS0tIHNpbmdsZSBvciBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBtZWRpYSBkZXNjcmlwdG9ycwotICAgIC0tPgotCi08IS0tIERlZmluZWQgZWxzZXdoZXJlIGluIHRoaXMgRFRECi08IUVOVElUWSAlIFVSSSAiQ0RBVEEiCi0+IDwhIGEgVW5pZm9ybSBSZXNvdXJjZSBJZGVudGlmaWVyLAotICAgICAgIHNlZSBbVVJJXQotICAgIC0tPgotCi08IUVOVElUWSAlIERhdGV0aW1lICJDREFUQSI+PCEtLSBkYXRlIGFuZCB0aW1lIGluZm9ybWF0aW9uLiBJU08gZGF0ZSBmb3JtYXQgLS0+Ci0KLQotPCFFTlRJVFkgJSBTY3JpcHQgIkNEQVRBIj48IS0tIHNjcmlwdCBleHByZXNzaW9uIC0tPgotCi08IUVOVElUWSAlIFN0eWxlU2hlZXQgIkNEQVRBIj48IS0tIHN0eWxlIHNoZWV0IGRhdGEgLS0+Ci0KLQotCi08IUVOVElUWSAlIFRleHQgIkNEQVRBIj4KLQotCi08IS0tIFBhcmFtZXRlciBFbnRpdGllcyAtLT4KLQotPCFFTlRJVFkgJSBoZWFkLm1pc2MgIlNDUklQVHxTVFlMRXxNRVRBfExJTkt8T0JKRUNUIj48IS0tIHJlcGVhdGFibGUgaGVhZCBlbGVtZW50cyAtLT4KLTwhRU5USVRZICUgaGVhZGluZyAiSDF8SDJ8SDN8SDR8SDV8SDYiPgotPCFFTlRJVFkgJSBsaXN0ICJVTCB8IE9MIj4KLTwhRU5USVRZICUgcHJlZm9ybWF0dGVkICJQUkUiPgotCi0KLTwhLS09PT09PT09PT09PT09PT09IENoYXJhY3RlciBtbmVtb25pYyBlbnRpdGllcyA9PT09PT09PT09PT09PT09PT09PT09PT09LS0+Ci0KLTwhLS1FTlRJVFkgJSBIVE1MbGF0MSBQVUJMSUMKLSAgICItLy9XM0MvL0VOVElUSUVTIExhdGluMS8vRU4vL0hUTUwiCi0gICAiSFRNTGxhdDEuZW50Ii0tPgotPCEtLSAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwLTk3MTIxOC9IVE1MbGF0MS5lbnQiLS0+Ci08IS0tJUhUTUxsYXQxOy0tPgotCi08IS0tRU5USVRZICUgSFRNTHN5bWJvbCBQVUJMSUMKLSAgICItLy9XM0MvL0VOVElUSUVTIFN5bWJvbHMvL0VOLy9IVE1MIgotICAgIkhUTUxzeW1ib2wuZW50Ii0tPgotPCEtLSAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwLTk3MTIxOC9IVE1Mc3ltYm9sLmVudCItLT4KLTwhLS0lSFRNTHN5bWJvbDstLT4KLQotPCEtLUVOVElUWSAlIEhUTUxzcGVjaWFsIFBVQkxJQwotICAgIi0vL1czQy8vRU5USVRJRVMgU3BlY2lhbC8vRU4vL0hUTUwiCi0gICAiSFRNTHNwZWNpYWwuZW50Ii0tPgotPCEtLSAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwLTk3MTIxOC9IVE1Mc3BlY2lhbC5lbnQiLS0+Ci08IS0tJUhUTUxzcGVjaWFsOy0tPgotCi08IS0tIFdlIGRlZmluZSB0aGVzZSBlbHNld2hlcmUgaW4gdGhpcyBtaXhlZCBEVEQKLTwhRU5USVRZIHF1b3QgIiYjMzQ7Ij4KLTwhRU5USVRZIGFtcCAgIiYjMzg7Ij4KLTwhRU5USVRZIGx0ICAgIiYjNjA7Ij4KLTwhRU5USVRZIGd0ICAgIiYjNjI7Ij4KLS0tPgotCi08IS0tPT09PT09PT09PT09PT09PT09PSBHZW5lcmljIEF0dHJpYnV0ZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IUVOVElUWSAlIGNvcmVhdHRycwotICJpZCAgICAgICAgICBJRCAgICAgICAgICAgICAjSU1QTElFRAotICBjbGFzcyAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICBzdHlsZSAgICAgICAlU3R5bGVTaGVldDsgICAjSU1QTElFRAotICB0aXRsZSAgICAgICAlVGV4dDsgICAgICAgICAjSU1QTElFRAotICAlcmVzdWx0LWVsZW1lbnQtYXR0czsiCi0+Ci0KLTwhRU5USVRZICUgaTE4bgotICJ4bWw6bGFuZyAgICAlTGFuZ3VhZ2VDb2RlOyAjSU1QTElFRAotICBkaXIgICAgICAgICAobHRyfHJ0bCkgICAgICAjSU1QTElFRCIKLSAgPgotCi08IUVOVElUWSAlIGV2ZW50cwotICJvbmNsaWNrICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmRibGNsaWNrICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbm1vdXNlZG93biAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbm1vdXNldXAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbm1vdXNlb3ZlciAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbm1vdXNlbW92ZSAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbm1vdXNlb3V0ICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmtleXByZXNzICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmtleWRvd24gICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmtleXVwICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRCIKLSAgPgotCi08IS0tIFJlc2VydmVkIEZlYXR1cmUgU3dpdGNoIC0tPgotPCFFTlRJVFkgJSBIVE1MLlJlc2VydmVkICJJR05PUkUiPgotCi08IS0tIFRoZSBmb2xsb3dpbmcgYXR0cmlidXRlcyBhcmUgcmVzZXJ2ZWQgZm9yIHBvc3NpYmxlIGZ1dHVyZSB1c2UgLS0+Ci08IVsgJUhUTUwuUmVzZXJ2ZWQ7IFsKLTwhRU5USVRZICUgcmVzZXJ2ZWQKLSAiZGF0YXNyYyAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgZGF0YWZsZCAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgZGF0YWZvcm1hdGFzIChwbGFpbnRleHR8aHRtbCkgcGxhaW50ZXh0IgotICA+Ci1dXT4KLQotPCFFTlRJVFkgJSByZXNlcnZlZCAiIj4KLQotPCFFTlRJVFkgJSBhdHRycyAiJWNvcmVhdHRyczsgJWkxOG47ICVldmVudHM7Ij4KLQotCi08IS0tPT09PT09PT09PT09PT09PT09PSBUZXh0IE1hcmt1cCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IUVOVElUWSAlIGZvbnRzdHlsZQotICJUVCB8IEkgfCBCIHwgQklHIHwgU01BTEwiPgotCi08IUVOVElUWSAlIHBocmFzZSAiRU0gfCBTVFJPTkcgfCBERk4gfCBDT0RFIHwKLSAgICAgICAgICAgICAgICAgICBTQU1QIHwgS0JEIHwgVkFSIHwgQ0lURSB8IEFCQlIgfCBBQ1JPTllNIiA+Ci0KLTwhRU5USVRZICUgc3BlY2lhbAotICAgIkEgfCBJTUcgfCBPQkpFQ1QgfCBCUiB8IFNDUklQVCB8IE1BUCB8IFEgfCBTVUIgfCBTVVAgfCBTUEFOIHwgQkRPIj4KLTwhRU5USVRZICUgc3BlY2lhbC1BCi0gICAiSU1HIHwgT0JKRUNUIHwgQlIgfCBTQ1JJUFQgfCBNQVAgfCBRIHwgU1VCIHwgU1VQIHwgU1BBTiB8IEJETyI+Ci0KLTwhRU5USVRZICUgZm9ybWN0cmwgIklOUFVUIHwgU0VMRUNUIHwgVEVYVEFSRUEgfCBMQUJFTCB8IEJVVFRPTiI+Ci0KLTwhLS0gJWlubGluZTsgY292ZXJzIGlubGluZSBvciAidGV4dC1sZXZlbCIgZWxlbWVudHMgLS0+Ci08IUVOVElUWSAlIGlubGluZSAiI1BDREFUQSB8ICVmb250c3R5bGU7IHwgJXBocmFzZTsgfCAlc3BlY2lhbDsgfCAlZm9ybWN0cmw7Ij4KLTwhRU5USVRZICUgaW5saW5lLUEgIiNQQ0RBVEEgfCAlZm9udHN0eWxlOyB8ICVwaHJhc2U7IHwgJXNwZWNpYWwtQTsgfCAlZm9ybWN0cmw7Ij4KLTwhRU5USVRZICUgaW5saW5lLUxBQkVMICIjUENEQVRBIHwgJWZvbnRzdHlsZTsgfCAlcGhyYXNlOyB8ICVzcGVjaWFsOyB8IElOUFVUIHwgU0VMRUNUIHwgVEVYVEFSRUEgfCBCVVRUT04iPgotCi08IS0tCi08IUVMRU1FTlQgKCVmb250c3R5bGU7fCVwaHJhc2U7KSAgICAgKCVpbmxpbmU7KSo+Ci08IUFUVExJU1QgKCVmb250c3R5bGU7fCVwaHJhc2U7KQotICAlYXR0cnM7Ci0gID4tLT4KLTwhRUxFTUVOVCBUVCAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIFRUICVhdHRyczs+Ci08IUVMRU1FTlQgSSAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEkgJWF0dHJzOz4KLTwhRUxFTUVOVCBCICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgQiAlYXR0cnM7PgotPCFFTEVNRU5UIEJJRyAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEJJRyAlYXR0cnM7PgotPCFFTEVNRU5UIFNNQUxMICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgU01BTEwgJWF0dHJzOz4KLTwhRUxFTUVOVCBFTSAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEVNICVhdHRyczs+Ci08IUVMRU1FTlQgU1RST05HICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgU1RST05HICVhdHRyczs+Ci08IUVMRU1FTlQgREZOICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgREZOICVhdHRyczs+Ci08IUVMRU1FTlQgQ09ERSAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIENPREUgJWF0dHJzOz4KLTwhRUxFTUVOVCBTQU1QICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgU0FNUCAlYXR0cnM7PgotPCFFTEVNRU5UIEtCRCAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEtCRCAlYXR0cnM7PgotPCFFTEVNRU5UIFZBUiAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIFZBUiAlYXR0cnM7PgotPCFFTEVNRU5UIENJVEUgKCVpbmxpbmU7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj4KLTwhQVRUTElTVCBDSVRFICVhdHRyczs+Ci08IUVMRU1FTlQgQUJCUiAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEFCQlIgJWF0dHJzOz4KLTwhRUxFTUVOVCBBQ1JPTllNICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgQUNST05ZTSAlYXR0cnM7PgotCi0KLTwhRUxFTUVOVCBTVVAgKCVpbmxpbmU7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj48IS0tIHN1YnNjcmlwdCwgc3VwZXJzY3JpcHQgLS0+Ci08IUFUVExJU1QgU1VQCi0gICVhdHRyczsKLSAgPgotPCFFTEVNRU5UIFNVQiAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gc3Vic2NyaXB0LCBzdXBlcnNjcmlwdCAtLT4KLTwhQVRUTElTVCBTVUIKLSAgJWF0dHJzOwotICA+Ci0KLTwhRUxFTUVOVCBTUEFOICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBnZW5lcmljIGxhbmd1YWdlL3N0eWxlIGNvbnRhaW5lciAtLT4KLTwhQVRUTElTVCBTUEFOCi0gICVhdHRyczsKLSAgJXJlc2VydmVkOwkJCQotICA+Ci0KLTwhRUxFTUVOVCBCRE8gKCVpbmxpbmU7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj48IS0tIEkxOE4gQmlEaSBvdmVyLXJpZGUgLS0+Ci08IUFUVExJU1QgQkRPCi0gICVjb3JlYXR0cnM7Ci0gIGxhbmcgICAgICAgICVMYW5ndWFnZUNvZGU7ICNJTVBMSUVECi0gIGRpciAgICAgICAgIChsdHJ8cnRsKSAgICAgICNSRVFVSVJFRAotICA+Ci0KLQotPCFFTEVNRU5UIEJSICAgICBFTVBUWT48IS0tIGZvcmNlZCBsaW5lIGJyZWFrIC0tPgotPCFBVFRMSVNUIEJSCi0gICVjb3JlYXR0cnM7Ci0gID4KLQotPCEtLT09PT09PT09PT09PT09PT09PSBIVE1MIGNvbnRlbnQgbW9kZWxzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0tLT4KLQotPCEtLQotICAgIEhUTUwgaGFzIHR3byBiYXNpYyBjb250ZW50IG1vZGVsczoKLQotICAgICAgICAlaW5saW5lOyAgICAgY2hhcmFjdGVyIGxldmVsIGVsZW1lbnRzIGFuZCB0ZXh0IHN0cmluZ3MKLSAgICAgICAgJWJsb2NrOyAgICAgIGJsb2NrLWxpa2UgZWxlbWVudHMgZS5nLiBwYXJhZ3JhcGhzIGFuZCBsaXN0cwotLS0+Ci0KLTwhRU5USVRZICUgYmxvY2sKLSAgICAgIlAgfCAlaGVhZGluZzsgfCAlbGlzdDsgfCAlcHJlZm9ybWF0dGVkOyB8IERMIHwgRElWIHwgTk9TQ1JJUFQgfAotICAgICAgQkxPQ0tRVU9URSB8IEZPUk0gfCBIUiB8IFRBQkxFIHwgRklFTERTRVQgfCBBRERSRVNTIj4KLTwhRU5USVRZICUgYmxvY2stRk9STQotICAgICAiUCB8ICVoZWFkaW5nOyB8ICVsaXN0OyB8ICVwcmVmb3JtYXR0ZWQ7IHwgREwgfCBESVYgfCBOT1NDUklQVCB8Ci0gICAgICBCTE9DS1FVT1RFIHwgSFIgfCBUQUJMRSB8IEZJRUxEU0VUIHwgQUREUkVTUyI+Ci08IUVOVElUWSAlIGJsb2NrLUZPUk0tRklFTERTRVQKLSAgICAgIlAgfCAlaGVhZGluZzsgfCAlbGlzdDsgfCAlcHJlZm9ybWF0dGVkOyB8IERMIHwgRElWIHwgTk9TQ1JJUFQgfAotICAgICAgQkxPQ0tRVU9URSB8IEhSIHwgVEFCTEUgfCBBRERSRVNTIj4KLQotPCEtLTwhRU5USVRZICUgZmxvdyAiJWJsb2NrOyB8ICVpbmxpbmU7Ij4tLT4KLTwhRU5USVRZICUgZmxvdyAiJWlubGluZTsgfCAlYmxvY2s7Ij4KLQotPCEtLT09PT09PT09PT09PT09PT09PT0gRG9jdW1lbnQgQm9keSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0tLT4KLQotPCEtLUVMRU1FTlQgQk9EWSAgICAgKCVibG9jazt8U0NSSVBUKSsgKyhJTlN8REVMKSAgZG9jdW1lbnQgYm9keSAtLT4KLTwhRUxFTUVOVCBCT0RZICgoSU5TfERFTCkqLCAoJXhzbC12YWxpZC1pbi1yZXN1bHRuczt8JWJsb2NrO3xTQ1JJUFQpLCAoSU5TfERFTCkqKSsgPjwhLS0gZG9jdW1lbnQgYm9keSAtLT4KLTwhQVRUTElTVCBCT0RZCi0gICVhdHRyczsKLSAgb25sb2FkICAgICAgICAgICVTY3JpcHQ7ICAgI0lNUExJRUQKLSAgb251bmxvYWQgICAgICAgICVTY3JpcHQ7ICAgI0lNUExJRUQKLSAgPgotCi08IUVMRU1FTlQgQUREUkVTUyAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gaW5mb3JtYXRpb24gb24gYXV0aG9yIC0tPgotPCFBVFRMSVNUIEFERFJFU1MKLSAgJWF0dHJzOwotICA+Ci0KLTwhRUxFTUVOVCBESVYgKCVmbG93OyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBnZW5lcmljIGxhbmd1YWdlL3N0eWxlIGNvbnRhaW5lciAtLT4KLTwhQVRUTElTVCBESVYKLSAgJWF0dHJzOwotICAlcmVzZXJ2ZWQ7Ci0gID4KLQotCi08IS0tPT09PT09PT09PT09PT09PT09IFRoZSBBbmNob3IgRWxlbWVudCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IUVOVElUWSAlIFNoYXBlICIocmVjdHxjaXJjbGV8cG9seXxkZWZhdWx0KSI+Ci08IUVOVElUWSAlIENvb3JkcyAiQ0RBVEEiPjwhLS0gY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgbGVuZ3RocyAtLT4KLQotPCFFTEVNRU5UIEEgKCVpbmxpbmUtQTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gYW5jaG9yIC0tPgotPCFBVFRMSVNUIEEKLSAgJWF0dHJzOwotICBjaGFyc2V0ICAgICAlQ2hhcnNldDsgICAgICAjSU1QTElFRAotICB0eXBlICAgICAgICAlQ29udGVudFR5cGU7ICAjSU1QTElFRAotICBuYW1lICAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICBocmVmICAgICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICBocmVmbGFuZyAgICAlTGFuZ3VhZ2VDb2RlOyAjSU1QTElFRAotICByZWwgICAgICAgICAlTGlua1R5cGVzOyAgICAjSU1QTElFRAotICByZXYgICAgICAgICAlTGlua1R5cGVzOyAgICAjSU1QTElFRAotICBhY2Nlc3NrZXkgICAlQ2hhcmFjdGVyOyAgICAjSU1QTElFRAotICBzaGFwZSAgICAgICAlU2hhcGU7ICAgICAgICAicmVjdCIKLSAgY29vcmRzICAgICAgJUNvb3JkczsgICAgICAgI0lNUExJRUQKLSAgdGFiaW5kZXggICAgJU51bWJlcjsgICAgICAgI0lNUExJRUQKLSAgb25mb2N1cyAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgb25ibHVyICAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PT09IENsaWVudC1zaWRlIGltYWdlIG1hcHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IS0tIFRoZXNlIGNhbiBiZSBwbGFjZWQgaW4gdGhlIHNhbWUgZG9jdW1lbnQgb3IgZ3JvdXBlZCBpbiBhCi0gICAgIHNlcGFyYXRlIGRvY3VtZW50IGFsdGhvdWdoIHRoaXMgaXNuJ3QgeWV0IHdpZGVseSBzdXBwb3J0ZWQgLS0+Ci0KLTwhRUxFTUVOVCBNQVAgICgoJXhzbC12YWxpZC1pbi1yZXN1bHRuczt8JWJsb2NrOykrIHwgKCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7fEFSRUErKSk+PCEtLSBjbGllbnQtc2lkZSBpbWFnZSBtYXAgLS0+Ci08IUFUVExJU1QgTUFQCi0gICVhdHRyczsKLSAgbmFtZSAgICAgICAgQ0RBVEEgICAgICAgICAgI1JFUVVJUkVECi0gID4KLQotPCFFTEVNRU5UIEFSRUEgICAgIEVNUFRZPjwhLS0gY2xpZW50LXNpZGUgaW1hZ2UgbWFwIGFyZWEgLS0+Ci08IUFUVExJU1QgQVJFQQotICAlYXR0cnM7Ci0gIHNoYXBlICAgICAgICVTaGFwZTsgICAgICAgICJyZWN0IgotICBjb29yZHMgICAgICAlQ29vcmRzOyAgICAgICAjSU1QTElFRAotICBocmVmICAgICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICBub2hyZWYgICAgICAobm9ocmVmKSAgICAgICAjSU1QTElFRAotICBhbHQgICAgICAgICAlVGV4dDsgICAgICAgICAjUkVRVUlSRUQKLSAgdGFiaW5kZXggICAgJU51bWJlcjsgICAgICAgI0lNUExJRUQKLSAgYWNjZXNza2V5ICAgJUNoYXJhY3RlcjsgICAgI0lNUExJRUQKLSAgb25mb2N1cyAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgb25ibHVyICAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PT09IFRoZSBMSU5LIEVsZW1lbnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IS0tCi0gIFJlbGF0aW9uc2hpcCB2YWx1ZXMgY2FuIGJlIHVzZWQgaW4gcHJpbmNpcGxlOgotCi0gICBhKSBmb3IgZG9jdW1lbnQgc3BlY2lmaWMgdG9vbGJhcnMvbWVudXMgd2hlbiB1c2VkCi0gICAgICB3aXRoIHRoZSBMSU5LIGVsZW1lbnQgaW4gZG9jdW1lbnQgaGVhZCBlLmcuCi0gICAgICAgIHN0YXJ0LCBjb250ZW50cywgcHJldmlvdXMsIG5leHQsIGluZGV4LCBlbmQsIGhlbHAKLSAgIGIpIHRvIGxpbmsgdG8gYSBzZXBhcmF0ZSBzdHlsZSBzaGVldCAocmVsPXN0eWxlc2hlZXQpCi0gICBjKSB0byBtYWtlIGEgbGluayB0byBhIHNjcmlwdCAocmVsPXNjcmlwdCkKLSAgIGQpIGJ5IHN0eWxlc2hlZXRzIHRvIGNvbnRyb2wgaG93IGNvbGxlY3Rpb25zIG9mCi0gICAgICBodG1sIG5vZGVzIGFyZSByZW5kZXJlZCBpbnRvIHByaW50ZWQgZG9jdW1lbnRzCi0gICBlKSB0byBtYWtlIGEgbGluayB0byBhIHByaW50YWJsZSB2ZXJzaW9uIG9mIHRoaXMgZG9jdW1lbnQKLSAgICAgIGUuZy4gYSBwb3N0c2NyaXB0IG9yIHBkZiB2ZXJzaW9uIChyZWw9YWx0ZXJuYXRlIG1lZGlhPXByaW50KQotLS0+Ci0KLTwhRUxFTUVOVCBMSU5LICAgICBFTVBUWT48IS0tIGEgbWVkaWEtaW5kZXBlbmRlbnQgbGluayAtLT4KLTwhQVRUTElTVCBMSU5LCi0gICVhdHRyczsKLSAgY2hhcnNldCAgICAgJUNoYXJzZXQ7ICAgICAgI0lNUExJRUQKLSAgaHJlZiAgICAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgaHJlZmxhbmcgICAgJUxhbmd1YWdlQ29kZTsgI0lNUExJRUQKLSAgdHlwZSAgICAgICAgJUNvbnRlbnRUeXBlOyAgI0lNUExJRUQKLSAgcmVsICAgICAgICAgJUxpbmtUeXBlczsgICAgI0lNUExJRUQKLSAgcmV2ICAgICAgICAgJUxpbmtUeXBlczsgICAgI0lNUExJRUQKLSAgbWVkaWEgICAgICAgJU1lZGlhRGVzYzsgICAgI0lNUExJRUQKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PT09PSBJbWFnZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IS0tIExlbmd0aCBkZWZpbmVkIGluIHN0cmljdCBEVEQgZm9yIGNlbGxwYWRkaW5nL2NlbGxzcGFjaW5nIC0tPgotPCFFTlRJVFkgJSBMZW5ndGggIkNEQVRBIj48IS0tIG5uIGZvciBwaXhlbHMgb3Igbm4lIGZvciBwZXJjZW50YWdlIGxlbmd0aCAtLT4KLTwhRU5USVRZICUgTXVsdGlMZW5ndGggIkNEQVRBIj48IS0tIHBpeGVsLCBwZXJjZW50YWdlLCBvciByZWxhdGl2ZSAtLT4KLQotPCFFTlRJVFkgJSBNdWx0aUxlbmd0aHMgIkNEQVRBIj48IS0tIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIE11bHRpTGVuZ3RoIC0tPgotCi08IUVOVElUWSAlIFBpeGVscyAiQ0RBVEEiPjwhLS0gaW50ZWdlciByZXByZXNlbnRpbmcgbGVuZ3RoIGluIHBpeGVscyAtLT4KLQotCi08IS0tIFRvIGF2b2lkIHByb2JsZW1zIHdpdGggdGV4dC1vbmx5IFVBcyBhcyB3ZWxsIGFzIAotICAgdG8gbWFrZSBpbWFnZSBjb250ZW50IHVuZGVyc3RhbmRhYmxlIGFuZCBuYXZpZ2FibGUgCi0gICB0byB1c2VycyBvZiBub24tdmlzdWFsIFVBcywgeW91IG5lZWQgdG8gcHJvdmlkZQotICAgYSBkZXNjcmlwdGlvbiB3aXRoIEFMVCwgYW5kIGF2b2lkIHNlcnZlci1zaWRlIGltYWdlIG1hcHMgLS0+Ci08IUVMRU1FTlQgSU1HICAgICBFTVBUWT48IS0tIEVtYmVkZGVkIGltYWdlIC0tPgotPCFBVFRMSVNUIElNRwotICAlYXR0cnM7Ci0gIHNyYyAgICAgICAgICVVUkk7ICAgICAgICAgICNSRVFVSVJFRAotICBhbHQgICAgICAgICAlVGV4dDsgICAgICAgICAjUkVRVUlSRUQKLSAgbG9uZ2Rlc2MgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgaGVpZ2h0ICAgICAgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgd2lkdGggICAgICAgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgdXNlbWFwICAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgaXNtYXAgICAgICAgKGlzbWFwKSAgICAgICAgI0lNUExJRUQKLSAgPgotCi08IS0tIFVTRU1BUCBwb2ludHMgdG8gYSBNQVAgZWxlbWVudCB3aGljaCBtYXkgYmUgaW4gdGhpcyBkb2N1bWVudAotICBvciBhbiBleHRlcm5hbCBkb2N1bWVudCwgYWx0aG91Z2ggdGhlIGxhdHRlciBpcyBub3Qgd2lkZWx5IHN1cHBvcnRlZCAtLT4KLQotPCEtLT09PT09PT09PT09PT09PT09PT09IE9CSkVDVCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotPCEtLQotICBPQkpFQ1QgaXMgdXNlZCB0byBlbWJlZCBvYmplY3RzIGFzIHBhcnQgb2YgSFRNTCBwYWdlcyAKLSAgUEFSQU0gZWxlbWVudHMgc2hvdWxkIHByZWNlZGUgb3RoZXIgY29udGVudC4gU0dNTCBtaXhlZCBjb250ZW50Ci0gIG1vZGVsIHRlY2huaWNhbGl0eSBwcmVjbHVkZXMgc3BlY2lmeWluZyB0aGlzIGZvcm1hbGx5IC4uLgotLS0+Ci0KLTwhRUxFTUVOVCBPQkpFQ1QgKCVmbG93OyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7IHwgUEFSQU0pKgotPjwhLS0gZ2VuZXJpYyBlbWJlZGRlZCBvYmplY3QgLS0+Ci08IUFUVExJU1QgT0JKRUNUCi0gICVhdHRyczsKLSAgZGVjbGFyZSAgICAgKGRlY2xhcmUpICAgICAgI0lNUExJRUQKLSAgY2xhc3NpZCAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgY29kZWJhc2UgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgZGF0YSAgICAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgdHlwZSAgICAgICAgJUNvbnRlbnRUeXBlOyAgI0lNUExJRUQKLSAgY29kZXR5cGUgICAgJUNvbnRlbnRUeXBlOyAgI0lNUExJRUQKLSAgYXJjaGl2ZSAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgc3RhbmRieSAgICAgJVRleHQ7ICAgICAgICAgI0lNUExJRUQKLSAgaGVpZ2h0ICAgICAgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgd2lkdGggICAgICAgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgdXNlbWFwICAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgbmFtZSAgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgdGFiaW5kZXggICAgJU51bWJlcjsgICAgICAgI0lNUExJRUQKLSAgJXJlc2VydmVkOwotICA+Ci0KLTwhRUxFTUVOVCBQQVJBTSAgICAgRU1QVFk+PCEtLSBuYW1lZCBwcm9wZXJ0eSB2YWx1ZSAtLT4KLTwhQVRUTElTVCBQQVJBTQotICBpZCAgICAgICAgICBJRCAgICAgICAgICAgICAjSU1QTElFRAotICBuYW1lICAgICAgICBDREFUQSAgICAgICAgICAjUkVRVUlSRUQKLSAgdmFsdWUgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgdmFsdWV0eXBlICAgKERBVEF8UkVGfE9CSkVDVCkgIkRBVEEiCi0gIHR5cGUgICAgICAgICVDb250ZW50VHlwZTsgICNJTVBMSUVECi0gID4KLQotCi08IS0tPT09PT09PT09PT09PT09PT09PSBIb3Jpem9udGFsIFJ1bGUgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IUVMRU1FTlQgSFIgICAgIEVNUFRZPjwhLS0gaG9yaXpvbnRhbCBydWxlIC0tPgotPCFBVFRMSVNUIEhSCi0gICVjb3JlYXR0cnM7Ci0gICVldmVudHM7Ci0gID4KLQotPCEtLT09PT09PT09PT09PT09PT09PT0gUGFyYWdyYXBocyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0tLT4KLQotPCFFTEVNRU5UIFAgKCVpbmxpbmU7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj48IS0tIHBhcmFncmFwaCAtLT4KLTwhQVRUTElTVCBQCi0gICVhdHRyczsKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PT09PSBIZWFkaW5ncyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IS0tCi0gIFRoZXJlIGFyZSBzaXggbGV2ZWxzIG9mIGhlYWRpbmdzIGZyb20gSDEgKHRoZSBtb3N0IGltcG9ydGFudCkKLSAgdG8gSDYgKHRoZSBsZWFzdCBpbXBvcnRhbnQpLgotLS0+Ci0KLTwhLS0KLTwhRUxFTUVOVCAoJWhlYWRpbmc7KSAgICAgICglaW5saW5lOykqPgotPCFBVFRMSVNUICglaGVhZGluZzspCi0gICVhdHRyczsKLSAgPi0tPgotPCFFTEVNRU5UIEgxICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgSDEgJWF0dHJzOz4KLTwhRUxFTUVOVCBIMiAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEgyICVhdHRyczs+Ci08IUVMRU1FTlQgSDMgKCVpbmxpbmU7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj4KLTwhQVRUTElTVCBIMyAlYXR0cnM7PgotPCFFTEVNRU5UIEg0ICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+Ci08IUFUVExJU1QgSDQgJWF0dHJzOz4KLTwhRUxFTUVOVCBINSAoJWlubGluZTsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPgotPCFBVFRMSVNUIEg1ICVhdHRyczs+Ci08IUVMRU1FTlQgSDYgKCVpbmxpbmU7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj4KLTwhQVRUTElTVCBINiAlYXR0cnM7PgotCi0KLTwhLS09PT09PT09PT09PT09PT09PT09IFByZWZvcm1hdHRlZCBUZXh0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09LS0+Ci0KLTwhLS0gZXhjbHVkZXMgbWFya3VwIGZvciBpbWFnZXMgYW5kIGNoYW5nZXMgaW4gZm9udCBzaXplIC0tPgotPCEtLQotPCFFTlRJVFkgJSBwcmUuZXhjbHVzaW9uICJJTUd8T0JKRUNUfEJJR3xTTUFMTHxTVUJ8U1VQIj4KLQotPCFFTEVNRU5UIFBSRSAgKCVpbmxpbmU7KSogLSglcHJlLmV4Y2x1c2lvbjspPjwhIHByZWZvcm1hdHRlZCB0ZXh0IC0tPgotCi08IUVMRU1FTlQgUFJFICgjUENEQVRBIHwleHNsLXZhbGlkLWluLXJlc3VsdG5zO3wgVFR8SXxCfCVwaHJhc2U7fEF8QlJ8U0NSSVBUfE1BUHxRfFNQQU58QkRPfCVmb3JtY3RybDspKj4KLQkJCTwhLS0gcHJlZm9ybWF0dGVkIHRleHQgLS0+Ci08IUFUVExJU1QgUFJFCi0gICVhdHRyczs+Ci08IS0tIFNob3VsZCB0aGUgYXR0cmlidXRlIGJlbG93IGJlIGluY3VkZWQgaW4gUFJFPwotICB4bWw6c3BhY2UgKGRlZmF1bHR8cHJlc2VydmUpICNGSVhFRCAicHJlc2VydmUiCi0tLT4KLQotPCEtLT09PT09PT09PT09PT09PT09PT09PSBJbmxpbmUgUXVvdGVzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0tLT4KLQotPCFFTEVNRU5UIFEgICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBzaG9ydCBpbmxpbmUgcXVvdGF0aW9uIC0tPgotPCFBVFRMSVNUIFEKLSAgJWF0dHJzOwotICBjaXRlICAgICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICA+Ci0KLTwhLS09PT09PT09PT09PT09PT09PT09IEJsb2NrLWxpa2UgUXVvdGVzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09LS0+Ci0KLTwhRUxFTUVOVCBCTE9DS1FVT1RFICAoJWJsb2NrO3wleHNsLXZhbGlkLWluLXJlc3VsdG5zO3xTQ1JJUFQpKz48IS0tIGxvbmcgcXVvdGF0aW9uIC0tPgotPCFBVFRMSVNUIEJMT0NLUVVPVEUKLSAgJWF0dHJzOwotICBjaXRlICAgICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICA+Ci0KLTwhLS09PT09PT09PT09PT09PT09PT09IEluc2VydGVkL0RlbGV0ZWQgVGV4dCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09LS0+Ci0KLQotPCEtLSBJTlMvREVMIGFyZSBoYW5kbGVkIGJ5IGluY2x1c2lvbiBvbiBCT0RZIC0tPgotPCFFTEVNRU5UIElOUyAoJWZsb3c7fCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBpbnNlcnRlZCB0ZXh0LCBkZWxldGVkIHRleHQgLS0+Ci08IUFUVExJU1QgSU5TCi0gICVhdHRyczsKLSAgY2l0ZSAgICAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgZGF0ZXRpbWUgICAgJURhdGV0aW1lOyAgICAgI0lNUExJRUQKLSAgPgotPCFFTEVNRU5UIERFTCAoJWZsb3c7fCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBpbnNlcnRlZCB0ZXh0LCBkZWxldGVkIHRleHQgLS0+Ci08IUFUVExJU1QgREVMCi0gICVhdHRyczsKLSAgY2l0ZSAgICAgICAgJVVSSTsgICAgICAgICAgI0lNUExJRUQKLSAgZGF0ZXRpbWUgICAgJURhdGV0aW1lOyAgICAgI0lNUExJRUQKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PT09PSBMaXN0cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IS0tIGRlZmluaXRpb24gbGlzdHMgLSBEVCBmb3IgdGVybSwgREQgZm9yIGl0cyBkZWZpbml0aW9uIC0tPgotCi08IUVMRU1FTlQgREwgICgleHNsLXZhbGlkLWluLXJlc3VsdG5zO3wgRFR8REQpKz48IS0tIGRlZmluaXRpb24gbGlzdCAtLT4KLTwhQVRUTElTVCBETAotICAlYXR0cnM7Ci0gID4KLQotPCFFTEVNRU5UIERUICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBkZWZpbml0aW9uIHRlcm0gLS0+Ci08IUVMRU1FTlQgREQgKCVmbG93OyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBkZWZpbml0aW9uIGRlc2NyaXB0aW9uIC0tPgotPCFBVFRMSVNUIERUCi0gICVhdHRyczsKLSAgPgotPCFBVFRMSVNUIERECi0gICVhdHRyczsKLSAgPgotCi0KLTwhRUxFTUVOVCBPTCAoJXhzbC12YWxpZC1pbi1yZXN1bHRuczsgfCBMSSkrPjwhLS0gb3JkZXJlZCBsaXN0IC0tPgotPCFBVFRMSVNUIE9MCi0gICVhdHRyczsKLSAgPgotCi08IS0tIFVub3JkZXJlZCBMaXN0cyAoVUwpIGJ1bGxldCBzdHlsZXMgLS0+Ci08IUVMRU1FTlQgVUwgKCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7IHwgTEkpKz48IS0tIHVub3JkZXJlZCBsaXN0IC0tPgotPCFBVFRMSVNUIFVMCi0gICVhdHRyczsKLSAgPgotCi0KLQotPCFFTEVNRU5UIExJICglZmxvdzsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gbGlzdCBpdGVtIC0tPgotPCFBVFRMSVNUIExJCi0gICVhdHRyczsKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PSBGb3JtcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotPCFFTEVNRU5UIEZPUk0gKCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7fCVibG9jay1GT1JNO3xTQ1JJUFQpKz4KLQotPCEtLSBpbnRlcmFjdGl2ZSBmb3JtIC0tPgotPCFBVFRMSVNUIEZPUk0KLSAgJWF0dHJzOwotICBhY3Rpb24gICAgICAlVVJJOyAgICAgICAgICAjUkVRVUlSRUQKLSAgbWV0aG9kICAgICAgKEdFVHxQT1NUKSAgICAgIkdFVCIKLSAgZW5jdHlwZSAgICAgJUNvbnRlbnRUeXBlOyAgImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIKLSAgb25zdWJtaXQgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgb25yZXNldCAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgYWNjZXB0LWNoYXJzZXQgJUNoYXJzZXRzOyAgI0lNUExJRUQKLSAgPgotCi08IS0tIEVhY2ggbGFiZWwgbXVzdCBub3QgY29udGFpbiBtb3JlIHRoYW4gT05FIGZpZWxkIC0tPgotPCFFTEVNRU5UIExBQkVMICAoJWlubGluZS1MQUJFTDsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gZm9ybSBmaWVsZCBsYWJlbCB0ZXh0IC0tPgotPCFBVFRMSVNUIExBQkVMCi0gICVhdHRyczsKLSAgZm9yICAgICAgICAgSURSRUYgICAgICAgICAgI0lNUExJRUQKLSAgYWNjZXNza2V5ICAgJUNoYXJhY3RlcjsgICAgI0lNUExJRUQKLSAgb25mb2N1cyAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgb25ibHVyICAgICAgJVNjcmlwdDsgICAgICAgI0lNUExJRUQKLSAgPgotCi08IUVOVElUWSAlIElucHV0VHlwZQotICAiKFRFWFQgfCBQQVNTV09SRCB8IENIRUNLQk9YIHwKLSAgICBSQURJTyB8IFNVQk1JVCB8IFJFU0VUIHwKLSAgICBGSUxFIHwgSElEREVOIHwgSU1BR0UgfCBCVVRUT04pIgotICAgPgotCi08IS0tIGF0dHJpYnV0ZSBuYW1lIHJlcXVpcmVkIGZvciBhbGwgYnV0IHN1Ym1pdCAmIHJlc2V0IC0tPgotPCFFTEVNRU5UIElOUFVUICAgICBFTVBUWT48IS0tIGZvcm0gY29udHJvbCAtLT4KLTwhQVRUTElTVCBJTlBVVAotICAlYXR0cnM7Ci0gIHR5cGUgICAgICAgICVJbnB1dFR5cGU7ICAgICJURVhUIgotICBuYW1lICAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICB2YWx1ZSAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICBjaGVja2VkICAgICAoY2hlY2tlZCkgICAgICAjSU1QTElFRAotICBkaXNhYmxlZCAgICAoZGlzYWJsZWQpICAgICAjSU1QTElFRAotICByZWFkb25seSAgICAocmVhZG9ubHkpICAgICAjSU1QTElFRAotICBzaXplICAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICBtYXhsZW5ndGggICAlTnVtYmVyOyAgICAgICAjSU1QTElFRAotICBzcmMgICAgICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICBhbHQgICAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICB1c2VtYXAgICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICB0YWJpbmRleCAgICAlTnVtYmVyOyAgICAgICAjSU1QTElFRAotICBhY2Nlc3NrZXkgICAlQ2hhcmFjdGVyOyAgICAjSU1QTElFRAotICBvbmZvY3VzICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmJsdXIgICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbnNlbGVjdCAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmNoYW5nZSAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBhY2NlcHQgICAgICAlQ29udGVudFR5cGVzOyAjSU1QTElFRAotICAlcmVzZXJ2ZWQ7Ci0gID4KLQotPCFFTEVNRU5UIFNFTEVDVCAoKCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7fE9QVEdST1VQKXwoJXhzbC12YWxpZC1pbi1yZXN1bHRuczt8T1BUSU9OKSkrID48IS0tIG9wdGlvbiBzZWxlY3RvciAtLT4KLTwhQVRUTElTVCBTRUxFQ1QKLSAgJWF0dHJzOwotICBuYW1lICAgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICBzaXplICAgICAgICAlTnVtYmVyOyAgICAgICAjSU1QTElFRAotICBtdWx0aXBsZSAgICAobXVsdGlwbGUpICAgICAjSU1QTElFRAotICBkaXNhYmxlZCAgICAoZGlzYWJsZWQpICAgICAjSU1QTElFRAotICB0YWJpbmRleCAgICAlTnVtYmVyOyAgICAgICAjSU1QTElFRAotICBvbmZvY3VzICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmJsdXIgICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmNoYW5nZSAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICAlcmVzZXJ2ZWQ7Ci0gID4KLQotPCFFTEVNRU5UIE9QVEdST1VQICgleHNsLXZhbGlkLWluLXJlc3VsdG5zO3xPUFRJT04pKz4gIDwhLS0gb3B0aW9uIGdyb3VwIC0tPgotPCFBVFRMSVNUIE9QVEdST1VQCi0gICVhdHRyczsKLSAgZGlzYWJsZWQgICAgKGRpc2FibGVkKSAgICAgI0lNUExJRUQKLSAgbGFiZWwgICAgICAgJVRleHQ7ICAgICAgICAgI1JFUVVJUkVECi0gID4KLQotPCFFTEVNRU5UIE9QVElPTiAgKCNQQ0RBVEEgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gc2VsZWN0YWJsZSBjaG9pY2UgLS0+Ci08IUFUVExJU1QgT1BUSU9OCi0gICVhdHRyczsKLSAgc2VsZWN0ZWQgICAgKHNlbGVjdGVkKSAgICAgI0lNUExJRUQKLSAgZGlzYWJsZWQgICAgKGRpc2FibGVkKSAgICAgI0lNUExJRUQKLSAgbGFiZWwgICAgICAgJVRleHQ7ICAgICAgICAgI0lNUExJRUQKLSAgdmFsdWUgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgPgotCi08IUVMRU1FTlQgVEVYVEFSRUEgKCNQQ0RBVEEgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gbXVsdGktbGluZSB0ZXh0IGZpZWxkIC0tPgotPCFBVFRMSVNUIFRFWFRBUkVBCi0gICVhdHRyczsKLSAgbmFtZSAgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgcm93cyAgICAgICAgJU51bWJlcjsgICAgICAgI1JFUVVJUkVECi0gIGNvbHMgICAgICAgICVOdW1iZXI7ICAgICAgICNSRVFVSVJFRAotICBkaXNhYmxlZCAgICAoZGlzYWJsZWQpICAgICAjSU1QTElFRAotICByZWFkb25seSAgICAocmVhZG9ubHkpICAgICAjSU1QTElFRAotICB0YWJpbmRleCAgICAlTnVtYmVyOyAgICAgICAjSU1QTElFRAotICBhY2Nlc3NrZXkgICAlQ2hhcmFjdGVyOyAgICAjSU1QTElFRAotICBvbmZvY3VzICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmJsdXIgICAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbnNlbGVjdCAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICBvbmNoYW5nZSAgICAlU2NyaXB0OyAgICAgICAjSU1QTElFRAotICAlcmVzZXJ2ZWQ7Ci0gID4KLQotPCEtLQotICAjUENEQVRBIGlzIHRvIHNvbHZlIHRoZSBtaXhlZCBjb250ZW50IHByb2JsZW0sCi0gIHBlciBzcGVjaWZpY2F0aW9uIG9ubHkgd2hpdGVzcGFjZSBpcyBhbGxvd2VkIHRoZXJlIQotCi0gIFdlIGRvIGFsbG93IFhTTCBpbnNpZGUgYXMgd2VsbAotIC0tPgotPCEtLUVMRU1FTlQgRklFTERTRVQgICAgICgjUENEQVRBLExFR0VORCwoJWZsb3c7KSopICAgIGZvcm0gY29udHJvbCBncm91cCAtLT4KLTwhRUxFTUVOVCBGSUVMRFNFVCAgKCVmbG93O3wleHNsLXZhbGlkLWluLXJlc3VsdG5zO3xMRUdFTkQpKj48IS0tIGZvcm0gY29udHJvbCBncm91cCAtLT4KLTwhQVRUTElTVCBGSUVMRFNFVAotICAlYXR0cnM7Ci0gID4KLQotPCFFTEVNRU5UIExFR0VORCAoJWlubGluZTt8JXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj48IS0tIGZpZWxkc2V0IGxlZ2VuZCAtLT4KLTwhRU5USVRZICUgTEFsaWduICIodG9wfGJvdHRvbXxsZWZ0fHJpZ2h0KSI+Ci0KLTwhQVRUTElTVCBMRUdFTkQKLSAgJWF0dHJzOwotICBhY2Nlc3NrZXkgICAlQ2hhcmFjdGVyOyAgICAjSU1QTElFRAotICA+Ci0KLTwhRUxFTUVOVCBCVVRUT04KLSAgICAgKCNQQ0RBVEEgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOyB8ICVmb250c3R5bGU7IHwgJXBocmFzZTsgfCAlc3BlY2lhbC1BOyB8ICVibG9jazspKgotPjwhLS0gcHVzaCBidXR0b24gLS0+Ci08IUFUVExJU1QgQlVUVE9OCi0gICVhdHRyczsKLSAgbmFtZSAgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgdmFsdWUgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgdHlwZSAgICAgICAgKGJ1dHRvbnxzdWJtaXR8cmVzZXQpICJzdWJtaXQiCi0gIGRpc2FibGVkICAgIChkaXNhYmxlZCkgICAgICNJTVBMSUVECi0gIHRhYmluZGV4ICAgICVOdW1iZXI7ICAgICAgICNJTVBMSUVECi0gIGFjY2Vzc2tleSAgICVDaGFyYWN0ZXI7ICAgICNJTVBMSUVECi0gIG9uZm9jdXMgICAgICVTY3JpcHQ7ICAgICAgICNJTVBMSUVECi0gIG9uYmx1ciAgICAgICVTY3JpcHQ7ICAgICAgICNJTVBMSUVECi0gICVyZXNlcnZlZDsKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PT09PT09PT0gVGFibGVzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotCi08IS0tIElFVEYgSFRNTCB0YWJsZSBzdGFuZGFyZCwgc2VlIFtSRkMxOTQyXSAtLT4KLQotPCEtLQotIFRoZSBCT1JERVIgYXR0cmlidXRlIHNldHMgdGhlIHRoaWNrbmVzcyBvZiB0aGUgZnJhbWUgYXJvdW5kIHRoZQotIHRhYmxlLiBUaGUgZGVmYXVsdCB1bml0cyBhcmUgc2NyZWVuIHBpeGVscy4KLQotIFRoZSBGUkFNRSBhdHRyaWJ1dGUgc3BlY2lmaWVzIHdoaWNoIHBhcnRzIG9mIHRoZSBmcmFtZSBhcm91bmQKLSB0aGUgdGFibGUgc2hvdWxkIGJlIHJlbmRlcmVkLiBUaGUgdmFsdWVzIGFyZSBub3QgdGhlIHNhbWUgYXMKLSBDQUxTIHRvIGF2b2lkIGEgbmFtZSBjbGFzaCB3aXRoIHRoZSBWQUxJR04gYXR0cmlidXRlLgotCi0gVGhlIHZhbHVlICJib3JkZXIiIGlzIGluY2x1ZGVkIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3aXRoCi0gPFRBQkxFIEJPUkRFUj4gd2hpY2ggeWllbGRzIGZyYW1lPWJvcmRlciBhbmQgYm9yZGVyPWltcGxpZWQKLSBGb3IgPFRBQkxFIEJPUkRFUj0xPiB5b3UgZ2V0IGJvcmRlcj0xIGFuZCBmcmFtZT1pbXBsaWVkLiBJbiB0aGlzCi0gY2FzZSwgaXQgaXMgYXBwcm9wcmlhdGUgdG8gdHJlYXQgdGhpcyBhcyBmcmFtZT1ib3JkZXIgZm9yIGJhY2t3YXJkcwotIGNvbXBhdGliaWxpdHkgd2l0aCBkZXBsb3llZCBicm93c2Vycy4KLS0tPgotPCFFTlRJVFkgJSBURnJhbWUgIih2b2lkfGFib3ZlfGJlbG93fGhzaWRlc3xsaHN8cmhzfHZzaWRlc3xib3h8Ym9yZGVyKSI+Ci0KLTwhLS0KLSBUaGUgUlVMRVMgYXR0cmlidXRlIGRlZmluZXMgd2hpY2ggcnVsZXMgdG8gZHJhdyBiZXR3ZWVuIGNlbGxzOgotCi0gSWYgUlVMRVMgaXMgYWJzZW50IHRoZW4gYXNzdW1lOgotICAgICAibm9uZSIgaWYgQk9SREVSIGlzIGFic2VudCBvciBCT1JERVI9MCBvdGhlcndpc2UgImFsbCIKLS0tPgotCi08IUVOVElUWSAlIFRSdWxlcyAiKG5vbmUgfCBncm91cHMgfCByb3dzIHwgY29scyB8IGFsbCkiPgotICAKLTwhLS0gaG9yaXpvbnRhbCBwbGFjZW1lbnQgb2YgdGFibGUgcmVsYXRpdmUgdG8gZG9jdW1lbnQgLS0+Ci08IUVOVElUWSAlIFRBbGlnbiAiKGxlZnR8Y2VudGVyfHJpZ2h0KSI+Ci0KLTwhLS0gaG9yaXpvbnRhbCBhbGlnbm1lbnQgYXR0cmlidXRlcyBmb3IgY2VsbCBjb250ZW50cyAtLT4KLTwhRU5USVRZICUgY2VsbGhhbGlnbgotICAiYWxpZ24gICAgICAobGVmdHxjZW50ZXJ8cmlnaHR8anVzdGlmeXxjaGFyKSAjSU1QTElFRAotICAgY2hhciAgICAgICAlQ2hhcmFjdGVyOyAgICAjSU1QTElFRAotICAgY2hhcm9mZiAgICAlTGVuZ3RoOyAgICAgICAjSU1QTElFRCIKLSAgPgotCi08IS0tIHZlcnRpY2FsIGFsaWdubWVudCBhdHRyaWJ1dGVzIGZvciBjZWxsIGNvbnRlbnRzIC0tPgotPCFFTlRJVFkgJSBjZWxsdmFsaWduCi0gICJ2YWxpZ24gICAgICh0b3B8bWlkZGxlfGJvdHRvbXxiYXNlbGluZSkgI0lNUExJRUQiCi0gID4KLQotPCFFTEVNRU5UIFRBQkxFIAotICAoKCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSosIENBUFRJT04/LCAoJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKiwKLSAgICgoQ09MIHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKnwoQ09MR1JPVVAgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqKSwKLSAgICgoVEhFQUQ/LCgleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqLFRGT09UPywoJXhzbC12YWxpZC1pbi1yZXN1bHRuczt8VEJPRFkpKykKLSAgICB8ICgleHNsLXZhbGlkLWluLXJlc3VsdG5zO3xUUikrKSApPgotCi08IUVMRU1FTlQgQ0FQVElPTiAgICglaW5saW5lOyB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSB0YWJsZSBjYXB0aW9uIC0tPgotPCFFTEVNRU5UIFRIRUFEICAgICAoVFJ8JXhzbC12YWxpZC1pbi1yZXN1bHRuczspKz48IS0tIHRhYmxlIGhlYWRlciAtLT4KLTwhRUxFTUVOVCBURk9PVCAgICAgKFRSfCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSs+PCEtLSB0YWJsZSBmb290ZXIgLS0+Ci08IUVMRU1FTlQgVEJPRFkgICAgIChUUnwleHNsLXZhbGlkLWluLXJlc3VsdG5zOykrPjwhLS0gdGFibGUgYm9keSAtLT4KLTwhRUxFTUVOVCBDT0xHUk9VUCAgKCV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7IHwgQ09MKSo+PCEtLSB0YWJsZSBjb2x1bW4gZ3JvdXAgLS0+Ci08IUVMRU1FTlQgQ09MICAgICAgIEVNUFRZPjwhLS0gdGFibGUgY29sdW1uIC0tPgotPCFFTEVNRU5UIFRSICAgICAgICAoVEh8VER8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSs+PCEtLSB0YWJsZSByb3cgLS0+Ci08IUVMRU1FTlQgVEggICAgICAgICglZmxvdzsgfCAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gdGFibGUgaGVhZGVyIGNlbGwsIHRhYmxlIGRhdGEgY2VsbC0tPgotPCFFTEVNRU5UIFREICAgICAgICAoJWZsb3c7IHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj48IS0tIHRhYmxlIGhlYWRlciBjZWxsLCB0YWJsZSBkYXRhIGNlbGwtLT4KLQotPCFBVFRMSVNUIFRBQkxFCi0gICVhdHRyczsKLSAgc3VtbWFyeSAgICAgJVRleHQ7ICAgICAgICAgI0lNUExJRUQKLSAgd2lkdGggICAgICAgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgYm9yZGVyICAgICAgJVBpeGVsczsgICAgICAgI0lNUExJRUQKLSAgZnJhbWUgICAgICAgJVRGcmFtZTsgICAgICAgI0lNUExJRUQKLSAgcnVsZXMgICAgICAgJVRSdWxlczsgICAgICAgI0lNUExJRUQKLSAgY2VsbHNwYWNpbmcgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgY2VsbHBhZGRpbmcgJUxlbmd0aDsgICAgICAgI0lNUExJRUQKLSAgJXJlc2VydmVkOwotICBkYXRhcGFnZXNpemUgQ0RBVEEgICAgICAgICAjSU1QTElFRAotICA+Ci0KLTwhRU5USVRZICUgQ0FsaWduICIodG9wfGJvdHRvbXxsZWZ0fHJpZ2h0KSI+Ci0KLTwhQVRUTElTVCBDQVBUSU9OCi0gICVhdHRyczsKLSAgPgotCi08IS0tCi1DT0xHUk9VUCBncm91cHMgYSBzZXQgb2YgQ09MIGVsZW1lbnRzLiBJdCBhbGxvd3MgeW91IHRvIGdyb3VwCi1zZXZlcmFsIHNlbWFudGljYWxseSByZWxhdGVkIGNvbHVtbnMgdG9nZXRoZXIuCi0tLT4KLTwhQVRUTElTVCBDT0xHUk9VUAotICAlYXR0cnM7Ci0gIHNwYW4gICAgICAgICVOdW1iZXI7ICAgICAgICIxIgotICB3aWR0aCAgICAgICAlTXVsdGlMZW5ndGg7ICAjSU1QTElFRAotICAlY2VsbGhhbGlnbjsKLSAgJWNlbGx2YWxpZ247Ci0gID4KLQotPCEtLQotIENPTCBlbGVtZW50cyBkZWZpbmUgdGhlIGFsaWdubWVudCBwcm9wZXJ0aWVzIGZvciBjZWxscyBpbgotIG9uZSBvciBtb3JlIGNvbHVtbnMuCi0KLSBUaGUgV0lEVEggYXR0cmlidXRlIHNwZWNpZmllcyB0aGUgd2lkdGggb2YgdGhlIGNvbHVtbnMsIGUuZy4KLQotICAgICB3aWR0aD02NCAgICAgICAgd2lkdGggaW4gc2NyZWVuIHBpeGVscwotICAgICB3aWR0aD0wLjUqICAgICAgcmVsYXRpdmUgd2lkdGggb2YgMC41Ci0KLSBUaGUgU1BBTiBhdHRyaWJ1dGUgY2F1c2VzIHRoZSBhdHRyaWJ1dGVzIG9mIG9uZQotIENPTCBlbGVtZW50IHRvIGFwcGx5IHRvIG1vcmUgdGhhbiBvbmUgY29sdW1uLgotLS0+Ci08IUFUVExJU1QgQ09MCi0gICVhdHRyczsKLSAgc3BhbiAgICAgICAgJU51bWJlcjsgICAgICAgIjEiCi0gIHdpZHRoICAgICAgICVNdWx0aUxlbmd0aDsgICNJTVBMSUVECi0gICVjZWxsaGFsaWduOwotICAlY2VsbHZhbGlnbjsKLSAgPgotCi08IS0tCi0gICAgVXNlIFRIRUFEIHRvIGR1cGxpY2F0ZSBoZWFkZXJzIHdoZW4gYnJlYWtpbmcgdGFibGUKLSAgICBhY3Jvc3MgcGFnZSBib3VuZGFyaWVzLCBvciBmb3Igc3RhdGljIGhlYWRlcnMgd2hlbgotICAgIFRCT0RZIHNlY3Rpb25zIGFyZSByZW5kZXJlZCBpbiBzY3JvbGxpbmcgcGFuZWwuCi0KLSAgICBVc2UgVEZPT1QgdG8gZHVwbGljYXRlIGZvb3RlcnMgd2hlbiBicmVha2luZyB0YWJsZQotICAgIGFjcm9zcyBwYWdlIGJvdW5kYXJpZXMsIG9yIGZvciBzdGF0aWMgZm9vdGVycyB3aGVuCi0gICAgVEJPRFkgc2VjdGlvbnMgYXJlIHJlbmRlcmVkIGluIHNjcm9sbGluZyBwYW5lbC4KLQotICAgIFVzZSBtdWx0aXBsZSBUQk9EWSBzZWN0aW9ucyB3aGVuIHJ1bGVzIGFyZSBuZWVkZWQKLSAgICBiZXR3ZWVuIGdyb3VwcyBvZiB0YWJsZSByb3dzLgotLS0+Ci08IUFUVExJU1QgVEhFQUQKLSAgJWF0dHJzOwotICAlY2VsbGhhbGlnbjsKLSAgJWNlbGx2YWxpZ247Ci0gID4KLTwhQVRUTElTVCBUQk9EWQotICAlYXR0cnM7Ci0gICVjZWxsaGFsaWduOwotICAlY2VsbHZhbGlnbjsKLSAgPgotPCFBVFRMSVNUIFRGT09UCi0gICVhdHRyczsKLSAgJWNlbGxoYWxpZ247Ci0gICVjZWxsdmFsaWduOwotICA+Ci0KLTwhQVRUTElTVCBUUgotICAlYXR0cnM7Ci0gICVjZWxsaGFsaWduOwotICAlY2VsbHZhbGlnbjsKLSAgPgotCi0KLTwhLS0gU2NvcGUgaXMgc2ltcGxlciB0aGFuIGF4ZXMgYXR0cmlidXRlIGZvciBjb21tb24gdGFibGVzIC0tPgotPCFFTlRJVFkgJSBTY29wZSAiKFJPV3xDT0x8Uk9XR1JPVVB8Q09MR1JPVVApIj4KLQotPCEtLSBUSCBpcyBmb3IgaGVhZGVycywgVEQgZm9yIGRhdGEsIGJ1dCBmb3IgY2VsbHMgYWN0aW5nIGFzIGJvdGggdXNlIFREIC0tPgotPCFBVFRMSVNUIFRICi0gICVhdHRyczsKLSAgYWJiciAgICAgICAgJVRleHQ7ICAgICAgICAgI0lNUExJRUQKLSAgYXhpcyAgICAgICAgQ0RBVEEgICAgICAgICAgI0lNUExJRUQKLSAgaGVhZGVycyAgICAgSURSRUZTICAgICAgICAgI0lNUExJRUQKLSAgc2NvcGUgICAgICAgJVNjb3BlOyAgICAgICAgI0lNUExJRUQKLSAgcm93c3BhbiAgICAgJU51bWJlcjsgICAgICAgIjEiCi0gIGNvbHNwYW4gICAgICVOdW1iZXI7ICAgICAgICIxIgotICAlY2VsbGhhbGlnbjsKLSAgJWNlbGx2YWxpZ247Ci0gID4KLTwhQVRUTElTVCBURAotICAlYXR0cnM7Ci0gIGFiYnIgICAgICAgICVUZXh0OyAgICAgICAgICNJTVBMSUVECi0gIGF4aXMgICAgICAgIENEQVRBICAgICAgICAgICNJTVBMSUVECi0gIGhlYWRlcnMgICAgIElEUkVGUyAgICAgICAgICNJTVBMSUVECi0gIHNjb3BlICAgICAgICVTY29wZTsgICAgICAgICNJTVBMSUVECi0gIHJvd3NwYW4gICAgICVOdW1iZXI7ICAgICAgICIxIgotICBjb2xzcGFuICAgICAlTnVtYmVyOyAgICAgICAiMSIKLSAgJWNlbGxoYWxpZ247Ci0gICVjZWxsdmFsaWduOwotICA+Ci0KLQotPCEtLT09PT09PT09PT09PT09PT0gRG9jdW1lbnQgSGVhZCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0tLT4KLTwhLS0gJWhlYWQubWlzYzsgZGVmaW5lZCBlYXJsaWVyIG9uIGFzICJTQ1JJUFR8U1RZTEV8TUVUQXxMSU5LfE9CSkVDVCIsCi0gICAgIGV4dGVuZGVkIG5vdyB0byBhbGxvdyB4c2wgLS0+Ci08IUVOVElUWSAlIGhlYWQubWlzYy1IRUFEICIlaGVhZC5taXNjO3wleHNsLXZhbGlkLWluLXJlc3VsdG5zOyI+Ci0KLTwhRU5USVRZICUgaGVhZC5jb250ZW50ICJUSVRMRSAmYW1wOyBCQVNFPyI+Ci0KLTwhLS1FTEVNRU5UIEhFQUQgICAgICglaGVhZC5jb250ZW50OykgKyglaGVhZC5taXNjOykgICBkb2N1bWVudCBoZWFkIC0tPgotPCFFTEVNRU5UIEhFQUQKLSAgICgoJWhlYWQubWlzYy1IRUFEOykqLCAoKEJBU0U/LCglaGVhZC5taXNjLUhFQUQ7KSosVElUTEU/KSB8IChUSVRMRT8sKCVoZWFkLm1pc2MtSEVBRDspKixCQVNFPyl8KCVoZWFkLm1pc2MtSEVBRDspKikrLCAoJWhlYWQubWlzYy1IRUFEOykqKT4KLTwhQVRUTElTVCBIRUFECi0gICVpMThuOwotICBwcm9maWxlICAgICAlVVJJOyAgICAgICAgICAjSU1QTElFRAotICAlcmVzdWx0LWVsZW1lbnQtYXR0czsKLSAgPgotCi08IS0tIFRoZSBUSVRMRSBlbGVtZW50IGlzIG5vdCBjb25zaWRlcmVkIHBhcnQgb2YgdGhlIGZsb3cgb2YgdGV4dC4KLSAgICAgICBJdCBzaG91bGQgYmUgZGlzcGxheWVkLCBmb3IgZXhhbXBsZSBhcyB0aGUgcGFnZSBoZWFkZXIgb3IKLSAgICAgICB3aW5kb3cgdGl0bGUuIEV4YWN0bHkgb25lIHRpdGxlIGlzIHJlcXVpcmVkIHBlciBkb2N1bWVudC4KLSAgICAtLT4KLTwhLS1FTEVNRU5UIFRJVExFICAgICAoI1BDREFUQSkgLSglaGVhZC5taXNjOykgIGRvY3VtZW50IHRpdGxlIC0tPgotPCFFTEVNRU5UIFRJVExFICAoI1BDREFUQSB8ICAleHNsLXZhbGlkLWluLXJlc3VsdG5zOykqPjwhLS0gZG9jdW1lbnQgdGl0bGUgLS0+Ci08IUFUVExJU1QgVElUTEUgJWkxOG47ICVyZXN1bHQtZWxlbWVudC1hdHRzOz4KLQotCi08IUVMRU1FTlQgQkFTRSAgICAgRU1QVFk+PCEtLSBkb2N1bWVudCBiYXNlIFVSSSAtLT4KLTwhQVRUTElTVCBCQVNFCi0gIGhyZWYgICAgICAgICVVUkk7ICAgICAgICAgICNSRVFVSVJFRAotICA+Ci0KLTwhRUxFTUVOVCBNRVRBICAgICBFTVBUWT48IS0tIGdlbmVyaWMgbWV0YWluZm9ybWF0aW9uIC0tPgotPCFBVFRMSVNUIE1FVEEKLSAgJWkxOG47Ci0gIGh0dHAtZXF1aXYgICVOYW1lOyAgICAgICAgICNJTVBMSUVECi0gIG5hbWUgICAgICAgICVOYW1lOyAgICAgICAgICNJTVBMSUVECi0gIGNvbnRlbnQgICAgIENEQVRBICAgICAgICAgICNSRVFVSVJFRAotICBzY2hlbWUgICAgICBDREFUQSAgICAgICAgICAjSU1QTElFRAotICAlcmVzdWx0LWVsZW1lbnQtYXR0czsKLSAgPgotCi08IS0tRUxFTUVOVCBTVFlMRSAgICAgJVN0eWxlU2hlZXQ7ICBzdHlsZSBpbmZvIC0tPgotPCFFTEVNRU5UIFNUWUxFICgjUENEQVRBIHwgJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKj48IS0tIHN0eWxlIGluZm8gLS0+Ci08IUFUVExJU1QgU1RZTEUKLSAgJWkxOG47Ci0gIHR5cGUgICAgICAgICVDb250ZW50VHlwZTsgICNSRVFVSVJFRAotICBtZWRpYSAgICAgICAlTWVkaWFEZXNjOyAgICAjSU1QTElFRAotICB0aXRsZSAgICAgICAlVGV4dDsgICAgICAgICAjSU1QTElFRAotICAlcmVzdWx0LWVsZW1lbnQtYXR0czsKLSAgPgotCi08IS0tRUxFTUVOVCBTQ1JJUFQgICAgICVTY3JpcHQ7IHNjcmlwdCBzdGF0ZW1lbnRzIC0tPgotPCFFTEVNRU5UIFNDUklQVCAoI1BDREFUQSB8ICV4c2wtdmFsaWQtaW4tcmVzdWx0bnM7KSo+PCEtLSBzY3JpcHQgc3RhdGVtZW50cyAtLT4KLTwhQVRUTElTVCBTQ1JJUFQKLSAgY2hhcnNldCAgICAgJUNoYXJzZXQ7ICAgICAgI0lNUExJRUQKLSAgdHlwZSAgICAgICAgJUNvbnRlbnRUeXBlOyAgI1JFUVVJUkVECi0gIGxhbmd1YWdlICAgIENEQVRBICAgICAgICAgICNJTVBMSUVECi0gIHNyYyAgICAgICAgICVVUkk7ICAgICAgICAgICNJTVBMSUVECi0gIGRlZmVyICAgICAgIChkZWZlcikgICAgICAgICNJTVBMSUVECi0gIGV2ZW50ICAgICAgIENEQVRBICAgICAgICAgICNJTVBMSUVECi0gIGZvciAgICAgICAgICVVUkk7ICAgICAgICAgICNJTVBMSUVECi0gICVyZXN1bHQtZWxlbWVudC1hdHRzOwotICA+Ci0KLTwhRUxFTUVOVCBOT1NDUklQVCAoJXhzbC12YWxpZC1pbi1yZXN1bHRuczt8JWJsb2NrOykrCi0+PCEtLSBhbHRlcm5hdGUgY29udGVudCBjb250YWluZXIgZm9yIG5vbiBzY3JpcHQtYmFzZWQgcmVuZGVyaW5nIC0tPgotPCFBVFRMSVNUIE5PU0NSSVBUCi0gICVhdHRyczsKLSAgPgotCi08IS0tPT09PT09PT09PT09PT09PSBEb2N1bWVudCBTdHJ1Y3R1cmUgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS0tPgotPCFFTlRJVFkgJSBodG1sLmNvbnRlbnQgIkhFQUQsIEJPRFkiPgotCi08IS0tPCFFTEVNRU5UIEhUTUwgICAgICglaHRtbC5jb250ZW50Oyk+IC0tPjwhLS0gZG9jdW1lbnQgcm9vdCBlbGVtZW50IC0tPgotPCFFTEVNRU5UIEhUTUwgKCgoJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKixIRUFEPywoJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKixCT0RZPywKLSAgICAgICAgICAgICAgICAoJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKikgfCAoJXhzbC12YWxpZC1pbi1yZXN1bHRuczspKik+Ci08IS0tIGRvY3VtZW50IHJvb3QgZWxlbWVudCAtLT4KLTwhQVRUTElTVCBIVE1MCi0gICVpMThuOwotICAlcmVzdWx0LWVsZW1lbnQtYXR0czsKLSAgPgpkaWZmIC0tZ2l0IGEveGRvY3Mvc3R5bGUvbG9hZGVyZGVzaWduLnhtbCBiL3hkb2NzL3N0eWxlL2xvYWRlcmRlc2lnbi54bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk3NTA1NWIuLjAwMDAwMDAKLS0tIGEveGRvY3Mvc3R5bGUvbG9hZGVyZGVzaWduLnhtbAorKysgL2Rldi9udWxsCkBAIC0xLDcgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci0KLTxsb2FkZXI+Ci0gIDxwcm9jZXNzb3IgbmFtZT0ieHNsdCI+Ci0gICAgPHBhcmFtZXRlciBuYW1lPSJzdHlsZXNoZWV0IiB2YWx1ZT0ic2JrOi9zdHlsZS9zdHlsZXNoZWV0cy9kZXNpZ24ycHJvamVjdC54c2wiLz4KLSAgPC9wcm9jZXNzb3I+Ci08L2xvYWRlcj4KZGlmZiAtLWdpdCBhL3hkb2NzL3N0eWxlL3N0eWxlc2hlZXRzL2Rlc2lnbjJwcm9qZWN0LnhzbCBiL3hkb2NzL3N0eWxlL3N0eWxlc2hlZXRzL2Rlc2lnbjJwcm9qZWN0LnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGQyMzk0MC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy9kZXNpZ24ycHJvamVjdC54c2wKKysrIC9kZXYvbnVsbApAQCAtMSwzMyArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiPz4KLQotPHhzbDpzdHlsZXNoZWV0IHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPgotICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPCEtLSBtYXRjaCB0aGUgcm9vdCBib29rIGVsZW1lbnQgLS0+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImJvb2siPgotICAgIDxwcm9qZWN0PgotICAgICAgPHBhcmFtZXRlciBuYW1lPSJjb3B5cmlnaHQiIHZhbHVlPSJ7QGNvcHlyaWdodH0iLz4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICA8L3Byb2plY3Q+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iZG9jdW1lbnQiPgotCi0gICAgPHByb2Nlc3Mgc291cmNlPSJ7QHNvdXJjZX0iIHByb2R1Y2VyPSJwYXJzZXIiPgotICAgICAgPHByb2Nlc3NvciBuYW1lPSJ4c2x0Ij4KLSAgICAgICAgPHBhcmFtZXRlciBuYW1lPSJzdHlsZXNoZWV0IiB2YWx1ZT0ic2JrOi9zdHlsZS9zdHlsZXNoZWV0cy9hbnkycHJvamVjdC54c2wiLz4KLSAgICAgIDwvcHJvY2Vzc29yPgotICAgIDwvcHJvY2Vzcz4KLQotICAgIDxjcmVhdGUgc291cmNlPSJ7QHNvdXJjZX0iIHRhcmdldD0ie0BpZH0uaHRtbCIgcHJvZHVjZXI9InBhcnNlciIgcHJpbnRlcj0iaHRtbCI+Ci0gICAgICA8cHJvY2Vzc29yIG5hbWU9InhzbHQiPgotICAgICAgICA8cGFyYW1ldGVyIG5hbWU9ImlkIiB2YWx1ZT0ie0BpZH0iLz4KLSAgICAgICAgPHBhcmFtZXRlciBuYW1lPSJzdHlsZXNoZWV0IiB2YWx1ZT0ic2JrOi9zdHlsZS9zdHlsZXNoZWV0cy9kZXNpZ25kb2MyaHRtbC54c2wiLz4KLSAgICAgIDwvcHJvY2Vzc29yPgotICAgIDwvY3JlYXRlPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi08L3hzbDpzdHlsZXNoZWV0PgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3hkb2NzL3N0eWxlL3N0eWxlc2hlZXRzL2Rlc2lnbmRvYzJodG1sLnhzbCBiL3hkb2NzL3N0eWxlL3N0eWxlc2hlZXRzL2Rlc2lnbmRvYzJodG1sLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNDY2M2U0MS4uMDAwMDAwMAotLS0gYS94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy9kZXNpZ25kb2MyaHRtbC54c2wKKysrIC9kZXYvbnVsbApAQCAtMSwyMTcgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci0KLTx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KLQotICA8eHNsOnBhcmFtIG5hbWU9InN0eWxlYm9vay5wcm9qZWN0Ii8+Ci0gIDx4c2w6cGFyYW0gbmFtZT0iY29weXJpZ2h0Ii8+Ci0gIDx4c2w6cGFyYW0gbmFtZT0iaWQiLz4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSIvIj4KLSAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InMxIj4KLSAgICA8aHRtbD4KLSAgICAgIDxoZWFkPgotICAgICAgICA8dGl0bGU+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0aXRsZSIvPjwvdGl0bGU+Ci0gICAgICA8L2hlYWQ+Ci0gICAgICA8Ym9keSB0ZXh0PSIjMDAwMDAwIiBsaW5rPSIjMDAwMGZmIiB2bGluaz0iIzAwMDBhYSIgYWxpbms9IiNmZjAwMDAiCi0gICAgICAgICAgICB0b3BtYXJnaW49IjQiIGxlZnRtYXJnaW49IjQiIG1hcmdpbndpZHRoPSI0IiBtYXJnaW5oZWlnaHQ9IjQiCi0gICAgICAgICAgICBiZ2NvbG9yPSIjZmZmZmZmIj4KLSAgICAgICAgIDx4c2w6dmFyaWFibGUgbmFtZT0idG9waW1hZ2UiIHNlbGVjdD0ic3RyaW5nKC4vcC9pbWcvQHNyYykiLz4KLSAgICAgICAgIDxoMT48YSBocmVmPSJodHRwOi8veG1sLmFwYWNoZS5vcmciPjxpbWcgc3JjPSJpbWFnZXMveyR0b3BpbWFnZX0iLz48L2E+JiMxNjA7JiMxNjA7Ci0gICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQHRpdGxlIi8+PC9oMT48aHIvPgotICAgICAgICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgICAgIDxoci8+Ci0gICAgICAgICAgICA8Zm9udCBzaXplPSItMSIgY29sb3I9IiMwMDg2YjIiPjxpPgotICAgICAgICAgICAgICBDb3B5cmlnaHQgJiMxNjk7IDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIkY29weXJpZ2h0Ii8+Ci0gICAgICAgICAgICA8L2k+PC9mb250PgotICAgICAgPC9ib2R5PgotICAgIDwvaHRtbD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iczIiPgotICAgICAgCi0gICAgICA8aDI+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0aXRsZSIvPjwvaDI+Ci0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InMzIj4KLSAgICAgIDxoMz48eHNsOnZhbHVlLW9mIHNlbGVjdD0iQHRpdGxlIi8+PC9oMz4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iczQiPgotICAgICAgPGg0Pjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAdGl0bGUiLz48L2g0PgotICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotPCEtLSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIC0tPgotPCEtLSBibG9ja3MgLS0+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icCI+Ci0gICAgPHA+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvcD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0ibm90ZSI+Ci0gICAgPHRhYmxlIHdpZHRoPSIxMDAlIiBjZWxsc3BhY2luZz0iMyIgY2VsbHBhZGRpbmc9IjAiIGJvcmRlcj0iMCI+Ci0gICAgICA8dHI+Ci0gICAgICAgIDx0ZCB3aWR0aD0iMjAiIHZhbGlnbj0idG9wIj4KLSAgICAgICAgICA8aW1nIHNyYz0icmVzb3VyY2VzL25vdGUuZ2lmIiB3aWR0aD0iMjAiIGhlaWdodD0iMjQiIHZzcGFjZT0iMCIgaHNwYWNlPSIwIiBib3JkZXI9IjAiIGFsdD0iTm90ZSIvPgotICAgICAgICA8L3RkPgotICAgICAgICA8dGQgdmFsaWduPSJ0b3AiPgotICAgICAgICAgIDxmb250IHNpemU9Ii0xIiBmYWNlPSJhcmlhbCxoZWx2ZXRpY2Esc2Fuc2VyaWYiIGNvbG9yPSIjMDAwMDAwIj4KLSAgICAgICAgICAgIDxpPgotICAgICAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgICAgICAgICA8L2k+Ci0gICAgICAgICAgPC9mb250PgotICAgICAgICA8L3RkPgotICAgICAgPC90cj4gIAotICAgIDwvdGFibGU+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InVsIj4KLSAgICA8dWw+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvdWw+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Im9sIj4KLSAgICA8b2w+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvb2w+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImxpIj4KLSAgICA8bGk+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvbGk+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLSAgICA8IS0tRGVmaW5pdGlvbiBsaXN0czogZ2xvc3MsIHRlcm0sIGxhYmVsLCBpdGVtIC0tPgotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJnbG9zcyI+Ci0gICAgPGRsPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2RsPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgIDwhLS0gPHRlcm0+IGNvbnRhaW5zIGEgc2luZ2xlLXdvcmQsIG11bHRpLXdvcmQgb3Igc3ltYm9saWMgCi0gICAgICAgZGVzaWduYXRpb24gd2hpY2ggaXMgcmVnYXJkZWQgYXMgYSB0ZWNobmljYWwgdGVybS4gLS0+IAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0ZXJtIj4KLSAgICA8ZGZuPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2Rmbj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImxhYmVsIiBwcmlvcml0eT0iMSI+Ci0gICAgPGR0Pjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2R0PgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iaXRlbSIgcHJpb3JpdHk9IjIiPgotICAgIDxkZD4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICA8L2RkPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzb3VyY2UiPgotICAgIDxwPjxmb250IHNpemU9Ii0xIj48cHJlPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L3ByZT48L2ZvbnQ+PC9wPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0YWJsZSI+Ci0gICAgPHRhYmxlIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIyIiBjZWxscGFkZGluZz0iMiI+Ci0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgPC90YWJsZT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idHIiPgotICAgIDx0cj48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC90cj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGgiPgotICAgIDx0ZCBiZ2NvbG9yPSIjMDM5YWNjIiBjb2xzcGFuPSJ7QGNvbHNwYW59IiByb3dzcGFuPSJ7QHJvd3NwYW59IiB2YWxpZ249ImNlbnRlciIgYWxpZ249ImNlbnRlciI+Ci0gICAgICA8Zm9udCBjb2xvcj0iI2ZmZmZmZiIgc2l6ZT0iLTEiIGZhY2U9ImFyaWFsLGhlbHZldGljYSxzYW5zZXJpZiI+Ci0gICAgICAgIDxiPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2I+JiMxNjA7Ci0gICAgICA8L2ZvbnQ+Ci0gICAgPC90ZD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGQiPgotICAgIDx0ZCBiZ2NvbG9yPSIjYTBkZGYwIiBjb2xzcGFuPSJ7QGNvbHNwYW59IiByb3dzcGFuPSJ7QHJvd3NwYW59IiB2YWxpZ249InRvcCIgYWxpZ249ImxlZnQiPgotICAgICAgPGZvbnQgY29sb3I9IiMwMDAwMDAiIHNpemU9Ii0xIiBmYWNlPSJhcmlhbCxoZWx2ZXRpY2Esc2Fuc2VyaWYiPgotICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+JiMxNjA7Ci0gICAgICA8L2ZvbnQ+Ci0gICAgPC90ZD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idG4iPgotICAgIDx0ZCBiZ2NvbG9yPSIjZmZmZmZmIiBjb2xzcGFuPSJ7QGNvbHNwYW59IiByb3dzcGFuPSJ7QHJvd3NwYW59Ij4KLSAgICAgICYjMTYwOwotICAgIDwvdGQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi08IS0tICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgLS0+Ci08IS0tIG1hcmt1cCAtLT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJlbSI+Ci0gICAgPGI+PHhzbDphcHBseS10ZW1wbGF0ZXMvPjwvYj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icmVmIj4KLSAgICA8aT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9pPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImNvZGUiPgotICAgIDxjb2RlPjxmb250IGZhY2U9ImNvdXJpZXIsIG1vbm9zcGFjZWQiPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2ZvbnQ+PC9jb2RlPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImJyIj4KLSAgICA8YnIvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi08IS0tICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgLS0+Ci08IS0tIGxpbmtzIC0tPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9ImxpbmsiPgotICAgIDx4c2w6aWYgdGVzdD0ic3RyaW5nLWxlbmd0aChAYW5jaG9yKT0wIj4KLSAgICAgIDx4c2w6aWYgdGVzdD0ic3RyaW5nLWxlbmd0aChAaWRyZWYpPTAiPgotICAgICAgICA8IS0teHNsOmFwcGx5LXRlbXBsYXRlcy8tLT4KLSAgICAgIDwveHNsOmlmPgotICAgICAgPHhzbDppZiB0ZXN0PSJzdHJpbmctbGVuZ3RoKEBpZHJlZik+MCI+Ci0gICAgICAgIDxhIGhyZWY9IntAaWRyZWZ9Lmh0bWwiPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2E+Ci0gICAgICA8L3hzbDppZj4KLSAgICA8L3hzbDppZj4KLQotICAgIDx4c2w6aWYgdGVzdD0ic3RyaW5nLWxlbmd0aChAYW5jaG9yKT4wIj4KLSAgICAgIDx4c2w6aWYgdGVzdD0ic3RyaW5nLWxlbmd0aChAaWRyZWYpPTAiPgotICAgICAgICA8YSBocmVmPSIje0BhbmNob3J9Ij48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9hPgotICAgICAgPC94c2w6aWY+Ci0gICAgICA8eHNsOmlmIHRlc3Q9InN0cmluZy1sZW5ndGgoQGlkcmVmKT4wIj4KLSAgICAgICAgPGEgaHJlZj0ie0BpZHJlZn0uaHRtbCN7QGFuY2hvcn0iPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2E+Ci0gICAgICA8L3hzbDppZj4KLSAgICA8L3hzbDppZj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iYW5jaG9yIj4KLSAgICA8YSBuYW1lPSJ7QG5hbWV9Ij48eHNsOmNvbW1lbnQ+YW5jaG9yPC94c2w6Y29tbWVudD48L2E+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Imp1bXAiPgotICAgIDxhIGhyZWY9IntAaHJlZn0iPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2E+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii9zMS9zMi8vaW1nIj4KLSAgICA8aW1nIHNyYz0iaW1hZ2VzL3tAc3JjfSIvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJyZXNvdXJjZS1yZWYiPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0icmVzb3VyY2VGaWxlIiAKLSAgICAgICAgICBzZWxlY3Q9ImRvY3VtZW50KCRzdHlsZWJvb2sucHJvamVjdCkvYm9vay9yZXNvdXJjZXMvQHNvdXJjZSIvPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0ieHJlZiIgc2VsZWN0PSJAaWRyZWYiLz4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9ImhyZWYiCi0gICAgICAgICAgc2VsZWN0PSJkb2N1bWVudCgkcmVzb3VyY2VGaWxlKS9yZXNvdXJjZXMvcmVzb3VyY2VbQGlkPSR4cmVmXS9AbG9jYXRpb24iLz4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9ImxhYmVsIgotICAgICAgICAgIHNlbGVjdD0iZG9jdW1lbnQoJHJlc291cmNlRmlsZSkvcmVzb3VyY2VzL3Jlc291cmNlW0BpZD0keHJlZl0vQHRpdGxlIi8+Ci0gICAgPEEgaHJlZj0ieyRocmVmfSIgdGFyZ2V0PSJfdG9wIj48eHNsOnZhbHVlLW9mIHNlbGVjdD0iJGxhYmVsIi8+PC9BPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJodW1hbi1yZXNvdXJjZS1yZWYiPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0icmVzb3VyY2VGaWxlIiAKLSAgICAgICAgICBzZWxlY3Q9ImRvY3VtZW50KCRzdHlsZWJvb2sucHJvamVjdCkvYm9vay9yZXNvdXJjZXMvQHNvdXJjZSIvPiAgCi0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJyZWYiICBzZWxlY3Q9IkBpZHJlZiIvPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0ibWFpbHRvIgotICAgICAgICAgIHNlbGVjdD0iZG9jdW1lbnQoJHJlc291cmNlRmlsZSkvcmVzb3VyY2VzL2h1bWFuLXJlc291cmNlW0BpZD0kcmVmXS9AbWFpbHRvIi8+Ci0gICA8eHNsOnZhcmlhYmxlIG5hbWU9Im5hbWUiCi0gICAgICAgICAgc2VsZWN0PSJkb2N1bWVudCgkcmVzb3VyY2VGaWxlKS9yZXNvdXJjZXMvaHVtYW4tcmVzb3VyY2VbQGlkPSRyZWZdL0BuYW1lIi8+ICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICA8QSBocmVmPSJtYWlsdG86eyRtYWlsdG99Ij48eHNsOnZhbHVlLW9mIHNlbGVjdD0iJG5hbWUiLz48L0E+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi08IS0tICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgLS0+Ci0KLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEveGRvY3Mvc3R5bGUvc3R5bGVzaGVldHMvZG9uZS54c2wgYi94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy9kb25lLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOGU1NDdmMC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy9kb25lLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDY2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiID8+Ci0KLTwhRE9DVFlQRSB4c2w6c3R5bGVzaGVldD4KLQotPCEtLSBYU0wgU3R5bGUgc2hlZXQsIERURCBvbWl0dGVkIC0tPgotCi08eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIiB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSI+Ci0gIDx4c2w6b3V0cHV0IG1ldGhvZD0ieG1sIi8+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJDb21taXRzIj4KLSAgPHhzbDpjb21tZW50PlRoaXMgWE1MIGZyYWdtZW50IGNvbnRhaW5zIGEgbGlzdCBvZiBzb3VyY2UgY29kZSB1cGRhdGVzIHRvIHBsYWNlIGluIGFuICZsdDtzMyZndDsgc2VjdGlvbiBvZiByZWFkbWUueG1sPC94c2w6Y29tbWVudD4KLSAgICA8eHNsOmlmIHRlc3Q9ImNvdW50KENvbW1pdFtAY2F0ZWdvcnk9J2NvcmUnXSk+MCI+Ci0gICAgICA8cD4gQ29yZSAoTm9uLVhTTFRDKSBzb3VyY2UgY29kZSB1cGRhdGVzOjwvcD4KLSAgICAgIDx1bD4KLSAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJDb21taXRbQGNhdGVnb3J5PSdjb3JlJ10iPgotICAgICAgICA8bGk+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJXaG98RGF0ZUNvbW1pdHRlZHxNb2RpZmllZHxBZGRlZHxSZW1vdmVkfExvZyIvPjwvbGk+Ci0gICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgIDwvdWw+Ci0gICAgPC94c2w6aWY+Ci0gICAgPHhzbDppZiB0ZXN0PSJjb3VudChDb21taXRbQGNhdGVnb3J5PSdjb3JlJ10pPTAiPgotICAgICAgPG5vdGU+VGhpcyByZWxlYXNlIGluY2x1ZGVzIG5vIHVwZGF0ZXMgb2YgdGhlIG5vbi1YU0xUQyBjb3JlIHNvdXJjZSBjb2RlLjwvbm90ZT4KLSAgICA8L3hzbDppZj4KLSAgICA8eHNsOmlmIHRlc3Q9ImNvdW50KENvbW1pdFtAY2F0ZWdvcnk9J2NvbXBhdCddKT4wIj4KLSAgICAgIDxwPkNvbXBhdGliaWxpdHkgc291cmNlIGNvZGUgdXBkYXRlczo8L3A+Ci0gICAgICA8dWw+Ci0gICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iQ29tbWl0W0BjYXRlZ29yeT0nY29tcGF0J10iPgotICAgICAgICA8bGk+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJXaG98RGF0ZUNvbW1pdHRlZHxNb2RpZmllZHxBZGRlZHxSZW1vdmVkfExvZyIvPjwvbGk+Ci0gICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgIDwvdWw+Ci0gICAgPC94c2w6aWY+Ci0gICAgPHhzbDppZiB0ZXN0PSJjb3VudChDb21taXRbQGNhdGVnb3J5PSdjb21wYXQnXSk9MCI+Ci0gICAgICA8bm90ZT5UaGlzIHJlbGVhc2UgaW5jbHVkZXMgbm8gdXBkYXRlcyBvZiB0aGUgY29tcGF0aWJpbGl0eSBzb3VyY2UgY29kZSAobm93IGRlcHJlY2F0ZWQpLjwvbm90ZT4KLSAgICA8L3hzbDppZj4KLSAgICA8IS0teHNsOmlmIHRlc3Q9ImNvdW50KENvbW1pdFtAY2F0ZWdvcnk9J3hzbHRjJ10pPjAiPgotICAgICAgPHA+WFNMVEMgc291cmNlIGNvZGUgdXBkYXRlczo8L3A+Ci0gICAgICA8dWw+Ci0gICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0iQ29tbWl0W0BjYXRlZ29yeT0neHNsdGMnXSI+Ci0gICAgICAgIDxsaT48eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9Ildob3xEYXRlQ29tbWl0dGVkfE1vZGlmaWVkfEFkZGVkfFJlbW92ZWR8TG9nIi8+PC9saT4KLSAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgPC91bD4KLSAgICA8L3hzbDppZj4KLSAgICA8eHNsOmlmIHRlc3Q9ImNvdW50KENvbW1pdFtAY2F0ZWdvcnk9J3hzbHRjJ10pPTAiPgotICAgICAgPG5vdGU+VGhpcyByZWxlYXNlIGluY2x1ZGVzIG5vIHVwZGF0ZXMgb2YgdGhlIFhTTFRDIHNvdXJjZSBjb2RlLjwvbm90ZT4KLSAgICA8L3hzbDppZi0tPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9IldobyI+Ci0gICAgPHJlZj5Db21taXR0ZWQgYnkgPC9yZWY+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9IkRhdGVDb21taXR0ZWQiPgotICAgIDxyZWY+IG9uIDwvcmVmPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PGJyLz4KLSAgPC94c2w6dGVtcGxhdGU+ICAgIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJNb2RpZmllZCI+ICAgIAotICAgIDxyZWY+TW9kaWZpZWQ6IDwvcmVmPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PGJyLz4KLSAgPC94c2w6dGVtcGxhdGU+ICAgIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJBZGRlZCI+ICAgIAotICAgIDxyZWY+QWRkZWQ6IDwvcmVmPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+PGJyLz4KLSAgPC94c2w6dGVtcGxhdGU+ICAgIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJSZW1vdmVkIj4gICAgCi0gICAgPHJlZj5SZW1vdmVkOiA8L3JlZj48eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPjxici8+Ci0gIDwveHNsOnRlbXBsYXRlPiAgICAKLSAgICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJMb2ciPiAgICAKLSAgICA8cmVmPkNvbW1pdHRlcidzIGxvZyBlbnRyeTogPC9yZWY+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48YnIvPjxici8+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLTwveHNsOnN0eWxlc2hlZXQ+ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEveGRvY3Mvc3R5bGUvc3R5bGVzaGVldHMvc3BlYy54c2wgYi94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy9zcGVjLnhzbApkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMjZkNzNiZC4uMDAwMDAwMAotLS0gYS94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy9zcGVjLnhzbAorKysgL2Rldi9udWxsCkBAIC0xLDIyMCArMCwwIEBACi08P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIiA/PgotCi08IURPQ1RZUEUgeHNsOnN0eWxlc2hlZXQgWwotPCFFTlRJVFkgY29weSAgICImIzE2OTsiPgotPCFFTlRJVFkgbmJzcCAgICImIzE2MDsiPgotXT4KLQotPCEtLSBYU0wgU3R5bGUgc2hlZXQsIERURCBvbWl0dGVkIC0tPgotCi08eHNsOnN0eWxlc2hlZXQgdmVyc2lvbj0iMS4wIiB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIKLSAgICAgICAgICAgICAgICB4bWxuczpyZWRpcmVjdD0ib3JnLmFwYWNoZS54YWxhbi5saWIuUmVkaXJlY3QiCi0gICAgICAgICAgICAgICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXM9InJlZGlyZWN0Ij4KLSAgPHhzbDpvdXRwdXQgbWV0aG9kPSJodG1sIiBkb2N0eXBlLXB1YmxpYz0iLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiIvPgotICAKLSAgPHhzbDpwYXJhbSBuYW1lPSJwYWNrYWdlLXJvb3QiIHNlbGVjdD0iJy4uLy4uLy4uL3NyYy8nIi8+ICA8IS0tIHJvb3Qgb2YgZGVzdGluYXRpb24gZm9yIHBhY2thZ2UuaHRtbCBmaWxlcyAtLT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzcGVjIj4KLSAgICA8aHRtbD4KLSAgICAgIDxoZWFkPgotICAgICAgICA8dGl0bGU+Ci0gICAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9ImhlYWRlci90aXRsZSIvPgotICAgICAgICA8L3RpdGxlPgotICAgICAgPC9oZWFkPgotICAgICAgPGJvZHk+Ci0gICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgIDwvYm9keT4KLSAgICA8L2h0bWw+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0ic3BlYy90aXRsZVsxXSI+Ci0gICAgPGgxPjx4c2w6YXBwbHktdGVtcGxhdGVzLz48L2gxPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJmcm9udG1hdHRlci9wdWJkYXRlIj4KLSAgICA8cD48Yj5FZGl0IERhdGU6IDwvYj48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9wPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJmcm9udG1hdHRlci9jb3B5cmlnaHQiPgotICAgIDwhLS0gcD4mY29weTs8eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9wIC0tPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJmcm9udG1hdHRlci9hdXRob3IiPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InNwZWMvdGl0bGUiPgotICAgIDxoMj4KLSAgICAgIDx4c2w6Y2hvb3NlPgotICAgICAgICA8eHNsOndoZW4gdGVzdD0iQGlkIj4KLSAgICAgICAgICA8YSBuYW1lPSJAaWQiPgotICAgICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgICAgICAgIDwvYT4KLSAgICAgICAgPC94c2w6d2hlbj4KLSAgICAgICAgPHhzbDpvdGhlcndpc2U+Ci0gICAgICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgICAgICA8L3hzbDpvdGhlcndpc2U+Ci0gICAgICA8L3hzbDpjaG9vc2U+Ci0gICAgPC9oMj4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG5hbWU9ImFwcGx5LWlkLXRlbXBsYXRlcyI+Ci0gICAgPHhzbDpjaG9vc2U+Ci0gICAgICA8eHNsOndoZW4gdGVzdD0iQGlkIj4KLSAgICAgICAgPGEgbmFtZT0ie0BpZH0iPgotICAgICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgICAgPC9hPgotICAgICAgPC94c2w6d2hlbj4KLSAgICAgIDx4c2w6b3RoZXJ3aXNlPgotICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgICA8L3hzbDpvdGhlcndpc2U+Ci0gICAgPC94c2w6Y2hvb3NlPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InNlY3QyL3RpdGxlIHwgc3BlYy8qL3RpdGxlIj4KLSAgICA8aDM+Ci0gICAgICA8eHNsOmNhbGwtdGVtcGxhdGUgbmFtZT0iYXBwbHktaWQtdGVtcGxhdGVzIi8+Ci0gICAgPC9oMz4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzZWN0My90aXRsZSI+Ci0gICAgPGg0PgotICAgICAgPHhzbDpjYWxsLXRlbXBsYXRlIG5hbWU9ImFwcGx5LWlkLXRlbXBsYXRlcyIvPgotICAgIDwvaDQ+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InNlY3Q0L3RpdGxlIj4KLSAgICA8aDU+Ci0gICAgICA8eHNsOmNhbGwtdGVtcGxhdGUgbmFtZT0iYXBwbHktaWQtdGVtcGxhdGVzIi8+Ci0gICAgPC9oNT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJwYXJhIj4KLSAgICA8cD48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9wPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ2YXJpYWJsZWxpc3QiPgotICAgIDx1bD4KLSAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0idmFybGlzdGVudHJ5Ij4KLSAgICAgIDxsaT4KLSAgICAgICAgPHA+PGI+PHhzbDphcHBseS10ZW1wbGF0ZXMgc2VsZWN0PSJ0ZXJtIi8+PC9iPjxici8+Ci0gICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzIHNlbGVjdD0ibGlzdGl0ZW0iLz48L3A+Ci0gICAgICA8L2xpPgotICAgIDwveHNsOmZvci1lYWNoPgotICAgIDwvdWw+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9Im9yZGVyZWRsaXN0Ij4KLSAgICA8b2w+Ci0gICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9Imxpc3RpdGVtIj4KLSAgICAgIDxsaT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+PC9saT4KLSAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICA8L29sPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJwYXR0ZXJucyI+Ci0gICAgPEgzPjx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAbW9kdWxlIi8+PHhzbDp0ZXh0PiA8L3hzbDp0ZXh0PlBhdHRlcm5zPC9IMz4KLSAgICA8dWw+Ci0gICAgICA8eHNsOmZvci1lYWNoIHNlbGVjdD0icGF0dGVybiI+Ci0gICAgICAgIDxwPgotICAgICAgICAgIDxiPgotICAgICAgICAgICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9InBhdHRlcm4tbmFtZSI+Ci0gICAgICAgICAgICAgIDx4c2w6Y2FsbC10ZW1wbGF0ZSBuYW1lPSJhcHBseS1pZC10ZW1wbGF0ZXMiLz4KLSAgICAgICAgICAgIDwveHNsOmZvci1lYWNoPgotICAgICAgICAgIDwvYj4KLSAgICAgICAgICA8YnIvPgotICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9IipbbmFtZSgpICE9ICdwYXR0ZXJuLW5hbWUnXSIvPjwvcD4KLSAgICAgIDwveHNsOmZvci1lYWNoPgotICAgIDwvdWw+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icGF0dGVybi9pbnRlbnQiPgotICAgIDxici8+PGk+SW50ZW50OiA8L2k+PHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InBhdHRlcm4vcmVzcG9uc2liaWxpdGllcyI+Ci0gICAgPGJyLz48aT5SZXNwb25zaWJpbGl0aWVzOiA8L2k+PHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJwYXR0ZXJuL3BvdGVudGlhbC1hbHRlcm5hdGUtbmFtZSI+Ci0gICAgPGJyLz48aT5Qb3RlbnRpYWwgYWx0ZXJuYXRlIG5hbWU6IDwvaT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icGF0dGVybi90aHJlYWQtc2FmZXR5Ij4KLSAgICA8YnIvPjxpPlRocmVhZCBzYWZldHk6IDwvaT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InBhdHRlcm4vbm90ZXMiPgotICAgIDxici8+PGk+Tm90ZXM6IDwvaT48eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InByb2dyYW1saXN0aW5nIj4KLSAgICA8Y29kZT4KLSAgICA8cHJlPgotICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotICAgIDwvcHJlPgotICAgIDwvY29kZT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJsaW5rIj4KLSAgICA8QSBocmVmPSIje0BsaW5rZW5kfSI+Ci0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgPC9BPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idWxpbmsiPgotICAgIDxBIGhyZWY9IntAdXJsfSI+Ci0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gICAgPC9BPgotICA8L3hzbDp0ZW1wbGF0ZT4KLQotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0ZXJtcmVmIj4KLSAgICA8eHNsOmNob29zZT4KLSAgICAgIDx4c2w6d2hlbiB0ZXN0PSJAbGluay11cmwiPgotICAgICAgICA8QSBocmVmPSIje0BsaW5rLXVybH0iPgotICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuIi8+Ci0gICAgICAgIDwvQT4KLSAgICAgIDwveHNsOndoZW4+Ci0gICAgICA8eHNsOm90aGVyd2lzZT4KLSAgICAgICAgPFU+PHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4iLz48L1U+Ci0gICAgICA8L3hzbDpvdGhlcndpc2U+Ci0gICAgPC94c2w6Y2hvb3NlPgotICA8L3hzbDp0ZW1wbGF0ZT4KLSAgCi0gIDx4c2w6dGVtcGxhdGUgbWF0Y2g9InBsaW5rIj4KLSAgICA8eHNsOnRleHQ+e0BsaW5rIDwveHNsOnRleHQ+Ci0gICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPgotICAgIDx4c2w6dGV4dD59PC94c2w6dGV4dD4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzZWN0MVtAaWQ9J3BhY2thZ2UnXSI+Ci0gICAgPHhzbDp2YXJpYWJsZSBuYW1lPSJmaWxlbmFtZSIgc2VsZWN0PSJjb25jYXQoJHBhY2thZ2Utcm9vdCx0cmFuc2xhdGUodGl0bGUsJy4nLCAnLycpLCcvcGFja2FnZS5odG1sJykiLz4KLSAgICA8cmVkaXJlY3Q6d3JpdGUgZmlsZT0ieyRmaWxlbmFtZX0iPgotICAgICAgPHhzbDpjYWxsLXRlbXBsYXRlIG5hbWU9InN1Yi1wYWNrYWdlIi8+Ci0gICAgPC9yZWRpcmVjdDp3cml0ZT4KLSAgPC94c2w6dGVtcGxhdGU+Ci0gIAotICA8eHNsOnRlbXBsYXRlIG1hdGNoPSJzZWN0MltAaWQ9J3NwZWNpYWxpemVkLXBhY2thZ2VzJ10iPgotICAgIDx4c2w6bWVzc2FnZT5Gb3VuZCBzcGVjaWFsaXplZC1wYWNrYWdlczwveHNsOm1lc3NhZ2U+Ci0gICAgPHhzbDpmb3ItZWFjaCBzZWxlY3Q9InNlY3QzIj4KLQkgIDx4c2w6dmFyaWFibGUgbmFtZT0iZmlsZW5hbWUiIHNlbGVjdD0iY29uY2F0KCRwYWNrYWdlLXJvb3QsdHJhbnNsYXRlKHRpdGxlLCcuJywgJy8nKSwnL3BhY2thZ2UuaHRtbCcpIi8+Ci0gICAgICA8cmVkaXJlY3Q6d3JpdGUgZmlsZT0ieyRmaWxlbmFtZX0iPgotICAgICAgICA8eHNsOmNhbGwtdGVtcGxhdGUgbmFtZT0ic3ViLXBhY2thZ2UiLz4KLSAgICAgIDwvcmVkaXJlY3Q6d3JpdGU+Ci0gICAgPC94c2w6Zm9yLWVhY2g+Ci0gIDwveHNsOnRlbXBsYXRlPgotICAKLSAgPHhzbDp0ZW1wbGF0ZSBuYW1lPSJzdWItcGFja2FnZSI+Ci0gICAgPGh0bWw+Ci0gICAgICAgPGhlYWQ+Ci0gICAgICAgICA8dGl0bGU+Ci0gICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0aXRsZSIvPgotICAgICAgICAgPC90aXRsZT4KLSAgICAgICA8L2hlYWQ+Ci0gICAgICAgPGJvZHk+Ci0gICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcyBzZWxlY3Q9Iipbbm90IChuYW1lKCk9J3RpdGxlJyldIi8+Ci0gICAgICAgPC9ib2R5PgotICAgICA8L2h0bWw+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0KLTwveHNsOnN0eWxlc2hlZXQ+Ci0KZGlmZiAtLWdpdCBhL3hkb2NzL3N0eWxlL3N0eWxlc2hlZXRzL3htbDJmby54c2wgYi94ZG9jcy9zdHlsZS9zdHlsZXNoZWV0cy94bWwyZm8ueHNsCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMDU5MzBkLi4wMDAwMDAwCi0tLSBhL3hkb2NzL3N0eWxlL3N0eWxlc2hlZXRzL3htbDJmby54c2wKKysrIC9kZXYvbnVsbApAQCAtMSw0ODkgKzAsMCBAQAotPD94bWwgdmVyc2lvbj0iMS4wIj8+Ci0KLTwhLS0gICAgWFNMVCBzdHlsZXNoZWV0IHRvIGNvbnZlcnQgdGhlIFhhbGFuIGRvY3VtZW50YXRpb24gY29sbGVjdGVkIGluIG9uZSB4bWwgZmlsZSBpbnRvIGEgZm8gZmlsZQotICAgICAgICBmb3IgdXNlIGluIEZPUCAKLQotVEJEOiAtIFRoZSBmYXEgZG9lc24ndCBzaG93IGluIHRoZSBjb250ZW50Ci0gICAgIC0gY2hlY2sgd2h5IG1hcmdpbi1ib3R0b20gb24gdGhlIHBhZ2Ugd2l0aCBwcm9wZXJ0aWVzIGlzIHRvbyBsYXJnZQotICAgICAtIGNoZWNrIHdoeSBrZWVwLW5leHQgbm90IG9ubHkgZG9lc24ndCB3b3JrLCBidXQgbGVhZHMgdG8gcmVwZWF0aW5nIGFscmVhZHkgcHJpbnRlZCBsaW5lcwotICAgICAtIG1ha2UgbGluZXMgY29udGFpbmluZyBvbmx5IGNvZGUgbG9vayBuaWNlciAoc21hbGxlciBsaW5lIGhlaWdodCkKLSAgICAgLSByZXBsYWNlIGJ1bGxldHMgaW4gb3JkZXJlZCBsaXN0cyB3aXRoIG51bWJlcnMKLSAgICAgLSBjb3JyZWN0IHRoZSBoYWNrIHJlcGxhY2luZyBuYnNwIHdpdGggJy0nCi0gICAgIC0gaGFuZGxlIHRoZSBsaW5rcyBjb3JyZWN0bHkgd2hpY2ggaGF2ZSBiZWVuIGV4dGVybmFsIGluIHRoZSBodG1sIGRvYyBhbmQgYXJlIG5vdyBpbnRlcm5hbAotCi0tLT4KLQotPHhzbDpzdHlsZXNoZWV0Ci0gICAgIHhtbG5zOnhzbD0iaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIiB2ZXJzaW9uPSIxLjAiCi0gICAgIHhtbG5zOmZvPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9Gb3JtYXQiPgotICAgICAKLSAgICAgPCEtLSB0byB1c2Ugd2l0aCBkb2N1bWVudCgpIHRvIGdldCByZXNvdXJjZXMueG1sIC0tPgotICAgIDx4c2w6cGFyYW0gbmFtZT0icmVzb3VyY2VGaWxlIiBzZWxlY3Q9IicuLi8uLi9zb3VyY2VzL3hhbGFuL3Jlc291cmNlcy54bWwnIi8+Ci0gICAgPHhzbDpwYXJhbSBuYW1lPSJwcm9qZWN0IiBzZWxlY3Q9IlhhbGFuIi8+Ci0gICAgICAgICAgICAgIAotPHhzbDp0ZW1wbGF0ZSBtYXRjaCA9Ii8iPgotCTxmbzpyb290IHhtbG5zOmZvPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9Gb3JtYXQiPgotCi0JICA8IS0tIGRlZmluZXMgcGFnZSBsYXlvdXQgLS0+Ci0JICA8Zm86bGF5b3V0LW1hc3Rlci1zZXQ+Ci0JCTxmbzpzaW1wbGUtcGFnZS1tYXN0ZXIgbWFzdGVyLW5hbWU9InNpbXBsZSIKLQkJCQkJCQkgICBwYWdlLWhlaWdodD0iMjkuN2NtIiAKLQkJCQkJCQkgICBwYWdlLXdpZHRoPSIyMWNtIgotCQkJCQkJCSAgIG1hcmdpbi10b3A9IjEuNWNtIiAKLQkJCQkJCQkgICBtYXJnaW4tYm90dG9tPSIyY20iIAotCQkJCQkJCSAgIG1hcmdpbi1sZWZ0PSIyLjVjbSIgCi0JCQkJCQkJICAgbWFyZ2luLXJpZ2h0PSIyLjVjbSI+Ci0JCSAgPGZvOnJlZ2lvbi1ib2R5IG1hcmdpbi10b3A9IjNjbSIvPgotCQkgIDxmbzpyZWdpb24tYmVmb3JlIGV4dGVudD0iMS41Y20iLz4KLQkJICA8Zm86cmVnaW9uLWFmdGVyIGV4dGVudD0iMS41Y20iLz4KLQkJPC9mbzpzaW1wbGUtcGFnZS1tYXN0ZXI+Ci0JICA8L2ZvOmxheW91dC1tYXN0ZXItc2V0PgotCi0JICA8Zm86cGFnZS1zZXF1ZW5jZSBtYXN0ZXItbmFtZT0ic2ltcGxlIj4KLQkJPGZvOnN0YXRpYy1jb250ZW50IGZsb3ctbmFtZT0ieHNsLXJlZ2lvbi1iZWZvcmUiPgotCQkJPGZvOmJsb2NrIHRleHQtYWxpZ249ImVuZCIgCi0JCQkgICAgCSAgZm9udC1zaXplPSIxMHB0IiAKLQkJCQkJICBmb250LWZhbWlseT0ic2VyaWYiIAotCQkJCQkgIGxpbmUtaGVpZ2h0PSIxNHB0IiA+Ci0JCQkJPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IiRwcm9qZWN0Ii8+IGRvY3VtZW50YXRpb24gLSBwLiA8Zm86cGFnZS1udW1iZXIvPgotCQkJPC9mbzpibG9jaz4KLQkJPC9mbzpzdGF0aWMtY29udGVudD4gCi0KLQkJPGZvOmZsb3cgZmxvdy1uYW1lPSJ4c2wtcmVnaW9uLWJvZHkiPgotCi0gICAgICAgICAgPGZvOmJsb2NrIGZvbnQtc2l6ZT0iMThwdCIgCi0gICAgICAgICAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiAKLSAgICAgICAgICAgICAgICAgICAgbGluZS1oZWlnaHQ9IjI0cHQiCi0gICAgICAgICAgICAgICAgICAgIHNwYWNlLWFmdGVyLm9wdGltdW09IjE1cHQiCi0gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I9ImJsdWUiCi0gICAgICAgICAgICAgICAgICAgIGNvbG9yPSJ3aGl0ZSIKLSAgICAgICAgICAgICAgICAgICAgdGV4dC1hbGlnbj0iY2VudGVyIj4KLSAgICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIkcHJvamVjdCIvPiAtIGFuIFhTTCBUcmFuc2Zvcm1lcgotICAgICAgICAgIDwvZm86YmxvY2s+Ci0KLQotICAgICAgICA8IS0tIGdlbmVyYXRlcyB0YWJsZSBvZiBjb250ZW50cyBhbmQgcHV0cyBpdCBpbnRvIGEgdGFibGUgLS0+Ci0KLSAgICAgICAgIDxmbzpibG9jayBmb250LXNpemU9IjE0cHQiIAotICAgICAgICAgICAgICAgICAgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIAotICAgICAgICAgICAgICAgICAgbGluZS1oZWlnaHQ9IjE4cHQiCi0gICAgICAgICAgICAgICAgICBzcGFjZS1hZnRlci5vcHRpbXVtPSIxMHB0IgotICAgICAgICAgICAgICAgICAgZm9udC13ZWlnaHQ9ImJvbGQiCi0gICAgICAgICAgICAgICAgICBzdGFydC1pbmRlbnQ9IjE1cHQiPgotICAgICAgICAgICAgQ29udGVudAotICAgICAgICAgPC9mbzpibG9jaz4KLQotICAgICAgICAgPGZvOnRhYmxlPgotICAgICAgICAgICAgPGZvOnRhYmxlLWNvbHVtbiBjb2x1bW4td2lkdGg9IjFjbSIvPgotICAgICAgICAgICAgPGZvOnRhYmxlLWNvbHVtbiBjb2x1bW4td2lkdGg9IjEwY20iLz4KLSAgICAgICAgICAgIDxmbzp0YWJsZS1jb2x1bW4gY29sdW1uLXdpZHRoPSI1Y20iLz4KLSAgICAgICAgICAgIDxmbzp0YWJsZS1ib2R5IGZvbnQtc2l6ZT0iMTJwdCIgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lLWhlaWdodD0iMTZwdCIKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIj4KLSAgICAgICAgICAgICAgPGZvOnRhYmxlLXJvdz4KLSAgICAgICAgICAgICAgICAgIDxmbzp0YWJsZS1jZWxsPgotICAgICAgICAgICAgICAgICAgICAgPGZvOmJsb2NrIHRleHQtYWxpZ249ImVuZCIgPgotICAgICAgICAgICAgICAgICAgICAgPC9mbzpibG9jaz4KLSAgICAgICAgICAgICAgICAgIDwvZm86dGFibGUtY2VsbD4KLSAgICAgICAgICAgICAgICAgIDxmbzp0YWJsZS1jZWxsPgotICAgICAgICAgICAgICAgICAgICAgPGZvOmJsb2NrIHRleHQtYWxpZ249ImVuZCIgPgotICAgICAgICAgICAgICAgICAgICAgPC9mbzpibG9jaz4KLSAgICAgICAgICAgICAgICAgIDwvZm86dGFibGUtY2VsbD4KLSAgICAgICAgICAgICAgICAgIDxmbzp0YWJsZS1jZWxsPgotICAgICAgICAgICAgICAgICAgICAgPGZvOmJsb2NrIHRleHQtYWxpZ249ImVuZCIgPgotICAgICAgICAgICAgICAgICAgICAgcGFnZQotICAgICAgICAgICAgICAgICAgICAgPC9mbzpibG9jaz4KLSAgICAgICAgICAgICAgICAgIDwvZm86dGFibGUtY2VsbD4KLSAgICAgICAgICAgICAgPC9mbzp0YWJsZS1yb3c+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJkb2N1bWVudGF0aW9uL2NoYXB0ZXIiPiAKLSAgICAgICAgICAgICAgICA8Zm86dGFibGUtcm93PgotICAgICAgICAgICAgICAgICAgPGZvOnRhYmxlLWNlbGw+Ci0gICAgICAgICAgICAgICAgICAgICA8Zm86YmxvY2sgdGV4dC1hbGlnbj0iZW5kIiA+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8eHNsOm51bWJlciB2YWx1ZT0icG9zaXRpb24oKSIgZm9ybWF0PSJJIi8+LiAgCi0gICAgICAgICAgICAgICAgICAgICA8L2ZvOmJsb2NrPgotICAgICAgICAgICAgICAgICAgPC9mbzp0YWJsZS1jZWxsPgotICAgICAgICAgICAgICAgICAgPGZvOnRhYmxlLWNlbGw+Ci0gICAgICAgICAgICAgICAgICAgICA8Zm86YmxvY2sgIHRleHQtYWxpZ249InN0YXJ0IiA+Ci0gICAgICAgICAgICAgICAgICAgICAgICA8Zm86YmFzaWMtbGluayBjb2xvcj0iYmx1ZSI+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJpbnRlcm5hbC1kZXN0aW5hdGlvbiI+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQGlkIi8+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICA8L3hzbDphdHRyaWJ1dGU+Ci0gICAgICAgICAgICAgICAgICAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJzMS9AdGl0bGV8ZmFxcy9AdGl0bGUiLz4KLSAgICAgICAgICAgICAgICAgICAgICAgIDwvZm86YmFzaWMtbGluaz4KLSAgICAgICAgICAgICAgICAgICAgIDwvZm86YmxvY2s+Ci0gICAgICAgICAgICAgICAgICA8L2ZvOnRhYmxlLWNlbGw+Ci0gICAgICAgICAgICAgICAgICA8Zm86dGFibGUtY2VsbD4KLSAgICAgICAgICAgICAgICAgICAgIDxmbzpibG9jayB0ZXh0LWFsaWduPSJlbmQiPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgIDxmbzpwYWdlLW51bWJlci1jaXRhdGlvbiByZWYtaWQ9IntAaWR9Ii8+Ci0gICAgICAgICAgICAgICAgICAgICA8L2ZvOmJsb2NrPgotICAgICAgICAgICAgICAgICAgPC9mbzp0YWJsZS1jZWxsPgotICAgICAgICAgICAgICAgPC9mbzp0YWJsZS1yb3c+Ci0gICAgICAgICAgICA8L3hzbDpmb3ItZWFjaD4KLSAgICAgICAgICAgIDwvZm86dGFibGUtYm9keT4KLSAgICAgICAgIDwvZm86dGFibGU+Ci0JCSA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+IAotCSAgIDwvZm86Zmxvdz4KLQkgICA8L2ZvOnBhZ2Utc2VxdWVuY2U+Ci0JPC9mbzpyb290PgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS1jaGFwdGVyLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoPSJjaGFwdGVyIj4KLSAgPGZvOmJsb2NrIGlkPSJ7QGlkfSIgYnJlYWstYmVmb3JlPSJwYWdlIi8+Ci0JPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAgIAotPC94c2w6dGVtcGxhdGU+ICAKLQotPCEtLSBzMSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2ggPSJzMSI+Ci0gICA8Zm86YmxvY2sgZm9udC1zaXplPSIxOHB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiAKLSAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIyNHB0IgotICAgICAgICAgICAgc3BhY2UtYmVmb3JlLm9wdGltdW09IjE1cHQiCi0gICAgICAgICAgICBzcGFjZS1hZnRlci5vcHRpbXVtPSIxNXB0IgotICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcj0iYmx1ZSIKLSAgICAgICAgICAgIGNvbG9yPSJ3aGl0ZSIKLSAgICAgICAgICAgIGtlZXAtd2l0aC1uZXh0LndpdGhpbi1wYWdlPSJhbHdheXMiCi0gICAgICAgICAgICB0ZXh0LWFsaWduPSJjZW50ZXIiPgotICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJpZCI+Ci0gICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0cmFuc2xhdGUoQHRpdGxlLCcgKSwtLignLCdfX19fJykiLz4KLSAgICAgPC94c2w6YXR0cmlidXRlPgotICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iQHRpdGxlIi8+Ci0gICA8L2ZvOmJsb2NrPgotICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4gCi08L3hzbDp0ZW1wbGF0ZT4KLQotPCEtLSBzMiAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2ggPSJzMiI+Ci0gICA8Zm86YmxvY2sgZm9udC1zaXplPSIxNnB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiAKLSAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIyMHB0IgotICAgICAgICAgICAga2VlcC13aXRoLW5leHQud2l0aGluLXBhZ2U9ImFsd2F5cyIgICAgICAgICAgICAKLSAgICAgICAgICAgIHNwYWNlLWJlZm9yZS5vcHRpbXVtPSIxNXB0IgotICAgICAgICAgICAgc3BhY2UtYWZ0ZXIub3B0aW11bT0iMTJwdCIKLSAgICAgICAgICAgIHRleHQtYWxpZ249InN0YXJ0IgotICAgICAgICAgICAgcGFkZGluZy10b3A9IjNwdCIKLSAgICAgICAgICAgID4KLSAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0aXRsZSIvPgotICAgPC9mbzpibG9jaz4KLSAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+IAotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gczMgLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoID0iczMiPgotICAgPGZvOmJsb2NrIGZvbnQtc2l6ZT0iMTRwdCIgCi0gICAgICAgICAgICBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgCi0gICAgICAgICAgICBsaW5lLWhlaWdodD0iMThwdCIKLSAgICAgICAgICAgIGtlZXAtd2l0aC1uZXh0LndpdGhpbi1wYWdlPSJhbHdheXMiCi0gICAgICAgICAgICBzcGFjZS1iZWZvcmUub3B0aW11bT0iMTBwdCIKLSAgICAgICAgICAgIHNwYWNlLWFmdGVyLm9wdGltdW09IjlwdCIKLSAgICAgICAgICAgIHRleHQtYWxpZ249InN0YXJ0IgotICAgICAgICAgICAgcGFkZGluZy10b3A9IjNwdCI+Ci0gICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAdGl0bGUiLz4KLSAgIDwvZm86YmxvY2s+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIHAgIFtub3QoY29kZSldIC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaCA9InAiPiAKLSAgIDxmbzpibG9jayBmb250LXNpemU9IjExcHQiIAotICAgICAgICAgICAgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIAotICAgICAgICAgICAgbGluZS1oZWlnaHQ9IjEzcHQiCi0gICAgICAgICAgICBzcGFjZS1hZnRlci5vcHRpbXVtPSIzcHQiCi0gICAgICAgICAgICBzcGFjZS1iZWZvcmUub3B0aW11bT0iM3B0IgotICAgICAgICAgICAgdGV4dC1hbGlnbj0ic3RhcnQiPgotICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+IAotICAgPC9mbzpibG9jaz4KLTwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoID0ibm90ZSI+IAotICAgPGZvOmJsb2NrIGZvbnQtc2l6ZT0iMTFwdCIgCi0gICAgICAgICAgICBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgCi0gICAgICAgICAgICBmb250LXdlaWdodD0iaXRhbGljIgotICAgICAgICAgICAgbGluZS1oZWlnaHQ9IjEzcHQiCi0gICAgICAgICAgICBzcGFjZS1hZnRlci5vcHRpbXVtPSIzcHQiCi0gICAgICAgICAgICBzcGFjZS1iZWZvcmUub3B0aW11bT0iM3B0IgotICAgICAgICAgICAgdGV4dC1hbGlnbj0ic3RhcnQiPgotICAgICAgICBOb3RlOiAgICAgCi0gICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4gCi0gICA8L2ZvOmJsb2NrPgotPC94c2w6dGVtcGxhdGU+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9ImFuY2hvciI+Ci0gIDxmbzpibG9jaz4gPCEtLWlkPSJjb25jYXQobG9jYWwtbmFtZShhbmNlc3Rvcjo6bm9kZSgpPSJjaGFwdGVyIi9AaWQuLCdfJyx7Li9AbmFtZX0iLy0tPgotICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9ImlkIj4KLSAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJjb25jYXQoYW5jZXN0b3I6OmNoYXB0ZXIvQGlkLCdfJywuL0BuYW1lKSIvPgotICAgIDwveHNsOmF0dHJpYnV0ZT4KLSAgPC9mbzpibG9jaz4gICAgCi08L3hzbDp0ZW1wbGF0ZT4KLQotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0idGFibGUiPgotICA8eHNsOnZhcmlhYmxlIG5hbWU9ImNvbHdpZHRoIiBzZWxlY3Q9IjE0LjUgZGl2IGNvdW50KHRyWzFdL3RkKSIvPgotICA8Zm86dGFibGU+Ci0gIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJ0clsxXS90ZCI+Ci0gICAgPGZvOnRhYmxlLWNvbHVtbiBjb2x1bW4td2lkdGg9InskY29sd2lkdGh9Y20iLz4KLSAgPC94c2w6Zm9yLWVhY2g+Ci0gIDxmbzp0YWJsZS1ib2R5IGZvbnQtc2l6ZT0iMTBwdCIgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiPgotICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwvZm86dGFibGUtYm9keT4KLSAgPC9mbzp0YWJsZT4gIAotPC94c2w6dGVtcGxhdGU+ICAKLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InRyIj4KLSAgPGZvOnRhYmxlLXJvdz4KLSAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+Ci0gIDwvZm86dGFibGUtcm93PgotPC94c2w6dGVtcGxhdGU+Ci08eHNsOnRlbXBsYXRlIG1hdGNoPSJ0ZCI+Ci0gIDxmbzp0YWJsZS1jZWxsPgotICAgIDxmbzpibG9jaz4KLSAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICA8L2ZvOmJsb2NrPgotICAgPC9mbzp0YWJsZS1jZWxsPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gcCArIGNvZGUgCi08eHNsOnRlbXBsYXRlIG1hdGNoID0icFtjb2RlXSI+Ci0gICA8Zm86YmxvY2sgZm9udC1zaXplPSIxMXB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiAKLSAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIxMXB0IgotICAgICAgICAgICAgc3BhY2UtYWZ0ZXIub3B0aW11bT0iMHB0IgotICAgICAgICAgICAgc3BhY2UtYmVmb3JlLm9wdGltdW09IjBwdCIKLSAgICAgICAgICAgIHRleHQtYWxpZ249InN0YXJ0Ij4KLSAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgIDwvZm86YmxvY2s+Ci08L3hzbDp0ZW1wbGF0ZT4KLS0tPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJpbWciPgotICA8Zm86YmxvY2s+Ci0gICAgPGZvOmV4dGVybmFsLWdyYXBoaWMgc3JjPSJmaWxlOmJ1aWxkL2RvY3MvaW1hZ2VzL3tAc3JjfSIvPgotICA8L2ZvOmJsb2NrPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gZmFxcyAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2ggPSJmYXFzIj4KLSAgIDxmbzpibG9jayBmb250LXNpemU9IjE4cHQiIAotICAgICAgICAgICAgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIAotICAgICAgICAgICAgbGluZS1oZWlnaHQ9IjI0cHQiCi0gICAgICAgICAgICBzcGFjZS1iZWZvcmUub3B0aW11bT0iMTVwdCIKLSAgICAgICAgICAgIHNwYWNlLWFmdGVyLm9wdGltdW09IjE1cHQiCi0gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yPSJibHVlIgotICAgICAgICAgICAgY29sb3I9IndoaXRlIgotICAgICAgICAgICAgdGV4dC1hbGlnbj0iY2VudGVyIgotICAgICAgICAgICAgPgotICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJpZCI+Ci0gICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJ0cmFuc2xhdGUoLiwnICksLS4oJywnX19fXycpIi8+Ci0gICAgIDwveHNsOmF0dHJpYnV0ZT4KLSAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IkB0aXRsZSIvPgotICAgPC9mbzpibG9jaz4KLSAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+IAotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gZmFxIC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaCA9ImZhcSI+Ci0gICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIHEgaW4gZmFxIC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaD0icSI+Ci0gICA8Zm86YmxvY2sgZm9udC1zaXplPSIxNHB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiAKLSAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIxOHB0IgotICAgICAgICAgICAga2VlcC13aXRoLW5leHQud2l0aGluLXBhZ2U9ImFsd2F5cyIKLSAgICAgICAgICAgIHNwYWNlLWJlZm9yZS5vcHRpbXVtPSIxMHB0IgotICAgICAgICAgICAgc3BhY2UtYWZ0ZXIub3B0aW11bT0iOXB0IgotICAgICAgICAgICAgdGV4dC1hbGlnbj0ic3RhcnQiCi0gICAgICAgICAgICBwYWRkaW5nLXRvcD0iM3B0Ij4gICAgIAotICAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgICA8L2ZvOmJsb2NrPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gYSBpbiBmYXEgLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoID0iYSI+Ci0gICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+IAotPC94c2w6dGVtcGxhdGU+Ci0KLQotPCEtLSBqdW1wIChsaW5rcykgLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoID0ianVtcCI+Ci0gIDxmbzpiYXNpYy1saW5rIGNvbG9yPSJibHVlIj4KLSAgICAgPHhzbDphdHRyaWJ1dGUgbmFtZT0iZXh0ZXJuYWwtZGVzdGluYXRpb24iPgotICAgICAgIDx4c2w6aWYgdGVzdD0ic3RhcnRzLXdpdGgoQGhyZWYsJ2FwaWRvY3MnKSI+Ci0gICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iY29uY2F0KCdodHRwOi8veG1sLmFwYWNoZS5vcmcveGFsYW4tai8nLEBocmVmKSIvPgotICAgICAgIDwveHNsOmlmPgotICAgICAgIDx4c2w6aWYgdGVzdD0ibm90KHN0YXJ0cy13aXRoKEBocmVmLCdhcGlkb2NzJykpIj4KLSAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJAaHJlZiIvPgotICAgICAgIDwveHNsOmlmPiAgICAKLSAgICAgPC94c2w6YXR0cmlidXRlPiAgCi0gICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLi90ZXh0KCkiLz4KLSAgICAgPCEtLXhzbDphcHBseS10ZW1wbGF0ZXMvLS0+IAotICAgPC9mbzpiYXNpYy1saW5rPgotPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0ibGluayI+Ci0gICAgPHhzbDppZiB0ZXN0PSJzdHJpbmctbGVuZ3RoKEBhbmNob3IpPTAiPgotICAgICAgPHhzbDppZiB0ZXN0PSJzdHJpbmctbGVuZ3RoKEBpZHJlZik9MCI+Ci0gICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgIDwveHNsOmlmPgotICAgICAgPHhzbDppZiB0ZXN0PSJzdHJpbmctbGVuZ3RoKEBpZHJlZik+MCI+Ci0gICAgICAgIDxmbzpiYXNpYy1saW5rIGNvbG9yPSJibHVlIiBpbnRlcm5hbC1kZXN0aW5hdGlvbj0ie0BpZHJlZn0iPgotICAgICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLi90ZXh0KCkiLz48L2ZvOmJhc2ljLWxpbms+Ci0gICAgICA8L3hzbDppZj4KLSAgICA8L3hzbDppZj4KLQotICAgIDx4c2w6aWYgdGVzdD0ic3RyaW5nLWxlbmd0aChAYW5jaG9yKT4wIj4KLSAgICAgIDx4c2w6aWYgdGVzdD0ic3RyaW5nLWxlbmd0aChAaWRyZWYpPTAiPgotICAgICAgICA8Zm86YmFzaWMtbGluayBjb2xvcj0iYmx1ZSIKLSAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbC1kZXN0aW5hdGlvbj0ie2NvbmNhdChhbmNlc3Rvcjo6Y2hhcHRlci9AaWQsJ18nLEBhbmNob3IpfSI+Ci0gICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSIuL3RleHQoKSIvPjwvZm86YmFzaWMtbGluaz4KLSAgICAgIDwveHNsOmlmPgotICAgICAgPHhzbDppZiB0ZXN0PSJzdHJpbmctbGVuZ3RoKEBpZHJlZik+MCI+Ci0gICAgICAgIDxmbzpiYXNpYy1saW5rIGNvbG9yPSJibHVlIiBpbnRlcm5hbC1kZXN0aW5hdGlvbj0ie0BpZHJlZn1fe0BhbmNob3J9Ij4KLSAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9Ii4vdGV4dCgpIi8+PC9mbzpiYXNpYy1saW5rPgotICAgICAgPC94c2w6aWY+Ci0gICAgPC94c2w6aWY+Ci0gIDwveHNsOnRlbXBsYXRlPgotCi0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9InJlc291cmNlLXJlZiI+Ci0gIDx4c2w6dmFyaWFibGUgbmFtZT0ieHJlZiIgc2VsZWN0PSJAaWRyZWYiLz4KLSAgPHhzbDp2YXJpYWJsZSBuYW1lPSJocmVmIgotICAgICAgICAgIHNlbGVjdD0iZG9jdW1lbnQoJHJlc291cmNlRmlsZSkvcmVzb3VyY2VzL3Jlc291cmNlW0BpZD0keHJlZl0vQGxvY2F0aW9uIi8+Ci0gIDx4c2w6dmFyaWFibGUgbmFtZT0ibGFiZWwiCi0gICAgICAgICAgc2VsZWN0PSJkb2N1bWVudCgkcmVzb3VyY2VGaWxlKS9yZXNvdXJjZXMvcmVzb3VyY2VbQGlkPSR4cmVmXS9AdGl0bGUiLz4KLSAgPGZvOmJhc2ljLWxpbmsgY29sb3I9ImJsdWUiPgotICAgICA8eHNsOmF0dHJpYnV0ZSBuYW1lPSJleHRlcm5hbC1kZXN0aW5hdGlvbiI+Ci0gICAgICAgPHhzbDppZiB0ZXN0PSJzdGFydHMtd2l0aCgkaHJlZiwnYXBpZG9jcycpIj4KLSAgICAgICAgIDx4c2w6dmFsdWUtb2Ygc2VsZWN0PSJjb25jYXQoJ2h0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi1qLycsJGhyZWYpIi8+Ci0gICAgICAgPC94c2w6aWY+Ci0gICAgICAgPHhzbDppZiB0ZXN0PSJub3Qoc3RhcnRzLXdpdGgoJGhyZWYsJ2FwaWRvY3MnKSkiPgotICAgICAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IiRocmVmIi8+Ci0gICAgICAgPC94c2w6aWY+ICAgIAotICAgICA8L3hzbDphdHRyaWJ1dGU+ICAKLSAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IiRsYWJlbCIvPgotICAgICA8IS0teHNsOmFwcGx5LXRlbXBsYXRlcy8tLT4gCi0gICA8L2ZvOmJhc2ljLWxpbms+ICAgICAgICAKLSAgPC94c2w6dGVtcGxhdGU+Ci0KLSAgPHhzbDp0ZW1wbGF0ZSBtYXRjaD0iaHVtYW4tcmVzb3VyY2UtcmVmIj4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9InJlc291cmNlRmlsZSIgCi0gICAgICAgICAgc2VsZWN0PSIuL3hhbGFuL3Jlc291cmNlcy54bWwiLz4gIAotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0icmVmIiAgc2VsZWN0PSJAaWRyZWYiLz4KLSAgICA8eHNsOnZhcmlhYmxlIG5hbWU9Im1haWx0byIKLSAgICAgICAgICBzZWxlY3Q9ImRvY3VtZW50KCRyZXNvdXJjZUZpbGUpL3Jlc291cmNlcy9odW1hbi1yZXNvdXJjZVtAaWQ9JHJlZl0vQG1haWx0byIvPgotICAgIDx4c2w6dmFyaWFibGUgbmFtZT0ibmFtZSIKLSAgICAgICAgICBzZWxlY3Q9ImRvY3VtZW50KCRyZXNvdXJjZUZpbGUpL3Jlc291cmNlcy9odW1hbi1yZXNvdXJjZVtAaWQ9JHJlZl0vQG5hbWUiLz4KLSAgPGZvOmJhc2ljLWxpbmsgY29sb3I9ImJsdWUiIGV4dGVybmFsLWRlc3RpbmF0aW9uPSJtYWlsdG86eyRtYWlsdG99Ij4KLSAgICAgPHhzbDp2YWx1ZS1vZiBzZWxlY3Q9IiRuYW1lIi8+Ci0gICAgIDwhLS14c2w6YXBwbHktdGVtcGxhdGVzLy0tPiAKLSAgIDwvZm86YmFzaWMtbGluaz4gICAgICAgICAgCi0gIDwveHNsOnRlbXBsYXRlPgotCi08eHNsOnRlbXBsYXRlIG1hdGNoID0ic291cmNlIj4gCi0gICA8Zm86YmxvY2sgZm9udC1zaXplPSIxMHB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJDb3VyaWVyIiAKLSAgICAgICAgICAgIHRleHQtYWxpZ249InN0YXJ0IgotICAgICAgICAgICAgd2hpdGUtc3BhY2UtY29sbGFwc2U9ImZhbHNlIj4KLSAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgIDwvZm86YmxvY2s+Ci0KLTwveHNsOnRlbXBsYXRlPgotICA8eHNsOnRlbXBsYXRlIG1hdGNoID0iYnIiPgotICA8Zm86YmxvY2s+PC9mbzpibG9jaz4KLTwveHNsOnRlbXBsYXRlPgotCi08IS0tIGNvZGUgLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoID0iKi9jb2RlIj4KLSAgIDxmbzppbmxpbmUgZm9udC1zaXplPSIxMHB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJDb3VyaWVyIj4KLSAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgIDwvZm86aW5saW5lPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gdWwgKHVub3JkZXJlZCBsaXN0KSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2ggPSJ1bCI+Ci0gIDxmbzpsaXN0LWJsb2NrIHN0YXJ0LWluZGVudD0iMWNtIiAKLSAgICAgICAgICAgICAgICAgcHJvdmlzaW9uYWwtZGlzdGFuY2UtYmV0d2Vlbi1zdGFydHM9IjEycHQiIAotICAgICAgICAgICAgICAgICBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgCi0gICAgICAgICAgICAgICAgIGZvbnQtc2l6ZT0iMTFwdCIgCi0gICAgICAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIxMXB0Ij4KLSAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgIDwvZm86bGlzdC1ibG9jaz4KLTwveHNsOnRlbXBsYXRlPiAgICAgICAgIAotICAgICAgICAgIAotPCEtLSBvbCAob3JkZXJlZCBsaXN0KSAtLT4KLTx4c2w6dGVtcGxhdGUgbWF0Y2ggPSJvbCI+Ci0gIDxmbzpsaXN0LWJsb2NrIHN0YXJ0LWluZGVudD0iMWNtIiAKLSAgICAgICAgICAgICAgICAgcHJvdmlzaW9uYWwtZGlzdGFuY2UtYmV0d2Vlbi1zdGFydHM9IjEycHQiIAotICAgICAgICAgICAgICAgICBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgCi0gICAgICAgICAgICAgICAgIGZvbnQtc2l6ZT0iMTFwdCIgCi0gICAgICAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIxMXB0Ij4KLSAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgIDwvZm86bGlzdC1ibG9jaz4KLTwveHNsOnRlbXBsYXRlPgotCi0KLTwhLS0gbGkgKGxpc3QgaXRlbSkgaW4gdW5vcmRlcmVkIGxpc3QgLS0+Ci08eHNsOnRlbXBsYXRlIG1hdGNoID0idWwvbGkiPgotICAgIDxmbzpsaXN0LWl0ZW0+Ci0gICAgICA8Zm86bGlzdC1pdGVtLWxhYmVsPgotICAgICAgICA8Zm86YmxvY2s+PGZvOmlubGluZSBmb250LWZhbWlseT0iU3ltYm9sIj4mIzE4Mzs8L2ZvOmlubGluZT48L2ZvOmJsb2NrPgotICAgICAgPC9mbzpsaXN0LWl0ZW0tbGFiZWw+Ci0gICAgICA8Zm86bGlzdC1pdGVtLWJvZHk+Ci0gICAgICAgIDxmbzpibG9jayBzcGFjZS1hZnRlci5vcHRpbXVtPSI0cHQiCi0gICAgICAgICAgICAgIHRleHQtYWxpZ249InN0YXJ0IgotICAgICAgICAgICAgICBwYWRkaW5nLXRvcD0iM3B0Ij4KLSAgICAgICAgICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+IAotICAgICAgIDwvZm86YmxvY2s+Ci0gICAgICA8L2ZvOmxpc3QtaXRlbS1ib2R5PgotICAgIDwvZm86bGlzdC1pdGVtPgotPC94c2w6dGVtcGxhdGU+Ci0KLTwhLS0gbGkgKGxpc3QgaXRlbSkgaW4gb3JkZXJlZCBsaXN0IC0tPgotPHhzbDp0ZW1wbGF0ZSBtYXRjaCA9Im9sL2xpIj4KLSAgICA8Zm86bGlzdC1pdGVtPgotICAgICAgPGZvOmxpc3QtaXRlbS1sYWJlbD4KLSAgICAgICAgPGZvOmJsb2NrPgotICAgICAgICAgIDx4c2w6bnVtYmVyIGxldmVsPSJtdWx0aXBsZSIgY291bnQ9ImxpIiBmb3JtYXQ9IjEiLz4pCi0gICAgICAgIDwvZm86YmxvY2s+Ci0gICAgICA8L2ZvOmxpc3QtaXRlbS1sYWJlbD4KLSAgICAgIDxmbzpsaXN0LWl0ZW0tYm9keT4KLSAgICAgICAgPGZvOmJsb2NrIHNwYWNlLWFmdGVyLm9wdGltdW09IjRwdCIKLSAgICAgICAgICAgICAgdGV4dC1hbGlnbj0ic3RhcnQiCi0gICAgICAgICAgICAgIHBhZGRpbmctdG9wPSIzcHQiPgotICAgICAgICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4gCi0gICAgICAgPC9mbzpibG9jaz4KLSAgICAgIDwvZm86bGlzdC1pdGVtLWJvZHk+Ci0gICAgPC9mbzpsaXN0LWl0ZW0+Ci08L3hzbDp0ZW1wbGF0ZT4KLQotPCEtLSB0ZW1wb3Jhcnkga2x1ZGdlIGZvciBkZWZpbml0aW9uIGxpc3QgZ2xvc3Mgd2l0aCBsYWJlbC1pdGVtIHBhaXJzICkgLS0+Ci0KLTx4c2w6dGVtcGxhdGUgbWF0Y2g9Imdsb3NzIj4KLSAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPgotPC94c2w6dGVtcGxhdGU+Ci08eHNsOnRlbXBsYXRlIG1hdGNoPSJsYWJlbCI+Ci0gICA8Zm86YmxvY2sgZm9udC1zaXplPSIxMXB0IiAKLSAgICAgICAgICAgIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiAKLSAgICAgICAgICAgIGxpbmUtaGVpZ2h0PSIxM3B0IgotICAgICAgICAgICAgc3BhY2UtYWZ0ZXIub3B0aW11bT0iM3B0IgotICAgICAgICAgICAgc3BhY2UtYmVmb3JlLm9wdGltdW09IjZwdCIKLSAgICAgICAgICAgIHRleHQtYWxpZ249InN0YXJ0Ij4KLSAgICAgPHhzbDphcHBseS10ZW1wbGF0ZXMvPiAKLSAgIDwvZm86YmxvY2s+Ci08L3hzbDp0ZW1wbGF0ZT4gCi08eHNsOnRlbXBsYXRlIG1hdGNoPSJpdGVtIj4KLSAgIDxmbzpibG9jayBmb250LXNpemU9IjExcHQiIAotICAgICAgICAgICAgZm9udC1mYW1pbHk9InNhbnMtc2VyaWYiIAotICAgICAgICAgICAgbGluZS1oZWlnaHQ9IjEzcHQiCi0gICAgICAgICAgICBzcGFjZS1hZnRlci5vcHRpbXVtPSI2cHQiCi0gICAgICAgICAgICBzcGFjZS1iZWZvcmUub3B0aW11bT0iMHB0IgotICAgICAgICAgICAgbWFyZ2luLWxlZnQ9IjI0cHQiCi0gICAgICAgICAgICB0ZXh0LWFsaWduPSJzdGFydCI+Ci0gICAgIDx4c2w6YXBwbHktdGVtcGxhdGVzLz4KLSAgICAgPGZvOmJsb2NrPjwvZm86YmxvY2s+IAotICAgPC9mbzpibG9jaz4KLTwveHNsOnRlbXBsYXRlPiAKLQotPCEtLSBlbmQgYm9keSAtLT4KLQotPC94c2w6c3R5bGVzaGVldD4KZGlmZiAtLWdpdCBhL3hkb2NzL3htbC1zaXRlLXN0eWxlLnRhci5neiBiL3hkb2NzL3htbC1zaXRlLXN0eWxlLnRhci5negpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjQ3N2E4NC4uMDAwMDAwMAotLS0gYS94ZG9jcy94bWwtc2l0ZS1zdHlsZS50YXIuZ3oKKysrIC9kZXYvbnVsbApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS94c2x0Y190b2RvLnhtbCBiL3hzbHRjX3RvZG8ueG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3NDQ4ZjkzLi4wMDAwMDAwCi0tLSBhL3hzbHRjX3RvZG8ueG1sCisrKyAvZGV2L251bGwKQEAgLTEsMTc2ICswLDAgQEAKLTw/eG1sIHZlcnNpb249IjEuMCI/PgotCi08dG9kbyB0aXRsZT0iVGhpbmdzIFRvIERvIiBwcm9qZWN0PSJYU0xUQyIgbWFqb3ItdmVyc2lvbj0iMSI+Ci0KLSAgPGRldnM+Ci0gICA8cGVyc29uIG5hbWU9IkphY2VrIEFtYnJvemlhayIgZW1haWw9ImphY2VrX2FtYnJvemlha0B5YWhvby5jb20iIGlkPSJKQSIgZXhwZXJ0aXNlPSJjb2RlIj4KLSAgICAgSW52ZW50b3IsIGFyY2hpdGVjdCwgZm9ybWVyIGxlYWQgZGV2ZWxvcGVyIGFuZCBldmFuZ2VsaXN0LgotICAgPC9wZXJzb24+ICAKLSAgIDxwZXJzb24gbmFtZT0iVG9tIEFtaXJvIiBlbWFpbD0iVG9tLkFtaXJvQFN1bi5DT00iIGlkPSJUQSIgZXhwZXJ0aXNlPSJ0ZXN0aW5nIj4KLSAgICAgVGVzdGluZy4KLSAgIDwvcGVyc29uPiAgCi0gICA8cGVyc29uIG5hbWU9Ik1vcnRlbiBKJiMyMTY7cmdlbnNlbiIgZW1haWw9Im1vcnRlbkB4bWwuYXBhY2hlLm9yZyIgaWQ9Ik1KIiBleHBlcnRpc2U9ImNvZGUsIGRvYyI+Ci0gICAgIExlYWQgZGV2ZWxvcGVyIC0ga2V5IGNvbnRyaWJ1dG9yIG9uIGRlc2lnbiBkb2N1bWVudGF0aW9uLCBJRC9LZXlzLCBwZXJmb3JtYW5jZSwgSkFYUCwgYW5kIGNvbnRpbnVpbmcgZGV2ZWxvcG1lbnQgaW4gZ2VuZXJhbC4KLSAgIDwvcGVyc29uPgotICAgPHBlcnNvbiBuYW1lPSJHLiBUb2RkIE1pbGxlciIgZW1haWw9IkdsZW5uLk1pbGxlckBTdW4uQ09NIiBpZD0iVE0iIGV4cGVydGlzZT0iY29kZSI+Ci0gICAgIERldmVsb3BlciAtIGtleSBjb250cmlidXRvciBvbiBUckFYLgotICAgPC9wZXJzb24+Ci0gICA8cGVyc29uIG5hbWU9IlNhbnRpYWdvIFBlcmljYXMtR2VlcnRzZW4iIGVtYWlsPSJzYW50aWFnb0Bjcy5idS5lZHUiIGlkPSJTUCIgZXhwZXJ0aXNlPSJjb2RlIj4KLSAgICAgRGV2ZWxvcGVyIC0ga2V5IGNvbnRyaWJ1dG9yIG9uIGNvbXBpbGF0aW9uIHN0cmF0ZWd5LgotICAgPC9wZXJzb24+Ci0gIDwvZGV2cz4KLSAKLSAgPGFjdGlvbnM+Ci0KLSAgIDx0YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbj4KLSAgICA8ZGF0ZT4wOS8/Py8wMTwvZGF0ZT4KLSAgICA8bGV2ZWw+Pz8/PzwvbGV2ZWw+Ci0gICAgPGdvYWwgdHlwZT0iY29uZm9ybWFuY2UiPlhTTFQgMS4wIGNvbXBsaWFudCAxMDAlLjwvZ29hbD4KLSAgICA8Z29hbCB0eXBlPSJwZXJmb3JtYW5jZSI+TWFpbnRhaW4gY3VycmVudCBsZXZlbC48L2dvYWw+Ci0gICAgPGdvYWwgdHlwZT0ic3RhYmlsaXR5Ij4gU3RhYmxlLCByZWFzb25hYmxlLjwvZ29hbD4KLSAgICA8Z29hbCB0eXBlPSJhcGkiPkFQSSBDb21wbGV0ZS48L2dvYWw+Ci0gICAgPGdvYWwgdHlwZT0iZG9jdW1lbnRhdGlvbiI+RG9jdW1lbnRhdGlvbiBmdW5jdGlvbmFsbHkgY29tcGxldGUuPC9nb2FsPgotICAgPC90YXJnZXQtcmVsZWFzZS1kZXNjcmlwdGlvbj4KLSAgIAotICA8YWN0aW9uIGNvbnRleHQ9InRlc3QsIHBhY2thZ2VzOm9yZy5hcGFjaGUueGFsYW4ueHNsdGMiCi0gICAgICAgICAgY2F0ZWdvcnk9InRlc3RzIgotICAgICAgICAgIHdobz0iVEEsIFNoYW5lIgotICAgICAgICAgIHByaW9yaXR5PSJoaWdoIj4KLSAgICAgTW9kaWZ5IFhhbGFuIHRlc3QgZW52aXJvbWVudCB0byB0ZXN0IFhTTFRDIGFzIGEgY29tcG9uZW50IG9mIFhhbGFuSjIuCi0gICA8L2FjdGlvbj4gICAgICAgCi0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlLCBwYWNrYWdlczpvcmcuYXBhY2hlLnhhbGFuLnhzbHRjIgotICAgICAgICAgIGNhdGVnb3J5PSJmZWF0dXJlIgotICAgICAgICAgIHdobz0iTUoiCi0gICAgICAgICAgcHJpb3JpdHk9ImhpZ2giPgotICAgICAgIEZpbmlzaCB0aGUgaW1wbGVtZW50YXRpb24gb2YgaWQoKSBhbmQga2V5KCkgaW4gcGF0dGVybnMuICAgCi0gICA8L2FjdGlvbj4gICAgICAgCi0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlLCBwYWNrYWdlczpvcmcuYXBhY2hlLnhhbGFuLnhzbHRjIgotICAgICAgICAgIGNhdGVnb3J5PSJidWciCi0gICAgICAgICAgd2hvPSI/PyIKLSAgICAgICAgICBwcmlvcml0eT0iaGlnaCI+Ci0gICAgICBDb250aW51ZSB0byBpbXByb3ZlIHRoZSBoYW5kbGluZyBvZiBuYW1lIHNwYWNlcy4gVGhlcmUgYXJlIGEgbnVtYmVyIG9mCi0gICAgICBidWdzIHRoYXQgYXJlIGluZGVwZW5kZW50IG9mIHRoZSBsYWNrIG9mIG5hbWVzcGFjZSBub2Rlcy4gIAotICAgICAoYnVnemlsbGEgMTQxMSwgMTUwNiwgMTUxOCwgMjU4MiwgMjgwMSwgMjg1NywgMjg1OSwgMjg2MywgMjUzNSwgMjk1NCwgMjg0MCkgICAgCi0gICA8L2FjdGlvbj4gICAgICAgCi0KLSAgPGFjdGlvbiBjb250ZXh0PSJjb2RlLCBwYWNrYWdlczpvcmcuYXBhY2hlLnhhbGFuLnhzbHRjIgotICAgICAgICAgIGNhdGVnb3J5PSJidWciCi0gICAgICAgICAgd2hvPSI/PyIKLSAgICAgICAgICBwcmlvcml0eT0iaGlnaCI+Ci0gICAgRml4IGJ1Z3MgdGhhdCBpbXBhY3QgdGhlIFhTTFRNYXJrIHBlcmZvcm1hbmNlIGJlbmNobWFyay4KLSAgICAoYnVnemlsbGEgMTM3NiwgMTQ5OCwgMTUxMiwgMTUzMiwgMjM1MSwgMjUxNywgMjU1MywgMzA2NSwgMzA2NikuICAgICAgICAgIAotICAgPC9hY3Rpb24+Ci0gICAgICAgIAotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSwgcGFja2FnZXM6b3JnLmFwYWNoZS54YWxhbi54c2x0YyIKLSAgICAgICAgICBjYXRlZ29yeT0iYnVncyIKLSAgICAgICAgICB3aG89IlRNIgotICAgICAgICAgIHByaW9yaXR5PSJoaWdoIj4KLSAgICAgICBGaXggYnVncyByZWZsZWN0aW5nIHBvc2l0aW9uYWwgcHJvYmxlbXMgKDE0MTAsIDE1MzIsIDI5MzkpLiAgICAgICAgICAKLSAgIDwvYWN0aW9uPgotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSwgcGFja2FnZXM6b3JnLmFwYWNoZS54YWxhbi54c2x0YyIKLSAgICAgICAgICBjYXRlZ29yeT0iYnVnIgotICAgICAgICAgIHdobz0iVE0iCi0gICAgICAgICAgcHJpb3JpdHk9ImhpZ2giPgotICAgICAgRml4IGJ1Z3Mgb24gZGVhbGluZyB3aXRoIFhQQVRIL0F4ZXMgZXhwcmVzc2lvbnMgKDE0OTgsIDI1NTEsIDI1NTMsIDI1NzIsIDI5MzIpLiAgICAgICAgICAKLSAgIDwvYWN0aW9uPiAgICAgICAKLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUsIHBhY2thZ2VzOm9yZy5hcGFjaGUueGFsYW4ueHNsdGMiCi0gICAgICAgICAgY2F0ZWdvcnk9ImJ1ZyIKLSAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgIHByaW9yaXR5PSJtZWRpdW0iPgotICAgICAgRml4IGJ1Z3MgaW52b2x2aW5nIHRlbXBsYXRlIHNlbGVjdGlvbiAoMTM5NywgMjc0OSwgMjU4MiwgMjU4NSwgMjY5NSwgMjc0OSwgMjc1NCwgMjg4NiwgMjkzNykuCi0gICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUsIHBhY2thZ2VzOm9yZy5hcGFjaGUueGFsYW4ueHNsdGMiCi0gICAgICAgICAgY2F0ZWdvcnk9ImJ1ZyIKLSAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgIHByaW9yaXR5PSJtZWRpdW0iPgotICAgICAgRml4IGJ1Z3MgYWZmZWN0aW5nIG51bWJlcmluZyAoMjkwMSwgMjkzMSkuCi0gICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUsIHBhY2thZ2VzOm9yZy5hcGFjaGUueGFsYW4ueHNsdGMiCi0gICAgICAgICAgY2F0ZWdvcnk9ImJ1ZyIKLSAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgIHByaW9yaXR5PSJtZWRpdW0iPgotICAgICAgRml4IGJ1Z3MgYWZmZWN0aW5nIGNvbW1lbnQgYW5kIHByb2Nlc3NpbmctaW50cnVjdGlvbiBub2RlcyAoMjU5OSwgMjgzNCwgMjg1OCkuCi0gICA8L2FjdGlvbj4KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUsIHBhY2thZ2VzOm9yZy5hcGFjaGUueGFsYW4ueHNsdGMiCi0gICAgICAgICAgY2F0ZWdvcnk9ImZlYXR1cmUiCi0gICAgICAgICAgd2hvPSJNSiIKLSAgICAgICAgICBwcmlvcml0eT0ibG93Ij4KLSAgICAgSW1wbGVtZW50IG5hbWUgc3BhY2Ugbm9kZXMgKGJ1Z3ppbGxhIDEzNzkpLgotICAgPC9hY3Rpb24+ICAgICAgIAotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSwgcGFja2FnZXM6Pz8/PyIKLSAgICAgICAgICBjYXRlZ29yeT0iZmVhdHVyZSwgaW50ZWdyYXRpb24gd2l0aCBYYWxhbiIKLSAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgIHByaW9yaXR5PSJtZWRpdW0iPgotICAgICAgSW1wbGVtZW50IGFuIGV4dGVuc2lvbiB0byBzdXBwb3J0IHRoZSByZWRpcmVjdGlvbiBvZiBvdXRwdXQgdG8gbXVsdGlwbGUKLSAgICAgIG91dHB1dCBmaWxlcyBmcm9tIHdpdGhpbiBhIHN0eWxlc2hlZXQgKGVxdWl2YWxlbnQgdG8geGFsYW46cmVkaXJlY3Qgb3IKLSAgICAgIHNheG9uOm91dHB1dCkuICBOb3RlOiBUYXNrIG1heSBiZSBpbXBsZW1lbnRlZCBhcyBhIHJlc3VsdCBvZiBpbnRlZ3JhdGluZyBYc2x0YyBhbmQgWGFsYW4gCi0gICAgIGFuZCB1c2luZyBzaGFyZWQgY29kZS4KLSAgIDwvYWN0aW9uPiAgICAgICAKLQotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSwgcGFja2FnZXM6Pz8/PyIKLSAgICAgICAgICBjYXRlZ29yeT0iZmVhdHVyZSwgaW50ZWdyYXRpb24gd2l0aCBYYWxhbiIKLSAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgIHByaW9yaXR5PSJtZWRpdW0iPgotICAgICBJbXBsZW1lbnQgYSBub2RlLXNldCBleHRlbnNpb24gdG8gY29udmVydCByZXN1bHQgdHJlZSBmcmFnbWVudHMgdG8KLSAgICAgbm9kZS1zZXRzLiBUaGlzIGVuYWJsZXMgc29ydGluZyBhbmQgZ3JvdXBpbmcgb2Ygbm9kZXMgYXNzaWduZWQgdG8gYSB0cmVlIAotICAgICB2YXJpYWJsZS4gTm90ZTogVGFzayBtYXkgYmUgaW1wbGVtZW50ZWQgYXMgYSByZXN1bHQgb2YgaW50ZWdyYXRpbmcgWHNsdGMgYW5kIFhhbGFuIAotICAgICBhbmQgdXNpbmcgc2hhcmVkIGNvZGUuCi0gICA8L2FjdGlvbj4gICAgICAgCi0KLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUsIHBhY2thZ2VzOj8/Pz8iCi0gICAgICAgICAgY2F0ZWdvcnk9ImZlYXR1cmUsIGludGVncmF0aW9uIHdpdGggWGFsYW4iCi0gICAgICAgICAgd2hvPSI/PyIKLSAgICAgICAgICBwcmlvcml0eT0ibWVkaXVtIj4KLSAgICAgIEFkZCBzdXBwb3J0IGZvciBub25zdGF0aWMgZXh0ZXJuYWwgSmF2YSBmdW5jdGlvbnMuICAKLSAgICAgIE5vdGU6IFRhc2sgbWF5IGJlIGltcGxlbWVudGVkIGFzIGEgcmVzdWx0IG9mIGludGVncmF0aW5nIFhzbHRjIGFuZCBYYWxhbiAKLSAgICAgIGFuZCB1c2luZyBzaGFyZWQgY29kZS4KLSAgIDwvYWN0aW9uPiAgICAgICAKLQotCi0gIDxhY3Rpb24gY29udGV4dD0iY29kZSwgcGFja2FnZXM6Pz8/PyIKLSAgICAgICAgICBjYXRlZ29yeT0iZmVhdHVyZSwgaW50ZWdyYXRpb24gd2l0aCBYYWxhbiIKLSAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgIHByaW9yaXR5PSJtZWRpdW0iPgotICAgIEZpeCBidWdzIGFmZmVjdGluZyB0aGUgY29ycmVjdG5lc3Mgb2Ygb3VwdXQgCi0gICAgKDE0MzksIDE1MDQsIDE1MTIsIDE1MTYsIDE1MjAsIDE1MjUsIDI1MTcsIDI1MjAsIDI1NzgsIDI5NDgsIDI5NTEsIDI5NTIsIDI5NTQsIDMwMDUsIDMwNjUpLgotICAgICBOb3RlOiBUYXNrIG1heSBiZSBpbXBsZW1lbnRlZCBhcyBhIHJlc3VsdCBvZiBpbnRlZ3JhdGluZyBYc2x0YyBhbmQgWGFsYW4gCi0gICAgIGFuZCB1c2luZyBzaGFyZWQgY29kZS4KLSAgIDwvYWN0aW9uPiAgICAgICAKLQotICA8YWN0aW9uIGNvbnRleHQ9ImNvZGUsIEFTVCIKLSAgICAgICAgICBjYXRlZ29yeT0iYXJjaGl0ZWN0dXJlIgotICAgICAgICAgIHdobz0iPz8iCi0gICAgICAgICAgcHJpb3JpdHk9Im1lZGl1bSI+Ci0gICAgVXNlIFNBWCB0byBidWlsZCB0aGUgQVNULiBUaGUgRE9NIGJ1aWxkZXIKLSAgICh0aGUgcmVhbCBET00gYnVpbGRlciwgbm90IG91ciBxdWFzaS1ET00gYnVpbGRlcikgcmVjZWl2ZXMgU0FYCi0gICBldmVudHMgd2hlbiBpdCBidWlsZHMgdGhlIERPTS4gVGhlIGNvbXBpbGVyLlBhcnNlciBjbGFzcyBjb3VsZAotICAgcG9zc2libGUgcmVjZWl2ZSB0aGVzZSBTQVggZXZlbnRzIGRpcmVjdGx5LCBhbmQgdGhlcmVieSBlbGltaW5hdGluZwotICAgdGhlIG5lZWQgZm9yIGEgRE9NIChzYXZlcyBsb2FkcyBvZiB0aW1lIGFuZCBtZW1vcnkpLgotICAgPC9hY3Rpb24+Ci0gICAKLSAgIDxhY3Rpb24gY29udGV4dD0iY29kZSwgRE9NIgotICAgICAgICAgICBjYXRlZ29yeT0iYXJjaGl0ZWN0dXJlIgotICAgICAgICAgICB3aG89Ij8/IgotICAgICAgICAgICBwcmlvcml0eT0ibWVkaXVtIj4KLSAgICAgIENvbnNpZGVyIGJ1aWxkaW5nIGEgRE9NLTItJ0RPTScgY29udmVydGVyLCBwZXJoYXBzIGJ5IGFkZGluZyAKLSAgICAgIGEgc2Vjb25kIERPTSBidWlsZGVyIGlubmVyIGNsYXNzIHRvIG91ciBET00uIFRoZW4gd2Ugd291bGQgaGF2ZSAKLSAgICAgIG9uZSBTQVggRE9NIGJ1aWxkZXIgYW5kIG9uZSBET00gRE9NIGJ1aWxkZXIuIEkgZG9uJ3Qga25vdyBpZgotICAgICAgSkFYUCBsZXRzIHlvdSBzdXBwbHkgdGhlIHN0eWxlc2hlZXQgYXMgYSBET00uIElmIGl0IGRvZXNuJ3QsIAotICAgICAgd2Ugc2hvdWxkIGFzc2lnbiB0aGlzIHRhc2sgYSB2ZXJ5IGxvdyBwcmlvcml0eS4gVGhlcmUgaXMgbm8KLSAgICAgIHBvaW50IGluIHNwZW5kaW5nIGEgbG90IG9mIHRpbWUgb24gdGhpcyBpZiBKQVhQIHVzZXJzIHdpbGwgCi0gICAgICBuZXZlciBiZSBhYmxlIHRvIHVzZSB0aGlzIGZ1bmN0aW9uYWxpdHkuCi0gICAgPC9hY3Rpb24+ICAgICAgIAotCi0gIDwvYWN0aW9ucz4KLTwvdG9kbz4K